diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs new file mode 100644 index 0000000000000..2c4cc42006e8c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -0,0 +1,82 @@ +What: /sys/fs/f2fs//gc_max_sleep_time +Date: July 2013 +Contact: "Namjae Jeon" +Description: + Controls the maximun sleep time for gc_thread. Time + is in milliseconds. + +What: /sys/fs/f2fs//gc_min_sleep_time +Date: July 2013 +Contact: "Namjae Jeon" +Description: + Controls the minimum sleep time for gc_thread. Time + is in milliseconds. + +What: /sys/fs/f2fs//gc_no_gc_sleep_time +Date: July 2013 +Contact: "Namjae Jeon" +Description: + Controls the default sleep time for gc_thread. Time + is in milliseconds. + +What: /sys/fs/f2fs//gc_idle +Date: July 2013 +Contact: "Namjae Jeon" +Description: + Controls the victim selection policy for garbage collection. + +What: /sys/fs/f2fs//reclaim_segments +Date: October 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the issue rate of segment discard commands. + +What: /sys/fs/f2fs//ipu_policy +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the in-place-update policy. + +What: /sys/fs/f2fs//min_ipu_util +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the FS utilization condition for the in-place-update + policies. + +What: /sys/fs/f2fs//min_fsync_blocks +Date: September 2014 +Contact: "Jaegeuk Kim" +Description: + Controls the dirty page count condition for the in-place-update + policies. + +What: /sys/fs/f2fs//max_small_discards +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the issue rate of small discard commands. + +What: /sys/fs/f2fs//max_victim_search +Date: January 2014 +Contact: "Jaegeuk Kim" +Description: + Controls the number of trials to find a victim segment. + +What: /sys/fs/f2fs//dir_level +Date: March 2014 +Contact: "Jaegeuk Kim" +Description: + Controls the directory level for large directory. + +What: /sys/fs/f2fs//ram_thresh +Date: March 2014 +Contact: "Jaegeuk Kim" +Description: + Controls the memory footprint used by f2fs. + +What: /sys/fs/f2fs//trim_sections +Date: February 2015 +Contact: "Jaegeuk Kim" +Description: + Controls the trimming rate in batch mode. diff --git a/Documentation/devicetree/bindings/batterydata/batterydata.txt b/Documentation/devicetree/bindings/batterydata/batterydata.txt index b0dc28ca6d734..08813fd38c63d 100644 --- a/Documentation/devicetree/bindings/batterydata/batterydata.txt +++ b/Documentation/devicetree/bindings/batterydata/batterydata.txt @@ -39,6 +39,20 @@ Profile data node required properties: influencing the final output of the state of charge read by software. +Profile data node optional properties: +- qcom,chg-rslow-comp-c1 : A constant for rslow compensation in the fuel gauge. + This will be provided by the profiling tool for + additional fuel gauge accuracy during charging. +- qcom,chg-rslow-comp-c2 : A constant for rslow compensation in the fuel gauge. + This will be provided by the profiling tool for + additional fuel gauge accuracy during charging. +- qcom,chg-rslow-comp-thr : A constant for rslow compensation in the fuel gauge. + This will be provided by the profiling tool for + additional fuel gauge accuracy during charging. +- qcom,chg-rs-to-rslow: A constant for rslow compensation in the fuel gauge. + This will be provided by the profiling tool for + additional fuel gauge accuracy during charging. + Profile data node required subnodes: - qcom,fcc-temp-lut : An 1-dimensional lookup table node that encodes temperature to fcc lookup. The units for this lookup diff --git a/Documentation/devicetree/bindings/power/qpnp-fg.txt b/Documentation/devicetree/bindings/power/qpnp-fg.txt index 4b3ca700ddd31..74a78b5d4c692 100644 --- a/Documentation/devicetree/bindings/power/qpnp-fg.txt +++ b/Documentation/devicetree/bindings/power/qpnp-fg.txt @@ -30,6 +30,9 @@ Optionally ADC nodes can be added Parent node required properties: - compatible : should be "qcom,qpnp-fg" for the FG driver. +- qcom,pmic-revid : Should specify the phandle of PMIC + revid module. This is used to identify + the PMIC subtype. Parent node optional properties: - qcom,warm-bat-decidegc: Warm battery temperature in decidegC. @@ -183,6 +186,7 @@ pmi8994_fg: qcom,fg { #address-cells = <1>; #size-cells = <1>; status = "disabled"; + qcom,pmic-revid = <&pmi8994_revid>; qcom,fg-soc@4000 { reg = <0x4000 0x100>; diff --git a/Documentation/devicetree/bindings/power/qpnp-smbcharger.txt b/Documentation/devicetree/bindings/power/qpnp-smbcharger.txt index 58692aecee72f..8083cf25eb1b2 100644 --- a/Documentation/devicetree/bindings/power/qpnp-smbcharger.txt +++ b/Documentation/devicetree/bindings/power/qpnp-smbcharger.txt @@ -255,6 +255,10 @@ Optional Properties: - qcom,battery-data Points to the phandle of node which contains the battery-profiles supported by the charger/FG. +- qcom,rerun-apsd A bool property that will force the charger to + force the msm USB phy to relinquish control of the + USB data lines and rerun APSD when a USB SDP is + selected. Example: qcom,qpnp-smbcharger { diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index bd3c56c67380b..75ea35a1c6877 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -101,6 +101,8 @@ MOUNT OPTIONS background_gc_off Turn off cleaning operations, namely garbage collection, triggered in background when I/O subsystem is idle. disable_roll_forward Disable the roll-forward recovery routine +norecovery Disable the roll-forward recovery routine, mounted read- + only (i.e., -o ro,disable_roll_forward) discard Issue discard/TRIM commands when a segment is cleaned. no_heap Disable heap-style segment allocation which finds free segments for data from the beginning of main area, while @@ -114,6 +116,31 @@ active_logs=%u Support configuring the number of active logs. In the Default number is 6. disable_ext_identify Disable the extension list configured by mkfs, so f2fs does not aware of cold files such as media files. +inline_xattr Enable the inline xattrs feature. +inline_data Enable the inline data feature: New created small(<~3.4k) + files can be written into inode block. +inline_dentry Enable the inline dir feature: data in new created + directory entries can be written into inode block. The + space of inode block which is used to store inline + dentries is limited to ~3.4k. +flush_merge Merge concurrent cache_flush commands as much as possible + to eliminate redundant command issues. If the underlying + device handles the cache_flush command relatively slowly, + recommend to enable this option. +nobarrier This option can be used if underlying storage guarantees + its cached data should be written to the novolatile area. + If this option is set, no cache_flush commands are issued + but f2fs still guarantees the write ordering of all the + data writes. +fastboot This option is used when a system wants to reduce mount + time as much as possible, even though normal performance + can be sacrificed. +extent_cache Enable an extent cache based on rb-tree, it can cache + as many as extent which map between contiguous logical + address and physical address per inode, resulting in + increasing the cache hit ratio. +noinline_data Disable the inline data feature, inline data feature is + enabled by default. ================================================================================ DEBUGFS ENTRIES @@ -127,6 +154,90 @@ f2fs. Each file shows the whole f2fs information. - average SIT information about whole segments - current memory footprint consumed by f2fs. +================================================================================ +SYSFS ENTRIES +================================================================================ + +Information about mounted f2f2 file systems can be found in +/sys/fs/f2fs. Each mounted filesystem will have a directory in +/sys/fs/f2fs based on its device name (i.e., /sys/fs/f2fs/sda). +The files in each per-device directory are shown in table below. + +Files in /sys/fs/f2fs/ +(see also Documentation/ABI/testing/sysfs-fs-f2fs) +.............................................................................. + File Content + + gc_max_sleep_time This tuning parameter controls the maximum sleep + time for the garbage collection thread. Time is + in milliseconds. + + gc_min_sleep_time This tuning parameter controls the minimum sleep + time for the garbage collection thread. Time is + in milliseconds. + + gc_no_gc_sleep_time This tuning parameter controls the default sleep + time for the garbage collection thread. Time is + in milliseconds. + + gc_idle This parameter controls the selection of victim + policy for garbage collection. Setting gc_idle = 0 + (default) will disable this option. Setting + gc_idle = 1 will select the Cost Benefit approach + & setting gc_idle = 2 will select the greedy aproach. + + reclaim_segments This parameter controls the number of prefree + segments to be reclaimed. If the number of prefree + segments is larger than the number of segments + in the proportion to the percentage over total + volume size, f2fs tries to conduct checkpoint to + reclaim the prefree segments to free segments. + By default, 5% over total # of segments. + + max_small_discards This parameter controls the number of discard + commands that consist small blocks less than 2MB. + The candidates to be discarded are cached until + checkpoint is triggered, and issued during the + checkpoint. By default, it is disabled with 0. + + trim_sections This parameter controls the number of sections + to be trimmed out in batch mode when FITRIM + conducts. 32 sections is set by default. + + ipu_policy This parameter controls the policy of in-place + updates in f2fs. There are five policies: + 0x01: F2FS_IPU_FORCE, 0x02: F2FS_IPU_SSR, + 0x04: F2FS_IPU_UTIL, 0x08: F2FS_IPU_SSR_UTIL, + 0x10: F2FS_IPU_FSYNC. + + min_ipu_util This parameter controls the threshold to trigger + in-place-updates. The number indicates percentage + of the filesystem utilization, and used by + F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. + + min_fsync_blocks This parameter controls the threshold to trigger + in-place-updates when F2FS_IPU_FSYNC mode is set. + The number indicates the number of dirty pages + when fsync needs to flush on its call path. If + the number is less than this value, it triggers + in-place-updates. + + max_victim_search This parameter controls the number of trials to + find a victim segment when conducting SSR and + cleaning operations. The default value is 4096 + which covers 8GB block address range. + + dir_level This parameter controls the directory level to + support large directory. If a directory has a + number of files, it can reduce the file lookup + latency by increasing this dir_level value. + Otherwise, it needs to decrease this value to + reduce the space overhead. The default value is 0. + + ram_thresh This parameter controls the memory footprint used + by free nids and cached nat entries. By default, + 10 is set, which indicates 10 MB / 1 GB RAM. + ================================================================================ USAGE ================================================================================ diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fd22b040a2ac3..44fdcafc67e47 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1357,6 +1357,19 @@ ndisc_notify - BOOLEAN 1 - Generate unsolicited neighbour advertisements when device is brought up or hardware address changes. +optimistic_dad - BOOLEAN + Whether to perform Optimistic Duplicate Address Detection (RFC 4429). + 0: disabled (default) + 1: enabled + +use_optimistic - BOOLEAN + If enabled, do not classify optimistic addresses as deprecated during + source address selection. Preferred addresses will still be chosen + before optimistic addresses, subject to other ranking in the source + address selection algorithm. + 0: disabled (default) + 1: enabled + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index c78f4dfc171b6..99f45df715240 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void $(CF) CFLAGS_MODULE = AFLAGS_MODULE = -LDFLAGS_MODULE = +LDFLAGS_MODULE = --strip-debug CFLAGS_KERNEL = AFLAGS_KERNEL = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage @@ -385,6 +385,12 @@ KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds +#ifdef VENDOR_EDIT +KBUILD_CFLAGS += -DVENDOR_EDIT +KBUILD_CPPFLAGS += -DVENDOR_EDIT +CFLAGS_KERNEL += -DVENDOR_EDIT +CFLAGS_MODULE += -DVENDOR_EDIT +#endif # Read KERNELRELEASE from include/config/kernel.release (if it exists) KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) diff --git a/arch/arm/boot/dts/qcom/apq8094-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8094-dragonboard.dtsi index fd95663c3c960..bc9b89ef71b80 100644 --- a/arch/arm/boot/dts/qcom/apq8094-dragonboard.dtsi +++ b/arch/arm/boot/dts/qcom/apq8094-dragonboard.dtsi @@ -288,7 +288,6 @@ 0x0 1 &intc 0 180 0>; interrupt-names = "hs_phy_irq", "pwr_event_irq"; qcom,charging-disabled; - vbus_dwc3-supply = <&vph_pwr_vreg>; qcom,ext-hub-reset-gpio = <&pm8994_gpios 1 0>; dwc3@f9200000 { snps,host-only-mode; @@ -599,8 +598,18 @@ /delete-property/ vdd-wlan-xtal-supply; }; +&usb_otg_switch{ + status= "disabled"; +}; + &pmi8994_charger { - status = "disabled"; + qcom,charging-disabled; + regulator-name = "pmi8994_otg_vreg"; + /delete-property/ otg-parent-supply; + + smbcharger_charger_otg { + parent-supply = <&pmi8994_boost_5v>; + }; }; &rpm_bus { diff --git a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi index 92841b5ef5387..cc52acd8a6950 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi @@ -306,6 +306,7 @@ qcom,cycle-counter-high-soc = <85>; qcom,capacity-learning-on; qcom,fg-cc-cv-threshold-mv = <4340>; + qcom,pmic-revid = <&pmi8994_revid>; qcom,fg-soc@4000 { status = "okay"; diff --git a/arch/arm/boot/dts/qcom/msm8992-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8992-camera-sensor-mtp.dtsi index 6dca4a0f72ce7..b5441ba19c195 100644 --- a/arch/arm/boot/dts/qcom/msm8992-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8992-camera-sensor-mtp.dtsi @@ -314,6 +314,31 @@ clock-names = "cam_src_clk", "cam_clk"; }; + eeprom4: qcom,eeprom@4 { + cell-index = <4>; + reg = <4>; + qcom,eeprom-name = "imx258_gt24c16"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <2166 0x00 2 0 1 0>; + + cam_vio-supply = <&pm8994_lvs1>; + qcom,cam-vreg-name = "cam_vio"; + qcom,cam-vreg-min-voltage = <0>; + qcom,cam-vreg-max-voltage = <0>; + qcom,cam-vreg-op-mode = <0>; + qcom,cam-power-seq-type = "sensor_vreg"; + qcom,cam-power-seq-val = "cam_vio"; + qcom,cam-power-seq-cfg-val = <1>; + qcom,cam-power-seq-delay = <1>; + status = "ok"; + }; + qcom,camera@0 { cell-index = <0>; compatible = "qcom,camera"; @@ -321,7 +346,7 @@ qcom,csiphy-sd-index = <0>; qcom,csid-sd-index = <0>; qcom,mount-angle = <270>; - qcom,eeprom-src = <&eeprom0 &eeprom2 &eeprom3>; + qcom,eeprom-src = <&eeprom0 &eeprom2 &eeprom3 &eeprom4>; qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,led-flash-src = <&led_flash0>; diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h index da1a0745029a3..fe7541b6cae16 100644 --- a/arch/arm/mach-msm/include/mach/camera.h +++ b/arch/arm/mach-msm/include/mach/camera.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2013, 2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -300,6 +300,8 @@ enum msm_cci_cmd_type { }; struct msm_camera_cci_wait_sync_cfg { + uint16_t cid; + int16_t csid; uint16_t line; uint16_t delay; }; diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 4f9f33874d358..9469467ea538c 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -20,6 +20,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) KBUILD_DEFCONFIG := defconfig KBUILD_CFLAGS += -mgeneral-regs-only +KBUILD_CFLAGS += -fno-pic ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB @@ -73,7 +74,12 @@ zinstall install: vmlinux dtbs: scripts $(Q)$(MAKE) $(build)=$(boot)/dts dtbs - $(Q)$(MAKE) $(build)=$(boot)/dts/qcom dtbs +# $(Q)$(MAKE) $(build)=$(boot)/dts/qcom dtbs + $(Q)$(MAKE) $(build)=$(boot)/dts/14049_HW_11 dtbs + $(Q)$(MAKE) $(build)=$(boot)/dts/14049_HW_12 dtbs + $(Q)$(MAKE) $(build)=$(boot)/dts/14049_HW_13 dtbs + $(Q)$(MAKE) $(build)=$(boot)/dts/14049_HW_14 dtbs + PHONY += vdso_install vdso_install: diff --git a/arch/arm64/boot/dts/14049_HW_11/Makefile b/arch/arm64/boot/dts/14049_HW_11/Makefile new file mode 100755 index 0000000000000..a3a9beb50722f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/Makefile @@ -0,0 +1,22 @@ +ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_MSM8994) += msm8994-v1-mtp_14049_HW_11.dtb \ + msm8994-v2.0-mtp_14049_HW_11.dtb \ + msm8994-v2.1-mtp_14049_HW_11.dtb + +DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) +ifneq ($(DTB_NAMES),) +DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) +else +DTB_LIST := $(dtb-y) +endif + +targets += dtbs +targets += $(addprefix ../, $(DTB_LIST)) +endif + +$(obj)/../%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + +dtbs: $(addprefix $(obj)/../,$(DTB_LIST)) + +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3000mah.dtsi new file mode 100755 index 0000000000000..dc23e181f64d3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3000mah.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3000mah { + qcom,max-voltage-uv = <4320000>; /* yangfangbiao@oneplus.cn, 2015/03/15 Set max voltage 4.32v */ + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3000mah"; + qcom,checksum = <0xF99F>; + qcom,fg-profile-data = [ + EC 83 39 7D + 10 81 04 77 + 23 83 9A 72 + AE 52 20 84 + FC 81 51 93 + FB AD D2 B0 + 5B 12 E5 82 + 09 78 90 75 + A7 70 0C 83 + 1A 80 71 8D + 48 89 08 82 + D4 99 74 BC + A2 C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 45 31 A4 44 + 6E 3B 00 00 + AD 3D 24 36 + A9 46 00 00 + 00 00 00 00 + 00 00 00 00 + E7 6A 05 6A + 8E 75 F9 80 + 5E 76 DA 68 + 45 74 54 81 + 10 75 13 60 + 61 7E 38 A1 + 33 DB 62 1A + 64 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3020mah.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3020mah.dtsi new file mode 100755 index 0000000000000..9a2ce4badf33e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata-itech-3020mah.dtsi @@ -0,0 +1,53 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3020mah { + qcom,max-voltage-uv = <4350000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3020mah"; + qcom,fg-profile-data = [ + E8 83 0C 7D + E9 80 B2 76 + 20 83 40 73 + D7 6C 59 7E + FB 81 58 93 + 0D AE 02 B1 + 5B 12 D7 82 + 86 78 F3 76 + 4A 71 0C 83 + 1B 80 73 8D + 49 89 07 82 + D8 99 79 BC + AA C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 09 2E 79 44 + 52 43 00 00 + DE 3D 2A 37 + D3 46 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 6B B7 69 + DD 6C 83 83 + 42 76 CA 68 + 78 75 EF 80 + D4 74 56 5B + 00 00 00 00 + 0A A5 5A D2 + 54 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata-mtp-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata-mtp-3000mah.dtsi new file mode 100755 index 0000000000000..198fbea2ef0af --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata-mtp-3000mah.dtsi @@ -0,0 +1,118 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,mtp-3000mah { + qcom,fcc-mah = <3000>; + qcom,default-rbatt-mohm = <113>; + qcom,max-voltage-uv = <4200000>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <200000>; + qcom,batt-id-kohm = <300>; + qcom,battery-type = "mtp_3000mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <3030 3033 3037 3035 3031>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4191 4188 4183 4179 4174>, + <4106 4125 4127 4125 4121>, + <4046 4082 4082 4080 4077>, + <3966 4038 4044 4040 4035>, + <3922 3983 3994 3998 3997>, + <3886 3949 3966 3966 3962>, + <3856 3908 3937 3935 3931>, + <3832 3875 3908 3907 3903>, + <3814 3847 3874 3878 3875>, + <3799 3826 3831 3832 3830>, + <3787 3807 3811 3811 3809>, + <3775 3793 3795 3795 3793>, + <3764 3782 3783 3783 3781>, + <3752 3775 3773 3772 3769>, + <3739 3768 3766 3762 3755>, + <3725 3756 3756 3747 3733>, + <3710 3732 3734 3725 3711>, + <3696 3707 3705 3697 3684>, + <3681 3695 3686 3678 3667>, + <3667 3690 3684 3676 3665>, + <3658 3688 3683 3675 3664>, + <3646 3685 3681 3674 3663>, + <3631 3682 3679 3673 3660>, + <3612 3677 3676 3669 3655>, + <3589 3667 3666 3660 3639>, + <3560 3643 3636 3630 3599>, + <3523 3600 3586 3581 3546>, + <3474 3537 3518 3516 3477>, + <3394 3446 3425 3427 3379>, + <3257 3306 3273 3283 3213>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>; + qcom,lut-data = <1025 208 100 85 80>, + <1025 208 100 85 80>, + <1032 225 103 87 81>, + <959 249 107 91 82>, + <954 249 109 92 84>, + <953 255 117 94 84>, + <957 230 123 98 87>, + <968 216 134 102 91>, + <983 212 138 112 95>, + <1002 213 103 89 82>, + <1030 215 100 86 81>, + <1066 219 101 89 83>, + <1115 224 104 92 85>, + <1182 234 106 94 86>, + <1263 246 108 92 84>, + <1357 257 107 87 81>, + <1464 261 102 85 80>, + <1564 256 101 84 80>, + <1637 268 100 84 80>, + <1580 276 102 87 81>, + <1617 285 104 87 82>, + <1670 298 107 91 82>, + <1725 315 108 92 83>, + <1785 338 112 92 83>, + <1850 361 111 91 82>, + <1921 378 108 89 84>, + <2000 394 112 92 87>, + <2119 430 121 99 94>, + <2795 497 144 114 104>, + <8769 1035 672 322 234>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <3030 3033 3037>, + <1898 2943 2960>, + <1184 2855 2948>, + <209 2464 2921>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata-palladium.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata-palladium.dtsi new file mode 100755 index 0000000000000..4c44351892565 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata-palladium.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,palladium-batterydata { + qcom,fcc-mah = <1500>; + qcom,default-rbatt-mohm = <210>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,flat-ocv-threshold-uv = <3800000>; + qcom,max-voltage-uv = <4200000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <75>; + qcom,battery-type = "palladium_1500mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <1467 1470 1473 1473 1470>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4175 4173 4167 4162 4157>, + <4097 4111 4112 4110 4107>, + <4039 4075 4072 4068 4064>, + <3963 4017 4025 4026 4025>, + <3920 3969 3984 3989 3988>, + <3887 3932 3957 3958 3955>, + <3856 3898 3929 3928 3925>, + <3830 3868 3900 3901 3898>, + <3808 3843 3858 3863 3862>, + <3793 3821 3827 3827 3827>, + <3779 3803 3807 3808 3807>, + <3768 3788 3792 3793 3792>, + <3757 3779 3780 3780 3779>, + <3746 3771 3772 3768 3768>, + <3734 3762 3765 3759 3749>, + <3722 3747 3753 3744 3730>, + <3707 3721 3731 3722 3709>, + <3693 3705 3704 3696 3683>, + <3678 3698 3687 3678 3667>, + <3664 3693 3683 3676 3665>, + <3656 3690 3682 3675 3664>, + <3646 3687 3681 3674 3662>, + <3634 3683 3680 3672 3661>, + <3618 3677 3676 3668 3656>, + <3599 3667 3667 3655 3639>, + <3573 3645 3638 3623 3603>, + <3541 3607 3591 3575 3554>, + <3496 3550 3528 3511 3490>, + <3428 3469 3445 3423 3400>, + <3312 3342 3308 3280 3250>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <909 216 100 85 84>, + <859 238 106 88 86>, + <860 237 105 88 86>, + <808 239 107 90 88>, + <801 234 111 94 90>, + <801 230 118 97 92>, + <801 224 123 100 95>, + <807 221 128 106 99>, + <818 221 111 101 97>, + <841 225 101 88 87>, + <870 229 101 88 87>, + <906 235 103 91 90>, + <950 243 106 93 93>, + <998 253 110 93 96>, + <1051 263 113 94 90>, + <1116 272 113 91 88>, + <1200 275 111 91 88>, + <1312 298 108 90 87>, + <1430 329 104 88 87>, + <1484 351 107 91 89>, + <1446 345 110 93 90>, + <1398 344 112 94 90>, + <1466 358 115 96 91>, + <1490 357 117 96 90>, + <1589 365 117 94 89>, + <1828 379 111 91 88>, + <2151 399 111 93 91>, + <2621 436 117 98 95>, + <3404 496 130 106 100>, + <8212 616 150 1906 134>, + <135251 124940 59087 49820 29672>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <1470 1470 1473>, + <601 1406 1430>, + <89 1247 1414>, + <8 764 1338>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata-unkown-3300mah.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata-unkown-3300mah.dtsi new file mode 100755 index 0000000000000..4ee01d90bd24d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata-unkown-3300mah.dtsi @@ -0,0 +1,50 @@ +qcom,oneplus_default_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "Unknown Battery"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_ATL_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_ATL_3300mAh.dtsi new file mode 100755 index 0000000000000..08924c2b14994 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_ATL_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "ATL"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_SDI_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_SDI_3300mAh.dtsi new file mode 100755 index 0000000000000..8756ab9405b54 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/batterydata_oneplus_SDI_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_SDI_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <0>; + qcom,battery-type = "SDI"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jd35695-1080p-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jd35695-1080p-cmd.dtsi new file mode 100755 index 0000000000000..1a2f9b6bdc85a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jd35695-1080p-cmd.dtsi @@ -0,0 +1,210 @@ +/************************************************************ + * Copyright (c) 2013-2013 OPPO Mobile communication Corp.ltd., + * VENDOR_EDIT + * Description: device tree for jdi cmd panel. + * Version : 1.0 + * Date : 2013-12-12 + * Author : yangxinqin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { +dsi_jd35695_1080_cmd: qcom,mdss_dsi_jd35695_1080p_cmd { + compatible = "qcom,mdss-dsi-panel"; + status = "ok"; + qcom,cont-splash-enabled; + qcom,mdss-dsi-panel-name = "jd35695 1080p cmd mode dsi panel"; + qcom,mdss-dsi-panel-manufacture = "JDI"; + qcom,mdss-dsi-panel-version = "JD35695"; + qcom,mdss-dsi-backlight-version= "PMI8994"; + qcom,mdss-dsi-backlight-manufacture = "Qualcomm"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <100>; + qcom,mdss-dsi-h-back-porch = <82>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <7>; + qcom,mdss-dsi-v-front-porch = <3>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0x0000ff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 39 01 00 00 00 00 05 2a 00 00 04 37 + 39 01 00 00 00 00 05 2b 00 00 07 7f + + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF E0 + 15 01 00 00 00 00 02 B5 86 + 15 01 00 00 00 00 02 B6 77 + 15 01 00 00 00 00 02 B8 AD + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 FF 10 + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + + 05 01 00 00 6E 00 02 11 00 + 05 01 00 00 2D 00 02 29 00 + ]; + qcom,mdss-dsi-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 00 + 05 01 00 00 64 00 02 28 00 + 05 01 00 00 64 00 02 10 00]; + + qcom,mdss-dsi-color-test-on-command= + [ + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 01 + 15 01 00 00 00 00 02 FF 20 + 15 01 00 00 00 00 02 67 4D]; + + + qcom,mdss-dsi-color-test-off-command = + [ + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 00 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 32 00 02 29 00]; + + qcom,mdss-dsi-cabc-off-command = [15 01 00 00 10 00 02 55 00 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-ui-command = [15 01 00 00 10 00 02 55 01 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-still-image-command = [15 01 00 00 10 00 02 55 02 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-video-command = [15 01 00 00 10 00 02 55 03 + 05 01 00 00 10 00 02 29 00]; + + qcom,mdss-dsi-on-command_shoushi = [ + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 60 00 02 29 00 + + ]; + qcom,mdss-dsi-color-test-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-color-test-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + + + + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + + + + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + //qcom,mdss-dsi-init-delay-us=<50000>; + /**************************************************************************/ + // qcom,esd-check-enabled; + // qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; + // qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; + // qcom,mdss-dsi-panel-status-check-mode = "reg_read_jd35695"; + // qcom,mdss-dsi-panel-status-read-length = <8>; + // qcom,mdss-dsi-panel-max-error-count = <2>; + // qcom,mdss-dsi-panel-status-value = <0x9c 0x00 0x00 0x02 0x40 0x80 0x00 0x00>; + /******************************************************************************/ + // qcom,mdss-dsi-dma-trigger = "trigger_sw"; + // qcom,mdss-dsi-mdp-trigger = "trigger_sw"; + + + + // qcom,mdss-tear-check-frame-rate=<6000>; + //qcom,mdss-tear-check-sync-cfg-height = <1932>; /* Height + VBP + VFP + VSW */ + //qcom,mdss-tear-check-sync-init-val= <1920>; /* Height */ + //qcom,mdss-tear-check-sync-threshold-start = <4>; + //qcom,mdss-tear-check-sync-threshold-continue = <4>; + //qcom,mdss-tear-check-start-pos= <1920>; /* Height */ + //qcom,mdss-tear-check-rd-ptr-trigger-intr= <1921>; /* Height + 1 */ + + + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <127>; + + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 14>, <0 5>, <1 20>; + + }; +}; + + diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jdi-1080p-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jdi-1080p-video.dtsi new file mode 100755 index 0000000000000..7e4e9ceeeaab8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-jdi-1080p-video.dtsi @@ -0,0 +1,97 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_jdi_1080_vid: qcom,mdss_dsi_jdi_1080p_video { + qcom,mdss-dsi-panel-name = "jdi 1080p video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 23 01 00 00 00 00 02 FF 10 + 15 01 00 00 10 00 02 35 00 + 15 01 00 00 10 00 02 bb 03 + //29 01 00 00 00 00 03 44 05 00 + 23 01 00 00 00 00 02 FF E0 + 23 01 00 00 00 00 02 B5 86 + 23 01 00 00 00 00 02 B6 77 + 23 01 00 00 00 00 02 B8 AD + 23 01 00 00 00 00 02 FB 01 + 23 01 00 00 00 00 02 FF 10 + +/************************************************************** + //15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + self test mode + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 23 01 00 00 00 00 02 FF 24 + 23 01 00 00 00 00 02 EC 01 + 23 01 00 00 00 00 02 FF 20 + 23 01 00 00 00 00 02 67 4D +*************************************************************/ + 15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + 23 01 00 00 00 00 02 FF 23 + 23 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 24 + + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 78 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 79 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-init-delay-us=<50000>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 50>; + qcom,mdss-pan-physical-width-dimension = <61>; + qcom,mdss-pan-physical-height-dimension = <110>; + }; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi new file mode 100755 index 0000000000000..8ae76e72ddb7a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi @@ -0,0 +1,68 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_0: qcom,mdss_dsi_sharp_wqxga_video_0 { + qcom,mdss-dsi-panel-name = "Dual 0 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <50>; + qcom,mdss-dsi-bl-pmic-bank-select = <2>; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi new file mode 100755 index 0000000000000..a9337b1866188 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi @@ -0,0 +1,66 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_1: qcom,mdss_dsi_sharp_wqxga_video_1 { + qcom,mdss-dsi-panel-name = "Dual 1 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-cmd.dtsi new file mode 100755 index 0000000000000..694973e4ff43f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-cmd.dtsi @@ -0,0 +1,94 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_cmd: qcom,mdss_dsi_sim_cmd{ + qcom,mdss-dsi-panel-name = "Simulator cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-cmd.dtsi new file mode 100755 index 0000000000000..74986f9b4e5f3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-cmd.dtsi @@ -0,0 +1,95 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_0: qcom,mdss_dsi_sim_cmd_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-video.dtsi new file mode 100755 index 0000000000000..13cd57f321c82 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi0-video.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_0: qcom,mdss_dsi_sim_video_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-cmd.dtsi new file mode 100755 index 0000000000000..f73e47bd504b5 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-cmd.dtsi @@ -0,0 +1,96 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_1: qcom,mdss_dsi_sim_cmd_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-video.dtsi new file mode 100755 index 0000000000000..882b2abdce34f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-dualmipi1-video.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_1: qcom,mdss_dsi_sim_video_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-video.dtsi b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-video.dtsi new file mode 100755 index 0000000000000..bd9322bac2e74 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/dsi-panel-sim-video.dtsi @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_vid: qcom,mdss_dsi_sim_video { + qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <640>; + qcom,mdss-dsi-panel-height = <480>; + qcom,mdss-dsi-h-front-porch = <6>; + qcom,mdss-dsi-h-back-porch = <6>; + qcom,mdss-dsi-h-pulse-width = <2>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <6>; + qcom,mdss-dsi-v-front-porch = <6>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [32 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-off-command = [22 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [00 00 00 00 00 00 00 00 00 00 00 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x1b>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 0>, <0 0>, <1 0>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-gdsc-8916.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-gdsc-8916.dtsi new file mode 100755 index 0000000000000..07e1e33fd4482 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-gdsc-8916.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@184c018 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0x184c018 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@184d078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0x184d078 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@185701c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0x185701c 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@1858034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0x1858034 0x4>; + status = "disabled"; + }; + + gdsc_vfe1: qcom,gdsc@185806c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe1"; + reg = <0x185806c 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@1858078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0x1858078 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@185901c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0x185901c 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@184c028 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0x184c028 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@184c030 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0x184c030 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-gdsc.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-gdsc.dtsi new file mode 100755 index 0000000000000..9a1f32eb0c7aa --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-gdsc.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@fd8c1024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0xfd8c1024 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@fd8c1040 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0xfd8c1040 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@fd8c1044 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0xfd8c1044 0x4>; + status = "disabled"; + }; + + gdsc_venus_core2: qcom,gdsc@fd8c1050 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core2"; + reg = <0xfd8c1050 0x4>; + status = "disabled"; + }; + + gdsc_vpu: qcom,gdsc@fd8c1404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vpu"; + reg = <0xfd8c1404 0x4>; + status = "disabled"; + }; + + gdsc_camss_top: qcom,gdsc@fd8c34a0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_camss_top"; + reg = <0xfd8c34a0 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@fd8c2304 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0xfd8c2304 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@fd8c35a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0xfd8c35a4 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@fd8c36a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0xfd8c36a4 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@fd8c36d4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0xfd8c36d4 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@fd8c4024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0xfd8c4024 0x4>; + status = "disabled"; + }; + + gdsc_oxili_cx: qcom,gdsc@fd8c4034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_cx"; + reg = <0xfd8c4034 0x4>; + status = "disabled"; + }; + + gdsc_usb_hsic: qcom,gdsc@fc400404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb_hsic"; + reg = <0xfc400404 0x4>; + status = "disabled"; + }; + + gdsc_pcie: qcom,gdsc@0xfc401e18 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie"; + reg = <0xfc401e18 0x4>; + status = "disabled"; + }; + + gdsc_pcie_0: qcom,gdsc@fc401ac4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_0"; + reg = <0xfc401ac4 0x4>; + status = "disabled"; + }; + + gdsc_pcie_1: qcom,gdsc@fc401b44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_1"; + reg = <0xfc401b44 0x4>; + status = "disabled"; + }; + + gdsc_usb30: qcom,gdsc@fc401e84 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30"; + reg = <0xfc401e84 0x4>; + status = "disabled"; + }; + + gdsc_usb30_sec: qcom,gdsc@fc401ec0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30_sec"; + reg = <0xfc401ec0 0x4>; + status = "disabled"; + }; + + gdsc_vcap: qcom,gdsc@fd8c1804 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vcap"; + reg = <0xfd8c1804 0x4>; + status = "disabled"; + }; + + gdsc_bcss: qcom,gdsc@fc744128 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_bcss"; + reg = <0xfc744128 0x4>; + status = "disabled"; + }; + + gdsc_ufs: qcom,gdsc@fc401d44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_ufs"; + reg = <0xfc401d44 0x4>; + status = "disabled"; + }; + + gdsc_fd: qcom,gdsc@fd8c3b64 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_fd"; + reg = <0xfd8c3b64 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v0.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v0.dtsi new file mode 100755 index 0000000000000..88919353600b8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v0.dtsi @@ -0,0 +1,328 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + lpass_iommu: qcom,iommu@fd000000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd000000 0x10000>; + interrupts = <0 248 0>; + qcom,glb-offset = <0xF000>; + label = "lpass_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "lpass_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <11 512 0 0>, + <11 512 0 1000>; + qcom,msm-enable-remote-spinlock; + status = "disabled"; + + lpass_q6_fw: qcom,iommu-ctx@fd000000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd000000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <0 15>; + label = "q6_fw"; + }; + + lpass_audio_shared: qcom,iommu-ctx@fd001000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd001000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <1>; + label = "audio_shared"; + }; + + lpass_video_shared: qcom,iommu-ctx@fd002000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd002000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <2>; + label = "video_shared"; + }; + + lpass_q6_spare: qcom,iommu-ctx@fd003000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd003000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare"; + }; + }; + + copss_iommu: qcom,iommu@fd010000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd010000 0x10000>; + interrupts = <0 252 0>; + qcom,glb-offset = <0xF000>; + label = "copss_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + + status = "disabled"; + + qcom,iommu-ctx@fd010000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd010000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <0>; + label = "copss_0"; + }; + + qcom,iommu-ctx@fd011000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd011000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <1>; + label = "copss_1"; + }; + + qcom,iommu-ctx@fd012000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd012000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <2>; + label = "copss_2"; + }; + + qcom,iommu-ctx@fd013000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd013000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <3>; + label = "copss_3"; + }; + + qcom,iommu-ctx@fd014000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd014000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <4>; + label = "copss_4"; + }; + + qcom,iommu-ctx@fd015000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd015000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <5>; + label = "copss_5"; + }; + + qcom,iommu-ctx@fd016000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd016000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <6>; + label = "copss_6"; + }; + + qcom,iommu-ctx@fd017000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd017000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <7>; + label = "copss_7"; + }; + }; + + mdpe_iommu: qcom,iommu@fd860000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd860000 0x10000>; + interrupts = <0 245 0>; + qcom,glb-offset = <0xF000>; + label = "mdpe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdpe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <92 512 0 0>, + <92 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd860000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd860000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <0 1 3>; + label = "mdpe_0"; + }; + + qcom,iommu-ctx@fd861000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd861000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <2>; + label = "mdpe_1"; + }; + }; + + mdps_iommu: qcom,iommu@fd870000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd870000 0x10000>; + interrupts = <0 73 0>; + qcom,glb-offset = <0xF000>; + label = "mdps_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdps_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd870000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd870000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <0>; + label = "mdps_0"; + }; + + qcom,iommu-ctx@fd871000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd871000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <1>; + label = "mdps_1"; + }; + }; + + gfx_iommu: qcom,iommu@fd880000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd880000 0x10000>; + interrupts = <0 38 0>; + qcom,glb-offset = <0xF000>; + qcom,needs-alt-core-clk; + label = "gfx_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "gfx_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd880000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd880000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 + 14 15>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fd881000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd881000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25 + 26 27 28 29 30 31>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fd882000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd882000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <>; + label = "gfx3d_spare"; + }; + }; + + vfe_iommu: qcom,iommu@fd890000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd890000 0x10000>; + interrupts = <0 62 0>; + qcom,glb-offset = <0xF000>; + label = "vfe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd890000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd890000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9>; + label = "vfe0"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v1.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v1.dtsi new file mode 100755 index 0000000000000..911d83c109235 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v1.dtsi @@ -0,0 +1,1513 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + jpeg_iommu: qcom,iommu@fda64000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda64000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 67 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "jpeg_iommu"; + status = "disabled"; + qcom,msm-bus,name = "jpeg_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <62 512 0 0>, + <62 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x0000ffff + 0x0 + 0x4 + 0x4 + 0x0 + 0x0 + 0x10 + 0x50 + 0x0 + 0x10 + 0x20 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@fda6d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <1>; + label = "jpeg_enc1"; + }; + + qcom,iommu-ctx@fda6e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6e000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <2>; + label = "jpeg_dec"; + }; + }; + + mdp_iommu: qcom,iommu@fd928000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd928000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000034 + 0x00000044 + 0x0 + 0x34 + 0x74 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd930000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd930000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd931000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd931000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd932000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd932000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; + + venus_iommu: qcom,iommu@fdc84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdc84000 0x10000 + 0xfdce0004 0x4>; + reg-names = "iommu_base", "clk_base"; + interrupts = <0 45 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <0>; + qcom,needs-alt-core-clk; + label = "venus_iommu"; + qcom,msm-bus,name = "venus_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2024 + 0x2028 + 0x202c + 0x2030 + 0x2034 + 0x2038>; + + qcom,iommu-bfb-data = <0xffffffff + 0xffffffff + 0x00000004 + 0x00000008 + 0x00000000 + 0x00000000 + 0x00000094 + 0x000000b4 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8c000 0x1000>; + interrupts = <0 42 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5>; + label = "venus_ns"; + }; + + venus_cp: qcom,iommu-ctx@fdc8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8d000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>; + label = "venus_cp"; + qcom,secure-context; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8e000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0xc0 0xc6>; + label = "venus_fw"; + qcom,secure-context; + }; + }; + + kgsl_iommu: qcom,iommu@fdb10000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdb10000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 38 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "kgsl_iommu"; + qcom,msm-bus,name = "kgsl_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000001 + 0x00000021 + 0x0 + 0x1 + 0x81 + 0x0>; + + qcom,iommu-ctx@fdb18000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb18000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fdb19000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb19000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fdb1a000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb1a000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <2>; + label = "gfx3d_spare"; + }; + + }; + + vfe_iommu: qcom,iommu@fda44000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda44000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 62 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <19>; + qcom,needs-alt-core-clk; + label = "vfe_iommu"; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x00000000 + 0x4 + 0x8 + 0x0 + 0x0 + 0x20 + 0x78 + 0x0 + 0x20 + 0x36 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda4c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4c000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <0 1>; + label = "vfe"; + }; + + qcom,iommu-ctx@fda4d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4d000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp"; + }; + + qcom,iommu-ctx@fda4e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4e000 0x1000>; + interrupts = <0 65 0>, <0 64 0>; + qcom,iommu-ctx-sids = <>; + label = "vfe_secure"; + qcom,secure-context; + }; + }; + + copss_iommu: qcom,iommu@f9bc4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xf9bc4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 153 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <8>; + label = "copss_iommu"; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x5 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x3 + 0x0>; + + + copss_cb0: qcom,iommu-ctx@f9bcc000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcc000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <0>; + label = "copss_cb0"; + }; + + copss_cb1: qcom,iommu-ctx@f9bcd000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcd000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <1>; + label = "copss_cb1"; + }; + + copss_usb: qcom,iommu-ctx@f9bce000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bce000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <2>; + label = "copss_usb"; + }; + + copss_cb3: qcom,iommu-ctx@f9bcf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcf000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <3>; + label = "copss_cb3"; + }; + + copss_cb4: qcom,iommu-ctx@f9bd0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd0000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <4>; + label = "copss_cb4"; + }; + + copss_cb5: qcom,iommu-ctx@f9bd1000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd1000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <5>; + label = "copss_cb5"; + }; + + copss_cb6: qcom,iommu-ctx@f9bd2000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd2000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <6>; + label = "copss_cb6"; + }; + + copss_cb_7: qcom,iommu-ctx@f9bd3000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd3000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <7>; + label = "copss_cb7"; + }; + }; + + vpu_iommu: qcom,iommu@fdee4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdee4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 147 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <7>; + label = "vpu_iommu"; + qcom,msm-bus,name = "vpu_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <93 512 0 0>, + <93 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0xffff + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x0 + 0x1e00 + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2000 + 0x2014>; + + qcom,iommu-lpae-bfb-data = <0xffff + 0x0 + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x1e00 + 0x5a2d + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x3 + 0x0>; + + + vpu_hlos: qcom,iommu-ctx@fdeec000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeec000 0x1000>; + interrupts = <0 145 0>; + qcom,iommu-ctx-sids = <0 1 3>; + label = "vpu_hlos"; + }; + + vpu_cp: qcom,iommu-ctx@fdeed000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeed000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <8 9>; + label = "vpu_cp"; + qcom,secure-context; + }; + + vpu_fw: qcom,iommu-ctx@fdeee000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeee000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <5 7 15>; + label = "vpu_fw"; + qcom,secure-context; + }; + }; + + lpass_qdsp_iommu: qcom,iommu@fe054000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe054000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 202 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <2>; + label = "lpass_qdsp_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x20 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x3 + 0x0>; + + + lpass_q6_fw: qcom,iommu-ctx@fe05c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05c000 0x1000>; + interrupts = <0 265 0>, <0 203 0>; + qcom,iommu-ctx-sids = <0 15>; + label = "q6_fw"; + qcom,secure-context; + }; + + lpass_audio_shared: qcom,iommu-ctx@fe05d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05d000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <1>; + label = "audio_shared"; + }; + + lpass_q6_spare1: qcom,iommu-ctx@fe05e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05e000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <2>; + label = "q6_spare1"; + }; + + lpass_q6_spare2: qcom,iommu-ctx@fe05f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05f000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare2"; + }; + }; + + lpass_core_iommu: qcom,iommu@fe064000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe064000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 166 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <6>; + label = "lpass_core_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0xc + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x3 + 0x0>; + + + lpass_core_image: qcom,iommu-ctx@fe06c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06c000 0x1000>; + interrupts = <0 267 0>, <0 180 0>; + qcom,iommu-ctx-sids = <11>; + label = "lpass_core_image"; + qcom,secure-context; + }; + + lpass_core_audio: qcom,iommu-ctx@fe06d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06d000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <12>; + label = "lpass_core_audio"; + }; + + lpass_core_slimbus: qcom,iommu-ctx@fe06e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06e000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <13>; + label = "lpass_core_slimbus"; + }; + }; + + vcap_iommu: qcom,iommu@fdfb6000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdfb6000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 315 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "vcap_iommu"; + status = "disabled"; + qcom,msm-bus,name = "vcap_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <48 512 0 0>, + <48 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2060>; + + qcom,iommu-bfb-data = <0x0ff + 0x00000004 + 0x00000008 + 0x0 + 0x0 + 0x00000008 + 0x00000028 + 0x0 + 0x001000 + 0x001000 + 0x003008 + 0x0 + 0x0 + 0x0 + 0x1555>; + + qcom,iommu-ctx@fdfbe000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbe000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <0>; + label = "vcap_cb0"; + }; + + qcom,iommu-ctx@fdfbf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbf000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <1>; + label = "vcap_cb1"; + }; + + qcom,iommu-ctx@fdfc0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfc0000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <>; + label = "vcap_cb2"; + }; + }; + + bcast_iommu: qcom,iommu@fc734000{ + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfc734000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 279 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "bcast_iommu"; + qcom,iommu-secure-id = <13>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2060>; + + qcom,iommu-bfb-data = <0xffffffff + 0x1 + 0x0000004 + 0x0000004 + 0x0 + 0x0 + 0x000055 + 0x0000d9 + 0x0 + 0x000aa00 + 0x0004200 + 0x000e821 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x1555>; + + bcast_cb0_hlos: qcom,iommu-ctx@fc73c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73c000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31>; + label = "bcast_cb0_hlos"; + }; + + bcast_cb1_cpz: qcom,iommu-ctx@fc73d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73d000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62>; + label = "bcast_cb1_cpz"; + qcom,secure-context; + }; + + bcast_cb2_demod: qcom,iommu-ctx@fc73e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73e000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <63>; + label = "bcast_cb2_demod"; + qcom,secure-context; + }; + + bcast_cb3_apz: qcom,iommu-ctx@fc73f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73f000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <>; + label = "bcast_cb3_apz"; + qcom,secure-context; + }; + }; + + fd_iommu: qcom,iommu@0xfd864000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd864000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 314 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "fd_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x00000007 + 0x1555 + 0x0 + 0x00000004 + 0x00000008 + 0x0601 + 0x1a0d + 0x0400 + 0x1a02 + 0x0 + 0x00000000 + 0x00000002 + 0x0000000a + 0x0>; + + qcom,iommu-ctx@fd86c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86c000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <0>; + label = "camera_fd"; + }; + + qcom,iommu-ctx@fd86d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86d000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_1"; + }; + + qcom,iommu-ctx@fd86e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86e000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_2"; + }; + }; + + cpp_iommu: qcom,iommu@0xfda84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda84000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 264 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "cpp_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c>; + + qcom,iommu-bfb-data = <0x00000003 + 0x3ff + 0x1555 + 0x0 + 0x00000004 + 0x10 + 0x1400 + 0x164b2 + 0x1400 + 0x1640a + 0x0 + 0x00000000 + 0x0000000a + 0x32 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8c000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp_0"; + }; + + qcom,iommu-ctx@fda8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8d000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_1"; + }; + + qcom,iommu-ctx@fda8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8e000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_2"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v2.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v2.dtsi new file mode 100755 index 0000000000000..2aa3828704d07 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-iommu-v2.dtsi @@ -0,0 +1,238 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gfx_iommu: qcom,iommu@1f00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1f00000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "gfx_iommu"; + qcom,iommu-secure-id = <18>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_gfx_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + status = "disabled"; + + qcom,iommu-ctx@1f09000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f09000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@1f0a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f0a000 0x1000>; + interrupts = <0 242 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + }; + + apps_iommu: qcom,iommu@1e00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1e00000 0x40000 + 0x1ef0000 0x3000>; + reg-names = "iommu_base", "smmu_local_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "apps_iommu"; + qcom,iommu-secure-id = <17>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_apss_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + qcom,cb-base-offset = <0x20000>; + status = "disabled"; + + qcom,iommu-ctx@1e22000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e22000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2000>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@1e23000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e23000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x400>; + label = "vfe"; + }; + + qcom,iommu-ctx@1e24000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e24000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xc00>; + label = "mdp_0"; + }; + + venus_ns: qcom,iommu-ctx@1e25000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e25000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x800 0x801 0x802 0x803 + 0x804 0x805 0x807>; + label = "venus_ns"; + }; + + qcom,iommu-ctx@1e26000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e26000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x402>; + label = "cpp"; + }; + + qcom,iommu-ctx@1e27000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e27000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1000>; + label = "mDSP"; + }; + + qcom,iommu-ctx@1e28000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e28000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1400>; + label = "gss"; + }; + + qcom,iommu-ctx@1e29000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e29000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1800>; + label = "a2"; + }; + + qcom,iommu-ctx@1e32000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e32000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0xc01>; + label = "mdp_1"; + }; + + venus_sec_pixel: qcom,iommu-ctx@1e33000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e33000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x885>; + label = "venus_sec_pixel"; + }; + + venus_sec_bitstream: qcom,iommu-ctx@1e34000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e34000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x880 0x881 0x882 0x883 0x884>; + label = "venus_sec_bitstream"; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@1e35000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e35000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x887 0x8a0>; + label = "venus_sec_non_pixel"; + }; + + venus_fw: qcom,iommu-ctx@1e36000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e36000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x8c0 0x8c6>; + label = "venus_fw"; + }; + + periph_rpm: qcom,iommu-ctx@1e37000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e37000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x40>; + label = "periph_rpm"; + }; + + qcom,iommu-ctx@1e38000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e38000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xC0 0xC4 0xC8 0xCC 0xD0 0xD3 + 0xD4 0xD7 0xD8 0xDB 0xDC 0xDF + 0xF0 0xF3 0xF4 0xF7 0xF8 0xFB + 0xFC 0xFF>; + label = "periph_CE"; + }; + + qcom,iommu-ctx@1e39000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e39000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x280 0x283 0x284 0x287 0x288 + 0x28B 0x28C 0x28F 0x290 0x293 + 0x294 0x297 0x298 0x29B 0x29C + 0x29F>; + label = "periph_BLSP"; + }; + + qcom,iommu-ctx@1e3a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3a000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x100>; + label = "periph_SDC1"; + }; + + qcom,iommu-ctx@1e3b000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3b000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x140>; + label = "periph_SDC2"; + }; + + qcom,iommu-ctx@1e3c000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1c0>; + label = "periph_audio"; + }; + + qcom,iommu-ctx@1e3d000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2c0>; + label = "periph_USB_HS1"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-pm8994-rpm-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-pm8994-rpm-regulator.dtsi new file mode 100755 index 0000000000000..8c32136aabd4b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-pm8994-rpm-regulator.dtsi @@ -0,0 +1,697 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + rpm-regulator-smpa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <3>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <4>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa5 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <5>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s5 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s5"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa7 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <7>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s7 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s7"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <2>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <3>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <4>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa6 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <6>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l6 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l6"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa8 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <8>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l8 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l8"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa9 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <9>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l9 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l9"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa10 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <10>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l10 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l10"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa11 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <11>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l11 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l11"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa12 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <12>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l12 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l12"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa13 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <13>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l13 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l13"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa14 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <14>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l14 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l14"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa15 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <15>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l15 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l15"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa16 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <16>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l16 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l16"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa17 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <17>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l17 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l17"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa18 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <18>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l18 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l18"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa19 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <19>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l19 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l19"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa20 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <20>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l20 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l20"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa21 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <21>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l21 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l21"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa22 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <22>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l22 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l22"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa23 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <23>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l23 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l23"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa24 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <24>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l24 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l24"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa25 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <25>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l25 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l25"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa26 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <26>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l26 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l26"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa27 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <27>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l27 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l27"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa28 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <28>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l28 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l28"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa29 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <29>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l29 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l29"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa30 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <30>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l30 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l30"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa31 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <31>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l31 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l31"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa32 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <32>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l32 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l32"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <2>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bstb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bstb"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-bst { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bbyb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bbyb"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + status = "disabled"; + + regulator-bby { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boostbypass"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpc2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpc"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-pm8994.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-pm8994.dtsi new file mode 100755 index 0000000000000..517c388718d72 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-pm8994.dtsi @@ -0,0 +1,576 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pm8994@0 { + spmi-slave-container; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + + pm8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,temp-alarm@2400 { + compatible = "qcom,qpnp-temp-alarm"; + reg = <0x2400 0x100>; + interrupts = <0x0 0x24 0x0>; + label = "pm8994_tz"; + qcom,channel-num = <8>; + qcom,threshold-set = <0>; + qcom,temp_alarm-vadc = <&pm8994_vadc>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + interrupts = <0x0 0x8 0x0>, + <0x0 0x8 0x1>, + <0x0 0x8 0x4>, + <0x0 0x8 0x5>; + interrupt-names = "kpdpwr", "resin", + "resin-bark", "kpdpwr-resin-bark"; + qcom,pon-dbc-delay = <15625>; + qcom,system-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + + qcom,pon_1 { + qcom,pon-type = <0>; + qcom,pull-up = <1>; + linux,code = <116>; + qcom,support-reset = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <6720>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_2 { + qcom,pon-type = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT + // comment out by yangrujin@bsp for vol_down is controled by gpio + //linux,code = <114>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_3 { + qcom,pon-type = <3>; + qcom,support-reset = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <6720>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + + qcom,use-bark; + }; + }; + + pm8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + + gpio@ca00 { + reg = <0xca00 0x100>; + qcom,pin-num = <11>; + status = "disabled"; + }; + + gpio@cb00 { + reg = <0xcb00 0x100>; + qcom,pin-num = <12>; + status = "disabled"; + }; + + gpio@cc00 { + reg = <0xcc00 0x100>; + qcom,pin-num = <13>; + status = "disabled"; + }; + + gpio@cd00 { + reg = <0xcd00 0x100>; + qcom,pin-num = <14>; + status = "disabled"; + }; + + gpio@ce00 { + reg = <0xce00 0x100>; + qcom,pin-num = <15>; + status = "disabled"; + }; + + gpio@cf00 { + reg = <0xcf00 0x100>; + qcom,pin-num = <16>; + status = "disabled"; + }; + + gpio@d000 { + reg = <0xd000 0x100>; + qcom,pin-num = <17>; + status = "disabled"; + }; + + gpio@d100 { + reg = <0xd100 0x100>; + qcom,pin-num = <18>; + status = "disabled"; + }; + + gpio@d200 { + reg = <0xd200 0x100>; + qcom,pin-num = <19>; + status = "disabled"; + }; + + gpio@d300 { + reg = <0xd300 0x100>; + qcom,pin-num = <20>; + status = "disabled"; + }; + + gpio@d500 { + reg = <0xd500 0x100>; + qcom,pin-num = <22>; + status = "disabled"; + }; + }; + + pm8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp02*/ + /* + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP2 as an Analog input to AMUX6 and read from channel 0x11 */ + mpp@a100 { /* MPP 2 */ + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <1>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH6 = 1*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4)*/ + /* + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + };*/ + /*#else VENDOR_EDIT*/ + /* Configure MPP4 as an Analog input to AMUX8 and read from channel 0x23 */ + mpp@a300 { /* MPP 4 */ + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 8 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4) end*/ + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp05*/ + /* + mpp@a400 { + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP5 as an Analog input to AMUX5 and read from channel 0x14 */ + mpp@a400 { /* MPP 5 */ + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <0>; /* AMUX 5 ,QPNP_PIN_AIN_AMUX_CH5 = 0*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a500 { + reg = <0xa500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + mpp@a600 { + reg = <0xa600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp08*/ + /* + mpp@a700 { + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP8 as an Analog input to AMUX8 and read from channel 0x17 */ + mpp@a700 { /* MPP 8 */ + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + }; + + pm8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x31 0x0>; + interrupt-names = "eoc-int-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + + chan@8 { + label = "die_temp"; + reg = <8>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <3>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@9 { + label = "ref_625mv"; + reg = <9>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@a { + label = "ref_1250v"; + reg = <0xa>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + /* VADC Channel configuration */ + chan@23 { + label = "cover_mpp4_div3"; + reg = <0x23>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; //Use 1:3 scaling to keep input voltage with in Max voltage: 1.8V + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /* //EVB2 floating,so use 1:1 chan + chan@13 { + label = "cover_mpp4_div3"; + reg = <0x13>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + };*/ + /*#endif VENDOR_EDIT*/ + + +/*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + /* VADC Channel configuration */ + chan@76 { + label = "pcb_version_AMUX_HW_ID"; + reg = <0x76>;//pcb_version_AMUX_HW_ID channel 54 + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; //Use 1:1 scaling to keep input voltage with in Max voltage: 1.8V + //qcom,calibration-type = "ratiometric"; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@11 { + label = "rf_mpp2"; + reg = <0x11>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@14 { + label = "rf_mpp5"; + reg = <0x14>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@17 { + label = "rf_mpp8"; + reg = <0x17>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#endif VENDOR_EDIT*/ + }; + + pm8994_adc_tm: vadc@3400 { + compatible = "qcom,qpnp-adc-tm"; + reg = <0x3400 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x34 0x0>, + <0x0 0x34 0x3>, + <0x0 0x34 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,adc_tm-vadc = <&pm8994_vadc>; + }; + + pm8994_coincell: qcom,coincell@2800 { + compatible = "qcom,qpnp-coincell"; + reg = <0x2800 0x100>; + }; + + qcom,pm8994_rtc { + spmi-dev-container; + compatible = "qcom,qpnp-rtc"; + #address-cells = <1>; + #size-cells = <1>; + qcom,qpnp-rtc-write = <0>; + /*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + qcom,qpnp-rtc-alarm-pwrup = <1>; + /*#endif VENDOR_EDIT*/ + + qcom,pm8994_rtc_rw@6000 { + reg = <0x6000 0x100>; + }; + qcom,pm8994_rtc_alarm@6100 { + reg = <0x6100 0x100>; + interrupts = <0x0 0x61 0x1>; + }; + }; + }; + + qcom,pm8994@1 { + spmi-slave-container; + reg = <0x1>; + #address-cells = <1>; + #size-cells = <1>; + + pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b500 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb500 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <4>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <4>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b600 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb600 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <5>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <5>; + #pwm-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-pmi8994.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-pmi8994.dtsi new file mode 100755 index 0000000000000..f7fbc86e1c32c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-pmi8994.dtsi @@ -0,0 +1,741 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pmi8994@2 { + spmi-slave-container; + reg = <0x2>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + qcom,secondary-pon-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + }; + + pmi8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + }; + + pmi8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + }; +//#ifdef VENDOR_EDIT /* shankai@BSP.driver, 2015/3/25, add for the button-backlight */ + qcom,leds@a300 { + compatible = "qcom,leds-qpnp"; + status = "okay"; + reg=<0xa300 0x100>; + qcom,led_mpp_3 { + label = "mpp"; + linux,name = "button-backlight"; + linux,default-trigger = "none"; + qcom,default-state = "off"; + qcom,max-current = <40>; + qcom,current-setting = <5>; + qcom,id = <6>; + qcom,mode = "manual"; + qcom,source-sel = <1>; + qcom,mode-ctrl = <0x60>; + }; + }; +//#endif /*VENDOR_EDIT*/ + + + + bcl@4200 { + compatible = "qcom,msm-bcl"; + reg = <0x4200 0xFF 0x88E 0x2>; + reg-names = "fg_user_adc", "pon_spare"; + interrupts = <0x2 0x42 0x0>, + <0x2 0x42 0x1>; + interrupt-names = "bcl-high-ibat-int", + "bcl-low-vbat-int"; + qcom,vbat-scaling-factor = <39000>; + qcom,vbat-gain-numerator = <1>; + qcom,vbat-gain-denominator = <128>; + qcom,vbat-polling-delay-ms = <100>; + qcom,ibat-scaling-factor = <39000>; + qcom,ibat-gain-numerator = <1>; + qcom,ibat-gain-denominator = <128>; + qcom,ibat-offset-numerator = <1200>; + qcom,ibat-offset-denominator = <1>; + qcom,ibat-polling-delay-ms = <100>; + qcom,inhibit-derating-ua = <550000>; + }; + + pmi8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x2 0x31 0x0>, + <0x2 0x31 0x3>, + <0x2 0x31 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + qcom,vadc-meas-int-mode; + }; + + pmi8994_charger: qcom,qpnp-smbcharger { + spmi-dev-container; + compatible = "qcom,qpnp-smbcharger"; + #address-cells = <1>; + #size-cells = <1>; + + qcom,iterm-ma = <150>; + qcom,fastchg-current-ma = <1910>; + qcom,float-voltage-mv = <4320>; + qcom,resume-delta-mv = <100>; + // qcom,chg-inhibit-en; + qcom,chg-inhibit-fg; + qcom,dc-psy-type = "Mains"; + qcom,dc-psy-ma = <1500>; + qcom,rparasitic-uohm = <100000>; + qcom,bms-psy-name = "bms"; + qcom,thermal-mitigation = <2000 1000 900 800>; + qcom,parallel-usb-min-current-ma = <1400>; + qcom,parallel-usb-9v-min-current-ma = <900>; + qcom,parallel-allowed-lowering-ma = <500>; + qcom,autoadjust-vfloat; + qcom,charge-unknown-battery; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x2 0x10 0x0>, + <0x2 0x10 0x1>, + <0x2 0x10 0x2>, + <0x2 0x10 0x3>, + <0x2 0x10 0x4>, + <0x2 0x10 0x5>, + <0x2 0x10 0x6>, + <0x2 0x10 0x7>; + + interrupt-names = "chg-error", + "chg-inhibit", + "chg-prechg-sft", + "chg-complete-chg-sft", + "chg-p2f-thr", + "chg-rechg-thr", + "chg-taper-thr", + "chg-tcc-thr"; + }; + + qcom,otg@1100 { + reg = <0x1100 0x100>; + }; + + qcom,bat-if@1200 { + reg = <0x1200 0x100>; + interrupts = <0x2 0x12 0x0>, + <0x2 0x12 0x1>, + <0x2 0x12 0x2>, + <0x2 0x12 0x3>, + <0x2 0x12 0x4>, + <0x2 0x12 0x5>, + <0x2 0x12 0x6>, + <0x2 0x12 0x7>; + + interrupt-names = "batt-hot", + "batt-warm", + "batt-cold", + "batt-cool", + "batt-ov", + "batt-low", + "batt-missing", + "batt-term-missing"; + }; + + qcom,usb-chgpth@1300 { + reg = <0x1300 0x100>; + interrupts = <0x2 0x13 0x0>, + <0x2 0x13 0x1>, + <0x2 0x13 0x2>, + <0x2 0x13 0x3>, + <0x2 0x13 0x4>, + <0x2 0x13 0x5>, + <0x2 0x13 0x6>; + + interrupt-names = "usbin-uv", + "usbin-ov", + "usbin-src-det", + "otg-fail", + "otg-oc", + "aicl-done", + "usbid-change"; + }; + + qcom,dc-chgpth@1400 { + reg = <0x1400 0x100>; + interrupts = <0x2 0x14 0x0>, + <0x2 0x14 0x1>; + + interrupt-names = "dcin-uv", + "dcin-ov"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x2 0x16 0x0>, + <0x2 0x16 0x1>, + <0x2 0x16 0x2>, + <0x2 0x16 0x3>, + <0x2 0x16 0x4>, + <0x2 0x16 0x5>; + + interrupt-names = "power-ok", + "temp-shutdown", + "safety-timeout", + "flash-fail", + "otst2", + "otst3"; + }; + }; + + pmi8994_fg: qcom,fg { + spmi-dev-container; + compatible = "qcom,qpnp-fg"; + #address-cells = <1>; + #size-cells = <1>; + //qcom,resume-soc = <95>; + qcom,resume-soc = <99>; + status = "okay"; + qcom,bcl-lm-threshold-ma = <127>; + qcom,bcl-mh-threshold-ma = <405>; + qcom,fg-chg-iterm-ma = <150>; + qcom,cycle-counter-en; + qcom,cycle-counter-low-soc = <15>; + qcom,cycle-counter-high-soc = <85>; + qcom,capacity-learning-on; + qcom,fg-cc-cv-threshold-mv = <4310>; + qcom,fg-iterm-ma = <200>; + qcom,fg-cutoff-voltage-mv=<3500>; + qcom,pmic-revid = <&pmi8994_revid>; + + qcom,thermal-coefficients = [da 86 f0 50 08 3c]; + qcom,fg-soc@4000 { + status = "okay"; + reg = <0x4000 0x100>; + interrupts = <0x2 0x40 0x0>, + <0x2 0x40 0x1>, + <0x2 0x40 0x2>, + <0x2 0x40 0x3>, + <0x2 0x40 0x4>, + <0x2 0x40 0x5>, + <0x2 0x40 0x6>, + <0x2 0x40 0x7>; + + interrupt-names = "high-soc", + "low-soc", + "full-soc", + "empty-soc", + "delta-soc", + "first-est-done", + "sw-fallbk-ocv", + "sw-fallbk-new-battrt-sts", + "fg-soc-irq-count"; + }; + + qcom,fg-batt@4100 { + reg = <0x4100 0x100>; + interrupts = <0x2 0x41 0x0>, + <0x2 0x41 0x1>, + <0x2 0x41 0x2>, + <0x2 0x41 0x3>, + <0x2 0x41 0x4>, + <0x2 0x41 0x5>, + <0x2 0x41 0x6>, + <0x2 0x41 0x7>; + + interrupt-names = "soft-cold", + "soft-hot", + "vbatt-low", + "batt-ided", + "batt-id-req", + "batt-unknown", + "batt-missing", + "batt-match"; + }; + + qcom,fg-adc-vbat@4254 { + reg = <0x4254 0x1>; + }; + + qcom,fg-adc-ibat@4255 { + reg = <0x4255 0x1>; + }; + + qcom,revid-tp-rev@1f1 { + reg = <0x1f1 0x1>; + }; + + qcom,fg-memif@4400 { + status = "okay"; + reg = <0x4400 0x100>; + interrupts = <0x2 0x44 0x0>, + <0x2 0x44 0x1>; + + interrupt-names = "mem-avail", + "data-rcvry-sug"; + }; + }; + }; + + qcom,pmi8994@3 { + spmi-slave-container; + reg = <0x3>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_pwm_1: pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_2: pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_3: pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_4: pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + }; + + labibb: qpnp-labibb-regulator { + status = "disabled"; + spmi-dev-container; + compatible = "qcom,qpnp-labibb-regulator"; + #address-cells = <1>; + #size-cells = <1>; + + lab_regulator: qcom,lab@de00 { + reg = <0xde00 0x100>; + reg-names = "lab"; + regulator-name = "lab_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-lab-min-voltage = <4600000>; + qcom,qpnp-lab-step-size = <100000>; + qcom,qpnp-lab-slew-rate = <5000>; + qcom,qpnp-lab-use-default-voltage; + qcom,qpnp-lab-init-voltage = <5500000>; + qcom,qpnp-lab-init-amoled-voltage = <4600000>; + qcom,qpnp-lab-init-lcd-voltage = <5500000>; + + qcom,qpnp-lab-soft-start = <800>; + + qcom,qpnp-lab-full-pull-down; + qcom,qpnp-lab-pull-down-enable; + qcom,qpnp-lab-switching-clock-frequency = <1600>; + qcom,qpnp-lab-limit-maximum-current = <800>; + qcom,qpnp-lab-limit-max-current-enable; + qcom,qpnp-lab-ps-threshold = <20>; + qcom,qpnp-lab-ps-enable; + qcom,qpnp-lab-nfet-size = <100>; + qcom,qpnp-lab-pfet-size = <100>; + qcom,qpnp-lab-max-precharge-time = <200>; + }; + + ibb_regulator: qcom,ibb@dc00 { + reg = <0xdc00 0x100>; + reg-names = "ibb_reg"; + regulator-name = "ibb_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-ibb-min-voltage = <1400000>; + qcom,qpnp-ibb-step-size = <100000>; + qcom,qpnp-ibb-slew-rate = <2000000>; + qcom,qpnp-ibb-use-default-voltage; + qcom,qpnp-ibb-init-voltage = <5500000>; + qcom,qpnp-ibb-init-amoled-voltage = <4000000>; + qcom,qpnp-ibb-init-lcd-voltage = <5500000>; + + qcom,qpnp-ibb-soft-start = <1000>; + + qcom,qpnp-ibb-discharge-resistor = <300>; + qcom,qpnp-ibb-lab-pwrup-delay = <4000>; + qcom,qpnp-ibb-lab-pwrdn-delay = <4000>; + qcom,qpnp-ibb-en-discharge; + + qcom,qpnp-ibb-full-pull-down; + qcom,qpnp-ibb-pull-down-enable; + qcom,qpnp-ibb-switching-clock-frequency = <1480>; + qcom,qpnp-ibb-limit-maximum-current = <1550>; + qcom,qpnp-ibb-debounce-cycle = <16>; + qcom,qpnp-ibb-limit-max-current-enable; + qcom,qpnp-ibb-ps-enable; + }; + + }; + + qcom,leds@d800 { + compatible = "qcom,qpnp-wled"; + reg = <0xd800 0x100>, + <0xd900 0x100>, + <0xdc00 0x100>, + <0xde00 0x100>; + reg-names = "qpnp-wled-ctrl-base", + "qpnp-wled-sink-base", + "qpnp-wled-ibb-base", + "qpnp-wled-lab-base"; + interrupts = <0x3 0xd8 0x2>; + interrupt-names = "sc-irq"; + status = "okay"; + linux,name = "wled"; + linux,default-trigger = "bkl-trigger"; + qcom,fdbk-output = "auto"; + qcom,vref-mv = <350>; + qcom,switch-freq-khz = <800>; + qcom,ovp-mv = <29500>; + qcom,ilim-ma = <980>; + qcom,boost-duty-ns = <26>; + qcom,mod-freq-khz = <9600>; + qcom,dim-mode = "hybrid"; + qcom,dim-method = "linear"; + qcom,hyb-thres = <625>; + qcom,sync-dly-us = <800>; + qcom,fs-curr-ua = <20000>;//guozhimig@oem add 2015-04-02 for adiudt backlight 20mA + qcom,en-phase-stag; + qcom,ibb-pwrup-dly = <8>; + qcom,led-strings-list = [00 01];//two WLED SINK/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,en-ext-pfet-sc-pro; + qcom,en-cabc;//guozhimig@oem add 2015-04-02 for en cabc + }; + +//#ifdef VENDOR_EDIT // shankai@bsp, 2015-4-4 do not use it ,comment it. +/* + pmi8994_haptics: qcom,haptic@c000 { + status = "disabled"; + compatible = "qcom,qpnp-haptic"; + reg = <0xc000 0x100>; + interrupts = <0x3 0xc0 0x0>, + <0x3 0xc0 0x1>; + interrupt-names = "sc-irq", "play-irq"; + qcom,play-mode = "direct"; + qcom,wave-play-rate-us = <5263>; + qcom,actuator-type = "lra"; + qcom,wave-shape = "square"; + qcom,vmax-mv = <2000>; + qcom,ilim-ma = <800>; + qcom,sc-deb-cycles = <8>; + qcom,int-pwm-freq-khz = <505>; + qcom,en-brake; + qcom,brake-pattern = [03 03 00 00]; + qcom,use-play-irq; + qcom,use-sc-irq; + qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e]; + qcom,wave-rep-cnt = <1>; + qcom,wave-samp-rep-cnt = <1>; + }; +*/ +//#endif + qcom,leds@d000 { + compatible = "qcom,leds-qpnp"; + reg = <0xd000 0x100>; + label = "rgb"; + status = "okay"; + + /*#ifndef VENDOR_EDIT //shankai@bsp.driver 2015-02-26 modify for rgb blink feature*/ + qcom,rgb_0 { + label = "rgb"; + qcom,id = <3>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_3 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <1>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "red"; + /*linux,default-trigger = + "battery-charging";*/ + qcom,use-blink; + }; + + qcom,rgb_1 { + label = "rgb"; + qcom,id = <4>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_2 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + /* + qcom,duty-pcts = [00 05 0A 0f 14 19 1d 23 28 2c + 32 37 3b 41 45 4a 50 55 5a 64]; + */ + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "green"; + /*linux,default-trigger = "battery-full";*/ + qcom,use-blink; + }; + + qcom,rgb_2 { + label = "rgb"; + qcom,id = <5>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_1 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + qcom,default-state = "off"; + linux,name = "blue"; + qcom,use-blink; + linux,default-trigger = "boot-indication"; + }; + /*#end VENDOR_EDIT*/ + }; + + qcom,leds@d300 { + compatible = "qcom,qpnp-flash-led"; + status = "okay"; + reg = <0xd300 0x100>; + label = "flash"; + qcom,headroom = <500>; + qcom,startup-dly = <128>; + qcom,clamp-curr = <200>; + qcom,pmic-charger-support; + qcom,self-check-enabled; + qcom,thermal-derate-enabled; + qcom,thermal-derate-threshold = <100>; + qcom,thermal-derate-rate = "5_PERCENT"; + qcom,current-ramp-enabled; + qcom,ramp_up_step = "6P7_US"; + qcom,ramp_dn_step = "6P7_US"; + qcom,vph-pwr-droop-enabled; + qcom,vph-pwr-droop-threshold = <3000>; + qcom,vph-pwr-droop-debounce-time = <10>; + qcom,headroom-sense-ch0-enabled; + qcom,headroom-sense-ch1-enabled; + qcom,power-detect-enabled; + + pmi8994_flash0: qcom,flash_0 { + label = "flash"; + qcom,led-name = "led:flash_0"; + qcom,default-led-trigger = + "flash0_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <0>; + qcom,current = <625>; + }; + + pmi8994_flash1: qcom,flash_1 { + label = "flash"; + qcom,led-name = "led:flash_1"; + qcom,default-led-trigger = + "flash1_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <1>; + qcom,current = <625>; + }; + + pmi8994_torch0: qcom,torch_0 { + label = "torch"; + qcom,led-name = "led:torch_0"; + qcom,default-led-trigger = + "torch0_trigger"; + qcom,max-current = <200>; + qcom,id = <0>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + + pmi8994_torch1: qcom,torch_1 { + label = "torch"; + qcom,led-name = "led:torch_1"; + qcom,default-led-trigger = + "torch1_trigger"; + qcom,max-current = <200>; + qcom,id = <1>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm-rdbg.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm-rdbg.dtsi new file mode 100755 index 0000000000000..f7f52bed111c6 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm-rdbg.dtsi @@ -0,0 +1,75 @@ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + smp2pgpio_rdbg_2_in: qcom,smp2pgpio-rdbg-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_in { + compatible = "qcom,smp2pgpio_client_rdbg_2_in"; + gpios = <&smp2pgpio_rdbg_2_in 0 0>; + }; + + smp2pgpio_rdbg_2_out: qcom,smp2pgpio-rdbg-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_out { + compatible = "qcom,smp2pgpio_client_rdbg_2_out"; + gpios = <&smp2pgpio_rdbg_2_out 0 0>; + }; + + smp2pgpio_rdbg_1_in: qcom,smp2pgpio-rdbg-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_in { + compatible = "qcom,smp2pgpio_client_rdbg_1_in"; + gpios = <&smp2pgpio_rdbg_1_in 0 0>; + }; + + smp2pgpio_rdbg_1_out: qcom,smp2pgpio-rdbg-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_out { + compatible = "qcom,smp2pgpio_client_rdbg_1_out"; + gpios = <&smp2pgpio_rdbg_1_out 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-bus.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-bus.dtsi new file mode 100755 index 0000000000000..6b77e2a0488e4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-bus.dtsi @@ -0,0 +1,1597 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + ad_hoc_bus: ad-hoc-bus@fc460000 { + compatible = "qcom,msm-bus-device"; + reg = <0xFC460000 0x5880>, + <0xFC380000 0x80000>, + <0xFC468000 0x2400>, + <0xFC478000 0x3480>, + <0xFC480000 0x80>; + reg-names = "snoc-base", "bimc-base", "pnoc-base", "mnoc-base", "cnoc-base"; + + fab_snoc: fab-snoc { + cell-id = ; + label = "fab-snoc"; + qcom,fab-dev; + qcom,base-name = "snoc-base"; + qcom,base-offset = <0x5000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_snoc_msmbus_clk>, + <&clock_rpm clk_snoc_msmbus_a_clk>; + + coresight-id = <50>; + coresight-name = "coresight-snoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <3>; + }; + + fab_bimc: fab-bimc { + cell-id = ; + label = "fab-bimc"; + qcom,fab-dev; + qcom,base-name = "bimc-base"; + qcom,bus-type = <2>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_bimc_msmbus_clk>, + <&clock_rpm clk_bimc_msmbus_a_clk>; + + coresight-id = <55>; + coresight-name = "coresight-bimc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <3>; + }; + + fab_pnoc: fab-pnoc { + cell-id = ; + label = "fab-pnoc"; + qcom,fab-dev; + qcom,base-name = "pnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_pnoc_msmbus_clk>, + <&clock_rpm clk_pnoc_msmbus_a_clk>; + + coresight-id = <54>; + coresight-name = "coresight-pnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <6>; + }; + + fab_mnoc: fab-mnoc { + cell-id = ; + label = "fab-mnoc"; + qcom,fab-dev; + qcom,base-name = "mnoc-base"; + qcom,base-offset = <0x3000>; + qcom,bus-type = <1>; + qcom,qos-off = <0x80>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_mmss clk_mmss_s0_axi_clk>, + <&clock_mmss clk_mmss_s0_axi_clk>; + + coresight-id = <56>; + coresight-name = "coresight-mmnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <5>; + }; + + fab_cnoc: fab-cnoc { + cell-id = ; + label = "fab-cnoc"; + qcom,fab-dev; + qcom,base-name = "cnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_cnoc_msmbus_clk>, + <&clock_rpm clk_cnoc_msmbus_a_clk>; + }; + + fab_ovirt: fab-ovirt { + cell-id = ; + label = "fab-ovirt"; + qcom,fab-dev; + qcom,bypass-qos-prg; + qcom,virt-dev; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_ocmemgx_msmbus_clk>, + <&clock_rpm clk_ocmemgx_msmbus_a_clk >; + }; + + + /* bimc Devices */ + mas_apps_proc: mas-apps-proc { + cell-id = ; + label = "mas-apps-proc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&bimc_int_apps_ebi &bimc_int_apps_snoc>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ws = <10000>; + qcom,gp = <5000>; + qcom,thmp = <50>; + qcom,ap-owned; + }; + + bimc_int_apps_ebi: bimc-int-apps-ebi { + cell-id = ; + label = "bimc-int-apps-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_ebi>; + }; + + bimc_int_apps_snoc: bimc-int-apps-snoc { + cell-id = ; + label = "bimc-int-apps-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,connections = <&slv_bimc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_oxili: mas-oxili { + cell-id = ; + label = "mas-oxili"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <2>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ap-owned; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + }; + + + mas_mnoc_bimc: mas-mnoc-bimc { + cell-id = ; + label = "mas-mnoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + qcom,ap-owned; + }; + + + mas_snoc_bimc: mas-snoc-bimc { + cell-id = ; + label = "mas-snoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2>; + qcom,mas-rpm-id = ; + }; + + + slv_ebi: slv-ebi { + cell-id = ; + label = "slv-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <0 1>; + qcom,slv-rpm-id = ; + }; + + + slv_appss_l2: slv-appss-l2 { + cell-id = ; + label = "slv-appss-l2"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_snoc: slv-bimc-snoc { + cell-id = ; + label = "slv-bimc-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_bimc_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* mnoc Devices */ + mas_cnoc_mnoc_mmss_cfg: mas-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_camera_cfg &slv_cpr_cfg &slv_cpr_xpu_cfg + &slv_ocmem_cfg &slv_misc_cfg &slv_misc_xpu_cfg + &slv_oxili_cfg &slv_venus_cfg &slv_mnoc_clocks_cfg + &slv_mnoc_clocks_xpu_cfg &slv_mnoc_mpu_cfg &slv_display_cfg + &slv_avsync_cfg &slv_vpu_cfg>; + qcom,ap-owned; + }; + + + mas_cnoc_mnoc_cfg: mas-cnoc-mnoc-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_srvc_mnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_gemini: mas-gemini { + cell-id = ; + label = "mas-gemini"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <0>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p0: mas-mdp-p0 { + cell-id = ; + label = "mas-mdp-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <2>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p1: mas-mdp-p1 { + cell-id = ; + label = "mas-mdp-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <1>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p0: mas-venus-p0 { + cell-id = ; + label = "mas-venus-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p1: mas-venus-p1 { + cell-id = ; + label = "mas-venus-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_vfe: mas-vfe { + cell-id = ; + label = "mas-vfe"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <6>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_cpp: mas-cpp { + cell-id = ; + label = "mas-cpp"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <5>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_vpu: mas-vpu { + cell-id = ; + label = "mas-vpu"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qos-mode = "bypass"; + qcom,qport = <8>; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_camera_cfg: slv-camera-cfg { + cell-id = ; + label = "slv-camera-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_cfg: slv-cpr-cfg { + cell-id = ; + label = "slv-cpr-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_xpu_cfg: slv-cpr-xpu-cfg { + cell-id = ; + label = "slv-cpr-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_ocmem_cfg: slv-ocmem-cfg { + cell-id = ; + label = "slv-ocmem-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_cfg: slv-misc-cfg { + cell-id = ; + label = "slv-misc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_xpu_cfg: slv-misc-xpu-cfg { + cell-id = ; + label = "slv-misc-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_oxili_cfg: slv-oxili-cfg { + cell-id = ; + label = "slv-oxili-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_venus_cfg: slv-venus-cfg { + cell-id = ; + label = "slv-venus-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_cfg: slv-mnoc-clocks-cfg { + cell-id = ; + label = "slv-mnoc-clocks-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_xpu_cfg: slv-mnoc-clocks-xpu-cfg { + cell-id = ; + label = "slv-mnoc-clocks-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_mpu_cfg: slv-mnoc-mpu-cfg { + cell-id = ; + label = "slv-mnoc-mpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_display_cfg: slv-display-cfg { + cell-id = ; + label = "slv-display-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_avsync_cfg: slv-avsync-cfg { + cell-id = ; + label = "slv-avsync-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_vpu_cfg: slv-vpu-cfg { + cell-id = ; + label = "slv-vpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_bimc: slv-mnoc-bimc { + cell-id = ; + label = "slv-mnoc-bimc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <16 17>; + qcom,connections = <&mas_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_srvc_mnoc: slv-srvc-mnoc { + cell-id = ; + label = "slv-srvc-mnoc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + /* snoc Devices */ + mas_lpass_ahb: mas-lpass-ahb { + cell-id = ; + label = "mas-lpass-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_ocimem &slv_snoc_pnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_bam: mas-qdss-bam { + cell-id = ; + label = "mas-qdss-bam"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <1>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc &slv_usb3>; + qcom,ap-owned; + }; + + + mas_bimc_snoc: mas-bimc-snoc { + cell-id = ; + label = "mas-bimc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_cnoc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + mas_cnoc_snoc: mas-cnoc-snoc { + cell-id = ; + label = "mas-cnoc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_crypto_c0: mas-crypto-c0 { + cell-id = ; + label = "mas-crypto-c0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <2>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c1: mas-crypto-c1 { + cell-id = ; + label = "mas-crypto-c1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <3>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c2: mas-crypto-c2 { + cell-id = ; + label = "mas-crypto-c2"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <9>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_lpass_proc: mas-lpass-proc { + cell-id = ; + label = "mas-lpass-proc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_ovirt_snoc: mas-ovirt-snoc { + cell-id = ; + label = "mas-ovirt-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <5>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc>; + qcom,mas-rpm-id = ; + }; + + + mas_periph_snoc: mas-periph-snoc { + cell-id = ; + label = "mas-periph-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <13>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_lpass &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_pcie_0: mas-pcie-0 { + cell-id = ; + label = "mas-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <7>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_pcie_1: mas-pcie-1 { + cell-id = ; + label = "mas-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <16>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_qdss_etr: mas-qdss-etr { + cell-id = ; + label = "mas-qdss-etr"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ufs: mas-ufs { + cell-id = ; + label = "mas-ufs"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt>; + qcom,ap-owned; + }; + + + mas_usb3: mas-usb3 { + cell-id = ; + label = "mas-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_snoc_cnoc &slv_ocimem &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ipa: mas-ipa { + cell-id = ; + label = "mas-ipa"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <15>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_usb3 &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_pcie_0 &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + slv_kpss_ahb: slv-kpss-ahb { + cell-id = ; + label = "slv-kpss-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_lpass: slv-lpass { + cell-id = ; + label = "slv-lpass"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_bimc: slv-snoc-bimc { + cell-id = ; + label = "slv-snoc-bimc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_bimc>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cnoc: slv-snoc-cnoc { + cell-id = ; + label = "slv-snoc-cnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_cnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_ocimem: slv-ocimem { + cell-id = ; + label = "slv-ocimem"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_ovirt: slv-snoc-ovirt { + cell-id = ; + label = "slv-snoc-ovirt"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_ovirt>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_pnoc: slv-snoc-pnoc { + cell-id = ; + label = "slv-snoc-pnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_pnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_stm: slv-qdss-stm { + cell-id = ; + label = "slv-qdss-stm"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + slv_usb3: slv-usb3 { + cell-id = ; + label = "slv-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0: slv-pcie-0 { + cell-id = ; + label = "slv-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1: slv-pcie-1 { + cell-id = ; + label = "slv-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + /* ovirt Devices */ + mas_snoc_ovirt: mas-snoc-ovirt { + cell-id = ; + label = "mas-snoc-ovirt"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + mas_ocmem_dma: mas-ocmem-dma { + cell-id = ; + label = "mas-ocmem-dma"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem &slv_ovirt_snoc>; + qcom,ap-owned; + }; + + + mas_oxili_ocmem: mas-oxili-ocmem { + cell-id = ; + label = "mas-oxili-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem_gfx>; + qcom,ap-owned; + }; + + + mas_venus_ocmem: mas-venus-ocmem { + cell-id = ; + label = "mas-venus-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + slv_ocmem: slv-ocmem { + cell-id = ; + label = "slv-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <16>; + qcom,ap-owned; + clock-names = "node_clk"; + clocks = <&clock_mmss clk_ocmemnoc_clk_src>; + }; + + slv_ocmem_gfx: slv-ocmem-gfx { + cell-id = ; + label = "slv-ocmem-gfx"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + }; + + + slv_ovirt_snoc: slv-ovirt-snoc { + cell-id = ; + label = "slv-ovirt-snoc"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&mas_ovirt_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* pnoc Devices */ + mas_bam_dma: mas-bam-dma { + cell-id = ; + label = "mas-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_sdcc_1 &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_2: mas-blsp-2 { + cell-id = ; + label = "mas-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_1: mas-blsp-1 { + cell-id = ; + label = "mas-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tsif: mas-tsif { + cell-id = ; + label = "mas-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_usb_hs: mas-usb-hs { + cell-id = ; + label = "mas-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_tsif &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_pnoc_cfg: mas-pnoc-cfg { + cell-id = ; + label = "mas-pnoc-cfg"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_prng>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_1: mas-sdcc-1 { + cell-id = ; + label = "mas-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_2: mas-sdcc-2 { + cell-id = ; + label = "mas-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_3: mas-sdcc-3 { + cell-id = ; + label = "mas-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_4: mas-sdcc-4 { + cell-id = ; + label = "mas-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_pnoc: mas-snoc-pnoc { + cell-id = ; + label = "mas-snoc-pnoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 + &slv_blsp_2 &slv_blsp_1 &slv_tsif &slv_usb_hs + &slv_pdm &slv_prng>; + qcom,mas-rpm-id = ; + }; + + + slv_bam_dma: slv-bam-dma { + cell-id = ; + label = "slv-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_1: slv-sdcc-1 { + cell-id = ; + label = "slv-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_3: slv-sdcc-3 { + cell-id = ; + label = "slv-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_2: slv-blsp-2 { + cell-id = ; + label = "slv-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_2: slv-sdcc-2 { + cell-id = ; + label = "slv-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_4: slv-sdcc-4 { + cell-id = ; + label = "slv-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_1: slv-blsp-1 { + cell-id = ; + label = "slv-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tsif: slv-tsif { + cell-id = ; + label = "slv-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_usb_hs: slv-usb-hs { + cell-id = ; + label = "slv-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pdm: slv-pdm { + cell-id = ; + label = "slv-pdm"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_prng: slv-prng { + cell-id = ; + label = "slv-prng"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_periph_snoc: slv-periph-snoc { + cell-id = ; + label = "slv-periph-snoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_periph_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* cnoc Devices */ + mas_rpm_inst: mas-rpm-inst { + cell-id = ; + label = "mas-rpm-inst"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_boot_rom>; + qcom,mas-rpm-id = ; + }; + + + mas_rpm_sys: mas-rpm-sys { + cell-id = ; + label = "mas-rpm-sys"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg + &slv_security &slv_tcsr &slv_tlmm &slv_crypto_0_cfg + &slv_crypto_1_cfg &slv_imem_cfg &slv_message_ram + &slv_bimc_cfg &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper + &slv_dehr_cfg &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg + &slv_snoc_cfg &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg + &slv_phy_apu_cfg &slv_ebi1_phy_cfg &slv_pcie_0_cfg + &slv_pcie_1_cfg &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_dehr: mas-dehr { + cell-id = ; + label = "mas-dehr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bimc_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_spdm: mas-spdm { + cell-id = ; + label = "mas-spdm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tic: mas-tic { + cell-id = ; + label = "mas-tic"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_cnoc: mas-snoc-cnoc { + cell-id = ; + label = "mas-snoc-cnoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_dap: mas-qdss-dap { + cell-id = ; + label = "mas-qdss-dap"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + slv_clk_ctl: slv-clk-ctl { + cell-id = ; + label = "slv-clk-ctl"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_2_cfg: slv-crypto-2-cfg { + cell-id = ; + label = "slv-crypto-2-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_security: slv-security { + cell-id = ; + label = "slv-security"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tcsr: slv-tcsr { + cell-id = ; + label = "slv-tcsr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tlmm: slv-tlmm { + cell-id = ; + label = "slv-tlmm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_0_cfg: slv-crypto-0-cfg { + cell-id = ; + label = "slv-crypto-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_1_cfg: slv-crypto-1-cfg { + cell-id = ; + label = "slv-crypto-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_imem_cfg: slv-imem-cfg { + cell-id = ; + label = "slv-imem-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_message_ram: slv-message-ram { + cell-id = ; + label = "slv-message-ram"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_cfg: slv-bimc-cfg { + cell-id = ; + label = "slv-bimc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_boot_rom: slv-boot-rom { + cell-id = ; + label = "slv-boot-rom"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_mmss_cfg: slv-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_mmss_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pmic_arb: slv-pmic-arb { + cell-id = ; + label = "slv-pmic-arb"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spdm_wrapper: slv-spdm-wrapper { + cell-id = ; + label = "slv-spdm-wrapper"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_dehr_cfg: slv-dehr-cfg { + cell-id = ; + label = "slv-dehr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_mpm: slv-mpm { + cell-id = ; + label = "slv-mpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_cfg: slv-qdss-cfg { + cell-id = ; + label = "slv-qdss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_qdss_apu_cfg: slv-rbcpr-qdss-apu-cfg { + cell-id = ; + label = "slv-rbcpr-qdss-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_cfg: slv-rbcpr-cfg { + cell-id = ; + label = "slv-rbcpr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_cfg: slv-cnoc-mnoc-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pnoc_cfg: slv-pnoc-cfg { + cell-id = ; + label = "slv-pnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_pnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cfg: slv-snoc-cfg { + cell-id = ; + label = "slv-snoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_mpu_cfg: slv-snoc-mpu-cfg { + cell-id = ; + label = "slv-snoc-mpu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_dll_cfg: slv-ebi1-dll-cfg { + cell-id = ; + label = "slv-ebi1-dll-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_phy_apu_cfg: slv-phy-apu-cfg { + cell-id = ; + label = "slv-phy-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_phy_cfg: slv-ebi1-phy-cfg { + cell-id = ; + label = "slv-ebi1-phy-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rpm: slv-rpm { + cell-id = ; + label = "slv-rpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0_cfg: slv-pcie-0-cfg { + cell-id = ; + label = "slv-pcie-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1_cfg: slv-pcie-1-cfg { + cell-id = ; + label = "slv-pcie-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spss_geni_ir: slv-spss-geni-ir { + cell-id = ; + label = "slv-spss-geni-ir"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ufs_cfg: slv-ufs-cfg { + cell-id = ; + label = "slv-ufs-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_snoc: slv-cnoc-snoc { + cell-id = ; + label = "slv-cnoc-snoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_snoc>; + qcom,slv-rpm-id = ; + }; + }; + + static-rules { + compatible = "qcom,msm-bus-static-bw-rules"; + + rule0 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <250000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <600000>; + }; + + rule1 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <900000>; + }; + + rule2 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + }; + }; + + devfreq_spdm_cpu { + compatible = "qcom,devfreq_spdm"; + qcom,msm-bus,name = "devfreq_spdm"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 512 0 0>, + <1 512 0 0>; + qcom,msm-bus,active-only; + qcom,spdm-client = <0>; + + clock-names = "cci_clk"; + clocks = <&clock_cpu clk_cci_clk>; + + qcom,bw-upstep = <1000>; + qcom,bw-dwnstep = <1000>; + qcom,max-vote = <10000>; + qcom,up-step-multp = <2>; + qcom,spdm-interval = <100>; + + qcom,ports = <16>; + qcom,alpha-up = <7>; + qcom,alpha-down = <15>; + qcom,bucket-size = <8>; + + /*max pl1 freq, max pl2 freq*/ + qcom,pl-freqs = <140000000 160000000>; + + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,reject-rate = <5000 5000 5000 5000 5000 5000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,response-time-us = <10000 10000 10000 10000 3000 3000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,cci-response-time-us = <10000 10000 10000 10000 1000 1000>; + qcom,max-cci-freq = <600000000>; + }; + + devfreq_spdm_gov { + compatible = "qcom,gov_spdm_hyp"; + interrupt-names = "spdm-irq"; + interrupts = <0 192 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-sensor-mtp.dtsi new file mode 100644 index 0000000000000..46588afa45fe1 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-sensor-mtp.dtsi @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + led_flash0: qcom,camera-flash { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-type = <1>; + qcom,flash-source = <&pmi8994_flash0 &pmi8994_flash1>; + qcom,torch-source = <&pmi8994_torch0 &pmi8994_torch1>; + }; +}; + +&cci { +//added by Likelong 2015.3.23 for proximity sensor start + proximity:qcom,proximity@0 { + cell-index = <0>; + reg = <0x29>; + compatible = "stmv,vl6180"; + qcom,cci-master = <0>;//use the same I2C bus with main camera + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.3.23 for proximity sensor end + + actuator0: qcom,actuator@0 { + cell-index = <0>; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + reg = <0x1C>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; +/* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8994_l23>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <100000>; + }; + +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + ois0: qcom,ois@0 { + cell-index = <0>; + reg = <0x1C>; + compatible = "qcom,ois"; + qcom,cci-master = <0>; + /* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + reg = <0x0>; + qcom,eeprom-name = "ov13860"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <7>; + + qcom,page0 = <0 0x0000 2 0x00 1 5>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <47 0x0000 2 0 1 0>; + + qcom,page1 = <0 0x0000 2 0x00 1 5>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0xa0>; + qcom,mem1 = <40 0x0100 2 0 1 0>; + + qcom,page2 = <0 0x0000 2 0x00 1 5>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0xa0>; + qcom,mem2 = <255 0x0200 2 0 1 0>; + + qcom,page3 = <0 0x0000 2 0x00 1 5>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0xa0>; + qcom,mem3 = <255 0x0300 2 0 1 0>; + + qcom,page4 = <0 0x0000 2 0x00 1 5>; + qcom,pageen4 = <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0xa0>; + qcom,mem4 = <255 0x0400 2 0 1 0>; + + qcom,page5 = <0 0x0000 2 0x00 1 5>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0xa0>; + qcom,mem5 = <255 0x0500 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0xa0>; + qcom,mem6 = <89 0x0600 2 0 1 0>; + +/* Kangjian,201/12/18,Add for camera driver */ + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + /*liuyan 2015/7/20, change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000>; + /*#endif*/ + + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + <&msm_gpio 102 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,cam-power-seq-type = "sensor_gpio", "sensor_vreg", "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "sensor_gpio_standby", "cam_vio", "cam_vana", "cam_vdig", + "sensor_gpio_reset","sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <1 0 0 0 1 24000000 0>; + qcom,cam-power-seq-delay = <0 0 0 0 0 0 0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + +/*muyuezhong@camera,2015-4-29,add for ov5648 OTP functions begin*/ + eeprom1: qcom,eeprom@1 { + cell-index = <2>; + reg = <0x2>; + qcom,eeprom-name = "ov5648"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <1>; + qcom,num-blocks = <26>; + + //read group 1:begin + qcom,page0 = <1 0x0103 2 0x01 1 0>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0x6c>; + qcom,mem0 = <0 0x0000 2 0 1 0>; + + qcom,page1 = <1 0x0100 2 0x01 1 0>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0x6c>; + qcom,mem1 = <0 0x0000 2 0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0x6c>; + qcom,mem2 = <0 0x0000 2 0 1 0>; + + qcom,page3 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0x6c>; + qcom,mem3 = <0 0x0000 2 0 1 0>; + + qcom,page4 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen4= <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0x6c>; + qcom,mem4 = <0 0x0000 2 0 1 0>; + + qcom,page5 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0x6c>; + qcom,mem5 = <0 0x0000 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0x6c>; + qcom,mem6 = <9 0x3d05 2 0 1 0>; + + qcom,page7 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen7 = <16 0x3d00 2 0x00 1 0>; + qcom,poll7 = <0 0x0000 2 0x00 1 5>; + qcom,saddr7 = <0x6c>; + qcom,mem7 = <0 0x0000 2 0 1 0>; + //read group 1:end +/*muyuezhong@camera,2015-8-12,add for other otp group*/ + //read group 2:begin + qcom,page8 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen8 = <0 0x0000 2 0x00 1 5>; + qcom,poll8 = <0 0x0000 2 0x00 1 5>; + qcom,saddr8 = <0x6c>; + qcom,mem8 = <0 0x0000 2 0 1 0>; + + qcom,page9 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen9 = <0 0x0000 2 0x00 1 5>; + qcom,poll9 = <0 0x0000 2 0x00 1 5>; + qcom,saddr9 = <0x6c>; + qcom,mem9 = <0 0x0000 2 0 1 0>; + + qcom,page10 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen10= <0 0x0000 2 0x00 1 5>; + qcom,poll10 = <0 0x0000 2 0x00 1 5>; + qcom,saddr10 = <0x6c>; + qcom,mem10 = <0 0x0000 2 0 1 0>; + + qcom,page11 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen11 = <0 0x0000 2 0x00 1 5>; + qcom,poll11 = <0 0x0000 2 0x00 1 5>; + qcom,saddr11 = <0x6c>; + qcom,mem11 = <0 0x0000 2 0 1 0>; + + qcom,page12 = <0 0x0000 2 0x00 1 5>; + qcom,pageen12 = <0 0x0000 2 0x00 1 5>; + qcom,poll12 = <0 0x0000 2 0x00 1 5>; + qcom,saddr12 = <0x6c>; + qcom,mem12 = <2 0x3d0e 2 0 1 0>; + + qcom,page13 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen13 = <0 0x0000 2 0x00 1 5>; + qcom,poll13 = <0 0x0000 2 0x00 1 5>; + qcom,saddr13 = <0x6c>; + qcom,mem13 = <0 0x0000 2 0 1 0>; + + qcom,page14 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen14 = <0 0x0000 2 0x00 1 5>; + qcom,poll14 = <0 0x0000 2 0x00 1 5>; + qcom,saddr14 = <0x6c>; + qcom,mem14 = <0 0x0000 2 0 1 0>; + + qcom,page15 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen15= <0 0x0000 2 0x00 1 5>; + qcom,poll15 = <0 0x0000 2 0x00 1 5>; + qcom,saddr15 = <0x6c>; + qcom,mem15 = <0 0x0000 2 0 1 0>; + + qcom,page16 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen16 = <0 0x0000 2 0x00 1 5>; + qcom,poll16 = <0 0x0000 2 0x00 1 5>; + qcom,saddr16 = <0x6c>; + qcom,mem16 = <0 0x0000 2 0 1 0>; + + qcom,page17 = <0 0x0000 2 0x00 1 5>; + qcom,pageen17 = <0 0x0000 2 0x00 1 5>; + qcom,poll17 = <0 0x0000 2 0x00 1 5>; + qcom,saddr17 = <0x6c>; + qcom,mem17 = <7 0x3d00 2 0 1 0>; + + qcom,page18 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen18 = <16 0x3d00 2 0x00 1 0>; + qcom,poll18 = <0 0x0000 2 0x00 1 5>; + qcom,saddr18 = <0x6c>; + qcom,mem18 = <0 0x0000 2 0 1 0>; + //read group 2:end + + //read group 3:begin + qcom,page19 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen19 = <0 0x0000 2 0x00 1 5>; + qcom,poll19 = <0 0x0000 2 0x00 1 5>; + qcom,saddr19 = <0x6c>; + qcom,mem19 = <0 0x0000 2 0 1 0>; + + qcom,page20 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen20 = <0 0x0000 2 0x00 1 5>; + qcom,poll20 = <0 0x0000 2 0x00 1 5>; + qcom,saddr20 = <0x6c>; + qcom,mem20 = <0 0x0000 2 0 1 0>; + + qcom,page21 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen21= <0 0x0000 2 0x00 1 5>; + qcom,poll21 = <0 0x0000 2 0x00 1 5>; + qcom,saddr21 = <0x6c>; + qcom,mem21 = <0 0x0000 2 0 1 0>; + + qcom,page22 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen22 = <0 0x0000 2 0x00 1 5>; + qcom,poll22 = <0 0x0000 2 0x00 1 5>; + qcom,saddr22 = <0x6c>; + qcom,mem22 = <0 0x0000 2 0 1 0>; + + qcom,page23 = <0 0x0000 2 0x00 1 5>; + qcom,pageen23 = <0 0x0000 2 0x00 1 5>; + qcom,poll23 = <0 0x0000 2 0x00 1 5>; + qcom,saddr23 = <0x6c>; + qcom,mem23 = <9 0x3d07 2 0 1 0>; + + qcom,page24 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen24 = <16 0x3d00 2 0x00 1 0>; + qcom,poll24 = <0 0x0000 2 0x00 1 5>; + qcom,saddr24 = <0x6c>; + qcom,mem24 = <0 0x0000 2 0 1 0>; + + qcom,page25 = <1 0x0100 2 0x00 1 0>; + qcom,pageen25 = <0 0x0000 2 0x00 1 5>; + qcom,poll25 = <0 0x0000 2 0x00 1 5>; + qcom,saddr25 = <0x6c>; + qcom,mem25= <0 0x0000 2 0 1 0>; + //read group 3:end + + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2","CAM_RESET2","CAM_STANDBY2"; + + qcom,cam-power-seq-type = "sensor_vreg","sensor_vreg", "sensor_gpio", "sensor_gpio", + "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "cam_vio","cam_vana", "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 24000000 0>; + qcom,cam-power-seq-delay = <0 5 0 0 0 0>; + + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>,<&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* muyuezhong@camera,2015-4-29,add for ov5648 OTP functions end*/ + +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ +/* + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <2>; + qcom,eeprom-name = "onsemi_cat24c32"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <2245 0x00 2 0 1 0>; + + cam_vio-supply = <&pm8994_lvs1>; + qcom,cam-vreg-name = "cam_vio"; + qcom,cam-vreg-min-voltage = <0>; + qcom,cam-vreg-max-voltage = <0>; + qcom,cam-vreg-op-mode = <0>; + qcom,cam-power-seq-type = "sensor_vreg"; + qcom,cam-power-seq-val = "cam_vio"; + qcom,cam-power-seq-cfg-val = <1>; + qcom,cam-power-seq-delay = <1>; + status = "ok"; + }; +*/ +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom0>; + qcom,actuator-src = <&actuator0>; +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + qcom,ois-src = <&ois0>; + qcom,led-flash-src = <&led_flash0>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + cam_v_custom1-supply = <&pm8994_l29>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_v_custom1"; + /*liuyan 2015/7/20, change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000 2800000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000 2800000>; + /*#endif*/ + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, + <&msm_gpio 102 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vaf = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0 >; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VAF0"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 0 2700000>; + qcom,cam-vreg-max-voltage = <1200000 0 2700000>; + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend &cam_sensor_rear2_suspend>; + gpios = <&msm_gpio 14 0>, + <&msm_gpio 94 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_STANDBY1"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +*/ + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom1>; + //qcom,actuator-src = <&actuator1>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; +/* Kangjian,2014/12/18,Add end */ diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v1.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v1.dtsi new file mode 100755 index 0000000000000..b1c810d391efe --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v1.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v2.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v2.dtsi new file mode 100755 index 0000000000000..b101e98dde0dd --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera-v2.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-camera.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera.dtsi new file mode 100755 index 0000000000000..03e578bcf4121 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-camera.dtsi @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,msm-cam@fd8c0000 { + compatible = "qcom,msm-cam"; + reg = <0xfd8c0000 0x10000>; + reg-names = "msm-cam"; + }; + + qcom,csiphy@fda0ac00 { + cell-index = <0>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0ac00 0x200>, + <0xfda00030 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 78 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0phy_clk>, + <&clock_mmss clk_csi0phytimer_clk_src>, + <&clock_mmss clk_camss_phy0_csi0phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b000 { + cell-index = <1>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b000 0x200>, + <0xfda00038 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 79 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1phy_clk>, + <&clock_mmss clk_csi1phytimer_clk_src>, + <&clock_mmss clk_camss_phy1_csi1phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b400 { + cell-index = <2>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b400 0x200>, + <0xfda00040 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 80 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2phy_clk>, + <&clock_mmss clk_csi2phytimer_clk_src>, + <&clock_mmss clk_camss_phy2_csi2phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csid@fda08000 { + cell-index = <0>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08000 0x400>; + reg-names = "csid"; + interrupts = <0 51 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0_ahb_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08400 { + cell-index = <1>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08400 0x400>; + reg-names = "csid"; + interrupts = <0 52 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1_ahb_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08800 { + cell-index = <2>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08800 0x400>; + reg-names = "csid"; + interrupts = <0 53 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2_ahb_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08c00 { + cell-index = <3>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08C00 0x100>; + reg-names = "csid"; + interrupts = <0 54 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3_ahb_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,ispif@fda0a000 { + cell-index = <0>; + compatible = "qcom,ispif-v3.0", "qcom,ispif"; + reg = <0xfda0A000 0x500>, + <0xfda00020 0x10>; + reg-names = "ispif", "csi_clk_mux"; + interrupts = <0 55 0>; + interrupt-names = "ispif"; + qcom,num-isps = <0x2>; + vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>; + clock-names = "ispif_ahb_clk", + "csi0_src_clk", "csi0_clk", + "csi0_pix_clk", "csi0_rdi_clk", + "csi1_src_clk", "csi1_clk", + "csi1_pix_clk", "csi1_rdi_clk", + "csi2_src_clk", "csi2_clk", + "csi2_pix_clk", "csi2_rdi_clk", + "csi3_src_clk", "csi3_clk", + "csi3_pix_clk", "csi3_rdi_clk", + "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk", + "vfe1_clk_src", "camss_vfe_vfe1_clk", "camss_csi_vfe1_clk"; + qcom,clock-rates = "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "-2", "0", "0", + "-2", "0", "0"; + }; + + vfe0: qcom,vfe@fda10000 { + cell-index = <0>; + compatible = "qcom,vfe46"; + reg = <0xfda10000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 57 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + + }; + + vfe1: qcom,vfe@fda14000 { + cell-index = <1>; + compatible = "qcom,vfe46"; + reg = <0xfda14000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 58 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + }; + + + qcom,jpeg@fda1c000 { + cell-index = <0>; + compatible = "qcom,jpeg"; + reg = <0xfda1c000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 59 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", + "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda20000 { + cell-index = <1>; + compatible = "qcom,jpeg"; + reg = <0xfda20000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 60 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda24000 { + cell-index = <2>; + compatible = "qcom,jpeg"; + reg = <0xfda24000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 61 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg2_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + qcom,jpeg@fdaa0000 { + cell-index = <3>; + compatible = "qcom,jpeg_dma"; + reg = <0xfdaa0000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 304 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_dma_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + + qcom,irqrouter@fda00000 { + cell-index = <0>; + compatible = "qcom,irqrouter"; + reg = <0xfda00000 0x100>; + reg-names = "irqrouter"; + }; + + qcom,cpp@fda04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xfda04000 0x100>, + <0xfda80000 0x200>, + <0xfda18000 0x008>; + reg-names = "cpp", "cpp_vbif", "cpp_hw"; + interrupts = <0 49 0>; + interrupt-names = "cpp"; + vdd-supply = <&gdsc_cpp>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cpp_core_clk", + "camss_vfe_cpp_ahb_clk", "camss_vfe_cpp_axi_clk", + "camss_vfe_cpp_clk","micro_iface_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 465000000 0 0 465000000 0 0>; + qcom,min-clock-rate = <320000000>; + }; + + qcom,fd@fd878000 { + cell-index = <0>; + compatible = "qcom,face-detection"; + reg = <0xfd878000 0x800>, + <0xfd87c000 0x800>, + <0xfd860000 0x1000>; + reg-names = "fd_core", "fd_misc", "fd_vbif"; + interrupts = <0 316 0>; + interrupt-names = "fd"; + vdd-supply = <&gdsc_fd>; + clocks = <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>, + <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>; + clock-names = "fd_core_clk", "fd_core_uar_clk", + "fd_axi_clk", "fd_ahb_clk"; + clock-rates = <60000000 60000000 75000000 40000000>, + <200000000 200000000 150000000 40000000>, + <400000000 400000000 333000000 80000000>; + }; + + cci: qcom,cci@fda0c000 { + cell-index = <0>; + compatible = "qcom,cci"; + reg = <0xfda0c000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "cci"; + interrupts = <0 50 0>; + interrupt-names = "cci"; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cci_clk_src>, + <&clock_mmss clk_camss_cci_cci_ahb_clk>, + <&clock_mmss clk_camss_cci_cci_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cci_src_clk", + "cci_ahb_clk", "camss_cci_clk", + "camss_ahb_clk"; + qcom,clock-rates = <0 19200000 0 0 0>, + <0 37500000 0 0 0>; + pinctrl-names = "cci_default", "cci_suspend"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + gpios = <&msm_gpio 17 0>, + <&msm_gpio 18 0>, + <&msm_gpio 19 0>, + <&msm_gpio 20 0>; + qcom,gpio-tbl-num = <0 1 2 3>; + qcom,gpio-tbl-flags = <1 1 1 1>; + qcom,gpio-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + i2c_freq_100Khz: qcom,i2c_standard_mode { + status = "disabled"; + }; + i2c_freq_400Khz: qcom,i2c_fast_mode { + status = "disabled"; + }; + i2c_freq_custom: qcom,i2c_custom_mode { + status = "disabled"; + }; + + i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { + status = "disabled"; + }; + + }; +}; + +&i2c_freq_100Khz { + qcom,hw-thigh = <104>; + qcom,hw-tlow = <88>; + qcom,hw-tsu-sto = <105>; + qcom,hw-tsu-sta = <119>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <84>; + qcom,hw-tbuf = <116>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_400Khz { + qcom,hw-thigh = <20>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <32>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_custom { + qcom,hw-thigh = <15>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <25>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_1Mhz { + qcom,hw-thigh = <16>; + qcom,hw-tlow = <22>; + qcom,hw-tsu-sto = <17>; + qcom,hw-tsu-sta = <18>; + qcom,hw-thd-dat = <16>; + qcom,hw-thd-sta = <15>; + qcom,hw-tbuf = <19>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <3>; + qcom,hw-tsp = <3>; + qcom,cci-clk-src = <37500000>; + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v1.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v1.dtsi new file mode 100755 index 0000000000000..b6ad994e6ae35 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v1.dtsi @@ -0,0 +1,774 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <9>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <10>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <11>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <12>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <18>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <19>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <20>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <21>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <22>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <23>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <24>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <25>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <44>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <45>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v2.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v2.dtsi new file mode 100755 index 0000000000000..681adbaf1c818 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-coresight-v2.dtsi @@ -0,0 +1,829 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + qcom,sg-enable; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss1: funnel@fbb70000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb70000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss1"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <0>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <9>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpda_lmh: tpda@fbb91000 { + compatible = "qcom,coresight-tpda"; + reg = <0xfbb91000 0x1000>; + reg-names = "tpda-base"; + + coresight-id = <10>; + coresight-name = "coresight-tpda-lmh"; + coresight-nr-inports = <32>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <3>; + + qcom,tpda-atid = <64>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpdm_lmh: tpdm@fbb90000 { + compatible = "qcom,coresight-tpdm"; + reg = <0xfbb90000 0x1000>; + reg-names = "tpdm-base"; + + coresight-id = <11>; + coresight-name = "coresight-tpdm-lmh"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&tpda_lmh>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <12>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <18>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <19>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <20>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <21>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <22>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <23>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <24>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <25>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <44>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <45>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <46>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <47>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <48>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-gpu.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-gpu.dtsi new file mode 100755 index 0000000000000..3d63cf8d2076c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-gpu.dtsi @@ -0,0 +1,181 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + msm_bus: qcom,kgsl-busmon{ + label = "kgsl-busmon"; + compatible = "qcom,kgsl-busmon"; + }; + + gpubw: qcom,gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,gpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc390000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <2>; + qcom,target-dev = <&gpubw>; + }; + + msm_gpu: qcom,kgsl-3d0@fdb00000 { + label = "kgsl-3d0"; + compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d"; + reg = <0xfdb00000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 33 0>; + interrupt-names = "kgsl_3d0_irq"; + qcom,id = <0>; + + qcom,chipid = <0x04030000>; + + qcom,initial-pwrlevel = <2>; + + qcom,idle-timeout = <8>; // + qcom,strtstp-sleepwake; + + qcom,pm-qos-active-latency = <501>; + qcom,pm-qos-wakeup-latency = <101>; + + /* + * Clocks = KGSL_CLK_CORE | KGSL_CLK_IFACE + * KGSL_CLK_RBBMTIMER + */ + qcom,clk-map = <0x00000086>; + + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>, + <&clock_mmss clk_oxili_rbbmtimer_clk>; + clock-names = "core_clk", "iface_clk", "rbbmtimer_clk"; + + /* Bus Scale Settings */ + qcom,gpubw-dev = <&gpubw>; + qcom,bus-control; + /* + * qcom,msm-bus structures below define + * GPU msm client and its vote data for + * each of available power levels + * (gpu-bus frequency combination) + */ + qcom,msm-bus,name = "grp3d"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1200000>, /* 1 bus=150 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3200000>, /* 3 bus=460 */ + <26 512 0 4224000>, /* 4 bus=533 */ + <26 512 0 5376000>, /* 5 bus=672 */ + <26 512 0 6681600>, /* 6 bus=777 */ + <26 512 0 8448000>, /* 7 bus=1036 */ + <26 512 0 12748800>; /* 8 bus=1555 */ + + /* GDSC oxili regulators */ + vddcx-supply = <&gdsc_oxili_cx>; + vdd-supply = <&gdsc_oxili_gx>; + + /* IOMMU Data */ + iommu = <&kgsl_iommu>; + + /* Trace bus */ + coresight-id = <67>; + coresight-name = "coresight-gfx"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <4>; + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <400000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <300000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <2>; + qcom,bus-max = <5>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <150000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <27000000>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + qcom,bus-freq = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <5>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu=600 */ + <89 662 0 6400000>, /* gpu=400 */ + <89 662 0 4800000>, /* gpu=300 */ + <89 662 0 2400000>, /* gpu=150 */ + <89 662 0 0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu-domains.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu-domains.dtsi new file mode 100755 index 0000000000000..840818c2d7cb3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu-domains.dtsi @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,iommu-domains { + compatible = "qcom,iommu-domains"; + + venus_domain_ns: qcom,iommu-domain1 { + label = "venus_ns"; + qcom,iommu-contexts = <&venus_ns>; + qcom,virtual-addr-pool = <0x5dc00000 0x7f000000 + 0xdcc00000 0x1000000>; + }; + + venus_domain_sec_bitstream: qcom,iommu-domain2 { + label = "venus_sec_bitstream"; + qcom,iommu-contexts = <&venus_sec_bitstream>; + qcom,virtual-addr-pool = <0x4b000000 0x12c00000>; + qcom,secure-domain; + }; + + venus_domain_sec_pixel: qcom,iommu-domain3 { + label = "venus_sec_pixel"; + qcom,iommu-contexts = <&venus_sec_pixel>; + qcom,virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-domain; + }; + + venus_domain_sec_non_pixel: qcom,iommu-domain4 { + label = "venus_sec_non_pixel"; + qcom,iommu-contexts = <&venus_sec_non_pixel>; + qcom,virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-domain; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu.dtsi new file mode 100755 index 0000000000000..0638ffc0a6b3c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-iommu.dtsi @@ -0,0 +1,430 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm-iommu-v1.dtsi" + +&soc { + mdp_iommu_8994: qcom,iommu@fd9cc000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd9cc000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + status = "ok"; + vdd-supply = <&gdsc_mdss>; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018>; + + qcom,iommu-bfb-data = <0x3 + 0x7fffff + 0x1777 + 0x0 + 0x4 + 0x10 + 0x5000 + 0x182c1 + 0x5a1d + 0x1822d + 0x0 + 0x0 + 0x28 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd9d4000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d4000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd9d5000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d5000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd9d6000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d6000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; +}; + +&venus_iommu { + status = "ok"; + vdd-supply = <&gdsc_venus>; + clocks = <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c>; + + qcom,iommu-bfb-data = <0x3 + 0x7ffffff + 0x1555 + 0x0 + 0x4 + 0x8 + 0x13607 + 0x140a0 + 0x4000 + 0x14020 + 0x0 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + qcom,iommu-ctx-sids = <0x00 0x21 0x45 0x47 0x48 0x49 0x4a + 0x4b 0x4c 0x65 0x67 0x69 0x6a 0x6b>; + qcom,iommu-sid-mask = <0x0 0xf 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 { + qcom,iommu-ctx-sids = <0x400 0x421 0x422 0x423 0x424 0x448 + 0x44a 0x46a>; + label = "venus_sec_bitstream"; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + qcom,iommu-ctx-sids = <0x600 0x606>; + }; + + venus_sec_pixel: qcom,iommu-ctx@fdc8f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8f000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x425 0x428 0x445 0x44c 0x465>; + label = "venus_sec_pixel"; + qcom,secure-context; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc90000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x427 0x447 0x449 0x44b 0x467 0x469 0x46b + 0x500>; + label = "venus_sec_non_pixel"; + qcom,secure-context; + }; +}; + +&jpeg_iommu { + status = "ok"; + vdd-supply = <&gdsc_jpeg>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0x3ffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2000 + 0xe673 + 0x2c00 + 0xe616 + 0x0 + 0x0 + 0x10 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6f000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <3>; + label = "jpeg_dma"; + }; +}; + +&kgsl_iommu { + status = "ok"; + vdd-supply = <&gdsc_oxili_cx>; + qcom,alt-vdd-supply = <&gdsc_oxili_gx>; + qcom,iommu-secure-id = <18>; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x2600 + 0x2604 + 0x2608 + 0x260c + 0x2610 + 0x2614 + 0x2618 + 0x261c + 0x2620 + 0x2624 + 0x2628 + 0x262c>; + + qcom,iommu-bfb-data = <0x3 + 0x3 + 0x1555 + 0x0 + 0x0 + 0x10 + 0x0 + 0x120 + 0x120 + 0x10 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x7 + 0x0 + 0x20 + 0x20 + 0x0c + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x10>; + + qcom,iommu-ctx@fdb18000 { + qcom,iommu-ctx-sids = <0 1>; + }; + + qcom,iommu-ctx@fdb19000 { + qcom,iommu-ctx-sids = <>; + }; + + qcom,iommu-ctx@fdb1a000 { + qcom,iommu-ctx-sids = <2>; + interrupts = <0 241 0>, <0 240 0>; + qcom,secure-context; + linux,contiguous-region = <&secure_mem>; + }; +}; + +&vfe_iommu { + status = "ok"; + vdd-supply = <&gdsc_vfe>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0xfffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2400 + 0x8844 + 0x2400 + 0x8812 + 0x0 + 0x0 + 0x12 + 0x5a + 0x0 + 0x0 + 0x0 + 0x0>; +}; + +&fd_iommu { + status = "ok"; + vdd-supply = <&gdsc_fd>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>, + <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk", "alt_iface_clk"; +}; + +&cpp_iommu { + status = "ok"; + vdd-supply = <&gdsc_cpp>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-ion.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-ion.dtsi new file mode 100755 index 0000000000000..16b920e069108 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-ion.dtsi @@ -0,0 +1,63 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ion { + compatible = "qcom,msm-ion"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,ion-heap@25 { + reg = <25>; + qcom,ion-heap-type = "SYSTEM"; + }; + + qcom,ion-heap@21 { + reg = <21>; + qcom,ion-heap-type = "SYSTEM_CONTIG"; + }; + + qcom,ion-heap@8 { /* CP_MM HEAP */ + compatible = "qcom,msm-ion-reserve"; + reg = <8>; + qcom,heap-align = <0x1000>; + linux,contiguous-region = <&secure_mem>; + qcom,ion-heap-type = "SECURE_DMA"; + qcom,default-prefetch-size = <0x6c00000>; + }; + + qcom,ion-heap@22 { /* adsp heap */ + reg = <22>; + linux,contiguous-region = <&adsp_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@27 { /* QSECOM HEAP */ + reg = <27>; + linux,contiguous-region = <&qsecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@28 { /* AUDIO HEAP */ + reg = <28>; + linux,contiguous-region = <&audio_mem>; + qcom,ion-heap-type = "DMA"; + }; + + adsp_venus_heap: qcom,ion-heap@23 { + compatible = "qcom,msm-ion-reserve"; + reg = <23>; + linux,contiguous-region = <&peripheral_mem>; + qcom,ion-heap-type = "DMA"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-ipcrouter.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-ipcrouter.dtsi new file mode 100755 index 0000000000000..006bd32eb5957 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-ipcrouter.dtsi @@ -0,0 +1,37 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ipc_router { + compatible = "qcom,ipc_router"; + qcom,node-id = <1>; + }; + + qcom,ipc_router_modem_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "modem"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + qcom,disable-pil-loading; + }; + + qcom,ipc_router_q6_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "adsp"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss-pll.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss-pll.dtsi new file mode 100755 index 0000000000000..a6cd3a43e5a65 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss-pll.dtsi @@ -0,0 +1,171 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@fd998300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xfd998300 0x500>, + <0xfd8c2300 0x8>, + <0xfd998200 0x64>, + <0xfd9a0300 0x500>; + reg-names = "pll_base", "gdsc_base", "dynamic_pll_base", + "pll_1_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-en-pll-90-phase; + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + /* Dynamic FPS data region */ + linux,contiguous-region = <&dfps_data_mem>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + mdss_dsi1_pll: qcom,mdss_dsi_pll@fd9a0300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xfd9a0300 0x500>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + + mdss_hdmi_pll: qcom,mdss_hdmi_pll@0xfd9a8600 { + compatible = "qcom,mdss_hdmi_pll_8994"; + label = "MDSS HDMI PLL"; + #clock-cells = <1>; + + reg = <0xfd9a8600 0xac4>, + <0xfd9a9200 0x0C8>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "phy_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss.dtsi new file mode 100755 index 0000000000000..269101b45a411 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-mdss.dtsi @@ -0,0 +1,508 @@ +/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_mdp: qcom,mdss_mdp@fd900000 { + compatible = "qcom,mdss_mdp"; + reg = <0xfd900000 0x90000>, + <0xfd9c8000 0x004d4>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-ib-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2048>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,mdss-vbif-qos-nrt-setting = <1 1 1 1>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <7300000>; + qcom,max-bandwidth-high-kbps = <7300000>; + qcom,max-bandwidth-per-pipe-kbps = <1800000>; + qcom,max-clk-rate = <400000000>; + qcom,mdss-dram-channels = <2>; + qcom,mdss-default-ot-wr-limit = <16>; + qcom,mdss-default-ot-rd-limit = <16>; + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000 + 0x00009000 0x0000B000>; + qcom,mdss-pipe-rgb-off = <0x00015000 0x00017000 + 0x00019000 0x0001B000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000>; + qcom,mdss-pipe-cursor-off = <0x00035000 0x00037000>; + + qcom,mdss-pipe-vig-fetch-id = <1 4 7 19>; + qcom,mdss-pipe-rgb-fetch-id = <16 17 18 22>; + qcom,mdss-pipe-dma-fetch-id = <10 13>; + + qcom,mdss-pipe-vig-xin-id = <0 4 8 12>; + qcom,mdss-pipe-rgb-xin-id = <1 5 9 13>; + qcom,mdss-pipe-dma-xin-id = <2 10>; + qcom,mdss-pipe-cursor-xin-id = <7 7>; + + qcom,mdss-en-svs-high; + qcom,mdss-has-panic-ctrl; + qcom,mdss-pipe-vig-panic-ctrl-offsets = <0 1 2 3>; + qcom,mdss-pipe-rgb-panic-ctrl-offsets = <4 5 6 7>; + qcom,mdss-pipe-dma-panic-ctrl-offsets = <8 9>; + + qcom,mdss-pipe-rgb-fixed-mmb = <5 0 1 8 9 10>, + <5 2 3 11 12 13>, + <5 4 5 14 15 16>, + <5 6 7 17 18 19>; + qcom,mdss-pipe-vig-fixed-mmb = <1 20>, + <1 21>, + <1 22>, + <1 23>; + + /* These Offsets are relative to "mdp_phys + mdp-reg-offset" address */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2AC 0 0>, + <0x2B4 0 0>, + <0x2BC 0 0>, + <0x2C4 0 0>; + qcom,mdss-pipe-rgb-clk-ctrl-offsets = <0x2AC 4 8>, + <0x2B4 4 8>, + <0x2BC 4 8>, + <0x2C4 4 8>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2AC 8 12>, + <0x2B4 8 12>; + + qcom,mdss-pipe-sw-reset-off = <0x0028>; + qcom,mdss-pipe-vig-sw-reset-map = <5 6 7 8>; + qcom,mdss-pipe-rgb-sw-reset-map = <9 10 11 12>; + qcom,mdss-pipe-dma-sw-reset-map = <13 14>; + + qcom,mdss-smp-data = <44 8192>; + qcom,mdss-sspp-len = <0x00002000>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004A000>; + qcom,mdss-mixer-wb-off = <0x00048000 0x00049000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000 0x00059000 + 0x0005B000>; + qcom,mdss-wb-off = <0x00065000 0x00065800 0x00066000 + 0x00066800 0x00067000>; + qcom,mdss-intf-off = <0x0006B000 0x0006B800 0x0006C000 + 0x0006C800 0x0006D000>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 0x00072000 + 0x00072800>; + qcom,mdss-ad-off = <0x0079000 0x00079800 0x0007A000>; + qcom,mdss-highest-bank-bit = <0x3>; + qcom,mdss-has-decimation; + qcom,mdss-has-rotator-downscale; + qcom,mdss-has-bwc; + + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + + qcom,mdss-ctl-len = <0x00000200>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdp_clk_src>, + <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_vsync_clk>; + clock-names = "iface_clk", "bus_clk", "core_clk_src", + "core_clk", "vsync_clk"; + + /* These Offsets are relative to "mdp_phys" address */ + qcom,mdp-settings = <0x0117c 0x00005555>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; + + qcom,regs-dump-mdp = <0x01000 0x01408>, + <0x02000 0x02064>, + <0x02200 0x02264>, + <0x02400 0x02464>, + <0x02600 0x02664>, + <0x02800 0x02864>, + <0x05000 0x05130>, + <0x05200 0x05230>, + <0x07000 0x07130>, + <0x07200 0x07230>, + <0x09000 0x09130>, + <0x09200 0x09230>, + <0x0b000 0x0b130>, + <0x0b200 0x0b230>, + <0x15000 0x15130>, + <0x15200 0x15230>, + <0x17000 0x17130>, + <0x17200 0x17230>, + <0x19000 0x19130>, + <0x19200 0x19230>, + <0x1b000 0x1b130>, + <0x1b200 0x1b230>, + <0x25000 0x2512C>, + <0x27000 0x2712C>, + <0x45000 0x4538c>, + <0x46000 0x4638c>, + <0x47000 0x4738c>, + <0x48000 0x4838c>, + <0x49000 0x4938c>, + <0x4a000 0x4a38c>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x59000 0x5922c>, + <0x5b000 0x5b22c>, + <0x65000 0x652b4>, + <0x65800 0x65ab4>, + <0x66000 0x662b4>, + <0x66800 0x66ab4>, + <0x67000 0x672b4>, + <0x6b800 0x6ba54>, + <0x6c000 0x6c254>, + <0x6c800 0x6ca54>, + <0x71000 0x710d0>, + <0x71800 0x718d0>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "VIG2_SSPP", "VIG2", "VIG3_SSPP", "VIG3", + "RGB0_SSPP", "RGB0", "RGB1_SSPP", "RGB1", + "RGB2_SSPP", "RGB2", "RGB3_SSPP", "RGB3", + "DMA0_SSPP", "DMA1_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_3", "LAYER_4", "LAYER_5", + "DSPP_0", "DSPP_1", "DSPP_2", "DSPP_3", + "WB_0", "WB_1", "WB_2", "WB_3", "WB_4", + "INTF_1", "INTF_2", "INTF_3", + "PP_0", "PP_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <2048>; + qcom,mdss-prefill-y-buffer-bytes = <4096>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2048>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + qcom,mdss-prefill-fbc-lines = <2>; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + qcom,cont-splash-memory { + linux,contiguous-region = <&cont_splash_mem>; + }; + }; + + mdss_fb1: qcom,mdss_fb_external { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_wfd { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + }; + }; + + mdss_dsi0: qcom,mdss_dsi@fd998000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xfd998000 0x260>, + <0xfd998500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte0_clk>, + <&clock_mmss clk_mdss_pclk0_clk>, + <&clock_mmss clk_mdss_esc0_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", "byte_clk_src", + "pixel_clk_src", "shadow_byte_clk_src", + "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + mdss_dsi1: qcom,mdss_dsi@fd9a0000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xfd9a0000 0x260>, + <0xfd9a0500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte1_clk>, + <&clock_mmss clk_mdss_pclk1_clk>, + <&clock_mmss clk_mdss_esc1_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", + "byte_clk_src", "pixel_clk_src", + "shadow_byte_clk_src", "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <1920 1080>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb2>; + }; + + mdss_hdmi_tx: qcom,hdmi_tx@fd9a8000{ + cell-index = <0>; + compatible = "qcom,hdmi-tx"; + + reg = <0xfd9a8000 0x38C>, + <0xfc4b8000 0x6fff>; + reg-names = "core_physical", "qfprom_physical"; + + hpd-gdsc-supply = <&gdsc_mdss>; + core-vdda-supply = <&pm8994_l12>; + core-vcc-supply = <&pm8994_s4>; + + qcom,supply-names = "hpd-gdsc", "core-vdda", "core-vcc"; + qcom,min-voltage-level = <0 1800000 1800000>; + qcom,max-voltage-level = <0 1800000 1800000>; + qcom,enable-load = <0 300000 0>; + qcom,disable-load = <0 0 0>; + + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_hdmi_clk>, + <&clock_mmss clk_mdss_hdmi_ahb_clk>, + <&clock_mmss clk_mdss_extpclk_clk>; + clock-names = "mdp_core_clk", "iface_clk", + "core_clk", "alt_iface_clk", "extp_clk"; + + qcom,hdmi-tx-hpd = <&pm8994_mpps 4 0>; + qcom,mdss-fb-map = <&mdss_fb1>; + + hdmi_audio: qcom,msm-hdmi-audio-rx { + compatible = "qcom,msm-hdmi-audio-codec-rx"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-mtp.dtsi new file mode 100755 index 0000000000000..1f926de5b4da4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-mtp.dtsi @@ -0,0 +1,1035 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8994-pinctrl.dtsi" +#include "msm8994-camera-sensor-mtp.dtsi" +#include "dsi-panel-jd35695-1080p-cmd.dtsi" +#include "dsi-panel-jdi-1080p-video.dtsi" + +/ { + bt_qca6174 { + compatible = "qca,qca6174"; + qca,bt-reset-gpio = <&pm8994_gpios 19 0>; /* BT_EN */ + qca,bt-vdd-pa-supply = <&bt_vreg>; + qca,bt-vdd-io-supply = <&pm8994_s4>; + qca,bt-vdd-xtal-supply = <&pm8994_l30>; + qca,bt-vdd-io-voltage-level = <1800000 1800000>; + qca,bt-vdd-xtal-voltage-level = <1800000 1800000>; + }; +}; + +&sdhc_1 { + vdd-supply = <&pm8994_l20>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + vdd-io-supply = <&pm8994_s4>; + qcom,vdd-io-always-on; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,nonremovable; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &pm8994_gpios 8 0x3>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&pm8994_gpios 8 0x1>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + status = "ok"; +}; + +&ufsphy1 { + status = "ok"; +}; + +&ufs1 { + status = "ok"; +}; + +&pm8994_vadc { + chan@5 { + label = "vcoin"; + reg = <5>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@7 { + label = "vph_pwr"; + reg = <7>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm8994_adc_tm { + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x48>; + qcom,thermal-node; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x68>; + qcom,thermal-node; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x70>; + qcom,thermal-node; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x78>; + qcom,thermal-node; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x80>; + qcom,thermal-node; + }; +}; + +&pmi8994_vadc { + chan@0 { + label = "usbin"; + reg = <0>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@1 { + label = "dcin"; + reg = <1>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@43 { + label = "usb_dp"; + reg = <0x43>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@44 { + label = "usb_dm"; + reg = <0x44>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; +}; + + +/**********************************************************************/ +//zhiming.guo@MM.lcddriver add for lcd driver 2015-01-31 + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&pmx_mdss { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 78>; +}; + + +&labibb { + status = "ok"; + qpnp,qpnp-labibb-mode = "lcd"; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 10>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jd35695_1080_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + qcom,platform-esd-te-gpio = <&msm_gpio 108 0>;//gzm@oem add 2015-03-28 add +}; +&dsi_jd35695_1080_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + +/* + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + +}; +*/ +&dsi_jdi_1080_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + + +/******************************************************************/ + + + +&soc { + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, delete it : synaptics@20.*/ + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, add for tp:synaptics */ + i2c@f9924000 { + synaptics-rmi-ts@20 { + compatible = "synaptics,s3320"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x8>; + synaptics,irq-gpio = <&msm_gpio 96 0x08>; + //synaptics,wakeup-gpio = <&msm_gpio 39 0x00>; + synaptics,reset-gpio = <&msm_gpio 31 0x00>; + //synaptics,id-gpio = <&msm_gpio 38 0x00>; + //synaptics,id3-gpio = <&msm_gpio 39 0x00>; + vdd_2v8-supply = <&pm8994_l22>; + vcc_i2c_1v8-supply = <&pm8994_l14>; + oem,support_hw_poweroff; + }; + }; +//#ifdef VENDOR_EDIT /* modify for fpc1021 fingerprints*/ + spi@f9968000 { + fpc_fpc1020@0 { //Slave driver and CS ID + compatible = "fpc,fpc1020"; //Manufacture, and Model + reg = <0>; //Same as CS ID + spi-max-frequency = <19200000>; //Max Frequency for Device + #spi-cs-high; //CS Active High + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <90 0>; //GPIO # and flags + fpc,gpio_irq = <&msm_gpio 90 0x00>; //Pass a GPIO + fpc,gpio_reset = <&msm_gpio 89 0x00>; + fpc,gpio_vendor = <&msm_gpio 91 0x00>; + #fpc,gpio_envdd = <&msm_gpio 16 0x00>; + fpc,vddtx_mv; + #fpc,txout_boost_enable; + #spi-cpol; //CPOL bit set for SPI polarity + #spi-cpha; //CPHA bit set for SPI Phase + vdd_io-supply = <&pm8994_s4>; // 1.8V + vdd_ana-supply = <&pm8994_l18>; // 3.3V N3 use gpio16 for enable_pin to controll 3.3V(boost) + fpc,gpio_envdd = <&msm_gpio 41 0x00>; + }; + }; +//#endif/*VENDOR_EDIT*/ + + gen-vkeys { + compatible = "qcom,gen-vkeys"; + label = "synaptics_dsx"; + qcom,disp-maxx = <1599>; + qcom,disp-maxy = <2559>; + qcom,panel-maxx = <1599>; + qcom,panel-maxy = <2703>; + qcom,key-codes = <158 139 102 217>; + }; + + i2c@f9928000 { /* BLSP1 QUP6 */ + status = "ok"; +//#ifdef VENDOR_EDIT +//added by Likelong 2015.5.15 for proximity sensor start + stmvl6180-tof@29 { + reg = <0x29>; + compatible = "stmv,vl6180"; + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.5.15 for proximity sensor end +//#endif/*VENDOR_EDIT*/ + /* + nfc-nci@e { + compatible = "qcom,nfc-nci"; + reg = <0x0e>; + qcom,irq-gpio = <&msm_gpio 29 0x00>; + qcom,dis-gpio = <&msm_gpio 30 0x00>; + qcom,clk-src = "BBCLK2"; + interrupt-parent = <&msm_gpio>; + interrupts = <29 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active","nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_disable_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; + qcom,clk-gpio = <&pm8994_gpios 10 0>; + qcom,pwr-req-gpio = <&pm8994_gpios 7 0>; + clocks = <&clock_rpm clk_bb_clk2_pin>; + clock-names = "ref_clk"; + };*/ + /* lifeng@BSP 2015.3.19 synaptics touch key s1302 */ + synaptics-rmi-ts@20 { + status = "okay"; + compatible = "synaptics,s1302"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <67 0x8>; + synaptics,irq-gpio = <&msm_gpio 67 0x08>; + synaptics,reset-gpio = <&msm_gpio 94 0x00>; + //synaptics,en3v_gpio = <&msm_gpio 41 0x00>; + //vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_s4>; + }; + }; + + //#ifdef VENDOR_EDIT + //#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support + i2c@f9928000 { + haptic-drv2605@5a { + status = "okay"; + compatible = "ti,drv2605"; + //drv2605,enable-gpio = <&pm8994_gpios 4 0x1>; + drv2605,enable-gpio = <&pm8994_gpios 22 0x1>; + reg = <0x5a >; + BIDIRInput = <0x01>; //should be added + loop = <0x1>; + RTPFormat=<0x0>; + actuator.device_type=<0x1>; + actuator.rated_vol=<0x50>; + actuator.g_effect_bank=<0x06>; + actuator.over_drive_vol=<0x84>; + actuator.LRAFreq=<205>; + a2h.a2h_min_input =<0x19>; + a2h.a2h_max_input = <0xff>; + a2h.a2h_min_output =<0x19>; + a2h.a2h_max_output = <0xFF>; + }; + }; + + //#endif VENDOR_EDIT + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + + vol_up { + label = "volume_up"; + gpios = <&pm8994_gpios 3 0x1>; + linux,input-type = <1>; + linux,code = <115>; + debounce-interval = <15>; + }; + + //#ifdef VENDOR_EDIT + /*for vol- support*/ + vol_down { + label = "volume_down"; + gpios = <&pm8994_gpios 2 0x1>; + linux,input-type = <1>; + linux,code = <114>; + debounce-interval = <15>; + }; + //endif VENDOR_EDIT + /* + cam_snapshot { + label = "cam_snapshot"; + gpios = <&pm8994_gpios 4 0x1>; + linux,input-type = <1>; + linux,code = <766>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + + cam_focus { + label = "cam_focus"; + gpios = <&pm8994_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <528>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + */ + /*VENDOR_EDIT*/ + /*qiuchangping add begin for hallsensor key 2015-03-25*/ + hallsensor_key { + label = "hallsensor_key"; + gpios = <&msm_gpio 75 1>; + interrupt-parent = <&msm_gpio>; + interrupts = <75 0x0>; + linux,input-type = <5>; + linux,code = <0>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + /*qiuchangping add end*/ + + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-28 add for tristate switch keys*/ + tri_state_key { + compatible = "oneplus,tri-state-key"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + //interrupts = <77 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + tristate,gpio_key2 = <&msm_gpio 77 0x00>; //Pass a GPIO + //tristate,gpio_key2 = <&msm_gpio 61 0x00>;//use gpio61 for test,MP will use 77 + tristate,gpio_key1 = <&msm_gpio 34 0x00>; + //vdd_io-supply = <&pm8994_s4>; // 1.8V + + /* MSM GPIO active and sleep settings */ + pinctrl-names = "key2_active","key2_suspend"; + pinctrl-0 = <&tristate_key2_active>; + pinctrl-1 = <&tristate_key2_suspend>; + }; + /*#endif VENDOR_EDIT*/ +/*#ifdef VENDOR_EDIT //changhua 2015-03-13 add for switch ANTENNA by gpio*/ + switch_antenna { + compatible = "oneplus,switch-antenna"; + antenna,antenna1_gpio = <&msm_gpio 120 0x00>; + antenna,antenna2_gpio = <&msm_gpio 121 0x00>; + antenna,antenna3_gpio = <&msm_gpio 122 0x00>; + antenna,antenna4_gpio = <&msm_gpio 124 0x00>; + }; + /*#endif VENDOR_EDIT*/ + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + switch_theme { + compatible = "oneplus,switch-theme"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <66 0>; //GPIO # and flags + //interrupts = <34 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + cover,gpio_irq = <&msm_gpio 66 0x00>; //Pass a GPIO + //cover,gpio_irq = <&msm_gpio 34 0x00>; //use gpio34 for test,MP will use 66 + cover,gpio_switch = <&pm8994_gpios 1 0>; + qcom,cover-vadc = <&pm8994_vadc>; + vdd_io-supply = <&pm8994_l21>; + /* MSM GPIO active and sleep settings */ + pinctrl-names = "cover_int_active","cover_int_suspend"; + pinctrl-0 = <&cover_int_active>; + pinctrl-1 = <&cover_int_suspend>; + }; + /*#endif VENDOR_EDIT*/ + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for pa*/ + i2c@f9967000{ + status = "ok"; +test_tfa9890: tfa9890@36 { + compatible = "nxp,tfa9890"; + reg = <0x36>; + nxp,tfa_max-vol-steps=<0x01>; + reset_gpio= <&msm_gpio 106 0>; + status = "okay"; + }; + }; + //endif VENDOR_EDIT + + + sound { + qcom,model = "msm8994-tomtom-mtp-snd-card"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK", + "ultrasound amp", "LINEOUT1", + "ultrasound amp", "LINEOUT3", + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,2015/3/19, changed for 14049 mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"AMIC5", "MIC BIAS3 External", + //"MIC BIAS3 External", "Analog Mic5", + //"AMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Analog Mic6", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#else + + "AMIC2", "MIC BIAS2 External", + "MIC BIAS2 External", "Headset Mic", + /*zhiguang.su@MultiMedia.AudioDrv ,2015/6/19, not to use internal resistance*/ + "AMIC3", "MIC BIAS3 External", + "MIC BIAS3 External", "Primary Mic", + "AMIC4", "MIC BIAS1 External", + "MIC BIAS1 External", "Noise Mic"; + + + + //#endif + + + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , delete for no swap for us-euro detect*/ + /* + qcom,us-euro-gpios = <&pm8994_mpps 2 0>; + */ + //endif VENDOR_EDIT + qcom,cdc-micbias2-headset-only; + /* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,mbhc-audio-jack-type = "6-pole-jack"; + */ + qcom,mbhc-audio-jack-type = "4-pole-jack"; + /* Modified end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + qcom,ext-ult-spk-amp-gpio = <&pmi8994_gpios 1 0>; + /* Commented begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,hdmi-audio-rx; + */ + /* Commented end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + asoc-codec = <&stub_codec>, <&hdmi_audio>; + asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-audio-codec-rx"; + }; +}; + +&pm8994_gpios { + + //#ifdef VENDOR_EDIT + /* changhua.li 2015-02-13 add for cover switch theme*/ + gpio@c000 { /* GPIO 1 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + //qcom,vin-sel = <2>; /* VIN 2 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + //#ifdef VENDOR_EDIT + /*for vol- support*/ + gpio@c100 { /* GPIO 2 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + gpio@c200 { /* GPIO 3 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c300 { /* GPIO 4 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c600 { /* GPIO 7 */ + /* NFC pwr request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c900 { /* GPIO 10 */ + /* NFC clk request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c700 { /* GPIO 8 */ + qcom,mode = <0>; /* Digital in */ + qcom,pull = <0>; /* PULL up 30uA */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output high */ + qcom,vin-sel = <2>; /* Logical 1 voltage value 1.8v */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* Low drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@c800 { /* GPIO 9 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <1>; /* Output high */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* High drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@cd00 { /* GPIO 14 */ + status = "okay"; + }; + + gpio@ce00 { /* GPIO 15 */ + qcom,mode = <1>; + qcom,output-type = <0>; + qcom,pull = <5>; + qcom,vin-sel = <2>; + qcom,out-strength = <1>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@d100 { /* GPIO 18 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + qcom,vin-sel = <2>; /* VIN 2 */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@d200 { /* GPIO 19 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#ifndef VENDOR_EDIT */ +//shankai@driver.bsp 2015.4.30 add for drv 2605 enable pin control + gpio@d500 { /* GPIO 22 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#end VENDOR_EDIT*/ +}; + +&pm8994_mpps { +/*#ifndef VENDOR_EDIT //changhua 2015-02-26 remove for rare cover use ADC(PM8994 MPP4) and pcb rf use adc*/ + //mpp@a100 { /* MPP 2 */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // status = "okay"; + //}; + + //mpp@a300 { /* MPP 4 */ + // /* HDMI_5v_vreg regulator enable */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // qcom,invert = <0>; + // status = "okay"; + //}; + /*#end VENDOR_EDIT*/ +}; + +&slim_msm { + tomtom_codec { + +//#ifndef VENDOR_EDIT +// /*zhiguang.su@MultiMedia.AudioDrv ,change for 14049*/ +// qcom,cdc-micbias1-ext-cap; +// qcom,cdc-micbias3-ext-cap; +// qcom,cdc-micbias4-ext-cap; +//#endif + + cdc-vdd-spkdrv-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-current = <600000>; + + cdc-vdd-spkdrv-2-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-2-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-2-current = <600000>; + + qcom,cdc-on-demand-supplies = "cdc-vdd-spkdrv", + "cdc-vdd-spkdrv-2"; + }; +}; + +&pmi8994_gpios { + gpio@c000 { /* GPIO 1 Ultrasound PA EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* CONSTANT */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 OTG SWITCH EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; +}; + +//&pmi8994_mpps { +// mpp@a300 { /* MPP 4 */ +// /* WLED FET */ +// qcom,mode = <1>; /* DIGITAL OUT */ +// qcom,vin-sel = <0>; /* VIN0 */ +// qcom,master-en = <1>; +// status = "okay"; +// }; +//}; + +&blsp2_uart2 { + status = "ok"; +}; + +&blsp1_uart2 { + status= "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_sleep>; +}; + +&pcie0 { + status = "disabled"; +}; + +&usb3 { + status = "ok"; +}; + +&hsphy0 { + status = "ok"; +}; + +&ssphy0 { + status = "ok"; +}; + +&qcom_crypto1fde { + status = "okay"; +}; + +&qcom_crypto2fde { + status = "okay"; +}; + +&qcom_crypto1pfe { + status = "okay"; +}; + +&qcom_crypto2pfe { + status = "okay"; +}; + +&qcom_cedev { + status = "okay"; +}; + +&i2c_5 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ +//#ifdef VENDOR_EDIT + status = "disabled";//Disabled by likelong 2015.5.18, as there is no FM on 14049, and there is a conflict with Laser sensor. +//#endif/*VENDOR_EDIT*/ + compatible = "silabs,si4705"; + reg = <0x11>; + vdd-supply = <&pm8994_s4>; + silabs,vdd-supply-voltage = <1800000 1800000>; + va-supply = <&bt_vreg>; + silabs,va-supply-voltage = <3300000 3300000>; + pinctrl-names = "pmx_fm_active","pmx_fm_suspend"; + pinctrl-0 = <&fm_int_active &fm_status_int_active &fm_rst_active>; + pinctrl-1 = <&fm_int_suspend &fm_status_int_suspend &fm_rst_suspend>; + silabs,reset-gpio = <&msm_gpio 62 0>; + silabs,int-gpio = <&msm_gpio 9 0>; + silabs,status-gpio = <&msm_gpio 11 0>; + #address-cells = <0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = < + 0 &msm_gpio 9 2 + 1 &msm_gpio 11 1 + >; + interrupt-names = "silabs_fm_int", "silabs_fm_status_int"; + }; +}; + +/{ + mtp_batterydata: qcom,battery-data { + //#ifdef VENDOR_EDIT//for chg, do not match batt ID and let pmi8994 to charge now, later we will use external charger + qcom,batt-id-range-pct = <30>; + //#endif + #include "batterydata_oneplus_ATL_3300mAh.dtsi" + #include "batterydata_oneplus_SDI_3300mAh.dtsi" + #include "batterydata-unkown-3300mah.dtsi" + + }; +}; + +&pmi8994_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,ext-sense-type; +}; + +//#ifdef VENDOR_EDIT // shankai@bsp 2015-4-4 do not use it for vibrator ,comment it. +/* +&pmi8994_haptics { + status = "okay"; +}; +*/ +//#endif +&pmi8994_charger { + qcom,dc-psy-type = "Wipower"; + qcom,dcin-vadc = <&pmi8994_vadc>; + qcom,vph-vadc = <&pm8994_vadc>; + qcom,wipower-default-ilim-map = <4000000 20000000 550 700 300>; + qcom,wipower-pt-ilim-map = <4000000 7140000 550 700 300>, + <7140000 8140000 550 700 300>, + <8140000 9140000 500 700 300>, + <9140000 9950000 500 700 300>; + qcom,wipower-div2-ilim-map = <4000000 4820000 550 700 300>, + <4820000 5820000 550 700 300>, + <5820000 6820000 550 650 650>, + <6820000 7820000 550 700 600>, + <7820000 8500000 550 700 550>; +}; + +&cnss { + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &pcie0_clkreq_default>; +}; + +&i2c_11 { + smb1357-charger@1c { + compatible = "qcom,smb1357-charger"; + //#ifdef VENDOR_EDIT //for chg + status = "disabled"; + //#endif + reg = <0x1c>; + qcom,parallel-charger; + qcom,float-voltage-mv = <4400>; + qcom,recharge-thresh-mv = <100>; + }; +}; + +&usb_ehci { + status = "ok"; + qcom,usb2-enable-uicc; +}; + +&qusb_phy { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-pinctrl.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-pinctrl.dtsi new file mode 100755 index 0000000000000..10807d34bf866 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-pinctrl.dtsi @@ -0,0 +1,1632 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tlmm_pinmux: pinctrl@fd510000 { + compatible = "qcom,msm-tlmm-8994", "qcom,msm-tlmm-8974"; + reg = <0xfd510000 0x4000>; + interrupts = <0 208 0>; + + /*General purpose pins*/ + gp: gp { + qcom,num-pins = <146>; + #qcom,pin-cells = <1>; + + msm_gpio: msm_gpio { + compatible = "qcom,msm-tlmm-gp"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + qcom,direct-connect-irqs = <8>; + num_irqs = <146>; + }; + }; + + pmx-uartconsole { + qcom,pins = <&gp 4>, <&gp 5>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <2>; + label = "uart-console"; + + uart_console_sleep: uart-console { + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp2_uart2_active { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <2>; + label = "blsp2_uart2_active"; + hsuart_active: default { + drive-strength = <16>; + bias-disable; + }; + }; + + blsp2_uart2_sleep { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <0>; + label = "blsp2_uart2_sleep"; + hsuart_sleep: sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_mdss: pmx_mdss { + label = "mdss-pins"; + qcom,pin-func = <0>; + mdss_dsi_active: active { + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + mdss_dsi_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + pmx_mdss_te: pmx_mdss_te { + label = "mdss-te-pins"; + qcom,pin-func = <1>; + mdss_te_active: active { + drive-strength = <2>; /* 8 mA */ + bias-pull-down = <0>; /* pull down*/ + input-debounce = <0>; + }; + mdss_te_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + input-debounce = <0>; + }; + }; + + pmx_hdmi_cec: pmx_hdmi_cec { + qcom,pin-func = <1>; + label = "hdmi-cec-pins"; + mdss_hdmi_cec_active: cec_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_cec_suspend: cec_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_ddc: pmx_hdmi_ddc { + qcom,pin-func = <1>; + label = "hdmi-ddc-pins"; + mdss_hdmi_ddc_active: ddc_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_ddc_suspend: ddc_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_hpd: pmx_hdmi_hpd { + qcom,pin-func = <1>; + label = "hdmi-hpd-pin"; + mdss_hdmi_hpd_active: hpd_active { + drive-strength = <16>; + bias-pull-down; + }; + mdss_hdmi_hpd_suspend: hpd_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + mhl_intr: mhl_intr { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_intr"; + + mhl_intr_active: mhl_intr_active { + bias-pull-up; + input-enable; + }; + }; + + mhl_reset: mhl_reset { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_reset"; + + mhl_reset_active: mhl_reset_active { + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + spi_0_active { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-active"; + + spi_0_active: spi_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_0_suspend { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-suspend"; + + spi_0_sleep: spi_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_cs1_active { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-active"; + + spi_0_cs1_active: cs1_active { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + spi_cs1_suspend { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-suspend"; + + spi_0_cs1_sleep: cs1_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + pmx_i2c_1 { + qcom,pins = <&gp 2>, <&gp 3>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_1"; + + status = "disabled"; + + i2c_1_active: i2c_1_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_1_sleep: i2c_1_sleep { + drive-strength = <2>; + bias-disable; + }; + }; +//#ifdef VENDOR_EDIT//add for fingerprint fpc1150 SPI pin use pinctrl + + spi_12_active { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-active"; + + spi_12_active: spi_12_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_suspend { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-suspend"; + + spi_12_sleep: spi_12_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_12_cs0_active { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-active"; + + spi_12_cs0_active: cs0_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_cs0_suspend { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-suspend"; + + spi_12_cs0_sleep: cs0_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for tristate key + tristate_key2{ + qcom,pins = <&gp 77>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "tri_state_key2"; + tristate_key2_active: active { + drive-strength = <2>; + bias-disable; + }; + tristate_key2_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for switch_cover + switch_cover_int{ + qcom,pins = <&gp 66>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "switch_cover_int"; + cover_int_active: active { + drive-strength = <2>; + bias-disable; + }; + cover_int_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + + audio_ext_devices { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "audio-ext-speakers"; + /* default state */ + audio_ext_speakers: audio_ext_speakers { + drive-strength = <2>; + bias-pull-up; + }; + }; + + /* SDC pin type */ + sdc: sdc { + /* + * 0-3 for sdc1 + * 4-6 for sdc2 + * 7-9 for sdc3 + */ + qcom,num-pins = <10>; + /* + * Order of pins: + * SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 + * SDC2: CLK -> 4, CMD -> 5, DATA -> 6 + * SDC3: CLK -> 7, CMD -> 8, DATA -> 9 + */ + #qcom,pin-cells = <1>; + }; + + pmx_sdc1_clk { + qcom,pins = <&sdc 0>; + qcom,num-grp-pins = <1>; + label = "sdc1-clk"; + sdc1_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc1_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_cmd { + qcom,pins = <&sdc 1>; + qcom,num-grp-pins = <1>; + label = "sdc1-cmd"; + sdc1_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_cmd_off: cmd_off { + bias-pull-up = <0x3>; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_data { + qcom,pins = <&sdc 2>; + qcom,num-grp-pins = <1>; + label = "sdc1-data"; + sdc1_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_rclk { + qcom,pins = <&sdc 3>; + qcom,num-grp-pins = <1>; + label = "sdc1-rclk"; + sdc1_rclk_on: rclk_on { + bias-pull-down; /* pull down */ + }; + sdc1_rclk_off: rclk_off { + bias-pull-down; /* pull down */ + }; + }; + + pmx_sdc2_clk { + qcom,pins = <&sdc 4>; + qcom,num-grp-pins = <1>; + label = "sdc2-clk"; + sdc2_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc2_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_cmd { + qcom,pins = <&sdc 5>; + qcom,num-grp-pins = <1>; + label = "sdc2-cmd"; + sdc2_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_data { + qcom,pins = <&sdc 6>; + qcom,num-grp-pins = <1>; + label = "sdc2-data"; + sdc2_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_clk { + qcom,pins = <&sdc 7>; + qcom,num-grp-pins = <1>; + label = "sdc3-clk"; + sdc3_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc3_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_cmd { + qcom,pins = <&sdc 8>; + qcom,num-grp-pins = <1>; + label = "sdc3-cmd"; + sdc3_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_data { + qcom,pins = <&sdc 9>; + qcom,num-grp-pins = <1>; + label = "sdc3-data"; + sdc3_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_i2c_2 { + qcom,pins = <&gp 6>, <&gp 7>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_2"; + + i2c_2_active: i2c_2_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_2_sleep: i2c_2_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_i2c_5 { + qcom,pins = <&gp 83>, <&gp 84>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_5"; + + i2c_5_active: i2c_5_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_5_sleep: i2c_5_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_fm_int_active { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_active"; + + fm_int_active: fm_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_int_suspend { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_suspend"; + + fm_int_suspend: fm_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_active { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_active"; + + fm_status_int_active: fm_status_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_suspend { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_suspend"; + + fm_status_int_suspend: fm_status_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_rst_active { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_active"; + + fm_rst_active: fm_rst_active { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_fm_rst_suspend { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_suspend"; + + fm_rst_suspend: fm_rst_suspend { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_i2c_6 { + qcom,pins = <&gp 28>, <&gp 27>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_6"; + + i2c_6_active: i2c_6_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_6_sleep: i2c_6_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_rd_nfc_int{ + qcom,pins = <&gp 29>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_int"; + + nfc_int_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_int_suspend: suspend { + drive-strength = <6>; + bias-pull-up; + }; + }; + + pmx_nfc_reset{ + qcom,pins = <&gp 30>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_disable"; + + nfc_disable_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_disable_suspend: suspend { + drive-strength = <6>; + bias-disable; + }; + }; + +//#ifdef VENDOR_EDIT +/*suzhiguang@Multimdia.audio.driver, remove unused pins which conflic with quat i2s.*/ +// pmx_ts { +// qcom,pins = <&gp 60>, <&gp 61>; +// qcom,pin-func = <0>; +// qcom,num-grp-pins = <2>; +// label = "pmx_ts"; +// +// ts_active: ts_active { +// drive-strength = <16>; +// bias-pull-up; +// }; +// +// ts_suspend: ts_suspend { +// drive-strength = <16>; +// bias-disable; +// }; +// }; +//#endif + + /* CoreSight */ + tpiu_seta_1 { + qcom,pins = <&gp 27>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-1"; + seta_1: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_2 { + qcom,pins = <&gp 28>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-seta-2"; + seta_2: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_3 { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <10>; + label = "tpiu-seta-3"; + seta_3: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_4 { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <11>; + label = "tpiu-seta-4"; + seta_4: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_5 { + qcom,pins = <&gp 63>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "tpiu-seta-5"; + seta_5: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_6 { + qcom,pins = <&gp 64>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-6"; + seta_6: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_7 { + qcom,pins = <&gp 65>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-7"; + seta_7: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_8 { + qcom,pins = <&gp 66>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-8"; + seta_8: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_9 { + qcom,pins = <&gp 67>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-9"; + seta_9: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_10 { + qcom,pins = <&gp 74>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-10"; + seta_10: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_11 { + qcom,pins = <&gp 75>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-11"; + seta_11: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_12 { + qcom,pins = <&gp 76>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-12"; + seta_12: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_13 { + qcom,pins = <&gp 77>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-13"; + seta_13: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_14 { + qcom,pins = <&gp 85>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-14"; + seta_14: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_15 { + qcom,pins = <&gp 86>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-15"; + seta_15: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_16 { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-16"; + seta_16: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_17 { + qcom,pins = <&gp 89>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-17"; + seta_17: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_18 { + qcom,pins = <&gp 90>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-18"; + seta_18: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_1 { + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-1"; + setb_1: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_2 { + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-2"; + setb_2: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_3 { + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-3"; + setb_3: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_4 { + qcom,pins = <&gp 16>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-4"; + setb_4: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_5 { + qcom,pins = <&gp 17>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-5"; + setb_5: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_6 { + qcom,pins = <&gp 18>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-6"; + setb_6: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_7 { + qcom,pins = <&gp 19>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-7"; + setb_7: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_8 { + qcom,pins = <&gp 21>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-8"; + setb_8: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_9 { + qcom,pins = <&gp 22>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-9"; + setb_9: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_10 { + qcom,pins = <&gp 23>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-10"; + setb_10: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_11 { + qcom,pins = <&gp 25>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-setb-11"; + setb_11: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_12 { + qcom,pins = <&gp 26>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-12"; + setb_12: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_13 { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-13"; + setb_13: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_14 { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-14"; + setb_14: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_15 { + qcom,pins = <&gp 91>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-15"; + setb_15: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_16 { + qcom,pins = <&gp 92>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-setb-16"; + setb_16: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_17 { + qcom,pins = <&gp 93>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-17"; + setb_17: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_18 { + qcom,pins = <&gp 94>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-18"; + setb_18: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + cti_trigout_a { + qcom,pins = <&gp 56>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "cti-trigout-a"; + trigout_a: trigout_a { + drive-strength = <2>; + bias-disable; + }; + }; + + cti_trigout_c { + qcom,pins = <&gp 41>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "cti-trigout-c"; + trigout_c: trigout_c { + drive-strength = <2>; + bias-disable; + }; + }; + + cci0_active { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci0-active"; + /* active state */ + cci0_active: cci0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci0_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci0-suspend"; + /*suspended state */ + cci0_suspend: cci0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_active { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci1-active"; + /* active state */ + cci1_active: cci1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci1-suspend"; + /*suspended state */ + cci1_suspend: cci1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_active { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk0_active"; + /* active state */ + cam_sensor_mclk0_active: cam_sensor_mclk0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_suspend { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk0_suspend"; + /*suspended state */ + cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear_active { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_active"; + /* active state */ + cam_sensor_rear_active: cam_sensor_rear_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear_suspend { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_suspend"; + /*suspended state */ + cam_sensor_rear_suspend: cam_sensor_rear_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_active { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk1_active"; + /* active state */ + cam_sensor_mclk1_active: cam_sensor_mclk1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_suspend { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk1_suspend"; + /* suspend state */ + cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear2_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_active"; + /* active state */ + cam_sensor_rear2_active: cam_sensor_rear2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear2_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_suspend"; + /*suspended state */ + cam_sensor_rear2_suspend: cam_sensor_rear2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_active { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk2_active"; + /* active state */ + cam_sensor_mclk2_active: cam_sensor_mclk2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_suspend { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk2_suspend"; + /* suspend state */ + cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_front_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_active"; + /* active state */ + cam_sensor_front_active: cam_sensor_front_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_front_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_suspend"; + /*suspended state */ + cam_sensor_front_suspend: cam_sensor_front_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cnss_pmux: cnss_pmux { + qcom,pins = <&gp 113>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss_pins"; + cnss_default: default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + cnss_lpass: cnss_lpass { + qcom,pins = <&gp 112>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss-lpass"; + /* default state */ + cnss_lpass_default: cnss_lpass_default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pcie0_clkreq { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie0-clkreq"; + /* default state */ + pcie0_clkreq_default: pcie0_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie0_perst { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + label = "pcie0-perst"; + /* default state */ + pcie0_perst_default: pcie0_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie0_wake { + qcom,pins = <&gp 55>; + qcom,num-grp-pins = <1>; + label = "pcie0-wake"; + /* default state */ + pcie0_wake_default: pcie0_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_clkreq { + qcom,pins = <&gp 36>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie1-clkreq"; + /* default state */ + pcie1_clkreq_default: pcie1_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_perst { + qcom,pins = <&gp 35>; + qcom,num-grp-pins = <1>; + label = "pcie1-perst"; + /* default state */ + pcie1_perst_default: pcie1_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_wake { + qcom,pins = <&gp 37>; + qcom,num-grp-pins = <1>; + label = "pcie1-wake"; + /* default state */ + pcie1_wake_default: pcie1_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + + pcie1_wake_sleep: pcie1_wake_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_sec_aux_pcm_sleep { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_sleep"; + sec_aux_pcm_sleep: sec_aux_pcm_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_active { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_active"; + sec_aux_pcm_active: sec_aux_pcm_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_sec_aux_pcm_din_sleep { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_din_sleep"; + sec_aux_pcm_din_sleep: sec_aux_pcm_din_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_din_active { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_din_active"; + sec_aux_pcm_din_active: sec_aux_pcm_din_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#ifdef VENDOR_EDIT +// pmx_pri_mi2s_sleep { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sleep"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_active { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_active"; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0_sleep { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sd0_sleep"; +//pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_sd0_active { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0_active"; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; + +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ +// pmx_pri_mi2s { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0 { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0"; +// pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; +//#endif + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for quat i2s*/ + pmx_quat_mi2s { + qcom,pins = <&gp 58>, <&gp 59>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "quat_mi2s"; + quat_mi2s_sleep: quat_mi2s_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_active: quat_mi2s_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_quat_mi2s_mclk { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_mclk"; + quat_mi2s_mclk_sleep: quat_mi2s_mclk_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_mclk_active: quat_mi2s_mclk_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd0 { + qcom,pins = <&gp 60>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd0"; + quat_mi2s_sd0_sleep: quat_mi2s_sd0_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd0_active: quat_mi2s_sd0_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd1 { + qcom,pins = <&gp 61>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd1"; + quat_mi2s_sd1_sleep: quat_mi2s_sd1_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd1_active: quat_mi2s_sd1_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#endif VENDOR_EDIT + + tsif0_signals { + qcom,pins = <&gp 89>, /* TSIF0 CLK */ + <&gp 90>, /* TSIF0 Enable */ + <&gp 91>; /* TSIF0 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif0-signals"; + tsif0_signals_active: tsif0_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif0_sync { + qcom,pins = <&gp 110>; /* TSIF0 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif0-sync"; + tsif0_sync_active: tsif0_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + tsif1_signals { + qcom,pins = <&gp 93>, /* TSIF1 CLK */ + <&gp 94>, /* TSIF1 Enable */ + <&gp 95>; /* TSIF1 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif1-signals"; + tsif1_signals_active: tsif1_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif1_sync { + qcom,pins = <&gp 96>; /* TSIF1 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif1-sync"; + tsif1_sync_active: tsif1_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pm8004.dtsi new file mode 100755 index 0000000000000..c495f2c6e786b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pm8004.dtsi @@ -0,0 +1,48 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm8994-pm8994-pmi8994-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000C 0x0 0x0>; +}; + +&rpm_bus { + /delete-node/ rpm-regulator-bstb; + /delete-node/ rpm-regulator-bbyb; + /delete-node/ rpm-regulator-smpb1; + /delete-node/ rpm-regulator-smpc2; + + rpm-regulator-smpb2 { + pm8004_s2_corner: regulator-s2-corner { + regulator-name = "pm8004_s2_corner"; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + regulator-name = "pm8004_s2_floor_corner"; + }; + }; +}; + +&spmi_bus { + /delete-node/ qcom,pmi8994@2; + /delete-node/ qcom,pmi8994@3; +}; + +&usb3 { + /delete-property/ vbus_dwc3-supply; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pmi8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pmi8994-pm8004.dtsi new file mode 100755 index 0000000000000..ee5fc8594ceb2 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-pm8994-pmi8994-pm8004.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000A 0x1000C 0x0>; +}; + +&rpm_bus { + rpm-regulator-smpb2 { + status = "disabled"; + }; + + rpm-regulator-smpc2 { + status = "okay"; + regulator-s2-corner { + status = "okay"; + }; + + regulator-s2-floor-corner { + status = "okay"; + }; + }; +}; + +/* + * Override PMI8994 resources with proper PM8004 resources for + * MSM8994 with PM8004. + */ + +&soc { + qcom,msm-thermal { + vdd-gfx-supply = <&pm8004_s2_floor_corner>; + }; +}; + +&gdsc_oxili_gx { + parent-supply = <&pm8004_s2_corner>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-regulator.dtsi new file mode 100755 index 0000000000000..fe12c7b1b7e43 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-regulator.dtsi @@ -0,0 +1,987 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + /* PM8994 S1 + S6 = 2 phase VDD_CX supply */ + rpm-regulator-smpa1 { + status = "okay"; + pm8994_s1_corner: regulator-s1-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s1_floor_corner: regulator-s1-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + + pm8994_s1_corner_ao: regulator-s1-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <4>; + regulator-max-microvolt = <7>; + regulator-always-on; + qcom,init-voltage-corner = <6>; + qcom,use-voltage-corner; + proxy-supply = <&pm8994_s1_corner_ao>; + qcom,proxy-consumer-voltage = <7 7>; + }; + }; + + /* PM8994 S2 + S12 = 2 phase VDD_MX supply */ + rpm-regulator-smpa2 { + status = "okay"; + pm8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s2_corner_ao: regulator-s2-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + }; + + rpm-regulator-smpa3 { + status = "okay"; + pm8994_s3: regulator-s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <1300000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa4 { + status = "okay"; + pm8994_s4: regulator-s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa5 { + status = "okay"; + pm8994_s5: regulator-s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + qcom,init-voltage = <2150000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa7 { + status = "okay"; + pm8994_s7: regulator-s7 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa1 { + status = "okay"; + pm8994_l1: regulator-l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa2 { + status = "okay"; + pm8994_l2: regulator-l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + proxy-supply = <&pm8994_l2>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa3 { + status = "okay"; + pm8994_l3: regulator-l3 { + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>;*/ + /*#else*/ + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + /*#endif*/ + status = "okay"; + }; + }; + + rpm-regulator-ldoa4 { + status = "okay"; + pm8994_l4: regulator-l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + qcom,init-voltage = <1225000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa6 { + status = "okay"; + pm8994_l6: regulator-l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa8 { + status = "okay"; + pm8994_l8: regulator-l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa9 { + status = "okay"; + pm8994_l9: regulator-l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa10 { + status = "okay"; + pm8994_l10: regulator-l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa11 { + status = "okay"; + pm8994_l11: regulator-l11 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa12 { + status = "okay"; + pm8994_l12: regulator-l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l12>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa13 { + status = "okay"; + pm8994_l13: regulator-l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa14 { + status = "okay"; + pm8994_l14: regulator-l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l14>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa15 { + status = "okay"; + pm8994_l15: regulator-l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa16 { + status = "okay"; + pm8994_l16: regulator-l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; +//#ifdef VENDOR_EDIT //FIX GPS power issue + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa17 { + status = "okay"; + pm8994_l17: regulator-l17 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa18 { + status = "okay"; + pm8994_l18: regulator-l18 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + qcom,init-voltage = <2850000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa19 { + status = "okay"; + pm8994_l19: regulator-l19 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa20 { + status = "okay"; + pm8994_l20: regulator-l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + qcom,init-current = <750>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa21 { + status = "okay"; + pm8994_l21: regulator-l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; +//#ifdef VENDOR_EDIT //changhua modify for cover + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa22 { + status = "okay"; + pm8994_l22: regulator-l22 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <3000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa23 { + status = "okay"; + pm8994_l23: regulator-l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa24 { + status = "okay"; + pm8994_l24: regulator-l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3150000>; + qcom,init-voltage = <3075000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa25 { + status = "okay"; + pm8994_l25: regulator-l25 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa26 { + status = "okay"; + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <987500>; + regulator-max-microvolt = <987500>; + qcom,init-voltage = <987500>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa27 { + status = "okay"; + pm8994_l27: regulator-l27 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + qcom,init-voltage = <1050000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa28 { + status = "okay"; + pm8994_l28: regulator-l28 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + qcom,init-current = <45>; + regulator-boot-on; + proxy-supply = <&pm8994_l28>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa29 { + status = "okay"; + pm8994_l29: regulator-l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa30 { + status = "okay"; + pm8994_l30: regulator-l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + qcom,init-current = <50>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa32 { + status = "okay"; + pm8994_l32: regulator-l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-vsa1 { + status = "okay"; + pm8994_lvs1: regulator-lvs1 { + status = "okay"; + }; + }; + + rpm-regulator-vsa2 { + status = "okay"; + pm8994_lvs2: regulator-lvs2 { + status = "okay"; + }; + }; + + rpm-regulator-smpb1 { + status = "okay"; + pmi8994_s1: regulator-s1 { + regulator-min-microvolt = <1025000>; + regulator-max-microvolt = <1025000>; + qcom,init-voltage = <1025000>; + status = "okay"; + }; + }; + + /* PMI8994 S2 + S3 = 2 phase VDD_GFX supply */ + rpm-regulator-smpb2 { + status = "okay"; + pmi8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pmi8994_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; + + rpm-regulator-bstb { + status = "okay"; + pmi8994_boost_5v: regulator-bst { + /* + * When enabled, the PMI8994 Boost regulator always + * outputs 5V. This takes precedence over the pin + * control boost regulator request. + */ + regulator-name = "pmi8994_boost_5v"; + status = "okay"; + }; + pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl { + /* + * When enabled, the output voltage of the PMI8994 + * boost regulator is determined by the state of the + * REQ_5V_BST pin. If the pin signal is high, then the + * regulator outputs 5V. If the pin signal is low, then + * the regulator outputs VPH_PWR voltage. + */ + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost_pin_ctrl"; + qcom,set = <3>; + qcom,enable-with-pin-ctrl = <0 1>; + }; + }; + + rpm-regulator-bbyb { + status = "okay"; + pmi8994_boostbypass: regulator-bby { + status = "okay"; + regulator-min-microvolt = <3150000>; + regulator-max-microvolt = <3600000>; + qcom,init-voltage = <3150000>; + }; + }; + + /* PM8004 S2 + S4 = 2 phase VDD_GFX supply */ + rpm-regulator-smpc2 { + status = "disabled"; + pm8004_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; +}; + +/* SPM controlled regulators: */ +&spmi_bus { + qcom,pm8994@1 { + /* PM8994 S8 = VDD_APC0 supply */ + pm8994_s8: spm-regulator@2900 { + compatible = "qcom,spm-regulator"; + reg = <0x2900 0x100>; + regulator-name = "pm8994_s8"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1180000>; + qcom,cpu-num = <0>; + }; + + /* + * PM8994 S9 + S10 + S11 = 3 phase VDD_APC1 supply + * S11 is the gang leader. + */ + pm8994_s11: spm-regulator@3200 { + compatible = "qcom,spm-regulator"; + reg = <0x3200 0x100>; + regulator-name = "pm8994_s11"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1225000>; + qcom,cpu-num = <4>; + }; + }; +}; + +/* CPR controlled regulators */ +&soc { + mem_acc0_vreg_corner: mem-acc0-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900d084 1>, <0xf900d088 1>, + <0xf900d08c 1>, <0xf900d090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc0_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type2 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type3 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type4 = <0x02 0x02 0x00 0x00>; + }; + + mem_acc1_vreg_corner: mem-acc1-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900f084 1>, <0xf900f088 1>, + <0xf900f08c 1>, <0xf900f090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc1_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type2 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type3 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type4 = <0x0b 0x0b 0x0b 0x0b>; + }; + + apc0_vreg_corner: regulator@f9019000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf9019000 0x1000>, <0xf900d064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 16 0>; + regulator-name = "apc0_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <13>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1180000>; + qcom,cpr-voltage-floor = <700000 700000 780000 835000>; + vdd-apc-supply = <&pm8994_s8>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc0_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <12>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <82 82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <800000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 3 3 3 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0xFFFFFFFF 0 900000 900000 900000 900000 + 1000000 1000000 1000000 1115000 + 1115000 1180000 1180000 1180000 + 1180000>; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 700000 700000 700000 725000 + 780000 800000 825000 835000 + 850000 915000 970000 980000 + 1000000>; + + qcom,cpr-fuse-version-map = + <0xffffffff 0xffffffff 1 0 0 0 0>, + <0xffffffff 0xffffffff 2 0 0 0 0>, + <0xffffffff 0xffffffff 3 0 0 0 0>, + <0xffffffff 0xffffffff 4 0 0 0 0>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-50)>, + <0 0 0 (-50)>, + <0 (-50) (-90) 40>, + <0 (-50) (-90) 0>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-25000)>, + <0 0 0 (-25000)>, + <0 (-25000) (-25000) 20000>, + <0 (-25000) (-25000) 0>; + + qcom,cpr-scaled-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for SVS2 */ + <2 300000000>, + <3 384000000>, + <4 460800000>, + <5 600000000>, + <6 672000000>, + <7 768000000>, + <8 864000000>, + <9 960000000>, + <10 1248000000>, + <11 1344000000>, + <12 1478400000>, + <13 1555200000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 4 7 13>; + qcom,cpr-enable; + }; + + apc1_vreg_corner: regulator@f901a000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf901a000 0x1000>, <0xf900f064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 19 0>; + regulator-name = "apc1_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <17>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1225000>; + qcom,cpr-voltage-floor = <700000 700000 750000 835000>; + vdd-apc-supply = <&pm8994_s11>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc1_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <14 14 12 12 12 12 7 8>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,cpr-clamp-timer-interval = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <21 29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <72 72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + qcom,speed-bin-fuse-sel = <22 0 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <0 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>, + <1 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>; + qcom,cpr-voltage-floor-override = + <0 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>, + <1 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>; + + qcom,cpr-fuse-version-map = + <0 0xffffffff 1 6 6 6 6>, + <0 0xffffffff 2 6 6 6 6>, + <0 0xffffffff 2 4 4 4 4>, + <0 0xffffffff 3 4 4 4 4>, + <0 0xffffffff 4 4 4 4 4>, + <1 0xffffffff 3 4 4 4 4>, + <1 0xffffffff 4 4 4 4 4>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-24)>, + <0 0 0 (-24)>, + <0 0 0 (-84)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>; + qcom,cpr-cpus = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,cpr-online-cpu-virtual-corner-init-voltage-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + qcom,cpr-online-cpu-virtual-corner-quotient-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + + qcom,cpr-online-cpu-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for "SVS2" */ + <2 300000000>, + <3 384000000>, + <4 480000000>, + <5 633600000>, + <6 768000000>, + <7 864000000>, + <8 960000000>, + <9 1248000000>, + <10 1344000000>, + <11 1440000000>, + <12 1536000000>, + <13 1632000000>, + <14 1728000000>, + <15 1766400000>, + <16 1824000000>, + <17 1958400000>; + qcom,cpr-speed-bin-max-corners = + <0 0 1 5 8 17>, + <1 0 1 5 8 15>; + qcom,cpr-enable; + }; + + bt_vreg: bt_vreg { + compatible = "regulator-fixed"; + regulator-name = "bt_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8994_gpios 9 0>; + }; + + usb_otg_switch: usb-otg-switch { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vreg"; + vin-supply = <&smbcharger_external_otg>; + enable-active-high; + gpio = <&pmi8994_gpios 5 0>; + }; +}; + +&pmi8994_charger { + otg-parent-supply = <&pmi8994_boost_5v>; + smbcharger_charger_otg: qcom,smbcharger-boost-otg { + regulator-name = "smbcharger_charger_otg"; + }; + + smbcharger_external_otg: qcom,smbcharger-external-otg { + regulator-name = "smbcharger_external_otg"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-smp2p.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-smp2p.dtsi new file mode 100755 index 0000000000000..c40cdaf335e8b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-smp2p.dtsi @@ -0,0 +1,169 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +&soc { + qcom,smp2p-modem { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <1>; + qcom,irq-bitmask = <0x4000>; + interrupts = <0 27 1>; + }; + + qcom,smp2p-adsp { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <2>; + qcom,irq-bitmask = <0x400>; + interrupts = <0 158 1>; + }; + + smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_in { + compatible = "qcom,smp2pgpio_test_smp2p_7_in"; + gpios = <&smp2pgpio_smp2p_7_in 0 0>; + }; + + smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_out { + compatible = "qcom,smp2pgpio_test_smp2p_7_out"; + gpios = <&smp2pgpio_smp2p_7_out 0 0>; + }; + + smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_in { + compatible = "qcom,smp2pgpio_test_smp2p_1_in"; + gpios = <&smp2pgpio_smp2p_1_in 0 0>; + }; + + smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_out { + compatible = "qcom,smp2pgpio_test_smp2p_1_out"; + gpios = <&smp2pgpio_smp2p_1_out 0 0>; + }; + + smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_in { + compatible = "qcom,smp2pgpio_test_smp2p_2_in"; + gpios = <&smp2pgpio_smp2p_2_in 0 0>; + }; + + smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_out { + compatible = "qcom,smp2pgpio_test_smp2p_2_out"; + gpios = <&smp2pgpio_smp2p_2_out 0 0>; + }; + + /* ssr - inbound entry from lpass. */ + smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to lpass */ + smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - inbound entry from mss. */ + smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to mss. */ + smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-mtp_14049_HW_11.dts b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-mtp_14049_HW_11.dts new file mode 100755 index 0000000000000..37c79055d8250 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-mtp_14049_HW_11.dts @@ -0,0 +1,26 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8994-v1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <11>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-pm.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-pm.dtsi new file mode 100755 index 0000000000000..371c020d1aa30 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1-pm.dtsi @@ -0,0 +1,593 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-ret = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900D210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 1f 18 03 2f 1b 18 7b d0 2b e0 3b c0 16 6b 26 6b 18 00 + 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d0 2b e0 3b + c0 16 6b 26 6b 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-retention"; + qcom,spm-cci-mode = "retention"; + qcom,latency-us = <45>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11609>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <1>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1375>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <760>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <775>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <40>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1505>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <647>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <653>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 332>, /* sps */ + <0xff 333>; /* ipa */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v1.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1.dtsi new file mode 100755 index 0000000000000..447a74220a008 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v1.dtsi @@ -0,0 +1,246 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v1.dtsi" +#include "msm8994-v1-pm.dtsi" +#include "msm8994-camera-v1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x10000>; + +}; + +&soc { + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 14 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + qcom,apply-cti-pmu-wa; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 14 0xff00>; + qcom,apply-cti-pmu-wa; + }; + + cci@f9100000 { + pmu@a000 { + interrupts = <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>; + }; + }; +}; + +&pm8994_s8 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1115000>; +}; + +&pm8994_s11 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1225000>; +}; + +&ufs1 { + freq-table-hz = + <100000000 171430000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +&mem_acc0_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&mem_acc1_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&apc0_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <9>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1115000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <16>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <116 0 73>; + qcom,cpr-fuse-ro-sel = <82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 800000 840000 860000 860000 + 900000 900000 940000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>, + <9 940800000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 9>; + qcom,cpr-enable; +}; + +&apc1_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <8>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1225000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <10>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <36 45 0>; + qcom,cpr-fuse-ro-sel = <72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 790000 840000 840000 860000 + 890000 920000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 8>; + qcom,cpr-enable; +}; + +&soc { + qcom,usbbam@f9304000 { + qcom,pipe0 { + qcom,pipe-connection-type = <1>; /* USB_BAM_PIPE_SYS2BAM */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2-pm.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2-pm.dtsi new file mode 100755 index 0000000000000..9272b2a079326 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2-pm.dtsi @@ -0,0 +1,690 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900d210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 38 48 26 6b 18 03 2f 1b 18 7b + 26 6b 40 40 48 38 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 03 2f 1b 18 7b d2 2b e2 3b c0 16 6b 26 6b 48 + 18 00 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x8>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 48 26 6b 18 03 2f 1b 18 7b 26 + 6b 40 40 48 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d2 2b + e2 3b c0 16 6b 26 6b 48 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-wfi"; + qcom,spm-cci-mode = "wfi"; + qcom,latency-us = <90>; + qcom,ss-power = <307>; + qcom,energy-overhead = <81180>; + qcom,time-overhead = <180>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11260>; + qcom,ss-power = <89>; + qcom,energy-overhead = <6959381>; + qcom,time-overhead = <5431>; + qcom,min-child-idx = <2>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <159>; + qcom,energy-overhead = <29640>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <148>; + qcom,energy-overhead = <44460>; + qcom,time-overhead = <180>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <800>; + qcom,ss-power = <104>; + qcom,energy-overhead = <432250>; + qcom,time-overhead = <1750>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <50>; + qcom,ss-power = <65>; + qcom,energy-overhead = <10650>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <100>; + qcom,ss-power = <51>; + qcom,energy-overhead = <15975>; + qcom,time-overhead = <150>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <400>; + qcom,ss-power = <50>; + qcom,energy-overhead = <74550>; + qcom,time-overhead = <700>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <480>; + qcom,ss-power = <30>; + qcom,energy-overhead = <85200>; + qcom,time-overhead = <800>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <80>; + qcom,ss-power = <270>; + qcom,energy-overhead = <72160>; + qcom,time-overhead = <160>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <190>; + qcom,ss-power = <189>; + qcom,energy-overhead = <157850>; + qcom,time-overhead = <350>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1260>; + qcom,ss-power = <93>; + qcom,energy-overhead = <1318724>; + qcom,time-overhead = <2924>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <117>; + qcom,energy-overhead = <31200>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <93>; + qcom,energy-overhead = <46800>; + qcom,time-overhead = <180>; + qcom,use-broadcast-timer; + }; + + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <475>; + qcom,ss-power = <66>; + qcom,energy-overhead = <201500>; + qcom,time-overhead = <775>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <636>; + qcom,ss-power = <60>; + qcom,energy-overhead = <248560>; + qcom,time-overhead = <956>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 20>, /* arch_timer */ + <0xff 23>, /* ARM64 Single-Bit Error PMU IRQ */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 48>, /* cpr */ + <0xff 51>, /* cpr */ + <0xff 54>, /* CCI error IRQ */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 164>, /* sps */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 212>, /* msm_dwc3 */ + <0xff 215>, /* fc388000.qcom,cpu-bwmon */ + <0xff 224>, /* spdm_bw_hyp */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 261>, /* msm_iommu_global_cfg */ + <0xff 263>, /* msm_iommu_global_client */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 272>, /* msm_iommu_secure_irq */ + <0xff 273>, /* msm_iommu_nonsecure_irq */ + <0xff 275>, /* int_msi */ + <0xff 283>, /* int_pls_err */ + <0xff 284>, /* int_aer_legacy */ + <0xff 286>, /* int_pls_link_down */ + <0xff 298>, /* msm_iommu_nonsecure_irq */ + <0xff 302>, /* coresight-tmc-etr */ + <0xff 303>, /* int_msi */ + <0xff 310>, /* int_pls_err */ + <0xff 311>, /* int_aer_legacy */ + <0xff 313>, /* int_pls_link_down */ + <0xff 329>, /* sps */ + <0xff 332>, /* sps */ + <0xff 333>, /* ipa */ + <0xff 348>, /* fd878000.qcom,fd */ + <0xff 350>, /* msm_iommu_nonsecure_irq */ + <0xff 360>, /* ARM64 primary DBE IRQ */ + <0xff 361>, /* ARM64 secondary DBE IRQ */ + <0xff 362>, /* ARM64 primary ext IRQ */ + <0xff 363>, /* ARM64 secondary ext IRQ */ + <0xff 364>; /* lmh_interrupt */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu4_clk", "cpu5_clk", "cpu6_clk", + "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,no-pll-switch-for-retention; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; + + qcom,npa-dump@0xfc190020 { + compatible = "qcom,npa-dump"; + reg = <0xfc190020 0x4>, <0xfc000000 0x1c00>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0-mtp_14049_HW_11.dts b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0-mtp_14049_HW_11.dts new file mode 100755 index 0000000000000..8dc8dc69c661a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0-mtp_14049_HW_11.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.0.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.0 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <11>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0.dtsi new file mode 100755 index 0000000000000..b824d0c5d195c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.0.dtsi @@ -0,0 +1,35 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.0"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20000>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030001>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1-mtp_14049_HW_11.dts b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1-mtp_14049_HW_11.dts new file mode 100755 index 0000000000000..61f07b74609d7 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1-mtp_14049_HW_11.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.1 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <11>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1.dtsi new file mode 100755 index 0000000000000..93bc398c9693f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.1.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.1"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20001>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030002>; + qcom,gpu-pwrlevels { + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <630000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + }; + qcom,ocmem-bus-client { + qcom,msm-bus,vectors-KBps = + <89 662 0 10080000>, /* gpu= 630 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.dtsi new file mode 100755 index 0000000000000..add83045413a4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994-v2.dtsi @@ -0,0 +1,428 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v2.dtsi" +#include "msm8994-camera-v2.dtsi" + +&soc { + + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 7 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 7 0xff00>; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon2"; + }; + + qcom,lmh { + compatible = "qcom,lmh"; + interrupts = <0 332 4>; + reg = <0xF9117000 0x4>; + qcom,lmh-trim-err-offset = <18>; + }; +}; + +/* Clock driver overrides */ +&clock_gcc { + compatible = "qcom,gcc-8994v2"; +}; + +&clock_mmss { + compatible = "qcom,mmsscc-8994v2"; +}; + +&clock_cpu { + compatible = "qcom,cpu-clock-8994-v2"; + vdd-dig-supply = <&pm8994_s2_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 384000000 3>, + < 460800000 4>, + < 600000000 5>, + < 672000000 6>, + < 768000000 7>, + < 864000000 8>, + < 960000000 9>, + < 1248000000 10>, + < 1344000000 11>, + < 1478400000 12>, + < 1555200000 13>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1728000000 14>, + < 1824000000 16>, + < 1958400000 17>; + qcom,a57-speedbin1-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1766400000 15>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 300000000 4>, + < 384000000 5>, + < 537600000 7>, + < 600000000 9>, + < 729600000 10>, + < 787200000 11>; +}; + +&cci_cache { + freq-tbl-khz = + < 300000 >, + < 384000 >, + < 537600 >, + < 600000 >, + < 729600 >, + < 787200 >; +}; + +&msm_cpufreq { + qcom,cpufreq-table-0 = + < 384000 >, + < 460800 >, + < 600000 >, + < 672000 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1478400 >, + < 1555200 >; + + qcom,cpufreq-table-4 = + < 384000 >, + < 480000 >, + < 633600 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1440000 >, + < 1536000 >, + < 1632000 >, + < 1728000 >, + < 1824000 >, + < 1958400 >; +}; + +&devfreq_cpufreq { + cpubw-cpufreq { + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5928 >, + < 1248000 7904 >, + < 1344000 9887 >, + < 1478400 11863 >, + < 1555200 11863 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 2288 >, + < 633600 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5126 >, + < 1248000 5928 >, + < 1344000 7904 >, + < 1440000 7904 >, + < 1536000 7904 >, + < 1632000 9887 >, + < 1728000 9887 >, + < 1824000 11863 >, + < 1958400 11863 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1478400 1525 >, + < 1555200 1525 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 1525 >, + < 633600 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1440000 1525 >, + < 1536000 1525 >, + < 1632000 1525 >, + < 1728000 1525 >, + < 1824000 1525 >, + < 1958400 7904 >; + }; + + cci-cpufreq { + cpu-to-dev-map-0 = + < 384000 300000 >, + < 460800 300000 >, + < 600000 300000 >, + < 672000 384000 >, + < 768000 384000 >, + < 864000 537600 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 787200 >, + < 1478400 787200 >, + < 1555200 787200 >; + cpu-to-dev-map-4 = + < 384000 300000 >, + < 480000 300000 >, + < 633600 384000 >, + < 768000 537600 >, + < 864000 600000 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 729600 >, + < 1440000 729600 >, + < 1536000 787200 >, + < 1632000 787200 >, + < 1728000 787200 >, + < 1824000 787200 >, + < 1958400 787200 >; + }; +}; + +/* GPU VBIF overrides */ +&gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5271 /* 691 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; +}; + +/* GPU overrides */ +&msm_gpu { + qcom,initial-pwrlevel = <4>; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1600000>, /* 1 bus=200 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3680000>, /* 3 bus=460 */ + <26 512 0 4376000>, /* 4 bus=547 */ + <26 512 0 5528000>, /* 5 bus=691 */ + <26 512 0 6216000>, /* 6 bus=777 */ + <26 512 0 8288000>, /* 7 bus=1036 */ + <26 512 0 10368000>, /* 8 bus=1296 */ + <26 512 0 12440000>; /* 9 bus=1555 */ + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <510000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <450000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <390000000>; + qcom,bus-freq = <5>; + qcom,bus-min = <4>; + qcom,bus-max = <6>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <305000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <4>; + }; + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <180000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <27000000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <7>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu= 600 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; + +&ufs1 { + freq-table-hz = + <100000000 200000000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +/* MDSS driver overrides */ +&mdss_mdp { + qcom,mdp-settings = <0x0117c 0x0000ffff>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; +}; + +/* Video driver overrides */ +&msm_vidc { + qcom,load-freq-tbl = + <979200 510000000 0x0c000000>, + <979200 510000000 0x01000414>, + <979200 510000000 0x030fcfff>, + <979200 510000000 0x04000000>, + <783360 510000000 0x0c000000>, + <783360 510000000 0x01000414>, + <783360 510000000 0x030fcfff>, + <783360 510000000 0x04000000>, + <489600 320000000 0x0c000000>, + <489600 320000000 0x01000414>, + <489600 320000000 0x030fcfff>, + <489600 320000000 0x04000000>, + <244800 150000000 0x0c000000>, + <244800 150000000 0x01000414>, + <244800 150000000 0x030fcfff>, + <244800 150000000 0x04000000>; +}; + +&cnss { + wlan-bootstrap-gpio = <&msm_gpio 112 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &cnss_lpass_default>; +}; + +#include "msm8994-v2-pm.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_11/msm8994.dtsi b/arch/arm64/boot/dts/14049_HW_11/msm8994.dtsi new file mode 100755 index 0000000000000..a9939b5726c94 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/msm8994.dtsi @@ -0,0 +1,3792 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/memreserve/ 0x00000000 0x00001000; +/memreserve/ 0xac1c0000 0x00001000; + +#include "skeleton64.dtsi" +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x0>; + qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>; + interrupt-parent = <&intc>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; + + aliases { + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + /*do not enable sdhc2 and sdhc3 + sdhc2 = &sdhc_2; + sdhc3 = &sdhc_3; + */ + i2c6 = &i2c_6; /* I2C6 NFC qup6 device */ + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c5 = &i2c_5; + spi0 = &spi_0; + /*#ifdef VENDOR_EDIT modify for fpc1021 fingerprints*/ + spi12 = &spi_12; + /*#end VENDOR_EDIT*/ + qup2 = &i2c_2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU4>; + }; + core1 { + cpu = <&CPU5>; + }; + core2 { + cpu = <&CPU6>; + }; + core3 { + cpu = <&CPU7>; + }; + }; + }; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc0>; + qcom,ldo = <&ldo0>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + power-domain = <&l2ccc_0>; + qcom,dump-size = <0x0>; /* A53 L2 dump not supported */ + L2_tlb_0: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc1>; + qcom,ldo = <&ldo1>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc2>; + qcom,ldo = <&ldo2>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc3>; + qcom,ldo = <&ldo3>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc4>; + qcom,ldo = <&ldo4>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + qcom,dump-size = <0x280040>; /*A57 Cluster L2 size is 1MB */ + power-domain = <&l2ccc_1>; + L2_tlb_1: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_itlb_100: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_100: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc5>; + qcom,ldo = <&ldo5>; + next-level-cache = <&L2_1>; + L1_itlb_101: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_101: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x102>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc6>; + qcom,ldo = <&ldo6>; + next-level-cache = <&L2_1>; + L1_itlb_102: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_102: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x103>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc7>; + qcom,ldo = <&ldo7>; + next-level-cache = <&L2_1>; + L1_itlb_103: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_103: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + }; + + soc: soc { }; + + memory { + #address-cells = <2>; + #size-cells = <2>; + + secure_mem: secure_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x12c00000>; + label = "secure_mem"; + }; + + adsp_mem: adsp_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x3F00000>; + label = "adsp_mem"; + }; + + qsecom_mem: qsecom_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x1800000>; + label = "qseecom_mem"; + }; + + audio_mem: audio_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0 0 0x614000>; + label = "audio_mem"; + }; + + removed_regions: removed_regions@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x06300000 0 0xD00000>; + label = "memory_hole"; + }; + /*#ifdef VENDOR_EDIT*/ + /*Add by LiWei. The region is used for nv backup,20150325*/ + nabackup_regions: nvbackup_regions@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for nv backup + //linux,remove-completely;//del by jiachenghui for nv backup + reg = <0 0x06200000 0 0x100000>; + label = "memory_nvbackup"; + }; + /*End by LiWei. The region is used for nv backup, 20150325*/ + /*#endif VENDOR_EDIT*/ + dfps_data_mem: dfps_data_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03400000 0 0x1000>; + label = "dfps_data_mem"; + }; +/*liyunbing@BSP,20150518 revert MIPI_FB_ADDR to default addr, because we located MDSS issue cause by nvbackup*/ + cont_splash_mem: cont_splash_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03401000 0 0x2200000>; + //reg = <0 0x83200000 0 0x2200000>; + label = "cont_splash_mem"; + }; + + peripheral_mem: peripheral_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x0ca00000 0 0x1f00000>; + label = "peripheral_mem"; + }; +/*#ifdef VENDOR_EDIT //changhua.li add for enlarge TZ APP memory to 25M*/ + tzapp_mem: tzapp_region@0 { + + linux,reserve-contiguous-region; + + linux,reserve-region; + + linux,remove-completely; + + reg = <0 0x0E900000 0 0x1900000>; + + label = "tzapp_mem"; + + }; +/*#endif VENDOR_EDIT*/ + + + modem_mem: modem_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x07000000 0 0x5a00000>; + label = "modem_mem"; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops_mem: ramoops_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for ramoops reserve region + //linux,remove-completely;//del by jiachenghui for ramoops reserve region + reg = <0 0xac000000 0 0x00100000>;//modify from 0x05800000 to 0xac000000 by jiachenghui for ramoops reserve region + label = "ramoops_mem"; + }; +/* #endif VENDOR_EDIT */ + + param_mem: param_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region; + //linux,remove-completely; + reg = <0 0xac200000 0 0x00100000>; + label = "param_mem"; + }; + + }; +}; + +#include "msm-gdsc.dtsi" +#include "msm8994-smp2p.dtsi" +#include "msm8994-ipcrouter.dtsi" +#include "msm8994-mdss.dtsi" +#include "msm8994-mdss-pll.dtsi" +#include "msm8994-bus.dtsi" + +&soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + cpuss@fd4a8000 { + compatible = "qcom,cpuss-8994"; + reg = <0xfd4a8000 0x4>; + }; + + acc0:clock-controller@f908b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9070000 0x1000>, + <0xf908b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc1:clock-controller@f909b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9071000 0x1000>, + <0xf909b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc2:clock-controller@f90ab004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9072000 0x1000>, + <0xf90ab000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc3:clock-controller@f90bb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9073000 0x1000>, + <0xf90bb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc4:clock-controller@f90cb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9074000 0x1000>, + <0xf90cb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc5:clock-controller@f90db004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9075000 0x1000>, + <0xf90db000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc6:clock-controller@f90eb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9076000 0x1000>, + <0xf90eb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc7:clock-controller@f90fb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9077000 0x1000>, + <0xf90fb000 0x1000>, + <0xf900b000 0x1000>; + }; + + ldo0:ldo-vref@f9070000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9070000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo1:ldo-vref@f9071000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9071000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo2:ldo-vref@f9072000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9072000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo3:ldo-vref@f9073000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9073000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo4:ldo-vref@f9074000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9074000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo5:ldo-vref@f9075000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9075000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo6:ldo-vref@f9076000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9076000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo7:ldo-vref@f9077000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9077000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + l2ccc_0: clock-controller@f900d000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900d000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster0_spm>; + }; + + l2ccc_1: clock-controller@f900f000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900f000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster1_spm>; + qcom,vctl-val = <0xb8>; + }; + + intc: interrupt-controller@f9000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0xf9000000 0x1000>, + <0xf9002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 2 0xff08>, + <1 3 0xff08>, + <1 4 0xff08>, + <1 1 0xff08>; + clock-frequency = <19200000>; + }; + + qcom,mpm2-sleep-counter@fc4a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0xfc4a3000 0x1000>; + clock-frequency = <32768>; + }; + + timer@f9020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xf9020000 0x1000>; + clock-frequency = <19200000>; + + frame@f9021000 { + frame-number = <0>; + interrupts = <0 9 0x4>, + <0 8 0x4>; + reg = <0xf9021000 0x1000>, + <0xf9022000 0x1000>; + }; + + frame@f9023000 { + frame-number = <1>; + interrupts = <0 10 0x4>; + reg = <0xf9023000 0x1000>; + status = "disabled"; + }; + + frame@f9024000 { + frame-number = <2>; + interrupts = <0 11 0x4>; + reg = <0xf9024000 0x1000>; + status = "disabled"; + }; + + frame@f9025000 { + frame-number = <3>; + interrupts = <0 12 0x4>; + reg = <0xf9025000 0x1000>; + status = "disabled"; + }; + + frame@f9026000 { + frame-number = <4>; + interrupts = <0 13 0x4>; + reg = <0xf9026000 0x1000>; + status = "disabled"; + }; + + frame@f9027000 { + frame-number = <5>; + interrupts = <0 14 0x4>; + reg = <0xf9027000 0x1000>; + status = "disabled"; + }; + + frame@f9028000 { + frame-number = <6>; + interrupts = <0 15 0x4>; + reg = <0xf9028000 0x1000>; + status = "disabled"; + }; + }; + + restart@fc4ab000 { + compatible = "qcom,pshold"; + reg = <0xfc4ab000 0x4>; + }; + + blsp1_uart3: serial@f991f000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991f000 0x1000>; + interrupts = <0 109 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp1_uart2: serial@f991e000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp2_uart2: uart@f995e000 { /* BLSP2 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xf995e000 0x1000>, + <0xf9944000 0x19000>; + status = "disabled"; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 114 0 + 1 &intc 0 239 0 + 2 &msm_gpio 46 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xFD>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp2_ahb_clk>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&hsuart_sleep>; + pinctrl-1 = <&hsuart_active>; + + qcom,msm-bus,name = "buart8"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + }; + + qcom,sps@f9984000 { + compatible = "qcom,msm_sps"; + reg-names = "bam_mem", "core_mem"; + reg = <0xf9984000 0x15000>, + <0xf9999000 0xb000>; + interrupts = <0 94 0>; + qcom,pipe-attr-ee; + clocks = <&clock_rpm clk_pnoc_sps_clk>, + <&clock_gcc clk_gcc_bam_dma_ahb_clk>; + clock-names = "dfab_clk", "dma_bam_pclk"; + }; + + pcie0: qcom,pcie@fc520000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0xfc520000 0x2000>, + <0xfc526000 0x1000>, + <0xff000000 0xf1d>, + <0xff000f20 0xa8>, + <0xff100000 0x100000>, + <0xff200000 0x100000>, + <0xff300000 0xd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie0>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 243 0 + 1 &intc 0 244 0 + 2 &intc 0 245 0 + 3 &intc 0 247 0 + 4 &intc 0 248 0 + 5 &intc 0 249 0 + 6 &intc 0 250 0 + 7 &intc 0 251 0 + 8 &intc 0 252 0 + 9 &intc 0 253 0 + 10 &intc 0 254 0 + 11 &intc 0 255 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; + + perst-gpio = <&msm_gpio 53 0>; + wake-gpio = <&msm_gpio 55 0>; + + gdsc-vdd-supply = <&gdsc_pcie_0>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9006040>; + qcom,msi-gicm-base = <0x180>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + qcom,scm-dev-id = <11>; + + clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_0_aux_clk>, + <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, + <&clock_gcc clk_pcie_0_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_0_reset>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", "pcie_0_aux_clk", + "pcie_0_cfg_ahb_clk", "pcie_0_mstr_axi_clk", + "pcie_0_slv_axi_clk", "pcie_0_ldo", "pcie_0_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + pcie1: qcom,pcie@fc528000 { + compatible = "qcom,pci-msm"; + cell-index = <1>; + + reg = <0xfc528000 0x2000>, + <0xfc52e000 0x1000>, + <0xf8800000 0xf1d>, + <0xf8800F20 0xa8>, + <0xf8801000 0x7f000>, + <0xf8880000 0x80000>, + <0xf8900000 0x700000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie1>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 271 0 + 1 &intc 0 272 0 + 2 &intc 0 273 0 + 3 &intc 0 274 0 + 4 &intc 0 275 0 + 5 &intc 0 276 0 + 6 &intc 0 277 0 + 7 &intc 0 278 0 + 8 &intc 0 279 0 + 9 &intc 0 280 0 + 10 &intc 0 281 0 + 11 &intc 0 282 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>; + pinctrl-1 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_sleep>; + + perst-gpio = <&msm_gpio 35 0>; + wake-gpio = <&msm_gpio 37 0>; + + gdsc-vdd-supply = <&gdsc_pcie_1>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,l1-supported; + qcom,l1ss-supported; + qcom,aux-clk-sync; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9007040>; + qcom,msi-gicm-base = <0x1a0>; + + qcom,ep-wakeirq; + + qcom,msm-bus,name = "pcie1"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, + <100 512 500 800>; + + qcom,scm-dev-id = <12>; + + clocks = <&clock_gcc clk_gcc_pcie_1_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_1_aux_clk>, + <&clock_gcc clk_gcc_pcie_1_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_1_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_1_slv_axi_clk>, + <&clock_gcc clk_pcie_1_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_1_reset>; + + clock-names = "pcie_1_pipe_clk", "pcie_1_ref_clk_src", "pcie_1_aux_clk", + "pcie_1_cfg_ahb_clk", "pcie_1_mstr_axi_clk", + "pcie_1_slv_axi_clk", "pcie_1_ldo", "pcie_1_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + ipa_hw: qcom,ipa@fd4c0000 { + compatible = "qcom,ipa"; + reg = <0xfd4c0000 0x29000>, + <0xfd4c4000 0x15820>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 301 0>, + <0 300 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <3>; /* IPA core version = IPAv2.0 */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; + qcom,ee = <2>; + clock-names = "core_clk"; + clocks = <&clock_rpm clk_ipa_clk>; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <90 512 0 0>, <90 585 0 0>, /* No vote */ + <90 512 100000 800000>, <90 585 100000 800000>, /* SVS */ + <90 512 100000 1200000>, <90 585 100000 1200000>; /* PERF */ + qcom,bus-vector-names = "MIN", "SVS", "PERF"; + + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + }; + + qcom,ipc-spinlock@fd484000 { + compatible = "qcom,ipc-spinlock-sfpb"; + reg = <0xfd484000 0x400>; + qcom,num-locks = <8>; + }; + + qcom,smem@6a00000 { + compatible = "qcom,smem"; + reg = <0x6a00000 0x200000>, + <0xf900d008 0x4>, + <0xfc428000 0x4000>; + reg-names = "smem", "irq-reg-base", "aux-mem1"; + qcom,mpu-enabled; + + qcom,smd-modem { + compatible = "qcom,smd"; + qcom,smd-edge = <0>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1000>; + interrupts = <0 25 1>; + label = "modem"; + qcom,not-loadable; + }; + + qcom,smsm-modem { + compatible = "qcom,smsm"; + qcom,smsm-edge = <0>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x2000>; + interrupts = <0 26 1>; + }; + + qcom,smd-adsp { + compatible = "qcom,smd"; + qcom,smd-edge = <1>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x100>; + interrupts = <0 156 1>; + label = "adsp"; + }; + + qcom,smsm-adsp { + compatible = "qcom,smsm"; + qcom,smsm-edge = <1>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x200>; + interrupts = <0 157 1>; + }; + + qcom,smd-rpm { + compatible = "qcom,smd"; + qcom,smd-edge = <15>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1>; + interrupts = <0 168 1>; + label = "rpm"; + qcom,irq-no-suspend; + qcom,not-loadable; + }; + }; + + qcom,msm-imem@fe87f000 { + compatible = "qcom,msm-imem"; + reg = <0xfe87f000 0x1000>; /* Address and size of IMEM */ + ranges = <0x0 0xfe87f000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + download_mode@0 { + compatible = "qcom,msm-imem-download_mode"; + reg = <0x0 8>; + }; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + + pil@94c { + compatible = "qcom,msm-imem-pil"; + reg = <0x94c 200>; + }; + + emergency_download_mode@fe0 { + compatible = "qcom,msm-imem-emergency_download_mode"; + reg = <0xfe0 12>; + }; + }; + + qcom,wdt@f9017000 { + compatible = "qcom,msm-watchdog"; + reg = <0xf9017000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 3 0>, <0 4 0>; +//liyunbing@BSP, 2015/05/21, WDT bark-time too short cause some task timeout + #qcom,bark-time = <11000>; + qcom,bark-time = <15000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + }; + + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + jtag_fuse: jtagfuse@fc4be024 { + compatible = "qcom,jtag-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + }; + + jtag_mm0: jtagmm@fb840000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb840000 0x1000>, + <0xfb810000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU0>; + }; + + jtag_mm1: jtagmm@fb940000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb940000 0x1000>, + <0xfb910000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU1>; + }; + + jtag_mm2: jtagmm@fba40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfba40000 0x1000>, + <0xfba10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU2>; + }; + + jtag_mm3: jtagmm@fbb40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbb40000 0x1000>, + <0xfbb10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU3>; + }; + + jtag_mm4: jtagmm@fbc40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbc40000 0x1000>, + <0xfbc10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU4>; + }; + + jtag_mm5: jtagmm@fbd40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbd40000 0x1000>, + <0xfbd10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU5>; + }; + + jtag_mm6: jtagmm@fbe40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbe40000 0x1000>, + <0xfbe10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU6>; + }; + + jtag_mm7: jtagmm@fbf40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbf40000 0x1000>, + <0xfbf10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU7>; + }; + + rpm_bus: qcom,rpm-smd { + compatible = "qcom,rpm-smd"; + rpm-channel-name = "rpm_requests"; + rpm-channel-type = <15>; /* SMD_APPS_RPM */ + }; + + qcom,msm-rng@f9bff000 { + compatible = "qcom,msm-rng"; + reg = <0xf9bff000 0x200>; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 618 0 0>, + <88 618 0 800>; + qcom,msm-rng-iface-clk; + clocks = <&clock_gcc clk_gcc_prng_ahb_clk>; + clock-names = "iface_clk"; + }; + + qcom,rmtfs_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00180000>; + reg-names = "rmtfs"; + qcom,client-id = <0x00000001>; + }; + + qcom,dsp_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_dsp"; + qcom,client-id = <0x011013ec>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,mdm_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_mdm"; + qcom,client-id = <0x011013ed>; + }; + + qcom,sensors_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_sensor"; + qcom,client-id = <0x011013ee>; + linux,contiguous-region = <&adsp_mem>; + }; + + sdhc_1: sdhci@f9824900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 123 0>, <0 138 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc1"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */ + <78 512 1600 3200>, /* 400 KB/s*/ + <78 512 80000 160000>, /* 20 MB/s */ + <78 512 100000 200000>, /* 25 MB/s */ + <78 512 200000 400000>, /* 50 MB/s */ + <78 512 400000 800000>, /* 100 MB/s */ + <78 512 400000 800000>, /* 200 MB/s */ + <78 512 400000 800000>, /* 400 MB/s */ + <78 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 400000000 4294967295>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>, + <&clock_gcc clk_gcc_sdcc1_apps_clk>; + + status = "disabled"; + }; + + sdhc_2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 125 0>, <0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>, + <&clock_gcc clk_gcc_sdcc2_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc2"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */ + <81 512 1600 3200>, /* 400 KB/s*/ + <81 512 80000 160000>, /* 20 MB/s */ + <81 512 100000 200000>, /* 25 MB/s */ + <81 512 200000 400000>, /* 50 MB/s */ + <81 512 400000 800000>, /* 100 MB/s */ + <81 512 800000 800000>, /* 200 MB/s */ + <81 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + + status = "disabled"; + }; + + sdhc_3: sdhci@f9864900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9864900 0x11c>, <0xf9864000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 127 0>, <0 224 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc3_ahb_clk>, + <&clock_gcc clk_gcc_sdcc3_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc3"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */ + <79 512 1600 3200>, /* 400 KB/s*/ + <79 512 80000 160000>, /* 20 MB/s */ + <79 512 100000 200000>, /* 25 MB/s */ + <79 512 200000 400000>, /* 50 MB/s */ + <79 512 400000 800000>, /* 100 MB/s */ + <79 512 800000 800000>, /* 200 MB/s */ + <79 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + qcom,dat1-mpm-int = <47>; + status = "disabled"; + }; + + ufs_ice: ufsice@fc5a0000 { + compatible = "qcom,ice"; + reg = <0xfc5a0000 0x8000>; + interrupt-names = "ufs_ice_nonsec_level_irq", "ufs_ice_sec_level_irq"; + interrupts = <0 258 0>, <0 257 0>; + status = "disabled"; + }; + + ufsphy1: ufsphy@fc597000 { + compatible = "qcom,ufs-phy-qmp-20nm"; + reg = <0xfc597000 0xda8>; + reg-names = "phy_mem"; + #phy-cells = <0>; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-max-microamp = <45000>; + vdda-pll-max-microamp = <100>; + vddp-ref-clk-supply = <&pm8994_l31>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + clock-names = "ref_clk_src", + "ref_clk", + "tx_iface_clk", + "rx_iface_clk"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_ufs_phy_ldo>, + <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, + <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; + status = "disabled"; + }; + + ufs1: ufshc@fc594000 { + compatible = "qcom,ufshc"; + reg = <0xfc594000 0x2500>, <0xfd512074 0x4>; + interrupts = <0 265 0>; + phys = <&ufsphy1>; + phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8994_l20>; + vccq-supply = <&pm8994_l31>; + vccq2-supply = <&pm8994_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <50000>; + vccq2-max-microamp = <750000>; + + clock-names = "core_clk_src", "core_clk", "bus_clk", "iface_clk", + "ref_clk", "rx_lane0_sync_clk", "tx_lane0_sync_clk", + "rx_lane1_sync_clk", "tx_lane1_sync_clk"; + clocks = + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>, + <&clock_rpm clk_bb_clk1>, + <&clock_gcc clk_gcc_ufs_rx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_rx_symbol_1_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_1_clk>; + qcom,msm-bus,name = "ufs1"; + qcom,msm-bus,num-cases = <22>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <95 512 0 0>, <1 650 0 0>, /* No vote */ + <95 512 922 0>, <1 650 1000 0>, /* PWM G1 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G3 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G4 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G1 L2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G2 L2 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G3 L2 */ + <95 512 14752 0>, <1 650 1000 0>, /* PWM G4 L2 */ + <95 512 127796 0>, <1 650 1000 0>, /* HS G1 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G2 RA */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G3 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G1 RA L2 */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G2 RA L2 */ + <95 512 1022362 0>, <1 650 1000 0>, /* HS G3 RA L2 */ + <95 512 149422 0>, <1 650 1000 0>, /* HS G1 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G2 RB */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G3 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G1 RB L2 */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G2 RB L2 */ + <95 512 1192756 0>, <1 650 1000 0>, /* HS G3 RB L2 */ + <95 512 4096000 0>, <1 650 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "PWM_G1_L2", "PWM_G2_L2", "PWM_G3_L2", "PWM_G4_L2", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", + "HS_RA_G1_L2", "HS_RA_G2_L2", "HS_RA_G3_L2", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", + "HS_RB_G1_L2", "HS_RB_G2_L2", "HS_RB_G3_L2", + "MAX"; + + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0xf>; /* little cluster */ + qcom,cpu-dma-latency-us = <301>; + + spm-level = <5>; + status = "disabled"; + }; + + spi_0: spi_epm: spi@f9923000 { /* BLSP1 QUP1 */ + compatible = "qcom,spi-qup-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical", "spi_bam_physical"; + reg = <0xf9923000 0x1000>, + <0xf9904000 0x19000>; + interrupt-names = "spi_irq", "spi_bam_irq"; + interrupts = <0 95 0>, <0 238 0>; + spi-max-frequency = <19200000>; + + qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <12>; + qcom,bam-producer-pipe-index = <13>; + qcom,master-id = <86>; + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_0_active &spi_0_cs1_active>; + pinctrl-1 = <&spi_0_sleep &spi_0_cs1_sleep>; + + clock-names = "iface_clk", "core_clk"; + + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + }; +//#ifdef VENDOR_EDIT +/* add for fpc1021 fingerprints */ + spi_12: spi@f9968000 { + compatible = "qcom,spi-qup-v2"; + //cell-index = <12>; //changhua + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical"/*, "spi_bam_physical"*/; + + /*Add BAM physical address + BLSP1: 0xf9904000 + BLSP2: 0xf9944000 + */ + + reg = <0xf9968000 0x1000>/*, + <0xf9944000 0x19000>*/; + + interrupt-names = "spi12_irq"/*, "spi_bam_irq"*/; + + /* Add BAM IRQ + BLSP1: 238 + BLSP2: 239 ??271??? 239 is offset + */ + interrupts = <0 106 0>/*, <0 239 0>*/; + + spi-max-frequency = <9600000>; + + /* //changhua + qcom,gpio-mosi = <&msm_gpio 85 0>; + qcom,gpio-miso = <&msm_gpio 86 0>; + qcom,gpio-clk = <&msm_gpio 88 0>; + qcom,gpio-cs0 = <&msm_gpio 87 0>; + */ + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup6_spi_apps_clk>; + + qcom,master-id = <86>; + /*qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <22>; + qcom,bam-producer-pipe-index = <23>; + */ + /*lichanghua add for use pinctrl*/ + /* Assign runtime functions to pins */ + + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_12_active &spi_12_cs0_active>; + pinctrl-1 = <&spi_12_sleep &spi_12_cs0_sleep>; + + qcom,shared; + + /*lichanghua add for use pinctrl end*/ + }; +//#endif/*VENDOR_EDIT*/ + + qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + }; + + qcom,msm-pacman { + compatible = "qcom,msm-pacman"; + }; + + wcd9xxx_intc: wcd9xxx-irq { + compatible = "qcom,wcd9xxx-irq"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&msm_gpio>; + interrupts = <72 0>; + interrupt-names = "cdc-int"; + }; + + tspp: msm_tspp@f99d8000 { + compatible = "qcom,msm_tspp"; + reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */ + <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */ + <0xf99da000 0x1000>, /* MSM_TSPP_PHYS */ + <0xf99c4000 0x11000>; /* MSM_TSPP_BAM_PHYS */ + reg-names = "MSM_TSIF0_PHYS", + "MSM_TSIF1_PHYS", + "MSM_TSPP_PHYS", + "MSM_TSPP_BAM_PHYS"; + interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */ + <0 119 0>, /* TSIF0_IRQ */ + <0 120 0>, /* TSIF1_IRQ */ + <0 122 0>; /* TSIF_BAM_IRQ */ + interrupt-names = "TSIF_TSPP_IRQ", + "TSIF0_IRQ", + "TSIF1_IRQ", + "TSIF_BAM_IRQ"; + + clock-names = "iface_clk", "ref_clk"; + clocks = <&clock_gcc clk_gcc_tsif_ahb_clk>, + <&clock_gcc clk_gcc_tsif_ref_clk>; + + qcom,msm-bus,name = "tsif"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <82 512 0 0>, /* No vote */ + <82 512 12288 24576>; /* Max. bandwidth, 2xTSIF, each max of 96Mbps */ + + pinctrl-names = "disabled", + "tsif0-mode1", "tsif0-mode2", + "tsif1-mode1", "tsif1-mode2", + "dual-tsif-mode1", "dual-tsif-mode2"; + + pinctrl-0 = <>; /* disabled */ + pinctrl-1 = <&tsif0_signals_active>; /* tsif0-mode1 */ + pinctrl-2 = <&tsif0_signals_active + &tsif0_sync_active>; /* tsif0-mode2 */ + pinctrl-3 = <&tsif1_signals_active>; /* tsif1-mode1 */ + pinctrl-4 = <&tsif1_signals_active + &tsif1_sync_active>; /* tsif1-mode2 */ + pinctrl-5 = <&tsif0_signals_active + &tsif1_signals_active>; /* dual-tsif-mode1 */ + pinctrl-6 = <&tsif0_signals_active + &tsif0_sync_active + &tsif1_signals_active + &tsif1_sync_active>; /* dual-tsif-mode2 */ + }; + + slim_msm: slim@fe12f000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0xfe12f000 0x2C000>, + <0xfe104000 0x20000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 163 0>, <0 164 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x60000000>; + qcom,ea-pc = <0x110>; + + tomtom_codec { + compatible = "qcom,tomtom-slim-pgd"; + elemental-addr = [00 01 30 01 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30 31>; + + qcom,cdc-reset-gpio = <&msm_gpio 68 0>; + + cdc-vdd-buck-supply = <&pm8994_s5>; + qcom,cdc-vdd-buck-voltage = <2150000 2150000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-vdd-tx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pm8994_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + cdc-vdd-a-1p2v-supply = <&pm8994_l11>; + qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>; + qcom,cdc-vdd-a-1p2v-current = <2000>; + + cdc-vddcx-1-supply = <&pm8994_l11>; + qcom,cdc-vddcx-1-voltage = <1200000 1200000>; + qcom,cdc-vddcx-1-current = <33000>; + + cdc-vddcx-2-supply = <&pm8994_l11>; + qcom,cdc-vddcx-2-voltage = <1200000 1200000>; + qcom,cdc-vddcx-2-current = <33000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1", + "cdc-vdd-a-1p2v", + "cdc-vddcx-1", + "cdc-vddcx-2"; + + qcom,cdc-micbias-ldoh-v = <0x3>; + qcom,cdc-micbias-cfilt1-mv = <1800>; + //#ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv , 2015/3/24, modify micbias voltage*/ + /*kangjirui@MultiMedia.AudioDrv , 2015/4/18, modify micbias voltage for headset button error*/ + qcom,cdc-micbias-cfilt2-mv = <2700>; + //#endif /* VENDOR_EDIT */ + qcom,cdc-micbias-cfilt3-mv = <1800>; + qcom,cdc-micbias1-cfilt-sel = <0x0>; + qcom,cdc-micbias2-cfilt-sel = <0x1>; + qcom,cdc-micbias3-cfilt-sel = <0x2>; + qcom,cdc-micbias4-cfilt-sel = <0x2>; + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tomtom-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 30 01 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + qcom,cdc-variant = "WCD9330"; + }; + }; + + spmi_bus: qcom,spmi@fc4c0000 { + compatible = "qcom,spmi-pmic-arb"; + reg-names = "core", "intr", "cnfg"; + reg = <0xfc4cf000 0x1000>, + <0xfc4cb000 0x1000>, + <0xfc4ca000 0x1000>; + /* 190,ee0_krait_hlos_spmi_periph_irq */ + /* 187,channel_0_krait_hlos_trans_done_irq */ + interrupts = <0 190 0>, <0 187 0>; + qcom,pmic-arb-channel = <0>; + qcom,pmic-arb-ee = <0>; + #interrupt-cells = <3>; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + }; + + usb3: ssusb@f9200000 { + compatible = "qcom,dwc-usb3-msm"; + status = "disabled"; + reg = <0xf9200000 0xfc000>, + <0xfd4ab000 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupt-parent = <&usb3>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x0 0xffffffff>; + interrupt-map = <0x0 0 &intc 0 133 0 + 0x0 1 &intc 0 180 0 + 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>; + interrupt-names = "hs_phy_irq", "pwr_event_irq", "pmic_id_irq"; + + USB3_GDSC-supply = <&gdsc_usb30>; + vdda33-supply = <&pm8994_l24>; + vbus_dwc3-supply = <&smbcharger_charger_otg>; + qcom,dwc-usb3-msm-tx-fifo-size = <29696>; + qcom,dwc-usb3-msm-qdss-tx-fifo-size = <8192>; + qcom,usb-dbm = <&dbm_1p5>; + + qcom,msm-bus,name = "usb3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <61 512 0 0>, + <61 512 240000 960000>; + + qcom,power-collapse-on-cable-disconnect; + qcom,por-after-power-collapse; + + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>, + <&clock_gcc clk_gcc_usb30_mock_utmi_clk>, + <&clock_gcc clk_gcc_usb30_sleep_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_rpm clk_cxo_dwc3_clk>; + clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk", + "ref_clk", "xo"; + + dwc3@f9200000 { + compatible = "synopsys,dwc3"; + reg = <0xf9200000 0xfc000>; + interrupt-parent = <&intc>; + interrupts = <0 131 0>; + tx-fifo-resize; + snps,usb3-u1u2-disable; + usb-phy = <&hsphy0>, <&ssphy0>; + }; + }; + + hsphy0: hsphy@f92f8800 { + compatible = "qcom,usb-hsphy"; + status = "disabled"; + reg = <0xf92f8800 0x3ff>, + <0xf9b3a000 0x110>; + reg-names = "core", "phy_csr"; + // #ifdef VENDOR_EDIT + /*modify by jiachenghui from 0x00D191A4 to 0x00D191A7 for OTG 2015-04-22*/ + /*change HS DC voltage-level to 0x0011 by jiachenghui for OTG detect issue 2015-05-23*/ + qcom,hsphy-init = <0x00D187A7>; + //#endif /*VENDOR_EDIT*/ + vdd-supply = <&pm8994_s2_corner>; + vddcx-supply = <&pm8994_s1_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,ext-vbus-id; + qcom,vbus-valid-override; + qcom,set-pllbtune; + qcom,sleep-clk-reset; + qcom,vdda-force-on; + clocks = <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>; + clock-names = "phy_sleep_clk"; + }; + + ssphy0: ssphy@f9b38000 { + compatible = "qcom,usb-ssphy-qmp"; + status = "disabled"; + reg = <0xf9b38000 0x800>, + <0xf9b3e000 0x3ff>; + reg-names = "qmp_phy_base", + "qmp_ahb2phy_base"; + vdd-supply = <&pm8994_l28>; + vdda18-supply = <&pm8994_l6>; + qcom,vdd-voltage-level = <0 1000000 1000000>; + qcom,vbus-valid-override; + qcom,no-pipe-clk-switch; + + clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>, + <&clock_gcc clk_gcc_usb3_phy_pipe_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_usb3_phy_reset>, + <&clock_gcc clk_gcc_usb3phy_phy_reset>, + <&clock_gcc clk_usb_ss_phy_ldo>; + clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset", + "phy_phy_reset", "ldo_clk"; + }; + + dbm_1p5: dbm@f92f8000 { + compatible = "qcom,usb-dbm-1p5"; + reg = <0xf92f8000 0x1000>; + qcom,reset-ep-after-lpm-resume; + }; + + qcom,usbbam@f9304000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xf9304000 0x9000>, + <0xf92f880c 0x4>; + reg-names = "ssusb", "qscratch_ram1_reg"; + interrupts = <0 132 0>; + interrupt-names = "ssusb"; + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>; + clock-names = "mem_clk", "mem_iface_clk"; + + qcom,usb-bam-fifo-baseaddr = <0xf9200000>; + qcom,usb-bam-num-pipes = <16>; + qcom,ignore-core-reset-ack; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + + qcom,pipe0 { + label = "ssusb-ipa-out-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <0>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,src-bam-physical-address = <0xf9304000>; + qcom,src-bam-pipe-index = <1>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe1 { + label = "ssusb-ipa-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe2 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <1>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,src-bam-physical-address = <0xfc37C000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-offset = <0xf0000>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0xf4000>; + qcom,descriptor-fifo-size = <0x1400>; + qcom,reset-bam-on-connect; + }; + + /* USB BAM pipe (consumer) configuration for accelerated DPL */ + qcom,pipe3 { + label = "ssusb-dpl-ipa-in-1"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <1>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + }; + + usb_otg: usb@f9a55000 { + compatible = "qcom,hsusb-otg"; + status = "disabled"; + + reg = <0xf9a55000 0x400>; + reg-names = "core"; + interrupts = <0 134 0 0 140 0>; + interrupt-names = "core_irq", "async_irq"; + + HSUSB_VDDCX-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "sleep_clk", "xo"; + + qcom,hsusb-otg-phy-type = <2>; + qcom,hsusb-otg-phy-init-seq = <0x63 0x81 0xffffffff>; + qcom,hsusb-otg-mode = <1>; + qcom,hsusb-otg-otg-control = <1>; + }; + + usb_ehci: ehci@f9a55000 { + compatible = "qcom,ehci-host"; + status = "disabled"; + reg = <0xf9a55000 0x400>; + interrupts = <0 134 0>, <0 140 0>; + interrupt-names = "core_irq", "async_irq"; + hsusb_vdd_dig-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 2 3 5 7>; + qcom,usb2-power-budget = <500>; + usb-phy = <&qusb_phy>; + qcom,pm-qos-latency = <30001>; + + qcom,msm-bus,name = "usb-hs"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <87 512 0 0>, + <87 512 40000 60000>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "xo"; + }; + + qusb_phy: qusb@f9b39000 { + compatible = "qcom,qusb2phy"; + status = "disabled"; + reg = <0xf9b39000 0x17f>; + reg-names = "qusb_phy_base"; + vdd-supply = <&pm8994_s2_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,qusb-tune = <0xa08391d5>; + phy_type = "ulpi"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_qusb2_phy_reset>; + clock-names = "ref_clk", "cfg_ahb_clk", "phy_reset"; + }; + + android_usb@fe87f0c8 { + compatible = "qcom,android-usb"; + reg = <0xfe87f0c8 0xc8>; + qcom,pm-qos-latency = <61 637 1261>; + /*add by jiachenghui for cdrom,20150528*/ + /*#ifdef VENDOR_EDIT*/ + qcom,android-usb-cdrom; + /*#ifdef VENDOR_EDIT*/ + /*end add by jiachenghui for cdrom,20150528*/ + }; + + qcom,venus@fdce0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfdce0000 0x4000>; + + vdd-supply = <&gdsc_venus>; + qcom,proxy-reg-names = "vdd"; + clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_rpm clk_scm_ce1_clk>; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + linux,contiguous-region = <&peripheral_mem>; + }; + + qcom,mss@fc880000 { + compatible = "qcom,pil-q6v55-mss"; + reg = <0xfc880000 0x100>, + <0xfd485000 0x400>, + <0xfc820000 0x020>, + <0xfc401680 0x004>; + reg-names = "qdsp6_base", "halt_base", "rmb_base", + "restart_reg"; + + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_mss_cfg_ahb_clk>, + <&clock_rpm clk_pnoc_modem_clk>, + <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>, + <&clock_gcc clk_gcc_boot_rom_ahb_clk>, + <&clock_gcc clk_gpll0_out_msscc>; + clock-names = "xo", "iface_clk", "pnoc_clk", "bus_clk", + "mem_clk", "gpll0_mss_clk"; + qcom,proxy-clock-names = "xo", "pnoc_clk"; + qcom,active-clock-names = "iface_clk", "bus_clk", "mem_clk", + "gpll0_mss_clk"; + + interrupts = <0 24 1>; + vdd_mss-supply = <&pm8994_s7>; + vdd_cx-supply = <&pm8994_s1_corner>; + vdd_mx-supply = <&pm8994_s2_corner>; + vdd_mx-uV = <7>; + vdd_pll-supply = <&pm8994_l12>; + qcom,vdd_pll = <1800000>; + qcom,firmware-name = "modem"; + qcom,pil-self-auth; + qcom,mba-image-is-not-elf; + qcom,sysmon-id = <0>; + qcom,ssctl-instance-id = <0x12>; + qcom,override-acc; + qcom,ahb-clk-vote; + qcom,pnoc-clk-vote; + + /* GPIO inputs from mss */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>; + + /* GPIO output to mss */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>; + + linux,contiguous-region = <&modem_mem>; + }; + + qcom,lpass@fe200000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfe200000 0x00100>; + interrupts = <0 162 1>; + + vdd_cx-supply = <&pm8994_s1_corner>; + qcom,proxy-reg-names = "vdd_cx"; + qcom,vdd_cx-uV-uA = <7 100000>; + + clocks = <&clock_rpm clk_cxo_pil_lpass_clk>, + <&clock_rpm clk_scm_ce1_clk>; + clock-names = "xo", "scm_ce1_clk"; + qcom,proxy-clock-names = "xo", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + qcom,pas-id = <1>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <423>; + qcom,sysmon-id = <1>; + qcom,ssctl-instance-id = <0x14>; + qcom,firmware-name = "adsp"; + + /* GPIO inputs from lpass */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_2_in 2 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_2_in 1 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_2_in 3 0>; + + /* GPIO output to lpass */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>; + + linux,contiguous-region = <&peripheral_mem>; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops { + compatible = "ramoops"; + /*reg = <0x05800000 0x00100000>;*/ + linux,contiguous-region = <&ramoops_mem>; + }; +/* #endif VENDOR_EDIT */ + + + clock_rpm: qcom,rpmcc@fc401880 { + compatible = "qcom,rpmcc-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + #clock-cells = <1>; + }; + + clock_gcc: qcom,gcc@fc400000 { + compatible = "qcom,gcc-8994"; + reg = <0xfc400000 0x2000>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + clock-names = "xo", "xo_a_clk"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_cxo_clk_src_ao>; + #clock-cells = <1>; + }; + + clock_mmss: qcom,mmsscc@fd8c0000 { + compatible = "qcom,mmsscc-8994"; + reg = <0xfd8c0000 0x5200>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + mmpll4_dig-supply = <&pm8994_s1_corner>; + mmpll4_analog-supply = <&pm8994_l12>; + clock-names = "xo", "gpll0", "mmssnoc_ahb", + "oxili_gfx3d_clk", "pclk0_src", "pclk1_src", + "byte0_src", "byte1_src", "extpclk_src"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_gcc clk_gpll0_out_mmsscc>, + <&clock_rpm clk_mmssnoc_ahb_clk>, + <&clock_rpm clk_oxili_gfx3d_clk_src>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_hdmi_pll clk_hdmi_20nm_vco_clk>; + #clock-cells = <1>; + }; + + clock_debug: qcom,cc-debug@fc401880 { + compatible = "qcom,cc-debug-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + clock-names = "debug_mmss_clk", "debug_rpm_clk", + "debug_cpu_clk"; + clocks = <&clock_mmss clk_mmss_debug_mux>, + <&clock_rpm clk_rpm_debug_mux>, + <&clock_cpu clk_cpu_debug_mux>; + #clock-cells = <1>; + }; + + cci_cache: qcom,cci { + compatible = "devfreq-simple-dev"; + clock-names = "devfreq_clk"; + clocks = <&clock_cpu clk_cci_clk>; + governor = "cpufreq"; + freq-tbl-khz = + < 150000 >, + < 200000 >, + < 249600 >, + < 300000 >, + < 384000 >, + < 499200 >, + < 600000 >; + }; + + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "cpufreq"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc388000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + cpubw-cpufreq { + target-dev = <&cpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 1525 >, + < 691200 2288 >, + < 768000 3562 >, + < 844800 4066 >, + < 921600 5126 >, + < 940800 6072 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 2288 >, + < 691200 3562 >, + < 768000 4066 >, + < 844800 5126 >, + < 921600 6072 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >, + < 940800 5928 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >; + }; + + cci-cpufreq { + target-dev = <&cci_cache>; + cpu-to-dev-map-0 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 384000 >, + < 844800 499200 >, + < 921600 600000 >, + < 940800 600000 >; + cpu-to-dev-map-4 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 499200 >, + < 844800 600000 >, + < 921600 600000 >; + }; + }; + + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "l2_clk", "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk"; + clocks = <&clock_cpu clk_cci_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>; + + qcom,governor-per-policy; + + qcom,cpufreq-table-0 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >, + < 940800 >; + + qcom,cpufreq-table-4 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >; + }; + + clock_cpu: qcom,cpu-clock-8994@f9015000 { + compatible = "qcom,cpu-clock-8994"; + reg = <0xf9015000 0x1000>, + <0xf9016000 0x1000>, + <0xf9011000 0x1000>, + <0xf900d000 0x1000>, + <0xf900f000 0x1000>, + <0xf9112000 0x1000>, + <0xfc4b80b0 0x8>; + reg-names = "c0_pll", "c1_pll", "cci_pll", "c0_mux", "c1_mux", "cci_mux", "efuse"; + vdd-a53-supply = <&apc0_vreg_corner>; + vdd-a57-supply = <&apc1_vreg_corner>; + vdd-cci-supply = <&apc0_vreg_corner>; + vdd-dig-supply = <&pm8994_s1_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>, + < 940800000 9>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 150000000 1>, + < 200000000 2>, + < 249600000 3>, + < 300000000 4>, + < 384000000 4>, + < 499200000 7>, + < 600000000 9>; + clock-names = "xo_ao", "aux_clk"; + clocks = <&clock_rpm clk_cxo_clk_src_ao>, + <&clock_gcc clk_gpll0_ao>; + #clock-cells = <1>; + }; + + ocmem: qcom,ocmem@fdd00000 { + compatible = "qcom,msm-ocmem"; + reg = <0xfdd00000 0x2000>, + <0xfdd02000 0x2000>, + <0xfe039000 0x400>, + <0xfec00000 0x200000>; + reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical"; + interrupts = <0 76 0 0 77 0>; + interrupt-names = "ocmem_irq", "dm_irq"; + qcom,ocmem-num-regions = <0x4>; + qcom,ocmem-num-macros = <0x20>; + qcom,resource-type = <0x706d636f>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfec00000 0x200000>; + clocks = <&clock_rpm clk_ocmemgx_core_clk>, + <&clock_mmss clk_ocmemcx_ocmemnoc_clk>; + clock-names = "core_clk", "iface_clk"; + + partition@0 { + reg = <0x0 0x180000>; + qcom,ocmem-part-name = "graphics"; + qcom,ocmem-part-min = <0x80000>; + }; + + partition@100000 { + reg = <0x180000 0x80000>; + qcom,ocmem-part-name = "video"; + qcom,ocmem-part-min = <0x55000>; + }; + + }; + + msm_vidc: qcom,vidc@fdc00000 { + compatible = "qcom,msm-vidc"; + reg = <0xfdc00000 0xff000>; + interrupts = <0 44 0>; + qcom,hfi = "venus"; + qcom,reg-presets = <0x800D8 0x707>, + <0xe0020 0x55555556>, + <0xe0024 0x55555556>, + <0x80124 0x3>; + qcom,qdss-presets = <0xfc325000 0x1000>, + <0xfc326000 0x1000>, + <0xfc321000 0x1000>, + <0xfc322000 0x1000>, + <0xfc323000 0x1000>, + <0xfc302000 0x1000>, + <0xfa180000 0x1000>, + <0xfa181000 0x1000>; + qcom,ocmem-size = <524288>; /* 512 * 1024*/ + qcom,max-hw-load = <1281600>; /* Full 4k @ 30 + 1080p @ 30 */ + clock-names = "core_clk", "core0_clk", "core1_clk", "core2_clk", + "iface_clk", "bus_clk", "mem_clk"; + venus-supply = <&gdsc_venus>; + venus-core0-supply = <&gdsc_venus_core0>; + venus-core1-supply = <&gdsc_venus_core1>; + venus-core2-supply = <&gdsc_venus_core2>; + qcom,clock-configs = <0x3 0x0 0x0 0x0 0x0 0x0 0x0>; + qcom,sw-power-collapse; + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_core0_vcodec_clk>, + <&clock_mmss clk_venus0_core1_vcodec_clk>, + <&clock_mmss clk_venus0_core2_vcodec_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>; + qcom,load-freq-tbl = + <979200 465000000 0x0c000000>, + <979200 465000000 0x01000414>, + <979200 465000000 0x030fcfff>, + <979200 465000000 0x04000000>, + <783360 465000000 0x0c000000>, + <783360 465000000 0x01000414>, + <783360 465000000 0x030fcfff>, + <783360 465000000 0x04000000>, + <489600 240000000 0x0c000000>, + <489600 240000000 0x01000414>, + <489600 240000000 0x030fcfff>, + <489600 240000000 0x04000000>, + <244800 133330000 0x0c000000>, + <244800 133330000 0x01000414>, + <244800 133330000 0x030fcfff>, + <244800 133330000 0x04000000>; + qcom,vidc-iommu-domains { + qcom,domain-ns { + qcom,vidc-domain-phandle = <&venus_domain_ns>; + qcom,vidc-partition-buffer-types = <0x7ff>, + <0x800>; + }; + qcom,domain-sec-bs { + qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>; + qcom,vidc-partition-buffer-types = <0x241>; + }; + qcom,domain-sec-px { + qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>; + qcom,vidc-partition-buffer-types = <0x106>; + }; + qcom,domain-sec-np { + qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>; + qcom,vidc-partition-buffer-types = <0x480>; + }; + }; + qcom,msm-bus-clients { + qcom,msm-bus-client@0 { + qcom,msm-bus,name = "venc-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 2108700 0>, + <63 512 2243700 0>, + <63 512 2615000 0>; + qcom,bus-configs = <0x1000414>; + }; + + qcom,msm-bus-client@1 { + qcom,msm-bus,name = "vdec-core0-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 151600 0>, + <63 512 393600 0>, + <63 512 393600 0>, + <63 512 749100 0>, + <63 512 749100 0>, + <63 512 1460700 0>, + <63 512 2390500 0>, + <63 512 2542300 0>, + <63 512 2959800 0>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@2 { + qcom,msm-bus,name = "vdec-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 113900 0>, + <63 512 296700 0>, + <63 512 296700 0>, + <63 512 571400 0>, + <63 512 571400 0>, + <63 512 1088500 0>, + <63 512 1811000 0>, + <63 512 1962000 0>, + <63 512 2242900 0>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@3 { + qcom,msm-bus,name = "venc-core2-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 89000 0>, + <63 512 270000 0>, + <63 512 270000 0>, + <63 512 759000 0>, + <63 512 759000 0>, + <63 512 1050000 0>, + <63 512 3077000 0>, + <63 512 3811000 0>, + <63 512 3812000 0>; + qcom,bus-configs = <0x04000000>; + }; + qcom,msm-bus-client@4 { + qcom,msm-bus,name = "venc-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 69000 2384000>, + <68 604 207000 2384000>, + <68 604 207000 2384000>, + <68 604 470000 2384000>, + <68 604 470000 2384000>, + <68 604 940000 3632000>, + <68 604 1787000 3632000>, + <68 604 1906000 3632000>, + <68 604 2234000 3632000>; + qcom,bus-configs = <0x10000414>; + }; + qcom,msm-bus-client@5 { + qcom,msm-bus,name = "venc-core2-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 71000 2384000>, + <68 604 214000 2384000>, + <68 604 214000 2384000>, + <68 604 564000 2384000>, + <68 604 564000 2384000>, + <68 604 1003000 3632000>, + <68 604 2040000 3632000>, + <68 604 2349000 3632000>, + <68 604 2551000 3632000>; + qcom,bus-configs = <0x04000000>; + }; + + qcom,msm-bus-client@6 { + qcom,msm-bus,name = "vdec-core0-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 79000 2384000>, + <68 604 201000 2384000>, + <68 604 201000 2384000>, + <68 604 367000 2384000>, + <68 604 367000 2384000>, + <68 604 735000 3632000>, + <68 604 1175000 3632000>, + <68 604 1254000 3632000>, + <68 604 1469000 3632000>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@7 { + qcom,msm-bus,name = "vdec-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 88000 2384000>, + <68 604 228000 2384000>, + <68 604 228000 2384000>, + <68 604 432000 2384000>, + <68 604 432000 2384000>, + <68 604 865000 3632000>, + <68 604 1374000 3632000>, + <68 604 1465000 3632000>, + <68 604 1717000 3632000>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@8 { + qcom,msm-bus,name = "venc-ddr-lp"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 1218000 0>, + <63 512 1218000 0>, + <63 512 1218000 0>; + qcom,bus-low-power; + qcom,bus-configs = <0x0000004>; + }; + + qcom,msm-bus-client@9 { + qcom,msm-bus,name = "venus-arm9-ddr"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 1000 1000>; + qcom,bus-configs = <0x00000000>; + qcom,bus-passive; + }; + }; + }; + + i2c_1: i2c@f9923000 { + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9923000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 95 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_1_active>; + pinctrl-1 = <&i2c_1_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + qcom,master-id = <86>; + dmas = <&dma_blsp1 10 64 0x20000020 0x20>, + <&dma_blsp1 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + dma_blsp1: qcom,sps-dma@f9904000 { /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9904000 0x19000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <10>; + }; + + dma_blsp2: qcom,sps-dma@f9944000 { /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9944000 0x19000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <10>; + }; + + + i2c_2: i2c@f9924000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9924000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 96 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_2_active>; + pinctrl-1 = <&i2c_2_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + + /* #ifdef VENDOR_EDIT */ + //add by yangrujin@bsp for dma has some issue causing i2c fail + //qcom,disable-dma; + /* #endif //VENDOR_EDIT */ + + + dmas = <&dma_blsp1 14 64 0x20000020 0x20>, + <&dma_blsp1 15 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + i2c_5: i2c_11: i2c@f9967000 { /* BLSP2 QUP5 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9967000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 105 0>; + qcom,clk-freq-out = <100000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup5_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_5_active>; + pinctrl-1 = <&i2c_5_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/4/13, dma mode will cause I2C fail*/ + qcom,disable-dma; + //#endif + dmas = <&dma_blsp2 20 64 0x20000020 0x20>, + <&dma_blsp2 21 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + }; + + i2c_6: i2c@f9928000 { /* BLSP1 QUP6 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + reg-names = "qup_phys_addr"; + reg = <0xf9928000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 100 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + dmas = <&dma_blsp1 22 64 0x20000020 0x20>, + <&dma_blsp1 23 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + sound { + compatible = "qcom,msm8994-asoc-snd"; + qcom,model = "msm8994-tomtom-snd-card"; + reg = <0xfe034000 0x4>, + <0xfe035000 0x4>, + <0xfe036000 0x4>, + <0xfe037000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK"; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/3/19, delete unsed mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#endif + + clock-names = "osr_clk"; + clocks = <&clock_rpm clk_div_clk1>; + qcom,cdc-mclk-gpios = <&pm8994_gpios 15 0>; + qcom,tomtom-mclk-clk-freq = <9600000>; + pinctrl-names = "sleep", + "auxpcm-active", + "mi2s-active", + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv,changed for quat i2s */ + "active", + "quat_mi2s_sleep", + "quat_mi2s_active"; + //#endif +//#ifdef VENDOR_EDIT +//pinctrl-0 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-1 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//pinctrl-2 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-3 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ + pinctrl-0 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-1 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; + pinctrl-2 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-3 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s */ + pinctrl-4 = <&quat_mi2s_sleep>, <&quat_mi2s_mclk_sleep>, <&quat_mi2s_sd0_sleep> , <&quat_mi2s_sd1_sleep>; + pinctrl-5 = <&quat_mi2s_active>, <&quat_mi2s_mclk_active>, <&quat_mi2s_sd0_active> , <&quat_mi2s_sd1_active>; +//#endif + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", "msm-pcm-dsp.2", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp"; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s*/ + asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>, <&dai_mi2s>,<&qua_mi2s>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, <&bt_sco_rx>, + <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>, + <&incall_music2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.0","msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.12288", + "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770"; +//#endif + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + }; + + qcom,msm-adsp-loader { + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + qcom,msm-audio-ion { + compatible = "qcom,msm-audio-ion"; + }; + + pcm0: qcom,msm-pcm { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <0>; + }; + + qcom,msm-pcm-lpa { + compatible = "qcom,msm-pcm-lpa"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm1: qcom,msm-pcm-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <1>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "regular"; + }; + + routing: qcom,msm-pcm-routing { + compatible = "qcom,msm-pcm-routing"; + }; + + compr: qcom,msm-compr-dsp { + compatible = "qcom,msm-compr-dsp"; + }; + + compress: qcom,msm-compress-dsp { + compatible = "qcom,msm-compress-dsp"; + }; + + voip: qcom,msm-voip-dsp { + compatible = "qcom,msm-voip-dsp"; + }; + + voice: qcom,msm-pcm-voice { + compatible = "qcom,msm-pcm-voice"; + qcom,destroy-cvd; + }; + + stub_codec: qcom,msm-stub-codec { + compatible = "qcom,msm-stub-codec"; + }; + + qcom,msm-dai-fe { + compatible = "qcom,msm-dai-fe"; + }; + + afe: qcom,msm-pcm-afe { + compatible = "qcom,msm-pcm-afe"; + }; + + dai_hdmi: qcom,msm-dai-q6-hdmi { + compatible = "qcom,msm-dai-q6-hdmi"; + qcom,msm-dai-q6-dev-id = <8>; + }; + + lsm: qcom,msm-lsm-client { + compatible = "qcom,msm-lsm-client"; + }; + + loopback: qcom,msm-pcm-loopback { + compatible = "qcom,msm-pcm-loopback"; + }; + + qcom,msm-voice-svc { + compatible = "qcom,msm-voice-svc"; + }; + + cpe: qcom,msm-cpe-lsm { + compatible = "qcom,msm-cpe-lsm"; + }; + + qcom,msm-dai-q6 { + compatible = "qcom,msm-dai-q6"; + sb_0_rx: qcom,msm-dai-q6-sb-0-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16384>; + }; + + sb_0_tx: qcom,msm-dai-q6-sb-0-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16385>; + }; + + sb_1_rx: qcom,msm-dai-q6-sb-1-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16386>; + }; + + sb_1_tx: qcom,msm-dai-q6-sb-1-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16387>; + }; + + sb_2_rx: qcom,msm-dai-q6-sb-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16388>; + }; + + sb_2_tx: qcom,msm-dai-q6-sb-2-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16389>; + }; + + sb_3_rx: qcom,msm-dai-q6-sb-3-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16390>; + }; + + sb_3_tx: qcom,msm-dai-q6-sb-3-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16391>; + }; + + sb_4_rx: qcom,msm-dai-q6-sb-4-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16392>; + }; + + sb_4_tx: qcom,msm-dai-q6-sb-4-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16393>; + }; + + sb_5_tx: qcom,msm-dai-q6-sb-5-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16395>; + }; + + bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12288>; + }; + + bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12289>; + }; + + int_fm_rx: qcom,msm-dai-q6-int-fm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12292>; + }; + + int_fm_tx: qcom,msm-dai-q6-int-fm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12293>; + }; + + afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <224>; + }; + + afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <225>; + }; + + afe_proxy_rx: com,msm-dai-q6-afe-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <241>; + }; + + afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <240>; + }; + + incall_record_rx: qcom,msm-dai-q6-incall-record-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32771>; + }; + + incall_record_tx: qcom,msm-dai-q6-incall-record-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32772>; + }; + + incall_music_rx: qcom,msm-dai-q6-incall-music-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32773>; + }; + + incall_music2_rx: qcom,msm-dai-q6-incall-music-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32770>; + }; + }; + + dai_pri_auxpcm: qcom,msm-pri-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "primary"; + }; + + dai_sec_auxpcm: qcom,msm-sec-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "secondary"; + }; + + qcom,msm-dai-mi2s { + compatible = "qcom,msm-dai-mi2s"; + dai_mi2s: qcom,msm-dai-q6-mi2s-prim { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <0>; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv ,changed for quat i2s*/ + + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + qua_mi2s: qcom,msm-dai-q6-mi2s-quat { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <3>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; +//#endif + }; + + hostless: qcom,msm-pcm-hostless { + compatible = "qcom,msm-pcm-hostless"; + }; + + tsens: tsens@fc4a8000 { + compatible = "qcom,msm8994-tsens"; + reg = <0xfc4a8000 0x2000>, + <0xfc4bc000 0x1000>; + reg-names = "tsens_physical", "tsens_eeprom_physical"; + interrupts = <0 184 0>; + interrupt-names = "tsens-upper-lower"; + qcom,sensors = <16>; + qcom,slope = <2901 2846 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200>; + }; + + qcom_tzlog: tz-log@fe87f720 { + compatible = "qcom,tz-log"; + reg = <0xfe87f720 0x2000>; + }; + + qcom_crypto1fde: qcrypto1fde@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2fde: qcrypto2fde@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto1pfe: qcrypto1pfe@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2pfe: qcrypto2pfe@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_cedev: qcedev@fd440000 { + compatible = "qcom,qcedev"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <1>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcedev_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,qseecom@6500000{ + compatible = "qcom,qseecom"; + reg = <0x0E900000 0x1900000>;//reg = <0x6500000 0x500000>; ----> <0x0E700000 0x700000>; ----> <0x0E900000 0x1900000>; /*VENDOR_EDIT changhua add more memory for fpc1150 and alipay in TZ*/ + reg-names = "secapp-region"; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,file-encrypt-pipe-pair = <0>; + qcom,support-multiple-ce-hw-instance; + qcom,hlos-num-ce-hw-instances = <2>; + qcom,hlos-ce-hw-instance = <1 2>; + qcom,qsee-ce-hw-instance = <0>; + qcom,msm-bus,name = "qseecom-noc"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,support-fde; + qcom,support-pfe; + qcom,no-clock-support; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 0 0>, + <55 512 120000 1200000>, + <55 512 393600 3936000>; + clock-names = "core_clk", "ufs_core_clk_src", "ufs_core_clk", + "ufs_bus_clk", "ufs_iface_clk"; + clocks = <&clock_rpm clk_qseecom_ce1_clk>, + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information@0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + }; + + sensor_information1: qcom,sensor-information@1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + }; + + sensor_information2: qcom,sensor-information@2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,alias-name = "pop_mem"; + }; + + sensor_information3: qcom,sensor-information@3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + }; + + sensor_information4: qcom,sensor-information@4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + }; + + sensor_information5: qcom,sensor-information@5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + }; + + sensor_information6: qcom,sensor-information@6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,alias-name = "cpu7"; + }; + + sensor_information7: qcom,sensor-information@7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,alias-name = "cpu0"; + }; + + sensor_information8: qcom,sensor-information@8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,alias-name = "cpu1"; + }; + + sensor_information9: qcom,sensor-information@9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,alias-name = "cpu2"; + }; + + sensor_information10: qcom,sensor-information@10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,alias-name = "cpu3"; + }; + + sensor_information11: qcom,sensor-information@11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + }; + + sensor_information12: qcom,sensor-information@12 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor12"; + qcom,alias-name = "gpu"; + }; + + sensor_information13: qcom,sensor-information@13 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor13"; + qcom,alias-name = "cpu4"; + }; + + sensor_information14: qcom,sensor-information@14 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor14"; + qcom,alias-name = "cpu5"; + }; + + sensor_information15: qcom,sensor-information@15 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor15"; + qcom,alias-name = "cpu6"; + }; + + sensor_information16: qcom,sensor-information@16 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pm8994_tz"; + qcom,scaling-factor = <1000>; + }; + + sensor_information17: qcom,sensor-information@17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + + sensor_information18: qcom,sensor-information@18 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "emmc_therm"; + }; + + sensor_information19: qcom,sensor-information@19 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + + sensor_information20: qcom,sensor-information@20 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + + sensor_information21: qcom,sensor-information@21 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + + sensor_information22: qcom,sensor-information@22 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "LLM_IA57"; + }; + + sensor_information23: qcom,sensor-information-23 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "battery"; + }; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <7>; + qcom,poll-ms = <250>; + qcom,limit-temp = <60>; + qcom,temp-hysteresis = <10>; + qcom,therm-reset-temp = <115>; + qcom,freq-step = <2>; + qcom,freq-control-mask = <0xff>; + qcom,core-limit-temp = <80>; + qcom,core-temp-hysteresis = <10>; + qcom,core-control-mask = <0xfe>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <40>; + qcom,cpu-sensors = "tsens_tz_sensor7", "tsens_tz_sensor8", + "tsens_tz_sensor9", "tsens_tz_sensor10", + "tsens_tz_sensor13", "tsens_tz_sensor14", + "tsens_tz_sensor15", "tsens_tz_sensor6"; + qcom,freq-mitigation-temp = <95>; + qcom,freq-mitigation-temp-hysteresis = <10>; + qcom,freq-mitigation-value = <960000>; + qcom,freq-mitigation-control-mask = <0xF0>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,mx-restriction-temp = <5>; + qcom,mx-restriction-temp-hysteresis = <10>; + qcom,mx-retention-min = <3>; + vdd-mx-supply = <&pm8994_s2_corner>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm8994_s1_floor_corner>; + vdd-gfx-supply = <&pmi8994_s2_floor_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <302400 600000 600000>; + qcom,freq-req; + }; + }; + + qcom,bcl { + compatible = "qcom,bcl"; + qcom,bcl-enable; + qcom,bcl-framework-interface; + qcom,bcl-freq-control-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,bcl-hotplug-list = <&CPU6 &CPU7>; + qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,ibat-monitor { + qcom,low-threshold-uamp = <3400000>; + qcom,high-threshold-uamp = <4200000>; + qcom,mitigation-freq-khz = <768000>; + qcom,vph-high-threshold-uv = <3500000>; + qcom,vph-low-threshold-uv = <3300000>; + qcom,soc-low-threshold = <20>; + qcom,thermal-handle = <&msm_thermal_freq>; + }; + }; + + cnss: qcom,cnss@06300000 { + compatible = "qcom,cnss"; + reg = <0x06300000 0x200000>; + reg-names = "ramdump"; + wlan-en-gpio = <&msm_gpio 113 0>; + vdd-wlan-supply = <&bt_vreg>; + vdd-wlan-io-supply = <&pm8994_s4>; + vdd-wlan-xtal-supply = <&pm8994_l30>; + qcom,notify-modem-status; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default>; + qcom,wlan-rc-num = <1>; + qcom,wlan-uart-access; + + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, /* No vote */ + <100 512 6250 200000>, /* 50 Mbps */ + <100 512 25000 200000>, /* 200 Mbps */ + <100 512 100000 200000>; /* 800 Mbps */ + }; + + audio_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&audio_mem>; + }; + + adsp_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,msm-core@fc4b8000 { + compatible = "qcom,apss-core-ea"; + reg = <0xfc4b8000 0x1000>; + qcom,low-hyst-temp = <10>; + qcom,high-hyst-temp = <5>; + qcom,polling-interval = <50>; + + qcom,core-mapping { + qcom,cpu0-chars { + qcom,sensor = <&sensor_information7>; + qcom,cpu-name = <&CPU0>; + }; + + qcom,cpu1-chars { + qcom,sensor = <&sensor_information8>; + qcom,cpu-name = <&CPU1>; + }; + + qcom,cpu2-chars { + qcom,sensor = <&sensor_information9>; + qcom,cpu-name = <&CPU2>; + }; + + qcom,cpu3-chars { + qcom,sensor = <&sensor_information10>; + qcom,cpu-name = <&CPU3>; + }; + + qcom,cpu4-chars { + qcom,sensor = <&sensor_information13>; + qcom,cpu-name = <&CPU4>; + }; + + qcom,cpu5-chars { + qcom,sensor = <&sensor_information14>; + qcom,cpu-name = <&CPU5>; + }; + + qcom,cpu6-chars { + qcom,sensor = <&sensor_information15>; + qcom,cpu-name = <&CPU6>; + }; + + qcom,cpu7-chars { + qcom,sensor = <&sensor_information6>; + qcom,cpu-name = <&CPU7>; + }; + }; + }; + + qcom,system-health-monitor { + compatible = "qcom,system-health-monitor"; + + qcom,system-health-monitor-modem { + qcom,subsys-name = "msm_mpss"; + qcom,ssrestart-string = "modem"; + }; + }; + + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,itlb_dump100 { + qcom,dump-node = <&L1_itlb_100>; + qcom,dump-id = <0x24>; + }; + qcom,itlb_dump101 { + qcom,dump-node = <&L1_itlb_101>; + qcom,dump-id = <0x25>; + }; + qcom,itlb_dump102 { + qcom,dump-node = <&L1_itlb_102>; + qcom,dump-id = <0x26>; + }; + qcom,itlb_dump103 { + qcom,dump-node = <&L1_itlb_103>; + qcom,dump-id = <0x27>; + }; + qcom,dtlb_dump100 { + qcom,dump-node = <&L1_dtlb_100>; + qcom,dump-id = <0x44>; + }; + qcom,dtlb_dump101 { + qcom,dump-node = <&L1_dtlb_101>; + qcom,dump-id = <0x45>; + }; + qcom,dtlb_dump102 { + qcom,dump-node = <&L1_dtlb_102>; + qcom,dump-id = <0x46>; + }; + qcom,dtlb_dump103 { + qcom,dump-node = <&L1_dtlb_103>; + qcom,dump-id = <0x47>; + }; + qcom,l2_tlb_dump0 { + qcom,dump-node = <&L2_tlb_0>; + qcom,dump-id = <0x120>; + }; + qcom,l2_tlb_dump100 { + qcom,dump-node = <&L2_tlb_1>; + qcom,dump-id = <0x121>; + }; + qcom,l2_dump0 { + qcom,dump-node = <&L2_0>; /* L2 cache dump for A53 cluster */ + qcom,dump-id = <0xC0>; + }; + qcom,l2_dump1 { + qcom,dump-node = <&L2_1>; /* L2 cache dumo for A57 cluster */ + qcom,dump-id = <0xC1>; + }; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + + qcom,avtimer@fe09c000 { + compatible = "qcom,avtimer"; + reg = <0xFE09C00C 0x4>, + <0xFE09C010 0x4>; + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr"; + qcom,clk_div = <27>; + }; + + cci@f9100000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9100000 0x1000>; + ranges = <0x0 0xf9100000 0x10000>; + hw-version = <8>; + + pmu@a000 { + compatible = "arm,cci-400-pmu"; + reg = <0x9000 0x5000>; + interrupts = <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>; + }; + + }; +}; + +&gdsc_usb30 { + reg = <0xfc4003c4 0x4>; + status = "ok"; +}; + +&gdsc_pcie_0 { + status = "ok"; +}; + +&gdsc_pcie_1 { + status = "ok"; +}; + +&gdsc_ufs { + status = "ok"; +}; + +&gdsc_venus { + clock-names = "ocmem_clk", "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + status = "ok"; +}; + +&gdsc_venus_core0 { + qcom,support-hw-trigger; + clock-names = "core0_clk"; + clocks = <&clock_mmss clk_venus0_core0_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core1 { + qcom,support-hw-trigger; + clock-names = "core1_clk"; + clocks = <&clock_mmss clk_venus0_core1_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core2 { + qcom,support-hw-trigger; + clock-names = "core2_clk"; + clocks = <&clock_mmss clk_venus0_core2_vcodec_clk>; + status = "ok"; +}; + +&gdsc_mdss { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_mdp_clk>; + status = "ok"; +}; + +&gdsc_camss_top { + clock-names = "csi0_clk", "csi1_clk", "bus_clk"; + clocks = <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>; + status = "ok"; +}; + +&gdsc_jpeg { + clock-names = "bus_clk", "core0_clk", "core1_clk", "core2_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg2_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_vfe { + clock-names = "bus_clk"; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_cpp { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_fd { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_core_clk>; + status = "ok"; +}; + +&gdsc_oxili_cx { + status = "ok"; +}; + +&gdsc_oxili_gx { + clock-names = "core_clk"; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>; + status = "ok"; + parent-supply = <&pmi8994_s2_corner>; +}; + +#include "msm-pm8994-rpm-regulator.dtsi" +#include "msm-pm8994.dtsi" +#include "msm-pmi8994.dtsi" +#include "msm8994-regulator.dtsi" +#include "msm8994-ion.dtsi" +#include "msm8994-iommu.dtsi" +#include "msm8994-iommu-domains.dtsi" +#include "msm8994-camera.dtsi" +#include "msm8994-gpu.dtsi" +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi0-video.dtsi" +#include "dsi-panel-sim-dualmipi1-video.dtsi" +#include "dsi-panel-sim-cmd.dtsi" +#include "dsi-panel-sim-dualmipi0-cmd.dtsi" +#include "dsi-panel-sim-dualmipi1-cmd.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_11/skeleton64.dtsi b/arch/arm64/boot/dts/14049_HW_11/skeleton64.dtsi new file mode 100755 index 0000000000000..1f8ba28132c4a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_11/skeleton64.dtsi @@ -0,0 +1,15 @@ +/* + * Skeleton device tree in the 64 bits version; the bare minimum + * needed to boot; just include and add a compatible value. The + * bootloader will typically populate the memory node. + */ + +/ { + #address-cells = <2>; + #size-cells = <2>; + cpus { }; + soc { }; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0 0 0>; }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/Makefile b/arch/arm64/boot/dts/14049_HW_12/Makefile new file mode 100755 index 0000000000000..d36cc1d101659 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/Makefile @@ -0,0 +1,22 @@ +ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_MSM8994) += msm8994-v1-mtp_14049_HW_12.dtb \ + msm8994-v2.0-mtp_14049_HW_12.dtb \ + msm8994-v2.1-mtp_14049_HW_12.dtb + +DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) +ifneq ($(DTB_NAMES),) +DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) +else +DTB_LIST := $(dtb-y) +endif + +targets += dtbs +targets += $(addprefix ../, $(DTB_LIST)) +endif + +$(obj)/../%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + +dtbs: $(addprefix $(obj)/../,$(DTB_LIST)) + +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3000mah.dtsi new file mode 100755 index 0000000000000..dc23e181f64d3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3000mah.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3000mah { + qcom,max-voltage-uv = <4320000>; /* yangfangbiao@oneplus.cn, 2015/03/15 Set max voltage 4.32v */ + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3000mah"; + qcom,checksum = <0xF99F>; + qcom,fg-profile-data = [ + EC 83 39 7D + 10 81 04 77 + 23 83 9A 72 + AE 52 20 84 + FC 81 51 93 + FB AD D2 B0 + 5B 12 E5 82 + 09 78 90 75 + A7 70 0C 83 + 1A 80 71 8D + 48 89 08 82 + D4 99 74 BC + A2 C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 45 31 A4 44 + 6E 3B 00 00 + AD 3D 24 36 + A9 46 00 00 + 00 00 00 00 + 00 00 00 00 + E7 6A 05 6A + 8E 75 F9 80 + 5E 76 DA 68 + 45 74 54 81 + 10 75 13 60 + 61 7E 38 A1 + 33 DB 62 1A + 64 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3020mah.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3020mah.dtsi new file mode 100755 index 0000000000000..9a2ce4badf33e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata-itech-3020mah.dtsi @@ -0,0 +1,53 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3020mah { + qcom,max-voltage-uv = <4350000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3020mah"; + qcom,fg-profile-data = [ + E8 83 0C 7D + E9 80 B2 76 + 20 83 40 73 + D7 6C 59 7E + FB 81 58 93 + 0D AE 02 B1 + 5B 12 D7 82 + 86 78 F3 76 + 4A 71 0C 83 + 1B 80 73 8D + 49 89 07 82 + D8 99 79 BC + AA C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 09 2E 79 44 + 52 43 00 00 + DE 3D 2A 37 + D3 46 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 6B B7 69 + DD 6C 83 83 + 42 76 CA 68 + 78 75 EF 80 + D4 74 56 5B + 00 00 00 00 + 0A A5 5A D2 + 54 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata-mtp-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata-mtp-3000mah.dtsi new file mode 100755 index 0000000000000..198fbea2ef0af --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata-mtp-3000mah.dtsi @@ -0,0 +1,118 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,mtp-3000mah { + qcom,fcc-mah = <3000>; + qcom,default-rbatt-mohm = <113>; + qcom,max-voltage-uv = <4200000>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <200000>; + qcom,batt-id-kohm = <300>; + qcom,battery-type = "mtp_3000mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <3030 3033 3037 3035 3031>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4191 4188 4183 4179 4174>, + <4106 4125 4127 4125 4121>, + <4046 4082 4082 4080 4077>, + <3966 4038 4044 4040 4035>, + <3922 3983 3994 3998 3997>, + <3886 3949 3966 3966 3962>, + <3856 3908 3937 3935 3931>, + <3832 3875 3908 3907 3903>, + <3814 3847 3874 3878 3875>, + <3799 3826 3831 3832 3830>, + <3787 3807 3811 3811 3809>, + <3775 3793 3795 3795 3793>, + <3764 3782 3783 3783 3781>, + <3752 3775 3773 3772 3769>, + <3739 3768 3766 3762 3755>, + <3725 3756 3756 3747 3733>, + <3710 3732 3734 3725 3711>, + <3696 3707 3705 3697 3684>, + <3681 3695 3686 3678 3667>, + <3667 3690 3684 3676 3665>, + <3658 3688 3683 3675 3664>, + <3646 3685 3681 3674 3663>, + <3631 3682 3679 3673 3660>, + <3612 3677 3676 3669 3655>, + <3589 3667 3666 3660 3639>, + <3560 3643 3636 3630 3599>, + <3523 3600 3586 3581 3546>, + <3474 3537 3518 3516 3477>, + <3394 3446 3425 3427 3379>, + <3257 3306 3273 3283 3213>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>; + qcom,lut-data = <1025 208 100 85 80>, + <1025 208 100 85 80>, + <1032 225 103 87 81>, + <959 249 107 91 82>, + <954 249 109 92 84>, + <953 255 117 94 84>, + <957 230 123 98 87>, + <968 216 134 102 91>, + <983 212 138 112 95>, + <1002 213 103 89 82>, + <1030 215 100 86 81>, + <1066 219 101 89 83>, + <1115 224 104 92 85>, + <1182 234 106 94 86>, + <1263 246 108 92 84>, + <1357 257 107 87 81>, + <1464 261 102 85 80>, + <1564 256 101 84 80>, + <1637 268 100 84 80>, + <1580 276 102 87 81>, + <1617 285 104 87 82>, + <1670 298 107 91 82>, + <1725 315 108 92 83>, + <1785 338 112 92 83>, + <1850 361 111 91 82>, + <1921 378 108 89 84>, + <2000 394 112 92 87>, + <2119 430 121 99 94>, + <2795 497 144 114 104>, + <8769 1035 672 322 234>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <3030 3033 3037>, + <1898 2943 2960>, + <1184 2855 2948>, + <209 2464 2921>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata-palladium.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata-palladium.dtsi new file mode 100755 index 0000000000000..4c44351892565 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata-palladium.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,palladium-batterydata { + qcom,fcc-mah = <1500>; + qcom,default-rbatt-mohm = <210>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,flat-ocv-threshold-uv = <3800000>; + qcom,max-voltage-uv = <4200000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <75>; + qcom,battery-type = "palladium_1500mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <1467 1470 1473 1473 1470>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4175 4173 4167 4162 4157>, + <4097 4111 4112 4110 4107>, + <4039 4075 4072 4068 4064>, + <3963 4017 4025 4026 4025>, + <3920 3969 3984 3989 3988>, + <3887 3932 3957 3958 3955>, + <3856 3898 3929 3928 3925>, + <3830 3868 3900 3901 3898>, + <3808 3843 3858 3863 3862>, + <3793 3821 3827 3827 3827>, + <3779 3803 3807 3808 3807>, + <3768 3788 3792 3793 3792>, + <3757 3779 3780 3780 3779>, + <3746 3771 3772 3768 3768>, + <3734 3762 3765 3759 3749>, + <3722 3747 3753 3744 3730>, + <3707 3721 3731 3722 3709>, + <3693 3705 3704 3696 3683>, + <3678 3698 3687 3678 3667>, + <3664 3693 3683 3676 3665>, + <3656 3690 3682 3675 3664>, + <3646 3687 3681 3674 3662>, + <3634 3683 3680 3672 3661>, + <3618 3677 3676 3668 3656>, + <3599 3667 3667 3655 3639>, + <3573 3645 3638 3623 3603>, + <3541 3607 3591 3575 3554>, + <3496 3550 3528 3511 3490>, + <3428 3469 3445 3423 3400>, + <3312 3342 3308 3280 3250>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <909 216 100 85 84>, + <859 238 106 88 86>, + <860 237 105 88 86>, + <808 239 107 90 88>, + <801 234 111 94 90>, + <801 230 118 97 92>, + <801 224 123 100 95>, + <807 221 128 106 99>, + <818 221 111 101 97>, + <841 225 101 88 87>, + <870 229 101 88 87>, + <906 235 103 91 90>, + <950 243 106 93 93>, + <998 253 110 93 96>, + <1051 263 113 94 90>, + <1116 272 113 91 88>, + <1200 275 111 91 88>, + <1312 298 108 90 87>, + <1430 329 104 88 87>, + <1484 351 107 91 89>, + <1446 345 110 93 90>, + <1398 344 112 94 90>, + <1466 358 115 96 91>, + <1490 357 117 96 90>, + <1589 365 117 94 89>, + <1828 379 111 91 88>, + <2151 399 111 93 91>, + <2621 436 117 98 95>, + <3404 496 130 106 100>, + <8212 616 150 1906 134>, + <135251 124940 59087 49820 29672>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <1470 1470 1473>, + <601 1406 1430>, + <89 1247 1414>, + <8 764 1338>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata-unkown-3300mah.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata-unkown-3300mah.dtsi new file mode 100755 index 0000000000000..4ee01d90bd24d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata-unkown-3300mah.dtsi @@ -0,0 +1,50 @@ +qcom,oneplus_default_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "Unknown Battery"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_ATL_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_ATL_3300mAh.dtsi new file mode 100755 index 0000000000000..08924c2b14994 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_ATL_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "ATL"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_SDI_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_SDI_3300mAh.dtsi new file mode 100755 index 0000000000000..8756ab9405b54 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/batterydata_oneplus_SDI_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_SDI_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <0>; + qcom,battery-type = "SDI"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jd35695-1080p-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jd35695-1080p-cmd.dtsi new file mode 100755 index 0000000000000..a5fb4014c8354 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jd35695-1080p-cmd.dtsi @@ -0,0 +1,212 @@ +/************************************************************ + * Copyright (c) 2013-2013 OPPO Mobile communication Corp.ltd., + * VENDOR_EDIT + * Description: device tree for jdi cmd panel. + * Version : 1.0 + * Date : 2013-12-12 + * Author : yangxinqin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { +dsi_jd35695_1080_cmd: qcom,mdss_dsi_jd35695_1080p_cmd { + compatible = "qcom,mdss-dsi-panel"; + status = "ok"; + qcom,cont-splash-enabled; + qcom,mdss-dsi-panel-name = "jd35695 1080p cmd mode dsi panel"; + qcom,mdss-dsi-panel-manufacture = "JDI"; + qcom,mdss-dsi-panel-version = "JD35695"; + qcom,mdss-dsi-backlight-version= "PMI8994"; + qcom,mdss-dsi-backlight-manufacture = "Qualcomm"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <100>; + qcom,mdss-dsi-h-back-porch = <82>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <7>; + qcom,mdss-dsi-v-front-porch = <3>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0x0000ff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 39 01 00 00 00 00 05 2a 00 00 04 37 + 39 01 00 00 00 00 05 2b 00 00 07 7f + + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF E0 + 15 01 00 00 00 00 02 B5 86 + 15 01 00 00 00 00 02 B6 77 + 15 01 00 00 00 00 02 B8 AD + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 FF 10 + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + + 05 01 00 00 6E 00 02 11 00 + 05 01 00 00 2D 00 02 29 00 + + ]; + qcom,mdss-dsi-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 00 + 05 01 00 00 64 00 02 28 00 + 05 01 00 00 64 00 02 10 00]; + + qcom,mdss-dsi-color-test-on-command= + [ + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 01 + 15 01 00 00 00 00 02 FF 20 + 15 01 00 00 00 00 02 67 4D]; + + + qcom,mdss-dsi-color-test-off-command = + [ + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 00 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 32 00 02 29 00]; + + qcom,mdss-dsi-cabc-off-command = [15 01 00 00 10 00 02 55 00 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-ui-command = [15 01 00 00 10 00 02 55 01 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-still-image-command = [15 01 00 00 10 00 02 55 02 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-video-command = [15 01 00 00 10 00 02 55 03 + 05 01 00 00 10 00 02 29 00]; + + qcom,mdss-dsi-on-command_shoushi = [ + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 60 00 02 29 00 + + ]; + + qcom,mdss-dsi-color-test-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-color-test-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + + + + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + + + + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + //qcom,mdss-dsi-init-delay-us=<50000>; + /**************************************************************************/ + // qcom,esd-check-enabled; + // qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; + // qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; + // qcom,mdss-dsi-panel-status-check-mode = "reg_read_jd35695"; + // qcom,mdss-dsi-panel-status-read-length = <8>; + // qcom,mdss-dsi-panel-max-error-count = <2>; + // qcom,mdss-dsi-panel-status-value = <0x9c 0x00 0x00 0x02 0x40 0x80 0x00 0x00>; + /******************************************************************************/ + // qcom,mdss-dsi-dma-trigger = "trigger_sw"; + // qcom,mdss-dsi-mdp-trigger = "trigger_sw"; + + + + // qcom,mdss-tear-check-frame-rate=<6000>; + // qcom,mdss-tear-check-sync-cfg-height = <1932>; /* Height + VBP + VFP + VSW */ + // qcom,mdss-tear-check-sync-init-val= <1920>; /* Height */ + //qcom,mdss-tear-check-sync-threshold-start = <4>; + // qcom,mdss-tear-check-sync-threshold-continue = <4>; + // qcom,mdss-tear-check-start-pos= <1920>; /* Height */ + // qcom,mdss-tear-check-rd-ptr-trigger-intr= <1921>; /* Height + 1 */ + + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <127>; + + + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 14>, <0 5>, <1 20>; + + }; +}; + + diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jdi-1080p-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jdi-1080p-video.dtsi new file mode 100755 index 0000000000000..7e4e9ceeeaab8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-jdi-1080p-video.dtsi @@ -0,0 +1,97 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_jdi_1080_vid: qcom,mdss_dsi_jdi_1080p_video { + qcom,mdss-dsi-panel-name = "jdi 1080p video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 23 01 00 00 00 00 02 FF 10 + 15 01 00 00 10 00 02 35 00 + 15 01 00 00 10 00 02 bb 03 + //29 01 00 00 00 00 03 44 05 00 + 23 01 00 00 00 00 02 FF E0 + 23 01 00 00 00 00 02 B5 86 + 23 01 00 00 00 00 02 B6 77 + 23 01 00 00 00 00 02 B8 AD + 23 01 00 00 00 00 02 FB 01 + 23 01 00 00 00 00 02 FF 10 + +/************************************************************** + //15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + self test mode + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 23 01 00 00 00 00 02 FF 24 + 23 01 00 00 00 00 02 EC 01 + 23 01 00 00 00 00 02 FF 20 + 23 01 00 00 00 00 02 67 4D +*************************************************************/ + 15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + 23 01 00 00 00 00 02 FF 23 + 23 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 24 + + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 78 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 79 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-init-delay-us=<50000>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 50>; + qcom,mdss-pan-physical-width-dimension = <61>; + qcom,mdss-pan-physical-height-dimension = <110>; + }; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi new file mode 100755 index 0000000000000..8ae76e72ddb7a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi @@ -0,0 +1,68 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_0: qcom,mdss_dsi_sharp_wqxga_video_0 { + qcom,mdss-dsi-panel-name = "Dual 0 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <50>; + qcom,mdss-dsi-bl-pmic-bank-select = <2>; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi new file mode 100755 index 0000000000000..a9337b1866188 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi @@ -0,0 +1,66 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_1: qcom,mdss_dsi_sharp_wqxga_video_1 { + qcom,mdss-dsi-panel-name = "Dual 1 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-cmd.dtsi new file mode 100755 index 0000000000000..694973e4ff43f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-cmd.dtsi @@ -0,0 +1,94 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_cmd: qcom,mdss_dsi_sim_cmd{ + qcom,mdss-dsi-panel-name = "Simulator cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-cmd.dtsi new file mode 100755 index 0000000000000..74986f9b4e5f3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-cmd.dtsi @@ -0,0 +1,95 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_0: qcom,mdss_dsi_sim_cmd_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-video.dtsi new file mode 100755 index 0000000000000..13cd57f321c82 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi0-video.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_0: qcom,mdss_dsi_sim_video_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-cmd.dtsi new file mode 100755 index 0000000000000..f73e47bd504b5 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-cmd.dtsi @@ -0,0 +1,96 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_1: qcom,mdss_dsi_sim_cmd_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-video.dtsi new file mode 100755 index 0000000000000..882b2abdce34f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-dualmipi1-video.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_1: qcom,mdss_dsi_sim_video_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-video.dtsi b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-video.dtsi new file mode 100755 index 0000000000000..bd9322bac2e74 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/dsi-panel-sim-video.dtsi @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_vid: qcom,mdss_dsi_sim_video { + qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <640>; + qcom,mdss-dsi-panel-height = <480>; + qcom,mdss-dsi-h-front-porch = <6>; + qcom,mdss-dsi-h-back-porch = <6>; + qcom,mdss-dsi-h-pulse-width = <2>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <6>; + qcom,mdss-dsi-v-front-porch = <6>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [32 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-off-command = [22 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [00 00 00 00 00 00 00 00 00 00 00 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x1b>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 0>, <0 0>, <1 0>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-gdsc-8916.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-gdsc-8916.dtsi new file mode 100755 index 0000000000000..07e1e33fd4482 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-gdsc-8916.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@184c018 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0x184c018 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@184d078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0x184d078 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@185701c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0x185701c 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@1858034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0x1858034 0x4>; + status = "disabled"; + }; + + gdsc_vfe1: qcom,gdsc@185806c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe1"; + reg = <0x185806c 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@1858078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0x1858078 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@185901c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0x185901c 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@184c028 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0x184c028 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@184c030 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0x184c030 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-gdsc.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-gdsc.dtsi new file mode 100755 index 0000000000000..9a1f32eb0c7aa --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-gdsc.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@fd8c1024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0xfd8c1024 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@fd8c1040 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0xfd8c1040 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@fd8c1044 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0xfd8c1044 0x4>; + status = "disabled"; + }; + + gdsc_venus_core2: qcom,gdsc@fd8c1050 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core2"; + reg = <0xfd8c1050 0x4>; + status = "disabled"; + }; + + gdsc_vpu: qcom,gdsc@fd8c1404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vpu"; + reg = <0xfd8c1404 0x4>; + status = "disabled"; + }; + + gdsc_camss_top: qcom,gdsc@fd8c34a0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_camss_top"; + reg = <0xfd8c34a0 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@fd8c2304 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0xfd8c2304 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@fd8c35a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0xfd8c35a4 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@fd8c36a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0xfd8c36a4 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@fd8c36d4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0xfd8c36d4 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@fd8c4024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0xfd8c4024 0x4>; + status = "disabled"; + }; + + gdsc_oxili_cx: qcom,gdsc@fd8c4034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_cx"; + reg = <0xfd8c4034 0x4>; + status = "disabled"; + }; + + gdsc_usb_hsic: qcom,gdsc@fc400404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb_hsic"; + reg = <0xfc400404 0x4>; + status = "disabled"; + }; + + gdsc_pcie: qcom,gdsc@0xfc401e18 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie"; + reg = <0xfc401e18 0x4>; + status = "disabled"; + }; + + gdsc_pcie_0: qcom,gdsc@fc401ac4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_0"; + reg = <0xfc401ac4 0x4>; + status = "disabled"; + }; + + gdsc_pcie_1: qcom,gdsc@fc401b44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_1"; + reg = <0xfc401b44 0x4>; + status = "disabled"; + }; + + gdsc_usb30: qcom,gdsc@fc401e84 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30"; + reg = <0xfc401e84 0x4>; + status = "disabled"; + }; + + gdsc_usb30_sec: qcom,gdsc@fc401ec0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30_sec"; + reg = <0xfc401ec0 0x4>; + status = "disabled"; + }; + + gdsc_vcap: qcom,gdsc@fd8c1804 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vcap"; + reg = <0xfd8c1804 0x4>; + status = "disabled"; + }; + + gdsc_bcss: qcom,gdsc@fc744128 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_bcss"; + reg = <0xfc744128 0x4>; + status = "disabled"; + }; + + gdsc_ufs: qcom,gdsc@fc401d44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_ufs"; + reg = <0xfc401d44 0x4>; + status = "disabled"; + }; + + gdsc_fd: qcom,gdsc@fd8c3b64 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_fd"; + reg = <0xfd8c3b64 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v0.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v0.dtsi new file mode 100755 index 0000000000000..88919353600b8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v0.dtsi @@ -0,0 +1,328 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + lpass_iommu: qcom,iommu@fd000000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd000000 0x10000>; + interrupts = <0 248 0>; + qcom,glb-offset = <0xF000>; + label = "lpass_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "lpass_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <11 512 0 0>, + <11 512 0 1000>; + qcom,msm-enable-remote-spinlock; + status = "disabled"; + + lpass_q6_fw: qcom,iommu-ctx@fd000000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd000000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <0 15>; + label = "q6_fw"; + }; + + lpass_audio_shared: qcom,iommu-ctx@fd001000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd001000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <1>; + label = "audio_shared"; + }; + + lpass_video_shared: qcom,iommu-ctx@fd002000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd002000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <2>; + label = "video_shared"; + }; + + lpass_q6_spare: qcom,iommu-ctx@fd003000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd003000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare"; + }; + }; + + copss_iommu: qcom,iommu@fd010000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd010000 0x10000>; + interrupts = <0 252 0>; + qcom,glb-offset = <0xF000>; + label = "copss_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + + status = "disabled"; + + qcom,iommu-ctx@fd010000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd010000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <0>; + label = "copss_0"; + }; + + qcom,iommu-ctx@fd011000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd011000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <1>; + label = "copss_1"; + }; + + qcom,iommu-ctx@fd012000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd012000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <2>; + label = "copss_2"; + }; + + qcom,iommu-ctx@fd013000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd013000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <3>; + label = "copss_3"; + }; + + qcom,iommu-ctx@fd014000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd014000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <4>; + label = "copss_4"; + }; + + qcom,iommu-ctx@fd015000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd015000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <5>; + label = "copss_5"; + }; + + qcom,iommu-ctx@fd016000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd016000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <6>; + label = "copss_6"; + }; + + qcom,iommu-ctx@fd017000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd017000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <7>; + label = "copss_7"; + }; + }; + + mdpe_iommu: qcom,iommu@fd860000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd860000 0x10000>; + interrupts = <0 245 0>; + qcom,glb-offset = <0xF000>; + label = "mdpe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdpe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <92 512 0 0>, + <92 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd860000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd860000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <0 1 3>; + label = "mdpe_0"; + }; + + qcom,iommu-ctx@fd861000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd861000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <2>; + label = "mdpe_1"; + }; + }; + + mdps_iommu: qcom,iommu@fd870000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd870000 0x10000>; + interrupts = <0 73 0>; + qcom,glb-offset = <0xF000>; + label = "mdps_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdps_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd870000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd870000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <0>; + label = "mdps_0"; + }; + + qcom,iommu-ctx@fd871000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd871000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <1>; + label = "mdps_1"; + }; + }; + + gfx_iommu: qcom,iommu@fd880000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd880000 0x10000>; + interrupts = <0 38 0>; + qcom,glb-offset = <0xF000>; + qcom,needs-alt-core-clk; + label = "gfx_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "gfx_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd880000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd880000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 + 14 15>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fd881000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd881000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25 + 26 27 28 29 30 31>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fd882000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd882000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <>; + label = "gfx3d_spare"; + }; + }; + + vfe_iommu: qcom,iommu@fd890000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd890000 0x10000>; + interrupts = <0 62 0>; + qcom,glb-offset = <0xF000>; + label = "vfe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd890000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd890000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9>; + label = "vfe0"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v1.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v1.dtsi new file mode 100755 index 0000000000000..911d83c109235 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v1.dtsi @@ -0,0 +1,1513 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + jpeg_iommu: qcom,iommu@fda64000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda64000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 67 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "jpeg_iommu"; + status = "disabled"; + qcom,msm-bus,name = "jpeg_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <62 512 0 0>, + <62 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x0000ffff + 0x0 + 0x4 + 0x4 + 0x0 + 0x0 + 0x10 + 0x50 + 0x0 + 0x10 + 0x20 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@fda6d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <1>; + label = "jpeg_enc1"; + }; + + qcom,iommu-ctx@fda6e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6e000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <2>; + label = "jpeg_dec"; + }; + }; + + mdp_iommu: qcom,iommu@fd928000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd928000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000034 + 0x00000044 + 0x0 + 0x34 + 0x74 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd930000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd930000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd931000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd931000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd932000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd932000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; + + venus_iommu: qcom,iommu@fdc84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdc84000 0x10000 + 0xfdce0004 0x4>; + reg-names = "iommu_base", "clk_base"; + interrupts = <0 45 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <0>; + qcom,needs-alt-core-clk; + label = "venus_iommu"; + qcom,msm-bus,name = "venus_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2024 + 0x2028 + 0x202c + 0x2030 + 0x2034 + 0x2038>; + + qcom,iommu-bfb-data = <0xffffffff + 0xffffffff + 0x00000004 + 0x00000008 + 0x00000000 + 0x00000000 + 0x00000094 + 0x000000b4 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8c000 0x1000>; + interrupts = <0 42 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5>; + label = "venus_ns"; + }; + + venus_cp: qcom,iommu-ctx@fdc8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8d000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>; + label = "venus_cp"; + qcom,secure-context; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8e000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0xc0 0xc6>; + label = "venus_fw"; + qcom,secure-context; + }; + }; + + kgsl_iommu: qcom,iommu@fdb10000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdb10000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 38 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "kgsl_iommu"; + qcom,msm-bus,name = "kgsl_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000001 + 0x00000021 + 0x0 + 0x1 + 0x81 + 0x0>; + + qcom,iommu-ctx@fdb18000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb18000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fdb19000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb19000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fdb1a000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb1a000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <2>; + label = "gfx3d_spare"; + }; + + }; + + vfe_iommu: qcom,iommu@fda44000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda44000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 62 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <19>; + qcom,needs-alt-core-clk; + label = "vfe_iommu"; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x00000000 + 0x4 + 0x8 + 0x0 + 0x0 + 0x20 + 0x78 + 0x0 + 0x20 + 0x36 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda4c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4c000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <0 1>; + label = "vfe"; + }; + + qcom,iommu-ctx@fda4d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4d000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp"; + }; + + qcom,iommu-ctx@fda4e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4e000 0x1000>; + interrupts = <0 65 0>, <0 64 0>; + qcom,iommu-ctx-sids = <>; + label = "vfe_secure"; + qcom,secure-context; + }; + }; + + copss_iommu: qcom,iommu@f9bc4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xf9bc4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 153 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <8>; + label = "copss_iommu"; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x5 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x3 + 0x0>; + + + copss_cb0: qcom,iommu-ctx@f9bcc000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcc000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <0>; + label = "copss_cb0"; + }; + + copss_cb1: qcom,iommu-ctx@f9bcd000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcd000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <1>; + label = "copss_cb1"; + }; + + copss_usb: qcom,iommu-ctx@f9bce000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bce000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <2>; + label = "copss_usb"; + }; + + copss_cb3: qcom,iommu-ctx@f9bcf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcf000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <3>; + label = "copss_cb3"; + }; + + copss_cb4: qcom,iommu-ctx@f9bd0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd0000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <4>; + label = "copss_cb4"; + }; + + copss_cb5: qcom,iommu-ctx@f9bd1000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd1000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <5>; + label = "copss_cb5"; + }; + + copss_cb6: qcom,iommu-ctx@f9bd2000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd2000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <6>; + label = "copss_cb6"; + }; + + copss_cb_7: qcom,iommu-ctx@f9bd3000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd3000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <7>; + label = "copss_cb7"; + }; + }; + + vpu_iommu: qcom,iommu@fdee4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdee4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 147 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <7>; + label = "vpu_iommu"; + qcom,msm-bus,name = "vpu_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <93 512 0 0>, + <93 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0xffff + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x0 + 0x1e00 + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2000 + 0x2014>; + + qcom,iommu-lpae-bfb-data = <0xffff + 0x0 + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x1e00 + 0x5a2d + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x3 + 0x0>; + + + vpu_hlos: qcom,iommu-ctx@fdeec000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeec000 0x1000>; + interrupts = <0 145 0>; + qcom,iommu-ctx-sids = <0 1 3>; + label = "vpu_hlos"; + }; + + vpu_cp: qcom,iommu-ctx@fdeed000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeed000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <8 9>; + label = "vpu_cp"; + qcom,secure-context; + }; + + vpu_fw: qcom,iommu-ctx@fdeee000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeee000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <5 7 15>; + label = "vpu_fw"; + qcom,secure-context; + }; + }; + + lpass_qdsp_iommu: qcom,iommu@fe054000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe054000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 202 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <2>; + label = "lpass_qdsp_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x20 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x3 + 0x0>; + + + lpass_q6_fw: qcom,iommu-ctx@fe05c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05c000 0x1000>; + interrupts = <0 265 0>, <0 203 0>; + qcom,iommu-ctx-sids = <0 15>; + label = "q6_fw"; + qcom,secure-context; + }; + + lpass_audio_shared: qcom,iommu-ctx@fe05d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05d000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <1>; + label = "audio_shared"; + }; + + lpass_q6_spare1: qcom,iommu-ctx@fe05e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05e000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <2>; + label = "q6_spare1"; + }; + + lpass_q6_spare2: qcom,iommu-ctx@fe05f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05f000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare2"; + }; + }; + + lpass_core_iommu: qcom,iommu@fe064000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe064000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 166 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <6>; + label = "lpass_core_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0xc + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x3 + 0x0>; + + + lpass_core_image: qcom,iommu-ctx@fe06c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06c000 0x1000>; + interrupts = <0 267 0>, <0 180 0>; + qcom,iommu-ctx-sids = <11>; + label = "lpass_core_image"; + qcom,secure-context; + }; + + lpass_core_audio: qcom,iommu-ctx@fe06d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06d000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <12>; + label = "lpass_core_audio"; + }; + + lpass_core_slimbus: qcom,iommu-ctx@fe06e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06e000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <13>; + label = "lpass_core_slimbus"; + }; + }; + + vcap_iommu: qcom,iommu@fdfb6000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdfb6000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 315 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "vcap_iommu"; + status = "disabled"; + qcom,msm-bus,name = "vcap_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <48 512 0 0>, + <48 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2060>; + + qcom,iommu-bfb-data = <0x0ff + 0x00000004 + 0x00000008 + 0x0 + 0x0 + 0x00000008 + 0x00000028 + 0x0 + 0x001000 + 0x001000 + 0x003008 + 0x0 + 0x0 + 0x0 + 0x1555>; + + qcom,iommu-ctx@fdfbe000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbe000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <0>; + label = "vcap_cb0"; + }; + + qcom,iommu-ctx@fdfbf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbf000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <1>; + label = "vcap_cb1"; + }; + + qcom,iommu-ctx@fdfc0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfc0000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <>; + label = "vcap_cb2"; + }; + }; + + bcast_iommu: qcom,iommu@fc734000{ + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfc734000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 279 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "bcast_iommu"; + qcom,iommu-secure-id = <13>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2060>; + + qcom,iommu-bfb-data = <0xffffffff + 0x1 + 0x0000004 + 0x0000004 + 0x0 + 0x0 + 0x000055 + 0x0000d9 + 0x0 + 0x000aa00 + 0x0004200 + 0x000e821 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x1555>; + + bcast_cb0_hlos: qcom,iommu-ctx@fc73c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73c000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31>; + label = "bcast_cb0_hlos"; + }; + + bcast_cb1_cpz: qcom,iommu-ctx@fc73d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73d000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62>; + label = "bcast_cb1_cpz"; + qcom,secure-context; + }; + + bcast_cb2_demod: qcom,iommu-ctx@fc73e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73e000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <63>; + label = "bcast_cb2_demod"; + qcom,secure-context; + }; + + bcast_cb3_apz: qcom,iommu-ctx@fc73f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73f000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <>; + label = "bcast_cb3_apz"; + qcom,secure-context; + }; + }; + + fd_iommu: qcom,iommu@0xfd864000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd864000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 314 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "fd_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x00000007 + 0x1555 + 0x0 + 0x00000004 + 0x00000008 + 0x0601 + 0x1a0d + 0x0400 + 0x1a02 + 0x0 + 0x00000000 + 0x00000002 + 0x0000000a + 0x0>; + + qcom,iommu-ctx@fd86c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86c000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <0>; + label = "camera_fd"; + }; + + qcom,iommu-ctx@fd86d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86d000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_1"; + }; + + qcom,iommu-ctx@fd86e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86e000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_2"; + }; + }; + + cpp_iommu: qcom,iommu@0xfda84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda84000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 264 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "cpp_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c>; + + qcom,iommu-bfb-data = <0x00000003 + 0x3ff + 0x1555 + 0x0 + 0x00000004 + 0x10 + 0x1400 + 0x164b2 + 0x1400 + 0x1640a + 0x0 + 0x00000000 + 0x0000000a + 0x32 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8c000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp_0"; + }; + + qcom,iommu-ctx@fda8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8d000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_1"; + }; + + qcom,iommu-ctx@fda8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8e000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_2"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v2.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v2.dtsi new file mode 100755 index 0000000000000..2aa3828704d07 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-iommu-v2.dtsi @@ -0,0 +1,238 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gfx_iommu: qcom,iommu@1f00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1f00000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "gfx_iommu"; + qcom,iommu-secure-id = <18>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_gfx_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + status = "disabled"; + + qcom,iommu-ctx@1f09000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f09000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@1f0a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f0a000 0x1000>; + interrupts = <0 242 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + }; + + apps_iommu: qcom,iommu@1e00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1e00000 0x40000 + 0x1ef0000 0x3000>; + reg-names = "iommu_base", "smmu_local_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "apps_iommu"; + qcom,iommu-secure-id = <17>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_apss_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + qcom,cb-base-offset = <0x20000>; + status = "disabled"; + + qcom,iommu-ctx@1e22000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e22000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2000>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@1e23000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e23000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x400>; + label = "vfe"; + }; + + qcom,iommu-ctx@1e24000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e24000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xc00>; + label = "mdp_0"; + }; + + venus_ns: qcom,iommu-ctx@1e25000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e25000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x800 0x801 0x802 0x803 + 0x804 0x805 0x807>; + label = "venus_ns"; + }; + + qcom,iommu-ctx@1e26000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e26000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x402>; + label = "cpp"; + }; + + qcom,iommu-ctx@1e27000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e27000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1000>; + label = "mDSP"; + }; + + qcom,iommu-ctx@1e28000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e28000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1400>; + label = "gss"; + }; + + qcom,iommu-ctx@1e29000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e29000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1800>; + label = "a2"; + }; + + qcom,iommu-ctx@1e32000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e32000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0xc01>; + label = "mdp_1"; + }; + + venus_sec_pixel: qcom,iommu-ctx@1e33000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e33000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x885>; + label = "venus_sec_pixel"; + }; + + venus_sec_bitstream: qcom,iommu-ctx@1e34000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e34000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x880 0x881 0x882 0x883 0x884>; + label = "venus_sec_bitstream"; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@1e35000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e35000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x887 0x8a0>; + label = "venus_sec_non_pixel"; + }; + + venus_fw: qcom,iommu-ctx@1e36000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e36000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x8c0 0x8c6>; + label = "venus_fw"; + }; + + periph_rpm: qcom,iommu-ctx@1e37000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e37000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x40>; + label = "periph_rpm"; + }; + + qcom,iommu-ctx@1e38000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e38000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xC0 0xC4 0xC8 0xCC 0xD0 0xD3 + 0xD4 0xD7 0xD8 0xDB 0xDC 0xDF + 0xF0 0xF3 0xF4 0xF7 0xF8 0xFB + 0xFC 0xFF>; + label = "periph_CE"; + }; + + qcom,iommu-ctx@1e39000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e39000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x280 0x283 0x284 0x287 0x288 + 0x28B 0x28C 0x28F 0x290 0x293 + 0x294 0x297 0x298 0x29B 0x29C + 0x29F>; + label = "periph_BLSP"; + }; + + qcom,iommu-ctx@1e3a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3a000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x100>; + label = "periph_SDC1"; + }; + + qcom,iommu-ctx@1e3b000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3b000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x140>; + label = "periph_SDC2"; + }; + + qcom,iommu-ctx@1e3c000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1c0>; + label = "periph_audio"; + }; + + qcom,iommu-ctx@1e3d000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2c0>; + label = "periph_USB_HS1"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-pm8994-rpm-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-pm8994-rpm-regulator.dtsi new file mode 100755 index 0000000000000..8c32136aabd4b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-pm8994-rpm-regulator.dtsi @@ -0,0 +1,697 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + rpm-regulator-smpa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <3>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <4>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa5 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <5>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s5 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s5"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa7 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <7>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s7 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s7"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <2>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <3>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <4>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa6 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <6>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l6 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l6"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa8 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <8>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l8 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l8"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa9 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <9>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l9 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l9"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa10 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <10>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l10 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l10"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa11 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <11>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l11 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l11"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa12 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <12>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l12 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l12"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa13 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <13>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l13 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l13"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa14 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <14>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l14 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l14"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa15 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <15>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l15 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l15"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa16 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <16>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l16 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l16"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa17 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <17>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l17 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l17"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa18 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <18>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l18 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l18"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa19 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <19>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l19 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l19"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa20 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <20>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l20 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l20"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa21 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <21>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l21 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l21"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa22 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <22>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l22 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l22"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa23 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <23>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l23 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l23"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa24 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <24>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l24 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l24"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa25 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <25>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l25 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l25"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa26 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <26>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l26 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l26"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa27 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <27>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l27 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l27"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa28 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <28>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l28 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l28"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa29 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <29>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l29 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l29"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa30 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <30>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l30 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l30"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa31 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <31>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l31 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l31"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa32 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <32>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l32 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l32"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <2>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bstb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bstb"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-bst { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bbyb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bbyb"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + status = "disabled"; + + regulator-bby { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boostbypass"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpc2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpc"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-pm8994.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-pm8994.dtsi new file mode 100755 index 0000000000000..7312c2594e9ec --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-pm8994.dtsi @@ -0,0 +1,576 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pm8994@0 { + spmi-slave-container; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + + pm8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,temp-alarm@2400 { + compatible = "qcom,qpnp-temp-alarm"; + reg = <0x2400 0x100>; + interrupts = <0x0 0x24 0x0>; + label = "pm8994_tz"; + qcom,channel-num = <8>; + qcom,threshold-set = <0>; + qcom,temp_alarm-vadc = <&pm8994_vadc>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + interrupts = <0x0 0x8 0x0>, + <0x0 0x8 0x1>, + <0x0 0x8 0x4>, + <0x0 0x8 0x5>; + interrupt-names = "kpdpwr", "resin", + "resin-bark", "kpdpwr-resin-bark"; + qcom,pon-dbc-delay = <15625>; + qcom,system-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + + qcom,pon_1 { + qcom,pon-type = <0>; + qcom,pull-up = <1>; + linux,code = <116>; + qcom,support-reset = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <10256>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_2 { + qcom,pon-type = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT + // comment out by yangrujin@bsp for vol_down is controled by gpio + //linux,code = <114>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_3 { + qcom,pon-type = <3>; + qcom,support-reset = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <6720>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + + qcom,use-bark; + }; + }; + + pm8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + + gpio@ca00 { + reg = <0xca00 0x100>; + qcom,pin-num = <11>; + status = "disabled"; + }; + + gpio@cb00 { + reg = <0xcb00 0x100>; + qcom,pin-num = <12>; + status = "disabled"; + }; + + gpio@cc00 { + reg = <0xcc00 0x100>; + qcom,pin-num = <13>; + status = "disabled"; + }; + + gpio@cd00 { + reg = <0xcd00 0x100>; + qcom,pin-num = <14>; + status = "disabled"; + }; + + gpio@ce00 { + reg = <0xce00 0x100>; + qcom,pin-num = <15>; + status = "disabled"; + }; + + gpio@cf00 { + reg = <0xcf00 0x100>; + qcom,pin-num = <16>; + status = "disabled"; + }; + + gpio@d000 { + reg = <0xd000 0x100>; + qcom,pin-num = <17>; + status = "disabled"; + }; + + gpio@d100 { + reg = <0xd100 0x100>; + qcom,pin-num = <18>; + status = "disabled"; + }; + + gpio@d200 { + reg = <0xd200 0x100>; + qcom,pin-num = <19>; + status = "disabled"; + }; + + gpio@d300 { + reg = <0xd300 0x100>; + qcom,pin-num = <20>; + status = "disabled"; + }; + + gpio@d500 { + reg = <0xd500 0x100>; + qcom,pin-num = <22>; + status = "disabled"; + }; + }; + + pm8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp02*/ + /* + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP2 as an Analog input to AMUX6 and read from channel 0x11 */ + mpp@a100 { /* MPP 2 */ + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <1>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH6 = 1*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4)*/ + /* + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + };*/ + /*#else VENDOR_EDIT*/ + /* Configure MPP4 as an Analog input to AMUX8 and read from channel 0x23 */ + mpp@a300 { /* MPP 4 */ + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 8 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4) end*/ + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp05*/ + /* + mpp@a400 { + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP5 as an Analog input to AMUX5 and read from channel 0x14 */ + mpp@a400 { /* MPP 5 */ + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <0>; /* AMUX 5 ,QPNP_PIN_AIN_AMUX_CH5 = 0*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a500 { + reg = <0xa500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + mpp@a600 { + reg = <0xa600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp08*/ + /* + mpp@a700 { + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP8 as an Analog input to AMUX8 and read from channel 0x17 */ + mpp@a700 { /* MPP 8 */ + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + }; + + pm8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x31 0x0>; + interrupt-names = "eoc-int-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + + chan@8 { + label = "die_temp"; + reg = <8>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <3>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@9 { + label = "ref_625mv"; + reg = <9>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@a { + label = "ref_1250v"; + reg = <0xa>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + /* VADC Channel configuration */ + chan@23 { + label = "cover_mpp4_div3"; + reg = <0x23>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; //Use 1:3 scaling to keep input voltage with in Max voltage: 1.8V + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /* //EVB2 floating,so use 1:1 chan + chan@13 { + label = "cover_mpp4_div3"; + reg = <0x13>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + };*/ + /*#endif VENDOR_EDIT*/ + + +/*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + /* VADC Channel configuration */ + chan@76 { + label = "pcb_version_AMUX_HW_ID"; + reg = <0x76>;//pcb_version_AMUX_HW_ID channel 54 + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; //Use 1:1 scaling to keep input voltage with in Max voltage: 1.8V + //qcom,calibration-type = "ratiometric"; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@11 { + label = "rf_mpp2"; + reg = <0x11>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@14 { + label = "rf_mpp5"; + reg = <0x14>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@17 { + label = "rf_mpp8"; + reg = <0x17>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#endif VENDOR_EDIT*/ + }; + + pm8994_adc_tm: vadc@3400 { + compatible = "qcom,qpnp-adc-tm"; + reg = <0x3400 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x34 0x0>, + <0x0 0x34 0x3>, + <0x0 0x34 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,adc_tm-vadc = <&pm8994_vadc>; + }; + + pm8994_coincell: qcom,coincell@2800 { + compatible = "qcom,qpnp-coincell"; + reg = <0x2800 0x100>; + }; + + qcom,pm8994_rtc { + spmi-dev-container; + compatible = "qcom,qpnp-rtc"; + #address-cells = <1>; + #size-cells = <1>; + qcom,qpnp-rtc-write = <0>; + /*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + qcom,qpnp-rtc-alarm-pwrup = <1>; + /*#endif VENDOR_EDIT*/ + + qcom,pm8994_rtc_rw@6000 { + reg = <0x6000 0x100>; + }; + qcom,pm8994_rtc_alarm@6100 { + reg = <0x6100 0x100>; + interrupts = <0x0 0x61 0x1>; + }; + }; + }; + + qcom,pm8994@1 { + spmi-slave-container; + reg = <0x1>; + #address-cells = <1>; + #size-cells = <1>; + + pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b500 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb500 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <4>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <4>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b600 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb600 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <5>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <5>; + #pwm-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-pmi8994.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-pmi8994.dtsi new file mode 100755 index 0000000000000..f7fbc86e1c32c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-pmi8994.dtsi @@ -0,0 +1,741 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pmi8994@2 { + spmi-slave-container; + reg = <0x2>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + qcom,secondary-pon-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + }; + + pmi8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + }; + + pmi8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + }; +//#ifdef VENDOR_EDIT /* shankai@BSP.driver, 2015/3/25, add for the button-backlight */ + qcom,leds@a300 { + compatible = "qcom,leds-qpnp"; + status = "okay"; + reg=<0xa300 0x100>; + qcom,led_mpp_3 { + label = "mpp"; + linux,name = "button-backlight"; + linux,default-trigger = "none"; + qcom,default-state = "off"; + qcom,max-current = <40>; + qcom,current-setting = <5>; + qcom,id = <6>; + qcom,mode = "manual"; + qcom,source-sel = <1>; + qcom,mode-ctrl = <0x60>; + }; + }; +//#endif /*VENDOR_EDIT*/ + + + + bcl@4200 { + compatible = "qcom,msm-bcl"; + reg = <0x4200 0xFF 0x88E 0x2>; + reg-names = "fg_user_adc", "pon_spare"; + interrupts = <0x2 0x42 0x0>, + <0x2 0x42 0x1>; + interrupt-names = "bcl-high-ibat-int", + "bcl-low-vbat-int"; + qcom,vbat-scaling-factor = <39000>; + qcom,vbat-gain-numerator = <1>; + qcom,vbat-gain-denominator = <128>; + qcom,vbat-polling-delay-ms = <100>; + qcom,ibat-scaling-factor = <39000>; + qcom,ibat-gain-numerator = <1>; + qcom,ibat-gain-denominator = <128>; + qcom,ibat-offset-numerator = <1200>; + qcom,ibat-offset-denominator = <1>; + qcom,ibat-polling-delay-ms = <100>; + qcom,inhibit-derating-ua = <550000>; + }; + + pmi8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x2 0x31 0x0>, + <0x2 0x31 0x3>, + <0x2 0x31 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + qcom,vadc-meas-int-mode; + }; + + pmi8994_charger: qcom,qpnp-smbcharger { + spmi-dev-container; + compatible = "qcom,qpnp-smbcharger"; + #address-cells = <1>; + #size-cells = <1>; + + qcom,iterm-ma = <150>; + qcom,fastchg-current-ma = <1910>; + qcom,float-voltage-mv = <4320>; + qcom,resume-delta-mv = <100>; + // qcom,chg-inhibit-en; + qcom,chg-inhibit-fg; + qcom,dc-psy-type = "Mains"; + qcom,dc-psy-ma = <1500>; + qcom,rparasitic-uohm = <100000>; + qcom,bms-psy-name = "bms"; + qcom,thermal-mitigation = <2000 1000 900 800>; + qcom,parallel-usb-min-current-ma = <1400>; + qcom,parallel-usb-9v-min-current-ma = <900>; + qcom,parallel-allowed-lowering-ma = <500>; + qcom,autoadjust-vfloat; + qcom,charge-unknown-battery; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x2 0x10 0x0>, + <0x2 0x10 0x1>, + <0x2 0x10 0x2>, + <0x2 0x10 0x3>, + <0x2 0x10 0x4>, + <0x2 0x10 0x5>, + <0x2 0x10 0x6>, + <0x2 0x10 0x7>; + + interrupt-names = "chg-error", + "chg-inhibit", + "chg-prechg-sft", + "chg-complete-chg-sft", + "chg-p2f-thr", + "chg-rechg-thr", + "chg-taper-thr", + "chg-tcc-thr"; + }; + + qcom,otg@1100 { + reg = <0x1100 0x100>; + }; + + qcom,bat-if@1200 { + reg = <0x1200 0x100>; + interrupts = <0x2 0x12 0x0>, + <0x2 0x12 0x1>, + <0x2 0x12 0x2>, + <0x2 0x12 0x3>, + <0x2 0x12 0x4>, + <0x2 0x12 0x5>, + <0x2 0x12 0x6>, + <0x2 0x12 0x7>; + + interrupt-names = "batt-hot", + "batt-warm", + "batt-cold", + "batt-cool", + "batt-ov", + "batt-low", + "batt-missing", + "batt-term-missing"; + }; + + qcom,usb-chgpth@1300 { + reg = <0x1300 0x100>; + interrupts = <0x2 0x13 0x0>, + <0x2 0x13 0x1>, + <0x2 0x13 0x2>, + <0x2 0x13 0x3>, + <0x2 0x13 0x4>, + <0x2 0x13 0x5>, + <0x2 0x13 0x6>; + + interrupt-names = "usbin-uv", + "usbin-ov", + "usbin-src-det", + "otg-fail", + "otg-oc", + "aicl-done", + "usbid-change"; + }; + + qcom,dc-chgpth@1400 { + reg = <0x1400 0x100>; + interrupts = <0x2 0x14 0x0>, + <0x2 0x14 0x1>; + + interrupt-names = "dcin-uv", + "dcin-ov"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x2 0x16 0x0>, + <0x2 0x16 0x1>, + <0x2 0x16 0x2>, + <0x2 0x16 0x3>, + <0x2 0x16 0x4>, + <0x2 0x16 0x5>; + + interrupt-names = "power-ok", + "temp-shutdown", + "safety-timeout", + "flash-fail", + "otst2", + "otst3"; + }; + }; + + pmi8994_fg: qcom,fg { + spmi-dev-container; + compatible = "qcom,qpnp-fg"; + #address-cells = <1>; + #size-cells = <1>; + //qcom,resume-soc = <95>; + qcom,resume-soc = <99>; + status = "okay"; + qcom,bcl-lm-threshold-ma = <127>; + qcom,bcl-mh-threshold-ma = <405>; + qcom,fg-chg-iterm-ma = <150>; + qcom,cycle-counter-en; + qcom,cycle-counter-low-soc = <15>; + qcom,cycle-counter-high-soc = <85>; + qcom,capacity-learning-on; + qcom,fg-cc-cv-threshold-mv = <4310>; + qcom,fg-iterm-ma = <200>; + qcom,fg-cutoff-voltage-mv=<3500>; + qcom,pmic-revid = <&pmi8994_revid>; + + qcom,thermal-coefficients = [da 86 f0 50 08 3c]; + qcom,fg-soc@4000 { + status = "okay"; + reg = <0x4000 0x100>; + interrupts = <0x2 0x40 0x0>, + <0x2 0x40 0x1>, + <0x2 0x40 0x2>, + <0x2 0x40 0x3>, + <0x2 0x40 0x4>, + <0x2 0x40 0x5>, + <0x2 0x40 0x6>, + <0x2 0x40 0x7>; + + interrupt-names = "high-soc", + "low-soc", + "full-soc", + "empty-soc", + "delta-soc", + "first-est-done", + "sw-fallbk-ocv", + "sw-fallbk-new-battrt-sts", + "fg-soc-irq-count"; + }; + + qcom,fg-batt@4100 { + reg = <0x4100 0x100>; + interrupts = <0x2 0x41 0x0>, + <0x2 0x41 0x1>, + <0x2 0x41 0x2>, + <0x2 0x41 0x3>, + <0x2 0x41 0x4>, + <0x2 0x41 0x5>, + <0x2 0x41 0x6>, + <0x2 0x41 0x7>; + + interrupt-names = "soft-cold", + "soft-hot", + "vbatt-low", + "batt-ided", + "batt-id-req", + "batt-unknown", + "batt-missing", + "batt-match"; + }; + + qcom,fg-adc-vbat@4254 { + reg = <0x4254 0x1>; + }; + + qcom,fg-adc-ibat@4255 { + reg = <0x4255 0x1>; + }; + + qcom,revid-tp-rev@1f1 { + reg = <0x1f1 0x1>; + }; + + qcom,fg-memif@4400 { + status = "okay"; + reg = <0x4400 0x100>; + interrupts = <0x2 0x44 0x0>, + <0x2 0x44 0x1>; + + interrupt-names = "mem-avail", + "data-rcvry-sug"; + }; + }; + }; + + qcom,pmi8994@3 { + spmi-slave-container; + reg = <0x3>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_pwm_1: pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_2: pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_3: pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_4: pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + }; + + labibb: qpnp-labibb-regulator { + status = "disabled"; + spmi-dev-container; + compatible = "qcom,qpnp-labibb-regulator"; + #address-cells = <1>; + #size-cells = <1>; + + lab_regulator: qcom,lab@de00 { + reg = <0xde00 0x100>; + reg-names = "lab"; + regulator-name = "lab_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-lab-min-voltage = <4600000>; + qcom,qpnp-lab-step-size = <100000>; + qcom,qpnp-lab-slew-rate = <5000>; + qcom,qpnp-lab-use-default-voltage; + qcom,qpnp-lab-init-voltage = <5500000>; + qcom,qpnp-lab-init-amoled-voltage = <4600000>; + qcom,qpnp-lab-init-lcd-voltage = <5500000>; + + qcom,qpnp-lab-soft-start = <800>; + + qcom,qpnp-lab-full-pull-down; + qcom,qpnp-lab-pull-down-enable; + qcom,qpnp-lab-switching-clock-frequency = <1600>; + qcom,qpnp-lab-limit-maximum-current = <800>; + qcom,qpnp-lab-limit-max-current-enable; + qcom,qpnp-lab-ps-threshold = <20>; + qcom,qpnp-lab-ps-enable; + qcom,qpnp-lab-nfet-size = <100>; + qcom,qpnp-lab-pfet-size = <100>; + qcom,qpnp-lab-max-precharge-time = <200>; + }; + + ibb_regulator: qcom,ibb@dc00 { + reg = <0xdc00 0x100>; + reg-names = "ibb_reg"; + regulator-name = "ibb_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-ibb-min-voltage = <1400000>; + qcom,qpnp-ibb-step-size = <100000>; + qcom,qpnp-ibb-slew-rate = <2000000>; + qcom,qpnp-ibb-use-default-voltage; + qcom,qpnp-ibb-init-voltage = <5500000>; + qcom,qpnp-ibb-init-amoled-voltage = <4000000>; + qcom,qpnp-ibb-init-lcd-voltage = <5500000>; + + qcom,qpnp-ibb-soft-start = <1000>; + + qcom,qpnp-ibb-discharge-resistor = <300>; + qcom,qpnp-ibb-lab-pwrup-delay = <4000>; + qcom,qpnp-ibb-lab-pwrdn-delay = <4000>; + qcom,qpnp-ibb-en-discharge; + + qcom,qpnp-ibb-full-pull-down; + qcom,qpnp-ibb-pull-down-enable; + qcom,qpnp-ibb-switching-clock-frequency = <1480>; + qcom,qpnp-ibb-limit-maximum-current = <1550>; + qcom,qpnp-ibb-debounce-cycle = <16>; + qcom,qpnp-ibb-limit-max-current-enable; + qcom,qpnp-ibb-ps-enable; + }; + + }; + + qcom,leds@d800 { + compatible = "qcom,qpnp-wled"; + reg = <0xd800 0x100>, + <0xd900 0x100>, + <0xdc00 0x100>, + <0xde00 0x100>; + reg-names = "qpnp-wled-ctrl-base", + "qpnp-wled-sink-base", + "qpnp-wled-ibb-base", + "qpnp-wled-lab-base"; + interrupts = <0x3 0xd8 0x2>; + interrupt-names = "sc-irq"; + status = "okay"; + linux,name = "wled"; + linux,default-trigger = "bkl-trigger"; + qcom,fdbk-output = "auto"; + qcom,vref-mv = <350>; + qcom,switch-freq-khz = <800>; + qcom,ovp-mv = <29500>; + qcom,ilim-ma = <980>; + qcom,boost-duty-ns = <26>; + qcom,mod-freq-khz = <9600>; + qcom,dim-mode = "hybrid"; + qcom,dim-method = "linear"; + qcom,hyb-thres = <625>; + qcom,sync-dly-us = <800>; + qcom,fs-curr-ua = <20000>;//guozhimig@oem add 2015-04-02 for adiudt backlight 20mA + qcom,en-phase-stag; + qcom,ibb-pwrup-dly = <8>; + qcom,led-strings-list = [00 01];//two WLED SINK/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,en-ext-pfet-sc-pro; + qcom,en-cabc;//guozhimig@oem add 2015-04-02 for en cabc + }; + +//#ifdef VENDOR_EDIT // shankai@bsp, 2015-4-4 do not use it ,comment it. +/* + pmi8994_haptics: qcom,haptic@c000 { + status = "disabled"; + compatible = "qcom,qpnp-haptic"; + reg = <0xc000 0x100>; + interrupts = <0x3 0xc0 0x0>, + <0x3 0xc0 0x1>; + interrupt-names = "sc-irq", "play-irq"; + qcom,play-mode = "direct"; + qcom,wave-play-rate-us = <5263>; + qcom,actuator-type = "lra"; + qcom,wave-shape = "square"; + qcom,vmax-mv = <2000>; + qcom,ilim-ma = <800>; + qcom,sc-deb-cycles = <8>; + qcom,int-pwm-freq-khz = <505>; + qcom,en-brake; + qcom,brake-pattern = [03 03 00 00]; + qcom,use-play-irq; + qcom,use-sc-irq; + qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e]; + qcom,wave-rep-cnt = <1>; + qcom,wave-samp-rep-cnt = <1>; + }; +*/ +//#endif + qcom,leds@d000 { + compatible = "qcom,leds-qpnp"; + reg = <0xd000 0x100>; + label = "rgb"; + status = "okay"; + + /*#ifndef VENDOR_EDIT //shankai@bsp.driver 2015-02-26 modify for rgb blink feature*/ + qcom,rgb_0 { + label = "rgb"; + qcom,id = <3>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_3 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <1>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "red"; + /*linux,default-trigger = + "battery-charging";*/ + qcom,use-blink; + }; + + qcom,rgb_1 { + label = "rgb"; + qcom,id = <4>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_2 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + /* + qcom,duty-pcts = [00 05 0A 0f 14 19 1d 23 28 2c + 32 37 3b 41 45 4a 50 55 5a 64]; + */ + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "green"; + /*linux,default-trigger = "battery-full";*/ + qcom,use-blink; + }; + + qcom,rgb_2 { + label = "rgb"; + qcom,id = <5>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_1 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + qcom,default-state = "off"; + linux,name = "blue"; + qcom,use-blink; + linux,default-trigger = "boot-indication"; + }; + /*#end VENDOR_EDIT*/ + }; + + qcom,leds@d300 { + compatible = "qcom,qpnp-flash-led"; + status = "okay"; + reg = <0xd300 0x100>; + label = "flash"; + qcom,headroom = <500>; + qcom,startup-dly = <128>; + qcom,clamp-curr = <200>; + qcom,pmic-charger-support; + qcom,self-check-enabled; + qcom,thermal-derate-enabled; + qcom,thermal-derate-threshold = <100>; + qcom,thermal-derate-rate = "5_PERCENT"; + qcom,current-ramp-enabled; + qcom,ramp_up_step = "6P7_US"; + qcom,ramp_dn_step = "6P7_US"; + qcom,vph-pwr-droop-enabled; + qcom,vph-pwr-droop-threshold = <3000>; + qcom,vph-pwr-droop-debounce-time = <10>; + qcom,headroom-sense-ch0-enabled; + qcom,headroom-sense-ch1-enabled; + qcom,power-detect-enabled; + + pmi8994_flash0: qcom,flash_0 { + label = "flash"; + qcom,led-name = "led:flash_0"; + qcom,default-led-trigger = + "flash0_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <0>; + qcom,current = <625>; + }; + + pmi8994_flash1: qcom,flash_1 { + label = "flash"; + qcom,led-name = "led:flash_1"; + qcom,default-led-trigger = + "flash1_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <1>; + qcom,current = <625>; + }; + + pmi8994_torch0: qcom,torch_0 { + label = "torch"; + qcom,led-name = "led:torch_0"; + qcom,default-led-trigger = + "torch0_trigger"; + qcom,max-current = <200>; + qcom,id = <0>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + + pmi8994_torch1: qcom,torch_1 { + label = "torch"; + qcom,led-name = "led:torch_1"; + qcom,default-led-trigger = + "torch1_trigger"; + qcom,max-current = <200>; + qcom,id = <1>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm-rdbg.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm-rdbg.dtsi new file mode 100755 index 0000000000000..f7f52bed111c6 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm-rdbg.dtsi @@ -0,0 +1,75 @@ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + smp2pgpio_rdbg_2_in: qcom,smp2pgpio-rdbg-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_in { + compatible = "qcom,smp2pgpio_client_rdbg_2_in"; + gpios = <&smp2pgpio_rdbg_2_in 0 0>; + }; + + smp2pgpio_rdbg_2_out: qcom,smp2pgpio-rdbg-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_out { + compatible = "qcom,smp2pgpio_client_rdbg_2_out"; + gpios = <&smp2pgpio_rdbg_2_out 0 0>; + }; + + smp2pgpio_rdbg_1_in: qcom,smp2pgpio-rdbg-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_in { + compatible = "qcom,smp2pgpio_client_rdbg_1_in"; + gpios = <&smp2pgpio_rdbg_1_in 0 0>; + }; + + smp2pgpio_rdbg_1_out: qcom,smp2pgpio-rdbg-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_out { + compatible = "qcom,smp2pgpio_client_rdbg_1_out"; + gpios = <&smp2pgpio_rdbg_1_out 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-bus.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-bus.dtsi new file mode 100755 index 0000000000000..6b77e2a0488e4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-bus.dtsi @@ -0,0 +1,1597 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + ad_hoc_bus: ad-hoc-bus@fc460000 { + compatible = "qcom,msm-bus-device"; + reg = <0xFC460000 0x5880>, + <0xFC380000 0x80000>, + <0xFC468000 0x2400>, + <0xFC478000 0x3480>, + <0xFC480000 0x80>; + reg-names = "snoc-base", "bimc-base", "pnoc-base", "mnoc-base", "cnoc-base"; + + fab_snoc: fab-snoc { + cell-id = ; + label = "fab-snoc"; + qcom,fab-dev; + qcom,base-name = "snoc-base"; + qcom,base-offset = <0x5000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_snoc_msmbus_clk>, + <&clock_rpm clk_snoc_msmbus_a_clk>; + + coresight-id = <50>; + coresight-name = "coresight-snoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <3>; + }; + + fab_bimc: fab-bimc { + cell-id = ; + label = "fab-bimc"; + qcom,fab-dev; + qcom,base-name = "bimc-base"; + qcom,bus-type = <2>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_bimc_msmbus_clk>, + <&clock_rpm clk_bimc_msmbus_a_clk>; + + coresight-id = <55>; + coresight-name = "coresight-bimc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <3>; + }; + + fab_pnoc: fab-pnoc { + cell-id = ; + label = "fab-pnoc"; + qcom,fab-dev; + qcom,base-name = "pnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_pnoc_msmbus_clk>, + <&clock_rpm clk_pnoc_msmbus_a_clk>; + + coresight-id = <54>; + coresight-name = "coresight-pnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <6>; + }; + + fab_mnoc: fab-mnoc { + cell-id = ; + label = "fab-mnoc"; + qcom,fab-dev; + qcom,base-name = "mnoc-base"; + qcom,base-offset = <0x3000>; + qcom,bus-type = <1>; + qcom,qos-off = <0x80>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_mmss clk_mmss_s0_axi_clk>, + <&clock_mmss clk_mmss_s0_axi_clk>; + + coresight-id = <56>; + coresight-name = "coresight-mmnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <5>; + }; + + fab_cnoc: fab-cnoc { + cell-id = ; + label = "fab-cnoc"; + qcom,fab-dev; + qcom,base-name = "cnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_cnoc_msmbus_clk>, + <&clock_rpm clk_cnoc_msmbus_a_clk>; + }; + + fab_ovirt: fab-ovirt { + cell-id = ; + label = "fab-ovirt"; + qcom,fab-dev; + qcom,bypass-qos-prg; + qcom,virt-dev; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_ocmemgx_msmbus_clk>, + <&clock_rpm clk_ocmemgx_msmbus_a_clk >; + }; + + + /* bimc Devices */ + mas_apps_proc: mas-apps-proc { + cell-id = ; + label = "mas-apps-proc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&bimc_int_apps_ebi &bimc_int_apps_snoc>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ws = <10000>; + qcom,gp = <5000>; + qcom,thmp = <50>; + qcom,ap-owned; + }; + + bimc_int_apps_ebi: bimc-int-apps-ebi { + cell-id = ; + label = "bimc-int-apps-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_ebi>; + }; + + bimc_int_apps_snoc: bimc-int-apps-snoc { + cell-id = ; + label = "bimc-int-apps-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,connections = <&slv_bimc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_oxili: mas-oxili { + cell-id = ; + label = "mas-oxili"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <2>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ap-owned; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + }; + + + mas_mnoc_bimc: mas-mnoc-bimc { + cell-id = ; + label = "mas-mnoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + qcom,ap-owned; + }; + + + mas_snoc_bimc: mas-snoc-bimc { + cell-id = ; + label = "mas-snoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2>; + qcom,mas-rpm-id = ; + }; + + + slv_ebi: slv-ebi { + cell-id = ; + label = "slv-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <0 1>; + qcom,slv-rpm-id = ; + }; + + + slv_appss_l2: slv-appss-l2 { + cell-id = ; + label = "slv-appss-l2"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_snoc: slv-bimc-snoc { + cell-id = ; + label = "slv-bimc-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_bimc_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* mnoc Devices */ + mas_cnoc_mnoc_mmss_cfg: mas-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_camera_cfg &slv_cpr_cfg &slv_cpr_xpu_cfg + &slv_ocmem_cfg &slv_misc_cfg &slv_misc_xpu_cfg + &slv_oxili_cfg &slv_venus_cfg &slv_mnoc_clocks_cfg + &slv_mnoc_clocks_xpu_cfg &slv_mnoc_mpu_cfg &slv_display_cfg + &slv_avsync_cfg &slv_vpu_cfg>; + qcom,ap-owned; + }; + + + mas_cnoc_mnoc_cfg: mas-cnoc-mnoc-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_srvc_mnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_gemini: mas-gemini { + cell-id = ; + label = "mas-gemini"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <0>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p0: mas-mdp-p0 { + cell-id = ; + label = "mas-mdp-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <2>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p1: mas-mdp-p1 { + cell-id = ; + label = "mas-mdp-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <1>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p0: mas-venus-p0 { + cell-id = ; + label = "mas-venus-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p1: mas-venus-p1 { + cell-id = ; + label = "mas-venus-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_vfe: mas-vfe { + cell-id = ; + label = "mas-vfe"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <6>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_cpp: mas-cpp { + cell-id = ; + label = "mas-cpp"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <5>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_vpu: mas-vpu { + cell-id = ; + label = "mas-vpu"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qos-mode = "bypass"; + qcom,qport = <8>; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_camera_cfg: slv-camera-cfg { + cell-id = ; + label = "slv-camera-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_cfg: slv-cpr-cfg { + cell-id = ; + label = "slv-cpr-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_xpu_cfg: slv-cpr-xpu-cfg { + cell-id = ; + label = "slv-cpr-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_ocmem_cfg: slv-ocmem-cfg { + cell-id = ; + label = "slv-ocmem-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_cfg: slv-misc-cfg { + cell-id = ; + label = "slv-misc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_xpu_cfg: slv-misc-xpu-cfg { + cell-id = ; + label = "slv-misc-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_oxili_cfg: slv-oxili-cfg { + cell-id = ; + label = "slv-oxili-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_venus_cfg: slv-venus-cfg { + cell-id = ; + label = "slv-venus-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_cfg: slv-mnoc-clocks-cfg { + cell-id = ; + label = "slv-mnoc-clocks-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_xpu_cfg: slv-mnoc-clocks-xpu-cfg { + cell-id = ; + label = "slv-mnoc-clocks-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_mpu_cfg: slv-mnoc-mpu-cfg { + cell-id = ; + label = "slv-mnoc-mpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_display_cfg: slv-display-cfg { + cell-id = ; + label = "slv-display-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_avsync_cfg: slv-avsync-cfg { + cell-id = ; + label = "slv-avsync-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_vpu_cfg: slv-vpu-cfg { + cell-id = ; + label = "slv-vpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_bimc: slv-mnoc-bimc { + cell-id = ; + label = "slv-mnoc-bimc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <16 17>; + qcom,connections = <&mas_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_srvc_mnoc: slv-srvc-mnoc { + cell-id = ; + label = "slv-srvc-mnoc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + /* snoc Devices */ + mas_lpass_ahb: mas-lpass-ahb { + cell-id = ; + label = "mas-lpass-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_ocimem &slv_snoc_pnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_bam: mas-qdss-bam { + cell-id = ; + label = "mas-qdss-bam"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <1>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc &slv_usb3>; + qcom,ap-owned; + }; + + + mas_bimc_snoc: mas-bimc-snoc { + cell-id = ; + label = "mas-bimc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_cnoc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + mas_cnoc_snoc: mas-cnoc-snoc { + cell-id = ; + label = "mas-cnoc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_crypto_c0: mas-crypto-c0 { + cell-id = ; + label = "mas-crypto-c0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <2>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c1: mas-crypto-c1 { + cell-id = ; + label = "mas-crypto-c1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <3>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c2: mas-crypto-c2 { + cell-id = ; + label = "mas-crypto-c2"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <9>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_lpass_proc: mas-lpass-proc { + cell-id = ; + label = "mas-lpass-proc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_ovirt_snoc: mas-ovirt-snoc { + cell-id = ; + label = "mas-ovirt-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <5>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc>; + qcom,mas-rpm-id = ; + }; + + + mas_periph_snoc: mas-periph-snoc { + cell-id = ; + label = "mas-periph-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <13>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_lpass &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_pcie_0: mas-pcie-0 { + cell-id = ; + label = "mas-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <7>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_pcie_1: mas-pcie-1 { + cell-id = ; + label = "mas-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <16>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_qdss_etr: mas-qdss-etr { + cell-id = ; + label = "mas-qdss-etr"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ufs: mas-ufs { + cell-id = ; + label = "mas-ufs"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt>; + qcom,ap-owned; + }; + + + mas_usb3: mas-usb3 { + cell-id = ; + label = "mas-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_snoc_cnoc &slv_ocimem &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ipa: mas-ipa { + cell-id = ; + label = "mas-ipa"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <15>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_usb3 &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_pcie_0 &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + slv_kpss_ahb: slv-kpss-ahb { + cell-id = ; + label = "slv-kpss-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_lpass: slv-lpass { + cell-id = ; + label = "slv-lpass"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_bimc: slv-snoc-bimc { + cell-id = ; + label = "slv-snoc-bimc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_bimc>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cnoc: slv-snoc-cnoc { + cell-id = ; + label = "slv-snoc-cnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_cnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_ocimem: slv-ocimem { + cell-id = ; + label = "slv-ocimem"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_ovirt: slv-snoc-ovirt { + cell-id = ; + label = "slv-snoc-ovirt"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_ovirt>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_pnoc: slv-snoc-pnoc { + cell-id = ; + label = "slv-snoc-pnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_pnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_stm: slv-qdss-stm { + cell-id = ; + label = "slv-qdss-stm"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + slv_usb3: slv-usb3 { + cell-id = ; + label = "slv-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0: slv-pcie-0 { + cell-id = ; + label = "slv-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1: slv-pcie-1 { + cell-id = ; + label = "slv-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + /* ovirt Devices */ + mas_snoc_ovirt: mas-snoc-ovirt { + cell-id = ; + label = "mas-snoc-ovirt"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + mas_ocmem_dma: mas-ocmem-dma { + cell-id = ; + label = "mas-ocmem-dma"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem &slv_ovirt_snoc>; + qcom,ap-owned; + }; + + + mas_oxili_ocmem: mas-oxili-ocmem { + cell-id = ; + label = "mas-oxili-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem_gfx>; + qcom,ap-owned; + }; + + + mas_venus_ocmem: mas-venus-ocmem { + cell-id = ; + label = "mas-venus-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + slv_ocmem: slv-ocmem { + cell-id = ; + label = "slv-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <16>; + qcom,ap-owned; + clock-names = "node_clk"; + clocks = <&clock_mmss clk_ocmemnoc_clk_src>; + }; + + slv_ocmem_gfx: slv-ocmem-gfx { + cell-id = ; + label = "slv-ocmem-gfx"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + }; + + + slv_ovirt_snoc: slv-ovirt-snoc { + cell-id = ; + label = "slv-ovirt-snoc"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&mas_ovirt_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* pnoc Devices */ + mas_bam_dma: mas-bam-dma { + cell-id = ; + label = "mas-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_sdcc_1 &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_2: mas-blsp-2 { + cell-id = ; + label = "mas-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_1: mas-blsp-1 { + cell-id = ; + label = "mas-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tsif: mas-tsif { + cell-id = ; + label = "mas-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_usb_hs: mas-usb-hs { + cell-id = ; + label = "mas-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_tsif &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_pnoc_cfg: mas-pnoc-cfg { + cell-id = ; + label = "mas-pnoc-cfg"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_prng>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_1: mas-sdcc-1 { + cell-id = ; + label = "mas-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_2: mas-sdcc-2 { + cell-id = ; + label = "mas-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_3: mas-sdcc-3 { + cell-id = ; + label = "mas-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_4: mas-sdcc-4 { + cell-id = ; + label = "mas-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_pnoc: mas-snoc-pnoc { + cell-id = ; + label = "mas-snoc-pnoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 + &slv_blsp_2 &slv_blsp_1 &slv_tsif &slv_usb_hs + &slv_pdm &slv_prng>; + qcom,mas-rpm-id = ; + }; + + + slv_bam_dma: slv-bam-dma { + cell-id = ; + label = "slv-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_1: slv-sdcc-1 { + cell-id = ; + label = "slv-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_3: slv-sdcc-3 { + cell-id = ; + label = "slv-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_2: slv-blsp-2 { + cell-id = ; + label = "slv-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_2: slv-sdcc-2 { + cell-id = ; + label = "slv-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_4: slv-sdcc-4 { + cell-id = ; + label = "slv-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_1: slv-blsp-1 { + cell-id = ; + label = "slv-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tsif: slv-tsif { + cell-id = ; + label = "slv-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_usb_hs: slv-usb-hs { + cell-id = ; + label = "slv-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pdm: slv-pdm { + cell-id = ; + label = "slv-pdm"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_prng: slv-prng { + cell-id = ; + label = "slv-prng"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_periph_snoc: slv-periph-snoc { + cell-id = ; + label = "slv-periph-snoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_periph_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* cnoc Devices */ + mas_rpm_inst: mas-rpm-inst { + cell-id = ; + label = "mas-rpm-inst"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_boot_rom>; + qcom,mas-rpm-id = ; + }; + + + mas_rpm_sys: mas-rpm-sys { + cell-id = ; + label = "mas-rpm-sys"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg + &slv_security &slv_tcsr &slv_tlmm &slv_crypto_0_cfg + &slv_crypto_1_cfg &slv_imem_cfg &slv_message_ram + &slv_bimc_cfg &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper + &slv_dehr_cfg &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg + &slv_snoc_cfg &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg + &slv_phy_apu_cfg &slv_ebi1_phy_cfg &slv_pcie_0_cfg + &slv_pcie_1_cfg &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_dehr: mas-dehr { + cell-id = ; + label = "mas-dehr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bimc_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_spdm: mas-spdm { + cell-id = ; + label = "mas-spdm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tic: mas-tic { + cell-id = ; + label = "mas-tic"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_cnoc: mas-snoc-cnoc { + cell-id = ; + label = "mas-snoc-cnoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_dap: mas-qdss-dap { + cell-id = ; + label = "mas-qdss-dap"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + slv_clk_ctl: slv-clk-ctl { + cell-id = ; + label = "slv-clk-ctl"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_2_cfg: slv-crypto-2-cfg { + cell-id = ; + label = "slv-crypto-2-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_security: slv-security { + cell-id = ; + label = "slv-security"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tcsr: slv-tcsr { + cell-id = ; + label = "slv-tcsr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tlmm: slv-tlmm { + cell-id = ; + label = "slv-tlmm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_0_cfg: slv-crypto-0-cfg { + cell-id = ; + label = "slv-crypto-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_1_cfg: slv-crypto-1-cfg { + cell-id = ; + label = "slv-crypto-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_imem_cfg: slv-imem-cfg { + cell-id = ; + label = "slv-imem-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_message_ram: slv-message-ram { + cell-id = ; + label = "slv-message-ram"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_cfg: slv-bimc-cfg { + cell-id = ; + label = "slv-bimc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_boot_rom: slv-boot-rom { + cell-id = ; + label = "slv-boot-rom"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_mmss_cfg: slv-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_mmss_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pmic_arb: slv-pmic-arb { + cell-id = ; + label = "slv-pmic-arb"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spdm_wrapper: slv-spdm-wrapper { + cell-id = ; + label = "slv-spdm-wrapper"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_dehr_cfg: slv-dehr-cfg { + cell-id = ; + label = "slv-dehr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_mpm: slv-mpm { + cell-id = ; + label = "slv-mpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_cfg: slv-qdss-cfg { + cell-id = ; + label = "slv-qdss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_qdss_apu_cfg: slv-rbcpr-qdss-apu-cfg { + cell-id = ; + label = "slv-rbcpr-qdss-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_cfg: slv-rbcpr-cfg { + cell-id = ; + label = "slv-rbcpr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_cfg: slv-cnoc-mnoc-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pnoc_cfg: slv-pnoc-cfg { + cell-id = ; + label = "slv-pnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_pnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cfg: slv-snoc-cfg { + cell-id = ; + label = "slv-snoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_mpu_cfg: slv-snoc-mpu-cfg { + cell-id = ; + label = "slv-snoc-mpu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_dll_cfg: slv-ebi1-dll-cfg { + cell-id = ; + label = "slv-ebi1-dll-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_phy_apu_cfg: slv-phy-apu-cfg { + cell-id = ; + label = "slv-phy-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_phy_cfg: slv-ebi1-phy-cfg { + cell-id = ; + label = "slv-ebi1-phy-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rpm: slv-rpm { + cell-id = ; + label = "slv-rpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0_cfg: slv-pcie-0-cfg { + cell-id = ; + label = "slv-pcie-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1_cfg: slv-pcie-1-cfg { + cell-id = ; + label = "slv-pcie-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spss_geni_ir: slv-spss-geni-ir { + cell-id = ; + label = "slv-spss-geni-ir"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ufs_cfg: slv-ufs-cfg { + cell-id = ; + label = "slv-ufs-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_snoc: slv-cnoc-snoc { + cell-id = ; + label = "slv-cnoc-snoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_snoc>; + qcom,slv-rpm-id = ; + }; + }; + + static-rules { + compatible = "qcom,msm-bus-static-bw-rules"; + + rule0 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <250000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <600000>; + }; + + rule1 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <900000>; + }; + + rule2 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + }; + }; + + devfreq_spdm_cpu { + compatible = "qcom,devfreq_spdm"; + qcom,msm-bus,name = "devfreq_spdm"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 512 0 0>, + <1 512 0 0>; + qcom,msm-bus,active-only; + qcom,spdm-client = <0>; + + clock-names = "cci_clk"; + clocks = <&clock_cpu clk_cci_clk>; + + qcom,bw-upstep = <1000>; + qcom,bw-dwnstep = <1000>; + qcom,max-vote = <10000>; + qcom,up-step-multp = <2>; + qcom,spdm-interval = <100>; + + qcom,ports = <16>; + qcom,alpha-up = <7>; + qcom,alpha-down = <15>; + qcom,bucket-size = <8>; + + /*max pl1 freq, max pl2 freq*/ + qcom,pl-freqs = <140000000 160000000>; + + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,reject-rate = <5000 5000 5000 5000 5000 5000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,response-time-us = <10000 10000 10000 10000 3000 3000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,cci-response-time-us = <10000 10000 10000 10000 1000 1000>; + qcom,max-cci-freq = <600000000>; + }; + + devfreq_spdm_gov { + compatible = "qcom,gov_spdm_hyp"; + interrupt-names = "spdm-irq"; + interrupts = <0 192 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-sensor-mtp.dtsi new file mode 100644 index 0000000000000..f086302c5c958 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-sensor-mtp.dtsi @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + led_flash0: qcom,camera-flash { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-type = <1>; + qcom,flash-source = <&pmi8994_flash0 &pmi8994_flash1>; + qcom,torch-source = <&pmi8994_torch0 &pmi8994_torch1>; + }; +}; + +&cci { +//added by Likelong 2015.3.23 for proximity sensor start + proximity:qcom,proximity@0 { + cell-index = <0>; + reg = <0x29>; + compatible = "stmv,vl6180"; + qcom,cci-master = <0>;//use the same I2C bus with main camera + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.3.23 for proximity sensor end + + actuator0: qcom,actuator@0 { + cell-index = <0>; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + reg = <0x1C>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; +/* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8994_l23>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <100000>; + }; + +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + ois0: qcom,ois@0 { + cell-index = <0>; + reg = <0x1C>; + compatible = "qcom,ois"; + qcom,cci-master = <0>; + /* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + reg = <0x0>; + qcom,eeprom-name = "ov13860"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <7>; + + qcom,page0 = <0 0x0000 2 0x00 1 5>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <47 0x0000 2 0 1 0>; + + qcom,page1 = <0 0x0000 2 0x00 1 5>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0xa0>; + qcom,mem1 = <40 0x0100 2 0 1 0>; + + qcom,page2 = <0 0x0000 2 0x00 1 5>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0xa0>; + qcom,mem2 = <255 0x0200 2 0 1 0>; + + qcom,page3 = <0 0x0000 2 0x00 1 5>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0xa0>; + qcom,mem3 = <255 0x0300 2 0 1 0>; + + qcom,page4 = <0 0x0000 2 0x00 1 5>; + qcom,pageen4 = <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0xa0>; + qcom,mem4 = <255 0x0400 2 0 1 0>; + + qcom,page5 = <0 0x0000 2 0x00 1 5>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0xa0>; + qcom,mem5 = <255 0x0500 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0xa0>; + qcom,mem6 = <89 0x0600 2 0 1 0>; + +/* Kangjian,201/12/18,Add for camera driver */ + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000>; + /*#endif*/ + + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + <&msm_gpio 102 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,cam-power-seq-type = "sensor_gpio", "sensor_vreg", "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "sensor_gpio_standby", "cam_vio", "cam_vana", "cam_vdig", + "sensor_gpio_reset","sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <1 0 0 0 1 24000000 0>; + qcom,cam-power-seq-delay = <0 0 0 0 0 0 0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + +/*muyuezhong@camera,2015-4-29,add for ov5648 OTP functions begin*/ + eeprom1: qcom,eeprom@1 { + cell-index = <2>; + reg = <0x2>; + qcom,eeprom-name = "ov5648"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <1>; + qcom,num-blocks = <26>; + + //read group 1:begin + qcom,page0 = <1 0x0103 2 0x01 1 0>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0x6c>; + qcom,mem0 = <0 0x0000 2 0 1 0>; + + qcom,page1 = <1 0x0100 2 0x01 1 0>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0x6c>; + qcom,mem1 = <0 0x0000 2 0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0x6c>; + qcom,mem2 = <0 0x0000 2 0 1 0>; + + qcom,page3 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0x6c>; + qcom,mem3 = <0 0x0000 2 0 1 0>; + + qcom,page4 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen4= <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0x6c>; + qcom,mem4 = <0 0x0000 2 0 1 0>; + + qcom,page5 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0x6c>; + qcom,mem5 = <0 0x0000 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0x6c>; + qcom,mem6 = <9 0x3d05 2 0 1 0>; + + qcom,page7 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen7 = <16 0x3d00 2 0x00 1 0>; + qcom,poll7 = <0 0x0000 2 0x00 1 5>; + qcom,saddr7 = <0x6c>; + qcom,mem7 = <0 0x0000 2 0 1 0>; + //read group 1:end +/*muyuezhong@camera,2015-8-12,add for other otp group*/ + //read group 2:begin + qcom,page8 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen8 = <0 0x0000 2 0x00 1 5>; + qcom,poll8 = <0 0x0000 2 0x00 1 5>; + qcom,saddr8 = <0x6c>; + qcom,mem8 = <0 0x0000 2 0 1 0>; + + qcom,page9 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen9 = <0 0x0000 2 0x00 1 5>; + qcom,poll9 = <0 0x0000 2 0x00 1 5>; + qcom,saddr9 = <0x6c>; + qcom,mem9 = <0 0x0000 2 0 1 0>; + + qcom,page10 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen10= <0 0x0000 2 0x00 1 5>; + qcom,poll10 = <0 0x0000 2 0x00 1 5>; + qcom,saddr10 = <0x6c>; + qcom,mem10 = <0 0x0000 2 0 1 0>; + + qcom,page11 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen11 = <0 0x0000 2 0x00 1 5>; + qcom,poll11 = <0 0x0000 2 0x00 1 5>; + qcom,saddr11 = <0x6c>; + qcom,mem11 = <0 0x0000 2 0 1 0>; + + qcom,page12 = <0 0x0000 2 0x00 1 5>; + qcom,pageen12 = <0 0x0000 2 0x00 1 5>; + qcom,poll12 = <0 0x0000 2 0x00 1 5>; + qcom,saddr12 = <0x6c>; + qcom,mem12 = <2 0x3d0e 2 0 1 0>; + + qcom,page13 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen13 = <0 0x0000 2 0x00 1 5>; + qcom,poll13 = <0 0x0000 2 0x00 1 5>; + qcom,saddr13 = <0x6c>; + qcom,mem13 = <0 0x0000 2 0 1 0>; + + qcom,page14 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen14 = <0 0x0000 2 0x00 1 5>; + qcom,poll14 = <0 0x0000 2 0x00 1 5>; + qcom,saddr14 = <0x6c>; + qcom,mem14 = <0 0x0000 2 0 1 0>; + + qcom,page15 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen15= <0 0x0000 2 0x00 1 5>; + qcom,poll15 = <0 0x0000 2 0x00 1 5>; + qcom,saddr15 = <0x6c>; + qcom,mem15 = <0 0x0000 2 0 1 0>; + + qcom,page16 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen16 = <0 0x0000 2 0x00 1 5>; + qcom,poll16 = <0 0x0000 2 0x00 1 5>; + qcom,saddr16 = <0x6c>; + qcom,mem16 = <0 0x0000 2 0 1 0>; + + qcom,page17 = <0 0x0000 2 0x00 1 5>; + qcom,pageen17 = <0 0x0000 2 0x00 1 5>; + qcom,poll17 = <0 0x0000 2 0x00 1 5>; + qcom,saddr17 = <0x6c>; + qcom,mem17 = <7 0x3d00 2 0 1 0>; + + qcom,page18 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen18 = <16 0x3d00 2 0x00 1 0>; + qcom,poll18 = <0 0x0000 2 0x00 1 5>; + qcom,saddr18 = <0x6c>; + qcom,mem18 = <0 0x0000 2 0 1 0>; + //read group 2:end + + //read group 3:begin + qcom,page19 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen19 = <0 0x0000 2 0x00 1 5>; + qcom,poll19 = <0 0x0000 2 0x00 1 5>; + qcom,saddr19 = <0x6c>; + qcom,mem19 = <0 0x0000 2 0 1 0>; + + qcom,page20 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen20 = <0 0x0000 2 0x00 1 5>; + qcom,poll20 = <0 0x0000 2 0x00 1 5>; + qcom,saddr20 = <0x6c>; + qcom,mem20 = <0 0x0000 2 0 1 0>; + + qcom,page21 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen21= <0 0x0000 2 0x00 1 5>; + qcom,poll21 = <0 0x0000 2 0x00 1 5>; + qcom,saddr21 = <0x6c>; + qcom,mem21 = <0 0x0000 2 0 1 0>; + + qcom,page22 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen22 = <0 0x0000 2 0x00 1 5>; + qcom,poll22 = <0 0x0000 2 0x00 1 5>; + qcom,saddr22 = <0x6c>; + qcom,mem22 = <0 0x0000 2 0 1 0>; + + qcom,page23 = <0 0x0000 2 0x00 1 5>; + qcom,pageen23 = <0 0x0000 2 0x00 1 5>; + qcom,poll23 = <0 0x0000 2 0x00 1 5>; + qcom,saddr23 = <0x6c>; + qcom,mem23 = <9 0x3d07 2 0 1 0>; + + qcom,page24 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen24 = <16 0x3d00 2 0x00 1 0>; + qcom,poll24 = <0 0x0000 2 0x00 1 5>; + qcom,saddr24 = <0x6c>; + qcom,mem24 = <0 0x0000 2 0 1 0>; + + qcom,page25 = <1 0x0100 2 0x00 1 0>; + qcom,pageen25 = <0 0x0000 2 0x00 1 5>; + qcom,poll25 = <0 0x0000 2 0x00 1 5>; + qcom,saddr25 = <0x6c>; + qcom,mem25= <0 0x0000 2 0 1 0>; + //read group 3:end + + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2","CAM_RESET2","CAM_STANDBY2"; + + qcom,cam-power-seq-type = "sensor_vreg","sensor_vreg", "sensor_gpio", "sensor_gpio", + "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "cam_vio","cam_vana", "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 24000000 0>; + qcom,cam-power-seq-delay = <0 5 0 0 0 0>; + + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>,<&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* muyuezhong@camera,2015-4-29,add for ov5648 OTP functions end*/ + +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ +/* + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <2>; + qcom,eeprom-name = "onsemi_cat24c32"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <2245 0x00 2 0 1 0>; + + cam_vio-supply = <&pm8994_lvs1>; + qcom,cam-vreg-name = "cam_vio"; + qcom,cam-vreg-min-voltage = <0>; + qcom,cam-vreg-max-voltage = <0>; + qcom,cam-vreg-op-mode = <0>; + qcom,cam-power-seq-type = "sensor_vreg"; + qcom,cam-power-seq-val = "cam_vio"; + qcom,cam-power-seq-cfg-val = <1>; + qcom,cam-power-seq-delay = <1>; + status = "ok"; + }; +*/ +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom0>; + qcom,actuator-src = <&actuator0>; +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + qcom,ois-src = <&ois0>; + qcom,led-flash-src = <&led_flash0>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + cam_v_custom1-supply = <&pm8994_l29>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_v_custom1"; + /*liuyan 2015/7/20, change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000 2800000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000 2800000>; + /*#endif*/ + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, + <&msm_gpio 102 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vaf = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0 >; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VAF0"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 0 2700000>; + qcom,cam-vreg-max-voltage = <1200000 0 2700000>; + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend &cam_sensor_rear2_suspend>; + gpios = <&msm_gpio 14 0>, + <&msm_gpio 94 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_STANDBY1"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +*/ + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom1>; + //qcom,actuator-src = <&actuator1>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; +/* Kangjian,2014/12/18,Add end */ diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v1.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v1.dtsi new file mode 100755 index 0000000000000..b1c810d391efe --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v1.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v2.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v2.dtsi new file mode 100755 index 0000000000000..b101e98dde0dd --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera-v2.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-camera.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera.dtsi new file mode 100755 index 0000000000000..03e578bcf4121 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-camera.dtsi @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,msm-cam@fd8c0000 { + compatible = "qcom,msm-cam"; + reg = <0xfd8c0000 0x10000>; + reg-names = "msm-cam"; + }; + + qcom,csiphy@fda0ac00 { + cell-index = <0>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0ac00 0x200>, + <0xfda00030 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 78 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0phy_clk>, + <&clock_mmss clk_csi0phytimer_clk_src>, + <&clock_mmss clk_camss_phy0_csi0phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b000 { + cell-index = <1>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b000 0x200>, + <0xfda00038 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 79 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1phy_clk>, + <&clock_mmss clk_csi1phytimer_clk_src>, + <&clock_mmss clk_camss_phy1_csi1phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b400 { + cell-index = <2>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b400 0x200>, + <0xfda00040 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 80 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2phy_clk>, + <&clock_mmss clk_csi2phytimer_clk_src>, + <&clock_mmss clk_camss_phy2_csi2phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csid@fda08000 { + cell-index = <0>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08000 0x400>; + reg-names = "csid"; + interrupts = <0 51 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0_ahb_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08400 { + cell-index = <1>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08400 0x400>; + reg-names = "csid"; + interrupts = <0 52 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1_ahb_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08800 { + cell-index = <2>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08800 0x400>; + reg-names = "csid"; + interrupts = <0 53 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2_ahb_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08c00 { + cell-index = <3>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08C00 0x100>; + reg-names = "csid"; + interrupts = <0 54 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3_ahb_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,ispif@fda0a000 { + cell-index = <0>; + compatible = "qcom,ispif-v3.0", "qcom,ispif"; + reg = <0xfda0A000 0x500>, + <0xfda00020 0x10>; + reg-names = "ispif", "csi_clk_mux"; + interrupts = <0 55 0>; + interrupt-names = "ispif"; + qcom,num-isps = <0x2>; + vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>; + clock-names = "ispif_ahb_clk", + "csi0_src_clk", "csi0_clk", + "csi0_pix_clk", "csi0_rdi_clk", + "csi1_src_clk", "csi1_clk", + "csi1_pix_clk", "csi1_rdi_clk", + "csi2_src_clk", "csi2_clk", + "csi2_pix_clk", "csi2_rdi_clk", + "csi3_src_clk", "csi3_clk", + "csi3_pix_clk", "csi3_rdi_clk", + "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk", + "vfe1_clk_src", "camss_vfe_vfe1_clk", "camss_csi_vfe1_clk"; + qcom,clock-rates = "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "-2", "0", "0", + "-2", "0", "0"; + }; + + vfe0: qcom,vfe@fda10000 { + cell-index = <0>; + compatible = "qcom,vfe46"; + reg = <0xfda10000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 57 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + + }; + + vfe1: qcom,vfe@fda14000 { + cell-index = <1>; + compatible = "qcom,vfe46"; + reg = <0xfda14000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 58 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + }; + + + qcom,jpeg@fda1c000 { + cell-index = <0>; + compatible = "qcom,jpeg"; + reg = <0xfda1c000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 59 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", + "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda20000 { + cell-index = <1>; + compatible = "qcom,jpeg"; + reg = <0xfda20000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 60 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda24000 { + cell-index = <2>; + compatible = "qcom,jpeg"; + reg = <0xfda24000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 61 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg2_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + qcom,jpeg@fdaa0000 { + cell-index = <3>; + compatible = "qcom,jpeg_dma"; + reg = <0xfdaa0000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 304 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_dma_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + + qcom,irqrouter@fda00000 { + cell-index = <0>; + compatible = "qcom,irqrouter"; + reg = <0xfda00000 0x100>; + reg-names = "irqrouter"; + }; + + qcom,cpp@fda04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xfda04000 0x100>, + <0xfda80000 0x200>, + <0xfda18000 0x008>; + reg-names = "cpp", "cpp_vbif", "cpp_hw"; + interrupts = <0 49 0>; + interrupt-names = "cpp"; + vdd-supply = <&gdsc_cpp>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cpp_core_clk", + "camss_vfe_cpp_ahb_clk", "camss_vfe_cpp_axi_clk", + "camss_vfe_cpp_clk","micro_iface_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 465000000 0 0 465000000 0 0>; + qcom,min-clock-rate = <320000000>; + }; + + qcom,fd@fd878000 { + cell-index = <0>; + compatible = "qcom,face-detection"; + reg = <0xfd878000 0x800>, + <0xfd87c000 0x800>, + <0xfd860000 0x1000>; + reg-names = "fd_core", "fd_misc", "fd_vbif"; + interrupts = <0 316 0>; + interrupt-names = "fd"; + vdd-supply = <&gdsc_fd>; + clocks = <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>, + <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>; + clock-names = "fd_core_clk", "fd_core_uar_clk", + "fd_axi_clk", "fd_ahb_clk"; + clock-rates = <60000000 60000000 75000000 40000000>, + <200000000 200000000 150000000 40000000>, + <400000000 400000000 333000000 80000000>; + }; + + cci: qcom,cci@fda0c000 { + cell-index = <0>; + compatible = "qcom,cci"; + reg = <0xfda0c000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "cci"; + interrupts = <0 50 0>; + interrupt-names = "cci"; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cci_clk_src>, + <&clock_mmss clk_camss_cci_cci_ahb_clk>, + <&clock_mmss clk_camss_cci_cci_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cci_src_clk", + "cci_ahb_clk", "camss_cci_clk", + "camss_ahb_clk"; + qcom,clock-rates = <0 19200000 0 0 0>, + <0 37500000 0 0 0>; + pinctrl-names = "cci_default", "cci_suspend"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + gpios = <&msm_gpio 17 0>, + <&msm_gpio 18 0>, + <&msm_gpio 19 0>, + <&msm_gpio 20 0>; + qcom,gpio-tbl-num = <0 1 2 3>; + qcom,gpio-tbl-flags = <1 1 1 1>; + qcom,gpio-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + i2c_freq_100Khz: qcom,i2c_standard_mode { + status = "disabled"; + }; + i2c_freq_400Khz: qcom,i2c_fast_mode { + status = "disabled"; + }; + i2c_freq_custom: qcom,i2c_custom_mode { + status = "disabled"; + }; + + i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { + status = "disabled"; + }; + + }; +}; + +&i2c_freq_100Khz { + qcom,hw-thigh = <104>; + qcom,hw-tlow = <88>; + qcom,hw-tsu-sto = <105>; + qcom,hw-tsu-sta = <119>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <84>; + qcom,hw-tbuf = <116>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_400Khz { + qcom,hw-thigh = <20>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <32>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_custom { + qcom,hw-thigh = <15>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <25>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_1Mhz { + qcom,hw-thigh = <16>; + qcom,hw-tlow = <22>; + qcom,hw-tsu-sto = <17>; + qcom,hw-tsu-sta = <18>; + qcom,hw-thd-dat = <16>; + qcom,hw-thd-sta = <15>; + qcom,hw-tbuf = <19>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <3>; + qcom,hw-tsp = <3>; + qcom,cci-clk-src = <37500000>; + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v1.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v1.dtsi new file mode 100755 index 0000000000000..b6ad994e6ae35 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v1.dtsi @@ -0,0 +1,774 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <9>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <10>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <11>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <12>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <18>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <19>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <20>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <21>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <22>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <23>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <24>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <25>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <44>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <45>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v2.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v2.dtsi new file mode 100755 index 0000000000000..681adbaf1c818 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-coresight-v2.dtsi @@ -0,0 +1,829 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + qcom,sg-enable; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss1: funnel@fbb70000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb70000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss1"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <0>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <9>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpda_lmh: tpda@fbb91000 { + compatible = "qcom,coresight-tpda"; + reg = <0xfbb91000 0x1000>; + reg-names = "tpda-base"; + + coresight-id = <10>; + coresight-name = "coresight-tpda-lmh"; + coresight-nr-inports = <32>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <3>; + + qcom,tpda-atid = <64>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpdm_lmh: tpdm@fbb90000 { + compatible = "qcom,coresight-tpdm"; + reg = <0xfbb90000 0x1000>; + reg-names = "tpdm-base"; + + coresight-id = <11>; + coresight-name = "coresight-tpdm-lmh"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&tpda_lmh>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <12>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <18>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <19>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <20>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <21>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <22>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <23>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <24>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <25>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <44>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <45>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <46>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <47>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <48>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-gpu.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-gpu.dtsi new file mode 100755 index 0000000000000..3d63cf8d2076c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-gpu.dtsi @@ -0,0 +1,181 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + msm_bus: qcom,kgsl-busmon{ + label = "kgsl-busmon"; + compatible = "qcom,kgsl-busmon"; + }; + + gpubw: qcom,gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,gpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc390000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <2>; + qcom,target-dev = <&gpubw>; + }; + + msm_gpu: qcom,kgsl-3d0@fdb00000 { + label = "kgsl-3d0"; + compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d"; + reg = <0xfdb00000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 33 0>; + interrupt-names = "kgsl_3d0_irq"; + qcom,id = <0>; + + qcom,chipid = <0x04030000>; + + qcom,initial-pwrlevel = <2>; + + qcom,idle-timeout = <8>; // + qcom,strtstp-sleepwake; + + qcom,pm-qos-active-latency = <501>; + qcom,pm-qos-wakeup-latency = <101>; + + /* + * Clocks = KGSL_CLK_CORE | KGSL_CLK_IFACE + * KGSL_CLK_RBBMTIMER + */ + qcom,clk-map = <0x00000086>; + + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>, + <&clock_mmss clk_oxili_rbbmtimer_clk>; + clock-names = "core_clk", "iface_clk", "rbbmtimer_clk"; + + /* Bus Scale Settings */ + qcom,gpubw-dev = <&gpubw>; + qcom,bus-control; + /* + * qcom,msm-bus structures below define + * GPU msm client and its vote data for + * each of available power levels + * (gpu-bus frequency combination) + */ + qcom,msm-bus,name = "grp3d"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1200000>, /* 1 bus=150 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3200000>, /* 3 bus=460 */ + <26 512 0 4224000>, /* 4 bus=533 */ + <26 512 0 5376000>, /* 5 bus=672 */ + <26 512 0 6681600>, /* 6 bus=777 */ + <26 512 0 8448000>, /* 7 bus=1036 */ + <26 512 0 12748800>; /* 8 bus=1555 */ + + /* GDSC oxili regulators */ + vddcx-supply = <&gdsc_oxili_cx>; + vdd-supply = <&gdsc_oxili_gx>; + + /* IOMMU Data */ + iommu = <&kgsl_iommu>; + + /* Trace bus */ + coresight-id = <67>; + coresight-name = "coresight-gfx"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <4>; + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <400000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <300000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <2>; + qcom,bus-max = <5>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <150000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <27000000>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + qcom,bus-freq = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <5>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu=600 */ + <89 662 0 6400000>, /* gpu=400 */ + <89 662 0 4800000>, /* gpu=300 */ + <89 662 0 2400000>, /* gpu=150 */ + <89 662 0 0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu-domains.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu-domains.dtsi new file mode 100755 index 0000000000000..840818c2d7cb3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu-domains.dtsi @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,iommu-domains { + compatible = "qcom,iommu-domains"; + + venus_domain_ns: qcom,iommu-domain1 { + label = "venus_ns"; + qcom,iommu-contexts = <&venus_ns>; + qcom,virtual-addr-pool = <0x5dc00000 0x7f000000 + 0xdcc00000 0x1000000>; + }; + + venus_domain_sec_bitstream: qcom,iommu-domain2 { + label = "venus_sec_bitstream"; + qcom,iommu-contexts = <&venus_sec_bitstream>; + qcom,virtual-addr-pool = <0x4b000000 0x12c00000>; + qcom,secure-domain; + }; + + venus_domain_sec_pixel: qcom,iommu-domain3 { + label = "venus_sec_pixel"; + qcom,iommu-contexts = <&venus_sec_pixel>; + qcom,virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-domain; + }; + + venus_domain_sec_non_pixel: qcom,iommu-domain4 { + label = "venus_sec_non_pixel"; + qcom,iommu-contexts = <&venus_sec_non_pixel>; + qcom,virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-domain; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu.dtsi new file mode 100755 index 0000000000000..0638ffc0a6b3c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-iommu.dtsi @@ -0,0 +1,430 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm-iommu-v1.dtsi" + +&soc { + mdp_iommu_8994: qcom,iommu@fd9cc000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd9cc000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + status = "ok"; + vdd-supply = <&gdsc_mdss>; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018>; + + qcom,iommu-bfb-data = <0x3 + 0x7fffff + 0x1777 + 0x0 + 0x4 + 0x10 + 0x5000 + 0x182c1 + 0x5a1d + 0x1822d + 0x0 + 0x0 + 0x28 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd9d4000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d4000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd9d5000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d5000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd9d6000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d6000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; +}; + +&venus_iommu { + status = "ok"; + vdd-supply = <&gdsc_venus>; + clocks = <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c>; + + qcom,iommu-bfb-data = <0x3 + 0x7ffffff + 0x1555 + 0x0 + 0x4 + 0x8 + 0x13607 + 0x140a0 + 0x4000 + 0x14020 + 0x0 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + qcom,iommu-ctx-sids = <0x00 0x21 0x45 0x47 0x48 0x49 0x4a + 0x4b 0x4c 0x65 0x67 0x69 0x6a 0x6b>; + qcom,iommu-sid-mask = <0x0 0xf 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 { + qcom,iommu-ctx-sids = <0x400 0x421 0x422 0x423 0x424 0x448 + 0x44a 0x46a>; + label = "venus_sec_bitstream"; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + qcom,iommu-ctx-sids = <0x600 0x606>; + }; + + venus_sec_pixel: qcom,iommu-ctx@fdc8f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8f000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x425 0x428 0x445 0x44c 0x465>; + label = "venus_sec_pixel"; + qcom,secure-context; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc90000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x427 0x447 0x449 0x44b 0x467 0x469 0x46b + 0x500>; + label = "venus_sec_non_pixel"; + qcom,secure-context; + }; +}; + +&jpeg_iommu { + status = "ok"; + vdd-supply = <&gdsc_jpeg>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0x3ffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2000 + 0xe673 + 0x2c00 + 0xe616 + 0x0 + 0x0 + 0x10 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6f000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <3>; + label = "jpeg_dma"; + }; +}; + +&kgsl_iommu { + status = "ok"; + vdd-supply = <&gdsc_oxili_cx>; + qcom,alt-vdd-supply = <&gdsc_oxili_gx>; + qcom,iommu-secure-id = <18>; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x2600 + 0x2604 + 0x2608 + 0x260c + 0x2610 + 0x2614 + 0x2618 + 0x261c + 0x2620 + 0x2624 + 0x2628 + 0x262c>; + + qcom,iommu-bfb-data = <0x3 + 0x3 + 0x1555 + 0x0 + 0x0 + 0x10 + 0x0 + 0x120 + 0x120 + 0x10 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x7 + 0x0 + 0x20 + 0x20 + 0x0c + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x10>; + + qcom,iommu-ctx@fdb18000 { + qcom,iommu-ctx-sids = <0 1>; + }; + + qcom,iommu-ctx@fdb19000 { + qcom,iommu-ctx-sids = <>; + }; + + qcom,iommu-ctx@fdb1a000 { + qcom,iommu-ctx-sids = <2>; + interrupts = <0 241 0>, <0 240 0>; + qcom,secure-context; + linux,contiguous-region = <&secure_mem>; + }; +}; + +&vfe_iommu { + status = "ok"; + vdd-supply = <&gdsc_vfe>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0xfffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2400 + 0x8844 + 0x2400 + 0x8812 + 0x0 + 0x0 + 0x12 + 0x5a + 0x0 + 0x0 + 0x0 + 0x0>; +}; + +&fd_iommu { + status = "ok"; + vdd-supply = <&gdsc_fd>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>, + <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk", "alt_iface_clk"; +}; + +&cpp_iommu { + status = "ok"; + vdd-supply = <&gdsc_cpp>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-ion.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-ion.dtsi new file mode 100755 index 0000000000000..16b920e069108 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-ion.dtsi @@ -0,0 +1,63 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ion { + compatible = "qcom,msm-ion"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,ion-heap@25 { + reg = <25>; + qcom,ion-heap-type = "SYSTEM"; + }; + + qcom,ion-heap@21 { + reg = <21>; + qcom,ion-heap-type = "SYSTEM_CONTIG"; + }; + + qcom,ion-heap@8 { /* CP_MM HEAP */ + compatible = "qcom,msm-ion-reserve"; + reg = <8>; + qcom,heap-align = <0x1000>; + linux,contiguous-region = <&secure_mem>; + qcom,ion-heap-type = "SECURE_DMA"; + qcom,default-prefetch-size = <0x6c00000>; + }; + + qcom,ion-heap@22 { /* adsp heap */ + reg = <22>; + linux,contiguous-region = <&adsp_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@27 { /* QSECOM HEAP */ + reg = <27>; + linux,contiguous-region = <&qsecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@28 { /* AUDIO HEAP */ + reg = <28>; + linux,contiguous-region = <&audio_mem>; + qcom,ion-heap-type = "DMA"; + }; + + adsp_venus_heap: qcom,ion-heap@23 { + compatible = "qcom,msm-ion-reserve"; + reg = <23>; + linux,contiguous-region = <&peripheral_mem>; + qcom,ion-heap-type = "DMA"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-ipcrouter.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-ipcrouter.dtsi new file mode 100755 index 0000000000000..006bd32eb5957 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-ipcrouter.dtsi @@ -0,0 +1,37 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ipc_router { + compatible = "qcom,ipc_router"; + qcom,node-id = <1>; + }; + + qcom,ipc_router_modem_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "modem"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + qcom,disable-pil-loading; + }; + + qcom,ipc_router_q6_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "adsp"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss-pll.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss-pll.dtsi new file mode 100755 index 0000000000000..a6cd3a43e5a65 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss-pll.dtsi @@ -0,0 +1,171 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@fd998300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xfd998300 0x500>, + <0xfd8c2300 0x8>, + <0xfd998200 0x64>, + <0xfd9a0300 0x500>; + reg-names = "pll_base", "gdsc_base", "dynamic_pll_base", + "pll_1_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-en-pll-90-phase; + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + /* Dynamic FPS data region */ + linux,contiguous-region = <&dfps_data_mem>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + mdss_dsi1_pll: qcom,mdss_dsi_pll@fd9a0300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xfd9a0300 0x500>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + + mdss_hdmi_pll: qcom,mdss_hdmi_pll@0xfd9a8600 { + compatible = "qcom,mdss_hdmi_pll_8994"; + label = "MDSS HDMI PLL"; + #clock-cells = <1>; + + reg = <0xfd9a8600 0xac4>, + <0xfd9a9200 0x0C8>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "phy_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss.dtsi new file mode 100755 index 0000000000000..269101b45a411 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-mdss.dtsi @@ -0,0 +1,508 @@ +/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_mdp: qcom,mdss_mdp@fd900000 { + compatible = "qcom,mdss_mdp"; + reg = <0xfd900000 0x90000>, + <0xfd9c8000 0x004d4>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-ib-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2048>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,mdss-vbif-qos-nrt-setting = <1 1 1 1>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <7300000>; + qcom,max-bandwidth-high-kbps = <7300000>; + qcom,max-bandwidth-per-pipe-kbps = <1800000>; + qcom,max-clk-rate = <400000000>; + qcom,mdss-dram-channels = <2>; + qcom,mdss-default-ot-wr-limit = <16>; + qcom,mdss-default-ot-rd-limit = <16>; + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000 + 0x00009000 0x0000B000>; + qcom,mdss-pipe-rgb-off = <0x00015000 0x00017000 + 0x00019000 0x0001B000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000>; + qcom,mdss-pipe-cursor-off = <0x00035000 0x00037000>; + + qcom,mdss-pipe-vig-fetch-id = <1 4 7 19>; + qcom,mdss-pipe-rgb-fetch-id = <16 17 18 22>; + qcom,mdss-pipe-dma-fetch-id = <10 13>; + + qcom,mdss-pipe-vig-xin-id = <0 4 8 12>; + qcom,mdss-pipe-rgb-xin-id = <1 5 9 13>; + qcom,mdss-pipe-dma-xin-id = <2 10>; + qcom,mdss-pipe-cursor-xin-id = <7 7>; + + qcom,mdss-en-svs-high; + qcom,mdss-has-panic-ctrl; + qcom,mdss-pipe-vig-panic-ctrl-offsets = <0 1 2 3>; + qcom,mdss-pipe-rgb-panic-ctrl-offsets = <4 5 6 7>; + qcom,mdss-pipe-dma-panic-ctrl-offsets = <8 9>; + + qcom,mdss-pipe-rgb-fixed-mmb = <5 0 1 8 9 10>, + <5 2 3 11 12 13>, + <5 4 5 14 15 16>, + <5 6 7 17 18 19>; + qcom,mdss-pipe-vig-fixed-mmb = <1 20>, + <1 21>, + <1 22>, + <1 23>; + + /* These Offsets are relative to "mdp_phys + mdp-reg-offset" address */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2AC 0 0>, + <0x2B4 0 0>, + <0x2BC 0 0>, + <0x2C4 0 0>; + qcom,mdss-pipe-rgb-clk-ctrl-offsets = <0x2AC 4 8>, + <0x2B4 4 8>, + <0x2BC 4 8>, + <0x2C4 4 8>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2AC 8 12>, + <0x2B4 8 12>; + + qcom,mdss-pipe-sw-reset-off = <0x0028>; + qcom,mdss-pipe-vig-sw-reset-map = <5 6 7 8>; + qcom,mdss-pipe-rgb-sw-reset-map = <9 10 11 12>; + qcom,mdss-pipe-dma-sw-reset-map = <13 14>; + + qcom,mdss-smp-data = <44 8192>; + qcom,mdss-sspp-len = <0x00002000>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004A000>; + qcom,mdss-mixer-wb-off = <0x00048000 0x00049000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000 0x00059000 + 0x0005B000>; + qcom,mdss-wb-off = <0x00065000 0x00065800 0x00066000 + 0x00066800 0x00067000>; + qcom,mdss-intf-off = <0x0006B000 0x0006B800 0x0006C000 + 0x0006C800 0x0006D000>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 0x00072000 + 0x00072800>; + qcom,mdss-ad-off = <0x0079000 0x00079800 0x0007A000>; + qcom,mdss-highest-bank-bit = <0x3>; + qcom,mdss-has-decimation; + qcom,mdss-has-rotator-downscale; + qcom,mdss-has-bwc; + + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + + qcom,mdss-ctl-len = <0x00000200>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdp_clk_src>, + <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_vsync_clk>; + clock-names = "iface_clk", "bus_clk", "core_clk_src", + "core_clk", "vsync_clk"; + + /* These Offsets are relative to "mdp_phys" address */ + qcom,mdp-settings = <0x0117c 0x00005555>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; + + qcom,regs-dump-mdp = <0x01000 0x01408>, + <0x02000 0x02064>, + <0x02200 0x02264>, + <0x02400 0x02464>, + <0x02600 0x02664>, + <0x02800 0x02864>, + <0x05000 0x05130>, + <0x05200 0x05230>, + <0x07000 0x07130>, + <0x07200 0x07230>, + <0x09000 0x09130>, + <0x09200 0x09230>, + <0x0b000 0x0b130>, + <0x0b200 0x0b230>, + <0x15000 0x15130>, + <0x15200 0x15230>, + <0x17000 0x17130>, + <0x17200 0x17230>, + <0x19000 0x19130>, + <0x19200 0x19230>, + <0x1b000 0x1b130>, + <0x1b200 0x1b230>, + <0x25000 0x2512C>, + <0x27000 0x2712C>, + <0x45000 0x4538c>, + <0x46000 0x4638c>, + <0x47000 0x4738c>, + <0x48000 0x4838c>, + <0x49000 0x4938c>, + <0x4a000 0x4a38c>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x59000 0x5922c>, + <0x5b000 0x5b22c>, + <0x65000 0x652b4>, + <0x65800 0x65ab4>, + <0x66000 0x662b4>, + <0x66800 0x66ab4>, + <0x67000 0x672b4>, + <0x6b800 0x6ba54>, + <0x6c000 0x6c254>, + <0x6c800 0x6ca54>, + <0x71000 0x710d0>, + <0x71800 0x718d0>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "VIG2_SSPP", "VIG2", "VIG3_SSPP", "VIG3", + "RGB0_SSPP", "RGB0", "RGB1_SSPP", "RGB1", + "RGB2_SSPP", "RGB2", "RGB3_SSPP", "RGB3", + "DMA0_SSPP", "DMA1_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_3", "LAYER_4", "LAYER_5", + "DSPP_0", "DSPP_1", "DSPP_2", "DSPP_3", + "WB_0", "WB_1", "WB_2", "WB_3", "WB_4", + "INTF_1", "INTF_2", "INTF_3", + "PP_0", "PP_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <2048>; + qcom,mdss-prefill-y-buffer-bytes = <4096>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2048>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + qcom,mdss-prefill-fbc-lines = <2>; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + qcom,cont-splash-memory { + linux,contiguous-region = <&cont_splash_mem>; + }; + }; + + mdss_fb1: qcom,mdss_fb_external { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_wfd { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + }; + }; + + mdss_dsi0: qcom,mdss_dsi@fd998000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xfd998000 0x260>, + <0xfd998500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte0_clk>, + <&clock_mmss clk_mdss_pclk0_clk>, + <&clock_mmss clk_mdss_esc0_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", "byte_clk_src", + "pixel_clk_src", "shadow_byte_clk_src", + "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + mdss_dsi1: qcom,mdss_dsi@fd9a0000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xfd9a0000 0x260>, + <0xfd9a0500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte1_clk>, + <&clock_mmss clk_mdss_pclk1_clk>, + <&clock_mmss clk_mdss_esc1_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", + "byte_clk_src", "pixel_clk_src", + "shadow_byte_clk_src", "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <1920 1080>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb2>; + }; + + mdss_hdmi_tx: qcom,hdmi_tx@fd9a8000{ + cell-index = <0>; + compatible = "qcom,hdmi-tx"; + + reg = <0xfd9a8000 0x38C>, + <0xfc4b8000 0x6fff>; + reg-names = "core_physical", "qfprom_physical"; + + hpd-gdsc-supply = <&gdsc_mdss>; + core-vdda-supply = <&pm8994_l12>; + core-vcc-supply = <&pm8994_s4>; + + qcom,supply-names = "hpd-gdsc", "core-vdda", "core-vcc"; + qcom,min-voltage-level = <0 1800000 1800000>; + qcom,max-voltage-level = <0 1800000 1800000>; + qcom,enable-load = <0 300000 0>; + qcom,disable-load = <0 0 0>; + + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_hdmi_clk>, + <&clock_mmss clk_mdss_hdmi_ahb_clk>, + <&clock_mmss clk_mdss_extpclk_clk>; + clock-names = "mdp_core_clk", "iface_clk", + "core_clk", "alt_iface_clk", "extp_clk"; + + qcom,hdmi-tx-hpd = <&pm8994_mpps 4 0>; + qcom,mdss-fb-map = <&mdss_fb1>; + + hdmi_audio: qcom,msm-hdmi-audio-rx { + compatible = "qcom,msm-hdmi-audio-codec-rx"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-mtp.dtsi new file mode 100755 index 0000000000000..d43d6374a2e6a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-mtp.dtsi @@ -0,0 +1,1064 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8994-pinctrl.dtsi" +#include "msm8994-camera-sensor-mtp.dtsi" +#include "dsi-panel-jd35695-1080p-cmd.dtsi" +#include "dsi-panel-jdi-1080p-video.dtsi" + +/ { + bt_qca6174 { + compatible = "qca,qca6174"; + qca,bt-reset-gpio = <&pm8994_gpios 19 0>; /* BT_EN */ + qca,bt-vdd-pa-supply = <&bt_vreg>; + qca,bt-vdd-io-supply = <&pm8994_s4>; + qca,bt-vdd-xtal-supply = <&pm8994_l30>; + qca,bt-vdd-io-voltage-level = <1800000 1800000>; + qca,bt-vdd-xtal-voltage-level = <1800000 1800000>; + }; +}; + +&sdhc_1 { + vdd-supply = <&pm8994_l20>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + vdd-io-supply = <&pm8994_s4>; + qcom,vdd-io-always-on; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,nonremovable; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &pm8994_gpios 8 0x3>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&pm8994_gpios 8 0x1>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + status = "ok"; +}; + +&ufsphy1 { + status = "ok"; +}; + +&ufs1 { + status = "ok"; +}; + +&pm8994_vadc { + chan@5 { + label = "vcoin"; + reg = <5>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@7 { + label = "vph_pwr"; + reg = <7>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm8994_adc_tm { + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x48>; + qcom,thermal-node; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x68>; + qcom,thermal-node; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x70>; + qcom,thermal-node; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x78>; + qcom,thermal-node; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x80>; + qcom,thermal-node; + }; +}; + +&pmi8994_vadc { + chan@0 { + label = "usbin"; + reg = <0>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@1 { + label = "dcin"; + reg = <1>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@43 { + label = "usb_dp"; + reg = <0x43>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@44 { + label = "usb_dm"; + reg = <0x44>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; +}; + + +/**********************************************************************/ +//zhiming.guo@MM.lcddriver add for lcd driver 2015-01-31 + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&pmx_mdss { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 78>; +}; + + +&labibb { + status = "ok"; + qpnp,qpnp-labibb-mode = "lcd"; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 10>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jd35695_1080_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + //qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + qcom,platform-esd-te-gpio = <&msm_gpio 108 0>;//gzm@oem add 2015-03-28 add + qcom,lcd-poweron-en-gpio = <&pmi8994_gpios 7 0>; + qcom,lcd-poweron-en-n-gpio = <&pmi8994_gpios 3 0>; + qcom,lm3630-bklight-en-gpio = <&pmi8994_gpios 2 0>; + qcom,use_external_ic_power; +}; +&dsi_jd35695_1080_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + +/* + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + +}; +*/ +&dsi_jdi_1080_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + + +/******************************************************************/ + + + +&soc { + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, delete it : synaptics@20.*/ + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, add for tp:synaptics */ + i2c@f9924000 { + synaptics-rmi-ts@20 { + compatible = "synaptics,s3320"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x8>; + synaptics,irq-gpio = <&msm_gpio 96 0x08>; + //synaptics,wakeup-gpio = <&msm_gpio 39 0x00>; + synaptics,reset-gpio = <&msm_gpio 31 0x00>; + //synaptics,id-gpio = <&msm_gpio 38 0x00>; + //synaptics,id3-gpio = <&msm_gpio 39 0x00>; + vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_l14>; + }; + }; +//#ifdef VENDOR_EDIT /* modify for fpc1021 fingerprints*/ + spi@f9968000 { + fpc_fpc1020@0 { //Slave driver and CS ID + compatible = "fpc,fpc1020"; //Manufacture, and Model + reg = <0>; //Same as CS ID + spi-max-frequency = <19200000>; //Max Frequency for Device + #spi-cs-high; //CS Active High + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <90 0>; //GPIO # and flags + fpc,gpio_irq = <&msm_gpio 90 0x00>; //Pass a GPIO + fpc,gpio_reset = <&msm_gpio 89 0x00>; + fpc,gpio_vendor = <&msm_gpio 91 0x00>; + #fpc,gpio_envdd = <&msm_gpio 16 0x00>; + fpc,vddtx_mv; + #fpc,txout_boost_enable; + #spi-cpol; //CPOL bit set for SPI polarity + #spi-cpha; //CPHA bit set for SPI Phase + vdd_io-supply = <&pm8994_s4>; // 1.8V + vdd_ana-supply = <&pm8994_l18>; // 3.3V N3 use gpio16 for enable_pin to controll 3.3V(boost) + fpc,gpio_envdd = <&msm_gpio 41 0x00>; + }; + }; +//#endif/*VENDOR_EDIT*/ + + gen-vkeys { + compatible = "qcom,gen-vkeys"; + label = "synaptics_dsx"; + qcom,disp-maxx = <1599>; + qcom,disp-maxy = <2559>; + qcom,panel-maxx = <1599>; + qcom,panel-maxy = <2703>; + qcom,key-codes = <158 139 102 217>; + }; + + i2c@f9928000 { /* BLSP1 QUP6 */ + status = "ok"; +//#ifdef VENDOR_EDIT +//added by Likelong 2015.5.15 for proximity sensor start + stmvl6180-tof@29 { + reg = <0x29>; + compatible = "stmv,vl6180"; + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.5.15 for proximity sensor end +//#endif/*VENDOR_EDIT*/ + /* + nfc-nci@e { + compatible = "qcom,nfc-nci"; + reg = <0x0e>; + qcom,irq-gpio = <&msm_gpio 29 0x00>; + qcom,dis-gpio = <&msm_gpio 30 0x00>; + qcom,clk-src = "BBCLK2"; + interrupt-parent = <&msm_gpio>; + interrupts = <29 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active","nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_disable_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; + qcom,clk-gpio = <&pm8994_gpios 10 0>; + qcom,pwr-req-gpio = <&pm8994_gpios 7 0>; + clocks = <&clock_rpm clk_bb_clk2_pin>; + clock-names = "ref_clk"; + };*/ + /* lifeng@BSP 2015.3.19 synaptics touch key s1302 */ + synaptics-rmi-ts@20 { + status = "okay"; + compatible = "synaptics,s1302"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <67 0x8>; + synaptics,irq-gpio = <&msm_gpio 67 0x08>; + synaptics,reset-gpio = <&msm_gpio 94 0x00>; + //synaptics,en3v_gpio = <&msm_gpio 41 0x00>; + //vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_s4>; + }; + }; + + //#ifdef VENDOR_EDIT + //#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support + i2c@f9928000 { + haptic-drv2605@5a { + status = "okay"; + compatible = "ti,drv2605"; + //drv2605,enable-gpio = <&pm8994_gpios 4 0x1>; + drv2605,enable-gpio = <&pm8994_gpios 22 0x1>; + reg = <0x5a >; + BIDIRInput = <0x01>; //should be added + loop = <0x1>; + RTPFormat=<0x0>; + actuator.device_type=<0x1>; + actuator.rated_vol=<0x50>; + actuator.g_effect_bank=<0x06>; + actuator.over_drive_vol=<0x84>; + actuator.LRAFreq=<205>; + a2h.a2h_min_input =<0x19>; + a2h.a2h_max_input = <0xff>; + a2h.a2h_min_output =<0x19>; + a2h.a2h_max_output = <0xFF>; + }; + }; + + //#endif VENDOR_EDIT + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + + vol_up { + label = "volume_up"; + gpios = <&pm8994_gpios 3 0x1>; + linux,input-type = <1>; + linux,code = <115>; + debounce-interval = <15>; + }; + + //#ifdef VENDOR_EDIT + /*for vol- support*/ + vol_down { + label = "volume_down"; + gpios = <&pm8994_gpios 2 0x1>; + linux,input-type = <1>; + linux,code = <114>; + debounce-interval = <15>; + }; + //endif VENDOR_EDIT + /* + cam_snapshot { + label = "cam_snapshot"; + gpios = <&pm8994_gpios 4 0x1>; + linux,input-type = <1>; + linux,code = <766>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + + cam_focus { + label = "cam_focus"; + gpios = <&pm8994_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <528>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + */ + /*VENDOR_EDIT*/ + /*qiuchangping add begin for hallsensor key 2015-03-25*/ + hallsensor_key { + label = "hallsensor_key"; + gpios = <&msm_gpio 75 1>; + interrupt-parent = <&msm_gpio>; + interrupts = <75 0x0>; + linux,input-type = <5>; + linux,code = <0>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + /*qiuchangping add end*/ + + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-28 add for tristate switch keys*/ + tri_state_key { + compatible = "oneplus,tri-state-key"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + //interrupts = <77 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + tristate,gpio_key2 = <&msm_gpio 77 0x00>; //Pass a GPIO + //tristate,gpio_key2 = <&msm_gpio 61 0x00>;//use gpio61 for test,MP will use 77 + tristate,gpio_key1 = <&msm_gpio 34 0x00>; + //vdd_io-supply = <&pm8994_s4>; // 1.8V + + /* MSM GPIO active and sleep settings */ + pinctrl-names = "key2_active","key2_suspend"; + pinctrl-0 = <&tristate_key2_active>; + pinctrl-1 = <&tristate_key2_suspend>; + }; + /*#endif VENDOR_EDIT*/ +/*#ifdef VENDOR_EDIT //changhua 2015-03-13 add for switch ANTENNA by gpio*/ + switch_antenna { + compatible = "oneplus,switch-antenna"; + antenna,antenna1_gpio = <&msm_gpio 120 0x00>; + antenna,antenna2_gpio = <&msm_gpio 121 0x00>; + antenna,antenna3_gpio = <&msm_gpio 122 0x00>; + antenna,antenna4_gpio = <&msm_gpio 124 0x00>; + }; + /*#endif VENDOR_EDIT*/ + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + switch_theme { + compatible = "oneplus,switch-theme"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <66 0>; //GPIO # and flags + //interrupts = <34 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + cover,gpio_irq = <&msm_gpio 66 0x00>; //Pass a GPIO + //cover,gpio_irq = <&msm_gpio 34 0x00>; //use gpio34 for test,MP will use 66 + cover,gpio_switch = <&pm8994_gpios 1 0>; + qcom,cover-vadc = <&pm8994_vadc>; + vdd_io-supply = <&pm8994_l21>; + /* MSM GPIO active and sleep settings */ + pinctrl-names = "cover_int_active","cover_int_suspend"; + pinctrl-0 = <&cover_int_active>; + pinctrl-1 = <&cover_int_suspend>; + }; + /*#endif VENDOR_EDIT*/ + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for pa*/ + i2c@f9967000{ + status = "ok"; +test_tfa9890: tfa9890@36 { + compatible = "nxp,tfa9890"; + reg = <0x36>; + nxp,tfa_max-vol-steps=<0x01>; + reset_gpio= <&msm_gpio 106 0>; + status = "okay"; + }; + }; + //endif VENDOR_EDIT + + + sound { + qcom,model = "msm8994-tomtom-mtp-snd-card"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK", + "ultrasound amp", "LINEOUT1", + "ultrasound amp", "LINEOUT3", + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,2015/3/19, changed for 14049 mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"AMIC5", "MIC BIAS3 External", + //"MIC BIAS3 External", "Analog Mic5", + //"AMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Analog Mic6", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#else + + "AMIC2", "MIC BIAS2 External", + "MIC BIAS2 External", "Headset Mic", + /*zhiguang.su@MultiMedia.AudioDrv ,2015/6/19, not to use internal resistance*/ + "AMIC3", "MIC BIAS3 External", + "MIC BIAS3 External", "Primary Mic", + "AMIC4", "MIC BIAS1 External", + "MIC BIAS1 External", "Noise Mic"; + + + + //#endif + + + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , delete for no swap for us-euro detect*/ + /* + qcom,us-euro-gpios = <&pm8994_mpps 2 0>; + */ + //endif VENDOR_EDIT + qcom,cdc-micbias2-headset-only; + /* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,mbhc-audio-jack-type = "6-pole-jack"; + */ + qcom,mbhc-audio-jack-type = "4-pole-jack"; + /* Modified end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + qcom,ext-ult-spk-amp-gpio = <&pmi8994_gpios 1 0>; + /* Commented begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,hdmi-audio-rx; + */ + /* Commented end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + asoc-codec = <&stub_codec>, <&hdmi_audio>; + asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-audio-codec-rx"; + }; +}; + +&pm8994_gpios { + + //#ifdef VENDOR_EDIT + /* changhua.li 2015-02-13 add for cover switch theme*/ + gpio@c000 { /* GPIO 1 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + //qcom,vin-sel = <2>; /* VIN 2 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + //#ifdef VENDOR_EDIT + /*for vol- support*/ + gpio@c100 { /* GPIO 2 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + gpio@c200 { /* GPIO 3 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c300 { /* GPIO 4 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c600 { /* GPIO 7 */ + /* NFC pwr request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c900 { /* GPIO 10 */ + /* NFC clk request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c700 { /* GPIO 8 */ + qcom,mode = <0>; /* Digital in */ + qcom,pull = <0>; /* PULL up 30uA */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output high */ + qcom,vin-sel = <2>; /* Logical 1 voltage value 1.8v */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* Low drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@c800 { /* GPIO 9 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <1>; /* Output high */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* High drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@cd00 { /* GPIO 14 */ + status = "okay"; + }; + + gpio@ce00 { /* GPIO 15 */ + qcom,mode = <1>; + qcom,output-type = <0>; + qcom,pull = <5>; + qcom,vin-sel = <2>; + qcom,out-strength = <1>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@d100 { /* GPIO 18 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + qcom,vin-sel = <2>; /* VIN 2 */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@d200 { /* GPIO 19 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#ifndef VENDOR_EDIT */ +//shankai@driver.bsp 2015.4.30 add for drv 2605 enable pin control + gpio@d500 { /* GPIO 22 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#end VENDOR_EDIT*/ +}; + +&pm8994_mpps { +/*#ifndef VENDOR_EDIT //changhua 2015-02-26 remove for rare cover use ADC(PM8994 MPP4) and pcb rf use adc*/ + //mpp@a100 { /* MPP 2 */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // status = "okay"; + //}; + + //mpp@a300 { /* MPP 4 */ + // /* HDMI_5v_vreg regulator enable */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // qcom,invert = <0>; + // status = "okay"; + //}; + /*#end VENDOR_EDIT*/ +}; + +&slim_msm { + tomtom_codec { + +//#ifndef VENDOR_EDIT +// /*zhiguang.su@MultiMedia.AudioDrv ,change for 14049*/ +// qcom,cdc-micbias1-ext-cap; +// qcom,cdc-micbias3-ext-cap; +// qcom,cdc-micbias4-ext-cap; +//#endif + + cdc-vdd-spkdrv-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-current = <600000>; + + cdc-vdd-spkdrv-2-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-2-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-2-current = <600000>; + + qcom,cdc-on-demand-supplies = "cdc-vdd-spkdrv", + "cdc-vdd-spkdrv-2"; + }; +}; + +&pmi8994_gpios { + gpio@c000 { /* GPIO 1 Ultrasound PA EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* CONSTANT */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 OTG SWITCH EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c100 { /* GPIO 2 LM3630 backlight output EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c200 { /* GPIO 3 TPS65132 +5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + gpio@c600 { /* GPIO 7 TPS65132 -5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; +}; + +//&pmi8994_mpps { +// mpp@a300 { /* MPP 4 */ +// /* WLED FET */ +// qcom,mode = <1>; /* DIGITAL OUT */ +// qcom,vin-sel = <0>; /* VIN0 */ +// qcom,master-en = <1>; +// status = "okay"; +// }; +//}; + +&blsp2_uart2 { + status = "ok"; +}; + +&blsp1_uart2 { + status= "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_sleep>; +}; + +&pcie0 { + status = "disabled"; +}; + +&usb3 { + status = "ok"; +}; + +&hsphy0 { + status = "ok"; +}; + +&ssphy0 { + status = "ok"; +}; + +&qcom_crypto1fde { + status = "okay"; +}; + +&qcom_crypto2fde { + status = "okay"; +}; + +&qcom_crypto1pfe { + status = "okay"; +}; + +&qcom_crypto2pfe { + status = "okay"; +}; + +&qcom_cedev { + status = "okay"; +}; + +&i2c_5 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ +//#ifdef VENDOR_EDIT + status = "disabled";//Disabled by likelong 2015.5.18, as there is no FM on 14049, and there is a conflict with Laser sensor. +//#endif/*VENDOR_EDIT*/ + compatible = "silabs,si4705"; + reg = <0x11>; + vdd-supply = <&pm8994_s4>; + silabs,vdd-supply-voltage = <1800000 1800000>; + va-supply = <&bt_vreg>; + silabs,va-supply-voltage = <3300000 3300000>; + pinctrl-names = "pmx_fm_active","pmx_fm_suspend"; + pinctrl-0 = <&fm_int_active &fm_status_int_active &fm_rst_active>; + pinctrl-1 = <&fm_int_suspend &fm_status_int_suspend &fm_rst_suspend>; + silabs,reset-gpio = <&msm_gpio 62 0>; + silabs,int-gpio = <&msm_gpio 9 0>; + silabs,status-gpio = <&msm_gpio 11 0>; + #address-cells = <0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = < + 0 &msm_gpio 9 2 + 1 &msm_gpio 11 1 + >; + interrupt-names = "silabs_fm_int", "silabs_fm_status_int"; + }; +}; + +/{ + mtp_batterydata: qcom,battery-data { + //#ifdef VENDOR_EDIT//for chg, do not match batt ID and let pmi8994 to charge now, later we will use external charger + qcom,batt-id-range-pct = <30>; + //#endif + #include "batterydata_oneplus_ATL_3300mAh.dtsi" + #include "batterydata_oneplus_SDI_3300mAh.dtsi" + #include "batterydata-unkown-3300mah.dtsi" + + }; +}; + +&pmi8994_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,ext-sense-type; +}; + +//#ifdef VENDOR_EDIT // shankai@bsp 2015-4-4 do not use it for vibrator ,comment it. +/* +&pmi8994_haptics { + status = "okay"; +}; +*/ +//#endif +&pmi8994_charger { + qcom,dc-psy-type = "Wipower"; + qcom,dcin-vadc = <&pmi8994_vadc>; + qcom,vph-vadc = <&pm8994_vadc>; + qcom,wipower-default-ilim-map = <4000000 20000000 550 700 300>; + qcom,wipower-pt-ilim-map = <4000000 7140000 550 700 300>, + <7140000 8140000 550 700 300>, + <8140000 9140000 500 700 300>, + <9140000 9950000 500 700 300>; + qcom,wipower-div2-ilim-map = <4000000 4820000 550 700 300>, + <4820000 5820000 550 700 300>, + <5820000 6820000 550 650 650>, + <6820000 7820000 550 700 600>, + <7820000 8500000 550 700 550>; +}; + +&cnss { + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &pcie0_clkreq_default>; +}; + +&i2c_11 { + smb1357-charger@1c { + compatible = "qcom,smb1357-charger"; + //#ifdef VENDOR_EDIT //for chg + status = "disabled"; + //#endif + reg = <0x1c>; + qcom,parallel-charger; + qcom,float-voltage-mv = <4400>; + qcom,recharge-thresh-mv = <100>; + }; +}; + +&usb_ehci { + status = "ok"; + qcom,usb2-enable-uicc; +}; + +&qusb_phy { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-pinctrl.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-pinctrl.dtsi new file mode 100755 index 0000000000000..10807d34bf866 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-pinctrl.dtsi @@ -0,0 +1,1632 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tlmm_pinmux: pinctrl@fd510000 { + compatible = "qcom,msm-tlmm-8994", "qcom,msm-tlmm-8974"; + reg = <0xfd510000 0x4000>; + interrupts = <0 208 0>; + + /*General purpose pins*/ + gp: gp { + qcom,num-pins = <146>; + #qcom,pin-cells = <1>; + + msm_gpio: msm_gpio { + compatible = "qcom,msm-tlmm-gp"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + qcom,direct-connect-irqs = <8>; + num_irqs = <146>; + }; + }; + + pmx-uartconsole { + qcom,pins = <&gp 4>, <&gp 5>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <2>; + label = "uart-console"; + + uart_console_sleep: uart-console { + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp2_uart2_active { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <2>; + label = "blsp2_uart2_active"; + hsuart_active: default { + drive-strength = <16>; + bias-disable; + }; + }; + + blsp2_uart2_sleep { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <0>; + label = "blsp2_uart2_sleep"; + hsuart_sleep: sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_mdss: pmx_mdss { + label = "mdss-pins"; + qcom,pin-func = <0>; + mdss_dsi_active: active { + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + mdss_dsi_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + pmx_mdss_te: pmx_mdss_te { + label = "mdss-te-pins"; + qcom,pin-func = <1>; + mdss_te_active: active { + drive-strength = <2>; /* 8 mA */ + bias-pull-down = <0>; /* pull down*/ + input-debounce = <0>; + }; + mdss_te_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + input-debounce = <0>; + }; + }; + + pmx_hdmi_cec: pmx_hdmi_cec { + qcom,pin-func = <1>; + label = "hdmi-cec-pins"; + mdss_hdmi_cec_active: cec_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_cec_suspend: cec_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_ddc: pmx_hdmi_ddc { + qcom,pin-func = <1>; + label = "hdmi-ddc-pins"; + mdss_hdmi_ddc_active: ddc_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_ddc_suspend: ddc_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_hpd: pmx_hdmi_hpd { + qcom,pin-func = <1>; + label = "hdmi-hpd-pin"; + mdss_hdmi_hpd_active: hpd_active { + drive-strength = <16>; + bias-pull-down; + }; + mdss_hdmi_hpd_suspend: hpd_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + mhl_intr: mhl_intr { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_intr"; + + mhl_intr_active: mhl_intr_active { + bias-pull-up; + input-enable; + }; + }; + + mhl_reset: mhl_reset { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_reset"; + + mhl_reset_active: mhl_reset_active { + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + spi_0_active { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-active"; + + spi_0_active: spi_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_0_suspend { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-suspend"; + + spi_0_sleep: spi_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_cs1_active { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-active"; + + spi_0_cs1_active: cs1_active { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + spi_cs1_suspend { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-suspend"; + + spi_0_cs1_sleep: cs1_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + pmx_i2c_1 { + qcom,pins = <&gp 2>, <&gp 3>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_1"; + + status = "disabled"; + + i2c_1_active: i2c_1_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_1_sleep: i2c_1_sleep { + drive-strength = <2>; + bias-disable; + }; + }; +//#ifdef VENDOR_EDIT//add for fingerprint fpc1150 SPI pin use pinctrl + + spi_12_active { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-active"; + + spi_12_active: spi_12_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_suspend { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-suspend"; + + spi_12_sleep: spi_12_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_12_cs0_active { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-active"; + + spi_12_cs0_active: cs0_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_cs0_suspend { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-suspend"; + + spi_12_cs0_sleep: cs0_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for tristate key + tristate_key2{ + qcom,pins = <&gp 77>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "tri_state_key2"; + tristate_key2_active: active { + drive-strength = <2>; + bias-disable; + }; + tristate_key2_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for switch_cover + switch_cover_int{ + qcom,pins = <&gp 66>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "switch_cover_int"; + cover_int_active: active { + drive-strength = <2>; + bias-disable; + }; + cover_int_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + + audio_ext_devices { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "audio-ext-speakers"; + /* default state */ + audio_ext_speakers: audio_ext_speakers { + drive-strength = <2>; + bias-pull-up; + }; + }; + + /* SDC pin type */ + sdc: sdc { + /* + * 0-3 for sdc1 + * 4-6 for sdc2 + * 7-9 for sdc3 + */ + qcom,num-pins = <10>; + /* + * Order of pins: + * SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 + * SDC2: CLK -> 4, CMD -> 5, DATA -> 6 + * SDC3: CLK -> 7, CMD -> 8, DATA -> 9 + */ + #qcom,pin-cells = <1>; + }; + + pmx_sdc1_clk { + qcom,pins = <&sdc 0>; + qcom,num-grp-pins = <1>; + label = "sdc1-clk"; + sdc1_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc1_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_cmd { + qcom,pins = <&sdc 1>; + qcom,num-grp-pins = <1>; + label = "sdc1-cmd"; + sdc1_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_cmd_off: cmd_off { + bias-pull-up = <0x3>; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_data { + qcom,pins = <&sdc 2>; + qcom,num-grp-pins = <1>; + label = "sdc1-data"; + sdc1_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_rclk { + qcom,pins = <&sdc 3>; + qcom,num-grp-pins = <1>; + label = "sdc1-rclk"; + sdc1_rclk_on: rclk_on { + bias-pull-down; /* pull down */ + }; + sdc1_rclk_off: rclk_off { + bias-pull-down; /* pull down */ + }; + }; + + pmx_sdc2_clk { + qcom,pins = <&sdc 4>; + qcom,num-grp-pins = <1>; + label = "sdc2-clk"; + sdc2_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc2_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_cmd { + qcom,pins = <&sdc 5>; + qcom,num-grp-pins = <1>; + label = "sdc2-cmd"; + sdc2_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_data { + qcom,pins = <&sdc 6>; + qcom,num-grp-pins = <1>; + label = "sdc2-data"; + sdc2_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_clk { + qcom,pins = <&sdc 7>; + qcom,num-grp-pins = <1>; + label = "sdc3-clk"; + sdc3_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc3_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_cmd { + qcom,pins = <&sdc 8>; + qcom,num-grp-pins = <1>; + label = "sdc3-cmd"; + sdc3_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_data { + qcom,pins = <&sdc 9>; + qcom,num-grp-pins = <1>; + label = "sdc3-data"; + sdc3_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_i2c_2 { + qcom,pins = <&gp 6>, <&gp 7>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_2"; + + i2c_2_active: i2c_2_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_2_sleep: i2c_2_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_i2c_5 { + qcom,pins = <&gp 83>, <&gp 84>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_5"; + + i2c_5_active: i2c_5_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_5_sleep: i2c_5_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_fm_int_active { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_active"; + + fm_int_active: fm_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_int_suspend { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_suspend"; + + fm_int_suspend: fm_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_active { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_active"; + + fm_status_int_active: fm_status_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_suspend { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_suspend"; + + fm_status_int_suspend: fm_status_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_rst_active { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_active"; + + fm_rst_active: fm_rst_active { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_fm_rst_suspend { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_suspend"; + + fm_rst_suspend: fm_rst_suspend { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_i2c_6 { + qcom,pins = <&gp 28>, <&gp 27>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_6"; + + i2c_6_active: i2c_6_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_6_sleep: i2c_6_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_rd_nfc_int{ + qcom,pins = <&gp 29>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_int"; + + nfc_int_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_int_suspend: suspend { + drive-strength = <6>; + bias-pull-up; + }; + }; + + pmx_nfc_reset{ + qcom,pins = <&gp 30>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_disable"; + + nfc_disable_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_disable_suspend: suspend { + drive-strength = <6>; + bias-disable; + }; + }; + +//#ifdef VENDOR_EDIT +/*suzhiguang@Multimdia.audio.driver, remove unused pins which conflic with quat i2s.*/ +// pmx_ts { +// qcom,pins = <&gp 60>, <&gp 61>; +// qcom,pin-func = <0>; +// qcom,num-grp-pins = <2>; +// label = "pmx_ts"; +// +// ts_active: ts_active { +// drive-strength = <16>; +// bias-pull-up; +// }; +// +// ts_suspend: ts_suspend { +// drive-strength = <16>; +// bias-disable; +// }; +// }; +//#endif + + /* CoreSight */ + tpiu_seta_1 { + qcom,pins = <&gp 27>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-1"; + seta_1: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_2 { + qcom,pins = <&gp 28>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-seta-2"; + seta_2: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_3 { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <10>; + label = "tpiu-seta-3"; + seta_3: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_4 { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <11>; + label = "tpiu-seta-4"; + seta_4: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_5 { + qcom,pins = <&gp 63>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "tpiu-seta-5"; + seta_5: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_6 { + qcom,pins = <&gp 64>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-6"; + seta_6: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_7 { + qcom,pins = <&gp 65>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-7"; + seta_7: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_8 { + qcom,pins = <&gp 66>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-8"; + seta_8: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_9 { + qcom,pins = <&gp 67>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-9"; + seta_9: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_10 { + qcom,pins = <&gp 74>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-10"; + seta_10: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_11 { + qcom,pins = <&gp 75>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-11"; + seta_11: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_12 { + qcom,pins = <&gp 76>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-12"; + seta_12: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_13 { + qcom,pins = <&gp 77>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-13"; + seta_13: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_14 { + qcom,pins = <&gp 85>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-14"; + seta_14: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_15 { + qcom,pins = <&gp 86>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-15"; + seta_15: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_16 { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-16"; + seta_16: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_17 { + qcom,pins = <&gp 89>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-17"; + seta_17: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_18 { + qcom,pins = <&gp 90>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-18"; + seta_18: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_1 { + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-1"; + setb_1: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_2 { + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-2"; + setb_2: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_3 { + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-3"; + setb_3: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_4 { + qcom,pins = <&gp 16>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-4"; + setb_4: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_5 { + qcom,pins = <&gp 17>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-5"; + setb_5: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_6 { + qcom,pins = <&gp 18>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-6"; + setb_6: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_7 { + qcom,pins = <&gp 19>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-7"; + setb_7: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_8 { + qcom,pins = <&gp 21>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-8"; + setb_8: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_9 { + qcom,pins = <&gp 22>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-9"; + setb_9: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_10 { + qcom,pins = <&gp 23>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-10"; + setb_10: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_11 { + qcom,pins = <&gp 25>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-setb-11"; + setb_11: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_12 { + qcom,pins = <&gp 26>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-12"; + setb_12: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_13 { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-13"; + setb_13: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_14 { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-14"; + setb_14: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_15 { + qcom,pins = <&gp 91>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-15"; + setb_15: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_16 { + qcom,pins = <&gp 92>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-setb-16"; + setb_16: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_17 { + qcom,pins = <&gp 93>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-17"; + setb_17: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_18 { + qcom,pins = <&gp 94>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-18"; + setb_18: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + cti_trigout_a { + qcom,pins = <&gp 56>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "cti-trigout-a"; + trigout_a: trigout_a { + drive-strength = <2>; + bias-disable; + }; + }; + + cti_trigout_c { + qcom,pins = <&gp 41>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "cti-trigout-c"; + trigout_c: trigout_c { + drive-strength = <2>; + bias-disable; + }; + }; + + cci0_active { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci0-active"; + /* active state */ + cci0_active: cci0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci0_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci0-suspend"; + /*suspended state */ + cci0_suspend: cci0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_active { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci1-active"; + /* active state */ + cci1_active: cci1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci1-suspend"; + /*suspended state */ + cci1_suspend: cci1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_active { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk0_active"; + /* active state */ + cam_sensor_mclk0_active: cam_sensor_mclk0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_suspend { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk0_suspend"; + /*suspended state */ + cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear_active { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_active"; + /* active state */ + cam_sensor_rear_active: cam_sensor_rear_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear_suspend { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_suspend"; + /*suspended state */ + cam_sensor_rear_suspend: cam_sensor_rear_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_active { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk1_active"; + /* active state */ + cam_sensor_mclk1_active: cam_sensor_mclk1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_suspend { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk1_suspend"; + /* suspend state */ + cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear2_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_active"; + /* active state */ + cam_sensor_rear2_active: cam_sensor_rear2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear2_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_suspend"; + /*suspended state */ + cam_sensor_rear2_suspend: cam_sensor_rear2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_active { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk2_active"; + /* active state */ + cam_sensor_mclk2_active: cam_sensor_mclk2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_suspend { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk2_suspend"; + /* suspend state */ + cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_front_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_active"; + /* active state */ + cam_sensor_front_active: cam_sensor_front_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_front_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_suspend"; + /*suspended state */ + cam_sensor_front_suspend: cam_sensor_front_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cnss_pmux: cnss_pmux { + qcom,pins = <&gp 113>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss_pins"; + cnss_default: default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + cnss_lpass: cnss_lpass { + qcom,pins = <&gp 112>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss-lpass"; + /* default state */ + cnss_lpass_default: cnss_lpass_default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pcie0_clkreq { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie0-clkreq"; + /* default state */ + pcie0_clkreq_default: pcie0_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie0_perst { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + label = "pcie0-perst"; + /* default state */ + pcie0_perst_default: pcie0_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie0_wake { + qcom,pins = <&gp 55>; + qcom,num-grp-pins = <1>; + label = "pcie0-wake"; + /* default state */ + pcie0_wake_default: pcie0_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_clkreq { + qcom,pins = <&gp 36>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie1-clkreq"; + /* default state */ + pcie1_clkreq_default: pcie1_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_perst { + qcom,pins = <&gp 35>; + qcom,num-grp-pins = <1>; + label = "pcie1-perst"; + /* default state */ + pcie1_perst_default: pcie1_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_wake { + qcom,pins = <&gp 37>; + qcom,num-grp-pins = <1>; + label = "pcie1-wake"; + /* default state */ + pcie1_wake_default: pcie1_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + + pcie1_wake_sleep: pcie1_wake_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_sec_aux_pcm_sleep { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_sleep"; + sec_aux_pcm_sleep: sec_aux_pcm_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_active { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_active"; + sec_aux_pcm_active: sec_aux_pcm_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_sec_aux_pcm_din_sleep { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_din_sleep"; + sec_aux_pcm_din_sleep: sec_aux_pcm_din_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_din_active { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_din_active"; + sec_aux_pcm_din_active: sec_aux_pcm_din_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#ifdef VENDOR_EDIT +// pmx_pri_mi2s_sleep { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sleep"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_active { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_active"; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0_sleep { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sd0_sleep"; +//pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_sd0_active { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0_active"; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; + +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ +// pmx_pri_mi2s { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0 { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0"; +// pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; +//#endif + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for quat i2s*/ + pmx_quat_mi2s { + qcom,pins = <&gp 58>, <&gp 59>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "quat_mi2s"; + quat_mi2s_sleep: quat_mi2s_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_active: quat_mi2s_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_quat_mi2s_mclk { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_mclk"; + quat_mi2s_mclk_sleep: quat_mi2s_mclk_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_mclk_active: quat_mi2s_mclk_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd0 { + qcom,pins = <&gp 60>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd0"; + quat_mi2s_sd0_sleep: quat_mi2s_sd0_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd0_active: quat_mi2s_sd0_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd1 { + qcom,pins = <&gp 61>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd1"; + quat_mi2s_sd1_sleep: quat_mi2s_sd1_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd1_active: quat_mi2s_sd1_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#endif VENDOR_EDIT + + tsif0_signals { + qcom,pins = <&gp 89>, /* TSIF0 CLK */ + <&gp 90>, /* TSIF0 Enable */ + <&gp 91>; /* TSIF0 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif0-signals"; + tsif0_signals_active: tsif0_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif0_sync { + qcom,pins = <&gp 110>; /* TSIF0 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif0-sync"; + tsif0_sync_active: tsif0_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + tsif1_signals { + qcom,pins = <&gp 93>, /* TSIF1 CLK */ + <&gp 94>, /* TSIF1 Enable */ + <&gp 95>; /* TSIF1 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif1-signals"; + tsif1_signals_active: tsif1_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif1_sync { + qcom,pins = <&gp 96>; /* TSIF1 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif1-sync"; + tsif1_sync_active: tsif1_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pm8004.dtsi new file mode 100755 index 0000000000000..c495f2c6e786b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pm8004.dtsi @@ -0,0 +1,48 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm8994-pm8994-pmi8994-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000C 0x0 0x0>; +}; + +&rpm_bus { + /delete-node/ rpm-regulator-bstb; + /delete-node/ rpm-regulator-bbyb; + /delete-node/ rpm-regulator-smpb1; + /delete-node/ rpm-regulator-smpc2; + + rpm-regulator-smpb2 { + pm8004_s2_corner: regulator-s2-corner { + regulator-name = "pm8004_s2_corner"; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + regulator-name = "pm8004_s2_floor_corner"; + }; + }; +}; + +&spmi_bus { + /delete-node/ qcom,pmi8994@2; + /delete-node/ qcom,pmi8994@3; +}; + +&usb3 { + /delete-property/ vbus_dwc3-supply; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pmi8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pmi8994-pm8004.dtsi new file mode 100755 index 0000000000000..ee5fc8594ceb2 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-pm8994-pmi8994-pm8004.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000A 0x1000C 0x0>; +}; + +&rpm_bus { + rpm-regulator-smpb2 { + status = "disabled"; + }; + + rpm-regulator-smpc2 { + status = "okay"; + regulator-s2-corner { + status = "okay"; + }; + + regulator-s2-floor-corner { + status = "okay"; + }; + }; +}; + +/* + * Override PMI8994 resources with proper PM8004 resources for + * MSM8994 with PM8004. + */ + +&soc { + qcom,msm-thermal { + vdd-gfx-supply = <&pm8004_s2_floor_corner>; + }; +}; + +&gdsc_oxili_gx { + parent-supply = <&pm8004_s2_corner>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-regulator.dtsi new file mode 100755 index 0000000000000..fe12c7b1b7e43 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-regulator.dtsi @@ -0,0 +1,987 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + /* PM8994 S1 + S6 = 2 phase VDD_CX supply */ + rpm-regulator-smpa1 { + status = "okay"; + pm8994_s1_corner: regulator-s1-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s1_floor_corner: regulator-s1-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + + pm8994_s1_corner_ao: regulator-s1-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <4>; + regulator-max-microvolt = <7>; + regulator-always-on; + qcom,init-voltage-corner = <6>; + qcom,use-voltage-corner; + proxy-supply = <&pm8994_s1_corner_ao>; + qcom,proxy-consumer-voltage = <7 7>; + }; + }; + + /* PM8994 S2 + S12 = 2 phase VDD_MX supply */ + rpm-regulator-smpa2 { + status = "okay"; + pm8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s2_corner_ao: regulator-s2-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + }; + + rpm-regulator-smpa3 { + status = "okay"; + pm8994_s3: regulator-s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <1300000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa4 { + status = "okay"; + pm8994_s4: regulator-s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa5 { + status = "okay"; + pm8994_s5: regulator-s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + qcom,init-voltage = <2150000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa7 { + status = "okay"; + pm8994_s7: regulator-s7 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa1 { + status = "okay"; + pm8994_l1: regulator-l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa2 { + status = "okay"; + pm8994_l2: regulator-l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + proxy-supply = <&pm8994_l2>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa3 { + status = "okay"; + pm8994_l3: regulator-l3 { + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>;*/ + /*#else*/ + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + /*#endif*/ + status = "okay"; + }; + }; + + rpm-regulator-ldoa4 { + status = "okay"; + pm8994_l4: regulator-l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + qcom,init-voltage = <1225000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa6 { + status = "okay"; + pm8994_l6: regulator-l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa8 { + status = "okay"; + pm8994_l8: regulator-l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa9 { + status = "okay"; + pm8994_l9: regulator-l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa10 { + status = "okay"; + pm8994_l10: regulator-l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa11 { + status = "okay"; + pm8994_l11: regulator-l11 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa12 { + status = "okay"; + pm8994_l12: regulator-l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l12>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa13 { + status = "okay"; + pm8994_l13: regulator-l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa14 { + status = "okay"; + pm8994_l14: regulator-l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l14>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa15 { + status = "okay"; + pm8994_l15: regulator-l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa16 { + status = "okay"; + pm8994_l16: regulator-l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; +//#ifdef VENDOR_EDIT //FIX GPS power issue + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa17 { + status = "okay"; + pm8994_l17: regulator-l17 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa18 { + status = "okay"; + pm8994_l18: regulator-l18 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + qcom,init-voltage = <2850000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa19 { + status = "okay"; + pm8994_l19: regulator-l19 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa20 { + status = "okay"; + pm8994_l20: regulator-l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + qcom,init-current = <750>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa21 { + status = "okay"; + pm8994_l21: regulator-l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; +//#ifdef VENDOR_EDIT //changhua modify for cover + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa22 { + status = "okay"; + pm8994_l22: regulator-l22 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <3000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa23 { + status = "okay"; + pm8994_l23: regulator-l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa24 { + status = "okay"; + pm8994_l24: regulator-l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3150000>; + qcom,init-voltage = <3075000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa25 { + status = "okay"; + pm8994_l25: regulator-l25 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa26 { + status = "okay"; + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <987500>; + regulator-max-microvolt = <987500>; + qcom,init-voltage = <987500>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa27 { + status = "okay"; + pm8994_l27: regulator-l27 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + qcom,init-voltage = <1050000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa28 { + status = "okay"; + pm8994_l28: regulator-l28 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + qcom,init-current = <45>; + regulator-boot-on; + proxy-supply = <&pm8994_l28>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa29 { + status = "okay"; + pm8994_l29: regulator-l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa30 { + status = "okay"; + pm8994_l30: regulator-l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + qcom,init-current = <50>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa32 { + status = "okay"; + pm8994_l32: regulator-l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-vsa1 { + status = "okay"; + pm8994_lvs1: regulator-lvs1 { + status = "okay"; + }; + }; + + rpm-regulator-vsa2 { + status = "okay"; + pm8994_lvs2: regulator-lvs2 { + status = "okay"; + }; + }; + + rpm-regulator-smpb1 { + status = "okay"; + pmi8994_s1: regulator-s1 { + regulator-min-microvolt = <1025000>; + regulator-max-microvolt = <1025000>; + qcom,init-voltage = <1025000>; + status = "okay"; + }; + }; + + /* PMI8994 S2 + S3 = 2 phase VDD_GFX supply */ + rpm-regulator-smpb2 { + status = "okay"; + pmi8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pmi8994_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; + + rpm-regulator-bstb { + status = "okay"; + pmi8994_boost_5v: regulator-bst { + /* + * When enabled, the PMI8994 Boost regulator always + * outputs 5V. This takes precedence over the pin + * control boost regulator request. + */ + regulator-name = "pmi8994_boost_5v"; + status = "okay"; + }; + pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl { + /* + * When enabled, the output voltage of the PMI8994 + * boost regulator is determined by the state of the + * REQ_5V_BST pin. If the pin signal is high, then the + * regulator outputs 5V. If the pin signal is low, then + * the regulator outputs VPH_PWR voltage. + */ + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost_pin_ctrl"; + qcom,set = <3>; + qcom,enable-with-pin-ctrl = <0 1>; + }; + }; + + rpm-regulator-bbyb { + status = "okay"; + pmi8994_boostbypass: regulator-bby { + status = "okay"; + regulator-min-microvolt = <3150000>; + regulator-max-microvolt = <3600000>; + qcom,init-voltage = <3150000>; + }; + }; + + /* PM8004 S2 + S4 = 2 phase VDD_GFX supply */ + rpm-regulator-smpc2 { + status = "disabled"; + pm8004_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; +}; + +/* SPM controlled regulators: */ +&spmi_bus { + qcom,pm8994@1 { + /* PM8994 S8 = VDD_APC0 supply */ + pm8994_s8: spm-regulator@2900 { + compatible = "qcom,spm-regulator"; + reg = <0x2900 0x100>; + regulator-name = "pm8994_s8"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1180000>; + qcom,cpu-num = <0>; + }; + + /* + * PM8994 S9 + S10 + S11 = 3 phase VDD_APC1 supply + * S11 is the gang leader. + */ + pm8994_s11: spm-regulator@3200 { + compatible = "qcom,spm-regulator"; + reg = <0x3200 0x100>; + regulator-name = "pm8994_s11"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1225000>; + qcom,cpu-num = <4>; + }; + }; +}; + +/* CPR controlled regulators */ +&soc { + mem_acc0_vreg_corner: mem-acc0-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900d084 1>, <0xf900d088 1>, + <0xf900d08c 1>, <0xf900d090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc0_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type2 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type3 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type4 = <0x02 0x02 0x00 0x00>; + }; + + mem_acc1_vreg_corner: mem-acc1-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900f084 1>, <0xf900f088 1>, + <0xf900f08c 1>, <0xf900f090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc1_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type2 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type3 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type4 = <0x0b 0x0b 0x0b 0x0b>; + }; + + apc0_vreg_corner: regulator@f9019000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf9019000 0x1000>, <0xf900d064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 16 0>; + regulator-name = "apc0_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <13>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1180000>; + qcom,cpr-voltage-floor = <700000 700000 780000 835000>; + vdd-apc-supply = <&pm8994_s8>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc0_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <12>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <82 82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <800000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 3 3 3 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0xFFFFFFFF 0 900000 900000 900000 900000 + 1000000 1000000 1000000 1115000 + 1115000 1180000 1180000 1180000 + 1180000>; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 700000 700000 700000 725000 + 780000 800000 825000 835000 + 850000 915000 970000 980000 + 1000000>; + + qcom,cpr-fuse-version-map = + <0xffffffff 0xffffffff 1 0 0 0 0>, + <0xffffffff 0xffffffff 2 0 0 0 0>, + <0xffffffff 0xffffffff 3 0 0 0 0>, + <0xffffffff 0xffffffff 4 0 0 0 0>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-50)>, + <0 0 0 (-50)>, + <0 (-50) (-90) 40>, + <0 (-50) (-90) 0>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-25000)>, + <0 0 0 (-25000)>, + <0 (-25000) (-25000) 20000>, + <0 (-25000) (-25000) 0>; + + qcom,cpr-scaled-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for SVS2 */ + <2 300000000>, + <3 384000000>, + <4 460800000>, + <5 600000000>, + <6 672000000>, + <7 768000000>, + <8 864000000>, + <9 960000000>, + <10 1248000000>, + <11 1344000000>, + <12 1478400000>, + <13 1555200000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 4 7 13>; + qcom,cpr-enable; + }; + + apc1_vreg_corner: regulator@f901a000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf901a000 0x1000>, <0xf900f064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 19 0>; + regulator-name = "apc1_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <17>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1225000>; + qcom,cpr-voltage-floor = <700000 700000 750000 835000>; + vdd-apc-supply = <&pm8994_s11>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc1_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <14 14 12 12 12 12 7 8>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,cpr-clamp-timer-interval = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <21 29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <72 72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + qcom,speed-bin-fuse-sel = <22 0 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <0 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>, + <1 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>; + qcom,cpr-voltage-floor-override = + <0 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>, + <1 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>; + + qcom,cpr-fuse-version-map = + <0 0xffffffff 1 6 6 6 6>, + <0 0xffffffff 2 6 6 6 6>, + <0 0xffffffff 2 4 4 4 4>, + <0 0xffffffff 3 4 4 4 4>, + <0 0xffffffff 4 4 4 4 4>, + <1 0xffffffff 3 4 4 4 4>, + <1 0xffffffff 4 4 4 4 4>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-24)>, + <0 0 0 (-24)>, + <0 0 0 (-84)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>; + qcom,cpr-cpus = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,cpr-online-cpu-virtual-corner-init-voltage-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + qcom,cpr-online-cpu-virtual-corner-quotient-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + + qcom,cpr-online-cpu-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for "SVS2" */ + <2 300000000>, + <3 384000000>, + <4 480000000>, + <5 633600000>, + <6 768000000>, + <7 864000000>, + <8 960000000>, + <9 1248000000>, + <10 1344000000>, + <11 1440000000>, + <12 1536000000>, + <13 1632000000>, + <14 1728000000>, + <15 1766400000>, + <16 1824000000>, + <17 1958400000>; + qcom,cpr-speed-bin-max-corners = + <0 0 1 5 8 17>, + <1 0 1 5 8 15>; + qcom,cpr-enable; + }; + + bt_vreg: bt_vreg { + compatible = "regulator-fixed"; + regulator-name = "bt_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8994_gpios 9 0>; + }; + + usb_otg_switch: usb-otg-switch { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vreg"; + vin-supply = <&smbcharger_external_otg>; + enable-active-high; + gpio = <&pmi8994_gpios 5 0>; + }; +}; + +&pmi8994_charger { + otg-parent-supply = <&pmi8994_boost_5v>; + smbcharger_charger_otg: qcom,smbcharger-boost-otg { + regulator-name = "smbcharger_charger_otg"; + }; + + smbcharger_external_otg: qcom,smbcharger-external-otg { + regulator-name = "smbcharger_external_otg"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-smp2p.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-smp2p.dtsi new file mode 100755 index 0000000000000..c40cdaf335e8b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-smp2p.dtsi @@ -0,0 +1,169 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +&soc { + qcom,smp2p-modem { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <1>; + qcom,irq-bitmask = <0x4000>; + interrupts = <0 27 1>; + }; + + qcom,smp2p-adsp { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <2>; + qcom,irq-bitmask = <0x400>; + interrupts = <0 158 1>; + }; + + smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_in { + compatible = "qcom,smp2pgpio_test_smp2p_7_in"; + gpios = <&smp2pgpio_smp2p_7_in 0 0>; + }; + + smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_out { + compatible = "qcom,smp2pgpio_test_smp2p_7_out"; + gpios = <&smp2pgpio_smp2p_7_out 0 0>; + }; + + smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_in { + compatible = "qcom,smp2pgpio_test_smp2p_1_in"; + gpios = <&smp2pgpio_smp2p_1_in 0 0>; + }; + + smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_out { + compatible = "qcom,smp2pgpio_test_smp2p_1_out"; + gpios = <&smp2pgpio_smp2p_1_out 0 0>; + }; + + smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_in { + compatible = "qcom,smp2pgpio_test_smp2p_2_in"; + gpios = <&smp2pgpio_smp2p_2_in 0 0>; + }; + + smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_out { + compatible = "qcom,smp2pgpio_test_smp2p_2_out"; + gpios = <&smp2pgpio_smp2p_2_out 0 0>; + }; + + /* ssr - inbound entry from lpass. */ + smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to lpass */ + smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - inbound entry from mss. */ + smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to mss. */ + smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-mtp_14049_HW_12.dts b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-mtp_14049_HW_12.dts new file mode 100755 index 0000000000000..4f67d9ee91d4d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-mtp_14049_HW_12.dts @@ -0,0 +1,26 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8994-v1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <12>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-pm.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-pm.dtsi new file mode 100755 index 0000000000000..371c020d1aa30 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1-pm.dtsi @@ -0,0 +1,593 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-ret = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900D210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 1f 18 03 2f 1b 18 7b d0 2b e0 3b c0 16 6b 26 6b 18 00 + 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d0 2b e0 3b + c0 16 6b 26 6b 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-retention"; + qcom,spm-cci-mode = "retention"; + qcom,latency-us = <45>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11609>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <1>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1375>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <760>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <775>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <40>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1505>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <647>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <653>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 332>, /* sps */ + <0xff 333>; /* ipa */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v1.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1.dtsi new file mode 100755 index 0000000000000..447a74220a008 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v1.dtsi @@ -0,0 +1,246 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v1.dtsi" +#include "msm8994-v1-pm.dtsi" +#include "msm8994-camera-v1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x10000>; + +}; + +&soc { + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 14 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + qcom,apply-cti-pmu-wa; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 14 0xff00>; + qcom,apply-cti-pmu-wa; + }; + + cci@f9100000 { + pmu@a000 { + interrupts = <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>; + }; + }; +}; + +&pm8994_s8 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1115000>; +}; + +&pm8994_s11 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1225000>; +}; + +&ufs1 { + freq-table-hz = + <100000000 171430000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +&mem_acc0_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&mem_acc1_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&apc0_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <9>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1115000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <16>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <116 0 73>; + qcom,cpr-fuse-ro-sel = <82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 800000 840000 860000 860000 + 900000 900000 940000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>, + <9 940800000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 9>; + qcom,cpr-enable; +}; + +&apc1_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <8>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1225000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <10>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <36 45 0>; + qcom,cpr-fuse-ro-sel = <72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 790000 840000 840000 860000 + 890000 920000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 8>; + qcom,cpr-enable; +}; + +&soc { + qcom,usbbam@f9304000 { + qcom,pipe0 { + qcom,pipe-connection-type = <1>; /* USB_BAM_PIPE_SYS2BAM */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2-pm.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2-pm.dtsi new file mode 100755 index 0000000000000..9272b2a079326 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2-pm.dtsi @@ -0,0 +1,690 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900d210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 38 48 26 6b 18 03 2f 1b 18 7b + 26 6b 40 40 48 38 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 03 2f 1b 18 7b d2 2b e2 3b c0 16 6b 26 6b 48 + 18 00 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x8>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 48 26 6b 18 03 2f 1b 18 7b 26 + 6b 40 40 48 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d2 2b + e2 3b c0 16 6b 26 6b 48 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-wfi"; + qcom,spm-cci-mode = "wfi"; + qcom,latency-us = <90>; + qcom,ss-power = <307>; + qcom,energy-overhead = <81180>; + qcom,time-overhead = <180>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11260>; + qcom,ss-power = <89>; + qcom,energy-overhead = <6959381>; + qcom,time-overhead = <5431>; + qcom,min-child-idx = <2>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <159>; + qcom,energy-overhead = <29640>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <148>; + qcom,energy-overhead = <44460>; + qcom,time-overhead = <180>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <800>; + qcom,ss-power = <104>; + qcom,energy-overhead = <432250>; + qcom,time-overhead = <1750>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <50>; + qcom,ss-power = <65>; + qcom,energy-overhead = <10650>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <100>; + qcom,ss-power = <51>; + qcom,energy-overhead = <15975>; + qcom,time-overhead = <150>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <400>; + qcom,ss-power = <50>; + qcom,energy-overhead = <74550>; + qcom,time-overhead = <700>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <480>; + qcom,ss-power = <30>; + qcom,energy-overhead = <85200>; + qcom,time-overhead = <800>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <80>; + qcom,ss-power = <270>; + qcom,energy-overhead = <72160>; + qcom,time-overhead = <160>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <190>; + qcom,ss-power = <189>; + qcom,energy-overhead = <157850>; + qcom,time-overhead = <350>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1260>; + qcom,ss-power = <93>; + qcom,energy-overhead = <1318724>; + qcom,time-overhead = <2924>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <117>; + qcom,energy-overhead = <31200>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <93>; + qcom,energy-overhead = <46800>; + qcom,time-overhead = <180>; + qcom,use-broadcast-timer; + }; + + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <475>; + qcom,ss-power = <66>; + qcom,energy-overhead = <201500>; + qcom,time-overhead = <775>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <636>; + qcom,ss-power = <60>; + qcom,energy-overhead = <248560>; + qcom,time-overhead = <956>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 20>, /* arch_timer */ + <0xff 23>, /* ARM64 Single-Bit Error PMU IRQ */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 48>, /* cpr */ + <0xff 51>, /* cpr */ + <0xff 54>, /* CCI error IRQ */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 164>, /* sps */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 212>, /* msm_dwc3 */ + <0xff 215>, /* fc388000.qcom,cpu-bwmon */ + <0xff 224>, /* spdm_bw_hyp */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 261>, /* msm_iommu_global_cfg */ + <0xff 263>, /* msm_iommu_global_client */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 272>, /* msm_iommu_secure_irq */ + <0xff 273>, /* msm_iommu_nonsecure_irq */ + <0xff 275>, /* int_msi */ + <0xff 283>, /* int_pls_err */ + <0xff 284>, /* int_aer_legacy */ + <0xff 286>, /* int_pls_link_down */ + <0xff 298>, /* msm_iommu_nonsecure_irq */ + <0xff 302>, /* coresight-tmc-etr */ + <0xff 303>, /* int_msi */ + <0xff 310>, /* int_pls_err */ + <0xff 311>, /* int_aer_legacy */ + <0xff 313>, /* int_pls_link_down */ + <0xff 329>, /* sps */ + <0xff 332>, /* sps */ + <0xff 333>, /* ipa */ + <0xff 348>, /* fd878000.qcom,fd */ + <0xff 350>, /* msm_iommu_nonsecure_irq */ + <0xff 360>, /* ARM64 primary DBE IRQ */ + <0xff 361>, /* ARM64 secondary DBE IRQ */ + <0xff 362>, /* ARM64 primary ext IRQ */ + <0xff 363>, /* ARM64 secondary ext IRQ */ + <0xff 364>; /* lmh_interrupt */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu4_clk", "cpu5_clk", "cpu6_clk", + "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,no-pll-switch-for-retention; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; + + qcom,npa-dump@0xfc190020 { + compatible = "qcom,npa-dump"; + reg = <0xfc190020 0x4>, <0xfc000000 0x1c00>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0-mtp_14049_HW_12.dts b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0-mtp_14049_HW_12.dts new file mode 100755 index 0000000000000..6aa9dd6efac2e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0-mtp_14049_HW_12.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.0.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.0 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <12>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0.dtsi new file mode 100755 index 0000000000000..b824d0c5d195c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.0.dtsi @@ -0,0 +1,35 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.0"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20000>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030001>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1-mtp_14049_HW_12.dts b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1-mtp_14049_HW_12.dts new file mode 100755 index 0000000000000..f5a7c0c28efa8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1-mtp_14049_HW_12.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.1 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <12>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1.dtsi new file mode 100755 index 0000000000000..93bc398c9693f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.1.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.1"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20001>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030002>; + qcom,gpu-pwrlevels { + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <630000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + }; + qcom,ocmem-bus-client { + qcom,msm-bus,vectors-KBps = + <89 662 0 10080000>, /* gpu= 630 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.dtsi new file mode 100755 index 0000000000000..add83045413a4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994-v2.dtsi @@ -0,0 +1,428 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v2.dtsi" +#include "msm8994-camera-v2.dtsi" + +&soc { + + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 7 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 7 0xff00>; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon2"; + }; + + qcom,lmh { + compatible = "qcom,lmh"; + interrupts = <0 332 4>; + reg = <0xF9117000 0x4>; + qcom,lmh-trim-err-offset = <18>; + }; +}; + +/* Clock driver overrides */ +&clock_gcc { + compatible = "qcom,gcc-8994v2"; +}; + +&clock_mmss { + compatible = "qcom,mmsscc-8994v2"; +}; + +&clock_cpu { + compatible = "qcom,cpu-clock-8994-v2"; + vdd-dig-supply = <&pm8994_s2_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 384000000 3>, + < 460800000 4>, + < 600000000 5>, + < 672000000 6>, + < 768000000 7>, + < 864000000 8>, + < 960000000 9>, + < 1248000000 10>, + < 1344000000 11>, + < 1478400000 12>, + < 1555200000 13>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1728000000 14>, + < 1824000000 16>, + < 1958400000 17>; + qcom,a57-speedbin1-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1766400000 15>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 300000000 4>, + < 384000000 5>, + < 537600000 7>, + < 600000000 9>, + < 729600000 10>, + < 787200000 11>; +}; + +&cci_cache { + freq-tbl-khz = + < 300000 >, + < 384000 >, + < 537600 >, + < 600000 >, + < 729600 >, + < 787200 >; +}; + +&msm_cpufreq { + qcom,cpufreq-table-0 = + < 384000 >, + < 460800 >, + < 600000 >, + < 672000 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1478400 >, + < 1555200 >; + + qcom,cpufreq-table-4 = + < 384000 >, + < 480000 >, + < 633600 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1440000 >, + < 1536000 >, + < 1632000 >, + < 1728000 >, + < 1824000 >, + < 1958400 >; +}; + +&devfreq_cpufreq { + cpubw-cpufreq { + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5928 >, + < 1248000 7904 >, + < 1344000 9887 >, + < 1478400 11863 >, + < 1555200 11863 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 2288 >, + < 633600 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5126 >, + < 1248000 5928 >, + < 1344000 7904 >, + < 1440000 7904 >, + < 1536000 7904 >, + < 1632000 9887 >, + < 1728000 9887 >, + < 1824000 11863 >, + < 1958400 11863 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1478400 1525 >, + < 1555200 1525 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 1525 >, + < 633600 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1440000 1525 >, + < 1536000 1525 >, + < 1632000 1525 >, + < 1728000 1525 >, + < 1824000 1525 >, + < 1958400 7904 >; + }; + + cci-cpufreq { + cpu-to-dev-map-0 = + < 384000 300000 >, + < 460800 300000 >, + < 600000 300000 >, + < 672000 384000 >, + < 768000 384000 >, + < 864000 537600 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 787200 >, + < 1478400 787200 >, + < 1555200 787200 >; + cpu-to-dev-map-4 = + < 384000 300000 >, + < 480000 300000 >, + < 633600 384000 >, + < 768000 537600 >, + < 864000 600000 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 729600 >, + < 1440000 729600 >, + < 1536000 787200 >, + < 1632000 787200 >, + < 1728000 787200 >, + < 1824000 787200 >, + < 1958400 787200 >; + }; +}; + +/* GPU VBIF overrides */ +&gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5271 /* 691 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; +}; + +/* GPU overrides */ +&msm_gpu { + qcom,initial-pwrlevel = <4>; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1600000>, /* 1 bus=200 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3680000>, /* 3 bus=460 */ + <26 512 0 4376000>, /* 4 bus=547 */ + <26 512 0 5528000>, /* 5 bus=691 */ + <26 512 0 6216000>, /* 6 bus=777 */ + <26 512 0 8288000>, /* 7 bus=1036 */ + <26 512 0 10368000>, /* 8 bus=1296 */ + <26 512 0 12440000>; /* 9 bus=1555 */ + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <510000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <450000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <390000000>; + qcom,bus-freq = <5>; + qcom,bus-min = <4>; + qcom,bus-max = <6>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <305000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <4>; + }; + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <180000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <27000000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <7>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu= 600 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; + +&ufs1 { + freq-table-hz = + <100000000 200000000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +/* MDSS driver overrides */ +&mdss_mdp { + qcom,mdp-settings = <0x0117c 0x0000ffff>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; +}; + +/* Video driver overrides */ +&msm_vidc { + qcom,load-freq-tbl = + <979200 510000000 0x0c000000>, + <979200 510000000 0x01000414>, + <979200 510000000 0x030fcfff>, + <979200 510000000 0x04000000>, + <783360 510000000 0x0c000000>, + <783360 510000000 0x01000414>, + <783360 510000000 0x030fcfff>, + <783360 510000000 0x04000000>, + <489600 320000000 0x0c000000>, + <489600 320000000 0x01000414>, + <489600 320000000 0x030fcfff>, + <489600 320000000 0x04000000>, + <244800 150000000 0x0c000000>, + <244800 150000000 0x01000414>, + <244800 150000000 0x030fcfff>, + <244800 150000000 0x04000000>; +}; + +&cnss { + wlan-bootstrap-gpio = <&msm_gpio 112 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &cnss_lpass_default>; +}; + +#include "msm8994-v2-pm.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_12/msm8994.dtsi b/arch/arm64/boot/dts/14049_HW_12/msm8994.dtsi new file mode 100755 index 0000000000000..e923d946dfbd3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/msm8994.dtsi @@ -0,0 +1,3792 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/memreserve/ 0x00000000 0x00001000; +/memreserve/ 0xac1c0000 0x00001000; + +#include "skeleton64.dtsi" +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x0>; + qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>; + interrupt-parent = <&intc>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; + + aliases { + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + /*do not enable sdhc2 and sdhc3 + sdhc2 = &sdhc_2; + sdhc3 = &sdhc_3; + */ + i2c6 = &i2c_6; /* I2C6 NFC qup6 device */ + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c5 = &i2c_5; + spi0 = &spi_0; + /*#ifdef VENDOR_EDIT modify for fpc1021 fingerprints*/ + spi12 = &spi_12; + /*#end VENDOR_EDIT*/ + qup2 = &i2c_2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU4>; + }; + core1 { + cpu = <&CPU5>; + }; + core2 { + cpu = <&CPU6>; + }; + core3 { + cpu = <&CPU7>; + }; + }; + }; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc0>; + qcom,ldo = <&ldo0>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + power-domain = <&l2ccc_0>; + qcom,dump-size = <0x0>; /* A53 L2 dump not supported */ + L2_tlb_0: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc1>; + qcom,ldo = <&ldo1>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc2>; + qcom,ldo = <&ldo2>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc3>; + qcom,ldo = <&ldo3>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc4>; + qcom,ldo = <&ldo4>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + qcom,dump-size = <0x280040>; /*A57 Cluster L2 size is 1MB */ + power-domain = <&l2ccc_1>; + L2_tlb_1: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_itlb_100: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_100: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc5>; + qcom,ldo = <&ldo5>; + next-level-cache = <&L2_1>; + L1_itlb_101: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_101: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x102>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc6>; + qcom,ldo = <&ldo6>; + next-level-cache = <&L2_1>; + L1_itlb_102: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_102: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x103>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc7>; + qcom,ldo = <&ldo7>; + next-level-cache = <&L2_1>; + L1_itlb_103: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_103: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + }; + + soc: soc { }; + + memory { + #address-cells = <2>; + #size-cells = <2>; + + secure_mem: secure_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x12c00000>; + label = "secure_mem"; + }; + + adsp_mem: adsp_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x3F00000>; + label = "adsp_mem"; + }; + + qsecom_mem: qsecom_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x1800000>; + label = "qseecom_mem"; + }; + + audio_mem: audio_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0 0 0x614000>; + label = "audio_mem"; + }; + + removed_regions: removed_regions@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x06300000 0 0xD00000>; + label = "memory_hole"; + }; + /*#ifdef VENDOR_EDIT*/ + /*Add by LiWei. The region is used for nv backup,20150325*/ + nabackup_regions: nvbackup_regions@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for nv backup + //linux,remove-completely;//del by jiachenghui for nv backup + reg = <0 0x06200000 0 0x100000>; + label = "memory_nvbackup"; + }; + /*End by LiWei. The region is used for nv backup, 20150325*/ + /*#endif VENDOR_EDIT*/ + dfps_data_mem: dfps_data_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03400000 0 0x1000>; + label = "dfps_data_mem"; + }; +/*liyunbing@BSP,20150518 revert MIPI_FB_ADDR to default addr, because we located MDSS issue cause by nvbackup*/ + cont_splash_mem: cont_splash_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03401000 0 0x2200000>; + //reg = <0 0x83200000 0 0x2200000>; + label = "cont_splash_mem"; + }; + + peripheral_mem: peripheral_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x0ca00000 0 0x1f00000>; + label = "peripheral_mem"; + }; +/*#ifdef VENDOR_EDIT //changhua.li add for enlarge TZ APP memory to 25M*/ + tzapp_mem: tzapp_region@0 { + + linux,reserve-contiguous-region; + + linux,reserve-region; + + linux,remove-completely; + + reg = <0 0x0E900000 0 0x1900000>; + + label = "tzapp_mem"; + + }; +/*#endif VENDOR_EDIT*/ + + + modem_mem: modem_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x07000000 0 0x5a00000>; + label = "modem_mem"; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops_mem: ramoops_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for ramoops reserve region + //linux,remove-completely;//del by jiachenghui for ramoops reserve region + reg = <0 0xac000000 0 0x00100000>;//modify from 0x05800000 to 0xac000000 by jiachenghui for ramoops reserve region + label = "ramoops_mem"; + }; +/* #endif VENDOR_EDIT */ + + param_mem: param_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region; + //linux,remove-completely; + reg = <0 0xac200000 0 0x00100000>; + label = "param_mem"; + }; + + }; +}; + +#include "msm-gdsc.dtsi" +#include "msm8994-smp2p.dtsi" +#include "msm8994-ipcrouter.dtsi" +#include "msm8994-mdss.dtsi" +#include "msm8994-mdss-pll.dtsi" +#include "msm8994-bus.dtsi" + +&soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + cpuss@fd4a8000 { + compatible = "qcom,cpuss-8994"; + reg = <0xfd4a8000 0x4>; + }; + + acc0:clock-controller@f908b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9070000 0x1000>, + <0xf908b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc1:clock-controller@f909b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9071000 0x1000>, + <0xf909b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc2:clock-controller@f90ab004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9072000 0x1000>, + <0xf90ab000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc3:clock-controller@f90bb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9073000 0x1000>, + <0xf90bb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc4:clock-controller@f90cb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9074000 0x1000>, + <0xf90cb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc5:clock-controller@f90db004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9075000 0x1000>, + <0xf90db000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc6:clock-controller@f90eb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9076000 0x1000>, + <0xf90eb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc7:clock-controller@f90fb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9077000 0x1000>, + <0xf90fb000 0x1000>, + <0xf900b000 0x1000>; + }; + + ldo0:ldo-vref@f9070000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9070000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo1:ldo-vref@f9071000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9071000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo2:ldo-vref@f9072000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9072000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo3:ldo-vref@f9073000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9073000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo4:ldo-vref@f9074000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9074000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo5:ldo-vref@f9075000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9075000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo6:ldo-vref@f9076000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9076000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo7:ldo-vref@f9077000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9077000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + l2ccc_0: clock-controller@f900d000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900d000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster0_spm>; + }; + + l2ccc_1: clock-controller@f900f000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900f000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster1_spm>; + qcom,vctl-val = <0xb8>; + }; + + intc: interrupt-controller@f9000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0xf9000000 0x1000>, + <0xf9002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 2 0xff08>, + <1 3 0xff08>, + <1 4 0xff08>, + <1 1 0xff08>; + clock-frequency = <19200000>; + }; + + qcom,mpm2-sleep-counter@fc4a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0xfc4a3000 0x1000>; + clock-frequency = <32768>; + }; + + timer@f9020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xf9020000 0x1000>; + clock-frequency = <19200000>; + + frame@f9021000 { + frame-number = <0>; + interrupts = <0 9 0x4>, + <0 8 0x4>; + reg = <0xf9021000 0x1000>, + <0xf9022000 0x1000>; + }; + + frame@f9023000 { + frame-number = <1>; + interrupts = <0 10 0x4>; + reg = <0xf9023000 0x1000>; + status = "disabled"; + }; + + frame@f9024000 { + frame-number = <2>; + interrupts = <0 11 0x4>; + reg = <0xf9024000 0x1000>; + status = "disabled"; + }; + + frame@f9025000 { + frame-number = <3>; + interrupts = <0 12 0x4>; + reg = <0xf9025000 0x1000>; + status = "disabled"; + }; + + frame@f9026000 { + frame-number = <4>; + interrupts = <0 13 0x4>; + reg = <0xf9026000 0x1000>; + status = "disabled"; + }; + + frame@f9027000 { + frame-number = <5>; + interrupts = <0 14 0x4>; + reg = <0xf9027000 0x1000>; + status = "disabled"; + }; + + frame@f9028000 { + frame-number = <6>; + interrupts = <0 15 0x4>; + reg = <0xf9028000 0x1000>; + status = "disabled"; + }; + }; + + restart@fc4ab000 { + compatible = "qcom,pshold"; + reg = <0xfc4ab000 0x4>; + }; + + blsp1_uart3: serial@f991f000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991f000 0x1000>; + interrupts = <0 109 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp1_uart2: serial@f991e000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp2_uart2: uart@f995e000 { /* BLSP2 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xf995e000 0x1000>, + <0xf9944000 0x19000>; + status = "disabled"; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 114 0 + 1 &intc 0 239 0 + 2 &msm_gpio 46 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xFD>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp2_ahb_clk>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&hsuart_sleep>; + pinctrl-1 = <&hsuart_active>; + + qcom,msm-bus,name = "buart8"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + }; + + qcom,sps@f9984000 { + compatible = "qcom,msm_sps"; + reg-names = "bam_mem", "core_mem"; + reg = <0xf9984000 0x15000>, + <0xf9999000 0xb000>; + interrupts = <0 94 0>; + qcom,pipe-attr-ee; + clocks = <&clock_rpm clk_pnoc_sps_clk>, + <&clock_gcc clk_gcc_bam_dma_ahb_clk>; + clock-names = "dfab_clk", "dma_bam_pclk"; + }; + + pcie0: qcom,pcie@fc520000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0xfc520000 0x2000>, + <0xfc526000 0x1000>, + <0xff000000 0xf1d>, + <0xff000f20 0xa8>, + <0xff100000 0x100000>, + <0xff200000 0x100000>, + <0xff300000 0xd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie0>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 243 0 + 1 &intc 0 244 0 + 2 &intc 0 245 0 + 3 &intc 0 247 0 + 4 &intc 0 248 0 + 5 &intc 0 249 0 + 6 &intc 0 250 0 + 7 &intc 0 251 0 + 8 &intc 0 252 0 + 9 &intc 0 253 0 + 10 &intc 0 254 0 + 11 &intc 0 255 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; + + perst-gpio = <&msm_gpio 53 0>; + wake-gpio = <&msm_gpio 55 0>; + + gdsc-vdd-supply = <&gdsc_pcie_0>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9006040>; + qcom,msi-gicm-base = <0x180>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + qcom,scm-dev-id = <11>; + + clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_0_aux_clk>, + <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, + <&clock_gcc clk_pcie_0_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_0_reset>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", "pcie_0_aux_clk", + "pcie_0_cfg_ahb_clk", "pcie_0_mstr_axi_clk", + "pcie_0_slv_axi_clk", "pcie_0_ldo", "pcie_0_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + pcie1: qcom,pcie@fc528000 { + compatible = "qcom,pci-msm"; + cell-index = <1>; + + reg = <0xfc528000 0x2000>, + <0xfc52e000 0x1000>, + <0xf8800000 0xf1d>, + <0xf8800F20 0xa8>, + <0xf8801000 0x7f000>, + <0xf8880000 0x80000>, + <0xf8900000 0x700000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie1>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 271 0 + 1 &intc 0 272 0 + 2 &intc 0 273 0 + 3 &intc 0 274 0 + 4 &intc 0 275 0 + 5 &intc 0 276 0 + 6 &intc 0 277 0 + 7 &intc 0 278 0 + 8 &intc 0 279 0 + 9 &intc 0 280 0 + 10 &intc 0 281 0 + 11 &intc 0 282 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>; + pinctrl-1 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_sleep>; + + perst-gpio = <&msm_gpio 35 0>; + wake-gpio = <&msm_gpio 37 0>; + + gdsc-vdd-supply = <&gdsc_pcie_1>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,l1-supported; + qcom,l1ss-supported; + qcom,aux-clk-sync; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9007040>; + qcom,msi-gicm-base = <0x1a0>; + + qcom,ep-wakeirq; + + qcom,msm-bus,name = "pcie1"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, + <100 512 500 800>; + + qcom,scm-dev-id = <12>; + + clocks = <&clock_gcc clk_gcc_pcie_1_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_1_aux_clk>, + <&clock_gcc clk_gcc_pcie_1_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_1_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_1_slv_axi_clk>, + <&clock_gcc clk_pcie_1_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_1_reset>; + + clock-names = "pcie_1_pipe_clk", "pcie_1_ref_clk_src", "pcie_1_aux_clk", + "pcie_1_cfg_ahb_clk", "pcie_1_mstr_axi_clk", + "pcie_1_slv_axi_clk", "pcie_1_ldo", "pcie_1_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + ipa_hw: qcom,ipa@fd4c0000 { + compatible = "qcom,ipa"; + reg = <0xfd4c0000 0x29000>, + <0xfd4c4000 0x15820>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 301 0>, + <0 300 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <3>; /* IPA core version = IPAv2.0 */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; + qcom,ee = <2>; + clock-names = "core_clk"; + clocks = <&clock_rpm clk_ipa_clk>; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <90 512 0 0>, <90 585 0 0>, /* No vote */ + <90 512 100000 800000>, <90 585 100000 800000>, /* SVS */ + <90 512 100000 1200000>, <90 585 100000 1200000>; /* PERF */ + qcom,bus-vector-names = "MIN", "SVS", "PERF"; + + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + }; + + qcom,ipc-spinlock@fd484000 { + compatible = "qcom,ipc-spinlock-sfpb"; + reg = <0xfd484000 0x400>; + qcom,num-locks = <8>; + }; + + qcom,smem@6a00000 { + compatible = "qcom,smem"; + reg = <0x6a00000 0x200000>, + <0xf900d008 0x4>, + <0xfc428000 0x4000>; + reg-names = "smem", "irq-reg-base", "aux-mem1"; + qcom,mpu-enabled; + + qcom,smd-modem { + compatible = "qcom,smd"; + qcom,smd-edge = <0>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1000>; + interrupts = <0 25 1>; + label = "modem"; + qcom,not-loadable; + }; + + qcom,smsm-modem { + compatible = "qcom,smsm"; + qcom,smsm-edge = <0>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x2000>; + interrupts = <0 26 1>; + }; + + qcom,smd-adsp { + compatible = "qcom,smd"; + qcom,smd-edge = <1>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x100>; + interrupts = <0 156 1>; + label = "adsp"; + }; + + qcom,smsm-adsp { + compatible = "qcom,smsm"; + qcom,smsm-edge = <1>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x200>; + interrupts = <0 157 1>; + }; + + qcom,smd-rpm { + compatible = "qcom,smd"; + qcom,smd-edge = <15>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1>; + interrupts = <0 168 1>; + label = "rpm"; + qcom,irq-no-suspend; + qcom,not-loadable; + }; + }; + + qcom,msm-imem@fe87f000 { + compatible = "qcom,msm-imem"; + reg = <0xfe87f000 0x1000>; /* Address and size of IMEM */ + ranges = <0x0 0xfe87f000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + download_mode@0 { + compatible = "qcom,msm-imem-download_mode"; + reg = <0x0 8>; + }; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + + pil@94c { + compatible = "qcom,msm-imem-pil"; + reg = <0x94c 200>; + }; + + emergency_download_mode@fe0 { + compatible = "qcom,msm-imem-emergency_download_mode"; + reg = <0xfe0 12>; + }; + }; + + qcom,wdt@f9017000 { + compatible = "qcom,msm-watchdog"; + reg = <0xf9017000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 3 0>, <0 4 0>; +//liyunbing@BSP, 2015/05/21, WDT bark-time too short cause some task timeout + #qcom,bark-time = <11000>; + qcom,bark-time = <15000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + }; + + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + jtag_fuse: jtagfuse@fc4be024 { + compatible = "qcom,jtag-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + }; + + jtag_mm0: jtagmm@fb840000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb840000 0x1000>, + <0xfb810000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU0>; + }; + + jtag_mm1: jtagmm@fb940000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb940000 0x1000>, + <0xfb910000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU1>; + }; + + jtag_mm2: jtagmm@fba40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfba40000 0x1000>, + <0xfba10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU2>; + }; + + jtag_mm3: jtagmm@fbb40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbb40000 0x1000>, + <0xfbb10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU3>; + }; + + jtag_mm4: jtagmm@fbc40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbc40000 0x1000>, + <0xfbc10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU4>; + }; + + jtag_mm5: jtagmm@fbd40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbd40000 0x1000>, + <0xfbd10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU5>; + }; + + jtag_mm6: jtagmm@fbe40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbe40000 0x1000>, + <0xfbe10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU6>; + }; + + jtag_mm7: jtagmm@fbf40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbf40000 0x1000>, + <0xfbf10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU7>; + }; + + rpm_bus: qcom,rpm-smd { + compatible = "qcom,rpm-smd"; + rpm-channel-name = "rpm_requests"; + rpm-channel-type = <15>; /* SMD_APPS_RPM */ + }; + + qcom,msm-rng@f9bff000 { + compatible = "qcom,msm-rng"; + reg = <0xf9bff000 0x200>; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 618 0 0>, + <88 618 0 800>; + qcom,msm-rng-iface-clk; + clocks = <&clock_gcc clk_gcc_prng_ahb_clk>; + clock-names = "iface_clk"; + }; + + qcom,rmtfs_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00180000>; + reg-names = "rmtfs"; + qcom,client-id = <0x00000001>; + }; + + qcom,dsp_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_dsp"; + qcom,client-id = <0x011013ec>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,mdm_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_mdm"; + qcom,client-id = <0x011013ed>; + }; + + qcom,sensors_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_sensor"; + qcom,client-id = <0x011013ee>; + linux,contiguous-region = <&adsp_mem>; + }; + + sdhc_1: sdhci@f9824900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 123 0>, <0 138 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc1"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */ + <78 512 1600 3200>, /* 400 KB/s*/ + <78 512 80000 160000>, /* 20 MB/s */ + <78 512 100000 200000>, /* 25 MB/s */ + <78 512 200000 400000>, /* 50 MB/s */ + <78 512 400000 800000>, /* 100 MB/s */ + <78 512 400000 800000>, /* 200 MB/s */ + <78 512 400000 800000>, /* 400 MB/s */ + <78 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 400000000 4294967295>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>, + <&clock_gcc clk_gcc_sdcc1_apps_clk>; + + status = "disabled"; + }; + + sdhc_2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 125 0>, <0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>, + <&clock_gcc clk_gcc_sdcc2_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc2"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */ + <81 512 1600 3200>, /* 400 KB/s*/ + <81 512 80000 160000>, /* 20 MB/s */ + <81 512 100000 200000>, /* 25 MB/s */ + <81 512 200000 400000>, /* 50 MB/s */ + <81 512 400000 800000>, /* 100 MB/s */ + <81 512 800000 800000>, /* 200 MB/s */ + <81 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + + status = "disabled"; + }; + + sdhc_3: sdhci@f9864900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9864900 0x11c>, <0xf9864000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 127 0>, <0 224 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc3_ahb_clk>, + <&clock_gcc clk_gcc_sdcc3_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc3"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */ + <79 512 1600 3200>, /* 400 KB/s*/ + <79 512 80000 160000>, /* 20 MB/s */ + <79 512 100000 200000>, /* 25 MB/s */ + <79 512 200000 400000>, /* 50 MB/s */ + <79 512 400000 800000>, /* 100 MB/s */ + <79 512 800000 800000>, /* 200 MB/s */ + <79 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + qcom,dat1-mpm-int = <47>; + status = "disabled"; + }; + + ufs_ice: ufsice@fc5a0000 { + compatible = "qcom,ice"; + reg = <0xfc5a0000 0x8000>; + interrupt-names = "ufs_ice_nonsec_level_irq", "ufs_ice_sec_level_irq"; + interrupts = <0 258 0>, <0 257 0>; + status = "disabled"; + }; + + ufsphy1: ufsphy@fc597000 { + compatible = "qcom,ufs-phy-qmp-20nm"; + reg = <0xfc597000 0xda8>; + reg-names = "phy_mem"; + #phy-cells = <0>; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-max-microamp = <45000>; + vdda-pll-max-microamp = <100>; + vddp-ref-clk-supply = <&pm8994_l31>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + clock-names = "ref_clk_src", + "ref_clk", + "tx_iface_clk", + "rx_iface_clk"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_ufs_phy_ldo>, + <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, + <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; + status = "disabled"; + }; + + ufs1: ufshc@fc594000 { + compatible = "qcom,ufshc"; + reg = <0xfc594000 0x2500>, <0xfd512074 0x4>; + interrupts = <0 265 0>; + phys = <&ufsphy1>; + phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8994_l20>; + vccq-supply = <&pm8994_l31>; + vccq2-supply = <&pm8994_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <50000>; + vccq2-max-microamp = <750000>; + + clock-names = "core_clk_src", "core_clk", "bus_clk", "iface_clk", + "ref_clk", "rx_lane0_sync_clk", "tx_lane0_sync_clk", + "rx_lane1_sync_clk", "tx_lane1_sync_clk"; + clocks = + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>, + <&clock_rpm clk_bb_clk1>, + <&clock_gcc clk_gcc_ufs_rx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_rx_symbol_1_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_1_clk>; + qcom,msm-bus,name = "ufs1"; + qcom,msm-bus,num-cases = <22>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <95 512 0 0>, <1 650 0 0>, /* No vote */ + <95 512 922 0>, <1 650 1000 0>, /* PWM G1 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G3 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G4 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G1 L2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G2 L2 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G3 L2 */ + <95 512 14752 0>, <1 650 1000 0>, /* PWM G4 L2 */ + <95 512 127796 0>, <1 650 1000 0>, /* HS G1 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G2 RA */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G3 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G1 RA L2 */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G2 RA L2 */ + <95 512 1022362 0>, <1 650 1000 0>, /* HS G3 RA L2 */ + <95 512 149422 0>, <1 650 1000 0>, /* HS G1 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G2 RB */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G3 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G1 RB L2 */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G2 RB L2 */ + <95 512 1192756 0>, <1 650 1000 0>, /* HS G3 RB L2 */ + <95 512 4096000 0>, <1 650 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "PWM_G1_L2", "PWM_G2_L2", "PWM_G3_L2", "PWM_G4_L2", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", + "HS_RA_G1_L2", "HS_RA_G2_L2", "HS_RA_G3_L2", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", + "HS_RB_G1_L2", "HS_RB_G2_L2", "HS_RB_G3_L2", + "MAX"; + + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0xf>; /* little cluster */ + qcom,cpu-dma-latency-us = <301>; + + spm-level = <5>; + status = "disabled"; + }; + + spi_0: spi_epm: spi@f9923000 { /* BLSP1 QUP1 */ + compatible = "qcom,spi-qup-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical", "spi_bam_physical"; + reg = <0xf9923000 0x1000>, + <0xf9904000 0x19000>; + interrupt-names = "spi_irq", "spi_bam_irq"; + interrupts = <0 95 0>, <0 238 0>; + spi-max-frequency = <19200000>; + + qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <12>; + qcom,bam-producer-pipe-index = <13>; + qcom,master-id = <86>; + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_0_active &spi_0_cs1_active>; + pinctrl-1 = <&spi_0_sleep &spi_0_cs1_sleep>; + + clock-names = "iface_clk", "core_clk"; + + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + }; +//#ifdef VENDOR_EDIT +/* add for fpc1021 fingerprints */ + spi_12: spi@f9968000 { + compatible = "qcom,spi-qup-v2"; + //cell-index = <12>; //changhua + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical"/*, "spi_bam_physical"*/; + + /*Add BAM physical address + BLSP1: 0xf9904000 + BLSP2: 0xf9944000 + */ + + reg = <0xf9968000 0x1000>/*, + <0xf9944000 0x19000>*/; + + interrupt-names = "spi12_irq"/*, "spi_bam_irq"*/; + + /* Add BAM IRQ + BLSP1: 238 + BLSP2: 239 ??271??? 239 is offset + */ + interrupts = <0 106 0>/*, <0 239 0>*/; + + spi-max-frequency = <9600000>; + + /* //changhua + qcom,gpio-mosi = <&msm_gpio 85 0>; + qcom,gpio-miso = <&msm_gpio 86 0>; + qcom,gpio-clk = <&msm_gpio 88 0>; + qcom,gpio-cs0 = <&msm_gpio 87 0>; + */ + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup6_spi_apps_clk>; + + qcom,master-id = <86>; + /*qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <22>; + qcom,bam-producer-pipe-index = <23>; + */ + /*lichanghua add for use pinctrl*/ + /* Assign runtime functions to pins */ + + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_12_active &spi_12_cs0_active>; + pinctrl-1 = <&spi_12_sleep &spi_12_cs0_sleep>; + + qcom,shared; + + /*lichanghua add for use pinctrl end*/ + }; +//#endif/*VENDOR_EDIT*/ + + qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + }; + + qcom,msm-pacman { + compatible = "qcom,msm-pacman"; + }; + + wcd9xxx_intc: wcd9xxx-irq { + compatible = "qcom,wcd9xxx-irq"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&msm_gpio>; + interrupts = <72 0>; + interrupt-names = "cdc-int"; + }; + + tspp: msm_tspp@f99d8000 { + compatible = "qcom,msm_tspp"; + reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */ + <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */ + <0xf99da000 0x1000>, /* MSM_TSPP_PHYS */ + <0xf99c4000 0x11000>; /* MSM_TSPP_BAM_PHYS */ + reg-names = "MSM_TSIF0_PHYS", + "MSM_TSIF1_PHYS", + "MSM_TSPP_PHYS", + "MSM_TSPP_BAM_PHYS"; + interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */ + <0 119 0>, /* TSIF0_IRQ */ + <0 120 0>, /* TSIF1_IRQ */ + <0 122 0>; /* TSIF_BAM_IRQ */ + interrupt-names = "TSIF_TSPP_IRQ", + "TSIF0_IRQ", + "TSIF1_IRQ", + "TSIF_BAM_IRQ"; + + clock-names = "iface_clk", "ref_clk"; + clocks = <&clock_gcc clk_gcc_tsif_ahb_clk>, + <&clock_gcc clk_gcc_tsif_ref_clk>; + + qcom,msm-bus,name = "tsif"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <82 512 0 0>, /* No vote */ + <82 512 12288 24576>; /* Max. bandwidth, 2xTSIF, each max of 96Mbps */ + + pinctrl-names = "disabled", + "tsif0-mode1", "tsif0-mode2", + "tsif1-mode1", "tsif1-mode2", + "dual-tsif-mode1", "dual-tsif-mode2"; + + pinctrl-0 = <>; /* disabled */ + pinctrl-1 = <&tsif0_signals_active>; /* tsif0-mode1 */ + pinctrl-2 = <&tsif0_signals_active + &tsif0_sync_active>; /* tsif0-mode2 */ + pinctrl-3 = <&tsif1_signals_active>; /* tsif1-mode1 */ + pinctrl-4 = <&tsif1_signals_active + &tsif1_sync_active>; /* tsif1-mode2 */ + pinctrl-5 = <&tsif0_signals_active + &tsif1_signals_active>; /* dual-tsif-mode1 */ + pinctrl-6 = <&tsif0_signals_active + &tsif0_sync_active + &tsif1_signals_active + &tsif1_sync_active>; /* dual-tsif-mode2 */ + }; + + slim_msm: slim@fe12f000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0xfe12f000 0x2C000>, + <0xfe104000 0x20000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 163 0>, <0 164 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x60000000>; + qcom,ea-pc = <0x110>; + + tomtom_codec { + compatible = "qcom,tomtom-slim-pgd"; + elemental-addr = [00 01 30 01 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30 31>; + + qcom,cdc-reset-gpio = <&msm_gpio 68 0>; + + cdc-vdd-buck-supply = <&pm8994_s5>; + qcom,cdc-vdd-buck-voltage = <2150000 2150000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-vdd-tx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pm8994_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + cdc-vdd-a-1p2v-supply = <&pm8994_l11>; + qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>; + qcom,cdc-vdd-a-1p2v-current = <2000>; + + cdc-vddcx-1-supply = <&pm8994_l11>; + qcom,cdc-vddcx-1-voltage = <1200000 1200000>; + qcom,cdc-vddcx-1-current = <33000>; + + cdc-vddcx-2-supply = <&pm8994_l11>; + qcom,cdc-vddcx-2-voltage = <1200000 1200000>; + qcom,cdc-vddcx-2-current = <33000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1", + "cdc-vdd-a-1p2v", + "cdc-vddcx-1", + "cdc-vddcx-2"; + + qcom,cdc-micbias-ldoh-v = <0x3>; + qcom,cdc-micbias-cfilt1-mv = <1800>; + //#ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv , 2015/3/24, modify micbias voltage*/ + /*kangjirui@MultiMedia.AudioDrv , 2015/4/18, modify micbias voltage for headset button error*/ + qcom,cdc-micbias-cfilt2-mv = <2700>; + //#endif /* VENDOR_EDIT */ + qcom,cdc-micbias-cfilt3-mv = <1800>; + qcom,cdc-micbias1-cfilt-sel = <0x0>; + qcom,cdc-micbias2-cfilt-sel = <0x1>; + qcom,cdc-micbias3-cfilt-sel = <0x2>; + qcom,cdc-micbias4-cfilt-sel = <0x2>; + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tomtom-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 30 01 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + qcom,cdc-variant = "WCD9330"; + }; + }; + + spmi_bus: qcom,spmi@fc4c0000 { + compatible = "qcom,spmi-pmic-arb"; + reg-names = "core", "intr", "cnfg"; + reg = <0xfc4cf000 0x1000>, + <0xfc4cb000 0x1000>, + <0xfc4ca000 0x1000>; + /* 190,ee0_krait_hlos_spmi_periph_irq */ + /* 187,channel_0_krait_hlos_trans_done_irq */ + interrupts = <0 190 0>, <0 187 0>; + qcom,pmic-arb-channel = <0>; + qcom,pmic-arb-ee = <0>; + #interrupt-cells = <3>; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + }; + + usb3: ssusb@f9200000 { + compatible = "qcom,dwc-usb3-msm"; + status = "disabled"; + reg = <0xf9200000 0xfc000>, + <0xfd4ab000 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupt-parent = <&usb3>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x0 0xffffffff>; + interrupt-map = <0x0 0 &intc 0 133 0 + 0x0 1 &intc 0 180 0 + 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>; + interrupt-names = "hs_phy_irq", "pwr_event_irq", "pmic_id_irq"; + + USB3_GDSC-supply = <&gdsc_usb30>; + vdda33-supply = <&pm8994_l24>; + vbus_dwc3-supply = <&smbcharger_charger_otg>; + qcom,dwc-usb3-msm-tx-fifo-size = <29696>; + qcom,dwc-usb3-msm-qdss-tx-fifo-size = <8192>; + qcom,usb-dbm = <&dbm_1p5>; + + qcom,msm-bus,name = "usb3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <61 512 0 0>, + <61 512 240000 960000>; + + qcom,power-collapse-on-cable-disconnect; + qcom,por-after-power-collapse; + + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>, + <&clock_gcc clk_gcc_usb30_mock_utmi_clk>, + <&clock_gcc clk_gcc_usb30_sleep_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_rpm clk_cxo_dwc3_clk>; + clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk", + "ref_clk", "xo"; + + dwc3@f9200000 { + compatible = "synopsys,dwc3"; + reg = <0xf9200000 0xfc000>; + interrupt-parent = <&intc>; + interrupts = <0 131 0>; + tx-fifo-resize; + snps,usb3-u1u2-disable; + usb-phy = <&hsphy0>, <&ssphy0>; + }; + }; + + hsphy0: hsphy@f92f8800 { + compatible = "qcom,usb-hsphy"; + status = "disabled"; + reg = <0xf92f8800 0x3ff>, + <0xf9b3a000 0x110>; + reg-names = "core", "phy_csr"; + // #ifdef VENDOR_EDIT + /*modify by jiachenghui from 0x00D191A4 to 0x00D191A7 for OTG 2015-04-22*/ + /*change HS DC voltage-level to 0x0011 by jiachenghui for OTG detect issue 2015-05-23*/ + qcom,hsphy-init = <0x00D187A7>; + //#endif /*VENDOR_EDIT*/ + vdd-supply = <&pm8994_s2_corner>; + vddcx-supply = <&pm8994_s1_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,ext-vbus-id; + qcom,vbus-valid-override; + qcom,set-pllbtune; + qcom,sleep-clk-reset; + qcom,vdda-force-on; + clocks = <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>; + clock-names = "phy_sleep_clk"; + }; + + ssphy0: ssphy@f9b38000 { + compatible = "qcom,usb-ssphy-qmp"; + status = "disabled"; + reg = <0xf9b38000 0x800>, + <0xf9b3e000 0x3ff>; + reg-names = "qmp_phy_base", + "qmp_ahb2phy_base"; + vdd-supply = <&pm8994_l28>; + vdda18-supply = <&pm8994_l6>; + qcom,vdd-voltage-level = <0 1000000 1000000>; + qcom,vbus-valid-override; + qcom,no-pipe-clk-switch; + + clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>, + <&clock_gcc clk_gcc_usb3_phy_pipe_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_usb3_phy_reset>, + <&clock_gcc clk_gcc_usb3phy_phy_reset>, + <&clock_gcc clk_usb_ss_phy_ldo>; + clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset", + "phy_phy_reset", "ldo_clk"; + }; + + dbm_1p5: dbm@f92f8000 { + compatible = "qcom,usb-dbm-1p5"; + reg = <0xf92f8000 0x1000>; + qcom,reset-ep-after-lpm-resume; + }; + + qcom,usbbam@f9304000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xf9304000 0x9000>, + <0xf92f880c 0x4>; + reg-names = "ssusb", "qscratch_ram1_reg"; + interrupts = <0 132 0>; + interrupt-names = "ssusb"; + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>; + clock-names = "mem_clk", "mem_iface_clk"; + + qcom,usb-bam-fifo-baseaddr = <0xf9200000>; + qcom,usb-bam-num-pipes = <16>; + qcom,ignore-core-reset-ack; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + + qcom,pipe0 { + label = "ssusb-ipa-out-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <0>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,src-bam-physical-address = <0xf9304000>; + qcom,src-bam-pipe-index = <1>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe1 { + label = "ssusb-ipa-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe2 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <1>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,src-bam-physical-address = <0xfc37C000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-offset = <0xf0000>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0xf4000>; + qcom,descriptor-fifo-size = <0x1400>; + qcom,reset-bam-on-connect; + }; + + /* USB BAM pipe (consumer) configuration for accelerated DPL */ + qcom,pipe3 { + label = "ssusb-dpl-ipa-in-1"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <1>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + }; + + usb_otg: usb@f9a55000 { + compatible = "qcom,hsusb-otg"; + status = "disabled"; + + reg = <0xf9a55000 0x400>; + reg-names = "core"; + interrupts = <0 134 0 0 140 0>; + interrupt-names = "core_irq", "async_irq"; + + HSUSB_VDDCX-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "sleep_clk", "xo"; + + qcom,hsusb-otg-phy-type = <2>; + qcom,hsusb-otg-phy-init-seq = <0x63 0x81 0xffffffff>; + qcom,hsusb-otg-mode = <1>; + qcom,hsusb-otg-otg-control = <1>; + }; + + usb_ehci: ehci@f9a55000 { + compatible = "qcom,ehci-host"; + status = "disabled"; + reg = <0xf9a55000 0x400>; + interrupts = <0 134 0>, <0 140 0>; + interrupt-names = "core_irq", "async_irq"; + hsusb_vdd_dig-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 2 3 5 7>; + qcom,usb2-power-budget = <500>; + usb-phy = <&qusb_phy>; + qcom,pm-qos-latency = <30001>; + + qcom,msm-bus,name = "usb-hs"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <87 512 0 0>, + <87 512 40000 60000>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "xo"; + }; + + qusb_phy: qusb@f9b39000 { + compatible = "qcom,qusb2phy"; + status = "disabled"; + reg = <0xf9b39000 0x17f>; + reg-names = "qusb_phy_base"; + vdd-supply = <&pm8994_s2_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,qusb-tune = <0xa08391d5>; + phy_type = "ulpi"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_qusb2_phy_reset>; + clock-names = "ref_clk", "cfg_ahb_clk", "phy_reset"; + }; + + android_usb@fe87f0c8 { + compatible = "qcom,android-usb"; + reg = <0xfe87f0c8 0xc8>; + qcom,pm-qos-latency = <61 637 1261>; + /*add by jiachenghui for cdrom,20150528*/ + /*#ifdef VENDOR_EDIT*/ + qcom,android-usb-cdrom; + /*#ifdef VENDOR_EDIT*/ + /*end add by jiachenghui for cdrom,20150528*/ + }; + + qcom,venus@fdce0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfdce0000 0x4000>; + + vdd-supply = <&gdsc_venus>; + qcom,proxy-reg-names = "vdd"; + clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_rpm clk_scm_ce1_clk>; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + linux,contiguous-region = <&peripheral_mem>; + }; + + qcom,mss@fc880000 { + compatible = "qcom,pil-q6v55-mss"; + reg = <0xfc880000 0x100>, + <0xfd485000 0x400>, + <0xfc820000 0x020>, + <0xfc401680 0x004>; + reg-names = "qdsp6_base", "halt_base", "rmb_base", + "restart_reg"; + + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_mss_cfg_ahb_clk>, + <&clock_rpm clk_pnoc_modem_clk>, + <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>, + <&clock_gcc clk_gcc_boot_rom_ahb_clk>, + <&clock_gcc clk_gpll0_out_msscc>; + clock-names = "xo", "iface_clk", "pnoc_clk", "bus_clk", + "mem_clk", "gpll0_mss_clk"; + qcom,proxy-clock-names = "xo", "pnoc_clk"; + qcom,active-clock-names = "iface_clk", "bus_clk", "mem_clk", + "gpll0_mss_clk"; + + interrupts = <0 24 1>; + vdd_mss-supply = <&pm8994_s7>; + vdd_cx-supply = <&pm8994_s1_corner>; + vdd_mx-supply = <&pm8994_s2_corner>; + vdd_mx-uV = <7>; + vdd_pll-supply = <&pm8994_l12>; + qcom,vdd_pll = <1800000>; + qcom,firmware-name = "modem"; + qcom,pil-self-auth; + qcom,mba-image-is-not-elf; + qcom,sysmon-id = <0>; + qcom,ssctl-instance-id = <0x12>; + qcom,override-acc; + qcom,ahb-clk-vote; + qcom,pnoc-clk-vote; + + /* GPIO inputs from mss */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>; + + /* GPIO output to mss */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>; + + linux,contiguous-region = <&modem_mem>; + }; + + qcom,lpass@fe200000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfe200000 0x00100>; + interrupts = <0 162 1>; + + vdd_cx-supply = <&pm8994_s1_corner>; + qcom,proxy-reg-names = "vdd_cx"; + qcom,vdd_cx-uV-uA = <7 100000>; + + clocks = <&clock_rpm clk_cxo_pil_lpass_clk>, + <&clock_rpm clk_scm_ce1_clk>; + clock-names = "xo", "scm_ce1_clk"; + qcom,proxy-clock-names = "xo", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + qcom,pas-id = <1>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <423>; + qcom,sysmon-id = <1>; + qcom,ssctl-instance-id = <0x14>; + qcom,firmware-name = "adsp"; + + /* GPIO inputs from lpass */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_2_in 2 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_2_in 1 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_2_in 3 0>; + + /* GPIO output to lpass */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>; + + linux,contiguous-region = <&peripheral_mem>; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops { + compatible = "ramoops"; + /*reg = <0x05800000 0x00100000>;*/ + linux,contiguous-region = <&ramoops_mem>; + }; +/* #endif VENDOR_EDIT */ + + + clock_rpm: qcom,rpmcc@fc401880 { + compatible = "qcom,rpmcc-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + #clock-cells = <1>; + }; + + clock_gcc: qcom,gcc@fc400000 { + compatible = "qcom,gcc-8994"; + reg = <0xfc400000 0x2000>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + clock-names = "xo", "xo_a_clk"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_cxo_clk_src_ao>; + #clock-cells = <1>; + }; + + clock_mmss: qcom,mmsscc@fd8c0000 { + compatible = "qcom,mmsscc-8994"; + reg = <0xfd8c0000 0x5200>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + mmpll4_dig-supply = <&pm8994_s1_corner>; + mmpll4_analog-supply = <&pm8994_l12>; + clock-names = "xo", "gpll0", "mmssnoc_ahb", + "oxili_gfx3d_clk", "pclk0_src", "pclk1_src", + "byte0_src", "byte1_src", "extpclk_src"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_gcc clk_gpll0_out_mmsscc>, + <&clock_rpm clk_mmssnoc_ahb_clk>, + <&clock_rpm clk_oxili_gfx3d_clk_src>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_hdmi_pll clk_hdmi_20nm_vco_clk>; + #clock-cells = <1>; + }; + + clock_debug: qcom,cc-debug@fc401880 { + compatible = "qcom,cc-debug-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + clock-names = "debug_mmss_clk", "debug_rpm_clk", + "debug_cpu_clk"; + clocks = <&clock_mmss clk_mmss_debug_mux>, + <&clock_rpm clk_rpm_debug_mux>, + <&clock_cpu clk_cpu_debug_mux>; + #clock-cells = <1>; + }; + + cci_cache: qcom,cci { + compatible = "devfreq-simple-dev"; + clock-names = "devfreq_clk"; + clocks = <&clock_cpu clk_cci_clk>; + governor = "cpufreq"; + freq-tbl-khz = + < 150000 >, + < 200000 >, + < 249600 >, + < 300000 >, + < 384000 >, + < 499200 >, + < 600000 >; + }; + + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "cpufreq"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc388000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + cpubw-cpufreq { + target-dev = <&cpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 1525 >, + < 691200 2288 >, + < 768000 3562 >, + < 844800 4066 >, + < 921600 5126 >, + < 940800 6072 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 2288 >, + < 691200 3562 >, + < 768000 4066 >, + < 844800 5126 >, + < 921600 6072 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >, + < 940800 5928 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >; + }; + + cci-cpufreq { + target-dev = <&cci_cache>; + cpu-to-dev-map-0 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 384000 >, + < 844800 499200 >, + < 921600 600000 >, + < 940800 600000 >; + cpu-to-dev-map-4 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 499200 >, + < 844800 600000 >, + < 921600 600000 >; + }; + }; + + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "l2_clk", "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk"; + clocks = <&clock_cpu clk_cci_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>; + + qcom,governor-per-policy; + + qcom,cpufreq-table-0 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >, + < 940800 >; + + qcom,cpufreq-table-4 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >; + }; + + clock_cpu: qcom,cpu-clock-8994@f9015000 { + compatible = "qcom,cpu-clock-8994"; + reg = <0xf9015000 0x1000>, + <0xf9016000 0x1000>, + <0xf9011000 0x1000>, + <0xf900d000 0x1000>, + <0xf900f000 0x1000>, + <0xf9112000 0x1000>, + <0xfc4b80b0 0x8>; + reg-names = "c0_pll", "c1_pll", "cci_pll", "c0_mux", "c1_mux", "cci_mux", "efuse"; + vdd-a53-supply = <&apc0_vreg_corner>; + vdd-a57-supply = <&apc1_vreg_corner>; + vdd-cci-supply = <&apc0_vreg_corner>; + vdd-dig-supply = <&pm8994_s1_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>, + < 940800000 9>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 150000000 1>, + < 200000000 2>, + < 249600000 3>, + < 300000000 4>, + < 384000000 4>, + < 499200000 7>, + < 600000000 9>; + clock-names = "xo_ao", "aux_clk"; + clocks = <&clock_rpm clk_cxo_clk_src_ao>, + <&clock_gcc clk_gpll0_ao>; + #clock-cells = <1>; + }; + + ocmem: qcom,ocmem@fdd00000 { + compatible = "qcom,msm-ocmem"; + reg = <0xfdd00000 0x2000>, + <0xfdd02000 0x2000>, + <0xfe039000 0x400>, + <0xfec00000 0x200000>; + reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical"; + interrupts = <0 76 0 0 77 0>; + interrupt-names = "ocmem_irq", "dm_irq"; + qcom,ocmem-num-regions = <0x4>; + qcom,ocmem-num-macros = <0x20>; + qcom,resource-type = <0x706d636f>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfec00000 0x200000>; + clocks = <&clock_rpm clk_ocmemgx_core_clk>, + <&clock_mmss clk_ocmemcx_ocmemnoc_clk>; + clock-names = "core_clk", "iface_clk"; + + partition@0 { + reg = <0x0 0x180000>; + qcom,ocmem-part-name = "graphics"; + qcom,ocmem-part-min = <0x80000>; + }; + + partition@100000 { + reg = <0x180000 0x80000>; + qcom,ocmem-part-name = "video"; + qcom,ocmem-part-min = <0x55000>; + }; + + }; + + msm_vidc: qcom,vidc@fdc00000 { + compatible = "qcom,msm-vidc"; + reg = <0xfdc00000 0xff000>; + interrupts = <0 44 0>; + qcom,hfi = "venus"; + qcom,reg-presets = <0x800D8 0x707>, + <0xe0020 0x55555556>, + <0xe0024 0x55555556>, + <0x80124 0x3>; + qcom,qdss-presets = <0xfc325000 0x1000>, + <0xfc326000 0x1000>, + <0xfc321000 0x1000>, + <0xfc322000 0x1000>, + <0xfc323000 0x1000>, + <0xfc302000 0x1000>, + <0xfa180000 0x1000>, + <0xfa181000 0x1000>; + qcom,ocmem-size = <524288>; /* 512 * 1024*/ + qcom,max-hw-load = <1281600>; /* Full 4k @ 30 + 1080p @ 30 */ + clock-names = "core_clk", "core0_clk", "core1_clk", "core2_clk", + "iface_clk", "bus_clk", "mem_clk"; + venus-supply = <&gdsc_venus>; + venus-core0-supply = <&gdsc_venus_core0>; + venus-core1-supply = <&gdsc_venus_core1>; + venus-core2-supply = <&gdsc_venus_core2>; + qcom,clock-configs = <0x3 0x0 0x0 0x0 0x0 0x0 0x0>; + qcom,sw-power-collapse; + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_core0_vcodec_clk>, + <&clock_mmss clk_venus0_core1_vcodec_clk>, + <&clock_mmss clk_venus0_core2_vcodec_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>; + qcom,load-freq-tbl = + <979200 465000000 0x0c000000>, + <979200 465000000 0x01000414>, + <979200 465000000 0x030fcfff>, + <979200 465000000 0x04000000>, + <783360 465000000 0x0c000000>, + <783360 465000000 0x01000414>, + <783360 465000000 0x030fcfff>, + <783360 465000000 0x04000000>, + <489600 240000000 0x0c000000>, + <489600 240000000 0x01000414>, + <489600 240000000 0x030fcfff>, + <489600 240000000 0x04000000>, + <244800 133330000 0x0c000000>, + <244800 133330000 0x01000414>, + <244800 133330000 0x030fcfff>, + <244800 133330000 0x04000000>; + qcom,vidc-iommu-domains { + qcom,domain-ns { + qcom,vidc-domain-phandle = <&venus_domain_ns>; + qcom,vidc-partition-buffer-types = <0x7ff>, + <0x800>; + }; + qcom,domain-sec-bs { + qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>; + qcom,vidc-partition-buffer-types = <0x241>; + }; + qcom,domain-sec-px { + qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>; + qcom,vidc-partition-buffer-types = <0x106>; + }; + qcom,domain-sec-np { + qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>; + qcom,vidc-partition-buffer-types = <0x480>; + }; + }; + qcom,msm-bus-clients { + qcom,msm-bus-client@0 { + qcom,msm-bus,name = "venc-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 2108700 0>, + <63 512 2243700 0>, + <63 512 2615000 0>; + qcom,bus-configs = <0x1000414>; + }; + + qcom,msm-bus-client@1 { + qcom,msm-bus,name = "vdec-core0-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 151600 0>, + <63 512 393600 0>, + <63 512 393600 0>, + <63 512 749100 0>, + <63 512 749100 0>, + <63 512 1460700 0>, + <63 512 2390500 0>, + <63 512 2542300 0>, + <63 512 2959800 0>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@2 { + qcom,msm-bus,name = "vdec-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 113900 0>, + <63 512 296700 0>, + <63 512 296700 0>, + <63 512 571400 0>, + <63 512 571400 0>, + <63 512 1088500 0>, + <63 512 1811000 0>, + <63 512 1962000 0>, + <63 512 2242900 0>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@3 { + qcom,msm-bus,name = "venc-core2-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 89000 0>, + <63 512 270000 0>, + <63 512 270000 0>, + <63 512 759000 0>, + <63 512 759000 0>, + <63 512 1050000 0>, + <63 512 3077000 0>, + <63 512 3811000 0>, + <63 512 3812000 0>; + qcom,bus-configs = <0x04000000>; + }; + qcom,msm-bus-client@4 { + qcom,msm-bus,name = "venc-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 69000 2384000>, + <68 604 207000 2384000>, + <68 604 207000 2384000>, + <68 604 470000 2384000>, + <68 604 470000 2384000>, + <68 604 940000 3632000>, + <68 604 1787000 3632000>, + <68 604 1906000 3632000>, + <68 604 2234000 3632000>; + qcom,bus-configs = <0x10000414>; + }; + qcom,msm-bus-client@5 { + qcom,msm-bus,name = "venc-core2-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 71000 2384000>, + <68 604 214000 2384000>, + <68 604 214000 2384000>, + <68 604 564000 2384000>, + <68 604 564000 2384000>, + <68 604 1003000 3632000>, + <68 604 2040000 3632000>, + <68 604 2349000 3632000>, + <68 604 2551000 3632000>; + qcom,bus-configs = <0x04000000>; + }; + + qcom,msm-bus-client@6 { + qcom,msm-bus,name = "vdec-core0-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 79000 2384000>, + <68 604 201000 2384000>, + <68 604 201000 2384000>, + <68 604 367000 2384000>, + <68 604 367000 2384000>, + <68 604 735000 3632000>, + <68 604 1175000 3632000>, + <68 604 1254000 3632000>, + <68 604 1469000 3632000>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@7 { + qcom,msm-bus,name = "vdec-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 88000 2384000>, + <68 604 228000 2384000>, + <68 604 228000 2384000>, + <68 604 432000 2384000>, + <68 604 432000 2384000>, + <68 604 865000 3632000>, + <68 604 1374000 3632000>, + <68 604 1465000 3632000>, + <68 604 1717000 3632000>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@8 { + qcom,msm-bus,name = "venc-ddr-lp"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 1218000 0>, + <63 512 1218000 0>, + <63 512 1218000 0>; + qcom,bus-low-power; + qcom,bus-configs = <0x0000004>; + }; + + qcom,msm-bus-client@9 { + qcom,msm-bus,name = "venus-arm9-ddr"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 1000 1000>; + qcom,bus-configs = <0x00000000>; + qcom,bus-passive; + }; + }; + }; + + i2c_1: i2c@f9923000 { + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9923000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 95 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_1_active>; + pinctrl-1 = <&i2c_1_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + qcom,master-id = <86>; + dmas = <&dma_blsp1 10 64 0x20000020 0x20>, + <&dma_blsp1 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + dma_blsp1: qcom,sps-dma@f9904000 { /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9904000 0x19000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <10>; + }; + + dma_blsp2: qcom,sps-dma@f9944000 { /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9944000 0x19000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <10>; + }; + + + i2c_2: i2c@f9924000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9924000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 96 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_2_active>; + pinctrl-1 = <&i2c_2_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + + /* #ifdef VENDOR_EDIT */ + //add by yangrujin@bsp for dma has some issue causing i2c fail + //qcom,disable-dma; + /* #endif //VENDOR_EDIT */ + + + dmas = <&dma_blsp1 14 64 0x20000020 0x20>, + <&dma_blsp1 15 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + i2c_5: i2c_11: i2c@f9967000 { /* BLSP2 QUP5 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9967000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 105 0>; + qcom,clk-freq-out = <100000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup5_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_5_active>; + pinctrl-1 = <&i2c_5_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/4/13, dma mode will cause I2C fail*/ + qcom,disable-dma; + //#endif + dmas = <&dma_blsp2 20 64 0x20000020 0x20>, + <&dma_blsp2 21 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + }; + + i2c_6: i2c@f9928000 { /* BLSP1 QUP6 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + reg-names = "qup_phys_addr"; + reg = <0xf9928000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 100 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + dmas = <&dma_blsp1 22 64 0x20000020 0x20>, + <&dma_blsp1 23 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + sound { + compatible = "qcom,msm8994-asoc-snd"; + qcom,model = "msm8994-tomtom-snd-card"; + reg = <0xfe034000 0x4>, + <0xfe035000 0x4>, + <0xfe036000 0x4>, + <0xfe037000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK"; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/3/19, delete unsed mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#endif + + clock-names = "osr_clk"; + clocks = <&clock_rpm clk_div_clk1>; + qcom,cdc-mclk-gpios = <&pm8994_gpios 15 0>; + qcom,tomtom-mclk-clk-freq = <9600000>; + pinctrl-names = "sleep", + "auxpcm-active", + "mi2s-active", + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv,changed for quat i2s */ + "active", + "quat_mi2s_sleep", + "quat_mi2s_active"; + //#endif +//#ifdef VENDOR_EDIT +//pinctrl-0 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-1 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//pinctrl-2 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-3 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ + pinctrl-0 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-1 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; + pinctrl-2 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-3 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s */ + pinctrl-4 = <&quat_mi2s_sleep>, <&quat_mi2s_mclk_sleep>, <&quat_mi2s_sd0_sleep> , <&quat_mi2s_sd1_sleep>; + pinctrl-5 = <&quat_mi2s_active>, <&quat_mi2s_mclk_active>, <&quat_mi2s_sd0_active> , <&quat_mi2s_sd1_active>; +//#endif + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", "msm-pcm-dsp.2", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp"; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s*/ + asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>, <&dai_mi2s>,<&qua_mi2s>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, <&bt_sco_rx>, + <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>, + <&incall_music2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.0","msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.12288", + "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770"; +//#endif + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + }; + + qcom,msm-adsp-loader { + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + qcom,msm-audio-ion { + compatible = "qcom,msm-audio-ion"; + }; + + pcm0: qcom,msm-pcm { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <0>; + }; + + qcom,msm-pcm-lpa { + compatible = "qcom,msm-pcm-lpa"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm1: qcom,msm-pcm-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <1>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "regular"; + }; + + routing: qcom,msm-pcm-routing { + compatible = "qcom,msm-pcm-routing"; + }; + + compr: qcom,msm-compr-dsp { + compatible = "qcom,msm-compr-dsp"; + }; + + compress: qcom,msm-compress-dsp { + compatible = "qcom,msm-compress-dsp"; + }; + + voip: qcom,msm-voip-dsp { + compatible = "qcom,msm-voip-dsp"; + }; + + voice: qcom,msm-pcm-voice { + compatible = "qcom,msm-pcm-voice"; + qcom,destroy-cvd; + }; + + stub_codec: qcom,msm-stub-codec { + compatible = "qcom,msm-stub-codec"; + }; + + qcom,msm-dai-fe { + compatible = "qcom,msm-dai-fe"; + }; + + afe: qcom,msm-pcm-afe { + compatible = "qcom,msm-pcm-afe"; + }; + + dai_hdmi: qcom,msm-dai-q6-hdmi { + compatible = "qcom,msm-dai-q6-hdmi"; + qcom,msm-dai-q6-dev-id = <8>; + }; + + lsm: qcom,msm-lsm-client { + compatible = "qcom,msm-lsm-client"; + }; + + loopback: qcom,msm-pcm-loopback { + compatible = "qcom,msm-pcm-loopback"; + }; + + qcom,msm-voice-svc { + compatible = "qcom,msm-voice-svc"; + }; + + cpe: qcom,msm-cpe-lsm { + compatible = "qcom,msm-cpe-lsm"; + }; + + qcom,msm-dai-q6 { + compatible = "qcom,msm-dai-q6"; + sb_0_rx: qcom,msm-dai-q6-sb-0-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16384>; + }; + + sb_0_tx: qcom,msm-dai-q6-sb-0-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16385>; + }; + + sb_1_rx: qcom,msm-dai-q6-sb-1-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16386>; + }; + + sb_1_tx: qcom,msm-dai-q6-sb-1-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16387>; + }; + + sb_2_rx: qcom,msm-dai-q6-sb-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16388>; + }; + + sb_2_tx: qcom,msm-dai-q6-sb-2-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16389>; + }; + + sb_3_rx: qcom,msm-dai-q6-sb-3-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16390>; + }; + + sb_3_tx: qcom,msm-dai-q6-sb-3-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16391>; + }; + + sb_4_rx: qcom,msm-dai-q6-sb-4-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16392>; + }; + + sb_4_tx: qcom,msm-dai-q6-sb-4-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16393>; + }; + + sb_5_tx: qcom,msm-dai-q6-sb-5-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16395>; + }; + + bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12288>; + }; + + bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12289>; + }; + + int_fm_rx: qcom,msm-dai-q6-int-fm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12292>; + }; + + int_fm_tx: qcom,msm-dai-q6-int-fm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12293>; + }; + + afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <224>; + }; + + afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <225>; + }; + + afe_proxy_rx: com,msm-dai-q6-afe-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <241>; + }; + + afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <240>; + }; + + incall_record_rx: qcom,msm-dai-q6-incall-record-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32771>; + }; + + incall_record_tx: qcom,msm-dai-q6-incall-record-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32772>; + }; + + incall_music_rx: qcom,msm-dai-q6-incall-music-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32773>; + }; + + incall_music2_rx: qcom,msm-dai-q6-incall-music-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32770>; + }; + }; + + dai_pri_auxpcm: qcom,msm-pri-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "primary"; + }; + + dai_sec_auxpcm: qcom,msm-sec-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "secondary"; + }; + + qcom,msm-dai-mi2s { + compatible = "qcom,msm-dai-mi2s"; + dai_mi2s: qcom,msm-dai-q6-mi2s-prim { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <0>; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv ,changed for quat i2s*/ + + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + qua_mi2s: qcom,msm-dai-q6-mi2s-quat { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <3>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; +//#endif + }; + + hostless: qcom,msm-pcm-hostless { + compatible = "qcom,msm-pcm-hostless"; + }; + + tsens: tsens@fc4a8000 { + compatible = "qcom,msm8994-tsens"; + reg = <0xfc4a8000 0x2000>, + <0xfc4bc000 0x1000>; + reg-names = "tsens_physical", "tsens_eeprom_physical"; + interrupts = <0 184 0>; + interrupt-names = "tsens-upper-lower"; + qcom,sensors = <16>; + qcom,slope = <2901 2846 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200>; + }; + + qcom_tzlog: tz-log@fe87f720 { + compatible = "qcom,tz-log"; + reg = <0xfe87f720 0x2000>; + }; + + qcom_crypto1fde: qcrypto1fde@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2fde: qcrypto2fde@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto1pfe: qcrypto1pfe@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2pfe: qcrypto2pfe@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_cedev: qcedev@fd440000 { + compatible = "qcom,qcedev"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <1>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcedev_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,qseecom@6500000{ + compatible = "qcom,qseecom"; + reg = <0x0E900000 0x1900000>;//reg = <0x6500000 0x500000>; ----> <0x0E700000 0x700000>; ----> <0x0E900000 0x1900000>; /*VENDOR_EDIT changhua add more memory for fpc1150 and alipay in TZ*/ + reg-names = "secapp-region"; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,file-encrypt-pipe-pair = <0>; + qcom,support-multiple-ce-hw-instance; + qcom,hlos-num-ce-hw-instances = <2>; + qcom,hlos-ce-hw-instance = <1 2>; + qcom,qsee-ce-hw-instance = <0>; + qcom,msm-bus,name = "qseecom-noc"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,support-fde; + qcom,support-pfe; + qcom,no-clock-support; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 0 0>, + <55 512 120000 1200000>, + <55 512 393600 3936000>; + clock-names = "core_clk", "ufs_core_clk_src", "ufs_core_clk", + "ufs_bus_clk", "ufs_iface_clk"; + clocks = <&clock_rpm clk_qseecom_ce1_clk>, + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information@0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + }; + + sensor_information1: qcom,sensor-information@1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + }; + + sensor_information2: qcom,sensor-information@2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,alias-name = "pop_mem"; + }; + + sensor_information3: qcom,sensor-information@3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + }; + + sensor_information4: qcom,sensor-information@4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + }; + + sensor_information5: qcom,sensor-information@5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + }; + + sensor_information6: qcom,sensor-information@6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,alias-name = "cpu7"; + }; + + sensor_information7: qcom,sensor-information@7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,alias-name = "cpu0"; + }; + + sensor_information8: qcom,sensor-information@8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,alias-name = "cpu1"; + }; + + sensor_information9: qcom,sensor-information@9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,alias-name = "cpu2"; + }; + + sensor_information10: qcom,sensor-information@10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,alias-name = "cpu3"; + }; + + sensor_information11: qcom,sensor-information@11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + }; + + sensor_information12: qcom,sensor-information@12 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor12"; + qcom,alias-name = "gpu"; + }; + + sensor_information13: qcom,sensor-information@13 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor13"; + qcom,alias-name = "cpu4"; + }; + + sensor_information14: qcom,sensor-information@14 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor14"; + qcom,alias-name = "cpu5"; + }; + + sensor_information15: qcom,sensor-information@15 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor15"; + qcom,alias-name = "cpu6"; + }; + + sensor_information16: qcom,sensor-information@16 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pm8994_tz"; + qcom,scaling-factor = <1000>; + }; + + sensor_information17: qcom,sensor-information@17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + + sensor_information18: qcom,sensor-information@18 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "emmc_therm"; + }; + + sensor_information19: qcom,sensor-information@19 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + + sensor_information20: qcom,sensor-information@20 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + + sensor_information21: qcom,sensor-information@21 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + + sensor_information22: qcom,sensor-information@22 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "LLM_IA57"; + }; + + sensor_information23: qcom,sensor-information-23 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "battery"; + }; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <7>; + qcom,poll-ms = <250>; + qcom,limit-temp = <60>; + qcom,temp-hysteresis = <10>; + qcom,therm-reset-temp = <115>; + qcom,freq-step = <2>; + qcom,freq-control-mask = <0xff>; + qcom,core-limit-temp = <80>; + qcom,core-temp-hysteresis = <10>; + qcom,core-control-mask = <0xfe>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <40>; + qcom,cpu-sensors = "tsens_tz_sensor7", "tsens_tz_sensor8", + "tsens_tz_sensor9", "tsens_tz_sensor10", + "tsens_tz_sensor13", "tsens_tz_sensor14", + "tsens_tz_sensor15", "tsens_tz_sensor6"; + qcom,freq-mitigation-temp = <95>; + qcom,freq-mitigation-temp-hysteresis = <10>; + qcom,freq-mitigation-value = <960000>; + qcom,freq-mitigation-control-mask = <0xF0>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,mx-restriction-temp = <5>; + qcom,mx-restriction-temp-hysteresis = <10>; + qcom,mx-retention-min = <3>; + vdd-mx-supply = <&pm8994_s2_corner>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm8994_s1_floor_corner>; + vdd-gfx-supply = <&pmi8994_s2_floor_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <302400 600000 600000>; + qcom,freq-req; + }; + }; + + qcom,bcl { + compatible = "qcom,bcl"; + qcom,bcl-enable; + qcom,bcl-framework-interface; + qcom,bcl-freq-control-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,bcl-hotplug-list = <&CPU6 &CPU7>; + qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,ibat-monitor { + qcom,low-threshold-uamp = <3400000>; + qcom,high-threshold-uamp = <4200000>; + qcom,mitigation-freq-khz = <768000>; + qcom,vph-high-threshold-uv = <3500000>; + qcom,vph-low-threshold-uv = <3300000>; + qcom,soc-low-threshold = <20>; + qcom,thermal-handle = <&msm_thermal_freq>; + }; + }; + + cnss: qcom,cnss@06300000 { + compatible = "qcom,cnss"; + reg = <0x06300000 0x200000>; + reg-names = "ramdump"; + wlan-en-gpio = <&msm_gpio 113 0>; + vdd-wlan-supply = <&bt_vreg>; + vdd-wlan-io-supply = <&pm8994_s4>; + vdd-wlan-xtal-supply = <&pm8994_l30>; + qcom,notify-modem-status; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default>; + qcom,wlan-rc-num = <1>; + qcom,wlan-uart-access; + + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, /* No vote */ + <100 512 6250 200000>, /* 50 Mbps */ + <100 512 25000 200000>, /* 200 Mbps */ + <100 512 100000 200000>; /* 800 Mbps */ + }; + + audio_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&audio_mem>; + }; + + adsp_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,msm-core@fc4b8000 { + compatible = "qcom,apss-core-ea"; + reg = <0xfc4b8000 0x1000>; + qcom,low-hyst-temp = <10>; + qcom,high-hyst-temp = <5>; + qcom,polling-interval = <50>; + + qcom,core-mapping { + qcom,cpu0-chars { + qcom,sensor = <&sensor_information7>; + qcom,cpu-name = <&CPU0>; + }; + + qcom,cpu1-chars { + qcom,sensor = <&sensor_information8>; + qcom,cpu-name = <&CPU1>; + }; + + qcom,cpu2-chars { + qcom,sensor = <&sensor_information9>; + qcom,cpu-name = <&CPU2>; + }; + + qcom,cpu3-chars { + qcom,sensor = <&sensor_information10>; + qcom,cpu-name = <&CPU3>; + }; + + qcom,cpu4-chars { + qcom,sensor = <&sensor_information13>; + qcom,cpu-name = <&CPU4>; + }; + + qcom,cpu5-chars { + qcom,sensor = <&sensor_information14>; + qcom,cpu-name = <&CPU5>; + }; + + qcom,cpu6-chars { + qcom,sensor = <&sensor_information15>; + qcom,cpu-name = <&CPU6>; + }; + + qcom,cpu7-chars { + qcom,sensor = <&sensor_information6>; + qcom,cpu-name = <&CPU7>; + }; + }; + }; + + qcom,system-health-monitor { + compatible = "qcom,system-health-monitor"; + + qcom,system-health-monitor-modem { + qcom,subsys-name = "msm_mpss"; + qcom,ssrestart-string = "modem"; + }; + }; + + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,itlb_dump100 { + qcom,dump-node = <&L1_itlb_100>; + qcom,dump-id = <0x24>; + }; + qcom,itlb_dump101 { + qcom,dump-node = <&L1_itlb_101>; + qcom,dump-id = <0x25>; + }; + qcom,itlb_dump102 { + qcom,dump-node = <&L1_itlb_102>; + qcom,dump-id = <0x26>; + }; + qcom,itlb_dump103 { + qcom,dump-node = <&L1_itlb_103>; + qcom,dump-id = <0x27>; + }; + qcom,dtlb_dump100 { + qcom,dump-node = <&L1_dtlb_100>; + qcom,dump-id = <0x44>; + }; + qcom,dtlb_dump101 { + qcom,dump-node = <&L1_dtlb_101>; + qcom,dump-id = <0x45>; + }; + qcom,dtlb_dump102 { + qcom,dump-node = <&L1_dtlb_102>; + qcom,dump-id = <0x46>; + }; + qcom,dtlb_dump103 { + qcom,dump-node = <&L1_dtlb_103>; + qcom,dump-id = <0x47>; + }; + qcom,l2_tlb_dump0 { + qcom,dump-node = <&L2_tlb_0>; + qcom,dump-id = <0x120>; + }; + qcom,l2_tlb_dump100 { + qcom,dump-node = <&L2_tlb_1>; + qcom,dump-id = <0x121>; + }; + qcom,l2_dump0 { + qcom,dump-node = <&L2_0>; /* L2 cache dump for A53 cluster */ + qcom,dump-id = <0xC0>; + }; + qcom,l2_dump1 { + qcom,dump-node = <&L2_1>; /* L2 cache dumo for A57 cluster */ + qcom,dump-id = <0xC1>; + }; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + + qcom,avtimer@fe09c000 { + compatible = "qcom,avtimer"; + reg = <0xFE09C00C 0x4>, + <0xFE09C010 0x4>; + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr"; + qcom,clk_div = <27>; + }; + + cci@f9100000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9100000 0x1000>; + ranges = <0x0 0xf9100000 0x10000>; + hw-version = <8>; + + pmu@a000 { + compatible = "arm,cci-400-pmu"; + reg = <0x9000 0x5000>; + interrupts = <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>; + }; + + }; +}; + +&gdsc_usb30 { + reg = <0xfc4003c4 0x4>; + status = "ok"; +}; + +&gdsc_pcie_0 { + status = "ok"; +}; + +&gdsc_pcie_1 { + status = "ok"; +}; + +&gdsc_ufs { + status = "ok"; +}; + +&gdsc_venus { + clock-names = "ocmem_clk", "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + status = "ok"; +}; + +&gdsc_venus_core0 { + qcom,support-hw-trigger; + clock-names = "core0_clk"; + clocks = <&clock_mmss clk_venus0_core0_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core1 { + qcom,support-hw-trigger; + clock-names = "core1_clk"; + clocks = <&clock_mmss clk_venus0_core1_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core2 { + qcom,support-hw-trigger; + clock-names = "core2_clk"; + clocks = <&clock_mmss clk_venus0_core2_vcodec_clk>; + status = "ok"; +}; + +&gdsc_mdss { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_mdp_clk>; + status = "ok"; +}; + +&gdsc_camss_top { + clock-names = "csi0_clk", "csi1_clk", "bus_clk"; + clocks = <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>; + status = "ok"; +}; + +&gdsc_jpeg { + clock-names = "bus_clk", "core0_clk", "core1_clk", "core2_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg2_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_vfe { + clock-names = "bus_clk"; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_cpp { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_fd { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_core_clk>; + status = "ok"; +}; + +&gdsc_oxili_cx { + status = "ok"; +}; + +&gdsc_oxili_gx { + clock-names = "core_clk"; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>; + status = "ok"; + parent-supply = <&pmi8994_s2_corner>; +}; + +#include "msm-pm8994-rpm-regulator.dtsi" +#include "msm-pm8994.dtsi" +#include "msm-pmi8994.dtsi" +#include "msm8994-regulator.dtsi" +#include "msm8994-ion.dtsi" +#include "msm8994-iommu.dtsi" +#include "msm8994-iommu-domains.dtsi" +#include "msm8994-camera.dtsi" +#include "msm8994-gpu.dtsi" +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi0-video.dtsi" +#include "dsi-panel-sim-dualmipi1-video.dtsi" +#include "dsi-panel-sim-cmd.dtsi" +#include "dsi-panel-sim-dualmipi0-cmd.dtsi" +#include "dsi-panel-sim-dualmipi1-cmd.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_12/skeleton64.dtsi b/arch/arm64/boot/dts/14049_HW_12/skeleton64.dtsi new file mode 100755 index 0000000000000..1f8ba28132c4a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_12/skeleton64.dtsi @@ -0,0 +1,15 @@ +/* + * Skeleton device tree in the 64 bits version; the bare minimum + * needed to boot; just include and add a compatible value. The + * bootloader will typically populate the memory node. + */ + +/ { + #address-cells = <2>; + #size-cells = <2>; + cpus { }; + soc { }; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0 0 0>; }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/Makefile b/arch/arm64/boot/dts/14049_HW_13/Makefile new file mode 100755 index 0000000000000..a547ccaf69433 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/Makefile @@ -0,0 +1,22 @@ +ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_MSM8994) += msm8994-v1-mtp_14049_HW_13.dtb \ + msm8994-v2.0-mtp_14049_HW_13.dtb \ + msm8994-v2.1-mtp_14049_HW_13.dtb + +DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) +ifneq ($(DTB_NAMES),) +DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) +else +DTB_LIST := $(dtb-y) +endif + +targets += dtbs +targets += $(addprefix ../, $(DTB_LIST)) +endif + +$(obj)/../%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + +dtbs: $(addprefix $(obj)/../,$(DTB_LIST)) + +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3000mah.dtsi new file mode 100755 index 0000000000000..dc23e181f64d3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3000mah.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3000mah { + qcom,max-voltage-uv = <4320000>; /* yangfangbiao@oneplus.cn, 2015/03/15 Set max voltage 4.32v */ + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3000mah"; + qcom,checksum = <0xF99F>; + qcom,fg-profile-data = [ + EC 83 39 7D + 10 81 04 77 + 23 83 9A 72 + AE 52 20 84 + FC 81 51 93 + FB AD D2 B0 + 5B 12 E5 82 + 09 78 90 75 + A7 70 0C 83 + 1A 80 71 8D + 48 89 08 82 + D4 99 74 BC + A2 C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 45 31 A4 44 + 6E 3B 00 00 + AD 3D 24 36 + A9 46 00 00 + 00 00 00 00 + 00 00 00 00 + E7 6A 05 6A + 8E 75 F9 80 + 5E 76 DA 68 + 45 74 54 81 + 10 75 13 60 + 61 7E 38 A1 + 33 DB 62 1A + 64 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3020mah.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3020mah.dtsi new file mode 100755 index 0000000000000..9a2ce4badf33e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata-itech-3020mah.dtsi @@ -0,0 +1,53 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3020mah { + qcom,max-voltage-uv = <4350000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3020mah"; + qcom,fg-profile-data = [ + E8 83 0C 7D + E9 80 B2 76 + 20 83 40 73 + D7 6C 59 7E + FB 81 58 93 + 0D AE 02 B1 + 5B 12 D7 82 + 86 78 F3 76 + 4A 71 0C 83 + 1B 80 73 8D + 49 89 07 82 + D8 99 79 BC + AA C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 09 2E 79 44 + 52 43 00 00 + DE 3D 2A 37 + D3 46 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 6B B7 69 + DD 6C 83 83 + 42 76 CA 68 + 78 75 EF 80 + D4 74 56 5B + 00 00 00 00 + 0A A5 5A D2 + 54 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata-mtp-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata-mtp-3000mah.dtsi new file mode 100755 index 0000000000000..198fbea2ef0af --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata-mtp-3000mah.dtsi @@ -0,0 +1,118 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,mtp-3000mah { + qcom,fcc-mah = <3000>; + qcom,default-rbatt-mohm = <113>; + qcom,max-voltage-uv = <4200000>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <200000>; + qcom,batt-id-kohm = <300>; + qcom,battery-type = "mtp_3000mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <3030 3033 3037 3035 3031>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4191 4188 4183 4179 4174>, + <4106 4125 4127 4125 4121>, + <4046 4082 4082 4080 4077>, + <3966 4038 4044 4040 4035>, + <3922 3983 3994 3998 3997>, + <3886 3949 3966 3966 3962>, + <3856 3908 3937 3935 3931>, + <3832 3875 3908 3907 3903>, + <3814 3847 3874 3878 3875>, + <3799 3826 3831 3832 3830>, + <3787 3807 3811 3811 3809>, + <3775 3793 3795 3795 3793>, + <3764 3782 3783 3783 3781>, + <3752 3775 3773 3772 3769>, + <3739 3768 3766 3762 3755>, + <3725 3756 3756 3747 3733>, + <3710 3732 3734 3725 3711>, + <3696 3707 3705 3697 3684>, + <3681 3695 3686 3678 3667>, + <3667 3690 3684 3676 3665>, + <3658 3688 3683 3675 3664>, + <3646 3685 3681 3674 3663>, + <3631 3682 3679 3673 3660>, + <3612 3677 3676 3669 3655>, + <3589 3667 3666 3660 3639>, + <3560 3643 3636 3630 3599>, + <3523 3600 3586 3581 3546>, + <3474 3537 3518 3516 3477>, + <3394 3446 3425 3427 3379>, + <3257 3306 3273 3283 3213>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>; + qcom,lut-data = <1025 208 100 85 80>, + <1025 208 100 85 80>, + <1032 225 103 87 81>, + <959 249 107 91 82>, + <954 249 109 92 84>, + <953 255 117 94 84>, + <957 230 123 98 87>, + <968 216 134 102 91>, + <983 212 138 112 95>, + <1002 213 103 89 82>, + <1030 215 100 86 81>, + <1066 219 101 89 83>, + <1115 224 104 92 85>, + <1182 234 106 94 86>, + <1263 246 108 92 84>, + <1357 257 107 87 81>, + <1464 261 102 85 80>, + <1564 256 101 84 80>, + <1637 268 100 84 80>, + <1580 276 102 87 81>, + <1617 285 104 87 82>, + <1670 298 107 91 82>, + <1725 315 108 92 83>, + <1785 338 112 92 83>, + <1850 361 111 91 82>, + <1921 378 108 89 84>, + <2000 394 112 92 87>, + <2119 430 121 99 94>, + <2795 497 144 114 104>, + <8769 1035 672 322 234>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <3030 3033 3037>, + <1898 2943 2960>, + <1184 2855 2948>, + <209 2464 2921>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata-palladium.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata-palladium.dtsi new file mode 100755 index 0000000000000..4c44351892565 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata-palladium.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,palladium-batterydata { + qcom,fcc-mah = <1500>; + qcom,default-rbatt-mohm = <210>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,flat-ocv-threshold-uv = <3800000>; + qcom,max-voltage-uv = <4200000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <75>; + qcom,battery-type = "palladium_1500mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <1467 1470 1473 1473 1470>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4175 4173 4167 4162 4157>, + <4097 4111 4112 4110 4107>, + <4039 4075 4072 4068 4064>, + <3963 4017 4025 4026 4025>, + <3920 3969 3984 3989 3988>, + <3887 3932 3957 3958 3955>, + <3856 3898 3929 3928 3925>, + <3830 3868 3900 3901 3898>, + <3808 3843 3858 3863 3862>, + <3793 3821 3827 3827 3827>, + <3779 3803 3807 3808 3807>, + <3768 3788 3792 3793 3792>, + <3757 3779 3780 3780 3779>, + <3746 3771 3772 3768 3768>, + <3734 3762 3765 3759 3749>, + <3722 3747 3753 3744 3730>, + <3707 3721 3731 3722 3709>, + <3693 3705 3704 3696 3683>, + <3678 3698 3687 3678 3667>, + <3664 3693 3683 3676 3665>, + <3656 3690 3682 3675 3664>, + <3646 3687 3681 3674 3662>, + <3634 3683 3680 3672 3661>, + <3618 3677 3676 3668 3656>, + <3599 3667 3667 3655 3639>, + <3573 3645 3638 3623 3603>, + <3541 3607 3591 3575 3554>, + <3496 3550 3528 3511 3490>, + <3428 3469 3445 3423 3400>, + <3312 3342 3308 3280 3250>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <909 216 100 85 84>, + <859 238 106 88 86>, + <860 237 105 88 86>, + <808 239 107 90 88>, + <801 234 111 94 90>, + <801 230 118 97 92>, + <801 224 123 100 95>, + <807 221 128 106 99>, + <818 221 111 101 97>, + <841 225 101 88 87>, + <870 229 101 88 87>, + <906 235 103 91 90>, + <950 243 106 93 93>, + <998 253 110 93 96>, + <1051 263 113 94 90>, + <1116 272 113 91 88>, + <1200 275 111 91 88>, + <1312 298 108 90 87>, + <1430 329 104 88 87>, + <1484 351 107 91 89>, + <1446 345 110 93 90>, + <1398 344 112 94 90>, + <1466 358 115 96 91>, + <1490 357 117 96 90>, + <1589 365 117 94 89>, + <1828 379 111 91 88>, + <2151 399 111 93 91>, + <2621 436 117 98 95>, + <3404 496 130 106 100>, + <8212 616 150 1906 134>, + <135251 124940 59087 49820 29672>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <1470 1470 1473>, + <601 1406 1430>, + <89 1247 1414>, + <8 764 1338>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata-unkown-3300mah.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata-unkown-3300mah.dtsi new file mode 100755 index 0000000000000..4ee01d90bd24d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata-unkown-3300mah.dtsi @@ -0,0 +1,50 @@ +qcom,oneplus_default_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "Unknown Battery"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_ATL_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_ATL_3300mAh.dtsi new file mode 100755 index 0000000000000..08924c2b14994 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_ATL_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "ATL"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_SDI_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_SDI_3300mAh.dtsi new file mode 100755 index 0000000000000..8756ab9405b54 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/batterydata_oneplus_SDI_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_SDI_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <0>; + qcom,battery-type = "SDI"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jd35695-1080p-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jd35695-1080p-cmd.dtsi new file mode 100755 index 0000000000000..992688672f350 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jd35695-1080p-cmd.dtsi @@ -0,0 +1,211 @@ +/************************************************************ + * Copyright (c) 2013-2013 OPPO Mobile communication Corp.ltd., + * VENDOR_EDIT + * Description: device tree for jdi cmd panel. + * Version : 1.0 + * Date : 2013-12-12 + * Author : yangxinqin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { +dsi_jd35695_1080_cmd: qcom,mdss_dsi_jd35695_1080p_cmd { + compatible = "qcom,mdss-dsi-panel"; + status = "ok"; + qcom,cont-splash-enabled; + qcom,mdss-dsi-panel-name = "jd35695 1080p cmd mode dsi panel"; + qcom,mdss-dsi-panel-manufacture = "JDI"; + qcom,mdss-dsi-panel-version = "JD35695"; + qcom,mdss-dsi-backlight-version= "PMI8994"; + qcom,mdss-dsi-backlight-manufacture = "Qualcomm"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <100>; + qcom,mdss-dsi-h-back-porch = <82>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <7>; + qcom,mdss-dsi-v-front-porch = <3>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0x0000ff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 39 01 00 00 00 00 05 2a 00 00 04 37 + 39 01 00 00 00 00 05 2b 00 00 07 7f + + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF E0 + 15 01 00 00 00 00 02 B5 86 + 15 01 00 00 00 00 02 B6 77 + 15 01 00 00 00 00 02 B8 AD + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 FF 10 + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + + 05 01 00 00 6E 00 02 11 00 + 05 01 00 00 2D 00 02 29 00 + + ]; + qcom,mdss-dsi-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 00 + 05 01 00 00 64 00 02 28 00 + 05 01 00 00 64 00 02 10 00]; + + qcom,mdss-dsi-color-test-on-command= + [ + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 01 + 15 01 00 00 00 00 02 FF 20 + 15 01 00 00 00 00 02 67 4D]; + + + qcom,mdss-dsi-color-test-off-command = + [ + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 00 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 32 00 02 29 00]; + + qcom,mdss-dsi-cabc-off-command = [15 01 00 00 10 00 02 55 00 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-ui-command = [15 01 00 00 10 00 02 55 01 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-still-image-command = [15 01 00 00 10 00 02 55 02 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-video-command = [15 01 00 00 10 00 02 55 03 + 05 01 00 00 10 00 02 29 00]; + + qcom,mdss-dsi-on-command_shoushi = [ + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 60 00 02 29 00 + + ]; + qcom,mdss-dsi-color-test-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-color-test-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + + + + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + + + + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + //qcom,mdss-dsi-init-delay-us=<50000>; + /**************************************************************************/ + // qcom,esd-check-enabled; + // qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; + // qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; + // qcom,mdss-dsi-panel-status-check-mode = "reg_read_jd35695"; + // qcom,mdss-dsi-panel-status-read-length = <8>; + // qcom,mdss-dsi-panel-max-error-count = <2>; + // qcom,mdss-dsi-panel-status-value = <0x9c 0x00 0x00 0x02 0x40 0x80 0x00 0x00>; + /******************************************************************************/ + // qcom,mdss-dsi-dma-trigger = "trigger_sw"; + // qcom,mdss-dsi-mdp-trigger = "trigger_sw"; + + + + //qcom,mdss-tear-check-frame-rate=<6000>; + //qcom,mdss-tear-check-sync-cfg-height = <1932>; /* Height + VBP + VFP + VSW */ + //qcom,mdss-tear-check-sync-init-val= <1920>; /* Height */ + //qcom,mdss-tear-check-sync-threshold-start = <4>; + //qcom,mdss-tear-check-sync-threshold-continue = <4>; + //qcom,mdss-tear-check-start-pos= <1920>; /* Height */ + //qcom,mdss-tear-check-rd-ptr-trigger-intr= <1921>; /* Height + 1 */ + + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <127>; + + + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 14>, <0 5>, <1 20>; + + }; +}; + + diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jdi-1080p-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jdi-1080p-video.dtsi new file mode 100755 index 0000000000000..7e4e9ceeeaab8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-jdi-1080p-video.dtsi @@ -0,0 +1,97 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_jdi_1080_vid: qcom,mdss_dsi_jdi_1080p_video { + qcom,mdss-dsi-panel-name = "jdi 1080p video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 23 01 00 00 00 00 02 FF 10 + 15 01 00 00 10 00 02 35 00 + 15 01 00 00 10 00 02 bb 03 + //29 01 00 00 00 00 03 44 05 00 + 23 01 00 00 00 00 02 FF E0 + 23 01 00 00 00 00 02 B5 86 + 23 01 00 00 00 00 02 B6 77 + 23 01 00 00 00 00 02 B8 AD + 23 01 00 00 00 00 02 FB 01 + 23 01 00 00 00 00 02 FF 10 + +/************************************************************** + //15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + self test mode + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 23 01 00 00 00 00 02 FF 24 + 23 01 00 00 00 00 02 EC 01 + 23 01 00 00 00 00 02 FF 20 + 23 01 00 00 00 00 02 67 4D +*************************************************************/ + 15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + 23 01 00 00 00 00 02 FF 23 + 23 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 24 + + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 78 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 79 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-init-delay-us=<50000>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 50>; + qcom,mdss-pan-physical-width-dimension = <61>; + qcom,mdss-pan-physical-height-dimension = <110>; + }; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi new file mode 100755 index 0000000000000..8ae76e72ddb7a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi @@ -0,0 +1,68 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_0: qcom,mdss_dsi_sharp_wqxga_video_0 { + qcom,mdss-dsi-panel-name = "Dual 0 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <50>; + qcom,mdss-dsi-bl-pmic-bank-select = <2>; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi new file mode 100755 index 0000000000000..a9337b1866188 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi @@ -0,0 +1,66 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_1: qcom,mdss_dsi_sharp_wqxga_video_1 { + qcom,mdss-dsi-panel-name = "Dual 1 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-cmd.dtsi new file mode 100755 index 0000000000000..694973e4ff43f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-cmd.dtsi @@ -0,0 +1,94 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_cmd: qcom,mdss_dsi_sim_cmd{ + qcom,mdss-dsi-panel-name = "Simulator cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-cmd.dtsi new file mode 100755 index 0000000000000..74986f9b4e5f3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-cmd.dtsi @@ -0,0 +1,95 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_0: qcom,mdss_dsi_sim_cmd_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-video.dtsi new file mode 100755 index 0000000000000..13cd57f321c82 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi0-video.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_0: qcom,mdss_dsi_sim_video_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-cmd.dtsi new file mode 100755 index 0000000000000..f73e47bd504b5 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-cmd.dtsi @@ -0,0 +1,96 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_1: qcom,mdss_dsi_sim_cmd_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-video.dtsi new file mode 100755 index 0000000000000..882b2abdce34f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-dualmipi1-video.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_1: qcom,mdss_dsi_sim_video_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-video.dtsi b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-video.dtsi new file mode 100755 index 0000000000000..bd9322bac2e74 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/dsi-panel-sim-video.dtsi @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_vid: qcom,mdss_dsi_sim_video { + qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <640>; + qcom,mdss-dsi-panel-height = <480>; + qcom,mdss-dsi-h-front-porch = <6>; + qcom,mdss-dsi-h-back-porch = <6>; + qcom,mdss-dsi-h-pulse-width = <2>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <6>; + qcom,mdss-dsi-v-front-porch = <6>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [32 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-off-command = [22 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [00 00 00 00 00 00 00 00 00 00 00 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x1b>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 0>, <0 0>, <1 0>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-gdsc-8916.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-gdsc-8916.dtsi new file mode 100755 index 0000000000000..07e1e33fd4482 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-gdsc-8916.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@184c018 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0x184c018 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@184d078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0x184d078 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@185701c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0x185701c 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@1858034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0x1858034 0x4>; + status = "disabled"; + }; + + gdsc_vfe1: qcom,gdsc@185806c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe1"; + reg = <0x185806c 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@1858078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0x1858078 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@185901c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0x185901c 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@184c028 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0x184c028 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@184c030 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0x184c030 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-gdsc.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-gdsc.dtsi new file mode 100755 index 0000000000000..9a1f32eb0c7aa --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-gdsc.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@fd8c1024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0xfd8c1024 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@fd8c1040 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0xfd8c1040 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@fd8c1044 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0xfd8c1044 0x4>; + status = "disabled"; + }; + + gdsc_venus_core2: qcom,gdsc@fd8c1050 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core2"; + reg = <0xfd8c1050 0x4>; + status = "disabled"; + }; + + gdsc_vpu: qcom,gdsc@fd8c1404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vpu"; + reg = <0xfd8c1404 0x4>; + status = "disabled"; + }; + + gdsc_camss_top: qcom,gdsc@fd8c34a0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_camss_top"; + reg = <0xfd8c34a0 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@fd8c2304 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0xfd8c2304 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@fd8c35a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0xfd8c35a4 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@fd8c36a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0xfd8c36a4 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@fd8c36d4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0xfd8c36d4 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@fd8c4024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0xfd8c4024 0x4>; + status = "disabled"; + }; + + gdsc_oxili_cx: qcom,gdsc@fd8c4034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_cx"; + reg = <0xfd8c4034 0x4>; + status = "disabled"; + }; + + gdsc_usb_hsic: qcom,gdsc@fc400404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb_hsic"; + reg = <0xfc400404 0x4>; + status = "disabled"; + }; + + gdsc_pcie: qcom,gdsc@0xfc401e18 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie"; + reg = <0xfc401e18 0x4>; + status = "disabled"; + }; + + gdsc_pcie_0: qcom,gdsc@fc401ac4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_0"; + reg = <0xfc401ac4 0x4>; + status = "disabled"; + }; + + gdsc_pcie_1: qcom,gdsc@fc401b44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_1"; + reg = <0xfc401b44 0x4>; + status = "disabled"; + }; + + gdsc_usb30: qcom,gdsc@fc401e84 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30"; + reg = <0xfc401e84 0x4>; + status = "disabled"; + }; + + gdsc_usb30_sec: qcom,gdsc@fc401ec0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30_sec"; + reg = <0xfc401ec0 0x4>; + status = "disabled"; + }; + + gdsc_vcap: qcom,gdsc@fd8c1804 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vcap"; + reg = <0xfd8c1804 0x4>; + status = "disabled"; + }; + + gdsc_bcss: qcom,gdsc@fc744128 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_bcss"; + reg = <0xfc744128 0x4>; + status = "disabled"; + }; + + gdsc_ufs: qcom,gdsc@fc401d44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_ufs"; + reg = <0xfc401d44 0x4>; + status = "disabled"; + }; + + gdsc_fd: qcom,gdsc@fd8c3b64 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_fd"; + reg = <0xfd8c3b64 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v0.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v0.dtsi new file mode 100755 index 0000000000000..88919353600b8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v0.dtsi @@ -0,0 +1,328 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + lpass_iommu: qcom,iommu@fd000000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd000000 0x10000>; + interrupts = <0 248 0>; + qcom,glb-offset = <0xF000>; + label = "lpass_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "lpass_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <11 512 0 0>, + <11 512 0 1000>; + qcom,msm-enable-remote-spinlock; + status = "disabled"; + + lpass_q6_fw: qcom,iommu-ctx@fd000000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd000000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <0 15>; + label = "q6_fw"; + }; + + lpass_audio_shared: qcom,iommu-ctx@fd001000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd001000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <1>; + label = "audio_shared"; + }; + + lpass_video_shared: qcom,iommu-ctx@fd002000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd002000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <2>; + label = "video_shared"; + }; + + lpass_q6_spare: qcom,iommu-ctx@fd003000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd003000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare"; + }; + }; + + copss_iommu: qcom,iommu@fd010000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd010000 0x10000>; + interrupts = <0 252 0>; + qcom,glb-offset = <0xF000>; + label = "copss_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + + status = "disabled"; + + qcom,iommu-ctx@fd010000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd010000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <0>; + label = "copss_0"; + }; + + qcom,iommu-ctx@fd011000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd011000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <1>; + label = "copss_1"; + }; + + qcom,iommu-ctx@fd012000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd012000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <2>; + label = "copss_2"; + }; + + qcom,iommu-ctx@fd013000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd013000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <3>; + label = "copss_3"; + }; + + qcom,iommu-ctx@fd014000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd014000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <4>; + label = "copss_4"; + }; + + qcom,iommu-ctx@fd015000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd015000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <5>; + label = "copss_5"; + }; + + qcom,iommu-ctx@fd016000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd016000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <6>; + label = "copss_6"; + }; + + qcom,iommu-ctx@fd017000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd017000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <7>; + label = "copss_7"; + }; + }; + + mdpe_iommu: qcom,iommu@fd860000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd860000 0x10000>; + interrupts = <0 245 0>; + qcom,glb-offset = <0xF000>; + label = "mdpe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdpe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <92 512 0 0>, + <92 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd860000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd860000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <0 1 3>; + label = "mdpe_0"; + }; + + qcom,iommu-ctx@fd861000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd861000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <2>; + label = "mdpe_1"; + }; + }; + + mdps_iommu: qcom,iommu@fd870000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd870000 0x10000>; + interrupts = <0 73 0>; + qcom,glb-offset = <0xF000>; + label = "mdps_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdps_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd870000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd870000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <0>; + label = "mdps_0"; + }; + + qcom,iommu-ctx@fd871000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd871000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <1>; + label = "mdps_1"; + }; + }; + + gfx_iommu: qcom,iommu@fd880000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd880000 0x10000>; + interrupts = <0 38 0>; + qcom,glb-offset = <0xF000>; + qcom,needs-alt-core-clk; + label = "gfx_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "gfx_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd880000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd880000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 + 14 15>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fd881000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd881000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25 + 26 27 28 29 30 31>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fd882000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd882000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <>; + label = "gfx3d_spare"; + }; + }; + + vfe_iommu: qcom,iommu@fd890000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd890000 0x10000>; + interrupts = <0 62 0>; + qcom,glb-offset = <0xF000>; + label = "vfe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd890000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd890000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9>; + label = "vfe0"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v1.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v1.dtsi new file mode 100755 index 0000000000000..911d83c109235 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v1.dtsi @@ -0,0 +1,1513 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + jpeg_iommu: qcom,iommu@fda64000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda64000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 67 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "jpeg_iommu"; + status = "disabled"; + qcom,msm-bus,name = "jpeg_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <62 512 0 0>, + <62 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x0000ffff + 0x0 + 0x4 + 0x4 + 0x0 + 0x0 + 0x10 + 0x50 + 0x0 + 0x10 + 0x20 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@fda6d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <1>; + label = "jpeg_enc1"; + }; + + qcom,iommu-ctx@fda6e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6e000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <2>; + label = "jpeg_dec"; + }; + }; + + mdp_iommu: qcom,iommu@fd928000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd928000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000034 + 0x00000044 + 0x0 + 0x34 + 0x74 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd930000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd930000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd931000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd931000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd932000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd932000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; + + venus_iommu: qcom,iommu@fdc84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdc84000 0x10000 + 0xfdce0004 0x4>; + reg-names = "iommu_base", "clk_base"; + interrupts = <0 45 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <0>; + qcom,needs-alt-core-clk; + label = "venus_iommu"; + qcom,msm-bus,name = "venus_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2024 + 0x2028 + 0x202c + 0x2030 + 0x2034 + 0x2038>; + + qcom,iommu-bfb-data = <0xffffffff + 0xffffffff + 0x00000004 + 0x00000008 + 0x00000000 + 0x00000000 + 0x00000094 + 0x000000b4 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8c000 0x1000>; + interrupts = <0 42 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5>; + label = "venus_ns"; + }; + + venus_cp: qcom,iommu-ctx@fdc8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8d000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>; + label = "venus_cp"; + qcom,secure-context; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8e000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0xc0 0xc6>; + label = "venus_fw"; + qcom,secure-context; + }; + }; + + kgsl_iommu: qcom,iommu@fdb10000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdb10000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 38 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "kgsl_iommu"; + qcom,msm-bus,name = "kgsl_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000001 + 0x00000021 + 0x0 + 0x1 + 0x81 + 0x0>; + + qcom,iommu-ctx@fdb18000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb18000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fdb19000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb19000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fdb1a000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb1a000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <2>; + label = "gfx3d_spare"; + }; + + }; + + vfe_iommu: qcom,iommu@fda44000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda44000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 62 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <19>; + qcom,needs-alt-core-clk; + label = "vfe_iommu"; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x00000000 + 0x4 + 0x8 + 0x0 + 0x0 + 0x20 + 0x78 + 0x0 + 0x20 + 0x36 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda4c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4c000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <0 1>; + label = "vfe"; + }; + + qcom,iommu-ctx@fda4d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4d000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp"; + }; + + qcom,iommu-ctx@fda4e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4e000 0x1000>; + interrupts = <0 65 0>, <0 64 0>; + qcom,iommu-ctx-sids = <>; + label = "vfe_secure"; + qcom,secure-context; + }; + }; + + copss_iommu: qcom,iommu@f9bc4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xf9bc4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 153 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <8>; + label = "copss_iommu"; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x5 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x3 + 0x0>; + + + copss_cb0: qcom,iommu-ctx@f9bcc000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcc000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <0>; + label = "copss_cb0"; + }; + + copss_cb1: qcom,iommu-ctx@f9bcd000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcd000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <1>; + label = "copss_cb1"; + }; + + copss_usb: qcom,iommu-ctx@f9bce000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bce000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <2>; + label = "copss_usb"; + }; + + copss_cb3: qcom,iommu-ctx@f9bcf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcf000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <3>; + label = "copss_cb3"; + }; + + copss_cb4: qcom,iommu-ctx@f9bd0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd0000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <4>; + label = "copss_cb4"; + }; + + copss_cb5: qcom,iommu-ctx@f9bd1000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd1000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <5>; + label = "copss_cb5"; + }; + + copss_cb6: qcom,iommu-ctx@f9bd2000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd2000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <6>; + label = "copss_cb6"; + }; + + copss_cb_7: qcom,iommu-ctx@f9bd3000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd3000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <7>; + label = "copss_cb7"; + }; + }; + + vpu_iommu: qcom,iommu@fdee4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdee4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 147 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <7>; + label = "vpu_iommu"; + qcom,msm-bus,name = "vpu_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <93 512 0 0>, + <93 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0xffff + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x0 + 0x1e00 + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2000 + 0x2014>; + + qcom,iommu-lpae-bfb-data = <0xffff + 0x0 + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x1e00 + 0x5a2d + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x3 + 0x0>; + + + vpu_hlos: qcom,iommu-ctx@fdeec000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeec000 0x1000>; + interrupts = <0 145 0>; + qcom,iommu-ctx-sids = <0 1 3>; + label = "vpu_hlos"; + }; + + vpu_cp: qcom,iommu-ctx@fdeed000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeed000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <8 9>; + label = "vpu_cp"; + qcom,secure-context; + }; + + vpu_fw: qcom,iommu-ctx@fdeee000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeee000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <5 7 15>; + label = "vpu_fw"; + qcom,secure-context; + }; + }; + + lpass_qdsp_iommu: qcom,iommu@fe054000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe054000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 202 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <2>; + label = "lpass_qdsp_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x20 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x3 + 0x0>; + + + lpass_q6_fw: qcom,iommu-ctx@fe05c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05c000 0x1000>; + interrupts = <0 265 0>, <0 203 0>; + qcom,iommu-ctx-sids = <0 15>; + label = "q6_fw"; + qcom,secure-context; + }; + + lpass_audio_shared: qcom,iommu-ctx@fe05d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05d000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <1>; + label = "audio_shared"; + }; + + lpass_q6_spare1: qcom,iommu-ctx@fe05e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05e000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <2>; + label = "q6_spare1"; + }; + + lpass_q6_spare2: qcom,iommu-ctx@fe05f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05f000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare2"; + }; + }; + + lpass_core_iommu: qcom,iommu@fe064000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe064000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 166 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <6>; + label = "lpass_core_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0xc + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x3 + 0x0>; + + + lpass_core_image: qcom,iommu-ctx@fe06c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06c000 0x1000>; + interrupts = <0 267 0>, <0 180 0>; + qcom,iommu-ctx-sids = <11>; + label = "lpass_core_image"; + qcom,secure-context; + }; + + lpass_core_audio: qcom,iommu-ctx@fe06d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06d000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <12>; + label = "lpass_core_audio"; + }; + + lpass_core_slimbus: qcom,iommu-ctx@fe06e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06e000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <13>; + label = "lpass_core_slimbus"; + }; + }; + + vcap_iommu: qcom,iommu@fdfb6000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdfb6000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 315 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "vcap_iommu"; + status = "disabled"; + qcom,msm-bus,name = "vcap_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <48 512 0 0>, + <48 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2060>; + + qcom,iommu-bfb-data = <0x0ff + 0x00000004 + 0x00000008 + 0x0 + 0x0 + 0x00000008 + 0x00000028 + 0x0 + 0x001000 + 0x001000 + 0x003008 + 0x0 + 0x0 + 0x0 + 0x1555>; + + qcom,iommu-ctx@fdfbe000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbe000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <0>; + label = "vcap_cb0"; + }; + + qcom,iommu-ctx@fdfbf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbf000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <1>; + label = "vcap_cb1"; + }; + + qcom,iommu-ctx@fdfc0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfc0000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <>; + label = "vcap_cb2"; + }; + }; + + bcast_iommu: qcom,iommu@fc734000{ + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfc734000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 279 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "bcast_iommu"; + qcom,iommu-secure-id = <13>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2060>; + + qcom,iommu-bfb-data = <0xffffffff + 0x1 + 0x0000004 + 0x0000004 + 0x0 + 0x0 + 0x000055 + 0x0000d9 + 0x0 + 0x000aa00 + 0x0004200 + 0x000e821 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x1555>; + + bcast_cb0_hlos: qcom,iommu-ctx@fc73c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73c000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31>; + label = "bcast_cb0_hlos"; + }; + + bcast_cb1_cpz: qcom,iommu-ctx@fc73d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73d000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62>; + label = "bcast_cb1_cpz"; + qcom,secure-context; + }; + + bcast_cb2_demod: qcom,iommu-ctx@fc73e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73e000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <63>; + label = "bcast_cb2_demod"; + qcom,secure-context; + }; + + bcast_cb3_apz: qcom,iommu-ctx@fc73f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73f000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <>; + label = "bcast_cb3_apz"; + qcom,secure-context; + }; + }; + + fd_iommu: qcom,iommu@0xfd864000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd864000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 314 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "fd_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x00000007 + 0x1555 + 0x0 + 0x00000004 + 0x00000008 + 0x0601 + 0x1a0d + 0x0400 + 0x1a02 + 0x0 + 0x00000000 + 0x00000002 + 0x0000000a + 0x0>; + + qcom,iommu-ctx@fd86c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86c000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <0>; + label = "camera_fd"; + }; + + qcom,iommu-ctx@fd86d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86d000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_1"; + }; + + qcom,iommu-ctx@fd86e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86e000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_2"; + }; + }; + + cpp_iommu: qcom,iommu@0xfda84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda84000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 264 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "cpp_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c>; + + qcom,iommu-bfb-data = <0x00000003 + 0x3ff + 0x1555 + 0x0 + 0x00000004 + 0x10 + 0x1400 + 0x164b2 + 0x1400 + 0x1640a + 0x0 + 0x00000000 + 0x0000000a + 0x32 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8c000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp_0"; + }; + + qcom,iommu-ctx@fda8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8d000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_1"; + }; + + qcom,iommu-ctx@fda8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8e000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_2"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v2.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v2.dtsi new file mode 100755 index 0000000000000..2aa3828704d07 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-iommu-v2.dtsi @@ -0,0 +1,238 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gfx_iommu: qcom,iommu@1f00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1f00000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "gfx_iommu"; + qcom,iommu-secure-id = <18>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_gfx_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + status = "disabled"; + + qcom,iommu-ctx@1f09000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f09000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@1f0a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f0a000 0x1000>; + interrupts = <0 242 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + }; + + apps_iommu: qcom,iommu@1e00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1e00000 0x40000 + 0x1ef0000 0x3000>; + reg-names = "iommu_base", "smmu_local_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "apps_iommu"; + qcom,iommu-secure-id = <17>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_apss_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + qcom,cb-base-offset = <0x20000>; + status = "disabled"; + + qcom,iommu-ctx@1e22000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e22000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2000>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@1e23000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e23000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x400>; + label = "vfe"; + }; + + qcom,iommu-ctx@1e24000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e24000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xc00>; + label = "mdp_0"; + }; + + venus_ns: qcom,iommu-ctx@1e25000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e25000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x800 0x801 0x802 0x803 + 0x804 0x805 0x807>; + label = "venus_ns"; + }; + + qcom,iommu-ctx@1e26000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e26000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x402>; + label = "cpp"; + }; + + qcom,iommu-ctx@1e27000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e27000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1000>; + label = "mDSP"; + }; + + qcom,iommu-ctx@1e28000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e28000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1400>; + label = "gss"; + }; + + qcom,iommu-ctx@1e29000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e29000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1800>; + label = "a2"; + }; + + qcom,iommu-ctx@1e32000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e32000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0xc01>; + label = "mdp_1"; + }; + + venus_sec_pixel: qcom,iommu-ctx@1e33000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e33000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x885>; + label = "venus_sec_pixel"; + }; + + venus_sec_bitstream: qcom,iommu-ctx@1e34000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e34000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x880 0x881 0x882 0x883 0x884>; + label = "venus_sec_bitstream"; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@1e35000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e35000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x887 0x8a0>; + label = "venus_sec_non_pixel"; + }; + + venus_fw: qcom,iommu-ctx@1e36000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e36000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x8c0 0x8c6>; + label = "venus_fw"; + }; + + periph_rpm: qcom,iommu-ctx@1e37000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e37000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x40>; + label = "periph_rpm"; + }; + + qcom,iommu-ctx@1e38000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e38000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xC0 0xC4 0xC8 0xCC 0xD0 0xD3 + 0xD4 0xD7 0xD8 0xDB 0xDC 0xDF + 0xF0 0xF3 0xF4 0xF7 0xF8 0xFB + 0xFC 0xFF>; + label = "periph_CE"; + }; + + qcom,iommu-ctx@1e39000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e39000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x280 0x283 0x284 0x287 0x288 + 0x28B 0x28C 0x28F 0x290 0x293 + 0x294 0x297 0x298 0x29B 0x29C + 0x29F>; + label = "periph_BLSP"; + }; + + qcom,iommu-ctx@1e3a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3a000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x100>; + label = "periph_SDC1"; + }; + + qcom,iommu-ctx@1e3b000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3b000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x140>; + label = "periph_SDC2"; + }; + + qcom,iommu-ctx@1e3c000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1c0>; + label = "periph_audio"; + }; + + qcom,iommu-ctx@1e3d000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2c0>; + label = "periph_USB_HS1"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-pm8994-rpm-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-pm8994-rpm-regulator.dtsi new file mode 100755 index 0000000000000..8c32136aabd4b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-pm8994-rpm-regulator.dtsi @@ -0,0 +1,697 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + rpm-regulator-smpa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <3>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <4>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa5 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <5>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s5 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s5"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa7 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <7>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s7 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s7"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <2>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <3>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <4>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa6 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <6>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l6 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l6"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa8 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <8>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l8 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l8"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa9 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <9>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l9 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l9"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa10 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <10>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l10 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l10"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa11 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <11>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l11 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l11"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa12 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <12>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l12 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l12"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa13 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <13>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l13 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l13"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa14 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <14>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l14 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l14"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa15 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <15>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l15 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l15"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa16 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <16>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l16 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l16"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa17 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <17>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l17 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l17"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa18 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <18>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l18 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l18"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa19 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <19>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l19 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l19"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa20 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <20>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l20 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l20"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa21 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <21>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l21 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l21"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa22 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <22>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l22 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l22"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa23 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <23>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l23 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l23"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa24 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <24>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l24 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l24"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa25 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <25>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l25 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l25"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa26 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <26>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l26 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l26"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa27 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <27>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l27 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l27"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa28 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <28>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l28 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l28"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa29 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <29>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l29 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l29"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa30 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <30>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l30 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l30"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa31 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <31>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l31 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l31"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa32 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <32>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l32 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l32"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <2>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bstb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bstb"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-bst { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bbyb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bbyb"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + status = "disabled"; + + regulator-bby { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boostbypass"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpc2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpc"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-pm8994.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-pm8994.dtsi new file mode 100755 index 0000000000000..7312c2594e9ec --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-pm8994.dtsi @@ -0,0 +1,576 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pm8994@0 { + spmi-slave-container; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + + pm8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,temp-alarm@2400 { + compatible = "qcom,qpnp-temp-alarm"; + reg = <0x2400 0x100>; + interrupts = <0x0 0x24 0x0>; + label = "pm8994_tz"; + qcom,channel-num = <8>; + qcom,threshold-set = <0>; + qcom,temp_alarm-vadc = <&pm8994_vadc>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + interrupts = <0x0 0x8 0x0>, + <0x0 0x8 0x1>, + <0x0 0x8 0x4>, + <0x0 0x8 0x5>; + interrupt-names = "kpdpwr", "resin", + "resin-bark", "kpdpwr-resin-bark"; + qcom,pon-dbc-delay = <15625>; + qcom,system-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + + qcom,pon_1 { + qcom,pon-type = <0>; + qcom,pull-up = <1>; + linux,code = <116>; + qcom,support-reset = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <10256>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_2 { + qcom,pon-type = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT + // comment out by yangrujin@bsp for vol_down is controled by gpio + //linux,code = <114>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_3 { + qcom,pon-type = <3>; + qcom,support-reset = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <6720>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + + qcom,use-bark; + }; + }; + + pm8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + + gpio@ca00 { + reg = <0xca00 0x100>; + qcom,pin-num = <11>; + status = "disabled"; + }; + + gpio@cb00 { + reg = <0xcb00 0x100>; + qcom,pin-num = <12>; + status = "disabled"; + }; + + gpio@cc00 { + reg = <0xcc00 0x100>; + qcom,pin-num = <13>; + status = "disabled"; + }; + + gpio@cd00 { + reg = <0xcd00 0x100>; + qcom,pin-num = <14>; + status = "disabled"; + }; + + gpio@ce00 { + reg = <0xce00 0x100>; + qcom,pin-num = <15>; + status = "disabled"; + }; + + gpio@cf00 { + reg = <0xcf00 0x100>; + qcom,pin-num = <16>; + status = "disabled"; + }; + + gpio@d000 { + reg = <0xd000 0x100>; + qcom,pin-num = <17>; + status = "disabled"; + }; + + gpio@d100 { + reg = <0xd100 0x100>; + qcom,pin-num = <18>; + status = "disabled"; + }; + + gpio@d200 { + reg = <0xd200 0x100>; + qcom,pin-num = <19>; + status = "disabled"; + }; + + gpio@d300 { + reg = <0xd300 0x100>; + qcom,pin-num = <20>; + status = "disabled"; + }; + + gpio@d500 { + reg = <0xd500 0x100>; + qcom,pin-num = <22>; + status = "disabled"; + }; + }; + + pm8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp02*/ + /* + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP2 as an Analog input to AMUX6 and read from channel 0x11 */ + mpp@a100 { /* MPP 2 */ + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <1>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH6 = 1*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4)*/ + /* + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + };*/ + /*#else VENDOR_EDIT*/ + /* Configure MPP4 as an Analog input to AMUX8 and read from channel 0x23 */ + mpp@a300 { /* MPP 4 */ + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 8 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4) end*/ + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp05*/ + /* + mpp@a400 { + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP5 as an Analog input to AMUX5 and read from channel 0x14 */ + mpp@a400 { /* MPP 5 */ + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <0>; /* AMUX 5 ,QPNP_PIN_AIN_AMUX_CH5 = 0*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a500 { + reg = <0xa500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + mpp@a600 { + reg = <0xa600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp08*/ + /* + mpp@a700 { + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP8 as an Analog input to AMUX8 and read from channel 0x17 */ + mpp@a700 { /* MPP 8 */ + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + }; + + pm8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x31 0x0>; + interrupt-names = "eoc-int-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + + chan@8 { + label = "die_temp"; + reg = <8>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <3>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@9 { + label = "ref_625mv"; + reg = <9>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@a { + label = "ref_1250v"; + reg = <0xa>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + /* VADC Channel configuration */ + chan@23 { + label = "cover_mpp4_div3"; + reg = <0x23>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; //Use 1:3 scaling to keep input voltage with in Max voltage: 1.8V + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /* //EVB2 floating,so use 1:1 chan + chan@13 { + label = "cover_mpp4_div3"; + reg = <0x13>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + };*/ + /*#endif VENDOR_EDIT*/ + + +/*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + /* VADC Channel configuration */ + chan@76 { + label = "pcb_version_AMUX_HW_ID"; + reg = <0x76>;//pcb_version_AMUX_HW_ID channel 54 + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; //Use 1:1 scaling to keep input voltage with in Max voltage: 1.8V + //qcom,calibration-type = "ratiometric"; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@11 { + label = "rf_mpp2"; + reg = <0x11>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@14 { + label = "rf_mpp5"; + reg = <0x14>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@17 { + label = "rf_mpp8"; + reg = <0x17>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#endif VENDOR_EDIT*/ + }; + + pm8994_adc_tm: vadc@3400 { + compatible = "qcom,qpnp-adc-tm"; + reg = <0x3400 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x34 0x0>, + <0x0 0x34 0x3>, + <0x0 0x34 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,adc_tm-vadc = <&pm8994_vadc>; + }; + + pm8994_coincell: qcom,coincell@2800 { + compatible = "qcom,qpnp-coincell"; + reg = <0x2800 0x100>; + }; + + qcom,pm8994_rtc { + spmi-dev-container; + compatible = "qcom,qpnp-rtc"; + #address-cells = <1>; + #size-cells = <1>; + qcom,qpnp-rtc-write = <0>; + /*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + qcom,qpnp-rtc-alarm-pwrup = <1>; + /*#endif VENDOR_EDIT*/ + + qcom,pm8994_rtc_rw@6000 { + reg = <0x6000 0x100>; + }; + qcom,pm8994_rtc_alarm@6100 { + reg = <0x6100 0x100>; + interrupts = <0x0 0x61 0x1>; + }; + }; + }; + + qcom,pm8994@1 { + spmi-slave-container; + reg = <0x1>; + #address-cells = <1>; + #size-cells = <1>; + + pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b500 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb500 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <4>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <4>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b600 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb600 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <5>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <5>; + #pwm-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-pmi8994.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-pmi8994.dtsi new file mode 100755 index 0000000000000..2e14cf1db68ba --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-pmi8994.dtsi @@ -0,0 +1,741 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pmi8994@2 { + spmi-slave-container; + reg = <0x2>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + qcom,secondary-pon-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + }; + + pmi8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + }; + + pmi8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + }; +//#ifdef VENDOR_EDIT /* shankai@BSP.driver, 2015/3/25, add for the button-backlight */ + qcom,leds@a300 { + compatible = "qcom,leds-qpnp"; + status = "okay"; + reg=<0xa300 0x100>; + qcom,led_mpp_3 { + label = "mpp"; + linux,name = "button-backlight"; + linux,default-trigger = "none"; + qcom,default-state = "off"; + qcom,max-current = <40>; + qcom,current-setting = <5>; + qcom,id = <6>; + qcom,mode = "manual"; + qcom,source-sel = <1>; + qcom,mode-ctrl = <0x60>; + }; + }; +//#endif /*VENDOR_EDIT*/ + + + + bcl@4200 { + compatible = "qcom,msm-bcl"; + reg = <0x4200 0xFF 0x88E 0x2>; + reg-names = "fg_user_adc", "pon_spare"; + interrupts = <0x2 0x42 0x0>, + <0x2 0x42 0x1>; + interrupt-names = "bcl-high-ibat-int", + "bcl-low-vbat-int"; + qcom,vbat-scaling-factor = <39000>; + qcom,vbat-gain-numerator = <1>; + qcom,vbat-gain-denominator = <128>; + qcom,vbat-polling-delay-ms = <100>; + qcom,ibat-scaling-factor = <39000>; + qcom,ibat-gain-numerator = <1>; + qcom,ibat-gain-denominator = <128>; + qcom,ibat-offset-numerator = <1200>; + qcom,ibat-offset-denominator = <1>; + qcom,ibat-polling-delay-ms = <100>; + qcom,inhibit-derating-ua = <550000>; + }; + + pmi8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x2 0x31 0x0>, + <0x2 0x31 0x3>, + <0x2 0x31 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + qcom,vadc-meas-int-mode; + }; + + pmi8994_charger: qcom,qpnp-smbcharger { + spmi-dev-container; + compatible = "qcom,qpnp-smbcharger"; + #address-cells = <1>; + #size-cells = <1>; + + qcom,iterm-ma = <150>; + qcom,fastchg-current-ma = <1910>; + qcom,float-voltage-mv = <4320>; + qcom,resume-delta-mv = <100>; + // qcom,chg-inhibit-en; + qcom,chg-inhibit-fg; + qcom,dc-psy-type = "Mains"; + qcom,dc-psy-ma = <1500>; + qcom,rparasitic-uohm = <100000>; + qcom,bms-psy-name = "bms"; + qcom,thermal-mitigation = <2000 1000 900 800>; + qcom,parallel-usb-min-current-ma = <1400>; + qcom,parallel-usb-9v-min-current-ma = <900>; + qcom,parallel-allowed-lowering-ma = <500>; + qcom,autoadjust-vfloat; + qcom,charge-unknown-battery; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x2 0x10 0x0>, + <0x2 0x10 0x1>, + <0x2 0x10 0x2>, + <0x2 0x10 0x3>, + <0x2 0x10 0x4>, + <0x2 0x10 0x5>, + <0x2 0x10 0x6>, + <0x2 0x10 0x7>; + + interrupt-names = "chg-error", + "chg-inhibit", + "chg-prechg-sft", + "chg-complete-chg-sft", + "chg-p2f-thr", + "chg-rechg-thr", + "chg-taper-thr", + "chg-tcc-thr"; + }; + + qcom,otg@1100 { + reg = <0x1100 0x100>; + }; + + qcom,bat-if@1200 { + reg = <0x1200 0x100>; + interrupts = <0x2 0x12 0x0>, + <0x2 0x12 0x1>, + <0x2 0x12 0x2>, + <0x2 0x12 0x3>, + <0x2 0x12 0x4>, + <0x2 0x12 0x5>, + <0x2 0x12 0x6>, + <0x2 0x12 0x7>; + + interrupt-names = "batt-hot", + "batt-warm", + "batt-cold", + "batt-cool", + "batt-ov", + "batt-low", + "batt-missing", + "batt-term-missing"; + }; + + qcom,usb-chgpth@1300 { + reg = <0x1300 0x100>; + interrupts = <0x2 0x13 0x0>, + <0x2 0x13 0x1>, + <0x2 0x13 0x2>, + <0x2 0x13 0x3>, + <0x2 0x13 0x4>, + <0x2 0x13 0x5>, + <0x2 0x13 0x6>; + + interrupt-names = "usbin-uv", + "usbin-ov", + "usbin-src-det", + "otg-fail", + "otg-oc", + "aicl-done", + "usbid-change"; + }; + + qcom,dc-chgpth@1400 { + reg = <0x1400 0x100>; + interrupts = <0x2 0x14 0x0>, + <0x2 0x14 0x1>; + + interrupt-names = "dcin-uv", + "dcin-ov"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x2 0x16 0x0>, + <0x2 0x16 0x1>, + <0x2 0x16 0x2>, + <0x2 0x16 0x3>, + <0x2 0x16 0x4>, + <0x2 0x16 0x5>; + + interrupt-names = "power-ok", + "temp-shutdown", + "safety-timeout", + "flash-fail", + "otst2", + "otst3"; + }; + }; + + pmi8994_fg: qcom,fg { + spmi-dev-container; + compatible = "qcom,qpnp-fg"; + #address-cells = <1>; + #size-cells = <1>; + //qcom,resume-soc = <95>; + qcom,resume-soc = <99>; + status = "okay"; + qcom,bcl-lm-threshold-ma = <127>; + qcom,bcl-mh-threshold-ma = <405>; + qcom,fg-chg-iterm-ma = <150>; + qcom,cycle-counter-en; + qcom,cycle-counter-low-soc = <15>; + qcom,cycle-counter-high-soc = <85>; + qcom,capacity-learning-on; + qcom,fg-cc-cv-threshold-mv = <4310>; + qcom,fg-iterm-ma = <200>; + qcom,fg-cutoff-voltage-mv=<3500>; + qcom,pmic-revid = <&pmi8994_revid>; + + qcom,thermal-coefficients = [da 86 f0 50 08 3c]; + qcom,fg-soc@4000 { + status = "okay"; + reg = <0x4000 0x100>; + interrupts = <0x2 0x40 0x0>, + <0x2 0x40 0x1>, + <0x2 0x40 0x2>, + <0x2 0x40 0x3>, + <0x2 0x40 0x4>, + <0x2 0x40 0x5>, + <0x2 0x40 0x6>, + <0x2 0x40 0x7>; + + interrupt-names = "high-soc", + "low-soc", + "full-soc", + "empty-soc", + "delta-soc", + "first-est-done", + "sw-fallbk-ocv", + "sw-fallbk-new-battrt-sts", + "fg-soc-irq-count"; + }; + + qcom,fg-batt@4100 { + reg = <0x4100 0x100>; + interrupts = <0x2 0x41 0x0>, + <0x2 0x41 0x1>, + <0x2 0x41 0x2>, + <0x2 0x41 0x3>, + <0x2 0x41 0x4>, + <0x2 0x41 0x5>, + <0x2 0x41 0x6>, + <0x2 0x41 0x7>; + + interrupt-names = "soft-cold", + "soft-hot", + "vbatt-low", + "batt-ided", + "batt-id-req", + "batt-unknown", + "batt-missing", + "batt-match"; + }; + + qcom,fg-adc-vbat@4254 { + reg = <0x4254 0x1>; + }; + + qcom,fg-adc-ibat@4255 { + reg = <0x4255 0x1>; + }; + + qcom,revid-tp-rev@1f1 { + reg = <0x1f1 0x1>; + }; + + qcom,fg-memif@4400 { + status = "okay"; + reg = <0x4400 0x100>; + interrupts = <0x2 0x44 0x0>, + <0x2 0x44 0x1>; + + interrupt-names = "mem-avail", + "data-rcvry-sug"; + }; + }; + }; + + qcom,pmi8994@3 { + spmi-slave-container; + reg = <0x3>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_pwm_1: pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_2: pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_3: pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_4: pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + }; + + labibb: qpnp-labibb-regulator { + status = "disabled"; + spmi-dev-container; + compatible = "qcom,qpnp-labibb-regulator"; + #address-cells = <1>; + #size-cells = <1>; + + lab_regulator: qcom,lab@de00 { + reg = <0xde00 0x100>; + reg-names = "lab"; + regulator-name = "lab_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-lab-min-voltage = <4600000>; + qcom,qpnp-lab-step-size = <100000>; + qcom,qpnp-lab-slew-rate = <5000>; + qcom,qpnp-lab-use-default-voltage; + qcom,qpnp-lab-init-voltage = <5500000>; + qcom,qpnp-lab-init-amoled-voltage = <4600000>; + qcom,qpnp-lab-init-lcd-voltage = <5500000>; + + qcom,qpnp-lab-soft-start = <800>; + + qcom,qpnp-lab-full-pull-down; + qcom,qpnp-lab-pull-down-enable; + qcom,qpnp-lab-switching-clock-frequency = <1600>; + qcom,qpnp-lab-limit-maximum-current = <800>; + qcom,qpnp-lab-limit-max-current-enable; + qcom,qpnp-lab-ps-threshold = <20>; + qcom,qpnp-lab-ps-enable; + qcom,qpnp-lab-nfet-size = <100>; + qcom,qpnp-lab-pfet-size = <100>; + qcom,qpnp-lab-max-precharge-time = <200>; + }; + + ibb_regulator: qcom,ibb@dc00 { + reg = <0xdc00 0x100>; + reg-names = "ibb_reg"; + regulator-name = "ibb_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-ibb-min-voltage = <1400000>; + qcom,qpnp-ibb-step-size = <100000>; + qcom,qpnp-ibb-slew-rate = <2000000>; + qcom,qpnp-ibb-use-default-voltage; + qcom,qpnp-ibb-init-voltage = <5500000>; + qcom,qpnp-ibb-init-amoled-voltage = <4000000>; + qcom,qpnp-ibb-init-lcd-voltage = <5500000>; + + qcom,qpnp-ibb-soft-start = <1000>; + + qcom,qpnp-ibb-discharge-resistor = <300>; + qcom,qpnp-ibb-lab-pwrup-delay = <4000>; + qcom,qpnp-ibb-lab-pwrdn-delay = <4000>; + qcom,qpnp-ibb-en-discharge; + + qcom,qpnp-ibb-full-pull-down; + qcom,qpnp-ibb-pull-down-enable; + qcom,qpnp-ibb-switching-clock-frequency = <1480>; + qcom,qpnp-ibb-limit-maximum-current = <1550>; + qcom,qpnp-ibb-debounce-cycle = <16>; + qcom,qpnp-ibb-limit-max-current-enable; + qcom,qpnp-ibb-ps-enable; + }; + + }; + + qcom,leds@d800 { + compatible = "qcom,qpnp-wled"; + reg = <0xd800 0x100>, + <0xd900 0x100>, + <0xdc00 0x100>, + <0xde00 0x100>; + reg-names = "qpnp-wled-ctrl-base", + "qpnp-wled-sink-base", + "qpnp-wled-ibb-base", + "qpnp-wled-lab-base"; + interrupts = <0x3 0xd8 0x2>; + interrupt-names = "sc-irq"; + status = "okay"; + linux,name = "wled"; + linux,default-trigger = "bkl-trigger"; + qcom,fdbk-output = "auto"; + qcom,vref-mv = <350>; + qcom,switch-freq-khz = <800>; + qcom,ovp-mv = <29500>; + qcom,ilim-ma = <980>; + qcom,boost-duty-ns = <26>; + qcom,mod-freq-khz = <9600>; + qcom,dim-mode = "hybrid"; + qcom,dim-method = "linear"; + qcom,hyb-thres = <625>; + qcom,sync-dly-us = <800>; + qcom,fs-curr-ua = <20000>;//guozhimig@oem add 2015-04-02 for adiudt backlight 20mA + qcom,en-phase-stag; + qcom,ibb-pwrup-dly = <8>; + qcom,led-strings-list = [00 01];//two WLED SINK/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,en-ext-pfet-sc-pro; + qcom,en-cabc;//guozhimig@oem add 2015-04-02 for en cabc + }; + +//#ifdef VENDOR_EDIT // shankai@bsp, 2015-4-4 do not use it ,comment it. +//shankai@bsp, 2015-5-28 now we use it + pmi8994_haptics: qcom,haptic@c000 { + status = "okay"; + compatible = "qcom,qpnp-haptic"; + reg = <0xc000 0x100>; + interrupts = <0x3 0xc0 0x0>, + <0x3 0xc0 0x1>; + interrupt-names = "sc-irq", "play-irq"; + qcom,play-mode = "direct"; + qcom,wave-play-rate-us = <5263>; + qcom,actuator-type = "erm"; + qcom,wave-shape = "square"; + qcom,vmax-mv = <3000>; + qcom,ilim-ma = <800>; + qcom,sc-deb-cycles = <8>; + qcom,int-pwm-freq-khz = <505>; + qcom,en-brake; + qcom,brake-pattern = [00 01 03 03]; + qcom,use-play-irq; + qcom,use-sc-irq; + qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e]; + qcom,wave-rep-cnt = <1>; + qcom,wave-samp-rep-cnt = <1>; + }; + +//#endif + qcom,leds@d000 { + compatible = "qcom,leds-qpnp"; + reg = <0xd000 0x100>; + label = "rgb"; + status = "okay"; + + /*#ifndef VENDOR_EDIT //shankai@bsp.driver 2015-02-26 modify for rgb blink feature*/ + qcom,rgb_0 { + label = "rgb"; + qcom,id = <3>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_3 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <1>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "red"; + /*linux,default-trigger = + "battery-charging";*/ + qcom,use-blink; + }; + + qcom,rgb_1 { + label = "rgb"; + qcom,id = <4>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_2 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + /* + qcom,duty-pcts = [00 05 0A 0f 14 19 1d 23 28 2c + 32 37 3b 41 45 4a 50 55 5a 64]; + */ + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "green"; + /*linux,default-trigger = "battery-full";*/ + qcom,use-blink; + }; + + qcom,rgb_2 { + label = "rgb"; + qcom,id = <5>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_1 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + qcom,default-state = "off"; + linux,name = "blue"; + qcom,use-blink; + linux,default-trigger = "boot-indication"; + }; + /*#end VENDOR_EDIT*/ + }; + + qcom,leds@d300 { + compatible = "qcom,qpnp-flash-led"; + status = "okay"; + reg = <0xd300 0x100>; + label = "flash"; + qcom,headroom = <500>; + qcom,startup-dly = <128>; + qcom,clamp-curr = <200>; + qcom,pmic-charger-support; + qcom,self-check-enabled; + qcom,thermal-derate-enabled; + qcom,thermal-derate-threshold = <100>; + qcom,thermal-derate-rate = "5_PERCENT"; + qcom,current-ramp-enabled; + qcom,ramp_up_step = "6P7_US"; + qcom,ramp_dn_step = "6P7_US"; + qcom,vph-pwr-droop-enabled; + qcom,vph-pwr-droop-threshold = <3000>; + qcom,vph-pwr-droop-debounce-time = <10>; + qcom,headroom-sense-ch0-enabled; + qcom,headroom-sense-ch1-enabled; + qcom,power-detect-enabled; + + pmi8994_flash0: qcom,flash_0 { + label = "flash"; + qcom,led-name = "led:flash_0"; + qcom,default-led-trigger = + "flash0_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <0>; + qcom,current = <625>; + }; + + pmi8994_flash1: qcom,flash_1 { + label = "flash"; + qcom,led-name = "led:flash_1"; + qcom,default-led-trigger = + "flash1_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <1>; + qcom,current = <625>; + }; + + pmi8994_torch0: qcom,torch_0 { + label = "torch"; + qcom,led-name = "led:torch_0"; + qcom,default-led-trigger = + "torch0_trigger"; + qcom,max-current = <200>; + qcom,id = <0>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + + pmi8994_torch1: qcom,torch_1 { + label = "torch"; + qcom,led-name = "led:torch_1"; + qcom,default-led-trigger = + "torch1_trigger"; + qcom,max-current = <200>; + qcom,id = <1>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm-rdbg.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm-rdbg.dtsi new file mode 100755 index 0000000000000..f7f52bed111c6 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm-rdbg.dtsi @@ -0,0 +1,75 @@ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + smp2pgpio_rdbg_2_in: qcom,smp2pgpio-rdbg-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_in { + compatible = "qcom,smp2pgpio_client_rdbg_2_in"; + gpios = <&smp2pgpio_rdbg_2_in 0 0>; + }; + + smp2pgpio_rdbg_2_out: qcom,smp2pgpio-rdbg-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_out { + compatible = "qcom,smp2pgpio_client_rdbg_2_out"; + gpios = <&smp2pgpio_rdbg_2_out 0 0>; + }; + + smp2pgpio_rdbg_1_in: qcom,smp2pgpio-rdbg-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_in { + compatible = "qcom,smp2pgpio_client_rdbg_1_in"; + gpios = <&smp2pgpio_rdbg_1_in 0 0>; + }; + + smp2pgpio_rdbg_1_out: qcom,smp2pgpio-rdbg-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_out { + compatible = "qcom,smp2pgpio_client_rdbg_1_out"; + gpios = <&smp2pgpio_rdbg_1_out 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-bus.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-bus.dtsi new file mode 100755 index 0000000000000..6b77e2a0488e4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-bus.dtsi @@ -0,0 +1,1597 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + ad_hoc_bus: ad-hoc-bus@fc460000 { + compatible = "qcom,msm-bus-device"; + reg = <0xFC460000 0x5880>, + <0xFC380000 0x80000>, + <0xFC468000 0x2400>, + <0xFC478000 0x3480>, + <0xFC480000 0x80>; + reg-names = "snoc-base", "bimc-base", "pnoc-base", "mnoc-base", "cnoc-base"; + + fab_snoc: fab-snoc { + cell-id = ; + label = "fab-snoc"; + qcom,fab-dev; + qcom,base-name = "snoc-base"; + qcom,base-offset = <0x5000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_snoc_msmbus_clk>, + <&clock_rpm clk_snoc_msmbus_a_clk>; + + coresight-id = <50>; + coresight-name = "coresight-snoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <3>; + }; + + fab_bimc: fab-bimc { + cell-id = ; + label = "fab-bimc"; + qcom,fab-dev; + qcom,base-name = "bimc-base"; + qcom,bus-type = <2>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_bimc_msmbus_clk>, + <&clock_rpm clk_bimc_msmbus_a_clk>; + + coresight-id = <55>; + coresight-name = "coresight-bimc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <3>; + }; + + fab_pnoc: fab-pnoc { + cell-id = ; + label = "fab-pnoc"; + qcom,fab-dev; + qcom,base-name = "pnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_pnoc_msmbus_clk>, + <&clock_rpm clk_pnoc_msmbus_a_clk>; + + coresight-id = <54>; + coresight-name = "coresight-pnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <6>; + }; + + fab_mnoc: fab-mnoc { + cell-id = ; + label = "fab-mnoc"; + qcom,fab-dev; + qcom,base-name = "mnoc-base"; + qcom,base-offset = <0x3000>; + qcom,bus-type = <1>; + qcom,qos-off = <0x80>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_mmss clk_mmss_s0_axi_clk>, + <&clock_mmss clk_mmss_s0_axi_clk>; + + coresight-id = <56>; + coresight-name = "coresight-mmnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <5>; + }; + + fab_cnoc: fab-cnoc { + cell-id = ; + label = "fab-cnoc"; + qcom,fab-dev; + qcom,base-name = "cnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_cnoc_msmbus_clk>, + <&clock_rpm clk_cnoc_msmbus_a_clk>; + }; + + fab_ovirt: fab-ovirt { + cell-id = ; + label = "fab-ovirt"; + qcom,fab-dev; + qcom,bypass-qos-prg; + qcom,virt-dev; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_ocmemgx_msmbus_clk>, + <&clock_rpm clk_ocmemgx_msmbus_a_clk >; + }; + + + /* bimc Devices */ + mas_apps_proc: mas-apps-proc { + cell-id = ; + label = "mas-apps-proc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&bimc_int_apps_ebi &bimc_int_apps_snoc>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ws = <10000>; + qcom,gp = <5000>; + qcom,thmp = <50>; + qcom,ap-owned; + }; + + bimc_int_apps_ebi: bimc-int-apps-ebi { + cell-id = ; + label = "bimc-int-apps-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_ebi>; + }; + + bimc_int_apps_snoc: bimc-int-apps-snoc { + cell-id = ; + label = "bimc-int-apps-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,connections = <&slv_bimc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_oxili: mas-oxili { + cell-id = ; + label = "mas-oxili"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <2>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ap-owned; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + }; + + + mas_mnoc_bimc: mas-mnoc-bimc { + cell-id = ; + label = "mas-mnoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + qcom,ap-owned; + }; + + + mas_snoc_bimc: mas-snoc-bimc { + cell-id = ; + label = "mas-snoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2>; + qcom,mas-rpm-id = ; + }; + + + slv_ebi: slv-ebi { + cell-id = ; + label = "slv-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <0 1>; + qcom,slv-rpm-id = ; + }; + + + slv_appss_l2: slv-appss-l2 { + cell-id = ; + label = "slv-appss-l2"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_snoc: slv-bimc-snoc { + cell-id = ; + label = "slv-bimc-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_bimc_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* mnoc Devices */ + mas_cnoc_mnoc_mmss_cfg: mas-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_camera_cfg &slv_cpr_cfg &slv_cpr_xpu_cfg + &slv_ocmem_cfg &slv_misc_cfg &slv_misc_xpu_cfg + &slv_oxili_cfg &slv_venus_cfg &slv_mnoc_clocks_cfg + &slv_mnoc_clocks_xpu_cfg &slv_mnoc_mpu_cfg &slv_display_cfg + &slv_avsync_cfg &slv_vpu_cfg>; + qcom,ap-owned; + }; + + + mas_cnoc_mnoc_cfg: mas-cnoc-mnoc-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_srvc_mnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_gemini: mas-gemini { + cell-id = ; + label = "mas-gemini"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <0>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p0: mas-mdp-p0 { + cell-id = ; + label = "mas-mdp-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <2>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p1: mas-mdp-p1 { + cell-id = ; + label = "mas-mdp-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <1>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p0: mas-venus-p0 { + cell-id = ; + label = "mas-venus-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p1: mas-venus-p1 { + cell-id = ; + label = "mas-venus-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_vfe: mas-vfe { + cell-id = ; + label = "mas-vfe"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <6>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_cpp: mas-cpp { + cell-id = ; + label = "mas-cpp"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <5>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_vpu: mas-vpu { + cell-id = ; + label = "mas-vpu"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qos-mode = "bypass"; + qcom,qport = <8>; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_camera_cfg: slv-camera-cfg { + cell-id = ; + label = "slv-camera-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_cfg: slv-cpr-cfg { + cell-id = ; + label = "slv-cpr-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_xpu_cfg: slv-cpr-xpu-cfg { + cell-id = ; + label = "slv-cpr-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_ocmem_cfg: slv-ocmem-cfg { + cell-id = ; + label = "slv-ocmem-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_cfg: slv-misc-cfg { + cell-id = ; + label = "slv-misc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_xpu_cfg: slv-misc-xpu-cfg { + cell-id = ; + label = "slv-misc-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_oxili_cfg: slv-oxili-cfg { + cell-id = ; + label = "slv-oxili-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_venus_cfg: slv-venus-cfg { + cell-id = ; + label = "slv-venus-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_cfg: slv-mnoc-clocks-cfg { + cell-id = ; + label = "slv-mnoc-clocks-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_xpu_cfg: slv-mnoc-clocks-xpu-cfg { + cell-id = ; + label = "slv-mnoc-clocks-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_mpu_cfg: slv-mnoc-mpu-cfg { + cell-id = ; + label = "slv-mnoc-mpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_display_cfg: slv-display-cfg { + cell-id = ; + label = "slv-display-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_avsync_cfg: slv-avsync-cfg { + cell-id = ; + label = "slv-avsync-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_vpu_cfg: slv-vpu-cfg { + cell-id = ; + label = "slv-vpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_bimc: slv-mnoc-bimc { + cell-id = ; + label = "slv-mnoc-bimc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <16 17>; + qcom,connections = <&mas_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_srvc_mnoc: slv-srvc-mnoc { + cell-id = ; + label = "slv-srvc-mnoc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + /* snoc Devices */ + mas_lpass_ahb: mas-lpass-ahb { + cell-id = ; + label = "mas-lpass-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_ocimem &slv_snoc_pnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_bam: mas-qdss-bam { + cell-id = ; + label = "mas-qdss-bam"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <1>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc &slv_usb3>; + qcom,ap-owned; + }; + + + mas_bimc_snoc: mas-bimc-snoc { + cell-id = ; + label = "mas-bimc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_cnoc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + mas_cnoc_snoc: mas-cnoc-snoc { + cell-id = ; + label = "mas-cnoc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_crypto_c0: mas-crypto-c0 { + cell-id = ; + label = "mas-crypto-c0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <2>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c1: mas-crypto-c1 { + cell-id = ; + label = "mas-crypto-c1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <3>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c2: mas-crypto-c2 { + cell-id = ; + label = "mas-crypto-c2"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <9>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_lpass_proc: mas-lpass-proc { + cell-id = ; + label = "mas-lpass-proc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_ovirt_snoc: mas-ovirt-snoc { + cell-id = ; + label = "mas-ovirt-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <5>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc>; + qcom,mas-rpm-id = ; + }; + + + mas_periph_snoc: mas-periph-snoc { + cell-id = ; + label = "mas-periph-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <13>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_lpass &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_pcie_0: mas-pcie-0 { + cell-id = ; + label = "mas-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <7>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_pcie_1: mas-pcie-1 { + cell-id = ; + label = "mas-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <16>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_qdss_etr: mas-qdss-etr { + cell-id = ; + label = "mas-qdss-etr"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ufs: mas-ufs { + cell-id = ; + label = "mas-ufs"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt>; + qcom,ap-owned; + }; + + + mas_usb3: mas-usb3 { + cell-id = ; + label = "mas-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_snoc_cnoc &slv_ocimem &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ipa: mas-ipa { + cell-id = ; + label = "mas-ipa"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <15>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_usb3 &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_pcie_0 &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + slv_kpss_ahb: slv-kpss-ahb { + cell-id = ; + label = "slv-kpss-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_lpass: slv-lpass { + cell-id = ; + label = "slv-lpass"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_bimc: slv-snoc-bimc { + cell-id = ; + label = "slv-snoc-bimc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_bimc>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cnoc: slv-snoc-cnoc { + cell-id = ; + label = "slv-snoc-cnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_cnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_ocimem: slv-ocimem { + cell-id = ; + label = "slv-ocimem"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_ovirt: slv-snoc-ovirt { + cell-id = ; + label = "slv-snoc-ovirt"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_ovirt>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_pnoc: slv-snoc-pnoc { + cell-id = ; + label = "slv-snoc-pnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_pnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_stm: slv-qdss-stm { + cell-id = ; + label = "slv-qdss-stm"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + slv_usb3: slv-usb3 { + cell-id = ; + label = "slv-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0: slv-pcie-0 { + cell-id = ; + label = "slv-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1: slv-pcie-1 { + cell-id = ; + label = "slv-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + /* ovirt Devices */ + mas_snoc_ovirt: mas-snoc-ovirt { + cell-id = ; + label = "mas-snoc-ovirt"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + mas_ocmem_dma: mas-ocmem-dma { + cell-id = ; + label = "mas-ocmem-dma"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem &slv_ovirt_snoc>; + qcom,ap-owned; + }; + + + mas_oxili_ocmem: mas-oxili-ocmem { + cell-id = ; + label = "mas-oxili-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem_gfx>; + qcom,ap-owned; + }; + + + mas_venus_ocmem: mas-venus-ocmem { + cell-id = ; + label = "mas-venus-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + slv_ocmem: slv-ocmem { + cell-id = ; + label = "slv-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <16>; + qcom,ap-owned; + clock-names = "node_clk"; + clocks = <&clock_mmss clk_ocmemnoc_clk_src>; + }; + + slv_ocmem_gfx: slv-ocmem-gfx { + cell-id = ; + label = "slv-ocmem-gfx"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + }; + + + slv_ovirt_snoc: slv-ovirt-snoc { + cell-id = ; + label = "slv-ovirt-snoc"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&mas_ovirt_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* pnoc Devices */ + mas_bam_dma: mas-bam-dma { + cell-id = ; + label = "mas-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_sdcc_1 &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_2: mas-blsp-2 { + cell-id = ; + label = "mas-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_1: mas-blsp-1 { + cell-id = ; + label = "mas-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tsif: mas-tsif { + cell-id = ; + label = "mas-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_usb_hs: mas-usb-hs { + cell-id = ; + label = "mas-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_tsif &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_pnoc_cfg: mas-pnoc-cfg { + cell-id = ; + label = "mas-pnoc-cfg"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_prng>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_1: mas-sdcc-1 { + cell-id = ; + label = "mas-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_2: mas-sdcc-2 { + cell-id = ; + label = "mas-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_3: mas-sdcc-3 { + cell-id = ; + label = "mas-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_4: mas-sdcc-4 { + cell-id = ; + label = "mas-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_pnoc: mas-snoc-pnoc { + cell-id = ; + label = "mas-snoc-pnoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 + &slv_blsp_2 &slv_blsp_1 &slv_tsif &slv_usb_hs + &slv_pdm &slv_prng>; + qcom,mas-rpm-id = ; + }; + + + slv_bam_dma: slv-bam-dma { + cell-id = ; + label = "slv-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_1: slv-sdcc-1 { + cell-id = ; + label = "slv-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_3: slv-sdcc-3 { + cell-id = ; + label = "slv-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_2: slv-blsp-2 { + cell-id = ; + label = "slv-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_2: slv-sdcc-2 { + cell-id = ; + label = "slv-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_4: slv-sdcc-4 { + cell-id = ; + label = "slv-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_1: slv-blsp-1 { + cell-id = ; + label = "slv-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tsif: slv-tsif { + cell-id = ; + label = "slv-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_usb_hs: slv-usb-hs { + cell-id = ; + label = "slv-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pdm: slv-pdm { + cell-id = ; + label = "slv-pdm"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_prng: slv-prng { + cell-id = ; + label = "slv-prng"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_periph_snoc: slv-periph-snoc { + cell-id = ; + label = "slv-periph-snoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_periph_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* cnoc Devices */ + mas_rpm_inst: mas-rpm-inst { + cell-id = ; + label = "mas-rpm-inst"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_boot_rom>; + qcom,mas-rpm-id = ; + }; + + + mas_rpm_sys: mas-rpm-sys { + cell-id = ; + label = "mas-rpm-sys"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg + &slv_security &slv_tcsr &slv_tlmm &slv_crypto_0_cfg + &slv_crypto_1_cfg &slv_imem_cfg &slv_message_ram + &slv_bimc_cfg &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper + &slv_dehr_cfg &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg + &slv_snoc_cfg &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg + &slv_phy_apu_cfg &slv_ebi1_phy_cfg &slv_pcie_0_cfg + &slv_pcie_1_cfg &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_dehr: mas-dehr { + cell-id = ; + label = "mas-dehr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bimc_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_spdm: mas-spdm { + cell-id = ; + label = "mas-spdm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tic: mas-tic { + cell-id = ; + label = "mas-tic"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_cnoc: mas-snoc-cnoc { + cell-id = ; + label = "mas-snoc-cnoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_dap: mas-qdss-dap { + cell-id = ; + label = "mas-qdss-dap"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + slv_clk_ctl: slv-clk-ctl { + cell-id = ; + label = "slv-clk-ctl"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_2_cfg: slv-crypto-2-cfg { + cell-id = ; + label = "slv-crypto-2-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_security: slv-security { + cell-id = ; + label = "slv-security"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tcsr: slv-tcsr { + cell-id = ; + label = "slv-tcsr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tlmm: slv-tlmm { + cell-id = ; + label = "slv-tlmm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_0_cfg: slv-crypto-0-cfg { + cell-id = ; + label = "slv-crypto-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_1_cfg: slv-crypto-1-cfg { + cell-id = ; + label = "slv-crypto-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_imem_cfg: slv-imem-cfg { + cell-id = ; + label = "slv-imem-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_message_ram: slv-message-ram { + cell-id = ; + label = "slv-message-ram"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_cfg: slv-bimc-cfg { + cell-id = ; + label = "slv-bimc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_boot_rom: slv-boot-rom { + cell-id = ; + label = "slv-boot-rom"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_mmss_cfg: slv-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_mmss_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pmic_arb: slv-pmic-arb { + cell-id = ; + label = "slv-pmic-arb"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spdm_wrapper: slv-spdm-wrapper { + cell-id = ; + label = "slv-spdm-wrapper"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_dehr_cfg: slv-dehr-cfg { + cell-id = ; + label = "slv-dehr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_mpm: slv-mpm { + cell-id = ; + label = "slv-mpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_cfg: slv-qdss-cfg { + cell-id = ; + label = "slv-qdss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_qdss_apu_cfg: slv-rbcpr-qdss-apu-cfg { + cell-id = ; + label = "slv-rbcpr-qdss-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_cfg: slv-rbcpr-cfg { + cell-id = ; + label = "slv-rbcpr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_cfg: slv-cnoc-mnoc-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pnoc_cfg: slv-pnoc-cfg { + cell-id = ; + label = "slv-pnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_pnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cfg: slv-snoc-cfg { + cell-id = ; + label = "slv-snoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_mpu_cfg: slv-snoc-mpu-cfg { + cell-id = ; + label = "slv-snoc-mpu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_dll_cfg: slv-ebi1-dll-cfg { + cell-id = ; + label = "slv-ebi1-dll-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_phy_apu_cfg: slv-phy-apu-cfg { + cell-id = ; + label = "slv-phy-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_phy_cfg: slv-ebi1-phy-cfg { + cell-id = ; + label = "slv-ebi1-phy-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rpm: slv-rpm { + cell-id = ; + label = "slv-rpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0_cfg: slv-pcie-0-cfg { + cell-id = ; + label = "slv-pcie-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1_cfg: slv-pcie-1-cfg { + cell-id = ; + label = "slv-pcie-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spss_geni_ir: slv-spss-geni-ir { + cell-id = ; + label = "slv-spss-geni-ir"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ufs_cfg: slv-ufs-cfg { + cell-id = ; + label = "slv-ufs-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_snoc: slv-cnoc-snoc { + cell-id = ; + label = "slv-cnoc-snoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_snoc>; + qcom,slv-rpm-id = ; + }; + }; + + static-rules { + compatible = "qcom,msm-bus-static-bw-rules"; + + rule0 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <250000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <600000>; + }; + + rule1 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <900000>; + }; + + rule2 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + }; + }; + + devfreq_spdm_cpu { + compatible = "qcom,devfreq_spdm"; + qcom,msm-bus,name = "devfreq_spdm"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 512 0 0>, + <1 512 0 0>; + qcom,msm-bus,active-only; + qcom,spdm-client = <0>; + + clock-names = "cci_clk"; + clocks = <&clock_cpu clk_cci_clk>; + + qcom,bw-upstep = <1000>; + qcom,bw-dwnstep = <1000>; + qcom,max-vote = <10000>; + qcom,up-step-multp = <2>; + qcom,spdm-interval = <100>; + + qcom,ports = <16>; + qcom,alpha-up = <7>; + qcom,alpha-down = <15>; + qcom,bucket-size = <8>; + + /*max pl1 freq, max pl2 freq*/ + qcom,pl-freqs = <140000000 160000000>; + + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,reject-rate = <5000 5000 5000 5000 5000 5000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,response-time-us = <10000 10000 10000 10000 3000 3000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,cci-response-time-us = <10000 10000 10000 10000 1000 1000>; + qcom,max-cci-freq = <600000000>; + }; + + devfreq_spdm_gov { + compatible = "qcom,gov_spdm_hyp"; + interrupt-names = "spdm-irq"; + interrupts = <0 192 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-sensor-mtp.dtsi new file mode 100644 index 0000000000000..f086302c5c958 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-sensor-mtp.dtsi @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + led_flash0: qcom,camera-flash { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-type = <1>; + qcom,flash-source = <&pmi8994_flash0 &pmi8994_flash1>; + qcom,torch-source = <&pmi8994_torch0 &pmi8994_torch1>; + }; +}; + +&cci { +//added by Likelong 2015.3.23 for proximity sensor start + proximity:qcom,proximity@0 { + cell-index = <0>; + reg = <0x29>; + compatible = "stmv,vl6180"; + qcom,cci-master = <0>;//use the same I2C bus with main camera + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.3.23 for proximity sensor end + + actuator0: qcom,actuator@0 { + cell-index = <0>; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + reg = <0x1C>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; +/* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8994_l23>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <100000>; + }; + +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + ois0: qcom,ois@0 { + cell-index = <0>; + reg = <0x1C>; + compatible = "qcom,ois"; + qcom,cci-master = <0>; + /* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + reg = <0x0>; + qcom,eeprom-name = "ov13860"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <7>; + + qcom,page0 = <0 0x0000 2 0x00 1 5>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <47 0x0000 2 0 1 0>; + + qcom,page1 = <0 0x0000 2 0x00 1 5>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0xa0>; + qcom,mem1 = <40 0x0100 2 0 1 0>; + + qcom,page2 = <0 0x0000 2 0x00 1 5>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0xa0>; + qcom,mem2 = <255 0x0200 2 0 1 0>; + + qcom,page3 = <0 0x0000 2 0x00 1 5>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0xa0>; + qcom,mem3 = <255 0x0300 2 0 1 0>; + + qcom,page4 = <0 0x0000 2 0x00 1 5>; + qcom,pageen4 = <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0xa0>; + qcom,mem4 = <255 0x0400 2 0 1 0>; + + qcom,page5 = <0 0x0000 2 0x00 1 5>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0xa0>; + qcom,mem5 = <255 0x0500 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0xa0>; + qcom,mem6 = <89 0x0600 2 0 1 0>; + +/* Kangjian,201/12/18,Add for camera driver */ + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000>; + /*#endif*/ + + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + <&msm_gpio 102 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,cam-power-seq-type = "sensor_gpio", "sensor_vreg", "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "sensor_gpio_standby", "cam_vio", "cam_vana", "cam_vdig", + "sensor_gpio_reset","sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <1 0 0 0 1 24000000 0>; + qcom,cam-power-seq-delay = <0 0 0 0 0 0 0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + +/*muyuezhong@camera,2015-4-29,add for ov5648 OTP functions begin*/ + eeprom1: qcom,eeprom@1 { + cell-index = <2>; + reg = <0x2>; + qcom,eeprom-name = "ov5648"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <1>; + qcom,num-blocks = <26>; + + //read group 1:begin + qcom,page0 = <1 0x0103 2 0x01 1 0>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0x6c>; + qcom,mem0 = <0 0x0000 2 0 1 0>; + + qcom,page1 = <1 0x0100 2 0x01 1 0>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0x6c>; + qcom,mem1 = <0 0x0000 2 0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0x6c>; + qcom,mem2 = <0 0x0000 2 0 1 0>; + + qcom,page3 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0x6c>; + qcom,mem3 = <0 0x0000 2 0 1 0>; + + qcom,page4 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen4= <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0x6c>; + qcom,mem4 = <0 0x0000 2 0 1 0>; + + qcom,page5 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0x6c>; + qcom,mem5 = <0 0x0000 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0x6c>; + qcom,mem6 = <9 0x3d05 2 0 1 0>; + + qcom,page7 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen7 = <16 0x3d00 2 0x00 1 0>; + qcom,poll7 = <0 0x0000 2 0x00 1 5>; + qcom,saddr7 = <0x6c>; + qcom,mem7 = <0 0x0000 2 0 1 0>; + //read group 1:end +/*muyuezhong@camera,2015-8-12,add for other otp group*/ + //read group 2:begin + qcom,page8 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen8 = <0 0x0000 2 0x00 1 5>; + qcom,poll8 = <0 0x0000 2 0x00 1 5>; + qcom,saddr8 = <0x6c>; + qcom,mem8 = <0 0x0000 2 0 1 0>; + + qcom,page9 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen9 = <0 0x0000 2 0x00 1 5>; + qcom,poll9 = <0 0x0000 2 0x00 1 5>; + qcom,saddr9 = <0x6c>; + qcom,mem9 = <0 0x0000 2 0 1 0>; + + qcom,page10 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen10= <0 0x0000 2 0x00 1 5>; + qcom,poll10 = <0 0x0000 2 0x00 1 5>; + qcom,saddr10 = <0x6c>; + qcom,mem10 = <0 0x0000 2 0 1 0>; + + qcom,page11 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen11 = <0 0x0000 2 0x00 1 5>; + qcom,poll11 = <0 0x0000 2 0x00 1 5>; + qcom,saddr11 = <0x6c>; + qcom,mem11 = <0 0x0000 2 0 1 0>; + + qcom,page12 = <0 0x0000 2 0x00 1 5>; + qcom,pageen12 = <0 0x0000 2 0x00 1 5>; + qcom,poll12 = <0 0x0000 2 0x00 1 5>; + qcom,saddr12 = <0x6c>; + qcom,mem12 = <2 0x3d0e 2 0 1 0>; + + qcom,page13 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen13 = <0 0x0000 2 0x00 1 5>; + qcom,poll13 = <0 0x0000 2 0x00 1 5>; + qcom,saddr13 = <0x6c>; + qcom,mem13 = <0 0x0000 2 0 1 0>; + + qcom,page14 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen14 = <0 0x0000 2 0x00 1 5>; + qcom,poll14 = <0 0x0000 2 0x00 1 5>; + qcom,saddr14 = <0x6c>; + qcom,mem14 = <0 0x0000 2 0 1 0>; + + qcom,page15 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen15= <0 0x0000 2 0x00 1 5>; + qcom,poll15 = <0 0x0000 2 0x00 1 5>; + qcom,saddr15 = <0x6c>; + qcom,mem15 = <0 0x0000 2 0 1 0>; + + qcom,page16 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen16 = <0 0x0000 2 0x00 1 5>; + qcom,poll16 = <0 0x0000 2 0x00 1 5>; + qcom,saddr16 = <0x6c>; + qcom,mem16 = <0 0x0000 2 0 1 0>; + + qcom,page17 = <0 0x0000 2 0x00 1 5>; + qcom,pageen17 = <0 0x0000 2 0x00 1 5>; + qcom,poll17 = <0 0x0000 2 0x00 1 5>; + qcom,saddr17 = <0x6c>; + qcom,mem17 = <7 0x3d00 2 0 1 0>; + + qcom,page18 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen18 = <16 0x3d00 2 0x00 1 0>; + qcom,poll18 = <0 0x0000 2 0x00 1 5>; + qcom,saddr18 = <0x6c>; + qcom,mem18 = <0 0x0000 2 0 1 0>; + //read group 2:end + + //read group 3:begin + qcom,page19 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen19 = <0 0x0000 2 0x00 1 5>; + qcom,poll19 = <0 0x0000 2 0x00 1 5>; + qcom,saddr19 = <0x6c>; + qcom,mem19 = <0 0x0000 2 0 1 0>; + + qcom,page20 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen20 = <0 0x0000 2 0x00 1 5>; + qcom,poll20 = <0 0x0000 2 0x00 1 5>; + qcom,saddr20 = <0x6c>; + qcom,mem20 = <0 0x0000 2 0 1 0>; + + qcom,page21 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen21= <0 0x0000 2 0x00 1 5>; + qcom,poll21 = <0 0x0000 2 0x00 1 5>; + qcom,saddr21 = <0x6c>; + qcom,mem21 = <0 0x0000 2 0 1 0>; + + qcom,page22 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen22 = <0 0x0000 2 0x00 1 5>; + qcom,poll22 = <0 0x0000 2 0x00 1 5>; + qcom,saddr22 = <0x6c>; + qcom,mem22 = <0 0x0000 2 0 1 0>; + + qcom,page23 = <0 0x0000 2 0x00 1 5>; + qcom,pageen23 = <0 0x0000 2 0x00 1 5>; + qcom,poll23 = <0 0x0000 2 0x00 1 5>; + qcom,saddr23 = <0x6c>; + qcom,mem23 = <9 0x3d07 2 0 1 0>; + + qcom,page24 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen24 = <16 0x3d00 2 0x00 1 0>; + qcom,poll24 = <0 0x0000 2 0x00 1 5>; + qcom,saddr24 = <0x6c>; + qcom,mem24 = <0 0x0000 2 0 1 0>; + + qcom,page25 = <1 0x0100 2 0x00 1 0>; + qcom,pageen25 = <0 0x0000 2 0x00 1 5>; + qcom,poll25 = <0 0x0000 2 0x00 1 5>; + qcom,saddr25 = <0x6c>; + qcom,mem25= <0 0x0000 2 0 1 0>; + //read group 3:end + + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2","CAM_RESET2","CAM_STANDBY2"; + + qcom,cam-power-seq-type = "sensor_vreg","sensor_vreg", "sensor_gpio", "sensor_gpio", + "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "cam_vio","cam_vana", "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 24000000 0>; + qcom,cam-power-seq-delay = <0 5 0 0 0 0>; + + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>,<&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* muyuezhong@camera,2015-4-29,add for ov5648 OTP functions end*/ + +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ +/* + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <2>; + qcom,eeprom-name = "onsemi_cat24c32"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <2245 0x00 2 0 1 0>; + + cam_vio-supply = <&pm8994_lvs1>; + qcom,cam-vreg-name = "cam_vio"; + qcom,cam-vreg-min-voltage = <0>; + qcom,cam-vreg-max-voltage = <0>; + qcom,cam-vreg-op-mode = <0>; + qcom,cam-power-seq-type = "sensor_vreg"; + qcom,cam-power-seq-val = "cam_vio"; + qcom,cam-power-seq-cfg-val = <1>; + qcom,cam-power-seq-delay = <1>; + status = "ok"; + }; +*/ +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom0>; + qcom,actuator-src = <&actuator0>; +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + qcom,ois-src = <&ois0>; + qcom,led-flash-src = <&led_flash0>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + cam_v_custom1-supply = <&pm8994_l29>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_v_custom1"; + /*liuyan 2015/7/20, change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000 2800000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000 2800000>; + /*#endif*/ + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, + <&msm_gpio 102 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vaf = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0 >; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VAF0"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 0 2700000>; + qcom,cam-vreg-max-voltage = <1200000 0 2700000>; + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend &cam_sensor_rear2_suspend>; + gpios = <&msm_gpio 14 0>, + <&msm_gpio 94 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_STANDBY1"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +*/ + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom1>; + //qcom,actuator-src = <&actuator1>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; +/* Kangjian,2014/12/18,Add end */ diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v1.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v1.dtsi new file mode 100755 index 0000000000000..b1c810d391efe --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v1.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v2.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v2.dtsi new file mode 100755 index 0000000000000..b101e98dde0dd --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera-v2.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-camera.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera.dtsi new file mode 100755 index 0000000000000..03e578bcf4121 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-camera.dtsi @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,msm-cam@fd8c0000 { + compatible = "qcom,msm-cam"; + reg = <0xfd8c0000 0x10000>; + reg-names = "msm-cam"; + }; + + qcom,csiphy@fda0ac00 { + cell-index = <0>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0ac00 0x200>, + <0xfda00030 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 78 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0phy_clk>, + <&clock_mmss clk_csi0phytimer_clk_src>, + <&clock_mmss clk_camss_phy0_csi0phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b000 { + cell-index = <1>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b000 0x200>, + <0xfda00038 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 79 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1phy_clk>, + <&clock_mmss clk_csi1phytimer_clk_src>, + <&clock_mmss clk_camss_phy1_csi1phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b400 { + cell-index = <2>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b400 0x200>, + <0xfda00040 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 80 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2phy_clk>, + <&clock_mmss clk_csi2phytimer_clk_src>, + <&clock_mmss clk_camss_phy2_csi2phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csid@fda08000 { + cell-index = <0>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08000 0x400>; + reg-names = "csid"; + interrupts = <0 51 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0_ahb_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08400 { + cell-index = <1>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08400 0x400>; + reg-names = "csid"; + interrupts = <0 52 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1_ahb_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08800 { + cell-index = <2>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08800 0x400>; + reg-names = "csid"; + interrupts = <0 53 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2_ahb_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08c00 { + cell-index = <3>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08C00 0x100>; + reg-names = "csid"; + interrupts = <0 54 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3_ahb_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,ispif@fda0a000 { + cell-index = <0>; + compatible = "qcom,ispif-v3.0", "qcom,ispif"; + reg = <0xfda0A000 0x500>, + <0xfda00020 0x10>; + reg-names = "ispif", "csi_clk_mux"; + interrupts = <0 55 0>; + interrupt-names = "ispif"; + qcom,num-isps = <0x2>; + vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>; + clock-names = "ispif_ahb_clk", + "csi0_src_clk", "csi0_clk", + "csi0_pix_clk", "csi0_rdi_clk", + "csi1_src_clk", "csi1_clk", + "csi1_pix_clk", "csi1_rdi_clk", + "csi2_src_clk", "csi2_clk", + "csi2_pix_clk", "csi2_rdi_clk", + "csi3_src_clk", "csi3_clk", + "csi3_pix_clk", "csi3_rdi_clk", + "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk", + "vfe1_clk_src", "camss_vfe_vfe1_clk", "camss_csi_vfe1_clk"; + qcom,clock-rates = "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "-2", "0", "0", + "-2", "0", "0"; + }; + + vfe0: qcom,vfe@fda10000 { + cell-index = <0>; + compatible = "qcom,vfe46"; + reg = <0xfda10000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 57 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + + }; + + vfe1: qcom,vfe@fda14000 { + cell-index = <1>; + compatible = "qcom,vfe46"; + reg = <0xfda14000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 58 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + }; + + + qcom,jpeg@fda1c000 { + cell-index = <0>; + compatible = "qcom,jpeg"; + reg = <0xfda1c000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 59 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", + "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda20000 { + cell-index = <1>; + compatible = "qcom,jpeg"; + reg = <0xfda20000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 60 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda24000 { + cell-index = <2>; + compatible = "qcom,jpeg"; + reg = <0xfda24000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 61 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg2_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + qcom,jpeg@fdaa0000 { + cell-index = <3>; + compatible = "qcom,jpeg_dma"; + reg = <0xfdaa0000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 304 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_dma_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + + qcom,irqrouter@fda00000 { + cell-index = <0>; + compatible = "qcom,irqrouter"; + reg = <0xfda00000 0x100>; + reg-names = "irqrouter"; + }; + + qcom,cpp@fda04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xfda04000 0x100>, + <0xfda80000 0x200>, + <0xfda18000 0x008>; + reg-names = "cpp", "cpp_vbif", "cpp_hw"; + interrupts = <0 49 0>; + interrupt-names = "cpp"; + vdd-supply = <&gdsc_cpp>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cpp_core_clk", + "camss_vfe_cpp_ahb_clk", "camss_vfe_cpp_axi_clk", + "camss_vfe_cpp_clk","micro_iface_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 465000000 0 0 465000000 0 0>; + qcom,min-clock-rate = <320000000>; + }; + + qcom,fd@fd878000 { + cell-index = <0>; + compatible = "qcom,face-detection"; + reg = <0xfd878000 0x800>, + <0xfd87c000 0x800>, + <0xfd860000 0x1000>; + reg-names = "fd_core", "fd_misc", "fd_vbif"; + interrupts = <0 316 0>; + interrupt-names = "fd"; + vdd-supply = <&gdsc_fd>; + clocks = <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>, + <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>; + clock-names = "fd_core_clk", "fd_core_uar_clk", + "fd_axi_clk", "fd_ahb_clk"; + clock-rates = <60000000 60000000 75000000 40000000>, + <200000000 200000000 150000000 40000000>, + <400000000 400000000 333000000 80000000>; + }; + + cci: qcom,cci@fda0c000 { + cell-index = <0>; + compatible = "qcom,cci"; + reg = <0xfda0c000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "cci"; + interrupts = <0 50 0>; + interrupt-names = "cci"; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cci_clk_src>, + <&clock_mmss clk_camss_cci_cci_ahb_clk>, + <&clock_mmss clk_camss_cci_cci_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cci_src_clk", + "cci_ahb_clk", "camss_cci_clk", + "camss_ahb_clk"; + qcom,clock-rates = <0 19200000 0 0 0>, + <0 37500000 0 0 0>; + pinctrl-names = "cci_default", "cci_suspend"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + gpios = <&msm_gpio 17 0>, + <&msm_gpio 18 0>, + <&msm_gpio 19 0>, + <&msm_gpio 20 0>; + qcom,gpio-tbl-num = <0 1 2 3>; + qcom,gpio-tbl-flags = <1 1 1 1>; + qcom,gpio-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + i2c_freq_100Khz: qcom,i2c_standard_mode { + status = "disabled"; + }; + i2c_freq_400Khz: qcom,i2c_fast_mode { + status = "disabled"; + }; + i2c_freq_custom: qcom,i2c_custom_mode { + status = "disabled"; + }; + + i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { + status = "disabled"; + }; + + }; +}; + +&i2c_freq_100Khz { + qcom,hw-thigh = <104>; + qcom,hw-tlow = <88>; + qcom,hw-tsu-sto = <105>; + qcom,hw-tsu-sta = <119>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <84>; + qcom,hw-tbuf = <116>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_400Khz { + qcom,hw-thigh = <20>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <32>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_custom { + qcom,hw-thigh = <15>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <25>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_1Mhz { + qcom,hw-thigh = <16>; + qcom,hw-tlow = <22>; + qcom,hw-tsu-sto = <17>; + qcom,hw-tsu-sta = <18>; + qcom,hw-thd-dat = <16>; + qcom,hw-thd-sta = <15>; + qcom,hw-tbuf = <19>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <3>; + qcom,hw-tsp = <3>; + qcom,cci-clk-src = <37500000>; + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v1.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v1.dtsi new file mode 100755 index 0000000000000..b6ad994e6ae35 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v1.dtsi @@ -0,0 +1,774 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <9>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <10>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <11>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <12>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <18>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <19>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <20>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <21>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <22>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <23>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <24>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <25>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <44>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <45>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v2.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v2.dtsi new file mode 100755 index 0000000000000..681adbaf1c818 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-coresight-v2.dtsi @@ -0,0 +1,829 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + qcom,sg-enable; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss1: funnel@fbb70000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb70000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss1"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <0>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <9>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpda_lmh: tpda@fbb91000 { + compatible = "qcom,coresight-tpda"; + reg = <0xfbb91000 0x1000>; + reg-names = "tpda-base"; + + coresight-id = <10>; + coresight-name = "coresight-tpda-lmh"; + coresight-nr-inports = <32>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <3>; + + qcom,tpda-atid = <64>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpdm_lmh: tpdm@fbb90000 { + compatible = "qcom,coresight-tpdm"; + reg = <0xfbb90000 0x1000>; + reg-names = "tpdm-base"; + + coresight-id = <11>; + coresight-name = "coresight-tpdm-lmh"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&tpda_lmh>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <12>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <18>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <19>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <20>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <21>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <22>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <23>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <24>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <25>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <44>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <45>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <46>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <47>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <48>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-gpu.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-gpu.dtsi new file mode 100755 index 0000000000000..3d63cf8d2076c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-gpu.dtsi @@ -0,0 +1,181 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + msm_bus: qcom,kgsl-busmon{ + label = "kgsl-busmon"; + compatible = "qcom,kgsl-busmon"; + }; + + gpubw: qcom,gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,gpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc390000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <2>; + qcom,target-dev = <&gpubw>; + }; + + msm_gpu: qcom,kgsl-3d0@fdb00000 { + label = "kgsl-3d0"; + compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d"; + reg = <0xfdb00000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 33 0>; + interrupt-names = "kgsl_3d0_irq"; + qcom,id = <0>; + + qcom,chipid = <0x04030000>; + + qcom,initial-pwrlevel = <2>; + + qcom,idle-timeout = <8>; // + qcom,strtstp-sleepwake; + + qcom,pm-qos-active-latency = <501>; + qcom,pm-qos-wakeup-latency = <101>; + + /* + * Clocks = KGSL_CLK_CORE | KGSL_CLK_IFACE + * KGSL_CLK_RBBMTIMER + */ + qcom,clk-map = <0x00000086>; + + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>, + <&clock_mmss clk_oxili_rbbmtimer_clk>; + clock-names = "core_clk", "iface_clk", "rbbmtimer_clk"; + + /* Bus Scale Settings */ + qcom,gpubw-dev = <&gpubw>; + qcom,bus-control; + /* + * qcom,msm-bus structures below define + * GPU msm client and its vote data for + * each of available power levels + * (gpu-bus frequency combination) + */ + qcom,msm-bus,name = "grp3d"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1200000>, /* 1 bus=150 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3200000>, /* 3 bus=460 */ + <26 512 0 4224000>, /* 4 bus=533 */ + <26 512 0 5376000>, /* 5 bus=672 */ + <26 512 0 6681600>, /* 6 bus=777 */ + <26 512 0 8448000>, /* 7 bus=1036 */ + <26 512 0 12748800>; /* 8 bus=1555 */ + + /* GDSC oxili regulators */ + vddcx-supply = <&gdsc_oxili_cx>; + vdd-supply = <&gdsc_oxili_gx>; + + /* IOMMU Data */ + iommu = <&kgsl_iommu>; + + /* Trace bus */ + coresight-id = <67>; + coresight-name = "coresight-gfx"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <4>; + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <400000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <300000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <2>; + qcom,bus-max = <5>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <150000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <27000000>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + qcom,bus-freq = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <5>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu=600 */ + <89 662 0 6400000>, /* gpu=400 */ + <89 662 0 4800000>, /* gpu=300 */ + <89 662 0 2400000>, /* gpu=150 */ + <89 662 0 0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu-domains.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu-domains.dtsi new file mode 100755 index 0000000000000..840818c2d7cb3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu-domains.dtsi @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,iommu-domains { + compatible = "qcom,iommu-domains"; + + venus_domain_ns: qcom,iommu-domain1 { + label = "venus_ns"; + qcom,iommu-contexts = <&venus_ns>; + qcom,virtual-addr-pool = <0x5dc00000 0x7f000000 + 0xdcc00000 0x1000000>; + }; + + venus_domain_sec_bitstream: qcom,iommu-domain2 { + label = "venus_sec_bitstream"; + qcom,iommu-contexts = <&venus_sec_bitstream>; + qcom,virtual-addr-pool = <0x4b000000 0x12c00000>; + qcom,secure-domain; + }; + + venus_domain_sec_pixel: qcom,iommu-domain3 { + label = "venus_sec_pixel"; + qcom,iommu-contexts = <&venus_sec_pixel>; + qcom,virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-domain; + }; + + venus_domain_sec_non_pixel: qcom,iommu-domain4 { + label = "venus_sec_non_pixel"; + qcom,iommu-contexts = <&venus_sec_non_pixel>; + qcom,virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-domain; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu.dtsi new file mode 100755 index 0000000000000..0638ffc0a6b3c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-iommu.dtsi @@ -0,0 +1,430 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm-iommu-v1.dtsi" + +&soc { + mdp_iommu_8994: qcom,iommu@fd9cc000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd9cc000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + status = "ok"; + vdd-supply = <&gdsc_mdss>; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018>; + + qcom,iommu-bfb-data = <0x3 + 0x7fffff + 0x1777 + 0x0 + 0x4 + 0x10 + 0x5000 + 0x182c1 + 0x5a1d + 0x1822d + 0x0 + 0x0 + 0x28 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd9d4000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d4000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd9d5000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d5000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd9d6000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d6000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; +}; + +&venus_iommu { + status = "ok"; + vdd-supply = <&gdsc_venus>; + clocks = <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c>; + + qcom,iommu-bfb-data = <0x3 + 0x7ffffff + 0x1555 + 0x0 + 0x4 + 0x8 + 0x13607 + 0x140a0 + 0x4000 + 0x14020 + 0x0 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + qcom,iommu-ctx-sids = <0x00 0x21 0x45 0x47 0x48 0x49 0x4a + 0x4b 0x4c 0x65 0x67 0x69 0x6a 0x6b>; + qcom,iommu-sid-mask = <0x0 0xf 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 { + qcom,iommu-ctx-sids = <0x400 0x421 0x422 0x423 0x424 0x448 + 0x44a 0x46a>; + label = "venus_sec_bitstream"; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + qcom,iommu-ctx-sids = <0x600 0x606>; + }; + + venus_sec_pixel: qcom,iommu-ctx@fdc8f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8f000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x425 0x428 0x445 0x44c 0x465>; + label = "venus_sec_pixel"; + qcom,secure-context; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc90000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x427 0x447 0x449 0x44b 0x467 0x469 0x46b + 0x500>; + label = "venus_sec_non_pixel"; + qcom,secure-context; + }; +}; + +&jpeg_iommu { + status = "ok"; + vdd-supply = <&gdsc_jpeg>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0x3ffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2000 + 0xe673 + 0x2c00 + 0xe616 + 0x0 + 0x0 + 0x10 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6f000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <3>; + label = "jpeg_dma"; + }; +}; + +&kgsl_iommu { + status = "ok"; + vdd-supply = <&gdsc_oxili_cx>; + qcom,alt-vdd-supply = <&gdsc_oxili_gx>; + qcom,iommu-secure-id = <18>; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x2600 + 0x2604 + 0x2608 + 0x260c + 0x2610 + 0x2614 + 0x2618 + 0x261c + 0x2620 + 0x2624 + 0x2628 + 0x262c>; + + qcom,iommu-bfb-data = <0x3 + 0x3 + 0x1555 + 0x0 + 0x0 + 0x10 + 0x0 + 0x120 + 0x120 + 0x10 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x7 + 0x0 + 0x20 + 0x20 + 0x0c + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x10>; + + qcom,iommu-ctx@fdb18000 { + qcom,iommu-ctx-sids = <0 1>; + }; + + qcom,iommu-ctx@fdb19000 { + qcom,iommu-ctx-sids = <>; + }; + + qcom,iommu-ctx@fdb1a000 { + qcom,iommu-ctx-sids = <2>; + interrupts = <0 241 0>, <0 240 0>; + qcom,secure-context; + linux,contiguous-region = <&secure_mem>; + }; +}; + +&vfe_iommu { + status = "ok"; + vdd-supply = <&gdsc_vfe>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0xfffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2400 + 0x8844 + 0x2400 + 0x8812 + 0x0 + 0x0 + 0x12 + 0x5a + 0x0 + 0x0 + 0x0 + 0x0>; +}; + +&fd_iommu { + status = "ok"; + vdd-supply = <&gdsc_fd>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>, + <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk", "alt_iface_clk"; +}; + +&cpp_iommu { + status = "ok"; + vdd-supply = <&gdsc_cpp>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-ion.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-ion.dtsi new file mode 100755 index 0000000000000..16b920e069108 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-ion.dtsi @@ -0,0 +1,63 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ion { + compatible = "qcom,msm-ion"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,ion-heap@25 { + reg = <25>; + qcom,ion-heap-type = "SYSTEM"; + }; + + qcom,ion-heap@21 { + reg = <21>; + qcom,ion-heap-type = "SYSTEM_CONTIG"; + }; + + qcom,ion-heap@8 { /* CP_MM HEAP */ + compatible = "qcom,msm-ion-reserve"; + reg = <8>; + qcom,heap-align = <0x1000>; + linux,contiguous-region = <&secure_mem>; + qcom,ion-heap-type = "SECURE_DMA"; + qcom,default-prefetch-size = <0x6c00000>; + }; + + qcom,ion-heap@22 { /* adsp heap */ + reg = <22>; + linux,contiguous-region = <&adsp_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@27 { /* QSECOM HEAP */ + reg = <27>; + linux,contiguous-region = <&qsecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@28 { /* AUDIO HEAP */ + reg = <28>; + linux,contiguous-region = <&audio_mem>; + qcom,ion-heap-type = "DMA"; + }; + + adsp_venus_heap: qcom,ion-heap@23 { + compatible = "qcom,msm-ion-reserve"; + reg = <23>; + linux,contiguous-region = <&peripheral_mem>; + qcom,ion-heap-type = "DMA"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-ipcrouter.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-ipcrouter.dtsi new file mode 100755 index 0000000000000..006bd32eb5957 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-ipcrouter.dtsi @@ -0,0 +1,37 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ipc_router { + compatible = "qcom,ipc_router"; + qcom,node-id = <1>; + }; + + qcom,ipc_router_modem_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "modem"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + qcom,disable-pil-loading; + }; + + qcom,ipc_router_q6_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "adsp"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss-pll.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss-pll.dtsi new file mode 100755 index 0000000000000..a6cd3a43e5a65 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss-pll.dtsi @@ -0,0 +1,171 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@fd998300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xfd998300 0x500>, + <0xfd8c2300 0x8>, + <0xfd998200 0x64>, + <0xfd9a0300 0x500>; + reg-names = "pll_base", "gdsc_base", "dynamic_pll_base", + "pll_1_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-en-pll-90-phase; + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + /* Dynamic FPS data region */ + linux,contiguous-region = <&dfps_data_mem>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + mdss_dsi1_pll: qcom,mdss_dsi_pll@fd9a0300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xfd9a0300 0x500>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + + mdss_hdmi_pll: qcom,mdss_hdmi_pll@0xfd9a8600 { + compatible = "qcom,mdss_hdmi_pll_8994"; + label = "MDSS HDMI PLL"; + #clock-cells = <1>; + + reg = <0xfd9a8600 0xac4>, + <0xfd9a9200 0x0C8>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "phy_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss.dtsi new file mode 100755 index 0000000000000..269101b45a411 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-mdss.dtsi @@ -0,0 +1,508 @@ +/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_mdp: qcom,mdss_mdp@fd900000 { + compatible = "qcom,mdss_mdp"; + reg = <0xfd900000 0x90000>, + <0xfd9c8000 0x004d4>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-ib-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2048>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,mdss-vbif-qos-nrt-setting = <1 1 1 1>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <7300000>; + qcom,max-bandwidth-high-kbps = <7300000>; + qcom,max-bandwidth-per-pipe-kbps = <1800000>; + qcom,max-clk-rate = <400000000>; + qcom,mdss-dram-channels = <2>; + qcom,mdss-default-ot-wr-limit = <16>; + qcom,mdss-default-ot-rd-limit = <16>; + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000 + 0x00009000 0x0000B000>; + qcom,mdss-pipe-rgb-off = <0x00015000 0x00017000 + 0x00019000 0x0001B000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000>; + qcom,mdss-pipe-cursor-off = <0x00035000 0x00037000>; + + qcom,mdss-pipe-vig-fetch-id = <1 4 7 19>; + qcom,mdss-pipe-rgb-fetch-id = <16 17 18 22>; + qcom,mdss-pipe-dma-fetch-id = <10 13>; + + qcom,mdss-pipe-vig-xin-id = <0 4 8 12>; + qcom,mdss-pipe-rgb-xin-id = <1 5 9 13>; + qcom,mdss-pipe-dma-xin-id = <2 10>; + qcom,mdss-pipe-cursor-xin-id = <7 7>; + + qcom,mdss-en-svs-high; + qcom,mdss-has-panic-ctrl; + qcom,mdss-pipe-vig-panic-ctrl-offsets = <0 1 2 3>; + qcom,mdss-pipe-rgb-panic-ctrl-offsets = <4 5 6 7>; + qcom,mdss-pipe-dma-panic-ctrl-offsets = <8 9>; + + qcom,mdss-pipe-rgb-fixed-mmb = <5 0 1 8 9 10>, + <5 2 3 11 12 13>, + <5 4 5 14 15 16>, + <5 6 7 17 18 19>; + qcom,mdss-pipe-vig-fixed-mmb = <1 20>, + <1 21>, + <1 22>, + <1 23>; + + /* These Offsets are relative to "mdp_phys + mdp-reg-offset" address */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2AC 0 0>, + <0x2B4 0 0>, + <0x2BC 0 0>, + <0x2C4 0 0>; + qcom,mdss-pipe-rgb-clk-ctrl-offsets = <0x2AC 4 8>, + <0x2B4 4 8>, + <0x2BC 4 8>, + <0x2C4 4 8>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2AC 8 12>, + <0x2B4 8 12>; + + qcom,mdss-pipe-sw-reset-off = <0x0028>; + qcom,mdss-pipe-vig-sw-reset-map = <5 6 7 8>; + qcom,mdss-pipe-rgb-sw-reset-map = <9 10 11 12>; + qcom,mdss-pipe-dma-sw-reset-map = <13 14>; + + qcom,mdss-smp-data = <44 8192>; + qcom,mdss-sspp-len = <0x00002000>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004A000>; + qcom,mdss-mixer-wb-off = <0x00048000 0x00049000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000 0x00059000 + 0x0005B000>; + qcom,mdss-wb-off = <0x00065000 0x00065800 0x00066000 + 0x00066800 0x00067000>; + qcom,mdss-intf-off = <0x0006B000 0x0006B800 0x0006C000 + 0x0006C800 0x0006D000>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 0x00072000 + 0x00072800>; + qcom,mdss-ad-off = <0x0079000 0x00079800 0x0007A000>; + qcom,mdss-highest-bank-bit = <0x3>; + qcom,mdss-has-decimation; + qcom,mdss-has-rotator-downscale; + qcom,mdss-has-bwc; + + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + + qcom,mdss-ctl-len = <0x00000200>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdp_clk_src>, + <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_vsync_clk>; + clock-names = "iface_clk", "bus_clk", "core_clk_src", + "core_clk", "vsync_clk"; + + /* These Offsets are relative to "mdp_phys" address */ + qcom,mdp-settings = <0x0117c 0x00005555>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; + + qcom,regs-dump-mdp = <0x01000 0x01408>, + <0x02000 0x02064>, + <0x02200 0x02264>, + <0x02400 0x02464>, + <0x02600 0x02664>, + <0x02800 0x02864>, + <0x05000 0x05130>, + <0x05200 0x05230>, + <0x07000 0x07130>, + <0x07200 0x07230>, + <0x09000 0x09130>, + <0x09200 0x09230>, + <0x0b000 0x0b130>, + <0x0b200 0x0b230>, + <0x15000 0x15130>, + <0x15200 0x15230>, + <0x17000 0x17130>, + <0x17200 0x17230>, + <0x19000 0x19130>, + <0x19200 0x19230>, + <0x1b000 0x1b130>, + <0x1b200 0x1b230>, + <0x25000 0x2512C>, + <0x27000 0x2712C>, + <0x45000 0x4538c>, + <0x46000 0x4638c>, + <0x47000 0x4738c>, + <0x48000 0x4838c>, + <0x49000 0x4938c>, + <0x4a000 0x4a38c>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x59000 0x5922c>, + <0x5b000 0x5b22c>, + <0x65000 0x652b4>, + <0x65800 0x65ab4>, + <0x66000 0x662b4>, + <0x66800 0x66ab4>, + <0x67000 0x672b4>, + <0x6b800 0x6ba54>, + <0x6c000 0x6c254>, + <0x6c800 0x6ca54>, + <0x71000 0x710d0>, + <0x71800 0x718d0>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "VIG2_SSPP", "VIG2", "VIG3_SSPP", "VIG3", + "RGB0_SSPP", "RGB0", "RGB1_SSPP", "RGB1", + "RGB2_SSPP", "RGB2", "RGB3_SSPP", "RGB3", + "DMA0_SSPP", "DMA1_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_3", "LAYER_4", "LAYER_5", + "DSPP_0", "DSPP_1", "DSPP_2", "DSPP_3", + "WB_0", "WB_1", "WB_2", "WB_3", "WB_4", + "INTF_1", "INTF_2", "INTF_3", + "PP_0", "PP_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <2048>; + qcom,mdss-prefill-y-buffer-bytes = <4096>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2048>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + qcom,mdss-prefill-fbc-lines = <2>; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + qcom,cont-splash-memory { + linux,contiguous-region = <&cont_splash_mem>; + }; + }; + + mdss_fb1: qcom,mdss_fb_external { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_wfd { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + }; + }; + + mdss_dsi0: qcom,mdss_dsi@fd998000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xfd998000 0x260>, + <0xfd998500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte0_clk>, + <&clock_mmss clk_mdss_pclk0_clk>, + <&clock_mmss clk_mdss_esc0_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", "byte_clk_src", + "pixel_clk_src", "shadow_byte_clk_src", + "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + mdss_dsi1: qcom,mdss_dsi@fd9a0000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xfd9a0000 0x260>, + <0xfd9a0500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte1_clk>, + <&clock_mmss clk_mdss_pclk1_clk>, + <&clock_mmss clk_mdss_esc1_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", + "byte_clk_src", "pixel_clk_src", + "shadow_byte_clk_src", "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <1920 1080>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb2>; + }; + + mdss_hdmi_tx: qcom,hdmi_tx@fd9a8000{ + cell-index = <0>; + compatible = "qcom,hdmi-tx"; + + reg = <0xfd9a8000 0x38C>, + <0xfc4b8000 0x6fff>; + reg-names = "core_physical", "qfprom_physical"; + + hpd-gdsc-supply = <&gdsc_mdss>; + core-vdda-supply = <&pm8994_l12>; + core-vcc-supply = <&pm8994_s4>; + + qcom,supply-names = "hpd-gdsc", "core-vdda", "core-vcc"; + qcom,min-voltage-level = <0 1800000 1800000>; + qcom,max-voltage-level = <0 1800000 1800000>; + qcom,enable-load = <0 300000 0>; + qcom,disable-load = <0 0 0>; + + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_hdmi_clk>, + <&clock_mmss clk_mdss_hdmi_ahb_clk>, + <&clock_mmss clk_mdss_extpclk_clk>; + clock-names = "mdp_core_clk", "iface_clk", + "core_clk", "alt_iface_clk", "extp_clk"; + + qcom,hdmi-tx-hpd = <&pm8994_mpps 4 0>; + qcom,mdss-fb-map = <&mdss_fb1>; + + hdmi_audio: qcom,msm-hdmi-audio-rx { + compatible = "qcom,msm-hdmi-audio-codec-rx"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-mtp.dtsi new file mode 100755 index 0000000000000..9f6809565c1c5 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-mtp.dtsi @@ -0,0 +1,1066 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8994-pinctrl.dtsi" +#include "msm8994-camera-sensor-mtp.dtsi" +#include "dsi-panel-jd35695-1080p-cmd.dtsi" +#include "dsi-panel-jdi-1080p-video.dtsi" + +/ { + bt_qca6174 { + compatible = "qca,qca6174"; + qca,bt-reset-gpio = <&pm8994_gpios 19 0>; /* BT_EN */ + qca,bt-vdd-pa-supply = <&bt_vreg>; + qca,bt-vdd-io-supply = <&pm8994_s4>; + qca,bt-vdd-xtal-supply = <&pm8994_l30>; + qca,bt-vdd-io-voltage-level = <1800000 1800000>; + qca,bt-vdd-xtal-voltage-level = <1800000 1800000>; + }; +}; + +&sdhc_1 { + vdd-supply = <&pm8994_l20>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + vdd-io-supply = <&pm8994_s4>; + qcom,vdd-io-always-on; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,nonremovable; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &pm8994_gpios 8 0x3>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&pm8994_gpios 8 0x1>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + status = "ok"; +}; + +&ufsphy1 { + status = "ok"; +}; + +&ufs1 { + status = "ok"; +}; + +&pm8994_vadc { + chan@5 { + label = "vcoin"; + reg = <5>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@7 { + label = "vph_pwr"; + reg = <7>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm8994_adc_tm { + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x48>; + qcom,thermal-node; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x68>; + qcom,thermal-node; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x70>; + qcom,thermal-node; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x78>; + qcom,thermal-node; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x80>; + qcom,thermal-node; + }; +}; + +&pmi8994_vadc { + chan@0 { + label = "usbin"; + reg = <0>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@1 { + label = "dcin"; + reg = <1>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@43 { + label = "usb_dp"; + reg = <0x43>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@44 { + label = "usb_dm"; + reg = <0x44>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; +}; + + +/**********************************************************************/ +//zhiming.guo@MM.lcddriver add for lcd driver 2015-01-31 + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&pmx_mdss { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 78>; +}; + + +&labibb { + status = "ok"; + qpnp,qpnp-labibb-mode = "lcd"; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 10>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jd35695_1080_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + //qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + qcom,platform-esd-te-gpio = <&msm_gpio 108 0>;//gzm@oem add 2015-03-28 add + qcom,lcd-poweron-en-gpio = <&pmi8994_gpios 7 0>; + qcom,lcd-poweron-en-n-gpio = <&pmi8994_gpios 3 0>; + qcom,lm3630-bklight-en-gpio = <&pmi8994_gpios 2 0>; + qcom,use_external_ic_power; +}; +&dsi_jd35695_1080_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + +/* + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + +}; +*/ +&dsi_jdi_1080_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + + +/******************************************************************/ + + + +&soc { + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, delete it : synaptics@20.*/ + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, add for tp:synaptics */ + i2c@f9924000 { + synaptics-rmi-ts@20 { + compatible = "synaptics,s3320"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x8>; + synaptics,irq-gpio = <&msm_gpio 96 0x08>; + //synaptics,wakeup-gpio = <&msm_gpio 39 0x00>; + synaptics,reset-gpio = <&msm_gpio 31 0x00>; + //synaptics,id-gpio = <&msm_gpio 38 0x00>; + //synaptics,id3-gpio = <&msm_gpio 39 0x00>; + vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_l14>; + }; + }; +//#ifdef VENDOR_EDIT /* modify for fpc1021 fingerprints*/ + spi@f9968000 { + fpc_fpc1020@0 { //Slave driver and CS ID + compatible = "fpc,fpc1020"; //Manufacture, and Model + reg = <0>; //Same as CS ID + spi-max-frequency = <19200000>; //Max Frequency for Device + #spi-cs-high; //CS Active High + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <90 0>; //GPIO # and flags + fpc,gpio_irq = <&msm_gpio 90 0x00>; //Pass a GPIO + fpc,gpio_reset = <&msm_gpio 89 0x00>; + fpc,gpio_vendor = <&msm_gpio 91 0x00>; + #fpc,gpio_envdd = <&msm_gpio 16 0x00>; + fpc,vddtx_mv; + #fpc,txout_boost_enable; + #spi-cpol; //CPOL bit set for SPI polarity + #spi-cpha; //CPHA bit set for SPI Phase + vdd_io-supply = <&pm8994_s4>; // 1.8V + vdd_ana-supply = <&pm8994_l18>; // 3.3V N3 use gpio16 for enable_pin to controll 3.3V(boost) + fpc,gpio_envdd = <&msm_gpio 41 0x00>; + }; + }; +//#endif/*VENDOR_EDIT*/ + + gen-vkeys { + compatible = "qcom,gen-vkeys"; + label = "synaptics_dsx"; + qcom,disp-maxx = <1599>; + qcom,disp-maxy = <2559>; + qcom,panel-maxx = <1599>; + qcom,panel-maxy = <2703>; + qcom,key-codes = <158 139 102 217>; + }; + + i2c@f9928000 { /* BLSP1 QUP6 */ + status = "ok"; +//#ifdef VENDOR_EDIT +//added by Likelong 2015.5.15 for proximity sensor start + stmvl6180-tof@29 { + reg = <0x29>; + compatible = "stmv,vl6180"; + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.5.15 for proximity sensor end +//#endif/*VENDOR_EDIT*/ + /* + nfc-nci@e { + compatible = "qcom,nfc-nci"; + reg = <0x0e>; + qcom,irq-gpio = <&msm_gpio 29 0x00>; + qcom,dis-gpio = <&msm_gpio 30 0x00>; + qcom,clk-src = "BBCLK2"; + interrupt-parent = <&msm_gpio>; + interrupts = <29 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active","nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_disable_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; + qcom,clk-gpio = <&pm8994_gpios 10 0>; + qcom,pwr-req-gpio = <&pm8994_gpios 7 0>; + clocks = <&clock_rpm clk_bb_clk2_pin>; + clock-names = "ref_clk"; + };*/ + /* lifeng@BSP 2015.3.19 synaptics touch key s1302 */ + synaptics-rmi-ts@20 { + status = "okay"; + compatible = "synaptics,s1302"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <67 0x8>; + synaptics,irq-gpio = <&msm_gpio 67 0x08>; + synaptics,reset-gpio = <&msm_gpio 94 0x00>; + //synaptics,en3v_gpio = <&msm_gpio 41 0x00>; + //vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_s4>; + }; + }; + + //#ifdef VENDOR_EDIT + //#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support + //shankai@bsp, 2015/5/28 ,comment it , as we do not use it any more . + /* + i2c@f9928000 { + haptic-drv2605@5a { + status = "okay"; + compatible = "ti,drv2605"; + //drv2605,enable-gpio = <&pm8994_gpios 4 0x1>; + drv2605,enable-gpio = <&pm8994_gpios 22 0x1>; + reg = <0x5a >; + BIDIRInput = <0x01>; //should be added + loop = <0x1>; + RTPFormat=<0x0>; + actuator.device_type=<0x1>; + actuator.rated_vol=<0x50>; + actuator.g_effect_bank=<0x06>; + actuator.over_drive_vol=<0x84>; + actuator.LRAFreq=<205>; + a2h.a2h_min_input =<0x19>; + a2h.a2h_max_input = <0xff>; + a2h.a2h_min_output =<0x19>; + a2h.a2h_max_output = <0xFF>; + }; + }; + */ + //#endif VENDOR_EDIT + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + + vol_up { + label = "volume_up"; + gpios = <&pm8994_gpios 3 0x1>; + linux,input-type = <1>; + linux,code = <115>; + debounce-interval = <15>; + }; + + //#ifdef VENDOR_EDIT + /*for vol- support*/ + vol_down { + label = "volume_down"; + gpios = <&pm8994_gpios 2 0x1>; + linux,input-type = <1>; + linux,code = <114>; + debounce-interval = <15>; + }; + //endif VENDOR_EDIT + /* + cam_snapshot { + label = "cam_snapshot"; + gpios = <&pm8994_gpios 4 0x1>; + linux,input-type = <1>; + linux,code = <766>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + + cam_focus { + label = "cam_focus"; + gpios = <&pm8994_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <528>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + */ + /*VENDOR_EDIT*/ + /*qiuchangping add begin for hallsensor key 2015-03-25*/ + hallsensor_key { + label = "hallsensor_key"; + gpios = <&msm_gpio 75 1>; + interrupt-parent = <&msm_gpio>; + interrupts = <75 0x0>; + linux,input-type = <5>; + linux,code = <0>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + /*qiuchangping add end*/ + + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-28 add for tristate switch keys*/ + tri_state_key { + compatible = "oneplus,tri-state-key"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + //interrupts = <77 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + tristate,gpio_key2 = <&msm_gpio 77 0x00>; //Pass a GPIO + //tristate,gpio_key2 = <&msm_gpio 61 0x00>;//use gpio61 for test,MP will use 77 + tristate,gpio_key1 = <&msm_gpio 34 0x00>; + //vdd_io-supply = <&pm8994_s4>; // 1.8V + + /* MSM GPIO active and sleep settings */ + pinctrl-names = "key2_active","key2_suspend"; + pinctrl-0 = <&tristate_key2_active>; + pinctrl-1 = <&tristate_key2_suspend>; + }; + /*#endif VENDOR_EDIT*/ +/*#ifdef VENDOR_EDIT //changhua 2015-03-13 add for switch ANTENNA by gpio*/ + switch_antenna { + compatible = "oneplus,switch-antenna"; + antenna,antenna1_gpio = <&msm_gpio 120 0x00>; + antenna,antenna2_gpio = <&msm_gpio 121 0x00>; + antenna,antenna3_gpio = <&msm_gpio 122 0x00>; + antenna,antenna4_gpio = <&msm_gpio 124 0x00>; + }; + /*#endif VENDOR_EDIT*/ + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + switch_theme { + compatible = "oneplus,switch-theme"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <66 0>; //GPIO # and flags + //interrupts = <34 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + cover,gpio_irq = <&msm_gpio 66 0x00>; //Pass a GPIO + //cover,gpio_irq = <&msm_gpio 34 0x00>; //use gpio34 for test,MP will use 66 + cover,gpio_switch = <&pm8994_gpios 1 0>; + qcom,cover-vadc = <&pm8994_vadc>; + vdd_io-supply = <&pm8994_l21>; + /* MSM GPIO active and sleep settings */ + pinctrl-names = "cover_int_active","cover_int_suspend"; + pinctrl-0 = <&cover_int_active>; + pinctrl-1 = <&cover_int_suspend>; + }; + /*#endif VENDOR_EDIT*/ + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for pa*/ + i2c@f9967000{ + status = "ok"; +test_tfa9890: tfa9890@36 { + compatible = "nxp,tfa9890"; + reg = <0x36>; + nxp,tfa_max-vol-steps=<0x01>; + reset_gpio= <&msm_gpio 106 0>; + status = "okay"; + }; + }; + //endif VENDOR_EDIT + + + sound { + qcom,model = "msm8994-tomtom-mtp-snd-card"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK", + "ultrasound amp", "LINEOUT1", + "ultrasound amp", "LINEOUT3", + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,2015/3/19, changed for 14049 mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"AMIC5", "MIC BIAS3 External", + //"MIC BIAS3 External", "Analog Mic5", + //"AMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Analog Mic6", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#else + + "AMIC2", "MIC BIAS2 External", + "MIC BIAS2 External", "Headset Mic", + /*zhiguang.su@MultiMedia.AudioDrv ,2015/6/19, not to use internal resistance*/ + "AMIC3", "MIC BIAS3 External", + "MIC BIAS3 External", "Primary Mic", + "AMIC4", "MIC BIAS1 External", + "MIC BIAS1 External", "Noise Mic"; + + + + //#endif + + + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , delete for no swap for us-euro detect*/ + /* + qcom,us-euro-gpios = <&pm8994_mpps 2 0>; + */ + //endif VENDOR_EDIT + qcom,cdc-micbias2-headset-only; + /* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,mbhc-audio-jack-type = "6-pole-jack"; + */ + qcom,mbhc-audio-jack-type = "4-pole-jack"; + /* Modified end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + qcom,ext-ult-spk-amp-gpio = <&pmi8994_gpios 1 0>; + /* Commented begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,hdmi-audio-rx; + */ + /* Commented end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + asoc-codec = <&stub_codec>, <&hdmi_audio>; + asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-audio-codec-rx"; + }; +}; + +&pm8994_gpios { + + //#ifdef VENDOR_EDIT + /* changhua.li 2015-02-13 add for cover switch theme*/ + gpio@c000 { /* GPIO 1 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + //qcom,vin-sel = <2>; /* VIN 2 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + //#ifdef VENDOR_EDIT + /*for vol- support*/ + gpio@c100 { /* GPIO 2 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + gpio@c200 { /* GPIO 3 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c300 { /* GPIO 4 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c600 { /* GPIO 7 */ + /* NFC pwr request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c900 { /* GPIO 10 */ + /* NFC clk request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c700 { /* GPIO 8 */ + qcom,mode = <0>; /* Digital in */ + qcom,pull = <0>; /* PULL up 30uA */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output high */ + qcom,vin-sel = <2>; /* Logical 1 voltage value 1.8v */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* Low drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@c800 { /* GPIO 9 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <1>; /* Output high */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* High drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@cd00 { /* GPIO 14 */ + status = "okay"; + }; + + gpio@ce00 { /* GPIO 15 */ + qcom,mode = <1>; + qcom,output-type = <0>; + qcom,pull = <5>; + qcom,vin-sel = <2>; + qcom,out-strength = <1>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@d100 { /* GPIO 18 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + qcom,vin-sel = <2>; /* VIN 2 */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@d200 { /* GPIO 19 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#ifndef VENDOR_EDIT */ +//shankai@driver.bsp 2015.4.30 add for drv 2605 enable pin control + gpio@d500 { /* GPIO 22 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#end VENDOR_EDIT*/ +}; + +&pm8994_mpps { +/*#ifndef VENDOR_EDIT //changhua 2015-02-26 remove for rare cover use ADC(PM8994 MPP4) and pcb rf use adc*/ + //mpp@a100 { /* MPP 2 */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // status = "okay"; + //}; + + //mpp@a300 { /* MPP 4 */ + // /* HDMI_5v_vreg regulator enable */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // qcom,invert = <0>; + // status = "okay"; + //}; + /*#end VENDOR_EDIT*/ +}; + +&slim_msm { + tomtom_codec { + +//#ifndef VENDOR_EDIT +// /*zhiguang.su@MultiMedia.AudioDrv ,change for 14049*/ +// qcom,cdc-micbias1-ext-cap; +// qcom,cdc-micbias3-ext-cap; +// qcom,cdc-micbias4-ext-cap; +//#endif + + cdc-vdd-spkdrv-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-current = <600000>; + + cdc-vdd-spkdrv-2-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-2-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-2-current = <600000>; + + qcom,cdc-on-demand-supplies = "cdc-vdd-spkdrv", + "cdc-vdd-spkdrv-2"; + }; +}; + +&pmi8994_gpios { + gpio@c000 { /* GPIO 1 Ultrasound PA EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* CONSTANT */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 OTG SWITCH EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c100 { /* GPIO 2 LM3630 backlight output EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c200 { /* GPIO 3 TPS65132 +5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + gpio@c600 { /* GPIO 7 TPS65132 -5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; +}; + +//&pmi8994_mpps { +// mpp@a300 { /* MPP 4 */ +// /* WLED FET */ +// qcom,mode = <1>; /* DIGITAL OUT */ +// qcom,vin-sel = <0>; /* VIN0 */ +// qcom,master-en = <1>; +// status = "okay"; +// }; +//}; + +&blsp2_uart2 { + status = "ok"; +}; + +&blsp1_uart2 { + status= "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_sleep>; +}; + +&pcie0 { + status = "disabled"; +}; + +&usb3 { + status = "ok"; +}; + +&hsphy0 { + status = "ok"; +}; + +&ssphy0 { + status = "ok"; +}; + +&qcom_crypto1fde { + status = "okay"; +}; + +&qcom_crypto2fde { + status = "okay"; +}; + +&qcom_crypto1pfe { + status = "okay"; +}; + +&qcom_crypto2pfe { + status = "okay"; +}; + +&qcom_cedev { + status = "okay"; +}; + +&i2c_5 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ +//#ifdef VENDOR_EDIT + status = "disabled";//Disabled by likelong 2015.5.18, as there is no FM on 14049, and there is a conflict with Laser sensor. +//#endif/*VENDOR_EDIT*/ + compatible = "silabs,si4705"; + reg = <0x11>; + vdd-supply = <&pm8994_s4>; + silabs,vdd-supply-voltage = <1800000 1800000>; + va-supply = <&bt_vreg>; + silabs,va-supply-voltage = <3300000 3300000>; + pinctrl-names = "pmx_fm_active","pmx_fm_suspend"; + pinctrl-0 = <&fm_int_active &fm_status_int_active &fm_rst_active>; + pinctrl-1 = <&fm_int_suspend &fm_status_int_suspend &fm_rst_suspend>; + silabs,reset-gpio = <&msm_gpio 62 0>; + silabs,int-gpio = <&msm_gpio 9 0>; + silabs,status-gpio = <&msm_gpio 11 0>; + #address-cells = <0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = < + 0 &msm_gpio 9 2 + 1 &msm_gpio 11 1 + >; + interrupt-names = "silabs_fm_int", "silabs_fm_status_int"; + }; +}; + +/{ + mtp_batterydata: qcom,battery-data { + //#ifdef VENDOR_EDIT//for chg, do not match batt ID and let pmi8994 to charge now, later we will use external charger + qcom,batt-id-range-pct = <30>; + //#endif + #include "batterydata_oneplus_ATL_3300mAh.dtsi" + #include "batterydata_oneplus_SDI_3300mAh.dtsi" + #include "batterydata-unkown-3300mah.dtsi" + + }; +}; + +&pmi8994_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,ext-sense-type; +}; + +//#ifdef VENDOR_EDIT // shankai@bsp 2015-4-4 do not use it for vibrator ,comment it. +/* +&pmi8994_haptics { + status = "okay"; +}; +*/ +//#endif +&pmi8994_charger { + qcom,dc-psy-type = "Wipower"; + qcom,dcin-vadc = <&pmi8994_vadc>; + qcom,vph-vadc = <&pm8994_vadc>; + qcom,wipower-default-ilim-map = <4000000 20000000 550 700 300>; + qcom,wipower-pt-ilim-map = <4000000 7140000 550 700 300>, + <7140000 8140000 550 700 300>, + <8140000 9140000 500 700 300>, + <9140000 9950000 500 700 300>; + qcom,wipower-div2-ilim-map = <4000000 4820000 550 700 300>, + <4820000 5820000 550 700 300>, + <5820000 6820000 550 650 650>, + <6820000 7820000 550 700 600>, + <7820000 8500000 550 700 550>; +}; + +&cnss { + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &pcie0_clkreq_default>; +}; + +&i2c_11 { + smb1357-charger@1c { + compatible = "qcom,smb1357-charger"; + //#ifdef VENDOR_EDIT //for chg + status = "disabled"; + //#endif + reg = <0x1c>; + qcom,parallel-charger; + qcom,float-voltage-mv = <4400>; + qcom,recharge-thresh-mv = <100>; + }; +}; + +&usb_ehci { + status = "ok"; + qcom,usb2-enable-uicc; +}; + +&qusb_phy { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-pinctrl.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-pinctrl.dtsi new file mode 100755 index 0000000000000..10807d34bf866 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-pinctrl.dtsi @@ -0,0 +1,1632 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tlmm_pinmux: pinctrl@fd510000 { + compatible = "qcom,msm-tlmm-8994", "qcom,msm-tlmm-8974"; + reg = <0xfd510000 0x4000>; + interrupts = <0 208 0>; + + /*General purpose pins*/ + gp: gp { + qcom,num-pins = <146>; + #qcom,pin-cells = <1>; + + msm_gpio: msm_gpio { + compatible = "qcom,msm-tlmm-gp"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + qcom,direct-connect-irqs = <8>; + num_irqs = <146>; + }; + }; + + pmx-uartconsole { + qcom,pins = <&gp 4>, <&gp 5>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <2>; + label = "uart-console"; + + uart_console_sleep: uart-console { + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp2_uart2_active { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <2>; + label = "blsp2_uart2_active"; + hsuart_active: default { + drive-strength = <16>; + bias-disable; + }; + }; + + blsp2_uart2_sleep { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <0>; + label = "blsp2_uart2_sleep"; + hsuart_sleep: sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_mdss: pmx_mdss { + label = "mdss-pins"; + qcom,pin-func = <0>; + mdss_dsi_active: active { + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + mdss_dsi_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + pmx_mdss_te: pmx_mdss_te { + label = "mdss-te-pins"; + qcom,pin-func = <1>; + mdss_te_active: active { + drive-strength = <2>; /* 8 mA */ + bias-pull-down = <0>; /* pull down*/ + input-debounce = <0>; + }; + mdss_te_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + input-debounce = <0>; + }; + }; + + pmx_hdmi_cec: pmx_hdmi_cec { + qcom,pin-func = <1>; + label = "hdmi-cec-pins"; + mdss_hdmi_cec_active: cec_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_cec_suspend: cec_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_ddc: pmx_hdmi_ddc { + qcom,pin-func = <1>; + label = "hdmi-ddc-pins"; + mdss_hdmi_ddc_active: ddc_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_ddc_suspend: ddc_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_hpd: pmx_hdmi_hpd { + qcom,pin-func = <1>; + label = "hdmi-hpd-pin"; + mdss_hdmi_hpd_active: hpd_active { + drive-strength = <16>; + bias-pull-down; + }; + mdss_hdmi_hpd_suspend: hpd_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + mhl_intr: mhl_intr { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_intr"; + + mhl_intr_active: mhl_intr_active { + bias-pull-up; + input-enable; + }; + }; + + mhl_reset: mhl_reset { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_reset"; + + mhl_reset_active: mhl_reset_active { + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + spi_0_active { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-active"; + + spi_0_active: spi_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_0_suspend { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-suspend"; + + spi_0_sleep: spi_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_cs1_active { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-active"; + + spi_0_cs1_active: cs1_active { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + spi_cs1_suspend { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-suspend"; + + spi_0_cs1_sleep: cs1_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + pmx_i2c_1 { + qcom,pins = <&gp 2>, <&gp 3>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_1"; + + status = "disabled"; + + i2c_1_active: i2c_1_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_1_sleep: i2c_1_sleep { + drive-strength = <2>; + bias-disable; + }; + }; +//#ifdef VENDOR_EDIT//add for fingerprint fpc1150 SPI pin use pinctrl + + spi_12_active { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-active"; + + spi_12_active: spi_12_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_suspend { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-suspend"; + + spi_12_sleep: spi_12_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_12_cs0_active { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-active"; + + spi_12_cs0_active: cs0_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_cs0_suspend { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-suspend"; + + spi_12_cs0_sleep: cs0_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for tristate key + tristate_key2{ + qcom,pins = <&gp 77>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "tri_state_key2"; + tristate_key2_active: active { + drive-strength = <2>; + bias-disable; + }; + tristate_key2_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for switch_cover + switch_cover_int{ + qcom,pins = <&gp 66>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "switch_cover_int"; + cover_int_active: active { + drive-strength = <2>; + bias-disable; + }; + cover_int_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + + audio_ext_devices { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "audio-ext-speakers"; + /* default state */ + audio_ext_speakers: audio_ext_speakers { + drive-strength = <2>; + bias-pull-up; + }; + }; + + /* SDC pin type */ + sdc: sdc { + /* + * 0-3 for sdc1 + * 4-6 for sdc2 + * 7-9 for sdc3 + */ + qcom,num-pins = <10>; + /* + * Order of pins: + * SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 + * SDC2: CLK -> 4, CMD -> 5, DATA -> 6 + * SDC3: CLK -> 7, CMD -> 8, DATA -> 9 + */ + #qcom,pin-cells = <1>; + }; + + pmx_sdc1_clk { + qcom,pins = <&sdc 0>; + qcom,num-grp-pins = <1>; + label = "sdc1-clk"; + sdc1_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc1_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_cmd { + qcom,pins = <&sdc 1>; + qcom,num-grp-pins = <1>; + label = "sdc1-cmd"; + sdc1_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_cmd_off: cmd_off { + bias-pull-up = <0x3>; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_data { + qcom,pins = <&sdc 2>; + qcom,num-grp-pins = <1>; + label = "sdc1-data"; + sdc1_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_rclk { + qcom,pins = <&sdc 3>; + qcom,num-grp-pins = <1>; + label = "sdc1-rclk"; + sdc1_rclk_on: rclk_on { + bias-pull-down; /* pull down */ + }; + sdc1_rclk_off: rclk_off { + bias-pull-down; /* pull down */ + }; + }; + + pmx_sdc2_clk { + qcom,pins = <&sdc 4>; + qcom,num-grp-pins = <1>; + label = "sdc2-clk"; + sdc2_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc2_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_cmd { + qcom,pins = <&sdc 5>; + qcom,num-grp-pins = <1>; + label = "sdc2-cmd"; + sdc2_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_data { + qcom,pins = <&sdc 6>; + qcom,num-grp-pins = <1>; + label = "sdc2-data"; + sdc2_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_clk { + qcom,pins = <&sdc 7>; + qcom,num-grp-pins = <1>; + label = "sdc3-clk"; + sdc3_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc3_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_cmd { + qcom,pins = <&sdc 8>; + qcom,num-grp-pins = <1>; + label = "sdc3-cmd"; + sdc3_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_data { + qcom,pins = <&sdc 9>; + qcom,num-grp-pins = <1>; + label = "sdc3-data"; + sdc3_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_i2c_2 { + qcom,pins = <&gp 6>, <&gp 7>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_2"; + + i2c_2_active: i2c_2_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_2_sleep: i2c_2_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_i2c_5 { + qcom,pins = <&gp 83>, <&gp 84>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_5"; + + i2c_5_active: i2c_5_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_5_sleep: i2c_5_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_fm_int_active { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_active"; + + fm_int_active: fm_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_int_suspend { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_suspend"; + + fm_int_suspend: fm_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_active { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_active"; + + fm_status_int_active: fm_status_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_suspend { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_suspend"; + + fm_status_int_suspend: fm_status_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_rst_active { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_active"; + + fm_rst_active: fm_rst_active { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_fm_rst_suspend { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_suspend"; + + fm_rst_suspend: fm_rst_suspend { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_i2c_6 { + qcom,pins = <&gp 28>, <&gp 27>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_6"; + + i2c_6_active: i2c_6_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_6_sleep: i2c_6_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_rd_nfc_int{ + qcom,pins = <&gp 29>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_int"; + + nfc_int_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_int_suspend: suspend { + drive-strength = <6>; + bias-pull-up; + }; + }; + + pmx_nfc_reset{ + qcom,pins = <&gp 30>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_disable"; + + nfc_disable_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_disable_suspend: suspend { + drive-strength = <6>; + bias-disable; + }; + }; + +//#ifdef VENDOR_EDIT +/*suzhiguang@Multimdia.audio.driver, remove unused pins which conflic with quat i2s.*/ +// pmx_ts { +// qcom,pins = <&gp 60>, <&gp 61>; +// qcom,pin-func = <0>; +// qcom,num-grp-pins = <2>; +// label = "pmx_ts"; +// +// ts_active: ts_active { +// drive-strength = <16>; +// bias-pull-up; +// }; +// +// ts_suspend: ts_suspend { +// drive-strength = <16>; +// bias-disable; +// }; +// }; +//#endif + + /* CoreSight */ + tpiu_seta_1 { + qcom,pins = <&gp 27>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-1"; + seta_1: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_2 { + qcom,pins = <&gp 28>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-seta-2"; + seta_2: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_3 { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <10>; + label = "tpiu-seta-3"; + seta_3: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_4 { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <11>; + label = "tpiu-seta-4"; + seta_4: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_5 { + qcom,pins = <&gp 63>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "tpiu-seta-5"; + seta_5: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_6 { + qcom,pins = <&gp 64>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-6"; + seta_6: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_7 { + qcom,pins = <&gp 65>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-7"; + seta_7: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_8 { + qcom,pins = <&gp 66>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-8"; + seta_8: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_9 { + qcom,pins = <&gp 67>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-9"; + seta_9: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_10 { + qcom,pins = <&gp 74>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-10"; + seta_10: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_11 { + qcom,pins = <&gp 75>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-11"; + seta_11: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_12 { + qcom,pins = <&gp 76>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-12"; + seta_12: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_13 { + qcom,pins = <&gp 77>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-13"; + seta_13: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_14 { + qcom,pins = <&gp 85>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-14"; + seta_14: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_15 { + qcom,pins = <&gp 86>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-15"; + seta_15: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_16 { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-16"; + seta_16: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_17 { + qcom,pins = <&gp 89>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-17"; + seta_17: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_18 { + qcom,pins = <&gp 90>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-18"; + seta_18: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_1 { + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-1"; + setb_1: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_2 { + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-2"; + setb_2: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_3 { + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-3"; + setb_3: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_4 { + qcom,pins = <&gp 16>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-4"; + setb_4: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_5 { + qcom,pins = <&gp 17>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-5"; + setb_5: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_6 { + qcom,pins = <&gp 18>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-6"; + setb_6: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_7 { + qcom,pins = <&gp 19>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-7"; + setb_7: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_8 { + qcom,pins = <&gp 21>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-8"; + setb_8: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_9 { + qcom,pins = <&gp 22>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-9"; + setb_9: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_10 { + qcom,pins = <&gp 23>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-10"; + setb_10: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_11 { + qcom,pins = <&gp 25>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-setb-11"; + setb_11: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_12 { + qcom,pins = <&gp 26>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-12"; + setb_12: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_13 { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-13"; + setb_13: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_14 { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-14"; + setb_14: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_15 { + qcom,pins = <&gp 91>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-15"; + setb_15: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_16 { + qcom,pins = <&gp 92>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-setb-16"; + setb_16: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_17 { + qcom,pins = <&gp 93>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-17"; + setb_17: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_18 { + qcom,pins = <&gp 94>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-18"; + setb_18: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + cti_trigout_a { + qcom,pins = <&gp 56>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "cti-trigout-a"; + trigout_a: trigout_a { + drive-strength = <2>; + bias-disable; + }; + }; + + cti_trigout_c { + qcom,pins = <&gp 41>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "cti-trigout-c"; + trigout_c: trigout_c { + drive-strength = <2>; + bias-disable; + }; + }; + + cci0_active { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci0-active"; + /* active state */ + cci0_active: cci0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci0_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci0-suspend"; + /*suspended state */ + cci0_suspend: cci0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_active { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci1-active"; + /* active state */ + cci1_active: cci1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci1-suspend"; + /*suspended state */ + cci1_suspend: cci1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_active { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk0_active"; + /* active state */ + cam_sensor_mclk0_active: cam_sensor_mclk0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_suspend { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk0_suspend"; + /*suspended state */ + cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear_active { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_active"; + /* active state */ + cam_sensor_rear_active: cam_sensor_rear_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear_suspend { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_suspend"; + /*suspended state */ + cam_sensor_rear_suspend: cam_sensor_rear_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_active { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk1_active"; + /* active state */ + cam_sensor_mclk1_active: cam_sensor_mclk1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_suspend { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk1_suspend"; + /* suspend state */ + cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear2_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_active"; + /* active state */ + cam_sensor_rear2_active: cam_sensor_rear2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear2_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_suspend"; + /*suspended state */ + cam_sensor_rear2_suspend: cam_sensor_rear2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_active { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk2_active"; + /* active state */ + cam_sensor_mclk2_active: cam_sensor_mclk2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_suspend { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk2_suspend"; + /* suspend state */ + cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_front_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_active"; + /* active state */ + cam_sensor_front_active: cam_sensor_front_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_front_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_suspend"; + /*suspended state */ + cam_sensor_front_suspend: cam_sensor_front_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cnss_pmux: cnss_pmux { + qcom,pins = <&gp 113>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss_pins"; + cnss_default: default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + cnss_lpass: cnss_lpass { + qcom,pins = <&gp 112>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss-lpass"; + /* default state */ + cnss_lpass_default: cnss_lpass_default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pcie0_clkreq { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie0-clkreq"; + /* default state */ + pcie0_clkreq_default: pcie0_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie0_perst { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + label = "pcie0-perst"; + /* default state */ + pcie0_perst_default: pcie0_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie0_wake { + qcom,pins = <&gp 55>; + qcom,num-grp-pins = <1>; + label = "pcie0-wake"; + /* default state */ + pcie0_wake_default: pcie0_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_clkreq { + qcom,pins = <&gp 36>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie1-clkreq"; + /* default state */ + pcie1_clkreq_default: pcie1_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_perst { + qcom,pins = <&gp 35>; + qcom,num-grp-pins = <1>; + label = "pcie1-perst"; + /* default state */ + pcie1_perst_default: pcie1_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_wake { + qcom,pins = <&gp 37>; + qcom,num-grp-pins = <1>; + label = "pcie1-wake"; + /* default state */ + pcie1_wake_default: pcie1_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + + pcie1_wake_sleep: pcie1_wake_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_sec_aux_pcm_sleep { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_sleep"; + sec_aux_pcm_sleep: sec_aux_pcm_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_active { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_active"; + sec_aux_pcm_active: sec_aux_pcm_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_sec_aux_pcm_din_sleep { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_din_sleep"; + sec_aux_pcm_din_sleep: sec_aux_pcm_din_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_din_active { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_din_active"; + sec_aux_pcm_din_active: sec_aux_pcm_din_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#ifdef VENDOR_EDIT +// pmx_pri_mi2s_sleep { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sleep"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_active { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_active"; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0_sleep { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sd0_sleep"; +//pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_sd0_active { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0_active"; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; + +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ +// pmx_pri_mi2s { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0 { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0"; +// pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; +//#endif + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for quat i2s*/ + pmx_quat_mi2s { + qcom,pins = <&gp 58>, <&gp 59>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "quat_mi2s"; + quat_mi2s_sleep: quat_mi2s_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_active: quat_mi2s_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_quat_mi2s_mclk { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_mclk"; + quat_mi2s_mclk_sleep: quat_mi2s_mclk_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_mclk_active: quat_mi2s_mclk_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd0 { + qcom,pins = <&gp 60>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd0"; + quat_mi2s_sd0_sleep: quat_mi2s_sd0_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd0_active: quat_mi2s_sd0_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd1 { + qcom,pins = <&gp 61>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd1"; + quat_mi2s_sd1_sleep: quat_mi2s_sd1_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd1_active: quat_mi2s_sd1_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#endif VENDOR_EDIT + + tsif0_signals { + qcom,pins = <&gp 89>, /* TSIF0 CLK */ + <&gp 90>, /* TSIF0 Enable */ + <&gp 91>; /* TSIF0 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif0-signals"; + tsif0_signals_active: tsif0_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif0_sync { + qcom,pins = <&gp 110>; /* TSIF0 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif0-sync"; + tsif0_sync_active: tsif0_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + tsif1_signals { + qcom,pins = <&gp 93>, /* TSIF1 CLK */ + <&gp 94>, /* TSIF1 Enable */ + <&gp 95>; /* TSIF1 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif1-signals"; + tsif1_signals_active: tsif1_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif1_sync { + qcom,pins = <&gp 96>; /* TSIF1 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif1-sync"; + tsif1_sync_active: tsif1_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pm8004.dtsi new file mode 100755 index 0000000000000..c495f2c6e786b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pm8004.dtsi @@ -0,0 +1,48 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm8994-pm8994-pmi8994-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000C 0x0 0x0>; +}; + +&rpm_bus { + /delete-node/ rpm-regulator-bstb; + /delete-node/ rpm-regulator-bbyb; + /delete-node/ rpm-regulator-smpb1; + /delete-node/ rpm-regulator-smpc2; + + rpm-regulator-smpb2 { + pm8004_s2_corner: regulator-s2-corner { + regulator-name = "pm8004_s2_corner"; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + regulator-name = "pm8004_s2_floor_corner"; + }; + }; +}; + +&spmi_bus { + /delete-node/ qcom,pmi8994@2; + /delete-node/ qcom,pmi8994@3; +}; + +&usb3 { + /delete-property/ vbus_dwc3-supply; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pmi8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pmi8994-pm8004.dtsi new file mode 100755 index 0000000000000..ee5fc8594ceb2 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-pm8994-pmi8994-pm8004.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000A 0x1000C 0x0>; +}; + +&rpm_bus { + rpm-regulator-smpb2 { + status = "disabled"; + }; + + rpm-regulator-smpc2 { + status = "okay"; + regulator-s2-corner { + status = "okay"; + }; + + regulator-s2-floor-corner { + status = "okay"; + }; + }; +}; + +/* + * Override PMI8994 resources with proper PM8004 resources for + * MSM8994 with PM8004. + */ + +&soc { + qcom,msm-thermal { + vdd-gfx-supply = <&pm8004_s2_floor_corner>; + }; +}; + +&gdsc_oxili_gx { + parent-supply = <&pm8004_s2_corner>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-regulator.dtsi new file mode 100755 index 0000000000000..5b8b364149099 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-regulator.dtsi @@ -0,0 +1,987 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + /* PM8994 S1 + S6 = 2 phase VDD_CX supply */ + rpm-regulator-smpa1 { + status = "okay"; + pm8994_s1_corner: regulator-s1-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s1_floor_corner: regulator-s1-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + + pm8994_s1_corner_ao: regulator-s1-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <4>; + regulator-max-microvolt = <7>; + regulator-always-on; + qcom,init-voltage-corner = <6>; + qcom,use-voltage-corner; + proxy-supply = <&pm8994_s1_corner_ao>; + qcom,proxy-consumer-voltage = <7 7>; + }; + }; + + /* PM8994 S2 + S12 = 2 phase VDD_MX supply */ + rpm-regulator-smpa2 { + status = "okay"; + pm8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s2_corner_ao: regulator-s2-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + }; + + rpm-regulator-smpa3 { + status = "okay"; + pm8994_s3: regulator-s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <1300000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa4 { + status = "okay"; + pm8994_s4: regulator-s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa5 { + status = "okay"; + pm8994_s5: regulator-s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + qcom,init-voltage = <2150000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa7 { + status = "okay"; + pm8994_s7: regulator-s7 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa1 { + status = "okay"; + pm8994_l1: regulator-l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa2 { + status = "okay"; + pm8994_l2: regulator-l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + proxy-supply = <&pm8994_l2>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa3 { + status = "okay"; + pm8994_l3: regulator-l3 { + /*liuyan 2015/7/20, change 1.2 to .125*/ + /*#ifndef VENDOR_EDIT*/ + /*regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>;*/ + /*#else*/ + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + /*#endif*/ + status = "okay"; + }; + }; + + rpm-regulator-ldoa4 { + status = "okay"; + pm8994_l4: regulator-l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + qcom,init-voltage = <1225000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa6 { + status = "okay"; + pm8994_l6: regulator-l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa8 { + status = "okay"; + pm8994_l8: regulator-l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa9 { + status = "okay"; + pm8994_l9: regulator-l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa10 { + status = "okay"; + pm8994_l10: regulator-l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa11 { + status = "okay"; + pm8994_l11: regulator-l11 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa12 { + status = "okay"; + pm8994_l12: regulator-l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l12>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa13 { + status = "okay"; + pm8994_l13: regulator-l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa14 { + status = "okay"; + pm8994_l14: regulator-l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l14>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa15 { + status = "okay"; + pm8994_l15: regulator-l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa16 { + status = "okay"; + pm8994_l16: regulator-l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; +//#ifdef VENDOR_EDIT //FIX GPS power issue + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa17 { + status = "okay"; + pm8994_l17: regulator-l17 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa18 { + status = "okay"; + pm8994_l18: regulator-l18 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + qcom,init-voltage = <2850000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa19 { + status = "okay"; + pm8994_l19: regulator-l19 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa20 { + status = "okay"; + pm8994_l20: regulator-l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + qcom,init-current = <750>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa21 { + status = "okay"; + pm8994_l21: regulator-l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; +//#ifdef VENDOR_EDIT //changhua modify for cover + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa22 { + status = "okay"; + pm8994_l22: regulator-l22 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <3000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa23 { + status = "okay"; + pm8994_l23: regulator-l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa24 { + status = "okay"; + pm8994_l24: regulator-l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3150000>; + qcom,init-voltage = <3075000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa25 { + status = "okay"; + pm8994_l25: regulator-l25 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa26 { + status = "okay"; + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <987500>; + regulator-max-microvolt = <987500>; + qcom,init-voltage = <987500>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa27 { + status = "okay"; + pm8994_l27: regulator-l27 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + qcom,init-voltage = <1050000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa28 { + status = "okay"; + pm8994_l28: regulator-l28 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + qcom,init-current = <45>; + regulator-boot-on; + proxy-supply = <&pm8994_l28>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa29 { + status = "okay"; + pm8994_l29: regulator-l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa30 { + status = "okay"; + pm8994_l30: regulator-l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + qcom,init-current = <50>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa32 { + status = "okay"; + pm8994_l32: regulator-l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-vsa1 { + status = "okay"; + pm8994_lvs1: regulator-lvs1 { + status = "okay"; + }; + }; + + rpm-regulator-vsa2 { + status = "okay"; + pm8994_lvs2: regulator-lvs2 { + status = "okay"; + }; + }; + + rpm-regulator-smpb1 { + status = "okay"; + pmi8994_s1: regulator-s1 { + regulator-min-microvolt = <1025000>; + regulator-max-microvolt = <1025000>; + qcom,init-voltage = <1025000>; + status = "okay"; + }; + }; + + /* PMI8994 S2 + S3 = 2 phase VDD_GFX supply */ + rpm-regulator-smpb2 { + status = "okay"; + pmi8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pmi8994_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; + + rpm-regulator-bstb { + status = "okay"; + pmi8994_boost_5v: regulator-bst { + /* + * When enabled, the PMI8994 Boost regulator always + * outputs 5V. This takes precedence over the pin + * control boost regulator request. + */ + regulator-name = "pmi8994_boost_5v"; + status = "okay"; + }; + pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl { + /* + * When enabled, the output voltage of the PMI8994 + * boost regulator is determined by the state of the + * REQ_5V_BST pin. If the pin signal is high, then the + * regulator outputs 5V. If the pin signal is low, then + * the regulator outputs VPH_PWR voltage. + */ + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost_pin_ctrl"; + qcom,set = <3>; + qcom,enable-with-pin-ctrl = <0 1>; + }; + }; + + rpm-regulator-bbyb { + status = "okay"; + pmi8994_boostbypass: regulator-bby { + status = "okay"; + regulator-min-microvolt = <3150000>; + regulator-max-microvolt = <3600000>; + qcom,init-voltage = <3150000>; + }; + }; + + /* PM8004 S2 + S4 = 2 phase VDD_GFX supply */ + rpm-regulator-smpc2 { + status = "disabled"; + pm8004_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; +}; + +/* SPM controlled regulators: */ +&spmi_bus { + qcom,pm8994@1 { + /* PM8994 S8 = VDD_APC0 supply */ + pm8994_s8: spm-regulator@2900 { + compatible = "qcom,spm-regulator"; + reg = <0x2900 0x100>; + regulator-name = "pm8994_s8"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1180000>; + qcom,cpu-num = <0>; + }; + + /* + * PM8994 S9 + S10 + S11 = 3 phase VDD_APC1 supply + * S11 is the gang leader. + */ + pm8994_s11: spm-regulator@3200 { + compatible = "qcom,spm-regulator"; + reg = <0x3200 0x100>; + regulator-name = "pm8994_s11"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1225000>; + qcom,cpu-num = <4>; + }; + }; +}; + +/* CPR controlled regulators */ +&soc { + mem_acc0_vreg_corner: mem-acc0-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900d084 1>, <0xf900d088 1>, + <0xf900d08c 1>, <0xf900d090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc0_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type2 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type3 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type4 = <0x02 0x02 0x00 0x00>; + }; + + mem_acc1_vreg_corner: mem-acc1-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900f084 1>, <0xf900f088 1>, + <0xf900f08c 1>, <0xf900f090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc1_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type2 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type3 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type4 = <0x0b 0x0b 0x0b 0x0b>; + }; + + apc0_vreg_corner: regulator@f9019000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf9019000 0x1000>, <0xf900d064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 16 0>; + regulator-name = "apc0_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <13>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1180000>; + qcom,cpr-voltage-floor = <700000 700000 780000 835000>; + vdd-apc-supply = <&pm8994_s8>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc0_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <12>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <82 82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <800000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 3 3 3 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0xFFFFFFFF 0 900000 900000 900000 900000 + 1000000 1000000 1000000 1115000 + 1115000 1180000 1180000 1180000 + 1180000>; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 700000 700000 700000 725000 + 780000 800000 825000 835000 + 850000 915000 970000 980000 + 1000000>; + + qcom,cpr-fuse-version-map = + <0xffffffff 0xffffffff 1 0 0 0 0>, + <0xffffffff 0xffffffff 2 0 0 0 0>, + <0xffffffff 0xffffffff 3 0 0 0 0>, + <0xffffffff 0xffffffff 4 0 0 0 0>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-50)>, + <0 0 0 (-50)>, + <0 (-50) (-90) 40>, + <0 (-50) (-90) 0>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-25000)>, + <0 0 0 (-25000)>, + <0 (-25000) (-25000) 20000>, + <0 (-25000) (-25000) 0>; + + qcom,cpr-scaled-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for SVS2 */ + <2 300000000>, + <3 384000000>, + <4 460800000>, + <5 600000000>, + <6 672000000>, + <7 768000000>, + <8 864000000>, + <9 960000000>, + <10 1248000000>, + <11 1344000000>, + <12 1478400000>, + <13 1555200000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 4 7 13>; + qcom,cpr-enable; + }; + + apc1_vreg_corner: regulator@f901a000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf901a000 0x1000>, <0xf900f064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 19 0>; + regulator-name = "apc1_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <17>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1225000>; + qcom,cpr-voltage-floor = <700000 700000 750000 835000>; + vdd-apc-supply = <&pm8994_s11>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc1_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <14 14 12 12 12 12 7 8>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,cpr-clamp-timer-interval = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <21 29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <72 72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + qcom,speed-bin-fuse-sel = <22 0 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <0 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>, + <1 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>; + qcom,cpr-voltage-floor-override = + <0 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>, + <1 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>; + + qcom,cpr-fuse-version-map = + <0 0xffffffff 1 6 6 6 6>, + <0 0xffffffff 2 6 6 6 6>, + <0 0xffffffff 2 4 4 4 4>, + <0 0xffffffff 3 4 4 4 4>, + <0 0xffffffff 4 4 4 4 4>, + <1 0xffffffff 3 4 4 4 4>, + <1 0xffffffff 4 4 4 4 4>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-24)>, + <0 0 0 (-24)>, + <0 0 0 (-84)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>; + qcom,cpr-cpus = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,cpr-online-cpu-virtual-corner-init-voltage-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + qcom,cpr-online-cpu-virtual-corner-quotient-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + + qcom,cpr-online-cpu-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for "SVS2" */ + <2 300000000>, + <3 384000000>, + <4 480000000>, + <5 633600000>, + <6 768000000>, + <7 864000000>, + <8 960000000>, + <9 1248000000>, + <10 1344000000>, + <11 1440000000>, + <12 1536000000>, + <13 1632000000>, + <14 1728000000>, + <15 1766400000>, + <16 1824000000>, + <17 1958400000>; + qcom,cpr-speed-bin-max-corners = + <0 0 1 5 8 17>, + <1 0 1 5 8 15>; + qcom,cpr-enable; + }; + + bt_vreg: bt_vreg { + compatible = "regulator-fixed"; + regulator-name = "bt_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8994_gpios 9 0>; + }; + + usb_otg_switch: usb-otg-switch { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vreg"; + vin-supply = <&smbcharger_external_otg>; + enable-active-high; + gpio = <&pmi8994_gpios 5 0>; + }; +}; + +&pmi8994_charger { + otg-parent-supply = <&pmi8994_boost_5v>; + smbcharger_charger_otg: qcom,smbcharger-boost-otg { + regulator-name = "smbcharger_charger_otg"; + }; + + smbcharger_external_otg: qcom,smbcharger-external-otg { + regulator-name = "smbcharger_external_otg"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-smp2p.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-smp2p.dtsi new file mode 100755 index 0000000000000..c40cdaf335e8b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-smp2p.dtsi @@ -0,0 +1,169 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +&soc { + qcom,smp2p-modem { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <1>; + qcom,irq-bitmask = <0x4000>; + interrupts = <0 27 1>; + }; + + qcom,smp2p-adsp { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <2>; + qcom,irq-bitmask = <0x400>; + interrupts = <0 158 1>; + }; + + smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_in { + compatible = "qcom,smp2pgpio_test_smp2p_7_in"; + gpios = <&smp2pgpio_smp2p_7_in 0 0>; + }; + + smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_out { + compatible = "qcom,smp2pgpio_test_smp2p_7_out"; + gpios = <&smp2pgpio_smp2p_7_out 0 0>; + }; + + smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_in { + compatible = "qcom,smp2pgpio_test_smp2p_1_in"; + gpios = <&smp2pgpio_smp2p_1_in 0 0>; + }; + + smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_out { + compatible = "qcom,smp2pgpio_test_smp2p_1_out"; + gpios = <&smp2pgpio_smp2p_1_out 0 0>; + }; + + smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_in { + compatible = "qcom,smp2pgpio_test_smp2p_2_in"; + gpios = <&smp2pgpio_smp2p_2_in 0 0>; + }; + + smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_out { + compatible = "qcom,smp2pgpio_test_smp2p_2_out"; + gpios = <&smp2pgpio_smp2p_2_out 0 0>; + }; + + /* ssr - inbound entry from lpass. */ + smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to lpass */ + smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - inbound entry from mss. */ + smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to mss. */ + smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-mtp_14049_HW_13.dts b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-mtp_14049_HW_13.dts new file mode 100755 index 0000000000000..541a39eaeec9b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-mtp_14049_HW_13.dts @@ -0,0 +1,26 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8994-v1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <13>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-pm.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-pm.dtsi new file mode 100755 index 0000000000000..371c020d1aa30 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1-pm.dtsi @@ -0,0 +1,593 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-ret = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900D210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 1f 18 03 2f 1b 18 7b d0 2b e0 3b c0 16 6b 26 6b 18 00 + 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d0 2b e0 3b + c0 16 6b 26 6b 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-retention"; + qcom,spm-cci-mode = "retention"; + qcom,latency-us = <45>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11609>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <1>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1375>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <760>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <775>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <40>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1505>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <647>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <653>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 332>, /* sps */ + <0xff 333>; /* ipa */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v1.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1.dtsi new file mode 100755 index 0000000000000..447a74220a008 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v1.dtsi @@ -0,0 +1,246 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v1.dtsi" +#include "msm8994-v1-pm.dtsi" +#include "msm8994-camera-v1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x10000>; + +}; + +&soc { + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 14 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + qcom,apply-cti-pmu-wa; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 14 0xff00>; + qcom,apply-cti-pmu-wa; + }; + + cci@f9100000 { + pmu@a000 { + interrupts = <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>; + }; + }; +}; + +&pm8994_s8 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1115000>; +}; + +&pm8994_s11 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1225000>; +}; + +&ufs1 { + freq-table-hz = + <100000000 171430000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +&mem_acc0_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&mem_acc1_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&apc0_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <9>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1115000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <16>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <116 0 73>; + qcom,cpr-fuse-ro-sel = <82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 800000 840000 860000 860000 + 900000 900000 940000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>, + <9 940800000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 9>; + qcom,cpr-enable; +}; + +&apc1_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <8>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1225000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <10>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <36 45 0>; + qcom,cpr-fuse-ro-sel = <72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 790000 840000 840000 860000 + 890000 920000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 8>; + qcom,cpr-enable; +}; + +&soc { + qcom,usbbam@f9304000 { + qcom,pipe0 { + qcom,pipe-connection-type = <1>; /* USB_BAM_PIPE_SYS2BAM */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2-pm.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2-pm.dtsi new file mode 100755 index 0000000000000..9272b2a079326 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2-pm.dtsi @@ -0,0 +1,690 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900d210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 38 48 26 6b 18 03 2f 1b 18 7b + 26 6b 40 40 48 38 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 03 2f 1b 18 7b d2 2b e2 3b c0 16 6b 26 6b 48 + 18 00 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x8>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 48 26 6b 18 03 2f 1b 18 7b 26 + 6b 40 40 48 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d2 2b + e2 3b c0 16 6b 26 6b 48 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-wfi"; + qcom,spm-cci-mode = "wfi"; + qcom,latency-us = <90>; + qcom,ss-power = <307>; + qcom,energy-overhead = <81180>; + qcom,time-overhead = <180>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11260>; + qcom,ss-power = <89>; + qcom,energy-overhead = <6959381>; + qcom,time-overhead = <5431>; + qcom,min-child-idx = <2>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <159>; + qcom,energy-overhead = <29640>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <148>; + qcom,energy-overhead = <44460>; + qcom,time-overhead = <180>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <800>; + qcom,ss-power = <104>; + qcom,energy-overhead = <432250>; + qcom,time-overhead = <1750>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <50>; + qcom,ss-power = <65>; + qcom,energy-overhead = <10650>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <100>; + qcom,ss-power = <51>; + qcom,energy-overhead = <15975>; + qcom,time-overhead = <150>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <400>; + qcom,ss-power = <50>; + qcom,energy-overhead = <74550>; + qcom,time-overhead = <700>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <480>; + qcom,ss-power = <30>; + qcom,energy-overhead = <85200>; + qcom,time-overhead = <800>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <80>; + qcom,ss-power = <270>; + qcom,energy-overhead = <72160>; + qcom,time-overhead = <160>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <190>; + qcom,ss-power = <189>; + qcom,energy-overhead = <157850>; + qcom,time-overhead = <350>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1260>; + qcom,ss-power = <93>; + qcom,energy-overhead = <1318724>; + qcom,time-overhead = <2924>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <117>; + qcom,energy-overhead = <31200>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <93>; + qcom,energy-overhead = <46800>; + qcom,time-overhead = <180>; + qcom,use-broadcast-timer; + }; + + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <475>; + qcom,ss-power = <66>; + qcom,energy-overhead = <201500>; + qcom,time-overhead = <775>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <636>; + qcom,ss-power = <60>; + qcom,energy-overhead = <248560>; + qcom,time-overhead = <956>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 20>, /* arch_timer */ + <0xff 23>, /* ARM64 Single-Bit Error PMU IRQ */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 48>, /* cpr */ + <0xff 51>, /* cpr */ + <0xff 54>, /* CCI error IRQ */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 164>, /* sps */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 212>, /* msm_dwc3 */ + <0xff 215>, /* fc388000.qcom,cpu-bwmon */ + <0xff 224>, /* spdm_bw_hyp */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 261>, /* msm_iommu_global_cfg */ + <0xff 263>, /* msm_iommu_global_client */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 272>, /* msm_iommu_secure_irq */ + <0xff 273>, /* msm_iommu_nonsecure_irq */ + <0xff 275>, /* int_msi */ + <0xff 283>, /* int_pls_err */ + <0xff 284>, /* int_aer_legacy */ + <0xff 286>, /* int_pls_link_down */ + <0xff 298>, /* msm_iommu_nonsecure_irq */ + <0xff 302>, /* coresight-tmc-etr */ + <0xff 303>, /* int_msi */ + <0xff 310>, /* int_pls_err */ + <0xff 311>, /* int_aer_legacy */ + <0xff 313>, /* int_pls_link_down */ + <0xff 329>, /* sps */ + <0xff 332>, /* sps */ + <0xff 333>, /* ipa */ + <0xff 348>, /* fd878000.qcom,fd */ + <0xff 350>, /* msm_iommu_nonsecure_irq */ + <0xff 360>, /* ARM64 primary DBE IRQ */ + <0xff 361>, /* ARM64 secondary DBE IRQ */ + <0xff 362>, /* ARM64 primary ext IRQ */ + <0xff 363>, /* ARM64 secondary ext IRQ */ + <0xff 364>; /* lmh_interrupt */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu4_clk", "cpu5_clk", "cpu6_clk", + "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,no-pll-switch-for-retention; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; + + qcom,npa-dump@0xfc190020 { + compatible = "qcom,npa-dump"; + reg = <0xfc190020 0x4>, <0xfc000000 0x1c00>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0-mtp_14049_HW_13.dts b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0-mtp_14049_HW_13.dts new file mode 100755 index 0000000000000..3f66a8b3d603d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0-mtp_14049_HW_13.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.0.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.0 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <13>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0.dtsi new file mode 100755 index 0000000000000..b824d0c5d195c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.0.dtsi @@ -0,0 +1,35 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.0"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20000>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030001>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1-mtp_14049_HW_13.dts b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1-mtp_14049_HW_13.dts new file mode 100755 index 0000000000000..230c935f7b81b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1-mtp_14049_HW_13.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.1 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <13>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1.dtsi new file mode 100755 index 0000000000000..93bc398c9693f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.1.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.1"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20001>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030002>; + qcom,gpu-pwrlevels { + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <630000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + }; + qcom,ocmem-bus-client { + qcom,msm-bus,vectors-KBps = + <89 662 0 10080000>, /* gpu= 630 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.dtsi new file mode 100755 index 0000000000000..a55f94a83941e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994-v2.dtsi @@ -0,0 +1,428 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v2.dtsi" +#include "msm8994-camera-v2.dtsi" + +&soc { + + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 7 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 7 0xff00>; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon2"; + }; + + qcom,lmh { + compatible = "qcom,lmh"; + interrupts = <0 332 4>; + reg = <0xF9117000 0x4>; + qcom,lmh-trim-err-offset = <18>; + }; +}; + +/* Clock driver overrides */ +&clock_gcc { + compatible = "qcom,gcc-8994v2"; +}; + +&clock_mmss { + compatible = "qcom,mmsscc-8994v2"; +}; + +&clock_cpu { + compatible = "qcom,cpu-clock-8994-v2"; + vdd-dig-supply = <&pm8994_s2_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 384000000 3>, + < 460800000 4>, + < 600000000 5>, + < 672000000 6>, + < 768000000 7>, + < 864000000 8>, + < 960000000 9>, + < 1248000000 10>, + < 1344000000 11>, + < 1478400000 12>, + < 1555200000 13>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1728000000 14>, + < 1824000000 16>, + < 1958400000 17>; + qcom,a57-speedbin1-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1766400000 15>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 300000000 4>, + < 384000000 5>, + < 537600000 7>, + < 600000000 9>, + < 729600000 10>, + < 787200000 11>; +}; + +&cci_cache { + freq-tbl-khz = + < 300000 >, + < 384000 >, + < 537600 >, + < 600000 >, + < 729600 >, + < 787200 >; +}; + +&msm_cpufreq { + qcom,cpufreq-table-0 = + < 384000 >, + < 460800 >, + < 600000 >, + < 672000 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1478400 >, + < 1555200 >; + + qcom,cpufreq-table-4 = + < 384000 >, + < 480000 >, + < 633600 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1440000 >, + < 1536000 >, + < 1632000 >, + < 1728000 >, + < 1824000 >, + < 1958400 >; +}; + +&devfreq_cpufreq { + cpubw-cpufreq { + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5928 >, + < 1248000 7904 >, + < 1344000 9887 >, + < 1478400 11863 >, + < 1555200 11863 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 2288 >, + < 633600 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5126 >, + < 1248000 5928 >, + < 1344000 7904 >, + < 1440000 7904 >, + < 1536000 7904 >, + < 1632000 9887 >, + < 1728000 9887 >, + < 1824000 11863 >, + < 1958400 11863 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1478400 1525 >, + < 1555200 1525 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 1525 >, + < 633600 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1440000 1525 >, + < 1536000 1525 >, + < 1632000 1525 >, + < 1728000 1525 >, + < 1824000 1525 >, + < 1958400 7904 >; + }; + + cci-cpufreq { + cpu-to-dev-map-0 = + < 384000 300000 >, + < 460800 300000 >, + < 600000 300000 >, + < 672000 384000 >, + < 768000 384000 >, + < 864000 537600 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 787200 >, + < 1478400 787200 >, + < 1555200 787200 >; + cpu-to-dev-map-4 = + < 384000 300000 >, + < 480000 300000 >, + < 633600 384000 >, + < 768000 537600 >, + < 864000 600000 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 729600 >, + < 1440000 729600 >, + < 1536000 787200 >, + < 1632000 787200 >, + < 1728000 787200 >, + < 1824000 787200 >, + < 1958400 787200 >; + }; +}; + +/* GPU VBIF overrides */ +&gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5271 /* 691 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; +}; + +/* GPU overrides */ +&msm_gpu { + qcom,initial-pwrlevel = <5>; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1600000>, /* 1 bus=200 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3680000>, /* 3 bus=460 */ + <26 512 0 4376000>, /* 4 bus=547 */ + <26 512 0 5528000>, /* 5 bus=691 */ + <26 512 0 6216000>, /* 6 bus=777 */ + <26 512 0 8288000>, /* 7 bus=1036 */ + <26 512 0 10368000>, /* 8 bus=1296 */ + <26 512 0 12440000>; /* 9 bus=1555 */ + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <510000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <450000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <390000000>; + qcom,bus-freq = <5>; + qcom,bus-min = <4>; + qcom,bus-max = <6>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <305000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <4>; + }; + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <180000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <27000000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <7>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu= 600 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; + +&ufs1 { + freq-table-hz = + <100000000 200000000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +/* MDSS driver overrides */ +&mdss_mdp { + qcom,mdp-settings = <0x0117c 0x0000ffff>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; +}; + +/* Video driver overrides */ +&msm_vidc { + qcom,load-freq-tbl = + <979200 510000000 0x0c000000>, + <979200 510000000 0x01000414>, + <979200 510000000 0x030fcfff>, + <979200 510000000 0x04000000>, + <783360 510000000 0x0c000000>, + <783360 510000000 0x01000414>, + <783360 510000000 0x030fcfff>, + <783360 510000000 0x04000000>, + <489600 320000000 0x0c000000>, + <489600 320000000 0x01000414>, + <489600 320000000 0x030fcfff>, + <489600 320000000 0x04000000>, + <244800 150000000 0x0c000000>, + <244800 150000000 0x01000414>, + <244800 150000000 0x030fcfff>, + <244800 150000000 0x04000000>; +}; + +&cnss { + wlan-bootstrap-gpio = <&msm_gpio 112 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &cnss_lpass_default>; +}; + +#include "msm8994-v2-pm.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_13/msm8994.dtsi b/arch/arm64/boot/dts/14049_HW_13/msm8994.dtsi new file mode 100755 index 0000000000000..e923d946dfbd3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/msm8994.dtsi @@ -0,0 +1,3792 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/memreserve/ 0x00000000 0x00001000; +/memreserve/ 0xac1c0000 0x00001000; + +#include "skeleton64.dtsi" +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x0>; + qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>; + interrupt-parent = <&intc>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; + + aliases { + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + /*do not enable sdhc2 and sdhc3 + sdhc2 = &sdhc_2; + sdhc3 = &sdhc_3; + */ + i2c6 = &i2c_6; /* I2C6 NFC qup6 device */ + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c5 = &i2c_5; + spi0 = &spi_0; + /*#ifdef VENDOR_EDIT modify for fpc1021 fingerprints*/ + spi12 = &spi_12; + /*#end VENDOR_EDIT*/ + qup2 = &i2c_2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU4>; + }; + core1 { + cpu = <&CPU5>; + }; + core2 { + cpu = <&CPU6>; + }; + core3 { + cpu = <&CPU7>; + }; + }; + }; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc0>; + qcom,ldo = <&ldo0>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + power-domain = <&l2ccc_0>; + qcom,dump-size = <0x0>; /* A53 L2 dump not supported */ + L2_tlb_0: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc1>; + qcom,ldo = <&ldo1>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc2>; + qcom,ldo = <&ldo2>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc3>; + qcom,ldo = <&ldo3>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc4>; + qcom,ldo = <&ldo4>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + qcom,dump-size = <0x280040>; /*A57 Cluster L2 size is 1MB */ + power-domain = <&l2ccc_1>; + L2_tlb_1: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_itlb_100: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_100: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc5>; + qcom,ldo = <&ldo5>; + next-level-cache = <&L2_1>; + L1_itlb_101: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_101: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x102>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc6>; + qcom,ldo = <&ldo6>; + next-level-cache = <&L2_1>; + L1_itlb_102: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_102: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x103>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc7>; + qcom,ldo = <&ldo7>; + next-level-cache = <&L2_1>; + L1_itlb_103: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_103: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + }; + + soc: soc { }; + + memory { + #address-cells = <2>; + #size-cells = <2>; + + secure_mem: secure_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x12c00000>; + label = "secure_mem"; + }; + + adsp_mem: adsp_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x3F00000>; + label = "adsp_mem"; + }; + + qsecom_mem: qsecom_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x1800000>; + label = "qseecom_mem"; + }; + + audio_mem: audio_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0 0 0x614000>; + label = "audio_mem"; + }; + + removed_regions: removed_regions@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x06300000 0 0xD00000>; + label = "memory_hole"; + }; + /*#ifdef VENDOR_EDIT*/ + /*Add by LiWei. The region is used for nv backup,20150325*/ + nabackup_regions: nvbackup_regions@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for nv backup + //linux,remove-completely;//del by jiachenghui for nv backup + reg = <0 0x06200000 0 0x100000>; + label = "memory_nvbackup"; + }; + /*End by LiWei. The region is used for nv backup, 20150325*/ + /*#endif VENDOR_EDIT*/ + dfps_data_mem: dfps_data_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03400000 0 0x1000>; + label = "dfps_data_mem"; + }; +/*liyunbing@BSP,20150518 revert MIPI_FB_ADDR to default addr, because we located MDSS issue cause by nvbackup*/ + cont_splash_mem: cont_splash_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03401000 0 0x2200000>; + //reg = <0 0x83200000 0 0x2200000>; + label = "cont_splash_mem"; + }; + + peripheral_mem: peripheral_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x0ca00000 0 0x1f00000>; + label = "peripheral_mem"; + }; +/*#ifdef VENDOR_EDIT //changhua.li add for enlarge TZ APP memory to 25M*/ + tzapp_mem: tzapp_region@0 { + + linux,reserve-contiguous-region; + + linux,reserve-region; + + linux,remove-completely; + + reg = <0 0x0E900000 0 0x1900000>; + + label = "tzapp_mem"; + + }; +/*#endif VENDOR_EDIT*/ + + + modem_mem: modem_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x07000000 0 0x5a00000>; + label = "modem_mem"; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops_mem: ramoops_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for ramoops reserve region + //linux,remove-completely;//del by jiachenghui for ramoops reserve region + reg = <0 0xac000000 0 0x00100000>;//modify from 0x05800000 to 0xac000000 by jiachenghui for ramoops reserve region + label = "ramoops_mem"; + }; +/* #endif VENDOR_EDIT */ + + param_mem: param_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region; + //linux,remove-completely; + reg = <0 0xac200000 0 0x00100000>; + label = "param_mem"; + }; + + }; +}; + +#include "msm-gdsc.dtsi" +#include "msm8994-smp2p.dtsi" +#include "msm8994-ipcrouter.dtsi" +#include "msm8994-mdss.dtsi" +#include "msm8994-mdss-pll.dtsi" +#include "msm8994-bus.dtsi" + +&soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + cpuss@fd4a8000 { + compatible = "qcom,cpuss-8994"; + reg = <0xfd4a8000 0x4>; + }; + + acc0:clock-controller@f908b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9070000 0x1000>, + <0xf908b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc1:clock-controller@f909b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9071000 0x1000>, + <0xf909b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc2:clock-controller@f90ab004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9072000 0x1000>, + <0xf90ab000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc3:clock-controller@f90bb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9073000 0x1000>, + <0xf90bb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc4:clock-controller@f90cb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9074000 0x1000>, + <0xf90cb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc5:clock-controller@f90db004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9075000 0x1000>, + <0xf90db000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc6:clock-controller@f90eb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9076000 0x1000>, + <0xf90eb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc7:clock-controller@f90fb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9077000 0x1000>, + <0xf90fb000 0x1000>, + <0xf900b000 0x1000>; + }; + + ldo0:ldo-vref@f9070000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9070000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo1:ldo-vref@f9071000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9071000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo2:ldo-vref@f9072000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9072000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo3:ldo-vref@f9073000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9073000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo4:ldo-vref@f9074000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9074000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo5:ldo-vref@f9075000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9075000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo6:ldo-vref@f9076000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9076000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo7:ldo-vref@f9077000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9077000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + l2ccc_0: clock-controller@f900d000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900d000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster0_spm>; + }; + + l2ccc_1: clock-controller@f900f000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900f000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster1_spm>; + qcom,vctl-val = <0xb8>; + }; + + intc: interrupt-controller@f9000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0xf9000000 0x1000>, + <0xf9002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 2 0xff08>, + <1 3 0xff08>, + <1 4 0xff08>, + <1 1 0xff08>; + clock-frequency = <19200000>; + }; + + qcom,mpm2-sleep-counter@fc4a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0xfc4a3000 0x1000>; + clock-frequency = <32768>; + }; + + timer@f9020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xf9020000 0x1000>; + clock-frequency = <19200000>; + + frame@f9021000 { + frame-number = <0>; + interrupts = <0 9 0x4>, + <0 8 0x4>; + reg = <0xf9021000 0x1000>, + <0xf9022000 0x1000>; + }; + + frame@f9023000 { + frame-number = <1>; + interrupts = <0 10 0x4>; + reg = <0xf9023000 0x1000>; + status = "disabled"; + }; + + frame@f9024000 { + frame-number = <2>; + interrupts = <0 11 0x4>; + reg = <0xf9024000 0x1000>; + status = "disabled"; + }; + + frame@f9025000 { + frame-number = <3>; + interrupts = <0 12 0x4>; + reg = <0xf9025000 0x1000>; + status = "disabled"; + }; + + frame@f9026000 { + frame-number = <4>; + interrupts = <0 13 0x4>; + reg = <0xf9026000 0x1000>; + status = "disabled"; + }; + + frame@f9027000 { + frame-number = <5>; + interrupts = <0 14 0x4>; + reg = <0xf9027000 0x1000>; + status = "disabled"; + }; + + frame@f9028000 { + frame-number = <6>; + interrupts = <0 15 0x4>; + reg = <0xf9028000 0x1000>; + status = "disabled"; + }; + }; + + restart@fc4ab000 { + compatible = "qcom,pshold"; + reg = <0xfc4ab000 0x4>; + }; + + blsp1_uart3: serial@f991f000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991f000 0x1000>; + interrupts = <0 109 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp1_uart2: serial@f991e000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp2_uart2: uart@f995e000 { /* BLSP2 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xf995e000 0x1000>, + <0xf9944000 0x19000>; + status = "disabled"; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 114 0 + 1 &intc 0 239 0 + 2 &msm_gpio 46 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xFD>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp2_ahb_clk>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&hsuart_sleep>; + pinctrl-1 = <&hsuart_active>; + + qcom,msm-bus,name = "buart8"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + }; + + qcom,sps@f9984000 { + compatible = "qcom,msm_sps"; + reg-names = "bam_mem", "core_mem"; + reg = <0xf9984000 0x15000>, + <0xf9999000 0xb000>; + interrupts = <0 94 0>; + qcom,pipe-attr-ee; + clocks = <&clock_rpm clk_pnoc_sps_clk>, + <&clock_gcc clk_gcc_bam_dma_ahb_clk>; + clock-names = "dfab_clk", "dma_bam_pclk"; + }; + + pcie0: qcom,pcie@fc520000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0xfc520000 0x2000>, + <0xfc526000 0x1000>, + <0xff000000 0xf1d>, + <0xff000f20 0xa8>, + <0xff100000 0x100000>, + <0xff200000 0x100000>, + <0xff300000 0xd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie0>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 243 0 + 1 &intc 0 244 0 + 2 &intc 0 245 0 + 3 &intc 0 247 0 + 4 &intc 0 248 0 + 5 &intc 0 249 0 + 6 &intc 0 250 0 + 7 &intc 0 251 0 + 8 &intc 0 252 0 + 9 &intc 0 253 0 + 10 &intc 0 254 0 + 11 &intc 0 255 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; + + perst-gpio = <&msm_gpio 53 0>; + wake-gpio = <&msm_gpio 55 0>; + + gdsc-vdd-supply = <&gdsc_pcie_0>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9006040>; + qcom,msi-gicm-base = <0x180>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + qcom,scm-dev-id = <11>; + + clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_0_aux_clk>, + <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, + <&clock_gcc clk_pcie_0_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_0_reset>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", "pcie_0_aux_clk", + "pcie_0_cfg_ahb_clk", "pcie_0_mstr_axi_clk", + "pcie_0_slv_axi_clk", "pcie_0_ldo", "pcie_0_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + pcie1: qcom,pcie@fc528000 { + compatible = "qcom,pci-msm"; + cell-index = <1>; + + reg = <0xfc528000 0x2000>, + <0xfc52e000 0x1000>, + <0xf8800000 0xf1d>, + <0xf8800F20 0xa8>, + <0xf8801000 0x7f000>, + <0xf8880000 0x80000>, + <0xf8900000 0x700000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie1>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 271 0 + 1 &intc 0 272 0 + 2 &intc 0 273 0 + 3 &intc 0 274 0 + 4 &intc 0 275 0 + 5 &intc 0 276 0 + 6 &intc 0 277 0 + 7 &intc 0 278 0 + 8 &intc 0 279 0 + 9 &intc 0 280 0 + 10 &intc 0 281 0 + 11 &intc 0 282 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>; + pinctrl-1 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_sleep>; + + perst-gpio = <&msm_gpio 35 0>; + wake-gpio = <&msm_gpio 37 0>; + + gdsc-vdd-supply = <&gdsc_pcie_1>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,l1-supported; + qcom,l1ss-supported; + qcom,aux-clk-sync; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9007040>; + qcom,msi-gicm-base = <0x1a0>; + + qcom,ep-wakeirq; + + qcom,msm-bus,name = "pcie1"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, + <100 512 500 800>; + + qcom,scm-dev-id = <12>; + + clocks = <&clock_gcc clk_gcc_pcie_1_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_1_aux_clk>, + <&clock_gcc clk_gcc_pcie_1_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_1_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_1_slv_axi_clk>, + <&clock_gcc clk_pcie_1_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_1_reset>; + + clock-names = "pcie_1_pipe_clk", "pcie_1_ref_clk_src", "pcie_1_aux_clk", + "pcie_1_cfg_ahb_clk", "pcie_1_mstr_axi_clk", + "pcie_1_slv_axi_clk", "pcie_1_ldo", "pcie_1_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + ipa_hw: qcom,ipa@fd4c0000 { + compatible = "qcom,ipa"; + reg = <0xfd4c0000 0x29000>, + <0xfd4c4000 0x15820>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 301 0>, + <0 300 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <3>; /* IPA core version = IPAv2.0 */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; + qcom,ee = <2>; + clock-names = "core_clk"; + clocks = <&clock_rpm clk_ipa_clk>; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <90 512 0 0>, <90 585 0 0>, /* No vote */ + <90 512 100000 800000>, <90 585 100000 800000>, /* SVS */ + <90 512 100000 1200000>, <90 585 100000 1200000>; /* PERF */ + qcom,bus-vector-names = "MIN", "SVS", "PERF"; + + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + }; + + qcom,ipc-spinlock@fd484000 { + compatible = "qcom,ipc-spinlock-sfpb"; + reg = <0xfd484000 0x400>; + qcom,num-locks = <8>; + }; + + qcom,smem@6a00000 { + compatible = "qcom,smem"; + reg = <0x6a00000 0x200000>, + <0xf900d008 0x4>, + <0xfc428000 0x4000>; + reg-names = "smem", "irq-reg-base", "aux-mem1"; + qcom,mpu-enabled; + + qcom,smd-modem { + compatible = "qcom,smd"; + qcom,smd-edge = <0>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1000>; + interrupts = <0 25 1>; + label = "modem"; + qcom,not-loadable; + }; + + qcom,smsm-modem { + compatible = "qcom,smsm"; + qcom,smsm-edge = <0>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x2000>; + interrupts = <0 26 1>; + }; + + qcom,smd-adsp { + compatible = "qcom,smd"; + qcom,smd-edge = <1>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x100>; + interrupts = <0 156 1>; + label = "adsp"; + }; + + qcom,smsm-adsp { + compatible = "qcom,smsm"; + qcom,smsm-edge = <1>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x200>; + interrupts = <0 157 1>; + }; + + qcom,smd-rpm { + compatible = "qcom,smd"; + qcom,smd-edge = <15>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1>; + interrupts = <0 168 1>; + label = "rpm"; + qcom,irq-no-suspend; + qcom,not-loadable; + }; + }; + + qcom,msm-imem@fe87f000 { + compatible = "qcom,msm-imem"; + reg = <0xfe87f000 0x1000>; /* Address and size of IMEM */ + ranges = <0x0 0xfe87f000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + download_mode@0 { + compatible = "qcom,msm-imem-download_mode"; + reg = <0x0 8>; + }; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + + pil@94c { + compatible = "qcom,msm-imem-pil"; + reg = <0x94c 200>; + }; + + emergency_download_mode@fe0 { + compatible = "qcom,msm-imem-emergency_download_mode"; + reg = <0xfe0 12>; + }; + }; + + qcom,wdt@f9017000 { + compatible = "qcom,msm-watchdog"; + reg = <0xf9017000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 3 0>, <0 4 0>; +//liyunbing@BSP, 2015/05/21, WDT bark-time too short cause some task timeout + #qcom,bark-time = <11000>; + qcom,bark-time = <15000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + }; + + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + jtag_fuse: jtagfuse@fc4be024 { + compatible = "qcom,jtag-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + }; + + jtag_mm0: jtagmm@fb840000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb840000 0x1000>, + <0xfb810000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU0>; + }; + + jtag_mm1: jtagmm@fb940000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb940000 0x1000>, + <0xfb910000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU1>; + }; + + jtag_mm2: jtagmm@fba40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfba40000 0x1000>, + <0xfba10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU2>; + }; + + jtag_mm3: jtagmm@fbb40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbb40000 0x1000>, + <0xfbb10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU3>; + }; + + jtag_mm4: jtagmm@fbc40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbc40000 0x1000>, + <0xfbc10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU4>; + }; + + jtag_mm5: jtagmm@fbd40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbd40000 0x1000>, + <0xfbd10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU5>; + }; + + jtag_mm6: jtagmm@fbe40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbe40000 0x1000>, + <0xfbe10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU6>; + }; + + jtag_mm7: jtagmm@fbf40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbf40000 0x1000>, + <0xfbf10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU7>; + }; + + rpm_bus: qcom,rpm-smd { + compatible = "qcom,rpm-smd"; + rpm-channel-name = "rpm_requests"; + rpm-channel-type = <15>; /* SMD_APPS_RPM */ + }; + + qcom,msm-rng@f9bff000 { + compatible = "qcom,msm-rng"; + reg = <0xf9bff000 0x200>; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 618 0 0>, + <88 618 0 800>; + qcom,msm-rng-iface-clk; + clocks = <&clock_gcc clk_gcc_prng_ahb_clk>; + clock-names = "iface_clk"; + }; + + qcom,rmtfs_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00180000>; + reg-names = "rmtfs"; + qcom,client-id = <0x00000001>; + }; + + qcom,dsp_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_dsp"; + qcom,client-id = <0x011013ec>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,mdm_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_mdm"; + qcom,client-id = <0x011013ed>; + }; + + qcom,sensors_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_sensor"; + qcom,client-id = <0x011013ee>; + linux,contiguous-region = <&adsp_mem>; + }; + + sdhc_1: sdhci@f9824900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 123 0>, <0 138 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc1"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */ + <78 512 1600 3200>, /* 400 KB/s*/ + <78 512 80000 160000>, /* 20 MB/s */ + <78 512 100000 200000>, /* 25 MB/s */ + <78 512 200000 400000>, /* 50 MB/s */ + <78 512 400000 800000>, /* 100 MB/s */ + <78 512 400000 800000>, /* 200 MB/s */ + <78 512 400000 800000>, /* 400 MB/s */ + <78 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 400000000 4294967295>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>, + <&clock_gcc clk_gcc_sdcc1_apps_clk>; + + status = "disabled"; + }; + + sdhc_2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 125 0>, <0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>, + <&clock_gcc clk_gcc_sdcc2_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc2"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */ + <81 512 1600 3200>, /* 400 KB/s*/ + <81 512 80000 160000>, /* 20 MB/s */ + <81 512 100000 200000>, /* 25 MB/s */ + <81 512 200000 400000>, /* 50 MB/s */ + <81 512 400000 800000>, /* 100 MB/s */ + <81 512 800000 800000>, /* 200 MB/s */ + <81 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + + status = "disabled"; + }; + + sdhc_3: sdhci@f9864900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9864900 0x11c>, <0xf9864000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 127 0>, <0 224 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc3_ahb_clk>, + <&clock_gcc clk_gcc_sdcc3_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc3"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */ + <79 512 1600 3200>, /* 400 KB/s*/ + <79 512 80000 160000>, /* 20 MB/s */ + <79 512 100000 200000>, /* 25 MB/s */ + <79 512 200000 400000>, /* 50 MB/s */ + <79 512 400000 800000>, /* 100 MB/s */ + <79 512 800000 800000>, /* 200 MB/s */ + <79 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + qcom,dat1-mpm-int = <47>; + status = "disabled"; + }; + + ufs_ice: ufsice@fc5a0000 { + compatible = "qcom,ice"; + reg = <0xfc5a0000 0x8000>; + interrupt-names = "ufs_ice_nonsec_level_irq", "ufs_ice_sec_level_irq"; + interrupts = <0 258 0>, <0 257 0>; + status = "disabled"; + }; + + ufsphy1: ufsphy@fc597000 { + compatible = "qcom,ufs-phy-qmp-20nm"; + reg = <0xfc597000 0xda8>; + reg-names = "phy_mem"; + #phy-cells = <0>; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-max-microamp = <45000>; + vdda-pll-max-microamp = <100>; + vddp-ref-clk-supply = <&pm8994_l31>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + clock-names = "ref_clk_src", + "ref_clk", + "tx_iface_clk", + "rx_iface_clk"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_ufs_phy_ldo>, + <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, + <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; + status = "disabled"; + }; + + ufs1: ufshc@fc594000 { + compatible = "qcom,ufshc"; + reg = <0xfc594000 0x2500>, <0xfd512074 0x4>; + interrupts = <0 265 0>; + phys = <&ufsphy1>; + phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8994_l20>; + vccq-supply = <&pm8994_l31>; + vccq2-supply = <&pm8994_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <50000>; + vccq2-max-microamp = <750000>; + + clock-names = "core_clk_src", "core_clk", "bus_clk", "iface_clk", + "ref_clk", "rx_lane0_sync_clk", "tx_lane0_sync_clk", + "rx_lane1_sync_clk", "tx_lane1_sync_clk"; + clocks = + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>, + <&clock_rpm clk_bb_clk1>, + <&clock_gcc clk_gcc_ufs_rx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_rx_symbol_1_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_1_clk>; + qcom,msm-bus,name = "ufs1"; + qcom,msm-bus,num-cases = <22>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <95 512 0 0>, <1 650 0 0>, /* No vote */ + <95 512 922 0>, <1 650 1000 0>, /* PWM G1 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G3 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G4 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G1 L2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G2 L2 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G3 L2 */ + <95 512 14752 0>, <1 650 1000 0>, /* PWM G4 L2 */ + <95 512 127796 0>, <1 650 1000 0>, /* HS G1 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G2 RA */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G3 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G1 RA L2 */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G2 RA L2 */ + <95 512 1022362 0>, <1 650 1000 0>, /* HS G3 RA L2 */ + <95 512 149422 0>, <1 650 1000 0>, /* HS G1 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G2 RB */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G3 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G1 RB L2 */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G2 RB L2 */ + <95 512 1192756 0>, <1 650 1000 0>, /* HS G3 RB L2 */ + <95 512 4096000 0>, <1 650 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "PWM_G1_L2", "PWM_G2_L2", "PWM_G3_L2", "PWM_G4_L2", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", + "HS_RA_G1_L2", "HS_RA_G2_L2", "HS_RA_G3_L2", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", + "HS_RB_G1_L2", "HS_RB_G2_L2", "HS_RB_G3_L2", + "MAX"; + + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0xf>; /* little cluster */ + qcom,cpu-dma-latency-us = <301>; + + spm-level = <5>; + status = "disabled"; + }; + + spi_0: spi_epm: spi@f9923000 { /* BLSP1 QUP1 */ + compatible = "qcom,spi-qup-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical", "spi_bam_physical"; + reg = <0xf9923000 0x1000>, + <0xf9904000 0x19000>; + interrupt-names = "spi_irq", "spi_bam_irq"; + interrupts = <0 95 0>, <0 238 0>; + spi-max-frequency = <19200000>; + + qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <12>; + qcom,bam-producer-pipe-index = <13>; + qcom,master-id = <86>; + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_0_active &spi_0_cs1_active>; + pinctrl-1 = <&spi_0_sleep &spi_0_cs1_sleep>; + + clock-names = "iface_clk", "core_clk"; + + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + }; +//#ifdef VENDOR_EDIT +/* add for fpc1021 fingerprints */ + spi_12: spi@f9968000 { + compatible = "qcom,spi-qup-v2"; + //cell-index = <12>; //changhua + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical"/*, "spi_bam_physical"*/; + + /*Add BAM physical address + BLSP1: 0xf9904000 + BLSP2: 0xf9944000 + */ + + reg = <0xf9968000 0x1000>/*, + <0xf9944000 0x19000>*/; + + interrupt-names = "spi12_irq"/*, "spi_bam_irq"*/; + + /* Add BAM IRQ + BLSP1: 238 + BLSP2: 239 ??271??? 239 is offset + */ + interrupts = <0 106 0>/*, <0 239 0>*/; + + spi-max-frequency = <9600000>; + + /* //changhua + qcom,gpio-mosi = <&msm_gpio 85 0>; + qcom,gpio-miso = <&msm_gpio 86 0>; + qcom,gpio-clk = <&msm_gpio 88 0>; + qcom,gpio-cs0 = <&msm_gpio 87 0>; + */ + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup6_spi_apps_clk>; + + qcom,master-id = <86>; + /*qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <22>; + qcom,bam-producer-pipe-index = <23>; + */ + /*lichanghua add for use pinctrl*/ + /* Assign runtime functions to pins */ + + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_12_active &spi_12_cs0_active>; + pinctrl-1 = <&spi_12_sleep &spi_12_cs0_sleep>; + + qcom,shared; + + /*lichanghua add for use pinctrl end*/ + }; +//#endif/*VENDOR_EDIT*/ + + qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + }; + + qcom,msm-pacman { + compatible = "qcom,msm-pacman"; + }; + + wcd9xxx_intc: wcd9xxx-irq { + compatible = "qcom,wcd9xxx-irq"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&msm_gpio>; + interrupts = <72 0>; + interrupt-names = "cdc-int"; + }; + + tspp: msm_tspp@f99d8000 { + compatible = "qcom,msm_tspp"; + reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */ + <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */ + <0xf99da000 0x1000>, /* MSM_TSPP_PHYS */ + <0xf99c4000 0x11000>; /* MSM_TSPP_BAM_PHYS */ + reg-names = "MSM_TSIF0_PHYS", + "MSM_TSIF1_PHYS", + "MSM_TSPP_PHYS", + "MSM_TSPP_BAM_PHYS"; + interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */ + <0 119 0>, /* TSIF0_IRQ */ + <0 120 0>, /* TSIF1_IRQ */ + <0 122 0>; /* TSIF_BAM_IRQ */ + interrupt-names = "TSIF_TSPP_IRQ", + "TSIF0_IRQ", + "TSIF1_IRQ", + "TSIF_BAM_IRQ"; + + clock-names = "iface_clk", "ref_clk"; + clocks = <&clock_gcc clk_gcc_tsif_ahb_clk>, + <&clock_gcc clk_gcc_tsif_ref_clk>; + + qcom,msm-bus,name = "tsif"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <82 512 0 0>, /* No vote */ + <82 512 12288 24576>; /* Max. bandwidth, 2xTSIF, each max of 96Mbps */ + + pinctrl-names = "disabled", + "tsif0-mode1", "tsif0-mode2", + "tsif1-mode1", "tsif1-mode2", + "dual-tsif-mode1", "dual-tsif-mode2"; + + pinctrl-0 = <>; /* disabled */ + pinctrl-1 = <&tsif0_signals_active>; /* tsif0-mode1 */ + pinctrl-2 = <&tsif0_signals_active + &tsif0_sync_active>; /* tsif0-mode2 */ + pinctrl-3 = <&tsif1_signals_active>; /* tsif1-mode1 */ + pinctrl-4 = <&tsif1_signals_active + &tsif1_sync_active>; /* tsif1-mode2 */ + pinctrl-5 = <&tsif0_signals_active + &tsif1_signals_active>; /* dual-tsif-mode1 */ + pinctrl-6 = <&tsif0_signals_active + &tsif0_sync_active + &tsif1_signals_active + &tsif1_sync_active>; /* dual-tsif-mode2 */ + }; + + slim_msm: slim@fe12f000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0xfe12f000 0x2C000>, + <0xfe104000 0x20000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 163 0>, <0 164 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x60000000>; + qcom,ea-pc = <0x110>; + + tomtom_codec { + compatible = "qcom,tomtom-slim-pgd"; + elemental-addr = [00 01 30 01 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30 31>; + + qcom,cdc-reset-gpio = <&msm_gpio 68 0>; + + cdc-vdd-buck-supply = <&pm8994_s5>; + qcom,cdc-vdd-buck-voltage = <2150000 2150000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-vdd-tx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pm8994_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + cdc-vdd-a-1p2v-supply = <&pm8994_l11>; + qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>; + qcom,cdc-vdd-a-1p2v-current = <2000>; + + cdc-vddcx-1-supply = <&pm8994_l11>; + qcom,cdc-vddcx-1-voltage = <1200000 1200000>; + qcom,cdc-vddcx-1-current = <33000>; + + cdc-vddcx-2-supply = <&pm8994_l11>; + qcom,cdc-vddcx-2-voltage = <1200000 1200000>; + qcom,cdc-vddcx-2-current = <33000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1", + "cdc-vdd-a-1p2v", + "cdc-vddcx-1", + "cdc-vddcx-2"; + + qcom,cdc-micbias-ldoh-v = <0x3>; + qcom,cdc-micbias-cfilt1-mv = <1800>; + //#ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv , 2015/3/24, modify micbias voltage*/ + /*kangjirui@MultiMedia.AudioDrv , 2015/4/18, modify micbias voltage for headset button error*/ + qcom,cdc-micbias-cfilt2-mv = <2700>; + //#endif /* VENDOR_EDIT */ + qcom,cdc-micbias-cfilt3-mv = <1800>; + qcom,cdc-micbias1-cfilt-sel = <0x0>; + qcom,cdc-micbias2-cfilt-sel = <0x1>; + qcom,cdc-micbias3-cfilt-sel = <0x2>; + qcom,cdc-micbias4-cfilt-sel = <0x2>; + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tomtom-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 30 01 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + qcom,cdc-variant = "WCD9330"; + }; + }; + + spmi_bus: qcom,spmi@fc4c0000 { + compatible = "qcom,spmi-pmic-arb"; + reg-names = "core", "intr", "cnfg"; + reg = <0xfc4cf000 0x1000>, + <0xfc4cb000 0x1000>, + <0xfc4ca000 0x1000>; + /* 190,ee0_krait_hlos_spmi_periph_irq */ + /* 187,channel_0_krait_hlos_trans_done_irq */ + interrupts = <0 190 0>, <0 187 0>; + qcom,pmic-arb-channel = <0>; + qcom,pmic-arb-ee = <0>; + #interrupt-cells = <3>; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + }; + + usb3: ssusb@f9200000 { + compatible = "qcom,dwc-usb3-msm"; + status = "disabled"; + reg = <0xf9200000 0xfc000>, + <0xfd4ab000 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupt-parent = <&usb3>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x0 0xffffffff>; + interrupt-map = <0x0 0 &intc 0 133 0 + 0x0 1 &intc 0 180 0 + 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>; + interrupt-names = "hs_phy_irq", "pwr_event_irq", "pmic_id_irq"; + + USB3_GDSC-supply = <&gdsc_usb30>; + vdda33-supply = <&pm8994_l24>; + vbus_dwc3-supply = <&smbcharger_charger_otg>; + qcom,dwc-usb3-msm-tx-fifo-size = <29696>; + qcom,dwc-usb3-msm-qdss-tx-fifo-size = <8192>; + qcom,usb-dbm = <&dbm_1p5>; + + qcom,msm-bus,name = "usb3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <61 512 0 0>, + <61 512 240000 960000>; + + qcom,power-collapse-on-cable-disconnect; + qcom,por-after-power-collapse; + + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>, + <&clock_gcc clk_gcc_usb30_mock_utmi_clk>, + <&clock_gcc clk_gcc_usb30_sleep_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_rpm clk_cxo_dwc3_clk>; + clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk", + "ref_clk", "xo"; + + dwc3@f9200000 { + compatible = "synopsys,dwc3"; + reg = <0xf9200000 0xfc000>; + interrupt-parent = <&intc>; + interrupts = <0 131 0>; + tx-fifo-resize; + snps,usb3-u1u2-disable; + usb-phy = <&hsphy0>, <&ssphy0>; + }; + }; + + hsphy0: hsphy@f92f8800 { + compatible = "qcom,usb-hsphy"; + status = "disabled"; + reg = <0xf92f8800 0x3ff>, + <0xf9b3a000 0x110>; + reg-names = "core", "phy_csr"; + // #ifdef VENDOR_EDIT + /*modify by jiachenghui from 0x00D191A4 to 0x00D191A7 for OTG 2015-04-22*/ + /*change HS DC voltage-level to 0x0011 by jiachenghui for OTG detect issue 2015-05-23*/ + qcom,hsphy-init = <0x00D187A7>; + //#endif /*VENDOR_EDIT*/ + vdd-supply = <&pm8994_s2_corner>; + vddcx-supply = <&pm8994_s1_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,ext-vbus-id; + qcom,vbus-valid-override; + qcom,set-pllbtune; + qcom,sleep-clk-reset; + qcom,vdda-force-on; + clocks = <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>; + clock-names = "phy_sleep_clk"; + }; + + ssphy0: ssphy@f9b38000 { + compatible = "qcom,usb-ssphy-qmp"; + status = "disabled"; + reg = <0xf9b38000 0x800>, + <0xf9b3e000 0x3ff>; + reg-names = "qmp_phy_base", + "qmp_ahb2phy_base"; + vdd-supply = <&pm8994_l28>; + vdda18-supply = <&pm8994_l6>; + qcom,vdd-voltage-level = <0 1000000 1000000>; + qcom,vbus-valid-override; + qcom,no-pipe-clk-switch; + + clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>, + <&clock_gcc clk_gcc_usb3_phy_pipe_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_usb3_phy_reset>, + <&clock_gcc clk_gcc_usb3phy_phy_reset>, + <&clock_gcc clk_usb_ss_phy_ldo>; + clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset", + "phy_phy_reset", "ldo_clk"; + }; + + dbm_1p5: dbm@f92f8000 { + compatible = "qcom,usb-dbm-1p5"; + reg = <0xf92f8000 0x1000>; + qcom,reset-ep-after-lpm-resume; + }; + + qcom,usbbam@f9304000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xf9304000 0x9000>, + <0xf92f880c 0x4>; + reg-names = "ssusb", "qscratch_ram1_reg"; + interrupts = <0 132 0>; + interrupt-names = "ssusb"; + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>; + clock-names = "mem_clk", "mem_iface_clk"; + + qcom,usb-bam-fifo-baseaddr = <0xf9200000>; + qcom,usb-bam-num-pipes = <16>; + qcom,ignore-core-reset-ack; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + + qcom,pipe0 { + label = "ssusb-ipa-out-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <0>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,src-bam-physical-address = <0xf9304000>; + qcom,src-bam-pipe-index = <1>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe1 { + label = "ssusb-ipa-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe2 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <1>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,src-bam-physical-address = <0xfc37C000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-offset = <0xf0000>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0xf4000>; + qcom,descriptor-fifo-size = <0x1400>; + qcom,reset-bam-on-connect; + }; + + /* USB BAM pipe (consumer) configuration for accelerated DPL */ + qcom,pipe3 { + label = "ssusb-dpl-ipa-in-1"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <1>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + }; + + usb_otg: usb@f9a55000 { + compatible = "qcom,hsusb-otg"; + status = "disabled"; + + reg = <0xf9a55000 0x400>; + reg-names = "core"; + interrupts = <0 134 0 0 140 0>; + interrupt-names = "core_irq", "async_irq"; + + HSUSB_VDDCX-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "sleep_clk", "xo"; + + qcom,hsusb-otg-phy-type = <2>; + qcom,hsusb-otg-phy-init-seq = <0x63 0x81 0xffffffff>; + qcom,hsusb-otg-mode = <1>; + qcom,hsusb-otg-otg-control = <1>; + }; + + usb_ehci: ehci@f9a55000 { + compatible = "qcom,ehci-host"; + status = "disabled"; + reg = <0xf9a55000 0x400>; + interrupts = <0 134 0>, <0 140 0>; + interrupt-names = "core_irq", "async_irq"; + hsusb_vdd_dig-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 2 3 5 7>; + qcom,usb2-power-budget = <500>; + usb-phy = <&qusb_phy>; + qcom,pm-qos-latency = <30001>; + + qcom,msm-bus,name = "usb-hs"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <87 512 0 0>, + <87 512 40000 60000>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "xo"; + }; + + qusb_phy: qusb@f9b39000 { + compatible = "qcom,qusb2phy"; + status = "disabled"; + reg = <0xf9b39000 0x17f>; + reg-names = "qusb_phy_base"; + vdd-supply = <&pm8994_s2_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,qusb-tune = <0xa08391d5>; + phy_type = "ulpi"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_qusb2_phy_reset>; + clock-names = "ref_clk", "cfg_ahb_clk", "phy_reset"; + }; + + android_usb@fe87f0c8 { + compatible = "qcom,android-usb"; + reg = <0xfe87f0c8 0xc8>; + qcom,pm-qos-latency = <61 637 1261>; + /*add by jiachenghui for cdrom,20150528*/ + /*#ifdef VENDOR_EDIT*/ + qcom,android-usb-cdrom; + /*#ifdef VENDOR_EDIT*/ + /*end add by jiachenghui for cdrom,20150528*/ + }; + + qcom,venus@fdce0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfdce0000 0x4000>; + + vdd-supply = <&gdsc_venus>; + qcom,proxy-reg-names = "vdd"; + clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_rpm clk_scm_ce1_clk>; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + linux,contiguous-region = <&peripheral_mem>; + }; + + qcom,mss@fc880000 { + compatible = "qcom,pil-q6v55-mss"; + reg = <0xfc880000 0x100>, + <0xfd485000 0x400>, + <0xfc820000 0x020>, + <0xfc401680 0x004>; + reg-names = "qdsp6_base", "halt_base", "rmb_base", + "restart_reg"; + + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_mss_cfg_ahb_clk>, + <&clock_rpm clk_pnoc_modem_clk>, + <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>, + <&clock_gcc clk_gcc_boot_rom_ahb_clk>, + <&clock_gcc clk_gpll0_out_msscc>; + clock-names = "xo", "iface_clk", "pnoc_clk", "bus_clk", + "mem_clk", "gpll0_mss_clk"; + qcom,proxy-clock-names = "xo", "pnoc_clk"; + qcom,active-clock-names = "iface_clk", "bus_clk", "mem_clk", + "gpll0_mss_clk"; + + interrupts = <0 24 1>; + vdd_mss-supply = <&pm8994_s7>; + vdd_cx-supply = <&pm8994_s1_corner>; + vdd_mx-supply = <&pm8994_s2_corner>; + vdd_mx-uV = <7>; + vdd_pll-supply = <&pm8994_l12>; + qcom,vdd_pll = <1800000>; + qcom,firmware-name = "modem"; + qcom,pil-self-auth; + qcom,mba-image-is-not-elf; + qcom,sysmon-id = <0>; + qcom,ssctl-instance-id = <0x12>; + qcom,override-acc; + qcom,ahb-clk-vote; + qcom,pnoc-clk-vote; + + /* GPIO inputs from mss */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>; + + /* GPIO output to mss */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>; + + linux,contiguous-region = <&modem_mem>; + }; + + qcom,lpass@fe200000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfe200000 0x00100>; + interrupts = <0 162 1>; + + vdd_cx-supply = <&pm8994_s1_corner>; + qcom,proxy-reg-names = "vdd_cx"; + qcom,vdd_cx-uV-uA = <7 100000>; + + clocks = <&clock_rpm clk_cxo_pil_lpass_clk>, + <&clock_rpm clk_scm_ce1_clk>; + clock-names = "xo", "scm_ce1_clk"; + qcom,proxy-clock-names = "xo", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + qcom,pas-id = <1>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <423>; + qcom,sysmon-id = <1>; + qcom,ssctl-instance-id = <0x14>; + qcom,firmware-name = "adsp"; + + /* GPIO inputs from lpass */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_2_in 2 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_2_in 1 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_2_in 3 0>; + + /* GPIO output to lpass */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>; + + linux,contiguous-region = <&peripheral_mem>; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops { + compatible = "ramoops"; + /*reg = <0x05800000 0x00100000>;*/ + linux,contiguous-region = <&ramoops_mem>; + }; +/* #endif VENDOR_EDIT */ + + + clock_rpm: qcom,rpmcc@fc401880 { + compatible = "qcom,rpmcc-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + #clock-cells = <1>; + }; + + clock_gcc: qcom,gcc@fc400000 { + compatible = "qcom,gcc-8994"; + reg = <0xfc400000 0x2000>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + clock-names = "xo", "xo_a_clk"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_cxo_clk_src_ao>; + #clock-cells = <1>; + }; + + clock_mmss: qcom,mmsscc@fd8c0000 { + compatible = "qcom,mmsscc-8994"; + reg = <0xfd8c0000 0x5200>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + mmpll4_dig-supply = <&pm8994_s1_corner>; + mmpll4_analog-supply = <&pm8994_l12>; + clock-names = "xo", "gpll0", "mmssnoc_ahb", + "oxili_gfx3d_clk", "pclk0_src", "pclk1_src", + "byte0_src", "byte1_src", "extpclk_src"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_gcc clk_gpll0_out_mmsscc>, + <&clock_rpm clk_mmssnoc_ahb_clk>, + <&clock_rpm clk_oxili_gfx3d_clk_src>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_hdmi_pll clk_hdmi_20nm_vco_clk>; + #clock-cells = <1>; + }; + + clock_debug: qcom,cc-debug@fc401880 { + compatible = "qcom,cc-debug-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + clock-names = "debug_mmss_clk", "debug_rpm_clk", + "debug_cpu_clk"; + clocks = <&clock_mmss clk_mmss_debug_mux>, + <&clock_rpm clk_rpm_debug_mux>, + <&clock_cpu clk_cpu_debug_mux>; + #clock-cells = <1>; + }; + + cci_cache: qcom,cci { + compatible = "devfreq-simple-dev"; + clock-names = "devfreq_clk"; + clocks = <&clock_cpu clk_cci_clk>; + governor = "cpufreq"; + freq-tbl-khz = + < 150000 >, + < 200000 >, + < 249600 >, + < 300000 >, + < 384000 >, + < 499200 >, + < 600000 >; + }; + + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "cpufreq"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc388000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + cpubw-cpufreq { + target-dev = <&cpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 1525 >, + < 691200 2288 >, + < 768000 3562 >, + < 844800 4066 >, + < 921600 5126 >, + < 940800 6072 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 2288 >, + < 691200 3562 >, + < 768000 4066 >, + < 844800 5126 >, + < 921600 6072 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >, + < 940800 5928 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >; + }; + + cci-cpufreq { + target-dev = <&cci_cache>; + cpu-to-dev-map-0 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 384000 >, + < 844800 499200 >, + < 921600 600000 >, + < 940800 600000 >; + cpu-to-dev-map-4 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 499200 >, + < 844800 600000 >, + < 921600 600000 >; + }; + }; + + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "l2_clk", "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk"; + clocks = <&clock_cpu clk_cci_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>; + + qcom,governor-per-policy; + + qcom,cpufreq-table-0 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >, + < 940800 >; + + qcom,cpufreq-table-4 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >; + }; + + clock_cpu: qcom,cpu-clock-8994@f9015000 { + compatible = "qcom,cpu-clock-8994"; + reg = <0xf9015000 0x1000>, + <0xf9016000 0x1000>, + <0xf9011000 0x1000>, + <0xf900d000 0x1000>, + <0xf900f000 0x1000>, + <0xf9112000 0x1000>, + <0xfc4b80b0 0x8>; + reg-names = "c0_pll", "c1_pll", "cci_pll", "c0_mux", "c1_mux", "cci_mux", "efuse"; + vdd-a53-supply = <&apc0_vreg_corner>; + vdd-a57-supply = <&apc1_vreg_corner>; + vdd-cci-supply = <&apc0_vreg_corner>; + vdd-dig-supply = <&pm8994_s1_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>, + < 940800000 9>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 150000000 1>, + < 200000000 2>, + < 249600000 3>, + < 300000000 4>, + < 384000000 4>, + < 499200000 7>, + < 600000000 9>; + clock-names = "xo_ao", "aux_clk"; + clocks = <&clock_rpm clk_cxo_clk_src_ao>, + <&clock_gcc clk_gpll0_ao>; + #clock-cells = <1>; + }; + + ocmem: qcom,ocmem@fdd00000 { + compatible = "qcom,msm-ocmem"; + reg = <0xfdd00000 0x2000>, + <0xfdd02000 0x2000>, + <0xfe039000 0x400>, + <0xfec00000 0x200000>; + reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical"; + interrupts = <0 76 0 0 77 0>; + interrupt-names = "ocmem_irq", "dm_irq"; + qcom,ocmem-num-regions = <0x4>; + qcom,ocmem-num-macros = <0x20>; + qcom,resource-type = <0x706d636f>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfec00000 0x200000>; + clocks = <&clock_rpm clk_ocmemgx_core_clk>, + <&clock_mmss clk_ocmemcx_ocmemnoc_clk>; + clock-names = "core_clk", "iface_clk"; + + partition@0 { + reg = <0x0 0x180000>; + qcom,ocmem-part-name = "graphics"; + qcom,ocmem-part-min = <0x80000>; + }; + + partition@100000 { + reg = <0x180000 0x80000>; + qcom,ocmem-part-name = "video"; + qcom,ocmem-part-min = <0x55000>; + }; + + }; + + msm_vidc: qcom,vidc@fdc00000 { + compatible = "qcom,msm-vidc"; + reg = <0xfdc00000 0xff000>; + interrupts = <0 44 0>; + qcom,hfi = "venus"; + qcom,reg-presets = <0x800D8 0x707>, + <0xe0020 0x55555556>, + <0xe0024 0x55555556>, + <0x80124 0x3>; + qcom,qdss-presets = <0xfc325000 0x1000>, + <0xfc326000 0x1000>, + <0xfc321000 0x1000>, + <0xfc322000 0x1000>, + <0xfc323000 0x1000>, + <0xfc302000 0x1000>, + <0xfa180000 0x1000>, + <0xfa181000 0x1000>; + qcom,ocmem-size = <524288>; /* 512 * 1024*/ + qcom,max-hw-load = <1281600>; /* Full 4k @ 30 + 1080p @ 30 */ + clock-names = "core_clk", "core0_clk", "core1_clk", "core2_clk", + "iface_clk", "bus_clk", "mem_clk"; + venus-supply = <&gdsc_venus>; + venus-core0-supply = <&gdsc_venus_core0>; + venus-core1-supply = <&gdsc_venus_core1>; + venus-core2-supply = <&gdsc_venus_core2>; + qcom,clock-configs = <0x3 0x0 0x0 0x0 0x0 0x0 0x0>; + qcom,sw-power-collapse; + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_core0_vcodec_clk>, + <&clock_mmss clk_venus0_core1_vcodec_clk>, + <&clock_mmss clk_venus0_core2_vcodec_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>; + qcom,load-freq-tbl = + <979200 465000000 0x0c000000>, + <979200 465000000 0x01000414>, + <979200 465000000 0x030fcfff>, + <979200 465000000 0x04000000>, + <783360 465000000 0x0c000000>, + <783360 465000000 0x01000414>, + <783360 465000000 0x030fcfff>, + <783360 465000000 0x04000000>, + <489600 240000000 0x0c000000>, + <489600 240000000 0x01000414>, + <489600 240000000 0x030fcfff>, + <489600 240000000 0x04000000>, + <244800 133330000 0x0c000000>, + <244800 133330000 0x01000414>, + <244800 133330000 0x030fcfff>, + <244800 133330000 0x04000000>; + qcom,vidc-iommu-domains { + qcom,domain-ns { + qcom,vidc-domain-phandle = <&venus_domain_ns>; + qcom,vidc-partition-buffer-types = <0x7ff>, + <0x800>; + }; + qcom,domain-sec-bs { + qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>; + qcom,vidc-partition-buffer-types = <0x241>; + }; + qcom,domain-sec-px { + qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>; + qcom,vidc-partition-buffer-types = <0x106>; + }; + qcom,domain-sec-np { + qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>; + qcom,vidc-partition-buffer-types = <0x480>; + }; + }; + qcom,msm-bus-clients { + qcom,msm-bus-client@0 { + qcom,msm-bus,name = "venc-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 2108700 0>, + <63 512 2243700 0>, + <63 512 2615000 0>; + qcom,bus-configs = <0x1000414>; + }; + + qcom,msm-bus-client@1 { + qcom,msm-bus,name = "vdec-core0-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 151600 0>, + <63 512 393600 0>, + <63 512 393600 0>, + <63 512 749100 0>, + <63 512 749100 0>, + <63 512 1460700 0>, + <63 512 2390500 0>, + <63 512 2542300 0>, + <63 512 2959800 0>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@2 { + qcom,msm-bus,name = "vdec-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 113900 0>, + <63 512 296700 0>, + <63 512 296700 0>, + <63 512 571400 0>, + <63 512 571400 0>, + <63 512 1088500 0>, + <63 512 1811000 0>, + <63 512 1962000 0>, + <63 512 2242900 0>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@3 { + qcom,msm-bus,name = "venc-core2-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 89000 0>, + <63 512 270000 0>, + <63 512 270000 0>, + <63 512 759000 0>, + <63 512 759000 0>, + <63 512 1050000 0>, + <63 512 3077000 0>, + <63 512 3811000 0>, + <63 512 3812000 0>; + qcom,bus-configs = <0x04000000>; + }; + qcom,msm-bus-client@4 { + qcom,msm-bus,name = "venc-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 69000 2384000>, + <68 604 207000 2384000>, + <68 604 207000 2384000>, + <68 604 470000 2384000>, + <68 604 470000 2384000>, + <68 604 940000 3632000>, + <68 604 1787000 3632000>, + <68 604 1906000 3632000>, + <68 604 2234000 3632000>; + qcom,bus-configs = <0x10000414>; + }; + qcom,msm-bus-client@5 { + qcom,msm-bus,name = "venc-core2-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 71000 2384000>, + <68 604 214000 2384000>, + <68 604 214000 2384000>, + <68 604 564000 2384000>, + <68 604 564000 2384000>, + <68 604 1003000 3632000>, + <68 604 2040000 3632000>, + <68 604 2349000 3632000>, + <68 604 2551000 3632000>; + qcom,bus-configs = <0x04000000>; + }; + + qcom,msm-bus-client@6 { + qcom,msm-bus,name = "vdec-core0-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 79000 2384000>, + <68 604 201000 2384000>, + <68 604 201000 2384000>, + <68 604 367000 2384000>, + <68 604 367000 2384000>, + <68 604 735000 3632000>, + <68 604 1175000 3632000>, + <68 604 1254000 3632000>, + <68 604 1469000 3632000>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@7 { + qcom,msm-bus,name = "vdec-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 88000 2384000>, + <68 604 228000 2384000>, + <68 604 228000 2384000>, + <68 604 432000 2384000>, + <68 604 432000 2384000>, + <68 604 865000 3632000>, + <68 604 1374000 3632000>, + <68 604 1465000 3632000>, + <68 604 1717000 3632000>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@8 { + qcom,msm-bus,name = "venc-ddr-lp"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 1218000 0>, + <63 512 1218000 0>, + <63 512 1218000 0>; + qcom,bus-low-power; + qcom,bus-configs = <0x0000004>; + }; + + qcom,msm-bus-client@9 { + qcom,msm-bus,name = "venus-arm9-ddr"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 1000 1000>; + qcom,bus-configs = <0x00000000>; + qcom,bus-passive; + }; + }; + }; + + i2c_1: i2c@f9923000 { + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9923000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 95 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_1_active>; + pinctrl-1 = <&i2c_1_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + qcom,master-id = <86>; + dmas = <&dma_blsp1 10 64 0x20000020 0x20>, + <&dma_blsp1 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + dma_blsp1: qcom,sps-dma@f9904000 { /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9904000 0x19000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <10>; + }; + + dma_blsp2: qcom,sps-dma@f9944000 { /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9944000 0x19000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <10>; + }; + + + i2c_2: i2c@f9924000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9924000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 96 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_2_active>; + pinctrl-1 = <&i2c_2_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + + /* #ifdef VENDOR_EDIT */ + //add by yangrujin@bsp for dma has some issue causing i2c fail + //qcom,disable-dma; + /* #endif //VENDOR_EDIT */ + + + dmas = <&dma_blsp1 14 64 0x20000020 0x20>, + <&dma_blsp1 15 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + i2c_5: i2c_11: i2c@f9967000 { /* BLSP2 QUP5 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9967000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 105 0>; + qcom,clk-freq-out = <100000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup5_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_5_active>; + pinctrl-1 = <&i2c_5_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/4/13, dma mode will cause I2C fail*/ + qcom,disable-dma; + //#endif + dmas = <&dma_blsp2 20 64 0x20000020 0x20>, + <&dma_blsp2 21 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + }; + + i2c_6: i2c@f9928000 { /* BLSP1 QUP6 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + reg-names = "qup_phys_addr"; + reg = <0xf9928000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 100 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + dmas = <&dma_blsp1 22 64 0x20000020 0x20>, + <&dma_blsp1 23 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + sound { + compatible = "qcom,msm8994-asoc-snd"; + qcom,model = "msm8994-tomtom-snd-card"; + reg = <0xfe034000 0x4>, + <0xfe035000 0x4>, + <0xfe036000 0x4>, + <0xfe037000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK"; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/3/19, delete unsed mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#endif + + clock-names = "osr_clk"; + clocks = <&clock_rpm clk_div_clk1>; + qcom,cdc-mclk-gpios = <&pm8994_gpios 15 0>; + qcom,tomtom-mclk-clk-freq = <9600000>; + pinctrl-names = "sleep", + "auxpcm-active", + "mi2s-active", + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv,changed for quat i2s */ + "active", + "quat_mi2s_sleep", + "quat_mi2s_active"; + //#endif +//#ifdef VENDOR_EDIT +//pinctrl-0 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-1 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//pinctrl-2 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-3 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ + pinctrl-0 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-1 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; + pinctrl-2 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-3 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s */ + pinctrl-4 = <&quat_mi2s_sleep>, <&quat_mi2s_mclk_sleep>, <&quat_mi2s_sd0_sleep> , <&quat_mi2s_sd1_sleep>; + pinctrl-5 = <&quat_mi2s_active>, <&quat_mi2s_mclk_active>, <&quat_mi2s_sd0_active> , <&quat_mi2s_sd1_active>; +//#endif + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", "msm-pcm-dsp.2", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp"; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s*/ + asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>, <&dai_mi2s>,<&qua_mi2s>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, <&bt_sco_rx>, + <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>, + <&incall_music2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.0","msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.12288", + "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770"; +//#endif + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + }; + + qcom,msm-adsp-loader { + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + qcom,msm-audio-ion { + compatible = "qcom,msm-audio-ion"; + }; + + pcm0: qcom,msm-pcm { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <0>; + }; + + qcom,msm-pcm-lpa { + compatible = "qcom,msm-pcm-lpa"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm1: qcom,msm-pcm-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <1>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "regular"; + }; + + routing: qcom,msm-pcm-routing { + compatible = "qcom,msm-pcm-routing"; + }; + + compr: qcom,msm-compr-dsp { + compatible = "qcom,msm-compr-dsp"; + }; + + compress: qcom,msm-compress-dsp { + compatible = "qcom,msm-compress-dsp"; + }; + + voip: qcom,msm-voip-dsp { + compatible = "qcom,msm-voip-dsp"; + }; + + voice: qcom,msm-pcm-voice { + compatible = "qcom,msm-pcm-voice"; + qcom,destroy-cvd; + }; + + stub_codec: qcom,msm-stub-codec { + compatible = "qcom,msm-stub-codec"; + }; + + qcom,msm-dai-fe { + compatible = "qcom,msm-dai-fe"; + }; + + afe: qcom,msm-pcm-afe { + compatible = "qcom,msm-pcm-afe"; + }; + + dai_hdmi: qcom,msm-dai-q6-hdmi { + compatible = "qcom,msm-dai-q6-hdmi"; + qcom,msm-dai-q6-dev-id = <8>; + }; + + lsm: qcom,msm-lsm-client { + compatible = "qcom,msm-lsm-client"; + }; + + loopback: qcom,msm-pcm-loopback { + compatible = "qcom,msm-pcm-loopback"; + }; + + qcom,msm-voice-svc { + compatible = "qcom,msm-voice-svc"; + }; + + cpe: qcom,msm-cpe-lsm { + compatible = "qcom,msm-cpe-lsm"; + }; + + qcom,msm-dai-q6 { + compatible = "qcom,msm-dai-q6"; + sb_0_rx: qcom,msm-dai-q6-sb-0-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16384>; + }; + + sb_0_tx: qcom,msm-dai-q6-sb-0-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16385>; + }; + + sb_1_rx: qcom,msm-dai-q6-sb-1-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16386>; + }; + + sb_1_tx: qcom,msm-dai-q6-sb-1-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16387>; + }; + + sb_2_rx: qcom,msm-dai-q6-sb-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16388>; + }; + + sb_2_tx: qcom,msm-dai-q6-sb-2-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16389>; + }; + + sb_3_rx: qcom,msm-dai-q6-sb-3-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16390>; + }; + + sb_3_tx: qcom,msm-dai-q6-sb-3-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16391>; + }; + + sb_4_rx: qcom,msm-dai-q6-sb-4-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16392>; + }; + + sb_4_tx: qcom,msm-dai-q6-sb-4-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16393>; + }; + + sb_5_tx: qcom,msm-dai-q6-sb-5-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16395>; + }; + + bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12288>; + }; + + bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12289>; + }; + + int_fm_rx: qcom,msm-dai-q6-int-fm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12292>; + }; + + int_fm_tx: qcom,msm-dai-q6-int-fm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12293>; + }; + + afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <224>; + }; + + afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <225>; + }; + + afe_proxy_rx: com,msm-dai-q6-afe-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <241>; + }; + + afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <240>; + }; + + incall_record_rx: qcom,msm-dai-q6-incall-record-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32771>; + }; + + incall_record_tx: qcom,msm-dai-q6-incall-record-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32772>; + }; + + incall_music_rx: qcom,msm-dai-q6-incall-music-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32773>; + }; + + incall_music2_rx: qcom,msm-dai-q6-incall-music-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32770>; + }; + }; + + dai_pri_auxpcm: qcom,msm-pri-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "primary"; + }; + + dai_sec_auxpcm: qcom,msm-sec-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "secondary"; + }; + + qcom,msm-dai-mi2s { + compatible = "qcom,msm-dai-mi2s"; + dai_mi2s: qcom,msm-dai-q6-mi2s-prim { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <0>; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv ,changed for quat i2s*/ + + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + qua_mi2s: qcom,msm-dai-q6-mi2s-quat { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <3>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; +//#endif + }; + + hostless: qcom,msm-pcm-hostless { + compatible = "qcom,msm-pcm-hostless"; + }; + + tsens: tsens@fc4a8000 { + compatible = "qcom,msm8994-tsens"; + reg = <0xfc4a8000 0x2000>, + <0xfc4bc000 0x1000>; + reg-names = "tsens_physical", "tsens_eeprom_physical"; + interrupts = <0 184 0>; + interrupt-names = "tsens-upper-lower"; + qcom,sensors = <16>; + qcom,slope = <2901 2846 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200>; + }; + + qcom_tzlog: tz-log@fe87f720 { + compatible = "qcom,tz-log"; + reg = <0xfe87f720 0x2000>; + }; + + qcom_crypto1fde: qcrypto1fde@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2fde: qcrypto2fde@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto1pfe: qcrypto1pfe@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2pfe: qcrypto2pfe@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_cedev: qcedev@fd440000 { + compatible = "qcom,qcedev"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <1>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcedev_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,qseecom@6500000{ + compatible = "qcom,qseecom"; + reg = <0x0E900000 0x1900000>;//reg = <0x6500000 0x500000>; ----> <0x0E700000 0x700000>; ----> <0x0E900000 0x1900000>; /*VENDOR_EDIT changhua add more memory for fpc1150 and alipay in TZ*/ + reg-names = "secapp-region"; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,file-encrypt-pipe-pair = <0>; + qcom,support-multiple-ce-hw-instance; + qcom,hlos-num-ce-hw-instances = <2>; + qcom,hlos-ce-hw-instance = <1 2>; + qcom,qsee-ce-hw-instance = <0>; + qcom,msm-bus,name = "qseecom-noc"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,support-fde; + qcom,support-pfe; + qcom,no-clock-support; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 0 0>, + <55 512 120000 1200000>, + <55 512 393600 3936000>; + clock-names = "core_clk", "ufs_core_clk_src", "ufs_core_clk", + "ufs_bus_clk", "ufs_iface_clk"; + clocks = <&clock_rpm clk_qseecom_ce1_clk>, + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information@0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + }; + + sensor_information1: qcom,sensor-information@1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + }; + + sensor_information2: qcom,sensor-information@2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,alias-name = "pop_mem"; + }; + + sensor_information3: qcom,sensor-information@3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + }; + + sensor_information4: qcom,sensor-information@4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + }; + + sensor_information5: qcom,sensor-information@5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + }; + + sensor_information6: qcom,sensor-information@6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,alias-name = "cpu7"; + }; + + sensor_information7: qcom,sensor-information@7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,alias-name = "cpu0"; + }; + + sensor_information8: qcom,sensor-information@8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,alias-name = "cpu1"; + }; + + sensor_information9: qcom,sensor-information@9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,alias-name = "cpu2"; + }; + + sensor_information10: qcom,sensor-information@10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,alias-name = "cpu3"; + }; + + sensor_information11: qcom,sensor-information@11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + }; + + sensor_information12: qcom,sensor-information@12 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor12"; + qcom,alias-name = "gpu"; + }; + + sensor_information13: qcom,sensor-information@13 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor13"; + qcom,alias-name = "cpu4"; + }; + + sensor_information14: qcom,sensor-information@14 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor14"; + qcom,alias-name = "cpu5"; + }; + + sensor_information15: qcom,sensor-information@15 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor15"; + qcom,alias-name = "cpu6"; + }; + + sensor_information16: qcom,sensor-information@16 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pm8994_tz"; + qcom,scaling-factor = <1000>; + }; + + sensor_information17: qcom,sensor-information@17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + + sensor_information18: qcom,sensor-information@18 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "emmc_therm"; + }; + + sensor_information19: qcom,sensor-information@19 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + + sensor_information20: qcom,sensor-information@20 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + + sensor_information21: qcom,sensor-information@21 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + + sensor_information22: qcom,sensor-information@22 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "LLM_IA57"; + }; + + sensor_information23: qcom,sensor-information-23 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "battery"; + }; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <7>; + qcom,poll-ms = <250>; + qcom,limit-temp = <60>; + qcom,temp-hysteresis = <10>; + qcom,therm-reset-temp = <115>; + qcom,freq-step = <2>; + qcom,freq-control-mask = <0xff>; + qcom,core-limit-temp = <80>; + qcom,core-temp-hysteresis = <10>; + qcom,core-control-mask = <0xfe>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <40>; + qcom,cpu-sensors = "tsens_tz_sensor7", "tsens_tz_sensor8", + "tsens_tz_sensor9", "tsens_tz_sensor10", + "tsens_tz_sensor13", "tsens_tz_sensor14", + "tsens_tz_sensor15", "tsens_tz_sensor6"; + qcom,freq-mitigation-temp = <95>; + qcom,freq-mitigation-temp-hysteresis = <10>; + qcom,freq-mitigation-value = <960000>; + qcom,freq-mitigation-control-mask = <0xF0>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,mx-restriction-temp = <5>; + qcom,mx-restriction-temp-hysteresis = <10>; + qcom,mx-retention-min = <3>; + vdd-mx-supply = <&pm8994_s2_corner>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm8994_s1_floor_corner>; + vdd-gfx-supply = <&pmi8994_s2_floor_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <302400 600000 600000>; + qcom,freq-req; + }; + }; + + qcom,bcl { + compatible = "qcom,bcl"; + qcom,bcl-enable; + qcom,bcl-framework-interface; + qcom,bcl-freq-control-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,bcl-hotplug-list = <&CPU6 &CPU7>; + qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,ibat-monitor { + qcom,low-threshold-uamp = <3400000>; + qcom,high-threshold-uamp = <4200000>; + qcom,mitigation-freq-khz = <768000>; + qcom,vph-high-threshold-uv = <3500000>; + qcom,vph-low-threshold-uv = <3300000>; + qcom,soc-low-threshold = <20>; + qcom,thermal-handle = <&msm_thermal_freq>; + }; + }; + + cnss: qcom,cnss@06300000 { + compatible = "qcom,cnss"; + reg = <0x06300000 0x200000>; + reg-names = "ramdump"; + wlan-en-gpio = <&msm_gpio 113 0>; + vdd-wlan-supply = <&bt_vreg>; + vdd-wlan-io-supply = <&pm8994_s4>; + vdd-wlan-xtal-supply = <&pm8994_l30>; + qcom,notify-modem-status; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default>; + qcom,wlan-rc-num = <1>; + qcom,wlan-uart-access; + + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, /* No vote */ + <100 512 6250 200000>, /* 50 Mbps */ + <100 512 25000 200000>, /* 200 Mbps */ + <100 512 100000 200000>; /* 800 Mbps */ + }; + + audio_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&audio_mem>; + }; + + adsp_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,msm-core@fc4b8000 { + compatible = "qcom,apss-core-ea"; + reg = <0xfc4b8000 0x1000>; + qcom,low-hyst-temp = <10>; + qcom,high-hyst-temp = <5>; + qcom,polling-interval = <50>; + + qcom,core-mapping { + qcom,cpu0-chars { + qcom,sensor = <&sensor_information7>; + qcom,cpu-name = <&CPU0>; + }; + + qcom,cpu1-chars { + qcom,sensor = <&sensor_information8>; + qcom,cpu-name = <&CPU1>; + }; + + qcom,cpu2-chars { + qcom,sensor = <&sensor_information9>; + qcom,cpu-name = <&CPU2>; + }; + + qcom,cpu3-chars { + qcom,sensor = <&sensor_information10>; + qcom,cpu-name = <&CPU3>; + }; + + qcom,cpu4-chars { + qcom,sensor = <&sensor_information13>; + qcom,cpu-name = <&CPU4>; + }; + + qcom,cpu5-chars { + qcom,sensor = <&sensor_information14>; + qcom,cpu-name = <&CPU5>; + }; + + qcom,cpu6-chars { + qcom,sensor = <&sensor_information15>; + qcom,cpu-name = <&CPU6>; + }; + + qcom,cpu7-chars { + qcom,sensor = <&sensor_information6>; + qcom,cpu-name = <&CPU7>; + }; + }; + }; + + qcom,system-health-monitor { + compatible = "qcom,system-health-monitor"; + + qcom,system-health-monitor-modem { + qcom,subsys-name = "msm_mpss"; + qcom,ssrestart-string = "modem"; + }; + }; + + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,itlb_dump100 { + qcom,dump-node = <&L1_itlb_100>; + qcom,dump-id = <0x24>; + }; + qcom,itlb_dump101 { + qcom,dump-node = <&L1_itlb_101>; + qcom,dump-id = <0x25>; + }; + qcom,itlb_dump102 { + qcom,dump-node = <&L1_itlb_102>; + qcom,dump-id = <0x26>; + }; + qcom,itlb_dump103 { + qcom,dump-node = <&L1_itlb_103>; + qcom,dump-id = <0x27>; + }; + qcom,dtlb_dump100 { + qcom,dump-node = <&L1_dtlb_100>; + qcom,dump-id = <0x44>; + }; + qcom,dtlb_dump101 { + qcom,dump-node = <&L1_dtlb_101>; + qcom,dump-id = <0x45>; + }; + qcom,dtlb_dump102 { + qcom,dump-node = <&L1_dtlb_102>; + qcom,dump-id = <0x46>; + }; + qcom,dtlb_dump103 { + qcom,dump-node = <&L1_dtlb_103>; + qcom,dump-id = <0x47>; + }; + qcom,l2_tlb_dump0 { + qcom,dump-node = <&L2_tlb_0>; + qcom,dump-id = <0x120>; + }; + qcom,l2_tlb_dump100 { + qcom,dump-node = <&L2_tlb_1>; + qcom,dump-id = <0x121>; + }; + qcom,l2_dump0 { + qcom,dump-node = <&L2_0>; /* L2 cache dump for A53 cluster */ + qcom,dump-id = <0xC0>; + }; + qcom,l2_dump1 { + qcom,dump-node = <&L2_1>; /* L2 cache dumo for A57 cluster */ + qcom,dump-id = <0xC1>; + }; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + + qcom,avtimer@fe09c000 { + compatible = "qcom,avtimer"; + reg = <0xFE09C00C 0x4>, + <0xFE09C010 0x4>; + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr"; + qcom,clk_div = <27>; + }; + + cci@f9100000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9100000 0x1000>; + ranges = <0x0 0xf9100000 0x10000>; + hw-version = <8>; + + pmu@a000 { + compatible = "arm,cci-400-pmu"; + reg = <0x9000 0x5000>; + interrupts = <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>; + }; + + }; +}; + +&gdsc_usb30 { + reg = <0xfc4003c4 0x4>; + status = "ok"; +}; + +&gdsc_pcie_0 { + status = "ok"; +}; + +&gdsc_pcie_1 { + status = "ok"; +}; + +&gdsc_ufs { + status = "ok"; +}; + +&gdsc_venus { + clock-names = "ocmem_clk", "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + status = "ok"; +}; + +&gdsc_venus_core0 { + qcom,support-hw-trigger; + clock-names = "core0_clk"; + clocks = <&clock_mmss clk_venus0_core0_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core1 { + qcom,support-hw-trigger; + clock-names = "core1_clk"; + clocks = <&clock_mmss clk_venus0_core1_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core2 { + qcom,support-hw-trigger; + clock-names = "core2_clk"; + clocks = <&clock_mmss clk_venus0_core2_vcodec_clk>; + status = "ok"; +}; + +&gdsc_mdss { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_mdp_clk>; + status = "ok"; +}; + +&gdsc_camss_top { + clock-names = "csi0_clk", "csi1_clk", "bus_clk"; + clocks = <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>; + status = "ok"; +}; + +&gdsc_jpeg { + clock-names = "bus_clk", "core0_clk", "core1_clk", "core2_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg2_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_vfe { + clock-names = "bus_clk"; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_cpp { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_fd { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_core_clk>; + status = "ok"; +}; + +&gdsc_oxili_cx { + status = "ok"; +}; + +&gdsc_oxili_gx { + clock-names = "core_clk"; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>; + status = "ok"; + parent-supply = <&pmi8994_s2_corner>; +}; + +#include "msm-pm8994-rpm-regulator.dtsi" +#include "msm-pm8994.dtsi" +#include "msm-pmi8994.dtsi" +#include "msm8994-regulator.dtsi" +#include "msm8994-ion.dtsi" +#include "msm8994-iommu.dtsi" +#include "msm8994-iommu-domains.dtsi" +#include "msm8994-camera.dtsi" +#include "msm8994-gpu.dtsi" +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi0-video.dtsi" +#include "dsi-panel-sim-dualmipi1-video.dtsi" +#include "dsi-panel-sim-cmd.dtsi" +#include "dsi-panel-sim-dualmipi0-cmd.dtsi" +#include "dsi-panel-sim-dualmipi1-cmd.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_13/skeleton64.dtsi b/arch/arm64/boot/dts/14049_HW_13/skeleton64.dtsi new file mode 100755 index 0000000000000..1f8ba28132c4a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_13/skeleton64.dtsi @@ -0,0 +1,15 @@ +/* + * Skeleton device tree in the 64 bits version; the bare minimum + * needed to boot; just include and add a compatible value. The + * bootloader will typically populate the memory node. + */ + +/ { + #address-cells = <2>; + #size-cells = <2>; + cpus { }; + soc { }; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0 0 0>; }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/Makefile b/arch/arm64/boot/dts/14049_HW_14/Makefile new file mode 100755 index 0000000000000..7a683387085d4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/Makefile @@ -0,0 +1,22 @@ +ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_MSM8994) += msm8994-v1-mtp_14049_HW_14.dtb \ + msm8994-v2.0-mtp_14049_HW_14.dtb \ + msm8994-v2.1-mtp_14049_HW_14.dtb + +DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES)) +ifneq ($(DTB_NAMES),) +DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) +else +DTB_LIST := $(dtb-y) +endif + +targets += dtbs +targets += $(addprefix ../, $(DTB_LIST)) +endif + +$(obj)/../%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + +dtbs: $(addprefix $(obj)/../,$(DTB_LIST)) + +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3000mah.dtsi new file mode 100755 index 0000000000000..dc23e181f64d3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3000mah.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3000mah { + qcom,max-voltage-uv = <4320000>; /* yangfangbiao@oneplus.cn, 2015/03/15 Set max voltage 4.32v */ + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3000mah"; + qcom,checksum = <0xF99F>; + qcom,fg-profile-data = [ + EC 83 39 7D + 10 81 04 77 + 23 83 9A 72 + AE 52 20 84 + FC 81 51 93 + FB AD D2 B0 + 5B 12 E5 82 + 09 78 90 75 + A7 70 0C 83 + 1A 80 71 8D + 48 89 08 82 + D4 99 74 BC + A2 C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 45 31 A4 44 + 6E 3B 00 00 + AD 3D 24 36 + A9 46 00 00 + 00 00 00 00 + 00 00 00 00 + E7 6A 05 6A + 8E 75 F9 80 + 5E 76 DA 68 + 45 74 54 81 + 10 75 13 60 + 61 7E 38 A1 + 33 DB 62 1A + 64 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3020mah.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3020mah.dtsi new file mode 100755 index 0000000000000..9a2ce4badf33e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata-itech-3020mah.dtsi @@ -0,0 +1,53 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,itech-3020mah { + qcom,max-voltage-uv = <4350000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <100>; + qcom,battery-type = "itech_3020mah"; + qcom,fg-profile-data = [ + E8 83 0C 7D + E9 80 B2 76 + 20 83 40 73 + D7 6C 59 7E + FB 81 58 93 + 0D AE 02 B1 + 5B 12 D7 82 + 86 78 F3 76 + 4A 71 0C 83 + 1B 80 73 8D + 49 89 07 82 + D8 99 79 BC + AA C8 7C 17 + F8 0B F4 5B + CE 6E 71 FD + 09 2E 79 44 + 52 43 00 00 + DE 3D 2A 37 + D3 46 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 6B B7 69 + DD 6C 83 83 + 42 76 CA 68 + 78 75 EF 80 + D4 74 56 5B + 00 00 00 00 + 0A A5 5A D2 + 54 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata-mtp-3000mah.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata-mtp-3000mah.dtsi new file mode 100755 index 0000000000000..198fbea2ef0af --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata-mtp-3000mah.dtsi @@ -0,0 +1,118 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,mtp-3000mah { + qcom,fcc-mah = <3000>; + qcom,default-rbatt-mohm = <113>; + qcom,max-voltage-uv = <4200000>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <200000>; + qcom,batt-id-kohm = <300>; + qcom,battery-type = "mtp_3000mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <3030 3033 3037 3035 3031>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4191 4188 4183 4179 4174>, + <4106 4125 4127 4125 4121>, + <4046 4082 4082 4080 4077>, + <3966 4038 4044 4040 4035>, + <3922 3983 3994 3998 3997>, + <3886 3949 3966 3966 3962>, + <3856 3908 3937 3935 3931>, + <3832 3875 3908 3907 3903>, + <3814 3847 3874 3878 3875>, + <3799 3826 3831 3832 3830>, + <3787 3807 3811 3811 3809>, + <3775 3793 3795 3795 3793>, + <3764 3782 3783 3783 3781>, + <3752 3775 3773 3772 3769>, + <3739 3768 3766 3762 3755>, + <3725 3756 3756 3747 3733>, + <3710 3732 3734 3725 3711>, + <3696 3707 3705 3697 3684>, + <3681 3695 3686 3678 3667>, + <3667 3690 3684 3676 3665>, + <3658 3688 3683 3675 3664>, + <3646 3685 3681 3674 3663>, + <3631 3682 3679 3673 3660>, + <3612 3677 3676 3669 3655>, + <3589 3667 3666 3660 3639>, + <3560 3643 3636 3630 3599>, + <3523 3600 3586 3581 3546>, + <3474 3537 3518 3516 3477>, + <3394 3446 3425 3427 3379>, + <3257 3306 3273 3283 3213>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>; + qcom,lut-data = <1025 208 100 85 80>, + <1025 208 100 85 80>, + <1032 225 103 87 81>, + <959 249 107 91 82>, + <954 249 109 92 84>, + <953 255 117 94 84>, + <957 230 123 98 87>, + <968 216 134 102 91>, + <983 212 138 112 95>, + <1002 213 103 89 82>, + <1030 215 100 86 81>, + <1066 219 101 89 83>, + <1115 224 104 92 85>, + <1182 234 106 94 86>, + <1263 246 108 92 84>, + <1357 257 107 87 81>, + <1464 261 102 85 80>, + <1564 256 101 84 80>, + <1637 268 100 84 80>, + <1580 276 102 87 81>, + <1617 285 104 87 82>, + <1670 298 107 91 82>, + <1725 315 108 92 83>, + <1785 338 112 92 83>, + <1850 361 111 91 82>, + <1921 378 108 89 84>, + <2000 394 112 92 87>, + <2119 430 121 99 94>, + <2795 497 144 114 104>, + <8769 1035 672 322 234>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <3030 3033 3037>, + <1898 2943 2960>, + <1184 2855 2948>, + <209 2464 2921>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata-palladium.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata-palladium.dtsi new file mode 100755 index 0000000000000..4c44351892565 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata-palladium.dtsi @@ -0,0 +1,121 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,palladium-batterydata { + qcom,fcc-mah = <1500>; + qcom,default-rbatt-mohm = <210>; + qcom,rbatt-capacitive-mohm = <50>; + qcom,flat-ocv-threshold-uv = <3800000>; + qcom,max-voltage-uv = <4200000>; + qcom,v-cutoff-uv = <3400000>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <75>; + qcom,battery-type = "palladium_1500mah"; + + qcom,fcc-temp-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-data = <1467 1470 1473 1473 1470>; + }; + + qcom,pc-temp-ocv-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <4175 4173 4167 4162 4157>, + <4097 4111 4112 4110 4107>, + <4039 4075 4072 4068 4064>, + <3963 4017 4025 4026 4025>, + <3920 3969 3984 3989 3988>, + <3887 3932 3957 3958 3955>, + <3856 3898 3929 3928 3925>, + <3830 3868 3900 3901 3898>, + <3808 3843 3858 3863 3862>, + <3793 3821 3827 3827 3827>, + <3779 3803 3807 3808 3807>, + <3768 3788 3792 3793 3792>, + <3757 3779 3780 3780 3779>, + <3746 3771 3772 3768 3768>, + <3734 3762 3765 3759 3749>, + <3722 3747 3753 3744 3730>, + <3707 3721 3731 3722 3709>, + <3693 3705 3704 3696 3683>, + <3678 3698 3687 3678 3667>, + <3664 3693 3683 3676 3665>, + <3656 3690 3682 3675 3664>, + <3646 3687 3681 3674 3662>, + <3634 3683 3680 3672 3661>, + <3618 3677 3676 3668 3656>, + <3599 3667 3667 3655 3639>, + <3573 3645 3638 3623 3603>, + <3541 3607 3591 3575 3554>, + <3496 3550 3528 3511 3490>, + <3428 3469 3445 3423 3400>, + <3312 3342 3308 3280 3250>, + <3000 3000 3000 3000 3000>; + }; + + qcom,rbatt-sf-lut { + qcom,lut-col-legend = <(-20) 0 25 40 60>; + qcom,lut-row-legend = <100 95 90 85 80>, + <75 70 65 60 55>, + <50 45 40 35 30>, + <25 20 16 13 11>, + <10 9 8 7 6>, + <5 4 3 2 1>, + <0>; + qcom,lut-data = <909 216 100 85 84>, + <859 238 106 88 86>, + <860 237 105 88 86>, + <808 239 107 90 88>, + <801 234 111 94 90>, + <801 230 118 97 92>, + <801 224 123 100 95>, + <807 221 128 106 99>, + <818 221 111 101 97>, + <841 225 101 88 87>, + <870 229 101 88 87>, + <906 235 103 91 90>, + <950 243 106 93 93>, + <998 253 110 93 96>, + <1051 263 113 94 90>, + <1116 272 113 91 88>, + <1200 275 111 91 88>, + <1312 298 108 90 87>, + <1430 329 104 88 87>, + <1484 351 107 91 89>, + <1446 345 110 93 90>, + <1398 344 112 94 90>, + <1466 358 115 96 91>, + <1490 357 117 96 90>, + <1589 365 117 94 89>, + <1828 379 111 91 88>, + <2151 399 111 93 91>, + <2621 436 117 98 95>, + <3404 496 130 106 100>, + <8212 616 150 1906 134>, + <135251 124940 59087 49820 29672>; + }; + + qcom,ibat-acc-lut { + qcom,lut-col-legend = <(-20) 0 25>; + qcom,lut-row-legend = <0 250 500 1000>; + qcom,lut-data = <1470 1470 1473>, + <601 1406 1430>, + <89 1247 1414>, + <8 764 1338>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata-unkown-3300mah.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata-unkown-3300mah.dtsi new file mode 100755 index 0000000000000..4ee01d90bd24d --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata-unkown-3300mah.dtsi @@ -0,0 +1,50 @@ +qcom,oneplus_default_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "Unknown Battery"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_ATL_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_ATL_3300mAh.dtsi new file mode 100755 index 0000000000000..08924c2b14994 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_ATL_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <1>; + qcom,battery-beta = <0>; + qcom,battery-type = "ATL"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_SDI_3300mAh.dtsi b/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_SDI_3300mAh.dtsi new file mode 100755 index 0000000000000..8756ab9405b54 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/batterydata_oneplus_SDI_3300mAh.dtsi @@ -0,0 +1,49 @@ +qcom,oneplus_SDI_3200mah { + qcom,max-voltage-uv = <4320000>; + qcom,nom-batt-capacity-mah = <3300>; + qcom,v-cutoff-uv = <3600000>; + qcom,chg-term-ua = <150000>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <0>; + qcom,battery-type = "SDI"; + qcom,rslow-comp-along-soc-c1-ch-milli = <2464>; + qcom,rslow-comp-along-soc-c2-ch-milli = <2876>; + qcom,rs-to-rslow-charge-fix-milli = <883>; + qcom,rslow-comp-ch-fix-th-milli = <600>; + qcom,checksum = <0xA6ED>; + qcom,gui-version = "PMI8994GUI - 2.1.6.2"; + qcom,fg-profile-data = [ + D2 83 01 7C + 0B 80 18 75 + 48 83 84 60 + EB 80 F8 8C + 21 82 70 99 + 31 BC 6F C8 + 55 0E E4 83 + 17 7C D7 7B + 9C 74 40 83 + 05 73 E1 77 + 73 66 49 82 + 38 99 2D BC + 83 C8 57 0D + DC 0C DA 59 + 08 6C 71 FD + 3C 3E B8 3D + 7B 40 00 00 + 26 4C 36 3A + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 06 70 BF 6A + 61 64 41 81 + 3F 75 B8 68 + 22 60 26 81 + 95 74 7E 63 + 99 77 BE B0 + 1E 39 69 8E + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 00 + ]; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jd35695-1080p-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jd35695-1080p-cmd.dtsi new file mode 100755 index 0000000000000..6d532bdc06403 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jd35695-1080p-cmd.dtsi @@ -0,0 +1,211 @@ +/************************************************************ + * Copyright (c) 2013-2013 OPPO Mobile communication Corp.ltd., + * VENDOR_EDIT + * Description: device tree for jdi cmd panel. + * Version : 1.0 + * Date : 2013-12-12 + * Author : yangxinqin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/*--------------------------------------------------------------------------- + * This file is autogenerated file using gcdb parser. Please do not edit it. + * Update input XML file to add a new entry or update variable in this file + * VERSION = "1.0" + *---------------------------------------------------------------------------*/ +&mdss_mdp { +dsi_jd35695_1080_cmd: qcom,mdss_dsi_jd35695_1080p_cmd { + compatible = "qcom,mdss-dsi-panel"; + status = "ok"; + qcom,cont-splash-enabled; + qcom,mdss-dsi-panel-name = "jd35695 1080p cmd mode dsi panel"; + qcom,mdss-dsi-panel-manufacture = "JDI"; + qcom,mdss-dsi-panel-version = "JD35695"; + qcom,mdss-dsi-backlight-version= "PMI8994"; + qcom,mdss-dsi-backlight-manufacture = "Qualcomm"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <100>; + qcom,mdss-dsi-h-back-porch = <82>; + qcom,mdss-dsi-h-pulse-width = <8>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <7>; + qcom,mdss-dsi-v-front-porch = <3>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0x0000ff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 39 01 00 00 00 00 05 2a 00 00 04 37 + 39 01 00 00 00 00 05 2b 00 00 07 7f + + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF E0 + 15 01 00 00 00 00 02 B5 86 + 15 01 00 00 00 00 02 B6 77 + 15 01 00 00 00 00 02 B8 AD + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 FF 10 + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + + 05 01 00 00 6E 00 02 11 00 + 05 01 00 00 2D 00 02 29 00 + + ]; + qcom,mdss-dsi-off-command = [ + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 53 00 + 05 01 00 00 64 00 02 28 00 + 05 01 00 00 64 00 02 10 00]; + + qcom,mdss-dsi-color-test-on-command= + [ + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 01 + 15 01 00 00 00 00 02 FF 20 + 15 01 00 00 00 00 02 67 4D]; + + + qcom,mdss-dsi-color-test-off-command = + [ + 15 01 00 00 00 00 02 FF 24 + 15 01 00 00 00 00 02 EC 00 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 03 44 05 00 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 32 00 02 29 00]; + + qcom,mdss-dsi-cabc-off-command = [15 01 00 00 10 00 02 55 00 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-ui-command = [15 01 00 00 10 00 02 55 01 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-still-image-command = [15 01 00 00 10 00 02 55 02 + 05 01 00 00 10 00 02 29 00]; + qcom,mdss-dsi-cabc-video-command = [15 01 00 00 10 00 02 55 03 + 05 01 00 00 10 00 02 29 00]; + + qcom,mdss-dsi-on-command_shoushi = [ + + 15 01 00 00 00 00 02 36 03 //add for lcd rotater 180 + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 2C + 15 01 00 00 00 00 02 55 02 + + 15 01 00 00 00 00 02 FF 23 + 15 01 00 00 00 00 02 FB 01 + 15 01 00 00 00 00 02 05 24 + 15 01 00 00 00 00 02 01 84 + 15 01 00 00 00 00 02 FF 10 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 60 00 02 29 00 + + ]; + qcom,mdss-dsi-color-test-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-color-test-off-command-state = "dsi_lp_mode"; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + + + + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + + + + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + //qcom,mdss-dsi-init-delay-us=<50000>; + /**************************************************************************/ + // qcom,esd-check-enabled; + // qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08]; + // qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode"; + // qcom,mdss-dsi-panel-status-check-mode = "reg_read_jd35695"; + // qcom,mdss-dsi-panel-status-read-length = <8>; + // qcom,mdss-dsi-panel-max-error-count = <2>; + // qcom,mdss-dsi-panel-status-value = <0x9c 0x00 0x00 0x02 0x40 0x80 0x00 0x00>; + /******************************************************************************/ + // qcom,mdss-dsi-dma-trigger = "trigger_sw"; + // qcom,mdss-dsi-mdp-trigger = "trigger_sw"; + + + + // qcom,mdss-tear-check-frame-rate=<6000>; + //qcom,mdss-tear-check-sync-cfg-height = <1932>; /* Height + VBP + VFP + VSW */ + //qcom,mdss-tear-check-sync-init-val= <1920>; /* Height */ + //qcom,mdss-tear-check-sync-threshold-start = <4>; + //qcom,mdss-tear-check-sync-threshold-continue = <4>; + //qcom,mdss-tear-check-start-pos= <1920>; /* Height */ + //qcom,mdss-tear-check-rd-ptr-trigger-intr= <1921>; /* Height + 1 */ + + qcom,mdss-pan-physical-width-dimension = <70>; + qcom,mdss-pan-physical-height-dimension = <127>; + + + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 14>, <0 5>, <1 20>; + + }; +}; + + diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jdi-1080p-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jdi-1080p-video.dtsi new file mode 100755 index 0000000000000..7e4e9ceeeaab8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-jdi-1080p-video.dtsi @@ -0,0 +1,97 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_jdi_1080_vid: qcom,mdss_dsi_jdi_1080p_video { + qcom,mdss-dsi-panel-name = "jdi 1080p video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [ + 23 01 00 00 00 00 02 FF 10 + 15 01 00 00 10 00 02 35 00 + 15 01 00 00 10 00 02 bb 03 + //29 01 00 00 00 00 03 44 05 00 + 23 01 00 00 00 00 02 FF E0 + 23 01 00 00 00 00 02 B5 86 + 23 01 00 00 00 00 02 B6 77 + 23 01 00 00 00 00 02 B8 AD + 23 01 00 00 00 00 02 FB 01 + 23 01 00 00 00 00 02 FF 10 + +/************************************************************** + //15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + self test mode + 05 01 00 00 32 00 02 28 00 + 05 01 00 00 32 00 02 10 00 + 23 01 00 00 00 00 02 FF 24 + 23 01 00 00 00 00 02 EC 01 + 23 01 00 00 00 00 02 FF 20 + 23 01 00 00 00 00 02 67 4D +*************************************************************/ + 15 01 00 00 10 00 02 36 03 //add for lcd rotater 180 + 23 01 00 00 00 00 02 FF 23 + 23 01 00 00 00 00 02 08 03 + 15 01 00 00 00 00 02 FF 10 + 15 01 00 00 00 00 02 51 FF + 15 01 00 00 00 00 02 53 24 + + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 78 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 79 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [E7 43 37 00 60 6C 39 45 5b 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x20>; + qcom,mdss-dsi-t-clk-pre = <0x3e>; + + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>;/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-init-delay-us=<50000>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 50>; + qcom,mdss-pan-physical-width-dimension = <61>; + qcom,mdss-pan-physical-height-dimension = <110>; + }; +}; + diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi new file mode 100755 index 0000000000000..8ae76e72ddb7a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi0-wqxga-video.dtsi @@ -0,0 +1,68 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_0: qcom,mdss_dsi_sharp_wqxga_video_0 { + qcom,mdss-dsi-panel-name = "Dual 0 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <50>; + qcom,mdss-dsi-bl-pmic-bank-select = <2>; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi new file mode 100755 index 0000000000000..a9337b1866188 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sharp-dualmipi1-wqxga-video.dtsi @@ -0,0 +1,66 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sharp_video_1: qcom,mdss_dsi_sharp_wqxga_video_1 { + qcom,mdss-dsi-panel-name = "Dual 1 SHARP video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <800>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <76>; + qcom,mdss-dsi-h-back-porch = <32>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <11>; + qcom,mdss-dsi-v-front-porch = <2>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [05 01 00 00 a0 00 02 11 00 + 05 01 00 00 02 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00 + 05 01 00 00 a0 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-panel-timings = [e2 36 24 00 66 6a 28 38 2a 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x02>; + qcom,mdss-dsi-t-clk-pre = <0x2a>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 2>, <0 5>, <1 120>; + qcom,mdss-pan-physical-width-dimension = <83>; + qcom,mdss-pan-physical-height-dimension = <133>; + qcom,mdss-dsi-min-refresh-rate = <53>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-cmd.dtsi new file mode 100755 index 0000000000000..694973e4ff43f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-cmd.dtsi @@ -0,0 +1,94 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_cmd: qcom,mdss_dsi_sim_cmd{ + qcom,mdss-dsi-panel-name = "Simulator cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <16>; + qcom,mdss-dsi-v-front-porch = <4>; + qcom,mdss-dsi-v-pulse-width = <1>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-cmd.dtsi new file mode 100755 index 0000000000000..74986f9b4e5f3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-cmd.dtsi @@ -0,0 +1,95 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_0: qcom,mdss_dsi_sim_cmd_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-video.dtsi new file mode 100755 index 0000000000000..13cd57f321c82 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi0-video.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_0: qcom,mdss_dsi_sim_video_0 { + qcom,mdss-dsi-panel-name = "Sim dual 0 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-cmd.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-cmd.dtsi new file mode 100755 index 0000000000000..f73e47bd504b5 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-cmd.dtsi @@ -0,0 +1,96 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_cmd_1: qcom,mdss_dsi_sim_cmd_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 cmd mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,cmd-sync-wait-broadcast; + qcom,cmd-sync-wait-trigger; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hor-line-idle = <0 40 256>, + <40 120 128>, + <120 240 64>; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-on-command = [29 01 00 00 00 00 02 b0 03 + 05 01 00 00 0a 00 01 00 + /* Soft reset, wait 10ms */ + 15 01 00 00 0a 00 02 3a 77 + /* Set Pixel format (24 bpp) */ + 39 01 00 00 0a 00 05 2a 00 00 04 ff + /* Set Column address */ + 39 01 00 00 0a 00 05 2b 00 00 05 9f + /* Set page address */ + 15 01 00 00 0a 00 02 35 00 + /* Set tear on */ + 39 01 00 00 0a 00 03 44 00 00 + /* Set tear scan line */ + 15 01 00 00 0a 00 02 51 ff + /* write display brightness */ + 15 01 00 00 0a 00 02 53 24 + /* write control brightness */ + 15 01 00 00 0a 00 02 55 00 + /* CABC brightness */ + 05 01 00 00 78 00 01 11 + /* exit sleep mode, wait 120ms */ + 05 01 00 00 10 00 01 29]; + /* Set display on, wait 16ms */ + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-video.dtsi new file mode 100755 index 0000000000000..882b2abdce34f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-dualmipi1-video.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_sim_vid_1: qcom,mdss_dsi_sim_video_1 { + qcom,mdss-dsi-panel-name = "Sim dual 1 video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi1>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_2"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1280>; + qcom,mdss-dsi-panel-height = <1440>; + qcom,mdss-dsi-h-front-porch = <120>; + qcom,mdss-dsi-h-back-porch = <44>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <8>; + qcom,mdss-dsi-v-pulse-width = <4>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-broadcast-mode; + qcom,mdss-dsi-panel-timings = [cd 32 22 00 60 64 26 34 29 03 + 04 00]; + qcom,mdss-dsi-t-clk-post = <0x03>; + qcom,mdss-dsi-t-clk-pre = <0x27>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-video.dtsi b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-video.dtsi new file mode 100755 index 0000000000000..bd9322bac2e74 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/dsi-panel-sim-video.dtsi @@ -0,0 +1,58 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_sim_vid: qcom,mdss_dsi_sim_video { + qcom,mdss-dsi-panel-name = "Simulator video mode dsi panel"; + qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-destination = "display_1"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <640>; + qcom,mdss-dsi-panel-height = <480>; + qcom,mdss-dsi-h-front-porch = <6>; + qcom,mdss-dsi-h-back-porch = <6>; + qcom,mdss-dsi-h-pulse-width = <2>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <6>; + qcom,mdss-dsi-v-front-porch = <6>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [32 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-off-command = [22 01 00 00 00 00 02 00 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [00 00 00 00 00 00 00 00 00 00 00 00]; + qcom,mdss-dsi-t-clk-post = <0x04>; + qcom,mdss-dsi-t-clk-pre = <0x1b>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-reset-sequence = <1 0>, <0 0>, <1 0>; + qcom,panel-ack-disabled; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-gdsc-8916.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-gdsc-8916.dtsi new file mode 100755 index 0000000000000..07e1e33fd4482 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-gdsc-8916.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@184c018 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0x184c018 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@184d078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0x184d078 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@185701c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0x185701c 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@1858034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0x1858034 0x4>; + status = "disabled"; + }; + + gdsc_vfe1: qcom,gdsc@185806c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe1"; + reg = <0x185806c 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@1858078 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0x1858078 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@185901c { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0x185901c 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@184c028 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0x184c028 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@184c030 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0x184c030 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-gdsc.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-gdsc.dtsi new file mode 100755 index 0000000000000..9a1f32eb0c7aa --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-gdsc.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gdsc_venus: qcom,gdsc@fd8c1024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus"; + reg = <0xfd8c1024 0x4>; + status = "disabled"; + }; + + gdsc_venus_core0: qcom,gdsc@fd8c1040 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core0"; + reg = <0xfd8c1040 0x4>; + status = "disabled"; + }; + + gdsc_venus_core1: qcom,gdsc@fd8c1044 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core1"; + reg = <0xfd8c1044 0x4>; + status = "disabled"; + }; + + gdsc_venus_core2: qcom,gdsc@fd8c1050 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_venus_core2"; + reg = <0xfd8c1050 0x4>; + status = "disabled"; + }; + + gdsc_vpu: qcom,gdsc@fd8c1404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vpu"; + reg = <0xfd8c1404 0x4>; + status = "disabled"; + }; + + gdsc_camss_top: qcom,gdsc@fd8c34a0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_camss_top"; + reg = <0xfd8c34a0 0x4>; + status = "disabled"; + }; + + gdsc_mdss: qcom,gdsc@fd8c2304 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_mdss"; + reg = <0xfd8c2304 0x4>; + status = "disabled"; + }; + + gdsc_jpeg: qcom,gdsc@fd8c35a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_jpeg"; + reg = <0xfd8c35a4 0x4>; + status = "disabled"; + }; + + gdsc_vfe: qcom,gdsc@fd8c36a4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vfe"; + reg = <0xfd8c36a4 0x4>; + status = "disabled"; + }; + + gdsc_cpp: qcom,gdsc@fd8c36d4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_cpp"; + reg = <0xfd8c36d4 0x4>; + status = "disabled"; + }; + + gdsc_oxili_gx: qcom,gdsc@fd8c4024 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_gx"; + reg = <0xfd8c4024 0x4>; + status = "disabled"; + }; + + gdsc_oxili_cx: qcom,gdsc@fd8c4034 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_oxili_cx"; + reg = <0xfd8c4034 0x4>; + status = "disabled"; + }; + + gdsc_usb_hsic: qcom,gdsc@fc400404 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb_hsic"; + reg = <0xfc400404 0x4>; + status = "disabled"; + }; + + gdsc_pcie: qcom,gdsc@0xfc401e18 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie"; + reg = <0xfc401e18 0x4>; + status = "disabled"; + }; + + gdsc_pcie_0: qcom,gdsc@fc401ac4 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_0"; + reg = <0xfc401ac4 0x4>; + status = "disabled"; + }; + + gdsc_pcie_1: qcom,gdsc@fc401b44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_pcie_1"; + reg = <0xfc401b44 0x4>; + status = "disabled"; + }; + + gdsc_usb30: qcom,gdsc@fc401e84 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30"; + reg = <0xfc401e84 0x4>; + status = "disabled"; + }; + + gdsc_usb30_sec: qcom,gdsc@fc401ec0 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_usb30_sec"; + reg = <0xfc401ec0 0x4>; + status = "disabled"; + }; + + gdsc_vcap: qcom,gdsc@fd8c1804 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_vcap"; + reg = <0xfd8c1804 0x4>; + status = "disabled"; + }; + + gdsc_bcss: qcom,gdsc@fc744128 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_bcss"; + reg = <0xfc744128 0x4>; + status = "disabled"; + }; + + gdsc_ufs: qcom,gdsc@fc401d44 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_ufs"; + reg = <0xfc401d44 0x4>; + status = "disabled"; + }; + + gdsc_fd: qcom,gdsc@fd8c3b64 { + compatible = "qcom,gdsc"; + regulator-name = "gdsc_fd"; + reg = <0xfd8c3b64 0x4>; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v0.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v0.dtsi new file mode 100755 index 0000000000000..88919353600b8 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v0.dtsi @@ -0,0 +1,328 @@ +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + lpass_iommu: qcom,iommu@fd000000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd000000 0x10000>; + interrupts = <0 248 0>; + qcom,glb-offset = <0xF000>; + label = "lpass_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "lpass_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <11 512 0 0>, + <11 512 0 1000>; + qcom,msm-enable-remote-spinlock; + status = "disabled"; + + lpass_q6_fw: qcom,iommu-ctx@fd000000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd000000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <0 15>; + label = "q6_fw"; + }; + + lpass_audio_shared: qcom,iommu-ctx@fd001000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd001000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <1>; + label = "audio_shared"; + }; + + lpass_video_shared: qcom,iommu-ctx@fd002000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd002000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <2>; + label = "video_shared"; + }; + + lpass_q6_spare: qcom,iommu-ctx@fd003000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd003000 0x1000>; + interrupts = <0 250 0>; + qcom,iommu-ctx-mids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare"; + }; + }; + + copss_iommu: qcom,iommu@fd010000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd010000 0x10000>; + interrupts = <0 252 0>; + qcom,glb-offset = <0xF000>; + label = "copss_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + + status = "disabled"; + + qcom,iommu-ctx@fd010000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd010000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <0>; + label = "copss_0"; + }; + + qcom,iommu-ctx@fd011000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd011000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <1>; + label = "copss_1"; + }; + + qcom,iommu-ctx@fd012000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd012000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <2>; + label = "copss_2"; + }; + + qcom,iommu-ctx@fd013000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd013000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <3>; + label = "copss_3"; + }; + + qcom,iommu-ctx@fd014000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd014000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <4>; + label = "copss_4"; + }; + + qcom,iommu-ctx@fd015000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd015000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <5>; + label = "copss_5"; + }; + + qcom,iommu-ctx@fd016000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd016000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <6>; + label = "copss_6"; + }; + + qcom,iommu-ctx@fd017000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd017000 0x1000>; + interrupts = <0 254 0>; + qcom,iommu-ctx-mids = <7>; + label = "copss_7"; + }; + }; + + mdpe_iommu: qcom,iommu@fd860000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd860000 0x10000>; + interrupts = <0 245 0>; + qcom,glb-offset = <0xF000>; + label = "mdpe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdpe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <92 512 0 0>, + <92 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd860000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd860000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <0 1 3>; + label = "mdpe_0"; + }; + + qcom,iommu-ctx@fd861000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd861000 0x1000>; + interrupts = <0 247 0>; + qcom,iommu-ctx-mids = <2>; + label = "mdpe_1"; + }; + }; + + mdps_iommu: qcom,iommu@fd870000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd870000 0x10000>; + interrupts = <0 73 0>; + qcom,glb-offset = <0xF000>; + label = "mdps_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "mdps_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd870000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd870000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <0>; + label = "mdps_0"; + }; + + qcom,iommu-ctx@fd871000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd871000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-mids = <1>; + label = "mdps_1"; + }; + }; + + gfx_iommu: qcom,iommu@fd880000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd880000 0x10000>; + interrupts = <0 38 0>; + qcom,glb-offset = <0xF000>; + qcom,needs-alt-core-clk; + label = "gfx_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "gfx_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd880000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd880000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 + 14 15>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fd881000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd881000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <16 17 18 19 20 21 22 23 24 25 + 26 27 28 29 30 31>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fd882000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd882000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-mids = <>; + label = "gfx3d_spare"; + }; + }; + + vfe_iommu: qcom,iommu@fd890000 { + compatible = "qcom,msm-smmu-v0"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd890000 0x10000>; + interrupts = <0 62 0>; + qcom,glb-offset = <0xF000>; + label = "vfe_iommu"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <4>; + qcom,iommu-pmu-event-classes = <0x08 + 0x09 + 0x10 + 0x12 + 0x80>; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-ctx@fd890000 { + compatible = "qcom,msm-smmu-v0-ctx"; + reg = <0xfd890000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-mids = <0 1 2 3 4 5 6 7 8 9>; + label = "vfe0"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v1.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v1.dtsi new file mode 100755 index 0000000000000..911d83c109235 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v1.dtsi @@ -0,0 +1,1513 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + jpeg_iommu: qcom,iommu@fda64000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda64000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 67 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "jpeg_iommu"; + status = "disabled"; + qcom,msm-bus,name = "jpeg_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <62 512 0 0>, + <62 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x0000ffff + 0x0 + 0x4 + 0x4 + 0x0 + 0x0 + 0x10 + 0x50 + 0x0 + 0x10 + 0x20 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@fda6d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <1>; + label = "jpeg_enc1"; + }; + + qcom,iommu-ctx@fda6e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6e000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <2>; + label = "jpeg_dec"; + }; + }; + + mdp_iommu: qcom,iommu@fd928000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd928000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000034 + 0x00000044 + 0x0 + 0x34 + 0x74 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd930000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd930000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd931000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd931000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd932000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd932000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; + + venus_iommu: qcom,iommu@fdc84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdc84000 0x10000 + 0xfdce0004 0x4>; + reg-names = "iommu_base", "clk_base"; + interrupts = <0 45 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <0>; + qcom,needs-alt-core-clk; + label = "venus_iommu"; + qcom,msm-bus,name = "venus_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2024 + 0x2028 + 0x202c + 0x2030 + 0x2034 + 0x2038>; + + qcom,iommu-bfb-data = <0xffffffff + 0xffffffff + 0x00000004 + 0x00000008 + 0x00000000 + 0x00000000 + 0x00000094 + 0x000000b4 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8c000 0x1000>; + interrupts = <0 42 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5>; + label = "venus_ns"; + }; + + venus_cp: qcom,iommu-ctx@fdc8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8d000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x80 0x81 0x82 0x83 0x84 0x85>; + label = "venus_cp"; + qcom,secure-context; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8e000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0xc0 0xc6>; + label = "venus_fw"; + qcom,secure-context; + }; + }; + + kgsl_iommu: qcom,iommu@fdb10000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdb10000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 38 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "kgsl_iommu"; + qcom,msm-bus,name = "kgsl_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x2314 + 0x2394 + 0x2414 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x0 + 0x00000004 + 0x00000010 + 0x00000000 + 0x00000000 + 0x00000001 + 0x00000021 + 0x0 + 0x1 + 0x81 + 0x0>; + + qcom,iommu-ctx@fdb18000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb18000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@fdb19000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb19000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + + qcom,iommu-ctx@fdb1a000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdb1a000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <2>; + label = "gfx3d_spare"; + }; + + }; + + vfe_iommu: qcom,iommu@fda44000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda44000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 62 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <19>; + qcom,needs-alt-core-clk; + label = "vfe_iommu"; + qcom,msm-bus,name = "vfe_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <29 512 0 0>, + <29 512 0 1000>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x20ac + 0x215c + 0x220c + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020>; + + qcom,iommu-bfb-data = <0xffffffff + 0x00000000 + 0x4 + 0x8 + 0x0 + 0x0 + 0x20 + 0x78 + 0x0 + 0x20 + 0x36 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda4c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4c000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <0 1>; + label = "vfe"; + }; + + qcom,iommu-ctx@fda4d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4d000 0x1000>; + interrupts = <0 65 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp"; + }; + + qcom,iommu-ctx@fda4e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda4e000 0x1000>; + interrupts = <0 65 0>, <0 64 0>; + qcom,iommu-ctx-sids = <>; + label = "vfe_secure"; + qcom,secure-context; + }; + }; + + copss_iommu: qcom,iommu@f9bc4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xf9bc4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 153 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <8>; + label = "copss_iommu"; + qcom,msm-bus,name = "copss_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 512 0 0>, + <88 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x5 + 0x0 + 0x1 + 0x0 + 0x0 + 0x40 + 0x44 + 0x3 + 0x0>; + + + copss_cb0: qcom,iommu-ctx@f9bcc000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcc000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <0>; + label = "copss_cb0"; + }; + + copss_cb1: qcom,iommu-ctx@f9bcd000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcd000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <1>; + label = "copss_cb1"; + }; + + copss_usb: qcom,iommu-ctx@f9bce000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bce000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <2>; + label = "copss_usb"; + }; + + copss_cb3: qcom,iommu-ctx@f9bcf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bcf000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <3>; + label = "copss_cb3"; + }; + + copss_cb4: qcom,iommu-ctx@f9bd0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd0000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <4>; + label = "copss_cb4"; + }; + + copss_cb5: qcom,iommu-ctx@f9bd1000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd1000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <5>; + label = "copss_cb5"; + }; + + copss_cb6: qcom,iommu-ctx@f9bd2000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd2000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <6>; + label = "copss_cb6"; + }; + + copss_cb_7: qcom,iommu-ctx@f9bd3000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xf9bd3000 0x1000>; + interrupts = <0 142 0>; + qcom,iommu-ctx-sids = <7>; + label = "copss_cb7"; + }; + }; + + vpu_iommu: qcom,iommu@fdee4000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdee4000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 147 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <7>; + label = "vpu_iommu"; + qcom,msm-bus,name = "vpu_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <93 512 0 0>, + <93 512 0 1000>; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0xffff + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x0 + 0x1e00 + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2000 + 0x2014>; + + qcom,iommu-lpae-bfb-data = <0xffff + 0x0 + 0x4 + 0x10 + 0x0 + 0x0 + 0xf + 0x4b + 0x1e00 + 0x5a2d + 0x1e00 + 0x5a0f + 0x0 + 0x0 + 0x0 + 0x3 + 0x0>; + + + vpu_hlos: qcom,iommu-ctx@fdeec000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeec000 0x1000>; + interrupts = <0 145 0>; + qcom,iommu-ctx-sids = <0 1 3>; + label = "vpu_hlos"; + }; + + vpu_cp: qcom,iommu-ctx@fdeed000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeed000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <8 9>; + label = "vpu_cp"; + qcom,secure-context; + }; + + vpu_fw: qcom,iommu-ctx@fdeee000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdeee000 0x1000>; + interrupts = <0 145 0>, <0 144 0>; + qcom,iommu-ctx-sids = <5 7 15>; + label = "vpu_fw"; + qcom,secure-context; + }; + }; + + lpass_qdsp_iommu: qcom,iommu@fe054000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe054000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 202 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <2>; + label = "lpass_qdsp_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0x20 + 0x0 + 0x10 + 0x0 + 0x0 + 0x15e + 0x19e + 0x3 + 0x0>; + + + lpass_q6_fw: qcom,iommu-ctx@fe05c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05c000 0x1000>; + interrupts = <0 265 0>, <0 203 0>; + qcom,iommu-ctx-sids = <0 15>; + label = "q6_fw"; + qcom,secure-context; + }; + + lpass_audio_shared: qcom,iommu-ctx@fe05d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05d000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <1>; + label = "audio_shared"; + }; + + lpass_q6_spare1: qcom,iommu-ctx@fe05e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05e000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <2>; + label = "q6_spare1"; + }; + + lpass_q6_spare2: qcom,iommu-ctx@fe05f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe05f000 0x1000>; + interrupts = <0 265 0>; + qcom,iommu-ctx-sids = <3 4 5 6 7 8 9 10 11 12 13 14>; + label = "q6_spare2"; + }; + }; + + lpass_core_iommu: qcom,iommu@fe064000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe064000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 166 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <6>; + label = "lpass_core_iommu"; + status = "disabled"; + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0a + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x3 + 0x4 + 0x4 + 0x0 + 0x0 + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x0 + 0x0>; + + qcom,iommu-lpae-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2000 + 0x2008>; + + qcom,iommu-lpae-bfb-data = <0x3 + 0x0 + 0x4 + 0x4 + 0x0 + 0xc + 0x0 + 0x4 + 0x0 + 0x0 + 0x40 + 0x50 + 0x3 + 0x0>; + + + lpass_core_image: qcom,iommu-ctx@fe06c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06c000 0x1000>; + interrupts = <0 267 0>, <0 180 0>; + qcom,iommu-ctx-sids = <11>; + label = "lpass_core_image"; + qcom,secure-context; + }; + + lpass_core_audio: qcom,iommu-ctx@fe06d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06d000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <12>; + label = "lpass_core_audio"; + }; + + lpass_core_slimbus: qcom,iommu-ctx@fe06e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfe06e000 0x1000>; + interrupts = <0 267 0>; + qcom,iommu-ctx-sids = <13>; + label = "lpass_core_slimbus"; + }; + }; + + vcap_iommu: qcom,iommu@fdfb6000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfdfb6000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 315 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,needs-alt-core-clk; + label = "vcap_iommu"; + status = "disabled"; + qcom,msm-bus,name = "vcap_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <48 512 0 0>, + <48 512 0 1000>; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2060>; + + qcom,iommu-bfb-data = <0x0ff + 0x00000004 + 0x00000008 + 0x0 + 0x0 + 0x00000008 + 0x00000028 + 0x0 + 0x001000 + 0x001000 + 0x003008 + 0x0 + 0x0 + 0x0 + 0x1555>; + + qcom,iommu-ctx@fdfbe000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbe000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <0>; + label = "vcap_cb0"; + }; + + qcom,iommu-ctx@fdfbf000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfbf000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <1>; + label = "vcap_cb1"; + }; + + qcom,iommu-ctx@fdfc0000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdfc0000 0x1000>; + interrupts = <0 313 0>; + qcom,iommu-ctx-sids = <>; + label = "vcap_cb2"; + }; + }; + + bcast_iommu: qcom,iommu@fc734000{ + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfc734000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 279 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "bcast_iommu"; + qcom,iommu-secure-id = <13>; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x204c + 0x2050 + 0x2514 + 0x2540 + 0x256c + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c + 0x2020 + 0x2060>; + + qcom,iommu-bfb-data = <0xffffffff + 0x1 + 0x0000004 + 0x0000004 + 0x0 + 0x0 + 0x000055 + 0x0000d9 + 0x0 + 0x000aa00 + 0x0004200 + 0x000e821 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x1555>; + + bcast_cb0_hlos: qcom,iommu-ctx@fc73c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73c000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31>; + label = "bcast_cb0_hlos"; + }; + + bcast_cb1_cpz: qcom,iommu-ctx@fc73d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73d000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62>; + label = "bcast_cb1_cpz"; + qcom,secure-context; + }; + + bcast_cb2_demod: qcom,iommu-ctx@fc73e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73e000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <63>; + label = "bcast_cb2_demod"; + qcom,secure-context; + }; + + bcast_cb3_apz: qcom,iommu-ctx@fc73f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfc73f000 0x1000>; + interrupts = <0 276 0>; + qcom,iommu-ctx-sids = <>; + label = "bcast_cb3_apz"; + qcom,secure-context; + }; + }; + + fd_iommu: qcom,iommu@0xfd864000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd864000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 314 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "fd_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008>; + + qcom,iommu-bfb-data = <0x00000003 + 0x00000007 + 0x1555 + 0x0 + 0x00000004 + 0x00000008 + 0x0601 + 0x1a0d + 0x0400 + 0x1a02 + 0x0 + 0x00000000 + 0x00000002 + 0x0000000a + 0x0>; + + qcom,iommu-ctx@fd86c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86c000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <0>; + label = "camera_fd"; + }; + + qcom,iommu-ctx@fd86d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86d000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_1"; + }; + + qcom,iommu-ctx@fd86e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd86e000 0x1000>; + interrupts = <0 318 0>; + qcom,iommu-ctx-sids = <>; + label = "fd_2"; + }; + }; + + cpp_iommu: qcom,iommu@0xfda84000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfda84000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 264 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + label = "cpp_iommu"; + status = "disabled"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c>; + + qcom,iommu-bfb-data = <0x00000003 + 0x3ff + 0x1555 + 0x0 + 0x00000004 + 0x10 + 0x1400 + 0x164b2 + 0x1400 + 0x1640a + 0x0 + 0x00000000 + 0x0000000a + 0x32 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda8c000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8c000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <2>; + label = "cpp_0"; + }; + + qcom,iommu-ctx@fda8d000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8d000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_1"; + }; + + qcom,iommu-ctx@fda8e000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda8e000 0x1000>; + interrupts = <0 266 0>; + qcom,iommu-ctx-sids = <>; + label = "cpp_2"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v2.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v2.dtsi new file mode 100755 index 0000000000000..2aa3828704d07 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-iommu-v2.dtsi @@ -0,0 +1,238 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gfx_iommu: qcom,iommu@1f00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1f00000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "gfx_iommu"; + qcom,iommu-secure-id = <18>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_gfx_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + status = "disabled"; + + qcom,iommu-ctx@1f09000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f09000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@1f0a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f0a000 0x1000>; + interrupts = <0 242 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + }; + + apps_iommu: qcom,iommu@1e00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1e00000 0x40000 + 0x1ef0000 0x3000>; + reg-names = "iommu_base", "smmu_local_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "apps_iommu"; + qcom,iommu-secure-id = <17>; + clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>, + <&clock_gcc clk_gcc_apss_tcu_clk>; + clock-names = "iface_clk", "core_clk"; + qcom,cb-base-offset = <0x20000>; + status = "disabled"; + + qcom,iommu-ctx@1e22000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e22000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2000>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@1e23000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e23000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x400>; + label = "vfe"; + }; + + qcom,iommu-ctx@1e24000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e24000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xc00>; + label = "mdp_0"; + }; + + venus_ns: qcom,iommu-ctx@1e25000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e25000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x800 0x801 0x802 0x803 + 0x804 0x805 0x807>; + label = "venus_ns"; + }; + + qcom,iommu-ctx@1e26000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e26000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x402>; + label = "cpp"; + }; + + qcom,iommu-ctx@1e27000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e27000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1000>; + label = "mDSP"; + }; + + qcom,iommu-ctx@1e28000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e28000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1400>; + label = "gss"; + }; + + qcom,iommu-ctx@1e29000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e29000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1800>; + label = "a2"; + }; + + qcom,iommu-ctx@1e32000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e32000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0xc01>; + label = "mdp_1"; + }; + + venus_sec_pixel: qcom,iommu-ctx@1e33000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e33000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x885>; + label = "venus_sec_pixel"; + }; + + venus_sec_bitstream: qcom,iommu-ctx@1e34000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e34000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x880 0x881 0x882 0x883 0x884>; + label = "venus_sec_bitstream"; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@1e35000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e35000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x887 0x8a0>; + label = "venus_sec_non_pixel"; + }; + + venus_fw: qcom,iommu-ctx@1e36000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e36000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x8c0 0x8c6>; + label = "venus_fw"; + }; + + periph_rpm: qcom,iommu-ctx@1e37000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e37000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x40>; + label = "periph_rpm"; + }; + + qcom,iommu-ctx@1e38000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e38000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xC0 0xC4 0xC8 0xCC 0xD0 0xD3 + 0xD4 0xD7 0xD8 0xDB 0xDC 0xDF + 0xF0 0xF3 0xF4 0xF7 0xF8 0xFB + 0xFC 0xFF>; + label = "periph_CE"; + }; + + qcom,iommu-ctx@1e39000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e39000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x280 0x283 0x284 0x287 0x288 + 0x28B 0x28C 0x28F 0x290 0x293 + 0x294 0x297 0x298 0x29B 0x29C + 0x29F>; + label = "periph_BLSP"; + }; + + qcom,iommu-ctx@1e3a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3a000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x100>; + label = "periph_SDC1"; + }; + + qcom,iommu-ctx@1e3b000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3b000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x140>; + label = "periph_SDC2"; + }; + + qcom,iommu-ctx@1e3c000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1c0>; + label = "periph_audio"; + }; + + qcom,iommu-ctx@1e3d000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2c0>; + label = "periph_USB_HS1"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-pm8994-rpm-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-pm8994-rpm-regulator.dtsi new file mode 100755 index 0000000000000..8c32136aabd4b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-pm8994-rpm-regulator.dtsi @@ -0,0 +1,697 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + rpm-regulator-smpa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <3>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <4>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa5 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <5>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s5 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s5"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpa7 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpa"; + qcom,resource-id = <7>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s7 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s7"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <2>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa3 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <3>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l3 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l3"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa4 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <4>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l4 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l4"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa6 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <6>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l6 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l6"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa8 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <8>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l8 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l8"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa9 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <9>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l9 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l9"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa10 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <10>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l10 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l10"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa11 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <11>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l11 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l11"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa12 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <12>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l12 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l12"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa13 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <13>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l13 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l13"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa14 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <14>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l14 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l14"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa15 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <15>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l15 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l15"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa16 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <16>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l16 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l16"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa17 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <17>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l17 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l17"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa18 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <18>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l18 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l18"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa19 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <19>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l19 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l19"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa20 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <20>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l20 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l20"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa21 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <21>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l21 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l21"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa22 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <22>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l22 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l22"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa23 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <23>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l23 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l23"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa24 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <24>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l24 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l24"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa25 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <25>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l25 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l25"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa26 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <26>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l26 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l26"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa27 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <27>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l27 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l27"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa28 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <28>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l28 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l28"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa29 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <29>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l29 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l29"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa30 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <30>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l30 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l30"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa31 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <31>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <10000>; + status = "disabled"; + + regulator-l31 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l31"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-ldoa32 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "ldoa"; + qcom,resource-id = <32>; + qcom,regulator-type = <0>; + qcom,hpm-min-load = <5000>; + status = "disabled"; + + regulator-l32 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_l32"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-vsa2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "vsa"; + qcom,resource-id = <2>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-lvs2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_lvs2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb1 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <1>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s1 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s1"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpb2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpb"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bstb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bstb"; + qcom,resource-id = <1>; + qcom,regulator-type = <2>; + status = "disabled"; + + regulator-bst { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-bbyb { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "bbyb"; + qcom,resource-id = <1>; + qcom,regulator-type = <0>; + status = "disabled"; + + regulator-bby { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boostbypass"; + qcom,set = <3>; + status = "disabled"; + }; + }; + + rpm-regulator-smpc2 { + compatible = "qcom,rpm-smd-regulator-resource"; + qcom,resource-name = "smpc"; + qcom,resource-id = <2>; + qcom,regulator-type = <1>; + qcom,hpm-min-load = <100000>; + status = "disabled"; + + regulator-s2 { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2"; + qcom,set = <3>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-pm8994.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-pm8994.dtsi new file mode 100755 index 0000000000000..7312c2594e9ec --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-pm8994.dtsi @@ -0,0 +1,576 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pm8994@0 { + spmi-slave-container; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + + pm8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,temp-alarm@2400 { + compatible = "qcom,qpnp-temp-alarm"; + reg = <0x2400 0x100>; + interrupts = <0x0 0x24 0x0>; + label = "pm8994_tz"; + qcom,channel-num = <8>; + qcom,threshold-set = <0>; + qcom,temp_alarm-vadc = <&pm8994_vadc>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + interrupts = <0x0 0x8 0x0>, + <0x0 0x8 0x1>, + <0x0 0x8 0x4>, + <0x0 0x8 0x5>; + interrupt-names = "kpdpwr", "resin", + "resin-bark", "kpdpwr-resin-bark"; + qcom,pon-dbc-delay = <15625>; + qcom,system-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + + qcom,pon_1 { + qcom,pon-type = <0>; + qcom,pull-up = <1>; + linux,code = <116>; + qcom,support-reset = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <10256>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_2 { + qcom,pon-type = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT + // comment out by yangrujin@bsp for vol_down is controled by gpio + //linux,code = <114>; + //#endif /*VENDOR_EDIT*/ + }; + + qcom,pon_3 { + qcom,pon-type = <3>; + qcom,support-reset = <1>; + qcom,pull-up = <1>; + // #ifdef VENDOR_EDIT // modify by xcb for hardreset + qcom,s1-timer = <6720>; + qcom,s2-timer = <1000>; + qcom,s2-type = <7>; + //#endif /*VENDOR_EDIT*/ + + qcom,use-bark; + }; + }; + + pm8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + + gpio@ca00 { + reg = <0xca00 0x100>; + qcom,pin-num = <11>; + status = "disabled"; + }; + + gpio@cb00 { + reg = <0xcb00 0x100>; + qcom,pin-num = <12>; + status = "disabled"; + }; + + gpio@cc00 { + reg = <0xcc00 0x100>; + qcom,pin-num = <13>; + status = "disabled"; + }; + + gpio@cd00 { + reg = <0xcd00 0x100>; + qcom,pin-num = <14>; + status = "disabled"; + }; + + gpio@ce00 { + reg = <0xce00 0x100>; + qcom,pin-num = <15>; + status = "disabled"; + }; + + gpio@cf00 { + reg = <0xcf00 0x100>; + qcom,pin-num = <16>; + status = "disabled"; + }; + + gpio@d000 { + reg = <0xd000 0x100>; + qcom,pin-num = <17>; + status = "disabled"; + }; + + gpio@d100 { + reg = <0xd100 0x100>; + qcom,pin-num = <18>; + status = "disabled"; + }; + + gpio@d200 { + reg = <0xd200 0x100>; + qcom,pin-num = <19>; + status = "disabled"; + }; + + gpio@d300 { + reg = <0xd300 0x100>; + qcom,pin-num = <20>; + status = "disabled"; + }; + + gpio@d500 { + reg = <0xd500 0x100>; + qcom,pin-num = <22>; + status = "disabled"; + }; + }; + + pm8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pm8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp02*/ + /* + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP2 as an Analog input to AMUX6 and read from channel 0x11 */ + mpp@a100 { /* MPP 2 */ + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <1>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH6 = 1*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4)*/ + /* + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + };*/ + /*#else VENDOR_EDIT*/ + /* Configure MPP4 as an Analog input to AMUX8 and read from channel 0x23 */ + mpp@a300 { /* MPP 4 */ + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 8 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT changhua 2015-02-26 modify for rare cover use ADC(PM8994 MPP4) end*/ + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp05*/ + /* + mpp@a400 { + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP5 as an Analog input to AMUX5 and read from channel 0x14 */ + mpp@a400 { /* MPP 5 */ + reg = <0xa400 0x100>; + qcom,pin-num = <5>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <0>; /* AMUX 5 ,QPNP_PIN_AIN_AMUX_CH5 = 0*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + + mpp@a500 { + reg = <0xa500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + mpp@a600 { + reg = <0xa600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + /*#ifndef VENDOR_EDIT //changhua 2015-02-26 modify for rf version use mpp08*/ + /* + mpp@a700 { + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + */ + /*#else VENDOR_EDIT*/ + /* Configure MPP8 as an Analog input to AMUX8 and read from channel 0x17 */ + mpp@a700 { /* MPP 8 */ + reg = <0xa700 0x100>; + qcom,pin-num = <8>; + qcom,mode = <4>; /* AIN input */ + //qcom,invert = <1>; /* Enable MPP */ + qcom,ain-route = <3>; /* AMUX 6 ,QPNP_PIN_AIN_AMUX_CH8 = 3*/ + qcom,master-en = <1>; /* Enable MPP */ + qcom,src-sel = <0>; /* Function constant */ + }; + /*#end VENDOR_EDIT*/ + }; + + pm8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x31 0x0>; + interrupt-names = "eoc-int-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + + chan@8 { + label = "die_temp"; + reg = <8>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <3>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@9 { + label = "ref_625mv"; + reg = <9>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@a { + label = "ref_1250v"; + reg = <0xa>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + /* VADC Channel configuration */ + chan@23 { + label = "cover_mpp4_div3"; + reg = <0x23>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; //Use 1:3 scaling to keep input voltage with in Max voltage: 1.8V + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /* //EVB2 floating,so use 1:1 chan + chan@13 { + label = "cover_mpp4_div3"; + reg = <0x13>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + };*/ + /*#endif VENDOR_EDIT*/ + + +/*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + /* VADC Channel configuration */ + chan@76 { + label = "pcb_version_AMUX_HW_ID"; + reg = <0x76>;//pcb_version_AMUX_HW_ID channel 54 + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; //Use 1:1 scaling to keep input voltage with in Max voltage: 1.8V + //qcom,calibration-type = "ratiometric"; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@11 { + label = "rf_mpp2"; + reg = <0x11>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@14 { + label = "rf_mpp5"; + reg = <0x14>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + chan@17 { + label = "rf_mpp8"; + reg = <0x17>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + /*#endif VENDOR_EDIT*/ + }; + + pm8994_adc_tm: vadc@3400 { + compatible = "qcom,qpnp-adc-tm"; + reg = <0x3400 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x0 0x34 0x0>, + <0x0 0x34 0x3>, + <0x0 0x34 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,adc_tm-vadc = <&pm8994_vadc>; + }; + + pm8994_coincell: qcom,coincell@2800 { + compatible = "qcom,qpnp-coincell"; + reg = <0x2800 0x100>; + }; + + qcom,pm8994_rtc { + spmi-dev-container; + compatible = "qcom,qpnp-rtc"; + #address-cells = <1>; + #size-cells = <1>; + qcom,qpnp-rtc-write = <0>; + /*#ifdef VENDOR_EDIT //changhua 2015-03-6 add for test PCB version,read by adb shell*/ + qcom,qpnp-rtc-alarm-pwrup = <1>; + /*#endif VENDOR_EDIT*/ + + qcom,pm8994_rtc_rw@6000 { + reg = <0x6000 0x100>; + }; + qcom,pm8994_rtc_alarm@6100 { + reg = <0x6100 0x100>; + interrupts = <0x0 0x61 0x1>; + }; + }; + }; + + qcom,pm8994@1 { + spmi-slave-container; + reg = <0x1>; + #address-cells = <1>; + #size-cells = <1>; + + pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b500 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb500 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <4>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <4>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm@b600 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb600 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <5>; + qcom,supported-sizes = <6>, <7>, <9>; + qcom,ramp-index = <5>; + #pwm-cells = <2>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-pmi8994.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-pmi8994.dtsi new file mode 100755 index 0000000000000..2e14cf1db68ba --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-pmi8994.dtsi @@ -0,0 +1,741 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&spmi_bus { + #address-cells = <1>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <3>; + + qcom,pmi8994@2 { + spmi-slave-container; + reg = <0x2>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + qcom,power-on@800 { + compatible = "qcom,qpnp-power-on"; + reg = <0x800 0x100>; + qcom,secondary-pon-reset; + qcom,s3-debounce = <32>; + qcom,s3-src = "kpdpwr-and-resin"; + }; + + pmi8994_gpios: gpios { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-gpio"; + + gpio@c000 { + reg = <0xc000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + gpio@c100 { + reg = <0xc100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + gpio@c200 { + reg = <0xc200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + gpio@c300 { + reg = <0xc300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + gpio@c400 { + reg = <0xc400 0x100>; + qcom,pin-num = <5>; + status = "disabled"; + }; + + gpio@c500 { + reg = <0xc500 0x100>; + qcom,pin-num = <6>; + status = "disabled"; + }; + + gpio@c600 { + reg = <0xc600 0x100>; + qcom,pin-num = <7>; + status = "disabled"; + }; + + gpio@c700 { + reg = <0xc700 0x100>; + qcom,pin-num = <8>; + status = "disabled"; + }; + + gpio@c800 { + reg = <0xc800 0x100>; + qcom,pin-num = <9>; + status = "disabled"; + }; + + gpio@c900 { + reg = <0xc900 0x100>; + qcom,pin-num = <10>; + status = "disabled"; + }; + }; + + pmi8994_mpps: mpps { + spmi-dev-container; + compatible = "qcom,qpnp-pin"; + gpio-controller; + #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + label = "pmi8994-mpp"; + + mpp@a000 { + reg = <0xa000 0x100>; + qcom,pin-num = <1>; + status = "disabled"; + }; + + mpp@a100 { + reg = <0xa100 0x100>; + qcom,pin-num = <2>; + status = "disabled"; + }; + + mpp@a200 { + reg = <0xa200 0x100>; + qcom,pin-num = <3>; + status = "disabled"; + }; + + mpp@a300 { + reg = <0xa300 0x100>; + qcom,pin-num = <4>; + status = "disabled"; + }; + + }; +//#ifdef VENDOR_EDIT /* shankai@BSP.driver, 2015/3/25, add for the button-backlight */ + qcom,leds@a300 { + compatible = "qcom,leds-qpnp"; + status = "okay"; + reg=<0xa300 0x100>; + qcom,led_mpp_3 { + label = "mpp"; + linux,name = "button-backlight"; + linux,default-trigger = "none"; + qcom,default-state = "off"; + qcom,max-current = <40>; + qcom,current-setting = <5>; + qcom,id = <6>; + qcom,mode = "manual"; + qcom,source-sel = <1>; + qcom,mode-ctrl = <0x60>; + }; + }; +//#endif /*VENDOR_EDIT*/ + + + + bcl@4200 { + compatible = "qcom,msm-bcl"; + reg = <0x4200 0xFF 0x88E 0x2>; + reg-names = "fg_user_adc", "pon_spare"; + interrupts = <0x2 0x42 0x0>, + <0x2 0x42 0x1>; + interrupt-names = "bcl-high-ibat-int", + "bcl-low-vbat-int"; + qcom,vbat-scaling-factor = <39000>; + qcom,vbat-gain-numerator = <1>; + qcom,vbat-gain-denominator = <128>; + qcom,vbat-polling-delay-ms = <100>; + qcom,ibat-scaling-factor = <39000>; + qcom,ibat-gain-numerator = <1>; + qcom,ibat-gain-denominator = <128>; + qcom,ibat-offset-numerator = <1200>; + qcom,ibat-offset-denominator = <1>; + qcom,ibat-polling-delay-ms = <100>; + qcom,inhibit-derating-ua = <550000>; + }; + + pmi8994_vadc: vadc@3100 { + compatible = "qcom,qpnp-vadc"; + reg = <0x3100 0x100>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0x2 0x31 0x0>, + <0x2 0x31 0x3>, + <0x2 0x31 0x4>; + interrupt-names = "eoc-int-en-set", + "high-thr-en-set", + "low-thr-en-set"; + qcom,adc-bit-resolution = <15>; + qcom,adc-vdd-reference = <1800>; + qcom,vadc-poll-eoc; + qcom,vadc-meas-int-mode; + }; + + pmi8994_charger: qcom,qpnp-smbcharger { + spmi-dev-container; + compatible = "qcom,qpnp-smbcharger"; + #address-cells = <1>; + #size-cells = <1>; + + qcom,iterm-ma = <150>; + qcom,fastchg-current-ma = <1910>; + qcom,float-voltage-mv = <4320>; + qcom,resume-delta-mv = <100>; + // qcom,chg-inhibit-en; + qcom,chg-inhibit-fg; + qcom,dc-psy-type = "Mains"; + qcom,dc-psy-ma = <1500>; + qcom,rparasitic-uohm = <100000>; + qcom,bms-psy-name = "bms"; + qcom,thermal-mitigation = <2000 1000 900 800>; + qcom,parallel-usb-min-current-ma = <1400>; + qcom,parallel-usb-9v-min-current-ma = <900>; + qcom,parallel-allowed-lowering-ma = <500>; + qcom,autoadjust-vfloat; + qcom,charge-unknown-battery; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x2 0x10 0x0>, + <0x2 0x10 0x1>, + <0x2 0x10 0x2>, + <0x2 0x10 0x3>, + <0x2 0x10 0x4>, + <0x2 0x10 0x5>, + <0x2 0x10 0x6>, + <0x2 0x10 0x7>; + + interrupt-names = "chg-error", + "chg-inhibit", + "chg-prechg-sft", + "chg-complete-chg-sft", + "chg-p2f-thr", + "chg-rechg-thr", + "chg-taper-thr", + "chg-tcc-thr"; + }; + + qcom,otg@1100 { + reg = <0x1100 0x100>; + }; + + qcom,bat-if@1200 { + reg = <0x1200 0x100>; + interrupts = <0x2 0x12 0x0>, + <0x2 0x12 0x1>, + <0x2 0x12 0x2>, + <0x2 0x12 0x3>, + <0x2 0x12 0x4>, + <0x2 0x12 0x5>, + <0x2 0x12 0x6>, + <0x2 0x12 0x7>; + + interrupt-names = "batt-hot", + "batt-warm", + "batt-cold", + "batt-cool", + "batt-ov", + "batt-low", + "batt-missing", + "batt-term-missing"; + }; + + qcom,usb-chgpth@1300 { + reg = <0x1300 0x100>; + interrupts = <0x2 0x13 0x0>, + <0x2 0x13 0x1>, + <0x2 0x13 0x2>, + <0x2 0x13 0x3>, + <0x2 0x13 0x4>, + <0x2 0x13 0x5>, + <0x2 0x13 0x6>; + + interrupt-names = "usbin-uv", + "usbin-ov", + "usbin-src-det", + "otg-fail", + "otg-oc", + "aicl-done", + "usbid-change"; + }; + + qcom,dc-chgpth@1400 { + reg = <0x1400 0x100>; + interrupts = <0x2 0x14 0x0>, + <0x2 0x14 0x1>; + + interrupt-names = "dcin-uv", + "dcin-ov"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x2 0x16 0x0>, + <0x2 0x16 0x1>, + <0x2 0x16 0x2>, + <0x2 0x16 0x3>, + <0x2 0x16 0x4>, + <0x2 0x16 0x5>; + + interrupt-names = "power-ok", + "temp-shutdown", + "safety-timeout", + "flash-fail", + "otst2", + "otst3"; + }; + }; + + pmi8994_fg: qcom,fg { + spmi-dev-container; + compatible = "qcom,qpnp-fg"; + #address-cells = <1>; + #size-cells = <1>; + //qcom,resume-soc = <95>; + qcom,resume-soc = <99>; + status = "okay"; + qcom,bcl-lm-threshold-ma = <127>; + qcom,bcl-mh-threshold-ma = <405>; + qcom,fg-chg-iterm-ma = <150>; + qcom,cycle-counter-en; + qcom,cycle-counter-low-soc = <15>; + qcom,cycle-counter-high-soc = <85>; + qcom,capacity-learning-on; + qcom,fg-cc-cv-threshold-mv = <4310>; + qcom,fg-iterm-ma = <200>; + qcom,fg-cutoff-voltage-mv=<3500>; + qcom,pmic-revid = <&pmi8994_revid>; + + qcom,thermal-coefficients = [da 86 f0 50 08 3c]; + qcom,fg-soc@4000 { + status = "okay"; + reg = <0x4000 0x100>; + interrupts = <0x2 0x40 0x0>, + <0x2 0x40 0x1>, + <0x2 0x40 0x2>, + <0x2 0x40 0x3>, + <0x2 0x40 0x4>, + <0x2 0x40 0x5>, + <0x2 0x40 0x6>, + <0x2 0x40 0x7>; + + interrupt-names = "high-soc", + "low-soc", + "full-soc", + "empty-soc", + "delta-soc", + "first-est-done", + "sw-fallbk-ocv", + "sw-fallbk-new-battrt-sts", + "fg-soc-irq-count"; + }; + + qcom,fg-batt@4100 { + reg = <0x4100 0x100>; + interrupts = <0x2 0x41 0x0>, + <0x2 0x41 0x1>, + <0x2 0x41 0x2>, + <0x2 0x41 0x3>, + <0x2 0x41 0x4>, + <0x2 0x41 0x5>, + <0x2 0x41 0x6>, + <0x2 0x41 0x7>; + + interrupt-names = "soft-cold", + "soft-hot", + "vbatt-low", + "batt-ided", + "batt-id-req", + "batt-unknown", + "batt-missing", + "batt-match"; + }; + + qcom,fg-adc-vbat@4254 { + reg = <0x4254 0x1>; + }; + + qcom,fg-adc-ibat@4255 { + reg = <0x4255 0x1>; + }; + + qcom,revid-tp-rev@1f1 { + reg = <0x1f1 0x1>; + }; + + qcom,fg-memif@4400 { + status = "okay"; + reg = <0x4400 0x100>; + interrupts = <0x2 0x44 0x0>, + <0x2 0x44 0x1>; + + interrupt-names = "mem-avail", + "data-rcvry-sug"; + }; + }; + }; + + qcom,pmi8994@3 { + spmi-slave-container; + reg = <0x3>; + #address-cells = <1>; + #size-cells = <1>; + + pmi8994_pwm_1: pwm@b100 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb100 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <0>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <0>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_2: pwm@b200 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb200 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <1>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <1>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_3: pwm@b300 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb300 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <2>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <2>; + #pwm-cells = <2>; + }; + + pmi8994_pwm_4: pwm@b400 { + compatible = "qcom,qpnp-pwm"; + reg = <0xb400 0x100>, + <0xb042 0x7e>; + reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; + qcom,channel-id = <3>; + qcom,supported-sizes = <6>, <9>; + qcom,ramp-index = <3>; + #pwm-cells = <2>; + }; + + labibb: qpnp-labibb-regulator { + status = "disabled"; + spmi-dev-container; + compatible = "qcom,qpnp-labibb-regulator"; + #address-cells = <1>; + #size-cells = <1>; + + lab_regulator: qcom,lab@de00 { + reg = <0xde00 0x100>; + reg-names = "lab"; + regulator-name = "lab_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-lab-min-voltage = <4600000>; + qcom,qpnp-lab-step-size = <100000>; + qcom,qpnp-lab-slew-rate = <5000>; + qcom,qpnp-lab-use-default-voltage; + qcom,qpnp-lab-init-voltage = <5500000>; + qcom,qpnp-lab-init-amoled-voltage = <4600000>; + qcom,qpnp-lab-init-lcd-voltage = <5500000>; + + qcom,qpnp-lab-soft-start = <800>; + + qcom,qpnp-lab-full-pull-down; + qcom,qpnp-lab-pull-down-enable; + qcom,qpnp-lab-switching-clock-frequency = <1600>; + qcom,qpnp-lab-limit-maximum-current = <800>; + qcom,qpnp-lab-limit-max-current-enable; + qcom,qpnp-lab-ps-threshold = <20>; + qcom,qpnp-lab-ps-enable; + qcom,qpnp-lab-nfet-size = <100>; + qcom,qpnp-lab-pfet-size = <100>; + qcom,qpnp-lab-max-precharge-time = <200>; + }; + + ibb_regulator: qcom,ibb@dc00 { + reg = <0xdc00 0x100>; + reg-names = "ibb_reg"; + regulator-name = "ibb_reg"; + + regulator-min-microvolt = <4600000>; + regulator-max-microvolt = <6000000>; + + qcom,qpnp-ibb-min-voltage = <1400000>; + qcom,qpnp-ibb-step-size = <100000>; + qcom,qpnp-ibb-slew-rate = <2000000>; + qcom,qpnp-ibb-use-default-voltage; + qcom,qpnp-ibb-init-voltage = <5500000>; + qcom,qpnp-ibb-init-amoled-voltage = <4000000>; + qcom,qpnp-ibb-init-lcd-voltage = <5500000>; + + qcom,qpnp-ibb-soft-start = <1000>; + + qcom,qpnp-ibb-discharge-resistor = <300>; + qcom,qpnp-ibb-lab-pwrup-delay = <4000>; + qcom,qpnp-ibb-lab-pwrdn-delay = <4000>; + qcom,qpnp-ibb-en-discharge; + + qcom,qpnp-ibb-full-pull-down; + qcom,qpnp-ibb-pull-down-enable; + qcom,qpnp-ibb-switching-clock-frequency = <1480>; + qcom,qpnp-ibb-limit-maximum-current = <1550>; + qcom,qpnp-ibb-debounce-cycle = <16>; + qcom,qpnp-ibb-limit-max-current-enable; + qcom,qpnp-ibb-ps-enable; + }; + + }; + + qcom,leds@d800 { + compatible = "qcom,qpnp-wled"; + reg = <0xd800 0x100>, + <0xd900 0x100>, + <0xdc00 0x100>, + <0xde00 0x100>; + reg-names = "qpnp-wled-ctrl-base", + "qpnp-wled-sink-base", + "qpnp-wled-ibb-base", + "qpnp-wled-lab-base"; + interrupts = <0x3 0xd8 0x2>; + interrupt-names = "sc-irq"; + status = "okay"; + linux,name = "wled"; + linux,default-trigger = "bkl-trigger"; + qcom,fdbk-output = "auto"; + qcom,vref-mv = <350>; + qcom,switch-freq-khz = <800>; + qcom,ovp-mv = <29500>; + qcom,ilim-ma = <980>; + qcom,boost-duty-ns = <26>; + qcom,mod-freq-khz = <9600>; + qcom,dim-mode = "hybrid"; + qcom,dim-method = "linear"; + qcom,hyb-thres = <625>; + qcom,sync-dly-us = <800>; + qcom,fs-curr-ua = <20000>;//guozhimig@oem add 2015-04-02 for adiudt backlight 20mA + qcom,en-phase-stag; + qcom,ibb-pwrup-dly = <8>; + qcom,led-strings-list = [00 01];//two WLED SINK/*guozhiming@oem.cn modify 2015-03-24*/ + qcom,en-ext-pfet-sc-pro; + qcom,en-cabc;//guozhimig@oem add 2015-04-02 for en cabc + }; + +//#ifdef VENDOR_EDIT // shankai@bsp, 2015-4-4 do not use it ,comment it. +//shankai@bsp, 2015-5-28 now we use it + pmi8994_haptics: qcom,haptic@c000 { + status = "okay"; + compatible = "qcom,qpnp-haptic"; + reg = <0xc000 0x100>; + interrupts = <0x3 0xc0 0x0>, + <0x3 0xc0 0x1>; + interrupt-names = "sc-irq", "play-irq"; + qcom,play-mode = "direct"; + qcom,wave-play-rate-us = <5263>; + qcom,actuator-type = "erm"; + qcom,wave-shape = "square"; + qcom,vmax-mv = <3000>; + qcom,ilim-ma = <800>; + qcom,sc-deb-cycles = <8>; + qcom,int-pwm-freq-khz = <505>; + qcom,en-brake; + qcom,brake-pattern = [00 01 03 03]; + qcom,use-play-irq; + qcom,use-sc-irq; + qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e]; + qcom,wave-rep-cnt = <1>; + qcom,wave-samp-rep-cnt = <1>; + }; + +//#endif + qcom,leds@d000 { + compatible = "qcom,leds-qpnp"; + reg = <0xd000 0x100>; + label = "rgb"; + status = "okay"; + + /*#ifndef VENDOR_EDIT //shankai@bsp.driver 2015-02-26 modify for rgb blink feature*/ + qcom,rgb_0 { + label = "rgb"; + qcom,id = <3>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_3 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <1>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "red"; + /*linux,default-trigger = + "battery-charging";*/ + qcom,use-blink; + }; + + qcom,rgb_1 { + label = "rgb"; + qcom,id = <4>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_2 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,default-state = "off"; + /* + qcom,duty-pcts = [00 05 0A 0f 14 19 1d 23 28 2c + 32 37 3b 41 45 4a 50 55 5a 64]; + */ + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + linux,name = "green"; + /*linux,default-trigger = "battery-full";*/ + qcom,use-blink; + }; + + qcom,rgb_2 { + label = "rgb"; + qcom,id = <5>; + qcom,mode = "pwm"; + pwms = <&pmi8994_pwm_1 0 0>; + qcom,pwm-us = <1000>; + qcom,max-current = <12>; + qcom,duty-pcts = [00 05 0a 0f 14 1d 28 32 3c 4b 64]; + qcom,duty-ms = <20>; + qcom,start-idx = <13>; + qcom,idx-len = <11>; + + qcom,lut-flags = <0x1f>; + qcom,ramp-step-ms = <100>; + qcom,pause-lo = <2000>; + qcom,pause-hi = <1000>; + + qcom,default-state = "off"; + linux,name = "blue"; + qcom,use-blink; + linux,default-trigger = "boot-indication"; + }; + /*#end VENDOR_EDIT*/ + }; + + qcom,leds@d300 { + compatible = "qcom,qpnp-flash-led"; + status = "okay"; + reg = <0xd300 0x100>; + label = "flash"; + qcom,headroom = <500>; + qcom,startup-dly = <128>; + qcom,clamp-curr = <200>; + qcom,pmic-charger-support; + qcom,self-check-enabled; + qcom,thermal-derate-enabled; + qcom,thermal-derate-threshold = <100>; + qcom,thermal-derate-rate = "5_PERCENT"; + qcom,current-ramp-enabled; + qcom,ramp_up_step = "6P7_US"; + qcom,ramp_dn_step = "6P7_US"; + qcom,vph-pwr-droop-enabled; + qcom,vph-pwr-droop-threshold = <3000>; + qcom,vph-pwr-droop-debounce-time = <10>; + qcom,headroom-sense-ch0-enabled; + qcom,headroom-sense-ch1-enabled; + qcom,power-detect-enabled; + + pmi8994_flash0: qcom,flash_0 { + label = "flash"; + qcom,led-name = "led:flash_0"; + qcom,default-led-trigger = + "flash0_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <0>; + qcom,current = <625>; + }; + + pmi8994_flash1: qcom,flash_1 { + label = "flash"; + qcom,led-name = "led:flash_1"; + qcom,default-led-trigger = + "flash1_trigger"; + qcom,max-current = <1000>; + qcom,duration = <1280>; + qcom,id = <1>; + qcom,current = <625>; + }; + + pmi8994_torch0: qcom,torch_0 { + label = "torch"; + qcom,led-name = "led:torch_0"; + qcom,default-led-trigger = + "torch0_trigger"; + qcom,max-current = <200>; + qcom,id = <0>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + + pmi8994_torch1: qcom,torch_1 { + label = "torch"; + qcom,led-name = "led:torch_1"; + qcom,default-led-trigger = + "torch1_trigger"; + qcom,max-current = <200>; + qcom,id = <1>; + qcom,current = <120>; + boost-supply = <&pmi8994_boostbypass>; + boost-voltage-max = <3600000>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm-rdbg.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm-rdbg.dtsi new file mode 100755 index 0000000000000..f7f52bed111c6 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm-rdbg.dtsi @@ -0,0 +1,75 @@ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + smp2pgpio_rdbg_2_in: qcom,smp2pgpio-rdbg-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_in { + compatible = "qcom,smp2pgpio_client_rdbg_2_in"; + gpios = <&smp2pgpio_rdbg_2_in 0 0>; + }; + + smp2pgpio_rdbg_2_out: qcom,smp2pgpio-rdbg-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_2_out { + compatible = "qcom,smp2pgpio_client_rdbg_2_out"; + gpios = <&smp2pgpio_rdbg_2_out 0 0>; + }; + + smp2pgpio_rdbg_1_in: qcom,smp2pgpio-rdbg-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_in { + compatible = "qcom,smp2pgpio_client_rdbg_1_in"; + gpios = <&smp2pgpio_rdbg_1_in 0 0>; + }; + + smp2pgpio_rdbg_1_out: qcom,smp2pgpio-rdbg-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "rdbg"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_client_rdbg_1_out { + compatible = "qcom,smp2pgpio_client_rdbg_1_out"; + gpios = <&smp2pgpio_rdbg_1_out 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-bus.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-bus.dtsi new file mode 100755 index 0000000000000..6b77e2a0488e4 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-bus.dtsi @@ -0,0 +1,1597 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +&soc { + ad_hoc_bus: ad-hoc-bus@fc460000 { + compatible = "qcom,msm-bus-device"; + reg = <0xFC460000 0x5880>, + <0xFC380000 0x80000>, + <0xFC468000 0x2400>, + <0xFC478000 0x3480>, + <0xFC480000 0x80>; + reg-names = "snoc-base", "bimc-base", "pnoc-base", "mnoc-base", "cnoc-base"; + + fab_snoc: fab-snoc { + cell-id = ; + label = "fab-snoc"; + qcom,fab-dev; + qcom,base-name = "snoc-base"; + qcom,base-offset = <0x5000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_snoc_msmbus_clk>, + <&clock_rpm clk_snoc_msmbus_a_clk>; + + coresight-id = <50>; + coresight-name = "coresight-snoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <3>; + }; + + fab_bimc: fab-bimc { + cell-id = ; + label = "fab-bimc"; + qcom,fab-dev; + qcom,base-name = "bimc-base"; + qcom,bus-type = <2>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_bimc_msmbus_clk>, + <&clock_rpm clk_bimc_msmbus_a_clk>; + + coresight-id = <55>; + coresight-name = "coresight-bimc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <3>; + }; + + fab_pnoc: fab-pnoc { + cell-id = ; + label = "fab-pnoc"; + qcom,fab-dev; + qcom,base-name = "pnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_pnoc_msmbus_clk>, + <&clock_rpm clk_pnoc_msmbus_a_clk>; + + coresight-id = <54>; + coresight-name = "coresight-pnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <6>; + }; + + fab_mnoc: fab-mnoc { + cell-id = ; + label = "fab-mnoc"; + qcom,fab-dev; + qcom,base-name = "mnoc-base"; + qcom,base-offset = <0x3000>; + qcom,bus-type = <1>; + qcom,qos-off = <0x80>; + qcom,util-fact = <153>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_mmss clk_mmss_s0_axi_clk>, + <&clock_mmss clk_mmss_s0_axi_clk>; + + coresight-id = <56>; + coresight-name = "coresight-mmnoc"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <5>; + }; + + fab_cnoc: fab-cnoc { + cell-id = ; + label = "fab-cnoc"; + qcom,fab-dev; + qcom,base-name = "cnoc-base"; + qcom,base-offset = <0x3000>; + qcom,qos-off = <0x80>; + qcom,bus-type = <1>; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_cnoc_msmbus_clk>, + <&clock_rpm clk_cnoc_msmbus_a_clk>; + }; + + fab_ovirt: fab-ovirt { + cell-id = ; + label = "fab-ovirt"; + qcom,fab-dev; + qcom,bypass-qos-prg; + qcom,virt-dev; + clock-names = "bus_clk", "bus_a_clk"; + clocks = <&clock_rpm clk_ocmemgx_msmbus_clk>, + <&clock_rpm clk_ocmemgx_msmbus_a_clk >; + }; + + + /* bimc Devices */ + mas_apps_proc: mas-apps-proc { + cell-id = ; + label = "mas-apps-proc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&bimc_int_apps_ebi &bimc_int_apps_snoc>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ws = <10000>; + qcom,gp = <5000>; + qcom,thmp = <50>; + qcom,ap-owned; + }; + + bimc_int_apps_ebi: bimc-int-apps-ebi { + cell-id = ; + label = "bimc-int-apps-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_ebi>; + }; + + bimc_int_apps_snoc: bimc-int-apps-snoc { + cell-id = ; + label = "bimc-int-apps-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,connections = <&slv_bimc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_oxili: mas-oxili { + cell-id = ; + label = "mas-oxili"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <2>; + qcom,qos-mode = "fixed"; + qcom,prio-lvl = <0>; + qcom,prio-rd = <0>; + qcom,prio-wr = <0>; + qcom,ap-owned; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + }; + + + mas_mnoc_bimc: mas-mnoc-bimc { + cell-id = ; + label = "mas-mnoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2 &slv_bimc_snoc>; + qcom,ap-owned; + }; + + + mas_snoc_bimc: mas-snoc-bimc { + cell-id = ; + label = "mas-snoc-bimc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_ebi &slv_appss_l2>; + qcom,mas-rpm-id = ; + }; + + + slv_ebi: slv-ebi { + cell-id = ; + label = "slv-ebi"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,qport = <0 1>; + qcom,slv-rpm-id = ; + }; + + + slv_appss_l2: slv-appss-l2 { + cell-id = ; + label = "slv-appss-l2"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_snoc: slv-bimc-snoc { + cell-id = ; + label = "slv-bimc-snoc"; + qcom,bus-dev = <&fab_bimc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_bimc_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* mnoc Devices */ + mas_cnoc_mnoc_mmss_cfg: mas-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_camera_cfg &slv_cpr_cfg &slv_cpr_xpu_cfg + &slv_ocmem_cfg &slv_misc_cfg &slv_misc_xpu_cfg + &slv_oxili_cfg &slv_venus_cfg &slv_mnoc_clocks_cfg + &slv_mnoc_clocks_xpu_cfg &slv_mnoc_mpu_cfg &slv_display_cfg + &slv_avsync_cfg &slv_vpu_cfg>; + qcom,ap-owned; + }; + + + mas_cnoc_mnoc_cfg: mas-cnoc-mnoc-cfg { + cell-id = ; + label = "mas-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,connections = <&slv_srvc_mnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_gemini: mas-gemini { + cell-id = ; + label = "mas-gemini"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <0>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p0: mas-mdp-p0 { + cell-id = ; + label = "mas-mdp-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <2>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_mdp_p1: mas-mdp-p1 { + cell-id = ; + label = "mas-mdp-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <1>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p0: mas-venus-p0 { + cell-id = ; + label = "mas-venus-p0"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <3>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_venus_p1: mas-venus-p1 { + cell-id = ; + label = "mas-venus-p1"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <4>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + mas_vfe: mas-vfe { + cell-id = ; + label = "mas-vfe"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <6>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_cpp: mas-cpp { + cell-id = ; + label = "mas-cpp"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <5>; + qcom,qos-mode = "bypass"; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + mas_vpu: mas-vpu { + cell-id = ; + label = "mas-vpu"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qos-mode = "bypass"; + qcom,qport = <8>; + qcom,connections = <&slv_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_camera_cfg: slv-camera-cfg { + cell-id = ; + label = "slv-camera-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_cfg: slv-cpr-cfg { + cell-id = ; + label = "slv-cpr-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_cpr_xpu_cfg: slv-cpr-xpu-cfg { + cell-id = ; + label = "slv-cpr-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_ocmem_cfg: slv-ocmem-cfg { + cell-id = ; + label = "slv-ocmem-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_cfg: slv-misc-cfg { + cell-id = ; + label = "slv-misc-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_misc_xpu_cfg: slv-misc-xpu-cfg { + cell-id = ; + label = "slv-misc-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_oxili_cfg: slv-oxili-cfg { + cell-id = ; + label = "slv-oxili-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_venus_cfg: slv-venus-cfg { + cell-id = ; + label = "slv-venus-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_cfg: slv-mnoc-clocks-cfg { + cell-id = ; + label = "slv-mnoc-clocks-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_clocks_xpu_cfg: slv-mnoc-clocks-xpu-cfg { + cell-id = ; + label = "slv-mnoc-clocks-xpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_mpu_cfg: slv-mnoc-mpu-cfg { + cell-id = ; + label = "slv-mnoc-mpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_display_cfg: slv-display-cfg { + cell-id = ; + label = "slv-display-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_avsync_cfg: slv-avsync-cfg { + cell-id = ; + label = "slv-avsync-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_vpu_cfg: slv-vpu-cfg { + cell-id = ; + label = "slv-vpu-cfg"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + slv_mnoc_bimc: slv-mnoc-bimc { + cell-id = ; + label = "slv-mnoc-bimc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,qport = <16 17>; + qcom,connections = <&mas_mnoc_bimc>; + qcom,ap-owned; + }; + + + slv_srvc_mnoc: slv-srvc-mnoc { + cell-id = ; + label = "slv-srvc-mnoc"; + qcom,bus-dev = <&fab_mnoc>; + qcom,buswidth = <16>; + qcom,slv-rpm-id = ; + }; + + + /* snoc Devices */ + mas_lpass_ahb: mas-lpass-ahb { + cell-id = ; + label = "mas-lpass-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <0>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_ocimem &slv_snoc_pnoc>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_bam: mas-qdss-bam { + cell-id = ; + label = "mas-qdss-bam"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <1>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc &slv_usb3>; + qcom,ap-owned; + }; + + + mas_bimc_snoc: mas-bimc-snoc { + cell-id = ; + label = "mas-bimc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_cnoc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + mas_cnoc_snoc: mas-cnoc-snoc { + cell-id = ; + label = "mas-cnoc-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_kpss_ahb &slv_lpass &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_crypto_c0: mas-crypto-c0 { + cell-id = ; + label = "mas-crypto-c0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <2>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c1: mas-crypto-c1 { + cell-id = ; + label = "mas-crypto-c1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <3>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_crypto_c2: mas-crypto-c2 { + cell-id = ; + label = "mas-crypto-c2"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,qport = <9>; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_ocimem &slv_snoc_ovirt &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_lpass_proc: mas-lpass-proc { + cell-id = ; + label = "mas-lpass-proc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <4>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt &slv_snoc_pnoc &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_ovirt_snoc: mas-ovirt-snoc { + cell-id = ; + label = "mas-ovirt-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <5>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_snoc_bimc>; + qcom,mas-rpm-id = ; + }; + + + mas_periph_snoc: mas-periph-snoc { + cell-id = ; + label = "mas-periph-snoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <13>; + qcom,qos-mode = "fixed"; + qcom,connections = <&slv_lpass &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_qdss_stm>; + qcom,mas-rpm-id = ; + }; + + + mas_pcie_0: mas-pcie-0 { + cell-id = ; + label = "mas-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <7>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_pcie_1: mas-pcie-1 { + cell-id = ; + label = "mas-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <16>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_kpss_ahb &slv_snoc_bimc &slv_ocimem>; + qcom,ap-owned; + }; + + + mas_qdss_etr: mas-qdss-etr { + cell-id = ; + label = "mas-qdss-etr"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ufs: mas-ufs { + cell-id = ; + label = "mas-ufs"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_snoc_bimc &slv_snoc_cnoc &slv_ocimem + &slv_snoc_ovirt>; + qcom,ap-owned; + }; + + + mas_usb3: mas-usb3 { + cell-id = ; + label = "mas-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_lpass &slv_usb3 &slv_snoc_bimc + &slv_snoc_cnoc &slv_ocimem &slv_snoc_pnoc>; + qcom,ap-owned; + }; + + + mas_ipa: mas-ipa { + cell-id = ; + label = "mas-ipa"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,qport = <15>; + qcom,qos-mode = "fixed"; + qcom,prio1 = <1>; + qcom,prio0 = <1>; + qcom,connections = <&slv_usb3 &slv_snoc_bimc &slv_snoc_cnoc + &slv_ocimem &slv_pcie_0 &slv_snoc_pnoc &slv_qdss_stm>; + qcom,ap-owned; + }; + + + slv_kpss_ahb: slv-kpss-ahb { + cell-id = ; + label = "slv-kpss-ahb"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_lpass: slv-lpass { + cell-id = ; + label = "slv-lpass"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_bimc: slv-snoc-bimc { + cell-id = ; + label = "slv-snoc-bimc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_bimc>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cnoc: slv-snoc-cnoc { + cell-id = ; + label = "slv-snoc-cnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_cnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_ocimem: slv-ocimem { + cell-id = ; + label = "slv-ocimem"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_ovirt: slv-snoc-ovirt { + cell-id = ; + label = "slv-snoc-ovirt"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_ovirt>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_pnoc: slv-snoc-pnoc { + cell-id = ; + label = "slv-snoc-pnoc"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_snoc_pnoc>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_stm: slv-qdss-stm { + cell-id = ; + label = "slv-qdss-stm"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + slv_usb3: slv-usb3 { + cell-id = ; + label = "slv-usb3"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0: slv-pcie-0 { + cell-id = ; + label = "slv-pcie-0"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1: slv-pcie-1 { + cell-id = ; + label = "slv-pcie-1"; + qcom,bus-dev = <&fab_snoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + /* ovirt Devices */ + mas_snoc_ovirt: mas-snoc-ovirt { + cell-id = ; + label = "mas-snoc-ovirt"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + mas_ocmem_dma: mas-ocmem-dma { + cell-id = ; + label = "mas-ocmem-dma"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem &slv_ovirt_snoc>; + qcom,ap-owned; + }; + + + mas_oxili_ocmem: mas-oxili-ocmem { + cell-id = ; + label = "mas-oxili-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem_gfx>; + qcom,ap-owned; + }; + + + mas_venus_ocmem: mas-venus-ocmem { + cell-id = ; + label = "mas-venus-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&slv_ocmem>; + qcom,ap-owned; + }; + + + slv_ocmem: slv-ocmem { + cell-id = ; + label = "slv-ocmem"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <16>; + qcom,ap-owned; + clock-names = "node_clk"; + clocks = <&clock_mmss clk_ocmemnoc_clk_src>; + }; + + slv_ocmem_gfx: slv-ocmem-gfx { + cell-id = ; + label = "slv-ocmem-gfx"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + }; + + + slv_ovirt_snoc: slv-ovirt-snoc { + cell-id = ; + label = "slv-ovirt-snoc"; + qcom,bus-dev = <&fab_ovirt>; + qcom,buswidth = <32>; + qcom,connections = <&mas_ovirt_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* pnoc Devices */ + mas_bam_dma: mas-bam-dma { + cell-id = ; + label = "mas-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_sdcc_1 &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_2: mas-blsp-2 { + cell-id = ; + label = "mas-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_blsp_1: mas-blsp-1 { + cell-id = ; + label = "mas-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tsif: mas-tsif { + cell-id = ; + label = "mas-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_usb_hs: mas-usb-hs { + cell-id = ; + label = "mas-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 + &slv_tsif &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_pnoc_cfg: mas-pnoc-cfg { + cell-id = ; + label = "mas-pnoc-cfg"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_prng>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_1: mas-sdcc-1 { + cell-id = ; + label = "mas-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_3 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_2: mas-sdcc-2 { + cell-id = ; + label = "mas-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_3: mas-sdcc-3 { + cell-id = ; + label = "mas-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_blsp_2 + &slv_sdcc_2 &slv_sdcc_4 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_sdcc_4: mas-sdcc-4 { + cell-id = ; + label = "mas-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_blsp_2 &slv_sdcc_2 &slv_blsp_1 &slv_tsif + &slv_usb_hs &slv_periph_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_pnoc: mas-snoc-pnoc { + cell-id = ; + label = "mas-snoc-pnoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bam_dma &slv_sdcc_1 &slv_sdcc_3 + &slv_sdcc_2 &slv_sdcc_4 + &slv_blsp_2 &slv_blsp_1 &slv_tsif &slv_usb_hs + &slv_pdm &slv_prng>; + qcom,mas-rpm-id = ; + }; + + + slv_bam_dma: slv-bam-dma { + cell-id = ; + label = "slv-bam-dma"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_1: slv-sdcc-1 { + cell-id = ; + label = "slv-sdcc-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_3: slv-sdcc-3 { + cell-id = ; + label = "slv-sdcc-3"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_2: slv-blsp-2 { + cell-id = ; + label = "slv-blsp-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_2: slv-sdcc-2 { + cell-id = ; + label = "slv-sdcc-2"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_sdcc_4: slv-sdcc-4 { + cell-id = ; + label = "slv-sdcc-4"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_blsp_1: slv-blsp-1 { + cell-id = ; + label = "slv-blsp-1"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tsif: slv-tsif { + cell-id = ; + label = "slv-tsif"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_usb_hs: slv-usb-hs { + cell-id = ; + label = "slv-usb-hs"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pdm: slv-pdm { + cell-id = ; + label = "slv-pdm"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_prng: slv-prng { + cell-id = ; + label = "slv-prng"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_periph_snoc: slv-periph-snoc { + cell-id = ; + label = "slv-periph-snoc"; + qcom,bus-dev = <&fab_pnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_periph_snoc>; + qcom,slv-rpm-id = ; + }; + + + /* cnoc Devices */ + mas_rpm_inst: mas-rpm-inst { + cell-id = ; + label = "mas-rpm-inst"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_boot_rom>; + qcom,mas-rpm-id = ; + }; + + + mas_rpm_sys: mas-rpm-sys { + cell-id = ; + label = "mas-rpm-sys"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg + &slv_security &slv_tcsr &slv_tlmm &slv_crypto_0_cfg + &slv_crypto_1_cfg &slv_imem_cfg &slv_message_ram + &slv_bimc_cfg &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper + &slv_dehr_cfg &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg + &slv_snoc_cfg &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg + &slv_phy_apu_cfg &slv_ebi1_phy_cfg &slv_pcie_0_cfg + &slv_pcie_1_cfg &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_dehr: mas-dehr { + cell-id = ; + label = "mas-dehr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_bimc_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_spdm: mas-spdm { + cell-id = ; + label = "mas-spdm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_tic: mas-tic { + cell-id = ; + label = "mas-tic"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + mas_snoc_cnoc: mas-snoc-cnoc { + cell-id = ; + label = "mas-snoc-cnoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg>; + qcom,mas-rpm-id = ; + }; + + + mas_qdss_dap: mas-qdss-dap { + cell-id = ; + label = "mas-qdss-dap"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&slv_clk_ctl &slv_crypto_2_cfg &slv_security + &slv_tcsr &slv_tlmm &slv_crypto_0_cfg &slv_crypto_1_cfg + &slv_imem_cfg &slv_message_ram &slv_bimc_cfg &slv_boot_rom + &slv_cnoc_mnoc_mmss_cfg &slv_spdm_wrapper &slv_dehr_cfg + &slv_mpm &slv_qdss_cfg &slv_pnoc_cfg &slv_snoc_cfg + &slv_snoc_mpu_cfg &slv_ebi1_dll_cfg &slv_phy_apu_cfg + &slv_ebi1_phy_cfg &slv_rpm &slv_pcie_0_cfg &slv_pcie_1_cfg + &slv_spss_geni_ir &slv_ufs_cfg &slv_cnoc_snoc>; + qcom,mas-rpm-id = ; + }; + + + slv_clk_ctl: slv-clk-ctl { + cell-id = ; + label = "slv-clk-ctl"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_2_cfg: slv-crypto-2-cfg { + cell-id = ; + label = "slv-crypto-2-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_security: slv-security { + cell-id = ; + label = "slv-security"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tcsr: slv-tcsr { + cell-id = ; + label = "slv-tcsr"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_tlmm: slv-tlmm { + cell-id = ; + label = "slv-tlmm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_0_cfg: slv-crypto-0-cfg { + cell-id = ; + label = "slv-crypto-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_crypto_1_cfg: slv-crypto-1-cfg { + cell-id = ; + label = "slv-crypto-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_imem_cfg: slv-imem-cfg { + cell-id = ; + label = "slv-imem-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_message_ram: slv-message-ram { + cell-id = ; + label = "slv-message-ram"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_bimc_cfg: slv-bimc-cfg { + cell-id = ; + label = "slv-bimc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_boot_rom: slv-boot-rom { + cell-id = ; + label = "slv-boot-rom"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_mmss_cfg: slv-cnoc-mnoc-mmss-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-mmss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_mmss_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pmic_arb: slv-pmic-arb { + cell-id = ; + label = "slv-pmic-arb"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spdm_wrapper: slv-spdm-wrapper { + cell-id = ; + label = "slv-spdm-wrapper"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_dehr_cfg: slv-dehr-cfg { + cell-id = ; + label = "slv-dehr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_mpm: slv-mpm { + cell-id = ; + label = "slv-mpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_qdss_cfg: slv-qdss-cfg { + cell-id = ; + label = "slv-qdss-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_qdss_apu_cfg: slv-rbcpr-qdss-apu-cfg { + cell-id = ; + label = "slv-rbcpr-qdss-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rbcpr_cfg: slv-rbcpr-cfg { + cell-id = ; + label = "slv-rbcpr-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_mnoc_cfg: slv-cnoc-mnoc-cfg { + cell-id = ; + label = "slv-cnoc-mnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_mnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_pnoc_cfg: slv-pnoc-cfg { + cell-id = ; + label = "slv-pnoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_pnoc_cfg>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_cfg: slv-snoc-cfg { + cell-id = ; + label = "slv-snoc-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_snoc_mpu_cfg: slv-snoc-mpu-cfg { + cell-id = ; + label = "slv-snoc-mpu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_dll_cfg: slv-ebi1-dll-cfg { + cell-id = ; + label = "slv-ebi1-dll-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_phy_apu_cfg: slv-phy-apu-cfg { + cell-id = ; + label = "slv-phy-apu-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ebi1_phy_cfg: slv-ebi1-phy-cfg { + cell-id = ; + label = "slv-ebi1-phy-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_rpm: slv-rpm { + cell-id = ; + label = "slv-rpm"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_0_cfg: slv-pcie-0-cfg { + cell-id = ; + label = "slv-pcie-0-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_pcie_1_cfg: slv-pcie-1-cfg { + cell-id = ; + label = "slv-pcie-1-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_spss_geni_ir: slv-spss-geni-ir { + cell-id = ; + label = "slv-spss-geni-ir"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,slv-rpm-id = ; + }; + + + slv_ufs_cfg: slv-ufs-cfg { + cell-id = ; + label = "slv-ufs-cfg"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,ap-owned; + qcom,slv-rpm-id = ; + }; + + + slv_cnoc_snoc: slv-cnoc-snoc { + cell-id = ; + label = "slv-cnoc-snoc"; + qcom,bus-dev = <&fab_cnoc>; + qcom,buswidth = <8>; + qcom,connections = <&mas_cnoc_snoc>; + qcom,slv-rpm-id = ; + }; + }; + + static-rules { + compatible = "qcom,msm-bus-static-bw-rules"; + + rule0 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <250000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <600000>; + }; + + rule1 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + qcom,dest-bw = <900000>; + }; + + rule2 { + qcom,src-nodes = <&mas_apps_proc>; + qcom,src-field = ; + qcom,src-op = ; + qcom,thresh = <307000>; + qcom,mode = ; + qcom,dest-node = <&mas_apps_proc>; + }; + }; + + devfreq_spdm_cpu { + compatible = "qcom,devfreq_spdm"; + qcom,msm-bus,name = "devfreq_spdm"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 512 0 0>, + <1 512 0 0>; + qcom,msm-bus,active-only; + qcom,spdm-client = <0>; + + clock-names = "cci_clk"; + clocks = <&clock_cpu clk_cci_clk>; + + qcom,bw-upstep = <1000>; + qcom,bw-dwnstep = <1000>; + qcom,max-vote = <10000>; + qcom,up-step-multp = <2>; + qcom,spdm-interval = <100>; + + qcom,ports = <16>; + qcom,alpha-up = <7>; + qcom,alpha-down = <15>; + qcom,bucket-size = <8>; + + /*max pl1 freq, max pl2 freq*/ + qcom,pl-freqs = <140000000 160000000>; + + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,reject-rate = <5000 5000 5000 5000 5000 5000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,response-time-us = <10000 10000 10000 10000 3000 3000>; + /* pl1 low, pl1 high, pl2 low, pl2 high, pl3 low, pl3 high */ + qcom,cci-response-time-us = <10000 10000 10000 10000 1000 1000>; + qcom,max-cci-freq = <600000000>; + }; + + devfreq_spdm_gov { + compatible = "qcom,gov_spdm_hyp"; + interrupt-names = "spdm-irq"; + interrupts = <0 192 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-sensor-mtp.dtsi new file mode 100644 index 0000000000000..f086302c5c958 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-sensor-mtp.dtsi @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + led_flash0: qcom,camera-flash { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-type = <1>; + qcom,flash-source = <&pmi8994_flash0 &pmi8994_flash1>; + qcom,torch-source = <&pmi8994_torch0 &pmi8994_torch1>; + }; +}; + +&cci { +//added by Likelong 2015.3.23 for proximity sensor start + proximity:qcom,proximity@0 { + cell-index = <0>; + reg = <0x29>; + compatible = "stmv,vl6180"; + qcom,cci-master = <0>;//use the same I2C bus with main camera + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.3.23 for proximity sensor end + + actuator0: qcom,actuator@0 { + cell-index = <0>; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + reg = <0x1C>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; +/* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&pm8994_l23>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <100000>; + }; + +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + ois0: qcom,ois@0 { + cell-index = <0>; + reg = <0x1C>; + compatible = "qcom,ois"; + qcom,cci-master = <0>; + /* deleted by zhangxiaowei@camera 201503221 for gpio control VAF functions */ + //cam_vaf-supply = <&pm8994_l23>; + //qcom,cam-vreg-name = "cam_vaf"; + //qcom,cam-vreg-min-voltage = <2800000>; + //qcom,cam-vreg-max-voltage = <2800000>; + //qcom,cam-vreg-op-mode = <100000>; + }; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + reg = <0x0>; + qcom,eeprom-name = "ov13860"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <7>; + + qcom,page0 = <0 0x0000 2 0x00 1 5>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <47 0x0000 2 0 1 0>; + + qcom,page1 = <0 0x0000 2 0x00 1 5>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0xa0>; + qcom,mem1 = <40 0x0100 2 0 1 0>; + + qcom,page2 = <0 0x0000 2 0x00 1 5>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0xa0>; + qcom,mem2 = <255 0x0200 2 0 1 0>; + + qcom,page3 = <0 0x0000 2 0x00 1 5>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0xa0>; + qcom,mem3 = <255 0x0300 2 0 1 0>; + + qcom,page4 = <0 0x0000 2 0x00 1 5>; + qcom,pageen4 = <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0xa0>; + qcom,mem4 = <255 0x0400 2 0 1 0>; + + qcom,page5 = <0 0x0000 2 0x00 1 5>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0xa0>; + qcom,mem5 = <255 0x0500 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0xa0>; + qcom,mem6 = <89 0x0600 2 0 1 0>; + +/* Kangjian,201/12/18,Add for camera driver */ + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000>; + /*#endif*/ + + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + <&msm_gpio 102 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,cam-power-seq-type = "sensor_gpio", "sensor_vreg", "sensor_vreg", "sensor_vreg", + "sensor_gpio", "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "sensor_gpio_standby", "cam_vio", "cam_vana", "cam_vdig", + "sensor_gpio_reset","sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <1 0 0 0 1 24000000 0>; + qcom,cam-power-seq-delay = <0 0 0 0 0 0 0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; + +/*muyuezhong@camera,2015-4-29,add for ov5648 OTP functions begin*/ + eeprom1: qcom,eeprom@1 { + cell-index = <2>; + reg = <0x2>; + qcom,eeprom-name = "ov5648"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0x6c>; + qcom,cci-master = <1>; + qcom,num-blocks = <26>; + + //read group 1:begin + qcom,page0 = <1 0x0103 2 0x01 1 0>; + qcom,pageen0 = <0 0x0000 2 0x00 1 5>; + qcom,poll0 = <0 0x0000 2 0x00 1 5>; + qcom,saddr0 = <0x6c>; + qcom,mem0 = <0 0x0000 2 0 1 0>; + + qcom,page1 = <1 0x0100 2 0x01 1 0>; + qcom,pageen1 = <0 0x0000 2 0x00 1 5>; + qcom,poll1 = <0 0x0000 2 0x00 1 5>; + qcom,saddr1 = <0x6c>; + qcom,mem1 = <0 0x0000 2 0 1 0>; + + qcom,page2 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen2 = <0 0x0000 2 0x00 1 5>; + qcom,poll2 = <0 0x0000 2 0x00 1 5>; + qcom,saddr2 = <0x6c>; + qcom,mem2 = <0 0x0000 2 0 1 0>; + + qcom,page3 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen3 = <0 0x0000 2 0x00 1 5>; + qcom,poll3 = <0 0x0000 2 0x00 1 5>; + qcom,saddr3 = <0x6c>; + qcom,mem3 = <0 0x0000 2 0 1 0>; + + qcom,page4 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen4= <0 0x0000 2 0x00 1 5>; + qcom,poll4 = <0 0x0000 2 0x00 1 5>; + qcom,saddr4 = <0x6c>; + qcom,mem4 = <0 0x0000 2 0 1 0>; + + qcom,page5 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen5 = <0 0x0000 2 0x00 1 5>; + qcom,poll5 = <0 0x0000 2 0x00 1 5>; + qcom,saddr5 = <0x6c>; + qcom,mem5 = <0 0x0000 2 0 1 0>; + + qcom,page6 = <0 0x0000 2 0x00 1 5>; + qcom,pageen6 = <0 0x0000 2 0x00 1 5>; + qcom,poll6 = <0 0x0000 2 0x00 1 5>; + qcom,saddr6 = <0x6c>; + qcom,mem6 = <9 0x3d05 2 0 1 0>; + + qcom,page7 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen7 = <16 0x3d00 2 0x00 1 0>; + qcom,poll7 = <0 0x0000 2 0x00 1 5>; + qcom,saddr7 = <0x6c>; + qcom,mem7 = <0 0x0000 2 0 1 0>; + //read group 1:end +/*muyuezhong@camera,2015-8-12,add for other otp group*/ + //read group 2:begin + qcom,page8 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen8 = <0 0x0000 2 0x00 1 5>; + qcom,poll8 = <0 0x0000 2 0x00 1 5>; + qcom,saddr8 = <0x6c>; + qcom,mem8 = <0 0x0000 2 0 1 0>; + + qcom,page9 = <1 0x3d85 2 0x00 1 0>; + qcom,pageen9 = <0 0x0000 2 0x00 1 5>; + qcom,poll9 = <0 0x0000 2 0x00 1 5>; + qcom,saddr9 = <0x6c>; + qcom,mem9 = <0 0x0000 2 0 1 0>; + + qcom,page10 = <1 0x3d86 2 0x0f 1 0>; + qcom,pageen10= <0 0x0000 2 0x00 1 5>; + qcom,poll10 = <0 0x0000 2 0x00 1 5>; + qcom,saddr10 = <0x6c>; + qcom,mem10 = <0 0x0000 2 0 1 0>; + + qcom,page11 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen11 = <0 0x0000 2 0x00 1 5>; + qcom,poll11 = <0 0x0000 2 0x00 1 5>; + qcom,saddr11 = <0x6c>; + qcom,mem11 = <0 0x0000 2 0 1 0>; + + qcom,page12 = <0 0x0000 2 0x00 1 5>; + qcom,pageen12 = <0 0x0000 2 0x00 1 5>; + qcom,poll12 = <0 0x0000 2 0x00 1 5>; + qcom,saddr12 = <0x6c>; + qcom,mem12 = <2 0x3d0e 2 0 1 0>; + + qcom,page13 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen13 = <0 0x0000 2 0x00 1 5>; + qcom,poll13 = <0 0x0000 2 0x00 1 5>; + qcom,saddr13 = <0x6c>; + qcom,mem13 = <0 0x0000 2 0 1 0>; + + qcom,page14 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen14 = <0 0x0000 2 0x00 1 5>; + qcom,poll14 = <0 0x0000 2 0x00 1 5>; + qcom,saddr14 = <0x6c>; + qcom,mem14 = <0 0x0000 2 0 1 0>; + + qcom,page15 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen15= <0 0x0000 2 0x00 1 5>; + qcom,poll15 = <0 0x0000 2 0x00 1 5>; + qcom,saddr15 = <0x6c>; + qcom,mem15 = <0 0x0000 2 0 1 0>; + + qcom,page16 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen16 = <0 0x0000 2 0x00 1 5>; + qcom,poll16 = <0 0x0000 2 0x00 1 5>; + qcom,saddr16 = <0x6c>; + qcom,mem16 = <0 0x0000 2 0 1 0>; + + qcom,page17 = <0 0x0000 2 0x00 1 5>; + qcom,pageen17 = <0 0x0000 2 0x00 1 5>; + qcom,poll17 = <0 0x0000 2 0x00 1 5>; + qcom,saddr17 = <0x6c>; + qcom,mem17 = <7 0x3d00 2 0 1 0>; + + qcom,page18 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen18 = <16 0x3d00 2 0x00 1 0>; + qcom,poll18 = <0 0x0000 2 0x00 1 5>; + qcom,saddr18 = <0x6c>; + qcom,mem18 = <0 0x0000 2 0 1 0>; + //read group 2:end + + //read group 3:begin + qcom,page19 = <1 0x3d84 2 0xc0 1 0>; + qcom,pageen19 = <0 0x0000 2 0x00 1 5>; + qcom,poll19 = <0 0x0000 2 0x00 1 5>; + qcom,saddr19 = <0x6c>; + qcom,mem19 = <0 0x0000 2 0 1 0>; + + qcom,page20 = <1 0x3d85 2 0x10 1 0>; + qcom,pageen20 = <0 0x0000 2 0x00 1 5>; + qcom,poll20 = <0 0x0000 2 0x00 1 5>; + qcom,saddr20 = <0x6c>; + qcom,mem20 = <0 0x0000 2 0 1 0>; + + qcom,page21 = <1 0x3d86 2 0x1f 1 0>; + qcom,pageen21= <0 0x0000 2 0x00 1 5>; + qcom,poll21 = <0 0x0000 2 0x00 1 5>; + qcom,saddr21 = <0x6c>; + qcom,mem21 = <0 0x0000 2 0 1 0>; + + qcom,page22 = <1 0x3d81 2 0x01 1 0>; + qcom,pageen22 = <0 0x0000 2 0x00 1 5>; + qcom,poll22 = <0 0x0000 2 0x00 1 5>; + qcom,saddr22 = <0x6c>; + qcom,mem22 = <0 0x0000 2 0 1 0>; + + qcom,page23 = <0 0x0000 2 0x00 1 5>; + qcom,pageen23 = <0 0x0000 2 0x00 1 5>; + qcom,poll23 = <0 0x0000 2 0x00 1 5>; + qcom,saddr23 = <0x6c>; + qcom,mem23 = <9 0x3d07 2 0 1 0>; + + qcom,page24 = <0 0x3d00 2 0x00 1 5>; + qcom,pageen24 = <16 0x3d00 2 0x00 1 0>; + qcom,poll24 = <0 0x0000 2 0x00 1 5>; + qcom,saddr24 = <0x6c>; + qcom,mem24 = <0 0x0000 2 0 1 0>; + + qcom,page25 = <1 0x0100 2 0x00 1 0>; + qcom,pageen25 = <0 0x0000 2 0x00 1 5>; + qcom,poll25 = <0 0x0000 2 0x00 1 5>; + qcom,saddr25 = <0x6c>; + qcom,mem25= <0 0x0000 2 0 1 0>; + //read group 3:end + + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2","CAM_RESET2","CAM_STANDBY2"; + + qcom,cam-power-seq-type = "sensor_vreg","sensor_vreg", "sensor_gpio", "sensor_gpio", + "sensor_clk","sensor_i2c_mux"; + qcom,cam-power-seq-val = "cam_vio","cam_vana", "sensor_gpio_reset", "sensor_gpio_standby", + "sensor_cam_mclk","none"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 24000000 0>; + qcom,cam-power-seq-delay = <0 5 0 0 0 0>; + + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>,<&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* muyuezhong@camera,2015-4-29,add for ov5648 OTP functions end*/ + +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ +/* + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <2>; + qcom,eeprom-name = "onsemi_cat24c32"; + compatible = "qcom,eeprom"; + qcom,slave-addr = <0xa0>; + qcom,cci-master = <0>; + qcom,num-blocks = <1>; + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xa0>; + qcom,mem0 = <2245 0x00 2 0 1 0>; + + cam_vio-supply = <&pm8994_lvs1>; + qcom,cam-vreg-name = "cam_vio"; + qcom,cam-vreg-min-voltage = <0>; + qcom,cam-vreg-max-voltage = <0>; + qcom,cam-vreg-op-mode = <0>; + qcom,cam-power-seq-type = "sensor_vreg"; + qcom,cam-power-seq-val = "cam_vio"; + qcom,cam-power-seq-cfg-val = <1>; + qcom,cam-power-seq-delay = <1>; + status = "ok"; + }; +*/ +/* added by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom0>; + qcom,actuator-src = <&actuator0>; +/* added by zhangxiaowei@camera 20150310 for qcom OIS architecture */ + qcom,ois-src = <&ois0>; + qcom,led-flash-src = <&led_flash0>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + cam_v_custom1-supply = <&pm8994_l29>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", + "cam_v_custom1"; + /*liuyan 2015/7/20, change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*qcom,cam-vreg-min-voltage = <1200000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000 2800000>;*/ + /*#else*/ + qcom,cam-vreg-min-voltage = <1250000 1800000 2700000 2800000>; + qcom,cam-vreg-max-voltage = <1250000 1800000 2700000 2800000>; + /*#endif*/ + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; + gpios = <&msm_gpio 13 0>, + <&msm_gpio 92 0>, + <&msm_gpio 102 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-vaf = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0 >; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0", + "CAM_VAF0"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +/* + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 0 2700000>; + qcom,cam-vreg-max-voltage = <1200000 0 2700000>; + qcom,cam-vreg-op-mode = <105000 0 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend &cam_sensor_rear2_suspend>; + gpios = <&msm_gpio 14 0>, + <&msm_gpio 94 0>, + <&msm_gpio 93 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_STANDBY1"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +*/ + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <270>; + qcom,eeprom-src = <&eeprom1>; + //qcom,actuator-src = <&actuator1>; + cam_vdig-supply = <&pm8994_l3>; + cam_vio-supply = <&pm8994_lvs1>; + cam_vana-supply = <&pm8994_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; + qcom,cam-vreg-min-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-max-voltage = <1200000 1800000 2700000>; + qcom,cam-vreg-op-mode = <105000 80000 80000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_front_suspend>; + gpios = <&msm_gpio 15 0>, + <&msm_gpio 104 0>, + <&msm_gpio 105 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + }; +}; +/* Kangjian,2014/12/18,Add end */ diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v1.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v1.dtsi new file mode 100755 index 0000000000000..b1c810d391efe --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v1.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x44441111 + 0x00000103>; + max-clk-nominal = <400000000>; + max-clk-turbo = <533330000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v2.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v2.dtsi new file mode 100755 index 0000000000000..b101e98dde0dd --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera-v2.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&vfe0 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; + +&vfe1 { + qos-entries = <8>; + qos-regs = <0x378 0x37C 0x380 0x384 0x388 0x38C + 0x390 0x394>; + qos-settings = <0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0xAAA9AAA9 + 0x0001AAA9>; + vbif-entries = <1>; + vbif-regs = <0x124>; + vbif-settings = <0x3>; + ds-entries = <17>; + ds-regs = <0xBD8 0xBDC 0xBE0 0xBE4 0xBE8 + 0xBEC 0xBF0 0xBF4 0xBF8 0xBFC 0xC00 + 0xC04 0xC08 0xC0C 0xC10 0xC14 0xC18>; + ds-settings = <0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0xCCCC1111 + 0x00000103>; + max-clk-nominal = <465000000>; + max-clk-turbo = <600000000>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-camera.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera.dtsi new file mode 100755 index 0000000000000..03e578bcf4121 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-camera.dtsi @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,msm-cam@fd8c0000 { + compatible = "qcom,msm-cam"; + reg = <0xfd8c0000 0x10000>; + reg-names = "msm-cam"; + }; + + qcom,csiphy@fda0ac00 { + cell-index = <0>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0ac00 0x200>, + <0xfda00030 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 78 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0phy_clk>, + <&clock_mmss clk_csi0phytimer_clk_src>, + <&clock_mmss clk_camss_phy0_csi0phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b000 { + cell-index = <1>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b000 0x200>, + <0xfda00038 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 79 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1phy_clk>, + <&clock_mmss clk_csi1phytimer_clk_src>, + <&clock_mmss clk_camss_phy1_csi1phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csiphy@fda0b400 { + cell-index = <2>; + compatible = "qcom,csiphy-v3.1.1", "qcom,csiphy"; + reg = <0xfda0b400 0x200>, + <0xfda00040 0x4>; + reg-names = "csiphy", "csiphy_clk_mux"; + interrupts = <0 80 0>; + interrupt-names = "csiphy"; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2phy_clk>, + <&clock_mmss clk_csi2phytimer_clk_src>, + <&clock_mmss clk_camss_phy2_csi2phytimer_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_src_clk", + "csi_phy_clk", "csiphy_timer_src_clk", + "csiphy_timer_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 200000000 0 0>; + }; + + qcom,csid@fda08000 { + cell-index = <0>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08000 0x400>; + reg-names = "csid"; + interrupts = <0 51 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0_ahb_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08400 { + cell-index = <1>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08400 0x400>; + reg-names = "csid"; + interrupts = <0 52 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1_ahb_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08800 { + cell-index = <2>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08800 0x400>; + reg-names = "csid"; + interrupts = <0 53 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2_ahb_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,csid@fda08c00 { + cell-index = <3>; + compatible = "qcom,csid-v3.1", "qcom,csid"; + reg = <0xfda08C00 0x100>; + reg-names = "csid"; + interrupts = <0 54 0>; + interrupt-names = "csid"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3_ahb_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", + "ispif_ahb_clk", "csi_clk", "csi_ahb_clk", + "csi_src_clk", "csi_rdi_clk", + "csi_pix_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 0 240000000 0 0 0 0 0>; + }; + + qcom,ispif@fda0a000 { + cell-index = <0>; + compatible = "qcom,ispif-v3.0", "qcom,ispif"; + reg = <0xfda0A000 0x500>, + <0xfda00020 0x10>; + reg-names = "ispif", "csi_clk_mux"; + interrupts = <0 55 0>; + interrupt-names = "ispif"; + qcom,num-isps = <0x2>; + vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_ispif_ahb_clk>, + <&clock_mmss clk_csi0_clk_src>, + <&clock_mmss clk_camss_csi0_clk>, + <&clock_mmss clk_camss_csi0rdi_clk>, + <&clock_mmss clk_camss_csi0pix_clk>, + <&clock_mmss clk_csi1_clk_src>, + <&clock_mmss clk_camss_csi1_clk>, + <&clock_mmss clk_camss_csi1rdi_clk>, + <&clock_mmss clk_camss_csi1pix_clk>, + <&clock_mmss clk_csi2_clk_src>, + <&clock_mmss clk_camss_csi2_clk>, + <&clock_mmss clk_camss_csi2rdi_clk>, + <&clock_mmss clk_camss_csi2pix_clk>, + <&clock_mmss clk_csi3_clk_src>, + <&clock_mmss clk_camss_csi3_clk>, + <&clock_mmss clk_camss_csi3rdi_clk>, + <&clock_mmss clk_camss_csi3pix_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>; + clock-names = "ispif_ahb_clk", + "csi0_src_clk", "csi0_clk", + "csi0_pix_clk", "csi0_rdi_clk", + "csi1_src_clk", "csi1_clk", + "csi1_pix_clk", "csi1_rdi_clk", + "csi2_src_clk", "csi2_clk", + "csi2_pix_clk", "csi2_rdi_clk", + "csi3_src_clk", "csi3_clk", + "csi3_pix_clk", "csi3_rdi_clk", + "vfe0_clk_src", "camss_vfe_vfe0_clk", "camss_csi_vfe0_clk", + "vfe1_clk_src", "camss_vfe_vfe1_clk", "camss_csi_vfe1_clk"; + qcom,clock-rates = "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "240000000", "0", "0", "0", + "-2", "0", "0", + "-2", "0", "0"; + }; + + vfe0: qcom,vfe@fda10000 { + cell-index = <0>; + compatible = "qcom,vfe46"; + reg = <0xfda10000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 57 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe0_clk_src>, + <&clock_mmss clk_camss_vfe_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + + }; + + vfe1: qcom,vfe@fda14000 { + cell-index = <1>; + compatible = "qcom,vfe46"; + reg = <0xfda14000 0x1000>, + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; + interrupts = <0 58 0>; + interrupt-names = "vfe"; + vdd-supply = <&gdsc_vfe>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_vfe1_clk_src>, + <&clock_mmss clk_camss_vfe_vfe1_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + clock-names = "camss_top_ahb_clk" , "camss_ahb_clk", + "vfe_clk_src", "camss_vfe_vfe_clk", "camss_csi_vfe_clk", + "iface_clk", "bus_clk"; + qcom,clock-rates = <0 0 320000000 0 0 0 0>; + }; + + + qcom,jpeg@fda1c000 { + cell-index = <0>; + compatible = "qcom,jpeg"; + reg = <0xfda1c000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 59 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", + "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda20000 { + cell-index = <1>; + compatible = "qcom,jpeg"; + reg = <0xfda20000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 60 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <320000000 0 0 0 0>; + }; + + qcom,jpeg@fda24000 { + cell-index = <2>; + compatible = "qcom,jpeg"; + reg = <0xfda24000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 61 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg2_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + qcom,jpeg@fdaa0000 { + cell-index = <3>; + compatible = "qcom,jpeg_dma"; + reg = <0xfdaa0000 0x400>, + <0xfda60000 0xc30>; + reg-names = "jpeg"; + interrupts = <0 304 0>; + interrupt-names = "jpeg"; + vdd-supply = <&gdsc_jpeg>; + clock-names = "core_clk", "iface_clk", "bus_clk0", "camss_top_ahb_clk", "camss_ahb_clk"; + clocks = <&clock_mmss clk_camss_jpeg_dma_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + qcom,clock-rates = <266670000 0 0 0 0>; + }; + + + qcom,irqrouter@fda00000 { + cell-index = <0>; + compatible = "qcom,irqrouter"; + reg = <0xfda00000 0x100>; + reg-names = "irqrouter"; + }; + + qcom,cpp@fda04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xfda04000 0x100>, + <0xfda80000 0x200>, + <0xfda18000 0x008>; + reg-names = "cpp", "cpp_vbif", "cpp_hw"; + interrupts = <0 49 0>; + interrupt-names = "cpp"; + vdd-supply = <&gdsc_cpp>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cpp_core_clk", + "camss_vfe_cpp_ahb_clk", "camss_vfe_cpp_axi_clk", + "camss_vfe_cpp_clk","micro_iface_clk", "camss_ahb_clk"; + qcom,clock-rates = <0 465000000 0 0 465000000 0 0>; + qcom,min-clock-rate = <320000000>; + }; + + qcom,fd@fd878000 { + cell-index = <0>; + compatible = "qcom,face-detection"; + reg = <0xfd878000 0x800>, + <0xfd87c000 0x800>, + <0xfd860000 0x1000>; + reg-names = "fd_core", "fd_misc", "fd_vbif"; + interrupts = <0 316 0>; + interrupt-names = "fd"; + vdd-supply = <&gdsc_fd>; + clocks = <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>, + <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>; + clock-names = "fd_core_clk", "fd_core_uar_clk", + "fd_axi_clk", "fd_ahb_clk"; + clock-rates = <60000000 60000000 75000000 40000000>, + <200000000 200000000 150000000 40000000>, + <400000000 400000000 333000000 80000000>; + }; + + cci: qcom,cci@fda0c000 { + cell-index = <0>; + compatible = "qcom,cci"; + reg = <0xfda0c000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "cci"; + interrupts = <0 50 0>; + interrupt-names = "cci"; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; + clocks = <&clock_mmss clk_camss_top_ahb_clk>, + <&clock_mmss clk_cci_clk_src>, + <&clock_mmss clk_camss_cci_cci_ahb_clk>, + <&clock_mmss clk_camss_cci_cci_clk>, + <&clock_mmss clk_camss_ahb_clk>; + clock-names = "camss_top_ahb_clk", "cci_src_clk", + "cci_ahb_clk", "camss_cci_clk", + "camss_ahb_clk"; + qcom,clock-rates = <0 19200000 0 0 0>, + <0 37500000 0 0 0>; + pinctrl-names = "cci_default", "cci_suspend"; + pinctrl-0 = <&cci0_active &cci1_active>; + pinctrl-1 = <&cci0_suspend &cci1_suspend>; + gpios = <&msm_gpio 17 0>, + <&msm_gpio 18 0>, + <&msm_gpio 19 0>, + <&msm_gpio 20 0>; + qcom,gpio-tbl-num = <0 1 2 3>; + qcom,gpio-tbl-flags = <1 1 1 1>; + qcom,gpio-tbl-label = "CCI_I2C_DATA0", + "CCI_I2C_CLK0", + "CCI_I2C_DATA1", + "CCI_I2C_CLK1"; + i2c_freq_100Khz: qcom,i2c_standard_mode { + status = "disabled"; + }; + i2c_freq_400Khz: qcom,i2c_fast_mode { + status = "disabled"; + }; + i2c_freq_custom: qcom,i2c_custom_mode { + status = "disabled"; + }; + + i2c_freq_1Mhz: qcom,i2c_fast_plus_mode { + status = "disabled"; + }; + + }; +}; + +&i2c_freq_100Khz { + qcom,hw-thigh = <104>; + qcom,hw-tlow = <88>; + qcom,hw-tsu-sto = <105>; + qcom,hw-tsu-sta = <119>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <84>; + qcom,hw-tbuf = <116>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_400Khz { + qcom,hw-thigh = <20>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <32>; +/* changed by zhangxiaowei@camera 20150213 for AF OIS functions */ + qcom,hw-scl-stretch-en = <1>; + //qcom,hw-scl-stretch-en = <0>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_custom { + qcom,hw-thigh = <15>; + qcom,hw-tlow = <28>; + qcom,hw-tsu-sto = <21>; + qcom,hw-tsu-sta = <21>; + qcom,hw-thd-dat = <13>; + qcom,hw-thd-sta = <18>; + qcom,hw-tbuf = <25>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <6>; + qcom,hw-tsp = <3>; + status = "ok"; +}; + +&i2c_freq_1Mhz { + qcom,hw-thigh = <16>; + qcom,hw-tlow = <22>; + qcom,hw-tsu-sto = <17>; + qcom,hw-tsu-sta = <18>; + qcom,hw-thd-dat = <16>; + qcom,hw-thd-sta = <15>; + qcom,hw-tbuf = <19>; + qcom,hw-scl-stretch-en = <1>; + qcom,hw-trdhld = <3>; + qcom,hw-tsp = <3>; + qcom,cci-clk-src = <37500000>; + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v1.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v1.dtsi new file mode 100755 index 0000000000000..b6ad994e6ae35 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v1.dtsi @@ -0,0 +1,774 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <9>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <10>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <11>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <12>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <18>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <19>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <20>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <21>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <22>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <23>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <24>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <25>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <44>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <45>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v2.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v2.dtsi new file mode 100755 index 0000000000000..681adbaf1c818 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-coresight-v2.dtsi @@ -0,0 +1,829 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tmc_etr: tmc@fc326000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc326000 0x1000>, + <0xfc37c000 0x3000>; + reg-names = "tmc-base", "bam-base"; + interrupts = <0 270 0>; + interrupt-names = "byte-cntr-irq"; + + qcom,memory-size = <0x2000000>; + qcom,tmc-flush-powerdown; + qcom,sg-enable; + + coresight-id = <0>; + coresight-name = "coresight-tmc-etr"; + coresight-nr-inports = <1>; + coresight-ctis = <&cti0 &cti8>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpiu: tpiu@fc320000 { + compatible = "arm,coresight-tpiu"; + reg = <0xfc320000 0x1000>, + <0xfd512000 0x1000>; + reg-names = "tpiu-base", "nidnt-base"; + + coresight-id = <1>; + coresight-name = "coresight-tpiu"; + coresight-nr-inports = <1>; + + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <2950000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + qcom,nidntsw; + qcom,nidnt-swduart; + qcom,nidnt-swdtrc; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + replicator: replicator@fc324000 { + compatible = "qcom,coresight-replicator"; + reg = <0xfc324000 0x1000>; + reg-names = "replicator-base"; + + coresight-id = <2>; + coresight-name = "coresight-replicator"; + coresight-nr-inports = <1>; + coresight-outports = <0 1>; + coresight-child-list = <&tmc_etr &tpiu>; + coresight-child-ports = <0 0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tmc_etf: tmc@fc325000 { + compatible = "arm,coresight-tmc"; + reg = <0xfc325000 0x1000>; + reg-names = "tmc-base"; + + coresight-id = <3>; + coresight-name = "coresight-tmc-etf"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&replicator>; + coresight-child-ports = <0>; + coresight-default-sink; + coresight-ctis = <&cti0 &cti8>; + + qcom,tmc-flush-powerdown; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_merg: funnel@fc323000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc323000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <4>; + coresight-name = "coresight-funnel-merg"; + coresight-nr-inports = <2>; + coresight-outports = <0>; + coresight-child-list = <&tmc_etf>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in0: funnel@fc321000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc321000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <5>; + coresight-name = "coresight-funnel-in0"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_in1: funnel@fc322000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc322000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <6>; + coresight-name = "coresight-funnel-in1"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_merg>; + coresight-child-ports = <1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss1: funnel@fbb70000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb70000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <7>; + coresight-name = "coresight-funnel-apss1"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_apss: funnel@fbb60000 { + compatible = "arm,coresight-funnel"; + reg = <0xfbb60000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <8>; + coresight-name = "coresight-funnel-apss"; + coresight-nr-inports = <8>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <0>; + + qcom,funnel-save-restore; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + funnel_mmss: funnel@fc370000 { + compatible = "arm,coresight-funnel"; + reg = <0xfc370000 0x1000>; + reg-names = "funnel-base"; + + coresight-id = <9>; + coresight-name = "coresight-funnel-mmss"; + coresight-nr-inports = <4>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpda_lmh: tpda@fbb91000 { + compatible = "qcom,coresight-tpda"; + reg = <0xfbb91000 0x1000>; + reg-names = "tpda-base"; + + coresight-id = <10>; + coresight-name = "coresight-tpda-lmh"; + coresight-nr-inports = <32>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss1>; + coresight-child-ports = <3>; + + qcom,tpda-atid = <64>; + qcom,cmb-elem-size = <0 64>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + tpdm_lmh: tpdm@fbb90000 { + compatible = "qcom,coresight-tpdm"; + reg = <0xfbb90000 0x1000>; + reg-names = "tpdm-base"; + + coresight-id = <11>; + coresight-name = "coresight-tpdm-lmh"; + coresight-nr-inports = <1>; + coresight-outports = <0>; + coresight-child-list = <&tpda_lmh>; + coresight-child-ports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + stm: stm@fc302000 { + compatible = "arm,coresight-stm"; + reg = <0xfc302000 0x1000>, + <0xfa280000 0x180000>; + reg-names = "stm-base", "stm-data-base"; + + coresight-id = <12>; + coresight-name = "coresight-stm"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <7>; + + qcom,data-barrier; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm0: etm@fb840000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb840000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <13>; + coresight-name = "coresight-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <0>; + coresight-etm-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm1: etm@fb940000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfb940000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <14>; + coresight-name = "coresight-etm1"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <1>; + coresight-etm-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm2: etm@fba40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfba40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <15>; + coresight-name = "coresight-etm2"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <2>; + coresight-etm-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm3: etm@fbb40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbb40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <16>; + coresight-name = "coresight-etm3"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <3>; + coresight-etm-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm4: etm@fbc40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbc40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <17>; + coresight-name = "coresight-etm4"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <4>; + coresight-etm-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm5: etm@fbd40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbd40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <18>; + coresight-name = "coresight-etm5"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <5>; + coresight-etm-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm6: etm@fbe40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbe40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <19>; + coresight-name = "coresight-etm6"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <6>; + coresight-etm-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + etm7: etm@fbf40000 { + compatible = "arm,coresight-etmv4"; + reg = <0xfbf40000 0x1000>; + reg-names = "etm-base"; + + coresight-id = <20>; + coresight-name = "coresight-etm7"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_apss>; + coresight-child-ports = <7>; + coresight-etm-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + audio_etm0 { + compatible = "qcom,coresight-audio-etm"; + + coresight-id = <21>; + coresight-name = "coresight-audio-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <2>; + }; + + modem_etm0 { + compatible = "qcom,coresight-modem-etm"; + + coresight-id = <22>; + coresight-name = "coresight-modem-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <1>; + }; + + wcn_etm0 { + compatible = "qcom,coresight-wcn-etm"; + + coresight-id = <23>; + coresight-name = "coresight-wcn-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in1>; + coresight-child-ports = <0>; + }; + + rpm_etm0 { + compatible = "qcom,coresight-rpm-etm"; + + coresight-id = <24>; + coresight-name = "coresight-rpm-etm0"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <0>; + }; + + csr: csr@fc301000 { + compatible = "qcom,coresight-csr"; + reg = <0xfc301000 0x1000>; + reg-names = "csr-base"; + + coresight-id = <25>; + coresight-name = "coresight-csr"; + coresight-nr-inports = <0>; + + qcom,blk-size = <1>; + }; + + cti0: cti@fc310000 { + compatible = "arm,coresight-cti"; + reg = <0xfc310000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <26>; + coresight-name = "coresight-cti0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti1: cti@fc311000 { + compatible = "arm,coresight-cti"; + reg = <0xfc311000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <27>; + coresight-name = "coresight-cti1"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti2: cti@fc312000 { + compatible = "arm,coresight-cti"; + reg = <0xfc312000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <28>; + coresight-name = "coresight-cti2"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti3: cti@fc313000 { + compatible = "arm,coresight-cti"; + reg = <0xfc313000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <29>; + coresight-name = "coresight-cti3"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti4: cti@fc314000 { + compatible = "arm,coresight-cti"; + reg = <0xfc314000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <30>; + coresight-name = "coresight-cti4"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti5: cti@fc315000 { + compatible = "arm,coresight-cti"; + reg = <0xfc315000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <31>; + coresight-name = "coresight-cti5"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti6: cti@fc316000 { + compatible = "arm,coresight-cti"; + reg = <0xfc316000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <32>; + coresight-name = "coresight-cti6"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <2>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_a>; + }; + + cti7: cti@fc317000 { + compatible = "arm,coresight-cti"; + reg = <0xfc317000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <33>; + coresight-name = "coresight-cti7"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti8: cti@fc318000 { + compatible = "arm,coresight-cti"; + reg = <0xfc318000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <34>; + coresight-name = "coresight-cti8"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-gpio-trigout = <4>; + pinctrl-names = "cti-trigout-pctrl"; + pinctrl-0 = <&trigout_c>; + }; + + cti_cpu0: cti@fb820000 { + compatible = "arm,coresight-cti"; + reg = <0xfb820000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <35>; + coresight-name = "coresight-cti-cpu0"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu1: cti@fb920000 { + compatible = "arm,coresight-cti"; + reg = <0xfb920000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <36>; + coresight-name = "coresight-cti-cpu1"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU1>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu2: cti@fba20000 { + compatible = "arm,coresight-cti"; + reg = <0xfba20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <37>; + coresight-name = "coresight-cti-cpu2"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU2>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu3: cti@fbb2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbb20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <38>; + coresight-name = "coresight-cti-cpu3"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU3>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu4: cti@fbc20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbc20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <39>; + coresight-name = "coresight-cti-cpu4"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU4>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu5: cti@fbd20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbd20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <40>; + coresight-name = "coresight-cti-cpu5"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU5>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu6: cti@fbe20000 { + compatible = "arm,coresight-cti"; + reg = <0xfbe20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <41>; + coresight-name = "coresight-cti-cpu6"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU6>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_cpu7: cti@fbf2000 { + compatible = "arm,coresight-cti"; + reg = <0xfbf20000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <42>; + coresight-name = "coresight-cti-cpu7"; + coresight-nr-inports = <0>; + coresight-cti-cpu = <&CPU7>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,cti-save; + }; + + cti_video_cpu0: cti@fc338000 { + compatible = "arm,coresight-cti"; + reg = <0xfc338000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <43>; + coresight-name = "coresight-cti-video-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_modem_cpu0: cti@fc33c000 { + compatible = "arm,coresight-cti"; + reg = <0xfc33c000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <44>; + coresight-name = "coresight-cti-modem-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_audio_cpu0: cti@fc360000 { + compatible = "arm,coresight-cti"; + reg = <0xfc360000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <45>; + coresight-name = "coresight-cti-audio-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + cti_rpm_cpu0: cti@fc364000 { + compatible = "arm,coresight-cti"; + reg = <0xfc364000 0x1000>; + reg-names = "cti-base"; + + coresight-id = <46>; + coresight-name = "coresight-cti-rpm-cpu0"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + }; + + hwevent: hwevent@fd820018 { + compatible = "qcom,coresight-hwevent"; + reg = <0xfd828018 0x80>, + <0xf9112000 0x80>, + <0xf9112080 0x4>, + <0xf9112084 0x4>, + <0xf9112088 0x14>, + <0xf9112148 0x38>, + <0xfd4ab160 0x80>, + <0xfc401600 0x80>, + <0xfd4ab360 0x80>, + <0xfc520000 0x4>, + <0xfc520058 0x80>, + <0xfc528000 0x4>, + <0xfc528058 0x80>; + reg-names = "mmss-mux", "apcs-hwev", "apcs-spi", "apcs-ppi", + "apcs-cpu", "apcs-cci", "ppss-mux", "gcc-mux", + "tcsr-mux", "pcie0-sysctl", "pcie0-hwev", + "pcie1-sysctl", "pcie1-hwev"; + + coresight-id = <47>; + coresight-name = "coresight-hwevent"; + coresight-nr-inports = <0>; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>; + clock-names = "core_clk", "core_a_clk", "core_mmss_clk"; + + qcom,hwevent-clks = "core_mmss_clk"; + }; + + fuse: fuse@fc4be024 { + compatible = "arm,coresight-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + + coresight-id = <48>; + coresight-name = "coresight-fuse"; + coresight-nr-inports = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-gpu.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-gpu.dtsi new file mode 100755 index 0000000000000..3d63cf8d2076c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-gpu.dtsi @@ -0,0 +1,181 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + msm_bus: qcom,kgsl-busmon{ + label = "kgsl-busmon"; + compatible = "qcom,kgsl-busmon"; + }; + + gpubw: qcom,gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,gpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc390000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <2>; + qcom,target-dev = <&gpubw>; + }; + + msm_gpu: qcom,kgsl-3d0@fdb00000 { + label = "kgsl-3d0"; + compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d"; + reg = <0xfdb00000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 33 0>; + interrupt-names = "kgsl_3d0_irq"; + qcom,id = <0>; + + qcom,chipid = <0x04030000>; + + qcom,initial-pwrlevel = <2>; + + qcom,idle-timeout = <8>; // + qcom,strtstp-sleepwake; + + qcom,pm-qos-active-latency = <501>; + qcom,pm-qos-wakeup-latency = <101>; + + /* + * Clocks = KGSL_CLK_CORE | KGSL_CLK_IFACE + * KGSL_CLK_RBBMTIMER + */ + qcom,clk-map = <0x00000086>; + + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>, + <&clock_mmss clk_oxili_rbbmtimer_clk>; + clock-names = "core_clk", "iface_clk", "rbbmtimer_clk"; + + /* Bus Scale Settings */ + qcom,gpubw-dev = <&gpubw>; + qcom,bus-control; + /* + * qcom,msm-bus structures below define + * GPU msm client and its vote data for + * each of available power levels + * (gpu-bus frequency combination) + */ + qcom,msm-bus,name = "grp3d"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1200000>, /* 1 bus=150 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3200000>, /* 3 bus=460 */ + <26 512 0 4224000>, /* 4 bus=533 */ + <26 512 0 5376000>, /* 5 bus=672 */ + <26 512 0 6681600>, /* 6 bus=777 */ + <26 512 0 8448000>, /* 7 bus=1036 */ + <26 512 0 12748800>; /* 8 bus=1555 */ + + /* GDSC oxili regulators */ + vddcx-supply = <&gdsc_oxili_cx>; + vdd-supply = <&gdsc_oxili_gx>; + + /* IOMMU Data */ + iommu = <&kgsl_iommu>; + + /* Trace bus */ + coresight-id = <67>; + coresight-name = "coresight-gfx"; + coresight-nr-inports = <0>; + coresight-outports = <0>; + coresight-child-list = <&funnel_in0>; + coresight-child-ports = <4>; + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <400000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <300000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <2>; + qcom,bus-max = <5>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <150000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <27000000>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + qcom,bus-freq = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <5>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu=600 */ + <89 662 0 6400000>, /* gpu=400 */ + <89 662 0 4800000>, /* gpu=300 */ + <89 662 0 2400000>, /* gpu=150 */ + <89 662 0 0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu-domains.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu-domains.dtsi new file mode 100755 index 0000000000000..840818c2d7cb3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu-domains.dtsi @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,iommu-domains { + compatible = "qcom,iommu-domains"; + + venus_domain_ns: qcom,iommu-domain1 { + label = "venus_ns"; + qcom,iommu-contexts = <&venus_ns>; + qcom,virtual-addr-pool = <0x5dc00000 0x7f000000 + 0xdcc00000 0x1000000>; + }; + + venus_domain_sec_bitstream: qcom,iommu-domain2 { + label = "venus_sec_bitstream"; + qcom,iommu-contexts = <&venus_sec_bitstream>; + qcom,virtual-addr-pool = <0x4b000000 0x12c00000>; + qcom,secure-domain; + }; + + venus_domain_sec_pixel: qcom,iommu-domain3 { + label = "venus_sec_pixel"; + qcom,iommu-contexts = <&venus_sec_pixel>; + qcom,virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-domain; + }; + + venus_domain_sec_non_pixel: qcom,iommu-domain4 { + label = "venus_sec_non_pixel"; + qcom,iommu-contexts = <&venus_sec_non_pixel>; + qcom,virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-domain; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu.dtsi new file mode 100755 index 0000000000000..0638ffc0a6b3c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-iommu.dtsi @@ -0,0 +1,430 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm-iommu-v1.dtsi" + +&soc { + mdp_iommu_8994: qcom,iommu@fd9cc000 { + compatible = "qcom,msm-smmu-v1"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfd9cc000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 73 0>, + <0 229 0>, <0 231 0>, + <0 230 0>, <0 232 0>; + interrupt-names = "pmon", + "global_cfg_NS_irq", "global_client_NS_irq", + "global_cfg_S_irq", "global_client_S_irq"; + qcom,iommu-secure-id = <1>; + label = "mdp_iommu"; + qcom,msm-bus,name = "mdp_ebi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + status = "ok"; + vdd-supply = <&gdsc_mdss>; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-pmu-ngroups = <1>; + qcom,iommu-pmu-ncounters = <8>; + qcom,iommu-pmu-event-classes = <0x00 + 0x01 + 0x08 + 0x09 + 0x0A + 0x10 + 0x11 + 0x12 + 0x80 + 0x81 + 0x82 + 0x83 + 0x90 + 0x91 + 0x92 + 0xb0 + 0xb1>; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018>; + + qcom,iommu-bfb-data = <0x3 + 0x7fffff + 0x1777 + 0x0 + 0x4 + 0x10 + 0x5000 + 0x182c1 + 0x5a1d + 0x1822d + 0x0 + 0x0 + 0x28 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fd9d4000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d4000 0x1000>; + interrupts = <0 47 0>; + qcom,iommu-ctx-sids = <0>; + label = "mdp_0"; + }; + + qcom,iommu-ctx@fd9d5000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d5000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <1>; + label = "mdp_1"; + qcom,secure-context; + }; + + qcom,iommu-ctx@fd9d6000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfd9d6000 0x1000>; + interrupts = <0 47 0>, <0 46 0>; + qcom,iommu-ctx-sids = <>; + label = "mdp_2"; + qcom,secure-context; + }; + }; +}; + +&venus_iommu { + status = "ok"; + vdd-supply = <&gdsc_venus>; + clocks = <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014 + 0x2018 + 0x201c>; + + qcom,iommu-bfb-data = <0x3 + 0x7ffffff + 0x1555 + 0x0 + 0x4 + 0x8 + 0x13607 + 0x140a0 + 0x4000 + 0x14020 + 0x0 + 0x0 + 0x94 + 0x114 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0 + 0x0>; + + venus_ns: qcom,iommu-ctx@fdc8c000 { + qcom,iommu-ctx-sids = <0x00 0x21 0x45 0x47 0x48 0x49 0x4a + 0x4b 0x4c 0x65 0x67 0x69 0x6a 0x6b>; + qcom,iommu-sid-mask = <0x0 0xf 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; + }; + + venus_sec_bitstream: qcom,iommu-ctx@fdc8d000 { + qcom,iommu-ctx-sids = <0x400 0x421 0x422 0x423 0x424 0x448 + 0x44a 0x46a>; + label = "venus_sec_bitstream"; + }; + + venus_fw: qcom,iommu-ctx@fdc8e000 { + qcom,iommu-ctx-sids = <0x600 0x606>; + }; + + venus_sec_pixel: qcom,iommu-ctx@fdc8f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc8f000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x425 0x428 0x445 0x44c 0x465>; + label = "venus_sec_pixel"; + qcom,secure-context; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@fdc90000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfdc90000 0x1000>; + interrupts = <0 42 0>, <0 43 0>; + qcom,iommu-ctx-sids = <0x427 0x447 0x449 0x44b 0x467 0x469 0x46b + 0x500>; + label = "venus_sec_non_pixel"; + qcom,secure-context; + }; +}; + +&jpeg_iommu { + status = "ok"; + vdd-supply = <&gdsc_jpeg>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0x3ffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2000 + 0xe673 + 0x2c00 + 0xe616 + 0x0 + 0x0 + 0x10 + 0x68 + 0x0 + 0x0 + 0x0 + 0x0>; + + qcom,iommu-ctx@fda6f000 { + compatible = "qcom,msm-smmu-v1-ctx"; + reg = <0xfda6f000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <3>; + label = "jpeg_dma"; + }; +}; + +&kgsl_iommu { + status = "ok"; + vdd-supply = <&gdsc_oxili_cx>; + qcom,alt-vdd-supply = <&gdsc_oxili_gx>; + qcom,iommu-secure-id = <18>; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>, + <&clock_mmss clk_oxilicx_ahb_clk>; + clock-names = "core_clk", "iface_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x2600 + 0x2604 + 0x2608 + 0x260c + 0x2610 + 0x2614 + 0x2618 + 0x261c + 0x2620 + 0x2624 + 0x2628 + 0x262c>; + + qcom,iommu-bfb-data = <0x3 + 0x3 + 0x1555 + 0x0 + 0x0 + 0x10 + 0x0 + 0x120 + 0x120 + 0x10 + 0x0 + 0x0 + 0x0 + 0x1 + 0x0 + 0x7 + 0x0 + 0x20 + 0x20 + 0x0c + 0x0 + 0x0 + 0x0 + 0x10 + 0x0 + 0x0 + 0x10>; + + qcom,iommu-ctx@fdb18000 { + qcom,iommu-ctx-sids = <0 1>; + }; + + qcom,iommu-ctx@fdb19000 { + qcom,iommu-ctx-sids = <>; + }; + + qcom,iommu-ctx@fdb1a000 { + qcom,iommu-ctx-sids = <2>; + interrupts = <0 241 0>, <0 240 0>; + qcom,secure-context; + linux,contiguous-region = <&secure_mem>; + }; +}; + +&vfe_iommu { + status = "ok"; + vdd-supply = <&gdsc_vfe>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>, + <&clock_mmss clk_camss_vfe_vfe_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; + + qcom,iommu-bfb-regs = <0x2000 + 0x204c + 0x2060 + 0x2514 + 0x2540 + 0x256c + 0x20ac + 0x215c + 0x220c + 0x22bc + 0x2314 + 0x2394 + 0x2414 + 0x2494 + 0x2008 + 0x200c + 0x2010 + 0x2014>; + + qcom,iommu-bfb-data = <0x3 + 0xfffff + 0x1555 + 0x0 + 0x4 + 0x4 + 0x2400 + 0x8844 + 0x2400 + 0x8812 + 0x0 + 0x0 + 0x12 + 0x5a + 0x0 + 0x0 + 0x0 + 0x0>; +}; + +&fd_iommu { + status = "ok"; + vdd-supply = <&gdsc_fd>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_ahb_clk>, + <&clock_mmss clk_fd_core_clk>, + <&clock_mmss clk_fd_core_uar_clk>; + clock-names = "core_clk", "iface_clk", "alt_core_clk", "alt_iface_clk"; +}; + +&cpp_iommu { + status = "ok"; + vdd-supply = <&gdsc_cpp>; + qcom,needs-alt-core-clk; + qcom,needs-alt-iface-clk; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_ahb_clk>, + <&clock_mmss clk_camss_ahb_clk>, + <&clock_mmss clk_camss_top_ahb_clk>; + clock-names = "core_clk", "iface_clk", "alt_iface_clk", "alt_core_clk"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-ion.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-ion.dtsi new file mode 100755 index 0000000000000..16b920e069108 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-ion.dtsi @@ -0,0 +1,63 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ion { + compatible = "qcom,msm-ion"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,ion-heap@25 { + reg = <25>; + qcom,ion-heap-type = "SYSTEM"; + }; + + qcom,ion-heap@21 { + reg = <21>; + qcom,ion-heap-type = "SYSTEM_CONTIG"; + }; + + qcom,ion-heap@8 { /* CP_MM HEAP */ + compatible = "qcom,msm-ion-reserve"; + reg = <8>; + qcom,heap-align = <0x1000>; + linux,contiguous-region = <&secure_mem>; + qcom,ion-heap-type = "SECURE_DMA"; + qcom,default-prefetch-size = <0x6c00000>; + }; + + qcom,ion-heap@22 { /* adsp heap */ + reg = <22>; + linux,contiguous-region = <&adsp_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@27 { /* QSECOM HEAP */ + reg = <27>; + linux,contiguous-region = <&qsecom_mem>; + qcom,ion-heap-type = "DMA"; + }; + + qcom,ion-heap@28 { /* AUDIO HEAP */ + reg = <28>; + linux,contiguous-region = <&audio_mem>; + qcom,ion-heap-type = "DMA"; + }; + + adsp_venus_heap: qcom,ion-heap@23 { + compatible = "qcom,msm-ion-reserve"; + reg = <23>; + linux,contiguous-region = <&peripheral_mem>; + qcom,ion-heap-type = "DMA"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-ipcrouter.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-ipcrouter.dtsi new file mode 100755 index 0000000000000..006bd32eb5957 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-ipcrouter.dtsi @@ -0,0 +1,37 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,ipc_router { + compatible = "qcom,ipc_router"; + qcom,node-id = <1>; + }; + + qcom,ipc_router_modem_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "modem"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + qcom,disable-pil-loading; + }; + + qcom,ipc_router_q6_xprt { + compatible = "qcom,ipc_router_smd_xprt"; + qcom,ch-name = "IPCRTR"; + qcom,xprt-remote = "adsp"; + qcom,xprt-linkid = <1>; + qcom,xprt-version = <1>; + qcom,fragmented-data; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss-pll.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss-pll.dtsi new file mode 100755 index 0000000000000..a6cd3a43e5a65 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss-pll.dtsi @@ -0,0 +1,171 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@fd998300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xfd998300 0x500>, + <0xfd8c2300 0x8>, + <0xfd998200 0x64>, + <0xfd9a0300 0x500>; + reg-names = "pll_base", "gdsc_base", "dynamic_pll_base", + "pll_1_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-en-pll-90-phase; + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + /* Dynamic FPS data region */ + linux,contiguous-region = <&dfps_data_mem>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + mdss_dsi1_pll: qcom,mdss_dsi_pll@fd9a0300 { + compatible = "qcom,mdss_dsi_pll_8994"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xfd9a0300 0x500>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; + + mdss_hdmi_pll: qcom,mdss_hdmi_pll@0xfd9a8600 { + compatible = "qcom,mdss_hdmi_pll_8994"; + label = "MDSS HDMI PLL"; + #clock-cells = <1>; + + reg = <0xfd9a8600 0xac4>, + <0xfd9a9200 0x0C8>, + <0xfd8c2300 0x8>; + reg-names = "pll_base", "phy_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>; + clock-names = "iface_clk"; + clock-rate = <0>; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + qcom,platform-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,platform-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss.dtsi new file mode 100755 index 0000000000000..269101b45a411 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-mdss.dtsi @@ -0,0 +1,508 @@ +/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_mdp: qcom,mdss_mdp@fd900000 { + compatible = "qcom,mdss_mdp"; + reg = <0xfd900000 0x90000>, + <0xfd9c8000 0x004d4>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-ib-factor = <1 1>; /* 1 times (removes fudge factor) */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2048>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,mdss-vbif-qos-nrt-setting = <1 1 1 1>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <7300000>; + qcom,max-bandwidth-high-kbps = <7300000>; + qcom,max-bandwidth-per-pipe-kbps = <1800000>; + qcom,max-clk-rate = <400000000>; + qcom,mdss-dram-channels = <2>; + qcom,mdss-default-ot-wr-limit = <16>; + qcom,mdss-default-ot-rd-limit = <16>; + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000 + 0x00009000 0x0000B000>; + qcom,mdss-pipe-rgb-off = <0x00015000 0x00017000 + 0x00019000 0x0001B000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000>; + qcom,mdss-pipe-cursor-off = <0x00035000 0x00037000>; + + qcom,mdss-pipe-vig-fetch-id = <1 4 7 19>; + qcom,mdss-pipe-rgb-fetch-id = <16 17 18 22>; + qcom,mdss-pipe-dma-fetch-id = <10 13>; + + qcom,mdss-pipe-vig-xin-id = <0 4 8 12>; + qcom,mdss-pipe-rgb-xin-id = <1 5 9 13>; + qcom,mdss-pipe-dma-xin-id = <2 10>; + qcom,mdss-pipe-cursor-xin-id = <7 7>; + + qcom,mdss-en-svs-high; + qcom,mdss-has-panic-ctrl; + qcom,mdss-pipe-vig-panic-ctrl-offsets = <0 1 2 3>; + qcom,mdss-pipe-rgb-panic-ctrl-offsets = <4 5 6 7>; + qcom,mdss-pipe-dma-panic-ctrl-offsets = <8 9>; + + qcom,mdss-pipe-rgb-fixed-mmb = <5 0 1 8 9 10>, + <5 2 3 11 12 13>, + <5 4 5 14 15 16>, + <5 6 7 17 18 19>; + qcom,mdss-pipe-vig-fixed-mmb = <1 20>, + <1 21>, + <1 22>, + <1 23>; + + /* These Offsets are relative to "mdp_phys + mdp-reg-offset" address */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2AC 0 0>, + <0x2B4 0 0>, + <0x2BC 0 0>, + <0x2C4 0 0>; + qcom,mdss-pipe-rgb-clk-ctrl-offsets = <0x2AC 4 8>, + <0x2B4 4 8>, + <0x2BC 4 8>, + <0x2C4 4 8>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2AC 8 12>, + <0x2B4 8 12>; + + qcom,mdss-pipe-sw-reset-off = <0x0028>; + qcom,mdss-pipe-vig-sw-reset-map = <5 6 7 8>; + qcom,mdss-pipe-rgb-sw-reset-map = <9 10 11 12>; + qcom,mdss-pipe-dma-sw-reset-map = <13 14>; + + qcom,mdss-smp-data = <44 8192>; + qcom,mdss-sspp-len = <0x00002000>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004A000>; + qcom,mdss-mixer-wb-off = <0x00048000 0x00049000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000 0x00059000 + 0x0005B000>; + qcom,mdss-wb-off = <0x00065000 0x00065800 0x00066000 + 0x00066800 0x00067000>; + qcom,mdss-intf-off = <0x0006B000 0x0006B800 0x0006C000 + 0x0006C800 0x0006D000>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 0x00072000 + 0x00072800>; + qcom,mdss-ad-off = <0x0079000 0x00079800 0x0007A000>; + qcom,mdss-highest-bank-bit = <0x3>; + qcom,mdss-has-decimation; + qcom,mdss-has-rotator-downscale; + qcom,mdss-has-bwc; + + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + + qcom,mdss-ctl-len = <0x00000200>; + + clocks = <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdp_clk_src>, + <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_vsync_clk>; + clock-names = "iface_clk", "bus_clk", "core_clk_src", + "core_clk", "vsync_clk"; + + /* These Offsets are relative to "mdp_phys" address */ + qcom,mdp-settings = <0x0117c 0x00005555>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; + + qcom,regs-dump-mdp = <0x01000 0x01408>, + <0x02000 0x02064>, + <0x02200 0x02264>, + <0x02400 0x02464>, + <0x02600 0x02664>, + <0x02800 0x02864>, + <0x05000 0x05130>, + <0x05200 0x05230>, + <0x07000 0x07130>, + <0x07200 0x07230>, + <0x09000 0x09130>, + <0x09200 0x09230>, + <0x0b000 0x0b130>, + <0x0b200 0x0b230>, + <0x15000 0x15130>, + <0x15200 0x15230>, + <0x17000 0x17130>, + <0x17200 0x17230>, + <0x19000 0x19130>, + <0x19200 0x19230>, + <0x1b000 0x1b130>, + <0x1b200 0x1b230>, + <0x25000 0x2512C>, + <0x27000 0x2712C>, + <0x45000 0x4538c>, + <0x46000 0x4638c>, + <0x47000 0x4738c>, + <0x48000 0x4838c>, + <0x49000 0x4938c>, + <0x4a000 0x4a38c>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x59000 0x5922c>, + <0x5b000 0x5b22c>, + <0x65000 0x652b4>, + <0x65800 0x65ab4>, + <0x66000 0x662b4>, + <0x66800 0x66ab4>, + <0x67000 0x672b4>, + <0x6b800 0x6ba54>, + <0x6c000 0x6c254>, + <0x6c800 0x6ca54>, + <0x71000 0x710d0>, + <0x71800 0x718d0>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "VIG2_SSPP", "VIG2", "VIG3_SSPP", "VIG3", + "RGB0_SSPP", "RGB0", "RGB1_SSPP", "RGB1", + "RGB2_SSPP", "RGB2", "RGB3_SSPP", "RGB3", + "DMA0_SSPP", "DMA1_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_3", "LAYER_4", "LAYER_5", + "DSPP_0", "DSPP_1", "DSPP_2", "DSPP_3", + "WB_0", "WB_1", "WB_2", "WB_3", "WB_4", + "INTF_1", "INTF_2", "INTF_3", + "PP_0", "PP_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <2048>; + qcom,mdss-prefill-y-buffer-bytes = <4096>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2048>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + qcom,mdss-prefill-fbc-lines = <2>; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + qcom,cont-splash-memory { + linux,contiguous-region = <&cont_splash_mem>; + }; + }; + + mdss_fb1: qcom,mdss_fb_external { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_wfd { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + }; + }; + + mdss_dsi0: qcom,mdss_dsi@fd998000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xfd998000 0x260>, + <0xfd998500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte0_clk>, + <&clock_mmss clk_mdss_pclk0_clk>, + <&clock_mmss clk_mdss_esc0_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", "byte_clk_src", + "pixel_clk_src", "shadow_byte_clk_src", + "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + mdss_dsi1: qcom,mdss_dsi@fd9a0000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xfd9a0000 0x260>, + <0xfd9a0500 0x280>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; + gdsc-supply = <&gdsc_mdss>; + vdd-supply = <&pm8994_l14>; + vddio-supply = <&pm8994_l12>; + vdda-supply = <&pm8994_l2>; + vcca-supply = <&pm8994_l28>; + qcom,mdss-fb-map = <&mdss_fb0>; + qcom,mdss-mdp = <&mdss_mdp>; + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mmss_misc_ahb_clk>, + <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_byte1_clk>, + <&clock_mmss clk_mdss_pclk1_clk>, + <&clock_mmss clk_mdss_esc1_clk>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_byte_clk_src>, + <&mdss_dsi0_pll clk_pixel_clk_src>, + <&mdss_dsi0_pll clk_shadow_byte_clk_src>, + <&mdss_dsi0_pll clk_shadow_pixel_clk_src>, + <&mdss_dsi1_pll clk_mdss_dsi1_vco_clk_src>; + + clock-names = "mdp_core_clk", "iface_clk", + "core_mmss_clk", "bus_clk", + "byte_clk", "pixel_clk", "core_clk", + "mdss_byte_clk_mux", "mdss_pixel_clk_mux", + "byte_clk_src", "pixel_clk_src", + "shadow_byte_clk_src", "shadow_pixel_clk_src", + "clk_mdss_dsi1_vco_clk_src"; + + qcom,platform-strength-ctrl = [77 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [03 03 03 00 20 07 01]; + qcom,platform-lane-config = [ + 02 a0 00 00 20 00 00 01 46 + 02 a0 00 00 40 00 00 01 46 + 02 a0 00 40 20 00 00 01 46 + 02 a0 00 40 00 00 00 01 46 + 00 a0 00 80 00 00 00 01 46]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + qcom,mmss-phyreset-ctrl-offset = <0x108>; + qcom,timing-db-mode; + qcom,dsi-clk-ln-recovery; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda"; + qcom,supply-min-voltage = <1250000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,ctrl-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + + qcom,ctrl-supply-entry@2 { + reg = <2>; + qcom,supply-name = "vcca"; + qcom,supply-min-voltage = <1000000>; + qcom,supply-max-voltage = <1000000>; + qcom,supply-enable-load = <10000>; + qcom,supply-disable-load = <100>; + }; + }; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <5>; + }; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <1920 1080>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb2>; + }; + + mdss_hdmi_tx: qcom,hdmi_tx@fd9a8000{ + cell-index = <0>; + compatible = "qcom,hdmi-tx"; + + reg = <0xfd9a8000 0x38C>, + <0xfc4b8000 0x6fff>; + reg-names = "core_physical", "qfprom_physical"; + + hpd-gdsc-supply = <&gdsc_mdss>; + core-vdda-supply = <&pm8994_l12>; + core-vcc-supply = <&pm8994_s4>; + + qcom,supply-names = "hpd-gdsc", "core-vdda", "core-vcc"; + qcom,min-voltage-level = <0 1800000 1800000>; + qcom,max-voltage-level = <0 1800000 1800000>; + qcom,enable-load = <0 300000 0>; + qcom,disable-load = <0 0 0>; + + clocks = <&clock_mmss clk_mdss_mdp_clk>, + <&clock_mmss clk_mdss_ahb_clk>, + <&clock_mmss clk_mdss_hdmi_clk>, + <&clock_mmss clk_mdss_hdmi_ahb_clk>, + <&clock_mmss clk_mdss_extpclk_clk>; + clock-names = "mdp_core_clk", "iface_clk", + "core_clk", "alt_iface_clk", "extp_clk"; + + qcom,hdmi-tx-hpd = <&pm8994_mpps 4 0>; + qcom,mdss-fb-map = <&mdss_fb1>; + + hdmi_audio: qcom,msm-hdmi-audio-rx { + compatible = "qcom,msm-hdmi-audio-codec-rx"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-mtp.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-mtp.dtsi new file mode 100755 index 0000000000000..3170ba70407ea --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-mtp.dtsi @@ -0,0 +1,1069 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8994-pinctrl.dtsi" +#include "msm8994-camera-sensor-mtp.dtsi" +#include "dsi-panel-jd35695-1080p-cmd.dtsi" +#include "dsi-panel-jdi-1080p-video.dtsi" + +/ { + bt_qca6174 { + compatible = "qca,qca6174"; + qca,bt-reset-gpio = <&pm8994_gpios 19 0>; /* BT_EN */ + qca,bt-vdd-pa-supply = <&bt_vreg>; + qca,bt-vdd-io-supply = <&pm8994_s4>; + qca,bt-vdd-xtal-supply = <&pm8994_l30>; + qca,bt-vdd-io-voltage-level = <1800000 1800000>; + qca,bt-vdd-xtal-voltage-level = <1800000 1800000>; + }; +}; + +&sdhc_1 { + vdd-supply = <&pm8994_l20>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + vdd-io-supply = <&pm8994_s4>; + qcom,vdd-io-always-on; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,nonremovable; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000 384000000>; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8994_l21>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8994_l13>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &pm8994_gpios 8 0x3>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&pm8994_gpios 8 0x1>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + status = "ok"; +}; + +&ufsphy1 { + status = "ok"; +}; + +&ufs1 { + status = "ok"; +}; + +&pm8994_vadc { + chan@5 { + label = "vcoin"; + reg = <5>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@7 { + label = "vph_pwr"; + reg = <7>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + }; +}; + +&pm8994_adc_tm { + chan@73 { + label = "msm_therm"; + reg = <0x73>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x48>; + qcom,thermal-node; + }; + + chan@74 { + label = "emmc_therm"; + reg = <0x74>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x68>; + qcom,thermal-node; + }; + + chan@75 { + label = "pa_therm0"; + reg = <0x75>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x70>; + qcom,thermal-node; + }; + + chan@77 { + label = "pa_therm1"; + reg = <0x77>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x78>; + qcom,thermal-node; + }; + + chan@78 { + label = "quiet_therm"; + reg = <0x78>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <0>; + qcom,calibration-type = "ratiometric"; + qcom,scale-function = <2>; + qcom,hw-settle-time = <2>; + qcom,fast-avg-setup = <0>; + qcom,btm-channel-number = <0x80>; + qcom,thermal-node; + }; +}; + +&pmi8994_vadc { + chan@0 { + label = "usbin"; + reg = <0>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@1 { + label = "dcin"; + reg = <1>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <4>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@43 { + label = "usb_dp"; + reg = <0x43>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; + + chan@44 { + label = "usb_dm"; + reg = <0x44>; + qcom,decimation = <0>; + qcom,pre-div-channel-scaling = <1>; + qcom,calibration-type = "absolute"; + qcom,scale-function = <0>; + qcom,hw-settle-time = <0>; + qcom,fast-avg-setup = <0>; + }; +}; + + +/**********************************************************************/ +//zhiming.guo@MM.lcddriver add for lcd driver 2015-01-31 + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&pmx_mdss { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 78>; +}; + + +&labibb { + status = "ok"; + qpnp,qpnp-labibb-mode = "lcd"; +}; + +&pmx_mdss_te { + qcom,num-grp-pins = <1>; + qcom,pins = <&gp 10>; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jd35695_1080_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + //qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + qcom,platform-esd-te-gpio = <&msm_gpio 108 0>;//gzm@oem add 2015-03-28 add + qcom,lcd-poweron-en-gpio = <&pmi8994_gpios 7 0>; + qcom,lcd-poweron-en-n-gpio = <&pmi8994_gpios 3 0>; + qcom,lm3630-bklight-en-gpio = <&pmi8994_gpios 2 0>; + qcom,use_external_ic_power; +}; +&dsi_jd35695_1080_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + +/* + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,dsi-panel-bias-vreg; + qcom,platform-reset-gpio = <&msm_gpio 78 0>; + qcom,platform-te-gpio = <&msm_gpio 10 0>; + +}; +*/ +&dsi_jdi_1080_vid { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,cont-splash-enabled; +}; + + +/******************************************************************/ + + + +&soc { + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, delete it : synaptics@20.*/ + /* LiuPing@Phone.BSP.Sensor, 2014/10/15, add for tp:synaptics */ + i2c@f9924000 { + synaptics-rmi-ts@20 { + compatible = "synaptics,s3320"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <96 0x8>; + synaptics,irq-gpio = <&msm_gpio 96 0x08>; + //synaptics,wakeup-gpio = <&msm_gpio 39 0x00>; + synaptics,reset-gpio = <&msm_gpio 31 0x00>; + synaptics,1v8-gpio = <&msm_gpio 74 0x00>; + //synaptics,id-gpio = <&msm_gpio 38 0x00>; + //synaptics,id3-gpio = <&msm_gpio 39 0x00>; + vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_l14>; + //oem,support_hw_poweroff; + }; + }; +//#ifdef VENDOR_EDIT /* modify for fpc1021 fingerprints*/ + spi@f9968000 { + fpc_fpc1020@0 { //Slave driver and CS ID + compatible = "fpc,fpc1020"; //Manufacture, and Model + reg = <0>; //Same as CS ID + spi-max-frequency = <19200000>; //Max Frequency for Device + #spi-cs-high; //CS Active High + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <90 0>; //GPIO # and flags + fpc,gpio_irq = <&msm_gpio 90 0x00>; //Pass a GPIO + fpc,gpio_reset = <&msm_gpio 89 0x00>; + fpc,gpio_vendor = <&msm_gpio 91 0x00>; + #fpc,gpio_envdd = <&msm_gpio 16 0x00>; + fpc,vddtx_mv; + #fpc,txout_boost_enable; + #spi-cpol; //CPOL bit set for SPI polarity + #spi-cpha; //CPHA bit set for SPI Phase + vdd_io-supply = <&pm8994_s4>; // 1.8V + vdd_ana-supply = <&pm8994_l18>; // 3.3V N3 use gpio16 for enable_pin to controll 3.3V(boost) + fpc,gpio_envdd = <&msm_gpio 41 0x00>; + fpc,gpio_fp2050 = <&msm_gpio 94 0x00>; + }; + }; +//#endif/*VENDOR_EDIT*/ + + gen-vkeys { + compatible = "qcom,gen-vkeys"; + label = "synaptics_dsx"; + qcom,disp-maxx = <1599>; + qcom,disp-maxy = <2559>; + qcom,panel-maxx = <1599>; + qcom,panel-maxy = <2703>; + qcom,key-codes = <158 139 102 217>; + }; + + i2c@f9928000 { /* BLSP1 QUP6 */ + status = "ok"; +//#ifdef VENDOR_EDIT +//added by Likelong 2015.5.15 for proximity sensor start + stmvl6180-tof@29 { + reg = <0x29>; + compatible = "stmv,vl6180"; + interrupt-parent = <&msm_gpio>; + interrupts = <61 0x8>; + st,irq-gpio= <&msm_gpio 61 0x00>; + st,standby-gpio = <&msm_gpio 62 0x00>; + vdd_1v8-supply = <&pm8994_l18>; + vcc_i2c_1v8-supply = <&pm8994_lvs1>; + }; +//added by Likelong 2015.5.15 for proximity sensor end +//#endif/*VENDOR_EDIT*/ + /* + nfc-nci@e { + compatible = "qcom,nfc-nci"; + reg = <0x0e>; + qcom,irq-gpio = <&msm_gpio 29 0x00>; + qcom,dis-gpio = <&msm_gpio 30 0x00>; + qcom,clk-src = "BBCLK2"; + interrupt-parent = <&msm_gpio>; + interrupts = <29 0>; + interrupt-names = "nfc_irq"; + pinctrl-names = "nfc_active","nfc_suspend"; + pinctrl-0 = <&nfc_int_active &nfc_disable_active>; + pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; + qcom,clk-gpio = <&pm8994_gpios 10 0>; + qcom,pwr-req-gpio = <&pm8994_gpios 7 0>; + clocks = <&clock_rpm clk_bb_clk2_pin>; + clock-names = "ref_clk"; + };*/ + /* lifeng@BSP 2015.3.19 synaptics touch key s1302 */ + synaptics-rmi-ts@20 { + status = "okay"; + compatible = "synaptics,s1302"; + reg = <0x20>; + interrupt-parent = <&msm_gpio>; + interrupts = <67 0x8>; + synaptics,irq-gpio = <&msm_gpio 67 0x08>; + //synaptics,reset-gpio = <&msm_gpio 94 0x00>; + //synaptics,en3v_gpio = <&msm_gpio 41 0x00>; + //vdd_2v8-supply = <&pm8994_l22>; + //vcc_i2c_1v8-supply = <&pm8994_s4>; + }; + }; + + //#ifdef VENDOR_EDIT + //#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support + //shankai@bsp, 2015/5/28 ,comment it , as we do not use it any more . + /* + i2c@f9928000 { + haptic-drv2605@5a { + status = "okay"; + compatible = "ti,drv2605"; + //drv2605,enable-gpio = <&pm8994_gpios 4 0x1>; + drv2605,enable-gpio = <&pm8994_gpios 22 0x1>; + reg = <0x5a >; + BIDIRInput = <0x01>; //should be added + loop = <0x1>; + RTPFormat=<0x0>; + actuator.device_type=<0x1>; + actuator.rated_vol=<0x50>; + actuator.g_effect_bank=<0x06>; + actuator.over_drive_vol=<0x84>; + actuator.LRAFreq=<205>; + a2h.a2h_min_input =<0x19>; + a2h.a2h_max_input = <0xff>; + a2h.a2h_min_output =<0x19>; + a2h.a2h_max_output = <0xFF>; + }; + }; + */ + //#endif VENDOR_EDIT + + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + + vol_up { + label = "volume_up"; + gpios = <&pm8994_gpios 3 0x1>; + linux,input-type = <1>; + linux,code = <115>; + debounce-interval = <15>; + }; + + //#ifdef VENDOR_EDIT + /*for vol- support*/ + vol_down { + label = "volume_down"; + gpios = <&pm8994_gpios 2 0x1>; + linux,input-type = <1>; + linux,code = <114>; + debounce-interval = <15>; + }; + //endif VENDOR_EDIT + /* + cam_snapshot { + label = "cam_snapshot"; + gpios = <&pm8994_gpios 4 0x1>; + linux,input-type = <1>; + linux,code = <766>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + + cam_focus { + label = "cam_focus"; + gpios = <&pm8994_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <528>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + */ + /*VENDOR_EDIT*/ + /*qiuchangping add begin for hallsensor key 2015-03-25*/ + hallsensor_key { + label = "hallsensor_key"; + gpios = <&msm_gpio 75 1>; + interrupt-parent = <&msm_gpio>; + interrupts = <75 0x0>; + linux,input-type = <5>; + linux,code = <0>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + /*qiuchangping add end*/ + + }; + /*#ifdef VENDOR_EDIT //changhua 2015-02-28 add for tristate switch keys*/ + tri_state_key { + compatible = "oneplus,tri-state-key"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + //interrupts = <77 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + tristate,gpio_key2 = <&msm_gpio 77 0x00>; //Pass a GPIO + //tristate,gpio_key2 = <&msm_gpio 61 0x00>;//use gpio61 for test,MP will use 77 + tristate,gpio_key1 = <&msm_gpio 34 0x00>; + //vdd_io-supply = <&pm8994_s4>; // 1.8V + + /* MSM GPIO active and sleep settings */ + pinctrl-names = "key2_active","key2_suspend"; + pinctrl-0 = <&tristate_key2_active>; + pinctrl-1 = <&tristate_key2_suspend>; + }; + /*#endif VENDOR_EDIT*/ +/*#ifdef VENDOR_EDIT //changhua 2015-03-13 add for switch ANTENNA by gpio*/ + switch_antenna { + compatible = "oneplus,switch-antenna"; + antenna,antenna1_gpio = <&msm_gpio 120 0x00>; + antenna,antenna2_gpio = <&msm_gpio 121 0x00>; + antenna,antenna3_gpio = <&msm_gpio 122 0x00>; + antenna,antenna4_gpio = <&msm_gpio 124 0x00>; + }; + /*#endif VENDOR_EDIT*/ + /*#ifdef VENDOR_EDIT //changhua 2015-02-26 add for rare cover use ADC*/ + switch_theme { + compatible = "oneplus,switch-theme"; + interrupt-parent = <&msm_gpio>; //GPIO Handler + interrupts = <66 0>; //GPIO # and flags + //interrupts = <34 0>; //GPIO # and flags + /* bits[3:0] trigger type and level flags + 1 = low-to-high edge triggered + 2 = high-to-low edge triggered + 4 = active high level-sensitive + 8 = active low level-sensitive + */ + cover,gpio_irq = <&msm_gpio 66 0x00>; //Pass a GPIO + //cover,gpio_irq = <&msm_gpio 34 0x00>; //use gpio34 for test,MP will use 66 + cover,gpio_switch = <&pm8994_gpios 1 0>; + qcom,cover-vadc = <&pm8994_vadc>; + vdd_io-supply = <&pm8994_l21>; + /* MSM GPIO active and sleep settings */ + pinctrl-names = "cover_int_active","cover_int_suspend"; + pinctrl-0 = <&cover_int_active>; + pinctrl-1 = <&cover_int_suspend>; + }; + /*#endif VENDOR_EDIT*/ + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for pa*/ + i2c@f9967000{ + status = "ok"; +test_tfa9890: tfa9890@36 { + compatible = "nxp,tfa9890"; + reg = <0x36>; + nxp,tfa_max-vol-steps=<0x01>; + reset_gpio= <&msm_gpio 106 0>; + status = "okay"; + }; + }; + //endif VENDOR_EDIT + + + sound { + qcom,model = "msm8994-tomtom-mtp-snd-card"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK", + "ultrasound amp", "LINEOUT1", + "ultrasound amp", "LINEOUT3", + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,2015/3/19, changed for 14049 mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"AMIC5", "MIC BIAS3 External", + //"MIC BIAS3 External", "Analog Mic5", + //"AMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Analog Mic6", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#else + + "AMIC2", "MIC BIAS2 External", + "MIC BIAS2 External", "Headset Mic", + /*zhiguang.su@MultiMedia.AudioDrv ,2015/6/19, not to use internal resistance*/ + "AMIC3", "MIC BIAS3 External", + "MIC BIAS3 External", "Primary Mic", + "AMIC4", "MIC BIAS1 External", + "MIC BIAS1 External", "Noise Mic"; + + + + //#endif + + + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , delete for no swap for us-euro detect*/ + /* + qcom,us-euro-gpios = <&pm8994_mpps 2 0>; + */ + //endif VENDOR_EDIT + qcom,cdc-micbias2-headset-only; + /* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,mbhc-audio-jack-type = "6-pole-jack"; + */ + qcom,mbhc-audio-jack-type = "4-pole-jack"; + /* Modified end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + qcom,ext-ult-spk-amp-gpio = <&pmi8994_gpios 1 0>; + /* Commented begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + qcom,hdmi-audio-rx; + */ + /* Commented end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + asoc-codec = <&stub_codec>, <&hdmi_audio>; + asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-audio-codec-rx"; + }; +}; + +&pm8994_gpios { + + //#ifdef VENDOR_EDIT + /* changhua.li 2015-02-13 add for cover switch theme*/ + gpio@c000 { /* GPIO 1 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + //qcom,vin-sel = <2>; /* VIN 2 */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + //#ifdef VENDOR_EDIT + /*for vol- support*/ + gpio@c100 { /* GPIO 2 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + //#endif /* VENDOR_EDIT */ + gpio@c200 { /* GPIO 3 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c300 { /* GPIO 4 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 */ + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <2>; + qcom,src-sel = <0>; + status = "okay"; + }; + + gpio@c600 { /* GPIO 7 */ + /* NFC pwr request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c900 { /* GPIO 10 */ + /* NFC clk request */ + qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */ + qcom,pull = <5>; /* QPNP_PIN_PULL_NO */ + qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */ + qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */ + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@c700 { /* GPIO 8 */ + qcom,mode = <0>; /* Digital in */ + qcom,pull = <0>; /* PULL up 30uA */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output high */ + qcom,vin-sel = <2>; /* Logical 1 voltage value 1.8v */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* Low drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@c800 { /* GPIO 9 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <1>; /* Output high */ + qcom,vin-sel = <0>; /* VPH_PWR */ + qcom,src-sel = <0>; /* Constant */ + qcom,out-strength = <1>; /* High drive strength */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@cd00 { /* GPIO 14 */ + status = "okay"; + }; + + gpio@ce00 { /* GPIO 15 */ + qcom,mode = <1>; + qcom,output-type = <0>; + qcom,pull = <5>; + qcom,vin-sel = <2>; + qcom,out-strength = <1>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + status = "okay"; + }; + + gpio@d100 { /* GPIO 18 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,invert = <0>; /* Output low initially */ + qcom,vin-sel = <2>; /* VIN 2 */ + qcom,src-sel = <3>; /* Function 2 */ + qcom,out-strength = <2>; /* Medium */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; + + gpio@d200 { /* GPIO 19 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#ifndef VENDOR_EDIT */ +//shankai@driver.bsp 2015.4.30 add for drv 2605 enable pin control + gpio@d500 { /* GPIO 22 */ + qcom,mode = <1>; /* Digital output*/ + qcom,pull = <4>; /* Pulldown 10uA */ + qcom,vin-sel = <2>; /* VIN2 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +/*#end VENDOR_EDIT*/ +}; + +&pm8994_mpps { +/*#ifndef VENDOR_EDIT //changhua 2015-02-26 remove for rare cover use ADC(PM8994 MPP4) and pcb rf use adc*/ + //mpp@a100 { /* MPP 2 */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // status = "okay"; + //}; + + //mpp@a300 { /* MPP 4 */ + // /* HDMI_5v_vreg regulator enable */ + // qcom,mode = <1>; /* Digital output */ + // qcom,output-type = <0>; /* CMOS logic */ + // qcom,vin-sel = <2>; /* S4 1.8V */ + // qcom,src-sel = <0>; /* Constant */ + // qcom,master-en = <1>; /* Enable GPIO */ + // qcom,invert = <0>; + // status = "okay"; + //}; + /*#end VENDOR_EDIT*/ +}; + +&slim_msm { + tomtom_codec { + +//#ifndef VENDOR_EDIT +// /*zhiguang.su@MultiMedia.AudioDrv ,change for 14049*/ +// qcom,cdc-micbias1-ext-cap; +// qcom,cdc-micbias3-ext-cap; +// qcom,cdc-micbias4-ext-cap; +//#endif + + cdc-vdd-spkdrv-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-current = <600000>; + + cdc-vdd-spkdrv-2-supply = <&pmi8994_boost_pin_ctrl>; + qcom,cdc-vdd-spkdrv-2-voltage = <5000000 5000000>; + qcom,cdc-vdd-spkdrv-2-current = <600000>; + + qcom,cdc-on-demand-supplies = "cdc-vdd-spkdrv", + "cdc-vdd-spkdrv-2"; + }; +}; + +&pmi8994_gpios { + gpio@c000 { /* GPIO 1 Ultrasound PA EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* CONSTANT */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c400 { /* GPIO 5 OTG SWITCH EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c100 { /* GPIO 2 LM3630 backlight output EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + + gpio@c200 { /* GPIO 3 TPS65132 +5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; + gpio@c600 { /* GPIO 7 TPS65132 -5V EN */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <2>; /* 1.8 */ + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* ENABLE GPIO */ + status = "okay"; + }; +}; + +//&pmi8994_mpps { +// mpp@a300 { /* MPP 4 */ +// /* WLED FET */ +// qcom,mode = <1>; /* DIGITAL OUT */ +// qcom,vin-sel = <0>; /* VIN0 */ +// qcom,master-en = <1>; +// status = "okay"; +// }; +//}; + +&blsp2_uart2 { + status = "ok"; +}; + +&blsp1_uart2 { + status= "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_sleep>; +}; + +&pcie0 { + status = "disabled"; +}; + +&usb3 { + status = "ok"; +}; + +&hsphy0 { + status = "ok"; +}; + +&ssphy0 { + status = "ok"; +}; + +&qcom_crypto1fde { + status = "okay"; +}; + +&qcom_crypto2fde { + status = "okay"; +}; + +&qcom_crypto1pfe { + status = "okay"; +}; + +&qcom_crypto2pfe { + status = "okay"; +}; + +&qcom_cedev { + status = "okay"; +}; + +&i2c_5 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ +//#ifdef VENDOR_EDIT + status = "disabled";//Disabled by likelong 2015.5.18, as there is no FM on 14049, and there is a conflict with Laser sensor. +//#endif/*VENDOR_EDIT*/ + compatible = "silabs,si4705"; + reg = <0x11>; + vdd-supply = <&pm8994_s4>; + silabs,vdd-supply-voltage = <1800000 1800000>; + va-supply = <&bt_vreg>; + silabs,va-supply-voltage = <3300000 3300000>; + pinctrl-names = "pmx_fm_active","pmx_fm_suspend"; + pinctrl-0 = <&fm_int_active &fm_status_int_active &fm_rst_active>; + pinctrl-1 = <&fm_int_suspend &fm_status_int_suspend &fm_rst_suspend>; + silabs,reset-gpio = <&msm_gpio 62 0>; + silabs,int-gpio = <&msm_gpio 9 0>; + silabs,status-gpio = <&msm_gpio 11 0>; + #address-cells = <0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = < + 0 &msm_gpio 9 2 + 1 &msm_gpio 11 1 + >; + interrupt-names = "silabs_fm_int", "silabs_fm_status_int"; + }; +}; + +/{ + mtp_batterydata: qcom,battery-data { + //#ifdef VENDOR_EDIT//for chg, do not match batt ID and let pmi8994 to charge now, later we will use external charger + qcom,batt-id-range-pct = <30>; + //#endif + #include "batterydata_oneplus_ATL_3300mAh.dtsi" + #include "batterydata_oneplus_SDI_3300mAh.dtsi" + #include "batterydata-unkown-3300mah.dtsi" + + }; +}; + +&pmi8994_fg { + qcom,battery-data = <&mtp_batterydata>; + qcom,ext-sense-type; +}; + +//#ifdef VENDOR_EDIT // shankai@bsp 2015-4-4 do not use it for vibrator ,comment it. +/* +&pmi8994_haptics { + status = "okay"; +}; +*/ +//#endif +&pmi8994_charger { + qcom,dc-psy-type = "Wipower"; + qcom,dcin-vadc = <&pmi8994_vadc>; + qcom,vph-vadc = <&pm8994_vadc>; + qcom,wipower-default-ilim-map = <4000000 20000000 550 700 300>; + qcom,wipower-pt-ilim-map = <4000000 7140000 550 700 300>, + <7140000 8140000 550 700 300>, + <8140000 9140000 500 700 300>, + <9140000 9950000 500 700 300>; + qcom,wipower-div2-ilim-map = <4000000 4820000 550 700 300>, + <4820000 5820000 550 700 300>, + <5820000 6820000 550 650 650>, + <6820000 7820000 550 700 600>, + <7820000 8500000 550 700 550>; +}; + +&cnss { + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &pcie0_clkreq_default>; +}; + +&i2c_11 { + smb1357-charger@1c { + compatible = "qcom,smb1357-charger"; + //#ifdef VENDOR_EDIT //for chg + status = "disabled"; + //#endif + reg = <0x1c>; + qcom,parallel-charger; + qcom,float-voltage-mv = <4400>; + qcom,recharge-thresh-mv = <100>; + }; +}; + +&usb_ehci { + status = "ok"; + qcom,usb2-enable-uicc; +}; + +&qusb_phy { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-pinctrl.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-pinctrl.dtsi new file mode 100755 index 0000000000000..10807d34bf866 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-pinctrl.dtsi @@ -0,0 +1,1632 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + tlmm_pinmux: pinctrl@fd510000 { + compatible = "qcom,msm-tlmm-8994", "qcom,msm-tlmm-8974"; + reg = <0xfd510000 0x4000>; + interrupts = <0 208 0>; + + /*General purpose pins*/ + gp: gp { + qcom,num-pins = <146>; + #qcom,pin-cells = <1>; + + msm_gpio: msm_gpio { + compatible = "qcom,msm-tlmm-gp"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + qcom,direct-connect-irqs = <8>; + num_irqs = <146>; + }; + }; + + pmx-uartconsole { + qcom,pins = <&gp 4>, <&gp 5>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <2>; + label = "uart-console"; + + uart_console_sleep: uart-console { + drive-strength = <2>; + bias-pull-down; + }; + }; + + blsp2_uart2_active { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <2>; + label = "blsp2_uart2_active"; + hsuart_active: default { + drive-strength = <16>; + bias-disable; + }; + }; + + blsp2_uart2_sleep { + qcom,pins = <&gp 45>, <&gp 46>, <&gp 47>, <&gp 48>; + qcom,num-grp-pins = <4>; + qcom,pin-func = <0>; + label = "blsp2_uart2_sleep"; + hsuart_sleep: sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_mdss: pmx_mdss { + label = "mdss-pins"; + qcom,pin-func = <0>; + mdss_dsi_active: active { + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + mdss_dsi_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + pmx_mdss_te: pmx_mdss_te { + label = "mdss-te-pins"; + qcom,pin-func = <1>; + mdss_te_active: active { + drive-strength = <2>; /* 8 mA */ + bias-pull-down = <0>; /* pull down*/ + input-debounce = <0>; + }; + mdss_te_suspend: suspend { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + input-debounce = <0>; + }; + }; + + pmx_hdmi_cec: pmx_hdmi_cec { + qcom,pin-func = <1>; + label = "hdmi-cec-pins"; + mdss_hdmi_cec_active: cec_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_cec_suspend: cec_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_ddc: pmx_hdmi_ddc { + qcom,pin-func = <1>; + label = "hdmi-ddc-pins"; + mdss_hdmi_ddc_active: ddc_active { + drive-strength = <2>; + bias-pull-up; + }; + mdss_hdmi_ddc_suspend: ddc_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pmx_hdmi_hpd: pmx_hdmi_hpd { + qcom,pin-func = <1>; + label = "hdmi-hpd-pin"; + mdss_hdmi_hpd_active: hpd_active { + drive-strength = <16>; + bias-pull-down; + }; + mdss_hdmi_hpd_suspend: hpd_suspend { + drive-strength = <2>; + bias-pull-down; + }; + }; + + mhl_intr: mhl_intr { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_intr"; + + mhl_intr_active: mhl_intr_active { + bias-pull-up; + input-enable; + }; + }; + + mhl_reset: mhl_reset { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "mhl_reset"; + + mhl_reset_active: mhl_reset_active { + drive-strength = <2>; + bias-pull-down; + output-low; + }; + }; + + spi_0_active { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-active"; + + spi_0_active: spi_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_0_suspend { + /* MOSI, MISO, CLK */ + qcom,pins = <&gp 0>, <&gp 1>, <&gp 3>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_0-suspend"; + + spi_0_sleep: spi_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_cs1_active { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-active"; + + spi_0_cs1_active: cs1_active { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + spi_cs1_suspend { + /* CS1 */ + qcom,pins = <&gp 8>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "spi_0-cs1-suspend"; + + spi_0_cs1_sleep: cs1_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + pmx_i2c_1 { + qcom,pins = <&gp 2>, <&gp 3>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_1"; + + status = "disabled"; + + i2c_1_active: i2c_1_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_1_sleep: i2c_1_sleep { + drive-strength = <2>; + bias-disable; + }; + }; +//#ifdef VENDOR_EDIT//add for fingerprint fpc1150 SPI pin use pinctrl + + spi_12_active { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-active"; + + spi_12_active: spi_12_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_suspend { + qcom,pins = <&gp 85>, <&gp 86>, <&gp 88>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "spi_12-suspend"; + + spi_12_sleep: spi_12_sleep { + drive-strength = <2>; + bias-pull-down; + }; + }; + + spi_12_cs0_active { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-active"; + + spi_12_cs0_active: cs0_active { + drive-strength = <12>; + bias-disable = <0>; + }; + }; + + spi_12_cs0_suspend { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "spi_12-cs0-suspend"; + + spi_12_cs0_sleep: cs0_sleep { + drive-strength = <2>; + bias-disable = <0>; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for tristate key + tristate_key2{ + qcom,pins = <&gp 77>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "tri_state_key2"; + tristate_key2_active: active { + drive-strength = <2>; + bias-disable; + }; + tristate_key2_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + +//#ifdef VENDOR_EDIT//add for switch_cover + switch_cover_int{ + qcom,pins = <&gp 66>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "switch_cover_int"; + cover_int_active: active { + drive-strength = <2>; + bias-disable; + }; + cover_int_suspend: suspend { + drive-strength = <2>; + bias-disable; + }; + }; + +//#endif/*VENDOR_EDIT*/ + + audio_ext_devices { + qcom,pins = <&gp 96>; + qcom,num-grp-pins = <1>; + label = "audio-ext-speakers"; + /* default state */ + audio_ext_speakers: audio_ext_speakers { + drive-strength = <2>; + bias-pull-up; + }; + }; + + /* SDC pin type */ + sdc: sdc { + /* + * 0-3 for sdc1 + * 4-6 for sdc2 + * 7-9 for sdc3 + */ + qcom,num-pins = <10>; + /* + * Order of pins: + * SDC1: CLK -> 0, CMD -> 1, DATA -> 2, RCLK -> 3 + * SDC2: CLK -> 4, CMD -> 5, DATA -> 6 + * SDC3: CLK -> 7, CMD -> 8, DATA -> 9 + */ + #qcom,pin-cells = <1>; + }; + + pmx_sdc1_clk { + qcom,pins = <&sdc 0>; + qcom,num-grp-pins = <1>; + label = "sdc1-clk"; + sdc1_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc1_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_cmd { + qcom,pins = <&sdc 1>; + qcom,num-grp-pins = <1>; + label = "sdc1-cmd"; + sdc1_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_cmd_off: cmd_off { + bias-pull-up = <0x3>; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_data { + qcom,pins = <&sdc 2>; + qcom,num-grp-pins = <1>; + label = "sdc1-data"; + sdc1_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <8>; /* 8 MA */ + }; + sdc1_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc1_rclk { + qcom,pins = <&sdc 3>; + qcom,num-grp-pins = <1>; + label = "sdc1-rclk"; + sdc1_rclk_on: rclk_on { + bias-pull-down; /* pull down */ + }; + sdc1_rclk_off: rclk_off { + bias-pull-down; /* pull down */ + }; + }; + + pmx_sdc2_clk { + qcom,pins = <&sdc 4>; + qcom,num-grp-pins = <1>; + label = "sdc2-clk"; + sdc2_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc2_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_cmd { + qcom,pins = <&sdc 5>; + qcom,num-grp-pins = <1>; + label = "sdc2-cmd"; + sdc2_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc2_data { + qcom,pins = <&sdc 6>; + qcom,num-grp-pins = <1>; + label = "sdc2-data"; + sdc2_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc2_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_clk { + qcom,pins = <&sdc 7>; + qcom,num-grp-pins = <1>; + label = "sdc3-clk"; + sdc3_clk_on: clk_on { + bias-disable; /* NO pull */ + drive-strength = <16>; /* 16 MA */ + }; + sdc3_clk_off: clk_off { + bias-disable; /* NO pull */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_cmd { + qcom,pins = <&sdc 8>; + qcom,num-grp-pins = <1>; + label = "sdc3-cmd"; + sdc3_cmd_on: cmd_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_cmd_off: cmd_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_sdc3_data { + qcom,pins = <&sdc 9>; + qcom,num-grp-pins = <1>; + label = "sdc3-data"; + sdc3_data_on: data_on { + bias-pull-up; /* pull up */ + drive-strength = <10>; /* 10 MA */ + }; + sdc3_data_off: data_off { + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + pmx_i2c_2 { + qcom,pins = <&gp 6>, <&gp 7>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_2"; + + i2c_2_active: i2c_2_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_2_sleep: i2c_2_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_i2c_5 { + qcom,pins = <&gp 83>, <&gp 84>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_5"; + + i2c_5_active: i2c_5_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_5_sleep: i2c_5_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_fm_int_active { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_active"; + + fm_int_active: fm_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_int_suspend { + qcom,pins = <&gp 9>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_int_suspend"; + + fm_int_suspend: fm_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_active { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_active"; + + fm_status_int_active: fm_status_int_active { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_status_int_suspend { + qcom,pins = <&gp 11>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_status_int_suspend"; + + fm_status_int_suspend: fm_status_int_suspend { + drive-strength = <16>; + bias-pull-up; + }; + }; + + pmx_fm_rst_active { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_active"; + + fm_rst_active: fm_rst_active { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_fm_rst_suspend { + qcom,pins = <&gp 62>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_fm_rst_suspend"; + + fm_rst_suspend: fm_rst_suspend { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pmx_i2c_6 { + qcom,pins = <&gp 28>, <&gp 27>; /* SDA, SCL */ + qcom,num-grp-pins = <2>; + qcom,pin-func = <3>; + label = "pmx_i2c_6"; + + i2c_6_active: i2c_6_active { + drive-strength = <2>; + bias-disable; + }; + + i2c_6_sleep: i2c_6_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_rd_nfc_int{ + qcom,pins = <&gp 29>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_int"; + + nfc_int_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_int_suspend: suspend { + drive-strength = <6>; + bias-pull-up; + }; + }; + + pmx_nfc_reset{ + qcom,pins = <&gp 30>; + qcom,pin-func = <0>; + qcom,num-grp-pins = <1>; + label = "pmx_nfc_disable"; + + nfc_disable_active: active { + drive-strength = <6>; + bias-pull-up; + }; + + nfc_disable_suspend: suspend { + drive-strength = <6>; + bias-disable; + }; + }; + +//#ifdef VENDOR_EDIT +/*suzhiguang@Multimdia.audio.driver, remove unused pins which conflic with quat i2s.*/ +// pmx_ts { +// qcom,pins = <&gp 60>, <&gp 61>; +// qcom,pin-func = <0>; +// qcom,num-grp-pins = <2>; +// label = "pmx_ts"; +// +// ts_active: ts_active { +// drive-strength = <16>; +// bias-pull-up; +// }; +// +// ts_suspend: ts_suspend { +// drive-strength = <16>; +// bias-disable; +// }; +// }; +//#endif + + /* CoreSight */ + tpiu_seta_1 { + qcom,pins = <&gp 27>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-1"; + seta_1: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_2 { + qcom,pins = <&gp 28>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-seta-2"; + seta_2: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_3 { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <10>; + label = "tpiu-seta-3"; + seta_3: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_4 { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <11>; + label = "tpiu-seta-4"; + seta_4: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_5 { + qcom,pins = <&gp 63>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "tpiu-seta-5"; + seta_5: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_6 { + qcom,pins = <&gp 64>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-6"; + seta_6: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_7 { + qcom,pins = <&gp 65>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-seta-7"; + seta_7: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_8 { + qcom,pins = <&gp 66>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-8"; + seta_8: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_9 { + qcom,pins = <&gp 67>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-9"; + seta_9: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_10 { + qcom,pins = <&gp 74>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-seta-10"; + seta_10: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_11 { + qcom,pins = <&gp 75>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-11"; + seta_11: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_12 { + qcom,pins = <&gp 76>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-12"; + seta_12: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_13 { + qcom,pins = <&gp 77>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-13"; + seta_13: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_14 { + qcom,pins = <&gp 85>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-14"; + seta_14: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_15 { + qcom,pins = <&gp 86>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-seta-15"; + seta_15: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_16 { + qcom,pins = <&gp 87>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-seta-16"; + seta_16: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_17 { + qcom,pins = <&gp 89>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-17"; + seta_17: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_seta_18 { + qcom,pins = <&gp 90>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-seta-18"; + seta_18: seta { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_1 { + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-1"; + setb_1: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_2 { + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "tpiu-setb-2"; + setb_2: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_3 { + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-3"; + setb_3: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_4 { + qcom,pins = <&gp 16>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <3>; + label = "tpiu-setb-4"; + setb_4: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_5 { + qcom,pins = <&gp 17>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-5"; + setb_5: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_6 { + qcom,pins = <&gp 18>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-6"; + setb_6: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_7 { + qcom,pins = <&gp 19>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-7"; + setb_7: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_8 { + qcom,pins = <&gp 21>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-8"; + setb_8: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_9 { + qcom,pins = <&gp 22>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <6>; + label = "tpiu-setb-9"; + setb_9: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_10 { + qcom,pins = <&gp 23>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-10"; + setb_10: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_11 { + qcom,pins = <&gp 25>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <8>; + label = "tpiu-setb-11"; + setb_11: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_12 { + qcom,pins = <&gp 26>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-12"; + setb_12: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_13 { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-13"; + setb_13: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_14 { + qcom,pins = <&gp 58>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-14"; + setb_14: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_15 { + qcom,pins = <&gp 91>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-15"; + setb_15: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_16 { + qcom,pins = <&gp 92>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <5>; + label = "tpiu-setb-16"; + setb_16: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_17 { + qcom,pins = <&gp 93>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-17"; + setb_17: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + tpiu_setb_18 { + qcom,pins = <&gp 94>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <7>; + label = "tpiu-setb-18"; + setb_18: setb { + drive-strength = <16>; + bias-disable; + }; + }; + + cti_trigout_a { + qcom,pins = <&gp 56>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <9>; + label = "cti-trigout-a"; + trigout_a: trigout_a { + drive-strength = <2>; + bias-disable; + }; + }; + + cti_trigout_c { + qcom,pins = <&gp 41>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <4>; + label = "cti-trigout-c"; + trigout_c: trigout_c { + drive-strength = <2>; + bias-disable; + }; + }; + + cci0_active { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci0-active"; + /* active state */ + cci0_active: cci0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci0_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 17>, <&gp 18>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci0-suspend"; + /*suspended state */ + cci0_suspend: cci0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_active { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "cci1-active"; + /* active state */ + cci1_active: cci1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cci1_suspend { + /* CLK, DATA */ + qcom,pins = <&gp 19>, <&gp 20>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <0>; + label = "cci1-suspend"; + /*suspended state */ + cci1_suspend: cci1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_active { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk0_active"; + /* active state */ + cam_sensor_mclk0_active: cam_sensor_mclk0_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk0_suspend { + /* MCLK0 */ + qcom,pins = <&gp 13>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk0_suspend"; + /*suspended state */ + cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear_active { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_active"; + /* active state */ + cam_sensor_rear_active: cam_sensor_rear_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear_suspend { + /* RESET, STANDBY */ +//#ifdef VENDOR_EDIT +//changed by zhangxiaowei@camera 20150321 for gpio control Vaf + qcom,pins = <&gp 92>, <&gp 93>; +//#else + //qcom,pins = <&gp 92>, <&gp 91>; +//#endif/*VENDOR_EDIT*/ + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear_suspend"; + /*suspended state */ + cam_sensor_rear_suspend: cam_sensor_rear_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_active { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk1_active"; + /* active state */ + cam_sensor_mclk1_active: cam_sensor_mclk1_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk1_suspend { + /* MCLK2 */ + qcom,pins = <&gp 14>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk1_suspend"; + /* suspend state */ + cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_rear2_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_active"; + /* active state */ + cam_sensor_rear2_active: cam_sensor_rear2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_rear2_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 94>, <&gp 93>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_rear2_suspend"; + /*suspended state */ + cam_sensor_rear2_suspend: cam_sensor_rear2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_active { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "cam_sensor_mclk2_active"; + /* active state */ + cam_sensor_mclk2_active: cam_sensor_mclk2_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_mclk2_suspend { + /* MCLK2 */ + qcom,pins = <&gp 15>; + qcom,num-grp-pins = <1>; + label = "cam_sensor_mclk2_suspend"; + /* suspend state */ + cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { + drive-strength = <2>; /* 2 MA */ + bias-pull-down; /* PULL DOWN */ + }; + }; + + cam_sensor_front_active { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_active"; + /* active state */ + cam_sensor_front_active: cam_sensor_front_active { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cam_sensor_front_suspend { + /* RESET, STANDBY */ + qcom,pins = <&gp 104>, <&gp 105>; + qcom,num-grp-pins = <2>; + label = "cam_sensor_front_suspend"; + /*suspended state */ + cam_sensor_front_suspend: cam_sensor_front_suspend { + drive-strength = <2>; /* 2 MA */ + bias-disable; /* No PULL */ + }; + }; + + cnss_pmux: cnss_pmux { + qcom,pins = <&gp 113>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss_pins"; + cnss_default: default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + cnss_lpass: cnss_lpass { + qcom,pins = <&gp 112>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "cnss-lpass"; + /* default state */ + cnss_lpass_default: cnss_lpass_default { + drive-strength = <16>; + bias-pull-down; + }; + }; + + pcie0_clkreq { + qcom,pins = <&gp 54>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie0-clkreq"; + /* default state */ + pcie0_clkreq_default: pcie0_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie0_perst { + qcom,pins = <&gp 53>; + qcom,num-grp-pins = <1>; + label = "pcie0-perst"; + /* default state */ + pcie0_perst_default: pcie0_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie0_wake { + qcom,pins = <&gp 55>; + qcom,num-grp-pins = <1>; + label = "pcie0-wake"; + /* default state */ + pcie0_wake_default: pcie0_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_clkreq { + qcom,pins = <&gp 36>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <2>; + label = "pcie1-clkreq"; + /* default state */ + pcie1_clkreq_default: pcie1_clkreq_default { + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_perst { + qcom,pins = <&gp 35>; + qcom,num-grp-pins = <1>; + label = "pcie1-perst"; + /* default state */ + pcie1_perst_default: pcie1_perst_default { + drive-strength = <2>; + bias-pull-down; + }; + }; + + pcie1_wake { + qcom,pins = <&gp 37>; + qcom,num-grp-pins = <1>; + label = "pcie1-wake"; + /* default state */ + pcie1_wake_default: pcie1_wake_default { + drive-strength = <2>; + bias-pull-down; + }; + + pcie1_wake_sleep: pcie1_wake_sleep { + drive-strength = <2>; + bias-disable; + }; + }; + + pmx_sec_aux_pcm_sleep { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_sleep"; + sec_aux_pcm_sleep: sec_aux_pcm_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_active { + qcom,pins = <&gp 79>, <&gp 80>, <&gp 82>; + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_active"; + sec_aux_pcm_active: sec_aux_pcm_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_sec_aux_pcm_din_sleep { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <0>; + label = "pmx_sec_aux_pcm_din_sleep"; + sec_aux_pcm_din_sleep: sec_aux_pcm_din_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + input-enable; + }; + }; + + pmx_sec_aux_pcm_din_active { + qcom,pins = <&gp 81>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "pmx_sec_aux_pcm_din_active"; + sec_aux_pcm_din_active: sec_aux_pcm_din_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#ifdef VENDOR_EDIT +// pmx_pri_mi2s_sleep { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sleep"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_active { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_active"; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0_sleep { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <0>; +// label = "pri_mi2s_sd0_sleep"; +//pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// input-enable; +// }; +// }; + +// pmx_pri_mi2s_sd0_active { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0_active"; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; + +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ +// pmx_pri_mi2s { +// qcom,pins = <&gp 65>, <&gp 66>; +// qcom,num-grp-pins = <2>; +// qcom,pin-func = <1>; +// label = "pri_mi2s"; +// pri_mi2s_sleep: pri_mi2s_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_active: pri_mi2s_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// output-high; +// }; +// }; + +// pmx_pri_mi2s_sd0 { +// qcom,pins = <&gp 67>; +// qcom,num-grp-pins = <1>; +// qcom,pin-func = <1>; +// label = "pri_mi2s_sd0"; +// pri_mi2s_sd0_sleep: pri_mi2s_sd0_sleep { +// drive-strength = <2>; /* 2 mA */ +// bias-pull-down; /* PULL DOWN */ +// }; +// pri_mi2s_sd0_active: pri_mi2s_sd0_active { +// drive-strength = <2>; /* 2 mA */ +// bias-disable; /* NO PULL */ +// }; +// }; +//#endif + + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv ,add for quat i2s*/ + pmx_quat_mi2s { + qcom,pins = <&gp 58>, <&gp 59>; + qcom,num-grp-pins = <2>; + qcom,pin-func = <1>; + label = "quat_mi2s"; + quat_mi2s_sleep: quat_mi2s_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_active: quat_mi2s_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + output-high; + }; + }; + + pmx_quat_mi2s_mclk { + qcom,pins = <&gp 57>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_mclk"; + quat_mi2s_mclk_sleep: quat_mi2s_mclk_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_mclk_active: quat_mi2s_mclk_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd0 { + qcom,pins = <&gp 60>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd0"; + quat_mi2s_sd0_sleep: quat_mi2s_sd0_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd0_active: quat_mi2s_sd0_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + + pmx_quat_mi2s_sd1 { + qcom,pins = <&gp 61>; + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "quat_mi2s_sd1"; + quat_mi2s_sd1_sleep: quat_mi2s_sd1_sleep { + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* PULL DOWN */ + }; + quat_mi2s_sd1_active: quat_mi2s_sd1_active { + drive-strength = <8>; /* 8 mA */ + bias-disable; /* NO PULL */ + }; + }; + +//#endif VENDOR_EDIT + + tsif0_signals { + qcom,pins = <&gp 89>, /* TSIF0 CLK */ + <&gp 90>, /* TSIF0 Enable */ + <&gp 91>; /* TSIF0 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif0-signals"; + tsif0_signals_active: tsif0_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif0_sync { + qcom,pins = <&gp 110>; /* TSIF0 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif0-sync"; + tsif0_sync_active: tsif0_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + tsif1_signals { + qcom,pins = <&gp 93>, /* TSIF1 CLK */ + <&gp 94>, /* TSIF1 Enable */ + <&gp 95>; /* TSIF1 DATA */ + qcom,num-grp-pins = <3>; + qcom,pin-func = <1>; + label = "tsif1-signals"; + tsif1_signals_active: tsif1_signals_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + + /* sync signal is only used if configured to mode-2 */ + tsif1_sync { + qcom,pins = <&gp 96>; /* TSIF1 SYNC */ + qcom,num-grp-pins = <1>; + qcom,pin-func = <1>; + label = "tsif1-sync"; + tsif1_sync_active: tsif1_sync_active { + drive_strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pm8004.dtsi new file mode 100755 index 0000000000000..c495f2c6e786b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pm8004.dtsi @@ -0,0 +1,48 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm8994-pm8994-pmi8994-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000C 0x0 0x0>; +}; + +&rpm_bus { + /delete-node/ rpm-regulator-bstb; + /delete-node/ rpm-regulator-bbyb; + /delete-node/ rpm-regulator-smpb1; + /delete-node/ rpm-regulator-smpc2; + + rpm-regulator-smpb2 { + pm8004_s2_corner: regulator-s2-corner { + regulator-name = "pm8004_s2_corner"; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + regulator-name = "pm8004_s2_floor_corner"; + }; + }; +}; + +&spmi_bus { + /delete-node/ qcom,pmi8994@2; + /delete-node/ qcom,pmi8994@3; +}; + +&usb3 { + /delete-property/ vbus_dwc3-supply; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pmi8994-pm8004.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pmi8994-pm8004.dtsi new file mode 100755 index 0000000000000..ee5fc8594ceb2 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-pm8994-pmi8994-pm8004.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only chipset-specific property overrides should be placed + * inside this file. + */ + +#include "msm-pm8004.dtsi" + +/ { + qcom,pmic-id = <0x10009 0x1000A 0x1000C 0x0>; +}; + +&rpm_bus { + rpm-regulator-smpb2 { + status = "disabled"; + }; + + rpm-regulator-smpc2 { + status = "okay"; + regulator-s2-corner { + status = "okay"; + }; + + regulator-s2-floor-corner { + status = "okay"; + }; + }; +}; + +/* + * Override PMI8994 resources with proper PM8004 resources for + * MSM8994 with PM8004. + */ + +&soc { + qcom,msm-thermal { + vdd-gfx-supply = <&pm8004_s2_floor_corner>; + }; +}; + +&gdsc_oxili_gx { + parent-supply = <&pm8004_s2_corner>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-regulator.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-regulator.dtsi new file mode 100755 index 0000000000000..fe12c7b1b7e43 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-regulator.dtsi @@ -0,0 +1,987 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&rpm_bus { + /* PM8994 S1 + S6 = 2 phase VDD_CX supply */ + rpm-regulator-smpa1 { + status = "okay"; + pm8994_s1_corner: regulator-s1-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s1_floor_corner: regulator-s1-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + + pm8994_s1_corner_ao: regulator-s1-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s1_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <4>; + regulator-max-microvolt = <7>; + regulator-always-on; + qcom,init-voltage-corner = <6>; + qcom,use-voltage-corner; + proxy-supply = <&pm8994_s1_corner_ao>; + qcom,proxy-consumer-voltage = <7 7>; + }; + }; + + /* PM8994 S2 + S12 = 2 phase VDD_MX supply */ + rpm-regulator-smpa2 { + status = "okay"; + pm8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8994_s2_corner_ao: regulator-s2-corner-ao { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8994_s2_corner_ao"; + qcom,set = <1>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + }; + + rpm-regulator-smpa3 { + status = "okay"; + pm8994_s3: regulator-s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + qcom,init-voltage = <1300000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa4 { + status = "okay"; + pm8994_s4: regulator-s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa5 { + status = "okay"; + pm8994_s5: regulator-s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + qcom,init-voltage = <2150000>; + status = "okay"; + }; + }; + + rpm-regulator-smpa7 { + status = "okay"; + pm8994_s7: regulator-s7 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa1 { + status = "okay"; + pm8994_l1: regulator-l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa2 { + status = "okay"; + pm8994_l2: regulator-l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + proxy-supply = <&pm8994_l2>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa3 { + status = "okay"; + pm8994_l3: regulator-l3 { + /*liuyan 2015/7/20,change 1.2 to 1.25*/ + /*#ifndef VENDOR_EDIT*/ + /*regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>;*/ + /*#else*/ + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + qcom,init-voltage = <1250000>; + /*#endif*/ + status = "okay"; + }; + }; + + rpm-regulator-ldoa4 { + status = "okay"; + pm8994_l4: regulator-l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + qcom,init-voltage = <1225000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa6 { + status = "okay"; + pm8994_l6: regulator-l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa8 { + status = "okay"; + pm8994_l8: regulator-l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa9 { + status = "okay"; + pm8994_l9: regulator-l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa10 { + status = "okay"; + pm8994_l10: regulator-l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa11 { + status = "okay"; + pm8994_l11: regulator-l11 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa12 { + status = "okay"; + pm8994_l12: regulator-l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l12>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa13 { + status = "okay"; + pm8994_l13: regulator-l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa14 { + status = "okay"; + pm8994_l14: regulator-l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + proxy-supply = <&pm8994_l14>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa15 { + status = "okay"; + pm8994_l15: regulator-l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa16 { + status = "okay"; + pm8994_l16: regulator-l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; +//#ifdef VENDOR_EDIT //FIX GPS power issue + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa17 { + status = "okay"; + pm8994_l17: regulator-l17 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + qcom,init-voltage = <2700000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa18 { + status = "okay"; + pm8994_l18: regulator-l18 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + qcom,init-voltage = <2850000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa19 { + status = "okay"; + pm8994_l19: regulator-l19 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa20 { + status = "okay"; + pm8994_l20: regulator-l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; + qcom,init-current = <750>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa21 { + status = "okay"; + pm8994_l21: regulator-l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + qcom,init-voltage = <2950000>; +//#ifdef VENDOR_EDIT //changhua modify for cover + regulator-always-on; +//#endif + status = "okay"; + }; + }; + + rpm-regulator-ldoa22 { + status = "okay"; + pm8994_l22: regulator-l22 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + qcom,init-voltage = <3000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa23 { + status = "okay"; + pm8994_l23: regulator-l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa24 { + status = "okay"; + pm8994_l24: regulator-l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3150000>; + qcom,init-voltage = <3075000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa25 { + status = "okay"; + pm8994_l25: regulator-l25 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa26 { + status = "okay"; + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <987500>; + regulator-max-microvolt = <987500>; + qcom,init-voltage = <987500>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa27 { + status = "okay"; + pm8994_l27: regulator-l27 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + qcom,init-voltage = <1050000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa28 { + status = "okay"; + pm8994_l28: regulator-l28 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + qcom,init-voltage = <1000000>; + qcom,init-current = <45>; + regulator-boot-on; + proxy-supply = <&pm8994_l28>; + qcom,proxy-consumer-enable; + qcom,proxy-consumer-current = <10000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa29 { + status = "okay"; + pm8994_l29: regulator-l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + qcom,init-voltage = <2800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa30 { + status = "okay"; + pm8994_l30: regulator-l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + qcom,init-voltage = <1200000>; + qcom,init-current = <50>; + regulator-boot-on; + status = "okay"; + }; + }; + + rpm-regulator-ldoa32 { + status = "okay"; + pm8994_l32: regulator-l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; + status = "okay"; + }; + }; + + rpm-regulator-vsa1 { + status = "okay"; + pm8994_lvs1: regulator-lvs1 { + status = "okay"; + }; + }; + + rpm-regulator-vsa2 { + status = "okay"; + pm8994_lvs2: regulator-lvs2 { + status = "okay"; + }; + }; + + rpm-regulator-smpb1 { + status = "okay"; + pmi8994_s1: regulator-s1 { + regulator-min-microvolt = <1025000>; + regulator-max-microvolt = <1025000>; + qcom,init-voltage = <1025000>; + status = "okay"; + }; + }; + + /* PMI8994 S2 + S3 = 2 phase VDD_GFX supply */ + rpm-regulator-smpb2 { + status = "okay"; + pmi8994_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pmi8994_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; + + rpm-regulator-bstb { + status = "okay"; + pmi8994_boost_5v: regulator-bst { + /* + * When enabled, the PMI8994 Boost regulator always + * outputs 5V. This takes precedence over the pin + * control boost regulator request. + */ + regulator-name = "pmi8994_boost_5v"; + status = "okay"; + }; + pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl { + /* + * When enabled, the output voltage of the PMI8994 + * boost regulator is determined by the state of the + * REQ_5V_BST pin. If the pin signal is high, then the + * regulator outputs 5V. If the pin signal is low, then + * the regulator outputs VPH_PWR voltage. + */ + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pmi8994_boost_pin_ctrl"; + qcom,set = <3>; + qcom,enable-with-pin-ctrl = <0 1>; + }; + }; + + rpm-regulator-bbyb { + status = "okay"; + pmi8994_boostbypass: regulator-bby { + status = "okay"; + regulator-min-microvolt = <3150000>; + regulator-max-microvolt = <3600000>; + qcom,init-voltage = <3150000>; + }; + }; + + /* PM8004 S2 + S4 = 2 phase VDD_GFX supply */ + rpm-regulator-smpc2 { + status = "disabled"; + pm8004_s2_corner: regulator-s2-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_corner"; + qcom,set = <3>; + qcom,init-voltage-corner = <2>; /* SVS SOC */ + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-corner; + }; + + pm8004_s2_floor_corner: regulator-s2-floor-corner { + compatible = "qcom,rpm-smd-regulator"; + regulator-name = "pm8004_s2_floor_corner"; + qcom,set = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + qcom,use-voltage-floor-corner; + qcom,always-send-voltage; + }; + }; +}; + +/* SPM controlled regulators: */ +&spmi_bus { + qcom,pm8994@1 { + /* PM8994 S8 = VDD_APC0 supply */ + pm8994_s8: spm-regulator@2900 { + compatible = "qcom,spm-regulator"; + reg = <0x2900 0x100>; + regulator-name = "pm8994_s8"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1180000>; + qcom,cpu-num = <0>; + }; + + /* + * PM8994 S9 + S10 + S11 = 3 phase VDD_APC1 supply + * S11 is the gang leader. + */ + pm8994_s11: spm-regulator@3200 { + compatible = "qcom,spm-regulator"; + reg = <0x3200 0x100>; + regulator-name = "pm8994_s11"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1225000>; + qcom,cpu-num = <4>; + }; + }; +}; + +/* CPR controlled regulators */ +&soc { + mem_acc0_vreg_corner: mem-acc0-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900d084 1>, <0xf900d088 1>, + <0xf900d08c 1>, <0xf900d090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc0_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type2 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type3 = <0x02 0x02 0x00 0x00>; + qcom,mem-acc-type4 = <0x02 0x02 0x00 0x00>; + }; + + mem_acc1_vreg_corner: mem-acc1-regulator { + compatible = "qcom,mem-acc-regulator"; + reg = <0xf900f084 1>, <0xf900f088 1>, + <0xf900f08c 1>, <0xf900f090 1>; + reg-names = "mem-acc-type1", "mem-acc-type2", + "mem-acc-type3", "mem-acc-type4"; + regulator-name = "mem_acc1_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <4>; + qcom,corner-acc-map = <1 1 0 0>; + qcom,mem-acc-type1 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type2 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type3 = <0x02 0x02 0x06 0x06>; + qcom,mem-acc-type4 = <0x0b 0x0b 0x0b 0x0b>; + }; + + apc0_vreg_corner: regulator@f9019000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf9019000 0x1000>, <0xf900d064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 16 0>; + regulator-name = "apc0_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <13>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1180000>; + qcom,cpr-voltage-floor = <700000 700000 780000 835000>; + vdd-apc-supply = <&pm8994_s8>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc0_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <12>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <82 82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <800000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 3 3 3 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0xFFFFFFFF 0 900000 900000 900000 900000 + 1000000 1000000 1000000 1115000 + 1115000 1180000 1180000 1180000 + 1180000>; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 700000 700000 700000 725000 + 780000 800000 825000 835000 + 850000 915000 970000 980000 + 1000000>; + + qcom,cpr-fuse-version-map = + <0xffffffff 0xffffffff 1 0 0 0 0>, + <0xffffffff 0xffffffff 2 0 0 0 0>, + <0xffffffff 0xffffffff 3 0 0 0 0>, + <0xffffffff 0xffffffff 4 0 0 0 0>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-50)>, + <0 0 0 (-50)>, + <0 (-50) (-90) 40>, + <0 (-50) (-90) 0>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-25000)>, + <0 0 0 (-25000)>, + <0 (-25000) (-25000) 20000>, + <0 (-25000) (-25000) 0>; + + qcom,cpr-scaled-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for SVS2 */ + <2 300000000>, + <3 384000000>, + <4 460800000>, + <5 600000000>, + <6 672000000>, + <7 768000000>, + <8 864000000>, + <9 960000000>, + <10 1248000000>, + <11 1344000000>, + <12 1478400000>, + <13 1555200000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 4 7 13>; + qcom,cpr-enable; + }; + + apc1_vreg_corner: regulator@f901a000 { + compatible = "qcom,cpr-regulator"; + reg = <0xf901a000 0x1000>, <0xf900f064 4>, <0xfc4bc000 0x1000>; + reg-names = "rbcpr", "rbcpr_clk", "efuse_addr"; + interrupts = <0 19 0>; + regulator-name = "apc1_corner"; + qcom,cpr-fuse-corners = <4>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <17>; + + qcom,cpr-voltage-ceiling = <900000 900000 1000000 1225000>; + qcom,cpr-voltage-floor = <700000 700000 750000 835000>; + vdd-apc-supply = <&pm8994_s11>; + + qcom,vdd-mx-corner-map = <3 4 5 7>; + qcom,vdd-mx-vmax = <7>; + qcom,vdd-mx-vmin-method = <4>; + vdd-mx-supply = <&pm8994_s2_corner_ao>; + + mem-acc-supply = <&mem_acc1_vreg_corner>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-irq-line = <0>; + qcom,cpr-step-quotient = <14 14 12 12 12 12 7 8>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-time = <1>; + qcom,cpr-clamp-timer-interval = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-apc-volt-step = <5000>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <21 29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-fuse-ro-sel = <72 72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 3 0>; + qcom,speed-bin-fuse-sel = <22 0 3 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <0 8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4>; + qcom,cpr-voltage-ceiling-override = + <0 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>, + <1 0 900000 900000 900000 900000 900000 + 1000000 1000000 1000000 1160000 1160000 + 1160000 1160000 1160000 1225000 1225000 + 1225000 1225000>; + qcom,cpr-voltage-floor-override = + <0 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>, + <1 0 700000 700000 700000 700000 725000 + 750000 775000 795000 835000 860000 + 880000 895000 915000 935000 945000 + 950000 980000>; + + qcom,cpr-fuse-version-map = + <0 0xffffffff 1 6 6 6 6>, + <0 0xffffffff 2 6 6 6 6>, + <0 0xffffffff 2 4 4 4 4>, + <0 0xffffffff 3 4 4 4 4>, + <0 0xffffffff 4 4 4 4 4>, + <1 0xffffffff 3 4 4 4 4>, + <1 0xffffffff 4 4 4 4 4>; + qcom,cpr-quotient-adjustment = + <0 0 0 (-24)>, + <0 0 0 (-24)>, + <0 0 0 (-84)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>, + <0 0 (-105) (-115)>; + qcom,cpr-init-voltage-adjustment = + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 0 (-15000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>, + <0 0 (-25000) (-35000)>; + qcom,cpr-cpus = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,cpr-online-cpu-virtual-corner-init-voltage-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-10000) (-10000) (-10000) (-15000) (-15000) (-20000) 0 (-20000) (-30000) >, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-5000) (-5000) (-5000) (-5000) (-5000) (-10000) 0 (-10000) (-10000) >, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + qcom,cpr-online-cpu-virtual-corner-quotient-adjustment = + /* 1st fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 2nd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-6) (-6) (-6) (-9) (-9) (-12) 0 (-12) (-18)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-3) (-3) (-3) (-3) (-3) (-6) 0 (-6) (-6)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 3rd fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 4th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 5th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 6th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 4 CPUs online */ + /* 7th fuse version tuple matched */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 0 CPUs online */ + <0 0 0 0 0 0 0 0 (-21) (-21) (-21) (-31) (-31) (-42) 0 (-42) (-63)>, /* 1 CPUs online */ + <0 0 0 0 0 0 0 0 (-10) (-10) (-10) (-10) (-10) (-21) 0 (-21) (-21)>, /* 2 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, /* 3 CPUs online */ + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; /* 4 CPUs online */ + + qcom,cpr-online-cpu-init-voltage-as-ceiling; + qcom,cpr-voltage-scaling-factor-max = <0 0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 300000000>, /* SVS Fmin for "SVS2" */ + <2 300000000>, + <3 384000000>, + <4 480000000>, + <5 633600000>, + <6 768000000>, + <7 864000000>, + <8 960000000>, + <9 1248000000>, + <10 1344000000>, + <11 1440000000>, + <12 1536000000>, + <13 1632000000>, + <14 1728000000>, + <15 1766400000>, + <16 1824000000>, + <17 1958400000>; + qcom,cpr-speed-bin-max-corners = + <0 0 1 5 8 17>, + <1 0 1 5 8 15>; + qcom,cpr-enable; + }; + + bt_vreg: bt_vreg { + compatible = "regulator-fixed"; + regulator-name = "bt_vreg"; + startup-delay-us = <4000>; + enable-active-high; + gpio = <&pm8994_gpios 9 0>; + }; + + usb_otg_switch: usb-otg-switch { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vreg"; + vin-supply = <&smbcharger_external_otg>; + enable-active-high; + gpio = <&pmi8994_gpios 5 0>; + }; +}; + +&pmi8994_charger { + otg-parent-supply = <&pmi8994_boost_5v>; + smbcharger_charger_otg: qcom,smbcharger-boost-otg { + regulator-name = "smbcharger_charger_otg"; + }; + + smbcharger_external_otg: qcom,smbcharger-external-otg { + regulator-name = "smbcharger_external_otg"; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-smp2p.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-smp2p.dtsi new file mode 100755 index 0000000000000..c40cdaf335e8b --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-smp2p.dtsi @@ -0,0 +1,169 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +&soc { + qcom,smp2p-modem { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <1>; + qcom,irq-bitmask = <0x4000>; + interrupts = <0 27 1>; + }; + + qcom,smp2p-adsp { + compatible = "qcom,smp2p"; + reg = <0xf900d008 0x4>; + qcom,remote-pid = <2>; + qcom,irq-bitmask = <0x400>; + interrupts = <0 158 1>; + }; + + smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_in { + compatible = "qcom,smp2pgpio_test_smp2p_7_in"; + gpios = <&smp2pgpio_smp2p_7_in 0 0>; + }; + + smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <7>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_7_out { + compatible = "qcom,smp2pgpio_test_smp2p_7_out"; + gpios = <&smp2pgpio_smp2p_7_out 0 0>; + }; + + smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_in { + compatible = "qcom,smp2pgpio_test_smp2p_1_in"; + gpios = <&smp2pgpio_smp2p_1_in 0 0>; + }; + + smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_1_out { + compatible = "qcom,smp2pgpio_test_smp2p_1_out"; + gpios = <&smp2pgpio_smp2p_1_out 0 0>; + }; + + smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_in { + compatible = "qcom,smp2pgpio_test_smp2p_2_in"; + gpios = <&smp2pgpio_smp2p_2_in 0 0>; + }; + + smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "smp2p"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + qcom,smp2pgpio_test_smp2p_2_out { + compatible = "qcom,smp2pgpio_test_smp2p_2_out"; + gpios = <&smp2pgpio_smp2p_2_out 0 0>; + }; + + /* ssr - inbound entry from lpass. */ + smp2pgpio_ssr_smp2p_2_in: qcom,smp2pgpio-ssr-smp2p-2-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <2>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to lpass */ + smp2pgpio_ssr_smp2p_2_out: qcom,smp2pgpio-ssr-smp2p-2-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - inbound entry from mss. */ + smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "slave-kernel"; + qcom,remote-pid = <1>; + qcom,is-inbound; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + /* ssr - outbound entry to mss. */ + smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out { + compatible = "qcom,smp2pgpio"; + qcom,entry-name = "master-kernel"; + qcom,remote-pid = <1>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-mtp_14049_HW_14.dts b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-mtp_14049_HW_14.dts new file mode 100755 index 0000000000000..bb79055848bb1 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-mtp_14049_HW_14.dts @@ -0,0 +1,26 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8994-v1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <14>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-pm.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-pm.dtsi new file mode 100755 index 0000000000000..371c020d1aa30 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1-pm.dtsi @@ -0,0 +1,593 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-ret = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900D210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 1f 18 03 2f 1b 18 7b d0 2b e0 3b c0 16 6b 26 6b 18 00 + 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 26 6b 16 6b c0 e0 d0 + 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d0 2b e0 3b + c0 16 6b 26 6b 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,use-qchannel-for-pc; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b 14 70 24 80 e0 a0 92 1b + 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 14 70 50 00 40 + 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-retention"; + qcom,spm-cci-mode = "retention"; + qcom,latency-us = <45>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11609>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <1>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1375>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <760>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <775>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <40>; + qcom,ss-power = <1000>; + qcom,energy-overhead = <300000>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1505>; + qcom,ss-power = <83>; + qcom,energy-overhead = <2274420>; + qcom,time-overhead = <6605>; + qcom,min-child-idx = <2>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <30>; + qcom,ss-power = <715>; + qcom,energy-overhead = <17700>; + qcom,time-overhead = <2>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <647>; + qcom,ss-power = <476>; + qcom,energy-overhead = <225300>; + qcom,time-overhead = <350>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <653>; + qcom,ss-power = <163>; + qcom,energy-overhead = <577736>; + qcom,time-overhead = <1000>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 332>, /* sps */ + <0xff 333>; /* ipa */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v1.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1.dtsi new file mode 100755 index 0000000000000..447a74220a008 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v1.dtsi @@ -0,0 +1,246 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v1.dtsi" +#include "msm8994-v1-pm.dtsi" +#include "msm8994-camera-v1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x10000>; + +}; + +&soc { + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 14 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + qcom,apply-cti-pmu-wa; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 14 0xff00>; + qcom,apply-cti-pmu-wa; + }; + + cci@f9100000 { + pmu@a000 { + interrupts = <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>, + <0 7 0>; + }; + }; +}; + +&pm8994_s8 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1115000>; +}; + +&pm8994_s11 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1225000>; +}; + +&ufs1 { + freq-table-hz = + <100000000 171430000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +&mem_acc0_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&mem_acc1_vreg_corner { + regulator-min-microvolt = <1>; + regulator-max-microvolt = <3>; + qcom,corner-acc-map = <1 0 0>; +}; + +&apc0_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <9>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1115000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <16>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <137 0>; + qcom,cpr-fuse-target-quot = <39 47 55>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <116 0 73>; + qcom,cpr-fuse-ro-sel = <82 82 82>; + qcom,cpr-fuse-init-voltage = + <138 0 6 0>, + <138 6 6 0>, + <138 12 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <56 21 43 0>, + <57 55 4 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 800000 840000 860000 860000 + 900000 900000 940000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>, + <9 940800000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 9>; + qcom,cpr-enable; +}; + +&apc1_vreg_corner { + qcom,cpr-fuse-corners = <3>; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <8>; + qcom,vdd-mx-corner-map = <4 5 7>; + + qcom,cpr-voltage-ceiling = <900000 1000000 1225000>; + qcom,cpr-voltage-floor = <725000 840000 940000>; + + qcom,cpr-step-quotient = <10>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <4>; + + qcom,cpr-fuse-row = <138 0>; + qcom,cpr-fuse-target-quot = <29 37 45>; + qcom,cpr-fuse-target-quot-size = <8 8 8>; + qcom,cpr-fuse-target-quot-scale = + <0 10>, + <0 10>, + <0 10>; + qcom,cpr-quotient-adjustment = <36 45 0>; + qcom,cpr-fuse-ro-sel = <72 72 72>; + qcom,cpr-fuse-init-voltage = + <138 54 6 0>, + <138 60 6 0>, + <139 2 6 0>; + qcom,cpr-fuse-revision = <62 48 2 0>; + + qcom,fuse-remap-base-row = <1000>; + qcom,fuse-remap-source = + <57 59 5 0>, + <136 0 42 0>; + qcom,cpr-fuse-redun-sel = <140 61 3 1 0>; + qcom,cpr-fuse-redun-row = <1000 0>; + qcom,cpr-fuse-redun-target-quot = <8 16 24>; + qcom,cpr-fuse-redun-ro-sel = <44 44 44>; + qcom,cpr-fuse-redun-init-voltage = + <1000 32 6 0>, + <1000 38 6 0>, + <1000 38 6 0>; + + qcom,cpr-init-voltage-ref = <900000 1000000 1225000>; + qcom,cpr-init-voltage-step = <10000>; + + qcom,cpr-corner-map = <1 2 2 3 3 3 3 3>; + /delete-property/ qcom,cpr-voltage-ceiling-override; + qcom,cpr-voltage-floor-override = + <0xFFFFFFFF 0 725000 790000 840000 840000 860000 + 890000 920000 940000>; + + /delete-property/ qcom,cpr-fuse-version-map; + /delete-property/ qcom,cpr-init-voltage-adjustment; + + qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>; + qcom,cpr-quot-adjust-scaling-factor-max = <0 2000 2000>; + qcom,cpr-corner-frequency-map = + <1 199200000>, + <2 302400000>, + <3 384000000>, + <4 600000000>, + <5 691200000>, + <6 768000000>, + <7 844800000>, + <8 921600000>; + qcom,cpr-speed-bin-max-corners = + <0xFFFFFFFF 0 1 3 8>; + qcom,cpr-enable; +}; + +&soc { + qcom,usbbam@f9304000 { + qcom,pipe0 { + qcom,pipe-connection-type = <1>; /* USB_BAM_PIPE_SYS2BAM */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2-pm.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2-pm.dtsi new file mode 100755 index 0000000000000..9272b2a079326 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2-pm.dtsi @@ -0,0 +1,690 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + qcom,spm@f9065000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9065000 0x1000>; + qcom,name = "system-cci"; /* CCI SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x0>; + qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,supports-rpm-hs; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC0 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC0 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [00 03 00 0f]; + qcom,saw2-spm-cmd-pc = [00 60 70 50 01 03 11 3f 3f 3f 3f 50 00 + 60 70 0f]; + }; + + cluster0_spm: qcom,spm@f9012000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9012000 0x1000>, + <0xf900d210 0x8>; + qcom,name = "a53-l2"; /* A53 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c1c>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 38 48 26 6b 18 03 2f 1b 18 7b + 26 6b 40 40 48 38 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 03 2f 1b 18 7b d2 2b e2 3b c0 16 6b 26 6b 48 + 18 00 30 50 08 0f]; + }; + + cluster1_spm: qcom,spm@f9013000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9013000 0x1000>, + <0xf900f210 0x8>; + qcom,name = "a57-l2"; /* A57 L2 SAW */ + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0x3c100c30>; + qcom,saw2-spm-ctl = <0x8>; + qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,vctl-timeout-us = <50>; + qcom,vctl-port = <0x0>; + qcom,phase-port = <0x1>; + qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ + qcom,saw2-pmic-data1 = <0x02030080>; /* VDD_APC1 on */ + qcom,pfm-port = <0x2>; + qcom,saw2-spm-cmd-wfi = [03 2f 1b 0f]; + qcom,saw2-spm-cmd-ret = [18 7b 48 26 6b 18 03 2f 1b 18 7b 26 + 6b 40 40 48 18 0f]; + qcom,saw2-spm-cmd-pc = [08 00 30 50 18 7b 48 26 6b 16 6b c0 e2 + d2 5b 18 b0 01 03 2f 1b 11 b0 3f 3f 3f 3f 18 7b d2 2b + e2 3b c0 16 6b 26 6b 48 18 00 30 50 08 0f]; + }; + + qcom,spm@f9089000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9089000 0x1000>, + <0xf908b060 0x8>; + qcom,name = "cpu0"; + qcom,cpu = <&CPU0>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f9099000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9099000 0x1000>, + <0xf909b060 0x8>; + qcom,name = "cpu1"; + qcom,cpu = <&CPU1>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90a9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90a9000 0x1000>, + <0xf90ab060 0x8>; + qcom,name = "cpu2"; + qcom,cpu = <&CPU2>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90b9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90b9000 0x1000>, + <0xf90bb060 0x8>; + qcom,name = "cpu3"; + qcom,cpu = <&CPU3>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,saw2-spm-cmd-wfi = [03 2f 0b 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b b0 e2 a0 92 1b 50 + 03 2f 0b 50 2b 92 1b e2 1b a0 b0 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90c9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90c9000 0x1000>, + <0xf90cb060 0x8>; + qcom,name = "cpu4"; + qcom,cpu = <&CPU4>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90d9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90d9000 0x1000>, + <0xf90db060 0x8>; + qcom,name = "cpu5"; + qcom,cpu = <&CPU5>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90e9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90e9000 0x1000>, + <0xf90eb060 0x8>; + qcom,name = "cpu6"; + qcom,cpu = <&CPU6>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,spm@f90f9000 { + compatible = "qcom,spm-v2"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf90f9000 0x1000>, + <0xf90fb060 0x8>; + qcom,name = "cpu7"; + qcom,cpu = <&CPU7>; + qcom,saw2-ver-reg = <0xfd0>; + qcom,saw2-cfg = <0x01>; + qcom,saw2-spm-dly = <0X3c100c00>; + qcom,saw2-spm-ctl = <0x8>; + qcom,use-qchannel-for-wfi; + qcom,saw2-spm-cmd-wfi = [03 50 2b 54 0f]; + qcom,saw2-spm-cmd-ret = [50 2b 00 c0 14 3b 1f 1f 1f 1f 1f 50 + 03 2f 0b 50 2b 1f 1f 1f 1f 1f 1f 14 3b 70 70 c0 00 50 + 0f]; + qcom,saw2-spm-cmd-pc = [00 40 30 50 2b c0 14 3b 24 3b 80 e2 + a0 92 1b 50 03 2f 0b 50 2b 92 1b e2 1b a0 80 24 3b 14 + 3b c0 50 00 40 30 0f]; + }; + + qcom,lpm-levels { + compatible = "qcom,lpm-levels"; + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cluster@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "system"; + qcom,spm-device-names = "cci"; + qcom,default-level = <0>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "system-cci-wfi"; + qcom,spm-cci-mode = "wfi"; + qcom,latency-us = <90>; + qcom,ss-power = <307>; + qcom,energy-overhead = <81180>; + qcom,time-overhead = <180>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "system-cci-pc"; + qcom,spm-cci-mode = "pc"; + qcom,latency-us = <11260>; + qcom,ss-power = <89>; + qcom,energy-overhead = <6959381>; + qcom,time-overhead = <5431>; + qcom,min-child-idx = <2>; + qcom,notify-rpm; + }; + + qcom,pm-cluster@0{ + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + label = "a53"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a53-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <159>; + qcom,energy-overhead = <29640>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a53-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <148>; + qcom,energy-overhead = <44460>; + qcom,time-overhead = <180>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a53-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <800>; + qcom,ss-power = <104>; + qcom,energy-overhead = <432250>; + qcom,time-overhead = <1750>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <50>; + qcom,ss-power = <65>; + qcom,energy-overhead = <10650>; + qcom,time-overhead = <100>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <100>; + qcom,ss-power = <51>; + qcom,energy-overhead = <15975>; + qcom,time-overhead = <150>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <400>; + qcom,ss-power = <50>; + qcom,energy-overhead = <74550>; + qcom,time-overhead = <700>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <480>; + qcom,ss-power = <30>; + qcom,energy-overhead = <85200>; + qcom,time-overhead = <800>; + qcom,use-broadcast-timer; + }; + }; + }; + + qcom,pm-cluster@1{ + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + label = "a57"; + qcom,spm-device-names = "l2"; + qcom,default-level=<0>; + qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,pm-cluster-level@0{ + reg = <0>; + label = "a57-l2-wfi"; + qcom,spm-l2-mode = "wfi"; + qcom,latency-us = <80>; + qcom,ss-power = <270>; + qcom,energy-overhead = <72160>; + qcom,time-overhead = <160>; + }; + + qcom,pm-cluster-level@1{ + reg = <1>; + label = "a57-l2-retention"; + qcom,spm-l2-mode = "retention"; + qcom,latency-us = <190>; + qcom,ss-power = <189>; + qcom,energy-overhead = <157850>; + qcom,time-overhead = <350>; + qcom,min-child-idx = <1>; + }; + + qcom,pm-cluster-level@2{ + reg = <2>; + label = "a57-l2-pc"; + qcom,spm-l2-mode = "pc"; + qcom,latency-us = <1260>; + qcom,ss-power = <93>; + qcom,energy-overhead = <1318724>; + qcom,time-overhead = <2924>; + qcom,min-child-idx = <3>; + }; + + qcom,pm-cpu { + #address-cells = <1>; + #size-cells = <0>; + + qcom,pm-cpu-level@0 { + reg = <0>; + qcom,spm-cpu-mode = "wfi"; + qcom,latency-us = <60>; + qcom,ss-power = <117>; + qcom,energy-overhead = <31200>; + qcom,time-overhead = <120>; + }; + + qcom,pm-cpu-level@1 { + reg = <1>; + qcom,spm-cpu-mode = "retention"; + qcom,latency-us = <120>; + qcom,ss-power = <93>; + qcom,energy-overhead = <46800>; + qcom,time-overhead = <180>; + qcom,use-broadcast-timer; + }; + + + qcom,pm-cpu-level@2 { + reg = <2>; + qcom,spm-cpu-mode = "standalone_pc"; + qcom,latency-us = <475>; + qcom,ss-power = <66>; + qcom,energy-overhead = <201500>; + qcom,time-overhead = <775>; + qcom,use-broadcast-timer; + }; + + qcom,pm-cpu-level@3 { + reg = <3>; + qcom,spm-cpu-mode = "pc"; + qcom,latency-us = <636>; + qcom,ss-power = <60>; + qcom,energy-overhead = <248560>; + qcom,time-overhead = <956>; + qcom,use-broadcast-timer; + }; + }; + }; + }; + + }; + + qcom,mpm@fc4281d0 { + compatible = "qcom,mpm-v2"; + reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */ + <0xf900f008 0x4>; /* MSM_APCS_GCC_BASE 4K */ + reg-names = "vmpm", "ipc"; + interrupts = <0 171 1>; + clocks = <&clock_rpm clk_cxo_lpm_clk>; + clock-names = "xo"; + + qcom,ipc-bit-offset = <1>; + + qcom,gic-parent = <&intc>; + qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ + <47 165>, /* usb30_hs_phy_irq */ + <52 212>, /* lfps_rxterm_irq for pwr_event_irq */ + <55 172>, /* usb1_hs_async_wakeup_irq */ + <62 222>, /* ee0_krait_hlos_spmi_periph_irq */ + <0xff 20>, /* arch_timer */ + <0xff 23>, /* ARM64 Single-Bit Error PMU IRQ */ + <0xff 33>, /* APCC_qgicL2PerfMonIrptReq */ + <0xff 34>, /* APCC_qgicL2ErrorIrptReq */ + <0xff 35>, /* WDT_barkInt */ + <0xff 40>, /* qtimer_phy_irq */ + <0xff 48>, /* cpr */ + <0xff 51>, /* cpr */ + <0xff 54>, /* CCI error IRQ */ + <0xff 56>, /* modem_watchdog */ + <0xff 57>, /* mss_to_apps_irq(0) */ + <0xff 58>, /* mss_to_apps_irq(1) */ + <0xff 59>, /* mss_to_apps_irq(2) */ + <0xff 60>, /* mss_to_apps_irq(3) */ + <0xff 61>, /* mss_a2_bam_irq */ + <0xff 70>, /* iommu_pmon_nonsecure_irq */ + <0xff 74>, /* osmmu_CIrpt[1] */ + <0xff 75>, /* osmmu_CIrpt[0] */ + <0xff 77>, /* osmmu_CIrpt[0] */ + <0xff 78>, /* osmmu_CIrpt[0] */ + <0xff 79>, /* osmmu_CIrpt[0] */ + <0xff 94>, /* osmmu_CIrpt[0] */ + <0xff 97>, /* iommu_nonsecure_irq */ + <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 102>, /* osmmu_CIrpt[1] */ + <0xff 105>, /* iommu_pmon_nonsecure_irq */ + <0xff 109>, /* ocmem_dm_nonsec_irq */ + <0xff 126>, /* bam_irq[0] */ + <0xff 155>, /* sdcc_irq[0] */ + <0xff 163>, /* usb30_ee1_irq */ + <0xff 164>, /* sps */ + <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 173>, /* o_wcss_apss_smd_hi */ + <0xff 174>, /* o_wcss_apss_smd_med */ + <0xff 175>, /* o_wcss_apss_smd_low */ + <0xff 176>, /* o_wcss_apss_smsm_irq */ + <0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */ + <0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */ + <0xff 179>, /* o_wcss_apss_asic_intr */ + <0xff 181>, /* wcnss watchdog */ + <0xff 188>, /* lpass_irq_out_apcs(0) */ + <0xff 189>, /* lpass_irq_out_apcs(1) */ + <0xff 190>, /* lpass_irq_out_apcs(2) */ + <0xff 191>, /* lpass_irq_out_apcs(3) */ + <0xff 192>, /* lpass_irq_out_apcs(4) */ + <0xff 193>, /* lpass_irq_out_apcs(5) */ + <0xff 194>, /* lpass_irq_out_apcs(6) */ + <0xff 195>, /* lpass_irq_out_apcs(7) */ + <0xff 196>, /* lpass_irq_out_apcs(8) */ + <0xff 197>, /* lpass_irq_out_apcs(9) */ + <0xff 198>, /* coresight-tmc-etr interrupt */ + <0xff 200>, /* rpm_ipc(4) */ + <0xff 201>, /* rpm_ipc(5) */ + <0xff 202>, /* rpm_ipc(6) */ + <0xff 203>, /* rpm_ipc(7) */ + <0xff 204>, /* rpm_ipc(24) */ + <0xff 205>, /* rpm_ipc(25) */ + <0xff 206>, /* rpm_ipc(26) */ + <0xff 207>, /* rpm_ipc(27) */ + <0xff 211>, /* usb_dwc3_otg */ + <0xff 212>, /* msm_dwc3 */ + <0xff 215>, /* fc388000.qcom,cpu-bwmon */ + <0xff 224>, /* spdm_bw_hyp */ + <0xff 240>, /* summary_irq_kpss */ + <0xff 261>, /* msm_iommu_global_cfg */ + <0xff 263>, /* msm_iommu_global_client */ + <0xff 268>, /* bam_irq[1] */ + <0xff 270>, /* bam_irq[0] */ + <0xff 271>, /* bam_irq[0] */ + <0xff 272>, /* msm_iommu_secure_irq */ + <0xff 273>, /* msm_iommu_nonsecure_irq */ + <0xff 275>, /* int_msi */ + <0xff 283>, /* int_pls_err */ + <0xff 284>, /* int_aer_legacy */ + <0xff 286>, /* int_pls_link_down */ + <0xff 298>, /* msm_iommu_nonsecure_irq */ + <0xff 302>, /* coresight-tmc-etr */ + <0xff 303>, /* int_msi */ + <0xff 310>, /* int_pls_err */ + <0xff 311>, /* int_aer_legacy */ + <0xff 313>, /* int_pls_link_down */ + <0xff 329>, /* sps */ + <0xff 332>, /* sps */ + <0xff 333>, /* ipa */ + <0xff 348>, /* fd878000.qcom,fd */ + <0xff 350>, /* msm_iommu_nonsecure_irq */ + <0xff 360>, /* ARM64 primary DBE IRQ */ + <0xff 361>, /* ARM64 secondary DBE IRQ */ + <0xff 362>, /* ARM64 primary ext IRQ */ + <0xff 363>, /* ARM64 secondary ext IRQ */ + <0xff 364>; /* lmh_interrupt */ + + qcom,gpio-parent = <&msm_gpio>; + qcom,gpio-map = <3 101>, + <4 1 >, + <5 5 >, + <6 9 >, + <7 18>, + <8 22>, + <9 26>, + <10 29>, + <11 34>, + <12 36>, + <13 37>, + <14 41>, + <15 42>, + <16 46>, + <17 50>, + <18 52>, + <19 53>, + <20 54>, + <21 55>, + <22 57>, + <23 40>, + <24 61>, + <25 64>, + <26 65>, + <27 66>, + <28 67>, + <29 72>, + <30 73>, + <31 74>, + <32 75>, + <33 76>, + <34 77>, + <35 82>, + <36 86>, + <37 90>, + <38 95>, + <39 96>, + <40 100>, + <41 71>, + <42 108>, + <43 111>, + <44 115>, + <45 127>; + + }; + + qcom,pm@fe87f664 { + compatible = "qcom,pm"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0xfe87f664 0x40>; + clock-names = "cpu4_clk", "cpu5_clk", "cpu6_clk", + "cpu7_clk", "l2_clk"; + clocks = <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_cci_clk>; + + qcom,tz-flushes-cache; + + qcom,no-pll-switch-for-retention; + + qcom,pm-snoc-client { + compatible = "qcom,pm-snoc-client"; + qcom,msm-bus,name = "ocimem_snoc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,active-only; + qcom,msm-bus,vectors-KBps = + , + ; + }; + + }; + + qcom,cpu-sleep-status@f908b008{ + compatible = "qcom,cpu-sleep-status"; + reg = <0xf908b008 0x100>; + qcom,cpu-alias-addr = <0x10000>; + qcom,sleep-status-mask= <0x80000>; + }; + + qcom,rpm-log@fc000000 { + compatible = "qcom,rpm-log"; + reg = <0xfc000000 0x4000>, + <0xfc190018 0x4>; + qcom,rpm-addr-phys = <0xfc000000>; + qcom,offset-version = <4>; + qcom,offset-page-buffer-addr = <36>; + qcom,offset-log-len = <40>; + qcom,offset-log-len-mask = <44>; + qcom,offset-page-indices = <56>; + }; + + qcom,rpm-stats@fc000000 { + compatible = "qcom,rpm-stats"; + reg = <0xfc000000 0x1000>, + <0xfc190014 0x4>, + <0xfc19001c 0x4>; + reg-names = "phys_addr_base", "offset_addr", "heap_phys_addrbase"; + qcom,sleep-stats-version = <2>; + }; + + qcom,rpm-rbcpr-stats@fc000000 { + compatible = "qcom,rpmrbcpr-stats"; + reg = <0xfc000000 0x1a0000>; + qcom,start-offset = <0x190010>; + }; + + qcom,npa-dump@0xfc190020 { + compatible = "qcom,npa-dump"; + reg = <0xfc190020 0x4>, <0xfc000000 0x1c00>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0-mtp_14049_HW_14.dts b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0-mtp_14049_HW_14.dts new file mode 100755 index 0000000000000..a50c534b3287a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0-mtp_14049_HW_14.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.0.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.0 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <14>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0.dtsi new file mode 100755 index 0000000000000..b824d0c5d195c --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.0.dtsi @@ -0,0 +1,35 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.0"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20000>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030001>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1-mtp_14049_HW_14.dts b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1-mtp_14049_HW_14.dts new file mode 100755 index 0000000000000..3ca7be7bb96b3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1-mtp_14049_HW_14.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8994-v2.1.dtsi" +#include "msm8994-pinctrl.dtsi" +#include "msm8994-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM8994v2.1 MTP"; + compatible = "qcom,msm8994-mtp", "qcom,msm8994", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,product-name = "14049"; + qcom,hw-ver = <14>; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1.dtsi new file mode 100755 index 0000000000000..93bc398c9693f --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.1.dtsi @@ -0,0 +1,54 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Device definitions should be placed inside the msm8994.dtsi + * file. + */ + +#include "msm8994-v2.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994v2.1"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x20001>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; +}; + +/* GPU overrides */ +&msm_gpu { + /* Updated chip ID */ + qcom,chipid = <0x04030002>; + qcom,gpu-pwrlevels { + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <630000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <8>; + }; + }; + qcom,ocmem-bus-client { + qcom,msm-bus,vectors-KBps = + <89 662 0 10080000>, /* gpu= 630 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.dtsi new file mode 100755 index 0000000000000..a55f94a83941e --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994-v2.dtsi @@ -0,0 +1,428 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. However, device definitions should be placed inside the + * msm8994.dtsi file. + */ + +#include "msm8994.dtsi" +#include "msm8994-coresight-v2.dtsi" +#include "msm8994-camera-v2.dtsi" + +&soc { + + arm64-cpu-erp@f9100000 { + compatible = "arm,arm64-cpu-erp"; + reg = <0xf9100000 0x1000>; + reg-names = "cci"; + interrupts = <0 328 0>, + <0 329 0>, + <0 330 0>, + <0 331 0>, + <0 22 0>, + <1 7 0>; + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq", + "cci-irq", + "sbe-irq"; + poll-delay-ms = <5000>; + }; + + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 7 0xff00>; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon2"; + }; + + qcom,lmh { + compatible = "qcom,lmh"; + interrupts = <0 332 4>; + reg = <0xF9117000 0x4>; + qcom,lmh-trim-err-offset = <18>; + }; +}; + +/* Clock driver overrides */ +&clock_gcc { + compatible = "qcom,gcc-8994v2"; +}; + +&clock_mmss { + compatible = "qcom,mmsscc-8994v2"; +}; + +&clock_cpu { + compatible = "qcom,cpu-clock-8994-v2"; + vdd-dig-supply = <&pm8994_s2_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 384000000 3>, + < 460800000 4>, + < 600000000 5>, + < 672000000 6>, + < 768000000 7>, + < 864000000 8>, + < 960000000 9>, + < 1248000000 10>, + < 1344000000 11>, + < 1478400000 12>, + < 1555200000 13>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1728000000 14>, + < 1824000000 16>, + < 1958400000 17>; + qcom,a57-speedbin1-v0 = + < 0 0>, + < 384000000 5>, + < 480000000 5>, + < 633600000 5>, + < 768000000 6>, + < 864000000 7>, + < 960000000 8>, + < 1248000000 9>, + < 1344000000 10>, + < 1440000000 11>, + < 1536000000 12>, + < 1632000000 13>, + < 1766400000 15>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 300000000 4>, + < 384000000 5>, + < 537600000 7>, + < 600000000 9>, + < 729600000 10>, + < 787200000 11>; +}; + +&cci_cache { + freq-tbl-khz = + < 300000 >, + < 384000 >, + < 537600 >, + < 600000 >, + < 729600 >, + < 787200 >; +}; + +&msm_cpufreq { + qcom,cpufreq-table-0 = + < 384000 >, + < 460800 >, + < 600000 >, + < 672000 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1478400 >, + < 1555200 >; + + qcom,cpufreq-table-4 = + < 384000 >, + < 480000 >, + < 633600 >, + < 768000 >, + < 864000 >, + < 960000 >, + < 1248000 >, + < 1344000 >, + < 1440000 >, + < 1536000 >, + < 1632000 >, + < 1728000 >, + < 1824000 >, + < 1958400 >; +}; + +&devfreq_cpufreq { + cpubw-cpufreq { + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5928 >, + < 1248000 7904 >, + < 1344000 9887 >, + < 1478400 11863 >, + < 1555200 11863 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 2288 >, + < 633600 2288 >, + < 768000 3509 >, + < 864000 4066 >, + < 960000 5126 >, + < 1248000 5928 >, + < 1344000 7904 >, + < 1440000 7904 >, + < 1536000 7904 >, + < 1632000 9887 >, + < 1728000 9887 >, + < 1824000 11863 >, + < 1958400 11863 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 384000 1525 >, + < 460800 1525 >, + < 600000 1525 >, + < 672000 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1478400 1525 >, + < 1555200 1525 >; + cpu-to-dev-map-4 = + < 384000 1525 >, + < 480000 1525 >, + < 633600 1525 >, + < 768000 1525 >, + < 864000 1525 >, + < 960000 1525 >, + < 1248000 1525 >, + < 1344000 1525 >, + < 1440000 1525 >, + < 1536000 1525 >, + < 1632000 1525 >, + < 1728000 1525 >, + < 1824000 1525 >, + < 1958400 7904 >; + }; + + cci-cpufreq { + cpu-to-dev-map-0 = + < 384000 300000 >, + < 460800 300000 >, + < 600000 300000 >, + < 672000 384000 >, + < 768000 384000 >, + < 864000 537600 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 787200 >, + < 1478400 787200 >, + < 1555200 787200 >; + cpu-to-dev-map-4 = + < 384000 300000 >, + < 480000 300000 >, + < 633600 384000 >, + < 768000 537600 >, + < 864000 600000 >, + < 960000 600000 >, + < 1248000 729600 >, + < 1344000 729600 >, + < 1440000 729600 >, + < 1536000 787200 >, + < 1632000 787200 >, + < 1728000 787200 >, + < 1824000 787200 >, + < 1958400 787200 >; + }; +}; + +/* GPU VBIF overrides */ +&gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5271 /* 691 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; +}; + +/* GPU overrides */ +&msm_gpu { + qcom,initial-pwrlevel = <5>; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + <26 512 0 1600000>, /* 1 bus=200 */ + <26 512 0 2400000>, /* 2 bus=300 */ + <26 512 0 3680000>, /* 3 bus=460 */ + <26 512 0 4376000>, /* 4 bus=547 */ + <26 512 0 5528000>, /* 5 bus=691 */ + <26 512 0 6216000>, /* 6 bus=777 */ + <26 512 0 8288000>, /* 7 bus=1036 */ + <26 512 0 10368000>, /* 8 bus=1296 */ + <26 512 0 12440000>; /* 9 bus=1555 */ + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <600000000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <510000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <6>; + qcom,bus-max = <8>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <450000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <390000000>; + qcom,bus-freq = <5>; + qcom,bus-min = <4>; + qcom,bus-max = <6>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <305000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <4>; + }; + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <180000000>; + qcom,bus-freq = <2>; + qcom,bus-min = <1>; + qcom,bus-max = <3>; + }; + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <27000000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + + /* + * qcom,ocmem-bus-client defines + * ocmem msm client and its vote data for + * each of available power levels - + * the same levels that grp3d above uses + */ + qcom,ocmem-bus-client { + qcom,msm-bus,name = "gpu-ocmem"; + qcom,msm-bus,num-cases = <7>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <89 662 0 9600000>, /* gpu= 600 */ + <89 662 0 8160000>, /* gpu= 510 */ + <89 662 0 7200000>, /* gpu= 450 */ + <89 662 0 6240000>, /* gpu= 390 */ + <89 662 0 4880000>, /* gpu= 305 */ + <89 662 0 2880000>, /* gpu= 180 */ + <89 662 0 0>; + }; +}; + +&ufs1 { + freq-table-hz = + <100000000 200000000>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>; +}; + +/* MDSS driver overrides */ +&mdss_mdp { + qcom,mdp-settings = <0x0117c 0x0000ffff>, + <0x01184 0xC000ff00>, + <0x011e0 0x000000a4>, + <0x011e4 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xccccc0c0>, + <0x013d0 0x00ccc000>; +}; + +/* Video driver overrides */ +&msm_vidc { + qcom,load-freq-tbl = + <979200 510000000 0x0c000000>, + <979200 510000000 0x01000414>, + <979200 510000000 0x030fcfff>, + <979200 510000000 0x04000000>, + <783360 510000000 0x0c000000>, + <783360 510000000 0x01000414>, + <783360 510000000 0x030fcfff>, + <783360 510000000 0x04000000>, + <489600 320000000 0x0c000000>, + <489600 320000000 0x01000414>, + <489600 320000000 0x030fcfff>, + <489600 320000000 0x04000000>, + <244800 150000000 0x0c000000>, + <244800 150000000 0x01000414>, + <244800 150000000 0x030fcfff>, + <244800 150000000 0x04000000>; +}; + +&cnss { + wlan-bootstrap-gpio = <&msm_gpio 112 0>; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default &cnss_lpass_default>; +}; + +#include "msm8994-v2-pm.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_14/msm8994.dtsi b/arch/arm64/boot/dts/14049_HW_14/msm8994.dtsi new file mode 100755 index 0000000000000..e923d946dfbd3 --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/msm8994.dtsi @@ -0,0 +1,3792 @@ +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/memreserve/ 0x00000000 0x00001000; +/memreserve/ 0xac1c0000 0x00001000; + +#include "skeleton64.dtsi" +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM 8994"; + compatible = "qcom,msm8994"; + qcom,msm-id = <207 0x0>; + qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>; + interrupt-parent = <&intc>; + + chosen { + bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; + }; + + aliases { + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + /*do not enable sdhc2 and sdhc3 + sdhc2 = &sdhc_2; + sdhc3 = &sdhc_3; + */ + i2c6 = &i2c_6; /* I2C6 NFC qup6 device */ + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c5 = &i2c_5; + spi0 = &spi_0; + /*#ifdef VENDOR_EDIT modify for fpc1021 fingerprints*/ + spi12 = &spi_12; + /*#end VENDOR_EDIT*/ + qup2 = &i2c_2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU4>; + }; + core1 { + cpu = <&CPU5>; + }; + core2 { + cpu = <&CPU6>; + }; + core3 { + cpu = <&CPU7>; + }; + }; + }; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc0>; + qcom,ldo = <&ldo0>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + power-domain = <&l2ccc_0>; + qcom,dump-size = <0x0>; /* A53 L2 dump not supported */ + L2_tlb_0: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc1>; + qcom,ldo = <&ldo1>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc2>; + qcom,ldo = <&ldo2>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc3>; + qcom,ldo = <&ldo3>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc4>; + qcom,ldo = <&ldo4>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + qcom,dump-size = <0x280040>; /*A57 Cluster L2 size is 1MB */ + power-domain = <&l2ccc_1>; + L2_tlb_1: l2-tlb { + qcom,dump-size = <0x4000>; + }; + }; + L1_itlb_100: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_100: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc5>; + qcom,ldo = <&ldo5>; + next-level-cache = <&L2_1>; + L1_itlb_101: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_101: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x102>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc6>; + qcom,ldo = <&ldo6>; + next-level-cache = <&L2_1>; + L1_itlb_102: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_102: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + + CPU7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x103>; + enable-method = "qcom,8994-arm-cortex-acc"; + qcom,acc = <&acc7>; + qcom,ldo = <&ldo7>; + next-level-cache = <&L2_1>; + L1_itlb_103: l1-itlb { + qcom,dump-size = <0x400>; + }; + L1_dtlb_103: l1-dtlb { + qcom,dump-size = <0x400>; + }; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0xd840>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + }; + }; + + soc: soc { }; + + memory { + #address-cells = <2>; + #size-cells = <2>; + + secure_mem: secure_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x12c00000>; + label = "secure_mem"; + }; + + adsp_mem: adsp_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x3F00000>; + label = "adsp_mem"; + }; + + qsecom_mem: qsecom_region@0 { + linux,reserve-contiguous-region; + reg = <0 0 0 0x1800000>; + label = "qseecom_mem"; + }; + + audio_mem: audio_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0 0 0x614000>; + label = "audio_mem"; + }; + + removed_regions: removed_regions@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x06300000 0 0xD00000>; + label = "memory_hole"; + }; + /*#ifdef VENDOR_EDIT*/ + /*Add by LiWei. The region is used for nv backup,20150325*/ + nabackup_regions: nvbackup_regions@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for nv backup + //linux,remove-completely;//del by jiachenghui for nv backup + reg = <0 0x06200000 0 0x100000>; + label = "memory_nvbackup"; + }; + /*End by LiWei. The region is used for nv backup, 20150325*/ + /*#endif VENDOR_EDIT*/ + dfps_data_mem: dfps_data_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03400000 0 0x1000>; + label = "dfps_data_mem"; + }; +/*liyunbing@BSP,20150518 revert MIPI_FB_ADDR to default addr, because we located MDSS issue cause by nvbackup*/ + cont_splash_mem: cont_splash_mem@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + reg = <0 0x03401000 0 0x2200000>; + //reg = <0 0x83200000 0 0x2200000>; + label = "cont_splash_mem"; + }; + + peripheral_mem: peripheral_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x0ca00000 0 0x1f00000>; + label = "peripheral_mem"; + }; +/*#ifdef VENDOR_EDIT //changhua.li add for enlarge TZ APP memory to 25M*/ + tzapp_mem: tzapp_region@0 { + + linux,reserve-contiguous-region; + + linux,reserve-region; + + linux,remove-completely; + + reg = <0 0x0E900000 0 0x1900000>; + + label = "tzapp_mem"; + + }; +/*#endif VENDOR_EDIT*/ + + + modem_mem: modem_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0 0x07000000 0 0x5a00000>; + label = "modem_mem"; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops_mem: ramoops_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region;//modify by jiachenghui for ramoops reserve region + //linux,remove-completely;//del by jiachenghui for ramoops reserve region + reg = <0 0xac000000 0 0x00100000>;//modify from 0x05800000 to 0xac000000 by jiachenghui for ramoops reserve region + label = "ramoops_mem"; + }; +/* #endif VENDOR_EDIT */ + + param_mem: param_region@0 { + linux,reserve-contiguous-region; + oem,reserve-region; + //linux,remove-completely; + reg = <0 0xac200000 0 0x00100000>; + label = "param_mem"; + }; + + }; +}; + +#include "msm-gdsc.dtsi" +#include "msm8994-smp2p.dtsi" +#include "msm8994-ipcrouter.dtsi" +#include "msm8994-mdss.dtsi" +#include "msm8994-mdss-pll.dtsi" +#include "msm8994-bus.dtsi" + +&soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + cpuss@fd4a8000 { + compatible = "qcom,cpuss-8994"; + reg = <0xfd4a8000 0x4>; + }; + + acc0:clock-controller@f908b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9070000 0x1000>, + <0xf908b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc1:clock-controller@f909b004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9071000 0x1000>, + <0xf909b000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc2:clock-controller@f90ab004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9072000 0x1000>, + <0xf90ab000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc3:clock-controller@f90bb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9073000 0x1000>, + <0xf90bb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc4:clock-controller@f90cb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9074000 0x1000>, + <0xf90cb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc5:clock-controller@f90db004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9075000 0x1000>, + <0xf90db000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc6:clock-controller@f90eb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9076000 0x1000>, + <0xf90eb000 0x1000>, + <0xf900b000 0x1000>; + }; + + acc7:clock-controller@f90fb004 { + compatible = "qcom,arm-cortex-acc"; + reg = <0xf9077000 0x1000>, + <0xf90fb000 0x1000>, + <0xf900b000 0x1000>; + }; + + ldo0:ldo-vref@f9070000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9070000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo1:ldo-vref@f9071000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9071000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo2:ldo-vref@f9072000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9072000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo3:ldo-vref@f9073000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9073000 0x30>; + qcom,ldo-vref-ret = <0x2a>; + }; + + ldo4:ldo-vref@f9074000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9074000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo5:ldo-vref@f9075000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9075000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo6:ldo-vref@f9076000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9076000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + ldo7:ldo-vref@f9077000 { + compatible = "qcom,8994-cpu-ldo-vref"; + reg = <0xf9077000 0x30>; + qcom,ldo-vref-ret = <0x3e>; + }; + + l2ccc_0: clock-controller@f900d000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900d000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster0_spm>; + }; + + l2ccc_1: clock-controller@f900f000 { + compatible = "qcom,8994-l2ccc"; + reg = <0xf900f000 0x1000>, + <0xf911210c 0x4>; + qcom,vctl-node = <&cluster1_spm>; + qcom,vctl-val = <0xb8>; + }; + + intc: interrupt-controller@f9000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0xf9000000 0x1000>, + <0xf9002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 2 0xff08>, + <1 3 0xff08>, + <1 4 0xff08>, + <1 1 0xff08>; + clock-frequency = <19200000>; + }; + + qcom,mpm2-sleep-counter@fc4a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0xfc4a3000 0x1000>; + clock-frequency = <32768>; + }; + + timer@f9020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xf9020000 0x1000>; + clock-frequency = <19200000>; + + frame@f9021000 { + frame-number = <0>; + interrupts = <0 9 0x4>, + <0 8 0x4>; + reg = <0xf9021000 0x1000>, + <0xf9022000 0x1000>; + }; + + frame@f9023000 { + frame-number = <1>; + interrupts = <0 10 0x4>; + reg = <0xf9023000 0x1000>; + status = "disabled"; + }; + + frame@f9024000 { + frame-number = <2>; + interrupts = <0 11 0x4>; + reg = <0xf9024000 0x1000>; + status = "disabled"; + }; + + frame@f9025000 { + frame-number = <3>; + interrupts = <0 12 0x4>; + reg = <0xf9025000 0x1000>; + status = "disabled"; + }; + + frame@f9026000 { + frame-number = <4>; + interrupts = <0 13 0x4>; + reg = <0xf9026000 0x1000>; + status = "disabled"; + }; + + frame@f9027000 { + frame-number = <5>; + interrupts = <0 14 0x4>; + reg = <0xf9027000 0x1000>; + status = "disabled"; + }; + + frame@f9028000 { + frame-number = <6>; + interrupts = <0 15 0x4>; + reg = <0xf9028000 0x1000>; + status = "disabled"; + }; + }; + + restart@fc4ab000 { + compatible = "qcom,pshold"; + reg = <0xfc4ab000 0x4>; + }; + + blsp1_uart3: serial@f991f000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991f000 0x1000>; + interrupts = <0 109 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart3_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp1_uart2: serial@f991e000 { + compatible = "qcom,msm-lsuart-v14"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0>; + status = "disabled"; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp1_ahb_clk>; + }; + + blsp2_uart2: uart@f995e000 { /* BLSP2 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xf995e000 0x1000>, + <0xf9944000 0x19000>; + status = "disabled"; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 114 0 + 1 &intc 0 239 0 + 2 &msm_gpio 46 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xFD>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>, + <&clock_gcc clk_gcc_blsp2_ahb_clk>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&hsuart_sleep>; + pinctrl-1 = <&hsuart_active>; + + qcom,msm-bus,name = "buart8"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + }; + + qcom,sps@f9984000 { + compatible = "qcom,msm_sps"; + reg-names = "bam_mem", "core_mem"; + reg = <0xf9984000 0x15000>, + <0xf9999000 0xb000>; + interrupts = <0 94 0>; + qcom,pipe-attr-ee; + clocks = <&clock_rpm clk_pnoc_sps_clk>, + <&clock_gcc clk_gcc_bam_dma_ahb_clk>; + clock-names = "dfab_clk", "dma_bam_pclk"; + }; + + pcie0: qcom,pcie@fc520000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0xfc520000 0x2000>, + <0xfc526000 0x1000>, + <0xff000000 0xf1d>, + <0xff000f20 0xa8>, + <0xff100000 0x100000>, + <0xff200000 0x100000>, + <0xff300000 0xd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie0>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 243 0 + 1 &intc 0 244 0 + 2 &intc 0 245 0 + 3 &intc 0 247 0 + 4 &intc 0 248 0 + 5 &intc 0 249 0 + 6 &intc 0 250 0 + 7 &intc 0 251 0 + 8 &intc 0 252 0 + 9 &intc 0 253 0 + 10 &intc 0 254 0 + 11 &intc 0 255 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; + + perst-gpio = <&msm_gpio 53 0>; + wake-gpio = <&msm_gpio 55 0>; + + gdsc-vdd-supply = <&gdsc_pcie_0>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9006040>; + qcom,msi-gicm-base = <0x180>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + qcom,scm-dev-id = <11>; + + clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_0_aux_clk>, + <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, + <&clock_gcc clk_pcie_0_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_0_reset>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", "pcie_0_aux_clk", + "pcie_0_cfg_ahb_clk", "pcie_0_mstr_axi_clk", + "pcie_0_slv_axi_clk", "pcie_0_ldo", "pcie_0_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + pcie1: qcom,pcie@fc528000 { + compatible = "qcom,pci-msm"; + cell-index = <1>; + + reg = <0xfc528000 0x2000>, + <0xfc52e000 0x1000>, + <0xf8800000 0xf1d>, + <0xf8800F20 0xa8>, + <0xf8801000 0x7f000>, + <0xf8880000 0x80000>, + <0xf8900000 0x700000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <0>; + interrupt-parent = <&pcie1>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 271 0 + 1 &intc 0 272 0 + 2 &intc 0 273 0 + 3 &intc 0 274 0 + 4 &intc 0 275 0 + 5 &intc 0 276 0 + 6 &intc 0 277 0 + 7 &intc 0 278 0 + 8 &intc 0 279 0 + 9 &intc 0 280 0 + 10 &intc 0 281 0 + 11 &intc 0 282 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", + "int_pls_pme", "int_pme_legacy", "int_pls_err", + "int_aer_legacy", "int_pls_link_up", + "int_pls_link_down", "int_bridge_flush_n"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>; + pinctrl-1 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_sleep>; + + perst-gpio = <&msm_gpio 35 0>; + wake-gpio = <&msm_gpio 37 0>; + + gdsc-vdd-supply = <&gdsc_pcie_1>; + vreg-1.8-supply = <&pm8994_l12>; + vreg-0.9-supply = <&pm8994_l28>; + + qcom,l1-supported; + qcom,l1ss-supported; + qcom,aux-clk-sync; + + qcom,ep-latency = <10>; + + qcom,msi-gicm-addr = <0xf9007040>; + qcom,msi-gicm-base = <0x1a0>; + + qcom,ep-wakeirq; + + qcom,msm-bus,name = "pcie1"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, + <100 512 500 800>; + + qcom,scm-dev-id = <12>; + + clocks = <&clock_gcc clk_gcc_pcie_1_pipe_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_pcie_1_aux_clk>, + <&clock_gcc clk_gcc_pcie_1_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_1_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_1_slv_axi_clk>, + <&clock_gcc clk_pcie_1_phy_ldo>, + <&clock_gcc clk_gcc_pcie_phy_1_reset>; + + clock-names = "pcie_1_pipe_clk", "pcie_1_ref_clk_src", "pcie_1_aux_clk", + "pcie_1_cfg_ahb_clk", "pcie_1_mstr_axi_clk", + "pcie_1_slv_axi_clk", "pcie_1_ldo", "pcie_1_phy_reset"; + + max-clock-frequency-hz = <125000000>, <0>, <1011000>, <0>, <0>, <0>, <0>, <0>; + }; + + ipa_hw: qcom,ipa@fd4c0000 { + compatible = "qcom,ipa"; + reg = <0xfd4c0000 0x29000>, + <0xfd4c4000 0x15820>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 301 0>, + <0 300 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <3>; /* IPA core version = IPAv2.0 */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; + qcom,ee = <2>; + clock-names = "core_clk"; + clocks = <&clock_rpm clk_ipa_clk>; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <90 512 0 0>, <90 585 0 0>, /* No vote */ + <90 512 100000 800000>, <90 585 100000 800000>, /* SVS */ + <90 512 100000 1200000>, <90 585 100000 1200000>; /* PERF */ + qcom,bus-vector-names = "MIN", "SVS", "PERF"; + + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + }; + + qcom,ipc-spinlock@fd484000 { + compatible = "qcom,ipc-spinlock-sfpb"; + reg = <0xfd484000 0x400>; + qcom,num-locks = <8>; + }; + + qcom,smem@6a00000 { + compatible = "qcom,smem"; + reg = <0x6a00000 0x200000>, + <0xf900d008 0x4>, + <0xfc428000 0x4000>; + reg-names = "smem", "irq-reg-base", "aux-mem1"; + qcom,mpu-enabled; + + qcom,smd-modem { + compatible = "qcom,smd"; + qcom,smd-edge = <0>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1000>; + interrupts = <0 25 1>; + label = "modem"; + qcom,not-loadable; + }; + + qcom,smsm-modem { + compatible = "qcom,smsm"; + qcom,smsm-edge = <0>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x2000>; + interrupts = <0 26 1>; + }; + + qcom,smd-adsp { + compatible = "qcom,smd"; + qcom,smd-edge = <1>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x100>; + interrupts = <0 156 1>; + label = "adsp"; + }; + + qcom,smsm-adsp { + compatible = "qcom,smsm"; + qcom,smsm-edge = <1>; + qcom,smsm-irq-offset = <0x0>; + qcom,smsm-irq-bitmask = <0x200>; + interrupts = <0 157 1>; + }; + + qcom,smd-rpm { + compatible = "qcom,smd"; + qcom,smd-edge = <15>; + qcom,smd-irq-offset = <0x0>; + qcom,smd-irq-bitmask = <0x1>; + interrupts = <0 168 1>; + label = "rpm"; + qcom,irq-no-suspend; + qcom,not-loadable; + }; + }; + + qcom,msm-imem@fe87f000 { + compatible = "qcom,msm-imem"; + reg = <0xfe87f000 0x1000>; /* Address and size of IMEM */ + ranges = <0x0 0xfe87f000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + download_mode@0 { + compatible = "qcom,msm-imem-download_mode"; + reg = <0x0 8>; + }; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + + pil@94c { + compatible = "qcom,msm-imem-pil"; + reg = <0x94c 200>; + }; + + emergency_download_mode@fe0 { + compatible = "qcom,msm-imem-emergency_download_mode"; + reg = <0xfe0 12>; + }; + }; + + qcom,wdt@f9017000 { + compatible = "qcom,msm-watchdog"; + reg = <0xf9017000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 3 0>, <0 4 0>; +//liyunbing@BSP, 2015/05/21, WDT bark-time too short cause some task timeout + #qcom,bark-time = <11000>; + qcom,bark-time = <15000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + }; + + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + jtag_fuse: jtagfuse@fc4be024 { + compatible = "qcom,jtag-fuse"; + reg = <0xfc4be024 0x8>; + reg-names = "fuse-base"; + }; + + jtag_mm0: jtagmm@fb840000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb840000 0x1000>, + <0xfb810000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU0>; + }; + + jtag_mm1: jtagmm@fb940000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfb940000 0x1000>, + <0xfb910000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU1>; + }; + + jtag_mm2: jtagmm@fba40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfba40000 0x1000>, + <0xfba10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU2>; + }; + + jtag_mm3: jtagmm@fbb40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbb40000 0x1000>, + <0xfbb10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU3>; + }; + + jtag_mm4: jtagmm@fbc40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbc40000 0x1000>, + <0xfbc10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU4>; + }; + + jtag_mm5: jtagmm@fbd40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbd40000 0x1000>, + <0xfbd10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU5>; + }; + + jtag_mm6: jtagmm@fbe40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbe40000 0x1000>, + <0xfbe10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU6>; + }; + + jtag_mm7: jtagmm@fbf40000 { + compatible = "qcom,jtagv8-mm"; + reg = <0xfbf40000 0x1000>, + <0xfbf10000 0x1000>; + reg-names = "etm-base","debug-base"; + + clocks = <&clock_rpm clk_qdss_clk>, + <&clock_rpm clk_qdss_a_clk>; + clock-names = "core_clk", "core_a_clk"; + + qcom,coresight-jtagmm-cpu = <&CPU7>; + }; + + rpm_bus: qcom,rpm-smd { + compatible = "qcom,rpm-smd"; + rpm-channel-name = "rpm_requests"; + rpm-channel-type = <15>; /* SMD_APPS_RPM */ + }; + + qcom,msm-rng@f9bff000 { + compatible = "qcom,msm-rng"; + reg = <0xf9bff000 0x200>; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <88 618 0 0>, + <88 618 0 800>; + qcom,msm-rng-iface-clk; + clocks = <&clock_gcc clk_gcc_prng_ahb_clk>; + clock-names = "iface_clk"; + }; + + qcom,rmtfs_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00180000>; + reg-names = "rmtfs"; + qcom,client-id = <0x00000001>; + }; + + qcom,dsp_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_dsp"; + qcom,client-id = <0x011013ec>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,mdm_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_mdm"; + qcom,client-id = <0x011013ed>; + }; + + qcom,sensors_sharedmem@00000000 { + compatible = "qcom,sharedmem-uio"; + reg = <0x00000000 0x00010000>; + reg-names = "rfsa_sensor"; + qcom,client-id = <0x011013ee>; + linux,contiguous-region = <&adsp_mem>; + }; + + sdhc_1: sdhci@f9824900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 123 0>, <0 138 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + qcom,bus-width = <8>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc1"; + qcom,msm-bus,num-cases = <9>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <78 512 0 0>, /* No vote */ + <78 512 1600 3200>, /* 400 KB/s*/ + <78 512 80000 160000>, /* 20 MB/s */ + <78 512 100000 200000>, /* 25 MB/s */ + <78 512 200000 400000>, /* 50 MB/s */ + <78 512 400000 800000>, /* 100 MB/s */ + <78 512 400000 800000>, /* 200 MB/s */ + <78 512 400000 800000>, /* 400 MB/s */ + <78 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 400000000 4294967295>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc1_ahb_clk>, + <&clock_gcc clk_gcc_sdcc1_apps_clk>; + + status = "disabled"; + }; + + sdhc_2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 125 0>, <0 221 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc2_ahb_clk>, + <&clock_gcc clk_gcc_sdcc2_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc2"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <81 512 0 0>, /* No vote */ + <81 512 1600 3200>, /* 400 KB/s*/ + <81 512 80000 160000>, /* 20 MB/s */ + <81 512 100000 200000>, /* 25 MB/s */ + <81 512 200000 400000>, /* 50 MB/s */ + <81 512 400000 800000>, /* 100 MB/s */ + <81 512 800000 800000>, /* 200 MB/s */ + <81 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + + status = "disabled"; + }; + + sdhc_3: sdhci@f9864900 { + compatible = "qcom,sdhci-msm"; + reg = <0xf9864900 0x11c>, <0xf9864000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <0 127 0>, <0 224 0>; + interrupt-names = "hc_irq", "pwr_irq"; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_sdcc3_ahb_clk>, + <&clock_gcc clk_gcc_sdcc3_apps_clk>; + + qcom,bus-width = <4>; + qcom,cpu-dma-latency-us = <301 70>; + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0x0f 0xf0>; + qcom,wakeup-on-idle; + + qcom,msm-bus,name = "sdhc3"; + qcom,msm-bus,num-cases = <8>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <79 512 0 0>, /* No vote */ + <79 512 1600 3200>, /* 400 KB/s*/ + <79 512 80000 160000>, /* 20 MB/s */ + <79 512 100000 200000>, /* 25 MB/s */ + <79 512 200000 400000>, /* 50 MB/s */ + <79 512 400000 800000>, /* 100 MB/s */ + <79 512 800000 800000>, /* 200 MB/s */ + <79 512 2048000 4096000>; /* Max. bandwidth */ + qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000 + 100000000 200000000 4294967295>; + qcom,dat1-mpm-int = <47>; + status = "disabled"; + }; + + ufs_ice: ufsice@fc5a0000 { + compatible = "qcom,ice"; + reg = <0xfc5a0000 0x8000>; + interrupt-names = "ufs_ice_nonsec_level_irq", "ufs_ice_sec_level_irq"; + interrupts = <0 258 0>, <0 257 0>; + status = "disabled"; + }; + + ufsphy1: ufsphy@fc597000 { + compatible = "qcom,ufs-phy-qmp-20nm"; + reg = <0xfc597000 0xda8>; + reg-names = "phy_mem"; + #phy-cells = <0>; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-max-microamp = <45000>; + vdda-pll-max-microamp = <100>; + vddp-ref-clk-supply = <&pm8994_l31>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + clock-names = "ref_clk_src", + "ref_clk", + "tx_iface_clk", + "rx_iface_clk"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_ufs_phy_ldo>, + <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, + <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; + status = "disabled"; + }; + + ufs1: ufshc@fc594000 { + compatible = "qcom,ufshc"; + reg = <0xfc594000 0x2500>, <0xfd512074 0x4>; + interrupts = <0 265 0>; + phys = <&ufsphy1>; + phy-names = "ufsphy"; + ufs-qcom-crypto = <&ufs_ice>; + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8994_l20>; + vccq-supply = <&pm8994_l31>; + vccq2-supply = <&pm8994_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <50000>; + vccq2-max-microamp = <750000>; + + clock-names = "core_clk_src", "core_clk", "bus_clk", "iface_clk", + "ref_clk", "rx_lane0_sync_clk", "tx_lane0_sync_clk", + "rx_lane1_sync_clk", "tx_lane1_sync_clk"; + clocks = + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>, + <&clock_rpm clk_bb_clk1>, + <&clock_gcc clk_gcc_ufs_rx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_0_clk>, + <&clock_gcc clk_gcc_ufs_rx_symbol_1_clk>, + <&clock_gcc clk_gcc_ufs_tx_symbol_1_clk>; + qcom,msm-bus,name = "ufs1"; + qcom,msm-bus,num-cases = <22>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <95 512 0 0>, <1 650 0 0>, /* No vote */ + <95 512 922 0>, <1 650 1000 0>, /* PWM G1 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G3 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G4 */ + <95 512 1844 0>, <1 650 1000 0>, /* PWM G1 L2 */ + <95 512 3688 0>, <1 650 1000 0>, /* PWM G2 L2 */ + <95 512 7376 0>, <1 650 1000 0>, /* PWM G3 L2 */ + <95 512 14752 0>, <1 650 1000 0>, /* PWM G4 L2 */ + <95 512 127796 0>, <1 650 1000 0>, /* HS G1 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G2 RA */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G3 RA */ + <95 512 255591 0>, <1 650 1000 0>, /* HS G1 RA L2 */ + <95 512 511181 0>, <1 650 1000 0>, /* HS G2 RA L2 */ + <95 512 1022362 0>, <1 650 1000 0>, /* HS G3 RA L2 */ + <95 512 149422 0>, <1 650 1000 0>, /* HS G1 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G2 RB */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G3 RB */ + <95 512 298189 0>, <1 650 1000 0>, /* HS G1 RB L2 */ + <95 512 596378 0>, <1 650 1000 0>, /* HS G2 RB L2 */ + <95 512 1192756 0>, <1 650 1000 0>, /* HS G3 RB L2 */ + <95 512 4096000 0>, <1 650 1000 0>; /* Max. bandwidth */ + qcom,bus-vector-names = "MIN", + "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1", + "PWM_G1_L2", "PWM_G2_L2", "PWM_G3_L2", "PWM_G4_L2", + "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1", + "HS_RA_G1_L2", "HS_RA_G2_L2", "HS_RA_G3_L2", + "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1", + "HS_RB_G1_L2", "HS_RB_G2_L2", "HS_RB_G3_L2", + "MAX"; + + qcom,cpu-affinity = "affine_cores"; + qcom,cpu-affinity-mask = <0xf>; /* little cluster */ + qcom,cpu-dma-latency-us = <301>; + + spm-level = <5>; + status = "disabled"; + }; + + spi_0: spi_epm: spi@f9923000 { /* BLSP1 QUP1 */ + compatible = "qcom,spi-qup-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical", "spi_bam_physical"; + reg = <0xf9923000 0x1000>, + <0xf9904000 0x19000>; + interrupt-names = "spi_irq", "spi_bam_irq"; + interrupts = <0 95 0>, <0 238 0>; + spi-max-frequency = <19200000>; + + qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <12>; + qcom,bam-producer-pipe-index = <13>; + qcom,master-id = <86>; + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_0_active &spi_0_cs1_active>; + pinctrl-1 = <&spi_0_sleep &spi_0_cs1_sleep>; + + clock-names = "iface_clk", "core_clk"; + + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + }; +//#ifdef VENDOR_EDIT +/* add for fpc1021 fingerprints */ + spi_12: spi@f9968000 { + compatible = "qcom,spi-qup-v2"; + //cell-index = <12>; //changhua + #address-cells = <1>; + #size-cells = <0>; + reg-names = "spi_physical"/*, "spi_bam_physical"*/; + + /*Add BAM physical address + BLSP1: 0xf9904000 + BLSP2: 0xf9944000 + */ + + reg = <0xf9968000 0x1000>/*, + <0xf9944000 0x19000>*/; + + interrupt-names = "spi12_irq"/*, "spi_bam_irq"*/; + + /* Add BAM IRQ + BLSP1: 238 + BLSP2: 239 ??271??? 239 is offset + */ + interrupts = <0 106 0>/*, <0 239 0>*/; + + spi-max-frequency = <9600000>; + + /* //changhua + qcom,gpio-mosi = <&msm_gpio 85 0>; + qcom,gpio-miso = <&msm_gpio 86 0>; + qcom,gpio-clk = <&msm_gpio 88 0>; + qcom,gpio-cs0 = <&msm_gpio 87 0>; + */ + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup6_spi_apps_clk>; + + qcom,master-id = <86>; + /*qcom,infinite-mode = <0>; + qcom,use-bam; + qcom,ver-reg-exists; + qcom,bam-consumer-pipe-index = <22>; + qcom,bam-producer-pipe-index = <23>; + */ + /*lichanghua add for use pinctrl*/ + /* Assign runtime functions to pins */ + + qcom,use-pinctrl; + pinctrl-names = "spi_default", "spi_sleep"; + pinctrl-0 = <&spi_12_active &spi_12_cs0_active>; + pinctrl-1 = <&spi_12_sleep &spi_12_cs0_sleep>; + + qcom,shared; + + /*lichanghua add for use pinctrl end*/ + }; +//#endif/*VENDOR_EDIT*/ + + qcom,msm-ssc-sensors { + compatible = "qcom,msm-ssc-sensors"; + }; + + qcom,msm-pacman { + compatible = "qcom,msm-pacman"; + }; + + wcd9xxx_intc: wcd9xxx-irq { + compatible = "qcom,wcd9xxx-irq"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&msm_gpio>; + interrupts = <72 0>; + interrupt-names = "cdc-int"; + }; + + tspp: msm_tspp@f99d8000 { + compatible = "qcom,msm_tspp"; + reg = <0xf99d8000 0x1000>, /* MSM_TSIF0_PHYS */ + <0xf99d9000 0x1000>, /* MSM_TSIF1_PHYS */ + <0xf99da000 0x1000>, /* MSM_TSPP_PHYS */ + <0xf99c4000 0x11000>; /* MSM_TSPP_BAM_PHYS */ + reg-names = "MSM_TSIF0_PHYS", + "MSM_TSIF1_PHYS", + "MSM_TSPP_PHYS", + "MSM_TSPP_BAM_PHYS"; + interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */ + <0 119 0>, /* TSIF0_IRQ */ + <0 120 0>, /* TSIF1_IRQ */ + <0 122 0>; /* TSIF_BAM_IRQ */ + interrupt-names = "TSIF_TSPP_IRQ", + "TSIF0_IRQ", + "TSIF1_IRQ", + "TSIF_BAM_IRQ"; + + clock-names = "iface_clk", "ref_clk"; + clocks = <&clock_gcc clk_gcc_tsif_ahb_clk>, + <&clock_gcc clk_gcc_tsif_ref_clk>; + + qcom,msm-bus,name = "tsif"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <82 512 0 0>, /* No vote */ + <82 512 12288 24576>; /* Max. bandwidth, 2xTSIF, each max of 96Mbps */ + + pinctrl-names = "disabled", + "tsif0-mode1", "tsif0-mode2", + "tsif1-mode1", "tsif1-mode2", + "dual-tsif-mode1", "dual-tsif-mode2"; + + pinctrl-0 = <>; /* disabled */ + pinctrl-1 = <&tsif0_signals_active>; /* tsif0-mode1 */ + pinctrl-2 = <&tsif0_signals_active + &tsif0_sync_active>; /* tsif0-mode2 */ + pinctrl-3 = <&tsif1_signals_active>; /* tsif1-mode1 */ + pinctrl-4 = <&tsif1_signals_active + &tsif1_sync_active>; /* tsif1-mode2 */ + pinctrl-5 = <&tsif0_signals_active + &tsif1_signals_active>; /* dual-tsif-mode1 */ + pinctrl-6 = <&tsif0_signals_active + &tsif0_sync_active + &tsif1_signals_active + &tsif1_sync_active>; /* dual-tsif-mode2 */ + }; + + slim_msm: slim@fe12f000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0xfe12f000 0x2C000>, + <0xfe104000 0x20000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 163 0>, <0 164 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x60000000>; + qcom,ea-pc = <0x110>; + + tomtom_codec { + compatible = "qcom,tomtom-slim-pgd"; + elemental-addr = [00 01 30 01 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30 31>; + + qcom,cdc-reset-gpio = <&msm_gpio 68 0>; + + cdc-vdd-buck-supply = <&pm8994_s5>; + qcom,cdc-vdd-buck-voltage = <2150000 2150000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-vdd-tx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pm8994_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pm8994_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + cdc-vdd-a-1p2v-supply = <&pm8994_l11>; + qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>; + qcom,cdc-vdd-a-1p2v-current = <2000>; + + cdc-vddcx-1-supply = <&pm8994_l11>; + qcom,cdc-vddcx-1-voltage = <1200000 1200000>; + qcom,cdc-vddcx-1-current = <33000>; + + cdc-vddcx-2-supply = <&pm8994_l11>; + qcom,cdc-vddcx-2-voltage = <1200000 1200000>; + qcom,cdc-vddcx-2-current = <33000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1", + "cdc-vdd-a-1p2v", + "cdc-vddcx-1", + "cdc-vddcx-2"; + + qcom,cdc-micbias-ldoh-v = <0x3>; + qcom,cdc-micbias-cfilt1-mv = <1800>; + //#ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv , 2015/3/24, modify micbias voltage*/ + /*kangjirui@MultiMedia.AudioDrv , 2015/4/18, modify micbias voltage for headset button error*/ + qcom,cdc-micbias-cfilt2-mv = <2700>; + //#endif /* VENDOR_EDIT */ + qcom,cdc-micbias-cfilt3-mv = <1800>; + qcom,cdc-micbias1-cfilt-sel = <0x0>; + qcom,cdc-micbias2-cfilt-sel = <0x1>; + qcom,cdc-micbias3-cfilt-sel = <0x2>; + qcom,cdc-micbias4-cfilt-sel = <0x2>; + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tomtom-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 30 01 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + qcom,cdc-variant = "WCD9330"; + }; + }; + + spmi_bus: qcom,spmi@fc4c0000 { + compatible = "qcom,spmi-pmic-arb"; + reg-names = "core", "intr", "cnfg"; + reg = <0xfc4cf000 0x1000>, + <0xfc4cb000 0x1000>, + <0xfc4ca000 0x1000>; + /* 190,ee0_krait_hlos_spmi_periph_irq */ + /* 187,channel_0_krait_hlos_trans_done_irq */ + interrupts = <0 190 0>, <0 187 0>; + qcom,pmic-arb-channel = <0>; + qcom,pmic-arb-ee = <0>; + #interrupt-cells = <3>; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + }; + + usb3: ssusb@f9200000 { + compatible = "qcom,dwc-usb3-msm"; + status = "disabled"; + reg = <0xf9200000 0xfc000>, + <0xfd4ab000 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupt-parent = <&usb3>; + interrupts = <0 1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x0 0xffffffff>; + interrupt-map = <0x0 0 &intc 0 133 0 + 0x0 1 &intc 0 180 0 + 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>; + interrupt-names = "hs_phy_irq", "pwr_event_irq", "pmic_id_irq"; + + USB3_GDSC-supply = <&gdsc_usb30>; + vdda33-supply = <&pm8994_l24>; + vbus_dwc3-supply = <&smbcharger_charger_otg>; + qcom,dwc-usb3-msm-tx-fifo-size = <29696>; + qcom,dwc-usb3-msm-qdss-tx-fifo-size = <8192>; + qcom,usb-dbm = <&dbm_1p5>; + + qcom,msm-bus,name = "usb3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <61 512 0 0>, + <61 512 240000 960000>; + + qcom,power-collapse-on-cable-disconnect; + qcom,por-after-power-collapse; + + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>, + <&clock_gcc clk_gcc_usb30_mock_utmi_clk>, + <&clock_gcc clk_gcc_usb30_sleep_clk>, + <&clock_rpm clk_ln_bb_clk>, + <&clock_rpm clk_cxo_dwc3_clk>; + clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk", + "ref_clk", "xo"; + + dwc3@f9200000 { + compatible = "synopsys,dwc3"; + reg = <0xf9200000 0xfc000>; + interrupt-parent = <&intc>; + interrupts = <0 131 0>; + tx-fifo-resize; + snps,usb3-u1u2-disable; + usb-phy = <&hsphy0>, <&ssphy0>; + }; + }; + + hsphy0: hsphy@f92f8800 { + compatible = "qcom,usb-hsphy"; + status = "disabled"; + reg = <0xf92f8800 0x3ff>, + <0xf9b3a000 0x110>; + reg-names = "core", "phy_csr"; + // #ifdef VENDOR_EDIT + /*modify by jiachenghui from 0x00D191A4 to 0x00D191A7 for OTG 2015-04-22*/ + /*change HS DC voltage-level to 0x0011 by jiachenghui for OTG detect issue 2015-05-23*/ + qcom,hsphy-init = <0x00D187A7>; + //#endif /*VENDOR_EDIT*/ + vdd-supply = <&pm8994_s2_corner>; + vddcx-supply = <&pm8994_s1_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,ext-vbus-id; + qcom,vbus-valid-override; + qcom,set-pllbtune; + qcom,sleep-clk-reset; + qcom,vdda-force-on; + clocks = <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>; + clock-names = "phy_sleep_clk"; + }; + + ssphy0: ssphy@f9b38000 { + compatible = "qcom,usb-ssphy-qmp"; + status = "disabled"; + reg = <0xf9b38000 0x800>, + <0xf9b3e000 0x3ff>; + reg-names = "qmp_phy_base", + "qmp_ahb2phy_base"; + vdd-supply = <&pm8994_l28>; + vdda18-supply = <&pm8994_l6>; + qcom,vdd-voltage-level = <0 1000000 1000000>; + qcom,vbus-valid-override; + qcom,no-pipe-clk-switch; + + clocks = <&clock_gcc clk_gcc_usb3_phy_aux_clk>, + <&clock_gcc clk_gcc_usb3_phy_pipe_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_usb3_phy_reset>, + <&clock_gcc clk_gcc_usb3phy_phy_reset>, + <&clock_gcc clk_usb_ss_phy_ldo>; + clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", "phy_reset", + "phy_phy_reset", "ldo_clk"; + }; + + dbm_1p5: dbm@f92f8000 { + compatible = "qcom,usb-dbm-1p5"; + reg = <0xf92f8000 0x1000>; + qcom,reset-ep-after-lpm-resume; + }; + + qcom,usbbam@f9304000 { + compatible = "qcom,usb-bam-msm"; + reg = <0xf9304000 0x9000>, + <0xf92f880c 0x4>; + reg-names = "ssusb", "qscratch_ram1_reg"; + interrupts = <0 132 0>; + interrupt-names = "ssusb"; + clocks = <&clock_gcc clk_gcc_usb30_master_clk>, + <&clock_gcc clk_gcc_sys_noc_usb3_axi_clk>; + clock-names = "mem_clk", "mem_iface_clk"; + + qcom,usb-bam-fifo-baseaddr = <0xf9200000>; + qcom,usb-bam-num-pipes = <16>; + qcom,ignore-core-reset-ack; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + + qcom,pipe0 { + label = "ssusb-ipa-out-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <0>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,src-bam-physical-address = <0xf9304000>; + qcom,src-bam-pipe-index = <1>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe1 { + label = "ssusb-ipa-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + qcom,pipe2 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <1>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,src-bam-physical-address = <0xfc37C000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-offset = <0xf0000>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0xf4000>; + qcom,descriptor-fifo-size = <0x1400>; + qcom,reset-bam-on-connect; + }; + + /* USB BAM pipe (consumer) configuration for accelerated DPL */ + qcom,pipe3 { + label = "ssusb-dpl-ipa-in-1"; + qcom,usb-bam-mem-type = <2>; + qcom,bam-type = <0>; + qcom,dir = <1>; + qcom,pipe-num = <1>; + qcom,peer-bam = <2>; + qcom,dst-bam-physical-address = <0xf9304000>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + qcom,reset-bam-on-connect; + }; + }; + + usb_otg: usb@f9a55000 { + compatible = "qcom,hsusb-otg"; + status = "disabled"; + + reg = <0xf9a55000 0x400>; + reg-names = "core"; + interrupts = <0 134 0 0 140 0>; + interrupt-names = "core_irq", "async_irq"; + + HSUSB_VDDCX-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_gcc clk_gcc_usb2_hs_phy_sleep_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "sleep_clk", "xo"; + + qcom,hsusb-otg-phy-type = <2>; + qcom,hsusb-otg-phy-init-seq = <0x63 0x81 0xffffffff>; + qcom,hsusb-otg-mode = <1>; + qcom,hsusb-otg-otg-control = <1>; + }; + + usb_ehci: ehci@f9a55000 { + compatible = "qcom,ehci-host"; + status = "disabled"; + reg = <0xf9a55000 0x400>; + interrupts = <0 134 0>, <0 140 0>; + interrupt-names = "core_irq", "async_irq"; + hsusb_vdd_dig-supply = <&pm8994_s2_corner>; + HSUSB_1p8-supply = <&pm8994_l6>; + HSUSB_3p3-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 2 3 5 7>; + qcom,usb2-power-budget = <500>; + usb-phy = <&qusb_phy>; + qcom,pm-qos-latency = <30001>; + + qcom,msm-bus,name = "usb-hs"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <87 512 0 0>, + <87 512 40000 60000>; + + clocks = <&clock_gcc clk_gcc_usb_hs_system_clk>, + <&clock_gcc clk_gcc_usb_hs_ahb_clk>, + <&clock_rpm clk_cxo_otg_clk>; + clock-names = "core_clk", "iface_clk", "xo"; + }; + + qusb_phy: qusb@f9b39000 { + compatible = "qcom,qusb2phy"; + status = "disabled"; + reg = <0xf9b39000 0x17f>; + reg-names = "qusb_phy_base"; + vdd-supply = <&pm8994_s2_corner>; + vdda18-supply = <&pm8994_l6>; + vdda33-supply = <&pm8994_l24>; + qcom,vdd-voltage-level = <1 5 7>; + qcom,qusb-tune = <0xa08391d5>; + phy_type = "ulpi"; + clocks = <&clock_rpm clk_ln_bb_clk>, + <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, + <&clock_gcc clk_gcc_qusb2_phy_reset>; + clock-names = "ref_clk", "cfg_ahb_clk", "phy_reset"; + }; + + android_usb@fe87f0c8 { + compatible = "qcom,android-usb"; + reg = <0xfe87f0c8 0xc8>; + qcom,pm-qos-latency = <61 637 1261>; + /*add by jiachenghui for cdrom,20150528*/ + /*#ifdef VENDOR_EDIT*/ + qcom,android-usb-cdrom; + /*#ifdef VENDOR_EDIT*/ + /*end add by jiachenghui for cdrom,20150528*/ + }; + + qcom,venus@fdce0000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfdce0000 0x4000>; + + vdd-supply = <&gdsc_venus>; + qcom,proxy-reg-names = "vdd"; + clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,proxy-clock-names = "core_clk", "iface_clk", + "bus_clk", "mem_clk", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_rpm clk_scm_ce1_clk>; + + qcom,msm-bus,name = "pil-venus"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 0 304000>; + qcom,pas-id = <9>; + qcom,proxy-timeout-ms = <100>; + qcom,firmware-name = "venus"; + linux,contiguous-region = <&peripheral_mem>; + }; + + qcom,mss@fc880000 { + compatible = "qcom,pil-q6v55-mss"; + reg = <0xfc880000 0x100>, + <0xfd485000 0x400>, + <0xfc820000 0x020>, + <0xfc401680 0x004>; + reg-names = "qdsp6_base", "halt_base", "rmb_base", + "restart_reg"; + + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_mss_cfg_ahb_clk>, + <&clock_rpm clk_pnoc_modem_clk>, + <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>, + <&clock_gcc clk_gcc_boot_rom_ahb_clk>, + <&clock_gcc clk_gpll0_out_msscc>; + clock-names = "xo", "iface_clk", "pnoc_clk", "bus_clk", + "mem_clk", "gpll0_mss_clk"; + qcom,proxy-clock-names = "xo", "pnoc_clk"; + qcom,active-clock-names = "iface_clk", "bus_clk", "mem_clk", + "gpll0_mss_clk"; + + interrupts = <0 24 1>; + vdd_mss-supply = <&pm8994_s7>; + vdd_cx-supply = <&pm8994_s1_corner>; + vdd_mx-supply = <&pm8994_s2_corner>; + vdd_mx-uV = <7>; + vdd_pll-supply = <&pm8994_l12>; + qcom,vdd_pll = <1800000>; + qcom,firmware-name = "modem"; + qcom,pil-self-auth; + qcom,mba-image-is-not-elf; + qcom,sysmon-id = <0>; + qcom,ssctl-instance-id = <0x12>; + qcom,override-acc; + qcom,ahb-clk-vote; + qcom,pnoc-clk-vote; + + /* GPIO inputs from mss */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>; + + /* GPIO output to mss */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>; + + linux,contiguous-region = <&modem_mem>; + }; + + qcom,lpass@fe200000 { + compatible = "qcom,pil-tz-generic"; + reg = <0xfe200000 0x00100>; + interrupts = <0 162 1>; + + vdd_cx-supply = <&pm8994_s1_corner>; + qcom,proxy-reg-names = "vdd_cx"; + qcom,vdd_cx-uV-uA = <7 100000>; + + clocks = <&clock_rpm clk_cxo_pil_lpass_clk>, + <&clock_rpm clk_scm_ce1_clk>; + clock-names = "xo", "scm_ce1_clk"; + qcom,proxy-clock-names = "xo", "scm_ce1_clk"; + qcom,scm_ce1_clk-freq = <85710000>; + + qcom,pas-id = <1>; + qcom,proxy-timeout-ms = <10000>; + qcom,smem-id = <423>; + qcom,sysmon-id = <1>; + qcom,ssctl-instance-id = <0x14>; + qcom,firmware-name = "adsp"; + + /* GPIO inputs from lpass */ + qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_2_in 0 0>; + qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_2_in 2 0>; + qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_2_in 1 0>; + qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_2_in 3 0>; + + /* GPIO output to lpass */ + qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_2_out 0 0>; + + linux,contiguous-region = <&peripheral_mem>; + }; + +/* #ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 */ + ramoops { + compatible = "ramoops"; + /*reg = <0x05800000 0x00100000>;*/ + linux,contiguous-region = <&ramoops_mem>; + }; +/* #endif VENDOR_EDIT */ + + + clock_rpm: qcom,rpmcc@fc401880 { + compatible = "qcom,rpmcc-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + #clock-cells = <1>; + }; + + clock_gcc: qcom,gcc@fc400000 { + compatible = "qcom,gcc-8994"; + reg = <0xfc400000 0x2000>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + clock-names = "xo", "xo_a_clk"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_rpm clk_cxo_clk_src_ao>; + #clock-cells = <1>; + }; + + clock_mmss: qcom,mmsscc@fd8c0000 { + compatible = "qcom,mmsscc-8994"; + reg = <0xfd8c0000 0x5200>; + reg-names = "cc_base"; + vdd_dig-supply = <&pm8994_s1_corner>; + mmpll4_dig-supply = <&pm8994_s1_corner>; + mmpll4_analog-supply = <&pm8994_l12>; + clock-names = "xo", "gpll0", "mmssnoc_ahb", + "oxili_gfx3d_clk", "pclk0_src", "pclk1_src", + "byte0_src", "byte1_src", "extpclk_src"; + clocks = <&clock_rpm clk_cxo_clk_src>, + <&clock_gcc clk_gpll0_out_mmsscc>, + <&clock_rpm clk_mmssnoc_ahb_clk>, + <&clock_rpm clk_oxili_gfx3d_clk_src>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_pixel_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_dsi0_pll clk_mdss_byte_clk_mux>, + <&mdss_hdmi_pll clk_hdmi_20nm_vco_clk>; + #clock-cells = <1>; + }; + + clock_debug: qcom,cc-debug@fc401880 { + compatible = "qcom,cc-debug-8994"; + reg = <0xfc401880 0x4>; + reg-names = "cc_base"; + clock-names = "debug_mmss_clk", "debug_rpm_clk", + "debug_cpu_clk"; + clocks = <&clock_mmss clk_mmss_debug_mux>, + <&clock_rpm clk_rpm_debug_mux>, + <&clock_cpu clk_cpu_debug_mux>; + #clock-cells = <1>; + }; + + cci_cache: qcom,cci { + compatible = "devfreq-simple-dev"; + clock-names = "devfreq_clk"; + clocks = <&clock_cpu clk_cci_clk>; + governor = "cpufreq"; + freq-tbl-khz = + < 150000 >, + < 200000 >, + < 249600 >, + < 300000 >, + < 384000 >, + < 499200 >, + < 600000 >; + }; + + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "cpufreq"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon"; + reg = <0xfc388000 0x300>, <0xfc381000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3509 /* 460 MHz */ >, + < 4066 /* 533 MHz */ >, + < 5126 /* 672 MHz */ >, + < 5928 /* 777 MHz */ >, + < 7904 /* 1036 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 11863 /* 1555 MHz */ >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + cpubw-cpufreq { + target-dev = <&cpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 1525 >, + < 691200 2288 >, + < 768000 3562 >, + < 844800 4066 >, + < 921600 5126 >, + < 940800 6072 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 1525 >, + < 600000 2288 >, + < 691200 3562 >, + < 768000 4066 >, + < 844800 5126 >, + < 921600 6072 >; + }; + + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >, + < 940800 5928 >; + cpu-to-dev-map-4 = + < 199200 1525 >, + < 302400 1525 >, + < 384000 2288 >, + < 600000 3509 >, + < 691200 4066 >, + < 768000 5126 >, + < 844800 5928 >, + < 921600 5928 >; + }; + + cci-cpufreq { + target-dev = <&cci_cache>; + cpu-to-dev-map-0 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 384000 >, + < 844800 499200 >, + < 921600 600000 >, + < 940800 600000 >; + cpu-to-dev-map-4 = + < 199200 150000 >, + < 302400 200000 >, + < 384000 249600 >, + < 600000 300000 >, + < 691200 384000 >, + < 768000 499200 >, + < 844800 600000 >, + < 921600 600000 >; + }; + }; + + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "l2_clk", "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk"; + clocks = <&clock_cpu clk_cci_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a53_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>, + <&clock_cpu clk_a57_clk>; + + qcom,governor-per-policy; + + qcom,cpufreq-table-0 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >, + < 940800 >; + + qcom,cpufreq-table-4 = + < 199200 >, + < 302400 >, + < 384000 >, + < 600000 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 921600 >; + }; + + clock_cpu: qcom,cpu-clock-8994@f9015000 { + compatible = "qcom,cpu-clock-8994"; + reg = <0xf9015000 0x1000>, + <0xf9016000 0x1000>, + <0xf9011000 0x1000>, + <0xf900d000 0x1000>, + <0xf900f000 0x1000>, + <0xf9112000 0x1000>, + <0xfc4b80b0 0x8>; + reg-names = "c0_pll", "c1_pll", "cci_pll", "c0_mux", "c1_mux", "cci_mux", "efuse"; + vdd-a53-supply = <&apc0_vreg_corner>; + vdd-a57-supply = <&apc1_vreg_corner>; + vdd-cci-supply = <&apc0_vreg_corner>; + vdd-dig-supply = <&pm8994_s1_corner_ao>; + qcom,a53-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>, + < 940800000 9>; + qcom,a57-speedbin0-v0 = + < 0 0>, + < 199200000 1>, + < 302400000 2>, + < 384000000 3>, + < 600000000 4>, + < 691200000 5>, + < 768000000 6>, + < 844800000 7>, + < 921600000 8>; + qcom,cci-speedbin0-v0 = + < 0 0>, + < 150000000 1>, + < 200000000 2>, + < 249600000 3>, + < 300000000 4>, + < 384000000 4>, + < 499200000 7>, + < 600000000 9>; + clock-names = "xo_ao", "aux_clk"; + clocks = <&clock_rpm clk_cxo_clk_src_ao>, + <&clock_gcc clk_gpll0_ao>; + #clock-cells = <1>; + }; + + ocmem: qcom,ocmem@fdd00000 { + compatible = "qcom,msm-ocmem"; + reg = <0xfdd00000 0x2000>, + <0xfdd02000 0x2000>, + <0xfe039000 0x400>, + <0xfec00000 0x200000>; + reg-names = "ocmem_ctrl_physical", "dm_ctrl_physical", "br_ctrl_physical", "ocmem_physical"; + interrupts = <0 76 0 0 77 0>; + interrupt-names = "ocmem_irq", "dm_irq"; + qcom,ocmem-num-regions = <0x4>; + qcom,ocmem-num-macros = <0x20>; + qcom,resource-type = <0x706d636f>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfec00000 0x200000>; + clocks = <&clock_rpm clk_ocmemgx_core_clk>, + <&clock_mmss clk_ocmemcx_ocmemnoc_clk>; + clock-names = "core_clk", "iface_clk"; + + partition@0 { + reg = <0x0 0x180000>; + qcom,ocmem-part-name = "graphics"; + qcom,ocmem-part-min = <0x80000>; + }; + + partition@100000 { + reg = <0x180000 0x80000>; + qcom,ocmem-part-name = "video"; + qcom,ocmem-part-min = <0x55000>; + }; + + }; + + msm_vidc: qcom,vidc@fdc00000 { + compatible = "qcom,msm-vidc"; + reg = <0xfdc00000 0xff000>; + interrupts = <0 44 0>; + qcom,hfi = "venus"; + qcom,reg-presets = <0x800D8 0x707>, + <0xe0020 0x55555556>, + <0xe0024 0x55555556>, + <0x80124 0x3>; + qcom,qdss-presets = <0xfc325000 0x1000>, + <0xfc326000 0x1000>, + <0xfc321000 0x1000>, + <0xfc322000 0x1000>, + <0xfc323000 0x1000>, + <0xfc302000 0x1000>, + <0xfa180000 0x1000>, + <0xfa181000 0x1000>; + qcom,ocmem-size = <524288>; /* 512 * 1024*/ + qcom,max-hw-load = <1281600>; /* Full 4k @ 30 + 1080p @ 30 */ + clock-names = "core_clk", "core0_clk", "core1_clk", "core2_clk", + "iface_clk", "bus_clk", "mem_clk"; + venus-supply = <&gdsc_venus>; + venus-core0-supply = <&gdsc_venus_core0>; + venus-core1-supply = <&gdsc_venus_core1>; + venus-core2-supply = <&gdsc_venus_core2>; + qcom,clock-configs = <0x3 0x0 0x0 0x0 0x0 0x0 0x0>; + qcom,sw-power-collapse; + clocks = <&clock_mmss clk_venus0_vcodec0_clk>, + <&clock_mmss clk_venus0_core0_vcodec_clk>, + <&clock_mmss clk_venus0_core1_vcodec_clk>, + <&clock_mmss clk_venus0_core2_vcodec_clk>, + <&clock_mmss clk_venus0_ahb_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_ocmemnoc_clk>; + qcom,load-freq-tbl = + <979200 465000000 0x0c000000>, + <979200 465000000 0x01000414>, + <979200 465000000 0x030fcfff>, + <979200 465000000 0x04000000>, + <783360 465000000 0x0c000000>, + <783360 465000000 0x01000414>, + <783360 465000000 0x030fcfff>, + <783360 465000000 0x04000000>, + <489600 240000000 0x0c000000>, + <489600 240000000 0x01000414>, + <489600 240000000 0x030fcfff>, + <489600 240000000 0x04000000>, + <244800 133330000 0x0c000000>, + <244800 133330000 0x01000414>, + <244800 133330000 0x030fcfff>, + <244800 133330000 0x04000000>; + qcom,vidc-iommu-domains { + qcom,domain-ns { + qcom,vidc-domain-phandle = <&venus_domain_ns>; + qcom,vidc-partition-buffer-types = <0x7ff>, + <0x800>; + }; + qcom,domain-sec-bs { + qcom,vidc-domain-phandle = <&venus_domain_sec_bitstream>; + qcom,vidc-partition-buffer-types = <0x241>; + }; + qcom,domain-sec-px { + qcom,vidc-domain-phandle = <&venus_domain_sec_pixel>; + qcom,vidc-partition-buffer-types = <0x106>; + }; + qcom,domain-sec-np { + qcom,vidc-domain-phandle = <&venus_domain_sec_non_pixel>; + qcom,vidc-partition-buffer-types = <0x480>; + }; + }; + qcom,msm-bus-clients { + qcom,msm-bus-client@0 { + qcom,msm-bus,name = "venc-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 2108700 0>, + <63 512 2243700 0>, + <63 512 2615000 0>; + qcom,bus-configs = <0x1000414>; + }; + + qcom,msm-bus-client@1 { + qcom,msm-bus,name = "vdec-core0-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 151600 0>, + <63 512 393600 0>, + <63 512 393600 0>, + <63 512 749100 0>, + <63 512 749100 0>, + <63 512 1460700 0>, + <63 512 2390500 0>, + <63 512 2542300 0>, + <63 512 2959800 0>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@2 { + qcom,msm-bus,name = "vdec-core1-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 113900 0>, + <63 512 296700 0>, + <63 512 296700 0>, + <63 512 571400 0>, + <63 512 571400 0>, + <63 512 1088500 0>, + <63 512 1811000 0>, + <63 512 1962000 0>, + <63 512 2242900 0>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@3 { + qcom,msm-bus,name = "venc-core2-ddr"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 89000 0>, + <63 512 270000 0>, + <63 512 270000 0>, + <63 512 759000 0>, + <63 512 759000 0>, + <63 512 1050000 0>, + <63 512 3077000 0>, + <63 512 3811000 0>, + <63 512 3812000 0>; + qcom,bus-configs = <0x04000000>; + }; + qcom,msm-bus-client@4 { + qcom,msm-bus,name = "venc-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 69000 2384000>, + <68 604 207000 2384000>, + <68 604 207000 2384000>, + <68 604 470000 2384000>, + <68 604 470000 2384000>, + <68 604 940000 3632000>, + <68 604 1787000 3632000>, + <68 604 1906000 3632000>, + <68 604 2234000 3632000>; + qcom,bus-configs = <0x10000414>; + }; + qcom,msm-bus-client@5 { + qcom,msm-bus,name = "venc-core2-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 71000 2384000>, + <68 604 214000 2384000>, + <68 604 214000 2384000>, + <68 604 564000 2384000>, + <68 604 564000 2384000>, + <68 604 1003000 3632000>, + <68 604 2040000 3632000>, + <68 604 2349000 3632000>, + <68 604 2551000 3632000>; + qcom,bus-configs = <0x04000000>; + }; + + qcom,msm-bus-client@6 { + qcom,msm-bus,name = "vdec-core0-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 79000 2384000>, + <68 604 201000 2384000>, + <68 604 201000 2384000>, + <68 604 367000 2384000>, + <68 604 367000 2384000>, + <68 604 735000 3632000>, + <68 604 1175000 3632000>, + <68 604 1254000 3632000>, + <68 604 1469000 3632000>; + qcom,bus-configs = <0xc000000>; + }; + + qcom,msm-bus-client@7 { + qcom,msm-bus,name = "vdec-core1-ocmem"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <68 604 0 0>, + <68 604 88000 2384000>, + <68 604 228000 2384000>, + <68 604 228000 2384000>, + <68 604 432000 2384000>, + <68 604 432000 2384000>, + <68 604 865000 3632000>, + <68 604 1374000 3632000>, + <68 604 1465000 3632000>, + <68 604 1717000 3632000>; + qcom,bus-configs = <0x30fcfff>; + }; + + qcom,msm-bus-client@8 { + qcom,msm-bus,name = "venc-ddr-lp"; + qcom,msm-bus,num-cases = <10>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 66800 0>, + <63 512 201100 0>, + <63 512 201100 0>, + <63 512 458300 0>, + <63 512 458300 0>, + <63 512 889200 0>, + <63 512 1218000 0>, + <63 512 1218000 0>, + <63 512 1218000 0>; + qcom,bus-low-power; + qcom,bus-configs = <0x0000004>; + }; + + qcom,msm-bus-client@9 { + qcom,msm-bus,name = "venus-arm9-ddr"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <63 512 0 0>, + <63 512 1000 1000>; + qcom,bus-configs = <0x00000000>; + qcom,bus-passive; + }; + }; + }; + + i2c_1: i2c@f9923000 { + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9923000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 95 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_1_active>; + pinctrl-1 = <&i2c_1_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + qcom,master-id = <86>; + dmas = <&dma_blsp1 10 64 0x20000020 0x20>, + <&dma_blsp1 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + dma_blsp1: qcom,sps-dma@f9904000 { /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9904000 0x19000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <10>; + }; + + dma_blsp2: qcom,sps-dma@f9944000 { /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xf9944000 0x19000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <10>; + }; + + + i2c_2: i2c@f9924000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9924000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 96 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_2_active>; + pinctrl-1 = <&i2c_2_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + + /* #ifdef VENDOR_EDIT */ + //add by yangrujin@bsp for dma has some issue causing i2c fail + //qcom,disable-dma; + /* #endif //VENDOR_EDIT */ + + + dmas = <&dma_blsp1 14 64 0x20000020 0x20>, + <&dma_blsp1 15 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + i2c_5: i2c_11: i2c@f9967000 { /* BLSP2 QUP5 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0xf9967000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 105 0>; + qcom,clk-freq-out = <100000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup5_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_5_active>; + pinctrl-1 = <&i2c_5_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/4/13, dma mode will cause I2C fail*/ + qcom,disable-dma; + //#endif + dmas = <&dma_blsp2 20 64 0x20000020 0x20>, + <&dma_blsp2 21 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + }; + + i2c_6: i2c@f9928000 { /* BLSP1 QUP6 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + reg-names = "qup_phys_addr"; + reg = <0xf9928000 0x1000>; + interrupt-names = "qup_irq"; + interrupts = <0 100 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + dmas = <&dma_blsp1 22 64 0x20000020 0x20>, + <&dma_blsp1 23 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + }; + + sound { + compatible = "qcom,msm8994-asoc-snd"; + qcom,model = "msm8994-tomtom-snd-card"; + reg = <0xfe034000 0x4>, + <0xfe035000 0x4>, + <0xfe036000 0x4>, + <0xfe037000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "LDO_H", "MCLK", + "MADINPUT", "MCLK"; + //#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv , 2015/3/19, delete unsed mic*/ + //"AMIC1", "MIC BIAS1 Internal1", + //"MIC BIAS1 Internal1", "Handset Mic", + //"AMIC2", "MIC BIAS2 External", + //"MIC BIAS2 External", "Headset Mic", + //"AMIC3", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCRight Headset Mic", + //"AMIC4", "MIC BIAS2 External", + //"MIC BIAS2 External", "ANCLeft Headset Mic", + //"DMIC1", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic1", + //"DMIC2", "MIC BIAS1 External", + //"MIC BIAS1 External", "Digital Mic2", + //"DMIC3", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic3", + //"DMIC4", "MIC BIAS3 External", + //"MIC BIAS3 External", "Digital Mic4", + //"DMIC5", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic5", + //"DMIC6", "MIC BIAS4 External", + //"MIC BIAS4 External", "Digital Mic6"; + //#endif + + clock-names = "osr_clk"; + clocks = <&clock_rpm clk_div_clk1>; + qcom,cdc-mclk-gpios = <&pm8994_gpios 15 0>; + qcom,tomtom-mclk-clk-freq = <9600000>; + pinctrl-names = "sleep", + "auxpcm-active", + "mi2s-active", + //#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv,changed for quat i2s */ + "active", + "quat_mi2s_sleep", + "quat_mi2s_active"; + //#endif +//#ifdef VENDOR_EDIT +//pinctrl-0 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-1 = <&pri_mi2s_sleep>, <&pri_mi2s_sd0_sleep>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//pinctrl-2 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; +//pinctrl-3 = <&pri_mi2s_active>, <&pri_mi2s_sd0_active>, +// <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif + +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv,2015-4-8,remove unused pri-i2s for conflict pins with BSP module.*/ + pinctrl-0 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-1 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; + pinctrl-2 = <&sec_aux_pcm_sleep>, <&sec_aux_pcm_din_sleep>; + pinctrl-3 = <&sec_aux_pcm_active>, <&sec_aux_pcm_din_active>; +//#endif +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s */ + pinctrl-4 = <&quat_mi2s_sleep>, <&quat_mi2s_mclk_sleep>, <&quat_mi2s_sd0_sleep> , <&quat_mi2s_sd1_sleep>; + pinctrl-5 = <&quat_mi2s_active>, <&quat_mi2s_mclk_active>, <&quat_mi2s_sd0_active> , <&quat_mi2s_sd1_active>; +//#endif + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", "msm-pcm-dsp.2", + "msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe", + "msm-lsm-client", "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp"; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv changed for quat i2s*/ + asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>, <&dai_mi2s>,<&qua_mi2s>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, <&bt_sco_rx>, + <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>, <&afe_pcm_rx>, + <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>, + <&incall_music2_rx>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.0","msm-dai-q6-mi2s.3", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.12288", + "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292", + "msm-dai-q6-dev.12293", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770"; +//#endif + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + }; + + qcom,msm-adsp-loader { + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + qcom,msm-audio-ion { + compatible = "qcom,msm-audio-ion"; + }; + + pcm0: qcom,msm-pcm { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <0>; + }; + + qcom,msm-pcm-lpa { + compatible = "qcom,msm-pcm-lpa"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm1: qcom,msm-pcm-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <1>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "regular"; + }; + + routing: qcom,msm-pcm-routing { + compatible = "qcom,msm-pcm-routing"; + }; + + compr: qcom,msm-compr-dsp { + compatible = "qcom,msm-compr-dsp"; + }; + + compress: qcom,msm-compress-dsp { + compatible = "qcom,msm-compress-dsp"; + }; + + voip: qcom,msm-voip-dsp { + compatible = "qcom,msm-voip-dsp"; + }; + + voice: qcom,msm-pcm-voice { + compatible = "qcom,msm-pcm-voice"; + qcom,destroy-cvd; + }; + + stub_codec: qcom,msm-stub-codec { + compatible = "qcom,msm-stub-codec"; + }; + + qcom,msm-dai-fe { + compatible = "qcom,msm-dai-fe"; + }; + + afe: qcom,msm-pcm-afe { + compatible = "qcom,msm-pcm-afe"; + }; + + dai_hdmi: qcom,msm-dai-q6-hdmi { + compatible = "qcom,msm-dai-q6-hdmi"; + qcom,msm-dai-q6-dev-id = <8>; + }; + + lsm: qcom,msm-lsm-client { + compatible = "qcom,msm-lsm-client"; + }; + + loopback: qcom,msm-pcm-loopback { + compatible = "qcom,msm-pcm-loopback"; + }; + + qcom,msm-voice-svc { + compatible = "qcom,msm-voice-svc"; + }; + + cpe: qcom,msm-cpe-lsm { + compatible = "qcom,msm-cpe-lsm"; + }; + + qcom,msm-dai-q6 { + compatible = "qcom,msm-dai-q6"; + sb_0_rx: qcom,msm-dai-q6-sb-0-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16384>; + }; + + sb_0_tx: qcom,msm-dai-q6-sb-0-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16385>; + }; + + sb_1_rx: qcom,msm-dai-q6-sb-1-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16386>; + }; + + sb_1_tx: qcom,msm-dai-q6-sb-1-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16387>; + }; + + sb_2_rx: qcom,msm-dai-q6-sb-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16388>; + }; + + sb_2_tx: qcom,msm-dai-q6-sb-2-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16389>; + }; + + sb_3_rx: qcom,msm-dai-q6-sb-3-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16390>; + }; + + sb_3_tx: qcom,msm-dai-q6-sb-3-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16391>; + }; + + sb_4_rx: qcom,msm-dai-q6-sb-4-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16392>; + }; + + sb_4_tx: qcom,msm-dai-q6-sb-4-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16393>; + }; + + sb_5_tx: qcom,msm-dai-q6-sb-5-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16395>; + }; + + bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12288>; + }; + + bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12289>; + }; + + int_fm_rx: qcom,msm-dai-q6-int-fm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12292>; + }; + + int_fm_tx: qcom,msm-dai-q6-int-fm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12293>; + }; + + afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <224>; + }; + + afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <225>; + }; + + afe_proxy_rx: com,msm-dai-q6-afe-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <241>; + }; + + afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <240>; + }; + + incall_record_rx: qcom,msm-dai-q6-incall-record-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32771>; + }; + + incall_record_tx: qcom,msm-dai-q6-incall-record-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32772>; + }; + + incall_music_rx: qcom,msm-dai-q6-incall-music-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32773>; + }; + + incall_music2_rx: qcom,msm-dai-q6-incall-music-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32770>; + }; + }; + + dai_pri_auxpcm: qcom,msm-pri-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "primary"; + }; + + dai_sec_auxpcm: qcom,msm-sec-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "secondary"; + }; + + qcom,msm-dai-mi2s { + compatible = "qcom,msm-dai-mi2s"; + dai_mi2s: qcom,msm-dai-q6-mi2s-prim { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <0>; +//#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv ,changed for quat i2s*/ + + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + qua_mi2s: qcom,msm-dai-q6-mi2s-quat { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <3>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; +//#endif + }; + + hostless: qcom,msm-pcm-hostless { + compatible = "qcom,msm-pcm-hostless"; + }; + + tsens: tsens@fc4a8000 { + compatible = "qcom,msm8994-tsens"; + reg = <0xfc4a8000 0x2000>, + <0xfc4bc000 0x1000>; + reg-names = "tsens_physical", "tsens_eeprom_physical"; + interrupts = <0 184 0>; + interrupt-names = "tsens-upper-lower"; + qcom,sensors = <16>; + qcom,slope = <2901 2846 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200>; + }; + + qcom_tzlog: tz-log@fe87f720 { + compatible = "qcom,tz-log"; + reg = <0xfe87f720 0x2000>; + }; + + qcom_crypto1fde: qcrypto1fde@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2fde: qcrypto2fde@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <0>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto1pfe: qcrypto1pfe@fd440000 { + compatible = "qcom,qcrypto"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <1>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto2pfe: qcrypto2pfe@0xfd3c0000 { + compatible = "qcom,qcrypto"; + reg = <0xfd3c0000 0x20000>, + <0xfd3c4000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 297 0>; + qcom,bam-pipe-pair = <0>; + qcom,ce-hw-instance = <2>; + qcom,ce-device = <1>; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcrypto_ce3_clk>, + <&clock_rpm clk_gcc_ce3_ahb_m_clk>, + <&clock_rpm clk_gcc_ce3_axi_m_clk>; + qcom,support-core-clk-only; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_cedev: qcedev@fd440000 { + compatible = "qcom,qcedev"; + reg = <0xfd440000 0x20000>, + <0xfd444000 0x9000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 236 0>; + qcom,bam-pipe-pair = <1>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "iface_clk", "bus_clk"; + clocks = <&clock_rpm clk_qcedev_ce2_clk>, + <&clock_rpm clk_gcc_ce2_ahb_m_clk>, + <&clock_rpm clk_gcc_ce2_axi_m_clk>; + qcom,support-core-clk-only; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,qseecom@6500000{ + compatible = "qcom,qseecom"; + reg = <0x0E900000 0x1900000>;//reg = <0x6500000 0x500000>; ----> <0x0E700000 0x700000>; ----> <0x0E900000 0x1900000>; /*VENDOR_EDIT changhua add more memory for fpc1150 and alipay in TZ*/ + reg-names = "secapp-region"; + qcom,disk-encrypt-pipe-pair = <2>; + qcom,file-encrypt-pipe-pair = <0>; + qcom,support-multiple-ce-hw-instance; + qcom,hlos-num-ce-hw-instances = <2>; + qcom,hlos-ce-hw-instance = <1 2>; + qcom,qsee-ce-hw-instance = <0>; + qcom,msm-bus,name = "qseecom-noc"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,support-fde; + qcom,support-pfe; + qcom,no-clock-support; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 0 0>, + <55 512 120000 1200000>, + <55 512 393600 3936000>; + clock-names = "core_clk", "ufs_core_clk_src", "ufs_core_clk", + "ufs_bus_clk", "ufs_iface_clk"; + clocks = <&clock_rpm clk_qseecom_ce1_clk>, + <&clock_gcc clk_ufs_axi_clk_src>, + <&clock_gcc clk_gcc_ufs_axi_clk>, + <&clock_gcc clk_gcc_sys_noc_ufs_axi_clk>, + <&clock_gcc clk_gcc_ufs_ahb_clk>; + qcom,ce-opp-freq = <171430000>; + }; + + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information@0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + }; + + sensor_information1: qcom,sensor-information@1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + }; + + sensor_information2: qcom,sensor-information@2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,alias-name = "pop_mem"; + }; + + sensor_information3: qcom,sensor-information@3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + }; + + sensor_information4: qcom,sensor-information@4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + }; + + sensor_information5: qcom,sensor-information@5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + }; + + sensor_information6: qcom,sensor-information@6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,alias-name = "cpu7"; + }; + + sensor_information7: qcom,sensor-information@7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,alias-name = "cpu0"; + }; + + sensor_information8: qcom,sensor-information@8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,alias-name = "cpu1"; + }; + + sensor_information9: qcom,sensor-information@9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,alias-name = "cpu2"; + }; + + sensor_information10: qcom,sensor-information@10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,alias-name = "cpu3"; + }; + + sensor_information11: qcom,sensor-information@11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + }; + + sensor_information12: qcom,sensor-information@12 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor12"; + qcom,alias-name = "gpu"; + }; + + sensor_information13: qcom,sensor-information@13 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor13"; + qcom,alias-name = "cpu4"; + }; + + sensor_information14: qcom,sensor-information@14 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor14"; + qcom,alias-name = "cpu5"; + }; + + sensor_information15: qcom,sensor-information@15 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor15"; + qcom,alias-name = "cpu6"; + }; + + sensor_information16: qcom,sensor-information@16 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pm8994_tz"; + qcom,scaling-factor = <1000>; + }; + + sensor_information17: qcom,sensor-information@17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + + sensor_information18: qcom,sensor-information@18 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "emmc_therm"; + }; + + sensor_information19: qcom,sensor-information@19 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + + sensor_information20: qcom,sensor-information@20 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + + sensor_information21: qcom,sensor-information@21 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + + sensor_information22: qcom,sensor-information@22 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "LLM_IA57"; + }; + + sensor_information23: qcom,sensor-information-23 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "battery"; + }; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <7>; + qcom,poll-ms = <250>; + qcom,limit-temp = <60>; + qcom,temp-hysteresis = <10>; + qcom,therm-reset-temp = <115>; + qcom,freq-step = <2>; + qcom,freq-control-mask = <0xff>; + qcom,core-limit-temp = <80>; + qcom,core-temp-hysteresis = <10>; + qcom,core-control-mask = <0xfe>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <40>; + qcom,cpu-sensors = "tsens_tz_sensor7", "tsens_tz_sensor8", + "tsens_tz_sensor9", "tsens_tz_sensor10", + "tsens_tz_sensor13", "tsens_tz_sensor14", + "tsens_tz_sensor15", "tsens_tz_sensor6"; + qcom,freq-mitigation-temp = <95>; + qcom,freq-mitigation-temp-hysteresis = <10>; + qcom,freq-mitigation-value = <960000>; + qcom,freq-mitigation-control-mask = <0xF0>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,mx-restriction-temp = <5>; + qcom,mx-restriction-temp-hysteresis = <10>; + qcom,mx-retention-min = <3>; + vdd-mx-supply = <&pm8994_s2_corner>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm8994_s1_floor_corner>; + vdd-gfx-supply = <&pmi8994_s2_floor_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 7 7>; /* Nominal, Super Turbo, Super Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <302400 600000 600000>; + qcom,freq-req; + }; + }; + + qcom,bcl { + compatible = "qcom,bcl"; + qcom,bcl-enable; + qcom,bcl-framework-interface; + qcom,bcl-freq-control-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,bcl-hotplug-list = <&CPU6 &CPU7>; + qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,ibat-monitor { + qcom,low-threshold-uamp = <3400000>; + qcom,high-threshold-uamp = <4200000>; + qcom,mitigation-freq-khz = <768000>; + qcom,vph-high-threshold-uv = <3500000>; + qcom,vph-low-threshold-uv = <3300000>; + qcom,soc-low-threshold = <20>; + qcom,thermal-handle = <&msm_thermal_freq>; + }; + }; + + cnss: qcom,cnss@06300000 { + compatible = "qcom,cnss"; + reg = <0x06300000 0x200000>; + reg-names = "ramdump"; + wlan-en-gpio = <&msm_gpio 113 0>; + vdd-wlan-supply = <&bt_vreg>; + vdd-wlan-io-supply = <&pm8994_s4>; + vdd-wlan-xtal-supply = <&pm8994_l30>; + qcom,notify-modem-status; + pinctrl-names = "default"; + pinctrl-0 = <&cnss_default>; + qcom,wlan-rc-num = <1>; + qcom,wlan-uart-access; + + qcom,msm-bus,name = "msm-cnss"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <100 512 0 0>, /* No vote */ + <100 512 6250 200000>, /* 50 Mbps */ + <100 512 25000 200000>, /* 200 Mbps */ + <100 512 100000 200000>; /* 800 Mbps */ + }; + + audio_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&audio_mem>; + }; + + adsp_heap { + compatible = "qcom,msm-shared-memory"; + qcom,proc-id = <1>; + linux,contiguous-region = <&adsp_mem>; + }; + + qcom,msm-core@fc4b8000 { + compatible = "qcom,apss-core-ea"; + reg = <0xfc4b8000 0x1000>; + qcom,low-hyst-temp = <10>; + qcom,high-hyst-temp = <5>; + qcom,polling-interval = <50>; + + qcom,core-mapping { + qcom,cpu0-chars { + qcom,sensor = <&sensor_information7>; + qcom,cpu-name = <&CPU0>; + }; + + qcom,cpu1-chars { + qcom,sensor = <&sensor_information8>; + qcom,cpu-name = <&CPU1>; + }; + + qcom,cpu2-chars { + qcom,sensor = <&sensor_information9>; + qcom,cpu-name = <&CPU2>; + }; + + qcom,cpu3-chars { + qcom,sensor = <&sensor_information10>; + qcom,cpu-name = <&CPU3>; + }; + + qcom,cpu4-chars { + qcom,sensor = <&sensor_information13>; + qcom,cpu-name = <&CPU4>; + }; + + qcom,cpu5-chars { + qcom,sensor = <&sensor_information14>; + qcom,cpu-name = <&CPU5>; + }; + + qcom,cpu6-chars { + qcom,sensor = <&sensor_information15>; + qcom,cpu-name = <&CPU6>; + }; + + qcom,cpu7-chars { + qcom,sensor = <&sensor_information6>; + qcom,cpu-name = <&CPU7>; + }; + }; + }; + + qcom,system-health-monitor { + compatible = "qcom,system-health-monitor"; + + qcom,system-health-monitor-modem { + qcom,subsys-name = "msm_mpss"; + qcom,ssrestart-string = "modem"; + }; + }; + + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,itlb_dump100 { + qcom,dump-node = <&L1_itlb_100>; + qcom,dump-id = <0x24>; + }; + qcom,itlb_dump101 { + qcom,dump-node = <&L1_itlb_101>; + qcom,dump-id = <0x25>; + }; + qcom,itlb_dump102 { + qcom,dump-node = <&L1_itlb_102>; + qcom,dump-id = <0x26>; + }; + qcom,itlb_dump103 { + qcom,dump-node = <&L1_itlb_103>; + qcom,dump-id = <0x27>; + }; + qcom,dtlb_dump100 { + qcom,dump-node = <&L1_dtlb_100>; + qcom,dump-id = <0x44>; + }; + qcom,dtlb_dump101 { + qcom,dump-node = <&L1_dtlb_101>; + qcom,dump-id = <0x45>; + }; + qcom,dtlb_dump102 { + qcom,dump-node = <&L1_dtlb_102>; + qcom,dump-id = <0x46>; + }; + qcom,dtlb_dump103 { + qcom,dump-node = <&L1_dtlb_103>; + qcom,dump-id = <0x47>; + }; + qcom,l2_tlb_dump0 { + qcom,dump-node = <&L2_tlb_0>; + qcom,dump-id = <0x120>; + }; + qcom,l2_tlb_dump100 { + qcom,dump-node = <&L2_tlb_1>; + qcom,dump-id = <0x121>; + }; + qcom,l2_dump0 { + qcom,dump-node = <&L2_0>; /* L2 cache dump for A53 cluster */ + qcom,dump-id = <0xC0>; + }; + qcom,l2_dump1 { + qcom,dump-node = <&L2_1>; /* L2 cache dumo for A57 cluster */ + qcom,dump-id = <0xC1>; + }; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + + qcom,avtimer@fe09c000 { + compatible = "qcom,avtimer"; + reg = <0xFE09C00C 0x4>, + <0xFE09C010 0x4>; + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr"; + qcom,clk_div = <27>; + }; + + cci@f9100000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf9100000 0x1000>; + ranges = <0x0 0xf9100000 0x10000>; + hw-version = <8>; + + pmu@a000 { + compatible = "arm,cci-400-pmu"; + reg = <0x9000 0x5000>; + interrupts = <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>, + <0 344 0>; + }; + + }; +}; + +&gdsc_usb30 { + reg = <0xfc4003c4 0x4>; + status = "ok"; +}; + +&gdsc_pcie_0 { + status = "ok"; +}; + +&gdsc_pcie_1 { + status = "ok"; +}; + +&gdsc_ufs { + status = "ok"; +}; + +&gdsc_venus { + clock-names = "ocmem_clk", "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_venus0_ocmemnoc_clk>, + <&clock_mmss clk_venus0_axi_clk>, + <&clock_mmss clk_venus0_vcodec0_clk>; + status = "ok"; +}; + +&gdsc_venus_core0 { + qcom,support-hw-trigger; + clock-names = "core0_clk"; + clocks = <&clock_mmss clk_venus0_core0_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core1 { + qcom,support-hw-trigger; + clock-names = "core1_clk"; + clocks = <&clock_mmss clk_venus0_core1_vcodec_clk>; + status = "ok"; +}; + +&gdsc_venus_core2 { + qcom,support-hw-trigger; + clock-names = "core2_clk"; + clocks = <&clock_mmss clk_venus0_core2_vcodec_clk>; + status = "ok"; +}; + +&gdsc_mdss { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_mdss_axi_clk>, + <&clock_mmss clk_mdss_mdp_clk>; + status = "ok"; +}; + +&gdsc_camss_top { + clock-names = "csi0_clk", "csi1_clk", "bus_clk"; + clocks = <&clock_mmss clk_camss_csi_vfe0_clk>, + <&clock_mmss clk_camss_csi_vfe1_clk>, + <&clock_mmss clk_camss_micro_ahb_clk>; + status = "ok"; +}; + +&gdsc_jpeg { + clock-names = "bus_clk", "core0_clk", "core1_clk", "core2_clk"; + clocks = <&clock_mmss clk_camss_jpeg_jpeg_axi_clk>, + <&clock_mmss clk_camss_jpeg_jpeg0_clk>, + <&clock_mmss clk_camss_jpeg_jpeg1_clk>, + <&clock_mmss clk_camss_jpeg_jpeg2_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_vfe { + clock-names = "bus_clk"; + clocks = <&clock_mmss clk_camss_vfe_vfe_axi_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_cpp { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_camss_vfe_cpp_axi_clk>, + <&clock_mmss clk_camss_vfe_cpp_clk>; + parent-supply = <&gdsc_camss_top>; + status = "ok"; +}; + +&gdsc_fd { + clock-names = "bus_clk", "core_clk"; + clocks = <&clock_mmss clk_fd_axi_clk>, + <&clock_mmss clk_fd_core_clk>; + status = "ok"; +}; + +&gdsc_oxili_cx { + status = "ok"; +}; + +&gdsc_oxili_gx { + clock-names = "core_clk"; + clocks = <&clock_mmss clk_oxili_gfx3d_clk>; + status = "ok"; + parent-supply = <&pmi8994_s2_corner>; +}; + +#include "msm-pm8994-rpm-regulator.dtsi" +#include "msm-pm8994.dtsi" +#include "msm-pmi8994.dtsi" +#include "msm8994-regulator.dtsi" +#include "msm8994-ion.dtsi" +#include "msm8994-iommu.dtsi" +#include "msm8994-iommu-domains.dtsi" +#include "msm8994-camera.dtsi" +#include "msm8994-gpu.dtsi" +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi0-video.dtsi" +#include "dsi-panel-sim-dualmipi1-video.dtsi" +#include "dsi-panel-sim-cmd.dtsi" +#include "dsi-panel-sim-dualmipi0-cmd.dtsi" +#include "dsi-panel-sim-dualmipi1-cmd.dtsi" diff --git a/arch/arm64/boot/dts/14049_HW_14/skeleton64.dtsi b/arch/arm64/boot/dts/14049_HW_14/skeleton64.dtsi new file mode 100755 index 0000000000000..1f8ba28132c4a --- /dev/null +++ b/arch/arm64/boot/dts/14049_HW_14/skeleton64.dtsi @@ -0,0 +1,15 @@ +/* + * Skeleton device tree in the 64 bits version; the bare minimum + * needed to boot; just include and add a compatible value. The + * bootloader will typically populate the memory node. + */ + +/ { + #address-cells = <2>; + #size-cells = <2>; + cpus { }; + soc { }; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0 0 0>; }; +}; diff --git a/arch/arm64/boot/qcom/Makefile b/arch/arm64/boot/qcom/Makefile new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/arch/arm64/configs/cm_oneplus2_defconfig b/arch/arm64/configs/cm_oneplus2_defconfig new file mode 100644 index 0000000000000..4467f558b5545 --- /dev/null +++ b/arch/arm64/configs/cm_oneplus2_defconfig @@ -0,0 +1,4002 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 3.10.49 Kernel Configuration +# +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_NO_IOPORT_MAP=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_ARM64_DMA_USE_IOMMU=y +CONFIG_ARM64_DMA_IOMMU_ALIGNMENT=8 +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="-perf" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_FHANDLE is not set +CONFIG_AUDIT=y +# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +# CONFIG_TICK_CPU_ACCOUNTING is not set +CONFIG_IRQ_TIME_ACCOUNTING=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +CONFIG_RCU_FAST_NO_HZ=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_RCU_NOCB_CPU is not set +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +# CONFIG_MEMCG is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +# CONFIG_BLK_CGROUP is not set +CONFIG_SCHED_HMP=y +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_NET_NS=y +CONFIG_UIDGID_CONVERTED=y +# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HOTPLUG=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_EXPERT=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_PCI_QUIRKS=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_JUMP_LABEL is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +# CONFIG_MODULES is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_TEST is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_ROW=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_FIOPS=y +CONFIG_IOSCHED_BFQ=y +CONFIG_CGROUP_BFQIO=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_ROW is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_FIOPS is not set +# CONFIG_DEFAULT_BFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_OEM_DEBUG_SUPORT=y +CONFIG_FREEZER=y + +# +# Platform selection +# +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_MSM=y +# CONFIG_ARCH_MSM8916 is not set +CONFIG_ARCH_MSM8994=y +CONFIG_ARCH_MSM8994_V1_TLBI_WA=y +# CONFIG_ARCH_MSM8992 is not set +# CONFIG_ARCH_XGENE is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +CONFIG_PCI_MSM=y +# CONFIG_PCIEPORTBUS is not set + +# +# Kernel Features +# +# CONFIG_ARM64_DCACHE_DISABLE is not set +# CONFIG_ARM64_ICACHE_DISABLE is not set +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_A57_ERRATA_832075=y +CONFIG_ARM64_SEV_IN_LOCK_UNLOCK=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +# CONFIG_ARCH_WANTS_CTXSW_LOGGING is not set +CONFIG_NR_CPUS=8 +CONFIG_HOTPLUG_CPU=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_SWP_EMULATE=y +CONFIG_HZ=100 +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HW_PERF_EVENTS=y +# CONFIG_PERF_EVENTS_USERMODE is not set +# CONFIG_PERF_EVENTS_RESET_PMU_DEBUGFS is not set +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARMV7_COMPAT=y +CONFIG_ARMV7_COMPAT_CPUINFO=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +# CONFIG_USE_USER_ACCESSIBLE_TIMERS is not set +# CONFIG_ZBUD is not set +# CONFIG_BALANCE_ANON_FILE_RECLAIM is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_KSWAPD_CPU_AFFINITY_MASK="" +# CONFIG_XEN is not set +CONFIG_FORCE_MAX_ZONEORDER=11 + +# +# Boot options +# +CONFIG_CMDLINE="" +# CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE is not set +# CONFIG_EFI is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HAS_WAKELOCK=y +CONFIG_WAKELOCK=y +CONFIG_POWERSUSPEND=y +# CONFIG_POWERSUSPEND_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_OPP=y +CONFIG_PM_CLK=y +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM64_CPU_SUSPEND=y + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_SCHED_FREQ_INPUT=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_BOOST=y +# CONFIG_GENERIC_CPUFREQ_CPU0 is not set + +# +# ARM CPU frequency scaling drivers +# +# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set +# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5440_CPUFREQ is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_CPU_FREQ_MSM=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=y +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_IPVTI is not set +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +CONFIG_ANDROID_PARANOID_NETWORK=y +CONFIG_NET_ACTIVITY_STATS=y +CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_SECMARK is not set +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_BROADCAST=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_DCCP=y +CONFIG_NF_NAT_PROTO_UDPLITE=y +CONFIG_NF_NAT_PROTO_SCTP=y +CONFIG_NF_NAT_AMANDA=y +CONFIG_NF_NAT_FTP=y +CONFIG_NF_NAT_IRC=y +# CONFIG_NF_NAT_SIP is not set +CONFIG_NF_NAT_TFTP=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NETMAP=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_REDIRECT=y +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ECN=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=y +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT_IPV4=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +# CONFIG_IP_NF_TARGET_NATTYPE_MODULE is not set +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_NF_NAT_PROTO_GRE=y +CONFIG_NF_NAT_PPTP=y +CONFIG_NF_NAT_H323=y +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_RAW=y +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_IP6_NF_SECURITY is not set +# CONFIG_NF_NAT_IPV6 is not set +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +# CONFIG_BRIDGE_EBT_T_FILTER is not set +# CONFIG_BRIDGE_EBT_T_NAT is not set +# CONFIG_BRIDGE_EBT_802_3 is not set +# CONFIG_BRIDGE_EBT_AMONG is not set +# CONFIG_BRIDGE_EBT_ARP is not set +# CONFIG_BRIDGE_EBT_IP is not set +# CONFIG_BRIDGE_EBT_IP6 is not set +# CONFIG_BRIDGE_EBT_LIMIT is not set +# CONFIG_BRIDGE_EBT_MARK is not set +# CONFIG_BRIDGE_EBT_PKTTYPE is not set +# CONFIG_BRIDGE_EBT_STP is not set +# CONFIG_BRIDGE_EBT_VLAN is not set +# CONFIG_BRIDGE_EBT_ARPREPLY is not set +# CONFIG_BRIDGE_EBT_DNAT is not set +# CONFIG_BRIDGE_EBT_MARK_T is not set +# CONFIG_BRIDGE_EBT_REDIRECT is not set +# CONFIG_BRIDGE_EBT_SNAT is not set +# CONFIG_BRIDGE_EBT_LOG is not set +# CONFIG_BRIDGE_EBT_ULOG is not set +# CONFIG_BRIDGE_EBT_NFLOG is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_HAVE_NET_DSA=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +CONFIG_NET_SCH_HTB=y +# CONFIG_NET_SCH_HFSC is not set +CONFIG_NET_SCH_PRIO=y +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_CODEL is not set +# CONFIG_NET_SCH_FQ_CODEL is not set +# CONFIG_NET_SCH_INGRESS is not set +# CONFIG_NET_SCH_PLUG is not set + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +CONFIG_NET_CLS_FLOW=y +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +# CONFIG_NET_EMATCH_CMP is not set +# CONFIG_NET_EMATCH_NBYTE is not set +CONFIG_NET_EMATCH_U32=y +# CONFIG_NET_EMATCH_META is not set +# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_GACT is not set +# CONFIG_NET_ACT_MIRRED is not set +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETLINK_DIAG is not set +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +# CONFIG_RMNET_DATA_DEBUG_PKT is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_NETPRIO_CGROUP is not set +CONFIG_BQL=y +CONFIG_SOCKEV_NLMCAST=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +CONFIG_MSM_BT_POWER=y +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_INTERNAL_REGDB=y +# CONFIG_CFG80211_WEXT is not set +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +# CONFIG_MAC80211 is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_NFC_QNCI=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_HAVE_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=15 +# CONFIG_CMA_RESERVE_DEFAULT_AREA is not set + +# +# Bus devices +# +CONFIG_ARM_CCI=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +# CONFIG_PROC_DEVICETREE is not set +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_SPMI=y +CONFIG_OF_SLIMBUS=y +CONFIG_OF_BATTERYDATA=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_PHANTOM is not set +# CONFIG_INTEL_MID_PTI is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_APDS9930 is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_UID_STAT is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_PCH_PHUB is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_HAPTIC_ISA1200 is not set +CONFIG_QSEECOM=y +# CONFIG_QFP_FUSE is not set +# CONFIG_QPNP_MISC is not set +CONFIG_TI_DRV2667=y +CONFIG_TI_DRV2605=y +CONFIG_QCOM_LIQUID_DOCK=y +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_ULTRASOUND=y + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +CONFIG_SCSI_UFSHCD=y +# CONFIG_SCSI_UFSHCD_PCI is not set +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_QCOM_ICE=y +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_CHELSIO_FCOE is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_HAVE_PATA_PLATFORM=y +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +CONFIG_DM_VERITY=y +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +CONFIG_DUMMY=y +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +CONFIG_MII=y +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +CONFIG_NET_CADENCE=y +# CONFIG_ARM_AT91_ETHER is not set +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2X is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EXAR=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +CONFIG_E1000E=y +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +CONFIG_NET_VENDOR_I825XX=y +# CONFIG_IP1000 is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_NET_VENDOR_MSM is not set +# CONFIG_MSM_RMNET_WWAN is not set +# CONFIG_ECM_IPA is not set +CONFIG_RNDIS_IPA=y +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_PCH_GBE is not set +# CONFIG_ETHOC is not set +CONFIG_NET_PACKET_ENGINE=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +# CONFIG_SFC is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_MPPE=y +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPPOE=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_CDC_MBIM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=y +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +CONFIG_USB_NET_CDC_SUBSET=y +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=y +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_MSM_RMNET_USB is not set +CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +# CONFIG_LIBRA_SDIOIF is not set +# CONFIG_ATH6K_LEGACY_EXT is not set +# CONFIG_WCNSS_CORE is not set +CONFIG_CNSS=y +# CONFIG_CNSS_SECURE_FW is not set +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CNSS_MAC_BUG=y +CONFIG_CLD_LL_CORE=y +CONFIG_ATH_CARDS=y +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH5K_PCI is not set +# CONFIG_ATH6KL is not set +CONFIG_WIL6210=y +CONFIG_WIL6210_ISR_COR=y +CONFIG_WIL6210_TRACING=y +CONFIG_WIL6210_PLATFORM_MSM=y +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_IPW2100 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_WL_TI is not set +# CONFIG_MWIFIEX is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_DANIPC is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYCOMBO is not set +# CONFIG_SENSORS_HALL is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_QPNP is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=y +# CONFIG_JOYSTICK_XPAD_FF is not set +# CONFIG_JOYSTICK_XPAD_LEDS is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v21=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21=y +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 is not set +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_FT5X06 is not set +# CONFIG_TOUCHSCREEN_MSTAR21XX is not set +# CONFIG_TOUCHSCREEN_GEN_VKEYS is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +CONFIG_SECURE_TOUCH=y +# CONFIG_TOUCHSCREEN_GT9XX is not set +# CONFIG_TOUCHSCREEN_BU21150 is not set +# CONFIG_INPUT_MT_WRAPPER is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI=y +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_HBTP_INPUT is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_SENSORS_MPU6050 is not set +# CONFIG_SENSORS_LIS3DH is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_ISA1200_FF_MEMLESS is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_BMP18X is not set +# CONFIG_SENSORS_MMA8X5X is not set +# CONFIG_SENSORS_AP3426 is not set +# CONFIG_SENSORS_LTR553 is not set +# CONFIG_SENSORS_MMC3416X is not set +# CONFIG_SENSORS_AKM09911 is not set +# CONFIG_SENSORS_AKM8963 is not set +# CONFIG_SENSORS_STK3X1X is not set +# CONFIG_SENSORS_CAPELLA_CM36283 is not set +# CONFIG_SENSORS_BMA2X2 is not set +# CONFIG_SENSORS_MC3430 is not set +# CONFIG_SENSORS_ISL29044A is not set +CONFIG_BTP_FPC1021=y +CONFIG_TRI_STATE_KEY=y +# CONFIG_SWITCH_ANTENNA is not set +CONFIG_SWITCH_THEME=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_N_SMUX is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_MFD_HSU is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_HSL=y +CONFIG_SERIAL_MSM_HSL_CONSOLE=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_PCH_UART is not set +CONFIG_SERIAL_MSM_SMD=y +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set + +# +# Diag Support +# +CONFIG_DIAG_CHAR=y + +# +# DIAG traffic over USB +# +CONFIG_DIAG_OVER_USB=y + +# +# HSIC/SMUX support for DIAG +# +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_ATMEL is not set +# CONFIG_HW_RANDOM_EXYNOS is not set +CONFIG_HW_RANDOM_MSM=y +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_MSM_SMD_PKT=y +CONFIG_MSM_ADSPRPC=y +# CONFIG_MSM_RDBG is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EG20T is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_INTEL_MID is not set +# CONFIG_I2C_QUP is not set +CONFIG_I2C_MSM_V2=y +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SLIMBUS=y +# CONFIG_SLIMBUS_MSM_CTRL is not set +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_TOPCLIFF_PCH is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +CONFIG_SPI_QUP=y +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB=y +CONFIG_MSM_QPNP_INT=y + +# +# Qualcomm MSM SSBI bus support +# +# CONFIG_SSBI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +# CONFIG_PTP_1588_CLOCK_PCH is not set +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_USE_PINCTRL_IRQ=y +CONFIG_PINCTRL_MSM_TLMM=y +# CONFIG_PINCTRL_EXYNOS is not set +# CONFIG_PINCTRL_EXYNOS5440 is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_MSM_V3 is not set +# CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_GRGPIO is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_GPIO_QPNP_PIN=y +# CONFIG_GPIO_QPNP_PIN_DEBUG is not set + +# +# USB GPIO expanders: +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_SMB137C_CHARGER is not set +# CONFIG_SMB349_USB_CHARGER is not set +# CONFIG_SMB349_DUAL_CHARGER is not set +# CONFIG_SMB1351_USB_CHARGER is not set +# CONFIG_SMB350_CHARGER is not set +# CONFIG_SMB135X_CHARGER is not set +# CONFIG_SMB1360_CHARGER_FG is not set +# CONFIG_SMB358_CHARGER is not set +# CONFIG_BATTERY_BQ28400 is not set +# CONFIG_QPNP_CHARGER is not set +CONFIG_QPNP_SMBCHARGER=y +CONFIG_SET_PMI8994_RESET_TYPE=y +CONFIG_QPNP_FG=y +CONFIG_BATTERY_BCL=y +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_QPNP_VM_BMS is not set +# CONFIG_QPNP_BMS is not set +# CONFIG_QPNP_LINEAR_CHARGER is not set +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_GPIO is not set +CONFIG_POWER_RESET_MSM=y +CONFIG_MSM_DLOAD_MODE=y +# CONFIG_POWER_AVS is not set +# CONFIG_POWER_AVS_MSM is not set +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_IDLE_STATS=y +CONFIG_MSM_IDLE_STATS_FIRST_BUCKET=62500 +CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT=2 +CONFIG_MSM_IDLE_STATS_BUCKET_COUNT=10 +CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET=1000000000 +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_BOOST_DYNAMIC_CONTROLLER is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_EPM_ADC is not set +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +# CONFIG_SENSORS_QPNP_ADC_CURRENT is not set +# CONFIG_SENSORS_QPNP_CURRENT_MONITOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_CPU_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +CONFIG_THERMAL_TSENS8974=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_THERMAL_MONITOR=y +# CONFIG_SUPPLY_LM_MONITOR is not set +CONFIG_THERMAL_QPNP=y +CONFIG_THERMAL_QPNP_ADC_TM=y +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_WCD9304_CODEC is not set +# CONFIG_WCD9310_CODEC is not set +# CONFIG_WCD9320_CODEC is not set +# CONFIG_WCD9306_CODEC is not set +CONFIG_WCD9330_CODEC=y +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_REGULATOR_PROXY_CONSUMER=y +# CONFIG_REGULATOR_GPIO is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_MEM_ACC=y +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_ONSEMI_NCP6335D is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS6524X is not set +CONFIG_REGULATOR_TPS65132=y +CONFIG_REGULATOR_STUB=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR=y +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +CONFIG_MEDIA_RADIO_SUPPORT=y +# CONFIG_MEDIA_RC_SUPPORT is not set +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_VIDEOBUF2_DMA_SG=y +CONFIG_VIDEOBUF2_MSM_MEM=y +# CONFIG_VIDEO_V4L2_INT_DEVICE is not set +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_USB_SN9C102 is not set + +# +# Webcam, TV (analog/digital) USB devices +# +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_MEDIA_PCI_SUPPORT is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set + +# +# Qualcomm MSM Camera And Video +# +# CONFIG_MSM_CAMERA is not set +CONFIG_MSMB_CAMERA=y +# CONFIG_MSMB_CAMERA_DEBUG is not set +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +# CONFIG_MSM_CSI20_HEADER is not set +# CONFIG_MSM_CSI22_HEADER is not set +CONFIG_MSM_CSI30_HEADER=y +# CONFIG_MSM_CSI31_HEADER is not set +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +# CONFIG_MSM_ISPIF_V1 is not set +# CONFIG_IMX134 is not set +# CONFIG_IMX132 is not set +# CONFIG_OV9724 is not set +CONFIG_HI256=y +# CONFIG_OV5648 is not set +CONFIG_MT9M114=y +# CONFIG_OV5645 is not set +# CONFIG_OV7695 is not set +# CONFIG_SP1628 is not set +# CONFIG_GC0339 is not set +# CONFIG_GC0310 is not set +# CONFIG_OV8825 is not set +# CONFIG_OV8865 is not set +# CONFIG_s5k4e1 is not set +# CONFIG_OV12830 is not set +CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_VIDC_V4L2=y +# CONFIG_MSM_VIDC_VMEM is not set +# CONFIG_MSM_WFD is not set +# CONFIG_TSPP is not set +# CONFIG_CI_BRIDGE_SPI is not set +# CONFIG_MSM_VPU is not set + +# +# Supported MMC/SDIO adapters +# +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_SHARK is not set +# CONFIG_RADIO_SHARK2 is not set +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_USB_KEENE is not set +# CONFIG_USB_MA901 is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +# CONFIG_RADIO_WL1273 is not set + +# +# Texas Instruments WL128x FM driver (ST based) +# +# CONFIG_RADIO_WL128X is not set +# CONFIG_RADIO_IRIS is not set +CONFIG_RADIO_SILABS=y +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y + +# +# Audio decoders, processors and mixers +# + +# +# RDS decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# Video encoders +# + +# +# Camera sensor devices +# + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Miscelaneous helper chips +# + +# +# Sensors used on soc_camera driver +# +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MC44S803=y + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_DRM is not set +CONFIG_MSM_KGSL=y +# CONFIG_MSM_KGSL_CFF_DUMP is not set +CONFIG_MSM_ADRENO_DEFAULT_GOVERNOR="msm-adreno-tz" +CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_MSM_VIDC_CONTENT_PROTECTION is not set +CONFIG_FB_MSM=y +CONFIG_FB_MSM_BACKLIGHT=y +# CONFIG_FB_MSM_LCDC_HW is not set +# CONFIG_FB_MSM_TRIPLE_BUFFER is not set +# CONFIG_FB_MSM_MDP_HW is not set +CONFIG_FB_MSM_MDSS_COMMON=y +# CONFIG_FB_MSM_MDP22 is not set +# CONFIG_FB_MSM_MDP30 is not set +# CONFIG_FB_MSM_MDP31 is not set +# CONFIG_FB_MSM_MDP40 is not set +CONFIG_FB_MSM_MDSS=y +# CONFIG_FB_MSM_MDP_NONE is not set +# CONFIG_FB_MSM_MDDI is not set +# CONFIG_FB_MSM_MIPI_DSI is not set +# CONFIG_FB_MSM_EXTMDDI is not set +# CONFIG_FB_MSM_MDDI_AUTO_DETECT is not set +# CONFIG_FB_MSM_LCDC_AUTO_DETECT is not set +CONFIG_FB_MSM_LVDS_CHIMEI_WXGA_PANEL=y +# CONFIG_FB_MSM_LVDS_FRC_FHD_PANEL is not set +# CONFIG_FB_MSM_MIPI_PANEL_DETECT is not set +# CONFIG_FB_MSM_MDDI_PANEL_AUTO_DETECT is not set +# CONFIG_FB_MSM_LCDC_PANEL_AUTO_DETECT is not set +# CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT is not set +# CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT is not set +# CONFIG_FB_MSM_MDDI_TOSHIBA_VGA is not set +# CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA_PANEL is not set +# CONFIG_FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_ORISE_VIDEO_720P_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_ORISE_CMD_720P_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_CHIMEI_WXGA_PANEL is not set +# CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA_PANEL is not set +# CONFIG_FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_NT35510_CMD_WVGA_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_NT35516_VIDEO_QHD_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_NT35516_CMD_QHD_PT_PANEL is not set +# CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO_PANEL is not set +# CONFIG_FB_MSM_PANEL_NONE is not set +# CONFIG_FB_MSM_HDMI_COMMON is not set +# CONFIG_FB_MSM_HDMI_3D is not set +# CONFIG_FB_MSM_EBI2_PANEL_DETECT is not set +# CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL is not set +# CONFIG_FB_MSM_QPIC_PANEL_DETECT is not set +CONFIG_FB_MSM_MDSS_WRITEBACK=y +# CONFIG_FB_MSM_MDSS_HDMI_PANEL is not set +# CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS is not set +# CONFIG_FB_MSM_MDSS_EDP_PANEL is not set +# CONFIG_FB_MSM_MDSS_MDP3 is not set +# CONFIG_FB_MSM_MDSS_XLOG_DEBUG is not set +CONFIG_FB_MSM_MDSS_KCAL_CTRL=y +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_ADF is not set +# CONFIG_LOGO is not set +# CONFIG_FB_SSD1307 is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_SOC=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# MSM SoC Audio support +# +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +# CONFIG_SND_SOC_QDSP6 is not set +CONFIG_SND_SOC_QDSP6V2=y +# CONFIG_AUDIO_OCMEM is not set +# CONFIG_DOLBY_DAP is not set +CONFIG_DTS_EAGLE=y +CONFIG_DOLBY_DS2=y +CONFIG_DTS_SRS_TM=y +CONFIG_QTI_PP=y +CONFIG_SND_SOC_CPE=y +CONFIG_SND_SOC_MSM8994=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_WCD9330=y +CONFIG_SND_SOC_WCD9XXX=y +CONFIG_SND_SOC_WCD_CPE=y +CONFIG_SND_SOC_MSM_STUB=y +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y +# CONFIG_SND_SIMPLE_CARD is not set +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HIDRAW is not set +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +CONFIG_HID_ELECOM=y +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO_TPKBD is not set +# CONFIG_HID_LOGITECH is not set +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_PS3REMOTE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# I2C HID support +# +# CONFIG_I2C_HID is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +# CONFIG_USB_XHCI_MSM_HSIC is not set +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_EHSET=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_MSM=y +# CONFIG_USB_EHCI_MSM_HSIC is not set +# CONFIG_USB_EHCI_MSM_UICC is not set +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_ICE40_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set +CONFIG_USB_CCID_BRIDGE=y + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +# CONFIG_USB_STORAGE_ENE_UB6250 is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_HOST is not set +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_DUAL_ROLE=y +# CONFIG_USB_DWC3_DEBUG is not set +# CONFIG_USB_CHIPIDEA is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_ZTE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +CONFIG_USB_SERIAL_CSVT=y +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +CONFIG_USB_EHSET_TEST_FIXTURE=y +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_QCOM_DIAG_BRIDGE is not set +# CONFIG_USB_QCOM_MDM_BRIDGE is not set +# CONFIG_USB_QCOM_KS_BRIDGE is not set +# CONFIG_USB_QCOM_IPC_BRIDGE is not set +CONFIG_USB_PHY=y +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_OMAP_CONTROL_USB is not set +# CONFIG_OMAP_USB3 is not set +# CONFIG_SAMSUNG_USBPHY is not set +# CONFIG_SAMSUNG_USB2PHY is not set +# CONFIG_SAMSUNG_USB3PHY is not set +# CONFIG_USB_MSM_OTG_72K is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +CONFIG_USB_MSM_OTG=y +# CONFIG_USB_MSM_ACA is not set +CONFIG_USB_MSM_HSPHY=y +CONFIG_USB_MSM_SSPHY=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +# CONFIG_USB_RCAR_PHY is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_AMD5536UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_USB_GOKU is not set +# CONFIG_USB_EG20T is not set +CONFIG_USB_CI13XXX_MSM=y +# CONFIG_USB_CI13XXX_MSM_HSIC is not set +CONFIG_USB_DWC3_MSM=y +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_F_SERIAL=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set +CONFIG_USB_CSW_HACK=y +# CONFIG_USB_MSC_PROFILING is not set +CONFIG_MODEM_SUPPORT=y +CONFIG_RMNET_SMD_CTL_CHANNEL="" +CONFIG_RMNET_SMD_DATA_CHANNEL="" +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_CLKGATE=y +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH=y +CONFIG_LEDS_QPNP_WLED=y +# CONFIG_LEDS_MSM_GPIO_FLASH is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_OT200 is not set +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_AW2013 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +# CONFIG_LEDS_TRIGGER_CPU is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +CONFIG_SWITCH=y +# CONFIG_SWITCH_GPIO is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_DS2404 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set +CONFIG_RTC_DRV_QPNP=y + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_ESOC is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_AMBA_PL08X is not set +CONFIG_QCOM_SPS_DMA=y +# CONFIG_TIMB_DMA is not set +# CONFIG_PL330_DMA is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=y +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_PCI_GENERIC is not set +# CONFIG_UIO_NETX is not set +CONFIG_UIO_MSM_SHAREDMEM=y +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_ET131X is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_R8712U is not set +# CONFIG_RTS5139 is not set +# CONFIG_TRANZPORT is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_DX_SEP is not set +CONFIG_ZSMALLOC=y +CONFIG_ZRAM=y +# CONFIG_ZRAM_DEBUG is not set +# CONFIG_FB_SM7XX is not set +# CONFIG_CRYSTALHD is not set +# CONFIG_FB_XGI is not set +# CONFIG_BCM_WIMAX is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +# CONFIG_ANDROID_BINDER_IPC_32BIT is not set +CONFIG_ASHMEM=y +CONFIG_ANDROID_LOGGER=y +CONFIG_LOGCAT_SIZE=256 +CONFIG_ANDROID_TIMED_OUTPUT=y +# CONFIG_ANDROID_TIMED_GPIO is not set +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y +CONFIG_ANDROID_INTF_ALARM_DEV=y +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +# CONFIG_SW_SYNC_USER is not set +CONFIG_ONESHOT_SYNC=y +# CONFIG_ONESHOT_SYNC_USER is not set +CONFIG_ION=y +# CONFIG_ION_TEST is not set +CONFIG_ION_MSM=y +# CONFIG_ALLOC_BUFFERS_IN_4K_CHUNKS is not set +# CONFIG_FIQ_DEBUGGER is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_USB_WPAN_HCD is not set +# CONFIG_WIMAX_GDM72XX is not set +CONFIG_NET_VENDOR_SILICOM=y +# CONFIG_CED1401 is not set +# CONFIG_DGRP is not set + +# +# Qualcomm Atheros CLD WLAN module +# +CONFIG_QCA_CLD_WLAN=y +CONFIG_QCACLD_WLAN_LFR3=y +CONFIG_PRIMA_WLAN_OKC=y +CONFIG_PRIMA_WLAN_11AC_HIGH_TP=y +CONFIG_WLAN_FEATURE_11W=y +CONFIG_WLAN_FEATURE_LPSS=y +CONFIG_QCOM_VOWIFI_11R=y +CONFIG_FEATURE_NAN=y +CONFIG_QCOM_TDLS=y +CONFIG_QCOM_LTE_COEX=y + +# +# Qualcomm MSM specific device drivers +# +# CONFIG_MSM_SSBI is not set +CONFIG_SPS=y +CONFIG_USB_BAM=y +# CONFIG_SPS_SUPPORT_BAMDMA is not set +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QPNP_POWER_ON=y +# CONFIG_QPNP_CLKDIV is not set +# CONFIG_QPNP_VIBRATOR is not set +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_QPNP_USB_DETECT=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +# CONFIG_KLM is not set +CONFIG_MSM_AVTIMER=y +# CONFIG_SSM is not set +# CONFIG_MSM_MHI is not set +# CONFIG_QCA1530 is not set +CONFIG_PFT=y +# CONFIG_MSM_SPSS is not set +CONFIG_MSM_BUS_SCALING=y +# CONFIG_MSM_BUSPM_DEV is not set +CONFIG_BUS_TOPOLOGY_ADHOC=y +# CONFIG_DEBUG_BUS_VOTER is not set +# CONFIG_I2C_MSM_PROF_DBG is not set +# CONFIG_MSM_UIM_HSL is not set +CONFIG_QPNP_HAPTIC=y +CONFIG_SEEMP_CORE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +# CONFIG_MSM_CLK_CONTROLLER_V2 is not set +CONFIG_MSM_MDSS_PLL=y +CONFIG_HWSPINLOCK=y + +# +# Hardware Spinlock drivers +# +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_CLKSRC_OF=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y +CONFIG_OF_IOMMU=y +CONFIG_MSM_IOMMU=y +CONFIG_MSM_IOMMU_V1=y +# CONFIG_IOMMU_LPAE is not set +CONFIG_MSM_IOMMU_VBIF_CHECK=y +# CONFIG_IOMMU_NON_SECURE is not set +# CONFIG_IOMMU_FORCE_4K_MAPPINGS is not set +# CONFIG_MSM_IOMMU_TLBINVAL_ON_MAP is not set +# CONFIG_MMU500_ACTIVE_PREFETCH_BUG_WITH_SECTION_MAPPING is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_CPUFREQ=y +CONFIG_DEVFREQ_GOV_MSM_ADRENO_TZ=y +CONFIG_MSM_BIMC_BWMON=y +CONFIG_DEVFREQ_GOV_MSM_GPUBW_MON=y +CONFIG_DEVFREQ_GOV_MSM_BW_HWMON=y +# CONFIG_DEVFREQ_GOV_MSM_CACHE_HWMON is not set +CONFIG_DEVFREQ_GOV_SPDM_HYP=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_SIMPLE_DEV=y +CONFIG_MSM_DEVFREQ_DEVBW=y +# CONFIG_SPDM_SCM is not set +CONFIG_DEVFREQ_SPDM=y +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_MSM_SHOW_RESUME_IRQ=y +CONFIG_MSM_IRQ=y +# CONFIG_IPACK_BUS is not set +CONFIG_MOBICORE_SUPPORT=y +# CONFIG_MOBICORE_DEBUG is not set +CONFIG_MOBICORE_API=y +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_CORESIGHT is not set +# CONFIG_BIF is not set +# CONFIG_SENSORS is not set +CONFIG_SENSORS_SSC=y + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_PHY_MSM_SATA is not set +# CONFIG_CP_ACCESS64 is not set +# CONFIG_MSM_BAM_DMUX is not set +CONFIG_MSM_EVENT_TIMER=y +# CONFIG_MSM_GLINK is not set +# CONFIG_MSM_GLINK_LOOPBACK_SERVER is not set +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +# CONFIG_MSM_JTAG is not set +# CONFIG_MSM_JTAG_MM is not set +# CONFIG_MSM_JTAGV8 is not set +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_SMD=y +CONFIG_MSM_SMD_DEBUG=y +CONFIG_MSM_MPM_OF=y +CONFIG_MSM_RPM_SMD=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_SMEM=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_MSM_QDSP6_APRV2=y +# CONFIG_MSM_QDSP6_APRV3 is not set +CONFIG_MSM_ADSP_LOADER=y +# CONFIG_MSM_MEMORY_DUMP is not set +CONFIG_MSM_MEMORY_DUMP_V2=y +# CONFIG_MSM_DEBUG_LAR_UNLOCK is not set +# CONFIG_MSM_DDR_HEALTH is not set +# CONFIG_MSM_COMMON_LOG is not set +CONFIG_MSM_WATCHDOG_V2=y +# CONFIG_MSM_FORCE_WDOG_BITE_ON_PANIC is not set +CONFIG_MSM_HVC=y +# CONFIG_MSM_HYP_DEBUG is not set +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_MSM_OCMEM=y +CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y +# CONFIG_MSM_OCMEM_DEBUG is not set +# CONFIG_MSM_OCMEM_POWER_DISABLE is not set +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_SCM=y +# CONFIG_MAXIMUM_CURRENT_THROTTLING is not set +CONFIG_MSM_CPU_PWR_CTL=y +# CONFIG_MSM_XPU_ERR_FATAL is not set +# CONFIG_MSM_CACHE_DUMP is not set +# CONFIG_MSM_CPUSS_DUMP is not set +CONFIG_MSM_SHARED_HEAP_ACCESS=y +CONFIG_MSM_SYSTEM_HEALTH_MONITOR=y +CONFIG_QCOM_EARLY_RANDOM=y +# CONFIG_MSM_PACMAN is not set +CONFIG_MSM_CORE_CTL_HELPER=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_QCOM_NPA_DUMP=y +CONFIG_KERNEL_TEXT_MPU_PROT=y +# CONFIG_MEM_SHARE_QMI_SERVICE is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_MSM_TZ_LOG is not set +CONFIG_PARAM_READ_WRITE=y +CONFIG_OEM_TRACE_SUPORT=y +CONFIG_OEM_FORCE_DUMP=y + +# +# Firmware Drivers +# + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +CONFIG_F2FS_FS_SECURITY=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set +CONFIG_EXFAT_FS=y +# CONFIG_EXFAT_VIRTUAL_XATTR is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_VIRTUALIZATION is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SYSRQ_SCHED_DEBUG=y +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_HAVE_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU_DELAY is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_CPU_STALL_VERBOSE=y +# CONFIG_RCU_CPU_STALL_INFO is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_MSM_RTB is not set +CONFIG_IPC_LOGGING=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_PROBE_EVENTS is not set +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_DYNAMIC_DEBUG is not set +CONFIG_OOPS_LOG_BUFFER=y +CONFIG_LOG_BUF_MAGIC=y +CONFIG_OOPS_LOG_BUF_SHIFT=14 +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_PANIC_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM64_PTDUMP is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_FORCE_PAGES is not set +# CONFIG_FREE_PAGES_RDONLY is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_PATH is not set +CONFIG_SECURITY_PFT=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_SECURITY_SELINUX=y +# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set +# CONFIG_SECURITY_SELINUX_DISABLE is not set +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_YAMA is not set +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_SELINUX=y +# CONFIG_DEFAULT_SECURITY_PFT is not set +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_DEFAULT_SECURITY="selinux" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_ABLK_HELPER=y + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_SEQIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +CONFIG_CRYPTO_XTS=y + +# +# Hash modes +# +# CONFIG_CRYPTO_CMAC is not set +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=y +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_QCE50=y +# CONFIG_FIPS_ENABLE is not set +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +# CONFIG_CRYPTO_DEV_OTA_CRYPTO is not set +CONFIG_CRYPTO_DEV_QCOM_ICE=y +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_LIBFDT=y +CONFIG_QMI_ENCDEC=y +# CONFIG_QMI_ENCDEC_DEBUG is not set +# CONFIG_STRICT_MEMORY_RWX is not set diff --git a/arch/arm64/configs/msm8994-OnePlus2-perf_defconfig b/arch/arm64/configs/msm8994-OnePlus2-perf_defconfig new file mode 100644 index 0000000000000..b4c6da05a30e9 --- /dev/null +++ b/arch/arm64/configs/msm8994-OnePlus2-perf_defconfig @@ -0,0 +1,632 @@ +CONFIG_LOCALVERSION="-perf" +CONFIG_ZRAM=y +CONFIG_ZSMALLOC=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_AUDIT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +#ifdef VENDOR_EDIT +# CONFIG_IKCONFIG_PROC is not set +#endif +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_HMP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_MSM=y +CONFIG_ARCH_MSM8994=y +CONFIG_ARCH_MSM8994_V1_TLBI_WA=y +CONFIG_PCI_MSM=y +CONFIG_ARM64_A57_ERRATA_832075=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_PREEMPT=y +CONFIG_ARMV7_COMPAT=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM_OPP=y +CONFIG_SUSPEND_TIME=y +CONFIG_CPU_FREQ=y +CONFIG_SCHED_FREQ_INPUT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_BOOST=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +CONFIG_NF_NAT_IPV4=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_CLS_ACT=y +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +#CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_RFKILL=y +CONFIG_NFC_QNCI=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_CMA=y +CONFIG_ARM_CCI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_QSEECOM=y +CONFIG_TI_DRV2667=y +#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support +CONFIG_TI_DRV2605=y +#endif VENDOR_EDIT +CONFIG_QCOM_LIQUID_DOCK=y +CONFIG_SCSI=y +CONFIG_SCSI_TGT=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_TEST=m +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_RNDIS_IPA=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_MPPE=y +CONFIG_PPPOE=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_USBNET=y +CONFIG_CNSS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CNSS_MAC_BUG=y +CONFIG_CLD_LL_CORE=y +CONFIG_ATH_CARDS=y +CONFIG_WIL6210=m +CONFIG_E1000E=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SECURE_TOUCH=y +#ifdef VENDOR_EDIT /* LiuPing@Phone.BSP.Sensor,2014/10/11, add for TP. */ +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y +#CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS=y +#CONFIG_TOUCHSCREEN_GEN_VKEYS=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI=y +#endif VENDOR_EDIT /*VENDOR_EDIT*/ +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=m +# CONFIG_SERIO_I8042 is not set +# CONFIG_VT is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_HSL=y +CONFIG_SERIAL_MSM_HSL_CONSOLE=y +CONFIG_SERIAL_MSM_SMD=y +CONFIG_DIAG_CHAR=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_MSM_SMD_PKT=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_DMADEVICES=y +CONFIG_HAS_DMA=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB=y +CONFIG_MSM_QPNP_INT=y +CONFIG_USE_PINCTRL_IRQ=y +CONFIG_PINCTRL_MSM_TLMM=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_QPNP_PIN=y +#ifdef VENDOR_EDIT +#CONFIG_SMB135X_CHARGER is not set +#CONFIG_SMB349_DUAL_CHARGER is not set +#endif +CONFIG_QPNP_SMBCHARGER=y +CONFIG_QPNP_FG=y +CONFIG_BATTERY_BCL=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_POWER_RESET_MSM=y +CONFIG_MSM_DLOAD_MODE=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_THERMAL=y +CONFIG_THERMAL_TSENS8974=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_QPNP=y +CONFIG_THERMAL_QPNP_ADC_TM=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_WCD9330_CODEC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_PROXY_CONSUMER=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_TPS65132=y +CONFIG_REGULATOR_STUB=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEOBUF2_MSM_MEM=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_MSMB_CAMERA=y +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +CONFIG_HI256=y +CONFIG_MT9M114=y +CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_VIDC_V4L2=y +CONFIG_RADIO_SILABS=y +CONFIG_MSM_KGSL=y +CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +# CONFIG_FB_MSM_MDSS_HDMI_PANEL is not set +#CONFIG_FB_MSM_MDSS_MHL3=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_MSM8994=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_EHSET=y +CONFIG_USB_EHCI_MSM=y +CONFIG_USB_ACM=y +CONFIG_USB_CCID_BRIDGE=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CSVT=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_PHY=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_CI13XXX_MSM=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_G_ANDROID=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=m +CONFIG_MMC_BLOCK_TEST=m +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_SWITCH=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_UIO=y +CONFIG_UIO_MSM_SHAREDMEM=y +CONFIG_STAGING=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_LOGGER=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ANDROID_INTF_ALARM_DEV=y +CONFIG_ONESHOT_SYNC=y +CONFIG_ION=y +CONFIG_ION_MSM=y +CONFIG_SPS=y +CONFIG_USB_BAM=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QPNP_POWER_ON=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_QPNP_USB_DETECT=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +CONFIG_MSM_AVTIMER=y +CONFIG_PFT=y +CONFIG_MSM_BUS_SCALING=y +CONFIG_BUS_TOPOLOGY_ADHOC=y +#CONFIG_DEBUG_BUS_VOTER=y +CONFIG_MSM_BUSPM_DEV=m +#ifdef VENDOR_EDIT +#// shankai@bsp, 2015-4-4 do not use it ,comment it. +# shankai@bsp ,2015-5-28 now we use it +CONFIG_QPNP_HAPTIC=y +#endif VENDOR_EDIT +CONFIG_SEEMP_CORE=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_IOMMU_VBIF_CHECK=y +CONFIG_MSM_IOMMU_V1=y +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +#CONFIG_CORESIGHT=y +#CONFIG_CORESIGHT_EVENT=y +#CONFIG_CORESIGHT_FUSE=y +CONFIG_CORESIGHT_CTI=y +#CONFIG_CORESIGHT_CTI_SAVE_DISABLE=y +#CONFIG_CORESIGHT_TMC=y +#CONFIG_CORESIGHT_TPIU=y +#CONFIG_CORESIGHT_FUNNEL=y +#CONFIG_CORESIGHT_REPLICATOR=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +#CONFIG_CORESIGHT_STM=y +#CONFIG_CORESIGHT_HWEVENT=y +CONFIG_SENSORS_SSC=y +CONFIG_GENERIC_PHY=y +CONFIG_MSM_EVENT_TIMER=y +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_SMD=y +CONFIG_MSM_SMD_DEBUG=y +CONFIG_MSM_RPM_SMD=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_SMEM=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_MSM_MEMORY_DUMP_V2=y +CONFIG_MSM_WATCHDOG_V2=y +CONFIG_MSM_HVC=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_MSM_OCMEM=y +CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_SCM=y +CONFIG_MSM_SHARED_HEAP_ACCESS=y +CONFIG_MSM_SYSTEM_HEALTH_MONITOR=y +CONFIG_QCOM_EARLY_RANDOM=y + +#ifdef VENDOR_EDIT +# hefaxi@filesystem,2015/05/05,support param partion read/write +CONFIG_PARAM_READ_WRITE=y +#endif + +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y + +#ifdef VENDOR_EDIT +# hefaxi@filesystem, 2105/04/17, Add for support ntfs and exfat +CONFIG_EXFAT_FS=y +CONFIG_NTFS_FS=y +#endif /* VENDOR_EDIT */ + +CONFIG_TMPFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +CONFIG_IPC_LOGGING=y +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +CONFIG_OOPS_LOG_BUFFER=y +CONFIG_LOG_BUF_MAGIC=y +CONFIG_OOPS_LOG_BUF_SHIFT=14 +CONFIG_KEYS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_PFT=y +CONFIG_SECURITY_NETWORK=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_SOCKEV_NLMCAST=y +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_QMI_ENCDEC=y +CONFIG_MOBICORE_SUPPORT=m +CONFIG_MOBICORE_API=m + +#ifdef VENDOR_EDIT // disable by xcb for ramoops 2015-03-31 +# CONFIG_STRICT_MEMORY_RWX=y +#endif /* VENDOR_EDIT */ + +CONFIG_DEVFREQ_SPDM=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_CONSOLE_FLUSH_ON_HOTPLUG=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_QCOM_NPA_DUMP=y +CONFIG_KERNEL_TEXT_MPU_PROT=y +CONFIG_MSM_CORE_CTL_HELPER=y +#VENDOR_EDIT add for fpc1021 fingerprints +CONFIG_BTP_FPC1021=y +#add end +#//ifdef VENDOR_EDIT changhua 2015-02-28 add for tristate switch +CONFIG_TRI_STATE_KEY=y +##endif/*VENDOR_EDIT*/ +#//ifdef VENDOR_EDIT changhua 2015-03-12 add for switch antenna by apk for test +#CONFIG_SWITCH_ANTENNA=y +##endif/*VENDOR_EDIT*/ +#//ifdef VENDOR_EDIT changhua 2015-02-12 add for switch Theme by rare cover +CONFIG_SWITCH_THEME=y +##endif/*VENDOR_EDIT*/ + +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y +#ifdef VENDOR_EDIT /*del by jiachenghui for boot time optimize,2015/5/19*/ +#PSTORE_FTRACE=y + +CONFIG_DEBUG_FS=y +#CONFIG_FUNCTION_TRACER=y +#endif VENDOR_EDIT /*VENDOR_EDIT*/ +#endif /* VENDOR_EDIT */ + +#add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +CONFIG_OEM_DEBUG_SUPORT=y +CONFIG_OEM_TRACE_SUPORT=y +#endif /*VENDOR_EDIT*/ +#end add by jiachenghui for support oem trace,2015/05/09 + +#add by yangrujin to fix handset die but no dump port in aging test,2015/07/20 +#ifdef VENDOR_EDIT +CONFIG_SET_PMI8994_RESET_TYPE=y +#endif /*VENDOR_EDIT*/ +#end add by yangrujin end. diff --git a/arch/arm64/configs/msm8994-OnePlus2_defconfig b/arch/arm64/configs/msm8994-OnePlus2_defconfig new file mode 100755 index 0000000000000..0f737654d39f8 --- /dev/null +++ b/arch/arm64/configs/msm8994-OnePlus2_defconfig @@ -0,0 +1,702 @@ +CONFIG_ZRAM=y +CONFIG_ZSMALLOC=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_AUDIT=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +#ifdef VENDOR_EDIT +# CONFIG_IKCONFIG_PROC is not set +#endif +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_HMP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_MSM=y +CONFIG_ARCH_MSM8994=y +CONFIG_ARCH_MSM8994_V1_TLBI_WA=y +CONFIG_MSM8994_V1_PMUIRQ_WA=y +CONFIG_ARCH_MSM8992=y +CONFIG_PCI_MSM=y +CONFIG_ARM64_A57_ERRATA_832075=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_ARCH_WANTS_CTXSW_LOGGING=y +CONFIG_PREEMPT=y +CONFIG_ARMV7_COMPAT=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +CONFIG_PM_RUNTIME=y +CONFIG_PM_OPP=y +CONFIG_SUSPEND_TIME=y +CONFIG_CPU_FREQ=y +CONFIG_SCHED_FREQ_INPUT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_BOOST=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +CONFIG_NF_NAT_IPV4=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_CLS_ACT=y +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_MSM_BT_POWER=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_RFKILL=y +CONFIG_NFC_QNCI=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_CMA=y +CONFIG_ARM_CCI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_UID_STAT=y +CONFIG_QSEECOM=y +CONFIG_TI_DRV2667=y +#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support +CONFIG_TI_DRV2605=y +#endif VENDOR_EDIT +CONFIG_QCOM_LIQUID_DOCK=y +CONFIG_SCSI=y +CONFIG_SCSI_TGT=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_TEST=m +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_KS8851=y +CONFIG_RNDIS_IPA=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_USB_USBNET=y +CONFIG_CNSS=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CNSS_MAC_BUG=y +CONFIG_CLD_LL_CORE=y +CONFIG_ATH_CARDS=y +CONFIG_WIL6210=m +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_R8169=y +CONFIG_E1000E=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_KEYBOARD_GPIO=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SECURE_TOUCH=y +#ifdef VENDOR_EDIT /* LiuPing@Phone.BSP.Sensor,2014/10/11, add for TP. */ +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y +#CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS=y +#CONFIG_TOUCHSCREEN_GEN_VKEYS=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y +#CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI=y +CONFIG_TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI=y +#endif VENDOR_EDIT /*VENDOR_EDIT*/ +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=m +# CONFIG_SERIO_I8042 is not set +# CONFIG_VT is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_HSL=y +CONFIG_SERIAL_MSM_HSL_CONSOLE=y +CONFIG_SERIAL_MSM_SMD=y +CONFIG_DIAG_CHAR=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y +CONFIG_MSM_SMD_PKT=y +CONFIG_MSM_ADSPRPC=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_DMADEVICES=y +CONFIG_HAS_DMA=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPMI=y +CONFIG_SPMI_MSM_PMIC_ARB=y +CONFIG_MSM_QPNP_INT=y +CONFIG_USE_PINCTRL_IRQ=y +CONFIG_PINCTRL_MSM_TLMM=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_QPNP_PIN=y +#ifdef VENDOR_EDIT +#CONFIG_SMB135X_CHARGER is not set +#CONFIG_SMB349_DUAL_CHARGER is not set +#endif +CONFIG_QPNP_SMBCHARGER=y +CONFIG_QPNP_FG=y +CONFIG_BATTERY_BCL=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_POWER_RESET_MSM=y +CONFIG_MSM_DLOAD_MODE=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_SENSORS_EPM_ADC=y +CONFIG_THERMAL=y +CONFIG_THERMAL_TSENS8974=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_QPNP=y +CONFIG_THERMAL_QPNP_ADC_TM=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_WCD9330_CODEC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_PROXY_CONSUMER=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_TPS65132=y +CONFIG_REGULATOR_STUB=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEOBUF2_MSM_MEM=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_MSMB_CAMERA=y +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +CONFIG_HI256=y +CONFIG_MT9M114=y +CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_VIDC_V4L2=y +CONFIG_RADIO_SILABS=y +CONFIG_MSM_KGSL=y +CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +# CONFIG_FB_MSM_MDSS_HDMI_PANEL is not set +CONFIG_FB_MSM_MDSS_MHL3=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_MSM8994=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_EHSET=y +CONFIG_USB_EHCI_MSM=y +CONFIG_USB_ACM=y +CONFIG_USB_CCID_BRIDGE=y +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CSVT=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_PHY=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_CI13XXX_MSM=y +CONFIG_USB_DWC3_MSM=y +CONFIG_USB_G_ANDROID=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=m +CONFIG_MMC_BLOCK_TEST=m +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_SWITCH=y +CONFIG_EDAC=y +CONFIG_EDAC_MM_EDAC=y +CONFIG_EDAC_CORTEX_ARM64=y +CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_UE=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_UIO=y +CONFIG_UIO_MSM_SHAREDMEM=y +CONFIG_STAGING=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_LOGGER=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ANDROID_INTF_ALARM_DEV=y +CONFIG_ONESHOT_SYNC=y +CONFIG_ION=y +CONFIG_ION_MSM=y +CONFIG_SPS=y +CONFIG_USB_BAM=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_QPNP_POWER_ON=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_QPNP_USB_DETECT=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +CONFIG_MSM_AVTIMER=y +CONFIG_PFT=y +CONFIG_MSM_BUS_SCALING=y +CONFIG_MSM_BUSPM_DEV=m +CONFIG_BUS_TOPOLOGY_ADHOC=y +CONFIG_DEBUG_BUS_VOTER=y +#ifdef VENDOR_EDIT // shankai@bsp, 2015-4-4 do not use it ,comment it. +#// shankai@bsp, 2015-5-28 use it ,do not comment it. +CONFIG_QPNP_HAPTIC=y +#endif VENDOR_EDIT +CONFIG_SEEMP_CORE=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_IOMMU_VBIF_CHECK=y +CONFIG_MSM_IOMMU_V1=y +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_CORESIGHT_FUSE=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TMC=y +CONFIG_CORESIGHT_TPIU=y +CONFIG_CORESIGHT_FUNNEL=y +CONFIG_CORESIGHT_REPLICATOR=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_ETMV4=y +CONFIG_CORESIGHT_AUDIO_ETM=y +CONFIG_CORESIGHT_MODEM_ETM=y +CONFIG_CORESIGHT_WCN_ETM=y +CONFIG_CORESIGHT_RPM_ETM=y +CONFIG_SENSORS_SSC=y +CONFIG_GENERIC_PHY=y +CONFIG_CP_ACCESS64=y +CONFIG_MSM_EVENT_TIMER=y +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_SMD=y +CONFIG_MSM_SMD_DEBUG=y +CONFIG_MSM_RPM_SMD=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_SMEM=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_MSM_MEMORY_DUMP_V2=y +CONFIG_MSM_DEBUG_LAR_UNLOCK=y +CONFIG_MSM_DDR_HEALTH=y +CONFIG_MSM_COMMON_LOG=y +CONFIG_MSM_WATCHDOG_V2=y +CONFIG_MSM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_MSM_HVC=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_MSM_OCMEM=y +CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y +CONFIG_MSM_OCMEM_DEBUG=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_SCM=y +CONFIG_MSM_XPU_ERR_FATAL=y +CONFIG_MSM_CPUSS_DUMP=y +CONFIG_MSM_SHARED_HEAP_ACCESS=y +CONFIG_MSM_SYSTEM_HEALTH_MONITOR=y +CONFIG_QCOM_EARLY_RANDOM=y +CONFIG_MSM_TZ_LOG=y + +#ifdef VENDOR_EDIT +# hefaxi@filesystem,2015/05/05,support param partion read/write +CONFIG_PARAM_READ_WRITE=y +#endif + +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y + +#ifdef VENDOR_EDIT +# hefaxi@filesystem, 2105/04/17, Add for support ntfs and exfat +CONFIG_EXFAT_FS=y +CONFIG_NTFS_FS=y +#endif /* VENDOR_EDIT */ + +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PAGE_OWNER=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_PANIC_ON_RT_THROTTLING=y +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y +CONFIG_SLUB_DEBUG_ON=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 +CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_LIST=y +CONFIG_RCU_CPU_STALL_INFO=y +CONFIG_RCU_TRACE=y +CONFIG_FAULT_INJECTION=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_MSM_RTB=y +CONFIG_MSM_RTB_SEPARATE_CPUS=y +CONFIG_IPC_LOGGING=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_OOPS_LOG_BUFFER=y +CONFIG_LOG_BUF_MAGIC=y +CONFIG_OOPS_LOG_BUF_SHIFT=14 +CONFIG_PANIC_ON_DATA_CORRUPTION=y +CONFIG_ARM64_PTDUMP=y +CONFIG_PID_IN_CONTEXTIDR=y +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_KERNEL_TEXT_RDONLY=y +CONFIG_SECURITY=y +CONFIG_SECURITY_PFT=y +CONFIG_SECURITY_NETWORK=y +CONFIG_CRYPTO=y +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_SOCKEV_NLMCAST=y +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_QMI_ENCDEC=y +CONFIG_MOBICORE_SUPPORT=m +CONFIG_MOBICORE_API=m + +#ifdef VENDOR_EDIT // disable by xcb for ramoops 2015-03-31 +# CONFIG_STRICT_MEMORY_RWX=y +#endif /* VENDOR_EDIT */ + +CONFIG_DEVFREQ_SPDM=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_QCOM_NPA_DUMP=y +CONFIG_KERNEL_TEXT_MPU_PROT +CONFIG_MSM_CORE_CTL_HELPER=y +#ifdef VENDOR_EDIT //dts proc +CONFIG_PROC_DEVICETREE=y +#endif /* VENDOR_EDIT */ +#VENDOR_EDIT add for fpc1021 fingerprints +CONFIG_BTP_FPC1021=y +#add end +#//ifdef VENDOR_EDIT changhua 2015-02-28 add for tristate switch +CONFIG_TRI_STATE_KEY=y +##endif/*VENDOR_EDIT*/ +#//ifdef VENDOR_EDIT changhua 2015-03-12 add for switch antenna by apk for test +#CONFIG_SWITCH_ANTENNA=y +##endif/*VENDOR_EDIT*/ +#//ifdef VENDOR_EDIT changhua 2015-02-12 add for switch Theme by rare cover +CONFIG_SWITCH_THEME=y +##endif/*VENDOR_EDIT*/ + +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y +PSTORE_FTRACE=y + +CONFIG_DEBUG_FS=y +CONFIG_FUNCTION_TRACER=y +#endif /* VENDOR_EDIT */ + +#add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +CONFIG_OEM_DEBUG_SUPORT=y +CONFIG_OEM_TRACE_SUPORT=y +#endif /*VENDOR_EDIT*/ +#end add by jiachenghui for support oem trace,2015/05/09 + +#add by yangrujin to fix handset die but no dump port in aging test,2015/07/20 +#ifdef VENDOR_EDIT +CONFIG_SET_PMI8994_RESET_TYPE=y +#endif /*VENDOR_EDIT*/ +#end add by yangrujin end. diff --git a/arch/arm64/configs/msm8994-perf_defconfig b/arch/arm64/configs/msm8994-perf_defconfig old mode 100644 new mode 100755 diff --git a/arch/arm64/configs/msm8994_defconfig b/arch/arm64/configs/msm8994_defconfig old mode 100644 new mode 100755 diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h index 6913643bbe54e..7e4e129596418 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -71,11 +71,13 @@ struct user_pt_regs { __u64 pstate; }; +#if defined (__LP64__) struct user_fpsimd_state { __uint128_t vregs[32]; __u32 fpsr; __u32 fpcr; }; +#endif struct user_hwdebug_state { __u32 dbg_info; diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h index c731ca011ca3c..7681c82de50e5 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h @@ -47,12 +47,14 @@ struct _aarch64_ctx { #define FPSIMD_MAGIC 0x46508001 +#if defined (__LP64__) struct fpsimd_context { struct _aarch64_ctx head; __u32 fpsr; __u32 fpcr; __uint128_t vregs[32]; }; +#endif /* ESR_EL1 context */ #define ESR_MAGIC 0x45535201 diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c old mode 100644 new mode 100755 index 85c5235a70351..c2bfb887b7fb9 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -502,10 +502,11 @@ static int c_show(struct seq_file *m, void *v) seq_puts(m, "\n"); - if (!arch_read_hardware_id) +//default use machine_name which contain cpu version info +// if (!arch_read_hardware_id) seq_printf(m, "Hardware\t: %s\n", machine_name); - else - seq_printf(m, "Hardware\t: %s\n", arch_read_hardware_id()); +// else +// seq_printf(m, "Hardware\t: %s\n", arch_read_hardware_id()); return 0; } diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched index e35a11526feab..4662b793a534d 100644 --- a/block/Kconfig.iosched +++ b/block/Kconfig.iosched @@ -61,6 +61,35 @@ config CFQ_GROUP_IOSCHED ---help--- Enable group IO scheduling in CFQ. +config IOSCHED_FIOPS + tristate "IOPS based I/O scheduler" + default y + ---help--- + This is an IOPS based I/O scheduler. It will try to distribute + IOPS equally among all processes in the system. It's mainly for + Flash based storage. + +config IOSCHED_BFQ + tristate "BFQ I/O scheduler" + default n + ---help--- + The BFQ I/O scheduler tries to distribute bandwidth among + all processes according to their weights. + It aims at distributing the bandwidth as desired, independently of + the disk parameters and with any workload. It also tries to + guarantee low latency to interactive and soft real-time + applications. If compiled built-in (saying Y here), BFQ can + be configured to support hierarchical scheduling. + +config CGROUP_BFQIO + bool "BFQ hierarchical scheduling support" + depends on CGROUPS && IOSCHED_BFQ=y + default n + ---help--- + Enable hierarchical scheduling in BFQ, using the cgroups + filesystem interface. The name of the subsystem will be + bfqio. + choice prompt "Default I/O scheduler" default DEFAULT_CFQ @@ -84,6 +113,19 @@ choice config DEFAULT_CFQ bool "CFQ" if IOSCHED_CFQ=y + config DEFAULT_FIOPS + bool "FIOPS" if IOSCHED_FIOPS=y + + config DEFAULT_BFQ + bool "BFQ" if IOSCHED_BFQ=y + help + Selects BFQ as the default I/O scheduler which will be + used by default for all block devices. + The BFQ I/O scheduler aims at distributing the bandwidth + as desired, independently of the disk parameters and with + any workload. It also tries to guarantee low latency to + interactive and soft real-time applications. + config DEFAULT_NOOP bool "No-op" @@ -94,6 +136,8 @@ config DEFAULT_IOSCHED default "deadline" if DEFAULT_DEADLINE default "row" if DEFAULT_ROW default "cfq" if DEFAULT_CFQ + default "fiops" if DEFAULT_FIOPS + default "bfq" if DEFAULT_BFQ default "noop" if DEFAULT_NOOP endmenu diff --git a/block/Makefile b/block/Makefile index b5e663709b3f4..5a3db053735cd 100644 --- a/block/Makefile +++ b/block/Makefile @@ -17,6 +17,8 @@ obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o obj-$(CONFIG_IOSCHED_ROW) += row-iosched.o obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o obj-$(CONFIG_IOSCHED_TEST) += test-iosched.o +obj-$(CONFIG_IOSCHED_FIOPS) += fiops-iosched.o +obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c new file mode 100644 index 0000000000000..e4d7b8a96ebc0 --- /dev/null +++ b/block/bfq-cgroup.c @@ -0,0 +1,913 @@ +/* + * BFQ: CGROUPS support. + * + * Based on ideas and code from CFQ: + * Copyright (C) 2003 Jens Axboe + * + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * + * Copyright (C) 2010 Paolo Valente + * + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ + * file. + */ + +#ifdef CONFIG_CGROUP_BFQIO + +static DEFINE_MUTEX(bfqio_mutex); + +static bool bfqio_is_removed(struct cgroup *cgroup) +{ + return test_bit(CGRP_REMOVED, &cgroup->flags); +} + +static struct bfqio_cgroup bfqio_root_cgroup = { + .weight = BFQ_DEFAULT_GRP_WEIGHT, + .ioprio = BFQ_DEFAULT_GRP_IOPRIO, + .ioprio_class = BFQ_DEFAULT_GRP_CLASS, +}; + +static inline void bfq_init_entity(struct bfq_entity *entity, + struct bfq_group *bfqg) +{ + entity->weight = entity->new_weight; + entity->orig_weight = entity->new_weight; + entity->ioprio = entity->new_ioprio; + entity->ioprio_class = entity->new_ioprio_class; + entity->parent = bfqg->my_entity; + entity->sched_data = &bfqg->sched_data; +} + +static struct bfqio_cgroup *cgroup_to_bfqio(struct cgroup *cgroup) +{ + return container_of(cgroup_subsys_state(cgroup, bfqio_subsys_id), + struct bfqio_cgroup, css); +} + +/* + * Search the bfq_group for bfqd into the hash table (by now only a list) + * of bgrp. Must be called under rcu_read_lock(). + */ +static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, + struct bfq_data *bfqd) +{ + struct bfq_group *bfqg; + void *key; + + hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) { + key = rcu_dereference(bfqg->bfqd); + if (key == bfqd) + return bfqg; + } + + return NULL; +} + +static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, + struct bfq_group *bfqg) +{ + struct bfq_entity *entity = &bfqg->entity; + + /* + * If the weight of the entity has never been set via the sysfs + * interface, then bgrp->weight == 0. In this case we initialize + * the weight from the current ioprio value. Otherwise, the group + * weight, if set, has priority over the ioprio value. + */ + if (bgrp->weight == 0) { + entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); + entity->new_ioprio = bgrp->ioprio; + } else { + if (bgrp->weight < BFQ_MIN_WEIGHT || + bgrp->weight > BFQ_MAX_WEIGHT) { + printk(KERN_CRIT "bfq_group_init_entity: " + "bgrp->weight %d\n", bgrp->weight); + BUG(); + } + entity->new_weight = bgrp->weight; + entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); + } + entity->orig_weight = entity->weight = entity->new_weight; + entity->ioprio = entity->new_ioprio; + entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; + entity->my_sched_data = &bfqg->sched_data; + bfqg->active_entities = 0; +} + +static inline void bfq_group_set_parent(struct bfq_group *bfqg, + struct bfq_group *parent) +{ + struct bfq_entity *entity; + + BUG_ON(parent == NULL); + BUG_ON(bfqg == NULL); + + entity = &bfqg->entity; + entity->parent = parent->my_entity; + entity->sched_data = &parent->sched_data; +} + +/** + * bfq_group_chain_alloc - allocate a chain of groups. + * @bfqd: queue descriptor. + * @cgroup: the leaf cgroup this chain starts from. + * + * Allocate a chain of groups starting from the one belonging to + * @cgroup up to the root cgroup. Stop if a cgroup on the chain + * to the root has already an allocated group on @bfqd. + */ +static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, + struct cgroup *cgroup) +{ + struct bfqio_cgroup *bgrp; + struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; + + for (; cgroup != NULL; cgroup = cgroup->parent) { + bgrp = cgroup_to_bfqio(cgroup); + + bfqg = bfqio_lookup_group(bgrp, bfqd); + if (bfqg != NULL) { + /* + * All the cgroups in the path from there to the + * root must have a bfq_group for bfqd, so we don't + * need any more allocations. + */ + break; + } + + bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); + if (bfqg == NULL) + goto cleanup; + + bfq_group_init_entity(bgrp, bfqg); + bfqg->my_entity = &bfqg->entity; + + if (leaf == NULL) { + leaf = bfqg; + prev = leaf; + } else { + bfq_group_set_parent(prev, bfqg); + /* + * Build a list of allocated nodes using the bfqd + * filed, that is still unused and will be + * initialized only after the node will be + * connected. + */ + prev->bfqd = bfqg; + prev = bfqg; + } + } + + return leaf; + +cleanup: + while (leaf != NULL) { + prev = leaf; + leaf = leaf->bfqd; + kfree(prev); + } + + return NULL; +} + +/** + * bfq_group_chain_link - link an allocated group chain to a cgroup + * hierarchy. + * @bfqd: the queue descriptor. + * @cgroup: the leaf cgroup to start from. + * @leaf: the leaf group (to be associated to @cgroup). + * + * Try to link a chain of groups to a cgroup hierarchy, connecting the + * nodes bottom-up, so we can be sure that when we find a cgroup in the + * hierarchy that already as a group associated to @bfqd all the nodes + * in the path to the root cgroup have one too. + * + * On locking: the queue lock protects the hierarchy (there is a hierarchy + * per device) while the bfqio_cgroup lock protects the list of groups + * belonging to the same cgroup. + */ +static void bfq_group_chain_link(struct bfq_data *bfqd, struct cgroup *cgroup, + struct bfq_group *leaf) +{ + struct bfqio_cgroup *bgrp; + struct bfq_group *bfqg, *next, *prev = NULL; + unsigned long flags; + + assert_spin_locked(bfqd->queue->queue_lock); + + for (; cgroup != NULL && leaf != NULL; cgroup = cgroup->parent) { + bgrp = cgroup_to_bfqio(cgroup); + next = leaf->bfqd; + + bfqg = bfqio_lookup_group(bgrp, bfqd); + BUG_ON(bfqg != NULL); + + spin_lock_irqsave(&bgrp->lock, flags); + + rcu_assign_pointer(leaf->bfqd, bfqd); + hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); + hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); + + spin_unlock_irqrestore(&bgrp->lock, flags); + + prev = leaf; + leaf = next; + } + + BUG_ON(cgroup == NULL && leaf != NULL); + if (cgroup != NULL && prev != NULL) { + bgrp = cgroup_to_bfqio(cgroup); + bfqg = bfqio_lookup_group(bgrp, bfqd); + bfq_group_set_parent(prev, bfqg); + } +} + +/** + * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. + * @bfqd: queue descriptor. + * @cgroup: cgroup being searched for. + * + * Return a group associated to @bfqd in @cgroup, allocating one if + * necessary. When a group is returned all the cgroups in the path + * to the root have a group associated to @bfqd. + * + * If the allocation fails, return the root group: this breaks guarantees + * but is a safe fallback. If this loss becomes a problem it can be + * mitigated using the equivalent weight (given by the product of the + * weights of the groups in the path from @group to the root) in the + * root scheduler. + * + * We allocate all the missing nodes in the path from the leaf cgroup + * to the root and we connect the nodes only after all the allocations + * have been successful. + */ +static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, + struct cgroup *cgroup) +{ + struct bfqio_cgroup *bgrp = cgroup_to_bfqio(cgroup); + struct bfq_group *bfqg; + + bfqg = bfqio_lookup_group(bgrp, bfqd); + if (bfqg != NULL) + return bfqg; + + bfqg = bfq_group_chain_alloc(bfqd, cgroup); + if (bfqg != NULL) + bfq_group_chain_link(bfqd, cgroup, bfqg); + else + bfqg = bfqd->root_group; + + return bfqg; +} + +/** + * bfq_bfqq_move - migrate @bfqq to @bfqg. + * @bfqd: queue descriptor. + * @bfqq: the queue to move. + * @entity: @bfqq's entity. + * @bfqg: the group to move to. + * + * Move @bfqq to @bfqg, deactivating it from its old group and reactivating + * it on the new one. Avoid putting the entity on the old group idle tree. + * + * Must be called under the queue lock; the cgroup owning @bfqg must + * not disappear (by now this just means that we are called under + * rcu_read_lock()). + */ +static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, + struct bfq_entity *entity, struct bfq_group *bfqg) +{ + int busy, resume; + + busy = bfq_bfqq_busy(bfqq); + resume = !RB_EMPTY_ROOT(&bfqq->sort_list); + + BUG_ON(resume && !entity->on_st); + BUG_ON(busy && !resume && entity->on_st && + bfqq != bfqd->in_service_queue); + + if (busy) { + BUG_ON(atomic_read(&bfqq->ref) < 2); + + if (!resume) + bfq_del_bfqq_busy(bfqd, bfqq, 0); + else + bfq_deactivate_bfqq(bfqd, bfqq, 0); + } else if (entity->on_st) + bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); + + /* + * Here we use a reference to bfqg. We don't need a refcounter + * as the cgroup reference will not be dropped, so that its + * destroy() callback will not be invoked. + */ + entity->parent = bfqg->my_entity; + entity->sched_data = &bfqg->sched_data; + + if (busy && resume) + bfq_activate_bfqq(bfqd, bfqq); + + if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) + bfq_schedule_dispatch(bfqd); +} + +/** + * __bfq_bic_change_cgroup - move @bic to @cgroup. + * @bfqd: the queue descriptor. + * @bic: the bic to move. + * @cgroup: the cgroup to move to. + * + * Move bic to cgroup, assuming that bfqd->queue is locked; the caller + * has to make sure that the reference to cgroup is valid across the call. + * + * NOTE: an alternative approach might have been to store the current + * cgroup in bfqq and getting a reference to it, reducing the lookup + * time here, at the price of slightly more complex code. + */ +static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, + struct bfq_io_cq *bic, + struct cgroup *cgroup) +{ + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); + struct bfq_entity *entity; + struct bfq_group *bfqg; + struct bfqio_cgroup *bgrp; + + bgrp = cgroup_to_bfqio(cgroup); + + bfqg = bfq_find_alloc_group(bfqd, cgroup); + if (async_bfqq != NULL) { + entity = &async_bfqq->entity; + + if (entity->sched_data != &bfqg->sched_data) { + bic_set_bfqq(bic, NULL, 0); + bfq_log_bfqq(bfqd, async_bfqq, + "bic_change_group: %p %d", + async_bfqq, atomic_read(&async_bfqq->ref)); + bfq_put_queue(async_bfqq); + } + } + + if (sync_bfqq != NULL) { + entity = &sync_bfqq->entity; + if (entity->sched_data != &bfqg->sched_data) + bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); + } + + return bfqg; +} + +/** + * bfq_bic_change_cgroup - move @bic to @cgroup. + * @bic: the bic being migrated. + * @cgroup: the destination cgroup. + * + * When the task owning @bic is moved to @cgroup, @bic is immediately + * moved into its new parent group. + */ +static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, + struct cgroup *cgroup) +{ + struct bfq_data *bfqd; + unsigned long uninitialized_var(flags); + + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), + &flags); + if (bfqd != NULL) { + __bfq_bic_change_cgroup(bfqd, bic, cgroup); + bfq_put_bfqd_unlock(bfqd, &flags); + } +} + +/** + * bfq_bic_update_cgroup - update the cgroup of @bic. + * @bic: the @bic to update. + * + * Make sure that @bic is enqueued in the cgroup of the current task. + * We need this in addition to moving bics during the cgroup attach + * phase because the task owning @bic could be at its first disk + * access or we may end up in the root cgroup as the result of a + * memory allocation failure and here we try to move to the right + * group. + * + * Must be called under the queue lock. It is safe to use the returned + * value even after the rcu_read_unlock() as the migration/destruction + * paths act under the queue lock too. IOW it is impossible to race with + * group migration/destruction and end up with an invalid group as: + * a) here cgroup has not yet been destroyed, nor its destroy callback + * has started execution, as current holds a reference to it, + * b) if it is destroyed after rcu_read_unlock() [after current is + * migrated to a different cgroup] its attach() callback will have + * taken care of remove all the references to the old cgroup data. + */ +static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) +{ + struct bfq_data *bfqd = bic_to_bfqd(bic); + struct bfq_group *bfqg; + struct cgroup *cgroup; + + BUG_ON(bfqd == NULL); + + rcu_read_lock(); + cgroup = task_cgroup(current, bfqio_subsys_id); + bfqg = __bfq_bic_change_cgroup(bfqd, bic, cgroup); + rcu_read_unlock(); + + return bfqg; +} + +/** + * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. + * @st: the service tree being flushed. + */ +static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) +{ + struct bfq_entity *entity = st->first_idle; + + for (; entity != NULL; entity = st->first_idle) + __bfq_deactivate_entity(entity, 0); +} + +/** + * bfq_reparent_leaf_entity - move leaf entity to the root_group. + * @bfqd: the device data structure with the root group. + * @entity: the entity to move. + */ +static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + + BUG_ON(bfqq == NULL); + bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); + return; +} + +/** + * bfq_reparent_active_entities - move to the root group all active + * entities. + * @bfqd: the device data structure with the root group. + * @bfqg: the group to move from. + * @st: the service tree with the entities. + * + * Needs queue_lock to be taken and reference to be valid over the call. + */ +static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, + struct bfq_group *bfqg, + struct bfq_service_tree *st) +{ + struct rb_root *active = &st->active; + struct bfq_entity *entity = NULL; + + if (!RB_EMPTY_ROOT(&st->active)) + entity = bfq_entity_of(rb_first(active)); + + for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) + bfq_reparent_leaf_entity(bfqd, entity); + + if (bfqg->sched_data.in_service_entity != NULL) + bfq_reparent_leaf_entity(bfqd, + bfqg->sched_data.in_service_entity); + + return; +} + +/** + * bfq_destroy_group - destroy @bfqg. + * @bgrp: the bfqio_cgroup containing @bfqg. + * @bfqg: the group being destroyed. + * + * Destroy @bfqg, making sure that it is not referenced from its parent. + */ +static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) +{ + struct bfq_data *bfqd; + struct bfq_service_tree *st; + struct bfq_entity *entity = bfqg->my_entity; + unsigned long uninitialized_var(flags); + int i; + + hlist_del(&bfqg->group_node); + + /* + * Empty all service_trees belonging to this group before + * deactivating the group itself. + */ + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { + st = bfqg->sched_data.service_tree + i; + + /* + * The idle tree may still contain bfq_queues belonging + * to exited task because they never migrated to a different + * cgroup from the one being destroyed now. No one else + * can access them so it's safe to act without any lock. + */ + bfq_flush_idle_tree(st); + + /* + * It may happen that some queues are still active + * (busy) upon group destruction (if the corresponding + * processes have been forced to terminate). We move + * all the leaf entities corresponding to these queues + * to the root_group. + * Also, it may happen that the group has an entity + * in service, which is disconnected from the active + * tree: it must be moved, too. + * There is no need to put the sync queues, as the + * scheduler has taken no reference. + */ + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); + if (bfqd != NULL) { + bfq_reparent_active_entities(bfqd, bfqg, st); + bfq_put_bfqd_unlock(bfqd, &flags); + } + BUG_ON(!RB_EMPTY_ROOT(&st->active)); + BUG_ON(!RB_EMPTY_ROOT(&st->idle)); + } + BUG_ON(bfqg->sched_data.next_in_service != NULL); + BUG_ON(bfqg->sched_data.in_service_entity != NULL); + + /* + * We may race with device destruction, take extra care when + * dereferencing bfqg->bfqd. + */ + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); + if (bfqd != NULL) { + hlist_del(&bfqg->bfqd_node); + __bfq_deactivate_entity(entity, 0); + bfq_put_async_queues(bfqd, bfqg); + bfq_put_bfqd_unlock(bfqd, &flags); + } + BUG_ON(entity->tree != NULL); + + /* + * No need to defer the kfree() to the end of the RCU grace + * period: we are called from the destroy() callback of our + * cgroup, so we can be sure that no one is a) still using + * this cgroup or b) doing lookups in it. + */ + kfree(bfqg); +} + +static void bfq_end_wr_async(struct bfq_data *bfqd) +{ + struct hlist_node *tmp; + struct bfq_group *bfqg; + + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) + bfq_end_wr_async_queues(bfqd, bfqg); + bfq_end_wr_async_queues(bfqd, bfqd->root_group); +} + +/** + * bfq_disconnect_groups - disconnect @bfqd from all its groups. + * @bfqd: the device descriptor being exited. + * + * When the device exits we just make sure that no lookup can return + * the now unused group structures. They will be deallocated on cgroup + * destruction. + */ +static void bfq_disconnect_groups(struct bfq_data *bfqd) +{ + struct hlist_node *tmp; + struct bfq_group *bfqg; + + bfq_log(bfqd, "disconnect_groups beginning"); + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) { + hlist_del(&bfqg->bfqd_node); + + __bfq_deactivate_entity(bfqg->my_entity, 0); + + /* + * Don't remove from the group hash, just set an + * invalid key. No lookups can race with the + * assignment as bfqd is being destroyed; this + * implies also that new elements cannot be added + * to the list. + */ + rcu_assign_pointer(bfqg->bfqd, NULL); + + bfq_log(bfqd, "disconnect_groups: put async for group %p", + bfqg); + bfq_put_async_queues(bfqd, bfqg); + } +} + +static inline void bfq_free_root_group(struct bfq_data *bfqd) +{ + struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; + struct bfq_group *bfqg = bfqd->root_group; + + bfq_put_async_queues(bfqd, bfqg); + + spin_lock_irq(&bgrp->lock); + hlist_del_rcu(&bfqg->group_node); + spin_unlock_irq(&bgrp->lock); + + /* + * No need to synchronize_rcu() here: since the device is gone + * there cannot be any read-side access to its root_group. + */ + kfree(bfqg); +} + +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) +{ + struct bfq_group *bfqg; + struct bfqio_cgroup *bgrp; + int i; + + bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); + if (bfqg == NULL) + return NULL; + + bfqg->entity.parent = NULL; + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; + + bgrp = &bfqio_root_cgroup; + spin_lock_irq(&bgrp->lock); + rcu_assign_pointer(bfqg->bfqd, bfqd); + hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); + spin_unlock_irq(&bgrp->lock); + + return bfqg; +} + +#define SHOW_FUNCTION(__VAR) \ +static u64 bfqio_cgroup_##__VAR##_read(struct cgroup *cgroup, \ + struct cftype *cftype) \ +{ \ + struct bfqio_cgroup *bgrp; \ + u64 ret = -ENODEV; \ + \ + mutex_lock(&bfqio_mutex); \ + if (bfqio_is_removed(cgroup)) \ + goto out_unlock; \ + \ + bgrp = cgroup_to_bfqio(cgroup); \ + spin_lock_irq(&bgrp->lock); \ + ret = bgrp->__VAR; \ + spin_unlock_irq(&bgrp->lock); \ + \ +out_unlock: \ + mutex_unlock(&bfqio_mutex); \ + return ret; \ +} + +SHOW_FUNCTION(weight); +SHOW_FUNCTION(ioprio); +SHOW_FUNCTION(ioprio_class); +#undef SHOW_FUNCTION + +#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ +static int bfqio_cgroup_##__VAR##_write(struct cgroup *cgroup, \ + struct cftype *cftype, \ + u64 val) \ +{ \ + struct bfqio_cgroup *bgrp; \ + struct bfq_group *bfqg; \ + int ret = -EINVAL; \ + \ + if (val < (__MIN) || val > (__MAX)) \ + return ret; \ + \ + ret = -ENODEV; \ + mutex_lock(&bfqio_mutex); \ + if (bfqio_is_removed(cgroup)) \ + goto out_unlock; \ + ret = 0; \ + \ + bgrp = cgroup_to_bfqio(cgroup); \ + \ + spin_lock_irq(&bgrp->lock); \ + bgrp->__VAR = (unsigned short)val; \ + hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \ + /* \ + * Setting the ioprio_changed flag of the entity \ + * to 1 with new_##__VAR == ##__VAR would re-set \ + * the value of the weight to its ioprio mapping. \ + * Set the flag only if necessary. \ + */ \ + if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ + bfqg->entity.new_##__VAR = (unsigned short)val; \ + /* \ + * Make sure that the above new value has been \ + * stored in bfqg->entity.new_##__VAR before \ + * setting the ioprio_changed flag. In fact, \ + * this flag may be read asynchronously (in \ + * critical sections protected by a different \ + * lock than that held here), and finding this \ + * flag set may cause the execution of the code \ + * for updating parameters whose value may \ + * depend also on bfqg->entity.new_##__VAR (in \ + * __bfq_entity_update_weight_prio). \ + * This barrier makes sure that the new value \ + * of bfqg->entity.new_##__VAR is correctly \ + * seen in that code. \ + */ \ + smp_wmb(); \ + bfqg->entity.ioprio_changed = 1; \ + } \ + } \ + spin_unlock_irq(&bgrp->lock); \ + \ +out_unlock: \ + mutex_unlock(&bfqio_mutex); \ + return ret; \ +} + +STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); +STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); +STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); +#undef STORE_FUNCTION + +static struct cftype bfqio_files[] = { + { + .name = "weight", + .read_u64 = bfqio_cgroup_weight_read, + .write_u64 = bfqio_cgroup_weight_write, + }, + { + .name = "ioprio", + .read_u64 = bfqio_cgroup_ioprio_read, + .write_u64 = bfqio_cgroup_ioprio_write, + }, + { + .name = "ioprio_class", + .read_u64 = bfqio_cgroup_ioprio_class_read, + .write_u64 = bfqio_cgroup_ioprio_class_write, + }, + { }, /* terminate */ +}; + +static struct cgroup_subsys_state *bfqio_create(struct cgroup *cgroup) +{ + struct bfqio_cgroup *bgrp; + + if (cgroup->parent != NULL) { + bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); + if (bgrp == NULL) + return ERR_PTR(-ENOMEM); + } else + bgrp = &bfqio_root_cgroup; + + spin_lock_init(&bgrp->lock); + INIT_HLIST_HEAD(&bgrp->group_data); + bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; + bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; + + return &bgrp->css; +} + +/* + * We cannot support shared io contexts, as we have no means to support + * two tasks with the same ioc in two different groups without major rework + * of the main bic/bfqq data structures. By now we allow a task to change + * its cgroup only if it's the only owner of its ioc; the drawback of this + * behavior is that a group containing a task that forked using CLONE_IO + * will not be destroyed until the tasks sharing the ioc die. + */ +static int bfqio_can_attach(struct cgroup *cgroup, struct cgroup_taskset *tset) +{ + struct task_struct *task; + struct io_context *ioc; + int ret = 0; + + cgroup_taskset_for_each(task, cgroup, tset) { + /* task_lock() is needed to avoid races with exit_io_context() */ + task_lock(task); + ioc = task->io_context; + if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) + /* + * ioc == NULL means that the task is either too + * young or exiting: if it has still no ioc the + * ioc can't be shared, if the task is exiting the + * attach will fail anyway, no matter what we + * return here. + */ + ret = -EINVAL; + task_unlock(task); + if (ret) + break; + } + + return ret; +} + +static void bfqio_attach(struct cgroup *cgroup, struct cgroup_taskset *tset) +{ + struct task_struct *task; + struct io_context *ioc; + struct io_cq *icq; + + /* + * IMPORTANT NOTE: The move of more than one process at a time to a + * new group has not yet been tested. + */ + cgroup_taskset_for_each(task, cgroup, tset) { + ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); + if (ioc) { + /* + * Handle cgroup change here. + */ + rcu_read_lock(); + hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node) + if (!strncmp( + icq->q->elevator->type->elevator_name, + "bfq", ELV_NAME_MAX)) + bfq_bic_change_cgroup(icq_to_bic(icq), + cgroup); + rcu_read_unlock(); + put_io_context(ioc); + } + } +} + +static void bfqio_destroy(struct cgroup *cgroup) +{ + struct bfqio_cgroup *bgrp = cgroup_to_bfqio(cgroup); + struct hlist_node *tmp; + struct bfq_group *bfqg; + + /* + * Since we are destroying the cgroup, there are no more tasks + * referencing it, and all the RCU grace periods that may have + * referenced it are ended (as the destruction of the parent + * cgroup is RCU-safe); bgrp->group_data will not be accessed by + * anything else and we don't need any synchronization. + */ + hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node) + bfq_destroy_group(bgrp, bfqg); + + BUG_ON(!hlist_empty(&bgrp->group_data)); + + kfree(bgrp); +} + +struct cgroup_subsys bfqio_subsys = { + .name = "bfqio", + .css_alloc = bfqio_create, + .can_attach = bfqio_can_attach, + .attach = bfqio_attach, + .css_free = bfqio_destroy, + .subsys_id = bfqio_subsys_id, + .base_cftypes = bfqio_files, +}; +#else +static inline void bfq_init_entity(struct bfq_entity *entity, + struct bfq_group *bfqg) +{ + entity->weight = entity->new_weight; + entity->orig_weight = entity->new_weight; + entity->ioprio = entity->new_ioprio; + entity->ioprio_class = entity->new_ioprio_class; + entity->sched_data = &bfqg->sched_data; +} + +static inline struct bfq_group * +bfq_bic_update_cgroup(struct bfq_io_cq *bic) +{ + struct bfq_data *bfqd = bic_to_bfqd(bic); + return bfqd->root_group; +} + +static inline void bfq_bfqq_move(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + struct bfq_entity *entity, + struct bfq_group *bfqg) +{ +} + +static void bfq_end_wr_async(struct bfq_data *bfqd) +{ + bfq_end_wr_async_queues(bfqd, bfqd->root_group); +} + +static inline void bfq_disconnect_groups(struct bfq_data *bfqd) +{ + bfq_put_async_queues(bfqd, bfqd->root_group); +} + +static inline void bfq_free_root_group(struct bfq_data *bfqd) +{ + kfree(bfqd->root_group); +} + +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) +{ + struct bfq_group *bfqg; + int i; + + bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); + if (bfqg == NULL) + return NULL; + + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; + + return bfqg; +} +#endif diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c new file mode 100644 index 0000000000000..7f6b0004ca701 --- /dev/null +++ b/block/bfq-ioc.c @@ -0,0 +1,36 @@ +/* + * BFQ: I/O context handling. + * + * Based on ideas and code from CFQ: + * Copyright (C) 2003 Jens Axboe + * + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * + * Copyright (C) 2010 Paolo Valente + */ + +/** + * icq_to_bic - convert iocontext queue structure to bfq_io_cq. + * @icq: the iocontext queue. + */ +static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) +{ + /* bic->icq is the first member, %NULL will convert to %NULL */ + return container_of(icq, struct bfq_io_cq, icq); +} + +/** + * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. + * @bfqd: the lookup key. + * @ioc: the io_context of the process doing I/O. + * + * Queue lock must be held. + */ +static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, + struct io_context *ioc) +{ + if (ioc) + return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); + return NULL; +} diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c new file mode 100644 index 0000000000000..014984d199e78 --- /dev/null +++ b/block/bfq-iosched.c @@ -0,0 +1,4218 @@ +/* + * Budget Fair Queueing (BFQ) disk scheduler. + * + * Based on ideas and code from CFQ: + * Copyright (C) 2003 Jens Axboe + * + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * + * Copyright (C) 2010 Paolo Valente + * + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ + * file. + * + * BFQ is a proportional-share storage-I/O scheduling algorithm based on + * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, + * measured in number of sectors, to processes instead of time slices. The + * device is not granted to the in-service process for a given time slice, + * but until it has exhausted its assigned budget. This change from the time + * to the service domain allows BFQ to distribute the device throughput + * among processes as desired, without any distortion due to ZBR, workload + * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, + * called B-WF2Q+, to schedule processes according to their budgets. More + * precisely, BFQ schedules queues associated to processes. Thanks to the + * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to + * I/O-bound processes issuing sequential requests (to boost the + * throughput), and yet guarantee a low latency to interactive and soft + * real-time applications. + * + * BFQ is described in [1], where also a reference to the initial, more + * theoretical paper on BFQ can be found. The interested reader can find + * in the latter paper full details on the main algorithm, as well as + * formulas of the guarantees and formal proofs of all the properties. + * With respect to the version of BFQ presented in these papers, this + * implementation adds a few more heuristics, such as the one that + * guarantees a low latency to soft real-time applications, and a + * hierarchical extension based on H-WF2Q+. + * + * B-WF2Q+ is based on WF2Q+, that is described in [2], together with + * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) + * complexity derives from the one introduced with EEVDF in [3]. + * + * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness + * with the BFQ Disk I/O Scheduler'', + * Proceedings of the 5th Annual International Systems and Storage + * Conference (SYSTOR '12), June 2012. + * + * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf + * + * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing + * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, + * Oct 1997. + * + * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz + * + * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline + * First: A Flexible and Accurate Mechanism for Proportional Share + * Resource Allocation,'' technical report. + * + * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "bfq.h" +#include "blk.h" + +/* Expiration time of sync (0) and async (1) requests, in jiffies. */ +static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; + +/* Maximum backwards seek, in KiB. */ +static const int bfq_back_max = 16 * 1024; + +/* Penalty of a backwards seek, in number of sectors. */ +static const int bfq_back_penalty = 2; + +/* Idling period duration, in jiffies. */ +static int bfq_slice_idle = HZ / 125; + +/* Default maximum budget values, in sectors and number of requests. */ +static const int bfq_default_max_budget = 16 * 1024; +static const int bfq_max_budget_async_rq = 4; + +/* + * Async to sync throughput distribution is controlled as follows: + * when an async request is served, the entity is charged the number + * of sectors of the request, multiplied by the factor below + */ +static const int bfq_async_charge_factor = 10; + +/* Default timeout values, in jiffies, approximating CFQ defaults. */ +static const int bfq_timeout_sync = HZ / 8; +static int bfq_timeout_async = HZ / 25; + +struct kmem_cache *bfq_pool; + +/* Below this threshold (in ms), we consider thinktime immediate. */ +#define BFQ_MIN_TT 2 + +/* hw_tag detection: parallel requests threshold and min samples needed. */ +#define BFQ_HW_QUEUE_THRESHOLD 4 +#define BFQ_HW_QUEUE_SAMPLES 32 + +#define BFQQ_SEEK_THR (sector_t)(8 * 1024) +#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) + +/* Min samples used for peak rate estimation (for autotuning). */ +#define BFQ_PEAK_RATE_SAMPLES 32 + +/* Shift used for peak rate fixed precision calculations. */ +#define BFQ_RATE_SHIFT 16 + +/* + * By default, BFQ computes the duration of the weight raising for + * interactive applications automatically, using the following formula: + * duration = (R / r) * T, where r is the peak rate of the device, and + * R and T are two reference parameters. + * In particular, R is the peak rate of the reference device (see below), + * and T is a reference time: given the systems that are likely to be + * installed on the reference device according to its speed class, T is + * about the maximum time needed, under BFQ and while reading two files in + * parallel, to load typical large applications on these systems. + * In practice, the slower/faster the device at hand is, the more/less it + * takes to load applications with respect to the reference device. + * Accordingly, the longer/shorter BFQ grants weight raising to interactive + * applications. + * + * BFQ uses four different reference pairs (R, T), depending on: + * . whether the device is rotational or non-rotational; + * . whether the device is slow, such as old or portable HDDs, as well as + * SD cards, or fast, such as newer HDDs and SSDs. + * + * The device's speed class is dynamically (re)detected in + * bfq_update_peak_rate() every time the estimated peak rate is updated. + * + * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] + * are the reference values for a slow/fast rotational device, whereas + * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for + * a slow/fast non-rotational device. Finally, device_speed_thresh are the + * thresholds used to switch between speed classes. + * Both the reference peak rates and the thresholds are measured in + * sectors/usec, left-shifted by BFQ_RATE_SHIFT. + */ +static int R_slow[2] = {1536, 10752}; +static int R_fast[2] = {17415, 34791}; +/* + * To improve readability, a conversion function is used to initialize the + * following arrays, which entails that they can be initialized only in a + * function. + */ +static int T_slow[2]; +static int T_fast[2]; +static int device_speed_thresh[2]; + +#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ + { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) + +#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) +#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) + +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); + +#include "bfq-ioc.c" +#include "bfq-sched.c" +#include "bfq-cgroup.c" + +#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ + IOPRIO_CLASS_IDLE) +#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ + IOPRIO_CLASS_RT) + +#define bfq_sample_valid(samples) ((samples) > 80) + +/* + * The following macro groups conditions that need to be evaluated when + * checking if existing queues and groups form a symmetric scenario + * and therefore idling can be reduced or disabled for some of the + * queues. See the comment to the function bfq_bfqq_must_not_expire() + * for further details. + */ +#ifdef CONFIG_CGROUP_BFQIO +#define symmetric_scenario (!bfqd->active_numerous_groups && \ + !bfq_differentiated_weights(bfqd)) +#else +#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) +#endif + +/* + * We regard a request as SYNC, if either it's a read or has the SYNC bit + * set (in which case it could also be a direct WRITE). + */ +static inline int bfq_bio_sync(struct bio *bio) +{ + if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) + return 1; + + return 0; +} + +/* + * Scheduler run of queue, if there are requests pending and no one in the + * driver that will restart queueing. + */ +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) +{ + if (bfqd->queued != 0) { + bfq_log(bfqd, "schedule dispatch"); + kblockd_schedule_work(bfqd->queue, &bfqd->unplug_work); + } +} + +/* + * Lifted from AS - choose which of rq1 and rq2 that is best served now. + * We choose the request that is closesr to the head right now. Distance + * behind the head is penalized and only allowed to a certain extent. + */ +static struct request *bfq_choose_req(struct bfq_data *bfqd, + struct request *rq1, + struct request *rq2, + sector_t last) +{ + sector_t s1, s2, d1 = 0, d2 = 0; + unsigned long back_max; +#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ +#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ + unsigned wrap = 0; /* bit mask: requests behind the disk head? */ + + if (rq1 == NULL || rq1 == rq2) + return rq2; + if (rq2 == NULL) + return rq1; + + if (rq_is_sync(rq1) && !rq_is_sync(rq2)) + return rq1; + else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) + return rq2; + if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) + return rq1; + else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) + return rq2; + + s1 = blk_rq_pos(rq1); + s2 = blk_rq_pos(rq2); + + /* + * By definition, 1KiB is 2 sectors. + */ + back_max = bfqd->bfq_back_max * 2; + + /* + * Strict one way elevator _except_ in the case where we allow + * short backward seeks which are biased as twice the cost of a + * similar forward seek. + */ + if (s1 >= last) + d1 = s1 - last; + else if (s1 + back_max >= last) + d1 = (last - s1) * bfqd->bfq_back_penalty; + else + wrap |= BFQ_RQ1_WRAP; + + if (s2 >= last) + d2 = s2 - last; + else if (s2 + back_max >= last) + d2 = (last - s2) * bfqd->bfq_back_penalty; + else + wrap |= BFQ_RQ2_WRAP; + + /* Found required data */ + + /* + * By doing switch() on the bit mask "wrap" we avoid having to + * check two variables for all permutations: --> faster! + */ + switch (wrap) { + case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ + if (d1 < d2) + return rq1; + else if (d2 < d1) + return rq2; + else { + if (s1 >= s2) + return rq1; + else + return rq2; + } + + case BFQ_RQ2_WRAP: + return rq1; + case BFQ_RQ1_WRAP: + return rq2; + case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ + default: + /* + * Since both rqs are wrapped, + * start with the one that's further behind head + * (--> only *one* back seek required), + * since back seek takes more time than forward. + */ + if (s1 <= s2) + return rq1; + else + return rq2; + } +} + +static struct bfq_queue * +bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, + sector_t sector, struct rb_node **ret_parent, + struct rb_node ***rb_link) +{ + struct rb_node **p, *parent; + struct bfq_queue *bfqq = NULL; + + parent = NULL; + p = &root->rb_node; + while (*p) { + struct rb_node **n; + + parent = *p; + bfqq = rb_entry(parent, struct bfq_queue, pos_node); + + /* + * Sort strictly based on sector. Smallest to the left, + * largest to the right. + */ + if (sector > blk_rq_pos(bfqq->next_rq)) + n = &(*p)->rb_right; + else if (sector < blk_rq_pos(bfqq->next_rq)) + n = &(*p)->rb_left; + else + break; + p = n; + bfqq = NULL; + } + + *ret_parent = parent; + if (rb_link) + *rb_link = p; + + bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", + (long long unsigned)sector, + bfqq != NULL ? bfqq->pid : 0); + + return bfqq; +} + +static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + struct rb_node **p, *parent; + struct bfq_queue *__bfqq; + + if (bfqq->pos_root != NULL) { + rb_erase(&bfqq->pos_node, bfqq->pos_root); + bfqq->pos_root = NULL; + } + + if (bfq_class_idle(bfqq)) + return; + if (!bfqq->next_rq) + return; + + bfqq->pos_root = &bfqd->rq_pos_tree; + __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, + blk_rq_pos(bfqq->next_rq), &parent, &p); + if (__bfqq == NULL) { + rb_link_node(&bfqq->pos_node, parent, p); + rb_insert_color(&bfqq->pos_node, bfqq->pos_root); + } else + bfqq->pos_root = NULL; +} + +/* + * Tell whether there are active queues or groups with differentiated weights. + */ +static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) +{ + /* + * For weights to differ, at least one of the trees must contain + * at least two nodes. + */ + return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && + (bfqd->queue_weights_tree.rb_node->rb_left || + bfqd->queue_weights_tree.rb_node->rb_right) +#ifdef CONFIG_CGROUP_BFQIO + ) || + (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && + (bfqd->group_weights_tree.rb_node->rb_left || + bfqd->group_weights_tree.rb_node->rb_right) +#endif + ); +} + +/* + * If the weight-counter tree passed as input contains no counter for + * the weight of the input entity, then add that counter; otherwise just + * increment the existing counter. + * + * Note that weight-counter trees contain few nodes in mostly symmetric + * scenarios. For example, if all queues have the same weight, then the + * weight-counter tree for the queues may contain at most one node. + * This holds even if low_latency is on, because weight-raised queues + * are not inserted in the tree. + * In most scenarios, the rate at which nodes are created/destroyed + * should be low too. + */ +static void bfq_weights_tree_add(struct bfq_data *bfqd, + struct bfq_entity *entity, + struct rb_root *root) +{ + struct rb_node **new = &(root->rb_node), *parent = NULL; + + /* + * Do not insert if the entity is already associated with a + * counter, which happens if: + * 1) the entity is associated with a queue, + * 2) a request arrival has caused the queue to become both + * non-weight-raised, and hence change its weight, and + * backlogged; in this respect, each of the two events + * causes an invocation of this function, + * 3) this is the invocation of this function caused by the + * second event. This second invocation is actually useless, + * and we handle this fact by exiting immediately. More + * efficient or clearer solutions might possibly be adopted. + */ + if (entity->weight_counter) + return; + + while (*new) { + struct bfq_weight_counter *__counter = container_of(*new, + struct bfq_weight_counter, + weights_node); + parent = *new; + + if (entity->weight == __counter->weight) { + entity->weight_counter = __counter; + goto inc_counter; + } + if (entity->weight < __counter->weight) + new = &((*new)->rb_left); + else + new = &((*new)->rb_right); + } + + entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), + GFP_ATOMIC); + entity->weight_counter->weight = entity->weight; + rb_link_node(&entity->weight_counter->weights_node, parent, new); + rb_insert_color(&entity->weight_counter->weights_node, root); + +inc_counter: + entity->weight_counter->num_active++; +} + +/* + * Decrement the weight counter associated with the entity, and, if the + * counter reaches 0, remove the counter from the tree. + * See the comments to the function bfq_weights_tree_add() for considerations + * about overhead. + */ +static void bfq_weights_tree_remove(struct bfq_data *bfqd, + struct bfq_entity *entity, + struct rb_root *root) +{ + if (!entity->weight_counter) + return; + + BUG_ON(RB_EMPTY_ROOT(root)); + BUG_ON(entity->weight_counter->weight != entity->weight); + + BUG_ON(!entity->weight_counter->num_active); + entity->weight_counter->num_active--; + if (entity->weight_counter->num_active > 0) + goto reset_entity_pointer; + + rb_erase(&entity->weight_counter->weights_node, root); + kfree(entity->weight_counter); + +reset_entity_pointer: + entity->weight_counter = NULL; +} + +static struct request *bfq_find_next_rq(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + struct request *last) +{ + struct rb_node *rbnext = rb_next(&last->rb_node); + struct rb_node *rbprev = rb_prev(&last->rb_node); + struct request *next = NULL, *prev = NULL; + + BUG_ON(RB_EMPTY_NODE(&last->rb_node)); + + if (rbprev != NULL) + prev = rb_entry_rq(rbprev); + + if (rbnext != NULL) + next = rb_entry_rq(rbnext); + else { + rbnext = rb_first(&bfqq->sort_list); + if (rbnext && rbnext != &last->rb_node) + next = rb_entry_rq(rbnext); + } + + return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); +} + +/* see the definition of bfq_async_charge_factor for details */ +static inline unsigned long bfq_serv_to_charge(struct request *rq, + struct bfq_queue *bfqq) +{ + return blk_rq_sectors(rq) * + (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * + bfq_async_charge_factor)); +} + +/** + * bfq_updated_next_req - update the queue after a new next_rq selection. + * @bfqd: the device data the queue belongs to. + * @bfqq: the queue to update. + * + * If the first request of a queue changes we make sure that the queue + * has enough budget to serve at least its first request (if the + * request has grown). We do this because if the queue has not enough + * budget for its first request, it has to go through two dispatch + * rounds to actually get it dispatched. + */ +static void bfq_updated_next_req(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; + struct bfq_service_tree *st = bfq_entity_service_tree(entity); + struct request *next_rq = bfqq->next_rq; + unsigned long new_budget; + + if (next_rq == NULL) + return; + + if (bfqq == bfqd->in_service_queue) + /* + * In order not to break guarantees, budgets cannot be + * changed after an entity has been selected. + */ + return; + + BUG_ON(entity->tree != &st->active); + BUG_ON(entity == entity->sched_data->in_service_entity); + + new_budget = max_t(unsigned long, bfqq->max_budget, + bfq_serv_to_charge(next_rq, bfqq)); + if (entity->budget != new_budget) { + entity->budget = new_budget; + bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", + new_budget); + bfq_activate_bfqq(bfqd, bfqq); + } +} + +static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) +{ + u64 dur; + + if (bfqd->bfq_wr_max_time > 0) + return bfqd->bfq_wr_max_time; + + dur = bfqd->RT_prod; + do_div(dur, bfqd->peak_rate); + + return dur; +} + +static inline unsigned +bfq_bfqq_cooperations(struct bfq_queue *bfqq) +{ + return bfqq->bic ? bfqq->bic->cooperations : 0; +} + +static inline void +bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) +{ + if (bic->saved_idle_window) + bfq_mark_bfqq_idle_window(bfqq); + else + bfq_clear_bfqq_idle_window(bfqq); + if (bic->saved_IO_bound) + bfq_mark_bfqq_IO_bound(bfqq); + else + bfq_clear_bfqq_IO_bound(bfqq); + /* Assuming that the flag in_large_burst is already correctly set */ + if (bic->wr_time_left && bfqq->bfqd->low_latency && + !bfq_bfqq_in_large_burst(bfqq) && + bic->cooperations < bfqq->bfqd->bfq_coop_thresh) { + /* + * Start a weight raising period with the duration given by + * the raising_time_left snapshot. + */ + if (bfq_bfqq_busy(bfqq)) + bfqq->bfqd->wr_busy_queues++; + bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff; + bfqq->wr_cur_max_time = bic->wr_time_left; + bfqq->last_wr_start_finish = jiffies; + bfqq->entity.ioprio_changed = 1; + } + /* + * Clear wr_time_left to prevent bfq_bfqq_save_state() from + * getting confused about the queue's need of a weight-raising + * period. + */ + bic->wr_time_left = 0; +} + +/* Must be called with the queue_lock held. */ +static int bfqq_process_refs(struct bfq_queue *bfqq) +{ + int process_refs, io_refs; + + io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; + process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; + BUG_ON(process_refs < 0); + return process_refs; +} + +/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ +static inline void bfq_reset_burst_list(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +{ + struct bfq_queue *item; + struct hlist_node *n; + + hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) + hlist_del_init(&item->burst_list_node); + hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); + bfqd->burst_size = 1; +} + +/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ +static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + /* Increment burst size to take into account also bfqq */ + bfqd->burst_size++; + + if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { + struct bfq_queue *pos, *bfqq_item; + struct hlist_node *n; + + /* + * Enough queues have been activated shortly after each + * other to consider this burst as large. + */ + bfqd->large_burst = true; + + /* + * We can now mark all queues in the burst list as + * belonging to a large burst. + */ + hlist_for_each_entry(bfqq_item, &bfqd->burst_list, + burst_list_node) + bfq_mark_bfqq_in_large_burst(bfqq_item); + bfq_mark_bfqq_in_large_burst(bfqq); + + /* + * From now on, and until the current burst finishes, any + * new queue being activated shortly after the last queue + * was inserted in the burst can be immediately marked as + * belonging to a large burst. So the burst list is not + * needed any more. Remove it. + */ + hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, + burst_list_node) + hlist_del_init(&pos->burst_list_node); + } else /* burst not yet large: add bfqq to the burst list */ + hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); +} + +/* + * If many queues happen to become active shortly after each other, then, + * to help the processes associated to these queues get their job done as + * soon as possible, it is usually better to not grant either weight-raising + * or device idling to these queues. In this comment we describe, firstly, + * the reasons why this fact holds, and, secondly, the next function, which + * implements the main steps needed to properly mark these queues so that + * they can then be treated in a different way. + * + * As for the terminology, we say that a queue becomes active, i.e., + * switches from idle to backlogged, either when it is created (as a + * consequence of the arrival of an I/O request), or, if already existing, + * when a new request for the queue arrives while the queue is idle. + * Bursts of activations, i.e., activations of different queues occurring + * shortly after each other, are typically caused by services or applications + * that spawn or reactivate many parallel threads/processes. Examples are + * systemd during boot or git grep. + * + * These services or applications benefit mostly from a high throughput: + * the quicker the requests of the activated queues are cumulatively served, + * the sooner the target job of these queues gets completed. As a consequence, + * weight-raising any of these queues, which also implies idling the device + * for it, is almost always counterproductive: in most cases it just lowers + * throughput. + * + * On the other hand, a burst of activations may be also caused by the start + * of an application that does not consist in a lot of parallel I/O-bound + * threads. In fact, with a complex application, the burst may be just a + * consequence of the fact that several processes need to be executed to + * start-up the application. To start an application as quickly as possible, + * the best thing to do is to privilege the I/O related to the application + * with respect to all other I/O. Therefore, the best strategy to start as + * quickly as possible an application that causes a burst of activations is + * to weight-raise all the queues activated during the burst. This is the + * exact opposite of the best strategy for the other type of bursts. + * + * In the end, to take the best action for each of the two cases, the two + * types of bursts need to be distinguished. Fortunately, this seems + * relatively easy to do, by looking at the sizes of the bursts. In + * particular, we found a threshold such that bursts with a larger size + * than that threshold are apparently caused only by services or commands + * such as systemd or git grep. For brevity, hereafter we call just 'large' + * these bursts. BFQ *does not* weight-raise queues whose activations occur + * in a large burst. In addition, for each of these queues BFQ performs or + * does not perform idling depending on which choice boosts the throughput + * most. The exact choice depends on the device and request pattern at + * hand. + * + * Turning back to the next function, it implements all the steps needed + * to detect the occurrence of a large burst and to properly mark all the + * queues belonging to it (so that they can then be treated in a different + * way). This goal is achieved by maintaining a special "burst list" that + * holds, temporarily, the queues that belong to the burst in progress. The + * list is then used to mark these queues as belonging to a large burst if + * the burst does become large. The main steps are the following. + * + * . when the very first queue is activated, the queue is inserted into the + * list (as it could be the first queue in a possible burst) + * + * . if the current burst has not yet become large, and a queue Q that does + * not yet belong to the burst is activated shortly after the last time + * at which a new queue entered the burst list, then the function appends + * Q to the burst list + * + * . if, as a consequence of the previous step, the burst size reaches + * the large-burst threshold, then + * + * . all the queues in the burst list are marked as belonging to a + * large burst + * + * . the burst list is deleted; in fact, the burst list already served + * its purpose (keeping temporarily track of the queues in a burst, + * so as to be able to mark them as belonging to a large burst in the + * previous sub-step), and now is not needed any more + * + * . the device enters a large-burst mode + * + * . if a queue Q that does not belong to the burst is activated while + * the device is in large-burst mode and shortly after the last time + * at which a queue either entered the burst list or was marked as + * belonging to the current large burst, then Q is immediately marked + * as belonging to a large burst. + * + * . if a queue Q that does not belong to the burst is activated a while + * later, i.e., not shortly after, than the last time at which a queue + * either entered the burst list or was marked as belonging to the + * current large burst, then the current burst is deemed as finished and: + * + * . the large-burst mode is reset if set + * + * . the burst list is emptied + * + * . Q is inserted in the burst list, as Q may be the first queue + * in a possible new burst (then the burst list contains just Q + * after this step). + */ +static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, + bool idle_for_long_time) +{ + /* + * If bfqq happened to be activated in a burst, but has been idle + * for at least as long as an interactive queue, then we assume + * that, in the overall I/O initiated in the burst, the I/O + * associated to bfqq is finished. So bfqq does not need to be + * treated as a queue belonging to a burst anymore. Accordingly, + * we reset bfqq's in_large_burst flag if set, and remove bfqq + * from the burst list if it's there. We do not decrement instead + * burst_size, because the fact that bfqq does not need to belong + * to the burst list any more does not invalidate the fact that + * bfqq may have been activated during the current burst. + */ + if (idle_for_long_time) { + hlist_del_init(&bfqq->burst_list_node); + bfq_clear_bfqq_in_large_burst(bfqq); + } + + /* + * If bfqq is already in the burst list or is part of a large + * burst, then there is nothing else to do. + */ + if (!hlist_unhashed(&bfqq->burst_list_node) || + bfq_bfqq_in_large_burst(bfqq)) + return; + + /* + * If bfqq's activation happens late enough, then the current + * burst is finished, and related data structures must be reset. + * + * In this respect, consider the special case where bfqq is the very + * first queue being activated. In this case, last_ins_in_burst is + * not yet significant when we get here. But it is easy to verify + * that, whether or not the following condition is true, bfqq will + * end up being inserted into the burst list. In particular the + * list will happen to contain only bfqq. And this is exactly what + * has to happen, as bfqq may be the first queue in a possible + * burst. + */ + if (time_is_before_jiffies(bfqd->last_ins_in_burst + + bfqd->bfq_burst_interval)) { + bfqd->large_burst = false; + bfq_reset_burst_list(bfqd, bfqq); + return; + } + + /* + * If we get here, then bfqq is being activated shortly after the + * last queue. So, if the current burst is also large, we can mark + * bfqq as belonging to this large burst immediately. + */ + if (bfqd->large_burst) { + bfq_mark_bfqq_in_large_burst(bfqq); + return; + } + + /* + * If we get here, then a large-burst state has not yet been + * reached, but bfqq is being activated shortly after the last + * queue. Then we add bfqq to the burst. + */ + bfq_add_to_burst(bfqd, bfqq); +} + +static void bfq_add_request(struct request *rq) +{ + struct bfq_queue *bfqq = RQ_BFQQ(rq); + struct bfq_entity *entity = &bfqq->entity; + struct bfq_data *bfqd = bfqq->bfqd; + struct request *next_rq, *prev; + unsigned long old_wr_coeff = bfqq->wr_coeff; + bool interactive = false; + + bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); + bfqq->queued[rq_is_sync(rq)]++; + bfqd->queued++; + + elv_rb_add(&bfqq->sort_list, rq); + + /* + * Check if this request is a better next-serve candidate. + */ + prev = bfqq->next_rq; + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); + BUG_ON(next_rq == NULL); + bfqq->next_rq = next_rq; + + /* + * Adjust priority tree position, if next_rq changes. + */ + if (prev != bfqq->next_rq) + bfq_rq_pos_tree_add(bfqd, bfqq); + + if (!bfq_bfqq_busy(bfqq)) { + bool soft_rt, coop_or_in_burst, + idle_for_long_time = time_is_before_jiffies( + bfqq->budget_timeout + + bfqd->bfq_wr_min_idle_time); + + if (bfq_bfqq_sync(bfqq)) { + bool already_in_burst = + !hlist_unhashed(&bfqq->burst_list_node) || + bfq_bfqq_in_large_burst(bfqq); + bfq_handle_burst(bfqd, bfqq, idle_for_long_time); + /* + * If bfqq was not already in the current burst, + * then, at this point, bfqq either has been + * added to the current burst or has caused the + * current burst to terminate. In particular, in + * the second case, bfqq has become the first + * queue in a possible new burst. + * In both cases last_ins_in_burst needs to be + * moved forward. + */ + if (!already_in_burst) + bfqd->last_ins_in_burst = jiffies; + } + + coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) || + bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh; + soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && + !coop_or_in_burst && + time_is_before_jiffies(bfqq->soft_rt_next_start); + interactive = !coop_or_in_burst && idle_for_long_time; + entity->budget = max_t(unsigned long, bfqq->max_budget, + bfq_serv_to_charge(next_rq, bfqq)); + + if (!bfq_bfqq_IO_bound(bfqq)) { + if (time_before(jiffies, + RQ_BIC(rq)->ttime.last_end_request + + bfqd->bfq_slice_idle)) { + bfqq->requests_within_timer++; + if (bfqq->requests_within_timer >= + bfqd->bfq_requests_within_timer) + bfq_mark_bfqq_IO_bound(bfqq); + } else + bfqq->requests_within_timer = 0; + } + + if (!bfqd->low_latency) + goto add_bfqq_busy; + + if (bfq_bfqq_just_split(bfqq)) + goto set_ioprio_changed; + + /* + * If the queue: + * - is not being boosted, + * - has been idle for enough time, + * - is not a sync queue or is linked to a bfq_io_cq (it is + * shared "for its nature" or it is not shared and its + * requests have not been redirected to a shared queue) + * start a weight-raising period. + */ + if (old_wr_coeff == 1 && (interactive || soft_rt) && + (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) { + bfqq->wr_coeff = bfqd->bfq_wr_coeff; + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); + else + bfqq->wr_cur_max_time = + bfqd->bfq_wr_rt_max_time; + bfq_log_bfqq(bfqd, bfqq, + "wrais starting at %lu, rais_max_time %u", + jiffies, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + } else if (old_wr_coeff > 1) { + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); + else if (coop_or_in_burst || + (bfqq->wr_cur_max_time == + bfqd->bfq_wr_rt_max_time && + !soft_rt)) { + bfqq->wr_coeff = 1; + bfq_log_bfqq(bfqd, bfqq, + "wrais ending at %lu, rais_max_time %u", + jiffies, + jiffies_to_msecs(bfqq-> + wr_cur_max_time)); + } else if (time_before( + bfqq->last_wr_start_finish + + bfqq->wr_cur_max_time, + jiffies + + bfqd->bfq_wr_rt_max_time) && + soft_rt) { + /* + * + * The remaining weight-raising time is lower + * than bfqd->bfq_wr_rt_max_time, which means + * that the application is enjoying weight + * raising either because deemed soft-rt in + * the near past, or because deemed interactive + * a long ago. + * In both cases, resetting now the current + * remaining weight-raising time for the + * application to the weight-raising duration + * for soft rt applications would not cause any + * latency increase for the application (as the + * new duration would be higher than the + * remaining time). + * + * In addition, the application is now meeting + * the requirements for being deemed soft rt. + * In the end we can correctly and safely + * (re)charge the weight-raising duration for + * the application with the weight-raising + * duration for soft rt applications. + * + * In particular, doing this recharge now, i.e., + * before the weight-raising period for the + * application finishes, reduces the probability + * of the following negative scenario: + * 1) the weight of a soft rt application is + * raised at startup (as for any newly + * created application), + * 2) since the application is not interactive, + * at a certain time weight-raising is + * stopped for the application, + * 3) at that time the application happens to + * still have pending requests, and hence + * is destined to not have a chance to be + * deemed soft rt before these requests are + * completed (see the comments to the + * function bfq_bfqq_softrt_next_start() + * for details on soft rt detection), + * 4) these pending requests experience a high + * latency because the application is not + * weight-raised while they are pending. + */ + bfqq->last_wr_start_finish = jiffies; + bfqq->wr_cur_max_time = + bfqd->bfq_wr_rt_max_time; + } + } +set_ioprio_changed: + if (old_wr_coeff != bfqq->wr_coeff) + entity->ioprio_changed = 1; +add_bfqq_busy: + bfqq->last_idle_bklogged = jiffies; + bfqq->service_from_backlogged = 0; + bfq_clear_bfqq_softrt_update(bfqq); + bfq_add_bfqq_busy(bfqd, bfqq); + } else { + if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && + time_is_before_jiffies( + bfqq->last_wr_start_finish + + bfqd->bfq_wr_min_inter_arr_async)) { + bfqq->wr_coeff = bfqd->bfq_wr_coeff; + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); + + bfqd->wr_busy_queues++; + entity->ioprio_changed = 1; + bfq_log_bfqq(bfqd, bfqq, + "non-idle wrais starting at %lu, rais_max_time %u", + jiffies, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + } + if (prev != bfqq->next_rq) + bfq_updated_next_req(bfqd, bfqq); + } + + if (bfqd->low_latency && + (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) + bfqq->last_wr_start_finish = jiffies; +} + +static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, + struct bio *bio) +{ + struct task_struct *tsk = current; + struct bfq_io_cq *bic; + struct bfq_queue *bfqq; + + bic = bfq_bic_lookup(bfqd, tsk->io_context); + if (bic == NULL) + return NULL; + + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); + if (bfqq != NULL) + return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); + + return NULL; +} + +static void bfq_activate_request(struct request_queue *q, struct request *rq) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + + bfqd->rq_in_driver++; + bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); + bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", + (long long unsigned)bfqd->last_position); +} + +static inline void bfq_deactivate_request(struct request_queue *q, + struct request *rq) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + + BUG_ON(bfqd->rq_in_driver == 0); + bfqd->rq_in_driver--; +} + +static void bfq_remove_request(struct request *rq) +{ + struct bfq_queue *bfqq = RQ_BFQQ(rq); + struct bfq_data *bfqd = bfqq->bfqd; + const int sync = rq_is_sync(rq); + + if (bfqq->next_rq == rq) { + bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); + bfq_updated_next_req(bfqd, bfqq); + } + + if (rq->queuelist.prev != &rq->queuelist) + list_del_init(&rq->queuelist); + BUG_ON(bfqq->queued[sync] == 0); + bfqq->queued[sync]--; + bfqd->queued--; + elv_rb_del(&bfqq->sort_list, rq); + + if (RB_EMPTY_ROOT(&bfqq->sort_list)) { + if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) + bfq_del_bfqq_busy(bfqd, bfqq, 1); + /* + * Remove queue from request-position tree as it is empty. + */ + if (bfqq->pos_root != NULL) { + rb_erase(&bfqq->pos_node, bfqq->pos_root); + bfqq->pos_root = NULL; + } + } + + if (rq->cmd_flags & REQ_META) { + BUG_ON(bfqq->meta_pending == 0); + bfqq->meta_pending--; + } +} + +static int bfq_merge(struct request_queue *q, struct request **req, + struct bio *bio) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct request *__rq; + + __rq = bfq_find_rq_fmerge(bfqd, bio); + if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { + *req = __rq; + return ELEVATOR_FRONT_MERGE; + } + + return ELEVATOR_NO_MERGE; +} + +static void bfq_merged_request(struct request_queue *q, struct request *req, + int type) +{ + if (type == ELEVATOR_FRONT_MERGE && + rb_prev(&req->rb_node) && + blk_rq_pos(req) < + blk_rq_pos(container_of(rb_prev(&req->rb_node), + struct request, rb_node))) { + struct bfq_queue *bfqq = RQ_BFQQ(req); + struct bfq_data *bfqd = bfqq->bfqd; + struct request *prev, *next_rq; + + /* Reposition request in its sort_list */ + elv_rb_del(&bfqq->sort_list, req); + elv_rb_add(&bfqq->sort_list, req); + /* Choose next request to be served for bfqq */ + prev = bfqq->next_rq; + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, + bfqd->last_position); + BUG_ON(next_rq == NULL); + bfqq->next_rq = next_rq; + /* + * If next_rq changes, update both the queue's budget to + * fit the new request and the queue's position in its + * rq_pos_tree. + */ + if (prev != bfqq->next_rq) { + bfq_updated_next_req(bfqd, bfqq); + bfq_rq_pos_tree_add(bfqd, bfqq); + } + } +} + +static void bfq_merged_requests(struct request_queue *q, struct request *rq, + struct request *next) +{ + struct bfq_queue *bfqq = RQ_BFQQ(rq), *next_bfqq = RQ_BFQQ(next); + + /* + * If next and rq belong to the same bfq_queue and next is older + * than rq, then reposition rq in the fifo (by substituting next + * with rq). Otherwise, if next and rq belong to different + * bfq_queues, never reposition rq: in fact, we would have to + * reposition it with respect to next's position in its own fifo, + * which would most certainly be too expensive with respect to + * the benefits. + */ + if (bfqq == next_bfqq && + !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && + time_before(rq_fifo_time(next), rq_fifo_time(rq))) { + list_del_init(&rq->queuelist); + list_replace_init(&next->queuelist, &rq->queuelist); + rq_set_fifo_time(rq, rq_fifo_time(next)); + } + + if (bfqq->next_rq == next) + bfqq->next_rq = rq; + + bfq_remove_request(next); +} + +/* Must be called with bfqq != NULL */ +static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) +{ + BUG_ON(bfqq == NULL); + if (bfq_bfqq_busy(bfqq)) + bfqq->bfqd->wr_busy_queues--; + bfqq->wr_coeff = 1; + bfqq->wr_cur_max_time = 0; + /* Trigger a weight change on the next activation of the queue */ + bfqq->entity.ioprio_changed = 1; +} + +static void bfq_end_wr_async_queues(struct bfq_data *bfqd, + struct bfq_group *bfqg) +{ + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < IOPRIO_BE_NR; j++) + if (bfqg->async_bfqq[i][j] != NULL) + bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); + if (bfqg->async_idle_bfqq != NULL) + bfq_bfqq_end_wr(bfqg->async_idle_bfqq); +} + +static void bfq_end_wr(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq; + + spin_lock_irq(bfqd->queue->queue_lock); + + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) + bfq_bfqq_end_wr(bfqq); + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) + bfq_bfqq_end_wr(bfqq); + bfq_end_wr_async(bfqd); + + spin_unlock_irq(bfqd->queue->queue_lock); +} + +static inline sector_t bfq_io_struct_pos(void *io_struct, bool request) +{ + if (request) + return blk_rq_pos(io_struct); + else + return ((struct bio *)io_struct)->bi_sector; +} + +static inline sector_t bfq_dist_from(sector_t pos1, + sector_t pos2) +{ + if (pos1 >= pos2) + return pos1 - pos2; + else + return pos2 - pos1; +} + +static inline int bfq_rq_close_to_sector(void *io_struct, bool request, + sector_t sector) +{ + return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <= + BFQQ_SEEK_THR; +} + +static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector) +{ + struct rb_root *root = &bfqd->rq_pos_tree; + struct rb_node *parent, *node; + struct bfq_queue *__bfqq; + + if (RB_EMPTY_ROOT(root)) + return NULL; + + /* + * First, if we find a request starting at the end of the last + * request, choose it. + */ + __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); + if (__bfqq != NULL) + return __bfqq; + + /* + * If the exact sector wasn't found, the parent of the NULL leaf + * will contain the closest sector (rq_pos_tree sorted by + * next_request position). + */ + __bfqq = rb_entry(parent, struct bfq_queue, pos_node); + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + if (blk_rq_pos(__bfqq->next_rq) < sector) + node = rb_next(&__bfqq->pos_node); + else + node = rb_prev(&__bfqq->pos_node); + if (node == NULL) + return NULL; + + __bfqq = rb_entry(node, struct bfq_queue, pos_node); + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + return NULL; +} + +/* + * bfqd - obvious + * cur_bfqq - passed in so that we don't decide that the current queue + * is closely cooperating with itself + * sector - used as a reference point to search for a close queue + */ +static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, + struct bfq_queue *cur_bfqq, + sector_t sector) +{ + struct bfq_queue *bfqq; + + if (bfq_class_idle(cur_bfqq)) + return NULL; + if (!bfq_bfqq_sync(cur_bfqq)) + return NULL; + if (BFQQ_SEEKY(cur_bfqq)) + return NULL; + + /* If device has only one backlogged bfq_queue, don't search. */ + if (bfqd->busy_queues == 1) + return NULL; + + /* + * We should notice if some of the queues are cooperating, e.g. + * working closely on the same area of the disk. In that case, + * we can group them together and don't waste time idling. + */ + bfqq = bfqq_close(bfqd, sector); + if (bfqq == NULL || bfqq == cur_bfqq) + return NULL; + + /* + * Do not merge queues from different bfq_groups. + */ + if (bfqq->entity.parent != cur_bfqq->entity.parent) + return NULL; + + /* + * It only makes sense to merge sync queues. + */ + if (!bfq_bfqq_sync(bfqq)) + return NULL; + if (BFQQ_SEEKY(bfqq)) + return NULL; + + /* + * Do not merge queues of different priority classes. + */ + if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) + return NULL; + + return bfqq; +} + +static struct bfq_queue * +bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +{ + int process_refs, new_process_refs; + struct bfq_queue *__bfqq; + + /* + * If there are no process references on the new_bfqq, then it is + * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain + * may have dropped their last reference (not just their last process + * reference). + */ + if (!bfqq_process_refs(new_bfqq)) + return NULL; + + /* Avoid a circular list and skip interim queue merges. */ + while ((__bfqq = new_bfqq->new_bfqq)) { + if (__bfqq == bfqq) + return NULL; + new_bfqq = __bfqq; + } + + process_refs = bfqq_process_refs(bfqq); + new_process_refs = bfqq_process_refs(new_bfqq); + /* + * If the process for the bfqq has gone away, there is no + * sense in merging the queues. + */ + if (process_refs == 0 || new_process_refs == 0) + return NULL; + + bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", + new_bfqq->pid); + + /* + * Merging is just a redirection: the requests of the process + * owning one of the two queues are redirected to the other queue. + * The latter queue, in its turn, is set as shared if this is the + * first time that the requests of some process are redirected to + * it. + * + * We redirect bfqq to new_bfqq and not the opposite, because we + * are in the context of the process owning bfqq, hence we have + * the io_cq of this process. So we can immediately configure this + * io_cq to redirect the requests of the process to new_bfqq. + * + * NOTE, even if new_bfqq coincides with the in-service queue, the + * io_cq of new_bfqq is not available, because, if the in-service + * queue is shared, bfqd->in_service_bic may not point to the + * io_cq of the in-service queue. + * Redirecting the requests of the process owning bfqq to the + * currently in-service queue is in any case the best option, as + * we feed the in-service queue with new requests close to the + * last request served and, by doing so, hopefully increase the + * throughput. + */ + bfqq->new_bfqq = new_bfqq; + atomic_add(process_refs, &new_bfqq->ref); + return new_bfqq; +} + +/* + * Attempt to schedule a merge of bfqq with the currently in-service queue + * or with a close queue among the scheduled queues. + * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue + * structure otherwise. + * + * The OOM queue is not allowed to participate to cooperation: in fact, since + * the requests temporarily redirected to the OOM queue could be redirected + * again to dedicated queues at any time, the state needed to correctly + * handle merging with the OOM queue would be quite complex and expensive + * to maintain. Besides, in such a critical condition as an out of memory, + * the benefits of queue merging may be little relevant, or even negligible. + */ +static struct bfq_queue * +bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, + void *io_struct, bool request) +{ + struct bfq_queue *in_service_bfqq, *new_bfqq; + + if (bfqq->new_bfqq) + return bfqq->new_bfqq; + + if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq)) + return NULL; + + in_service_bfqq = bfqd->in_service_queue; + + if (in_service_bfqq == NULL || in_service_bfqq == bfqq || + !bfqd->in_service_bic || + unlikely(in_service_bfqq == &bfqd->oom_bfqq)) + goto check_scheduled; + + if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq)) + goto check_scheduled; + + if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq)) + goto check_scheduled; + + if (in_service_bfqq->entity.parent != bfqq->entity.parent) + goto check_scheduled; + + if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && + bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) { + new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); + if (new_bfqq != NULL) + return new_bfqq; /* Merge with in-service queue */ + } + + /* + * Check whether there is a cooperator among currently scheduled + * queues. The only thing we need is that the bio/request is not + * NULL, as we need it to establish whether a cooperator exists. + */ +check_scheduled: + new_bfqq = bfq_close_cooperator(bfqd, bfqq, + bfq_io_struct_pos(io_struct, request)); + if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq)) + return bfq_setup_merge(bfqq, new_bfqq); + + return NULL; +} + +static inline void +bfq_bfqq_save_state(struct bfq_queue *bfqq) +{ + /* + * If bfqq->bic == NULL, the queue is already shared or its requests + * have already been redirected to a shared queue; both idle window + * and weight raising state have already been saved. Do nothing. + */ + if (bfqq->bic == NULL) + return; + if (bfqq->bic->wr_time_left) + /* + * This is the queue of a just-started process, and would + * deserve weight raising: we set wr_time_left to the full + * weight-raising duration to trigger weight-raising when + * and if the queue is split and the first request of the + * queue is enqueued. + */ + bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd); + else if (bfqq->wr_coeff > 1) { + unsigned long wr_duration = + jiffies - bfqq->last_wr_start_finish; + /* + * It may happen that a queue's weight raising period lasts + * longer than its wr_cur_max_time, as weight raising is + * handled only when a request is enqueued or dispatched (it + * does not use any timer). If the weight raising period is + * about to end, don't save it. + */ + if (bfqq->wr_cur_max_time <= wr_duration) + bfqq->bic->wr_time_left = 0; + else + bfqq->bic->wr_time_left = + bfqq->wr_cur_max_time - wr_duration; + /* + * The bfq_queue is becoming shared or the requests of the + * process owning the queue are being redirected to a shared + * queue. Stop the weight raising period of the queue, as in + * both cases it should not be owned by an interactive or + * soft real-time application. + */ + bfq_bfqq_end_wr(bfqq); + } else + bfqq->bic->wr_time_left = 0; + bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); + bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); + bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); + bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); + bfqq->bic->cooperations++; + bfqq->bic->failed_cooperations = 0; +} + +static inline void +bfq_get_bic_reference(struct bfq_queue *bfqq) +{ + /* + * If bfqq->bic has a non-NULL value, the bic to which it belongs + * is about to begin using a shared bfq_queue. + */ + if (bfqq->bic) + atomic_long_inc(&bfqq->bic->icq.ioc->refcount); +} + +static void +bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, + struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +{ + bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", + (long unsigned)new_bfqq->pid); + /* Save weight raising and idle window of the merged queues */ + bfq_bfqq_save_state(bfqq); + bfq_bfqq_save_state(new_bfqq); + if (bfq_bfqq_IO_bound(bfqq)) + bfq_mark_bfqq_IO_bound(new_bfqq); + bfq_clear_bfqq_IO_bound(bfqq); + /* + * Grab a reference to the bic, to prevent it from being destroyed + * before being possibly touched by a bfq_split_bfqq(). + */ + bfq_get_bic_reference(bfqq); + bfq_get_bic_reference(new_bfqq); + /* + * Merge queues (that is, let bic redirect its requests to new_bfqq) + */ + bic_set_bfqq(bic, new_bfqq, 1); + bfq_mark_bfqq_coop(new_bfqq); + /* + * new_bfqq now belongs to at least two bics (it is a shared queue): + * set new_bfqq->bic to NULL. bfqq either: + * - does not belong to any bic any more, and hence bfqq->bic must + * be set to NULL, or + * - is a queue whose owning bics have already been redirected to a + * different queue, hence the queue is destined to not belong to + * any bic soon and bfqq->bic is already NULL (therefore the next + * assignment causes no harm). + */ + new_bfqq->bic = NULL; + bfqq->bic = NULL; + bfq_put_queue(bfqq); +} + +static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq) +{ + struct bfq_io_cq *bic = bfqq->bic; + struct bfq_data *bfqd = bfqq->bfqd; + + if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) { + bic->failed_cooperations++; + if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations) + bic->cooperations = 0; + } +} + +static int bfq_allow_merge(struct request_queue *q, struct request *rq, + struct bio *bio) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_io_cq *bic; + struct bfq_queue *bfqq, *new_bfqq; + + /* + * Disallow merge of a sync bio into an async request. + */ + if (bfq_bio_sync(bio) && !rq_is_sync(rq)) + return 0; + + /* + * Lookup the bfqq that this bio will be queued with. Allow + * merge only if rq is queued there. + * Queue lock is held here. + */ + bic = bfq_bic_lookup(bfqd, current->io_context); + if (bic == NULL) + return 0; + + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); + /* + * We take advantage of this function to perform an early merge + * of the queues of possible cooperating processes. + */ + if (bfqq != NULL) { + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); + if (new_bfqq != NULL) { + bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); + /* + * If we get here, the bio will be queued in the + * shared queue, i.e., new_bfqq, so use new_bfqq + * to decide whether bio and rq can be merged. + */ + bfqq = new_bfqq; + } else + bfq_bfqq_increase_failed_cooperations(bfqq); + } + + return bfqq == RQ_BFQQ(rq); +} + +static void __bfq_set_in_service_queue(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +{ + if (bfqq != NULL) { + bfq_mark_bfqq_must_alloc(bfqq); + bfq_mark_bfqq_budget_new(bfqq); + bfq_clear_bfqq_fifo_expire(bfqq); + + bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; + + bfq_log_bfqq(bfqd, bfqq, + "set_in_service_queue, cur-budget = %lu", + bfqq->entity.budget); + } + + bfqd->in_service_queue = bfqq; +} + +/* + * Get and set a new queue for service. + */ +static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); + + __bfq_set_in_service_queue(bfqd, bfqq); + return bfqq; +} + +/* + * If enough samples have been computed, return the current max budget + * stored in bfqd, which is dynamically updated according to the + * estimated disk peak rate; otherwise return the default max budget + */ +static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) +{ + if (bfqd->budgets_assigned < 194) + return bfq_default_max_budget; + else + return bfqd->bfq_max_budget; +} + +/* + * Return min budget, which is a fraction of the current or default + * max budget (trying with 1/32) + */ +static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) +{ + if (bfqd->budgets_assigned < 194) + return bfq_default_max_budget / 32; + else + return bfqd->bfq_max_budget / 32; +} + +static void bfq_arm_slice_timer(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq = bfqd->in_service_queue; + struct bfq_io_cq *bic; + unsigned long sl; + + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); + + /* Processes have exited, don't wait. */ + bic = bfqd->in_service_bic; + if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0) + return; + + bfq_mark_bfqq_wait_request(bfqq); + + /* + * We don't want to idle for seeks, but we do want to allow + * fair distribution of slice time for a process doing back-to-back + * seeks. So allow a little bit of time for him to submit a new rq. + * + * To prevent processes with (partly) seeky workloads from + * being too ill-treated, grant them a small fraction of the + * assigned budget before reducing the waiting time to + * BFQ_MIN_TT. This happened to help reduce latency. + */ + sl = bfqd->bfq_slice_idle; + /* + * Unless the queue is being weight-raised or the scenario is + * asymmetric, grant only minimum idle time if the queue either + * has been seeky for long enough or has already proved to be + * constantly seeky. + */ + if (bfq_sample_valid(bfqq->seek_samples) && + ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > + bfq_max_budget(bfqq->bfqd) / 8) || + bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 && + symmetric_scenario) + sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); + else if (bfqq->wr_coeff > 1) + sl = sl * 3; + bfqd->last_idling_start = ktime_get(); + mod_timer(&bfqd->idle_slice_timer, jiffies + sl); + bfq_log(bfqd, "arm idle: %u/%u ms", + jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); +} + +/* + * Set the maximum time for the in-service queue to consume its + * budget. This prevents seeky processes from lowering the disk + * throughput (always guaranteed with a time slice scheme as in CFQ). + */ +static void bfq_set_budget_timeout(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq = bfqd->in_service_queue; + unsigned int timeout_coeff; + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) + timeout_coeff = 1; + else + timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; + + bfqd->last_budget_start = ktime_get(); + + bfq_clear_bfqq_budget_new(bfqq); + bfqq->budget_timeout = jiffies + + bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; + + bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", + jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * + timeout_coeff)); +} + +/* + * Move request from internal lists to the request queue dispatch list. + */ +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_queue *bfqq = RQ_BFQQ(rq); + + /* + * For consistency, the next instruction should have been executed + * after removing the request from the queue and dispatching it. + * We execute instead this instruction before bfq_remove_request() + * (and hence introduce a temporary inconsistency), for efficiency. + * In fact, in a forced_dispatch, this prevents two counters related + * to bfqq->dispatched to risk to be uselessly decremented if bfqq + * is not in service, and then to be incremented again after + * incrementing bfqq->dispatched. + */ + bfqq->dispatched++; + bfq_remove_request(rq); + elv_dispatch_sort(q, rq); + + if (bfq_bfqq_sync(bfqq)) + bfqd->sync_flight++; +} + +/* + * Return expired entry, or NULL to just start from scratch in rbtree. + */ +static struct request *bfq_check_fifo(struct bfq_queue *bfqq) +{ + struct request *rq = NULL; + + if (bfq_bfqq_fifo_expire(bfqq)) + return NULL; + + bfq_mark_bfqq_fifo_expire(bfqq); + + if (list_empty(&bfqq->fifo)) + return NULL; + + rq = rq_entry_fifo(bfqq->fifo.next); + + if (time_before(jiffies, rq_fifo_time(rq))) + return NULL; + + return rq; +} + +static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; + return entity->budget - entity->service; +} + +static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + BUG_ON(bfqq != bfqd->in_service_queue); + + __bfq_bfqd_reset_in_service(bfqd); + + /* + * If this bfqq is shared between multiple processes, check + * to make sure that those processes are still issuing I/Os + * within the mean seek distance. If not, it may be time to + * break the queues apart again. + */ + if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) + bfq_mark_bfqq_split_coop(bfqq); + + if (RB_EMPTY_ROOT(&bfqq->sort_list)) { + /* + * Overloading budget_timeout field to store the time + * at which the queue remains with no backlog; used by + * the weight-raising mechanism. + */ + bfqq->budget_timeout = jiffies; + bfq_del_bfqq_busy(bfqd, bfqq, 1); + } else { + bfq_activate_bfqq(bfqd, bfqq); + /* + * Resort priority tree of potential close cooperators. + */ + bfq_rq_pos_tree_add(bfqd, bfqq); + } +} + +/** + * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. + * @bfqd: device data. + * @bfqq: queue to update. + * @reason: reason for expiration. + * + * Handle the feedback on @bfqq budget. See the body for detailed + * comments. + */ +static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + enum bfqq_expiration reason) +{ + struct request *next_rq; + unsigned long budget, min_budget; + + budget = bfqq->max_budget; + min_budget = bfq_min_budget(bfqd); + + BUG_ON(bfqq != bfqd->in_service_queue); + + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", + bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", + budget, bfq_min_budget(bfqd)); + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", + bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); + + if (bfq_bfqq_sync(bfqq)) { + switch (reason) { + /* + * Caveat: in all the following cases we trade latency + * for throughput. + */ + case BFQ_BFQQ_TOO_IDLE: + /* + * This is the only case where we may reduce + * the budget: if there is no request of the + * process still waiting for completion, then + * we assume (tentatively) that the timer has + * expired because the batch of requests of + * the process could have been served with a + * smaller budget. Hence, betting that + * process will behave in the same way when it + * becomes backlogged again, we reduce its + * next budget. As long as we guess right, + * this budget cut reduces the latency + * experienced by the process. + * + * However, if there are still outstanding + * requests, then the process may have not yet + * issued its next request just because it is + * still waiting for the completion of some of + * the still outstanding ones. So in this + * subcase we do not reduce its budget, on the + * contrary we increase it to possibly boost + * the throughput, as discussed in the + * comments to the BUDGET_TIMEOUT case. + */ + if (bfqq->dispatched > 0) /* still outstanding reqs */ + budget = min(budget * 2, bfqd->bfq_max_budget); + else { + if (budget > 5 * min_budget) + budget -= 4 * min_budget; + else + budget = min_budget; + } + break; + case BFQ_BFQQ_BUDGET_TIMEOUT: + /* + * We double the budget here because: 1) it + * gives the chance to boost the throughput if + * this is not a seeky process (which may have + * bumped into this timeout because of, e.g., + * ZBR), 2) together with charge_full_budget + * it helps give seeky processes higher + * timestamps, and hence be served less + * frequently. + */ + budget = min(budget * 2, bfqd->bfq_max_budget); + break; + case BFQ_BFQQ_BUDGET_EXHAUSTED: + /* + * The process still has backlog, and did not + * let either the budget timeout or the disk + * idling timeout expire. Hence it is not + * seeky, has a short thinktime and may be + * happy with a higher budget too. So + * definitely increase the budget of this good + * candidate to boost the disk throughput. + */ + budget = min(budget * 4, bfqd->bfq_max_budget); + break; + case BFQ_BFQQ_NO_MORE_REQUESTS: + /* + * Leave the budget unchanged. + */ + default: + return; + } + } else /* async queue */ + /* async queues get always the maximum possible budget + * (their ability to dispatch is limited by + * @bfqd->bfq_max_budget_async_rq). + */ + budget = bfqd->bfq_max_budget; + + bfqq->max_budget = budget; + + if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && + bfqq->max_budget > bfqd->bfq_max_budget) + bfqq->max_budget = bfqd->bfq_max_budget; + + /* + * Make sure that we have enough budget for the next request. + * Since the finish time of the bfqq must be kept in sync with + * the budget, be sure to call __bfq_bfqq_expire() after the + * update. + */ + next_rq = bfqq->next_rq; + if (next_rq != NULL) + bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, + bfq_serv_to_charge(next_rq, bfqq)); + else + bfqq->entity.budget = bfqq->max_budget; + + bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", + next_rq != NULL ? blk_rq_sectors(next_rq) : 0, + bfqq->entity.budget); +} + +static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) +{ + unsigned long max_budget; + + /* + * The max_budget calculated when autotuning is equal to the + * amount of sectors transfered in timeout_sync at the + * estimated peak rate. + */ + max_budget = (unsigned long)(peak_rate * 1000 * + timeout >> BFQ_RATE_SHIFT); + + return max_budget; +} + +/* + * In addition to updating the peak rate, checks whether the process + * is "slow", and returns 1 if so. This slow flag is used, in addition + * to the budget timeout, to reduce the amount of service provided to + * seeky processes, and hence reduce their chances to lower the + * throughput. See the code for more details. + */ +static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, + int compensate, enum bfqq_expiration reason) +{ + u64 bw, usecs, expected, timeout; + ktime_t delta; + int update = 0; + + if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) + return 0; + + if (compensate) + delta = bfqd->last_idling_start; + else + delta = ktime_get(); + delta = ktime_sub(delta, bfqd->last_budget_start); + usecs = ktime_to_us(delta); + + /* Don't trust short/unrealistic values. */ + if (usecs < 100 || usecs >= LONG_MAX) + return 0; + + /* + * Calculate the bandwidth for the last slice. We use a 64 bit + * value to store the peak rate, in sectors per usec in fixed + * point math. We do so to have enough precision in the estimate + * and to avoid overflows. + */ + bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; + do_div(bw, (unsigned long)usecs); + + timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); + + /* + * Use only long (> 20ms) intervals to filter out spikes for + * the peak rate estimation. + */ + if (usecs > 20000) { + if (bw > bfqd->peak_rate || + (!BFQQ_SEEKY(bfqq) && + reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { + bfq_log(bfqd, "measured bw =%llu", bw); + /* + * To smooth oscillations use a low-pass filter with + * alpha=7/8, i.e., + * new_rate = (7/8) * old_rate + (1/8) * bw + */ + do_div(bw, 8); + if (bw == 0) + return 0; + bfqd->peak_rate *= 7; + do_div(bfqd->peak_rate, 8); + bfqd->peak_rate += bw; + update = 1; + bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); + } + + update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; + + if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) + bfqd->peak_rate_samples++; + + if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && + update) { + int dev_type = blk_queue_nonrot(bfqd->queue); + if (bfqd->bfq_user_max_budget == 0) { + bfqd->bfq_max_budget = + bfq_calc_max_budget(bfqd->peak_rate, + timeout); + bfq_log(bfqd, "new max_budget=%lu", + bfqd->bfq_max_budget); + } + if (bfqd->device_speed == BFQ_BFQD_FAST && + bfqd->peak_rate < device_speed_thresh[dev_type]) { + bfqd->device_speed = BFQ_BFQD_SLOW; + bfqd->RT_prod = R_slow[dev_type] * + T_slow[dev_type]; + } else if (bfqd->device_speed == BFQ_BFQD_SLOW && + bfqd->peak_rate > device_speed_thresh[dev_type]) { + bfqd->device_speed = BFQ_BFQD_FAST; + bfqd->RT_prod = R_fast[dev_type] * + T_fast[dev_type]; + } + } + } + + /* + * If the process has been served for a too short time + * interval to let its possible sequential accesses prevail on + * the initial seek time needed to move the disk head on the + * first sector it requested, then give the process a chance + * and for the moment return false. + */ + if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) + return 0; + + /* + * A process is considered ``slow'' (i.e., seeky, so that we + * cannot treat it fairly in the service domain, as it would + * slow down too much the other processes) if, when a slice + * ends for whatever reason, it has received service at a + * rate that would not be high enough to complete the budget + * before the budget timeout expiration. + */ + expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; + + /* + * Caveat: processes doing IO in the slower disk zones will + * tend to be slow(er) even if not seeky. And the estimated + * peak rate will actually be an average over the disk + * surface. Hence, to not be too harsh with unlucky processes, + * we keep a budget/3 margin of safety before declaring a + * process slow. + */ + return expected > (4 * bfqq->entity.budget) / 3; +} + +/* + * To be deemed as soft real-time, an application must meet two + * requirements. First, the application must not require an average + * bandwidth higher than the approximate bandwidth required to playback or + * record a compressed high-definition video. + * The next function is invoked on the completion of the last request of a + * batch, to compute the next-start time instant, soft_rt_next_start, such + * that, if the next request of the application does not arrive before + * soft_rt_next_start, then the above requirement on the bandwidth is met. + * + * The second requirement is that the request pattern of the application is + * isochronous, i.e., that, after issuing a request or a batch of requests, + * the application stops issuing new requests until all its pending requests + * have been completed. After that, the application may issue a new batch, + * and so on. + * For this reason the next function is invoked to compute + * soft_rt_next_start only for applications that meet this requirement, + * whereas soft_rt_next_start is set to infinity for applications that do + * not. + * + * Unfortunately, even a greedy application may happen to behave in an + * isochronous way if the CPU load is high. In fact, the application may + * stop issuing requests while the CPUs are busy serving other processes, + * then restart, then stop again for a while, and so on. In addition, if + * the disk achieves a low enough throughput with the request pattern + * issued by the application (e.g., because the request pattern is random + * and/or the device is slow), then the application may meet the above + * bandwidth requirement too. To prevent such a greedy application to be + * deemed as soft real-time, a further rule is used in the computation of + * soft_rt_next_start: soft_rt_next_start must be higher than the current + * time plus the maximum time for which the arrival of a request is waited + * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. + * This filters out greedy applications, as the latter issue instead their + * next request as soon as possible after the last one has been completed + * (in contrast, when a batch of requests is completed, a soft real-time + * application spends some time processing data). + * + * Unfortunately, the last filter may easily generate false positives if + * only bfqd->bfq_slice_idle is used as a reference time interval and one + * or both the following cases occur: + * 1) HZ is so low that the duration of a jiffy is comparable to or higher + * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with + * HZ=100. + * 2) jiffies, instead of increasing at a constant rate, may stop increasing + * for a while, then suddenly 'jump' by several units to recover the lost + * increments. This seems to happen, e.g., inside virtual machines. + * To address this issue, we do not use as a reference time interval just + * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In + * particular we add the minimum number of jiffies for which the filter + * seems to be quite precise also in embedded systems and KVM/QEMU virtual + * machines. + */ +static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +{ + return max(bfqq->last_idle_bklogged + + HZ * bfqq->service_from_backlogged / + bfqd->bfq_wr_max_softrt_rate, + jiffies + bfqq->bfqd->bfq_slice_idle + 4); +} + +/* + * Return the largest-possible time instant such that, for as long as possible, + * the current time will be lower than this time instant according to the macro + * time_is_before_jiffies(). + */ +static inline unsigned long bfq_infinity_from_now(unsigned long now) +{ + return now + ULONG_MAX / 2; +} + +/** + * bfq_bfqq_expire - expire a queue. + * @bfqd: device owning the queue. + * @bfqq: the queue to expire. + * @compensate: if true, compensate for the time spent idling. + * @reason: the reason causing the expiration. + * + * + * If the process associated to the queue is slow (i.e., seeky), or in + * case of budget timeout, or, finally, if it is async, we + * artificially charge it an entire budget (independently of the + * actual service it received). As a consequence, the queue will get + * higher timestamps than the correct ones upon reactivation, and + * hence it will be rescheduled as if it had received more service + * than what it actually received. In the end, this class of processes + * will receive less service in proportion to how slowly they consume + * their budgets (and hence how seriously they tend to lower the + * throughput). + * + * In contrast, when a queue expires because it has been idling for + * too much or because it exhausted its budget, we do not touch the + * amount of service it has received. Hence when the queue will be + * reactivated and its timestamps updated, the latter will be in sync + * with the actual service received by the queue until expiration. + * + * Charging a full budget to the first type of queues and the exact + * service to the others has the effect of using the WF2Q+ policy to + * schedule the former on a timeslice basis, without violating the + * service domain guarantees of the latter. + */ +static void bfq_bfqq_expire(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + int compensate, + enum bfqq_expiration reason) +{ + int slow; + BUG_ON(bfqq != bfqd->in_service_queue); + + /* Update disk peak rate for autotuning and check whether the + * process is slow (see bfq_update_peak_rate). + */ + slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); + + /* + * As above explained, 'punish' slow (i.e., seeky), timed-out + * and async queues, to favor sequential sync workloads. + * + * Processes doing I/O in the slower disk zones will tend to be + * slow(er) even if not seeky. Hence, since the estimated peak + * rate is actually an average over the disk surface, these + * processes may timeout just for bad luck. To avoid punishing + * them we do not charge a full budget to a process that + * succeeded in consuming at least 2/3 of its budget. + */ + if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) + bfq_bfqq_charge_full_budget(bfqq); + + bfqq->service_from_backlogged += bfqq->entity.service; + + if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && + !bfq_bfqq_constantly_seeky(bfqq)) { + bfq_mark_bfqq_constantly_seeky(bfqq); + if (!blk_queue_nonrot(bfqd->queue)) + bfqd->const_seeky_busy_in_flight_queues++; + } + + if (reason == BFQ_BFQQ_TOO_IDLE && + bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) + bfq_clear_bfqq_IO_bound(bfqq); + + if (bfqd->low_latency && bfqq->wr_coeff == 1) + bfqq->last_wr_start_finish = jiffies; + + if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && + RB_EMPTY_ROOT(&bfqq->sort_list)) { + /* + * If we get here, and there are no outstanding requests, + * then the request pattern is isochronous (see the comments + * to the function bfq_bfqq_softrt_next_start()). Hence we + * can compute soft_rt_next_start. If, instead, the queue + * still has outstanding requests, then we have to wait + * for the completion of all the outstanding requests to + * discover whether the request pattern is actually + * isochronous. + */ + if (bfqq->dispatched == 0) + bfqq->soft_rt_next_start = + bfq_bfqq_softrt_next_start(bfqd, bfqq); + else { + /* + * The application is still waiting for the + * completion of one or more requests: + * prevent it from possibly being incorrectly + * deemed as soft real-time by setting its + * soft_rt_next_start to infinity. In fact, + * without this assignment, the application + * would be incorrectly deemed as soft + * real-time if: + * 1) it issued a new request before the + * completion of all its in-flight + * requests, and + * 2) at that time, its soft_rt_next_start + * happened to be in the past. + */ + bfqq->soft_rt_next_start = + bfq_infinity_from_now(jiffies); + /* + * Schedule an update of soft_rt_next_start to when + * the task may be discovered to be isochronous. + */ + bfq_mark_bfqq_softrt_update(bfqq); + } + } + + bfq_log_bfqq(bfqd, bfqq, + "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, + slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); + + /* + * Increase, decrease or leave budget unchanged according to + * reason. + */ + __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); + __bfq_bfqq_expire(bfqd, bfqq); +} + +/* + * Budget timeout is not implemented through a dedicated timer, but + * just checked on request arrivals and completions, as well as on + * idle timer expirations. + */ +static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) +{ + if (bfq_bfqq_budget_new(bfqq) || + time_before(jiffies, bfqq->budget_timeout)) + return 0; + return 1; +} + +/* + * If we expire a queue that is waiting for the arrival of a new + * request, we may prevent the fictitious timestamp back-shifting that + * allows the guarantees of the queue to be preserved (see [1] for + * this tricky aspect). Hence we return true only if this condition + * does not hold, or if the queue is slow enough to deserve only to be + * kicked off for preserving a high throughput. +*/ +static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) +{ + bfq_log_bfqq(bfqq->bfqd, bfqq, + "may_budget_timeout: wait_request %d left %d timeout %d", + bfq_bfqq_wait_request(bfqq), + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, + bfq_bfqq_budget_timeout(bfqq)); + + return (!bfq_bfqq_wait_request(bfqq) || + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) + && + bfq_bfqq_budget_timeout(bfqq); +} + +/* + * Device idling is allowed only for the queues for which this function + * returns true. For this reason, the return value of this function plays a + * critical role for both throughput boosting and service guarantees. The + * return value is computed through a logical expression. In this rather + * long comment, we try to briefly describe all the details and motivations + * behind the components of this logical expression. + * + * First, the expression is false if bfqq is not sync, or if: bfqq happened + * to become active during a large burst of queue activations, and the + * pattern of requests bfqq contains boosts the throughput if bfqq is + * expired. In fact, queues that became active during a large burst benefit + * only from throughput, as discussed in the comments to bfq_handle_burst. + * In this respect, expiring bfqq certainly boosts the throughput on NCQ- + * capable flash-based devices, whereas, on rotational devices, it boosts + * the throughput only if bfqq contains random requests. + * + * On the opposite end, if (a) bfqq is sync, (b) the above burst-related + * condition does not hold, and (c) bfqq is being weight-raised, then the + * expression always evaluates to true, as device idling is instrumental + * for preserving low-latency guarantees (see [1]). If, instead, conditions + * (a) and (b) do hold, but (c) does not, then the expression evaluates to + * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and + * (2) at least one of the following two conditions holds. + * The first condition is that the device is not performing NCQ, because + * idling the device most certainly boosts the throughput if this condition + * holds and bfqq is I/O-bound and has been granted a non-null idle window. + * The second compound condition is made of the logical AND of two components. + * + * The first component is true only if there is no weight-raised busy + * queue. This guarantees that the device is not idled for a sync non- + * weight-raised queue when there are busy weight-raised queues. The former + * is then expired immediately if empty. Combined with the timestamping + * rules of BFQ (see [1] for details), this causes sync non-weight-raised + * queues to get a lower number of requests served, and hence to ask for a + * lower number of requests from the request pool, before the busy weight- + * raised queues get served again. + * + * This is beneficial for the processes associated with weight-raised + * queues, when the request pool is saturated (e.g., in the presence of + * write hogs). In fact, if the processes associated with the other queues + * ask for requests at a lower rate, then weight-raised processes have a + * higher probability to get a request from the pool immediately (or at + * least soon) when they need one. Hence they have a higher probability to + * actually get a fraction of the disk throughput proportional to their + * high weight. This is especially true with NCQ-capable drives, which + * enqueue several requests in advance and further reorder internally- + * queued requests. + * + * In the end, mistreating non-weight-raised queues when there are busy + * weight-raised queues seems to mitigate starvation problems in the + * presence of heavy write workloads and NCQ, and hence to guarantee a + * higher application and system responsiveness in these hostile scenarios. + * + * If the first component of the compound condition is instead true, i.e., + * there is no weight-raised busy queue, then the second component of the + * compound condition takes into account service-guarantee and throughput + * issues related to NCQ (recall that the compound condition is evaluated + * only if the device is detected as supporting NCQ). + * + * As for service guarantees, allowing the drive to enqueue more than one + * request at a time, and hence delegating de facto final scheduling + * decisions to the drive's internal scheduler, causes loss of control on + * the actual request service order. In this respect, when the drive is + * allowed to enqueue more than one request at a time, the service + * distribution enforced by the drive's internal scheduler is likely to + * coincide with the desired device-throughput distribution only in the + * following, perfectly symmetric, scenario: + * 1) all active queues have the same weight, + * 2) all active groups at the same level in the groups tree have the same + * weight, + * 3) all active groups at the same level in the groups tree have the same + * number of children. + * + * Even in such a scenario, sequential I/O may still receive a preferential + * treatment, but this is not likely to be a big issue with flash-based + * devices, because of their non-dramatic loss of throughput with random + * I/O. Things do differ with HDDs, for which additional care is taken, as + * explained after completing the discussion for flash-based devices. + * + * Unfortunately, keeping the necessary state for evaluating exactly the + * above symmetry conditions would be quite complex and time-consuming. + * Therefore BFQ evaluates instead the following stronger sub-conditions, + * for which it is much easier to maintain the needed state: + * 1) all active queues have the same weight, + * 2) all active groups have the same weight, + * 3) all active groups have at most one active child each. + * In particular, the last two conditions are always true if hierarchical + * support and the cgroups interface are not enabled, hence no state needs + * to be maintained in this case. + * + * According to the above considerations, the second component of the + * compound condition evaluates to true if any of the above symmetry + * sub-condition does not hold, or the device is not flash-based. Therefore, + * if also the first component is true, then idling is allowed for a sync + * queue. These are the only sub-conditions considered if the device is + * flash-based, as, for such a device, it is sensible to force idling only + * for service-guarantee issues. In fact, as for throughput, idling + * NCQ-capable flash-based devices would not boost the throughput even + * with sequential I/O; rather it would lower the throughput in proportion + * to how fast the device is. In the end, (only) if all the three + * sub-conditions hold and the device is flash-based, the compound + * condition evaluates to false and therefore no idling is performed. + * + * As already said, things change with a rotational device, where idling + * boosts the throughput with sequential I/O (even with NCQ). Hence, for + * such a device the second component of the compound condition evaluates + * to true also if the following additional sub-condition does not hold: + * the queue is constantly seeky. Unfortunately, this different behavior + * with respect to flash-based devices causes an additional asymmetry: if + * some sync queues enjoy idling and some other sync queues do not, then + * the latter get a low share of the device throughput, simply because the + * former get many requests served after being set as in service, whereas + * the latter do not. As a consequence, to guarantee the desired throughput + * distribution, on HDDs the compound expression evaluates to true (and + * hence device idling is performed) also if the following last symmetry + * condition does not hold: no other queue is benefiting from idling. Also + * this last condition is actually replaced with a simpler-to-maintain and + * stronger condition: there is no busy queue which is not constantly seeky + * (and hence may also benefit from idling). + * + * To sum up, when all the required symmetry and throughput-boosting + * sub-conditions hold, the second component of the compound condition + * evaluates to false, and hence no idling is performed. This helps to + * keep the drives' internal queues full on NCQ-capable devices, and hence + * to boost the throughput, without causing 'almost' any loss of service + * guarantees. The 'almost' follows from the fact that, if the internal + * queue of one such device is filled while all the sub-conditions hold, + * but at some point in time some sub-condition stops to hold, then it may + * become impossible to let requests be served in the new desired order + * until all the requests already queued in the device have been served. + */ +static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) +{ + struct bfq_data *bfqd = bfqq->bfqd; +#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ + bfqd->busy_in_flight_queues == \ + bfqd->const_seeky_busy_in_flight_queues) + +#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ + bfqd->hw_tag && \ + (blk_queue_nonrot(bfqd->queue) || \ + bfq_bfqq_constantly_seeky(bfqq))) + +/* + * Condition for expiring a non-weight-raised queue (and hence not idling + * the device). + */ +#define cond_for_expiring_non_wr (bfqd->hw_tag && \ + (bfqd->wr_busy_queues > 0 || \ + (blk_queue_nonrot(bfqd->queue) || \ + cond_for_seeky_on_ncq_hdd))) + + return bfq_bfqq_sync(bfqq) && + !cond_for_expiring_in_burst && + (bfqq->wr_coeff > 1 || !symmetric_scenario || + (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && + !cond_for_expiring_non_wr) + ); +} + +/* + * If the in-service queue is empty but sync, and the function + * bfq_bfqq_must_not_expire returns true, then: + * 1) the queue must remain in service and cannot be expired, and + * 2) the disk must be idled to wait for the possible arrival of a new + * request for the queue. + * See the comments to the function bfq_bfqq_must_not_expire for the reasons + * why performing device idling is the best choice to boost the throughput + * and preserve service guarantees when bfq_bfqq_must_not_expire itself + * returns true. + */ +static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) +{ + struct bfq_data *bfqd = bfqq->bfqd; + + return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && + bfq_bfqq_must_not_expire(bfqq); +} + +/* + * Select a queue for service. If we have a current queue in service, + * check whether to continue servicing it, or retrieve and set a new one. + */ +static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq; + struct request *next_rq; + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; + + bfqq = bfqd->in_service_queue; + if (bfqq == NULL) + goto new_queue; + + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); + + if (bfq_may_expire_for_budg_timeout(bfqq) && + !timer_pending(&bfqd->idle_slice_timer) && + !bfq_bfqq_must_idle(bfqq)) + goto expire; + + next_rq = bfqq->next_rq; + /* + * If bfqq has requests queued and it has enough budget left to + * serve them, keep the queue, otherwise expire it. + */ + if (next_rq != NULL) { + if (bfq_serv_to_charge(next_rq, bfqq) > + bfq_bfqq_budget_left(bfqq)) { + reason = BFQ_BFQQ_BUDGET_EXHAUSTED; + goto expire; + } else { + /* + * The idle timer may be pending because we may + * not disable disk idling even when a new request + * arrives. + */ + if (timer_pending(&bfqd->idle_slice_timer)) { + /* + * If we get here: 1) at least a new request + * has arrived but we have not disabled the + * timer because the request was too small, + * 2) then the block layer has unplugged + * the device, causing the dispatch to be + * invoked. + * + * Since the device is unplugged, now the + * requests are probably large enough to + * provide a reasonable throughput. + * So we disable idling. + */ + bfq_clear_bfqq_wait_request(bfqq); + del_timer(&bfqd->idle_slice_timer); + } + goto keep_queue; + } + } + + /* + * No requests pending. However, if the in-service queue is idling + * for a new request, or has requests waiting for a completion and + * may idle after their completion, then keep it anyway. + */ + if (timer_pending(&bfqd->idle_slice_timer) || + (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) { + bfqq = NULL; + goto keep_queue; + } + + reason = BFQ_BFQQ_NO_MORE_REQUESTS; +expire: + bfq_bfqq_expire(bfqd, bfqq, 0, reason); +new_queue: + bfqq = bfq_set_in_service_queue(bfqd); + bfq_log(bfqd, "select_queue: new queue %d returned", + bfqq != NULL ? bfqq->pid : 0); +keep_queue: + return bfqq; +} + +static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; + if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ + bfq_log_bfqq(bfqd, bfqq, + "raising period dur %u/%u msec, old coeff %u, w %d(%d)", + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), + jiffies_to_msecs(bfqq->wr_cur_max_time), + bfqq->wr_coeff, + bfqq->entity.weight, bfqq->entity.orig_weight); + + BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != + entity->orig_weight * bfqq->wr_coeff); + if (entity->ioprio_changed) + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); + + /* + * If the queue was activated in a burst, or + * too much time has elapsed from the beginning + * of this weight-raising period, or the queue has + * exceeded the acceptable number of cooperations, + * then end weight raising. + */ + if (bfq_bfqq_in_large_burst(bfqq) || + bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh || + time_is_before_jiffies(bfqq->last_wr_start_finish + + bfqq->wr_cur_max_time)) { + bfqq->last_wr_start_finish = jiffies; + bfq_log_bfqq(bfqd, bfqq, + "wrais ending at %lu, rais_max_time %u", + bfqq->last_wr_start_finish, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + bfq_bfqq_end_wr(bfqq); + } + } + /* Update weight both if it must be raised and if it must be lowered */ + if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) + __bfq_entity_update_weight_prio( + bfq_entity_service_tree(entity), + entity); +} + +/* + * Dispatch one request from bfqq, moving it to the request queue + * dispatch list. + */ +static int bfq_dispatch_request(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +{ + int dispatched = 0; + struct request *rq; + unsigned long service_to_charge; + + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); + + /* Follow expired path, else get first next available. */ + rq = bfq_check_fifo(bfqq); + if (rq == NULL) + rq = bfqq->next_rq; + service_to_charge = bfq_serv_to_charge(rq, bfqq); + + if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { + /* + * This may happen if the next rq is chosen in fifo order + * instead of sector order. The budget is properly + * dimensioned to be always sufficient to serve the next + * request only if it is chosen in sector order. The reason + * is that it would be quite inefficient and little useful + * to always make sure that the budget is large enough to + * serve even the possible next rq in fifo order. + * In fact, requests are seldom served in fifo order. + * + * Expire the queue for budget exhaustion, and make sure + * that the next act_budget is enough to serve the next + * request, even if it comes from the fifo expired path. + */ + bfqq->next_rq = rq; + /* + * Since this dispatch is failed, make sure that + * a new one will be performed + */ + if (!bfqd->rq_in_driver) + bfq_schedule_dispatch(bfqd); + goto expire; + } + + /* Finally, insert request into driver dispatch list. */ + bfq_bfqq_served(bfqq, service_to_charge); + bfq_dispatch_insert(bfqd->queue, rq); + + bfq_update_wr_data(bfqd, bfqq); + + bfq_log_bfqq(bfqd, bfqq, + "dispatched %u sec req (%llu), budg left %lu", + blk_rq_sectors(rq), + (long long unsigned)blk_rq_pos(rq), + bfq_bfqq_budget_left(bfqq)); + + dispatched++; + + if (bfqd->in_service_bic == NULL) { + atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); + bfqd->in_service_bic = RQ_BIC(rq); + } + + if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && + dispatched >= bfqd->bfq_max_budget_async_rq) || + bfq_class_idle(bfqq))) + goto expire; + + return dispatched; + +expire: + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); + return dispatched; +} + +static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) +{ + int dispatched = 0; + + while (bfqq->next_rq != NULL) { + bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); + dispatched++; + } + + BUG_ON(!list_empty(&bfqq->fifo)); + return dispatched; +} + +/* + * Drain our current requests. + * Used for barriers and when switching io schedulers on-the-fly. + */ +static int bfq_forced_dispatch(struct bfq_data *bfqd) +{ + struct bfq_queue *bfqq, *n; + struct bfq_service_tree *st; + int dispatched = 0; + + bfqq = bfqd->in_service_queue; + if (bfqq != NULL) + __bfq_bfqq_expire(bfqd, bfqq); + + /* + * Loop through classes, and be careful to leave the scheduler + * in a consistent state, as feedback mechanisms and vtime + * updates cannot be disabled during the process. + */ + list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { + st = bfq_entity_service_tree(&bfqq->entity); + + dispatched += __bfq_forced_dispatch_bfqq(bfqq); + bfqq->max_budget = bfq_max_budget(bfqd); + + bfq_forget_idle(st); + } + + BUG_ON(bfqd->busy_queues != 0); + + return dispatched; +} + +static int bfq_dispatch_requests(struct request_queue *q, int force) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_queue *bfqq; + int max_dispatch; + + bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); + if (bfqd->busy_queues == 0) + return 0; + + if (unlikely(force)) + return bfq_forced_dispatch(bfqd); + + bfqq = bfq_select_queue(bfqd); + if (bfqq == NULL) + return 0; + + if (bfq_class_idle(bfqq)) + max_dispatch = 1; + + if (!bfq_bfqq_sync(bfqq)) + max_dispatch = bfqd->bfq_max_budget_async_rq; + + if (!bfq_bfqq_sync(bfqq) && bfqq->dispatched >= max_dispatch) { + if (bfqd->busy_queues > 1) + return 0; + if (bfqq->dispatched >= 4 * max_dispatch) + return 0; + } + + if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) + return 0; + + bfq_clear_bfqq_wait_request(bfqq); + BUG_ON(timer_pending(&bfqd->idle_slice_timer)); + + if (!bfq_dispatch_request(bfqd, bfqq)) + return 0; + + bfq_log_bfqq(bfqd, bfqq, "dispatched %s request", + bfq_bfqq_sync(bfqq) ? "sync" : "async"); + + return 1; +} + +/* + * Task holds one reference to the queue, dropped when task exits. Each rq + * in-flight on this queue also holds a reference, dropped when rq is freed. + * + * Queue lock must be held here. + */ +static void bfq_put_queue(struct bfq_queue *bfqq) +{ + struct bfq_data *bfqd = bfqq->bfqd; + + BUG_ON(atomic_read(&bfqq->ref) <= 0); + + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, + atomic_read(&bfqq->ref)); + if (!atomic_dec_and_test(&bfqq->ref)) + return; + + BUG_ON(rb_first(&bfqq->sort_list) != NULL); + BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); + BUG_ON(bfqq->entity.tree != NULL); + BUG_ON(bfq_bfqq_busy(bfqq)); + BUG_ON(bfqd->in_service_queue == bfqq); + + if (bfq_bfqq_sync(bfqq)) + /* + * The fact that this queue is being destroyed does not + * invalidate the fact that this queue may have been + * activated during the current burst. As a consequence, + * although the queue does not exist anymore, and hence + * needs to be removed from the burst list if there, + * the burst size has not to be decremented. + */ + hlist_del_init(&bfqq->burst_list_node); + + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); + + kmem_cache_free(bfq_pool, bfqq); +} + +static void bfq_put_cooperator(struct bfq_queue *bfqq) +{ + struct bfq_queue *__bfqq, *next; + + /* + * If this queue was scheduled to merge with another queue, be + * sure to drop the reference taken on that queue (and others in + * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. + */ + __bfqq = bfqq->new_bfqq; + while (__bfqq) { + if (__bfqq == bfqq) + break; + next = __bfqq->new_bfqq; + bfq_put_queue(__bfqq); + __bfqq = next; + } +} + +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + if (bfqq == bfqd->in_service_queue) { + __bfq_bfqq_expire(bfqd, bfqq); + bfq_schedule_dispatch(bfqd); + } + + bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, + atomic_read(&bfqq->ref)); + + bfq_put_cooperator(bfqq); + + bfq_put_queue(bfqq); +} + +static inline void bfq_init_icq(struct io_cq *icq) +{ + struct bfq_io_cq *bic = icq_to_bic(icq); + + bic->ttime.last_end_request = jiffies; + /* + * A newly created bic indicates that the process has just + * started doing I/O, and is probably mapping into memory its + * executable and libraries: it definitely needs weight raising. + * There is however the possibility that the process performs, + * for a while, I/O close to some other process. EQM intercepts + * this behavior and may merge the queue corresponding to the + * process with some other queue, BEFORE the weight of the queue + * is raised. Merged queues are not weight-raised (they are assumed + * to belong to processes that benefit only from high throughput). + * If the merge is basically the consequence of an accident, then + * the queue will be split soon and will get back its old weight. + * It is then important to write down somewhere that this queue + * does need weight raising, even if it did not make it to get its + * weight raised before being merged. To this purpose, we overload + * the field raising_time_left and assign 1 to it, to mark the queue + * as needing weight raising. + */ + bic->wr_time_left = 1; +} + +static void bfq_exit_icq(struct io_cq *icq) +{ + struct bfq_io_cq *bic = icq_to_bic(icq); + struct bfq_data *bfqd = bic_to_bfqd(bic); + + if (bic->bfqq[BLK_RW_ASYNC]) { + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); + bic->bfqq[BLK_RW_ASYNC] = NULL; + } + + if (bic->bfqq[BLK_RW_SYNC]) { + /* + * If the bic is using a shared queue, put the reference + * taken on the io_context when the bic started using a + * shared bfq_queue. + */ + if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC])) + put_io_context(icq->ioc); + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); + bic->bfqq[BLK_RW_SYNC] = NULL; + } +} + +/* + * Update the entity prio values; note that the new values will not + * be used until the next (re)activation. + */ +static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) +{ + struct task_struct *tsk = current; + int ioprio_class; + + ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); + switch (ioprio_class) { + default: + dev_err(bfqq->bfqd->queue->backing_dev_info.dev, + "bfq: bad prio class %d\n", ioprio_class); + case IOPRIO_CLASS_NONE: + /* + * No prio set, inherit CPU scheduling settings. + */ + bfqq->entity.new_ioprio = task_nice_ioprio(tsk); + bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); + break; + case IOPRIO_CLASS_RT: + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; + break; + case IOPRIO_CLASS_BE: + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; + break; + case IOPRIO_CLASS_IDLE: + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; + bfqq->entity.new_ioprio = 7; + bfq_clear_bfqq_idle_window(bfqq); + break; + } + + if (bfqq->entity.new_ioprio < 0 || + bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { + printk(KERN_CRIT "bfq_set_next_ioprio_data: new_ioprio %d\n", + bfqq->entity.new_ioprio); + BUG(); + } + + bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->entity.new_ioprio); + bfqq->entity.ioprio_changed = 1; +} + +static void bfq_check_ioprio_change(struct bfq_io_cq *bic) +{ + struct bfq_data *bfqd; + struct bfq_queue *bfqq, *new_bfqq; + struct bfq_group *bfqg; + unsigned long uninitialized_var(flags); + int ioprio = bic->icq.ioc->ioprio; + + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), + &flags); + /* + * This condition may trigger on a newly created bic, be sure to + * drop the lock before returning. + */ + if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio)) + goto out; + + bic->ioprio = ioprio; + + bfqq = bic->bfqq[BLK_RW_ASYNC]; + if (bfqq != NULL) { + bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, + sched_data); + new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic, + GFP_ATOMIC); + if (new_bfqq != NULL) { + bic->bfqq[BLK_RW_ASYNC] = new_bfqq; + bfq_log_bfqq(bfqd, bfqq, + "check_ioprio_change: bfqq %p %d", + bfqq, atomic_read(&bfqq->ref)); + bfq_put_queue(bfqq); + } + } + + bfqq = bic->bfqq[BLK_RW_SYNC]; + if (bfqq != NULL) + bfq_set_next_ioprio_data(bfqq, bic); + +out: + bfq_put_bfqd_unlock(bfqd, &flags); +} + +static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, + struct bfq_io_cq *bic, pid_t pid, int is_sync) +{ + RB_CLEAR_NODE(&bfqq->entity.rb_node); + INIT_LIST_HEAD(&bfqq->fifo); + INIT_HLIST_NODE(&bfqq->burst_list_node); + + atomic_set(&bfqq->ref, 0); + bfqq->bfqd = bfqd; + + if (bic) + bfq_set_next_ioprio_data(bfqq, bic); + + if (is_sync) { + if (!bfq_class_idle(bfqq)) + bfq_mark_bfqq_idle_window(bfqq); + bfq_mark_bfqq_sync(bfqq); + } + bfq_mark_bfqq_IO_bound(bfqq); + + /* Tentative initial value to trade off between thr and lat */ + bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; + bfqq->pid = pid; + + bfqq->wr_coeff = 1; + bfqq->last_wr_start_finish = 0; + /* + * Set to the value for which bfqq will not be deemed as + * soft rt when it becomes backlogged. + */ + bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); +} + +static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, + struct bfq_group *bfqg, + int is_sync, + struct bfq_io_cq *bic, + gfp_t gfp_mask) +{ + struct bfq_queue *bfqq, *new_bfqq = NULL; + +retry: + /* bic always exists here */ + bfqq = bic_to_bfqq(bic, is_sync); + + /* + * Always try a new alloc if we fall back to the OOM bfqq + * originally, since it should just be a temporary situation. + */ + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { + bfqq = NULL; + if (new_bfqq != NULL) { + bfqq = new_bfqq; + new_bfqq = NULL; + } else if (gfp_mask & __GFP_WAIT) { + spin_unlock_irq(bfqd->queue->queue_lock); + new_bfqq = kmem_cache_alloc_node(bfq_pool, + gfp_mask | __GFP_ZERO, + bfqd->queue->node); + spin_lock_irq(bfqd->queue->queue_lock); + if (new_bfqq != NULL) + goto retry; + } else { + bfqq = kmem_cache_alloc_node(bfq_pool, + gfp_mask | __GFP_ZERO, + bfqd->queue->node); + } + + if (bfqq != NULL) { + bfq_init_bfqq(bfqd, bfqq, bic, current->pid, + is_sync); + bfq_init_entity(&bfqq->entity, bfqg); + bfq_log_bfqq(bfqd, bfqq, "allocated"); + } else { + bfqq = &bfqd->oom_bfqq; + bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); + } + } + + if (new_bfqq != NULL) + kmem_cache_free(bfq_pool, new_bfqq); + + return bfqq; +} + +static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, + struct bfq_group *bfqg, + int ioprio_class, int ioprio) +{ + switch (ioprio_class) { + case IOPRIO_CLASS_RT: + return &bfqg->async_bfqq[0][ioprio]; + case IOPRIO_CLASS_NONE: + ioprio = IOPRIO_NORM; + /* fall through */ + case IOPRIO_CLASS_BE: + return &bfqg->async_bfqq[1][ioprio]; + case IOPRIO_CLASS_IDLE: + return &bfqg->async_idle_bfqq; + default: + BUG(); + } +} + +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, + struct bfq_group *bfqg, int is_sync, + struct bfq_io_cq *bic, gfp_t gfp_mask) +{ + const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); + const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); + struct bfq_queue **async_bfqq = NULL; + struct bfq_queue *bfqq = NULL; + + if (!is_sync) { + async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, + ioprio); + bfqq = *async_bfqq; + } + + if (bfqq == NULL) + bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask); + + /* + * Pin the queue now that it's allocated, scheduler exit will + * prune it. + */ + if (!is_sync && *async_bfqq == NULL) { + atomic_inc(&bfqq->ref); + bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", + bfqq, atomic_read(&bfqq->ref)); + *async_bfqq = bfqq; + } + + atomic_inc(&bfqq->ref); + bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, + atomic_read(&bfqq->ref)); + return bfqq; +} + +static void bfq_update_io_thinktime(struct bfq_data *bfqd, + struct bfq_io_cq *bic) +{ + unsigned long elapsed = jiffies - bic->ttime.last_end_request; + unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); + + bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; + bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; + bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / + bic->ttime.ttime_samples; +} + +static void bfq_update_io_seektime(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + struct request *rq) +{ + sector_t sdist; + u64 total; + + if (bfqq->last_request_pos < blk_rq_pos(rq)) + sdist = blk_rq_pos(rq) - bfqq->last_request_pos; + else + sdist = bfqq->last_request_pos - blk_rq_pos(rq); + + /* + * Don't allow the seek distance to get too large from the + * odd fragment, pagein, etc. + */ + if (bfqq->seek_samples == 0) /* first request, not really a seek */ + sdist = 0; + else if (bfqq->seek_samples <= 60) /* second & third seek */ + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); + else + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); + + bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; + bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; + total = bfqq->seek_total + (bfqq->seek_samples/2); + do_div(total, bfqq->seek_samples); + bfqq->seek_mean = (sector_t)total; + + bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, + (u64)bfqq->seek_mean); +} + +/* + * Disable idle window if the process thinks too long or seeks so much that + * it doesn't matter. + */ +static void bfq_update_idle_window(struct bfq_data *bfqd, + struct bfq_queue *bfqq, + struct bfq_io_cq *bic) +{ + int enable_idle; + + /* Don't idle for async or idle io prio class. */ + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) + return; + + /* Idle window just restored, statistics are meaningless. */ + if (bfq_bfqq_just_split(bfqq)) + return; + + enable_idle = bfq_bfqq_idle_window(bfqq); + + if (atomic_read(&bic->icq.ioc->active_ref) == 0 || + bfqd->bfq_slice_idle == 0 || + (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && + bfqq->wr_coeff == 1)) + enable_idle = 0; + else if (bfq_sample_valid(bic->ttime.ttime_samples)) { + if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && + bfqq->wr_coeff == 1) + enable_idle = 0; + else + enable_idle = 1; + } + bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", + enable_idle); + + if (enable_idle) + bfq_mark_bfqq_idle_window(bfqq); + else + bfq_clear_bfqq_idle_window(bfqq); +} + +/* + * Called when a new fs request (rq) is added to bfqq. Check if there's + * something we should do about it. + */ +static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + struct request *rq) +{ + struct bfq_io_cq *bic = RQ_BIC(rq); + + if (rq->cmd_flags & REQ_META) + bfqq->meta_pending++; + + bfq_update_io_thinktime(bfqd, bic); + bfq_update_io_seektime(bfqd, bfqq, rq); + if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { + bfq_clear_bfqq_constantly_seeky(bfqq); + if (!blk_queue_nonrot(bfqd->queue)) { + BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); + bfqd->const_seeky_busy_in_flight_queues--; + } + } + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || + !BFQQ_SEEKY(bfqq)) + bfq_update_idle_window(bfqd, bfqq, bic); + bfq_clear_bfqq_just_split(bfqq); + + bfq_log_bfqq(bfqd, bfqq, + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", + bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), + (long long unsigned)bfqq->seek_mean); + + bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); + + if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { + int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && + blk_rq_sectors(rq) < 32; + int budget_timeout = bfq_bfqq_budget_timeout(bfqq); + + /* + * There is just this request queued: if the request + * is small and the queue is not to be expired, then + * just exit. + * + * In this way, if the disk is being idled to wait for + * a new request from the in-service queue, we avoid + * unplugging the device and committing the disk to serve + * just a small request. On the contrary, we wait for + * the block layer to decide when to unplug the device: + * hopefully, new requests will be merged to this one + * quickly, then the device will be unplugged and + * larger requests will be dispatched. + */ + if (small_req && !budget_timeout) + return; + + /* + * A large enough request arrived, or the queue is to + * be expired: in both cases disk idling is to be + * stopped, so clear wait_request flag and reset + * timer. + */ + bfq_clear_bfqq_wait_request(bfqq); + del_timer(&bfqd->idle_slice_timer); + + /* + * The queue is not empty, because a new request just + * arrived. Hence we can safely expire the queue, in + * case of budget timeout, without risking that the + * timestamps of the queue are not updated correctly. + * See [1] for more details. + */ + if (budget_timeout) + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); + + /* + * Let the request rip immediately, or let a new queue be + * selected if bfqq has just been expired. + */ + __blk_run_queue(bfqd->queue); + } +} + +static void bfq_insert_request(struct request_queue *q, struct request *rq) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; + + assert_spin_locked(bfqd->queue->queue_lock); + + /* + * An unplug may trigger a requeue of a request from the device + * driver: make sure we are in process context while trying to + * merge two bfq_queues. + */ + if (!in_interrupt()) { + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); + if (new_bfqq != NULL) { + if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) + new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); + /* + * Release the request's reference to the old bfqq + * and make sure one is taken to the shared queue. + */ + new_bfqq->allocated[rq_data_dir(rq)]++; + bfqq->allocated[rq_data_dir(rq)]--; + atomic_inc(&new_bfqq->ref); + bfq_put_queue(bfqq); + if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) + bfq_merge_bfqqs(bfqd, RQ_BIC(rq), + bfqq, new_bfqq); + rq->elv.priv[1] = new_bfqq; + bfqq = new_bfqq; + } else + bfq_bfqq_increase_failed_cooperations(bfqq); + } + + bfq_add_request(rq); + + /* + * Here a newly-created bfq_queue has already started a weight-raising + * period: clear raising_time_left to prevent bfq_bfqq_save_state() + * from assigning it a full weight-raising period. See the detailed + * comments about this field in bfq_init_icq(). + */ + if (bfqq->bic != NULL) + bfqq->bic->wr_time_left = 0; + rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]); + list_add_tail(&rq->queuelist, &bfqq->fifo); + + bfq_rq_enqueued(bfqd, bfqq, rq); +} + +static void bfq_update_hw_tag(struct bfq_data *bfqd) +{ + bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, + bfqd->rq_in_driver); + + if (bfqd->hw_tag == 1) + return; + + /* + * This sample is valid if the number of outstanding requests + * is large enough to allow a queueing behavior. Note that the + * sum is not exact, as it's not taking into account deactivated + * requests. + */ + if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) + return; + + if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) + return; + + bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; + bfqd->max_rq_in_driver = 0; + bfqd->hw_tag_samples = 0; +} + +static void bfq_completed_request(struct request_queue *q, struct request *rq) +{ + struct bfq_queue *bfqq = RQ_BFQQ(rq); + struct bfq_data *bfqd = bfqq->bfqd; + bool sync = bfq_bfqq_sync(bfqq); + + bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", + blk_rq_sectors(rq), sync); + + bfq_update_hw_tag(bfqd); + + BUG_ON(!bfqd->rq_in_driver); + BUG_ON(!bfqq->dispatched); + bfqd->rq_in_driver--; + bfqq->dispatched--; + + if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { + bfq_weights_tree_remove(bfqd, &bfqq->entity, + &bfqd->queue_weights_tree); + if (!blk_queue_nonrot(bfqd->queue)) { + BUG_ON(!bfqd->busy_in_flight_queues); + bfqd->busy_in_flight_queues--; + if (bfq_bfqq_constantly_seeky(bfqq)) { + BUG_ON(!bfqd-> + const_seeky_busy_in_flight_queues); + bfqd->const_seeky_busy_in_flight_queues--; + } + } + } + + if (sync) { + bfqd->sync_flight--; + RQ_BIC(rq)->ttime.last_end_request = jiffies; + } + + /* + * If we are waiting to discover whether the request pattern of the + * task associated with the queue is actually isochronous, and + * both requisites for this condition to hold are satisfied, then + * compute soft_rt_next_start (see the comments to the function + * bfq_bfqq_softrt_next_start()). + */ + if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && + RB_EMPTY_ROOT(&bfqq->sort_list)) + bfqq->soft_rt_next_start = + bfq_bfqq_softrt_next_start(bfqd, bfqq); + + /* + * If this is the in-service queue, check if it needs to be expired, + * or if we want to idle in case it has no pending requests. + */ + if (bfqd->in_service_queue == bfqq) { + if (bfq_bfqq_budget_new(bfqq)) + bfq_set_budget_timeout(bfqd); + + if (bfq_bfqq_must_idle(bfqq)) { + bfq_arm_slice_timer(bfqd); + goto out; + } else if (bfq_may_expire_for_budg_timeout(bfqq)) + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); + else if (RB_EMPTY_ROOT(&bfqq->sort_list) && + (bfqq->dispatched == 0 || + !bfq_bfqq_must_not_expire(bfqq))) + bfq_bfqq_expire(bfqd, bfqq, 0, + BFQ_BFQQ_NO_MORE_REQUESTS); + } + + if (!bfqd->rq_in_driver) + bfq_schedule_dispatch(bfqd); + +out: + return; +} + +static inline int __bfq_may_queue(struct bfq_queue *bfqq) +{ + if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { + bfq_clear_bfqq_must_alloc(bfqq); + return ELV_MQUEUE_MUST; + } + + return ELV_MQUEUE_MAY; +} + +static int bfq_may_queue(struct request_queue *q, int rw) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct task_struct *tsk = current; + struct bfq_io_cq *bic; + struct bfq_queue *bfqq; + + /* + * Don't force setup of a queue from here, as a call to may_queue + * does not necessarily imply that a request actually will be + * queued. So just lookup a possibly existing queue, or return + * 'may queue' if that fails. + */ + bic = bfq_bic_lookup(bfqd, tsk->io_context); + if (bic == NULL) + return ELV_MQUEUE_MAY; + + bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); + if (bfqq != NULL) + return __bfq_may_queue(bfqq); + + return ELV_MQUEUE_MAY; +} + +/* + * Queue lock held here. + */ +static void bfq_put_request(struct request *rq) +{ + struct bfq_queue *bfqq = RQ_BFQQ(rq); + + if (bfqq != NULL) { + const int rw = rq_data_dir(rq); + + BUG_ON(!bfqq->allocated[rw]); + bfqq->allocated[rw]--; + + rq->elv.priv[0] = NULL; + rq->elv.priv[1] = NULL; + + bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", + bfqq, atomic_read(&bfqq->ref)); + bfq_put_queue(bfqq); + } +} + +/* + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this + * was the last process referring to said bfqq. + */ +static struct bfq_queue * +bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) +{ + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); + + put_io_context(bic->icq.ioc); + + if (bfqq_process_refs(bfqq) == 1) { + bfqq->pid = current->pid; + bfq_clear_bfqq_coop(bfqq); + bfq_clear_bfqq_split_coop(bfqq); + return bfqq; + } + + bic_set_bfqq(bic, NULL, 1); + + bfq_put_cooperator(bfqq); + + bfq_put_queue(bfqq); + return NULL; +} + +/* + * Allocate bfq data structures associated with this request. + */ +static int bfq_set_request(struct request_queue *q, struct request *rq, + struct bio *bio, gfp_t gfp_mask) +{ + struct bfq_data *bfqd = q->elevator->elevator_data; + struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); + const int rw = rq_data_dir(rq); + const int is_sync = rq_is_sync(rq); + struct bfq_queue *bfqq; + struct bfq_group *bfqg; + unsigned long flags; + bool split = false; + + might_sleep_if(gfp_mask & __GFP_WAIT); + + bfq_check_ioprio_change(bic); + + spin_lock_irqsave(q->queue_lock, flags); + + if (bic == NULL) + goto queue_fail; + + bfqg = bfq_bic_update_cgroup(bic); + +new_queue: + bfqq = bic_to_bfqq(bic, is_sync); + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); + bic_set_bfqq(bic, bfqq, is_sync); + if (split && is_sync) { + if ((bic->was_in_burst_list && bfqd->large_burst) || + bic->saved_in_large_burst) + bfq_mark_bfqq_in_large_burst(bfqq); + else { + bfq_clear_bfqq_in_large_burst(bfqq); + if (bic->was_in_burst_list) + hlist_add_head(&bfqq->burst_list_node, + &bfqd->burst_list); + } + } + } else { + /* If the queue was seeky for too long, break it apart. */ + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); + bfqq = bfq_split_bfqq(bic, bfqq); + split = true; + if (!bfqq) + goto new_queue; + } + } + + bfqq->allocated[rw]++; + atomic_inc(&bfqq->ref); + bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, + atomic_read(&bfqq->ref)); + + rq->elv.priv[0] = bic; + rq->elv.priv[1] = bfqq; + + /* + * If a bfq_queue has only one process reference, it is owned + * by only one bfq_io_cq: we can set the bic field of the + * bfq_queue to the address of that structure. Also, if the + * queue has just been split, mark a flag so that the + * information is available to the other scheduler hooks. + */ + if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { + bfqq->bic = bic; + if (split) { + bfq_mark_bfqq_just_split(bfqq); + /* + * If the queue has just been split from a shared + * queue, restore the idle window and the possible + * weight raising period. + */ + bfq_bfqq_resume_state(bfqq, bic); + } + } + + spin_unlock_irqrestore(q->queue_lock, flags); + + return 0; + +queue_fail: + bfq_schedule_dispatch(bfqd); + spin_unlock_irqrestore(q->queue_lock, flags); + + return 1; +} + +static void bfq_kick_queue(struct work_struct *work) +{ + struct bfq_data *bfqd = + container_of(work, struct bfq_data, unplug_work); + struct request_queue *q = bfqd->queue; + + spin_lock_irq(q->queue_lock); + __blk_run_queue(q); + spin_unlock_irq(q->queue_lock); +} + +/* + * Handler of the expiration of the timer running if the in-service queue + * is idling inside its time slice. + */ +static void bfq_idle_slice_timer(unsigned long data) +{ + struct bfq_data *bfqd = (struct bfq_data *)data; + struct bfq_queue *bfqq; + unsigned long flags; + enum bfqq_expiration reason; + + spin_lock_irqsave(bfqd->queue->queue_lock, flags); + + bfqq = bfqd->in_service_queue; + /* + * Theoretical race here: the in-service queue can be NULL or + * different from the queue that was idling if the timer handler + * spins on the queue_lock and a new request arrives for the + * current queue and there is a full dispatch cycle that changes + * the in-service queue. This can hardly happen, but in the worst + * case we just expire a queue too early. + */ + if (bfqq != NULL) { + bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); + if (bfq_bfqq_budget_timeout(bfqq)) + /* + * Also here the queue can be safely expired + * for budget timeout without wasting + * guarantees + */ + reason = BFQ_BFQQ_BUDGET_TIMEOUT; + else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) + /* + * The queue may not be empty upon timer expiration, + * because we may not disable the timer when the + * first request of the in-service queue arrives + * during disk idling. + */ + reason = BFQ_BFQQ_TOO_IDLE; + else + goto schedule_dispatch; + + bfq_bfqq_expire(bfqd, bfqq, 1, reason); + } + +schedule_dispatch: + bfq_schedule_dispatch(bfqd); + + spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); +} + +static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) +{ + del_timer_sync(&bfqd->idle_slice_timer); + cancel_work_sync(&bfqd->unplug_work); +} + +static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, + struct bfq_queue **bfqq_ptr) +{ + struct bfq_group *root_group = bfqd->root_group; + struct bfq_queue *bfqq = *bfqq_ptr; + + bfq_log(bfqd, "put_async_bfqq: %p", bfqq); + if (bfqq != NULL) { + bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); + bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", + bfqq, atomic_read(&bfqq->ref)); + bfq_put_queue(bfqq); + *bfqq_ptr = NULL; + } +} + +/* + * Release all the bfqg references to its async queues. If we are + * deallocating the group these queues may still contain requests, so + * we reparent them to the root cgroup (i.e., the only one that will + * exist for sure until all the requests on a device are gone). + */ +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) +{ + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < IOPRIO_BE_NR; j++) + __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); + + __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); +} + +static void bfq_exit_queue(struct elevator_queue *e) +{ + struct bfq_data *bfqd = e->elevator_data; + struct request_queue *q = bfqd->queue; + struct bfq_queue *bfqq, *n; + + bfq_shutdown_timer_wq(bfqd); + + spin_lock_irq(q->queue_lock); + + BUG_ON(bfqd->in_service_queue != NULL); + list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) + bfq_deactivate_bfqq(bfqd, bfqq, 0); + + bfq_disconnect_groups(bfqd); + spin_unlock_irq(q->queue_lock); + + bfq_shutdown_timer_wq(bfqd); + + synchronize_rcu(); + + BUG_ON(timer_pending(&bfqd->idle_slice_timer)); + + bfq_free_root_group(bfqd); + kfree(bfqd); +} + +static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) +{ + struct bfq_group *bfqg; + struct bfq_data *bfqd; + struct elevator_queue *eq; + + eq = elevator_alloc(q, e); + if (eq == NULL) + return -ENOMEM; + + bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); + if (bfqd == NULL) { + kobject_put(&eq->kobj); + return -ENOMEM; + } + eq->elevator_data = bfqd; + + /* + * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. + * Grab a permanent reference to it, so that the normal code flow + * will not attempt to free it. + */ + bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0); + atomic_inc(&bfqd->oom_bfqq.ref); + bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; + bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; + bfqd->oom_bfqq.entity.new_weight = + bfq_ioprio_to_weight(bfqd->oom_bfqq.entity.new_ioprio); + /* + * Trigger weight initialization, according to ioprio, at the + * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio + * class won't be changed any more. + */ + bfqd->oom_bfqq.entity.ioprio_changed = 1; + + bfqd->queue = q; + + spin_lock_irq(q->queue_lock); + q->elevator = eq; + spin_unlock_irq(q->queue_lock); + + bfqg = bfq_alloc_root_group(bfqd, q->node); + if (bfqg == NULL) { + kfree(bfqd); + kobject_put(&eq->kobj); + return -ENOMEM; + } + + bfqd->root_group = bfqg; + bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); +#ifdef CONFIG_CGROUP_BFQIO + bfqd->active_numerous_groups = 0; +#endif + + init_timer(&bfqd->idle_slice_timer); + bfqd->idle_slice_timer.function = bfq_idle_slice_timer; + bfqd->idle_slice_timer.data = (unsigned long)bfqd; + + bfqd->rq_pos_tree = RB_ROOT; + bfqd->queue_weights_tree = RB_ROOT; + bfqd->group_weights_tree = RB_ROOT; + + INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); + + INIT_LIST_HEAD(&bfqd->active_list); + INIT_LIST_HEAD(&bfqd->idle_list); + INIT_HLIST_HEAD(&bfqd->burst_list); + + bfqd->hw_tag = -1; + + bfqd->bfq_max_budget = bfq_default_max_budget; + + bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; + bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; + bfqd->bfq_back_max = bfq_back_max; + bfqd->bfq_back_penalty = bfq_back_penalty; + bfqd->bfq_slice_idle = bfq_slice_idle; + bfqd->bfq_class_idle_last_service = 0; + bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; + bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; + bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; + + bfqd->bfq_coop_thresh = 2; + bfqd->bfq_failed_cooperations = 7000; + bfqd->bfq_requests_within_timer = 120; + + bfqd->bfq_large_burst_thresh = 11; + bfqd->bfq_burst_interval = msecs_to_jiffies(500); + + bfqd->low_latency = true; + + bfqd->bfq_wr_coeff = 20; + bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); + bfqd->bfq_wr_max_time = 0; + bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); + bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); + bfqd->bfq_wr_max_softrt_rate = 7000; /* + * Approximate rate required + * to playback or record a + * high-definition compressed + * video. + */ + bfqd->wr_busy_queues = 0; + bfqd->busy_in_flight_queues = 0; + bfqd->const_seeky_busy_in_flight_queues = 0; + + /* + * Begin by assuming, optimistically, that the device peak rate is + * equal to the highest reference rate. + */ + bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * + T_fast[blk_queue_nonrot(bfqd->queue)]; + bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; + bfqd->device_speed = BFQ_BFQD_FAST; + + return 0; +} + +static void bfq_slab_kill(void) +{ + if (bfq_pool != NULL) + kmem_cache_destroy(bfq_pool); +} + +static int __init bfq_slab_setup(void) +{ + bfq_pool = KMEM_CACHE(bfq_queue, 0); + if (bfq_pool == NULL) + return -ENOMEM; + return 0; +} + +static ssize_t bfq_var_show(unsigned int var, char *page) +{ + return sprintf(page, "%d\n", var); +} + +static ssize_t bfq_var_store(unsigned long *var, const char *page, + size_t count) +{ + unsigned long new_val; + int ret = kstrtoul(page, 10, &new_val); + + if (ret == 0) + *var = new_val; + + return count; +} + +static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) +{ + struct bfq_data *bfqd = e->elevator_data; + return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? + jiffies_to_msecs(bfqd->bfq_wr_max_time) : + jiffies_to_msecs(bfq_wr_duration(bfqd))); +} + +static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) +{ + struct bfq_queue *bfqq; + struct bfq_data *bfqd = e->elevator_data; + ssize_t num_char = 0; + + num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", + bfqd->queued); + + spin_lock_irq(bfqd->queue->queue_lock); + + num_char += sprintf(page + num_char, "Active:\n"); + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { + num_char += sprintf(page + num_char, + "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", + bfqq->pid, + bfqq->entity.weight, + bfqq->queued[0], + bfqq->queued[1], + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), + jiffies_to_msecs(bfqq->wr_cur_max_time)); + } + + num_char += sprintf(page + num_char, "Idle:\n"); + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { + num_char += sprintf(page + num_char, + "pid%d: weight %hu, dur %d/%u\n", + bfqq->pid, + bfqq->entity.weight, + jiffies_to_msecs(jiffies - + bfqq->last_wr_start_finish), + jiffies_to_msecs(bfqq->wr_cur_max_time)); + } + + spin_unlock_irq(bfqd->queue->queue_lock); + + return num_char; +} + +#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ +static ssize_t __FUNC(struct elevator_queue *e, char *page) \ +{ \ + struct bfq_data *bfqd = e->elevator_data; \ + unsigned int __data = __VAR; \ + if (__CONV) \ + __data = jiffies_to_msecs(__data); \ + return bfq_var_show(__data, (page)); \ +} +SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); +SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); +SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); +SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); +SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); +SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); +SHOW_FUNCTION(bfq_max_budget_async_rq_show, + bfqd->bfq_max_budget_async_rq, 0); +SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); +SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); +SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); +SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); +SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); +SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); +SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, + 1); +SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); +#undef SHOW_FUNCTION + +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ +static ssize_t \ +__FUNC(struct elevator_queue *e, const char *page, size_t count) \ +{ \ + struct bfq_data *bfqd = e->elevator_data; \ + unsigned long uninitialized_var(__data); \ + int ret = bfq_var_store(&__data, (page), count); \ + if (__data < (MIN)) \ + __data = (MIN); \ + else if (__data > (MAX)) \ + __data = (MAX); \ + if (__CONV) \ + *(__PTR) = msecs_to_jiffies(__data); \ + else \ + *(__PTR) = __data; \ + return ret; \ +} +STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, + INT_MAX, 1); +STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, + INT_MAX, 1); +STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); +STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, + INT_MAX, 0); +STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); +STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, + 1, INT_MAX, 0); +STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, + INT_MAX, 1); +STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); +STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); +STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, + 1); +STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, + INT_MAX, 1); +STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, + &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); +STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, + INT_MAX, 0); +#undef STORE_FUNCTION + +/* do nothing for the moment */ +static ssize_t bfq_weights_store(struct elevator_queue *e, + const char *page, size_t count) +{ + return count; +} + +static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) +{ + u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); + + if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) + return bfq_calc_max_budget(bfqd->peak_rate, timeout); + else + return bfq_default_max_budget; +} + +static ssize_t bfq_max_budget_store(struct elevator_queue *e, + const char *page, size_t count) +{ + struct bfq_data *bfqd = e->elevator_data; + unsigned long uninitialized_var(__data); + int ret = bfq_var_store(&__data, (page), count); + + if (__data == 0) + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); + else { + if (__data > INT_MAX) + __data = INT_MAX; + bfqd->bfq_max_budget = __data; + } + + bfqd->bfq_user_max_budget = __data; + + return ret; +} + +static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, + const char *page, size_t count) +{ + struct bfq_data *bfqd = e->elevator_data; + unsigned long uninitialized_var(__data); + int ret = bfq_var_store(&__data, (page), count); + + if (__data < 1) + __data = 1; + else if (__data > INT_MAX) + __data = INT_MAX; + + bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); + if (bfqd->bfq_user_max_budget == 0) + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); + + return ret; +} + +static ssize_t bfq_low_latency_store(struct elevator_queue *e, + const char *page, size_t count) +{ + struct bfq_data *bfqd = e->elevator_data; + unsigned long uninitialized_var(__data); + int ret = bfq_var_store(&__data, (page), count); + + if (__data > 1) + __data = 1; + if (__data == 0 && bfqd->low_latency != 0) + bfq_end_wr(bfqd); + bfqd->low_latency = __data; + + return ret; +} + +#define BFQ_ATTR(name) \ + __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) + +static struct elv_fs_entry bfq_attrs[] = { + BFQ_ATTR(fifo_expire_sync), + BFQ_ATTR(fifo_expire_async), + BFQ_ATTR(back_seek_max), + BFQ_ATTR(back_seek_penalty), + BFQ_ATTR(slice_idle), + BFQ_ATTR(max_budget), + BFQ_ATTR(max_budget_async_rq), + BFQ_ATTR(timeout_sync), + BFQ_ATTR(timeout_async), + BFQ_ATTR(low_latency), + BFQ_ATTR(wr_coeff), + BFQ_ATTR(wr_max_time), + BFQ_ATTR(wr_rt_max_time), + BFQ_ATTR(wr_min_idle_time), + BFQ_ATTR(wr_min_inter_arr_async), + BFQ_ATTR(wr_max_softrt_rate), + BFQ_ATTR(weights), + __ATTR_NULL +}; + +static struct elevator_type iosched_bfq = { + .ops = { + .elevator_merge_fn = bfq_merge, + .elevator_merged_fn = bfq_merged_request, + .elevator_merge_req_fn = bfq_merged_requests, + .elevator_allow_merge_fn = bfq_allow_merge, + .elevator_dispatch_fn = bfq_dispatch_requests, + .elevator_add_req_fn = bfq_insert_request, + .elevator_activate_req_fn = bfq_activate_request, + .elevator_deactivate_req_fn = bfq_deactivate_request, + .elevator_completed_req_fn = bfq_completed_request, + .elevator_former_req_fn = elv_rb_former_request, + .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_init_icq_fn = bfq_init_icq, + .elevator_exit_icq_fn = bfq_exit_icq, + .elevator_set_req_fn = bfq_set_request, + .elevator_put_req_fn = bfq_put_request, + .elevator_may_queue_fn = bfq_may_queue, + .elevator_init_fn = bfq_init_queue, + .elevator_exit_fn = bfq_exit_queue, + }, + .icq_size = sizeof(struct bfq_io_cq), + .icq_align = __alignof__(struct bfq_io_cq), + .elevator_attrs = bfq_attrs, + .elevator_name = "bfq", + .elevator_owner = THIS_MODULE, +}; + +static int __init bfq_init(void) +{ + /* + * Can be 0 on HZ < 1000 setups. + */ + if (bfq_slice_idle == 0) + bfq_slice_idle = 1; + + if (bfq_timeout_async == 0) + bfq_timeout_async = 1; + + if (bfq_slab_setup()) + return -ENOMEM; + + /* + * Times to load large popular applications for the typical systems + * installed on the reference devices (see the comments before the + * definitions of the two arrays). + */ + T_slow[0] = msecs_to_jiffies(2600); + T_slow[1] = msecs_to_jiffies(1000); + T_fast[0] = msecs_to_jiffies(5500); + T_fast[1] = msecs_to_jiffies(2000); + + /* + * Thresholds that determine the switch between speed classes (see + * the comments before the definition of the array). + */ + device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; + device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; + + elv_register(&iosched_bfq); + pr_info("BFQ I/O-scheduler: v7r8"); + + return 0; +} + +static void __exit bfq_exit(void) +{ + elv_unregister(&iosched_bfq); + bfq_slab_kill(); +} + +module_init(bfq_init); +module_exit(bfq_exit); + +MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); +MODULE_LICENSE("GPL"); diff --git a/block/bfq-sched.c b/block/bfq-sched.c new file mode 100644 index 0000000000000..d0890c6d4c114 --- /dev/null +++ b/block/bfq-sched.c @@ -0,0 +1,1180 @@ +/* + * BFQ: Hierarchical B-WF2Q+ scheduler. + * + * Based on ideas and code from CFQ: + * Copyright (C) 2003 Jens Axboe + * + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * + * Copyright (C) 2010 Paolo Valente + */ + +#ifdef CONFIG_CGROUP_BFQIO +#define for_each_entity(entity) \ + for (; entity != NULL; entity = entity->parent) + +#define for_each_entity_safe(entity, parent) \ + for (; entity && ({ parent = entity->parent; 1; }); entity = parent) + +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, + int extract, + struct bfq_data *bfqd); + +static inline void bfq_update_budget(struct bfq_entity *next_in_service) +{ + struct bfq_entity *bfqg_entity; + struct bfq_group *bfqg; + struct bfq_sched_data *group_sd; + + BUG_ON(next_in_service == NULL); + + group_sd = next_in_service->sched_data; + + bfqg = container_of(group_sd, struct bfq_group, sched_data); + /* + * bfq_group's my_entity field is not NULL only if the group + * is not the root group. We must not touch the root entity + * as it must never become an in-service entity. + */ + bfqg_entity = bfqg->my_entity; + if (bfqg_entity != NULL) + bfqg_entity->budget = next_in_service->budget; +} + +static int bfq_update_next_in_service(struct bfq_sched_data *sd) +{ + struct bfq_entity *next_in_service; + + if (sd->in_service_entity != NULL) + /* will update/requeue at the end of service */ + return 0; + + /* + * NOTE: this can be improved in many ways, such as returning + * 1 (and thus propagating upwards the update) only when the + * budget changes, or caching the bfqq that will be scheduled + * next from this subtree. By now we worry more about + * correctness than about performance... + */ + next_in_service = bfq_lookup_next_entity(sd, 0, NULL); + sd->next_in_service = next_in_service; + + if (next_in_service != NULL) + bfq_update_budget(next_in_service); + + return 1; +} + +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, + struct bfq_entity *entity) +{ + BUG_ON(sd->next_in_service != entity); +} +#else +#define for_each_entity(entity) \ + for (; entity != NULL; entity = NULL) + +#define for_each_entity_safe(entity, parent) \ + for (parent = NULL; entity != NULL; entity = parent) + +static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) +{ + return 0; +} + +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, + struct bfq_entity *entity) +{ +} + +static inline void bfq_update_budget(struct bfq_entity *next_in_service) +{ +} +#endif + +/* + * Shift for timestamp calculations. This actually limits the maximum + * service allowed in one timestamp delta (small shift values increase it), + * the maximum total weight that can be used for the queues in the system + * (big shift values increase it), and the period of virtual time + * wraparounds. + */ +#define WFQ_SERVICE_SHIFT 22 + +/** + * bfq_gt - compare two timestamps. + * @a: first ts. + * @b: second ts. + * + * Return @a > @b, dealing with wrapping correctly. + */ +static inline int bfq_gt(u64 a, u64 b) +{ + return (s64)(a - b) > 0; +} + +static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = NULL; + + BUG_ON(entity == NULL); + + if (entity->my_sched_data == NULL) + bfqq = container_of(entity, struct bfq_queue, entity); + + return bfqq; +} + + +/** + * bfq_delta - map service into the virtual time domain. + * @service: amount of service. + * @weight: scale factor (weight of an entity or weight sum). + */ +static inline u64 bfq_delta(unsigned long service, + unsigned long weight) +{ + u64 d = (u64)service << WFQ_SERVICE_SHIFT; + + do_div(d, weight); + return d; +} + +/** + * bfq_calc_finish - assign the finish time to an entity. + * @entity: the entity to act upon. + * @service: the service to be charged to the entity. + */ +static inline void bfq_calc_finish(struct bfq_entity *entity, + unsigned long service) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + + BUG_ON(entity->weight == 0); + + entity->finish = entity->start + + bfq_delta(service, entity->weight); + + if (bfqq != NULL) { + bfq_log_bfqq(bfqq->bfqd, bfqq, + "calc_finish: serv %lu, w %d", + service, entity->weight); + bfq_log_bfqq(bfqq->bfqd, bfqq, + "calc_finish: start %llu, finish %llu, delta %llu", + entity->start, entity->finish, + bfq_delta(service, entity->weight)); + } +} + +/** + * bfq_entity_of - get an entity from a node. + * @node: the node field of the entity. + * + * Convert a node pointer to the relative entity. This is used only + * to simplify the logic of some functions and not as the generic + * conversion mechanism because, e.g., in the tree walking functions, + * the check for a %NULL value would be redundant. + */ +static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) +{ + struct bfq_entity *entity = NULL; + + if (node != NULL) + entity = rb_entry(node, struct bfq_entity, rb_node); + + return entity; +} + +/** + * bfq_extract - remove an entity from a tree. + * @root: the tree root. + * @entity: the entity to remove. + */ +static inline void bfq_extract(struct rb_root *root, + struct bfq_entity *entity) +{ + BUG_ON(entity->tree != root); + + entity->tree = NULL; + rb_erase(&entity->rb_node, root); +} + +/** + * bfq_idle_extract - extract an entity from the idle tree. + * @st: the service tree of the owning @entity. + * @entity: the entity being removed. + */ +static void bfq_idle_extract(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct rb_node *next; + + BUG_ON(entity->tree != &st->idle); + + if (entity == st->first_idle) { + next = rb_next(&entity->rb_node); + st->first_idle = bfq_entity_of(next); + } + + if (entity == st->last_idle) { + next = rb_prev(&entity->rb_node); + st->last_idle = bfq_entity_of(next); + } + + bfq_extract(&st->idle, entity); + + if (bfqq != NULL) + list_del(&bfqq->bfqq_list); +} + +/** + * bfq_insert - generic tree insertion. + * @root: tree root. + * @entity: entity to insert. + * + * This is used for the idle and the active tree, since they are both + * ordered by finish time. + */ +static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) +{ + struct bfq_entity *entry; + struct rb_node **node = &root->rb_node; + struct rb_node *parent = NULL; + + BUG_ON(entity->tree != NULL); + + while (*node != NULL) { + parent = *node; + entry = rb_entry(parent, struct bfq_entity, rb_node); + + if (bfq_gt(entry->finish, entity->finish)) + node = &parent->rb_left; + else + node = &parent->rb_right; + } + + rb_link_node(&entity->rb_node, parent, node); + rb_insert_color(&entity->rb_node, root); + + entity->tree = root; +} + +/** + * bfq_update_min - update the min_start field of a entity. + * @entity: the entity to update. + * @node: one of its children. + * + * This function is called when @entity may store an invalid value for + * min_start due to updates to the active tree. The function assumes + * that the subtree rooted at @node (which may be its left or its right + * child) has a valid min_start value. + */ +static inline void bfq_update_min(struct bfq_entity *entity, + struct rb_node *node) +{ + struct bfq_entity *child; + + if (node != NULL) { + child = rb_entry(node, struct bfq_entity, rb_node); + if (bfq_gt(entity->min_start, child->min_start)) + entity->min_start = child->min_start; + } +} + +/** + * bfq_update_active_node - recalculate min_start. + * @node: the node to update. + * + * @node may have changed position or one of its children may have moved, + * this function updates its min_start value. The left and right subtrees + * are assumed to hold a correct min_start value. + */ +static inline void bfq_update_active_node(struct rb_node *node) +{ + struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); + + entity->min_start = entity->start; + bfq_update_min(entity, node->rb_right); + bfq_update_min(entity, node->rb_left); +} + +/** + * bfq_update_active_tree - update min_start for the whole active tree. + * @node: the starting node. + * + * @node must be the deepest modified node after an update. This function + * updates its min_start using the values held by its children, assuming + * that they did not change, and then updates all the nodes that may have + * changed in the path to the root. The only nodes that may have changed + * are the ones in the path or their siblings. + */ +static void bfq_update_active_tree(struct rb_node *node) +{ + struct rb_node *parent; + +up: + bfq_update_active_node(node); + + parent = rb_parent(node); + if (parent == NULL) + return; + + if (node == parent->rb_left && parent->rb_right != NULL) + bfq_update_active_node(parent->rb_right); + else if (parent->rb_left != NULL) + bfq_update_active_node(parent->rb_left); + + node = parent; + goto up; +} + +static void bfq_weights_tree_add(struct bfq_data *bfqd, + struct bfq_entity *entity, + struct rb_root *root); + +static void bfq_weights_tree_remove(struct bfq_data *bfqd, + struct bfq_entity *entity, + struct rb_root *root); + + +/** + * bfq_active_insert - insert an entity in the active tree of its + * group/device. + * @st: the service tree of the entity. + * @entity: the entity being inserted. + * + * The active tree is ordered by finish time, but an extra key is kept + * per each node, containing the minimum value for the start times of + * its children (and the node itself), so it's possible to search for + * the eligible node with the lowest finish time in logarithmic time. + */ +static void bfq_active_insert(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct rb_node *node = &entity->rb_node; +#ifdef CONFIG_CGROUP_BFQIO + struct bfq_sched_data *sd = NULL; + struct bfq_group *bfqg = NULL; + struct bfq_data *bfqd = NULL; +#endif + + bfq_insert(&st->active, entity); + + if (node->rb_left != NULL) + node = node->rb_left; + else if (node->rb_right != NULL) + node = node->rb_right; + + bfq_update_active_tree(node); + +#ifdef CONFIG_CGROUP_BFQIO + sd = entity->sched_data; + bfqg = container_of(sd, struct bfq_group, sched_data); + BUG_ON(!bfqg); + bfqd = (struct bfq_data *)bfqg->bfqd; +#endif + if (bfqq != NULL) + list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); +#ifdef CONFIG_CGROUP_BFQIO + else { /* bfq_group */ + BUG_ON(!bfqd); + bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); + } + if (bfqg != bfqd->root_group) { + BUG_ON(!bfqg); + BUG_ON(!bfqd); + bfqg->active_entities++; + if (bfqg->active_entities == 2) + bfqd->active_numerous_groups++; + } +#endif +} + +/** + * bfq_ioprio_to_weight - calc a weight from an ioprio. + * @ioprio: the ioprio value to convert. + */ +static inline unsigned short bfq_ioprio_to_weight(int ioprio) +{ + BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); + return IOPRIO_BE_NR - ioprio; +} + +/** + * bfq_weight_to_ioprio - calc an ioprio from a weight. + * @weight: the weight value to convert. + * + * To preserve as mush as possible the old only-ioprio user interface, + * 0 is used as an escape ioprio value for weights (numerically) equal or + * larger than IOPRIO_BE_NR + */ +static inline unsigned short bfq_weight_to_ioprio(int weight) +{ + BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); + return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; +} + +static inline void bfq_get_entity(struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + + if (bfqq != NULL) { + atomic_inc(&bfqq->ref); + bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", + bfqq, atomic_read(&bfqq->ref)); + } +} + +/** + * bfq_find_deepest - find the deepest node that an extraction can modify. + * @node: the node being removed. + * + * Do the first step of an extraction in an rb tree, looking for the + * node that will replace @node, and returning the deepest node that + * the following modifications to the tree can touch. If @node is the + * last node in the tree return %NULL. + */ +static struct rb_node *bfq_find_deepest(struct rb_node *node) +{ + struct rb_node *deepest; + + if (node->rb_right == NULL && node->rb_left == NULL) + deepest = rb_parent(node); + else if (node->rb_right == NULL) + deepest = node->rb_left; + else if (node->rb_left == NULL) + deepest = node->rb_right; + else { + deepest = rb_next(node); + if (deepest->rb_right != NULL) + deepest = deepest->rb_right; + else if (rb_parent(deepest) != node) + deepest = rb_parent(deepest); + } + + return deepest; +} + +/** + * bfq_active_extract - remove an entity from the active tree. + * @st: the service_tree containing the tree. + * @entity: the entity being removed. + */ +static void bfq_active_extract(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct rb_node *node; +#ifdef CONFIG_CGROUP_BFQIO + struct bfq_sched_data *sd = NULL; + struct bfq_group *bfqg = NULL; + struct bfq_data *bfqd = NULL; +#endif + + node = bfq_find_deepest(&entity->rb_node); + bfq_extract(&st->active, entity); + + if (node != NULL) + bfq_update_active_tree(node); + +#ifdef CONFIG_CGROUP_BFQIO + sd = entity->sched_data; + bfqg = container_of(sd, struct bfq_group, sched_data); + BUG_ON(!bfqg); + bfqd = (struct bfq_data *)bfqg->bfqd; +#endif + if (bfqq != NULL) + list_del(&bfqq->bfqq_list); +#ifdef CONFIG_CGROUP_BFQIO + else { /* bfq_group */ + BUG_ON(!bfqd); + bfq_weights_tree_remove(bfqd, entity, + &bfqd->group_weights_tree); + } + if (bfqg != bfqd->root_group) { + BUG_ON(!bfqg); + BUG_ON(!bfqd); + BUG_ON(!bfqg->active_entities); + bfqg->active_entities--; + if (bfqg->active_entities == 1) { + BUG_ON(!bfqd->active_numerous_groups); + bfqd->active_numerous_groups--; + } + } +#endif +} + +/** + * bfq_idle_insert - insert an entity into the idle tree. + * @st: the service tree containing the tree. + * @entity: the entity to insert. + */ +static void bfq_idle_insert(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct bfq_entity *first_idle = st->first_idle; + struct bfq_entity *last_idle = st->last_idle; + + if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) + st->first_idle = entity; + if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) + st->last_idle = entity; + + bfq_insert(&st->idle, entity); + + if (bfqq != NULL) + list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); +} + +/** + * bfq_forget_entity - remove an entity from the wfq trees. + * @st: the service tree. + * @entity: the entity being removed. + * + * Update the device status and forget everything about @entity, putting + * the device reference to it, if it is a queue. Entities belonging to + * groups are not refcounted. + */ +static void bfq_forget_entity(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + struct bfq_sched_data *sd; + + BUG_ON(!entity->on_st); + + entity->on_st = 0; + st->wsum -= entity->weight; + if (bfqq != NULL) { + sd = entity->sched_data; + bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", + bfqq, atomic_read(&bfqq->ref)); + bfq_put_queue(bfqq); + } +} + +/** + * bfq_put_idle_entity - release the idle tree ref of an entity. + * @st: service tree for the entity. + * @entity: the entity being released. + */ +static void bfq_put_idle_entity(struct bfq_service_tree *st, + struct bfq_entity *entity) +{ + bfq_idle_extract(st, entity); + bfq_forget_entity(st, entity); +} + +/** + * bfq_forget_idle - update the idle tree if necessary. + * @st: the service tree to act upon. + * + * To preserve the global O(log N) complexity we only remove one entry here; + * as the idle tree will not grow indefinitely this can be done safely. + */ +static void bfq_forget_idle(struct bfq_service_tree *st) +{ + struct bfq_entity *first_idle = st->first_idle; + struct bfq_entity *last_idle = st->last_idle; + + if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && + !bfq_gt(last_idle->finish, st->vtime)) { + /* + * Forget the whole idle tree, increasing the vtime past + * the last finish time of idle entities. + */ + st->vtime = last_idle->finish; + } + + if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) + bfq_put_idle_entity(st, first_idle); +} + +static struct bfq_service_tree * +__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, + struct bfq_entity *entity) +{ + struct bfq_service_tree *new_st = old_st; + + if (entity->ioprio_changed) { + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); + unsigned short prev_weight, new_weight; + struct bfq_data *bfqd = NULL; + struct rb_root *root; +#ifdef CONFIG_CGROUP_BFQIO + struct bfq_sched_data *sd; + struct bfq_group *bfqg; +#endif + + if (bfqq != NULL) + bfqd = bfqq->bfqd; +#ifdef CONFIG_CGROUP_BFQIO + else { + sd = entity->my_sched_data; + bfqg = container_of(sd, struct bfq_group, sched_data); + BUG_ON(!bfqg); + bfqd = (struct bfq_data *)bfqg->bfqd; + BUG_ON(!bfqd); + } +#endif + + BUG_ON(old_st->wsum < entity->weight); + old_st->wsum -= entity->weight; + + if (entity->new_weight != entity->orig_weight) { + if (entity->new_weight < BFQ_MIN_WEIGHT || + entity->new_weight > BFQ_MAX_WEIGHT) { + printk(KERN_CRIT "update_weight_prio: " + "new_weight %d\n", + entity->new_weight); + BUG(); + } + entity->orig_weight = entity->new_weight; + entity->ioprio = + bfq_weight_to_ioprio(entity->orig_weight); + } + + entity->ioprio_class = entity->new_ioprio_class; + entity->ioprio_changed = 0; + + /* + * NOTE: here we may be changing the weight too early, + * this will cause unfairness. The correct approach + * would have required additional complexity to defer + * weight changes to the proper time instants (i.e., + * when entity->finish <= old_st->vtime). + */ + new_st = bfq_entity_service_tree(entity); + + prev_weight = entity->weight; + new_weight = entity->orig_weight * + (bfqq != NULL ? bfqq->wr_coeff : 1); + /* + * If the weight of the entity changes, remove the entity + * from its old weight counter (if there is a counter + * associated with the entity), and add it to the counter + * associated with its new weight. + */ + if (prev_weight != new_weight) { + root = bfqq ? &bfqd->queue_weights_tree : + &bfqd->group_weights_tree; + bfq_weights_tree_remove(bfqd, entity, root); + } + entity->weight = new_weight; + /* + * Add the entity to its weights tree only if it is + * not associated with a weight-raised queue. + */ + if (prev_weight != new_weight && + (bfqq ? bfqq->wr_coeff == 1 : 1)) + /* If we get here, root has been initialized. */ + bfq_weights_tree_add(bfqd, entity, root); + + new_st->wsum += entity->weight; + + if (new_st != old_st) + entity->start = new_st->vtime; + } + + return new_st; +} + +/** + * bfq_bfqq_served - update the scheduler status after selection for + * service. + * @bfqq: the queue being served. + * @served: bytes to transfer. + * + * NOTE: this can be optimized, as the timestamps of upper level entities + * are synchronized every time a new bfqq is selected for service. By now, + * we keep it to better check consistency. + */ +static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) +{ + struct bfq_entity *entity = &bfqq->entity; + struct bfq_service_tree *st; + + for_each_entity(entity) { + st = bfq_entity_service_tree(entity); + + entity->service += served; + BUG_ON(entity->service > entity->budget); + BUG_ON(st->wsum == 0); + + st->vtime += bfq_delta(served, st->wsum); + bfq_forget_idle(st); + } + bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); +} + +/** + * bfq_bfqq_charge_full_budget - set the service to the entity budget. + * @bfqq: the queue that needs a service update. + * + * When it's not possible to be fair in the service domain, because + * a queue is not consuming its budget fast enough (the meaning of + * fast depends on the timeout parameter), we charge it a full + * budget. In this way we should obtain a sort of time-domain + * fairness among all the seeky/slow queues. + */ +static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; + + bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); + + bfq_bfqq_served(bfqq, entity->budget - entity->service); +} + +/** + * __bfq_activate_entity - activate an entity. + * @entity: the entity being activated. + * + * Called whenever an entity is activated, i.e., it is not active and one + * of its children receives a new request, or has to be reactivated due to + * budget exhaustion. It uses the current budget of the entity (and the + * service received if @entity is active) of the queue to calculate its + * timestamps. + */ +static void __bfq_activate_entity(struct bfq_entity *entity) +{ + struct bfq_sched_data *sd = entity->sched_data; + struct bfq_service_tree *st = bfq_entity_service_tree(entity); + + if (entity == sd->in_service_entity) { + BUG_ON(entity->tree != NULL); + /* + * If we are requeueing the current entity we have + * to take care of not charging to it service it has + * not received. + */ + bfq_calc_finish(entity, entity->service); + entity->start = entity->finish; + sd->in_service_entity = NULL; + } else if (entity->tree == &st->active) { + /* + * Requeueing an entity due to a change of some + * next_in_service entity below it. We reuse the + * old start time. + */ + bfq_active_extract(st, entity); + } else if (entity->tree == &st->idle) { + /* + * Must be on the idle tree, bfq_idle_extract() will + * check for that. + */ + bfq_idle_extract(st, entity); + entity->start = bfq_gt(st->vtime, entity->finish) ? + st->vtime : entity->finish; + } else { + /* + * The finish time of the entity may be invalid, and + * it is in the past for sure, otherwise the queue + * would have been on the idle tree. + */ + entity->start = st->vtime; + st->wsum += entity->weight; + bfq_get_entity(entity); + + BUG_ON(entity->on_st); + entity->on_st = 1; + } + + st = __bfq_entity_update_weight_prio(st, entity); + bfq_calc_finish(entity, entity->budget); + bfq_active_insert(st, entity); +} + +/** + * bfq_activate_entity - activate an entity and its ancestors if necessary. + * @entity: the entity to activate. + * + * Activate @entity and all the entities on the path from it to the root. + */ +static void bfq_activate_entity(struct bfq_entity *entity) +{ + struct bfq_sched_data *sd; + + for_each_entity(entity) { + __bfq_activate_entity(entity); + + sd = entity->sched_data; + if (!bfq_update_next_in_service(sd)) + /* + * No need to propagate the activation to the + * upper entities, as they will be updated when + * the in-service entity is rescheduled. + */ + break; + } +} + +/** + * __bfq_deactivate_entity - deactivate an entity from its service tree. + * @entity: the entity to deactivate. + * @requeue: if false, the entity will not be put into the idle tree. + * + * Deactivate an entity, independently from its previous state. If the + * entity was not on a service tree just return, otherwise if it is on + * any scheduler tree, extract it from that tree, and if necessary + * and if the caller did not specify @requeue, put it on the idle tree. + * + * Return %1 if the caller should update the entity hierarchy, i.e., + * if the entity was in service or if it was the next_in_service for + * its sched_data; return %0 otherwise. + */ +static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) +{ + struct bfq_sched_data *sd = entity->sched_data; + struct bfq_service_tree *st = bfq_entity_service_tree(entity); + int was_in_service = entity == sd->in_service_entity; + int ret = 0; + + if (!entity->on_st) + return 0; + + BUG_ON(was_in_service && entity->tree != NULL); + + if (was_in_service) { + bfq_calc_finish(entity, entity->service); + sd->in_service_entity = NULL; + } else if (entity->tree == &st->active) + bfq_active_extract(st, entity); + else if (entity->tree == &st->idle) + bfq_idle_extract(st, entity); + else if (entity->tree != NULL) + BUG(); + + if (was_in_service || sd->next_in_service == entity) + ret = bfq_update_next_in_service(sd); + + if (!requeue || !bfq_gt(entity->finish, st->vtime)) + bfq_forget_entity(st, entity); + else + bfq_idle_insert(st, entity); + + BUG_ON(sd->in_service_entity == entity); + BUG_ON(sd->next_in_service == entity); + + return ret; +} + +/** + * bfq_deactivate_entity - deactivate an entity. + * @entity: the entity to deactivate. + * @requeue: true if the entity can be put on the idle tree + */ +static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) +{ + struct bfq_sched_data *sd; + struct bfq_entity *parent; + + for_each_entity_safe(entity, parent) { + sd = entity->sched_data; + + if (!__bfq_deactivate_entity(entity, requeue)) + /* + * The parent entity is still backlogged, and + * we don't need to update it as it is still + * in service. + */ + break; + + if (sd->next_in_service != NULL) + /* + * The parent entity is still backlogged and + * the budgets on the path towards the root + * need to be updated. + */ + goto update; + + /* + * If we reach there the parent is no more backlogged and + * we want to propagate the dequeue upwards. + */ + requeue = 1; + } + + return; + +update: + entity = parent; + for_each_entity(entity) { + __bfq_activate_entity(entity); + + sd = entity->sched_data; + if (!bfq_update_next_in_service(sd)) + break; + } +} + +/** + * bfq_update_vtime - update vtime if necessary. + * @st: the service tree to act upon. + * + * If necessary update the service tree vtime to have at least one + * eligible entity, skipping to its start time. Assumes that the + * active tree of the device is not empty. + * + * NOTE: this hierarchical implementation updates vtimes quite often, + * we may end up with reactivated processes getting timestamps after a + * vtime skip done because we needed a ->first_active entity on some + * intermediate node. + */ +static void bfq_update_vtime(struct bfq_service_tree *st) +{ + struct bfq_entity *entry; + struct rb_node *node = st->active.rb_node; + + entry = rb_entry(node, struct bfq_entity, rb_node); + if (bfq_gt(entry->min_start, st->vtime)) { + st->vtime = entry->min_start; + bfq_forget_idle(st); + } +} + +/** + * bfq_first_active_entity - find the eligible entity with + * the smallest finish time + * @st: the service tree to select from. + * + * This function searches the first schedulable entity, starting from the + * root of the tree and going on the left every time on this side there is + * a subtree with at least one eligible (start >= vtime) entity. The path on + * the right is followed only if a) the left subtree contains no eligible + * entities and b) no eligible entity has been found yet. + */ +static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) +{ + struct bfq_entity *entry, *first = NULL; + struct rb_node *node = st->active.rb_node; + + while (node != NULL) { + entry = rb_entry(node, struct bfq_entity, rb_node); +left: + if (!bfq_gt(entry->start, st->vtime)) + first = entry; + + BUG_ON(bfq_gt(entry->min_start, st->vtime)); + + if (node->rb_left != NULL) { + entry = rb_entry(node->rb_left, + struct bfq_entity, rb_node); + if (!bfq_gt(entry->min_start, st->vtime)) { + node = node->rb_left; + goto left; + } + } + if (first != NULL) + break; + node = node->rb_right; + } + + BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); + return first; +} + +/** + * __bfq_lookup_next_entity - return the first eligible entity in @st. + * @st: the service tree. + * + * Update the virtual time in @st and return the first eligible entity + * it contains. + */ +static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, + bool force) +{ + struct bfq_entity *entity, *new_next_in_service = NULL; + + if (RB_EMPTY_ROOT(&st->active)) + return NULL; + + bfq_update_vtime(st); + entity = bfq_first_active_entity(st); + BUG_ON(bfq_gt(entity->start, st->vtime)); + + /* + * If the chosen entity does not match with the sched_data's + * next_in_service and we are forcedly serving the IDLE priority + * class tree, bubble up budget update. + */ + if (unlikely(force && entity != entity->sched_data->next_in_service)) { + new_next_in_service = entity; + for_each_entity(new_next_in_service) + bfq_update_budget(new_next_in_service); + } + + return entity; +} + +/** + * bfq_lookup_next_entity - return the first eligible entity in @sd. + * @sd: the sched_data. + * @extract: if true the returned entity will be also extracted from @sd. + * + * NOTE: since we cache the next_in_service entity at each level of the + * hierarchy, the complexity of the lookup can be decreased with + * absolutely no effort just returning the cached next_in_service value; + * we prefer to do full lookups to test the consistency of * the data + * structures. + */ +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, + int extract, + struct bfq_data *bfqd) +{ + struct bfq_service_tree *st = sd->service_tree; + struct bfq_entity *entity; + int i = 0; + + BUG_ON(sd->in_service_entity != NULL); + + if (bfqd != NULL && + jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { + entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, + true); + if (entity != NULL) { + i = BFQ_IOPRIO_CLASSES - 1; + bfqd->bfq_class_idle_last_service = jiffies; + sd->next_in_service = entity; + } + } + for (; i < BFQ_IOPRIO_CLASSES; i++) { + entity = __bfq_lookup_next_entity(st + i, false); + if (entity != NULL) { + if (extract) { + bfq_check_next_in_service(sd, entity); + bfq_active_extract(st + i, entity); + sd->in_service_entity = entity; + sd->next_in_service = NULL; + } + break; + } + } + + return entity; +} + +/* + * Get next queue for service. + */ +static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) +{ + struct bfq_entity *entity = NULL; + struct bfq_sched_data *sd; + struct bfq_queue *bfqq; + + BUG_ON(bfqd->in_service_queue != NULL); + + if (bfqd->busy_queues == 0) + return NULL; + + sd = &bfqd->root_group->sched_data; + for (; sd != NULL; sd = entity->my_sched_data) { + entity = bfq_lookup_next_entity(sd, 1, bfqd); + BUG_ON(entity == NULL); + entity->service = 0; + } + + bfqq = bfq_entity_to_bfqq(entity); + BUG_ON(bfqq == NULL); + + return bfqq; +} + +static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) +{ + if (bfqd->in_service_bic != NULL) { + put_io_context(bfqd->in_service_bic->icq.ioc); + bfqd->in_service_bic = NULL; + } + + bfqd->in_service_queue = NULL; + del_timer(&bfqd->idle_slice_timer); +} + +static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, + int requeue) +{ + struct bfq_entity *entity = &bfqq->entity; + + if (bfqq == bfqd->in_service_queue) + __bfq_bfqd_reset_in_service(bfqd); + + bfq_deactivate_entity(entity, requeue); +} + +static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + struct bfq_entity *entity = &bfqq->entity; + + bfq_activate_entity(entity); +} + +/* + * Called when the bfqq no longer has requests pending, remove it from + * the service tree. + */ +static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, + int requeue) +{ + BUG_ON(!bfq_bfqq_busy(bfqq)); + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); + + bfq_log_bfqq(bfqd, bfqq, "del from busy"); + + bfq_clear_bfqq_busy(bfqq); + + BUG_ON(bfqd->busy_queues == 0); + bfqd->busy_queues--; + + if (!bfqq->dispatched) { + bfq_weights_tree_remove(bfqd, &bfqq->entity, + &bfqd->queue_weights_tree); + if (!blk_queue_nonrot(bfqd->queue)) { + BUG_ON(!bfqd->busy_in_flight_queues); + bfqd->busy_in_flight_queues--; + if (bfq_bfqq_constantly_seeky(bfqq)) { + BUG_ON(!bfqd-> + const_seeky_busy_in_flight_queues); + bfqd->const_seeky_busy_in_flight_queues--; + } + } + } + if (bfqq->wr_coeff > 1) + bfqd->wr_busy_queues--; + + bfq_deactivate_bfqq(bfqd, bfqq, requeue); +} + +/* + * Called when an inactive queue receives a new request. + */ +static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) +{ + BUG_ON(bfq_bfqq_busy(bfqq)); + BUG_ON(bfqq == bfqd->in_service_queue); + + bfq_log_bfqq(bfqd, bfqq, "add to busy"); + + bfq_activate_bfqq(bfqd, bfqq); + + bfq_mark_bfqq_busy(bfqq); + bfqd->busy_queues++; + + if (!bfqq->dispatched) { + if (bfqq->wr_coeff == 1) + bfq_weights_tree_add(bfqd, &bfqq->entity, + &bfqd->queue_weights_tree); + if (!blk_queue_nonrot(bfqd->queue)) { + bfqd->busy_in_flight_queues++; + if (bfq_bfqq_constantly_seeky(bfqq)) + bfqd->const_seeky_busy_in_flight_queues++; + } + } + if (bfqq->wr_coeff > 1) + bfqd->wr_busy_queues++; +} diff --git a/block/bfq.h b/block/bfq.h new file mode 100644 index 0000000000000..aeb9bb4bbce7f --- /dev/null +++ b/block/bfq.h @@ -0,0 +1,805 @@ +/* + * BFQ-v7r8 for 3.10.8+: data structures and common functions prototypes. + * + * Based on ideas and code from CFQ: + * Copyright (C) 2003 Jens Axboe + * + * Copyright (C) 2008 Fabio Checconi + * Paolo Valente + * + * Copyright (C) 2010 Paolo Valente + */ + +#ifndef _BFQ_H +#define _BFQ_H + +#include +#include +#include +#include + +#define BFQ_IOPRIO_CLASSES 3 +#define BFQ_CL_IDLE_TIMEOUT (HZ/5) + +#define BFQ_MIN_WEIGHT 1 +#define BFQ_MAX_WEIGHT 1000 + +#define BFQ_DEFAULT_QUEUE_IOPRIO 4 + +#define BFQ_DEFAULT_GRP_WEIGHT 10 +#define BFQ_DEFAULT_GRP_IOPRIO 0 +#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE + +struct bfq_entity; + +/** + * struct bfq_service_tree - per ioprio_class service tree. + * @active: tree for active entities (i.e., those backlogged). + * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). + * @first_idle: idle entity with minimum F_i. + * @last_idle: idle entity with maximum F_i. + * @vtime: scheduler virtual time. + * @wsum: scheduler weight sum; active and idle entities contribute to it. + * + * Each service tree represents a B-WF2Q+ scheduler on its own. Each + * ioprio_class has its own independent scheduler, and so its own + * bfq_service_tree. All the fields are protected by the queue lock + * of the containing bfqd. + */ +struct bfq_service_tree { + struct rb_root active; + struct rb_root idle; + + struct bfq_entity *first_idle; + struct bfq_entity *last_idle; + + u64 vtime; + unsigned long wsum; +}; + +/** + * struct bfq_sched_data - multi-class scheduler. + * @in_service_entity: entity in service. + * @next_in_service: head-of-the-line entity in the scheduler. + * @service_tree: array of service trees, one per ioprio_class. + * + * bfq_sched_data is the basic scheduler queue. It supports three + * ioprio_classes, and can be used either as a toplevel queue or as + * an intermediate queue on a hierarchical setup. + * @next_in_service points to the active entity of the sched_data + * service trees that will be scheduled next. + * + * The supported ioprio_classes are the same as in CFQ, in descending + * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. + * Requests from higher priority queues are served before all the + * requests from lower priority queues; among requests of the same + * queue requests are served according to B-WF2Q+. + * All the fields are protected by the queue lock of the containing bfqd. + */ +struct bfq_sched_data { + struct bfq_entity *in_service_entity; + struct bfq_entity *next_in_service; + struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; +}; + +/** + * struct bfq_weight_counter - counter of the number of all active entities + * with a given weight. + * @weight: weight of the entities that this counter refers to. + * @num_active: number of active entities with this weight. + * @weights_node: weights tree member (see bfq_data's @queue_weights_tree + * and @group_weights_tree). + */ +struct bfq_weight_counter { + short int weight; + unsigned int num_active; + struct rb_node weights_node; +}; + +/** + * struct bfq_entity - schedulable entity. + * @rb_node: service_tree member. + * @weight_counter: pointer to the weight counter associated with this entity. + * @on_st: flag, true if the entity is on a tree (either the active or + * the idle one of its service_tree). + * @finish: B-WF2Q+ finish timestamp (aka F_i). + * @start: B-WF2Q+ start timestamp (aka S_i). + * @tree: tree the entity is enqueued into; %NULL if not on a tree. + * @min_start: minimum start time of the (active) subtree rooted at + * this entity; used for O(log N) lookups into active trees. + * @service: service received during the last round of service. + * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. + * @weight: weight of the queue + * @parent: parent entity, for hierarchical scheduling. + * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the + * associated scheduler queue, %NULL on leaf nodes. + * @sched_data: the scheduler queue this entity belongs to. + * @ioprio: the ioprio in use. + * @new_weight: when a weight change is requested, the new weight value. + * @orig_weight: original weight, used to implement weight boosting + * @new_ioprio: when an ioprio change is requested, the new ioprio value. + * @ioprio_class: the ioprio_class in use. + * @new_ioprio_class: when an ioprio_class change is requested, the new + * ioprio_class value. + * @ioprio_changed: flag, true when the user requested a weight, ioprio or + * ioprio_class change. + * + * A bfq_entity is used to represent either a bfq_queue (leaf node in the + * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each + * entity belongs to the sched_data of the parent group in the cgroup + * hierarchy. Non-leaf entities have also their own sched_data, stored + * in @my_sched_data. + * + * Each entity stores independently its priority values; this would + * allow different weights on different devices, but this + * functionality is not exported to userspace by now. Priorities and + * weights are updated lazily, first storing the new values into the + * new_* fields, then setting the @ioprio_changed flag. As soon as + * there is a transition in the entity state that allows the priority + * update to take place the effective and the requested priority + * values are synchronized. + * + * Unless cgroups are used, the weight value is calculated from the + * ioprio to export the same interface as CFQ. When dealing with + * ``well-behaved'' queues (i.e., queues that do not spend too much + * time to consume their budget and have true sequential behavior, and + * when there are no external factors breaking anticipation) the + * relative weights at each level of the cgroups hierarchy should be + * guaranteed. All the fields are protected by the queue lock of the + * containing bfqd. + */ +struct bfq_entity { + struct rb_node rb_node; + struct bfq_weight_counter *weight_counter; + + int on_st; + + u64 finish; + u64 start; + + struct rb_root *tree; + + u64 min_start; + + unsigned long service, budget; + unsigned short weight, new_weight; + unsigned short orig_weight; + + struct bfq_entity *parent; + + struct bfq_sched_data *my_sched_data; + struct bfq_sched_data *sched_data; + + unsigned short ioprio, new_ioprio; + unsigned short ioprio_class, new_ioprio_class; + + int ioprio_changed; +}; + +struct bfq_group; + +/** + * struct bfq_queue - leaf schedulable entity. + * @ref: reference counter. + * @bfqd: parent bfq_data. + * @new_bfqq: shared bfq_queue if queue is cooperating with + * one or more other queues. + * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). + * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). + * @sort_list: sorted list of pending requests. + * @next_rq: if fifo isn't expired, next request to serve. + * @queued: nr of requests queued in @sort_list. + * @allocated: currently allocated requests. + * @meta_pending: pending metadata requests. + * @fifo: fifo list of requests in sort_list. + * @entity: entity representing this queue in the scheduler. + * @max_budget: maximum budget allowed from the feedback mechanism. + * @budget_timeout: budget expiration (in jiffies). + * @dispatched: number of requests on the dispatch list or inside driver. + * @flags: status flags. + * @bfqq_list: node for active/idle bfqq list inside our bfqd. + * @burst_list_node: node for the device's burst list. + * @seek_samples: number of seeks sampled + * @seek_total: sum of the distances of the seeks sampled + * @seek_mean: mean seek distance + * @last_request_pos: position of the last request enqueued + * @requests_within_timer: number of consecutive pairs of request completion + * and arrival, such that the queue becomes idle + * after the completion, but the next request arrives + * within an idle time slice; used only if the queue's + * IO_bound has been cleared. + * @pid: pid of the process owning the queue, used for logging purposes. + * @last_wr_start_finish: start time of the current weight-raising period if + * the @bfq-queue is being weight-raised, otherwise + * finish time of the last weight-raising period + * @wr_cur_max_time: current max raising time for this queue + * @soft_rt_next_start: minimum time instant such that, only if a new + * request is enqueued after this time instant in an + * idle @bfq_queue with no outstanding requests, then + * the task associated with the queue it is deemed as + * soft real-time (see the comments to the function + * bfq_bfqq_softrt_next_start()) + * @last_idle_bklogged: time of the last transition of the @bfq_queue from + * idle to backlogged + * @service_from_backlogged: cumulative service received from the @bfq_queue + * since the last transition from idle to + * backlogged + * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the + * queue is shared + * + * A bfq_queue is a leaf request queue; it can be associated with an + * io_context or more, if it is async or shared between cooperating + * processes. @cgroup holds a reference to the cgroup, to be sure that it + * does not disappear while a bfqq still references it (mostly to avoid + * races between request issuing and task migration followed by cgroup + * destruction). + * All the fields are protected by the queue lock of the containing bfqd. + */ +struct bfq_queue { + atomic_t ref; + struct bfq_data *bfqd; + + /* fields for cooperating queues handling */ + struct bfq_queue *new_bfqq; + struct rb_node pos_node; + struct rb_root *pos_root; + + struct rb_root sort_list; + struct request *next_rq; + int queued[2]; + int allocated[2]; + int meta_pending; + struct list_head fifo; + + struct bfq_entity entity; + + unsigned long max_budget; + unsigned long budget_timeout; + + int dispatched; + + unsigned int flags; + + struct list_head bfqq_list; + + struct hlist_node burst_list_node; + + unsigned int seek_samples; + u64 seek_total; + sector_t seek_mean; + sector_t last_request_pos; + + unsigned int requests_within_timer; + + pid_t pid; + struct bfq_io_cq *bic; + + /* weight-raising fields */ + unsigned long wr_cur_max_time; + unsigned long soft_rt_next_start; + unsigned long last_wr_start_finish; + unsigned int wr_coeff; + unsigned long last_idle_bklogged; + unsigned long service_from_backlogged; +}; + +/** + * struct bfq_ttime - per process thinktime stats. + * @ttime_total: total process thinktime + * @ttime_samples: number of thinktime samples + * @ttime_mean: average process thinktime + */ +struct bfq_ttime { + unsigned long last_end_request; + + unsigned long ttime_total; + unsigned long ttime_samples; + unsigned long ttime_mean; +}; + +/** + * struct bfq_io_cq - per (request_queue, io_context) structure. + * @icq: associated io_cq structure + * @bfqq: array of two process queues, the sync and the async + * @ttime: associated @bfq_ttime struct + * @wr_time_left: snapshot of the time left before weight raising ends + * for the sync queue associated to this process; this + * snapshot is taken to remember this value while the weight + * raising is suspended because the queue is merged with a + * shared queue, and is used to set @raising_cur_max_time + * when the queue is split from the shared queue and its + * weight is raised again + * @saved_idle_window: same purpose as the previous field for the idle + * window + * @saved_IO_bound: same purpose as the previous two fields for the I/O + * bound classification of a queue + * @saved_in_large_burst: same purpose as the previous fields for the + * value of the field keeping the queue's belonging + * to a large burst + * @was_in_burst_list: true if the queue belonged to a burst list + * before its merge with another cooperating queue + * @cooperations: counter of consecutive successful queue merges underwent + * by any of the process' @bfq_queues + * @failed_cooperations: counter of consecutive failed queue merges of any + * of the process' @bfq_queues + */ +struct bfq_io_cq { + struct io_cq icq; /* must be the first member */ + struct bfq_queue *bfqq[2]; + struct bfq_ttime ttime; + int ioprio; + + unsigned int wr_time_left; + bool saved_idle_window; + bool saved_IO_bound; + + bool saved_in_large_burst; + bool was_in_burst_list; + + unsigned int cooperations; + unsigned int failed_cooperations; +}; + +enum bfq_device_speed { + BFQ_BFQD_FAST, + BFQ_BFQD_SLOW, +}; + +/** + * struct bfq_data - per device data structure. + * @queue: request queue for the managed device. + * @root_group: root bfq_group for the device. + * @rq_pos_tree: rbtree sorted by next_request position, used when + * determining if two or more queues have interleaving + * requests (see bfq_close_cooperator()). + * @active_numerous_groups: number of bfq_groups containing more than one + * active @bfq_entity. + * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by + * weight. Used to keep track of whether all @bfq_queues + * have the same weight. The tree contains one counter + * for each distinct weight associated to some active + * and not weight-raised @bfq_queue (see the comments to + * the functions bfq_weights_tree_[add|remove] for + * further details). + * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted + * by weight. Used to keep track of whether all + * @bfq_groups have the same weight. The tree contains + * one counter for each distinct weight associated to + * some active @bfq_group (see the comments to the + * functions bfq_weights_tree_[add|remove] for further + * details). + * @busy_queues: number of bfq_queues containing requests (including the + * queue in service, even if it is idling). + * @busy_in_flight_queues: number of @bfq_queues containing pending or + * in-flight requests, plus the @bfq_queue in + * service, even if idle but waiting for the + * possible arrival of its next sync request. This + * field is updated only if the device is rotational, + * but used only if the device is also NCQ-capable. + * The reason why the field is updated also for non- + * NCQ-capable rotational devices is related to the + * fact that the value of @hw_tag may be set also + * later than when busy_in_flight_queues may need to + * be incremented for the first time(s). Taking also + * this possibility into account, to avoid unbalanced + * increments/decrements, would imply more overhead + * than just updating busy_in_flight_queues + * regardless of the value of @hw_tag. + * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues + * (that is, seeky queues that expired + * for budget timeout at least once) + * containing pending or in-flight + * requests, including the in-service + * @bfq_queue if constantly seeky. This + * field is updated only if the device + * is rotational, but used only if the + * device is also NCQ-capable (see the + * comments to @busy_in_flight_queues). + * @wr_busy_queues: number of weight-raised busy @bfq_queues. + * @queued: number of queued requests. + * @rq_in_driver: number of requests dispatched and waiting for completion. + * @sync_flight: number of sync requests in the driver. + * @max_rq_in_driver: max number of reqs in driver in the last + * @hw_tag_samples completed requests. + * @hw_tag_samples: nr of samples used to calculate hw_tag. + * @hw_tag: flag set to one if the driver is showing a queueing behavior. + * @budgets_assigned: number of budgets assigned. + * @idle_slice_timer: timer set when idling for the next sequential request + * from the queue in service. + * @unplug_work: delayed work to restart dispatching on the request queue. + * @in_service_queue: bfq_queue in service. + * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. + * @last_position: on-disk position of the last served request. + * @last_budget_start: beginning of the last budget. + * @last_idling_start: beginning of the last idle slice. + * @peak_rate: peak transfer rate observed for a budget. + * @peak_rate_samples: number of samples used to calculate @peak_rate. + * @bfq_max_budget: maximum budget allotted to a bfq_queue before + * rescheduling. + * @group_list: list of all the bfq_groups active on the device. + * @active_list: list of all the bfq_queues active on the device. + * @idle_list: list of all the bfq_queues idle on the device. + * @bfq_fifo_expire: timeout for async/sync requests; when it expires + * requests are served in fifo order. + * @bfq_back_penalty: weight of backward seeks wrt forward ones. + * @bfq_back_max: maximum allowed backward seek. + * @bfq_slice_idle: maximum idling time. + * @bfq_user_max_budget: user-configured max budget value + * (0 for auto-tuning). + * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to + * async queues. + * @bfq_timeout: timeout for bfq_queues to consume their budget; used to + * to prevent seeky queues to impose long latencies to well + * behaved ones (this also implies that seeky queues cannot + * receive guarantees in the service domain; after a timeout + * they are charged for the whole allocated budget, to try + * to preserve a behavior reasonably fair among them, but + * without service-domain guarantees). + * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is + * no more granted any weight-raising. + * @bfq_failed_cooperations: number of consecutive failed cooperation + * chances after which weight-raising is restored + * to a queue subject to more than bfq_coop_thresh + * queue merges. + * @bfq_requests_within_timer: number of consecutive requests that must be + * issued within the idle time slice to set + * again idling to a queue which was marked as + * non-I/O-bound (see the definition of the + * IO_bound flag for further details). + * @last_ins_in_burst: last time at which a queue entered the current + * burst of queues being activated shortly after + * each other; for more details about this and the + * following parameters related to a burst of + * activations, see the comments to the function + * @bfq_handle_burst. + * @bfq_burst_interval: reference time interval used to decide whether a + * queue has been activated shortly after + * @last_ins_in_burst. + * @burst_size: number of queues in the current burst of queue activations. + * @bfq_large_burst_thresh: maximum burst size above which the current + * queue-activation burst is deemed as 'large'. + * @large_burst: true if a large queue-activation burst is in progress. + * @burst_list: head of the burst list (as for the above fields, more details + * in the comments to the function bfq_handle_burst). + * @low_latency: if set to true, low-latency heuristics are enabled. + * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised + * queue is multiplied. + * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). + * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. + * @bfq_wr_min_idle_time: minimum idle period after which weight-raising + * may be reactivated for a queue (in jiffies). + * @bfq_wr_min_inter_arr_async: minimum period between request arrivals + * after which weight-raising may be + * reactivated for an already busy queue + * (in jiffies). + * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, + * sectors per seconds. + * @RT_prod: cached value of the product R*T used for computing the maximum + * duration of the weight raising automatically. + * @device_speed: device-speed class for the low-latency heuristic. + * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. + * + * All the fields are protected by the @queue lock. + */ +struct bfq_data { + struct request_queue *queue; + + struct bfq_group *root_group; + struct rb_root rq_pos_tree; + +#ifdef CONFIG_CGROUP_BFQIO + int active_numerous_groups; +#endif + + struct rb_root queue_weights_tree; + struct rb_root group_weights_tree; + + int busy_queues; + int busy_in_flight_queues; + int const_seeky_busy_in_flight_queues; + int wr_busy_queues; + int queued; + int rq_in_driver; + int sync_flight; + + int max_rq_in_driver; + int hw_tag_samples; + int hw_tag; + + int budgets_assigned; + + struct timer_list idle_slice_timer; + struct work_struct unplug_work; + + struct bfq_queue *in_service_queue; + struct bfq_io_cq *in_service_bic; + + sector_t last_position; + + ktime_t last_budget_start; + ktime_t last_idling_start; + int peak_rate_samples; + u64 peak_rate; + unsigned long bfq_max_budget; + + struct hlist_head group_list; + struct list_head active_list; + struct list_head idle_list; + + unsigned int bfq_fifo_expire[2]; + unsigned int bfq_back_penalty; + unsigned int bfq_back_max; + unsigned int bfq_slice_idle; + u64 bfq_class_idle_last_service; + + unsigned int bfq_user_max_budget; + unsigned int bfq_max_budget_async_rq; + unsigned int bfq_timeout[2]; + + unsigned int bfq_coop_thresh; + unsigned int bfq_failed_cooperations; + unsigned int bfq_requests_within_timer; + + unsigned long last_ins_in_burst; + unsigned long bfq_burst_interval; + int burst_size; + unsigned long bfq_large_burst_thresh; + bool large_burst; + struct hlist_head burst_list; + + bool low_latency; + + /* parameters of the low_latency heuristics */ + unsigned int bfq_wr_coeff; + unsigned int bfq_wr_max_time; + unsigned int bfq_wr_rt_max_time; + unsigned int bfq_wr_min_idle_time; + unsigned long bfq_wr_min_inter_arr_async; + unsigned int bfq_wr_max_softrt_rate; + u64 RT_prod; + enum bfq_device_speed device_speed; + + struct bfq_queue oom_bfqq; +}; + +enum bfqq_state_flags { + BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ + BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ + BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ + BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ + BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ + BFQ_BFQQ_FLAG_sync, /* synchronous queue */ + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ + BFQ_BFQQ_FLAG_IO_bound, /* + * bfqq has timed-out at least once + * having consumed at most 2/10 of + * its budget + */ + BFQ_BFQQ_FLAG_in_large_burst, /* + * bfqq activated in a large burst, + * see comments to bfq_handle_burst. + */ + BFQ_BFQQ_FLAG_constantly_seeky, /* + * bfqq has proved to be slow and + * seeky until budget timeout + */ + BFQ_BFQQ_FLAG_softrt_update, /* + * may need softrt-next-start + * update + */ + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ + BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */ + BFQ_BFQQ_FLAG_just_split, /* queue has just been split */ +}; + +#define BFQ_BFQQ_FNS(name) \ +static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ +{ \ + (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ +} \ +static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ +{ \ + (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ +} \ +static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ +{ \ + return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ +} + +BFQ_BFQQ_FNS(busy); +BFQ_BFQQ_FNS(wait_request); +BFQ_BFQQ_FNS(must_alloc); +BFQ_BFQQ_FNS(fifo_expire); +BFQ_BFQQ_FNS(idle_window); +BFQ_BFQQ_FNS(sync); +BFQ_BFQQ_FNS(budget_new); +BFQ_BFQQ_FNS(IO_bound); +BFQ_BFQQ_FNS(in_large_burst); +BFQ_BFQQ_FNS(constantly_seeky); +BFQ_BFQQ_FNS(coop); +BFQ_BFQQ_FNS(split_coop); +BFQ_BFQQ_FNS(just_split); +BFQ_BFQQ_FNS(softrt_update); +#undef BFQ_BFQQ_FNS + +/* Logging facilities. */ +#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ + blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) + +#define bfq_log(bfqd, fmt, args...) \ + blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) + +/* Expiration reasons. */ +enum bfqq_expiration { + BFQ_BFQQ_TOO_IDLE = 0, /* + * queue has been idling for + * too long + */ + BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ + BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ + BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ +}; + +#ifdef CONFIG_CGROUP_BFQIO +/** + * struct bfq_group - per (device, cgroup) data structure. + * @entity: schedulable entity to insert into the parent group sched_data. + * @sched_data: own sched_data, to contain child entities (they may be + * both bfq_queues and bfq_groups). + * @group_node: node to be inserted into the bfqio_cgroup->group_data + * list of the containing cgroup's bfqio_cgroup. + * @bfqd_node: node to be inserted into the @bfqd->group_list list + * of the groups active on the same device; used for cleanup. + * @bfqd: the bfq_data for the device this group acts upon. + * @async_bfqq: array of async queues for all the tasks belonging to + * the group, one queue per ioprio value per ioprio_class, + * except for the idle class that has only one queue. + * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). + * @my_entity: pointer to @entity, %NULL for the toplevel group; used + * to avoid too many special cases during group creation/ + * migration. + * @active_entities: number of active entities belonging to the group; + * unused for the root group. Used to know whether there + * are groups with more than one active @bfq_entity + * (see the comments to the function + * bfq_bfqq_must_not_expire()). + * + * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup + * there is a set of bfq_groups, each one collecting the lower-level + * entities belonging to the group that are acting on the same device. + * + * Locking works as follows: + * o @group_node is protected by the bfqio_cgroup lock, and is accessed + * via RCU from its readers. + * o @bfqd is protected by the queue lock, RCU is used to access it + * from the readers. + * o All the other fields are protected by the @bfqd queue lock. + */ +struct bfq_group { + struct bfq_entity entity; + struct bfq_sched_data sched_data; + + struct hlist_node group_node; + struct hlist_node bfqd_node; + + void *bfqd; + + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; + struct bfq_queue *async_idle_bfqq; + + struct bfq_entity *my_entity; + + int active_entities; +}; + +/** + * struct bfqio_cgroup - bfq cgroup data structure. + * @css: subsystem state for bfq in the containing cgroup. + * @weight: cgroup weight. + * @ioprio: cgroup ioprio. + * @ioprio_class: cgroup ioprio_class. + * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. + * @group_data: list containing the bfq_group belonging to this cgroup. + * + * @group_data is accessed using RCU, with @lock protecting the updates, + * @ioprio and @ioprio_class are protected by @lock. + */ +struct bfqio_cgroup { + struct cgroup_subsys_state css; + + unsigned short weight, ioprio, ioprio_class; + + spinlock_t lock; + struct hlist_head group_data; +}; +#else +struct bfq_group { + struct bfq_sched_data sched_data; + + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; + struct bfq_queue *async_idle_bfqq; +}; +#endif + +static inline struct bfq_service_tree * +bfq_entity_service_tree(struct bfq_entity *entity) +{ + struct bfq_sched_data *sched_data = entity->sched_data; + unsigned int idx = entity->ioprio_class - 1; + + BUG_ON(idx >= BFQ_IOPRIO_CLASSES); + BUG_ON(sched_data == NULL); + + return sched_data->service_tree + idx; +} + +static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, + bool is_sync) +{ + return bic->bfqq[is_sync]; +} + +static inline void bic_set_bfqq(struct bfq_io_cq *bic, + struct bfq_queue *bfqq, bool is_sync) +{ + bic->bfqq[is_sync] = bfqq; +} + +static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) +{ + return bic->icq.q->elevator->elevator_data; +} + +/** + * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. + * @ptr: a pointer to a bfqd. + * @flags: storage for the flags to be saved. + * + * This function allows bfqg->bfqd to be protected by the + * queue lock of the bfqd they reference; the pointer is dereferenced + * under RCU, so the storage for bfqd is assured to be safe as long + * as the RCU read side critical section does not end. After the + * bfqd->queue->queue_lock is taken the pointer is rechecked, to be + * sure that no other writer accessed it. If we raced with a writer, + * the function returns NULL, with the queue unlocked, otherwise it + * returns the dereferenced pointer, with the queue locked. + */ +static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, + unsigned long *flags) +{ + struct bfq_data *bfqd; + + rcu_read_lock(); + bfqd = rcu_dereference(*(struct bfq_data **)ptr); + + if (bfqd != NULL) { + spin_lock_irqsave(bfqd->queue->queue_lock, *flags); + if (*ptr == bfqd) + goto out; + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); + } + + bfqd = NULL; +out: + rcu_read_unlock(); + return bfqd; +} + +static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, + unsigned long *flags) +{ + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); +} + +static void bfq_check_ioprio_change(struct bfq_io_cq *bic); +static void bfq_put_queue(struct bfq_queue *bfqq); +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, + struct bfq_group *bfqg, int is_sync, + struct bfq_io_cq *bic, gfp_t gfp_mask); +static void bfq_end_wr_async_queues(struct bfq_data *bfqd, + struct bfq_group *bfqg); +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); + +#endif /* _BFQ_H */ diff --git a/block/fiops-iosched.c b/block/fiops-iosched.c new file mode 100644 index 0000000000000..7a3f6655040fd --- /dev/null +++ b/block/fiops-iosched.c @@ -0,0 +1,764 @@ +/* + * IOPS based IO scheduler. Based on CFQ. + * Copyright (C) 2003 Jens Axboe + * Shaohua Li + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "blk.h" + +#define VIOS_SCALE_SHIFT 10 +#define VIOS_SCALE (1 << VIOS_SCALE_SHIFT) + +#define VIOS_READ_SCALE (1) +#define VIOS_WRITE_SCALE (1) +#define VIOS_SYNC_SCALE (2) +#define VIOS_ASYNC_SCALE (5) + +#define VIOS_PRIO_SCALE (5) + +struct fiops_rb_root { + struct rb_root rb; + struct rb_node *left; + unsigned count; + + u64 min_vios; +}; +#define FIOPS_RB_ROOT (struct fiops_rb_root) { .rb = RB_ROOT} + +enum wl_prio_t { + IDLE_WORKLOAD = 0, + BE_WORKLOAD = 1, + RT_WORKLOAD = 2, + FIOPS_PRIO_NR, +}; + +struct fiops_data { + struct request_queue *queue; + + struct fiops_rb_root service_tree[FIOPS_PRIO_NR]; + + unsigned int busy_queues; + unsigned int in_flight[2]; + + struct work_struct unplug_work; + + unsigned int read_scale; + unsigned int write_scale; + unsigned int sync_scale; + unsigned int async_scale; +}; + +struct fiops_ioc { + struct io_cq icq; + + unsigned int flags; + struct fiops_data *fiopsd; + struct rb_node rb_node; + u64 vios; /* key in service_tree */ + struct fiops_rb_root *service_tree; + + unsigned int in_flight; + + struct rb_root sort_list; + struct list_head fifo; + + pid_t pid; + unsigned short ioprio; + enum wl_prio_t wl_type; +}; + +#define ioc_service_tree(ioc) (&((ioc)->fiopsd->service_tree[(ioc)->wl_type])) +#define RQ_CIC(rq) icq_to_cic((rq)->elv.icq) + +enum ioc_state_flags { + FIOPS_IOC_FLAG_on_rr = 0, /* on round-robin busy list */ + FIOPS_IOC_FLAG_prio_changed, /* task priority has changed */ +}; + +#define FIOPS_IOC_FNS(name) \ +static inline void fiops_mark_ioc_##name(struct fiops_ioc *ioc) \ +{ \ + ioc->flags |= (1 << FIOPS_IOC_FLAG_##name); \ +} \ +static inline void fiops_clear_ioc_##name(struct fiops_ioc *ioc) \ +{ \ + ioc->flags &= ~(1 << FIOPS_IOC_FLAG_##name); \ +} \ +static inline int fiops_ioc_##name(const struct fiops_ioc *ioc) \ +{ \ + return ((ioc)->flags & (1 << FIOPS_IOC_FLAG_##name)) != 0; \ +} + +FIOPS_IOC_FNS(on_rr); +FIOPS_IOC_FNS(prio_changed); +#undef FIOPS_IOC_FNS + +#define fiops_log_ioc(fiopsd, ioc, fmt, args...) \ + blk_add_trace_msg((fiopsd)->queue, "ioc%d " fmt, (ioc)->pid, ##args) +#define fiops_log(fiopsd, fmt, args...) \ + blk_add_trace_msg((fiopsd)->queue, "fiops " fmt, ##args) + +enum wl_prio_t fiops_wl_type(short prio_class) +{ + if (prio_class == IOPRIO_CLASS_RT) + return RT_WORKLOAD; + if (prio_class == IOPRIO_CLASS_BE) + return BE_WORKLOAD; + return IDLE_WORKLOAD; +} + +static inline struct fiops_ioc *icq_to_cic(struct io_cq *icq) +{ + /* cic->icq is the first member, %NULL will convert to %NULL */ + return container_of(icq, struct fiops_ioc, icq); +} + +static inline struct fiops_ioc *fiops_cic_lookup(struct fiops_data *fiopsd, + struct io_context *ioc) +{ + if (ioc) + return icq_to_cic(ioc_lookup_icq(ioc, fiopsd->queue)); + return NULL; +} + +/* + * The below is leftmost cache rbtree addon + */ +static struct fiops_ioc *fiops_rb_first(struct fiops_rb_root *root) +{ + /* Service tree is empty */ + if (!root->count) + return NULL; + + if (!root->left) + root->left = rb_first(&root->rb); + + if (root->left) + return rb_entry(root->left, struct fiops_ioc, rb_node); + + return NULL; +} + +static void rb_erase_init(struct rb_node *n, struct rb_root *root) +{ + rb_erase(n, root); + RB_CLEAR_NODE(n); +} + +static void fiops_rb_erase(struct rb_node *n, struct fiops_rb_root *root) +{ + if (root->left == n) + root->left = NULL; + rb_erase_init(n, &root->rb); + --root->count; +} + +static inline u64 max_vios(u64 min_vios, u64 vios) +{ + s64 delta = (s64)(vios - min_vios); + if (delta > 0) + min_vios = vios; + + return min_vios; +} + +static void fiops_update_min_vios(struct fiops_rb_root *service_tree) +{ + struct fiops_ioc *ioc; + + ioc = fiops_rb_first(service_tree); + if (!ioc) + return; + service_tree->min_vios = max_vios(service_tree->min_vios, ioc->vios); +} + +/* + * The fiopsd->service_trees holds all pending fiops_ioc's that have + * requests waiting to be processed. It is sorted in the order that + * we will service the queues. + */ +static void fiops_service_tree_add(struct fiops_data *fiopsd, + struct fiops_ioc *ioc) +{ + struct rb_node **p, *parent; + struct fiops_ioc *__ioc; + struct fiops_rb_root *service_tree = ioc_service_tree(ioc); + u64 vios; + int left; + + /* New added IOC */ + if (RB_EMPTY_NODE(&ioc->rb_node)) { + if (ioc->in_flight > 0) + vios = ioc->vios; + else + vios = max_vios(service_tree->min_vios, ioc->vios); + } else { + vios = ioc->vios; + /* ioc->service_tree might not equal to service_tree */ + fiops_rb_erase(&ioc->rb_node, ioc->service_tree); + ioc->service_tree = NULL; + } + + fiops_log_ioc(fiopsd, ioc, "service tree add, vios %lld", vios); + + left = 1; + parent = NULL; + ioc->service_tree = service_tree; + p = &service_tree->rb.rb_node; + while (*p) { + struct rb_node **n; + + parent = *p; + __ioc = rb_entry(parent, struct fiops_ioc, rb_node); + + /* + * sort by key, that represents service time. + */ + if (vios < __ioc->vios) + n = &(*p)->rb_left; + else { + n = &(*p)->rb_right; + left = 0; + } + + p = n; + } + + if (left) + service_tree->left = &ioc->rb_node; + + ioc->vios = vios; + rb_link_node(&ioc->rb_node, parent, p); + rb_insert_color(&ioc->rb_node, &service_tree->rb); + service_tree->count++; + + fiops_update_min_vios(service_tree); +} + +/* + * Update ioc's position in the service tree. + */ +static void fiops_resort_rr_list(struct fiops_data *fiopsd, + struct fiops_ioc *ioc) +{ + /* + * Resorting requires the ioc to be on the RR list already. + */ + if (fiops_ioc_on_rr(ioc)) + fiops_service_tree_add(fiopsd, ioc); +} + +/* + * add to busy list of queues for service, trying to be fair in ordering + * the pending list according to last request service + */ +static void fiops_add_ioc_rr(struct fiops_data *fiopsd, struct fiops_ioc *ioc) +{ + BUG_ON(fiops_ioc_on_rr(ioc)); + fiops_mark_ioc_on_rr(ioc); + + fiopsd->busy_queues++; + + fiops_resort_rr_list(fiopsd, ioc); +} + +/* + * Called when the ioc no longer has requests pending, remove it from + * the service tree. + */ +static void fiops_del_ioc_rr(struct fiops_data *fiopsd, struct fiops_ioc *ioc) +{ + BUG_ON(!fiops_ioc_on_rr(ioc)); + fiops_clear_ioc_on_rr(ioc); + + if (!RB_EMPTY_NODE(&ioc->rb_node)) { + fiops_rb_erase(&ioc->rb_node, ioc->service_tree); + ioc->service_tree = NULL; + } + + BUG_ON(!fiopsd->busy_queues); + fiopsd->busy_queues--; +} + +/* + * rb tree support functions + */ +static void fiops_del_rq_rb(struct request *rq) +{ + struct fiops_ioc *ioc = RQ_CIC(rq); + + elv_rb_del(&ioc->sort_list, rq); +} + +static void fiops_add_rq_rb(struct request *rq) +{ + struct fiops_ioc *ioc = RQ_CIC(rq); + struct fiops_data *fiopsd = ioc->fiopsd; + + elv_rb_add(&ioc->sort_list, rq); + + if (!fiops_ioc_on_rr(ioc)) + fiops_add_ioc_rr(fiopsd, ioc); +} + +static void fiops_reposition_rq_rb(struct fiops_ioc *ioc, struct request *rq) +{ + elv_rb_del(&ioc->sort_list, rq); + fiops_add_rq_rb(rq); +} + +static void fiops_remove_request(struct request *rq) +{ + list_del_init(&rq->queuelist); + fiops_del_rq_rb(rq); +} + +static u64 fiops_scaled_vios(struct fiops_data *fiopsd, + struct fiops_ioc *ioc, struct request *rq) +{ + int vios = VIOS_SCALE; + + if (rq_data_dir(rq) == WRITE) + vios = vios * fiopsd->write_scale / fiopsd->read_scale; + + if (!rq_is_sync(rq)) + vios = vios * fiopsd->async_scale / fiopsd->sync_scale; + + vios += vios * (ioc->ioprio - IOPRIO_NORM) / VIOS_PRIO_SCALE; + + return vios; +} + +/* return vios dispatched */ +static u64 fiops_dispatch_request(struct fiops_data *fiopsd, + struct fiops_ioc *ioc) +{ + struct request *rq; + struct request_queue *q = fiopsd->queue; + + rq = rq_entry_fifo(ioc->fifo.next); + + fiops_remove_request(rq); + elv_dispatch_add_tail(q, rq); + + fiopsd->in_flight[rq_is_sync(rq)]++; + ioc->in_flight++; + + return fiops_scaled_vios(fiopsd, ioc, rq); +} + +static int fiops_forced_dispatch(struct fiops_data *fiopsd) +{ + struct fiops_ioc *ioc; + int dispatched = 0; + int i; + + for (i = RT_WORKLOAD; i >= IDLE_WORKLOAD; i--) { + while (!RB_EMPTY_ROOT(&fiopsd->service_tree[i].rb)) { + ioc = fiops_rb_first(&fiopsd->service_tree[i]); + + while (!list_empty(&ioc->fifo)) { + fiops_dispatch_request(fiopsd, ioc); + dispatched++; + } + if (fiops_ioc_on_rr(ioc)) + fiops_del_ioc_rr(fiopsd, ioc); + } + } + return dispatched; +} + +static struct fiops_ioc *fiops_select_ioc(struct fiops_data *fiopsd) +{ + struct fiops_ioc *ioc; + struct fiops_rb_root *service_tree = NULL; + int i; + struct request *rq; + + for (i = RT_WORKLOAD; i >= IDLE_WORKLOAD; i--) { + if (!RB_EMPTY_ROOT(&fiopsd->service_tree[i].rb)) { + service_tree = &fiopsd->service_tree[i]; + break; + } + } + + if (!service_tree) + return NULL; + + ioc = fiops_rb_first(service_tree); + + rq = rq_entry_fifo(ioc->fifo.next); + /* + * we are the only async task and sync requests are in flight, delay a + * moment. If there are other tasks coming, sync tasks have no chance + * to be starved, don't delay + */ + if (!rq_is_sync(rq) && fiopsd->in_flight[1] != 0 && + service_tree->count == 1) { + fiops_log_ioc(fiopsd, ioc, + "postpone async, in_flight async %d sync %d", + fiopsd->in_flight[0], fiopsd->in_flight[1]); + return NULL; + } + + return ioc; +} + +static void fiops_charge_vios(struct fiops_data *fiopsd, + struct fiops_ioc *ioc, u64 vios) +{ + struct fiops_rb_root *service_tree = ioc->service_tree; + ioc->vios += vios; + + fiops_log_ioc(fiopsd, ioc, "charge vios %lld, new vios %lld", vios, ioc->vios); + + if (RB_EMPTY_ROOT(&ioc->sort_list)) + fiops_del_ioc_rr(fiopsd, ioc); + else + fiops_resort_rr_list(fiopsd, ioc); + + fiops_update_min_vios(service_tree); +} + +static int fiops_dispatch_requests(struct request_queue *q, int force) +{ + struct fiops_data *fiopsd = q->elevator->elevator_data; + struct fiops_ioc *ioc; + u64 vios; + + if (unlikely(force)) + return fiops_forced_dispatch(fiopsd); + + ioc = fiops_select_ioc(fiopsd); + if (!ioc) + return 0; + + vios = fiops_dispatch_request(fiopsd, ioc); + + fiops_charge_vios(fiopsd, ioc, vios); + return 1; +} + +static void fiops_init_prio_data(struct fiops_ioc *cic) +{ + struct task_struct *tsk = current; + struct io_context *ioc = cic->icq.ioc; + int ioprio_class; + + if (!fiops_ioc_prio_changed(cic)) + return; + + ioprio_class = IOPRIO_PRIO_CLASS(ioc->ioprio); + switch (ioprio_class) { + default: + printk(KERN_ERR "fiops: bad prio %x\n", ioprio_class); + case IOPRIO_CLASS_NONE: + /* + * no prio set, inherit CPU scheduling settings + */ + cic->ioprio = task_nice_ioprio(tsk); + cic->wl_type = fiops_wl_type(task_nice_ioclass(tsk)); + break; + case IOPRIO_CLASS_RT: + cic->ioprio = IOPRIO_PRIO_DATA(ioc->ioprio); + cic->wl_type = fiops_wl_type(IOPRIO_CLASS_RT); + break; + case IOPRIO_CLASS_BE: + cic->ioprio = IOPRIO_PRIO_DATA(ioc->ioprio); + cic->wl_type = fiops_wl_type(IOPRIO_CLASS_BE); + break; + case IOPRIO_CLASS_IDLE: + cic->wl_type = fiops_wl_type(IOPRIO_CLASS_IDLE); + cic->ioprio = 7; + break; + } + + fiops_clear_ioc_prio_changed(cic); +} + +static void fiops_insert_request(struct request_queue *q, struct request *rq) +{ + struct fiops_ioc *ioc = RQ_CIC(rq); + + fiops_init_prio_data(ioc); + + list_add_tail(&rq->queuelist, &ioc->fifo); + + fiops_add_rq_rb(rq); +} + +/* + * scheduler run of queue, if there are requests pending and no one in the + * driver that will restart queueing + */ +static inline void fiops_schedule_dispatch(struct fiops_data *fiopsd) +{ + if (fiopsd->busy_queues) + kblockd_schedule_work(fiopsd->queue, &fiopsd->unplug_work); +} + +static void fiops_completed_request(struct request_queue *q, struct request *rq) +{ + struct fiops_data *fiopsd = q->elevator->elevator_data; + struct fiops_ioc *ioc = RQ_CIC(rq); + + fiopsd->in_flight[rq_is_sync(rq)]--; + ioc->in_flight--; + + fiops_log_ioc(fiopsd, ioc, "in_flight %d, busy queues %d", + ioc->in_flight, fiopsd->busy_queues); + + if (fiopsd->in_flight[0] + fiopsd->in_flight[1] == 0) + fiops_schedule_dispatch(fiopsd); +} + +static struct request * +fiops_find_rq_fmerge(struct fiops_data *fiopsd, struct bio *bio) +{ + struct task_struct *tsk = current; + struct fiops_ioc *cic; + + cic = fiops_cic_lookup(fiopsd, tsk->io_context); + + if (cic) { + sector_t sector = bio->bi_sector + bio_sectors(bio); + + return elv_rb_find(&cic->sort_list, sector); + } + + return NULL; +} + +static int fiops_merge(struct request_queue *q, struct request **req, + struct bio *bio) +{ + struct fiops_data *fiopsd = q->elevator->elevator_data; + struct request *__rq; + + __rq = fiops_find_rq_fmerge(fiopsd, bio); + if (__rq && elv_rq_merge_ok(__rq, bio)) { + *req = __rq; + return ELEVATOR_FRONT_MERGE; + } + + return ELEVATOR_NO_MERGE; +} + +static void fiops_merged_request(struct request_queue *q, struct request *req, + int type) +{ + if (type == ELEVATOR_FRONT_MERGE) { + struct fiops_ioc *ioc = RQ_CIC(req); + + fiops_reposition_rq_rb(ioc, req); + } +} + +static void +fiops_merged_requests(struct request_queue *q, struct request *rq, + struct request *next) +{ + struct fiops_ioc *ioc = RQ_CIC(rq); + struct fiops_data *fiopsd = q->elevator->elevator_data; + + fiops_remove_request(next); + + ioc = RQ_CIC(next); + /* + * all requests of this task are merged to other tasks, delete it + * from the service tree. + */ + if (fiops_ioc_on_rr(ioc) && RB_EMPTY_ROOT(&ioc->sort_list)) + fiops_del_ioc_rr(fiopsd, ioc); +} + +static int fiops_allow_merge(struct request_queue *q, struct request *rq, + struct bio *bio) +{ + struct fiops_data *fiopsd = q->elevator->elevator_data; + struct fiops_ioc *cic; + + /* + * Lookup the ioc that this bio will be queued with. Allow + * merge only if rq is queued there. + */ + cic = fiops_cic_lookup(fiopsd, current->io_context); + + return cic == RQ_CIC(rq); +} + +static void fiops_exit_queue(struct elevator_queue *e) +{ + struct fiops_data *fiopsd = e->elevator_data; + + cancel_work_sync(&fiopsd->unplug_work); + + kfree(fiopsd); +} + +static void fiops_kick_queue(struct work_struct *work) +{ + struct fiops_data *fiopsd = + container_of(work, struct fiops_data, unplug_work); + struct request_queue *q = fiopsd->queue; + + spin_lock_irq(q->queue_lock); + __blk_run_queue(q); + spin_unlock_irq(q->queue_lock); +} + +static int fiops_init_queue(struct request_queue *q, struct elevator_type *e) +{ + struct fiops_data *fiopsd; + int i; + struct elevator_queue *eq; + + eq = elevator_alloc(q, e); + if (!eq) + return -ENOMEM; + + fiopsd = kzalloc_node(sizeof(*fiopsd), GFP_KERNEL, q->node); + if (!fiopsd) { + kobject_put(&eq->kobj); + return -ENOMEM; + } + eq->elevator_data = fiopsd; + + fiopsd->queue = q; + spin_lock_irq(q->queue_lock); + q->elevator = eq; + spin_unlock_irq(q->queue_lock); + + for (i = IDLE_WORKLOAD; i <= RT_WORKLOAD; i++) + fiopsd->service_tree[i] = FIOPS_RB_ROOT; + + INIT_WORK(&fiopsd->unplug_work, fiops_kick_queue); + + fiopsd->read_scale = VIOS_READ_SCALE; + fiopsd->write_scale = VIOS_WRITE_SCALE; + fiopsd->sync_scale = VIOS_SYNC_SCALE; + fiopsd->async_scale = VIOS_ASYNC_SCALE; + + return 0; +} + +static void fiops_init_icq(struct io_cq *icq) +{ + struct fiops_data *fiopsd = icq->q->elevator->elevator_data; + struct fiops_ioc *ioc = icq_to_cic(icq); + + RB_CLEAR_NODE(&ioc->rb_node); + INIT_LIST_HEAD(&ioc->fifo); + ioc->sort_list = RB_ROOT; + + ioc->fiopsd = fiopsd; + + ioc->pid = current->pid; + fiops_mark_ioc_prio_changed(ioc); +} + +/* + * sysfs parts below --> + */ +static ssize_t +fiops_var_show(unsigned int var, char *page) +{ + return sprintf(page, "%d\n", var); +} + +static ssize_t +fiops_var_store(unsigned int *var, const char *page, size_t count) +{ + char *p = (char *) page; + + *var = simple_strtoul(p, &p, 10); + return count; +} + +#define SHOW_FUNCTION(__FUNC, __VAR) \ +static ssize_t __FUNC(struct elevator_queue *e, char *page) \ +{ \ + struct fiops_data *fiopsd = e->elevator_data; \ + return fiops_var_show(__VAR, (page)); \ +} +SHOW_FUNCTION(fiops_read_scale_show, fiopsd->read_scale); +SHOW_FUNCTION(fiops_write_scale_show, fiopsd->write_scale); +SHOW_FUNCTION(fiops_sync_scale_show, fiopsd->sync_scale); +SHOW_FUNCTION(fiops_async_scale_show, fiopsd->async_scale); +#undef SHOW_FUNCTION + +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \ +static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count) \ +{ \ + struct fiops_data *fiopsd = e->elevator_data; \ + unsigned int __data; \ + int ret = fiops_var_store(&__data, (page), count); \ + if (__data < (MIN)) \ + __data = (MIN); \ + else if (__data > (MAX)) \ + __data = (MAX); \ + *(__PTR) = __data; \ + return ret; \ +} +STORE_FUNCTION(fiops_read_scale_store, &fiopsd->read_scale, 1, 100); +STORE_FUNCTION(fiops_write_scale_store, &fiopsd->write_scale, 1, 100); +STORE_FUNCTION(fiops_sync_scale_store, &fiopsd->sync_scale, 1, 100); +STORE_FUNCTION(fiops_async_scale_store, &fiopsd->async_scale, 1, 100); +#undef STORE_FUNCTION + +#define FIOPS_ATTR(name) \ + __ATTR(name, S_IRUGO|S_IWUSR, fiops_##name##_show, fiops_##name##_store) + +static struct elv_fs_entry fiops_attrs[] = { + FIOPS_ATTR(read_scale), + FIOPS_ATTR(write_scale), + FIOPS_ATTR(sync_scale), + FIOPS_ATTR(async_scale), + __ATTR_NULL +}; + +static struct elevator_type iosched_fiops = { + .ops = { + .elevator_merge_fn = fiops_merge, + .elevator_merged_fn = fiops_merged_request, + .elevator_merge_req_fn = fiops_merged_requests, + .elevator_allow_merge_fn = fiops_allow_merge, + .elevator_dispatch_fn = fiops_dispatch_requests, + .elevator_add_req_fn = fiops_insert_request, + .elevator_completed_req_fn = fiops_completed_request, + .elevator_former_req_fn = elv_rb_former_request, + .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_init_icq_fn = fiops_init_icq, + .elevator_init_fn = fiops_init_queue, + .elevator_exit_fn = fiops_exit_queue, + }, + .icq_size = sizeof(struct fiops_ioc), + .icq_align = __alignof__(struct fiops_ioc), + .elevator_attrs = fiops_attrs, + .elevator_name = "fiops", + .elevator_owner = THIS_MODULE, +}; + +static int __init fiops_init(void) +{ + return elv_register(&iosched_fiops); +} + +static void __exit fiops_exit(void) +{ + elv_unregister(&iosched_fiops); +} + +module_init(fiops_init); +module_exit(fiops_exit); + +MODULE_AUTHOR("Jens Axboe, Shaohua Li "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("IOPS based IO scheduler"); diff --git a/drivers/Kconfig b/drivers/Kconfig index 69c7c1c99fbf2..d39a9846f2efa 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -188,4 +188,15 @@ source "drivers/soc/Kconfig" source "drivers/firmware/Kconfig" +#ifdef VENDOR_EDIT +# hefaxi@filesystem,2015/05/05,support param partion read/write +source "drivers/param_read_write/Kconfig" +#endif + +#add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +source "drivers/oem_debug/Kconfig" +#endif +#end add by jiachenghui for support oem trace,2015/05/09 + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 1e45a0a5cafae..a753c696518ba 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -168,3 +168,14 @@ obj-$(CONFIG_ESOC) += esoc/ obj-$(CONFIG_BIF) += bif/ obj-$(CONFIG_SENSORS) += sensors/ obj-$(CONFIG_SENSORS_SSC) += sensors/ + +#ifdef VENDOR_EDIT +# hefaxi@filesystem,2015/05/05,support param partion read/write +obj-y += param_read_write/ +#endif + +#add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +obj-$(CONFIG_OEM_DEBUG_SUPORT) += oem_debug/ +#endif +#end add by jiachenghui for support oem trace,2015/05/09 diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c old mode 100644 new mode 100755 index f6e779e4f11ec..2e2c84ba9e7f1 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -218,6 +218,36 @@ static __init struct cma *cma_create_area(unsigned long base_pfn, /*****************************************************************************/ +//add by jiachenghui for nv backup +#ifdef VENDOR_EDIT +void init_param_mem_base_size(phys_addr_t base, unsigned long size); +void __init oem_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base, + phys_addr_t limit, const char *name) +{ + phys_addr_t base = *res_base; + + pr_debug("%s(size %lx, base %pa, limit %pa)\n", __func__, + (unsigned long)size, &base, + &limit); + + if (base) { + if (memblock_is_region_reserved(base, size) || + memblock_reserve(base, size) < 0) { + printk("OEM: reserve fail EBUSY(%s, base:%pa)\n", name, &base); + } + else{ + printk("OEM: Found %s, memory base %pa, size %ld MiB, limit %pa\n", name,&base, (unsigned long)size / SZ_1M, &limit); + if(!strncmp(name, "param_mem",9)) + init_param_mem_base_size(base,size); + } + } else { + printk("OEM: (%s) reserve address NULL\n", name); + } + +} +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for nv backup + #ifdef CONFIG_OF int __init cma_fdt_scan(unsigned long node, const char *uname, int depth, void *data) @@ -232,6 +262,11 @@ int __init cma_fdt_scan(unsigned long node, const char *uname, unsigned long addr_cells = dt_root_addr_cells; phys_addr_t limit = MEMBLOCK_ALLOC_ANYWHERE; const char *status; +//add by jiachenghui for nv backup +#ifdef VENDOR_EDIT + bool oem_reserve; +#endif /*VENDOR_EDIT*/ +//add by jiachenghui for nv backup if (!of_get_flat_dt_prop(node, "linux,reserve-contiguous-region", NULL)) return 0; @@ -270,6 +305,16 @@ int __init cma_fdt_scan(unsigned long node, const char *uname, remove = of_get_flat_dt_prop(node, "linux,remove-completely", NULL) ? 1 : 0; +//add by jiachenghui for nv backup +#ifdef VENDOR_EDIT + oem_reserve = of_get_flat_dt_prop(node, "oem,reserve-region", NULL) ? 1 : 0; + if(oem_reserve){ + oem_contiguous_reserve_area(size, &base, limit, name); + return 0; + } +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for nv backup + pr_info("Found %s, memory base %pa, size %ld MiB, limit %pa\n", uname, &base, (unsigned long)size / SZ_1M, &limit); dma_contiguous_reserve_area(size, &base, limit, name, diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c old mode 100644 new mode 100755 index 79715e7fa43e3..40c61b5eda584 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -5,7 +5,10 @@ * * This file is released under the GPLv2. */ - +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for active wl dump */ +#include +#endif /* VENDOR_EDIT */ #include #include #include @@ -855,6 +858,48 @@ static int print_wakeup_source_stats(struct seq_file *m, return ret; } +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for active wl dump */ +static int dump_active_wakeup_source(struct wakeup_source *ws) +{ + unsigned long flags; + ktime_t total_time; + ktime_t max_time; + unsigned long active_count; + ktime_t active_time; + ktime_t prevent_sleep_time; + int ret = 0; + + spin_lock_irqsave(&ws->lock, flags); + + total_time = ws->total_time; + max_time = ws->max_time; + prevent_sleep_time = ws->prevent_sleep_time; + active_count = ws->active_count; + if (ws->active) { + ktime_t now = ktime_get(); + + active_time = ktime_sub(now, ws->last_time); + total_time = ktime_add(total_time, active_time); + if (active_time.tv64 > max_time.tv64) + max_time = active_time; + + if (ws->autosleep_enabled) + prevent_sleep_time = ktime_add(prevent_sleep_time, + ktime_sub(now, ws->start_prevent_time)); + } else { + active_time = ktime_set(0, 0); + } + + if(ktime_to_ms(active_time)) + pr_info("%-12s\t %lld\n",ws->name, ktime_to_ms(active_time)); + + spin_unlock_irqrestore(&ws->lock, flags); + + return ret; +} +#endif /* VENDOR_EDIT */ + /** * wakeup_sources_stats_show - Print wakeup sources statistics information. * @m: seq_file to print the statistics into. @@ -888,10 +933,46 @@ static const struct file_operations wakeup_sources_stats_fops = { .release = single_release, }; +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for active wl dump */ +static struct workqueue_struct *wakelock_dump_wq; +static struct delayed_work wakelock_dump_worker; + +static bool dump_active_wl_enable = false; +module_param(dump_active_wl_enable, bool, S_IRUGO | S_IWUSR); + +static void dump_active_wl(void) +{ + struct wakeup_source *ws; + + rcu_read_lock(); + + pr_info("%s+++++++++++++++++\n",__func__); + list_for_each_entry_rcu(ws, &wakeup_sources, entry) + dump_active_wakeup_source(ws); + pr_info("%s-----------------\n",__func__); + + rcu_read_unlock(); +} + +static void wakelock_dump_handler(struct work_struct *work) +{ + if(dump_active_wl_enable) + dump_active_wl(); + queue_delayed_work(wakelock_dump_wq,&wakelock_dump_worker, 20 * HZ); +} +#endif /* VENDOR_EDIT */ + static int __init wakeup_sources_debugfs_init(void) { wakeup_sources_stats_dentry = debugfs_create_file("wakeup_sources", S_IRUGO, NULL, NULL, &wakeup_sources_stats_fops); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for active wl dump */ + wakelock_dump_wq = create_singlethread_workqueue("wakelock_dump_wq"); + INIT_DELAYED_WORK(&wakelock_dump_worker,wakelock_dump_handler); + queue_delayed_work(wakelock_dump_wq,&wakelock_dump_worker, 20 * HZ); +#endif /* VENDOR_EDIT */ return 0; } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 38d3069b7f0a4..36c320364c5fa 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -774,7 +774,8 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig) #if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT) static int open_port(struct inode *inode, struct file *filp) { - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; + return 0; + //return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } #endif diff --git a/drivers/clk/qcom/clock-cpu-8994.c b/drivers/clk/qcom/clock-cpu-8994.c old mode 100644 new mode 100755 index 6eb346b754204..95f090a5f07f8 --- a/drivers/clk/qcom/clock-cpu-8994.c +++ b/drivers/clk/qcom/clock-cpu-8994.c @@ -1518,6 +1518,11 @@ static int add_opp(struct clk *c, struct device *cpudev, struct device *vregdev, return 0; } +static unsigned long ftm_apc0_fmax; +static unsigned long ftm_apc1_fmax; +module_param(ftm_apc0_fmax, ulong, 0444); +module_param(ftm_apc1_fmax, ulong, 0444); + static void print_opp_table(int a53_cpu, int a57_cpu) { struct opp *oppfmax, *oppfmin; @@ -1544,6 +1549,8 @@ static void print_opp_table(int a53_cpu, int a57_cpu) true); oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a57_cpu), apc1_fmin, true); + ftm_apc0_fmax = apc0_fmax/1000; + ftm_apc1_fmax = apc1_fmax/1000; pr_info("clock_cpu: a57: OPP voltage for %lu: %lu\n", apc1_fmin, dev_pm_opp_get_voltage(oppfmin)); pr_info("clock_cpu: a57: OPP voltage for %lu: %lu\n", apc1_fmax, @@ -1644,6 +1651,14 @@ static void init_v2_data(void) static int a57speedbin; static int a53speedbin; +module_param(a57speedbin, int, 0444); +module_param(a53speedbin, int, 0444); + +int get_chipset_a57speedbin(void) +{ + return a57speedbin; +} +EXPORT_SYMBOL(get_chipset_a57speedbin); struct platform_device *cpu_clock_8994_dev; /* Low power mux code begins here */ diff --git a/drivers/clk/qcom/clock-debug.c b/drivers/clk/qcom/clock-debug.c old mode 100644 new mode 100755 index d0ff821eb2039..f342e85ad6608 --- a/drivers/clk/qcom/clock-debug.c +++ b/drivers/clk/qcom/clock-debug.c @@ -534,6 +534,10 @@ static void clock_measure_add(struct clk *clock) &clock_measure_fops); } +//#ifdef VENDOR_EDIT //changhua add for control spi12 ahb,qup in fpc1020_main.c sysfs +struct clk* blsp2_ahb_clk; +struct clk* blsp2_qup6_spi_clk; +//#endif static int clock_debug_add(struct clk *clock) { char temp[50], *ptr; @@ -545,7 +549,19 @@ static int clock_debug_add(struct clk *clock) strlcpy(temp, clock->dbg_name, ARRAY_SIZE(temp)); for (ptr = temp; *ptr; ptr++) *ptr = tolower(*ptr); - + + //#ifdef VENDOR_EDIT //changhua add for control spi12 ahb,qup in fpc1020_main.c sysfs + //printk("%s : %s \n",__func__,temp); + if(strcmp(temp,"gcc_blsp2_ahb_clk")==0) + { printk("%s : gcc_blsp2_ahb_clk \n",__func__); + blsp2_ahb_clk=clock; + } + if(strcmp(temp,"gcc_blsp2_qup6_spi_apps_clk")==0) + { printk("%s : gcc_blsp2_qup6_spi_apps_clk \n",__func__); + blsp2_qup6_spi_clk=clock; + } + //#endif + clk_dir = debugfs_create_dir(temp, debugfs_base); if (!clk_dir) return -ENOMEM; diff --git a/drivers/cpufreq/cpu-boost.c b/drivers/cpufreq/cpu-boost.c index 545d484b17596..b5b3fbf5d1c09 100644 --- a/drivers/cpufreq/cpu-boost.c +++ b/drivers/cpufreq/cpu-boost.c @@ -48,6 +48,11 @@ static struct work_struct input_boost_work; static unsigned int boost_ms; module_param(boost_ms, uint, 0644); +#ifdef VENDOR_EDIT +extern unsigned int sysctl_thermal_aware_scheduling; +module_param(sysctl_thermal_aware_scheduling, uint, 0644); +#endif + static unsigned int sync_threshold; module_param(sync_threshold, uint, 0644); diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c old mode 100644 new mode 100755 index 3e64a87310e71..77d1048cff88e --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -393,7 +393,7 @@ static u64 update_load(int cpu) } #define MAX_LOCAL_LOAD 100 -static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) +static void cpufreq_interactive_timer(unsigned long data) { u64 now; unsigned int delta_time; @@ -496,7 +496,7 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) new_freq = pcpu->freq_table[index].frequency; - if (!is_notif && new_freq < pcpu->target_freq && + if (new_freq < pcpu->target_freq && now - pcpu->max_freq_hyst_start_time < tunables->max_freq_hysteresis) { trace_cpufreq_interactive_notyet(data, cpu_load, @@ -510,7 +510,7 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) * floor frequency for the minimum sample time since last validated. */ max_fvtime = max(pcpu->floor_validate_time, pcpu->local_fvtime); - if (!is_notif && new_freq < pcpu->floor_freq && + if (new_freq < pcpu->floor_freq && pcpu->target_freq >= pcpu->policy->cur) { if (now - max_fvtime < tunables->min_sample_time) { trace_cpufreq_interactive_notyet( @@ -566,10 +566,6 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) return; } -static void cpufreq_interactive_timer(unsigned long data) -{ - __cpufreq_interactive_timer(data, false); -} static void cpufreq_interactive_idle_end(void) { @@ -741,7 +737,7 @@ static int load_change_callback(struct notifier_block *nb, unsigned long val, trace_cpufreq_interactive_load_change(cpu); del_timer(&pcpu->cpu_timer); del_timer(&pcpu->cpu_slack_timer); - __cpufreq_interactive_timer(cpu, true); + cpufreq_interactive_timer(cpu); up_read(&pcpu->enable_sem); return 0; diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index a1873a868976a..c6c98558840ca 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -108,7 +108,7 @@ config DEVFREQ_GOV_MSM_GPUBW_MON config DEVFREQ_GOV_MSM_BW_HWMON tristate "HW monitor based governor for device BW" - depends on ARCH_MSM_KRAIT || ARCH_MSM_BIMC_BWMON + depends on ARCH_MSM_KRAIT || MSM_BIMC_BWMON help HW monitor based governor for device to DDR bandwidth voting. diff --git a/drivers/devfreq/governor_cpufreq.c b/drivers/devfreq/governor_cpufreq.c index d8cce47979ffa..fec80dfe49cc6 100644 --- a/drivers/devfreq/governor_cpufreq.c +++ b/drivers/devfreq/governor_cpufreq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -52,6 +52,7 @@ struct devfreq_node { }; static LIST_HEAD(devfreq_list); static DEFINE_MUTEX(state_lock); +static DEFINE_MUTEX(cpufreq_reg_lock); #define show_attr(name) \ static ssize_t show_##name(struct device *dev, \ @@ -239,7 +240,7 @@ static int register_cpufreq(void) unsigned int cpu; struct cpufreq_policy *policy; - mutex_lock(&state_lock); + mutex_lock(&cpufreq_reg_lock); if (cpufreq_cnt) goto cnt_not_zero; @@ -270,7 +271,7 @@ static int register_cpufreq(void) cnt_not_zero: if (!ret) cpufreq_cnt++; - mutex_unlock(&state_lock); + mutex_unlock(&cpufreq_reg_lock); return ret; } @@ -279,7 +280,7 @@ static int unregister_cpufreq(void) int ret = 0; int cpu; - mutex_lock(&state_lock); + mutex_lock(&cpufreq_reg_lock); if (cpufreq_cnt > 1) goto out; @@ -299,7 +300,7 @@ static int unregister_cpufreq(void) out: cpufreq_cnt--; - mutex_unlock(&state_lock); + mutex_unlock(&cpufreq_reg_lock); return ret; } diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c old mode 100644 new mode 100755 index f498c757bd938..48ffb0486d6bc --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -32,6 +32,7 @@ #define KGSL_PWRFLAGS_CLK_ON 1 #define KGSL_PWRFLAGS_AXI_ON 2 #define KGSL_PWRFLAGS_IRQ_ON 3 +#define KGSL_PWRFLAGS_WAKEUP_PWRLEVEL 4 #define UPDATE_BUSY_VAL 1000000 @@ -367,6 +368,14 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, new_level = _adjust_pwrlevel(pwr, new_level, &pwr->constraint, device->pwrscale.popp_level); + /* + * When waking up from SLUMBER at turbo then set the pwrlevel + * to one level below turbo + */ + if (new_level == 0 && test_bit(KGSL_PWRFLAGS_WAKEUP_PWRLEVEL, + &device->pwrctrl.ctrl_flags)) + new_level = 1; + /* * If thermal cycling is required and the new level hits the * thermal limit, kick off the cycling. @@ -1398,6 +1407,7 @@ void kgsl_thermal_timer(unsigned long data) queue_work(device->work_queue, &device->pwrctrl.thermal_cycle_ws); } +int get_chipset_a57speedbin(void); int kgsl_pwrctrl_init(struct kgsl_device *device) { int i, k, m, set_bus = 1, n = 0, result = 0; @@ -1436,6 +1446,10 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) /* Initialize the user and thermal clock constraints */ pwr->max_pwrlevel = 0; +#if 0 + if(get_chipset_a57speedbin()) + pwr->max_pwrlevel = 1; +#endif pwr->min_pwrlevel = pdata->num_levels - 2; pwr->thermal_pwrlevel = 0; @@ -1918,7 +1932,16 @@ _aware(struct kgsl_device *device) del_timer_sync(&device->idle_timer); break; case KGSL_STATE_SLUMBER: + /* + * Set this flag to avoid waking up at turbo + * because wakeup at turbo is not stable + * on some slow parts + */ + set_bit(KGSL_PWRFLAGS_WAKEUP_PWRLEVEL, + &device->pwrctrl.ctrl_flags); status = kgsl_pwrctrl_enable(device); + clear_bit(KGSL_PWRFLAGS_WAKEUP_PWRLEVEL, + &device->pwrctrl.ctrl_flags); break; default: status = -EINVAL; diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index c6a85f5474079..a5dd336bb2b5e 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -407,7 +407,13 @@ struct i2c_msm_clk_div_fld { * divider values as per HW Designers */ static struct i2c_msm_clk_div_fld i2c_msm_clk_div_map[] = { +#ifndef VENDOR_EDIT //add by jiachenghui for DCDC I2C SCL duty cycle 2015-06-26 {KHz(100), 124, 62}, +//add by jiachenghui for DCDC I2C SCL duty cycle 2015-06-26 +#else + {KHz(100), 93, 0},//19200/(100*2)-3 +#endif //VENDOR_EDIT +//end add by jiachenghui for DCDC I2C SCL duty cycle 2015-06-26 {KHz(400), 28, 14}, {KHz(1000), 8, 5}, }; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 8eda2894c4b05..e589434645b3c 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -31,6 +31,11 @@ #include #include +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/07/03, add for force dump function +#include +#endif + struct gpio_button_data { const struct gpio_keys_button *button; struct input_dev *input; @@ -331,6 +336,11 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/07/03, add for force dump function + oem_check_force_dump_key(button->code,state); +#endif + if (type == EV_ABS) { if (state) input_event(input, type, button->code, button->value); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig old mode 100644 new mode 100755 index 95ddc97ca3aea..3949a1aaa2328 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -863,5 +863,33 @@ config SENSORS_ISL29044A help This option enables support for the INTERSIL ISL29044A P/L sensor. +#add for fpc1021 fingerprints +config BTP_FPC1021 + default n + tristate "FPC_BTP fingerprint sensor support" + depends on SPI_MASTER +#add end +#VENDOR_EDIT changhua 2015-02-28 add for switch Profiles by triple state switch key +config TRI_STATE_KEY + default n + tristate "switch Profiles by this triple key" + help + Say Y here if you want to enable the feature. +#add end +config SWITCH_ANTENNA + default n + tristate "switch ANTENNA by gpio" + help + Say Y here if you want to enable the feature. +#add end + +#changhua 2015-02-12 add for switch theme when change rare cover +config SWITCH_THEME + default n + tristate "switch theme when change rare cover support by ADC" + help + Say Y here if you want to enable the feature. +#add end + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile old mode 100644 new mode 100755 index 1849fa48b24be..d8a112c6f6d16 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -89,3 +89,12 @@ endif obj-$(CONFIG_SENSORS_MC3430) += mc3xxx.o obj-$(CONFIG_SENSORS_ISL29044A) += isl29044a.o +#VENDOR_EDIT add for fpc1021 fingerprints +obj-$(CONFIG_BTP_FPC1021) += fpc1020_main.o fpc1020_capture.o fpc1020_common.o fpc1020_regulator.o fpc1020_nav.o +#VENDOR_EDIT changhua add for tree state keys +obj-$(CONFIG_TRI_STATE_KEY) += tri_state_key.o +#VNEDOR_EDIT changhua add for use apk to controll antenna switch,MP not use +obj-$(CONFIG_SWITCH_ANTENNA) += switch_antenna.o + +#changhua add for switch theme +obj-$(CONFIG_SWITCH_THEME) += switch_theme.o diff --git a/drivers/input/misc/fpc1020.h b/drivers/input/misc/fpc1020.h new file mode 100755 index 0000000000000..7e8b1e38d0388 --- /dev/null +++ b/drivers/input/misc/fpc1020.h @@ -0,0 +1,56 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef LINUX_SPI_FPC1020_H +#define LINUX_SPI_FPC1020_H + +struct fpc1020_platform_data { + int irq_gpio; + int reset_gpio; +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for Hw Config + int cs_gpio; +#else /* VENDOR_EDIT */ + int vdden_gpio; +#endif /* VENDOR_EDIT */ + #ifdef VENDOR_EDIT //changhua add for reconize DT CT module + int vendor_gpio; + int fp2050_gpio; + #endif + int external_supply_mv; + int txout_boost; +}; + +typedef enum { + FPC1020_MODE_IDLE = 0, + FPC1020_MODE_WAIT_AND_CAPTURE = 1, + FPC1020_MODE_SINGLE_CAPTURE = 2, + FPC1020_MODE_CHECKERBOARD_TEST_NORM = 3, + FPC1020_MODE_CHECKERBOARD_TEST_INV = 4, + FPC1020_MODE_BOARD_TEST_ONE = 5, + FPC1020_MODE_BOARD_TEST_ZERO = 6, + FPC1020_MODE_WAIT_FINGER_DOWN = 7, + FPC1020_MODE_WAIT_FINGER_UP = 8, + FPC1020_MODE_SINGLE_CAPTURE_CAL = 9, + FPC1020_MODE_CAPTURE_AND_WAIT_FINGER_UP = 10, +} fpc1020_capture_mode_t; + +typedef enum { + FPC1020_CHIP_NONE = 0, + FPC1020_CHIP_1020A = 1, + FPC1020_CHIP_1021A = 2, + FPC1020_CHIP_1021B = 3, + FPC1020_CHIP_1150A = 4, + FPC1020_CHIP_1150B = 5, + FPC1020_CHIP_1150F = 6, + FPC1020_CHIP_1155X = 7 +} fpc1020_chip_t; + +#endif + diff --git a/drivers/input/misc/fpc1020_capture.c b/drivers/input/misc/fpc1020_capture.c new file mode 100755 index 0000000000000..c468d3c27f9f1 --- /dev/null +++ b/drivers/input/misc/fpc1020_capture.c @@ -0,0 +1,805 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#define DEBUG + +#include +#include +#include + +#if 0 //#ifndef CONFIG_USE_OF //oneplus changhua modify for MSM8994 +#include +#include +#else +#include "fpc1020_common.h" +#include "fpc1020_capture.h" +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for fingerprint animation +#include "fpc1020_input.h" +#endif /* VENDOR_EDIT */ +#endif + + +/* -------------------------------------------------------------------- */ +/* function prototypes */ +/* -------------------------------------------------------------------- */ +static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020); +int fpc1020_capture_finger_detect_settings(fpc1020_data_t *fpc1020); + + + +/* -------------------------------------------------------------------- */ +/* function definitions */ +/* -------------------------------------------------------------------- */ +int fpc1020_init_capture(fpc1020_data_t *fpc1020) +{ + fpc1020->capture.state = FPC1020_CAPTURE_STATE_IDLE; + fpc1020->capture.current_mode = FPC1020_MODE_IDLE; + fpc1020->capture.available_bytes = 0; + fpc1020->capture.deferred_finger_up = false; + + init_waitqueue_head(&fpc1020->capture.wq_data_avail); + + return 0; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_write_capture_setup(fpc1020_data_t *fpc1020) +{ + return fpc1020_write_sensor_setup(fpc1020); +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_write_test_setup(fpc1020_data_t *fpc1020, u16 pattern) +{ + int error = 0; + u8 config = 0x04; + fpc1020_reg_access_t reg; + + dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, pattern); + + error = fpc1020_write_sensor_setup(fpc1020); + if (error) + goto out; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &pattern); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &config); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + error = fpc1020_capture_settings(fpc1020, 0); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_write_cb_test_setup_102x(fpc1020_data_t *fpc1020, bool invert) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u64 temp_u64; + fpc1020_reg_access_t reg; + + temp_u16 = (invert) ? 0x55aa : 0xaa55; + dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16); + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x04; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = (invert) ? 0x0f1b : 0x0f0f; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = (invert) ? 0x0800 : 0x00; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x14; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x20; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x1e1e1e1e2d2d2d2d; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_write_cb_test_setup_1155(fpc1020_data_t *fpc1020, bool invert) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u64 temp_u64; + fpc1020_reg_access_t reg; + + temp_u16 = (invert) ? 0x55aa : 0xaa55; + dev_dbg(&fpc1020->spi->dev, "%s, pattern 0x%x\n", __func__, temp_u16); + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x14; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = (invert) ? 0x0f1a : 0x0f0e; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = (invert) ? 0x0800 : 0x0000; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x2f; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x38; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x373737373f3f3f3f; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x5540002d24; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; +out: + return error; +} + +/* -------------------------------------------------------------------- */ +int fpc1020_write_cb_test_setup(fpc1020_data_t *fpc1020, bool invert) +{ + return (fpc1020->chip.type == FPC1020_CHIP_1155X) ? + fpc1020_write_cb_test_setup_1155(fpc1020, invert) : + fpc1020_write_cb_test_setup_102x(fpc1020, invert); +} + + +/* -------------------------------------------------------------------- */ +bool fpc1020_capture_check_ready(fpc1020_data_t *fpc1020) +{ + fpc1020_capture_state_t state = fpc1020->capture.state; + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-11-19 Add for debug info for fpc1020_read no return + static fpc1020_capture_state_t last_state = 0; + if (last_state != state) { + dev_dbg(&fpc1020->spi->dev, "%s state %d nav_enabled %d\n", __func__, state, fpc1020->nav.enabled); + last_state = state; + } +#endif /* VENDOR_EDIT */ + + + return ((state == FPC1020_CAPTURE_STATE_IDLE) || + (state == FPC1020_CAPTURE_STATE_COMPLETED) || + (state == FPC1020_CAPTURE_STATE_FAILED)) && + (!fpc1020->nav.enabled); +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_task(fpc1020_data_t *fpc1020) +{ + struct timespec ts_t1, ts_t2, ts_t3, ts_delta; + int time_settings_us[FPC1020_BUFFER_MAX_IMAGES]; + int time_capture_us[FPC1020_BUFFER_MAX_IMAGES]; + int time_capture_sum_us; + int error = 0; + bool wait_finger_down = false; + bool wait_finger_up = false; + bool adjust_settings; + fpc1020_capture_mode_t mode = fpc1020->capture.current_mode; + int current_capture, capture_count; + int image_offset; + size_t image_byte_size; + + fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS; + + error = fpc1020_wake_up(fpc1020); + if (error < 0) + goto out_error; + + switch (mode) { + case FPC1020_MODE_CAPTURE_AND_WAIT_FINGER_UP: + wait_finger_up = true; + capture_count = fpc1020->setup.capture_count; + adjust_settings = true; + error = fpc1020_write_capture_setup(fpc1020); + break; + + case FPC1020_MODE_WAIT_AND_CAPTURE: + wait_finger_down = + wait_finger_up = true; + + case FPC1020_MODE_SINGLE_CAPTURE: + case FPC1020_MODE_SINGLE_CAPTURE_CAL: + capture_count = fpc1020->setup.capture_count; + adjust_settings = true; + error = fpc1020_write_capture_setup(fpc1020); + break; + + case FPC1020_MODE_CHECKERBOARD_TEST_NORM: + capture_count = 1; + adjust_settings = false; + error = fpc1020_write_cb_test_setup(fpc1020, false); + break; + + case FPC1020_MODE_CHECKERBOARD_TEST_INV: + capture_count = 1; + adjust_settings = false; + error = fpc1020_write_cb_test_setup(fpc1020, true); + break; + + case FPC1020_MODE_BOARD_TEST_ONE: + capture_count = 1; + adjust_settings = false; + error = fpc1020_write_test_setup(fpc1020, 0xffff); + break; + + case FPC1020_MODE_BOARD_TEST_ZERO: + capture_count = 1; + adjust_settings = false; + error = fpc1020_write_test_setup(fpc1020, 0x0000); + break; + + case FPC1020_MODE_WAIT_FINGER_DOWN: + wait_finger_down = true; + capture_count = 0; + adjust_settings = false; + error = fpc1020_write_capture_setup(fpc1020); + break; + + case FPC1020_MODE_WAIT_FINGER_UP: + wait_finger_up = true; + capture_count = 0; + adjust_settings = false; + error = fpc1020_write_capture_setup(fpc1020); + break; + + case FPC1020_MODE_IDLE: + default: + capture_count = 0; + adjust_settings = false; + error = -EINVAL; + break; + } + + if (error < 0) + goto out_error; + + error = fpc1020_capture_set_crop(fpc1020, + fpc1020->setup.capture_col_start, + fpc1020->setup.capture_col_groups, + fpc1020->setup.capture_row_start, + fpc1020->setup.capture_row_count); + if (error < 0) + goto out_error; + + image_byte_size = fpc1020_calc_image_size(fpc1020); + + /*dev_dbg(&fpc1020->spi->dev, + "Start capture, mode %d, (%d frames)\n", + mode, + capture_count);*/ + + if (!wait_finger_down) + fpc1020->capture.deferred_finger_up = false; + + if (wait_finger_down) { + error = fpc1020_capture_finger_detect_settings(fpc1020); + if (error < 0) + goto out_error; + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-11-05 Remove for don't wait finger up + if (wait_finger_down && fpc1020->capture.deferred_finger_up) { + fpc1020->capture.state = + FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP; + + dev_dbg(&fpc1020->spi->dev, "Waiting for (deferred) finger up\n"); + + error = fpc1020_capture_wait_finger_up(fpc1020); + + if (error < 0) + goto out_error; + + dev_dbg(&fpc1020->spi->dev, "Finger up\n"); + + fpc1020->capture.deferred_finger_up = false; + } +#endif /* VENDOR_EDIT */ + + if (wait_finger_down) { + fpc1020->capture.state = + FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN; + + error = fpc1020_capture_wait_finger_down(fpc1020); + + if (error < 0) + goto out_error; + + dev_dbg(&fpc1020->spi->dev, "Finger down\n"); + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for fingerprint animation + if (mode == FPC1020_MODE_WAIT_AND_CAPTURE) { + fpc1020_report_finger_down(fpc1020); + } + //Lycan.Wang@Prd.BasicDrv, 2014-11-05 Add for don't wait finger up + fpc1020->capture.deferred_finger_up = false; +#endif /* VENDOR_EDIT */ + + if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) { + + fpc1020->capture.available_bytes = 4; + fpc1020->huge_buffer[0] = 'F'; + fpc1020->huge_buffer[1] = ':'; + fpc1020->huge_buffer[2] = 'D'; + fpc1020->huge_buffer[3] = 'N'; + } + } + + current_capture = 0; + image_offset = 0; + + fpc1020->diag.last_capture_time = 0; + + if (mode == FPC1020_MODE_SINGLE_CAPTURE_CAL) { + error = fpc1020_capture_set_sample_mode(fpc1020, true); + if (error) + goto out_error; + } + + while (capture_count && (error >= 0)) + { + getnstimeofday(&ts_t1); + + fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE; + + /*dev_dbg(&fpc1020->spi->dev, + "Capture, frame #%d \n", + current_capture + 1);*/ + + error = (!adjust_settings) ? 0 : + fpc1020_capture_settings(fpc1020, current_capture); + + if (error < 0) + goto out_error; + + getnstimeofday(&ts_t2); + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_CAPTURE_IMAGE, + FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA); + + if (error < 0) + goto out_error; + + fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH; + + error = fpc1020_fetch_image(fpc1020, + fpc1020->huge_buffer, + image_offset, + image_byte_size, + (size_t)fpc1020->huge_buffer_size); + if (error < 0) + goto out_error; + + fpc1020->capture.available_bytes += (error >= 0) ? + (int)image_byte_size : 0; + fpc1020->capture.last_error = error; + + getnstimeofday(&ts_t3); + + ts_delta = timespec_sub(ts_t2, ts_t1); + time_settings_us[current_capture] = + ts_delta.tv_sec * USEC_PER_SEC + + (ts_delta.tv_nsec / NSEC_PER_USEC); + + ts_delta = timespec_sub(ts_t3, ts_t2); + time_capture_us[current_capture] = + ts_delta.tv_sec * USEC_PER_SEC + + (ts_delta.tv_nsec / NSEC_PER_USEC); + + capture_count--; + current_capture++; + image_offset += (int)image_byte_size; + } + + error = fpc1020_capture_set_sample_mode(fpc1020, false); + if (error) + goto out_error; + + /* Update finger_present_status after image capture */ + fpc1020_check_finger_present_raw(fpc1020); + + if (mode != FPC1020_MODE_WAIT_FINGER_UP) + wake_up_interruptible(&fpc1020->capture.wq_data_avail); + + if (wait_finger_up) { + fpc1020->capture.state = + FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP; + + error = fpc1020_capture_finger_detect_settings(fpc1020); + if (error < 0) + goto out_error; + + error = fpc1020_capture_wait_finger_up(fpc1020); + + if(error == -EINTR) { + dev_dbg(&fpc1020->spi->dev, "Finger up check interrupted\n"); + fpc1020->capture.deferred_finger_up = true; + goto out_interrupted; + + } else if (error < 0) + goto out_error; + + if (mode == FPC1020_MODE_WAIT_FINGER_UP) { + fpc1020->capture.available_bytes = 4; + fpc1020->huge_buffer[0] = 'F'; + fpc1020->huge_buffer[1] = ':'; + fpc1020->huge_buffer[2] = 'U'; + fpc1020->huge_buffer[3] = 'P'; + + wake_up_interruptible(&fpc1020->capture.wq_data_avail); + } + + dev_dbg(&fpc1020->spi->dev, "Finger up\n"); +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for fingerprint animation + if (mode == FPC1020_MODE_WAIT_AND_CAPTURE) { + fpc1020_report_finger_up(fpc1020); + } +#endif /* VENDOR_EDIT */ + } + +out_interrupted: + + capture_count = 0; + time_capture_sum_us = 0; + + while (current_capture){ + + current_capture--; + + dev_dbg(&fpc1020->spi->dev, + "Frame #%d acq. time %d+%d=%d (us)\n", + capture_count + 1, + time_settings_us[capture_count], + time_capture_us[capture_count], + time_settings_us[capture_count] + + time_capture_us[capture_count]); + + time_capture_sum_us += time_settings_us[capture_count]; + time_capture_sum_us += time_capture_us[capture_count]; + + capture_count++; + } + fpc1020->diag.last_capture_time = time_capture_sum_us / 1000; + + dev_dbg(&fpc1020->spi->dev, + "Total acq. time %d (us)\n", time_capture_sum_us); + +out_error: + fpc1020->capture.last_error = error; + + if (error) { + fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED; + dev_err(&fpc1020->spi->dev, "%s %s %d\n", __func__, + (error == -EINTR) ? "TERMINATED" : "FAILED", error); +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-16 Add for report up when capture terminated + if (mode == FPC1020_MODE_WAIT_AND_CAPTURE) { + fpc1020_report_finger_up(fpc1020); + } +#endif /* VENDOR_EDIT */ + } else { + fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED; + dev_err(&fpc1020->spi->dev, "%s OK\n", __func__); + } + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_wait_finger_down(fpc1020_data_t *fpc1020) +{ + int error; + bool finger_down = false; + + error = fpc1020_wait_finger_present(fpc1020); + + while (!finger_down && (error >= 0)) { + + if (fpc1020->worker.stop_request) + error = -EINTR; + else + error = fpc1020_check_finger_present_sum(fpc1020); + + if (error > fpc1020->setup.capture_finger_down_threshold) + finger_down = true; + else + msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS); + } + + fpc1020_read_irq(fpc1020, true); + + return (finger_down) ? 0 : error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_wait_finger_up(fpc1020_data_t *fpc1020) +{ + int error = 0; + bool finger_up = false; + + while (!finger_up && (error >= 0)) { + + if (fpc1020->worker.stop_request) + error = -EINTR; + else + error = fpc1020_check_finger_present_sum(fpc1020); + + if ((error >= 0) && (error < fpc1020->setup.capture_finger_up_threshold + 1)) + finger_up = true; + else + msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS); + } + + fpc1020_read_irq(fpc1020, true); + + return (finger_up) ? 0 : error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_settings(fpc1020_data_t *fpc1020, int select) +{ + int error = 0; + fpc1020_reg_access_t reg; + + u16 pxlCtrl; + u16 adc_shift_gain; + + //dev_dbg(&fpc1020->spi->dev, "%s #%d\n", __func__, select); + + if (select >= FPC1020_MAX_ADC_SETTINGS) { + error = -EINVAL; + goto out_err; + } + + pxlCtrl = fpc1020->setup.pxl_ctrl[select]; + pxlCtrl |= FPC1020_PXL_BIAS_CTRL; + + adc_shift_gain = fpc1020->setup.adc_shift[select]; + adc_shift_gain <<= 8; + adc_shift_gain |= fpc1020->setup.adc_gain[select]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &pxlCtrl); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out_err; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &adc_shift_gain); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out_err; + +out_err: + if (error) + dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error); + + return error; +} + +int fpc1020_capture_set_sample_mode(fpc1020_data_t* fpc1020, bool single) +{ + int error = 0; + fpc1020_reg_access_t reg; + + u8 image_setup; + u8 image_rd; + + dev_dbg(&fpc1020->spi->dev, "%s single %s\n", __func__, single ? + "true" : "false"); + + if (single) { + image_setup = 0x0A; + image_rd = 0x0C; + } else { + image_setup = 0x03 | 0x08; + image_rd = 0x0E; + } + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &image_setup); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out_err; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMG_RD, &image_rd); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out_err; + +out_err: + if (error) + dev_err(&fpc1020->spi->dev, "%s Error %d\n", __func__, error); + + return error; +} + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_finger_detect_settings(fpc1020_data_t *fpc1020) +{ + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + return fpc1020_capture_settings(fpc1020, FPC1020_MAX_ADC_SETTINGS - 1); +} + + +/* -------------------------------------------------------------------- */ +static size_t fpc1020_calc_image_size(fpc1020_data_t *fpc1020) +{ + int image_byte_size = fpc1020->setup.capture_row_count * + fpc1020->setup.capture_col_groups * + fpc1020->chip.adc_group_size; + + dev_dbg(&fpc1020->spi->dev, "%s Rows %d->%d,Cols %d->%d (%d bytes)\n", + __func__, + fpc1020->setup.capture_row_start, + fpc1020->setup.capture_row_start + + fpc1020->setup.capture_row_count - 1, + fpc1020->setup.capture_col_start + * fpc1020->chip.adc_group_size, + (fpc1020->setup.capture_col_start + * fpc1020->chip.adc_group_size) + + (fpc1020->setup.capture_col_groups * + fpc1020->chip.adc_group_size) - 1, + image_byte_size + ); + + return image_byte_size; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_set_crop(fpc1020_data_t *fpc1020, + int first_column, + int num_columns, + int first_row, + int num_rows) +{ + fpc1020_reg_access_t reg; + u32 temp_u32; + + temp_u32 = first_row; + temp_u32 <<= 8; + temp_u32 |= num_rows; + temp_u32 <<= 8; + temp_u32 |= (first_column * fpc1020->chip.adc_group_size); + temp_u32 <<= 8; + temp_u32 |= (num_columns * fpc1020->chip.adc_group_size); + + FPC1020_MK_REG_WRITE(reg,FPC102X_REG_IMG_CAPT_SIZE, &temp_u32); + return fpc1020_reg_access(fpc1020, ®); +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_capture_buffer(fpc1020_data_t *fpc1020, + u8 *data, + size_t offset, + size_t image_size_bytes) +{ + int error = 0; + + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_CAPTURE_IMAGE, + FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA); + + if (error < 0) + goto out_error; + + error = fpc1020_fetch_image(fpc1020, + data, + offset, + image_size_bytes, + (size_t)fpc1020->huge_buffer_size); + if (error < 0) + goto out_error; + + return 0; + +out_error: + dev_dbg(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error); + + return error; +} + + +/* -------------------------------------------------------------------- */ +extern int fpc1020_capture_deferred_task(fpc1020_data_t *fpc1020) +{ + int error = 0; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = (fpc1020->capture.deferred_finger_up) ? + fpc1020_capture_wait_finger_up(fpc1020) : 0; + + if (error >= 0) + fpc1020->capture.deferred_finger_up = false; + + return error; +} + + +/* -------------------------------------------------------------------- */ + diff --git a/drivers/input/misc/fpc1020_capture.h b/drivers/input/misc/fpc1020_capture.h new file mode 100755 index 0000000000000..824c142bfea6c --- /dev/null +++ b/drivers/input/misc/fpc1020_capture.h @@ -0,0 +1,47 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef LINUX_SPI_FPC1020_CAPTURE_H +#define LINUX_SPI_FPC1020_CAPTURE_H + +extern int fpc1020_init_capture(fpc1020_data_t *fpc1020); + +extern int fpc1020_write_capture_setup(fpc1020_data_t *fpc1020); + +extern int fpc1020_write_test_setup(fpc1020_data_t *fpc1020, u16 pattern); + +extern bool fpc1020_capture_check_ready(fpc1020_data_t *fpc1020); + +extern int fpc1020_capture_task(fpc1020_data_t *fpc1020); + +extern int fpc1020_capture_wait_finger_down(fpc1020_data_t *fpc1020); + +extern int fpc1020_capture_wait_finger_up(fpc1020_data_t *fpc1020); + +extern int fpc1020_capture_settings(fpc1020_data_t *fpc1020, int select); + +extern int fpc1020_capture_set_sample_mode(fpc1020_data_t* fpc1020, + bool single); +extern int fpc1020_capture_set_crop(fpc1020_data_t *fpc1020, + int first_column, + int num_columns, + int first_row, + int num_rows); + +extern int fpc1020_capture_buffer(fpc1020_data_t *fpc1020, + u8 *data, + size_t offset, + size_t image_size_bytes); + +extern int fpc1020_capture_deferred_task(fpc1020_data_t *fpc1020); + +extern int fpc1020_capture_finger_detect_settings(fpc1020_data_t *fpc1020); + +#endif /* LINUX_SPI_FPC1020_CAPTURE_H */ + diff --git a/drivers/input/misc/fpc1020_common.c b/drivers/input/misc/fpc1020_common.c new file mode 100755 index 0000000000000..871f34b1b0266 --- /dev/null +++ b/drivers/input/misc/fpc1020_common.c @@ -0,0 +1,2062 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#define DEBUG + +#include +#include + +#if 0 //#ifndef CONFIG_USE_OF /*VENDOR_EDIT*/ //oneplus changhua modify for MSM8994 +#include +#include +#include +#include +#else +#include "fpc1020_common.h" +#include "fpc1020_regs.h" +#include "fpc1020_capture.h" +#include "fpc1020_regulator.h" +#endif + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + const bool target_little_endian = true; +#else + #warning BE target not tested! + const bool target_little_endian = false; +#endif + + +/* -------------------------------------------------------------------- */ +/* fpc1020 data types */ +/* -------------------------------------------------------------------- */ +struct chip_struct { + fpc1020_chip_t type; + u16 hwid; + u8 revision; + u8 pixel_rows; + u8 pixel_columns; + u8 adc_group_size; +}; + + +/* -------------------------------------------------------------------- */ +/* fpc1020 driver constants */ +/* -------------------------------------------------------------------- */ +#define FPC1150_ROWS 208u +#define FPC1150_COLUMNS 80u + +#define FPC1021_ROWS 160u +#define FPC1021_COLUMNS 160u + +#define FPC1020_ROWS 192u +#define FPC1020_COLUMNS 192u +#define FPC102X_ADC_GROUP_SIZE 8u + +#define FPC1020_EXT_HWID_CHECK_ID1020A_ROWS 5u + + +static const char *chip_text[] = { + "N/A", /* FPC1020_CHIP_NONE */ + "fpc1020a", /* FPC1020_CHIP_1020A */ + "fpc1021a", /* FPC1020_CHIP_1021A */ + "fpc1021b", /* FPC1020_CHIP_1021B */ + "fpc1150a", /* FPC1020_CHIP_1150A */ + "fpc1150b", /* FPC1020_CHIP_1150B */ + "fpc1150f", /* FPC1020_CHIP_1150F */ + "fpc1155x" /* FPC1020_CHIP_1155X */ +}; + +static const struct chip_struct chip_data[] = { + {FPC1020_CHIP_1020A, 0x020a, 0, FPC1020_ROWS, FPC1020_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1021A, 0x021a, 2, FPC1021_ROWS, FPC1021_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1021B, 0x021b, 1, FPC1021_ROWS, FPC1021_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1150A, 0x150a, 1, FPC1150_ROWS, FPC1150_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1150B, 0x150b, 1, FPC1150_ROWS, FPC1150_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1150F, 0x150f, 1, FPC1150_ROWS, FPC1150_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_1155X, 0x9500, 1, FPC1150_ROWS, FPC1150_COLUMNS, FPC102X_ADC_GROUP_SIZE}, + {FPC1020_CHIP_NONE, 0,0,0,0,0} +}; + +const fpc1020_setup_t fpc1020_setup_default_1020_a1a2 = { + .adc_gain = {0, 0, 1, 1}, + .adc_shift = {1, 2, 1, 1}, + .pxl_ctrl = {0x1b, 0x1f, 0x0b, 0x0b}, + .capture_settings_mux = 0, + .capture_count = 1, + .capture_mode = FPC1020_MODE_WAIT_AND_CAPTURE, + .capture_row_start = 0, + .capture_row_count = FPC1020_ROWS, + .capture_col_start = 0, + .capture_col_groups = FPC1020_COLUMNS / FPC102X_ADC_GROUP_SIZE, + .capture_finger_up_threshold = 0, + .capture_finger_down_threshold = 6, + .finger_detect_threshold = 0x50, + .wakeup_detect_rows = {92, 92}, + .wakeup_detect_cols = {64, 120}, +}; + +const fpc1020_setup_t fpc1020_setup_default_1020_a3a4 = { + .adc_gain = {2, 2, 2, 2}, + .adc_shift = {10, 10, 10, 10}, + .pxl_ctrl = {0x1e, 0x0e, 0x0a, 0x0a}, + .capture_settings_mux = 0, + .capture_count = 1, + .capture_mode = FPC1020_MODE_WAIT_AND_CAPTURE, + .capture_row_start = 0, + .capture_row_count = FPC1020_ROWS, + .capture_col_start = 0, + .capture_col_groups = FPC1020_COLUMNS / FPC102X_ADC_GROUP_SIZE, + .capture_finger_up_threshold = 0, + .capture_finger_down_threshold = 6, + .finger_detect_threshold = 0x50, + .wakeup_detect_rows = {92, 92}, + .wakeup_detect_cols = {64, 120}, +}; + +const fpc1020_setup_t fpc1020_setup_default_1021_a2b1 = { + .adc_gain = {2, 2, 3, 3}, + .adc_shift = {10, 10, 7, 7}, + .pxl_ctrl = {0x1e, 0x0e, 0x0e, 0x0e}, + .capture_settings_mux = 0, + .capture_count = 1, + .capture_mode = FPC1020_MODE_WAIT_AND_CAPTURE, + .capture_row_start = 0, + .capture_row_count = FPC1021_ROWS, + .capture_col_start = 0, + .capture_col_groups = FPC1021_COLUMNS / FPC102X_ADC_GROUP_SIZE, + .capture_finger_up_threshold = 0, + .capture_finger_down_threshold = 6, + .finger_detect_threshold = 0x50, + .wakeup_detect_rows = {76, 76}, + .wakeup_detect_cols = {56, 88}, +}; + +const fpc1020_setup_t fpc1020_setup_default_1150_a1b1f1 = { + .adc_gain = {2, 2, 2, 5}, + .adc_shift = {10, 10, 10, 5}, + .pxl_ctrl = {0x1e, 0x0e, 0x0a, 0x0a}, + .capture_settings_mux = 0, + .capture_count = 1, + .capture_mode = FPC1020_MODE_WAIT_AND_CAPTURE, + .capture_row_start = 0, + .capture_row_count = FPC1150_ROWS, + .capture_col_start = 0, + .capture_col_groups = FPC1150_COLUMNS / FPC102X_ADC_GROUP_SIZE, + .capture_finger_up_threshold = 0, + .capture_finger_down_threshold = 1, + .finger_detect_threshold = 0x20, + .wakeup_detect_rows = {72, 128}, + .wakeup_detect_cols = {32, 32}, +}; + +const fpc1020_setup_t fpc1020_setup_default_1155 = { + .adc_gain = {2, 2, 2, 2}, + .adc_shift = {10, 10, 10, 10}, + .pxl_ctrl = {0x1e, 0x0e, 0x0a, 0x0a}, + .capture_settings_mux = 0, + .capture_count = 1, + .capture_mode = FPC1020_MODE_WAIT_AND_CAPTURE, + .capture_row_start = 0, + .capture_row_count = FPC1150_ROWS, + .capture_col_start = 0, + .capture_col_groups = FPC1150_COLUMNS / FPC102X_ADC_GROUP_SIZE, + .capture_finger_up_threshold = 0, + .capture_finger_down_threshold = 7, + .finger_detect_threshold = 0x50, + .wakeup_detect_rows = {72, 128}, + .wakeup_detect_cols = {32, 32}, +}; + + +const fpc1020_diag_t fpc1020_diag_default = { + .selftest = 0, + .spi_register = 0, + .spi_regsize = 0, + .spi_data = 0, +}; + + +/* -------------------------------------------------------------------- */ +/* function prototypes */ +/* -------------------------------------------------------------------- */ +static int fpc1020_check_hw_id_extended(fpc1020_data_t *fpc1020); + +static int fpc1020_hwid_1020a(fpc1020_data_t *fpc1020); + +static int fpc1020_write_id_1020a_setup(fpc1020_data_t *fpc1020); + +static int fpc1020_write_sensor_1020a_setup(fpc1020_data_t *fpc1020); +static int fpc1020_write_sensor_1020a_a1a2_setup(fpc1020_data_t *fpc1020); +static int fpc1020_write_sensor_1020a_a3a4_setup(fpc1020_data_t *fpc1020); + +static int fpc1020_write_sensor_1021_setup(fpc1020_data_t *fpc1020); + +static int fpc1020_write_sensor_1150_setup(fpc1020_data_t *fpc1020); + +static int fpc1020_write_sensor_1155_setup(fpc1020_data_t *fpc1020); +#ifdef VENDOR_EDIT +static int fpc1020_check_irq_after_reset(fpc1020_data_t *fpc1020); +#endif +static int fpc1020_flush_adc(fpc1020_data_t *fpc1020); + +/* -------------------------------------------------------------------- */ +/* function definitions */ +/* -------------------------------------------------------------------- */ +size_t fpc1020_calc_huge_buffer_minsize(fpc1020_data_t *fpc1020) +{ + const size_t buff_min = FPC1020_EXT_HWID_CHECK_ID1020A_ROWS * + FPC1020_COLUMNS; + size_t buff_req; + + buff_req = (fpc1020->chip.type == FPC1020_CHIP_NONE) ? buff_min : + (fpc1020->chip.pixel_columns * + fpc1020->chip.pixel_rows * + FPC1020_BUFFER_MAX_IMAGES); + + return (buff_req > buff_min) ? buff_req : buff_min; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_manage_huge_buffer(fpc1020_data_t *fpc1020, size_t new_size) +{ + int error = 0; + int buffer_order_new, buffer_order_curr; + + buffer_order_curr = get_order(fpc1020->huge_buffer_size); + buffer_order_new = get_order(new_size); + + if (new_size == 0) { + if (fpc1020->huge_buffer) { + free_pages((unsigned long)fpc1020->huge_buffer, + buffer_order_curr); + + fpc1020->huge_buffer = NULL; + } + fpc1020->huge_buffer_size = 0; + error = 0; + + } else { + if (fpc1020->huge_buffer && + (buffer_order_curr != buffer_order_new)) { + + free_pages((unsigned long)fpc1020->huge_buffer, + buffer_order_curr); + + fpc1020->huge_buffer = NULL; + } + + if (fpc1020->huge_buffer == NULL) + { + fpc1020->huge_buffer = + (u8 *)__get_free_pages(GFP_KERNEL, + buffer_order_new); + + fpc1020->huge_buffer_size = (fpc1020->huge_buffer) ? + (size_t)PAGE_SIZE << buffer_order_new : 0; + + error = (fpc1020->huge_buffer_size == 0) ? -ENOMEM : 0; + } + } + + + if (error) { + dev_err(&fpc1020->spi->dev, "%s, failed %d\n", + __func__, error); + } else { + dev_info(&fpc1020->spi->dev, "%s, size=%d bytes\n", + __func__, (int)fpc1020->huge_buffer_size); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_setup_defaults(fpc1020_data_t *fpc1020) +{ + int error = 0; + const fpc1020_setup_t *ptr; + + memcpy((void *)&fpc1020->diag, + (void *)&fpc1020_diag_default, + sizeof(fpc1020_diag_t)); + + switch (fpc1020->chip.type) { + + case FPC1020_CHIP_1020A: + + ptr = (fpc1020->chip.revision == 1) ? &fpc1020_setup_default_1020_a1a2 : + (fpc1020->chip.revision == 2) ? &fpc1020_setup_default_1020_a1a2 : + (fpc1020->chip.revision == 3) ? &fpc1020_setup_default_1020_a3a4 : + (fpc1020->chip.revision == 4) ? &fpc1020_setup_default_1020_a3a4 : + NULL; + break; + + case FPC1020_CHIP_1021A: + ptr = (fpc1020->chip.revision == 2) ? &fpc1020_setup_default_1021_a2b1 : + NULL; + break; + + case FPC1020_CHIP_1021B: + ptr = (fpc1020->chip.revision == 1) ? &fpc1020_setup_default_1021_a2b1 : + NULL; + break; + + case FPC1020_CHIP_1150A: + case FPC1020_CHIP_1150B: + case FPC1020_CHIP_1150F: + ptr = (fpc1020->chip.revision == 1) ? &fpc1020_setup_default_1150_a1b1f1 : + NULL; + break; + + case FPC1020_CHIP_1155X: + ptr = (fpc1020->chip.revision == 1) ? &fpc1020_setup_default_1155 : NULL; + break; + + default: + ptr = NULL; + break; + } + + error = (ptr == NULL) ? -EINVAL : 0; + if (error) + goto out_err; + + memcpy((void *)&fpc1020->setup, ptr, sizeof(fpc1020_setup_t)); + + dev_dbg(&fpc1020->spi->dev, "%s OK\n", __func__); + + return 0; + +out_err: + memset((void *)&fpc1020->setup, 0, sizeof(fpc1020_setup_t)); + dev_err(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error); + + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_gpio_reset(fpc1020_data_t *fpc1020) +{ + int error = 0; + int counter = FPC1020_RESET_RETRIES; + + while (counter) { + counter--; + + gpio_set_value(fpc1020->reset_gpio, 1); + udelay(FPC1020_RESET_HIGH1_US); + + gpio_set_value(fpc1020->reset_gpio, 0); + udelay(FPC1020_RESET_LOW_US); + + gpio_set_value(fpc1020->reset_gpio, 1); + udelay(FPC1020_RESET_HIGH2_US); + + error = gpio_get_value(fpc1020->irq_gpio) ? 0 : -EIO; + + if (!error) { + //printk(KERN_INFO "%s OK !\n", __func__); + counter = 0; + } else { + printk(KERN_INFO "%s timed out,retrying ...\n", + __func__); + + udelay(1250); + } + } + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_spi_reset(fpc1020_data_t *fpc1020) +{ + int error = 0; + int counter = FPC1020_RESET_RETRIES; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + while (counter) { + counter--; + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_SOFT_RESET, + false); + + if (error >= 0) { + error = fpc1020_wait_for_irq(fpc1020, + FPC1020_DEFAULT_IRQ_TIMEOUT_MS); + } + + if (error >= 0) { + error = gpio_get_value(fpc1020->irq_gpio) ? 0 : -EIO; + + if (!error) { + dev_dbg(&fpc1020->spi->dev, + "%s OK !\n", __func__); + + counter = 0; + + } else { + dev_dbg(&fpc1020->spi->dev, + "%s timed out,retrying ...\n", + __func__); + } + } + } + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_reset(fpc1020_data_t *fpc1020) +{ + int error = 0; + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + error = (fpc1020->soft_reset_enabled) ? + fpc1020_spi_reset(fpc1020) : +#endif /* VENDOR_EDIT */ + + fpc1020_gpio_reset(fpc1020); + + disable_irq(fpc1020->irq); + fpc1020->interrupt_done = false; + enable_irq(fpc1020->irq); + +#ifdef VENDOR_EDIT +//Changhua.Li@Prd.BSP, 2015-02-4 Remove for not spi access in AP + error = fpc1020_check_irq_after_reset(fpc1020); +#endif /* VENDOR_EDIT */ + + if (error < 0){ + if(error == -EIO && (fpc1020->to_power == true)){//IC is out of state,just power reset(GPIO41) + dev_err(&fpc1020->spi->dev, "%s,fpc1150 IC is out of state,power off!!!\n", __func__); + gpio_set_value(fpc1020->vdden_gpio,0); + mdelay(3); + gpio_set_value(fpc1020->vdden_gpio,1); + mdelay(3); + dev_err(&fpc1020->spi->dev, "%s,fpc1150 IC is out of state,power on done!!!\n", __func__); + fpc1020_gpio_reset(fpc1020); + + disable_irq(fpc1020->irq); + fpc1020->interrupt_done = false; + enable_irq(fpc1020->irq); + error = fpc1020_check_irq_after_reset(fpc1020); + if (error < 0) + goto out; + } + else + goto out; + } + + error = (gpio_get_value(fpc1020->irq_gpio) != 0) ? -EIO : 0; + + if (error) + dev_err(&fpc1020->spi->dev, "IRQ pin, not low after clear.\n"); + +#ifndef VENDOR_EDIT +//Changhua.Li@Prd.BSP, 2015-02-4 Remove for not spi access in AP + error = fpc1020_read_irq(fpc1020, true); +#endif /* VENDOR_EDIT */ + + if (error != 0) { + dev_err(&fpc1020->spi->dev, + "IRQ register, expected 0x%x, got 0x%x.\n", + 0, + (u8)error); + + error = -EIO; + } + + if (!error && (fpc1020->chip.type == FPC1020_CHIP_1020A)) + error = fpc1020_flush_adc(fpc1020); + + fpc1020->capture.available_bytes = 0; + fpc1020->capture.read_offset = 0; + fpc1020->capture.read_pending_eof = false; +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_check_hw_id(fpc1020_data_t *fpc1020) +{ + int error = 0; + u16 hardware_id; + + fpc1020_reg_access_t reg; + int counter = 0; + bool match = false; + + FPC1020_MK_REG_READ(reg, FPC102X_REG_HWID, &hardware_id); + error = fpc1020_reg_access(fpc1020, ®); + + if (error) + return error; + + while (!match && chip_data[counter].type != FPC1020_CHIP_NONE) { + if (chip_data[counter].hwid == hardware_id) + match = true; + else + counter++; + } + + if (match) { + fpc1020->chip.type = chip_data[counter].type; + fpc1020->chip.revision = chip_data[counter].revision; + + fpc1020->chip.pixel_rows = chip_data[counter].pixel_rows; + fpc1020->chip.pixel_columns = chip_data[counter].pixel_columns; + fpc1020->chip.adc_group_size = chip_data[counter].adc_group_size; + + if (fpc1020->chip.revision == 0) { + error = fpc1020_check_hw_id_extended(fpc1020); + + if (error > 0) { + fpc1020->chip.revision = error; + error = 0; + } + } + + dev_info(&fpc1020->spi->dev, + "Hardware id: 0x%x (%s, rev.%d) \n", + hardware_id, + chip_text[fpc1020->chip.type], + fpc1020->chip.revision); + } else { + dev_err(&fpc1020->spi->dev, + "Hardware id mismatch: got 0x%x\n", hardware_id); + + fpc1020->chip.type = FPC1020_CHIP_NONE; + fpc1020->chip.revision = 0; + + return -EIO; + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +const char *fpc1020_hw_id_text(fpc1020_data_t *fpc1020) +{ + return chip_text[fpc1020->chip.type]; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_check_hw_id_extended(fpc1020_data_t *fpc1020) +{ + int error = 0; + + if (fpc1020->chip.revision != 0) { + return fpc1020->chip.revision; + } + + error = (fpc1020->chip.type == FPC1020_CHIP_1020A) ? + fpc1020_hwid_1020a(fpc1020) : -EINVAL; + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s, Unable to check chip revision %d\n", + __func__,error); + } + + return (error < 0) ? error : fpc1020->chip.revision; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_hwid_1020a(fpc1020_data_t *fpc1020) +{ + int error = 0; + int xpos, ypos, m1, m2, count; + + const int num_rows = FPC1020_EXT_HWID_CHECK_ID1020A_ROWS; + const int num_pixels = 32; + const size_t image_size = num_rows * fpc1020->chip.pixel_columns; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + if (fpc1020->chip.type != FPC1020_CHIP_1020A) + return -EINVAL; + + error = fpc1020_write_id_1020a_setup(fpc1020); + if (error) + goto out_err; + + error = fpc1020_capture_set_crop(fpc1020, + 0, + fpc1020->chip.pixel_columns / fpc1020->chip.adc_group_size, + 0, + num_rows); + if (error) + goto out_err; + + error = fpc1020_capture_buffer(fpc1020, + fpc1020->huge_buffer, + 0, + image_size); + if (error) + goto out_err; + + m1 = m2 = count = 0; + + for (ypos = 1; ypos < num_rows; ypos++) { + for (xpos = 0; xpos < num_pixels; xpos++) { + m1 += fpc1020->huge_buffer + [(ypos * fpc1020->chip.pixel_columns) + xpos]; + + m2 += fpc1020->huge_buffer + [(ypos * fpc1020->chip.pixel_columns) + + (fpc1020->chip.pixel_columns - 1 - xpos)]; + count++; + } + } + + m1 /= count; + m2 /= count; + + if (fpc1020_check_in_range_u64(m1, 181, 219) && + fpc1020_check_in_range_u64(m2, 101, 179)) + { + fpc1020->chip.revision = 1; + } + else if (fpc1020_check_in_range_u64(m1, 181, 219) && + fpc1020_check_in_range_u64(m2, 181, 219)) + { + fpc1020->chip.revision = 2; + } + else if (fpc1020_check_in_range_u64(m1, 101, 179) && + fpc1020_check_in_range_u64(m2, 151, 179)) + { + fpc1020->chip.revision = 3; + } + else if (fpc1020_check_in_range_u64(m1, 0, 99) && + fpc1020_check_in_range_u64(m2, 0, 99)) + { + fpc1020->chip.revision = 4; + } + else + { + fpc1020->chip.revision = 0; + } + + dev_dbg(&fpc1020->spi->dev, "%s m1,m2 = %d,%d %s rev=%d \n", __func__, + m1, m2, + (fpc1020->chip.revision == 0) ? "UNKNOWN!" : "detected", + fpc1020->chip.revision); + +out_err: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_id_1020a_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + fpc1020_reg_access_t reg; + + temp_u16 = 15 << 8; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = 0xffff; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_TST_COL_PATTERN_EN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x04; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_write_sensor_setup(fpc1020_data_t *fpc1020) +{ + switch (fpc1020->chip.type) + { + case FPC1020_CHIP_1020A: + return fpc1020_write_sensor_1020a_setup(fpc1020); + + case FPC1020_CHIP_1021A: + case FPC1020_CHIP_1021B: + return fpc1020_write_sensor_1021_setup(fpc1020); + + case FPC1020_CHIP_1150A: + case FPC1020_CHIP_1150B: + case FPC1020_CHIP_1150F: + return fpc1020_write_sensor_1150_setup(fpc1020); + + case FPC1020_CHIP_1155X: + return fpc1020_write_sensor_1155_setup(fpc1020); + + default: + break; + } + + return -EINVAL; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1020a_setup(fpc1020_data_t *fpc1020) +{ + switch (fpc1020->chip.revision) + { + case 1: + case 2: + return fpc1020_write_sensor_1020a_a1a2_setup(fpc1020); + + case 3: + case 4: + return fpc1020_write_sensor_1020a_a3a4_setup(fpc1020); + + default: + break; + } + + return -EINVAL; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1020a_a1a2_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u32 temp_u32; + u64 temp_u64; + fpc1020_reg_access_t reg; + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + const int rev = fpc1020->chip.revision; + + dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + if ((rev != 1) && (rev != 2)) + return -EINVAL; + + temp_u64 = (rev == 1) ? 0x363636363f3f3f3f : 0x141414141e1e1e1e; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = (rev == 1) ? 0x33 : 0x0f; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = (rev == 1) ? 0x37 : 0x15; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x5540003f24; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u32 = 0x00080000; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ANA_TEST_MUX, &temp_u32); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x5540003f34; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = (fpc1020->vddtx_mv > 0) ? 0x02 : /* external supply */ + (fpc1020->txout_boost) ? 0x22 : 0x12; /* internal supply */ + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + temp_u16 |= FPC1020_PXL_BIAS_CTRL; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x03 | 0x08; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = fpc1020->setup.finger_detect_threshold; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_THRES, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = 0x00ff; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_CNTR, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1020a_a3a4_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u64 temp_u64; + fpc1020_reg_access_t reg; + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + const int rev = fpc1020->chip.revision; + + dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + if (rev == 4) + { + temp_u8 = 0x09; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x0808080814141414; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + } + else if (rev == 3) + { + temp_u64 = 0x1717171723232323; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x0f; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x18; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + } + else + { + error = -EINVAL; + goto out; + } + + temp_u8 = (fpc1020->vddtx_mv > 0) ? 0x02 : /* external supply */ + (fpc1020->txout_boost) ? 0x22 : 0x12; /* internal supply */ + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + temp_u16 |= FPC1020_PXL_BIAS_CTRL; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x03 | 0x08; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = fpc1020->setup.finger_detect_threshold; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_THRES, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = 0x00ff; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_CNTR, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1021_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u64 temp_u64; + fpc1020_reg_access_t reg; + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + const int rev = fpc1020->chip.revision; + + dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + if (rev == 0) + return -EINVAL; + + temp_u8 = 0x09; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x0808080814141414; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = (fpc1020->vddtx_mv > 0) ? 0x02 : /* external supply */ + (fpc1020->txout_boost) ? 0x22 : 0x12; /* internal supply */ + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + temp_u16 |= FPC1020_PXL_BIAS_CTRL; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x03 | 0x08; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = fpc1020->setup.finger_detect_threshold; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_THRES, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = 0x00ff; + FPC1020_MK_REG_WRITE(reg, FPC1020_REG_FNGR_DET_CNTR, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1150_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u32 temp_u32; + u64 temp_u64; + fpc1020_reg_access_t reg; + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + const int rev = fpc1020->chip.revision; + + //dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + if (rev == 0) + return -EINVAL; + + temp_u8 = 0x09; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x0808080814141414; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + #ifndef AS_HOME_KEY + temp_u8 = (fpc1020->vddtx_mv > 0) ? 0x02 : /* external supply */ + (fpc1020->txout_boost) ? 0x22 : 0x12; /* internal supply */ + #else + temp_u8 = 0x02; + #endif + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + temp_u16 |= FPC1020_PXL_BIAS_CTRL; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x03 | 0x08; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u32 = 0x0001; /* fngrUpSteps */ + temp_u32 <<= 8; + fpc1020->setup.finger_detect_threshold = 0x20;//0xf;//0x20; + temp_u32 |= fpc1020->setup.finger_detect_threshold; /* fngrLstThr */ + temp_u32 <<= 8; + temp_u32 |= fpc1020->setup.finger_detect_threshold; /* fngrDetThr */ + + //dev_dbg(&fpc1020->spi->dev, "%s: finger_detect_threshold(%d)\n", __func__, temp_u32); + + FPC1020_MK_REG_WRITE(reg, FPC1150_REG_FNGR_DET_THRES, &temp_u32); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + #ifdef AS_HOME_KEY + temp_u32 = 0x19010001; + #else + temp_u32 = 0x190100ff; + #endif + FPC1020_MK_REG_WRITE(reg,FPC1150_REG_FNGR_DET_CNTR, &temp_u32); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_sensor_1155_setup(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 temp_u8; + u16 temp_u16; + u32 temp_u32; + u64 temp_u64; + fpc1020_reg_access_t reg; + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + const int rev = fpc1020->chip.revision; + + dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + if (rev == 0) + return -EINVAL; + + temp_u8 = 0x38; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x373737373F3F3F3F; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_SAMPLE_PX_DLY, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + if (fpc1020->vddtx_mv > 0) + dev_err(&fpc1020->spi->dev, "%s Ignoring external TxOut setting\n", __func__); + + if (fpc1020->txout_boost) + dev_err(&fpc1020->spi->dev, "%s Ignoring TxOut boost setting\n", __func__); + + temp_u8 = 0x12; /* internal supply, no boost */ + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + temp_u16 |= FPC1020_PXL_BIAS_CTRL; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x03 | 0x08; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_IMAGE_SETUP, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u32 = 0x0001; /* fngrUpSteps */ + temp_u32 <<= 8; + temp_u32 |= fpc1020->setup.finger_detect_threshold; /* fngrLstThr */ + temp_u32 <<= 8; + temp_u32 |= fpc1020->setup.finger_detect_threshold; /* fngrDetThr */ + FPC1020_MK_REG_WRITE(reg, FPC1150_REG_FNGR_DET_THRES, &temp_u32); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u32 = 0x1901ffff; + FPC1020_MK_REG_WRITE(reg, FPC1150_REG_FNGR_DET_CNTR, &temp_u32); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u64 = 0x5540002D24; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SETUP, &temp_u64); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u8 = 0x2F; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_RST_DLY, &temp_u8); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ + +#ifdef VENDOR_EDIT +static int fpc1020_check_irq_after_reset(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 irq_status; + + fpc1020_reg_access_t reg_clear = { + .reg = FPC102X_REG_READ_INTERRUPT_WITH_CLEAR, + .write = false, + .reg_size = FPC1020_REG_SIZE( + FPC102X_REG_READ_INTERRUPT_WITH_CLEAR), + .dataptr = &irq_status + }; + + error = fpc1020_reg_access(fpc1020, ®_clear); + + if(error < 0) + return error; + + if (irq_status != FPC_1020_IRQ_REG_BITS_REBOOT) { + dev_err(&fpc1020->spi->dev, + "IRQ register, expected 0x%x, got 0x%x.\n", + FPC_1020_IRQ_REG_BITS_REBOOT, + irq_status); + + error = -EIO; + } + + return (error < 0) ? error : irq_status; +} +#endif + +/* -------------------------------------------------------------------- */ +int fpc1020_wait_for_irq(fpc1020_data_t *fpc1020, int timeout) +{ + int result = 0; + + if (!timeout) { + result = wait_event_interruptible( + fpc1020->wq_irq_return, + fpc1020->interrupt_done); + } else { + result = wait_event_interruptible_timeout( + fpc1020->wq_irq_return, + fpc1020->interrupt_done, timeout); + } + + if (result < 0) { + dev_err(&fpc1020->spi->dev, + "wait_event_interruptible interrupted by signal.\n"); + + return result; + } + + if (result || !timeout) { + fpc1020->interrupt_done = false; + return 0; + } + + return -ETIMEDOUT; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_read_irq(fpc1020_data_t *fpc1020, bool clear_irq) +{ + int error = 0; + u8 irq_status; + fpc1020_reg_access_t reg_read = { + .reg = FPC102X_REG_READ_INTERRUPT, + .write = false, + .reg_size = FPC1020_REG_SIZE(FPC102X_REG_READ_INTERRUPT), + .dataptr = &irq_status + }; + + fpc1020_reg_access_t reg_clear = { + .reg = FPC102X_REG_READ_INTERRUPT_WITH_CLEAR, + .write = false, + .reg_size = FPC1020_REG_SIZE( + FPC102X_REG_READ_INTERRUPT_WITH_CLEAR), + .dataptr = &irq_status + }; + + error = fpc1020_reg_access(fpc1020, + (clear_irq) ? ®_clear : ®_read); + + if(error < 0) + return error; + + if (irq_status == FPC_1020_IRQ_REG_BITS_REBOOT) { + + dev_err(&fpc1020->spi->dev, + "%s: unexpected irq_status = 0x%x\n" + , __func__, irq_status); + + error = -EIO; + } + + return (error < 0) ? error : irq_status; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_read_status_reg(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8 status; + /* const */ fpc1020_reg_access_t reg_read = { + .reg = FPC102X_REG_FPC_STATUS, + .write = false, + .reg_size = FPC1020_REG_SIZE(FPC102X_REG_FPC_STATUS), + .dataptr = &status + }; + + error = fpc1020_reg_access(fpc1020, ®_read); + + return (error < 0) ? error : status; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_reg_access(fpc1020_data_t *fpc1020, + fpc1020_reg_access_t *reg_data) +{ + int error = 0; + + u8 temp_buffer[FPC1020_REG_MAX_SIZE]; + + struct spi_message msg; + + struct spi_transfer cmd = { + .cs_change = 0, + .delay_usecs = 0, + .speed_hz = FPC1020_SPI_CLOCK_SPEED, + .tx_buf = &(reg_data->reg), + .rx_buf = NULL, + .len = 1 + FPC1020_REG_ACCESS_DUMMY_BYTES(reg_data->reg), + .tx_dma = 0, + .rx_dma = 0, + .bits_per_word = 0, + }; + + struct spi_transfer data = { +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for HW Config + .cs_change = 1, +#else /* VENDOR_EDIT */ + .cs_change = 0, //modified by oppo +#endif /* VENDOR_EDIT */ + .delay_usecs = 0, + .speed_hz = FPC1020_SPI_CLOCK_SPEED, + .tx_buf = (reg_data->write) ? temp_buffer : NULL, + .rx_buf = (!reg_data->write) ? temp_buffer : NULL, + .len = reg_data->reg_size, + .tx_dma = 0, + .rx_dma = 0, + .bits_per_word = 0, + }; + + if (reg_data->reg_size > sizeof(temp_buffer)) { + dev_err(&fpc1020->spi->dev, + "%s : illegal register size\n", + __func__); + + error = -ENOMEM; + goto out; + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 0); +#endif /* VENDOR_EDIT */ + + if (reg_data->write) { + if (target_little_endian) { + int src = 0; + int dst = reg_data->reg_size - 1; + + while (src < reg_data->reg_size) { + temp_buffer[dst] = reg_data->dataptr[src]; + src++; + dst--; + } + } else { + memcpy(temp_buffer, + reg_data->dataptr, + reg_data->reg_size); + } + } + + spi_message_init(&msg); + spi_message_add_tail(&cmd, &msg); + spi_message_add_tail(&data, &msg); + + error = spi_sync(fpc1020->spi, &msg); + + if (error) + dev_err(&fpc1020->spi->dev, "%s : spi_sync failed.\n", __func__); + + if (!reg_data->write) { + if (target_little_endian) { + int src = reg_data->reg_size - 1; + int dst = 0; + + while (dst < reg_data->reg_size) { + reg_data->dataptr[dst] = temp_buffer[src]; + src--; + dst++; + } + } else { + memcpy(reg_data->dataptr, + temp_buffer, + reg_data->reg_size); + } + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 1); +#endif /* VENDOR_EDIT */ + +/* + dev_dbg(&fpc1020->spi->dev, + "%s %s 0x%x/%dd (%d bytes) %x %x %x %x : %x %x %x %x\n", + __func__, + (reg_data->write) ? "WRITE" : "READ", + reg_data->reg, + reg_data->reg, + reg_data->reg_size, + (reg_data->reg_size > 0) ? temp_buffer[0] : 0, + (reg_data->reg_size > 1) ? temp_buffer[1] : 0, + (reg_data->reg_size > 2) ? temp_buffer[2] : 0, + (reg_data->reg_size > 3) ? temp_buffer[3] : 0, + (reg_data->reg_size > 4) ? temp_buffer[4] : 0, + (reg_data->reg_size > 5) ? temp_buffer[5] : 0, + (reg_data->reg_size > 6) ? temp_buffer[6] : 0, + (reg_data->reg_size > 7) ? temp_buffer[7] : 0); +*/ +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_cmd(fpc1020_data_t *fpc1020, + fpc1020_cmd_t cmd, + u8 wait_irq_mask) +{ + int error = 0; + struct spi_message msg; + + struct spi_transfer t = { +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for HW Config + .cs_change = 1, +#else /* VENDOR_EDIT */ + .cs_change = 0, //modified by oppo +#endif /* VENDOR_EDIT */ + .delay_usecs = 0, + .speed_hz = FPC1020_SPI_CLOCK_SPEED, + .tx_buf = &cmd, + .rx_buf = NULL, + .len = 1, + .tx_dma = 0, + .rx_dma = 0, + .bits_per_word = 0, + }; + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 0); +#endif /* VENDOR_EDIT */ + + spi_message_init(&msg); + spi_message_add_tail(&t, &msg); + + error = spi_sync(fpc1020->spi, &msg); + + if (error) + dev_err(&fpc1020->spi->dev, "spi_sync failed.\n"); + + if ((error >= 0) && wait_irq_mask) { + error = fpc1020_wait_for_irq(fpc1020, + FPC1020_DEFAULT_IRQ_TIMEOUT_MS); + + if (error >= 0) + error = fpc1020_read_irq(fpc1020, true); + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 1); +#endif /* VENDOR_EDIT */ + + // dev_dbg(&fpc1020->spi->dev, "%s 0x%x/%dd\n", __func__, cmd, cmd); + + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_wait_finger_present(fpc1020_data_t *fpc1020) +{ + int error = 0; + + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) + return error; + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_WAIT_FOR_FINGER_PRESENT, 0); + + if (error < 0) + return error; + + while (1) { + error = fpc1020_wait_for_irq(fpc1020, + FPC1020_DEFAULT_IRQ_TIMEOUT_MS); + + if (error >= 0) { + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) + return error; + + if (error & + (FPC_1020_IRQ_REG_BIT_FINGER_DOWN | + FPC_1020_IRQ_REG_BIT_COMMAND_DONE)) { + + dev_err(&fpc1020->spi->dev, "Finger down\n"); + + error = 0; + } else { + dev_err(&fpc1020->spi->dev, + "%s Unexpected IRQ = %d\n", __func__, + error); + + error = -EIO; + } + return error; + } + + if (error < 0) { + if (fpc1020->worker.stop_request) + return -EINTR; + if (error != -ETIMEDOUT) + return error; + } + } +} +#ifdef AS_HOME_KEY +int fpc1020_wait_finger_present_timeout(fpc1020_data_t *fpc1020) +{ + int error = 0; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) + return error; + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_WAIT_FOR_FINGER_PRESENT, 0); + + if (error < 0) + return error; + + //while (1) { + error = fpc1020_wait_for_irq(fpc1020, + 10);//wait only 100ms,to check double tab + + if (error >= 0) { + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) + return error; + + if (error & + (FPC_1020_IRQ_REG_BIT_FINGER_DOWN | + FPC_1020_IRQ_REG_BIT_COMMAND_DONE)) { + + dev_dbg(&fpc1020->spi->dev, "Finger down\n"); + + error = 0; + } else { + dev_dbg(&fpc1020->spi->dev, + "%s Unexpected IRQ = %d\n", __func__, + error); + + error = -EIO; + } + return error; + } + + if (error < 0) { + if (fpc1020->worker.stop_request) + return -EINTR; + //if (error != -ETIMEDOUT) + return error; + } + //} + + return error; +} +#endif +/* -------------------------------------------------------------------- */ +int fpc1020_get_finger_present_status(fpc1020_data_t *fpc1020) +{ + int status; + + if (!down_trylock(&fpc1020->mutex)) { + if (!down_trylock(&fpc1020->worker.sem_idle)) { + status = fpc1020_capture_finger_detect_settings(fpc1020); + status = fpc1020_check_finger_present_raw(fpc1020); + + up(&fpc1020->worker.sem_idle); + } else { + /* Return last recorded status */ + status = (int)fpc1020->diag.finger_present_status; + } + up(&fpc1020->mutex); + } else { + /* Return last recorded status */ + status = (int)fpc1020->diag.finger_present_status; + } + return status; +} + +/* -------------------------------------------------------------------- */ +int fpc1020_check_finger_present_raw(fpc1020_data_t *fpc1020) +{ + fpc1020_reg_access_t reg; + u16 temp_u16; + int error = 0; + + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) + return error; + + error = fpc1020_cmd(fpc1020, + FPC1020_CMD_FINGER_PRESENT_QUERY, + FPC_1020_IRQ_REG_BIT_COMMAND_DONE); + + if (error < 0) + return error; + + FPC1020_MK_REG_READ(reg, FPC102X_REG_FINGER_PRESENT_STATUS, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + return error; + + fpc1020->diag.finger_present_status = temp_u16; + + //dev_dbg(&fpc1020->spi->dev, "%s zonedata = 0x%x\n", __func__, temp_u16); + + return temp_u16; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_check_finger_present_sum(fpc1020_data_t *fpc1020) +{ + int zones = 0; + u16 mask = FPC1020_FINGER_DETECT_ZONE_MASK; + u8 count = 0; + + zones = fpc1020_check_finger_present_raw(fpc1020); + + if (zones < 0) + return zones; + else { + zones &= mask; + while (zones && mask) { + count += (zones & 1) ? 1 : 0; + zones >>= 1; + mask >>= 1; + } + // dev_dbg(&fpc1020->spi->dev, "%s %d zones\n", __func__, count); + return (int)count; + } +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_wake_up(fpc1020_data_t *fpc1020) +{ + const fpc1020_status_reg_t status_mask = FPC1020_STATUS_REG_MODE_MASK; + + int power = fpc1020_regulator_set(fpc1020, true); + int reset = fpc1020_reset(fpc1020); + int status = fpc1020_read_status_reg(fpc1020); + + if (power == 0 && reset == 0 && status >= 0 && + (fpc1020_status_reg_t)(status & status_mask) == + FPC1020_STATUS_REG_IN_IDLE_MODE) { + + //dev_dbg(&fpc1020->spi->dev, "%s OK\n", __func__); + + return 0; + } else { + + dev_err(&fpc1020->spi->dev, "%s FAILED\n", __func__); + + return -EIO; + } +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_sleep(fpc1020_data_t *fpc1020, bool deep_sleep) +{ + const char *str_deep = "deep"; + const char *str_regular = "regular"; + + const fpc1020_status_reg_t status_mask = FPC1020_STATUS_REG_MODE_MASK; + + int error = fpc1020_cmd(fpc1020, + (deep_sleep) ? FPC1020_CMD_ACTIVATE_DEEP_SLEEP_MODE : + FPC1020_CMD_ACTIVATE_SLEEP_MODE, + 0); + bool sleep_ok; + + int retries = FPC1020_SLEEP_RETRIES; + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s %s command failed %d\n", __func__, + (deep_sleep)? str_deep : str_regular, + error); + + return error; + } + + error = 0; + sleep_ok = false; + + while (!sleep_ok && retries && (error >= 0)) { + + error = fpc1020_read_status_reg(fpc1020); + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s %s read status failed %d\n", __func__, + (deep_sleep)? str_deep : str_regular, + error); + } else { + error &= status_mask; + sleep_ok = (deep_sleep) ? + error == FPC1020_STATUS_REG_IN_DEEP_SLEEP_MODE : + error == FPC1020_STATUS_REG_IN_SLEEP_MODE; + } + if (!sleep_ok) { + udelay(FPC1020_SLEEP_RETRY_TIME_US); + retries--; + } + } + + if (deep_sleep && sleep_ok && gpio_is_valid(fpc1020->reset_gpio)) + gpio_set_value(fpc1020->reset_gpio, 0); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (deep_sleep && sleep_ok && gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 0); +#endif /* VENDOR_EDIT */ + + /* Optional: Also disable power supplies in sleep */ +/* + if (deep_sleep && sleep_ok) + error = fpc1020_regulator_set(fpc1020, false); +*/ + + if (sleep_ok) { + /*dev_err(&fpc1020->spi->dev, + "%s %s OK\n", __func__, + (deep_sleep)? str_deep : str_regular);*/ + return 0; + } else { + dev_err(&fpc1020->spi->dev, + "%s %s FAILED\n", __func__, + (deep_sleep)? str_deep : str_regular); + + return (deep_sleep) ? -EIO : -EAGAIN; + } +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_fetch_image(fpc1020_data_t *fpc1020, + u8 *buffer, + int offset, + size_t image_size_bytes, + size_t buff_size) +{ + int error = 0; + struct spi_message msg; + const u8 tx_data[2] = {FPC1020_CMD_READ_IMAGE , 0}; + + //dev_dbg(&fpc1020->spi->dev, "%s (+%d)\n", __func__, offset); + + if ((offset + (int)image_size_bytes) > buff_size) { + dev_err(&fpc1020->spi->dev, + "Image buffer too small for offset +%d (max %d bytes)", + offset, + (int)buff_size); + + error = -ENOBUFS; + } + + if (!error) { + struct spi_transfer cmd = { + .cs_change = 0, + .delay_usecs = 0, + .speed_hz = FPC1020_SPI_CLOCK_SPEED, + .tx_buf = tx_data, + .rx_buf = NULL, + .len = 2, + .tx_dma = 0, + .rx_dma = 0, + .bits_per_word = 0, + }; + + struct spi_transfer data = { +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for HW Config + .cs_change = 1, +#else /* VENDOR_EDIT */ + .cs_change = 0, //modified by oppo +#endif /* VENDOR_EDIT */ + .delay_usecs = 0, + .speed_hz = FPC1020_SPI_CLOCK_SPEED, + .tx_buf = NULL, + .rx_buf = buffer + offset, + .len = (int)image_size_bytes, + .tx_dma = 0, + .rx_dma = 0, + .bits_per_word = 0, + }; + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 0); +#endif /* VENDOR_EDIT */ + + spi_message_init(&msg); + spi_message_add_tail(&cmd, &msg); + spi_message_add_tail(&data, &msg); + + error = spi_sync(fpc1020->spi, &msg); + + if (error) + dev_err(&fpc1020->spi->dev, "spi_sync failed.\n"); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for HW Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_set_value(fpc1020->cs_gpio, 1); +#endif /* VENDOR_EDIT */ + } + + error = fpc1020_read_irq(fpc1020, true); + + if (error > 0) + error = (error & FPC_1020_IRQ_REG_BIT_ERROR) ? -EIO : 0; + + return error; +} + + +/* -------------------------------------------------------------------- */ +bool fpc1020_check_in_range_u64(u64 val, u64 min, u64 max) +{ + return (val >= min) && (val <= max); +} + + +/* -------------------------------------------------------------------- */ +u32 fpc1020_calc_pixel_sum(u8 *buffer, size_t count) +{ + size_t index = count; + u32 sum = 0; + + while(index) + { + index--; + sum += ((0xff - buffer[index]) / 8); + } + return sum; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_set_finger_drive(fpc1020_data_t *fpc1020, bool enable) +{ + + int error = 0; + u8 config; + fpc1020_reg_access_t reg; + + //dev_dbg(&fpc1020->spi->dev, "%s %s\n", __func__, (enable)? "ON":"OFF"); + + FPC1020_MK_REG_READ(reg, FPC102X_REG_FINGER_DRIVE_CONF, &config); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + if (enable) + config |= 0x02; + else + config &= ~0x02; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_FINGER_DRIVE_CONF, &config); + error = fpc1020_reg_access(fpc1020, ®); + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_calc_finger_detect_threshold_min(fpc1020_data_t *fpc1020) +{ + int error = 0; + int index; + int first_col, first_row, adc_groups, row_count; + u32 pixelsum[FPC1020_WAKEUP_DETECT_ZONE_COUNT] = {0, 0}; + u32 temp_u32; + + size_t image_size; + + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_write_sensor_setup(fpc1020); + + if (!error) + error = fpc1020_capture_finger_detect_settings(fpc1020); + + if (!error) + error = fpc1020_set_finger_drive(fpc1020, false); + + adc_groups = FPC1020_WAKEUP_DETECT_COLS / fpc1020->chip.adc_group_size; + image_size = (FPC1020_WAKEUP_DETECT_ROWS + 1) * adc_groups * fpc1020->chip.adc_group_size; + row_count = FPC1020_WAKEUP_DETECT_ROWS + 1; + + index = FPC1020_WAKEUP_DETECT_ZONE_COUNT; + while (index && !error) { + + index--; + + first_col = fpc1020->setup.wakeup_detect_cols[index] / fpc1020->chip.adc_group_size; + first_row = fpc1020->setup.wakeup_detect_rows[index] - 1; + + error = fpc1020_capture_set_crop(fpc1020, + first_col, + adc_groups, + first_row, + row_count); + if (!error) { + error = fpc1020_capture_buffer(fpc1020, + fpc1020->huge_buffer, + 0, + image_size); + } + + if (!error) { + pixelsum[index] = fpc1020_calc_pixel_sum( + fpc1020->huge_buffer + fpc1020->chip.adc_group_size, + image_size - fpc1020->chip.adc_group_size); + } + } + + if (!error) { + temp_u32 = 0; + + index = FPC1020_WAKEUP_DETECT_ZONE_COUNT; + while (index) { + index--; + if (pixelsum[index] > temp_u32) + temp_u32 = pixelsum[index]; + } + error = (int)(temp_u32 / 2); + + if (error >= 0xff) + error = -EINVAL; + } + + dev_dbg(&fpc1020->spi->dev, "%s : %s %d\n", + __func__, + (error < 0) ? "Error" : "measured min =", + error); + + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_set_finger_detect_threshold(fpc1020_data_t *fpc1020, + int measured_val) +{ + int error = 0; + int new_val; + //u8 old_val = fpc1020->setup.finger_detect_threshold; + + #ifndef AS_HOME_KEY + new_val = measured_val + 40; // Todo: awaiting calculated values + #else + new_val = measured_val + 15;//1;//16; //450 480 raw pixelsum Todo: awaiting calculated values + #endif + if ((measured_val < 0) || (new_val >= 0xff)) + error = -EINVAL; + + if (!error) { + fpc1020->setup.finger_detect_threshold = (u8)new_val; + + //dev_dbg(&fpc1020->spi->dev, "%s %d -> %d\n",__func__,old_val,fpc1020->setup.finger_detect_threshold); + } else { + dev_err(&fpc1020->spi->dev, + "%s unable to set finger detect threshold %d\n", + __func__, + error); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_flush_adc(fpc1020_data_t *fpc1020) +{ + int error = 0; + const int adc_groups = 9; + const int row_count = 1; + const int image_size = adc_groups * fpc1020->chip.adc_group_size * row_count; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_capture_set_crop(fpc1020, 0, adc_groups, 0, row_count); + + if (!error) { + error = fpc1020_capture_buffer(fpc1020, + fpc1020->huge_buffer, + 0, + image_size); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ + diff --git a/drivers/input/misc/fpc1020_common.h b/drivers/input/misc/fpc1020_common.h new file mode 100755 index 0000000000000..1b365f0a10a0e --- /dev/null +++ b/drivers/input/misc/fpc1020_common.h @@ -0,0 +1,414 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef LINUX_SPI_FPC1020_COMMON_H +#define LINUX_SPI_FPC1020_COMMON_H + +#define DEBUG +#define CONFIG_INPUT_FPC1020_NAV + +#define AS_HOME_KEY + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if 0 //#ifndef CONFIG_USE_OF //oneplus changhua.li modify for MSM8994 +#include +#include +#else +#include "fpc1020.h" +#include "fpc1020_regs.h" +#endif + +/* -------------------------------------------------------------------- */ +/* fpc1020 driver constants */ +/* -------------------------------------------------------------------- */ +extern const bool target_little_endian; + +extern unsigned int nav_switch; +extern unsigned int enable_keys; + +#define FPC1020_DEV_NAME "fpc1020" +#define FPC1020_TOUCH_PAD_DEV_NAME "fpc1020tp" + +//#define FPC1020_MAJOR 230 +#define FPC1020_MAJOR -1 + +#define FPC1020_SPI_CLOCK_SPEED (8 * 1000000U) + +#define FPC1020_BUFFER_MAX_IMAGES 3 + + +#define FPC_TEE_INTERRUPT_ONLY + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config +#define FPC1020_PIXEL_ROWS 80//160U + +#define FPC1020_PIXEL_COLUMNS 208//160U + +#define FPC1020_FRAME_SIZE_MAX (FPC1020_PIXEL_COLUMNS * \ + FPC1020_PIXEL_ROWS) + +#define FPC1020_DEADPIXEL_THRESHOLD 11 +#endif /* VENDOR_EDIT */ +#define FPC1020_MAX_ADC_SETTINGS (FPC1020_BUFFER_MAX_IMAGES + 1) + +#define FPC1020_DEFAULT_IRQ_TIMEOUT_MS (500 * HZ / 1000) + +#define FPC1020_STATUS_REG_RESET_VALUE 0x1e + +#define FPC1020_STATUS_REG_MODE_MASK ( \ + FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD | \ + FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE | \ + FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN) + +#define FPC1020_STATUS_REG_IN_DEEP_SLEEP_MODE 0 + +#define FPC1020_STATUS_REG_IN_SLEEP_MODE 0 + +#define FPC1020_STATUS_REG_IN_IDLE_MODE ( \ + FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD | \ + FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE | \ + FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN) + +#define FPC1020_SLEEP_RETRIES 5 +#define FPC1020_SLEEP_RETRY_TIME_US 1000 + +#define FPC1020_RESET_RETRIES 2 +#define FPC1020_RESET_LOW_US 1000 +#define FPC1020_RESET_HIGH1_US 100 +#define FPC1020_RESET_HIGH2_US 1250 + +#define FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS 20 + +#define NAV_IMAGE_WIDTH 128 +#define NAV_IMAGE_HEIGHT 8 +#define NAV_FRAME_SIZE NAV_IMAGE_WIDTH*NAV_IMAGE_HEIGHT + +#define FPC1020_WAKEUP_DETECT_ZONE_COUNT 2 +#define FPC1020_WAKEUP_DETECT_ROWS 8 +#define FPC1020_WAKEUP_DETECT_COLS 8 + +#define FPC1020_PXL_BIAS_CTRL 0x0F00 + +/* -------------------------------------------------------------------- */ +/* fpc1020 data types */ +/* -------------------------------------------------------------------- */ +typedef enum { + FPC_1020_STATUS_REG_BIT_IRQ = 1 << 0, + FPC_1020_STATUS_REG_BIT_MAIN_IDLE_CMD = 1 << 1, + FPC_1020_STATUS_REG_BIT_SYNC_PWR_IDLE = 1 << 2, + FPC_1020_STATUS_REG_BIT_PWR_DWN_OSC_HIN = 1 << 3, + FPC_1020_STATUS_REG_BIT_FIFO_EMPTY = 1 << 4, + FPC_1020_STATUS_REG_BIT_FIFO_FULL = 1 << 5, + FPC_1020_STATUS_REG_BIT_MISO_EDGRE_RISE_EN = 1 << 6 +} fpc1020_status_reg_t; + +typedef enum { + FPC1020_CMD_FINGER_PRESENT_QUERY = 32, + FPC1020_CMD_WAIT_FOR_FINGER_PRESENT = 36, + FPC1020_CMD_ACTIVATE_SLEEP_MODE = 40, + FPC1020_CMD_ACTIVATE_DEEP_SLEEP_MODE = 44, + FPC1020_CMD_ACTIVATE_IDLE_MODE = 52, + FPC1020_CMD_CAPTURE_IMAGE = 192, + FPC1020_CMD_READ_IMAGE = 196, + FPC1020_CMD_SOFT_RESET = 248 +} fpc1020_cmd_t; + +typedef enum { + FPC_1020_IRQ_REG_BIT_FINGER_DOWN = 1 << 0, + FPC_1020_IRQ_REG_BIT_ERROR = 1 << 2, + FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA = 1 << 5, + FPC_1020_IRQ_REG_BIT_COMMAND_DONE = 1 << 7, + FPC_1020_IRQ_REG_BITS_REBOOT = 0xff +} fpc1020_irq_reg_t; + +typedef enum { + FPC1020_CAPTURE_STATE_IDLE = 0, + FPC1020_CAPTURE_STATE_STARTED, + FPC1020_CAPTURE_STATE_PENDING, + FPC1020_CAPTURE_STATE_WRITE_SETTINGS, + FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN, + FPC1020_CAPTURE_STATE_ACQUIRE, + FPC1020_CAPTURE_STATE_FETCH, + FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP, + FPC1020_CAPTURE_STATE_COMPLETED, + FPC1020_CAPTURE_STATE_FAILED, +} fpc1020_capture_state_t; + +typedef struct fpc1020_worker_struct { + struct task_struct *thread; + struct semaphore sem_idle; + wait_queue_head_t wq_wait_job; + int req_mode; + bool stop_request; +} fpc1020_worker_t; + +typedef struct fpc1020_capture_struct { + fpc1020_capture_mode_t current_mode; + fpc1020_capture_state_t state; + u32 read_offset; + u32 available_bytes; + wait_queue_head_t wq_data_avail; + int last_error; + bool read_pending_eof; + bool deferred_finger_up; +} fpc1020_capture_task_t; + +#ifdef CONFIG_INPUT_FPC1020_NAV +typedef struct fpc1020_nav_struct { + bool enabled; + + /*image based navigation parameter*/ + u8 image_nav_row_start; + u8 image_nav_row_count; + u8 image_nav_col_start; + u8 image_nav_col_groups; + + unsigned long time; + int tap_status; + u8 input_mode; + int nav_sum_x; + int nav_sum_y; + + u8 p_multiplier_x; + u8 p_multiplier_y; + u8 p_sensitivity_key; + u8 p_sensitivity_ptr; + u8 multiplier_key_accel; + u8 multiplier_ptr_accel; + u8 threshold_key_accel; + u8 threshold_ptr_accel; + u8 threshold_ptr_start; + u8 duration_ptr_clear; + u8 nav_finger_up_threshold; +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for move parameter + int move_time_threshold; + int move_distance_threshold; +#endif /* VENDOR_EDIT */ +} fpc1020_nav_task_t; +#endif + +typedef struct fpc1020_setup { + u8 adc_gain[FPC1020_MAX_ADC_SETTINGS]; + u8 adc_shift[FPC1020_MAX_ADC_SETTINGS]; + u16 pxl_ctrl[FPC1020_MAX_ADC_SETTINGS]; + u8 capture_settings_mux; + u8 capture_count; + fpc1020_capture_mode_t capture_mode; + u8 capture_row_start; /* Row 0-191 */ + u8 capture_row_count; /* Rows <= 192 */ + u8 capture_col_start; /* ADC group 0-23 */ + u8 capture_col_groups; /* ADC groups, 1-24 */ + u8 capture_finger_up_threshold; + u8 capture_finger_down_threshold; + u8 finger_detect_threshold; + u8 wakeup_detect_rows[FPC1020_WAKEUP_DETECT_ZONE_COUNT]; + u8 wakeup_detect_cols[FPC1020_WAKEUP_DETECT_ZONE_COUNT]; +} fpc1020_setup_t; + +typedef struct fpc1020_diag { + const char *chip_id; /* RO */ + u8 selftest; /* RO */ + u16 spi_register; /* RW */ + u8 spi_regsize; /* RO */ + u8 spi_data; /* RW */ + u16 last_capture_time; /* RO*/ + u16 finger_present_status; /* RO*/ +} fpc1020_diag_t; + +typedef struct fpc1020_chip_info { + fpc1020_chip_t type; + u8 revision; + u8 pixel_rows; + u8 pixel_columns; + u8 adc_group_size; +}fpc1020_chip_info_t; + +typedef struct { + struct spi_device *spi; + struct class *class; + struct device *device; + struct cdev cdev; + dev_t devno; + fpc1020_chip_info_t chip; +#ifndef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + u32 cs_gpio; +#endif /* VENDOR_EDIT */ + u32 reset_gpio; + u32 irq_gpio; +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config + u32 vdden_gpio; //ranfei +#endif /* VENDOR_EDIT */ + + #ifdef VENDOR_EDIT //changhua add for reconize DT CT module + int vendor_gpio; + int fp2050_gpio; + bool to_power; + #if defined(CONFIG_FB) + struct notifier_block fb_notif; + #endif + #endif + + int irq; + wait_queue_head_t wq_irq_return; + bool interrupt_done; + struct semaphore mutex; + u8 *huge_buffer; + size_t huge_buffer_size; + fpc1020_worker_t worker; + fpc1020_capture_task_t capture; + fpc1020_setup_t setup; + fpc1020_diag_t diag; + bool soft_reset_enabled; +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + struct regulator *vcc_spi; +#endif /* VENDOR_EDIT */ + struct regulator *vdd_ana; + struct regulator *vdd_io; + bool power_enabled; + int vddtx_mv; + bool txout_boost; + +#ifdef CONFIG_INPUT_FPC1020_NAV + struct input_dev *input_dev; + struct input_dev *touch_pad_dev; + fpc1020_nav_task_t nav; + u8* prev_img_buf; + u8* cur_img_buf; +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for navigation move event + unsigned long touch_time; + int move_distance; + unsigned int moving_key; +#endif /* VENDOR_EDIT */ + +#ifdef FPC_TEE_INTERRUPT_ONLY + wait_queue_head_t g_irq_event; + bool tee_interrupt_done; + bool tee_int_enable; + bool wait_abort; + bool wake_irq_state; + + struct wake_lock wakelock; + struct wake_lock irq_wakelock; +#endif + +#endif +} fpc1020_data_t; + +typedef struct { + fpc1020_reg_t reg; + bool write; + u16 reg_size; + u8 *dataptr; +} fpc1020_reg_access_t; + + +/* -------------------------------------------------------------------- */ +/* function prototypes */ +/* -------------------------------------------------------------------- */ +extern size_t fpc1020_calc_huge_buffer_minsize(fpc1020_data_t *fpc1020); + +extern int fpc1020_manage_huge_buffer(fpc1020_data_t *fpc1020, + size_t new_size); + +extern int fpc1020_setup_defaults(fpc1020_data_t *fpc1020); + +extern int fpc1020_gpio_reset(fpc1020_data_t *fpc1020); + +extern int fpc1020_spi_reset(fpc1020_data_t *fpc1020); + +extern int fpc1020_reset(fpc1020_data_t *fpc1020); + +extern int fpc1020_check_hw_id(fpc1020_data_t *fpc1020); + +extern const char *fpc1020_hw_id_text(fpc1020_data_t *fpc1020); + +extern int fpc1020_write_sensor_setup(fpc1020_data_t *fpc1020); + +extern int fpc1020_wait_for_irq(fpc1020_data_t *fpc1020, int timeout); + +extern int fpc1020_read_irq(fpc1020_data_t *fpc1020, bool clear_irq); + +extern int fpc1020_read_status_reg(fpc1020_data_t *fpc1020); + +extern int fpc1020_reg_access(fpc1020_data_t *fpc1020, + fpc1020_reg_access_t *reg_data); + +extern int fpc1020_cmd(fpc1020_data_t *fpc1020, fpc1020_cmd_t cmd, + u8 wait_irq_mask); + +extern int fpc1020_wait_finger_present(fpc1020_data_t *fpc1020); +#ifdef AS_HOME_KEY +extern int fpc1020_wait_finger_present_timeout(fpc1020_data_t *fpc1020); +#endif +extern int fpc1020_get_finger_present_status(fpc1020_data_t *fpc1020); + +extern int fpc1020_check_finger_present_raw(fpc1020_data_t *fpc1020); + +extern int fpc1020_check_finger_present_sum(fpc1020_data_t *fpc1020); + +extern int fpc1020_wake_up(fpc1020_data_t *fpc1020); + +extern int fpc1020_sleep(fpc1020_data_t *fpc1020, bool deep_sleep); + +extern int fpc1020_fetch_image(fpc1020_data_t *fpc1020, + u8 *buffer, + int offset, + size_t image_size_bytes, + size_t buff_size); + +extern bool fpc1020_check_in_range_u64(u64 val, u64 min, u64 max); + +extern int fpc1020_calc_finger_detect_threshold_min(fpc1020_data_t *fpc1020); + +extern int fpc1020_set_finger_detect_threshold(fpc1020_data_t *fpc1020, + int measured_val); + +#define FPC1020_MK_REG_READ_BYTES(__dst, __reg, __count, __ptr) { \ + (__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \ + (__dst).reg_size = (__count); \ + (__dst).write = false; \ + (__dst).dataptr = (__ptr); } + +#define FPC1020_MK_REG_READ(__dst, __reg, __ptr) { \ + (__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \ + (__dst).reg_size = FPC1020_REG_SIZE((__reg)); \ + (__dst).write = false; \ + (__dst).dataptr = (u8 *)(__ptr); } + +#define FPC1020_MK_REG_WRITE_BYTES(__dst, __reg, __count, __ptr) { \ + (__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \ + (__dst).reg_size = (__count); \ + (__dst).write = true; \ + (__dst).dataptr = (__ptr); } + +#define FPC1020_MK_REG_WRITE(__dst, __reg, __ptr) { \ + (__dst).reg = FPC1020_REG_TO_ACTUAL((__reg)); \ + (__dst).reg_size = FPC1020_REG_SIZE((__reg)); \ + (__dst).write = true; \ + (__dst).dataptr = (u8 *)(__ptr); } + +#define FPC1020_FINGER_DETECT_ZONE_MASK 0x0FFFU + +#endif /* LINUX_SPI_FPC1020_COMMON_H */ + diff --git a/drivers/input/misc/fpc1020_input.h b/drivers/input/misc/fpc1020_input.h new file mode 100755 index 0000000000000..4571ca4c473ba --- /dev/null +++ b/drivers/input/misc/fpc1020_input.h @@ -0,0 +1,29 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef LINUX_SPI_FPC1020_INPUT_H +#define LINUX_SPI_FPC1020_INPUT_H + +extern int /*__devinit*/ fpc1020_input_init(fpc1020_data_t *fpc1020); + +extern void /*__devexit*/ fpc1020_input_destroy(fpc1020_data_t *fpc1020); + +extern int fpc1020_input_enable(fpc1020_data_t *fpc1020, bool enabled); + +extern int fpc1020_input_task(fpc1020_data_t *fpc1020); + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for report touch down and up +extern void fpc1020_report_finger_down(fpc1020_data_t *fpc1020); + +extern void fpc1020_report_finger_up(fpc1020_data_t *fpc1020); +#endif /* VENDOR_EDIT */ + +#endif /* LINUX_SPI_FPC1020_NAV_H */ + diff --git a/drivers/input/misc/fpc1020_main.c b/drivers/input/misc/fpc1020_main.c new file mode 100755 index 0000000000000..f8f008007f4d2 --- /dev/null +++ b/drivers/input/misc/fpc1020_main.c @@ -0,0 +1,3116 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config +///* +#include +#include +#include + +#include + +#ifdef CONFIG_FB +#include +#include +#endif + +#include +//*/ +#include +#include +#include "../../../fs/proc/internal.h" //oneplus lichanghua mask for kernel changed. for use PDE +//#include //oneplus lichanghua mask for kernel changed. +#endif /* VENDOR_EDIT */ + +#if 0 //#ifndef CONFIG_USE_OF /*VENDOR_EDIT*/ //oneplus lichanghua modify for MSM8994 +#include +#include +#include +#include +#include +#include +#else +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config +#include +#include +#endif /* VENDOR_EDIT */ +#include +#include "fpc1020.h" +#include "fpc1020_common.h" +#include "fpc1020_regs.h" +#include "fpc1020_input.h" +#include "fpc1020_capture.h" +#include "fpc1020_regulator.h" +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Fingerprint Cards AB "); +MODULE_DESCRIPTION("FPC1020 touch sensor driver."); + + +/* -------------------------------------------------------------------- */ +/* fpc1020 sensor commands and registers */ +/* -------------------------------------------------------------------- */ +typedef enum { + FPC_1020_ERROR_REG_BIT_FIFO_UNDERFLOW = 1 << 0 +} fpc1020_error_reg_t; + + + +/* -------------------------------------------------------------------- */ +/* global variables */ +/* -------------------------------------------------------------------- */ +static int fpc1020_device_count; + + +/* -------------------------------------------------------------------- */ +/* fpc1020 data types */ +/* -------------------------------------------------------------------- */ +struct fpc1020_attribute { + struct device_attribute attr; + size_t offset; +}; + +enum { + FPC1020_WORKER_IDLE_MODE = 0, + FPC1020_WORKER_CAPTURE_MODE, + FPC1020_WORKER_INPUT_MODE, + FPC1020_WORKER_EXIT +}; + + +/* -------------------------------------------------------------------- */ +/* fpc1020 driver constants */ +/* -------------------------------------------------------------------- */ +#define FPC1020_CLASS_NAME "fpsensor" +#define FPC1020_WORKER_THREAD_NAME "fpc1020_worker" + + +/* -------------------------------------------------------------------- */ +/* function prototypes */ +/* -------------------------------------------------------------------- */ + +/*VENDOR_EDIT +Notices by changhua.li for kernel VERSION >=3.8 build error: +a whole set of __dev¡­ macros are no longer used or defined Here is the list: +__devinit, __devinitdata, __devinitconst, __devexit, __devexitdata, __devexitconst +background: These attributes were used on certain driver functions and data declarations, putting them in a separate section that could be discarded under certain circumstances. +This functionality is no longer relevant, and the macros were removed in version 3.8 of the kernel. The macros should no longer be used. Just remove the attributes any place they are used. + +see this commit: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54b956b903607 +*/ +static int __init fpc1020_init(void); + +static void __exit fpc1020_exit(void); + +static int /*__devinit*/ fpc1020_probe(struct spi_device *spi); + +static int /*__devexit*/ fpc1020_remove(struct spi_device *spi); + +static int fpc1020_suspend(struct device *dev); + +static int fpc1020_resume(struct device *dev); + +static int fpc1020_open(struct inode *inode, struct file *file); + +static ssize_t fpc1020_write(struct file *file, const char *buff, + size_t count, loff_t *ppos); + +static ssize_t fpc1020_read(struct file *file, char *buff, + size_t count, loff_t *ppos); + +static int fpc1020_release(struct inode *inode, struct file *file); + +static unsigned int fpc1020_poll(struct file *file, poll_table *wait); +static long fpc1020_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); + +static int fpc1020_cleanup(fpc1020_data_t *fpc1020, struct spi_device *spidev); + +static int /*__devinit*/ fpc1020_param_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata); + +static int /*__devinit*/ fpc1020_supply_init(fpc1020_data_t *fpc1020); + +static int /*__devinit*/ fpc1020_reset_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata); + +static int /*__devinit*/ fpc1020_irq_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata); + +static int /*__devinit*/ fpc1020_spi_setup(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata); + +static int /*__devinit*/ fpc1020_worker_init(fpc1020_data_t *fpc1020); + +static int /*__devexit*/ fpc1020_worker_destroy(fpc1020_data_t *fpc1020); + +static int /*__devinit*/ fpc1020_get_of_pdata(struct device *dev, + struct fpc1020_platform_data *pdata); + +static int /*__devinit*/ fpc1020_create_class(fpc1020_data_t *fpc1020); + +static int /*__devinit*/ fpc1020_create_device(fpc1020_data_t *fpc1020); + +static int fpc1020_manage_sysfs(fpc1020_data_t *fpc1020, + struct spi_device *spi, bool create); + +irqreturn_t fpc1020_interrupt(int irq, void *_fpc1020); + +static ssize_t fpc1020_show_attr_setup(struct device *dev, + struct device_attribute *attr, + char *buf); + +static ssize_t fpc1020_store_attr_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); + +static ssize_t fpc1020_show_attr_diag(struct device *dev, + struct device_attribute *attr, + char *buf); + +static ssize_t fpc1020_store_attr_diag(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count); + +static u8 fpc1020_selftest_short(fpc1020_data_t *fpc1020); + +static int fpc1020_start_capture(fpc1020_data_t *fpc1020); + +static int fpc1020_new_job(fpc1020_data_t *fpc1020, int new_job); + +static int fpc1020_worker_goto_idle(fpc1020_data_t *fpc1020); + +static int fpc1020_worker_function(void *_fpc1020); + +#ifdef CONFIG_INPUT_FPC1020_NAV +static int fpc1020_start_navigation(fpc1020_data_t *fpc1020); +#endif + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); +#endif + +unsigned int nav_switch = 1; +unsigned int enable_keys = 1; + +/* -------------------------------------------------------------------- */ +/* External interface */ +/* -------------------------------------------------------------------- */ +module_init(fpc1020_init); +module_exit(fpc1020_exit); + +static const struct dev_pm_ops fpc1020_pm = { + .suspend = fpc1020_suspend, + .resume = fpc1020_resume +}; + +//#ifdef CONFIG_USE_OF /*VENDOR_EDIT*/ +static struct of_device_id fpc1020_of_match[] /*__devinitdata*/ = { + { .compatible = "fpc,fpc1020", }, + {} +}; + +MODULE_DEVICE_TABLE(of, fpc1020_of_match); +//#endif /*VENDOR_EDIT*/ + + +static struct spi_driver fpc1020_driver = { + .driver = { + .name = FPC1020_DEV_NAME, + .bus = &spi_bus_type, + .owner = THIS_MODULE, + .pm = &fpc1020_pm, +//#ifdef CONFIG_USE_OF /*VENDOR_EDIT*/ + .of_match_table = fpc1020_of_match, +//#endif /*VENDOR_EDIT*/ + }, + .probe = fpc1020_probe, + .remove = /*__devexit_p*/(fpc1020_remove) +}; + +static const struct file_operations fpc1020_fops = { + .owner = THIS_MODULE, + .open = fpc1020_open, + .write = fpc1020_write, + .read = fpc1020_read, + .release = fpc1020_release, + .poll = fpc1020_poll, + .unlocked_ioctl = fpc1020_ioctl, + .compat_ioctl = fpc1020_ioctl, +}; + +static int is_tee_driver = true; + +/* -------------------------------------------------------------------- */ +/* devfs */ +/* -------------------------------------------------------------------- */ +#define FPC1020_ATTR(__grp, __field, __mode) \ +{ \ + .attr = __ATTR(__field, (__mode), \ + fpc1020_show_attr_##__grp, \ + fpc1020_store_attr_##__grp), \ + .offset = offsetof(struct fpc1020_##__grp, __field) \ +} + +#define FPC1020_DEV_ATTR(_grp, _field, _mode) \ +struct fpc1020_attribute fpc1020_attr_##_field = \ + FPC1020_ATTR(_grp, _field, (_mode)) + +#define DEVFS_SETUP_MODE (S_IWUSR|S_IWGRP/*|S_IWOTH*/|S_IRUSR|S_IRGRP/*|S_IROTH*/) + +static FPC1020_DEV_ATTR(setup, adc_gain, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, adc_shift, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_mode, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_count, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_settings_mux, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, pxl_ctrl, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_row_start, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_row_count, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_col_start, DEVFS_SETUP_MODE); +static FPC1020_DEV_ATTR(setup, capture_col_groups, DEVFS_SETUP_MODE); + +static struct attribute *fpc1020_setup_attrs[] = { + &fpc1020_attr_adc_gain.attr.attr, + &fpc1020_attr_adc_shift.attr.attr, + &fpc1020_attr_capture_mode.attr.attr, + &fpc1020_attr_capture_count.attr.attr, + &fpc1020_attr_capture_settings_mux.attr.attr, + &fpc1020_attr_pxl_ctrl.attr.attr, + &fpc1020_attr_capture_row_start.attr.attr, + &fpc1020_attr_capture_row_count.attr.attr, + &fpc1020_attr_capture_col_start.attr.attr, + &fpc1020_attr_capture_col_groups.attr.attr, + NULL +}; + +static const struct attribute_group fpc1020_setup_attr_group = { + .attrs = fpc1020_setup_attrs, + .name = "setup" +}; + +#define DEVFS_DIAG_MODE_RO (S_IRUSR|S_IRGRP|S_IROTH) +#define DEVFS_DIAG_MODE_RW (S_IWUSR|S_IWGRP/*|S_IWOTH*/|S_IRUSR|S_IRGRP/*|S_IROTH*/) + +static FPC1020_DEV_ATTR(diag, chip_id, DEVFS_DIAG_MODE_RO); +static FPC1020_DEV_ATTR(diag, selftest, DEVFS_DIAG_MODE_RO); +static FPC1020_DEV_ATTR(diag, spi_register, DEVFS_DIAG_MODE_RW); +static FPC1020_DEV_ATTR(diag, spi_regsize, DEVFS_DIAG_MODE_RO); +static FPC1020_DEV_ATTR(diag, spi_data , DEVFS_DIAG_MODE_RW); +static FPC1020_DEV_ATTR(diag, last_capture_time,DEVFS_DIAG_MODE_RO); +static FPC1020_DEV_ATTR(diag, finger_present_status, DEVFS_DIAG_MODE_RO); + +static struct attribute *fpc1020_diag_attrs[] = { + &fpc1020_attr_chip_id.attr.attr, + &fpc1020_attr_selftest.attr.attr, + &fpc1020_attr_spi_register.attr.attr, + &fpc1020_attr_spi_regsize.attr.attr, + &fpc1020_attr_spi_data.attr.attr, + &fpc1020_attr_last_capture_time.attr.attr, + &fpc1020_attr_finger_present_status.attr.attr, + NULL +}; + +static const struct attribute_group fpc1020_diag_attr_group = { + .attrs = fpc1020_diag_attrs, + .name = "diag" +}; + + +/* -------------------------------------------------------------------- */ +/* SPI debug interface, prototypes */ +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_select(fpc1020_data_t *fpc1020, + fpc1020_reg_t reg); + +static int fpc1020_spi_debug_value_write(fpc1020_data_t *fpc1020, u64 data); + +static int fpc1020_spi_debug_buffer_write(fpc1020_data_t *fpc1020, + const char *data, + size_t count); + +static int fpc1020_spi_debug_value_read(fpc1020_data_t *fpc1020, + u64 *data); + +static int fpc1020_spi_debug_buffer_read(fpc1020_data_t *fpc1020, + u8 *data, + size_t max_count); + +static void fpc1020_spi_debug_buffer_to_hex_string(char *string, + u8 *buffer, + size_t bytes); + +static int fpc1020_spi_debug_hex_string_to_buffer(u8 *buffer, + size_t buf_size, + const char *string, + size_t chars); + +/* -------------------------------------------------------------------- */ +/* function definitions */ +/* -------------------------------------------------------------------- */ +static int __init fpc1020_init(void) +{ + if(spi_register_driver(&fpc1020_driver)) + return -EINVAL; + return 0; +} + + +/* -------------------------------------------------------------------- */ +static void __exit fpc1020_exit(void) +{ + printk(KERN_INFO "%s\n", __func__); + + spi_unregister_driver(&fpc1020_driver); +} + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-28 Add for navigation switch + +static int fpc1020_nav_switch_show(struct seq_file *seq, void *offset) +{ + fpc1020_data_t *fpc1020 = seq->private; + + seq_printf(seq, "nav_switch:%d\n", fpc1020->nav.enabled); + return 0; +} + +static int fpc1020_nav_switch_open(struct inode *inode, struct file *file) +{ + fpc1020_data_t *fpc1020 = PDE(inode)->data;; + + return single_open(file, fpc1020_nav_switch_show, fpc1020); +} + +static void write_nav_switch(fpc1020_data_t *fpc1020) +{ + if(fpc1020->nav.enabled != nav_switch) { + fpc1020_input_enable(fpc1020, nav_switch); + if (nav_switch) { + fpc1020_start_navigation(fpc1020); + } else { + fpc1020_worker_goto_idle(fpc1020); + } + } +} + +static ssize_t fpc1020_nav_switch_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + fpc1020_data_t *fpc1020 = (fpc1020_data_t*)PDE(file->f_path.dentry->d_inode)->data; + + if (!fpc1020) { + return -EFAULT; + } + #if 0 + if (copy_from_user(&nav_switch, buffer, sizeof(nav_switch))) + return -EFAULT; + #else + sscanf(buffer, "%d", &nav_switch); + #endif + dev_err(&fpc1020->spi->dev, "nav_switch change to %d\n", nav_switch); + + write_nav_switch(fpc1020); + + return count; +} + +static const struct file_operations nav_switch_proc_fops = { + .owner = THIS_MODULE, + .open = fpc1020_nav_switch_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = fpc1020_nav_switch_write, +}; + + +static int vendor_show(struct seq_file *seq, void *offset) +{ + fpc1020_data_t *fpc1020 = seq->private; + seq_printf(seq, "%d : %s\n", gpio_get_value(fpc1020->vendor_gpio),gpio_get_value(fpc1020->vendor_gpio)?"DT" : "CT"); + return 0; +} + +static int vendor_open(struct inode *inode, struct file *file) +{ + fpc1020_data_t *fpc1020 = PDE(inode)->data; + return single_open(file, vendor_show, fpc1020); +} + + +static const struct file_operations vendor_proc_fops = { + .owner = THIS_MODULE, + .open = vendor_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + //.write = , +}; + +static ssize_t fpc1020_state_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + char * tmp; + fpc1020_data_t *fpc1020; + + tmp = strsep((char **) &buf, "\n"); + + fpc1020 = dev_get_drvdata(dev); + + //dev_dbg(&fpc1020->spi->dev, "%s go to %s\n", __func__, tmp); + + if(!strcmp(tmp, "idle")) { + fpc1020_worker_goto_idle(fpc1020); + } + + return count; +} +static ssize_t fpc1020_state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + fpc1020_data_t *fpc1020; + fpc1020 = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", fpc1020->worker.req_mode); +} + +// extern from clock_debug.c +///* +extern struct clk* blsp2_ahb_clk; +extern struct clk* blsp2_qup6_spi_clk; +static ssize_t fpc1020_clock_enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + //char * tmp; + fpc1020_data_t *fpc1020; + + //tmp = strsep((char **) &buf, "\n"); + char *after; + unsigned long val = simple_strtoul(buf, &after, 10); + int rc = -1; + + fpc1020 = dev_get_drvdata(dev); + + //dev_err(&fpc1020->spi->dev, "%s set clock %ld\n", __func__, val); + + if (val == 1) + { + rc = clk_prepare_enable(blsp2_ahb_clk); + if (rc) { + dev_err(&fpc1020->spi->dev, "%s: unable to enable core_clk\n", + __func__); + + } + + rc = clk_prepare_enable(blsp2_qup6_spi_clk); + if (rc) { + dev_err(&fpc1020->spi->dev, "%s: unable to enable iface_clk\n", + __func__); + } + }else + { + clk_disable_unprepare(blsp2_ahb_clk); + + clk_disable_unprepare(blsp2_qup6_spi_clk); + + } + + + return count; +} +static ssize_t fpc1020_clock_enable_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + + int ahb_enabled; + int qup_enabled; + + fpc1020_data_t *fpc1020; + fpc1020 = dev_get_drvdata(dev); + + + if (blsp2_ahb_clk->ops->is_enabled) + ahb_enabled = blsp2_ahb_clk->ops->is_enabled(blsp2_ahb_clk); + else + ahb_enabled = !!(blsp2_ahb_clk->count); + + if (blsp2_qup6_spi_clk->ops->is_enabled) + qup_enabled = blsp2_qup6_spi_clk->ops->is_enabled(blsp2_qup6_spi_clk); + else + qup_enabled = !!(blsp2_qup6_spi_clk->count); + + return sprintf(buf, "%d\n", ahb_enabled?qup_enabled:0); +} + +static DEFINE_MUTEX(mLock); + +static ssize_t fpc1020_home_switch_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + //char * tmp; + fpc1020_data_t *fpc1020; + + //tmp = strsep((char **) &buf, "\n"); + char *after; + + mutex_lock(&mLock); + + nav_switch = simple_strtoul(buf, &after, 10); + //int rc = -1; + + fpc1020 = dev_get_drvdata(dev); + + dev_err(&fpc1020->spi->dev, "nav_switch change to %d\n", nav_switch); + + write_nav_switch(fpc1020); + + mutex_unlock(&mLock); + return count; +} +static ssize_t fpc1020_home_switch_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + fpc1020_data_t *fpc1020; + fpc1020 = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", fpc1020->nav.enabled); +} +//*/ +static struct device_attribute fpc1020_state_attr = + __ATTR(state, 0660, fpc1020_state_show, fpc1020_state_store); +///* +static struct device_attribute fpc1020_clock_enable_attr = + __ATTR(clock_enable, 0660, fpc1020_clock_enable_show, fpc1020_clock_enable_store); + +static struct device_attribute fpc1020_home_switch_attr = + __ATTR(ap_tz_switch, 0660, fpc1020_home_switch_show, fpc1020_home_switch_store); +//*/ +#endif /* VENDOR_EDIT */ + +/* -------------------------------------------------------------------- */ +/*static*/ struct wake_lock fpc1020_wake_lock; +static char *chip_text[] = { + "N/A", /* FPC1020_CHIP_NONE */ + "fpc1020a", /* FPC1020_CHIP_1020A */ + "fpc1021a", /* FPC1020_CHIP_1021A */ + "fpc1021b", /* FPC1020_CHIP_1021B */ + "fpc1150a", /* FPC1020_CHIP_1150A */ + "fpc1150b", /* FPC1020_CHIP_1150B */ + "fpc1150f", /* FPC1020_CHIP_1150F */ + "fpc1155x" /* FPC1020_CHIP_1155X */ +}; +static int /*__devinit*/ fpc1020_probe(struct spi_device *spi) +{ + + + struct fpc1020_platform_data *fpc1020_pdata; + struct fpc1020_platform_data pdata_of; + struct device *dev = &spi->dev; + int error = 0; + fpc1020_data_t *fpc1020 = NULL; + size_t buffer_size; + + int retry_time = 0; + +#ifdef VENDOR_EDIT //changhua.li for debug + int cs; + int cpha,cpol,cs_high; + u32 max_speed; + + + +//return 0; + + + cs = spi->chip_select; + cpha = ( spi->mode & SPI_CPHA ) ? 1:0; + cpol = ( spi->mode & SPI_CPOL ) ? 1:0; + cs_high = ( spi->mode & SPI_CS_HIGH ) ? 1:0; + max_speed = spi->max_speed_hz; + dev_err(&spi->dev, "cs [%x] CPHA [%x] CPOL [%x] CS_HIGH [%x]\n",cs, cpha, cpol, cs_high); + dev_err(&spi->dev, "Max_speed [%d]\n", max_speed ); +#endif + + fpc1020 = kzalloc(sizeof(*fpc1020), GFP_KERNEL); + if (!fpc1020) { + dev_err(&spi->dev, + "failed to allocate memory for struct fpc1020_data\n"); + + return -ENOMEM; + } + + printk(KERN_INFO "%s\n", __func__); + + buffer_size = fpc1020_calc_huge_buffer_minsize(fpc1020); + error = fpc1020_manage_huge_buffer(fpc1020, buffer_size); + if (error) + goto malloc_err; + +#ifdef CONFIG_INPUT_FPC1020_NAV + fpc1020->prev_img_buf = kzalloc(NAV_FRAME_SIZE * sizeof(u8), GFP_KERNEL); + + if (!fpc1020->prev_img_buf) { + dev_err(&fpc1020->spi->dev, "failed allocating image buffer memory.\n"); + error = -ENOMEM; + goto malloc_err; + } + + fpc1020->cur_img_buf = kzalloc(NAV_FRAME_SIZE * sizeof(u8), GFP_KERNEL); + + if (!fpc1020->cur_img_buf) { + dev_err(&fpc1020->spi->dev, "failed allocating image buffer memory.\n"); + error = -ENOMEM; + goto malloc_err; + } +#endif + + + spi_set_drvdata(spi, fpc1020); + fpc1020->spi = spi; + + fpc1020->reset_gpio = -EINVAL; + fpc1020->irq_gpio = -EINVAL; +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + fpc1020->cs_gpio = -EINVAL; +#endif + + fpc1020->irq = -EINVAL; + + init_waitqueue_head(&fpc1020->wq_irq_return); + + wake_lock_init(&fpc1020->wakelock, WAKE_LOCK_SUSPEND, "fingerprint"); + wake_lock_init(&fpc1020->irq_wakelock, WAKE_LOCK_SUSPEND, "fingerprint_irq"); + +#ifdef FPC_TEE_INTERRUPT_ONLY + init_waitqueue_head(&fpc1020->g_irq_event); + fpc1020->tee_interrupt_done = true; + fpc1020->wait_abort = false; + fpc1020->wake_irq_state = false; +#endif + + error = fpc1020_init_capture(fpc1020); + if (error) + goto err; + + fpc1020_pdata = spi->dev.platform_data; + + if (!fpc1020_pdata) { + error = fpc1020_get_of_pdata(dev, &pdata_of); + fpc1020_pdata = &pdata_of; + + if (error) + goto err; + } + + if (!fpc1020_pdata) { + dev_err(&fpc1020->spi->dev, + "spi->dev.platform_data is NULL.\n"); + error = -EINVAL; + goto err; + } + + error = fpc1020_param_init(fpc1020, fpc1020_pdata); + if (error) + goto err; + + error = fpc1020_supply_init(fpc1020); + if (error) + goto err; + + error = fpc1020_reset_init(fpc1020, fpc1020_pdata); + if (error) + goto err; + + error = fpc1020_irq_init(fpc1020, fpc1020_pdata); + if (error) + goto err; + + error = fpc1020_spi_setup(fpc1020, fpc1020_pdata); + if (error) + goto err; + +#ifdef VENDOR_EDIT +//Changhua.Li@Prd.BSP,add for workaround some device bootup first time reset fail + do{ + error = fpc1020_reset(fpc1020); + if(error == 0) + break; + }while(retry_time++ < 5); + if (error) + goto err; + + error = fpc1020_check_hw_id(fpc1020); + if (error) + goto err; + + if(gpio_is_valid(fpc1020->fp2050_gpio)) + push_component_info(FINGERPRINTS,chip_text[fpc1020->chip.type] , gpio_get_value(fpc1020->fp2050_gpio)?(gpio_get_value(fpc1020->vendor_gpio)?"(FPC+2050)DT" : "(FPC+2050)CT"):(gpio_get_value(fpc1020->vendor_gpio)?"(FPC)DT" : "(FPC)CT")); + else + push_component_info(FINGERPRINTS,chip_text[fpc1020->chip.type] , gpio_get_value(fpc1020->vendor_gpio)?"(FPC)DT" : "(FPC)CT"); +#endif /* VENDOR_EDIT */ + + buffer_size = fpc1020_calc_huge_buffer_minsize(fpc1020); + error = fpc1020_manage_huge_buffer(fpc1020, buffer_size); + if (error) + goto err; + + error = fpc1020_setup_defaults(fpc1020); + if (error) + goto err; + + error = fpc1020_create_class(fpc1020); + if (error) + { + dev_err(&fpc1020->spi->dev, "fpc1020_create_class err!\n"); + goto err; + } + error = fpc1020_create_device(fpc1020); + if (error) + { + dev_err(&fpc1020->spi->dev, "fpc1020_create_device err!\n"); + goto err; + } + + sema_init(&fpc1020->mutex, 0); + + error = fpc1020_manage_sysfs(fpc1020, spi, true); + if (error) + { + dev_err(&fpc1020->spi->dev, "fpc1020_manage_sysfs err!\n"); + goto err; + } + + cdev_init(&fpc1020->cdev, &fpc1020_fops); + fpc1020->cdev.owner = THIS_MODULE; + + error = cdev_add(&fpc1020->cdev, fpc1020->devno, 1); + if (error) { + dev_err(&fpc1020->spi->dev, "cdev_add failed.\n"); + goto err_chrdev; + } + + error = fpc1020_worker_init(fpc1020); + if (error){ + dev_err(&fpc1020->spi->dev, "fpc1020_worker_init failed.\n"); + goto err_cdev; + } + +#ifdef VENDOR_EDIT +//Changhua.Li@Prd.BSP, 2015-02-4 Remove for not spi access in AP + error = fpc1020_calc_finger_detect_threshold_min(fpc1020); + if (error < 0){ + dev_err(&fpc1020->spi->dev, "fpc1020_calc_finger_detect_threshold_min failed.\n"); + goto err_cdev; + } +#endif /* VENDOR_EDIT */ + + error = fpc1020_set_finger_detect_threshold(fpc1020, error); + if (error < 0){ + dev_err(&fpc1020->spi->dev, "fpc1020_set_finger_detect_threshold failed.\n"); + goto err_cdev; + } + +#ifdef CONFIG_INPUT_FPC1020_NAV + error = fpc1020_input_init(fpc1020); + if (error) + goto err_cdev; + + #if defined(CONFIG_FB) + fpc1020->fb_notif.notifier_call = fb_notifier_callback; + error = fb_register_client(&fpc1020->fb_notif); + if(error) + dev_err(&fpc1020->spi->dev, "Unable to register fb_notifier: %d\n", error); + #endif + + error = fpc1020_start_navigation(fpc1020); + if (error) + goto err_cdev; +#else + error = fpc1020_sleep(fpc1020, true); + if (error) + goto err_cdev; +#endif + +#ifdef VENDOR_EDIT +/* + ahb_clk = clk_get(dev, "core_clk"); + if (IS_ERR(ahb_clk)) { + dev_err(&fpc1020->spi->dev, "%s: unable to get core_clk\n", __func__); + + } + + qup_clk= clk_get(dev, "iface_clk"); + if (IS_ERR(qup_clk)) { + dev_err(&fpc1020->spi->dev, "%s: unable to get iface_clk\n", __func__); + + } +*/ + //Lycan.Wang@Prd.BasicDrv, 2014-10-16 Add for navigation switch + if (!proc_create_data("nav_switch", 0666, NULL, &nav_switch_proc_fops, fpc1020)) { + error = -ENOMEM; + } + if (!proc_create_data("fpc_vendor", 0660, NULL, &vendor_proc_fops, fpc1020)) { + error = -ENOMEM; + } + + //Lycan.Wang@Prd.BasicDrv, 2014-11-03 Add for go to idle + dev_set_drvdata(fpc1020->device, fpc1020); + error = sysfs_create_file(&fpc1020->device->kobj, &fpc1020_state_attr.attr); +///* + error = sysfs_create_file(&fpc1020->device->kobj, &fpc1020_clock_enable_attr.attr); + error = sysfs_create_file(&fpc1020->device->kobj, &fpc1020_home_switch_attr.attr); + + device_init_wakeup(&fpc1020->spi->dev, 1); + wake_lock_init(&fpc1020_wake_lock, WAKE_LOCK_SUSPEND, "fpc1020_homekey"); +//*/ +#endif + + up(&fpc1020->mutex); + + return 0; + +err_cdev: + cdev_del(&fpc1020->cdev); + +err_chrdev: + //unregister_chrdev_region(fpc1020->devno, 1);//move after device_destroy + + fpc1020_manage_sysfs(fpc1020, spi, false); + +err: + wake_lock_destroy(&fpc1020->wakelock); + wake_lock_destroy(&fpc1020->irq_wakelock); + +malloc_err: + fpc1020_cleanup(fpc1020, spi); + return error; + +} + +/* -------------------------------------------------------------------- */ +static int /*__devexit*/ fpc1020_remove(struct spi_device *spi) +{ + fpc1020_data_t *fpc1020 = spi_get_drvdata(spi); + + printk(KERN_INFO "%s\n", __func__); + + #if defined(CONFIG_FB) + if( fb_unregister_client(&fpc1020->fb_notif) ) + dev_err(&fpc1020->spi->dev, "Error occurred while unregistering fb_notifier.\n"); + #endif + + fpc1020_manage_sysfs(fpc1020, spi, false); + + fpc1020_sleep(fpc1020, true); + + cdev_del(&fpc1020->cdev); + + unregister_chrdev_region(fpc1020->devno, 1); + + fpc1020_cleanup(fpc1020, spi); + + return 0; +} + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + + fpc1020_data_t *fpc1020 = container_of(self, fpc1020_data_t, fb_notif); + + if(FB_EARLY_EVENT_BLANK != event && FB_EVENT_BLANK != event) + return 0; + if((evdata) && (evdata->data) && (fpc1020)) { + blank = evdata->data; + if( *blank == FB_BLANK_UNBLANK && (event == FB_EARLY_EVENT_BLANK )) { + dev_err(&fpc1020->spi->dev, "%s change to home key\n", __func__); + fpc1020->to_power = false; + enable_keys = 1; + } else if( *blank == FB_BLANK_POWERDOWN && (event == FB_EVENT_BLANK )) { + dev_err(&fpc1020->spi->dev, "%s change to power key\n", __func__); + fpc1020->to_power = true; + enable_keys = 0; + } + } + return 0; +} +#endif + +/* -------------------------------------------------------------------- */ +static int fpc1020_suspend(struct device *dev) +{ + fpc1020_data_t *fpc1020 = dev_get_drvdata(dev); + int error = 0; + + //dev_err(&fpc1020->spi->dev, "%s,fpc1020->tee_interrupt_done=(%d),1:goto deep sleep 0:wait for finger\n", __func__,fpc1020->tee_interrupt_done); + //dev_err(&fpc1020->spi->dev, "%s,fpc1020->wake_irq_state=(%d)\n", __func__,fpc1020->wake_irq_state); +if (fpc1020->tee_interrupt_done){//no one open fingerprint mode,just goto deep sleep + fpc1020_worker_goto_idle(fpc1020); + + fpc1020_wake_up(fpc1020); + + fpc1020_write_sensor_setup(fpc1020); + + //fpc1020_worker_goto_idle(fpc1020); + + return fpc1020_sleep(fpc1020, true); + //error = fpc1020_sleep(fpc1020, false);//changhua.li modify for fingerdetect in sleep mode + //enable_irq_wake(fpc1020->irq); +} + if (!fpc1020->tee_interrupt_done && !fpc1020->wake_irq_state) { + fpc1020_worker_goto_idle(fpc1020); + dev_dbg(&fpc1020->spi->dev, "%s enable irq wake\n", __func__); + enable_irq_wake(fpc1020->irq);//TZ have set ic to sleep(0) + fpc1020->wake_irq_state = true; + } + + return error; +} + +/* -------------------------------------------------------------------- */ +static int fpc1020_resume(struct device *dev) +{ + fpc1020_data_t *fpc1020 = dev_get_drvdata(dev); + + //dev_err(&fpc1020->spi->dev, "%s,fpc1020->wake_irq_state=(%d)\n", __func__,fpc1020->wake_irq_state); + + if (fpc1020->wake_irq_state) { //home key will be back when nav_switch to 1 (sensor.release) + //dev_dbg(&fpc1020->spi->dev, "%s disable irq wake\n", __func__); + disable_irq_wake(fpc1020->irq); + fpc1020->wake_irq_state = false; + } + else{//no one open fingerprint mode,just resume to home key + #ifdef CONFIG_INPUT_FPC1020_NAV + //disable_irq_wake(fpc1020->irq); + //wake_lock_timeout(&fpc1020_wake_lock, 5 * HZ); + if(fpc1020->nav.enabled) + fpc1020_start_navigation(fpc1020); + #endif + } + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_open(struct inode *inode, struct file *file) + +{ + fpc1020_data_t *fpc1020; + + fpc1020 = container_of(inode->i_cdev, fpc1020_data_t, cdev); + + dev_err(&fpc1020->spi->dev, "%s\n", __func__); + + if (down_interruptible(&fpc1020->mutex)) + return -ERESTARTSYS; + + file->private_data = fpc1020; + + if (is_tee_driver) { + if (!wake_lock_active(&fpc1020->wakelock)) + wake_lock(&fpc1020->wakelock); + //dev_err(&fpc1020->spi->dev, "wake_lock(&fpc1020->wakelock);"); + /* + if (!fpc1020->clk_enable) { + ret = clk_prepare_enable(fpc1020->iface_clk); + if (ret) { + dev_err(&fpc1020->spi->dev, + "error on clk_prepare_enable(iface_clk):%d\n", ret); + } + + ret = clk_prepare_enable(fpc1020->core_clk); + if (ret) { + clk_disable_unprepare(fpc1020->iface_clk); + dev_err(&fpc1020->spi->dev, + "error clk_prepare_enable(core_clk):%d\n", ret); + } + + fpc1020->clk_enable = 1; + } + */ + fpc1020->wait_abort = false; + } + + up(&fpc1020->mutex); + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_write(struct file *file, const char *buff, + size_t count, loff_t *ppos) +{ + printk(KERN_INFO "%s\n", __func__); + + return -ENOTTY; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_read(struct file *file, char *buff, + size_t count, loff_t *ppos) +{ + fpc1020_data_t *fpc1020 = file->private_data; + int error = 0; + u32 max_data; + u32 avail_data; + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-11-10 Add for workaround method for hal bug(repeat read 0 byte) + if (count <= 0) { + //dev_dbg(&fpc1020->spi->dev, "%s : count = %d\n", __func__, count); + dev_dbg(&fpc1020->spi->dev, "%s : count = %zu\n", __func__, count); + return -EINVAL; + } +#endif /* VENDOR_EDIT */ + + if (down_interruptible(&fpc1020->mutex)) + return -ERESTARTSYS; + + if (fpc1020->capture.available_bytes > 0) { + goto copy_data; + } else { + + if (fpc1020->capture.read_pending_eof) { + fpc1020->capture.read_pending_eof = false; + error = 0; + goto out; + } + + if (file->f_flags & O_NONBLOCK) { + if (fpc1020_capture_check_ready(fpc1020)) { + error = fpc1020_start_capture(fpc1020); + if (error) + goto out; + } + + error = -EWOULDBLOCK; + goto out; + + } else { + error = fpc1020_start_capture(fpc1020); + if (error) + goto out; + } + } + + error = wait_event_interruptible( + fpc1020->capture.wq_data_avail, + (fpc1020->capture.available_bytes > 0)); + + if (error) + goto out; + + if (fpc1020->capture.last_error != 0) { + error = fpc1020->capture.last_error; + goto out; + } + +copy_data: + avail_data = fpc1020->capture.available_bytes; + max_data = (count > avail_data) ? avail_data : count; + + if (max_data) { + error = copy_to_user(buff, + &fpc1020->huge_buffer[fpc1020->capture.read_offset], + max_data); + + if (error) + goto out; + + fpc1020->capture.read_offset += max_data; + fpc1020->capture.available_bytes -= max_data; + + error = max_data; + + if (fpc1020->capture.available_bytes == 0) + fpc1020->capture.read_pending_eof = true; + } + +out: + up(&fpc1020->mutex); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_release(struct inode *inode, struct file *file) +{ + fpc1020_data_t *fpc1020 = file->private_data; + int status = 0; + + dev_err(&fpc1020->spi->dev, "%s\n", __func__); + + if (wake_lock_active(&fpc1020->wakelock)) { + wake_unlock(&fpc1020->wakelock); + } + //dev_err(&fpc1020->spi->dev, "wake_unlock(&fpc1020->wakelock);"); +if (!is_tee_driver) { + + if (down_interruptible(&fpc1020->mutex)) + return -ERESTARTSYS; + +#ifdef CONFIG_INPUT_FPC1020_NAV + fpc1020_start_navigation(fpc1020); +#else + fpc1020_worker_goto_idle(fpc1020); + + fpc1020_sleep(fpc1020, true); +#endif + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-11-19 Add for workaround method for fpc1020_read no return + if ((fpc1020->capture.state != FPC1020_CAPTURE_STATE_IDLE) && + (fpc1020->capture.state != FPC1020_CAPTURE_STATE_COMPLETED) && + (fpc1020->capture.state != FPC1020_CAPTURE_STATE_FAILED)) { + dev_err(&fpc1020->spi->dev,"%s capture state is %d\n", __func__, fpc1020->capture.state); + fpc1020->capture.state = FPC1020_CAPTURE_STATE_IDLE; + } +#endif /* VENDOR_EDIT */ + + up(&fpc1020->mutex); +} + + return status; +} + + +/* -------------------------------------------------------------------- */ +static unsigned int fpc1020_poll(struct file *file, poll_table *wait) +{ + fpc1020_data_t *fpc1020 = file->private_data; + unsigned int ret = 0; + fpc1020_capture_mode_t mode = fpc1020->setup.capture_mode; + bool blocking_op; + + if (down_interruptible(&fpc1020->mutex)) + return -ERESTARTSYS; + + if (fpc1020->capture.available_bytes > 0) + ret |= (POLLIN | POLLRDNORM); + else if (fpc1020->capture.read_pending_eof) + ret |= POLLHUP; + else { /* available_bytes == 0 && !pending_eof */ + + blocking_op = + (mode == FPC1020_MODE_WAIT_AND_CAPTURE) ? true : false; + + switch (fpc1020->capture.state) { + case FPC1020_CAPTURE_STATE_IDLE: + if (!blocking_op) + ret |= POLLIN; + break; + + case FPC1020_CAPTURE_STATE_STARTED: + case FPC1020_CAPTURE_STATE_PENDING: + case FPC1020_CAPTURE_STATE_WRITE_SETTINGS: + case FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN: + case FPC1020_CAPTURE_STATE_ACQUIRE: + case FPC1020_CAPTURE_STATE_FETCH: + case FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP: + case FPC1020_CAPTURE_STATE_COMPLETED: + ret |= POLLIN; + + poll_wait(file, &fpc1020->capture.wq_data_avail, wait); + + if (fpc1020->capture.available_bytes > 0) + ret |= POLLRDNORM; + else if (blocking_op) + ret = 0; + + break; + + case FPC1020_CAPTURE_STATE_FAILED: + if (!blocking_op) + ret |= POLLIN; + break; + + default: + dev_err(&fpc1020->spi->dev, + "%s unknown state\n", __func__); + break; + } + } + + up(&fpc1020->mutex); + + return ret; +} + +#define FPC_HW_RESET _IOW('K', 0, int) +#define FPC_GET_INTERRUPT _IOR('K', 1, int) +#define FPC_GET_IRQ_GPIO _IOR('K', 2, int) +#define FPC_REG_CMD _IOR('K', 3, int) +#define FPC_REG_ACCESS _IOWR('K', 4, fpc1020_reg_io_access_t) +#define FPC_REG_READALL _IOR('K', 5, int) +#define FPC_ABORT _IOR('K', 6, int) +#define FPC_ENABLE_SPI_CLK _IOR('K', 7, int) +#define FPC_DISABLE_SPI_CLK _IOR('K', 8, int) + +static long fpc1020_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + fpc1020_data_t *fpc1020 = file->private_data; + void __user *up = (void __user *)arg; + int value; + int ret; + + switch (cmd) { + case FPC_HW_RESET: + dev_dbg(&fpc1020->spi->dev, "FPC_HW_RESET "); + if (!gpio_is_valid(fpc1020->reset_gpio)) + { + dev_dbg(&fpc1020->spi->dev, "fpc Reset pin was not assigned properly %d", fpc1020->reset_gpio); + } + + fpc1020_gpio_reset(fpc1020); + break; + + case FPC_GET_INTERRUPT: + { + value = gpio_get_value(fpc1020->irq_gpio); + if (value) { + dev_err(&fpc1020->spi->dev, "gpio (%d) no need wait", value); + + if (!wake_lock_active(&fpc1020->wakelock)) { + wake_lock(&fpc1020->wakelock); + } + //dev_err(&fpc1020->spi->dev, "wake_lock(&fpc1020->wakelock);"); + + if (put_user(value,(int *)up)) + { + dev_dbg(&fpc1020->spi->dev, "fpc put_user (%d)" , *(int *)up); + return -EFAULT; + } + + return 0; + } + + //dev_err(&fpc1020->spi->dev, "FPC_GET_INTERRUPT: waiting irq....\n"); + if (fpc1020->tee_interrupt_done) { + fpc1020->tee_interrupt_done = false; + //enable_irq(fpc1020->irq); + dev_err(&fpc1020->spi->dev, "FPC_GET_INTERRUPT: enable_irq\n"); + } +#ifdef FPC_TEE_INTERRUPT_ONLY + //wait_event_interruptible_timeout(fpc1020->g_irq_event, fpc1020->tee_interrupt_done, 100); + if (wake_lock_active(&fpc1020->wakelock)) { + wake_unlock(&fpc1020->wakelock); + } + //dev_err(&fpc1020->spi->dev, "wake_unlock(&fpc1020->wakelock);"); + + ret = wait_event_interruptible(fpc1020->g_irq_event, fpc1020->tee_interrupt_done || fpc1020->wait_abort); + //dev_err(&fpc1020->spi->dev, "tee_interrupt_done(%d) wait_abort(%d) ret = %d\n" , fpc1020->tee_interrupt_done, fpc1020->wait_abort, ret); + if (ret == -ERESTARTSYS) { + return ret; + } +#endif + if (fpc1020->wait_abort) { + fpc1020->wait_abort = false; + } else { + value = gpio_get_value(fpc1020->irq_gpio); + if (value) { + if (!wake_lock_active(&fpc1020->wakelock)) { + wake_lock(&fpc1020->wakelock); + } + //dev_err(&fpc1020->spi->dev, "wake_lock(&fpc1020->wakelock);"); + + } + } + + //dev_err(&fpc1020->spi->dev, "FPC_GET_INTERRUPT irq gpio (%d) comming\n" , value); + + if (put_user(value,(int *)up)) + { + dev_dbg(&fpc1020->spi->dev, "fpc put_user (%d)" , *(int *)up); + return -EFAULT; + } + break; + } + + case FPC_GET_IRQ_GPIO: + { + if (!up) + { + dev_err(&fpc1020->spi->dev, "%s up is NULL \n", __func__); + } + + if (!gpio_is_valid(fpc1020->irq_gpio)) + { + dev_dbg(&fpc1020->spi->dev, "fpc irq_gpio was not assigned properly %d", fpc1020->irq_gpio); + } + + value = gpio_get_value(fpc1020->irq_gpio); + dev_dbg(&fpc1020->spi->dev, "FPC_GET_IRQ_GPIO: (%d)", value); + + if (put_user(value,(int *)up)) + { + dev_dbg(&fpc1020->spi->dev, "fpc put_user (%d)" , *(int *)up); + return -EFAULT; + } + break; + + } + + case FPC_REG_CMD: + { + + unsigned int reg_cmd = *(unsigned int*)up; + + dev_dbg(&fpc1020->spi->dev, "FPC_REG_CMD: "); + + value = fpc1020_cmd(fpc1020, reg_cmd, false); + + dev_dbg(&fpc1020->spi->dev, "fpc cmd: (%d)" , reg_cmd); + break; + + } + +#if 0 + case FPC_REG_ACCESS: + { + fpc1020_reg_io_access_t fpcreg; + + dev_dbg(&fpc1020->spi->dev, "FPC_REG_ACCESS: "); + + if (!up) + { + dev_dbg(&fpc1020->spi->dev, "FPC_REG_ACCESS: up is NULL "); + return -EINVAL; + } + memcpy(&fpcreg, up, sizeof(fpc1020_reg_io_access_t)); + + value = fpc1020_reg_io_access(fpc1020, &fpcreg); + + dev_dbg(&fpc1020->spi->dev, "fpc reg access reg: (%d)" , fpcreg.reg); + + //if (put_user(&fpcreg,up)) + if (copy_to_user((fpc1020_reg_io_access_t *)up, &fpcreg, sizeof(fpc1020_reg_io_access_t))) + { + dev_dbg(&fpc1020->spi->dev, "fpc copy_to_user fail \n"); + return -EFAULT; + } + + break; + + } +#endif + case FPC_REG_READALL: + //fpc1020_read_all + break; + + case FPC_ABORT: + dev_err(&fpc1020->spi->dev, "FPC_ABORT \n"); + //wake_up_interruptible(&fpc1020->g_irq_event); + //fpc1020->tee_interrupt_done = true; + fpc1020->wait_abort = true; + wake_up_interruptible(&fpc1020->g_irq_event); + break; +/* + case FPC_ENABLE_SPI_CLK: + if (!fpc1020->clk_enable) { + dev_dbg(&fpc1020->spi->dev, "spi clk enable\n"); + ret = clk_prepare_enable(fpc1020->iface_clk); + if (ret) { + dev_err(&fpc1020->spi->dev, + "error on clk_prepare_enable(iface_clk):%d\n", ret); + } + + ret = clk_prepare_enable(fpc1020->core_clk); + if (ret) { + clk_disable_unprepare(fpc1020->iface_clk); + dev_err(&fpc1020->spi->dev, + "error clk_prepare_enable(core_clk):%d\n", ret); + } + + fpc1020->clk_enable = 1; + } + break; + + case FPC_DISABLE_SPI_CLK: + if (fpc1020->clk_enable) { + dev_dbg(&fpc1020->spi->dev, "spi clk disable\n"); + clk_disable_unprepare(fpc1020->core_clk); + clk_disable_unprepare(fpc1020->iface_clk); + fpc1020->clk_enable = 0; + } + break; +*/ + default: + dev_dbg(&fpc1020->spi->dev, "ENOIOCTLCMD: cmd=%d ", cmd); + return -ENOIOCTLCMD; + } + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_cleanup(fpc1020_data_t *fpc1020, struct spi_device *spidev) +{ + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + fpc1020_worker_destroy(fpc1020); + + if (!IS_ERR_OR_NULL(fpc1020->device)) + device_destroy(fpc1020->class, fpc1020->devno); + + class_destroy(fpc1020->class); + + unregister_chrdev_region(fpc1020->devno, 1); + + if (fpc1020->irq >= 0) + free_irq(fpc1020->irq, fpc1020); + + if (gpio_is_valid(fpc1020->irq_gpio)) + gpio_free(fpc1020->irq_gpio); + + if (gpio_is_valid(fpc1020->reset_gpio)) + gpio_free(fpc1020->reset_gpio); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + if (gpio_is_valid(fpc1020->cs_gpio)) + gpio_free(fpc1020->cs_gpio); +#endif /* VENDOR_EDIT */ + + fpc1020_manage_huge_buffer(fpc1020, 0); + +#ifdef CONFIG_INPUT_FPC1020_NAV + fpc1020_input_destroy(fpc1020); +#endif + + fpc1020_regulator_release(fpc1020); + +#ifdef CONFIG_INPUT_FPC1020_NAV + kfree(fpc1020->prev_img_buf); + kfree(fpc1020->cur_img_buf); +#endif + + kfree(fpc1020); + + spi_set_drvdata(spidev, NULL); + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_param_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata) +{ + fpc1020->vddtx_mv = pdata->external_supply_mv; + fpc1020->txout_boost = pdata->txout_boost; + + if (fpc1020->vddtx_mv > 0) { + dev_info(&fpc1020->spi->dev, + "External TxOut supply (%d mV)\n", + fpc1020->vddtx_mv); + } else { + dev_info(&fpc1020->spi->dev, + "Internal TxOut supply (boost %s)\n", + (fpc1020->txout_boost) ? "ON" : "OFF"); + } + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_supply_init(fpc1020_data_t *fpc1020) +{ + int error = 0; + + error = fpc1020_regulator_configure(fpc1020); + if (error) { + dev_err(&fpc1020->spi->dev, + "fpc1020_probe - regulator configuration failed.\n"); + goto err; + } + + error = fpc1020_regulator_set(fpc1020, true); + if (error) { + dev_err(&fpc1020->spi->dev, + "fpc1020_probe - regulator enable failed.\n"); + goto err; + } + +err: + return error; +} + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_reset_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata) +{ + int error = 0; + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for Hw Config + if (gpio_is_valid(pdata->reset_gpio)) { + + dev_info(&fpc1020->spi->dev, + "Assign HW reset -> GPIO%d\n", pdata->reset_gpio); + + fpc1020->soft_reset_enabled = false; + + error = gpio_request(pdata->reset_gpio, "fpc1020_reset"); + + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_request (reset) failed.\n"); + return error; + } + + fpc1020->reset_gpio = pdata->reset_gpio; + + error = gpio_direction_output(fpc1020->reset_gpio, 1); + + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_direction_output(reset) failed.\n"); + return error; + } + } else { + dev_info(&fpc1020->spi->dev, "Using soft reset\n"); + + fpc1020->soft_reset_enabled = true; + } + +#else /* VENDOR_EDIT */ + struct gpio fpc1020_all_gpio[] = + { + {pdata->irq_gpio, GPIOF_DIR_IN, "fpc_irq_gpio"}, + {pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "fpc_reset_gpio"}, + #ifdef VENDOR_EDIT /*oneplus changhua remove for HW CONFIG of 14009 EVB2*/ + {pdata->vdden_gpio, GPIOF_OUT_INIT_HIGH, "fpc_envdd_gpio"}, + #endif /* VENDOR_EDIT */ + #ifdef VENDOR_EDIT //changhua add for recognize CT DT module + {pdata->vendor_gpio, GPIOF_DIR_IN, "fpc_vendor_gpio"}, + //{pdata->fp2050_gpio, GPIOF_DIR_IN, "fpc_2050_gpio"}, + #endif + }; + + gpio_request_array(fpc1020_all_gpio, ARRAY_SIZE(fpc1020_all_gpio)); + #if 0 + gpio_tlmm_config(GPIO_CFG(pdata->irq_gpio, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); + #ifndef VENDOR_EDIT /*2014 12.31 oneplus changhua remove for HW CONFIG of 14009 EVB2*/ + gpio_tlmm_config(GPIO_CFG(pdata->vdden_gpio, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); + #endif /* VENDOR_EDIT */ + gpio_tlmm_config(GPIO_CFG(pdata->reset_gpio, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); + #else + //gpio_direction_input(pdata->irq_gpio); + gpio_direction_output(pdata->reset_gpio,1); + + if(gpio_is_valid(pdata->fp2050_gpio)) + { + gpio_request(pdata->fp2050_gpio,"fpc_2050_gpio"); + gpio_direction_input(pdata->fp2050_gpio); + } + + #endif + fpc1020->reset_gpio = pdata->reset_gpio; + fpc1020->irq_gpio = pdata->irq_gpio; + #ifdef VENDOR_EDIT /*2014 12.31 oneplus changhua remove for HW CONFIG of 14009 EVB2*/ + fpc1020->vdden_gpio = pdata->vdden_gpio; + #endif /* VENDOR_EDIT */ + #ifdef VENDOR_EDIT //changhua add for recognize CT DT module + fpc1020->vendor_gpio = pdata->vendor_gpio; + fpc1020->fp2050_gpio = pdata->fp2050_gpio; + #endif + fpc1020->soft_reset_enabled = false; +#endif /* VENDOR_EDIT */ + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_irq_init(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata) +{ + int error = 0; + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + if (gpio_is_valid(pdata->irq_gpio)) { + + dev_info(&fpc1020->spi->dev, + "Assign IRQ -> GPIO%d\n", + pdata->irq_gpio); + + error = gpio_request(pdata->irq_gpio, "fpc1020_irq"); + + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_request (irq) failed.\n"); + + return error; + } + + fpc1020->irq_gpio = pdata->irq_gpio; + + error = gpio_direction_input(fpc1020->irq_gpio); + + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_direction_input (irq) failed.\n"); + return error; + } + } else { + return -EINVAL; + } +#endif /* VENDOR_EDIT */ + + fpc1020->irq = gpio_to_irq(fpc1020->irq_gpio); + + + if (fpc1020->irq < 0) { + dev_err(&fpc1020->spi->dev, "gpio_to_irq failed.\n"); + error = fpc1020->irq; + return error; + } + + error = request_irq(fpc1020->irq, fpc1020_interrupt, + IRQF_TRIGGER_RISING, "fpc1020", fpc1020); + + if (error) { + dev_err(&fpc1020->spi->dev, + "request_irq %i failed.\n", + fpc1020->irq); + + fpc1020->irq = -EINVAL; + + return error; + } + + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_spi_setup(fpc1020_data_t *fpc1020, + struct fpc1020_platform_data *pdata) +{ + int error = 0; + + printk(KERN_INFO "%s\n", __func__); + + fpc1020->spi->mode = SPI_MODE_0; + fpc1020->spi->bits_per_word = 8; + + error = spi_setup(fpc1020->spi); + + if (error) { + dev_err(&fpc1020->spi->dev, "spi_setup failed\n"); + goto out_err; + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + if (gpio_is_valid(pdata->cs_gpio)) { + + dev_info(&fpc1020->spi->dev, + "Assign SPI.CS -> GPIO%d\n", + pdata->cs_gpio); + + error = gpio_request(pdata->cs_gpio, "fpc1020_cs"); + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_request (cs) failed.\n"); + + goto out_err; + } + + fpc1020->cs_gpio = pdata->cs_gpio; + + error = gpio_direction_output(fpc1020->cs_gpio, 1); + if (error) { + dev_err(&fpc1020->spi->dev, + "gpio_direction_output(cs) failed.\n"); + goto out_err; + } + } else { + error = -EINVAL; + } +#endif /* VENDOR_EDIT */ + +out_err: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_worker_init(fpc1020_data_t *fpc1020) +{ + int error = 0; + + printk(KERN_INFO "%s\n", __func__); + + init_waitqueue_head(&fpc1020->worker.wq_wait_job); + sema_init(&fpc1020->worker.sem_idle, 0); + + fpc1020->worker.req_mode = FPC1020_WORKER_IDLE_MODE; + + fpc1020->worker.thread = kthread_run(fpc1020_worker_function, + fpc1020, "%s", + FPC1020_WORKER_THREAD_NAME); + + if (IS_ERR(fpc1020->worker.thread)) { + dev_err(&fpc1020->spi->dev, "kthread_run failed.\n"); + error = (int)PTR_ERR(fpc1020->worker.thread); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int /*__devexit*/ fpc1020_worker_destroy(fpc1020_data_t *fpc1020) +{ + int error = 0; + + printk(KERN_INFO "%s\n", __func__); + + if (fpc1020->worker.thread) { + fpc1020_worker_goto_idle(fpc1020); + + fpc1020->worker.req_mode = FPC1020_WORKER_EXIT; + wake_up_interruptible(&fpc1020->worker.wq_wait_job); + kthread_stop(fpc1020->worker.thread); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +#if 1//#ifdef CONFIG_USE_OF /*VENDOR_EDIT*/ //changhua modify for MSM8994 +static int /*__devinit*/ fpc1020_get_of_pdata(struct device *dev, + struct fpc1020_platform_data *pdata) +{ +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for Hw Config + const struct device_node *node = dev->of_node; + /* required properties */ + const void *irq_prop = of_get_property(node, "fpc,gpio_irq", NULL); + const void *rst_prop = of_get_property(node, "fpc,gpio_reset", NULL); + const void *cs_prop = of_get_property(node, "fpc,gpio_cs", NULL); + + /* optional properties */ + const void *vddtx_prop = of_get_property(node, "fpc,vddtx_mv", NULL); + const void *boost_prop = + of_get_property(node, "fpc,txout_boost_enable", NULL); + + if (node == NULL) { + dev_err(dev, "%s: Could not find OF device node\n", __func__); + goto of_err; + } + + if (!irq_prop || !rst_prop || !cs_prop) { + dev_err(dev, "%s: Missing OF property\n", __func__); + goto of_err; + } + + pdata->irq_gpio = be32_to_cpup(irq_prop); + pdata->reset_gpio = be32_to_cpup(rst_prop); + pdata->cs_gpio = be32_to_cpup(cs_prop); + + pdata->external_supply_mv = + (vddtx_prop != NULL) ? be32_to_cpup(vddtx_prop) : 0; + + pdata->txout_boost = (boost_prop != NULL) ? 1 : 0; + + return 0; + +of_err: + pdata->reset_gpio = -EINVAL; + pdata->irq_gpio = -EINVAL; + pdata->cs_gpio = -EINVAL; + + pdata->external_supply_mv = 0; + pdata->txout_boost = 0; + + return -ENODEV; + +#else /* VENDOR_EDIT */ + struct device_node *node = dev->of_node; + + pdata->irq_gpio= of_get_named_gpio(node, "fpc,gpio_irq", 0); + if ((!gpio_is_valid(pdata->irq_gpio))) + return -EINVAL; + + pdata->reset_gpio= of_get_named_gpio(node, "fpc,gpio_reset", 0); + if ((!gpio_is_valid(pdata->reset_gpio))) + return -EINVAL; + + #ifdef VENDOR_EDIT //changhua add for reconize DT CT module + pdata->vendor_gpio= of_get_named_gpio(node, "fpc,gpio_vendor", 0); + if ((!gpio_is_valid(pdata->vendor_gpio))) + return -EINVAL; + + pdata->fp2050_gpio= of_get_named_gpio(node, "fpc,gpio_fp2050", 0); + if ((!gpio_is_valid(pdata->fp2050_gpio))) + printk("invalid fp2050 gpio,keep moving for machine before PVT\n"); + #endif + + #ifdef VENDOR_EDIT /*2014 12.31 oneplus changhua remove for HW CONFIG of 14009 EVB2*/ + pdata->vdden_gpio = of_get_named_gpio(node, "fpc,gpio_envdd", 0); + if ((!gpio_is_valid(pdata->vdden_gpio))) + return -EINVAL; + #endif /* VENDOR_EDIT */ + + pdata->external_supply_mv = 1; + pdata->txout_boost = 0; + + return 0; +#endif /* VENDOR_EDIT */ +} + +#else +static int /*__devinit*/ fpc1020_get_of_pdata(struct device *dev, + struct fpc1020_platform_data *pdata) +{ + pdata->reset_gpio = -EINVAL; + pdata->irq_gpio = -EINVAL; +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw Config + pdata->cs_gpio = -EINVAL; +#endif /* VENDOR_EDIT */ + + pdata->external_supply_mv = 0; + pdata->txout_boost = 0; + + return -ENODEV; +} +#endif + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_create_class(fpc1020_data_t *fpc1020) +{ + int error = 0; + + dev_err(&fpc1020->spi->dev, "%s\n", __func__); + + fpc1020->class = class_create(THIS_MODULE, FPC1020_CLASS_NAME); + + if (IS_ERR(fpc1020->class)) { + dev_err(&fpc1020->spi->dev, "failed to create class.\n"); + error = PTR_ERR(fpc1020->class); + } + + return error; +} + + + +/* -------------------------------------------------------------------- */ +static int /*__devinit*/ fpc1020_create_device(fpc1020_data_t *fpc1020) +{ + int error = 0; + + dev_err(&fpc1020->spi->dev, "%s\n", __func__); + + if (FPC1020_MAJOR > 0) { + fpc1020->devno = MKDEV(FPC1020_MAJOR, fpc1020_device_count++); + + error = register_chrdev_region(fpc1020->devno, + 1, + FPC1020_DEV_NAME); + } else { + error = alloc_chrdev_region(&fpc1020->devno, + fpc1020_device_count++, + 1, + FPC1020_DEV_NAME); + } + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s: FAILED %d.\n", __func__, error); + goto out; + + } else { + dev_info(&fpc1020->spi->dev, "%s: major=%d, minor=%d\n", + __func__, + MAJOR(fpc1020->devno), + MINOR(fpc1020->devno)); + } + + fpc1020->device = device_create(fpc1020->class, NULL, fpc1020->devno, + NULL, "%s", FPC1020_DEV_NAME); + + if (IS_ERR(fpc1020->device)) { + dev_err(&fpc1020->spi->dev, "device_create failed.\n"); + error = PTR_ERR(fpc1020->device); + } + +out: + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_manage_sysfs(fpc1020_data_t *fpc1020, + struct spi_device *spi, bool create) +{ + int error = 0; + + if (create) { + dev_err(&fpc1020->spi->dev, "%s create\n", __func__); + + error = sysfs_create_group(&spi->dev.kobj, + &fpc1020_setup_attr_group); + + if (error) { + dev_err(&fpc1020->spi->dev, + "sysf_create_group failed.\n"); + return error; + } + + error = sysfs_create_group(&spi->dev.kobj, + &fpc1020_diag_attr_group); + + if (error) { + sysfs_remove_group(&spi->dev.kobj, + &fpc1020_setup_attr_group); + + dev_err(&fpc1020->spi->dev, + "sysf_create_group failed.\n"); + + return error; + } + } else { + dev_err(&fpc1020->spi->dev, "%s remove\n", __func__); + + sysfs_remove_group(&spi->dev.kobj, &fpc1020_setup_attr_group); + sysfs_remove_group(&spi->dev.kobj, &fpc1020_diag_attr_group); + } + + return error; +} + + +/* -------------------------------------------------------------------- */ +irqreturn_t fpc1020_interrupt(int irq, void *_fpc1020) +{ + fpc1020_data_t *fpc1020 = _fpc1020; + + //dev_dbg(&fpc1020->spi->dev,"fpc1020_interrupt.fpc1020->tee_interrupt_done=(%d)\n",fpc1020->tee_interrupt_done); + if (gpio_get_value(fpc1020->irq_gpio)) { + fpc1020->interrupt_done = true; + wake_up_interruptible(&fpc1020->wq_irq_return); + +#ifdef FPC_TEE_INTERRUPT_ONLY + if (!fpc1020->tee_interrupt_done) { + fpc1020->tee_interrupt_done = true; + wake_up_interruptible(&fpc1020->g_irq_event); + wake_lock_timeout(&fpc1020->irq_wakelock, HZ/2); + } +#endif + + return IRQ_HANDLED; + } + return IRQ_NONE; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_show_attr_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + fpc1020_data_t *fpc1020 = dev_get_drvdata(dev); + struct fpc1020_attribute *fpc_attr; + int val = -1; + int mux; + + fpc_attr = container_of(attr, struct fpc1020_attribute, attr); + + mux = fpc1020->setup.capture_settings_mux; + + if (fpc_attr->offset == offsetof(fpc1020_setup_t, adc_gain)) + val = fpc1020->setup.adc_gain[mux]; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, adc_shift)) + val = fpc1020->setup.adc_shift[mux]; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, pxl_ctrl)) + val = fpc1020->setup.pxl_ctrl[mux]; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_mode)) + val = fpc1020->setup.capture_mode; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_count)) + val = fpc1020->setup.capture_count; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_settings_mux)) + val = fpc1020->setup.capture_settings_mux; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_row_start)) + val = fpc1020->setup.capture_row_start; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_row_count)) + val = fpc1020->setup.capture_row_count; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_col_start)) + val = fpc1020->setup.capture_col_start; + + else if (fpc_attr->offset == offsetof(fpc1020_setup_t, capture_col_groups)) + val = fpc1020->setup.capture_col_groups; + + if (val >= 0) + return scnprintf(buf, PAGE_SIZE, "%i\n", val); + + return -ENOENT; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_store_attr_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + fpc1020_data_t *fpc1020 = dev_get_drvdata(dev); + u64 val; + int error = kstrtou64(buf, 0, &val); + int mux; + int column_groups = fpc1020->chip.pixel_columns / fpc1020->chip.adc_group_size; + + struct fpc1020_attribute *fpc_attr; + fpc_attr = container_of(attr, struct fpc1020_attribute, attr); + + mux = fpc1020->setup.capture_settings_mux; + + if (!error) { + if (fpc_attr->offset == + offsetof(fpc1020_setup_t, adc_gain)) { + + fpc1020->setup.adc_gain[mux] = (u8)val; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, adc_shift)) { + + fpc1020->setup.adc_shift[mux] = (u8)val; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, pxl_ctrl)) { + + fpc1020->setup.pxl_ctrl[mux] = (u16)val; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_mode)) { + + fpc1020->setup.capture_mode = + (fpc1020_capture_mode_t)val; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_count)) { + + if (fpc1020_check_in_range_u64 + (val, 1, FPC1020_BUFFER_MAX_IMAGES)) { + + fpc1020->setup.capture_count = (u8)val; + } else + return -EINVAL; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_settings_mux)) { + + if (fpc1020_check_in_range_u64 + (val, 0, (FPC1020_BUFFER_MAX_IMAGES - 1))) { + + fpc1020->setup.capture_settings_mux = (u8)val; + } else + return -EINVAL; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_row_start)) { + + if (fpc1020_check_in_range_u64 + (val, 0, (fpc1020->chip.pixel_rows - 1))) { + + fpc1020->setup.capture_row_start = (u8)val; + } else + return -EINVAL; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_row_count)) { + + if (fpc1020_check_in_range_u64 + (val, 1, fpc1020->chip.pixel_rows)) { + + fpc1020->setup.capture_row_count = (u8)val; + } else + return -EINVAL; + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_col_start)) { + + if (fpc1020_check_in_range_u64 + (val, 0, (column_groups - 1))) { + + fpc1020->setup.capture_col_start = (u8)val; + } else + return -EINVAL; + + + } else if (fpc_attr->offset == + offsetof(fpc1020_setup_t, capture_col_groups)) { + + if (fpc1020_check_in_range_u64 + (val, 1, column_groups)) { + + fpc1020->setup.capture_col_groups = (u8)val; + } else + return -EINVAL; + + } else + return -ENOENT; + + return strnlen(buf, count); + } + return error; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_show_attr_diag(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + fpc1020_data_t *fpc1020; + struct fpc1020_attribute *fpc_attr; + u64 val; + int error = 0; + bool is_buffer = false; + u8 u8_buffer[FPC1020_REG_MAX_SIZE]; + char hex_string[sizeof("0x") + (FPC1020_REG_MAX_SIZE * 2)]; + + fpc1020 = dev_get_drvdata(dev); + + fpc_attr = container_of(attr, struct fpc1020_attribute, attr); + + if (fpc_attr->offset == offsetof(fpc1020_diag_t, chip_id)) { + return scnprintf(buf, + PAGE_SIZE, + "%s rev.%d\n", + fpc1020_hw_id_text(fpc1020), + fpc1020->chip.revision); + } + else if (fpc_attr->offset == offsetof(fpc1020_diag_t, selftest)) { + val = (u64)fpc1020_selftest_short(fpc1020); + } + + else if (fpc_attr->offset == offsetof(fpc1020_diag_t, spi_register)) { + val = (int)fpc1020->diag.spi_register; + } + + else if (fpc_attr->offset == offsetof(fpc1020_diag_t, spi_regsize)) { + val = (int)fpc1020->diag.spi_regsize; + } + + else if (fpc_attr->offset == offsetof(fpc1020_diag_t, spi_data)) { + + is_buffer = (fpc1020->diag.spi_regsize > sizeof(val)); + + if (!is_buffer) { + error = fpc1020_spi_debug_value_read(fpc1020, &val); + } else { + error = fpc1020_spi_debug_buffer_read(fpc1020, + u8_buffer, + sizeof(u8_buffer)); + } + } else if (fpc_attr->offset == offsetof(fpc1020_diag_t, last_capture_time)) { + val = (int)fpc1020->diag.last_capture_time; + } + else if (fpc_attr->offset == offsetof(fpc1020_diag_t, finger_present_status)) { + error = fpc1020_get_finger_present_status(fpc1020); + if (error >= 0) { + val = (int)error; + error = 0; + } + } + + if (error >= 0 && !is_buffer) { + return scnprintf(buf, + PAGE_SIZE, + "%lu\n", + (long unsigned int)val); + } + + if (error >= 0 && is_buffer) { + fpc1020_spi_debug_buffer_to_hex_string(hex_string, + u8_buffer, + fpc1020->diag.spi_regsize); + + return scnprintf(buf, PAGE_SIZE, "%s\n", hex_string); + } + + //return -ENOTTY; + return error; +} + + +/* -------------------------------------------------------------------- */ +static ssize_t fpc1020_store_attr_diag(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + fpc1020_data_t *fpc1020 = dev_get_drvdata(dev); + u64 val; + int error = 0; + + struct fpc1020_attribute *fpc_attr; + fpc_attr = container_of(attr, struct fpc1020_attribute, attr); + + if (fpc_attr->offset == offsetof(fpc1020_diag_t, spi_register)) { + error = kstrtou64(buf, 0, &val); + + if (!error) { + error = fpc1020_spi_debug_select(fpc1020, + (fpc1020_reg_t)val); + } + } else if (fpc_attr->offset == offsetof(fpc1020_diag_t, spi_data)) { + + if (fpc1020->diag.spi_regsize <= sizeof(val)) { + error = kstrtou64(buf, 0, &val); + + if (!error) + error = fpc1020_spi_debug_value_write(fpc1020, + val); + } else { + error = fpc1020_spi_debug_buffer_write(fpc1020, + buf, + count); + } + } else + error = -EPERM; + + return (error < 0) ? error : strnlen(buf, count); +} + + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config +/* -------------------------------------------------------------------- */ +int compare(const void *a, const void *b) +{ + int c = (int)(*(u8 *)a); + int d = (int)(*(u8 *)b); + + if(c < d) return -1; //-1: a < b + else if (c == d) return 0; // 0: a == b + else return 1; // 1: a > b +} + + +/* -------------------------------------------------------------------- */ +#define CB_TYPE1_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT 240 +#define CB_TYPE1_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT 160 + +#define CB_TYPE2_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT 140 +#define CB_TYPE2_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT 50 + +#define ICB_TYPE1_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT 210 +#define ICB_TYPE1_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT 130 + +#define ICB_TYPE2_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT 80 +#define ICB_TYPE2_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT 0 + +#define FPC102X_DEADPIXEL_THRESHOLD 60 + +static int fpc1020_check_for_deadPixels(fpc1020_data_t *fpc1020, u8* ripPixels, bool bCB) +{ + int deadpixels = 0; + int x = 0, y = 0; + int i1 = 0, i2 = 0; + u8 *buff = fpc1020->huge_buffer; + int pixel_columns = fpc1020->chip.pixel_columns; + int pixel_rows = fpc1020->chip.pixel_rows; + int buffersize = pixel_columns * pixel_rows; + bool odd; + int maxDev = 0; + int dev1 = 0, dev2 = 0; + int m1 = 0, m2 = 0; + + int config_max_deviation = 25; + int config_min_checker_diff = 60; + //int config_max_dead_pixels = 11; + int config_max_dead_pixels_to_list = 11; + + int sum1 = 0; + int sum2 = 0; + int i = 0; + + u8 *p1 = (u8 *)kmalloc(sizeof(u8)*(buffersize/2), GFP_KERNEL); + u8 *p2 = (u8 *)kmalloc(sizeof(u8)*(buffersize/2), GFP_KERNEL); + memset(p1, 0, (buffersize/2)); + memset(p2, 0, (buffersize/2)); + + + //for (i = 0; i < FPC1020_FRAME_SIZE_MAX; i += 8) + // printk("%s: %2x %2x %2x %2x %2x %2x %2x %x\n", __func__, + // buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7]); + + for (y = 0; y < pixel_rows; y++) { + for (x = 0; x < pixel_columns; x += 2) { + odd = (y % 2) != 0; + i1 = y * pixel_columns + x + ((odd) ? 1 : 0); + i2 = y * pixel_columns + x + ((odd) ? 0 : 1); + sum1 += buff[i1]; + sum2 += buff[i2]; + + p1[i] = buff[i1]; + p2[i] = buff[i2]; + i++; + } + } + + sum1 /= (buffersize / 2); + sum2 /= (buffersize / 2); + + sort((void *)p1, buffersize/2, sizeof(u8), &compare, NULL); + sort((void *)p2, buffersize/2, sizeof(u8), &compare, NULL); + + m1 = ((int)p1[buffersize/4-1] + (int)p1[buffersize/4])/2; + m2 = ((int)p2[buffersize/4-1] + (int)p2[buffersize/4])/2; + + kfree(p1); + kfree(p2); + + dev_info(&fpc1020->spi->dev, + "%s: Average (median) pixel values = %d (%d) and %d (%d)\n", __func__, sum1, m1, sum2, m2); + + if (bCB) { + if (m1 < CB_TYPE1_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT || + m1 > CB_TYPE1_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT) { + dev_err(&fpc1020->spi->dev, "Type1 median is out of bound\n"); + return 1; + } + + if (m2 < CB_TYPE2_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT || + m2 > CB_TYPE2_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT) { + dev_err(&fpc1020->spi->dev, "Type2 median is out of bound\n"); + return 1; + } + + } else { + + // Here m2 = median of type1 pattern, m1 = median of type2 pattern + if (m2 < ICB_TYPE1_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT || + m2 > ICB_TYPE1_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT) { + dev_err(&fpc1020->spi->dev, "Type1 median is out of bound\n"); + return 1; + } + + if (m1 < ICB_TYPE2_MEDIAN_BOUNDARY_VALUE_LOWER_LIMIT || + m1 > ICB_TYPE2_MEDIAN_BOUNDARY_VALUE_UPPER_LIMIT) { + dev_err(&fpc1020->spi->dev, "Type2 median is out of bound\n"); + return 1; + } + } + + if (abs(sum1 - sum2) < config_min_checker_diff) { + dev_err(&fpc1020->spi->dev, "%s: Too small differance between white and black\n", __func__); + return 1; + } + + + for (y = 0; y < pixel_rows; y++) { + for (x = 0; x < pixel_columns; x += 2) { + odd = (y % 2) != 0; + i1 = y * pixel_columns + x + ((odd) ? 1 : 0); + i2 = y * pixel_columns + x + ((odd) ? 0 : 1); + + dev1 = abs(sum1 - (int)buff[i1]); + dev2 = abs(sum2 - (int)buff[i2]); + + if (dev1 > maxDev) maxDev = dev1; + if (dev2 > maxDev) maxDev = dev2; + + if (dev1 > config_max_deviation) { + if (deadpixels < config_max_dead_pixels_to_list) { + dev_err(&fpc1020->spi->dev, + "%s: Dead pixel found @ ImgXY[%d, %d]\n", __func__, (x + ((odd) ? 1 : 0)), y); + } + ripPixels[i1] = 1; + deadpixels++; + } + if (dev2 > config_max_deviation) { + if (deadpixels < config_max_dead_pixels_to_list) { + dev_err(&fpc1020->spi->dev, + "%s: Dead pixel found @ imgXY[%d, %d]\n", __func__, (x + ((odd) ? 0 : 1)), y); + } + ripPixels[i2] = 1; + deadpixels++; + } + } + } + + if (deadpixels > config_max_dead_pixels_to_list) { + dev_err(&fpc1020->spi->dev, + "%s: More dead pixels found... Not listing all, deadpixel num =%d .n", __func__,deadpixels); + //return deadpixels; + } + + if (deadpixels == 0) { + printk("%s: Found no dead pixels, highest deviation = %d\n", __func__, maxDev); + } + + return deadpixels > FPC102X_DEADPIXEL_THRESHOLD ? 1 : 0; +} + + +/* -------------------------------------------------------------------- */ +static int CheckDeadPixelInDetectZone(fpc1020_data_t *fpc1020, int index) +{ + int xpos = 0, ypos = 0; + int xp_1020[] = { 16, 64, 120, 168 }, yp_1020[] = { 28, 92, 156 }; + int xp_1021[] = { 16, 56, 88, 128 }, yp_1021[] = { 20, 76, 132 }; + int error = -1; + + int* xp; + int* yp; + int x = 0, y = 0; + + if (fpc1020->chip.type == FPC1020_CHIP_1021A) { + + ypos = index / 192; + xpos = index % 192; + xp = xp_1020; + yp = yp_1020; + + } else if (fpc1020->chip.type == FPC1020_CHIP_1021A || + fpc1020->chip.type == FPC1020_CHIP_1021B) { + + ypos = index / 160; + xpos = index % 160; + xp = xp_1021; + yp = yp_1021; + + } else { + + return 0; + + } + + + for (x = 0; x < 4; x++) { + for (y = 0; y < 3; y++) { + if (xpos >= xp[x] && xpos <= (xp[x] + 8) && + ypos >= yp[y] && ypos <= (yp[y] + 8)) { + return error; + } + } + } + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_test_deadpixels(fpc1020_data_t *fpc1020) +{ + int error = 0; + u8* ripPixels = NULL; + int pixel_columns = fpc1020->chip.pixel_columns; + int pixel_rows = fpc1020->chip.pixel_rows; + int buffersize = pixel_columns * pixel_rows; + int i = 0; + + // Checkerboard Test + fpc1020->setup.capture_mode = FPC1020_MODE_CHECKERBOARD_TEST_NORM; + error = fpc1020_start_capture(fpc1020); + if (error) + goto out; + + error = wait_event_interruptible( + fpc1020->capture.wq_data_avail, + (fpc1020->capture.available_bytes > 0)); + + if (error) + goto out; + + if (fpc1020->capture.last_error != 0) { + error = fpc1020->capture.last_error; + goto out; + } + + ripPixels = (u8 *)kmalloc(sizeof(u8)*buffersize, GFP_KERNEL); + memset(ripPixels, 0, buffersize); + + error = fpc1020_check_for_deadPixels(fpc1020, ripPixels, true); + if (error) + goto out; + + for (i = 0; i < buffersize; i++) { + if (ripPixels[i] != 0) { + if ((error = CheckDeadPixelInDetectZone(fpc1020, i))) { + // At least one pixel is in the not-allowed finger detect zone + dev_err(&fpc1020->spi->dev, "Dead pixel found in finger detect zone\n"); + goto out; + } + } + } + + // INV Checkerboard Test + fpc1020->setup.capture_mode = FPC1020_MODE_CHECKERBOARD_TEST_INV; + error = fpc1020_start_capture(fpc1020); + if (error) + goto out; + + error = wait_event_interruptible( + fpc1020->capture.wq_data_avail, + (fpc1020->capture.available_bytes > 0)); + + if (error) + goto out; + + if (fpc1020->capture.last_error != 0) { + error = fpc1020->capture.last_error; + goto out; + } + + memset(ripPixels, 0, buffersize); + + error = fpc1020_check_for_deadPixels(fpc1020, ripPixels, false); + if (error) + goto out; + + for (i = 0; i < buffersize; i++) { + if (ripPixels[i] != 0) { + if ((error = CheckDeadPixelInDetectZone(fpc1020, i))) { + // At least one pixel is in the not-allowed finger detect zone + dev_err(&fpc1020->spi->dev, "Dead pixel found in finger detect zone\n"); + goto out; + } + } + } + +out: + kfree(ripPixels); + //up(&fpc1020->mutex); + if (!error) + dev_info(&fpc1020->spi->dev, "%s: PASS\n", __func__); + + return error; +} + + +#endif /* VENDOR_EDIT */ + +/* -------------------------------------------------------------------- */ +static u8 fpc1020_selftest_short(fpc1020_data_t *fpc1020) +{ + const char *id_str = "selftest,"; + int error = 0; + +#ifdef CONFIG_INPUT_FPC1020_NAV + bool resume_nav = false; + if(fpc1020->nav.enabled) { + resume_nav = true; + fpc1020_worker_goto_idle(fpc1020); + } +#endif + fpc1020->diag.selftest = 0; + + error = fpc1020_wake_up(fpc1020); + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s wake up fail on entry.\n", id_str); + goto out; + } + + error = fpc1020_reset(fpc1020); + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s reset fail on entry.\n", id_str); + goto out; + } + + error = fpc1020_check_hw_id(fpc1020); + + if (error) + goto out; + + error = fpc1020_cmd(fpc1020, FPC1020_CMD_CAPTURE_IMAGE, false); + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s capture command failed.\n", id_str); + goto out; + } + + error = gpio_get_value(fpc1020->irq_gpio) ? 0 : -EIO; + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s IRQ not HIGH after capture.\n", id_str); + goto out; + } + + error = fpc1020_wait_for_irq(fpc1020, FPC1020_DEFAULT_IRQ_TIMEOUT_MS); + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s IRQ-wait after capture failed.\n", id_str); + goto out; + } + + error = fpc1020_read_irq(fpc1020, true); + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s IRQ clear fail\n", id_str); + goto out; + } else + error = 0; + + error = (gpio_get_value(fpc1020->irq_gpio) == 0) ? 0 : -EIO; + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s IRQ not LOW after clear.\n", id_str); + goto out; + } + + error = fpc1020_reset(fpc1020); + + if (error) { + dev_err(&fpc1020->spi->dev, + "%s reset fail on exit.\n", id_str); + goto out; + } + + error = fpc1020_read_status_reg(fpc1020); + + if (error != FPC1020_STATUS_REG_RESET_VALUE) { + dev_err(&fpc1020->spi->dev, + "%s status check fail on exit.\n", id_str); + goto out; + } + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw Config + error = fpc1020_test_deadpixels(fpc1020); + if (error){ + dev_err(&fpc1020->spi->dev, + "%s fpc1020_test_deadpixels failed.\n", id_str); + goto out; + } +#endif /* VENDOR_EDIT */ + + error = 0; + +out: + fpc1020->diag.selftest = (error == 0) ? 1 : 0; + + dev_info(&fpc1020->spi->dev, "%s %s\n", id_str, + (fpc1020->diag.selftest) ? "PASS" : "FAIL"); + +#ifdef CONFIG_INPUT_FPC1020_NAV + if (resume_nav && fpc1020->diag.selftest) + fpc1020_start_navigation(fpc1020); +#endif + + return fpc1020->diag.selftest; +}; + + +/* -------------------------------------------------------------------- */ +static int fpc1020_start_capture(fpc1020_data_t *fpc1020) +{ + fpc1020_capture_mode_t mode = fpc1020->setup.capture_mode; + int error = 0; + + dev_dbg(&fpc1020->spi->dev, "%s mode= %d\n", __func__, mode); + + /* Mode check (and pre-conditions if required) ? */ + switch (mode) { + case FPC1020_MODE_WAIT_AND_CAPTURE: + case FPC1020_MODE_SINGLE_CAPTURE: + case FPC1020_MODE_CHECKERBOARD_TEST_NORM: + case FPC1020_MODE_CHECKERBOARD_TEST_INV: + case FPC1020_MODE_BOARD_TEST_ONE: + case FPC1020_MODE_BOARD_TEST_ZERO: + case FPC1020_MODE_WAIT_FINGER_DOWN: + case FPC1020_MODE_WAIT_FINGER_UP: + case FPC1020_MODE_SINGLE_CAPTURE_CAL: + case FPC1020_MODE_CAPTURE_AND_WAIT_FINGER_UP: + break; + + case FPC1020_MODE_IDLE: + default: + error = -EINVAL; + break; + } + + fpc1020->capture.current_mode = (error >= 0) ? mode : FPC1020_MODE_IDLE; + + fpc1020->capture.state = FPC1020_CAPTURE_STATE_STARTED; + fpc1020->capture.available_bytes = 0; + fpc1020->capture.read_offset = 0; + fpc1020->capture.read_pending_eof = false; + + fpc1020_new_job(fpc1020, FPC1020_WORKER_CAPTURE_MODE); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_worker_goto_idle(fpc1020_data_t *fpc1020) +{ + const int wait_idle_us = 100; + + if (down_trylock(&fpc1020->worker.sem_idle)) { + dev_dbg(&fpc1020->spi->dev, "%s, stop_request\n", __func__); + + fpc1020->worker.stop_request = true; + fpc1020->worker.req_mode = FPC1020_WORKER_IDLE_MODE; + + while (down_trylock(&fpc1020->worker.sem_idle)) { + + fpc1020->worker.stop_request = true; + fpc1020->worker.req_mode = FPC1020_WORKER_IDLE_MODE; + + usleep(wait_idle_us); + } + dev_dbg(&fpc1020->spi->dev, "%s, is idle\n", __func__); + up(&fpc1020->worker.sem_idle); + + } else { + dev_dbg(&fpc1020->spi->dev, "%s, already idle\n", __func__); + up(&fpc1020->worker.sem_idle); + } + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_new_job(fpc1020_data_t *fpc1020, int new_job) +{ + //dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, new_job); + + fpc1020_worker_goto_idle(fpc1020); + + fpc1020->worker.req_mode = new_job; + fpc1020->worker.stop_request = false; + + wake_up_interruptible(&fpc1020->worker.wq_wait_job); + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_worker_function(void *_fpc1020) +{ + fpc1020_data_t *fpc1020 = _fpc1020; + + while (!kthread_should_stop()) { +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-10-23 Add for workaround method for navigation invalid + int retry = 5; +#endif /* VENDOR_EDIT */ + + up(&fpc1020->worker.sem_idle); + + wait_event_interruptible(fpc1020->worker.wq_wait_job, + fpc1020->worker.req_mode != FPC1020_WORKER_IDLE_MODE); + + down(&fpc1020->worker.sem_idle); +//#ifndef VENDOR_EDIT //changhua.li uncomment to implement home key + switch (fpc1020->worker.req_mode) { + case FPC1020_WORKER_CAPTURE_MODE: + fpc1020->capture.state = FPC1020_CAPTURE_STATE_PENDING; + fpc1020_capture_task(fpc1020); + break; + +#ifdef CONFIG_INPUT_FPC1020_NAV + case FPC1020_WORKER_INPUT_MODE: + if (fpc1020_capture_deferred_task(fpc1020) != -EINTR) { +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-28 Remove for navigation switch + fpc1020_input_enable(fpc1020, true); + fpc1020_input_task(fpc1020); +#else + //Lycan.Wang Workaround method for navigation invalid + while ((fpc1020_input_task(fpc1020) == -EIO) && retry--) { + dev_dbg(&fpc1020->spi->dev, "fpc1020_input_task failed ! Try again !(%d)\n", retry); + } +#endif + + } + break; +#endif + + case FPC1020_WORKER_IDLE_MODE: + case FPC1020_WORKER_EXIT: + default: + break; + } + +//#endif /* VENDOR_EDIT */ + + if (fpc1020->worker.req_mode != FPC1020_WORKER_EXIT) + fpc1020->worker.req_mode = FPC1020_WORKER_IDLE_MODE; + } + + return 0; +} + + +/* -------------------------------------------------------------------- */ +/* SPI debug interface, implementation */ +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_select(fpc1020_data_t *fpc1020, fpc1020_reg_t reg) +{ + u8 size = FPC1020_REG_SIZE(reg); + + if (size) { + fpc1020->diag.spi_register = reg; + fpc1020->diag.spi_regsize = size; + + dev_dbg(&fpc1020->spi->dev, "%s : selected %d (%d byte(s))\n", + __func__ + , fpc1020->diag.spi_register + , fpc1020->diag.spi_regsize); + return 0; + } else { + dev_dbg(&fpc1020->spi->dev, + "%s : reg %d not available\n", __func__, reg); + + return -ENOENT; + } +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_value_write(fpc1020_data_t *fpc1020, u64 data) +{ + int error = 0; + fpc1020_reg_access_t reg; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + FPC1020_MK_REG_WRITE_BYTES(reg, + fpc1020->diag.spi_register, + fpc1020->diag.spi_regsize, + (u8 *)&data); + + error = fpc1020_reg_access(fpc1020, ®); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_buffer_write(fpc1020_data_t *fpc1020, + const char *data, size_t count) +{ + int error = 0; + fpc1020_reg_access_t reg; + u8 u8_buffer[FPC1020_REG_MAX_SIZE]; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_spi_debug_hex_string_to_buffer(u8_buffer, + sizeof(u8_buffer), + data, + count); + + if (error < 0) + return error; + + FPC1020_MK_REG_WRITE_BYTES(reg, + fpc1020->diag.spi_register, + fpc1020->diag.spi_regsize, + u8_buffer); + + error = fpc1020_reg_access(fpc1020, ®); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_value_read(fpc1020_data_t *fpc1020, u64 *data) +{ + int error = 0; + fpc1020_reg_access_t reg; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + *data = 0; + + FPC1020_MK_REG_READ_BYTES(reg, + fpc1020->diag.spi_register, + fpc1020->diag.spi_regsize, + (u8 *)data); + + error = fpc1020_reg_access(fpc1020, ®); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_buffer_read(fpc1020_data_t *fpc1020, + u8 *data, size_t max_count) +{ + int error = 0; + fpc1020_reg_access_t reg; + + if (max_count < fpc1020->diag.spi_regsize) + return -ENOMEM; + + FPC1020_MK_REG_READ_BYTES(reg, + fpc1020->diag.spi_register, + fpc1020->diag.spi_regsize, + data); + + error = fpc1020_reg_access(fpc1020, ®); + + return error; +} + + +/* -------------------------------------------------------------------- */ +static void fpc1020_spi_debug_buffer_to_hex_string(char *string, + u8 *buffer, + size_t bytes) +{ + int count = bytes; + int pos = 0; + int src = (target_little_endian) ? (bytes - 1) : 0; + u8 v1, v2; + + string[pos++] = '0'; + string[pos++] = 'x'; + + while (count) { + v1 = buffer[src] >> 4; + v2 = buffer[src] & 0x0f; + + string[pos++] = (v1 >= 0x0a) ? ('a' - 0x0a + v1) : ('0' + v1); + string[pos++] = (v2 >= 0x0a) ? ('a' - 0x0a + v2) : ('0' + v2); + + src += (target_little_endian) ? -1 : 1; + + count--; + } + + string[pos] = '\0'; +} + + +/* -------------------------------------------------------------------- */ +static u8 fpc1020_char_to_u8(char in_char) +{ + if ((in_char >= 'A') && (in_char <= 'F')) + return (u8)(in_char - 'A' + 0xa); + + if ((in_char >= 'a') && (in_char <= 'f')) + return (u8)(in_char - 'a' + 0xa); + + if ((in_char >= '0') && (in_char <= '9')) + return (u8)(in_char - '0'); + + return 0; +} + + +/* -------------------------------------------------------------------- */ +static int fpc1020_spi_debug_hex_string_to_buffer(u8 *buffer, + size_t buf_size, + const char *string, + size_t chars) +{ + int bytes = 0; + int count; + int dst = (target_little_endian) ? 0 : (buf_size - 1); + int pos; + u8 v1, v2; + + if (string[1] != 'x' && string[1] != 'X') + return -EINVAL; + + if (string[0] != '0') + return -EINVAL; + + if (chars < sizeof("0x1")) + return -EINVAL; + + count = buf_size; + while (count) + buffer[--count] = 0; + + count = chars - sizeof("0x"); + + bytes = ((count % 2) == 0) ? (count / 2) : (count / 2) + 1; + + if (bytes > buf_size) + return -EINVAL; + + pos = chars - 2; + + while (pos >= 2) { + v1 = fpc1020_char_to_u8(string[pos--]); + v2 = (pos >= 2) ? fpc1020_char_to_u8(string[pos--]) : 0; + + buffer[dst] = (v2 << 4) | v1; + + dst += (target_little_endian) ? 1 : -1; + } + return bytes; +} + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +static int fpc1020_start_navigation(fpc1020_data_t *fpc1020) +{ + return fpc1020_new_job(fpc1020, FPC1020_WORKER_INPUT_MODE); +} +#endif + + +/* -------------------------------------------------------------------- */ + + diff --git a/drivers/input/misc/fpc1020_nav.c b/drivers/input/misc/fpc1020_nav.c new file mode 100755 index 0000000000000..a07d9d26201bb --- /dev/null +++ b/drivers/input/misc/fpc1020_nav.c @@ -0,0 +1,1313 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#define DEBUG + +#include +#include +#include + +#include + +#ifndef CONFIG_OF +#include +#include +#include +#else +#include "fpc1020_common.h" +#include "fpc1020_input.h" +#include "fpc1020_capture.h" +#endif + + +/* -------------------------------------------------------------------- */ +/* function prototypes */ +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#ifndef AS_HOME_KEY +static int fpc1020_write_nav_setup(fpc1020_data_t *fpc1020); + +//static int fpc1020_wait_finger_present_lpm(fpc1020_data_t *fpc1020); + +static int capture_nav_image(fpc1020_data_t *fpc1020); +#endif + +#endif + + +/* -------------------------------------------------------------------- */ +/* driver constants */ +/* -------------------------------------------------------------------- */ +#define FPC1020_KEY_FINGER_PRESENT KEY_F18 /* 188*/ + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for report touch down or up +#define FPC1020_KEY_FINGER_TOUCH KEY_F19 /* 189*/ +#define FPC1020_KEY_MOVE_FORWARD KEY_F20 /* 190*/ +#define FPC1020_KEY_MOVE_BACKWARD KEY_F21 /* 191*/ +#define FPC1020_KEY_ROTATE_FORWARD KEY_F22 /* 192*/ +#define FPC1020_KEY_ROTATE_BACKWARD KEY_F23 /* 192*/ + +#ifdef AS_HOME_KEY +#define FPC1020_KEY_FINGER_PRESS KEY_HOME /* 102*/ +#define FPC1020_KEY_FINGER_DOUBLE_TAB KEY_F18 /* 188*/ +#define FPC1020_KEY_FINGER_LONG_PRESS KEY_F19 /* 189*/ +#define LONG_PRESS_TIME_IN_SEC 2 //not use ,only report down&up,long press by phonewindowmanager.java like other key +#define DOUBLE_TAB_INTERVAL_IN_MS 100 + +#include + +#endif + +#endif /* VENDOR_EDIT */ + +#define FPC1020_INPUT_POLL_TIME_MS 1000u + +#define FPC1020_HW_DETECT_MASK 0x6f6 + +#define FPC1020_INPUT_POLL_INTERVAL 5000 +#define FLOAT_MAX 100 + +#define DEVICE_WIDTH 720 +#define DEVICE_HEIGHT 1280 + +#define IMAGE_PADDING 24 +#define BEST_IMAGE_WIDTH 4 +#define BEST_IMAGE_HEIGHT 6 + +enum { + FNGR_ST_NONE = 0, + FNGR_ST_DETECTED, + FNGR_ST_LOST, + FNGR_ST_TAP, + FNGR_ST_HOLD, + FNGR_ST_MOVING, + FNGR_ST_L_HOLD, + FNGR_ST_DOUBLE_TAP, +}; + +enum { + FPC1020_INPUTMODE_TRACKPAD = 0, //trackpad(navi) event report + FPC1020_INPUTMODE_MOUSE = 1, //mouse event report + FPC1020_INPUTMODE_TOUCH = 2, //touch event report +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for navigation move event + FPC1020_INPUTMODE_MOVE = 3, //move event report +#endif /* VENDOR_EDIT */ +}; + +/* -------------------------------------------------------------------- */ +/* function definitions */ +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#ifndef AS_HOME_KEY +/* -------------------------------------------------------------------- */ +static int getSliceDiff(unsigned char* a, unsigned char* b, unsigned int columns, unsigned int rows) +{ + int diff = 0; + int x; + int y; + int i; + + for (y = 0; y < rows; y++) { + for (x = 0; x < columns; x++) { + i = x + y * NAV_IMAGE_WIDTH; + diff += abs(a[i] - b[i]); + } + } + return diff; +} + + +/* -------------------------------------------------------------------- */ +static void get_movement(unsigned char* prev, unsigned char* cur, int* mx, int* my) +{ + int compare_width = NAV_IMAGE_WIDTH - 2 * IMAGE_PADDING; + int diff = 0; + int min_diff = 255 * 40; + int x; + int y; + + int cr1 = 0; + int cr2 = 0; + const int THRESHOLD_CR = 1400; + + *mx = 0; + *my = 0; + for(y = 0 ; y < BEST_IMAGE_HEIGHT ; y++) { + for(x = -BEST_IMAGE_WIDTH ; x <= BEST_IMAGE_WIDTH; x++) { + diff = getSliceDiff(prev + IMAGE_PADDING, cur + IMAGE_PADDING + x + y*NAV_IMAGE_WIDTH, compare_width, NAV_IMAGE_HEIGHT - BEST_IMAGE_HEIGHT); + if(diff < min_diff) { + min_diff = diff; + *mx = x; + *my = y; + } + + if (x == 0 && y == 0) + cr1 = diff; + + diff = getSliceDiff(cur + IMAGE_PADDING, prev + IMAGE_PADDING + x + y*NAV_IMAGE_WIDTH, compare_width, NAV_IMAGE_HEIGHT - BEST_IMAGE_HEIGHT); + if(diff < min_diff) { + min_diff = diff; + *mx = -x; + *my = -y; + } + + if (x == 0 && y == 0) + cr2 = diff; + } + } + + if (*mx || *my) { + //defensing 'division by zero' case. + if(min_diff != 0) { + if (max(cr1, cr2) * 1000 / min_diff < THRESHOLD_CR) { + *mx = 0; + *my = 0; + } + } + } +} + + +/* -------------------------------------------------------------------- */ +void init_enhanced_navi_setting(fpc1020_data_t *fpc1020) +{ + dev_info(&fpc1020->spi->dev, "%s\n", __func__); + switch(fpc1020->nav.input_mode) { + case FPC1020_INPUTMODE_TRACKPAD: + fpc1020->nav.p_sensitivity_key = 25; + fpc1020->nav.p_sensitivity_ptr = 180; + fpc1020->nav.p_multiplier_x = 75; + fpc1020->nav.p_multiplier_y = 95; + fpc1020->nav.multiplier_key_accel = 2; + fpc1020->nav.multiplier_ptr_accel = 2; + fpc1020->nav.threshold_key_accel = 70; + fpc1020->nav.threshold_ptr_accel = 10; + fpc1020->nav.threshold_ptr_start = 5; + fpc1020->nav.duration_ptr_clear = 100; + fpc1020->nav.nav_finger_up_threshold = 3; + break; +/* case BTP_INPUTMODE_MOUSE: + fpc1020->nav.p_sensitivity_key = 180; + fpc1020->nav.p_sensitivity_ptr = 170;//180; + fpc1020->nav.p_multiplier_x = 150;//110; + fpc1020->nav.p_multiplier_y = 100;//110; + fpc1020->nav.multiplier_key_accel = 1; + fpc1020->nav.multiplier_ptr_accel = 2; + fpc1020->nav.threshold_key_accel = 40; + fpc1020->nav.threshold_ptr_accel = 30;//20; + fpc1020->nav.threshold_ptr_start = 2;//5; + fpc1020->nav.duration_ptr_clear = 100; + fpc1020->nav.nav_finger_up_threshold = 3; + break;*/ + case FPC1020_INPUTMODE_TOUCH: + fpc1020->nav.p_sensitivity_key = 200;//180; + fpc1020->nav.p_sensitivity_ptr = 180; + fpc1020->nav.p_multiplier_x = 255;//110; + fpc1020->nav.p_multiplier_y = 110; + fpc1020->nav.multiplier_key_accel = 1; + fpc1020->nav.multiplier_ptr_accel = 2; + fpc1020->nav.threshold_key_accel = 40; + fpc1020->nav.threshold_ptr_accel = 20; + fpc1020->nav.threshold_ptr_start = 5; + fpc1020->nav.duration_ptr_clear = 100; + fpc1020->nav.nav_finger_up_threshold = 3; + break; +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for navigation move event + case FPC1020_INPUTMODE_MOVE: + fpc1020->nav.p_sensitivity_key = 200;//180; + fpc1020->nav.p_sensitivity_ptr = 180; + fpc1020->nav.p_multiplier_x = 255;//110; + fpc1020->nav.p_multiplier_y = 110; + fpc1020->nav.multiplier_key_accel = 1; + fpc1020->nav.multiplier_ptr_accel = 2; + fpc1020->nav.threshold_key_accel = 40; + fpc1020->nav.threshold_ptr_accel = 20; + fpc1020->nav.threshold_ptr_start = 5; + fpc1020->nav.duration_ptr_clear = 100; + fpc1020->nav.nav_finger_up_threshold = 3; + fpc1020->nav.move_time_threshold = 200; + fpc1020->nav.move_distance_threshold = 50; + break; +#endif /* VENDOR_EDIT */ + default: + break; + } +} + + +/* -------------------------------------------------------------------- */ +static void dispatch_trackpad_event(fpc1020_data_t *fpc1020, int x, int y, int finger_status) +{ + int abs_x, abs_y; + int sign_x, sign_y; + + if (finger_status == FNGR_ST_TAP) { + input_report_key(fpc1020->input_dev, KEY_ENTER, 1); + input_sync(fpc1020->input_dev); + input_report_key(fpc1020->input_dev, KEY_ENTER, 0); + input_sync(fpc1020->input_dev); + return; + } + + sign_x = x > 0 ? 1 : -1; + sign_y = y > 0 ? 1 : -1; + abs_x = x * sign_x; + abs_y = y * sign_y; + + abs_x = x > 0 ? x : -x; + abs_y = y > 0 ? y : -y; + + if (abs_x > fpc1020->nav.threshold_key_accel) + x = ( fpc1020->nav.threshold_key_accel + ( abs_x - fpc1020->nav.threshold_key_accel ) * fpc1020->nav.multiplier_key_accel ) * sign_x; + if (abs_y > fpc1020->nav.threshold_key_accel) + y = ( fpc1020->nav.threshold_key_accel + ( abs_y - fpc1020->nav.threshold_key_accel ) * fpc1020->nav.multiplier_key_accel ) * sign_y; + + // Correct axis factor + x = x * fpc1020->nav.p_multiplier_x / FLOAT_MAX; + y = y * fpc1020->nav.p_multiplier_y / FLOAT_MAX; + + // Adjust Sensitivity + x = x * fpc1020->nav.p_sensitivity_key / FLOAT_MAX; + y = y * fpc1020->nav.p_sensitivity_key / FLOAT_MAX; + + input_report_rel(fpc1020->input_dev, REL_X, x); + input_report_rel(fpc1020->input_dev, REL_Y, y); + + input_sync(fpc1020->input_dev); +} + + +/* -------------------------------------------------------------------- */ +static void dispatch_touch_event(fpc1020_data_t *fpc1020, int x, int y, int finger_status) +{ + int sign_x, sign_y; + int abs_x, abs_y; + + switch(finger_status) { + case FNGR_ST_DETECTED: + fpc1020->nav.nav_sum_x = 360; + fpc1020->nav.nav_sum_y = 640; + input_report_abs(fpc1020->touch_pad_dev, ABS_X, fpc1020->nav.nav_sum_x); + input_report_abs(fpc1020->touch_pad_dev, ABS_Y, fpc1020->nav.nav_sum_y); + input_report_abs(fpc1020->touch_pad_dev, ABS_Z, 0); + input_report_key(fpc1020->touch_pad_dev, BTN_TOUCH, 1); + input_sync(fpc1020->touch_pad_dev); + break; + + case FNGR_ST_LOST: + // case FNGR_ST_TAP: + input_report_abs(fpc1020->touch_pad_dev, ABS_X, fpc1020->nav.nav_sum_x); + input_report_abs(fpc1020->touch_pad_dev, ABS_Y, fpc1020->nav.nav_sum_y); + input_report_abs(fpc1020->touch_pad_dev, ABS_Z, 0); + input_report_key(fpc1020->touch_pad_dev, BTN_TOUCH, 0); + input_sync(fpc1020->touch_pad_dev); + break; + + case FNGR_ST_MOVING: + sign_x = x > 0 ? 1 : -1; + sign_y = y > 0 ? 1 : -1; //reverse direction + abs_x = x > 0 ? x : -x; + abs_y = y > 0 ? y : -y; + + if (abs_x > fpc1020->nav.threshold_key_accel) + x = ( fpc1020->nav.threshold_key_accel + ( abs_x - fpc1020->nav.threshold_key_accel ) * fpc1020->nav.multiplier_key_accel ) * sign_x; + if (abs_y > fpc1020->nav.threshold_key_accel) + y = ( fpc1020->nav.threshold_key_accel + ( abs_y - fpc1020->nav.threshold_key_accel ) * fpc1020->nav.multiplier_key_accel ) * sign_y; + + x = x * fpc1020->nav.p_multiplier_x / FLOAT_MAX; + y = y * fpc1020->nav.p_multiplier_y / FLOAT_MAX; + + x = x * fpc1020->nav.p_sensitivity_key / FLOAT_MAX; + y = y * fpc1020->nav.p_sensitivity_key / FLOAT_MAX; + + if(x != 0 || y != 0) { + if(abs(x) > abs(y)) { + int newX = fpc1020->nav.nav_sum_x; + //newX += x; + if(newX < 0) { + newX = 0; + } else if(newX >= DEVICE_WIDTH) { + newX = DEVICE_WIDTH -1; + } + + if(newX != fpc1020->nav.nav_sum_x) { + //fpc1020->nav.nav_sum_x = newX; + input_report_abs(fpc1020->touch_pad_dev, ABS_X, fpc1020->nav.nav_sum_x); + input_report_abs(fpc1020->touch_pad_dev, ABS_Y, fpc1020->nav.nav_sum_y); + input_report_abs(fpc1020->touch_pad_dev, ABS_Z, 0); + input_report_key(fpc1020->touch_pad_dev, BTN_TOUCH, 1); + input_sync(fpc1020->touch_pad_dev); + } + } else { + int newY = fpc1020->nav.nav_sum_y; + newY -= y; + if(newY < 0) { + newY = 0; + } else if(newY >= DEVICE_HEIGHT) { + newY = DEVICE_HEIGHT -1; + } + + if(newY != fpc1020->nav.nav_sum_y) { + fpc1020->nav.nav_sum_y = newY; + + input_report_abs(fpc1020->touch_pad_dev, ABS_X, fpc1020->nav.nav_sum_x); + input_report_abs(fpc1020->touch_pad_dev, ABS_Y, fpc1020->nav.nav_sum_y); + input_report_abs(fpc1020->touch_pad_dev, ABS_Z, 0); + input_report_key(fpc1020->touch_pad_dev, BTN_TOUCH, 1); + input_sync(fpc1020->touch_pad_dev); + } + } + } + break; + + default: + break; + } +} + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for navigation move event +/* -------------------------------------------------------------------- */ +static void dispatch_move_event(fpc1020_data_t *fpc1020, int x, int y, int finger_status) +{ + int sign_y; + int abs_y; + int newY; + + switch(finger_status) { + case FNGR_ST_DETECTED: + fpc1020->nav.nav_sum_y = 640; + fpc1020->touch_time = jiffies; + fpc1020->move_distance = 0; + fpc1020->moving_key = 0; + break; + + case FNGR_ST_LOST: + printk("lycan test %d time %dms\n", fpc1020->move_distance, jiffies_to_msecs(jiffies - fpc1020->touch_time)); + if (fpc1020->moving_key) { + input_report_key(fpc1020->input_dev, fpc1020->moving_key, 0); + input_sync(fpc1020->input_dev); + } else if (abs(fpc1020->move_distance) > fpc1020->nav.move_distance_threshold && + jiffies_to_msecs(jiffies - fpc1020->touch_time) < fpc1020->nav.move_time_threshold) { + if (fpc1020->move_distance > 0) { + input_report_key(fpc1020->input_dev, FPC1020_KEY_ROTATE_FORWARD, 1); + input_sync(fpc1020->input_dev); + input_report_key(fpc1020->input_dev, FPC1020_KEY_ROTATE_FORWARD, 0); + input_sync(fpc1020->input_dev); + } else { + input_report_key(fpc1020->input_dev, FPC1020_KEY_ROTATE_BACKWARD, 1); + input_sync(fpc1020->input_dev); + input_report_key(fpc1020->input_dev, FPC1020_KEY_ROTATE_BACKWARD, 0); + input_sync(fpc1020->input_dev); + } + } else if (abs(fpc1020->move_distance) < fpc1020->nav.move_distance_threshold) { + input_report_key(fpc1020->input_dev, FPC1020_KEY_FINGER_TOUCH, 1); + input_sync(fpc1020->input_dev); + input_report_key(fpc1020->input_dev, FPC1020_KEY_FINGER_TOUCH, 0); + input_sync(fpc1020->input_dev); + } + break; + + case FNGR_ST_MOVING: + sign_y = y > 0 ? 1 : -1; //reverse direction + abs_y = y > 0 ? y : -y; + + if (abs_y > fpc1020->nav.threshold_key_accel) + y = ( fpc1020->nav.threshold_key_accel + ( abs_y - fpc1020->nav.threshold_key_accel ) * fpc1020->nav.multiplier_key_accel ) * sign_y; + + y = y * fpc1020->nav.p_multiplier_y / FLOAT_MAX; + y = y * fpc1020->nav.p_sensitivity_key / FLOAT_MAX; + + newY = fpc1020->nav.nav_sum_y - y; + + if(newY < 0) { + newY = 0; + } else if(newY >= DEVICE_HEIGHT) { + newY = DEVICE_HEIGHT -1; + } + + fpc1020->nav.nav_sum_y = newY; + if (jiffies_to_msecs(jiffies - fpc1020->touch_time) > fpc1020->nav.move_time_threshold) { + if (abs(fpc1020->move_distance) < abs(newY - 640)) + fpc1020->move_distance = newY - 640; + + if (!fpc1020->moving_key) { + if (abs(fpc1020->move_distance) > fpc1020->nav.move_distance_threshold) { + if (fpc1020->move_distance > 0) { + fpc1020->moving_key = FPC1020_KEY_MOVE_FORWARD; + } else { + fpc1020->moving_key = FPC1020_KEY_MOVE_BACKWARD; + } + input_report_key(fpc1020->input_dev, fpc1020->moving_key, 1); + input_sync(fpc1020->input_dev); + } + } + } + break; + + default: + break; + } +} +#endif /* VENDOR_EDIT */ + +/* -------------------------------------------------------------------- */ +static void process_navi_event(fpc1020_data_t *fpc1020, int dx, int dy, int finger_status) +{ + const int THRESHOLD_RANGE_TAP = 100; + //const unsigned long THRESHOLD_DURATION_TAP = 3000;//350; + int filtered_finger_status = finger_status; + static int deviation_x = 0; + static int deviation_y = 0; + int deviation; + static unsigned long tick_down = 0; + unsigned long tick_curr = jiffies * 1000 / HZ; + unsigned long duration = 0; + const unsigned long THRESHOLD_DURATION_HOLD = 900; + + if ( finger_status == FNGR_ST_DETECTED ) { + tick_down = tick_curr; + } + + if ( tick_down > 0 ) { + duration = tick_curr - tick_down; + deviation_x += dx; + deviation_y += dy; + deviation = deviation_x * deviation_x + deviation_y * deviation_y; + + if ( deviation > THRESHOLD_RANGE_TAP ) { + deviation_x = 0; + deviation_y = 0; + tick_down = 0; + fpc1020->nav.tap_status = -1; + } else if ( duration > THRESHOLD_DURATION_HOLD ) { + filtered_finger_status = FNGR_ST_HOLD; + tick_down = 0; + deviation_x = 0; + deviation_y = 0; + } + } + + //dev_info(&fpc1020->spi->dev, "[INFO] mode[%d] dx : %d / dy : %d\n", fpc1020->nav_settings.btp_input_mode, dx, dy); + + switch(fpc1020->nav.input_mode) { + case FPC1020_INPUTMODE_TRACKPAD : + dispatch_trackpad_event(fpc1020, -dx, dy, filtered_finger_status); + break; +// case BTP_INPUTMODE_MOUSE: +// dispatch_mouse_event( fpc_btp, -dx, dy, filtered_finger_status ); +// break; + case FPC1020_INPUTMODE_TOUCH: + dispatch_touch_event(fpc1020, dx, dy, filtered_finger_status); + break; +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-29 Add for navigation move event + case FPC1020_INPUTMODE_MOVE: + dispatch_move_event(fpc1020, dx, dy, filtered_finger_status); + break; +#endif /* VENDOR_EDIT */ + default: + break; + } +} +#endif +/* -------------------------------------------------------------------- */ +int /*__devinit*/ fpc1020_input_init(fpc1020_data_t *fpc1020) +{ + int error = 0; + + if ((fpc1020->chip.type != FPC1020_CHIP_1020A) + && (fpc1020->chip.type != FPC1020_CHIP_1021A) + && (fpc1020->chip.type != FPC1020_CHIP_1021B) + && (fpc1020->chip.type != FPC1020_CHIP_1150B) + && (fpc1020->chip.type != FPC1020_CHIP_1150F) + && (fpc1020->chip.type != FPC1020_CHIP_1150A)){ + dev_err(&fpc1020->spi->dev, "%s, chip not supported (%s)\n", + __func__, + fpc1020_hw_id_text(fpc1020)); + + return -EINVAL; + } + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + fpc1020->input_dev = input_allocate_device(); + + if (!fpc1020->input_dev) { + dev_err(&fpc1020->spi->dev, "Input_allocate_device failed.\n"); + error = -ENOMEM; + } + + if (!error) { + fpc1020->input_dev->name = FPC1020_DEV_NAME; + + /* Set event bits according to what events we are generating */ + set_bit(EV_KEY, fpc1020->input_dev->evbit); + set_bit(EV_REL, fpc1020->input_dev->evbit); + input_set_capability(fpc1020->input_dev, EV_REL, REL_X); + input_set_capability(fpc1020->input_dev, EV_REL, REL_Y); + input_set_capability(fpc1020->input_dev, EV_KEY, BTN_MOUSE); + input_set_capability(fpc1020->input_dev, EV_KEY, KEY_ENTER); + +#ifdef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for report touch down or up + set_bit(FPC1020_KEY_FINGER_TOUCH, fpc1020->input_dev->keybit); + set_bit(FPC1020_KEY_MOVE_FORWARD, fpc1020->input_dev->keybit); + set_bit(FPC1020_KEY_MOVE_BACKWARD, fpc1020->input_dev->keybit); + set_bit(FPC1020_KEY_ROTATE_FORWARD, fpc1020->input_dev->keybit); + set_bit(FPC1020_KEY_ROTATE_BACKWARD, fpc1020->input_dev->keybit); +#ifdef AS_HOME_KEY + set_bit(FPC1020_KEY_FINGER_PRESS, fpc1020->input_dev->keybit); + //set_bit(FPC1020_KEY_FINGER_LONG_PRESS, fpc1020->input_dev->keybit); + set_bit(FPC1020_KEY_FINGER_DOUBLE_TAB, fpc1020->input_dev->keybit); + set_bit(KEY_POWER, fpc1020->input_dev->keybit); + set_bit(KEY_F2, fpc1020->input_dev->keybit); + fpc1020->to_power = false; + /* + init_timer(&s_timer); + s_timer.function = &fpc1020_timer_handle; + s_timer.expires = jiffies + LONG_PRESS_TIME_IN_SEC*HZ;//changhua.li check finger present after 100ms + */ +#endif + +#endif /* VENDOR_EDIT */ + + /* Register the input device */ + error = input_register_device(fpc1020->input_dev); + + + if (error) { + dev_err(&fpc1020->spi->dev, "Input_register_device failed.\n"); + input_free_device(fpc1020->input_dev); + fpc1020->input_dev = NULL; + } + } + + fpc1020->touch_pad_dev = input_allocate_device(); + + if (!fpc1020->touch_pad_dev) { + dev_err(&fpc1020->spi->dev, "Input_allocate_device failed.\n"); + error = -ENOMEM; + } + + if (!error) { + fpc1020->touch_pad_dev->name = FPC1020_TOUCH_PAD_DEV_NAME; + + /* Set event bits according to what events we are generating */ + set_bit(EV_KEY, fpc1020->touch_pad_dev->evbit); + set_bit(EV_ABS, fpc1020->touch_pad_dev->evbit); + set_bit(BTN_TOUCH, fpc1020->touch_pad_dev->keybit); + set_bit(ABS_X, fpc1020->touch_pad_dev->absbit); + set_bit(ABS_Y, fpc1020->touch_pad_dev->absbit); + set_bit(ABS_Z, fpc1020->touch_pad_dev->absbit); + input_set_abs_params(fpc1020->touch_pad_dev, ABS_X, 0, DEVICE_WIDTH, 0, 0); + input_set_abs_params(fpc1020->touch_pad_dev, ABS_Y, 0, DEVICE_HEIGHT, 0, 0); + + /* Register the input device */ + error = input_register_device(fpc1020->touch_pad_dev); + + + if (error) { + dev_err(&fpc1020->spi->dev, "Input_register_device failed.\n"); + input_free_device(fpc1020->touch_pad_dev); + fpc1020->touch_pad_dev = NULL; + } + } + + if (!error) { + /* sub area setup */ + fpc1020->nav.image_nav_row_start = ((fpc1020->chip.pixel_rows - NAV_IMAGE_HEIGHT)/2); + fpc1020->nav.image_nav_row_count = NAV_IMAGE_HEIGHT; + fpc1020->nav.image_nav_col_start = ((fpc1020->chip.pixel_columns - NAV_IMAGE_WIDTH)/2) / fpc1020->chip.adc_group_size; + fpc1020->nav.image_nav_col_groups = (NAV_IMAGE_WIDTH + fpc1020->chip.adc_group_size - 1) / fpc1020->chip.adc_group_size; + + //fpc1020->nav.input_mode = FPC1020_INPUTMODE_TRACKPAD; +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-29 Modify for navigation move event + fpc1020->nav.input_mode = FPC1020_INPUTMODE_TOUCH; +#else /* VENDOR_EDIT */ + fpc1020->nav.input_mode = FPC1020_INPUTMODE_MOVE; +#ifndef AS_HOME_KEY + fpc1020->nav.enabled = false; + init_enhanced_navi_setting(fpc1020); +#else + fpc1020->nav.enabled = true; +#endif +#endif /* VENDOR_EDIT */ + + } + + return error; +} +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +void /*__devexit*/ fpc1020_input_destroy(fpc1020_data_t *fpc1020) +{ + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + if (fpc1020->input_dev != NULL) + input_free_device(fpc1020->input_dev); + if (fpc1020->touch_pad_dev != NULL) + input_free_device(fpc1020->touch_pad_dev); +} +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +int fpc1020_input_enable(fpc1020_data_t *fpc1020, bool enabled) +{ + //dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + fpc1020->nav.enabled = enabled; + + return 0; +} +#endif + +#ifdef VENDOR_EDIT +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for report touch down or up +void fpc1020_report_finger_down(fpc1020_data_t *fpc1020) +{ + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_TOUCH, 1); + + input_sync(fpc1020->input_dev); +} + +void fpc1020_report_finger_up(fpc1020_data_t *fpc1020) +{ + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_TOUCH, 0); + + input_sync(fpc1020->input_dev); +} +#endif /* VENDOR_EDIT */ + +#ifdef AS_HOME_KEY +/* +struct timer_list s_timer; +static void fpc1020_timer_handle(unsigned long arg) +{ + int error = 0; + //mod_timer(&s_timer, jiffies + HZ); + error = fpc1020_wait_finger_present_lpm(fpc1020); + + if (error == 0) { + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 1); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + + input_sync(fpc1020->input_dev); + } + //del_timer(&switch_data->s_timer); + + printk(KERN_ERR "finger timer to check finger present after 2s. \n"); +} +*/ + +/* -------------------------------------------------------------------- */ +static int fpc1020_write_lpm_setup(fpc1020_data_t *fpc1020) +{ + const int mux = FPC1020_MAX_ADC_SETTINGS - 1; + int error = 0; + u16 temp_u16; + fpc1020_reg_access_t reg; + + //dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + error = fpc1020_write_sensor_setup(fpc1020); + if(error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + +out: + return error; +} + + +extern struct wake_lock fpc1020_wake_lock; +/* -------------------------------------------------------------------- */ +static int fpc1020_wait_finger_present_lpm(fpc1020_data_t *fpc1020) +{ + const int lpm_poll_delay_ms = FPC1020_INPUT_POLL_TIME_MS; + #if 0 + const int zmask_5 = 1 << 5; + const int zmask_6 = 1 << 6; + #endif + const int zmask_ext = FPC1020_FINGER_DETECT_ZONE_MASK; + + int error = 0; + int zone_raw = 0; + + bool wakeup_center = false; + bool wakeup_ext = false; + bool wakeup = false; + + int is_2050 = 0; + #if 0 + bool double_tap = false; + #endif + bool finger_up = false; + + error = fpc1020_wake_up(fpc1020); + + if (!error) + error = fpc1020_calc_finger_detect_threshold_min(fpc1020); + + if (error >= 0) + error = fpc1020_set_finger_detect_threshold(fpc1020, error); + + if (error >= 0) + error = fpc1020_write_lpm_setup(fpc1020); +//changhua remove for 12 zone to detect,will consume more 6ma,before is 250ua + is_2050 = gpio_is_valid(fpc1020->fp2050_gpio) ? gpio_get_value(fpc1020->fp2050_gpio):0; + if(is_2050)//with 2050,do sleep(0) with 5 6 zone detect home for antenna issue + { + + if (!error) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) + error = 0; + } + } + + } + + while (!fpc1020->worker.stop_request && !error && !wakeup) { + if (!error) + error = fpc1020_wait_finger_present(fpc1020); + + /*dev_err(&fpc1020->spi->dev, + "%s fpc1020_wait_finger_present return %d !\n", __func__,error);*/ + if (!error){ + //if(fpc1020->to_power == true){ + // dev_err(&fpc1020->spi->dev,"%s Finger report Power KEY\n", __func__); + // input_report_key(fpc1020->input_dev, + // KEY_POWER, 1); + // input_sync(fpc1020->input_dev); + // input_report_key(fpc1020->input_dev, + // KEY_POWER, 0); + // input_sync(fpc1020->input_dev); + // error = 0; + //}else{ + error = fpc1020_check_finger_present_raw(fpc1020); + /*dev_err(&fpc1020->spi->dev, + "%s fpc1020_check_finger_present_raw return %d !\n", __func__,error);*/ + //} + + } + + zone_raw = (error >= 0) ? error : 0; + + #ifdef AS_HOME_KEY //add for fast tab by changhua + /* //remove for single click become double click + if (error == 0){ + dev_err(&fpc1020->spi->dev,"%s fast tab ---HOME DOWN !\n", __func__); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 1); + input_sync(fpc1020->input_dev); + finger_up = true; + dev_err(&fpc1020->spi->dev,"%s fast tab --- HOME UP !\n", __func__); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + input_sync(fpc1020->input_dev); + wakeup = true; + }*/ + if (error > 0) { + #else + + if (error >= 0) { + #endif + error = 0; + #if 0 + wakeup_center = (zone_raw & zmask_5) || + (zone_raw & zmask_6); + #else + wakeup_center = true; + #endif + /* Todo: refined extended processing ? */ + wakeup_ext = ((zone_raw & zmask_ext) == zmask_ext); + //changhua.li add for more condition + if (zone_raw > fpc1020->setup.capture_finger_down_threshold) + wakeup_ext = true; + + } else { + wakeup_center = + wakeup_ext = false; + } + + if (wakeup_center && wakeup_ext) { + dev_err(&fpc1020->spi->dev, + "%s Wake up !\n", __func__); + #if 0 + //check for double tab,timeout in 100ms + if(fpc1020_wait_finger_present_timeout(fpc1020) < 0/*==-ETIMEDOUT*/) + { + double_tap = false; + dev_err(&fpc1020->spi->dev,"%s HOME DOWN !\n", __func__); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 1); + input_sync(fpc1020->input_dev); + + while (!finger_up && (error >= 0)) { + + if (fpc1020->worker.stop_request) + { + error = -EINTR; + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + input_sync(fpc1020->input_dev); + } + else + error = fpc1020_check_finger_present_sum(fpc1020); + + if ((error >= 0) && (error < fpc1020->setup.capture_finger_up_threshold + 1)) + { + finger_up = true; + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + input_sync(fpc1020->input_dev); + } + else + msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS); + } + } + else + { + double_tap = true; + dev_err(&fpc1020->spi->dev,"%s DOUBLE_TAB !\n", __func__); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_DOUBLE_TAB, 1); + input_sync(fpc1020->input_dev); + + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_DOUBLE_TAB, 0); + input_sync(fpc1020->input_dev); + } + #else + dev_err(&fpc1020->spi->dev,"%s HOME DOWN ! fpc1020->to_power(%d)\n", __func__,fpc1020->to_power); + if(fpc1020->to_power != true){ + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 1); + input_sync(fpc1020->input_dev); + }else if (enable_keys) { + wake_lock_timeout(&fpc1020_wake_lock,5*HZ); + input_report_key(fpc1020->input_dev, + KEY_HOME, 1); + input_sync(fpc1020->input_dev); + } + while (!finger_up && (error >= 0)) { + + if (fpc1020->worker.stop_request) + { + error = -EINTR; + /* + dev_err(&fpc1020->spi->dev,"%s HOME UP by stop requst !\n", __func__); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + input_sync(fpc1020->input_dev); + */ + if(fpc1020->to_power == true){ + dev_err(&fpc1020->spi->dev,"%s KEY UP by stop requst !\n", __func__); + input_report_key(fpc1020->input_dev, + KEY_HOME, 0); + input_sync(fpc1020->input_dev); + //wake_unlock(&fpc1020_wake_lock); + } + } + else{ + //fpc1020_reset(fpc1020);//changhua add for can not detect finger leave in some IC with dead pixel + //fpc1020_write_capture_setup(fpc1020);//changhua add for can not detect finger leave in some IC with dead pixel + + error = fpc1020_check_finger_present_sum(fpc1020); + } + + if ((error >= 0) && (error < fpc1020->setup.capture_finger_up_threshold + 1))//changhua modify from 1-->2 for iron ball&fall down test damage IC(dead pixel [18,33]) + { + finger_up = true; + dev_err(&fpc1020->spi->dev,"%s HOME UP ! fpc1020->to_power(%d)\n", __func__,fpc1020->to_power); + if(fpc1020->to_power != true){ + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + input_sync(fpc1020->input_dev); + }else if (enable_keys) { + input_report_key(fpc1020->input_dev, + KEY_HOME, 0); + input_sync(fpc1020->input_dev); + //wake_unlock(&fpc1020_wake_lock); + } + } + else + msleep(FPC1020_CAPTURE_WAIT_FINGER_DELAY_MS); + } + #endif + + wakeup = true; + } + if (!wakeup && !error) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) + error = 0; + + if (!error) + msleep(lpm_poll_delay_ms); + } + } + + /*if (error < 0) + dev_err(&fpc1020->spi->dev, + "%s %s %d!\n", __func__, + (error == -EINTR) ? "TERMINATED" : "FAILED", error);*/ + + return error; +} +#endif/*AS_HOME_KEY*/ +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +int fpc1020_input_task(fpc1020_data_t *fpc1020) +{ +#ifndef AS_HOME_KEY + bool isReverse = false; + int dx = 0; + int dy = 0; + int sumX = 0; + int sumY = 0; + int error = 0; + unsigned char* prevBuffer = NULL; + unsigned char* curBuffer = NULL; + unsigned long diffTime = 0; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + error = fpc1020_write_nav_setup(fpc1020); + + while (!fpc1020->worker.stop_request && + fpc1020->nav.enabled && (error >= 0)) { + + error = fpc1020_capture_wait_finger_down(fpc1020); + if (error < 0) + break; + + process_navi_event(fpc1020, 0, 0, FNGR_ST_DETECTED); + + error = capture_nav_image(fpc1020); + if(error < 0) + break; + + memcpy(fpc1020->prev_img_buf, fpc1020->huge_buffer, NAV_IMAGE_WIDTH * NAV_IMAGE_HEIGHT); + + while (!fpc1020->worker.stop_request && (error >= 0)) { + + if(isReverse) { + prevBuffer = fpc1020->cur_img_buf; + curBuffer = fpc1020->prev_img_buf; + } else { + prevBuffer = fpc1020->prev_img_buf; + curBuffer = fpc1020->cur_img_buf; + } + + error = capture_nav_image(fpc1020); + if(error < 0) + break; + + memcpy(curBuffer, fpc1020->huge_buffer, NAV_IMAGE_WIDTH * NAV_IMAGE_HEIGHT); + + error = fpc1020_check_finger_present_sum(fpc1020); + if (error < fpc1020->setup.capture_finger_up_threshold + 1) { + process_navi_event(fpc1020, 0, 0, FNGR_ST_LOST); + sumX = 0; + sumY = 0; + fpc1020->nav.time = 0; + isReverse = false; + break; + } + + isReverse = !isReverse; + + get_movement(prevBuffer, curBuffer, &dx, &dy); + + sumX += dx; + sumY += dy; + + diffTime = abs(jiffies - fpc1020->nav.time); + if(diffTime > 0) { + diffTime = diffTime * 1000000 / HZ; + + if (diffTime >= FPC1020_INPUT_POLL_INTERVAL) { + process_navi_event(fpc1020, sumX, sumY, FNGR_ST_MOVING); + //dev_info(&fpc1020->spi->dev, "[INFO] nav finger moving. sumX = %d, sumY = %d\n", sumX, sumY); + sumX = 0; + sumY = 0; + fpc1020->nav.time = jiffies; + } + } + + } + } + + if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s %s (%d)\n", + __func__, + (error == -EINTR) ? "TERMINATED" : "FAILED", error); + } + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-28 Remove for nav disabled when out of suspend + fpc1020->nav.enabled = false; +#endif /* VENDOR_EDIT */ + + + return error; + + +#else// AS_HOME_KEY +int error = 0; + + //dev_err(&fpc1020->spi->dev, "%s\n", __func__); + + while (!fpc1020->worker.stop_request && + fpc1020->nav.enabled /*&& !error*/) { + + error = fpc1020_wait_finger_present_lpm(fpc1020); + /* + //add_timer(&s_timer); + if (error == 0) { + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 1); + input_report_key(fpc1020->input_dev, + FPC1020_KEY_FINGER_PRESS, 0); + + input_sync(fpc1020->input_dev); + }*/ + if (error < 0 && error != -EINTR){ + msleep(10); + } + } + /*if (error < 0) { + dev_err(&fpc1020->spi->dev, + "%s %s (%d)\n", + __func__, + (error == -EINTR) ? "TERMINATED" : "FAILED", error); + }*/ + return error; + +#endif// AS_HOME_KEY +} +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#ifndef AS_HOME_KEY +static int fpc1020_write_nav_setup(fpc1020_data_t *fpc1020) +{ + const int mux = 2; + int error = 0; + u16 temp_u16; + fpc1020_reg_access_t reg; + + dev_dbg(&fpc1020->spi->dev, "%s %d\n", __func__, mux); + + error = fpc1020_wake_up(fpc1020); + if (error) + goto out; + + error = fpc1020_write_sensor_setup(fpc1020); + if(error) + goto out; + + temp_u16 = fpc1020->setup.adc_shift[mux]; + temp_u16 <<= 8; + temp_u16 |= fpc1020->setup.adc_gain[mux]; + + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_ADC_SHIFT_GAIN, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + temp_u16 = fpc1020->setup.pxl_ctrl[mux]; + FPC1020_MK_REG_WRITE(reg, FPC102X_REG_PXL_CTRL, &temp_u16); + error = fpc1020_reg_access(fpc1020, ®); + if (error) + goto out; + + error = fpc1020_capture_set_crop(fpc1020, + fpc1020->nav.image_nav_col_start, fpc1020->nav.image_nav_col_groups, + fpc1020->nav.image_nav_row_start, fpc1020->nav.image_nav_row_count); + if (error) + goto out; + + dev_dbg(&fpc1020->spi->dev, "%s, (%d, %d, %d, %d)\n", __func__, + fpc1020->nav.image_nav_col_start, fpc1020->nav.image_nav_col_groups, + fpc1020->nav.image_nav_row_start, fpc1020->nav.image_nav_row_count); + +out: + return error; +} +#endif +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#if 0 +static int fpc1020_write_lpm_setup(fpc1020_data_t *fpc1020) +{ + return fpc1020_write_sensor_setup(fpc1020); +} +#endif +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#if 0 +static int fpc1020_wait_finger_present_lpm(fpc1020_data_t *fpc1020) +{ + const int lpm_poll_delay_ms = FPC1020_INPUT_POLL_TIME_MS; + const int zmask_5 = 1 << 5; + const int zmask_6 = 1 << 6; + const int zmask_ext = FPC1020_FINGER_DETECT_ZONE_MASK & + FPC1020_HW_DETECT_MASK; + + int error = 0; + int zone_raw = 0; + + bool wakeup_center = false; + bool wakeup_ext = false; + bool wakeup = false; + + error = fpc1020_write_lpm_setup(fpc1020); + + if (!error) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) + error = 0; + } + } + + while (!fpc1020->worker.stop_request && !error && !wakeup) { + if (!error) + error = fpc1020_wait_finger_present(fpc1020); + + if (!error) + error = fpc1020_check_finger_present_raw(fpc1020); + + zone_raw = (error >= 0) ? error : 0; + + if (error >= 0) { + error = 0; + + wakeup_center = (zone_raw & zmask_5) || + (zone_raw & zmask_6); + + /* Todo: refined extended processing ? */ + wakeup_ext = ((zone_raw & zmask_ext) == zmask_ext); + + } else { + wakeup_center = + wakeup_ext = false; + } + + if (wakeup_center && wakeup_ext) { + dev_dbg(&fpc1020->spi->dev, + "%s Wake up !\n", __func__); + wakeup = true; + } + if (!wakeup && !error) { + error = fpc1020_sleep(fpc1020, false); + + if (error == -EAGAIN) + error = 0; + + if (!error) + msleep(lpm_poll_delay_ms); + } + } + + if (!error) + error = fpc1020_write_nav_setup(fpc1020); + + if (error < 0) + dev_dbg(&fpc1020->spi->dev, + "%s FAILED %d!\n", __func__, + error); + + return error; +} +#endif +#endif + + +/* -------------------------------------------------------------------- */ +#ifdef CONFIG_INPUT_FPC1020_NAV +#ifndef AS_HOME_KEY +static int capture_nav_image(fpc1020_data_t *fpc1020) +{ + int error = 0; + size_t image_size = 0; + + error = fpc1020_read_irq(fpc1020, true); + if (error < 0) { + dev_dbg(&fpc1020->spi->dev, "%s, fpc1020_read_irq error\n", __func__); + } + + /* + dev_dbg(&fpc1020->spi->dev, "%s, !!!!!(%d, %d, %d, %d)!!!!!\n", __func__, + fpc1020->nav.image_nav_col_start, fpc1020->nav.image_nav_col_groups, + fpc1020->nav.image_nav_row_start, fpc1020->nav.image_nav_row_count); + */ + image_size = fpc1020->nav.image_nav_row_count * + fpc1020->nav.image_nav_col_groups * fpc1020->chip.adc_group_size; + + error = fpc1020_capture_buffer(fpc1020, + fpc1020->huge_buffer, + 0, + image_size); + + return error; +} +#endif +#endif + + +/* -------------------------------------------------------------------- */ + diff --git a/drivers/input/misc/fpc1020_regs.h b/drivers/input/misc/fpc1020_regs.h new file mode 100755 index 0000000000000..617740f1398cf --- /dev/null +++ b/drivers/input/misc/fpc1020_regs.h @@ -0,0 +1,103 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef __FPC1020_REGS_H +#define __FPC1020_REGS_H + +typedef enum { + /* --- Common registers --- */ + FPC102X_REG_FPC_STATUS = 20, /* RO, 1 bytes */ + FPC102X_REG_READ_INTERRUPT = 24, /* RO, 1 byte */ + FPC102X_REG_READ_INTERRUPT_WITH_CLEAR = 28, /* RO, 1 byte */ + FPC102X_REG_READ_ERROR_WITH_CLEAR = 56, /* RO, 1 byte */ + FPC102X_REG_MISO_EDGE_RIS_EN = 64, /* WO, 1 byte */ + FPC102X_REG_FPC_CONFIG = 68, /* RW, 1 byte */ + FPC102X_REG_IMG_SMPL_SETUP = 76, /* RW, 3 bytes */ + FPC102X_REG_CLOCK_CONFIG = 80, /* RW, 1 byte */ + FPC102X_REG_IMG_CAPT_SIZE = 84, /* RW, 4 bytes */ + FPC102X_REG_IMAGE_SETUP = 92, /* RW, 1 byte */ + FPC102X_REG_ADC_TEST_CTRL = 96, /* RW, 1 byte */ + FPC102X_REG_IMG_RD = 100, /* RW, 1 byte */ + FPC102X_REG_SAMPLE_PX_DLY = 104, /* RW, 8 bytes */ + FPC102X_REG_PXL_RST_DLY = 108, /* RW, 1 byte */ + FPC102X_REG_TST_COL_PATTERN_EN = 120, /* RW, 2 bytes */ + FPC102X_REG_CLK_BIST_RESULT = 124, /* RW, 4 bytes */ + FPC102X_REG_ADC_WEIGHT_SETUP = 132, /* RW, 1 byte */ + FPC102X_REG_ANA_TEST_MUX = 136, /* RW, 4 bytes */ + FPC102X_REG_FINGER_DRIVE_CONF = 140, /* RW, 1 byte */ + FPC102X_REG_FINGER_DRIVE_DLY = 144, /* RW, 1 byte */ + FPC102X_REG_OSC_TRIM = 148, /* RW, 2 bytes */ + FPC102X_REG_ADC_WEIGHT_TABLE = 152, /* RW, 10 bytes */ + FPC102X_REG_ADC_SETUP = 156, /* RW, 5 bytes */ + FPC102X_REG_ADC_SHIFT_GAIN = 160, /* RW, 2 bytes */ + FPC102X_REG_BIAS_TRIM = 164, /* RW, 1 byte */ + FPC102X_REG_PXL_CTRL = 168, /* RW, 2 bytes */ + FPC102X_REG_FPC_DEBUG = 208, /* RO, 1 bytes */ + FPC102X_REG_FINGER_PRESENT_STATUS = 212, /* RO, 2 bytes */ + FPC102X_REG_HWID = 252, /* RO, 2 bytes */ + /* --- fpc1020/21 specific --- */ + FPC1020_REG_FNGR_DET_THRES = 216, /* RW, 1 byte */ + FPC1020_REG_FNGR_DET_CNTR = 220, /* RW, 2 bytes */ + /* --- fpc1150 specific --- */ + FPC1150_REG_OFFSET = 1000, /* Not a register ! */ + FPC1150_REG_FNGR_DET_THRES = 1216, /* RW, 4 byte */ + FPC1150_REG_FNGR_DET_CNTR = 1220, /* RW, 4 bytes */ + +} fpc1020_reg_t; + +#define FPC1020_REG_MAX_SIZE 10 + +#define FPC1020_REG_SIZE(reg) ( \ + ((reg) == FPC102X_REG_FPC_STATUS) ? 1 : \ + ((reg) == FPC102X_REG_READ_INTERRUPT) ? 1 : \ + ((reg) == FPC102X_REG_READ_INTERRUPT_WITH_CLEAR) ? 1 : \ + ((reg) == FPC102X_REG_READ_ERROR_WITH_CLEAR) ? 1 : \ + ((reg) == FPC102X_REG_MISO_EDGE_RIS_EN) ? 1 : \ + ((reg) == FPC102X_REG_FPC_CONFIG) ? 1 : \ + ((reg) == FPC102X_REG_IMG_SMPL_SETUP) ? 3 : \ + ((reg) == FPC102X_REG_CLOCK_CONFIG) ? 1 : \ + ((reg) == FPC102X_REG_IMG_CAPT_SIZE) ? 4 : \ + ((reg) == FPC102X_REG_IMAGE_SETUP) ? 1 : \ + ((reg) == FPC102X_REG_ADC_TEST_CTRL) ? 1 : \ + ((reg) == FPC102X_REG_IMG_RD) ? 1 : \ + ((reg) == FPC102X_REG_SAMPLE_PX_DLY) ? 8 : \ + ((reg) == FPC102X_REG_PXL_RST_DLY) ? 1 : \ + ((reg) == FPC102X_REG_TST_COL_PATTERN_EN) ? 2 : \ + ((reg) == FPC102X_REG_CLK_BIST_RESULT) ? 4 : \ + ((reg) == FPC102X_REG_ADC_WEIGHT_SETUP) ? 1 : \ + ((reg) == FPC102X_REG_ANA_TEST_MUX) ? 4 : \ + ((reg) == FPC102X_REG_FINGER_DRIVE_CONF) ? 1 : \ + ((reg) == FPC102X_REG_FINGER_DRIVE_DLY) ? 1 : \ + ((reg) == FPC102X_REG_OSC_TRIM) ? 2 : \ + ((reg) == FPC102X_REG_ADC_WEIGHT_TABLE) ? 10 :\ + ((reg) == FPC102X_REG_ADC_SETUP) ? 5 : \ + ((reg) == FPC102X_REG_ADC_SHIFT_GAIN) ? 2 : \ + ((reg) == FPC102X_REG_BIAS_TRIM) ? 1 : \ + ((reg) == FPC102X_REG_PXL_CTRL) ? 2 : \ + ((reg) == FPC102X_REG_FPC_DEBUG) ? 2 : \ + ((reg) == FPC102X_REG_FINGER_PRESENT_STATUS) ? 2 : \ + ((reg) == FPC102X_REG_HWID) ? 2 : \ + \ + ((reg) == FPC1020_REG_FNGR_DET_THRES) ? 1 : \ + ((reg) == FPC1020_REG_FNGR_DET_CNTR) ? 2 : \ + \ + ((reg) == FPC1150_REG_FNGR_DET_THRES) ? 4 : \ + ((reg) == FPC1150_REG_FNGR_DET_CNTR) ? 4 : \ + 0) + +#define FPC1020_REG_ACCESS_DUMMY_BYTES(reg) ( \ + ((reg) == FPC102X_REG_FPC_STATUS) ? 1 : \ + ((reg) == FPC102X_REG_FPC_DEBUG) ? 1 : 0) + +#define FPC1020_REG_TO_ACTUAL(reg) ( \ + ((reg) >= FPC1150_REG_OFFSET) ? ((reg) - FPC1150_REG_OFFSET) : (reg) ) + +#endif /* __FPC1020_REGS_H */ + + diff --git a/drivers/input/misc/fpc1020_regulator.c b/drivers/input/misc/fpc1020_regulator.c new file mode 100755 index 0000000000000..14ff1d39b92ef --- /dev/null +++ b/drivers/input/misc/fpc1020_regulator.c @@ -0,0 +1,262 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#define DEBUG + +#include + +#if 0 //#ifndef CONFIG_USE_OF /*VENDOR_EDIT*/ //oneplus changhua modify for MSM8994 +#include +#include +#include +#else +#include +#include "fpc1020.h" +#include "fpc1020_common.h" +#include "fpc1020_regulator.h" +#endif + + +/* -------------------------------------------------------------------- */ +int fpc1020_regulator_configure(fpc1020_data_t *fpc1020) +{ + int error = 0; + + dev_dbg(&fpc1020->spi->dev, "%s\n", __func__); + + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + fpc1020->vcc_spi = regulator_get(&fpc1020->spi->dev, "vcc_spi"); + if (IS_ERR(fpc1020->vcc_spi)) { + error = PTR_ERR(fpc1020->vcc_spi); + dev_err(&fpc1020->spi->dev, + "Regulator get failed, vcc_spi, error=%d\n", error); + goto supply_err; + } + + if (regulator_count_voltages(fpc1020->vcc_spi) > 0) { + error = regulator_set_voltage(fpc1020->vcc_spi, + SUPPLY_SPI_MIN, SUPPLY_SPI_MAX); + if (error) { + dev_err(&fpc1020->spi->dev, + "regulator set(spi) failed, error=%d\n", error); + goto supply_err; + } + } +#endif /* VENDOR_EDIT */ + + + fpc1020->vdd_io = regulator_get(&fpc1020->spi->dev, "vdd_io"); + if (IS_ERR(fpc1020->vdd_io)) { + error = PTR_ERR(fpc1020->vdd_io); + dev_err(&fpc1020->spi->dev, + "Regulator get failed, vdd_io, error=%d\n", error); + goto supply_err; + } + + if (regulator_count_voltages(fpc1020->vdd_io) > 0) { + error = regulator_set_voltage(fpc1020->vdd_io, + SUPPLY_IO_MIN, SUPPLY_IO_MAX); + if (error) { + dev_err(&fpc1020->spi->dev, + "regulator set(io) failed, error=%d\n", error); + goto supply_err; + } + } + +//#ifndef VENDOR_EDIT 2014-12-31 changhua add for 14009 HW config + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + fpc1020->vdd_ana = regulator_get(&fpc1020->spi->dev, "vdd_ana"); + if (IS_ERR(fpc1020->vdd_ana)) { + error = PTR_ERR(fpc1020->vdd_ana); + dev_err(&fpc1020->spi->dev, + "Regulator get failed, vdd_ana error=%d\n", error); + goto supply_err; + } + + if (regulator_count_voltages(fpc1020->vdd_ana) > 0) { + error = regulator_set_voltage(fpc1020->vdd_ana, + SUPPLY_ANA_MIN, SUPPLY_ANA_MAX); + if (error) { + dev_err(&fpc1020->spi->dev, + "regulator set(ana) failed, error=%d\n", error); + goto supply_err; + } + } +//#endif /* VENDOR_EDIT */ + + return 0; + +supply_err: + fpc1020_regulator_release(fpc1020); + return error; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_regulator_release(fpc1020_data_t *fpc1020) +{ + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + if (fpc1020->vcc_spi != NULL) { + regulator_put(fpc1020->vcc_spi); + fpc1020->vcc_spi = NULL; + } +#endif /* VENDOR_EDIT */ + + if (fpc1020->vdd_io != NULL) { + regulator_put(fpc1020->vdd_io); + fpc1020->vdd_io = NULL; + } + +//#ifndef VENDOR_EDIT 2014-12-31 changhua add for 14009 HW config + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + if (fpc1020->vdd_ana != NULL) { + regulator_put(fpc1020->vdd_ana); + fpc1020->vdd_ana = NULL; + } +//#endif /* VENDOR_EDIT */ + + fpc1020->power_enabled = false; + + return 0; +} + + +/* -------------------------------------------------------------------- */ +int fpc1020_regulator_set(fpc1020_data_t *fpc1020, bool enable) +{ + int error = 0; + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Modify for Hw COnfig + //if ((fpc1020->vcc_spi == NULL) || + // (fpc1020->vdd_io == NULL) || + // (fpc1020->vdd_ana == NULL)) { +#else /* VENDOR_EDIT */ + if (fpc1020->vdd_io == NULL) { +#endif /* VENDOR_EDIT */ + dev_err(&fpc1020->spi->dev, + "Regulators not set\n"); + return -EINVAL; + } + + if (enable) { + dev_dbg(&fpc1020->spi->dev, "%s on\n", __func__); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + regulator_set_optimum_mode(fpc1020->vcc_spi, + SUPPLY_SPI_REQ_CURRENT); + + error = (regulator_is_enabled(fpc1020->vcc_spi) == 0) ? + regulator_enable(fpc1020->vcc_spi) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vcc_spi enable failed, error=%d\n", + error); + goto out_err; + } +#endif /* VENDOR_EDIT */ + + regulator_set_optimum_mode(fpc1020->vdd_io, + SUPPLY_IO_REQ_CURRENT); + + error = (regulator_is_enabled(fpc1020->vdd_io) == 0) ? + regulator_enable(fpc1020->vdd_io) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vdd_io enable failed, error=%d\n", + error); + goto out_err; + } + +#ifndef VENDOR_EDIT //2014-12-31 changhua remove for 14009 HW config + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw COnfig + gpio_set_value(fpc1020->vdden_gpio, 1); +#endif /* VENDOR_EDIT */ + +//#ifndef VENDOR_EDIT //2014-12-31 changhua add for 14009 HW config + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + regulator_set_optimum_mode(fpc1020->vdd_ana, + SUPPLY_ANA_REQ_CURRENT); + + error = (regulator_is_enabled(fpc1020->vdd_ana) == 0) ? + regulator_enable(fpc1020->vdd_ana) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vdd_ana enable failed, error=%d\n", + error); + goto out_err; + } +//#endif /* VENDOR_EDIT */ + } else { + dev_dbg(&fpc1020->spi->dev, "%s off\n", __func__); + +#ifndef VENDOR_EDIT + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + error = (fpc1020->power_enabled && + regulator_is_enabled(fpc1020->vcc_spi) > 0) ? + regulator_disable(fpc1020->vcc_spi) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vcc_spi disable failed, error=%d\n", + error); + goto out_err; + } +#endif /* VENDOR_EDIT */ + + error = (fpc1020->power_enabled && + regulator_is_enabled(fpc1020->vdd_io) > 0) ? + regulator_disable(fpc1020->vdd_io) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vdd_io disable failed, error=%d\n", + error); + goto out_err; + } + +#ifndef VENDOR_EDIT //2014-12-31 oneplus changhua@BSP remove for 14009 HW config +//Lycan.Wang@Prd.BasicDrv, 2014-09-12 Add for Hw COnfig + gpio_set_value(fpc1020->vdden_gpio, 0); +#endif /* VENDOR_EDIT */ + +//#ifndef VENDOR_EDIT //2014-12-31 changhua add for 14009 HW config + //Lycan.Wang@Prd.BasicDrv, 2014-09-12 Remove for Hw COnfig + error = (fpc1020->power_enabled && + regulator_is_enabled(fpc1020->vdd_ana) > 0) ? + regulator_disable(fpc1020->vdd_ana) : 0; + + if (error) { + dev_err(&fpc1020->spi->dev, + "Regulator vdd_ana disable failed error=%d\n", + error); + goto out_err; + } +//#endif /* VENDOR_EDIT */ + } + + fpc1020->power_enabled = enable; + + return 0; + +out_err: + fpc1020_regulator_release(fpc1020); + return error; +} + + + diff --git a/drivers/input/misc/fpc1020_regulator.h b/drivers/input/misc/fpc1020_regulator.h new file mode 100755 index 0000000000000..61239012fc934 --- /dev/null +++ b/drivers/input/misc/fpc1020_regulator.h @@ -0,0 +1,35 @@ +/* FPC1020 Touch sensor driver + * + * Copyright (c) 2013,2014 Fingerprint Cards AB + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#ifndef LINUX_SPI_FPC1020_REGULATOR_H +#define LINUX_SPI_FPC1020_REGULATOR_H + +#define SUPPLY_1V8 1800000UL +#define SUPPLY_2V85 2850000UL//changhua added +#define SUPPLY_SPI_MIN SUPPLY_1V8 +#define SUPPLY_SPI_MAX SUPPLY_1V8 + +#define SUPPLY_IO_MIN SUPPLY_1V8 +#define SUPPLY_IO_MAX SUPPLY_1V8 + +#define SUPPLY_ANA_MIN SUPPLY_2V85//changhua added for fpc1150 datasheet 1.8~3.3V +#define SUPPLY_ANA_MAX SUPPLY_2V85 + +#define SUPPLY_SPI_REQ_CURRENT 10U +#define SUPPLY_IO_REQ_CURRENT 6000U +#define SUPPLY_ANA_REQ_CURRENT 6000U + +extern int fpc1020_regulator_configure(fpc1020_data_t *fpc1020); + +extern int fpc1020_regulator_release(fpc1020_data_t *fpc1020); + +extern int fpc1020_regulator_set(fpc1020_data_t *fpc1020, bool enable); + +#endif /* LINUX_SPI_FPC1020_REGULATOR_H */ + diff --git a/drivers/input/misc/switch_antenna.c b/drivers/input/misc/switch_antenna.c new file mode 100755 index 0000000000000..a48e09646d5cf --- /dev/null +++ b/drivers/input/misc/switch_antenna.c @@ -0,0 +1,589 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "../../../fs/proc/internal.h" + +#define DRV_NAME "switch_antenna" +#define CLASS_NAME "sw_antenna" +#define DEV_NAME "sw_antenna" +#define CDEV_NAME "sw_antenna" + +//#define BUILD_MODULE + +struct antenna_dev_data { + + + int antenna1_gpio; + int antenna2_gpio; + int antenna3_gpio; + int antenna4_gpio; + + struct device *dev; + int state; + + /* + struct device *device; + + dev_t devno; + */ + //struct input_dev *input; +}; + +static struct antenna_dev_data *antenna_data; +/* +static int antenna_device_count; +static struct class *antenna_class; +static ssize_t antenna_state_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *after; + unsigned long val = simple_strtoul(buf, &after, 10); + //int rc = -1; +printk("%s : enter val=(%d)\n",__func__,val); + switch(val) + { + case 0: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 1: + gpio_direction_output(antenna_data->antenna1_gpio,1); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 2: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,1); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 3: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,1); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 4: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,1); + break; + default: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + + } + return count; +} +static ssize_t antenna_state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int val=0; + if(gpio_direction_input(antenna_data->antenna1_gpio)) + { + val=1; + return sprintf(buf, "%d\n", val); + } + if(gpio_direction_input(antenna_data->antenna2_gpio)) + { + val=2; + return sprintf(buf, "%d\n", val); + } + if(gpio_direction_input(antenna_data->antenna3_gpio)) + { + val=3; + return sprintf(buf, "%d\n", val); + } + if(gpio_direction_input(antenna_data->antenna4_gpio)) + { + val=4; + return sprintf(buf, "%d\n", val); + } + + val=0; + return sprintf(buf, "%d\n", val); + +} + +static struct device_attribute antenna_state_attr = + __ATTR(antenna_state, 0666, antenna_state_show, antenna_state_store); +*/ +static DEFINE_MUTEX(sem); +static int antenna_state_show(struct seq_file *seq, void *offset) +{ + + seq_printf(seq, "%d\n", antenna_data->state); + return 0; +} + +static ssize_t antenna_state_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + //char* after; + //char* buf; + int state; + int enable; + if (!antenna_data) { + return -EFAULT; + } + mutex_lock(&sem); +/* + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + state = simple_strtoul(buf, &after, 10); +*/ + sscanf(buffer, "%d", &state); + + printk("antenna_state before(0x%x),enter(%d),count=%zu \n",antenna_data->state,state,count); + + enable = state%10; + state = state/10; + if(enable!=0) + { + //if(antenna_data->state!= state) { + if(state == 0) + antenna_data->state = 0; + else + antenna_data->state |= (1<< (state-1)); + switch(state) + { + case 0: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 1: + gpio_direction_output(antenna_data->antenna1_gpio,1); + /* + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + */ + break; + case 2: + //gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,1); + //gpio_direction_output(antenna_data->antenna3_gpio,0); + //gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 3: + //gpio_direction_output(antenna_data->antenna1_gpio,0); + //gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,1); + //gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 4: + /* + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + */ + gpio_direction_output(antenna_data->antenna4_gpio,1); + break; + default: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + + } + + + + //} + } + else + { + //if(antenna_data->state!= state) { + if(state == 0) + antenna_data->state = 0; + else + antenna_data->state &= ~(1<< (state-1)); + switch(state) + { + case 0: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 1: + gpio_direction_output(antenna_data->antenna1_gpio,0); + /* + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + */ + break; + case 2: + //gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + //gpio_direction_output(antenna_data->antenna3_gpio,0); + //gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 3: + //gpio_direction_output(antenna_data->antenna1_gpio,0); + //gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + //gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + case 4: + /* + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + */ + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + default: + gpio_direction_output(antenna_data->antenna1_gpio,0); + gpio_direction_output(antenna_data->antenna2_gpio,0); + gpio_direction_output(antenna_data->antenna3_gpio,0); + gpio_direction_output(antenna_data->antenna4_gpio,0); + break; + + } + + + + //} + } + printk("antenna_state change to (0x%x) \n",antenna_data->state); + mutex_unlock(&sem); + return count; +} + +static int antenna_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, antenna_state_show, antenna_data); +} + + +static const struct file_operations antenna_state_proc_fops = { + .owner = THIS_MODULE, + .open = antenna_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = antenna_state_write, +}; + +#ifndef BUILD_MODULE +#ifdef CONFIG_OF +static int antenna_dev_get_devtree_pdata(struct device *dev) +{ + struct device_node *node; + + node = dev->of_node; + if (!node) + return -EINVAL; + + antenna_data->antenna2_gpio= of_get_named_gpio(node, "antenna,antenna2_gpio", 0); + if ((!gpio_is_valid(antenna_data->antenna2_gpio))) + return -EINVAL; + + + + antenna_data->antenna1_gpio= of_get_named_gpio(node, "antenna,antenna1_gpio", 0); + if ((!gpio_is_valid(antenna_data->antenna1_gpio))) + return -EINVAL; + + antenna_data->antenna3_gpio= of_get_named_gpio(node, "antenna,antenna3_gpio", 0); + if ((!gpio_is_valid(antenna_data->antenna2_gpio))) + return -EINVAL; + + + + antenna_data->antenna4_gpio= of_get_named_gpio(node, "antenna,antenna4_gpio", 0); + if ((!gpio_is_valid(antenna_data->antenna1_gpio))) + return -EINVAL; + + return 0; +} + +static struct of_device_id antenna_of_match[] = { + { .compatible = "oneplus,switch-antenna", }, + { }, +}; +MODULE_DEVICE_TABLE(of, antenna_of_match); + +#else + +static int +antenna_dev_get_devtree_pdata(struct device *dev) +{ + return 0; +} +#endif +#endif + +static int antenna_dev_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + int error=0; + +printk("%s\n",__func__); + + antenna_data = kzalloc(sizeof(struct antenna_dev_data), GFP_KERNEL); + antenna_data->dev = dev; + +/* + if (!antenna_class) { + antenna_class = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(antenna_class)) + error = PTR_ERR(antenna_class); + //dev_err(dev,"%s: class_create FAILED %d.\n", __func__, error); + //goto err_antenna_dev_register; + } + + error = alloc_chrdev_region(&antenna_data->devno, + antenna_device_count++, + 1, + DRV_NAME); + + if (error < 0) { + dev_err(dev, + "%s: alloc_chrdev_region FAILED %d.\n", __func__, error); + goto err_class; + + } else { + dev_info(dev, "%s: major=%d, minor=%d\n", + __func__, + MAJOR(antenna_data->devno), + MINOR(antenna_data->devno)); + } + antenna_data->device = device_create(antenna_class, NULL, antenna_data->devno, + NULL, "%s", CDEV_NAME); + + if (IS_ERR(antenna_data->device)) { + dev_err(dev, "%s: device_create failed.\n",__func__); + error = PTR_ERR(antenna_data->device); + goto err_class; + } + + error = sysfs_create_file(&antenna_data->device->kobj, &antenna_state_attr.attr); + //error = sysfs_create_file(&antenna_data->dev->kobj, &antenna_state_attr.attr); +*/ + #ifndef BUILD_MODULE + //parse device tree node + error = antenna_dev_get_devtree_pdata(dev); + #else //TODO modify gpio number by hw + antenna_data->antenna1_gpio = 998;//34-->912 66-->944 + antenna_data->antenna1_gpio = 999; + antenna_data->antenna1_gpio = 1000; + antenna_data->antenna1_gpio = 1002; + //TODO maybe need to use pin-ctrl if that gpios are not in gpio mode, + //then to do in .ko will use ioremap instead of pin-ctrl to write the register(0xfd511xxx), + //register bit[0]= + //0:mode + //4:in out status 0 1 + //8:INTR status 9f + #endif + if (error) { + dev_err(dev, "parse device tree fail!!!\n"); + //goto err_device; + goto err_antenna_dev_register; + } + if (!proc_create_data("antenna_switch", 0666, NULL, &antenna_state_proc_fops, antenna_data)) { + error = -ENOMEM; + goto err_antenna_dev_register; + } + + error = gpio_request(antenna_data->antenna1_gpio,"antenna1_gpio"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + error = gpio_direction_output(antenna_data->antenna1_gpio,0); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_output, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + + + error = gpio_request(antenna_data->antenna2_gpio,"antenna2_gpio"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + error = gpio_direction_output(antenna_data->antenna2_gpio,0); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_output, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + + error = gpio_request(antenna_data->antenna3_gpio,"antenna3_gpio"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + error = gpio_direction_output(antenna_data->antenna3_gpio,0); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_output, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + + error = gpio_request(antenna_data->antenna4_gpio,"antenna4_gpio"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + error = gpio_direction_output(antenna_data->antenna4_gpio,0); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_output, err=%d", __func__, error); + //return retval; + goto err_set_gpio; + } + printk("%s ok!\n",__func__); + return 0; + + + +err_set_gpio: +if (gpio_is_valid(antenna_data->antenna1_gpio)) + gpio_free(antenna_data->antenna1_gpio); +if (gpio_is_valid(antenna_data->antenna2_gpio)) + gpio_free(antenna_data->antenna2_gpio); +if (gpio_is_valid(antenna_data->antenna3_gpio)) + gpio_free(antenna_data->antenna3_gpio); +if (gpio_is_valid(antenna_data->antenna4_gpio)) + gpio_free(antenna_data->antenna4_gpio); + +/* +err_device: + if (!IS_ERR_OR_NULL(antenna_data->device)) + device_destroy(antenna_class, antenna_data->devno); + +err_class: +class_destroy(antenna_class); + antenna_class = NULL; +*/ +err_antenna_dev_register: + kfree(antenna_data); + + return error; +} + +static int antenna_dev_remove(struct platform_device *pdev) +{ +printk("%s\n",__func__); + + if (gpio_is_valid(antenna_data->antenna1_gpio)) + gpio_free(antenna_data->antenna1_gpio); + if (gpio_is_valid(antenna_data->antenna2_gpio)) + gpio_free(antenna_data->antenna2_gpio); + if (gpio_is_valid(antenna_data->antenna3_gpio)) + gpio_free(antenna_data->antenna3_gpio); + if (gpio_is_valid(antenna_data->antenna4_gpio)) + gpio_free(antenna_data->antenna4_gpio); + + /* + if (!IS_ERR_OR_NULL(antenna_data->device)) + device_destroy(antenna_class, antenna_data->devno); + + class_destroy(antenna_class); + antenna_class = NULL; + */ + kfree(antenna_data); + + return 0; +} + +#ifdef BUILD_MODULE +static struct platform_device antenna_device = { + .name = DRV_NAME, + .id = -1, +}; + +static struct platform_driver antenna_dev_driver = { + .probe = antenna_dev_probe, + .remove = antenna_dev_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init switch_antenna_init(void) +{ + + platform_device_register(&antenna_device); + + + return = platform_driver_register(&antenna_dev_driver); +} + + + +static void __exit switch_antenna_exit(void) +{ + printk(KERN_INFO "%s\n", __func__); + platform_driver_unregister(&antenna_device); + + platform_driver_unregister(&antenna_dev_driver); +} +module_init(switch_antenna_init); +module_exit(switch_antenna_exit); + +#else + +static struct platform_driver antenna_dev_driver = { + .probe = antenna_dev_probe, + .remove = antenna_dev_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(antenna_of_match), + }, +}; +module_platform_driver(antenna_dev_driver); +#endif +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("switch antenna by gpio's driver"); + diff --git a/drivers/input/misc/switch_theme.c b/drivers/input/misc/switch_theme.c new file mode 100755 index 0000000000000..1b4c08a7b3020 --- /dev/null +++ b/drivers/input/misc/switch_theme.c @@ -0,0 +1,669 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include + + +#include +#include +#include "../../../fs/proc/internal.h" + + +//#include +#define DRV_NAME "switch-theme" +/* +* HW SCHEMATIC +* Cover | Phone +* | +* -----|----R2(2K Ohm)------[3.3 V +* | | +* R1 | +* | | +* |____|___________ADC +* | | +* | | +* | R3(51K ohm) +* | | +* | = GND +*/ + +/* +* cover type | cover resist(K 0hm) | ADC voltage (V) +* 1 | 0 | 3.18 +* 2 | 5.6 | 2.87 +* 3 | 12 | 2.59 +* 4 | 20 | 2.31 +* 5 | 30.9 | 2.01 +* 6 | 51 | 1.62 +* 7 | 82 | 1.25 +* 8 | 121 | 0.97 +* 9 | 200 | 0.67 +* 10 | 470 | 0.32 +* .. | .. | ... +* +*/ + +/*procfs enable_switch_theme when change cover feature + procfs cover_type for boot up to read,when enable,read the type to change theme +*/ + +//TODO change name to real cover type +typedef enum { + COVER_TYPE_UNKNOWN, + COVER_TYPE1, + COVER_TYPE2, + COVER_TYPE3, + COVER_TYPE4, + COVER_TYPE5, + COVER_TYPE6, + COVER_TYPE7, + COVER_TYPE8, + COVER_TYPE9, + COVER_TYPE10, + COVER_TYPE_MAX_NUM +} cover_t; + +struct switch_theme_data { + cover_t last_type; + cover_t cover_type; + int adc_value;//int ? + int switch_enable; + int irq; + int irq_gpio;//gpio66 + int cover_switch_gpio;//pm8994 gpio01 + //ADC channel PM8994 MPP04 + struct qpnp_vadc_chip *vadc_dev; + + struct regulator *vdd_io; + bool power_enabled; + + struct work_struct work; + struct switch_dev sdev; + struct device *dev; + //struct input_dev *input; + + struct pinctrl * key_pinctrl; + struct pinctrl_state * set_state; +}; + +static struct switch_theme_data *switch_data; +/* +#define SUPPLY_3V3 2950000UL +#define SUPPLY_IO_MIN SUPPLY_3V3 +#define SUPPLY_IO_MAX SUPPLY_3V3 +#define SUPPLY_IO_REQ_CURRENT 6000U + +int cover_switch_regulator_release(void) +{ + + + + if (switch_data->vdd_io != NULL) { + regulator_put(switch_data->vdd_io); + switch_data->vdd_io = NULL; + } + + switch_data->power_enabled = false; + + return 0; +} + +int cover_switch_regulator_set(bool enable) +{ + int error = 0; + + if (switch_data->vdd_io == NULL) { + dev_err(switch_data->dev, + "Regulators not set\n"); + return -EINVAL; + } + + if (enable) { + dev_dbg(switch_data->dev, "%s on\n", __func__); + + regulator_set_optimum_mode(switch_data->vdd_io, + SUPPLY_IO_REQ_CURRENT); + + error = (regulator_is_enabled(switch_data->vdd_io) == 0) ? + regulator_enable(switch_data->vdd_io) : 0; + + if (error) { + dev_err(switch_data->dev, + "Regulator vdd_io enable failed, error=%d\n", + error); + goto out_err; + } + + } else { + dev_dbg(switch_data->dev, "%s off\n", __func__); + + error = (switch_data->power_enabled && + regulator_is_enabled(switch_data->vdd_io) > 0) ? + regulator_disable(switch_data->vdd_io) : 0; + + if (error) { + dev_err(switch_data->dev, + "Regulator vdd_io disable failed, error=%d\n", + error); + goto out_err; + } + + } + switch_data->power_enabled = enable; + return 0; + +out_err: + cover_switch_regulator_release(); + return error; +} + +static int cover_switch_supply_init(void) +{ + int error = 0; + + switch_data->vdd_io = regulator_get(switch_data->dev, "vdd_io"); + if (IS_ERR(switch_data->vdd_io)) { + error = PTR_ERR(switch_data->vdd_io); + dev_err(switch_data->dev, + "Regulator get failed, vdd_io, error=%d\n", error); + goto err; + } + + if (regulator_count_voltages(switch_data->vdd_io) > 0) { + error = regulator_set_voltage(switch_data->vdd_io, + SUPPLY_IO_MIN, SUPPLY_IO_MAX); + if (error) { + dev_err(switch_data->dev, + "regulator set(io) failed, error=%d\n", error); + goto err; + } + } + if (error) { + dev_err(switch_data->dev, + "regulator configuration failed.\n"); + goto err; + } + + error = cover_switch_regulator_set(true); + if (error) { + dev_err(switch_data->dev, + "regulator enable failed.\n"); + goto err; + } + +err: + return error; +} +*/ +static int cover_switch_enable_show(struct seq_file *seq, void *offset) +{ + + seq_printf(seq, "%d\n", switch_data->switch_enable); + return 0; +} + +static ssize_t cover_switch_enable_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + unsigned int cover_switch; + + if (!switch_data) { + return -EFAULT; + } + + if (copy_from_user(&cover_switch, buffer, sizeof(cover_switch))) + return -EFAULT; + + printk("cover_switch_enable %d change to %d\n",switch_data->switch_enable,cover_switch); + + if(switch_data->switch_enable!= cover_switch) { + switch_data->switch_enable = cover_switch; + } + + return count; +} + +static int cover_switch_enable_open(struct inode *inode, struct file *file) +{ + return single_open(file, cover_switch_enable_show, switch_data); +} + + +static const struct file_operations cover_switch_enable_proc_fops = { + .owner = THIS_MODULE, + .open = cover_switch_enable_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cover_switch_enable_write, +}; + +//add for test +static int cover_type_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", switch_data->cover_type); + return 0; +} + +static int cover_type_open(struct inode *inode, struct file *file) +{ + return single_open(file, cover_type_show, switch_data); +} + +static ssize_t cover_type_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + int state; + if (!switch_data) { + return -EFAULT; + } + /* + if (copy_from_user(&cover_switch, buffer, sizeof(cover_switch))) + return -EFAULT; + */ + sscanf(buffer, "%d", &state); + printk("cover_type_write by procfs: (%d) change to (%d)\n",switch_data->cover_type,state); + + if(switch_data->cover_type!= state) { + switch_data->last_type = switch_data->cover_type; + switch_data->cover_type = state; + switch_set_state(&switch_data->sdev, switch_data->cover_type); + } + + return count; +} + +static const struct file_operations cover_type_proc_fops = { + .owner = THIS_MODULE, + .open = cover_type_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cover_type_write, +}; + +static int ADC_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", switch_data->adc_value); + return 0; +} + +static int ADC_open(struct inode *inode, struct file *file) +{ + return single_open(file, ADC_show, switch_data); +} + + +static const struct file_operations ADC_proc_fops = { + .owner = THIS_MODULE, + .open = ADC_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + //.write = ADC_write, +}; + +//#define Test //use gpio34(fingerprint key' gpio) for test,cause now we have no hardware + +#ifdef Test //changhua add for test uevent + +static void cover_switch_work(struct work_struct *work) +{ + printk("%s gpio_get_value(%d)=%d",__func__,switch_data->irq_gpio,gpio_get_value(switch_data->irq_gpio)); + switch_set_state(&switch_data->sdev, (!!gpio_get_value(switch_data->irq_gpio)?COVER_TYPE1:COVER_TYPE2)); +} +irqreturn_t cover_switch_interrupt(int irq, void *_dev) +{ + schedule_work(&switch_data->work); + + return IRQ_HANDLED; +} +#else +//static int voltage_tbl [] = {2840,2570,2310,2060,1790,1450,1110,860,590,290}; +static int voltage_tbl [] = {2769,2388,2003,1635,1360,983,626,383}; +static DEFINE_MUTEX(mLock); +irqreturn_t cover_switch_interrupt(int irq, void *_dev) +{ + //if (!gpio_get_value(switch_data->irq_gpio)) {//triger_falling + schedule_work(&switch_data->work); + //return IRQ_HANDLED; + //} + return IRQ_NONE; +} +static void cover_switch_work(struct work_struct *work) +{ + int adc; + int i=0; + int err=0; + struct qpnp_vadc_result result; + mutex_lock(&mLock); + printk("%s\n",__func__); + if (gpio_get_value(switch_data->irq_gpio)) + { + switch_data->cover_type = COVER_TYPE_UNKNOWN; + printk("%s,cover_type(%d) --->(%d)\n",__func__,switch_data->last_type,switch_data->cover_type); + switch_data->last_type = switch_data->cover_type; + switch_set_state(&switch_data->sdev, switch_data->cover_type); + mutex_unlock(&mLock); + return; + } + disable_irq_nosync(switch_data->irq); + free_irq(switch_data->irq,switch_data); + + //TODO read ADC & report data + if(gpio_is_valid(switch_data->cover_switch_gpio)) + gpio_direction_output(switch_data->cover_switch_gpio,1);//switch to read adc channel + mdelay(100);//wait for ADC stable + //read adc + //Read the VADC channel using the QPNP-ADC-API. + err = qpnp_vadc_read(switch_data->vadc_dev, P_MUX4_1_3, &result); //Read the MPP4 VADC channel with 1:3 scaling + if (err) { + printk("%s,Unable to read cover adc, rc=%d\n",__func__,err); + + } + printk("%s,read cover adc =%lld uV\n",__func__,result.physical); + adc = (int) result.physical; + adc = adc / 1000; /* uV to mV */ + printk("%s,read cover adc =%d mV\n",__func__,adc); + switch_data->adc_value = adc; + for(i=1;i<(sizeof(voltage_tbl)/sizeof(voltage_tbl[0]));i++) + { + if(switch_data->adc_value >= voltage_tbl[i]) + { + if((switch_data->adc_value - voltage_tbl[i]) < (voltage_tbl[i-1] - switch_data->adc_value)) + switch_data->cover_type = (cover_t)(i+1); + else + switch_data->cover_type = (cover_t)(i); + break; + } + } + if(switch_data->adc_value > voltage_tbl[0]) + switch_data->cover_type = COVER_TYPE1; + if(i >= (sizeof(voltage_tbl)/sizeof(voltage_tbl[0]))) + switch_data->cover_type = (cover_t)(i);//COVER_TYPE10; + if(switch_data->adc_value < 20) + switch_data->cover_type = COVER_TYPE_UNKNOWN; + printk("%s,cover_type(%d) --->(%d)\n",__func__,switch_data->last_type,switch_data->cover_type); + if(switch_data->last_type != switch_data->cover_type) + { + switch_data->last_type = switch_data->cover_type; + switch_set_state(&switch_data->sdev, switch_data->cover_type); + } + + //switch to INT channel after read adc to detect next changing of cover + if(gpio_is_valid(switch_data->cover_switch_gpio)) + gpio_direction_output(switch_data->cover_switch_gpio,0);//switch to INT + mdelay(1); + err = request_irq(switch_data->irq, cover_switch_interrupt, + IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "covor_switch", switch_data); + //to check whether cover is leave when we check type done,cause we have disable irq,so when cover leave here will not have interrupt to tell us + if (gpio_get_value(switch_data->irq_gpio)) + { + switch_data->cover_type = COVER_TYPE_UNKNOWN; + printk("%s,cover is leave when we check type,cover_type(%d) --->(%d)\n",__func__,switch_data->last_type,switch_data->cover_type); + switch_data->last_type = switch_data->cover_type; + switch_set_state(&switch_data->sdev, switch_data->cover_type); + } + printk("%s OK\n",__func__); + mutex_unlock(&mLock); +} + + +#endif +/* //no need cause switch_class.c state_show() +static ssize_t cover_switch_print_state(struct switch_dev *sdev, char *buf) +{ + cover_t state; + state = switch_data->cover_type; + + if (state) + return sprintf(buf, "%d\n", state); + return -1; +} +*/ +#ifdef CONFIG_OF +static int switch_theme_get_devtree_pdata(struct device *dev) +{ + struct device_node *node; + + node = dev->of_node; + if (!node) + return -EINVAL; + +printk("%s, node name:%s , %s\n",__func__,node->name,node->full_name); + switch_data->irq_gpio= of_get_named_gpio(node, "cover,gpio_irq", 0); + if ((!gpio_is_valid(switch_data->irq_gpio))) + return -EINVAL; + +printk("%s, irq gpio:%d \n", __func__, switch_data->irq_gpio); + + switch_data->cover_switch_gpio= of_get_named_gpio(node, "cover,gpio_switch", 0); + if ((!gpio_is_valid(switch_data->cover_switch_gpio))) + return -EINVAL; +printk("%s, switch gpio:%d \n", __func__, switch_data->cover_switch_gpio); + return 0; +} + +static struct of_device_id switch_theme_of_match[] = { + { .compatible = "oneplus,switch-theme", }, + { }, +}; +MODULE_DEVICE_TABLE(of, switch_theme_of_match); + +#else + +static inline int +switch_theme_get_devtree_pdata(struct device *dev) +{ + return 0; +} +#endif + +static int switch_theme_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + int error=0; + +printk("%s\n",__func__); + + switch_data = kzalloc(sizeof(struct switch_theme_data), GFP_KERNEL); + switch_data->dev = dev; + switch_data->last_type = COVER_TYPE_UNKNOWN; + + + /* early for VADC get, defer probe if needed */ + switch_data->vadc_dev = qpnp_get_vadc(dev, "cover"); + if (IS_ERR(switch_data->vadc_dev)) { + error = PTR_ERR(switch_data->vadc_dev); + if (error == -EPROBE_DEFER) + printk("%s, vadc not found - defer rc=%d\n",__func__, error); + else + printk("%s, vadc property missing, rc=%d\n",__func__, error); + goto err_switch_dev_register;; + } +/* + switch_data->dev = dev; + + switch_data->input = input_allocate_device(); + + switch_data->input->name = pdev->name; + switch_data->input->phys = DRV_NAME"/input0"; + switch_data->input->dev.parent = &pdev->dev; + + switch_data->input->id.bustype = BUS_HOST; + switch_data->input->id.vendor = 0x0001; + switch_data->input->id.product = 0x0001; + switch_data->input->id.version = 0x0100; + + input_set_drvdata(switch_data->input, switch_data); + + __set_bit(EV_KEY, switch_data->input->evbit); + */ + //changhua remove for L21 always-on + /* + error = cover_switch_supply_init(); + if (error) { + dev_err(dev, "parse device tree fail!!!\n"); + goto err_regulator; + } +*/ + + //parse device tree node + error = switch_theme_get_devtree_pdata(dev); + if (error) { + dev_err(dev, "parse device tree fail!!!\n"); + goto err_switch_dev_register; + } + + switch_data->key_pinctrl = devm_pinctrl_get(switch_data->dev); + if (IS_ERR_OR_NULL(switch_data->key_pinctrl)) { + dev_err(switch_data->dev, "Failed to get pinctrl \n"); + goto err_switch_dev_register; + } + switch_data->set_state =pinctrl_lookup_state(switch_data->key_pinctrl,"cover_int_active"); + if (IS_ERR_OR_NULL(switch_data->set_state)) { + dev_err(switch_data->dev, "Failed to lookup_state \n"); + goto err_switch_dev_register; + } + pinctrl_select_state(switch_data->key_pinctrl, switch_data->set_state); + + //config cover_switch gpio(pm8994 gpio01) to output low to switch to INT_R,not ADC(pm8994 mpp04) + error = gpio_request(switch_data->cover_switch_gpio,"cover_switch-ADC-INT"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + goto err_switch_dev_register; + + } + error = gpio_direction_output(switch_data->cover_switch_gpio,0); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_output, err=%d", __func__, error); + return error; + + } + + //config irq gpio and request irq + switch_data->irq = gpio_to_irq(switch_data->irq_gpio); + if (switch_data->irq <= 0) + { + printk("%s, irq number is not specified, irq #= %d, int pin=%d\n\n", __func__, switch_data->irq, switch_data->irq_gpio); + goto err_detect_irq_num_failed; + } + else + { + error = gpio_request(switch_data->irq_gpio,"switch_theme-int"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_request_gpio; + } + error = gpio_direction_input(switch_data->irq_gpio); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_input, err=%d", __func__, error); + //return retval; + goto err_set_gpio_input; + } + printk("%s gpio_get_value(%d)=%d",__func__,switch_data->irq_gpio,gpio_get_value(switch_data->irq_gpio)); + #ifdef Test + error = request_irq(switch_data->irq, cover_switch_interrupt, + IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "covor_switch", switch_data); + #else + error = request_irq(switch_data->irq, cover_switch_interrupt, + IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "covor_switch", switch_data); + #endif + if (error) { + dev_err(dev, + "request_irq %i failed.\n", + switch_data->irq); + + switch_data->irq = -EINVAL; + goto err_request_irq; + } + } + enable_irq_wake(switch_data->irq); + if (!proc_create_data("cover_type", 0660, NULL, &cover_type_proc_fops, switch_data)) { + error = -ENOMEM; + goto err_request_irq; + } + + INIT_WORK(&switch_data->work, cover_switch_work); + switch_data->sdev.name = DRV_NAME; + //switch_data->sdev.print_state = cover_switch_print_state; //no need cause switch_class.c state_show() + error = switch_dev_register(&switch_data->sdev); + if (error < 0) + goto err_request_gpio; + //report the first switch + cover_switch_work(&switch_data->work); + return 0; + + +err_request_gpio: + switch_dev_unregister(&switch_data->sdev); +err_request_irq: +err_detect_irq_num_failed: +err_set_gpio_input: + gpio_free(switch_data->cover_switch_gpio); + gpio_free(switch_data->irq_gpio); + //changhua remove for L21 always-on + /* +err_regulator: + cover_switch_regulator_release(); +*/ +err_switch_dev_register: + kfree(switch_data); + + return error; +} + +static int switch_theme_remove(struct platform_device *pdev) +{ +printk("%s\n",__func__); + cancel_work_sync(&switch_data->work); + gpio_free(switch_data->cover_switch_gpio); + gpio_free(switch_data->irq_gpio); + switch_dev_unregister(&switch_data->sdev); + kfree(switch_data); + + return 0; +} + +static struct platform_driver switch_theme_driver = { + .probe = switch_theme_probe, + .remove = switch_theme_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(switch_theme_of_match), + }, +}; +module_platform_driver(switch_theme_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("switch theme by rare cover type driver"); diff --git a/drivers/input/misc/tri_state_key.c b/drivers/input/misc/tri_state_key.c new file mode 100755 index 0000000000000..b164a0c8ed95f --- /dev/null +++ b/drivers/input/misc/tri_state_key.c @@ -0,0 +1,583 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#define DRV_NAME "tri-state-key" + +/* + KEY1(GPIO34) KEY2(GPIO77) +1½ÅºÍ4½ÅÁ¬½Ó 0 1 | MUTE +2½ÅºÍ5½ÅÁ¬½Ó 1 1 | Do Not Disturb +4½ÅºÍ3½ÅÁ¬½Ó 1 0 | Normal + +*/ +typedef enum { + MODE_UNKNOWN, + MODE_MUTE, + MODE_DO_NOT_DISTURB, + MODE_NORMAL, + MODE_MAX_NUM +} tri_mode_t; + +static int current_mode = 0; +static int keyCode_slider_top = 600; +static int keyCode_slider_middle = 601; +static int keyCode_slider_bottom = 602; + +struct switch_dev_data { + //tri_mode_t last_type; + //tri_mode_t mode_type; + //int switch_enable; + int irq_key2; + int irq_key1; + int key1_gpio;//key1 gpio34 + int key2_gpio;//key2 gpio77 + + struct regulator *vdd_io; + //bool power_enabled; + + struct work_struct work; + struct switch_dev sdev; + struct device *dev; + //struct input_dev *input; + + struct timer_list s_timer; + struct pinctrl * key_pinctrl; + struct pinctrl_state * set_state; + struct input_dev *input; +}; + +static struct switch_dev_data *switch_data; +static DEFINE_MUTEX(sem); + +static int set_gpio_by_pinctrl(void) +{ + printk(KERN_ERR "tristate_key set_gpio_by_pinctrl. \n"); + return pinctrl_select_state(switch_data->key_pinctrl, switch_data->set_state); +} + +static void send_input(int keyCode) +{ + input_report_key(switch_data->input, keyCode, 1); + input_sync(switch_data->input); + input_report_key(switch_data->input, keyCode, 0); + input_sync(switch_data->input); +} + +static void switch_dev_work(struct work_struct *work) +{ + int keyCode; + //printk("%s gpio_get_value(%d)=%d\n",__func__,switch_data->key1_gpio,gpio_get_value(switch_data->key1_gpio)); + //printk("%s gpio_get_value(%d)=%d\n",__func__,switch_data->key2_gpio,gpio_get_value(switch_data->key2_gpio)); + mutex_lock(&sem); + if(!gpio_get_value(switch_data->key2_gpio)) + { + current_mode = MODE_NORMAL; + keyCode = keyCode_slider_bottom; + } + else if(gpio_get_value(switch_data->key1_gpio)) + { + current_mode = MODE_DO_NOT_DISTURB; + keyCode = keyCode_slider_middle; + } + else + { + current_mode = MODE_MUTE; + keyCode = keyCode_slider_top; + } + switch_set_state(&switch_data->sdev, current_mode); + send_input(keyCode); + printk("%s ,tristate set to state(%d) \n",__func__,switch_data->sdev.state); + mutex_unlock(&sem); +} +irqreturn_t switch_dev_interrupt(int irq, void *_dev) +{ +//printk("%s\n",__func__); + schedule_work(&switch_data->work); + + return IRQ_HANDLED; +} + +static void timer_handle(unsigned long arg) +{ + //mod_timer(&s_timer, jiffies + HZ); + if(set_gpio_by_pinctrl() < 0) + printk(KERN_ERR "tristate_key set_gpio_by_pinctrl FAILD!!!. \n"); + schedule_work(&switch_data->work); + //del_timer(&switch_data->s_timer); + + //printk(KERN_ERR "tristate_key set gpio77 timer. \n"); +} + +/* //no need cause switch_class.c state_show() +static ssize_t switch_dev_print_state(struct switch_dev *sdev, char *buf) +{ + tri_mode_t state; + state = switch_data->mode_type; + + if (state) + return sprintf(buf, "%d\n", state); + return -1; +} +*/ +#ifdef CONFIG_OF +static int switch_dev_get_devtree_pdata(struct device *dev) +{ + struct device_node *node; + + node = dev->of_node; + if (!node) + return -EINVAL; + + switch_data->key2_gpio= of_get_named_gpio(node, "tristate,gpio_key2", 0); + if ((!gpio_is_valid(switch_data->key2_gpio))) + return -EINVAL; + +//printk("%s, key2 gpio:%d \n", __func__, switch_data->key2_gpio); + + switch_data->key1_gpio= of_get_named_gpio(node, "tristate,gpio_key1", 0); + if ((!gpio_is_valid(switch_data->key1_gpio))) + return -EINVAL; +//printk("%s, key1 gpio:%d \n", __func__, switch_data->key1_gpio); + return 0; +} + +static struct of_device_id tristate_dev_of_match[] = { + { .compatible = "oneplus,tri-state-key", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tristate_dev_of_match); + +#else + +static inline int +switch_dev_get_devtree_pdata(struct device *dev) +{ + return 0; +} +#endif +/* +#define SUPPLY_1V8 1800000UL +#define SUPPLY_IO_MIN SUPPLY_1V8 +#define SUPPLY_IO_MAX SUPPLY_1V8 +#define SUPPLY_IO_REQ_CURRENT 6000U + +int tristate_regulator_release(void) +{ + + + + if (switch_data->vdd_io != NULL) { + regulator_put(switch_data->vdd_io); + switch_data->vdd_io = NULL; + } + + switch_data->power_enabled = false; + + return 0; +} + +int tristate_regulator_set(bool enable) +{ + int error = 0; + + if (switch_data->vdd_io == NULL) { + dev_err(switch_data->dev, + "Regulators not set\n"); + return -EINVAL; + } + + if (enable) { + dev_dbg(switch_data->dev, "%s on\n", __func__); + + regulator_set_optimum_mode(switch_data->vdd_io, + SUPPLY_IO_REQ_CURRENT); + + error = (regulator_is_enabled(switch_data->vdd_io) == 0) ? + regulator_enable(switch_data->vdd_io) : 0; + + if (error) { + dev_err(switch_data->dev, + "Regulator vdd_io enable failed, error=%d\n", + error); + goto out_err; + } + + } else { + dev_dbg(switch_data->dev, "%s off\n", __func__); + + error = (switch_data->power_enabled && + regulator_is_enabled(switch_data->vdd_io) > 0) ? + regulator_disable(switch_data->vdd_io) : 0; + + if (error) { + dev_err(switch_data->dev, + "Regulator vdd_io disable failed, error=%d\n", + error); + goto out_err; + } + + } + switch_data->power_enabled = enable; + return 0; + +out_err: + tristate_regulator_release(); + return error; +} + +static int tristate_supply_init(void) +{ + int error = 0; + + switch_data->vdd_io = regulator_get(switch_data->dev, "vdd_io"); + if (IS_ERR(switch_data->vdd_io)) { + error = PTR_ERR(switch_data->vdd_io); + dev_err(switch_data->dev, + "Regulator get failed, vdd_io, error=%d\n", error); + goto err; + } + + if (regulator_count_voltages(switch_data->vdd_io) > 0) { + error = regulator_set_voltage(switch_data->vdd_io, + SUPPLY_IO_MIN, SUPPLY_IO_MAX); + if (error) { + dev_err(switch_data->dev, + "regulator set(io) failed, error=%d\n", error); + goto err; + } + } + if (error) { + dev_err(switch_data->dev, + "regulator configuration failed.\n"); + goto err; + } + + error = tristate_regulator_set(true); + if (error) { + dev_err(switch_data->dev, + "regulator enable failed.\n"); + goto err; + } + +err: + return error; +} + +*/ + +static ssize_t keyCode_slider_top_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", keyCode_slider_top); +} + +static ssize_t keyCode_slider_top_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int data; + + if (sscanf(buf, "%d", &data) != 1) + return -EINVAL; + if (data != 600 && data != 601 && data != 602) + return -EINVAL; + + keyCode_slider_top = data; + if (current_mode == 1) + send_input(keyCode_slider_top); + + return strnlen(buf, count); +} + +static ssize_t keyCode_slider_middle_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", keyCode_slider_middle); +} + +static ssize_t keyCode_slider_middle_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int data; + + if (sscanf(buf, "%d", &data) != 1) + return -EINVAL; + if (data != 600 && data != 601 && data != 602) + return -EINVAL; + + keyCode_slider_middle = data; + if (current_mode == 2) + send_input(keyCode_slider_middle); + + return strnlen(buf, count); +} + +static ssize_t keyCode_slider_bottom_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", keyCode_slider_bottom); +} + +static ssize_t keyCode_slider_bottom_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int data; + + if (sscanf(buf, "%d", &data) != 1) + return -EINVAL; + if (data != 600 && data != 601 && data != 602) + return -EINVAL; + + keyCode_slider_bottom = data; + if (current_mode == 3) + send_input(keyCode_slider_bottom); + + return strnlen(buf, count); +} + +/* sysfs attributes */ +static struct device_attribute keyCode_attrs[] = { + __ATTR(keyCode_top, (S_IRUGO | S_IWUSR | S_IWGRP), + keyCode_slider_top_show, + keyCode_slider_top_store), + __ATTR(keyCode_middle, (S_IRUGO | S_IWUSR | S_IWGRP), + keyCode_slider_middle_show, + keyCode_slider_middle_store), + __ATTR(keyCode_bottom, (S_IRUGO | S_IWUSR | S_IWGRP), + keyCode_slider_bottom_show, + keyCode_slider_bottom_store), +}; + +static int tristate_dev_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + int i; + int error=0; + + //void __iomem *cfg_reg; + + switch_data = kzalloc(sizeof(struct switch_dev_data), GFP_KERNEL); + switch_data->dev = dev; + + switch_data->key_pinctrl = devm_pinctrl_get(switch_data->dev); + if (IS_ERR_OR_NULL(switch_data->key_pinctrl)) { + dev_err(switch_data->dev, "Failed to get pinctrl \n"); + goto err_switch_dev_register; + } + switch_data->set_state =pinctrl_lookup_state(switch_data->key_pinctrl,"key2_active"); + if (IS_ERR_OR_NULL(switch_data->set_state)) { + dev_err(switch_data->dev, "Failed to lookup_state \n"); + goto err_switch_dev_register; + } + //switch_data->last_type = MODE_UNKNOWN; + + //tristate_supply_init(); + + switch_data->dev = dev; + + switch_data->input = input_allocate_device(); + + switch_data->input->name = DRV_NAME; + switch_data->input->dev.parent = &pdev->dev; + set_bit(EV_KEY, switch_data->input->evbit); + set_bit(keyCode_slider_top, switch_data->input->keybit); + set_bit(keyCode_slider_middle, switch_data->input->keybit); + set_bit(keyCode_slider_bottom, switch_data->input->keybit); + input_set_drvdata(switch_data->input, switch_data); + error = input_register_device(switch_data->input); + if (error) { + dev_err(dev, "Failed to register input device\n"); + goto err_input_device_register; + } + + //parse device tree node + error = switch_dev_get_devtree_pdata(dev); + if (error) { + dev_err(dev, "parse device tree fail!!!\n"); + goto err_switch_dev_register; + } + + //config irq gpio and request irq + switch_data->irq_key1 = gpio_to_irq(switch_data->key1_gpio); + if (switch_data->irq_key1 <= 0) + { + printk("%s, irq number is not specified, irq #= %d, int pin=%d\n\n", __func__, switch_data->irq_key1, switch_data->key1_gpio); + goto err_detect_irq_num_failed; + } + else + { + error = gpio_request(switch_data->key1_gpio,"tristate_key1-int"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_request_gpio; + } + error = gpio_direction_input(switch_data->key1_gpio); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_input, err=%d", __func__, error); + //return retval; + goto err_set_gpio_input; + } +//printk("%s gpio_get_value(%d)=%d \n",__func__,switch_data->key1_gpio,gpio_get_value(switch_data->key1_gpio)); + error = request_irq(switch_data->irq_key1, switch_dev_interrupt, + IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "tristate_key1", switch_data); + if (error) { + dev_err(dev, + "request_irq %i failed.\n", + switch_data->irq_key1); + + switch_data->irq_key1 = -EINVAL; + goto err_request_irq; + } + } + //config irq gpio and request irq + switch_data->irq_key2 = gpio_to_irq(switch_data->key2_gpio); + if (switch_data->irq_key2 <= 0) + { + printk("%s, irq number is not specified, irq #= %d, int pin=%d\n\n", __func__, switch_data->irq_key2, switch_data->key2_gpio); + goto err_detect_irq_num_failed; + } + else + { + error = gpio_request(switch_data->key2_gpio,"tristate_key2-int"); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, error); + //return retval; + goto err_request_gpio; + } + error = gpio_direction_input(switch_data->key2_gpio); + if(error < 0) + { + printk(KERN_ERR "%s: gpio_direction_input, err=%d", __func__, error); + //return retval; + goto err_set_gpio_input; + } + //cfg_reg = (void __iomem *)0xffffff80000794d0; + //writel_relaxed(0x00000000, cfg_reg); + + +//printk("%s gpio_get_value(%d)=%d \n",__func__,switch_data->key2_gpio,gpio_get_value(switch_data->key2_gpio)); + error = request_irq(switch_data->irq_key2, switch_dev_interrupt, + IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "tristate_key2", switch_data); + + if (error) { + dev_err(dev, + "request_irq %i failed.\n", + switch_data->irq_key2); + + switch_data->irq_key2 = -EINVAL; + goto err_request_irq; + } + + } + + INIT_WORK(&switch_data->work, switch_dev_work); + + init_timer(&switch_data->s_timer); + switch_data->s_timer.function = &timer_handle; + switch_data->s_timer.expires = jiffies + 20*HZ; + + add_timer(&switch_data->s_timer); + + enable_irq_wake(switch_data->irq_key1); + enable_irq_wake(switch_data->irq_key2); + + + switch_data->sdev.name = DRV_NAME; + //switch_data->sdev.print_state = switch_dev_print_state; //no need cause switch_class.c state_show() + error = switch_dev_register(&switch_data->sdev); + if (error < 0) + goto err_request_gpio; + //set_gpio_by_pinctrl(); + //report the first switch + //switch_dev_work(&switch_data->work); + + for (i = 0; i < ARRAY_SIZE(keyCode_attrs); i++) { + error = sysfs_create_file(&switch_data->dev->kobj, + &keyCode_attrs[i].attr); + if (error < 0) { + dev_err(dev, "sysfs creation failed\n"); + goto err_sysfs; + } + } + + return 0; + + +err_request_gpio: + switch_dev_unregister(&switch_data->sdev); +err_request_irq: +err_detect_irq_num_failed: +err_set_gpio_input: + gpio_free(switch_data->key2_gpio); + gpio_free(switch_data->key1_gpio); +err_switch_dev_register: + kfree(switch_data); +err_input_device_register: + input_unregister_device(switch_data->input); + input_free_device(switch_data->input); +err_sysfs: + for (i--; i >= 0; i--) + sysfs_remove_file(&switch_data->dev->kobj, + &keyCode_attrs[i].attr); + + return error; +} + +static int tristate_dev_remove(struct platform_device *pdev) +{ + printk("%s\n",__func__); + cancel_work_sync(&switch_data->work); + gpio_free(switch_data->key1_gpio); + gpio_free(switch_data->key2_gpio); + switch_dev_unregister(&switch_data->sdev); + input_unregister_device(switch_data->input); + input_free_device(switch_data->input); + kfree(switch_data); + + return 0; +} + +static struct platform_driver tristate_dev_driver = { + .probe = tristate_dev_probe, + .remove = tristate_dev_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tristate_dev_of_match), + }, +}; +module_platform_driver(tristate_dev_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("switch Profiles by this triple key driver"); + diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig old mode 100644 new mode 100755 index a42fea5862af2..94dca1d04966e --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1062,4 +1062,25 @@ config INPUT_MT_WRAPPER If unsure, say N. +#ifdef VENDOR_EDIT /* LiuPing@Phone.BSP.Sensor, 2014/10/11, add for tp. */ +config TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI + tristate "Synaptics s3508 i2c touchscreen" + depends on I2C + help + This enables support for Synaptics s3508 RMI over I2C based touchscreens. +#endif /*VENDOR_EDIT*/ +#ifdef VENDOR_EDIT /* lifeng@BSP, 2015/3/19, add for tp_key. */ +config TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI + tristate "Synaptics s1302 i2c touchscreen" + depends on I2C + help + This enables support for Synaptics s1302 RMI over I2C based touch key. +#endif /*VENDOR_EDIT*/ +#ifdef VENDOR_EDIT /* lifeng@BSP, 2015/3/19, add for tp_key. */ +config TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI + tristate "Synaptics s3320 i2c touchscreen" + depends on I2C + help + This enables support for Synaptics s1302 RMI over I2C based touch key. +#endif /*VENDOR_EDIT*/ endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile old mode 100644 new mode 100755 index 90b92629c66f2..3be9b493abd38 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -70,6 +70,18 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o + +#ifdef VENDOR_EDIT /* LiuPing@Phone.BSP.Sensor, 2014/10/11, add for tp. */ +#obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI) += synaptics_dsx_i2c.o +#obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI) += synaptics_dsx_fw_update.o +#obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S3508_I2C_RMI) += synaptics_dsx_rmi_dev.o +#obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI) += synaptics_dsx_s1302.o +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI) += synaptics_driver_s3320.o +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S3320_I2C_RMI) += synaptics_s3320_redremote.o +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI) += synaptics_driver_s1302.o +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_S1302_I2C_RMI) += synaptics_s1302_redremote.o +#endif /*VENDOR_EDIT*/ + obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o diff --git a/drivers/input/touchscreen/synaptics_baseline.h b/drivers/input/touchscreen/synaptics_baseline.h new file mode 100755 index 0000000000000..5abd39439459b --- /dev/null +++ b/drivers/input/touchscreen/synaptics_baseline.h @@ -0,0 +1,75 @@ +#ifndef SYNAPTICS_BASELINE_H +#define SYNAPTICS_BASELINE_H + +#define TX_NUM_JDI (30) +#define RX_NUM_JDI (17) +const int16_t cap_data_JDI[2][TX_NUM_JDI][RX_NUM_JDI*2] = +{ + //enable cbc + { + {1533,2299,1567,2351,1578,2366,1614,2422,1505,2257,1482,2224,1478,2216,1463,2195,1482,2224,1472,2208,1490,2234,1486,2230,1490,2236,1545,2317,1590,2386,1603,2405,1575,2363,}, + {1475,2213,1511,2267,1525,2287,1561,2341,1449,2173,1428,2142,1425,2137,1408,2112,1418,2126,1418,2126,1438,2158,1432,2148,1433,2149,1489,2233,1536,2304,1546,2320,1522,2284,}, + {1475,2213,1513,2269,1526,2290,1563,2345,1450,2176,1429,2143,1425,2137,1406,2110,1418,2126,1418,2128,1438,2158,1432,2148,1434,2152,1487,2231,1538,2308,1550,2324,1525,2287,}, + {1481,2221,1520,2280,1533,2299,1567,2351,1455,2183,1436,2154,1430,2146,1413,2119,1423,2135,1422,2134,1444,2166,1438,2158,1439,2159,1495,2243,1545,2317,1555,2333,1532,2298,}, + {1484,2226,1520,2280,1535,2303,1570,2354,1454,2182,1435,2153,1430,2146,1414,2122,1422,2134,1425,2137,1446,2168,1439,2159,1442,2162,1490,2236,1543,2315,1556,2334,1533,2299,}, + {1489,2233,1526,2288,1542,2312,1574,2362,1462,2192,1439,2159,1435,2153,1418,2126,1429,2143,1429,2143,1450,2176,1444,2166,1445,2167,1497,2245,1548,2322,1559,2339,1536,2304,}, + {1492,2238,1532,2298,1546,2318,1579,2369,1466,2198,1447,2171,1442,2162,1426,2138,1432,2148,1434,2152,1454,2180,1448,2172,1449,2173,1503,2255,1553,2329,1564,2346,1539,2309,}, + {1494,2240,1533,2299,1548,2322,1582,2372,1468,2202,1449,2173,1444,2166,1426,2138,1438,2156,1438,2158,1458,2186,1450,2176,1453,2179,1504,2256,1554,2332,1568,2352,1542,2314,}, + {1498,2246,1538,2306,1550,2324,1584,2376,1470,2206,1453,2179,1447,2171,1426,2140,1436,2154,1438,2158,1458,2186,1454,2180,1454,2182,1504,2256,1558,2338,1571,2357,1546,2318,}, + {1501,2251,1542,2314,1554,2332,1587,2381,1474,2212,1454,2182,1448,2172,1432,2148,1441,2161,1442,2162,1461,2191,1458,2186,1458,2186,1510,2266,1562,2342,1575,2363,1550,2324,}, + {1502,2254,1543,2315,1555,2333,1589,2383,1478,2216,1458,2188,1453,2179,1432,2148,1444,2166,1442,2164,1465,2197,1458,2188,1460,2190,1513,2269,1564,2346,1574,2362,1550,2324,}, + {1507,2261,1549,2323,1561,2341,1594,2392,1482,2224,1461,2191,1455,2183,1438,2158,1446,2168,1448,2172,1467,2201,1464,2196,1463,2195,1514,2270,1570,2354,1579,2369,1554,2332,}, + {1514,2270,1554,2332,1567,2351,1601,2401,1486,2230,1467,2201,1461,2191,1442,2162,1450,2176,1454,2180,1471,2207,1467,2201,1468,2202,1520,2280,1572,2358,1586,2378,1558,2338,}, + {1518,2278,1558,2338,1571,2357,1606,2410,1492,2238,1471,2207,1465,2197,1448,2172,1458,2186,1458,2188,1478,2216,1471,2207,1474,2210,1526,2288,1578,2368,1590,2386,1564,2346,}, + {1516,2274,1558,2336,1571,2357,1606,2408,1490,2236,1470,2206,1465,2197,1447,2171,1457,2185,1455,2183,1477,2215,1469,2203,1472,2208,1523,2285,1574,2362,1588,2382,1561,2341,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1494,2240,1474,2212,1469,2203,1450,2176,1458,2186,1460,2190,1481,2221,1474,2210,1474,2212,1526,2290,1578,2368,1590,2386,1565,2347,}, + {1520,2280,1561,2341,1574,2360,1609,2413,1493,2239,1474,2212,1468,2202,1449,2173,1458,2188,1461,2191,1480,2220,1475,2213,1475,2213,1526,2290,1577,2365,1589,2383,1565,2347,}, + {1520,2280,1564,2346,1577,2365,1612,2418,1496,2244,1478,2216,1471,2207,1454,2180,1462,2192,1462,2192,1482,2224,1478,2216,1477,2215,1528,2292,1579,2369,1592,2388,1566,2350,}, + {1519,2279,1563,2345,1575,2363,1610,2414,1497,2245,1475,2213,1471,2207,1451,2177,1460,2190,1462,2192,1482,2224,1475,2213,1475,2213,1526,2288,1578,2368,1592,2388,1564,2346,}, + {1522,2282,1564,2346,1577,2365,1612,2418,1496,2244,1477,2215,1470,2206,1454,2180,1462,2192,1462,2192,1481,2221,1477,2215,1478,2216,1526,2290,1579,2369,1592,2388,1564,2346,}, + {1522,2282,1564,2346,1577,2365,1610,2416,1498,2246,1477,2215,1470,2206,1454,2180,1462,2192,1462,2192,1481,2221,1477,2215,1477,2215,1528,2292,1581,2371,1592,2388,1564,2346,}, + {1519,2279,1562,2342,1574,2362,1609,2413,1495,2243,1474,2210,1469,2203,1449,2173,1458,2188,1461,2191,1480,2220,1474,2210,1474,2212,1522,2282,1577,2365,1590,2386,1562,2342,}, + {1522,2282,1562,2342,1577,2365,1610,2414,1495,2243,1474,2212,1468,2202,1451,2177,1458,2186,1461,2191,1480,2220,1474,2212,1474,2210,1523,2285,1577,2365,1589,2383,1564,2346,}, + {1516,2274,1559,2339,1572,2358,1606,2408,1492,2238,1470,2206,1466,2198,1449,2173,1455,2183,1455,2183,1475,2213,1470,2206,1470,2206,1520,2280,1572,2358,1586,2378,1559,2339,}, + {1515,2273,1558,2336,1572,2358,1604,2406,1490,2234,1470,2206,1464,2196,1446,2168,1454,2180,1455,2183,1475,2213,1468,2202,1469,2203,1517,2275,1571,2357,1582,2374,1555,2333,}, + {1510,2266,1555,2333,1570,2354,1600,2400,1486,2228,1465,2197,1462,2192,1442,2164,1454,2180,1454,2180,1472,2208,1466,2198,1466,2198,1517,2275,1568,2352,1578,2368,1553,2329,}, + {1507,2261,1549,2323,1561,2341,1596,2394,1480,2220,1461,2191,1455,2183,1435,2153,1444,2166,1445,2167,1467,2201,1461,2191,1460,2190,1510,2264,1562,2342,1574,2362,1546,2320,}, + {1502,2254,1542,2314,1558,2336,1589,2383,1474,2212,1454,2180,1450,2176,1429,2143,1438,2158,1441,2161,1460,2190,1454,2182,1455,2183,1502,2254,1559,2339,1570,2354,1543,2315,}, + {1499,2249,1539,2309,1550,2324,1584,2376,1469,2203,1448,2172,1444,2166,1425,2137,1435,2153,1435,2153,1454,2182,1450,2176,1448,2172,1499,2249,1551,2327,1563,2345,1538,2306,}, + {1529,2293,1572,2358,1585,2377,1619,2429,1502,2254,1484,2226,1481,2221,1461,2191,1469,2203,1469,2203,1490,2236,1482,2224,1482,2224,1529,2293,1585,2377,1597,2395,1571,2357,}, + }, + //disable cbc + { + {1534,2302,1567,2351,1578,2368,1614,2422,1505,2257,1483,2225,1475,2213,1463,2195,1482,2224,1474,2210,1492,2238,1487,2231,1490,2236,1546,2318,1589,2383,1602,2404,1577,2365,}, + {1474,2212,1511,2267,1526,2288,1561,2341,1449,2173,1429,2143,1423,2135,1408,2112,1418,2126,1418,2126,1438,2158,1433,2149,1435,2153,1489,2233,1536,2304,1548,2322,1523,2285,}, + {1475,2213,1515,2273,1529,2293,1562,2342,1451,2177,1430,2146,1426,2140,1408,2112,1419,2129,1419,2129,1438,2158,1432,2148,1435,2153,1490,2234,1538,2306,1551,2327,1526,2288,}, + {1480,2220,1518,2278,1532,2298,1567,2351,1455,2183,1435,2153,1429,2143,1411,2117,1422,2132,1422,2134,1442,2164,1438,2156,1438,2156,1492,2238,1542,2314,1556,2334,1531,2297,}, + {1482,2224,1520,2280,1535,2303,1568,2352,1454,2182,1435,2153,1429,2143,1413,2119,1425,2137,1422,2134,1444,2166,1438,2158,1438,2158,1492,2238,1543,2315,1556,2334,1531,2297,}, + {1487,2231,1526,2290,1538,2308,1572,2358,1462,2192,1442,2162,1436,2154,1419,2129,1428,2142,1429,2143,1448,2172,1444,2166,1446,2168,1498,2246,1546,2320,1559,2339,1538,2306,}, + {1493,2239,1530,2294,1543,2315,1578,2368,1466,2198,1447,2171,1442,2162,1423,2135,1434,2152,1435,2153,1455,2183,1449,2173,1448,2172,1501,2251,1551,2327,1565,2347,1540,2310,}, + {1494,2240,1534,2302,1546,2320,1582,2372,1468,2202,1451,2177,1446,2168,1429,2143,1438,2158,1438,2156,1455,2183,1450,2176,1453,2179,1504,2256,1555,2333,1568,2352,1540,2310,}, + {1494,2240,1536,2304,1550,2324,1586,2378,1472,2208,1454,2180,1447,2171,1429,2143,1438,2158,1438,2158,1458,2186,1453,2179,1454,2182,1506,2260,1556,2334,1570,2356,1546,2318,}, + {1499,2249,1539,2309,1551,2327,1587,2381,1474,2210,1454,2180,1446,2168,1430,2146,1439,2159,1441,2161,1458,2188,1457,2185,1457,2185,1507,2261,1561,2341,1572,2358,1546,2318,}, + {1504,2256,1545,2317,1558,2336,1589,2383,1477,2215,1458,2188,1453,2179,1433,2149,1442,2164,1447,2171,1464,2196,1458,2186,1462,2192,1513,2269,1565,2347,1577,2365,1551,2327,}, + {1510,2264,1550,2324,1562,2342,1594,2392,1480,2220,1461,2191,1455,2183,1438,2158,1447,2171,1448,2172,1469,2203,1464,2196,1465,2197,1516,2274,1568,2352,1579,2369,1555,2333,}, + {1513,2269,1552,2328,1566,2350,1599,2399,1486,2228,1466,2198,1460,2190,1441,2161,1451,2177,1453,2179,1474,2212,1467,2201,1466,2198,1520,2280,1572,2358,1582,2374,1558,2338,}, + {1511,2267,1552,2328,1568,2352,1604,2406,1486,2230,1467,2201,1464,2196,1442,2164,1451,2177,1454,2180,1474,2210,1468,2202,1469,2203,1520,2280,1572,2358,1585,2377,1558,2338,}, + {1516,2274,1558,2338,1571,2357,1606,2408,1490,2236,1470,2206,1467,2201,1448,2172,1457,2185,1458,2188,1478,2218,1471,2207,1472,2208,1525,2287,1575,2363,1588,2382,1563,2345,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1494,2240,1472,2208,1468,2202,1451,2177,1458,2188,1458,2188,1480,2220,1474,2212,1477,2215,1525,2287,1578,2366,1590,2386,1564,2346,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1496,2244,1474,2212,1468,2202,1451,2177,1460,2190,1461,2191,1481,2221,1477,2215,1477,2215,1528,2292,1579,2369,1590,2386,1564,2346,}, + {1522,2282,1561,2341,1574,2362,1609,2413,1495,2243,1474,2210,1470,2206,1450,2176,1458,2188,1460,2190,1480,2220,1475,2213,1475,2213,1526,2288,1578,2366,1591,2387,1561,2341,}, + {1518,2278,1561,2341,1577,2365,1612,2418,1497,2245,1475,2213,1471,2207,1453,2179,1461,2191,1461,2191,1480,2220,1474,2210,1474,2212,1525,2287,1577,2365,1590,2386,1563,2345,}, + {1523,2285,1564,2346,1577,2365,1612,2418,1496,2244,1478,2216,1470,2206,1454,2180,1462,2192,1462,2192,1483,2225,1478,2216,1477,2215,1528,2292,1582,2372,1594,2390,1565,2347,}, + {1522,2282,1563,2345,1577,2365,1610,2414,1496,2244,1475,2213,1470,2206,1453,2179,1461,2191,1460,2190,1480,2220,1474,2212,1474,2212,1528,2292,1578,2366,1590,2386,1564,2346,}, + {1519,2279,1562,2342,1574,2360,1607,2411,1494,2240,1474,2212,1467,2201,1449,2173,1458,2186,1461,2191,1478,2218,1474,2210,1474,2212,1525,2287,1578,2366,1590,2386,1563,2345,}, + {1520,2280,1563,2345,1574,2360,1607,2411,1495,2243,1474,2210,1467,2201,1450,2176,1458,2188,1461,2191,1478,2216,1474,2210,1474,2210,1522,2284,1578,2366,1588,2382,1563,2345,}, + {1517,2275,1558,2338,1574,2360,1606,2408,1489,2233,1470,2206,1464,2196,1447,2171,1454,2182,1458,2186,1477,2215,1471,2207,1471,2207,1519,2279,1574,2360,1585,2377,1559,2339,}, + {1513,2269,1558,2336,1571,2357,1606,2408,1490,2234,1470,2206,1465,2197,1445,2167,1454,2182,1455,2183,1474,2212,1469,2203,1470,2206,1517,2275,1571,2357,1584,2376,1555,2333,}, + {1510,2266,1552,2328,1566,2350,1600,2400,1486,2228,1464,2196,1460,2190,1442,2162,1451,2177,1450,2176,1470,2206,1464,2196,1465,2197,1514,2270,1566,2350,1578,2366,1552,2328,}, + {1507,2261,1549,2323,1561,2341,1594,2390,1480,2220,1463,2195,1454,2182,1438,2156,1446,2168,1446,2168,1465,2197,1461,2191,1458,2188,1510,2264,1562,2342,1574,2360,1548,2322,}, + {1501,2251,1543,2315,1556,2334,1589,2383,1474,2210,1454,2182,1449,2173,1430,2146,1439,2159,1441,2161,1461,2191,1455,2183,1454,2182,1502,2254,1556,2334,1570,2354,1542,2314,}, + {1498,2246,1540,2310,1551,2327,1582,2374,1470,2206,1450,2176,1446,2168,1426,2138,1434,2152,1434,2152,1457,2185,1450,2176,1451,2177,1500,2250,1552,2328,1564,2346,1538,2308,}, + {1530,2294,1574,2360,1586,2378,1618,2426,1503,2255,1486,2230,1482,2224,1462,2192,1469,2203,1469,2203,1493,2239,1486,2228,1483,2225,1530,2294,1586,2378,1599,2399,1572,2358,}, + } +}; +#endif diff --git a/drivers/input/touchscreen/synaptics_driver_s1302.c b/drivers/input/touchscreen/synaptics_driver_s1302.c new file mode 100755 index 0000000000000..2b266defec63a --- /dev/null +++ b/drivers/input/touchscreen/synaptics_driver_s1302.c @@ -0,0 +1,1715 @@ +/************************************************************************************ + ** File: - /android/kernel/drivers/input/touchscreen/synaptic_s1302.c + ** VENDOR_EDIT + ** Copyright (C), 2008-2012, OEM Mobile Comm Corp., Ltd + ** + ** Description: + ** touch panel driver for synaptics + ** can change MAX_POINT_NUM value to support multipoint + ** Version: 1.0 + ** Date created: 10:49:46,18/01/2012 + ** Author: Yixue.Ge@BasicDrv.TP + ** + ** --------------------------- Revision History: -------------------------------- + ** + ** chenggang.li@BSP.TP modified for oem 2014-07-30 14005 tp_driver + ************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_FB +#include +#include +#endif + +#include + +#include "synaptics_s1302_redremote.h" +#include "../misc/fpc1020_common.h" +#include +#include +/*------------------------------------------------Global Define--------------------------------------------*/ +#define TP_TEST_ENABLE 1 +#define SYNAPTICS_NAME "synaptics" +#define TPD_DEVICE "synaptics,s1302" +#define LOG_TAG "touchkey,s1302" + +#define SUPPORT_TP_SLEEP_MODE +#define TYPE_B_PROTOCOL //Multi-finger operation +#define TP_FW_NAME_MAX_LEN 128 + +/******************for Red function*****************/ +#define CONFIG_SYNAPTIC_RED + +/*********************for Debug LOG switch*******************/ +#define TPD_ERR(a, arg...) pr_err(LOG_TAG ": " a, ##arg) +#define TPDTM_DMESG(a, arg...) printk(LOG_TAG ": " a, ##arg) + +#define TPD_DEBUG(a,arg...)\ + do{\ + if(tp_debug)\ + pr_err(LOG_TAG ": " a,##arg);\ + }while(0) + +/*---------------------------------------------Global Variable----------------------------------------------*/ + static unsigned int tp_debug = 0; +static int force_update = 0; +static int key_reverse = 0; +static struct synaptics_ts_data *tc_g = NULL; +int test_err = 0; + +/*-----------------------------------------Global Registers----------------------------------------------*/ +static unsigned short SynaF34DataBase; +static unsigned short SynaF34QueryBase; +static unsigned short SynaF01DataBase; +static unsigned short SynaF01CommandBase; + +static unsigned short SynaF34Reflash_BlockNum; +static unsigned short SynaF34Reflash_BlockData; +static unsigned short SynaF34ReflashQuery_BootID; +static unsigned short SynaF34ReflashQuery_FlashPropertyQuery; +static unsigned short SynaF34ReflashQuery_FirmwareBlockSize; +static unsigned short SynaF34ReflashQuery_FirmwareBlockCount; +static unsigned short SynaF34ReflashQuery_ConfigBlockSize; +static unsigned short SynaF34ReflashQuery_ConfigBlockCount; + +static unsigned short SynaFirmwareBlockSize; +static unsigned short SynaF34_FlashControl; + +static int F01_RMI_QUERY_BASE; +static int F01_RMI_CMD_BASE; +static int F01_RMI_CTRL_BASE; +static int F01_RMI_DATA_BASE; + +static int F11_2D_QUERY_BASE; +static int F11_2D_CMD_BASE; +static int F11_2D_CTRL_BASE; +static int F11_2D_DATA_BASE; + +static int F34_FLASH_QUERY_BASE; +static int F34_FLASH_CMD_BASE; +static int F34_FLASH_CTRL_BASE; +static int F34_FLASH_DATA_BASE; + +static int F51_CUSTOM_QUERY_BASE; +static int F51_CUSTOM_CMD_BASE; +static int F51_CUSTOM_CTRL_BASE; +static int F51_CUSTOM_DATA_BASE; + +static int F01_RMI_CTRL01; + +#if TP_TEST_ENABLE +static int F54_ANALOG_QUERY_BASE;//0x73 +static int F54_ANALOG_COMMAND_BASE;//0x72 +static int F54_ANALOG_CONTROL_BASE;//0x0d +static int F54_ANALOG_DATA_BASE;//0x00 +#endif + +/*------------------------------------------Fuction Declare----------------------------------------------*/ +static int synaptics_ts_resume(struct device *dev); +static int synaptics_ts_suspend(struct device *dev); +static int synaptics_ts_remove(struct i2c_client *client); +static int synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id); +static int synapitcs_ts_update(struct i2c_client *client, const uint8_t *data, uint32_t data_len ,bool force); + +static int synaptics_rmi4_i2c_read_block(struct i2c_client* client, + unsigned char addr,unsigned short length,unsigned char *data); + +static int synaptics_rmi4_i2c_write_block(struct i2c_client* client, + unsigned char addr, unsigned short length, unsigned char const *data); + +static int synaptics_rmi4_i2c_read_byte(struct i2c_client* client, + unsigned char addr); + +static int synaptics_rmi4_i2c_write_byte(struct i2c_client* client, + unsigned char addr,unsigned char data); + +static int synaptics_rmi4_i2c_read_word(struct i2c_client* client, + unsigned char addr); + +//static int synaptics_rmi4_i2c_write_word(struct i2c_client* client, +// unsigned char addr,unsigned short data); + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); +#endif +static int synaptics_soft_reset(struct synaptics_ts_data *ts); +static void synaptics_hard_reset(struct synaptics_ts_data *ts); + +/*-------------------------------Using Struct----------------------------------*/ +static const struct i2c_device_id synaptics_ts_id[] = { + { TPD_DEVICE, 0 }, + { } +}; + +static struct of_device_id synaptics_match_table[] = { + { .compatible = TPD_DEVICE,}, + { }, +}; + +static const struct dev_pm_ops synaptic_pm_ops = { +#ifdef CONFIG_PM + .suspend = NULL, + .resume = NULL, +#else + .suspend = NULL, + .resume = NULL, +#endif +}; + +//add by jiachenghui for boot time optimize 2015-5-13 +#ifdef VENDOR_EDIT +static int probe_ret; +struct synaptics_optimize_data{ + struct delayed_work work; + struct workqueue_struct *workqueue; + struct i2c_client *client; + const struct i2c_device_id *dev_id; +}; +static struct synaptics_optimize_data optimize_data; +static void synaptics_ts_probe_func(struct work_struct *w) +{ + struct i2c_client *client_optimize = optimize_data.client; + const struct i2c_device_id *dev_id = optimize_data.dev_id; + TPD_ERR("boot_time: after optimize call [synaptics_ts_probe] on cpu %d\n",smp_processor_id()); + probe_ret = synaptics_ts_probe(client_optimize,dev_id); + TPD_ERR("boot_time: synaptics_ts_probe return %d\n", probe_ret); +} + +static int oem_synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int i; + //unsigned long flags; + //spinlock_t oem_lock; + optimize_data.client = client; + optimize_data.dev_id = id; + optimize_data.workqueue = create_workqueue("tc_probe_optimize"); + INIT_DELAYED_WORK(&(optimize_data.work), synaptics_ts_probe_func); + TPD_ERR("boot_time: before optimize [synaptics_ts_probe] on cpu %d\n",smp_processor_id()); + //spin_lock_irqsave(&oem_lock, flags); + if(get_boot_mode() == MSM_BOOT_MODE__NORMAL) + { + + //get_online_cpus(); + for (i = 0; i <= 3; i++) + { + TPD_ERR("boot_time: [synaptics_ts_probe] CPU%d is %s\n",i,cpu_is_offline(i)?"offline":"online"); + if (cpu_is_offline(i) || i == smp_processor_id()) + { + continue; + } + queue_delayed_work_on(i,optimize_data.workqueue,&(optimize_data.work),msecs_to_jiffies(300)); + //put_online_cpus(); + break; + } + } + else + { + queue_delayed_work_on(0,optimize_data.workqueue,&(optimize_data.work),msecs_to_jiffies(300)); + } + //flush_workqueue(optimize_data.workqueue); + //spin_unlock_irqrestore(&oem_lock, flags); + return probe_ret; +} +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for boot time optimize 2015-5-13 + +static struct i2c_driver tc_i2c_driver = { +//add by jiachenghui for boot time optimize 2015-5-13 +#ifdef VENDOR_EDIT + .probe = oem_synaptics_ts_probe, +#else +//end add by jiachenghui for boot time optimize 2015-5-13 + .probe = synaptics_ts_probe, +#endif /*VENDOR_EDIT*///add by jiachenghui for boot time optimize 2015-5-13 + .remove = synaptics_ts_remove, + .id_table = synaptics_ts_id, + .driver = { + // .owner = THIS_MODULE, + .name = TPD_DEVICE, + .of_match_table = synaptics_match_table, + .pm = &synaptic_pm_ops, + }, +}; + +struct synaptics_ts_data { + struct i2c_client *client; + struct mutex mutex; + int irq; + int irq_gpio; + int reset_gpio; + int en3v_gpio; + int enable_remote; + int pre_btn_state; + int is_suspended; + uint32_t irq_flags; + struct work_struct work; + struct delayed_work speed_up_work; + struct input_dev *input_dev; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#endif + + /******power*******/ + struct regulator *vdd_2v8; + struct regulator *vcc_i2c_1v8; + + /*pinctrl******/ + struct device *dev; + struct pinctrl *pinctrl; + struct pinctrl_state *id_pullup; + struct pinctrl_state *id_pulldown; + + /*******for FW update*******/ + bool suspended; + bool loading_fw; + char fw_name[TP_FW_NAME_MAX_LEN]; + char fw_id[12]; + char manu_name[12]; +}; +/* +static int tc_hw_pwron(struct synaptics_ts_data *ts) +{ + int rc; + + //enable the 2v8 power + if (!IS_ERR(ts->vdd_2v8)) { + rc = regulator_enable(ts->vdd_2v8); + if(rc){ + dev_err(&ts->client->dev, + "Regulator vdd enable failed rc=%d\n", rc); + } + } + + msleep(1); + + if( ts->en3v_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the en3v_gpio\n"); + gpio_direction_output(ts->en3v_gpio, 1); + } + + if (!IS_ERR(ts->vcc_i2c_1v8)) { + rc = regulator_enable( ts->vcc_i2c_1v8 ); + if(rc) { + dev_err(&ts->client->dev, "Regulator vcc_i2c enable failed rc=%d\n", rc); + } + } + msleep(3); + if( ts->reset_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the reset_gpio\n"); + gpio_direction_output(ts->reset_gpio, 1); + } + return rc; +} + +static int tc_hw_pwroff(struct synaptics_ts_data *ts) +{ + int rc = 0; + if( ts->reset_gpio > 0 ) { + TPD_ERR("synaptics:disable the reset_gpio\n"); + gpio_direction_output(ts->reset_gpio, 0); + } + + if (!IS_ERR(ts->vcc_i2c_1v8)) { + rc = regulator_disable( ts->vcc_i2c_1v8 ); + if(rc) { + dev_err(&ts->client->dev, "Regulator vcc_i2c enable failed rc=%d\n", rc); + return rc; + } + } + + if (!IS_ERR(ts->vdd_2v8)) { + rc = regulator_disable(ts->vdd_2v8); + if (rc) { + dev_err(&ts->client->dev, "Regulator vdd disable failed rc=%d\n", rc); + return rc; + } + } + + if( ts->en3v_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the en3v_gpio\n"); + gpio_direction_output(ts->en3v_gpio, 0); + } + return rc; +} + +static int tc_power(struct synaptics_ts_data *ts, unsigned int on) +{ + int ret; + if(on) + ret = tpd_hw_pwron(ts); + else + ret = tpd_hw_pwroff(ts); + + return ret; +} +*/ +static int synaptics_read_register_map(struct synaptics_ts_data *ts) +{ + uint8_t buf[4]; + int ret; + memset(buf, 0, sizeof(buf)); + ret = synaptics_rmi4_i2c_write_byte( ts->client, 0xff, 0x0 ); + if( ret < 0 ){ + TPD_ERR("synaptics_read_register_map: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xDD, 4, &(buf[0x0])); + if( ret < 0 ){ + TPD_ERR("failed for page select!\n"); + return -1; + } + + F11_2D_QUERY_BASE = buf[0]; + F11_2D_CMD_BASE = buf[1]; + F11_2D_CTRL_BASE = buf[2]; + F11_2D_DATA_BASE = buf[3]; + + TPD_ERR("F11_2D_QUERY_BASE = %x \n \ + F11_2D_CMD_BASE = %x \n\ + F11_2D_CTRL_BASE = %x \n\ + F11_2D_DATA_BASE = %x \n\ + ",F11_2D_QUERY_BASE,F11_2D_CMD_BASE,F11_2D_CTRL_BASE,F11_2D_DATA_BASE); + + + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE3, 4, &(buf[0x0])); + F01_RMI_QUERY_BASE = buf[0]; + F01_RMI_CMD_BASE = buf[1]; + F01_RMI_CTRL_BASE = buf[2]; + F01_RMI_DATA_BASE = buf[3]; + TPD_DEBUG("F01_RMI_QUERY_BASE = %x \n\ + F01_RMI_CMD_BASE = %x \n\ + F01_RMI_CTRL_BASE = %x \n\ + F01_RMI_DATA_BASE = %x \n\ + ", F01_RMI_QUERY_BASE, F01_RMI_CMD_BASE, F01_RMI_CTRL_BASE, F01_RMI_DATA_BASE); + + ret = synaptics_rmi4_i2c_read_block( ts->client, 0xE9, 4, &(buf[0x0]) ); + F34_FLASH_QUERY_BASE = buf[0]; + F34_FLASH_CMD_BASE = buf[1]; + F34_FLASH_CTRL_BASE = buf[2]; + F34_FLASH_DATA_BASE = buf[3]; + TPD_DEBUG("F34_FLASH_QUERY_BASE = %x \n\ + F34_FLASH_CMD_BASE = %x \n\ + F34_FLASH_CTRL_BASE = %x \n\ + F34_FLASH_DATA_BASE = %x \n\ + ", F34_FLASH_QUERY_BASE, F34_FLASH_CMD_BASE, F34_FLASH_CTRL_BASE, F34_FLASH_DATA_BASE); + + F01_RMI_CTRL01 = F01_RMI_CTRL_BASE + 1; + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x1); + if( ret < 0 ){ + TPD_DEBUG("synaptics_read_register_map: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE9, 4, &(buf[0x0])); + F51_CUSTOM_QUERY_BASE = buf[0]; + F51_CUSTOM_CMD_BASE = buf[1]; + F51_CUSTOM_CTRL_BASE = buf[2]; + F51_CUSTOM_DATA_BASE = buf[3]; + + TPD_DEBUG("F51_CUSTOM_QUERY_BASE = %x \n\ + F51_CUSTOM_CMD_BASE = %x \n\ + F51_CUSTOM_CTRL_BASE = %x \n\ + F51_CUSTOM_DATA_BASE = %x \n\ + ", F51_CUSTOM_QUERY_BASE, F51_CUSTOM_CMD_BASE, F51_CUSTOM_CTRL_BASE, F51_CUSTOM_DATA_BASE); + +#if TP_TEST_ENABLE + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE9, 4, &(buf[0x0])); + F54_ANALOG_QUERY_BASE = buf[0]; + F54_ANALOG_COMMAND_BASE = buf[1]; + F54_ANALOG_CONTROL_BASE = buf[2]; + F54_ANALOG_DATA_BASE = buf[3]; + TPD_DEBUG("F54_QUERY_BASE = %x \n\ + F54_CMD_BASE = %x \n\ + F54_CTRL_BASE = %x \n\ + F54_DATA_BASE = %x \n\ + ", F54_ANALOG_QUERY_BASE, F54_ANALOG_COMMAND_BASE , F54_ANALOG_CONTROL_BASE, F54_ANALOG_DATA_BASE); +#endif + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00); + return 0; +} + +static int synaptics_read_product_id(struct synaptics_ts_data *ts,char *id) +{ + uint8_t buf[5]={"\n"}; + int ret ; + + memset(buf, 0 , sizeof(buf)); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPD_ERR("synaptics_read_product_id: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0x83, 5, &(buf[0x0])); + if( ret < 0 ){ + TPD_ERR("synaptics_read_product_id error %s\n",&buf[0]); + return -1; + } + memcpy(id,&buf[0],sizeof(buf)); + TPD_ERR("product id is %s\n",&buf[0]); + return 0; +} + +static int synaptics_enable_interrupt(struct synaptics_ts_data *ts, int enable) +{ + int ret; + uint8_t abs_status_int; + + return 0; + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if( ret < 0 ) { + TPDTM_DMESG("%s: select page failed ret = %d\n",__func__, + ret); + return -1; + } + if( enable ) { + abs_status_int = 0x7f; + /*clear interrupt bits for previous touch*/ + ret = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_DATA_BASE+1); + if( ret < 0 ) { + TPDTM_DMESG("%s :clear interrupt bits failed\n",__func__); + return -1; + } + } else { + abs_status_int = 0x0; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client, F01_RMI_CTRL01, abs_status_int); + if( ret < 0 ) { + TPDTM_DMESG("%s: enable or disable abs \ + interrupt failed,abs_int =%d\n", __func__, abs_status_int); + return -1; + } + return 0; +} + +static void delay_qt_ms(unsigned long w_ms) +{ + unsigned long i; + unsigned long j; + for(i = 0; i < w_ms; i++) { + for (j = 0; j < 1000; j++) { + udelay(1); + } + } +} + +static void int_state(struct synaptics_ts_data *ts) +{ + int ret = -1; + return; + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD_BASE, 0x01); + if(ret){ + TPD_ERR("%s:cannot reset touch panel \n",__func__); + return; + } + delay_qt_ms(170); + TPD_DEBUG("%s %d\n",__func__,__LINE__); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CTRL_BASE, 0x80); + if( ret < 0 ){ + TPD_ERR("%s:to wakeup failed\n", __func__); + } + ret = synaptics_enable_interrupt(ts, 1); + if(ret){ + TPD_DEBUG("%s:cannot enable interrupt \n",__func__); + return; + } +} + +//Added for larger than 32 length read! +static int synaptics_rmi4_i2c_read_block(struct i2c_client* client, + unsigned char addr,unsigned short length,unsigned char *data) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + buf = addr & 0xFF; + for( retry = 0; retry < 2; retry++ ) { + if( i2c_transfer(client->adapter, msg, 2) == 2) { + retval = length; + break; + } + msleep(20); + } + if( retry == 2 ) { + dev_err(&client->dev, + "%s: I2C read over retry limit\n", + __func__); + //rst_flag_counter = 1;//reset tp + retval = -5; + } else { + //rst_flag_counter = 0; + } + return retval; +} + +static int synaptics_rmi4_i2c_write_block(struct i2c_client* client, + unsigned char addr, unsigned short length, unsigned char const *data) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + buf[0] = addr & 0xff; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(client->adapter, msg, 1) == 1) { + retval = length; + break; + } + msleep(20); + } + if (retry == 2) { + //rst_flag_counter = 1;//rest tp + retval = -EIO; + } else { + //rst_flag_counter = 0; + } + return retval; +} + +static int synaptics_rmi4_i2c_read_byte(struct i2c_client* client, + unsigned char addr) +{ + int retval = 0; + unsigned char buf[2] = {0}; + retval = synaptics_rmi4_i2c_read_block(client,addr,1,buf); + if(retval >= 0) + retval = buf[0]&0xff; + return retval; +} + +static int synaptics_rmi4_i2c_write_byte(struct i2c_client* client, + unsigned char addr,unsigned char data) +{ + int retval; + unsigned char data_send = data; + retval = synaptics_rmi4_i2c_write_block(client,addr,1,&data_send); + return retval; +} + +static int synaptics_rmi4_i2c_read_word(struct i2c_client* client, + unsigned char addr) +{ + int retval; + unsigned char buf[2] = {0}; + retval = synaptics_rmi4_i2c_read_block(client,addr,2,buf); + if(retval >= 0) + retval = buf[1]<<8|buf[0]; + return retval; +} +/* +static int synaptics_rmi4_i2c_write_word(struct i2c_client* client, + unsigned char addr,unsigned short data) +{ + int retval; + unsigned char buf[2] = {data&0xff,(data>>8)&0xff}; + retval = synaptics_rmi4_i2c_write_block(client,addr,2,buf); + if(retval >= 0) + retval = buf[1]<<8|buf[0]; + return retval; +} +*/ +static char log_count = 0; +#define REP_KEY_MENU (key_reverse?(KEY_BACK):(KEY_MENU)) +#define REP_KEY_BACK (key_reverse?(KEY_MENU):(KEY_BACK)) +static void int_key(struct synaptics_ts_data *ts ) +{ + + int ret; + int button_key; + + if (!nav_switch || !enable_keys) + return; + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x02 ); + if (ret < 0) { + TPD_ERR("%s: Failed to change page 2!!\n", + __func__); + return; + } + + button_key = synaptics_rmi4_i2c_read_byte(ts->client,0x00); + if (6 == (++log_count % 12)) + printk("%s button_key:%d pre_btn_state:%d\n",__func__,button_key,ts->pre_btn_state); + if((button_key & 0x01) && !(ts->pre_btn_state & 0x01))//back + { + input_report_key(ts->input_dev, REP_KEY_BACK, 1); + input_sync(ts->input_dev); + }else if(!(button_key & 0x01) && (ts->pre_btn_state & 0x01)){ + input_report_key(ts->input_dev, REP_KEY_BACK, 0); + input_sync(ts->input_dev); + } + + if((button_key & 0x02) && !(ts->pre_btn_state & 0x02))//menu + { + input_report_key(ts->input_dev, REP_KEY_MENU, 1); + input_sync(ts->input_dev); + }else if(!(button_key & 0x02) && (ts->pre_btn_state & 0x02)){ + input_report_key(ts->input_dev, REP_KEY_MENU, 0); + input_sync(ts->input_dev); + } + + if((button_key & 0x04) && !(ts->pre_btn_state & 0x04))//home + { + input_report_key(ts->input_dev, KEY_HOMEPAGE, 1);//KEY_HOMEPAGE + input_sync(ts->input_dev); + }else if(!(button_key & 0x04) && (ts->pre_btn_state & 0x04)){ + input_report_key(ts->input_dev, KEY_HOMEPAGE, 0); + input_sync(ts->input_dev); + } + + ts->pre_btn_state = button_key & 0x07; + //input_sync(ts->input_dev); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00); + if (ret < 0) { + TPD_ERR("%s: Failed to change page 2!!\n", + __func__); + return; + } + return; +} + +static void synaptics_ts_report(struct synaptics_ts_data *ts ) +{ + int ret; + uint8_t status = 0; + uint8_t inte = 0; + if( ts->enable_remote) { + goto END; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00 ); + ret = synaptics_rmi4_i2c_read_word(ts->client, 0x13); + + if( ret < 0 ) { + TPDTM_DMESG("Synaptic:ret = %d\n", ret); + synaptics_hard_reset(ts); + goto END; + } + status = ret & 0xff; + inte = (ret & 0x7f00)>>8; + if(status) { + int_state(ts); + //goto END; + } + if( inte & 0x10) { + int_key(ts); + } +END: + return; +} +static irqreturn_t synaptics_irq_thread_fn(int irq, void *dev_id) +{ + struct synaptics_ts_data *ts = (struct synaptics_ts_data *)dev_id; + mutex_lock(&ts->mutex); + synaptics_ts_report(ts); + mutex_unlock(&ts->mutex); + return IRQ_HANDLED; +} + +static int synaptics_input_init(struct synaptics_ts_data *ts) +{ + int ret = 0; + + TPD_DEBUG("%s is called\n",__func__); + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("synaptics_ts_probe: Failed to allocate input device\n"); + return ret; + } + ts->input_dev->name = SYNAPTICS_NAME; + ts->input_dev->dev.parent = &ts->client->dev; + set_bit(EV_SYN, ts->input_dev->evbit); + set_bit(EV_KEY, ts->input_dev->evbit); + set_bit(KEY_BACK, ts->input_dev->keybit); + set_bit(KEY_MENU, ts->input_dev->keybit); + set_bit(KEY_HOMEPAGE, ts->input_dev->keybit); + input_set_drvdata(ts->input_dev, ts); + + if(input_register_device(ts->input_dev)) { + TPD_ERR("%s: Failed to register input device\n",__func__); + input_unregister_device(ts->input_dev); + input_free_device(ts->input_dev); + return -1; + } + return 0; +} + +/*********************FW Update Func******************************************/ +static int synatpitcs_fw_update(struct device *dev, bool force) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + const struct firmware *fw = NULL; + int ret; + char fw_id_temp[12]; + uint8_t buf[4]; + uint32_t CURRENT_FIRMWARE_ID = 0 ; + + TPD_DEBUG("%s is called\n",__func__); + + if(!ts->client) { + TPD_ERR("i2c client point is NULL\n"); + return 0; + } + ret = request_firmware(&fw, ts->fw_name, dev); + if (ret < 0) { + TPD_ERR("Request firmware failed - %s (%d)\n", + ts->fw_name, ret); + return ret; + } + ret = synapitcs_ts_update(ts->client, fw->data, fw->size, force); + if(ret < 0){ + TPD_ERR("FW update not success try again\n"); + ret = synapitcs_ts_update(ts->client, fw->data, fw->size, force); + if(ret < 0){ + TPD_ERR("FW update failed twice, quit updating process!\n"); + return ret; + } + } + release_firmware(fw); + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + ret = synaptics_rmi4_i2c_read_block(ts->client, F34_FLASH_CTRL_BASE, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3]; + sprintf(fw_id_temp,"0x%x",CURRENT_FIRMWARE_ID); + strcpy(ts->fw_id,fw_id_temp); + synaptics_enable_interrupt(ts,1); + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_mt_sync(ts->input_dev); + input_sync(ts->input_dev); + return 0; +} + +static int synaptics_s1302_fw_show(struct seq_file *seq, void *offset) +{ + struct synaptics_ts_data *ts = tc_g; + seq_printf(seq, "\ + synaptics ic type is %s\n\ + firmware name is %s\n\ + firmware version is %s\n\ + is update firmware state: %s\n",\ + ts->manu_name,ts->fw_name,ts->fw_id,\ + (ts->loading_fw)?("loading..."):("no update")); + return 0; +} +static ssize_t synaptics_s1302_fw_write(struct file *file, const char __user *page, size_t t, loff_t *lo) +{ + int val = 0; + + if (NULL == tc_g) + return -EINVAL; + TPD_ERR("start update ******* fw_name:%s\n",tc_g->fw_name); + if (t > 2) + return -EINVAL; + + sscanf(page, "%d", &val); + + if(!val) + val = force_update; + + disable_irq_nosync(tc_g->irq); + mutex_lock(&tc_g->mutex); + tc_g->loading_fw = true; + synatpitcs_fw_update(tc_g->dev, val); + tc_g->loading_fw = false; + mutex_unlock(&tc_g->mutex); + enable_irq(tc_g->irq); + force_update = 0; + return t; +} +static int synaptics_s1302_fw_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_s1302_fw_show, inode->i_private); +} +const struct file_operations proc_firmware_update = +{ + .owner = THIS_MODULE, + .open = synaptics_s1302_fw_open, + .read = seq_read, + .write = synaptics_s1302_fw_write, + .llseek = seq_lseek, + .release = single_release, +}; +static ssize_t synaptics_s1302_key_reverse_write(struct file *file, const char __user *page, size_t t, loff_t *lo) +{ + int ret = 0; + char buf[10]; + + if( t > 2) + return t; + if( copy_from_user(buf, page, t) ){ + TPD_ERR("%s: read proc input error.\n", __func__); + return t; + } + + sscanf(buf, "%d", &ret); + TPD_ERR("%s key_reverse:%d\n",__func__,ret); + if( (ret == 0 )||(ret == 1) ) + { + key_reverse = ret; + } + return t; +} +static int synaptics_s1302_key_reverse_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n",key_reverse); + return 0 ; +} +static int synaptics_s1302_key_reverse_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_s1302_key_reverse_show, inode->i_private); +} +const struct file_operations proc_reverse_key = +{ + .owner = THIS_MODULE, + .open = synaptics_s1302_key_reverse_open, + .read = seq_read, + .write = synaptics_s1302_key_reverse_write, + .llseek = seq_lseek, + .release = single_release, +}; +static int page ,address,block; +static int synaptics_s1302_radd_show(struct seq_file *seq, void *offset) +{ + int ret; + char buffer[256]; + int i; + + struct synaptics_ts_data *ts = tc_g; + printk("%s page=0x%x,address=0x%x,block=0x%x\n",__func__,page,address,block); + ret = synaptics_rmi4_i2c_write_byte(ts->client,0xff,page); + ret = synaptics_rmi4_i2c_read_block(ts->client,address,block,buffer); + for (i=0;i < block;i++) + { + printk("buffer[%d]=0x%x\n",i,buffer[i]); + } + seq_printf(seq,"page:0x%x;address:0x%x;buff[%d]:[0]0x%x,[1]0x%x,[2]0x%x,[3]0x%x\n",\ + page,address,block,buffer[0],buffer[1],buffer[2],buffer[3]); + return 0; +} + +static ssize_t synaptics_s1302_radd_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + int buf[128]; + int ret,i; + struct synaptics_ts_data *ts = tc_g; + int temp_block,wbyte; + char reg[30]; + + ret = sscanf(buffer,"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",\ + &buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6],&buf[7],&buf[8],&buf[9],\ + &buf[10],&buf[11],&buf[12],&buf[13],&buf[14],&buf[15],&buf[16],&buf[17]); + for (i = 0;i < ret;i++) + { + printk("buf[i]=0x%x,",buf[i]); + } + printk("\n"); + page= buf[0]; + address = buf[1]; + temp_block = buf[2]; + wbyte = buf[3]; + if (0xFF == temp_block)//the mark is to write register else read register + { + for (i=0;i < wbyte;i++) + { + reg[i] = (char)buf[4+i]; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client,0xff,page); + ret = synaptics_rmi4_i2c_write_block(ts->client,(char)address,wbyte,reg); + printk("%s write page=0x%x,address=0x%x\n",__func__,page,address); + for (i=0;i < wbyte;i++) + { + printk("reg=0x%x\n",reg[i]); + } + } + else + block = temp_block; + return count; +} +static int synaptics_s1302_radd_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_s1302_radd_show, inode->i_private); +} +const struct file_operations proc_radd = +{ + .owner = THIS_MODULE, + .open = synaptics_s1302_radd_open, + .read = seq_read, + .write = synaptics_s1302_radd_write, + .llseek = seq_lseek, + .release = single_release, +}; +static ssize_t synaptics_s1302_reset_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + int ret,write_flag; + struct synaptics_ts_data *ts = tc_g; + + if(ts->loading_fw) { + TPD_ERR("%s FW is updating break!!\n",__func__); + return count; + } + + ret = sscanf(buffer,"%x",&write_flag); + TPD_ERR("%s write %d\n",__func__,write_flag); + if (1 == write_flag) + { + ret = synaptics_soft_reset(ts); + } + else if(2 == write_flag) + { + synaptics_hard_reset(ts); + } + return count; +} +static int synaptics_s1302_reset_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n",test_err); + return 0 ; +} + +static int synaptics_s1302_reset_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_s1302_reset_show, inode->i_private); +} + +const struct file_operations proc_reset = +{ + .owner = THIS_MODULE, + .open = synaptics_s1302_reset_open, + .read = seq_read, + .write = synaptics_s1302_reset_write, + .llseek = seq_lseek, + .release = single_release, +}; +static ssize_t synaptics_s1302_debug_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + int ret,write_flag; + + ret = sscanf(buffer,"%x",&write_flag); + TPD_ERR("%s write %d\n",__func__,write_flag); + tp_debug = write_flag?1:0; + return count; +} +static int synaptics_s1302_debug_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "s1302 debug log is %s!\n",tp_debug?"on":"off"); + return 0 ; +} + +static int synaptics_s1302_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_s1302_debug_show, inode->i_private); +} + +const struct file_operations proc_debug = +{ + .owner = THIS_MODULE, + .open = synaptics_s1302_debug_open, + .read = seq_read, + .write = synaptics_s1302_debug_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int synaptics_s1302_proc(void) +{ + struct proc_dir_entry *proc_entry=0; + + struct proc_dir_entry *procdir = proc_mkdir( "s1302", NULL ); + //for firmware version + proc_entry = proc_create_data("fw_update", 0444, procdir,&proc_firmware_update,NULL); + proc_entry = proc_create_data("key_rep", 0666, procdir,&proc_reverse_key,NULL); + proc_entry = proc_create_data("radd", 0666, procdir,&proc_radd,NULL); + proc_entry = proc_create_data("reset", 0666, procdir,&proc_reset,NULL); + proc_entry = proc_create_data("debug", 0666, procdir,&proc_debug,NULL); + TPD_ERR("create nodes is successe!\n"); + + return 0; +} +/******************************end****************************/ + +/****************************S3203*****update**********************************/ +#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10 +#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 + +static void re_scan_PDT(struct i2c_client *client) +{ + uint8_t buf[8]; + i2c_smbus_read_i2c_block_data(client, 0xE9, 6, buf); + SynaF34DataBase = buf[3]; + SynaF34QueryBase = buf[0]; + i2c_smbus_read_i2c_block_data(client, 0xE3, 6, buf); + SynaF01DataBase = buf[3]; + SynaF01CommandBase = buf[1]; + i2c_smbus_read_i2c_block_data(client, 0xDD, 6, buf); + + SynaF34Reflash_BlockNum = SynaF34DataBase; + SynaF34Reflash_BlockData = SynaF34DataBase + 2; + SynaF34ReflashQuery_BootID = SynaF34QueryBase; + SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 2; + SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 3; + SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase +5; + SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 7; + SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 9; + i2c_smbus_read_i2c_block_data(client, SynaF34ReflashQuery_FirmwareBlockSize, 2, buf); + SynaFirmwareBlockSize = buf[0] | (buf[1] << 8); + TPD_DEBUG("SynaFirmwareBlockSize s1302 is %d\n", SynaFirmwareBlockSize); + SynaF34_FlashControl = SynaF34DataBase + 0x12; +} +struct image_header { + /* 0x00 - 0x0f */ + unsigned char checksum[4]; + unsigned char reserved_04; + unsigned char reserved_05; + unsigned char options_firmware_id:1; + unsigned char options_contain_bootloader:1; + unsigned char options_reserved:6; + unsigned char bootloader_version; + unsigned char firmware_size[4]; + unsigned char config_size[4]; + /* 0x10 - 0x1f */ + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE]; + unsigned char package_id[2]; + unsigned char package_id_revision[2]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; + /* 0x20 - 0x2f */ + unsigned char reserved_20_2f[16]; + /* 0x30 - 0x3f */ + unsigned char ds_id[16]; + /* 0x40 - 0x4f */ + unsigned char ds_info[10]; + unsigned char reserved_4a_4f[6]; + /* 0x50 - 0x53 */ + unsigned char firmware_id[4]; +}; + +struct image_header_data { + bool contains_firmware_id; + unsigned int firmware_id; + unsigned int checksum; + unsigned int firmware_size; + unsigned int config_size; + unsigned char bootloader_version; + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; +}; + +static unsigned int extract_uint_le(const unsigned char *ptr) +{ + return (unsigned int)ptr[0] + + (unsigned int)ptr[1] * 0x100 + + (unsigned int)ptr[2] * 0x10000 + + (unsigned int)ptr[3] * 0x1000000; +} + +static void parse_header(struct image_header_data *header, + const unsigned char *fw_image) +{ + struct image_header *data = (struct image_header *)fw_image; + + header->checksum = extract_uint_le(data->checksum); + TPD_DEBUG(" debug checksume is 0x%x\n", header->checksum); + header->bootloader_version = data->bootloader_version; + TPD_DEBUG(" debug bootloader_version is %d\n", header->bootloader_version); + + header->firmware_size = extract_uint_le(data->firmware_size); + TPD_DEBUG(" debug firmware_size is 0x%x\n", header->firmware_size); + + header->config_size = extract_uint_le(data->config_size); + TPD_DEBUG(" debug header->config_size is 0x%x\n", header->config_size); + + memcpy(header->product_id, data->product_id, sizeof(data->product_id)); + header->product_id[sizeof(data->product_id)] = 0; + + memcpy(header->product_info, data->product_info, + sizeof(data->product_info)); + + header->contains_firmware_id = data->options_firmware_id; + TPD_DEBUG(" debug header->contains_firmware_id is %x\n", header->contains_firmware_id); + if( header->contains_firmware_id ) + header->firmware_id = extract_uint_le(data->firmware_id); + + return; +} + +static int checkFlashState(struct i2c_client *client) +{ + int ret ; + int count = 0; + ret = synaptics_rmi4_i2c_read_byte(client,SynaF34_FlashControl); + while ( (ret != 0x80)&&(count < 8) ) { + msleep(3); //wait 3ms + ret = synaptics_rmi4_i2c_read_byte(client,SynaF34_FlashControl); + count++; + } + if(count == 8) + return 1; + else + return 0; +} + +static int synaptics_fw_check(struct synaptics_ts_data *ts ) +{ + int ret; + uint8_t buf[5]; + uint32_t bootloader_mode; + + if(!ts){ + TPD_ERR("%s ts is NULL\n",__func__); + return -1; + } + + ret = synaptics_enable_interrupt(ts, 0); + if(ret < 0) { + TPDTM_DMESG(" synaptics_ts_probe: disable interrupt failed\n"); + } + + /*read product id */ + ret = synaptics_read_product_id(ts,&buf[0]); + if(ret) { + TPD_ERR("failed to read product info \n"); + return -1; + } + + bootloader_mode = synaptics_rmi4_i2c_read_byte(ts->client,F01_RMI_DATA_BASE); + bootloader_mode = bootloader_mode&0xff; + bootloader_mode = bootloader_mode&0x40; + TPD_DEBUG("afte fw update,program memory self-check bootloader_mode = 0x%x\n",bootloader_mode); + + if(bootloader_mode == 0x40) { + TPD_ERR("Something terrible wrong \n Trying Update the Firmware again\n"); + return -1; + } + return 0; +} + +static int synapitcs_ts_update(struct i2c_client *client, const uint8_t *data, uint32_t data_len ,bool force) +{ + int ret,j; + uint8_t buf[8]; + uint8_t bootloder_id[10]; + uint16_t block,firmware,configuration; + uint32_t CURRENT_FIRMWARE_ID = 0 , FIRMWARE_ID = 0; + const uint8_t *Config_Data = NULL; + const uint8_t *Firmware_Data = NULL; + struct image_header_data header; + struct synaptics_ts_data *ts = dev_get_drvdata(&client->dev); + + TPD_DEBUG("%s is called\n",__func__); + if(!client) + return -1; + + parse_header(&header,data); + if((header.firmware_size + header.config_size + 0x100) > data_len) { + TPDTM_DMESG("firmware_size + config_size + 0x100 > data_len data_len = %d \n",data_len); + return -1; + } + + Firmware_Data = data + 0x100; + Config_Data = Firmware_Data + header.firmware_size; + ret = synaptics_rmi4_i2c_write_byte(client, 0xff, 0x0); + + ret = synaptics_rmi4_i2c_read_block(client, F34_FLASH_CTRL_BASE, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3]; + FIRMWARE_ID = (Config_Data[0]<<24)|(Config_Data[1]<<16)|(Config_Data[2]<<8)|Config_Data[3]; + TPD_ERR("CURRENT_FIRMWARE_ID is %x-----------, FIRMWARE_ID is %x-----------\n", CURRENT_FIRMWARE_ID, FIRMWARE_ID); + //TPD_ERR("synaptics force is %d\n", force); + if(!force) { + if(CURRENT_FIRMWARE_ID == FIRMWARE_ID) { + return 0; + } + } + re_scan_PDT(client); + block = 16; + TPD_DEBUG("block is %d \n",block); + firmware = (header.firmware_size)/16; + TPD_DEBUG("firmware is %d \n",firmware); + configuration = (header.config_size)/16; + TPD_DEBUG("configuration is %d \n",configuration); + + + ret = i2c_smbus_read_i2c_block_data(client, SynaF34ReflashQuery_BootID, 8, &(bootloder_id[0])); + TPD_DEBUG("bootloader id is %x \n",(bootloder_id[1] << 8)|bootloder_id[0]); + ret=i2c_smbus_write_i2c_block_data(client, SynaF34Reflash_BlockData, 2, &(bootloder_id[0x0])); + TPDTM_DMESG("Write bootloader id SynaF34_FlashControl is 0x00%x ret is %d\n",SynaF34_FlashControl,ret); + + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x0F); + msleep(10); + TPD_DEBUG("attn step 4 SynaF34_FlashControl:0x%x\n",SynaF34_FlashControl); + ret=checkFlashState(client); + if(ret > 0) { + TPD_ERR("Get in prog:The status(Image) of flashstate is %x\n",ret); + return -1; + } + ret = i2c_smbus_read_byte_data(client,0x04); + TPD_DEBUG("The status(device state) is %x\n",ret); + ret= i2c_smbus_read_byte_data(client,F01_RMI_CTRL_BASE); + TPD_DEBUG("The status(control f01_RMI_CTRL_DATA) is %x\n",ret); + ret= i2c_smbus_write_byte_data(client,F01_RMI_CTRL_BASE,ret|0x04); + /********************get into prog end************/ + ret=i2c_smbus_write_i2c_block_data(client, SynaF34Reflash_BlockData, 2, &(bootloder_id[0x0])); + TPD_DEBUG("ret is %d\n",ret); + re_scan_PDT(client); + i2c_smbus_read_i2c_block_data(client,SynaF34ReflashQuery_BootID,2,buf); + i2c_smbus_write_i2c_block_data(client,SynaF34Reflash_BlockData,2,buf); + i2c_smbus_write_byte_data(client,SynaF34_FlashControl,0x03); + msleep(1500); + ret = i2c_smbus_read_byte_data(client,SynaF34_FlashControl); + TPDTM_DMESG("going to flash firmware area synaF34_FlashControl %d\n",ret); + + TPD_ERR("update-----------------firmware ------------------update!\n"); + TPD_DEBUG("cnt %d\n",firmware); + for(j=0; j>8; + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockNum,2,buf); + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockData,16,&Firmware_Data[j*16]); + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x02); + ret=checkFlashState(client); + if(ret > 0) { + TPD_ERR("Firmware:The status(Image) of flash data3 is %x,time =%d\n",ret,j); + return -1; + } + } + //step 7 configure data + //TPD_ERR("going to flash configuration area\n"); + //TPD_ERR("header.firmware_size is 0x%x\n", header.firmware_size); + //TPD_ERR("bootloader_size is 0x%x\n", bootloader_size); + TPD_ERR("update-----------------configuration ------------------update!\n"); + for(j=0;j>8; + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockNum,2,buf); + //b) write data + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockData,16,&Config_Data[j*16]); + //c) issue write + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x06); + //d) wait attn + ret = checkFlashState(client); + if(ret > 0) { + TPD_ERR("Configuration:The status(Image) of flash data3 is %x,time =%d\n",ret,j); + return -1; + } + } + + //step 1 issue reset + synaptics_rmi4_i2c_write_byte(client,SynaF01CommandBase,0x01); + //step2 wait ATTN + //delay_qt_ms(1000); + mdelay(1500); + synaptics_read_register_map(ts); + //FW flash check! + ret =synaptics_fw_check(ts); + if(ret < 0 ) { + TPD_ERR("Firmware self check failed\n"); + return -1; + } + TPD_DEBUG("Firmware self check Ok\n"); + return 0; +} +static int synaptics_soft_reset(struct synaptics_ts_data *ts) +{ + int ret; + + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD_BASE, 0x01); + if (ret < 0){ + TPD_ERR("reset error ret=%d\n",ret); + } + TPD_ERR("%s !!!\n",__func__); + return ret; +} +static void synaptics_hard_reset(struct synaptics_ts_data *ts) +{ + return; //WAR 1302 hw error[RST short issue] + if(ts->reset_gpio > 0) + { + gpio_set_value(ts->reset_gpio,0); + msleep(5); + gpio_set_value(ts->reset_gpio,1); + msleep(100); + TPD_ERR("%s !!!\n",__func__); + } + +} +static int synaptics_parse_dts(struct device *dev, struct synaptics_ts_data *ts) +{ + int rc; + int retval; + struct device_node *np; + + np = dev->of_node; + ts->irq_gpio = of_get_named_gpio_flags(np, "synaptics,irq-gpio", 0, &(ts->irq_flags)); + if( ts->irq_gpio < 0 ){ + TPD_DEBUG("ts->irq_gpio not specified\n"); + } + + ts->reset_gpio = of_get_named_gpio(np, "synaptics,reset-gpio", 0); + if( ts->reset_gpio < 0 ){ + TPD_DEBUG("ts->reset-gpio not specified\n"); + } + ts->en3v_gpio = of_get_named_gpio(np, "synaptics,en3v_gpio", 0); + if( ts->en3v_gpio < 0 ){ + TPD_DEBUG("ts->en3v_gpio not specified\n"); + } + + /***********power regulator_get****************/ + /* + ts->vdd_2v8 = regulator_get(&ts->client->dev, "vdd_2v8"); + if( IS_ERR(ts->vdd_2v8) ){ + rc = PTR_ERR(ts->vdd_2v8); + TPD_DEBUG("Regulator get failed vdd rc=%d\n", rc); + } + + ts->vcc_i2c_1v8 = regulator_get(&ts->client->dev, "vcc_i2c_1v8"); + if( IS_ERR(ts->vcc_i2c_1v8) ){ + rc = PTR_ERR(ts->vcc_i2c_1v8); + TPD_DEBUG("Regulator get failed vcc_i2c rc=%d\n", rc); + } + + if( ts->reset_gpio > 0){ + if( gpio_is_valid(ts->reset_gpio) ){ + rc = gpio_request(ts->reset_gpio, "tp-s1302-reset"); + if(rc){ + TPD_ERR("unable to request gpio [%d]\n", ts->reset_gpio); + } + } + } + */ + + if( ts->reset_gpio > 0){ + if( gpio_is_valid(ts->reset_gpio) ){ + rc = gpio_request(ts->reset_gpio, "s1302_reset"); + if(rc) + TPD_ERR("unable to request gpio [%d]\n", ts->reset_gpio); + retval = gpio_direction_input(ts->reset_gpio); + } + } + if( ts->en3v_gpio > 0){ + if( gpio_is_valid(ts->en3v_gpio) ){ + rc = gpio_request(ts->en3v_gpio, "s1302_en3v"); + if(rc) + TPD_ERR("unable to request gpio [%d]\n", ts->en3v_gpio); + retval = gpio_direction_output(ts->en3v_gpio,1); + } + } + return rc; +} +static int synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ +#ifdef CONFIG_SYNAPTIC_RED + struct remotepanel_data *premote_data = NULL; +#endif + struct synaptics_ts_data *ts = NULL; + int ret = -1; + uint8_t buf[4]; + uint32_t CURRENT_FIRMWARE_ID = 0; + uint32_t bootloader_mode; + + TPD_ERR("%s is called\n",__func__); + + ts = kzalloc(sizeof(struct synaptics_ts_data), GFP_KERNEL); + if( ts == NULL ) { + ret = -ENOMEM; + goto err_alloc_data_failed; + } + + ts->client = client; + i2c_set_clientdata(client, ts); + ts->dev = &client->dev; + ts->loading_fw = false; + tc_g = ts; + + synaptics_parse_dts(&client->dev, ts); + + mutex_init(&ts->mutex); + synaptics_s1302_proc(); + ts->is_suspended = 0; + + if( !i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ){ + TPD_ERR("%s: need I2C_FUNC_I2C\n", __func__); + ret = -ENODEV; + goto err_check_functionality_failed; + } + ret = synaptics_read_product_id(ts,ts->manu_name); + if( ret < 0 ) { + test_err = 1; + synaptics_hard_reset(ts); + ret = synaptics_read_product_id(ts,ts->manu_name); + if( ret < 0 ) { + TPD_ERR("synaptics is no exist!\n"); + goto err_check_functionality_failed; + } + } + + synaptics_read_register_map(ts); + synaptics_rmi4_i2c_read_block(ts->client, F34_FLASH_CTRL_BASE, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + TPD_ERR("CURRENT_FIRMWARE_ID = 0x%x\n", CURRENT_FIRMWARE_ID); + sprintf(ts->fw_id,"0x%x",CURRENT_FIRMWARE_ID); + + memset(ts->fw_name,TP_FW_NAME_MAX_LEN,0); + strcpy(ts->fw_name,"tp/14049/14049_FW_S1302.img"); + TPD_DEBUG("synatpitcs_fw: fw_name = %s \n",ts->fw_name); + + push_component_info(TOUCH_KEY, ts->fw_id, ts->manu_name); + + bootloader_mode = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_DATA_BASE); + bootloader_mode = bootloader_mode&0x40; + TPD_ERR("before fw update,bootloader_mode = 0x%x\n", bootloader_mode); + if(0x40 == bootloader_mode){ + force_update = 1; + TPD_ERR("This FW need to be updated!\n"); + } else { + force_update = 0; + } + + ret = synaptics_input_init(ts); + if(ret < 0) { + TPD_ERR("synaptics_input_init failed!\n"); + } +#if defined(CONFIG_FB) + ts->suspended = 0; + ts->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); + if(ret) + TPD_ERR("Unable to register fb_notifier: %d\n", ret); +#endif + if (gpio_is_valid(ts->irq_gpio)) { + /* configure touchscreen irq gpio */ + ret = gpio_request(ts->irq_gpio,"s1302_int"); + if (ret) { + TPD_ERR("unable to request gpio [%d]\n",ts->irq_gpio); + } + ret = gpio_direction_input(ts->irq_gpio); + msleep(50); + ts->irq = gpio_to_irq(ts->irq_gpio); + } + TPD_ERR("synaptic:ts->irq is %d\n",ts->irq); + ret = request_threaded_irq(ts->irq, NULL, + synaptics_irq_thread_fn, + ts->irq_flags | IRQF_ONESHOT, + TPD_DEVICE, ts); + if(ret < 0) + TPD_ERR("%s request_threaded_irq ret is %d\n",__func__,ret); + + ret = synaptics_soft_reset(ts); + if (ret < 0){ + TPD_ERR("%s faile to reset device\n",__func__); + } + ret = synaptics_enable_interrupt(ts, 1); + if(ret < 0) + TPD_ERR("%s enable interrupt error ret=%d\n",__func__,ret); + +#ifdef CONFIG_SYNAPTIC_RED + premote_data = remote_alloc_panel_data_s1302(); + if(premote_data) { + premote_data->client = client; + premote_data->input_dev = ts->input_dev; + premote_data->pmutex = &ts->mutex; + premote_data->irq_gpio = ts->irq_gpio; + premote_data->irq = client->irq; + premote_data->enable_remote = &(ts->enable_remote); + register_remote_device_s1302(premote_data); + } +#endif + TPDTM_DMESG("synaptics_ts_probe s1302: normal end\n"); + return 0; + +err_check_functionality_failed: +err_alloc_data_failed: + kfree(ts); + ts = NULL; + tc_g = NULL; + printk("touchkey,s1302 probe: not normal end\n"); + return ret; +} + +static int synaptics_ts_remove(struct i2c_client *client) +{ + struct synaptics_ts_data *ts = i2c_get_clientdata(client); + + printk("touchkey,s1302 %s is called\n",__func__); +#ifdef CONFIG_SYNAPTIC_RED + unregister_remote_device_s1302(); +#endif + +#if defined(CONFIG_FB) + if( fb_unregister_client(&ts->fb_notif) ) + dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); +#endif + input_unregister_device(ts->input_dev); + input_free_device(ts->input_dev); + kfree(ts); + return 0; +} + +static int synaptics_ts_suspend(struct device *dev) +{ + int ret; + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + TPD_DEBUG("%s: is called\n", __func__); + + if(ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("input_dev registration is not complete\n"); + return -1; + } + if(ts->loading_fw) { + TPD_ERR("FW is updating while suspending"); + return -1; + } + ts->is_suspended = 1; + disable_irq_nosync(ts->irq); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CTRL_BASE, 0x81); + if( ret < 0 ){ + TPD_ERR("%s to sleep failed\n", __func__); + return -1; + } + TPD_DEBUG("%s:normal end\n", __func__); + return 0; +} + +static int synaptics_ts_resume(struct device *dev) +{ + int ret; + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + + TPD_DEBUG("%s is called\n", __func__); + if(ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("input_dev registration is not complete\n"); + goto ERR_RESUME; + } + + ts->is_suspended = 0; + mutex_lock(&ts->mutex); + + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPD_ERR("%s: failed for page select try again later\n", __func__); + msleep(20); + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPD_ERR("%s: failed for page select try again later\n", __func__); + } + } + + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CTRL_BASE, 0x80); + if( ret < 0 ){ + TPD_ERR("%s:to wakeup failed\n", __func__); + goto ERR_RESUME; + } + enable_irq(ts->irq); + TPD_DEBUG("%s:normal end!\n", __func__); +ERR_RESUME: + mutex_unlock(&ts->mutex); + return 0; +} + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + + struct synaptics_ts_data *ts = container_of(self, struct synaptics_ts_data, fb_notif); + + if(FB_EVENT_BLANK != event) + return 0; + if((evdata) && (evdata->data) && (ts) && (ts->client)&&(event == FB_EVENT_BLANK)) { + blank = evdata->data; + if( *blank == FB_BLANK_UNBLANK) { + TPD_DEBUG("%s going TP resume\n", __func__); + if(ts->suspended == 1){ + synaptics_ts_resume(&ts->client->dev); + ts->suspended = 0; + } + + } else if( *blank == FB_BLANK_POWERDOWN) { + TPD_DEBUG("%s : going TP suspend\n", __func__); + if(ts->suspended == 0) { + ts->suspended = 1; + synaptics_ts_suspend(&ts->client->dev); + } + } + } + return 0; +} +#endif + +static int __init tc_driver_init(void) +{ + if( i2c_add_driver(&tc_i2c_driver)!= 0 ){ + TPD_ERR("unable to add i2c driver.\n"); + return -1; + } + return 0; +} + +/* should never be called */ +static void __exit tc_driver_exit(void) +{ + i2c_del_driver(&tc_i2c_driver); + return; +} + +module_init(tc_driver_init); +module_exit(tc_driver_exit); + +MODULE_DESCRIPTION("Synaptics S1302 Touchscreen Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_driver_s3320.c b/drivers/input/touchscreen/synaptics_driver_s3320.c new file mode 100755 index 0000000000000..39ee70841db9f --- /dev/null +++ b/drivers/input/touchscreen/synaptics_driver_s3320.c @@ -0,0 +1,3730 @@ +/************************************************************************************ + ** File: - /android/kernel/drivers/input/touchscreen/synaptic_s3320.c + ** VENDOR_EDIT + ** Copyright (C), 2008-2012, OEM Mobile Comm Corp., Ltd + ** + ** Description: + ** touch panel driver for synaptics + ** can change MAX_POINT_NUM value to support multipoint + ** Version: 1.0 + ** Date created: 10:49:46,18/01/2012 + ** Author: Yixue.Ge@BasicDrv.TP + ** + ** --------------------------- Revision History: -------------------------------- + ** + ** chenggang.li@BSP.TP modified for oem 2014-07-30 14005 tp_driver + ************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_FB +#include +#include +#endif + +#include + +#include "synaptics_redremote.h" +#include +#include +#include "synaptics_baseline.h" +/*------------------------------------------------Global Define--------------------------------------------*/ + +#define TP_UNKNOWN 0 +#define TP_G2Y 1 +#define TP_TPK 2 +#define TP_TRULY 3 +#define TP_OFILM 4 +#define TP_JDI_TPK 6 +#define TP_TEST_ENABLE 1 + +#define DiagonalUpperLimit 1100 +#define DiagonalLowerLimit 900 + +#define PAGESIZE 512 +#define TPD_USE_EINT + +#define SYNAPTICS_NAME "synaptics_gestures" +#define TPD_DEVICE "synaptics,s3320" + +//#define SUPPORT_SLEEP_POWEROFF +#define SUPPORT_GESTURE +#define RESET_ONESECOND +//#define SUPPORT_GLOVES_MODE + +#define SUPPORT_TP_SLEEP_MODE +#define TYPE_B_PROTOCOL //Multi-finger operation +#define TP_FW_NAME_MAX_LEN 128 + +#define TEST_MAGIC1 0x494D494C +#define TEST_MAGIC2 0x474D4954 + +struct test_header { + unsigned int magic1; + unsigned int magic2; + unsigned int withCBC; + unsigned int array_limit_offset; + unsigned int array_limit_size; + unsigned int array_limitcbc_offset; + unsigned int array_limitcbc_size; +}; + +/******************for Red function*****************/ +#define CONFIG_SYNAPTIC_RED + +/*********************for gesture*******************/ +#ifdef SUPPORT_GESTURE +#define ENABLE_UNICODE 0x40 +#define ENABLE_VEE 0x20 +#define ENABLE_CIRCLE 0x08 +#define ENABLE_SWIPE 0x02 +#define ENABLE_DTAP 0x01 + +#define UNICODE_DETECT 0x0b +#define VEE_DETECT 0x0a +#define CIRCLE_DETECT 0x08 +#define SWIPE_DETECT 0x07 +#define DTAP_DETECT 0x03 + + +#define UnkownGestrue 0 +#define DouTap 1 // double tap +#define UpVee 2 // V +#define DownVee 3 // ^ +#define LeftVee 4 // > +#define RightVee 5 // < +#define Circle 6 // O +#define DouSwip 7 // || +#define Left2RightSwip 8 // --> +#define Right2LeftSwip 9 // <-- +#define Up2DownSwip 10 // |v +#define Down2UpSwip 11 // |^ +#define Mgestrue 12 // M +#define Wgestrue 13 // W + +// carlo@oneplus.net 2015-05-25, begin. +#ifdef VENDOR_EDIT +#define KEY_DOUBLE_TAP 249 // double tap to wake +#define KEY_GESTURE_CIRCLE 250 // draw circle to lunch camera +#define KEY_GESTURE_TWO_SWIPE 251 // swipe two finger vertically to play/pause +#define KEY_GESTURE_V 252 // draw v to toggle flashlight +#define KEY_GESTURE_LEFT_V 253 // draw left arrow for previous track +#define KEY_GESTURE_RIGHT_V 254 // draw right arrow for next track +#endif +// carlo@oneplus.net 2015-05-25, end. + +//ruanbanmao@BSP add for tp gesture 2015-05-06, begin +#ifdef VENDOR_EDIT +#define BIT0 (0x1 << 0) +#define BIT1 (0x1 << 1) +#define BIT2 (0x1 << 2) +#define BIT3 (0x1 << 3) +#define BIT4 (0x1 << 4) +#define BIT5 (0x1 << 5) +#define BIT6 (0x1 << 6) +#define BIT7 (0x1 << 7) + +int LeftVee_gesture = 0; //">" +int RightVee_gesture = 0; //"<" +int DouSwip_gesture = 0; // "||" +int Circle_gesture = 0; // "O" +int UpVee_gesture = 0; //"V" +int DownVee_gesture = 0; //"^" +int DouTap_gesture = 0; //"double tap" + +int Left2RightSwip_gesture=0;//"(-->)" +int Right2LeftSwip_gesture=0;//"(<--)" +int Up2DownSwip_gesture =0;//"up to down |" +int Down2UpSwip_gesture =0;//"down to up |" + +int Wgestrue_gesture =0;//"(W)" +int Mgestrue_gesture =0;//"(M)" + +#endif +//ruanbanmao@BSP add for tp gesture 2015-05-06, end +#endif +int syna_use_gesture = 0; +EXPORT_SYMBOL(syna_use_gesture); + +/*********************for Debug LOG switch*******************/ +#define TPD_ERR(a, arg...) pr_err(TPD_DEVICE ": " a, ##arg) +#define TPDTM_DMESG(a, arg...) printk(TPD_DEVICE ": " a, ##arg) + +#define TPD_DEBUG(a,arg...)\ + do{\ + if(tp_debug)\ + pr_err(TPD_DEVICE ": " a,##arg);\ + }while(0) + +/*---------------------------------------------Global Variable----------------------------------------------*/ +static int baseline_ret = 0; +static int TP_FW; +static int tp_dev = 6; +static unsigned int tp_debug = 0; +static int button_map[3]; +static int tx_rx_num[2]; +static int16_t Rxdata[30][30]; +static int16_t delta_baseline[30][30]; +static int TX_NUM; +static int RX_NUM; +static int report_key_point_y = 0; +static int force_update = 0; +static int LCD_WIDTH ; +static int LCD_HEIGHT ; + +#ifdef SUPPORT_TP_SLEEP_MODE +static int sleep_enable; +#endif + +static struct synaptics_ts_data *ts_g = NULL; +static struct workqueue_struct *synaptics_wq = NULL; +static struct workqueue_struct *synaptics_report = NULL; +static struct proc_dir_entry *prEntry_tp = NULL; + + +#ifdef SUPPORT_GESTURE +static uint32_t clockwise; +static uint32_t gesture; + +static uint32_t gesture_upload; + +/****point position*****/ +struct Coordinate { + uint32_t x; + uint32_t y; +}; +static struct Coordinate Point_start; +static struct Coordinate Point_end; +static struct Coordinate Point_1st; +static struct Coordinate Point_2nd; +static struct Coordinate Point_3rd; +static struct Coordinate Point_4th; +#endif + +/*-----------------------------------------Global Registers----------------------------------------------*/ +static unsigned short SynaF34DataBase; +static unsigned short SynaF34QueryBase; +static unsigned short SynaF01DataBase; +static unsigned short SynaF01CommandBase; + +static unsigned short SynaF34Reflash_BlockNum; +static unsigned short SynaF34Reflash_BlockData; +static unsigned short SynaF34ReflashQuery_BootID; +static unsigned short SynaF34ReflashQuery_FlashPropertyQuery; +static unsigned short SynaF34ReflashQuery_FirmwareBlockSize; +static unsigned short SynaF34ReflashQuery_FirmwareBlockCount; +static unsigned short SynaF34ReflashQuery_ConfigBlockSize; +static unsigned short SynaF34ReflashQuery_ConfigBlockCount; + +static unsigned short SynaFirmwareBlockSize; +static unsigned short SynaF34_FlashControl; + +static int F01_RMI_QUERY_BASE; +static int F01_RMI_CMD_BASE; +static int F01_RMI_CTRL_BASE; +static int F01_RMI_DATA_BASE; + +static int F12_2D_QUERY_BASE; +static int F12_2D_CMD_BASE; +static int F12_2D_CTRL_BASE; +static int F12_2D_DATA_BASE; + +static int F34_FLASH_QUERY_BASE; +static int F34_FLASH_CMD_BASE; +static int F34_FLASH_CTRL_BASE; +static int F34_FLASH_DATA_BASE; + +static int F51_CUSTOM_QUERY_BASE; +static int F51_CUSTOM_CMD_BASE; +static int F51_CUSTOM_CTRL_BASE; +static int F51_CUSTOM_DATA_BASE; + +static int F01_RMI_QUERY11; +static int F01_RMI_DATA01; +static int F01_RMI_CMD00; +static int F01_RMI_CTRL00; +static int F01_RMI_CTRL01; + +static int F12_2D_CTRL08; +static int F12_2D_CTRL32; +static int F12_2D_DATA04; +static int F12_2D_DATA38; +static int F12_2D_DATA39; +static int F12_2D_CMD00; +static int F12_2D_CTRL20; +static int F12_2D_CTRL27; + +static int F34_FLASH_CTRL00; + +static int F51_CUSTOM_CTRL00; +static int F51_CUSTOM_DATA04; +static int F51_CUSTOM_DATA11; + +#if TP_TEST_ENABLE +static int F54_ANALOG_QUERY_BASE;//0x73 +static int F54_ANALOG_COMMAND_BASE;//0x72 +static int F54_ANALOG_CONTROL_BASE;//0x0d +static int F54_ANALOG_DATA_BASE;//0x00 +#endif + +/*------------------------------------------Fuction Declare----------------------------------------------*/ +static int synaptics_i2c_suspend(struct device *dev); +static int synaptics_i2c_resume(struct device *dev); +/**************I2C resume && suspend end*********/ +static void speedup_synaptics_resume(struct work_struct *work); +static int synaptics_ts_resume(struct device *dev); +static int synaptics_ts_suspend(struct device *dev); +static int synaptics_ts_remove(struct i2c_client *client); +static int synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id); +static ssize_t synaptics_rmi4_baseline_show(struct device *dev, char *buf, bool savefile) ; +static ssize_t synaptics_rmi4_vendor_id_show(struct device *dev, struct device_attribute *attr, char *buf); +static int synapitcs_ts_update(struct i2c_client *client, const uint8_t *data, uint32_t data_len ,bool force); + +static int synaptics_rmi4_i2c_read_block(struct i2c_client* client, + unsigned char addr,unsigned short length,unsigned char *data); + +static int synaptics_rmi4_i2c_write_block(struct i2c_client* client, + unsigned char addr, unsigned short length, unsigned char const *data); + +static int synaptics_rmi4_i2c_read_byte(struct i2c_client* client, + unsigned char addr); + +static int synaptics_rmi4_i2c_write_byte(struct i2c_client* client, + unsigned char addr,unsigned char data); + +static int synaptics_rmi4_i2c_read_word(struct i2c_client* client, + unsigned char addr); + +static int synaptics_rmi4_i2c_write_word(struct i2c_client* client, + unsigned char addr,unsigned short data); +static int synaptics_mode_change(int mode); +#ifdef TPD_USE_EINT +static irqreturn_t synaptics_irq_thread_fn(int irq, void *dev_id); +#endif + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); +#endif +static int synaptics_soft_reset(struct synaptics_ts_data *ts); +static void synaptics_hard_reset(struct synaptics_ts_data *ts); +static int set_changer_bit(struct synaptics_ts_data *ts); + +/*-------------------------------Using Struct----------------------------------*/ +struct point_info { + unsigned char status; + int x; + int raw_x; + int y; + int raw_y; + int z; +}; + +static const struct i2c_device_id synaptics_ts_id[] = { + { TPD_DEVICE, 0 }, + { } +}; + +static struct of_device_id synaptics_match_table[] = { + { .compatible = TPD_DEVICE,}, + { }, +}; + +static const struct dev_pm_ops synaptic_pm_ops = { +#ifdef CONFIG_PM + .suspend = synaptics_i2c_suspend, + .resume = synaptics_i2c_resume, +#else + .suspend = NULL, + .resume = NULL, +#endif +}; + +//add by jiachenghui for boot time optimize 2015-5-13 +#ifdef VENDOR_EDIT +static int probe_ret; +struct synaptics_optimize_data{ + struct delayed_work work; + struct workqueue_struct *workqueue; + struct i2c_client *client; + const struct i2c_device_id *dev_id; +}; +static struct synaptics_optimize_data optimize_data; +static void synaptics_ts_probe_func(struct work_struct *w) +{ + struct i2c_client *client_optimize = optimize_data.client; + const struct i2c_device_id *dev_id = optimize_data.dev_id; + printk("boot_time: after optimize call [synaptics_ts_probe] on cpu %d\n",smp_processor_id()); + probe_ret = synaptics_ts_probe(client_optimize,dev_id); + printk("boot_time: synaptics_ts_probe return %d\n", probe_ret); +} + +static int oem_synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int i; + //unsigned long flags; + //spinlock_t oem_lock; + optimize_data.client = client; + optimize_data.dev_id = id; + optimize_data.workqueue = create_workqueue("tpd_probe_optimize"); + INIT_DELAYED_WORK(&(optimize_data.work), synaptics_ts_probe_func); + printk("boot_time: before optimize [synaptics_ts_probe] on cpu %d\n",smp_processor_id()); + //spin_lock_irqsave(&oem_lock, flags); + if(get_boot_mode() == MSM_BOOT_MODE__NORMAL) + { + + //get_online_cpus(); + for (i = 0; i <= 3; i++) + { + printk("boot_time: [synaptics_ts_probe] CPU%d is %s\n",i,cpu_is_offline(i)?"offline":"online"); + if (cpu_is_offline(i) || i == smp_processor_id()) + { + continue; + } + queue_delayed_work_on(i,optimize_data.workqueue,&(optimize_data.work),msecs_to_jiffies(300)); + //put_online_cpus(); + break; + } + } + else + { + queue_delayed_work_on(0,optimize_data.workqueue,&(optimize_data.work),msecs_to_jiffies(300)); + } + //flush_workqueue(optimize_data.workqueue); + //spin_unlock_irqrestore(&oem_lock, flags); + return probe_ret; +} +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for boot time optimize 2015-5-13 + +static struct i2c_driver tpd_i2c_driver = { +//add by jiachenghui for boot time optimize 2015-5-13 +#ifdef VENDOR_EDIT + .probe = oem_synaptics_ts_probe, +#else +//end add by jiachenghui for boot time optimize 2015-5-13 + .probe = synaptics_ts_probe, +#endif /*VENDOR_EDIT*///add by jiachenghui for boot time optimize 2015-5-13 + .remove = synaptics_ts_remove, + .id_table = synaptics_ts_id, + .driver = { + // .owner = THIS_MODULE, + .name = TPD_DEVICE, + .of_match_table = synaptics_match_table, + .pm = &synaptic_pm_ops, + }, +}; + +struct synaptics_ts_data { + struct i2c_client *client; + struct mutex mutex; + int irq; + int irq_gpio; + atomic_t irq_enable; + int id1_gpio; + int id2_gpio; + int id3_gpio; + int reset_gpio; + int v1p8_gpio; + int support_hw_poweroff; + int enable2v8_gpio; + int max_num; + int enable_remote; + uint32_t irq_flags; + uint32_t max_x; + uint32_t max_y; + uint32_t max_y_real; + uint32_t btn_state; + uint32_t pre_finger_state; + uint32_t pre_btn_state; + struct work_struct work; + struct work_struct report_work; + struct delayed_work speed_up_work; + struct input_dev *input_dev; + struct hrtimer timer; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#endif + /******gesture*******/ + int double_enable; + int gesture_enable; + int glove_enable; + int changer_connet; + int is_suspended; + atomic_t is_stop; + spinlock_t lock; + + /********test*******/ + int i2c_device_test; + + /******power*******/ + struct regulator *vdd_2v8; + struct regulator *vcc_i2c_1v8; + + /*pinctrl******/ + struct device *dev; + struct pinctrl *pinctrl; + struct pinctrl_state *id_pullup; + struct pinctrl_state *id_pulldown; + + /*******for FW update*******/ + bool loading_fw; + char fw_name[TP_FW_NAME_MAX_LEN]; + char test_limit_name[TP_FW_NAME_MAX_LEN]; + char fw_id[12]; + char manu_name[12]; +}; + +static struct device_attribute attrs_oem[] = { + // __ATTR(baseline_test, 0664, synaptics_rmi4_baseline_show, NULL), + __ATTR(vendor_id, 0664, synaptics_rmi4_vendor_id_show, NULL), +}; + +static void touch_enable (struct synaptics_ts_data *ts) +{ + spin_lock(&ts->lock); + if(0 == atomic_read(&ts->irq_enable)) + { + if(ts->irq) + enable_irq(ts->irq); + atomic_set(&ts->irq_enable,1); + //TPD_ERR("test %%%% enable irq\n"); + } + spin_unlock(&ts->lock); +} + +static void touch_disable(struct synaptics_ts_data *ts) +{ + spin_lock(&ts->lock); + if(1 == atomic_read(&ts->irq_enable)) + { + if(ts->irq) + disable_irq_nosync(ts->irq); + atomic_set(&ts->irq_enable,0); + //TPD_ERR("test ****************** disable irq\n"); + } + spin_unlock(&ts->lock); +} + +static int tpd_hw_pwron(struct synaptics_ts_data *ts) +{ + int rc; + + /***enable the 2v8 power*****/ + if (!IS_ERR(ts->vdd_2v8)) { + //regulator_set_optimum_mode(ts->vdd_2v8,100000); + rc = regulator_enable(ts->vdd_2v8); + if(rc){ + dev_err(&ts->client->dev, + "Regulator vdd enable failed rc=%d\n", rc); + //return rc; + } + } + if( ts->v1p8_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the v1p8_gpio\n"); + gpio_direction_output(ts->v1p8_gpio, 1); + } + //msleep(100); + + if( ts->enable2v8_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the enable2v8_gpio\n"); + gpio_direction_output(ts->enable2v8_gpio, 1); + } + + if (!IS_ERR(ts->vcc_i2c_1v8)) { + //regulator_set_optimum_mode(ts->vcc_i2c_1v8,100000); + rc = regulator_enable( ts->vcc_i2c_1v8 ); + if(rc) { + dev_err(&ts->client->dev, "Regulator vcc_i2c enable failed rc=%d\n", rc); + //return rc; + } + } + if( ts->reset_gpio > 0 ) { + gpio_direction_output(ts->reset_gpio, 1); + msleep(10); + gpio_direction_output(ts->reset_gpio, 0); + msleep(5); + gpio_direction_output(ts->reset_gpio, 1); + TPD_DEBUG("synaptics:enable the reset_gpio\n"); + } + return rc; +} + +static int tpd_hw_pwroff(struct synaptics_ts_data *ts) +{ + int rc = 0; + if( ts->reset_gpio > 0 ) { + TPD_ERR("synaptics:disable the reset_gpio\n"); + gpio_direction_output(ts->reset_gpio, 0); + } + + if (!IS_ERR(ts->vcc_i2c_1v8)) { + rc = regulator_disable( ts->vcc_i2c_1v8 ); + if(rc) { + dev_err(&ts->client->dev, "Regulator vcc_i2c enable failed rc=%d\n", rc); + return rc; + } + } + if( ts->v1p8_gpio > 0 ) { + TPD_DEBUG("synaptics:disable the v1p8_gpio\n"); + gpio_direction_output(ts->v1p8_gpio, 0); + } + msleep(200); + if (!IS_ERR(ts->vdd_2v8)) { + rc = regulator_disable(ts->vdd_2v8); + if (rc) { + dev_err(&ts->client->dev, "Regulator vdd disable failed rc=%d\n", rc); + return rc; + } + } + if( ts->enable2v8_gpio > 0 ) { + TPD_DEBUG("synaptics:enable the enable2v8_gpio\n"); + gpio_direction_output(ts->enable2v8_gpio, 0); + } + return rc; +} + +static int tpd_power(struct synaptics_ts_data *ts, unsigned int on) +{ + int ret; + if(on) + ret = tpd_hw_pwron(ts); + else + ret = tpd_hw_pwroff(ts); + + return ret; +} + +static int synaptics_read_register_map(struct synaptics_ts_data *ts) +{ + uint8_t buf[4]; + int ret; + memset(buf, 0, sizeof(buf)); + ret = synaptics_rmi4_i2c_write_byte( ts->client, 0xff, 0x0 ); + if( ret < 0 ){ + TPD_ERR("synaptics_read_register_map: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xDD, 4, &(buf[0x0])); + if( ret < 0 ){ + TPD_ERR("failed for page select!\n"); + return -1; + } + + F12_2D_QUERY_BASE = buf[0]; + F12_2D_CMD_BASE = buf[1]; + F12_2D_CTRL_BASE = buf[2]; + F12_2D_DATA_BASE = buf[3]; + + TPD_ERR("F12_2D_QUERY_BASE = %x \n \ + F12_2D_CMD_BASE = %x \n\ + F12_2D_CTRL_BASE = %x \n\ + F12_2D_DATA_BASE = %x \n\ + ",F12_2D_QUERY_BASE,F12_2D_CMD_BASE,F12_2D_CTRL_BASE,F12_2D_DATA_BASE); + + + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE3, 4, &(buf[0x0])); + F01_RMI_QUERY_BASE = buf[0]; + F01_RMI_CMD_BASE = buf[1]; + F01_RMI_CTRL_BASE = buf[2]; + F01_RMI_DATA_BASE = buf[3]; + TPD_DEBUG("F01_RMI_QUERY_BASE = %x \n\ + F01_RMI_CMD_BASE = %x \n\ + F01_RMI_CTRL_BASE = %x \n\ + F01_RMI_DATA_BASE = %x \n\ + ", F01_RMI_QUERY_BASE, F01_RMI_CMD_BASE, F01_RMI_CTRL_BASE, F01_RMI_DATA_BASE); + + ret = synaptics_rmi4_i2c_read_block( ts->client, 0xE9, 4, &(buf[0x0]) ); + F34_FLASH_QUERY_BASE = buf[0]; + F34_FLASH_CMD_BASE = buf[1]; + F34_FLASH_CTRL_BASE = buf[2]; + F34_FLASH_DATA_BASE = buf[3]; + TPD_DEBUG("F34_FLASH_QUERY_BASE = %x \n\ + F34_FLASH_CMD_BASE = %x \n\ + F34_FLASH_CTRL_BASE = %x \n\ + F34_FLASH_DATA_BASE = %x \n\ + ", F34_FLASH_QUERY_BASE, F34_FLASH_CMD_BASE, F34_FLASH_CTRL_BASE, F34_FLASH_DATA_BASE); + + F01_RMI_QUERY11 = F12_2D_QUERY_BASE+11; + F01_RMI_CTRL00 = F01_RMI_CTRL_BASE; + F01_RMI_CTRL01 = F01_RMI_CTRL_BASE + 1; + F01_RMI_CMD00 = F01_RMI_CMD_BASE; + F01_RMI_DATA01 = F01_RMI_DATA_BASE + 1; + + F12_2D_CTRL08 = F12_2D_CTRL_BASE; + F12_2D_CTRL32 = F12_2D_CTRL_BASE + 15; + F12_2D_DATA38 = F12_2D_DATA_BASE + 54; + F12_2D_DATA39 = F12_2D_DATA_BASE + 55; + F12_2D_CMD00 = F12_2D_CMD_BASE; + F12_2D_CTRL20 = F12_2D_CTRL_BASE + 0x07; + F12_2D_CTRL27 = F12_2D_CTRL_BASE + 0x0c; + + + F34_FLASH_CTRL00 = F34_FLASH_CTRL_BASE; + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x4); + if( ret < 0 ){ + TPD_DEBUG("synaptics_read_register_map: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE9, 4, &(buf[0x0])); + F51_CUSTOM_QUERY_BASE = buf[0]; + F51_CUSTOM_CMD_BASE = buf[1]; + F51_CUSTOM_CTRL_BASE = buf[2]; + F51_CUSTOM_DATA_BASE = buf[3]; + F51_CUSTOM_CTRL00 = F51_CUSTOM_CTRL_BASE; + F51_CUSTOM_DATA04 = F51_CUSTOM_DATA_BASE; + F51_CUSTOM_DATA11 = F51_CUSTOM_DATA_BASE; + + TPD_DEBUG("F51_CUSTOM_QUERY_BASE = %x \n\ + F51_CUSTOM_CMD_BASE = %x \n\ + F51_CUSTOM_CTRL_BASE = %x \n\ + F51_CUSTOM_DATA_BASE = %x \n\ + ", F51_CUSTOM_QUERY_BASE, F51_CUSTOM_CMD_BASE, F51_CUSTOM_CTRL_BASE, F51_CUSTOM_DATA_BASE); + +#if TP_TEST_ENABLE + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x01); + if(ret < 0) { + TPD_ERR("synaptics_read_register_map: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE9, 4, &(buf[0x0])); + F54_ANALOG_QUERY_BASE = buf[0]; + F54_ANALOG_COMMAND_BASE = buf[1]; + F54_ANALOG_CONTROL_BASE = buf[2]; + F54_ANALOG_DATA_BASE = buf[3]; + TPD_DEBUG("F54_QUERY_BASE = %x \n\ + F54_CMD_BASE = %x \n\ + F54_CTRL_BASE = %x \n\ + F54_DATA_BASE = %x \n\ + ", F54_ANALOG_QUERY_BASE, F54_ANALOG_COMMAND_BASE , F54_ANALOG_CONTROL_BASE, F54_ANALOG_DATA_BASE); +#endif + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00); + return 0; +} + +#ifdef SUPPORT_GESTURE +static int synaptics_enable_interrupt_for_gesture(struct synaptics_ts_data *ts, int enable) +{ + int ret; + unsigned char reportbuf[4]; + //chenggang.li@BSP.TP modified for gesture + TPD_DEBUG("%s is called\n", __func__); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if( ret < 0 ) { + TPD_ERR("%s: select page failed ret = %d\n", __func__, ret); + return -1; + } + ret = i2c_smbus_read_i2c_block_data( ts->client, F12_2D_CTRL20, 3, &(reportbuf[0x0]) ); + if( ret < 0 ) { + TPD_DEBUG("read reg F12_2D_CTRL20[0x%x] failed\n",F12_2D_CTRL20); + return -1; + } + + if( enable ) { + ts->gesture_enable = 1; + reportbuf[2] |= 0x02 ; + } else { + ts->gesture_enable = 0; + reportbuf[2] &= 0xfd ; + } + printk("F12_2D_CTRL20:0x%x=[2]:0x%x\n", F12_2D_CTRL20, reportbuf[2]); + ret = i2c_smbus_write_i2c_block_data( ts->client, F12_2D_CTRL20, 3, &(reportbuf[0x0]) ); + if( ret < 0 ){ + TPD_ERR("%s :Failed to write report buffer\n", __func__); + return -1; + } + gesture = UnkownGestrue; + return 0; +} +#endif + +#ifdef SUPPORT_GLOVES_MODE +#define GLOVES_ADDR 0x001f //0x001D 0x001f +static int synaptics_glove_mode_enable(struct synaptics_ts_data *ts) +{ + int ret; + TPD_DEBUG("glove mode enable\n"); + /* page select = 0x4 */ + if( 1 == ts->glove_enable) { + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + if( ret < 0 ){ + TPD_DEBUG("i2c_smbus_write_byte_data failed for mode select\n"); + goto GLOVE_ENABLE_END; + } + ret = i2c_smbus_read_byte_data(ts->client, GLOVES_ADDR); + //TPDTM_DMESG("enable glove ret is %x ret|0x20 is %x\n", ret, ret|0x20); + ret = i2c_smbus_write_byte_data(ts->client, GLOVES_ADDR, ret | 0x01); + if( ret < 0 ){ + TPD_DEBUG("i2c_smbus_write_byte_data failed for mode select\n"); + goto GLOVE_ENABLE_END; + } + }else{ + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPD_DEBUG("i2c_smbus_write_byte_data failed for mode select\n"); + goto GLOVE_ENABLE_END; + } + ret = i2c_smbus_read_byte_data(ts->client, GLOVES_ADDR); + ret = i2c_smbus_write_byte_data(ts->client, GLOVES_ADDR, ret & 0xFE); + if( ret < 0 ){ + TPD_DEBUG("i2c_smbus_write_byte_data failed for mode select\n"); + goto GLOVE_ENABLE_END; + } + } + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + if( ret < 0 ){ + TPD_DEBUG("i2c_smbus_write_byte_data failed for page select\n"); + goto GLOVE_ENABLE_END; + } + +GLOVE_ENABLE_END: + return ret; +} +#endif + +#ifdef SUPPORT_TP_SLEEP_MODE +static int synaptics_sleep_mode_enable(struct synaptics_ts_data *ts) +{ + int ret; + /* page select = 0x0 */ + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + if( ret < 0 ){ + TPD_ERR("i2c_smbus_write_byte_data failed for page select\n"); + goto SLEEP_ENABLE_END; + } + if( 1 == sleep_enable ){ + /*0x00:enable glove mode,0x02:disable glove mode,*/ + TPDTM_DMESG("sleep mode enable\n"); + ret = synaptics_mode_change(0x01); + if( ret < 0 ){ + TPD_ERR("i2c_smbus_write_byte_data failed for mode select\n"); + goto SLEEP_ENABLE_END; + } + }else{ + TPDTM_DMESG("sleep mode disable\n"); + ret = synaptics_mode_change(0x84); + if( ret < 0 ){ + TPD_ERR("i2c_smbus_write_byte_data failed for mode select\n"); + goto SLEEP_ENABLE_END; + } + } + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + if( ret < 0 ){ + TPD_ERR("i2c_smbus_write_byte_data failed for page select\n"); + goto SLEEP_ENABLE_END; + } + +SLEEP_ENABLE_END: + return ret; +} +#endif + +static int synaptics_read_product_id(struct synaptics_ts_data *ts) +{ + uint8_t buf1[11]; + int ret ; + + memset(buf1, 0 , sizeof(buf1)); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPDTM_DMESG("synaptics_read_product_id: failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, F01_RMI_QUERY_BASE+11, 8, &(buf1[0x0])); + ret = synaptics_rmi4_i2c_read_block(ts->client, F01_RMI_QUERY_BASE+19, 2, &(buf1[0x8])); + if( ret < 0 ){ + TPD_ERR("synaptics_read_product_id: failed to read product info\n"); + return -1; + } + return 0; +} + +static int synaptics_init_panel(struct synaptics_ts_data *ts) +{ + int ret; + + TPD_DEBUG("%s is called!\n",__func__); + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x0); + if( ret < 0 ){ + TPD_ERR("init_panel failed for page select\n"); + return -1; + } + /*device control: normal operation, configur=1*/ + + ret = synaptics_mode_change(0x84); + if( ret < 0 ){ + msleep(150); + ret = synaptics_mode_change(0x84); + if( ret < 0 ){ + TPD_ERR("%s failed for mode select\n",__func__); + } + } + + return ret; +} + +static int synaptics_enable_interrupt(struct synaptics_ts_data *ts, int enable) +{ + int ret; + uint8_t abs_status_int; + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if( ret < 0 ) { + TPDTM_DMESG("synaptics_enable_interrupt: select page failed ret = %d\n", + ret); + return -1; + } + if( enable ) { + abs_status_int = 0x7f; + /*clear interrupt bits for previous touch*/ + ret = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_DATA_BASE+1); + if( ret < 0 ) { + TPDTM_DMESG("synaptics_enable_interrupt :clear interrupt bits failed\n"); + return -1; + } + } else { + abs_status_int = 0x0; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client, F01_RMI_CTRL00+1, abs_status_int); + if( ret < 0 ) { + TPDTM_DMESG("%s: enable or disable abs \ + interrupt failed,abs_int =%d\n", __func__, abs_status_int); + return -1; + } + ret = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_CTRL00+1); + return 0; +} + +static void delay_qt_ms(unsigned long w_ms) +{ + unsigned long i; + unsigned long j; + for(i = 0; i < w_ms; i++) { + for (j = 0; j < 1000; j++) { + udelay(1); + } + } +} + +static void int_state(struct synaptics_ts_data *ts) +{ + int ret = -1; + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD00, 0x01); + if(ret){ + TPD_ERR("int_state:cannot reset touch panel \n"); + return; + } + delay_qt_ms(170); +#ifdef SUPPORT_GLOVES_MODE + synaptics_glove_mode_enable(ts); +#endif + TPD_DEBUG("%s %d\n",__func__,__LINE__); + synaptics_init_panel(ts); + if( ret < 0 ){ + TPD_DEBUG("int_state: control tm1400 to sleep failed\n"); + return; + } + ret = synaptics_enable_interrupt(ts, 1); + if(ret){ + TPD_DEBUG("int_state:cannot enable interrupt \n"); + return; + } +} + +//Added for larger than 32 length read! +static int synaptics_rmi4_i2c_read_block(struct i2c_client* client, + unsigned char addr,unsigned short length,unsigned char *data) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + buf = addr & 0xFF; + for( retry = 0; retry < 2; retry++ ) { + if( i2c_transfer(client->adapter, msg, 2) == 2) { + retval = length; + break; + } + msleep(20); + } + if( retry == 2 ) { + dev_err(&client->dev, + "%s: I2C read over retry limit\n", + __func__); + //rst_flag_counter = 1;//reset tp + retval = -5; + } else { + //rst_flag_counter = 0; + } + return retval; +} + +static int synaptics_rmi4_i2c_write_block(struct i2c_client* client, + unsigned char addr, unsigned short length, unsigned char const *data) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + buf[0] = addr & 0xff; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(client->adapter, msg, 1) == 1) { + retval = length; + break; + } + msleep(20); + } + if (retry == 2) { + //rst_flag_counter = 1;//rest tp + retval = -EIO; + } else { + //rst_flag_counter = 0; + } + return retval; +} + +static int synaptics_rmi4_i2c_read_byte(struct i2c_client* client, + unsigned char addr) +{ + int retval = 0; + unsigned char buf[2] = {0}; + retval = synaptics_rmi4_i2c_read_block(client,addr,1,buf); + if(retval >= 0) + retval = buf[0]&0xff; + return retval; +} + +static int synaptics_rmi4_i2c_write_byte(struct i2c_client* client, + unsigned char addr,unsigned char data) +{ + int retval; + unsigned char data_send = data; + retval = synaptics_rmi4_i2c_write_block(client,addr,1,&data_send); + return retval; +} + +static int synaptics_rmi4_i2c_read_word(struct i2c_client* client, + unsigned char addr) +{ + int retval; + unsigned char buf[2] = {0}; + retval = synaptics_rmi4_i2c_read_block(client,addr,2,buf); + if(retval >= 0) + retval = buf[1]<<8|buf[0]; + return retval; +} + +static int synaptics_rmi4_i2c_write_word(struct i2c_client* client, + unsigned char addr,unsigned short data) +{ + int retval; + unsigned char buf[2] = {data&0xff,(data>>8)&0xff}; + retval = synaptics_rmi4_i2c_write_block(client,addr,2,buf); + if(retval >= 0) + retval = buf[1]<<8|buf[0]; + return retval; +} + +//chenggang.li@BSP.TP modified for oem 2014-08-05 gesture_judge +/***************start****************/ +#ifdef SUPPORT_GESTURE +static void synaptics_get_coordinate_point(struct synaptics_ts_data *ts) +{ + int ret,i; + uint8_t coordinate_buf[25] = {0}; + uint16_t trspoint = 0; + + TPD_DEBUG("%s is called!\n",__func__); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x4); + ret = i2c_smbus_read_i2c_block_data(ts->client, F51_CUSTOM_DATA11, 8, &(coordinate_buf[0])); + ret = i2c_smbus_read_i2c_block_data(ts->client, F51_CUSTOM_DATA11 + 8, 8, &(coordinate_buf[8])); + ret = i2c_smbus_read_i2c_block_data(ts->client, F51_CUSTOM_DATA11 + 16, 8, &(coordinate_buf[16])); + ret = i2c_smbus_read_i2c_block_data(ts->client, F51_CUSTOM_DATA11 + 24, 1, &(coordinate_buf[24])); + + for(i = 0; i< 23; i += 2) { + trspoint = coordinate_buf[i]|coordinate_buf[i+1] << 8; + TPD_DEBUG("synaptics TP read coordinate_point[%d] = %d\n",i,trspoint); + } + + TPD_DEBUG("synaptics TP coordinate_buf = 0x%x\n",coordinate_buf[24]); + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + Point_start.x = (coordinate_buf[0] | (coordinate_buf[1] << 8)) * LCD_WIDTH/ (ts->max_x); + Point_start.y = (coordinate_buf[2] | (coordinate_buf[3] << 8)) * LCD_HEIGHT/ (ts->max_y); + Point_end.x = (coordinate_buf[4] | (coordinate_buf[5] << 8)) * LCD_WIDTH / (ts->max_x); + Point_end.y = (coordinate_buf[6] | (coordinate_buf[7] << 8)) * LCD_HEIGHT / (ts->max_y); + Point_1st.x = (coordinate_buf[8] | (coordinate_buf[9] << 8)) * LCD_WIDTH / (ts->max_x); + Point_1st.y = (coordinate_buf[10] | (coordinate_buf[11] << 8)) * LCD_HEIGHT / (ts->max_y); + Point_2nd.x = (coordinate_buf[12] | (coordinate_buf[13] << 8)) * LCD_WIDTH / (ts->max_x); + Point_2nd.y = (coordinate_buf[14] | (coordinate_buf[15] << 8)) * LCD_HEIGHT / (ts->max_y); + Point_3rd.x = (coordinate_buf[16] | (coordinate_buf[17] << 8)) * LCD_WIDTH / (ts->max_x); + Point_3rd.y = (coordinate_buf[18] | (coordinate_buf[19] << 8)) * LCD_HEIGHT / (ts->max_y); + Point_4th.x = (coordinate_buf[20] | (coordinate_buf[21] << 8)) * LCD_WIDTH / (ts->max_x); + Point_4th.y = (coordinate_buf[22] | (coordinate_buf[23] << 8)) * LCD_HEIGHT / (ts->max_y); + clockwise = (coordinate_buf[24] & 0x10) ? 1 : + (coordinate_buf[24] & 0x20) ? 0 : 2; // 1--clockwise, 0--anticlockwise, not circle, report 2 +} + +static void gesture_judge(struct synaptics_ts_data *ts) +{ + unsigned int keyCode = KEY_F4; + int ret = 0,gesture_sign, regswipe; + uint8_t gesture_buffer[10]; + unsigned char reportbuf[3]; + F12_2D_DATA04 = 0x0007; + + TPD_DEBUG("%s is called!\n",__func__); + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00); + if (ret < 0) { + TPDTM_DMESG("failed to transfer the data, ret = %d\n", ret); + } + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + ret = i2c_smbus_read_i2c_block_data(ts->client, F12_2D_DATA04, 5, &(gesture_buffer[0])); + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x4); + regswipe = i2c_smbus_read_byte_data(ts->client, F51_CUSTOM_DATA04+0x18); + TPD_DEBUG(" gesture_buffer[0] = 0x%x, regswipe = 0x%x,gesture_buffer[2] = 0x%x, gesture_buffer[4] = 0x%x\n", gesture_buffer[0], regswipe, gesture_buffer[2], gesture_buffer[4]); + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + gesture_sign = gesture_buffer[0]; + //detect the gesture mode + switch (gesture_sign) { + case DTAP_DETECT: + //#ifdef VENDOR_EDIT, ruanbanmao@bsp 2015-05-06, begin. + gesture = DouTap; + break; + case SWIPE_DETECT: + gesture = (regswipe == 0x41) ? Left2RightSwip : + (regswipe == 0x42) ? Right2LeftSwip : + (regswipe == 0x44) ? Up2DownSwip : + (regswipe == 0x48) ? Down2UpSwip : + (regswipe == 0x80) ? DouSwip : + UnkownGestrue; + break; + case CIRCLE_DETECT: + gesture = Circle; + break; + case VEE_DETECT: + gesture = (gesture_buffer[2] == 0x01) ? DownVee : + (gesture_buffer[2] == 0x02) ? UpVee : + (gesture_buffer[2] == 0x04) ? RightVee : + (gesture_buffer[2] == 0x08) ? LeftVee : + UnkownGestrue; + break; + case UNICODE_DETECT: + gesture = (gesture_buffer[2] == 0x77) ? Wgestrue : + (gesture_buffer[2] == 0x6d) ? Mgestrue : + UnkownGestrue; + //#endif, ruanbanmao@bsp 2015-05-06, end. + } + +// carlo@oneplus.net 2015-05-25, begin. +#ifdef VENDOR_EDIT + keyCode = UnkownGestrue; + // Get key code based on registered gesture. + switch (gesture) { + case DouTap: + keyCode = KEY_DOUBLE_TAP; + break; + case UpVee: + keyCode = KEY_GESTURE_V; + break; + case DownVee: + keyCode = KEY_GESTURE_V; + break; + case LeftVee: + keyCode = KEY_GESTURE_RIGHT_V; + break; + case RightVee: + keyCode = KEY_GESTURE_LEFT_V; + break; + case Circle: + keyCode = KEY_GESTURE_CIRCLE; + break; + case DouSwip: + keyCode = KEY_GESTURE_TWO_SWIPE; + break; + default: + break; + } +#endif +// carlo@oneplus.net 2015-05-25, end. + + TPD_ERR("detect %s gesture\n", gesture == DouTap ? "double tap" : + gesture == UpVee ? "(V)" : + gesture == DownVee ? "(^)" : + gesture == LeftVee ? "(>)" : + gesture == RightVee ? "(<)" : + gesture == Circle ? "(O)" : + gesture == DouSwip ? "(||)" : + gesture == Left2RightSwip ? "(-->)" : + gesture == Right2LeftSwip ? "(<--)" : + gesture == Up2DownSwip ? "up to down |" : + gesture == Down2UpSwip ? "down to up |" : + gesture == Mgestrue ? "(M)" : + gesture == Wgestrue ? "(W)" : "unknown"); + synaptics_get_coordinate_point(ts); + + TPD_DEBUG("gesture suport LeftVee:%d RightVee:%d DouSwip:%d Circle:%d UpVee:%d DouTap:%d\n",\ + LeftVee_gesture,RightVee_gesture,DouSwip_gesture,Circle_gesture,UpVee_gesture,DouTap_gesture); + if((gesture == DouTap && DouTap_gesture)||(gesture == RightVee && RightVee_gesture)\ + ||(gesture == LeftVee && LeftVee_gesture)||(gesture == UpVee && UpVee_gesture)\ + ||(gesture == Circle && Circle_gesture)||(gesture == DouSwip && DouSwip_gesture)){ + gesture_upload = gesture; + input_report_key(ts->input_dev, keyCode, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, keyCode, 0); + input_sync(ts->input_dev); + }else{ + + ret = i2c_smbus_read_i2c_block_data( ts->client, F12_2D_CTRL20, 3, &(reportbuf[0x0]) ); + ret = reportbuf[2] & 0x20; + if(ret == 0) + reportbuf[2] |= 0x02 ; + ret = i2c_smbus_write_i2c_block_data( ts->client, F12_2D_CTRL20, 3, &(reportbuf[0x0]) ); //enable gesture + if( ret < 0 ){ + TPD_ERR("%s :Failed to write report buffer\n", __func__); + return; + } + } +} +#endif +/***************end****************/ +static char prlog_count = 0; +static void int_touch(struct synaptics_ts_data *ts) +{ + int ret = -1,i = 0; + uint8_t buf[80]; + uint8_t finger_num = 0; + uint8_t finger_status = 0; + struct point_info points; + uint32_t finger_info = 0; + + memset(buf, 0, sizeof(buf)); + points.x = 0; + points.y = 0; + points.z = 0; + points.status = 0; + + ret = synaptics_rmi4_i2c_read_block(ts->client, F12_2D_DATA_BASE, 80, buf); + if (ret < 0) { + TPD_ERR("synaptics_int_touch: i2c_transfer failed\n"); + return; + } + for( i = 0; i < ts->max_num; i++ ) { + points.status = buf[i*8]; + points.x = ((buf[i*8+2]&0x0f)<<8) | (buf[i*8+1] & 0xff); + points.raw_x = buf[i*8+6] & 0x0f; + points.y = ((buf[i*8+4]&0x0f)<<8) | (buf[i*8+3] & 0xff); + points.raw_y = buf[i*8+7] & 0x0f; + points.z = buf[i*8+5]; + finger_info <<= 1; + finger_status = points.status & 0x03; + if (finger_status) { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, finger_status); + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_report_key(ts->input_dev, BTN_TOOL_FINGER, 1); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, points.x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, points.y); + //#ifdef REPORT_2D_W + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, max(points.raw_x, points.raw_y)); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, min(points.raw_x, points.raw_y)); + //#endif +#ifndef TYPE_B_PROTOCOL + input_mt_sync(ts->input_dev); +#endif + + finger_num++; + finger_info |= 1 ; + TPD_DEBUG("%s: Finger %d: status = 0x%02x " + "x = %4d, y = %4d, wx = %2d, wy = %2d\n", + __func__, i, points.status, points.x, points.y, points.raw_x, points.raw_y); + + } + } + + for ( i = 0; i < ts->max_num; i++ ) + { + finger_status = (finger_info>>(ts->max_num-i-1)) & 1 ; + if(!finger_status) + { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, finger_status); + } + } + + if (finger_num == 0) + { + input_report_key(ts->input_dev,BTN_TOUCH, 0); + if (3 == (++prlog_count % 6)) + TPD_ERR("all finger up\n"); + input_report_key(ts->input_dev, BTN_TOOL_FINGER, 0); +#ifndef TYPE_B_PROTOCOL + input_mt_sync(ts->input_dev); +#endif + } + + input_sync(ts->input_dev); + + +#ifdef SUPPORT_GESTURE + if (ts->gesture_enable == 1 && ts->is_suspended == 1) { + gesture_judge(ts); + } +#endif +} + +static void synaptics_ts_work_func(struct work_struct *work) +{ + int ret; + uint8_t status = 0; + uint8_t inte = 0; + struct synaptics_ts_data *ts = ts_g; + if( ts->enable_remote) { + goto END; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x00 ); + ret = synaptics_rmi4_i2c_read_word(ts->client, F01_RMI_DATA_BASE); + if (atomic_read(&ts->is_stop) == 1) + goto END; + if( ret < 0 ) { + TPDTM_DMESG("Synaptic:ret = %d\n", ret); + synaptics_hard_reset(ts); + goto END; + } + status = ret & 0xff; + inte = (ret & 0x7f00)>>8; + if(status) { + int_state(ts); + goto END; + } + if( inte & 0x04 ) { + int_touch(ts); + } +END: + ret = set_changer_bit(ts); + touch_enable(ts); + return; +} + +#ifndef TPD_USE_EINT +static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) +{ + struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer); + mutex_lock(&ts->mutex); + synaptics_ts_work_func(ts); + mutex_unlock(&ts->mutex); + hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} +#else +static irqreturn_t synaptics_irq_thread_fn(int irq, void *dev_id) +{ + struct synaptics_ts_data *ts = (struct synaptics_ts_data *)dev_id; + mutex_lock(&ts->mutex); + touch_disable(ts); + queue_work(synaptics_report, &ts->report_work); + mutex_unlock(&ts->mutex); + return IRQ_HANDLED; +} +#endif + +//wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" begin +static ssize_t tp_baseline_test_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + char page[PAGESIZE]; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return baseline_ret; + if(baseline_ret == 0){ + count = synaptics_rmi4_baseline_show(ts->dev,page,0); + baseline_ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + }else{ + baseline_ret = 0; + } + return baseline_ret; +} +//wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" end + +static ssize_t i2c_device_test_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + struct synaptics_ts_data *ts = ts_g; + if(!ts_g) + return ret; + TPD_DEBUG("gesture enable is: %d\n", ts->double_enable); + ret = sprintf(page, "%d\n", ts->i2c_device_test); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +#ifdef SUPPORT_GESTURE +static ssize_t tp_gesture_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return ret; + TPD_DEBUG("gesture enable is: %d\n", ts->double_enable); + ret = sprintf(page, "%d\n", ts->double_enable); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} +extern int syna_use_gesture; +//EXPORT_SYMBOL(syna_use_gesture); + +static ssize_t tp_gesture_write_func(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + //int ret=0; + char buf[10]; + struct synaptics_ts_data *ts = ts_g; + //printk("%s buffer[0]=%d,buffer[1]=%d\n",__func__,buffer[0],buffer[1]); + if( count > 2) + return count; + if( copy_from_user(buf, buffer, count) ){ + printk(KERN_INFO "%s: read proc input error.\n", __func__); + return count; + } + //ruanbanmao@BSP add for tp gesture 2015-05-06, begin + #ifdef VENDOR_EDIT + //sscanf(buf, "%d", &ret); + printk("synap %s status write buf[0]=%x\n",__func__,buf[0]); + if(!ts) + return count; + + UpVee_gesture = (buf[0] & BIT0)?1:0; //"V" + DouSwip_gesture = (buf[0] & BIT1)?1:0;//"||" + LeftVee_gesture = (buf[0] & BIT3)?1:0; //">" + RightVee_gesture = (buf[0] & BIT4)?1:0;//"<" + Circle_gesture = (buf[0] & BIT6)?1:0; //"O" + DouTap_gesture = (buf[0] & BIT7)?1:0; //double tap + + if(DouTap_gesture||Circle_gesture||UpVee_gesture||LeftVee_gesture\ + ||RightVee_gesture||DouSwip_gesture) + { + ts->double_enable = 1; + syna_use_gesture = 1; + } + else + { + ts->double_enable = 0; + syna_use_gesture = 0; + } + #endif + //ruanbanmao@BSP add for tp gesture 2015-05-06, end + return count; +} +static ssize_t coordinate_proc_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + TPD_ERR("%s:gesture_upload = %d \n",__func__,gesture_upload); + ret = sprintf(page, "%d,%d:%d,%d:%d,%d:%d,%d:%d,%d:%d,%d:%d,%d\n", gesture_upload, + Point_start.x, Point_start.y, Point_end.x, Point_end.y, + Point_1st.x, Point_1st.y, Point_2nd.x, Point_2nd.y, + Point_3rd.x, Point_3rd.y, Point_4th.x, Point_4th.y, + clockwise); + + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t double_tap_enable_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + ret = sprintf(page, "%d\n", DouTap_gesture); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t double_tap_enable_write_func(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + int ret = 0; + struct synaptics_ts_data *ts = ts_g; + + sscanf(buf, "%d", &ret); + + DouTap_gesture = ret; + if (DouTap_gesture || Circle_gesture || UpVee_gesture || + (LeftVee_gesture && RightVee_gesture && DouSwip_gesture)) + { + ts->double_enable = 1; + syna_use_gesture = 1; + } + else + { + ts->double_enable = 0; + syna_use_gesture = 0; + } + return count; +} + +static ssize_t camera_enable_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + ret = sprintf(page, "%d\n", Circle_gesture); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t camera_enable_write_func(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + int ret = 0; + struct synaptics_ts_data *ts = ts_g; + + sscanf(buf, "%d", &ret); + + Circle_gesture = ret; + if (DouTap_gesture || Circle_gesture || UpVee_gesture || + (LeftVee_gesture && RightVee_gesture && DouSwip_gesture)) + { + ts->double_enable = 1; + syna_use_gesture = 1; + } + else + { + ts->double_enable = 0; + syna_use_gesture = 0; + } + return count; +} + +static ssize_t music_enable_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + ret = sprintf(page, "%d\n", LeftVee_gesture && RightVee_gesture && DouSwip_gesture); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t music_enable_write_func(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + int ret = 0; + struct synaptics_ts_data *ts = ts_g; + + sscanf(buf, "%d", &ret); + + DouSwip_gesture = ret; + LeftVee_gesture = ret; + RightVee_gesture = ret; + if (DouTap_gesture || Circle_gesture || UpVee_gesture || + (LeftVee_gesture && RightVee_gesture && DouSwip_gesture)) + { + ts->double_enable = 1; + syna_use_gesture = 1; + } + else + { + ts->double_enable = 0; + syna_use_gesture = 0; + } + return count; +} + +static ssize_t flashlight_enable_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + ret = sprintf(page, "%d\n", UpVee_gesture); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t flashlight_enable_write_func(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + int ret = 0; + struct synaptics_ts_data *ts = ts_g; + + sscanf(buf, "%d", &ret); + + UpVee_gesture = ret; + if (DouTap_gesture || Circle_gesture || UpVee_gesture || + (LeftVee_gesture && RightVee_gesture && DouSwip_gesture)) + { + ts->double_enable = 1; + syna_use_gesture = 1; + } + else + { + ts->double_enable = 0; + syna_use_gesture = 0; + } + return count; +} + +// chenggang.li@BSP.TP modified for oem 2014-08-08 create node +/******************************start****************************/ +static const struct file_operations tp_gesture_proc_fops = { + .write = tp_gesture_write_func, + .read = tp_gesture_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations coordinate_proc_fops = { + .read = coordinate_proc_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations double_tap_enable_proc_fops = { + .write = double_tap_enable_write_func, + .read = double_tap_enable_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations camera_enable_proc_fops = { + .write = camera_enable_write_func, + .read = camera_enable_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations music_enable_proc_fops = { + .write = music_enable_write_func, + .read = music_enable_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations flashlight_enable_proc_fops = { + .write = flashlight_enable_write_func, + .read = flashlight_enable_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +#endif +static int page ,address,block; +static ssize_t synap_read_address(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret; + char buffer[PAGESIZE]; + char buf[128]; + int i; + int cnt = 0; + + struct synaptics_ts_data *ts = ts_g; + printk("%s page=0x%x,address=0x%x,block=0x%x\n",__func__,page,address,block); + cnt += sprintf(&(buffer[cnt]), "page=0x%x,address=0x%x,block=0x%x\n",page,address,block); + ret = synaptics_rmi4_i2c_write_byte(ts->client,0xff,page); + ret = synaptics_rmi4_i2c_read_block(ts->client,address,block,buf); + for (i=0;i < block;i++) + { + cnt += sprintf(&(buffer[cnt]), "buf[%d]=0x%x\n",i,buf[i]); + printk("buffer[%d]=0x%x\n",i,buffer[i]); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buffer, strlen(buffer)); + return ret; +} + +static ssize_t synap_write_address(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + int buf[128]; + int ret,i; + struct synaptics_ts_data *ts = ts_g; + int temp_block,wbyte; + char reg[30]; + + ret = sscanf(buffer,"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",\ + &buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6],&buf[7],&buf[8],&buf[9],\ + &buf[10],&buf[11],&buf[12],&buf[13],&buf[14],&buf[15],&buf[16],&buf[17]); + for (i = 0;i < ret;i++) + { + printk("buf[i]=0x%x,",buf[i]); + } + printk("\n"); + page= buf[0]; + address = buf[1]; + temp_block = buf[2]; + wbyte = buf[3]; + if (0xFF == temp_block)//the mark is to write register else read register + { + for (i=0;i < wbyte;i++) + { + reg[i] = (char)buf[4+i]; + } + ret = synaptics_rmi4_i2c_write_byte(ts->client,0xff,page); + ret = synaptics_rmi4_i2c_write_block(ts->client,(char)address,wbyte,reg); + printk("%s write page=0x%x,address=0x%x\n",__func__,page,address); + for (i=0;i < wbyte;i++) + { + printk("reg=0x%x\n",reg[i]); + } + } + else + block = temp_block; + return count; +} + +#ifdef SUPPORT_GLOVES_MODE +static ssize_t tp_glove_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return ret; + printk("glove mode enable is: %d\n", ts->glove_enable); + ret = sprintf(page, "%d\n", ts->glove_enable); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t tp_glove_write_func(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct synaptics_ts_data *ts= ts_g; + int ret = 0 ; + char buf[10]; + + if( count > 10 ) + goto GLOVE_ENABLE_END; + if( copy_from_user( buf, buffer, count) ){ + printk(KERN_INFO "%s: read proc input error.\n", __func__); + goto GLOVE_ENABLE_END; + } + sscanf(buf, "%d", &ret); + if(!ts) + return count; + TPDTM_DMESG("tp_glove_write_func:buf = %d,ret = %d\n", *buf, ret); + if( (ret == 0 ) || (ret == 1) ){ + ts->glove_enable = ret; + synaptics_glove_mode_enable(ts); + } + switch(ret){ + case 0: + TPDTM_DMESG("tp_glove_func will be disable\n"); + break; + case 1: + TPDTM_DMESG("tp_glove_func will be enable\n"); + break; + default: + TPDTM_DMESG("Please enter 0 or 1 to open or close the glove function\n"); + } +GLOVE_ENABLE_END: + return count; +} +#endif + + +#ifdef SUPPORT_TP_SLEEP_MODE +static ssize_t tp_sleep_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + printk("sleep mode enable is: %d\n", sleep_enable); + ret = sprintf(page, "%d\n", sleep_enable); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t tp_sleep_write_func(struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + char buf[10]; + struct synaptics_ts_data *ts = ts_g; + int ret = 0 ; + if( count > 10 ) + return count; + if(!ts) + return count; + if( copy_from_user( buf, buffer, count) ) { + printk(KERN_INFO "%s: read proc input error.\n", __func__); + return count; + } + sscanf(buf, "%d", &ret); + TPDTM_DMESG("tp_sleep_write_func:buf = %d,ret = %d\n", *buf, ret); + if( (ret == 0 ) || (ret == 1) ) { + sleep_enable = ret; + synaptics_sleep_mode_enable(ts); + } + switch(ret) { + case 0: + TPDTM_DMESG("tp_sleep_func will be disable\n"); + break; + case 1: + TPDTM_DMESG("tp_sleep_func will be enable\n"); + break; + default: + TPDTM_DMESG("Please enter 0 or 1 to open or close the sleep function\n"); + } + return count; +} +#endif + +static ssize_t tp_show(struct device_driver *ddri, char *buf) +{ + // uint8_t ret = 0; + struct synaptics_ts_data *ts = ts_g; + int a ; + int b,c; + if(!ts) + return 0; + a = synaptics_rmi4_i2c_read_word(ts->client, F01_RMI_DATA_BASE); + if( a < 0 ) + printk("tp_show read i2c err\n"); + b = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_DATA01); + if( b < 0 ) + printk("tp_show read i2c err\n"); + c = synaptics_rmi4_i2c_read_byte(ts->client, F12_2D_DATA_BASE); + if( c < 0 ) + printk("tp_show read i2c err\n"); + + return sprintf(buf, "F01_RMI_DATA_BASE[0x%x]=0x%x;F01_RMI_DATA01[0x%x]=0x%x;F12_2D_DATA_BASE[0x%x]=0x%x;\n", \ + F01_RMI_DATA_BASE,a,F01_RMI_DATA01,b,F12_2D_DATA_BASE,c); +} + +static ssize_t store_tp(struct device_driver *ddri, const char *buf, size_t count) +{ + int tmp = 0; + if( 1 == sscanf(buf, "%d", &tmp) ){ + tp_debug = tmp; + } else { + TPDTM_DMESG("invalid content: '%s', length = %zd\n", buf, count); + } + return count; +} +static ssize_t vendor_id_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[4]; + ret = sprintf(page, "6\n"); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +#if TP_TEST_ENABLE +static int synaptics_read_register_map_page1(struct synaptics_ts_data *ts) +{ + unsigned char buf[4]; + int ret; + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x1); + if( ret < 0 ) { + TPDTM_DMESG("synaptics_rmi4_i2c_write_byte failed for page select\n"); + return -1; + } + ret = synaptics_rmi4_i2c_read_block(ts->client, 0xE9, 4, &(buf[0x0])); + F54_ANALOG_QUERY_BASE = buf[0]; + F54_ANALOG_COMMAND_BASE = buf[1]; + F54_ANALOG_CONTROL_BASE = buf[2]; + F54_ANALOG_DATA_BASE = buf[3]; + return 0; +} + +static void checkCMD(void) +{ + int ret; + int flag_err = 0; + struct synaptics_ts_data *ts = ts_g; + do { + delay_qt_ms(30); //wait 10ms + ret = synaptics_rmi4_i2c_read_byte(ts->client, F54_ANALOG_COMMAND_BASE); + flag_err++; + }while( (ret > 0x00) && (flag_err < 30) ); + printk("%s flag_err=%d\n",__func__,flag_err); + if( ret > 0x00 ) + TPD_ERR("checkCMD error ret is %x flag_err is %d\n", ret, flag_err); +} +#endif + +static ssize_t tp_baseline_show(struct device_driver *ddri, char *buf) +{ + int ret = 0; + int x, y; + ssize_t num_read_chars = 0; + uint8_t tmp_l = 0,tmp_h = 0; + uint16_t tmp_old = 0; + uint16_t tmp_new = 0; + uint16_t count = 0; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return count; + memset(delta_baseline,0,sizeof(delta_baseline)); + /*disable irq when read data from IC*/ + touch_disable(ts); + mutex_lock(&ts->mutex); + synaptics_read_register_map_page1(ts); + + TPD_DEBUG("\nstep 1:select report type 0x03 baseline\n"); + + /*step 1:check raw capacitance*/ + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_DATA_BASE, 0x03);//select report type 0x03 + if( ret < 0 ){ + TPDTM_DMESG("step 1: select report type 0x03 failed \n"); + //return sprintf(buf, "i2c err!"); + } + + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+20, 0x01); + ret = i2c_smbus_read_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+23); + tmp_old = ret & 0xff; + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+23, (tmp_old & 0xef)); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+27); + tmp_new = ret & 0xdf; + i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+27, tmp_new); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); // force update + + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+7, 0x01);// Forbid NoiseMitigation + + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); // force update + checkCMD(); + //TPDTM_DMESG("forbid Forbid NoiseMitigation oK\n"); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0X02);//force Cal + checkCMD(); + //TPDTM_DMESG("Force Cal oK\n"); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_DATA_BASE+1, 0x00);//set fifo 00 + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x01);//get report + checkCMD(); + count = 0; + for( x = 0; x < TX_NUM; x++ ){ + //printk("\n[%d]", x); + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]", x); + for( y = 0; y < RX_NUM; y++ ){ + ret = i2c_smbus_read_byte_data(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_l = ret&0xff; + ret = i2c_smbus_read_byte_data(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_h = ret&0xff; + delta_baseline[x][y] = (tmp_h << 8)|tmp_l; + //printk("%d,", delta_baseline[x][y]); + num_read_chars += sprintf(&(buf[num_read_chars]), "%d ", delta_baseline[x][y]); + } + } + TPDTM_DMESG("\nread all is oK\n"); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0X02); + delay_qt_ms(60); + +#ifdef SUPPORT_GLOVES_MODE + synaptics_glove_mode_enable(ts); +#endif + synaptics_init_panel(ts); + + synaptics_enable_interrupt(ts,1); + mutex_unlock(&ts->mutex); + touch_enable(ts); + return num_read_chars; +} + +static ssize_t tp_rawdata_show(struct device_driver *ddri, char *buf) +{ + int ret = 0; + int x, y; + ssize_t num_read_chars = 0; + uint8_t tmp_l = 0, tmp_h = 0; + uint16_t count = 0; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return 0; + memset(delta_baseline, 0, sizeof(delta_baseline)); + /*disable irq when read data from IC*/ + touch_disable(ts); + mutex_lock(&ts->mutex); + synaptics_read_register_map_page1(ts); + + //TPD_DEBUG("\nstep 2:report type2 delta image\n"); + memset(delta_baseline, 0, sizeof(delta_baseline)); + ret = synaptics_rmi4_i2c_write_byte(ts->client, F54_ANALOG_DATA_BASE, 0x02);//select report type 0x02 + ret = synaptics_rmi4_i2c_write_word(ts->client, F54_ANALOG_DATA_BASE+1, 0x00);//set fifo 00 + ret = synaptics_rmi4_i2c_write_byte(ts->client, F54_ANALOG_COMMAND_BASE, 0X01);//get report + checkCMD(); + count = 0; + for( x = 0; x < TX_NUM; x++ ){ + //printk("\n[%d]", x); + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]", x); + for( y = 0; y < RX_NUM; y++ ){ + ret = synaptics_rmi4_i2c_read_byte(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_l = ret&0xff; + ret = synaptics_rmi4_i2c_read_byte(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_h = ret&0xff; + delta_baseline[x][y] = (tmp_h<<8)|tmp_l; + //printk("%3d,", delta_baseline[x][y]); + num_read_chars += sprintf(&(buf[num_read_chars]), "%3d ", delta_baseline[x][y]); + } + } + ret = i2c_smbus_write_byte_data(ts->client,F54_ANALOG_COMMAND_BASE,0X02); + delay_qt_ms(60); + synaptics_enable_interrupt(ts, 1); + mutex_unlock(&ts->mutex); + touch_enable(ts); + return num_read_chars; +} + +static ssize_t tp_delta_store(struct device_driver *ddri, + const char *buf, size_t count) +{ + TPDTM_DMESG("tp_test_store is not support\n"); + return count; +} + +static ssize_t synaptics_rmi4_baseline_show_s3508(struct device *dev, char *buf, bool savefile) +{ + + ssize_t num_read_chars = 0; +#if TP_TEST_ENABLE + int ret = 0; + uint8_t x,y; + int tx_datal; + int16_t baseline_data = 0; + uint8_t tmp_old = 0; + uint8_t tmp_new = 0; + uint8_t tmp_l = 0,tmp_h = 0; + uint16_t count = 0; + int error_count = 0; + uint8_t buffer[9]; + int16_t *baseline_data_test; + int enable_cbc = 1; + + int fd = -1; + struct timespec now_time; + struct rtc_time rtc_now_time; + uint8_t data_buf[64]; + mm_segment_t old_fs; + + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + /* + const struct firmware *fw = NULL; + struct test_header *ph = NULL; + ret = request_firmware(&fw, ts->test_limit_name, dev); + if (ret < 0) { + TPD_ERR("Request firmware failed - %s (%d)\n",ts->test_limit_name, ret); + error_count++; + num_read_chars += sprintf(&(buf[num_read_chars]), "imageid=0x%x,deviceid=0x%x\n",TP_FW,TP_FW); + num_read_chars += sprintf(&(buf[num_read_chars]), "%d error(s). %s\n", error_count, error_count?"":"All test passed."); + return num_read_chars; + } + + //ph = (struct test_header *)(fw->data); + */ + mutex_lock(&ts->mutex); + touch_disable(ts); + + memset(Rxdata, 0, sizeof(Rxdata)); + synaptics_read_register_map_page1(ts); + //TPDTM_DMESG("step 1:select report type 0x03\n"); + + if(savefile) { + getnstimeofday(&now_time); + rtc_time_to_tm(now_time.tv_sec, &rtc_now_time); + sprintf(data_buf, "/sdcard/tp_testlimit_%02d%02d%02d-%02d%02d%02d.csv", + (rtc_now_time.tm_year+1900)%100, rtc_now_time.tm_mon+1, rtc_now_time.tm_mday, + rtc_now_time.tm_hour, rtc_now_time.tm_min, rtc_now_time.tm_sec); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fd = sys_open(data_buf, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) { + TPD_ERR("Open log file '%s' failed.\n", data_buf); + set_fs(old_fs); + } + } + + //step 1:check raw capacitance. +TEST_WITH_CBC_s3508: + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_DATA_BASE, 0x03);//select report type 0x03 + if( ret < 0 ){ + TPD_ERR("read_baseline: i2c_smbus_write_byte_data failed \n"); + goto END; + } + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+20, 0x01); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+23); + tmp_old = ret&0xff; + + if(enable_cbc){ + TPD_DEBUG("ret = %x ,tmp_old =%x ,tmp_new = %x\n",ret,tmp_old,(tmp_old | 0x10)); + ret = i2c_smbus_write_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+23,(tmp_old | 0x10)); + ret = i2c_smbus_write_word_data(ts->client,F54_ANALOG_COMMAND_BASE,0x04); + checkCMD(); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+27); + tmp_new = ret | 0x20; + i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+27, tmp_new); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); + TPD_DEBUG("Test open cbc\n"); + baseline_data_test = (int16_t *)cap_data_JDI[0]; + + }else{ + TPD_DEBUG("ret = %x ,tmp_old =%x ,tmp_new = %x\n",ret,tmp_old,(tmp_old & 0xef)); + ret = i2c_smbus_write_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+23,(tmp_old & 0xef)); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+27); + tmp_new = ret & 0xdf; + i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+27, tmp_new); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); // force update + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+7, 0x01);// Forbid NoiseMitigation + baseline_data_test = (int16_t *)cap_data_JDI[1]; + } + /******write No Relax to 1******/ + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); // force update + checkCMD(); + TPD_DEBUG("forbid Forbid NoiseMitigation oK\n"); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0X02);//force Cal + checkCMD(); + TPD_DEBUG("Force Cal oK\n"); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_DATA_BASE+1, 0x00);//set fifo 00 + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x01);//get report + checkCMD(); + + count = 0; + for( x = 0; x < TX_NUM; x++ ){ + + for( y = 0; y < RX_NUM; y++ ){ + ret = i2c_smbus_read_byte_data(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_l = ret&0xff; + ret = i2c_smbus_read_byte_data(ts->client, F54_ANALOG_DATA_BASE+3); + tmp_h = ret&0xff; + baseline_data = (tmp_h<<8)|tmp_l; + if (fd >= 0){ + sprintf(data_buf, "%d,", baseline_data); + sys_write(fd, data_buf, strlen(data_buf)); + } + if( (y < RX_NUM ) && (x < TX_NUM) ){ + //printk("%4d ,",baseline_data); + if((baseline_data < *(baseline_data_test+count*2)) || (baseline_data > *(baseline_data_test+count*2+1))){ + TPD_ERR("Synaptic:touchpanel failed---------------;baseline_data is %d,TPK_array_limit[%d*2]=%d,TPK_array_limit[%d*2+1]=%d\n ",baseline_data,count,*(baseline_data_test+count*2),count,*(baseline_data_test+count*2+1)); + num_read_chars += sprintf(&(buf[num_read_chars]), "0 raw data erro baseline_data[%d][%d]=%d[%d,%d]\n",x,y,baseline_data,*(baseline_data_test+count*2), *(baseline_data_test+count*2+1)); + error_count++; + goto END; + } + } + /* + //test virtual key + if( (y==(RX_NUM-1)) && (x>= TX_NUM-3) ){ + TPD_DEBUG("synaptics:test virtual key,y= %d ,x = %d\n",y,x); + TPD_DEBUG("Synaptic:test virtual key;baseline_data is %d,TPK_array_limit[%d*2]=%d,TPK_array_limit[%d*2+1]=%d\n ",baseline_data,count,*(baseline_data_test+count*2),count,*(baseline_data_test+count*2+1)); + if((baseline_data < *(baseline_data_test+count*2)) || (baseline_data > *(baseline_data_test+count*2+1))){ + TPD_ERR("Synaptic:test virtual key failed------------;baseline_data is %d,TPK_array_limit[%d*2]=%d,TPK_array_limit[%d*2+1]=%d\n ",baseline_data,count,*(baseline_data_test+count*2),count,*(baseline_data_test+count*2+1)); + num_read_chars += sprintf(&(buf[num_read_chars]), "0 raw data erro baseline_data[%d][%d]=%d[%d,%d]\n",x,y,baseline_data,*(baseline_data_test+count*2), *(baseline_data_test+count*2+1)); + error_count++; + goto END; + } + } + */ + count++; + } + //printk("\n synaptics:s3320 TX_NUM:%d\n",x); + if (fd >= 0){ + sys_write(fd, "\n", 1); + } + } + + if(!enable_cbc){ + enable_cbc = 0; + TPD_ERR("test cbc baseline again\n"); + goto TEST_WITH_CBC_s3508; + } + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); + checkCMD(); + + //step 2 :check tx-to-tx and tx-to-vdd + TPD_ERR("step 2:check TRx-TRx & TRx-Vdd short\n" ); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD_BASE, 0x01);//software reset TP + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_DATA_BASE, 0x1A);//select report type 26 + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_DATA_BASE+1, 0x0); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x01);//get report + //msleep(100); + checkCMD(); + tx_datal = i2c_smbus_read_i2c_block_data(ts->client, F54_ANALOG_DATA_BASE+3, 7, buffer); + for(x = 0;x < 7; x++) + { + //TPD_ERR("Check Trx-trx trx-vdd:buf[%d]=%d", x, buffer[x]); + if(buffer[x]){ + error_count++; + goto END; + } + } + num_read_chars += sprintf(buf, "1"); + + //Step3 : Check trx-to-ground + TPD_ERR("step 3:Check trx-to-ground\n" ); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD_BASE, 0x01);//software reset TP + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_DATA_BASE, 0x1A);//select report type 26 + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_DATA_BASE+1, 0x0); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x01);//get report + checkCMD(); + tx_datal = i2c_smbus_read_i2c_block_data(ts->client, F54_ANALOG_DATA_BASE+3, 7, buffer); + for(x = 0;x < 7; x++) + { + //TPD_ERR("Check trx-to-ground:buf[%d]=%d", x, buffer[x]); + if(buffer[x]){ + error_count++; + goto END; + } + } + +END: + if (fd >= 0) { + sys_close(fd); + set_fs(old_fs); + } + //release_firmware(fw); + num_read_chars += sprintf(&(buf[num_read_chars]), "imageid=0x%x,deviceid=0x%x\n", TP_FW, TP_FW); + num_read_chars += sprintf(&(buf[num_read_chars]), "%d error(s). %s\n", error_count, error_count?"":"All test passed."); + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_COMMAND_BASE, 0X02); + delay_qt_ms(60); + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x00); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD00, 0x01); + msleep(150); + +#ifdef SUPPORT_GLOVES_MODE + synaptics_glove_mode_enable(ts); +#endif + synaptics_init_panel(ts); + synaptics_enable_interrupt(ts, 1); + touch_enable(ts); + printk("\n\nstep5 reset and open irq complete\n"); + mutex_unlock(&ts->mutex); +#endif + return num_read_chars; +} + +static ssize_t tp_baseline_show_with_cbc(struct device_driver *ddri, char *buf) +{ + int ret = 0; + int x,y; + ssize_t num_read_chars = 0; + uint8_t tmp_l = 0,tmp_h = 0; + uint8_t tmp_old, tmp_new; + uint16_t count = 0; + struct synaptics_ts_data *ts = ts_g; + if(ts->is_suspended == 1) + return count; + memset(delta_baseline,0,sizeof(delta_baseline)); + if(!ts) + return 0; + /*disable irq when read data from IC*/ + touch_disable(ts); + mutex_lock(&ts->mutex); + synaptics_read_register_map_page1(ts); + TPD_DEBUG("\nstep 1:select report type 0x03 baseline\n"); + //step 1:check raw capacitance. + + ret = synaptics_rmi4_i2c_write_byte(ts->client,F54_ANALOG_DATA_BASE,0x03);//select report type 0x03 + if (ret < 0) { + TPDTM_DMESG("step 1: select report type 0x03 failed \n"); + //return sprintf(buf, "i2c err!"); + } + + ret = i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+20, 0x01); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+23); + tmp_old = ret&0xff; + TPD_DEBUG("ret = %x ,tmp_old =%x ,tmp_new = %x\n",ret,tmp_old,(tmp_old | 0x10)); + ret = i2c_smbus_write_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+23,(tmp_old | 0x10)); + ret = i2c_smbus_write_word_data(ts->client,F54_ANALOG_COMMAND_BASE,0x04); + checkCMD(); + TPD_DEBUG("open CBC oK\n"); + ret = i2c_smbus_read_byte_data(ts->client,F54_ANALOG_CONTROL_BASE+27); + tmp_new = ret | 0x20; + i2c_smbus_write_byte_data(ts->client, F54_ANALOG_CONTROL_BASE+27, tmp_new); + ret = i2c_smbus_write_word_data(ts->client, F54_ANALOG_COMMAND_BASE, 0x04); + + + ret = synaptics_rmi4_i2c_write_byte(ts->client,F54_ANALOG_COMMAND_BASE,0X04);//force F54_ANALOG_CMD00 + checkCMD(); + TPD_DEBUG("forbid Forbid NoiseMitigation oK\n"); + + ret = synaptics_rmi4_i2c_write_byte(ts->client,F54_ANALOG_COMMAND_BASE,0X02);//Force Cal, F54_ANALOG_CMD00 + checkCMD(); + TPDTM_DMESG("Force Cal oK\n"); + + ret = synaptics_rmi4_i2c_write_word(ts->client,F54_ANALOG_DATA_BASE+1,0x00);//set fifo 00 + ret = synaptics_rmi4_i2c_write_byte(ts->client,F54_ANALOG_COMMAND_BASE,0x01);//get report + checkCMD(); + count = 0; + for(x = 0;x < TX_NUM; x++) { + TPD_DEBUG("\n[%d]",x); + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]",x); + for(y = 0; y < RX_NUM; y++){ + ret = synaptics_rmi4_i2c_read_byte(ts->client,F54_ANALOG_DATA_BASE+3); + tmp_l = ret&0xff; + ret = synaptics_rmi4_i2c_read_byte(ts->client,F54_ANALOG_DATA_BASE+3); + tmp_h = ret&0xff; + delta_baseline[x][y] = (tmp_h<<8)|tmp_l; + TPD_DEBUG("%d,",delta_baseline[x][y]); + num_read_chars += sprintf(&(buf[num_read_chars]), "%d ",delta_baseline[x][y]); + } + } + + ret = synaptics_rmi4_i2c_write_byte(ts->client,F54_ANALOG_COMMAND_BASE,0X02); + delay_qt_ms(60); + synaptics_enable_interrupt(ts,1); + mutex_unlock(&ts->mutex); + touch_enable(ts); + return num_read_chars; +} + +static ssize_t synaptics_rmi4_baseline_show(struct device *dev, char *buf, bool savefile) +{ + return synaptics_rmi4_baseline_show_s3508(dev,buf,savefile); +} + +static ssize_t tp_test_store(struct device_driver *ddri, + const char *buf, size_t count) +{ + TPDTM_DMESG("tp_test_store is not support\n"); + return count; +} + +static ssize_t synaptics_rmi4_vendor_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if( (tp_dev == TP_G2Y) || (tp_dev == TP_TPK) ) + return sprintf(buf, "%d\n", TP_TPK); + if(tp_dev == TP_TRULY) + return sprintf(buf, "%d\n", TP_TRULY); + if(tp_dev == TP_OFILM) + return sprintf(buf, "%d\n", TP_OFILM); + return sprintf(buf, "%d\n", tp_dev); +} + + +static int synaptics_input_init(struct synaptics_ts_data *ts) +{ + int attr_count = 0; + int ret = 0; + + TPD_DEBUG("%s is called\n",__func__); + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("synaptics_ts_probe: Failed to allocate input device\n"); + return ret; + } + ts->input_dev->name = SYNAPTICS_NAME; + ts->input_dev->dev.parent = &ts->client->dev; + set_bit(EV_SYN, ts->input_dev->evbit); + set_bit(EV_ABS, ts->input_dev->evbit); + set_bit(EV_KEY, ts->input_dev->evbit); + set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit); + set_bit(ABS_MT_WIDTH_MAJOR,ts->input_dev->absbit); + set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit); + set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit); + set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + +#ifdef SUPPORT_GESTURE + set_bit(KEY_F4 , ts->input_dev->keybit);//doulbe-tap resume +#ifdef VENDOR_EDIT + set_bit(KEY_DOUBLE_TAP, ts->input_dev->keybit); + set_bit(KEY_GESTURE_CIRCLE, ts->input_dev->keybit); + set_bit(KEY_GESTURE_V, ts->input_dev->keybit); + set_bit(KEY_GESTURE_TWO_SWIPE, ts->input_dev->keybit); + set_bit(KEY_GESTURE_LEFT_V, ts->input_dev->keybit); + set_bit(KEY_GESTURE_RIGHT_V, ts->input_dev->keybit); +#endif +#endif + /* For multi touch */ + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, (ts->max_x-1), 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, (ts->max_y-1), 0, 0); +#ifdef TYPE_B_PROTOCOL + input_mt_init_slots(ts->input_dev, ts->max_num, 0); +#endif + set_bit(BTN_TOUCH, ts->input_dev->keybit); + input_set_drvdata(ts->input_dev, ts); + + if(input_register_device(ts->input_dev)) { + TPD_ERR("%s: Failed to register input device\n",__func__); + input_unregister_device(ts->input_dev); + input_free_device(ts->input_dev); + return -1; + } + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs_oem); attr_count++) { + ret = sysfs_create_file(&ts->input_dev->dev.kobj, + &attrs_oem[attr_count].attr); + if (ret < 0) { + dev_err(&ts->client->dev, + "%s: Failed to create sysfs attributes\n", + __func__); + for (attr_count--; attr_count >= 0; attr_count--) { + sysfs_remove_file(&ts->input_dev->dev.kobj, + &attrs_oem[attr_count].attr); + } + return -1; + } + } + return 0; +} + +/*********************FW Update Func******************************************/ +static int synatpitcs_fw_update(struct device *dev, bool force) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + const struct firmware *fw = NULL; + int ret; + char fw_id_temp[12]; + uint8_t buf[4]; + uint32_t CURRENT_FIRMWARE_ID = 0 ; + + TPD_DEBUG("%s is called\n",__func__); + + if(!ts->client) { + TPD_ERR("i2c client point is NULL\n"); + return 0; + } + ret = request_firmware(&fw, ts->fw_name, dev); + if (ret < 0) { + TPD_ERR("Request firmware failed - %s (%d)\n", + ts->fw_name, ret); + return ret; + } + ret = synapitcs_ts_update(ts->client, fw->data, fw->size, force); + if(ret < 0){ + TPD_ERR("FW update not success try again\n"); + ret = synapitcs_ts_update(ts->client, fw->data, fw->size, force); + if(ret < 0){ + TPD_ERR("FW update failed twice, quit updating process!\n"); + return ret; + } + } + release_firmware(fw); + + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + ret = synaptics_rmi4_i2c_read_block(ts->client, F34_FLASH_CTRL00, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3]; + sprintf(fw_id_temp,"0x%x",CURRENT_FIRMWARE_ID); + strcpy(ts->fw_id,fw_id_temp); + report_key_point_y = ts->max_y*button_map[2]/LCD_HEIGHT; +#ifdef SUPPORT_GLOVES_MODE + synaptics_glove_mode_enable(ts); +#endif + synaptics_init_panel(ts); + synaptics_enable_interrupt(ts,1); + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_mt_sync(ts->input_dev); + input_sync(ts->input_dev); + return 0; +} + +static ssize_t synaptics_update_fw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_ts_data *data = dev_get_drvdata(dev); + return snprintf(buf, 2, "%d\n", data->loading_fw); +} + +static ssize_t synaptics_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + unsigned long val; + int rc; + printk("start update ******* fw_name:%s\n",ts->fw_name); + + if (size > 2) + return -EINVAL; + + rc = kstrtoul(buf, 10, &val); + if (rc != 0) + return rc; + + if(!val) + val = force_update; + + touch_disable(ts); + mutex_lock(&ts->mutex); + ts->loading_fw = true; + synatpitcs_fw_update(dev, val); + ts->loading_fw = false; + mutex_unlock(&ts->mutex); + touch_enable(ts); + force_update = 0; + return size; +} +/*********************FW Update Func End*************************************/ + + +static ssize_t synaptics_test_limit_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + int ret = 0; + uint16_t *prow = NULL; + uint16_t *prowcbc = NULL; + const struct firmware *fw = NULL; + struct test_header *ph = NULL; + int i = 0; + int temp = 0; + static int cat_cbc_change = 0; + ret = request_firmware(&fw, ts->test_limit_name, dev); + if (ret < 0) { + TPD_ERR("Request firmware failed - %s (%d)\n", + ts->test_limit_name, ret); + temp = temp + sprintf(&buf[temp],"Request failed,Check the path %d",temp); + return temp; + } + + ph = (struct test_header *)(fw->data); + prow = (uint16_t *)(fw->data + ph->array_limit_offset); + + prowcbc = (uint16_t *)(fw->data + ph->array_limitcbc_offset); + + TPD_DEBUG("synaptics_test_limit_show:array_limit_offset = %x array_limitcbc_offset = %x\n", + ph->array_limit_offset,ph->array_limitcbc_offset); + + TPD_DEBUG("test begin:\n"); + if(cat_cbc_change == 0 || ph->withCBC == 0) { + temp += sprintf(buf, "Without cbc:"); + for(i = 0 ;i < (ph->array_limit_size/2 ); i++){ + if(i % (2*RX_NUM) == 0) + temp += sprintf(&(buf[temp]), "\n[%d] ",(i/RX_NUM)/2); + temp += sprintf(&buf[temp],"%d,",prow[i]); + printk("%d,",prow[i]); + } + cat_cbc_change = 1; + }else{ + temp += sprintf(buf, "With cbc:"); + cat_cbc_change = 0; + if( ph->withCBC == 0){ + return temp; + } + for(i = 0 ;i < (ph->array_limitcbc_size/2 ); i++){ + if(i % (2*RX_NUM) == 0) + temp += sprintf(&(buf[temp]), "\n[%d] ",(i/RX_NUM)/2); + temp += sprintf(&buf[temp],"%d,",prowcbc[i]); + printk("%d,",prowcbc[i]); + } + } + release_firmware(fw); + return temp; +} + +static ssize_t synaptics_test_limit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + return size; +} + +//static DRIVER_ATTR(tp_baseline_image_with_cbc, 0664, tp_baseline_show_with_cbc, tp_test_store); +static DEVICE_ATTR(test_limit, 0664, synaptics_test_limit_show, synaptics_test_limit_store); +static DRIVER_ATTR(tp_baseline_image, 0664, tp_baseline_show, tp_delta_store); +static DRIVER_ATTR(tp_baseline_image_with_cbc, 0664, tp_baseline_show_with_cbc, tp_test_store); +static DRIVER_ATTR(tp_delta_image, 0664, tp_rawdata_show, NULL); +static DRIVER_ATTR(tp_debug_log, 0664, tp_show, store_tp); +static DEVICE_ATTR(tp_fw_update, 0664, synaptics_update_fw_show, synaptics_update_fw_store); + + +static ssize_t tp_reset_write_func (struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + int ret,write_flag; + struct synaptics_ts_data *ts = ts_g; + + if(ts->loading_fw) { + printk("%s FW is updating break!!\n",__func__); + return count; + } + + ret = sscanf(buffer,"%x",&write_flag); + printk("%s write %d\n",__func__,write_flag); + if (1 == write_flag) + { + ret = synaptics_soft_reset(ts); + } + else if(2 == write_flag) + { + synaptics_hard_reset(ts); + } + else if(3 == write_flag) + { + disable_irq_nosync(ts->irq); + } + else if(4 == write_flag) + { + enable_irq(ts->irq); + } + else if(8 == write_flag) + { + touch_enable(ts); + } + else if(9 == write_flag) + { + touch_disable(ts); + } + return count; +} + +//chenggang.li@bsp add for 14045 +static const struct file_operations base_register_address= { + .write = synap_write_address, + .read = synap_read_address, + .open = simple_open, + .owner = THIS_MODULE, +}; + + +//wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" begin +static const struct file_operations i2c_device_test_fops = { + .read = i2c_device_test_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +//wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" begin +static const struct file_operations tp_baseline_test_proc_fops = { + .read = tp_baseline_test_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +//wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" end + +#ifdef SUPPORT_GLOVES_MODE +static const struct file_operations glove_mode_enable_proc_fops = { + .write = tp_glove_write_func, + .read = tp_glove_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +#endif + +static const struct file_operations sleep_mode_enable_proc_fops = { + .write = tp_sleep_write_func, + .read = tp_sleep_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; + +static const struct file_operations tp_reset_proc_fops = { + .write = tp_reset_write_func, + //.read = tp_sleep_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +static const struct file_operations vendor_id_proc_fops = { + .read = vendor_id_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +static int set_changer_bit(struct synaptics_ts_data *ts) +{ + int mode; + int ret; + mode = i2c_smbus_read_byte_data(ts_g->client, F01_RMI_CTRL00); + if (ts->changer_connet) + mode = mode | 0x20; + else + mode = mode & 0xDF; + ret = i2c_smbus_write_byte_data(ts_g->client, F01_RMI_CTRL00, mode); + return ret; +} +static ssize_t changer_read_func(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) +{ + int ret = 0; + char page[PAGESIZE]; + struct synaptics_ts_data *ts = ts_g; + if(!ts) + return ret; + ret = sprintf(page, "the changer is %s!\n", ts->changer_connet?("conneted"):("disconneted")); + ret = simple_read_from_buffer(user_buf, count, ppos, page, strlen(page)); + return ret; +} + +static ssize_t changer_write_func(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct synaptics_ts_data *ts= ts_g; + int ret = 0 ; + + sscanf(&buffer[0], "%d", &ret); + if(!ts) + return count; + if( (ret == 0 ) || (ret == 1) ){ + ts->changer_connet = ret; + ret = set_changer_bit(ts); + } + TPDTM_DMESG("%s:ts->changer_connet = %d\n",__func__,ts->changer_connet); + return count; +} +static const struct file_operations changer_ops = { + .write = changer_write_func, + .read = changer_read_func, + .open = simple_open, + .owner = THIS_MODULE, +}; +static int init_synaptics_proc(void) +{ + int ret = 0; + struct proc_dir_entry *prEntry_tmp = NULL; + prEntry_tp = proc_mkdir("touchpanel", NULL); + if( prEntry_tp == NULL ){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create TP proc entry\n"); + } + +#ifdef SUPPORT_GESTURE + prEntry_tmp = proc_create( "gesture_enable", 0666, prEntry_tp, &tp_gesture_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create("coordinate", 0444, prEntry_tp, &coordinate_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create("double_tap_enable", 0666, prEntry_tp, &double_tap_enable_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create("camera_enable", 0666, prEntry_tp, &camera_enable_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create("music_enable", 0666, prEntry_tp, &music_enable_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create("flashlight_enable", 0666, prEntry_tp, &flashlight_enable_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } +#endif + +#ifdef SUPPORT_GLOVES_MODE + prEntry_tmp = proc_create( "glove_mode_enable", 0666, prEntry_tp,&glove_mode_enable_proc_fops); + if(prEntry_tmp == NULL) { + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } +#endif + +#ifdef SUPPORT_TP_SLEEP_MODE + prEntry_tmp = proc_create("sleep_mode_enable", 0666, prEntry_tp, &sleep_mode_enable_proc_fops); + if( prEntry_tmp == NULL ){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } +#endif + +#ifdef RESET_ONESECOND + prEntry_tmp = proc_create( "tp_reset", 0666, prEntry_tp, &tp_reset_proc_fops); + if( prEntry_tmp == NULL ){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create tp reset proc entry\n"); + } +#endif + //wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" begin + prEntry_tmp = proc_create( "baseline_test", 0666, prEntry_tp, &tp_baseline_test_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + //wangwenxue@BSP add for change baseline_test to "proc\touchpanel\baseline_test" end + //wangwenxue@BSP add for change baseline_test to "proc\touchpanel\i2c_device_test" begin + prEntry_tmp = proc_create( "i2c_device_test", 0666, prEntry_tp, &i2c_device_test_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + prEntry_tmp = proc_create( "radd", 0777, prEntry_tp, &base_register_address); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + prEntry_tmp = proc_create("vendor_id", 0444, prEntry_tp, &vendor_id_proc_fops); + if(prEntry_tmp == NULL){ + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + prEntry_tmp = proc_create("changer_connet", 0666, prEntry_tp, &changer_ops); + return ret; +} +/******************************end****************************/ + +/****************************S3203*****update**********************************/ +#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10 +#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 + +static void re_scan_PDT(struct i2c_client *client) +{ + uint8_t buf[8]; + i2c_smbus_read_i2c_block_data(client, 0xE9, 6, buf); + SynaF34DataBase = buf[3]; + SynaF34QueryBase = buf[0]; + i2c_smbus_read_i2c_block_data(client, 0xE3, 6, buf); + SynaF01DataBase = buf[3]; + SynaF01CommandBase = buf[1]; + i2c_smbus_read_i2c_block_data(client, 0xDD, 6, buf); + + SynaF34Reflash_BlockNum = SynaF34DataBase; + SynaF34Reflash_BlockData = SynaF34DataBase + 1; + SynaF34ReflashQuery_BootID = SynaF34QueryBase; + SynaF34ReflashQuery_FlashPropertyQuery = SynaF34QueryBase + 1; + SynaF34ReflashQuery_FirmwareBlockSize = SynaF34QueryBase + 2; + SynaF34ReflashQuery_FirmwareBlockCount = SynaF34QueryBase +3; + SynaF34ReflashQuery_ConfigBlockSize = SynaF34QueryBase + 3; + SynaF34ReflashQuery_ConfigBlockCount = SynaF34QueryBase + 3; + i2c_smbus_read_i2c_block_data(client, SynaF34ReflashQuery_FirmwareBlockSize, 2, buf); + SynaFirmwareBlockSize = buf[0] | (buf[1] << 8); + TPD_DEBUG("SynaFirmwareBlockSize 3310 is %d\n", SynaFirmwareBlockSize); + SynaF34_FlashControl = SynaF34DataBase + 2; +} +struct image_header { + /* 0x00 - 0x0f */ + unsigned char checksum[4]; + unsigned char reserved_04; + unsigned char reserved_05; + unsigned char options_firmware_id:1; + unsigned char options_contain_bootloader:1; + unsigned char options_reserved:6; + unsigned char bootloader_version; + unsigned char firmware_size[4]; + unsigned char config_size[4]; + /* 0x10 - 0x1f */ + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE]; + unsigned char package_id[2]; + unsigned char package_id_revision[2]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; + /* 0x20 - 0x2f */ + unsigned char reserved_20_2f[16]; + /* 0x30 - 0x3f */ + unsigned char ds_id[16]; + /* 0x40 - 0x4f */ + unsigned char ds_info[10]; + unsigned char reserved_4a_4f[6]; + /* 0x50 - 0x53 */ + unsigned char firmware_id[4]; +}; + +struct image_header_data { + bool contains_firmware_id; + unsigned int firmware_id; + unsigned int checksum; + unsigned int firmware_size; + unsigned int config_size; + unsigned char bootloader_version; + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; +}; + +static unsigned int extract_uint_le(const unsigned char *ptr) +{ + return (unsigned int)ptr[0] + + (unsigned int)ptr[1] * 0x100 + + (unsigned int)ptr[2] * 0x10000 + + (unsigned int)ptr[3] * 0x1000000; +} + +static void parse_header(struct image_header_data *header, + const unsigned char *fw_image) +{ + struct image_header *data = (struct image_header *)fw_image; + + header->checksum = extract_uint_le(data->checksum); + TPD_DEBUG(" debug checksume is %x", header->checksum); + header->bootloader_version = data->bootloader_version; + TPD_DEBUG(" debug bootloader_version is %d\n", header->bootloader_version); + + header->firmware_size = extract_uint_le(data->firmware_size); + TPD_DEBUG(" debug firmware_size is %x", header->firmware_size); + + header->config_size = extract_uint_le(data->config_size); + TPD_DEBUG(" debug header->config_size is %x", header->config_size); + + memcpy(header->product_id, data->product_id, sizeof(data->product_id)); + header->product_id[sizeof(data->product_id)] = 0; + + memcpy(header->product_info, data->product_info, + sizeof(data->product_info)); + + header->contains_firmware_id = data->options_firmware_id; + TPD_DEBUG(" debug header->contains_firmware_id is %x\n", header->contains_firmware_id); + if( header->contains_firmware_id ) + header->firmware_id = extract_uint_le(data->firmware_id); + + return; +} + +static int checkFlashState(struct i2c_client *client) +{ + int ret ; + int count = 0; + ret = synaptics_rmi4_i2c_read_byte(client,SynaF34_FlashControl+1); + while ( (ret != 0x80)&&(count < 8) ) { + msleep(3); //wait 3ms + ret = synaptics_rmi4_i2c_read_byte(client,SynaF34_FlashControl+1); + count++; + } + if(count == 8) + return 1; + else + return 0; +} + +static int synaptics_fw_check(struct synaptics_ts_data *ts ) +{ + int ret; + uint8_t buf[4]; + uint32_t bootloader_mode; + int max_y_ic = 0; + int max_x_ic = 0; + if(!ts){ + TPD_ERR("%s ts is NULL\n",__func__); + return -1; + } + + ret = synaptics_enable_interrupt(ts, 0); + if(ret < 0) { + TPDTM_DMESG(" synaptics_ts_probe: disable interrupt failed\n"); + } + + /*read product id */ + ret = synaptics_read_product_id(ts); + if(ret) { + TPD_ERR("failed to read product info \n"); + return -1; + } + /*read max_x ,max_y*/ + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if (ret < 0) { + ret = synaptics_rmi4_i2c_write_byte(ts->client, 0xff, 0x0); + if(ret < 0 ){ + TPD_ERR("synaptics_rmi4_i2c_write_byte failed for page select\n"); + return -1; + } + } + + i2c_smbus_read_i2c_block_data(ts->client, F12_2D_CTRL08, 14, buf); + printk("buf[0] = 0x%x, buf[1] = 0x%x\n", buf[0], buf[1]); + max_x_ic = ( (buf[1]<<8)&0xffff ) | (buf[0]&0xffff); + max_y_ic = ( (buf[3]<<8)&0xffff ) | (buf[2]&0xffff); + + TPD_ERR("max_x = %d,max_y = %d\n max_x_ic = %d,max_y_ic = %d\n",ts->max_x,ts->max_y,max_x_ic,max_y_ic); + if((ts->max_x == 0) ||(ts->max_y ==0 )) { + ts->max_x = max_x_ic; + ts->max_y = max_y_ic; + } + bootloader_mode = synaptics_rmi4_i2c_read_byte(ts->client,F01_RMI_DATA_BASE); + bootloader_mode = bootloader_mode&0xff; + bootloader_mode = bootloader_mode&0x40; + TPD_DEBUG("afte fw update,program memory self-check bootloader_mode = 0x%x\n",bootloader_mode); + + if((max_x_ic == 0)||(max_y_ic == 0)||(bootloader_mode == 0x40)) { + TPD_ERR("Something terrible wrong \n Trying Update the Firmware again\n"); + return -1; + } + return 0; +} + +static int synapitcs_ts_update(struct i2c_client *client, const uint8_t *data, uint32_t data_len ,bool force) +{ + int ret,j; + uint8_t buf[8]; + uint8_t bootloder_id[10]; + uint16_t block,firmware,configuration; + uint32_t CURRENT_FIRMWARE_ID = 0 , FIRMWARE_ID = 0; + const uint8_t *Config_Data = NULL; + const uint8_t *Firmware_Data = NULL; + struct image_header_data header; + struct synaptics_ts_data *ts = dev_get_drvdata(&client->dev); + + TPD_DEBUG("%s is called\n",__func__); + if(!client) + return -1; + + parse_header(&header,data); + if((header.firmware_size + header.config_size + 0x100) > data_len) { + TPDTM_DMESG("firmware_size + config_size + 0x100 > data_len data_len = %d \n",data_len); + return -1; + } + + Firmware_Data = data + 0x100; + Config_Data = Firmware_Data + header.firmware_size; + ret = synaptics_rmi4_i2c_write_byte(client, 0xff, 0x0); + + ret = synaptics_rmi4_i2c_read_block(client, F34_FLASH_CTRL00, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3]; + FIRMWARE_ID = (Config_Data[0]<<24)|(Config_Data[1]<<16)|(Config_Data[2]<<8)|Config_Data[3]; + TPD_ERR("CURRENT_FIRMWARE_ID is %x-----------, FIRMWARE_ID is %x-----------\n", CURRENT_FIRMWARE_ID, FIRMWARE_ID); + //TPD_ERR("synaptics force is %d\n", force); + if(!force) { + if(CURRENT_FIRMWARE_ID == FIRMWARE_ID) { + return 0; + } + } + re_scan_PDT(client); + block = 16; + TPD_DEBUG("block is %d \n",block); + firmware = (header.firmware_size)/16; + TPD_DEBUG("firmware is %d \n",firmware); + configuration = (header.config_size)/16; + TPD_DEBUG("configuration is %d \n",configuration); + + + ret = i2c_smbus_read_i2c_block_data(client, SynaF34ReflashQuery_BootID, 8, &(bootloder_id[0])); + TPD_DEBUG("bootloader id is %x \n",(bootloder_id[1] << 8)|bootloder_id[0]); + ret=i2c_smbus_write_i2c_block_data(client, SynaF34Reflash_BlockData, 2, &(bootloder_id[0x0])); + TPDTM_DMESG("Write bootloader id SynaF34_FlashControl is 0x00%x ret is %d\n",SynaF34_FlashControl,ret); + + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x0F); + msleep(10); + TPD_DEBUG("attn step 4\n"); + ret=checkFlashState(client); + if(ret > 0) { + TPD_ERR("Get in prog:The status(Image) of flashstate is %x\n",ret); + return -1; + } + ret = i2c_smbus_read_byte_data(client,0x04); + TPD_DEBUG("The status(device state) is %x\n",ret); + ret= i2c_smbus_read_byte_data(client,F01_RMI_CTRL_BASE); + TPD_DEBUG("The status(control f01_RMI_CTRL_DATA) is %x\n",ret); + ret= i2c_smbus_write_byte_data(client,F01_RMI_CTRL_BASE,ret&0x04); + /********************get into prog end************/ + ret=i2c_smbus_write_i2c_block_data(client, SynaF34Reflash_BlockData, 2, &(bootloder_id[0x0])); + TPD_DEBUG("ret is %d\n",ret); + re_scan_PDT(client); + i2c_smbus_read_i2c_block_data(client,SynaF34ReflashQuery_BootID,2,buf); + i2c_smbus_write_i2c_block_data(client,SynaF34Reflash_BlockData,2,buf); + i2c_smbus_write_byte_data(client,SynaF34_FlashControl,0x03); + msleep(1500); + ret = i2c_smbus_read_byte_data(client,SynaF34_FlashControl); + TPDTM_DMESG("going to flash firmware area synaF34_FlashControl %d\n",ret); + + TPD_ERR("update-----------------firmware ------------------update!\n"); + TPD_DEBUG("cnt %d\n",firmware); + for(j=0; j>8; + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockNum,2,buf); + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockData,16,&Firmware_Data[j*16]); + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x02); + ret=checkFlashState(client); + if(ret > 0) { + TPD_ERR("Firmware:The status(Image) of flash data3 is %x,time =%d\n",ret,j); + return -1; + } + } + //step 7 configure data + //TPD_ERR("going to flash configuration area\n"); + //TPD_ERR("header.firmware_size is 0x%x\n", header.firmware_size); + //TPD_ERR("bootloader_size is 0x%x\n", bootloader_size); + TPD_ERR("update-----------------configuration ------------------update!\n"); + for(j=0;j>8; + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockNum,2,buf); + //b) write data + synaptics_rmi4_i2c_write_block(client,SynaF34Reflash_BlockData,16,&Config_Data[j*16]); + //c) issue write + synaptics_rmi4_i2c_write_byte(client,SynaF34_FlashControl,0x06); + //d) wait attn + ret = checkFlashState(client); + if(ret > 0) { + TPD_ERR("Configuration:The status(Image) of flash data3 is %x,time =%d\n",ret,j); + return -1; + } + } + + //step 1 issue reset + synaptics_rmi4_i2c_write_byte(client,SynaF01CommandBase,0x01); + //step2 wait ATTN + //delay_qt_ms(1000); + mdelay(1500); + synaptics_read_register_map(ts); + //FW flash check! + ret =synaptics_fw_check(ts); + if(ret < 0 ) { + TPD_ERR("Firmware self check failed\n"); + return -1; + } + TPD_DEBUG("Firmware self check Ok\n"); + return 0; +} +static int synaptics_soft_reset(struct synaptics_ts_data *ts) +{ + int ret; + + if(ts->loading_fw) { + TPD_ERR("%s FW is updating break!\n",__func__); + return -1; + } + touch_disable(ts); + ret = i2c_smbus_write_byte_data(ts->client, F01_RMI_CMD_BASE, 0x01); + if (ret < 0){ + TPD_ERR("reset error ret=%d\n",ret); + } + TPD_ERR("%s !!!\n",__func__); + msleep(100); + touch_enable(ts); + return ret; +} +static void synaptics_hard_reset(struct synaptics_ts_data *ts) +{ + if(ts->reset_gpio > 0) + { + gpio_set_value(ts->reset_gpio,0); + msleep(5); + gpio_set_value(ts->reset_gpio,1); + msleep(100); + TPD_ERR("%s !!!\n",__func__); + } + +} +static int synaptics_parse_dts(struct device *dev, struct synaptics_ts_data *ts) +{ + int rc; + struct device_node *np; + int temp_array[2]; + + + np = dev->of_node; + ts->irq_gpio = of_get_named_gpio_flags(np, "synaptics,irq-gpio", 0, &(ts->irq_flags)); + if( ts->irq_gpio < 0 ){ + TPD_DEBUG("ts->irq_gpio not specified\n"); + } + + ts->reset_gpio = of_get_named_gpio(np, "synaptics,reset-gpio", 0); + if( ts->reset_gpio < 0 ){ + TPD_DEBUG("ts->reset-gpio not specified\n"); + } + ts->v1p8_gpio = of_get_named_gpio(np, "synaptics,1v8-gpio", 0); + if( ts->v1p8_gpio < 0 ){ + TPD_DEBUG("ts->1v8-gpio not specified\n"); + } + + if(of_property_read_bool(np, "oem,support_hw_poweroff")) + ts->support_hw_poweroff=true; + else + ts->support_hw_poweroff=false; + + TPD_ERR("%s ts->support_hw_poweroff =%d\n",__func__,ts->support_hw_poweroff); + + ts->enable2v8_gpio = of_get_named_gpio(np, "synaptics,enable2v8-gpio", 0); + if( ts->enable2v8_gpio < 0 ){ + TPD_DEBUG("ts->enable2v8_gpio not specified\n"); + } + + rc = of_property_read_u32(np, "synaptics,max-num-support", &ts->max_num); + if(rc){ + TPD_DEBUG("ts->max_num not specified\n"); + ts->max_num = 10; + } + + rc = of_property_read_u32_array(np, "synaptics,button-map", button_map, 3); + if(rc){ + TPD_DEBUG("button-map not specified\n"); + //button_map[0] = 180; + //button_map[1] = 180; + //button_map[2] = 2021; + } + TPD_DEBUG("synaptics:button map readed is %d %d %d\n", button_map[0], button_map[1], button_map[2]); + + rc = of_property_read_u32_array(np, "synaptics,tx-rx-num", tx_rx_num,2); + if(rc){ + TPD_ERR("button-map not specified\n"); + TX_NUM = 30; + RX_NUM = 17; + }else{ + TX_NUM = tx_rx_num[0]; + RX_NUM = tx_rx_num[1]; + } + TPD_ERR("synaptics,tx-rx-num is %d %d \n", TX_NUM,RX_NUM); + + rc = of_property_read_u32_array(np, "synaptics,display-coords", temp_array, 2); + if(rc){ + TPD_ERR("lcd size not specified\n"); + LCD_WIDTH = 1080; + LCD_HEIGHT = 1920; + }else{ + LCD_WIDTH = temp_array[0]; + LCD_HEIGHT = temp_array[1]; + } + rc = of_property_read_u32_array(np, "synaptics,panel-coords", temp_array, 2); + if(rc){ + ts->max_x = 1080; + ts->max_y = 1920; + }else{ + ts->max_x = temp_array[0]; + ts->max_y = temp_array[1]; + } + TPDTM_DMESG("synaptic:ts->irq_gpio:%d irq_flags:%u max_num %d\n"\ + ,ts->irq_gpio, ts->irq_flags, ts->max_num); + + /***********power regulator_get****************/ + ts->vdd_2v8 = regulator_get(&ts->client->dev, "vdd_2v8"); + if( IS_ERR(ts->vdd_2v8) ){ + rc = PTR_ERR(ts->vdd_2v8); + TPD_DEBUG("Regulator get failed vdd rc=%d\n", rc); + } + + ts->vcc_i2c_1v8 = regulator_get(&ts->client->dev, "vcc_i2c_1v8"); + if( IS_ERR(ts->vcc_i2c_1v8) ){ + rc = PTR_ERR(ts->vcc_i2c_1v8); + TPD_DEBUG("Regulator get failed vcc_i2c rc=%d\n", rc); + } + + if( ts->reset_gpio > 0){ + if( gpio_is_valid(ts->reset_gpio) ){ + rc = gpio_request(ts->reset_gpio, "tp-s3320-reset"); + if(rc){ + TPD_ERR("unable to request reset_gpio [%d]\n", ts->reset_gpio); + } + } + } + if( ts->v1p8_gpio > 0){ + if( gpio_is_valid(ts->v1p8_gpio) ){ + rc = gpio_request(ts->v1p8_gpio, "tp-s3320-1v8"); + if(rc){ + TPD_ERR("unable to request v1p8_gpio [%d]\n", ts->v1p8_gpio); + } + } + } + + if( ts->enable2v8_gpio > 0){ + if( gpio_is_valid(ts->enable2v8_gpio) ){ + rc = gpio_request(ts->enable2v8_gpio, "rmi4-enable2v8-gpio"); + if(rc) + TPD_ERR("unable to request enable2v8_gpio [%d]\n", ts->enable2v8_gpio); + + } + } + + return rc; +} + +static int synaptics_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ +#ifdef CONFIG_SYNAPTIC_RED + struct remotepanel_data *premote_data = NULL; +#endif + struct synaptics_ts_data *ts = NULL; + int ret = -1; + uint8_t buf[4]; + uint32_t CURRENT_FIRMWARE_ID = 0; + uint32_t bootloader_mode; + + TPD_ERR("%s is called\n",__func__); + + ts = kzalloc(sizeof(struct synaptics_ts_data), GFP_KERNEL); + if( ts == NULL ) { + ret = -ENOMEM; + goto err_alloc_data_failed; + } + + ts->client = client; + i2c_set_clientdata(client, ts); + ts->dev = &client->dev; + ts->loading_fw = false; + ts_g = ts; + + synaptics_parse_dts(&client->dev, ts); + + /***power_init*****/ + ret = tpd_power(ts, 1); + if( ret < 0 ) + TPD_ERR("regulator_enable is called\n"); + + mutex_init(&ts->mutex); + atomic_set(&ts->irq_enable,0); + init_synaptics_proc(); + + ts->is_suspended = 0; + atomic_set(&ts->is_stop,0); + spin_lock_init(&ts->lock); + /*****power_end*********/ + if( !i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ){ + TPD_ERR("%s: need I2C_FUNC_I2C\n", __func__); + ret = -ENODEV; + goto err_check_functionality_failed; + } + + ret = synaptics_rmi4_i2c_read_byte(client, 0x13); + if( ret < 0 ) { + ret = synaptics_rmi4_i2c_read_byte(client, 0x13); + if( ret < 0 ) { + printk("synaptics is no exist!\n"); + goto err_check_functionality_failed; + } + } + + ts->i2c_device_test = ret; + + synaptics_read_register_map(ts); + bootloader_mode = synaptics_rmi4_i2c_read_byte(ts->client, F01_RMI_DATA_BASE); + + bootloader_mode = bootloader_mode&0x40; + printk("synaptics:before fw update,bootloader_mode = 0x%x\n", bootloader_mode); + + synaptics_rmi4_i2c_read_block(ts->client, F34_FLASH_CTRL00, 4, buf); + CURRENT_FIRMWARE_ID = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + TPD_ERR("CURRENT_FIRMWARE_ID = 0x%x\n", CURRENT_FIRMWARE_ID); + TP_FW = CURRENT_FIRMWARE_ID; + sprintf(ts->fw_id,"0x%x",TP_FW); + + memset(ts->fw_name,TP_FW_NAME_MAX_LEN,0); + memset(ts->test_limit_name,TP_FW_NAME_MAX_LEN,0); + + sprintf(ts->manu_name, "TP_JDI"); + + strcpy(ts->fw_name,"tp/14049/14049_FW_S3320_jdi.img"); + strcpy(ts->test_limit_name,"tp/14049/14049_Limit_jdi.img"); + TPD_DEBUG("synatpitcs_fw: fw_name = %s \n",ts->fw_name); + + push_component_info(TP, ts->fw_id, ts->manu_name); + + synaptics_wq = create_singlethread_workqueue("synaptics_wq"); + if( !synaptics_wq ){ + ret = -ENOMEM; + goto exit_createworkqueue_failed; + } + INIT_DELAYED_WORK(&ts->speed_up_work,speedup_synaptics_resume); + + synaptics_report = create_singlethread_workqueue("synaptics_report"); + if( !synaptics_report ){ + ret = -ENOMEM; + goto exit_createworkqueue_failed; + } + INIT_WORK(&ts->report_work,synaptics_ts_work_func); + + ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */ + if (ret < 0) { + TPD_ERR("synaptics_init_panel failed\n"); + } + + //Detect whether TP FW is error, max_x,max_y may be incoorect while it has been damaged! + ret = synaptics_fw_check(ts); + if(ret < 0 ) { + force_update = 1; + TPD_ERR("This FW need to be updated!\n"); + } else { + force_update = 0; + } + /*disable interrupt*/ + ret = synaptics_enable_interrupt(ts, 0); + if( ret < 0 ) { + TPD_ERR(" synaptics_ts_probe: disable interrupt failed\n"); + } + ret = synaptics_soft_reset(ts); + if (ret < 0){ + TPD_ERR("%s faile to reset device\n",__func__); + } + ret = synaptics_input_init(ts); + if(ret < 0) { + TPD_ERR("synaptics_input_init failed!\n"); + } +#if defined(CONFIG_FB) + ts->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); + if(ret) + TPD_ERR("Unable to register fb_notifier: %d\n", ret); +#endif + + + +#ifndef TPD_USE_EINT + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = synaptics_ts_timer_func; + hrtimer_start(&ts->timer, ktime_set(3, 0), HRTIMER_MODE_REL); +#endif + +#ifdef TPD_USE_EINT + /**************** + shoud set the irq GPIO + *******************/ + if (gpio_is_valid(ts->irq_gpio)) { + /* configure touchscreen irq gpio */ + ret = gpio_request(ts->irq_gpio,"tp-s3320-irq"); + if (ret) { + TPD_ERR("unable to request gpio [%d]\n",ts->irq_gpio); + } + ret = gpio_direction_input(ts->irq_gpio); + msleep(50); + ts->irq = gpio_to_irq(ts->irq_gpio); + } + TPD_ERR("synaptic:ts->irq is %d\n",ts->irq); + + ret = request_threaded_irq(ts->irq, NULL, + synaptics_irq_thread_fn, + ts->irq_flags | IRQF_ONESHOT, + TPD_DEVICE, ts); + if(ret < 0) + TPD_ERR("%s request_threaded_irq ret is %d\n",__func__,ret); + msleep(5); + ret = synaptics_enable_interrupt(ts, 1); + if(ret < 0) + TPD_ERR("%s enable interrupt error ret=%d\n",__func__,ret); +#endif + + if (device_create_file(&client->dev, &dev_attr_test_limit)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + TPD_DEBUG("synaptics_ts_probe: going to create files--tp_fw_update\n"); + if (device_create_file(&client->dev, &dev_attr_tp_fw_update)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + if( driver_create_file(&tpd_i2c_driver.driver, &driver_attr_tp_debug_log)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + if (driver_create_file(&tpd_i2c_driver.driver, &driver_attr_tp_baseline_image_with_cbc)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + if( driver_create_file(&tpd_i2c_driver.driver, &driver_attr_tp_baseline_image)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + if( driver_create_file(&tpd_i2c_driver.driver, &driver_attr_tp_delta_image)) { + TPDTM_DMESG("driver_create_file failt\n"); + goto exit_init_failed; + } + +#ifdef CONFIG_SYNAPTIC_RED + premote_data = remote_alloc_panel_data(); + if(premote_data) { + premote_data->client = client; + premote_data->input_dev = ts->input_dev; + premote_data->pmutex = &ts->mutex; + premote_data->irq_gpio = ts->irq_gpio; + premote_data->irq = client->irq; + premote_data->enable_remote = &(ts->enable_remote); + register_remote_device(premote_data); + + } +#endif + TPDTM_DMESG("synaptics_ts_probe 3203: normal end\n"); + return 0; + +exit_init_failed: + free_irq(client->irq,ts); +exit_createworkqueue_failed: + destroy_workqueue(synaptics_wq); + synaptics_wq = NULL; + destroy_workqueue(synaptics_report); + synaptics_report = NULL; + +err_check_functionality_failed: + tpd_power(ts, 0); +err_alloc_data_failed: + kfree(ts); + ts = NULL; + ts_g = NULL; + printk("synaptics_ts_probe: not normal end\n"); + return ret; +} + +static int synaptics_ts_remove(struct i2c_client *client) +{ + int attr_count; + struct synaptics_ts_data *ts = i2c_get_clientdata(client); + + printk("%s is called\n",__func__); +#ifdef CONFIG_SYNAPTIC_RED + unregister_remote_device(); +#endif + +#if defined(CONFIG_FB) + if( fb_unregister_client(&ts->fb_notif) ) + dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); +#endif + +#ifndef TPD_USE_EINT + hrtimer_cancel(&ts->timer); +#endif + + for(attr_count = 0; attr_count < ARRAY_SIZE(attrs_oem); attr_count++){ + sysfs_remove_file(&ts->input_dev->dev.kobj, &attrs_oem[attr_count].attr); + } + input_unregister_device(ts->input_dev); + input_free_device(ts->input_dev); + kfree(ts); + tpd_hw_pwroff(ts); + return 0; +} + +static int synaptics_ts_suspend(struct device *dev) +{ + int ret,i; + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + TPDTM_DMESG("%s: is called\n", __func__); + + if(ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("input_dev registration is not complete\n"); + return -1; + } + if(ts->loading_fw) { + TPD_ERR("FW is updating while suspending"); + return -1; + } + //ts->is_suspended = 1; + for (i = 0; i < ts->max_num; i++) + { + input_mt_slot(ts->input_dev, i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } +#ifndef TYPE_B_PROTOCOL + input_mt_sync(ts->input_dev); +#endif + input_sync(ts->input_dev); + +#ifndef TPD_USE_EINT + hrtimer_cancel(&ts->timer); +#endif + +#ifdef SUPPORT_GESTURE + if( ts->double_enable ){ + synaptics_enable_interrupt_for_gesture(ts, 1); + TPD_ERR("synaptics s3320 enable gesture by suspend\n"); + atomic_set(&ts->is_stop,0); + return 0; + } +#endif + + ret = synaptics_mode_change(0x01); + if( ret < 0 ){ + TPD_ERR("%s: synaptics s3320 to sleep failed\n", __func__); + return -1; + } + touch_disable(ts); +//#ifdef SUPPORT_SLEEP_POWEROFF + if(ts->support_hw_poweroff){ + ret = tpd_hw_pwroff(ts); + if (ret < 0) + TPD_ERR("%s power off err\n",__func__); + } +//#endif + TPD_ERR("%s:normal end\n", __func__); + return 0; +} + +static void speedup_synaptics_resume(struct work_struct *work) +{ + touch_enable(ts_g); +#ifdef SUPPORT_GLOVES_MODE + ret = synaptics_glove_mode_enable(ts_g); + if(ret){ + TPD_ERR("%s: set gloves mode err!!\n", __func__); + } +#endif +} + +static int synaptics_ts_resume(struct device *dev) +{ + int ret; + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + + TPD_ERR("%s is called\n", __func__); + + if(ts->loading_fw) { + TPD_ERR("%s FW is updating break!\n",__func__); + return -1; + } +//#ifdef SUPPORT_SLEEP_POWEROFF + if (ts->support_hw_poweroff){ + if(0 == ts->double_enable) + { + ret = tpd_hw_pwron(ts); + if (ret < 0) + TPD_ERR("%s power on err\n",__func__); + touch_enable(ts); + return 0; + } + } +//#endif + + if(ts->input_dev == NULL) { + ret = -ENOMEM; + TPD_ERR("input_dev registration is not complete\n"); + goto ERR_RESUME; + } + + //ts->is_suspended = 0; +#ifndef TYPE_B_PROTOCOL + input_mt_sync(ts->input_dev); +#endif + input_sync(ts->input_dev); + + mutex_lock(&ts->mutex); +#ifndef TPD_USE_EINT + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); +#else + + ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x0); + /*****Gesture Register********/ + if( ts->double_enable ) + { + ret = synaptics_enable_interrupt_for_gesture(ts, 0); + if(ret<0) + TPD_ERR("%s: failed to disable gesture report!!\n", __func__); + } + gpio_set_value(ts->reset_gpio,0); + msleep(5); + gpio_set_value(ts->reset_gpio,1); +#endif + //queue_delayed_work(synaptics_wq,&ts->speed_up_work, msecs_to_jiffies(500)); + TPD_ERR("%s:normal end!\n", __func__); +ERR_RESUME: + mutex_unlock(&ts->mutex); + return 0; +} + +static int synaptics_i2c_suspend(struct device *dev) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + TPD_DEBUG("%s: is called\n", __func__); + if (ts->gesture_enable == 1){ + /*enable gpio wake system through intterrupt*/ + enable_irq_wake(ts->irq); + } + return 0; +} + +static int synaptics_i2c_resume(struct device *dev) +{ + struct synaptics_ts_data *ts = dev_get_drvdata(dev); + TPD_DEBUG("%s is called\n", __func__); + if (ts->gesture_enable == 1){ + /*disable gpio wake system through intterrupt*/ + disable_irq_wake(ts->irq); + } + //enable_irq(ts->irq); + return 0; +} +static int synaptics_mode_change(int mode) +{ + int ret; + int tmp_mode; + tmp_mode = i2c_smbus_read_byte_data(ts_g->client, F01_RMI_CTRL00); + tmp_mode = tmp_mode & 0xF8; + tmp_mode = tmp_mode | mode; + ret = i2c_smbus_write_byte_data(ts_g->client, F01_RMI_CTRL00, tmp_mode); + if(ret<0) + TPD_ERR("%s: set dose mode err!!\n", __func__); + return ret; +} +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + //int ret; + + struct synaptics_ts_data *ts = container_of(self, struct synaptics_ts_data, fb_notif); + + if(FB_EARLY_EVENT_BLANK != event && FB_EVENT_BLANK != event) + return 0; + if((evdata) && (evdata->data) && (ts) && (ts->client)) { + blank = evdata->data; + if((*blank == FB_BLANK_UNBLANK || *blank == FB_BLANK_VSYNC_SUSPEND)\ + && (event == FB_EARLY_EVENT_BLANK )) { + if (ts->is_suspended == 1) + { + TPD_DEBUG("%s going TP resume\n", __func__); + synaptics_ts_resume(&ts->client->dev); + ts->is_suspended = 0; + atomic_set(&ts->is_stop,0); + } + } else if( *blank == FB_BLANK_POWERDOWN && (event == FB_EVENT_BLANK )) { + if (ts->is_suspended == 0) + { + TPD_DEBUG("%s : going TP suspend\n", __func__); + synaptics_ts_suspend(&ts->client->dev); + ts->is_suspended = 1; + } + } + else if( *blank == FB_BLANK_UNBLANK && (event == FB_EVENT_BLANK )) { + //ret = synaptics_mode_change(0x04); + //TPD_DEBUG("%s %d F01_RMI_CTRL00:0x%x = 0x%x\n",__func__,__LINE__, + // F01_RMI_CTRL00,i2c_smbus_read_byte_data(ts_g->client, F01_RMI_CTRL00)); + queue_delayed_work(synaptics_wq,&ts->speed_up_work, msecs_to_jiffies(5)); + }else if( *blank == FB_BLANK_POWERDOWN && (event == FB_EARLY_EVENT_BLANK )) { + atomic_set(&ts->is_stop,1); + } + } + return 0; +} +#endif + +static int __init tpd_driver_init(void) +{ + printk("Synaptics:%s is called\n", __func__); + if( i2c_add_driver(&tpd_i2c_driver)!= 0 ){ + TPDTM_DMESG("unable to add i2c driver.\n"); + return -1; + } + return 0; +} + +/* should never be called */ +static void __exit tpd_driver_exit(void) +{ + i2c_del_driver(&tpd_i2c_driver); + if(synaptics_wq ){ + destroy_workqueue(synaptics_wq); + synaptics_wq = NULL; + } + return; +} + +module_init(tpd_driver_init); +module_exit(tpd_driver_exit); + +MODULE_DESCRIPTION("Synaptics S3203 Touchscreen Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_dsx.h b/drivers/input/touchscreen/synaptics_dsx.h new file mode 100755 index 0000000000000..2e6c1180cafe6 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx.h @@ -0,0 +1,61 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SYNAPTICS_DSX_H_ +#define _SYNAPTICS_DSX_H_ + +/* + * synaptics_dsx_cap_button_map - 0d button map + * @nbuttons: number of 0d buttons + * @map: pointer to array of button types + */ +struct synaptics_dsx_cap_button_map { + unsigned char nbuttons; + unsigned char *map; +}; + +/* + * struct synaptics_dsx_platform_data - dsx platform data + * @x_flip: x flip flag + * @y_flip: y flip flag + * @regulator_en: regulator enable flag + * @reset_gpio: reset gpio + * @irq_gpio: attention interrupt gpio + * @irq_flags: irq flags + * @panel_x: x-axis resolution of display panel + * @panel_y: y-axis resolution of display panel + * @gpio_config: pointer to gpio configuration function + * @cap_button_map: pointer to 0d button map + */ +struct synaptics_dsx_platform_data { + bool x_flip; + bool y_flip; + bool swap_axes; + bool regulator_en; + int reset_gpio; + int irq_gpio; + unsigned long irq_flags; + unsigned int panel_x; + unsigned int panel_y; + unsigned int reset_delay_ms; + int (*gpio_config)(int gpio, bool configure); + struct synaptics_dsx_cap_button_map *cap_button_map; +}; + +#endif diff --git a/drivers/input/touchscreen/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_fw_update.c new file mode 100755 index 0000000000000..d1c0b2b1b51a1 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx_fw_update.c @@ -0,0 +1,2144 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "synaptics_dsx.h" +#include "synaptics_dsx_i2c.h" +#include "synaptics_firmware_jdi_14049.h" +#include "synaptics_firmware_s1302.h" + +#include +#include +#include +#include + +#define FW_IMAGE_NAME "synaptics/startup_fw_update.img" +static char s1302_vendor_str[32]; //vendor string + +#define DO_STARTUP_FW_UPDATE +#define STARTUP_FW_UPDATE_DELAY_MS 200 /* ms */ +#define FORCE_UPDATE false +#define DO_LOCKDOWN false + +#define MAX_IMAGE_NAME_LEN 256 +#define MAX_FIRMWARE_ID_LEN 10 + +#define LOCKDOWN_OFFSET 0xb0 +#define FW_IMAGE_OFFSET 0x100 + +#define BOOTLOADER_ID_OFFSET 0 +#define BLOCK_NUMBER_OFFSET 0 + +#define V5_PROPERTIES_OFFSET 2 +#define V5_BLOCK_SIZE_OFFSET 3 +#define V5_BLOCK_COUNT_OFFSET 5 +#define V5_BLOCK_DATA_OFFSET 2 + +#define V6_PROPERTIES_OFFSET 1 +#define V6_BLOCK_SIZE_OFFSET 2 +#define V6_BLOCK_COUNT_OFFSET 3 +#define V6_BLOCK_DATA_OFFSET 1 +#define V6_FLASH_COMMAND_OFFSET 2 +#define V6_FLASH_STATUS_OFFSET 3 + +#define LOCKDOWN_BLOCK_COUNT 5 + +#define REG_MAP (1 << 0) +#define UNLOCKED (1 << 1) +#define HAS_CONFIG_ID (1 << 2) +#define HAS_PERM_CONFIG (1 << 3) +#define HAS_BL_CONFIG (1 << 4) +#define HAS_DISP_CONFIG (1 << 5) +#define HAS_CTRL1 (1 << 6) + +#define UI_CONFIG_AREA 0x00 +#define PERM_CONFIG_AREA 0x01 +#define BL_CONFIG_AREA 0x02 +#define DISP_CONFIG_AREA 0x03 + +#define CMD_WRITE_FW_BLOCK 0x2 +#define CMD_ERASE_ALL 0x3 +#define CMD_WRITE_LOCKDOWN_BLOCK 0x4 +#define CMD_READ_CONFIG_BLOCK 0x5 +#define CMD_WRITE_CONFIG_BLOCK 0x6 +#define CMD_ERASE_CONFIG 0x7 +#define CMD_ERASE_BL_CONFIG 0x9 +#define CMD_ERASE_DISP_CONFIG 0xa +#define CMD_ENABLE_FLASH_PROG 0xf + +#define SLEEP_MODE_NORMAL (0x00) +#define SLEEP_MODE_SENSOR_SLEEP (0x01) +#define SLEEP_MODE_RESERVED0 (0x02) +#define SLEEP_MODE_RESERVED1 (0x03) + +#define ENABLE_WAIT_MS (1 * 1000) +#define WRITE_WAIT_MS (1) +#define ERASE_WAIT_MS (5 * 1000) + +#define MIN_SLEEP_TIME_US 50 +#define MAX_SLEEP_TIME_US 100 + +static ssize_t fwu_sysfs_show_image(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t fwu_sysfs_store_image(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_write_config_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_read_config_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_config_area_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_image_name_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_image_size_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t fwu_sysfs_block_size_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf); + +enum bl_version { + V5 = 5, + V6 = 6, +}; + +enum flash_area { + NONE, + UI_FIRMWARE, + CONFIG_AREA, +}; + +enum update_mode { + NORMAL = 1, + FORCE = 2, + LOCKDOWN = 8, +}; + +struct image_header { + /* 0x00 - 0x0f */ + unsigned char checksum[4]; + unsigned char reserved_04; + unsigned char reserved_05; + unsigned char options_firmware_id:1; + unsigned char options_contain_bootloader:1; + unsigned char options_reserved:6; + unsigned char bootloader_version; + unsigned char firmware_size[4]; + unsigned char config_size[4]; + /* 0x10 - 0x1f */ + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE]; + unsigned char package_id[2]; + unsigned char package_id_revision[2]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; + /* 0x20 - 0x2f */ + unsigned char reserved_20_2f[16]; + /* 0x30 - 0x3f */ + unsigned char ds_id[16]; + /* 0x40 - 0x4f */ + unsigned char ds_info[10]; + unsigned char reserved_4a_4f[6]; + /* 0x50 - 0x53 */ + unsigned char firmware_id[4]; +}; + +struct image_header_data { + bool contains_firmware_id; + unsigned int firmware_id; + unsigned int checksum; + unsigned int firmware_size; + unsigned int config_size; + unsigned char bootloader_version; + unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; +}; + +struct pdt_properties { + union { + struct { + unsigned char reserved_1:6; + unsigned char has_bsr:1; + unsigned char reserved_2:1; + } __packed; + unsigned char data[1]; + }; +}; + +struct f01_device_status { + union { + struct { + unsigned char status_code:4; + unsigned char reserved:2; + unsigned char flash_prog:1; + unsigned char unconfigured:1; + } __packed; + unsigned char data[1]; + }; +}; + +struct f01_device_control { + union { + struct { + unsigned char sleep_mode:2; + unsigned char nosleep:1; + unsigned char reserved:2; + unsigned char charger_connected:1; + unsigned char report_rate:1; + unsigned char configured:1; + } __packed; + unsigned char data[1]; + }; +}; + +struct synaptics_rmi4_fwu_handle { + enum bl_version bl_version; + bool initialized; + bool program_enabled; + bool has_perm_config; + bool has_bl_config; + bool has_disp_config; + bool force_update; + bool in_flash_prog_mode; + bool do_lockdown; + unsigned int data_pos; + unsigned int image_size; + unsigned char *image_name; + unsigned char *ext_data_source; + unsigned char *read_config_buf; + unsigned char intr_mask; + unsigned char command; + unsigned char bootloader_id[2]; + unsigned char flash_properties; + unsigned char flash_status; + unsigned char productinfo1; + unsigned char productinfo2; + unsigned char properties_off; + unsigned char blk_size_off; + unsigned char blk_count_off; + unsigned char blk_data_off; + unsigned char flash_cmd_off; + unsigned char flash_status_off; + unsigned short block_size; + unsigned short fw_block_count; + unsigned short config_block_count; + unsigned short lockdown_block_count; + unsigned short perm_config_block_count; + unsigned short bl_config_block_count; + unsigned short disp_config_block_count; + unsigned short config_size; + unsigned short config_area; + char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; + const unsigned char *firmware_data; + const unsigned char *config_data; + const unsigned char *lockdown_data; + struct workqueue_struct *fwu_workqueue; + struct delayed_work fwu_work; + struct synaptics_rmi4_fn_desc f01_fd; + struct synaptics_rmi4_fn_desc f34_fd; + struct synaptics_rmi4_exp_fn_ptr *fn_ptr; + struct synaptics_rmi4_data *rmi4_data; +}; + +static struct bin_attribute dev_attr_data = { + .attr = { + .name = "data", + .mode = (S_IWUSR | S_IRUSR), + }, + .size = 0, + .read = fwu_sysfs_show_image, + .write = fwu_sysfs_store_image, +}; + +static struct device_attribute attrs[] = { + __ATTR(doreflash, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_do_reflash_store), + __ATTR(writeconfig, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_write_config_store), + __ATTR(readconfig, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_read_config_store), + __ATTR(configarea, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_config_area_store), + __ATTR(imagename, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_image_name_store), + __ATTR(imagesize, S_IWUSR, + synaptics_rmi4_show_error, + fwu_sysfs_image_size_store), + __ATTR(blocksize, S_IRUGO, + fwu_sysfs_block_size_show, + synaptics_rmi4_store_error), + __ATTR(fwblockcount, S_IRUGO, + fwu_sysfs_firmware_block_count_show, + synaptics_rmi4_store_error), + __ATTR(configblockcount, S_IRUGO, + fwu_sysfs_configuration_block_count_show, + synaptics_rmi4_store_error), + __ATTR(permconfigblockcount, S_IRUGO, + fwu_sysfs_perm_config_block_count_show, + synaptics_rmi4_store_error), + __ATTR(blconfigblockcount, S_IRUGO, + fwu_sysfs_bl_config_block_count_show, + synaptics_rmi4_store_error), + __ATTR(dispconfigblockcount, S_IRUGO, + fwu_sysfs_disp_config_block_count_show, + synaptics_rmi4_store_error), +}; + +static struct synaptics_rmi4_fwu_handle *fwu; + +DECLARE_COMPLETION(fwu_remove_complete); + +static unsigned int extract_uint_le(const unsigned char *ptr) +{ + return (unsigned int)ptr[0] + + (unsigned int)ptr[1] * 0x100 + + (unsigned int)ptr[2] * 0x10000 + + (unsigned int)ptr[3] * 0x1000000; +} + +static unsigned int extract_uint_be(const unsigned char *ptr) +{ + return (unsigned int)ptr[3] + + (unsigned int)ptr[2] * 0x100 + + (unsigned int)ptr[1] * 0x10000 + + (unsigned int)ptr[0] * 0x1000000; +} + +static void parse_header(struct image_header_data *header, + const unsigned char *fw_image) +{ + struct image_header *data = (struct image_header *)fw_image; + + header->checksum = extract_uint_le(data->checksum); + + header->bootloader_version = data->bootloader_version; + + header->firmware_size = extract_uint_le(data->firmware_size); + + header->config_size = extract_uint_le(data->config_size); + + memcpy(header->product_id, data->product_id, sizeof(data->product_id)); + header->product_id[sizeof(data->product_id)] = 0; + + memcpy(header->product_info, data->product_info, + sizeof(data->product_info)); + + header->contains_firmware_id = data->options_firmware_id; + if (header->contains_firmware_id) + header->firmware_id = extract_uint_le(data->firmware_id); + + return; +} + +static int fwu_read_f01_device_status(struct f01_device_status *status) +{ + int retval; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f01_fd.data_base_addr, + status->data, + sizeof(status->data)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read F01 device status\n", + __func__); + return retval; + } + + return 0; +} + +static int fwu_read_f34_queries(void) +{ + int retval; + unsigned char count; + unsigned char buf[10]; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET, + fwu->bootloader_id, + sizeof(fwu->bootloader_id)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read bootloader ID\n", + __func__); + return retval; + } + + if (fwu->bootloader_id[1] == '5') { + fwu->bl_version = V5; + } else if (fwu->bootloader_id[1] == '6') { + fwu->bl_version = V6; + } else { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Unrecognized bootloader version\n", + __func__); + return -EINVAL; + } + + if (fwu->bl_version == V5) { + fwu->properties_off = V5_PROPERTIES_OFFSET; + fwu->blk_size_off = V5_BLOCK_SIZE_OFFSET; + fwu->blk_count_off = V5_BLOCK_COUNT_OFFSET; + fwu->blk_data_off = V5_BLOCK_DATA_OFFSET; + } else if (fwu->bl_version == V6) { + fwu->properties_off = V6_PROPERTIES_OFFSET; + fwu->blk_size_off = V6_BLOCK_SIZE_OFFSET; + fwu->blk_count_off = V6_BLOCK_COUNT_OFFSET; + fwu->blk_data_off = V6_BLOCK_DATA_OFFSET; + } + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.query_base_addr + fwu->properties_off, + &fwu->flash_properties, + sizeof(fwu->flash_properties)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read flash properties\n", + __func__); + return retval; + } + + count = 4; + + if (fwu->flash_properties & HAS_PERM_CONFIG) { + fwu->has_perm_config = 1; + count += 2; + } + + if (fwu->flash_properties & HAS_BL_CONFIG) { + fwu->has_bl_config = 1; + count += 2; + } + + if (fwu->flash_properties & HAS_DISP_CONFIG) { + fwu->has_disp_config = 1; + count += 2; + } + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.query_base_addr + fwu->blk_size_off, + buf, + 2); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read block size info\n", + __func__); + return retval; + } + + batohs(&fwu->block_size, &(buf[0])); + + if (fwu->bl_version == V5) { + fwu->flash_cmd_off = fwu->blk_data_off + fwu->block_size; + fwu->flash_status_off = fwu->flash_cmd_off; + } else if (fwu->bl_version == V6) { + fwu->flash_cmd_off = V6_FLASH_COMMAND_OFFSET; + fwu->flash_status_off = V6_FLASH_STATUS_OFFSET; + } + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.query_base_addr + fwu->blk_count_off, + buf, + count); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read block count info\n", + __func__); + return retval; + } + + batohs(&fwu->fw_block_count, &(buf[0])); + batohs(&fwu->config_block_count, &(buf[2])); + + count = 4; + + if (fwu->has_perm_config) { + batohs(&fwu->perm_config_block_count, &(buf[count])); + count += 2; + } + + if (fwu->has_bl_config) { + batohs(&fwu->bl_config_block_count, &(buf[count])); + count += 2; + } + + if (fwu->has_disp_config) + batohs(&fwu->disp_config_block_count, &(buf[count])); + + return 0; +} + +static int fwu_read_f34_flash_status(void) +{ + int retval; + unsigned char status; + unsigned char command; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->flash_status_off, + &status, + sizeof(status)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read flash status\n", + __func__); + return retval; + } + + fwu->program_enabled = status >> 7; + + if (fwu->bl_version == V5) + fwu->flash_status = (status >> 4) & MASK_3BIT; + else if (fwu->bl_version == V6) + fwu->flash_status = status & MASK_3BIT; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->flash_cmd_off, + &command, + sizeof(command)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read flash command\n", + __func__); + return retval; + } + + fwu->command = command & MASK_4BIT; + + return 0; +} + +static int fwu_write_f34_command(unsigned char cmd) +{ + int retval; + unsigned char command = cmd & MASK_4BIT; + + fwu->command = cmd; + + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->flash_cmd_off, + &command, + sizeof(command)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write command 0x%02x\n", + __func__, command); + return retval; + } + + return 0; +} + +static int fwu_wait_for_idle(int timeout_ms) +{ + int count = 0; + int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1; + + do { + usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US); + + count++; + if (count == timeout_count) + fwu_read_f34_flash_status(); + + if ((fwu->command == 0x00) && (fwu->flash_status == 0x00)) + { + return 0; + } + } while (count < timeout_count); + + printk("synap %s: Timed out waiting for idle status\n", + __func__); + + return -ETIMEDOUT; +} + +static enum flash_area fwu_go_nogo(struct image_header_data *header) +{ + int retval; + enum flash_area flash_area = NONE; + unsigned char index = 0; + unsigned char config_id[4]; + unsigned int device_config_id; + unsigned int image_config_id; + unsigned int device_fw_id; + unsigned long image_fw_id; + char *strptr; + char *firmware_id; + + if (fwu->force_update) { + flash_area = UI_FIRMWARE; + goto exit; + } + + /* Update both UI and config if device is in bootloader mode */ + if (fwu->in_flash_prog_mode) { + flash_area = UI_FIRMWARE; + goto exit; + } + + /* Get device firmware ID */ + device_fw_id = fwu->rmi4_data->firmware_id; +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: Device firmware ID = %d\n", +// __func__, device_fw_id); + +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: image firmware ID = %d\n", +// __func__, header->firmware_id); + header->contains_firmware_id = 1 ; + header->firmware_id = device_fw_id ; + + /* Get image firmware ID */ + if (header->contains_firmware_id) { + image_fw_id = header->firmware_id; + } else { + strptr = strstr(fwu->image_name, "PR"); + if (!strptr) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: No valid PR number (PRxxxxxxx) " + "found in image file name (%s)\n", + __func__, fwu->image_name); + flash_area = NONE; + goto exit; + } + + strptr += 2; + firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL); + while (strptr[index] >= '0' && strptr[index] <= '9') { + firmware_id[index] = strptr[index]; + index++; + } + + retval = sstrtoul(firmware_id, 10, &image_fw_id); + kfree(firmware_id); + if (retval) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to obtain image firmware ID\n", + __func__); + flash_area = NONE; + goto exit; + } + } +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: Image firmware ID = %d\n", +// __func__, (unsigned int)image_fw_id); + + if (image_fw_id > device_fw_id) { + flash_area = UI_FIRMWARE; + goto exit; + } else if (image_fw_id < device_fw_id) { + dev_info(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Image firmware ID older than device firmware ID\n", + __func__); + flash_area = NONE; + goto exit; + } + + /* Get device config ID */ + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.ctrl_base_addr, + config_id, + sizeof(config_id)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read device config ID\n", + __func__); + flash_area = NONE; + goto exit; + } + device_config_id = extract_uint_be(config_id); +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: Device config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", +// __func__, +// config_id[0], +// config_id[1], +// config_id[2], +// config_id[3]); + + /* Get image config ID */ + image_config_id = extract_uint_be(fwu->config_data); +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: Image config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", +// __func__, +// fwu->config_data[0], +// fwu->config_data[1], +// fwu->config_data[2], +// fwu->config_data[3]); + + fwu->rmi4_data->image_cid = image_config_id; + fwu->rmi4_data->device_cid = device_config_id ; + printk("[syna] config id: [image]=0x%x,[device]=0x%x\n",image_config_id,device_config_id); + + if (image_config_id != device_config_id || fwu->force_update) { + printk("[syna] config id: [image]=0x%x,[device]=0x%x, update!\n",image_config_id,device_config_id); + flash_area = UI_FIRMWARE; + goto exit; + } + + flash_area = NONE; + +exit: +// if (flash_area == NONE) { +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: No need to do reflash\n", +// __func__); +// } else { +// dev_info(&fwu->rmi4_data->i2c_client->dev, +// "synap %s: Updating %s\n", +// __func__, +// flash_area == UI_FIRMWARE ? +// "UI firmware" : +// "config only"); +// } + + return flash_area; +} + +static int fwu_scan_pdt(void) +{ + int retval; + unsigned char ii; + unsigned char intr_count = 0; + unsigned char intr_off; + unsigned char intr_src; + unsigned short addr; + bool f01found = false; + bool f34found = false; + struct synaptics_rmi4_fn_desc rmi_fd; + + for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) { + retval = fwu->fn_ptr->read(fwu->rmi4_data, + addr, + (unsigned char *)&rmi_fd, + sizeof(rmi_fd)); + if (retval < 0) + return retval; + + if (rmi_fd.fn_number) { + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Found F%02x\n", + __func__, rmi_fd.fn_number); + switch (rmi_fd.fn_number) { + case SYNAPTICS_RMI4_F01: + f01found = true; + fwu->f01_fd.query_base_addr = + rmi_fd.query_base_addr; + fwu->f01_fd.ctrl_base_addr = + rmi_fd.ctrl_base_addr; + fwu->f01_fd.data_base_addr = + rmi_fd.data_base_addr; + fwu->f01_fd.cmd_base_addr = + rmi_fd.cmd_base_addr; + break; + case SYNAPTICS_RMI4_F34: + f34found = true; + fwu->f34_fd.query_base_addr = + rmi_fd.query_base_addr; + fwu->f34_fd.ctrl_base_addr = + rmi_fd.ctrl_base_addr; + fwu->f34_fd.data_base_addr = + rmi_fd.data_base_addr; + + fwu->intr_mask = 0; + intr_src = rmi_fd.intr_src_count; + intr_off = intr_count % 8; + for (ii = intr_off; + ii < ((intr_src & MASK_3BIT) + + intr_off); + ii++) { + fwu->intr_mask |= 1 << ii; + } + break; + } + } else { + break; + } + + intr_count += (rmi_fd.intr_src_count & MASK_3BIT); + } + + if (!f01found || !f34found) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to find both F01 and F34\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt, + unsigned char command) +{ + int retval; + unsigned char block_offset[] = {0, 0}; + unsigned short block_num; + + block_offset[1] |= (fwu->config_area << 5); + + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET, + block_offset, + sizeof(block_offset)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write to block number registers\n", + __func__); + return retval; + } + + for (block_num = 0; block_num < block_cnt; block_num++) { + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->blk_data_off, + block_ptr, + fwu->block_size); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write block data (block %d)\n", + __func__, block_num); + return retval; + } + + retval = fwu_write_f34_command(command); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write command for block %d\n", + __func__, block_num); + return retval; + } + + retval = fwu_wait_for_idle(WRITE_WAIT_MS); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to wait for idle status (block %d)\n", + __func__, block_num); + return retval; + } + + block_ptr += fwu->block_size; + } + + return 0; +} + +static int fwu_write_firmware(void) +{ + return fwu_write_blocks((unsigned char *)fwu->firmware_data, + fwu->fw_block_count, CMD_WRITE_FW_BLOCK); +} + +static int fwu_write_configuration(void) +{ + return fwu_write_blocks((unsigned char *)fwu->config_data, + fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK); +} + +static int fwu_write_lockdown(void) +{ + return fwu_write_blocks((unsigned char *)fwu->lockdown_data, + fwu->lockdown_block_count, CMD_WRITE_LOCKDOWN_BLOCK); +} + +static int fwu_write_bootloader_id(void) +{ + int retval; + + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->blk_data_off, + fwu->bootloader_id, + sizeof(fwu->bootloader_id)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write bootloader ID\n", + __func__); + return retval; + } + + return 0; +} + +static int fwu_enter_flash_prog(void) +{ + int retval; + struct f01_device_status f01_device_status; + struct f01_device_control f01_device_control; + + retval = fwu_write_bootloader_id(); + if (retval < 0) + return retval; + + retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG); + if (retval < 0) + return retval; + + retval = fwu_wait_for_idle(ENABLE_WAIT_MS); + if (retval < 0) + return retval; + + if (!fwu->program_enabled) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Program enabled bit not set\n", + __func__); + return -EINVAL; + } + + retval = fwu_scan_pdt(); + if (retval < 0) + return retval; + + retval = fwu_read_f01_device_status(&f01_device_status); + if (retval < 0) + return retval; + + if (!f01_device_status.flash_prog) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Not in flash prog mode\n", + __func__); + return -EINVAL; + } + + retval = fwu_read_f34_queries(); + if (retval < 0) + return retval; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f01_fd.ctrl_base_addr, + f01_device_control.data, + sizeof(f01_device_control.data)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read F01 device control\n", + __func__); + return retval; + } + + f01_device_control.nosleep = true; + f01_device_control.sleep_mode = SLEEP_MODE_NORMAL; + + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f01_fd.ctrl_base_addr, + f01_device_control.data, + sizeof(f01_device_control.data)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write F01 device control\n", + __func__); + return retval; + } + + return retval; +} + +static int fwu_do_reflash(void) +{ + int retval; + + + retval = fwu_enter_flash_prog(); + if (retval < 0) + return retval; + + printk("synap %s: Entered flash prog mode\n", + __func__); + + retval = fwu_write_bootloader_id(); + if (retval < 0) + return retval; + + printk("synap %s: Bootloader ID written\n", + __func__); + + retval = fwu_write_f34_command(CMD_ERASE_ALL); + if (retval < 0) + return retval; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Erase all command written\n", + __func__); + + retval = fwu_wait_for_idle(ERASE_WAIT_MS); + if (retval < 0) + return retval; + + printk("synap %s: Idle status detected\n",__func__); + + if (fwu->firmware_data) { + retval = fwu_write_firmware(); + if (retval < 0) + return retval; + pr_notice("synap %s: Firmware programmed\n", __func__); + } + printk("synap %s: write_configuration\n",__func__); + if (fwu->config_data) { + retval = fwu_write_configuration(); + if (retval < 0) + return retval; + pr_notice("synap %s: Configuration programmed\n", __func__); + } + + return retval; +} + +static int fwu_do_write_config(void) +{ + int retval; + + retval = fwu_enter_flash_prog(); + if (retval < 0) + return retval; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Entered flash prog mode\n", + __func__); + + if (fwu->config_area == PERM_CONFIG_AREA) { + fwu->config_block_count = fwu->perm_config_block_count; + goto write_config; + } + + retval = fwu_write_bootloader_id(); + if (retval < 0) + return retval; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Bootloader ID written\n", + __func__); + + switch (fwu->config_area) { + case UI_CONFIG_AREA: + retval = fwu_write_f34_command(CMD_ERASE_CONFIG); + break; + case BL_CONFIG_AREA: + retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG); + fwu->config_block_count = fwu->bl_config_block_count; + break; + case DISP_CONFIG_AREA: + retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG); + fwu->config_block_count = fwu->disp_config_block_count; + break; + } + if (retval < 0) + return retval; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Erase command written\n", + __func__); + + retval = fwu_wait_for_idle(ERASE_WAIT_MS); + if (retval < 0) + return retval; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Idle status detected\n", + __func__); + +write_config: + retval = fwu_write_configuration(); + if (retval < 0) + return retval; + + pr_notice("synap %s: Config written\n", __func__); + + return retval; +} + +static int fwu_start_write_config(void) +{ + int retval; + unsigned short block_count; + unsigned short f01_cmd_base_addr; + struct image_header_data header; + + f01_cmd_base_addr = fwu->f01_fd.cmd_base_addr; + + switch (fwu->config_area) { + case UI_CONFIG_AREA: + block_count = fwu->config_block_count; + break; + case PERM_CONFIG_AREA: + if (!fwu->has_perm_config) + return -EINVAL; + block_count = fwu->perm_config_block_count; + break; + case BL_CONFIG_AREA: + if (!fwu->has_bl_config) + return -EINVAL; + block_count = fwu->bl_config_block_count; + break; + case DISP_CONFIG_AREA: + if (!fwu->has_disp_config) + return -EINVAL; + block_count = fwu->disp_config_block_count; + break; + default: + return -EINVAL; + } + + if (fwu->ext_data_source) + fwu->config_data = fwu->ext_data_source; + else + return -EINVAL; + + fwu->config_size = fwu->block_size * block_count; + + /* Jump to the config area if given a packrat image */ + if ((fwu->config_area == UI_CONFIG_AREA) && + (fwu->config_size != fwu->image_size)) { + parse_header(&header, fwu->ext_data_source); + + if (header.config_size) { + fwu->config_data = fwu->ext_data_source + + FW_IMAGE_OFFSET + + header.firmware_size; + } else { + return -EINVAL; + } + } + + pr_notice("synap %s: Start of write config process\n", __func__); + + retval = fwu_do_write_config(); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write config\n", + __func__); + } + + fwu->rmi4_data->reset_device(fwu->rmi4_data, f01_cmd_base_addr); + + pr_notice("synap %s: End of write config process\n", __func__); + + return retval; +} + +static int fwu_do_read_config(void) +{ + int retval; + unsigned char block_offset[] = {0, 0}; + unsigned short block_num; + unsigned short block_count; + unsigned short index = 0; + unsigned short f01_cmd_base_addr; + + f01_cmd_base_addr = fwu->f01_fd.cmd_base_addr; + + retval = fwu_enter_flash_prog(); + if (retval < 0) + goto exit; + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Entered flash prog mode\n", + __func__); + + switch (fwu->config_area) { + case UI_CONFIG_AREA: + block_count = fwu->config_block_count; + break; + case PERM_CONFIG_AREA: + if (!fwu->has_perm_config) { + retval = -EINVAL; + goto exit; + } + block_count = fwu->perm_config_block_count; + break; + case BL_CONFIG_AREA: + if (!fwu->has_bl_config) { + retval = -EINVAL; + goto exit; + } + block_count = fwu->bl_config_block_count; + break; + case DISP_CONFIG_AREA: + if (!fwu->has_disp_config) { + retval = -EINVAL; + goto exit; + } + block_count = fwu->disp_config_block_count; + break; + default: + retval = -EINVAL; + goto exit; + } + + fwu->config_size = fwu->block_size * block_count; + + kfree(fwu->read_config_buf); + fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL); + + block_offset[1] |= (fwu->config_area << 5); + + retval = fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET, + block_offset, + sizeof(block_offset)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write to block number registers\n", + __func__); + goto exit; + } + + for (block_num = 0; block_num < block_count; block_num++) { + retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to write read config command\n", + __func__); + goto exit; + } + + retval = fwu_wait_for_idle(WRITE_WAIT_MS); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to wait for idle status\n", + __func__); + goto exit; + } + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.data_base_addr + fwu->blk_data_off, + &fwu->read_config_buf[index], + fwu->block_size); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read block data (block %d)\n", + __func__, block_num); + goto exit; + } + + index += fwu->block_size; + } + +exit: + fwu->rmi4_data->reset_device(fwu->rmi4_data, f01_cmd_base_addr); + + return retval; +} + +static int fwu_do_lockdown(void) +{ + int retval; + + retval = fwu_enter_flash_prog(); + if (retval < 0) + return retval; + + retval = fwu->fn_ptr->read(fwu->rmi4_data, + fwu->f34_fd.query_base_addr + fwu->properties_off, + &fwu->flash_properties, + sizeof(fwu->flash_properties)); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to read flash properties\n", + __func__); + return retval; + } + + if ((fwu->flash_properties & UNLOCKED) == 0) { + dev_info(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Device already locked down\n", + __func__); + return retval; + } + + retval = fwu_write_lockdown(); + if (retval < 0) + return retval; + + pr_notice("synap %s: Lockdown programmed\n", __func__); + + return retval; +} + +static int fwu_start_reflash(void) +{ + int retval = 0; + enum flash_area flash_area; + unsigned short f01_cmd_base_addr; + struct image_header_data header; + struct f01_device_status f01_device_status; + const unsigned char *fw_image; + const struct firmware *fw_entry = NULL; + unsigned char command = 0x01; + + f01_cmd_base_addr = fwu->f01_fd.cmd_base_addr; + + if (fwu->rmi4_data->sensor_sleep) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Sensor sleeping\n", + __func__); + return -ENODEV; + } + + fwu->rmi4_data->stay_awake = true; + + //pr_notice("synap %s: Start of reflash process\n", __func__); + + if (fwu->ext_data_source) { + fw_image = fwu->ext_data_source; + } else { + strncpy(fwu->image_name, FW_IMAGE_NAME, MAX_IMAGE_NAME_LEN); + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Requesting firmware image %s\n", + __func__, fwu->image_name); + + retval = request_firmware(&fw_entry, fwu->image_name, + &fwu->rmi4_data->i2c_client->dev); + if (retval != 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Firmware image %s not available\n", + __func__, fwu->image_name); + retval = -EINVAL; + goto exit; + } + + dev_dbg(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Firmware image size = %d\n", + __func__, (int)fw_entry->size); + + fw_image = fw_entry->data; + } + + parse_header(&header, fw_image); + + if (fwu->bl_version != header.bootloader_version) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Bootloader version mismatch\n", + __func__); + retval = -EINVAL; + goto exit; + } + + retval = fwu_read_f01_device_status(&f01_device_status); + if (retval < 0) + goto exit; + + if (f01_device_status.flash_prog) { + dev_info(&fwu->rmi4_data->i2c_client->dev, + "synap %s: In flash prog mode\n", + __func__); + fwu->in_flash_prog_mode = true; + } else { + fwu->in_flash_prog_mode = false; + } + + if (fwu->do_lockdown) { + switch (fwu->bl_version) { + case V5: + case V6: + fwu->lockdown_data = fw_image + LOCKDOWN_OFFSET; + fwu->lockdown_block_count = LOCKDOWN_BLOCK_COUNT; + retval = fwu_do_lockdown(); + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to do lockdown\n", + __func__); + } + default: + break; + } + } + + if (header.firmware_size) + fwu->firmware_data = fw_image + FW_IMAGE_OFFSET; + if (header.config_size) { + fwu->config_data = fw_image + FW_IMAGE_OFFSET + + header.firmware_size; + } + + flash_area = fwu_go_nogo(&header); + //flash_area = UI_FIRMWARE; // add by lauson , force update. + switch (flash_area) { + case UI_FIRMWARE: + retval = fwu_do_reflash(); + break; + case CONFIG_AREA: + retval = fwu_do_write_config(); + break; + case NONE: + default: + goto exit; + } + + if (retval < 0) { + dev_err(&fwu->rmi4_data->i2c_client->dev, + "synap %s: Failed to do reflash\n", + __func__); + } + +exit: + if(flash_area) + { + // reset tp + fwu->fn_ptr->write(fwu->rmi4_data, + fwu->f01_fd.cmd_base_addr, + &command, + sizeof(command)); + + fwu->rmi4_data->reset_device(fwu->rmi4_data, f01_cmd_base_addr); + } + + if (fw_entry) + release_firmware(fw_entry); + + //pr_notice("synap %s: End of reflash process\n", __func__); + + fwu->rmi4_data->stay_awake = false; + + return retval; +} + +static int synaptics_rmi4_fwu_init_func(struct synaptics_rmi4_data *rmi4_data) ; + +//return current firmware version +int synaptics_rmi4_get_firmware_version(int vendor_id) +{ + if(vendor_id == TP_VENDOR_JDI) + { + return FIRMWARE_JDI_14049_VERSION; + } + else + { + return 0 ; + } +} + +int synaptics_fw_updater(unsigned char *fw_data) +{ + int retval; + + if (!fwu) + return -ENODEV; + + if (!fwu->initialized) + return -ENODEV; + + fwu->ext_data_source = fw_data; + fwu->config_area = UI_CONFIG_AREA; + + retval = fwu_start_reflash(); + + return retval; +} +EXPORT_SYMBOL(synaptics_fw_updater); + +//read tp firmware from /sdcard/synaptics/startup_fw_update.img +#include +static unsigned char* synaptics_get_fw_from_file(void) +{ + int fd = 0; + int count = 0; + unsigned char* filedata = NULL; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + sprintf(fwu->image_name,"%s/%s",fwu->image_name,FW_IMAGE_NAME); + fd = sys_open(fwu->image_name, O_RDONLY, 0); + if (fd < 0) { + set_fs(old_fs); + printk(KERN_WARNING "synap %s: Can not open firmware:%d\n", __func__,fd); + return 0; + } + count = sys_lseek(fd, (off_t)0, 2); + if (count <= 0) { + goto err_load_fw_close_file; + } + + sys_lseek(fd, (off_t)0, 0); + filedata = kmalloc(count, GFP_KERNEL); + if (!filedata) { + printk(KERN_WARNING "synap %s: Can not alloc data\n", __func__); + goto err_load_fw_close_file; + } + if (sys_read(fd, (char *)filedata, count) != count) { + goto err_load_fw_free_data; + } + + if (strncmp(filedata+0x10, "S3508", 5)) { + printk(KERN_WARNING "synap %s: Not correct fw file.\n", __func__); + goto err_load_fw_free_data; + } + + sys_close(fd); + set_fs(old_fs); + + return filedata ; + + +err_load_fw_free_data: + kfree(filedata); +err_load_fw_close_file: + sys_close(fd); + set_fs(old_fs); + fwu->image_name[0] = 0; + return 0; +} + +static unsigned char* fwu_rmi4_get_firmware_data(void) { + unsigned char* firmwaredata = 0; + unsigned int vendor_id ; + + if(!fwu || !(fwu->rmi4_data)) + return 0 ; + + vendor_id = fwu->rmi4_data->vendor_id ; + + if(fwu->image_name && fwu->image_name[0] != 0) //add manual update firmware + { + firmwaredata = synaptics_get_fw_from_file(); + } + else if(1302 == fwu->rmi4_data->product_info) + { + firmwaredata = (unsigned char*)Syna_Firmware_Data; + printk("synap firmware update s1302!\n"); + } + else if(3320 == fwu->rmi4_data->product_info) + { + if(vendor_id == TP_VENDOR_JDI) + { + firmwaredata = (unsigned char*)Syna_Firmware_Data_JDI_14049; + printk("synap firmware update s3320!\n"); + } + } + + return firmwaredata ; +} + +char* synaptics_s1302_get_vender(void) +{ + char *pconst = "fW_version"; + + //printk("synap %s, pconst = %s, version = 0x%x\n", __func__, pconst, FIRMWARE_VERSION); + sprintf(s1302_vendor_str,"%s(%x)",pconst,FIRMWARE_VERSION); + + return s1302_vendor_str; +} +EXPORT_SYMBOL(synaptics_s1302_get_vender); +static void fwu_startup_fw_update_work(struct work_struct *work) +{ + unsigned char* firmwaredata = 0; + + firmwaredata = fwu_rmi4_get_firmware_data() ; + if(!firmwaredata) { + printk("[syna]can't find firmware data\n"); + if(fwu && (fwu->rmi4_data)) + fwu->rmi4_data->bcontinue = 1 ; + return ; + } + + synaptics_fw_updater(firmwaredata); + + fwu->image_name[0] = 0; + + fwu->rmi4_data->bcontinue = 1 ; + + return; +} + +static ssize_t fwu_sysfs_show_image(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + if (count < fwu->config_size) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Not enough space (%d bytes) in buffer\n", + __func__, (int)count); + return -EINVAL; + } + + memcpy(buf, fwu->read_config_buf, fwu->config_size); + + return fwu->config_size; +} + +static ssize_t fwu_sysfs_store_image(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]), + (const void *)buf, + count); + + fwu->data_pos += count; + + return count; +} + +static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + if (sscanf(buf, "%u", &input) != 1) { + retval = -EINVAL; + goto exit; + } + + if (input & LOCKDOWN) { + fwu->do_lockdown = true; + input &= ~LOCKDOWN; + } + + if ((input != NORMAL) && (input != FORCE)) { + retval = -EINVAL; + goto exit; + } + + if (input == FORCE) + fwu->force_update = true; + + retval = synaptics_fw_updater(fwu->ext_data_source); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to do reflash\n", + __func__); + goto exit; + } + + retval = count; + +exit: + kfree(fwu->ext_data_source); + fwu->ext_data_source = NULL; + fwu->force_update = FORCE_UPDATE; + fwu->do_lockdown = DO_LOCKDOWN; + return retval; +} + +static ssize_t fwu_sysfs_write_config_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + if (sscanf(buf, "%u", &input) != 1) { + retval = -EINVAL; + goto exit; + } + + if (input != 1) { + retval = -EINVAL; + goto exit; + } + + retval = fwu_start_write_config(); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to write config\n", + __func__); + goto exit; + } + + retval = count; + +exit: + kfree(fwu->ext_data_source); + fwu->ext_data_source = NULL; + return retval; +} + +static ssize_t fwu_sysfs_read_config_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + retval = fwu_do_read_config(); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to read config\n", + __func__); + return retval; + } + + return count; +} + +static ssize_t fwu_sysfs_config_area_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned long config_area; + + retval = sstrtoul(buf, 10, &config_area); + if (retval) + return retval; + + fwu->config_area = config_area; + + return count; +} + +static ssize_t fwu_sysfs_image_name_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + memcpy(fwu->image_name, buf, count); + + return count; +} + +static ssize_t fwu_sysfs_image_size_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned long size; + struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + retval = sstrtoul(buf, 10, &size); + if (retval) + return retval; + + fwu->image_size = size; + fwu->data_pos = 0; + + kfree(fwu->ext_data_source); + fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL); + if (!fwu->ext_data_source) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to alloc mem for image data\n", + __func__); + return -ENOMEM; + } + + return count; +} + +static ssize_t fwu_sysfs_block_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size); +} + +static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count); +} + +static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count); +} + +static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count); +} + +static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count); +} + +static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count); +} + +static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask) +{ + if (!fwu) + return; + + if (fwu->intr_mask & intr_mask) + fwu_read_f34_flash_status(); + + return; +} + +//init device's function +static int synaptics_rmi4_fwu_init_func(struct synaptics_rmi4_data *rmi4_data) { + int retval; + struct pdt_properties pdt_props; + + retval = fwu->fn_ptr->read(rmi4_data, + PDT_PROPS, + pdt_props.data, + sizeof(pdt_props.data)); + if (retval < 0) { + dev_dbg(&rmi4_data->i2c_client->dev, + "synap %s: Failed to read PDT properties, assuming 0x00\n", + __func__); + } else if (pdt_props.has_bsr) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Reflash for LTS not currently supported\n", + __func__); + retval = -ENODEV; + goto exit_free_mem; + } + + retval = fwu_scan_pdt(); + if (retval < 0) + goto exit_free_mem; + + fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0]; + fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1]; + memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string, + SYNAPTICS_RMI4_PRODUCT_ID_SIZE); + fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0; + + dev_dbg(&rmi4_data->i2c_client->dev, + "synap %s: F01 product info: 0x%04x 0x%04x\n", + __func__, fwu->productinfo1, fwu->productinfo2); + dev_dbg(&rmi4_data->i2c_client->dev, + "synap %s: F01 product ID: %s\n", + __func__, fwu->product_id); + + retval = fwu_read_f34_queries(); + if (retval < 0) + goto exit_free_mem; + + fwu->force_update = FORCE_UPDATE; + fwu->do_lockdown = DO_LOCKDOWN; + fwu->initialized = true; + + return 0 ; + +exit_free_mem: + + return retval; + +} + +static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char attr_count; + int i,match; + + fwu = kzalloc(sizeof(*fwu), GFP_KERNEL); + if (!fwu) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to alloc mem for fwu\n", + __func__); + retval = -ENOMEM; + goto exit; + } + + fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL); + if (!fwu->fn_ptr) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to alloc mem for fn_ptr\n", + __func__); + retval = -ENOMEM; + goto exit_free_fwu; + } + + fwu->image_name = kzalloc(MAX_IMAGE_NAME_LEN, GFP_KERNEL); + if (!fwu->image_name) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to alloc mem for image name\n", + __func__); + retval = -ENOMEM; + goto exit_free_fn_ptr; + } + + fwu->rmi4_data = rmi4_data; + fwu->fn_ptr->read = rmi4_data->i2c_read; + fwu->fn_ptr->write = rmi4_data->i2c_write; + fwu->fn_ptr->enable = rmi4_data->irq_enable; + + if(synaptics_rmi4_fwu_init_func(rmi4_data)) + goto exit_free_mem ; + + + + retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj, + &dev_attr_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to create sysfs bin file\n", + __func__); + goto exit_free_mem; + } + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, + &attrs[attr_count].attr); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "synap %s: Failed to create sysfs attributes\n", + __func__); + retval = -ENODEV; + goto exit_remove_attrs; + } + } + +#ifdef DO_STARTUP_FW_UPDATE +if (1) +{ + fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue"); + INIT_DELAYED_WORK(&fwu->fwu_work, fwu_startup_fw_update_work); + /*Call fwu thread to idle CPU*/ + match = 0; + for(i = 0; i < 3; i++){ + if(cpu_is_offline(i)||(i==smp_processor_id())) + continue; + queue_delayed_work_on(i, fwu->fwu_workqueue, + &fwu->fwu_work, + msecs_to_jiffies(STARTUP_FW_UPDATE_DELAY_MS)); + printk("synaptics fwu queue work %d\n", i); + match = 1; + break; + } + if(match == 0) + queue_delayed_work_on(0, fwu->fwu_workqueue, + &fwu->fwu_work, + msecs_to_jiffies(STARTUP_FW_UPDATE_DELAY_MS)); +} +#endif + + return 0; + +exit_remove_attrs: +for (attr_count--; attr_count >= 0; attr_count--) { + sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, + &attrs[attr_count].attr); +} + +sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); + +exit_free_mem: + kfree(fwu->image_name); + +exit_free_fn_ptr: + kfree(fwu->fn_ptr); + +exit_free_fwu: + kfree(fwu); + fwu = NULL; + +exit: + return retval; +} + +static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data) +{ + unsigned char attr_count; + + if (!fwu) + goto exit; + + sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, + &attrs[attr_count].attr); + } + + kfree(fwu->read_config_buf); + kfree(fwu->image_name); + kfree(fwu->fn_ptr); + kfree(fwu); + fwu = NULL; + +exit: + complete(&fwu_remove_complete); + + return; +} +#if 1 /* delete it by lauson. */ +static ssize_t synaptics_proc_write(struct file *file, const char __user *buff, size_t len, loff_t *lo) +{ + int copy_len = len; + unsigned char temp[20] ; + unsigned int val[4]; + int ret ; + + if (copy_len >= 20 || copy_from_user( temp, buff, copy_len )) { + printk(KERN_INFO "synaptics read proc input error.\n"); + return -EFAULT; + } + temp[copy_len] = 0; + + if (temp[0] == '1') { + fwu->force_update = 1; + ret = synaptics_fw_updater(fwu_rmi4_get_firmware_data()); + printk("[syna]update return value=0x%x\n",ret); + } else if(temp[0] == '2' && temp[1] == '2') { + //add interface for load tp firmware from file + fwu->force_update = 1; + if(!fwu->image_name[0]) { + strcpy(fwu->image_name,"/sdcard"); + queue_delayed_work(fwu->fwu_workqueue, + &fwu->fwu_work, + msecs_to_jiffies(5)); + } + } else if(temp[0]=='3' && temp[1]=='3') { + //test codes + sscanf(temp+3, "%x %x %x", val,val+1,val+2); + temp[0]=val[0];temp[1]=val[1];temp[2]=val[2]; + if(temp[2]<=8) { + ret = fwu->fn_ptr->read(fwu->rmi4_data, + (((unsigned short)temp[0])<<8)|temp[1],temp+3,temp[2]); + printk("[syna]:read[%x]:%x %x %x %x %x %x %x %x\n",ret, + temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10]); + + } + + } else if(temp[0]=='4' && temp[1]=='4') { + //test codes + sscanf(temp+3, "%x %x %x", val,val+1,val+2); + temp[0]=val[0];temp[1]=val[1];temp[2]=val[2]; + if(temp[2]<=3) { + sscanf(temp+12, "%x %x %x", val,val+1,val+2); + temp[3]=val[0];temp[4]=val[1];temp[5]=val[2]; + ret = fwu->fn_ptr->write(fwu->rmi4_data, + (((unsigned short)temp[0])<<8)|temp[1],temp+3,temp[2]); + printk("[syna]:write[%x]\n",ret); + } + + } else { + printk("[syna]I can't get your cmd!!\n"); + } + + return len ; +} +const struct file_operations syna_write= +{ + //.owner = THIS_MODULE, + //.open = seq_open, + //.read = seq_read, + .write = synaptics_proc_write, + //.llseek = seq_lseek, + //.release = single_release, +}; + +static int init_synaptics_proc(void) +{ + int ret=0; + + struct proc_dir_entry *proc_entry; + + proc_entry = proc_create_data("syna_write", 0222, NULL,&syna_write,NULL); + + if (proc_entry == NULL) + { + ret = -ENOMEM; + printk(KERN_INFO"init_synaptics_proc: Couldn't create proc entry\n"); + } + + return ret; +} +#endif + +//init s3508 fw module +int rmi4_fw_module_init(bool insert) { + synaptics_rmi4_new_function(RMI_FW_UPDATER, insert, + synaptics_rmi4_fwu_init, + synaptics_rmi4_fwu_remove, + synaptics_rmi4_fwu_attn); + return 0; +} + +//init s1302 fw module +extern void synaptics_rmi4_new_function_s1302(enum exp_fn fn_type, bool insert, + int (*func_init)(struct synaptics_rmi4_data *rmi4_data), + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask)); +int rmi4_fw_module_init_s1302(bool insert) { + synaptics_rmi4_new_function_s1302(RMI_FW_UPDATER, insert, + synaptics_rmi4_fwu_init, + synaptics_rmi4_fwu_remove, + synaptics_rmi4_fwu_attn); + return 0; +} +static int __init rmi4_fw_update_module_init(void) +{ + /* + synaptics_rmi4_new_function(RMI_FW_UPDATER, true, + synaptics_rmi4_fwu_init, + synaptics_rmi4_fwu_remove, + synaptics_rmi4_fwu_attn); + */ + init_synaptics_proc(); + return 0; +} + +static void __exit rmi4_fw_update_module_exit(void) +{ + synaptics_rmi4_new_function(RMI_FW_UPDATER, false, + synaptics_rmi4_fwu_init, + synaptics_rmi4_fwu_remove, + synaptics_rmi4_fwu_attn); + wait_for_completion(&fwu_remove_complete); + return; +} + +module_init(rmi4_fw_update_module_init); +module_exit(rmi4_fw_update_module_exit); + +MODULE_DESCRIPTION("Synaptics DSX FW Update Module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx_i2c.c new file mode 100755 index 0000000000000..a46cb73eb5921 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx_i2c.c @@ -0,0 +1,5398 @@ +/************************************************************* + ** Copyright (C), 2012-2016, OEM Mobile Comm Corp., Ltd + ** VENDOR_EDIT + ** File : synaptics_dsx_i2c.c + ** Description : + ** Date : 2014-10-27 11:37 + ** Author : BSP.Sensor + ** + ** ------------------ Revision History: --------------------- + ** + *************************************************************/ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include + +#include "synaptics_dsx.h" +#include "synaptics_dsx_i2c.h" + +#include "synaptics_test_rawdata.h" +#include "../../../fs/proc/internal.h" +#ifdef KERNEL_ABOVE_2_6_38 +#include +#endif +#include + +#define DRIVER_NAME "synaptics-rmi-ts" +#define INPUT_PHYS_NAME "synaptics-rmi-ts/input0" + +#ifdef KERNEL_ABOVE_2_6_38 +#define TYPE_B_PROTOCOL +#endif +#define REPORT_2D_Z +#define NO_0D_WHILE_2D + +#define REPORT_2D_W + +//mingqiang.guo add for check wrong TP befor make ,only for test work station +//#define CHECK_WRONG_TP_BEFORCE_MAKE +#define RPT_TYPE (1 << 0) +#define RPT_X_LSB (1 << 1) +#define RPT_X_MSB (1 << 2) +#define RPT_Y_LSB (1 << 3) +#define RPT_Y_MSB (1 << 4) +#define RPT_Z (1 << 5) +#define RPT_WX (1 << 6) +#define RPT_WY (1 << 7) +#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB) + +#define EXP_FN_WORK_DELAY_MS 10 /* ms */ +#define SYN_I2C_RETRY_TIMES 1 +#define MAX_F11_TOUCH_WIDTH 15 + +#define CHECK_STATUS_TIMEOUT_MS 100 + +#define F01_STD_QUERY_LEN 21 +#define F01_BUID_ID_OFFSET 18 +#define F11_STD_QUERY_LEN 9 +#define F11_STD_CTRL_LEN 10 +#define F11_STD_DATA_LEN 12 + +#define STATUS_NO_ERROR 0x00 +#define STATUS_RESET_OCCURRED 0x01 +#define STATUS_INVALID_CONFIG 0x02 +#define STATUS_DEVICE_FAILURE 0x03 +#define STATUS_CONFIG_CRC_FAILURE 0x04 +#define STATUS_FIRMWARE_CRC_FAILURE 0x05 +#define STATUS_CRC_IN_PROGRESS 0x06 + +#define NORMAL_OPERATION (0 << 0) +#define SENSOR_SLEEP (1 << 0) +#define NO_SLEEP_OFF (0 << 2) +#define NO_SLEEP_ON (1 << 2) +#define CONFIGURED (1 << 7) + +#include +static struct wake_lock tp_wake_lock;//有åŒå‡»å”¤é†’中断时,延时2S,放弃suspendæµç¨‹ï¼Œç­‰å¾…resumeæµç¨‹ + +static void speedup_synaptics_resume(struct work_struct *work); //mingqiang.guo add for LCD show later when push power button and two click in gesture +static DEFINE_SEMAPHORE(work_sem); +static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, + unsigned short length); + +static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, + unsigned short length); + +static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data, + unsigned short ctrl28); + +static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data); +static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data); +static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data, unsigned short f01_cmd_base_addr); +static inline void wait_test_cmd_finished(void); + +#ifdef CONFIG_HAS_EARLYSUSPEND +static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static void synaptics_rmi4_early_suspend(struct early_suspend *h); + +static void synaptics_rmi4_late_resume(struct early_suspend *h); +#endif + +static int synaptics_rmi4_suspend(struct device *dev); + +static int synaptics_rmi4_resume(struct device *dev); + +static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t synaptics_rmi4_suspend_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t synaptics_rmi4_open_or_close_holster_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t synaptics_rmi4_open_or_close_holster_mode_show(struct device *dev, + struct device_attribute *attr, char *buf); + +struct synaptics_rmi4_f01_device_status { + union { + struct { + unsigned char status_code:4; + unsigned char reserved:2; + unsigned char flash_prog:1; + unsigned char unconfigured:1; + } __packed; + unsigned char data[1]; + }; +}; + +struct synaptics_rmi4_f12_query_5 { + union { + struct { + unsigned char size_of_query6; + struct { + unsigned char ctrl0_is_present:1; + unsigned char ctrl1_is_present:1; + unsigned char ctrl2_is_present:1; + unsigned char ctrl3_is_present:1; + unsigned char ctrl4_is_present:1; + unsigned char ctrl5_is_present:1; + unsigned char ctrl6_is_present:1; + unsigned char ctrl7_is_present:1; + } __packed; + struct { + unsigned char ctrl8_is_present:1; + unsigned char ctrl9_is_present:1; + unsigned char ctrl10_is_present:1; + unsigned char ctrl11_is_present:1; + unsigned char ctrl12_is_present:1; + unsigned char ctrl13_is_present:1; + unsigned char ctrl14_is_present:1; + unsigned char ctrl15_is_present:1; + } __packed; + struct { + unsigned char ctrl16_is_present:1; + unsigned char ctrl17_is_present:1; + unsigned char ctrl18_is_present:1; + unsigned char ctrl19_is_present:1; + unsigned char ctrl20_is_present:1; + unsigned char ctrl21_is_present:1; + unsigned char ctrl22_is_present:1; + unsigned char ctrl23_is_present:1; + } __packed; + struct { + unsigned char ctrl24_is_present:1; + unsigned char ctrl25_is_present:1; + unsigned char ctrl26_is_present:1; + unsigned char ctrl27_is_present:1; + unsigned char ctrl28_is_present:1; + unsigned char ctrl29_is_present:1; + unsigned char ctrl30_is_present:1; + unsigned char ctrl31_is_present:1; + } __packed; + }; + unsigned char data[5]; + }; +}; + +struct synaptics_rmi4_f12_query_8 { + union { + struct { + unsigned char size_of_query9; + struct { + unsigned char data0_is_present:1; + unsigned char data1_is_present:1; + unsigned char data2_is_present:1; + unsigned char data3_is_present:1; + unsigned char data4_is_present:1; + unsigned char data5_is_present:1; + unsigned char data6_is_present:1; + unsigned char data7_is_present:1; + } __packed; + struct { + unsigned char data8_is_present:1; + unsigned char data9_is_present:1; + unsigned char data10_is_present:1; + unsigned char data11_is_present:1; + unsigned char data12_is_present:1; + unsigned char data13_is_present:1; + unsigned char data14_is_present:1; + unsigned char data15_is_present:1; + } __packed; + }; + unsigned char data[3]; + }; +}; + +struct synaptics_rmi4_f12_ctrl_8 { + union { + struct { + unsigned char max_x_coord_lsb; + unsigned char max_x_coord_msb; + unsigned char max_y_coord_lsb; + unsigned char max_y_coord_msb; + unsigned char rx_pitch_lsb; + unsigned char rx_pitch_msb; + unsigned char tx_pitch_lsb; + unsigned char tx_pitch_msb; + unsigned char low_rx_clip; + unsigned char high_rx_clip; + unsigned char low_tx_clip; + unsigned char high_tx_clip; + unsigned char num_of_rx; + unsigned char num_of_tx; + }; + unsigned char data[14]; + }; +}; + +struct synaptics_rmi4_f12_ctrl_23 { + union { + struct { + unsigned char obj_type_enable; + unsigned char max_reported_objects; + }; + unsigned char data[2]; + }; +}; + +struct synaptics_rmi4_f12_finger_data { + unsigned char object_type_and_status; + unsigned char x_lsb; + unsigned char x_msb; + unsigned char y_lsb; + unsigned char y_msb; +#ifdef REPORT_2D_Z + unsigned char z; +#endif +#ifdef REPORT_2D_W + unsigned char wx; + unsigned char wy; +#endif +}; + +struct synaptics_rmi4_f1a_query { + union { + struct { + unsigned char max_button_count:3; + unsigned char reserved:5; + unsigned char has_general_control:1; + unsigned char has_interrupt_enable:1; + unsigned char has_multibutton_select:1; + unsigned char has_tx_rx_map:1; + unsigned char has_perbutton_threshold:1; + unsigned char has_release_threshold:1; + unsigned char has_strongestbtn_hysteresis:1; + unsigned char has_filter_strength:1; + } __packed; + unsigned char data[2]; + }; +}; + +struct synaptics_rmi4_f1a_control_0 { + union { + struct { + unsigned char multibutton_report:2; + unsigned char filter_mode:2; + unsigned char reserved:4; + } __packed; + unsigned char data[1]; + }; +}; + +struct synaptics_rmi4_f1a_control { + struct synaptics_rmi4_f1a_control_0 general_control; + unsigned char button_int_enable; + unsigned char multi_button; + unsigned char *txrx_map; + unsigned char *button_threshold; + unsigned char button_release_threshold; + unsigned char strongest_button_hysteresis; + unsigned char filter_strength; +}; + +struct synaptics_rmi4_f1a_handle { + int button_bitmask_size; + unsigned char max_count; + unsigned char valid_button_count; + unsigned char *button_data_buffer; + unsigned char *button_map; + struct synaptics_rmi4_f1a_query button_query; + struct synaptics_rmi4_f1a_control button_control; +}; + +struct synaptics_rmi4_exp_fn { + enum exp_fn fn_type; + bool inserted; + int (*func_init)(struct synaptics_rmi4_data *rmi4_data); + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data); + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask); + struct list_head link; +}; + +struct synaptics_rmi4_exp_fn_data { + bool initialized; + bool queue_work; + struct mutex mutex; + struct list_head list; + struct delayed_work work; + struct workqueue_struct *workqueue; + struct synaptics_rmi4_data *rmi4_data; +}; + +static struct synaptics_rmi4_exp_fn_data exp_data; +static void synaptics_set_int_mask(struct synaptics_rmi4_data *ts, int enable); +static ssize_t synaptics_rmi4_gesture_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t synaptics_rmi4_gesture_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_rmi4_delta_data_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_rmi4_baseline_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_rmi4_baseline_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t synaptics_rmi4_read_baseline_data_open_cbc(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_rmi4_read_baseline_data_close_cbc(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_rmi4_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t synaptics_attr_loglevel_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t synaptics_attr_loglevel_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t sense_frequency_selection_reg_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t sense_frequency_selection_reg_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static struct device_attribute attrs[] = { +#ifdef CONFIG_HAS_EARLYSUSPEND + __ATTR(full_pm_cycle, (S_IRUGO | S_IWUSR), + synaptics_rmi4_full_pm_cycle_show, + synaptics_rmi4_full_pm_cycle_store), +#endif + __ATTR(reset, S_IWUSR, + synaptics_rmi4_show_error, + synaptics_rmi4_f01_reset_store), + __ATTR(productinfo, S_IRUGO, + synaptics_rmi4_f01_productinfo_show, + synaptics_rmi4_store_error), + __ATTR(buildid, S_IRUGO, + synaptics_rmi4_f01_buildid_show, + synaptics_rmi4_store_error), + __ATTR(flashprog, S_IRUGO, + synaptics_rmi4_f01_flashprog_show, + synaptics_rmi4_store_error), + __ATTR(0dbutton, (S_IRUGO | S_IWUSR), + synaptics_rmi4_0dbutton_show, + synaptics_rmi4_0dbutton_store), + __ATTR(suspend, S_IWUSR, + synaptics_rmi4_show_error, + synaptics_rmi4_suspend_store), + __ATTR(gesture, (S_IRUGO | S_IWUSR), + synaptics_rmi4_gesture_show, + synaptics_rmi4_gesture_store), + __ATTR(delta_data, S_IRUGO, + synaptics_rmi4_delta_data_show, + synaptics_rmi4_store_error), + __ATTR(baseline_test, (S_IRUGO | S_IWUSR), + synaptics_rmi4_baseline_show, + synaptics_rmi4_baseline_store), + __ATTR(read_baseline_data_open_cbc, S_IRUGO, + synaptics_rmi4_read_baseline_data_open_cbc, + synaptics_rmi4_store_error), + __ATTR(read_baseline_data_close_cbc, S_IRUGO, + synaptics_rmi4_read_baseline_data_close_cbc, + synaptics_rmi4_store_error), + __ATTR(vendor_id, (S_IRUGO), + synaptics_rmi4_vendor_show, + synaptics_rmi4_store_error), + __ATTR(log_level, (S_IRUGO | S_IWUSR), + synaptics_attr_loglevel_show, + synaptics_attr_loglevel_store), + __ATTR(holstere_open_or_close, (S_IRUGO | S_IWUSR), + synaptics_rmi4_open_or_close_holster_mode_show, + synaptics_rmi4_open_or_close_holster_mode_store), + __ATTR(sense_frequency_selection_reg, (S_IRUGO | S_IWUSR), + sense_frequency_selection_reg_show, + sense_frequency_selection_reg_store), +}; + +#ifdef CONFIG_HAS_EARLYSUSPEND +static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + rmi4_data->full_pm_cycle); +} + +static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + rmi4_data->full_pm_cycle = input > 0 ? 1 : 0; + + return count; +} +#endif + +static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int reset; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + if (sscanf(buf, "%u", &reset) != 1) + return -EINVAL; + + if (reset != 1) + return -EINVAL; + + printk(KERN_ERR "[syna]: reset device[%d]\n",rmi4_data->reset_count) ; + rmi4_data->reset_count = 0 ; + retval = synaptics_rmi4_reset_device(rmi4_data, rmi4_data->f01_cmd_base_addr); + if (retval < 0) { + dev_err(dev, "%s: Failed to issue reset command, error = %d\n", __func__, retval); + return retval; + } + + return count; +} + +static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n", + (rmi4_data->rmi4_mod_info.product_info[0]), + (rmi4_data->rmi4_mod_info.product_info[1])); +} + +static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + rmi4_data->firmware_id); +} + +static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int retval; + struct synaptics_rmi4_f01_device_status device_status; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + retval = synaptics_rmi4_i2c_read(rmi4_data, + rmi4_data->f01_data_base_addr, + device_status.data, + sizeof(device_status.data)); + if (retval < 0) { + dev_err(dev, + "%s: Failed to read device status, error = %d\n", + __func__, retval); + return retval; + } + + return snprintf(buf, PAGE_SIZE, "%u\n", + device_status.flash_prog); +} + +static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", + rmi4_data->button_0d_enabled); +} + +static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int retval; + unsigned int input; + unsigned char ii; + unsigned char intr_enable; + struct synaptics_rmi4_fn *fhandler; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + struct synaptics_rmi4_device_info *rmi; + + rmi = &(rmi4_data->rmi4_mod_info); + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + input = input > 0 ? 1 : 0; + + if (rmi4_data->button_0d_enabled == input) + return count; + + if (list_empty(&rmi->support_fn_list)) + return -ENODEV; + + list_for_each_entry(fhandler, &rmi->support_fn_list, link) { + if(fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) { + ii = fhandler->intr_reg_num; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + rmi4_data->f01_ctrl_base_addr + 1 + ii, + &intr_enable, + sizeof(intr_enable)); + if (retval < 0) + return retval; + + if (input == 1) + intr_enable |= fhandler->intr_mask; + else + intr_enable &= ~fhandler->intr_mask; + + retval = synaptics_rmi4_i2c_write(rmi4_data, + rmi4_data->f01_ctrl_base_addr + 1 + ii, + &intr_enable, + sizeof(intr_enable)); + if (retval < 0) + return retval; + } + } + + rmi4_data->button_0d_enabled = input; + + return count; +} + +static ssize_t synaptics_rmi4_suspend_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input == 1) + synaptics_rmi4_suspend(dev); + else if (input == 0) + synaptics_rmi4_resume(dev); + else + return -EINVAL; + + return count; +} + +static ssize_t synaptics_rmi4_open_or_close_holster_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + uint8_t databuf; + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input == 1) + { + rmi4_data->holstere_mode_open_or_close= 1;//open holstere mode + synaptics_rmi4_i2c_write(rmi4_data,rmi4_data->holstere_mode_control_addr,(unsigned char*)&(rmi4_data->holstere_mode_open_or_close),1); + } + else if (input == 0) + { + rmi4_data->holstere_mode_open_or_close = 0;//close holstere mode + synaptics_rmi4_i2c_write(rmi4_data,rmi4_data->holstere_mode_control_addr,(unsigned char*)&(rmi4_data->holstere_mode_open_or_close),1); + } + else + return -EINVAL; + + synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->holstere_mode_control_addr, &databuf,1) ; + printk("%s holstere mode %s\n",input ? "open" : "close", + (databuf == (rmi4_data->holstere_mode_open_or_close) ) ? "success" : "fail"); + + return count; +} + +static ssize_t synaptics_rmi4_open_or_close_holster_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + uint8_t databuf; + + synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->holstere_mode_control_addr, &databuf,1) ; + return sprintf(buf, " holstere mode is %s \n",databuf ? "open" : "close" ); +} +/** + * synaptics_rmi4_set_page() + * + * Called by synaptics_rmi4_i2c_read() and synaptics_rmi4_i2c_write(). + * + * This function writes to the page select register to switch to the + * assigned page. + */ +static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data, + unsigned int address) +{ + int retval = 0; + unsigned char retry; + unsigned char buf[PAGE_SELECT_LEN]; + unsigned char page; + struct i2c_client *i2c = rmi4_data->i2c_client; + + page = ((address >> 8) & MASK_8BIT); + if (page != rmi4_data->current_page) { + buf[0] = MASK_8BIT; + buf[1] = page; + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN); + if (retval != PAGE_SELECT_LEN) { + msleep(20); + } else { + rmi4_data->current_page = page; + break; + } + } + if (retry == SYN_I2C_RETRY_TIMES) { + //dump_stack(); + dev_err(&rmi4_data->i2c_client->dev, "%s: I2C read over retry limit\n", __func__); + synaptics_rmi4_reset_device(rmi4_data, rmi4_data->f01_cmd_base_addr) ; + retval = -EIO; + } else { + rmi4_data->reset_count = 0 ; + } + + } else { + retval = PAGE_SELECT_LEN; + } + + return retval; +} + +/** + * synaptics_rmi4_i2c_read() + * + * Called by various functions in this driver, and also exported to + * other expansion Function modules such as rmi_dev. + * + * This function reads data of an arbitrary length from the sensor, + * starting from an assigned register address of the sensor, via I2C + * with a retry mechanism. + */ +static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_msg msg[] = { + { + .addr = rmi4_data->i2c_client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = rmi4_data->i2c_client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + + buf = addr & MASK_8BIT; + + mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + retval = synaptics_rmi4_set_page(rmi4_data, addr); + if (retval != PAGE_SELECT_LEN) + goto exit; + + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) { + retval = length; + break; + } + + msleep(20); + } + + if (retry == SYN_I2C_RETRY_TIMES) { + //dump_stack(); + dev_err(&rmi4_data->i2c_client->dev, "%s: I2C read over retry limit\n", __func__); + rmi4_data->current_page = MASK_8BIT; + retval = -EIO; + } + +exit: + mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + return retval; +} + +/** + * synaptics_rmi4_i2c_write() + * + * Called by various functions in this driver, and also exported to + * other expansion Function modules such as rmi_dev. + * + * This function writes data of an arbitrary length to the sensor, + * starting from an assigned register address of the sensor, via I2C with + * a retry mechanism. + */ +static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_msg msg[] = { + { + .addr = rmi4_data->i2c_client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + retval = synaptics_rmi4_set_page(rmi4_data, addr); + if (retval != PAGE_SELECT_LEN) + goto exit; + + buf[0] = addr & MASK_8BIT; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) { + retval = length; + break; + } + + msleep(20); + } + + if (retry == SYN_I2C_RETRY_TIMES) { + //dump_stack(); + dev_err(&rmi4_data->i2c_client->dev, + "%s: I2C write over retry limit\n", + __func__); + rmi4_data->current_page = MASK_8BIT; + retval = -EIO; + } + +exit: + mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + return retval; +} + +/** + * synaptics_rmi4_f11_abs_report() + * + * Called by synaptics_rmi4_report_touch() when valid Function $11 + * finger data has been detected. + * + * This function reads the Function $11 data registers, determines the + * status of each finger supported by the Function, processes any + * necessary coordinate manipulation, reports the finger data to + * the input subsystem, and returns the number of fingers detected. + */ +static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + int retval; + unsigned char touch_count = 0; /* number of touch points */ + unsigned char reg_index; + unsigned char finger; + unsigned char fingers_supported; + unsigned char num_of_finger_status_regs; + unsigned char finger_shift; + unsigned char finger_status; + unsigned char data_reg_blk_size; + unsigned char finger_status_reg[3]; + unsigned char data[F11_STD_DATA_LEN]; + unsigned short data_addr; + unsigned short data_offset; + int x; + int y; + int wx; + int wy; + int temp; + + /* + * The number of finger status registers is determined by the + * maximum number of fingers supported - 2 bits per finger. So + * the number of finger status registers to read is: + * register_count = ceil(max_num_of_fingers / 4) + */ + fingers_supported = fhandler->num_of_data_points; + num_of_finger_status_regs = (fingers_supported + 3) / 4; + data_addr = fhandler->full_addr.data_base; + data_reg_blk_size = fhandler->size_of_data_register_block; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + data_addr, + finger_status_reg, + num_of_finger_status_regs); + if (retval < 0) + return 0; + + for (finger = 0; finger < fingers_supported; finger++) { + reg_index = finger / 4; + finger_shift = (finger % 4) * 2; + finger_status = (finger_status_reg[reg_index] >> finger_shift) + & MASK_2BIT; + + /* + * Each 2-bit finger status field represents the following: + * 00 = finger not present + * 01 = finger present and data accurate + * 10 = finger present but data may be inaccurate + * 11 = reserved + */ +#ifdef TYPE_B_PROTOCOL + input_mt_slot(rmi4_data->input_dev, finger); + input_mt_report_slot_state(rmi4_data->input_dev, + MT_TOOL_FINGER, finger_status); +#endif + + if (finger_status) { + data_offset = data_addr + + num_of_finger_status_regs + + (finger * data_reg_blk_size); + retval = synaptics_rmi4_i2c_read(rmi4_data, + data_offset, + data, + data_reg_blk_size); + if (retval < 0) + return 0; + + x = (data[0] << 4) | (data[2] & MASK_4BIT); + y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT); + wx = (data[3] & MASK_4BIT); + wy = (data[3] >> 4) & MASK_4BIT; + + if (rmi4_data->board->swap_axes) { + temp = x; + x = y; + y = temp; + temp = wx; + wx = wy; + wy = temp; + } + + if (rmi4_data->board->x_flip) + x = rmi4_data->sensor_max_x - x; + if (rmi4_data->board->y_flip) + y = rmi4_data->sensor_max_y - y; + + input_report_key(rmi4_data->input_dev, + BTN_TOUCH, 1); + input_report_key(rmi4_data->input_dev, + BTN_TOOL_FINGER, 1); + input_report_abs(rmi4_data->input_dev, + ABS_MT_POSITION_X, x); + input_report_abs(rmi4_data->input_dev, + ABS_MT_POSITION_Y, y); +#ifdef REPORT_2D_W + input_report_abs(rmi4_data->input_dev, + ABS_MT_TOUCH_MAJOR, max(wx, wy)); + input_report_abs(rmi4_data->input_dev, + ABS_MT_TOUCH_MINOR, min(wx, wy)); +#endif +#ifndef TYPE_B_PROTOCOL + input_mt_sync(rmi4_data->input_dev); +#endif + + dev_dbg(&rmi4_data->i2c_client->dev, + "%s: Finger %d:\n" + "status = 0x%02x\n" + "x = %d\n" + "y = %d\n" + "wx = %d\n" + "wy = %d\n", + __func__, finger, + finger_status, + x, y, wx, wy); + + touch_count++; + } + } + + if (touch_count == 0) { + input_report_key(rmi4_data->input_dev, + BTN_TOUCH, 0); + input_report_key(rmi4_data->input_dev, + BTN_TOOL_FINGER, 0); +#ifndef TYPE_B_PROTOCOL + input_mt_sync(rmi4_data->input_dev); +#endif + } + + input_sync(rmi4_data->input_dev); + + return touch_count; +} + + +/* Analog voltage @3.0 V */ +#define SYNA_VTG_MIN_UV 3000000 +#define SYNA_VTG_MAX_UV 3000000 +#define SYNA_ACTIVE_LOAD_UA 15000 +#define SYNA_LPM_LOAD_UA 10 +/* i2c voltage @1.8 V */ +#define SYNA_I2C_VTG_MIN_UV 1800000 +#define SYNA_I2C_VTG_MAX_UV 1800000 +#define SYNA_I2C_LOAD_UA 10000 +#define SYNA_I2C_LPM_LOAD_UA 10 + + +#define SYNA_NO_GESTURE 0x00 +#define SYNA_ONE_FINGER_DOUBLE_TAP 0x03 +#define SYNA_TWO_FINGER_SWIPE 0x07 +#define SYNA_ONE_FINGER_CIRCLE 0x08 +#define SYNA_ONE_FINGER_DIRECTION 0x0a +#define SYNA_ONE_FINGER_W_OR_M 0x0b + + +#define KEY_F3 61 // Double click, light the screen +#define KEY_F4 62 // cycle , open the carmer +#define KEY_F5 63 // v, open the flashlight +#define KEY_F6 64 // ||, stop the music +#define KEY_F7 65 // <, last music +#define KEY_F8 66 // >, next music +#define KEY_F9 67 // M or W + +#define UnkownGestrue 0 +#define DouTap 1 // double tap +#define UpVee 2 // V +#define DownVee 3 // ^ +#define LeftVee 4 // > +#define RightVee 5 // < +#define Circle 6 // O +#define DouSwip 7 // || +#define Left2RightSwip 8 // --> +#define Right2LeftSwip 9 // <-- +#define Up2DownSwip 10 // |v +#define Down2UpSwip 11 // |^ +#define Mgestrue 12 // M +#define Wgestrue 13 // W + +#define BLANK 1 +#define UNBLANK 0 + +#define SYNA_SMARTCOVER_MIN 0 +#define SYNA_SMARTCOVER_MAN 750 + + +#define SYNA_ADDR_REPORT_FLAG 0x19 //report mode register +#define SYNA_ADDR_GESTURE_FLAG 0x1e //gesture enable register +#define SYNA_ADDR_GLOVE_FLAG 0x1f //glove enable register +#define SYNA_ADDR_GESTURE_OFFSET_s3320 0x07 //gesture register addr=0x08 +#define SYNA_ADDR_GESTURE_OFFSET_s3508 0x07 //gesture register addr=0x07 +#define SYNA_ADDR_GESTURE_EXT_S3508 0x402 //gesture ext data, for 13077 and 14001 +#define SYNA_ADDR_GESTURE_EXT_S3528 0x400 //gesture ext data, for 14021 +#define SYNA_ADDR_SMARTCOVER_EXT 0x41f //smartcover mode +#define SYNA_ADDR_PDOZE_FLAG 0x07 //pdoze status register +#define SYNA_ADDR_TOUCH_FEATURE 0x1E //ThreeD Touch Features +#define SYNA_ADDR_F12_2D_CTRL23 0x1D +#define SYNA_ADDR_F12_2D_CTRL10 0x16 + +#define SYNA_ADDR_F54_ANALOG_CTRL113 0x136 + +extern int rmi4_fw_module_init(bool insert); + +#define F54_CTRL_BASE_ADDR (syna_rmi4_data->f54_ctrl_base_addr) +#define F54_CMD_BASE_ADDR (syna_rmi4_data->f54_cmd_base_addr) +#define F54_DATA_BASE_ADDR (syna_rmi4_data->f54_data_base_addr) + +/*************** log definition **********************************/ +#define TS_ERROR 1 +#define TS_WARNING 2 +#define TS_INFO 3 +#define TS_DEBUG 4 +#define TS_TRACE 5 +static int syna_log_level = TS_INFO; +#define print_ts(level, ...) \ + do { \ + if (syna_log_level >= (level)) \ + printk(__VA_ARGS__); \ + } while (0) +/*****************************************************************/ + +struct synaptics_rmi4_data *syna_rmi4_data=0; +EXPORT_SYMBOL(syna_rmi4_data); +static struct regulator *vdd_regulator=0; +static struct regulator *vdd_regulator_i2c=0; +int syna_use_gesture = 0 ; +static uint8_t int_mask = 0; +static int syna_test_max_err_count = 10; +static char synaptics_vendor_str[32]; //vendor string +static char *synaptics_id_str; +static unsigned int syna_lcd_ratio1 ; +static unsigned int syna_lcd_ratio2 ; +EXPORT_SYMBOL(syna_use_gesture); + +/***** For virtual key definition begin *******************/ +enum tp_vkey_enum +{ + TP_VKEY_MENU, + TP_VKEY_HOME, + TP_VKEY_BACK, + + TP_VKEY_NONE, + TP_VKEY_COUNT = TP_VKEY_NONE, +}; +static struct tp_vkey_button +{ + int x; + int y; + int width; + int height; +}vkey_buttons[TP_VKEY_COUNT]; + +#define LCD_SENSOR_X (1080) +#define LCD_SENSOR_Y (2040) +#define LCD_MAX_X (1080) +#define LCD_MAX_Y (1920) +#define LCD_MAX_X_FIND7S (1440) +#define LCD_MAX_Y_FIND7S (2560) +#define LCD_MULTI_RATIO(m) (((syna_lcd_ratio1)*(m))/(syna_lcd_ratio2)) +#define VK_LCD_WIDTH LCD_MULTI_RATIO(LCD_MAX_X/TP_VKEY_COUNT) // 3 keys + +#define VK_VENTE_Y 1974 + +static void vk_calculate_area(void) //added by liujun +{ + int i; + struct synaptics_rmi4_data *syna_ts_data = syna_rmi4_data ; + int tp_max_x = syna_ts_data->sensor_max_x; + int tp_max_y = syna_ts_data->sensor_max_y; + int vk_height = syna_ts_data->virtual_key_height; + int vk_width = tp_max_x/TP_VKEY_COUNT; + int margin_x = 85; + + + syna_ts_data->vk_prop_center_y = 2626; + syna_ts_data->vk_prop_height = 152; + syna_ts_data->vk_prop_width = 200; + + + print_ts(TS_INFO, "%s, max_x = %d,max_y = %d,virtual_kye_height = %d\n", __func__, tp_max_x, tp_max_y, vk_height); + + for (i = 0; i < TP_VKEY_COUNT; ++i) + { + vkey_buttons[i].width = vk_width - margin_x*2; + vkey_buttons[i].height = vk_height - 10; + vkey_buttons[i].x = vk_width*i + margin_x; + vkey_buttons[i].y = tp_max_y - vkey_buttons[i].height; + + printk("[syna][%d]w = %d,h = %d,x = %d,y = %d\n",i,vkey_buttons[i].width,vkey_buttons[i].height,vkey_buttons[i].x,vkey_buttons[i].y); + } + //vkey_buttons[TP_VKEY_MENU].x -= 20; + vkey_buttons[TP_VKEY_BACK].x += 20; +} + +static ssize_t vk_syna_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct synaptics_rmi4_data *ts = syna_rmi4_data; + int len ; + + print_ts(TS_INFO, "%s\n", __func__); + + len = sprintf(buf, + __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":%d:%d:%d:%d" + ":" __stringify(EV_KEY) ":" __stringify(KEY_HOMEPAGE) ":%d:%d:%d:%d" + ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":%d:%d:%d:%d" "\n", + VK_LCD_WIDTH/2 + 0, ts->vk_prop_center_y, ts->vk_prop_width, ts->vk_prop_height, + VK_LCD_WIDTH*3/2, ts->vk_prop_center_y, ts->vk_prop_width, ts->vk_prop_height, + VK_LCD_WIDTH*5/2+20 , ts->vk_prop_center_y, ts->vk_prop_width, ts->vk_prop_height); + + return len ; +} + +static struct kobj_attribute vk_syna_attr = { + .attr = { + .name = "virtualkeys."DRIVER_NAME, + .mode = S_IRUGO, + }, + .show = &vk_syna_show, +}; + +static struct attribute *syna_properties_attrs[] = { + &vk_syna_attr.attr, + NULL +}; + +static struct attribute_group syna_properties_attr_group = { + .attrs = syna_properties_attrs, +}; + +static void synaptics_ts_init_area(struct synaptics_rmi4_data *ts){ + ts->snap_top = 0; + ts->snap_left = 0; + ts->snap_right = 0; + ts->snap_bottom = 0 ; +} + +static int synaptics_ts_init_virtual_key(struct synaptics_rmi4_data *ts ) +{ + int ret = 0; + + vk_calculate_area(); + /* virtual keys */ + if(ts->properties_kobj || ts->sensor_max_x<=0 || ts->sensor_max_y<=0) + return 0 ; + if (1) /* delete it by lauson. */ + { + ts->properties_kobj = kobject_create_and_add("board_properties", NULL); + if (ts->properties_kobj) + ret = sysfs_create_group(ts->properties_kobj, &syna_properties_attr_group); + } + + if (!ts->properties_kobj || ret) + printk("%s: failed to create board_properties\n", __func__); + /* virtual keys */ + return ret; +} + +static int get_virtual_key_button(int x, int y) +{ + int i; + int lcdheight = LCD_MAX_Y_FIND7S ; + + if(y <= lcdheight) + return 0 ; + + for (i = 0; i < TP_VKEY_NONE; ++i) + { + struct tp_vkey_button* button = &vkey_buttons[i]; + if ((x >= button->x) && (x <= button->x + button->width)) + { + // In this button area. + break; + } + } + return i; +} +/***** For virtual key definition end *********************/ + +static int synaptics_set_f12ctrl_data(struct synaptics_rmi4_data *rmi4_data, bool enable, unsigned char suppression) +{ + int retval; + unsigned char val[4]; + unsigned char reportbuf[3]; + unsigned short reportaddr = SYNA_ADDR_REPORT_FLAG; //F12_2D_CTRL register changed in new firmware + + retval = synaptics_rmi4_i2c_read(rmi4_data, reportaddr, reportbuf, sizeof(reportbuf)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to get report buffer\n", __func__); + return -1 ; + } + + if(suppression) { + if(suppression >= 200) + suppression = 0 ; + reportbuf[0] = suppression ; + reportbuf[1] = suppression ; + + } else { + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_GESTURE_FLAG,val,sizeof(val)); + val[0] = syna_rmi4_data->gesture_enable & 0xff ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GESTURE_FLAG,val,sizeof(val)); + + if(enable) + reportbuf[2] |= 0x02 ; + else { + reportbuf[2] &= 0xfd ; + syna_use_gesture = (rmi4_data->gesture_enable&0xff)?1:0 ; + } + } + + retval = synaptics_rmi4_i2c_write(rmi4_data, reportaddr, reportbuf, sizeof(reportbuf)); + if (retval < 0) { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to write report buffer\n", __func__); + return -1 ; + } + + return 0 ; + +} + +static int synaptics_enable_gesture(struct synaptics_rmi4_data *rmi4_data, bool enable) +{ + if(!syna_use_gesture) + return 0 ; + + if(rmi4_data->gesture == enable) + return 0 ; + + if(synaptics_set_f12ctrl_data(rmi4_data,enable,0) < 0) + return -1 ; + + rmi4_data->gesture = enable ; + print_ts(TS_DEBUG, KERN_ERR "[syna]:gesture source = 0x%x\n", rmi4_data->gesture_enable); + + return 0 ; + +} + +//enable pdoze function +static int synaptics_enable_pdoze(struct synaptics_rmi4_data *rmi4_data, bool enable) { + unsigned char val[3] ; + int retval ; + + if(!syna_rmi4_data->pdoze_enable) + return 0 ; + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_REPORT_FLAG,val,sizeof(val)); + + val[2] &= 0x7f ; + if(enable) + val[2] |= 0x80 ; + + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_REPORT_FLAG,val,sizeof(val)); + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_TOUCH_FEATURE,val,1); + + val[0] |= 0x10 ; + if(enable) + val[0] &= 0xEF ; + + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_TOUCH_FEATURE,val,1); + + return 0; +} + +//enable irq wakeup +static int synaptics_enable_irqwake(struct synaptics_rmi4_data *rmi4_data, bool enable) { + if(enable) { + enable_irq_wake(rmi4_data->i2c_client->irq); + } + else { + disable_irq_wake(rmi4_data->i2c_client->irq); + } + + return 0 ; +} + +static ssize_t synaptics_rmi4_gesture_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n",syna_use_gesture); +} + +static ssize_t synaptics_rmi4_gesture_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + printk("synap input:%d\n",input); + if(input == 1) { + synaptics_enable_gesture(syna_rmi4_data,true); + syna_use_gesture = 1 ; + } else if(input == 0) { + synaptics_enable_gesture(syna_rmi4_data,false); + syna_use_gesture = 0 ; + } + else + return -EINVAL; + + return count; +} + +//support tp2.0 interface, app read it to get points + +static int synaptics_rmi4_coordinate_show(struct seq_file *seq, void *offset) +{ + int len; + + print_ts(TS_ERROR, "%s, gesturemode = %d! (%d:%d),(%d:%d),(%d:%d),(%d:%d),(%d:%d),(%d:%d),%d\n", + __func__, syna_rmi4_data->gesturemode, + syna_rmi4_data->points[0], syna_rmi4_data->points[1], syna_rmi4_data->points[2], syna_rmi4_data->points[3], + syna_rmi4_data->points[4], syna_rmi4_data->points[5], syna_rmi4_data->points[6], syna_rmi4_data->points[7], + syna_rmi4_data->points[8], syna_rmi4_data->points[9], syna_rmi4_data->points[10], syna_rmi4_data->points[11], + syna_rmi4_data->points[12]); + + len = seq_printf(seq, "%d,%d:%d,%d:%d,%d:%d,%d:%d,%d:%d,%d:%d,%d\n", syna_rmi4_data->gesturemode, + syna_rmi4_data->points[0], syna_rmi4_data->points[1], syna_rmi4_data->points[2], syna_rmi4_data->points[3], + syna_rmi4_data->points[4], syna_rmi4_data->points[5], syna_rmi4_data->points[6], syna_rmi4_data->points[7], + syna_rmi4_data->points[8], syna_rmi4_data->points[9], syna_rmi4_data->points[10], syna_rmi4_data->points[11], + syna_rmi4_data->points[12]); + + return 0 ; +} +static int synaptics_coordinate_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_coordinate_show, inode->i_private); +} + +//support pdoze status +static int synaptics_rmi4_pdoze_show(struct seq_file *seq, void *offset) +{ + int len = 0 ; + + len = seq_printf(seq, "%d\n", syna_rmi4_data->pdoze_status); + + return 0 ; +} +static int synaptics_pdoze_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_pdoze_show, inode->i_private); +} + +static int synaptics_rmi4_gesture_proc_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", ((syna_rmi4_data->gesture_enable)?1:0)); + return 0 ; +} + +static int synaptics_gesture_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_gesture_proc_show, inode->i_private); +} + +static ssize_t synaptics_rmi4_gesture_proc_write(struct file *filp, const char __user *buff, size_t len, loff_t *lo) +{ + unsigned char bak; + unsigned int enable ; + if(len > 2) + return 0 ; + + enable = (buff[0]=='0')?0:1 ; + bak = syna_rmi4_data->gesture_enable ; + syna_rmi4_data->gesture_enable &= 0x00 ; + if(enable) + syna_rmi4_data->gesture_enable |= 0x7b ; + if(bak == syna_rmi4_data->gesture_enable) + return len ; + + if(!(syna_use_gesture && syna_rmi4_data->gesture)) + syna_use_gesture = (syna_rmi4_data->gesture_enable&0xff)?1:0 ; + + print_ts(TS_DEBUG, KERN_ERR "%s, gesture_enable = 0x%x\n", __func__, syna_rmi4_data->gesture_enable); + + return len; +} + +#ifdef VENDOR_EDIT +//zhanhua.li@BSP.TP,2014/05/07,add smartcover function +//smartcover proc write function +static int synaptics_rmi4_open_smartcover( void ) +{ + int retval; + unsigned char val[10]; + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,val,1); + val[0] = 1;//syna_rmi4_data->smartcover_enable & 0xff ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,val,1); + + //set + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,1); + val[0] |= 0x01; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,1); + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_F12_2D_CTRL10,val,7); + val[6] &= ~(0x01) ;//0b1111 1110 + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_F12_2D_CTRL10,val,7); + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_F54_ANALOG_CTRL113,val,1); + val[0] &= ~(0x01<< 1) ; //0b1111 1101 + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_F54_ANALOG_CTRL113,val,1); + + val[0] = 0x04 ; + synaptics_rmi4_i2c_write(syna_rmi4_data, F54_CMD_BASE_ADDR, val,1); // force update + wait_test_cmd_finished(); + printk(KERN_ERR " open smartcover\n"); + return retval ; +} + +static int synaptics_rmi4_close_smartcover( void ) +{ + int retval; + unsigned char val[10]; + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,val,1); + val[0] = 0;//syna_rmi4_data->smartcover_enable & 0xff ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,val,1); + + //set 0x001D bit5 + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,1); + val[0] &= ~(0x01); + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,1); + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_F12_2D_CTRL10,val,7); + val[6] |= 0x01 ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_F12_2D_CTRL10,val,7); + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_F54_ANALOG_CTRL113,val,1); + val[0] |= 0x01<< 1 ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_F54_ANALOG_CTRL113,val,1); + + val[0] = 0x04 ; + synaptics_rmi4_i2c_write(syna_rmi4_data, F54_CMD_BASE_ADDR, val,1); // force update + wait_test_cmd_finished(); + printk(KERN_ERR "close smartcover\n"); + return retval; +} +#endif/*VENDOR_EDIT*/ + +//smartcover proc read function +static int synaptics_rmi4_proc_smartcover_show(struct seq_file *seq, void *offset) { + seq_printf(seq, "%d\n", ((syna_rmi4_data->smartcover_enable)?1:0)); + return 0 ; +} + +static int synaptics_smartcover_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_proc_smartcover_show, inode->i_private); +} + +static ssize_t synaptics_rmi4_proc_smartcover_write(struct file *file, const char __user *page, size_t t, loff_t *lo) { + int retval; + // unsigned char val[10]; + unsigned char bak; + unsigned int enable ; + //user space interface,zhanhua.li@BSP.TP modify + if(t > 2) + return 0 ; + printk(KERN_ERR "buff[0]=%x len=%ld\n",page[0],t); + if( !(page[0] == 0x31 || page[0] == 0x30) ) + return t; + + printk(KERN_ERR "smartcover setting=%x \n",page[0]); + enable =(page[0]=='0')?0:1 ; + bak = syna_rmi4_data->smartcover_enable ; + syna_rmi4_data->smartcover_enable &= 0x00 ; + if(enable) + syna_rmi4_data->smartcover_enable |= 0x01 ; + if(bak == syna_rmi4_data->smartcover_enable) + return t ; + + print_ts(TS_DEBUG, KERN_ERR "smartcover enable=0x%x\n", syna_rmi4_data->smartcover_enable); + + if ( enable) { + retval = synaptics_rmi4_open_smartcover(); + } else { + retval = synaptics_rmi4_close_smartcover(); + } + + return t; +} + +//glove proc read function +static int synaptics_rmi4_proc_glove_show(struct seq_file *seq, void *offset) { + seq_printf(seq, "%d\n", ((syna_rmi4_data->glove_enable)?1:0)); + return 0 ; +} +static int synaptics_glove_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_proc_glove_show, inode->i_private); +} +//glove proc write function +static ssize_t synaptics_rmi4_proc_glove_write(struct file *file, const char __user *page, size_t t, loff_t *lo) { + int retval; + unsigned char val[1]; + unsigned char bak; + unsigned int enable ; + if(t > 2) + return 0 ; + + enable =(page[0]==0x30)?0:1 ; + bak = syna_rmi4_data->glove_enable ; + syna_rmi4_data->glove_enable &= 0x00 ; + if(enable) + syna_rmi4_data->glove_enable |= 0x01 ; + if(bak == syna_rmi4_data->glove_enable) + return t ; + + print_ts(TS_DEBUG, KERN_ERR "glove enable=0x%x\n", syna_rmi4_data->glove_enable); + + + retval = synaptics_rmi4_i2c_read(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,sizeof(val)); + + + val[0] = syna_rmi4_data->glove_enable & 0xff ; + retval = synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,val,sizeof(val)); + + return (retval==sizeof(val))?t:0; +} + +//pdoze proc read function +static int synaptics_rmi4_proc_pdoze_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", ((syna_rmi4_data->pdoze_enable)?1:0)); + return 0 ; +} +static int synaptics_pdoze_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_proc_pdoze_show, inode->i_private); +} + +//pdoze proc write function +static ssize_t synaptics_rmi4_proc_pdoze_write(struct file *file, const char __user *page, size_t t, loff_t *lo) { + unsigned int enable ; + + if(t > 2) + return 0 ; + + enable =(page[0]==0x30)?0:1 ; + + syna_rmi4_data->pdoze_enable = enable ; + + print_ts(TS_DEBUG, KERN_ERR "[syna]:pdoze enable=0x%x\n", syna_rmi4_data->pdoze_enable); + + return t ; +} +static ssize_t synaptics_rmi4_baseline_data(char *buf, bool savefile); +static int synaptics_rmi4_proc_baseline_show(struct seq_file *seq, void *offset) +{ + unsigned char *buffer = 0 ; + int rev = 0; + + buffer = kzalloc(1024, GFP_KERNEL); + if(buffer) { + synaptics_rmi4_baseline_data(buffer,0); + rev = seq_printf(seq, buffer); + kfree(buffer); + } + return rev ; +} +static int synaptics_rmi4_baseline_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_proc_baseline_show, inode->i_private); +} +static int synaptics_rmi4_proc_vendor_id_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", syna_rmi4_data->vendor_id); + return 0 ; +} +static int synaptics_rmi4_vendor_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rmi4_proc_vendor_id_show, inode->i_private); +} + +const struct file_operations synap[] = +{ + { + .owner = THIS_MODULE, + .open = synaptics_glove_open, + .read = seq_read, + .write = synaptics_rmi4_proc_glove_write, + .llseek = seq_lseek, + .release = single_release, + }, + + { + .owner = THIS_MODULE, + .open = synaptics_gesture_open, + .read = seq_read, + .write = synaptics_rmi4_gesture_proc_write, + .llseek = seq_lseek, + .release = single_release, + }, + + + { + .owner = THIS_MODULE, + .open = synaptics_pdoze_open, + .read = seq_read, + .write = synaptics_rmi4_proc_pdoze_write, + .llseek = seq_lseek, + .release = single_release, + + }, + + { + .owner = THIS_MODULE, + .open = synaptics_smartcover_open, + .read = seq_read, + .write = synaptics_rmi4_proc_smartcover_write, + .llseek = seq_lseek, + .release = single_release, + }, + + { + .owner = THIS_MODULE, + .open = synaptics_pdoze_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }, + + { + .owner = THIS_MODULE, + .open = synaptics_coordinate_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }, + + { + .owner = THIS_MODULE, + .open = synaptics_rmi4_baseline_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }, + + { + .owner = THIS_MODULE, + .open = synaptics_rmi4_vendor_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + } +}; + +static int synaptics_rmi4_init_touchpanel_proc(void) +{ + struct proc_dir_entry *proc_entry=0; + + struct proc_dir_entry *procdir = proc_mkdir( "touchpanel", NULL ); + + //glove mode inteface + proc_entry = proc_create_data("glove_mode_enable", 0666, procdir,&synap[0],NULL); + + proc_entry = proc_create_data("double_tap_enable", 0666, procdir,&synap[1],NULL); + + //for pdoze enable/disable interface + proc_entry = proc_create_data("pdoze_mode_enable", 0666, procdir,&synap[2],NULL); + + //for smartcover + proc_entry = proc_create_data("smartcover_mode_enable", 0666, procdir,&synap[3],NULL); + + //for pdoze status + proc_entry = proc_create_data("pdozedetect", 0444, procdir,&synap[4],NULL); + + //for support tp2.0 coordirate + proc_entry = proc_create_data("coordinate", 0444, procdir,&synap[5],NULL); + + //for baseline test + proc_entry = proc_create_data("baseline_test", 0666, procdir,&synap[6],NULL); + + //for vendor id + proc_entry = proc_create_data("vendor_id", 0444, procdir,&synap[7],NULL); + + printk("%s over.\n", __func__); + + return 0; +} + +static inline void wait_test_cmd_finished(void) +{ + uint8_t data = 0; + int i = 0 ; + do { + + synaptics_rmi4_i2c_read(syna_rmi4_data, syna_rmi4_data->f54_cmd_base_addr, &data,1); + mdelay(1); //wait 1ms + if(i <= 80) { + i ++; + } else { + print_ts(TS_WARNING,"synap %s time out!",__func__); + break ; + } + } while (data != 0x00); +} + +static void synaptics_set_int_mask(struct synaptics_rmi4_data *ts, int enable) +{ + uint8_t buf = 0; + synaptics_rmi4_i2c_read(ts, ts->f01_data_base_addr+1, &buf,1); //clear the interrupt + + if(enable) + buf= int_mask; + else + buf = 0x00; + + synaptics_rmi4_i2c_write(ts, ts->f01_ctrl_base_addr+1, &buf,1); +} + +static ssize_t synaptics_rmi4_read_delta_data(char *buf) +{ + uint8_t tmp_new = 0; + uint tx_num = 0; + uint rx_num = 0; + int16_t read_data; + uint16_t word_value; + int x,y; + ssize_t num_read_chars = 0; + int ret = 0; + + struct synaptics_rmi4_data *syna_ts_data = syna_rmi4_data ; + struct i2c_client* client = syna_ts_data->i2c_client; + + syna_rmi4_data->touch_stopped = true; + + disable_irq_nosync(client->irq); + + if (syna_ts_data->vendor_id == TP_VENDOR_WINTEK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TRULY) + { + tx_num = TX_NUM_TRULY_N3; + rx_num = RX_NUM_TRULY_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK_GFF) + { + tx_num = TX_NUM_TPK_GFF_N3; + rx_num = RX_NUM_TPK_GFF_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_JDI) + { + tx_num = TX_NUM_JDI; + rx_num = RX_NUM_JDI; + } + + //set report type + tmp_new = 0x02 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + word_value = 0 ;//set fifo 00 , first address + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + + tmp_new = 0x01 ;//send get report command + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + + wait_test_cmd_finished(); + + for(x = 0;x < tx_num; x++) + { + print_ts(TS_INFO,"\n[%d]",x); + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]",x); + for(y = 0; y < rx_num; y++) + { + ret = i2c_smbus_read_word_data(client,F54_DATA_BASE_ADDR+3); + read_data = ret & 0xffff; + + print_ts(TS_INFO,"%3d,",read_data); + + num_read_chars += sprintf(&(buf[num_read_chars]), "%d ",read_data); + } + } + + synaptics_rmi4_reset_device(syna_ts_data, syna_ts_data->f01_cmd_base_addr); + synaptics_rmi4_reinit_device(syna_rmi4_data); + + msleep(150); + + syna_rmi4_data->touch_stopped = false ; + //enable_irq(client->irq); + + return num_read_chars; +} + +static ssize_t synaptics_rmi4_baseline_data_open_cbc(char *buf) +{ + int ret = 0; + int x, y; + int16_t read_data; + uint8_t tmp_old = 0; + uint8_t tmp_new = 0; + ssize_t num_read_chars = 0; + uint tx_num = 0; + uint rx_num = 0; + + const int16_t *raw_cap_data = NULL; + int16_t *cdata; + uint16_t word_value; + struct synaptics_rmi4_data *syna_ts_data = syna_rmi4_data ; + struct i2c_client* client = syna_ts_data->i2c_client; + + syna_rmi4_data->touch_stopped = true; + + disable_irq_nosync(client->irq); + + if (syna_ts_data->vendor_id == TP_VENDOR_WINTEK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + raw_cap_data = (const int16_t *)raw_cap_data_wintek_9093; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + raw_cap_data = (const int16_t *)raw_cap_data_tpk; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TRULY) + { + tx_num = TX_NUM_TRULY_N3; + rx_num = RX_NUM_TRULY_N3; + raw_cap_data = (const int16_t *)raw_cap_data_turly_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK_GFF) + { + tx_num = TX_NUM_TPK_GFF_N3; + rx_num = RX_NUM_TPK_GFF_N3; + raw_cap_data = (const int16_t *)raw_cap_data_tpk_gff_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_JDI) + { + tx_num = TX_NUM_JDI; + rx_num = RX_NUM_JDI; + raw_cap_data = (const int16_t *)raw_cap_data_JDI; + } + + cdata = (int16_t *)raw_cap_data ; + + //set report type + tmp_new = 0x03 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + //enable cbc + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+23, &tmp_old,1); + tmp_new = tmp_old | 0x10; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +23, &tmp_new,1); + + // Forbid NoiseMitigation + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +7, &tmp_new,1); + tmp_new = 0x04 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force update + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Forbid NoiseMitigation oK, %d\n", __LINE__); + tmp_new = 0x02 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force cal + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Force Cal oK\n"); + + word_value = 0 ;//set fifo 00 , first address + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + tmp_new = 0x01 ;//send get report command + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + wait_test_cmd_finished(); + + num_read_chars += sprintf(&(buf[num_read_chars]), "\n enable cbc:\n"); + + for(x = 0;x < tx_num; x++) + { + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]",x); + for(y = 0; y < rx_num; y++) + { + ret = i2c_smbus_read_word_data(client,F54_DATA_BASE_ADDR+3); + read_data = ret & 0xffff; + + num_read_chars += sprintf(&(buf[num_read_chars]), "%d ",read_data); + + print_ts(TS_DEBUG, "Raw[%2d][%2d] = %4d, ", x, y, read_data); + print_ts(TS_DEBUG, "range:[%4d ~ %4d]\n", cdata[0], cdata[1]); + + cdata += 2 ; + } + + } + + synaptics_rmi4_reset_device(syna_ts_data, syna_ts_data->f01_cmd_base_addr); + synaptics_rmi4_reinit_device(syna_rmi4_data); + + msleep(150); + + syna_rmi4_data->touch_stopped = false ; + //enable_irq(client->irq); + + return num_read_chars; + +} + +static ssize_t synaptics_rmi4_baseline_data_close_cbc(char *buf) +{ + int ret = 0; + int x, y; + int16_t read_data; + uint8_t tmp_old = 0; + uint8_t tmp_old2 = 0; + uint8_t tmp_new = 0; + ssize_t num_read_chars = 0; + uint tx_num = 0; + uint rx_num = 0; + + const int16_t *raw_cap_data = NULL; + int16_t *cdata; + uint16_t word_value; + struct synaptics_rmi4_data *syna_ts_data = syna_rmi4_data ; + struct i2c_client* client = syna_ts_data->i2c_client; + + syna_rmi4_data->touch_stopped = true; + + disable_irq_nosync(client->irq); + + if (syna_ts_data->vendor_id == TP_VENDOR_WINTEK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + raw_cap_data = (const int16_t *)raw_cap_data_wintek_9093; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + raw_cap_data = (const int16_t *)raw_cap_data_tpk; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TRULY) + { + tx_num = TX_NUM_TRULY_N3; + rx_num = RX_NUM_TRULY_N3; + raw_cap_data = (const int16_t *)raw_cap_data_turly_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK_GFF) + { + tx_num = TX_NUM_TPK_GFF_N3; + rx_num = RX_NUM_TPK_GFF_N3; + raw_cap_data = (const int16_t *)raw_cap_data_tpk_gff_N3; + } + else if (syna_ts_data->vendor_id == TP_VENDOR_JDI) + { + tx_num = TX_NUM_JDI; + rx_num = RX_NUM_JDI; + raw_cap_data = (const int16_t *)raw_cap_data_JDI; + } + cdata = (int16_t *)raw_cap_data + tx_num * rx_num * 2 ; + + print_ts(TS_INFO, "F54_DATA_BASE_ADDR = 0x%x, F54_CTRL_BASE_ADDR = 0x%x, F54_CMD_BASE_ADDR = 0x%x.\n", F54_DATA_BASE_ADDR, F54_CTRL_BASE_ADDR, F54_CMD_BASE_ADDR); + + //set report type + tmp_new = 0x03 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + tmp_new = 1;//disable cdm + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +20, &tmp_new,1); + + //disable cbc + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+23, &tmp_old,1); + tmp_new = tmp_old & 0xef; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +23, &tmp_new,1); + + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+25, &tmp_old2,1); + tmp_new = tmp_old2 & 0xdf; + print_ts(TS_DEBUG, "tmp_old =0x%x ,tmp_new = 0x%x\n", tmp_old2, tmp_new); + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +25, &tmp_new,1); + + tmp_new = 0x04 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force update + wait_test_cmd_finished(); + + // Forbid NoiseMitigation + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +7, &tmp_new,1); + tmp_new = 0x04 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force update + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Forbid NoiseMitigation oK, %d\n", __LINE__); + tmp_new = 0x02 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force cal + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Force Cal oK\n"); + + word_value = 0 ;//set fifo 00 + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + wait_test_cmd_finished(); + + num_read_chars += sprintf(&(buf[num_read_chars]), "\n disable cbc:\n"); + + for(x = 0;x < tx_num; x++) + { + num_read_chars += sprintf(&(buf[num_read_chars]), "\n[%d]",x); + for(y = 0; y < rx_num; y++) + { + ret = i2c_smbus_read_word_data(client,F54_DATA_BASE_ADDR+3); + read_data = ret & 0xffff; + + num_read_chars += sprintf(&(buf[num_read_chars]), "%d ",read_data); + + print_ts(TS_DEBUG, "Raw[%2d][%2d] = %4d, ", x, y, read_data); + print_ts(TS_DEBUG, "range:[%4d ~ %4d]\n", cdata[0], cdata[1]); + + cdata += 2 ; + } + + } + + synaptics_rmi4_reset_device(syna_ts_data, syna_ts_data->f01_cmd_base_addr); + + synaptics_rmi4_reinit_device(syna_rmi4_data); + + msleep(150); + + syna_rmi4_data->touch_stopped = false ; + //enable_irq(client->irq); + + return num_read_chars; + +} + +static ssize_t synaptics_rmi4_baseline_data(char *buf, bool savefile) +{ + int ret = 0; + int x, y, i; + int16_t read_data; + uint8_t tmp_old = 0; + uint8_t tmp_old2 = 0; + uint8_t tmp_new = 0; + ssize_t num_read_chars = 0; + uint tx_num = 0; + uint rx_num = 0; + uint tx_judge_num = 0; + uint rx_judge_num = 0; + uint rx2rx_lower_limit = 0; + uint rx2rx_upper_limit = 0; + const int16_t *raw_cap_data = NULL; + int16_t *cdata; + int16_t *Rxdata = NULL; + int error_count = 0; + static bool isbaseline = 0 ; + uint16_t word_value; + struct synaptics_rmi4_data *syna_ts_data = syna_rmi4_data ; + struct i2c_client* client = syna_ts_data->i2c_client; + + int fd = -1; + struct timespec now_time; + struct rtc_time rtc_now_time; + uint8_t data_buf[64]; + mm_segment_t old_fs; + + int iCbcDataGroupe=0; + int iCbcDataSize=0; + + if(isbaseline == true) { + return sprintf(&(buf[num_read_chars]), "-1 please wait to finish .\n"); + } + + syna_rmi4_data->touch_stopped = true ; + + isbaseline = true ; + + disable_irq_nosync(client->irq); + + if (syna_ts_data->vendor_id == TP_VENDOR_TRULY) + { + tx_num = TX_NUM_TRULY; + rx_num = RX_NUM_TRULY; + rx2rx_lower_limit = DiagonalLowerLimit_TRULY; + rx2rx_upper_limit = DiagonalUpperLimit_TRULY; + raw_cap_data = (const int16_t *)raw_cap_data_truly_3035; + iCbcDataSize = sizeof(raw_cap_data_truly_3035); + } + else if (syna_ts_data->vendor_id == TP_VENDOR_WINTEK) + { + tx_num = TX_NUM_WINTEK; + rx_num = RX_NUM_WINTEK; + rx2rx_lower_limit = DiagonalLowerLimit_WINTEK; + rx2rx_upper_limit = DiagonalUpperLimit_WINTEK; + raw_cap_data = (const int16_t *)raw_cap_data_wintek_9093; + iCbcDataSize = sizeof(raw_cap_data_wintek_9093); + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK) + { + tx_num = TX_NUM_TPK; + rx_num = RX_NUM_TPK; + rx2rx_lower_limit = DiagonalLowerLimit_TPK; + rx2rx_upper_limit = DiagonalUpperLimit_TPK; + raw_cap_data = (const int16_t *)raw_cap_data_tpk; + iCbcDataSize = sizeof(raw_cap_data_tpk); + } + else if (syna_ts_data->vendor_id == TP_VENDOR_YOUNGFAST) + { + tx_num = TX_NUM_YOUNGFAST; + rx_num = RX_NUM_YOUNGFAST; + rx2rx_lower_limit = DiagonalLowerLimit_YOUNGFAST; + rx2rx_upper_limit = DiagonalUpperLimit_YOUNGFAST; + raw_cap_data = (const int16_t *)raw_cap_data_youngfast; + iCbcDataSize = sizeof(raw_cap_data_youngfast); + } + else if (syna_ts_data->vendor_id == TP_VENDOR_TPK_GFF) + { + tx_num = TX_NUM_TPK_GFF_N3; + rx_num = RX_NUM_TPK_GFF_N3; + rx2rx_lower_limit = DiagonalLowerLimit_TPK; + rx2rx_upper_limit = DiagonalUpperLimit_TPK; + raw_cap_data = (const int16_t *)raw_cap_data_tpk_gff_N3; + iCbcDataSize = sizeof(raw_cap_data_tpk_gff_N3); + } + else if (syna_ts_data->vendor_id == TP_VENDOR_JDI) + { + tx_num = TX_NUM_JDI; + rx_num = RX_NUM_JDI; + rx2rx_lower_limit = DiagonalLowerLimit_JDI; + rx2rx_upper_limit = DiagonalUpperLimit_JDI; + raw_cap_data = (const int16_t *)raw_cap_data_JDI; + iCbcDataSize = sizeof(raw_cap_data_JDI); + } + + if (tx_num == 0 || rx_num == 0 || raw_cap_data == NULL + || rx2rx_lower_limit == 0 || rx2rx_upper_limit == 0 || tx_num < rx_num) + { + num_read_chars += sprintf(&(buf[num_read_chars]), "%2d++ NO appropriate data for current tp.\n", ++error_count); + goto END_TP_TEST; + } + + print_ts(TS_DEBUG, "alloc test memory.\n"); + Rxdata = kmalloc(sizeof(int16_t)*rx_num*rx_num, GFP_KERNEL); + if (Rxdata == NULL) + { + num_read_chars += sprintf(&(buf[num_read_chars]), "%2d++ alloc memory failed.\n", ++error_count); + goto END_TP_TEST; + } + //memset(Rxdata, 0, sizeof(Rxdata)); + + synaptics_set_int_mask(syna_ts_data, 0); + //step1:check baseline capacitance + print_ts(TS_DEBUG, "-------------------Step 1: check baseline capacitance --------------------- \n"); + if(savefile) { + getnstimeofday(&now_time); + rtc_time_to_tm(now_time.tv_sec, &rtc_now_time); + sprintf(data_buf, "/sdcard/tp_testlimit_%02d%02d%02d-%02d%02d%02d.csv", + (rtc_now_time.tm_year+1900)%100, rtc_now_time.tm_mon+1, rtc_now_time.tm_mday, + rtc_now_time.tm_hour, rtc_now_time.tm_min, rtc_now_time.tm_sec); + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fd = sys_open(data_buf, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) { + print_ts(TS_DEBUG, "Open log file '%s' failed.\n", data_buf); + set_fs(old_fs); + } + + } + + for(iCbcDataGroupe=0;iCbcDataGroupe<2;iCbcDataGroupe++) + { + if(0 == iCbcDataGroupe) // enable cbc default, for enable cbc test + { + cdata = (int16_t *)raw_cap_data ; + //set report type + tmp_new = 0x03 ;//set report type 0x03, for enable cbc + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + // Forbid NoiseMitigation + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +7, &tmp_new,1); + + tmp_new = 0x02 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force cal + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Force Cal oK\n"); + + word_value = 0 ;//set fifo 00 , first address + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + tmp_new = 0x01 ;//send get report command + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + wait_test_cmd_finished(); + } + else if(1 == iCbcDataGroupe) // disable cbc, for disable cbc test + { + if( iCbcDataSize < ( tx_num * rx_num * 2) ) + { + print_ts(TS_DEBUG, " Only one group test data \n" ); + break ; + } + else + { + cdata = (int16_t *)raw_cap_data + tx_num * rx_num * 2 ; + + //set report type + tmp_new = 0x03 ;//set report type 0x03, for enable cbc + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + //disable cbc + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+21, &tmp_old,1); + tmp_new = tmp_old & 0xef; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +21, &tmp_new,1); + + tmp_new = 0x04 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force update + wait_test_cmd_finished(); + + // Forbid NoiseMitigation + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +7, &tmp_new,1); + + print_ts(TS_DEBUG, "Forbid NoiseMitigation oK, %d\n", __LINE__); + tmp_new = 0x02 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force cal + wait_test_cmd_finished(); + print_ts(TS_DEBUG, "Force Cal oK\n"); + + word_value = 0 ;//set fifo 00 + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + tmp_new = 0x01 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + wait_test_cmd_finished(); + } + } + + tx_judge_num = tx_num; + rx_judge_num = rx_num; + + for(x = 0;x < tx_num; x++) + { + for(y = 0; y < rx_num; y++) + { + ret = i2c_smbus_read_word_data(client,F54_DATA_BASE_ADDR+3); + read_data = ret & 0xffff; + + print_ts(TS_DEBUG, "Raw[%d][%d] = %d, ", x, y, read_data); + print_ts(TS_DEBUG, "range:[%d ~ %d], ", cdata[0], cdata[1]); + + if (fd >= 0) + { + sprintf(data_buf, "%d,", read_data); + sys_write(fd, data_buf, strlen(data_buf)); + } + + if (read_data >= cdata[0] && read_data <= cdata[1]) + { + print_ts(TS_DEBUG, "pass.\n"); + } + else + { + print_ts(TS_ERROR, "NOT in range!!\n"); + + if (error_count >= syna_test_max_err_count) + { + if (!savefile) { + num_read_chars += sprintf(&(buf[num_read_chars]), " == Reach max error count (%d), stop test.\n", syna_test_max_err_count); + goto END_TP_TEST; + } + } else { + num_read_chars += sprintf(&(buf[num_read_chars]), "%2d++ raw_cap[%02d][%02d]=%4d is not in range[%04d~%04d].\n", + ++error_count,x,y,read_data,cdata[0],cdata[1]); + } + + } + cdata += 2; + } + + if (fd >= 0) + { + sys_write(fd, "\n", 1); + } + + } + } + + + // step2 for high impedance test + print_ts(TS_DEBUG, "-------------------Step 2 : high resistance test--------------------- \n"); + print_ts(TS_DEBUG, "n"); + + tmp_new = 1;// software reset TP + synaptics_rmi4_i2c_write(syna_ts_data,syna_ts_data->f01_cmd_base_addr,(unsigned char*)&tmp_new,1); + msleep(150); + + tmp_new = 4 ;//set report type 0x4, for disable cbc + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, &tmp_new,1); + + tmp_new = 1;//disable cdm + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +20, &tmp_new,1); + + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+23, &tmp_old,1);//disable cbc + tmp_new = tmp_old & 0xef; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +23, &tmp_new,1); + + synaptics_rmi4_i2c_read(syna_ts_data, F54_CTRL_BASE_ADDR+25, &tmp_old2,1); + tmp_new = tmp_old2 & 0xdf; + print_ts(TS_DEBUG, "tmp_old =0x%x ,tmp_new = 0x%x\n", tmp_old2, tmp_new); + synaptics_rmi4_i2c_write(syna_ts_data, F54_CTRL_BASE_ADDR +25, &tmp_new,1); + + tmp_new = 0x04 ; + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); // force update + wait_test_cmd_finished(); + + word_value = 0 ;//set fifo 00 , first address + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)&word_value,2); + tmp_new = 0x01 ;//send get report command + synaptics_rmi4_i2c_write(syna_ts_data, F54_CMD_BASE_ADDR, &tmp_new,1); + wait_test_cmd_finished(); + + //高阻测试项,主è¦çš„æµ‹è¯•æ•°æ®ç”±3个WORD组æˆï¼Œè¯»å›žæ•°æ®é™¤ä»¥1000åŽï¼Œ Limit 分别为:(-1,0.45),(-1,0.45),(-0.5,0.02) + for(i = 0;i < 3; i++) + { + int iTemp[2]; + ret = i2c_smbus_read_word_data(client,F54_DATA_BASE_ADDR+3); //is F54_DATA_BASE_ADDR+3 not F54_DATA_BASE_ADDR+i + read_data = ret & 0xffff; + + if (fd >= 0) + { + sprintf(data_buf, "%d,", read_data); + sys_write(fd, data_buf, strlen(data_buf)); + } + + if( (i==0) || (i==1) ) //(-1000 ,450) , (-400,20) + { + iTemp[0] = (-1) *1000; + iTemp[1] = 0.45*1000; + } + else if(i==2) + { + iTemp[0] = (-0.5) *1000; + iTemp[1] = 0.02*1000; + } + if (read_data >= iTemp[0] && read_data <= iTemp[1]) + { + print_ts(TS_DEBUG, "pass.\n"); + } + else + { + print_ts(TS_ERROR,"========= High Resistance Raw NOT in range, Raw[%d] = %d \n ", i, read_data); + num_read_chars += sprintf(&(buf[num_read_chars]), "=========== High Resistance Raw NOT in range, Raw[%d] = %d \n ", i, read_data); + error_count ++; // in app , pass ---> error_count = 0 , fail ---> error_count = not zero + } + + } + + //Step3 : Check trx-to-trx ,short test + print_ts(TS_DEBUG, "-------------------Step 3 : Check trx-to-trx--------------------- \n"); + + tmp_new = 1;// software reset TP + synaptics_rmi4_i2c_write(syna_ts_data,syna_ts_data->f01_cmd_base_addr,(unsigned char*)&tmp_new,1); + msleep(150); + + tmp_new = 26 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, (unsigned char*)&tmp_new,1); //select report type 0x26 + + tmp_new = 0 ; + data_buf[0] = 0 ; + data_buf[1] = 0 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)data_buf,2); + tmp_new = 1 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_CMD_BASE_ADDR, (unsigned char*)&tmp_new,1); //get report + wait_test_cmd_finished(); + + y = synaptics_rmi4_i2c_read(syna_ts_data, F54_DATA_BASE_ADDR+3, data_buf,7) ; + print_ts(TS_DEBUG," trx-to-trx raw readback: %x %x %x %x %x %x \n", data_buf[0],data_buf[1],data_buf[2],data_buf[3],data_buf[4],data_buf[5]); + num_read_chars += sprintf(&(buf[num_read_chars]), " trx-to-trx raw readback: %x %x %x %x %x %x \n", data_buf[0],data_buf[1],data_buf[2],data_buf[3],data_buf[4],data_buf[5]); + if((data_buf[0]==0) && (data_buf[1]==0) && (data_buf[2]==0)\ + &&( (data_buf[3]&0x07)==0) && (data_buf[4]==0) && ((data_buf[5]&0x3f)==0)) + { + print_ts(TS_DEBUG, " trx-to-trx test pass.\n"); + } + else + { + print_ts(TS_ERROR," trx-to-trx test error: data_buf[3]&0x07 =%x data_buf[5]&0x3f=%x \n",data_buf[3]&0x07,data_buf[5]&0x3f) ; + num_read_chars += sprintf(&(buf[num_read_chars]), " trx-to-trx test error: data_buf[3]&0x07 =%x data_buf[5]&0x3f=%x \n",data_buf[3]&0x07,data_buf[5]&0x3f) ; + error_count ++; + } + + //Step4 : Check trx-to-ground + print_ts(TS_DEBUG, "-------------------step 4 : Check trx-to-ground--------------------- \n"); + + tmp_new = 1;// software reset TP + synaptics_rmi4_i2c_write(syna_ts_data,syna_ts_data->f01_cmd_base_addr,(unsigned char*)&tmp_new,1); + msleep(150); + + tmp_new = 25 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR, (unsigned char*)&tmp_new,1); //select report type 0x25 + + tmp_new = 0 ; + data_buf[0] = 0 ; + data_buf[1] = 0 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_DATA_BASE_ADDR+1, (unsigned char*)data_buf,2); + tmp_new = 1 ; + synaptics_rmi4_i2c_write(syna_ts_data,F54_CMD_BASE_ADDR, (unsigned char*)&tmp_new,1); //get report + wait_test_cmd_finished(); + + y = synaptics_rmi4_i2c_read(syna_ts_data, F54_DATA_BASE_ADDR+3, data_buf,7) ; + print_ts(TS_DEBUG,"trx-to-ground raw readback: %x %x %x %x %x %x \n", data_buf[0],data_buf[1],data_buf[2],data_buf[3],data_buf[4],data_buf[5]); + + print_ts(TS_DEBUG, "%d: syna_ts_data->vendor_id=%d,data_buf[4]=%d\n",__LINE__,syna_ts_data->vendor_id,data_buf[4]); + + if((data_buf[0]==0x00) && (data_buf[1]==0xa0) && (data_buf[2]==0xff)\ + &&( (data_buf[3]&0x07)==0x7) && (data_buf[4]==0x00) && (data_buf[5]==0x00)) + { + print_ts(TS_DEBUG, "pass.\n"); + } + else + { + print_ts(TS_ERROR, "%d: syna_ts_data->vendor_id=%d,data_buf[4]=%d\n",__LINE__,syna_ts_data->vendor_id,data_buf[4]); + print_ts(TS_ERROR, " trx-to-ground Test Failed [%d]\n",__LINE__); + num_read_chars += sprintf(&(buf[num_read_chars]), " trx-to-ground test Failed[%d]\n",__LINE__); + error_count ++; + } + //step 5:reset touchpanel and reconfig the device +END_TP_TEST: + if (fd >= 0) { + sys_close(fd); + set_fs(old_fs); + } + + if (Rxdata) + { + print_ts(TS_DEBUG, "Release test memory.\n"); + kfree(Rxdata); + } + + printk(error_count ? " ********** TP auto test error ********** " : " ********** TP All test passed ********** "); + num_read_chars += sprintf(&(buf[num_read_chars]), "imageid=0x%x,deviceid=0x%x\n", syna_ts_data->image_cid,syna_ts_data->device_cid); + + num_read_chars += sprintf(&(buf[num_read_chars]), "%d error(s). %s\n", error_count, error_count?"":" ********** All test passed. ********** "); + synaptics_rmi4_reset_device(syna_ts_data, syna_ts_data->f01_cmd_base_addr); + + msleep(150); + synaptics_set_int_mask(syna_ts_data, 1); + + syna_rmi4_data->touch_stopped = false ; + //enable_irq(client->irq); + + isbaseline = false ; + + return num_read_chars; +} + +static ssize_t synaptics_rmi4_baseline_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + unsigned char *buffer = 0 ; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if(input == 21) { + buffer = kzalloc(1024, GFP_KERNEL); + if(buffer) { + synaptics_rmi4_baseline_data(buffer,1); + kfree(buffer); + } + } + + return count ; +} +static ssize_t synaptics_attr_loglevel_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + //add test code. for tp is invalid + unsigned int value = gpio_get_value(syna_rmi4_data->irq_gpio); + return sprintf(buf, "%d:0x%x\n", syna_log_level,value); +} +static ssize_t synaptics_attr_loglevel_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int val = 0; + sscanf(buf, "%d", &val); + syna_log_level = val; + printk("[synaptics] set log level : %d\n", val); + return count; +} + +static ssize_t synaptics_rmi4_vendor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", syna_rmi4_data->vendor_id); +} + +static ssize_t synaptics_rmi4_delta_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return synaptics_rmi4_read_delta_data(buf); +} + +static ssize_t synaptics_rmi4_baseline_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return synaptics_rmi4_baseline_data(buf,0); +} + +static ssize_t synaptics_rmi4_read_baseline_data_open_cbc(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return synaptics_rmi4_baseline_data_open_cbc(buf); +} + +static ssize_t synaptics_rmi4_read_baseline_data_close_cbc(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return synaptics_rmi4_baseline_data_close_cbc(buf); +} + +static ssize_t sense_frequency_selection_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned char value ; + + synaptics_rmi4_i2c_read(syna_rmi4_data, 0x010B, &value,1); + return sprintf(buf, "sense_frequency_selection_reg 0x10b = 0x%x\n", value); +} +static ssize_t sense_frequency_selection_reg_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int val = 0; + sscanf(buf, "%d", &val); + return count; +} + +static struct synaptics_dsx_cap_button_map button_map = { + .nbuttons = 0, + .map = "NULL", +}; + + +static struct synaptics_dsx_platform_data dsx_platformdata = { + .irq_flags = IRQF_TRIGGER_FALLING|IRQF_ONESHOT, + .reset_delay_ms = 100, + .cap_button_map = &button_map, + .regulator_en = 1, +}; + +static int synaptics_parse_dt(struct device *dev, struct synaptics_rmi4_data *ts) +{ + int ret = 0; + if (dev->of_node) + { + struct device_node *np = dev->of_node; + + /* reset, irq gpio info */ + ts->irq_gpio = of_get_named_gpio(np, "synaptics,irq-gpio", 0); + if( ts->irq_gpio < 0 ){ + printk("ts->irq_gpio not specified\n"); + } + ts->reset_gpio = of_get_named_gpio(np, "synaptics,reset-gpio", 0); + if( ts->reset_gpio < 0 ){ + printk("ts->reset_gpio not specified\n"); + } + /* + ts->wakeup_gpio = of_get_named_gpio(np, "synaptics,wakeup-gpio", 0); + if( ts->wakeup_gpio < 0 ){ + printk("ts->wakeup_gpio not specified\n"); + } + ts->id_gpio = of_get_named_gpio(np, "synaptics,id-gpio", 0); + if( ts->id_gpio < 0 ){ + printk("ts->id_gpio not specified\n"); + } + */ + printk("%s irq_gpio:%d reset_gpio:%d wakeup_gpio:%d id_gpio:%d \n", __func__, ts->irq_gpio, ts->reset_gpio, ts->wakeup_gpio, ts->id_gpio); + + vdd_regulator = regulator_get(dev, "vdd_2v8"); + if( IS_ERR(vdd_regulator) ){ + ret = PTR_ERR(vdd_regulator); + printk("%s Regulator get failed vdd rc=%d\n", __func__, ret); + } + + vdd_regulator_i2c = regulator_get(dev, "vcc_i2c_1v8"); + if( IS_ERR(vdd_regulator_i2c) ){ + ret = PTR_ERR(vdd_regulator_i2c); + printk("%s Regulator get failed vdd_i2c rc=%d\n", __func__, ret); + } + + } + return ret; +} + +int synaptics_regulator_configure(bool on) +{ + int rc = -1; + + if (on == false) + goto hw_shutdown; + + if(!vdd_regulator) { + //vdd_regulator = regulator_get(NULL, "8941_l22"); + if (IS_ERR(vdd_regulator)) { + rc = PTR_ERR(vdd_regulator); + printk("Regulator get failed vcc_ana rc=%d\n", rc); + return rc; + } + } + if (regulator_count_voltages(vdd_regulator) > 0) { + rc = regulator_set_voltage(vdd_regulator, SYNA_VTG_MIN_UV, SYNA_VTG_MAX_UV); + if (rc) { + printk( "regulator set_vtg failed rc=%d\n", rc); + goto error_set_vtg_vcc_ana; + } + rc = regulator_enable(vdd_regulator); + } + + //vdd_regulator_i2c = regulator_get(NULL, "8941_l14"); + if (IS_ERR(vdd_regulator_i2c)) { + rc = PTR_ERR(vdd_regulator_i2c); + printk( "Regulator get failed rc=%d\n", rc); + goto error_get_vtg_i2c; + } + if (regulator_count_voltages(vdd_regulator_i2c) > 0) { + rc = regulator_set_voltage(vdd_regulator_i2c, SYNA_I2C_VTG_MIN_UV, SYNA_I2C_VTG_MAX_UV); + if (rc) { + printk( "regulator set_vtg failed rc=%d\n", rc); + goto error_set_vtg_i2c; + } + rc = regulator_enable(vdd_regulator_i2c); + } + + return 0; + +error_set_vtg_i2c: + regulator_put(vdd_regulator_i2c); +error_get_vtg_i2c: + if (regulator_count_voltages(vdd_regulator) > 0) + regulator_set_voltage(vdd_regulator, 0, 0); + +error_set_vtg_vcc_ana: + regulator_put(vdd_regulator); + return rc; + +hw_shutdown: + if (regulator_count_voltages(vdd_regulator) > 0) + regulator_set_voltage(vdd_regulator, 0, 0); + regulator_put(vdd_regulator); + //vdd_regulator = 0 ; + + if (regulator_count_voltages(vdd_regulator_i2c) > 0) + regulator_set_voltage(vdd_regulator_i2c, 0, 0); + regulator_put(vdd_regulator_i2c); + //vdd_regulator_i2c = 0 ; + + return 0; +} + +static unsigned char synaptics_rmi4_update_gesture(unsigned char *gesture,unsigned char *gestureext) { + int i ; + unsigned char keyvalue = 0 ; + unsigned char gesturemode = UnkownGestrue ; + unsigned short points[16]; + + for(i = 0 ; i < 2*6; i++) { + points[i] = ((unsigned short)gestureext[i*2]) | (((unsigned short)gestureext[i*2+1])<<8) ; + } + + points[i] = + (gestureext[24] == 0x10) ? 1 : + (gestureext[24] == 0x20) ? 0 : + 2 ;// 1--clockwise, 0--anticlockwise, not circle, report 2 + + print_ts(TS_ERROR, KERN_ERR "%s, gesture[0] = 0x%x, points[12] = %d (%s)\n", __func__,gesture[0], points[12], + (points[12] == 1) ? "clockwise" : + (points[12] == 0) ? "anticlockwise" : + "not circle"); + switch(gesture[0]) { + case SYNA_ONE_FINGER_CIRCLE: + gesturemode = Circle ; + keyvalue = KEY_F4; + break ; + + case SYNA_TWO_FINGER_SWIPE: + gesturemode = + (gestureext[24] == 0x41) ? Left2RightSwip : + (gestureext[24] == 0x42) ? Right2LeftSwip : + (gestureext[24] == 0x44) ? Up2DownSwip : + (gestureext[24] == 0x48) ? Down2UpSwip : + (gestureext[24] == 0x80) ? DouSwip : + UnkownGestrue; + + if( gesturemode==DouSwip || + gesturemode==Down2UpSwip || + gesturemode==Up2DownSwip) { + if(abs(points[3] - points[1]) <= 800) + gesturemode=UnkownGestrue; + } + + if(gesturemode!=UnkownGestrue) { + keyvalue = KEY_F6; + } + break ; + + case SYNA_ONE_FINGER_DOUBLE_TAP: + gesturemode = DouTap ; + keyvalue = KEY_F3; + break ; + + case SYNA_ONE_FINGER_DIRECTION: + switch(gesture[2]){ + case 0x01: //UP + gesturemode = DownVee ; + keyvalue = KEY_F5; + break; + case 0x02: //DOWN + gesturemode = UpVee ; + keyvalue = KEY_F5; + break; + case 0x04: //LEFT + gesturemode = RightVee ; + keyvalue = KEY_F7; + break; + case 0x08: //RIGHT + gesturemode = LeftVee ; + keyvalue = KEY_F8; + break; + } + break; + + case SYNA_ONE_FINGER_W_OR_M: + gesturemode = + (gesture[2] == 0x77 && gesture[3] == 0x00) ? Wgestrue : + (gesture[2] == 0x6d && gesture[3] == 0x00) ? Mgestrue : + UnkownGestrue; + + keyvalue = KEY_F9; + break ; + } + + if(gesturemode != UnkownGestrue) + { + syna_rmi4_data->gesturemode = gesturemode ; + memcpy(syna_rmi4_data->points,points,sizeof(syna_rmi4_data->points)); + } + else + { + keyvalue = 0 ; + } + + print_ts(TS_ERROR, "%s, gesture keyvalue = %d, gesturemode = %d (%s).\n", __func__, keyvalue, gesturemode, + (gesturemode == 0) ? "UnkownGestrue" : + (gesturemode == 1) ? "Double Tap" : + (gesturemode == 2) ? "V" : + (gesturemode == 3) ? "^" : + (gesturemode == 4) ? ">" : + (gesturemode == 5) ? "<" : + (gesturemode == 6) ? "O" : + (gesturemode == 7) ? "||" : + (gesturemode == 8) ? "-->" : + (gesturemode == 9) ? "<--" : + (gesturemode == 10) ? "|V" : + (gesturemode == 11) ? "|^" : + (gesturemode == 12) ? "M" : + "W" ); + + return keyvalue ; +} + +/** + * synaptics_rmi4_f12_abs_report() + * + * Called by synaptics_rmi4_report_touch() when valid Function $12 + * finger data has been detected. + * + * This function reads the Function $12 data registers, determines the + * status of each finger supported by the Function, processes any + * necessary coordinate manipulation, reports the finger data to + * the input subsystem, and returns the number of fingers detected. + */ +static int synaptics_rmi4_f12_abs_report(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + int retval; + unsigned char touch_count = 0; /* number of touch points */ + unsigned char finger; + unsigned char fingers_to_process; + unsigned char finger_status; + unsigned char size_of_2d_data; + unsigned short data_addr; + int x; + int y; + int wx; + int wy; + int temp; + struct synaptics_rmi4_f12_extra_data *extra_data; + struct synaptics_rmi4_f12_finger_data *data; + struct synaptics_rmi4_f12_finger_data *finger_data; + unsigned char gesture[5]; + unsigned char gestureext[25]; + unsigned char keyvalue; + unsigned int finger_info = 0; + + fingers_to_process = fhandler->num_of_data_points; + data_addr = fhandler->full_addr.data_base; + extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; + size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); + + if(rmi4_data->gesture ) + { + retval = synaptics_rmi4_i2c_read(rmi4_data, SYNA_ADDR_GESTURE_OFFSET_s3320, gesture, sizeof(gesture)); + retval = synaptics_rmi4_i2c_read(rmi4_data, SYNA_ADDR_GESTURE_EXT_S3528, gestureext, sizeof(gestureext)); + + if(gesture[0]==0x0c) //mingqiang.guo@phone.bsp 厂家新添加了三击手势代å·ä¸º0x0c,OPPO未用到,这个会影å“到åŒå‡»äº®å±æˆåŠŸçŽ‡ï¼Œ + //当æˆåŒå‡»äº®å±å¤„ç†,åŒå‡»æˆ–者多击æˆåŠŸçŽ‡æé«˜ï¼Œä¸Žä»¥å‰é‡äº§å›ºä»¶ä¿æŒä¸€è‡´ + gesture[0]=0x03; + + if(gesture[0] != 0) //如果为åŒå‡»å”¤é†’æ‰‹åŠ¿ä¸­æ–­ï¼ŒæŒæœ‰è¯¥wake_lock,å¦‚æžœå½“å‰æ­£åœ¨è·‘suspendæµç¨‹ï¼Œå°†ä¼šè°ƒç”¨resume唤醒系统,放弃suspend + wake_lock_timeout(&tp_wake_lock, 5 * HZ); + + if(gesture[0]) + { + keyvalue = synaptics_rmi4_update_gesture(gesture,gestureext); + if(keyvalue) + { + keyvalue = KEY_F4 ; + + print_ts(TS_ERROR, KERN_ERR"report gesture keyvalue!\n"); + + input_report_key(rmi4_data->input_dev, keyvalue, 1); + input_sync(rmi4_data->input_dev); + input_report_key(rmi4_data->input_dev, keyvalue, 0); + input_sync(rmi4_data->input_dev); + } + } + } + + //check pdoze status + if(rmi4_data->pdoze_enable) + { + retval = synaptics_rmi4_i2c_read(rmi4_data, SYNA_ADDR_PDOZE_FLAG, &keyvalue, 1); + keyvalue = (keyvalue & 0x60)?1:0 ; + rmi4_data->pdoze_status = keyvalue ; + print_ts(TS_DEBUG, KERN_ERR "[syna]pdoze status: %d\n",rmi4_data->pdoze_status); + } + + retval = synaptics_rmi4_i2c_read(rmi4_data, data_addr + extra_data->data1_offset, (unsigned char *)fhandler->data, fingers_to_process * size_of_2d_data); + if (retval < 0) + { + printk(KERN_ERR"[TP]%s:%d i2c communication error \n ",__func__,__LINE__); + return 0; + } + data = (struct synaptics_rmi4_f12_finger_data *)fhandler->data; + + for (finger = 0; finger < fingers_to_process; finger++) + { + finger_data = data + finger; + finger_status = finger_data->object_type_and_status & MASK_2BIT; + finger_info <<= 1; + //print_ts(TS_DEBUG, KERN_ERR"%s finger:%d finger_status:%d object_type_and_status:%d \n", __func__, finger, finger_status, finger_data->object_type_and_status); + if (finger_status) + { + x = (finger_data->x_msb << 8) | (finger_data->x_lsb); + y = (finger_data->y_msb << 8) | (finger_data->y_lsb); +#ifdef REPORT_2D_W + wx = finger_data->wx; + wy = finger_data->wy; +#endif + + if (rmi4_data->board->swap_axes) { + temp = x; + x = y; + y = temp; + temp = wx; + wx = wy; + wy = temp; + } + + if (rmi4_data->board->x_flip) + x = rmi4_data->sensor_max_x - x; + if (rmi4_data->board->y_flip) + y = rmi4_data->sensor_max_y - y; + + { + int pressed_vkey = get_virtual_key_button(x, y); + + //print_ts(TS_DEBUG, KERN_ERR"%s: virtual_key = %d\n", __func__, pressed_vkey); + + if (pressed_vkey == TP_VKEY_NONE) + { + continue; + } + } + + input_mt_slot(rmi4_data->input_dev, finger); + input_mt_report_slot_state(rmi4_data->input_dev, MT_TOOL_FINGER, finger_status); + input_report_key(rmi4_data->input_dev, BTN_TOUCH, 1); + input_report_key(rmi4_data->input_dev, BTN_TOOL_FINGER, 1); + input_report_abs(rmi4_data->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(rmi4_data->input_dev, ABS_MT_POSITION_Y, y); +#ifdef REPORT_2D_W + input_report_abs(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, max(wx, wy)); + input_report_abs(rmi4_data->input_dev, ABS_MT_TOUCH_MINOR, min(wx, wy)); +#endif +#ifndef TYPE_B_PROTOCOL + input_mt_sync(rmi4_data->input_dev); +#endif + + print_ts(TS_DEBUG, KERN_ERR + "%s: Finger %d: status = 0x%02x " + "x = %4d, y = %4d, wx = %2d, wy = %2d\n", + __func__, finger, finger_status, x, y, wx, wy); + + touch_count++; + finger_info |= 1 ; + } + } + + for (finger = 0; finger < fingers_to_process; finger++) + { + finger_status = (finger_info>>(fingers_to_process-finger-1)) & 1 ; + if(!finger_status) + { + input_mt_slot(rmi4_data->input_dev, finger); + input_mt_report_slot_state(rmi4_data->input_dev, MT_TOOL_FINGER, finger_status); + } + } + + if (touch_count == 0) + { + input_report_key(rmi4_data->input_dev,BTN_TOUCH, 0); + print_ts(TS_DEBUG,"all finger up\n"); + input_report_key(rmi4_data->input_dev, BTN_TOOL_FINGER, 0); +#ifndef TYPE_B_PROTOCOL + input_mt_sync(rmi4_data->input_dev); +#endif + } + + input_sync(rmi4_data->input_dev); + + return touch_count; +} + +static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + int retval; + unsigned char touch_count = 0; + unsigned char button; + unsigned char index; + unsigned char shift; + unsigned char status; + unsigned char *data; + unsigned short data_addr = fhandler->full_addr.data_base; + struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; + static unsigned char do_once = 1; + static bool current_status[MAX_NUMBER_OF_BUTTONS]; +#ifdef NO_0D_WHILE_2D + static bool before_2d_status[MAX_NUMBER_OF_BUTTONS]; + static bool while_2d_status[MAX_NUMBER_OF_BUTTONS]; +#endif + + if (do_once) { + memset(current_status, 0, sizeof(current_status)); +#ifdef NO_0D_WHILE_2D + memset(before_2d_status, 0, sizeof(before_2d_status)); + memset(while_2d_status, 0, sizeof(while_2d_status)); +#endif + do_once = 0; + } + + retval = synaptics_rmi4_i2c_read(rmi4_data, + data_addr, + f1a->button_data_buffer, + f1a->button_bitmask_size); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to read button data registers\n", + __func__); + return; + } + + data = f1a->button_data_buffer; + + for (button = 0; button < f1a->valid_button_count; button++) { + index = button / 8; + shift = button % 8; + status = ((data[index] >> shift) & MASK_1BIT); + + if (current_status[button] == status) + continue; + else + current_status[button] = status; + + dev_dbg(&rmi4_data->i2c_client->dev, + "%s: Button %d (code %d) ->%d\n", + __func__, button, + f1a->button_map[button], + status); +#ifdef NO_0D_WHILE_2D + if (rmi4_data->fingers_on_2d == false) { + if (status == 1) { + before_2d_status[button] = 1; + } else { + if (while_2d_status[button] == 1) { + while_2d_status[button] = 0; + continue; + } else { + before_2d_status[button] = 0; + } + } + touch_count++; + input_report_key(rmi4_data->input_dev, + f1a->button_map[button], + status); + } else { + if (before_2d_status[button] == 1) { + before_2d_status[button] = 0; + touch_count++; + input_report_key(rmi4_data->input_dev, + f1a->button_map[button], + status); + } else { + if (status == 1) + while_2d_status[button] = 1; + else + while_2d_status[button] = 0; + } + } +#else + touch_count++; + input_report_key(rmi4_data->input_dev, + f1a->button_map[button], + status); +#endif + } + + if (touch_count) + input_sync(rmi4_data->input_dev); + + return; +} + +/** + * synaptics_rmi4_report_touch() + * + * Called by synaptics_rmi4_sensor_report(). + * + * This function calls the appropriate finger data reporting function + * based on the function handler it receives and returns the number of + * fingers detected. + */ +static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + unsigned char touch_count_2d; + + //print_ts(TS_DEBUG, KERN_ERR"%s: Function %02x reporting\n",__func__, fhandler->fn_number); + + switch (fhandler->fn_number) { + case SYNAPTICS_RMI4_F11: + touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data,fhandler); + if (touch_count_2d) + rmi4_data->fingers_on_2d = true; + else + rmi4_data->fingers_on_2d = false; + break; + case SYNAPTICS_RMI4_F12: + touch_count_2d = synaptics_rmi4_f12_abs_report(rmi4_data,fhandler); + if (touch_count_2d) + rmi4_data->fingers_on_2d = true; + else + rmi4_data->fingers_on_2d = false; + break; + case SYNAPTICS_RMI4_F1A: + synaptics_rmi4_f1a_report(rmi4_data, fhandler); + break; + default: + break; + } + + return; +} + +static void tpd_down(struct synaptics_rmi4_data *rmi4_data,int raw_x, int raw_y, int x, int y, int p) +{ + if(rmi4_data && rmi4_data->input_dev) + { + input_mt_slot(rmi4_data->input_dev, 0); + input_mt_report_slot_state(rmi4_data->input_dev, MT_TOOL_FINGER, 1); + + input_report_key(rmi4_data->input_dev, BTN_TOUCH, 1); + input_report_key(rmi4_data->input_dev, BTN_TOOL_FINGER, 1); + + input_report_abs(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, p); + input_report_abs(rmi4_data->input_dev, ABS_MT_WIDTH_MAJOR, (raw_x+raw_y)/2); + input_report_abs(rmi4_data->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(rmi4_data->input_dev, ABS_MT_POSITION_Y, y); + + //input_mt_sync(rmi4_data->input_dev); + } +} + +static void tpd_up(struct synaptics_rmi4_data *rmi4_data,int raw_x, int raw_y, int x, int y, int p) +{ + if(rmi4_data && rmi4_data->input_dev) + { + input_mt_slot(rmi4_data->input_dev, 0); + input_mt_report_slot_state(rmi4_data->input_dev, MT_TOOL_FINGER, 0); + + input_report_key(rmi4_data->input_dev, BTN_TOUCH, 0); + input_report_key(rmi4_data->input_dev, BTN_TOOL_FINGER, 0); + + //input_mt_sync(rmi4_data->input_dev); + } +} + +static void int_key_report(struct synaptics_rmi4_data *rmi4_data) +{ + int ret= 0; + int F1A_0D_DATA00=0x0; + i2c_smbus_write_byte_data(rmi4_data->i2c_client, 0xff, 0x2); + ret = i2c_smbus_read_byte_data(rmi4_data->i2c_client, F1A_0D_DATA00); + + if((ret&0x07)!=0) + { + print_ts(TS_INFO,"F1A_0D_DATA00 is 0x%x\n",ret); + + if(ret&0x01)//menu + { + tpd_down(rmi4_data,40, 20, rmi4_data->sensor_max_x/6, VK_VENTE_Y,44); + } + + if(ret&0x02)//home + { + tpd_down(rmi4_data,40, 20, rmi4_data->sensor_max_x/2, VK_VENTE_Y,44); + } + + if(ret&0x04)//reback + { + tpd_down(rmi4_data,40, 20, rmi4_data->sensor_max_x*5/6, VK_VENTE_Y,44); + } + } + else + { + print_ts(TS_INFO,"virtual key_up\n"); + tpd_up(rmi4_data,0, 0, 0, 0,0); + } + + input_sync(rmi4_data->input_dev); + i2c_smbus_write_byte_data(rmi4_data->i2c_client, 0xff, 0x0); +} + +static void synaptics_rmi4_esd_process(struct synaptics_rmi4_data *rmi4_data) +{ + print_ts(TS_ERROR,"%s: esd process begin! \n", __func__); + + synaptics_rmi4_reset_device(rmi4_data, rmi4_data->f01_cmd_base_addr); + synaptics_rmi4_reinit_device(rmi4_data); + + print_ts(TS_ERROR,"%s: esd process end! \n", __func__); +} + +/** + * synaptics_rmi4_sensor_report() + * + * Called by synaptics_rmi4_irq(). + * + * This function determines the interrupt source(s) from the sensor + * and calls synaptics_rmi4_report_touch() with the appropriate + * function handler for each function with valid data inputs. + */ +static void synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char data[MAX_INTR_REGISTERS + 1]; + unsigned char *intr = &data[1]; + struct synaptics_rmi4_f01_device_status status; + struct synaptics_rmi4_fn *fhandler; + struct synaptics_rmi4_exp_fn *exp_fhandler; + struct synaptics_rmi4_device_info *rmi; + //print_ts(TS_DEBUG, KERN_ERR"%s report data .... \n", __func__); + rmi = &(rmi4_data->rmi4_mod_info); + + down(&work_sem); + /* + * Get interrupt status information from F01 Data1 register to + * determine the source(s) that are flagging the interrupt. + */ + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_data_base_addr, data, rmi4_data->num_of_intr_regs + 1); + if (retval < 0) + { + print_ts(TS_DEBUG, KERN_ERR"'%s line:%d i2c error... \n ", __func__, __LINE__); + synaptics_rmi4_esd_process(rmi4_data); // zhangqiang add for tp esd process + + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to read interrupt status\n", __func__); + up(&work_sem); + return; + } + + status.data[0] = data[0]; + if (status.unconfigured && !status.flash_prog) { + print_ts(TS_INFO,"%s: spontaneous reset detected\n", __func__); + print_ts(TS_DEBUG, KERN_ERR"%s: data[0] = 0x%x data[1] = 0x%x\n",__func__, data[0],data[1]); + retval = synaptics_rmi4_reinit_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to reinit device\n", __func__); + } + up(&work_sem); + return; + } + + + if(data[1] & 0x04) + { + /* + * Traverse the function handler list and service the source(s) + * of the interrupt accordingly. + */ + if (!list_empty(&rmi->support_fn_list)) { + list_for_each_entry(fhandler, &rmi->support_fn_list, link) { + if (list_empty(&rmi->support_fn_list)) + { + printk(KERN_ERR"[TP] %s:%d support_fn_list is empty, tp happen erro,will reset tp\n",__func__,__LINE__); + up(&work_sem); + return; + } + if (fhandler->num_of_data_sources) { + if (fhandler->intr_mask & intr[fhandler->intr_reg_num]) + { + synaptics_rmi4_report_touch(rmi4_data, fhandler); + } + } + } + } + } + if(data[1] &0x10) + { + int_key_report(rmi4_data); + } + + mutex_lock(&exp_data.mutex); + if (!list_empty(&exp_data.list)) { + list_for_each_entry(exp_fhandler, &exp_data.list, link) { + if(exp_fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (exp_fhandler->inserted && + (exp_fhandler->func_attn != NULL)) + exp_fhandler->func_attn(rmi4_data, intr[0]); + } + } + mutex_unlock(&exp_data.mutex); + + up(&work_sem); + return; +} + +/** + * synaptics_rmi4_irq() + * + * Called by the kernel when an interrupt occurs (when the sensor + * asserts the attention irq). + * + * This function is the ISR thread and handles the acquisition + * and the reporting of finger data when the presence of fingers + * is detected. + */ +static irqreturn_t synaptics_rmi4_irq(int irq, void *data) +{ + struct synaptics_rmi4_data *rmi4_data = data; + + if (!rmi4_data->touch_stopped) + synaptics_rmi4_sensor_report(rmi4_data); + return IRQ_HANDLED; +} + +/** + * synaptics_rmi4_irq_enable() + * + * Called by synaptics_rmi4_probe() and the power management functions + * in this driver and also exported to other expansion Function modules + * such as rmi_dev. + * + * This function handles the enabling and disabling of the attention + * irq including the setting up of the ISR thread. + */ +static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data, + bool enable) +{ + int retval = 0; + unsigned char intr_status[MAX_INTR_REGISTERS]; + const struct synaptics_dsx_platform_data *platform_data = rmi4_data->i2c_client->dev.platform_data; + + if (enable) { + if (rmi4_data->irq_enabled) + return retval; + + /* Clear interrupts first */ + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_data_base_addr + 1, intr_status, rmi4_data->num_of_intr_regs); + if (retval < 0) + return retval; + + + retval = request_threaded_irq(rmi4_data->irq, NULL, synaptics_rmi4_irq, platform_data->irq_flags, DRIVER_NAME, rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to create irq(:%d) thread\n", __func__, rmi4_data->irq); + return retval; + } + + rmi4_data->irq_enabled = true; + } else { + if (rmi4_data->irq_enabled) { + disable_irq(rmi4_data->irq); + free_irq(rmi4_data->irq, rmi4_data); + rmi4_data->irq_enabled = false; + } + } + + return retval; +} + +/** + * synaptics_rmi4_f11_init() + * + * Called by synaptics_rmi4_query_device(). + * + * This funtion parses information from the Function 11 registers + * and determines the number of fingers supported, x and y data ranges, + * offset to the associated interrupt status register, interrupt bit + * mask, and gathers finger data acquisition capabilities from the query + * registers. + */ +static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler, + struct synaptics_rmi4_fn_desc *fd, + unsigned int intr_count) +{ + int retval; + unsigned char ii; + unsigned char intr_offset; + unsigned char abs_data_size; + unsigned char abs_data_blk_size; + unsigned char query[F11_STD_QUERY_LEN]; + unsigned char control[F11_STD_CTRL_LEN]; + + fhandler->fn_number = fd->fn_number; + fhandler->num_of_data_sources = fd->intr_src_count; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.query_base, + query, + sizeof(query)); + if (retval < 0) + return retval; + + /* Maximum number of fingers supported */ + if ((query[1] & MASK_3BIT) <= 4) + fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1; + else if ((query[1] & MASK_3BIT) == 5) + fhandler->num_of_data_points = 10; + + rmi4_data->num_of_fingers = fhandler->num_of_data_points; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.ctrl_base, + control, + sizeof(control)); + if (retval < 0) + return retval; + + /* Maximum x and y */ + rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) | + ((control[7] & MASK_4BIT) << 8); + rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) | + ((control[9] & MASK_4BIT) << 8); + dev_dbg(&rmi4_data->i2c_client->dev, + "%s: Function %02x max x = %d max y = %d\n", + __func__, fhandler->fn_number, + rmi4_data->sensor_max_x, + rmi4_data->sensor_max_y); + + rmi4_data->max_touch_width = MAX_F11_TOUCH_WIDTH; + + fhandler->intr_reg_num = (intr_count + 7) / 8; + if (fhandler->intr_reg_num != 0) + fhandler->intr_reg_num -= 1; + + /* Set an enable bit for each data source */ + intr_offset = intr_count % 8; + fhandler->intr_mask = 0; + for (ii = intr_offset; + ii < ((fd->intr_src_count & MASK_3BIT) + + intr_offset); + ii++) + fhandler->intr_mask |= 1 << ii; + + abs_data_size = query[5] & MASK_2BIT; + abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0)); + fhandler->size_of_data_register_block = abs_data_blk_size; + fhandler->data = NULL; + fhandler->extra = NULL; + + return retval; +} + +static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data, + unsigned short ctrl28) +{ + int retval; + static unsigned short ctrl_28_address; + + if (ctrl28) + ctrl_28_address = ctrl28; + + retval = synaptics_rmi4_i2c_write(rmi4_data, + ctrl_28_address, + &rmi4_data->report_enable, + sizeof(rmi4_data->report_enable)); + if (retval < 0) + return retval; + + return retval; +} + +/** + * synaptics_rmi4_f12_init() + * + * Called by synaptics_rmi4_query_device(). + * + * This funtion parses information from the Function 12 registers and + * determines the number of fingers supported, offset to the data1 + * register, x and y data ranges, offset to the associated interrupt + * status register, interrupt bit mask, and allocates memory resources + * for finger data acquisition. + */ +static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler, + struct synaptics_rmi4_fn_desc *fd, + unsigned int intr_count) +{ + int retval; + unsigned char ii; + unsigned char intr_offset; + unsigned char size_of_2d_data; + unsigned char size_of_query8; + unsigned char ctrl_8_offset; + unsigned char ctrl_23_offset; + unsigned char ctrl_28_offset; + unsigned char num_of_fingers; + struct synaptics_rmi4_f12_extra_data *extra_data; + struct synaptics_rmi4_f12_query_5 query_5; + struct synaptics_rmi4_f12_query_8 query_8; + struct synaptics_rmi4_f12_ctrl_8 ctrl_8; + struct synaptics_rmi4_f12_ctrl_23 ctrl_23; + + fhandler->fn_number = fd->fn_number; + fhandler->num_of_data_sources = fd->intr_src_count; + fhandler->extra = kmalloc(sizeof(*extra_data), GFP_KERNEL); + extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; + size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.query_base + 5, + query_5.data, + sizeof(query_5.data)); + if (retval < 0) + return retval; + + ctrl_8_offset = query_5.ctrl0_is_present + + query_5.ctrl1_is_present + + query_5.ctrl2_is_present + + query_5.ctrl3_is_present + + query_5.ctrl4_is_present + + query_5.ctrl5_is_present + + query_5.ctrl6_is_present + + query_5.ctrl7_is_present; + + ctrl_23_offset = ctrl_8_offset + + query_5.ctrl8_is_present + + query_5.ctrl9_is_present + + query_5.ctrl10_is_present + + query_5.ctrl11_is_present + + query_5.ctrl12_is_present + + query_5.ctrl13_is_present + + query_5.ctrl14_is_present + + query_5.ctrl15_is_present + + query_5.ctrl16_is_present + + query_5.ctrl17_is_present + + query_5.ctrl18_is_present + + query_5.ctrl19_is_present + + query_5.ctrl20_is_present + + query_5.ctrl21_is_present + + query_5.ctrl22_is_present; + + ctrl_28_offset = ctrl_23_offset + + query_5.ctrl23_is_present + + query_5.ctrl24_is_present + + query_5.ctrl25_is_present + + query_5.ctrl26_is_present + + query_5.ctrl27_is_present; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.ctrl_base + ctrl_23_offset, + ctrl_23.data, + sizeof(ctrl_23.data)); + if (retval < 0) + return retval; + + /* Maximum number of fingers supported */ + fhandler->num_of_data_points = min(ctrl_23.max_reported_objects, + (unsigned char)F12_FINGERS_TO_SUPPORT); + + num_of_fingers = fhandler->num_of_data_points; + rmi4_data->num_of_fingers = num_of_fingers; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.query_base + 7, + &size_of_query8, + sizeof(size_of_query8)); + if (retval < 0) + return retval; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.query_base + 8, + query_8.data, + size_of_query8); + if (retval < 0) + return retval; + + /* Determine the presence of the Data0 register */ + extra_data->data1_offset = query_8.data0_is_present; + + if ((size_of_query8 >= 3) && (query_8.data15_is_present)) { + extra_data->data15_offset = query_8.data0_is_present + + query_8.data1_is_present + + query_8.data2_is_present + + query_8.data3_is_present + + query_8.data4_is_present + + query_8.data5_is_present + + query_8.data6_is_present + + query_8.data7_is_present + + query_8.data8_is_present + + query_8.data9_is_present + + query_8.data10_is_present + + query_8.data11_is_present + + query_8.data12_is_present + + query_8.data13_is_present + + query_8.data14_is_present; + extra_data->data15_size = (num_of_fingers + 7) / 8; + } else { + extra_data->data15_size = 0; + } + + rmi4_data->report_enable = RPT_DEFAULT; +#ifdef REPORT_2D_Z + rmi4_data->report_enable |= RPT_Z; +#endif +#ifdef REPORT_2D_W + rmi4_data->report_enable |= (RPT_WX | RPT_WY); +#endif + + retval = synaptics_rmi4_f12_set_enables(rmi4_data, + fhandler->full_addr.ctrl_base + ctrl_28_offset); + if (retval < 0) + return retval; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.ctrl_base + ctrl_8_offset, + ctrl_8.data, + sizeof(ctrl_8.data)); + if (retval < 0) + return retval; + + /* Maximum x and y */ + rmi4_data->sensor_max_x = + ((unsigned short)ctrl_8.max_x_coord_lsb << 0) | + ((unsigned short)ctrl_8.max_x_coord_msb << 8); + rmi4_data->sensor_max_y = + ((unsigned short)ctrl_8.max_y_coord_lsb << 0) | + ((unsigned short)ctrl_8.max_y_coord_msb << 8); + dev_dbg(&rmi4_data->i2c_client->dev, + "%s: Function %02x max x = %d max y = %d\n", + __func__, fhandler->fn_number, + rmi4_data->sensor_max_x, + rmi4_data->sensor_max_y); + + rmi4_data->num_of_rx = ctrl_8.num_of_rx; + rmi4_data->num_of_tx = ctrl_8.num_of_tx; + rmi4_data->max_touch_width = max(rmi4_data->num_of_rx, + rmi4_data->num_of_tx); + + fhandler->intr_reg_num = (intr_count + 7) / 8; + if (fhandler->intr_reg_num != 0) + fhandler->intr_reg_num -= 1; + + /* Set an enable bit for each data source */ + intr_offset = intr_count % 8; + fhandler->intr_mask = 0; + for (ii = intr_offset; + ii < ((fd->intr_src_count & MASK_3BIT) + + intr_offset); + ii++) + fhandler->intr_mask |= 1 << ii; + + /* Allocate memory for finger data storage space */ + fhandler->data_size = num_of_fingers * size_of_2d_data; + fhandler->data = kmalloc(fhandler->data_size, GFP_KERNEL); + + return retval; +} + +static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + int retval; + struct synaptics_rmi4_f1a_handle *f1a; + + f1a = kzalloc(sizeof(*f1a), GFP_KERNEL); + if (!f1a) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for function handle\n", + __func__); + return -ENOMEM; + } + + fhandler->data = (void *)f1a; + fhandler->extra = NULL; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.query_base, + f1a->button_query.data, + sizeof(f1a->button_query.data)); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to read query registers\n", + __func__); + return retval; + } + + f1a->max_count = f1a->button_query.max_button_count + 1; + + f1a->button_control.txrx_map = kzalloc(f1a->max_count * 2, GFP_KERNEL); + if (!f1a->button_control.txrx_map) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for tx rx mapping\n", + __func__); + return -ENOMEM; + } + + f1a->button_bitmask_size = (f1a->max_count + 7) / 8; + + f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size, + sizeof(*(f1a->button_data_buffer)), GFP_KERNEL); + if (!f1a->button_data_buffer) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for data buffer\n", + __func__); + return -ENOMEM; + } + + f1a->button_map = kcalloc(f1a->max_count, + sizeof(*(f1a->button_map)), GFP_KERNEL); + if (!f1a->button_map) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for button map\n", + __func__); + return -ENOMEM; + } + + return 0; +} + +static int synaptics_rmi4_f1a_button_map(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler) +{ + int retval; + unsigned char ii; + unsigned char mapping_offset = 0; + struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; + const struct synaptics_dsx_platform_data *pdata = rmi4_data->board; + + mapping_offset = f1a->button_query.has_general_control + + f1a->button_query.has_interrupt_enable + + f1a->button_query.has_multibutton_select; + + if (f1a->button_query.has_tx_rx_map) { + retval = synaptics_rmi4_i2c_read(rmi4_data, + fhandler->full_addr.ctrl_base + mapping_offset, + f1a->button_control.txrx_map, + sizeof(f1a->button_control.txrx_map)); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to read tx rx mapping\n", + __func__); + return retval; + } + + rmi4_data->button_txrx_mapping = f1a->button_control.txrx_map; + } + + if (!pdata->cap_button_map) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: cap_button_map is NULL in board file\n", + __func__); + return -ENODEV; + } else if (!pdata->cap_button_map->map) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Button map is missing in board file\n", + __func__); + return -ENODEV; + } else { + if (pdata->cap_button_map->nbuttons != f1a->max_count) { + f1a->valid_button_count = min(f1a->max_count, + pdata->cap_button_map->nbuttons); + } else { + f1a->valid_button_count = f1a->max_count; + } + + for (ii = 0; ii < f1a->valid_button_count; ii++) + f1a->button_map[ii] = pdata->cap_button_map->map[ii]; + } + + return 0; +} + +static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler) +{ + struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; + + if (f1a) { + kfree(f1a->button_control.txrx_map); + kfree(f1a->button_data_buffer); + kfree(f1a->button_map); + kfree(f1a); + fhandler->data = NULL; + } + + return; +} + +static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data, + struct synaptics_rmi4_fn *fhandler, + struct synaptics_rmi4_fn_desc *fd, + unsigned int intr_count) +{ + int retval; + unsigned char ii; + unsigned short intr_offset; + + fhandler->fn_number = fd->fn_number; + fhandler->num_of_data_sources = fd->intr_src_count; + + fhandler->intr_reg_num = (intr_count + 7) / 8; + if (fhandler->intr_reg_num != 0) + fhandler->intr_reg_num -= 1; + + /* Set an enable bit for each data source */ + intr_offset = intr_count % 8; + fhandler->intr_mask = 0; + for (ii = intr_offset; + ii < ((fd->intr_src_count & MASK_3BIT) + + intr_offset); + ii++) + fhandler->intr_mask |= 1 << ii; + + retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler); + if (retval < 0) + goto error_exit; + + retval = synaptics_rmi4_f1a_button_map(rmi4_data, fhandler); + if (retval < 0) + goto error_exit; + + rmi4_data->button_0d_enabled = 1; + + return 0; + +error_exit: + synaptics_rmi4_f1a_kfree(fhandler); + + return retval; +} + +static void synaptics_rmi4_empty_fn_list(struct synaptics_rmi4_data *rmi4_data) +{ + struct synaptics_rmi4_fn *fhandler; + struct synaptics_rmi4_fn *fhandler_temp; + struct synaptics_rmi4_device_info *rmi; + + rmi = &(rmi4_data->rmi4_mod_info); + + if (!list_empty(&rmi->support_fn_list)) { + list_for_each_entry_safe(fhandler,fhandler_temp,&rmi->support_fn_list,link) + { + if(fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) { + synaptics_rmi4_f1a_kfree(fhandler); + } else { + kfree(fhandler->extra); + kfree(fhandler->data); + } + list_del(&fhandler->link); + kfree(fhandler); + } + } + INIT_LIST_HEAD(&rmi->support_fn_list); + + return; +} + +static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data, + bool *was_in_bl_mode) +{ + int retval; + int timeout = CHECK_STATUS_TIMEOUT_MS; + unsigned char command = 0x01; + unsigned char intr_status; + struct synaptics_rmi4_f01_device_status status; + + /* Do a device reset first */ + retval = synaptics_rmi4_i2c_write(rmi4_data, + rmi4_data->f01_cmd_base_addr, + &command, + sizeof(command)); + if (retval < 0) + return retval; + + msleep(rmi4_data->board->reset_delay_ms); + + retval = synaptics_rmi4_i2c_read(rmi4_data, + rmi4_data->f01_data_base_addr, + status.data, + sizeof(status.data)); + if (retval < 0) + return retval; + + while (status.status_code == STATUS_CRC_IN_PROGRESS) { + if (timeout > 0) + msleep(20); + else + return -1; + + retval = synaptics_rmi4_i2c_read(rmi4_data, + rmi4_data->f01_data_base_addr, + status.data, + sizeof(status.data)); + if (retval < 0) + return retval; + + timeout -= 20; + } + + if (timeout != CHECK_STATUS_TIMEOUT_MS) + *was_in_bl_mode = true; + + if (status.flash_prog == 1) { + rmi4_data->flash_prog_mode = true; + pr_notice("%s: In flash prog mode, status = 0x%02x\n", + __func__, + status.status_code); + } else { + rmi4_data->flash_prog_mode = false; + } + + retval = synaptics_rmi4_i2c_read(rmi4_data, + rmi4_data->f01_data_base_addr + 1, + &intr_status, + sizeof(intr_status)); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to read interrupt status\n", + __func__); + return retval; + } + + return 0; +} + +static void synaptics_rmi4_set_configured(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char device_ctrl; + + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to set configured\n", __func__); + return; + } + + rmi4_data->no_sleep_setting = device_ctrl & NO_SLEEP_ON; + device_ctrl |= CONFIGURED; + + retval = synaptics_rmi4_i2c_write(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to set configured\n", __func__); + } + + return; +} + +static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler, + struct synaptics_rmi4_fn_desc *rmi_fd, int page_number) +{ + *fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL); + if (!(*fhandler)) + return -ENOMEM; + + (*fhandler)->full_addr.data_base = (rmi_fd->data_base_addr | (page_number << 8)); + (*fhandler)->full_addr.ctrl_base = (rmi_fd->ctrl_base_addr | (page_number << 8)); + (*fhandler)->full_addr.cmd_base = (rmi_fd->cmd_base_addr | (page_number << 8)); + (*fhandler)->full_addr.query_base = (rmi_fd->query_base_addr | (page_number << 8)); + + return 0; +} + +/** + * synaptics_rmi4_query_device() + * + * Called by synaptics_rmi4_probe(). + * + * This funtion scans the page description table, records the offsets + * to the register types of Function $01, sets up the function handlers + * for Function $11 and Function $12, determines the number of interrupt + * sources from the sensor, adds valid Functions with data inputs to the + * Function linked list, parses information from the query registers of + * Function $01, and enables the interrupt sources from the valid Functions + * with data inputs. + */ +static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char ii; + unsigned char page_number; + unsigned char intr_count; + unsigned char f01_query[F01_STD_QUERY_LEN]; + unsigned short pdt_entry_addr; + unsigned short intr_addr; + bool was_in_bl_mode; + struct synaptics_rmi4_fn_desc rmi_fd; + struct synaptics_rmi4_fn *fhandler; + struct synaptics_rmi4_device_info *rmi; + + rmi = &(rmi4_data->rmi4_mod_info); + +rescan_pdt: + was_in_bl_mode = false; + intr_count = 0; + INIT_LIST_HEAD(&rmi->support_fn_list); + + /* Scan the page description tables of the pages to service */ + for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) { + for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END; pdt_entry_addr -= PDT_ENTRY_SIZE) { + pdt_entry_addr |= (page_number << 8); + + retval = synaptics_rmi4_i2c_read(rmi4_data, pdt_entry_addr, (unsigned char *)&rmi_fd, sizeof(rmi_fd)); + if (retval < 0) + return retval; + + fhandler = NULL; + + if (rmi_fd.fn_number == 0) { + dev_dbg(&rmi4_data->i2c_client->dev, "%s: Reached end of PDT\n", __func__); + break; + } + + print_ts(TS_DEBUG, "%s: F%02x found (page %d)\n", __func__, rmi_fd.fn_number, page_number); + + switch (rmi_fd.fn_number) { + case SYNAPTICS_RMI4_F01: + rmi4_data->f01_query_base_addr = rmi_fd.query_base_addr; + rmi4_data->f01_ctrl_base_addr = rmi_fd.ctrl_base_addr; + rmi4_data->f01_data_base_addr = rmi_fd.data_base_addr; + rmi4_data->f01_cmd_base_addr = rmi_fd.cmd_base_addr; + + print_ts(TS_DEBUG, "Tp f01_query_base_addr = 0x%x!\n", rmi4_data->f01_query_base_addr); // N3 : 0x27 + print_ts(TS_DEBUG, "Tp f01_ctrl_base_addr = 0x%x!\n", rmi4_data->f01_ctrl_base_addr); // N3 : 0x0e + print_ts(TS_DEBUG, "Tp f01_data_base_addr = 0x%x!\n", rmi4_data->f01_data_base_addr); // N3 : 0x04 + print_ts(TS_DEBUG, "Tp f01_cmd_base_addr = 0x%x!\n", rmi4_data->f01_cmd_base_addr); // N3 : 0x22 + + retval = synaptics_rmi4_check_status(rmi4_data, &was_in_bl_mode); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to check status\n", __func__); + return retval; + } + + if (was_in_bl_mode) + goto rescan_pdt; + + if (rmi4_data->flash_prog_mode) + goto flash_prog_mode; + + break; + case SYNAPTICS_RMI4_F11: + if (rmi_fd.intr_src_count == 0) + break; + + retval = synaptics_rmi4_alloc_fh(&fhandler, &rmi_fd, page_number); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to alloc for F%d\n", __func__, rmi_fd.fn_number); + return retval; + } + + retval = synaptics_rmi4_f11_init(rmi4_data, fhandler, &rmi_fd, intr_count); + if (retval < 0) + return retval; + break; + case SYNAPTICS_RMI4_F12: + if (rmi_fd.intr_src_count == 0) + break; + + retval = synaptics_rmi4_alloc_fh(&fhandler, &rmi_fd, page_number); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to alloc for F%d\n", __func__, rmi_fd.fn_number); + return retval; + } + + retval = synaptics_rmi4_f12_init(rmi4_data, fhandler, &rmi_fd, intr_count); + if (retval < 0) + return retval; + break; + case SYNAPTICS_RMI4_F1A: + if (rmi_fd.intr_src_count == 0) + break; + + retval = synaptics_rmi4_alloc_fh(&fhandler, &rmi_fd, page_number); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to alloc for F%d\n", __func__, rmi_fd.fn_number); + return retval; + } + + retval = synaptics_rmi4_f1a_init(rmi4_data, fhandler, &rmi_fd, intr_count); + if (retval < 0) { + return retval; + } + break; + case SYNAPTICS_RMI4_F54: + rmi4_data->f54_data_base_addr = (rmi_fd.data_base_addr |(page_number << 8)); + rmi4_data->f54_ctrl_base_addr = (rmi_fd.ctrl_base_addr |(page_number << 8)); + rmi4_data->f54_cmd_base_addr = (rmi_fd.cmd_base_addr |(page_number << 8)); + rmi4_data->f54_query_base_addr = (rmi_fd.query_base_addr |(page_number << 8)); + + print_ts(TS_DEBUG, "Tp f54_query_base_addr = 0x%x!\n", rmi4_data->f54_query_base_addr); // N3 : 0x149 + print_ts(TS_DEBUG, "Tp f54_ctrl_base_addr = 0x%x!\n", rmi4_data->f54_ctrl_base_addr); // N3 : 0x10e + print_ts(TS_DEBUG, "Tp f54_data_base_addr = 0x%x!\n", rmi4_data->f54_data_base_addr); // N3 : 0x100 + print_ts(TS_DEBUG, "Tp f54_cmd_base_addr = 0x%x!\n", rmi4_data->f54_cmd_base_addr); // N3 : 0x148 + + break ; + } + + /* Accumulate the interrupt count */ + intr_count += (rmi_fd.intr_src_count & MASK_3BIT); + + if (fhandler && rmi_fd.intr_src_count) { + list_add_tail(&fhandler->link, &rmi->support_fn_list); + } + } + } + +flash_prog_mode: + rmi4_data->num_of_intr_regs = (intr_count + 7) / 8; + dev_dbg(&rmi4_data->i2c_client->dev, "%s: Number of interrupt registers = %d\n", __func__, rmi4_data->num_of_intr_regs); + + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_query_base_addr, f01_query, sizeof(f01_query)); + if (retval < 0) + return retval; + + /* RMI Version 4.0 currently supported */ + rmi->version_major = 4; + rmi->version_minor = 0; + + rmi->manufacturer_id = f01_query[0]; + rmi->product_props = f01_query[1]; + rmi->product_info[0] = f01_query[2] & MASK_7BIT; + rmi->product_info[1] = f01_query[3] & MASK_7BIT; + rmi->date_code[0] = f01_query[4] & MASK_5BIT; + rmi->date_code[1] = f01_query[5] & MASK_4BIT; + rmi->date_code[2] = f01_query[6] & MASK_5BIT; + rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) | (f01_query[8] & MASK_7BIT); + rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) | (f01_query[10] & MASK_7BIT); + memcpy(rmi->product_id_string, &f01_query[11], 10); + + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET, rmi->build_id, sizeof(rmi->build_id)); + if (retval < 0) + return retval; + + rmi4_data->firmware_id = (unsigned int)rmi->build_id[0] + (unsigned int)rmi->build_id[1] * 0x100 + (unsigned int)rmi->build_id[2] * 0x10000; + + memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask)); + + /* + * Map out the interrupt bit masks for the interrupt sources + * from the registered function handlers. + */ + if (!list_empty(&rmi->support_fn_list)) { + list_for_each_entry(fhandler, &rmi->support_fn_list, link) { + if(fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (fhandler->num_of_data_sources) { + rmi4_data->intr_mask[fhandler->intr_reg_num] |= fhandler->intr_mask; + } + } + } + + /* Enable the interrupt sources */ + for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { + if (rmi4_data->intr_mask[ii] != 0x00) { + dev_dbg(&rmi4_data->i2c_client->dev, "%s: Interrupt enable mask %d = 0x%02x\n", __func__, ii, rmi4_data->intr_mask[ii]); + intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii; + retval = synaptics_rmi4_i2c_write(rmi4_data, intr_addr, &(rmi4_data->intr_mask[ii]), sizeof(rmi4_data->intr_mask[ii])); + if (retval < 0) + return retval; + } + } + + synaptics_rmi4_set_configured(rmi4_data); + + return 0; +} + +static void synaptics_rmi4_set_params(struct synaptics_rmi4_data *rmi4_data) +{ + unsigned char ii; + struct synaptics_rmi4_f1a_handle *f1a; + struct synaptics_rmi4_fn *fhandler; + struct synaptics_rmi4_device_info *rmi; + + rmi = &(rmi4_data->rmi4_mod_info); + + set_bit(KEY_BACK, rmi4_data->input_dev->keybit); + set_bit(KEY_MENU, rmi4_data->input_dev->keybit); + set_bit(KEY_HOMEPAGE, rmi4_data->input_dev->keybit); + set_bit(KEY_F3, rmi4_data->input_dev->keybit); + set_bit(KEY_F4, rmi4_data->input_dev->keybit); + set_bit(KEY_F5, rmi4_data->input_dev->keybit); + set_bit(KEY_F6, rmi4_data->input_dev->keybit); + set_bit(KEY_F7, rmi4_data->input_dev->keybit); + set_bit(KEY_F8, rmi4_data->input_dev->keybit); + set_bit(KEY_POWER, rmi4_data->input_dev->keybit); + + input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_X, rmi4_data->snap_left, rmi4_data->sensor_max_x-rmi4_data->snap_right, 0, 0); + input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_Y, rmi4_data->snap_top, rmi4_data->sensor_max_y-rmi4_data->virtual_key_height-rmi4_data->snap_bottom, 0, 0); + print_ts(TS_DEBUG, KERN_ERR"%s x:%d y:%d \n", __func__, rmi4_data->sensor_max_x-rmi4_data->snap_right, rmi4_data->sensor_max_y-rmi4_data->virtual_key_height-rmi4_data->snap_bottom); +#ifdef REPORT_2D_W + input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, rmi4_data->max_touch_width, 0, 0); + input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MINOR, 0, rmi4_data->max_touch_width, 0, 0); +#endif + +#ifdef TYPE_B_PROTOCOL + input_mt_init_slots(rmi4_data->input_dev, rmi4_data->num_of_fingers, 0); +#endif + + f1a = NULL; + if (!list_empty(&rmi->support_fn_list)) { + list_for_each_entry(fhandler, &rmi->support_fn_list, link) { + if(fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) + f1a = fhandler->data; + } + } + + if (f1a) { + for (ii = 0; ii < f1a->valid_button_count; ii++) { + set_bit(f1a->button_map[ii], rmi4_data->input_dev->keybit); + input_set_capability(rmi4_data->input_dev, EV_KEY, f1a->button_map[ii]); + } + } + + return; +} + +static int synaptics_rmi4_set_input_dev(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + int temp; + + rmi4_data->input_dev = input_allocate_device(); + if (rmi4_data->input_dev == NULL) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to allocate input device\n", __func__); + retval = -ENOMEM; + goto err_input_device; + } + + rmi4_data->input_dev->name = DRIVER_NAME; + rmi4_data->input_dev->phys = INPUT_PHYS_NAME; + rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; + rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; + rmi4_data->input_dev->id.bustype = BUS_I2C; + rmi4_data->input_dev->dev.parent = &rmi4_data->i2c_client->dev; + input_set_drvdata(rmi4_data->input_dev, rmi4_data); + + set_bit(EV_SYN, rmi4_data->input_dev->evbit); + set_bit(EV_KEY, rmi4_data->input_dev->evbit); + set_bit(EV_ABS, rmi4_data->input_dev->evbit); + set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit); + set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit); +#ifdef INPUT_PROP_DIRECT + set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit); +#endif + + retval = synaptics_rmi4_query_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to query device\n", __func__); + goto err_query_device; + } + /* oem lifeng 2015.3.9 bootloader mode update fw then err report point begin*/ + if(true == rmi4_data->flash_prog_mode){ + rmi4_data->max_touch_width = 30; + rmi4_data->num_of_fingers = 10; + } + /* oem lifeng 2015.3.9 bootloader mode update fw then err report point end*/ + if (rmi4_data->board->swap_axes) { + temp = rmi4_data->sensor_max_x; + rmi4_data->sensor_max_x = rmi4_data->sensor_max_y; + rmi4_data->sensor_max_y = temp; + } + + synaptics_rmi4_set_params(rmi4_data); + + retval = input_register_device(rmi4_data->input_dev); + if (retval) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to register input device\n", __func__); + goto err_register_input; + } + + return 0; + +err_register_input: +err_query_device: + synaptics_rmi4_empty_fn_list(rmi4_data); + input_free_device(rmi4_data->input_dev); + +err_input_device: + return retval; +} + +static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data) +{ + unsigned char ii; + +#ifdef TYPE_B_PROTOCOL + for (ii = 0; ii < rmi4_data->num_of_fingers; ii++) { + input_mt_slot(rmi4_data->input_dev, ii); + input_mt_report_slot_state(rmi4_data->input_dev,MT_TOOL_FINGER, 0); + } +#endif + input_report_key(rmi4_data->input_dev,BTN_TOUCH, 0); + input_report_key(rmi4_data->input_dev,BTN_TOOL_FINGER, 0); +#ifndef TYPE_B_PROTOCOL + input_mt_sync(rmi4_data->input_dev); +#endif + input_sync(rmi4_data->input_dev); + + rmi4_data->fingers_on_2d = false; + + return 0; +} + +static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char tmp_new ; + struct synaptics_rmi4_device_info *rmi; + + rmi = &(rmi4_data->rmi4_mod_info); + + mutex_lock(&(rmi4_data->rmi4_reset_mutex)); + + synaptics_rmi4_free_fingers(rmi4_data); + + synaptics_rmi4_set_configured(rmi4_data); + + if(syna_use_gesture && rmi4_data->gesture) { + synaptics_set_f12ctrl_data(rmi4_data,rmi4_data->gesture,0); + } + + tmp_new = 4 ; + retval = synaptics_rmi4_i2c_write(rmi4_data,F54_CMD_BASE_ADDR,(unsigned char*)&tmp_new,1); + + mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); + return retval; +} + +static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data, unsigned short f01_cmd_base_addr) +{ + int retval; + int temp; + int rc; + + rmi4_data->reset_count ++ ; + if(rmi4_data->reset_count >= 2) + return 0 ; + + mutex_lock(&(rmi4_data->rmi4_reset_mutex)); + + rmi4_data->touch_stopped = true; + synaptics_rmi4_irq_enable(rmi4_data, false) ; + //power off device + regulator_disable(rmi4_data->regulator); + msleep(30); + rmi4_data->current_page = MASK_8BIT; + rmi4_data->touch_stopped = false; + //synaptics_rmi4_irq_enable(rmi4_data, false) ; + + synaptics_rmi4_free_fingers(rmi4_data); + + synaptics_rmi4_empty_fn_list(rmi4_data); + + //power on device + rc = regulator_enable(rmi4_data->regulator); + msleep(180); + + retval = synaptics_rmi4_query_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to query device\n", __func__); + mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); + rmi4_data->touch_stopped = false; + + return retval; + } + + if (rmi4_data->board->swap_axes) { + temp = rmi4_data->sensor_max_x; + rmi4_data->sensor_max_x = rmi4_data->sensor_max_y; + rmi4_data->sensor_max_y = temp; + } + + synaptics_rmi4_set_params(rmi4_data); + + mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); + + //reinit device + msleep(10); + synaptics_rmi4_irq_enable(rmi4_data, true) ; + synaptics_rmi4_i2c_read(rmi4_data,rmi4_data->f01_data_base_addr + 1,(unsigned char*)&temp,1); + + return retval; +} + +/** + * synaptics_rmi4_exp_fn_work() + * + * Called by the kernel at the scheduled time. + * + * This function is a work thread that checks for the insertion and + * removal of other expansion Function modules such as rmi_dev and calls + * their initialization and removal callback functions accordingly. + */ +static void synaptics_rmi4_exp_fn_work(struct work_struct *work) +{ + struct synaptics_rmi4_exp_fn *exp_fhandler; + struct synaptics_rmi4_exp_fn *exp_fhandler_temp; + struct synaptics_rmi4_data *rmi4_data = exp_data.rmi4_data; + + mutex_lock(&exp_data.mutex); + if (!list_empty(&exp_data.list)) { + list_for_each_entry_safe(exp_fhandler,exp_fhandler_temp,&exp_data.list, link) + { + if(exp_fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if ((exp_fhandler->func_init != NULL) && (exp_fhandler->inserted == false)) + { + if(exp_fhandler->func_init(rmi4_data) < 0) + { + //retry init + queue_delayed_work(exp_data.workqueue, &exp_data.work, msecs_to_jiffies(500)); + mutex_unlock(&exp_data.mutex); + return ; + } + exp_fhandler->inserted = true; + } + else if ((exp_fhandler->func_init == NULL) && (exp_fhandler->inserted == true)) + { + exp_fhandler->func_remove(rmi4_data); + list_del(&exp_fhandler->link); + kfree(exp_fhandler); + } + } + } + mutex_unlock(&exp_data.mutex); + + return; +} + +/** + * synaptics_rmi4_new_function() + * + * Called by other expansion Function modules in their module init and + * module exit functions. + * + * This function is used by other expansion Function modules such as + * rmi_dev to register themselves with the driver by providing their + * initialization and removal callback function pointers so that they + * can be inserted or removed dynamically at module init and exit times, + * respectively. + */ +void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, + int (*func_init)(struct synaptics_rmi4_data *rmi4_data), + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask)) +{ + struct synaptics_rmi4_exp_fn *exp_fhandler; + + if (!exp_data.initialized) { + mutex_init(&exp_data.mutex); + INIT_LIST_HEAD(&exp_data.list); + exp_data.initialized = true; + } + + mutex_lock(&exp_data.mutex); + if (insert) { + exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL); + if (!exp_fhandler) { + pr_err("%s: Failed to alloc mem for expansion function\n", __func__); + goto exit; + } + exp_fhandler->fn_type = fn_type; + exp_fhandler->func_init = func_init; + exp_fhandler->func_attn = func_attn; + exp_fhandler->func_remove = func_remove; + exp_fhandler->inserted = false; + list_add_tail(&exp_fhandler->link, &exp_data.list); + } + else if (!list_empty(&exp_data.list)) + { + list_for_each_entry(exp_fhandler, &exp_data.list, link) + { + if(exp_fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (exp_fhandler->fn_type == fn_type) { + exp_fhandler->func_init = NULL; + exp_fhandler->func_attn = NULL; + goto exit; + } + } + } + +exit: + mutex_unlock(&exp_data.mutex); + + if (exp_data.queue_work) { + queue_delayed_work(exp_data.workqueue, &exp_data.work, msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); + } + + return; +} +EXPORT_SYMBOL(synaptics_rmi4_new_function); + +int synaptics_rmi4_get_vendorid1(int id1, int id2, int id3) { + if(id1 == 0 && id2 == 0 && id3 == 0) + return TP_VENDOR_TPK ; + else if(id1 == 0 && id2 == 1 && id3 == 0) + return TP_VENDOR_WINTEK ; + + return 0 ; +} + +int synaptics_rmi4_get_vendorid2(int id1, int id2, int id3) { + if(id1 == 0 && id2 == 0 && id3 == 0) + return TP_VENDOR_YOUNGFAST ; + else if(id1 == 0 && id2 == 1 && id3 == 0) + return TP_VENDOR_TRULY ; + else if(id1 == 1 && id2 == 0 && id3 == 0) + return TP_VENDOR_TPK ; + else if(id1 == 1 && id2 == 1 && id3 == 0) + return TP_VENDOR_WINTEK ; + + return 0 ; +} + +int synaptics_rmi4_get_vendorid3(int id1, int id2, int id3) { + if(id1 == 0 && id2 == 0 ) + return TP_VENDOR_TPK ; + else if(id1 == 1 && id2 == 0 ) + return TP_VENDOR_WINTEK ; + else if(id1 == 0 && id2 == 1 ) + return TP_VENDOR_TRULY ; + else if(id1 == 1 && id2 == 1 ) + return TP_VENDOR_TPK_GFF ; + + return 0 ; +} + +//return firmware version and string +extern int synaptics_rmi4_get_firmware_version(int vendor_id); +char* synaptics_rmi4_get_vendorstring(int id) { + char *pconst = "UNKNOWN"; + + switch(id) { + case TP_VENDOR_WINTEK: + pconst= "WINTEK" ; + break ; + case TP_VENDOR_TPK: + pconst= "TPK" ; + break ; + case TP_VENDOR_TRULY: + pconst= "TRULY" ; + break ; + case TP_VENDOR_YOUNGFAST: + pconst= "YOUNGFAST" ; + break ; + case TP_VENDOR_TPK_GFF: + pconst= "TPK_GFF" ; + break ; + case TP_VENDOR_JDI: + pconst= "JDI" ; + break ; + } + + print_ts(TS_INFO, "%s, pconst = %s, version = 0x%x\n", __func__, pconst, synaptics_rmi4_get_firmware_version(id)); + + sprintf(synaptics_vendor_str,"%s(%x)",pconst,synaptics_rmi4_get_firmware_version(id)); + + return synaptics_vendor_str; + +} + +static void synaptics_rmi4_get_vendorid(struct synaptics_rmi4_data *rmi4_data) +{ + rmi4_data->vendor_id = TP_VENDOR_JDI; + synaptics_rmi4_get_vendorstring(rmi4_data->vendor_id); + print_ts(TS_INFO, KERN_ERR "[syna] vendor id: %x\n", rmi4_data->vendor_id); +} + +#ifdef CONFIG_FB +static int fb_notifier_callback(struct notifier_block *p, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int new_status ; + + mutex_lock(&syna_rmi4_data->ops_lock); + + switch (event) { + case FB_EVENT_BLANK : + new_status = (*(int *)evdata->data) ? BLANK : UNBLANK; + if (new_status == syna_rmi4_data->old_status) + break; + + if(new_status != UNBLANK) { + print_ts(TS_DEBUG, KERN_ERR "[syna]:suspend tp\n"); + synaptics_rmi4_suspend(&(syna_rmi4_data->input_dev->dev)); + } + else { + print_ts(TS_DEBUG, KERN_ERR "[syna]:resume tp\n"); + synaptics_rmi4_resume(&(syna_rmi4_data->input_dev->dev)); + } + syna_rmi4_data->old_status = new_status; + break; + } + mutex_unlock(&syna_rmi4_data->ops_lock); + + return 0; +} +#endif + +/** + * synaptics_rmi4_probe() + * + * Called by the kernel when an association with an I2C device of the + * same name is made (after doing i2c_add_driver). + * + * This funtion allocates and initializes the resources for the driver + * as an input driver, turns on the power to the sensor, queries the + * sensor for its supported Functions and characteristics, registers + * the driver to the input subsystem, sets up the interrupt, handles + * the registration of the early_suspend and late_resume functions, + * and creates a work queue for detection of other expansion Function + * modules. + */ +static int synaptics_rmi4_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int retval = 0; + char product_info; + unsigned char attr_count; + struct synaptics_rmi4_data *rmi4_data; + const struct synaptics_dsx_platform_data *platform_data =&dsx_platformdata; + + printk("%s, start ....!\n", __func__); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "%s: SMBus byte data not supported\n", __func__); + return -EIO; + } + + if (!platform_data) { + dev_err(&client->dev, "%s: No platform data found\n", __func__); + return -EINVAL; + } + + rmi4_data = kzalloc(sizeof(*rmi4_data), GFP_KERNEL); + if (!rmi4_data) { + dev_err(&client->dev, "%s: Failed to alloc mem for rmi4_data\n", __func__); + return -ENOMEM; + } + + rmi4_data->i2c_client = client; + rmi4_data->current_page = MASK_8BIT; + rmi4_data->board = platform_data; + rmi4_data->touch_stopped = false; + rmi4_data->sensor_sleep = false; + rmi4_data->irq_enabled = false; + rmi4_data->fingers_on_2d = false; + + rmi4_data->i2c_read = synaptics_rmi4_i2c_read; + rmi4_data->i2c_write = synaptics_rmi4_i2c_write; + rmi4_data->irq_enable = synaptics_rmi4_irq_enable; + rmi4_data->reset_device = synaptics_rmi4_reset_device; + rmi4_data->product_info = 3320; + + retval = i2c_master_send(rmi4_data->i2c_client,&product_info,1); + if (retval < 0){ + printk("synap i2c test error!!! ret=%d\n",retval); + goto err_regulator; + } + + rmi4_data->virtual_key_height = 0; + rmi4_data->sensor_max_x = LCD_MAX_X; + rmi4_data->sensor_max_y = LCD_MAX_Y; + syna_lcd_ratio1 = 133 ; + syna_lcd_ratio2 = 100 ; + + mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex)); + mutex_init(&(rmi4_data->rmi4_reset_mutex)); + + syna_rmi4_data = rmi4_data; + client->dev.platform_data = &dsx_platformdata ; + retval = synaptics_parse_dt(&client->dev, rmi4_data); + if (retval) + { + printk(KERN_ERR "%s synaptics parse_dt error \n", __func__); + goto err_regulator; + } + + if(vdd_regulator) + { + printk("%s, config the regulator \n", __func__); + if(synaptics_regulator_configure(true)) + goto err_set_input_dev; + } + + rmi4_data->regulator = vdd_regulator ; + + dsx_platformdata.irq_gpio = rmi4_data->irq_gpio; + dsx_platformdata.reset_gpio = rmi4_data->reset_gpio ; + rmi4_data->irq = rmi4_data->i2c_client->irq ; + + rmi4_data->irq = gpio_to_irq(rmi4_data->irq_gpio); + if (rmi4_data->irq <= 0) + { + printk("%s, irq number is not specified, irq #= %d, int pin=%d\n\n", __func__, rmi4_data->irq, rmi4_data->irq_gpio); + } + + retval = gpio_request(rmi4_data->irq_gpio,"synap-s3320-int"); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_request_int, err=%d", __func__, retval); + goto err_set_input_dev; + } + + retval = gpio_direction_input(rmi4_data->irq_gpio); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_direction_input, err=%d", __func__, retval); + goto err_set_input_dev; + } + + retval = gpio_request(rmi4_data->reset_gpio,"synap-s3320-reset"); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_request_reset, err=%d", __func__, retval); + goto err_set_input_dev; + } + + retval = gpio_direction_output(rmi4_data->reset_gpio,1); + if(retval < 0) + { + printk(KERN_ERR "%s: reset gpio_direction_output, err=%d", __func__, retval); + goto err_set_input_dev; + } + + synaptics_rmi4_get_vendorid(rmi4_data); + + synaptics_ts_init_area(rmi4_data); + + i2c_set_clientdata(client, rmi4_data); + + retval = synaptics_rmi4_set_input_dev(rmi4_data); + if (retval < 0) { + dev_err(&client->dev, "%s: Failed to set up input device\n", __func__); + goto err_set_input_dev; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend; + rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume; + register_early_suspend(&rmi4_data->early_suspend); +#endif + +#ifdef CONFIG_FB //for tp suspend and resume + mutex_init(&rmi4_data->ops_lock); + + rmi4_data->fb_notif.notifier_call = fb_notifier_callback; + + retval = fb_register_client(&rmi4_data->fb_notif); + + if (retval) + goto err_enable_irq ; +#endif + + if(rmi4_data->rmi4_mod_info.product_id_string[0]) + synaptics_id_str = rmi4_data->rmi4_mod_info.product_id_string ; + else + synaptics_id_str = "UNKNOWN"; + push_component_info(TP, synaptics_id_str, synaptics_vendor_str); + + if (syna_use_gesture) + rmi4_data->gesture_enable = 0x7b; + synaptics_ts_init_virtual_key(rmi4_data); + synaptics_rmi4_init_touchpanel_proc(); + + //mingqiang.guo add for LCD show later when push power button and two click in gesture + rmi4_data->speedup_resume_wq = create_singlethread_workqueue("speedup_resume_wq"); + INIT_DELAYED_WORK(&rmi4_data->speed_up_work,speedup_synaptics_resume); + + wake_lock_init(&tp_wake_lock, WAKE_LOCK_SUSPEND, "tp_gesture"); + + if (!exp_data.initialized) { + mutex_init(&exp_data.mutex); + INIT_LIST_HEAD(&exp_data.list); + exp_data.initialized = true; + } + + exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue"); + INIT_DELAYED_WORK(&exp_data.work, synaptics_rmi4_exp_fn_work); + exp_data.rmi4_data = rmi4_data; + exp_data.queue_work = true; + queue_delayed_work(exp_data.workqueue, &exp_data.work, msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); + + rmi4_fw_module_init(true); + while(1) + { + msleep(50); + if(rmi4_data->bcontinue) + { + rmi4_fw_module_init(false); + rmi4_data->bremove = 1; + break ; + } + } + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, &attrs[attr_count].attr); + if (retval < 0) { + dev_err(&client->dev, "%s: Failed to create sysfs attributes\n", __func__); + goto err_sysfs; + } + } + + retval = synaptics_rmi4_irq_enable(rmi4_data, true); + if (retval < 0) { + dev_err(&client->dev, "%s: Failed to enable attention interrupt\n", __func__); + } + synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_ctrl_base_addr+1, &int_mask,1); + print_ts(TS_INFO, "%s: Interrupt enable mask = 0x%x\n", __func__, int_mask); + + printk("%s probe ok !!!! \n", __func__); + return retval; + +err_sysfs: + for (attr_count--; attr_count >= 0; attr_count--) { + sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, &attrs[attr_count].attr); + } + cancel_delayed_work_sync(&exp_data.work); + flush_workqueue(exp_data.workqueue); + destroy_workqueue(exp_data.workqueue); + synaptics_rmi4_irq_enable(rmi4_data, false); + +err_enable_irq: + if (platform_data->gpio_config && (platform_data->reset_gpio >= 0)) + platform_data->gpio_config(platform_data->reset_gpio, false); + + if (platform_data->gpio_config) + platform_data->gpio_config(platform_data->irq_gpio, false); + + synaptics_rmi4_empty_fn_list(rmi4_data); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&rmi4_data->early_suspend); +#endif + input_unregister_device(rmi4_data->input_dev); + rmi4_data->input_dev = NULL; + +err_set_input_dev: + if (platform_data->regulator_en) { + regulator_disable(rmi4_data->regulator); + regulator_put(rmi4_data->regulator); + } + +err_regulator: + kfree(rmi4_data); + + return retval; +} +#if 1 +struct synaptics_optimize_data{ + struct delayed_work work; + struct workqueue_struct *workqueue; + struct i2c_client *client; + const struct i2c_device_id *dev_id; +}; +static struct synaptics_optimize_data optimize_data_s3320; + +static void synaptics_s3320_work(struct work_struct *work) +{ + int retval; + struct i2c_client *client_optimize = optimize_data_s3320.client; + const struct i2c_device_id *dev_id = optimize_data_s3320.dev_id; + + retval = synaptics_rmi4_probe(client_optimize, dev_id); +} + + +static int synaptics_rmi4_probe_s3320(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int i, match; + + optimize_data_s3320.workqueue = create_workqueue("optimize_workqueue_s3320"); + INIT_DELAYED_WORK(&(optimize_data_s3320.work), synaptics_s3320_work); + optimize_data_s3320.client = client; + optimize_data_s3320.dev_id = dev_id; + printk("synaptics s3320 probe cpu %d\n", smp_processor_id()); + + for (i = 0; i <= 3; i++) + { + if (cpu_is_offline(i) || i == smp_processor_id()) + { + continue; + } + queue_delayed_work_on(i, optimize_data_s3320.workqueue, + &(optimize_data_s3320.work), + msecs_to_jiffies(10)); + match = 1; + printk("synap s3320 work on cpu %d\n",i); + break; + } + if (match == 0) + { + queue_delayed_work_on(0, optimize_data_s3320.workqueue, + &(optimize_data_s3320.work), + msecs_to_jiffies(10)); + } + return 0; +} +#endif + +/** + * synaptics_rmi4_remove() + * + * Called by the kernel when the association with an I2C device of the + * same name is broken (when the driver is unloaded). + * + * This funtion terminates the work queue, stops sensor data acquisition, + * frees the interrupt, unregisters the driver from the input subsystem, + * turns off the power to the sensor, and frees other allocated resources. + */ +static int synaptics_rmi4_remove(struct i2c_client *client) +{ + unsigned char attr_count; + struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client); + const struct synaptics_dsx_platform_data *platform_data = + rmi4_data->board; + + synaptics_rmi4_irq_enable(rmi4_data, false); + + if (platform_data->gpio_config) { + platform_data->gpio_config( + platform_data->irq_gpio, + false); + + if (platform_data->reset_gpio >= 0) { + platform_data->gpio_config( + platform_data->reset_gpio, + false); + } + } + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, + &attrs[attr_count].attr); + } + + cancel_delayed_work_sync(&exp_data.work); + flush_workqueue(exp_data.workqueue); + destroy_workqueue(exp_data.workqueue); + + synaptics_rmi4_empty_fn_list(rmi4_data); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&rmi4_data->early_suspend); +#endif + input_unregister_device(rmi4_data->input_dev); + + if (platform_data->regulator_en) { + regulator_disable(rmi4_data->regulator); + regulator_put(rmi4_data->regulator); + } + + kfree(rmi4_data); + + return 0; +} + +#ifdef CONFIG_PM +/** + * synaptics_rmi4_sensor_sleep() + * + * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend(). + * + * This function stops finger data acquisition and puts the sensor to sleep. + */ +static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char device_ctrl; + + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to enter sleep mode\n", __func__); + rmi4_data->sensor_sleep = false; + return; + } + + device_ctrl = (device_ctrl & ~MASK_3BIT); + device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP); + + retval = synaptics_rmi4_i2c_write(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to enter sleep mode\n", __func__); + rmi4_data->sensor_sleep = false; + return; + } + else + { + rmi4_data->sensor_sleep = true; + } + + return; +} + +/** + * synaptics_rmi4_sensor_wake() + * + * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume(). + * + * This function wakes the sensor from sleep. + */ +static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char device_ctrl; + unsigned char no_sleep_setting = rmi4_data->no_sleep_setting; + + retval = synaptics_rmi4_i2c_read(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to wake from sleep mode\n", __func__); + rmi4_data->sensor_sleep = true; + return; + } + + device_ctrl = (device_ctrl & ~MASK_3BIT); + device_ctrl = (device_ctrl | no_sleep_setting | NORMAL_OPERATION); + + retval = synaptics_rmi4_i2c_write(rmi4_data, rmi4_data->f01_ctrl_base_addr, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to wake from sleep mode\n", __func__); + rmi4_data->sensor_sleep = true; + return; + } + else + { + rmi4_data->sensor_sleep = false; + } + + return; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +/** + * synaptics_rmi4_early_suspend() + * + * Called by the kernel during the early suspend phase when the system + * enters suspend. + * + * This function calls synaptics_rmi4_sensor_sleep() to stop finger + * data acquisition and put the sensor to sleep. + */ +static void synaptics_rmi4_early_suspend(struct early_suspend *h) +{ + struct synaptics_rmi4_data *rmi4_data = + container_of(h, struct synaptics_rmi4_data, + early_suspend); + + if (rmi4_data->stay_awake) { + rmi4_data->staying_awake = true; + return; + } else { + rmi4_data->staying_awake = false; + } + + rmi4_data->touch_stopped = true; + synaptics_rmi4_irq_enable(rmi4_data, false); + synaptics_rmi4_sensor_sleep(rmi4_data); + synaptics_rmi4_free_fingers(rmi4_data); + + if (rmi4_data->full_pm_cycle) + synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); + + return; +} + +/** + * synaptics_rmi4_late_resume() + * + * Called by the kernel during the late resume phase when the system + * wakes up from suspend. + * + * This function goes through the sensor wake process if the system wakes + * up from early suspend (without going into suspend). + */ +static void synaptics_rmi4_late_resume(struct early_suspend *h) +{ + int retval; + struct synaptics_rmi4_data *rmi4_data = + container_of(h, struct synaptics_rmi4_data, + early_suspend); + + if (rmi4_data->staying_awake) + return; + + if (rmi4_data->full_pm_cycle) + synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); + + if (rmi4_data->sensor_sleep == true) { + synaptics_rmi4_sensor_wake(rmi4_data); + synaptics_rmi4_irq_enable(rmi4_data, true); + rmi4_data->touch_stopped = false; + retval = synaptics_rmi4_reinit_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to reinit device\n", + __func__); + } + } + + return; +} +#endif + +/** + * synaptics_rmi4_suspend() + * + * Called by the kernel during the suspend phase when the system + * enters suspend. + * + * This function stops finger data acquisition and puts the sensor to + * sleep (if not already done so during the early suspend phase), + * disables the interrupt, and turns off the power to the sensor. + */ +static int synaptics_rmi4_suspend(struct device *dev) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + unsigned char val=0; + const struct synaptics_dsx_platform_data *platform_data = + rmi4_data->board; + + if(rmi4_data->pwrrunning) + { + return 0 ; + } + + down(&work_sem); + rmi4_data->pwrrunning = true ; + + if(rmi4_data->smartcover_enable) + synaptics_rmi4_close_smartcover(); + //synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,&val,sizeof(val)); + + if(rmi4_data->glove_enable) + synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,&val,sizeof(val)); + + synaptics_enable_gesture(rmi4_data,true); + synaptics_enable_pdoze(rmi4_data,true); + if(rmi4_data->gesture || rmi4_data->pdoze_enable) { + synaptics_enable_irqwake(rmi4_data,true); + gpio_set_value(rmi4_data->reset_gpio,1); + goto GO_OUT; + } + + if (rmi4_data->staying_awake) { + goto GO_OUT; + } + + if (!rmi4_data->sensor_sleep) { + rmi4_data->touch_stopped = true; + + synaptics_rmi4_irq_enable(rmi4_data, false); + synaptics_rmi4_sensor_sleep(rmi4_data); + synaptics_rmi4_free_fingers(rmi4_data); + + //when suspend, close tp's vdd power + if (platform_data->regulator_en) { +#ifdef CHECK_WRONG_TP_BEFORCE_MAKE + regulator_disable(rmi4_data->regulator); +#else + //regulator_disable(rmi4_data->regulator); +#endif + } + } + +GO_OUT: + rmi4_data->pwrrunning = false ; + up(&work_sem); + return 0; +} + +#ifdef SYNC_RMI4_PWR +void synaptics_rmi4_sync_lcd_suspend(void) { + if(!syna_rmi4_data) + return ; + synaptics_rmi4_suspend(&syna_rmi4_data->i2c_client->dev); +} +void synaptics_rmi4_sync_lcd_resume(void) { + if(!syna_rmi4_data) + return ; + synaptics_rmi4_resume(&syna_rmi4_data->i2c_client->dev); +} +#endif + +//mingqiang.guo add for LCD show later when push power button and two click in gesture +static void speedup_synaptics_resume(struct work_struct *work) +{ + int retval; + unsigned char val=1; + struct synaptics_rmi4_data *rmi4_data = syna_rmi4_data; + const struct synaptics_dsx_platform_data *platform_data = rmi4_data->board; + print_ts(TS_DEBUG,"[TP] %s:%d\n",__func__,__LINE__); + + if(rmi4_data->pwrrunning) + return; + + print_ts(TS_DEBUG, KERN_ERR "gesture status[0x%x,0x%x]\n", syna_use_gesture,rmi4_data->gesture_enable); + + down(&work_sem); + synaptics_set_int_mask(syna_rmi4_data, 0);//mingqiang.guo add for black gesture failure + + rmi4_data->pwrrunning = true ; + +#if 1 //software reset it + synaptics_rmi4_i2c_write(rmi4_data,rmi4_data->f01_cmd_base_addr,&val,sizeof(val)); + msleep(200); +#else //hardware reset it ,maybe lead to balcak gesture failure + //hardware reset it + retval = synaptics_rmi4_reset_device(rmi4_data, rmi4_data->f01_cmd_base_addr); + if (retval < 0) { + printk( "%s: Failed to issue TP reset command, error = %d\n",__func__, retval); + goto GO_RETURN; + } +#endif + + if(rmi4_data->smartcover_enable) + synaptics_rmi4_open_smartcover(); + //synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_SMARTCOVER_EXT,&val,sizeof(val)); + + if(rmi4_data->glove_enable) + synaptics_rmi4_i2c_write(syna_rmi4_data,SYNA_ADDR_GLOVE_FLAG,&val,sizeof(val)); + + if(rmi4_data->gesture || rmi4_data->pdoze_enable) { + synaptics_enable_gesture(rmi4_data,false); + synaptics_enable_pdoze(rmi4_data,false); + synaptics_enable_irqwake(rmi4_data,false); + rmi4_data->pwrrunning = false ; + goto GO_RETURN; + } + + if (rmi4_data->staying_awake) { + rmi4_data->pwrrunning = false ; + goto GO_RETURN; + } + + if (!rmi4_data->sensor_sleep) { + rmi4_data->pwrrunning = false ; + goto GO_RETURN; + } + + //resume tp's vdd power + if (platform_data->regulator_en) { +#ifdef CHECK_WRONG_TP_BEFORCE_MAKE + regulator_enable(rmi4_data->regulator); + msleep(platform_data->reset_delay_ms); + rmi4_data->current_page = MASK_8BIT; +#else + //regulator_enable(rmi4_data->regulator); + //msleep(platform_data->reset_delay_ms); + //rmi4_data->current_page = MASK_8BIT; +#endif + } + + synaptics_rmi4_sensor_wake(rmi4_data); + synaptics_rmi4_irq_enable(rmi4_data, true); + rmi4_data->touch_stopped = false; + retval = synaptics_rmi4_reinit_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to reinit device\n", + __func__); + rmi4_data->pwrrunning = false ; + goto GO_RETURN; + } + rmi4_data->pwrrunning = false ; + +GO_RETURN: + synaptics_set_int_mask(syna_rmi4_data, 1);//mingqiang.guo add for black gesture failure + up(&work_sem); + return ; +} +//mingqiang.guo add end + +/** + * synaptics_rmi4_resume() + * + * Called by the kernel during the resume phase when the system + * wakes up from suspend. + * + * This function turns on the power to the sensor, wakes the sensor + * from sleep, enables the interrupt, and starts finger data + * acquisition. + */ +static int synaptics_rmi4_resume(struct device *dev) +{ + //mingqiang.guo add for LCD show later when push power button and two click in gesture + print_ts(TS_DEBUG,"%s is called\n",__func__); + queue_delayed_work(syna_rmi4_data->speedup_resume_wq,&syna_rmi4_data->speed_up_work, msecs_to_jiffies(10)); + msleep(50);//LCD亮得太快,ä¼šé—ªçƒ + return 0; +} + +#ifndef CONFIG_FB +static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = { + .suspend = synaptics_rmi4_suspend, + .resume = synaptics_rmi4_resume, +}; +#endif +#endif + +static const struct i2c_device_id synaptics_rmi4_id_table[] = { + {DRIVER_NAME, 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table); + +static struct of_device_id synaptics_of_match_table[] = { + { .compatible = "synaptics,rmi-ts",}, + { }, +}; + +static struct i2c_driver synaptics_rmi4_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM +#ifndef CONFIG_FB + .pm = &synaptics_rmi4_dev_pm_ops, +#endif +#endif + .of_match_table = synaptics_of_match_table, + }, + .probe = synaptics_rmi4_probe_s3320, + .remove = (synaptics_rmi4_remove), + .id_table = synaptics_rmi4_id_table, +}; + +/** + * synaptics_rmi4_init() + * + * Called by the kernel during do_initcalls (if built-in) + * or when the driver is loaded (if a module). + * + * This function registers the driver to the I2C subsystem. + * + */ +static int __init synaptics_rmi4_init(void) +{ + return i2c_add_driver(&synaptics_rmi4_driver); +} + +/** + * synaptics_rmi4_exit() + * + * Called by the kernel when the driver is unloaded. + * + * This funtion unregisters the driver from the I2C subsystem. + * + */ +static void __exit synaptics_rmi4_exit(void) +{ + i2c_del_driver(&synaptics_rmi4_driver); + + return; +} + +module_init(synaptics_rmi4_init); +module_exit(synaptics_rmi4_exit); + +MODULE_DESCRIPTION("Synaptics DSX I2C Touch Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_dsx_i2c.h b/drivers/input/touchscreen/synaptics_dsx_i2c.h new file mode 100755 index 0000000000000..c1078f5a4f664 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx_i2c.h @@ -0,0 +1,355 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _SYNAPTICS_DSX_RMI4_H_ +#define _SYNAPTICS_DSX_RMI4_H_ + +#define SYNAPTICS_DS4 (1 << 0) +#define SYNAPTICS_DS5 (1 << 1) +#define SYNAPTICS_DSX_DRIVER_PRODUCT (SYNAPTICS_DS4 | SYNAPTICS_DS5) +#define SYNAPTICS_DSX_DRIVER_VERSION 0x1016 + +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) +#define KERNEL_ABOVE_2_6_38 +#endif + +#ifdef KERNEL_ABOVE_2_6_38 +#define sstrtoul(...) kstrtoul(__VA_ARGS__) +#else +#define sstrtoul(...) strict_strtoul(__VA_ARGS__) +#endif + +#define PDT_PROPS (0X00EF) +#define PDT_START (0x00E9) +#define PDT_END (0x000A) +#define PDT_ENTRY_SIZE (0x0006) +#define PAGES_TO_SERVICE (10) +#define PAGE_SELECT_LEN (2) + +#define SYNAPTICS_RMI4_F01 (0x01) +#define SYNAPTICS_RMI4_F11 (0x11) +#define SYNAPTICS_RMI4_F12 (0x12) +#define SYNAPTICS_RMI4_F1A (0x1a) +#define SYNAPTICS_RMI4_F34 (0x34) +#define SYNAPTICS_RMI4_F51 (0x51) +#define SYNAPTICS_RMI4_F54 (0x54) + +#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 +#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3 +#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10 +#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3 + +#define F12_FINGERS_TO_SUPPORT 10 + +#define MAX_NUMBER_OF_BUTTONS 4 +#define MAX_INTR_REGISTERS 4 + +#define MASK_16BIT 0xFFFF +#define MASK_8BIT 0xFF +#define MASK_7BIT 0x7F +#define MASK_6BIT 0x3F +#define MASK_5BIT 0x1F +#define MASK_4BIT 0x0F +#define MASK_3BIT 0x07 +#define MASK_2BIT 0x03 +#define MASK_1BIT 0x01 + +#define TP_VENDOR_WINTEK 1 //wintek +#define TP_VENDOR_TPK 2 //TPK +#define TP_VENDOR_TRULY 3 //truly +#define TP_VENDOR_YOUNGFAST 4 //youngfast +#define TP_VENDOR_TPK_GFF 5 //Tpk gff +#define TP_VENDOR_JDI 6 //jdi +//#define SYNC_RMI4_PWR + +#ifdef SYNC_RMI4_PWR +extern void synaptics_rmi4_sync_lcd_suspend(void); +extern void synaptics_rmi4_sync_lcd_resume(void); +#endif + + +/* + * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT + * @query_base_addr: base address for query registers + * @cmd_base_addr: base address for command registers + * @ctrl_base_addr: base address for control registers + * @data_base_addr: base address for data registers + * @intr_src_count: number of interrupt sources + * @fn_number: function number + */ +struct synaptics_rmi4_fn_desc { + unsigned char query_base_addr; + unsigned char cmd_base_addr; + unsigned char ctrl_base_addr; + unsigned char data_base_addr; + unsigned char intr_src_count; + unsigned char fn_number; +}; + +/* + * synaptics_rmi4_fn_full_addr - full 16-bit base addresses + * @query_base: 16-bit base address for query registers + * @cmd_base: 16-bit base address for data registers + * @ctrl_base: 16-bit base address for command registers + * @data_base: 16-bit base address for control registers + */ +struct synaptics_rmi4_fn_full_addr { + unsigned short query_base; + unsigned short cmd_base; + unsigned short ctrl_base; + unsigned short data_base; +}; + +struct synaptics_rmi4_f12_extra_data { + unsigned char data1_offset; + unsigned char data15_offset; + unsigned char data15_size; + unsigned char data15_data[(F12_FINGERS_TO_SUPPORT + 7) / 8]; +}; + +/* + * struct synaptics_rmi4_fn - function handler data structure + * @fn_number: function number + * @num_of_data_sources: number of data sources + * @num_of_data_points: maximum number of fingers supported + * @size_of_data_register_block: data register block size + * @intr_reg_num: index to associated interrupt register + * @intr_mask: interrupt mask + * @full_addr: full 16-bit base addresses of function registers + * @link: linked list for function handlers + * @data_size: size of private data + * @data: pointer to private data + */ +struct synaptics_rmi4_fn { + unsigned char fn_number; + unsigned char num_of_data_sources; + unsigned char num_of_data_points; + unsigned char size_of_data_register_block; + unsigned char intr_reg_num; + unsigned char intr_mask; + struct synaptics_rmi4_fn_full_addr full_addr; + struct list_head link; + int data_size; + void *data; + void *extra; +}; + +/* + * struct synaptics_rmi4_device_info - device information + * @version_major: rmi protocol major version number + * @version_minor: rmi protocol minor version number + * @manufacturer_id: manufacturer id + * @product_props: product properties information + * @product_info: product info array + * @date_code: device manufacture date + * @tester_id: tester id array + * @serial_number: device serial number + * @product_id_string: device product id + * @support_fn_list: linked list for function handlers + */ +struct synaptics_rmi4_device_info { + unsigned int version_major; + unsigned int version_minor; + unsigned char manufacturer_id; + unsigned char product_props; + unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; + unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE]; + unsigned short tester_id; + unsigned short serial_number; + unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; + unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE]; + struct list_head support_fn_list; +}; + +/* + * struct synaptics_rmi4_data - rmi4 device instance data + * @i2c_client: pointer to associated i2c client + * @input_dev: pointer to associated input device + * @board: constant pointer to platform data + * @rmi4_mod_info: device information + * @regulator: pointer to associated regulator + * @rmi4_io_ctrl_mutex: mutex for i2c i/o control + * @early_suspend: instance to support early suspend power management + * @current_page: current page in sensor to acess + * @button_0d_enabled: flag for 0d button support + * @full_pm_cycle: flag for full power management cycle in early suspend stage + * @num_of_intr_regs: number of interrupt registers + * @f01_query_base_addr: query base address for f01 + * @f01_cmd_base_addr: command base address for f01 + * @f01_ctrl_base_addr: control base address for f01 + * @f01_data_base_addr: data base address for f01 + * @irq: attention interrupt + * @sensor_max_x: sensor maximum x value + * @sensor_max_y: sensor maximum y value + * @irq_enabled: flag for indicating interrupt enable status + * @fingers_on_2d: flag to indicate presence of fingers in 2d area + * @sensor_sleep: flag to indicate sleep state of sensor + * @wait: wait queue for touch data polling in interrupt thread + * @i2c_read: pointer to i2c read function + * @i2c_write: pointer to i2c write function + * @irq_enable: pointer to irq enable function + */ +struct synaptics_rmi4_data { + struct i2c_client *i2c_client; + struct input_dev *input_dev; + const struct synaptics_dsx_platform_data *board; + struct synaptics_rmi4_device_info rmi4_mod_info; + struct regulator *regulator; + struct mutex rmi4_reset_mutex; + struct mutex rmi4_io_ctrl_mutex; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + unsigned char current_page; + unsigned char button_0d_enabled; + unsigned char full_pm_cycle; + unsigned char num_of_rx; + unsigned char num_of_tx; + unsigned char num_of_fingers; + unsigned char max_touch_width; + unsigned char report_enable; + unsigned char no_sleep_setting; + unsigned char intr_mask[MAX_INTR_REGISTERS]; + unsigned char *button_txrx_mapping; + unsigned short num_of_intr_regs; + unsigned short f01_query_base_addr; + unsigned short f01_cmd_base_addr; + unsigned short f01_ctrl_base_addr; + unsigned short f01_data_base_addr; + unsigned short holstere_mode_control_addr; + unsigned char holstere_mode_open_or_close; + unsigned int firmware_id; + unsigned int product_info; + int irq; + int sensor_max_x; + int sensor_max_y; + bool flash_prog_mode; + bool irq_enabled; + bool touch_stopped; + bool fingers_on_2d; + bool sensor_sleep; + bool stay_awake; + bool staying_awake; + int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr, + unsigned char *data, unsigned short length); + int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr, + unsigned char *data, unsigned short length); + int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); + int (*reset_device)(struct synaptics_rmi4_data *rmi4_data, + unsigned short f01_cmd_base_addr); + + uint32_t id_gpio; + uint32_t wakeup_gpio; + uint32_t id3_gpio; + uint32_t reset_gpio; + uint32_t v3_gpio; + uint32_t irq_gpio; + struct kobject *properties_kobj; + uint32_t virtual_key_height; + uint32_t snap_top; + uint32_t snap_left; + uint32_t snap_right; + uint32_t snap_bottom; + uint32_t vk_prop_center_y; + uint32_t vk_prop_width; + uint32_t vk_prop_height; + uint32_t vendor_id; + uint32_t image_cid; + uint32_t device_cid; + unsigned short f54_query_base_addr; + unsigned short f54_cmd_base_addr; + unsigned short f54_ctrl_base_addr; + unsigned short f54_data_base_addr; + unsigned char gesturemode; + bool gesture; + bool pwrrunning; + unsigned int old_status; + unsigned int reset_count; //for reset count + unsigned int pre_btn_state; + unsigned short points[2*7]; + struct mutex ops_lock; + struct notifier_block fb_notif; + unsigned char gesture_enable; + unsigned char glove_enable; //glove mode + unsigned char pdoze_enable; //pdoze mode + unsigned char smartcover_enable; //smartcover mode + unsigned char pdoze_status; + unsigned char bcontinue; + unsigned char bremove; + struct workqueue_struct *reportqueue; //for work queue + struct work_struct reportwork; + struct delayed_work speed_up_work;//mingqiang.guo add for LCD show later when push power button and two click in gesture + struct workqueue_struct *speedup_resume_wq; +}; + +enum exp_fn { + RMI_DEV = 0, + RMI_F54, + RMI_FW_UPDATER, + RMI_LAST, +}; + +struct synaptics_rmi4_exp_fn_ptr { + int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, + unsigned char *data, unsigned short length); + int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, + unsigned char *data, unsigned short length); + int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); +}; + +void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, + int (*func_init)(struct synaptics_rmi4_data *rmi4_data), + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask)); + +int synaptics_fw_updater(unsigned char *fw_data); + +static inline ssize_t synaptics_rmi4_show_error(struct device *dev, + struct device_attribute *attr, char *buf) +{ + dev_warn(dev, "%s Attempted to read from write-only attribute %s\n", + __func__, attr->attr.name); + return -EPERM; +} + +static inline ssize_t synaptics_rmi4_store_error(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + dev_warn(dev, "%s Attempted to write to read-only attribute %s\n", + __func__, attr->attr.name); + return -EPERM; +} + +static inline void batohs(unsigned short *dest, unsigned char *src) +{ + *dest = src[1] * 0x100 + src[0]; +} + +static inline void hstoba(unsigned char *dest, unsigned short src) +{ + dest[0] = src % 0x100; + dest[1] = src / 0x100; +} + +#endif diff --git a/drivers/input/touchscreen/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx_rmi_dev.c new file mode 100755 index 0000000000000..d6273a2f0b756 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx_rmi_dev.c @@ -0,0 +1,789 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "synaptics_dsx.h" +#include "synaptics_dsx_i2c.h" + +#define CHAR_DEVICE_NAME "rmi" +#define DEVICE_CLASS_NAME "rmidev" +#define SYSFS_FOLDER_NAME "rmidev" +#define DEV_NUMBER 1 +#define REG_ADDR_LIMIT 0xFFFF + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf); + +struct rmidev_handle { + dev_t dev_no; + struct device dev; + struct synaptics_rmi4_data *rmi4_data; + struct synaptics_rmi4_exp_fn_ptr *fn_ptr; + struct kobject *sysfs_dir; + void *data; + bool irq_enabled; +}; + +struct rmidev_data { + int ref_count; + struct cdev main_dev; + struct class *device_class; + struct mutex file_mutex; + struct rmidev_handle *rmi_dev; +}; + +static struct bin_attribute attr_data = { + .attr = { + .name = "data", + .mode = (S_IWUSR | S_IRUSR), + }, + .size = 0, + .read = rmidev_sysfs_data_show, + .write = rmidev_sysfs_data_store, +}; + +static struct device_attribute attrs[] = { + __ATTR(open, S_IWUSR, + synaptics_rmi4_show_error, + rmidev_sysfs_open_store), + __ATTR(release, S_IWUSR, + synaptics_rmi4_show_error, + rmidev_sysfs_release_store), + __ATTR(attn_state, S_IRUGO, + rmidev_sysfs_attn_state_show, + synaptics_rmi4_store_error), +}; + +static int rmidev_major_num; + +static struct class *rmidev_device_class; + +static struct rmidev_handle *rmidev; + +DECLARE_COMPLETION(rmidev_remove_complete); + +static irqreturn_t rmidev_sysfs_irq(int irq, void *data) +{ + struct synaptics_rmi4_data *rmi4_data = data; + + sysfs_notify(&rmi4_data->input_dev->dev.kobj, + SYSFS_FOLDER_NAME, "attn_state"); + + return IRQ_HANDLED; +} + +static int rmidev_sysfs_irq_enable(struct synaptics_rmi4_data *rmi4_data, + bool enable) +{ + int retval = 0; + unsigned char intr_status[MAX_INTR_REGISTERS]; + unsigned long irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; + + if (enable) { + if (rmidev->irq_enabled) + return retval; + + /* Clear interrupts first */ + retval = rmidev->fn_ptr->read(rmi4_data, + rmi4_data->f01_data_base_addr + 1, + intr_status, + rmi4_data->num_of_intr_regs); + if (retval < 0) + return retval; + + retval = request_threaded_irq(rmi4_data->irq, NULL, + rmidev_sysfs_irq, irq_flags, + "synaptics_dsx_rmidev", rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to create irq thread\n", + __func__); + return retval; + } + + rmidev->irq_enabled = true; + } else { + if (rmidev->irq_enabled) { + disable_irq(rmi4_data->irq); + free_irq(rmi4_data->irq, rmi4_data); + rmidev->irq_enabled = false; + } + } + + return retval; +} + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int length = (unsigned int)count; + unsigned short address = (unsigned short)pos; + + if (length > (REG_ADDR_LIMIT - address)) { + dev_err(&rmidev->rmi4_data->i2c_client->dev, + "%s: Out of register map limit\n", + __func__); + return -EINVAL; + } + + if (length) { + retval = rmidev->fn_ptr->read(rmidev->rmi4_data, + address, + (unsigned char *)buf, + length); + if (retval < 0) { + dev_err(&rmidev->rmi4_data->i2c_client->dev, + "%s: Failed to read data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return length; +} + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int length = (unsigned int)count; + unsigned short address = (unsigned short)pos; + + if (length > (REG_ADDR_LIMIT - address)) { + dev_err(&rmidev->rmi4_data->i2c_client->dev, + "%s: Out of register map limit\n", + __func__); + return -EINVAL; + } + + if (length) { + retval = rmidev->fn_ptr->write(rmidev->rmi4_data, + address, + (unsigned char *)buf, + length); + if (retval < 0) { + dev_err(&rmidev->rmi4_data->i2c_client->dev, + "%s: Failed to write data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return length; +} + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + rmidev->fn_ptr->enable(rmi4_data, false); + rmidev_sysfs_irq_enable(rmi4_data, true); + + dev_dbg(&rmidev->rmi4_data->i2c_client->dev, + "%s: Attention interrupt disabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + unsigned short f01_cmd_base_addr; + struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; + + f01_cmd_base_addr = rmi4_data->f01_cmd_base_addr; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + rmi4_data->reset_device(rmi4_data, f01_cmd_base_addr); + + rmidev_sysfs_irq_enable(rmi4_data, false); + rmidev->fn_ptr->enable(rmi4_data, true); + + dev_dbg(&rmidev->rmi4_data->i2c_client->dev, + "%s: Attention interrupt enabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int attn_state; + //const struct synaptics_dsx_platform_data *platform_data = + // rmidev->rmi4_data->board; + + attn_state = gpio_get_value(rmidev->rmi4_data->irq_gpio); + + return snprintf(buf, PAGE_SIZE, "%u\n", attn_state); +} + +/* + * rmidev_llseek - used to set up register address + * + * @filp: file structure for seek + * @off: offset + * if whence == SEEK_SET, + * high 16 bits: page address + * low 16 bits: register address + * if whence == SEEK_CUR, + * offset from current position + * if whence == SEEK_END, + * offset from end position (0xFFFF) + * @whence: SEEK_SET, SEEK_CUR, or SEEK_END + */ +static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) +{ + loff_t newpos; + struct rmidev_data *dev_data = filp->private_data; + + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + mutex_lock(&(dev_data->file_mutex)); + + switch (whence) { + case SEEK_SET: + newpos = off; + break; + case SEEK_CUR: + newpos = filp->f_pos + off; + break; + case SEEK_END: + newpos = REG_ADDR_LIMIT + off; + break; + default: + newpos = -EINVAL; + goto clean_up; + } + + if (newpos < 0 || newpos > REG_ADDR_LIMIT) { + dev_err(&rmidev->rmi4_data->i2c_client->dev, + "%s: New position 0x%04x is invalid\n", + __func__, (unsigned int)newpos); + newpos = -EINVAL; + goto clean_up; + } + + filp->f_pos = newpos; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + + return newpos; +} + +/* + * rmidev_read: - use to read data from rmi device + * + * @filp: file structure for read + * @buf: user space buffer pointer + * @count: number of bytes to read + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + mutex_lock(&(dev_data->file_mutex)); + + retval = rmidev->fn_ptr->read(rmidev->rmi4_data, + *f_pos, + tmpbuf, + count); + if (retval < 0) + goto clean_up; + + if (copy_to_user(buf, tmpbuf, count)) + retval = -EFAULT; + else + *f_pos += retval; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + + return retval; +} + +/* + * rmidev_write: - used to write data to rmi device + * + * @filep: file structure for write + * @buf: user space buffer pointer + * @count: number of bytes to write + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + if (copy_from_user(tmpbuf, buf, count)) + return -EFAULT; + + mutex_lock(&(dev_data->file_mutex)); + + retval = rmidev->fn_ptr->write(rmidev->rmi4_data, + *f_pos, + tmpbuf, + count); + if (retval >= 0) + *f_pos += retval; + + mutex_unlock(&(dev_data->file_mutex)); + + return retval; +} + +/* + * rmidev_open: enable access to rmi device + * @inp: inode struture + * @filp: file structure + */ +static int rmidev_open(struct inode *inp, struct file *filp) +{ + int retval = 0; + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + + if (!dev_data) + return -EACCES; + + filp->private_data = dev_data; + + mutex_lock(&(dev_data->file_mutex)); + + rmidev->fn_ptr->enable(rmidev->rmi4_data, false); + dev_dbg(&rmidev->rmi4_data->i2c_client->dev, + "%s: Attention interrupt disabled\n", + __func__); + + if (dev_data->ref_count < 1) + dev_data->ref_count++; + else + retval = -EACCES; + + mutex_unlock(&(dev_data->file_mutex)); + + return retval; +} + +/* + * rmidev_release: - release access to rmi device + * @inp: inode structure + * @filp: file structure + */ +static int rmidev_release(struct inode *inp, struct file *filp) +{ + unsigned short f01_cmd_base_addr; + struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + + f01_cmd_base_addr = rmi4_data->f01_cmd_base_addr; + + if (!dev_data) + return -EACCES; + + rmi4_data->reset_device(rmi4_data, f01_cmd_base_addr); + + mutex_lock(&(dev_data->file_mutex)); + + dev_data->ref_count--; + if (dev_data->ref_count < 0) + dev_data->ref_count = 0; + + rmidev->fn_ptr->enable(rmidev->rmi4_data, true); + dev_dbg(&rmidev->rmi4_data->i2c_client->dev, + "%s: Attention interrupt enabled\n", + __func__); + + mutex_unlock(&(dev_data->file_mutex)); + + return 0; +} + +static const struct file_operations rmidev_fops = { + .owner = THIS_MODULE, + .llseek = rmidev_llseek, + .read = rmidev_read, + .write = rmidev_write, + .open = rmidev_open, + .release = rmidev_release, +}; + +static void rmidev_device_cleanup(struct rmidev_data *dev_data) +{ + dev_t devno; + + if (dev_data) { + devno = dev_data->main_dev.dev; + + if (dev_data->device_class) + device_destroy(dev_data->device_class, devno); + + cdev_del(&dev_data->main_dev); + + unregister_chrdev_region(devno, 1); + + dev_dbg(&rmidev->rmi4_data->i2c_client->dev, + "%s: rmidev device removed\n", + __func__); + } + + return; +} + +static char *rmi_char_devnode(struct device *dev, umode_t *mode) +{ + if (!mode) + return NULL; + + *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); +} + +static int rmidev_create_device_class(void) +{ + rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); + + if (IS_ERR(rmidev_device_class)) { + pr_err("%s: Failed to create /dev/%s\n", + __func__, CHAR_DEVICE_NAME); + return -ENODEV; + } + + rmidev_device_class->devnode = rmi_char_devnode; + + return 0; +} + +static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + dev_t dev_no; + unsigned char attr_count; + struct rmidev_data *dev_data; + struct device *device_ptr; + + rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); + if (!rmidev) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for rmidev\n", + __func__); + retval = -ENOMEM; + goto err_rmidev; + } + + rmidev->fn_ptr = kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL); + if (!rmidev) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for fn_ptr\n", + __func__); + retval = -ENOMEM; + goto err_fn_ptr; + } + + rmidev->fn_ptr->read = rmi4_data->i2c_read; + rmidev->fn_ptr->write = rmi4_data->i2c_write; + rmidev->fn_ptr->enable = rmi4_data->irq_enable; + rmidev->rmi4_data = rmi4_data; + + retval = rmidev_create_device_class(); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to create device class\n", + __func__); + goto err_device_class; + } + + if (rmidev_major_num) { + dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); + retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); + } else { + retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to allocate char device region\n", + __func__); + goto err_device_region; + } + + rmidev_major_num = MAJOR(dev_no); + dev_dbg(&rmi4_data->i2c_client->dev, + "%s: Major number of rmidev = %d\n", + __func__, rmidev_major_num); + } + + dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + if (!dev_data) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to alloc mem for dev_data\n", + __func__); + retval = -ENOMEM; + goto err_dev_data; + } + + mutex_init(&dev_data->file_mutex); + dev_data->rmi_dev = rmidev; + rmidev->data = dev_data; + + cdev_init(&dev_data->main_dev, &rmidev_fops); + + retval = cdev_add(&dev_data->main_dev, dev_no, 1); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to add rmi char device\n", + __func__); + goto err_char_device; + } + + dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); + dev_data->device_class = rmidev_device_class; + + device_ptr = device_create(dev_data->device_class, NULL, dev_no, + NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); + if (IS_ERR(device_ptr)) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to create rmi char device\n", + __func__); + retval = -ENODEV; + goto err_char_device; + } + + retval = gpio_export(rmi4_data->irq_gpio, false); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to export attention gpio\n", + __func__); + } else { + retval = gpio_export_link(&(rmi4_data->input_dev->dev), + "attn", rmi4_data->irq_gpio); + if (retval < 0) { + dev_err(&rmi4_data->input_dev->dev, + "%s Failed to create gpio symlink\n", + __func__); + } else { + dev_dbg(&rmi4_data->input_dev->dev, + "%s: Exported attention gpio %d\n", + __func__, rmi4_data->board->irq_gpio); + } + } + + rmidev->sysfs_dir = kobject_create_and_add(SYSFS_FOLDER_NAME, + &rmi4_data->input_dev->dev.kobj); + if (!rmidev->sysfs_dir) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to create sysfs directory\n", + __func__); + retval = -ENODEV; + goto err_sysfs_dir; + } + + retval = sysfs_create_bin_file(rmidev->sysfs_dir, + &attr_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to create sysfs bin file\n", + __func__); + goto err_sysfs_bin; + } + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + retval = sysfs_create_file(rmidev->sysfs_dir, + &attrs[attr_count].attr); + if (retval < 0) { + dev_err(&rmi4_data->input_dev->dev, + "%s: Failed to create sysfs attributes\n", + __func__); + retval = -ENODEV; + goto err_sysfs_attrs; + } + } + + return 0; + +err_sysfs_attrs: + for (attr_count--; attr_count >= 0; attr_count--) + sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); + + sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); + +err_sysfs_bin: + kobject_put(rmidev->sysfs_dir); + +err_sysfs_dir: +err_char_device: + rmidev_device_cleanup(dev_data); + kfree(dev_data); + +err_dev_data: + unregister_chrdev_region(dev_no, 1); + +err_device_region: + class_destroy(rmidev_device_class); + +err_device_class: + kfree(rmidev->fn_ptr); + +err_fn_ptr: + kfree(rmidev); + rmidev = NULL; + +err_rmidev: + return retval; +} + +static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data) +{ + unsigned char attr_count; + struct rmidev_data *dev_data; + + if (!rmidev) + goto exit; + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) + sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); + + sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); + + kobject_put(rmidev->sysfs_dir); + + dev_data = rmidev->data; + if (dev_data) { + rmidev_device_cleanup(dev_data); + kfree(dev_data); + } + + unregister_chrdev_region(rmidev->dev_no, 1); + + class_destroy(rmidev_device_class); + + kfree(rmidev->fn_ptr); + kfree(rmidev); + rmidev = NULL; + +exit: + complete(&rmidev_remove_complete); + + return; +} +extern void synaptics_rmi4_new_function_s1302(enum exp_fn fn_type, bool insert, + int (*func_init)(struct synaptics_rmi4_data *rmi4_data), + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask)); +static int __init rmidev_module_init(void) +{ + synaptics_rmi4_new_function_s1302(RMI_DEV, true, + rmidev_init_device, + rmidev_remove_device, + NULL); + return 0; +} + +static void __exit rmidev_module_exit(void) +{ + synaptics_rmi4_new_function_s1302(RMI_DEV, false, + rmidev_init_device, + rmidev_remove_device, + NULL); + wait_for_completion(&rmidev_remove_complete); + return; +} + +module_init(rmidev_module_init); +module_exit(rmidev_module_exit); + +MODULE_DESCRIPTION("Synaptics DSX RMI Dev Module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_dsx_s1302.c b/drivers/input/touchscreen/synaptics_dsx_s1302.c new file mode 100755 index 0000000000000..4f9c692495683 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_dsx_s1302.c @@ -0,0 +1,1150 @@ +/************************************************************* + ** Copyright (C), 2012-2016, OEM Mobile Comm Corp., Ltd + ** VENDOR_EDIT + ** File : synaptics_dsx_s1302.c + ** Description : + ** Date : 2015-3-19 15:37 + ** Author : BSP + ** + ** ------------------ Revision History: --------------------- + ** + *************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "synaptics_dsx.h" +#include "synaptics_dsx_i2c.h" + +#define DRIVER_NAME "synaptics-s1302" +#define INPUT_PHYS_NAME "synaptics-rmi-ts/input5" + +#include +#include + +#define SYN_I2C_RETRY_TIMES 10 +#define S1302_WORK_DELAY_MS 200 /* ms */ + +struct synaptics_rmi4_exp_fn_s1302{ + enum exp_fn fn_type; + bool inserted; + int (*func_init)(struct synaptics_rmi4_data *rmi4_data); + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data); + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask); + struct list_head link; +}; + + +struct synaptics_rmi4_exp_fn_data_s1302 { + bool initialized; + bool queue_work; + struct mutex mutex; + struct list_head list; + struct delayed_work work; + struct workqueue_struct *workqueue; + struct synaptics_rmi4_data *rmi4_data; +}; +struct synaptics_rmi4_exp_fn_data_s1302 exp_data_s1302; +static struct synaptics_rmi4_data *syna_s1302_data=0; +static int key_rep = 0; + +static int synaptics_rmi4_s1302_reset(struct synaptics_rmi4_data *rmi4_data, unsigned short f01_cmd_base_addr); +static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data, + unsigned int address) +{ + int retval = 0; + unsigned char retry; + unsigned char buf[PAGE_SELECT_LEN]; + unsigned char page; + struct i2c_client *i2c = rmi4_data->i2c_client; + + page = ((address >> 8) & MASK_8BIT); + if (page != rmi4_data->current_page) { + buf[0] = MASK_8BIT; + buf[1] = page; + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN); + if (retval != PAGE_SELECT_LEN) { + msleep(20); + } else { + rmi4_data->current_page = page; + break; + } + } + if (retry == SYN_I2C_RETRY_TIMES) { + dev_err(&rmi4_data->i2c_client->dev, "%s: I2C read over retry limit\n", __func__); + synaptics_rmi4_s1302_reset(rmi4_data, rmi4_data->f01_cmd_base_addr); + retval = -EIO; + } else { + rmi4_data->reset_count = 0 ; + } + + } else { + retval = PAGE_SELECT_LEN; + } + + return retval; +} + +/** + * synaptics_rmi4_i2c_read() + * + * Called by various functions in this driver, and also exported to + * other expansion Function modules such as rmi_dev. + * + * This function reads data of an arbitrary length from the sensor, + * starting from an assigned register address of the sensor, via I2C + * with a retry mechanism. + */ +static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_msg msg[] = { + { + .addr = rmi4_data->i2c_client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = rmi4_data->i2c_client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + + buf = addr & MASK_8BIT; + + mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + retval = synaptics_rmi4_set_page(rmi4_data, addr); + if (retval != PAGE_SELECT_LEN) + goto exit; + + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) { + retval = length; + break; + } + + msleep(20); + } + + if (retry == SYN_I2C_RETRY_TIMES) { + dev_err(&rmi4_data->i2c_client->dev, "%s: I2C read over retry limit\n", __func__); + rmi4_data->current_page = MASK_8BIT; + retval = -EIO; + } + +exit: + mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + return retval; +} + +/** + * synaptics_rmi4_i2c_write() + * + * Called by various functions in this driver, and also exported to + * other expansion Function modules such as rmi_dev. + * + * This function writes data of an arbitrary length to the sensor, + * starting from an assigned register address of the sensor, via I2C with + * a retry mechanism. + */ +static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, + unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_msg msg[] = { + { + .addr = rmi4_data->i2c_client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + retval = synaptics_rmi4_set_page(rmi4_data, addr); + if (retval != PAGE_SELECT_LEN) + goto exit; + + buf[0] = addr & MASK_8BIT; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { + if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) { + retval = length; + break; + } + + msleep(20); + } + + if (retry == SYN_I2C_RETRY_TIMES) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: I2C write over retry limit\n", + __func__); + rmi4_data->current_page = MASK_8BIT; + retval = -EIO; + } + +exit: + mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); + + return retval; +} +#define S1302_RESET_ADDR 0x006D +#define S1302_SLEEP_ADDR 0x0037 +#define KEY_ADD_STATUS 0x0014 +#define KEY_ADD 0x0200 +#define S1302_ID_ADDR 0x0083 +static int synaptics_rmi4_s1302_reset(struct synaptics_rmi4_data *rmi4_data,unsigned short f01_cmd_base_addr) +{ + int retval; + char status = 1; + + retval = synaptics_rmi4_i2c_write(rmi4_data,S1302_RESET_ADDR,&status,1); + printk("s1302 soft reset !!!!\n"); + return 0; +} +static void synaptics_rmi4_s1302_hard_reset(struct synaptics_rmi4_data *rmi4_data) +{ + gpio_set_value(rmi4_data->reset_gpio,0); + msleep(10); + printk("%s rmi4_data->reset_gpio:%d\n",__func__,gpio_get_value(rmi4_data->reset_gpio)); + gpio_set_value(rmi4_data->reset_gpio,1); + msleep(100); + printk("%s rmi4_data->reset_gpio:%d\n",__func__,gpio_get_value(rmi4_data->reset_gpio)); + printk("s1302 hard reset !!!!\n"); +} +#define REP_KEY_MENU (key_rep?(KEY_BACK):(KEY_MENU)) +#define REP_KEY_BACK (key_rep?(KEY_MENU):(KEY_BACK)) +static void synaptics_s1302_report(struct synaptics_rmi4_data *rmi4_data) +{ + + int retval; + char status; + char button_key; + + retval = synaptics_rmi4_i2c_read(rmi4_data,KEY_ADD_STATUS,&status,1); + //printk("%s status:%d\n",__func__,status); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, + "%s: Failed to read button data registers\n", + __func__); + return; + } + if (status && 0x10) + { + retval = synaptics_rmi4_i2c_read(rmi4_data,KEY_ADD,&button_key,1); + printk("%s button_key:%d pre_btn_state:%d\n",__func__,button_key,rmi4_data->pre_btn_state); + if((button_key & 0x01) && !(rmi4_data->pre_btn_state & 0x01))//back + { + input_report_key(rmi4_data->input_dev, REP_KEY_BACK, 1); + input_sync(rmi4_data->input_dev); + }else if(!(button_key & 0x01) && (rmi4_data->pre_btn_state & 0x01)){ + input_report_key(rmi4_data->input_dev, REP_KEY_BACK, 0); + input_sync(rmi4_data->input_dev); + } + + if((button_key & 0x02) && !(rmi4_data->pre_btn_state & 0x02))//menu + { + input_report_key(rmi4_data->input_dev, REP_KEY_MENU, 1); + input_sync(rmi4_data->input_dev); + }else if(!(button_key & 0x02) && (rmi4_data->pre_btn_state & 0x02)){ + input_report_key(rmi4_data->input_dev, REP_KEY_MENU, 0); + input_sync(rmi4_data->input_dev); + } + + if((button_key & 0x04) && !(rmi4_data->pre_btn_state & 0x04))//home + { + input_report_key(rmi4_data->input_dev, KEY_HOMEPAGE, 1);//KEY_HOMEPAGE + input_sync(rmi4_data->input_dev); + }else if(!(button_key & 0x04) && (rmi4_data->pre_btn_state & 0x04)){ + input_report_key(rmi4_data->input_dev, KEY_HOMEPAGE, 0); + input_sync(rmi4_data->input_dev); + } + + rmi4_data->pre_btn_state = button_key & 0x07; + //input_sync(rmi4_data->input_dev); + } + return; +} +//irq work function +static void synaptics_s1302_report_work(struct work_struct *work) { + struct synaptics_rmi4_data *rmi4_data = syna_s1302_data; + + synaptics_s1302_report(rmi4_data); + enable_irq(rmi4_data->i2c_client->irq); +} +static int synaptics_parse_dt(struct device *dev, struct synaptics_rmi4_data *ts) +{ + int ret = 0; + if (dev->of_node) + { + struct device_node *np = dev->of_node; + + /* reset, irq gpio info */ + ts->irq_gpio = of_get_named_gpio(np, "synaptics,irq-gpio", 0); + if( ts->irq_gpio < 0 ){ + printk("ts->irq_gpio not specified\n"); + } + ts->reset_gpio = of_get_named_gpio(np, "synaptics,reset-gpio", 0); + if( ts->reset_gpio < 0 ){ + printk("ts->reset_gpio not specified\n"); + } + ts->v3_gpio = of_get_named_gpio(np, "synaptics,en3v_gpio", 0); + if( ts->v3_gpio < 0 ){ + printk("ts->v3_gpio not specified\n"); + } + } + return ret; +} + +/** + * synaptics_s1302_wq() + * + * Called by the kernel when an interrupt occurs (when the sensor + * asserts the attention irq). + * + * This function is the ISR thread and handles the acquisition + * and the reporting of finger data when the presence of fingers + * is detected. + */ +static irqreturn_t synaptics_s1302_irq(int irq, void *data) +{ + struct synaptics_rmi4_data *rmi4_data = data; + + disable_irq_nosync(rmi4_data->i2c_client->irq); + //use work to handle irq event + queue_work(rmi4_data->reportqueue, &rmi4_data->reportwork); + return IRQ_HANDLED; +} + +/** + * synaptics_s1302_irq_enable() + * + * Called by synaptics_rmi4_probe() and the power management functions + * in this driver and also exported to other expansion Function modules + * such as rmi_dev. + * + * This function handles the enabling and disabling of the attention + * irq including the setting up of the ISR thread. + */ +static int synaptics_s1302_irq_enable(struct synaptics_rmi4_data *rmi4_data, + bool enable) +{ + int retval = 0; + unsigned char intr_status; + + if (enable) { + if (rmi4_data->irq_enabled) + return retval; + + /* Clear interrupts first */ + retval = synaptics_rmi4_i2c_read(rmi4_data, 0x0014, &intr_status, 1); + if (retval < 0) + return retval; + //printk("synap read *******status:[0x%d],[0x%d],[0x%d],[0x%d],[0x%d],[0x%d],[0x%d],[0x%d]\n",intr_status[0], + // intr_status[1],intr_status[2],intr_status[3],intr_status[4],intr_status[5],intr_status[6],intr_status[7]); + printk("synap s1302 irq=%d\n",rmi4_data->irq); + retval = request_irq(rmi4_data->irq, synaptics_s1302_irq, IRQF_TRIGGER_FALLING, DRIVER_NAME, rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to create irq(:%d) thread\n", __func__, rmi4_data->irq); + return retval; + } + + rmi4_data->irq_enabled = true; + } else { + if (rmi4_data->irq_enabled) { + disable_irq(rmi4_data->irq); + free_irq(rmi4_data->irq, rmi4_data); + rmi4_data->irq_enabled = false; + } + } + + return retval; +} + +static int synaptics_rmi4_set_input(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + + rmi4_data->input_dev = input_allocate_device(); + if (rmi4_data->input_dev == NULL) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to allocate input device\n", __func__); + retval = -ENOMEM; + goto err_input_device; + } + + rmi4_data->input_dev->name = DRIVER_NAME; + rmi4_data->input_dev->phys = INPUT_PHYS_NAME; + rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; + rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; + rmi4_data->input_dev->id.bustype = BUS_I2C; + rmi4_data->input_dev->dev.parent = &rmi4_data->i2c_client->dev; + input_set_drvdata(rmi4_data->input_dev, rmi4_data); + + set_bit(EV_SYN, rmi4_data->input_dev->evbit); + set_bit(EV_KEY, rmi4_data->input_dev->evbit); + set_bit(KEY_BACK, rmi4_data->input_dev->keybit); + set_bit(KEY_MENU, rmi4_data->input_dev->keybit); + set_bit(KEY_HOMEPAGE, rmi4_data->input_dev->keybit); +#ifdef INPUT_PROP_DIRECT + set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit); +#endif + + // retval = synaptics_rmi4_query_device(rmi4_data); + if (retval < 0) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to query device\n", __func__); + goto err_query_device; + } + + retval = input_register_device(rmi4_data->input_dev); + if (retval) { + dev_err(&rmi4_data->i2c_client->dev, "%s: Failed to register input device\n", __func__); + goto err_register_input; + } + + return 0; + +err_register_input: +err_query_device: + input_free_device(rmi4_data->input_dev); + +err_input_device: + return retval; +} +extern int rmi4_fw_module_init_s1302(bool insert); + +/** + * synaptics_rmi4_exp_fn_work_s1302() + * + * Called by the kernel at the scheduled time. + * + * This function is a work thread that checks for the insertion and + * removal of other expansion Function modules such as rmi_dev and calls + * their initialization and removal callback functions accordingly. + */ +static void synaptics_rmi4_exp_fn_work_s1302(struct work_struct *work) +{ + struct synaptics_rmi4_exp_fn_s1302 *exp_fhandler; + struct synaptics_rmi4_exp_fn_s1302 *exp_fhandler_temp; + struct synaptics_rmi4_data *rmi4_data = exp_data_s1302.rmi4_data; + + mutex_lock(&exp_data_s1302.mutex); + if (!list_empty(&exp_data_s1302.list)) { + list_for_each_entry_safe(exp_fhandler,exp_fhandler_temp,&exp_data_s1302.list, link) + { + if(exp_fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if ((exp_fhandler->func_init != NULL) && (exp_fhandler->inserted == false)) + { + if(exp_fhandler->func_init(rmi4_data) < 0) + { + //retry init + queue_delayed_work(exp_data_s1302.workqueue, &exp_data_s1302.work, msecs_to_jiffies(500)); + mutex_unlock(&exp_data_s1302.mutex); + return ; + } + exp_fhandler->inserted = true; + } + else if ((exp_fhandler->func_init == NULL) && (exp_fhandler->inserted == true)) + { + exp_fhandler->func_remove(rmi4_data); + list_del(&exp_fhandler->link); + kfree(exp_fhandler); + } + } + } + mutex_unlock(&exp_data_s1302.mutex); + + return; +} +/** + * synaptics_rmi4_new_function_s1302() + * + * Called by other expansion Function modules in their module init and + * module exit functions. + * + * This function is used by other expansion Function modules such as + * rmi_dev to register themselves with the driver by providing their + * initialization and removal callback function pointers so that they + * can be inserted or removed dynamically at module init and exit times, + * respectively. + */ +void synaptics_rmi4_new_function_s1302(enum exp_fn fn_type, bool insert, + int (*func_init)(struct synaptics_rmi4_data *rmi4_data), + void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), + void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, + unsigned char intr_mask)) +{ + struct synaptics_rmi4_exp_fn_s1302 *exp_fhandler; + + if (!exp_data_s1302.initialized) { + mutex_init(&exp_data_s1302.mutex); + INIT_LIST_HEAD(&exp_data_s1302.list); + exp_data_s1302.initialized = true; + } + + mutex_lock(&exp_data_s1302.mutex); + if (insert) { + exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL); + if (!exp_fhandler) { + pr_err("%s: Failed to alloc mem for expansion function\n", __func__); + goto exit; + } + exp_fhandler->fn_type = fn_type; + exp_fhandler->func_init = func_init; + exp_fhandler->func_attn = func_attn; + exp_fhandler->func_remove = func_remove; + exp_fhandler->inserted = false; + list_add_tail(&exp_fhandler->link, &exp_data_s1302.list); + } + else if (!list_empty(&exp_data_s1302.list)) + { + list_for_each_entry(exp_fhandler, &exp_data_s1302.list, link) + { + if(exp_fhandler == NULL) + { + printk("[TP] %s:%d fhandler is NULL, continue loop\n",__func__,__LINE__); + continue; + } + if (exp_fhandler->fn_type == fn_type) { + exp_fhandler->func_init = NULL; + exp_fhandler->func_attn = NULL; + goto exit; + } + } + } + +exit: + mutex_unlock(&exp_data_s1302.mutex); + + if (exp_data_s1302.queue_work) { + queue_delayed_work(exp_data_s1302.workqueue, &exp_data_s1302.work, msecs_to_jiffies(S1302_WORK_DELAY_MS)); + } + + return; +} +#ifdef CONFIG_FB +#define NORMAL_OPERATION (0 << 0) +#define SENSOR_SLEEP (1 << 0) +#define NO_SLEEP_OFF (0 << 2) +#define NO_SLEEP_ON (1 << 2) +#define CONFIGURED (1 << 7) + +#define MASK_3BIT 0x07 +/** + * synaptics_s1302_sleep() + * + * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend(). + * + * This function stops finger data acquisition and puts the sensor to sleep. + */ +static void synaptics_s1302_sleep(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char device_ctrl; + + msleep(20); + retval = synaptics_rmi4_i2c_read(rmi4_data, S1302_SLEEP_ADDR, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to enter sleep mode\n", __func__); + rmi4_data->sensor_sleep = false; + return; + } + + device_ctrl = (device_ctrl & ~MASK_3BIT); + device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP); + + retval = synaptics_rmi4_i2c_write(rmi4_data, S1302_SLEEP_ADDR, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to enter sleep mode\n", __func__); + rmi4_data->sensor_sleep = false; + return; + } + else + { + rmi4_data->sensor_sleep = true; + } + + return; +} + +/** + * synaptics_s1302_wake() + * + * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume(). + * + * This function wakes the sensor from sleep. + */ +static void synaptics_s1302_wake(struct synaptics_rmi4_data *rmi4_data) +{ + int retval; + unsigned char device_ctrl; + unsigned char no_sleep_setting = rmi4_data->no_sleep_setting; + + retval = synaptics_rmi4_i2c_read(rmi4_data, S1302_SLEEP_ADDR, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to wake from sleep mode\n", __func__); + rmi4_data->sensor_sleep = true; + return; + } + + device_ctrl = (device_ctrl & ~MASK_3BIT); + device_ctrl = (device_ctrl | no_sleep_setting | NORMAL_OPERATION); + + retval = synaptics_rmi4_i2c_write(rmi4_data, S1302_SLEEP_ADDR, &device_ctrl, sizeof(device_ctrl)); + if (retval < 0) + { + dev_err(&(rmi4_data->input_dev->dev), "%s: Failed to wake from sleep mode\n", __func__); + rmi4_data->sensor_sleep = true; + return; + } + else + { + rmi4_data->sensor_sleep = false; + } + + return; +} +static DEFINE_SEMAPHORE(work_sem); +static int synaptics_s1302_suspend(struct device *dev) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + synaptics_s1302_sleep(rmi4_data); + down(&work_sem); + synaptics_s1302_irq_enable(rmi4_data, false); + //regulator_disable(rmi4_data->regulator); + up(&work_sem); + return 0; +} + +static int synaptics_s1302_resume(struct device *dev) +{ + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + + synaptics_s1302_wake(rmi4_data); + down(&work_sem); +#if 0 //software reset it + unsigned char val=1; + synaptics_rmi4_i2c_write(rmi4_data,rmi4_data->f01_cmd_base_addr,&val,sizeof(val)); +#endif + + //regulator_enable(rmi4_data->regulator); + synaptics_s1302_irq_enable(rmi4_data, true); + up(&work_sem); + return 0; +} +#define BLANK 1 +#define UNBLANK 0 +static int fb_notifier_callback(struct notifier_block *p, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int new_status ; + + mutex_lock(&syna_s1302_data->ops_lock); + + switch (event) { + case FB_EVENT_BLANK : + new_status = (*(int *)evdata->data) ? BLANK : UNBLANK; + if (new_status == syna_s1302_data->old_status) + break; + + if(new_status != UNBLANK) { + printk("synap s1302:suspend!\n"); + synaptics_s1302_suspend(&(syna_s1302_data->input_dev->dev)); + } + else { + printk("synap s1302:resume!\n"); + synaptics_s1302_resume(&(syna_s1302_data->input_dev->dev)); + } + syna_s1302_data->old_status = new_status; + break; + } + mutex_unlock(&syna_s1302_data->ops_lock); + + return 0; +} +#endif +static int synaptics_fw_version_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "s1302 device_id:%d,image_id:%d\n",syna_s1302_data->device_cid,\ + syna_s1302_data->image_cid); + return 0 ; +} +static int synaptics_s1302_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_fw_version_show, inode->i_private); +} +static int synaptics_rep_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "s1302 menu key in %s\n",key_rep?("right"):("left")); + return 0 ; +} +static ssize_t synaptics_rep_write(struct file *file, const char __user *page, size_t t, loff_t *lo) +{ + int ret = 0; + char buf[10]; + + if( t > 2) + return t; + if( copy_from_user(buf, page, t) ){ + printk(KERN_INFO "%s: read proc input error.\n", __func__); + return t; + } + + sscanf(buf, "%d", &ret); + + if( (ret == 0 )||(ret == 1) ) + { + key_rep = ret; + } + return t; +} +static int synaptics_s1302_key_rep(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_rep_show, inode->i_private); +} +static int spage ,addr,blc; +static int synap_read_address(struct seq_file *seq, void *offset) +{ + int ret; + char buffer[128]; + int i; + + printk("%s page=0x%x,address=0x%x,block=0x%x\n",__func__,spage,addr,blc); + ret = synaptics_rmi4_i2c_read(syna_s1302_data,((spage&0xff << 8) | addr),buffer,blc); + for (i=0;i < blc;i++) + { + printk("buffer[%d]=0x%x\n",i,buffer[i]); + } + seq_printf(seq, "spage:%x addr:0x%x blc:%d\n",spage,addr,blc); + return 0; +} + +static ssize_t synap_write_address(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + int buf[128]; + int ret,i; + int temp_block,wbyte; + char reg[30]; + + ret = sscanf(buffer,"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",\ + &buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6],&buf[7],&buf[8],&buf[9],\ + &buf[10],&buf[11],&buf[12],&buf[13],&buf[14],&buf[15],&buf[16],&buf[17]); + for (i = 0;i < ret;i++) + { + printk("buf[i]=0x%x,",buf[i]); + } + printk("\n"); + spage= buf[0]; + addr = buf[1]; + temp_block = buf[2]; + wbyte = buf[3]; + if (0xFF == temp_block)//the mark is to write register else read register + { + for (i=0;i < wbyte;i++) + { + reg[i] = (char)buf[4+i]; + } + ret = synaptics_rmi4_i2c_write(syna_s1302_data,((spage&0xff << 8) | addr),reg,wbyte); + printk("%s write page=0x%x,address=0x%x\n",__func__,spage,addr); + for (i=0;i < wbyte;i++) + { + printk("reg=0x%x\n",reg[i]); + } + } + else + blc = temp_block; + return count; +} +static int synaptics_addr_open(struct inode *inode, struct file *file) +{ + return single_open(file, synap_read_address, inode->i_private); +} + +static ssize_t synaptics_s1302_reset_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) +{ + int ret,write_flag; + int retval; + char status = 1; + + ret = sscanf(buffer,"%x",&write_flag); + printk("%s write %d\n",__func__,write_flag); + if (1 == write_flag) + { + retval = synaptics_rmi4_i2c_write(syna_s1302_data,S1302_RESET_ADDR,&status,1); + printk("s1302 soft reset !!!!\n"); + } + else if(2 == write_flag) + { + synaptics_rmi4_s1302_hard_reset(syna_s1302_data); + } + else if(3 == write_flag) + { + gpio_set_value(syna_s1302_data->v3_gpio,0); + msleep(10); + printk("%s rmi4_data->v3_gpio:%d\n",__func__,gpio_get_value(syna_s1302_data->v3_gpio)); + gpio_set_value(syna_s1302_data->v3_gpio,1); + msleep(100); + printk("%s rmi4_data->v3_gpio:%d\n",__func__,gpio_get_value(syna_s1302_data->v3_gpio)); + printk("s1302 power off -> on !!!!\n"); + } + return count; +} +static int test_err = 0; +static int synaptics_reset_show(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n",test_err); + return 0 ; +} + +static int synaptics_s1302_reset_open(struct inode *inode, struct file *file) +{ + return single_open(file, synaptics_reset_show, inode->i_private); +} + +const struct file_operations synap_s1302[] = +{ + { + .owner = THIS_MODULE, + .open = synaptics_s1302_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }, + { + .owner = THIS_MODULE, + .open = synaptics_s1302_key_rep, + .read = seq_read, + .write = synaptics_rep_write, + .llseek = seq_lseek, + .release = single_release, + }, + { + .owner = THIS_MODULE, + .open = synaptics_addr_open, + .read = seq_read, + .write = synap_write_address, + .llseek = seq_lseek, + .release = single_release, + }, + { + .owner = THIS_MODULE, + .open = synaptics_s1302_reset_open, + .read = seq_read, + .write = synaptics_s1302_reset_write, + .llseek = seq_lseek, + .release = single_release, + } +}; + +static int synaptics_s1302_proc(void) +{ + struct proc_dir_entry *proc_entry=0; + + struct proc_dir_entry *procdir = proc_mkdir( "s1302", NULL ); + //for firmware version + proc_entry = proc_create_data("fw_version", 0444, procdir,&synap_s1302[0],NULL); + proc_entry = proc_create_data("key_rep", 0666, procdir,&synap_s1302[1],NULL); + proc_entry = proc_create_data("radd", 0666, procdir,&synap_s1302[2],NULL); + proc_entry = proc_create_data("reset", 0666, procdir,&synap_s1302[3],NULL); + printk("%s over.\n", __func__); + + return 0; +} +EXPORT_SYMBOL(synaptics_rmi4_new_function_s1302); + +extern char* synaptics_s1302_get_vender(void); + +static int synaptics_1302_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int retval; + char buffer[6] = {0}; + + struct synaptics_rmi4_data *rmi4_data; + + rmi4_data = kzalloc(sizeof(*rmi4_data), GFP_KERNEL); + if (!rmi4_data) { + dev_err(&client->dev, "%s: Failed to alloc mem for rmi4_data\n", __func__); + return -ENOMEM; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "%s: SMBus byte data not supported\n", __func__); + goto ERR_FREE; + } + + mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex)); + mutex_init(&(rmi4_data->rmi4_reset_mutex)); + + retval = synaptics_parse_dt(&client->dev, rmi4_data); + if (retval) + { + printk(KERN_ERR "%s synaptics parse_dt error \n", __func__); + goto ERR_FREE; + } + + rmi4_data->irq = gpio_to_irq(rmi4_data->irq_gpio); + if (rmi4_data->irq <= 0) + { + printk("%s, irq number is not specified, irq #= %d, int pin=%d\n\n", __func__, rmi4_data->irq, rmi4_data->irq_gpio); + } + retval = gpio_request(rmi4_data->irq_gpio,"s1302_int"); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, retval); + } + + retval = gpio_request(rmi4_data->reset_gpio,"s1302_reset"); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, retval); + } + + retval = gpio_request(rmi4_data->v3_gpio,"s1302_3v_en"); + if(retval < 0) + { + printk(KERN_ERR "%s: v3_gpio_request, err=%d", __func__, retval); + } + retval = gpio_direction_output(rmi4_data->reset_gpio,1); + retval = gpio_direction_output(rmi4_data->v3_gpio,1); + retval = gpio_direction_input(rmi4_data->irq_gpio); + if(retval < 0) + { + printk(KERN_ERR "%s: gpio_direction_input, err=%d", __func__, retval); + } + gpio_set_value(rmi4_data->irq_gpio,1); + + rmi4_data->i2c_client = client; + rmi4_data->current_page = MASK_8BIT; + rmi4_data->irq_enabled = false; + + rmi4_data->i2c_read = synaptics_rmi4_i2c_read; + rmi4_data->i2c_write = synaptics_rmi4_i2c_write; + rmi4_data->irq_enable = synaptics_s1302_irq_enable; + rmi4_data->reset_device = synaptics_rmi4_s1302_reset; + syna_s1302_data = rmi4_data; + rmi4_data->product_info = 1302; + retval = synaptics_rmi4_i2c_read(rmi4_data,S1302_ID_ADDR,&buffer[0],5); + printk("%s i2c test read id is %s\n",__func__,&buffer[0]); + if (retval < 0){ + test_err = 1; + synaptics_rmi4_s1302_reset(rmi4_data, rmi4_data->f01_cmd_base_addr); + msleep(100); + retval = synaptics_rmi4_i2c_read(rmi4_data,S1302_ID_ADDR,&buffer[0],5); + if (retval < 0){ + printk("synap s1302 i2c test fail retval=%d buffer:%s\n",retval,&buffer[0]); + //goto ERR_FREE; + } + } + +#ifdef CONFIG_FB //for tp suspend and resume + mutex_init(&rmi4_data->ops_lock); + rmi4_data->fb_notif.notifier_call = fb_notifier_callback; + retval = fb_register_client(&rmi4_data->fb_notif); + if (retval) + goto ERR_FREE ; +#endif + i2c_set_clientdata(client, rmi4_data); + retval = synaptics_rmi4_set_input(rmi4_data); + if (retval < 0) { + dev_err(&client->dev, "%s: Failed to set up input device\n", __func__); + goto ERR_INPUT; + } + rmi4_data->reportqueue = create_singlethread_workqueue("synaptics_s1302_wq"); + INIT_WORK(&rmi4_data->reportwork, synaptics_s1302_report_work); + +#if 1 + if (!exp_data_s1302.initialized) { + mutex_init(&exp_data_s1302.mutex); + INIT_LIST_HEAD(&exp_data_s1302.list); + exp_data_s1302.initialized = true; + } + exp_data_s1302.workqueue = create_singlethread_workqueue("dsx1302_exp_workqueue"); + INIT_DELAYED_WORK(&exp_data_s1302.work, synaptics_rmi4_exp_fn_work_s1302); + exp_data_s1302.rmi4_data = rmi4_data; + exp_data_s1302.queue_work = true; + queue_delayed_work(exp_data_s1302.workqueue, &exp_data_s1302.work, msecs_to_jiffies(S1302_WORK_DELAY_MS)); + rmi4_fw_module_init_s1302(true); + while(1) + { + msleep(50); + if(rmi4_data->bcontinue) + { + rmi4_fw_module_init_s1302(false); + break ; + } + } +#endif + synaptics_s1302_proc(); + push_component_info(TOUCH_KEY, "S1302", synaptics_s1302_get_vender()); + retval = synaptics_s1302_irq_enable(rmi4_data, true); + syna_s1302_data->bremove = 1; + return 0; + +ERR_INPUT: + input_unregister_device(rmi4_data->input_dev); + rmi4_data->input_dev = NULL; +ERR_FREE: + kfree(rmi4_data); + return retval; +} +#if 1 +struct synaptics_optimize_data{ + struct delayed_work work; + struct workqueue_struct *workqueue; + struct i2c_client *client; + const struct i2c_device_id *dev_id; +}; +static struct synaptics_optimize_data optimize_data_s1302; +extern struct synaptics_rmi4_data *syna_rmi4_data; +static void synaptics_s1302_work(struct work_struct *work) +{ + int retval; + struct i2c_client *client_optimize = optimize_data_s1302.client; + const struct i2c_device_id *dev_id = optimize_data_s1302.dev_id; + + while(1) + { + msleep(100); + if(NULL == syna_rmi4_data || syna_rmi4_data->bremove) + { + retval = synaptics_1302_probe(client_optimize, dev_id); + break ; + } + } + printk("synaptics s1302 return %d\n", retval); +} + + +static int synaptics_rmi4_probe_s1302(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int i, match; + optimize_data_s1302.workqueue = create_workqueue("optimize_workqueue_s1302"); + INIT_DELAYED_WORK(&(optimize_data_s1302.work), synaptics_s1302_work); + optimize_data_s1302.client = client; + optimize_data_s1302.dev_id = dev_id; + + printk("synaptics s1302 probe cpu %d\n", smp_processor_id()); + for (i = 0; i <= 3; i++) + { + if (cpu_is_offline(i) || i == smp_processor_id()) + { + continue; + } + queue_delayed_work_on(i, optimize_data_s1302.workqueue, + &(optimize_data_s1302.work), + msecs_to_jiffies(1000)); + match = 1; + printk("synap s1302 work on cpu %d\n",i); + break; + } + if (match == 0) + { + queue_delayed_work_on(0, optimize_data_s1302.workqueue, + &(optimize_data_s1302.work), + msecs_to_jiffies(1000)); + } + return 0; +} +#endif +static int synaptics_1302_remove(struct i2c_client *client) +{ + struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client); + + cancel_delayed_work_sync(&exp_data_s1302.work); + flush_workqueue(exp_data_s1302.workqueue); + destroy_workqueue(exp_data_s1302.workqueue); + + input_unregister_device(rmi4_data->input_dev); + kfree(rmi4_data); + return 0; +} +#ifdef CONFIG_FB //for tp suspend and resume +static const struct dev_pm_ops synaptics_s1302_pm_ops = { + .suspend = synaptics_s1302_suspend, + .resume = synaptics_s1302_resume, +}; +#endif +static const struct i2c_device_id synaptics_1302_id_table[] = { + {DRIVER_NAME, 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, synaptics_1302_id_table); + +static struct of_device_id synaptics_1302_match_table[] = { + { .compatible = "synaptics,s1302",}, + { }, +}; + +static struct i2c_driver synaptics_rmi4_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + +#ifdef CONFIG_FB //for tp suspend and resume + //.pm = &synaptics_s1302_pm_ops, +#endif + .of_match_table = synaptics_1302_match_table, + }, + .probe = synaptics_rmi4_probe_s1302, + .remove = synaptics_1302_remove, + .id_table = synaptics_1302_id_table, +}; + +static int __init synaptics_1302_init(void) +{ + return i2c_add_driver(&synaptics_rmi4_driver); +} + +static void __exit synaptics_1302_exit(void) +{ + i2c_del_driver(&synaptics_rmi4_driver); + return; +} + +module_init(synaptics_1302_init); +module_exit(synaptics_1302_exit); + +MODULE_DESCRIPTION("Synaptics DSX I2C Touch Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/synaptics_firmware_jdi_14049.h b/drivers/input/touchscreen/synaptics_firmware_jdi_14049.h new file mode 100755 index 0000000000000..959a9e06747f8 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_firmware_jdi_14049.h @@ -0,0 +1,6009 @@ +#ifndef SYANPTICS_UPDATE_FIRMWARE_H +#define SYANPTICS_UPDATE_FIRMWARE_H + +#define FIRMWARE_JDI_14049_VERSION (0x14049004) + +const unsigned char Syna_Firmware_Data_JDI_14049[] = { +0x2A,0xAC,0x54,0x5B,0x00,0x00,0x01,0x06,0x00,0x6C,0x01,0x00,0x00,0x04,0x00,0x00, +0x53,0x33,0x33,0x32,0x30,0x54,0x00,0x00,0x00,0x00,0xF8,0x0C,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x44,0x53,0x35,0x20,0x52,0x32,0x2E,0x31,0x31,0x2E,0x30,0x00,0x00,0x00,0x00,0x00, +0x53,0x33,0x33,0x32,0x30,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xE6,0xB1,0x1A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x49,0x32,0x43,0x00,0x05,0x00,0xFF,0x00,0x0C,0x0D,0x20,0x00,0x00,0x00,0x00,0x00, +0x49,0x32,0x43,0x00,0x05,0x00,0xFF,0x00,0x0C,0x0D,0x20,0x00,0x00,0x00,0x00,0x00, +0x1D,0x72,0x90,0xC1,0x75,0x1E,0xF2,0xE4,0xEF,0xB3,0xBA,0xA2,0x63,0x93,0x36,0x10, +0xF3,0x91,0xFE,0x0B,0x1D,0x07,0xDA,0x56,0x54,0xF2,0xA9,0x2A,0x8B,0x33,0xD5,0x63, +0x4C,0x4A,0xAA,0xA0,0x75,0x66,0xD7,0x0C,0x32,0xF4,0xE6,0xBA,0xCE,0xF1,0xF1,0xC9, +0x81,0x7C,0xC4,0xEE,0x7B,0x86,0xAA,0xE2,0x83,0xA5,0xFD,0x3A,0x7B,0x6F,0xFE,0xD8, +0x3A,0x32,0x07,0xDD,0x81,0x65,0x2A,0xAD,0xA9,0x16,0x33,0x6F,0x82,0x99,0x79,0xE8, +0xE0,0x7F,0x45,0x81,0xB9,0xB7,0xBD,0x2B,0x1B,0xB9,0x45,0xA6,0xC3,0x67,0xEE,0x2A, +0x88,0x2A,0xFC,0x9F,0xB1,0xD7,0x78,0x26,0x47,0x81,0x97,0xA5,0x24,0x90,0xB2,0x06, +0x21,0x2F,0x2B,0xC6,0x6E,0xE7,0x9F,0x36,0xCC,0x87,0x94,0x43,0xCA,0x53,0x91,0x38, +0xE0,0x14,0x9A,0xCD,0x80,0x69,0x13,0x0D,0x2F,0x28,0x23,0x6A,0x59,0xFF,0x6F,0x2B, +0xB7,0xA2,0x38,0x60,0x49,0x46,0x90,0x56,0x26,0x0F,0x24,0xC0,0xF6,0x8C,0x8C,0x77, +0xA2,0x96,0xD5,0xAF,0x06,0xAA,0x23,0x8C,0xC4,0x3F,0xB0,0x10,0x35,0x0B,0x95,0x55, +0xDE,0xF6,0x52,0xDF,0x5B,0x24,0xFD,0x80,0x4D,0x77,0x50,0x81,0xE8,0xE1,0x81,0x1D, +0x13,0xF8,0x09,0x1B,0x78,0xCD,0x4C,0x8B,0x97,0x62,0xD6,0x53,0x99,0x30,0xDB,0x96, +0x98,0x15,0x6C,0xA2,0x97,0x47,0x56,0x49,0xF3,0x9C,0xED,0x58,0x32,0x76,0xA3,0x63, +0xCB,0x90,0x4A,0xBE,0x3C,0x5F,0x3B,0xFD,0x80,0x13,0x3A,0x32,0x73,0x29,0xDC,0x47, +0xFD,0x8D,0x1A,0x12,0x07,0xCC,0x92,0x24,0xF5,0xAD,0xF6,0xFB,0xBB,0xD4,0xF8,0x92, +0xFD,0x02,0x28,0xA7,0x92,0x7A,0x9C,0xAB,0x4A,0x22,0x16,0xD8,0xB6,0xE8,0x11,0x0A, +0x07,0xA4,0x95,0xDE,0x03,0xEF,0xA0,0xC0,0xD5,0x4B,0x57,0xF7,0xF7,0x68,0x9F,0x72, +0x54,0x70,0x5E,0x0F,0xFD,0x0C,0x24,0x53,0x29,0xB9,0x14,0xB6,0x3C,0xE5,0x91,0x25, +0x8C,0x78,0xEE,0xAB,0x34,0x9F,0x78,0x74,0x73,0xE7,0x08,0x12,0x77,0x54,0xDE,0x1A, +0xD0,0xAF,0x1C,0xCF,0x7E,0xBA,0xBE,0x85,0x0E,0xFE,0xA0,0x09,0xC8,0xC6,0xF6,0x09, +0xC4,0xEC,0x3E,0x05,0xAF,0x7B,0xE0,0x8E,0x3C,0x05,0x0F,0x7D,0x6E,0xC5,0xC1,0xF7, +0x79,0xFD,0x17,0xE5,0xDB,0xAD,0x89,0x62,0x2D,0xA1,0x97,0x78,0xC0,0x86,0x21,0x51, +0xE8,0xAC,0x48,0x50,0xF9,0xD2,0x63,0x27,0x5D,0x78,0xD0,0x34,0xF1,0x9A,0x55,0xF5, +0xA0,0x0E,0x19,0x82,0x37,0x8E,0x1D,0xB1,0x57,0xFD,0x95,0xDC,0x5A,0x95,0x08,0x0C, +0x19,0x56,0x0E,0xA1,0x8D,0x8D,0xEA,0xA5,0x00,0x13,0xA2,0x92,0xD3,0xBA,0xEF,0x2E, +0xB8,0x7B,0xCE,0x4C,0x4A,0xC4,0xDB,0x84,0x7D,0x02,0xC8,0x6D,0xB4,0x03,0x4B,0xB4, +0x1C,0xC2,0xC2,0x6C,0x1D,0xD0,0xB8,0x38,0x8F,0x00,0xA7,0x5E,0xBF,0xC3,0x38,0x3F, +0x5F,0xCD,0x0D,0x17,0x34,0x43,0xED,0x08,0x24,0x96,0xD1,0x09,0x34,0xE4,0x1F,0xC1, +0xF7,0xCE,0x7F,0x1A,0x5D,0x0C,0x18,0x6E,0xA9,0xAB,0x1B,0xE6,0x32,0xDF,0x42,0xC8, +0xAF,0xFB,0x04,0x44,0x2F,0xF6,0xF3,0x9F,0xCB,0xC8,0xF9,0xCE,0x44,0x2A,0x14,0xBB, +0x69,0x55,0xA4,0xD7,0x70,0xB9,0x2F,0x83,0x9B,0xC3,0x1A,0xAC,0x9F,0x3F,0x88,0x3F, +0xB0,0x11,0x8A,0x2F,0x39,0xCE,0x80,0x3F,0xC7,0x60,0x71,0x8D,0x94,0x12,0x8C,0x49, +0x5D,0x5D,0xC1,0xF1,0x58,0xF6,0x26,0xF2,0x0A,0xFD,0xBF,0xD2,0x17,0x7C,0xD1,0x79, +0xA8,0x43,0x0A,0x88,0xD4,0xD0,0xAB,0xB9,0xF9,0x16,0x07,0xE0,0x69,0x45,0xB2,0x48, +0x25,0x2E,0xC9,0xDB,0x17,0x7E,0x42,0xC8,0xB5,0x2E,0x78,0x97,0x98,0x79,0x01,0xD0, +0x05,0x46,0x5F,0x55,0x46,0x94,0x27,0x6F,0xC7,0x3A,0x7A,0xFE,0x14,0x31,0x82,0x7C, +0x2C,0x66,0xBA,0xCF,0x87,0x77,0x44,0x2D,0x8F,0x83,0x7F,0xF4,0x76,0x2D,0x08,0xBA, +0x03,0x44,0x1F,0xCB,0xFC,0xB4,0x2A,0xD2,0x44,0xD8,0x15,0x94,0x66,0x53,0x82,0x6F, +0x5C,0x35,0x80,0x43,0x01,0xD7,0x00,0x19,0x09,0x52,0xFF,0x00,0xFC,0x02,0x02,0x6C, +0x6E,0x7A,0xC9,0x5F,0x49,0x96,0xAA,0xA5,0x4B,0xFF,0x97,0x7E,0x42,0xF3,0x2F,0x60, +0x85,0x2B,0xEA,0xE0,0x5D,0x6D,0x01,0x78,0xEE,0x18,0x4E,0xBB,0xF8,0xC5,0x75,0x37, +0xCF,0x27,0xE4,0x1D,0x7C,0x45,0xB6,0x13,0xCF,0x34,0xCB,0xDD,0xC1,0x9E,0x89,0x26, +0x95,0x04,0xAA,0xA7,0x3C,0x5A,0xB9,0x9B,0x90,0x2E,0x4A,0xFA,0xDA,0xD2,0xA2,0x9E, +0xFF,0x3F,0x84,0xFB,0x68,0x01,0x9A,0x0F,0x58,0x99,0x7B,0x83,0x47,0xD4,0x0D,0x34, +0xBA,0x72,0xEF,0x09,0xDA,0x18,0x03,0x97,0xEA,0x75,0x26,0x1E,0x16,0x36,0x38,0xEE, +0x4B,0xEA,0x10,0x4B,0x82,0x12,0x8A,0xC7,0x27,0xA5,0x86,0xDE,0x34,0x05,0xAA,0xB2, +0x7C,0x35,0x63,0x75,0x40,0x3F,0x79,0xDA,0x97,0xAA,0xDD,0xEF,0x8D,0x53,0x6F,0xB3, +0xF1,0xE5,0x0A,0x45,0xDC,0x7F,0xAE,0x75,0x16,0xAA,0x02,0xBD,0xBB,0x74,0xC3,0x47, +0x10,0x49,0xD4,0x20,0x45,0xF8,0x4E,0x4C,0x51,0x3F,0x8F,0xE5,0x34,0x93,0xEE,0x3D, +0x13,0xC1,0x79,0x3E,0x31,0x3D,0x45,0xA8,0xE9,0x4B,0xEA,0x14,0x5B,0xCE,0xE1,0x0F, +0x61,0x43,0x3C,0x86,0x62,0x08,0x8F,0xF8,0x6A,0x35,0x31,0x45,0x0C,0xF7,0x61,0x76, +0x7D,0x95,0x2B,0x00,0xDB,0x78,0xFD,0x10,0x32,0xE1,0x6A,0xD2,0xA3,0x89,0x09,0x52, +0x85,0x3B,0xD4,0xBA,0x72,0xE5,0x24,0x75,0x19,0x1E,0xBA,0xD5,0x00,0xFA,0x85,0x2D, +0x07,0x99,0xA3,0x19,0x79,0xA5,0x69,0x9B,0x59,0x01,0x8B,0x50,0xC1,0x86,0x08,0x9B, +0x8C,0x1B,0x0C,0x5D,0x32,0x3A,0x31,0xA5,0xA7,0x23,0x06,0x5B,0x04,0x0F,0xED,0x91, +0xBA,0xE0,0x8A,0xC8,0x7E,0x4D,0xFF,0x47,0x3E,0x58,0xA5,0xE8,0xB6,0x90,0xD5,0xFC, +0x50,0xAD,0x94,0x38,0x45,0x6D,0x5E,0xC5,0x35,0x7D,0x8D,0xD5,0x62,0xCD,0x5A,0x8A, +0x42,0x4A,0x3C,0x8F,0x56,0x9D,0x8C,0xEC,0xF4,0x45,0xBD,0x8D,0x57,0x07,0x62,0xB0, +0x08,0xB3,0x84,0x7F,0x65,0x87,0x62,0xAA,0xD8,0x22,0xBA,0xFC,0xA9,0x47,0x57,0xDB, +0x90,0xF3,0x5B,0xE9,0xE4,0x1A,0x64,0x9F,0xED,0xF1,0x19,0x92,0xB5,0x1A,0x56,0x0E, +0x2F,0x2F,0x1A,0xF2,0xA6,0x98,0xBF,0x52,0x68,0x67,0x9B,0x9E,0xE8,0x7B,0x6F,0x39, +0x04,0xF5,0xD5,0x9E,0x9F,0xFB,0x1F,0xA2,0x0C,0xE2,0x3B,0xAB,0xEC,0x7B,0x29,0x81, +0xD2,0x8E,0xBC,0xDD,0x6D,0x84,0xD1,0x84,0xA9,0x3B,0x17,0x94,0xB8,0x65,0x74,0xF3, +0xC6,0x1C,0x2E,0x36,0xB8,0xDA,0xB1,0x4B,0x57,0x71,0xBD,0x55,0xC9,0x2F,0x26,0xCE, +0xBC,0x2A,0x8A,0x65,0x4A,0x4D,0xBE,0x17,0x5C,0x57,0xDE,0x6B,0x87,0xD0,0xAA,0x22, +0xBB,0x91,0x40,0x1D,0xC8,0x8F,0xD4,0x66,0x9B,0xD5,0x67,0x40,0xE1,0xA1,0x89,0x83, +0x1E,0x1E,0x3B,0x0D,0x70,0xE8,0x19,0xAC,0x9A,0x21,0xDF,0xCF,0xF2,0x82,0xAC,0xFA, +0x66,0x1D,0x35,0xDC,0x2A,0xA4,0xBF,0x1A,0xB5,0x56,0x1F,0x50,0xD5,0xEE,0x4C,0x92, +0x76,0x3D,0xEA,0x29,0xD6,0xDD,0xA4,0x1F,0x43,0x9C,0xD0,0x51,0x86,0xE0,0xEA,0x0E, +0x03,0xDE,0xDD,0x39,0xC0,0xEA,0xF9,0x1A,0x83,0xD0,0x4B,0x1D,0xA9,0x92,0xCE,0xCD, +0xBE,0xB4,0x98,0x5F,0x99,0x23,0x57,0xCE,0xFE,0x67,0x2F,0x86,0x65,0x17,0x51,0x1A, +0x25,0x18,0x4B,0x9F,0xEC,0x34,0x8F,0x91,0x49,0x58,0xD7,0xEB,0xE4,0x15,0xCD,0xBC, +0x1D,0xFD,0x93,0x44,0xDE,0xDB,0x66,0x10,0xFD,0x66,0x84,0x8C,0x7C,0x33,0xB8,0x0B, +0xAE,0xD4,0x30,0xC3,0x9E,0x39,0x64,0x27,0xB5,0x49,0xA9,0xDE,0x31,0xF4,0x70,0x5E, +0x7D,0x0B,0x5A,0xF7,0xD6,0xAE,0xC8,0x43,0xA4,0xAE,0x12,0x2E,0xF8,0xF1,0x57,0x07, +0x47,0x87,0x59,0x5B,0x84,0xED,0x6E,0x2C,0xBF,0x74,0xA4,0x42,0x9B,0x2B,0xFF,0x15, +0xF7,0x07,0xB2,0x5C,0x39,0x8B,0x0C,0x2B,0x92,0xFB,0xB5,0x17,0x18,0xD6,0xEA,0xD0, +0xF6,0x9B,0x60,0x12,0x37,0x22,0xC4,0x2A,0x17,0x1E,0x3A,0xA3,0x3F,0xDD,0x8A,0x34, +0x06,0x7D,0x1A,0x95,0xF1,0x25,0xF6,0x4E,0x42,0xB1,0x91,0x51,0xAB,0x54,0x49,0x3D, +0x39,0x83,0x15,0x74,0x4E,0x5D,0x74,0xCF,0x43,0xC0,0xB0,0xAB,0x06,0x9F,0x05,0xDC, +0x15,0x8B,0x12,0x5A,0xD7,0x1D,0x81,0xBD,0x63,0xF4,0x79,0xD2,0x99,0xE5,0x2F,0x16, +0x78,0xC1,0xA2,0xD0,0x59,0x80,0x50,0x98,0x80,0x28,0x47,0x07,0x82,0x49,0x67,0xA5, +0x33,0x4A,0x4F,0xB7,0x7E,0xC1,0xCE,0x1F,0xF0,0x3A,0x8E,0x42,0x4F,0x01,0x7D,0x2D, +0xBD,0x38,0x07,0xA3,0x4C,0xA2,0x3B,0x35,0x45,0x3A,0x2C,0x15,0x8B,0xA6,0xE5,0xC2, +0x92,0x48,0xD9,0xED,0xC9,0xDA,0x8A,0xB2,0xCD,0x5E,0x56,0x98,0xC8,0xE8,0x0F,0x92, +0x7E,0xB9,0xE9,0xE6,0x8E,0x07,0x26,0x03,0x8D,0xC7,0xC5,0x6D,0x44,0xB3,0x0C,0xA2, +0xD3,0xE8,0x70,0x35,0x10,0xB9,0x0F,0x3C,0x47,0x17,0x7D,0x43,0xC4,0x71,0x37,0x0E, +0x74,0xCD,0x11,0x37,0xDC,0x7B,0xD6,0xDF,0x1F,0xCC,0x6D,0x91,0xC4,0xBF,0x1A,0xD5, +0xFE,0x88,0x9E,0x62,0x11,0xDB,0xEA,0x97,0x77,0xD9,0x06,0xDD,0x8C,0xFC,0x82,0xEC, +0x8B,0x8F,0xB5,0xDD,0x7A,0xF3,0x53,0x1E,0x2F,0x0C,0x46,0xDD,0x6A,0xA0,0xF6,0x06, +0x3C,0x11,0x68,0x43,0x16,0x27,0xBC,0x4F,0x6A,0x68,0x11,0x46,0x6C,0x28,0x31,0x52, +0x29,0x00,0x6C,0xBE,0x3E,0x4B,0x6C,0xA1,0x51,0x2B,0x6B,0xF4,0xA0,0x4B,0x83,0xD2, +0xB3,0xB1,0xB5,0x27,0x1F,0x0B,0x20,0xF5,0x55,0x29,0x8F,0xE8,0x66,0xC4,0x53,0x2A, +0x6C,0xCF,0x2F,0x44,0xFB,0x33,0x28,0x69,0x3C,0x1A,0x29,0xEA,0x41,0xC3,0x54,0xE6, +0x97,0x6B,0xFE,0xD8,0x63,0xC6,0xFC,0x14,0x1D,0xBC,0xB0,0xF7,0x58,0x20,0x32,0xB1, +0xEB,0xDD,0x94,0xC7,0x5C,0x60,0x37,0xA1,0xCF,0xDA,0x19,0xBE,0xF9,0x05,0xCC,0xFF, +0x4E,0x9A,0x60,0xAE,0x6D,0x08,0x37,0x5D,0xD6,0x74,0xED,0xC8,0x2A,0xBD,0x86,0xEA, +0xCE,0x99,0x5E,0xE9,0x94,0x42,0x5B,0x1E,0x52,0xDD,0x12,0xAA,0xAC,0xB6,0xC7,0x3F, +0x74,0xAD,0x5A,0xD7,0x40,0x60,0x21,0x31,0x2A,0x91,0x0D,0xF0,0x04,0x2E,0x0C,0x76, +0xBD,0x4D,0x76,0x15,0x90,0x84,0x69,0x79,0xC0,0xE6,0x57,0x77,0x07,0xF6,0xFB,0x9C, +0x95,0x76,0x60,0x3A,0xBC,0x24,0xD7,0x19,0x5D,0x6A,0x88,0x21,0x76,0xD9,0x00,0xC8, +0x2C,0x45,0xE7,0x5F,0x25,0x07,0xA9,0xE4,0x62,0xD3,0x42,0xE5,0x99,0x85,0xA6,0x1F, +0xC8,0xC9,0x46,0x21,0x0E,0x9E,0x5E,0x2C,0xAC,0xC9,0xE2,0x7E,0xC6,0xFA,0xDE,0xFC, +0xC6,0x33,0xDA,0x66,0xF7,0xD0,0x60,0xCD,0xCF,0x2A,0x0C,0xC1,0x8F,0x98,0x65,0xDE, +0x5E,0x49,0x5E,0x7B,0x5E,0x18,0xA4,0x1B,0x51,0x04,0xAE,0x10,0x8D,0xAA,0x05,0x7B, +0x6B,0x07,0x83,0xF5,0xB7,0x0D,0xFA,0xB6,0xDC,0xDB,0x29,0x34,0x37,0xCB,0x53,0xB5, +0x4C,0xAB,0xE4,0x6B,0xEC,0x32,0xEC,0x25,0x9A,0xDB,0x31,0x54,0x79,0xAF,0x3C,0x5A, +0x19,0x18,0x97,0x52,0xC6,0x0F,0x05,0x75,0x30,0x96,0xAD,0xA3,0x7F,0xA8,0x5E,0x4E, +0x2C,0x1D,0xAC,0x40,0x29,0x9B,0xDB,0x50,0x42,0x7A,0x70,0x4A,0xDA,0xF7,0x14,0xAC, +0xCE,0x59,0xE6,0x21,0x8A,0xF3,0x0F,0xEA,0x33,0xFE,0x3D,0xA5,0x1A,0xF3,0x84,0x27, +0x40,0xFC,0xDD,0xD3,0x05,0x32,0xBF,0xAF,0xC4,0x2E,0xAF,0xF8,0xBD,0x58,0xB9,0x07, +0x37,0x12,0x2B,0xCE,0x83,0x15,0xC2,0xFA,0xE2,0xFD,0xE2,0xB9,0x14,0x17,0x04,0x47, +0x4A,0x2F,0x8E,0xAA,0x73,0x55,0x80,0xDA,0x7C,0x6F,0x19,0x24,0xE6,0xDE,0xE0,0x6E, +0x7E,0x0F,0xFF,0x9A,0xC2,0xC1,0x4B,0xB9,0x52,0xCD,0x39,0x4F,0xCD,0xF5,0xAD,0x21, +0xBA,0xB5,0x66,0xD2,0xA5,0x21,0xF7,0x62,0x68,0xCF,0x57,0xD6,0xA6,0xE9,0xF9,0x4C, +0x85,0x2B,0xB7,0xBE,0xE8,0xF3,0x6A,0x8E,0x04,0xD2,0x8B,0x57,0xCD,0xB5,0x41,0xDA, +0x7E,0x86,0x57,0xED,0xDA,0xEC,0xA2,0xEF,0x57,0x45,0x3D,0x76,0x7A,0xC5,0x37,0x98, +0x6C,0xC6,0xB4,0x17,0x73,0x66,0x2C,0x90,0xE5,0xE3,0x0F,0xC0,0xA9,0x02,0xCD,0x76, +0x71,0x37,0xBA,0xCF,0x31,0xDE,0x05,0x98,0xF8,0xF5,0x29,0xAD,0x73,0xB8,0xB7,0xC8, +0xD7,0x35,0xAE,0xF5,0x69,0x81,0xE6,0xAC,0x84,0xAF,0x80,0x56,0x5B,0xF9,0x46,0x81, +0x5C,0x6F,0xF1,0x8C,0x19,0x20,0x31,0x4E,0x08,0x16,0x04,0x8E,0x03,0x67,0xBA,0x58, +0x8A,0xC5,0x07,0x47,0x75,0x93,0x21,0x18,0x56,0xA0,0x33,0x26,0xC4,0xA3,0x23,0xAC, +0xA7,0x10,0x63,0x87,0xCB,0x5F,0x9E,0xBA,0xDD,0x0C,0x1F,0xDB,0xFF,0xF9,0x76,0xCD, +0xA3,0x65,0xF9,0x5F,0x77,0x3F,0xBD,0xD7,0x30,0xB9,0x5F,0x4F,0xF0,0x73,0x90,0x7B, +0xC3,0x0C,0xC5,0xE0,0xDF,0xE1,0x26,0x5A,0x0A,0xD2,0x37,0xEC,0x23,0xAA,0x65,0x38, +0x66,0x6B,0x3A,0xCE,0xE7,0xD9,0x58,0xAD,0x43,0x8F,0xA5,0xE1,0x13,0x80,0xFB,0xC8, +0xAF,0xA1,0xCB,0x2C,0x86,0x72,0x1A,0xD3,0xC0,0x9C,0xDE,0xAB,0xA1,0xD8,0xC8,0x17, +0x70,0x9D,0xCD,0x1B,0xE2,0xED,0x52,0x49,0xDF,0xFE,0x81,0xBF,0xBA,0xAC,0x94,0xA1, +0x06,0xE1,0x98,0x6E,0x87,0x32,0xFA,0xC2,0xD2,0x30,0xE9,0x2F,0xE2,0x54,0xA4,0xBA, +0x1B,0xC3,0x3D,0x87,0xFE,0xF0,0x6E,0xD2,0xA5,0x77,0x0A,0x39,0xF8,0xFB,0xE3,0x48, +0x37,0xE5,0x9F,0x06,0x7D,0x68,0x07,0x75,0x4B,0x12,0xE8,0x23,0xEC,0x71,0xC6,0xDD, +0x29,0x78,0x89,0xDA,0xDF,0x27,0xE8,0xB4,0x6B,0xEE,0xF5,0xEB,0x57,0x71,0xD4,0x9C, +0xA8,0xA4,0xAC,0x14,0x8E,0xA4,0xEE,0x2B,0x1B,0xC6,0x1C,0x30,0x22,0x65,0x16,0xC4, +0x30,0x2D,0x54,0x07,0x18,0x3F,0x2A,0x77,0x22,0x03,0xF2,0xB7,0x41,0x75,0xA5,0xC5, +0x0A,0x3E,0x99,0x25,0xA6,0xBD,0x6D,0x63,0xD0,0x49,0xF4,0x79,0xCE,0x79,0x44,0x7E, +0xD7,0x4B,0x63,0x31,0x71,0xB2,0x77,0xB0,0x8E,0x4A,0x83,0x6D,0x24,0xE1,0x5B,0x34, +0xD7,0x0C,0xFD,0x18,0xCA,0xC4,0x67,0xAC,0x83,0x9F,0x0A,0x7F,0x0B,0x73,0xB0,0xD1, +0x6A,0x4C,0xA4,0x10,0x89,0xDB,0xA9,0xD5,0x15,0x38,0x72,0xE4,0x8D,0x16,0xF5,0x15, +0x73,0x6C,0xFA,0xDB,0x4B,0xDF,0xC9,0xEE,0xB2,0x2C,0x9C,0x73,0x60,0xD6,0xBC,0x60, +0x58,0x5D,0x6F,0xAA,0x80,0x73,0x2F,0xE1,0x65,0x7B,0x76,0x90,0x09,0x6B,0xEC,0xBE, +0xFC,0x73,0x7D,0xD3,0x1A,0x17,0x9C,0xB4,0x5E,0x91,0x8A,0x5D,0x3F,0x85,0x46,0x83, +0xD4,0xB1,0x19,0xEF,0x06,0x4A,0xEF,0x1E,0x7B,0x66,0x2D,0xCF,0xFC,0x7E,0xAB,0x31, +0x30,0xF4,0x56,0x98,0xA9,0xAA,0xE1,0xDC,0xE5,0xEE,0x51,0xE6,0xEE,0x9E,0x7F,0x5F, +0x94,0xCA,0x77,0x02,0xF9,0x45,0x34,0x3C,0xA1,0x61,0x35,0x3A,0x67,0x3C,0x03,0xD5, +0x08,0xB9,0x94,0x94,0x97,0x6C,0xB0,0x04,0xE6,0xEA,0xC7,0x17,0x8D,0x6E,0x93,0xA1, +0xD0,0xFA,0x18,0x34,0xB6,0x92,0x7B,0x4E,0x75,0x0B,0xC9,0xE3,0xA5,0x25,0x5C,0x76, +0xE5,0x94,0x9E,0x3C,0x61,0x7E,0x8E,0xF5,0xE6,0x22,0xD3,0xDB,0x87,0x88,0xA6,0xAB, +0xCF,0xCB,0xEA,0xE7,0x2C,0x6C,0xA2,0xCE,0x7F,0xB3,0x94,0x0A,0x55,0x18,0x68,0xE7, +0x05,0xCC,0xE6,0xC4,0x24,0x3C,0x3B,0x02,0xFA,0xEA,0x3C,0x32,0x45,0x2A,0x37,0x6C, +0x15,0xED,0x8F,0x9A,0x06,0xCD,0xA5,0x6C,0xE3,0xB8,0xCE,0xCA,0x81,0xD6,0xE9,0xF0, +0xCE,0x9A,0xC1,0x99,0x41,0x17,0x9B,0xD4,0x9F,0xA2,0x58,0x64,0xAD,0x42,0x97,0x7B, +0x4A,0xC2,0x4E,0xBA,0x74,0x25,0xD9,0x7C,0x8C,0xDF,0xA3,0xDA,0x73,0xAC,0x38,0x2A, +0x26,0x14,0x18,0x54,0xFC,0xE8,0xD6,0xEC,0x17,0xFD,0xF5,0x9A,0x29,0x24,0x41,0x26, +0xD5,0xE5,0x03,0xDB,0xA4,0x8C,0xE6,0x41,0x03,0x24,0x2B,0x03,0x66,0x29,0x5D,0x5C, +0x67,0x75,0xCB,0x31,0xBC,0x78,0x54,0xD7,0xE0,0xE4,0xFA,0x41,0xBF,0xD0,0xE6,0x63, +0x07,0x63,0x9A,0x56,0xA6,0x87,0x3A,0xB2,0x03,0xD9,0x70,0x0A,0x35,0x3E,0x0C,0xCC, +0x39,0xFA,0x58,0x42,0x8D,0xA5,0x00,0xF6,0x96,0xA3,0xD2,0x0E,0x07,0x9F,0xDD,0xC3, +0x1D,0x68,0x0A,0xE9,0x57,0x57,0x05,0xAE,0xED,0x2C,0xBD,0xC6,0x68,0x5D,0xEC,0xBA, +0xF1,0x8F,0xC2,0xB1,0xDF,0x08,0xA2,0x55,0x3E,0x05,0x41,0x2B,0xFA,0x3A,0xE8,0xB1, +0x4C,0x8B,0x8F,0x13,0x9E,0x8C,0x77,0xB5,0x87,0xB4,0xF4,0x01,0xFC,0x68,0x7A,0x2A, +0x07,0xD8,0xEA,0x73,0x10,0xA2,0x7E,0x39,0x94,0x31,0xB6,0xC9,0xD8,0x7F,0x97,0xB4, +0x6D,0xA4,0x3D,0x81,0xE0,0xB4,0x00,0x1A,0x66,0x05,0x31,0x6F,0x52,0x3C,0xA1,0xF8, +0x64,0x19,0x48,0x27,0x45,0x15,0x93,0x06,0xCB,0x38,0xC2,0xFA,0xAA,0x62,0x93,0xA1, +0xEC,0x0A,0x43,0xA4,0x58,0x7A,0x69,0x26,0xEE,0x86,0x36,0x28,0xFD,0xC9,0x8C,0xDF, +0xE4,0xFE,0xBD,0x72,0x8B,0x76,0xBE,0xA5,0x9C,0xE9,0x26,0x22,0x92,0x6C,0x54,0xA9, +0x64,0x87,0x99,0x28,0xF6,0x75,0x6E,0xED,0xEF,0x1A,0x37,0x81,0x5C,0x74,0x10,0x23, +0x7A,0x63,0x0F,0x84,0xA6,0x61,0xD3,0xDD,0xC1,0xBF,0xAF,0x23,0xCF,0xF1,0xE9,0x1E, +0x5B,0x46,0xA8,0xF6,0x0B,0x28,0x46,0x42,0x5E,0x5B,0x41,0x74,0x95,0x0C,0x82,0xE0, +0xCC,0x20,0xC3,0xA4,0x6E,0x4E,0x9E,0xA9,0xD3,0x4A,0x77,0x9F,0x18,0x6A,0x1F,0x30, +0x42,0x13,0x4C,0xB9,0xA7,0xCF,0x5A,0xA0,0x92,0x26,0x46,0xC3,0x49,0xB5,0xCC,0xB3, +0x9F,0xE4,0xD9,0x13,0xB6,0x73,0xEE,0x59,0x17,0xB4,0x78,0x1C,0x22,0xDD,0x80,0xFA, +0x28,0x41,0x13,0xDA,0xAC,0x3A,0xBE,0x8C,0xBD,0x21,0x98,0x30,0x31,0x63,0x93,0x54, +0xFA,0xD5,0x0D,0x03,0xEF,0x56,0x59,0xD8,0xD0,0x48,0xBB,0x96,0x74,0xF0,0x7D,0x62, +0x4E,0xF0,0xBF,0xF3,0x85,0x60,0x8D,0xAE,0xE7,0x20,0xBF,0xEB,0x93,0x1A,0x15,0x6B, +0x99,0xC0,0xB0,0x99,0x20,0x6B,0x5C,0x45,0x82,0xCD,0x26,0x40,0x90,0xC8,0xE6,0x25, +0xE9,0x58,0xCA,0xBF,0x49,0xD6,0x2C,0xAD,0x57,0xFC,0xEB,0xE0,0xAA,0x2D,0x7F,0xF8, +0xA7,0x01,0x01,0x13,0xED,0xDA,0x15,0x4D,0x7C,0xE8,0xE9,0xA9,0xBF,0x26,0x73,0xCB, +0x98,0x32,0x6B,0x0F,0x99,0x0B,0x8C,0x96,0x37,0xAA,0xBD,0x00,0x8D,0x42,0xC9,0xA4, +0xF6,0xB2,0x6F,0x07,0x46,0xD1,0xAF,0xD5,0x25,0xC9,0x9A,0x4F,0x1E,0x1A,0xEC,0x0E, +0xB5,0x87,0x1B,0x29,0xE9,0x04,0xAE,0x77,0x42,0xA2,0x86,0x4B,0x77,0xBE,0xA6,0xA3, +0xF7,0xCB,0x52,0xBF,0x8D,0x4C,0x98,0xBB,0xF8,0xD4,0xE5,0xE1,0x91,0xAE,0x05,0x15, +0x4C,0x0C,0xB6,0xED,0xC0,0x5E,0x3F,0x5E,0xC8,0xDC,0x59,0x8D,0xF2,0x57,0x18,0x13, +0xC4,0xEB,0x4A,0x00,0xC7,0xF3,0xC9,0xAE,0xCF,0x89,0x67,0x1D,0x6F,0x02,0xEF,0x04, +0xEF,0x7D,0x46,0xC2,0x6A,0x1E,0x92,0x54,0x74,0x5A,0x73,0xBF,0x66,0x6C,0x81,0xD3, +0x5B,0x8A,0xC3,0xF3,0x56,0xB5,0xE4,0xBE,0x5D,0xDB,0xCF,0xB9,0x99,0x50,0xE5,0x7D, +0x90,0xAE,0xD8,0x7C,0x07,0x7B,0xCE,0x90,0xE5,0x32,0xF5,0x49,0x7D,0xE2,0x0C,0x17, +0xF9,0xCE,0x9D,0xA6,0x4B,0xC0,0xE4,0x6A,0xF7,0xAE,0x99,0x43,0x09,0x2A,0xA7,0x30, +0xE6,0xB9,0x24,0x4A,0x5E,0xF0,0xC2,0x98,0x9C,0x2D,0xAB,0x7E,0x78,0x3E,0x00,0x03, +0x4C,0xF6,0x2B,0x72,0xB7,0x5F,0xAA,0x82,0xD4,0xAF,0xE0,0x42,0x42,0x24,0x02,0x3E, +0x13,0x0E,0x86,0xDA,0xB5,0xAE,0xB9,0x92,0xA1,0xDB,0x0F,0x32,0x81,0x24,0xFF,0x8F, +0x8D,0x60,0xD6,0xBA,0x95,0x21,0x31,0x25,0xD5,0x78,0x7E,0x07,0xED,0x6B,0xD5,0xEA, +0x82,0x15,0xED,0x0D,0x16,0x7F,0x7A,0xB3,0x33,0x87,0x8A,0xBE,0xF9,0xD4,0x29,0xBF, +0x68,0x25,0x3A,0x42,0x07,0xFA,0x4C,0x78,0x7D,0x62,0xE4,0x62,0x20,0x1D,0x65,0xA7, +0x04,0x3C,0xDB,0x28,0x43,0x8D,0x18,0x4D,0x42,0x78,0xDC,0x43,0xF7,0xEB,0x42,0x29, +0x48,0x13,0x4C,0x65,0xE0,0x26,0xEB,0x6E,0xCD,0x03,0xEF,0xDD,0x0A,0xFE,0xB4,0xA4, +0xBB,0x4E,0x39,0xCC,0xC0,0x47,0x49,0x55,0x91,0xC7,0x41,0x60,0x94,0x92,0x6F,0x43, +0xB5,0x55,0xFE,0xC5,0x92,0xC0,0xE6,0xBC,0xE5,0xDF,0x49,0x0B,0x16,0x70,0x2A,0xC4, +0x45,0x46,0x46,0x3C,0xD5,0x22,0x7B,0x3D,0xF8,0x10,0xCC,0x31,0xA7,0x56,0x95,0xCA, +0xD6,0xA1,0x0D,0x24,0x3E,0x97,0x14,0x6C,0x32,0x99,0xBA,0xF0,0xB0,0xE5,0xE9,0x83, +0x1C,0xCC,0xB5,0xDE,0x67,0x5A,0x37,0xC0,0xBD,0x3F,0x49,0x55,0x14,0x89,0xD2,0x15, +0x4F,0x1A,0x7C,0x01,0x14,0x55,0x7F,0xEF,0xB2,0xE6,0x76,0xCE,0xA4,0x3E,0xEF,0x2B, +0xC4,0x82,0xEA,0xE6,0x73,0x09,0xE6,0xC4,0x96,0x46,0x83,0x4E,0xCC,0xF7,0x04,0xB2, +0x9F,0x78,0x89,0x64,0xBD,0xBA,0x7E,0x26,0x22,0x2B,0x1A,0x43,0x71,0x23,0x7E,0xA6, +0x9F,0x79,0xBE,0x75,0x35,0x7F,0x0E,0x19,0xE3,0xEB,0x72,0xBB,0x33,0xB8,0x3B,0x27, +0xC3,0xB2,0xC1,0x7E,0xA4,0x42,0xDA,0xBA,0xE2,0x4A,0x1E,0x85,0xDF,0x90,0x4E,0x9C, +0x50,0x6D,0xC7,0x82,0x5F,0x13,0xE2,0x1B,0x9F,0xE4,0x48,0x35,0xD1,0x90,0x91,0x70, +0xC7,0x08,0x23,0x29,0xF8,0x6E,0xD4,0xA4,0x14,0xC5,0xA5,0x8E,0xC1,0x9C,0xD7,0x9A, +0x77,0xC6,0x50,0x4C,0x3E,0x28,0x62,0x56,0xEE,0x4A,0xEC,0x09,0xBC,0x98,0xC6,0x0D, +0x8D,0xEA,0xA9,0xE3,0xBD,0xE3,0x77,0x0D,0x54,0x12,0xCD,0x61,0x15,0xC4,0x24,0x09, +0xDB,0x62,0xF3,0x9F,0xA8,0xD3,0xDB,0x43,0x00,0x07,0xA0,0xA9,0x00,0x57,0x5D,0x90, +0xAE,0x8E,0x7B,0xB3,0x91,0x3C,0xBB,0x15,0x06,0x36,0x50,0x95,0x9F,0x18,0x5F,0x30, +0x4A,0xF4,0xCB,0xAC,0xAB,0x7E,0x42,0x01,0xE6,0x31,0x86,0x5C,0x09,0x78,0x49,0x46, +0x21,0x8C,0x63,0x65,0xB8,0xD4,0x7F,0xEF,0x64,0xC4,0x47,0x24,0x8E,0x55,0x2E,0x07, +0x89,0xBD,0x9C,0x9E,0x25,0x33,0xB2,0xDE,0xDD,0x72,0x71,0x66,0xE3,0x71,0x55,0xB5, +0x89,0x0C,0x5A,0x42,0x8E,0x84,0x39,0x7F,0xFA,0xCE,0xDD,0x45,0xF1,0x8D,0x07,0xD8, +0x83,0xA4,0x1F,0xDE,0x4D,0x43,0x91,0xA9,0x59,0xA9,0x70,0xB8,0x05,0x76,0x9E,0xBA, +0x2C,0xB8,0xDB,0x5E,0x35,0x2A,0x8F,0xE9,0x98,0x00,0x1A,0xB2,0xD2,0xAD,0x38,0x79, +0xC0,0x14,0xD9,0xF1,0x73,0x88,0x3C,0x4E,0xC7,0xE3,0xC6,0x9C,0x73,0x56,0xDE,0x45, +0x3C,0x5A,0xB8,0x7E,0x06,0xCE,0x9C,0x29,0xB1,0x81,0x01,0xBE,0x40,0x72,0xA4,0x09, +0x3F,0xBC,0x26,0xF7,0xEF,0x57,0xF1,0x53,0x9D,0x56,0xD8,0xBC,0x0B,0xCC,0x8C,0xF7, +0x36,0xB3,0x10,0x52,0x58,0x18,0xE2,0x61,0x2C,0x97,0xC3,0x4E,0xC7,0x4A,0xEB,0x52, +0xD3,0x80,0xBB,0x31,0x1B,0x78,0x06,0x3A,0x1D,0xBA,0xB4,0x41,0xC9,0x86,0x4C,0x04, +0x1E,0x60,0x8E,0xF6,0x0C,0xF5,0x39,0xB0,0x6C,0x1D,0xC9,0xC2,0x74,0x69,0x07,0x50, +0xB6,0xE9,0x7F,0xD2,0xB2,0x5E,0xD4,0x9E,0x89,0x44,0x21,0xB2,0xCE,0xEA,0x73,0x32, +0x09,0x54,0x23,0xA9,0x94,0x35,0x68,0xDD,0xE2,0x7F,0x5C,0xE5,0xCF,0xB4,0x87,0x00, +0x6E,0xC3,0xA8,0xBB,0xF8,0x89,0xFB,0x0A,0x89,0x38,0xCF,0x07,0xE4,0xEC,0x2F,0x43, +0x31,0x72,0xA8,0x7E,0xA0,0xA6,0x74,0xB3,0x76,0x47,0x2E,0x56,0x77,0xBB,0x9B,0x63, +0x12,0xEA,0xD5,0x29,0x93,0x57,0xEC,0xD2,0x50,0xC3,0x34,0x7F,0x03,0x2D,0x46,0x49, +0xF6,0x87,0xD4,0x58,0xAA,0xFA,0x47,0x99,0xE8,0x4C,0x83,0x8A,0x3F,0x58,0x05,0xF7, +0x60,0xFA,0xB4,0xA9,0x9E,0xD3,0xD8,0x15,0x95,0x08,0xED,0xD1,0x73,0xE6,0x41,0x67, +0xCE,0xE1,0x9B,0xA4,0x58,0x24,0x8A,0xD2,0x02,0x99,0x4F,0x20,0x04,0x46,0x3B,0x6F, +0x83,0x94,0xE9,0x57,0xA3,0x17,0x6E,0xF3,0x26,0x64,0x17,0xC3,0x4D,0x90,0x51,0xB5, +0x23,0x27,0xBC,0xBD,0x67,0xD4,0x6D,0x14,0xD4,0xF5,0xAB,0xA6,0x68,0x8B,0xAB,0xF8, +0x22,0x18,0x30,0x10,0x6C,0x3A,0x6C,0x80,0x3F,0x45,0x6A,0x1F,0x11,0x3B,0x25,0x5F, +0xB7,0x67,0xE9,0x43,0x06,0xA8,0x32,0xDE,0x3F,0x76,0x1D,0xF9,0xAD,0x53,0xCE,0xD0, +0x51,0xCD,0xD4,0x1E,0x6C,0x41,0xD9,0x77,0xC3,0x38,0x08,0xFA,0xF3,0x9D,0x2D,0x22, +0x37,0xCD,0x1B,0x05,0x36,0x09,0xC0,0xE7,0x10,0xB3,0x30,0xF0,0xBC,0x9F,0x36,0xA2, +0xE5,0xE1,0x4A,0x0E,0x30,0xC5,0x1A,0x81,0x50,0x22,0xD6,0x9B,0x02,0x0A,0x3D,0xA4, +0xBD,0x2B,0xCA,0x2A,0xDC,0xF4,0xC2,0xB4,0x7A,0x19,0xAF,0x22,0xCF,0x31,0xAE,0x80, +0x5D,0x5A,0x1D,0x99,0x99,0x0E,0xF9,0xF9,0xAE,0x99,0x81,0x7F,0x74,0xF2,0x99,0x9B, +0xA6,0xB3,0x94,0xE5,0x42,0x44,0x44,0xCD,0xBB,0xF5,0x46,0xD3,0x3F,0xFB,0x6E,0xF1, +0x40,0x75,0xBC,0xDA,0xC4,0x53,0xA3,0x44,0xEA,0xBF,0x0B,0xE6,0xC1,0x1F,0x32,0x0F, +0x1D,0xD5,0xDD,0xD6,0x02,0x34,0xA2,0xBC,0x25,0x71,0x13,0x26,0x2D,0xBA,0x2C,0x50, +0xD3,0x5B,0x36,0x0C,0x5B,0xFE,0x61,0x2C,0xD1,0x10,0xE9,0x19,0xA7,0x73,0xFC,0xA0, +0x52,0x3D,0xC7,0xD4,0x26,0x1D,0xD1,0xF5,0xAF,0xC3,0x6C,0xDE,0xF7,0x61,0xD2,0x1B, +0xBD,0xDD,0x79,0xAD,0xC0,0x6E,0x99,0x60,0x3D,0x3D,0x7A,0xC9,0xB9,0x3E,0x0E,0x75, +0xD2,0xC8,0xAC,0xEB,0x4D,0xA2,0x20,0x79,0x1C,0x2B,0x05,0x07,0xE5,0xED,0x25,0xDD, +0x09,0x3B,0x51,0x80,0x2B,0xAC,0x86,0xB1,0x5E,0x9F,0xC6,0xA8,0xCE,0x17,0x87,0x7B, +0x04,0xF2,0x37,0x63,0xBB,0xD9,0xC8,0x3D,0x74,0x08,0x34,0xDD,0xF6,0xBF,0xC8,0x45, +0x90,0x45,0x8E,0xAA,0xD9,0x1A,0x10,0x66,0xB9,0x29,0x47,0xCA,0xF9,0xF1,0x0E,0x10, +0xBE,0x22,0x6D,0x80,0x70,0xAC,0x75,0x82,0x23,0xA3,0x05,0xE2,0xCA,0x76,0x86,0x9B, +0xED,0x38,0x68,0x36,0x98,0x4F,0x5B,0x55,0x72,0x85,0x9F,0xE7,0x9D,0xEB,0x3E,0x5C, +0x04,0x83,0xB2,0x01,0x06,0xF9,0xC4,0xCC,0x36,0x25,0x65,0xA5,0xAF,0xF6,0x7E,0x1E, +0x59,0xEE,0x40,0x4B,0x56,0x79,0xE1,0xC4,0x1F,0xA4,0xA8,0x33,0x23,0xA6,0xBD,0x02, +0x1E,0x75,0x8A,0x26,0xC7,0xA6,0x33,0x14,0x75,0x98,0x9E,0x75,0x7C,0x1C,0x91,0x65, +0xE4,0x54,0x76,0x1B,0xD3,0x96,0x91,0x68,0x07,0x08,0x3D,0xAF,0x69,0x0C,0x9D,0xB2, +0xFD,0xA6,0xD7,0x6C,0x62,0xFB,0x54,0xA2,0xA8,0x08,0x93,0xD7,0x2F,0xB8,0xD5,0x47, +0xC5,0x40,0x1B,0xD1,0x3D,0x97,0xC5,0xC0,0x14,0xD1,0x12,0x5A,0xDB,0xDA,0xEF,0xFA, +0xFF,0x3E,0x9C,0xBB,0x53,0x0D,0xD9,0xC8,0xFF,0x2E,0xC7,0xFC,0x6B,0x84,0xD1,0xEB, +0xE4,0x54,0xE7,0x59,0xC2,0xE5,0x94,0x70,0x0B,0xC4,0x8C,0x75,0x2D,0x33,0xC5,0x17, +0x37,0xB1,0x44,0xAB,0x69,0x5B,0x30,0xF5,0xC4,0x02,0x02,0xAC,0x6C,0xA5,0xAB,0xE2, +0x60,0x80,0x27,0xE5,0x32,0x2A,0xAC,0x7F,0x69,0x30,0x28,0x96,0xEC,0x9E,0xB1,0x37, +0x2A,0x70,0x43,0xAE,0x43,0x27,0x87,0xB0,0x7C,0xBA,0x91,0x54,0x77,0xE3,0x04,0x56, +0x2E,0xE6,0x72,0x58,0x24,0x84,0xF8,0x8C,0xFE,0x0C,0xD0,0x8C,0xC7,0x6D,0xCB,0xB2, +0x27,0x66,0x81,0x14,0xB3,0x66,0xED,0x0B,0x9E,0x87,0x4B,0xDA,0x13,0x47,0x15,0xAC, +0x80,0x9F,0xA4,0xF9,0x2A,0x4D,0x23,0x8F,0xEA,0x61,0x55,0x46,0x8E,0x00,0x90,0xB9, +0x4B,0xD0,0xC3,0x5C,0x49,0x21,0xD4,0xA6,0x2D,0x97,0x3E,0x85,0x6A,0x43,0xB1,0x95, +0x14,0x04,0x17,0xB4,0x07,0x54,0x38,0x83,0xEE,0x5E,0xCA,0xAF,0xEE,0x98,0x7D,0x5D, +0x09,0x14,0xAC,0xBC,0x36,0x16,0xB3,0xE9,0x2B,0x3E,0x3A,0x04,0x41,0xFA,0xE2,0x1F, +0x16,0x09,0x06,0x5D,0xFD,0x0B,0xD9,0xCA,0x2E,0x59,0xBD,0x1A,0xBE,0xAD,0x08,0xF9, +0x3F,0xB1,0x22,0xB0,0x44,0xD8,0xEC,0xE4,0x23,0x26,0x0F,0xEC,0x43,0x8B,0xC9,0xCE, +0x16,0xDC,0xE6,0xAF,0x6E,0x62,0xBB,0x54,0x08,0xB7,0xFD,0x75,0x9D,0x22,0x58,0x66, +0xD5,0x57,0xD6,0x3C,0xE7,0xF4,0x3D,0x4E,0xB6,0x38,0xF4,0x92,0x9B,0x7B,0x4B,0xC3, +0xC8,0x39,0xFE,0xB1,0x96,0xB1,0x8C,0x43,0xE3,0xB3,0x95,0x58,0xD1,0xA1,0xC3,0xF4, +0xCC,0x4E,0x7D,0xC1,0x6A,0x9E,0x1F,0xF5,0x0A,0x0D,0x6C,0x33,0x8B,0x42,0x47,0x89, +0xB8,0x3B,0xD1,0x11,0xC4,0x1C,0x61,0xDF,0x02,0xE4,0xDB,0x6C,0xFA,0xE3,0x49,0x81, +0x9D,0xD7,0x32,0xA5,0x46,0x7C,0x50,0xE3,0x19,0xCE,0xD4,0x75,0xC5,0x6B,0x9D,0x9D, +0x4E,0xA9,0x12,0x43,0x58,0x56,0xFB,0x64,0xD2,0x61,0xDA,0x03,0xFC,0xE3,0xAD,0x4A, +0xD3,0x06,0x27,0xE0,0xBB,0x62,0x03,0xB7,0xA1,0xAC,0x2A,0x7A,0x86,0xC7,0xDB,0xD9, +0x90,0xA2,0xB7,0x3B,0x64,0x50,0x63,0xCE,0xC4,0x3B,0x8F,0xC7,0xDA,0xC5,0x3D,0x51, +0xA0,0x9D,0xDB,0x6A,0xFB,0x69,0x17,0x6E,0x53,0x88,0x81,0x7B,0x5D,0x3E,0xBD,0xDE, +0xF0,0xD8,0x3C,0x2A,0x33,0x53,0x32,0x54,0x7B,0x09,0x8B,0x73,0x5A,0xE2,0x6B,0x0D, +0x52,0x67,0xE9,0x92,0xB0,0x4A,0x1C,0xB1,0xE2,0xCB,0x72,0x61,0x8D,0x79,0x9C,0xFD, +0x16,0x98,0xE2,0x00,0x7B,0x94,0xFE,0x7E,0xA9,0x55,0x67,0x80,0x58,0x27,0xCA,0xF2, +0x0D,0x0F,0x86,0xE3,0x05,0xAB,0x3A,0xBE,0x51,0x5A,0xF9,0xDD,0x68,0x86,0x38,0x0A, +0xE4,0x2D,0x81,0x7B,0x78,0x7A,0xFB,0x8D,0xB2,0x12,0x1F,0xB2,0x72,0x7C,0x54,0x43, +0x72,0x20,0x4E,0xE3,0x45,0x31,0x35,0x78,0x42,0xD8,0xD4,0x36,0x1E,0x10,0xAE,0xF2, +0x61,0x9F,0xD4,0xD3,0xB3,0xD2,0xF2,0xB7,0xCE,0xEC,0x88,0xF9,0xFB,0x91,0xC4,0x4F, +0x13,0xB8,0x79,0x94,0x16,0x92,0xC6,0x33,0x1D,0x72,0x6A,0xFC,0x9B,0xCA,0x8F,0xA2, +0xCB,0xA3,0xF8,0x8B,0x35,0x72,0xA2,0xB2,0x80,0x35,0x27,0xBC,0x8D,0x22,0x2B,0x48, +0x2E,0x7C,0x12,0x2D,0xB9,0x12,0x7D,0x41,0x6C,0x77,0xEE,0x41,0x79,0xD3,0x3D,0x4D, +0xBD,0x3F,0x11,0xCD,0x2B,0x9D,0x95,0xF6,0x84,0x85,0x39,0x23,0xDE,0xA1,0xE9,0x8E, +0xE7,0xFF,0x38,0xA9,0xD1,0x2A,0x8B,0x56,0xB5,0xDA,0x3C,0xA1,0xA5,0x6B,0x5C,0x5B, +0x87,0x6B,0x1A,0x3E,0xEC,0xB8,0x8D,0x78,0x73,0x7F,0x29,0x5E,0x0D,0xC0,0x5C,0x60, +0x37,0x4C,0x7C,0x46,0x2B,0x08,0x83,0x09,0xBF,0xFB,0xA3,0xC9,0x51,0x4E,0x31,0x2B, +0x51,0xA6,0xDC,0x3C,0x04,0xDC,0xCA,0x93,0x6C,0x7D,0xEA,0x59,0xBA,0x70,0x5F,0x65, +0x8E,0xAF,0x30,0xEE,0x44,0x9C,0x6D,0x14,0x5B,0x03,0xF0,0x51,0x84,0x03,0x17,0x3A, +0x8D,0x9B,0xB6,0xC8,0x22,0xBF,0x1D,0x88,0x95,0xDA,0xDF,0x6B,0xF9,0xCC,0x91,0x42, +0xCD,0x64,0x1A,0x5B,0x7F,0x01,0xE3,0x45,0x26,0x67,0x0D,0xA7,0x2C,0x51,0x93,0xF3, +0xB7,0x11,0xB3,0x1F,0x9C,0x3C,0x9D,0x2C,0x3E,0xBD,0x7E,0xC7,0x17,0x48,0x2D,0xC1, +0x35,0x99,0xF1,0xCC,0xD1,0xDF,0x7B,0x00,0x5D,0x1A,0x27,0x44,0xEE,0xBD,0x3F,0xB4, +0x36,0x6E,0xAC,0xFF,0xFE,0x72,0xB6,0x9B,0x8E,0x75,0x0D,0x1F,0xD6,0x7A,0xC1,0xBE, +0xE5,0x73,0x4A,0xB4,0x56,0x61,0x77,0x3F,0xF1,0xCE,0x41,0xB3,0x32,0x8E,0x89,0x5E, +0xAA,0x4C,0x4F,0xCD,0xE2,0x70,0xDF,0x17,0x11,0x12,0x37,0x4B,0x1C,0x9D,0xFD,0x0D, +0x30,0xA1,0x5A,0x54,0x55,0x9D,0x8B,0x62,0x2B,0xCC,0xC7,0xD6,0x96,0x4B,0x62,0xF7, +0x3C,0xB8,0x5C,0x87,0x05,0xB9,0xA7,0x77,0x91,0x95,0x0A,0xE7,0x15,0x97,0x4C,0x33, +0xD2,0x63,0xBD,0x71,0x60,0x85,0x90,0x46,0xD7,0xC3,0xA7,0xA5,0xFD,0xC9,0x5B,0x13, +0x51,0xE6,0xEF,0x02,0xE6,0x05,0x17,0x2A,0xB6,0x2C,0xC7,0x77,0xD5,0xE5,0x0B,0x2F, +0x39,0x20,0xF6,0x4F,0xB6,0x98,0x1D,0x68,0xBE,0xD7,0xF9,0x0B,0x83,0x86,0x31,0x66, +0x8A,0x4C,0x8B,0x11,0x08,0xB3,0x0B,0xBE,0x7C,0x25,0xFF,0xE3,0xC2,0x64,0xC0,0xEE, +0x2C,0x7F,0x67,0x60,0xB7,0xD8,0xA9,0x99,0xFD,0x76,0x20,0x6C,0x2B,0x46,0x79,0xD2, +0xEF,0xEE,0xA4,0x0F,0xA6,0xF4,0xCE,0x6C,0xFE,0x8A,0xF1,0x09,0xC3,0x87,0x46,0x0B, +0xA4,0x84,0x8A,0x54,0xBF,0xA0,0xE4,0xEF,0xDC,0x2A,0x0D,0x61,0x88,0xE8,0xC2,0x20, +0x0A,0xFB,0x6F,0x8A,0xD4,0x5C,0xEB,0xE4,0x2A,0x79,0xD7,0xCA,0x18,0xBC,0xFE,0xDE, +0xA4,0x65,0x9E,0xC4,0x4A,0x07,0xD6,0xFF,0x02,0x2B,0x77,0x56,0x8D,0x01,0x1B,0x49, +0x8C,0x66,0xC2,0xBC,0x19,0x04,0x98,0xC1,0x56,0xAC,0xBD,0xA5,0x33,0x79,0x66,0xBB, +0x63,0x94,0x68,0x7D,0xFE,0x41,0x3C,0xA3,0xC9,0x9C,0xDE,0x53,0x3B,0x90,0x22,0x47, +0x4F,0x9A,0x50,0xAE,0xB0,0xED,0xFC,0xB6,0xE0,0xD0,0x3C,0x87,0x9B,0x69,0xEA,0x4B, +0xE8,0x6E,0xC0,0xAE,0x9B,0x02,0x44,0xC3,0x84,0x03,0x8E,0x4C,0x08,0x19,0x56,0x99, +0xD4,0x6F,0x4C,0x0A,0x3A,0x5E,0xC8,0x74,0xBE,0x3B,0x28,0xCA,0x1B,0x1E,0xED,0xEF, +0x93,0xF5,0xD5,0x81,0x96,0x92,0xDE,0xB2,0x77,0x54,0x53,0xF1,0x92,0xF7,0x3F,0x42, +0x3D,0x43,0x19,0x5D,0xD0,0xD3,0x73,0xE7,0xB5,0x32,0xB0,0xAF,0xCE,0x3E,0x6C,0xF5, +0xC2,0xEE,0xBF,0xC7,0x74,0xB9,0x4D,0x5F,0x46,0x72,0x6C,0x72,0x5A,0x53,0x80,0x32, +0x6C,0xC0,0x64,0xAA,0x05,0x90,0x8A,0x58,0x51,0x26,0xD7,0x70,0x51,0xAF,0x68,0xA2, +0xBD,0x04,0x95,0x05,0x48,0x87,0xAD,0xCF,0x74,0xA3,0x66,0x59,0xB9,0x2C,0x3A,0x5D, +0xEF,0x3B,0x12,0xF5,0x7E,0x37,0xCD,0x95,0xB7,0x14,0x73,0x11,0x85,0x4E,0xEB,0x1E, +0x3C,0xBE,0xD6,0xF4,0x61,0x1B,0x78,0xA4,0xF8,0xC6,0xFA,0xC9,0x24,0xCA,0xA8,0x5D, +0x3F,0x81,0x41,0x7E,0x20,0xFA,0xDA,0x45,0xA7,0xE9,0xB0,0x7C,0x4A,0x96,0xC4,0x84, +0xB2,0xE5,0x66,0x1A,0x14,0x6C,0x4E,0x6A,0x5A,0xE9,0xCB,0x62,0x4F,0xEE,0xEB,0xBE, +0xE7,0x40,0xC3,0xD0,0xD2,0x7E,0xBF,0x3A,0x9E,0x1F,0x2D,0xEA,0x23,0x64,0x6D,0xA4, +0xDB,0xA6,0x84,0xA3,0x2D,0x61,0xFB,0x99,0x54,0x4E,0x89,0xF5,0xBC,0x49,0x46,0xAC, +0xD8,0x41,0x79,0x92,0x1D,0x7F,0x0F,0xCD,0x55,0xAD,0xD1,0x99,0x35,0x00,0x1E,0x79, +0xB1,0xEE,0x39,0xBA,0xC1,0x6B,0x7C,0x01,0xB4,0x25,0x17,0xD4,0xAA,0x4B,0xFE,0xE4, +0xCF,0x48,0xFE,0x50,0x15,0x6A,0x40,0x03,0x23,0xC6,0xAD,0x70,0x84,0x35,0x8C,0x3B, +0xE5,0xEE,0x6B,0xD7,0x7B,0x7E,0xCF,0x18,0xAB,0x0A,0x85,0x71,0x6A,0xCD,0xE1,0xEF, +0xEA,0x80,0x57,0x2E,0x96,0xEC,0x77,0x03,0x09,0xB2,0x6E,0xE9,0xE3,0x94,0x38,0x20, +0xC9,0xB4,0xC3,0xC3,0xB6,0x9F,0xC0,0xB5,0xF6,0x80,0x0E,0x85,0x79,0x99,0xCB,0x8D, +0xE9,0x3A,0x62,0x3F,0x92,0x8C,0xB9,0xD0,0x7D,0x82,0x78,0xDC,0xEE,0x1B,0x0B,0xFC, +0xED,0x71,0x93,0x49,0xB6,0x18,0x6D,0x66,0x0E,0xE2,0xA0,0xC2,0x2C,0x3F,0xAD,0x49, +0xFE,0x45,0x8C,0x72,0xF1,0x60,0x80,0x28,0xC8,0xB3,0x62,0x5A,0x02,0xD6,0x92,0x3A, +0xB4,0xBE,0x89,0x30,0x27,0x6E,0xE1,0x77,0xA1,0x44,0x99,0x42,0x28,0xE5,0xEF,0x0F, +0xE9,0xB5,0xEE,0xC3,0xAF,0x21,0x04,0x59,0xA4,0xFC,0x12,0xC0,0x1A,0xB2,0x14,0x0C, +0x55,0x17,0x0E,0x74,0x63,0xFF,0xDA,0x3B,0x65,0x2C,0x27,0x66,0xF6,0x3C,0x5C,0x9B, +0xCF,0xA2,0xEB,0xC2,0x0F,0x7B,0x12,0x43,0x2E,0xDE,0x2D,0xE5,0x0A,0xFA,0xA6,0x6C, +0xEE,0x26,0x15,0xE3,0xDB,0x4C,0xA8,0xDE,0xB7,0xB0,0xCE,0xE3,0xBD,0xCB,0xCE,0x53, +0x91,0x81,0x64,0x33,0x9F,0x76,0x29,0x7E,0x7A,0xF6,0x38,0xE8,0x35,0x8D,0xFE,0xA8, +0x09,0xC8,0x69,0xC0,0x0F,0x8C,0xFE,0xCF,0xC6,0xFA,0x89,0x7C,0x35,0x8B,0xE8,0x46, +0xF7,0xCA,0xD6,0x80,0x47,0x8B,0xCB,0x80,0x45,0xDF,0xD9,0xCA,0x8B,0xDE,0x01,0xF1, +0x33,0x87,0x9C,0x62,0x5E,0xD4,0x64,0x67,0x7E,0x51,0xFF,0xDD,0x39,0x3C,0x4C,0x6A, +0xA5,0x45,0xE4,0x99,0xBF,0xBB,0xB9,0xC2,0xA7,0x9F,0x03,0x69,0x5F,0x99,0x71,0x2D, +0x20,0x3F,0xFF,0x22,0x7F,0x3A,0xFF,0x9F,0xAB,0xC6,0x21,0xFF,0xAE,0xE6,0x2E,0x84, +0xA1,0xE2,0xB8,0xE6,0x0C,0xA2,0x3F,0x94,0x6F,0x88,0x8F,0xA2,0x2D,0x20,0x27,0x2D, +0xEC,0x01,0x7F,0xC1,0x98,0xF2,0x7D,0xFA,0x28,0x32,0x49,0xDB,0xE5,0xC9,0x8B,0x3A, +0x28,0x04,0x20,0xEE,0x34,0x1A,0x03,0xA4,0x7B,0x6D,0x28,0xD8,0xF8,0x60,0xA6,0x43, +0x6A,0xCA,0x7B,0x02,0xB5,0xEE,0x26,0x64,0x55,0x82,0x4C,0x77,0x56,0xDB,0x00,0x29, +0xD0,0x95,0x1E,0x6D,0xEA,0xC3,0xAD,0xCA,0x62,0xFA,0xA0,0x1A,0x0E,0x07,0x01,0x31, +0xD1,0x1B,0x0D,0xF6,0xAD,0xB8,0x03,0xE8,0x22,0xF3,0x89,0xB0,0x11,0x1C,0xC1,0x27, +0xEF,0xC9,0xDF,0x52,0x3E,0x32,0xA3,0x3E,0x7B,0x60,0xBE,0x47,0x24,0x77,0x7A,0x60, +0x11,0x1F,0xC6,0x61,0x92,0xBD,0xE4,0x4D,0x70,0x44,0x21,0x40,0xA4,0x37,0x71,0xDB, +0x41,0x51,0x4C,0x2E,0x66,0x10,0x67,0xAC,0x06,0x17,0xA6,0x76,0x3A,0xF1,0xAC,0x02, +0x3E,0xD3,0x9E,0x4C,0xF7,0x12,0xF9,0xBD,0xA6,0xBD,0xFD,0x8C,0x9A,0x4A,0x57,0x2A, +0x2E,0x4E,0x81,0x22,0xD1,0x48,0x64,0x8E,0xB4,0x0C,0x21,0xFE,0x60,0x94,0xC3,0xF4, +0x4B,0xA2,0xC3,0x01,0x87,0x10,0xAC,0xB0,0x25,0xC2,0x61,0x55,0x37,0x6F,0x88,0x44, +0x1E,0xD3,0xDC,0xDA,0x88,0x30,0x76,0xDA,0x8F,0x64,0x7A,0x4D,0x6A,0x7B,0x7D,0x0E, +0xE8,0xDF,0xA5,0x19,0x73,0xDC,0x56,0x0B,0x6F,0xFD,0x6F,0x8C,0xA6,0x71,0xF0,0x6C, +0x9A,0x97,0x58,0xAD,0xB2,0xB6,0x7A,0x88,0xC2,0x17,0x91,0x14,0xE2,0xA5,0x43,0xC2, +0x29,0xDC,0xA4,0xA8,0x60,0x0A,0x7F,0xAE,0xC5,0x29,0x74,0x34,0x76,0x40,0x3E,0xCE, +0x4C,0xF2,0xDB,0xC5,0x15,0x0C,0xB6,0x91,0x79,0xB2,0x85,0x72,0xD1,0x27,0x3C,0x2D, +0xF8,0x41,0xFF,0xF9,0xD6,0x63,0x46,0x7F,0xD2,0xED,0x1E,0xAC,0x22,0x74,0x60,0xB5, +0x8E,0x39,0x9B,0xF0,0x6D,0xC3,0x62,0xA2,0xD2,0x32,0xF2,0x92,0x22,0xFA,0x21,0xB1, +0xA3,0x6A,0x4E,0xD3,0xCE,0x3B,0x4E,0x11,0x2F,0xCE,0x6D,0x45,0x85,0xFE,0x5C,0x67, +0x0F,0x14,0x56,0x92,0x10,0x50,0x72,0x08,0xDC,0xE6,0xC0,0xF8,0x98,0x89,0x51,0x50, +0xB0,0xA0,0x14,0x7D,0x81,0x1C,0x41,0x8C,0x00,0xD7,0xC7,0x50,0x9A,0x33,0x3C,0xFC, +0xCA,0x30,0x63,0xC5,0x6B,0xE4,0xD3,0x54,0xB0,0xEE,0xFD,0xD8,0x98,0x9B,0xB1,0x4C, +0x14,0x5F,0xD6,0x13,0x12,0xC8,0x5D,0x75,0x28,0x21,0x41,0xA1,0xA9,0x26,0xBA,0xA1, +0x8C,0x15,0x37,0x98,0x1B,0xD0,0x3C,0xC9,0xDF,0xA4,0xBC,0x9D,0xFD,0x74,0xC5,0xA3, +0x95,0xD1,0xF7,0x6D,0x26,0x33,0x20,0x12,0x1E,0xCC,0xAF,0x6F,0x1A,0xDB,0x1D,0x55, +0xEF,0xC4,0x9D,0x5D,0x41,0x04,0x93,0xBE,0x3D,0xBE,0x47,0x4F,0xA9,0x10,0x6B,0x4B, +0xFC,0xA3,0x1F,0x13,0xD6,0xBB,0x98,0xB6,0x44,0x54,0xE3,0x94,0x9C,0xAF,0x60,0xA6, +0xAD,0xF0,0x01,0x6D,0x1B,0x1B,0xF0,0x2F,0x60,0x68,0x4C,0xD5,0xA4,0x25,0x7D,0x21, +0x9B,0x26,0xBB,0xA1,0xF4,0x60,0x41,0x7B,0x72,0x79,0x02,0x70,0x6B,0xCB,0x41,0x49, +0x07,0x5B,0xAB,0x69,0x22,0xE8,0xBE,0x64,0x5B,0x04,0x36,0x9C,0x14,0xFE,0xEB,0xDF, +0x23,0x69,0x07,0xFB,0x00,0xBF,0x6C,0x78,0x96,0x07,0xF0,0x74,0xD5,0x2B,0x94,0x95, +0x71,0x49,0x46,0xDE,0x07,0xC4,0xE7,0x54,0xED,0x1F,0xAB,0x62,0x62,0x1C,0xF0,0x2D, +0x73,0x4C,0x6D,0xE9,0xAD,0xFD,0x7A,0xD6,0x57,0x3E,0x9C,0xD1,0x13,0xFC,0x4B,0xD8, +0xDB,0xAD,0x1B,0x4C,0x87,0xE8,0xB7,0x33,0xFA,0x56,0xF9,0x87,0x61,0x85,0x33,0x30, +0x5F,0x47,0x31,0x65,0xF2,0x7D,0x5B,0xAD,0x75,0x28,0x57,0x41,0x4E,0x74,0x1F,0x22, +0x98,0x43,0xC9,0xB9,0x17,0xE9,0xC9,0xFB,0x96,0x5F,0x68,0x1D,0x88,0x3E,0x43,0x6F, +0xD7,0x27,0x4D,0x6C,0xE3,0xE0,0xA3,0x2C,0x99,0xF3,0xA7,0xDD,0xED,0xA6,0x93,0x03, +0xA6,0xEE,0xEE,0x38,0xDF,0xB6,0xAB,0xA2,0xF6,0xE9,0x97,0xEF,0x74,0x99,0xD5,0x7F, +0x65,0x8B,0x36,0xE5,0xD7,0x9E,0x03,0xCA,0x13,0xC9,0xC8,0x35,0x8D,0x90,0x62,0xA4, +0x48,0xFE,0x34,0x8E,0x08,0xEF,0x27,0x5F,0x79,0xA6,0x3E,0xBE,0x87,0x0F,0x2D,0x51, +0xE9,0x33,0xCE,0xA5,0x6F,0x77,0x86,0x4C,0xD0,0x86,0x6F,0x81,0x40,0x0A,0x92,0x73, +0xE6,0x38,0x76,0xA6,0xBD,0xC2,0xF5,0x58,0xC8,0xAC,0x3F,0x8E,0x3C,0x23,0xC6,0xFD, +0x36,0x52,0x27,0x02,0x34,0xE7,0xB4,0x9D,0xD2,0x4D,0x33,0x24,0x38,0x5E,0xDF,0x63, +0xFC,0x5C,0x55,0x4C,0xEE,0xC2,0x01,0x90,0x97,0x80,0xCD,0x67,0xEB,0x03,0xC0,0x38, +0x7D,0xF9,0xA8,0x0E,0x11,0xC6,0x27,0x68,0x95,0x11,0x03,0x1C,0xD1,0x02,0x14,0xCC, +0xE8,0x80,0xF5,0x38,0x8B,0x81,0x48,0x79,0x13,0x89,0x98,0x20,0xAE,0x29,0x4F,0x59, +0xC7,0x76,0xE4,0x3A,0xE2,0x1B,0xF7,0x9D,0xFD,0xED,0xB0,0xA1,0x87,0x06,0x58,0xC5, +0x9F,0x27,0xC9,0xA1,0xB2,0x7A,0xB0,0x8D,0x3D,0x4D,0xD4,0xB8,0xD4,0xFA,0x3C,0x19, +0xEC,0xDA,0x56,0x6D,0xA1,0x11,0x5D,0x85,0xDC,0x86,0x5D,0xD2,0x0F,0x37,0x2A,0xF2, +0x4F,0xC9,0x33,0xAF,0x55,0xCA,0x92,0x56,0xE1,0x69,0x84,0xF4,0x8E,0x9D,0x6C,0x0C, +0x76,0xFB,0xE8,0x40,0xDC,0x6E,0xDF,0xDC,0x4A,0x4A,0x44,0x65,0x25,0x39,0xA7,0xDB, +0x7C,0xC6,0x5C,0xA0,0xC7,0x17,0x76,0x1A,0x63,0xBE,0xB1,0x92,0xB5,0x08,0x11,0x39, +0xE0,0x7B,0xB0,0x0A,0xC1,0x78,0xE1,0x5E,0x48,0x1A,0x2A,0x0D,0xBE,0x94,0x6F,0x94, +0x0E,0x14,0x46,0x8D,0xDB,0xCC,0x7D,0x91,0x9E,0xBB,0xB2,0xE1,0x42,0x45,0x87,0x3C, +0x8A,0x5A,0xB8,0xF7,0xEC,0xEB,0x8D,0x8B,0x73,0xA8,0x29,0x5A,0x71,0xE3,0x34,0x59, +0x2E,0x52,0x3A,0x69,0x53,0xFC,0x92,0x02,0x67,0x94,0x54,0xB7,0x7F,0x26,0xE9,0x24, +0xB7,0x8A,0x86,0x43,0x17,0xD2,0x87,0x76,0x66,0xCB,0x65,0x62,0x46,0xC9,0x8C,0x90, +0x7E,0xDF,0x28,0x38,0x60,0xB3,0x44,0x41,0xE1,0xEE,0xB3,0x00,0x8D,0xEE,0xBF,0x3B, +0x2D,0x6A,0xA9,0x34,0x86,0x42,0xB9,0xB6,0xF5,0x4B,0xC6,0xA6,0x01,0xC8,0xBE,0xC0, +0x7A,0x3E,0x9A,0x97,0x3F,0x38,0x7A,0x5F,0xDC,0xF1,0xCF,0xCF,0xF0,0x6E,0x33,0xF9, +0x0C,0xAE,0x3F,0x3A,0xAB,0xEA,0xA4,0x68,0xDB,0x0A,0x50,0xE1,0x15,0xD8,0xB0,0x87, +0x0A,0xE4,0xEA,0xEC,0x26,0xD2,0x09,0x7A,0x51,0x9D,0x6C,0xB1,0xF1,0x27,0x36,0x7B, +0x6E,0x7E,0x9D,0x64,0x1E,0xE3,0x98,0x3D,0xB9,0xB8,0x7E,0x2D,0x1E,0x58,0x7B,0xD5, +0x99,0xCA,0x0F,0x62,0x2C,0x5E,0x8B,0xAB,0x70,0x41,0xDC,0x00,0x1D,0x2B,0xCB,0x0D, +0xF9,0x44,0x3B,0xBF,0x4D,0x63,0xA7,0xCC,0x73,0xC4,0x2B,0xED,0xC8,0x45,0x74,0x49, +0x92,0xFE,0xAC,0xCF,0x49,0x54,0x68,0x6F,0x9C,0xBF,0x94,0x14,0xE7,0x3B,0x2B,0xD8, +0x34,0x33,0xAE,0xB7,0x91,0x7A,0xF2,0x77,0x44,0x73,0x7C,0x00,0xED,0x83,0x82,0x28, +0x44,0x20,0xE0,0x4E,0xB6,0x77,0x01,0xA3,0xF9,0x40,0x21,0x02,0x76,0x40,0x9A,0x64, +0xB8,0x47,0x8D,0xCF,0x41,0x14,0xFB,0x0B,0x89,0xFF,0x62,0x65,0xD9,0xF0,0x21,0xB6, +0x5A,0x8A,0x1F,0x6E,0xBB,0x95,0xC9,0xE8,0x19,0xE4,0x45,0x8B,0xC8,0x67,0x5B,0x98, +0x4D,0x54,0xD2,0x07,0x33,0xCB,0x69,0xB8,0xA7,0x33,0x2C,0xC0,0xD0,0x07,0xE3,0xE9, +0x31,0x57,0x1A,0xC8,0x45,0x74,0x6C,0x25,0xA4,0x60,0x66,0x2F,0x9A,0x99,0x61,0x08, +0x8F,0xDF,0xFC,0x55,0xEF,0x86,0x16,0x32,0x64,0x7F,0x18,0x8D,0xE1,0xE8,0xF3,0x71, +0x34,0x46,0x4D,0x80,0x49,0x8B,0x7C,0x39,0x15,0x5F,0x66,0x96,0x83,0x48,0xA0,0xCC, +0xC7,0x7A,0x08,0x81,0x29,0x74,0xD5,0x8F,0x48,0x93,0x30,0xD8,0x2C,0xC3,0x39,0xBA, +0x7D,0xF6,0xD4,0xBF,0xF0,0xB0,0x4A,0xAB,0x56,0x63,0x92,0x6E,0x35,0x28,0x58,0x8E, +0x0E,0x5F,0x13,0xF7,0x17,0x0C,0x4A,0x18,0x11,0x51,0x06,0x2B,0x2F,0xE4,0xFD,0x51, +0xD2,0x5F,0x21,0x9A,0x18,0xC9,0x2C,0xD0,0x06,0xF3,0x8B,0x33,0xEF,0xBF,0x4C,0x42, +0xBE,0xB9,0xF9,0x34,0x7A,0xCF,0xCA,0x4D,0xB6,0x9C,0x88,0x4A,0xC0,0xFA,0xC9,0xE8, +0x82,0x50,0x7B,0xC0,0x6A,0x61,0x32,0x98,0xE4,0xB9,0xE7,0xF1,0x64,0xCA,0x09,0x15, +0xAA,0xAF,0xD8,0x08,0x9F,0xA9,0xEA,0x8A,0xA9,0xE4,0xEB,0xFE,0xFA,0x2A,0x0C,0x90, +0xBF,0x77,0xB4,0xDA,0x4B,0x9F,0x80,0xE6,0x5C,0xC4,0x1E,0xC4,0x9F,0x92,0x6D,0x68, +0x3D,0xEC,0xCB,0x80,0x3A,0xCE,0x9B,0x28,0x7F,0x4F,0xB9,0x6C,0x73,0x31,0x39,0x62, +0xA9,0xC7,0xF1,0x7C,0xDF,0xA4,0xDE,0x4C,0x77,0x11,0xE9,0x1A,0x6E,0x29,0xFC,0x4C, +0x42,0xDC,0x60,0x6D,0x66,0x52,0x85,0xB3,0x3D,0xC0,0x4A,0x5A,0xEA,0xBE,0x48,0x79, +0xAC,0x5C,0x92,0x2B,0x62,0x3C,0x87,0x2E,0x21,0xDD,0x09,0x25,0xB3,0xCD,0x51,0xFF, +0x05,0x4F,0x91,0x54,0xD5,0x8D,0xE4,0x24,0xD9,0x3E,0x82,0xDD,0xF5,0x27,0x2A,0x25, +0x6D,0xA5,0xC2,0x47,0xA8,0xBD,0x7A,0x1E,0x2B,0xAB,0x20,0x19,0x84,0x54,0x3C,0x56, +0x37,0x93,0x95,0x62,0xCF,0x2F,0x1E,0xD5,0x5D,0x73,0xFA,0x78,0x46,0xC0,0x8A,0x6B, +0xE0,0x92,0xA2,0x9E,0xBA,0x8A,0x5C,0xEC,0x8F,0x16,0x6F,0xEC,0x1C,0x3A,0xA3,0x3C, +0xA9,0x77,0xC3,0xD2,0x4B,0x58,0x33,0xFC,0xFA,0xAC,0x90,0xF3,0x87,0x4B,0xAE,0xC6, +0x2E,0x69,0x63,0xB9,0xEB,0x62,0xC1,0xAA,0x05,0xE9,0xF6,0xEC,0x58,0xA4,0x07,0x10, +0x55,0xBC,0x6D,0xE8,0x44,0x44,0x08,0x39,0x3E,0x09,0x79,0x2A,0x0E,0xF0,0x87,0x62, +0x1D,0x58,0x8A,0x03,0x94,0xBF,0x8A,0x51,0x20,0xC8,0xF4,0xE7,0x04,0x9A,0x13,0x7C, +0xCC,0x06,0x61,0x8E,0x91,0xF0,0x60,0x80,0xD9,0x67,0xB8,0xA0,0x5A,0x75,0xCB,0xE4, +0x30,0xDE,0x00,0x6A,0xCD,0xDA,0x17,0x86,0xE6,0xBD,0x3A,0xE5,0x7A,0xDC,0xCC,0x6A, +0xC5,0x9B,0x7A,0x38,0x53,0xA3,0xC5,0xB0,0xF9,0xC8,0x88,0xF5,0x70,0x2A,0x86,0x84, +0x11,0xE3,0x93,0xF8,0x54,0x33,0xB4,0x86,0x66,0x29,0x6F,0x8C,0x27,0x24,0x6D,0xD1, +0xD8,0xF1,0x71,0xBF,0x39,0xFA,0x74,0xFA,0x9E,0x9B,0x26,0x5B,0x41,0x5F,0x82,0x53, +0xCF,0xBE,0x9A,0x83,0x48,0xF7,0x28,0x23,0xB2,0xBD,0x15,0x6F,0xFB,0xA0,0xEC,0xD4, +0xAF,0xD3,0x8A,0x95,0x60,0x6D,0x2A,0xEA,0x20,0xC6,0x87,0x54,0x77,0x66,0x55,0xB1, +0x96,0x1A,0x55,0xE6,0x21,0x4F,0xAB,0xF8,0x12,0x2B,0x22,0x83,0xA7,0x2D,0xA1,0x1D, +0x0E,0x26,0x1A,0x37,0xD4,0x6D,0xD9,0xCB,0x57,0xA2,0xDE,0x2B,0x3A,0x97,0xD4,0x26, +0x6E,0x6E,0x7D,0x03,0x14,0x1D,0xC6,0x30,0xEE,0x7F,0x56,0x33,0x8B,0x6C,0xEF,0x8F, +0xFA,0x8D,0x7A,0x3E,0xEC,0x6F,0x0B,0xC8,0x03,0xB1,0xDF,0x16,0xAA,0xFA,0xE1,0x07, +0x61,0x8C,0x9B,0x97,0xFE,0x4B,0xE4,0x38,0xF9,0x77,0xE4,0xD1,0x92,0x6D,0x10,0x34, +0x56,0x82,0xE2,0xF5,0xFC,0x53,0x07,0xA8,0x42,0xFE,0x53,0xEC,0x94,0xBD,0x62,0x41, +0x06,0x70,0x19,0x50,0x55,0xD9,0xBE,0xD3,0xF0,0x22,0xC0,0xDD,0x2C,0xCB,0xE9,0x33, +0x23,0x85,0xAF,0x3E,0x40,0xA5,0x8E,0x5A,0x85,0xCB,0x39,0x9D,0xB0,0x5E,0xFD,0xA7, +0xF1,0x1E,0x2E,0xC9,0x2B,0xD1,0xC3,0x86,0x98,0x27,0x6F,0xAB,0x52,0x78,0x9E,0x18, +0x54,0xCA,0xFB,0x88,0xD2,0x03,0x39,0x05,0xC9,0xDA,0xD9,0x68,0x2A,0x8B,0x6E,0x4B, +0x0B,0x01,0xD5,0x93,0x1B,0x93,0x6B,0x97,0x97,0x96,0x01,0x67,0x52,0xEE,0x91,0x70, +0xBC,0xC1,0x56,0x5B,0x1C,0x4C,0x28,0xF3,0xC8,0x63,0x83,0x97,0x8D,0xFF,0xCE,0xC9, +0xFF,0x53,0x47,0x23,0x6A,0x54,0x62,0xFD,0x80,0x72,0xF1,0xC3,0xFA,0xF9,0xBC,0x2A, +0x55,0xC0,0x50,0xAF,0x4C,0x71,0xA0,0xF3,0xAE,0x5C,0x6C,0xC6,0xC8,0xF8,0x3D,0xC7, +0xB9,0x75,0xD0,0xA2,0x22,0x0F,0x25,0xC9,0x0C,0x25,0x32,0x6C,0xD4,0x40,0x6D,0xA9, +0xDE,0xA2,0xDD,0xAB,0xEC,0x71,0xBB,0xC7,0x6C,0x18,0x5F,0x43,0x00,0x47,0xEF,0x9C, +0xA7,0xCC,0xAE,0x9A,0x7F,0xEF,0xA0,0xDE,0x24,0x70,0x80,0x92,0x83,0x19,0x69,0x03, +0x0E,0x20,0x64,0x21,0x60,0xE0,0xD7,0x46,0x14,0xCE,0xBF,0x7A,0x72,0xA5,0xC6,0x09, +0xFC,0xEC,0xC8,0x1C,0x4D,0xE6,0xD3,0x96,0xEE,0xEE,0x8F,0xB7,0x73,0xEB,0x27,0xA3, +0x01,0xC2,0xCF,0x04,0xD2,0x27,0x77,0xB8,0xD7,0xDD,0x78,0x54,0x03,0xB8,0x39,0x06, +0xB8,0x41,0x99,0x74,0x9E,0xA5,0x5E,0xA9,0xD9,0x67,0xA5,0x4F,0xD3,0xF3,0x8C,0x32, +0xEF,0x7B,0x9C,0x2A,0x35,0x90,0x53,0x9D,0x68,0xB1,0x23,0xD8,0xA3,0x81,0x0C,0x41, +0xF0,0x3A,0x57,0x8F,0xC3,0x57,0x4A,0x4F,0xCA,0xF6,0xD4,0xEB,0x41,0xD2,0x47,0xBA, +0xFD,0xAB,0x84,0xBF,0x4E,0xC6,0x29,0x7F,0xC7,0xF5,0xFC,0x95,0x0F,0x91,0x31,0x89, +0xEA,0x6E,0xF7,0xA3,0xA3,0x57,0x8B,0x9C,0x33,0xFD,0x31,0x77,0x25,0x74,0xB5,0x74, +0x8A,0x0A,0x3E,0x5B,0xEE,0x04,0x59,0xED,0x73,0x4B,0x8C,0xDC,0xDB,0x3C,0xDD,0x4C, +0x54,0x41,0x6B,0xDE,0x97,0xB8,0x23,0xB7,0xF6,0xC3,0x47,0x3F,0xE6,0xDA,0xB9,0xFC, +0x8E,0x87,0x3D,0x6F,0x04,0xBD,0x22,0xB8,0xF4,0xD0,0x5D,0xC5,0x78,0x7E,0x8F,0x04, +0xB2,0xB1,0x21,0x04,0xE2,0xBA,0x96,0xB4,0x66,0x65,0x03,0xE6,0xFF,0x8E,0x77,0x6E, +0x46,0xB2,0xC7,0xD9,0x3F,0x26,0xCC,0xAD,0x28,0x78,0x22,0xD1,0xFC,0x0E,0x37,0x61, +0x06,0xEE,0x1D,0x4F,0x16,0x27,0xCF,0x79,0x42,0x02,0x69,0x0B,0x60,0xC2,0xC9,0xD9, +0xD0,0x84,0x72,0xFB,0xFA,0xD5,0x59,0x41,0x8F,0x5E,0x5C,0x99,0xB9,0x63,0xD3,0x45, +0x85,0x8B,0x54,0xC1,0x19,0x0D,0x0D,0x2B,0x1E,0xD3,0x49,0x4C,0xF4,0x6A,0x17,0x68, +0x65,0x4B,0xB0,0x92,0x8A,0x99,0xBB,0x88,0xB1,0xCC,0xA5,0x35,0xF1,0x06,0x4E,0x93, +0x75,0xE9,0x55,0xB3,0x8F,0x42,0x9E,0x86,0x7A,0xB0,0x2E,0x05,0xD4,0x45,0x55,0xFC, +0xA1,0x4E,0xC0,0x20,0x61,0x43,0xB4,0x12,0x9C,0xE9,0x57,0xCE,0xCC,0x9E,0x78,0x87, +0x4E,0x69,0x59,0x2F,0xA0,0xD2,0xF3,0x7C,0xD8,0x66,0x14,0xCA,0xBA,0xC0,0x74,0x1C, +0x1E,0x27,0xB5,0x80,0xA0,0x95,0xED,0x2D,0x5E,0x6E,0x88,0x3F,0x30,0x2B,0xE7,0x6F, +0xCB,0x21,0x65,0x28,0xA3,0x4A,0x00,0x14,0xEF,0x02,0x41,0x38,0xC3,0x04,0x44,0xEB, +0xB0,0x00,0x98,0x1E,0x83,0x2C,0x42,0x8A,0x2F,0x53,0x6B,0x4B,0xAC,0x06,0x6D,0x0B, +0x21,0xB0,0x31,0x2B,0x63,0x2D,0x13,0x09,0x84,0x05,0xA3,0xEF,0x35,0xE7,0xD4,0x5F, +0xA2,0x07,0xEC,0xBD,0x0C,0xE4,0xFE,0xB9,0x60,0x82,0x26,0x38,0x45,0xE6,0x05,0x4F, +0x3A,0x23,0xE0,0x17,0x39,0x08,0x20,0x4A,0x6C,0x28,0x30,0x87,0xC7,0x8C,0xE3,0xFA, +0xF1,0x8F,0x49,0x3E,0x32,0xE9,0x4D,0xF8,0x1C,0x28,0x1B,0xE4,0xFF,0x7D,0x59,0x19, +0x1D,0x2F,0x31,0x4C,0x40,0x8E,0x19,0x09,0x00,0xAA,0x89,0x2F,0x86,0xF4,0x47,0x77, +0x22,0x10,0xA3,0xE8,0x18,0xAE,0xFB,0xC0,0x5F,0x81,0x45,0xC6,0x46,0x91,0x6F,0xA8, +0x90,0xF6,0x52,0x82,0x7B,0x42,0xFE,0xF8,0xE5,0x74,0x7D,0x89,0x59,0xCD,0x30,0x77, +0xAB,0x10,0x24,0x21,0x37,0xC0,0x78,0x8A,0x6D,0x9F,0xB3,0xD0,0xF0,0x81,0x07,0x96, +0x21,0x76,0x1A,0x2F,0x27,0x08,0xF7,0xB9,0x6E,0x66,0x0D,0x99,0x30,0xE7,0x5A,0xFA, +0x90,0x59,0xBC,0x85,0x98,0x3C,0xD8,0xCA,0xF4,0x07,0x94,0x64,0xD6,0xCD,0xE2,0xDA, +0x92,0x1C,0x69,0x7F,0x19,0x57,0x1B,0x0B,0x17,0x9E,0x06,0x9D,0xC2,0x54,0x09,0x5E, +0xA3,0x47,0xCC,0xB6,0x5B,0xCC,0x58,0x5C,0xE4,0x75,0xCB,0x3F,0xB7,0x3B,0x05,0xA8, +0xCC,0xCE,0xE9,0x6E,0xEF,0x59,0xEF,0x7D,0x07,0x36,0x2E,0x15,0x4C,0x53,0x30,0x93, +0xCF,0xFB,0x03,0xA6,0x24,0x4F,0xFC,0x28,0xC9,0xA1,0x1C,0x15,0xB4,0xE4,0x31,0x28, +0xE8,0x08,0xCB,0x40,0x6C,0x82,0xFC,0x4E,0x38,0x0E,0x70,0xD5,0x2B,0x9C,0x4A,0xC3, +0x43,0x4B,0xB1,0xF0,0xA7,0x52,0xE0,0xBC,0x40,0xA8,0x72,0x29,0xB2,0xAF,0xC4,0xD2, +0x88,0x05,0x20,0x69,0x27,0x67,0xAA,0xC2,0xE6,0xC0,0xCC,0x87,0x47,0x7E,0xB6,0xA2, +0xC1,0x86,0x80,0x59,0xBE,0xC6,0xB6,0x4F,0x64,0x21,0xF8,0xEA,0xB8,0xB2,0x9F,0x17, +0x0E,0xD6,0x0A,0xCE,0x3E,0xEB,0xF0,0xCE,0x05,0x23,0x34,0x5B,0x65,0x5C,0xBE,0x38, +0x78,0x05,0x28,0x8C,0x4E,0x38,0x28,0x6F,0x64,0xBE,0x49,0x89,0x85,0x3E,0x17,0xEB, +0x25,0xC7,0x3D,0x76,0x39,0x02,0x21,0x8E,0xBD,0xE2,0xCB,0xB3,0xEC,0x4E,0xCE,0x88, +0x74,0xA9,0x47,0x73,0x7B,0xA0,0xC6,0xE6,0xFA,0x06,0x76,0x75,0x97,0xB6,0xA2,0xD5, +0xC7,0xAA,0x49,0xD2,0x0C,0x1A,0xC1,0x04,0xDA,0xE3,0x49,0xEA,0xFE,0xCC,0xD6,0xF8, +0x3D,0xDB,0xE1,0xD9,0x42,0x0B,0xEF,0xCD,0xFA,0xEC,0x96,0xB2,0xD6,0xC3,0xF2,0x21, +0xE6,0xF7,0xAA,0x1C,0xD4,0x2A,0xD6,0x52,0x59,0xCA,0x0B,0xBD,0x7D,0x56,0x00,0x71, +0xF7,0x84,0x5C,0x24,0x79,0xA0,0x50,0x65,0x53,0xB0,0x5F,0x8B,0x0F,0xFA,0xE5,0x0E, +0x10,0x1F,0x79,0xD3,0x78,0x7B,0xC1,0xF3,0x64,0xF6,0xC7,0x0D,0x51,0xCD,0x0A,0x81, +0x1C,0xA1,0xFC,0x7F,0xBD,0x3D,0x15,0x23,0x40,0xA2,0xC8,0x47,0x9A,0x45,0x83,0x83, +0x08,0xD3,0x75,0x03,0x11,0xEC,0xAF,0x3D,0xEC,0xA5,0x6F,0x24,0x37,0xC1,0x83,0xEB, +0xA5,0x35,0xB2,0x63,0xB7,0x55,0x14,0xDC,0xDA,0x04,0x4C,0x72,0x4D,0xDE,0x43,0x0A, +0xF6,0x21,0x50,0xBD,0xDA,0xC5,0x0C,0x73,0x62,0xCD,0x23,0x0A,0x35,0xED,0xF3,0x50, +0x39,0x16,0x34,0x25,0xC6,0xFD,0x00,0xC8,0xB2,0x5B,0x79,0xFD,0x6D,0xAD,0xC9,0x53, +0xAD,0x1B,0x4D,0x6E,0xE6,0x5D,0x07,0x21,0xD1,0x09,0xA8,0x0C,0x66,0x7B,0xE5,0x05, +0x23,0x55,0x45,0x3C,0xC4,0xB2,0x91,0x14,0x69,0x53,0x05,0x33,0xD9,0x2C,0x0A,0x48, +0xAD,0x55,0x13,0xEE,0x6F,0x98,0xEA,0xFD,0x45,0xF8,0xC6,0xE4,0x23,0xCD,0x5E,0x7C, +0x94,0x2F,0x06,0x8E,0x60,0xCF,0x60,0x27,0x6A,0xEA,0xC3,0x9E,0x86,0xF9,0x84,0x24, +0x49,0xA3,0x99,0x6D,0x7A,0xF0,0x92,0xE6,0xB6,0xC8,0xB1,0xAA,0xC7,0x1C,0xA6,0xCA, +0x65,0x76,0xBC,0x5F,0xD5,0x7F,0x0C,0x65,0x91,0x37,0x73,0xB8,0xAB,0xDE,0x38,0x71, +0x97,0x7E,0x32,0x8D,0x47,0x0D,0xE5,0xB4,0x9A,0x8B,0x24,0xC3,0x46,0xAA,0x66,0xDD, +0xBE,0x0C,0xA9,0x29,0x4C,0x8B,0xB8,0xFF,0x57,0xF2,0xFA,0x3B,0xB5,0xEA,0x13,0x0C, +0x43,0x49,0x08,0xD7,0x18,0x4F,0x2D,0xBB,0xB3,0xD3,0xFE,0x0E,0xE0,0x3B,0x15,0xB4, +0x90,0xFC,0xF0,0x29,0x27,0xFF,0xB4,0x09,0x3A,0xBC,0x92,0xBB,0xE6,0x03,0x71,0x58, +0x3C,0xEC,0x2B,0x6C,0x17,0xD2,0x68,0x0F,0x48,0xCB,0xFF,0xE3,0xB0,0xC9,0xD3,0x11, +0x6E,0x41,0xC5,0xF9,0xA2,0x7C,0xB3,0x6A,0xC2,0xEF,0x6F,0x4C,0xBE,0x03,0x2E,0xE8, +0xA9,0xFD,0xC0,0x60,0x5B,0x4F,0xCC,0xCA,0x61,0xCF,0x88,0x1D,0xA4,0x63,0xDA,0x97, +0xEC,0x11,0x8C,0x99,0xD6,0x6A,0x47,0x90,0x19,0xE6,0x33,0xDD,0x12,0x03,0xBE,0x8D, +0x12,0x7C,0xB8,0x42,0xB4,0xC9,0x37,0x37,0x17,0xDA,0x48,0xAC,0xF5,0xCF,0x66,0xB8, +0xCE,0xBE,0xB3,0x16,0x47,0xB2,0x28,0x68,0x22,0x7C,0x50,0xC2,0x64,0x86,0xBF,0x82, +0xCD,0x11,0xCA,0xB3,0x66,0xD9,0x79,0xAE,0x34,0x1B,0xAD,0xEE,0x1A,0x54,0x53,0xD7, +0xD9,0x32,0x38,0x88,0xA9,0x9F,0x7D,0x20,0x7C,0xA0,0x2F,0x55,0x88,0x88,0x5A,0xB4, +0x26,0xFC,0x0A,0x2E,0x22,0xF2,0x64,0xF6,0xDE,0xC5,0xB1,0x29,0x29,0x03,0xF4,0xE8, +0xE1,0x1E,0x43,0x9E,0x03,0x90,0x78,0xB7,0x79,0x79,0xC4,0x21,0xC4,0x0B,0x65,0x99, +0x68,0x9B,0x9C,0x0F,0x1C,0x3D,0x64,0x2A,0x22,0x50,0xE3,0x8F,0x0F,0xDB,0x52,0x14, +0x2C,0x84,0xE7,0x09,0x82,0x58,0x11,0xCD,0x6D,0x08,0x22,0x40,0xE1,0xBA,0x10,0xF2, +0x0A,0x5E,0xBA,0xA8,0xEC,0x0E,0xF8,0x15,0x19,0x55,0x4B,0x45,0x81,0x7B,0x68,0xE2, +0xE6,0x52,0x20,0x75,0xB9,0xAA,0xA8,0xE3,0xA2,0x30,0x8F,0x77,0x1E,0x61,0xCC,0xC6, +0x19,0x6F,0xBF,0xE0,0x51,0xE8,0xB8,0x0E,0xDA,0xD6,0xD6,0xA6,0xC8,0xCF,0x05,0x39, +0x31,0xC2,0x00,0x4C,0x9B,0xA9,0x39,0x90,0x04,0xE4,0x4D,0x38,0x1A,0xE3,0x24,0xD7, +0x7D,0xAF,0x3B,0x46,0xF6,0xE4,0x8C,0xFE,0x76,0x00,0xED,0x40,0x73,0x34,0x5D,0x6E, +0x4D,0x8A,0x4A,0xB5,0x36,0xCB,0x32,0x67,0x7E,0x6A,0x99,0xCE,0xB5,0x25,0x33,0x21, +0x7F,0x4B,0x68,0x1B,0x50,0xF5,0x20,0x7C,0x5D,0x2D,0x13,0xD5,0xDC,0x32,0x3A,0x6D, +0x0C,0x86,0xB1,0xC9,0x78,0x71,0x7C,0x94,0xCA,0xD6,0x9F,0x2F,0x31,0x9F,0xAF,0x74, +0x06,0x37,0x80,0x55,0x0C,0x6C,0x81,0xD5,0xE8,0x2A,0x0F,0x3B,0xB7,0xBF,0x34,0xAC, +0xB1,0x14,0x13,0xE2,0x74,0x0B,0xA3,0x32,0x15,0x0D,0xF9,0x70,0xD9,0xD5,0x63,0x47, +0x62,0xF5,0xBA,0x54,0x8B,0x98,0x06,0x8A,0xD6,0xCA,0x53,0x2E,0xA1,0xD7,0x98,0xA2, +0xE2,0xC1,0xF7,0xED,0xE4,0xE7,0x5C,0x7D,0x51,0x32,0xDB,0xE5,0x76,0xE6,0x3E,0x4A, +0x43,0x59,0xC3,0x4B,0x34,0x4F,0xC1,0xF7,0xA0,0x90,0xF8,0xF9,0x6F,0x85,0x1C,0xB7, +0xC7,0x2F,0x32,0x46,0x1B,0xC4,0xFD,0x2D,0xF6,0xCA,0x6A,0x98,0xD3,0xEF,0x2A,0x72, +0xAF,0xF2,0x59,0x5E,0x4E,0x30,0x1F,0x14,0xA6,0xBB,0x97,0xC9,0x3E,0xEB,0x71,0x01, +0x60,0x46,0x47,0xFD,0xB4,0x21,0xB0,0xF1,0xF7,0xBA,0xF8,0xC2,0x3B,0x4B,0x4F,0x0F, +0x44,0xC4,0x8B,0x58,0x5E,0xA4,0x34,0x5A,0x78,0xC5,0x37,0x95,0xE5,0x09,0xFE,0x6A, +0x65,0x9F,0x3B,0x3C,0x06,0x6B,0xA6,0x13,0xE5,0xEF,0xB5,0x8A,0x34,0xAB,0x20,0x1C, +0x10,0x7D,0x52,0xC7,0x90,0xFD,0xDF,0xA9,0x1C,0x01,0xE0,0x58,0x05,0x1F,0x18,0x6E, +0x10,0xD7,0xDB,0x14,0x23,0x6D,0x32,0x14,0xF9,0xB8,0xA0,0xCC,0x24,0x17,0x03,0xDF, +0x3A,0xAF,0x90,0x19,0xF1,0xBE,0x5E,0xD0,0x1C,0x7D,0x47,0xEA,0x25,0x8F,0xBA,0x8B, +0xA2,0xD3,0xA6,0x0B,0xA9,0x4B,0xC3,0xA3,0x38,0x0D,0x28,0xFE,0x86,0x92,0xCD,0xAD, +0x3C,0xE9,0xAE,0x37,0x9D,0xB7,0xA9,0x3C,0x11,0x81,0x4B,0x2F,0x9A,0xA7,0x00,0x04, +0x85,0x04,0x2F,0x01,0x5B,0x0F,0xF3,0x4F,0xD6,0xCC,0x6F,0x8D,0x50,0xA0,0x12,0x4C, +0x1D,0xA4,0x94,0xC6,0xB6,0xE8,0x40,0x02,0x4B,0x2D,0xD7,0x54,0xB9,0x15,0x2F,0xB1, +0x17,0x95,0x65,0xE7,0x50,0x77,0x5B,0x03,0x7C,0xA7,0x38,0xEC,0x9F,0xAC,0x55,0x0E, +0xF5,0x2D,0xA2,0x81,0xE4,0xF8,0xE1,0x7E,0xB8,0x90,0x02,0xAA,0x43,0xE9,0x18,0xBE, +0xF7,0x95,0x64,0x09,0xE1,0x11,0xE6,0xF6,0x0E,0xD4,0x1E,0x10,0x21,0xD8,0xD2,0xEA, +0xDE,0x63,0x33,0x3B,0x0C,0x5A,0x4E,0xF0,0x55,0x2C,0xC3,0xD0,0xD5,0xE5,0xA5,0x2D, +0x01,0xD8,0xBA,0x6C,0x5F,0x7C,0xC7,0x7E,0x4D,0x23,0xB0,0x62,0x6A,0xC9,0xEE,0x94, +0x62,0xFC,0xC3,0xFD,0x9B,0xDA,0xE6,0x85,0x0F,0xBC,0x95,0xB9,0x2D,0x44,0xC7,0xD7, +0xBC,0xAF,0xC2,0x8F,0x37,0x0C,0x5B,0x2D,0xB0,0x93,0x56,0x94,0xFD,0x98,0xFA,0xA1, +0xA6,0x7E,0x9B,0x9B,0x3D,0xD1,0xC2,0x95,0x68,0x27,0xDF,0x8A,0xE3,0x76,0x5B,0x01, +0xD2,0xDA,0x0E,0xE6,0xA9,0x09,0x63,0xF2,0x56,0x67,0x4B,0x1B,0xBF,0x03,0xE3,0x34, +0xAC,0xE6,0x79,0x54,0x54,0xCE,0xD3,0xCD,0x3A,0xD7,0x6A,0x11,0x5C,0xE6,0x85,0x74, +0x16,0xA9,0x29,0xD1,0xBA,0x60,0x27,0x19,0x81,0x23,0xAB,0x22,0x32,0x04,0x04,0x43, +0xE3,0x9C,0x06,0x06,0xB1,0x1B,0xC7,0x74,0xF7,0x37,0xEC,0x76,0x56,0x33,0x8E,0xBB, +0x35,0xAF,0xFC,0xFB,0xC9,0x61,0x9F,0x04,0xCA,0x36,0x10,0x20,0x4F,0x89,0x67,0x0D, +0xC8,0x8C,0x73,0x71,0xF9,0x86,0x56,0xE5,0x1C,0x77,0x8D,0xD6,0xA5,0x7A,0x93,0x06, +0x6C,0xFC,0x0D,0xC2,0x42,0x71,0xBA,0x9E,0x47,0x73,0xCE,0x30,0xF5,0x9C,0x00,0xBB, +0x01,0x92,0x34,0x23,0x99,0x1D,0xC7,0x6F,0x38,0xCB,0x29,0xA0,0x57,0x34,0x19,0xE1, +0x45,0x9D,0xEE,0x5A,0x6A,0x93,0x25,0x44,0x38,0x2C,0x68,0xEB,0xEF,0xB6,0xB0,0xF6, +0x45,0x22,0x60,0x32,0x9A,0xCF,0x4B,0xED,0xD7,0x00,0xE6,0xF0,0xAB,0xEC,0x0B,0xD3, +0x6D,0xAA,0x9B,0xFD,0x0D,0x5C,0x72,0x25,0xC4,0xA5,0x39,0x5C,0x6B,0x32,0xAF,0x8B, +0x32,0x59,0x8C,0x78,0xE7,0x48,0x99,0x91,0xB1,0xC9,0x98,0xC9,0x9A,0x46,0xB3,0x26, +0x1C,0x21,0x2D,0x1C,0x10,0x64,0x58,0xCB,0x3E,0x87,0x11,0xC6,0x0B,0x86,0x25,0x2D, +0x0E,0x05,0x55,0xFC,0x5E,0x82,0x27,0x57,0xB3,0x61,0xA7,0x16,0x0C,0xF4,0x80,0x5A, +0xE3,0x55,0xF8,0x11,0x37,0x29,0x92,0xCD,0xAA,0xF6,0x52,0x89,0x00,0x79,0xF2,0x0C, +0x9A,0x4E,0x08,0x51,0x72,0xFF,0x06,0x88,0x52,0x5B,0x81,0x00,0x32,0xEA,0xD5,0xA3, +0xDB,0xB2,0x4D,0xBD,0xEA,0xA2,0x4B,0xCA,0xFF,0x76,0x48,0x42,0x04,0x18,0xD3,0xC5, +0x0C,0x3C,0xCC,0x46,0xF7,0x38,0x31,0xF8,0xC5,0x65,0x45,0x6A,0xDC,0x02,0xEA,0x32, +0x3F,0x50,0xD7,0x3F,0x58,0x01,0x63,0x46,0x69,0xBC,0xC2,0xD2,0x90,0x88,0x52,0xF2, +0xFA,0xEA,0xD1,0xB2,0x99,0x12,0xE4,0x9F,0x90,0x97,0x12,0x3E,0x4F,0xBC,0xCE,0x27, +0xA6,0x8D,0xBD,0x48,0x9F,0xAA,0x67,0x32,0x3A,0xA0,0xC5,0x04,0x7E,0x55,0x03,0x58, +0xF8,0x55,0xD5,0xED,0xE2,0x25,0x61,0xFA,0x8E,0x2C,0x73,0x96,0x57,0x71,0xCD,0x4B, +0x6F,0xDD,0xFA,0x66,0x27,0x96,0x00,0xD3,0xF5,0x14,0xFE,0x57,0x76,0xC4,0x6F,0x07, +0x59,0x56,0x46,0xA4,0x48,0x30,0x91,0xE4,0x90,0x5D,0xA7,0xEE,0x1E,0x3E,0x60,0x87, +0x58,0x69,0x75,0x80,0xFD,0x1D,0x0C,0xE7,0x31,0x1B,0xBD,0x3E,0x7D,0x09,0xFE,0xF7, +0xDD,0x37,0xD7,0x71,0x8F,0xAC,0x68,0x1E,0x27,0x0C,0xBF,0xA7,0xC6,0x1B,0x60,0x6C, +0x88,0xDA,0x79,0x7D,0x13,0xE0,0xFE,0x2D,0xA5,0x78,0xB1,0xA6,0x47,0x1C,0x81,0x5C, +0x43,0x57,0xF4,0x11,0x93,0x43,0xF5,0x09,0x07,0x8C,0xA3,0x16,0x33,0xDB,0x3F,0x76, +0x89,0xA3,0xF2,0xA2,0xFD,0xD0,0x20,0x9D,0x96,0x67,0x6A,0xC4,0xFC,0xCE,0x7F,0x83, +0xD3,0x68,0x44,0x6D,0xB3,0x95,0xC3,0x3E,0x2E,0x25,0xA4,0x03,0x21,0x98,0x98,0xC1, +0xC5,0x4E,0xE9,0x96,0x9D,0x95,0x12,0x6D,0x5D,0xB2,0xE2,0x1D,0xFD,0x98,0xEB,0x58, +0x57,0xCB,0x4E,0x08,0xF1,0x13,0x53,0x1E,0x38,0xB4,0x7C,0xD8,0x70,0xC4,0xFF,0xC1, +0x2D,0xA4,0x4C,0x80,0x24,0x91,0x9C,0xBC,0xAE,0x1F,0x90,0xEE,0xB2,0xD1,0xFF,0xCF, +0x41,0xBC,0x1C,0x7F,0x88,0x9C,0x10,0x58,0x7A,0x7A,0xD1,0xAA,0xCD,0x84,0x96,0x0C, +0x11,0x1A,0x89,0xB0,0x96,0x73,0x18,0x7E,0xC1,0x5C,0xF9,0x59,0xF6,0x9F,0x85,0x0B, +0xC8,0xDB,0xA3,0xCD,0xD3,0xB0,0xA1,0x79,0xE5,0x2E,0xF1,0x28,0x80,0xB5,0xFC,0x6A, +0xC7,0xE1,0x7A,0x8C,0x54,0x97,0x77,0xD0,0x53,0xF1,0x09,0x72,0xBC,0xD4,0x77,0x84, +0x3E,0x79,0x67,0x8E,0x07,0xC4,0xA7,0x75,0x05,0x3C,0x0E,0x14,0x0A,0x6F,0xEA,0xD3, +0xE1,0xD7,0x25,0x05,0x61,0xA7,0xD8,0xC1,0xD7,0xF2,0x19,0x79,0x85,0xFD,0xAB,0xC6, +0x34,0xBF,0x26,0x85,0x43,0xC8,0x0F,0x54,0xD4,0xC9,0x5D,0x8D,0xD9,0x36,0x1A,0x94, +0xFB,0xB7,0x53,0x17,0xB8,0x87,0x84,0x65,0xC1,0xB6,0xED,0x87,0x05,0x33,0x2C,0xDF, +0x15,0x6B,0xD3,0xC6,0x9E,0x6C,0xE9,0xD5,0xA1,0x3C,0xF0,0xF6,0x48,0xE6,0x5B,0xEC, +0x42,0x40,0xB6,0x85,0x89,0x09,0xB1,0xA7,0x0C,0xF8,0x80,0x4D,0x1B,0xBD,0xC5,0x30, +0xE4,0xF6,0x96,0xE0,0x1F,0x8B,0xA0,0x93,0xBA,0x42,0xB2,0xCA,0x7F,0x2C,0x33,0xBA, +0xF6,0xE0,0x3B,0x6E,0xDC,0xC6,0x54,0x01,0x2B,0x5E,0x00,0x58,0xA8,0x94,0x63,0xF1, +0xCA,0x09,0x62,0xDC,0x93,0xF1,0x51,0x04,0xED,0xA6,0x40,0x28,0x14,0xEB,0x6E,0xB7, +0xA3,0x43,0x3D,0xDA,0xFC,0x8D,0xC2,0xC8,0x0A,0x96,0x53,0xD2,0x0A,0xC7,0xA7,0x4B, +0xC5,0x87,0x2A,0xF4,0xAE,0x87,0x6C,0x7B,0xF1,0xCC,0xE5,0x07,0x0A,0x1C,0xCE,0xE2, +0x5F,0xBF,0x23,0x70,0xC0,0xAF,0x76,0x26,0x79,0x8D,0xE6,0x60,0x0B,0x50,0xD3,0x13, +0xDF,0x3A,0xBD,0xA5,0x00,0x58,0x72,0xB7,0x55,0x40,0x78,0xC7,0x02,0x01,0x95,0x9C, +0xBF,0x3D,0x54,0xB5,0x25,0x74,0xAE,0xA0,0xCD,0x63,0xC5,0x48,0xE3,0xBD,0x16,0xFA, +0x85,0x35,0xCB,0x70,0xFD,0x52,0xB4,0x9A,0x57,0x91,0x1B,0x6F,0x57,0x4B,0xE8,0x71, +0x5A,0x40,0xFB,0x89,0xBE,0x84,0xF9,0x3C,0xE9,0x21,0x42,0x62,0x16,0xB0,0x3C,0x5A, +0x06,0x69,0xFD,0x76,0x8B,0x15,0x5B,0xAA,0x75,0xC9,0x1D,0xDA,0x79,0xB9,0xF6,0x23, +0xA3,0x65,0x6B,0xE4,0x28,0x39,0x4C,0x0B,0x90,0x78,0xA4,0x9D,0x47,0xA2,0x3E,0x3E, +0x5A,0xB4,0xFC,0x9C,0xB1,0x6B,0xA8,0xF8,0xD8,0x37,0x8F,0x2E,0xA3,0x9E,0x6C,0xE2, +0x18,0x9F,0x35,0xBC,0x93,0x62,0x3E,0xC1,0xCB,0xB3,0x08,0xA0,0xD1,0x80,0x90,0x91, +0x6F,0x63,0x5A,0x13,0x01,0x8E,0xE1,0xB1,0x2E,0x6F,0xF2,0xB5,0x0B,0x01,0x88,0x97, +0x63,0xC0,0xFD,0xED,0xFD,0x13,0x75,0x72,0xB0,0x95,0xB4,0x60,0xD3,0xC2,0x83,0xAD, +0x02,0x7E,0xED,0xBA,0x32,0xD5,0x8A,0xA6,0xCE,0x42,0x46,0x8F,0x7E,0xF8,0x49,0xF2, +0x72,0xD2,0x36,0x50,0x76,0x3E,0x13,0x90,0xEF,0x47,0x68,0x06,0x7D,0xD7,0xA1,0xD2, +0x87,0xE8,0xFE,0x3F,0x01,0xC1,0x07,0x46,0xFA,0x29,0xAC,0x7A,0x1F,0x21,0xF5,0x3C, +0xAB,0x26,0x4C,0x3F,0xD6,0x2A,0xE7,0x61,0xA3,0x9D,0xA5,0x39,0x19,0xAF,0x0F,0x7A, +0xE1,0x1E,0xD9,0x3A,0x0E,0x00,0x55,0xAA,0x13,0x95,0x8A,0x88,0xD1,0x8A,0x94,0xCD, +0x33,0x18,0x39,0xE7,0x31,0x57,0x5C,0x2E,0xFC,0x05,0x2F,0x5C,0x72,0x0B,0xDE,0x73, +0x85,0x96,0x06,0x1D,0xE6,0xB9,0x30,0xFD,0xC2,0x7D,0xB0,0x42,0xDE,0x0C,0x79,0x00, +0xF3,0xA4,0x85,0x74,0x91,0x5B,0xF6,0x43,0xC0,0x4E,0x44,0xEB,0x19,0xA2,0x83,0x54, +0x45,0x86,0x5E,0x08,0x03,0xED,0x5B,0x0A,0x7F,0xB9,0x8D,0xEB,0x67,0x4A,0x69,0xD2, +0x8C,0x7C,0x15,0x44,0x27,0x2B,0x93,0xF7,0x2F,0xF7,0x0C,0xB7,0x34,0x88,0xA1,0x8B, +0x37,0x87,0x3E,0x0F,0xE6,0x47,0x08,0x96,0xDA,0x69,0xD5,0x59,0x23,0x81,0xA3,0xAD, +0x89,0xBB,0x0A,0x2A,0xD4,0x7A,0x34,0x46,0xDC,0xA4,0x50,0x99,0x10,0xCA,0x14,0xD1, +0x9C,0x60,0xB3,0xDD,0xD4,0x69,0x45,0x5C,0x2D,0x4A,0x00,0x8E,0xAB,0xA1,0xE7,0x27, +0x14,0x21,0x89,0x6D,0x32,0xB7,0x39,0xA8,0xC6,0x6D,0x39,0xDA,0x2A,0x8D,0xD8,0x1D, +0x31,0xE3,0x22,0x8A,0x4C,0x5A,0xDB,0xF6,0x86,0x64,0x8A,0x98,0x5B,0xB1,0x06,0x5A, +0x83,0xED,0x1B,0xED,0xB7,0xE5,0xC1,0x7A,0xE0,0xB1,0x41,0xF6,0x1B,0x4D,0x64,0x83, +0xCD,0x46,0x98,0x8D,0x7C,0xED,0x3B,0xFC,0x96,0x98,0x54,0xCE,0xFA,0xE1,0x6F,0x54, +0x2C,0x36,0xA7,0x0A,0xC3,0xCF,0xD9,0x2A,0x4D,0x17,0x01,0x22,0x03,0x21,0x28,0xF3, +0xD9,0xBC,0x42,0x05,0xFF,0x2C,0x39,0xA0,0xC9,0x2C,0x83,0xFB,0x01,0x1D,0x5C,0xA8, +0x9E,0x03,0xCC,0x93,0xFC,0x11,0xC5,0x59,0x48,0xA9,0x01,0x58,0x5C,0xF9,0xC5,0x7D, +0x6C,0x14,0xB2,0x15,0x78,0x34,0xE8,0xB4,0x58,0xAD,0xD5,0xA0,0x1C,0x31,0xFE,0xB2, +0xCD,0x00,0xF8,0xEB,0x51,0xF6,0x8E,0xA4,0x57,0x8F,0x7F,0xC8,0x40,0x7F,0xC1,0x55, +0x01,0x14,0x12,0x3B,0x11,0xE5,0xB7,0x2F,0x09,0x79,0x23,0xC8,0x3D,0x27,0xCE,0x33, +0xB1,0xF8,0xBA,0x2B,0xCF,0xBA,0xAF,0xBD,0xFF,0x88,0xEA,0x17,0x5B,0xFA,0x1E,0x2C, +0x30,0x5E,0xB7,0x24,0x8C,0x43,0xC3,0x69,0x69,0x0A,0x5A,0xF0,0xBE,0x5D,0x50,0x13, +0x82,0x5F,0xC6,0x83,0x03,0x77,0xC6,0xC2,0xEE,0xB3,0x53,0x4B,0x36,0x09,0x48,0x0E, +0xA5,0xC8,0x3D,0x78,0x09,0x7E,0x02,0x27,0x4C,0xA3,0x06,0x9A,0x8B,0xB5,0x99,0x24, +0x0C,0x8A,0xB3,0x19,0xA9,0x3D,0x22,0x3B,0x0E,0x22,0x43,0xEE,0x22,0xB8,0xF5,0x16, +0x03,0x55,0xD2,0xEF,0xDC,0xA0,0xE7,0xC7,0x0C,0xD4,0x36,0xEB,0x95,0x19,0x80,0xD0, +0x9D,0x27,0xDD,0x2B,0x9F,0xA8,0xC2,0xF9,0xB1,0xAC,0x39,0xD3,0xB4,0xA3,0x18,0x7B, +0x85,0x4B,0x34,0xC2,0xD3,0x17,0x79,0x45,0xA9,0x35,0xD0,0x2D,0x64,0xBB,0x7F,0xCA, +0x0A,0xF2,0x09,0x4A,0x8F,0x46,0x84,0xF3,0x28,0x67,0x87,0x34,0xD2,0x08,0x4D,0x26, +0x49,0x6E,0x64,0xBF,0x36,0xCE,0x42,0x87,0xF2,0xD6,0xB4,0x98,0x7A,0x0E,0xC8,0x38, +0x37,0xD5,0xAB,0x23,0x87,0x36,0xF2,0x0D,0x62,0x0D,0x6D,0x42,0xDB,0x93,0xCB,0x1B, +0x5B,0xA1,0xFD,0x42,0x08,0xAB,0x4C,0xF2,0xB5,0x0F,0xD0,0xCB,0x05,0xC5,0xE5,0x85, +0xCA,0xA1,0x32,0x35,0xAF,0x49,0xC8,0xFA,0x4F,0xD8,0x4E,0x47,0xA2,0xFA,0xDD,0x1F, +0x6C,0xF9,0x54,0x3F,0x86,0xCD,0x5E,0x27,0x59,0xAC,0xF9,0xF0,0x42,0x5E,0x8F,0x98, +0x6F,0xEB,0xDC,0x27,0x2B,0xC1,0x3A,0x7C,0xED,0xF8,0xBD,0x6A,0x1F,0x9B,0xAB,0x14, +0xB1,0xE8,0x65,0xEB,0x07,0x8A,0xFA,0xF5,0xD8,0x3F,0x34,0xAE,0xEF,0x3B,0xA6,0xB5, +0x70,0x76,0x63,0xDB,0x13,0x46,0xD7,0x35,0x86,0x2F,0x7E,0xC9,0xCF,0x9C,0x23,0xAE, +0x19,0xDF,0x3C,0xBD,0xC7,0xD6,0x2B,0xCA,0xBB,0x3F,0xF2,0x70,0x92,0x55,0x67,0xA7, +0x9D,0x30,0xD5,0x8A,0xB8,0x43,0xDD,0xA3,0xE8,0x06,0x5C,0x9D,0xA5,0x3E,0xED,0xF0, +0xD3,0x02,0xBE,0x76,0xCB,0x94,0xB8,0xE7,0x02,0x11,0xA5,0x05,0x95,0x1F,0x35,0x2C, +0x46,0x6E,0xD9,0x3A,0x2F,0xF9,0x96,0x1A,0x62,0x70,0x30,0x7D,0x6C,0xC0,0xE2,0xE3, +0xC0,0x07,0x89,0x0B,0x1E,0x28,0x09,0x21,0x2E,0xC1,0x36,0x4C,0x6F,0x56,0x7F,0xAD, +0x58,0xA2,0xF7,0x8D,0x93,0x20,0x74,0xA5,0x7C,0xA9,0x31,0x70,0x9F,0x97,0xB5,0xA7, +0x48,0x2C,0xD7,0x4F,0xCD,0xA6,0x49,0x4A,0x7C,0xF2,0xB3,0x49,0x33,0x36,0x6B,0x01, +0xA6,0xC6,0xBB,0xE4,0x14,0xC6,0xB8,0x7F,0xDE,0xC4,0x86,0x9E,0x6C,0x4C,0xBA,0x5F, +0xDB,0xFB,0x85,0x2C,0xB0,0xC1,0xE9,0x03,0x2F,0x41,0x20,0xD5,0xAF,0x57,0x69,0xE7, +0xB4,0xF2,0xAE,0x8C,0x39,0x91,0x15,0xEB,0x33,0xDB,0x53,0xF5,0x6C,0x27,0xB9,0x57, +0x60,0x4B,0x7B,0x3A,0x3E,0x2C,0xAB,0x90,0x09,0x5E,0x6F,0x47,0xCD,0x83,0xC7,0x3D, +0xF4,0x82,0xE8,0xD4,0x84,0xEC,0x27,0xF2,0xB8,0x5A,0x05,0xFC,0xC5,0x9A,0xB9,0x8A, +0x8C,0x65,0x67,0x2A,0x03,0xF7,0x6F,0x3A,0x5C,0x26,0x00,0x6A,0xB3,0xE6,0xF1,0xAB, +0x66,0x97,0xE5,0xBE,0x64,0xA1,0xE4,0x36,0x59,0xCD,0x54,0xC2,0x6F,0x75,0x72,0x53, +0xB0,0xE3,0x05,0xCC,0xDC,0x0F,0xCB,0x3C,0xDE,0xC7,0x5C,0x7A,0xAD,0x07,0x3F,0x5F, +0x19,0x3D,0x6D,0xD8,0xF6,0xA4,0x2C,0x65,0x8D,0x6D,0xAF,0xC0,0xA4,0xE0,0xAE,0x46, +0x84,0x71,0x67,0xF6,0xA8,0x77,0x4E,0x92,0xAE,0x2F,0xEA,0x4A,0x25,0x1E,0x7C,0x6A, +0x27,0x71,0xB4,0x18,0x6D,0x4B,0x6B,0xE7,0xEA,0xF6,0x11,0x8C,0x2F,0xD3,0xA5,0x4A, +0x36,0x9E,0x06,0x4A,0xEF,0x11,0x16,0x33,0xB2,0x93,0x35,0xE8,0x26,0x51,0x2D,0x97, +0xEE,0x73,0x49,0x57,0x01,0x05,0x2B,0xB6,0xC1,0xF6,0xBA,0xDB,0x47,0xA4,0x31,0x9D, +0x91,0xA6,0x0F,0x28,0xE5,0x62,0x90,0xBD,0x3C,0xAA,0x9C,0x31,0x1F,0x31,0x81,0x96, +0xD2,0xBE,0x82,0x61,0xD0,0xAF,0xA6,0x84,0xD8,0x35,0x42,0x3A,0x19,0xB2,0xD3,0xBF, +0xE5,0x51,0x31,0xB5,0x5E,0x07,0x61,0x20,0xCC,0x6C,0x26,0x98,0x02,0x96,0x5A,0xC4, +0x7A,0xE6,0xCB,0x8B,0xDA,0x48,0x0D,0x14,0xC1,0x2E,0x5D,0x22,0x23,0xD4,0x83,0xA3, +0x30,0xD0,0x91,0x30,0x64,0xC3,0x0A,0xFE,0x62,0xB3,0x4C,0xAF,0x60,0x77,0x0D,0x66, +0x8B,0x15,0xE8,0x1C,0x09,0x27,0xE5,0x1D,0x2B,0xDA,0xF8,0x3C,0x8A,0xCD,0xC5,0xAA, +0xE7,0x95,0x29,0xC0,0xC1,0x0C,0xDA,0xD6,0xC4,0xB8,0x33,0x48,0xD6,0xFC,0xCD,0xE9, +0x01,0xA8,0x0C,0x29,0x4A,0xF3,0xFD,0xE2,0x4A,0xC0,0x58,0x6E,0xE3,0x26,0x4A,0xE1, +0xFF,0x63,0x67,0xEC,0xDA,0xF8,0xBC,0xE9,0x90,0xC4,0xAB,0x0D,0xAA,0xCD,0x42,0x69, +0x0C,0x04,0xC0,0xC9,0xCA,0xDE,0x77,0x3F,0xFC,0xC7,0x13,0x05,0x06,0x92,0xBF,0xCF, +0x54,0x05,0x55,0x08,0x61,0xB0,0x5D,0x94,0x78,0x13,0xC1,0x90,0x7A,0x51,0xB0,0xDD, +0xB4,0x20,0xFE,0xD2,0x56,0x9F,0xD4,0xED,0xC4,0x98,0x5C,0xAE,0x6F,0x39,0x18,0x82, +0x33,0x0B,0xFD,0x61,0x29,0xD2,0x20,0xFC,0x9E,0x07,0x2A,0xF5,0x1D,0x51,0x82,0x15, +0xC2,0xEB,0xA1,0x78,0x80,0x73,0xBA,0x08,0x18,0x02,0x68,0xCC,0x1E,0x73,0x2F,0x1A, +0x78,0x28,0x5B,0x43,0x4E,0xD3,0x4E,0xF1,0x79,0xB2,0x12,0x61,0x4E,0x0B,0xEA,0xBD, +0x62,0xE2,0xB7,0x83,0x82,0xAB,0x1C,0xB3,0xF3,0x7B,0x6E,0x68,0x11,0x95,0xAC,0x1F, +0x89,0xC9,0xE2,0x02,0x9F,0xDD,0x0E,0x5D,0xAA,0x3F,0xF0,0x46,0xFA,0xE8,0xDC,0x24, +0xC7,0xE9,0xE9,0x3A,0x76,0xB5,0x14,0x97,0xCF,0x3D,0x3D,0xC7,0x35,0xFC,0x79,0x7B, +0x9F,0xA3,0x3B,0x72,0x51,0x70,0x00,0xFF,0xE7,0x9C,0xDC,0x6B,0xDE,0xA6,0x47,0x84, +0xDA,0xB1,0xAE,0xCF,0xB5,0x3A,0x4B,0xC1,0x6D,0xDD,0xC8,0x42,0xB3,0x57,0x93,0x65, +0x2C,0xEE,0xC6,0x62,0xD5,0xBC,0x83,0xB3,0xC8,0xEA,0x59,0xB0,0x2B,0xE7,0xA7,0x2E, +0x6D,0x9E,0xF3,0xFF,0x1E,0xA2,0x6A,0x9C,0xE7,0x97,0x32,0xFC,0x09,0x15,0x1F,0x62, +0x77,0x77,0x4B,0xC1,0x87,0xC4,0x65,0x27,0xB3,0x8B,0x02,0xD7,0xCF,0x9C,0x8A,0x50, +0xBD,0xE6,0x00,0xF3,0xED,0xD4,0xFB,0xD3,0x73,0xF7,0x9B,0x63,0x1F,0x83,0xCD,0xA3, +0x1B,0x03,0x91,0x18,0xB8,0xD0,0x0B,0x30,0xCD,0x7E,0x04,0x2C,0xE3,0xE0,0xC6,0x7A, +0xAF,0xFA,0x53,0x28,0x71,0xA7,0x9E,0x59,0x06,0x2A,0xD5,0x48,0xE7,0x82,0x3F,0x6A, +0xEB,0x86,0xF6,0x4D,0xCE,0xD4,0x50,0x42,0x7A,0xD8,0x2B,0xEE,0xB9,0xE5,0x0D,0xDA, +0x43,0xAA,0x14,0xE4,0x0B,0xA1,0xDB,0x3F,0x12,0x2D,0xE5,0x1A,0x49,0xA0,0xBB,0xDE, +0x18,0x54,0x01,0x70,0xFD,0x58,0x0A,0xE6,0x82,0x79,0xD0,0x6A,0xEE,0x6A,0x39,0x83, +0x52,0xCA,0x67,0xC2,0x77,0xB6,0x7A,0x94,0x2B,0x62,0x4F,0xAB,0x64,0x85,0x04,0x60, +0x25,0x48,0xE3,0x06,0x39,0xD9,0x8D,0xB0,0xA1,0x86,0x95,0xDC,0x86,0x0C,0x1C,0x85, +0xFD,0x4C,0x9F,0xE1,0xB8,0xA2,0xB5,0x37,0x4F,0x5C,0x95,0xAE,0xC7,0xE6,0x58,0xBD, +0x2C,0xFE,0x42,0x29,0x68,0xC6,0xFA,0xE0,0x5B,0x32,0x3F,0x57,0x92,0xD2,0x95,0xE5, +0x1C,0xC0,0x03,0xF0,0xED,0x34,0x8A,0xA7,0xF6,0xA7,0xC9,0x77,0x3F,0xF5,0xAF,0xCA, +0x47,0xB9,0x63,0xDF,0x57,0x3F,0x7C,0x63,0x09,0xE7,0x22,0x82,0x61,0x73,0x3B,0x4A, +0xA8,0xDD,0x26,0x8B,0xE1,0x6D,0x44,0xB2,0x18,0x21,0xD3,0xD3,0x9C,0x65,0x20,0x7A, +0x52,0x0C,0x52,0x8B,0x54,0x90,0x22,0xA3,0x78,0x8D,0xAC,0x2A,0x48,0x94,0xF5,0x42, +0x46,0xE3,0x39,0xAF,0xBD,0xD9,0x45,0xAA,0xD4,0x1D,0xB7,0xB8,0x7E,0x93,0xAF,0xF0, +0x94,0x10,0x5F,0xAF,0xCF,0x0C,0xF2,0x88,0x3E,0x9E,0xB1,0x46,0x78,0x8F,0xF0,0x98, +0xA3,0x1A,0xE2,0x7A,0x5F,0xF9,0x26,0xC3,0x49,0x20,0x31,0xD2,0x19,0x89,0x3E,0x04, +0xE3,0x56,0x5F,0x2C,0xEE,0xC8,0x64,0x7B,0x4A,0x53,0x7E,0xEF,0xE2,0x29,0xA8,0xD9, +0x93,0xC2,0x7C,0x0E,0x12,0x74,0x94,0x5F,0xE3,0x1D,0xF2,0x8C,0x82,0x29,0x8F,0xAA, +0x91,0x9E,0x80,0x2D,0xCC,0xB7,0x8C,0xFB,0x6E,0x48,0xEB,0xCB,0xC6,0x8D,0xA0,0x3F, +0x64,0x50,0xF4,0x64,0xBE,0x68,0x06,0x4E,0xE1,0x2E,0xCA,0x0B,0x7C,0x41,0xF0,0xEE, +0x78,0xCB,0x3E,0xE3,0x06,0x69,0x28,0x6A,0x88,0x27,0x00,0x64,0x8C,0x41,0x4E,0xCF, +0x07,0xFD,0xDB,0x5C,0xEA,0xBE,0xE8,0x54,0x52,0x92,0xBD,0x1C,0xF2,0xF7,0x74,0xC8, +0x26,0x6B,0x47,0x87,0x11,0x32,0xB4,0x93,0x97,0x75,0xF3,0xF0,0xCF,0x4B,0x7D,0x7D, +0x6B,0xFE,0x0B,0xA6,0xCA,0xBE,0x03,0xB7,0x83,0x93,0x2B,0x18,0xCD,0x41,0x30,0xC7, +0xD0,0x29,0xC0,0x6E,0xD4,0xDE,0x39,0xAF,0xAF,0xA9,0x11,0x03,0x3B,0x9A,0xFC,0x45, +0xA8,0x6A,0x45,0xBF,0xCC,0xF4,0x00,0x1C,0xDF,0x43,0x9A,0x60,0x86,0x81,0xD2,0x88, +0x46,0x66,0x0C,0x84,0x8D,0x85,0x9B,0xD4,0x8F,0xC3,0xA6,0x2F,0x45,0x9E,0xA9,0x18, +0xDA,0xD5,0x76,0x4D,0xEF,0xFE,0x71,0xF1,0xF0,0xAA,0x77,0xDA,0x2C,0x7E,0x0E,0x42, +0x4D,0x54,0x9C,0x8F,0x32,0xCE,0x13,0x9B,0x75,0xAF,0x54,0xC5,0xE0,0x2B,0x22,0x2D, +0x0F,0x34,0x67,0xC3,0xA0,0x0A,0xF3,0xC1,0x00,0x86,0x0C,0xBA,0x7E,0x9D,0xB4,0x6A, +0x9B,0x98,0x77,0xA2,0x06,0xDC,0x17,0xEC,0x39,0x93,0xC5,0x3E,0x3E,0xCA,0xFA,0x53, +0x07,0xB4,0xED,0x12,0x58,0x9D,0x05,0xBA,0x57,0x88,0x13,0x14,0x03,0x0D,0xE4,0x91, +0x24,0xF3,0xB6,0x2F,0xFE,0xCB,0x78,0x17,0x81,0x52,0x58,0x49,0xA2,0xA2,0xC7,0x77, +0xC7,0xF4,0x45,0x26,0xEE,0x85,0xC3,0xB6,0xF4,0x20,0xE6,0xC5,0x6C,0x78,0xB9,0x33, +0x50,0x84,0x0F,0x35,0xF7,0xA5,0x08,0x0A,0x31,0x29,0x88,0x49,0x39,0x52,0x03,0x2D, +0x14,0x1A,0x59,0x8D,0xB4,0xE6,0x63,0xC1,0xF8,0x80,0x19,0xD0,0x08,0x91,0x54,0x8A, +0xDC,0xB1,0x27,0x11,0xA0,0x17,0x08,0xF2,0xB8,0x7B,0xC5,0x9D,0x12,0x3B,0x68,0xFE, +0xFA,0xE7,0xE3,0x9B,0x25,0x8C,0x8F,0x30,0x77,0xB6,0x0A,0xE0,0x92,0x2A,0xDC,0xFA, +0x33,0xF0,0x40,0xDF,0xD9,0xC2,0x84,0xFA,0x76,0x6B,0x3E,0xDD,0xF8,0x2C,0x76,0x46, +0xE1,0xF1,0x30,0xBF,0x54,0x30,0x31,0xFA,0x4A,0x98,0xEC,0x82,0x62,0x42,0xA2,0x07, +0x93,0x77,0x9B,0x3C,0xAE,0x30,0xC6,0xCF,0x0F,0xCB,0xF7,0x04,0xAF,0x34,0xFC,0x15, +0xF4,0xE4,0xD6,0x66,0x29,0x71,0x9B,0xEF,0x60,0x5C,0x93,0x7D,0x2B,0xAE,0xEC,0xD1, +0x37,0x63,0x29,0xFC,0xEF,0x55,0xC5,0xEC,0x08,0xC0,0xC4,0x7C,0xDC,0x3C,0x42,0x09, +0xA4,0xA8,0x5C,0xF0,0xE3,0x93,0x78,0x64,0xEE,0x32,0xF5,0x5A,0x27,0x11,0x1C,0xC5, +0x51,0xC9,0x48,0xA6,0x4C,0x88,0xC0,0x7F,0xBD,0x21,0xB9,0xE4,0x0B,0x99,0xC8,0x34, +0xE1,0x84,0x8E,0x45,0x12,0xED,0x0B,0x79,0xFC,0x63,0x06,0xBC,0x80,0xAF,0xFA,0xBA, +0xEB,0x81,0xAA,0x39,0x52,0xF3,0xE7,0x65,0xC0,0x5C,0xFB,0xFE,0x19,0x0D,0xB8,0xA5, +0xBC,0x53,0x96,0x11,0x59,0x6C,0xC2,0x50,0xF8,0xFC,0x64,0x13,0xA5,0x82,0x68,0x30, +0x98,0xF2,0x57,0x05,0xD8,0x25,0x16,0x02,0x45,0x76,0x3B,0xA5,0xC7,0xF6,0xE4,0x30, +0x1D,0xF1,0xA0,0x28,0x3C,0xA9,0x77,0xE3,0xC0,0xC1,0xE0,0x1A,0x1B,0xF3,0x58,0xBA, +0xFF,0xFD,0x36,0xF0,0xBF,0xF9,0xF3,0x10,0x37,0x8C,0x44,0xD5,0x83,0xE0,0x69,0x88, +0x99,0xE9,0xAA,0x44,0x75,0x30,0x1A,0x0E,0xBE,0xB1,0x1B,0x44,0x82,0x3D,0x5D,0xCB, +0x0E,0x54,0x54,0x6A,0xF0,0xE6,0x13,0x79,0xFF,0x35,0xEA,0x03,0xB1,0xEA,0xD2,0x16, +0xF4,0x94,0xF5,0x74,0xF3,0x4E,0xC4,0x0E,0x94,0xBB,0x70,0x0F,0xD6,0xDF,0x2D,0x4D, +0x1A,0x00,0xE4,0x09,0x7B,0x1F,0xB7,0xC4,0x00,0x3F,0xC5,0xEA,0xD4,0x6D,0xC8,0xE6, +0x9B,0x9A,0x51,0xAD,0xFD,0xD0,0x0B,0xDD,0xA4,0x36,0x3C,0x4D,0x65,0x86,0xC6,0xDD, +0x18,0x9A,0x96,0x2E,0x7B,0x5A,0x0F,0xAB,0x40,0xA5,0xDB,0x83,0x9C,0x57,0xC2,0x36, +0x53,0xA6,0xEB,0x69,0xC4,0x38,0xA3,0xED,0xCD,0x54,0xE7,0xEA,0xED,0x5A,0xAD,0xF1, +0x15,0xDF,0xA5,0x28,0x5A,0x5D,0x14,0x42,0xBA,0xA9,0x6B,0x67,0x8D,0x9A,0xBC,0x93, +0xA9,0x62,0x49,0xCD,0x91,0xE6,0x49,0x02,0x02,0x84,0x80,0x7C,0x61,0xF7,0x08,0x05, +0x7A,0xD5,0x95,0xCD,0xCB,0xD6,0x3B,0xD8,0x6E,0x61,0xC1,0x57,0xF2,0x6D,0x9F,0xDD, +0x4D,0x50,0x6D,0xAF,0x98,0x5B,0x71,0xC6,0x9E,0xC7,0x39,0x7A,0xA7,0x5D,0x34,0xF4, +0x07,0x64,0xA6,0x0E,0x96,0x9F,0x90,0xB2,0xC9,0x5F,0x80,0xA0,0x75,0xD6,0xD6,0x69, +0xA0,0x76,0x8D,0x12,0x24,0xE0,0xAB,0xD5,0x8A,0x97,0x82,0xC6,0x6E,0xB9,0x84,0x55, +0x4D,0xF4,0xCE,0x5E,0x5E,0x66,0x8B,0x3A,0xF8,0x8C,0x66,0x80,0x20,0x87,0x24,0x18, +0xD1,0xD4,0x90,0xB8,0x0B,0x22,0x04,0x0F,0x64,0x4B,0x85,0x3B,0x40,0x09,0xEC,0xAF, +0xE2,0xC9,0x46,0x80,0xE2,0x84,0xF1,0xB9,0x61,0x59,0x8A,0x8E,0xA4,0x39,0xDF,0x7F, +0xED,0x70,0x71,0x72,0xB8,0x92,0xE8,0x54,0xE9,0x4F,0x97,0x58,0x91,0xB3,0x5D,0xCD, +0x1D,0x38,0x0A,0xF9,0x9E,0xC0,0xB0,0xEE,0xB2,0x23,0xF7,0xCA,0x8E,0x9A,0x69,0xF1, +0xBA,0x4C,0x7D,0x6E,0xAB,0x00,0xC9,0x43,0x3E,0xA7,0xC2,0xDC,0x0A,0x3F,0x4B,0x38, +0x6A,0x95,0xFE,0x13,0x4F,0x4B,0x7F,0x4F,0xE1,0xBE,0x1F,0x8A,0xDD,0xD8,0xC5,0xA7, +0x40,0x4E,0x63,0xB0,0x57,0xDD,0xC2,0xDE,0x22,0xFB,0x4F,0x1A,0x00,0x49,0x72,0x91, +0x66,0xE1,0x2C,0xD6,0xD3,0xA2,0x9F,0xC5,0xA7,0x55,0x0D,0x45,0x81,0xD8,0x45,0x4C, +0x4D,0xA1,0xDF,0xC1,0x55,0x17,0xC9,0x47,0xAD,0x66,0x55,0x65,0x52,0x15,0x67,0x6C, +0x28,0x69,0xBE,0x06,0x9F,0xF4,0x43,0xD0,0x71,0xE4,0x92,0x48,0xDD,0x7F,0xE3,0xFA, +0x2A,0x1A,0x42,0x3D,0xC6,0x2F,0xEC,0xA7,0xC1,0x6D,0xC8,0x46,0x6B,0x2D,0x5F,0x1C, +0x54,0xF0,0xD6,0x86,0x4D,0x52,0x9C,0x81,0x6B,0xA5,0x09,0x84,0xB3,0x9B,0xB4,0x23, +0x41,0xB2,0xCC,0x26,0xC8,0x42,0x4C,0x3B,0x30,0x53,0x79,0x2E,0xE8,0x34,0xD9,0x00, +0x5F,0x47,0xCE,0xE4,0x5A,0x47,0x93,0x29,0x1E,0xB6,0x88,0x61,0x81,0x20,0xAF,0x92, +0x18,0x3B,0x6C,0x58,0x65,0xF1,0x29,0x11,0x2A,0x9C,0x02,0xF9,0x9B,0x82,0xBA,0xDC, +0xEF,0x4C,0x06,0x90,0x4E,0xD2,0xB9,0x28,0xA4,0x62,0xF8,0x74,0x76,0x50,0x53,0x4F, +0x8D,0xE3,0x23,0x18,0x9C,0x4B,0xAB,0xFB,0xFB,0x73,0xC9,0xC3,0x92,0x60,0x3A,0x7A, +0x18,0x1D,0x8D,0x8E,0x55,0x70,0x23,0x76,0x9A,0x91,0x96,0x11,0x7F,0x78,0x66,0xEC, +0x55,0xFA,0x75,0x71,0x71,0x5B,0xFA,0xE4,0x3A,0x21,0xC2,0xE5,0xD5,0xA2,0x60,0x06, +0xF7,0x12,0x29,0xE5,0xEF,0x77,0x27,0xC0,0xAE,0x18,0x5D,0x87,0x1E,0x1C,0x16,0xC5, +0x3F,0xA0,0xA7,0xBE,0x57,0x63,0x60,0xCC,0xDD,0x82,0xB9,0x29,0xCD,0xCD,0x2F,0xB4, +0x72,0xE7,0x48,0xE0,0x6F,0xE2,0x18,0xF0,0xE9,0x5B,0xE7,0x7D,0xAA,0x24,0xA6,0x38, +0xC3,0x8B,0xC5,0x39,0xB6,0x0C,0x68,0xB2,0x3E,0x27,0xF1,0x99,0x70,0xA1,0x53,0x1D, +0x2B,0x5D,0xE2,0xFD,0xA6,0x14,0x32,0x4C,0x25,0xA8,0x1D,0x0D,0x67,0x33,0x75,0xC1, +0x73,0xA1,0xB1,0x16,0x25,0x4F,0x9A,0x95,0x07,0xD7,0x4A,0xA8,0xFD,0xE5,0x96,0x1C, +0x47,0x8B,0x79,0x41,0x13,0x52,0xBE,0x70,0x30,0x37,0xC6,0x60,0x20,0x22,0xA3,0x2A, +0x71,0x16,0x06,0xAF,0x52,0xF5,0x88,0x66,0x56,0x1D,0xE2,0x5C,0xDA,0xE8,0x93,0x48, +0x33,0x98,0x42,0xA3,0xBB,0xF8,0xF8,0xEF,0x3B,0x0D,0xE3,0x3C,0x42,0x88,0x14,0xCD, +0x43,0xAD,0xE0,0x63,0xDC,0x5B,0xD8,0x4D,0x53,0xB6,0xE7,0xF4,0xE0,0x77,0x59,0x33, +0x20,0x2A,0xB5,0x07,0xF4,0x82,0x75,0x90,0x23,0x59,0x67,0x79,0x14,0xE5,0xD9,0x28, +0xDB,0x84,0x1E,0xA3,0x09,0xEB,0x10,0xD4,0x83,0x63,0x6A,0x5D,0x7A,0xFD,0x76,0xC6, +0x4E,0xA1,0xE7,0xF3,0x91,0x2A,0xE2,0xD8,0x6F,0x4B,0x27,0x52,0x2B,0x2D,0x31,0x89, +0xC6,0xC7,0xDE,0xC5,0xF4,0x2C,0xA2,0xE5,0x22,0x4E,0xFC,0x1C,0x71,0xFB,0x89,0x1C, +0x66,0x58,0x5E,0xA8,0x51,0x24,0xB4,0x9B,0x89,0x6C,0x96,0xA3,0x8E,0xAF,0xD0,0x68, +0xD3,0x1E,0xBB,0x68,0x1C,0xDF,0x38,0xF7,0xBB,0x54,0x5A,0xB6,0x21,0x30,0x59,0xD4, +0xB4,0x8B,0xD8,0x6C,0x8F,0x61,0x94,0xA7,0xDC,0xE2,0x82,0xE8,0x26,0x11,0x43,0xE0, +0x8D,0x78,0x39,0xEC,0x4C,0xF2,0x96,0xF7,0x1B,0xB5,0xE2,0x1E,0x7E,0x32,0x30,0xA6, +0x68,0xEA,0xFF,0x92,0x85,0xB2,0xB9,0x3C,0xEB,0xC3,0x71,0x15,0x5B,0x3A,0xC4,0xAF, +0x8C,0x58,0xBF,0x1C,0xF6,0x53,0x68,0xB9,0x1D,0xFE,0x01,0x70,0xBC,0x51,0x38,0x5C, +0x65,0x94,0x8D,0x2C,0xC0,0xDF,0x00,0xF1,0x07,0xE9,0x63,0xB9,0x71,0x9B,0x75,0x71, +0x6A,0xB6,0x54,0x84,0x38,0x4D,0x85,0x1F,0x92,0x40,0x1A,0xFD,0x7C,0xA6,0xF2,0xE7, +0x7B,0xD9,0x70,0x56,0x2C,0xEF,0x64,0x61,0x62,0xFD,0x1B,0x93,0xE2,0x2C,0x0B,0xD3, +0x64,0x7D,0x12,0xD2,0x03,0x5C,0xC4,0x28,0xF9,0x96,0x84,0x60,0x28,0x03,0x73,0x91, +0x1D,0x91,0x34,0x9C,0x2C,0x4E,0x2C,0xE6,0x87,0x0C,0x61,0x22,0xDB,0x6C,0x43,0x48, +0x89,0x58,0x24,0x80,0x82,0xA7,0x10,0xAB,0xD0,0x3D,0x72,0x82,0xBC,0x48,0x3D,0xC2, +0xC8,0xEC,0xB6,0x41,0xE0,0x18,0xAA,0x33,0xDB,0xB5,0x56,0x19,0x7C,0x74,0x42,0x6C, +0x51,0xBB,0x46,0xD3,0x7C,0xC0,0xE7,0x98,0x7C,0xE4,0x64,0xFF,0xD9,0x71,0x20,0x20, +0x61,0x4C,0xDF,0xDA,0x41,0x09,0x32,0x48,0xCD,0xD7,0xCE,0x00,0x92,0x65,0x74,0xC5, +0xE5,0x34,0xF2,0x12,0xDE,0x19,0xD6,0xC4,0xD4,0x53,0x2D,0x76,0xEA,0x4F,0xB8,0x08, +0x96,0xC3,0xFC,0x5F,0x69,0xB8,0xDA,0x9D,0xC2,0x7C,0x20,0xE8,0x94,0xC6,0x3B,0x2D, +0x2E,0xBF,0x05,0x1E,0x19,0x44,0x16,0xA9,0xCE,0x44,0xA6,0x5B,0x65,0xA5,0x25,0xC4, +0x9E,0x26,0x7F,0x03,0x4F,0x81,0x20,0xC0,0x22,0x62,0xC5,0xC4,0xB7,0xFF,0xBE,0x46, +0xE6,0x99,0x3E,0x71,0x43,0xB5,0x73,0xDA,0x02,0xAE,0xFF,0x85,0xBC,0x9E,0xB5,0x97, +0xDC,0x7F,0x19,0x8C,0x12,0xAA,0xE1,0x8B,0xF8,0xC2,0x76,0xAA,0x69,0x24,0x44,0x16, +0x3B,0xAE,0xC5,0x65,0x99,0xC3,0xB5,0xAF,0x64,0x75,0xCF,0x09,0x75,0x29,0x3B,0xD3, +0xB7,0x72,0x87,0x84,0xA0,0xEB,0x16,0x87,0x7E,0xC8,0x76,0xCF,0x9D,0xD0,0xC5,0x6E, +0x17,0x77,0x61,0x0F,0xED,0x0E,0xEE,0xB9,0x95,0x61,0x57,0x01,0xE5,0x08,0x1A,0xEB, +0xDA,0x6F,0x67,0x97,0xC7,0x7A,0x3B,0x41,0xFB,0x7D,0x15,0x76,0x05,0x35,0xD8,0x2E, +0x93,0xAD,0x13,0xBC,0x49,0xA1,0xAF,0x29,0xC8,0x46,0xF9,0x72,0x8D,0x33,0xBB,0x10, +0x05,0x27,0x3D,0x1F,0xFE,0xF2,0x0A,0x82,0xF6,0xA2,0x03,0xCA,0xC1,0xCA,0x4D,0xD5, +0x34,0x87,0x36,0x17,0x5F,0xA7,0x5B,0xA6,0x2C,0x96,0x8E,0x8D,0xDA,0x25,0xEF,0x1B, +0xAF,0xD3,0xF7,0xB2,0x96,0xEE,0x8A,0xDF,0x30,0x9C,0x4F,0x26,0xC0,0x3D,0x8D,0xAD, +0xDF,0x43,0xEC,0x3F,0x6A,0x5B,0xA9,0xAC,0xD2,0x48,0xBB,0x4A,0x56,0xC6,0xDE,0x7C, +0x57,0xC3,0x13,0xA1,0xA3,0xB5,0xF5,0x8D,0xCB,0xF9,0x76,0x21,0xB1,0xC5,0x50,0xF2, +0x22,0x0B,0xCD,0xA4,0x71,0xEC,0x0E,0xC2,0xEC,0xCF,0x1D,0xBF,0x6A,0x10,0x66,0x67, +0xAF,0x8F,0x89,0x9B,0xA0,0x0D,0x46,0x0D,0xA6,0xCE,0xE9,0xB7,0x79,0x66,0xD0,0x6B, +0xE7,0xF5,0xFD,0x23,0xC4,0xBB,0xF0,0x74,0xE1,0xC5,0xB4,0x4E,0xDE,0x94,0xB5,0x1A, +0xA1,0x0B,0x01,0xBB,0x01,0x12,0x95,0x92,0x64,0x95,0x27,0x01,0x75,0xE9,0x70,0xE8, +0xCE,0x22,0x39,0x62,0x22,0xB8,0xA1,0x31,0x39,0x47,0x58,0x03,0x22,0x4D,0xC6,0xAC, +0x21,0xE9,0x2B,0x6F,0x14,0xF3,0x35,0x14,0xBB,0x72,0x55,0x74,0x7F,0xC8,0x6B,0xC9, +0x99,0xB9,0x96,0xFB,0x64,0x47,0xE3,0xCF,0xDA,0xB0,0x01,0xDE,0x19,0x86,0x54,0xCF, +0x93,0xE4,0x8C,0x9F,0xB5,0xC7,0xC1,0x9B,0xDC,0xB3,0xA2,0x8D,0xDE,0xE9,0xAC,0x09, +0xB9,0xC3,0xB4,0x4D,0x00,0x3F,0x4F,0xEE,0x77,0x88,0x4E,0x41,0x0D,0xAA,0xAC,0xC9, +0xB6,0xFE,0xF5,0x37,0x75,0xAC,0xB0,0x45,0x30,0xEE,0x4C,0x53,0xE7,0x89,0x56,0xCF, +0xCA,0x01,0x48,0x91,0x4E,0xAB,0x20,0xAC,0xC5,0xAB,0x2C,0x04,0xC1,0x33,0x61,0x51, +0x99,0x3A,0xF5,0x1A,0xD4,0x35,0xCA,0x83,0x23,0xDF,0xAC,0xB0,0xAE,0xB5,0xF2,0x81, +0x5F,0x66,0x3A,0x5C,0x46,0x3A,0x84,0xE7,0xD3,0xA1,0xD1,0x5A,0x68,0x9C,0xE6,0x9C, +0xF6,0x37,0x13,0x3D,0xBD,0x64,0xB2,0x11,0xCC,0x50,0x62,0xF5,0xA3,0xAA,0x62,0xB5, +0x94,0x16,0x2F,0x92,0x41,0xC9,0x32,0xF7,0xB5,0x1B,0x91,0x6F,0x75,0x6D,0x46,0x6B, +0xCB,0xB4,0xFE,0x0F,0x08,0x6E,0xA5,0xA2,0xAF,0x60,0x87,0x56,0xA0,0x2C,0x44,0x15, +0x21,0xA7,0xB7,0x03,0xFE,0x64,0x03,0x34,0x86,0xCC,0xAB,0xA9,0xED,0x42,0xD5,0x7C, +0x86,0xEE,0x48,0x0F,0xF2,0xF6,0x67,0x2F,0x4A,0xD9,0xCB,0x99,0x5F,0xC0,0x14,0x71, +0x6B,0xA0,0xA7,0x6A,0x91,0xA3,0xC2,0xCF,0xE1,0xFF,0xFD,0xCA,0x26,0x13,0xFE,0xCA, +0xEE,0x95,0x04,0x37,0xD9,0x9D,0x40,0x15,0x63,0xDF,0x09,0x77,0x0C,0x92,0xC4,0x1F, +0xA6,0xF5,0xA2,0x9D,0x6E,0x3B,0x33,0x2F,0xFB,0xFA,0xE0,0xF4,0xFC,0xF5,0xDC,0x45, +0xB2,0x82,0xFC,0x1B,0x8D,0xB3,0x55,0x2F,0xAF,0x6E,0x51,0xA2,0x5E,0x56,0x53,0x9F, +0xC0,0x25,0x4E,0x57,0x6C,0x04,0xC0,0x33,0xEC,0x7A,0x95,0x35,0x61,0xBE,0xB8,0x3F, +0x35,0x1E,0x19,0xF8,0x15,0x0B,0x19,0x0B,0xAC,0x1B,0xF2,0x7D,0x56,0x32,0xA5,0x4D, +0x93,0x7B,0x83,0x72,0xAE,0x80,0x39,0x6E,0x05,0xFF,0x2B,0xDB,0x6A,0xF9,0xE0,0x0F, +0x87,0xF7,0x58,0x62,0x1B,0x88,0x82,0x5C,0xDE,0xD4,0x23,0xFE,0x51,0x34,0xD8,0x00, +0xFF,0xA3,0xF1,0x7D,0x52,0x82,0xAA,0xC3,0x99,0xAD,0xF1,0x87,0x29,0xC4,0x9B,0xAC, +0x86,0x67,0x5B,0xD2,0x01,0x4D,0xD9,0x47,0x5B,0x6C,0xB5,0x49,0x05,0x58,0x51,0x64, +0xCC,0x81,0xCF,0x95,0x58,0xEA,0xE6,0xE6,0x3F,0x2F,0xBC,0xE6,0xC8,0x4B,0x50,0x1B, +0xDE,0x5F,0xE8,0x3F,0xCB,0x0D,0x6B,0xE7,0xE5,0x86,0x92,0x69,0xA4,0xEF,0x8C,0xCA, +0xF7,0xCF,0x6A,0x9F,0x74,0xB4,0xFC,0x58,0x4B,0xA1,0x5F,0x9B,0xE6,0xE4,0x90,0x38, +0x33,0x0B,0x84,0xC3,0x0D,0xEF,0x8E,0xCF,0xC3,0x4D,0x96,0x6E,0x62,0x08,0x19,0x4E, +0xA4,0x5C,0x0C,0x52,0xD6,0x48,0x0D,0x28,0xF1,0xBD,0xA6,0xEB,0x7C,0x2E,0x9B,0x6B, +0x6A,0x54,0xB6,0xFD,0x6A,0x67,0x23,0x1C,0x20,0xD0,0x37,0x11,0x8E,0x0B,0xB9,0x3E, +0x20,0xF2,0xD1,0x2E,0xF8,0x63,0xF8,0x1F,0xAE,0xCA,0xB2,0x00,0xA3,0xA4,0x18,0xE7, +0x03,0x4B,0x02,0xB0,0xF7,0x9B,0xBF,0x2F,0xDE,0xFB,0x84,0x74,0xE2,0x93,0xE0,0x92, +0x78,0x69,0x6D,0xDF,0x22,0xD9,0xF3,0x9D,0xCB,0x04,0x7C,0xB1,0xFC,0xB3,0x6E,0xDC, +0x3E,0xDD,0x96,0xBD,0x6A,0xB6,0xB4,0x18,0xCF,0x5E,0xC3,0x0F,0x7C,0xF3,0x89,0x84, +0x4B,0xF0,0x6F,0xA6,0x31,0xBB,0xD9,0xBF,0xED,0x56,0x08,0xE2,0x92,0x6A,0xAF,0x6C, +0x80,0x7E,0x1A,0xE6,0x95,0x1F,0x32,0x05,0xFB,0x34,0x63,0x50,0xB1,0xBE,0xA8,0x9B, +0x31,0xE6,0x51,0x1A,0xB1,0xC6,0x5D,0x63,0xFC,0x13,0x5B,0x28,0x5E,0x88,0x4A,0x21, +0x1E,0x7E,0x25,0x55,0xF3,0x18,0x85,0xC7,0x92,0xBD,0xEC,0x0E,0x0A,0x05,0x5A,0x9B, +0xDE,0x88,0x21,0x97,0xDD,0xDB,0xF9,0x7D,0x53,0xF0,0x4F,0xDD,0xC9,0x19,0x50,0x61, +0x39,0xA8,0xB8,0x9E,0xA5,0x46,0x52,0xD6,0x45,0x6D,0x30,0x06,0x7F,0xD9,0xA9,0xEB, +0x86,0xD1,0x29,0x12,0x5F,0x1C,0x1A,0xCA,0x46,0x26,0x42,0xD8,0x88,0xA0,0xB9,0x75, +0x06,0x0A,0x18,0x35,0x25,0x22,0xB8,0xEF,0xE0,0x75,0xF8,0x47,0xF3,0x7C,0xF2,0x9E, +0xA7,0xFB,0x8B,0x00,0xFD,0x8E,0x34,0x46,0xF7,0x73,0x39,0xC9,0xA5,0x29,0x6F,0xE6, +0xCA,0xEA,0x64,0x88,0x86,0xC9,0x2E,0x34,0x47,0x09,0x23,0x8A,0xAB,0x7D,0x6F,0x00, +0x7D,0x40,0x95,0x2E,0x48,0x14,0x95,0x60,0x6C,0x38,0x9E,0xFE,0x4C,0x55,0x14,0x3C, +0x61,0x4C,0x06,0xE8,0x8B,0xF7,0xBD,0x84,0x5E,0xFB,0x92,0xBE,0x4B,0xC5,0xEC,0x8A, +0x88,0xA8,0x36,0x50,0xA6,0x76,0xEA,0xA4,0x4F,0x75,0xBA,0x4F,0x2F,0x0C,0x84,0x29, +0x4B,0x83,0x5F,0x95,0x30,0xF2,0xEB,0x31,0x8A,0xBA,0x2C,0x6E,0xA7,0x1B,0x24,0xF6, +0xF2,0xE0,0xE3,0xDF,0x38,0x70,0x1B,0xF6,0xCE,0xC8,0xED,0xF7,0x05,0x67,0x59,0xC2, +0x8B,0xE7,0x48,0xA5,0x40,0x77,0x40,0x44,0xBE,0xD9,0x46,0x4F,0xC6,0x33,0x17,0x91, +0xCC,0x13,0x79,0x1B,0x9B,0xF4,0xBA,0x17,0x6C,0x7D,0x95,0x54,0x0B,0xE0,0xC7,0xA9, +0x74,0x0D,0xA0,0x19,0x2F,0x33,0xE1,0xBD,0x63,0x41,0x01,0x27,0x5C,0xEF,0xC5,0x96, +0x94,0x99,0xB0,0xB8,0xE8,0x70,0xEE,0x33,0xA0,0xDF,0x7A,0x44,0xCA,0x13,0x05,0xFC, +0x15,0xD7,0x60,0xC4,0xC2,0x5B,0xDA,0xBF,0xE1,0x9F,0x17,0xC6,0xAB,0x12,0x06,0xF5, +0x03,0x2D,0x8E,0xA9,0x7E,0xCE,0xDA,0x7E,0xB8,0x11,0x71,0xB7,0xC9,0x3E,0x7D,0x39, +0x09,0x80,0xBC,0x43,0x93,0x29,0x53,0x37,0x4D,0x37,0x54,0x0E,0x19,0xE7,0xFC,0x2F, +0xCE,0x59,0xF4,0x66,0x14,0x17,0x59,0x8F,0x1C,0x09,0xD4,0x76,0x5F,0x49,0x71,0xAD, +0x8C,0xBA,0x90,0x42,0xF9,0xF5,0x1B,0xDE,0xC2,0x0F,0xD2,0x9E,0x0F,0x97,0xBB,0x6B, +0xAA,0x85,0xD9,0x16,0xBC,0x81,0x4A,0x31,0x06,0x03,0xCA,0x0A,0x35,0xEC,0x8B,0xF0, +0x57,0x4F,0x12,0xF1,0xCA,0x3E,0x2B,0x5C,0xE9,0x44,0x4D,0x74,0x63,0x41,0xE0,0xF7, +0xB5,0xB2,0xB3,0x6B,0x23,0xBB,0xCB,0x1E,0x50,0xB8,0x36,0xAA,0xBD,0x2D,0x64,0x31, +0x79,0x93,0x37,0x42,0x0E,0x6F,0x3B,0x32,0x96,0x7F,0x5C,0xE6,0xE5,0x49,0xBE,0xD1, +0x70,0xA9,0x07,0x64,0x63,0x5D,0xDA,0x07,0x75,0x2A,0xD9,0xE1,0xBD,0x85,0x17,0xC2, +0x75,0xF6,0xAC,0x3F,0x02,0x96,0x70,0x28,0x23,0x1D,0x80,0x6F,0x52,0x8F,0x1B,0x42, +0x95,0x14,0x4D,0x76,0x0F,0x66,0x68,0x14,0xF6,0x98,0xD2,0x94,0x19,0x92,0xEA,0xB0, +0x11,0xCC,0x51,0x36,0x73,0xA9,0xCD,0x9A,0x33,0x9F,0x06,0xCE,0x00,0xB8,0xFB,0xF9, +0x57,0xA2,0x78,0x5B,0x88,0x2C,0x55,0xA6,0xF9,0xA4,0x89,0x4C,0xB4,0x29,0x72,0xA4, +0xD7,0x41,0x1D,0xF8,0xB9,0xA1,0xDB,0x26,0xF2,0x9C,0x92,0xDC,0x2B,0xED,0xD1,0xF4, +0xA4,0xAA,0x2F,0x5F,0xAF,0x92,0xF2,0xB9,0xC7,0x69,0x4D,0xBF,0xD0,0x42,0xE4,0x6A, +0x4B,0x42,0x70,0x9F,0x49,0xAB,0xB0,0x7B,0x1E,0x42,0x69,0xEE,0xC6,0x1A,0xFC,0xAD, +0xEE,0xB7,0x0C,0x77,0x5D,0xC3,0xE3,0x3A,0x60,0x76,0x36,0x5C,0x1D,0x7A,0x7B,0xB5, +0xEB,0x03,0x0B,0x49,0x56,0x3E,0xC8,0xF1,0xC9,0xAD,0xF1,0xD9,0x54,0x0D,0xBE,0x93, +0x71,0x41,0x7F,0xC4,0x2C,0xBA,0x7E,0xDA,0xB4,0x88,0x1E,0xD6,0x6E,0x13,0x88,0xBE, +0x5B,0x6D,0x61,0x9F,0xAF,0x80,0x76,0x23,0xC9,0x9F,0xC9,0xD9,0x7D,0xD5,0xBF,0xDB, +0x1D,0x24,0xF5,0x6C,0x92,0xD4,0xA0,0x01,0x97,0xF8,0x73,0xF8,0xEE,0x78,0xD5,0x02, +0x84,0x18,0x46,0x5C,0x59,0x0A,0x20,0x86,0xB6,0x6D,0xA2,0x53,0x22,0x9F,0x8F,0xCA, +0xA2,0xBC,0x4A,0x6B,0x86,0x0B,0x4F,0x0D,0x4F,0x73,0xDD,0x49,0x99,0x7B,0x1E,0x36, +0xD8,0x4E,0x92,0xE1,0xFB,0xBD,0x0C,0x7B,0x3F,0x70,0xF5,0x6B,0x04,0x17,0xC1,0x00, +0xC8,0x41,0x5E,0xA3,0x55,0x3A,0x21,0xBF,0x1E,0xB2,0x40,0xB1,0x3E,0x04,0x21,0xD1, +0x93,0xE7,0x98,0xC3,0xBA,0x9F,0x8A,0x36,0x6F,0x15,0x2A,0x27,0x8D,0x16,0x74,0x28, +0x03,0x5D,0x23,0x93,0x6F,0x8B,0x42,0xE3,0xF4,0x56,0x90,0xCF,0xDF,0xB7,0x28,0xAF, +0xFE,0xCE,0xE0,0x2F,0xCA,0xF1,0x7F,0xB3,0x92,0xA3,0x86,0x5D,0x67,0x4A,0x3A,0x2B, +0xC6,0x55,0x77,0x07,0x72,0xF9,0x3D,0xF9,0x5F,0xBE,0x6D,0x21,0xAA,0x95,0x06,0x8C, +0x1F,0x0A,0x3D,0x76,0x27,0xB3,0x96,0x93,0x7C,0x16,0x5B,0x35,0xA9,0x4F,0x4B,0xE3, +0x0F,0xDE,0xE6,0xD7,0xCE,0x28,0xD2,0x25,0xD4,0xBA,0xB7,0x0B,0x9B,0xD0,0x61,0x8B, +0x37,0xE0,0xA6,0x37,0x00,0x37,0x17,0xFE,0xBE,0x4F,0x2B,0x18,0xF1,0xDD,0x65,0xA7, +0xBB,0x88,0x74,0xBA,0xD5,0x22,0xF8,0xE8,0xA7,0xF2,0x41,0x53,0x6B,0xDA,0x9F,0x1B, +0x8B,0xC1,0xCE,0xB3,0x47,0x48,0xC6,0xDE,0xE7,0xC8,0xFD,0x7F,0xA5,0xE9,0xDC,0x44, +0xF2,0x41,0xF6,0x48,0x9E,0x03,0xA1,0x35,0x1F,0x95,0x7E,0xF2,0x8B,0x81,0xA1,0x27, +0x53,0xDF,0xC1,0xE6,0x89,0xAA,0x64,0x9D,0xD5,0xAB,0xAD,0x77,0x10,0x5E,0x5F,0x99, +0x56,0xDB,0xD0,0x38,0x64,0x52,0x88,0x76,0x4B,0x07,0x28,0x79,0x0F,0xD4,0x1B,0x66, +0xA2,0x42,0x2E,0x64,0xFA,0xC8,0x7E,0x4E,0x05,0x5E,0xDA,0xE8,0x3D,0x6E,0xAE,0x9C, +0x35,0xFA,0x6C,0x82,0xA5,0xDA,0x77,0x51,0x4A,0x7A,0xF2,0xC0,0xA9,0x9C,0xD7,0x29, +0x50,0x29,0x41,0xEF,0xAD,0x51,0xA8,0xDB,0xB7,0x7D,0xCA,0xFD,0x1F,0xEA,0x04,0x64, +0x7B,0x69,0x00,0x4F,0x14,0x2E,0x3E,0xBA,0x69,0x21,0xE5,0x2E,0xDB,0x75,0x6B,0xF7, +0x01,0x1E,0x2D,0xE3,0xB2,0xFB,0x05,0x43,0xBC,0xB7,0x0F,0x6B,0xCD,0x6B,0x27,0x00, +0xBD,0x89,0x0E,0x44,0x2A,0x47,0x26,0xFA,0xE7,0x6C,0x04,0x6A,0x22,0x69,0xCE,0xE8, +0x80,0x9E,0xF4,0x8F,0x23,0x2E,0x02,0xE3,0x5F,0x7E,0xFC,0x43,0xFB,0x54,0x9E,0xBF, +0xBD,0xDB,0x4D,0x8F,0x65,0x98,0xA9,0x6E,0xA8,0x7C,0xF2,0x24,0xD9,0xCB,0x22,0xAB, +0xBD,0xCC,0x2E,0x0D,0xFF,0x1A,0xEA,0x8C,0xDD,0x33,0x6F,0xCE,0x4C,0xE0,0x15,0x4E, +0x88,0x6C,0x1C,0x6E,0xA5,0xA5,0xCA,0xCD,0x34,0x81,0xFB,0xED,0xDE,0xD2,0x19,0xE4, +0xCD,0x4B,0xB2,0xB8,0x21,0x7D,0x43,0xCA,0x2A,0x17,0x6C,0x0E,0x05,0x1F,0x48,0x49, +0x74,0xB1,0x23,0x65,0x81,0x66,0xC5,0x70,0x52,0x16,0x5E,0xF8,0x67,0x3A,0x1D,0xA6, +0x60,0xF0,0x5F,0x00,0x3F,0xDB,0xB3,0x68,0x3D,0x36,0x03,0x67,0x1B,0xD6,0x2F,0xA0, +0x6D,0x21,0x91,0xD9,0x80,0x1C,0x5F,0xEE,0x1B,0x41,0x2F,0x6C,0x66,0x08,0x99,0xA2, +0xB2,0xF9,0xE4,0xC7,0xCE,0xFD,0x9E,0xD3,0xF2,0x9C,0xCB,0xAE,0x5A,0x5A,0xCE,0x9F, +0x68,0xB1,0xC5,0x71,0xB6,0xD6,0xF8,0x5F,0x20,0xAC,0x43,0x7A,0x51,0x5F,0xD2,0x38, +0x6D,0x7E,0xE5,0xF6,0x4E,0x6A,0xB7,0x03,0xCE,0xE8,0xCE,0x16,0x98,0xE0,0x95,0x96, +0x4C,0x20,0xA4,0xE6,0x43,0x6C,0x1B,0xA0,0x2F,0x06,0xCC,0x45,0x3A,0xE7,0x6A,0xEC, +0xF6,0x23,0x2F,0xD3,0xB3,0xAE,0x06,0x7D,0x47,0xC0,0xEA,0x1D,0xC4,0x97,0xB7,0xBB, +0x66,0x18,0x85,0xE3,0xF8,0x9F,0x36,0xCE,0xDA,0x04,0x53,0x65,0x01,0xCB,0x2A,0x8A, +0xE6,0x46,0xB7,0xCE,0xC1,0x57,0x46,0x6E,0x1E,0xF7,0xE3,0xBF,0x70,0x39,0x29,0x71, +0x9B,0x9E,0x0B,0x18,0x37,0x65,0x55,0xA7,0x27,0x23,0x6E,0xD6,0xD4,0x0E,0x41,0x18, +0x8C,0xCB,0x0F,0x15,0xE7,0xCA,0x8A,0xD9,0x06,0xB9,0xC1,0x27,0xEA,0x73,0xD1,0xB0, +0x03,0x69,0x9A,0x99,0x12,0xC9,0x20,0x83,0x96,0x30,0x4A,0xED,0x0B,0xFB,0xBE,0xC8, +0xA8,0x1C,0x10,0x0B,0x67,0x48,0x48,0x52,0x33,0x64,0x1B,0x56,0xCB,0xE4,0xC2,0x12, +0xC5,0x50,0xBB,0xDE,0x98,0x40,0x88,0x77,0x2F,0x5D,0x8D,0x00,0xDC,0x69,0x28,0xD0, +0x1C,0x5B,0x61,0xA5,0xB6,0xF7,0x74,0xA1,0x02,0x6B,0x69,0x50,0x4C,0x6B,0x39,0x6F, +0xF3,0xCE,0xA4,0x84,0xE6,0xD9,0x64,0x10,0x55,0x82,0xBD,0x13,0xB9,0x42,0xA9,0x06, +0xE3,0x85,0xB3,0x05,0x3B,0x78,0xA6,0xA0,0x10,0x11,0xCE,0xD8,0xF5,0x05,0x61,0xEF, +0x3A,0xF8,0x8D,0x12,0x77,0xC3,0xBA,0x98,0x20,0x1B,0xB7,0x49,0xE6,0xB7,0x70,0xFD, +0xC8,0xA5,0x46,0x41,0x76,0x72,0xDE,0x45,0x1D,0x73,0x10,0x40,0xA7,0x67,0xE1,0x14, +0x39,0xB0,0x3E,0xF8,0x23,0xFB,0x23,0x27,0x57,0x22,0xAD,0xA9,0xE9,0xFE,0xA8,0x4A, +0xB4,0x2F,0x01,0xCF,0x41,0x92,0xC6,0xED,0x7D,0x92,0xB2,0x79,0xFF,0xC2,0x67,0x05, +0xAC,0x62,0x16,0x76,0x3E,0x0A,0xCF,0x80,0x0C,0xE9,0xF6,0xDC,0x2A,0xE5,0xE2,0x01, +0x6C,0x98,0xAF,0xA7,0xE9,0x23,0xB8,0x7E,0xBF,0xD6,0x20,0x67,0x6C,0xDF,0x07,0x4A, +0x32,0x1D,0x15,0xDD,0xDA,0xA8,0x25,0x71,0x18,0xC6,0x95,0xBA,0x62,0xB8,0xB2,0x93, +0x5C,0x45,0x72,0xA6,0xF8,0x40,0xFB,0x96,0x1C,0x0B,0xFD,0x25,0x22,0x41,0x60,0x3B, +0xF1,0xDA,0xCE,0xB9,0x5F,0xB6,0x9E,0xD0,0x7D,0x9D,0x15,0x00,0x2B,0x49,0x99,0x59, +0xB5,0x1F,0xA8,0x6C,0xB5,0x2F,0x6A,0x2C,0xF9,0x2A,0xF3,0xB3,0x84,0xEF,0x4F,0x21, +0x36,0x3F,0x5E,0xED,0x8C,0x20,0x24,0x72,0x1D,0x8A,0x9F,0xF9,0x28,0xA3,0x64,0x6A, +0x35,0xFD,0xD7,0xC2,0x36,0xB1,0x02,0xF6,0xDC,0x6D,0x3B,0x66,0xD0,0x41,0x4D,0x79, +0xF6,0x2E,0x36,0x52,0xEC,0x51,0xF2,0x58,0xC0,0x3F,0x21,0x69,0x3F,0x15,0xAD,0x8F, +0xF1,0xAE,0xF8,0xBC,0x48,0xF9,0x77,0x09,0x08,0xB9,0xF7,0x1E,0x8F,0x9E,0x9C,0xE0, +0xAE,0x8E,0xFE,0x26,0x6F,0x56,0xFE,0x58,0x83,0xDF,0x17,0x87,0x8D,0x46,0x90,0xAF, +0x2C,0x55,0x79,0xB3,0x0B,0xCA,0x52,0xB3,0xA1,0x2C,0x4F,0x1A,0x26,0x0D,0x8B,0x39, +0x06,0x8F,0x24,0x5B,0xAB,0xB3,0x62,0x68,0x90,0xE3,0xC1,0x9D,0xFE,0x8E,0x35,0x9C, +0x2D,0x1E,0xD2,0xE5,0x9E,0x24,0xD8,0xA3,0xBE,0xD7,0xA9,0x37,0xE5,0x9B,0xDB,0x28, +0x35,0x45,0x43,0x3A,0x20,0x42,0xC5,0xEF,0xA2,0x4C,0xD9,0x0D,0x76,0x08,0x55,0x6E, +0xC2,0x2C,0x64,0x73,0xFD,0x32,0x83,0xEB,0x0C,0xE6,0xBF,0x47,0x1E,0xD0,0x73,0x7C, +0x54,0x7B,0x4B,0xE1,0x5F,0xC5,0x6C,0x37,0x9A,0x70,0xCF,0x43,0x4F,0x15,0x5D,0x35, +0x7C,0x0B,0x29,0xDF,0xD2,0xF1,0xCC,0xA2,0x4B,0x6F,0x1C,0x51,0x15,0xD7,0x0E,0xE6, +0x8D,0x7B,0x19,0x51,0x20,0x59,0xA9,0x6A,0xE3,0xAC,0x27,0x80,0x1D,0xD2,0xF1,0xD8, +0x30,0x9B,0xB1,0x43,0x55,0x16,0x6F,0x2C,0x2D,0x9A,0x21,0xBE,0x58,0x9F,0x6C,0x17, +0x30,0x9B,0x15,0x04,0x76,0xF0,0x0C,0xD0,0x13,0x6B,0xF5,0x3F,0x61,0xB6,0xE9,0xA2, +0x02,0xED,0x1B,0x70,0x65,0x3B,0x4C,0x57,0xEA,0x88,0xF5,0x72,0x5D,0x96,0x49,0x8D, +0xE8,0x07,0xA8,0x4D,0x15,0xAB,0x4E,0xB3,0x78,0xEB,0x90,0x81,0xD3,0xA7,0xB0,0x04, +0x9B,0x04,0xFF,0x49,0xC7,0xFF,0xF5,0x64,0xF5,0xAE,0xD7,0xE7,0x7D,0x2E,0xC5,0x3D, +0x17,0x91,0x39,0x11,0xF4,0x22,0x36,0x0B,0x6E,0x44,0x3B,0xFC,0x85,0xF5,0x39,0xCF, +0x60,0x2F,0x8A,0x06,0xE4,0xB2,0xA1,0x4D,0x87,0xBB,0xA8,0xE6,0xA9,0x98,0x3F,0x98, +0x6C,0x33,0x06,0xF6,0x65,0xD8,0x7D,0xB7,0x58,0x0F,0x27,0xFC,0xE3,0xA4,0xC0,0xC2, +0x14,0xE5,0xF5,0x32,0x11,0x52,0x0A,0x6F,0xCA,0x8C,0xA3,0xD5,0x37,0x5F,0xCC,0x81, +0xA5,0xBB,0x35,0x5A,0xC7,0xF9,0xDE,0xF4,0xAF,0x25,0xFE,0x3B,0x33,0x29,0xAE,0x4A, +0x93,0xCD,0x08,0xF2,0xE0,0xAA,0x4F,0xE8,0xE6,0xC7,0xA4,0xCE,0xE4,0xE5,0x97,0xB0, +0x60,0x94,0xDB,0x20,0xA5,0x92,0x9A,0x04,0x85,0x68,0x61,0x75,0x1F,0xBA,0x6E,0x2B, +0x40,0xB9,0x39,0x35,0x76,0xE8,0x4E,0x3A,0x92,0xB3,0x9D,0xC7,0x5D,0x32,0x8C,0xBF, +0xB7,0xDF,0xF2,0x9B,0xCC,0x44,0x5F,0x65,0x7B,0x58,0xA3,0xEA,0x57,0xA8,0xD7,0x13, +0x64,0x77,0x33,0xD1,0xC5,0xC1,0x58,0xBA,0x41,0x5A,0x3A,0xC0,0x64,0x45,0xFC,0x26, +0x78,0x56,0x9E,0xE4,0xCB,0x23,0xE1,0x7E,0xA5,0x4F,0x0C,0xDE,0xEB,0x1E,0xC5,0xE5, +0x1E,0x5A,0xE4,0x3E,0x82,0xE5,0x5A,0x8A,0xF8,0x57,0x5A,0xBD,0xEA,0x7D,0x3F,0x83, +0x01,0x27,0x5E,0xFD,0x55,0x46,0xBB,0xE0,0xA3,0x1D,0xD2,0x35,0x03,0x30,0x62,0xC5, +0x5A,0xF0,0xF0,0xA0,0x62,0x74,0xFA,0xB9,0x78,0x90,0x77,0x69,0x5D,0x3D,0xAA,0x5A, +0x2B,0xD6,0x79,0xB8,0xB2,0xE9,0x62,0xC6,0xE6,0xC7,0xE4,0x92,0xE5,0x1A,0xD9,0x87, +0xF4,0x76,0x8C,0x80,0x5E,0x5A,0x95,0x0C,0xC3,0xDE,0x51,0x25,0x72,0x20,0x78,0xAF, +0xB4,0x42,0x1F,0xB2,0xE0,0x78,0xF2,0xDC,0xFF,0x96,0x04,0xFF,0x0B,0xC1,0xD7,0x13, +0x32,0x54,0xF5,0x82,0xC5,0x3E,0x43,0x49,0x58,0x5C,0xAD,0x8E,0xB2,0x0C,0x18,0xE1, +0x3A,0xE2,0xC6,0x75,0x22,0x2A,0x57,0xCB,0x82,0x48,0x6C,0x6B,0xF4,0xF1,0x0E,0xBF, +0xA3,0x1F,0x72,0xD7,0x84,0x11,0x20,0xCF,0x43,0xDA,0x99,0xCF,0x4D,0xEB,0x0A,0x41, +0x37,0x74,0x09,0x7F,0xD6,0x49,0x67,0x45,0xFE,0xCB,0x2F,0x83,0x98,0x73,0x89,0x20, +0xDE,0x3D,0xC3,0x78,0xB5,0x91,0x5C,0xBE,0x97,0x1A,0xE1,0xE6,0x98,0xF0,0x39,0xC6, +0x9C,0x0A,0x28,0x4D,0xB5,0x97,0xF0,0x25,0x73,0xC2,0x38,0xF8,0xB1,0x4F,0x4B,0x5F, +0xB1,0xE3,0x68,0xCD,0xF1,0xB5,0x31,0x4A,0xB6,0xCD,0x82,0x4F,0xA4,0xBB,0x0F,0xDA, +0xB8,0xBD,0x05,0x99,0xF0,0x68,0x2E,0x9F,0x1C,0x99,0xA2,0x48,0xD0,0xDB,0xA4,0x81, +0x09,0x66,0x30,0xCB,0x9B,0x96,0xCB,0x66,0x24,0xEA,0x5D,0x5D,0x46,0xDA,0x0F,0xFC, +0xD5,0xA9,0xAB,0xE4,0xE5,0xB5,0xB5,0xD4,0xDC,0x2F,0xF0,0xF9,0x11,0xD6,0xAB,0xA6, +0x10,0x7A,0xB1,0x4B,0xF2,0xB5,0xCA,0xF0,0x4E,0x75,0x18,0x81,0x13,0x4F,0x57,0x9D, +0x99,0x21,0x9E,0x7A,0xCC,0xE8,0x07,0xFE,0x61,0xDD,0xB9,0x3B,0xA4,0x7F,0xD2,0x3A, +0x6C,0x58,0xCC,0x3D,0x2F,0x46,0x40,0x59,0xAC,0x0C,0x81,0xFA,0x94,0x0C,0x05,0x13, +0xF8,0xEB,0x91,0x0F,0x0A,0x9D,0xA8,0xFE,0xEC,0x73,0x81,0x6C,0xFA,0x6F,0xB7,0x84, +0x55,0x24,0xA6,0x36,0x8F,0x50,0xCC,0xFC,0xAA,0x7E,0xF8,0x9C,0xF8,0x3D,0x96,0x47, +0x4F,0x76,0x0F,0x35,0xFA,0x20,0x25,0xBF,0xA6,0x12,0xA5,0x1B,0x76,0x94,0x93,0x64, +0x4D,0x48,0xFD,0xEB,0x34,0xDE,0x1E,0x8D,0x11,0x92,0x94,0xF9,0x10,0x72,0x26,0x2C, +0xAB,0xE2,0x3C,0xA2,0x16,0x51,0x6E,0x07,0xF6,0xE3,0xB9,0x24,0x35,0x20,0xBF,0xA1, +0x8A,0x28,0x9D,0xF3,0x38,0xA5,0x18,0x49,0x39,0xF8,0x74,0xE9,0x19,0x71,0x18,0x1D, +0x17,0xDA,0xB9,0x30,0x8F,0x92,0xF1,0x47,0xB8,0x15,0x7F,0x7A,0x7C,0x6F,0x2A,0x39, +0xB2,0xE3,0x77,0x50,0xAA,0x3A,0x15,0x63,0xCD,0xE1,0xA3,0x48,0x08,0x15,0x8D,0x3C, +0x3C,0x5E,0x92,0xFB,0x53,0xDF,0xE4,0x97,0x6D,0x79,0x7D,0x38,0x07,0xE3,0x3C,0x11, +0xC3,0x63,0x5A,0x90,0x35,0x43,0x7B,0x89,0x3D,0xAB,0xB8,0x00,0xF2,0xEA,0xA3,0x00, +0xB7,0x37,0x1C,0xD8,0x78,0x8A,0xC4,0x94,0xDE,0xFD,0xB3,0xC5,0xEA,0x6D,0x45,0x34, +0x6A,0xAF,0x39,0xAD,0x2D,0x6D,0x9D,0x7A,0xDB,0xCF,0x6F,0xB1,0xBF,0xCB,0xB7,0x66, +0x6D,0x3E,0xA8,0xE5,0x70,0xDA,0x23,0x74,0xF2,0x3B,0x06,0x16,0xFC,0xA6,0x8C,0xC6, +0xBC,0x62,0x2E,0x9E,0x18,0xC4,0xD7,0x29,0x9F,0x92,0xBF,0x70,0x6E,0xCC,0x71,0xA9, +0x6E,0x22,0x7D,0x04,0x3A,0x71,0x74,0xA8,0x64,0x4A,0x16,0xAE,0x96,0xC4,0xFF,0xDD, +0x7D,0x28,0x29,0xF0,0xC4,0x33,0x01,0xB7,0xA2,0x8F,0x65,0xD8,0xFD,0xC4,0xA8,0x95, +0x9F,0x08,0xCA,0x75,0x23,0x23,0xF7,0xD3,0x93,0xB7,0x5C,0x45,0xEF,0x01,0x70,0xDD, +0x84,0x43,0xA5,0xE6,0x6D,0x56,0x56,0x4D,0x1A,0x4D,0x8D,0x35,0xDA,0x20,0xB8,0x30, +0x9C,0xE0,0x0D,0xF9,0xE6,0x35,0x0A,0x2B,0xAA,0xB4,0xA4,0x4B,0xDC,0x35,0xBC,0xF3, +0x91,0x7C,0xAC,0xA1,0xC4,0x28,0x6E,0x09,0x8C,0xB6,0x21,0xC7,0x16,0x26,0x29,0x8E, +0x5F,0xD6,0xF0,0x48,0xA5,0xED,0x23,0x7D,0xD6,0x07,0x78,0xF1,0x01,0x78,0xC7,0xD5, +0x93,0x6F,0x47,0x5F,0x46,0x91,0x11,0x1A,0x47,0xEF,0x5B,0x77,0xE0,0x7E,0x0C,0x3B, +0x73,0x7E,0x6D,0x6E,0xD0,0x3B,0x5E,0x11,0xC7,0xC1,0x79,0xFB,0xDD,0xC5,0xC1,0x0A, +0xD1,0x55,0x88,0x2A,0xB8,0x5C,0x6D,0xEA,0x50,0x44,0xDD,0x9B,0x31,0x39,0xAA,0xCD, +0xC4,0xF0,0xE7,0x8F,0x66,0x1A,0x41,0x87,0xB4,0xB6,0x1E,0x62,0x24,0xB8,0xB1,0xF9, +0x8A,0x75,0x17,0x8A,0x8D,0x29,0x95,0x93,0xE7,0xE9,0x69,0xA0,0x3F,0x49,0xB8,0x3A, +0x98,0x72,0x16,0x60,0x8F,0x63,0xB3,0xF4,0xF5,0x18,0x59,0x29,0xE3,0xCB,0x7F,0x6F, +0x8F,0x93,0x44,0x11,0x12,0x54,0x2E,0x94,0xC7,0x83,0x62,0x4B,0x01,0x12,0xA6,0x17, +0x0B,0x3B,0xA6,0xF0,0xE4,0x1A,0xA9,0x9F,0xB9,0xAF,0xC1,0x48,0xE7,0xD7,0x4A,0x79, +0x6E,0xF2,0x6D,0x4D,0x29,0xAA,0x93,0x42,0x23,0x2C,0xB7,0xC5,0x9E,0xBB,0x9C,0x18, +0x68,0xD7,0x02,0x9D,0xB1,0xD7,0x1A,0xC0,0x0E,0x74,0x71,0xE7,0x04,0x91,0xC3,0x4F, +0xF7,0x65,0x5A,0xC7,0x5D,0x97,0x59,0xB6,0x46,0x4A,0x3C,0x48,0xDD,0x1A,0x40,0x11, +0x34,0x05,0x32,0x9C,0x8C,0x69,0xE2,0x33,0xE0,0x0C,0x20,0xE6,0xC1,0xCF,0x54,0xCB, +0x28,0x7C,0xC9,0xBB,0x0A,0x2F,0x24,0xC3,0xF5,0x46,0x83,0x91,0x4B,0x4F,0x3D,0xC1, +0x3F,0xE0,0xAC,0x93,0xB9,0x64,0x1A,0x00,0x03,0x14,0x86,0x94,0xFD,0x8D,0xB2,0x1E, +0x28,0x03,0xD1,0x7C,0xDE,0xC2,0x6A,0x58,0x32,0x9D,0xD0,0xB8,0x15,0x78,0x5D,0xA3, +0x66,0xC1,0xB7,0x3C,0x4C,0x70,0xAA,0xD2,0x2A,0x01,0xB4,0x42,0xE6,0x66,0xD1,0xC3, +0xC8,0x54,0x62,0xB1,0x5D,0x41,0x8C,0x06,0x73,0x11,0xA1,0xB8,0x0C,0x59,0xD2,0xE0, +0xA7,0x23,0x85,0xD0,0x8A,0x2F,0xB5,0xA2,0xF1,0xFF,0x5F,0x57,0xFA,0x2D,0x45,0x0C, +0x1E,0x56,0x5C,0x69,0x17,0x39,0xB8,0x5C,0x4D,0x70,0x07,0xE0,0x71,0xF3,0x6C,0x96, +0xBC,0x43,0x9B,0x9B,0x74,0x3C,0x36,0x42,0x0B,0xD8,0x40,0x88,0x48,0xE3,0x98,0xA9, +0x56,0xB0,0x28,0x40,0x58,0xE3,0x7C,0x90,0x4E,0x64,0x86,0x0C,0xB4,0x00,0xD5,0xC4, +0x3C,0x13,0x7D,0xF2,0x71,0xDB,0x1A,0xB2,0x8B,0x7A,0x56,0xB0,0x49,0x53,0xC3,0xCA, +0x5A,0xF8,0x4B,0xD2,0x1B,0xCE,0xEA,0xA0,0x3D,0x46,0x1B,0x70,0xDA,0x5E,0x29,0xC9, +0x9C,0xD2,0xC5,0x62,0x7B,0x8F,0x78,0x9A,0x26,0x75,0xA3,0x79,0x9F,0x39,0x80,0xA7, +0xE6,0x22,0xAD,0x2F,0x8A,0x64,0xE5,0x1A,0xD6,0x7C,0xCB,0x67,0xA9,0x9B,0x29,0xC4, +0x62,0xD9,0x67,0x9E,0x9B,0x8F,0xF2,0x65,0x6E,0x9F,0x1C,0xDA,0xD2,0xA0,0x58,0x25, +0x76,0x62,0xAD,0x9A,0xEB,0xFC,0xD2,0x4C,0x38,0xED,0x48,0xDF,0xC8,0x01,0xEF,0xF4, +0x28,0x51,0x04,0xAA,0x57,0x3D,0xAA,0xF2,0x4A,0x43,0x84,0x4C,0xCD,0xCB,0x90,0x95, +0x3C,0x04,0xF7,0xD3,0xA1,0x6C,0x37,0x87,0x81,0x50,0x30,0x86,0xF2,0x58,0x37,0x33, +0x5A,0x4D,0x26,0x64,0x26,0xD8,0x0F,0x7E,0xB3,0x6D,0xD2,0xB1,0xE5,0x50,0x82,0x55, +0xB1,0x19,0xBE,0x1C,0x28,0x19,0x62,0xAD,0x33,0x18,0x3F,0x8E,0xFC,0x2F,0x6C,0x1E, +0x40,0x40,0x58,0x1F,0x91,0x14,0xB7,0x26,0x1A,0x0A,0x88,0xB8,0xE7,0x74,0x8F,0xFB, +0x3C,0x59,0xB7,0x5F,0x40,0xAF,0x8E,0x45,0x2F,0x81,0x32,0x08,0xBE,0x5C,0xD9,0xDF, +0x7A,0xB4,0x40,0xA9,0x45,0x89,0xFC,0x69,0x4F,0x48,0x38,0xFA,0x3D,0xFA,0xEC,0x21, +0x88,0x41,0xD4,0xAE,0xA8,0x2C,0x22,0xEC,0xB5,0xD5,0xBD,0x93,0xFF,0xD0,0x40,0x6B, +0xF4,0xE9,0x9B,0xC5,0x2D,0x09,0x62,0xDA,0x62,0xEF,0xB5,0xBD,0xD1,0x15,0xFA,0xFB, +0x04,0x6D,0x7E,0x79,0x9C,0x9C,0xD3,0x39,0xB9,0x42,0xE4,0x29,0xFA,0x5E,0x52,0xC6, +0xA6,0x6A,0x50,0xFF,0x20,0xE4,0x32,0x24,0x44,0x15,0x00,0x5B,0xE4,0xA4,0x39,0x4F, +0x6E,0x9B,0xC5,0xD2,0x50,0xB1,0x7F,0x73,0xCD,0xC6,0x52,0x48,0xDA,0x57,0x4A,0x2B, +0xB0,0x52,0xF2,0x2B,0xFB,0x0C,0x1B,0x34,0x05,0x83,0xCB,0x1F,0x1E,0xEC,0xFB,0x59, +0x46,0x00,0x0C,0xCC,0xC3,0xF5,0x74,0x6F,0xD4,0x88,0x5E,0x86,0xF0,0x8B,0x9D,0x49, +0x3D,0xF2,0x5E,0xEC,0xAB,0x79,0x52,0x22,0x73,0xE5,0x1F,0x64,0xE4,0xA4,0xE9,0x89, +0xA7,0x23,0xFB,0x28,0x87,0x74,0xBB,0x24,0x5A,0x27,0x86,0x86,0xA1,0xC6,0xDC,0x4D, +0xE1,0xB2,0x7E,0x0C,0x66,0xDE,0x5C,0x52,0x83,0x3F,0x88,0xCB,0xEC,0x11,0x13,0xC7, +0xA5,0x77,0xBF,0x3C,0x0B,0xF5,0xE9,0x5C,0xE5,0x70,0xB3,0xE9,0x71,0x0A,0xB2,0x21, +0xCB,0x44,0x0E,0x38,0xBF,0xC3,0xAB,0x3B,0x3A,0x24,0x34,0x11,0x9C,0xED,0x3D,0xDD, +0xFF,0xC6,0xFD,0x23,0xA8,0xAD,0x36,0x9B,0xF9,0xD9,0xA3,0x99,0x7E,0x2D,0x1E,0x47, +0x1B,0xD3,0xEA,0xFB,0xCA,0x70,0x71,0xE8,0x0E,0x85,0x85,0x65,0x15,0xA3,0xC5,0x9F, +0x5B,0xE0,0x48,0xD5,0x9F,0x91,0x00,0x53,0x7A,0xA6,0x30,0xBF,0x19,0xC3,0x60,0x39, +0xF3,0x62,0x88,0x70,0x88,0x54,0xB2,0xF4,0xBD,0xAD,0x82,0x9E,0xEB,0x9F,0x37,0x00, +0xDD,0x0E,0x3E,0x26,0x10,0x06,0xA3,0x3D,0x46,0x42,0x76,0x03,0xFA,0x8E,0x3A,0x5E, +0x24,0xC3,0x4E,0xCA,0x49,0xF2,0xE4,0xFA,0x22,0x4C,0xB6,0x60,0x15,0x6B,0x3E,0xC7, +0x69,0x49,0xDD,0xE6,0x08,0x55,0x36,0x1E,0x83,0x86,0x3F,0xB2,0xC4,0x3E,0x98,0x17, +0x83,0x05,0x08,0x8A,0xCC,0x54,0x4A,0xEB,0xA6,0x86,0xAD,0xF6,0xC3,0x6C,0x60,0x78, +0x34,0xB1,0x91,0x0B,0x5D,0xBF,0xD4,0x67,0x5C,0xE1,0x79,0xB9,0xD5,0xFB,0xBF,0xF9, +0xA7,0x55,0x82,0x29,0xA2,0x5A,0xA4,0xD0,0x27,0x31,0x4E,0x0A,0x16,0xE0,0xD6,0xB0, +0x9F,0xF1,0x6F,0x11,0xCE,0xEE,0xCD,0x45,0xD4,0x8B,0x00,0xFA,0x29,0x7F,0xB8,0x2F, +0x28,0xC7,0xC9,0xAC,0x37,0x2F,0x8C,0x1B,0xFB,0x8D,0x3E,0xD2,0xFD,0xCB,0xF1,0x44, +0x0E,0x1D,0x42,0x3A,0xE4,0x80,0x97,0x91,0x8D,0xAD,0xFF,0x4A,0xE1,0x2A,0x44,0xC2, +0xC0,0xA7,0x51,0x61,0xC0,0x75,0x72,0x19,0xCC,0xE7,0xF6,0xE8,0x19,0x4E,0x9C,0xDB, +0x38,0x96,0xBC,0xAE,0xDB,0x45,0x2C,0x06,0x05,0x93,0x18,0xFA,0x42,0x84,0x19,0xC7, +0xBD,0x31,0xA3,0x85,0x4B,0x46,0xCC,0x8A,0x92,0xFD,0x15,0xDB,0x41,0xC2,0xF3,0x5A, +0x33,0x73,0xB9,0xC8,0x58,0x7D,0x7F,0xB6,0x5D,0xBC,0xDB,0xBD,0xF7,0x03,0x1D,0x6D, +0x59,0x12,0x44,0x3F,0xE4,0xC0,0x37,0x89,0x38,0xA2,0xA5,0x75,0x16,0xF1,0xF3,0xC1, +0xAB,0x69,0xD9,0x18,0xA5,0xFD,0xEF,0xE1,0xD2,0x68,0x3D,0x78,0x9C,0x3E,0x65,0x61, +0xE7,0x21,0x4C,0x8B,0xE2,0xC5,0xD2,0x63,0xB6,0x89,0x31,0x7F,0x32,0xDD,0x03,0xBA, +0x4D,0x5E,0x07,0x08,0xB6,0x11,0x19,0xE8,0xBA,0xC3,0x16,0xEF,0xC6,0x85,0x4D,0x13, +0x54,0x31,0x51,0xE8,0xA6,0x9D,0xBB,0xE8,0xAE,0xA0,0x2F,0xB7,0x87,0x3B,0x60,0x77, +0x70,0x6E,0x77,0x76,0xCA,0xE4,0xC8,0x44,0xBF,0x0D,0x30,0x46,0x87,0x1A,0x4A,0xFF, +0xF1,0x45,0xC3,0x24,0xF0,0xC0,0x92,0x31,0xE4,0x6B,0x5A,0x74,0xBC,0x52,0x59,0xE3, +0x92,0x97,0x00,0x58,0x47,0x50,0xDF,0xE7,0x0D,0x14,0x8E,0x0F,0x53,0x11,0xBD,0xC7, +0x28,0x4B,0xF1,0x34,0x23,0x69,0x5E,0x0E,0xAF,0x95,0x9C,0x08,0x56,0xD4,0x90,0xA3, +0x7D,0xBD,0x4B,0x7A,0xBE,0xF3,0x14,0x9D,0x29,0x6D,0xB7,0xD7,0x11,0x09,0x85,0x2C, +0xDE,0xC1,0x14,0xED,0x6D,0x5D,0xEF,0x11,0x0E,0x29,0x86,0xBA,0x4A,0xEF,0x71,0x66, +0x7B,0x26,0x77,0xF3,0xCD,0xCD,0x2F,0xD9,0x62,0xB3,0xE6,0x5C,0xFC,0x7F,0xF4,0x69, +0x11,0x44,0xAB,0x47,0xD2,0xA6,0x84,0xAD,0xB9,0x96,0x7F,0x18,0x4C,0xD9,0x4A,0x32, +0x6F,0xFC,0x9C,0x49,0x91,0xE3,0x01,0x09,0x95,0x54,0x6E,0x29,0x20,0x6A,0x51,0x72, +0x1A,0x86,0xF3,0x04,0xA0,0x3D,0x06,0x56,0x15,0x09,0x5A,0x5E,0xEB,0xF1,0x28,0xC6, +0xAF,0xC4,0xA1,0xEF,0x09,0x2B,0xE8,0xCE,0x67,0x2D,0x4A,0x7F,0x1C,0xAE,0xFA,0x0F, +0xB8,0x96,0x8B,0x37,0xFB,0x8D,0xFD,0x50,0x35,0xC9,0xBF,0x89,0x22,0x62,0xFF,0x66, +0x82,0x70,0xB6,0x2D,0x59,0x73,0xC5,0x76,0xC5,0xBB,0xF6,0xA9,0x26,0x69,0xB5,0x9F, +0x5D,0x30,0x88,0x95,0x99,0x63,0x43,0x89,0xE1,0x6B,0x62,0x6B,0x41,0x3E,0x81,0x01, +0x74,0xFA,0x46,0x66,0x1E,0xF6,0x7B,0x45,0xE7,0x48,0xAC,0x6A,0xC1,0x77,0x6B,0x65, +0x9C,0x55,0x8C,0x69,0xE8,0xD9,0xF5,0xD0,0x55,0xB8,0xF3,0xC8,0xEB,0xCF,0x87,0xDC, +0xF5,0x91,0x65,0xC1,0x57,0x63,0x30,0x8D,0xBD,0xEB,0xE8,0xCA,0x90,0xF6,0x52,0x71, +0x9A,0x6B,0xAB,0x1A,0xD0,0x26,0xA4,0x8E,0x41,0x67,0x1B,0xBB,0x50,0x18,0x3B,0xD5, +0x5B,0xE4,0xF2,0xE9,0x3A,0x19,0x8D,0xFB,0x2C,0x4D,0x00,0xF0,0x84,0x89,0x68,0xE2, +0x97,0xF1,0x78,0x07,0x71,0xD3,0x3D,0xD7,0xB8,0x49,0x5B,0xEE,0x62,0x61,0xCE,0x76, +0x03,0x1F,0xF4,0xE1,0xF9,0x9B,0xD3,0x78,0x5B,0xEB,0x3E,0x8D,0x63,0x91,0x6F,0x79, +0xA6,0x48,0xE5,0xAF,0x88,0xB3,0x9B,0x67,0x13,0x63,0xCD,0x5A,0xC4,0x5D,0xFB,0x53, +0xF2,0x62,0x0E,0x29,0x65,0x52,0x36,0x5F,0x98,0x34,0x3D,0xCC,0xD9,0x9A,0x25,0xCC, +0x08,0xFC,0x14,0x2A,0x79,0x95,0xC7,0x3B,0x15,0x9A,0x03,0x4D,0xF1,0x19,0xFB,0xA0, +0x89,0x18,0x11,0x81,0x1F,0x89,0xFD,0xC2,0xA1,0x60,0xC8,0x9D,0xED,0xBC,0xA1,0x24, +0x00,0xA6,0xEE,0x36,0x1D,0xA0,0x8A,0xCE,0xE6,0x18,0x59,0xA4,0x84,0x3E,0x56,0x3C, +0xAD,0xB3,0x99,0xBC,0x3F,0x4F,0xF6,0x0B,0x27,0x7A,0x88,0xC3,0x1A,0xBE,0xB1,0x39, +0x3A,0xB9,0xCE,0x7F,0x97,0xF1,0xDA,0xD2,0x51,0x7D,0x37,0x3B,0x12,0x10,0x93,0x5D, +0x39,0x85,0x3A,0x64,0xE6,0x0B,0x68,0xC0,0x83,0x09,0xD2,0x34,0xA2,0x2E,0x19,0xD1, +0xCE,0xA2,0x63,0x37,0x08,0x4F,0x78,0x0D,0x54,0xDB,0xC6,0x62,0x33,0xC6,0xD6,0x7C, +0xFD,0xDC,0x8A,0x2F,0xD1,0xE3,0xA6,0xCF,0x39,0x31,0x2C,0x7C,0x3B,0xC1,0x5D,0xEB, +0x79,0x6F,0xF8,0x4F,0xA8,0xE5,0xD4,0x65,0x16,0x68,0x9A,0x3A,0x61,0x73,0xB5,0xB9, +0xA3,0x23,0x9C,0x68,0x23,0xE7,0x21,0xA2,0x28,0x48,0x6D,0x2B,0x16,0xDA,0x2F,0xF7, +0xAE,0xBC,0x72,0xD1,0x54,0xA5,0x8D,0x40,0x2C,0x90,0x38,0x19,0x14,0x9A,0x8C,0x80, +0x5B,0x19,0xF1,0xB6,0xD9,0x0D,0x3B,0x53,0x88,0xD5,0x94,0xB2,0xED,0xE4,0x6B,0x1F, +0xB9,0x63,0x2A,0x76,0xFB,0x07,0x79,0x6E,0x79,0xF6,0xA2,0x71,0xF0,0x14,0x08,0x83, +0x0A,0x25,0x34,0x70,0x09,0x87,0xB2,0x8D,0x46,0x9D,0x8A,0x01,0xD8,0x44,0xD6,0x83, +0x09,0xF8,0x83,0x93,0x4A,0x65,0xEC,0xB6,0xEB,0x06,0x7C,0xA9,0x13,0xE3,0x4E,0x0C, +0x7F,0x0D,0xE6,0x4A,0xB7,0x09,0x01,0xF8,0x34,0x53,0xB9,0x9E,0x1E,0x19,0xE2,0x07, +0xFF,0xC9,0xC2,0x41,0x3D,0xE5,0x0F,0x2A,0x30,0x47,0x66,0x60,0xBB,0x9C,0x60,0xF2, +0xE9,0xFA,0x8B,0x52,0xF2,0x88,0xBF,0x5C,0x1E,0x8C,0x7F,0xDD,0xF2,0xCB,0xAB,0xC7, +0x47,0xD1,0xEB,0xFB,0xD3,0x88,0x9D,0xBA,0xBD,0x8D,0xAD,0xF1,0x0E,0xD3,0x8C,0x9A, +0x89,0x53,0x71,0xCC,0xB6,0x2C,0x67,0xB2,0xD5,0xB1,0x10,0x97,0x45,0x7F,0x82,0xE2, +0xB4,0x3E,0xF8,0xA9,0xF6,0x03,0xF8,0x69,0xC5,0xD7,0x46,0x3C,0x63,0xA1,0x4A,0x28, +0xE6,0x94,0xE0,0x13,0x5F,0x97,0xEE,0x96,0x6E,0xDB,0x1A,0x15,0x6A,0x9D,0x69,0x6A, +0x9E,0x17,0x07,0x84,0xB0,0x58,0x20,0xE6,0x18,0x3C,0x26,0x26,0x59,0xAD,0xC0,0xB4, +0x96,0x89,0xC2,0xB9,0x50,0xB8,0x22,0xB9,0x8A,0xC4,0x04,0x3A,0x1A,0xE3,0xB6,0x2E, +0x9F,0xF0,0xE0,0x73,0x2A,0xAE,0x50,0xBD,0x56,0x08,0x53,0x24,0x22,0xB0,0xF2,0xEA, +0xDA,0xD3,0x29,0x9C,0x67,0xCE,0x71,0x83,0x86,0xD5,0x86,0x80,0x50,0x07,0xFD,0x65, +0xA9,0xEA,0x75,0x84,0x11,0xFD,0xC7,0xE4,0xDE,0x03,0x9E,0xFC,0x31,0x62,0x66,0x2E, +0xDA,0xDE,0xB3,0xEC,0xC0,0xC2,0xCB,0x87,0x1C,0x87,0xDD,0x74,0x48,0x2F,0x5D,0x9B, +0x11,0xC0,0x69,0x90,0x8E,0xC0,0x8B,0xE5,0x20,0xA8,0x50,0xDF,0x3F,0xCF,0x0D,0x4D, +0x78,0xFA,0x67,0x5A,0x96,0xC0,0x2C,0x15,0x83,0x7F,0x6E,0xDF,0xE6,0xD5,0x66,0x9A, +0xB6,0x6C,0x13,0x73,0x10,0x77,0xDD,0xBE,0xB7,0x8B,0x1D,0x7A,0x33,0xF8,0x24,0x2E, +0x26,0x28,0xFD,0x50,0x4B,0x99,0xA5,0x1A,0x9B,0x77,0x8A,0x42,0x49,0x68,0x17,0x8C, +0xDA,0xD5,0x33,0xEA,0x0A,0xE8,0x82,0x7A,0x19,0x4C,0xD3,0x53,0x36,0x71,0xBB,0x08, +0x0D,0x42,0xD1,0xE6,0x84,0x60,0x46,0x03,0xC7,0x81,0x16,0x06,0x43,0xEC,0x35,0x63, +0xD0,0x38,0x3F,0xC8,0xCD,0x2D,0xBE,0x11,0x63,0xF0,0x5F,0xFB,0x3B,0xA5,0x3C,0x30, +0x64,0xFF,0x7E,0xD9,0x2A,0xE0,0xEF,0x33,0x29,0x3B,0xAD,0x7A,0xF3,0x86,0x5A,0x8D, +0x1E,0xD8,0x62,0xED,0xDB,0x8D,0x3F,0x35,0x92,0xC5,0xCC,0x09,0x6F,0xDD,0xDC,0xB3, +0xB5,0xE8,0x9A,0x5F,0x31,0xAB,0x1C,0x6F,0xF5,0x26,0xBE,0x2A,0xCA,0xBB,0x49,0x16, +0x28,0xCB,0xCA,0x79,0xA7,0x10,0x45,0x16,0x87,0x1C,0xB5,0xDC,0x08,0xF6,0x96,0x09, +0x26,0x44,0x4E,0x93,0xBF,0x04,0x39,0x2A,0x53,0xF1,0x44,0x14,0x08,0x00,0xCB,0x3D, +0x58,0xCC,0xA9,0x4C,0xB2,0x1C,0x09,0xA7,0x0A,0x57,0xB0,0x2B,0x4B,0x17,0xE5,0xC3, +0xD6,0xA8,0x0D,0x6D,0x2A,0x55,0xBB,0xC4,0x74,0x7F,0xD6,0x68,0xB6,0x2D,0x45,0xB8, +0x4C,0x2F,0x05,0x6E,0x7F,0x84,0xD5,0xA0,0x3D,0x7F,0x56,0x78,0xF7,0x3D,0xD7,0xA9, +0x4D,0xE6,0xE0,0x1E,0x49,0x48,0xDD,0x4C,0x1D,0xB3,0x00,0x00,0x82,0xBF,0x62,0x6A, +0xC5,0x62,0x22,0x9A,0x49,0xC6,0x84,0x9A,0x14,0x7E,0x8A,0x07,0xA4,0x8B,0xE9,0xEB, +0xFD,0x12,0x19,0xD6,0x10,0xCD,0xB8,0x90,0xC3,0xEF,0x26,0x9F,0xBC,0xE5,0x9B,0xAF, +0xF9,0x7D,0x2B,0xF8,0x6C,0x0F,0x7C,0x6C,0xDD,0xE3,0xFF,0xB6,0x6A,0xD6,0x8C,0x17, +0x45,0xC3,0x05,0xF4,0x31,0x85,0xB4,0xDD,0x36,0xA1,0xC5,0xB1,0x98,0xB9,0x3E,0x5B, +0x38,0xFD,0x74,0xFE,0xFD,0x70,0x9F,0x56,0xA1,0xA9,0xFC,0xD7,0x69,0x0E,0x17,0x0F, +0x1C,0x49,0x29,0x9F,0xF2,0xA6,0xBA,0x40,0x83,0x30,0x34,0xF8,0x83,0x02,0x01,0xFD, +0x24,0xDF,0x4D,0x39,0x9F,0x7B,0x24,0x68,0x04,0x2A,0x17,0xBB,0x2D,0x8E,0xF3,0x58, +0xBA,0x8B,0xBC,0x08,0xCF,0x77,0x33,0x94,0x17,0x33,0x4D,0x8A,0x57,0x78,0x31,0xAE, +0x19,0xB6,0xAA,0x85,0x98,0x4A,0x5D,0xCF,0x7E,0xFB,0x74,0x28,0x35,0x6C,0xAB,0xBD, +0x46,0xD8,0xF7,0x50,0xD0,0x74,0x91,0x60,0xDC,0xD1,0x92,0x97,0x8B,0x5F,0xC9,0x4C, +0x4C,0xCC,0x2E,0x21,0xBA,0x4E,0xDE,0xAD,0xE5,0x3B,0xC3,0x56,0xC4,0xCE,0x7C,0x2E, +0x78,0x81,0xD6,0x19,0x81,0x50,0x8D,0xEC,0xB0,0x9C,0x19,0x2B,0xAD,0xBD,0xB2,0x21, +0xE6,0x89,0x42,0x33,0xD6,0x7A,0x49,0xFD,0x37,0x22,0x05,0xA3,0xA4,0x95,0x81,0xA6, +0x29,0x6B,0x22,0xB2,0x68,0x07,0xA6,0xE5,0x91,0xDF,0xA5,0x4D,0xA5,0x3B,0x10,0xC8, +0x9F,0x7B,0x13,0x1C,0x51,0xED,0x6F,0x00,0x55,0x87,0x3C,0x53,0x41,0x4A,0x6F,0xC5, +0x61,0x12,0x04,0x8A,0xA6,0xC3,0xAC,0xC8,0xF5,0x9C,0xE4,0x95,0x13,0x78,0x61,0xCC, +0xCA,0x3E,0x04,0x61,0xFD,0x27,0x49,0x4A,0x81,0xD9,0x76,0xDF,0x21,0xB5,0xA9,0xEA, +0x74,0x6B,0x49,0xF2,0xC9,0xC9,0x2F,0xE0,0x44,0xDB,0x64,0x6C,0x56,0x1A,0x39,0xD7, +0x5A,0x23,0xAF,0x98,0xF6,0x4B,0xEA,0x77,0x0D,0xE3,0x8A,0x59,0xAF,0x1C,0xAA,0x5C, +0xD2,0x06,0x56,0x61,0xC9,0x55,0xD8,0xBE,0xE5,0x78,0xF6,0x60,0xBE,0x4A,0x33,0xB2, +0x4C,0x01,0xDC,0x4A,0x12,0x06,0xA0,0x65,0xB6,0xE9,0x85,0xD9,0x1E,0xDB,0x1E,0xA0, +0xB9,0x34,0x02,0xB0,0xD6,0xED,0x60,0x2F,0xC5,0xD2,0xCE,0xED,0x3B,0x8F,0xC5,0xC2, +0x0D,0xAC,0xDC,0xE6,0x32,0x64,0xD0,0xE7,0xB5,0x68,0x96,0x88,0x08,0xEB,0xB1,0x2B, +0x6C,0xD7,0x5B,0x5E,0xE8,0xD3,0x0E,0x24,0x49,0xFA,0xEB,0x5F,0xD8,0xF1,0x45,0xF9, +0x2A,0xC5,0xE8,0xAA,0xCA,0xA2,0xFB,0x1C,0xDC,0xBB,0x6A,0x92,0x6C,0x55,0x14,0x80, +0x54,0x82,0xF8,0xA3,0xE3,0xD1,0xC3,0x12,0xB6,0xC0,0x07,0x89,0xF2,0x01,0xCD,0x78, +0xE7,0x4D,0x08,0x5B,0x6B,0x17,0xDF,0x46,0x45,0x79,0x41,0x55,0x83,0xFC,0xCA,0x2D, +0x62,0x0C,0xA9,0xFE,0xC9,0xC0,0x3C,0x4E,0x5F,0x27,0x0E,0xE5,0x49,0xDC,0xA2,0x94, +0x25,0x01,0x37,0x40,0xBB,0x63,0x8C,0xBF,0x4E,0x17,0xEB,0x56,0xED,0x94,0x02,0x5E, +0x33,0x71,0xB4,0x2C,0xDE,0x4C,0xAE,0x1A,0x20,0x00,0x65,0x64,0x12,0x7F,0x1F,0xF7, +0x81,0xFB,0x61,0x88,0x80,0xD1,0x53,0xB1,0x9E,0xD6,0x86,0xA3,0xCD,0x0A,0x6C,0xAC, +0xCD,0x16,0x4C,0xD8,0xD5,0x2B,0x89,0x52,0x70,0xFD,0x2C,0xC4,0x83,0x36,0x32,0xE2, +0x3F,0x1A,0xBC,0xD3,0xC5,0xA2,0x8C,0x4B,0x47,0x28,0xF9,0x42,0x36,0xFF,0x7E,0x58, +0x63,0x97,0xE7,0x3A,0xA5,0x00,0xB5,0xF3,0x4D,0x40,0x75,0xFA,0x67,0xDB,0x4E,0x29, +0x4C,0x36,0x58,0x9A,0xDE,0x67,0x4C,0xF8,0x53,0xD8,0xC4,0xCA,0x9C,0x94,0x30,0x78, +0x2F,0xA0,0x41,0x85,0x16,0x72,0x61,0x33,0xE2,0x91,0xC6,0xF4,0x0A,0xC8,0x4F,0x09, +0xA1,0xB7,0x78,0x99,0x97,0x36,0x8C,0xAC,0x92,0xFF,0x7A,0x4E,0x20,0xA0,0xC0,0xC7, +0x9E,0xC4,0xF1,0x8D,0x05,0x5E,0x4A,0xF3,0x8A,0xAC,0xE0,0xD8,0x04,0xDA,0xEE,0xB2, +0xFF,0xBE,0x87,0xE4,0x0E,0xE6,0x83,0xC9,0x90,0xE4,0x20,0x7C,0x66,0xC4,0x0E,0x04, +0x90,0x40,0x99,0xC3,0xC0,0x82,0xE0,0x3C,0xF6,0x81,0xBC,0xD3,0xB6,0x51,0xD2,0xAC, +0xCF,0x58,0xD2,0xA3,0x89,0x85,0x40,0xC1,0xDA,0x94,0x05,0xDF,0x98,0x99,0x1A,0x73, +0x5F,0x83,0x35,0x15,0xCB,0x64,0xF0,0x67,0x28,0x25,0xBD,0xEB,0xD1,0xFF,0xA8,0xAB, +0xD6,0x94,0x9D,0xCA,0x6B,0x18,0xA3,0x66,0xB2,0xFF,0x21,0xB4,0xD8,0x82,0x92,0xBF, +0xA2,0xB8,0xAB,0xCD,0x5C,0x95,0x5D,0x50,0x8E,0xF2,0x65,0xEE,0xD1,0xF8,0xAA,0x14, +0xC4,0x55,0xFE,0xF1,0xBB,0x48,0xE9,0x94,0x0B,0x1D,0xF2,0xAF,0x7E,0x06,0xB3,0xAD, +0x93,0x77,0x42,0xB6,0xE5,0x8D,0x7F,0x37,0xD6,0xFB,0x89,0xF2,0xF4,0xC8,0x4A,0x87, +0x6E,0x1F,0x4A,0xF2,0x2F,0xAF,0xDD,0xCE,0x81,0x97,0x3B,0x36,0x7B,0x06,0x17,0x44, +0x7F,0xE5,0xB9,0xCE,0x6C,0x50,0xFF,0xBC,0xC3,0x99,0x1A,0x6B,0x85,0x60,0xD2,0x63, +0x26,0xF7,0x23,0xB5,0x73,0x14,0x39,0xA9,0xE8,0xCE,0x96,0xCB,0xD9,0x4E,0xD7,0xB3, +0xF7,0x06,0x85,0x19,0x7C,0xAA,0xD3,0x44,0x33,0x9F,0xC6,0xD0,0x95,0xBA,0xB7,0xC5, +0xCF,0xFF,0xD9,0x87,0xEA,0x48,0xB3,0x40,0x3A,0xED,0xE8,0x66,0x23,0x4A,0xDC,0xA2, +0x7B,0x1C,0x66,0x90,0xBA,0x5D,0xF3,0xF6,0x7C,0x14,0x83,0x38,0xAF,0x7B,0x47,0x20, +0x4B,0xF2,0x49,0x4C,0x43,0x40,0xAA,0x62,0x86,0x08,0x70,0x0C,0x4C,0xAA,0x73,0xA4, +0xF0,0xB3,0xC5,0x73,0x76,0xB5,0xB6,0x6D,0xC4,0x6D,0x76,0x7A,0x75,0x1F,0xC5,0xE4, +0xC1,0x23,0x33,0xC0,0x2F,0xB8,0x7E,0x96,0x0D,0xCD,0xA5,0x13,0xED,0x82,0xA4,0xB0, +0x6B,0x6B,0xF4,0xA1,0x80,0xF4,0x0B,0x98,0xEB,0xED,0x6A,0xC1,0xDD,0x14,0xDE,0xC7, +0x80,0xD1,0x85,0x0E,0x54,0x4C,0xDD,0x14,0xEF,0x1C,0x0A,0xEB,0x33,0x55,0x6A,0xC9, +0xBA,0x14,0x5D,0xE7,0x33,0x6C,0x85,0x06,0xD0,0x0D,0x68,0x9D,0xDF,0x2B,0xB5,0xAC, +0x0D,0xB0,0x7C,0x02,0xD2,0xAA,0x1F,0xD4,0x50,0x2D,0x70,0x65,0xB5,0x91,0x7D,0xB8, +0x4A,0x19,0x79,0x41,0x04,0x56,0x81,0xC9,0xAB,0x53,0xC8,0x35,0x71,0x09,0xE0,0x21, +0xED,0x0A,0xE3,0x87,0x9C,0xC0,0x23,0xA7,0xD8,0xF3,0x58,0x9F,0xD0,0x21,0x02,0xD3, +0x03,0xAC,0xE5,0x2C,0xC2,0x19,0x47,0x09,0xA1,0xE7,0x0B,0xB3,0x1C,0x40,0xE5,0xDF, +0x4A,0xAF,0x98,0xA5,0x68,0xF5,0x33,0xA8,0x6F,0xC7,0xBC,0xD6,0x96,0xA6,0x83,0x76, +0x92,0x50,0xB5,0x2C,0xD3,0x39,0x63,0x44,0xA6,0x73,0x6D,0xF7,0x92,0xE2,0xDA,0xBE, +0xBB,0x35,0x68,0x1E,0x2F,0x11,0x24,0xA4,0x6B,0x57,0xAA,0xC7,0x04,0xF8,0xF9,0x40, +0x2E,0xB2,0x72,0xA5,0x5F,0xCF,0x66,0x5A,0x60,0x8C,0xD8,0xAD,0x24,0x0C,0x99,0x66, +0x40,0xF0,0xF9,0x0F,0xCB,0xA5,0xC9,0x98,0xB2,0xAF,0x65,0x46,0xD6,0xF4,0x85,0x17, +0x3A,0x38,0x4A,0xC7,0x61,0xEF,0x39,0xC0,0x95,0x8B,0x03,0xC7,0x5B,0x2C,0x42,0x79, +0xC1,0xCD,0x49,0xF6,0x51,0x59,0xD6,0xF5,0xBF,0x64,0x9C,0xA6,0x40,0x72,0xA0,0x54, +0xFD,0x62,0xDA,0xA5,0xCC,0x8E,0xD4,0x01,0x44,0xF5,0x44,0x78,0xD2,0x9F,0xF7,0xBE, +0xF1,0x33,0x76,0xB2,0x20,0xD2,0x97,0x55,0xE2,0xCB,0x48,0x57,0x64,0x62,0x1B,0xC1, +0x49,0x83,0x91,0x21,0x62,0xA8,0xE3,0xC5,0xB0,0x8B,0x13,0x46,0x86,0x21,0x5D,0xC1, +0xE6,0x08,0x50,0x77,0x6C,0x94,0x7A,0xC2,0x50,0x3D,0x65,0x05,0xFE,0x7E,0x33,0xEC, +0xE9,0x63,0x99,0xB6,0x5A,0xCF,0x8F,0x6B,0x90,0xBE,0x07,0x7D,0x1F,0x22,0x66,0xC8, +0x38,0x96,0x5A,0xC4,0xC4,0xBD,0x92,0xF9,0xA4,0x8D,0xC1,0xB7,0xAC,0x4E,0xAA,0x73, +0x78,0xE6,0xBE,0x7E,0x82,0xA5,0x17,0xFE,0xC3,0xBF,0xD4,0x56,0x25,0xA5,0xB6,0xF7, +0x6D,0xB8,0x8A,0x5B,0x0C,0xF1,0x63,0x0D,0x95,0x07,0x04,0xB0,0x46,0x2C,0x85,0x5E, +0x03,0xE5,0xF1,0x75,0x95,0x8B,0x23,0x74,0x02,0xD1,0x78,0x35,0x20,0xC3,0x90,0xCF, +0xBA,0x50,0x7E,0xCE,0xAD,0x58,0xCE,0xEC,0x9D,0xDC,0x52,0x82,0xC1,0x51,0xF4,0x95, +0xBB,0xEC,0xF1,0x44,0xA3,0x6C,0xE4,0x8A,0x57,0x4E,0x85,0x2F,0xAB,0xB3,0x7B,0x95, +0x20,0xC8,0xBC,0xA5,0x16,0x37,0xDA,0x8E,0x09,0x16,0xA0,0x68,0x13,0xF2,0xF2,0x63, +0x15,0x23,0x13,0x94,0x27,0x49,0x4D,0x69,0x00,0x86,0xDB,0x3E,0x7C,0x92,0x2B,0xAA, +0x1A,0x1B,0xB9,0x9F,0x7D,0x0F,0x6B,0x7F,0x3F,0x5F,0xB8,0xC3,0xB7,0xA7,0x55,0x8A, +0xC8,0x34,0xDA,0x4C,0x33,0x0D,0x22,0x2E,0x94,0x18,0x60,0x10,0x38,0xA8,0x02,0x04, +0x04,0x61,0x73,0x65,0x83,0xF7,0x66,0x0B,0xB3,0xB9,0x16,0xC0,0xB7,0x44,0x6D,0x08, +0x85,0x0E,0x37,0xD7,0x97,0x21,0xA2,0x61,0xBD,0x65,0xFC,0x68,0x46,0x12,0xB4,0xF1, +0x82,0x83,0x4D,0x9B,0xEA,0xB6,0xB2,0x20,0x87,0x2E,0xCF,0x58,0xA7,0xBD,0x9D,0x49, +0xD8,0x16,0x0B,0xD3,0x61,0x5D,0xAE,0x33,0xB7,0x40,0xBC,0x62,0xAB,0xC2,0x0E,0x1A, +0x1C,0x53,0x70,0xE6,0x4F,0x74,0x21,0xFC,0x84,0x63,0xA1,0x27,0x24,0x73,0x2E,0x32, +0x12,0xE0,0x14,0xB9,0x7C,0xCA,0x1C,0x01,0x88,0xB5,0xED,0x9F,0xFB,0x2A,0xD7,0x3D, +0x9D,0xAE,0xFF,0x87,0x0C,0xF9,0xEA,0x4B,0xC6,0x37,0x87,0xB9,0x49,0x6E,0xCB,0x49, +0xD4,0x08,0x7A,0x52,0x0F,0x2B,0x76,0x01,0x9A,0xD3,0x80,0xFB,0xFA,0x64,0x5C,0xA1, +0x8A,0x5B,0x13,0x65,0xEE,0xBD,0x54,0x56,0x32,0x16,0x79,0x5F,0xC2,0xD7,0x3B,0x62, +0x2D,0x50,0x8E,0x70,0x75,0xDB,0x39,0x1A,0x6C,0x83,0x75,0xFB,0x74,0x21,0x3D,0xD4, +0x2D,0xF0,0xB9,0x4F,0x32,0xC0,0x64,0xA8,0xFF,0x1D,0x5F,0x49,0x87,0x85,0xD2,0xAE, +0xC1,0xAB,0xB3,0x39,0x08,0x37,0x7E,0xA9,0x46,0x37,0xE3,0xD7,0x11,0x26,0xCE,0xE3, +0x02,0x29,0x0A,0xB9,0x1E,0xFA,0x1A,0xDE,0xD1,0xA1,0xAE,0x5B,0x66,0x7D,0x19,0x53, +0x79,0x92,0xF6,0x57,0x74,0x18,0x1B,0xF7,0xBA,0x03,0x1D,0x1B,0x82,0xE7,0x2D,0x68, +0x01,0x78,0xA5,0x66,0x24,0xC0,0x92,0x1C,0x2B,0x00,0x36,0x8A,0x51,0xBC,0x31,0xBE, +0x14,0x11,0x3C,0xDA,0xC6,0xFB,0xA0,0x1C,0x51,0xD9,0x08,0x7B,0x13,0x84,0x9C,0x92, +0x05,0x0D,0xA5,0x21,0x25,0x7D,0x69,0x3B,0xF0,0xFF,0xE8,0xBC,0xE4,0x9D,0xFB,0x02, +0x4B,0xE4,0x9E,0xE7,0x7C,0x70,0xB0,0xFE,0xD2,0x14,0x90,0xE4,0x28,0xEB,0x70,0x0D, +0x26,0x39,0x27,0x4C,0x7D,0xB1,0xBD,0x92,0x6D,0x5A,0xCA,0xB0,0x48,0x7A,0x34,0x18, +0x8D,0x9A,0xFD,0xA7,0x2C,0x96,0x15,0x4B,0x74,0x62,0xE3,0x76,0xC4,0x7C,0x7D,0x98, +0xC8,0xBA,0x5B,0xBF,0xBF,0x32,0x6F,0x5B,0xF6,0x39,0xD6,0xD3,0x6B,0x5F,0xD1,0xB3, +0x17,0x41,0xA0,0x1B,0x57,0xC9,0x45,0x01,0xC6,0x3B,0xE4,0x99,0xB3,0x97,0xD3,0x81, +0x6F,0x96,0x19,0xE1,0x84,0xC5,0xE6,0xC4,0x46,0x24,0x67,0x79,0x5A,0xC6,0x35,0xCB, +0xFA,0xA0,0x4F,0xA5,0x40,0x0A,0xFC,0x42,0xAF,0x98,0xD8,0xAA,0x23,0x8C,0xCC,0x50, +0xB3,0xDC,0x9D,0xD3,0x7C,0xA3,0xF4,0xAF,0x99,0x2A,0x71,0xD2,0x37,0x59,0x5D,0xE0, +0xF5,0x96,0x25,0xDA,0x65,0x90,0x68,0xAA,0xD5,0x51,0x10,0xA8,0xE8,0x1C,0x52,0x17, +0x36,0x26,0xCC,0x4F,0xE0,0x3A,0x5A,0xE8,0x09,0x3F,0x64,0x3C,0xCD,0x09,0xC7,0xB7, +0x1A,0x93,0x9E,0x98,0x14,0xC2,0x64,0x66,0x1F,0xD1,0xCF,0xDE,0x1B,0xCC,0x8F,0x26, +0x8A,0xEA,0x9F,0x2D,0xE8,0x43,0xA3,0x38,0xF1,0x37,0xB7,0x77,0xEB,0x14,0xC8,0xA7, +0xE8,0x4E,0x08,0x72,0x46,0xA3,0x8E,0x24,0xAF,0x52,0xA6,0xF9,0x00,0x2F,0xE9,0x80, +0x29,0x99,0x13,0x49,0xD3,0xBD,0xF1,0x2D,0xF7,0x48,0xBC,0x7C,0x57,0xF3,0xD0,0x94, +0xE0,0x84,0xAC,0xD3,0xAE,0xA7,0xDA,0x03,0xCF,0x3C,0x9C,0xBF,0x43,0x80,0xD7,0x85, +0x3A,0xCA,0x0B,0xB7,0xDF,0xE2,0xBD,0x50,0x6C,0x7A,0x65,0xEB,0x36,0x67,0x08,0x0B, +0x06,0xD0,0xF1,0x2C,0x43,0x76,0x5C,0xFE,0x88,0x27,0x44,0xCA,0x3D,0x09,0xDD,0x89, +0x7E,0x7E,0xC2,0xBC,0xFF,0x99,0xE4,0xA2,0xAC,0xD9,0xF0,0x5C,0x0C,0xEF,0x57,0xCD, +0xBC,0x10,0x3C,0xA4,0x93,0x80,0x64,0xBB,0x46,0x3C,0x86,0xD8,0x0F,0x1D,0x71,0x16, +0x95,0xFD,0xB0,0xFB,0x52,0x89,0x36,0x60,0x05,0xA7,0x0B,0x61,0xEE,0x5F,0x68,0x8A, +0x90,0x95,0x93,0x1A,0xC9,0x6E,0xBB,0xE8,0xAC,0x95,0xA6,0x48,0x47,0x6E,0x14,0x1B, +0x59,0x1C,0x14,0x2E,0x96,0x3E,0x08,0xFD,0x34,0x76,0xF4,0x90,0x46,0x60,0x0E,0x64, +0x51,0x7F,0xE3,0xC3,0x35,0xE8,0x9E,0x6D,0xEE,0xE0,0xF1,0x96,0x7F,0x11,0xB5,0xFF, +0x8B,0x05,0xF2,0x3B,0x8A,0x75,0x11,0x78,0x74,0xC8,0x58,0x19,0x6B,0xCB,0x21,0xAE, +0x8C,0x00,0x8E,0x51,0x0C,0x1B,0xD7,0x75,0x62,0x29,0xDF,0x10,0x6A,0xC2,0x16,0x74, +0xFF,0x03,0xF2,0xE5,0x40,0x4C,0x23,0xFC,0x7E,0x74,0x67,0xFC,0x6F,0x6F,0x30,0xFE, +0x06,0x38,0xF5,0xD3,0xCA,0xC3,0x82,0x44,0xB5,0x42,0xAD,0xC4,0x48,0xDD,0xDC,0xC8, +0xE7,0x89,0x64,0x20,0x12,0x09,0xE2,0xD5,0x56,0xB5,0x17,0x7E,0x83,0x98,0xC1,0xB7, +0x88,0x5F,0x99,0x75,0x4C,0x26,0xFB,0x07,0x1B,0x55,0x00,0x40,0xA2,0xFC,0xCB,0xBD, +0x5E,0x7A,0x4F,0x5B,0xC6,0x94,0x6C,0xB5,0xA7,0x3E,0x20,0x13,0xF5,0x42,0x9E,0x3B, +0x9D,0x0A,0x52,0x78,0x20,0xB9,0xF5,0xC2,0x94,0x87,0x2E,0x9B,0x0D,0xF3,0xCE,0xA4, +0x2F,0x0D,0xF3,0x70,0x29,0xC7,0x80,0x15,0x66,0xC0,0x43,0x0F,0xA5,0xE1,0xAD,0x13, +0xFF,0x36,0x1C,0x78,0x64,0x42,0xF8,0x95,0x33,0x88,0xD2,0xFF,0xF5,0x07,0x62,0x74, +0xDB,0x37,0x12,0x00,0xD7,0x21,0x53,0x7D,0xD2,0x6B,0xA5,0xC4,0x7E,0x78,0xF4,0x5E, +0x74,0x1F,0x0E,0x19,0x5F,0xE2,0x89,0x03,0x50,0xA9,0x69,0x47,0xDB,0x4A,0x90,0x0A, +0xEC,0x58,0x7D,0x75,0xDD,0x6F,0x80,0x06,0x08,0x0C,0xA8,0xFE,0xFC,0x4A,0x52,0x99, +0xFC,0x2A,0xA4,0x90,0x69,0x25,0x26,0xCE,0xC9,0x94,0xD1,0x5D,0x69,0x07,0x6A,0xAE, +0x98,0xDB,0xCC,0xBA,0xC3,0x06,0xF1,0xA8,0x7D,0x00,0x0D,0x1C,0xF3,0x89,0xE6,0xAA, +0xE2,0x36,0x5A,0xD4,0xA5,0xD8,0x68,0xEC,0x9A,0x28,0x8C,0xFC,0xC0,0x96,0x69,0x44, +0x30,0x76,0xD9,0x5B,0xD3,0x61,0x00,0x2D,0xB4,0xA1,0xE7,0x76,0xAB,0x83,0x53,0x35, +0xD3,0x5B,0xE6,0x4A,0xE6,0x17,0x2F,0x27,0x9E,0xC4,0x10,0x74,0xDA,0xA6,0x30,0x7C, +0x25,0xDC,0x9C,0x8D,0xA9,0xCB,0x67,0x26,0x94,0xE3,0x21,0x9E,0xA6,0xB2,0x65,0x9D, +0xA3,0x93,0xEF,0x94,0x39,0xE1,0xA1,0x5C,0x67,0x08,0x94,0x14,0x54,0xCE,0x61,0xFC, +0xE9,0x5D,0x6F,0xB2,0x68,0x2B,0x5E,0x3C,0x7E,0x9A,0xC2,0xA7,0x10,0xCE,0x2E,0xFD, +0x49,0x70,0xED,0x53,0xDE,0x20,0x4C,0x0F,0x45,0x20,0x84,0xB9,0xB4,0xE4,0x51,0xBE, +0x15,0x63,0x2E,0x9C,0x14,0xE8,0x22,0x30,0x1B,0x14,0x5B,0xC8,0x4F,0x28,0xB4,0x26, +0xBF,0xAA,0x63,0x23,0x46,0x88,0xA9,0x98,0x94,0x94,0x6B,0x13,0x87,0x61,0x23,0x72, +0x24,0x10,0x4C,0xCB,0xDC,0x7B,0x3F,0x0B,0xA1,0xF9,0x93,0x83,0x80,0xA8,0xFF,0x32, +0x78,0x00,0xD2,0x4E,0x65,0x0E,0x7B,0x3C,0xBC,0x0C,0x58,0x1C,0x01,0x66,0xE9,0xDF, +0x5E,0x0C,0x28,0x2C,0xC9,0x3F,0xBA,0x57,0xBF,0x6B,0xCE,0xC0,0x13,0xC3,0x64,0xED, +0xC9,0x83,0xB1,0x57,0x1F,0x13,0x9D,0x72,0x0A,0x70,0x11,0x4E,0x10,0x08,0xCB,0xEE, +0xC0,0x5D,0xDC,0xEE,0x33,0x1C,0x49,0x46,0x7E,0xC9,0xCB,0x84,0x1F,0xC8,0x8B,0x54, +0x27,0x1D,0x39,0xDC,0xCE,0x42,0xE2,0xC1,0xEE,0xE4,0xA9,0xE0,0x85,0x7C,0xF3,0xBA, +0xE5,0xFF,0x43,0x7E,0x37,0x37,0x26,0x6B,0x4B,0xB2,0x0F,0xB5,0xAD,0x15,0x98,0x2E, +0x51,0x65,0x7C,0x4C,0xED,0x21,0x9E,0xDE,0xC8,0xEE,0x5C,0xAD,0xA2,0xC3,0x5B,0x72, +0xB7,0xCD,0x73,0xB4,0xD6,0xED,0x24,0xB5,0xA4,0xF3,0x09,0x46,0xFC,0xC7,0x40,0x42, +0xD6,0x0C,0xA3,0x66,0x7A,0xAB,0x82,0x59,0x37,0x01,0x65,0xD7,0xC4,0xDC,0xBD,0x45, +0xE7,0x84,0xF6,0xF7,0x68,0x66,0x6C,0x38,0xB6,0x90,0x1E,0xF5,0x07,0x89,0x57,0x30, +0xAC,0x60,0x8D,0xDF,0x51,0xCC,0xF1,0x48,0x3F,0x28,0x21,0x98,0xDC,0xC7,0x2E,0x35, +0xD1,0x4F,0xCC,0x77,0xF2,0xE8,0x8C,0xB3,0x67,0x06,0x7B,0x21,0x29,0x8F,0x8F,0xB8, +0x93,0x20,0x3C,0x57,0x58,0x8D,0x66,0x98,0xF6,0xC5,0xB5,0x44,0x4E,0x28,0xD6,0xB1, +0x7C,0x8B,0x57,0x60,0x60,0xE9,0x97,0x18,0x1C,0x2D,0x97,0xB4,0x28,0x50,0xD6,0xEC, +0x33,0xF4,0x2C,0x59,0xD0,0xC3,0x75,0x8C,0xDE,0x43,0x99,0xF9,0xD7,0x4C,0x71,0xC0, +0x4B,0x9A,0x36,0x03,0x67,0x30,0xCC,0xA4,0x0F,0xCA,0xD0,0xB3,0x8A,0xA0,0x3C,0xD6, +0x93,0xF1,0xF9,0xED,0x64,0x66,0xB2,0x46,0x2E,0x1E,0x0E,0x08,0x98,0x38,0x5D,0x85, +0x7B,0x07,0x40,0xB6,0x9A,0x98,0x89,0x91,0x28,0xB5,0x4C,0x72,0x22,0xDC,0xB0,0xF9, +0xA0,0x6A,0x2B,0x7E,0x23,0x76,0xA4,0xAB,0xCC,0x52,0x6E,0x8A,0x3F,0x2D,0x70,0xEC, +0xA2,0xAF,0xBC,0x95,0x2E,0xC0,0xFA,0xB8,0x03,0x14,0xF1,0xD7,0x55,0x07,0xC3,0xF1, +0x0B,0xA1,0x2E,0xF7,0xDC,0x77,0xC2,0x4F,0xEF,0x93,0x34,0x26,0x01,0x94,0xCB,0xE6, +0xA3,0x4B,0x74,0x6C,0x82,0x89,0xAC,0x34,0x9A,0x3D,0x1A,0xB7,0xB1,0xFD,0x7C,0xE3, +0x80,0x57,0x2D,0xCA,0x16,0xB0,0x17,0x1B,0x11,0xE6,0x2A,0x8E,0xAF,0xE3,0x63,0x87, +0x9E,0x29,0xA0,0x40,0xCA,0x40,0xA7,0x40,0x72,0xD9,0xC8,0x30,0x02,0xB9,0x56,0x84, +0x74,0xC0,0x1E,0xE2,0xD8,0xC0,0xA7,0x58,0x46,0x6B,0xA5,0x6C,0x45,0x6D,0x1E,0x33, +0x4A,0x7D,0xF1,0xCF,0x1C,0x93,0x71,0x2D,0x13,0x0B,0xEE,0x05,0xB7,0xF7,0x5F,0xFB, +0x7F,0x0D,0x28,0x06,0xD8,0xCC,0xFF,0x00,0x2B,0x34,0xD1,0x6F,0x4A,0xC1,0xCA,0x13, +0x63,0x98,0x61,0xEE,0x8E,0x9F,0x5D,0x0D,0x69,0x22,0xC4,0xED,0x7A,0x0F,0x72,0xCF, +0xED,0xAB,0xB9,0x3F,0x35,0x8A,0xAF,0x61,0x07,0x54,0x8B,0x8E,0x8D,0xF1,0x1F,0xA8, +0x99,0x1B,0x50,0x9E,0x01,0x2D,0xA1,0x8C,0x8E,0xFA,0xBB,0xAE,0x5C,0x48,0xB5,0x9E, +0xE2,0x16,0xC8,0xBF,0x35,0xF6,0x1B,0xD9,0x57,0xAD,0x71,0x6F,0x2A,0x11,0x90,0x7C, +0xFD,0x50,0x7E,0x35,0x4B,0xAE,0xE6,0xD7,0x57,0x5B,0x09,0xA5,0x20,0x43,0x40,0x41, +0x71,0x2A,0x2A,0x1A,0x5C,0x15,0xC2,0x89,0x0B,0xC8,0x63,0x7A,0x70,0x58,0x9E,0x78, +0x0A,0xA1,0xC2,0x99,0x8A,0x76,0x84,0xCC,0x25,0x8E,0xB7,0x12,0x22,0xCE,0x20,0x34, +0x7A,0x89,0x8D,0xB6,0x2F,0x63,0x99,0xA5,0x8E,0x98,0xB0,0x29,0x03,0x10,0xB1,0xBB, +0xCF,0x11,0x1F,0xF4,0xF9,0xC7,0x49,0x0C,0xEA,0xDB,0x20,0x21,0x32,0x85,0x5C,0x69, +0xA9,0xB7,0xC0,0x96,0xB0,0xA6,0x77,0xE7,0x1D,0xAA,0x5F,0xB1,0x1B,0xEA,0x35,0x21, +0x3C,0xFB,0x89,0x72,0x60,0xC8,0xAE,0x59,0x6A,0xBA,0xFA,0x36,0x94,0x34,0x38,0x0B, +0x2F,0x33,0x5B,0x51,0xCE,0x9C,0xDA,0x5A,0x2C,0xF2,0x02,0x0B,0xC3,0xC6,0xAC,0x29, +0x39,0x62,0xCE,0x49,0x38,0x23,0x83,0x9A,0x6B,0x9E,0x85,0xB4,0x16,0xC2,0x77,0x63, +0x77,0x8B,0xA3,0xE7,0xD8,0x0E,0x74,0xD7,0xC5,0x24,0xEF,0x38,0x78,0x1E,0x7E,0x43, +0x7D,0xFA,0x0F,0x66,0xF0,0x0C,0xAC,0xB3,0xB4,0x7B,0xFE,0x6B,0x92,0x03,0x71,0xFB, +0x25,0x4E,0xE3,0x27,0x64,0x9F,0x02,0x62,0xAB,0xAA,0x47,0x1D,0x87,0xBF,0x71,0xA4, +0x5F,0x3D,0x49,0xAA,0x11,0x10,0x32,0xEB,0x7E,0x39,0x7A,0x51,0xEC,0xD9,0x00,0xAA, +0x45,0x46,0x4B,0xBE,0x70,0x5C,0x5D,0xD9,0xF7,0x6F,0x87,0x7A,0x2B,0x33,0x97,0x4C, +0x9D,0x59,0x90,0x28,0x88,0xDA,0xF5,0x54,0x89,0x0F,0x70,0xF1,0xA0,0x92,0xC7,0x40, +0xC1,0x91,0x53,0x55,0x8F,0x22,0x5B,0xEE,0xE6,0x86,0x80,0x1F,0xE7,0xB7,0x33,0xFA, +0xB7,0x83,0xD9,0x47,0x04,0x6C,0xDB,0x7D,0x01,0x03,0xDB,0x66,0x58,0x57,0x30,0xD7, +0xFA,0x19,0x11,0x78,0x65,0x00,0x13,0x60,0x8E,0xB5,0xEE,0xE4,0x6F,0x91,0x6E,0x94, +0x20,0xE4,0x2F,0xC9,0xB4,0x6F,0xDA,0xD2,0xB5,0xAE,0xC6,0xD8,0xF8,0xFE,0x6B,0xF7, +0x65,0x1A,0x7D,0xE2,0xBE,0x3C,0x8F,0x92,0x7C,0x25,0xB6,0xD3,0xE2,0x8E,0x93,0x5C, +0x1B,0x54,0x63,0xC3,0xAE,0x2D,0x6C,0xE8,0xDB,0x4F,0x88,0xD6,0xF6,0x3C,0xC5,0x99, +0xF3,0xAA,0xAD,0x3B,0x05,0x92,0x73,0xC2,0x45,0xCE,0x00,0x40,0x85,0x8C,0x75,0x22, +0x64,0x38,0x97,0xB3,0x64,0xCA,0xB3,0xA1,0x92,0x26,0x7E,0xC6,0x17,0x75,0x7E,0x4E, +0x34,0x10,0x05,0x31,0x54,0xD1,0x23,0x7D,0x31,0x0E,0x42,0x71,0x07,0xEF,0x7A,0xBF, +0x26,0xB8,0x47,0x8C,0xBA,0xE8,0xDF,0xDA,0x9F,0xE6,0xF1,0xD5,0xDA,0xA7,0x51,0xFF, +0x55,0x10,0xFC,0x28,0xD2,0x2A,0x72,0xCC,0x6E,0xF4,0xF9,0x5A,0xBC,0x43,0xCC,0xA0, +0x2C,0x65,0xC5,0x18,0x65,0x16,0x06,0x95,0x76,0x3F,0xB1,0xE7,0xB9,0x79,0x5D,0x8D, +0x67,0xAB,0xD6,0x0F,0x50,0xDD,0x5C,0xB0,0xC9,0x3D,0xD2,0x38,0x30,0x54,0x87,0x3B, +0xB8,0x09,0xDD,0xC3,0x70,0x5C,0xDD,0x36,0x25,0xA3,0x54,0x43,0x40,0xD3,0x91,0x42, +0x9D,0x55,0x65,0x8C,0x00,0x9F,0xD1,0x4D,0x5F,0x20,0xA9,0x44,0xDD,0xFC,0x9D,0xDC, +0xA3,0x4A,0x09,0xE3,0x0D,0xBF,0x68,0x53,0xD5,0x47,0x30,0xBA,0xD3,0x2A,0xF0,0x60, +0x9B,0x5D,0xB3,0x0D,0xB0,0x97,0x53,0x81,0x0B,0xBA,0x1F,0xA8,0x4A,0x0B,0x51,0xF2, +0x85,0x18,0x23,0xC5,0x76,0xCB,0x93,0x23,0xD7,0x54,0x7B,0x27,0xE6,0x81,0xE4,0x2C, +0x0D,0x8E,0xB6,0x52,0x60,0xA6,0x60,0x8B,0xE4,0xC1,0xE4,0xF6,0xBA,0x43,0x75,0xB7, +0xCD,0xB8,0xD1,0x90,0x78,0x66,0x5B,0xF6,0x31,0x7B,0x99,0x1F,0x44,0x72,0xAA,0x25, +0xCF,0xFA,0x08,0x9C,0xE1,0x54,0x39,0xD2,0xCC,0x24,0xAA,0x5C,0x69,0x1A,0xA9,0x2F, +0xB1,0x60,0x8E,0x05,0x5D,0xBE,0xB8,0x99,0x88,0x31,0x03,0x52,0xE0,0xD4,0xD6,0xC1, +0x13,0x6D,0xBD,0x8B,0xC5,0xD2,0x60,0xE4,0x8D,0x90,0xC1,0xA5,0x58,0xE6,0xA5,0x90, +0xB9,0x01,0x4C,0x43,0xAE,0x51,0x0C,0xE3,0xA4,0xA6,0x7D,0x7C,0x9A,0xD7,0xB7,0xB4, +0xB9,0xF4,0x41,0x5A,0x6A,0x49,0xD5,0xD9,0x09,0x35,0x08,0x3E,0xEF,0x75,0xE6,0xF8, +0x67,0x81,0x2B,0x1E,0x2F,0x4F,0xB0,0x28,0xC2,0x4B,0x89,0xB7,0xF6,0x37,0x6E,0xC2, +0xCE,0xD2,0x51,0x73,0xA3,0xBE,0xE6,0x54,0x69,0x3C,0x67,0xD3,0x15,0xD4,0x59,0x4D, +0x9C,0x68,0xB9,0x3B,0x45,0x13,0x1F,0x39,0x12,0xE4,0x2A,0xBA,0x45,0x38,0x1F,0x81, +0x51,0x26,0x60,0x00,0x5B,0x2D,0x82,0xDD,0x90,0xAF,0x00,0x9E,0xF9,0x81,0x94,0xD5, +0x6D,0x21,0x0D,0xE5,0x22,0x64,0xF3,0x30,0xEB,0x28,0x61,0x49,0x9D,0x8A,0x75,0xD3, +0xAA,0x3E,0xE8,0x5D,0xF1,0x0D,0x5B,0xCF,0x89,0xB9,0x42,0xC1,0x29,0xBF,0x81,0x5D, +0x0B,0xD7,0x93,0x08,0x43,0x43,0xE5,0x89,0x59,0x55,0x9F,0x13,0x0B,0xA0,0x26,0xA4, +0x67,0x70,0xFB,0xD1,0xEF,0x8D,0x95,0xBA,0x12,0x87,0x59,0x00,0x8E,0x55,0x1C,0x5A, +0xE5,0xAA,0xE2,0x21,0xDB,0x82,0xFD,0x54,0xD8,0xAA,0x95,0x1F,0x6C,0x0D,0x94,0xEA, +0x17,0x03,0xC5,0x8A,0xA9,0x44,0xCD,0x20,0x63,0x54,0x3B,0x98,0x78,0xA7,0x25,0xBB, +0xA8,0x74,0x73,0x17,0x9F,0x52,0xAC,0xD0,0xE0,0x1A,0xB6,0x71,0xAD,0x14,0xC6,0x49, +0x58,0x57,0xA0,0x67,0x27,0x4C,0x64,0x81,0xD9,0x60,0x6C,0xE3,0x05,0x96,0xE6,0x2E, +0xD0,0x7C,0xB3,0xCD,0xA6,0x59,0x48,0x38,0xF8,0x10,0xED,0x0D,0x48,0x6E,0x28,0x78, +0x13,0xF5,0x4F,0xBC,0x0B,0x70,0x58,0x2C,0x03,0x3F,0x41,0xB1,0xEE,0xA9,0xEE,0x64, +0x71,0xAF,0x30,0xFE,0x12,0x49,0x08,0x5B,0xA8,0x06,0x85,0x38,0x36,0x7A,0x89,0x5D, +0x30,0xE2,0x92,0x42,0x8B,0x95,0x36,0xA8,0xEE,0x23,0x72,0xA5,0xE8,0x3D,0xC6,0xF8, +0xCC,0x6E,0x88,0x54,0x45,0xCC,0x29,0xDF,0x51,0x78,0xB6,0x01,0x6E,0x31,0x72,0xA1, +0x2B,0x8F,0xB3,0x41,0x87,0x53,0xD6,0x3B,0xDC,0xBE,0x3B,0xA8,0x9D,0xA0,0x26,0x07, +0xF8,0x7E,0xA8,0xF2,0x81,0x94,0xA3,0x07,0xF0,0xAD,0x04,0x15,0xBF,0xC8,0x96,0x3D, +0x04,0xC7,0x94,0xEE,0xFA,0xBB,0xAE,0xA4,0xFE,0x8E,0x13,0x25,0x16,0x49,0xD1,0xFF, +0xF8,0xC9,0x8E,0x7C,0x7B,0xD8,0x32,0x49,0xDD,0xCA,0x57,0x13,0xAB,0xDB,0xBA,0x54, +0xDF,0x6C,0xFE,0xD7,0xAC,0x97,0xB9,0x6E,0x58,0xA5,0xC2,0x55,0x7E,0xFB,0x0A,0xEA, +0x00,0x7E,0xBF,0xD6,0x81,0x58,0xB3,0xD5,0x71,0x9A,0xE0,0x9D,0x21,0x87,0xF1,0x43, +0x9E,0x5C,0x30,0x72,0x95,0x17,0xDE,0x8A,0x25,0xAF,0xD8,0xF9,0x48,0x44,0x93,0x83, +0x9A,0x43,0x85,0xB4,0x35,0xA4,0x1A,0x39,0x25,0xE3,0xF1,0x9C,0x5F,0x30,0x80,0xB1, +0x66,0xF2,0xAA,0xB4,0x6A,0xC2,0xE7,0x36,0x97,0x68,0x90,0x31,0x2C,0x08,0xB8,0x5A, +0x90,0xF1,0x3C,0xE1,0x0C,0x5D,0xDC,0xD3,0xF6,0x79,0x16,0xAF,0x9B,0xCA,0x56,0xD9, +0xAA,0x36,0x0F,0x45,0xC7,0xE9,0xD4,0x66,0x60,0x3F,0x09,0x51,0x36,0x95,0xDD,0x0D, +0xBB,0x39,0xCF,0x7F,0xE1,0x82,0x14,0xA6,0xA5,0xA0,0xBA,0x84,0x39,0x7D,0xD9,0x0D, +0x50,0x7E,0x13,0x38,0x19,0x19,0x43,0x9C,0x32,0x13,0x71,0x67,0xA6,0x4B,0xB0,0x88, +0xA5,0x6E,0x85,0x52,0x9B,0x3D,0x19,0x12,0x12,0xC5,0x5E,0x19,0x6D,0xD1,0x2C,0x56, +0xF8,0x48,0x59,0x09,0x34,0x86,0xDB,0x57,0xF1,0x57,0x36,0x2E,0x2C,0x65,0x2C,0x83, +0x24,0x90,0xB0,0x60,0xF9,0x38,0x35,0x8F,0xF0,0x6D,0x96,0x6C,0xEB,0xAA,0xB6,0xEC, +0x71,0xC3,0xE7,0x18,0xD3,0x0F,0x4E,0x2B,0x1B,0xA4,0xBB,0xC2,0xE9,0x26,0x8E,0xF1, +0xED,0x9C,0x8F,0x3B,0x00,0x81,0x38,0x62,0xCA,0x57,0x12,0x64,0x1D,0xAB,0x6B,0x19, +0xAE,0x39,0x9A,0x3B,0x91,0x51,0x58,0x1E,0x18,0x46,0xA1,0x7C,0x5D,0x85,0x5D,0xA4, +0x06,0x2D,0x1D,0xFD,0xF1,0xF4,0x55,0xC3,0xE0,0x7A,0x06,0x8B,0x15,0x85,0x49,0x3D, +0x9C,0x6C,0xB9,0xBC,0x21,0xDC,0x37,0x7B,0xDD,0x44,0x15,0xA5,0x01,0x41,0x06,0x1E, +0x35,0xF4,0xA2,0x03,0x28,0x20,0x1A,0x1F,0x2E,0xB8,0x3D,0x1C,0x5F,0xC6,0xB7,0x3B, +0x8D,0x0B,0x2F,0x46,0xFE,0xE8,0x75,0x24,0x3B,0x41,0xFC,0x9D,0x00,0x0C,0xA2,0xD0, +0x97,0xE8,0x22,0xFD,0x79,0x87,0x48,0x8E,0x9E,0xC7,0xB1,0xEB,0xDA,0xA1,0xA1,0xC4, +0x05,0x15,0x7E,0x83,0x02,0x87,0xA8,0x5E,0xDE,0x6A,0x55,0x27,0xAE,0x2A,0x62,0x06, +0xBD,0x34,0xFD,0x3A,0x5F,0xA6,0xC0,0x6F,0xA7,0xE3,0xCB,0xBE,0xEB,0xEF,0xEF,0xB5, +0xBE,0x01,0x04,0x61,0x22,0xCF,0xD0,0xE9,0x48,0xF5,0x75,0xA4,0x74,0x5A,0xC9,0x4C, +0x2E,0x96,0x63,0x9B,0x6D,0xE1,0xAC,0x4A,0xB0,0x60,0x7E,0x99,0x3B,0x21,0x7D,0xE2, +0x31,0x4F,0xBC,0xC3,0x03,0x4F,0xE4,0x60,0x6B,0x60,0x51,0xCC,0xBB,0x37,0x4B,0x2D, +0x16,0xB4,0x81,0x32,0xFA,0x6D,0x32,0x20,0x9E,0xCA,0xCB,0x62,0xB0,0x53,0x6A,0x28, +0x8A,0x7A,0x35,0xAB,0x83,0xDD,0xEF,0x36,0x24,0xF3,0x30,0x7D,0x16,0x4A,0x94,0x5C, +0xC1,0xE0,0xC7,0x67,0x64,0x8D,0xF0,0xA0,0x3F,0x5C,0xBB,0x3E,0xED,0x75,0x21,0x1E, +0xB4,0x45,0x9E,0x90,0xD2,0xE0,0x10,0xED,0xAB,0x38,0xA5,0x04,0xCD,0xCC,0x19,0xED, +0x30,0x0D,0xD6,0xA7,0x71,0x20,0xC6,0x0A,0x02,0x6B,0x35,0x59,0xAE,0x4E,0x34,0x4E, +0x0A,0x8C,0x95,0x38,0xE0,0xB1,0x41,0x02,0x4A,0xB0,0x5C,0x77,0xCC,0x5A,0x91,0x42, +0xAE,0xB6,0x43,0xA2,0x8E,0xF7,0xC3,0x51,0x85,0xD9,0x05,0x44,0x1A,0xF6,0xE8,0xB0, +0xD4,0x61,0x7F,0x95,0x33,0x1C,0x6C,0x16,0xA5,0x84,0x47,0xEA,0x1B,0xC5,0xF6,0x6A, +0xFA,0xEC,0x3A,0x69,0x36,0x3A,0xE5,0x04,0xB5,0xFA,0xB3,0x75,0x4B,0xB1,0x5B,0xE8, +0x35,0xC3,0x42,0x24,0xCB,0x86,0x3B,0x77,0x52,0xD8,0xC2,0xD9,0x6A,0x3B,0x35,0xCB, +0xC4,0x8D,0xE9,0x15,0x70,0x31,0x96,0xB2,0x31,0xB6,0xF0,0xA1,0x36,0xCE,0xDC,0x14, +0x9A,0x9D,0xC0,0xA2,0x2D,0x0B,0x3B,0x14,0x93,0x61,0x44,0x4E,0xF8,0xE4,0xDC,0x5B, +0x3E,0x45,0x51,0x80,0x29,0x7C,0x86,0xE0,0x21,0x90,0xCA,0xB4,0x57,0xDB,0xD5,0x17, +0x32,0xD7,0xFE,0xE8,0x3E,0x56,0xF2,0x72,0xBA,0x2D,0x6B,0x71,0xC8,0x16,0x7C,0xFD, +0xBA,0x22,0x96,0x8F,0xB7,0x0E,0x6E,0xF1,0xCA,0xF9,0x08,0xB4,0x8A,0x17,0x44,0xD2, +0xED,0x74,0xA3,0x06,0xF4,0xE4,0x60,0xDF,0xA9,0x33,0x23,0xB4,0x61,0xCD,0x71,0xCB, +0x63,0xC5,0x6A,0xF4,0x31,0x61,0xAA,0xD2,0x60,0xF3,0xB1,0xA3,0xB5,0xCE,0x62,0x8F, +0xDB,0xDB,0x5B,0x92,0x24,0xD7,0x7A,0xB0,0x45,0xCF,0xB4,0x6B,0xA5,0x69,0x83,0x59, +0x2F,0x60,0xC6,0xCF,0x0B,0x8A,0xDC,0x8F,0x80,0x3B,0x6A,0x29,0x1E,0xB1,0x9A,0x29, +0xCC,0xF4,0xCA,0xD1,0xF8,0xA7,0x94,0x86,0x01,0x7C,0x38,0xF3,0xDF,0xFF,0xF7,0x75, +0x1B,0x9F,0x6F,0x4D,0x31,0x64,0x63,0x69,0xE0,0x43,0x52,0x18,0xF9,0x04,0xBC,0x04, +0x22,0x2C,0xCC,0x9C,0xDD,0xA7,0xF3,0x5F,0xE8,0xF9,0xD3,0x68,0x74,0x3D,0x4B,0x56, +0xAB,0x3C,0x13,0xAC,0x23,0x29,0x9B,0x37,0x28,0xF9,0x43,0xC9,0xA2,0x95,0xF8,0xF4, +0xFD,0xD9,0x34,0xEF,0xA4,0x16,0xEF,0xE5,0x33,0xB6,0xFA,0xE0,0x23,0x61,0x82,0xBD, +0x52,0xBE,0x43,0xE5,0x97,0xDC,0xF4,0x60,0x9D,0xAC,0x8D,0xAD,0xED,0xB7,0xEF,0xAA, +0x9A,0x24,0x27,0xFA,0xB3,0xED,0x35,0xFF,0x95,0xE2,0x73,0x65,0x4F,0x96,0x8E,0xE7, +0x5F,0x78,0x6C,0x41,0xED,0x4B,0x83,0xED,0x21,0x6C,0x7C,0x15,0xE7,0x99,0xC7,0x6D, +0xC9,0x37,0x93,0xD0,0xA4,0x55,0x84,0x06,0xB2,0x32,0x12,0x5B,0xB8,0xB4,0xD5,0xC4, +0x40,0x46,0xF2,0xB4,0x34,0x4D,0x2B,0x71,0x29,0x67,0x14,0xCD,0xD8,0xE3,0xD6,0x98, +0x43,0xEB,0x96,0xD9,0x2B,0x59,0x11,0x57,0x8E,0xEA,0xC4,0x1E,0x94,0xC2,0x94,0x71, +0xEC,0xA9,0x6A,0x94,0xDC,0x0C,0xD2,0x55,0x2A,0xB2,0x83,0x90,0x84,0xD4,0x00,0x0B, +0xB2,0x04,0xCA,0xA5,0xEF,0xDB,0x8C,0x8B,0xB3,0x57,0x6E,0x9F,0xF9,0x83,0x49,0xB4, +0x86,0xAC,0x7D,0x7D,0x7D,0x64,0x55,0xF0,0x04,0x27,0xCF,0x21,0x92,0x74,0x84,0x43, +0x07,0x2D,0xCD,0x8B,0x01,0x20,0x91,0x57,0xEF,0x3A,0x23,0xF6,0xC7,0x6A,0x44,0x32, +0x28,0xA8,0x1D,0xB6,0x6F,0x39,0x8C,0x81,0xE1,0x9B,0x27,0x75,0x53,0x68,0x88,0x73, +0x6C,0xC4,0xF8,0x33,0x4A,0xC2,0x34,0xF2,0xA1,0xA7,0xD4,0x29,0x34,0x66,0x60,0xBA, +0xCF,0x5D,0xEC,0x4C,0x5F,0xD0,0xF3,0xDC,0x4B,0x19,0x9C,0x77,0x95,0xE2,0x2A,0xE6, +0xC6,0xB7,0xC8,0xE1,0xEE,0x49,0x26,0xC7,0x1A,0x44,0x82,0xD2,0xC9,0x77,0x64,0x79, +0x9F,0xE8,0x9A,0x57,0xBF,0xB1,0x6A,0x7C,0x32,0xC6,0x3A,0x5D,0x05,0x0F,0xD8,0x4E, +0xB4,0x50,0x92,0x22,0xA7,0x76,0x81,0xB8,0x6D,0x55,0xAB,0x06,0x13,0x12,0x77,0x53, +0x52,0x99,0xEC,0xF3,0xA9,0x37,0x5E,0x8D,0x49,0x80,0x8A,0x22,0xFD,0x00,0x9E,0xE1, +0x5A,0xC4,0xA1,0xB1,0x82,0x82,0x37,0x14,0xEA,0xE5,0x80,0x44,0x39,0x12,0x72,0xCE, +0x37,0xF2,0x5D,0x09,0xB8,0x06,0x8C,0xE6,0xD1,0x3D,0x35,0x0B,0x4B,0x6E,0x26,0xC0, +0x31,0xAD,0xE9,0x02,0xE9,0x71,0xBC,0xE5,0x65,0xFD,0x71,0x13,0x5D,0x6C,0x1B,0x63, +0x9A,0x33,0xFB,0x75,0x16,0x05,0x08,0xAA,0xEC,0x9A,0x3C,0x3B,0x09,0x09,0xC4,0x62, +0xD4,0x02,0x8F,0xBC,0xCC,0x0D,0x36,0xA5,0xBE,0xD7,0x3D,0xEC,0xE8,0x3F,0x72,0xF6, +0x88,0x39,0xF8,0xE7,0x63,0x39,0x38,0x17,0x19,0xC0,0x6F,0xC6,0x90,0x38,0x82,0x74, +0x41,0x90,0x54,0xD2,0xA8,0xD3,0x76,0xA9,0x05,0x1A,0x0A,0x20,0xBF,0x38,0x41,0x42, +0x74,0x19,0xBE,0x8D,0x47,0x8C,0x0C,0xD1,0x68,0xC4,0xE9,0xA6,0x93,0x35,0xBC,0x9C, +0xDB,0x07,0xA3,0xB0,0xB4,0xAE,0xE1,0x95,0x04,0x23,0x17,0x6B,0x97,0x5B,0x23,0x43, +0x9F,0x23,0x08,0xCB,0x48,0x19,0xF6,0x64,0x06,0x1A,0x4B,0xB2,0x3E,0x31,0xB0,0x9E, +0xDE,0x27,0x39,0xFF,0x5E,0xBA,0x70,0xAF,0xC7,0xC0,0x86,0x5E,0x15,0x38,0xD4,0x5A, +0x5D,0xD1,0x4A,0x51,0x2C,0xB5,0xDF,0x79,0x34,0x11,0x27,0xBF,0x0A,0xFE,0x9C,0x13, +0x23,0x13,0x3C,0x3D,0x67,0xEA,0xAC,0x11,0x6A,0x35,0xFD,0xBB,0x73,0x3B,0x68,0x93, +0x1D,0x23,0xAC,0xD6,0x6F,0xB8,0x32,0x3B,0xFA,0xCA,0x33,0xE9,0x89,0x4A,0x52,0x95, +0x6D,0x84,0xBD,0xD3,0xD0,0xF9,0x62,0xF5,0x81,0xEE,0x61,0xF7,0x09,0x4B,0xB2,0x24, +0xD0,0x21,0x4A,0xE9,0xB9,0x07,0xAC,0x36,0x23,0x5C,0x16,0xD0,0x40,0xB9,0x55,0x39, +0x43,0x09,0x26,0xBE,0x3A,0x09,0x6E,0x72,0xF4,0x4A,0x74,0x1E,0x0A,0x4F,0x99,0x48, +0x30,0xA1,0xE8,0xBF,0xAD,0x32,0x1E,0x42,0x89,0xA1,0xAA,0x73,0xA0,0xC8,0x4F,0x95, +0xF4,0x75,0x7B,0x04,0x20,0x98,0x7A,0xAB,0x30,0x59,0x54,0x15,0xAC,0xCE,0x83,0x40, +0x77,0xA8,0x5D,0x2F,0x88,0xD5,0x87,0x60,0x1C,0xF1,0x5D,0x25,0x60,0x54,0xF2,0xC7, +0x94,0xEC,0x14,0x04,0x66,0x3D,0xF0,0xB9,0x0F,0xD5,0xD2,0xCF,0x22,0xCC,0x4A,0x4B, +0xCF,0x6F,0x04,0xB6,0x80,0x6D,0xC4,0xDF,0xDE,0xE3,0x90,0x5A,0x6C,0x0A,0x51,0xB2, +0x3D,0x82,0xF2,0x3D,0x82,0xE6,0xEA,0x6D,0x01,0x54,0xAC,0xD8,0x2F,0xB9,0x20,0x28, +0x93,0x49,0x42,0x0D,0xED,0x94,0x9A,0xE1,0xCA,0x85,0xB1,0x99,0x43,0x13,0x8C,0xAB, +0x2A,0x35,0xC4,0x83,0xAA,0xA9,0x3B,0xCF,0xD1,0x79,0x40,0xAA,0x04,0x4F,0x0E,0xF0, +0x27,0x97,0x82,0xF9,0xD7,0xDB,0x04,0x9D,0x0B,0xA5,0xF3,0x77,0xE3,0x48,0xF5,0x0C, +0x88,0x45,0x0C,0x75,0x95,0x6A,0x72,0x63,0xF9,0x32,0xC1,0x2A,0x68,0x6F,0xFC,0x55, +0xD0,0x04,0x15,0x05,0xC2,0x96,0x62,0x49,0x89,0x97,0x70,0x70,0x63,0xC3,0xE9,0xA2, +0xFA,0x69,0x51,0xC9,0x89,0x7A,0x53,0xC5,0x02,0xBB,0x6C,0x5A,0x46,0x35,0xA7,0xAB, +0xD5,0x77,0xB1,0x2C,0x42,0x64,0xF8,0x5D,0xD0,0xCA,0x70,0x0E,0x59,0x84,0xA9,0x73, +0x2C,0xB4,0x7E,0x58,0xEB,0xC0,0xC4,0x42,0x3E,0x21,0x8D,0x2F,0xBB,0xEB,0x4F,0xF1, +0x8C,0x03,0x67,0xD0,0xFB,0x79,0xB2,0x41,0x1D,0x25,0xB6,0xF8,0xAF,0xCB,0x41,0xBF, +0x2F,0x2A,0x14,0x53,0xCE,0xBA,0x76,0x1D,0xAB,0x62,0xA9,0x95,0xD7,0xEB,0xD7,0x22, +0x69,0xC7,0x10,0xA1,0xC3,0x1B,0x79,0x43,0x3C,0xB1,0x69,0x60,0x4A,0x08,0xCE,0x39, +0x7C,0xE0,0x15,0xE1,0xC4,0x25,0xC5,0x43,0xA5,0x6B,0xA5,0x64,0x92,0xFD,0xF5,0xC1, +0xD9,0x5A,0xBE,0xDC,0x0B,0x5C,0xF8,0xB4,0xB5,0xCA,0x37,0xA2,0xCC,0xEF,0x0C,0x45, +0xE0,0x89,0x8C,0x3C,0xB0,0x0C,0xC1,0x75,0xE8,0xA1,0x6D,0x20,0x15,0x17,0x56,0x6F, +0x47,0x07,0x88,0x80,0xE3,0x17,0x86,0xA3,0xBB,0xE9,0x55,0x6B,0x6E,0x8A,0x5F,0x22, +0x6A,0xD4,0xD8,0xD3,0xCD,0x0F,0x1C,0xBD,0xD8,0x49,0x3B,0xF1,0x57,0xCC,0xD3,0xDD, +0x8E,0xC6,0xF7,0xE1,0xE6,0x68,0xF3,0xD4,0x35,0x03,0x10,0x09,0xEA,0x00,0x1C,0xD6, +0xA5,0xC8,0xCF,0x7C,0x29,0xE9,0x7A,0x0C,0xC4,0x74,0xA6,0x00,0x55,0x94,0x2D,0x15, +0xC3,0x56,0x86,0xF9,0x77,0xE4,0xE5,0x66,0x0C,0x06,0xEB,0x65,0xCB,0xA4,0x5C,0x00, +0x60,0x14,0x3D,0x03,0xBB,0x0A,0x39,0xF5,0x22,0x83,0xBA,0x53,0x73,0x0F,0x38,0xFE, +0x81,0x31,0xB9,0x9E,0xDC,0xF2,0xE6,0xCB,0x3A,0xDB,0x85,0xE6,0x89,0xEB,0xC8,0x9B, +0xA3,0x68,0xD6,0x3C,0xB7,0x19,0x27,0xE7,0x71,0x26,0x59,0x01,0x37,0xFF,0x8B,0x17, +0x37,0xE3,0x6A,0x8B,0xF4,0xED,0xB2,0x29,0xFF,0x4E,0x6C,0x76,0x4B,0x65,0xE5,0xE5, +0xA4,0xF9,0x2A,0xBF,0xE3,0x3F,0xE9,0x46,0x9B,0xDD,0x37,0x12,0xD7,0xBC,0x40,0x69, +0x9C,0xE0,0x31,0x78,0xA4,0xAE,0x10,0x4B,0x25,0xE2,0x52,0x25,0xC4,0xA5,0x0F,0x0D, +0x8F,0xA0,0x25,0x02,0xBF,0x8A,0x98,0xFF,0x9D,0xFA,0xD2,0xAF,0x0F,0xE9,0x14,0xB7, +0x9F,0xEC,0x20,0x8E,0x6A,0x3C,0x8E,0x94,0xD7,0x41,0x1A,0x92,0x0D,0xA3,0x3B,0x26, +0xFF,0x0D,0x73,0xE0,0x7A,0xE9,0x70,0x07,0x56,0xA3,0xB3,0x59,0x9D,0x95,0x65,0x9D, +0x5F,0x5A,0xE4,0x5F,0x1C,0x49,0x88,0xD4,0xFE,0x37,0x11,0x1B,0x53,0x72,0x6E,0x6C, +0x89,0x5F,0x84,0xE0,0xA1,0xC7,0xDD,0x73,0x14,0x4F,0x40,0x79,0x6E,0x0B,0xF3,0x33, +0x36,0xDC,0x0E,0xCF,0xC2,0x16,0x57,0x20,0x29,0x93,0x01,0xC8,0x39,0xB2,0xE5,0xBF, +0xF5,0xFC,0x07,0x61,0x1D,0x89,0x59,0xC5,0xF8,0x70,0xED,0x50,0x25,0xB8,0xF2,0x6E, +0x53,0xBC,0x08,0x93,0x69,0x4F,0xB9,0x5C,0x9C,0x56,0xC3,0x8A,0xF7,0x74,0xB0,0xBC, +0x50,0x24,0x6B,0x31,0xAE,0x98,0x65,0x1B,0x47,0xC8,0xC9,0xF9,0xED,0x15,0xF2,0x9F, +0xE3,0xB7,0x33,0xD9,0xA2,0x79,0xC5,0x3D,0x27,0x6F,0x6C,0x00,0xD7,0x8B,0xF8,0xB0, +0x33,0x9B,0xB8,0x74,0x6D,0x8F,0xDA,0x8A,0x83,0xFB,0x1B,0xD6,0x87,0xE9,0x80,0x36, +0xCD,0xF3,0xB5,0xB2,0x81,0xF0,0x95,0xFB,0x14,0x18,0x7F,0x92,0x16,0xF9,0x24,0x07, +0x55,0x3D,0xC7,0x52,0x55,0x07,0x56,0x62,0x72,0x15,0xE3,0x20,0x01,0xAA,0x60,0x38, +0x75,0x5D,0xE8,0x34,0x9C,0x2C,0xD9,0x65,0x53,0xAD,0xEF,0x72,0x47,0x62,0xB0,0xDE, +0xA9,0xDC,0x81,0x51,0x11,0x07,0x39,0x02,0x55,0xF5,0xED,0xF9,0x7B,0xFF,0x5D,0x12, +0x33,0xE2,0x62,0x1D,0x61,0x8A,0xD9,0xF4,0xEE,0xF6,0xB7,0xF5,0x53,0x46,0xA9,0x58, +0xB6,0xA7,0x1E,0xE9,0x5F,0xFB,0xE3,0xD3,0x5D,0xCC,0xB2,0x16,0x61,0x0D,0x32,0x8A, +0xF8,0xC0,0x8E,0xC2,0xD2,0x5F,0xD5,0x80,0x2C,0x61,0x51,0xBB,0xA6,0x0E,0xAF,0x10, +0xED,0xCE,0xA0,0xE6,0x57,0xF4,0x6B,0xBC,0xD2,0xED,0xF0,0xB0,0xF1,0xB4,0xFA,0x8A, +0xBE,0x25,0xFA,0x00,0x2E,0xDD,0xBF,0x99,0x8F,0xD7,0x66,0x79,0x28,0x11,0x18,0x48, +0x01,0x53,0xBB,0x83,0x72,0xC1,0x2F,0x85,0x20,0xD1,0x4F,0x54,0x65,0xB8,0x93,0x49, +0x46,0xE0,0xF4,0x76,0xE7,0x53,0x2F,0x4F,0xA1,0xA0,0xAA,0x22,0xB6,0xC4,0x1A,0xA0, +0x40,0x72,0xC3,0x1C,0x4B,0xB3,0xF3,0x9D,0x36,0xE2,0x1D,0x4F,0xC7,0x7C,0x19,0xC8, +0x9B,0x7A,0x2A,0x36,0xD3,0xCF,0x10,0x92,0x5C,0x72,0x9B,0x1C,0xF3,0xE3,0xDE,0x74, +0x20,0x20,0x2E,0x79,0xE3,0x62,0xDE,0xF4,0x48,0x4B,0xDD,0xAC,0xB4,0xC0,0x27,0x8F, +0x4D,0x4A,0x2A,0xD8,0xE6,0x72,0x2C,0x18,0xF8,0x76,0x7F,0x79,0x7D,0x7F,0x0B,0xDA, +0xE6,0x88,0xB8,0x91,0xA7,0x80,0x82,0x8D,0xDC,0xDA,0xD4,0x47,0xBF,0xB7,0x65,0x8F, +0x62,0x1A,0x64,0x4E,0xFD,0x40,0x74,0xE3,0x9A,0x4E,0xB6,0xFA,0x2A,0x77,0xC3,0xE8, +0xA5,0xE1,0xD7,0x34,0xC5,0x1F,0x94,0xA5,0xDF,0xB9,0x75,0x34,0x59,0xF0,0x54,0x01, +0x22,0x56,0x84,0x71,0xB1,0x04,0xE4,0x8E,0xA9,0x38,0xF6,0x04,0xAC,0x92,0x43,0x07, +0xD8,0xE9,0xFB,0x26,0x7B,0x1C,0xFF,0xB5,0x78,0x63,0x41,0xFF,0x2E,0xDA,0x23,0xC4, +0x5F,0x9D,0x86,0x3A,0x2F,0x17,0x72,0x4C,0x52,0x35,0x49,0xAE,0x25,0x06,0x4C,0xB5, +0x3B,0x6F,0xBE,0xD2,0x17,0xBC,0x1F,0x00,0xAB,0x55,0xB4,0x51,0xDF,0x0C,0xCC,0xB4, +0xD3,0x64,0x3E,0xF2,0x2A,0x51,0xD7,0x72,0x20,0xA1,0xFC,0x26,0xE3,0xAC,0x85,0x7B, +0xEE,0x48,0xDA,0xAB,0xC8,0x8B,0x94,0x85,0x31,0xA5,0x01,0xDB,0x08,0x3E,0xA7,0x93, +0x6A,0x65,0x6B,0x36,0x80,0xA3,0x48,0x30,0x36,0xF0,0xB9,0x00,0x67,0x8C,0x2A,0xCB, +0xED,0x18,0xAF,0xB0,0x71,0x33,0x2B,0x1A,0x7C,0xF6,0xD1,0xBA,0x48,0x71,0xE7,0x20, +0xB5,0x85,0x40,0xA3,0x58,0xB0,0xB9,0x99,0x41,0x3A,0x83,0x4A,0x7D,0x58,0x3F,0x38, +0x87,0x15,0x2E,0x8E,0xB2,0x53,0x4C,0x19,0x33,0xF6,0x37,0x98,0xC5,0xD2,0xFC,0x4E, +0xF0,0x64,0xFA,0x1A,0x19,0x4E,0xB8,0x55,0x88,0xE7,0x5C,0x92,0x4C,0xD9,0x57,0x20, +0x02,0x5D,0x8D,0x76,0x16,0x60,0xDF,0x43,0x0F,0xB3,0xB9,0xA3,0x32,0xF6,0x70,0xCE, +0x2B,0x44,0x52,0x1A,0x29,0x3F,0x95,0x9F,0x80,0xD1,0x56,0xF8,0x91,0x82,0x2E,0xF6, +0x88,0x45,0x74,0x94,0xC8,0x6F,0x2D,0x89,0x82,0x81,0x4A,0xBF,0xB5,0xDE,0x87,0x41, +0x03,0x74,0xC9,0xAB,0xA9,0x39,0x42,0x98,0xB3,0xA5,0x49,0xA8,0xD4,0x97,0x0B,0x8C, +0xAE,0x51,0xD9,0xFB,0x0D,0x44,0xB6,0xCF,0x95,0xEC,0x86,0xD7,0xE0,0x02,0xA5,0xBA, +0xE6,0xF3,0xCE,0x95,0x26,0x55,0x14,0x3E,0xF9,0xC4,0xC3,0x36,0x51,0x65,0x74,0xA7, +0xA5,0x1D,0x04,0xC2,0x5F,0x14,0x98,0x14,0x72,0x31,0x5E,0x07,0xAC,0x2D,0x4D,0x26, +0xA1,0x9C,0x13,0xAE,0x68,0x5C,0xAB,0xA8,0xF2,0x8A,0x32,0x6A,0xD9,0x2D,0x33,0x85, +0x4B,0xBE,0x23,0x0E,0x1E,0x6B,0x28,0x6B,0x05,0x53,0xFE,0x15,0x2F,0x70,0x1C,0x81, +0x6B,0x1F,0x0B,0x36,0x20,0xE8,0xEF,0xEB,0x97,0x3C,0xE9,0xA1,0x08,0xAA,0x80,0x30, +0x1E,0x86,0x50,0x5A,0x4A,0x3B,0xE9,0x08,0x8A,0xF9,0xC5,0x22,0x7B,0xC1,0xBC,0x7C, +0x65,0x01,0x34,0x57,0x7A,0xCD,0xC4,0x95,0xBB,0x85,0xAA,0xAF,0x35,0x44,0x49,0x5E, +0x08,0xF1,0xE4,0x38,0x62,0x59,0xE8,0xCE,0xF8,0x1B,0xD9,0x25,0xE4,0x01,0x90,0x2B, +0xAA,0x5C,0xAB,0x6D,0xCF,0x90,0xBA,0xBF,0x14,0x57,0x51,0x4B,0xE2,0x0D,0x98,0x98, +0x0A,0x7C,0xCC,0x16,0xC0,0x67,0x05,0x40,0xC3,0x60,0x53,0xB5,0x2B,0x49,0x48,0x44, +0x39,0xD4,0xE6,0xF7,0xA7,0x69,0x50,0xA4,0xDF,0xC7,0x90,0x58,0x74,0x03,0x63,0x4B, +0xA2,0x0F,0xC5,0x00,0x02,0x9E,0x24,0x9B,0x45,0x76,0x58,0xC8,0x48,0x3A,0x52,0x16, +0x65,0x23,0x43,0x76,0xF0,0x81,0x2C,0x03,0xE7,0xC8,0xD2,0x19,0x24,0xE3,0x54,0x40, +0xF9,0xB2,0x99,0x22,0xE0,0x00,0x58,0x1F,0x1D,0x43,0x18,0x5D,0x85,0x23,0x31,0xFC, +0xC4,0x62,0x6F,0x60,0xC5,0xAA,0x9F,0xAE,0x1B,0x78,0x62,0x67,0xC4,0xBF,0x43,0x9F, +0x51,0xBB,0xCB,0xBB,0x0E,0xD5,0xB1,0x95,0x49,0x7F,0x97,0x63,0xA0,0xA0,0x43,0xF8, +0xCE,0xA7,0x74,0x25,0x4F,0xEB,0xBD,0x6D,0xE3,0xEC,0x60,0x83,0xA1,0xB2,0x00,0xDB, +0xFE,0x0C,0xEF,0xAA,0x04,0x03,0xE2,0x69,0x10,0xCB,0xE6,0x95,0x5C,0x35,0xF4,0x9E, +0x3B,0x3D,0xD2,0x98,0xEA,0xB8,0x6E,0xD6,0x15,0xB5,0xC2,0x23,0xCD,0x1F,0x8F,0xBA, +0x4E,0x15,0x79,0xF7,0x46,0x31,0x4D,0x8E,0x42,0xE5,0x19,0xA5,0x52,0xDE,0x63,0xE7, +0x95,0x8C,0x5E,0x8D,0xD6,0xCC,0x47,0x82,0x33,0x3A,0x48,0x7E,0x06,0x40,0x0F,0x6A, +0x80,0x92,0x5B,0x64,0xC4,0xED,0xDD,0x6E,0xC9,0xB2,0x45,0xC6,0x1C,0xD0,0x3B,0xF3, +0xF5,0xC1,0x3E,0x61,0x91,0x17,0x3E,0x9D,0x22,0xC3,0x4B,0x4A,0x50,0xD4,0x0F,0x75, +0xD2,0x81,0x08,0xBB,0xB3,0xD3,0xDF,0x51,0xE9,0xA6,0x15,0x43,0x7B,0x6E,0x9E,0xCA, +0x5B,0xFE,0x77,0x8E,0x99,0xD4,0x9E,0xDE,0x38,0x99,0xF8,0x63,0x23,0xBE,0x72,0x57, +0xB2,0x4A,0xEA,0x49,0xEE,0xD2,0xDF,0x5C,0x0F,0x5E,0x93,0x72,0xEF,0xD0,0x9B,0xEC, +0xE2,0x41,0xCA,0x52,0x06,0xBA,0xA7,0x7D,0x76,0x26,0x6D,0xEB,0x23,0xAC,0x02,0xEE, +0x31,0x32,0x58,0xDF,0x34,0x86,0x90,0xBD,0x41,0xC9,0xB0,0x83,0x8E,0x8B,0x23,0xEB, +0x7C,0x81,0xB8,0x11,0xE5,0x46,0x47,0x93,0xAC,0xAA,0x98,0xAF,0xC4,0xF4,0xEA,0xFE, +0x7D,0x29,0x5F,0xE9,0x37,0xAF,0x41,0x34,0x74,0xBD,0x22,0xD9,0x41,0xAF,0x4A,0xBC, +0x70,0xD1,0xDF,0x42,0xEA,0x2E,0xDF,0x22,0x6F,0xD1,0x5A,0x31,0x83,0x80,0x06,0x8C, +0x80,0x4F,0x67,0x92,0xCF,0xB4,0x3A,0x43,0x2A,0xC6,0xE8,0xF5,0x41,0xA8,0xB2,0x37, +0x54,0xAB,0x10,0x86,0x99,0x0B,0x56,0x66,0x9B,0xF6,0xE7,0x7D,0x09,0xCA,0x19,0x2F, +0xE6,0x32,0xBE,0xA9,0xE2,0xFF,0xF2,0x2D,0x77,0x51,0x42,0x99,0xAE,0xF3,0x39,0xF6, +0xAB,0xAA,0x98,0xD5,0xDB,0x47,0x1D,0x5B,0x08,0x4F,0x16,0x6C,0x5C,0x61,0x25,0x2C, +0x77,0xE6,0x70,0x04,0x10,0x47,0x3F,0x85,0x9E,0xF7,0x9D,0xC3,0xDB,0x17,0x6C,0xD6, +0xD4,0xFB,0xF2,0xF5,0x52,0xFB,0x2D,0x9C,0xB1,0xE3,0xA0,0xE0,0xB9,0xA3,0xAE,0x1F, +0x90,0xDE,0x95,0xDD,0x47,0x15,0x8A,0x1F,0x4B,0x1C,0x5F,0xE0,0x6E,0xEC,0xD1,0x37, +0x4C,0x2C,0x78,0xDF,0xB8,0xC3,0x99,0xDC,0x00,0x58,0xC8,0x7E,0x59,0x00,0x24,0xA7, +0xF2,0xD0,0xCA,0x53,0x8E,0x24,0xB1,0xE3,0xF3,0xDA,0x78,0x7C,0x4B,0x50,0x01,0x87, +0x7F,0x8B,0x7E,0x4F,0xBA,0x5F,0x3B,0x96,0x53,0xF3,0x1B,0x9D,0x33,0x3C,0x91,0x87, +0x61,0xC3,0xD6,0xED,0x91,0x8F,0x80,0x28,0xF0,0x1A,0x42,0xB1,0x12,0xB0,0xED,0x60, +0xEB,0x21,0xB3,0x16,0x6A,0xD3,0x75,0x89,0xCA,0x2D,0xE7,0xBE,0xFE,0xE7,0x42,0xDD, +0xC9,0x9A,0x26,0xCD,0x93,0xE0,0xFC,0x04,0xE1,0x4A,0x10,0xBF,0x62,0x3F,0x66,0x70, +0xC2,0xE3,0x3F,0x2B,0xA2,0xC5,0x20,0x3B,0xA8,0x65,0x8D,0xAA,0xAD,0x47,0x0C,0x6A, +0x0C,0xAB,0xA6,0x79,0xE0,0x21,0x8E,0x61,0xE8,0xAE,0x9B,0xB8,0x73,0x18,0x9F,0x87, +0xC6,0x4B,0x28,0xC8,0xAE,0x27,0x41,0xB9,0x35,0x86,0xBF,0xC5,0xE9,0xA6,0xCD,0x30, +0x00,0x3A,0x3F,0xD7,0x60,0x31,0x41,0xBE,0x2F,0x48,0xF6,0x19,0xA1,0xD3,0xBA,0x4C, +0x3C,0x25,0xDB,0x0B,0x36,0xC4,0x4A,0x22,0x26,0x4A,0xDE,0xF0,0x69,0x6A,0x7A,0x72, +0xDA,0x29,0x0F,0xA7,0xB2,0xD5,0x45,0x8F,0xB9,0x90,0x05,0x70,0x42,0x75,0x12,0xB2, +0x41,0x28,0x1D,0x76,0xBF,0x48,0x8C,0x84,0xD1,0xFF,0x96,0xB4,0x56,0xD7,0x3B,0x52, +0x84,0x42,0x4A,0x0C,0x85,0x4D,0x61,0x68,0x56,0x98,0xE3,0x71,0xCE,0x8B,0x46,0xDF, +0xFD,0xBA,0x4A,0x83,0x47,0x40,0xB4,0x05,0x8D,0xA5,0x10,0x20,0xEC,0xBE,0x61,0x5E, +0x9C,0xAA,0xD5,0x84,0xBC,0x15,0xF9,0xBA,0x27,0x5E,0x21,0x4D,0x53,0x45,0x1B,0xB1, +0x8D,0x93,0x6E,0x45,0xBE,0x6E,0x69,0xB3,0x18,0xD3,0x66,0xB5,0xB4,0xBC,0x13,0x0C, +0xBB,0x3E,0x5A,0x8A,0x4F,0x37,0xAB,0xE7,0x6B,0x49,0x34,0xAE,0xBF,0xD5,0xE4,0x8D, +0xEB,0x22,0x8C,0x69,0xD5,0xBB,0xA6,0xE1,0x97,0xBA,0x39,0xFE,0x72,0xDC,0xA9,0xC9, +0xB5,0x4D,0x3B,0x75,0x51,0x9A,0x6A,0x3A,0xFD,0xD1,0x76,0x09,0xFE,0xB3,0xE1,0xB6, +0xAF,0xBB,0x6A,0xF8,0x0D,0xBD,0x11,0x1A,0x05,0x11,0x4B,0x58,0xB6,0xDE,0x86,0x2A, +0xBF,0xD9,0x96,0x09,0xBC,0x11,0xC3,0xED,0x2E,0x2A,0x88,0xE6,0x4B,0xD6,0xB5,0x75, +0x87,0xC8,0xE8,0x2A,0x5B,0x7B,0xEA,0xA2,0x27,0xFD,0x7A,0x8D,0x42,0xB9,0xD6,0x53, +0x65,0x23,0x80,0xCE,0x3D,0x6F,0x0D,0xC5,0xDD,0xB6,0xF2,0xA4,0x9A,0x7C,0xA8,0xB8, +0x1F,0x8D,0x37,0x67,0xC3,0x1B,0x39,0xD2,0x51,0xE3,0xA6,0x41,0x92,0x5D,0x04,0x28, +0xB5,0x53,0x40,0x4B,0xF2,0xE5,0x71,0xB3,0xF9,0xA1,0xA3,0x6A,0x3A,0x72,0x5B,0x28, +0x94,0x82,0x26,0xEC,0xF7,0x91,0xAD,0x8B,0x9E,0x07,0xAA,0xAD,0xE1,0xB1,0x54,0xFE, +0x15,0xBD,0x76,0xDB,0xF5,0x76,0x48,0x74,0xB1,0x5E,0x5B,0x02,0x48,0x11,0x87,0xBC, +0xC8,0xDD,0xD4,0x49,0x8A,0x70,0xEE,0x89,0x90,0x69,0x1D,0x8C,0xA3,0x5E,0xC7,0xF8, +0xA6,0x16,0x45,0x6F,0xBE,0x2A,0x86,0xF5,0xD8,0xD4,0x18,0x21,0x4B,0xEE,0x4C,0xA8, +0x5D,0xD1,0x52,0x07,0xC0,0xE6,0x29,0xC6,0x0B,0x4E,0xD6,0x47,0xB1,0x7C,0x08,0xB7, +0xEE,0xA5,0xAC,0x25,0x6A,0x6B,0x1E,0xAF,0xFB,0x7F,0x4A,0x9B,0xD9,0x92,0xE2,0x12, +0x7E,0xD1,0xB7,0xA9,0x81,0xBE,0x16,0x68,0x5A,0x6E,0xD1,0x94,0xE5,0xBE,0x37,0xAE, +0x07,0x79,0x72,0xC5,0x0E,0x81,0xC6,0x22,0x32,0x3D,0xF1,0xE8,0xBF,0x34,0x5E,0x22, +0x59,0xC7,0x75,0x76,0xFA,0x55,0x62,0x0C,0x81,0x55,0x83,0x95,0xB8,0xD8,0x38,0xB2, +0x66,0x4A,0x42,0xD4,0xDE,0xED,0x0C,0xE8,0xE0,0x5C,0xD0,0xC3,0x3E,0xDF,0xF6,0xA6, +0x2E,0xBB,0xFF,0x3F,0xD2,0x74,0xCB,0xF7,0xF9,0x70,0xA0,0x84,0x96,0x15,0x00,0xE7, +0xE3,0x11,0x1F,0x62,0x06,0x87,0x92,0x60,0xA5,0x0C,0xEE,0x76,0xED,0x5F,0x77,0x04, +0xD6,0x10,0xFE,0x51,0x1E,0xB7,0x1C,0x9E,0x63,0x01,0x51,0xAE,0x11,0x1E,0xCD,0x12, +0xCE,0x45,0x77,0xF0,0x20,0x1D,0x7D,0xBC,0xB5,0x94,0xDF,0xFB,0xFB,0x2C,0x32,0x9C, +0x34,0xD4,0xF8,0x85,0xEB,0xC7,0x18,0x25,0x58,0xEF,0x59,0x90,0xE8,0xC7,0x0F,0xEB, +0x84,0x8F,0x06,0x8C,0x7C,0x37,0x6C,0x8F,0xAB,0x93,0x46,0x40,0x17,0xA0,0x72,0x96, +0x5A,0x4A,0x71,0x31,0x3A,0x87,0xB1,0xD6,0x85,0xDC,0xEB,0x32,0xE5,0x04,0x91,0xD5, +0x5C,0x22,0xEC,0xD1,0xC4,0x46,0x50,0x6A,0x23,0xEE,0x24,0x6E,0x51,0x4D,0x53,0xEE, +0xFB,0x06,0xC4,0xB2,0x16,0xD5,0x86,0x5F,0x99,0x71,0xE0,0xE3,0x18,0x2B,0x5E,0x94, +0x4B,0xEF,0xA0,0x5C,0x67,0x76,0x8A,0x77,0x0D,0xF9,0xE8,0xD4,0x4B,0x15,0x96,0xAE, +0x31,0x66,0x98,0xDB,0x25,0xCB,0x94,0xAC,0x92,0x72,0x0F,0xE9,0x3F,0xF4,0x36,0x67, +0xB3,0xCC,0xAD,0x67,0x64,0x40,0x52,0x72,0x7A,0xD9,0x54,0x18,0xEA,0xA3,0xEA,0x91, +0x40,0x28,0x4B,0x0C,0x28,0x89,0x32,0x85,0xC9,0x27,0x35,0xEF,0xCD,0xDE,0xFA,0x54, +0x64,0x0C,0xF1,0x4A,0xF6,0xEB,0xC7,0xC7,0x90,0x6A,0xCC,0xF6,0x6F,0xF5,0x31,0x1E, +0x80,0x06,0xB6,0x94,0x14,0x49,0x9A,0xB5,0xBF,0x2F,0x46,0xB3,0x9C,0x27,0x09,0xF8, +0xBE,0xFC,0xF2,0xB8,0x7C,0x65,0x51,0x89,0xB2,0xD3,0xE9,0x61,0x61,0x29,0x77,0xE3, +0x3B,0xC2,0x04,0xC2,0x14,0xBB,0x9A,0xD4,0xEC,0x1A,0x75,0x99,0xC9,0xB6,0x86,0xC9, +0x29,0xB5,0x0E,0x8A,0x6F,0xD0,0x49,0xCE,0x85,0x99,0x6E,0x8D,0xB7,0xA0,0x79,0xB6, +0x47,0xCA,0x96,0x5B,0x00,0xCB,0x68,0x39,0x70,0xA0,0xF4,0x28,0x7A,0xC7,0xAD,0x52, +0x2D,0xE8,0x96,0x6D,0xD4,0x07,0x3A,0x39,0x7E,0xEE,0xC6,0x3C,0x7C,0x1D,0xAB,0xB8, +0xB6,0x85,0xE2,0x0E,0x9C,0xBB,0x63,0xD5,0xAD,0xDF,0x0D,0xFB,0xEC,0xFA,0xE2,0x80, +0xB2,0x35,0x31,0x6C,0x3C,0x3A,0xFA,0xE5,0x92,0x2D,0x5B,0xB8,0x85,0x2F,0xBA,0x97, +0x9D,0x03,0x6B,0xD7,0xA2,0x42,0x22,0x4D,0x3D,0x68,0x7D,0x36,0x7D,0x99,0xB8,0xF8, +0xBA,0x45,0xD7,0xEA,0x08,0x4D,0xA6,0x5E,0xB1,0xD9,0x05,0xFF,0x58,0x13,0x3B,0x7F, +0x27,0xBB,0x24,0x9E,0x93,0x28,0x45,0xD1,0x8F,0x62,0xE7,0x7C,0x3C,0x06,0x99,0x98, +0x82,0x0F,0x86,0xD8,0xC9,0x26,0x40,0xDE,0x6E,0x58,0x55,0x02,0xE2,0x39,0x49,0xEF, +0x18,0x57,0xFB,0x7F,0x95,0x2F,0x89,0x91,0x7B,0x51,0xCF,0x59,0x9C,0xE5,0xB3,0xDA, +0x5F,0x8E,0x72,0x13,0x77,0x4A,0x16,0xD1,0x89,0xA1,0x17,0x3F,0xC6,0x0A,0x9E,0xC3, +0x9C,0x69,0x93,0x0F,0xF2,0x89,0x3F,0xE1,0x9C,0xA4,0xE0,0x4B,0x48,0x41,0xB6,0x17, +0xA4,0x76,0xC1,0x59,0xB8,0x5D,0x49,0x92,0xCB,0x18,0x16,0x6D,0x31,0x8E,0xB2,0x7C, +0x14,0x29,0x14,0xB1,0x8B,0x02,0x56,0xC8,0x4F,0x10,0xEC,0x70,0x2C,0x58,0x77,0xEB, +0xC7,0xFA,0xB2,0x87,0x81,0x1F,0xC0,0xA5,0xD9,0xAF,0xBC,0x00,0x6D,0x2E,0x9C,0x1F, +0x55,0xF2,0x66,0xD6,0x76,0xCA,0x0F,0xED,0x3C,0xB1,0xA7,0xE2,0xFC,0x0E,0x55,0x84, +0xC9,0x82,0x2F,0x1B,0x60,0x84,0x36,0x57,0x89,0x90,0xF4,0x71,0x12,0xF8,0xC7,0x7E, +0xB8,0x05,0x6B,0x40,0x79,0x4D,0xA1,0x6A,0xF8,0xAA,0xD2,0x92,0x6A,0xBB,0xEB,0x4D, +0x8A,0xA4,0x75,0xE9,0xDC,0x25,0xBF,0x58,0xB7,0xC8,0x39,0x54,0x45,0xB5,0xCE,0xF4, +0xCE,0x60,0xFA,0xF6,0xA4,0xB9,0x6D,0x88,0xD1,0x90,0x09,0xC1,0x4B,0x80,0x53,0x73, +0x83,0x98,0xA6,0x34,0x38,0x34,0xEA,0x79,0xB2,0x9D,0x2B,0x5E,0xE5,0x13,0x9B,0x3C, +0x2D,0xE8,0xCE,0x35,0x14,0x7C,0xD9,0x5F,0xC4,0xA8,0x14,0x8F,0x13,0x17,0xB2,0xDA, +0xF0,0xD8,0x1E,0x37,0x7E,0x9A,0x61,0x63,0x85,0x79,0xF8,0xC9,0x0F,0xD9,0xF4,0xEE, +0xF8,0xBE,0x7F,0x89,0x02,0xB1,0xED,0x0D,0x9D,0x6D,0x02,0x0E,0x1B,0xD6,0x0A,0xDF, +0x4D,0x98,0xE9,0xF4,0x5C,0x32,0x40,0x3E,0x3B,0x02,0xB7,0xBF,0x03,0x9A,0x5C,0x2B, +0xBE,0x1B,0xF0,0xCD,0xAD,0xE7,0x8E,0xBC,0xD2,0x87,0xC9,0x0F,0xD7,0xFD,0x16,0x5B, +0x69,0x7F,0xD1,0x81,0x42,0xD3,0x1A,0x8F,0xAE,0x15,0xF6,0xFA,0xBF,0x20,0x4F,0xE3, +0x2E,0x1C,0x10,0xC1,0xDD,0x9E,0xB4,0xCA,0x5B,0x00,0xEA,0x53,0x11,0x8F,0x3D,0xAD, +0xAB,0x90,0x63,0xD6,0x82,0x2F,0xFC,0x7F,0x9A,0x01,0xB1,0x4B,0x2C,0x57,0x10,0xFB, +0xBF,0x05,0xC7,0x8F,0x0B,0xEC,0x70,0x99,0x70,0xB2,0x21,0xFB,0x08,0x60,0x7B,0xCD, +0xA4,0x12,0x00,0x56,0x0A,0x5B,0x42,0x7A,0x96,0x8E,0x40,0xE0,0x4C,0x8C,0x05,0xCF, +0x65,0x91,0x0B,0x0F,0x17,0x52,0x67,0x35,0x69,0x01,0x0B,0x39,0xE6,0x2D,0xCC,0xCF, +0x06,0x5A,0x08,0x06,0xB2,0x1E,0x5F,0x8E,0x1F,0x26,0xB1,0x25,0x05,0xB9,0x0B,0x47, +0xEB,0xD3,0x47,0x80,0xB6,0x39,0xD0,0xB6,0xDE,0x94,0xEF,0xF6,0x07,0x0C,0x58,0xDD, +0x14,0x31,0x71,0x9E,0x84,0x94,0x9A,0x17,0x02,0x5C,0x85,0xBE,0x94,0x39,0xBE,0x9F, +0xC1,0xB4,0x8A,0x72,0xEE,0xC6,0x2A,0xFE,0x7C,0x8B,0xE4,0x38,0xE7,0x28,0xE2,0xB3, +0x32,0xC5,0xF8,0x6B,0x50,0x42,0x2F,0xEC,0xC8,0x6B,0x1C,0xD1,0x1C,0x9B,0xE2,0x3F, +0xF8,0x3E,0x3E,0x5F,0x3B,0x46,0xF6,0xCB,0x12,0x52,0x89,0x0C,0x4B,0xD2,0x48,0xAD, +0xCB,0x03,0x4B,0x17,0x6D,0x96,0xA9,0xC8,0x9C,0x34,0xF3,0xD0,0xAF,0xD7,0x17,0xBE, +0xB8,0x6F,0xE4,0x18,0xF0,0x15,0x4E,0xAC,0xEA,0xFB,0x16,0xEF,0x78,0x0E,0xC5,0x03, +0xC6,0xD3,0x6D,0xDA,0x72,0x15,0xC3,0x47,0x82,0xEB,0xFE,0x8E,0x68,0x5F,0xB0,0x08, +0xC1,0xE6,0xD4,0x14,0xFE,0x4C,0x61,0x2A,0x3C,0x38,0x0F,0xDD,0x91,0xAB,0x07,0xD7, +0x1C,0xA1,0x9C,0xC5,0xAE,0x3A,0x6A,0x26,0x9B,0x65,0xBE,0xDC,0x1F,0x09,0x7E,0x5B, +0x53,0xE9,0x31,0x20,0x5C,0x00,0x11,0x5C,0x6A,0xC5,0xCA,0x96,0x07,0x6F,0x52,0xD4, +0xFF,0xCA,0xB5,0x04,0xB8,0x75,0xE6,0xB6,0xED,0xB6,0x0C,0xE4,0xDF,0x6A,0x02,0x80, +0x9E,0x9B,0x6F,0xD2,0x35,0xA7,0x40,0x30,0x1F,0x9E,0x88,0x40,0x3B,0x9D,0x2F,0xDA, +0x5C,0x63,0xFE,0xBB,0xDA,0x9A,0x14,0x1E,0xC8,0x05,0x0D,0xC8,0xC2,0x70,0xD6,0xE1, +0xEA,0xD5,0x14,0x9A,0x76,0x97,0x0F,0x60,0xCC,0x35,0xFC,0xF9,0xE5,0x14,0xE0,0x89, +0x3E,0x3D,0x6D,0x91,0x28,0x49,0xC1,0x01,0x17,0xE7,0xC3,0x89,0x76,0x99,0xB8,0x79, +0xA7,0xA4,0xC0,0x48,0xE7,0xF0,0xD8,0x49,0x49,0xCC,0xDD,0xC5,0xC4,0x68,0x03,0x47, +0x6C,0xF7,0x72,0x83,0xDC,0xB5,0x5B,0xE9,0xCB,0x1A,0xE2,0xE9,0xA7,0x67,0xF1,0x13, +0x19,0xD5,0xBC,0xCA,0xC3,0xF7,0x66,0xDA,0xE0,0xB9,0xE5,0x44,0x1E,0x3F,0x30,0x34, +0xDD,0x82,0x43,0x38,0x33,0x32,0xF9,0x70,0xDA,0x10,0x11,0x95,0x00,0xAF,0x14,0x4D, +0xAE,0xBF,0xC1,0x37,0x98,0x7D,0xD7,0x4E,0xF0,0xAA,0x6D,0x9C,0xA2,0xF1,0xF0,0x09, +0xB3,0xA0,0x23,0x66,0xA0,0x79,0x2F,0x68,0x83,0xB6,0xCE,0xCF,0x55,0xC7,0x5C,0xC6, +0xB2,0x6A,0x5E,0xA1,0xF1,0x4E,0x18,0x8C,0x24,0x58,0x20,0xE6,0x0F,0x8A,0x2E,0x50, +0xB6,0xDD,0x2B,0x7F,0xE0,0x46,0x41,0xC1,0x35,0xCA,0x72,0xB4,0xB1,0x07,0x2A,0x94, +0xA3,0x9B,0x91,0xB0,0x06,0xBC,0x04,0x36,0xAC,0x5F,0x3E,0x19,0x28,0x12,0x2A,0x81, +0x41,0xD3,0x78,0x04,0x86,0x47,0xC5,0xF5,0x01,0x53,0x06,0x51,0xA2,0x71,0x1D,0x0F, +0xCF,0x09,0x2F,0x13,0xF6,0x0C,0xA6,0x4D,0xC9,0x5E,0xBD,0x5C,0x6B,0x52,0x7C,0x8A, +0x9F,0xFE,0x09,0x23,0x16,0x93,0x2F,0x38,0xBE,0x84,0x17,0x95,0x77,0xD0,0x98,0x35, +0xD9,0x44,0xAF,0xE3,0x4C,0xA0,0x94,0x9F,0x9C,0x58,0x23,0x5F,0x13,0xD2,0x3C,0x7B, +0xBA,0x52,0x14,0x25,0xFE,0x9C,0x64,0xB7,0x99,0x73,0x68,0x34,0x5D,0x5F,0xF9,0x15, +0x49,0x3A,0x6B,0x03,0x58,0xC0,0xCB,0xFD,0x3B,0x78,0xD5,0x54,0x39,0x24,0x67,0x12, +0x11,0x41,0xCF,0x37,0x64,0xC3,0x6E,0x97,0x69,0xA0,0x0D,0x2A,0x69,0x65,0xBA,0x4C, +0x27,0x07,0x0E,0x49,0xFC,0xD2,0x92,0x99,0x8F,0x50,0x2E,0x75,0xB4,0x86,0xB0,0x05, +0x21,0x1A,0x98,0xE8,0xBB,0x0B,0x90,0x5D,0xD5,0x5D,0x09,0xB1,0x0E,0x5A,0x62,0xA4, +0x32,0x9E,0xE3,0xD4,0xA9,0x79,0x78,0x57,0xD0,0x2E,0x2D,0x65,0x41,0xE3,0x5D,0xFB, +0x1B,0x69,0x8F,0x5A,0x3C,0xE8,0xA6,0x4D,0xB4,0x97,0xFB,0xFA,0xF9,0x16,0xD2,0x6A, +0x96,0xD4,0xC4,0x3B,0xF9,0x0E,0x61,0x69,0xD2,0x7F,0xA1,0xBC,0xBF,0x1E,0xAA,0x8F, +0x86,0x5B,0x60,0x1C,0x06,0x1F,0x95,0x2D,0xD8,0x38,0x32,0xD8,0x4D,0xA0,0x44,0xDB, +0x7E,0x17,0x36,0x3D,0x96,0x4A,0x03,0x1A,0x05,0x96,0x9A,0xFF,0xF7,0x9B,0x62,0x6C, +0xC2,0xA2,0x79,0xE6,0xCB,0xEF,0xD1,0x37,0x8C,0xE5,0x18,0x3E,0xE4,0xF6,0x66,0x3A, +0x67,0x5D,0xAA,0xAE,0x38,0x5B,0x1A,0x03,0xFC,0xBE,0x26,0x4F,0x5D,0xF6,0x77,0x0F, +0xCA,0xFE,0x27,0x3D,0xE2,0x61,0x6E,0xA2,0x06,0x91,0x33,0x6A,0xCC,0x21,0x2E,0x73, +0xEB,0x80,0x34,0xD1,0x14,0xAE,0xB6,0x72,0x2E,0xB5,0x03,0x10,0x98,0x19,0x61,0x40, +0xBE,0xC3,0x7F,0x40,0xE8,0x97,0x74,0x6D,0x7B,0x1C,0x28,0x08,0x08,0x5F,0xE6,0x11, +0x20,0x2A,0xF6,0xB5,0x99,0xF3,0x86,0xD4,0xBF,0x78,0x3B,0xDC,0xDA,0xB5,0xA0,0xE4, +0x44,0x76,0xFB,0xD9,0xDE,0xEA,0x43,0xA0,0x2B,0x1D,0x73,0x14,0xBC,0xAA,0x33,0xE9, +0x02,0xC8,0x08,0xFB,0x44,0x7A,0x7C,0xED,0x43,0x91,0xA7,0xAE,0xB3,0xD5,0x6E,0x7A, +0xCD,0x47,0x6D,0xD2,0x55,0xF3,0x70,0x5B,0xD7,0x6E,0x96,0x4A,0xB6,0x6E,0x79,0x0E, +0x25,0xFA,0xB2,0x2C,0xA7,0xCE,0x96,0x34,0x15,0x8D,0xC8,0xFF,0xCA,0xB2,0x2E,0x22, +0xDA,0xF0,0x75,0xD5,0x70,0xF3,0xB9,0x89,0x42,0x42,0x67,0x84,0xE0,0xA5,0xFB,0x87, +0x60,0x2A,0xEB,0x3D,0x4C,0x63,0x96,0x72,0xD1,0x0A,0xA3,0x27,0xE9,0x87,0xC6,0xD9, +0x32,0x7C,0x14,0x3A,0xEC,0x08,0x7A,0x10,0x10,0xA5,0x9D,0x9E,0xDB,0xDA,0x41,0x6C, +0xE8,0x8E,0x29,0xFB,0x59,0x78,0x00,0x47,0x62,0xCC,0xDF,0x97,0xF2,0x2C,0x78,0xBF, +0x68,0x65,0x29,0x88,0x12,0x73,0x46,0x7A,0x36,0x44,0xE7,0x10,0x0B,0x0D,0x36,0xAF, +0xFB,0xA2,0x54,0xFC,0x50,0x3C,0x57,0x0A,0xCE,0xC8,0x9E,0xF6,0x68,0x07,0xC7,0x7A, +0xDD,0x33,0xB2,0x71,0xE5,0x98,0x85,0x1B,0xF9,0x30,0xF6,0xA0,0x0E,0x03,0xFC,0xD9, +0x49,0xA0,0x3B,0x82,0x60,0x30,0x93,0x25,0xCA,0x65,0x6B,0x48,0x23,0xB3,0xBB,0xC8, +0x4A,0xA9,0xB9,0xCE,0x97,0xB6,0xD5,0xF6,0x41,0x56,0x83,0x6D,0x1D,0x1B,0x8D,0xD2, +0xC6,0x91,0x4F,0xDE,0xDA,0xC7,0x81,0x1A,0x4E,0xA7,0x9C,0xF9,0xE6,0xA3,0xF8,0x48, +0x57,0xD1,0xC8,0x7D,0xE1,0x28,0xAE,0x2F,0xB9,0xA2,0xDC,0xA4,0x45,0xBA,0xC5,0x85, +0xDC,0x5F,0xA0,0x11,0x6F,0x54,0xAC,0xDE,0x44,0x20,0x7E,0xBA,0x42,0x76,0xC6,0x95, +0xF3,0xD3,0x6C,0xBF,0x3A,0xF6,0x2D,0x2E,0x23,0xBC,0xEA,0x59,0x4D,0x70,0x1E,0x6E, +0x4B,0xF3,0x1A,0xFE,0x9D,0xB4,0x41,0xCB,0x66,0x66,0xD2,0xBD,0x90,0x4F,0xAD,0xC4, +0xC0,0xB6,0x6D,0x47,0x85,0x2E,0xE4,0x67,0x0B,0x01,0x63,0xEC,0xA6,0xCB,0xC8,0x68, +0x32,0x60,0x9B,0x03,0x74,0x75,0x92,0x4C,0xEA,0x04,0xF8,0x2B,0x89,0x5C,0x6C,0x3F, +0x45,0xC0,0x88,0x36,0x37,0x5C,0x82,0x2C,0x88,0x30,0xB8,0x46,0xF7,0x87,0xF7,0x5F, +0xEA,0x98,0x11,0x73,0x97,0x9B,0x2B,0xF1,0xE5,0x36,0x88,0x78,0x0B,0x27,0x52,0x2A, +0x40,0xAB,0x20,0x93,0x59,0xDE,0xB2,0x61,0x64,0x05,0xF9,0x79,0x4D,0x37,0x58,0x1F, +0x8A,0x27,0x99,0x7F,0xFA,0x5E,0x4B,0x17,0x6A,0xCE,0x28,0x95,0x2E,0xF7,0x8B,0x51, +0x1C,0xB7,0xE3,0xDC,0x0B,0xA3,0xCB,0xA9,0x83,0x66,0x5A,0xEF,0x48,0x27,0x5A,0xE8, +0xB8,0x1A,0x30,0x14,0xE5,0x3B,0x27,0x53,0x6E,0x01,0x4A,0x32,0x3C,0xC0,0xC8,0xF7, +0xEF,0x0F,0x9D,0x6E,0xBD,0x98,0x9D,0x28,0xA2,0xE3,0xA0,0x16,0x07,0xA7,0x40,0x96, +0x02,0x3C,0xDB,0x35,0x64,0x55,0x17,0x78,0xCA,0x4A,0x59,0xEA,0x4F,0x53,0x5E,0x92, +0x64,0xFF,0x2F,0xD5,0xE3,0x78,0x37,0x58,0x47,0x93,0xAA,0x36,0x9F,0x3E,0xF8,0x63, +0x82,0x3B,0xC2,0xC4,0xC6,0x52,0x04,0xB3,0x88,0xD6,0x69,0x50,0xF2,0x1B,0xA6,0x74, +0xE4,0x80,0x38,0x04,0x0B,0x21,0x53,0x52,0x0E,0xC9,0x50,0x16,0x59,0xB4,0x77,0x47, +0x66,0x30,0x16,0x5E,0x0A,0x5D,0x6D,0x37,0x8E,0x0E,0x89,0xAC,0x6E,0xA7,0x2A,0x99, +0xFE,0xFF,0x14,0x6D,0x33,0x2C,0x81,0x92,0xB1,0x26,0xA1,0x64,0xDE,0xD0,0x86,0x07, +0x95,0x8D,0x6A,0xC8,0x14,0xBF,0x79,0xF7,0x41,0x45,0x1E,0x13,0xD8,0xAF,0x70,0xF0, +0x66,0xF6,0xB6,0x1D,0x41,0x08,0xD9,0xEB,0x21,0x2D,0xBD,0xF1,0x21,0x7F,0x16,0x4B, +0xF8,0x5E,0x21,0x03,0x43,0x4C,0x54,0x52,0xA8,0x68,0xDB,0xBC,0x75,0xC8,0x63,0xC3, +0x54,0x53,0xBC,0x05,0x6E,0xE7,0xB8,0x38,0x09,0xE2,0x20,0x6B,0x1B,0x26,0xB4,0xB8, +0x6D,0xB2,0xDF,0xDE,0x78,0xF6,0xBC,0x9F,0xFC,0x6C,0x1E,0x2F,0x0D,0x7B,0x74,0x28, +0xF0,0x3B,0x49,0xFD,0x7D,0x53,0x99,0x35,0x0C,0xDF,0x92,0x25,0x67,0xD1,0x6E,0x77, +0x22,0x6F,0x98,0xB2,0xAE,0x59,0x92,0xA2,0x27,0x4A,0xF8,0x2A,0xEF,0x5A,0xC6,0xD9, +0x8E,0x69,0x81,0x0C,0x4A,0x05,0xC7,0x36,0xB6,0x81,0x82,0x1B,0x31,0x9B,0x55,0x4D, +0xBE,0xFD,0x97,0x9C,0xC1,0xF0,0xE6,0x32,0xEA,0xBE,0x13,0xBE,0xF6,0xFA,0xC9,0x71, +0xB3,0xEC,0xCA,0xF3,0x03,0x23,0x7E,0xEE,0xEE,0x5B,0x42,0x53,0x60,0xD7,0x8F,0x80, +0xAE,0x68,0xD3,0xBF,0x65,0x6E,0x94,0x9D,0x4C,0xF0,0x8F,0x8E,0x34,0xEA,0x7D,0x7E, +0xD2,0xB1,0x05,0x77,0x83,0x16,0xBB,0x52,0xFD,0x6D,0xD5,0x72,0x57,0x12,0xAA,0x39, +0x9D,0xBD,0x13,0x6E,0x5C,0xB4,0x64,0xA1,0x1D,0xAC,0x8A,0x32,0x78,0xD8,0x25,0xEB, +0x72,0xC7,0x79,0xA3,0x75,0x06,0x67,0xE6,0x57,0x92,0x80,0xA1,0x23,0xAD,0x88,0x67, +0x31,0x4C,0x83,0xF0,0xC8,0xBF,0x65,0x42,0x33,0x36,0x0B,0xD7,0xF5,0x26,0x15,0x6D, +0x0E,0x73,0x68,0xDF,0xDD,0x7F,0xA8,0x02,0x78,0x9D,0x2B,0x7D,0x79,0x92,0xDC,0x0D, +0xFC,0x38,0x90,0xD7,0x15,0xC8,0xBD,0x7B,0xD8,0x41,0x21,0x2B,0x09,0xEF,0xB1,0x03, +0x02,0x0C,0x18,0x84,0x24,0xDF,0x82,0x4D,0x2E,0x79,0x7F,0xB1,0x18,0x10,0x96,0x88, +0xA9,0x51,0x4C,0xF9,0xB4,0xBB,0x78,0x7C,0xC2,0xAF,0xF5,0x0F,0xC2,0xFE,0xDC,0x3C, +0xF7,0x96,0xB3,0x41,0x31,0xA1,0xDA,0x1B,0x8D,0xB8,0x49,0x95,0x39,0xE5,0x99,0x36, +0x83,0x32,0x6F,0x62,0x81,0x36,0x86,0xAD,0x67,0x0A,0xA2,0x4E,0xA0,0xA2,0x45,0xBD, +0x00,0xDB,0x9C,0x7E,0xBB,0xFF,0x0F,0x2E,0x34,0x72,0x5D,0x44,0x94,0x8B,0xAC,0x14, +0x0C,0x8B,0x1E,0xD5,0x8E,0x35,0x38,0x0D,0xDD,0xD3,0xB2,0x45,0x12,0x64,0x50,0x75, +0x73,0xC0,0x75,0xB1,0x60,0x7A,0xBD,0x6F,0xBF,0xDC,0xE9,0x31,0x72,0x23,0x5C,0xC1, +0xD0,0x02,0x8B,0xB1,0x74,0x0C,0x06,0x2D,0x78,0xB5,0x90,0x4E,0x07,0x2F,0xF6,0xB3, +0xB5,0xCF,0xB6,0xEC,0xA0,0x6D,0xA1,0x36,0x0A,0x20,0x9E,0x88,0x4B,0x6C,0x0D,0xA4, +0x3A,0x28,0x03,0x0A,0xAE,0xA3,0xBF,0xEF,0xE1,0x7E,0x0B,0x0C,0x8A,0x18,0x5A,0xC0, +0x0B,0xC5,0xD6,0xD9,0xE6,0xB8,0xFD,0xFA,0x74,0x81,0x38,0xAD,0xAE,0x26,0xD5,0x0E, +0x12,0x02,0xCE,0x22,0x0D,0xDF,0x7D,0xC3,0xEA,0xB3,0x29,0x41,0x9B,0x54,0xF4,0x05, +0xC2,0x69,0x6D,0x39,0x68,0x92,0x57,0x35,0x16,0x79,0x89,0x98,0xD9,0xAB,0xF3,0x0D, +0x0C,0x67,0x45,0x8C,0x53,0x87,0xD8,0x1E,0x02,0xF6,0x1E,0xE0,0x85,0x20,0x4E,0xAB, +0x04,0xE6,0x39,0x41,0xD0,0x6A,0xBA,0xBB,0x78,0xA9,0xE8,0x40,0x51,0xC0,0xFD,0x6F, +0x50,0x04,0xA4,0x96,0x8F,0x05,0x5C,0x87,0x74,0xC5,0x10,0xCB,0xC8,0x15,0x75,0x2C, +0x4E,0x8A,0x1C,0x4D,0xC3,0xFB,0xC6,0x21,0xF2,0xCE,0xD0,0xBC,0x0B,0x34,0x12,0x9F, +0x1B,0xE6,0x3F,0xA4,0xC9,0xC4,0x20,0x98,0x87,0x0E,0x84,0xFA,0x40,0xB0,0x82,0x80, +0xBD,0x2F,0x38,0x8B,0xE2,0xE8,0x6C,0x52,0x6F,0x60,0x00,0x1B,0xF5,0xBD,0xA7,0x74, +0xB0,0x98,0x2E,0x99,0x06,0xD8,0xFA,0xF7,0x41,0x2F,0x90,0x78,0x94,0x42,0x6D,0x87, +0xF4,0x3D,0xE8,0x8C,0x63,0x00,0xCA,0x3F,0x25,0xF8,0xB0,0xD3,0xCD,0xFA,0x18,0xEF, +0x37,0x95,0xF4,0x03,0x81,0x57,0x6E,0xB5,0x77,0x6B,0xBA,0x59,0x02,0x49,0xB6,0x82, +0x53,0x5A,0x2A,0x7F,0x0E,0xF6,0x6D,0xF7,0x4F,0xDE,0xF3,0x2C,0x28,0x3D,0x46,0x14, +0xA7,0xF9,0xE0,0xEA,0xC5,0xEC,0xFE,0x69,0xCD,0x34,0xAC,0x01,0x07,0x18,0xDC,0xD0, +0x30,0x5B,0x31,0x1F,0x25,0xA5,0x43,0x76,0x98,0x78,0xF4,0xD4,0x36,0xAA,0xE7,0x3E, +0xD3,0xF7,0xD8,0xE7,0x73,0x04,0xBD,0x85,0xBB,0x9D,0x6A,0xE8,0x14,0x8E,0xC3,0x76, +0xD7,0xF3,0x36,0x85,0xB1,0x23,0xD4,0xC0,0x6A,0x3B,0x15,0x01,0x76,0xEE,0xCF,0x03, +0x8A,0x66,0x22,0x45,0xF2,0x5D,0xDE,0x2F,0x1F,0xC8,0x24,0x1F,0x33,0x41,0x21,0x07, +0x1D,0x8F,0x11,0x4E,0x32,0xB3,0x01,0x3A,0xF2,0xE4,0x66,0x4A,0x7D,0xE4,0x03,0x68, +0x50,0x4D,0xFF,0x10,0xC7,0x50,0x7D,0x31,0xDE,0xDA,0x7E,0x8C,0xF0,0x18,0xE5,0x41, +0xB5,0x69,0xFA,0xB8,0x20,0x5F,0x5B,0xDC,0xCD,0x80,0xFD,0x93,0xEB,0x7C,0x32,0xC7, +0xF0,0x52,0xF1,0xCB,0xA5,0x52,0x62,0xF4,0x5C,0x49,0x5B,0x09,0x85,0x49,0x04,0x76, +0x80,0x1C,0xA9,0x80,0xE4,0xCF,0xF4,0x4D,0x66,0x27,0x57,0x4B,0xF2,0x61,0x11,0x0F, +0x1D,0xB1,0x96,0xE0,0x27,0x1B,0x26,0x25,0x1A,0xCE,0x7F,0x85,0xDF,0x9C,0x40,0xD5, +0x26,0x9E,0x29,0x4B,0x72,0x5D,0x7F,0xFB,0xC9,0x6E,0x08,0x03,0x85,0x9C,0xA2,0x32, +0xE0,0xD6,0x51,0xF0,0x58,0x6F,0xF4,0x03,0xF4,0x9F,0xBF,0x0A,0x5B,0x1B,0x6A,0x63, +0x4D,0xC7,0xDF,0x4B,0x28,0x59,0xD7,0x83,0xE5,0x87,0xD6,0xF7,0x83,0xD6,0x78,0x3A, +0xA9,0x9A,0xAC,0xFC,0xEA,0xA4,0xFE,0xCF,0x82,0xE1,0x3B,0x79,0x69,0xF1,0x8C,0x31, +0x25,0x90,0x7D,0x78,0xD4,0x30,0xD1,0x02,0x93,0x27,0x25,0x89,0xC6,0x5D,0x9E,0x5E, +0x86,0xE7,0x11,0x5C,0x72,0xCD,0xA6,0xC2,0x4E,0x7D,0x46,0xB4,0x4A,0xEA,0x86,0x80, +0x35,0x65,0x50,0x06,0xDF,0x8C,0xE0,0x00,0xCA,0x37,0xBC,0xC7,0xB3,0xEA,0x63,0x21, +0x89,0x75,0x61,0x4E,0x44,0x43,0x9C,0x7A,0xF0,0x84,0x17,0x2F,0x45,0x90,0x6A,0x05, +0x29,0xC7,0xE3,0x25,0x1B,0x57,0x67,0x3F,0x65,0x0E,0x9E,0x14,0x86,0x18,0x43,0x1C, +0x02,0x5E,0x15,0x01,0x12,0x13,0xD0,0x98,0x1B,0x50,0xEF,0xC6,0x0D,0x66,0x74,0x0A, +0x7B,0x56,0xEB,0x51,0x7D,0xB8,0x67,0x52,0x80,0x6B,0xC5,0x30,0xCA,0xEB,0xE6,0x2C, +0xEE,0x17,0x98,0x69,0xFC,0xFC,0x36,0xC7,0xAD,0x7D,0xE1,0x70,0x79,0xDD,0xCD,0xEE, +0x10,0x6E,0xAA,0x8C,0x4F,0x2B,0x87,0xF2,0x8B,0x37,0xAA,0x80,0x4D,0x3E,0x85,0xBC, +0x88,0xC5,0x1B,0xB6,0xCE,0xDA,0xF4,0x93,0xF0,0x4D,0x9C,0xA2,0xF0,0x2F,0x4E,0x1C, +0x87,0xB4,0x25,0x2F,0xCC,0xA5,0x3C,0xDE,0x81,0x98,0xAD,0xFA,0x63,0x3C,0xE5,0xBD, +0x65,0xA1,0x3D,0xB9,0xA9,0x1F,0xA8,0x72,0xC7,0x7D,0x3E,0x74,0xB7,0xC5,0x36,0x1E, +0x59,0x0E,0x3D,0xDC,0xF2,0x46,0x1D,0x94,0x2C,0x48,0x7A,0x8B,0xD3,0x3F,0x7C,0x74, +0x71,0x15,0x1B,0xC7,0xA1,0x0B,0xBB,0x25,0x8F,0xB2,0xAB,0x46,0x87,0x96,0x0E,0xFB, +0x9D,0xD0,0x98,0xE8,0x77,0x9B,0x89,0x11,0x29,0x9F,0x67,0xD4,0xFD,0xC8,0x18,0x04, +0x63,0x10,0x84,0xB2,0x2C,0x79,0x92,0x2A,0xAE,0x6D,0xF5,0xDE,0x0F,0x7F,0xAA,0xDF, +0x80,0x42,0xB4,0x3C,0x64,0x90,0xAD,0x6F,0xCC,0x6C,0xDA,0xCF,0x46,0xB2,0x2C,0x1C, +0x41,0xBE,0xDA,0xC8,0x56,0xAC,0x1F,0xBB,0xD7,0xE9,0x58,0xB5,0x9E,0xDD,0x3D,0xF8, +0xB2,0x63,0xD1,0xF0,0x16,0x00,0xD1,0x0E,0x5D,0xBB,0xF4,0x7C,0x62,0x97,0x15,0xC6, +0xE1,0x93,0xE0,0x8F,0xF9,0xED,0x72,0xF2,0x35,0x6F,0x20,0x78,0x72,0xC6,0x53,0xCE, +0xE0,0x88,0x41,0xB0,0x08,0xE2,0x3B,0xDC,0x3E,0x07,0x6F,0xE3,0x20,0x21,0x3F,0xD0, +0x04,0x50,0xD6,0x29,0xC9,0xF6,0x24,0xEB,0xD6,0x90,0xD8,0xC5,0xE0,0x6C,0x2B,0x4C, +0x06,0x8D,0xFB,0xC6,0xED,0x8B,0x89,0xEB,0xAA,0xB8,0xAE,0x46,0xEF,0xF8,0x01,0xD8, +0xDE,0x46,0xE9,0x7F,0x44,0x0D,0xDB,0x4A,0x4D,0x8F,0x88,0x66,0xFC,0x91,0x15,0x2B, +0xCA,0x0A,0x40,0x94,0xB8,0x5A,0x81,0x0D,0x2B,0x9C,0x40,0x29,0x0C,0xF1,0xF9,0xD2, +0x4A,0xC9,0x5C,0x89,0xAF,0xA3,0xE2,0x62,0xF3,0xEB,0xBC,0x36,0x52,0x6D,0x63,0x55, +0xBE,0x80,0x6E,0xCC,0x3D,0xE9,0x77,0xEB,0x3E,0x44,0xDA,0xFC,0x9E,0x6A,0x84,0x1D, +0x04,0x84,0xD9,0x5E,0x06,0x20,0x86,0xF0,0x7C,0x87,0x97,0xF2,0x12,0x2B,0xEE,0x2A, +0x67,0x0C,0xBE,0x3F,0xB3,0x48,0xC5,0xD1,0xE8,0x3A,0xBA,0x16,0x6A,0x1F,0xB4,0x66, +0xF2,0x68,0x53,0xC0,0xAA,0xBF,0xBC,0x2D,0x53,0x52,0x06,0xC2,0x0E,0xF6,0x3B,0x66, +0xB9,0xDF,0xB1,0x0A,0xDC,0x67,0xA9,0x76,0xEB,0x11,0xB7,0xB7,0xAC,0xAF,0x37,0x8E, +0x5F,0x3B,0x80,0x5E,0x97,0x58,0x0C,0xC2,0x40,0x9D,0xE5,0x2C,0x99,0xDD,0xD2,0x06, +0x65,0x8D,0x81,0xE6,0x16,0x1C,0xBA,0xD1,0xFE,0xBF,0x12,0x29,0x80,0x00,0x5D,0x82, +0x47,0x1A,0x37,0xAC,0xF8,0x3C,0x69,0x4B,0xD2,0x60,0x4A,0x36,0x69,0xA1,0x62,0x35, +0x96,0xC3,0x68,0x0E,0x26,0x82,0x25,0xE3,0xB0,0x8B,0x90,0xE2,0x6A,0x5C,0x5C,0x24, +0xBA,0x6A,0xAB,0x2C,0xF4,0x27,0xDD,0x7E,0xCF,0x51,0x22,0xE4,0x5C,0xB0,0xBC,0xFD, +0x42,0x53,0xA1,0xBB,0xB7,0xE4,0x19,0x39,0x1A,0x76,0xF8,0x63,0x0E,0xAE,0x58,0xCD, +0x46,0x4A,0xD2,0xCB,0x86,0x29,0xC7,0x59,0x1B,0xA1,0x74,0x3B,0xF5,0x24,0x5B,0xBF, +0x01,0x39,0x42,0x9A,0x26,0x39,0xB0,0x12,0x97,0x62,0x73,0xEE,0x2B,0xB7,0x1A,0xA1, +0x97,0xA4,0x05,0x80,0x12,0xD3,0xB9,0x48,0xAF,0x78,0x72,0x17,0x44,0x8B,0x4B,0x89, +0x8C,0x05,0x66,0x50,0x5D,0x9F,0x6A,0x04,0x0E,0x84,0x14,0x65,0xA1,0x9F,0xFA,0x47, +0xE4,0x91,0xCC,0xC6,0xBA,0x7F,0xF8,0xF9,0x26,0x6C,0x0E,0xAF,0x3B,0x7B,0x4E,0x10, +0x1A,0x42,0xFD,0xF5,0xE8,0x00,0xEE,0xF3,0x15,0xE5,0x52,0x9B,0xCC,0x15,0x5F,0x4D, +0xDB,0x17,0x63,0xED,0x09,0x9F,0x27,0xCC,0xB4,0x1E,0xF0,0x8B,0x77,0x56,0xA2,0x86, +0x80,0xC8,0xDF,0x43,0x61,0x8E,0xD8,0x3F,0xAC,0x93,0xAF,0xD8,0x79,0xEB,0xB8,0xCC, +0x73,0xF0,0x7D,0x5A,0x92,0x3E,0xAE,0xF3,0x23,0x3C,0x06,0xFB,0x61,0xC8,0x71,0x6C, +0x2E,0xD0,0xB6,0xBB,0x73,0xDC,0x20,0x48,0xEC,0x77,0xDD,0xDA,0x77,0x7C,0x89,0x4C, +0x55,0xD5,0x61,0x09,0x49,0x51,0x65,0x89,0xC6,0x79,0xBC,0xF8,0xD4,0x74,0xC3,0x7D, +0xE9,0x2D,0x03,0x85,0x9B,0xA5,0x23,0xCA,0x81,0x45,0x43,0x63,0x89,0x01,0x99,0x4D, +0x92,0x19,0xE1,0xDA,0xF0,0x9D,0xA3,0x8A,0x4B,0x30,0xD8,0x69,0xA1,0x69,0x6C,0xF8, +0x46,0xAD,0xF2,0x5B,0xEF,0x26,0x4F,0x3B,0x5D,0xEB,0xB6,0x7E,0xAF,0x33,0x53,0x74, +0xB9,0x80,0x3A,0xC0,0xFA,0x17,0x1B,0x6E,0x62,0xDA,0x0C,0x4D,0x71,0x91,0x5F,0x0E, +0x12,0xDF,0x85,0x2F,0x9F,0xCD,0x29,0x61,0x63,0xD3,0xFD,0xFB,0xEB,0xDC,0xAD,0x96, +0xDA,0x5C,0x8C,0x36,0xB3,0x83,0xEA,0xE8,0x43,0xB2,0x9E,0x21,0x30,0x55,0x95,0x32, +0x12,0xEB,0x57,0xF4,0x61,0x57,0x18,0xC0,0x68,0x03,0x5B,0x81,0x04,0xE2,0x56,0x2E, +0x9E,0xE9,0xC9,0x09,0x6A,0x90,0xAC,0xB7,0xFA,0xC9,0xFE,0x2A,0x43,0x54,0x68,0x68, +0x66,0xC3,0xA7,0x16,0x80,0xF8,0xDF,0x95,0xD6,0x12,0xCA,0xDC,0xA4,0xD5,0x76,0x62, +0xCD,0x20,0x14,0xAA,0x60,0x8B,0xAA,0x36,0x39,0xBC,0xA9,0xD1,0xF6,0x69,0xEE,0x6B, +0xA1,0xBE,0xFD,0x92,0x24,0xBC,0x4D,0x2A,0x02,0x62,0x40,0x27,0x87,0xB7,0x29,0xAC, +0xA1,0xBB,0x01,0xF5,0x53,0x29,0xBF,0x17,0xE1,0xD4,0xDA,0x83,0xC2,0xFB,0x1A,0x34, +0x88,0x08,0xB0,0xF6,0x7F,0x6B,0x93,0x74,0x97,0xF7,0x4C,0xC5,0xA5,0x17,0x12,0x7B, +0x19,0x31,0x8E,0xA8,0x10,0x61,0x53,0x00,0x50,0x1C,0xD2,0x2B,0x6B,0x02,0x15,0xB8, +0xB5,0x2D,0x6D,0xAE,0xDB,0x9A,0x79,0x88,0x4A,0x85,0x96,0xEA,0x89,0x6B,0xFC,0x35, +0x14,0x36,0xC4,0xE2,0x16,0xFD,0x69,0x6E,0x80,0x75,0x63,0x34,0x5B,0x61,0x00,0x7B, +0x0A,0x10,0x45,0xFB,0x44,0x71,0x3A,0xEA,0x7F,0xA9,0xFD,0xB9,0x2D,0xAA,0x63,0x94, +0xAD,0x8A,0x03,0x97,0x97,0xF6,0x49,0x63,0xE8,0xD7,0x7B,0x92,0x80,0x53,0xA0,0xB2, +0x02,0x37,0x65,0xC7,0x52,0xA0,0xDA,0x7B,0x0F,0xA1,0x57,0x55,0x88,0xCD,0xEF,0xA5, +0xA9,0xC4,0xE2,0x37,0xC3,0x93,0xD6,0xB1,0x0A,0x89,0x7C,0x5B,0x75,0x9B,0xDC,0x3F, +0x52,0xAA,0x82,0xFC,0x90,0x92,0x23,0x05,0x63,0xD4,0x34,0xA8,0xB6,0x75,0x08,0xA9, +0x5E,0x8B,0x28,0x4A,0x21,0x4B,0x24,0x82,0x28,0x9A,0x6B,0x0B,0x0E,0xFC,0xBF,0xF9, +0xE5,0xD4,0xD8,0x28,0xD3,0xC1,0x06,0x65,0x68,0x73,0x80,0x79,0xEF,0xE9,0x6E,0x57, +0xC2,0xB0,0xBA,0x7D,0xBE,0xCF,0xCD,0x56,0xFF,0xEE,0x0A,0x85,0x2D,0x66,0xDA,0x6F, +0x6E,0x89,0x9C,0x29,0x57,0x10,0x14,0xD5,0x30,0x03,0xB6,0x20,0xE7,0x5B,0x4B,0xF2, +0x8D,0x21,0xC4,0xFD,0xF5,0xA8,0x62,0x65,0xB7,0xAB,0xEB,0x6F,0xE1,0x3D,0x2E,0xF4, +0xFC,0x2E,0x6A,0x43,0x83,0x5A,0xAC,0xDA,0xFE,0x6D,0x4B,0x39,0x5B,0x90,0x83,0xA9, +0x8B,0x1E,0xA0,0x00,0xFA,0x50,0xEF,0x90,0x1A,0x28,0x63,0x77,0x6F,0x40,0xE2,0xEA, +0xDA,0x88,0x76,0x41,0x4F,0x01,0xD1,0xCE,0x2D,0x72,0x97,0x54,0x82,0x41,0xC9,0xFE, +0xD3,0x90,0x5B,0x23,0x1B,0x72,0xAF,0x4D,0x5B,0x49,0x29,0x89,0xC1,0xBD,0xAF,0xD2, +0x9D,0x44,0xD8,0x06,0x68,0x7A,0xE1,0xBB,0x07,0xCB,0x4E,0xA0,0xDE,0x72,0x0E,0x09, +0x12,0x96,0xE0,0xB4,0x6D,0x5A,0x15,0x73,0x30,0xB2,0x0F,0xAD,0x47,0x36,0x51,0xD6, +0x10,0xD1,0xBE,0xE6,0xE5,0x4B,0x4B,0x7A,0x6C,0xEF,0x33,0x0A,0xBC,0xD9,0x5C,0x6B, +0x87,0xF2,0xA6,0x38,0xD5,0xFF,0xAB,0xDB,0x09,0xBA,0x64,0x92,0x54,0x9B,0x81,0x7F, +0x8A,0x92,0x78,0x18,0x02,0x20,0xFF,0x11,0x70,0xBC,0x64,0x81,0xF7,0xD3,0x1F,0x58, +0x39,0x60,0xEE,0x08,0xE3,0xE3,0xB3,0x07,0xA1,0x1D,0x02,0x8B,0x34,0x9E,0xA6,0x7D, +0xDE,0xF5,0xD6,0x34,0x28,0x33,0x85,0x37,0xF3,0xCE,0x3D,0x1B,0xA9,0x0A,0x15,0x1F, +0xE0,0xE5,0x28,0x72,0x3A,0x53,0x51,0x6B,0x9B,0xBC,0x47,0x02,0x70,0xF5,0xB1,0x04, +0xD3,0x4A,0x9A,0xB7,0x2A,0x6B,0x22,0x0E,0xB2,0xB8,0x82,0x9C,0xE4,0xDF,0x62,0xCE, +0xDC,0xA9,0xDE,0xA3,0x4E,0xE4,0xB1,0xF9,0xCA,0x58,0x84,0xA2,0xB6,0x46,0xED,0xF3, +0xA5,0xC2,0xDE,0x39,0xAB,0x2B,0x1A,0xB8,0xD9,0xDC,0xE3,0xBA,0xF8,0x37,0x50,0x72, +0x56,0x4D,0xF7,0xC6,0xC2,0x3F,0x21,0xCE,0xD4,0x6C,0x5E,0x4B,0xCC,0x20,0x05,0xDC, +0x96,0x54,0xDC,0xF1,0xB8,0x2E,0x49,0x90,0x68,0x7A,0x15,0xEB,0xCC,0x96,0x69,0x04, +0xC1,0x4D,0x68,0x46,0x52,0xAC,0x2C,0xFB,0xBF,0xBE,0xE9,0x47,0x73,0x7D,0xCE,0xBF, +0x8D,0xE9,0x37,0x10,0xE5,0xDE,0xE0,0x10,0x83,0x45,0x4F,0x4C,0x5E,0xF3,0x5B,0x11, +0x36,0xF1,0x94,0xF5,0xC6,0x00,0x68,0x20,0xFE,0x96,0xC0,0x24,0x03,0xD7,0xB9,0x01, +0xF6,0x8F,0x8E,0x9F,0x0C,0x90,0x4B,0xFE,0x9B,0x06,0x34,0x62,0x56,0x04,0x7A,0x4E, +0xBE,0x7A,0x7E,0xC2,0xBD,0xEA,0x76,0xA4,0x83,0x4D,0xFF,0xE2,0xD8,0x08,0xE3,0xEB, +0xF9,0xD3,0x0C,0xF3,0x5E,0x2F,0x35,0xB4,0xAF,0x9D,0x55,0xE9,0x02,0x19,0x00,0x99, +0xF3,0xFE,0xCC,0xE7,0x07,0x49,0x4D,0xCA,0x1E,0x7C,0x5A,0xE0,0x22,0x23,0x64,0xC7, +0x4E,0x51,0xDB,0x3B,0x44,0x5C,0x0A,0x0F,0xB5,0xE0,0xCB,0x82,0xB3,0xF7,0x30,0x65, +0xF2,0xB6,0x8A,0x8B,0x2C,0x17,0xA7,0xA7,0xAC,0xCE,0x48,0x22,0x1B,0xE0,0x21,0x26, +0x02,0x92,0x36,0x9F,0xAF,0x8D,0xE8,0x16,0xB6,0x99,0xDF,0xD6,0x06,0xAB,0x10,0xB0, +0x71,0x52,0xCE,0xE4,0x37,0xDC,0x06,0xEE,0xCC,0xFB,0xF6,0x80,0x03,0xBE,0x3E,0x30, +0xB9,0x30,0xE8,0x1F,0xCA,0x70,0x73,0x74,0xD8,0xF8,0x25,0x32,0x20,0x9A,0xC5,0xC5, +0x0E,0xD5,0xAC,0xC2,0x55,0x1C,0xFA,0xBB,0x82,0xF0,0xF1,0x55,0xFC,0x04,0x6B,0x86, +0x4F,0xEA,0x91,0xF8,0xFA,0xB1,0x68,0x4E,0x1F,0xD8,0x9B,0x67,0xC4,0x9A,0xEA,0x56, +0xE5,0xD5,0xFE,0x31,0x36,0xAF,0xC6,0xF3,0x3D,0x8E,0xC1,0x84,0x71,0x08,0x7C,0x91, +0xF9,0x6C,0x11,0x5C,0x7C,0x3B,0x03,0xE7,0x17,0x38,0xD9,0x57,0xF2,0x3B,0xC6,0x24, +0x88,0x09,0x54,0x3E,0x74,0xBA,0xB5,0xE3,0xFE,0x6B,0xA9,0xC0,0x08,0xED,0xE0,0x8F, +0x52,0x1C,0xC3,0xC7,0x96,0x8E,0x61,0xA0,0xE0,0x81,0x69,0xA7,0xD4,0x97,0x1E,0x7A, +0xB3,0xAF,0x12,0x59,0xB1,0xE4,0xB2,0xDF,0x10,0xC2,0x73,0xBB,0x5C,0x14,0x1A,0xA9, +0x79,0x21,0x09,0xDB,0x48,0x86,0x0C,0x68,0x58,0x9F,0xE7,0x38,0x42,0xBA,0x41,0xC9, +0x30,0x0B,0x1F,0xFE,0xDB,0x21,0x88,0x3A,0x89,0x24,0x1A,0x16,0x5B,0x72,0x8E,0x08, +0xD0,0xEC,0x98,0x7C,0x23,0x75,0x23,0x41,0x6C,0x0B,0xB4,0x47,0xBC,0xCB,0xE0,0x9B, +0x11,0x7C,0x54,0x3B,0x56,0x6B,0xD3,0x5D,0x53,0x2C,0xAD,0x59,0x09,0x26,0x56,0x76, +0xE2,0x8E,0xEF,0x0D,0x56,0x39,0x0B,0x31,0x50,0x6F,0x9B,0x08,0xBE,0x17,0x28,0x64, +0x8D,0xDF,0xC7,0x12,0x12,0x8D,0x87,0x41,0x47,0x3F,0x34,0xBC,0x37,0x57,0xD8,0x22, +0xA9,0x43,0x16,0xA1,0xA7,0xE3,0x86,0x0D,0x15,0xA2,0x91,0xB8,0xA4,0xA6,0xCD,0x66, +0x75,0x72,0xC4,0xED,0x7C,0x0D,0x6A,0x5C,0xD4,0xC3,0xE5,0x1D,0x10,0xFD,0x48,0xCE, +0x70,0x9B,0x28,0xFE,0x37,0xE3,0x91,0x84,0xEB,0xF0,0xB1,0x33,0x17,0x05,0x2A,0x88, +0x98,0xD2,0x68,0x57,0xC9,0x5C,0x56,0x57,0xA7,0xCC,0x72,0xFC,0xD2,0xE4,0x75,0x35, +0xAB,0x39,0xE4,0xDB,0x3B,0x07,0xB7,0x55,0xEC,0x55,0x04,0xEB,0x81,0x52,0xF2,0x9A, +0xD3,0x5B,0xB2,0x63,0x39,0x01,0x3C,0xA6,0xF2,0x1A,0x7D,0xFC,0x16,0x27,0xB5,0xD8, +0x9F,0xB8,0x8B,0x27,0x67,0xEB,0xC3,0x48,0xA3,0x16,0x42,0x27,0x51,0x29,0x97,0x0C, +0x2D,0x50,0x67,0x37,0xE5,0x44,0x23,0xF7,0x3D,0x79,0x04,0x93,0x72,0xE0,0xC3,0x45, +0x80,0x56,0x35,0x3E,0x1A,0xB1,0x17,0x52,0xF8,0x65,0x19,0x20,0x14,0xE8,0x08,0x45, +0x6E,0x58,0x1B,0xAE,0xA1,0x7F,0xFC,0x76,0x28,0xC5,0x57,0xF3,0x8D,0x1A,0xAC,0xC2, +0x5F,0x9D,0x2B,0x69,0x30,0x37,0x34,0x3E,0x9B,0x9F,0x86,0x6B,0x61,0xF0,0xE8,0xF0, +0x2C,0xB0,0xF5,0x6B,0x24,0x7E,0x49,0x95,0x38,0x1E,0x88,0xE1,0x5B,0xE9,0x3A,0x06, +0x4D,0x72,0xA6,0x67,0xBB,0x7E,0x24,0x9A,0x5F,0x55,0x03,0x25,0xDC,0xFD,0xD8,0x7E, +0x5D,0xC7,0xC4,0x78,0xBD,0x7A,0x1D,0xE2,0x31,0xAA,0x40,0x9E,0x06,0x0E,0x11,0xC7, +0x6F,0x60,0xBF,0xDD,0x69,0x19,0x29,0x85,0x3C,0x29,0x25,0xED,0xD3,0xB7,0x0F,0x9D, +0xFC,0x2F,0x65,0xF5,0xBE,0x9A,0xF3,0x50,0x5D,0x35,0x28,0x1C,0x3A,0x4C,0xDD,0x52, +0x77,0xB4,0xD7,0x92,0x5E,0x6C,0x4D,0xBC,0x54,0xEB,0xDA,0x86,0x1E,0x09,0x3F,0xF7, +0x57,0x90,0xD8,0x88,0x51,0xA1,0x20,0x01,0x42,0xAA,0x76,0x39,0x5F,0x3E,0xBB,0xC2, +0x15,0x72,0x50,0xD9,0xD2,0xBA,0x00,0x53,0x36,0x64,0x23,0xC2,0x8C,0x4B,0x56,0xBD, +0x8F,0x40,0x54,0x23,0xDD,0xCB,0x95,0xAF,0xFA,0x56,0x03,0x10,0x4B,0x9B,0x5C,0x40, +0x86,0x3F,0xF3,0x90,0x60,0x71,0x2F,0x26,0x32,0xE9,0x6C,0x65,0x53,0x04,0x37,0xDE, +0x05,0x2D,0x7C,0xE2,0x13,0x15,0x09,0xD7,0x56,0xD9,0xAD,0x58,0x4D,0xCD,0xBC,0x7F, +0x2D,0x6E,0x59,0x32,0xDB,0x64,0x44,0x40,0x50,0xFF,0x8F,0x40,0x8F,0x7B,0xAE,0xD4, +0x9F,0xF9,0x7D,0xFF,0x96,0xA2,0x87,0x30,0x4D,0x9A,0xDE,0x51,0xC0,0x45,0x99,0x71, +0xC3,0x49,0x6B,0x00,0x48,0x31,0x03,0x19,0x4A,0x0B,0x16,0x9B,0x89,0x85,0x0C,0x4A, +0x93,0x32,0x81,0x94,0x70,0x60,0xC5,0x59,0xE4,0x2C,0x66,0xE9,0x3B,0xC5,0x9F,0xC7, +0xB7,0x4B,0xC2,0xD9,0x5A,0x25,0xBF,0x0F,0x4A,0x5E,0xBB,0x62,0x32,0x4D,0x3C,0x05, +0xD5,0xAB,0x84,0x11,0x28,0xD1,0x6E,0x61,0xFD,0x93,0x90,0x4B,0x0C,0x33,0x78,0x08, +0xB7,0x61,0xC2,0xA8,0x5A,0x88,0x79,0xA3,0x0F,0x16,0x93,0x5A,0x46,0x1E,0xF2,0x12, +0xB4,0x48,0x01,0xA0,0x36,0x68,0xCF,0x02,0x8E,0x4D,0x27,0xF9,0xA6,0x46,0x3F,0x0D, +0xA9,0xF0,0x9E,0xE9,0x55,0x92,0x37,0xD2,0x8A,0xB1,0x79,0xE0,0x21,0x13,0x99,0xEB, +0xB6,0xB7,0x71,0x35,0xEE,0x60,0x83,0x33,0xFC,0xC5,0x01,0x8E,0x65,0xDD,0x46,0xD3, +0x33,0xBA,0x2D,0xEE,0x43,0x93,0x9A,0x67,0x09,0x5A,0x05,0x01,0xED,0x36,0xC0,0x83, +0xCF,0x36,0xE2,0xDC,0x8C,0x35,0x08,0x3D,0xC1,0xEE,0x96,0x03,0x5A,0x86,0xFC,0x19, +0xF2,0x39,0xC7,0xC0,0xFF,0xAA,0x76,0x54,0x21,0x64,0x6B,0x77,0x26,0x91,0xEC,0x0B, +0x19,0x2C,0x6D,0xD6,0x69,0x91,0x2F,0x85,0x37,0x05,0x6C,0x1A,0xD7,0xF8,0x6C,0xC6, +0xD8,0xE7,0x17,0x42,0xE7,0x9D,0xED,0xAB,0xF5,0xB6,0x94,0xD8,0x27,0x4C,0x3D,0x18, +0x99,0xAD,0x31,0x47,0x4C,0x59,0x6B,0x7D,0x9C,0x54,0xBA,0x66,0x61,0xBF,0x37,0xD2, +0x8A,0x50,0x39,0xB8,0xBE,0xDD,0x3E,0xF7,0x7E,0xB6,0xF9,0x6B,0x15,0x5F,0x3A,0x23, +0x4E,0x24,0x99,0x3A,0x5F,0x61,0xBB,0x7D,0x83,0x0B,0x3C,0xAD,0x4A,0xE7,0x79,0x13, +0xD4,0xF3,0xEA,0xBE,0xC3,0xF7,0xBE,0xCD,0xB5,0xF1,0xFD,0xD7,0xDA,0x6B,0x43,0x7F, +0x9C,0xA0,0xB8,0x79,0x4F,0xFA,0x9F,0xD1,0x76,0x08,0x3F,0x09,0x2E,0x12,0x63,0x97, +0xB5,0x42,0xEE,0xA7,0x70,0x6E,0x1F,0xC0,0xA0,0x39,0x3F,0xB7,0xBD,0x4A,0xE6,0xDC, +0x0E,0x1A,0x94,0x3E,0xB6,0x5B,0x90,0x48,0x71,0x69,0x89,0xDB,0x89,0x77,0xD2,0x00, +0x71,0x92,0xDB,0x82,0x55,0x83,0xF7,0x47,0x46,0xAB,0x77,0x93,0x91,0x01,0xD8,0xBE, +0xD5,0x02,0x5B,0x40,0x12,0xEB,0x1A,0x8B,0x8F,0xA3,0x16,0x2C,0xDB,0x61,0x0D,0xD1, +0x75,0xB4,0x8A,0x77,0x48,0x61,0x06,0x43,0x9F,0xA8,0xC7,0xB7,0xF7,0x6D,0x60,0xE2, +0xEC,0xB0,0x69,0x18,0xBE,0x57,0x4E,0x7E,0x44,0x30,0x7E,0x99,0xB3,0xD4,0xF2,0x46, +0x25,0x3A,0x0C,0xA9,0xC7,0xF9,0x6A,0x5D,0x9B,0x14,0x40,0xA6,0xA7,0xF0,0x78,0xAF, +0xCB,0xA9,0x7C,0x4E,0xC7,0x8C,0x55,0x93,0x76,0xDE,0xB9,0xAD,0x73,0xE7,0x81,0xC4, +0x24,0x75,0x10,0xE5,0x80,0xC1,0x59,0xDB,0x95,0x3E,0xAB,0xC5,0xCC,0x29,0xD8,0xA9, +0xF2,0x73,0x32,0xF4,0xAF,0x8A,0xDA,0xCC,0x63,0xB1,0x94,0x28,0x16,0x27,0x10,0x9C, +0x6B,0x8F,0x96,0xD8,0x14,0xEE,0x93,0x39,0x78,0x8E,0x17,0xB7,0x00,0x2A,0x64,0x99, +0x61,0xB2,0x9D,0xF9,0xDD,0x51,0xDF,0x5F,0xDC,0xEA,0x9F,0xD2,0xD9,0x54,0x9F,0x49, +0x46,0xF0,0xD8,0x96,0x10,0x17,0x12,0x90,0x02,0xF4,0x23,0x92,0xB6,0x8D,0x40,0xD5, +0x89,0x2B,0x89,0xD2,0x9C,0x26,0xAC,0xA3,0x96,0x35,0xE6,0x3B,0x34,0x48,0xD4,0x75, +0xC2,0xDB,0x27,0x7E,0x78,0x1E,0x68,0xEA,0x39,0x8A,0xAE,0xE0,0x72,0xF7,0x17,0x3F, +0x42,0xAA,0xD5,0x66,0xB9,0x3A,0x0B,0xB2,0x9C,0x1A,0x34,0xF9,0xAA,0xD8,0xE1,0xDE, +0x5E,0x63,0x86,0x19,0xDF,0xBF,0x70,0x53,0xF0,0x8E,0x7A,0x98,0xAD,0xAD,0x77,0x69, +0x93,0xE0,0xEE,0xE3,0xC6,0x9A,0xDB,0x1B,0x0B,0xE7,0x94,0xEC,0xAA,0x1A,0x14,0xDD, +0x5A,0x5F,0x2B,0xE9,0xDA,0xA8,0xFA,0xC7,0x55,0x38,0x82,0xA1,0xD1,0x5D,0x75,0x00, +0x2B,0xC3,0x99,0x63,0xB3,0xA9,0xC8,0x93,0x74,0xA2,0xB4,0xF9,0xFB,0xBF,0x62,0xE3, +0x89,0xEF,0xEF,0x7B,0xCB,0x03,0x10,0x8D,0x9A,0xFA,0xE5,0x98,0x0E,0x6F,0xBA,0x93, +0xBB,0xE1,0xD4,0xCA,0x26,0x03,0xDE,0x62,0xA0,0x02,0xE5,0x29,0xDB,0x7E,0xED,0xAE, +0x25,0xCA,0xDF,0x08,0xD0,0xFB,0x30,0xE5,0x45,0x82,0xD7,0xFD,0x41,0x6D,0xDA,0x10, +0xF2,0x8A,0x68,0x6D,0xD8,0x30,0x7C,0x45,0xBC,0x96,0x74,0xAD,0xA9,0x48,0xC2,0xAE, +0xF6,0xD3,0x36,0x49,0x70,0x53,0x0B,0x3B,0xFB,0x49,0xC7,0x71,0x37,0x0F,0xC5,0xA6, +0x32,0x91,0xA0,0xD1,0x96,0xE7,0xC1,0xC3,0x0E,0x4A,0x06,0x65,0x12,0xC1,0x39,0xBB, +0xFB,0x0B,0x9B,0x2C,0x4B,0x44,0xED,0x29,0xD6,0x7A,0x32,0x08,0xD1,0x16,0xF2,0xE2, +0x46,0xC7,0x85,0xBA,0x35,0xC2,0x24,0x66,0xB7,0x7F,0x2B,0x62,0x62,0xED,0xA9,0xF9, +0xD0,0x0D,0x93,0x41,0x9D,0x19,0x3D,0xD5,0x1B,0x7A,0x38,0x43,0x05,0xB9,0x2A,0xCB, +0xFC,0x4B,0xDE,0x4F,0x24,0x92,0x60,0x92,0x9F,0x10,0x94,0x2E,0xD1,0xE2,0x91,0x3B, +0x51,0xC7,0xE3,0xE4,0xF8,0x70,0xF6,0x73,0x85,0xAC,0x35,0x34,0x85,0x3F,0xE2,0x0B, +0x6E,0xC7,0x73,0x80,0x61,0x60,0x53,0xB4,0xB1,0xAC,0x2A,0xDE,0x51,0x9A,0x98,0xAD, +0xC5,0xAD,0xB6,0x2D,0x3C,0x66,0x11,0x4D,0xF1,0x89,0x6B,0xF1,0x30,0x23,0xB9,0x7D, +0xE0,0xC7,0xFF,0x08,0xAA,0xA9,0x15,0x7C,0xE7,0xB0,0xC4,0x4C,0x17,0x63,0xC6,0x24, +0x21,0xD2,0xCE,0xE1,0x78,0x84,0xBE,0x8B,0xEC,0xF3,0x7C,0x16,0x76,0x36,0x5A,0xD1, +0xD9,0x87,0x0D,0xD7,0x99,0x18,0xF1,0x8D,0x60,0xB7,0xDC,0x70,0xB6,0xF9,0x81,0x89, +0x0F,0x92,0x40,0xB4,0x58,0x42,0xFD,0x90,0xBB,0xAA,0x5D,0xC6,0x8E,0xA2,0x92,0xE7, +0x0B,0x4A,0x8E,0x15,0xC6,0xEB,0x56,0x3C,0x4C,0xF4,0x35,0x98,0xAC,0x92,0x6E,0x03, +0x4B,0xF3,0x02,0x63,0x5C,0x5B,0x88,0x28,0x2F,0x38,0xB5,0xBB,0x86,0xEC,0x5B,0xFF, +0xA6,0x0F,0xEE,0x30,0x33,0x07,0xE4,0x19,0xE7,0x8A,0x6D,0x49,0x2A,0x50,0xA9,0x77, +0xC8,0x29,0x88,0x60,0xAB,0xFE,0x4C,0x1E,0x9B,0xF1,0x04,0x15,0xD2,0x41,0x7F,0x21, +0x5E,0x00,0x6C,0xF3,0xB2,0x1A,0x19,0x70,0x3A,0x90,0xC4,0x64,0xF1,0x8D,0xC7,0x65, +0xE7,0x2E,0x38,0x90,0xAF,0x75,0xD2,0xB7,0x66,0x6F,0x90,0x0D,0x7D,0x94,0x1C,0x58, +0xFC,0x7F,0x55,0x63,0x1C,0x37,0xAA,0x81,0x3D,0xD8,0x06,0xBF,0x91,0x3C,0xF2,0xAC, +0x17,0x3C,0x15,0x67,0x57,0x84,0xAB,0x66,0x9A,0x75,0x1F,0xE3,0x75,0x03,0x75,0xDA, +0xD4,0x44,0x13,0x42,0xB8,0x9F,0x12,0x56,0x9F,0x5E,0x2D,0xC6,0xBB,0xC4,0xEA,0xFB, +0xAA,0x43,0xE7,0xB5,0xB8,0xCF,0x16,0xB6,0x0C,0x2D,0x47,0x70,0xCF,0x1E,0xA1,0x03, +0x11,0x23,0xB8,0x96,0x11,0x81,0x0B,0x30,0xA6,0xD9,0xFB,0x00,0x3D,0xA8,0x7D,0x5B, +0xE9,0x67,0x90,0xA4,0x69,0x96,0xA3,0xD1,0x0A,0x6A,0xC0,0x36,0x7D,0x2D,0x3D,0xBD, +0x73,0x83,0xEC,0x75,0xCB,0x05,0x70,0x2B,0x7E,0xCB,0xD4,0x8F,0x04,0x09,0x0B,0xD5, +0x8A,0x01,0x08,0x16,0x6D,0xBF,0x57,0x81,0x58,0x66,0xA1,0xB7,0x58,0x15,0xB4,0x58, +0x60,0x8C,0xA6,0x64,0x1D,0x09,0x76,0x60,0x7A,0x44,0xCF,0x2D,0x76,0x35,0xE1,0xD1, +0xEB,0xD4,0x30,0xDB,0x4E,0x1A,0x6B,0x1D,0xED,0xCD,0xF4,0xE9,0xCE,0xF1,0xE6,0x44, +0xEA,0x01,0xBF,0x7C,0x67,0x1D,0x67,0x07,0xE9,0xDC,0x44,0x11,0xE6,0x91,0x75,0xA5, +0xF6,0xFF,0xDC,0xA5,0x56,0xB1,0x84,0x1B,0xE9,0x02,0xAF,0xEE,0xBC,0xFF,0xC5,0x38, +0x91,0xA9,0x8D,0xB0,0x15,0xF6,0xE0,0xA0,0x19,0x86,0x1B,0xAB,0x7F,0x70,0x4B,0x4E, +0xB4,0x7A,0xC2,0x3E,0x12,0x95,0x65,0x36,0x89,0x60,0x89,0x03,0xF7,0xA2,0xE0,0x3E, +0xCC,0x7D,0x14,0x5C,0xAD,0x51,0xE6,0x0B,0xE5,0xDD,0xB2,0xB4,0xFD,0xD6,0xF3,0x84, +0xF3,0x6F,0xBD,0x5E,0xDC,0xC8,0xD5,0x81,0xB5,0xDC,0xE6,0x2F,0xE2,0xD9,0x42,0xAB, +0xFC,0xD2,0x8A,0x11,0x8C,0x42,0xBB,0x82,0xD3,0x12,0x23,0xDB,0xB9,0x03,0x44,0xAE, +0x68,0xE7,0xE0,0xB5,0x55,0x85,0x22,0x09,0x66,0xCE,0x77,0x27,0x04,0x98,0x10,0x5D, +0xCB,0x19,0x3C,0x53,0x98,0xC5,0x00,0xE4,0x9B,0xEF,0xFF,0x77,0x9D,0x43,0xC4,0xB5, +0x7F,0x22,0x25,0x2A,0xC8,0x47,0xB8,0x3B,0x9A,0xC8,0x97,0xBA,0x36,0x92,0x7B,0x3E, +0x54,0x5F,0x04,0x90,0xA4,0xCF,0x98,0x34,0xEF,0x46,0x5D,0x99,0x08,0xE1,0x41,0xE0, +0xDA,0xB9,0x68,0xBA,0xD3,0x53,0xDE,0xCD,0x42,0xCE,0x85,0xC9,0xCE,0x19,0x78,0x2D, +0x48,0xB6,0xAF,0x48,0xD2,0x1F,0x60,0x4E,0x72,0xA8,0x84,0x50,0x8F,0x73,0x8F,0x21, +0x0E,0x4C,0x43,0x63,0x53,0x09,0xEC,0xB8,0xD9,0x8F,0xDF,0x55,0x12,0x6C,0xD2,0x12, +0x9C,0xEA,0xE8,0x91,0x11,0x1C,0x14,0x68,0xF5,0x21,0x28,0x1C,0xBF,0xC3,0xC0,0xF4, +0x65,0x90,0xC7,0x9E,0xCE,0xCC,0x55,0x37,0x91,0x6E,0x03,0x99,0xBF,0x58,0xE0,0x32, +0x70,0xE8,0xED,0x96,0xA9,0x1D,0x40,0xFF,0xD3,0xA3,0xFD,0x1C,0xC2,0xC3,0x7F,0xA0, +0xF3,0x6D,0xF1,0x68,0xA0,0x92,0xE5,0xE1,0xBE,0xDA,0x7E,0xB4,0x20,0xAF,0x55,0x54, +0x92,0xCC,0xAF,0x71,0x31,0xD3,0x88,0x4D,0xB6,0x4F,0xB0,0x5F,0x79,0x82,0x10,0x30, +0xAC,0xA1,0x18,0x61,0x44,0x58,0xA7,0x24,0x48,0xEC,0x11,0x90,0x4F,0x0C,0xE9,0x43, +0x51,0xB3,0x55,0x28,0x13,0x63,0x1B,0x0C,0xAF,0xCC,0x52,0x43,0x45,0xBD,0xCA,0xB4, +0x27,0x70,0xB3,0xAF,0x8D,0x7D,0x27,0xA9,0x19,0x7D,0x9F,0xB5,0xFE,0xB0,0xEC,0x5A, +0xA6,0x2A,0x9E,0xB5,0xBD,0x2B,0xD3,0xD8,0x58,0xCC,0x09,0x14,0x5E,0x8D,0xE4,0x8C, +0xB6,0x65,0xE4,0x72,0x7D,0x27,0xCB,0xCB,0xC0,0x9E,0xAF,0xC0,0x51,0xA6,0x4B,0x49, +0xB8,0xF3,0xEA,0x59,0x86,0xE5,0xFC,0x31,0xC7,0x94,0x90,0x5D,0xF7,0x61,0xA4,0x39, +0x2B,0xF2,0xA7,0x6D,0x4C,0xBA,0x6C,0xCF,0x1D,0xD6,0xE4,0xC5,0x5D,0x73,0x5C,0x13, +0x87,0xBD,0x7E,0xD4,0x99,0x41,0x6E,0x26,0x9E,0x7B,0x05,0x0C,0x03,0xDE,0x8C,0x98, +0x94,0x28,0x12,0x2F,0x88,0xA2,0x39,0x82,0x3D,0xBF,0x85,0x51,0x4F,0x0D,0xA3,0xE7, +0xB8,0x63,0x7F,0x68,0xA7,0xF3,0xF0,0x42,0x76,0xFD,0x90,0x2F,0x90,0x7E,0x1D,0x57, +0x94,0x22,0x5B,0x89,0xFF,0xCA,0x25,0xF3,0xD8,0x48,0x14,0x86,0x07,0xFF,0x86,0x7C, +0x1A,0xCA,0x4F,0x13,0x25,0xFC,0xB5,0xA9,0xC8,0xCA,0x20,0xDF,0x42,0xFA,0x05,0x25, +0x5B,0x74,0x79,0xA4,0x25,0x20,0xD8,0x0C,0x9E,0x80,0x23,0xE4,0x6A,0x85,0x6B,0xDE, +0x25,0x80,0x6A,0xCE,0xD8,0x03,0x3B,0x97,0x2F,0xD4,0x5F,0x30,0x69,0xDA,0x6E,0x00, +0xFB,0x6B,0x7C,0x87,0x0F,0xA0,0x0A,0x5E,0x4E,0x52,0x8E,0xB0,0x88,0xF2,0xB8,0xA6, +0x33,0x48,0x8F,0x3F,0xBB,0x93,0x93,0x22,0x73,0x3B,0x84,0xB1,0x96,0x8F,0x31,0x0B, +0x09,0xC8,0xED,0x81,0x72,0x3B,0xAA,0xDC,0x9E,0x81,0xE8,0x87,0xCE,0x5E,0x9E,0xAD, +0x8A,0xFA,0xE9,0xF4,0xF4,0x08,0xBD,0xCE,0xDF,0x67,0xAF,0xD6,0xC8,0x33,0x23,0x3B, +0x4E,0xEE,0x2E,0xE5,0x9C,0x49,0x99,0x8E,0x3F,0x03,0xFF,0x82,0x30,0x34,0x00,0x41, +0xD0,0x64,0x33,0x54,0x1E,0xE7,0x85,0x55,0x4F,0xDF,0x85,0xDD,0x59,0xA7,0x3C,0x67, +0xE4,0xFE,0xA5,0x11,0x3B,0x37,0xBC,0x65,0x1D,0x0C,0xAA,0xAF,0x27,0x57,0xDB,0x3C, +0x3F,0x87,0x4B,0xC0,0xE1,0x18,0x38,0xBF,0xAB,0x9E,0xF0,0x10,0x8F,0x2B,0x1A,0xBF, +0xFF,0x92,0x59,0xF6,0x95,0x95,0xA1,0xB1,0x02,0xBB,0x70,0xF3,0x99,0x10,0x83,0xB9, +0x16,0xF2,0xB4,0x25,0xD1,0xDA,0x73,0xDC,0x69,0xC8,0xBF,0x61,0x96,0x0B,0x41,0x66, +0x7C,0xF0,0xD0,0x2D,0x69,0x4B,0x39,0x67,0x4F,0x5E,0xE2,0x16,0xA1,0xCF,0xE7,0x83, +0x77,0x65,0xF1,0xA9,0x8E,0x08,0x7D,0x79,0x0F,0xD6,0x86,0x35,0x8D,0x03,0xE0,0xEE, +0xA0,0xFA,0x2E,0x75,0x1A,0x33,0xF3,0x8B,0xB5,0x72,0x1A,0xF6,0x04,0x48,0x05,0x67, +0x75,0xFF,0x28,0x06,0x3F,0x20,0x32,0x53,0xE0,0xD3,0x88,0xD9,0xA0,0xD9,0x38,0xE4, +0x57,0xA8,0x0B,0x27,0x9A,0xE8,0x16,0xAC,0x1D,0x13,0x41,0x33,0x63,0x39,0xCF,0xB5, +0xE4,0x01,0xF5,0x71,0xAA,0x86,0xE2,0x2D,0x9A,0xE5,0xFF,0x9F,0x0E,0x40,0xC4,0xF5, +0x79,0xD7,0x0C,0x18,0xC5,0xA5,0x3E,0xE5,0xA5,0xCD,0xF8,0x14,0xAE,0x38,0x51,0x0B, +0x66,0x11,0x12,0x5F,0x06,0x5D,0x46,0x9F,0xAD,0xCA,0xFC,0x27,0x7F,0x50,0xC5,0x0F, +0x2B,0xD0,0xE3,0xF2,0x61,0xA5,0x60,0x2F,0x06,0xF4,0xA1,0x21,0x2C,0x28,0xE1,0x68, +0x52,0x82,0x68,0x38,0xD2,0x89,0x44,0xEE,0x86,0xCC,0xF5,0x78,0xDB,0x60,0xDD,0x58, +0xB8,0x6F,0xFF,0x82,0xDE,0x76,0x64,0xBA,0x4A,0x20,0x16,0xC4,0x8C,0x52,0xF2,0x22, +0x08,0xA8,0xFB,0xD9,0x1E,0x4E,0xB3,0xE3,0x8A,0x85,0xC9,0x1E,0x8A,0x93,0x50,0x5E, +0xD0,0xA4,0x2F,0xD5,0xD9,0x65,0x9F,0xF0,0x12,0x5B,0x53,0x48,0xA7,0x4D,0x30,0x30, +0x26,0x88,0xF6,0x97,0x15,0xB3,0x99,0x79,0x27,0x0D,0x4F,0xB6,0xF2,0xDB,0xA6,0x72, +0x92,0x2B,0xF6,0xC2,0xE9,0x71,0x61,0x3F,0x0B,0xE5,0x3D,0x72,0xB6,0x81,0xA4,0x78, +0xA3,0xBD,0xFE,0x68,0x77,0x82,0xE4,0x61,0x85,0xD8,0xFA,0xF3,0x3A,0x4B,0x6C,0xB2, +0x0A,0xA7,0x25,0x6C,0x13,0xA0,0x8B,0xE1,0xBB,0x55,0xA9,0x3D,0xCC,0xA9,0x48,0xA8, +0xE8,0x8B,0x5F,0xFC,0x11,0x83,0xA2,0x13,0x2B,0x93,0xAB,0xB5,0xC6,0x9F,0xB8,0x2B, +0x4B,0xB8,0x9D,0xF9,0x74,0x56,0x0F,0x13,0xE1,0x77,0x5D,0x90,0xF0,0x9B,0x95,0x38, +0x9F,0x06,0x54,0xF2,0x6E,0x8A,0x62,0xAF,0x03,0x70,0x75,0xD2,0x98,0xCF,0x1A,0x60, +0x0F,0x17,0x9C,0x3A,0x12,0x9E,0x07,0xB5,0x38,0xE2,0xFA,0x82,0xDD,0xA2,0xBC,0xF3, +0x86,0x50,0x38,0xD1,0x67,0x77,0x63,0xA4,0xD7,0xA8,0x0B,0x53,0x65,0xCA,0x75,0x23, +0xBD,0x2A,0x35,0xC5,0x88,0xA2,0x8A,0xEB,0x5F,0xFF,0xD8,0x2D,0x75,0x92,0xE5,0xD1, +0xA3,0x79,0x8D,0x68,0x44,0x34,0xA3,0x28,0x44,0x60,0x6A,0xA2,0xE2,0x3A,0x9E,0x2C, +0xDC,0x92,0x18,0x3A,0x4B,0x79,0x64,0x81,0x3A,0xD2,0x26,0x49,0x0A,0xB8,0xDB,0x84, +0x5C,0x64,0x73,0x07,0xA4,0x41,0x4E,0x25,0x90,0x74,0x0E,0x1A,0xC8,0x87,0x07,0x83, +0x7A,0xC7,0x90,0x6D,0xB9,0x69,0x78,0x8B,0x58,0x2B,0x01,0x3E,0xD7,0x29,0x34,0x0A, +0x5E,0x42,0xD1,0xA7,0x72,0x1B,0xF6,0xE3,0x30,0xBD,0x6D,0xE3,0x3C,0x00,0x04,0x89, +0xBF,0x72,0x39,0xA1,0x65,0xCF,0x57,0x34,0x8D,0x80,0x05,0x7C,0x1F,0x19,0xEF,0x7A, +0xDE,0x77,0xFC,0x24,0x60,0x46,0x76,0x5E,0x16,0x10,0xB0,0x69,0x1E,0x23,0xC1,0xF0, +0xED,0xAE,0x36,0x46,0xBE,0x07,0x1E,0xAC,0x73,0x8D,0x15,0xFE,0x72,0x84,0x36,0xC5, +0xA5,0xE8,0xD1,0xD2,0x3B,0x99,0xDD,0x6A,0x6D,0x8F,0xFA,0x42,0x77,0xA1,0x85,0xE3, +0xBA,0x4F,0x11,0x00,0xF3,0x0F,0xFC,0x10,0x9F,0x78,0x4A,0xB8,0x18,0xF4,0xCA,0x97, +0xE4,0x74,0x6A,0x88,0xEB,0xD3,0x36,0x59,0x5B,0xDD,0xC4,0x80,0xB5,0xA1,0xCF,0x8E, +0x5A,0xB6,0xD1,0xE6,0x75,0xF6,0x65,0x17,0x91,0x72,0x27,0xC1,0x55,0xD8,0xE7,0x87, +0x37,0xD3,0x6F,0x36,0xAC,0xD7,0x26,0x6E,0xBD,0x05,0xFE,0x83,0x48,0x7F,0x90,0x26, +0x17,0x53,0xF9,0xB8,0x97,0x96,0x63,0xD1,0xD7,0xB3,0x1C,0xD4,0x37,0x69,0x8C,0x50, +0x4E,0x94,0x40,0x75,0xB4,0x57,0x20,0xC0,0x08,0x6C,0x5C,0xCC,0x2B,0xDB,0x78,0x00, +0x84,0x3C,0xCA,0xF9,0xD4,0x28,0x22,0x9A,0x8B,0xF4,0xCA,0xA6,0x96,0x39,0xDE,0x64, +0x8F,0x98,0x3A,0x5F,0xB5,0x2A,0x27,0x48,0x38,0xEC,0x90,0x59,0x3B,0x2F,0x5C,0xCC, +0x41,0xC4,0x03,0xC9,0x9D,0xA9,0xDF,0x2A,0x2F,0xD5,0x59,0x54,0x06,0x2F,0xBB,0x7B, +0xA4,0x25,0x97,0x2C,0x64,0x7B,0x6D,0x7C,0x52,0xC4,0x54,0xC1,0x33,0x71,0x74,0x43, +0x59,0x89,0x22,0xA0,0xE6,0xE7,0x23,0xF0,0x75,0x77,0xDD,0x87,0xA2,0x60,0xBF,0x55, +0x72,0x75,0x02,0x76,0x5F,0x26,0xA6,0x27,0x2C,0x4E,0xF7,0x68,0x3D,0x98,0x80,0x7F, +0x7C,0x54,0x10,0x3E,0x5F,0xB0,0xEF,0x1A,0xAF,0xBC,0xE8,0xF2,0x1F,0xD4,0x4B,0x9A, +0x88,0x03,0x33,0x88,0x80,0xBB,0x2E,0x4D,0xFB,0x37,0xD3,0xFC,0xB0,0x31,0xBF,0x8F, +0x02,0xDC,0x90,0x33,0x79,0x19,0xAB,0xDA,0x8F,0x0D,0x20,0x28,0xEB,0x21,0xD1,0x4E, +0xFA,0xEB,0xF0,0x59,0x3E,0x94,0x93,0x2D,0x5B,0x40,0x19,0xC3,0xDB,0xAD,0x5B,0xDD, +0x15,0x4D,0xEC,0x17,0xE3,0x55,0x1C,0x8A,0xA7,0xE4,0x10,0x50,0xCB,0xC6,0x24,0xD1, +0xF9,0x8D,0x07,0x73,0x49,0x49,0x30,0xC5,0x41,0x4A,0x0A,0x77,0xD5,0x82,0x43,0x10, +0x04,0x39,0xA4,0x0F,0xEE,0x93,0xD8,0x21,0x0D,0x62,0x62,0x0C,0x2D,0x22,0x6E,0x9C, +0xAC,0x16,0x63,0x3B,0x88,0xAB,0x7C,0xCA,0x3E,0xB6,0x36,0x52,0xB4,0xA7,0x07,0x37, +0x01,0x57,0xFC,0x04,0x73,0x62,0xFB,0xA5,0xEB,0xD9,0xB3,0x16,0x94,0x45,0xBC,0xA0, +0xA3,0x7B,0xD0,0xFF,0xD9,0xAD,0xB8,0x61,0xB2,0x34,0xAD,0x00,0xB3,0x09,0x6C,0xD8, +0x71,0xBC,0x48,0x29,0x78,0x23,0x74,0x27,0x66,0x01,0x0E,0x9D,0x3B,0xCE,0xCE,0x2A, +0x44,0xDC,0x2D,0x39,0x98,0xDC,0x58,0xCF,0xB4,0xB8,0x7A,0xD6,0xF3,0xB3,0xD6,0xA4, +0xA9,0xFD,0x69,0x9C,0x91,0x26,0x58,0xC1,0x06,0xD5,0x74,0xB1,0xCB,0x9B,0x7A,0xB9, +0x9F,0x81,0x26,0x9F,0x4A,0xD6,0xA7,0x4B,0x67,0xD4,0xBD,0xEA,0x96,0xF0,0x75,0x70, +0x38,0x2A,0x3A,0xAB,0xE6,0x2A,0xB7,0x4D,0xAD,0xB8,0x10,0xBF,0xC9,0x48,0x7C,0xE8, +0x93,0xDC,0x38,0x11,0x3F,0x7C,0xAF,0xCF,0x04,0x13,0xCF,0xBE,0x21,0xF2,0x83,0xC9, +0xF3,0x34,0x7E,0x3C,0xD5,0x5D,0x6E,0xF7,0x13,0xBB,0x0A,0x79,0x38,0x90,0xEE,0x05, +0x61,0x40,0x6A,0x27,0xA9,0xBA,0xD1,0x1A,0x55,0x26,0x99,0x8C,0x76,0x9E,0xAB,0xDE, +0x4D,0xC8,0xCC,0x16,0xD0,0x32,0x81,0x53,0x02,0x81,0x00,0x96,0x33,0x17,0x51,0x9E, +0x78,0xD8,0x2D,0x42,0x88,0x21,0x85,0xDB,0xF7,0x08,0xA3,0x53,0x25,0x76,0x26,0xE7, +0x1E,0xF6,0x16,0x8C,0x4B,0xD4,0xDC,0x9F,0x33,0x18,0x5B,0x71,0x4F,0x47,0xB9,0xB1, +0xAF,0xC4,0xD5,0xE2,0x52,0x71,0xC7,0x86,0x3F,0xA4,0x03,0x3D,0x5D,0x55,0x5A,0x2A, +0x0B,0xA8,0x55,0xA5,0x23,0xEC,0xBD,0xC7,0x87,0xC6,0x26,0xF5,0x1E,0xB2,0x58,0x9A, +0x49,0x73,0x11,0xE8,0xF3,0x9B,0x7F,0x31,0x69,0x8E,0x08,0xFC,0x32,0xCF,0x9E,0x95, +0xF6,0x5D,0x11,0x2A,0x86,0xDB,0x23,0xAD,0x02,0xAD,0x24,0xBF,0xDC,0xFC,0x70,0x0C, +0x05,0x4E,0x17,0x82,0xDF,0x33,0xB2,0x61,0x70,0x1D,0x88,0x1C,0x4B,0xD7,0x33,0xF9, +0xD4,0x15,0xC5,0x24,0x58,0xCE,0x90,0x0F,0xD8,0x72,0xFF,0x72,0x01,0x92,0xE6,0x65, +0xD2,0xC3,0x99,0xAF,0x1D,0x9B,0x9C,0x66,0x93,0x9A,0xDB,0x76,0x68,0xE1,0xBC,0x37, +0x55,0x7E,0x58,0x41,0xA1,0x7C,0x2D,0x5E,0x13,0x72,0x18,0xC5,0xC9,0x1E,0xFC,0xD4, +0xB5,0x65,0xE1,0x20,0x73,0xB3,0x04,0xC8,0x32,0xE7,0xB5,0x27,0xB9,0xC5,0x7F,0x16, +0x1C,0x5F,0xF4,0xCE,0x4C,0x9B,0x43,0xC2,0xF2,0x37,0xE3,0xF5,0x04,0x73,0xB4,0xA3, +0x30,0xE9,0xE4,0xF5,0xF3,0x36,0x37,0x20,0x99,0xA9,0xEB,0xFB,0x06,0x48,0x40,0x0F, +0x51,0xD4,0x78,0x4E,0xCA,0x4F,0x13,0xF3,0x92,0x51,0x7E,0xEF,0xBD,0x0C,0x29,0x7A, +0x58,0x36,0x71,0xC3,0xC7,0xA8,0x08,0x6A,0x54,0x6D,0x6D,0xCC,0xE6,0x74,0xDC,0x79, +0x58,0xB3,0xDD,0x9E,0xF5,0xCE,0x9D,0x7F,0xE0,0x27,0x89,0x00,0x8F,0x3D,0x82,0xE8, +0xDD,0x80,0x11,0x83,0xA5,0xD4,0x4B,0x5D,0xBB,0xAC,0x66,0x87,0xD0,0x9B,0x05,0x81, +0x71,0x35,0xA8,0x9F,0xC6,0xF8,0xBD,0x56,0x96,0x84,0xBD,0xF2,0xBB,0xC3,0x50,0xF0, +0xB1,0xEC,0xE0,0x67,0xF5,0xEC,0x1F,0x35,0x93,0xE1,0x6B,0xD3,0x11,0xC1,0xC3,0x12, +0x0B,0xB1,0x51,0x3B,0xA6,0xEF,0x5C,0xEC,0x5E,0x24,0xA4,0xD0,0x49,0x41,0x9B,0xA3, +0x2D,0x38,0xAC,0xCB,0x7C,0xEB,0xF2,0x60,0xA2,0xDB,0xD4,0xC5,0xCD,0xA7,0xC5,0xDD, +0xB1,0x16,0x1A,0xEE,0x9B,0xC3,0x3B,0xC1,0x4C,0xA6,0xF0,0x90,0x4F,0xC0,0xF1,0xE2, +0xDE,0x2A,0x33,0x45,0x1A,0x91,0x76,0x42,0xA2,0xCD,0xFD,0xB1,0xFC,0x1A,0x5C,0xCE, +0x58,0x54,0xD8,0xB6,0x75,0x4E,0x1E,0x94,0x04,0x2F,0x75,0xBE,0xB8,0xAE,0xD7,0xEF, +0x9F,0x55,0xBB,0x42,0x63,0xA8,0x0B,0xCB,0xD6,0x05,0x71,0xAD,0xE8,0x63,0x77,0xFE, +0x93,0x1C,0x05,0xEB,0x02,0xCA,0xCB,0xFC,0x5C,0xB2,0x3E,0x80,0x15,0x2C,0xEA,0x82, +0x91,0xD2,0x6E,0x5B,0x8B,0x3B,0x80,0x0A,0x4A,0x5F,0x26,0xB9,0x8D,0x44,0x59,0xE4, +0x43,0xC5,0xC2,0x50,0xF1,0xE0,0x7A,0x20,0x5D,0x28,0xBA,0xB0,0x99,0xC5,0x6B,0x3C, +0x51,0x7E,0x90,0xEA,0x31,0x14,0x8D,0x2E,0x2F,0xD0,0x5B,0xDA,0x6B,0xF7,0xB2,0xBD, +0x26,0x76,0x59,0xAD,0xC1,0x91,0x12,0xAE,0xF3,0xC5,0xC3,0xF9,0x31,0x76,0xD5,0x67, +0x62,0x7E,0x77,0xB0,0xFC,0xD0,0x0F,0xD1,0x0C,0xCC,0x7B,0x11,0xD7,0xBA,0x31,0x35, +0xC3,0xAE,0x3E,0x70,0x27,0x66,0xEF,0x87,0x8B,0xFE,0xA6,0x37,0x97,0x23,0xBB,0x92, +0x20,0x37,0x90,0xE0,0x0B,0xE1,0x5E,0x84,0xD6,0x72,0xCB,0x76,0x08,0x13,0x36,0xC1, +0xD7,0x4D,0x89,0x34,0x3F,0x84,0xDF,0xCB,0xA2,0xFE,0x4C,0xF5,0x61,0xE4,0x9F,0xEB, +0x2F,0xC5,0xAC,0x21,0x66,0x2D,0x0C,0x36,0x4B,0xF7,0x4D,0xEE,0xAD,0x29,0x5B,0xDA, +0x0D,0xBA,0xA5,0xAC,0x27,0xE5,0x2C,0x28,0x15,0x54,0xEC,0x7D,0xB0,0x87,0xCC,0x37, +0x10,0xA5,0x3E,0x20,0x4E,0x40,0x7E,0x94,0x14,0x82,0xF2,0x77,0xB7,0xA6,0xE5,0x4A, +0x85,0x03,0x7E,0x55,0x01,0xB0,0xD1,0x49,0xAC,0xA3,0xF2,0xA8,0xCB,0xEE,0x33,0x18, +0xCE,0x6E,0xC2,0xDB,0xA6,0xEA,0x73,0xB2,0x66,0xCA,0xE9,0x48,0x74,0x8B,0x72,0x12, +0xDD,0x2E,0xDB,0x41,0x76,0xA0,0xD4,0xF9,0x17,0x52,0xA8,0x9A,0xE1,0xC8,0xFD,0x15, +0x6A,0x27,0xF2,0x05,0x71,0x45,0x17,0x59,0x7B,0x23,0x00,0xE3,0x72,0xF4,0xEA,0x5A, +0x01,0xE8,0x4C,0xDD,0xA3,0x95,0xC0,0x07,0xF7,0xC3,0xE5,0x78,0x35,0x7F,0x60,0xF9, +0xD7,0xEC,0xA1,0x5A,0xC4,0xB2,0x9A,0x4D,0x5A,0x5A,0x10,0x53,0x58,0x26,0x69,0x26, +0x78,0x90,0x1C,0xF8,0x9C,0x44,0xA6,0xAB,0x0C,0x05,0x07,0x6E,0x47,0x44,0x6C,0x93, +0x41,0x53,0xA7,0x6C,0x8C,0xD3,0x28,0x89,0x1B,0x48,0x1C,0xF4,0x8C,0x70,0xCF,0x01, +0xD2,0xDF,0xBC,0x73,0x4D,0xCD,0xD7,0x21,0xD6,0xAD,0xB2,0x31,0x30,0x42,0xFC,0x29, +0x33,0x41,0x29,0xE1,0x9E,0xC3,0x40,0x04,0x81,0xF9,0x3C,0x22,0x6C,0xA5,0xDE,0xFF, +0xBA,0x72,0xB1,0x02,0x17,0xE3,0x7D,0x22,0xC7,0xF8,0x48,0x26,0x02,0x56,0x54,0x0F, +0x39,0x48,0xE1,0xF7,0xFB,0x23,0x04,0x98,0xAB,0xBA,0xE2,0x46,0xC3,0xF4,0x94,0x19, +0x96,0x95,0x7A,0x93,0x5A,0x76,0x49,0x99,0x39,0x33,0x1F,0x98,0x30,0xAA,0x59,0xE8, +0x78,0xA8,0x0B,0x98,0x7C,0x21,0x1D,0x64,0xA5,0xAE,0x5F,0x38,0xD6,0x1D,0x0C,0xC6, +0x62,0x15,0xAF,0xFB,0xFF,0x47,0xAA,0x5D,0x55,0xBE,0x19,0xB2,0xF9,0x9F,0xB0,0xD0, +0x90,0xC8,0xE3,0x26,0xEF,0x60,0x98,0x58,0x0E,0x91,0x07,0xAC,0x83,0xDE,0x0D,0x00, +0x91,0x55,0x79,0x01,0x6C,0x87,0x7F,0x4A,0x14,0x80,0x3A,0x94,0xBE,0x2C,0xB5,0x1D, +0xDC,0xEA,0x89,0x82,0xCC,0x53,0x2F,0xFF,0x00,0x8F,0x70,0xAE,0x89,0xD7,0x94,0x79, +0x07,0xDB,0xFB,0xBD,0x32,0x45,0xF9,0x0C,0x73,0x9C,0xB7,0x1B,0xCB,0x00,0x70,0xE4, +0x70,0xF8,0x43,0x2A,0x91,0x14,0x67,0x47,0xCF,0xBE,0x44,0xA7,0xB7,0xF5,0xC3,0x31, +0xD6,0x32,0x2B,0x7C,0xB0,0xFB,0x2E,0xA3,0xFE,0x65,0xDB,0xF9,0xD7,0xAC,0x8F,0xC8, +0x9E,0xDC,0x82,0x1B,0x9D,0x7F,0x1B,0xC2,0x6B,0x27,0x9C,0x5C,0x28,0xDF,0x2B,0x93, +0x0F,0x3A,0xA1,0x7D,0x2B,0x28,0x48,0x17,0x7F,0x35,0x2D,0x76,0x10,0xDB,0xD9,0xE9, +0x51,0x1F,0xD7,0x1A,0x6A,0xCC,0x8B,0xD0,0x50,0x66,0x0E,0xDD,0xE7,0x27,0x0D,0xB3, +0x0A,0x7E,0x90,0xD4,0xD8,0xB7,0x07,0xAE,0xC9,0xE9,0xCA,0x45,0x80,0x4B,0x1B,0xB3, +0x12,0xBA,0xB6,0xDA,0xE0,0x55,0xCC,0x7E,0x7A,0x4E,0x8A,0x16,0xBE,0xC8,0xC7,0x2D, +0x3B,0xF8,0xE5,0x1B,0xF1,0xF7,0x7A,0xA9,0x93,0x72,0x73,0x7C,0x68,0x65,0x85,0x5E, +0x30,0xE5,0xB1,0xE8,0x36,0xD0,0xC8,0xE9,0xB3,0x6D,0x20,0x0A,0xB8,0xD4,0xC0,0x87, +0x36,0xD4,0x39,0xFE,0x5E,0xB2,0x1D,0x2F,0x78,0x3B,0x46,0x0E,0x21,0xBC,0x48,0xAD, +0x7C,0x7F,0x69,0xA3,0xA0,0x57,0xAF,0x57,0x33,0x3A,0xD6,0x9C,0xE2,0xAB,0x6F,0x51, +0x00,0xCC,0x1E,0x13,0x4C,0xEB,0xEF,0xD9,0x72,0x43,0x18,0x1E,0xE6,0x43,0x79,0x13, +0x0C,0xE8,0xA4,0x05,0xAB,0xB1,0x1A,0xFC,0x0B,0xA1,0xFC,0x8D,0x8A,0xC7,0x88,0xC6, +0x5F,0x6E,0x9E,0xEB,0x76,0x94,0x03,0xFD,0x86,0x30,0xA1,0x5A,0xB6,0x7B,0x55,0xDB, +0x54,0xDD,0xF8,0x24,0xC7,0x8E,0xDC,0xDA,0x31,0x75,0x0B,0x98,0x3C,0xF0,0x5A,0x9A, +0x01,0x17,0xA3,0x02,0xED,0x78,0xF9,0x9B,0x63,0x5A,0x57,0x03,0xE7,0xA4,0x1D,0x96, +0x61,0x50,0xB4,0xCE,0x34,0x40,0x87,0xC0,0x19,0x32,0x5D,0x5C,0xAF,0x32,0xD0,0x3D, +0xED,0x37,0x19,0x98,0x9B,0x31,0xDD,0xAA,0x86,0x3A,0x5D,0x3B,0x07,0xF1,0x20,0x91, +0x0D,0x24,0x1D,0x0F,0x7A,0xC6,0x9A,0x6F,0x12,0xE9,0x0B,0xCF,0xAA,0x92,0xDA,0x44, +0x21,0x5E,0x50,0xF5,0xC1,0xC4,0x47,0x37,0x80,0xFC,0x04,0xBD,0xD5,0x21,0x98,0x3E, +0x2E,0x9B,0xC7,0x39,0x4B,0x51,0xDF,0x10,0x07,0x81,0x2F,0x39,0x31,0xAF,0xE2,0x49, +0x60,0x29,0xD6,0x91,0xF4,0xB8,0x95,0x3B,0x63,0xB4,0x5C,0x0B,0x72,0x9F,0x4E,0xA3, +0x92,0x25,0xA8,0x7D,0x63,0xEF,0xD7,0x20,0xAA,0x5F,0xA6,0x3D,0x5E,0x88,0xB2,0x26, +0x09,0x70,0x94,0x2F,0xA8,0xB5,0x27,0x9C,0xBA,0x8C,0xC7,0xB4,0x6E,0x57,0x8F,0x0A, +0x2D,0x9A,0x15,0x53,0x16,0x15,0x36,0xC5,0xBF,0xFB,0x2C,0x0C,0xF5,0x5E,0x8E,0xBD, +0xD9,0x5A,0xDA,0xE5,0x28,0x92,0xE1,0x7A,0xDC,0x18,0x19,0x87,0x7B,0x3D,0xC0,0xCF, +0x34,0x95,0x4D,0x3C,0xFB,0xD6,0x2D,0x82,0x69,0x92,0x3C,0x7B,0x8D,0xE5,0xA0,0x74, +0xBA,0xDD,0xBD,0x15,0xFD,0xFE,0x0C,0x69,0x63,0xD5,0x26,0x9F,0x1F,0x52,0xF5,0x54, +0x84,0x2A,0xAC,0xE5,0x53,0x85,0x0E,0x5E,0xD3,0x7F,0xA8,0xAF,0x5A,0x3D,0xA7,0xA1, +0x18,0x88,0xF3,0xC1,0x7E,0x91,0x88,0x22,0x82,0x60,0xBE,0x00,0x52,0xC6,0x29,0x1E, +0xF7,0xD5,0x97,0x1E,0x6D,0x41,0xF7,0x62,0xA8,0x93,0x09,0xC3,0xBB,0x7F,0xF9,0xF3, +0x72,0xDB,0xC1,0xFE,0x33,0x3F,0x55,0x35,0xE4,0x81,0x8A,0x3F,0x43,0xDA,0xEA,0x2F, +0xB3,0xC8,0x20,0x3C,0xA7,0xCF,0xE5,0xBE,0xAB,0x75,0xC6,0xB8,0xDB,0xF5,0x56,0x1B, +0xAB,0xAD,0x27,0xB9,0x3A,0x21,0xE8,0xAB,0x07,0xFD,0xD5,0xCD,0xBF,0x36,0x91,0x8B, +0x19,0x38,0x7E,0xCC,0x52,0xA9,0x64,0x8F,0xA8,0xF4,0xC0,0x6E,0x06,0x45,0x65,0x69, +0x11,0xB3,0x6C,0xF3,0xFD,0xC6,0x1A,0x12,0xC2,0xD4,0x29,0xD7,0x71,0x91,0x6F,0xDD, +0x6E,0x36,0xF0,0x67,0xB0,0x91,0x23,0x25,0x7B,0x3D,0xFC,0x1A,0x4D,0xF7,0x81,0x48, +0x3E,0x1E,0x9E,0x9E,0x06,0x89,0x40,0xF9,0xBA,0x6B,0xF8,0x9E,0xDB,0x89,0xCD,0xFA, +0xFB,0xEF,0xC0,0x23,0xA1,0x3C,0x60,0x34,0x72,0x92,0x7A,0x58,0xD7,0x3A,0xE0,0x8A, +0xA2,0xB9,0x27,0x28,0xC2,0x31,0x79,0x53,0xE1,0x9A,0xD9,0x0F,0x00,0x98,0xE3,0x41, +0x81,0x8A,0xD1,0x61,0xB8,0x56,0xEA,0xDC,0xB1,0xCA,0x5B,0xF7,0xE2,0x55,0x82,0x0D, +0x88,0xD7,0x14,0x88,0x6D,0x11,0x60,0x6B,0xF5,0x69,0xBF,0xA2,0xDA,0xBA,0xD1,0x67, +0xE5,0xD0,0xC2,0xE5,0x42,0x00,0xFB,0x03,0x49,0x3B,0xC1,0x75,0xF0,0x0F,0x81,0xB3, +0xBB,0x95,0x8F,0xB7,0xBA,0x4F,0x4F,0x2B,0xB8,0xFB,0x44,0x2E,0x76,0xC2,0x7E,0xE4, +0x77,0x13,0x84,0x86,0xDF,0x45,0xA1,0xF8,0x87,0xC6,0x52,0xB2,0xED,0x57,0x00,0x2B, +0x92,0x9F,0x42,0xAD,0xAC,0x12,0x00,0x37,0x65,0x38,0x73,0x0D,0x85,0xE5,0xD8,0x09, +0x4B,0x8B,0xC5,0xCA,0x84,0x98,0x24,0x02,0x18,0xB7,0x01,0x17,0x51,0x03,0x61,0x07, +0xC7,0x1D,0x4E,0xEA,0xC5,0x1D,0xA0,0x72,0x6A,0xCA,0x04,0xC2,0x19,0x86,0x2D,0xDA, +0x9C,0x2A,0x61,0xE6,0xF9,0x07,0x4A,0x13,0xC7,0x8C,0x62,0x0A,0x15,0x28,0x6C,0xF1, +0xBD,0x47,0x72,0x67,0x5D,0x20,0xA6,0xAF,0x73,0x23,0xC9,0x18,0xEC,0xC8,0x41,0xED, +0xF4,0xA1,0x5E,0x83,0x76,0xAF,0x6E,0x87,0x39,0x04,0x56,0x4C,0x66,0x35,0xBB,0x82, +0x06,0x13,0x67,0x6E,0x43,0xEE,0x33,0x6C,0x28,0xAD,0x6E,0xBA,0xE8,0x02,0x3E,0xDC, +0x20,0xFF,0xE8,0x8F,0xE5,0x3E,0x0E,0x90,0x6A,0xF5,0x1D,0x80,0x02,0xD5,0x64,0x44, +0x4F,0xBC,0xA6,0xE9,0x2C,0x41,0xB2,0xD2,0x3A,0x07,0x62,0xC2,0xA3,0x1F,0x25,0xF5, +0xC5,0x0B,0xEA,0xBB,0xE8,0xB7,0x1D,0xAC,0xD1,0x7F,0x54,0xB7,0xCE,0x30,0x37,0xC6, +0xF7,0x1E,0x94,0x7E,0x07,0x75,0x1C,0xDF,0x88,0x0D,0x0D,0x88,0x11,0x9D,0x84,0xF4, +0xAC,0x28,0x8F,0xCC,0x1B,0xED,0x95,0xE1,0xD3,0xEA,0x47,0xB2,0x30,0x1C,0x2A,0xA5, +0x41,0x9E,0x74,0x12,0x35,0x0B,0x15,0x17,0x3B,0xAC,0x58,0xFF,0x7F,0x11,0x6C,0xDC, +0xC6,0xD1,0x81,0x28,0xA2,0x25,0xA0,0x46,0x33,0x6F,0xB5,0x3F,0x5F,0x04,0x79,0x0B, +0xAF,0xD7,0x20,0xB3,0xD5,0x0D,0x30,0xB2,0x14,0xF9,0xBD,0x07,0x89,0x61,0x63,0x69, +0xC6,0x16,0xD5,0x70,0x5C,0x6A,0xF4,0xE7,0xBB,0x76,0xF8,0x1A,0x48,0xD6,0x10,0x1F, +0xC5,0x21,0x25,0x28,0x93,0xC1,0xD5,0xC1,0x9D,0xC5,0xDD,0x84,0xF0,0x26,0x3F,0xA3, +0x0D,0xFA,0xAC,0x00,0x4F,0x65,0xF3,0x54,0xCF,0x6E,0x50,0xE8,0xE2,0xEE,0x01,0xB7, +0xA0,0x27,0xE8,0xE6,0xC7,0x90,0x9D,0x0E,0x3A,0x71,0x48,0x90,0x40,0xBC,0x2C,0xB3, +0x5A,0x9F,0x9C,0xE1,0xCD,0x1D,0x15,0x67,0xFF,0x41,0x64,0x43,0xD9,0x10,0x6F,0x2C, +0x37,0x40,0xC4,0x4C,0x6A,0x7C,0x73,0x04,0x9B,0x6E,0x96,0x39,0x25,0x47,0x83,0x57, +0x79,0x26,0x08,0xA5,0x24,0xFE,0xB5,0x8E,0x08,0xA4,0x2E,0x62,0xF8,0xFC,0xB0,0xED, +0x90,0x9B,0x13,0x55,0xD5,0x76,0x31,0xAA,0xE9,0xBC,0x53,0x70,0xCA,0x17,0x0F,0x91, +0xD7,0xEC,0xDE,0xCF,0x6B,0x18,0xE7,0xEE,0x75,0x50,0x56,0x38,0xAF,0x23,0xBC,0x3D, +0x41,0x0A,0xC4,0xE4,0x8D,0x14,0x6D,0xFF,0xD7,0x9F,0x45,0x57,0x9C,0x2E,0x83,0x89, +0xC5,0xC6,0xA2,0x4E,0xD4,0x92,0xF5,0x06,0xDC,0x0D,0xFA,0xF7,0xEC,0xE0,0xE6,0x4A, +0x19,0x97,0xAE,0x13,0xE9,0x5B,0x31,0x78,0x4E,0x49,0xCB,0x00,0x6C,0xB8,0xB8,0xB0, +0x36,0xE2,0x5C,0x8D,0x9F,0xC5,0xC5,0x3F,0x19,0x8A,0x55,0x83,0x82,0x84,0x23,0x2A, +0x65,0x26,0x94,0xBA,0xB9,0xAD,0x45,0xD8,0x6A,0x22,0x4E,0x1F,0xB8,0x7A,0xEC,0xA0, +0x8F,0xAE,0xB9,0xA1,0x8E,0x98,0xD1,0x70,0xD3,0x27,0xC0,0xC4,0xD1,0x6E,0x18,0x2C, +0xF8,0x6B,0x9A,0xCB,0x28,0x1A,0xA6,0x9A,0xF8,0xEF,0x4C,0xE7,0x2B,0xE1,0xD2,0x31, +0x1F,0x63,0x28,0x4A,0x51,0x5D,0xFD,0x7A,0x97,0xFC,0x0B,0x78,0x24,0x64,0xB9,0xD1, +0x21,0xC2,0xC8,0xE9,0x42,0x11,0xB8,0x09,0x28,0x1A,0x31,0xF3,0x85,0x05,0x03,0x06, +0x27,0x42,0xDC,0x78,0xC4,0x89,0x6C,0x20,0x38,0x0E,0xCE,0x53,0xF1,0xED,0xBD,0xC1, +0xE7,0xE9,0x73,0x48,0xE0,0x80,0x87,0x69,0xB5,0x57,0x06,0xDC,0x08,0x47,0x5F,0xD1, +0xD8,0x5F,0xBE,0x77,0x29,0x79,0x9E,0x96,0xE6,0xB5,0xE1,0xC4,0x43,0xA5,0x6C,0x32, +0x07,0xFF,0x0F,0x73,0x2E,0x58,0x9E,0x67,0x8A,0x98,0x7F,0x3E,0x02,0xCD,0xC1,0x1A, +0x25,0xCB,0x24,0x92,0x27,0x49,0x58,0x31,0xFB,0x7B,0x27,0x86,0x00,0xD8,0x59,0x01, +0x42,0x77,0x10,0x76,0xEF,0xFE,0x6C,0x4A,0xE0,0xCD,0x31,0x77,0x3A,0x39,0xD2,0x2B, +0xFE,0x16,0x8D,0x60,0x25,0x71,0x52,0x92,0xF6,0x7F,0x7C,0x51,0x45,0x78,0xFC,0x2E, +0x3F,0xDC,0xF2,0xFB,0x34,0xF3,0x25,0xF6,0xFB,0xB1,0x23,0x40,0x48,0x54,0x96,0x48, +0x12,0x9D,0xF2,0xA9,0x56,0xA1,0xCD,0xC2,0xF2,0x61,0x97,0x5D,0xFD,0x47,0x99,0xC0, +0x18,0xED,0x7D,0xE5,0x91,0x6A,0xA4,0x7D,0x67,0x48,0xB6,0x8F,0xA7,0xD8,0x97,0xC4, +0xB9,0x69,0xE3,0x5C,0xF2,0xC7,0xFF,0xDC,0xA4,0x0C,0xEE,0x62,0xA6,0xF2,0x8D,0x5F, +0xD7,0x01,0xE8,0x53,0x55,0x6C,0x5C,0x0A,0x90,0x74,0x2F,0x41,0x24,0x0F,0xE3,0x0C, +0x00,0xA9,0x42,0xD4,0xC1,0xA0,0xE2,0x73,0x57,0x11,0x04,0x57,0x38,0x02,0x9E,0xB5, +0x80,0x1D,0xE1,0x76,0xEA,0x1D,0x57,0x4B,0x76,0xDD,0xAA,0x42,0xA4,0x02,0xFF,0xB9, +0x91,0x04,0x08,0x73,0x56,0x40,0x93,0xCE,0xB1,0xD3,0x84,0xFD,0x37,0x0D,0x2A,0x34, +0xB4,0x55,0x6E,0x28,0x95,0x08,0xC6,0x66,0x69,0x7C,0x91,0x2E,0x6B,0xAA,0x21,0xB0, +0x64,0x66,0x48,0xEB,0x7C,0x61,0x7F,0x60,0xF5,0x7C,0x45,0x39,0x8D,0xE1,0x04,0x77, +0x36,0xA8,0x4D,0x34,0x52,0x3F,0xE9,0x90,0x15,0x67,0xF7,0xF4,0x91,0x1A,0xA8,0xA0, +0x0E,0xC8,0x58,0x9F,0x09,0xDD,0xCB,0x6E,0x11,0xD9,0x1C,0x4A,0x4F,0x6B,0x53,0x99, +0x2E,0xDC,0x11,0x72,0x83,0x87,0xCC,0x09,0x6F,0x18,0xC7,0x92,0x2A,0x59,0xA1,0x66, +0x30,0x69,0x28,0x94,0x30,0xDD,0x77,0xD0,0x17,0xF3,0x0D,0xDF,0x1C,0x08,0x9D,0x4D, +0x0E,0x17,0x99,0x22,0xC0,0xAF,0x4A,0x8F,0x46,0x06,0x9D,0x29,0xD9,0x8D,0xC1,0xEB, +0xE8,0x78,0xDF,0xE2,0x33,0xF8,0xE8,0xE0,0x9F,0x7A,0x27,0x56,0x2C,0xD9,0x25,0xB6, +0x7D,0x02,0xD1,0xB2,0x47,0xB1,0x44,0x87,0x03,0xAF,0x06,0xC2,0x3B,0x22,0x68,0xA1, +0x7A,0x80,0xA3,0xEE,0xDE,0x12,0x21,0xFB,0xD2,0xB3,0x80,0x4C,0x1F,0x01,0x40,0x7B, +0x08,0x70,0xD4,0x74,0x21,0x6C,0x86,0x35,0xC7,0x88,0x98,0xB6,0x38,0xAE,0xC9,0xFA, +0x6E,0xBB,0x91,0x08,0xB9,0x06,0x01,0xD1,0xC3,0x77,0x75,0xD0,0xCD,0xE7,0x90,0x61, +0x0F,0x39,0x77,0x57,0x57,0xFF,0xDC,0x1A,0x09,0xDC,0xBB,0x39,0xE6,0x01,0x11,0xBF, +0xD4,0xD0,0x16,0x90,0x53,0x9A,0x49,0x4B,0x10,0x39,0x2E,0x3F,0xAF,0x22,0x30,0x69, +0x5A,0xEE,0xB6,0xB4,0xB5,0x90,0x33,0x9A,0xB4,0x69,0x01,0x29,0x75,0x21,0x47,0xE1, +0x4B,0xCA,0x45,0x7C,0xD7,0x8D,0x82,0xB8,0x37,0x54,0xB8,0x51,0x10,0x3F,0x5B,0x25, +0xE9,0x43,0x11,0x7D,0xD4,0x69,0xE4,0x58,0xFF,0x9C,0x7E,0xD2,0x0D,0x61,0xA3,0x8E, +0x6C,0x81,0xFC,0x9D,0xDF,0xDE,0xC5,0x1A,0x87,0xBF,0x22,0x35,0xD7,0xAF,0xC6,0xFF, +0xAA,0xE8,0xB0,0xA5,0xF8,0xC2,0xF8,0x5D,0x45,0x95,0x4C,0x70,0x20,0xA4,0xC8,0x88, +0xFA,0xED,0x16,0xA4,0x6E,0x3E,0x67,0xCD,0x40,0x46,0x64,0xC0,0x75,0x11,0x0E,0x73, +0x69,0xE7,0xA6,0xB2,0x75,0x0D,0xD2,0x29,0x51,0x9F,0x8E,0xDF,0xAC,0x58,0x5D,0xB1, +0x3B,0x22,0xD0,0x83,0xA7,0xF7,0x53,0x7E,0x1F,0x62,0x41,0x82,0x71,0x9D,0xDF,0x8A, +0x7A,0x40,0x63,0x26,0x37,0x0E,0xFB,0x9F,0x0E,0x0C,0x1C,0x4B,0x10,0x44,0x31,0xC1, +0x68,0x60,0x8C,0x34,0x17,0x4A,0xAE,0xC7,0x02,0xD9,0x9F,0x9B,0x16,0xF3,0x8D,0xD7, +0xF2,0xB1,0x9D,0xB1,0x87,0xFD,0x4A,0xDF,0x51,0x2A,0xEA,0xD1,0x22,0x61,0xA9,0x8D, +0x45,0x68,0xBB,0xFC,0xD2,0x3B,0xE6,0x79,0xC9,0xA3,0xD5,0x07,0xB1,0x48,0x56,0x71, +0xAD,0xE9,0x4B,0xC3,0x52,0x56,0x41,0x5A,0x93,0xF3,0x8C,0x41,0x49,0xAF,0x36,0xF9, +0xCB,0x83,0x0A,0x77,0xD0,0xF0,0x86,0x30,0xB0,0xFB,0x90,0xE8,0xFB,0x04,0x9E,0xE7, +0x5B,0x56,0x8C,0xE2,0xA7,0x8D,0xAE,0x8D,0x32,0x66,0x1B,0x52,0xA1,0x86,0x80,0x75, +0xC6,0x39,0xC7,0x4D,0x11,0xDE,0x0B,0xAD,0x56,0xA3,0x61,0x29,0x16,0x44,0xEA,0xBD, +0xAE,0x4F,0xCB,0x80,0x39,0x31,0xCB,0x44,0x20,0xC3,0x3F,0x0C,0xCF,0x98,0x8D,0xB3, +0xEB,0x6E,0x7F,0x32,0xF3,0x24,0x80,0xA9,0xAC,0x3C,0xC8,0x7F,0x62,0xB5,0x8A,0xB5, +0x24,0x59,0x9C,0xCE,0x47,0xA3,0x33,0x40,0xD9,0x9A,0x13,0xEA,0xB6,0x25,0xEF,0x29, +0xE8,0x7E,0x9B,0x80,0x9D,0x1E,0xBC,0x11,0xAB,0x67,0xE0,0xB5,0x69,0x68,0x72,0x78, +0x50,0xCA,0x2B,0x89,0xDD,0x96,0x95,0xB4,0xE3,0x12,0x2F,0xC5,0xF7,0x31,0x73,0x0C, +0x17,0xD7,0xB3,0x08,0x09,0x1A,0xB5,0xB1,0x48,0xB7,0x15,0xC3,0xB1,0xFA,0xF8,0x18, +0xA7,0x14,0xCF,0x01,0x34,0xC1,0x1D,0x44,0x8F,0x29,0xE1,0x3C,0x4B,0xB8,0x02,0x03, +0xA5,0xBE,0x9D,0xFA,0xA5,0x76,0x07,0xD2,0x11,0xBD,0x12,0xA9,0xE0,0xF6,0x7D,0x92, +0xC7,0x44,0xD1,0x61,0xF4,0xE0,0x5D,0x29,0xB3,0x53,0x38,0x25,0xE2,0x3B,0x3E,0x08, +0x8E,0xAB,0x87,0xC9,0x15,0x34,0x34,0xE3,0x0F,0x09,0xE3,0x50,0x9B,0x5F,0x99,0x81, +0x6F,0x09,0x6A,0xC5,0x69,0x69,0x48,0x23,0xC5,0x87,0x9F,0x26,0x2A,0x15,0xE1,0x8F, +0x85,0xF7,0x2F,0x35,0xC9,0x14,0x87,0xE7,0x70,0x22,0x84,0x75,0x24,0x94,0x4C,0xE3, +0xB1,0xA4,0xAD,0xB0,0x6C,0x0F,0x8B,0xE8,0xCD,0xC3,0xE6,0x8A,0x99,0x2A,0xE2,0xC0, +0x9B,0xC9,0x2C,0x76,0x77,0xBB,0xC0,0xE0,0x58,0x7B,0x66,0xDE,0xC9,0x39,0x5B,0x60, +0x80,0x23,0x10,0x15,0xB9,0xD9,0x9E,0x29,0xEA,0xE2,0xEA,0xBE,0x9E,0x4B,0x2F,0xF6, +0xB7,0x8D,0xA3,0xA0,0x61,0x8F,0x1F,0xC8,0x4A,0xA3,0x68,0x66,0x47,0x89,0xEC,0x39, +0x63,0x19,0xD7,0x02,0x4C,0x0F,0x01,0x46,0xFC,0xFC,0xBA,0x42,0x79,0x42,0x11,0x4C, +0x3A,0x88,0xA9,0x1E,0x53,0x76,0x2B,0x23,0x5A,0xBF,0x3D,0x2D,0x74,0x2E,0x5A,0xC2, +0xB7,0x30,0x00,0xA8,0x3D,0xA5,0x80,0x8D,0xFF,0x31,0xED,0x06,0x55,0x69,0x8A,0x56, +0xAF,0xEE,0xE9,0xEE,0xAB,0xDE,0x54,0x0D,0x1D,0x28,0x21,0x6A,0x26,0xCD,0x35,0xB9, +0x1D,0x0D,0xF3,0x69,0x30,0x57,0x13,0x96,0xDA,0xBD,0x5D,0x36,0xD6,0x8F,0x05,0xAE, +0xC5,0xC6,0xD2,0x95,0xE0,0x1D,0xB1,0x3A,0xBA,0x1F,0x02,0x34,0xEA,0x3E,0xAF,0xF2, +0x42,0x48,0x30,0xC6,0xB1,0x7B,0x78,0x4D,0xC8,0x0A,0x1A,0x40,0xA5,0x05,0x25,0xC3, +0x27,0x80,0x82,0x94,0x7A,0xCD,0xA0,0x28,0xB7,0xBF,0x8F,0xE1,0xB9,0x30,0x99,0x0F, +0x90,0xDE,0x61,0x98,0x91,0x89,0x0D,0x6A,0x41,0x90,0x8E,0xFC,0x7C,0xB1,0xBC,0xE1, +0x18,0x29,0x79,0xA3,0x68,0x27,0xD1,0xF5,0xFB,0xD1,0x05,0xB9,0x0D,0x80,0xF0,0xFC, +0xD2,0x1A,0x63,0xEB,0x23,0xC0,0x4F,0xCC,0x70,0xF5,0x73,0x64,0xD4,0xCE,0x6F,0xCA, +0x6F,0xD0,0x33,0x02,0xED,0xCD,0xC3,0x02,0xAE,0xFF,0x1F,0xF6,0xE7,0x82,0xAE,0x47, +0x8B,0xF4,0x8B,0x76,0xDE,0x76,0x09,0x6B,0x73,0x13,0x35,0xD5,0xAF,0x40,0xCE,0x2B, +0xF5,0xE0,0x52,0x8F,0xA2,0x7B,0x07,0x90,0xF8,0xAB,0xEA,0xF6,0xF2,0x78,0x6C,0xF1, +0xA8,0x81,0xA1,0x28,0xD1,0x38,0x5C,0x54,0x2E,0xF3,0x51,0x21,0xF5,0xD6,0xBC,0x6B, +0x22,0x50,0x73,0xC0,0xAA,0x6C,0x63,0xD3,0x9B,0xE1,0xEF,0x67,0x49,0x63,0xA3,0x4E, +0x4C,0x5A,0xE1,0x95,0x96,0x03,0xC2,0x79,0xBE,0xC1,0xD4,0x6A,0x0A,0x35,0xC0,0x00, +0x5F,0xDF,0xA0,0x28,0x3D,0x2A,0xEF,0x11,0xB2,0x83,0xD2,0x34,0x19,0x05,0xC9,0x1D, +0xF6,0x1E,0x92,0x0D,0x2F,0x66,0xC3,0x60,0x76,0xA9,0xB0,0xA8,0x3B,0x9C,0xB4,0xD1, +0x5F,0x5F,0x4C,0xEB,0xCF,0x2B,0x57,0xFF,0xA0,0x48,0xD8,0xEA,0xBC,0xCB,0xB9,0x25, +0xE8,0x46,0x56,0x8D,0x7A,0x44,0x53,0x40,0x82,0x4B,0x84,0x42,0x1F,0x76,0xFF,0x99, +0x2D,0xAF,0x15,0x73,0x98,0xBB,0xA2,0x16,0xC7,0x13,0xCD,0xAB,0xA0,0xEC,0x13,0x23, +0x67,0xED,0x3C,0x9E,0xC5,0x50,0xA8,0x2D,0x53,0xC7,0x01,0x00,0x1A,0x5A,0xFF,0x70, +0x22,0x34,0x50,0x0B,0xFE,0xA7,0xEE,0xC1,0xDC,0xBE,0x19,0xBB,0xA4,0x2F,0x12,0xA7, +0x68,0xC7,0x89,0x34,0xF9,0x5B,0xB8,0xE4,0x90,0xF1,0xA1,0xED,0xA5,0xF9,0x3B,0xC4, +0xDA,0x65,0x3F,0x16,0x8F,0x7F,0xE7,0xD1,0x05,0xE3,0x51,0x79,0x3A,0x2F,0xFC,0xB3, +0x44,0x5C,0xDF,0x30,0xBE,0x7C,0x27,0xF3,0xD7,0x7D,0xCE,0x6C,0x71,0xE8,0xF8,0x8D, +0x3F,0xDF,0x73,0xF1,0x4E,0x4E,0x15,0x95,0xF1,0x71,0xAD,0x53,0x42,0xA3,0x63,0xDE, +0x0A,0x7D,0xEF,0xB9,0x12,0x25,0x1C,0x51,0x2D,0x5E,0x9B,0x11,0x2D,0x01,0xB2,0x1B, +0x20,0xDC,0x9D,0x2F,0xA6,0x12,0x32,0x5E,0x82,0x98,0x19,0x52,0x7B,0xC8,0xA1,0x7E, +0xAA,0xD9,0x62,0x02,0x99,0xDC,0x4A,0x62,0x85,0x05,0xC6,0x1A,0x75,0x04,0x94,0x49, +0x98,0x69,0xD5,0x9B,0x8A,0x7A,0xCF,0x5E,0x67,0x22,0x74,0x22,0xB0,0x97,0xD0,0x17, +0x69,0x87,0x54,0x14,0x1E,0x6D,0x49,0xD8,0x04,0x55,0xAC,0x39,0x8F,0x4F,0x9C,0x19, +0xD9,0xC6,0x7C,0x3C,0xB6,0xE5,0x2F,0x5B,0x9A,0xB3,0x4E,0x9C,0xF0,0x77,0x87,0x53, +0x95,0xDE,0xA3,0x84,0x14,0x3F,0xF6,0xB5,0x54,0x3E,0x84,0x31,0x9E,0x70,0xA9,0xAC, +0xA8,0xD3,0x18,0xEB,0x5D,0x57,0x6D,0x5F,0xAD,0x20,0x7E,0x30,0x73,0xA2,0x7D,0xCE, +0x20,0xB0,0x1D,0x52,0x99,0xE0,0xAE,0x39,0x12,0x37,0xEB,0x14,0x28,0x44,0x2C,0xF1, +0x5A,0x1E,0x40,0x1A,0x12,0x56,0xD3,0xC2,0xCF,0x88,0x18,0x1D,0x0D,0x9C,0xAA,0x0B, +0x32,0x3D,0xF8,0x4C,0x27,0x0F,0x87,0xD1,0x40,0xBE,0xB4,0x72,0xBC,0xB9,0x90,0xB7, +0xB0,0xA5,0x89,0x65,0x49,0x5D,0x3A,0xB2,0x9F,0x0D,0x79,0xAB,0x78,0xD6,0xCC,0x36, +0x09,0x24,0xD7,0x6F,0xEF,0x41,0xCF,0x46,0xFC,0x72,0x49,0x8E,0xB9,0x2D,0x29,0x45, +0x67,0x27,0xDC,0x5F,0x82,0x8C,0xDF,0x55,0x3A,0x75,0xE6,0xC1,0xF4,0x2A,0xC3,0x9F, +0x2E,0x50,0x55,0x32,0x3D,0x5E,0x1E,0xD3,0x5A,0x81,0x18,0x26,0xD0,0x50,0xFB,0xB6, +0xC7,0xC5,0x43,0x6F,0xB2,0xDE,0x8D,0x2F,0xD8,0x97,0xA9,0x65,0x65,0xB6,0x82,0x22, +0x29,0x1E,0x41,0x7E,0x16,0x46,0x85,0x46,0x53,0xEE,0xEA,0xDF,0x6C,0xC6,0xF7,0xFC, +0x0A,0x88,0x22,0xB7,0x96,0xE0,0xF4,0xC4,0xC4,0xC1,0x51,0x25,0x03,0xDD,0x5A,0xD5, +0x7C,0x2E,0xF2,0xC6,0x23,0x56,0x1E,0x05,0x32,0x53,0x57,0x83,0x03,0x56,0xB0,0xCF, +0x44,0xBC,0x87,0x36,0x99,0xFF,0x39,0x98,0x63,0xC3,0xED,0xB1,0x34,0x4B,0x34,0x24, +0x20,0xCF,0x90,0x8A,0x66,0x4C,0x8F,0x8C,0x15,0xA8,0x2D,0x9E,0xE8,0xE0,0xBF,0x84, +0x57,0xCD,0x0D,0xCC,0x1D,0xF1,0x2E,0x35,0x0C,0x5D,0x96,0x5C,0x5F,0xF7,0xE1,0x21, +0x0D,0xFD,0x10,0x1D,0x0A,0x09,0xAF,0x18,0xFE,0x57,0x67,0x4C,0x38,0xAF,0x21,0x0E, +0x35,0x83,0xFE,0xAC,0x15,0xDF,0x2F,0xE1,0x6B,0x5D,0x97,0x34,0x53,0x64,0xD4,0xCF, +0xD2,0x41,0x1D,0x00,0x2D,0xF5,0x8C,0xDD,0xAD,0x4B,0x4B,0x23,0x07,0xE7,0xDB,0xF9, +0x9F,0xE8,0x37,0x96,0xF2,0xE3,0xFA,0x7A,0x37,0x16,0xBB,0x14,0x94,0xAE,0x4A,0x83, +0xAA,0x9B,0x2C,0xBD,0xE0,0xAD,0x76,0x03,0xD6,0xD6,0x95,0xE0,0x04,0x1D,0xE2,0x89, +0x36,0xDB,0x59,0xBC,0x52,0xE2,0xFD,0xB3,0x44,0xA5,0x55,0xAA,0xF8,0x09,0x8F,0x66, +0xA3,0x20,0x1B,0xAE,0xFE,0x73,0xD3,0xFA,0xA9,0x90,0x80,0x94,0x44,0x34,0x89,0x4E, +0xF9,0xA9,0x9D,0x6F,0xEF,0xD6,0xBD,0xC3,0x46,0x5A,0xF7,0x6C,0xD6,0x6A,0xC3,0x2E, +0xAA,0x4D,0xC8,0xFA,0x64,0x13,0x6E,0x93,0x42,0xED,0xD7,0xE5,0x61,0x09,0x2A,0xA6, +0x5A,0xE5,0x10,0x0B,0xB6,0x49,0x83,0xB2,0xFC,0xE5,0xF8,0xA5,0x30,0x06,0x85,0x61, +0x15,0x75,0xE5,0x6B,0x18,0x07,0xBB,0x13,0xCD,0x19,0x96,0xD2,0x6B,0x44,0xA0,0xB4, +0x47,0xCE,0x9B,0xA1,0xC9,0x30,0xB1,0xBC,0x6B,0x9F,0xCB,0xD5,0x78,0x47,0x2E,0x08, +0x52,0xBD,0x0E,0x2E,0xF6,0x02,0x1D,0xAB,0x96,0xAF,0x83,0x5D,0xA8,0x3A,0x06,0x9A, +0x47,0x33,0xF3,0xD2,0x4C,0x38,0xA6,0x54,0xE9,0xE7,0x0A,0xBF,0xE7,0x12,0x46,0xD9, +0xC5,0x87,0x9C,0x8F,0xCA,0x3B,0xDA,0xD1,0x93,0xB1,0x8B,0xD8,0xF5,0x5F,0x51,0x50, +0xA2,0x40,0x0D,0xA0,0xB1,0x34,0x36,0x00,0x4C,0xD5,0x3C,0x6E,0x4A,0x40,0x9E,0xFE, +0x0F,0x71,0x2B,0xDD,0x13,0x9D,0xAC,0x8F,0x77,0xC6,0x47,0x12,0x83,0x03,0xFE,0x83, +0xA9,0x64,0xE4,0x0A,0xE4,0x3A,0xB4,0xC0,0xFA,0x9D,0xD8,0xB3,0xAB,0x02,0xCE,0x2D, +0x05,0xCE,0x3F,0xBE,0x32,0xFA,0xE7,0xF0,0x1A,0xB4,0x22,0x43,0x65,0x61,0x4C,0x94, +0x2C,0x2D,0x25,0x36,0x45,0x85,0x62,0x95,0x96,0x2B,0xFF,0x75,0x51,0x57,0x22,0x10, +0xEF,0xCD,0x39,0x05,0x85,0x54,0x4B,0x01,0x0F,0xE3,0x41,0x7A,0x9F,0x95,0xD7,0x4E, +0x3E,0xE7,0x7B,0x7A,0x70,0xAC,0x8A,0x46,0xB2,0x18,0x2A,0x89,0x4A,0x1A,0x5B,0x05, +0xA8,0x6D,0x56,0x19,0x4C,0xEE,0x0A,0x4A,0xE7,0x0F,0xE1,0x76,0x4C,0x93,0x9D,0x90, +0x24,0x8A,0x7A,0x37,0x69,0x30,0xC8,0x2A,0xCC,0x80,0x3A,0x35,0x16,0x8F,0xCD,0xDB, +0x73,0x63,0x9C,0xA2,0x68,0xE0,0xA5,0x9D,0x8E,0x12,0xCC,0xA1,0x37,0xF5,0xFD,0x8D, +0x44,0xE4,0x0E,0x1D,0x9B,0x34,0xC5,0x8F,0x2E,0xDD,0xCD,0x24,0x07,0x01,0xC4,0xF4, +0xA5,0x58,0x17,0x44,0x54,0xA8,0x95,0xD3,0xB9,0x22,0xC0,0xD8,0x14,0x9B,0x9E,0xB9, +0x3A,0x2D,0x23,0x4F,0x5C,0x7D,0x89,0x96,0x38,0xE5,0x15,0x4D,0xF8,0xF1,0x7A,0x88, +0x48,0xBF,0x80,0x13,0x29,0x1D,0xA8,0x37,0x8D,0xB2,0x87,0xB5,0x65,0xAA,0x1E,0x55, +0xAA,0x79,0x24,0x4D,0xBD,0x8F,0xF3,0xA9,0x7F,0x15,0x87,0x01,0x3A,0xB7,0x46,0xB2, +0x7B,0xA5,0xEF,0xC6,0x2E,0x25,0x66,0x3A,0xF2,0x8B,0x6D,0xE4,0x79,0x4D,0x07,0x63, +0xF3,0xBD,0x83,0xAD,0x91,0x36,0xDA,0x00,0xB3,0xC3,0xBD,0xC6,0xAC,0xAF,0x7D,0x1D, +0x08,0xFD,0xCD,0x1F,0x46,0xA4,0x32,0xBE,0x93,0x17,0x46,0x3D,0xF2,0xAC,0xBF,0xEC, +0xB1,0xFF,0xC2,0x7C,0x9D,0xBD,0xC9,0xFF,0xB8,0x2E,0x18,0x81,0x8A,0xC9,0x5F,0x69, +0x0F,0x14,0x64,0x2A,0xD3,0xBB,0x69,0x9A,0xB3,0xCD,0x44,0x6B,0x5D,0xA3,0x96,0x2D, +0xBC,0x55,0x9C,0xBF,0x75,0x2C,0x02,0xA2,0xD5,0x68,0x99,0x89,0x23,0x33,0x66,0x13, +0x5B,0x0B,0xBD,0x3A,0xA5,0x95,0xCD,0x54,0x37,0xE0,0x9E,0x98,0xE3,0x05,0x10,0x0F, +0xFD,0x96,0x6C,0x76,0x6B,0x8B,0xBF,0xE2,0xF5,0x14,0xFA,0x60,0x09,0x5F,0x3F,0x7F, +0xCB,0xB4,0x4A,0x6B,0xE6,0x4C,0x3D,0x3C,0xD2,0xE0,0xE2,0xB6,0xA2,0xA5,0xCD,0x4A, +0xCC,0x11,0x07,0x73,0xE5,0xAC,0x0C,0xED,0x70,0x92,0x2D,0x48,0x0B,0xCE,0x32,0xB4, +0x01,0xE8,0xAE,0xBA,0xAB,0xAF,0x48,0x98,0x3B,0x02,0x13,0x98,0x31,0x42,0x6C,0xD3, +0x2D,0x7A,0x98,0x11,0x9B,0x63,0x3D,0xB6,0xCD,0xD2,0xF0,0xA2,0xB9,0x77,0x4F,0x56, +0x76,0x01,0x80,0x3A,0x08,0xFB,0xB7,0xDD,0xDB,0x24,0x99,0xC0,0x31,0x94,0xE7,0x7D, +0x8C,0x35,0xBF,0xA5,0x62,0x88,0x54,0x77,0x27,0x58,0xB4,0x1C,0x45,0xA0,0x41,0x2C, +0xA8,0x68,0x99,0x8A,0x98,0x3C,0x9D,0xBE,0xBD,0x2B,0x16,0x27,0x0B,0x81,0xE6,0xB2, +0x1B,0xA8,0x8D,0x7A,0xE7,0x40,0x6D,0xCC,0xF6,0x0A,0xBA,0x79,0x51,0x99,0x5F,0x71, +0x2A,0xFC,0xD5,0xA1,0x5D,0xDB,0xAA,0x51,0x18,0x99,0x81,0x48,0xA2,0xB1,0xA0,0x06, +0x01,0x7D,0x98,0xBC,0x47,0x4A,0xD3,0x7B,0x99,0xF8,0x21,0x91,0x31,0x48,0x2D,0x8D, +0xBE,0x81,0xF4,0xFF,0x9A,0xDD,0xC2,0x3E,0x3D,0x80,0xD7,0xEA,0x38,0x7C,0x1F,0xF8, +0xCF,0x76,0xAB,0xE9,0xF3,0x5F,0x83,0x2C,0x8E,0x2F,0x26,0xE2,0xEA,0xF0,0x75,0x6D, +0x42,0x85,0xED,0xEF,0x5B,0xB3,0x60,0x34,0xE4,0x8C,0xFC,0xC4,0x5E,0x3B,0x0D,0x7C, +0x22,0x0D,0xC0,0x29,0xAF,0xF6,0xC4,0xF9,0x01,0xFE,0xD7,0x89,0xDF,0x1D,0xE6,0xC2, +0x5E,0x4D,0x2B,0xD7,0xC3,0xE9,0x45,0xE5,0x51,0x65,0xD5,0xD1,0xDF,0xCF,0x04,0x12, +0x8D,0xE3,0x66,0x0B,0x96,0x69,0x65,0x8D,0x7E,0xA8,0xFD,0x66,0xCE,0xFB,0x74,0x74, +0xA4,0x3A,0x7D,0xC8,0x42,0xA2,0x99,0x49,0x35,0x87,0x51,0x25,0xF2,0x03,0x8F,0xB8, +0xF6,0x53,0x3A,0xDF,0x00,0x35,0x0A,0x12,0x6F,0x47,0x09,0x78,0x73,0xBA,0xBF,0xC0, +0x62,0x1B,0x23,0xD5,0xC5,0x6A,0x14,0x37,0x5A,0x23,0xBC,0x3D,0x22,0x4B,0x37,0x41, +0x4D,0x6B,0x0B,0x01,0x4E,0x43,0xE9,0xB6,0xBD,0x97,0x15,0x4E,0xC4,0x86,0xF3,0x88, +0x5F,0x78,0x14,0x9F,0x8F,0x25,0x07,0x20,0x0E,0x95,0xDE,0x71,0xAE,0x82,0xF9,0x58, +0xE6,0x0C,0x55,0xE7,0x8C,0x97,0x80,0xDE,0xEB,0x4A,0xB6,0x39,0xFC,0x22,0x56,0xED, +0xBF,0x3B,0xC3,0x60,0x15,0x7A,0xE2,0x11,0x11,0x82,0xB0,0x26,0x20,0xA0,0x9B,0xBC, +0x63,0x0D,0x89,0x2D,0x14,0x84,0xEB,0xA2,0x75,0x25,0x7E,0x3B,0xFA,0x7D,0xA7,0x71, +0x47,0x06,0xA4,0xD5,0x9B,0x86,0xA6,0xB3,0x88,0xAB,0x5D,0xE6,0x04,0xE3,0x5C,0x2E, +0xF3,0xDC,0x8D,0x5C,0x10,0x9D,0xCB,0xC3,0x4A,0xC8,0xC1,0x8E,0x46,0x66,0x24,0x14, +0xE9,0xEC,0x52,0x9F,0x79,0x60,0xCB,0xA6,0x90,0x6E,0x17,0x3F,0x6A,0x3E,0xD2,0xAF, +0xAB,0x65,0xC3,0x39,0xD1,0xB9,0x9E,0x3E,0x54,0xEE,0x11,0xDE,0x8B,0x28,0x37,0xD1, +0xC8,0x67,0x57,0x61,0x38,0x7A,0x24,0xC0,0xCD,0xCF,0xCC,0x5A,0x18,0x42,0xE1,0x84, +0x3A,0xF6,0x6D,0xFF,0x72,0xEF,0x27,0x46,0x60,0x21,0x65,0xDE,0xBA,0x2E,0x37,0x27, +0x21,0x0C,0x52,0x90,0xEF,0x80,0x21,0x0B,0xE6,0x85,0xEB,0x05,0xB3,0x38,0xC6,0x9B, +0xEC,0x25,0x4F,0x71,0xF3,0xE6,0xFE,0x11,0xAF,0x26,0x37,0x66,0xF5,0x10,0x2A,0xE6, +0xD7,0xB3,0xDB,0x98,0xDD,0xDE,0xE2,0xAB,0x2A,0xFD,0xB2,0xCF,0xB6,0xD6,0xEB,0x1A, +0x46,0x77,0x01,0x12,0xD7,0x98,0x9F,0x90,0xBB,0x73,0x4F,0x2E,0xC8,0xB2,0x39,0xF4, +0xAC,0x48,0x11,0x8A,0x3B,0x2A,0x30,0x90,0xE0,0x10,0x9C,0xAB,0xE4,0x91,0x13,0xFE, +0x6F,0x37,0x2D,0xDD,0xC1,0x1D,0x49,0x8B,0x9C,0xB8,0x96,0xEE,0x3B,0x91,0x68,0x89, +0xE8,0x77,0x7F,0x08,0xFE,0x52,0xD4,0x2D,0xCF,0xB9,0xE2,0x1C,0x59,0xA8,0x2D,0xCE, +0xAC,0x7A,0xF7,0xE2,0xAE,0xBC,0x9C,0x7C,0x8A,0x62,0x55,0x48,0xC1,0x40,0x03,0xBC, +0x28,0xC3,0x59,0xEB,0xEC,0x23,0x08,0xE5,0x85,0x5F,0x28,0x66,0x04,0xE0,0x5C,0x39, +0x4B,0x7B,0x76,0xC8,0x3A,0xFD,0x6C,0xA2,0xFF,0xC9,0x79,0x38,0x98,0x5E,0x1D,0x17, +0xEB,0x6D,0xB9,0x4F,0xB7,0x92,0x07,0x3A,0x80,0x2D,0xB0,0xB3,0x83,0x0E,0x56,0xC1, +0xF0,0x1E,0x37,0xA8,0xAA,0x0C,0xA0,0x41,0x57,0xF2,0x47,0x54,0xDC,0xF1,0xF6,0x98, +0xE9,0xB6,0x1C,0x71,0xDD,0x01,0xE1,0xB2,0xAA,0xAA,0xB9,0x07,0xDE,0x77,0x39,0xD7, +0xC7,0x19,0x1D,0xCD,0xCC,0x29,0xD6,0x08,0x6C,0xD4,0x58,0xC9,0xC7,0x73,0x00,0xB2, +0xDD,0xA1,0xA4,0xBF,0x7E,0x13,0x8F,0xB7,0xD3,0x04,0x9C,0x0E,0x19,0xA0,0xDE,0xF0, +0x04,0x74,0x8A,0xC8,0x9A,0x79,0xA5,0x51,0x37,0x4D,0x7D,0xE7,0xCE,0x30,0x4A,0x14, +0xA4,0x0C,0xC8,0x24,0x08,0x0E,0xEA,0x4D,0x7B,0xFA,0x44,0x06,0x53,0x71,0xE1,0x33, +0xCC,0xB8,0x06,0xBE,0x8E,0xE1,0x1F,0x9D,0x94,0x50,0x48,0x94,0xA7,0x43,0x6B,0xDC, +0x8D,0xA7,0x98,0x97,0x77,0xC0,0x0F,0x22,0x2F,0xD6,0xFD,0x75,0xDD,0x37,0x4D,0xE8, +0x64,0x89,0xAA,0x10,0xEB,0x10,0x53,0xE4,0xF1,0xDF,0xD3,0x58,0x2A,0x66,0x1A,0x93, +0xA3,0xC4,0x40,0xF2,0x54,0x86,0xD6,0xD1,0xC9,0xA5,0x92,0xFB,0x04,0x73,0xEC,0xE4, +0xCB,0x07,0xA2,0x7E,0x81,0x32,0xF1,0x8B,0x6A,0x1C,0x6E,0x0F,0x1D,0x4F,0x04,0x1F, +0x02,0xD6,0x17,0x42,0x12,0xF6,0x43,0xD9,0xDD,0xDE,0x15,0x15,0xB5,0x6D,0x3F,0x26, +0x5B,0xF5,0xF1,0x2B,0xE6,0xEB,0xE7,0x35,0x82,0xE2,0x9A,0x30,0xAC,0x67,0xB9,0x2D, +0x9A,0x3B,0x1A,0xB3,0x24,0x29,0x88,0x93,0x56,0x78,0x1F,0x2C,0xA5,0x57,0x99,0x57, +0x76,0x60,0x2E,0x3C,0x6D,0xB1,0x23,0x0F,0x3A,0x5B,0xD2,0xE1,0x94,0x5E,0x56,0xE5, +0x01,0x73,0xC6,0x01,0x2E,0x66,0x82,0x34,0x5F,0xB4,0x76,0x01,0xE4,0x6B,0x59,0x4A, +0xA6,0x38,0xDA,0x2B,0x2F,0x74,0xCA,0x85,0xA1,0xCA,0x61,0x2B,0x31,0xAF,0x34,0x93, +0x8D,0xA7,0x29,0xEC,0xAD,0xF2,0xA4,0x86,0x85,0x49,0xB6,0x2A,0x3D,0x42,0x3B,0xBC, +0x6F,0xA2,0x06,0x4C,0x7E,0x81,0xF5,0x3D,0xD9,0x02,0xA1,0x15,0x53,0xBC,0x06,0xBF, +0x00,0xA9,0xF8,0xF2,0xB8,0xC4,0x5E,0x56,0x98,0x62,0x3F,0xF7,0x73,0xD7,0x8B,0xBA, +0xEA,0xE6,0x5C,0x53,0x26,0xCC,0x3D,0x02,0x4C,0xAA,0xA4,0x03,0x1A,0x63,0x6A,0xE2, +0x21,0x2C,0xF3,0x8E,0xC3,0x7E,0xB1,0x5D,0x8A,0xC3,0xAF,0x6B,0x83,0x3A,0xFC,0x2F, +0x72,0xD6,0xF6,0x5F,0x08,0x19,0xD4,0x58,0x45,0xED,0x75,0x29,0x06,0x8D,0xF0,0x0E, +0x7A,0x0A,0x2E,0x5E,0xD7,0x29,0x8B,0xB4,0x23,0xBF,0x14,0x0D,0xCC,0x98,0x22,0xC3, +0x97,0x30,0xF8,0x62,0x44,0xD6,0x6C,0xD7,0x49,0x9E,0xF8,0x78,0x86,0xF7,0x26,0x0F, +0xDA,0x29,0x0B,0xA3,0xEF,0x41,0x83,0xC5,0x69,0xC3,0x80,0x3C,0x33,0xD8,0x4C,0xDA, +0xD7,0x7E,0xFB,0xCF,0x6B,0x16,0xED,0xAA,0x39,0xB6,0x42,0x1B,0xDD,0x23,0xE7,0x08, +0x71,0x56,0xDD,0x48,0xE5,0xA3,0x9C,0x21,0x3F,0xD4,0x95,0xB4,0x13,0x99,0x83,0x12, +0xA4,0x1D,0x4A,0x67,0xAC,0x9A,0x80,0x87,0x5D,0x07,0xCE,0xD0,0x08,0xDD,0x18,0x2B, +0x96,0x02,0x55,0x26,0x64,0xF7,0xB9,0x3E,0xBF,0x16,0x8C,0xAE,0xD5,0xDF,0x11,0x51, +0xCC,0xFC,0x84,0xFF,0x30,0xBF,0x47,0x26,0x86,0x11,0x40,0xD5,0xAB,0x5B,0x99,0x95, +0x2D,0xEB,0x98,0x76,0x4B,0x59,0x6F,0x06,0x66,0x8C,0x6A,0x93,0x04,0x43,0xA2,0xF8, +0x6C,0x0C,0x86,0x7B,0x8E,0xED,0x81,0x75,0x09,0x5E,0x50,0x8D,0xF8,0x72,0x86,0x66, +0xCC,0x23,0x72,0x16,0xBD,0xDA,0xAF,0xC6,0x8A,0x52,0x8D,0x26,0xD4,0x23,0xAD,0x10, +0x10,0xE5,0x34,0x2A,0x52,0xE5,0x56,0xD5,0x41,0xF2,0xB6,0xE7,0xEB,0xCF,0xD7,0x1A, +0xC1,0xC6,0x6C,0xE5,0x68,0x86,0xF8,0x16,0x9B,0x76,0xB3,0x87,0x66,0x32,0x37,0x4C, +0x99,0xF1,0x75,0x17,0xEF,0x88,0x47,0x1A,0xA5,0x27,0x9D,0x1C,0xC8,0x99,0xF7,0xC0, +0x1E,0xF1,0x93,0xD9,0xCB,0xCF,0x04,0x5B,0x25,0xE5,0xC3,0x1C,0x17,0x45,0x59,0xBC, +0x1E,0xB4,0x03,0xED,0xE8,0xCF,0x33,0x27,0x17,0x5A,0x13,0xDC,0x6C,0x61,0x09,0x26, +0x79,0x15,0x58,0x40,0x3F,0x1A,0x28,0xB2,0x9F,0x0F,0x98,0xFF,0x40,0xC3,0xA0,0x6A, +0x3A,0xF6,0x0A,0x00,0x8F,0xCD,0x61,0xD4,0xCB,0x04,0xF9,0x16,0x50,0x1D,0xAB,0x43, +0x7A,0x43,0x5E,0xAE,0x59,0xF4,0x0E,0xBF,0x1E,0xA1,0x39,0xC8,0x86,0xF4,0x5E,0x56, +0x9B,0x13,0x87,0xD5,0x36,0x06,0x83,0xF9,0xF5,0x8A,0xF5,0x27,0x2B,0x23,0x9C,0x2B, +0xF0,0xEC,0x3C,0xC3,0xC5,0x1E,0x5F,0xBA,0x3C,0x05,0x42,0xA6,0x7B,0x62,0xA2,0xED, +0x2C,0x4C,0x9F,0xF6,0x5D,0x39,0x2B,0xF0,0x80,0x3A,0x6A,0x54,0xF7,0xF5,0x28,0xC6, +0x4A,0xBE,0xD4,0xA3,0xCF,0x11,0xAA,0xD7,0xAC,0x1A,0x28,0x68,0xD7,0x41,0xDF,0x44, +0x1B,0xB6,0x86,0x0F,0x61,0xC1,0x82,0xBE,0xCD,0x30,0x3A,0x42,0x15,0x9C,0xEB,0xBE, +0x79,0x11,0x53,0xB1,0x5F,0x6B,0xB0,0xD0,0xD8,0x9B,0x4E,0xFC,0x26,0x20,0xCA,0xBF, +0xD3,0x0D,0x54,0xB2,0x08,0x44,0xF5,0xC5,0x25,0x2A,0x34,0x57,0x90,0x22,0xD0,0x7F, +0xDC,0x0A,0x07,0xFE,0xF6,0x1B,0x39,0x75,0x30,0x9E,0x20,0x4D,0x79,0x94,0x25,0x24, +0x8C,0x98,0x34,0x22,0x71,0x50,0x39,0xF8,0x01,0xF7,0xC9,0x44,0x35,0x51,0xA7,0x32, +0x1C,0x3C,0xC2,0x76,0x04,0x70,0x99,0xC3,0xA4,0xA0,0xE7,0x50,0x2A,0xD0,0x86,0x27, +0xC8,0xEC,0xDE,0x36,0x65,0xEF,0x3D,0x13,0x9F,0x56,0xC4,0x89,0xD1,0xC0,0x26,0x7A, +0x2C,0xCC,0x33,0x94,0x69,0x3D,0xF4,0x42,0x56,0x30,0xA8,0xC4,0xEC,0xE8,0x8E,0x7C, +0x29,0xAF,0xBC,0x73,0x5B,0x16,0x56,0x2C,0x93,0xB4,0x9E,0xA7,0xC2,0xF8,0x2E,0x14, +0xB1,0xEA,0x08,0xB7,0xC4,0xCB,0x0E,0x91,0x3B,0x3F,0x8A,0x02,0x0B,0x73,0xD9,0xF0, +0xA2,0x11,0x5F,0xD6,0xAD,0xA4,0x50,0x50,0x02,0xB7,0x24,0x29,0x41,0x70,0x8A,0x73, +0xA5,0x57,0x64,0xE1,0x43,0x99,0xC4,0x39,0x41,0xD8,0xE2,0x13,0x46,0x30,0x77,0xCF, +0x01,0xFF,0x8C,0x0A,0xC5,0xDB,0xCC,0x66,0xE0,0xA7,0x2B,0xC1,0x18,0xAC,0x1E,0x68, +0xC1,0xFC,0xAF,0x50,0x0C,0xEC,0xC3,0xC8,0x12,0x99,0x7E,0x80,0xD9,0xCA,0xDE,0xD5, +0xAB,0xD5,0xD6,0xB3,0x7D,0x57,0x86,0x50,0xCA,0xFF,0x5D,0x18,0x55,0x9E,0x50,0xB8, +0xE0,0x94,0xCE,0xA3,0x36,0xA3,0xCC,0x67,0xD6,0xC4,0x85,0x31,0x06,0x16,0x8E,0x31, +0x69,0x8B,0xB2,0x72,0xD0,0x8B,0xB3,0xA3,0xB8,0x68,0xBF,0x31,0x62,0x91,0x38,0x88, +0x37,0x14,0xCC,0x1B,0x22,0x53,0x87,0xB4,0xC8,0x05,0xFD,0xAB,0xD4,0xA6,0x56,0x18, +0x49,0xE5,0x8F,0xB6,0xF8,0x3D,0x8F,0x6B,0xAC,0x02,0xCE,0x15,0x01,0x4A,0xCF,0x51, +0x8E,0x26,0x49,0x1F,0xA3,0x97,0xA5,0xC6,0x4E,0x96,0x96,0x38,0x13,0x6C,0x55,0x79, +0x49,0x9D,0x95,0xA0,0xFC,0x48,0x4B,0x59,0x0B,0x81,0x2C,0xE7,0x11,0x96,0xB1,0xEA, +0x5B,0xA0,0xCF,0xD6,0xE0,0xA5,0xB2,0x6A,0x5D,0x84,0x1A,0x2F,0x9B,0xD7,0x02,0x55, +0x95,0xC2,0xAC,0x66,0x4C,0xE1,0x93,0x85,0x06,0x8F,0xAA,0x7F,0x73,0x9D,0x41,0x7A, +0x45,0xC0,0x09,0x65,0x07,0x67,0xC2,0x8C,0x2F,0x53,0x4C,0xB3,0x4B,0x62,0xBE,0xB7, +0x7D,0xE4,0x47,0x84,0xEF,0xB4,0xC3,0x72,0x63,0xDA,0x6F,0x95,0x35,0x12,0x8A,0xE7, +0x3D,0x69,0x9D,0x09,0xB6,0xC7,0x01,0x1C,0xC5,0x64,0xCF,0x06,0x91,0xA4,0xD0,0x6A, +0x64,0x30,0x55,0xEF,0xC1,0x85,0x21,0x68,0xE2,0x7A,0x1F,0x5E,0xEA,0x7F,0xDE,0x31, +0x77,0x7F,0xD5,0x3A,0x0E,0x38,0x20,0x8B,0x86,0x3F,0x07,0x98,0xFB,0x58,0x99,0x4A, +0xAE,0x6D,0xFB,0x84,0x1A,0x02,0xA4,0x74,0x31,0xB8,0xEF,0x0C,0xF4,0x2F,0x92,0x3E, +0x4F,0x16,0x02,0xAE,0xCB,0x0C,0xF7,0xBA,0x0E,0x8A,0xBE,0x7F,0xBB,0x85,0x25,0xEE, +0x1B,0x37,0x88,0x17,0xCB,0x1D,0xC8,0x8D,0x58,0x47,0x6A,0x32,0xAA,0x03,0xAB,0xDE, +0x90,0xA4,0x44,0xFA,0x4D,0x10,0xB9,0x1E,0xAE,0x9F,0x7B,0xE1,0xBF,0x0B,0xA0,0x6A, +0x95,0xC7,0x6D,0xE8,0xF3,0xEA,0x37,0x40,0xD7,0xD4,0xBF,0xA0,0x2F,0xDC,0xF1,0x3A, +0x73,0xCF,0x23,0xB9,0x57,0xBE,0xE4,0xA0,0xDC,0x8E,0xB8,0x68,0xBB,0x35,0xEA,0xB8, +0x7E,0xF1,0x2A,0x46,0x9F,0x24,0x51,0xB5,0xCF,0xE8,0xF6,0x6C,0xD4,0x82,0x10,0xFD, +0x08,0xFD,0xB9,0x99,0x12,0x44,0x18,0xCF,0xFF,0x50,0x40,0x34,0x78,0x23,0x56,0x78, +0x4E,0x5F,0xCE,0x6D,0x10,0x14,0x1D,0x34,0xD3,0xE6,0x56,0xE5,0xF7,0x77,0xCB,0xC1, +0x11,0xB3,0x5B,0xC6,0xAF,0xD6,0x41,0xEB,0xAF,0x11,0xFE,0xB7,0x54,0x88,0x01,0x0E, +0xEB,0x39,0xCA,0x42,0xA4,0x2C,0xE9,0xDA,0x3C,0x6B,0x86,0x11,0x1A,0x54,0xB3,0x7B, +0x20,0x31,0x70,0x4E,0x80,0x62,0x22,0x5A,0x60,0x4A,0x52,0xAE,0x42,0x9B,0x42,0x6A, +0xBF,0x69,0x1B,0xA4,0xB5,0x7A,0x77,0x2D,0x76,0xEA,0xF2,0x92,0x3C,0x61,0x3F,0x62, +0x43,0xA3,0x40,0xCB,0x9C,0x02,0x13,0x64,0x52,0xF7,0x2D,0x63,0xAC,0x1F,0x78,0x75, +0x61,0x18,0x17,0x51,0x0E,0xC7,0xD9,0x15,0x5F,0xA2,0xCA,0xAF,0xF8,0xCA,0xBF,0x36, +0x67,0xEF,0xAE,0xAC,0x11,0x04,0x0C,0x36,0x65,0x75,0x58,0xF0,0x40,0x41,0x16,0xF1, +0x08,0x40,0x81,0xA2,0xDE,0x60,0x90,0xEB,0xBE,0xB3,0x14,0x9D,0xE3,0xF6,0x51,0x67, +0x75,0x7A,0xF6,0x3B,0x7D,0x73,0x64,0x57,0x70,0x51,0xD2,0x82,0xE3,0xC4,0x37,0xAE, +0x7A,0xE7,0x23,0x3F,0x54,0xCE,0x3C,0x4A,0x2A,0x7E,0x85,0x19,0xDB,0x88,0xFE,0xD4, +0x66,0xA6,0x2B,0xBA,0x5F,0x4B,0x2F,0xBD,0x5C,0x6C,0x4E,0x85,0xCB,0x1D,0x00,0xF4, +0xBE,0x6B,0xF5,0x99,0x3D,0x10,0xF9,0xEC,0x84,0xEF,0xF0,0xAA,0x8C,0xDC,0x9E,0xF9, +0x44,0xB0,0xB7,0x5A,0x4B,0x0B,0xDD,0x41,0xCF,0x98,0xD2,0x73,0xB4,0xCE,0x94,0x22, +0x82,0xEC,0xA3,0xE6,0x08,0xEA,0x67,0xBA,0xB4,0xDA,0xCE,0x0E,0xF6,0x54,0x1C,0x9C, +0x0D,0x60,0x24,0x29,0x42,0xE3,0x99,0xA8,0x65,0x56,0x1C,0xDE,0x1B,0x0B,0x9A,0x1D, +0xDF,0xA5,0x71,0x84,0x2C,0x6B,0x1A,0xAA,0x88,0x61,0x54,0x40,0x53,0xFA,0x9C,0x2E, +0x43,0x72,0x59,0x87,0x55,0xD5,0xD6,0xE4,0xFC,0xD5,0x5C,0x47,0x3D,0x6D,0x80,0x77, +0xDC,0x15,0xE2,0xDC,0x9F,0x78,0xBB,0x09,0xA3,0x69,0x52,0x7E,0xBB,0x73,0x4E,0x49, +0x9A,0xCF,0xAD,0xC1,0x06,0x13,0xF5,0x82,0x9F,0xAF,0xA6,0x5D,0x9A,0x3C,0x06,0xB0, +0x1B,0x14,0x92,0xEC,0xB3,0x23,0x38,0x27,0x03,0x7C,0xDB,0x1D,0x8A,0xAC,0x9B,0xAC, +0xC8,0xB5,0x11,0xE2,0xC4,0x8B,0x01,0x71,0x9D,0x60,0x16,0x88,0x80,0xCE,0x74,0xD5, +0xD7,0x85,0x51,0x59,0x7E,0xA3,0x22,0x1B,0x4C,0x0A,0x6C,0xD1,0xD2,0xBC,0x7D,0x7B, +0x53,0x99,0xB7,0xF3,0x31,0xCF,0xB1,0x5B,0x45,0xCC,0xDC,0x02,0xB8,0xA5,0x37,0x03, +0xC4,0x64,0xD9,0x9E,0xE0,0x0F,0xDE,0x7C,0xEB,0x62,0x7E,0xB4,0x59,0xF0,0x9F,0xA5, +0x64,0x89,0xC0,0xCC,0xE5,0xDE,0xFE,0x29,0x0B,0x72,0xB7,0x08,0x7F,0x90,0x2A,0xE4, +0x83,0x77,0x1C,0x0A,0x92,0x8A,0xBF,0xF1,0x18,0x6D,0x83,0xFF,0xBD,0x44,0x96,0x70, +0xFE,0x40,0xCA,0xB6,0x7B,0xF4,0x67,0x91,0x96,0x5E,0x68,0xAA,0x82,0xD9,0xA2,0x68, +0x82,0xC1,0xB9,0x71,0xEB,0x87,0xEB,0x5E,0x73,0xB0,0x06,0xEE,0xF9,0x8E,0x5A,0x2F, +0x21,0x25,0x93,0x41,0x25,0x02,0x9B,0xA8,0xC0,0x07,0xBC,0x98,0xBA,0x0D,0x51,0x81, +0x0A,0x00,0xD6,0x15,0xD8,0x19,0x9B,0x9A,0x3B,0x2E,0x99,0x4F,0x78,0x7B,0x7D,0x7A, +0xF2,0x83,0x9F,0xAD,0xA0,0x09,0xEB,0xB2,0x1E,0x50,0xE2,0x5A,0x11,0xA0,0xCE,0x6F, +0x42,0x44,0xF9,0x20,0xDF,0xA8,0x5E,0x54,0xFC,0x66,0xE4,0x3D,0xCF,0x79,0xC9,0x04, +0x34,0x34,0x5D,0xE4,0xFF,0xBC,0xDB,0xD5,0x98,0x10,0x8F,0x76,0x7B,0x6D,0x00,0xCE, +0x6E,0x64,0x16,0x31,0x4E,0xF8,0x16,0xFF,0x64,0x31,0x0E,0xE1,0xDA,0x20,0xB3,0x39, +0xE2,0xDD,0xD8,0x2D,0xB4,0x2C,0xB1,0x52,0x82,0xE8,0x46,0xEF,0x25,0xB8,0x28,0x26, +0xFB,0x73,0x72,0x95,0x80,0x15,0x8E,0x3F,0xDA,0xC2,0x19,0x23,0xED,0x31,0x36,0xC4, +0x1D,0x69,0xC3,0x1A,0x90,0x1D,0xED,0x18,0x8B,0x8F,0xF1,0x28,0xB5,0x3B,0x7F,0x51, +0x96,0x98,0x28,0x7C,0x94,0xC2,0x05,0x75,0x94,0xB6,0x68,0xD3,0x01,0xA6,0xC0,0x03, +0xB8,0xFB,0x52,0x4C,0x45,0x28,0xF2,0xD5,0xC2,0x91,0xBB,0x4F,0x27,0x45,0xB1,0x3A, +0x5D,0x2D,0x2E,0xFB,0x56,0xA0,0x40,0x76,0x37,0xF2,0x67,0x1C,0x2A,0xA7,0x38,0x35, +0xD8,0x45,0xF8,0xB1,0xDD,0xF3,0xF0,0xCA,0x1C,0xD9,0x94,0x59,0x19,0x04,0x6F,0xCD, +0xD1,0xE1,0x3A,0x7D,0xBC,0x74,0x17,0x61,0x9D,0x3F,0xB9,0x71,0x36,0x96,0x43,0x0C, +0x6E,0x37,0xCF,0x2E,0xC8,0xD1,0x0A,0xEE,0x3B,0x9E,0x00,0x4D,0x08,0x10,0x96,0x10, +0x76,0x1E,0x20,0x82,0xDB,0xFC,0xE2,0x91,0x83,0x88,0xB4,0x67,0xE8,0x07,0xDD,0x73, +0xFE,0xA1,0x17,0x02,0xA7,0xD0,0xF0,0x2F,0x0E,0x5F,0x7A,0xB7,0xCD,0xE2,0x76,0x25, +0x95,0xE6,0x40,0xFC,0x12,0x6C,0xE3,0x48,0xA5,0x40,0x74,0x37,0x5A,0xF6,0xAB,0x41, +0xC5,0x8F,0xFE,0x6B,0x5B,0x4E,0x19,0xE2,0x7B,0x7C,0x96,0x45,0x55,0x3B,0xB3,0x19, +0xF7,0x04,0x48,0x09,0x98,0x6D,0x0E,0xBA,0x8E,0x91,0x12,0x88,0x49,0xAE,0x12,0x45, +0x17,0xC9,0xCF,0x29,0xC1,0xA2,0xD0,0x73,0xDF,0xA3,0x6E,0xD4,0x2A,0x47,0x47,0x5A, +0x79,0xC7,0x06,0x6A,0xEB,0xEB,0xAE,0xF2,0x56,0xE6,0xA7,0xB0,0x36,0x73,0xF3,0x07, +0xB5,0xE6,0x20,0x9B,0xAE,0x9A,0xE4,0x64,0x6E,0x0D,0x09,0x59,0x50,0xD5,0xC9,0x75, +0xC7,0x9B,0x61,0x5D,0xF9,0x96,0x3B,0x11,0x59,0x50,0xA7,0x2D,0x4A,0xFA,0x3F,0xE0, +0xEE,0x6C,0x36,0x2E,0x9D,0xE2,0xC0,0x44,0x84,0xAD,0x6C,0xAE,0x0B,0x17,0x9D,0x1E, +0x71,0x9E,0x90,0x1E,0x7E,0xD2,0xCD,0xDC,0x32,0x1E,0xD8,0x05,0x0E,0xD0,0x45,0x04, +0x76,0x77,0xC4,0x73,0x92,0xDE,0xDE,0xC4,0xFF,0x74,0xF4,0x4E,0xC8,0xDD,0x53,0xC8, +0x6E,0x2F,0x59,0xF6,0x03,0xC5,0x32,0x6B,0x1F,0x4F,0x85,0x08,0x7D,0x3F,0x49,0x11, +0x4E,0x83,0xC1,0x8A,0x4B,0x7E,0x6B,0x3B,0xE9,0x3A,0x10,0x81,0x1E,0xAD,0xAF,0x1F, +0xA2,0xD8,0xE6,0xCD,0x86,0x59,0xC7,0x2E,0x1D,0x29,0xED,0x5D,0x12,0xAD,0xF9,0x74, +0x9E,0xB2,0x4F,0xE5,0x9E,0x6A,0x29,0x81,0x5E,0xFE,0x15,0x06,0xC7,0xA6,0xBF,0xDD, +0x26,0xF3,0x71,0xEB,0x56,0xFE,0xE1,0x2A,0xF2,0x74,0xD7,0x1F,0xAB,0xAC,0x24,0x78, +0x13,0x6E,0x83,0x8C,0xFD,0x38,0x94,0xE4,0x93,0x88,0x55,0x82,0xD8,0x71,0x51,0xA2, +0xB3,0x6F,0xDE,0xCE,0x95,0x0B,0x26,0xEC,0x87,0xC6,0x83,0xA2,0x66,0x8B,0x23,0x4A, +0xD3,0x0E,0xFF,0x82,0x2A,0xCC,0xF0,0xE2,0x99,0xF7,0x5F,0x29,0xBC,0xCE,0x58,0x7B, +0xFE,0x41,0x05,0x9A,0xE7,0xB2,0x1D,0xC1,0x12,0x0D,0xEE,0x22,0x86,0x4A,0x39,0x3A, +0xAE,0xFE,0x9C,0xBB,0xE7,0x8E,0xAD,0xC1,0x9A,0x52,0x48,0x1F,0xCC,0x2F,0xA0,0xAA, +0x6D,0x87,0xF1,0x54,0x5B,0xCD,0xA0,0xF6,0xBA,0x93,0x88,0x74,0xBF,0xA9,0x90,0xBF, +0x2C,0x66,0x24,0x10,0xDE,0x89,0x09,0x7D,0xD4,0x20,0x7E,0x7D,0x49,0xC0,0x88,0xC6, +0x55,0x13,0xF5,0xC3,0xFE,0xE5,0x51,0xC7,0xE3,0xF9,0xFF,0x20,0x31,0xA0,0x06,0xCF, +0x1B,0xE4,0xD0,0x86,0x8C,0x8F,0x22,0xC4,0x5F,0x0B,0x25,0x59,0xB2,0xEC,0x22,0x87, +0x99,0x46,0xB1,0x00,0x87,0x8B,0x04,0x55,0x86,0xE4,0xC9,0xD1,0x16,0xA9,0xB5,0x9E, +0x21,0x37,0x65,0xE1,0xF7,0x30,0xB5,0x76,0xB5,0x6A,0x7B,0x4E,0xEC,0x7C,0xDF,0x6E, +0xC4,0xCE,0x9E,0xE8,0x86,0x4D,0x7E,0x05,0x1F,0xCA,0xCA,0x59,0xC8,0x40,0x53,0xC6, +0xB7,0x7A,0x47,0x40,0x97,0x66,0x50,0xDA,0x58,0x18,0x9E,0x02,0x0D,0x16,0x4C,0x2E, +0x07,0x71,0xC4,0x5E,0x62,0x42,0xFD,0x07,0x6A,0x5B,0x4C,0xBA,0xDA,0x00,0xDE,0x2E, +0x8E,0x24,0x85,0x39,0xDB,0x08,0x23,0xDA,0xB4,0xB3,0xDE,0x60,0xB6,0xB9,0xBD,0x53, +0xF1,0x76,0x60,0x80,0x68,0xB9,0x82,0x03,0xFF,0xE8,0x6A,0x39,0xF0,0x50,0xEC,0x88, +0xCA,0x9D,0x87,0x24,0xA9,0x16,0x76,0xEE,0xA1,0xE7,0xEB,0x8E,0xFD,0x1E,0x57,0x8C, +0x69,0x16,0x67,0x74,0xCE,0xAA,0xAD,0x17,0x4A,0x96,0x20,0x69,0xFC,0x6C,0xB2,0xC6, +0xC0,0x5B,0x92,0x50,0x5B,0xAB,0x27,0x8E,0xAF,0x5E,0x6F,0xEB,0xC4,0xD7,0xB0,0xD3, +0xFA,0x32,0x45,0x78,0xAD,0x62,0xAE,0xB8,0xBF,0x24,0x96,0x65,0xCA,0x5C,0x4C,0x6D, +0x4B,0x3F,0xB0,0xF2,0xF2,0x1F,0x62,0x53,0xE6,0x45,0xFE,0x1D,0x43,0x27,0x27,0x1B, +0xF5,0x28,0x4A,0x10,0x5E,0xCE,0xAB,0xED,0xC5,0x13,0x9D,0x8A,0xEB,0x69,0x79,0xA2, +0x75,0x06,0xF8,0x85,0xD1,0xD7,0x64,0xC4,0x59,0x9B,0x8C,0x15,0x30,0xA9,0x2F,0x42, +0x0C,0x4D,0xE2,0x89,0xCC,0x29,0x2C,0x5B,0xE5,0xDD,0x18,0x94,0x75,0xE4,0x6F,0xF9, +0x7B,0xFA,0x73,0x7F,0x71,0x13,0x36,0x77,0x24,0x05,0xA0,0x74,0x92,0x0C,0xF4,0x8D, +0x73,0x44,0xEC,0x93,0xE6,0x51,0xFF,0xDB,0x2F,0xCB,0x9B,0x24,0x6B,0x88,0x2A,0x72, +0x5E,0xF3,0x4B,0x77,0x24,0x0F,0x34,0x15,0x88,0xB7,0x39,0x4F,0x93,0x80,0xEC,0xD1, +0x2D,0xA8,0xE3,0xA2,0x63,0xF4,0xD1,0x05,0xDA,0xC9,0x75,0x4D,0xA8,0xA8,0x8E,0x2F, +0x48,0xB6,0xC9,0xCB,0x6E,0x7A,0xDF,0xBD,0xD9,0xD7,0xD9,0x47,0xBA,0x17,0xA8,0xF6, +0x15,0x73,0x0C,0x5E,0x68,0xC4,0x2B,0xE9,0x4F,0x3B,0xB7,0x18,0x5D,0x22,0x0B,0x91, +0x8A,0xD8,0x4A,0x06,0xDF,0x58,0xF6,0x0B,0xBD,0xFC,0x2C,0x90,0xB9,0x8F,0xBF,0x77, +0xF1,0x2C,0x2A,0xE8,0x3A,0x35,0xE7,0xC2,0x91,0x60,0x26,0x48,0x85,0x77,0x4A,0xE3, +0x28,0xC3,0xFA,0xF8,0x0E,0xBC,0xC2,0x80,0xD3,0x70,0xD8,0xDA,0x4B,0x16,0x71,0x22, +0x76,0x4F,0x8D,0x03,0x9F,0x8B,0x13,0x32,0x2C,0x7F,0x2B,0xC3,0x95,0xA7,0x5D,0xFE, +0xFB,0x16,0xB0,0x79,0xDB,0x87,0x6E,0x30,0xEF,0xB0,0xA4,0xD0,0x3C,0x2A,0xFB,0xF1, +0x69,0xFD,0xD9,0xC1,0x48,0x40,0x7A,0x17,0x55,0x15,0x66,0x47,0x96,0x18,0x82,0x3B, +0x7C,0x94,0xEA,0xC7,0x71,0xC4,0x6D,0x7E,0x8A,0x2F,0x7A,0xDC,0x34,0xF0,0x96,0xF5, +0x12,0x6F,0xD0,0x11,0x51,0xD1,0xA9,0x29,0xEB,0xA1,0xBA,0xAA,0x7C,0x07,0xA9,0xA1, +0xD5,0x8B,0x64,0x80,0x5A,0x0B,0xE8,0x0E,0xFE,0xB4,0xEB,0x74,0xFB,0x8E,0xD3,0x93, +0xAD,0xA6,0xD0,0x96,0xE8,0x29,0x58,0xC8,0xA4,0x6D,0x0A,0x58,0x85,0x8C,0xB0,0x7D, +0x44,0x7E,0x07,0xC5,0xB0,0xD0,0x52,0x47,0xD9,0xDA,0x59,0x56,0x04,0xCB,0x00,0xCE, +0xBB,0xD5,0xBC,0x75,0x4C,0xA6,0xBB,0xFA,0x18,0x70,0x17,0x22,0x0F,0x11,0x22,0xAD, +0x8B,0x6F,0xBF,0xC1,0x34,0x0E,0xC9,0x0D,0x16,0x5B,0x82,0x93,0x9A,0xA9,0xD4,0xC2, +0x76,0x79,0xBF,0x66,0x7E,0xFE,0xC9,0x6F,0xE3,0x92,0xFA,0xCE,0x35,0x5F,0xEC,0x6A, +0x4C,0xC1,0x9D,0xF9,0x35,0x64,0x60,0x2F,0xAE,0x5F,0x40,0x64,0x3C,0xA4,0x9D,0xE9, +0x6E,0xD5,0x2D,0xAD,0x7F,0x75,0x00,0x38,0x90,0x5A,0xA9,0x8C,0xFE,0xE2,0x9A,0x11, +0x03,0xCB,0xA3,0x53,0x76,0x1A,0xC9,0xF6,0xE2,0x7D,0x50,0xE7,0x1B,0x8B,0x17,0xDB, +0x05,0x14,0x5F,0x26,0x2A,0xDF,0x3E,0x14,0x36,0x1C,0x1D,0xED,0x55,0x28,0x4A,0xCB, +0x98,0x91,0x7B,0x10,0x61,0x57,0xDD,0x76,0x10,0x93,0x4D,0x20,0x7F,0x75,0x1A,0x7B, +0x37,0x03,0xFE,0x6A,0x4E,0xFF,0x5B,0x76,0x9A,0x73,0x81,0x03,0x2E,0x0D,0x0E,0x1A, +0xDE,0x21,0xCA,0x0F,0x48,0x6B,0x73,0xA2,0xDD,0x24,0x96,0xCD,0x9E,0xD6,0x33,0x5A, +0x60,0x16,0xF8,0xD2,0x2F,0x21,0x11,0xEC,0xFE,0xB9,0xA3,0x6D,0x03,0x87,0x5E,0x9B, +0xA5,0x38,0x55,0x9C,0x9D,0x3D,0x83,0x85,0xBA,0xB0,0x59,0xDA,0xDB,0xB9,0xE3,0xDF, +0xEB,0x10,0x6E,0x7A,0x90,0xA2,0x88,0x1A,0x4F,0x65,0xA0,0xAF,0x34,0xCC,0xAC,0xFC, +0x71,0x70,0x99,0x13,0xE3,0x1D,0x60,0x35,0xFC,0x96,0x87,0xB1,0xEB,0x24,0x18,0x61, +0x6A,0xCF,0x04,0x81,0x34,0xD4,0x09,0x4E,0xE8,0x8C,0xF1,0x13,0x73,0x86,0x09,0x85, +0x51,0x6E,0x24,0xF9,0x66,0xFB,0x4F,0x3B,0x89,0x74,0x5A,0x9A,0xAC,0xAE,0x3B,0x8A, +0x2C,0x3B,0x9A,0x49,0xD1,0xAC,0xEC,0x87,0x99,0xA2,0xB5,0xA3,0x82,0x72,0xEA,0x16, +0xBB,0x3E,0x4C,0xD0,0xB6,0xAA,0x8E,0xB8,0x0D,0xC6,0xDC,0x63,0x73,0x9F,0x4B,0x8B, +0x6E,0x37,0xE5,0x49,0x71,0xE4,0x31,0x16,0xD9,0x16,0xAD,0xA4,0x94,0x29,0x9A,0xF1, +0x67,0x76,0x02,0x66,0x64,0x89,0x3B,0x87,0x4B,0xFD,0xEF,0x3E,0xB5,0x25,0x17,0xE3, +0xAD,0x85,0x17,0x58,0xAE,0x3B,0x68,0x5C,0xA4,0x74,0xC2,0x83,0x06,0xD3,0x3D,0xE2, +0x8B,0x24,0xAC,0x7C,0x1E,0xE5,0xE6,0x88,0x6E,0x56,0xC6,0x72,0x23,0x4A,0x5F,0x8C, +0x92,0x87,0xFF,0x6D,0xA1,0xBA,0xA6,0x21,0x72,0x83,0x93,0x3E,0xEC,0xE8,0xBE,0x6F, +0xE0,0x54,0xFA,0xE8,0x0E,0x5F,0x29,0x34,0xED,0x35,0xCC,0xA2,0xFE,0x5B,0xEC,0x3E, +0x0D,0xE6,0xD2,0x6D,0x8F,0xAB,0x1E,0x47,0xCD,0x2D,0xA7,0x87,0x70,0x7B,0x3B,0x23, +0x42,0x3C,0x72,0x88,0x59,0x65,0x9A,0xC7,0x45,0xCA,0xE8,0xF0,0xF2,0x05,0x27,0x37, +0xA6,0x76,0x36,0x2A,0xE1,0xB7,0x0B,0xD9,0x87,0xEE,0xCB,0x58,0xBC,0x42,0x9F,0x88, +0xB2,0x5B,0xA8,0xD9,0xB9,0x2F,0x2A,0x60,0x05,0x48,0x79,0x28,0x34,0x2C,0x31,0x9B, +0x01,0xCF,0xAB,0x38,0x65,0x68,0x66,0x13,0x3B,0x60,0x33,0x1B,0x1C,0xD4,0xFE,0x70, +0x8C,0xF0,0x5B,0x08,0x57,0xF5,0x77,0xF5,0xE8,0x93,0xBE,0x3A,0xFA,0xBC,0x06,0x56, +0x75,0x37,0x7D,0x0A,0x03,0xDD,0x72,0x89,0x65,0xAE,0x9A,0x75,0xA4,0x9E,0xFE,0x43, +0xCC,0x73,0x38,0xC9,0x60,0x1A,0x5D,0x35,0x10,0xB2,0x4E,0x68,0x31,0xF2,0x96,0xEC, +0x55,0x6B,0xF1,0x76,0xD0,0x68,0xBA,0xC8,0x36,0x32,0x8F,0x65,0x74,0x9B,0xF5,0x96, +0x77,0xB7,0x49,0x05,0xD6,0x6A,0x1E,0x00,0x0F,0xC2,0x0A,0xB1,0xA2,0xF5,0xF9,0xE4, +0x17,0xDB,0x80,0xEF,0x2D,0x92,0xAA,0x42,0xDB,0xD7,0xF3,0xF8,0x36,0x28,0x52,0xC2, +0x57,0x64,0x5A,0xD2,0xE8,0x93,0x8C,0x1B,0x6F,0x75,0xA1,0x27,0x81,0x6C,0xC6,0x7D, +0x0E,0xE0,0x37,0xC5,0x4D,0xD3,0xF4,0x81,0x66,0xAA,0x84,0xCE,0x24,0xCC,0x73,0xDF, +0x94,0x38,0x0C,0x95,0x9F,0xC3,0x68,0xBA,0xEB,0x9A,0x40,0x45,0x98,0x7B,0x49,0x23, +0xCB,0xB7,0x06,0xFD,0xCF,0x4A,0x55,0x09,0xFF,0x36,0x21,0x28,0x16,0x7C,0xF1,0xD7, +0xC6,0xEB,0xE6,0x17,0x3F,0x41,0xA9,0xCF,0xBE,0xBA,0x4F,0xBF,0x47,0x28,0x6B,0xA4, +0xFA,0x82,0x3B,0x0B,0x18,0x04,0x43,0x85,0xE1,0x1C,0x7B,0x24,0xF2,0x7D,0x2D,0x79, +0xA0,0x5C,0x80,0xE7,0xA0,0xFA,0x40,0xCE,0xCA,0x3D,0x63,0x6E,0x2B,0x48,0x12,0x8E, +0x86,0xFA,0x4E,0xF7,0xEA,0xBE,0x04,0x9F,0x81,0x64,0x8D,0x74,0x5C,0x65,0x5C,0x5B, +0x57,0x7F,0x1A,0x43,0xDD,0xAC,0xD8,0xD6,0xA5,0x0C,0x95,0x0E,0xC3,0x05,0x1F,0x4F, +0x27,0xD0,0x09,0xF2,0x51,0x59,0x52,0x89,0xEB,0x6C,0xA8,0x64,0x28,0x3D,0xEB,0xD4, +0xEF,0x2B,0xD5,0x6C,0x83,0x78,0xC6,0xE6,0xD2,0x7D,0x00,0x37,0x92,0x50,0xAE,0x57, +0xB8,0x95,0xBF,0xAF,0x66,0xCE,0x9D,0x49,0x20,0x77,0x0E,0x69,0xE2,0x37,0xB7,0xAC, +0x87,0x14,0x57,0x0E,0x72,0x19,0x0B,0x6D,0xE5,0xCF,0x25,0x87,0x36,0x31,0xD0,0x19, +0xB2,0x36,0x40,0x0D,0x22,0xD7,0x4F,0xD1,0x29,0xEB,0xF9,0x73,0x3B,0x97,0xFD,0x42, +0x0F,0x04,0x00,0xBA,0x07,0x2D,0x48,0x06,0x88,0x87,0x1C,0x84,0xE1,0xB4,0xAD,0x87, +0x7D,0x31,0x2E,0x7E,0x18,0x85,0x96,0x17,0xF8,0x3F,0xDD,0xF4,0x6D,0x0C,0x63,0xBF, +0x69,0xFB,0x51,0x70,0xC6,0x2A,0xE8,0xD5,0xBF,0x8A,0x97,0xA5,0x02,0xE3,0x0F,0x94, +0x43,0x35,0xB1,0x5E,0x3E,0x54,0xAD,0x0C,0x51,0xAF,0xF6,0x1E,0x11,0xF1,0x3A,0x17, +0x66,0xAF,0xAF,0x35,0x08,0xAC,0x7F,0xF6,0x72,0xF8,0x38,0x67,0xE6,0x76,0x7E,0xF3, +0x29,0xFE,0x69,0xED,0x4A,0x8D,0x3C,0xBE,0x2F,0x32,0xE6,0xCA,0xEC,0xAC,0xA5,0x24, +0xC4,0x27,0xE1,0x15,0x59,0x75,0x13,0x90,0xCD,0x5F,0x9F,0xAD,0x7A,0x22,0x35,0x32, +0x44,0x65,0xC6,0x45,0x44,0xBD,0x53,0xC3,0xB0,0xBA,0x5A,0xAB,0xA5,0x00,0x53,0xBF, +0xA9,0x5F,0x9C,0x85,0x8E,0xA4,0xFE,0x5C,0xEF,0x64,0x05,0xDB,0x01,0xEB,0xE0,0x98, +0xBB,0x48,0xDB,0x69,0xF9,0x4F,0x42,0xEA,0x5A,0x1D,0xB9,0x9D,0xF5,0xB9,0xE0,0x57, +0xDD,0x68,0xEA,0x6A,0xAD,0x42,0x5F,0xEC,0xCF,0x35,0x3D,0xC7,0xDA,0xDF,0xF1,0x01, +0xD0,0xE2,0xC7,0xE1,0xF8,0x11,0x82,0x1E,0x5F,0xC8,0xD0,0x8A,0x6B,0x08,0xEE,0x73, +0xB9,0x31,0xDC,0xE9,0x28,0x43,0x5A,0x73,0x0E,0x22,0xED,0x2D,0x1C,0x8A,0x31,0xE3, +0x75,0x8E,0x26,0x63,0x07,0x50,0x72,0x4B,0xB4,0x3E,0x9C,0x47,0xF4,0xD0,0x41,0xFF, +0x6A,0x90,0x90,0x72,0x21,0xAB,0xE6,0x42,0x13,0x97,0xE2,0xC6,0x1C,0x4A,0x08,0x9B, +0xFC,0x10,0x62,0xE8,0x1A,0xD1,0xA5,0x8A,0x58,0xE2,0xD2,0x5F,0x79,0xC0,0xD0,0x16, +0x4A,0x52,0xEA,0x0C,0x7B,0x55,0x55,0xED,0x53,0x6A,0x50,0x5F,0x3C,0xAF,0xCA,0xD6, +0x4F,0xC2,0xE1,0x92,0xEF,0xBF,0xA6,0xF4,0x57,0x3E,0x8A,0x49,0xF4,0x8E,0x99,0xD7, +0x2A,0xCB,0xE1,0x07,0x44,0xDB,0x25,0x9D,0x3C,0x3A,0xB5,0xA9,0x05,0x38,0x7C,0x06, +0x9A,0x9C,0xC2,0x43,0x2E,0xE0,0xE6,0x4E,0xDA,0x74,0x08,0xFD,0xD8,0xFC,0xCE,0x2E, +0x92,0x76,0xAE,0x69,0x94,0x9C,0x6D,0xAE,0x39,0x2E,0x16,0x74,0x87,0xA4,0x14,0xC4, +0x5F,0x5A,0x34,0xF3,0xCE,0x7A,0xF5,0x78,0x9A,0x9C,0xEF,0xFE,0xAE,0x1B,0x3A,0xE0, +0x18,0xC8,0x03,0x0A,0x13,0x2B,0x9A,0x3A,0x43,0xC6,0x93,0x28,0xF4,0x05,0xDD,0x9D, +0x36,0x4E,0x14,0xBA,0x6E,0x7E,0x42,0x2C,0x17,0x64,0x3D,0x93,0xAC,0x18,0x8B,0xD9, +0x51,0xCA,0x4D,0xAA,0x29,0x3B,0xDB,0xF4,0x0F,0xD5,0x91,0xC4,0xD0,0x0D,0x0C,0xCD, +0x04,0x10,0x74,0x36,0xAF,0xF2,0xA2,0x88,0x8D,0x72,0x67,0x42,0x88,0x57,0xD6,0x5A, +0x02,0x31,0x51,0xDB,0xA3,0x3A,0x72,0xF5,0x9D,0x9F,0xE4,0xE6,0x31,0xE5,0x98,0xB9, +0x6C,0x9E,0x5D,0x0C,0xF0,0xD3,0x89,0xC1,0x1C,0x32,0x02,0x8A,0xB1,0x8F,0x66,0x30, +0x81,0x0A,0x00,0x98,0xCD,0x4B,0xF2,0x7D,0x9D,0x6B,0x2F,0x9F,0x13,0x1E,0x36,0xD2, +0x25,0x31,0xAC,0x37,0x42,0xD4,0x12,0x41,0x40,0x8A,0x53,0x8D,0x75,0xD8,0x74,0x2F, +0xFE,0x63,0xF5,0x17,0xD0,0x17,0xC1,0x58,0x46,0x42,0xB2,0x0B,0xD6,0x3E,0xA5,0xBF, +0x40,0xC3,0x99,0x99,0x4B,0xB6,0xD9,0xA4,0x13,0x01,0xAD,0xCA,0x67,0xE7,0xCD,0x7A, +0x5B,0x10,0x17,0x4A,0xB5,0x5D,0x68,0xCB,0x7F,0x74,0xF0,0x74,0xB2,0x92,0x22,0xAB, +0x62,0x43,0x0E,0x13,0xB7,0x4E,0x09,0x56,0xBC,0x48,0x7B,0x6A,0x66,0x92,0x78,0xDC, +0x76,0xAD,0x25,0x21,0xDB,0x20,0xA7,0xF0,0x7A,0x15,0x64,0xC4,0x66,0x27,0xB9,0xEC, +0x58,0xBF,0x74,0x8B,0x56,0xF2,0x91,0x6D,0xF5,0x5E,0xFC,0x39,0x64,0x44,0xD7,0x13, +0x65,0xEA,0x49,0xF1,0xFA,0x17,0x02,0x39,0x25,0xF6,0xE3,0x74,0x3C,0x48,0xE2,0x16, +0x4F,0x9E,0x17,0x69,0xD9,0x51,0x79,0xC2,0xF8,0x0D,0x39,0x71,0xF3,0x3B,0x7F,0x30, +0x3F,0x70,0x49,0xC1,0x2C,0x6F,0x96,0xA5,0xE4,0x83,0x9F,0xC7,0x38,0xC5,0x14,0x27, +0xDD,0x1D,0xC2,0xF6,0x2F,0x71,0x8B,0xF4,0x01,0xFA,0xFB,0xEF,0xCE,0x72,0xB9,0x06, +0xD0,0x33,0x88,0x8E,0x71,0x26,0x8D,0x1E,0x04,0x86,0xD1,0xB7,0xCF,0x63,0x30,0x51, +0x03,0x44,0x50,0xC3,0xB8,0x0A,0x51,0x4E,0x12,0xF3,0xBD,0x73,0x5A,0xCB,0xFD,0x4F, +0x7B,0x03,0x4C,0x58,0x99,0xBB,0x40,0xC5,0xCF,0xFD,0x2F,0x30,0x11,0x70,0x24,0xA2, +0x90,0x5D,0xF7,0x27,0x0E,0x68,0x4C,0x61,0x34,0x33,0x33,0xC8,0xCF,0x1A,0x9D,0x37, +0x1A,0x8F,0x71,0xBA,0x7E,0xDD,0x00,0x6B,0xEF,0x8C,0xBD,0x87,0x8C,0x02,0x0F,0xA7, +0x30,0x22,0x9E,0xB6,0xE8,0x5E,0x1A,0x3A,0x49,0x07,0x54,0x16,0x09,0x91,0x74,0x53, +0x56,0xAA,0x72,0xDF,0xC9,0x40,0xD6,0x07,0xD6,0xBF,0xD3,0x67,0x61,0x8E,0xC9,0x3E, +0x74,0x13,0x26,0xA2,0x72,0x5A,0xB8,0x1D,0x9E,0x10,0x1C,0x73,0x26,0x51,0x94,0xA2, +0x21,0x8E,0xED,0xEE,0x40,0x4E,0xEE,0x89,0xD8,0xC0,0x81,0xF8,0xCD,0xD2,0x75,0xBF, +0xD7,0x71,0x21,0xBA,0xE2,0xA7,0x5C,0x6F,0x90,0x16,0xBA,0x49,0x9D,0xD3,0xDF,0xE6, +0x78,0x16,0xF3,0x13,0xC1,0x8E,0xB2,0xCA,0x01,0x22,0x1C,0xB8,0x77,0x64,0xBF,0x4C, +0x2A,0xC3,0xE3,0x47,0xBD,0x07,0x60,0xC7,0x77,0x6E,0x90,0x08,0x32,0x2C,0xFC,0x10, +0x22,0x63,0x7F,0x16,0x6E,0xA6,0x19,0xBE,0x4B,0xC4,0xA1,0x38,0x11,0x54,0x60,0x23, +0xE7,0xD6,0x95,0x0A,0x41,0x4E,0xC5,0xCB,0xAC,0xF1,0xF3,0x04,0xAA,0x8A,0x51,0x3B, +0x8A,0x65,0xBD,0xF5,0xED,0xF8,0x87,0x0C,0xAC,0x2E,0x37,0xFD,0x29,0x0C,0x55,0x43, +0x2E,0x70,0x54,0xFE,0x03,0xB5,0x41,0x09,0x62,0x39,0x5C,0x60,0x4E,0xB7,0x87,0x5E, +0x61,0x38,0x37,0xEB,0x9B,0x3F,0x4F,0xCE,0xA7,0xC1,0x68,0xD5,0x77,0x7D,0x3D,0x50, +0x86,0x42,0x0D,0x36,0x6C,0x79,0x89,0x31,0x2E,0x49,0xC1,0x20,0x44,0xCC,0x9D,0x2C, +0xB8,0xCB,0x73,0xAE,0x60,0x7F,0x0F,0x62,0x6A,0xBE,0xBE,0x92,0x24,0xB6,0x5F,0x7F, +0xFB,0xA5,0xAB,0x6D,0x44,0xC4,0xFD,0x1D,0xC2,0xDA,0x78,0x84,0x5B,0xA8,0x93,0x66, +0xF8,0x45,0xE9,0xDA,0x1A,0xD3,0x31,0xAC,0xDA,0x24,0x13,0x6E,0x42,0xE5,0x34,0x8E, +0xB0,0x0F,0xD1,0xEF,0x23,0x57,0x31,0xF4,0x49,0x84,0x33,0xAC,0x2E,0xDA,0xBD,0x94, +0xC3,0x01,0x98,0x16,0x94,0x35,0x56,0xE3,0x30,0x01,0x0B,0x34,0x83,0xD7,0xB5,0x19, +0x98,0xDB,0x62,0x50,0x70,0xF9,0xF5,0xB8,0x92,0x15,0xF8,0x5E,0xDD,0x0F,0x06,0xF7, +0xDD,0xDC,0x2D,0x21,0xC2,0xD6,0xDA,0x26,0xD9,0x06,0x2F,0x4E,0xCD,0x39,0x84,0xCB, +0x2F,0x90,0x77,0xFF,0x45,0xDF,0xAA,0x3C,0x53,0xEE,0xE2,0x67,0xEA,0x96,0x24,0x0F, +0x9F,0xB8,0xBC,0xA5,0x91,0x99,0x7B,0x47,0x54,0xC0,0x64,0x74,0x6A,0x7A,0x37,0x8C, +0x78,0xCC,0x60,0xFB,0xCE,0xAF,0xAE,0xC8,0xB5,0xE4,0x47,0x7E,0x97,0x92,0x6A,0x0D, +0x92,0x1A,0xCA,0x34,0x1D,0xAE,0x29,0xE1,0xAE,0x1D,0xF1,0x54,0x7F,0x38,0xD4,0xD6, +0xD3,0x56,0xFE,0xCC,0x50,0x84,0x46,0x25,0x4B,0xA5,0x43,0x0F,0x9D,0x22,0x08,0x8D, +0x28,0x90,0xC2,0x1B,0xC8,0x43,0x7B,0xB3,0x4A,0x34,0x94,0x62,0x18,0x06,0x52,0x1D, +0x4C,0x35,0xA4,0xE6,0x63,0x60,0x9A,0xFF,0x83,0x57,0xCA,0x63,0x71,0x04,0x9A,0x30, +0xD1,0x62,0x0D,0x7A,0x92,0x39,0xA7,0x2E,0x15,0x8B,0xA3,0x3E,0x28,0xC8,0x6C,0x72, +0xB3,0x36,0x1B,0x37,0x5C,0xB4,0x8C,0xE8,0x4E,0xCD,0x86,0xC0,0xF1,0xD5,0xAC,0x7A, +0x95,0x2D,0xB6,0xCC,0x31,0x4D,0x35,0x70,0xD5,0x62,0x3A,0x02,0x99,0xBB,0xC8,0x14, +0x56,0x7F,0x81,0xE6,0xB8,0xBF,0xA6,0x97,0x89,0x66,0x01,0xC9,0xAF,0x69,0x78,0x86, +0x63,0x50,0xFE,0xAC,0xBD,0xEF,0xA3,0xAA,0xAF,0x00,0x10,0x2E,0xA7,0x37,0x48,0x16, +0x01,0x04,0xF0,0xE5,0x7E,0xE8,0x62,0xC9,0x45,0xDC,0x60,0xD6,0x10,0x44,0xC6,0xF5, +0x30,0x9F,0x4C,0x6D,0x98,0x32,0x32,0x11,0x3A,0x56,0x6E,0xFF,0x8F,0x0B,0x7C,0xA1, +0x38,0xC3,0x6E,0xFB,0x77,0x98,0x93,0x95,0x59,0xB1,0x54,0x78,0x14,0xE2,0xB5,0xFA, +0xE5,0x09,0xC6,0x1E,0xAB,0x2A,0x10,0x8C,0x85,0x7F,0x37,0xBC,0x0A,0x2B,0x4D,0xD6, +0x02,0x47,0x8A,0x25,0xE3,0x79,0xFF,0xD4,0x47,0x2A,0x7E,0xD4,0x28,0x1D,0x19,0x83, +0x43,0xEA,0xE1,0xAF,0xF4,0xEF,0xDA,0x82,0xEB,0x76,0x79,0x7D,0x56,0xEA,0x1A,0x1F, +0x80,0x61,0xCB,0x57,0xFF,0x6C,0xE5,0x1F,0x31,0x3D,0xC2,0x4E,0xDD,0xEE,0xDB,0xDE, +0x7F,0x2D,0x58,0xF9,0x07,0xC7,0x1E,0x73,0xB2,0x02,0xAA,0x05,0xDC,0x59,0xDE,0xF8, +0x4C,0x0C,0xC1,0x4F,0xD5,0x25,0xDA,0x6C,0x49,0xB5,0x16,0xC4,0x73,0xF5,0x2C,0x2A, +0x96,0x31,0x8A,0x5B,0xD9,0x1D,0xA8,0xB0,0xF5,0x9D,0x08,0x8A,0xDF,0x5B,0x23,0x90, +0xFE,0x08,0x83,0x22,0x17,0xA1,0xF3,0xBD,0x76,0x22,0xE0,0x6D,0xF3,0xB7,0x0E,0x98, +0xDC,0xA9,0x5A,0xC6,0x97,0x78,0xA2,0x8F,0xDA,0xEF,0x2E,0x1C,0xD8,0x56,0xF4,0x50, +0xB8,0xB6,0x87,0x70,0xCD,0xA4,0x3F,0x0A,0x09,0x03,0xB0,0x27,0x32,0xF1,0x8B,0x34, +0xCA,0x86,0x7C,0x36,0x68,0x0C,0xE6,0x4E,0x85,0xC5,0xE4,0x61,0x6E,0xF1,0xE8,0xF6, +0xC1,0xFC,0x51,0x12,0x4F,0xD8,0x84,0x91,0x17,0x7A,0x7E,0x73,0x24,0xB0,0x91,0x29, +0xE4,0x87,0xF7,0xAA,0x79,0x21,0x78,0xC4,0x75,0x46,0xAB,0x04,0xB2,0x06,0xE9,0xC3, +0xFE,0xCF,0xFC,0xB1,0x61,0xFF,0x83,0xAB,0x40,0x8F,0x7C,0x12,0x33,0x71,0x4E,0xBF, +0xBF,0x01,0xDB,0xAB,0xF5,0xC2,0xEF,0xE7,0xD7,0x98,0x4E,0xBA,0xAF,0xF0,0x40,0x77, +0x98,0x11,0x02,0xCF,0xE1,0xED,0x7D,0xBD,0xE8,0x31,0xC5,0x8E,0x10,0x7D,0xFE,0x0F, +0xDA,0x07,0x87,0x86,0xC4,0x5F,0xDA,0x6A,0xCB,0xB2,0xB6,0xD2,0x54,0xF7,0x0C,0x1F, +0x3F,0x05,0x8D,0xC0,0x83,0xE0,0x4B,0x84,0x67,0x79,0xF9,0x4F,0xC4,0xB5,0x8F,0x6D, +0x75,0x19,0x11,0x6E,0xF4,0x19,0x9E,0x7A,0x64,0xE3,0x99,0x45,0x3C,0x7C,0x48,0x10, +0xE6,0x1B,0x30,0x1E,0x12,0xD7,0xB6,0x43,0x1A,0xD0,0x98,0x85,0x49,0x46,0x1C,0x69, +0x2C,0x13,0xEF,0xA9,0x22,0x2E,0x5A,0x1F,0xD1,0xF0,0x9A,0x51,0x43,0xC8,0x9F,0xBB, +0xC3,0x7F,0x75,0xC3,0xDE,0x7C,0x7B,0x8B,0x69,0x75,0xF5,0x2F,0x5F,0x48,0x67,0xD1, +0x61,0x75,0x50,0x1D,0x99,0xA2,0x14,0xE4,0xB6,0xD8,0xD0,0x21,0x1C,0x92,0xF6,0x8D, +0x07,0xAD,0x14,0xAB,0x4A,0x42,0x4B,0x6F,0x55,0x62,0xF9,0x39,0x8D,0xD0,0xF2,0xEA, +0x04,0x7E,0xFF,0x34,0xD6,0xE7,0x08,0x9A,0xE7,0x36,0x07,0xE0,0x3C,0xA2,0xE3,0xF6, +0x09,0x5E,0x4F,0x28,0x04,0xFD,0xC5,0x8D,0x28,0xCB,0xA6,0x1F,0x52,0xB0,0x90,0x19, +0x68,0xEB,0x67,0x66,0xE6,0xAF,0x6E,0xAC,0xB3,0x60,0xB4,0x75,0xED,0x63,0x64,0x43, +0xB8,0x16,0x2B,0x70,0x0F,0x12,0x0C,0x4B,0x92,0xED,0x19,0xD1,0x5A,0x4D,0x25,0xFA, +0x55,0xC4,0x64,0x09,0x6E,0x35,0x9B,0x74,0xCF,0xAE,0x17,0x25,0xE5,0xC6,0xBD,0x01, +0xB4,0x84,0x60,0xB0,0x34,0x42,0x12,0xEC,0xCE,0xFB,0x87,0x55,0x19,0xB0,0x05,0x52, +0x40,0xB0,0xB4,0xDE,0xD8,0x17,0xCE,0xF1,0x02,0x0E,0xFD,0xD7,0x09,0x78,0xF3,0xEF, +0x77,0x37,0x99,0x26,0xAE,0x68,0xFD,0x08,0x11,0x29,0x0A,0x71,0x80,0x8B,0xFD,0x0B, +0x5B,0x15,0xE3,0xD3,0x80,0xFA,0xCB,0x50,0xBD,0x0E,0xA1,0x64,0x54,0x31,0xCC,0x8D, +0x73,0x6F,0x99,0xB7,0x17,0xB7,0x50,0x0B,0x9C,0x41,0xF9,0x26,0x90,0xBA,0x52,0xDC, +0xCE,0x50,0x88,0x00,0x03,0xE7,0x5C,0xE9,0x33,0x9C,0x12,0xC9,0xE2,0x4E,0x4C,0x53, +0x1C,0xAB,0xB8,0xFA,0x91,0x53,0x6F,0x7D,0xF0,0x96,0xE4,0xF0,0xD9,0x31,0xC9,0x68, +0x4F,0x96,0x93,0xEF,0xCD,0x02,0x7B,0xBB,0x62,0x4F,0xD4,0x10,0xBF,0x10,0x0A,0xD0, +0x44,0x94,0xB1,0x1F,0xA8,0xAF,0xE8,0x71,0x87,0xAC,0xE1,0x0A,0x1F,0x61,0x18,0x0E, +0x1B,0x64,0x76,0x41,0xF7,0x78,0xA5,0xC7,0x13,0x10,0x22,0xB2,0x15,0x71,0x63,0x88, +0x12,0x88,0x1E,0x9A,0x35,0xCC,0xDC,0xAB,0x9F,0xC1,0x39,0xA5,0xD0,0x7D,0xE4,0xA2, +0x60,0x1E,0x76,0x1E,0x94,0xD7,0x6F,0x75,0x43,0x59,0xD4,0x57,0x4C,0x49,0x86,0x05, +0x42,0x84,0x9B,0x08,0x94,0x7C,0x2D,0x25,0x43,0x41,0x59,0x75,0x68,0xD7,0x80,0x73, +0x1D,0x90,0x6D,0xD7,0xB8,0xDF,0x50,0x04,0x95,0x28,0x29,0x27,0x74,0x0D,0xA8,0xAD, +0x1F,0x52,0x7C,0x0F,0xBE,0xE4,0xD2,0x1F,0x6E,0x29,0x2D,0x8C,0x6E,0x75,0x40,0xE4, +0xBC,0x82,0x33,0x82,0x3A,0xD1,0x91,0xF1,0x55,0xFE,0x7D,0x46,0xFF,0x8A,0x0E,0x78, +0x7C,0x7A,0xB6,0x47,0x2A,0xA2,0xED,0x52,0xF6,0xE3,0xFA,0x8A,0xF4,0x32,0xF1,0xD9, +0x26,0x22,0x7A,0x3C,0xF1,0xCB,0x73,0x55,0x66,0x49,0x89,0xE3,0xC7,0xCC,0x06,0x7E, +0x94,0xC9,0x42,0x23,0xB8,0x03,0x51,0x49,0xCC,0x70,0xB6,0x73,0x36,0x37,0xAC,0x62, +0xC4,0x55,0xB6,0x8F,0x17,0x5F,0x00,0xBD,0x64,0x01,0xA2,0x60,0xF7,0x47,0xF9,0xC2, +0x7A,0x63,0xBF,0x29,0x4D,0x14,0x67,0x82,0x3C,0x21,0x16,0x45,0x20,0x4D,0xD9,0x22, +0x05,0xD2,0xD3,0x40,0x38,0xD0,0xEF,0x42,0x76,0xA1,0x29,0xE5,0x84,0x2F,0x57,0x13, +0xFF,0x8C,0xAE,0x3C,0x32,0xF0,0xC2,0x7A,0x88,0x62,0xB6,0x19,0x56,0xD7,0xC0,0x40, +0xE3,0x1F,0xAF,0xB8,0x0E,0xED,0xA4,0x58,0x2B,0xDE,0x0C,0x68,0x58,0xAF,0xB1,0x4F, +0xE9,0x66,0x1D,0xB5,0x99,0xDB,0xEF,0x8D,0x63,0x9B,0xCC,0xC6,0x64,0xB7,0x12,0x30, +0x9D,0x7A,0xB1,0xF0,0xDC,0x59,0xCC,0x2A,0xD9,0x53,0x7A,0x54,0x04,0xAA,0x2B,0x86, +0x66,0x41,0xD5,0xFC,0x1A,0xF6,0xBD,0xE0,0x5B,0x23,0x04,0x9B,0x8B,0xDD,0x41,0xD3, +0x55,0xA8,0x76,0xB1,0xED,0xC5,0x90,0x5A,0x85,0x4D,0x1A,0x96,0x39,0xFB,0x00,0xA1, +0x30,0x34,0x02,0x62,0x4A,0xEA,0x99,0x43,0x85,0x84,0x18,0x65,0x5B,0xFC,0x5A,0x83, +0x20,0x2F,0xCB,0xE9,0xD2,0x84,0x38,0x71,0x21,0x4F,0x10,0xE2,0x33,0x18,0x3E,0xC0, +0xF5,0xF4,0xE0,0x61,0x01,0x6B,0xF6,0xF3,0x9D,0x3A,0xB6,0x04,0x11,0xB3,0x47,0x0E, +0x6E,0x13,0x24,0xB4,0x62,0x40,0xFD,0x41,0x80,0x68,0x1E,0xC7,0x34,0x25,0x65,0x2D, +0x0A,0x1A,0xD8,0x09,0x7C,0x32,0xA7,0xB2,0xDE,0x83,0x00,0xDA,0x04,0x23,0x78,0xEE, +0xD8,0xB9,0xDE,0xF4,0x32,0x31,0x56,0xA9,0x50,0x99,0x2D,0x81,0xAE,0x3A,0xB2,0xFD, +0x97,0x52,0xF6,0x91,0x50,0x3F,0x18,0xCC,0xE0,0x32,0x2A,0x82,0xDF,0x87,0x0D,0x6D, +0xA4,0xA6,0x45,0x37,0xB9,0x8F,0xB7,0x24,0xF0,0xF2,0x02,0x8F,0x45,0x67,0xB3,0xFE, +0xE9,0x49,0xD9,0x05,0xD1,0xFE,0x72,0x0F,0xA0,0xCA,0x94,0x7A,0x39,0x77,0x31,0x09, +0x13,0x62,0x29,0x7B,0x39,0x9E,0x13,0xE7,0x17,0x40,0x1F,0x0B,0xCC,0x09,0x05,0x6D, +0x6C,0xE6,0x8B,0x38,0x4B,0x91,0x8A,0x61,0x6C,0xA4,0x6E,0x00,0x9D,0xDB,0x71,0xDA, +0x7F,0xDB,0xD5,0x5F,0x65,0x92,0x33,0xF1,0x23,0xB1,0x25,0x62,0xC5,0xDD,0x14,0xCB, +0x3C,0x4A,0x57,0x8D,0xD6,0xAF,0xD6,0xA0,0x57,0xB5,0x79,0x63,0x96,0x00,0x02,0xB5, +0x05,0xD6,0x0A,0xE5,0x83,0x7E,0xFA,0xFD,0x21,0x9D,0xC5,0x3A,0xBE,0x35,0x7B,0xAE, +0xB6,0x7B,0xE6,0x47,0xB5,0x3E,0x34,0xD5,0xA5,0x0A,0xFD,0xAD,0xA1,0xE7,0x99,0xE9, +0xCD,0xF0,0xA8,0xD0,0xCF,0x1E,0x2F,0xA7,0x6C,0xB0,0x05,0x52,0xB7,0xDA,0x57,0x79, +0xB1,0x30,0x36,0x50,0xF3,0xBB,0xB0,0xA3,0xB6,0x78,0xFF,0x6A,0x95,0x71,0x75,0x47, +0xE2,0xCC,0x64,0x06,0xDE,0x80,0xEA,0x06,0xC7,0x87,0x09,0xA5,0x78,0x3A,0x5F,0x47, +0x6C,0x72,0x89,0xB4,0xE3,0x92,0xC7,0x4F,0x4C,0x15,0xE7,0xC1,0x12,0x77,0xC2,0x07, +0x8F,0xD0,0x6D,0x6B,0xD2,0xFA,0xCD,0x27,0x78,0xB0,0xB8,0x73,0x3C,0x94,0xF3,0x01, +0x74,0xC9,0x54,0x1D,0xA8,0xDE,0xBF,0xEE,0x18,0x2F,0x63,0xA7,0x8F,0x73,0x4D,0xF8, +0xDC,0x67,0x53,0xFD,0xFA,0x69,0xD3,0x13,0xA6,0xD9,0x7D,0x0C,0xC0,0x87,0x8F,0x6F, +0xED,0x11,0xD5,0xBC,0x39,0xAB,0x7F,0xB8,0x42,0xE4,0xA8,0x03,0x30,0xF7,0xCE,0x1B, +0xD7,0xF5,0xD9,0x82,0x7A,0x90,0x28,0xCE,0xD7,0x31,0xC0,0x50,0x73,0x7A,0xE3,0xFC, +0xCA,0x97,0x33,0xAF,0x89,0x82,0xC1,0x7D,0x76,0x12,0x2D,0x9B,0xB4,0xFC,0x4C,0x7B, +0x53,0x6E,0x17,0x6E,0x2B,0x05,0x37,0x20,0xF4,0x5D,0xBD,0xB0,0xBA,0x26,0xB3,0x61, +0x91,0x14,0x29,0x35,0x31,0x1D,0xAC,0x67,0x69,0xC6,0x78,0x99,0x85,0x4F,0x31,0x97, +0x0C,0x95,0x2B,0x15,0xD0,0xB1,0x41,0x00,0x4C,0x95,0x8E,0xC0,0xF9,0x17,0xBB,0x5A, +0x0F,0x96,0x1C,0x04,0xDA,0x9E,0x66,0x31,0x72,0x48,0x98,0x89,0xFB,0xF6,0x62,0x52, +0x47,0x33,0xF2,0x55,0xE3,0xA6,0x45,0x03,0xE4,0x9F,0xB1,0x46,0xE7,0x39,0x36,0x8E, +0x8A,0xCB,0x69,0x75,0x39,0x43,0xDD,0x98,0x89,0x2A,0x8D,0xDC,0x39,0xF0,0xDF,0x49, +0x26,0x13,0x62,0x1B,0x29,0xF6,0x6D,0xB0,0xE8,0xA8,0x28,0x78,0x8A,0xFC,0xB0,0x1A, +0xFF,0xC5,0xFE,0xA8,0xA0,0xE0,0xB5,0xD0,0x23,0x68,0xAC,0x9E,0xEF,0x5E,0xFC,0x81, +0x06,0xC8,0x4E,0x18,0xFC,0xFC,0x0C,0x38,0x86,0xEC,0xEB,0xEC,0x28,0xDE,0xCA,0x9F, +0x30,0x44,0x71,0x91,0x2B,0x8B,0x9A,0xA2,0xED,0xE2,0x91,0xC8,0x6E,0x2D,0xC2,0x62, +0xA0,0x0D,0xFF,0x65,0x4F,0xD9,0xC3,0x1D,0xCF,0xE0,0x20,0x35,0x60,0x3B,0x10,0xE9, +0x34,0x4E,0xC2,0x7C,0x1E,0xB4,0xDE,0x10,0x7B,0xA9,0xD1,0xA5,0xD9,0x19,0x5D,0x7B, +0xF8,0xA6,0xA4,0x05,0xF1,0x17,0x3F,0xD7,0x56,0x16,0x41,0x43,0xDB,0xDA,0x30,0x5B, +0xE5,0x71,0xAD,0x07,0xDC,0x67,0x37,0x99,0x07,0x53,0xE2,0x06,0x73,0x3E,0x4C,0xF6, +0x42,0x8E,0x93,0xC9,0x0A,0x04,0x18,0xDB,0x58,0x30,0x00,0x05,0xEE,0xC0,0xB8,0x08, +0x00,0xB0,0xD0,0x36,0x66,0xAA,0x0B,0x95,0xB2,0x0D,0xAB,0x49,0xB0,0x91,0x42,0x2D, +0xC0,0x96,0x97,0x59,0xC3,0x05,0x39,0xEE,0x3E,0xC7,0xCC,0x18,0x5D,0x31,0xFB,0xEF, +0x6C,0x2B,0x80,0x5B,0x30,0x36,0x1B,0x79,0x4C,0x01,0x64,0x78,0xC0,0xC8,0xD9,0xE0, +0x12,0x75,0x60,0x76,0x21,0xF3,0x8F,0x61,0x04,0x91,0x7D,0x7B,0xED,0x43,0xC3,0xE1, +0xFE,0x79,0x2A,0x85,0x87,0x21,0xCA,0x6C,0xFF,0xC4,0xC8,0x63,0x31,0x2F,0xFD,0x04, +0xC3,0x50,0x9A,0xC1,0x78,0x2F,0xC0,0xF2,0xF1,0x97,0x7C,0xCD,0x22,0x26,0xDC,0x26, +0x1B,0xFF,0x97,0x89,0xA0,0x9A,0x1F,0x2B,0xFC,0x6E,0x14,0xE2,0x2E,0x4B,0xBE,0xCB, +0xC6,0x30,0x30,0xFA,0xA5,0x09,0x52,0x93,0xE5,0x4F,0xDC,0x9A,0x49,0x5D,0x0B,0x61, +0x42,0xD2,0x63,0xB5,0xF1,0x6A,0xD1,0xEE,0x65,0x01,0x6C,0xDE,0x94,0x1A,0xB0,0xAF, +0xEB,0xB5,0x1A,0x8E,0xE8,0x95,0x89,0xEA,0xEC,0x1A,0x28,0x7E,0xB0,0xA4,0x6B,0x5C, +0x2D,0xDF,0xB5,0xA6,0xC4,0xD2,0x6D,0x62,0x38,0x9C,0xA2,0x1B,0x32,0x96,0x25,0xF0, +0x85,0x39,0xDC,0x9F,0x2C,0x6B,0xFA,0x9F,0xA5,0x46,0xC8,0xFB,0x36,0x1B,0xFD,0x51, +0x14,0x0D,0x2E,0x0D,0x84,0x6B,0x52,0x3F,0xBB,0x8C,0xD7,0x32,0xA2,0x76,0x34,0xEA, +0x15,0xB6,0x05,0x54,0x88,0x32,0x80,0x4A,0xB8,0x5E,0xFA,0x31,0x62,0x41,0xDB,0x37, +0x21,0x66,0x47,0x5A,0xDF,0x7C,0xA8,0x4F,0x3E,0xBC,0x22,0x59,0x26,0x42,0xD7,0xCC, +0x5D,0x3E,0x37,0x54,0xB1,0x0A,0xF7,0xD1,0x7D,0xD2,0x41,0xB7,0xEE,0xE1,0xC9,0x10, +0xDC,0x7B,0x28,0x09,0x30,0x32,0xEF,0x72,0x2B,0x11,0xE1,0xB9,0x38,0xDB,0x94,0x5E, +0xE0,0x4F,0x65,0x3E,0x02,0x9A,0x0F,0x5F,0x0C,0xC7,0x19,0xF5,0x5C,0x90,0x92,0xA5, +0xA8,0xBB,0xAF,0xDD,0xDA,0xD5,0xF1,0xF6,0x4A,0x50,0x95,0x2B,0x1A,0x96,0x0D,0x42, +0x70,0x61,0x35,0x73,0x01,0xB6,0xEF,0x40,0xA9,0x62,0x91,0xAB,0x3C,0x70,0x12,0x6F, +0x71,0xD1,0x45,0x93,0xCE,0x24,0x6B,0x12,0xB8,0x24,0x2D,0xBD,0x2B,0x3D,0x2F,0x52, +0x2E,0x66,0x49,0xEB,0xBD,0xE4,0x0F,0x56,0x17,0xCC,0xDD,0x7E,0xB3,0xAB,0x8B,0x81, +0x54,0x4A,0x49,0x63,0x45,0xC8,0xCF,0x67,0xB4,0x1F,0x33,0xF5,0xA0,0xD9,0x79,0xFF, +0x87,0xF9,0x9F,0xA7,0x06,0xE9,0x1E,0x50,0x75,0x29,0xA4,0xEA,0x57,0xB9,0xA5,0x8E, +0x33,0xAD,0xC4,0xF5,0xCB,0x0C,0x58,0xCC,0x57,0x1B,0x36,0x3A,0xB0,0x8C,0x26,0x9B, +0xDC,0x1E,0x41,0x44,0x2F,0xC2,0x5F,0x52,0xF2,0xDF,0x1C,0x51,0xFA,0x45,0xFD,0xE1, +0xFA,0x8B,0xE6,0x2B,0xBA,0xDD,0x53,0xAD,0x77,0x02,0x30,0x30,0x91,0xA5,0xFD,0x3B, +0x92,0xF8,0xCD,0x76,0x3B,0xF2,0xD2,0x84,0xFF,0x81,0x69,0xF4,0x9D,0x5C,0x88,0xEA, +0x98,0x25,0xBC,0xD7,0xDB,0xD6,0xC7,0x0B,0x87,0x49,0xAA,0x9E,0x21,0x0B,0x4B,0x61, +0xC1,0xB2,0x1F,0x67,0x8B,0x57,0xBF,0xC9,0x8D,0x26,0x21,0x7A,0x23,0x39,0xC8,0xA5, +0x1B,0x02,0x85,0x81,0xD4,0x1D,0xC3,0x6D,0xB0,0x42,0x5A,0xDB,0x35,0x25,0xC5,0xCC, +0x43,0xF5,0x0F,0x8C,0xB8,0x6D,0xD1,0x54,0xDE,0x30,0xAC,0x5B,0xE2,0xC1,0xB9,0xF6, +0x2E,0xC9,0x4A,0xB7,0xF7,0xFD,0x44,0x9B,0xC9,0x89,0x81,0x78,0xBC,0xC7,0x9E,0xB0, +0xD3,0x6C,0x0A,0x64,0xBB,0xE5,0x84,0xFB,0x9A,0xE3,0x6B,0xF4,0x9A,0x6D,0xA1,0x62, +0xA7,0x8A,0xA0,0x17,0x1D,0x43,0x2D,0x51,0xC3,0xFE,0xB4,0xD8,0x6D,0xC7,0xF4,0x4F, +0xFD,0x0D,0xD1,0xAD,0xE1,0xBB,0x5F,0x42,0xCB,0x6F,0x6D,0xD8,0x56,0xF9,0x58,0x54, +0xCE,0x33,0x1A,0x60,0x7C,0x2C,0xB9,0xB1,0x55,0xDE,0xFC,0x17,0x2F,0x5D,0x8F,0x7F, +0x9D,0xF2,0xB1,0xB6,0xDA,0xCA,0x29,0xDD,0xDE,0x74,0xFC,0xC4,0xF9,0x1B,0x15,0x79, +0x20,0xA4,0xB8,0xB9,0xBD,0xDC,0xDA,0x38,0xCB,0x8D,0x30,0xB9,0x05,0xE5,0x12,0xB2, +0x93,0x9C,0x32,0x0E,0x08,0x00,0x43,0x94,0xFF,0x32,0x44,0x05,0x4C,0x6C,0xFC,0x99, +0x79,0x6F,0xCE,0x78,0x58,0x9E,0x0D,0xD5,0xA5,0xC8,0x73,0xA9,0xF9,0xE5,0x41,0x3E, +0x67,0xB4,0x9F,0x88,0x68,0xFD,0x92,0xB6,0x28,0x4B,0xC6,0xBE,0x82,0xC6,0x51,0xC0, +0xD4,0x07,0x0E,0x5A,0x6F,0x5B,0x18,0xB5,0xD8,0x65,0x46,0x41,0xF1,0xA8,0x6B,0x7E, +0xB8,0xEC,0x2F,0x93,0xB3,0x62,0x03,0x0C,0x99,0x39,0xB6,0x43,0xA5,0xEB,0x06,0x68, +0x7D,0x8E,0xA4,0x84,0xFE,0x6B,0x8C,0xAD,0xB7,0x21,0x47,0x39,0x5A,0xAE,0xDC,0x4A, +0x1D,0x94,0xED,0x29,0x92,0x6E,0x5D,0x75,0x1D,0x1E,0xFB,0x7E,0xED,0x11,0x59,0x47, +0x5C,0xE2,0xF0,0xFB,0x82,0xA3,0x1E,0xC6,0x13,0x9C,0x96,0x8B,0xFD,0xAA,0xBB,0x9A, +0x35,0x77,0x7A,0x2B,0x0D,0x14,0x5D,0xA7,0xA1,0x84,0xB1,0x50,0xC4,0x03,0xAE,0x00, +0xC8,0x8B,0x21,0xCD,0x3C,0x54,0x86,0x2F,0xD3,0x3F,0xC7,0x35,0x53,0x9E,0xDA,0xF8, +0x30,0x25,0x04,0x16,0x42,0x54,0x33,0x0E,0xD4,0x35,0x26,0xE6,0xFA,0xF6,0x1E,0x85, +0x75,0x2F,0x40,0x10,0x70,0x04,0xBC,0x2D,0x73,0x87,0x26,0xEB,0xB1,0x50,0x95,0x97, +0xF6,0x84,0x18,0x4D,0x97,0x7B,0x0A,0x03,0xF4,0xA2,0x83,0x98,0x24,0x17,0xCC,0xED, +0x20,0x20,0xCF,0xD1,0x2B,0x27,0x96,0x0B,0x2E,0x99,0xBE,0x7E,0x1D,0x7B,0x49,0x98, +0xB9,0xCD,0x33,0x59,0xA3,0x97,0xB0,0x86,0x20,0x86,0x50,0x25,0xEA,0xF5,0x17,0x17, +0x74,0xF7,0x40,0x92,0xE7,0x18,0xC4,0x06,0xAE,0xF9,0x63,0x32,0xA8,0x82,0xE6,0xD7, +0xB1,0x0C,0xF7,0x5A,0x50,0x6F,0x80,0xFC,0xB5,0xE7,0x93,0xFD,0xC1,0x9A,0xC0,0x7C, +0x1D,0x86,0x34,0x88,0xA4,0xF5,0x32,0x7E,0xF4,0x23,0x80,0x01,0xF8,0xC7,0x2B,0x89, +0x72,0x6E,0x7C,0x06,0xBE,0xA9,0x5A,0x15,0xC8,0xEF,0x97,0x0F,0xFE,0x90,0x87,0x9D, +0xF6,0x67,0xB8,0x8D,0xC3,0xD0,0x30,0x3B,0xF0,0x5C,0xB2,0xA0,0xA7,0x3E,0x5C,0x59, +0x4F,0xE3,0x34,0x0E,0x26,0xF2,0xAC,0xC4,0xD9,0x5B,0x57,0x50,0xC6,0xAF,0x82,0x7D, +0x67,0xBD,0x64,0x3D,0x50,0x43,0x79,0xF8,0xE1,0xB2,0x7A,0xEA,0x22,0xED,0x75,0xC1, +0xDB,0x77,0x1D,0x82,0x63,0xCF,0xCF,0x50,0x0F,0xDF,0x89,0x8A,0xA6,0x4C,0xCA,0xF1, +0x94,0x8D,0x8B,0xE4,0x20,0x24,0xA8,0x34,0x05,0x87,0x68,0xEE,0xF4,0x7E,0xA8,0x9F, +0x59,0x7F,0x0D,0xEE,0xDD,0xF3,0x99,0x40,0xD9,0x25,0x8E,0x36,0x8B,0x0A,0x51,0x3C, +0xDD,0x95,0x30,0x42,0xA5,0x39,0xB9,0xF4,0x4A,0xFC,0xAD,0x1B,0x29,0x96,0x54,0x5F, +0xC1,0xED,0x40,0x70,0x37,0x89,0x51,0xF8,0xCC,0xFC,0xD0,0x1A,0xE3,0x1E,0x52,0xE9, +0x2F,0x5A,0x01,0xD1,0xB1,0x41,0xEC,0x4B,0x76,0x0C,0xD2,0x79,0x28,0x2A,0x52,0x7E, +0xBF,0x4F,0xA9,0xE8,0xFF,0x2F,0x8A,0xE1,0x35,0xA6,0x8E,0x1A,0xB4,0xEE,0x56,0xF2, +0xFF,0x0E,0x96,0xFF,0x5B,0x77,0x90,0xEA,0xEA,0xC6,0x72,0xDE,0x7D,0x40,0x3C,0x1B, +0x05,0xD4,0x95,0x1A,0x5F,0x09,0xE6,0xBA,0x96,0xCC,0x55,0x65,0x51,0xF8,0x20,0x6E, +0x4A,0x87,0x62,0xEB,0xBC,0x68,0xB4,0x0F,0xD4,0x5B,0x93,0x92,0x6F,0x81,0xD2,0xA7, +0x8F,0xFA,0x7B,0xC7,0xEE,0x79,0xB9,0x90,0x15,0xE4,0x32,0xE2,0x6A,0x05,0x3F,0xDC, +0x5F,0x96,0xD3,0x13,0x84,0x2D,0xF3,0x3A,0x6E,0xF8,0x63,0xB2,0x3A,0x53,0xDF,0xCD, +0x56,0x89,0xAB,0x88,0x81,0xC4,0xDF,0x34,0x0E,0x82,0xF7,0xF7,0x7E,0x4F,0x22,0xAE, +0xCF,0xF6,0xC3,0x5C,0xDF,0x1A,0x64,0xCE,0x17,0x95,0xC4,0x0A,0x5B,0x8F,0x09,0xF1, +0x39,0x3D,0x4E,0x8D,0xA1,0x5A,0x22,0x00,0xE3,0x1E,0x8B,0x8C,0x57,0x13,0x71,0x58, +0x9F,0xE1,0xDB,0x22,0x10,0x6E,0x27,0xAA,0x4E,0xCC,0xF0,0x53,0x8C,0x2A,0x30,0xED, +0x31,0x01,0x46,0xF1,0x67,0xF0,0x75,0x76,0x0B,0xB0,0x98,0xBC,0xDA,0xE3,0x78,0x79, +0x06,0x1E,0x20,0x87,0x20,0xE5,0x48,0x99,0x8D,0x84,0x57,0x47,0xBC,0x80,0x9C,0x09, +0x74,0xA4,0xBD,0x50,0x0D,0x37,0xF4,0x9D,0x04,0xA2,0xB4,0xF9,0x21,0x9A,0x63,0x34, +0x67,0xB2,0x13,0xBC,0xF4,0x1D,0xE0,0x88,0xB3,0x33,0x00,0xF8,0xAA,0x88,0x12,0x99, +0x77,0xF2,0x2D,0xA0,0x3D,0x5D,0x8F,0xD2,0x2B,0x49,0xE9,0xCB,0x20,0x0D,0x6D,0x76, +0xAD,0x32,0xDF,0x4C,0x0E,0xBF,0xEE,0xED,0xC5,0x60,0xAF,0xD2,0x9D,0x6D,0xD2,0xD6, +0x17,0x8A,0xB7,0x05,0xE4,0x61,0x4E,0x59,0xEC,0x28,0x55,0x5A,0x39,0xB1,0x68,0xD6, +0x80,0xC4,0x3B,0xF6,0xD8,0x57,0x41,0x3A,0xFE,0xC3,0x24,0x6A,0x24,0x57,0xF3,0x3F, +0x90,0xFF,0x8E,0x47,0xC8,0xF9,0x9A,0x55,0x63,0xCE,0xF8,0x0B,0x93,0x39,0xF9,0xD1, +0xE4,0x17,0x85,0xC5,0x12,0x44,0x3E,0xAE,0xB9,0x11,0x79,0x7A,0xAA,0x13,0xDA,0xC6, +0xB2,0xF4,0xFE,0xB3,0x66,0x1E,0x26,0x07,0x14,0xAC,0xA9,0x2A,0xD8,0xB9,0xDA,0x51, +0x08,0x09,0xEB,0x95,0xD7,0x32,0xAF,0x04,0xE0,0xFB,0x59,0xB8,0x98,0x87,0x42,0x55, +0x81,0xD7,0xD6,0x52,0x63,0xA4,0xEE,0xAD,0x77,0x81,0xB9,0x77,0x35,0x5B,0xB7,0xCD, +0x8D,0xB6,0xE8,0x25,0x38,0x05,0x06,0x2A,0xFF,0x3D,0x3A,0x4E,0x2F,0xBC,0xD4,0x3E, +0x00,0x32,0xA3,0x69,0x70,0x1F,0xA2,0x11,0x0F,0x19,0x06,0x89,0x5E,0x6A,0xA7,0x3B, +0x1E,0x1A,0x30,0x84,0x63,0xD2,0x16,0x04,0xBD,0xE8,0xF6,0xC6,0x35,0x24,0x1E,0xF4, +0x71,0xBD,0x0C,0x0D,0x86,0xA8,0xC8,0x62,0x44,0x73,0x26,0xFF,0xC1,0x05,0xE4,0x2A, +0xD9,0x16,0xC4,0x90,0x35,0xBD,0xE0,0xEF,0xDA,0x4F,0xA5,0x0B,0x54,0x0B,0xE6,0x76, +0xC9,0x0C,0xD2,0xAE,0x7D,0xDD,0x71,0x6B,0xD4,0xAB,0xEC,0xF5,0x13,0x97,0x15,0x13, +0x8A,0x70,0x73,0xF0,0x89,0x1D,0x1E,0x3D,0xBC,0x93,0x06,0x8A,0xA5,0xB6,0x70,0xAE, +0xFD,0x7D,0x6B,0x45,0x5E,0xCB,0xB8,0x27,0xE4,0xFD,0x9A,0x25,0xC4,0x72,0x6F,0x5F, +0x3E,0xE3,0x32,0xBB,0xDF,0xD3,0x5A,0x5B,0x9D,0xC0,0xE7,0x36,0xFE,0xDC,0x69,0xB9, +0xF8,0x49,0x78,0xB2,0x79,0x93,0x5F,0xF4,0xFD,0x49,0x65,0x99,0x6C,0xBE,0xFC,0x12, +0xA7,0xCC,0x66,0x55,0xCB,0xBD,0xFE,0x21,0x47,0xBD,0xDA,0x03,0x6D,0xEF,0x13,0xF5, +0x54,0x80,0xE2,0x82,0x16,0xC9,0xD7,0x1E,0xD3,0x74,0x34,0xE8,0x22,0xBF,0xD4,0xBC, +0xE6,0xDB,0xAD,0x55,0xE3,0x28,0x0C,0x5D,0xB6,0x1A,0x64,0x61,0xB5,0x08,0x5B,0x3E, +0x31,0xCF,0xB7,0x3E,0x48,0x29,0x6C,0x27,0x1F,0x76,0x16,0x03,0x4B,0x92,0x81,0xB8, +0x7B,0x65,0x2B,0xEB,0x06,0x61,0x98,0x85,0x3B,0x9D,0x3E,0x05,0x2C,0x08,0xE8,0x5C, +0xF9,0x56,0xF0,0xF5,0xD0,0xDE,0x70,0x18,0x7E,0x08,0xFD,0x59,0x74,0x4D,0xB2,0xF8, +0x75,0x52,0xE9,0xF2,0xB4,0xD4,0x4F,0x98,0xD9,0x8A,0x8A,0xDF,0x69,0x14,0xAB,0xD5, +0xB3,0x9C,0xCF,0x5D,0xCC,0x41,0x8C,0xF3,0xFF,0xFD,0xA8,0x53,0x67,0x8E,0x84,0xE4, +0xFA,0xC7,0x02,0xC0,0x0C,0xE7,0x1B,0x15,0x04,0x5E,0xEA,0x90,0x4E,0xF8,0x89,0x76, +0x0C,0x43,0xC1,0x5B,0xA3,0xBB,0x6C,0xE3,0xF3,0xA6,0xF6,0xF1,0x8A,0xEF,0xB8,0xD9, +0x08,0xCC,0x5F,0xA8,0xB9,0x22,0x06,0xFC,0xC4,0x63,0x36,0x7C,0x76,0xF2,0x64,0x26, +0x06,0x09,0xB3,0xE8,0x20,0x14,0x6D,0xF0,0x45,0xA4,0x1B,0x05,0xF5,0x32,0x3F,0x84, +0xDC,0x14,0x19,0x03,0x37,0x90,0x35,0xC5,0x39,0x12,0xBB,0x58,0x72,0x17,0x49,0xBB, +0x35,0x2D,0xA1,0x6B,0x4E,0x4F,0xC5,0x84,0x1D,0x42,0xC4,0x36,0x85,0x08,0xA3,0x25, +0xC6,0xD3,0x6C,0x11,0x49,0x28,0x76,0x9D,0xFE,0x2F,0x56,0xAD,0x75,0x49,0x21,0xE1, +0x07,0x74,0x09,0xD9,0x4B,0xEC,0x95,0xB6,0xC3,0x5F,0x20,0xAE,0x1D,0x67,0x01,0xFA, +0x1B,0x24,0x1E,0xCB,0x64,0x10,0x72,0x7F,0x14,0x8D,0xF8,0x02,0x4F,0x4D,0xE8,0xB8, +0xAB,0x12,0xCB,0xB2,0x93,0xE5,0x2A,0xF2,0x17,0xEE,0x86,0x97,0x0F,0x22,0x56,0x1D, +0x40,0x4E,0x21,0xEF,0xD6,0xCF,0x82,0x58,0xBC,0x49,0x25,0x9D,0x7A,0x9D,0xE5,0x23, +0xA4,0xB8,0x4C,0xAE,0xEE,0xED,0x57,0x88,0xDC,0x87,0x39,0xAE,0x0C,0x74,0xB7,0xED, +0x8C,0x0D,0xCA,0x45,0x88,0x20,0xFA,0x7B,0x9A,0x6D,0x92,0xEF,0xEC,0x78,0x08,0xAB, +0xFE,0xE4,0x97,0x91,0x0E,0xD3,0xCF,0x65,0x75,0x31,0x7B,0x25,0x16,0xEB,0x62,0x54, +0xAE,0xD1,0x38,0x60,0x9D,0x91,0x4A,0x49,0x23,0x90,0x70,0xDE,0x7F,0xED,0x21,0x42, +0x93,0x50,0xB0,0x8A,0x4F,0xFA,0xE7,0x63,0x85,0xD6,0xB8,0x8A,0xB3,0xB3,0x8A,0x82, +0x40,0x27,0x2C,0xAC,0xFD,0x90,0xB0,0xEF,0xB7,0x39,0x90,0x39,0x05,0x89,0xC4,0xBF, +0x55,0x79,0xDA,0xC6,0xBF,0xAB,0xE7,0xC1,0xD8,0xC5,0xC6,0x51,0xB4,0x7E,0x5E,0xBC, +0xF6,0x87,0x79,0xCE,0x43,0x35,0xD3,0x23,0x62,0x4E,0x2B,0x65,0xFE,0xAF,0x35,0x1E, +0x8A,0xDA,0x57,0x82,0xAB,0x7B,0x9D,0x4F,0x92,0x93,0x12,0x12,0x24,0xC4,0xA0,0xC9, +0xB4,0x6F,0x29,0x80,0x4A,0x34,0x13,0x89,0x71,0x0D,0x60,0x65,0xCD,0x3D,0x7E,0x5E, +0xB3,0xBE,0x73,0xA9,0x41,0x8C,0x9C,0x6E,0x06,0xA8,0xA5,0x6B,0x19,0x0D,0xEA,0x4E, +0xFE,0x48,0x65,0x1D,0x16,0xEF,0xF4,0x11,0xBE,0x15,0xBC,0x98,0x0C,0x0D,0xE8,0xD8, +0xF5,0x4F,0xA2,0x5F,0xC9,0x58,0xA1,0x8E,0x95,0x36,0x90,0xEA,0x5C,0x0F,0x8A,0xEE, +0x91,0xC4,0xC2,0x71,0x07,0x61,0x44,0xA3,0xF0,0x3B,0x5B,0x99,0xB0,0x7F,0x8B,0x11, +0x21,0x80,0xB0,0xD9,0xB6,0xDD,0xF1,0x12,0x7C,0x25,0x6D,0x7B,0x27,0x5F,0xBB,0xBF, +0x28,0x42,0x0C,0xB5,0x25,0x36,0x7D,0x41,0x10,0x6B,0xDE,0x0F,0x70,0x40,0xC5,0x64, +0xB9,0x74,0x12,0x77,0x1F,0xF7,0x02,0xA9,0xD2,0x7F,0x5A,0x52,0x95,0x56,0xFC,0x0A, +0xA1,0x04,0xD8,0x40,0x35,0x81,0x0C,0xC1,0x65,0xEE,0x1C,0x22,0x4E,0xDA,0x87,0xCB, +0x8A,0x80,0xFD,0x69,0x71,0xFD,0xDD,0xDB,0x10,0xEE,0x2B,0xF2,0x84,0x0F,0xE3,0x73, +0x26,0x6E,0xA0,0x28,0x1D,0x72,0x4C,0x0C,0x21,0x56,0xC6,0xC1,0xB2,0xC4,0x72,0xC6, +0xBB,0x54,0x48,0xDB,0x08,0x88,0x6F,0x7B,0xD3,0xAB,0xA3,0x67,0xB7,0x43,0xC4,0x50, +0x1B,0x7A,0x03,0x07,0xB1,0xD5,0x8C,0x6E,0x72,0x26,0x08,0xF3,0xBF,0x28,0x81,0x62, +0x5C,0x1B,0x05,0x8C,0x74,0x59,0x99,0xE8,0xD6,0xFD,0x97,0xFB,0x3B,0x85,0x5B,0x54, +0x9C,0x37,0x80,0x6E,0xCC,0x12,0x14,0xCC,0xBF,0x25,0xFA,0x7A,0xEA,0x38,0x19,0xF5, +0xF1,0x50,0x48,0x68,0xB3,0x41,0x8D,0x1A,0x99,0x76,0x83,0xBE,0xEB,0x5C,0xFC,0x9D, +0xC3,0xDA,0x80,0xAB,0xA5,0x23,0x1B,0xF0,0x13,0xA5,0xD2,0x8F,0x79,0xCC,0xBA,0x22, +0xC5,0xB5,0x6F,0xD2,0xFC,0x00,0x7C,0xA7,0xD6,0xAF,0x86,0x5E,0x41,0x94,0x81,0x02, +0xE9,0x1D,0xC1,0xD2,0x93,0x5B,0x58,0x16,0x7B,0x4B,0xBB,0xC2,0xB0,0x06,0x31,0xBC, +0xD0,0x34,0x6B,0x71,0x5B,0xB3,0x79,0x91,0xF3,0x0C,0xBC,0x7F,0x5D,0x24,0x2A,0x91, +0x26,0x94,0xCC,0x6F,0xFA,0x93,0xA4,0xF5,0x3B,0x53,0x6C,0x37,0x05,0x8D,0x89,0x03, +0xD3,0x77,0xCB,0xBC,0xEC,0xE5,0xDE,0x2D,0xCD,0xA0,0xCB,0x74,0x71,0x19,0xBC,0xE8, +0x84,0x85,0xCC,0x3F,0xF3,0xB7,0xDE,0x2D,0x25,0x76,0xBF,0xF5,0x48,0xE9,0x0B,0xC3, +0x57,0x1E,0xEE,0x49,0x65,0x1D,0xEF,0xC0,0x46,0xDE,0x6D,0xE1,0x35,0x25,0x88,0x49, +0x59,0x29,0xD9,0x6A,0x0B,0x72,0xFF,0x9C,0xA9,0xB0,0x2E,0xB6,0x4B,0xE3,0x00,0x04, +0x84,0xE9,0xAF,0x63,0x66,0xB0,0x73,0x8D,0x5B,0xBF,0xDA,0xA4,0x8C,0x1B,0xA0,0x60, +0x05,0xA5,0xBF,0x9F,0x30,0xD1,0xEB,0x7E,0x45,0x9A,0x62,0x8F,0x2C,0x5C,0xC9,0x73, +0xB8,0xED,0x07,0x9B,0x11,0x0A,0x51,0x1A,0x17,0xFD,0x87,0x96,0x5D,0x4F,0x82,0x0A, +0x0F,0x8F,0x7C,0x30,0xD1,0xAF,0x88,0xF0,0xBC,0x81,0xE6,0xE5,0xEC,0x3E,0x2D,0xE9, +0x78,0xD4,0x05,0x5D,0x79,0x53,0x37,0x08,0x8B,0x49,0xA3,0xC6,0x1D,0x53,0x5A,0xD1, +0xB1,0xD1,0xAD,0xC3,0x7C,0x3D,0x56,0xE9,0x9D,0xE5,0xBC,0xA0,0xD6,0xA4,0xD7,0x66, +0x3B,0x86,0xEE,0x3B,0x19,0x5A,0x15,0x78,0x1E,0x5E,0x04,0x7D,0x04,0x40,0x29,0x33, +0x94,0x08,0xA5,0x47,0xC0,0xF1,0x3A,0xB0,0xB1,0x7B,0xB2,0xF5,0x18,0x05,0x7C,0xB6, +0xC0,0x93,0x00,0x0A,0x64,0xD3,0xDC,0x52,0x52,0x33,0x1E,0x28,0x8C,0x82,0x0A,0xA9, +0xE8,0x4E,0xB0,0x68,0xC3,0x0C,0xBD,0x1A,0x05,0x4A,0xDB,0xE0,0x01,0x16,0x49,0xF3, +0xDE,0x3E,0x50,0x9B,0x62,0x21,0xDE,0x5B,0x8E,0xC7,0x42,0xBE,0xB5,0xF6,0x3E,0xC3, +0x87,0x5B,0x60,0xE1,0x7C,0x59,0x69,0x92,0x37,0x9F,0xF1,0x51,0x07,0x86,0xFB,0x47, +0x1A,0xAD,0xC8,0xD3,0xB2,0x29,0x72,0xD8,0xD1,0x1C,0xD6,0xBA,0xE6,0xEB,0x8B,0x1D, +0xBC,0xC3,0x78,0x8B,0x89,0x82,0x17,0x59,0x97,0x5F,0xAB,0x5C,0xD4,0x20,0x56,0xE4, +0x7E,0xEC,0x0C,0xA0,0x6C,0xFA,0x9E,0xE9,0x53,0x91,0xC3,0x52,0x5D,0x10,0x51,0x35, +0xDC,0x57,0x87,0x75,0x00,0x89,0x18,0x4C,0x2D,0x4F,0x7B,0xC3,0x35,0xCC,0x38,0xCA, +0xE9,0xC6,0x59,0x91,0x5A,0x2D,0xEB,0x56,0x12,0x65,0x5D,0xAA,0x0F,0xB6,0x2A,0xF2, +0x38,0x79,0xE2,0x90,0xAD,0xBF,0x24,0x80,0x8A,0x3C,0x5C,0x3B,0x3F,0xB6,0x4E,0x90, +0x09,0x27,0xBF,0xB8,0x40,0xF9,0x45,0x41,0x86,0xDD,0x04,0x1B,0x66,0xBC,0xFF,0xE6, +0x66,0x6C,0xA6,0x78,0xAC,0x00,0x23,0x26,0xBF,0xA3,0x7B,0x97,0x0B,0x40,0x1C,0xED, +0x52,0xB8,0xF3,0xED,0xBA,0xC0,0xE8,0xD2,0x70,0x9C,0xAA,0xBA,0x2A,0xD7,0xC9,0x35, +0x6E,0xDC,0x50,0xB1,0xCE,0xF2,0xB6,0x18,0x9F,0xAE,0xF5,0xFB,0x3E,0x02,0xE8,0xDD, +0x44,0x38,0x33,0x40,0x04,0x9B,0xF9,0xD6,0x9F,0x63,0x9A,0x14,0x3B,0x53,0x59,0x33, +0xC3,0x56,0xEB,0xE0,0x68,0x07,0x92,0xC1,0x64,0xFB,0x2D,0x05,0xE2,0x68,0xC2,0xB7, +0x91,0x3F,0x4D,0x07,0x96,0x1E,0x85,0x05,0xCE,0x44,0xC2,0x66,0xB0,0x10,0x6F,0x9A, +0x96,0xCD,0x72,0xE1,0x20,0xB0,0x2F,0xA6,0xA3,0x31,0x06,0x2A,0xC9,0x30,0x57,0x35, +0x84,0xAB,0xA0,0xBD,0x0B,0x11,0x7C,0xF2,0xDB,0xC9,0x6D,0x37,0x10,0xA3,0x9A,0x06, +0x14,0x85,0x74,0xDA,0xBA,0x8D,0xB7,0xB7,0x31,0x30,0x16,0xB2,0x98,0x9B,0xFE,0xF8, +0xE6,0xD5,0x9D,0x19,0xD8,0x4E,0x28,0x2B,0xF7,0x12,0xC5,0xA4,0x1A,0x41,0x40,0xD2, +0x6F,0xFA,0x5C,0x6F,0xB7,0xDD,0x33,0x49,0x83,0xB7,0x32,0xE7,0x32,0x7D,0xBE,0x90, +0x09,0xE7,0xF2,0xE2,0x7E,0x18,0x3C,0x9E,0x94,0x02,0xE3,0xC7,0xAA,0x3A,0x19,0xAE, +0x80,0xA1,0xAB,0x24,0xB0,0x99,0x1F,0x4E,0x5B,0xD3,0xE2,0x08,0x85,0x5D,0x8B,0x6C, +0xBB,0x44,0x73,0x7D,0x09,0xD5,0x23,0x10,0xB2,0x60,0xDF,0x1E,0xB0,0xDC,0x81,0xC5, +0xDB,0x49,0x71,0x71,0x70,0x0F,0xC3,0x9E,0xB7,0xC0,0x74,0x8C,0xDE,0xED,0xC4,0x2A, +0xDB,0x33,0x46,0x7C,0x64,0x84,0xEE,0x01,0xF0,0x19,0x91,0x19,0x90,0xDE,0x30,0x2E, +0xD3,0xBF,0x9C,0xDE,0x0E,0x16,0x9B,0x5F,0x9A,0x1A,0xEC,0x76,0xB5,0x59,0x85,0x32, +0x06,0x49,0x8F,0xA7,0x71,0x61,0xB7,0xD1,0x20,0x24,0xE0,0xB4,0xB9,0x39,0x97,0xF5, +0xEE,0xA8,0xF3,0xDC,0x40,0xCD,0xDA,0xBB,0xCD,0xFD,0xD3,0x30,0xBF,0x10,0x13,0x35, +0x1C,0xDC,0xC5,0x53,0x96,0x4D,0xE7,0x28,0x9D,0xD5,0x11,0x0E,0x12,0x60,0xAE,0x25, +0x06,0xE6,0x31,0xA8,0x57,0x49,0xC6,0xF0,0x31,0x00,0xDB,0xE9,0xA1,0x37,0x13,0x82, +0x3A,0x4E,0x54,0x3E,0x04,0x7F,0x48,0x27,0xC0,0x57,0x99,0x9A,0x1D,0x6B,0x00,0x87, +0x5C,0x71,0xF5,0xE8,0xC4,0x2E,0xFC,0x2B,0xE5,0xC8,0x47,0x1B,0x51,0xF3,0x19,0xB7, +0xBC,0x80,0x03,0x35,0x8E,0xAF,0xE8,0xCA,0xE5,0xFC,0x2D,0x51,0x71,0x78,0x90,0x49, +0xF6,0x6B,0x4D,0x59,0x5C,0xED,0xC6,0xCF,0x9A,0xAC,0x5E,0x66,0x49,0x22,0x34,0x4F, +0x16,0xD0,0x17,0xAC,0xDE,0x0E,0x8B,0xB7,0x72,0x23,0xCF,0x19,0x20,0x3D,0x5A,0x33, +0x28,0xB6,0x5F,0xF3,0x3C,0xAA,0x44,0xE6,0x60,0x53,0x0D,0xD6,0x6E,0x12,0xEB,0x10, +0xC3,0xCC,0x48,0x07,0xC8,0xAB,0x28,0xF5,0xA6,0x41,0x01,0xD3,0x89,0xB3,0x17,0x8B, +0x17,0x59,0x86,0x42,0x33,0x82,0x97,0xCA,0x0D,0xB9,0xF2,0xD2,0x65,0x88,0x74,0x9D, +0x37,0xD2,0xB6,0x1B,0x20,0x2C,0x93,0x3C,0x6A,0x8B,0x44,0xAF,0x92,0xF7,0x57,0xE1, +0x77,0x69,0xA3,0xAA,0x2F,0xF6,0xA9,0x25,0x80,0x93,0x04,0xA5,0xD0,0xBE,0x1A,0xD1, +0x62,0x39,0xF2,0x64,0xCC,0x08,0x14,0x5C,0x63,0xFD,0x4B,0x49,0xEE,0x33,0xF3,0x5F, +0xF5,0x8C,0x3B,0x88,0x02,0x5E,0xF8,0x5D,0xDE,0x20,0xCC,0x79,0x0A,0x62,0x13,0x2E, +0xAD,0x8A,0x40,0x4C,0x79,0xFC,0x09,0xAD,0x62,0xE1,0xE7,0x83,0xF6,0x12,0x3C,0x57, +0x15,0xDB,0xD8,0xF5,0x8A,0x4A,0xEB,0x36,0x00,0x35,0xE8,0x94,0x2F,0x2A,0x80,0x4A, +0xF0,0x99,0x76,0x25,0xB3,0x77,0x61,0xC1,0x1A,0xF5,0x00,0x68,0x27,0x12,0x9B,0x8C, +0xCF,0xD6,0x40,0x97,0x53,0xEA,0xD4,0x4C,0xDC,0xA9,0x9F,0x6F,0x35,0x5E,0xEB,0x66, +0xD7,0xAC,0x49,0xC5,0xF0,0x9B,0x31,0x10,0xBA,0xD4,0x68,0xE0,0xD0,0xEE,0x1C,0xE4, +0x99,0x03,0x34,0x8F,0x25,0x65,0x6D,0x25,0x4C,0x2E,0xFC,0x0A,0x87,0x37,0xC8,0x53, +0xCA,0x53,0x7D,0x19,0xCB,0x8A,0xC8,0x46,0xC2,0x0C,0x4A,0xEA,0x3D,0xA6,0xA7,0x33, +0x0E,0x90,0x9C,0x82,0x81,0xA1,0xBE,0x77,0x91,0xE4,0xA5,0xF1,0x54,0xC8,0x42,0x2D, +0x78,0xDF,0x4A,0x02,0xD5,0x8D,0xE1,0x30,0xBD,0x96,0x9B,0xA0,0x59,0x26,0x43,0x17, +0x95,0xB0,0xD6,0x25,0x78,0xDF,0xA9,0xE1,0xE7,0x5D,0x6C,0x09,0x12,0x78,0xE0,0x98, +0xCB,0x49,0x9C,0xDB,0xEF,0x4B,0x49,0xB1,0x66,0x59,0xCF,0x25,0x05,0xA5,0xCA,0xD8, +0xA0,0xBD,0xDF,0xD7,0x16,0xA6,0x80,0xE3,0xF0,0x21,0x09,0x28,0x1A,0xFC,0x14,0x65, +0x28,0xD4,0x07,0xF1,0x6D,0x99,0xA4,0xAD,0x5C,0xBD,0x02,0x6F,0x78,0x45,0x22,0x13, +0xC3,0x1D,0x45,0x72,0xD7,0x23,0x77,0xF5,0x32,0x01,0x82,0xCA,0x30,0x28,0xA9,0x99, +0x96,0xDC,0x6E,0xC2,0x72,0x11,0x28,0x21,0xCC,0xFE,0xC9,0x40,0x17,0xA7,0x69,0x37, +0x0F,0x05,0x13,0xEE,0x4A,0xCE,0xFE,0x37,0xC9,0x43,0xB4,0x87,0xC8,0x43,0x3C,0x9D, +0xB4,0x83,0xD0,0xC5,0x40,0x66,0x80,0xBD,0x91,0xD9,0x6F,0xEB,0x28,0x91,0x57,0xD3, +0x1A,0x44,0xFA,0xF9,0x0F,0xCA,0x1B,0x9D,0xB4,0x60,0x50,0x60,0xBA,0xA8,0x66,0x93, +0x83,0x0C,0x03,0x73,0x83,0x9E,0x3D,0xE2,0x05,0x11,0x98,0x6D,0x0B,0x7D,0x87,0x8F, +0x3C,0x6F,0x69,0x0D,0x78,0x0C,0x5E,0xEC,0x6C,0x9C,0x71,0x75,0xDD,0x7B,0xB0,0xB8, +0xC7,0xCC,0x7D,0x13,0x56,0x61,0xDF,0xA0,0xD3,0xFC,0xA1,0xBD,0xDB,0x2D,0x08,0x42, +0x69,0x24,0x15,0xF1,0xE3,0xF8,0x9B,0xD3,0x8D,0x8A,0x43,0x53,0x63,0xCA,0x11,0x57, +0x5C,0x0A,0xE7,0x71,0x75,0xDA,0xBF,0x51,0x71,0x28,0x31,0xEC,0x76,0xA6,0x23,0xF2, +0x56,0xF0,0x51,0xFB,0x9C,0xAF,0x69,0xA6,0x68,0x49,0x54,0x3E,0x95,0x2C,0xB1,0x87, +0x64,0x94,0x64,0xE4,0x7C,0x83,0xCC,0x3D,0xF6,0xFD,0x5B,0xC9,0x2D,0x6C,0x38,0xF9, +0xB6,0xA5,0x80,0x71,0x30,0xB6,0xBA,0xA5,0xA1,0xBA,0xFC,0x85,0xE9,0x9C,0xD9,0xE5, +0x14,0xD7,0xF3,0xDA,0x93,0xC9,0x06,0x91,0xFC,0xAA,0x5F,0x58,0xB1,0xFC,0x45,0xFF, +0x11,0xC8,0x7C,0x50,0xA8,0xD4,0x70,0x7B,0x4D,0xB8,0x7F,0x90,0x7B,0x2C,0x21,0xD3, +0xCD,0x09,0x9B,0x4D,0x6D,0x62,0xFB,0xA0,0xF2,0xBE,0x43,0xA0,0xA2,0x05,0x2C,0xDA, +0x98,0xE7,0x72,0xFD,0xC0,0xC3,0x95,0xB1,0xED,0x68,0x28,0x92,0x7B,0x96,0x24,0x08, +0x79,0x67,0xB0,0xAB,0xBB,0x7F,0xD4,0x25,0xFA,0xF2,0x97,0xE3,0x63,0x0D,0x48,0x7B, +0xC1,0x35,0x92,0x55,0x69,0x71,0x74,0x27,0xE3,0x5A,0xDC,0x5B,0x83,0x64,0x48,0x8B, +0xCF,0x34,0x5A,0x4A,0x3D,0xB6,0x0F,0x02,0xE8,0x7E,0x21,0xF2,0xC5,0xA7,0x8E,0x0A, +0xDA,0xE8,0x45,0x34,0xC1,0x4F,0xE1,0x96,0x79,0x57,0xBC,0xD2,0x97,0xCA,0x41,0x7F, +0x77,0x7A,0x44,0x67,0x7B,0x6A,0x58,0xC3,0xC4,0xC9,0x1E,0x6A,0xBB,0xBB,0x3D,0xEA, +0x5E,0x0B,0x48,0x90,0x45,0x63,0xDB,0xC3,0xE2,0xF6,0x80,0x16,0x33,0x68,0x52,0x2B, +0xA4,0x1F,0x24,0xA7,0xF4,0xBE,0x69,0xDC,0xB8,0xA3,0x72,0x80,0x46,0x9C,0x1C,0xAB, +0x4A,0x6A,0x46,0xBB,0xC0,0x1B,0x32,0xAB,0x54,0xF8,0x2D,0x29,0x5A,0xDD,0xA1,0xD3, +0xD5,0xC4,0xED,0x6D,0x54,0x5D,0xCE,0x5E,0x03,0x48,0xEF,0xF1,0xC6,0x5B,0x75,0xB7, +0x02,0x81,0x7F,0xC8,0x69,0x26,0xCB,0xFC,0xC0,0x84,0x6A,0x57,0x22,0xAB,0x19,0x89, +0xAA,0x4F,0x2D,0x55,0xA3,0xEF,0x1B,0x52,0x9E,0x2C,0x59,0xFE,0x02,0x4F,0x70,0xA2, +0x2A,0x5B,0x04,0x0F,0x55,0x5B,0x43,0xB1,0xFD,0xE8,0xB6,0x16,0x82,0x64,0x3D,0x5C, +0xCA,0xA3,0xD7,0x1A,0x8D,0x80,0xE3,0x92,0xDD,0xAD,0x98,0xF6,0xEF,0xCF,0x54,0xA4, +0xD4,0x4C,0xB6,0xFA,0x0A,0x37,0x3E,0x9A,0x41,0xB1,0xCD,0x91,0x25,0x61,0x0C,0x58, +0x7D,0x16,0x8A,0xF0,0x2A,0xAA,0x04,0xD9,0xC7,0x29,0x82,0x5B,0xD4,0xC9,0x32,0x1A, +0x23,0xB6,0x17,0xFC,0xA2,0xE0,0x2E,0x39,0x03,0xCA,0x9B,0xD7,0xCB,0x97,0xD4,0x77, +0xC2,0x2E,0x52,0xBA,0x6B,0x5E,0x70,0x42,0x1D,0x32,0xCD,0x11,0x34,0xFE,0x60,0x32, +0x76,0x46,0x85,0x65,0x0D,0xD4,0x4D,0xC8,0xB1,0x58,0xA6,0xF9,0x73,0x69,0x23,0xC8, +0x76,0x5A,0x0E,0x0A,0x04,0xE9,0x63,0xD0,0xC3,0xD0,0x5E,0x0E,0xF7,0xE7,0x5C,0x54, +0x8B,0xE2,0x89,0x47,0xF6,0x49,0x7B,0xF8,0x99,0x27,0x97,0x68,0xEA,0x68,0xE9,0xC5, +0x11,0x2D,0xA0,0x3B,0x25,0x42,0x17,0x3B,0x0C,0x39,0xC9,0x3B,0x72,0x44,0xD2,0x1E, +0x4A,0x85,0xB1,0x1A,0xC2,0x0E,0x10,0xF8,0xDD,0xC3,0x74,0x0E,0xA7,0x3D,0xA3,0xC2, +0x70,0x38,0xEB,0xCB,0x11,0x83,0xE6,0xBB,0x05,0x58,0xB5,0x76,0x35,0x5B,0x77,0x5E, +0xCC,0x64,0x55,0x87,0x12,0xEE,0x3B,0x1A,0x3C,0x1A,0xC3,0x7A,0x1C,0xBE,0x5C,0xFF, +0x93,0xF4,0xBB,0x4B,0x12,0xEB,0x01,0xDF,0xA0,0x0B,0xFB,0x33,0x51,0xA8,0xE4,0x13, +0xA5,0x04,0x17,0x42,0x6A,0xCE,0xA1,0x4C,0xBC,0x4E,0xE0,0x54,0xA8,0xBE,0x3E,0xC2, +0x54,0x13,0xB5,0x7B,0xFC,0x90,0x48,0xB0,0x7D,0xAD,0x89,0x3A,0x42,0x5B,0xBF,0x7A, +0x65,0x10,0x14,0x2A,0xF3,0x3F,0x73,0x46,0x79,0x22,0xC0,0x26,0x08,0xF4,0xA6,0x90, +0xB7,0x4B,0x3F,0x3B,0x25,0x87,0xF9,0x14,0xE5,0x2D,0x0A,0x98,0x2B,0x02,0x64,0xE2, +0x00,0x78,0xF9,0x21,0x99,0x82,0x41,0xD5,0x24,0xF6,0x60,0xE6,0x21,0xA9,0x63,0xF3, +0x20,0xCD,0x2F,0x30,0x5B,0xE9,0x8D,0x0D,0x10,0xF1,0xDA,0x1E,0x8A,0xB4,0x73,0x38, +0x81,0x90,0xC3,0xDD,0x2E,0xA0,0xB3,0xC8,0x25,0x62,0x3B,0x4E,0x55,0xAB,0xF4,0xB4, +0x7B,0x9C,0xFC,0xF9,0x49,0xC7,0x07,0x35,0x21,0x24,0xA0,0x76,0x06,0xEC,0xC1,0x8A, +0xFA,0x65,0x9D,0x8E,0x9B,0x15,0xC3,0x2C,0xDF,0xB9,0x03,0xD5,0xE6,0x64,0xFA,0x43, +0x9E,0x32,0x24,0x56,0xA6,0x75,0xDF,0x53,0x25,0xBA,0xC2,0x57,0x27,0x55,0x92,0xF7, +0x55,0xF1,0xCA,0xC2,0x9E,0x4B,0x09,0x3E,0xC5,0x8F,0xA3,0x3D,0xE1,0xDB,0x7D,0x83, +0xC6,0x3C,0xAA,0x11,0x0F,0x6E,0x5B,0x74,0x81,0x81,0xFE,0xB4,0x4F,0x1B,0xBB,0x50, +0x4F,0xD5,0x88,0xA4,0x1C,0xF8,0x7A,0x5C,0x51,0x4D,0xEB,0xF4,0x0D,0x46,0x60,0x5E, +0x50,0xA6,0xA7,0xC2,0xC1,0x86,0xCF,0x72,0xC6,0xA5,0xF5,0x53,0x34,0xDF,0xBB,0xAB, +0x0F,0xB1,0x99,0x61,0xC6,0x06,0x1D,0x8E,0x82,0x94,0xE7,0x66,0xC3,0x85,0x0E,0xA5, +0x0E,0x98,0xA6,0xA7,0x6C,0x5E,0x23,0x95,0x37,0x2B,0xEC,0x69,0x0D,0x0A,0xF5,0x8D, +0x6B,0x68,0x88,0x82,0xDA,0xBB,0x90,0x32,0xA4,0x49,0xE0,0xF9,0x17,0xF3,0x99,0x14, +0xCC,0xE0,0xDE,0x48,0x99,0xC7,0xB3,0xEB,0xE7,0xF6,0x16,0x9C,0x5F,0x26,0x8E,0x6A, +0xC9,0x58,0x93,0x83,0x49,0x33,0xDB,0x0F,0x7E,0x0D,0x4A,0xBA,0x09,0x03,0x58,0x0C, +0xCA,0xE3,0x7A,0x1D,0x0D,0x0B,0x20,0xA0,0xF3,0xB4,0x1C,0x9B,0x4E,0xA0,0x6B,0xB9, +0xFA,0xE1,0x8C,0x9D,0x03,0x23,0x63,0xB4,0x6F,0x10,0x27,0xB2,0xBF,0x1F,0x92,0x3F, +0xDB,0x39,0x7F,0x07,0x3B,0x4F,0x38,0x41,0x86,0x61,0xA9,0x3E,0x76,0x4E,0x7F,0x5C, +0x9C,0xB5,0xF3,0x53,0x2B,0xF6,0x14,0x2F,0x54,0x57,0x0B,0x9B,0x3A,0xB1,0xBC,0x77, +0x05,0x06,0x66,0xD3,0x01,0xC6,0x82,0x46,0x58,0x26,0xBC,0x1A,0x97,0x18,0xC3,0x6B, +0x38,0xDF,0xE0,0x21,0x02,0x63,0x27,0xF9,0x2D,0x68,0xC5,0xC6,0x2F,0xB1,0xDB,0x45, +0xF0,0xF6,0x24,0x50,0x9A,0x93,0x63,0xA7,0xE9,0xD9,0x43,0x32,0x26,0x11,0x81,0x2E, +0x64,0x4E,0x30,0x9D,0xD2,0xF1,0xC3,0xD2,0x32,0xCB,0x32,0xFF,0x72,0xB4,0x9B,0x8F, +0x16,0xED,0xFE,0x95,0x24,0x68,0xB4,0x1E,0x55,0xEB,0x85,0x9A,0x80,0x9B,0x40,0x9D, +0xF4,0xBC,0xC6,0xCE,0xF0,0x19,0x9A,0xD5,0x01,0xD0,0x52,0x99,0x27,0x14,0xAF,0x40, +0xCE,0x4B,0xA7,0x30,0x8F,0x2F,0x6C,0x94,0xD0,0x11,0x55,0x4F,0x0B,0xB2,0x75,0x2C, +0xC7,0x40,0x4C,0x47,0x19,0x17,0x6C,0x4B,0x02,0x2E,0x1F,0x85,0x8F,0xF2,0xAA,0x42, +0xD3,0x7A,0x25,0xCB,0xC2,0x39,0x93,0x32,0x92,0x8D,0xBC,0x53,0xA0,0x1C,0x86,0xC0, +0xD9,0xCC,0x38,0x69,0x25,0x9C,0xCB,0x8E,0x69,0x73,0x43,0xA4,0x84,0x5F,0x78,0x30, +0xBD,0x69,0x2F,0x3F,0xA2,0x86,0xE9,0x4C,0xA5,0x36,0x9D,0x37,0x2C,0x1B,0xB6,0x58, +0x27,0x11,0xA1,0x72,0x89,0x1F,0x39,0x74,0x1F,0x31,0x8C,0x89,0x11,0x6B,0x99,0x32, +0x4C,0x89,0xC2,0x10,0x8D,0x3E,0x6A,0xC4,0x23,0xB3,0x88,0x98,0x69,0x36,0x6F,0xFF, +0x15,0x04,0x8F,0xF7,0x7B,0x6B,0x8A,0x26,0x92,0x96,0x62,0x0E,0x7D,0x3C,0x3C,0xD2, +0xE9,0x50,0x03,0xFC,0xAA,0x75,0x2B,0xB8,0x09,0x0D,0xDA,0x5E,0xBD,0xAC,0xC9,0x52, +0xA3,0x96,0xCA,0x7A,0xD4,0x8C,0xF4,0xBC,0xB9,0xC4,0xED,0x38,0x07,0xB8,0x10,0x50, +0x96,0xA8,0xF5,0x92,0x67,0xCB,0x05,0x59,0xA8,0x2A,0x84,0xE6,0x98,0x1E,0xC5,0x9E, +0x04,0x2C,0x8C,0x43,0x0B,0xFE,0x07,0x6D,0xFC,0x86,0xA1,0xE6,0xD2,0x49,0x50,0xE2, +0x89,0xEF,0x72,0x4E,0xDF,0x2F,0x1A,0xD8,0xA6,0x66,0xEC,0xC5,0x53,0xB8,0x47,0xE5, +0x53,0x98,0xCD,0xF1,0x52,0xFA,0xDF,0x50,0xC3,0x27,0xE7,0x07,0xC5,0x8B,0x2F,0xBA, +0x7F,0x2F,0x65,0xDE,0x50,0xE8,0x51,0x65,0x7B,0x90,0xC5,0x8A,0xFF,0xFE,0x3C,0xC2, +0xF3,0x62,0xBA,0x45,0xA0,0xB8,0x0F,0x7E,0x3D,0xC5,0xB2,0xF2,0x08,0x62,0x68,0x28, +0xF6,0xEF,0xF3,0x60,0xCD,0x71,0x31,0x14,0xC7,0xAF,0xE4,0x1C,0x43,0xE0,0x43,0x42, +0xD5,0xAF,0xE7,0xE8,0x34,0xDD,0x19,0x8C,0xF9,0x26,0xBB,0xBA,0x82,0x65,0x78,0xED, +0xBB,0x46,0x2B,0x91,0x67,0x20,0x92,0xAF,0xCC,0xB0,0x6E,0x3E,0x52,0x31,0x68,0x62, +0x20,0x14,0xCA,0x8E,0xDA,0xC7,0x00,0xBC,0x6C,0x32,0xFF,0x53,0x3C,0xCB,0x4A,0xFD, +0x98,0xF0,0x92,0xF3,0x5C,0x71,0xB3,0xDD,0xEC,0x30,0x15,0xE7,0xD8,0x0E,0x2A,0xB1, +0x5C,0x9D,0x5B,0xED,0x66,0x76,0x8B,0x5D,0xD2,0x82,0x85,0xCE,0x7F,0xAA,0x78,0xFD, +0x07,0xBE,0xA9,0xCE,0xA9,0xE8,0x0A,0x22,0x8D,0x51,0xD2,0x47,0x66,0xA3,0x3D,0x92, +0x4B,0xE7,0xA4,0x93,0x98,0xD0,0x56,0x5B,0xA4,0xAB,0x15,0x75,0x6A,0x06,0x4D,0xA1, +0x73,0x7B,0x0C,0x96,0x87,0xBF,0xA4,0xD5,0x11,0x52,0xC3,0x35,0x22,0xF3,0x24,0xAF, +0xFD,0x01,0xCF,0x93,0xC8,0x33,0x4C,0x7B,0xF0,0x3F,0xFB,0x25,0x63,0xCF,0x29,0xC1, +0x00,0xD7,0x9A,0xEB,0xF0,0x38,0x6D,0xF4,0x85,0xA6,0xD1,0xC2,0x31,0x3D,0x3B,0x1D, +0xBE,0x93,0xED,0x60,0xB1,0x4D,0xC6,0xED,0xB1,0x48,0xE0,0x4B,0x03,0x9B,0x01,0xF6, +0x5A,0x5B,0xD4,0xA0,0x80,0x7A,0xD0,0x38,0x89,0xCB,0xCD,0xCA,0xD4,0x86,0x04,0x06, +0x56,0x06,0x66,0xA0,0x33,0x56,0x76,0x36,0x6A,0xC4,0xE4,0xAD,0xAD,0xAC,0x49,0x26, +0xE1,0xED,0x90,0x6A,0x86,0xDE,0x2B,0x5B,0x1A,0x05,0x59,0x1D,0x8D,0x0C,0xF1,0xA4, +0x69,0x81,0x7F,0xCD,0xC2,0xC7,0xB8,0xB7,0x58,0xC2,0x5E,0xCD,0xA8,0x47,0xDF,0xB4, +0x25,0xCA,0x5E,0x82,0xE6,0xB9,0x1B,0x3B,0x50,0x31,0xE6,0xDF,0x2C,0x32,0xBE,0xA3, +0x6A,0xCB,0x9E,0x81,0x89,0x6F,0xEF,0xC6,0xCB,0x53,0xD2,0x37,0xF8,0x58,0xDA,0x3D, +0xC3,0x7E,0xAD,0x87,0x50,0x83,0x20,0x57,0xB8,0xE5,0x99,0x36,0xCD,0x72,0x13,0x09, +0xA6,0x59,0xA5,0x36,0x2F,0xC7,0x99,0xF8,0xD6,0xEC,0x07,0x54,0x69,0x4E,0xC6,0x14, +0xE6,0x70,0x07,0x80,0x95,0x19,0xF2,0x49,0x54,0xE6,0xDB,0x30,0xB6,0x91,0xA1,0xAC, +0xE5,0x65,0x2E,0xD8,0xD0,0x10,0xF1,0x18,0xBF,0xFC,0x6C,0xC5,0xF0,0x03,0x48,0x14, +0x1E,0x80,0xD2,0xFA,0x70,0x76,0x3E,0x10,0xB1,0x8E,0xF8,0x9C,0xB3,0x62,0x6C,0x15, +0x03,0x69,0xF1,0x8E,0x14,0x5C,0x73,0x9B,0x9A,0xD2,0x35,0x40,0x4B,0x98,0x53,0xD1, +0x55,0xCB,0x90,0x92,0xCB,0x34,0xD5,0x6D,0xAB,0x37,0xCE,0xD0,0xEC,0x98,0x60,0xC7, +0xF0,0x83,0xA0,0xEF,0xF5,0x81,0xE8,0xBA,0xFB,0x06,0x82,0xAA,0x11,0x35,0x34,0x05, +0x68,0x92,0xC2,0xE4,0xD3,0xDB,0x9C,0xF9,0x3E,0x35,0x9E,0xC0,0xA9,0x19,0x53,0xA7, +0xDA,0x97,0x6F,0x18,0x99,0xB2,0x4F,0x51,0xA2,0x14,0x8F,0xE0,0xEF,0x42,0x61,0x99, +0x11,0x02,0x59,0xDD,0xBA,0xDC,0x6E,0x12,0xFF,0xBF,0x43,0x90,0x7C,0xF1,0x16,0x49, +0xAC,0x52,0x8B,0xCF,0xEE,0x72,0x72,0x70,0x07,0x43,0x9E,0x89,0x8B,0x06,0x19,0x8F, +0xDD,0x07,0x47,0xA7,0x0A,0xB2,0x88,0xF4,0xA0,0x7C,0xD4,0x0B,0x9B,0xE7,0xF0,0x71, +0x52,0x64,0x7C,0x90,0xF5,0xAA,0x30,0xA5,0xED,0x45,0xF4,0x62,0x84,0x6F,0xB3,0xB6, +0x4B,0x84,0x20,0x02,0x32,0x85,0x7C,0xB6,0x82,0x82,0x83,0xA2,0x3E,0xC3,0xE4,0x1E, +0x95,0x97,0x10,0x3A,0xD6,0x48,0xD6,0x5E,0x21,0x5A,0xAE,0x53,0xDD,0xCF,0xDF,0x23, +0x69,0x93,0x40,0x40,0x6A,0x2E,0xC2,0x88,0x0A,0x89,0x03,0xF1,0xE6,0x1C,0x01,0x7E, +0xC9,0xBC,0x91,0x82,0x36,0x7E,0x68,0x52,0xC5,0x20,0x34,0xE9,0x32,0x24,0x46,0xD0, +0xC8,0x12,0x60,0x3F,0x19,0xFE,0x3A,0x06,0xC7,0x0C,0xED,0x23,0xE2,0xC9,0x67,0x9A, +0xC4,0x23,0xC0,0xD7,0x09,0x7E,0x9D,0xF1,0x6E,0x24,0xEE,0x6D,0x70,0xBF,0x88,0x8B, +0x55,0x98,0x6C,0x44,0x22,0xC5,0xBB,0xDC,0x4A,0x16,0x26,0x26,0x0C,0x37,0xAE,0xD9, +0x3D,0x9F,0x19,0x38,0x1D,0x7F,0x6D,0x0F,0x7A,0xFD,0xDC,0x32,0xC4,0x4C,0x34,0x65, +0xAA,0x5E,0x8C,0xCA,0x69,0x95,0x6F,0xC2,0x55,0xF9,0x18,0xF6,0x6F,0x7C,0x9A,0x67, +0x45,0x7D,0xEA,0x49,0x1F,0xC7,0x0C,0xB2,0x20,0x22,0xEA,0xA2,0x2B,0xE2,0x7C,0x44, +0xFD,0x16,0x75,0xF0,0x08,0x8A,0xD1,0x15,0x80,0x71,0x06,0x42,0x10,0xE4,0x40,0x29, +0x0B,0xB5,0x64,0xBB,0x54,0x23,0x4A,0xE4,0x51,0x1B,0x3D,0x0B,0x68,0xC8,0x0D,0x59, +0xF8,0x98,0x1C,0x2B,0x17,0x2E,0x57,0x78,0x80,0xD2,0xA7,0x6B,0x04,0xDF,0xDE,0x1F, +0xC7,0x2E,0xF7,0x93,0xF6,0x9F,0x19,0xAA,0xB9,0xCB,0xE5,0xF3,0xA7,0xB3,0x2B,0xEB, +0x2F,0x31,0x86,0xFB,0x6F,0x19,0xFF,0xDF,0x18,0xF9,0x74,0x26,0xEE,0x50,0x90,0x51, +0xF0,0x1A,0xC9,0xE8,0x1A,0x7B,0xCF,0x31,0xF2,0x43,0x11,0x34,0xB4,0xDF,0x84,0x9B, +0x60,0x1C,0x0C,0x55,0x16,0xD9,0xC1,0x8E,0x49,0x1C,0xCA,0x0E,0x30,0x6E,0xA2,0x7D, +0xEC,0xFD,0x8A,0x4F,0x84,0x6A,0xCA,0x02,0x8B,0x82,0x1D,0x9B,0x04,0xBA,0xE0,0x41, +0x05,0xC5,0xA0,0x3F,0xB9,0x6F,0x5E,0xB6,0xEF,0xD5,0x8B,0xAB,0x2A,0x8A,0xCB,0x3D, +0x71,0xA1,0xD6,0xC4,0xFA,0x29,0xC6,0xB6,0xDD,0xA4,0xA3,0x16,0x0B,0xB8,0x90,0xB2, +0xAC,0x12,0x4B,0x34,0x43,0xBC,0xB2,0xFE,0xAF,0xCD,0x85,0x1C,0xB9,0xC8,0xDB,0xF7, +0x35,0xF0,0x60,0x53,0x4C,0x34,0x77,0x8A,0x1B,0xC7,0x28,0xC5,0x9D,0x61,0x72,0x00, +0xF0,0xCF,0x7E,0x72,0xE2,0xFB,0x23,0x28,0x32,0xDE,0x6A,0x96,0x65,0x28,0x3E,0xBC, +0x9B,0xCC,0xC5,0x5E,0x8E,0xF0,0x2E,0x44,0x38,0x49,0x38,0x82,0xCB,0x57,0xAF,0x44, +0x45,0xD8,0xC5,0x93,0xE4,0x3C,0x72,0xD7,0x70,0x10,0xF5,0xEC,0x0A,0x42,0x96,0x67, +0xB9,0x09,0xC6,0x43,0x8C,0x11,0x7E,0x1E,0x30,0xAF,0x3E,0xEA,0x50,0x50,0x57,0x51, +0xE1,0x98,0x20,0xCB,0xDC,0x1B,0x86,0xB6,0xFD,0x51,0xB5,0x1E,0xD1,0xDA,0xD7,0xF4, +0xC0,0x65,0x76,0xB5,0x4C,0xC4,0x0C,0x78,0x93,0xDC,0x13,0x0B,0x65,0x22,0x99,0x74, +0x7F,0x87,0x1E,0xAA,0x97,0xE3,0x7A,0xBA,0x04,0x5C,0x1C,0xC7,0x8E,0x61,0xC4,0x4D, +0x37,0x28,0x88,0x68,0xE6,0x22,0x97,0xD1,0xEF,0x21,0xB0,0x28,0xF5,0x05,0xD4,0x59, +0x0B,0xC1,0xE6,0xF9,0x65,0xCE,0x77,0x36,0x0A,0xD4,0x53,0xCC,0xD4,0xE3,0x26,0xAB, +0x6D,0x48,0xD0,0x97,0x27,0x3D,0x67,0x6E,0x2F,0x26,0x69,0x54,0x9F,0xE0,0xE8,0x66, +0x94,0x2A,0xCF,0x51,0x80,0x65,0x95,0xA2,0xDA,0x0E,0x7A,0xE9,0xD1,0xEF,0x61,0xA0, +0xD9,0x90,0x02,0x11,0x96,0x15,0x21,0x5A,0x32,0x08,0x5E,0xE0,0x97,0xA3,0x07,0xFF, +0xC6,0xD5,0x8F,0x9E,0x6C,0xB6,0x7E,0xA4,0xCA,0x67,0xDF,0x8D,0x50,0x43,0x6A,0xCA, +0x9B,0xEF,0xFB,0x16,0x19,0x45,0x2A,0xDF,0x74,0x7F,0x39,0xA8,0xF8,0x99,0x7F,0xB0, +0xAD,0x64,0x2F,0x7A,0x9B,0x23,0x85,0xE4,0xE7,0x6C,0x7F,0xD0,0x6A,0x6E,0x0F,0x97, +0x98,0x59,0x24,0xE7,0xF3,0x78,0xAC,0x29,0x11,0x63,0xAC,0x92,0xC1,0x51,0x98,0xAF, +0xE6,0x22,0x21,0x28,0x40,0x29,0xC4,0x79,0x55,0x5A,0x7F,0x34,0xE2,0xA6,0x06,0x91, +0x06,0xCA,0xA5,0x11,0x1B,0x04,0x3E,0x1D,0x9D,0x60,0x09,0x15,0xBD,0xAA,0x9E,0x2C, +0xF1,0xDA,0x64,0x09,0x5C,0x65,0xD0,0x99,0x75,0x74,0xB6,0xC2,0x18,0x69,0x51,0xE3, +0x89,0x64,0xA7,0x79,0xA6,0x28,0x56,0x0A,0x9F,0x1A,0x48,0x07,0x05,0xCC,0xD8,0xD8, +0x86,0x9B,0x8A,0x1A,0xA1,0x32,0x03,0x30,0xA3,0xFB,0x60,0x29,0x1A,0xD5,0x27,0x98, +0x82,0x1F,0x8D,0xA4,0xDA,0x52,0x1A,0xFF,0x25,0xA9,0xE7,0xCC,0x41,0xE1,0xCC,0xED, +0xB9,0xD0,0x4B,0x90,0xD9,0x2E,0xD3,0x93,0xA2,0x97,0x78,0x8F,0x9E,0xF8,0xA1,0x67, +0xD6,0xFC,0xCC,0x08,0xCE,0x29,0xB6,0x88,0xB6,0x4A,0x9A,0x55,0x48,0x06,0x6C,0xF7, +0x6E,0x0D,0xFF,0x2F,0xC8,0xA3,0xF0,0xA7,0x80,0x6D,0x30,0x31,0x6D,0x29,0x07,0x80, +0x73,0x83,0xC5,0xA8,0x80,0x3F,0x2D,0xE8,0x86,0x1F,0xEB,0x6A,0x73,0x39,0x99,0x04, +0x3E,0xD1,0x28,0xF8,0x69,0x3F,0x99,0x18,0x4B,0xB4,0xE2,0x48,0x50,0xD8,0x25,0x5D, +0x2F,0xCC,0xC2,0x29,0x51,0x87,0xA8,0x5A,0x61,0x6F,0x32,0xAB,0x04,0x36,0xEF,0x78, +0x17,0xC9,0x55,0xAA,0xF8,0x1A,0x78,0x57,0xBA,0x42,0x5F,0xC9,0x84,0xD5,0xD1,0x3B, +0x0B,0x27,0x41,0x48,0xFA,0x8B,0x76,0xFF,0xC5,0x1E,0x26,0x76,0x36,0x5A,0x82,0xBF, +0xB0,0x75,0x91,0xE6,0x51,0x49,0xBD,0x0C,0xBF,0xDA,0x96,0x91,0x7C,0x4A,0xD5,0x99, +0x9B,0x35,0xA2,0x95,0x64,0x60,0xA7,0xB1,0xA6,0xC6,0x30,0xCC,0x08,0xA0,0x81,0x0C, +0xA5,0xFF,0x6D,0xE3,0xBF,0xA1,0x81,0x47,0xFE,0x5B,0xC0,0x08,0x36,0x2D,0x87,0xA2, +0x37,0xE9,0x70,0xB8,0xC8,0xF6,0x7C,0xDF,0x1F,0x76,0x01,0x01,0xD8,0xB3,0x8C,0xE2, +0xB0,0x46,0xF5,0x79,0x42,0x22,0x12,0x10,0x18,0x00,0x83,0xAD,0x58,0x3D,0xA5,0xBB, +0x92,0x40,0xA4,0x07,0xA1,0x82,0x84,0x04,0x5B,0x32,0xD7,0x21,0xF6,0xF0,0x94,0x22, +0x1E,0x8E,0x52,0x49,0xBC,0x7E,0x36,0x46,0xC4,0x0A,0xB4,0xDF,0x40,0x35,0x3D,0xE1, +0x67,0x98,0x82,0x07,0xB5,0x63,0xD3,0x17,0x94,0xAC,0x63,0x2F,0x18,0xCD,0x80,0xD2, +0xCE,0x0A,0xBD,0x4B,0xE7,0x9C,0xBF,0x7B,0x45,0x71,0x95,0xD9,0x55,0xA1,0x58,0xDE, +0xB5,0xED,0xC2,0x1D,0xC2,0xD7,0x53,0xA1,0x8A,0x79,0xC6,0x59,0xDB,0x0F,0x37,0xD0, +0xBE,0x99,0x17,0x2E,0x51,0x33,0x35,0x08,0x82,0xE1,0xA2,0xE0,0xD9,0x13,0x6D,0xB4, +0xEE,0x60,0x14,0x5A,0xBE,0x77,0x8B,0xDE,0xBF,0x66,0xB9,0xDA,0x8E,0xDD,0xB9,0x47, +0x40,0x05,0x60,0x36,0x77,0xDC,0x4F,0x74,0x2A,0xD2,0xBF,0x0A,0x80,0xF6,0xF6,0x1B, +0xCA,0xEE,0x8D,0x4B,0xCF,0xFC,0xCC,0xD1,0x3F,0xAD,0xF1,0x82,0xC0,0x9B,0xA2,0x8A, +0xF6,0xFD,0xD0,0x74,0x75,0x0D,0xDF,0x4F,0x3B,0xEA,0x99,0x05,0x43,0x44,0x96,0x97, +0x9A,0xC7,0x69,0x95,0x41,0xE5,0x0F,0xBB,0xB9,0x70,0x40,0xEA,0x25,0x0E,0xC1,0x82, +0x3A,0x07,0x24,0x13,0x79,0x2D,0x1A,0x24,0x1E,0xC0,0xD5,0x33,0x3B,0x08,0xBF,0xE7, +0x88,0x96,0xE1,0x7D,0x74,0xAD,0x92,0xC3,0x19,0x47,0xE7,0xC1,0xD5,0x9D,0x53,0x74, +0x2B,0xB3,0x34,0xEF,0xD1,0x1B,0x92,0xBF,0x0C,0x50,0x62,0x73,0x47,0x95,0x80,0x56, +0xA9,0x26,0xED,0x38,0x3F,0x60,0x58,0x45,0x09,0xD3,0x0C,0x89,0xD8,0x8E,0x87,0x77, +0xC8,0x2D,0x6C,0x40,0xF1,0xE3,0x1C,0x9E,0x38,0xB8,0x84,0x34,0x4F,0xA5,0xBB,0xDC, +0x75,0x67,0x48,0x1D,0x94,0x60,0xCE,0xBC,0x55,0x3B,0xF3,0x2C,0xC5,0x85,0xE6,0x66, +0x42,0x2D,0x17,0x5D,0x77,0xB4,0x51,0x99,0x69,0x8C,0x51,0x10,0x5C,0xBA,0xC4,0x07, +0x30,0x4F,0x24,0x7A,0xBD,0xC0,0xC6,0x40,0x45,0x42,0xAA,0xCE,0xA2,0x09,0x20,0x5B, +0x92,0xA4,0xEE,0x2B,0x5D,0xB3,0x68,0x0B,0x97,0x91,0x81,0xD3,0x87,0x2F,0xD5,0x0E, +0x01,0xCE,0xC5,0x00,0xE5,0x7C,0x89,0x05,0xEA,0xEA,0x09,0x79,0x66,0x14,0x4F,0x41, +0xB3,0xFE,0x9D,0xF5,0x2B,0x23,0x5B,0x79,0x12,0x35,0x98,0xC1,0x4F,0x1E,0xA7,0xFE, +0x3A,0xA3,0xFE,0x19,0x26,0x35,0x14,0x78,0xDB,0x66,0x4D,0x7E,0xED,0x93,0x52,0x0B, +0x56,0xC9,0xDF,0xE1,0x85,0xF2,0xD7,0x8D,0x6E,0x4F,0xD1,0xFE,0xB9,0xF4,0x28,0x63, +0x7F,0xBE,0xA1,0x4F,0xFE,0x59,0x07,0x9D,0xBD,0x7D,0x1B,0xBB,0x6E,0x23,0x0D,0x83, +0x14,0x17,0x12,0x4C,0xF4,0x09,0xBE,0xC1,0x68,0x41,0x2E,0x56,0x31,0x37,0x34,0xC7, +0xAD,0xB9,0xF6,0x45,0x5E,0x13,0x2B,0xF2,0xCE,0x69,0x21,0xFD,0xC0,0x4B,0x73,0x4C, +0xA3,0xF5,0x6C,0x87,0xD6,0xEC,0xBA,0x63,0x8A,0xB1,0xD4,0x9E,0x4A,0x49,0xE8,0x9E, +0x7B,0xC9,0xD1,0x59,0xF5,0x59,0xC6,0x47,0x01,0x89,0x11,0x8D,0x77,0x52,0x9C,0x54, +0xDB,0x32,0x6F,0x59,0x07,0x08,0x5C,0x83,0xE2,0x61,0xDF,0x72,0x3D,0xA7,0xB8,0xFF, +0x99,0x58,0xFC,0x1C,0xAA,0x13,0xC2,0xDA,0x20,0x5D,0x8F,0xD8,0x40,0x4B,0x92,0x5F, +0x95,0x34,0x8A,0xC9,0xF3,0x48,0x26,0x66,0xE5,0x64,0x53,0xF1,0x48,0x47,0x0C,0x36, +0xB1,0x86,0xDE,0x82,0xF2,0xE8,0x71,0x7A,0x22,0xF1,0x47,0xDB,0xF0,0x3E,0x47,0xA5, +0x77,0xAA,0x5C,0x64,0x40,0x9D,0xF0,0x4D,0x89,0x34,0x16,0x05,0x2D,0x3D,0xB1,0x0A, +0x33,0x05,0xB5,0x63,0x48,0x4D,0x48,0x07,0x48,0x36,0x2A,0x8D,0x17,0xC9,0x01,0xCA, +0x48,0xC4,0xBA,0x98,0x41,0xF1,0x51,0x3B,0xCA,0xAC,0x7F,0x2B,0x76,0x96,0x2A,0xF5, +0xF7,0x5A,0xED,0xF7,0x8F,0x6C,0x81,0xE9,0x3C,0xC2,0x59,0xEE,0x23,0x67,0x5A,0x94, +0xC3,0x97,0x32,0x97,0xFC,0x6A,0x81,0xCB,0x76,0x2E,0xC1,0x19,0xDA,0x52,0x0B,0xC5, +0x69,0xBA,0xA6,0x2F,0xA3,0xC2,0x42,0x0C,0x52,0xC3,0xFB,0x90,0x07,0x2F,0x8C,0x86, +0xD8,0x7E,0xC8,0x5F,0x6E,0x3C,0x3C,0x14,0x2A,0x3B,0x64,0xFB,0xB8,0x2C,0x96,0x35, +0x19,0x94,0x8E,0x11,0xB7,0x36,0xB2,0xF3,0x5A,0x60,0x9D,0x1F,0x2F,0xF6,0x54,0x2B, +0x8B,0x80,0xFB,0x54,0xFD,0x70,0x3B,0x09,0xEF,0xA5,0xD0,0x31,0x3E,0x45,0x2F,0x71, +0x84,0xE3,0x2E,0xB9,0x29,0x9A,0xB9,0x26,0x57,0xE9,0x5F,0x99,0x94,0xF8,0x5E,0x6F, +0x21,0xE0,0xBD,0x41,0x1B,0x0F,0xF9,0xB2,0x27,0xC7,0xDF,0x95,0x4D,0x57,0xC0,0x84, +0x9D,0xD4,0xB2,0x68,0x6D,0x6B,0x99,0xCB,0x84,0x63,0xCC,0xE5,0xD1,0x81,0xFA,0x5F, +0x64,0x8A,0xA7,0x1A,0x95,0xA2,0x9D,0xAD,0xD2,0xA8,0x83,0x0E,0x7A,0x54,0xFF,0xB9, +0x8B,0x13,0xE4,0xC9,0x1D,0xE2,0xE2,0xAB,0xA9,0x46,0x38,0x20,0x2D,0xE8,0x8C,0x24, +0xE0,0x4D,0xDE,0xC0,0xD7,0x99,0x4D,0x6A,0x34,0x9F,0xF0,0x42,0xBD,0x5E,0xC5,0x48, +0x84,0x4A,0x89,0xD3,0x80,0x2C,0x63,0x56,0xBF,0xEC,0xB6,0x11,0xAE,0xCB,0x20,0x1C, +0xFE,0xDD,0xD9,0x14,0xE4,0x67,0x75,0x8D,0x0B,0x70,0xCB,0x75,0xE6,0xC8,0x42,0x29, +0x39,0xAD,0x76,0x6E,0x34,0x5D,0xC8,0x06,0x5D,0xDB,0x33,0x3C,0x40,0x0F,0x50,0x0A, +0xCE,0x32,0xEF,0x2F,0x2E,0x39,0x9D,0x90,0x75,0x6D,0xC7,0xE9,0xE3,0xE2,0x76,0xF9, +0xDA,0x92,0xDE,0x1A,0xCA,0x3A,0x36,0xF8,0xCE,0x6A,0x7C,0x1A,0x82,0x9F,0x5A,0x03, +0x6E,0xD7,0xD4,0x6C,0x34,0x89,0xB9,0x2C,0xF8,0x21,0xCC,0x07,0xBC,0x70,0xC7,0x83, +0x1E,0xC6,0xE3,0xAA,0x2B,0x91,0xC7,0x58,0x6C,0xEA,0xB8,0x31,0x98,0xFC,0xD5,0x6A, +0x79,0xE2,0xE0,0xC2,0x8B,0x7A,0x20,0x44,0x63,0xF3,0xEA,0x94,0xE9,0xF3,0xB0,0x95, +0xBD,0xFF,0x5A,0x62,0x12,0xC2,0x53,0xCF,0x7B,0x08,0x83,0xF8,0xED,0x8E,0x6B,0x11, +0x73,0xF5,0xC2,0x72,0x2F,0x77,0x80,0xF9,0x92,0x70,0x80,0xA2,0x8D,0x4C,0x1B,0x7B, +0x38,0x8A,0x3D,0x86,0x1F,0x3B,0x52,0x45,0x15,0x5B,0x3B,0x97,0xD0,0xFD,0x4A,0x7E, +0xE0,0xEF,0x4E,0xBA,0x1A,0x4E,0x67,0x7E,0xE7,0xAE,0x34,0x0D,0x2A,0x7A,0x1C,0x8E, +0x3A,0x76,0xC7,0x2F,0x79,0x8C,0x03,0xE9,0xA7,0x42,0xD7,0x6E,0x46,0x24,0x51,0x7B, +0xDA,0x9A,0xAB,0xC7,0x63,0xDA,0xCD,0xAB,0xE0,0x5F,0x9E,0x81,0xF2,0x01,0x61,0x13, +0x15,0xD9,0x1D,0xD7,0x36,0xA1,0xA8,0x59,0xD6,0xFE,0x66,0xB7,0x35,0x7D,0x6D,0x8D, +0x59,0x16,0xC4,0xC3,0x0C,0x29,0x68,0x52,0xA5,0x87,0xA0,0xC2,0x79,0x56,0x59,0xC8, +0x85,0x22,0xA0,0x2B,0xF6,0xA1,0x66,0x9A,0x6F,0x76,0xE7,0xF1,0x59,0x53,0x2E,0x81, +0xF6,0x5D,0x1A,0xEB,0x27,0x41,0x3E,0x47,0xF5,0x77,0xCD,0x24,0x78,0xC1,0x39,0x36, +0x70,0x2B,0x32,0x75,0x0C,0xE2,0x4A,0xB7,0x76,0x07,0x66,0x2E,0x9D,0x42,0xEB,0x02, +0x30,0x6C,0x9C,0xB6,0x7A,0x22,0xFB,0x6C,0x83,0x52,0x2B,0x30,0xD0,0xEE,0x7A,0x86, +0xF9,0xCA,0x15,0x8A,0xC8,0x39,0xEB,0x49,0xC6,0x5C,0x85,0x56,0x21,0xB3,0xE2,0xEC, +0x19,0x32,0xF9,0x13,0x1A,0x17,0x89,0x74,0x3F,0x48,0x9C,0x12,0xC3,0xDA,0x5F,0x48, +0x67,0x78,0x3B,0x1E,0xEE,0xCD,0x18,0xE8,0x17,0x2A,0x70,0xD4,0xC3,0xDE,0x62,0x87, +0x43,0xAD,0x76,0x98,0x87,0x50,0xA5,0xAC,0x3F,0xDD,0x9B,0x72,0x76,0xDC,0x80,0xD6, +0xC4,0x36,0x81,0x83,0x3E,0x7F,0x6D,0x48,0x58,0x0E,0xCD,0x73,0xAC,0xD8,0xD4,0x9E, +0xB4,0x4D,0x9A,0xE7,0xEA,0xBA,0xE3,0x7A,0x5F,0x94,0xE8,0x89,0xBF,0x87,0x6E,0x3A, +0xE0,0x6A,0xDC,0x43,0x13,0xC7,0xD8,0xE6,0xC3,0x50,0x8C,0xB6,0x67,0x51,0x68,0xC9, +0x75,0xA5,0x14,0x88,0x91,0x76,0x5B,0x74,0x81,0x84,0xD5,0x20,0xFF,0xA2,0xFA,0xBB, +0xA5,0xEE,0xE6,0x70,0xDE,0x4E,0x2C,0x6C,0xF4,0x75,0xC1,0x48,0x82,0x2E,0x45,0xFB, +0x53,0xDE,0xE0,0xA3,0x6A,0xE4,0x8A,0xB2,0x40,0x63,0xE4,0x42,0xEC,0x58,0x52,0x3E, +0x29,0x76,0x59,0xED,0xD3,0xCD,0x39,0x8D,0x0E,0x86,0x28,0x73,0x95,0x0A,0x01,0x58, +0x02,0xEB,0xEB,0xC8,0xE0,0xCE,0xE4,0xDA,0x4B,0xB1,0x1E,0x33,0xD3,0x52,0x20,0xB1, +0x46,0x83,0xDD,0x2E,0x02,0x2D,0x2B,0xB1,0x30,0x78,0x5E,0xCB,0xEF,0xED,0xCC,0x20, +0xBF,0xD1,0xA1,0x8A,0xA1,0x22,0xB6,0xDB,0x3A,0x87,0x7B,0x65,0xB1,0xD7,0xB3,0x7E, +0xD6,0x63,0x69,0xE8,0xEA,0xE8,0x9D,0x10,0x45,0xAD,0x14,0xC0,0x0A,0x90,0xC3,0xBE, +0x36,0x6C,0x10,0x42,0x0C,0xDD,0x28,0x13,0x71,0xE7,0xF4,0xC5,0xE7,0x91,0x5A,0xCF, +0x87,0x43,0xEA,0xB1,0x60,0x8C,0x04,0x90,0xE8,0x0B,0x73,0x3A,0x91,0x8B,0x68,0x56, +0x89,0xC2,0x21,0x29,0xA3,0x3B,0xCF,0xF8,0x91,0x5C,0xE9,0x4B,0x74,0xD2,0xF1,0x7F, +0xDE,0x69,0x3D,0x83,0xE8,0xC7,0x3F,0x56,0x67,0xDE,0xA8,0xFE,0x7C,0xD9,0x2D,0xEF, +0x28,0x21,0x39,0xC7,0x15,0xF0,0xDA,0x23,0x47,0xB1,0x3C,0xF3,0x14,0xBD,0x10,0x68, +0xC2,0xE3,0x44,0x0C,0x85,0xC1,0x52,0x8A,0xA5,0x9D,0x4D,0xEB,0x83,0xA3,0xA5,0x7A, +0xA9,0xBF,0x66,0x8B,0x82,0xDA,0x37,0xEE,0x37,0x31,0x19,0xF9,0x02,0x4D,0x2E,0x07, +0x89,0x15,0x9B,0x60,0xA2,0x7A,0x93,0xCE,0x85,0xAD,0xB3,0x51,0x42,0x06,0xCA,0x40, +0x8C,0x97,0xCE,0xEA,0x5D,0x93,0x8D,0xC6,0x8E,0xF9,0x5B,0xCE,0x2F,0xE6,0x60,0xB6, +0xC0,0xE4,0x3C,0x16,0xAC,0x33,0x27,0x5E,0x9F,0x7A,0x74,0x26,0x09,0x61,0xB0,0xFF, +0x17,0x07,0xAB,0x80,0x44,0xA1,0x09,0xB6,0x77,0x38,0x2C,0xCD,0xEC,0x74,0x43,0xE3, +0xAA,0xE4,0x78,0x35,0xE5,0x50,0x47,0xA7,0xCE,0xB9,0xC4,0xFA,0xD0,0xFC,0x1A,0xFB, +0x7C,0x3D,0x5B,0x3E,0x2B,0xFC,0x0D,0x59,0xD5,0x83,0x75,0xD6,0x0B,0x41,0x7D,0xA1, +0x55,0xFC,0xE2,0x73,0x7B,0x8E,0x7D,0xD9,0x8D,0x6C,0x18,0xBA,0x71,0x02,0xD2,0xDB, +0x5F,0xA6,0xA7,0xF0,0x72,0x73,0xC6,0x29,0x72,0x42,0x01,0xA9,0x71,0x42,0xA4,0xCB, +0xAA,0xD1,0xD7,0x05,0xBA,0x2A,0xB1,0xBD,0xBD,0xBC,0x76,0xB9,0xCF,0xFF,0x7A,0xFA, +0x5C,0xF1,0xFE,0x74,0xBD,0x91,0xC1,0xFC,0x9E,0x38,0x95,0xD9,0x5B,0x63,0xD2,0xA8, +0x0F,0xDA,0x67,0xD1,0xD8,0x26,0x24,0xEF,0x6D,0x17,0xFD,0x8F,0xEA,0x0D,0xFC,0x2B, +0xAF,0x74,0x29,0x1F,0xC4,0x0B,0x25,0xCA,0x14,0xCF,0x13,0x0D,0x82,0xB1,0x3E,0x94, +0x7B,0x07,0x4D,0xE4,0xAA,0x04,0xD5,0xBF,0x2E,0x92,0xC2,0x6B,0x0A,0xA1,0x1A,0x81, +0xD0,0x6D,0xFA,0x6A,0xF8,0xF3,0x3A,0x4A,0xF8,0xA1,0x07,0xE3,0x1A,0xE8,0xDE,0x9F, +0x6F,0x19,0x92,0x69,0xD2,0x29,0x98,0xA4,0xB8,0x44,0x26,0x98,0xB6,0x8C,0xAE,0x80, +0x30,0xF9,0xCA,0xDB,0x7F,0x8A,0xD9,0x25,0x06,0x79,0x11,0x0E,0x4D,0x42,0x80,0x29, +0x3D,0xA2,0xB3,0x5A,0x7B,0xC1,0x33,0xDF,0xFF,0x7D,0xA6,0xFD,0xBE,0x14,0xBD,0xA5, +0x20,0x6F,0xB5,0xA1,0x6B,0xE8,0x0E,0x5C,0x49,0x6A,0xF2,0xD3,0xCB,0x96,0xB9,0x08, +0x82,0xFC,0x56,0xED,0x9D,0x10,0x6F,0x6C,0x4A,0xBA,0x01,0x50,0x10,0x06,0xD3,0x0C, +0x03,0x89,0x79,0x46,0x58,0x02,0xF8,0xF0,0x62,0xB1,0xAB,0x7C,0xBA,0x4B,0x55,0xD0, +0xAB,0x86,0x7F,0x7E,0xCA,0x01,0x2E,0x21,0x2A,0x23,0xD0,0xFB,0xE3,0xB3,0x94,0x5D, +0x6E,0xE2,0xAC,0x04,0x00,0xCB,0xA4,0x58,0xC8,0xDD,0xA4,0x09,0x6A,0x0B,0xAD,0x83, +0x23,0xBF,0x04,0x24,0x0F,0x9E,0x08,0x9C,0x0B,0x6F,0xBD,0xFB,0xCF,0x13,0x22,0x0D, +0xF0,0x7A,0x9B,0xE8,0xA8,0xF7,0x1E,0xC1,0x34,0xA6,0x9B,0x0C,0x2B,0x35,0x77,0x31, +0xAB,0x5D,0x0F,0xDF,0x73,0x0B,0x03,0x24,0xBB,0x9B,0xAB,0xC3,0x32,0x22,0x62,0x49, +0x83,0x97,0x69,0xBD,0xD3,0xAF,0x56,0x70,0x05,0xE3,0xA4,0x7E,0xD5,0xD8,0x7E,0x3B, +0x39,0x5A,0xBC,0xE9,0x41,0xF9,0x05,0x9C,0x75,0x8C,0x11,0x07,0x22,0x9E,0x6C,0xD7, +0xC1,0xE3,0x37,0xA0,0xCE,0x1E,0x7A,0x98,0x1D,0xEC,0x25,0x19,0x07,0x0D,0xB3,0x1C, +0x65,0xB8,0x7C,0x3F,0x26,0xDD,0x32,0xFB,0x86,0xCF,0xF8,0x60,0xE9,0xB5,0x6D,0xDA, +0x7F,0xD0,0x59,0x8B,0x51,0x0E,0x1F,0xDA,0xE6,0x19,0x12,0x7A,0xD7,0x0C,0x8D,0x85, +0x35,0x28,0xE8,0x6E,0x94,0xE6,0xB0,0x57,0xAC,0x16,0x65,0xA1,0x6A,0x81,0x06,0x09, +0x0E,0x99,0xC1,0x84,0x63,0xCD,0xD7,0xD3,0x0B,0xA4,0x27,0x99,0xC1,0x66,0x04,0x38, +0x23,0x08,0x2B,0x1B,0x22,0x03,0xE5,0x56,0x0A,0x1F,0x2F,0x20,0x8E,0xE1,0xC0,0x06, +0x2F,0xDA,0xC2,0xED,0x90,0x48,0xD8,0x11,0x8C,0x01,0xCD,0x28,0x6E,0x1E,0xAE,0xA2, +0xC8,0x7D,0x7F,0x8F,0x90,0xE8,0x4E,0xAD,0xE1,0xF6,0x2B,0x73,0x08,0xED,0x8E,0x05, +0x49,0x5A,0x3A,0xC0,0x7D,0x66,0xE8,0xE5,0x9E,0x2C,0xA1,0xD5,0x7F,0x70,0x73,0x9F, +0xC0,0x24,0xA3,0x89,0x55,0xF1,0xB7,0x94,0xE6,0x1F,0xC1,0x64,0xA5,0x0A,0x78,0x65, +0x8C,0xC9,0xDF,0x64,0x36,0x68,0xCA,0xA4,0x4C,0xB0,0x4B,0xC6,0x26,0xF6,0x45,0x12, +0x62,0x2D,0xB9,0x80,0x21,0x06,0x1B,0xCE,0xF6,0xEF,0x4A,0x72,0x99,0x66,0x41,0xEA, +0x99,0x4A,0x1C,0xE4,0xF7,0xC7,0x9B,0x86,0xC3,0x01,0xB7,0x76,0xCE,0xC2,0x6F,0xD9, +0x70,0x16,0x22,0xC5,0x28,0x6B,0x16,0x99,0xA0,0x71,0xA1,0x0B,0x34,0xFE,0xA1,0xDC, +0x90,0xF5,0x34,0xC5,0x56,0xA3,0x08,0x6C,0xA0,0xB9,0x98,0x63,0x48,0x6F,0x4E,0x8D, +0x83,0x2C,0x26,0x37,0x33,0x0C,0xCD,0x56,0xE3,0xF1,0x8E,0x20,0x64,0xA4,0x55,0x8B, +0x9F,0xAF,0x6C,0xFE,0x98,0xF7,0xF8,0x7A,0xA0,0x58,0x7A,0xFE,0x09,0x74,0xBD,0x1E, +0xA4,0xF9,0xAD,0x06,0x04,0x37,0xE0,0xFD,0x2B,0xD4,0xC3,0x22,0xB9,0x5A,0x19,0xC3, +0x12,0xA9,0xFF,0xB4,0xB4,0x9B,0x76,0x5A,0x2F,0x94,0x75,0xAD,0xD2,0x1B,0x44,0x62, +0x32,0x6E,0xC8,0x1F,0x0F,0xAC,0x5F,0x80,0xD6,0x0C,0xBB,0x05,0xC1,0xDC,0xB3,0xB8, +0xCD,0x75,0xAA,0xD5,0x80,0x01,0x3D,0x16,0x33,0x64,0xB1,0xD1,0x5E,0xD4,0xB6,0x14, +0xD3,0x42,0xA3,0xFD,0x95,0xBF,0xAF,0x8A,0x6F,0xC1,0x17,0xB3,0x3E,0x25,0x74,0x62, +0xE3,0x76,0x0F,0xC4,0xC4,0x6A,0x3B,0xC0,0x42,0x4C,0x43,0x51,0x41,0x13,0x74,0x76, +0x13,0xB3,0xAF,0xD7,0xD1,0x68,0x92,0x34,0x7B,0x7B,0x10,0x1E,0x65,0x8A,0xD1,0xD1, +0x90,0xD1,0xBC,0x97,0x6A,0x8C,0x8E,0xA2,0xA8,0x65,0x0F,0xB6,0x64,0x0C,0x77,0x9D, +0xFB,0x07,0x43,0x38,0x2D,0x78,0x96,0xFD,0x73,0xE7,0x78,0xD5,0xD3,0x4D,0xD0,0x9D, +0x3B,0x01,0xE8,0x5C,0xF5,0x3F,0x8C,0xC4,0x87,0x02,0x5F,0xB5,0xB9,0x20,0x54,0x99, +0xB0,0x82,0xE9,0x06,0x39,0x0A,0xD3,0x1D,0x82,0x32,0x36,0xEF,0x46,0xBC,0x72,0x81, +0x02,0x8F,0x6E,0xC5,0x55,0x89,0x85,0x46,0x96,0x2C,0xA7,0x22,0x91,0xF5,0x30,0x4A, +0x70,0x11,0x86,0x06,0xCB,0x30,0x7A,0x35,0xD6,0x46,0x71,0x5B,0x4C,0xE1,0x2B,0x3A, +0x78,0xB4,0x16,0xD2,0x1D,0x40,0x88,0x71,0x25,0x1F,0x61,0x84,0xA4,0x88,0x9C,0x40, +0xC0,0x45,0x8B,0x95,0x77,0xF2,0x24,0xD2,0x51,0xCC,0x1F,0xAD,0x98,0xF2,0x42,0xF4, +0x6A,0x74,0xDE,0x28,0x32,0x72,0x7B,0x2E,0x97,0x32,0x5E,0x75,0xC9,0x63,0xB4,0x6A, +0x79,0x3E,0x0A,0x0D,0x9C,0x20,0xC2,0x49,0x89,0x97,0x8A,0x82,0x06,0x71,0x39,0x1E, +0x5C,0xC7,0x79,0xCC,0x52,0x57,0x52,0x35,0xD8,0x62,0x0E,0x6C,0x61,0xAE,0x93,0x2D, +0xD3,0x3F,0x35,0x86,0x6F,0x6D,0xAE,0x5F,0xB7,0x86,0xC9,0x2C,0x04,0xB0,0x99,0x2E, +0x8F,0xFE,0xAF,0xD4,0xAB,0xBD,0x6A,0x59,0x48,0xB2,0xA3,0xDE,0xA7,0x64,0x00,0x6E, +0x7E,0xDF,0xA8,0x6C,0x1F,0x85,0x8A,0xF2,0x88,0x65,0xDE,0x25,0xD4,0x1D,0x76,0x55, +0xA7,0xC1,0x0F,0xAB,0xA3,0x3A,0x73,0xAB,0x11,0x15,0x5E,0x5D,0x1C,0x68,0x9C,0x64, +0x13,0x09,0x50,0xF9,0xA8,0x14,0xD7,0xC3,0x0E,0xA9,0xA8,0x07,0x3A,0x6A,0xFE,0x50, +0xB3,0x89,0xD7,0xB8,0x2C,0x1F,0x78,0x10,0xBF,0x7B,0x5A,0xE4,0x52,0xC3,0x0E,0x6B, +0x62,0x12,0x12,0x8A,0x5A,0xB2,0x35,0x6A,0x42,0xEB,0x89,0xC5,0xE2,0xE4,0xBB,0xB5, +0xF2,0xE7,0xF3,0x88,0xDD,0xEE,0xC5,0xAB,0xFA,0xDA,0x34,0x51,0xFB,0x81,0x81,0x99, +0xC1,0xE2,0x20,0x5A,0xEC,0xEF,0xFA,0x28,0xC6,0xBF,0x30,0x10,0x23,0xAF,0x3D,0xE9, +0xBE,0x89,0xC9,0x8C,0x3B,0xAC,0x03,0x62,0x00,0x3E,0xCB,0x03,0x0D,0x12,0x71,0x74, +0xE2,0x90,0xD9,0x84,0x5B,0xCE,0xED,0xC3,0xCA,0xC9,0x1E,0x23,0x13,0x98,0xA8,0x7F, +0x18,0x51,0xE4,0xE3,0x17,0xFC,0x96,0xEB,0x77,0xF5,0x67,0xF1,0xD1,0x64,0xD5,0xBC, +0xAC,0xB5,0x9B,0x2F,0x9A,0x40,0xB7,0x12,0xF1,0x33,0x09,0x84,0x62,0xF6,0xB2,0x44, +0x96,0xE0,0xEE,0x1B,0x4F,0xE2,0x93,0x95,0xED,0x06,0x12,0x6E,0x60,0x6D,0x81,0xEF, +0xB7,0x7E,0x94,0x46,0x51,0x2A,0xA1,0x98,0xB4,0xC7,0x67,0x47,0x24,0x38,0xA3,0x48, +0xA7,0x74,0x54,0x60,0xE2,0x74,0x69,0x8E,0x85,0xE4,0x24,0xBB,0xA2,0xF9,0xBF,0xF8, +0x16,0x1F,0x8C,0x1E,0xBF,0x87,0x4A,0x1B,0xEF,0x78,0x5F,0x56,0x7A,0x7F,0xD7,0x78, +0xF2,0xC0,0xE3,0xFF,0xFA,0xAA,0xFA,0x59,0x81,0xB3,0x54,0x34,0x2B,0xFE,0x75,0x66, +0x52,0x7D,0xA1,0x59,0x1E,0x7A,0xCA,0xE2,0x36,0xE7,0x93,0xAD,0x1D,0x62,0x7D,0x2E, +0xEF,0x2D,0x63,0x4C,0x68,0x5E,0x7C,0x80,0xB4,0x95,0x6D,0x77,0x9D,0x18,0x36,0x59, +0xC9,0x5B,0x7D,0x7A,0x8C,0x1E,0x0D,0xF7,0x9B,0x9A,0x4E,0xD8,0x69,0x2D,0x33,0xDA, +0xAD,0xF1,0x2B,0xB9,0xF2,0x91,0xFE,0x70,0xA6,0x45,0xFC,0xD5,0xAF,0x85,0xFF,0x49, +0x16,0xAA,0xD6,0x3C,0x6D,0xB1,0x69,0xE3,0x52,0x07,0x14,0x35,0xF2,0x18,0xC0,0x75, +0x58,0x2B,0xC7,0xD5,0xAA,0x47,0x59,0xBC,0x61,0xFD,0x62,0x7A,0x22,0xA3,0x23,0x89, +0xDE,0xB7,0x24,0x07,0x50,0x9B,0xB4,0x85,0x1C,0x61,0x9A,0xC3,0xFC,0x88,0xE6,0x69, +0x08,0x0D,0x9E,0xB4,0x4C,0xA2,0xE1,0x94,0x40,0x10,0x62,0x69,0xDC,0x6B,0xAE,0xC4, +0x9E,0x3C,0xF3,0x83,0xAD,0xC1,0x63,0x18,0x19,0x8F,0x59,0x0B,0xD3,0x83,0x8B,0xD7, +0xB5,0xC4,0x11,0x99,0x02,0xAD,0xCB,0xD4,0x93,0xB6,0x0B,0xD9,0x5B,0x96,0xD4,0x44, +0xDA,0x5E,0xB1,0xA8,0x03,0xCB,0x85,0x50,0xF4,0xEB,0x81,0x54,0x1A,0xAB,0x63,0xD8, +0x3E,0x40,0xD1,0xCC,0x85,0xCB,0xEC,0x37,0xD2,0x7C,0x29,0xB1,0x1A,0xA9,0x01,0x9F, +0x05,0x0C,0xDF,0xAC,0xB2,0x5A,0x9C,0xF8,0x8C,0x62,0xF1,0x9A,0x72,0x2F,0x20,0x46, +0x78,0x86,0xB6,0xAF,0x60,0x31,0xAD,0x1A,0xA9,0x39,0x0E,0x23,0xAA,0x69,0x59,0x03, +0x2C,0x1C,0x09,0x77,0xFC,0xB9,0xFD,0x39,0x83,0x7F,0xA9,0x9A,0x8A,0x6C,0xB7,0xE9, +0x69,0x2F,0x9E,0xB1,0x80,0x18,0x58,0x8E,0x96,0x75,0x0C,0x27,0x29,0xBF,0x0E,0x9E, +0x2D,0x89,0x92,0xDB,0x1B,0x0C,0x29,0xEB,0x9B,0xA6,0x0D,0x02,0x50,0x05,0xBA,0xC0, +0xC0,0x2A,0x20,0xF2,0x18,0xDB,0xA5,0xCC,0xA5,0xB4,0xF2,0x83,0x1C,0x1F,0x28,0x21, +0xE7,0x3A,0x7F,0x37,0xEC,0x46,0xEB,0x62,0x81,0x5C,0x9C,0x1A,0xE1,0x5E,0xF5,0x26, +0x04,0x19,0xB9,0xB8,0x93,0x4D,0x08,0x0A,0x3B,0xB3,0x06,0x4E,0xE9,0x95,0x07,0x4F, +0x6D,0x46,0x0F,0x45,0xD5,0xC4,0xF2,0x4A,0x71,0xEF,0xE1,0x8B,0xC1,0xE3,0x28,0xB0, +0xDC,0xE0,0x1D,0xB9,0xB3,0x53,0xB0,0xA6,0xAF,0x37,0x3F,0xB1,0x6C,0xC6,0xF6,0xEB, +0xF6,0x34,0xBD,0xA2,0x1E,0xDF,0x8C,0x5E,0xA4,0x3B,0x84,0x68,0xF4,0x0E,0xBE,0x55, +0x93,0x0E,0x7D,0x76,0xEB,0xFB,0x3F,0x3F,0xAD,0x7C,0xBC,0xE3,0xEC,0x9A,0x5E,0x2D, +0xF0,0xE9,0x83,0x4D,0xA3,0x10,0xCE,0x61,0x65,0x57,0x8D,0xE6,0x74,0xC2,0x31,0xB6, +0x75,0x94,0x23,0x7E,0xF3,0x99,0x07,0x05,0x59,0xAD,0xB5,0xB7,0xD9,0x85,0x60,0xC5, +0x24,0xBA,0x6A,0xA7,0x1A,0x45,0x0F,0xE8,0xF6,0xD7,0xCF,0x6C,0x92,0xC9,0x5B,0x89, +0x18,0x99,0x5A,0x11,0xC0,0x1F,0x6B,0x4C,0xA1,0x85,0x54,0x80,0x08,0x92,0xAB,0x37, +0xA4,0x94,0x5A,0x49,0x5E,0x78,0xF2,0xD2,0x40,0xDA,0x6E,0xAF,0xDB,0xD0,0x8F,0xC9, +0x11,0xE5,0x3F,0x1E,0x1A,0x86,0x6B,0x9B,0x47,0xF9,0x03,0x0C,0xAC,0x49,0xAB,0xA7, +0xB6,0x4D,0xCA,0x32,0x81,0xE4,0x87,0x2D,0x4D,0x3D,0x3B,0xD9,0x51,0x66,0xE1,0x61, +0x7F,0x98,0x06,0x18,0xC9,0x43,0xC3,0x92,0xC0,0x81,0x80,0x2F,0xA5,0xA8,0x8E,0x7B, +0x0C,0xE8,0x4C,0x7C,0xE1,0x06,0x6B,0x32,0x92,0xD2,0x50,0xBD,0x5F,0xC3,0x73,0x48, +0xDA,0x3A,0x82,0x1A,0x74,0x5C,0x88,0xFF,0x46,0x96,0x6E,0xC4,0x14,0x3E,0x0B,0x54, +0x5B,0x75,0xE9,0x0C,0x8F,0x75,0xA1,0x33,0x6C,0xC7,0x8B,0x69,0x31,0xCE,0x12,0xFF, +0x46,0x40,0x14,0x92,0x89,0x53,0x8D,0x47,0x8A,0xEB,0x6E,0xEC,0xB0,0xE3,0x0E,0xD6, +0x92,0xF7,0xA2,0x3C,0xCB,0x71,0x52,0xF9,0x85,0xB0,0x04,0xB2,0xAA,0x33,0x59,0xEF, +0xA0,0x69,0xB2,0xA5,0xDF,0x84,0x94,0x50,0xEF,0xE9,0xEE,0x22,0x5B,0xE2,0x7C,0x57, +0x9B,0x2E,0xCB,0x9D,0x5B,0xB8,0x35,0x96,0x7B,0x50,0xC3,0x82,0xAF,0xA1,0xC4,0x1C, +0x06,0x08,0xD9,0xE6,0xC6,0x9F,0x32,0x4C,0xC3,0xEB,0x2A,0xFB,0xFD,0xA0,0x3B,0x34, +0xE7,0xE7,0x20,0x54,0x27,0x4C,0x9F,0xE5,0xB8,0x28,0xCE,0xA4,0x71,0x46,0xBF,0x89, +0x13,0xD1,0x36,0xB4,0x3E,0x07,0x9A,0xEC,0x0A,0xBB,0xFE,0x2A,0xB2,0xDD,0xA6,0xB2, +0xD2,0x4C,0x52,0xF3,0xCC,0xDF,0x0E,0xA1,0x8D,0xD4,0x96,0x8C,0xC0,0xAC,0x09,0x1E, +0x2F,0x85,0x10,0x5F,0xCA,0xC3,0x82,0x54,0x3E,0xA6,0xC5,0x50,0x22,0x7B,0x5B,0x00, +0xF3,0x71,0x96,0xAF,0xE7,0x20,0x44,0xB9,0xC9,0xC5,0xA6,0xBB,0x6D,0x80,0x0E,0x34, +0x05,0xD3,0x1E,0xB9,0x3F,0xB1,0xF3,0xFC,0x2C,0x47,0x58,0x6E,0x72,0x61,0xB8,0xF3, +0x42,0x35,0xBE,0x0C,0x70,0x34,0xA0,0x7F,0xD6,0xA3,0x7A,0x6B,0xA2,0x84,0x2F,0x3D, +0x8D,0xE9,0x98,0xA3,0x8D,0x42,0xFF,0x44,0x98,0xBB,0xFF,0xC9,0xB0,0xE7,0x37,0x76, +0x41,0x03,0x30,0xA3,0xB0,0x99,0x02,0xBB,0xAC,0xD3,0x78,0xD2,0xC5,0x87,0x51,0x90, +0xAD,0xE7,0x6F,0xF1,0x83,0x6C,0x86,0x2D,0xF7,0x4D,0x59,0x2D,0xC8,0xDB,0xB1,0x54, +0xCB,0x10,0x8C,0x16,0xBC,0xC4,0x70,0x5B,0xA5,0x2E,0x9F,0x3D,0xCC,0x82,0x53,0xF6, +0xE2,0x2C,0x79,0x26,0x2A,0xF6,0xE3,0x22,0x01,0xDF,0x7F,0x68,0xDF,0x4F,0x28,0xD4, +0x18,0x2A,0x1D,0xA7,0x68,0x2C,0x6A,0x9C,0x2B,0x5D,0x43,0xB4,0x21,0xED,0x7A,0xC9, +0x08,0xE0,0xCE,0x4D,0x0A,0x15,0xAD,0xE3,0x32,0x25,0xD0,0x5D,0xD3,0x9D,0xFE,0x77, +0x0C,0x81,0x6D,0xB0,0x9C,0x0F,0xFA,0xBC,0xE4,0x4F,0xEF,0x00,0xB9,0x2C,0x9E,0xC1, +0xFB,0x51,0x44,0x5A,0xE0,0x81,0xE9,0x09,0x0A,0x2D,0xA1,0x9A,0xE8,0x95,0xDB,0x53, +0x44,0x36,0xEA,0xB8,0xD1,0xE7,0x3F,0x80,0xCA,0x27,0x31,0xF9,0xA9,0x74,0xB5,0x92, +0x82,0xB7,0x9C,0x6E,0xF5,0x75,0x0B,0x97,0x2D,0x71,0xD1,0x47,0xA8,0x40,0x8F,0xE5, +0x47,0x33,0x6D,0x51,0xD1,0x53,0x09,0xFE,0x60,0xAF,0xC6,0x6F,0x85,0x9B,0x5A,0xE4, +0xCB,0xE9,0x2A,0x44,0x29,0x2D,0xEA,0xE0,0xEE,0xC6,0xE3,0x62,0xC9,0xBD,0xE4,0x30, +0xDF,0x0F,0x0D,0xEF,0x57,0x1F,0xB7,0x12,0x9E,0x6D,0xFC,0x9A,0x7B,0x0C,0xEE,0x05, +0x2B,0x4F,0x88,0x4D,0x9E,0x0C,0xE4,0x37,0x24,0x37,0xF2,0x2A,0x36,0x87,0x31,0xA7, +0x74,0x9E,0x3C,0x85,0x78,0xA6,0xAF,0xA3,0x84,0xE0,0x36,0xCC,0x3D,0x70,0xC9,0x20, +0x9F,0x23,0xFD,0xFE,0x95,0x4D,0xA8,0xA0,0xD0,0x88,0xE4,0xE3,0xA8,0xAA,0xC0,0x4D, +0xD6,0x59,0xA5,0x65,0x8C,0x43,0x43,0xAD,0xC4,0xA6,0xC4,0x1C,0xE1,0x61,0x6F,0x8C, +0xE2,0x36,0xE6,0xCA,0xD4,0x11,0x5C,0x49,0xC2,0x5E,0xF2,0xDD,0xEF,0xD3,0x7B,0xFA, +0x5A,0xDE,0x6F,0x65,0x24,0xFF,0x2B,0x72,0x95,0xAF,0xCD,0x09,0x7C,0xFF,0x94,0x51, +0xCB,0x0F,0xDA,0x4B,0x11,0x2E,0x83,0x46,0xE2,0x3A,0x75,0x86,0xCB,0x45,0x98,0xE7, +0x09,0x33,0x72,0xC7,0x5C,0x15,0x62,0x19,0xD3,0x65,0x35,0xF9,0xDF,0x38,0x49,0x5C, +0x80,0x98,0x9E,0x80,0x07,0x27,0xE5,0x14,0x7E,0x80,0x40,0x1F,0xA9,0x12,0x6E,0x3D, +0x95,0x85,0xB7,0xF8,0xE2,0xB6,0x34,0x73,0xE8,0x54,0x19,0x67,0x7C,0xF6,0x5E,0x38, +0xD2,0xAD,0x14,0x05,0x08,0xF2,0xF0,0x86,0x64,0x1A,0xE5,0x35,0xC2,0x6A,0x07,0xE4, +0xA3,0x86,0x4F,0x29,0x7A,0x81,0xFE,0x28,0xE8,0x83,0x4A,0x95,0xB6,0x3C,0x85,0xC7, +0x30,0x29,0x10,0x1A,0xFD,0x3D,0xF2,0xFD,0xB2,0x36,0x3F,0xB2,0xA6,0x4D,0x7B,0xA9, +0xA2,0x9A,0x90,0x40,0x00,0x4D,0x8B,0x78,0x8D,0xC1,0x04,0x4A,0x95,0x24,0xA0,0x2D, +0xDD,0xED,0x58,0x95,0x4A,0xE4,0xB7,0xF7,0x79,0x41,0xC5,0x22,0xD1,0xA0,0x0C,0x04, +0xCA,0x0A,0x27,0x6A,0x6C,0xE4,0xD0,0x73,0x4F,0xCC,0xD5,0x72,0xCB,0x87,0x2B,0x15, +0xB3,0x2D,0x38,0x9E,0xB7,0x85,0x39,0x4E,0x6A,0x13,0x39,0x8C,0xB4,0xA2,0xCA,0x1A, +0x05,0xD3,0x88,0xB9,0x78,0xA3,0xEA,0x07,0xBA,0x47,0xAF,0x39,0x31,0xAC,0x13,0x5F, +0x2C,0x82,0xC1,0xFE,0x6C,0x3E,0x84,0x06,0x1A,0x9D,0x64,0x0D,0xD4,0x16,0xED,0xA8, +0x51,0x02,0x0C,0x5C,0xDE,0x08,0x49,0xC3,0x26,0xAA,0xAE,0x40,0x6A,0x4D,0x83,0xC2, +0x11,0x83,0x2B,0xF1,0xED,0x3A,0x2C,0xA7,0xF3,0x06,0xFF,0x4C,0xA6,0xF6,0xE8,0x88, +0x53,0xE8,0xD4,0xFE,0x09,0xF7,0x68,0x60,0x32,0xBC,0xD7,0x88,0xED,0x43,0x03,0xD1, +0x39,0x13,0xEF,0x04,0x5C,0xF2,0xBE,0x5F,0x08,0x05,0x6D,0xDF,0x99,0xD9,0x9F,0xDF, +0x0C,0xEF,0xDD,0x82,0x48,0x4E,0xBD,0x32,0xAE,0xB4,0x1B,0xC9,0x5A,0xEF,0x7A,0xBD, +0xB2,0xDF,0xEA,0x5D,0xC7,0x41,0x49,0xF5,0x9C,0xEC,0x0E,0x4D,0x9C,0xE9,0x05,0x9D, +0x89,0xB0,0x2E,0x00,0x96,0x07,0x5F,0xDD,0xB0,0xF0,0x4C,0x54,0x1E,0xB3,0x94,0xC1, +0xCE,0x0E,0x88,0xAA,0x84,0x79,0xE1,0xFF,0xD5,0x85,0xC5,0xB3,0x49,0xBC,0x31,0x0B, +0x21,0x93,0xD9,0x7E,0xDB,0x25,0x75,0x5C,0xDC,0x84,0xAA,0xCA,0xC7,0x99,0x09,0x66, +0x23,0xFF,0x70,0xC2,0x34,0xC7,0xB9,0xC0,0x6D,0x53,0x7D,0x2D,0xC8,0x0F,0x1F,0xEB, +0x21,0xD3,0x7E,0x7E,0xD3,0x43,0xEE,0xE6,0xA9,0x72,0xF8,0x02,0x4B,0xA0,0xD7,0xEC, +0x42,0xE6,0xB2,0xD2,0xB6,0x60,0x1D,0x14,0x20,0x99,0xCA,0x78,0xCE,0x42,0x2E,0xC0, +0xEB,0x2E,0x64,0xF8,0xA2,0x35,0x72,0x70,0x9B,0x62,0x17,0xBA,0xED,0x36,0x52,0x41, +0xF9,0xE5,0x3B,0x61,0x46,0x38,0x9C,0x4F,0x59,0xB4,0xDC,0x10,0x32,0x7C,0x0D,0x3A, +0xAD,0x0D,0xC2,0xE7,0xA7,0x1F,0x68,0x9C,0x0D,0xE3,0x62,0xF2,0x33,0x31,0xCF,0xCD, +0x6A,0x0C,0xCA,0xB3,0x55,0x1B,0x6F,0x75,0xE9,0x0A,0x69,0x68,0xAD,0xFA,0x19,0x00, +0x9F,0x8F,0x45,0xB6,0x88,0x55,0xE6,0x61,0x11,0x68,0xBA,0x5D,0xFE,0xFB,0xEC,0xF4, +0x72,0x83,0xDC,0xC6,0x96,0x65,0x12,0x20,0x31,0x78,0x61,0xD1,0xB3,0x54,0x58,0x62, +0x62,0x45,0x88,0x4F,0xBA,0x48,0x30,0x1C,0x91,0x4E,0xCB,0x16,0xA2,0xB7,0xB5,0x93, +0xBA,0x29,0x54,0xD4,0x5D,0x08,0xCB,0x31,0x8B,0xF0,0xCD,0xDC,0xF2,0xBE,0xAB,0x30, +0xBA,0x02,0x83,0x20,0xD8,0x88,0x55,0x4E,0x72,0xD4,0xCE,0xF4,0x12,0x47,0xE0,0x48, +0x7B,0x33,0xA7,0x5E,0x59,0x41,0x3C,0x72,0x71,0xBF,0x16,0xA1,0xE9,0x91,0x1C,0x2D, +0x6E,0x82,0x78,0x13,0xFB,0x06,0xCD,0x2C,0x4A,0xFF,0xC9,0xE7,0x4D,0x23,0x01,0x42, +0xD6,0x1A,0xB3,0xF1,0x5E,0x5B,0x90,0x6F,0x5C,0xCB,0xFC,0xDC,0x77,0x74,0x4E,0xBF, +0xC8,0xB4,0xEE,0xDE,0x39,0x8E,0x90,0x24,0x36,0x7D,0xB1,0xA0,0x04,0xC4,0xBF,0x2E, +0x13,0x7B,0xD7,0x61,0xE5,0x43,0xFE,0x4C,0xC5,0x2E,0xA5,0x96,0xFC,0xE8,0xEC,0x45, +0xD1,0x1A,0xBE,0x5F,0x7F,0xFE,0x69,0x17,0xE2,0xBB,0x4F,0x1A,0x43,0x47,0x10,0x33, +0x85,0xE4,0xAB,0x02,0xA4,0x6F,0x59,0x5C,0x01,0xC1,0xAC,0xE8,0x76,0x7E,0x8D,0x72, +0xE9,0xD1,0x34,0x90,0x4A,0x04,0xAC,0xDE,0xBC,0xD0,0x4B,0xF1,0x20,0x42,0xFC,0xB0, +0x1E,0xCC,0x2A,0xEB,0xB7,0xE0,0xF9,0x76,0x08,0x77,0x0D,0x60,0xD5,0x2F,0x50,0xD1, +0xE8,0x18,0x2D,0x6A,0xAE,0x4B,0x33,0x53,0x35,0x3B,0x8D,0x6F,0xEA,0xE4,0xD9,0xC8, +0x2E,0x3E,0x4D,0x0E,0x30,0xA7,0x87,0xB2,0x08,0xD6,0x63,0xCB,0x7B,0x7E,0x69,0x13, +0x22,0x7B,0x47,0x05,0x90,0x69,0xEC,0x07,0x6B,0x58,0x72,0xF5,0x09,0x49,0xFC,0x7B, +0x21,0xB1,0xB1,0xA2,0x2A,0xC5,0x23,0x92,0x6C,0x72,0x13,0xCE,0xEA,0xC8,0x6F,0x82, +0xE3,0xE7,0xB1,0xD1,0xF8,0x73,0x9F,0xA6,0x1D,0x9E,0xC0,0x50,0x60,0x04,0xAA,0x87, +0xC2,0x4E,0xAC,0xE1,0xD0,0x9C,0x63,0x22,0x8E,0x0A,0x76,0x1E,0xFE,0xAD,0x93,0xF8, +0x4C,0xF3,0xC2,0x51,0x1D,0xCF,0x76,0x7A,0xD2,0x7A,0xDA,0x71,0x51,0x3B,0x1E,0x84, +0x63,0x0F,0x97,0xA8,0xE0,0xE8,0xDF,0x2A,0x1A,0x22,0xF3,0xD9,0x50,0x1A,0x8B,0xB7, +0x5E,0x8E,0x9F,0xFA,0xEE,0x8C,0x02,0x36,0x6B,0x3E,0xF6,0x29,0x00,0xD6,0xA0,0x8A, +0x24,0xC9,0x96,0x64,0xD0,0x5A,0xD2,0x11,0x49,0x6E,0x40,0xAA,0x93,0x79,0xA3,0x19, +0xBC,0xE1,0xED,0xBF,0x10,0xA0,0xEA,0x70,0x2F,0x6C,0xF0,0xFB,0x64,0x01,0x46,0x94, +0xF0,0x09,0x94,0x7D,0x74,0xB8,0x76,0x49,0x4D,0x8C,0xF6,0x26,0x59,0xCA,0x14,0x65, +0x95,0x2A,0xEA,0x7F,0x0A,0x57,0x9B,0x47,0x84,0x53,0x14,0x39,0xE2,0xE3,0xEA,0x12, +0x5C,0x02,0xDA,0xEF,0xE8,0x3E,0x03,0x5E,0xED,0x4A,0x71,0x1D,0x51,0x93,0xCE,0x94, +0x85,0x0B,0x65,0x8E,0x9F,0x23,0xC1,0x4A,0x3B,0xEE,0x6E,0x1B,0x48,0x8E,0x1C,0xA8, +0xB2,0xF2,0x25,0xBF,0x8D,0x72,0x3D,0x83,0xDE,0x57,0xAC,0xE1,0x46,0x31,0xAF,0xC0, +0xF5,0xBB,0xE5,0x9F,0x50,0x2E,0x9B,0xF9,0x04,0x4D,0x32,0x60,0x38,0xCB,0x62,0xDA, +0xD7,0xBD,0x9A,0x66,0xA0,0xB0,0xDD,0x52,0x40,0x16,0xCE,0x28,0x8B,0x87,0x4B,0x66, +0x29,0x34,0xBA,0x98,0x6A,0x07,0xCB,0x20,0xBB,0x26,0xDF,0xD9,0xCA,0xF7,0x37,0xAF, +0x84,0x6E,0xA7,0xA5,0x7A,0x84,0x6F,0xA6,0xB8,0xA4,0x04,0x7C,0xFF,0xB1,0x12,0x1E, +0x8B,0x04,0x3F,0xAF,0x8B,0x4E,0x80,0x20,0x73,0x26,0x85,0xF1,0x00,0xB8,0x7D,0x3A, +0x3C,0x6F,0x2F,0x55,0x72,0x3D,0x83,0x07,0x38,0x1D,0x0D,0x41,0xE3,0x56,0xF2,0x3C, +0x9E,0x41,0x1D,0xA8,0x5A,0xD7,0xBD,0xAC,0x66,0x61,0x48,0x0C,0x7C,0xE7,0x09,0x22, +0x9A,0x30,0x96,0x85,0xE8,0x36,0x33,0x1E,0x08,0x27,0x05,0xB5,0x4A,0x02,0x53,0x7E, +0x63,0x86,0x1C,0x85,0x41,0x69,0x86,0x7B,0xC3,0xCA,0x8E,0x5A,0x55,0xEE,0xC6,0x10, +0xF4,0xBD,0xE2,0xBA,0x34,0xE7,0x4C,0x76,0x95,0x78,0x8B,0x97,0xA0,0xB7,0xFF,0x79, +0xB8,0x9A,0x1A,0x59,0x7B,0x42,0xAF,0x4D,0xA1,0xB6,0x7B,0x09,0x80,0x98,0xDC,0x02, +0x1F,0xE8,0x16,0x42,0x4E,0xDE,0x9E,0xC3,0xB3,0x77,0x93,0x9C,0xD4,0x23,0x58,0x9D, +0xAE,0xD2,0x77,0x63,0xFB,0x09,0xC8,0x7E,0xB1,0x88,0x17,0x14,0x02,0xF2,0xC6,0xD6, +0xF9,0xD9,0x1F,0x34,0xA7,0xE5,0xBE,0x4C,0x38,0x37,0x04,0x55,0xCE,0x6F,0x06,0xBA, +0xA7,0xB9,0x83,0x55,0xFF,0x0F,0xA4,0x73,0x91,0xD8,0xE7,0x8C,0x11,0x15,0x1B,0xFB, +0xC7,0xDB,0x90,0xAA,0x2B,0x63,0x92,0x41,0x28,0x53,0x30,0xDC,0x72,0x83,0xD6,0x5A, +0x00,0x66,0x5C,0x05,0x4C,0xEF,0xC7,0xB5,0x97,0x7D,0xFF,0x30,0x0F,0x65,0x5B,0xCF, +0xC7,0x94,0xE2,0xFF,0xC2,0x25,0xBB,0x34,0x26,0x0D,0xB8,0x45,0x8B,0x38,0x79,0x0E, +0x83,0x74,0x83,0x44,0xDC,0x4A,0xFF,0xE1,0xAD,0xC4,0xA9,0xCF,0x15,0xCA,0xD0,0x58, +0x57,0x6F,0x9D,0x11,0x0E,0xEE,0x7E,0xC6,0xCF,0x84,0xC1,0xE5,0x60,0x84,0x7E,0x36, +0xAE,0x3D,0x40,0xD1,0xAB,0xA3,0x5F,0xD2,0x95,0x32,0x6C,0xC1,0x2B,0x3B,0x0A,0xDF, +0xB4,0xFE,0x5A,0xA2,0x52,0x96,0x35,0x4E,0x7E,0xFA,0xD0,0x26,0x3D,0x28,0xF7,0x20, +0xE5,0xA2,0x15,0xB0,0x15,0xB3,0xC7,0x1C,0xB7,0xA8,0x00,0xBA,0xBF,0xEA,0x7C,0xAB, +0xB8,0xB4,0xE8,0xFC,0x27,0xAC,0x04,0x6C,0xD6,0x0A,0xCD,0x3B,0xA2,0xE4,0x17,0x68, +0xA5,0xD5,0x24,0x8C,0x5A,0x1A,0xCF,0xA0,0x9A,0x42,0x2C,0x56,0x67,0x89,0x1B,0x34, +0x8D,0xE9,0x15,0x20,0xAD,0x61,0x8E,0x89,0xA6,0x19,0x88,0x9F,0x0D,0xE0,0x5B,0xB1, +0xBD,0x4F,0xF8,0xC5,0x71,0xCD,0xB6,0xFB,0x8C,0x6A,0x07,0xE4,0xBE,0xE5,0xA2,0x08, +0x0E,0x75,0x4D,0xCE,0xBC,0xCC,0x88,0xD4,0x18,0x7D,0x47,0x32,0x7A,0x04,0x0D,0xF9, +0x33,0x39,0x6D,0xE4,0x41,0x1F,0x1D,0xEF,0x85,0x88,0xE9,0xF8,0x51,0x59,0x86,0x50, +0xC3,0x88,0x8C,0x6C,0x5D,0x05,0x21,0x9E,0x39,0x1A,0x57,0x19,0x29,0x6B,0x70,0xD4, +0xB8,0xEA,0xA9,0xA1,0x77,0xEF,0x74,0x71,0x02,0xBE,0xB1,0xB5,0x52,0x5F,0xF6,0x60, +0x28,0xDE,0x8B,0x22,0xF2,0xEE,0x77,0xBA,0x27,0xF5,0x9F,0x90,0x22,0xEC,0xD9,0xE9, +0x94,0x25,0x10,0xBB,0xEA,0xBC,0xDC,0xCF,0xFB,0x0B,0x59,0x6B,0x81,0xEC,0xC4,0x06, +0xA9,0x11,0x54,0xCF,0x22,0x66,0xC8,0x0D,0xF8,0x7F,0xB8,0xDD,0x81,0x3F,0x36,0xD6, +0x09,0x0C,0xCB,0xE5,0x51,0x3A,0xBB,0x73,0xDD,0x54,0xFC,0x14,0xDD,0x0A,0xC5,0xC7, +0x9B,0xDD,0x2C,0xC3,0x6F,0x9C,0xE8,0x64,0x61,0x47,0xA3,0xBF,0x2B,0xCC,0x30,0x39, +0xF5,0x0F,0x74,0xEA,0x88,0x35,0x7F,0x14,0xD9,0xC5,0xF2,0xBF,0x7E,0x35,0xBA,0xA7, +0xFA,0x74,0x08,0x1A,0xA1,0x44,0xA2,0xB5,0x75,0x8C,0xA4,0x60,0x77,0x2D,0xCC,0x51, +0x20,0xB0,0x21,0xBE,0x70,0xE6,0xE0,0x28,0x20,0xF0,0x9B,0xAE,0xAD,0xE1,0x18,0x96, +0xAB,0x9C,0x3E,0x77,0xB7,0xC6,0xBE,0x21,0x5C,0x55,0xBE,0xDD,0x33,0xB2,0x6B,0x35, +0x74,0xE3,0x8B,0xBC,0x83,0x2B,0x00,0xF2,0x95,0xA3,0xD6,0x14,0xED,0x01,0x59,0x50, +0xE9,0x8C,0x92,0x96,0xC4,0xDE,0x6F,0xEA,0xC4,0x07,0xB3,0x3D,0x33,0x44,0xD2,0x5C, +0x87,0xC7,0x4F,0x62,0x19,0x77,0x26,0x94,0xA8,0xA3,0x96,0x2F,0xD7,0xD4,0x60,0x1D, +0x60,0x30,0x7A,0x64,0x8F,0xED,0xD3,0xFF,0x3F,0x9C,0xDF,0x7E,0x9C,0xF5,0x9A,0xA7, +0x09,0x30,0x39,0x57,0x69,0x59,0x5C,0x74,0x7F,0x69,0x99,0xDE,0x12,0xE1,0xB8,0x6D, +0x13,0x37,0xCC,0x1F,0x12,0xF6,0xE4,0x7B,0xFF,0x1A,0x0E,0xC7,0x43,0x29,0x36,0x22, +0x04,0x45,0x0B,0x04,0x7D,0x6D,0xAC,0xA6,0x2D,0x38,0x1B,0x2C,0xDA,0x75,0x38,0xAF, +0x89,0x4D,0xEF,0x6B,0xC7,0xB4,0xD4,0xE9,0xE6,0x56,0xC9,0x9C,0x0F,0xE2,0xEC,0x32, +0x77,0xED,0x02,0x5F,0x5A,0xFB,0x01,0x41,0xA4,0x18,0xBF,0xBD,0x89,0x68,0x8B,0x47, +0x8E,0x3B,0xB9,0x85,0xE2,0x77,0xB8,0x6B,0xFA,0x2D,0x22,0x0D,0x18,0xCF,0x9C,0x34, +0x2D,0xE0,0x26,0xA9,0xA6,0xE0,0x36,0xBB,0xEE,0xBC,0x0C,0x10,0x37,0xBF,0x40,0xB4, +0x07,0x00,0x8F,0xE6,0x4E,0x74,0xD4,0x00,0x0A,0x2D,0xB1,0x39,0xFA,0x27,0x9F,0x6D, +0x25,0xAA,0x0B,0x1E,0x81,0x7C,0x0B,0x0C,0xDF,0xF0,0x6A,0xF6,0x7E,0x1A,0x23,0x39, +0x0B,0x10,0x3A,0xBB,0x28,0xD1,0x79,0xEB,0x47,0x9E,0x2A,0x4A,0x42,0x19,0x92,0x88, +0xB0,0xFC,0x00,0x22,0x78,0xB7,0x1C,0xAD,0x8F,0x51,0x0B,0x34,0x42,0xEF,0xAD,0x86, +0x4C,0x9A,0xFA,0x85,0x91,0xD3,0xB5,0xFF,0xB3,0xCC,0x0E,0x3B,0xAF,0x6A,0x7E,0x76, +0x76,0x72,0xB2,0xE9,0x4F,0x8E,0x5E,0x51,0x8E,0xD0,0x3F,0x6E,0x36,0xCE,0x9D,0xC0, +0xB8,0x0B,0x96,0xD5,0x33,0x3C,0x20,0xF2,0xA0,0xE1,0x16,0xB9,0xB0,0x78,0x41,0x41, +0xC0,0x6F,0x60,0x7E,0xDB,0xB2,0x89,0xAD,0x81,0xF3,0x61,0x05,0xD8,0x74,0xBE,0xA7, +0x88,0x5F,0x9A,0x6D,0x0C,0xCE,0xFB,0xEE,0x05,0x05,0xD9,0x45,0x6E,0x90,0x88,0x0D, +0x94,0x5D,0xE5,0x18,0x64,0x44,0xE7,0xAA,0xDA,0x31,0x55,0xDF,0x29,0xAA,0xEC,0x56, +0x3F,0x88,0xCD,0xAD,0xF7,0x7B,0x78,0x9B,0xD3,0x38,0xBC,0xE9,0x2F,0x80,0x92,0x23, +0x7F,0xC9,0x38,0x08,0x58,0x65,0x92,0xEB,0xA8,0x3B,0x0E,0x95,0x9D,0xEA,0xD0,0xBD, +0x9F,0xD4,0x30,0x28,0x3B,0xA1,0xEE,0x23,0xE3,0x15,0xFB,0xA3,0xD4,0x27,0x59,0x81, +0xAB,0x94,0x42,0x38,0xEA,0xE2,0x88,0xD9,0xF2,0x5A,0x6D,0x5A,0xB3,0xFD,0xF1,0x41, +0xAE,0x2C,0x80,0xB3,0xFF,0x9C,0xF5,0x70,0xA5,0xAA,0xE5,0xE5,0xAA,0x11,0x1E,0x86, +0x8A,0x28,0x97,0xDB,0x98,0xC5,0x01,0x89,0x78,0xE7,0x57,0xF9,0x1E,0x28,0x7F,0x5F, +0x98,0x8B,0xCA,0x38,0x1B,0xE7,0x57,0xA1,0x2B,0x28,0x56,0x0F,0xFE,0x5C,0xC2,0xD7, +0x9F,0x5D,0x27,0x44,0xD4,0x4A,0xBF,0x5F,0xC6,0xBE,0x66,0x58,0xF1,0xF1,0x20,0xD0, +0x25,0x21,0xDA,0xF3,0x62,0xD6,0x9B,0xB7,0xC8,0x81,0x23,0xE4,0x2A,0x40,0x31,0x50, +0x0B,0xDE,0xBF,0x1E,0x43,0x8E,0x05,0x8A,0xC4,0xA2,0x1B,0xE5,0x2A,0xC5,0x77,0xAE, +0x03,0xF3,0x9A,0x1F,0x68,0x68,0x83,0xB4,0x82,0x9F,0xB6,0xBE,0xAF,0x2F,0xF4,0x46, +0x63,0x9C,0x95,0xA6,0x1C,0x56,0x42,0xF6,0x28,0xF0,0xCD,0x7A,0x97,0xFF,0x96,0x08, +0xD7,0x00,0x0B,0xA4,0x8B,0xC0,0xE6,0x86,0x84,0x04,0x64,0x28,0xEC,0x5B,0xA1,0x15, +0x96,0xEB,0x23,0x4A,0x14,0x1B,0x06,0x3B,0x9E,0x8A,0x35,0xDE,0x79,0xA7,0x20,0x37, +0x34,0x5B,0xA5,0xDE,0x21,0xFC,0x58,0xBF,0x92,0x24,0x1B,0x54,0x2F,0xA5,0xD3,0x1A, +0x9D,0x4F,0xBC,0xA4,0xA5,0x56,0x97,0xFB,0x8B,0x49,0xBC,0x61,0x0A,0x6C,0xC3,0x85, +0x0C,0xCE,0x6C,0x37,0x0E,0x57,0xF4,0x96,0x87,0x21,0xDF,0xB3,0xA7,0xDD,0x8E,0x5E, +0x03,0x15,0x3C,0x46,0xE4,0xC6,0xBD,0x7F,0xBB,0xFB,0x12,0x1F,0x73,0xFC,0x6A,0xB7, +0x26,0xC1,0xF4,0x3E,0x7A,0xA4,0x9C,0x44,0x97,0xB3,0xF4,0x81,0x11,0x85,0xB3,0x56, +0x64,0x8E,0xAF,0xB9,0xAF,0x53,0x9E,0xC4,0xDB,0xB0,0x82,0x6E,0xBC,0x30,0x78,0x48, +0x3C,0x38,0xD5,0xA8,0x03,0x7E,0x28,0x0B,0xB5,0x99,0x26,0x79,0xD3,0x8E,0x65,0xA7, +0xF6,0xB8,0x4F,0xD9,0xBA,0xB4,0x01,0xF9,0x7E,0xF7,0x5A,0x1D,0x84,0xE4,0x14,0x6F, +0x56,0x02,0x25,0x73,0xB2,0x3E,0xC0,0x65,0x75,0xE3,0x12,0xCB,0x3B,0x85,0x0E,0x64, +0xB6,0x15,0x5F,0x17,0xAF,0x8E,0xEF,0xDB,0x74,0xF3,0xFA,0x75,0x64,0x03,0xFC,0x4E, +0xBC,0xB0,0xB3,0x01,0xCE,0x1E,0xB8,0x7B,0x91,0xC8,0x34,0xE9,0xE6,0x60,0x59,0x0C, +0xB6,0xE0,0xDF,0xFE,0xF2,0xC9,0x18,0x5E,0x10,0x80,0xEB,0x8A,0x10,0xCC,0xFA,0x8E, +0x37,0xF4,0x3D,0x38,0x1A,0xE6,0x85,0x05,0x8F,0x9E,0xF7,0x53,0x9C,0xC6,0x63,0x2E, +0xFA,0x74,0x2A,0x9A,0xA3,0xEA,0x86,0x94,0xDF,0xD3,0x8B,0x22,0x2E,0x79,0x9B,0xD0, +0x42,0xCC,0x9A,0x21,0xE6,0x1A,0x03,0xC3,0x65,0x83,0x93,0x5A,0xE1,0x85,0x01,0xBF, +0x56,0xE3,0xDF,0x77,0x17,0xB1,0x53,0xF5,0xB7,0xA9,0x4D,0xB2,0x38,0x7B,0x2C,0x3A, +0x9F,0xC2,0xEE,0x41,0xC6,0xC8,0x52,0x70,0xF9,0xB9,0xF6,0x33,0x49,0xF4,0x6B,0xBA, +0xEC,0xF5,0x6D,0x49,0xA5,0x0A,0xBB,0x86,0x80,0xAD,0x7B,0x39,0xB8,0xBC,0x0A,0x7F, +0xE4,0xFC,0xA9,0x5C,0xAE,0x41,0xA3,0x25,0x03,0x20,0xDC,0x4B,0xFC,0xAB,0x60,0x82, +0xAA,0x88,0xF3,0x22,0x85,0x58,0x15,0xA0,0x27,0x16,0x33,0x16,0x62,0x45,0xF1,0xA7, +0x77,0x4A,0x6C,0xAF,0xC3,0xAB,0xAA,0x1F,0x8E,0xF7,0xCA,0x82,0xC3,0x2A,0x38,0xF5, +0x18,0x45,0x0C,0x40,0xCA,0x29,0xDB,0x48,0x31,0x76,0xA1,0xFD,0x65,0x1B,0x56,0x81, +0x1E,0x85,0xDB,0x37,0x9A,0xD6,0x34,0x33,0x0C,0x4B,0x58,0xB2,0xCF,0x37,0x72,0xC0, +0xB5,0x21,0xBA,0x17,0x6B,0x67,0x13,0xB8,0x96,0x28,0x50,0xC0,0xB9,0x45,0x97,0x31, +0xC8,0x20,0x0E,0x06,0x4D,0x49,0x17,0x2F,0x4E,0xBD,0xF1,0x08,0x17,0x54,0x5B,0xBC, +0xFF,0x7E,0x42,0xB8,0xF0,0x96,0xE8,0x79,0xD5,0x89,0xE0,0xE7,0x5E,0x43,0x5D,0xFE, +0x76,0x7D,0xE5,0x3C,0xCC,0xB3,0x7E,0x49,0x4D,0x5B,0x39,0xD8,0x40,0xBA,0x45,0x27, +0x77,0x42,0x43,0xF6,0x51,0x93,0x79,0x65,0x35,0x16,0x40,0x08,0x55,0x96,0xE5,0x63, +0xE3,0xEC,0x08,0x65,0x96,0x6A,0x39,0x59,0x21,0x49,0x29,0xF4,0xF4,0xA3,0xDB,0xE8, +0xA6,0x07,0xC8,0x0E,0x2C,0x65,0xF8,0xEB,0x7A,0x41,0x24,0x9D,0xD4,0xE9,0x05,0x25, +0xB0,0x3A,0x41,0x23,0xF1,0xC9,0x8E,0xEA,0xC9,0x10,0x6C,0x50,0xD3,0x42,0x18,0xE7, +0xFD,0xB3,0x11,0xFC,0x08,0x99,0x6E,0x01,0x44,0x89,0xBD,0xDE,0xD8,0x93,0x66,0xD0, +0x46,0xA7,0xBD,0xDF,0x16,0x15,0x0E,0x36,0xA2,0x2F,0xDB,0x6E,0x1C,0x3F,0xC8,0x4B, +0x49,0x76,0x50,0x94,0x4A,0x71,0x98,0xCC,0xD4,0x7C,0xEC,0xB1,0x3B,0x55,0x24,0xBB, +0xF8,0xE8,0x04,0x04,0xEE,0x06,0x56,0xC5,0x9E,0x97,0x1F,0xD4,0x4A,0x43,0x31,0x45, +0x62,0x06,0x35,0xE1,0x3A,0x1F,0x0F,0x9F,0xC0,0xB7,0xDC,0x7D,0x99,0xA7,0x72,0x44, +0xB4,0x8D,0xC4,0x58,0x6F,0x54,0xEC,0x74,0x4D,0xF1,0x67,0xBB,0x8E,0x98,0xFC,0xFB, +0x77,0x72,0x0C,0xF5,0x18,0x30,0xDF,0x9D,0x71,0x31,0x6F,0xBF,0x50,0x35,0xD7,0xAA, +0x05,0x8B,0x37,0x5F,0x7F,0x72,0x06,0xF5,0x08,0x51,0x6C,0x38,0x7A,0xBB,0xF6,0x57, +0x82,0xF3,0x08,0x4E,0xF9,0xDF,0xC2,0x95,0x8E,0xCE,0xF4,0xCA,0x1B,0x62,0x89,0x2C, +0xB9,0x1E,0x28,0xA8,0xF3,0xEE,0xC5,0x2A,0xEC,0x6C,0x7D,0x3E,0x2C,0xC3,0x20,0x33, +0x1F,0xC0,0x18,0xC7,0x17,0xDE,0x91,0xDA,0xF7,0x5C,0xA9,0x6D,0xE2,0x78,0x31,0xF9, +0x8C,0xE3,0xA5,0xBE,0xE9,0xB5,0xA8,0x7C,0x54,0xFB,0x23,0xB4,0xEE,0x7C,0x9D,0x88, +0xCF,0x71,0x62,0x89,0xBA,0x2F,0x4D,0x0D,0x59,0x42,0xA3,0x53,0x5F,0x04,0x10,0xF0, +0x4A,0x2F,0x38,0xCC,0xEE,0x13,0x21,0xA5,0xB6,0xF6,0x48,0x98,0x13,0x1A,0x92,0x4E, +0x51,0x5E,0x7E,0x53,0x51,0x3D,0xA5,0x72,0x8E,0xAC,0x7D,0x64,0x8B,0xF3,0x10,0xAF, +0x83,0xD3,0xBF,0xCD,0x7E,0x0C,0x0B,0x85,0xD8,0x07,0xDE,0xF6,0x6C,0xE9,0x59,0xBC, +0xD8,0x39,0xB6,0x2B,0x6E,0xCD,0xC0,0x88,0x84,0x82,0xDD,0x97,0xC4,0x04,0xE6,0x9A, +0xB9,0x90,0x2F,0xD0,0xFD,0x21,0x64,0x03,0x29,0x72,0x21,0xDE,0xE0,0xE5,0x45,0x26, +0xDA,0xF2,0x80,0x50,0x7A,0xB1,0xD9,0x4D,0x63,0x6B,0x81,0x6D,0x03,0xAB,0xF5,0xB5, +0x69,0xFD,0x24,0x2A,0x07,0xF7,0x86,0x5E,0x35,0x46,0x09,0xB5,0x5C,0x36,0xB1,0x28, +0x81,0xDB,0x2C,0xDF,0xB0,0x7A,0xFA,0xC5,0xEB,0x8E,0x7A,0x40,0x59,0x42,0x62,0x8C, +0x2D,0x79,0x34,0x76,0x78,0xD3,0xD7,0x65,0x44,0x07,0xF9,0x02,0xC0,0x1D,0x49,0x62, +0x77,0x2B,0xC6,0xAC,0x17,0x7A,0x1E,0x27,0xF4,0xE8,0xC1,0xBB,0x69,0xA7,0x1D,0xCD, +0x4E,0x46,0x4E,0xA0,0xC0,0x1B,0x36,0x7B,0x53,0xE5,0x96,0xFC,0xDE,0x89,0xE3,0x38, +0x7E,0xAF,0xFA,0xFE,0x59,0xA9,0x7A,0x18,0x74,0xB1,0xEA,0xB2,0x93,0x82,0xE6,0x5F, +0xD5,0xEE,0xA4,0x6E,0x02,0x7F,0xAE,0xD1,0xF4,0xB0,0x12,0xC4,0x95,0x4E,0x09,0x8A, +0xBC,0x98,0xC4,0xC9,0x80,0xC0,0x7C,0x8F,0x99,0x97,0x52,0xF9,0xD1,0xD9,0xF9,0x1A, +0x37,0x04,0xB9,0xB6,0xE3,0x8D,0x9A,0x2F,0x82,0xAC,0xBB,0xDE,0x51,0xD6,0xB2,0xD2, +0x1E,0xA7,0x8A,0x0E,0xF0,0x05,0xB2,0xE4,0x5E,0x7A,0xF9,0xB9,0x1F,0xE4,0x5E,0x65, +0x7B,0xFF,0xBE,0xC3,0xAE,0xD7,0x2D,0x26,0x00,0xFB,0x54,0xE8,0xDD,0x75,0xD7,0x3A, +0x92,0x6A,0xE6,0x99,0x18,0xD0,0xC9,0x57,0x35,0x56,0x5B,0x17,0x61,0x6C,0x23,0x2F, +0x57,0x96,0x85,0x93,0x80,0xBA,0x40,0x4E,0xA3,0x75,0xBD,0x9A,0x65,0xDD,0x82,0xAD, +0xB1,0x91,0xB1,0x0F,0x8A,0x83,0x11,0xA0,0x1B,0xF0,0x5C,0x77,0x13,0x2E,0xAA,0xB2, +0x63,0x4F,0x23,0x5C,0x17,0x4B,0x4F,0x3E,0x68,0x05,0xBC,0xFD,0xFB,0x95,0xF8,0xBF, +0xCB,0x8F,0xE7,0x69,0x34,0x47,0xD9,0x2E,0x1F,0x4A,0xDE,0xA6,0x41,0xA4,0xE4,0x7C, +0xE6,0x8E,0x24,0x2D,0xCF,0xDD,0x81,0x1A,0x12,0xE1,0x61,0xE2,0x63,0xDA,0x5D,0xDC, +0xEF,0x49,0xE2,0x4D,0x9D,0x96,0x23,0x1E,0x5B,0x48,0x7A,0xA8,0xE5,0x04,0x36,0xE7, +0x79,0x7B,0x82,0x4A,0x36,0x8C,0xF1,0x69,0xB5,0x81,0x03,0x7E,0x88,0x88,0x81,0x94, +0xE8,0x39,0xDF,0xB4,0x76,0x4B,0x5C,0x8F,0xF1,0x31,0x0B,0xE1,0xB7,0x0E,0x5D,0x04, +0x09,0xB7,0x97,0xA1,0xB0,0x3D,0x3F,0xBD,0xAF,0x4B,0x13,0x7E,0x15,0x8A,0x52,0xFD, +0xEB,0xA0,0xD1,0xDA,0xD8,0x5D,0xC4,0x6E,0xF2,0xDE,0x8A,0x40,0xD2,0xC1,0xE7,0x0A, +0x97,0x88,0x5A,0x42,0x7A,0x0D,0x6B,0x17,0x43,0x2B,0x4F,0xA7,0x0A,0x1A,0xE9,0xBB, +0xDB,0xDD,0x8E,0xA3,0xD9,0x70,0x8F,0x76,0xD6,0x89,0xF6,0x9B,0x37,0xC0,0x36,0x7D, +0x1B,0xDA,0xE4,0xE2,0x24,0x89,0xBC,0x0E,0x86,0x1C,0xEA,0x1A,0x24,0x1F,0x1F,0xE4, +0x9C,0x81,0xD6,0xB3,0x73,0xC2,0x5C,0x68,0xE5,0xC0,0x9C,0xEB,0x81,0xCE,0x49,0xFA, +0x4F,0x7A,0xCE,0x0E,0x33,0x3B,0xC8,0xF0,0xBB,0x29,0xB7,0xFD,0x06,0x0C,0x4C,0xF0, +0x93,0xC5,0x92,0x4E,0x5E,0x34,0x7A,0x51,0x33,0x19,0x86,0x9A,0x41,0x1C,0xB4,0x22, +0xA8,0xA5,0x8C,0x79,0x5A,0xE2,0x73,0xD0,0x8D,0x04,0x33,0x30,0x23,0xE7,0x1F,0x2F, +0x65,0x4A,0xCF,0xEB,0xF5,0xD1,0x90,0x8C,0xAE,0x63,0x82,0x78,0xF4,0x47,0x3A,0x73, +0x8F,0x8A,0x1E,0x85,0xF0,0xA1,0xDD,0x1B,0x57,0x29,0xA3,0x32,0xA0,0x51,0x08,0x1B, +0xBE,0xE6,0x67,0x36,0x1F,0x45,0xA9,0xA6,0xFF,0xF6,0x92,0x30,0xA0,0x57,0xC8,0xE2, +0x34,0xC9,0xFC,0x5C,0x70,0xAD,0x60,0x23,0xE8,0x38,0x18,0x44,0x8E,0x87,0xAC,0x3F, +0x13,0x2A,0x6B,0xB5,0x1C,0x7C,0x3B,0x96,0x81,0x20,0x7A,0x80,0x30,0x16,0xE5,0x28, +0xF2,0x92,0xAE,0x4E,0x41,0xB5,0xE8,0xC1,0xB3,0x4F,0x19,0x03,0x4B,0xBB,0x70,0x4F, +0xD6,0x1B,0x88,0x99,0x90,0x37,0x12,0x3C,0x28,0x07,0x9F,0xE8,0x63,0xB2,0x6F,0x81, +0x13,0x8D,0xA4,0x7F,0x79,0x01,0xDA,0x08,0xED,0x44,0x4B,0xFC,0x03,0x72,0x0D,0xF7, +0xA3,0xF0,0x5A,0xC4,0x1A,0x80,0xCA,0x31,0x88,0xE1,0x74,0xB3,0xBD,0x91,0x50,0x20, +0x5F,0x42,0x90,0x3E,0x99,0xB6,0x60,0x51,0x03,0x66,0x9F,0x58,0x12,0x84,0xAF,0xA9, +0x40,0xEF,0xAC,0x7B,0x88,0x1B,0x43,0x1B,0xC5,0x50,0x0E,0x82,0x3D,0x81,0x41,0x10, +0x52,0xF3,0xB3,0x44,0xA4,0xF6,0x1B,0x0D,0x17,0xC6,0x25,0x4D,0x5A,0x8C,0x54,0xD3, +0x9C,0x64,0xF3,0x73,0x2F,0x11,0x19,0x0E,0x0C,0xFB,0x1E,0x5D,0x6A,0x92,0x38,0x84, +0xE6,0xFD,0x9F,0x43,0x73,0xBB,0x48,0x5A,0xF9,0x1B,0x95,0xFD,0x6C,0x18,0xA5,0xC3, +0xC2,0x20,0x73,0xEB,0x67,0x2E,0x68,0xEF,0x19,0x9C,0x9F,0x6F,0x74,0xCB,0xD3,0x13, +0x2B,0xE2,0x0B,0x88,0x60,0x85,0x14,0xC9,0x3B,0x04,0x70,0x7F,0x4D,0x39,0xB9,0xBB, +0x3F,0x7E,0xA3,0x69,0x98,0x72,0xC2,0x50,0xD7,0xC5,0xF2,0xB0,0xE5,0x12,0x00,0x50, +0xA2,0xEB,0x33,0xFB,0xA1,0xDF,0x64,0x4A,0x68,0x33,0x65,0x6C,0xDC,0xD9,0x08,0xB8, +0xF4,0xAA,0x18,0x00,0x4A,0x10,0xC0,0xE9,0x08,0x38,0x48,0x56,0x21,0x3F,0x3E,0x85, +0x21,0xC3,0xA5,0x62,0xC7,0xF0,0xD2,0x67,0xF6,0xCB,0x48,0xAD,0x20,0xAF,0xDD,0xC0, +0x78,0x07,0x55,0x74,0x46,0x87,0x3A,0x12,0x49,0x13,0x8A,0x38,0x73,0x39,0x56,0xA3, +0x96,0x5C,0x67,0x3A,0xE3,0x53,0x8E,0xB7,0x20,0xCE,0xE6,0x25,0x81,0xEE,0xE8,0x51, +0xC3,0xE0,0x5A,0x4F,0x90,0x3F,0xC7,0x99,0xAF,0x35,0xA8,0x8A,0xA6,0xD5,0x55,0xFF, +0x47,0x52,0xA2,0x57,0x1D,0x76,0x00,0xAA,0x88,0x94,0xE0,0xBE,0x54,0xA4,0x5A,0x76, +0x26,0x26,0x0D,0xD2,0x0B,0x92,0x62,0xED,0x68,0x5B,0xDC,0x9D,0x0A,0x8F,0x0C,0xA3, +0x37,0x21,0xEB,0x05,0x45,0x7C,0xF3,0x76,0xCF,0xD7,0xBD,0x37,0xBD,0x9D,0xDD,0x78, +0x8C,0xBC,0x0A,0x74,0x0B,0x01,0x4B,0x92,0x21,0xCD,0x08,0x17,0xC7,0x71,0xE8,0xC8, +0x3D,0xB4,0x69,0x69,0xCD,0x80,0xCA,0x4B,0xBB,0x44,0x15,0xB6,0x73,0xE7,0x12,0xAC, +0xE3,0x4D,0x39,0xDC,0xC6,0x90,0x16,0x6F,0xD7,0xDE,0xE9,0xD2,0x83,0x4B,0x63,0x71, +0x0D,0x49,0x8F,0x16,0x6E,0x32,0x53,0xFD,0x6C,0x49,0xA6,0x7D,0xA5,0x0D,0xA2,0x5B, +0x1A,0xCB,0x3A,0x7C,0x3F,0xB1,0x6A,0x8E,0x6C,0xAA,0x26,0x08,0x59,0xCE,0x15,0xDF, +0x45,0xC9,0x44,0xA0,0xAC,0x4C,0xE6,0xB7,0xFE,0x15,0x25,0x0F,0x2C,0xA8,0x7F,0x60, +0x50,0xBD,0xDC,0x57,0x29,0x53,0x78,0xB3,0xDA,0xDA,0x90,0xDC,0x69,0xB9,0x94,0x2C, +0xD3,0x82,0x63,0x98,0x44,0x9A,0x18,0x39,0x86,0x49,0x1B,0x48,0x84,0xAD,0xB1,0x5B, +0xE3,0x90,0x54,0xB7,0x86,0x80,0xC7,0x12,0x89,0x57,0x43,0x37,0x97,0x9D,0x23,0x20, +0x59,0x77,0x62,0x67,0x33,0xC6,0xAA,0xA5,0x97,0x3E,0x30,0xD3,0x7C,0x0B,0x2F,0x0B, +0x42,0xE5,0x05,0x33,0xF4,0xD2,0xD3,0x8E,0x5F,0xC8,0x7E,0x38,0xA5,0xBC,0xC2,0x3F, +0xA1,0xC8,0xD0,0x7F,0x71,0xD4,0x88,0xA4,0xCB,0x09,0xDB,0xA0,0xE7,0x07,0xA4,0x53, +0x62,0x43,0x66,0xE2,0x3D,0x2A,0x61,0x1F,0x0E,0x56,0x6D,0x9C,0x85,0x1E,0x75,0x2F, +0x88,0x81,0x07,0x92,0x92,0xA1,0x40,0xB7,0x63,0xB6,0x2D,0xF8,0x2C,0x37,0xCD,0x38, +0x01,0xF1,0xB9,0x50,0xF7,0x23,0x6C,0x30,0x1D,0x52,0xB9,0xCA,0x13,0x72,0xC0,0xFF, +0x7A,0x3F,0x16,0xC1,0xFC,0x8D,0x40,0xB4,0x3C,0x55,0x38,0xE1,0xBA,0x8F,0x51,0x59, +0x82,0x22,0x44,0x19,0x5E,0x9B,0xF1,0x8B,0x64,0x27,0x44,0x53,0xA2,0x09,0x30,0x8E, +0x46,0x36,0x6F,0xEC,0xB1,0x49,0x03,0xDA,0x3D,0xC2,0x0C,0x6C,0xC0,0xCA,0x7C,0x7F, +0xFF,0x13,0x2D,0x1D,0xDB,0x4E,0xC0,0x22,0x6D,0x7A,0x67,0x46,0xAE,0x73,0x5E,0x52, +0x9B,0x39,0x48,0x73,0xC7,0xCA,0x4E,0xA5,0x5C,0x91,0xE6,0x0E,0x1B,0x47,0x3B,0x3D, +0xFE,0x06,0x88,0xE1,0x67,0xC6,0xD1,0x16,0x79,0x7C,0x79,0x45,0xD1,0xD8,0x59,0x64, +0x43,0x7D,0x54,0x38,0x58,0x79,0x81,0x6F,0x70,0x85,0x69,0x2F,0x63,0x83,0x8E,0x21, +0x6D,0xE0,0x3A,0xF2,0x01,0x07,0x8C,0xE0,0x00,0x2B,0x12,0xDB,0x2A,0xFF,0x8C,0xE7, +0xB7,0x1A,0xCF,0x21,0xF1,0x64,0x27,0x84,0x88,0x25,0xD6,0xF5,0x0B,0xDB,0xA0,0xF5, +0xE6,0x9A,0xF9,0x91,0x7B,0x9C,0x32,0xFE,0x94,0xBF,0xF2,0xF5,0xF5,0xD9,0x86,0xB3, +0x08,0xD1,0x0B,0x25,0xEA,0x08,0xE1,0x19,0xA1,0x63,0x94,0x82,0x74,0x0E,0x6B,0x1D, +0xC4,0x6A,0x46,0x06,0x73,0x84,0xED,0xAE,0xA0,0x25,0xC7,0x01,0xEA,0xDA,0xCA,0x2A, +0xF1,0xE1,0xE5,0x51,0xB4,0x04,0xA6,0x87,0x65,0x51,0x8C,0xEE,0xA5,0xB4,0x8B,0xCD, +0x82,0xFC,0x28,0x3F,0x84,0x2E,0x8A,0x49,0x45,0x36,0xB6,0x94,0xDD,0xB8,0xCC,0x61, +0xEF,0x95,0xEA,0x35,0xFB,0xD1,0x67,0xAC,0xB2,0x95,0x27,0x73,0x4C,0x32,0xF5,0xCD, +0x08,0x15,0x34,0x58,0x24,0x0C,0x24,0x4A,0xDF,0xBA,0x89,0x1B,0x0E,0xCC,0x73,0x53, +0x2A,0x4B,0xA0,0x86,0x9A,0xF3,0xED,0xF4,0xDE,0xE2,0xD2,0x1E,0x7D,0x8B,0xEF,0x12, +0xCA,0xE5,0x9D,0xE0,0x40,0x46,0xDB,0x92,0x75,0xFE,0x84,0xA0,0x21,0xE4,0xF2,0x48, +0xEB,0xB9,0x52,0xE8,0x13,0x8F,0x57,0x8E,0x80,0xFE,0xE2,0x0A,0xD4,0x3F,0xD1,0x5C, +0x95,0xDE,0x30,0x26,0xD7,0xD9,0x09,0x1D,0x97,0x05,0x9A,0xE2,0x79,0x8F,0x2D,0x34, +0xAE,0xE7,0x52,0xFC,0x52,0xA6,0x17,0xA5,0xA5,0xD5,0x85,0x89,0xFC,0x2D,0xEC,0xC5, +0x68,0xF2,0x6A,0xCD,0x85,0x95,0x1C,0xB3,0xAF,0xBF,0xB8,0xA2,0x1E,0x93,0x91,0x00, +0xC8,0xAF,0xDD,0x8B,0xB0,0xE2,0xF6,0xBD,0x0B,0xE8,0x14,0xC9,0xD7,0xC2,0x85,0x05, +0xA6,0x63,0xBA,0x92,0x91,0x2D,0xE3,0x13,0xEA,0x35,0x1C,0xD6,0xB3,0x5E,0xAC,0x25, +0xCF,0x69,0xF2,0x36,0x43,0xC2,0xE8,0x2B,0x4F,0x84,0xA5,0xB5,0x3C,0x65,0x8F,0xDD, +0xA7,0x6D,0xA2,0x1B,0xA5,0xCA,0x50,0x65,0x6A,0xF1,0x28,0x22,0x86,0xAB,0x6F,0x65, +0x52,0xFD,0x14,0x0D,0xEB,0x40,0x72,0xE5,0xE3,0xEF,0x1E,0xA8,0x08,0xCB,0xDF,0x9F, +0x0D,0x7D,0xD2,0xD1,0x8F,0x63,0x2B,0x7D,0x73,0x96,0x72,0xFE,0x79,0xE1,0x2A,0xE1, +0xF0,0xE9,0x93,0x63,0x98,0x5A,0x6B,0x51,0xCB,0xD7,0xE5,0x57,0x5C,0x3B,0x27,0xFF, +0x5B,0xC4,0xB0,0x8D,0x84,0x25,0x23,0x0E,0x24,0xEE,0x0F,0x30,0x4D,0x99,0x72,0x78, +0x98,0x05,0x7E,0x89,0x22,0x60,0xD4,0xDD,0x89,0xBB,0xD7,0x32,0x69,0x7F,0xA2,0x46, +0xCA,0x4E,0x8A,0x99,0xA6,0x28,0xE3,0xEE,0x5B,0x13,0x51,0x1C,0xE5,0x81,0x81,0x3A, +0xEF,0x3F,0xE0,0xE8,0x03,0xB3,0x5A,0x81,0x96,0x0B,0x11,0x64,0x70,0xA0,0x4F,0xE7, +0x30,0xDD,0xAE,0xF0,0x54,0x13,0xC3,0x67,0xF0,0x37,0x81,0xFA,0xCC,0x6B,0xB1,0x29, +0xC4,0x4E,0x1D,0x4D,0x9B,0xE3,0x75,0x7B,0xB9,0x91,0x82,0x66,0x42,0x01,0x0F,0x39, +0xC1,0x2B,0xDC,0x92,0xCD,0x1E,0x98,0x15,0x7E,0x26,0x32,0xF1,0x79,0xED,0xB8,0xA5, +0x07,0x5F,0xA8,0xF4,0x1D,0x59,0xBF,0x1E,0x50,0x4C,0xDA,0xB7,0xA7,0x60,0x8F,0xAB, +0x74,0x13,0xA8,0xEC,0xDA,0x49,0x77,0xE5,0x3C,0x31,0x6E,0x00,0x5E,0xD6,0x22,0x66, +0x1D,0x7A,0x7C,0x7E,0xD7,0x5E,0x23,0x9A,0x44,0xA9,0x80,0x46,0x5A,0x49,0x1F,0xDB, +0xCB,0x66,0xE5,0xC6,0x15,0x53,0xE3,0x71,0x92,0x06,0x2A,0x9B,0x96,0xEF,0xAD,0x42, +0xF1,0xCC,0xDF,0x1C,0xE4,0x7D,0x77,0xC0,0x00,0xAB,0x2F,0x22,0xAD,0x4B,0xBF,0xBD, +0x7E,0x0E,0xF2,0x11,0xFD,0xE6,0xBB,0x03,0x02,0x2C,0xDC,0x34,0x57,0x77,0xCF,0x56, +0x9C,0xBD,0x78,0x6A,0x26,0x6B,0xDA,0xCC,0x61,0xD9,0x29,0x33,0x06,0xD7,0xC0,0x6F, +0x4C,0xF2,0xC7,0x8D,0xDA,0x8D,0x66,0x31,0xDC,0x9C,0xEF,0x4A,0x32,0xFC,0xBD,0xE0, +0x30,0xDE,0xA9,0x34,0xD5,0x14,0x44,0xCC,0x89,0x9A,0x2B,0x8C,0xDB,0x4B,0xC3,0x17, +0xE2,0xB7,0x7B,0x98,0x71,0x2D,0x76,0xB7,0xF8,0x27,0x75,0xB0,0x65,0xAA,0xB1,0xA2, +0x27,0x57,0xE7,0xD7,0x43,0xE2,0xA7,0x79,0xEC,0x93,0x52,0x3E,0xE4,0x89,0xA4,0x97, +0x36,0xB9,0x11,0x7D,0xE2,0xCF,0xC3,0x7A,0x2B,0x2C,0x64,0x26,0xCF,0xFB,0x05,0x20, +0xAC,0x98,0x60,0x77,0xDA,0x31,0xCD,0x07,0xC3,0xD6,0x75,0x79,0x0F,0xFC,0xB5,0x90, +0x3B,0x7B,0x1B,0x0C,0x32,0x8D,0x1A,0x2E,0x3D,0x94,0xE3,0xB5,0x18,0xAA,0x6A,0x7C, +0xD9,0x7F,0x62,0x59,0x20,0x35,0xB6,0x29,0xC7,0xCD,0xAE,0x8E,0x8E,0x60,0xCF,0xB0, +0x00,0xC9,0x13,0xBF,0x8D,0xD2,0x25,0xD7,0x68,0xD0,0x99,0xCD,0x0D,0x30,0xFA,0x23, +0x86,0x2C,0x1A,0xC1,0x7D,0xA1,0xD7,0x12,0xE7,0x47,0xFA,0xBB,0x2F,0x24,0x6F,0x45, +0x0D,0x2C,0x45,0x09,0x1B,0xE9,0x15,0x06,0x03,0xAA,0x38,0xC4,0xFA,0x97,0xF2,0xB5, +0x43,0x4E,0x3D,0x49,0xE6,0x1D,0xE7,0x50,0x7E,0x4C,0xFA,0x06,0x03,0x90,0x99,0xB1, +0x57,0xFB,0x14,0xE8,0x5B,0x58,0xB1,0x65,0x27,0xE9,0x1F,0x0F,0x1B,0xAF,0xBB,0x24, +0x33,0xD1,0x91,0x61,0x60,0xAB,0x21,0xAA,0xE2,0xD4,0x49,0xE4,0x79,0xFC,0x5F,0x80, +0x9C,0x3D,0xE9,0x98,0x88,0x83,0x42,0x23,0xA2,0xF0,0xC5,0xA7,0x95,0x90,0xFB,0x77, +0x3E,0x46,0xD4,0xEF,0x3E,0xD0,0xBF,0x99,0x66,0xDF,0x1B,0x97,0x3F,0x19,0x70,0xBA, +0x58,0x99,0xAD,0xD5,0xB0,0x58,0x77,0x5B,0xE3,0xC0,0x99,0x0D,0x02,0xDE,0xAE,0x35, +0xF8,0x98,0xC7,0xC8,0x22,0x70,0x3D,0x45,0xD7,0xF9,0xCB,0x9E,0x7A,0x83,0x2E,0x01, +0xB4,0x25,0xB7,0x49,0x49,0x13,0x88,0x1D,0x0F,0x2E,0xE7,0x23,0x81,0x21,0x40,0x4D, +0x7A,0x9C,0xC7,0x5B,0x66,0x96,0xE5,0xF9,0x6D,0x51,0xB8,0x04,0x16,0x88,0x53,0x2B, +0xAD,0x72,0x06,0x31,0xE7,0xB3,0x9A,0x5F,0xF5,0x83,0x64,0x63,0x53,0xD5,0xD9,0xD5, +0x9C,0xE3,0x90,0x7C,0x1F,0x73,0x2E,0x97,0x6B,0x28,0xDF,0x1D,0xB9,0xE0,0x15,0x79, +0x95,0x55,0xBC,0x7C,0xEE,0xA0,0x50,0x9F,0x7C,0x84,0xD6,0x38,0x2D,0x56,0xDE,0xCD, +0x95,0x44,0x3F,0xF5,0xD7,0x82,0xEF,0x0D,0xC5,0x16,0x11,0x4E,0xF7,0xE4,0x2E,0x22, +0xC9,0xA3,0x94,0x75,0x2C,0xCD,0x2C,0xAD,0xF7,0xCF,0x3E,0x04,0x4E,0xDF,0xD0,0xB9, +0x03,0x13,0xE5,0x55,0xC9,0x1F,0xD0,0x95,0x1C,0x04,0x1E,0x0E,0x66,0x8A,0x08,0x46, +0xDE,0x13,0x9C,0x15,0x98,0xFD,0x69,0x00,0x32,0xC8,0xCE,0x8E,0x65,0x89,0x0D,0x3D, +0xB1,0x31,0x77,0x4D,0x60,0x22,0xF2,0x60,0xC6,0xE6,0x50,0x2C,0x05,0xF8,0xCF,0x7F, +0x9E,0x37,0x0F,0xCE,0x90,0x87,0x7F,0xE1,0xB8,0x74,0x85,0x2C,0x45,0x8C,0x63,0x20, +0x81,0x15,0x08,0x39,0xA3,0xC3,0xE9,0x87,0x91,0xFB,0xB7,0x4A,0x15,0x41,0x3E,0x88, +0x06,0x46,0xF4,0xA7,0x2C,0xB2,0xE4,0x8E,0x77,0x2E,0xF7,0x89,0xF1,0x4C,0x75,0x75, +0x58,0x18,0xA8,0x3A,0xD6,0x8C,0xD0,0x81,0x7B,0x79,0x9B,0x80,0xB4,0xFA,0x4B,0xB6, +0x2A,0xB2,0x6D,0x53,0x67,0x5C,0x73,0x97,0xD0,0xD2,0x5A,0xF5,0x18,0x51,0x44,0x9E, +0xA5,0xE0,0xEC,0xDB,0x8C,0x43,0x83,0x67,0xAF,0x86,0xAA,0x75,0x77,0xC0,0xD2,0x51, +0x1B,0x9A,0x12,0xA6,0xED,0x75,0x22,0x36,0x63,0x03,0x1D,0xFB,0xA6,0xE8,0x38,0x94, +0xFA,0xF1,0x47,0xEE,0x71,0x98,0x77,0x6E,0xAE,0xF0,0x38,0x61,0x02,0x5F,0x11,0x46, +0xD6,0xC2,0x0C,0x01,0x77,0x8B,0x48,0x3E,0x19,0xA0,0x20,0x39,0xCA,0x38,0x30,0x56, +0xE5,0xD7,0xE1,0x1F,0x07,0x64,0x74,0x7A,0xF9,0xA8,0x20,0x76,0x05,0xFA,0x86,0xB1, +0xD1,0x1F,0xD7,0x7A,0xA4,0x29,0xD1,0x59,0x3C,0x3F,0x02,0x3F,0x05,0xEE,0xCD,0x67, +0xC0,0x9D,0x2E,0x00,0xAA,0xBC,0x9A,0x2E,0x30,0xC7,0xCA,0x0C,0xC0,0x67,0x84,0xBB, +0xFB,0xAA,0xB0,0x05,0xD2,0x51,0xD3,0xB2,0x00,0x5B,0x09,0xD4,0xB1,0xB6,0xA4,0xFB, +0x71,0x80,0x41,0x87,0xDE,0x1E,0xDD,0xA0,0x27,0x4A,0xBD,0x8D,0x90,0x92,0x4A,0xC8, +0x05,0x42,0x07,0x47,0x11,0x60,0xA5,0xB2,0x5F,0x71,0x42,0x84,0xE8,0x00,0x15,0xA5, +0x3C,0x85,0x0B,0x8D,0x5B,0xCB,0x49,0x31,0x21,0x0A,0xAD,0x18,0x96,0x83,0xEB,0x0B, +0x8D,0xB6,0x87,0x75,0xB7,0xB2,0xCF,0xA6,0x68,0x81,0x18,0x5B,0x8C,0x51,0xE3,0xE4, +0xCC,0x57,0xD8,0x4E,0x37,0xE4,0xF6,0x18,0x8E,0xE9,0xA0,0x03,0xD1,0xA7,0x7B,0x99, +0xA6,0x87,0x3E,0xDE,0x0A,0xAE,0xF2,0x6E,0x8A,0x3A,0x24,0x94,0x44,0xD0,0xB9,0x75, +0x97,0xD4,0x23,0x12,0x8A,0xE7,0x24,0x78,0x96,0xAB,0x7F,0x63,0xA7,0xDD,0xEF,0xD8, +0xE5,0xCC,0x42,0xED,0xE0,0x09,0xD4,0x55,0xD4,0xF3,0x5E,0x49,0x86,0xC7,0xA2,0x8D, +0x35,0x1B,0xDE,0x04,0xEA,0xBC,0x21,0xF3,0x52,0x38,0xFC,0x00,0x38,0x26,0x71,0x94, +0x14,0x7C,0x6F,0x44,0x2F,0x6B,0xC1,0x1F,0x9B,0xA0,0xC8,0x55,0x10,0x3D,0x37,0xD4, +0x44,0xAE,0xB0,0x96,0xF6,0x22,0x8E,0x8D,0x5E,0x1D,0x60,0x1E,0x39,0x72,0x34,0x13, +0x40,0x74,0x5C,0x4C,0xED,0xEA,0xF4,0xFC,0x92,0x80,0x9C,0x4C,0xBB,0x6E,0xB2,0xB7, +0xF3,0x50,0x4E,0x82,0x79,0x24,0xE5,0x8D,0x16,0x18,0x20,0xD1,0xCE,0x81,0x72,0xB2, +0x5D,0xF8,0x5D,0x44,0xCD,0x83,0x77,0xF9,0xA2,0x05,0x39,0xA0,0xCF,0xEB,0x47,0x6A, +0x7F,0xC6,0xF6,0x9A,0x16,0x01,0xA0,0x7B,0xCF,0xE5,0xE9,0xDF,0xEA,0x9E,0x79,0x67, +0xBC,0x49,0x2B,0x0F,0xE9,0x2D,0x72,0xD0,0xD5,0x1B,0xD7,0x29,0x2A,0x30,0x96,0xC6, +0x43,0xD9,0x3D,0xC2,0xDE,0x2E,0xA2,0xB0,0x13,0x84,0xCD,0x78,0xC1,0xB6,0xAC,0x79, +0x47,0x14,0x1C,0x1E,0xC5,0x46,0x62,0xD9,0x83,0xC1,0xD4,0xC3,0xC6,0xCE,0x2E,0x21, +0x99,0x18,0x76,0x0B,0xA8,0x3C,0x6E,0x76,0x6C,0x94,0x27,0x0A,0x7D,0x93,0x88,0x7B, +0x16,0x1F,0xFC,0x6F,0x82,0xA0,0xEC,0x87,0x7F,0x32,0x41,0x62,0x8F,0x02,0x6C,0xBF, +0x99,0xE9,0x15,0x79,0x2A,0x8A,0xEC,0x1D,0xCE,0xDE,0x76,0x7A,0xA7,0x14,0x84,0x6E, +0xBA,0x98,0xBC,0x6A,0x82,0x58,0x7E,0xB8,0x4B,0x99,0x66,0x7F,0x8B,0xEB,0x4E,0x58, +0xCC,0x83,0x85,0x75,0x3C,0x81,0x20,0x3C,0x86,0x82,0x36,0xBB,0x73,0xC1,0x23,0xBD, +0x33,0xA6,0xEB,0x20,0x7D,0x33,0xB3,0x83,0x8E,0x55,0xA9,0x8A,0xF1,0x8E,0x85,0x0C, +0x2E,0x6C,0xB3,0x6F,0x24,0xEB,0x1A,0xE9,0x6B,0xBA,0xA5,0x29,0xAB,0xF0,0x9A,0xCD, +0xC2,0xF1,0xFD,0x6D,0x9E,0x1C,0x47,0xA3,0xAC,0x92,0xBE,0x3F,0x8D,0xF9,0x82,0x40, +0x60,0xF1,0x81,0x85,0xE3,0x28,0x5D,0xB3,0xF6,0x62,0x8E,0x77,0x10,0xB6,0xB1,0x38, +0x3C,0xEC,0xAA,0xF9,0x91,0x28,0x43,0xE7,0xFF,0x89,0xDB,0x80,0xA7,0x41,0x46,0x6C, +0x3C,0xF8,0xC3,0x00,0x24,0xAB,0x81,0xBC,0x64,0x4E,0x34,0x3F,0xA1,0x03,0x7D,0x12, +0x10,0x13,0x1B,0xA9,0xE8,0x92,0x1C,0xAF,0xB2,0x6A,0x49,0x01,0xEF,0xA6,0x78,0x9B, +0x18,0xBE,0x8A,0xEF,0x96,0xB5,0x9C,0x3C,0xC6,0x7E,0xA2,0x70,0x3B,0xFE,0x25,0xEC, +0x47,0x46,0xE6,0xD4,0x52,0xA1,0x0B,0x5B,0xBA,0x80,0x47,0xFE,0x50,0x70,0x2C,0x89, +0x40,0x3C,0x43,0x17,0x8B,0x5E,0xF2,0xB1,0x23,0x6C,0x63,0x35,0x0E,0xC5,0x84,0x9C, +0x9E,0x12,0x56,0xB0,0x8F,0x23,0x01,0x55,0x1B,0x22,0x6E,0x90,0x7D,0xC8,0x8F,0x0A, +0xF7,0x35,0x85,0x24,0x42,0xD7,0xD2,0x09,0x09,0x3D,0x7D,0x48,0x44,0x38,0xFE,0x29, +0x44,0x5E,0x5C,0x72,0x8F,0x74,0x5C,0xFB,0x16,0xF3,0x62,0xB3,0xBF,0x64,0x3F,0x71, +0xE1,0xFF,0x0D,0x13,0x62,0xF4,0xE4,0xD9,0xDE,0x7E,0x37,0xC6,0xF7,0x19,0x8E,0xDE, +0x1E,0xE5,0x63,0x59,0x6E,0x44,0xD0,0xC2,0x12,0x6B,0x19,0x38,0x61,0x92,0xB0,0x42, +0x33,0x5A,0x18,0xCA,0x6A,0xB0,0xEC,0x5C,0xB2,0x4D,0x64,0xEF,0x23,0x1C,0x3A,0x86, +0x7E,0xE4,0x69,0x7D,0x72,0x71,0x24,0x58,0xA9,0x4A,0xCF,0x8A,0xEB,0x55,0x04,0x01, +0x23,0x75,0x96,0xF5,0xCE,0x19,0xF8,0x15,0x91,0x2A,0xBB,0xC0,0x77,0x87,0x79,0xEF, +0x02,0x2B,0x70,0xF2,0x98,0x26,0xB0,0x59,0x9C,0xDA,0xED,0x55,0x27,0x57,0xD3,0xE2, +0x12,0x70,0xF4,0x14,0xFD,0x29,0xDC,0xC2,0x09,0xC9,0x89,0xCA,0x8E,0xB9,0x3C,0xEB, +0x02,0xAF,0xD6,0x52,0x9C,0x9E,0x95,0xC3,0xD4,0x6A,0x34,0xCC,0xC6,0x0C,0x33,0xE0, +0x4B,0x72,0x5F,0x58,0x8F,0x06,0x6D,0xD3,0x94,0x2E,0xE9,0xC1,0x18,0xC1,0x79,0x5B, +0xAB,0xB1,0x78,0xD7,0x54,0xB0,0x71,0x97,0x13,0xBE,0xD9,0x2C,0x71,0x68,0xE4,0x37, +0x2E,0x76,0x20,0x0D,0x3B,0xF6,0xBC,0x8C,0x70,0xAD,0x52,0x8C,0x7A,0x07,0x02,0xB5, +0x4D,0x30,0xCE,0xCF,0xCC,0x4C,0x71,0xC4,0x43,0x77,0x45,0x61,0x7C,0xF3,0xF3,0x66, +0x51,0x6E,0xE9,0x57,0xA2,0x4C,0xB0,0x5C,0x1F,0xFD,0x5F,0x18,0x23,0x25,0x8F,0xDA, +0xCC,0x5C,0xFE,0x95,0xE6,0xEA,0xB3,0xE6,0xE1,0xF3,0x56,0x94,0xF1,0xDD,0x79,0x17, +0x68,0x7B,0x34,0x17,0xBD,0xCB,0x29,0x62,0x06,0xB7,0x38,0xDD,0x1F,0xC3,0x3C,0xA6, +0x25,0x8A,0x79,0xF1,0x28,0x99,0xED,0x7F,0x2B,0x79,0x28,0x1B,0x54,0xB7,0xCE,0xF1, +0x69,0xB0,0xC8,0xB7,0x7E,0x81,0x05,0x55,0x82,0xB8,0x1C,0xE9,0x84,0x91,0x9C,0x86, +0xDA,0x36,0x3E,0x48,0x30,0xFA,0xA8,0x84,0x66,0xEB,0xB2,0x41,0xE7,0xC6,0x8D,0x27, +0x86,0x26,0x17,0x3A,0x4D,0xBA,0xD8,0x83,0x94,0x67,0x50,0xCD,0x63,0x40,0xD0,0x3A, +0xF3,0xF7,0x5A,0x9B,0x96,0x7B,0xEE,0x52,0x6F,0x2A,0xD3,0x3D,0x55,0x32,0x15,0xCD, +0x56,0x56,0xF4,0x2E,0xC4,0x72,0x6E,0x9D,0xEB,0x55,0x93,0x34,0xAF,0xFE,0xE8,0xFF, +0xE0,0x38,0x15,0x07,0xBD,0x1B,0xAD,0x01,0x12,0x8A,0x0E,0xBE,0x9C,0xBC,0x7B,0x2E, +0x38,0xB3,0x64,0xA1,0xA7,0xBD,0x34,0xF3,0x6B,0xE2,0x41,0x14,0x36,0x48,0x50,0x71, +0x4B,0xA7,0x44,0xCC,0xF2,0x08,0x2E,0xF1,0xEF,0x05,0x25,0xD2,0xE9,0x85,0x82,0xBD, +0x5F,0xCE,0xD1,0xA5,0x02,0x08,0xAB,0x9E,0xF0,0xC9,0x75,0x5C,0x45,0x34,0xA1,0x84, +0x12,0x8E,0x9A,0xC8,0x38,0xE0,0x36,0xA3,0x3F,0x37,0x18,0xE6,0xB2,0x4C,0xAA,0xE1, +0xD5,0x18,0x7E,0x51,0xC1,0xFF,0x2E,0xBB,0x75,0x6B,0xA0,0xC5,0x85,0x8D,0xAA,0x52, +0x87,0x99,0x83,0xC1,0x08,0x3E,0xFE,0xCF,0xC8,0x26,0xD8,0xE4,0x6D,0x33,0x9E,0x88, +0x20,0xC2,0xE5,0x62,0x70,0xD7,0x76,0x0E,0x7B,0x4D,0x0E,0x19,0x1F,0xF6,0x7E,0x11, +0xF7,0x71,0xFD,0x8F,0x77,0xD8,0xE6,0xD2,0x28,0xAF,0x42,0x38,0x99,0x4E,0x9C,0xD7, +0x94,0x63,0x18,0x9F,0xC3,0x57,0x4F,0x5C,0xAA,0x32,0xB8,0x51,0xB0,0xA1,0x5F,0xF6, +0x08,0xA9,0xAE,0xA1,0xED,0xCE,0x02,0x6B,0x45,0xA7,0x63,0x97,0x66,0xE4,0x3D,0x96, +0xDE,0x77,0xCA,0xB6,0x8B,0x9B,0x5E,0x5A,0xF0,0x50,0x23,0xBC,0x01,0xDC,0xCB,0x24, +0x8E,0xF8,0xC4,0xF5,0x7D,0xE8,0x16,0x33,0xEB,0x37,0x01,0x81,0x1D,0xFB,0x4C,0xB8, +0xD5,0x41,0x5A,0x07,0xE8,0x8D,0xD8,0xB6,0x99,0x54,0x7A,0x35,0xCC,0x74,0x8F,0x3A, +0x49,0xF4,0x5F,0xA3,0x43,0x37,0x7E,0xFB,0xCB,0x90,0x5B,0x18,0xAC,0xB3,0xCB,0xDD, +0xB0,0xD3,0x57,0xF8,0xD5,0x8D,0x7C,0xB4,0x9D,0x6F,0x1E,0xA6,0x41,0xCC,0x6F,0x79, +0xA9,0x5A,0x4E,0x8B,0xA6,0x4A,0x14,0xDE,0x5A,0x8D,0x90,0x9D,0x78,0x69,0xAD,0xE8, +0x85,0x70,0x0D,0xED,0xF3,0xCB,0x6F,0x4F,0xE1,0xAB,0x30,0x09,0xD5,0x2D,0x20,0xBD, +0x60,0x3B,0x57,0x67,0xAD,0xF1,0x45,0x11,0xED,0xAB,0x80,0x1A,0x19,0x63,0x93,0xDF, +0x06,0x8D,0xB1,0xB9,0xDD,0x47,0x2E,0xE3,0x20,0x02,0x37,0x4D,0xBC,0xAE,0x87,0x46, +0x8A,0x08,0x0F,0xA1,0x8A,0x05,0xC2,0x0D,0x19,0xB4,0x15,0x6F,0x40,0xFE,0x7C,0x5D, +0x00,0xD7,0x1A,0xB1,0x6F,0xB9,0xF3,0xA4,0x89,0x76,0x55,0xC5,0x46,0x1B,0x5E,0xA3, +0xA3,0xF8,0x30,0x22,0x19,0xE2,0x6F,0x92,0x21,0x63,0xE2,0xA8,0x0C,0x6D,0x1B,0x21, +0x2B,0x87,0x67,0x3E,0x42,0xA2,0xDF,0x9A,0x1B,0x4F,0x48,0x87,0x0C,0xBF,0xC7,0x2B, +0x2C,0xF7,0x01,0xA6,0x64,0x0D,0xE8,0xB4,0x86,0x2F,0xE4,0xEC,0x6B,0x5C,0xB4,0xAD, +0x34,0x4C,0x22,0xE3,0x9C,0x9F,0x33,0xD3,0x1A,0xAA,0x46,0x37,0xDB,0x44,0xF1,0xF1, +0x7B,0x9D,0x77,0x99,0x3F,0xBB,0xC9,0x3B,0x2C,0x27,0x56,0xED,0x0F,0x88,0x51,0xC0, +0xA2,0x8D,0xD6,0x81,0x99,0x18,0xA2,0x43,0x0E,0xBD,0x5E,0xC5,0x96,0x07,0x42,0x56, +0xDB,0x54,0xE5,0x81,0x33,0xDE,0xCC,0x9A,0x4F,0x77,0x93,0x37,0xE8,0x29,0x28,0x26, +0x2B,0x09,0xCC,0xA7,0x01,0xE3,0x4A,0x04,0xDC,0x33,0xB8,0xF0,0xA3,0x50,0xC3,0x8B, +0x17,0x4D,0x4D,0xEC,0x2E,0x0E,0x8A,0x4C,0xBD,0x10,0x37,0x6B,0xAA,0xE5,0x33,0x19, +0xF1,0xE6,0xAF,0x07,0x17,0x01,0x4C,0xDD,0xDD,0xE8,0xE2,0xE5,0xAF,0x78,0xC5,0xA1, +0x89,0x43,0x46,0xA7,0x1F,0xBE,0xEC,0xFD,0x0A,0x4F,0x60,0xB0,0x2B,0xE2,0xA3,0x03, +0xD3,0x5A,0x47,0x10,0x05,0x7E,0x7B,0x59,0x42,0x64,0x0A,0x68,0xA3,0x50,0x9A,0xB0, +0xE8,0xC7,0xB7,0x14,0xD6,0x31,0xA2,0xEA,0x5C,0x40,0x5E,0x8D,0xD3,0x44,0x87,0x01, +0xFF,0x30,0x59,0x25,0x40,0x80,0x1E,0x35,0xEC,0x21,0xFC,0x15,0x3E,0x85,0xB1,0x2C, +0xBF,0x8F,0x80,0x2B,0x45,0x1C,0xB0,0x02,0x9B,0x4E,0x99,0xF2,0xB1,0x04,0xC9,0x1F, +0xCF,0xFF,0x63,0x4F,0x96,0x6A,0x66,0xB5,0x0E,0x4B,0x9B,0x74,0x94,0xF5,0xDC,0xCF, +0x50,0xC1,0x64,0x08,0x89,0x28,0x31,0x81,0x47,0xD7,0x17,0x65,0x36,0x21,0x0A,0x47, +0xE7,0xAC,0x3F,0x9B,0xC8,0x91,0x39,0xF6,0x63,0x1E,0x15,0xA4,0xAD,0x10,0x70,0xE5, +0xA8,0x81,0xFD,0xFA,0xEF,0x1A,0xE4,0x08,0xFD,0x63,0x29,0x11,0xA7,0x02,0xFE,0x0E, +0x9E,0x4A,0x3E,0x79,0x35,0x67,0xF3,0xD7,0x68,0xA2,0xEE,0x8F,0xF5,0xC8,0x26,0x5A, +0x52,0x3A,0x48,0x0C,0xA4,0xE5,0x97,0x6B,0x7A,0xF5,0x64,0xEF,0xED,0x66,0x31,0xB3, +0xDC,0x66,0x0E,0x14,0x36,0x14,0xF1,0x47,0xC2,0xCC,0xFE,0xD7,0x97,0x4B,0x0E,0xB8, +0x6A,0x99,0xE4,0xFA,0x2A,0x82,0x97,0xE0,0xCA,0xDD,0x37,0xAE,0x6F,0x91,0x86,0x19, +0xB4,0x69,0xDB,0x1B,0x18,0xAC,0x35,0xA4,0xD3,0x00,0x5E,0x93,0x15,0xC9,0x27,0xF7, +0x66,0x66,0xA9,0xF9,0x3F,0x6F,0x67,0xDD,0xAC,0xEF,0x62,0xFE,0xCA,0x18,0x58,0xC7, +0xF9,0xB9,0x31,0x4C,0xB1,0xA5,0xFB,0xEE,0x27,0x1A,0x7D,0x8F,0xF0,0x1D,0x94,0xB1, +0x25,0x3C,0xAF,0x17,0x86,0x88,0x82,0xB8,0x51,0xCA,0xE5,0x4E,0x55,0x98,0xBE,0xB8, +0x58,0xDE,0x7B,0xC2,0xC0,0xD5,0x24,0xC9,0x3F,0x86,0x1D,0x35,0x54,0x62,0xFD,0x3C, +0x63,0x25,0xF1,0xE8,0x3F,0x07,0xD5,0x9A,0x9E,0xD7,0x94,0xC3,0xED,0x28,0xAB,0x43, +0x99,0x41,0xE5,0x0A,0x32,0xF4,0x09,0xD5,0x10,0x85,0xD3,0x88,0xB6,0x82,0x8F,0x0E, +0x2C,0x38,0x74,0x78,0x31,0x50,0x2A,0x2F,0xB4,0x92,0xE9,0xCF,0xC5,0xBA,0xAE,0x60, +0x4E,0xA9,0xEC,0x01,0xD8,0xC3,0x68,0xAA,0xF7,0xA6,0x98,0x20,0xAA,0x3C,0x56,0xB8, +0xA9,0x7E,0x51,0xAC,0x9B,0x07,0xD9,0xDE,0xA3,0xE6,0x2B,0x57,0x54,0x61,0x46,0xE9, +0xCE,0xDB,0x00,0xA7,0x73,0x3E,0xF2,0x03,0x29,0xAD,0xF9,0x0A,0x7C,0x70,0xE0,0xB8, +0x27,0x78,0x89,0x64,0x4C,0xA4,0x55,0x66,0x63,0xA6,0x8E,0xAD,0x33,0x62,0x7B,0x16, +0x1F,0xF9,0x5A,0xF9,0xEB,0xFB,0x8B,0x28,0x99,0x4E,0xCF,0x3D,0xBD,0x31,0xC0,0x62, +0x1F,0xA2,0x20,0x04,0x64,0xBA,0xE3,0xD5,0xD1,0x75,0x35,0xB8,0x2D,0x1F,0x3A,0xCD, +0xD3,0xCD,0x85,0x1F,0x05,0x07,0xF1,0xE0,0xD1,0x4E,0x92,0x23,0x62,0x97,0x1C,0x89, +0x29,0x5D,0x16,0x04,0x93,0xF6,0xB2,0x10,0x09,0xCA,0x0A,0xDA,0x08,0xB3,0xAA,0x2E, +0x2C,0xAA,0xD8,0x3C,0xDA,0xA3,0x7B,0xCE,0xE7,0x9E,0x40,0x5B,0x59,0x0F,0x91,0x46, +0xFC,0x37,0x1C,0x8E,0x09,0x7F,0x01,0x5C,0x32,0x8E,0xC4,0xF2,0x20,0x5E,0xDB,0x1B, +0x5E,0x8D,0x8E,0xBD,0xC2,0xDE,0x91,0x02,0xC6,0x02,0xFD,0xA4,0xCF,0xE6,0xCB,0xC7, +0x44,0x0F,0x0A,0x0A,0xDC,0xBD,0xD0,0x9D,0x54,0x80,0xA0,0x37,0x09,0xAD,0xFE,0xB4, +0x51,0x60,0xB9,0xB2,0xA3,0x00,0x8F,0x6A,0x0D,0x0A,0xD3,0x6B,0x6D,0xAB,0x47,0x05, +0xA2,0x15,0xDF,0x48,0xF0,0x40,0xCE,0xAD,0xC1,0xE5,0xC0,0xDD,0x55,0xA2,0x82,0x9F, +0x9B,0x0A,0x29,0xFB,0x49,0x2F,0x04,0x5F,0x2C,0x50,0x83,0x32,0x70,0xAA,0x75,0xDB, +0x50,0xCC,0xFC,0x2E,0x1B,0x14,0x36,0xD8,0xA6,0x2F,0x1C,0xA2,0x66,0xC8,0xCC,0x67, +0x05,0x8B,0xAD,0x7C,0x53,0x1E,0x88,0x75,0x2A,0x42,0x00,0x7F,0x61,0x02,0x83,0x70, +0x43,0xAE,0xDE,0xCD,0x8D,0x7F,0x3D,0xD0,0x21,0x09,0x98,0x36,0xD9,0x1E,0xBF,0x5A, +0x23,0xCC,0x2E,0x26,0x2C,0xF5,0x5D,0x1D,0xB9,0x1A,0x55,0x47,0x01,0x2C,0x8B,0x41, +0x85,0xAD,0x24,0x2F,0xC6,0x7E,0x51,0x9D,0xB8,0x22,0xC7,0x6D,0x34,0xBF,0x70,0x18, +0xBC,0xFD,0x31,0xD3,0xB6,0x63,0x1D,0x03,0x02,0x3C,0x10,0x29,0x74,0xA0,0xEF,0x8B, +0x43,0xE6,0xC9,0x43,0x18,0xF4,0xD7,0x36,0xE0,0xFA,0x51,0x03,0x13,0x4F,0x72,0x85, +0x4D,0xAE,0x30,0xF2,0x7F,0x22,0x40,0x25,0x4A,0x28,0xE3,0xD0,0xDB,0xEC,0x8E,0xD1, +0x80,0x2E,0x93,0x92,0x19,0xA6,0x84,0x5C,0x8A,0x6E,0x7F,0xB7,0x50,0x53,0xA3,0x12, +0x3B,0x4E,0x3F,0x1A,0x68,0xC4,0x08,0xC4,0x1A,0x03,0xE1,0x5D,0xFF,0xA0,0x21,0x61, +0x19,0x46,0x24,0x3D,0x34,0x38,0x11,0xD6,0x09,0x2B,0xB5,0x95,0x65,0xC9,0xC9,0xF0, +0x1E,0x51,0xE1,0x9D,0xEA,0x8E,0x1E,0xC6,0xED,0x55,0xDE,0xA7,0x26,0xA3,0xFB,0xED, +0x88,0xA4,0xFF,0x6B,0x44,0xBA,0xA4,0xF7,0x59,0x21,0x49,0x11,0xD5,0x1D,0x0B,0x32, +0x58,0xD7,0x73,0xB2,0xF9,0xEC,0xF4,0x29,0x2A,0x62,0x81,0x89,0x30,0xFD,0x86,0xA2, +0xA7,0xA3,0x9C,0x1A,0x8E,0xD8,0xE4,0xAE,0x71,0xCC,0xB9,0x6C,0xD4,0x2C,0x44,0xE0, +0x3F,0xF0,0x12,0xA7,0x12,0xB7,0x22,0x8B,0x9D,0x36,0x78,0x3C,0xFE,0x75,0x99,0xB7, +0x0C,0x74,0x72,0xDF,0x26,0xA5,0xCB,0x79,0xD8,0x7E,0x4B,0x02,0xBA,0x36,0x44,0x80, +0xF3,0x41,0x91,0x16,0x72,0x11,0xDE,0xE7,0x19,0x83,0xE2,0x64,0x60,0x96,0x1D,0xF3, +0x43,0xAE,0x96,0xAF,0x25,0x29,0x5A,0xE9,0x42,0xC8,0x1E,0x90,0x8C,0x20,0x11,0xB5, +0x72,0xAF,0x25,0x3B,0x13,0xAE,0x17,0xD8,0x80,0x4D,0xC0,0xF0,0x9D,0x38,0xF8,0x52, +0x67,0xC6,0x2E,0x66,0xDC,0x42,0x89,0xBC,0xFC,0xB8,0x8D,0x06,0x94,0x8D,0x1C,0x5E, +0x87,0x63,0x0C,0xF3,0xBF,0x38,0x49,0x21,0x97,0x3F,0x9D,0xAF,0xF6,0x1C,0x5E,0x09, +0x60,0x2B,0xA3,0x6F,0x68,0x27,0x4A,0x3E,0x7B,0xFD,0xCB,0xA2,0x6B,0x2B,0xA7,0x33, +0x8F,0xB4,0xA5,0xDE,0xDB,0x5D,0xFB,0x50,0xC5,0x63,0x91,0x9E,0x7B,0xD4,0xEB,0xB0, +0x0A,0x37,0x06,0x2C,0xA6,0x28,0xA6,0xAA,0x6C,0xF1,0x37,0x6B,0xE8,0xFD,0x42,0x84, +0xDC,0x80,0x28,0xA5,0xFF,0xDC,0x4B,0x54,0xD1,0x2D,0x72,0x2C,0xF0,0xAC,0x71,0x6F, +0x07,0x78,0x12,0x3E,0x7D,0xFC,0x2D,0xBF,0x5E,0xE5,0xBF,0x8A,0xE8,0x56,0xAC,0xA4, +0xD9,0xB1,0x74,0x68,0xC2,0xBE,0x1B,0x84,0x98,0x8D,0x1F,0x19,0xAE,0xE8,0xA2,0x11, +0x6D,0x8C,0xD5,0x15,0x90,0x9B,0x5E,0x01,0x1F,0x25,0x3F,0x1D,0x68,0x38,0x8F,0x2A, +0x99,0x2A,0xB9,0x0B,0x20,0xB7,0x33,0x67,0xFC,0x23,0xE4,0xFD,0x78,0x02,0x38,0x13, +0x14,0x3F,0x86,0x68,0xEF,0xCE,0xA3,0xAD,0x69,0x8C,0x5F,0x95,0x0E,0x03,0x40,0xA7, +0x1E,0x97,0x61,0x2B,0x8F,0x29,0x5F,0x81,0x05,0x15,0xE9,0xCF,0xB3,0x2A,0xEE,0x01, +0xD6,0x60,0x8D,0x2E,0x52,0x73,0x46,0x06,0xEB,0x9B,0xD3,0x5A,0x82,0x0A,0x48,0x54, +0x1D,0x99,0xB0,0x84,0xEC,0x90,0x81,0xA6,0x35,0x61,0xAD,0xF5,0x7C,0x94,0xA2,0x85, +0xF6,0x0D,0x5B,0x72,0x64,0x9B,0xDB,0xE2,0x63,0xB1,0xDE,0x2A,0x76,0x1B,0x26,0x3C, +0x47,0xBA,0x29,0xEF,0x2F,0xDC,0x40,0x88,0x15,0x20,0xCE,0x6B,0x5C,0xA2,0x0E,0x96, +0x92,0x10,0xFA,0x90,0x00,0xFA,0x08,0x6B,0x98,0x9B,0x11,0x4D,0x15,0x4A,0x8E,0x76, +0xB2,0xF3,0x00,0x27,0x6B,0x66,0xF6,0x43,0xA5,0x34,0x62,0x92,0xA4,0x96,0x7D,0xF6, +0x28,0x10,0x3B,0x39,0x33,0x76,0x5D,0x3B,0x08,0x76,0xC5,0x8E,0xFE,0xB6,0x56,0x3A, +0x74,0xA4,0x44,0x7F,0xEB,0x8C,0x04,0x1D,0xFE,0xC5,0xE8,0x3F,0x58,0x5D,0x7F,0x58, +0x70,0xFD,0xE3,0x53,0x06,0x87,0xC3,0x2C,0x19,0x43,0x40,0x1C,0x9D,0x16,0x21,0xDC, +0x23,0x6D,0xE9,0x76,0x4F,0xE7,0x06,0x4C,0x63,0x7F,0x3A,0x11,0x6C,0xAE,0x33,0xFF, +0x00,0x9E,0xD3,0x1A,0x4A,0x7C,0xF4,0xD9,0xC6,0xB8,0x87,0x64,0x42,0xE4,0xB4,0xBF, +0x78,0x40,0xDB,0xA8,0x75,0x10,0x03,0xFA,0xD8,0xAA,0x29,0x6F,0x0F,0x80,0x88,0x8F, +0x8A,0xB4,0xB5,0xA7,0xEA,0xF4,0x92,0xC5,0x14,0xDA,0xE5,0xBD,0x0B,0x4B,0x37,0x63, +0x64,0xFC,0xC9,0xAF,0x96,0x05,0xCF,0xD4,0xE7,0xED,0xB5,0xCB,0x68,0xFE,0x0B,0x33, +0x12,0xA3,0x67,0x04,0xAE,0x05,0x0A,0xAA,0x7E,0xCF,0xAA,0x48,0xE0,0x97,0x6E,0xBE, +0x1F,0x66,0xA7,0xB5,0xA2,0x39,0xA0,0x57,0x8E,0xF3,0x2F,0xA7,0xA5,0xEC,0x67,0xFD, +0xF6,0xDA,0xE4,0x0A,0xCA,0x63,0x3E,0xAA,0x8E,0x7E,0xF1,0x5F,0x90,0x67,0xCD,0x45, +0x2E,0x91,0xCB,0x01,0xB4,0xB2,0x6C,0x7D,0x44,0x7B,0x8A,0x46,0xF4,0xD6,0x07,0x69, +0x05,0x0D,0xAB,0x0F,0x94,0x6E,0x03,0x2E,0xE0,0xCD,0xF3,0x44,0x46,0xF8,0x99,0x3F, +0xC1,0x76,0xD7,0xD0,0x4E,0xEE,0xB9,0xAD,0x7F,0x1A,0xD2,0x57,0xBE,0x21,0xF8,0xD0, +0x07,0x85,0x79,0x7E,0x04,0x14,0x0F,0xBE,0xF2,0x05,0x73,0x28,0x98,0xE6,0xD3,0x05, +0x07,0x8E,0x11,0x70,0xC8,0x30,0x66,0x32,0xEE,0xCF,0x92,0x38,0xFA,0x70,0x10,0x93, +0x28,0x12,0x5D,0x5E,0xD6,0x10,0x63,0x22,0x46,0x5F,0x4B,0x69,0x84,0x74,0x86,0x52, +0x4D,0x18,0xCC,0x14,0x99,0x53,0x55,0xCD,0x99,0x6B,0xEA,0xBD,0x1F,0x55,0x18,0x24, +0x2F,0xBC,0x85,0xC0,0xE5,0x80,0x50,0x3D,0x26,0x0D,0xE8,0xF9,0xA6,0x5C,0x42,0x95, +0xC8,0x41,0xE4,0xB4,0xE8,0x3B,0xFA,0x37,0x8D,0x12,0xB8,0x5B,0xC1,0x1C,0xE9,0x41, +0xFA,0x1A,0x3D,0xB8,0xA7,0x82,0x29,0x22,0x47,0xD8,0xC7,0xDA,0x44,0x7A,0x52,0xDA, +0x29,0xB5,0xAB,0x62,0xC6,0xEA,0x06,0xAE,0xC1,0x62,0x36,0x15,0x73,0x88,0xEF,0x40, +0x45,0x95,0xFC,0xBC,0xCD,0x9D,0xFE,0xC1,0x9C,0x33,0x72,0xCF,0x6C,0x2F,0x52,0xCE, +0x5C,0xF6,0x36,0x86,0x5C,0xCA,0xCB,0x57,0xEB,0xA4,0x96,0x88,0xFE,0x51,0x39,0x72, +0x03,0xEB,0xB3,0x44,0x71,0xC0,0x68,0x6E,0x52,0x60,0x47,0x41,0xE6,0xE5,0x39,0xAA, +0xF4,0xA3,0x69,0x87,0xFD,0x29,0xD2,0xAC,0x01,0x00,0xE3,0x48,0x1D,0x17,0x1A,0xFD, +0x56,0xC3,0xB9,0x2F,0x01,0xE1,0xFF,0x2F,0x23,0x35,0x3D,0x0E,0x63,0x5B,0x16,0x39, +0x73,0xE3,0xBC,0x87,0x89,0x53,0xFE,0x25,0xEC,0xBD,0xC1,0x0F,0xCD,0x37,0xAA,0xE3, +0xDB,0x3A,0x24,0x16,0x6F,0xE7,0x85,0x40,0x3A,0x43,0x73,0x49,0xA9,0x3B,0xC5,0xF1, +0xEF,0xF0,0x4B,0xD6,0xB2,0x84,0xC6,0x93,0xAE,0x0E,0x78,0x1D,0xFE,0xA0,0x86,0xE1, +0xA6,0x77,0x3A,0x31,0xFA,0x63,0x71,0x64,0xC4,0x1E,0x14,0xF4,0x5B,0xC1,0x94,0xBC, +0xD1,0x57,0xCA,0xBD,0x88,0xF3,0xE9,0xF4,0x85,0xCA,0x60,0xE1,0x29,0xB7,0xC6,0xDC, +0x2B,0x49,0xAB,0xBA,0x71,0x4B,0xF9,0xD7,0xF6,0x42,0x18,0x63,0x26,0xF1,0x2E,0x52, +0x9B,0xB5,0xFC,0xF4,0x49,0x36,0xD7,0xA4,0x5E,0xFF,0x04,0xE2,0x80,0x40,0x9E,0x96, +0x97,0x77,0x8F,0x9C,0xCB,0x84,0x7B,0xC4,0x1F,0x8F,0xBE,0xBC,0xF3,0x04,0xBF,0x34, +0x73,0x88,0xA7,0xDD,0x5A,0x6A,0x97,0x1B,0xCB,0x7E,0x7E,0xCE,0x9C,0x31,0xB7,0x6C, +0x25,0xB0,0xC0,0xCA,0x0A,0xB3,0xA1,0x32,0xD1,0xD1,0x66,0xBF,0xD0,0x6C,0xF4,0x22, +0x27,0x64,0x8D,0xCC,0x31,0xDE,0x24,0xFC,0xE2,0x2E,0x67,0x01,0x9A,0xF7,0xDF,0xD6, +0x24,0x7F,0x0F,0x61,0x66,0x08,0xB4,0x56,0x4A,0x48,0x5F,0xE8,0xBC,0x90,0x33,0x03, +0x64,0x0C,0x7B,0xB8,0xA6,0x4D,0x7A,0x17,0x54,0x3E,0x4F,0xAF,0x29,0x08,0x07,0x52, +0x81,0x7F,0xDD,0x3A,0x79,0x2C,0x6D,0xB3,0x2E,0xF1,0xBC,0xFC,0x3D,0x49,0x4D,0xC1, +0xE4,0x03,0x22,0x97,0xE2,0x20,0xFC,0x0C,0xC4,0x68,0x0D,0x14,0x29,0x97,0x0E,0xB6, +0x4D,0xBE,0x88,0x75,0x4B,0xB4,0xCA,0xA3,0x61,0x23,0x9F,0x68,0x35,0x9F,0x19,0xA3, +0xDE,0x0F,0x15,0x58,0x30,0x37,0x17,0x9A,0xE1,0xD9,0x49,0xDD,0x4F,0xBD,0x00,0xC0, +0x7B,0x9E,0x97,0x4A,0x11,0xCC,0xC4,0xA8,0x68,0x6C,0x38,0x83,0x0C,0x7D,0x4B,0xD6, +0x32,0xCD,0x1B,0xB4,0xAA,0x9F,0xB6,0x8D,0x2E,0x1B,0x35,0xA7,0xEE,0x0A,0xA3,0x13, +0x71,0xE4,0xD5,0xE6,0xEF,0xB9,0x3C,0x4A,0x39,0xA8,0x88,0xF5,0x8C,0xB4,0xF1,0x60, +0xE4,0x3C,0x1E,0xEB,0x68,0xA5,0xF0,0x4F,0xD2,0xE0,0xFF,0xA3,0x29,0x8D,0xF7,0x02, +0x51,0xB9,0xB6,0x71,0x72,0x14,0xFF,0x36,0xD0,0xC2,0x59,0x83,0xA1,0x8E,0xF0,0x77, +0xB0,0x96,0x85,0x8B,0x19,0xD6,0xF5,0xE9,0x05,0x8A,0x6E,0xCA,0x85,0x6B,0x1E,0x60, +0xE3,0x9F,0x42,0xBC,0xDD,0x18,0x81,0x79,0x11,0x9E,0x67,0xBD,0xF4,0x92,0x94,0x1E, +0x14,0x28,0x61,0xAD,0x29,0x21,0x8F,0xAE,0xB6,0x08,0x92,0x20,0x28,0x6D,0x70,0x5C, +0xD4,0x3A,0x46,0x33,0x29,0x9C,0xF7,0xA3,0x7B,0x65,0xA9,0x87,0xB7,0x19,0x21,0xB9, +0x11,0x1D,0x4E,0x1A,0x8F,0x00,0x8B,0x80,0xCB,0x4B,0x8E,0x65,0xA0,0xE3,0x08,0x15, +0xF0,0xC8,0xF0,0xF6,0x42,0x18,0x75,0x10,0xB5,0x26,0x2B,0x67,0xCF,0xCC,0x85,0x5C, +0x8B,0xB2,0x0F,0x23,0xF7,0xBC,0x06,0x7E,0x4E,0x22,0xB5,0x81,0xF7,0xD5,0x82,0x19, +0x65,0x82,0xA2,0xEA,0x48,0xA8,0x84,0xE3,0x36,0x05,0xC4,0xD5,0x39,0xD6,0x0D,0x54, +0xE9,0x98,0x25,0x64,0xCF,0x7E,0xF7,0x6E,0x5A,0x7D,0xD1,0xD1,0x43,0x07,0x55,0xC3, +0xEB,0x4B,0x66,0x93,0xD3,0x86,0x88,0x6B,0x64,0x6B,0x88,0x33,0x54,0x4C,0xFB,0x83, +0x89,0x63,0xB5,0x43,0xAE,0xEB,0xF5,0x48,0xF2,0xD1,0x12,0x92,0x0E,0x30,0xE7,0xF8, +0x60,0x2D,0x84,0x61,0x4C,0x72,0x55,0xDF,0xC9,0x88,0x6B,0xBE,0xCC,0xDD,0xFB,0xB1, +0x1C,0x1C,0xD7,0xC5,0x45,0x4E,0xD8,0x01,0x7A,0x8A,0x53,0x1F,0xC3,0x3D,0xBB,0xA1, +0x0F,0xE0,0x5F,0x0F,0x8A,0xBA,0x98,0x65,0xB8,0x20,0xDA,0xF0,0x10,0x7B,0x21,0x70, +0x91,0x0A,0x7C,0xA8,0x88,0x5B,0x80,0x48,0xCA,0xBC,0x3A,0x62,0x02,0x21,0x78,0xBA, +0xCD,0xFC,0x17,0x4B,0x7C,0xCC,0x66,0x95,0x76,0xD8,0x36,0x31,0x97,0xDA,0x38,0xBE, +0xF0,0x3B,0xED,0xAF,0xDF,0xE7,0xD3,0x08,0x0B,0xC0,0x2D,0xFA,0x86,0xED,0xB1,0x2F, +0xF6,0x06,0xED,0x1D,0xE6,0xEA,0x28,0x42,0x62,0xA6,0x5B,0xF0,0x7F,0x89,0xB4,0x37, +0xC5,0xC5,0x99,0x12,0x82,0x31,0x98,0x63,0xDA,0x6A,0xD6,0xC9,0x64,0x21,0x61,0xFF, +0xAE,0x11,0x99,0xE7,0xC2,0xE7,0x73,0xA1,0x06,0x9C,0x8C,0xD8,0xF3,0x55,0x52,0x07, +0xDB,0x64,0x4D,0xEF,0x81,0xE0,0x65,0x08,0xA4,0x48,0x4D,0xB8,0xFB,0xB1,0xD3,0x98, +0xAD,0xC1,0xE1,0x0D,0x73,0x1A,0x2F,0xB9,0x8B,0xAA,0x3E,0x47,0xD4,0xB2,0x45,0x35, +0x16,0x8E,0x98,0xAE,0xDB,0x48,0xDA,0x6D,0x33,0x68,0x29,0x17,0x71,0xCF,0xDD,0x3B, +0xA0,0x40,0x88,0x24,0xE1,0x19,0xD2,0x5A,0xD6,0x28,0x9D,0xE4,0x74,0xE4,0x22,0x0D, +0x97,0x80,0x89,0x1B,0xAC,0x22,0xA3,0x67,0x7C,0x80,0x5A,0x17,0x6B,0x5E,0x35,0xFC, +0x74,0x01,0x82,0xD2,0xC2,0x66,0x3F,0xE3,0xFC,0xA7,0xE9,0x0E,0x80,0xF5,0x72,0x1A, +0xF5,0x86,0x64,0x19,0x23,0x8D,0x1F,0x25,0x58,0x57,0xE5,0x35,0x3F,0x4A,0x0E,0xA2, +0xB6,0xFD,0x8A,0xCC,0x5B,0x48,0x72,0x82,0xB4,0xF7,0x5D,0x37,0xBC,0x1D,0x3F,0x83, +0x1D,0x4F,0xAA,0xD1,0x4B,0xFA,0xE0,0x8D,0xAC,0xE8,0xAC,0x22,0x4E,0xCF,0x5B,0x58, +0x81,0x6C,0x13,0x4A,0x6B,0x52,0xA1,0x4C,0x87,0x95,0x61,0xDB,0x22,0xAC,0x69,0xF9, +0xC1,0xA3,0xF2,0x5E,0xCF,0x89,0xE6,0x6F,0xB1,0xC7,0x04,0xC5,0xC7,0xF9,0x60,0xE8, +0x79,0x69,0x18,0x2E,0x02,0x77,0x5C,0xE6,0x34,0xBD,0x94,0x81,0x07,0xA8,0x9B,0x4A, +0x34,0xD6,0x5E,0xA2,0x23,0x1F,0x0C,0x1F,0x8C,0xC7,0xAE,0xA2,0xB2,0xFA,0x6F,0xCE, +0x8E,0x7E,0x47,0x5F,0x34,0x15,0x70,0x02,0xD6,0xA2,0x14,0x9D,0x1C,0x5F,0xA5,0xC2, +0x56,0x96,0x9E,0x7C,0xC2,0x96,0x0E,0x2F,0x61,0xC9,0xAA,0x83,0x4F,0xB7,0x10,0x1A, +0x7E,0x2A,0x73,0xA1,0x5C,0x70,0xCB,0x0C,0x1A,0x33,0x8B,0xF1,0xB9,0x83,0xE9,0xEA, +0xEA,0x04,0xC2,0xBF,0xCA,0xFD,0x1E,0x79,0xDB,0xBF,0x39,0x15,0xB7,0xBC,0x49,0xC9, +0x43,0x11,0x1A,0x22,0x85,0x66,0x60,0xBC,0x73,0x77,0x44,0x83,0xB8,0x68,0xA3,0xDE, +0xD7,0x0F,0xA1,0xDC,0xFE,0x0E,0xE3,0x03,0xD8,0xF3,0xCF,0xA8,0x24,0xA6,0x75,0x4F, +0x2E,0x7D,0xE5,0x1B,0xF3,0x9A,0x87,0x45,0xB6,0x06,0xB0,0x73,0xEC,0x1C,0xC7,0x77, +0xDC,0x68,0x1A,0x2C,0xB6,0xB1,0x52,0x17,0xB8,0xAA,0x7D,0x2A,0x92,0x7E,0xB4,0x36, +0x14,0xBC,0xB1,0xA9,0x98,0x01,0xE6,0x32,0x7D,0x40,0x8A,0x38,0x6A,0xB4,0x76,0x65, +0x26,0xF3,0x94,0x13,0x05,0xCA,0x60,0xC1,0x3C,0x42,0xCE,0x80,0x0E,0x4A,0x87,0xD4, +0x2B,0x35,0xF4,0x6D,0xB7,0xBE,0xFB,0xAB,0xA2,0xED,0x40,0x29,0x3A,0x6B,0x29,0x3B, +0xC8,0x99,0x57,0x44,0xA5,0x8D,0x71,0x6E,0x6E,0xFC,0x4D,0x66,0xDE,0x8D,0x74,0xA6, +0x78,0x49,0x7A,0x4C,0x64,0xE3,0xC6,0xF0,0x22,0x35,0xFE,0x70,0x99,0xA9,0x6F,0x41, +0x6F,0x63,0x4B,0x3D,0xF5,0x2A,0x97,0xD7,0xEC,0x21,0x1F,0x16,0xD5,0xDB,0x7B,0x17, +0x2C,0x0D,0x88,0x69,0xFE,0xF2,0xA9,0xA4,0x18,0x66,0x03,0x3B,0x6D,0x13,0x0E,0x0E, +0x0E,0xAE,0x8E,0x8D,0x1B,0x18,0xDF,0x7A,0x70,0xC6,0x84,0xEC,0x84,0xD3,0x70,0x63, +0x4A,0x94,0xC3,0xEF,0x5E,0x59,0x53,0x19,0x0A,0x12,0x08,0x88,0x43,0x65,0x36,0x0A, +0x13,0x72,0x5B,0x75,0xB0,0x8B,0xE3,0xEF,0xDD,0xCE,0x5A,0xD1,0x22,0x66,0xC7,0x63, +0x04,0x8C,0x17,0xB1,0xCC,0xF8,0x58,0x74,0xE0,0x6E,0x30,0x7D,0xEA,0x08,0xED,0x82, +0x2A,0x41,0x24,0xE5,0xA8,0x40,0x21,0x66,0x43,0x29,0x23,0xC9,0x24,0x44,0xF5,0xB4, +0xAC,0x47,0xDF,0xA9,0xCD,0x0F,0xD6,0xEA,0x43,0x97,0xBA,0x14,0x09,0xD7,0x48,0x18, +0xAE,0xCE,0x99,0xE4,0x62,0xF2,0x04,0x6B,0x36,0x78,0x8A,0x09,0x43,0x64,0xF7,0xEA, +0x0E,0xEC,0xA3,0xEE,0x94,0x9F,0x84,0xD5,0x17,0x89,0x7F,0x8F,0xDA,0x27,0x4C,0x87, +0x8F,0x42,0x18,0x16,0xCC,0xC2,0x19,0x32,0x8F,0xD9,0x14,0x53,0x1A,0x01,0xD4,0x57, +0x95,0xB9,0x95,0x4F,0xFF,0x07,0x54,0x2E,0xAB,0x1C,0xF8,0xEC,0xBC,0x2E,0xE8,0x1A, +0xFA,0x29,0x11,0xF7,0x60,0xC3,0x69,0x2C,0x40,0xE9,0x34,0xCE,0x8B,0x5C,0x4B,0x49, +0x22,0xBF,0x86,0xF2,0x13,0x17,0x82,0xEF,0xB3,0x91,0x58,0x15,0x52,0x71,0xF0,0xEC, +0x08,0x6B,0xE3,0x5C,0x54,0xA4,0x16,0x8C,0xD4,0xC8,0x54,0x7B,0x76,0x6C,0x1A,0xEF, +0xB4,0xA1,0xBF,0xF3,0x90,0x59,0x8F,0xF9,0xFF,0x16,0xF9,0xDD,0xE5,0xAF,0x76,0x94, +0x8E,0x58,0x84,0x7D,0x3C,0x69,0x22,0x9B,0x61,0x72,0x73,0xA4,0x17,0x73,0xFF,0xAE, +0xF7,0x7D,0x20,0x79,0x84,0x05,0x8D,0x9F,0xB3,0xEE,0x46,0x87,0x9A,0x4C,0x34,0xA7, +0xDD,0x04,0xE2,0x68,0xDC,0x31,0xE2,0x9D,0x3A,0x51,0xA3,0xB9,0x2B,0x1F,0x34,0x72, +0xC0,0x2B,0xED,0x33,0x86,0x17,0xCE,0xB8,0x6E,0xDB,0x1C,0x90,0x5F,0x35,0xF8,0x98, +0x0D,0xFF,0xFA,0x7D,0x02,0xA3,0xAF,0xBA,0xE1,0x7F,0xE7,0x4A,0x29,0xFB,0x94,0x4E, +0x9C,0x68,0xFA,0xDB,0x57,0xD3,0x95,0xE5,0xF0,0x52,0x11,0xB2,0x0F,0x55,0xA8,0x36, +0x24,0xF9,0xCA,0x42,0x28,0xA7,0xE5,0x6C,0x6E,0x1B,0xA8,0x56,0x87,0x9A,0x85,0x0B, +0x7C,0x60,0xD5,0x71,0x03,0xB7,0x1F,0xB4,0x40,0x6C,0x41,0x8B,0xDF,0x92,0xE1,0x85, +0xD5,0x2D,0xDD,0x88,0xB3,0xB1,0xC5,0x9B,0x27,0x52,0x93,0x3B,0xCC,0x1A,0xBA,0x44, +0xB8,0x27,0x82,0x07,0x18,0x22,0x2C,0x9B,0xA2,0x51,0x39,0xEA,0xEA,0x11,0x87,0x7F, +0xDA,0x4F,0x48,0x51,0x19,0xB7,0x78,0x46,0x37,0x47,0xD7,0xCC,0x52,0xFF,0xCA,0x1B, +0x75,0xB7,0x89,0x8C,0x77,0xA8,0x84,0x98,0x67,0x9F,0x60,0xF1,0x1F,0xE8,0x29,0xF5, +0x04,0x76,0xBB,0x15,0x50,0x7D,0xC6,0xA6,0xE8,0x6A,0xD2,0xBE,0x1D,0x48,0xB5,0x17, +0x5A,0x5B,0x0C,0x11,0xB7,0x98,0xBF,0xBF,0x71,0x81,0xCF,0x28,0xDD,0xED,0x34,0xEF, +0x00,0x09,0x01,0x22,0x15,0x65,0xB9,0xFF,0xFD,0xAC,0xD0,0x16,0xB0,0x82,0x15,0x2B, +0xF3,0xCE,0xA3,0x06,0xAB,0x34,0x1B,0x52,0x88,0x5D,0xE4,0x5F,0xB7,0xAB,0x48,0x96, +0x1F,0xC9,0x21,0x88,0x44,0x01,0x06,0xC8,0xAF,0xC5,0x83,0x19,0x24,0x33,0x86,0xDD, +0xA2,0x7D,0xB0,0x35,0x50,0x16,0x47,0x11,0x92,0x75,0x3D,0x5F,0x6D,0x69,0x45,0x3B, +0x26,0x92,0x3F,0xB4,0x44,0xBA,0x02,0x38,0x96,0xEA,0xED,0xE8,0xD0,0xE0,0x38,0x1C, +0x12,0xEF,0x4B,0x34,0xE5,0x5D,0x4E,0x47,0xF3,0x2B,0xE2,0x19,0x65,0x0C,0x4F,0xD0, +0xF9,0x31,0x3D,0xEF,0x04,0xFE,0x19,0xB7,0xA2,0x97,0x4F,0x79,0x56,0x10,0x19,0x6F, +0x91,0x11,0x35,0xBC,0x55,0x9B,0xD6,0xC2,0xD1,0x12,0x47,0xDD,0x91,0x09,0x82,0x40, +0x66,0x40,0x11,0xB2,0x9A,0x2B,0x29,0x39,0x54,0x1E,0x41,0xA3,0x8D,0x76,0x61,0x8A, +0x26,0x89,0xB2,0xC4,0x22,0xF8,0x6C,0x61,0x34,0xDC,0x2E,0x2F,0xF5,0x85,0x15,0x06, +0x63,0xCC,0x02,0x1C,0x6C,0x15,0x0C,0x9B,0xCC,0xBC,0x84,0x06,0xB2,0x4C,0xCA,0x6E, +0x1F,0x6F,0xAE,0x9A,0x7B,0xD7,0x79,0xCA,0xFC,0x3F,0xF8,0x28,0x55,0xF3,0xF2,0x93, +0xDD,0x95,0x08,0x3E,0x2D,0x69,0x97,0xA0,0xCD,0xAF,0x46,0xA1,0x5D,0x5A,0xAD,0x98, +0x04,0x11,0xD2,0xD6,0xE1,0x21,0xD4,0xED,0x19,0x0E,0xD9,0x5A,0x37,0x25,0x5C,0x04, +0x1A,0xF4,0xD9,0x0F,0x4A,0x4F,0x58,0x77,0x8D,0x20,0x07,0xAB,0x90,0xC2,0x52,0xB7, +0x40,0xC5,0x27,0xAD,0x2E,0xE6,0x0B,0xD4,0x1E,0x20,0x6F,0x38,0x4C,0x50,0x1D,0x2B, +0x7E,0xD6,0xA5,0xE7,0x66,0x03,0x34,0x2F,0xD9,0xBE,0xFC,0x06,0x4A,0xC2,0x9A,0x08, +0xA7,0xE3,0x70,0x89,0x33,0xB2,0x2F,0x20,0x6F,0xA2,0xE7,0x3A,0x37,0x52,0x1D,0x80, +0x81,0xCC,0xCA,0x26,0xD7,0xAE,0x1F,0xB7,0x18,0x6B,0x19,0x89,0xAF,0x7B,0x3C,0xFB, +0x93,0x3B,0xEC,0x2E,0x0D,0xE7,0xB7,0xC7,0xC1,0xDA,0x37,0xC5,0xAF,0xC3,0xEF,0x46, +0xF2,0x40,0xC2,0x1E,0x40,0x0C,0x84,0xBB,0x26,0x25,0x3F,0x07,0xCE,0x25,0x55,0x74, +0x1C,0x47,0xCA,0x08,0x05,0x0C,0xFF,0xCD,0x98,0xD6,0xEA,0x2E,0x27,0xD5,0xAD,0x47, +0x9F,0x97,0x0A,0x4A,0xD3,0x9F,0x9E,0xA3,0xCD,0x25,0xFA,0xD8,0xFA,0x9A,0x0D,0x6A, +0x68,0x9E,0x95,0x7B,0xA2,0xCE,0x8E,0xE0,0x36,0xCC,0xF5,0xE5,0x91,0x14,0x49,0xC7, +0x66,0xCB,0xDA,0x43,0x1A,0x49,0xEE,0xC1,0x74,0x05,0x0E,0xB5,0x7D,0x1D,0x3F,0x25, +0x84,0x74,0x0D,0x97,0xAB,0x9D,0x19,0x6C,0xEF,0x03,0xFB,0x24,0x50,0x9F,0xB2,0x2C, +0x95,0x2E,0x46,0xB5,0x29,0x7E,0x25,0x2A,0x83,0x0B,0x7A,0x46,0x8D,0xFD,0x67,0xE5, +0x29,0x29,0x7E,0x3B,0x17,0x17,0x6A,0x1F,0xB0,0x61,0x78,0xEA,0x28,0xE0,0xED,0x66, +0xC7,0xFA,0xC3,0xEE,0xF6,0xE6,0xC9,0x4A,0x7F,0xE8,0x71,0x13,0x13,0x3B,0x69,0x04, +0xDE,0x23,0x3D,0xB8,0xFB,0x92,0xEC,0x60,0xDC,0x58,0x7D,0xBA,0xD0,0xD7,0x9D,0xF4, +0xC6,0xF5,0xBD,0x66,0x7A,0x5D,0xEE,0x1F,0x75,0x70,0x39,0xB5,0x16,0xBD,0xD7,0x80, +0xBF,0xA6,0x77,0x62,0xE3,0x38,0x8F,0x10,0xAD,0x51,0x5D,0xC8,0x91,0xE4,0x7E,0x0A, +0x27,0xE7,0x42,0x04,0x8C,0xC1,0x16,0x56,0xD8,0x77,0x83,0x04,0x73,0xD7,0x26,0x35, +0x72,0xEB,0xF8,0xD8,0x0F,0x5C,0x5E,0xD4,0x57,0x2C,0x1B,0x7C,0x03,0x70,0xB3,0x78, +0xF3,0x2D,0x46,0xE4,0x7D,0xFE,0xC7,0xA8,0x0F,0x32,0xDE,0x6C,0xAB,0x6A,0x9E,0xBE, +0x44,0x2D,0x0C,0x15,0x22,0x7C,0x12,0x39,0x8A,0xF9,0xFD,0xCF,0x39,0xC0,0x14,0xF8, +0x36,0xFA,0xF1,0x1C,0x9D,0x92,0x0D,0x7A,0x31,0x1C,0x56,0x63,0x36,0x4D,0x8A,0xC4, +0x71,0x81,0x1E,0xF0,0x8F,0x42,0x7D,0x11,0xBE,0x5B,0x69,0x17,0xD4,0xA8,0xD5,0x30, +0xE4,0x85,0xC4,0x3A,0x0D,0xF6,0x52,0x81,0x5B,0x35,0xE1,0x87,0xCD,0x12,0x16,0x36, +0x5E,0xCF,0x64,0xC7,0x37,0xA8,0x94,0xA5,0xD6,0x39,0xE6,0x05,0xE6,0xF6,0x89,0x6D, +0x9B,0x9D,0x6F,0xAB,0x71,0x25,0x5D,0x63,0x07,0xB2,0xFD,0x74,0xEA,0xB3,0xBF,0x67, +0x46,0x8C,0x29,0x30,0x5C,0x7D,0x82,0xCC,0x8E,0xD9,0x06,0x88,0xE7,0xD4,0xF3,0xE7, +0xAA,0xBC,0x45,0xE8,0xC6,0x6D,0x9C,0xBD,0x62,0xAE,0x19,0x42,0x24,0x3E,0xD8,0x7D, +0xE1,0x8A,0xAC,0xB8,0xC2,0x70,0x66,0x89,0x4A,0x80,0x8F,0x13,0x27,0x06,0x63,0xA5, +0x80,0x3D,0xEC,0x27,0x00,0xDC,0xAD,0x7D,0xD4,0x33,0x78,0x2E,0x4E,0xAB,0x2B,0x5A, +0x93,0x68,0x44,0x20,0xAC,0xCC,0x5F,0x2F,0xC7,0xBF,0x56,0xA9,0xCA,0xF5,0x94,0x6F, +0x0D,0xE5,0x46,0x15,0x51,0x52,0xAF,0x5E,0x19,0x68,0x09,0xD2,0xD6,0xF8,0x6E,0x5C, +0xE9,0xBA,0x78,0xBC,0xE7,0x80,0x00,0x9A,0x66,0x71,0xCA,0x53,0x12,0xB2,0x1A,0xF6, +0x93,0xDF,0x5F,0x9E,0x32,0x85,0xCB,0xA3,0xD3,0xBD,0x63,0x6F,0xB6,0x70,0x58,0x57, +0x10,0x11,0x7A,0xA8,0x7F,0xC1,0xC1,0xBF,0x8E,0xAF,0x0D,0x5E,0x9B,0x1A,0x41,0x94, +0x46,0x45,0x8A,0x4B,0x00,0x72,0x8E,0x8F,0xF4,0xC7,0x9E,0xA0,0xE7,0xA5,0x7A,0xE6, +0xA0,0xB4,0x71,0x2F,0xF4,0x37,0xBA,0xC2,0xE6,0x42,0x27,0x5A,0x3C,0x5D,0x03,0x3C, +0x1C,0x84,0x37,0xD8,0xE1,0x05,0x27,0x33,0x1F,0xAE,0x31,0xDE,0x7D,0x53,0xB7,0x5D, +0x84,0x92,0x05,0x1E,0x8C,0xE5,0xC7,0x65,0x89,0x06,0x06,0x9C,0x77,0xC9,0xC6,0x67, +0x3F,0x2F,0x3B,0x52,0x84,0x17,0x3F,0x41,0xDA,0xE9,0x05,0x89,0x9D,0x8A,0xA1,0x81, +0x21,0x21,0x56,0xF5,0xAF,0xF9,0x97,0x34,0x37,0x1E,0x07,0x1C,0x52,0x09,0xA7,0xD1, +0x17,0x44,0xAA,0x7F,0x21,0x51,0xA5,0xB3,0x8A,0x60,0x33,0xAB,0xFD,0xF3,0x8D,0xA4, +0xED,0x89,0x69,0x98,0x15,0xC8,0x35,0xA8,0x7A,0xE5,0x4B,0xC2,0xF2,0x69,0x70,0x0E, +0xF8,0x8E,0x8C,0xCC,0x0B,0xC6,0x42,0x43,0x92,0xBB,0x17,0x62,0xCC,0x45,0x6C,0xBD, +0xB5,0x84,0x85,0x76,0xA7,0x8C,0x0D,0x86,0x8B,0x1A,0x01,0x37,0xFE,0xA8,0x05,0x4A, +0x2E,0xD2,0xA9,0xD5,0x69,0xA9,0x99,0x25,0x1D,0xD4,0x3F,0x60,0x5A,0x66,0xC1,0xE6, +0xB1,0x11,0xE7,0xE1,0x3E,0xB4,0xFF,0xA4,0x84,0x8F,0xEA,0x25,0x4B,0xF4,0xC1,0x49, +0x7B,0x7F,0x81,0x9C,0xE7,0xA3,0x58,0x0C,0xA8,0x4D,0xDE,0x64,0x13,0x5A,0x7F,0x29, +0x39,0xB2,0xC3,0x73,0x0C,0xD4,0x1A,0x7B,0x37,0x5B,0x36,0x31,0x2E,0xB7,0x9E,0x73, +0xAC,0x29,0x3E,0xA6,0xCB,0x0D,0x6D,0xC3,0xD9,0xB5,0x0F,0x9A,0xD9,0xAD,0x1D,0x0B, +0x7D,0x55,0x33,0xBD,0x2F,0x17,0x25,0x19,0x4C,0xB4,0xB7,0x3E,0xCF,0x64,0x8E,0x51, +0x73,0x92,0x75,0xC8,0x90,0x82,0x3E,0x74,0xC7,0x53,0x10,0x74,0xFA,0x7C,0xE7,0x08, +0x65,0x46,0x65,0x04,0x28,0xD4,0x49,0xEF,0x09,0x26,0x2E,0x1A,0xAE,0x68,0xF1,0x40, +0x0D,0x95,0xE8,0xD4,0x18,0xE7,0x36,0x3B,0xEF,0x9B,0xD0,0xF7,0x23,0x74,0x24,0xDC, +0x77,0x4C,0xB7,0x9F,0x73,0x83,0xAD,0xFC,0x09,0x1F,0x8B,0x03,0xCD,0xF2,0x74,0xDC, +0x6B,0x6B,0x31,0xC2,0x4B,0xF3,0x1F,0x93,0xFA,0x26,0xC9,0x80,0x00,0x9B,0x67,0x70, +0x96,0x73,0x6A,0x39,0xA0,0xC9,0xA1,0x35,0x16,0x6E,0x0E,0xEE,0x9B,0xA9,0x71,0x70, +0xB8,0x27,0xFC,0x3F,0x37,0x44,0xE3,0x93,0x2C,0x24,0xA0,0x42,0xD8,0x4A,0x21,0xA2, +0xFF,0x3C,0x4F,0xA0,0x0B,0xD9,0x86,0xB9,0x97,0xE5,0x84,0x04,0xFE,0xE2,0x4F,0x78, +0x02,0x4C,0x5B,0xE9,0xC3,0x81,0x6B,0x05,0x76,0x59,0xF3,0x6C,0xA9,0x0C,0x4D,0x56, +0x84,0x01,0x72,0xD2,0x14,0x79,0x0C,0x74,0x86,0x45,0x85,0x06,0x08,0x3B,0xD6,0x2E, +0xDC,0xE9,0x92,0x06,0x6D,0x44,0xEF,0xA9,0xEE,0x00,0xBF,0x04,0x44,0xEC,0x0D,0x61, +0x45,0x24,0x52,0x20,0xF5,0x84,0xA2,0x59,0xAA,0xA4,0xBE,0x95,0x2E,0x20,0xC1,0x6C, +0xF6,0x2F,0x74,0x1E,0x9D,0x00,0x11,0x37,0x18,0x15,0x46,0x6E,0x98,0x26,0x85,0x9C, +0x92,0x98,0xE5,0x8D,0xAF,0x3C,0x5B,0x24,0x1B,0xAC,0xB7,0x88,0x01,0xC2,0xFC,0x93, +0x2D,0x15,0x7A,0x2B,0xE8,0x11,0x16,0x21,0xB4,0x19,0xD5,0x91,0xD1,0xEF,0x52,0x5B, +0xD9,0xE6,0xA2,0xA5,0x2C,0x26,0x7B,0x1B,0xB8,0x28,0x04,0x51,0x41,0x25,0xCF,0xEB, +0x7B,0xA9,0xC6,0xF4,0x79,0x25,0xDF,0xDB,0xBA,0x7A,0xE3,0x7A,0xB9,0x96,0xD4,0xC7, +0xF7,0xE4,0x3A,0x67,0x51,0x14,0x9C,0x82,0xE2,0x87,0x3F,0x1D,0xE9,0xED,0x1B,0x3A, +0x41,0xA5,0xF7,0x8B,0x8E,0x92,0xAC,0x00,0x51,0xFD,0x4D,0x73,0x65,0x12,0x40,0xF6, +0x55,0x19,0x69,0x21,0x48,0x75,0x46,0x95,0x2C,0x8F,0xE5,0xCA,0x79,0xDC,0x23,0x5A, +0x81,0x4A,0x2B,0xD4,0x05,0x9A,0x42,0x90,0xEF,0xE5,0xA8,0x80,0x8A,0xC9,0x81,0xD0, +0x20,0x23,0x85,0x54,0x32,0x47,0xC4,0xFD,0x53,0x14,0xD0,0xB1,0xE8,0xF6,0x5E,0x34, +0x69,0x87,0x1E,0x02,0x13,0xC2,0x04,0x23,0x99,0x88,0x86,0xE8,0xF2,0x41,0x48,0x19, +0x56,0x1E,0xBD,0x80,0x50,0x5B,0xA5,0x92,0xC3,0x4A,0x1A,0x4F,0x7F,0x9B,0xA9,0x10, +0xB5,0x20,0xDB,0x8D,0x07,0x7B,0xA8,0xA0,0x90,0xB8,0x3C,0x80,0x5E,0xFF,0xB9,0xAF, +0x6D,0x93,0xD0,0xC3,0xC6,0x22,0x76,0x45,0x6C,0xFD,0x8C,0x3D,0x08,0x0D,0xF0,0x8C, +0x3E,0x80,0xE7,0x98,0x6B,0x2C,0x74,0x67,0xB5,0xD0,0xA0,0x61,0xEF,0x49,0x42,0xFD, +0x66,0xD0,0x84,0x65,0x00,0xD7,0xBF,0x83,0xCB,0x43,0xC9,0x86,0x15,0x07,0x75,0x95, +0x15,0x47,0xCC,0x96,0xE6,0xEA,0x3B,0x76,0x65,0x0A,0x91,0x9B,0xDB,0x04,0x24,0x02, +0xBA,0x43,0x9F,0xFD,0x6F,0xE5,0xA7,0xE0,0x45,0x80,0x43,0x5E,0xE1,0xBC,0xF9,0xA5, +0xB6,0x42,0x1F,0x2C,0x03,0x41,0xBD,0x70,0xCA,0x28,0x1B,0x7D,0x07,0x87,0x61,0xB8, +0xFB,0x68,0x71,0xE2,0x51,0x2C,0xD5,0xE6,0xD2,0x5E,0xAC,0xCD,0xB6,0xCD,0x12,0xBB, +0x8E,0xDA,0xB3,0xE3,0x16,0xF1,0xA2,0xB7,0x34,0xFB,0x2F,0x50,0x0D,0xC0,0xB8,0xAC, +0x94,0x01,0x75,0x68,0x94,0x67,0x97,0x0E,0x52,0xB5,0x4B,0xFA,0x9B,0x49,0xC1,0x7C, +0x9B,0x52,0xDD,0x7B,0xB5,0x60,0x4C,0x6B,0x43,0x20,0xFE,0xF1,0x30,0xDD,0x84,0x67, +0xD0,0x4E,0xF2,0x64,0x32,0xAF,0x49,0xB0,0x18,0xE6,0x14,0x60,0xD9,0xF1,0x27,0x4F, +0x14,0xE3,0x4B,0x56,0x6E,0x23,0xEF,0xE0,0xC5,0x38,0x07,0x78,0x7C,0x1D,0x51,0xCC, +0x46,0x3D,0x21,0x1F,0x9F,0xEB,0x7C,0xE3,0x45,0x46,0xE6,0xAE,0x0C,0x70,0x03,0xF5, +0xC8,0x93,0x19,0x72,0x34,0xDD,0x36,0x36,0x02,0x5C,0x4B,0x96,0x70,0x55,0x38,0xCC, +0xF6,0xAF,0xB2,0xEF,0x3B,0xA2,0x12,0x7E,0x15,0xC1,0xF5,0x17,0x9A,0xFF,0xF9,0x8C, +0x65,0xE0,0xF8,0x19,0xA8,0x41,0x0D,0xD0,0xE1,0x51,0xC7,0xCB,0x71,0xF7,0xFD,0x0F, +0xEC,0x42,0x01,0xD4,0x37,0xF9,0x46,0x12,0xA0,0x79,0x24,0xF3,0x2B,0x70,0x75,0x9E, +0xFA,0x10,0x84,0x1B,0x90,0x73,0x92,0x74,0x3C,0x46,0xDD,0x93,0x47,0xE4,0xED,0x4C, +0x7D,0xA9,0x00,0x9A,0xA3,0xDA,0x35,0xF8,0x96,0xAF,0x7E,0x55,0x67,0x70,0x79,0x57, +0xD6,0x64,0xDD,0xB5,0x8C,0x66,0xDD,0x64,0x74,0xE9,0xB0,0xFE,0xC4,0xB8,0x4F,0xEB, +0xBA,0x27,0x97,0x30,0x32,0xCD,0x69,0xE4,0x59,0xC3,0xA3,0x5B,0x44,0xB8,0x64,0x91, +0x12,0x67,0xAB,0xCA,0x08,0x48,0xB7,0x54,0xD3,0x7A,0xFA,0xA2,0x0C,0x0F,0x9D,0x20, +0x7A,0x2E,0x2C,0x1F,0xBC,0xF9,0x01,0x0A,0x62,0x89,0x7A,0xA3,0x58,0xA4,0xBC,0xE2, +0x14,0xD8,0x4C,0x09,0xB7,0x8F,0x18,0xDE,0xD0,0x29,0x32,0xF9,0x70,0x47,0xB2,0xBE, +0x17,0x9C,0xAA,0xAD,0x38,0xA3,0x04,0xD9,0xE0,0xC7,0x07,0x5B,0x48,0x86,0x87,0x17, +0xD7,0xFA,0x26,0xEA,0xAA,0xC9,0x7E,0xFF,0xFF,0xD8,0x6F,0x7B,0xC4,0xB7,0x5E,0xE4, +0xE1,0x41,0x70,0xED,0xD7,0x9D,0xB0,0x53,0x2D,0x70,0xDF,0x64,0x29,0x9C,0xAF,0x46, +0x07,0xD4,0xFE,0x83,0x46,0x7E,0x52,0x76,0x78,0xB7,0x12,0x6E,0x90,0x4E,0x58,0x70, +0x53,0x8F,0x3B,0xE8,0xAF,0xF8,0x67,0x49,0xD5,0xA9,0x12,0x1F,0x06,0x82,0xF5,0xBA, +0xCB,0x13,0xF1,0x9E,0x4B,0xA8,0xA0,0xEE,0x11,0x7D,0xA8,0xD5,0x58,0xB8,0xD6,0x22, +0x25,0x94,0xD4,0x5F,0x78,0x4F,0x45,0x34,0x43,0x61,0x5A,0x92,0x0C,0xAB,0xCA,0xAB, +0x88,0x94,0xE4,0xFE,0x97,0x22,0xFA,0xE4,0x12,0xF8,0x67,0x49,0x87,0x06,0x67,0xC7, +0xE6,0xDC,0xA2,0xCA,0x42,0xBA,0x79,0xC2,0xA1,0x5A,0x00,0x94,0x17,0x06,0xEA,0x87, +0x5D,0xBB,0xC3,0xEA,0xFA,0xA4,0x15,0x72,0x82,0xBD,0x7F,0x42,0x18,0x39,0x9B,0xD2, +0xA5,0x39,0xEB,0x17,0xF5,0x6A,0x8F,0x9A,0x4D,0xA3,0xE6,0xA6,0xB5,0xE9,0x32,0x88, +0x97,0x01,0x7C,0x1B,0x59,0xD2,0x90,0x52,0x25,0xF0,0x41,0xA4,0x39,0xF6,0x4B,0x90, +0x71,0xFA,0xA9,0xE4,0x91,0xB7,0xAB,0x39,0x40,0xE6,0x31,0xD4,0xBE,0x4F,0x6F,0x6C, +0x63,0x7C,0xE4,0x2B,0x9E,0x0E,0xA7,0xF5,0xAA,0x69,0x68,0x2D,0x58,0x00,0x88,0x2A, +0xA1,0xCE,0xED,0xEB,0x96,0x3B,0x74,0x39,0xEF,0xF5,0x08,0x8D,0xC2,0xC0,0x77,0x1A, +0xDC,0x25,0xC8,0x82,0x11,0xD5,0xDB,0xF5,0x3B,0x2D,0x39,0xDF,0x89,0xAC,0x75,0xED, +0x7D,0x82,0xBD,0x4C,0x71,0xFE,0x55,0x70,0x97,0x8C,0xA0,0xF1,0x7B,0xE9,0x15,0x41, +0xF4,0x88,0x99,0xB9,0xFE,0xBE,0xE4,0x9A,0x27,0x08,0xE8,0x0C,0xFC,0x62,0xB3,0x2F, +0xC4,0x13,0xE3,0x6F,0x23,0x25,0xB2,0xC5,0xDE,0x7B,0x39,0xBF,0x5C,0x4E,0x2E,0x13, +0x5C,0xA0,0x4E,0x57,0x1C,0x15,0x07,0x5B,0x43,0xA7,0x99,0xD9,0xC1,0x65,0x49,0x99, +0x41,0xCC,0x83,0x43,0xC6,0xFC,0xD6,0x7B,0xD4,0xD1,0x07,0xDE,0x24,0x8F,0x4B,0x26, +0x5F,0x21,0x93,0xF7,0x0C,0x23,0x15,0x40,0xF1,0x4B,0x41,0xB3,0x69,0x25,0xCC,0xFB, +0xD1,0xED,0x36,0xF4,0x3C,0x05,0xD7,0xAD,0x38,0xDD,0x6A,0xB3,0xDF,0xEB,0xF2,0xC3, +0xD4,0x16,0x97,0xD6,0x51,0x84,0x9A,0xC3,0xA5,0x8B,0x0D,0xAE,0x92,0x3A,0x68,0x49, +0x9C,0xF6,0x37,0xCB,0x7E,0x40,0x93,0x1E,0x17,0x21,0x59,0x25,0xDE,0x44,0x37,0x5C, +0x27,0x60,0x9F,0xAC,0x9B,0x17,0xC7,0x3A,0x05,0xE1,0xC4,0x0C,0xB5,0xF6,0xE5,0xDF, +0xC5,0xEB,0xCA,0xD0,0xE1,0x57,0x5D,0x43,0x5A,0x8C,0x62,0xDB,0x7C,0xF4,0xE6,0xE9, +0x86,0x43,0x44,0x42,0x91,0x18,0xCC,0xEE,0xDD,0x1A,0x3E,0x86,0xC5,0x0C,0xB9,0x47, +0xA0,0x85,0xDF,0x8B,0x38,0x0C,0x37,0xBF,0x13,0x56,0x55,0x2B,0xCB,0xE9,0xDB,0xD7, +0xAF,0x96,0x5A,0x47,0xFA,0xA6,0xF5,0x74,0x80,0x6C,0x14,0xD9,0x54,0x77,0xE3,0xA9, +0x50,0x01,0x30,0x4D,0x0D,0xB8,0xC8,0xB4,0x9F,0x04,0x17,0xD7,0xA3,0x2A,0x5E,0x14, +0x5B,0x4E,0x93,0x18,0x06,0x72,0x35,0xBE,0x4B,0xB6,0x89,0x28,0x07,0x22,0x96,0x7B, +0x26,0x44,0xE1,0x3A,0xC5,0x97,0x05,0x44,0xCE,0x6A,0x08,0x0D,0x83,0x3B,0x1C,0x80, +0x7A,0xB0,0x64,0xBD,0x3B,0xBD,0xA3,0x95,0x6D,0xC1,0x40,0xB6,0xD6,0xCC,0x4A,0x29, +0x29,0xE6,0x66,0x4F,0xC6,0x94,0x97,0x43,0x4A,0x0B,0x06,0x3D,0x83,0x43,0xCD,0x00, +0x1A,0xF6,0x38,0x38,0xB9,0x51,0xDE,0x79,0xBB,0x08,0x9C,0x38,0x89,0xA2,0xB5,0x26, +0x0A,0x00,0xFC,0x34,0xDC,0xBB,0x74,0xB3,0xB4,0x4D,0x35,0x12,0x8B,0x07,0x9B,0x1A, +0x2C,0x46,0x7E,0x75,0x89,0x41,0x12,0x7B,0x2B,0xA6,0xE0,0x61,0xDE,0x4C,0x55,0x33, +0x23,0x03,0x0B,0xCE,0x6E,0x7D,0x05,0x58,0xBB,0x20,0xE1,0x96,0x53,0xFD,0x64,0xF6, +0x34,0x1A,0x7C,0x8C,0x2C,0x3A,0x4C,0xA4,0xAE,0xC5,0x02,0xEC,0xBC,0x51,0xC6,0x14, +0xE5,0x01,0x86,0xA5,0xE9,0xC2,0x78,0x28,0xC8,0x71,0x29,0x1E,0x2B,0x1F,0x92,0x71, +0x88,0x1A,0x3A,0x32,0xED,0x65,0x90,0xDC,0x04,0x17,0x29,0x29,0x86,0x1B,0x6B,0xC5, +0xEA,0xA6,0x29,0xA6,0x08,0x08,0x2B,0x20,0x08,0x7E,0x4F,0xE5,0x10,0xD2,0x27,0x58, +0x24,0xBD,0x95,0xF2,0x42,0x6D,0xCD,0x28,0xF6,0xF7,0x59,0xA3,0xD8,0x71,0x5B,0xB4, +0x9E,0x9D,0x10,0x47,0xF9,0x72,0x3D,0x22,0x68,0x75,0xF0,0x05,0xFC,0xA9,0x47,0xC8, +0xBC,0xA5,0x63,0xB5,0x51,0xFA,0x0C,0x46,0xF1,0x0B,0x85,0xA7,0x08,0xB9,0xCF,0xA9, +0xDC,0x97,0xE5,0xFC,0xA3,0xE0,0x4E,0xE0,0x62,0x73,0x92,0x6B,0x44,0x18,0x71,0xA2, +0x96,0x25,0xB7,0x02,0xB9,0xAE,0x68,0x65,0x8F,0x3B,0x5A,0x9E,0x2F,0x04,0x69,0xD3, +0xFF,0x75,0x33,0x60,0x74,0x37,0x41,0xDD,0x5E,0x27,0x4B,0x8D,0x01,0x2E,0x9B,0x08, +0x2E,0xE8,0xDF,0x9B,0xA6,0x1A,0x0C,0x79,0xE0,0xDB,0x61,0x5B,0x0F,0xD5,0xE0,0x06, +0x90,0x5E,0xA4,0x83,0xA3,0x44,0xCC,0x1D,0xF3,0x4E,0x0A,0xA4,0xED,0xFA,0x7E,0xD0, +0xB5,0xA8,0xC5,0x27,0x41,0x24,0x92,0xB8,0x72,0xF2,0x6D,0x80,0xCB,0xC8,0xEC,0x6A, +0xFF,0xA3,0xFC,0xE5,0x92,0xFE,0xE9,0x1E,0xD3,0xAF,0x39,0x9A,0xED,0x32,0xF7,0xBA, +0xFE,0x78,0xFF,0x0D,0x59,0x5D,0x7E,0x38,0xD9,0xCA,0x17,0xAD,0xEE,0xDE,0x1A,0xEB, +0x5F,0xCA,0x17,0x74,0xFF,0xC5,0x7D,0x24,0x9A,0x3D,0x73,0xAA,0xA4,0x31,0xF2,0x08, +0x69,0x0B,0x5A,0x1C,0x4D,0x09,0x78,0x48,0x38,0x9B,0xEA,0xAA,0x75,0x67,0xF7,0x87, +0xFB,0x43,0x3D,0x95,0x35,0x28,0x22,0x1D,0xDD,0xF9,0x26,0x23,0xDB,0xF6,0x86,0x00, +0xFA,0x58,0x9B,0x8C,0x10,0x7A,0x11,0x8B,0x4F,0xD5,0x82,0xCF,0xE4,0xD4,0x03,0xAD, +0x7B,0x4D,0x1D,0xBD,0x33,0xD5,0xC0,0x8F,0x45,0x3C,0xB1,0x6D,0xBD,0x55,0xC2,0x5C, +0x40,0xA0,0x89,0xEE,0x61,0x6A,0xD1,0x14,0xE1,0x59,0x4E,0xEB,0xA0,0x36,0x19,0x9A, +0x69,0x41,0x0F,0x86,0x62,0x95,0x9E,0xCF,0xF4,0xC6,0x6F,0x3D,0xE7,0xD6,0x11,0xCB, +0x73,0xEE,0xC1,0xE4,0x4C,0x47,0x38,0x05,0x58,0x1F,0x46,0xF8,0xA6,0x0E,0x4E,0x35, +0x6D,0xB8,0x20,0xA8,0x10,0x88,0xDE,0x33,0x60,0x99,0xAE,0x3F,0xE6,0xDB,0x59,0xCE, +0xA5,0x8E,0xB3,0xA7,0x67,0x76,0xAA,0xB0,0xE2,0x94,0x49,0x82,0x2F,0x9C,0xFE,0x79, +0x53,0x19,0x1D,0xE3,0xD7,0x35,0x02,0xE9,0x54,0x74,0xF5,0x32,0x23,0x49,0x9E,0x1C, +0x4B,0xBF,0x09,0x4B,0xBD,0x5E,0xA9,0x75,0xF7,0x96,0xE7,0x8C,0x54,0x62,0xC5,0x29, +0x88,0xD4,0x41,0x77,0xAB,0x0A,0x40,0x81,0xAF,0x71,0x3E,0x34,0xEE,0xA1,0x58,0x61, +0x8C,0x79,0x97,0x26,0x63,0xF4,0xCB,0x5E,0xE2,0x1D,0xF9,0xF0,0xFE,0x01,0x57,0xC8, +0x8C,0xAE,0x9C,0xC0,0x83,0x8F,0x2C,0x0B,0xCD,0xF4,0x1F,0x52,0x0E,0xD7,0x1F,0x8D, +0xAF,0xD3,0xDC,0x85,0xC7,0xB8,0x21,0xAB,0x50,0xAC,0x04,0xD8,0x7F,0x4A,0xF5,0x5D, +0xBB,0x18,0x4E,0x0F,0x07,0xBF,0xD8,0x7A,0xD1,0x73,0x54,0xBC,0xE3,0xEE,0x61,0xC3, +0x1E,0x22,0x79,0x60,0xC3,0x06,0x81,0xE0,0x7E,0x67,0x8D,0x68,0xEC,0x20,0x4C,0xA2, +0xC6,0x83,0x4C,0xBC,0x4B,0xF7,0x54,0xE9,0xA9,0xF6,0xA3,0xBB,0xD5,0x2E,0xAE,0x86, +0xA1,0x40,0x74,0x44,0x9E,0xEE,0x55,0xEC,0xE2,0xF8,0x57,0x51,0xC2,0xA0,0xAA,0xE2, +0x2F,0x66,0xE7,0xF8,0xD2,0xC0,0xF2,0x0A,0x24,0xA3,0x0E,0xFA,0x6C,0x08,0x35,0x09, +0x30,0x30,0xF6,0xE4,0x33,0xD0,0xD2,0xF0,0x6E,0x44,0xC2,0x72,0x38,0x4F,0x48,0xB1, +0xFC,0xAA,0x9B,0x2F,0x34,0x83,0x5A,0x70,0x38,0x93,0xF8,0xE1,0xF3,0x05,0x76,0x46, +0xCA,0xB2,0x44,0xD8,0x61,0x02,0xB5,0x7F,0x77,0x4A,0xBE,0x0A,0xAF,0xE4,0x06,0x82, +0xC0,0xFF,0x53,0x9D,0x1C,0x4C,0x5F,0xE6,0x30,0x88,0xC9,0x5C,0x14,0xA0,0x90,0x36, +0xCA,0x8D,0x83,0xF0,0x3E,0x74,0x8E,0x1B,0x48,0x2A,0xEE,0x4A,0xBD,0x0A,0x6D,0x22, +0xAF,0xCC,0xE4,0xE3,0x67,0x29,0x81,0xC1,0x74,0xB6,0x91,0x29,0x82,0xB9,0x81,0xB4, +0xBC,0x99,0xAE,0x98,0xD4,0x62,0x6B,0x0A,0x0A,0x73,0x20,0x88,0xB5,0xD8,0xF0,0x55, +0x23,0xA9,0x4B,0x5A,0x3F,0xC5,0x65,0xFE,0x08,0x09,0x0F,0x43,0xAC,0x44,0x3B,0x94, +0x71,0x89,0x1A,0x3A,0xA3,0x2D,0xF6,0xB9,0x49,0x4E,0x62,0xFB,0x88,0x83,0xDA,0x1F, +0xC8,0xBD,0xFD,0x09,0x6B,0x37,0xD2,0xDD,0xC7,0x9C,0x6B,0x94,0x8F,0x56,0xEA,0x12, +0x6E,0x73,0x48,0xFF,0x8F,0xFB,0x50,0x7E,0x70,0x12,0xF9,0x97,0x75,0xE7,0xBD,0x96, +0x30,0xF4,0xBB,0x7F,0xDD,0xEE,0xAA,0x1F,0x6D,0x0B,0x36,0xEB,0x23,0xE1,0x49,0xE6, +0xB2,0xFF,0x47,0x99,0xE7,0xDD,0x87,0x67,0xCE,0xDD,0xD2,0x75,0xC3,0x7F,0x50,0x3B, +0x63,0xDA,0x19,0x1E,0x5F,0x06,0xDC,0xCC,0x98,0x6B,0xFA,0x1A,0xD5,0xBD,0x44,0xFB, +0x23,0x58,0x4B,0x25,0x49,0xBE,0x1D,0xF7,0x71,0xEA,0x54,0xBA,0xD9,0x25,0x33,0x68, +0xEF,0xAC,0x89,0x22,0x40,0xD1,0x61,0xC5,0x1D,0xB1,0xBB,0x61,0xD0,0x6B,0x4B,0x3C, +0x06,0xAF,0x66,0x08,0x1E,0x1E,0x3A,0x03,0x08,0x15,0x0D,0xB7,0x2C,0x26,0xD7,0x4C, +0xA8,0x66,0x7D,0x07,0x6B,0xAD,0x36,0xE3,0x4B,0x9A,0x40,0x6A,0xF1,0x51,0xD2,0x2D, +0x0A,0x0E,0xEE,0x0A,0x2C,0xF8,0xD7,0x25,0xFC,0xC9,0xCD,0xDD,0xD7,0x06,0xF3,0x9E, +0xE7,0x50,0xF5,0xC2,0x4E,0xC3,0x13,0x04,0xC9,0x46,0xBA,0x79,0xEF,0x30,0xF3,0xD4, +0xA2,0x4C,0x99,0x0C,0xB3,0x5E,0xE7,0xFF,0xF7,0x82,0x1C,0x6D,0x58,0x8B,0xC8,0x22, +0x93,0x11,0x1C,0x3C,0xD7,0x6A,0x8B,0xC2,0x23,0x73,0x2A,0x4A,0xF9,0x0C,0xED,0xD0, +0xA2,0x38,0x2A,0xDF,0xF1,0x47,0xFE,0x05,0x96,0x60,0x33,0x0A,0x60,0x1F,0xD0,0x6C, +0x31,0x3A,0x5A,0x4E,0x26,0x61,0x03,0x91,0x55,0x2C,0xF4,0x0D,0xA6,0xBB,0xBE,0x87, +0x70,0xD1,0xC3,0x1D,0xA3,0x8A,0x57,0x46,0x4D,0xF6,0x9A,0xEB,0x61,0x19,0xF5,0xB4, +0x9C,0x55,0x1B,0x6C,0x3A,0xA8,0xBE,0xEA,0x29,0x83,0xD9,0xA8,0x9F,0x1D,0xA0,0xD5, +0x83,0x1C,0x41,0xF6,0x2A,0xCA,0xEB,0x77,0x65,0xC2,0x0A,0xA1,0x70,0x82,0x2F,0x5F, +0xBA,0x3E,0xF7,0x63,0xFC,0xF1,0xEE,0xC0,0xF3,0x7E,0xA2,0x99,0x96,0x05,0xC2,0xD4, +0xFB,0x28,0x04,0xD1,0xA8,0x9C,0x62,0xBF,0x78,0xB3,0xCD,0xD5,0xD6,0x5D,0x8B,0x8E, +0x27,0x30,0x45,0xFA,0x17,0x49,0xE7,0xC9,0x46,0x1D,0xD0,0x61,0xBF,0x37,0x24,0x62, +0x02,0x50,0x69,0x31,0x2C,0xA8,0xE5,0x29,0xF9,0x81,0x33,0x34,0xB8,0x65,0xC7,0xAC, +0x53,0xBE,0x4A,0xEE,0x40,0x19,0x3B,0x99,0xAF,0x96,0xC3,0x95,0xA4,0x7D,0xEC,0x2D, +0xB7,0xF4,0x6A,0xDF,0xB0,0xCE,0xFB,0x3C,0xA3,0xCA,0xD2,0x52,0x6A,0xEE,0x9B,0x42, +0xF4,0xF5,0xD1,0xF3,0xBC,0x6A,0x2E,0x64,0x6E,0x16,0x36,0xE1,0x97,0xCF,0xBB,0x51, +0xA9,0x53,0x3C,0xEA,0xEA,0x93,0x5E,0xA0,0xD5,0xD3,0x99,0x84,0xA7,0x58,0xBE,0x45, +0x75,0x8D,0x09,0xFC,0x40,0x68,0x9D,0x2F,0x78,0xE3,0x39,0xA1,0xC5,0x69,0xB1,0x77, +0x4C,0x5F,0xCB,0xD4,0x5B,0xC4,0x08,0x7C,0x72,0x62,0x9E,0x7F,0x68,0xE1,0x94,0x77, +0xDD,0xD3,0x58,0x4F,0xA7,0x5D,0xC8,0xDA,0xDD,0x8F,0x0A,0x38,0xC1,0x9D,0x79,0x31, +0xAC,0x96,0x68,0xC9,0x13,0x71,0x3F,0xBE,0x12,0x38,0x69,0xFE,0xEE,0x40,0x40,0x0E, +0xF8,0x33,0xDE,0x59,0xC2,0x3D,0xC9,0xD7,0x0D,0xFC,0x77,0x5E,0x3F,0x92,0x02,0xEE, +0x67,0x07,0xB1,0x0C,0x6C,0x4F,0xD3,0x0A,0xAD,0x9B,0x15,0x0E,0xBF,0xAC,0x09,0x03, +0x3F,0x48,0x79,0x25,0x1A,0xDE,0xB5,0x3E,0x43,0xCE,0x99,0x9B,0xC6,0x26,0xEC,0xC6, +0x5E,0x66,0x3A,0xA3,0x97,0x19,0xA7,0xB9,0x0E,0xFE,0x2E,0x74,0x8A,0x66,0x2F,0x88, +0x12,0x01,0x6A,0xB3,0xE4,0x1D,0x37,0xB6,0xD9,0xC5,0x90,0xE3,0xCC,0x51,0x66,0x71, +0xD3,0xE1,0x30,0xBE,0xE7,0xCF,0x4A,0x9D,0xB5,0x28,0x46,0xF8,0x42,0xA8,0x58,0xE7, +0x46,0x2F,0xF9,0x9D,0xAB,0xD8,0x47,0x25,0xCC,0x4D,0xD1,0x1A,0xBA,0x10,0x40,0xC6, +0x86,0x78,0x8C,0x5E,0xBA,0x9E,0x5A,0x38,0xE7,0xB9,0x78,0xA4,0xBA,0xBF,0x8B,0x66, +0xC5,0xBD,0x80,0xFD,0xC2,0xE1,0x49,0x5B,0xAE,0x90,0xDE,0xB1,0xAC,0xD2,0x51,0xE5, +0x72,0x22,0xF7,0x9E,0xAF,0x90,0x90,0xC3,0x47,0xFF,0x93,0x78,0xB9,0xD5,0xAD,0x25, +0x13,0xA9,0xA9,0x78,0x9C,0x66,0x76,0xF5,0xC8,0x93,0x62,0xCB,0x2B,0x49,0x80,0x46, +0x3C,0x3B,0xA8,0x91,0xF3,0xFB,0xDE,0x34,0x76,0xEB,0x43,0x6F,0x52,0x6F,0x26,0x88, +0xB8,0x2C,0x37,0xA3,0xF2,0xE1,0x9F,0x10,0xE9,0x80,0x81,0xA5,0x3B,0x15,0x82,0xD0, +0x2A,0x7E,0x7C,0x4E,0x60,0x4A,0xA8,0xCF,0xC8,0x7F,0x86,0x52,0x8F,0x77,0x51,0x40, +0x56,0xFF,0x0F,0xEC,0x2B,0xC0,0x08,0x63,0x09,0x02,0x62,0x8C,0x23,0x73,0x7A,0xDE, +0xD5,0x15,0x7E,0x6D,0xB0,0x28,0x82,0xCB,0x4F,0xD4,0x3B,0xA7,0xB7,0xE0,0xAD,0x1E, +0xC2,0xD3,0x12,0x0E,0x5E,0x01,0x7F,0xD6,0xF2,0x4D,0x39,0x43,0x5E,0x5D,0x00,0x4D, +0x16,0x55,0xE0,0xDE,0x9F,0x96,0x46,0x96,0x2B,0x42,0x6E,0x47,0xF4,0x4F,0x75,0xDA, +0x93,0x4E,0xCA,0xDD,0xF3,0xCD,0x1A,0x90,0xDA,0xE5,0x95,0xDF,0x33,0x7D,0x05,0x1E, +0x1A,0xB0,0xA9,0x79,0x62,0x18,0xAD,0x06,0x21,0xF1,0x56,0xA0,0x01,0x96,0xE1,0xAC, +0x90,0x8D,0x63,0x78,0x19,0x6C,0xEB,0xE7,0x72,0x35,0x09,0xA8,0xD9,0xD3,0x6A,0x90, +0xAE,0xA7,0x7A,0xD7,0xCC,0x58,0x5F,0xD2,0x12,0xC8,0xE0,0x80,0x54,0x3D,0x35,0x25, +0x3A,0x46,0x83,0x67,0xA1,0xA3,0x87,0x52,0x85,0xA4,0x8E,0xC4,0x16,0x5C,0x6E,0x83, +0x43,0xDE,0x80,0x50,0x4A,0x02,0x05,0x10,0x89,0x02,0xC4,0xB4,0xF1,0xC7,0x98,0x64, +0x41,0xBB,0xAD,0xAF,0xA9,0x1E,0x55,0xFD,0xBD,0x49,0xA4,0xCF,0xDE,0x34,0x28,0x90, +0xC5,0x97,0x1D,0xEF,0xB8,0x77,0x92,0x50,0x35,0xA2,0x93,0x8C,0x9A,0x83,0x8C,0xC5, +0xBF,0x83,0x59,0x2A,0x2F,0x0B,0x64,0x05,0xD6,0x9D,0x22,0xAC,0x35,0x1B,0xA7,0xC5, +0xAE,0x2D,0xB3,0xEF,0x59,0x53,0xB9,0x9F,0xB8,0x58,0x3C,0xE2,0x7C,0x3D,0x56,0xAB, +0x0C,0xC4,0xE7,0x47,0xB3,0x3A,0xCF,0x16,0x71,0xD8,0x38,0x9D,0x47,0x1F,0x0B,0x21, +0x5F,0xC6,0x3F,0x01,0x23,0xF7,0x92,0xF7,0x6E,0x99,0x6F,0xE2,0xED,0xCD,0xD0,0x74, +0x82,0x93,0x1D,0x5A,0x7F,0x63,0x3C,0x79,0xF5,0x90,0x33,0x0C,0x29,0xD1,0x19,0x85, +0x8B,0x05,0xF2,0xCF,0x60,0x40,0xF4,0x08,0xBB,0x7C,0x6D,0x28,0x0A,0xAE,0x38,0xC0, +0xED,0x45,0xC1,0x05,0xAB,0xFA,0x80,0x76,0x7D,0xCE,0x57,0xE0,0x8C,0x2A,0xB7,0xD9, +0x3A,0xEF,0x42,0xB3,0x63,0xDE,0x4E,0x8C,0xD9,0xE0,0x02,0x8B,0x87,0x5E,0x4B,0xC6, +0xEF,0xA5,0x8B,0x2B,0x18,0xAA,0x21,0x76,0xF0,0xC7,0x32,0x7C,0xFB,0x3F,0xF8,0x45, +0x22,0xF9,0x7B,0xCB,0x90,0x99,0x1C,0x72,0xBD,0x46,0x3B,0x4E,0x14,0x68,0x24,0x23, +0x58,0x11,0x4A,0x98,0x08,0x88,0xB7,0x63,0x29,0x1F,0x18,0x10,0x99,0x24,0x08,0xB5, +0xC2,0xF0,0x0D,0xC5,0xA3,0x53,0x27,0x19,0x76,0x4E,0xC9,0x97,0x78,0xA5,0x40,0x34, +0xE1,0x4E,0x71,0xC4,0xBF,0x8F,0x21,0x31,0x9B,0xA8,0x41,0x0F,0x3C,0xD8,0x83,0x73, +0x4F,0x68,0xFC,0xA2,0xCB,0x1A,0x8F,0xCC,0xA4,0xD8,0x9F,0x5A,0x9E,0xA8,0xFC,0xDE, +0xD0,0x39,0xCD,0x33,0x40,0xC9,0x29,0xB2,0x00,0x41,0xCA,0x4D,0xF5,0x95,0x28,0x43, +0x28,0x46,0x7F,0x76,0x2A,0xB7,0x52,0xE2,0x0C,0x81,0x24,0xB3,0x68,0x36,0x03,0xD1, +0xE1,0x15,0xB5,0xF7,0x87,0xD9,0xB1,0x0C,0x93,0x3B,0x61,0x24,0x7F,0xCD,0x78,0xB7, +0x2D,0x13,0xCD,0x1C,0xDC,0xB4,0xDB,0xAF,0xF5,0x05,0xB9,0xF0,0x73,0xDC,0x3A,0xA6, +0xF6,0x2C,0x55,0x2C,0xF6,0xF3,0x7B,0x0F,0x47,0xCD,0xE7,0x1F,0xD0,0xB1,0xD1,0x72, +0xDF,0x03,0x94,0xF2,0xB6,0x7C,0xF7,0x2E,0xB2,0x95,0x30,0x04,0x4E,0x0B,0x38,0x85, +0x3F,0x22,0x68,0x03,0x98,0xEA,0x25,0x9A,0xBA,0xE0,0x1D,0xE8,0x23,0xD6,0xE3,0x5A, +0x11,0x2C,0xDB,0xD7,0x3B,0x3B,0x0C,0x88,0x68,0xA1,0x87,0x74,0x3B,0xD4,0xC9,0x51, +0xC9,0x7D,0x48,0x91,0x19,0x04,0x77,0x09,0xB1,0x1A,0x32,0x14,0x47,0x56,0xEA,0xC2, +0x12,0xB3,0xF3,0xF9,0x86,0x56,0x48,0xB1,0xFA,0xD7,0x14,0x0D,0xF1,0xAF,0xC8,0x51, +0xE9,0x9E,0xCB,0xE3,0x7D,0x15,0x07,0x9E,0x0B,0xEF,0xCA,0x95,0x75,0x86,0x28,0x6A, +0x88,0x97,0xDD,0x88,0xD1,0xD0,0x50,0x06,0x67,0xBE,0x0E,0x20,0x9D,0xAB,0xBE,0xA6, +0xD4,0xDA,0xA9,0xC7,0x86,0x09,0xFE,0x56,0x2E,0x64,0x11,0x23,0x83,0x01,0xF8,0x95, +0x92,0xF4,0x2F,0x90,0x41,0x75,0x1F,0x6F,0x93,0xB5,0xDD,0x57,0xFA,0x74,0x3D,0xE0, +0xFD,0x43,0xA5,0xBD,0xED,0x6E,0xE4,0x9C,0x66,0xAB,0x2B,0xB7,0xFF,0x13,0xDC,0x25, +0x5D,0x2E,0x00,0xD7,0x75,0x4E,0xFB,0x41,0x4D,0xFB,0xE3,0xBD,0xBE,0x47,0x08,0xE6, +0xE8,0x4B,0xAB,0x08,0x74,0xFA,0x0C,0x36,0x11,0xE0,0xB1,0x04,0x65,0x41,0xBE,0x5B, +0x6C,0xDF,0xA3,0x89,0xF6,0x8A,0xAC,0xBB,0x9B,0xE5,0x63,0x74,0x32,0x7B,0xC0,0xBA, +0xF1,0x0C,0xE2,0x70,0x9B,0x9B,0x40,0xD7,0x72,0x9B,0xA6,0x24,0x21,0xCB,0x20,0x03, +0xF4,0x6A,0x5C,0xAC,0x6D,0xF7,0xA3,0xE5,0xD4,0xCD,0xB9,0x1E,0x04,0xDC,0x3D,0x99, +0xBF,0x57,0x4F,0x82,0x3C,0xC5,0x74,0x2F,0xA3,0x5B,0xD5,0x09,0xB7,0x4B,0x91,0x05, +0xF5,0x78,0x2B,0x20,0x43,0x7C,0x30,0xF2,0x68,0xEA,0xE6,0x1C,0x2C,0x85,0xB6,0xD8, +0x4C,0x37,0x09,0xA7,0xFB,0xA1,0x49,0x36,0x76,0x55,0xD4,0x9A,0x7E,0x1D,0x1A,0xD9, +0xD8,0x5C,0x14,0x49,0x72,0x44,0x3E,0x52,0x0B,0x43,0x67,0xDC,0x2A,0xED,0x56,0x8F, +0x29,0x5E,0x79,0xB6,0x38,0xF9,0x65,0x1F,0x32,0x35,0x18,0x09,0x6D,0x5E,0x9E,0x09, +0x4B,0x6A,0x8A,0x35,0x06,0xC3,0xA6,0xE6,0xF4,0xEA,0x39,0x16,0x26,0x26,0x5A,0xB6, +0xB5,0x57,0xEE,0xE1,0xBA,0x54,0x6F,0x5F,0x92,0xFE,0xB9,0x38,0xA0,0xE2,0x86,0xA5, +0xE8,0x24,0x6C,0x4E,0xC0,0x4A,0x37,0x5D,0xAF,0x84,0x93,0x93,0xCB,0x4E,0x9E,0x44, +0xAD,0x6F,0xED,0xFA,0x47,0x9A,0xDC,0xDD,0x7A,0x72,0x57,0x9B,0xC8,0xCC,0x4A,0xB4, +0xB3,0xD0,0x59,0x65,0x02,0x59,0x6E,0xFA,0x97,0x04,0xEE,0x18,0x2B,0xE6,0xB2,0xC3, +0x39,0xA3,0xE9,0x34,0x61,0x1D,0xBD,0x29,0x4B,0x7D,0x16,0xC7,0x4C,0x6A,0x2A,0xD8, +0xDC,0xE8,0x7E,0xD4,0x9E,0xF9,0x1D,0x5D,0xF0,0x7D,0x76,0x2F,0xBF,0xBA,0x9B,0xCC, +0x67,0xDC,0xEA,0x17,0xE6,0xB6,0x0F,0x12,0x88,0x6A,0xF3,0x15,0x61,0x25,0x3E,0x04, +0x3B,0x66,0x2D,0x96,0x12,0xF7,0x9B,0x5E,0xB4,0x11,0x14,0x4C,0x67,0x4A,0xA8,0xBF, +0x5B,0xB4,0x77,0x39,0xBA,0x13,0x73,0x3D,0x5C,0xFB,0x6A,0x12,0x20,0x84,0x12,0x6A, +0xC3,0x11,0x7D,0x27,0x59,0xBB,0xE7,0xBC,0x3E,0x81,0x34,0x21,0xE5,0x60,0xE6,0xE3, +0xA0,0x10,0x04,0xF4,0x14,0x7E,0x70,0x76,0x1F,0xA1,0x85,0x9F,0x4C,0x47,0xFD,0x96, +0x76,0x6B,0xD1,0x71,0x4F,0xD9,0xC1,0x94,0xCF,0x08,0x3A,0x5A,0xE9,0xC3,0x8D,0x80, +0x83,0xD1,0x11,0x9B,0xB8,0xB4,0x1E,0x35,0x4B,0x4D,0x23,0x91,0xFE,0xAD,0x0F,0xD7, +0xEF,0x7E,0x62,0x6F,0x33,0x09,0xF0,0xB7,0xAA,0x5D,0xE6,0x89,0x1F,0xD5,0x68,0x3A, +0x4E,0x3E,0x18,0xDF,0xBF,0x70,0x2F,0xD6,0x87,0x1B,0xAE,0x44,0x09,0x21,0x9A,0x7B, +0xDF,0x7E,0xC8,0x27,0x47,0x4D,0x5D,0x25,0xE3,0x58,0xCA,0x2C,0x94,0xD4,0xEE,0x77, +0x97,0x0C,0x17,0x82,0x2F,0x68,0x4A,0x34,0x1B,0x8B,0xB6,0xCA,0x2B,0x20,0xDA,0xBA, +0xD8,0xAA,0xA6,0x5F,0x28,0x30,0x9D,0x01,0xCA,0x8D,0x81,0xFD,0xDB,0xE4,0x52,0x89, +0xAF,0x7C,0x4A,0xF4,0xE2,0x86,0x78,0x53,0xBD,0x9E,0xB7,0x48,0x43,0xB8,0x0A,0xBC, +0xDA,0x00,0x6B,0x10,0xFC,0x07,0x7A,0x4D,0xA5,0xD8,0xFD,0x59,0xD7,0xE8,0x3A,0xEF, +0x47,0x19,0xEC,0x08,0xDD,0x38,0xE1,0x27,0x18,0x10,0xCF,0x80,0xA8,0xE3,0x69,0x41, +0x06,0xFA,0x9D,0xD6,0x60,0x25,0x49,0x9D,0x0A,0xB6,0x1D,0xFA,0x50,0xD5,0x3D,0xD9, +0x75,0x15,0x91,0xFD,0xAA,0xFA,0xEF,0x81,0x0C,0xE1,0xE1,0x23,0x1D,0xD0,0xAD,0xB3, +0x8B,0xCC,0x2E,0x49,0x6B,0x47,0x3D,0x89,0x7F,0xD1,0xA8,0xE1,0xE9,0xAC,0x98,0x07, +0x2E,0x65,0xFB,0xC5,0x4F,0xEA,0x67,0x36,0x94,0xD2,0xAD,0x58,0x73,0x12,0x83,0xA2, +0x85,0xFD,0xD8,0x5D,0x0F,0xCE,0xA8,0xB4,0xCF,0x40,0xF5,0x4A,0xC7,0xDA,0x18,0x60, +0xFE,0x85,0x54,0x67,0x9D,0xAF,0x9D,0xE7,0xBD,0x09,0x09,0xBB,0x46,0xB5,0xA2,0xE9, +0x3B,0x2B,0xB9,0xFC,0x48,0xDC,0x34,0x5E,0x27,0xAF,0x38,0x6E,0x93,0xC3,0x91,0xF5, +0x55,0xCA,0x80,0x43,0x0B,0xF8,0x45,0x95,0xA0,0x93,0xF5,0x14,0x9F,0xE0,0xB2,0x96, +0xA8,0x3B,0xE1,0xE9,0x61,0x55,0x50,0x57,0x21,0x0B,0x98,0x65,0x10,0x52,0x5F,0x3F, +0x58,0x1C,0xB2,0xE2,0xD6,0x17,0x5E,0xB6,0x02,0xF8,0x4C,0xE4,0x64,0x69,0xB3,0x8D, +0x91,0xC2,0x9D,0x40,0x9F,0x10,0xF7,0x8E,0x9B,0x24,0x7B,0xB5,0x9B,0xF1,0x22,0x73, +0x1F,0x4A,0xAD,0x7D,0xEB,0xE2,0x0E,0xAF,0xAF,0xA1,0xEE,0x93,0xE1,0xC6,0xEE,0xCA, +0x13,0xEC,0x2B,0xF7,0xB8,0xA5,0xFB,0xE8,0xD0,0xC8,0x28,0xE9,0x37,0x2E,0xE4,0xF7, +0x83,0x17,0xDF,0x1A,0x36,0xF1,0x10,0x90,0x5D,0x16,0x7C,0x5A,0x1A,0x29,0xD0,0xEF, +0x18,0x9F,0x8B,0x9D,0xB2,0x93,0xBF,0x66,0x8C,0x0E,0xB6,0x45,0x02,0x96,0x5E,0xB4, +0x9B,0x5E,0xBB,0xA2,0x5C,0x99,0xCA,0x40,0xA4,0x4C,0x6F,0x7A,0x04,0x13,0x95,0x4A, +0x43,0x82,0x1B,0xFB,0x1F,0xB3,0xCC,0x85,0x14,0x41,0xB6,0xEE,0x31,0x33,0x9E,0x6C, +0x24,0xF6,0x34,0xD5,0x8C,0xC1,0xFC,0x90,0x90,0xE8,0x81,0xD0,0x9D,0xBF,0x07,0x74, +0xD1,0xA6,0xDC,0xF7,0x4C,0x46,0x2E,0x84,0x62,0x8B,0x56,0xD2,0x5B,0x31,0xBF,0x1B, +0x7A,0x8F,0x4E,0x7A,0x0E,0x03,0x95,0x14,0xC3,0xA1,0x88,0x14,0x05,0xEC,0x2A,0xFE, +0x1A,0x77,0x55,0x16,0x99,0xE8,0x35,0x06,0x51,0x17,0x81,0x47,0x50,0x92,0x27,0xEC, +0x0E,0xAC,0xC3,0xA2,0x92,0x9D,0x30,0xE0,0x57,0xD9,0x09,0xBD,0xD8,0xF8,0x01,0x89, +0xA8,0x71,0xFD,0x6C,0x7D,0x55,0xE3,0xE2,0xB2,0xC5,0x11,0xC6,0x5F,0xCE,0xBB,0xD9, +0x62,0x44,0xB2,0x92,0x68,0x96,0xB6,0x40,0x29,0xFF,0xFA,0xFE,0x29,0x42,0xA0,0xD3, +0x28,0xB4,0xD8,0x45,0xFD,0xF3,0x2B,0xFF,0x13,0x07,0xCA,0x7B,0x0C,0x29,0x98,0x7F, +0x6F,0x38,0x7B,0xAF,0xEF,0xF3,0x35,0x37,0xBD,0xAC,0xEE,0xF9,0xAB,0x27,0x5B,0x9E, +0x28,0x56,0x80,0xAE,0x7E,0x05,0x9F,0xAF,0x94,0xE7,0xDA,0xFF,0x5F,0x81,0xC5,0xC4, +0xE7,0x22,0xCC,0x88,0x33,0x99,0x11,0xD0,0x3B,0xBA,0x97,0x25,0x31,0xE9,0x03,0x57, +0x79,0x71,0xB7,0x2E,0x69,0xA4,0x74,0x2E,0x24,0x08,0xC9,0x8C,0xFC,0xA9,0x81,0xFB, +0xF9,0x16,0x8F,0xF1,0xCB,0xF9,0xEC,0xAB,0x10,0x57,0xFF,0x6C,0x8B,0x8F,0x4D,0x65, +0xFD,0xD4,0xAD,0xA5,0xF9,0xB7,0x43,0x1C,0x3D,0x74,0xE4,0x43,0xA1,0x6C,0xD3,0xCC, +0xCF,0xB0,0xE5,0xB7,0x7F,0x2A,0x97,0x11,0x74,0xB3,0x35,0xE0,0xFE,0xC1,0x89,0x6D, +0xC6,0xA6,0x13,0x60,0xF8,0x21,0x94,0x24,0x4B,0x15,0xBA,0x02,0x5C,0xF7,0x7E,0x69, +0xBA,0x7D,0x78,0x5D,0x62,0xA1,0xF5,0x04,0xD4,0xD7,0x6B,0x60,0x47,0xBF,0x60,0x57, +0x5B,0xC0,0x9E,0xAC,0xFD,0x27,0x25,0x02,0x79,0x77,0x35,0xB8,0x8F,0x12,0x31,0x2F, +0x5B,0x47,0x99,0x60,0xDA,0xA1,0xB8,0x82,0xF7,0xD4,0x5D,0xEA,0x75,0x92,0x6C,0x40, +0x33,0x9B,0x83,0xBC,0x3B,0x8B,0xBA,0xC6,0xB8,0xED,0xC3,0xA6,0x7D,0xE3,0x36,0x2F, +0xB8,0xBA,0x18,0x0D,0x19,0xB3,0x67,0x12,0x1B,0xFB,0xD1,0x69,0xAD,0x61,0x96,0xDA, +0x67,0x13,0x91,0x71,0x90,0x5D,0x01,0x43,0xB0,0x55,0x33,0x23,0x70,0xE8,0x14,0x85, +0x41,0xC7,0x7C,0x7D,0x58,0x59,0x32,0x6B,0xBE,0xED,0x61,0x57,0x09,0x0F,0x68,0x56, +0x64,0xCA,0x42,0x46,0x2C,0xFB,0xDE,0xA0,0x87,0xB6,0x28,0x79,0x86,0x3E,0x53,0xD1, +0x6E,0x45,0x37,0x40,0x3C,0x29,0xEB,0x08,0xAC,0x86,0x68,0x0A,0x81,0x0E,0x6E,0x10, +0xD4,0x2B,0xC0,0xD4,0x6C,0xD0,0xC9,0x88,0x69,0xC5,0x77,0x14,0x64,0xB6,0xBE,0xF2, +0x36,0x46,0x3C,0x40,0x5E,0x8D,0x92,0x2F,0x60,0x13,0x7E,0x6D,0xCB,0x81,0x76,0xB2, +0xB4,0xA2,0x76,0x7B,0xD2,0xCA,0x89,0x77,0xBB,0xB4,0xED,0xE3,0x51,0xE2,0x73,0x4D, +0x8E,0x1D,0x5F,0x1B,0x96,0x43,0x7F,0x1D,0xD1,0xBC,0x1F,0xC0,0x3B,0x3E,0x30,0x69, +0xCD,0xBE,0xE1,0xF6,0xAF,0x75,0xCE,0x37,0x28,0xB5,0x99,0x5A,0xA8,0x2B,0xF3,0xFF, +0xB0,0x23,0x63,0xF0,0xB0,0xE0,0x78,0x44,0x4B,0x7E,0x91,0xD8,0xF4,0xEA,0xC3,0x02, +0xE1,0x67,0x37,0xCD,0x7C,0xC4,0x45,0x95,0xD8,0x99,0x89,0x3A,0xEB,0x70,0x00,0xA0, +0x3D,0x84,0x70,0xF7,0x92,0xBE,0x4C,0xFA,0x28,0xC7,0xDE,0x16,0xD3,0xCC,0x42,0xEE, +0x98,0xC3,0xDC,0xB1,0x2A,0x62,0xD7,0x02,0x59,0xC8,0x09,0x76,0x1E,0xA5,0x4C,0x08, +0xB1,0xAA,0xAA,0xD1,0x1F,0x29,0x2F,0x4C,0x34,0x76,0x61,0x21,0xC1,0xC6,0x0D,0xE7, +0xC2,0xFD,0x89,0x64,0xB8,0x3D,0xD6,0x56,0x62,0x42,0xDA,0x72,0xEA,0xFA,0x8B,0x5B, +0x04,0xEF,0x02,0xCE,0x21,0xD8,0xD6,0x86,0x4E,0xB5,0x13,0xA9,0xDE,0x52,0x99,0x45, +0x24,0x1B,0x83,0x14,0x1C,0xD9,0x66,0x7D,0xC3,0xF0,0xF0,0xC6,0x6C,0x20,0xB3,0x8C, +0xF3,0xD6,0x62,0x31,0xB7,0xFD,0x45,0x27,0x1E,0x7B,0x81,0xAC,0xD7,0x81,0x98,0x29, +0xB0,0xD3,0x37,0x5A,0xF7,0x16,0x44,0x9D,0xF5,0x19,0x69,0xD0,0x46,0xFC,0x0F,0x96, +0x0B,0xFD,0x00,0x9D,0x7D,0xCF,0x84,0x3A,0x36,0xF7,0x51,0xFF,0xF9,0xC1,0x73,0xE0, +0x57,0x25,0x91,0x87,0x57,0x2C,0x5B,0x54,0x0B,0xF3,0x50,0x44,0x5A,0x24,0xEE,0xFA, +0x77,0x5D,0x22,0x37,0x02,0x99,0x3E,0xD5,0x46,0xA7,0xDB,0x0F,0x46,0x80,0xBD,0x8B, +0x5F,0x92,0x33,0x74,0xA6,0x00,0x19,0x99,0x34,0xFE,0x3F,0xDB,0xEC,0x68,0x6A,0x3E, +0xB8,0xF6,0x42,0x81,0x5E,0xF1,0xA5,0x56,0x34,0x99,0xEA,0xF0,0x55,0x97,0x4C,0xB5, +0x92,0xCE,0x7E,0x41,0x6D,0x47,0x1B,0x4D,0xC8,0xF9,0x3B,0x65,0xAD,0x03,0x74,0x35, +0xDB,0x88,0x4B,0xD4,0x8D,0x8F,0x83,0x3A,0xEE,0x4A,0x0A,0xA8,0x21,0x32,0x3F,0xD5, +0x36,0xAC,0x3E,0xED,0xC2,0x9E,0x0F,0xB4,0xC3,0x96,0x88,0x43,0x19,0xC3,0xF4,0x22, +0x9E,0xC5,0x1A,0x1E,0xF2,0x9C,0xC0,0x1C,0xDE,0xAE,0x7E,0x0E,0x3C,0x31,0x4F,0x77, +0x0B,0x42,0x39,0x9B,0x03,0x44,0x79,0x06,0x1C,0xCE,0x7B,0x5B,0x47,0xE5,0x33,0x4F, +0xFA,0xE5,0x87,0xAD,0xEB,0xF1,0x1C,0x87,0x39,0x83,0xF4,0xE1,0x44,0xF5,0xE4,0x83, +0x99,0x4D,0x1C,0x7A,0x62,0x5E,0x48,0xF7,0x4D,0x7A,0xC4,0x21,0xD2,0xF4,0x54,0x63, +0x19,0xC6,0x28,0x94,0x93,0x62,0xCF,0xFA,0x68,0xC1,0x73,0xA8,0xD8,0x06,0x2E,0x29, +0xD1,0xCF,0x70,0x85,0xAA,0x95,0x3E,0x86,0x95,0x90,0x79,0x4F,0x2E,0x4A,0xAA,0x98, +0xEE,0x6E,0x97,0x7D,0xEB,0xE8,0x15,0x07,0x1A,0x67,0xF7,0x2F,0x5D,0xD4,0x5F,0xC8, +0xC8,0x41,0x20,0xD8,0x67,0x7F,0xD3,0x58,0xD8,0xCB,0xDC,0xA9,0x3D,0x95,0x47,0xBF, +0x6D,0xD0,0xFB,0xF3,0xF0,0x62,0x1A,0xB7,0xBD,0xFA,0x8E,0x68,0x88,0x34,0xBD,0x1F, +0x3C,0x9F,0xF6,0xE5,0xA0,0xC5,0x61,0xAE,0x5B,0x0E,0xDC,0xCA,0x85,0x03,0x38,0x0B, +0xA8,0x82,0x71,0x4C,0x72,0x3B,0x5B,0x53,0x67,0x52,0x06,0x97,0xEB,0x76,0x81,0x8F, +0x56,0x1E,0x62,0xCF,0x41,0x20,0x77,0x4D,0x5D,0x61,0xCD,0x8E,0x41,0xDB,0x51,0xC0, +0xC7,0x03,0xC2,0xE1,0x5E,0x82,0xE2,0x10,0xF7,0xB7,0xF9,0xC5,0x57,0xAC,0xC9,0x26, +0x74,0x0D,0xAE,0x4E,0x93,0xDC,0x23,0xC6,0x5C,0xF2,0x3B,0x24,0xCA,0x89,0xF6,0x30, +0xAA,0x4A,0x7C,0xCE,0xD9,0x47,0x1F,0xED,0x51,0xB3,0x13,0x3B,0x5E,0xA1,0xB5,0x96, +0x1A,0x7C,0x55,0x35,0x7F,0x18,0x0B,0x34,0x0C,0x96,0xF9,0x4A,0xA3,0x88,0x3B,0x9C, +0x7D,0x30,0x47,0x59,0xA6,0x44,0xA9,0x46,0xDC,0x02,0x06,0xEA,0x61,0x2A,0x9B,0x3B, +0xE6,0x2B,0x50,0xC6,0xE9,0xE3,0x0A,0x5B,0x60,0x6D,0xA9,0xA5,0xD9,0x31,0x7D,0x9D, +0xBF,0x23,0x11,0xD9,0x3F,0x88,0x4C,0xA5,0xDE,0x17,0x66,0x1B,0x0C,0xB2,0x14,0x8F, +0xD8,0x7D,0x12,0x8A,0x43,0x9E,0x43,0xBB,0x30,0x02,0x3E,0x46,0x51,0x20,0x56,0xFE, +0x5E,0x46,0x35,0x45,0xA3,0xC2,0x19,0x65,0xB1,0x36,0xD1,0x57,0xF7,0xE6,0x50,0x9D, +0xA9,0x74,0xE5,0x71,0x8D,0x4C,0x57,0xDA,0x23,0xB5,0x4D,0x81,0x5F,0x4B,0x13,0x42, +0xD9,0x5D,0x1B,0xEA,0xF9,0x73,0x36,0x51,0x69,0xEA,0xC2,0xC9,0x1F,0x28,0x8A,0xD3, +0xAA,0x2D,0x91,0xBA,0x6E,0xE7,0xFB,0x0A,0xD4,0xF9,0xD2,0x5F,0xD1,0xB4,0x47,0x8D, +0x56,0xF9,0x5C,0xD2,0xA6,0x6C,0x36,0x24,0xD1,0xF9,0x80,0xD9,0x31,0x29,0x86,0x6B, +0x02,0x04,0xAD,0x6B,0xAD,0x7B,0xFB,0x1A,0x23,0x38,0x4F,0x29,0xFF,0x60,0xBC,0xF3, +0xD7,0xE9,0x94,0x46,0x5A,0x03,0x52,0xAF,0x4F,0xC4,0x7A,0xEE,0x93,0x04,0x95,0x23, +0xB8,0xE3,0x87,0x12,0x77,0x67,0x0A,0x80,0x9C,0x84,0x88,0x61,0xD1,0xCE,0xA5,0x50, +0x88,0xF9,0xC9,0x5B,0x40,0x67,0x1A,0x05,0xCC,0x82,0x8B,0xAA,0x56,0xA3,0x19,0xF2, +0x79,0x77,0xF1,0x0C,0x51,0x20,0xD8,0xC8,0x47,0x77,0x49,0xB3,0xF4,0xE9,0x4F,0x0A, +0x09,0xDA,0x8B,0x26,0x86,0xA7,0x52,0xC7,0x21,0xAD,0x74,0x4D,0x2F,0x46,0x63,0xB6, +0x1D,0x7B,0xC6,0xD5,0x72,0xC6,0x50,0x24,0xF1,0xFA,0x95,0xFB,0x5D,0xDB,0xE0,0x51, +0x75,0x8C,0xAD,0x7F,0xD7,0xB6,0x5B,0x97,0x6E,0xCE,0x49,0xED,0xCC,0x0C,0xBA,0x5E, +0x1A,0xE7,0x9A,0x1A,0xCC,0x50,0xFB,0x66,0x97,0x8F,0x14,0x53,0xA7,0x3D,0x36,0xA2, +0x37,0x2E,0x71,0x62,0x65,0x6E,0x92,0xF5,0x89,0xBB,0x56,0x6C,0xDC,0x9D,0x61,0xFC, +0xDD,0xE7,0x75,0x78,0xEB,0xF7,0x64,0x7A,0x9B,0x88,0x6C,0x7A,0x39,0x8D,0xA9,0xCE, +0x8F,0x82,0xA0,0x4B,0xB3,0xF9,0x51,0xFC,0x97,0xDD,0xF8,0x4F,0xD9,0x7E,0x38,0x28, +0xBA,0x73,0x96,0x0A,0x8D,0xA8,0xA7,0x2A,0x53,0x01,0xEC,0x0E,0x5A,0xBE,0x06,0x5D, +0x09,0xC8,0xB4,0x13,0x6D,0x25,0x64,0xCA,0xCC,0xDB,0xD3,0xEC,0x99,0x04,0x4A,0x1E, +0x6A,0xB8,0xAF,0x7D,0x56,0x3B,0xD3,0x8E,0x21,0x9D,0xF2,0x5A,0x01,0xA6,0x5C,0x1B, +0xB6,0xB4,0x62,0xA3,0x9C,0xC0,0x01,0xEF,0x8C,0xAA,0x61,0xFC,0xFF,0xC9,0x73,0xB2, +0xCC,0x32,0xBE,0xB0,0x20,0xA7,0xA2,0xB7,0x9A,0x1D,0xA7,0xE7,0xB5,0x02,0x83,0xA0, +0x61,0x28,0x49,0xBD,0x4A,0x74,0x33,0xB8,0x0B,0x97,0xC6,0xDF,0x74,0x61,0x28,0x50, +0x1A,0x18,0x4F,0xE8,0x73,0xCD,0x2F,0xB2,0xF0,0x29,0x56,0x2B,0x31,0xCB,0xA2,0x26, +0x90,0x3D,0x14,0xC1,0xA2,0xC4,0x7D,0x9F,0x2B,0x19,0x29,0xBC,0x91,0xBF,0x57,0x7E, +0x23,0x85,0x60,0xE3,0x38,0x27,0x7C,0x8B,0xF0,0xF1,0xB5,0x3A,0xF6,0x49,0x59,0x12, +0x7F,0x7D,0x17,0xF8,0x6C,0xD0,0x16,0xF4,0xB0,0x42,0xE5,0xB8,0xB0,0xD8,0x2C,0xBA, +0xC2,0x50,0xF2,0xE0,0x3A,0xAF,0x7F,0xAD,0x61,0xE1,0x36,0x35,0x85,0xEF,0x33,0x09, +0x2B,0x09,0xE9,0x09,0x4E,0x23,0xF9,0x32,0x81,0x73,0x59,0x31,0x75,0xF3,0x85,0xEA, +0xD8,0xFB,0xAA,0x96,0x41,0x6C,0x05,0x32,0x4A,0xDD,0x0C,0x7C,0x0A,0x3F,0x56,0x62, +0xAC,0xA5,0xFC,0x7C,0x45,0x80,0x4B,0xFE,0x0F,0xD8,0x61,0x8D,0xF0,0x10,0xC4,0x38, +0x11,0x64,0xC3,0x8E,0xA4,0xE2,0xBF,0x8F,0x0C,0x3E,0x7A,0x85,0x0F,0x9B,0x6F,0xEF, +0xA1,0xE6,0x0C,0x58,0xE3,0xD7,0x2A,0xA2,0xBF,0xA7,0x31,0xED,0x4C,0x4D,0x6F,0xE2, +0xFF,0x10,0x62,0x98,0x2E,0x16,0x14,0xCE,0xEF,0x2C,0xFE,0x41,0xCD,0x3A,0x06,0x87, +0xCF,0xC5,0x35,0xAC,0xC4,0x43,0xBA,0x1A,0x24,0x6A,0x16,0x5D,0x2B,0xF6,0x4F,0xDB, +0x4F,0xF7,0x67,0x36,0x99,0xDD,0x3B,0x25,0x54,0xE0,0x6B,0x93,0xF8,0x68,0x30,0xA2, +0x53,0xBB,0x01,0xB8,0x46,0x22,0xEC,0x52,0x55,0x9C,0x40,0xD7,0x35,0x62,0x99,0xA6, +0xAD,0x48,0xDC,0xFC,0x98,0x06,0xE4,0xD7,0x44,0x36,0x19,0x2A,0x69,0xCA,0x33,0x90, +0xA9,0x71,0x01,0x85,0x96,0x04,0xA4,0x77,0x3F,0xF0,0xDF,0x04,0x72,0x4A,0x5D,0xCA, +0x10,0x01,0xC3,0x6C,0x8E,0x2D,0x00,0x63,0x58,0x66,0xDC,0x56,0xA6,0xCE,0xEF,0x2B, +0x71,0x6C,0xC4,0xC5,0x60,0xD1,0xDB,0xE1,0xAB,0x49,0x32,0x27,0xAF,0x2B,0x92,0x44, +0xF0,0xF3,0x21,0xCA,0x70,0xCD,0xF1,0xD5,0x48,0x79,0x02,0x1A,0xAE,0x35,0x09,0x49, +0x2A,0x97,0xF8,0xAE,0xD7,0xBC,0xB3,0x9F,0x09,0x88,0x46,0x93,0x61,0xB5,0x02,0xEC, +0x6A,0x12,0x2C,0x25,0xBA,0x75,0xED,0x55,0x41,0x71,0xC0,0xF6,0x20,0x71,0x2E,0x93, +0x2A,0xD7,0x9A,0x0D,0x07,0x38,0xD5,0xD1,0xCE,0xA6,0x7A,0x3E,0x4B,0xD4,0x2E,0xA7, +0x63,0x91,0xC2,0x7D,0x6C,0x28,0x7C,0xE4,0x2F,0xF0,0x52,0x9E,0xAF,0xF9,0xFB,0xE6, +0xC4,0xFF,0xEC,0x59,0xC9,0x94,0xCC,0x2C,0xFC,0x6D,0xE9,0xFD,0x74,0xB5,0x21,0xDA, +0xD6,0x7E,0x7A,0x54,0x0D,0x3A,0x94,0x03,0x94,0x4E,0x9E,0x59,0x20,0xA9,0x3D,0x91, +0x4E,0xFA,0xDA,0x53,0x97,0x23,0x43,0xD6,0x76,0xA1,0xA1,0x40,0x8A,0xDE,0x8B,0x21, +0xC5,0x19,0x01,0x3E,0xA9,0x0D,0x6D,0x29,0xC7,0x43,0x9D,0xF5,0xA1,0xC6,0x37,0x0C, +0xE9,0x16,0x05,0xBC,0x41,0xE6,0x9D,0xD9,0x82,0xCC,0x08,0x33,0xC6,0x53,0x63,0xEB, +0x1F,0x3E,0x64,0x25,0xBE,0xB3,0x05,0xA5,0x48,0x79,0xF6,0x36,0x68,0x16,0x57,0x54, +0x20,0xA6,0xC2,0x20,0xE3,0xDD,0x5B,0xF0,0xC4,0x9B,0x9F,0xB2,0x91,0xBD,0x54,0x18, +0x5A,0xA4,0xE5,0xB7,0x99,0x43,0xB7,0xEA,0x19,0x95,0x93,0x32,0x0A,0x4F,0xE1,0x45, +0xDC,0x68,0xAE,0x53,0x2B,0x6E,0xF2,0x3C,0x50,0xB4,0x2B,0x32,0x37,0xE3,0x62,0x3A, +0x68,0xAB,0xFE,0xEB,0x23,0xA9,0xBD,0x69,0x5D,0x3B,0xD8,0x3D,0x82,0x68,0xC8,0x00, +0x0B,0x8E,0xC2,0x88,0x07,0xA5,0xFA,0x57,0x5A,0xA4,0xBE,0x01,0x0B,0x5C,0x66,0x03, +0x5D,0xDB,0xC6,0x52,0x4A,0xD3,0x82,0x8F,0x44,0x41,0xAD,0x7E,0xFF,0x53,0x75,0xC1, +0xF9,0x60,0xD3,0x58,0xB1,0x1E,0x88,0x86,0xD1,0x3D,0x07,0xCA,0xF8,0x8D,0x82,0x5E, +0x82,0x56,0x9E,0xB8,0xE1,0x1D,0xE8,0x1E,0xE7,0xA0,0x40,0x8F,0x80,0x2D,0xCC,0xBB, +0xEF,0x30,0xC8,0x5A,0x98,0x9A,0xA6,0xCC,0xDA,0x82,0xAC,0x56,0xD7,0xD2,0x9C,0x9E, +0xDC,0xFB,0xBE,0x1D,0xE8,0xA4,0xA4,0xFC,0x8C,0x67,0x7C,0xF9,0xEA,0x3C,0xAE,0x64, +0xD8,0x21,0xCC,0x27,0xB8,0x36,0x81,0x68,0x64,0xBC,0xD0,0x64,0x09,0x51,0xB9,0x3D, +0xA9,0x9B,0xD3,0x84,0xF2,0x09,0x44,0x7F,0xE6,0x4D,0xE6,0x7F,0x16,0x8E,0xC8,0xDF, +0x5A,0xF5,0x09,0xF6,0x94,0x31,0x4A,0xB9,0xA5,0x90,0xED,0xDE,0xD1,0x7F,0x67,0x8D, +0x1E,0x0D,0x89,0xB7,0x66,0x46,0x99,0xC0,0x3F,0xF5,0x7F,0xD2,0x8A,0x6A,0x43,0x1B, +0x7E,0x7D,0xAD,0x61,0x14,0x46,0x36,0x9A,0x13,0x1D,0x94,0xD6,0xAB,0x23,0x0E,0x35, +0x97,0x23,0xC8,0x8B,0x2C,0x54,0x74,0x7E,0x99,0x3E,0x86,0xC7,0x99,0x11,0x93,0x61, +0x5E,0x59,0x40,0xB5,0xF1,0xB3,0xA7,0xBE,0x64,0x1F,0x41,0xA4,0x93,0xF9,0xD3,0x97, +0x9C,0x16,0xFC,0x3B,0x1E,0x8D,0x1E,0x9C,0x48,0xB1,0xAB,0x39,0xA3,0x3E,0x3B,0xC4, +0x76,0x47,0x3C,0x8E,0x7D,0x6A,0x30,0x11,0x5A,0x6E,0x1D,0xC5,0xCA,0x45,0xC0,0xB6, +0x3E,0x02,0xC0,0x81,0xCC,0x7C,0x1C,0x21,0x75,0xD3,0x0A,0x54,0x7A,0xF8,0xDC,0xFB, +0xFA,0x79,0x63,0x2B,0x01,0x82,0x7A,0xB1,0x51,0x92,0x6E,0x66,0x94,0x1C,0x30,0xC2, +0x7F,0xAB,0x3A,0x56,0x84,0x42,0xFA,0xDC,0xFD,0x1F,0x34,0xB6,0x39,0xA5,0xF5,0xA7, +0x52,0xF4,0x8B,0xC5,0xBC,0x89,0xBD,0xBF,0xE4,0xD3,0x5E,0xD2,0xD4,0xCE,0x38,0x28, +0xB5,0x98,0x58,0xFC,0x61,0x7E,0xB6,0x26,0x27,0x43,0x6A,0x55,0xCC,0xD7,0x47,0x86, +0x3E,0x7E,0xD6,0x55,0xAE,0xE1,0x34,0xD1,0x87,0x06,0x7A,0xAA,0x02,0x1C,0xD1,0x70, +0x41,0x55,0xAD,0x34,0x35,0xF3,0x85,0xB4,0x1D,0x70,0xC5,0x1E,0xBF,0xEB,0x53,0x95, +0xF2,0x11,0x16,0x5A,0x6C,0x26,0xAC,0x2B,0x63,0xA1,0xEB,0xDF,0x36,0xAB,0x4E,0xCF, +0x03,0xC6,0xCB,0x6F,0xF5,0xDE,0xF6,0x66,0x90,0xE9,0x3F,0x36,0x75,0x1B,0xA4,0xB2, +0xFE,0x86,0x2C,0xFF,0x76,0xFA,0x9E,0xA7,0x4D,0xBA,0x41,0x31,0x13,0x02,0x17,0x3A, +0x19,0xA6,0x17,0x59,0x05,0x58,0xBF,0x64,0xD6,0xBF,0x69,0xF7,0xF7,0xA8,0x7B,0x45, +0x73,0x9E,0x89,0x95,0xC8,0x80,0x12,0x5B,0xC0,0xE8,0x8A,0xD9,0x4E,0xC0,0xC9,0xD5, +0x65,0x1E,0xF5,0xC0,0x5A,0xA1,0x71,0x65,0xAE,0x0C,0x66,0xF1,0xC6,0xFD,0x47,0x0C, +0x1D,0xEE,0xCA,0x3C,0xDA,0x3E,0xE7,0x07,0x6D,0x4C,0x79,0x29,0xDA,0x23,0x8E,0xA3, +0x8A,0x9C,0x7D,0x7F,0x4B,0xB8,0xBC,0x84,0x4D,0xFD,0x65,0x53,0xFC,0xC4,0x2A,0xD7, +0xB2,0x16,0x74,0x20,0xC1,0x36,0x72,0xC3,0x52,0x17,0x94,0x2A,0xD1,0x65,0x10,0x83, +0x40,0xB2,0x5A,0x46,0x2B,0xD2,0x80,0x53,0xA1,0x1E,0x29,0xC5,0xFE,0x89,0x1D,0x43, +0xA8,0xFD,0x2D,0x89,0x24,0xEF,0x48,0xF7,0x23,0xB5,0x92,0x65,0xDF,0xB7,0xA7,0x2B, +0xDB,0xEB,0x22,0xC0,0xAE,0x0D,0x0A,0xD2,0x08,0x4D,0x16,0xB8,0x7E,0x4B,0x33,0x9C, +0xAE,0x46,0xFD,0xE7,0xAC,0xF2,0x8A,0x1F,0x6D,0x56,0x06,0x41,0x9F,0x55,0x17,0xCC, +0x4F,0xF6,0x00,0xA0,0x2F,0x6D,0x9C,0x61,0x0D,0x8A,0xC3,0xD1,0xEF,0x61,0x24,0x79, +0x57,0x4C,0xF5,0xDC,0x88,0x64,0xDE,0xA5,0x26,0x11,0x78,0xE8,0x7B,0xE0,0xDC,0xC9, +0x94,0xEB,0x09,0x6F,0xD4,0x4F,0x06,0x9C,0x31,0xB1,0xE5,0xB0,0xD3,0xCC,0x19,0xCF, +0xBC,0x5A,0x19,0x8F,0x82,0x0A,0xCA,0x70,0x50,0xD7,0xA3,0x79,0x42,0xCF,0x7E,0x56, +0xC4,0x64,0xFE,0xF4,0xC8,0xFD,0xC2,0x18,0x2F,0x67,0xC1,0x9D,0xBE,0xF8,0x6B,0x6F, +0x74,0xCE,0xFA,0xDE,0xA0,0xB9,0x55,0x68,0x55,0x09,0x92,0xB0,0xBE,0x6E,0x35,0x37, +0xAD,0x4E,0xFA,0x79,0xC9,0xC4,0xA2,0x9A,0xF0,0x90,0xD2,0x12,0x6B,0x7B,0x02,0x20, +0xC3,0xFF,0x38,0x00,0x1F,0x75,0xE7,0x12,0x4A,0xE5,0xF0,0x81,0x56,0xF7,0xE8,0x98, +0x85,0x17,0xF2,0x34,0xA7,0x9C,0x31,0x46,0x41,0x36,0xCA,0xFB,0x86,0xDE,0xB3,0xB7, +0xFE,0x23,0xD2,0x1E,0x6C,0x79,0x65,0xF9,0x75,0x01,0xBE,0xBA,0x40,0xFB,0xF1,0x21, +0xE9,0x84,0x14,0xD6,0x19,0x02,0x99,0xBE,0xA9,0x11,0x89,0x72,0x17,0x24,0x2E,0xA7, +0xF5,0x4F,0x30,0x87,0x20,0x82,0x7C,0x3D,0x7C,0xEB,0x68,0x9C,0x92,0xCD,0xD1,0xB3, +0x59,0x7B,0x0E,0xE5,0xD9,0xE7,0xF7,0x8C,0x19,0x55,0x15,0xC3,0x7F,0xEB,0x0E,0x64, +0x14,0xD2,0xF9,0xA4,0x74,0x52,0x39,0x01,0x4E,0xF7,0x3B,0xB2,0xC8,0x7C,0xA3,0x91, +0xB0,0xF3,0x9A,0x22,0xDD,0x48,0xE7,0x5E,0x53,0xFD,0x3F,0x6E,0xB9,0xFD,0xB5,0xE9, +0xC4,0x6B,0xA7,0xC0,0x70,0xE4,0x83,0xDC,0x72,0xBF,0xA5,0x9F,0x07,0x9E,0xC8,0x87, +0x21,0x34,0x99,0x25,0x2E,0x1F,0x87,0x66,0xE7,0xF3,0xC4,0x9D,0xA2,0xB2,0x18,0x50, +0x1B,0xE8,0xB9,0x2C,0x00,0xAF,0xE5,0xD5,0xE5,0x86,0x28,0xF7,0x9D,0xE3,0x28,0x82, +0xD8,0x47,0xF6,0x2C,0x60,0x6F,0xFF,0x9C,0xF7,0x83,0x5D,0x28,0x56,0x23,0xC3,0x1E, +0x20,0xA5,0x0D,0x75,0x43,0xD3,0xB4,0xD6,0x30,0xCB,0x86,0x43,0x97,0x22,0x6A,0x6E, +0xCD,0x6E,0xF5,0x22,0xE4,0x13,0x37,0x79,0xE1,0x7D,0xA1,0x80,0x3F,0x83,0xB7,0x25, +0x5B,0xB7,0x58,0x01,0xBE,0xDF,0x25,0xAC,0x98,0x9A,0x7D,0x0E,0x32,0xA3,0x50,0xFF, +0x87,0x73,0x16,0xBA,0x89,0xA6,0xDA,0xC6,0x1A,0x42,0xCD,0xF7,0x8B,0x93,0xC6,0xE9, +0xD5,0xC6,0xAF,0xB4,0xB3,0x13,0x59,0xCF,0xA7,0x58,0xEB,0xA5,0xD0,0x6B,0xED,0xC2, +0x8C,0x10,0x5F,0x4A,0xD8,0x58,0xD2,0x57,0xD8,0x4D,0x60,0xA7,0xE8,0x81,0x24,0x3F, +0x2F,0xBF,0xE6,0x4E,0x66,0xB3,0xB9,0xC0,0xA7,0x27,0xC2,0xFE,0x2A,0x46,0xB7,0x5D, +0xDA,0xFD,0x1D,0xB5,0x5B,0x82,0x73,0x24,0xC5,0xDE,0x97,0x42,0xD8,0x56,0xD3,0xCA, +0x1D,0x05,0x30,0x0D,0x3D,0x44,0x54,0x59,0xFE,0x13,0x7F,0x76,0xEE,0xB2,0xD5,0xE0, +0x01,0x49,0x30,0x55,0x83,0xF2,0xD4,0x3B,0x68,0x97,0xFB,0x3C,0x76,0xEB,0x5C,0xBC, +0x1A,0xDC,0xC0,0xA2,0x10,0xA0,0xDE,0xE8,0x6B,0x9F,0x79,0x05,0xD9,0xA4,0x10,0x25, +0x68,0x66,0x76,0x2E,0x6E,0x08,0xD1,0xFC,0x4D,0xC4,0x26,0xA2,0x6D,0xB0,0x5E,0x2D, +0x34,0x6C,0xB4,0x14,0xA9,0x43,0x8A,0x17,0x7C,0x24,0x49,0x7B,0x3C,0xB5,0x93,0xA2, +0xAC,0x7C,0x69,0x3D,0xDB,0x11,0x6D,0x04,0x01,0x6D,0xC0,0xF5,0x72,0x70,0x1A,0xF2, +0x21,0x05,0x0D,0xC5,0x75,0x24,0x66,0xAC,0xF3,0xD2,0xEC,0x46,0x98,0x34,0x9B,0x11, +0xAB,0xB3,0xAA,0x85,0x0F,0xD6,0x33,0xC1,0xB4,0xB4,0xB0,0x9F,0x7F,0x31,0xDE,0x01, +0x28,0xC1,0x8D,0x63,0x24,0xF5,0x34,0x84,0xB0,0x7F,0x1B,0x85,0xB7,0xAA,0x76,0x3F, +0x46,0xCC,0x86,0x16,0x34,0xCD,0xC3,0xE7,0xBF,0xE1,0xE2,0xA5,0x20,0xA7,0x0D,0x7D, +0x60,0xC4,0x1A,0x10,0x6F,0x0E,0xD7,0xC8,0x7E,0x2F,0xBD,0xC5,0x3A,0xD4,0xBE,0xB8, +0x01,0xD0,0x43,0xAC,0xAB,0x6C,0x28,0xAE,0xF6,0x35,0xF6,0x3E,0x8D,0x11,0xB4,0xEB, +0x0B,0xD4,0x9A,0x12,0xA1,0xD7,0xCC,0x7F,0x68,0x0E,0x0E,0x83,0x02,0x14,0xA1,0x6B, +0x6F,0x1D,0x29,0x96,0x9E,0x69,0xBA,0xED,0xD0,0x2F,0xEA,0x05,0x14,0xDA,0xCB,0x7D, +0x6D,0x32,0xA9,0x16,0x00,0x98,0x2F,0x96,0xD7,0x10,0x80,0x90,0x10,0xAA,0xF5,0xF4, +0x2C,0x3A,0xB0,0x19,0xB9,0x50,0x16,0x83,0xB8,0xCF,0x95,0xA5,0xF5,0xA1,0x7F,0xBB, +0x2B,0x3F,0xBD,0x45,0x97,0xA1,0xEC,0xB7,0x1A,0x18,0x2C,0xBC,0xFA,0xFC,0x57,0x24, +0x47,0xD3,0xA8,0xAF,0x00,0x22,0x5A,0xE9,0xFE,0x4F,0xCB,0x54,0xA9,0xA1,0xF2,0xEA, +0xB1,0x20,0xB5,0x04,0x44,0x18,0xEA,0x7D,0xDA,0x41,0x53,0x37,0x93,0x2E,0x55,0x2E, +0x74,0x8B,0x45,0xE1,0xCC,0xC2,0x82,0x06,0xE2,0x7E,0x01,0x7E,0xCB,0xC5,0x22,0xAE, +0x5B,0x5A,0x00,0x92,0x95,0x7F,0xB9,0xE7,0x5C,0xB2,0x36,0x65,0x3C,0x88,0xFA,0xBF, +0x2C,0xD0,0x3C,0xA7,0xB5,0x8B,0x8A,0x7D,0xD5,0x07,0xBC,0x86,0x5E,0x85,0x36,0xB7, +0xF3,0xE3,0x93,0xE2,0x9D,0xF6,0x17,0x30,0xBA,0x32,0xDD,0xA3,0x90,0x63,0x61,0xDE, +0x49,0xDD,0xAB,0x4A,0x92,0x41,0x85,0xEC,0xA2,0x34,0x16,0x61,0x7E,0xD4,0x5F,0x55, +0x0E,0xB6,0x54,0xB0,0xB1,0x3B,0xDC,0x0B,0x07,0xE6,0x94,0x15,0xE2,0x22,0x60,0xF8, +0xCD,0x3E,0x11,0x9F,0xE3,0xFC,0x73,0x83,0x68,0x7C,0xC6,0x65,0xCF,0x75,0x38,0xEB, +0x5F,0x82,0xC3,0x99,0xAB,0x52,0x43,0x17,0x5F,0xBA,0x0F,0x6D,0x37,0xB3,0xA8,0x56, +0x56,0x1A,0x54,0x44,0xAD,0xFC,0x67,0xFF,0x69,0xE4,0x50,0x89,0xF0,0xA7,0x16,0xAF, +0x1E,0xBD,0x37,0x46,0xE4,0x9A,0x75,0x2E,0x69,0x0B,0xA6,0x52,0xE5,0x35,0xD7,0xC5, +0x9C,0x18,0x5E,0x6A,0x29,0x2D,0x72,0x34,0x02,0xE3,0x9F,0x8E,0x25,0xB8,0x1F,0xCE, +0x79,0x08,0x57,0x29,0xD7,0x44,0x73,0x7C,0x26,0x71,0xBC,0x72,0xAF,0x3D,0x1E,0xD0, +0x2C,0x1A,0x3A,0x02,0xE6,0x06,0x3B,0xCF,0x8A,0x52,0xF8,0x82,0x09,0x45,0x77,0xD2, +0x60,0xBB,0xF4,0x4A,0x53,0x2D,0xE8,0xA6,0xDC,0x39,0x61,0xE6,0x1B,0xE8,0x8D,0x65, +0xD8,0x91,0x47,0xF9,0xC5,0xF8,0xAA,0xCA,0x75,0xC5,0x1E,0xFA,0xC1,0x00,0xFC,0xFC, +0x26,0x6F,0x06,0x71,0x47,0x92,0x31,0xFA,0xF4,0x05,0x94,0x0E,0x8C,0x1A,0x68,0x48, +0x4D,0x75,0x9F,0xD2,0x7C,0x03,0x90,0x47,0x63,0x58,0xC8,0x80,0x89,0xBA,0x64,0xD2, +0x65,0x2B,0x19,0x93,0x5B,0x4C,0x3E,0xB2,0x62,0x69,0x94,0xE0,0xF0,0xB9,0x7D,0x60, +0x4B,0x6C,0x01,0x08,0x24,0x8F,0xD7,0xD6,0xF9,0x71,0xD9,0x0D,0xC7,0xB0,0x41,0x82, +0x56,0x95,0x94,0xE2,0xA2,0x0E,0xBB,0x53,0x7C,0xFF,0x0C,0x2E,0x76,0x24,0xF7,0x8B, +0x31,0x56,0xD3,0xCD,0xC9,0xB7,0xF3,0x60,0x47,0xE5,0xE7,0x11,0x30,0xFC,0x73,0x33, +0xDA,0x76,0xAC,0xB8,0x12,0x51,0xAF,0xEE,0x28,0xD8,0x74,0x4A,0x2C,0xA4,0xD2,0x78, +0x88,0xC4,0xC9,0x58,0x9A,0x6C,0x37,0x6F,0x90,0x28,0xA7,0x0E,0xFE,0x14,0xDA,0x4A, +0x42,0x81,0x3B,0x47,0x5C,0xFE,0x9D,0x72,0x15,0x89,0xA0,0x6E,0xD6,0xF7,0x66,0x85, +0x52,0xC7,0x3E,0xDB,0x5A,0xDE,0xDE,0x33,0x0E,0xD1,0x3B,0x5B,0xD8,0xE6,0x33,0x1E, +0xBC,0x4F,0x73,0xFC,0x73,0xD0,0x36,0x7E,0x93,0xAB,0xA0,0x7C,0x71,0x48,0x53,0xFC, +0x66,0xD3,0x8B,0x1A,0x0D,0xF3,0x29,0xD0,0x47,0xDE,0xA9,0x05,0x29,0x25,0x46,0xA6, +0x2B,0x58,0x81,0x2B,0x23,0x0B,0xB3,0xCA,0x2A,0x00,0xAA,0x7D,0xBB,0x45,0xCD,0x06, +0xC4,0x7B,0xC7,0xD1,0xCE,0xBE,0x90,0x4D,0xE4,0x31,0x5E,0xFF,0x28,0xDC,0x11,0x72, +0x19,0x24,0x63,0xC1,0x1B,0xD3,0x13,0x6A,0x5C,0x0B,0x66,0xAB,0x79,0x01,0x04,0xF4, +0x18,0xCC,0x22,0x32,0x80,0x06,0x13,0x34,0x6F,0x7F,0x3B,0xBB,0xE7,0xFC,0xA8,0xFD, +0x8E,0x0E,0xF1,0x8A,0xCC,0x34,0xEF,0xF3,0x50,0x1D,0xBF,0xC0,0xC4,0xC1,0xA4,0xBF, +0xD1,0x66,0xF2,0x65,0x1E,0x17,0x47,0x4B,0x60,0x7F,0xC7,0x0A,0x1C,0xEF,0x88,0xA7, +0x92,0x6F,0xEB,0xC3,0x69,0x3A,0x5F,0x79,0xD9,0x9F,0xBD,0x99,0xE5,0x09,0x16,0x17, +0xAF,0x2C,0x62,0xA0,0x7D,0xAF,0x5A,0x0A,0x4E,0xAB,0xDF,0xCD,0xBA,0x76,0xE6,0x34, +0x74,0xED,0xC2,0x97,0x36,0xF0,0x93,0xF1,0x6D,0x5F,0xD5,0x64,0x45,0xD5,0x05,0x47, +0x97,0x66,0x7B,0x35,0xD9,0x9A,0x67,0x6A,0x69,0x89,0x0C,0x87,0xBD,0x0A,0x6C,0xA6, +0xF8,0xAE,0x65,0xED,0xEA,0x7F,0x75,0xA6,0xEF,0xD0,0xCC,0x58,0x6A,0xEF,0xC6,0x2C, +0x68,0x16,0xC6,0x22,0xED,0x4D,0x7F,0x9E,0x6E,0x66,0xF6,0x4D,0x46,0xB7,0x31,0x3F, +0x02,0x25,0xDB,0xCD,0x70,0xE9,0x5C,0xDD,0x44,0xAD,0xFC,0x40,0x79,0xEB,0x44,0xAC, +0x51,0x1D,0x35,0xCD,0x7A,0xF3,0x77,0x5C,0x33,0x52,0x6B,0x19,0x54,0x33,0xEE,0xEB, +0x34,0x3F,0x99,0x82,0x70,0x76,0x4C,0x4A,0x30,0xF1,0x33,0xDA,0x83,0xC6,0x66,0x0A, +0xB6,0xD3,0xB9,0xAD,0xB9,0xAB,0x62,0x5D,0x55,0x8F,0xDD,0xCF,0x74,0x45,0x76,0x92, +0xDC,0x86,0xDC,0x49,0x34,0xFC,0xF1,0xC8,0xE4,0xB4,0x32,0x2C,0x66,0x6E,0xC2,0xD7, +0x53,0x57,0x00,0x74,0xE3,0xD6,0xE2,0xA9,0x63,0x4B,0x33,0x20,0x4A,0x38,0x44,0xD0, +0xF7,0x95,0xD9,0xFD,0x7A,0x47,0x22,0xCE,0x39,0x63,0xBE,0x2F,0xBC,0x09,0x7E,0x69, +0x61,0x09,0x90,0xE0,0x98,0xBB,0x18,0x0E,0xF8,0xDF,0xEC,0x33,0xA3,0xFC,0x32,0x60, +0xE8,0xEE,0xDD,0x36,0x85,0x14,0x6D,0xB8,0x36,0xBD,0x73,0x50,0x92,0xC0,0xF2,0x61, +0x5C,0x1A,0x20,0xD8,0x8F,0x19,0x92,0x64,0x40,0xE4,0xA8,0x79,0x50,0x76,0xD3,0xE7, +0x34,0x4E,0xE4,0x5D,0x2F,0x78,0xBF,0xF0,0x4A,0x3B,0x8E,0xA1,0xCB,0xA0,0x1F,0x2B, +0xE1,0xB8,0xD5,0x4D,0xAF,0xB5,0x8D,0xE2,0x42,0x2A,0x24,0x79,0x08,0xA9,0x5A,0xFE, +0x37,0xFF,0xD7,0x06,0x71,0xB6,0x99,0x57,0xD9,0x10,0xCD,0x2A,0x04,0xE5,0xD2,0x27, +0xE3,0x08,0x14,0x59,0x47,0xC4,0x34,0x93,0x20,0xB1,0x6B,0x5A,0x30,0x63,0x2B,0xE7, +0x59,0x8A,0xDB,0x80,0x12,0x1B,0x4E,0x35,0x08,0x2F,0xEA,0x59,0x04,0xFF,0x94,0x30, +0x2A,0x16,0x0E,0xA5,0xAF,0x53,0x96,0xF8,0x36,0xD7,0x08,0x3C,0xA6,0x29,0xFA,0x5B, +0x7D,0x9F,0x18,0xF1,0x1D,0x71,0x8B,0xF6,0x2E,0x9E,0x3D,0x4D,0x87,0xD2,0xBC,0x74, +0xB2,0x63,0xC9,0xE9,0x49,0xE3,0x1D,0x17,0xE1,0xB0,0xD9,0xB3,0xF9,0xA0,0x74,0xDD, +0x4E,0xDB,0xA0,0xFA,0x5B,0x8F,0x44,0xF1,0x66,0x65,0x6C,0x14,0x3B,0x36,0xCE,0xD1, +0xF0,0x41,0x80,0xDC,0xC9,0x57,0x66,0x30,0x4B,0x4C,0x3C,0xDA,0x5F,0xEF,0x64,0xFD, +0xAB,0xAC,0x11,0x0B,0x47,0xA7,0x34,0xC9,0x8D,0xE5,0x16,0xCF,0x2B,0xC7,0x57,0x25, +0x7F,0xE7,0x12,0x63,0x6E,0x0E,0x8F,0x90,0xBD,0x49,0xD3,0x6A,0x62,0xCD,0xE9,0x56, +0x1D,0x32,0x4C,0xF3,0x0B,0xDC,0x52,0xEF,0x29,0x09,0x75,0x2E,0xE7,0xF0,0x8C,0x9D, +0xBF,0x33,0x74,0x9D,0x7A,0xDD,0x70,0x9B,0x80,0x67,0x96,0x52,0xE4,0x2B,0x86,0xB0, +0x78,0xBB,0x59,0x21,0xCC,0xA5,0x27,0xA6,0xC9,0xE8,0xE7,0xD8,0x63,0x77,0xD3,0x43, +0x05,0x30,0xF5,0xF0,0x0E,0x4D,0x8E,0x05,0x64,0x44,0x6F,0xF0,0xC8,0xB2,0x9F,0x76, +0x49,0x5F,0x9B,0x81,0x8F,0xA5,0x61,0xFF,0xEA,0x88,0xC6,0x20,0x77,0x7F,0x09,0x41, +0xFB,0x81,0x63,0x1F,0xB0,0x97,0x18,0xF5,0x8A,0xE2,0x4D,0x5B,0xA9,0xDA,0xCB,0xBA, +0x99,0xAF,0x19,0x0F,0x43,0xDD,0xFC,0xD1,0x7C,0x58,0xCB,0xF3,0xB3,0xD1,0xD0,0x81, +0xC3,0x78,0x4C,0x0F,0xD5,0x92,0x5A,0x94,0xF8,0xE0,0x58,0x89,0x76,0xD3,0xE8,0xA9, +0x97,0x8A,0x80,0x23,0xEB,0x38,0x39,0x1C,0xAC,0xB1,0x19,0x2E,0x93,0x18,0xB2,0x9B, +0x92,0x2B,0x4D,0x6C,0xF0,0xA3,0xF9,0xA4,0x8D,0x14,0xC9,0x80,0xEE,0x4A,0x03,0x4B, +0x08,0xDF,0x58,0x9A,0xE4,0x6B,0x90,0xC2,0x05,0x4E,0xFD,0x00,0xA3,0x55,0xB9,0xEB, +0x11,0x9F,0xC3,0xFD,0x93,0x8C,0x85,0x9C,0xE4,0xDB,0x59,0x53,0xF6,0xA2,0xE1,0xC6, +0x6E,0x64,0xA8,0x36,0xE3,0xB3,0xA5,0x9B,0xEA,0x38,0xFD,0x4D,0x83,0xA5,0x53,0xC6, +0x93,0xAD,0xF5,0x60,0xBA,0xA5,0x66,0x0A,0xBB,0x94,0x50,0x45,0x1A,0x74,0xE8,0x5E, +0x00,0xB7,0x3F,0xAB,0x86,0x72,0x80,0xE3,0x99,0x7A,0x6E,0xDF,0x18,0x78,0x86,0xE2, +0x80,0x0E,0x25,0x20,0xE2,0xC7,0x0A,0xA7,0x96,0x0E,0x6E,0xFA,0x02,0x44,0xF1,0x1F, +0x7D,0xC3,0x34,0xC2,0xB9,0x1D,0x63,0x2E,0x23,0x4D,0x45,0xE6,0x83,0x6D,0x8E,0x04, +0xEB,0x87,0xCE,0x3C,0x3A,0xB9,0x6C,0x69,0x34,0x39,0xAB,0x75,0xB0,0x80,0x83,0x4C, +0xE4,0x68,0x59,0x51,0x85,0xE9,0x99,0xDE,0x06,0x91,0x83,0x23,0x25,0x52,0xDD,0x14, +0x3E,0x41,0x60,0xB4,0x9E,0x71,0xD3,0x5D,0x49,0xA1,0x2A,0x6E,0xE4,0xFE,0x1B,0x62, +0x73,0x69,0x1A,0x18,0xAD,0xEA,0x3B,0xD7,0x48,0x7F,0x43,0xF5,0xCA,0xD6,0x3B,0xE6, +0x28,0x41,0x81,0x02,0xF1,0x06,0x8A,0x35,0xA5,0xA1,0x30,0xCA,0x20,0x58,0xB6,0x06, +0x1A,0x5A,0xF0,0x3E,0x51,0x03,0x8A,0x80,0xDA,0xBB,0x2E,0xB4,0x3B,0xB8,0xD1,0x5D, +0xBE,0x2C,0x2E,0x12,0xC8,0x66,0x39,0x6A,0x31,0x3F,0x97,0x11,0x9F,0x74,0x36,0xBC, +0x6C,0xEF,0x06,0x18,0xBE,0x4C,0x67,0x7A,0x95,0x29,0x1F,0x23,0x33,0x7F,0xDC,0x09, +0xCF,0xF0,0x21,0xA7,0xC1,0xCF,0xF9,0x55,0x16,0xAB,0x76,0xA4,0xBA,0xD1,0x49,0x27, +0x35,0x7A,0xFC,0x22,0x15,0x35,0x66,0xBE,0x5B,0x30,0x2A,0x16,0xFB,0xFF,0x00,0x41, +0x85,0xF6,0xA3,0x3F,0x7F,0x99,0x7B,0x9D,0x4A,0xB6,0x5B,0x04,0xC1,0x86,0xF1,0xFB, +0x74,0xA6,0x8E,0xEB,0x1C,0x78,0x64,0xB2,0x34,0xA9,0x60,0xD4,0x2B,0xAF,0xA7,0x4D, +0x64,0x60,0x3F,0xEE,0x8B,0x00,0xCD,0xD7,0x5A,0x66,0x93,0x00,0x00,0x21,0x23,0x9F, +0x1D,0x97,0x5D,0x85,0x4C,0xA5,0x14,0x22,0xDC,0x7F,0xD6,0x04,0x8E,0x5C,0x43,0x31, +0xB5,0xF4,0x9C,0x90,0xD7,0x9D,0xB1,0x6C,0xF6,0x2F,0xCC,0x27,0x24,0x93,0x4E,0xA6, +0xBF,0x4A,0x2D,0xAB,0x5C,0x4A,0xCD,0xF7,0xE2,0x3F,0x56,0xCF,0xB2,0x28,0x7B,0x33, +0xEF,0x29,0x66,0x3B,0xFC,0xEE,0xE7,0xBE,0x25,0x09,0x92,0x50,0x6F,0xAE,0xDF,0xB5, +0xB2,0x27,0x9C,0x11,0x40,0xE8,0xCD,0xEF,0x17,0x36,0x2B,0x88,0xEA,0x20,0xF2,0x5E, +0xD6,0x23,0x03,0xF3,0xD7,0x55,0x5F,0x1C,0x51,0x8E,0xAD,0x3A,0xAF,0x9F,0x28,0x93, +0x72,0x82,0xAE,0x1E,0xB7,0xB3,0x12,0x91,0xE3,0x50,0x1E,0x61,0x1C,0x90,0xEB,0x7F, +0x16,0x05,0xED,0x86,0x5A,0x11,0x8A,0x76,0xBA,0xDE,0xE6,0xEC,0x3B,0x4C,0xC9,0x0E, +0xB5,0x11,0xE4,0x5D,0x21,0x4E,0x2C,0x1C,0x7B,0x79,0xF1,0x56,0x0A,0x5C,0x37,0x55, +0xCB,0xD7,0x46,0x36,0x4F,0xB2,0x10,0x79,0x3C,0xF9,0x0D,0x8E,0xDD,0xAB,0xD1,0x8D, +0x33,0xC3,0x9D,0x31,0x63,0x2F,0x1B,0xAA,0xD0,0x14,0x48,0xD2,0x44,0xD3,0x78,0xDF, +0x16,0xB9,0xCF,0xBD,0x61,0xEB,0x0B,0xCF,0xBB,0x54,0x50,0x83,0x68,0xBF,0xBF,0x50, +0x6A,0xAF,0x2D,0x68,0x55,0xD0,0xF0,0x14,0xA9,0x5D,0x80,0x2B,0xA1,0x39,0xB8,0x0B, +0x09,0x3D,0xF7,0xB1,0xD5,0xBE,0xB9,0x96,0x60,0xD5,0xE0,0x4E,0x3F,0x6F,0xC1,0x4D, +0xB2,0x97,0x22,0x80,0xA7,0x3B,0x97,0x94,0xD8,0x10,0xAE,0x98,0xFC,0x6D,0xAC,0x6E, +0xF8,0x27,0xDA,0x8D,0xC6,0xD4,0xB5,0x28,0x42,0xDA,0x6E,0xF1,0x94,0xB4,0x7B,0x48, +0x75,0xB8,0xD8,0xBE,0xD3,0x0A,0xA9,0x1F,0x6A,0x56,0x20,0x67,0x0F,0x70,0x19,0x28, +0x30,0x8A,0x8F,0xF1,0x42,0xA2,0x35,0x30,0x1D,0xAB,0xD3,0x76,0x92,0xF7,0x1F,0x0D, +0x77,0xBA,0xB3,0x89,0xD1,0x80,0x69,0xBD,0x7C,0x05,0x89,0x11,0x56,0x27,0xDA,0xC6, +0x0E,0x63,0x13,0xB6,0x58,0xC7,0x14,0xCD,0xEF,0xA5,0x10,0x1B,0xB3,0x39,0xFE,0xE0, +0xB1,0xFD,0x75,0x13,0x7F,0x85,0x3C,0x81,0x17,0x0C,0x50,0x97,0x6B,0xAA,0x90,0x00, +0x19,0x55,0x30,0xE6,0x5B,0x47,0x29,0x0F,0xAF,0x0B,0x67,0x5B,0x2D,0xA7,0xA4,0xBB, +0x7E,0x92,0x17,0xD0,0x92,0xE4,0x84,0xEC,0x0B,0x10,0x22,0x9E,0xD9,0x8A,0x4D,0xDF, +0x06,0x5E,0x42,0x7E,0x49,0x74,0x0B,0xED,0x0B,0x3C,0xFD,0xDB,0xE6,0xA7,0xAE,0xE9, +0x3C,0x52,0x4B,0x3F,0x18,0x47,0x13,0x30,0x39,0x83,0x28,0x54,0xFF,0x11,0xAB,0x9C, +0x18,0x7A,0xF2,0xDF,0xC5,0x9A,0x99,0xFF,0x2C,0x28,0x22,0x14,0xF3,0x69,0x3C,0x27, +0x89,0xDD,0x3B,0x19,0xFA,0x6D,0x6A,0x5D,0xA7,0x04,0x91,0x3D,0x53,0x41,0x19,0x5B, +0x57,0xC2,0x78,0x78,0xFE,0x7A,0xA5,0x38,0xF3,0xB6,0x01,0x96,0x44,0x01,0x07,0xBB, +0x4C,0x05,0x5A,0x0F,0xB0,0xEF,0x5A,0x03,0x69,0xD0,0x99,0x4C,0xC5,0x4C,0x65,0x43, +0x94,0x3D,0x2E,0x37,0xCC,0x90,0x08,0xDE,0x34,0xEB,0x5E,0x08,0xB0,0x1D,0xEF,0x0C, +0x9C,0x5F,0x7D,0x75,0xBE,0xD2,0xE1,0x0B,0x8E,0x20,0x72,0x22,0xB7,0x27,0x3C,0xF6, +0xCF,0xA8,0x9D,0xD4,0x49,0xA6,0x15,0xEC,0x7C,0xCB,0x05,0x78,0xDD,0xAB,0x7E,0x47, +0x16,0x19,0xAB,0x2B,0x79,0x51,0xA2,0xCD,0x45,0x11,0xFC,0x5C,0x41,0x96,0xA8,0xCB, +0x2B,0xD8,0x9E,0x04,0xF2,0x58,0xEE,0xBA,0x16,0x44,0xDC,0x6C,0xA7,0x94,0x25,0x08, +0xCE,0xD5,0xD3,0xA9,0x32,0x42,0x97,0x56,0x95,0x8B,0x13,0xC9,0x0A,0xF3,0x1B,0xD6, +0x41,0x10,0x36,0x7E,0x95,0xE1,0x16,0xAC,0xFE,0xF7,0xA2,0x5B,0xD6,0x11,0x91,0x94, +0x28,0x51,0xCA,0x11,0x1C,0xD3,0x1C,0x40,0x10,0x7E,0xBF,0x14,0x76,0x9A,0xB8,0x74, +0xD5,0x80,0x79,0xA5,0x22,0x8B,0x9D,0x9D,0xC1,0x05,0x99,0x93,0x85,0x2A,0xB0,0x18, +0x98,0xB3,0xC4,0xE1,0x90,0xE5,0xD2,0x0D,0x12,0x2A,0x1E,0xDB,0x66,0x8D,0x3F,0xFF, +0x17,0x5F,0x44,0x4E,0x7D,0x05,0x07,0xD3,0x36,0x4B,0xE8,0x4D,0x5D,0x5C,0x8B,0x21, +0x5D,0xA7,0x2D,0x4B,0x65,0x2A,0x87,0xCB,0xE7,0xD6,0x6B,0x5E,0x23,0xB5,0x1A,0xBA, +0x3A,0xBB,0x5C,0x1B,0x13,0x21,0x24,0x37,0x83,0x55,0xD1,0x3B,0xEC,0xB0,0xA4,0x17, +0x89,0xED,0x49,0x12,0xEC,0x2B,0x8E,0x7C,0x19,0x2A,0x0A,0xAB,0x77,0xDC,0xFD,0x41, +0x59,0x9D,0x65,0xE4,0x31,0x0C,0x29,0xE2,0x93,0x42,0xF7,0x39,0xDB,0xFD,0x3F,0x9F, +0xA7,0x3F,0xA9,0xDB,0xEF,0xDD,0x39,0x9F,0xBD,0x8A,0x09,0xFC,0xB1,0x46,0x78,0x62, +0xBA,0xC0,0x9E,0xC3,0x38,0xC8,0x7B,0xC0,0x68,0x51,0x40,0xBF,0x5D,0x98,0x16,0x99, +0xE2,0x1B,0x37,0xE5,0x7C,0x39,0xA1,0xAA,0xC2,0x25,0xAB,0x31,0xC3,0xB5,0xF8,0x83, +0x9C,0xF1,0x48,0x5D,0xDF,0x03,0xF3,0xA6,0x24,0x96,0x6B,0x5B,0x16,0x6A,0xCD,0x40, +0xE7,0xA5,0x80,0xBA,0x08,0xF1,0x0D,0x31,0x1C,0x02,0xE5,0x5D,0x39,0x58,0x1C,0xCB, +0x40,0xAA,0xA9,0x18,0x2B,0xB9,0x1D,0x0B,0x6C,0xCD,0x3E,0x28,0x4A,0x7A,0xAF,0xDB, +0xB6,0xC5,0xCF,0xA6,0x71,0x45,0x87,0xF9,0x4D,0x0E,0x5B,0xD0,0x43,0x52,0x28,0xA6, +0x02,0xD3,0x59,0x0A,0x52,0x2F,0x21,0x58,0x9D,0x66,0xD4,0x2D,0xBE,0x6C,0x2D,0x64, +0x81,0xE1,0x71,0x0C,0xE0,0xE2,0x86,0x75,0x1E,0x8B,0x12,0x23,0xB2,0xA3,0x54,0x5C, +0xF0,0x67,0x0C,0x62,0xD6,0x68,0x35,0x96,0x5E,0x53,0x40,0xD1,0x22,0x8C,0x1C,0xE3, +0x95,0x36,0xF2,0x95,0x94,0x39,0x3C,0x27,0xDD,0x88,0x01,0x11,0xA8,0x87,0xBD,0x9C, +0x7D,0x5F,0x7A,0xBF,0xF5,0xE2,0x95,0x64,0x39,0x7A,0x15,0x8C,0x07,0x37,0xD9,0x59, +0x1A,0x80,0x0F,0xF9,0x3B,0x73,0x32,0x75,0x4C,0xFE,0xB1,0x01,0x64,0x19,0x25,0xD6, +0x13,0xC5,0x46,0x90,0xAC,0xC1,0xE6,0x3A,0x66,0x89,0xA8,0xD4,0x75,0xD1,0xC2,0x60, +0xF3,0xA2,0x06,0x22,0x2C,0xD3,0x2D,0x69,0x8F,0x62,0x50,0x16,0x83,0x9C,0x4D,0xAD, +0x58,0x4F,0x56,0xBF,0xFC,0x06,0x49,0xA1,0x03,0x5F,0xCC,0xAD,0x1E,0xD6,0x71,0x34, +0x46,0x5D,0xDF,0xE5,0x94,0x92,0x90,0x9A,0xEA,0xF8,0x6A,0x31,0xA0,0x95,0xC0,0x2A, +0xDA,0x74,0xEE,0x8D,0x6B,0xD4,0x0B,0x6E,0xF3,0x05,0x7E,0x66,0x06,0x42,0x8A,0xA0, +0xC7,0xFC,0x44,0xC8,0xB1,0x60,0xCA,0xB3,0x12,0x7A,0xB6,0xE6,0xC6,0xB6,0x8A,0xD2, +0xE1,0x98,0x86,0x05,0x33,0xC2,0xF7,0xF4,0xC2,0x57,0xB6,0x78,0x69,0xE6,0x8B,0xC0, +0xB0,0x5D,0x29,0x49,0x01,0x41,0xC1,0xA6,0xA2,0x09,0x82,0xD2,0x67,0x95,0x07,0x6C, +0x70,0xEA,0x37,0x4A,0x8B,0x52,0x86,0x94,0x2D,0xD4,0x68,0xA0,0x05,0x92,0x81,0x02, +0x11,0x96,0xB0,0x0F,0x6D,0x21,0xC2,0xF5,0x54,0xE0,0x81,0x16,0x75,0x6A,0x97,0xA4, +0x68,0x10,0x95,0xE5,0x3F,0xAC,0x91,0x03,0xB9,0xC1,0x8B,0x0A,0x2F,0x98,0x0A,0xE2, +0xB4,0x1C,0x2E,0x29,0xF2,0xF7,0x9D,0x2B,0x25,0x2C,0xB2,0xA8,0xA3,0x6D,0x45,0x41, +0x29,0x1B,0x5E,0xF8,0x65,0x17,0x23,0xD2,0xA0,0xF6,0xEA,0x56,0x8C,0x79,0x35,0xEA, +0x0A,0x85,0xA0,0xE9,0xD6,0x5A,0xB0,0xBE,0x2C,0x8D,0xF3,0xBA,0x3E,0x14,0x0F,0xA6, +0x49,0xA0,0x41,0x43,0xC0,0x6E,0x31,0xF3,0xAF,0x4E,0xB6,0xD5,0xC3,0x04,0xDE,0xD4, +0xAA,0x3C,0x07,0x14,0x00,0xBB,0xF9,0x13,0x93,0x5D,0xC1,0x74,0x2E,0x1F,0xF2,0x56, +0xC9,0xC2,0x50,0x27,0xDF,0xF1,0x8B,0xE7,0xF4,0x3A,0x9D,0xD3,0x49,0xF1,0xED,0xB1, +0x14,0x2F,0x4D,0x4A,0x2E,0xFE,0x3A,0xC6,0x7C,0x8A,0xF0,0x9E,0xCF,0xA9,0xD0,0xE1, +0x9E,0x5B,0x93,0x56,0xD9,0xA0,0xE3,0xE7,0x9D,0x2A,0xEB,0x45,0xD4,0x99,0x54,0xB1, +0x6A,0x4F,0x56,0x7E,0x8D,0x67,0xCD,0x3F,0x5F,0xEC,0xD9,0xDA,0x39,0xEA,0x64,0xA9, +0x3F,0x21,0xB0,0x18,0x79,0x2F,0x72,0xE9,0x65,0xC6,0xFE,0xD9,0xCE,0x09,0x68,0xEC, +0x71,0x8A,0x89,0xBE,0x59,0x3D,0x85,0x6A,0xD6,0xD0,0x7B,0xF5,0x40,0xA6,0xA9,0x01, +0x1A,0xF0,0xF0,0x37,0xDC,0x26,0x1C,0xAE,0x66,0xFF,0x64,0xCD,0x66,0xAA,0x84,0x9F, +0x0F,0x79,0x81,0x3D,0xA6,0x27,0xBC,0x98,0xD1,0x76,0x44,0xCC,0x31,0x02,0x71,0xF8, +0x10,0xE3,0x63,0x0A,0xD4,0xDB,0xA0,0x09,0xCA,0x70,0x08,0x67,0xF8,0xC4,0x99,0x8D, +0x5A,0x3F,0xFA,0xA9,0xAC,0x6E,0x8F,0xDF,0x7F,0x8C,0x86,0xF6,0x5B,0x07,0x09,0x9E, +0xB3,0x83,0x06,0x56,0x9D,0xB2,0xBA,0x9D,0x4E,0xB5,0x86,0x67,0x19,0x79,0xC8,0x92, +0xF1,0xA2,0x0F,0x7E,0xB4,0x8A,0xE5,0xA1,0xD5,0xAF,0x0A,0xCA,0x08,0x83,0x2C,0x93, +0xBD,0xF4,0xB2,0xC5,0x27,0xA7,0x75,0xA5,0xBF,0x2A,0x77,0x80,0x3F,0xB3,0x57,0x1C, +0x88,0x80,0x88,0x0F,0xF5,0x2E,0x30,0xD8,0x3F,0xD1,0x80,0x76,0xED,0x68,0x7D,0x32, +0x14,0xFD,0xC3,0x4F,0x0C,0x2F,0x02,0x86,0xE3,0x51,0x76,0x36,0xC2,0x1E,0x0C,0xA1, +0x63,0xB2,0x65,0xCC,0xA1,0x6F,0x01,0x3B,0x2A,0x38,0x09,0xA1,0xE6,0xAC,0x10,0xFE, +0xC0,0x6C,0xE5,0xE0,0xC5,0x21,0x74,0xCB,0xF2,0x25,0xD6,0x12,0xC8,0x50,0x1E,0x47, +0xA7,0x06,0x0C,0xA9,0x23,0x20,0x45,0x95,0x66,0xEE,0x0C,0x95,0xA0,0xD7,0x93,0x17, +0x1E,0x09,0x89,0x59,0xD6,0x09,0xC4,0xCD,0x0D,0x92,0xAD,0x12,0x6F,0x06,0x53,0x43, +0x16,0xE8,0x30,0x53,0x3D,0x74,0xEF,0x93,0x44,0x2C,0x45,0x99,0x7D,0x0E,0x70,0x1E, +0x44,0x21,0x2B,0xD8,0x19,0x17,0x79,0x48,0x84,0xD2,0x58,0xE0,0xCB,0x1A,0x64,0x11, +0x24,0xC2,0xCE,0x53,0x56,0x3E,0x9F,0x09,0xC0,0x6D,0xD8,0x96,0x3D,0x52,0x58,0x13, +0x96,0x01,0x20,0x26,0xA6,0xDE,0x0B,0x38,0xC7,0xB1,0xA2,0xAD,0xA3,0x53,0xCA,0x70, +0x23,0x98,0xF6,0x69,0x49,0x87,0xAE,0xCF,0x72,0x67,0xAB,0x65,0xFD,0x19,0xA2,0xD8, +0x7E,0x57,0x1A,0xF2,0x27,0xE2,0x61,0xC0,0xC9,0xD3,0x3F,0x04,0xF3,0xAF,0x0F,0x51, +0x4A,0xCC,0x1B,0xE5,0x05,0x86,0x79,0x2B,0x9F,0x10,0xF5,0x02,0x61,0xF5,0x6D,0x8E, +0x12,0xB6,0x64,0xD9,0x2C,0xF9,0x65,0x4E,0x6C,0xE4,0x6F,0x23,0xE3,0xCA,0x2D,0x5D, +0x98,0x73,0xEA,0xA1,0xB0,0x4C,0xCD,0xCE,0x93,0x83,0x04,0x22,0x2F,0xDD,0x18,0x7C, +0x27,0xAB,0x3F,0x14,0x2D,0xA4,0x91,0xA7,0xE1,0x2C,0x8C,0x45,0x9D,0xA8,0x99,0x68, +0xD9,0xD5,0xAA,0x38,0xEC,0x57,0xBD,0x49,0x91,0x9B,0x2C,0x34,0xD6,0x54,0xC1,0x2A, +0x8E,0x1B,0x59,0xAB,0x39,0xB6,0xEC,0x91,0x8A,0xD3,0x84,0xAB,0x4A,0xFD,0xF8,0x13, +0x41,0xEC,0xEB,0xA3,0x4F,0x9B,0x28,0xCA,0x64,0x9C,0x59,0x3E,0xD0,0x0B,0xC8,0x17, +0x40,0x35,0x85,0xCC,0xAB,0x33,0x99,0xBE,0x75,0x5E,0xCC,0xF8,0x98,0xDF,0xF7,0xBD, +0xC1,0x39,0xFF,0xD3,0xD1,0x63,0x48,0x13,0xB8,0x7E,0x94,0x0C,0x55,0x9A,0x27,0x73, +0x23,0x32,0x02,0xAB,0xA9,0x8A,0xD8,0xF3,0xA3,0x57,0x1D,0xBD,0xF2,0x8D,0xE4,0xB7, +0xF8,0x7C,0x61,0x99,0x6F,0xAD,0xBE,0xC5,0x17,0x1B,0x1B,0x5D,0x14,0xA6,0xF5,0xBD, +0xE4,0xBB,0xD2,0x60,0xB3,0xF3,0x3A,0x04,0x27,0xE3,0xE8,0x5F,0x13,0x2E,0x28,0x74, +0xBC,0x2B,0x9E,0x2B,0xE6,0x87,0x7F,0x33,0xCE,0x1A,0xD4,0x62,0x92,0x3F,0x62,0xC5, +0x17,0x6B,0x75,0x5C,0x1C,0x0D,0xD4,0x23,0x5E,0x55,0xB0,0x52,0x25,0x13,0xFB,0xFC, +0x09,0xFB,0xD1,0x43,0x3A,0x52,0x0B,0x00,0x99,0xFE,0x08,0x05,0x1E,0xEE,0x74,0x58, +0x10,0xC9,0xC3,0xCD,0xA6,0xC5,0xB8,0x6B,0x54,0xFC,0xB2,0x4E,0x66,0x3A,0x67,0xEA, +0x93,0x3D,0x22,0x71,0x77,0xDD,0x5C,0xAE,0x9F,0x60,0x2E,0x13,0x9A,0x90,0x1E,0xC6, +0xF4,0xF4,0xB3,0xB9,0xA4,0x45,0x1B,0x60,0x73,0xE5,0x83,0xE3,0xA8,0x05,0x60,0x9A, +0xF3,0xAE,0x44,0xC1,0x79,0x4E,0x7B,0x4A,0xB4,0x8C,0xBB,0x0D,0x23,0x77,0x52,0x03, +0x3F,0x9F,0xE3,0x41,0x12,0x9E,0xD0,0x4D,0x20,0x46,0xF6,0xD5,0xCC,0x86,0xD3,0x15, +0xFF,0x43,0x7D,0x09,0xD5,0x89,0xCC,0xDF,0xB1,0x8B,0x56,0xFA,0xAC,0xAD,0x76,0xC9, +0x48,0xB3,0xED,0xC1,0x6F,0xFD,0xDE,0x1B,0x9A,0xC2,0xBA,0x2C,0xDF,0x5C,0xBD,0x04, +0xA7,0xB7,0xB9,0x6F,0xC8,0x89,0x6E,0xAD,0x85,0x97,0x3A,0xEF,0x20,0x21,0x7B,0xA2, +0xC9,0xBA,0xCE,0xF3,0x1B,0xF1,0xDC,0xFD,0x9F,0x75,0x7F,0xA8,0x6B,0x29,0x92,0xFF, +0x0C,0x3E,0xF2,0x42,0xE2,0x64,0x10,0xDA,0x16,0x7D,0x60,0xF2,0x16,0xCE,0xEF,0xB8, +0x2B,0x1C,0x7B,0xE7,0x0B,0xC4,0x33,0x30,0x16,0x69,0x46,0xE5,0x02,0xDC,0xBA,0x15, +0x5A,0xB3,0x6B,0x53,0x24,0x81,0x63,0x43,0xF5,0x2E,0x5A,0x48,0x7D,0x61,0x27,0xBC, +0xBD,0xDC,0xC2,0xEC,0x05,0x8C,0x1D,0x80,0x21,0x69,0xDA,0xF5,0x06,0x9F,0x7B,0xFC, +0x7C,0x58,0x64,0x91,0x68,0xBA,0x9A,0x4F,0x5B,0x8A,0x7C,0x20,0xD1,0x04,0x29,0x4E, +0x27,0x29,0xCE,0x00,0x6E,0xCD,0x4F,0x89,0x7E,0x05,0xCD,0xA8,0xE9,0x52,0xA8,0x21, +0x51,0xF5,0x5B,0x1D,0x4B,0xD2,0xC0,0xA2,0xF7,0x34,0x2D,0x50,0xD9,0x74,0x3D,0x57, +0x3C,0x9E,0x37,0xF7,0x8F,0xDA,0x1F,0x55,0x07,0xAC,0xB6,0x63,0xC5,0xE9,0x7D,0x77, +0x1E,0x4A,0xD3,0x30,0x81,0x62,0x88,0xFC,0xB2,0x0D,0x88,0xCE,0xF8,0xD7,0xEA,0xF5, +0x6B,0x48,0xD5,0xF9,0x38,0x18,0x4C,0x29,0x3A,0x4E,0x81,0x43,0xF6,0x25,0x71,0x87, +0xEB,0x7C,0xBF,0x91,0x04,0x69,0x6F,0xD8,0x0A,0x36,0x70,0x24,0x71,0x82,0x73,0x92, +0x58,0xEC,0xA5,0x20,0x4C,0x4C,0x2C,0x5A,0x7B,0xC4,0x80,0xC1,0xEA,0x79,0xCD,0xAB, +0x33,0x44,0x82,0xA7,0x13,0xB7,0xD8,0x55,0x55,0x41,0x4F,0x5B,0x8A,0x9D,0x64,0x20, +0x5B,0x4F,0x55,0xFD,0x81,0x1E,0x49,0x91,0x1D,0xA5,0x40,0xC7,0xC5,0x49,0xCB,0x01, +0xEB,0x7D,0x61,0xE7,0xB6,0x3B,0x1D,0x64,0xBD,0x8B,0x0E,0xAC,0x96,0x53,0xEF,0xAA, +0x35,0x6D,0x3A,0x90,0xF7,0xB5,0xCF,0xF6,0x3B,0x69,0x08,0x58,0xB6,0xA4,0xF2,0xE0, +0xEC,0x9D,0x0F,0x68,0x4F,0x86,0xE7,0xA6,0xCA,0x63,0x86,0x52,0x34,0xA5,0x35,0x8F, +0x58,0xF1,0x78,0x3D,0x3A,0x4B,0xA7,0xB2,0xE7,0xED,0x2E,0x1E,0x53,0x6A,0x16,0xAF, +0x3D,0x9F,0xA7,0x92,0x35,0xF7,0x27,0xDF,0xF2,0x0A,0x76,0x76,0x6E,0xCC,0xBF,0xBC, +0x77,0x25,0x66,0x33,0xD0,0x82,0xA8,0x58,0x19,0x3B,0xCD,0x82,0x0E,0x29,0x0D,0x0B, +0x81,0xEF,0xB7,0x6F,0x55,0x75,0xF0,0x7B,0x19,0xED,0x22,0xEE,0x02,0x5A,0x13,0x18, +0x31,0xE1,0xB2,0x25,0xF8,0x6A,0xEA,0xE3,0x5B,0x98,0xD3,0x2F,0x12,0xFC,0xD5,0x70, +0x5B,0xCD,0xCD,0xFE,0xAC,0xE1,0x35,0x13,0x3B,0xF4,0x8A,0x3B,0x6A,0xF6,0x61,0x51, +0xC2,0x1C,0x30,0xA6,0xE7,0x4B,0xCC,0x8F,0x3D,0x62,0x04,0x68,0x7B,0x45,0xF1,0xAE, +0x2D,0x32,0x99,0x8C,0x94,0xEA,0x98,0xFB,0xAD,0x20,0xEA,0x39,0x70,0xD1,0x11,0xF7, +0x9B,0x53,0x4E,0xBB,0xC8,0x8F,0x54,0x81,0xEB,0xC8,0x98,0x19,0xCE,0x7D,0xCF,0xB7, +0x04,0x1D,0x3A,0xB3,0xBA,0xDF,0xA5,0xA9,0xB9,0x74,0x97,0x1E,0x6F,0xBD,0x2A,0x3A, +0xB1,0xF9,0x0D,0x59,0x9E,0xAB,0x94,0x8E,0x8B,0x41,0xBF,0x1D,0x47,0x9F,0x12,0x68, +0x4D,0x2D,0x76,0x59,0x6F,0xA3,0xB6,0xF4,0xD0,0xAE,0x95,0x01,0x47,0x8B,0x6D,0xEA, +0x85,0xB7,0x90,0x21,0x0E,0x7B,0x88,0x37,0x66,0xCC,0x24,0x51,0x25,0x31,0xDC,0xF2, +0x89,0xD0,0xB7,0x31,0xF2,0x96,0xA4,0xBA,0xE9,0xAA,0x26,0xEB,0xAB,0xF5,0x98,0xAE, +0x5D,0x8B,0xC1,0x25,0x4C,0xC8,0xF4,0x56,0xC2,0x46,0xC6,0xC4,0x35,0xFD,0xB2,0x39, +0x7F,0xA0,0xAD,0x9D,0xBB,0x7A,0xEF,0xED,0xA9,0x29,0xBE,0xE4,0x0C,0x39,0x19,0xD9, +0x3A,0x89,0x0E,0x0D,0xFA,0x50,0x87,0xE8,0x53,0x50,0xED,0x4E,0x5B,0xC3,0xED,0x8C, +0x0D,0x33,0x69,0xB4,0xD3,0x38,0xE0,0x8C,0xA0,0x39,0xB7,0x9E,0x4E,0xA9,0xAC,0xF0, +0x48,0xFC,0xBE,0x48,0x99,0x99,0x27,0x02,0x91,0x4F,0x6F,0xCD,0xFF,0x96,0x12,0x57, +0x30,0x35,0xBE,0xB4,0xCF,0xEC,0xD2,0x46,0xD6,0xD4,0x1C,0x7A,0x26,0x7E,0xAC,0x57, +0x4E,0x9D,0x62,0x8B,0x92,0x01,0xDB,0xD3,0xFD,0x59,0xEF,0x45,0x92,0xC3,0x15,0xCB, +0x00,0x8D,0x05,0x34,0xC7,0xF0,0x2B,0x09,0x84,0x0B,0x99,0x45,0x92,0x50,0x4B,0x3A, +0x07,0x12,0x00,0x93,0x77,0xC6,0x87,0x4F,0x70,0x98,0x6C,0x27,0xF2,0x29,0x38,0x2F, +0xE3,0x96,0x03,0x1F,0x99,0xEF,0xE4,0x5F,0x1D,0x54,0x55,0x71,0xA8,0x29,0xFC,0x23, +0x10,0xD9,0x5B,0x5A,0xC2,0xD6,0x09,0xCD,0xF7,0xC7,0xF4,0x53,0x6C,0x3D,0xE7,0xC5, +0x63,0x9E,0x4B,0x04,0xB7,0xF5,0x64,0x28,0xC5,0x73,0x25,0x9A,0x23,0xAF,0x43,0x01, +0x48,0x50,0xF1,0xA9,0x6D,0xEB,0xD1,0x09,0x24,0x00,0x3C,0xDA,0x14,0x4D,0x0D,0x00, +0x4D,0x83,0xB5,0x56,0x9D,0x4B,0x65,0x06,0x3A,0xB2,0xB4,0xC2,0x8A,0xAC,0xB4,0x06, +0xCC,0xDF,0x6F,0xAC,0xE4,0xBC,0x64,0x71,0x73,0x78,0x72,0xAF,0xF7,0xED,0x78,0x1F, +0x86,0x65,0x11,0x0D,0xE6,0xFD,0x68,0x8A,0xE6,0x48,0x4E,0x42,0x0E,0x04,0x77,0x59, +0xD1,0xAC,0xB1,0xA4,0x32,0x42,0x6A,0x7E,0x04,0x2A,0xEA,0x0F,0x6C,0x0D,0x58,0x03, +0x36,0x02,0xD7,0x22,0xC4,0x8F,0xC0,0x16,0x8D,0x17,0x87,0x1B,0x43,0xE9,0xCE,0xC8, +0x9F,0x64,0x15,0xC4,0xEB,0xFB,0x88,0xAA,0x33,0x56,0x07,0x3C,0x79,0x3B,0x5A,0xE2, +0x82,0xE3,0x44,0x3F,0x9D,0x70,0x5C,0xB9,0x49,0x1D,0x8F,0xD3,0x29,0xEE,0xAB,0x4B, +0x5F,0x3B,0x74,0x11,0xA4,0x18,0x52,0x05,0x62,0x9C,0x8D,0xCB,0xC2,0xAE,0x8A,0xD0, +0x8B,0x89,0xF8,0x0E,0x80,0x2B,0xBF,0xA1,0x8F,0x61,0xC3,0xE2,0x14,0x5C,0x54,0x58, +0x79,0xE4,0x2E,0xAE,0x7F,0x2C,0xA5,0x14,0x6B,0x33,0x57,0xCB,0x76,0x1A,0xA4,0x6A, +0x24,0xAE,0x8D,0xE9,0x71,0xCC,0x73,0x6F,0xBC,0x69,0x3A,0x2E,0x59,0x9B,0x23,0x0F, +0xF9,0x5F,0xFA,0xB4,0x1A,0xE0,0xB1,0xCC,0x75,0x26,0xBB,0x07,0x6D,0x01,0xE9,0x77, +0xAE,0xF0,0xA1,0x6A,0xA0,0x8C,0x29,0xBB,0x39,0x77,0x86,0x16,0x6A,0x93,0xCC,0xDE, +0xD2,0x5D,0x12,0xA2,0xC3,0xF3,0xDF,0x55,0xE4,0xE8,0xFB,0x50,0x7A,0xC2,0xF4,0x73, +0xA3,0x42,0x73,0x59,0x2E,0x2F,0x87,0x13,0xA2,0x77,0xF0,0xD9,0x24,0x7B,0xD4,0x39, +0x77,0x26,0x88,0x51,0x1E,0xE9,0x21,0x5C,0x32,0x9E,0xF3,0x3E,0x2B,0xCE,0x8B,0x21, +0x82,0xD0,0x52,0xF3,0xBA,0xF3,0x64,0x06,0xC0,0x89,0xAD,0xAE,0x3F,0x52,0xB6,0xFA, +0xAE,0x47,0x29,0x3A,0x00,0xF4,0x04,0xBF,0x7B,0xA4,0x67,0x5D,0xF7,0x39,0x3E,0xDE, +0x8E,0xCF,0xB7,0x56,0xD2,0x41,0x9A,0x09,0x1F,0xA3,0x1C,0xC6,0x4F,0x34,0x80,0x3B, +0x6D,0x99,0xFD,0x18,0xB7,0xC9,0x21,0xFB,0x8B,0x8E,0xE8,0x20,0x42,0xA6,0x7D,0x2A, +0x42,0xCC,0x7F,0x7F,0xEC,0xF3,0x12,0x55,0xBC,0xE3,0xC7,0xAA,0x73,0xF5,0xF1,0x19, +0x23,0xDC,0x58,0x4E,0xD0,0xF0,0x53,0x07,0x36,0x87,0xC6,0x53,0x86,0x6B,0xD5,0x74, +0x51,0x0F,0x0C,0xF1,0x66,0x43,0x3A,0x7C,0x9D,0x9F,0x15,0xD5,0xFD,0xB2,0x5E,0x98, +0xE5,0x4E,0x40,0x57,0x64,0x40,0x86,0x5E,0x9C,0xE1,0xDB,0x97,0x9D,0x44,0x22,0x41, +0xE9,0xAD,0xD7,0xC3,0xEE,0x26,0x52,0x8C,0x33,0x1F,0x59,0x07,0xD5,0xD6,0xF4,0x8F, +0x2D,0xC6,0x6C,0x2F,0x54,0x22,0xE8,0x96,0x02,0xA2,0x4A,0xB8,0xFD,0x1C,0x5E,0x99, +0x82,0x76,0xA3,0xB8,0xF1,0xDF,0x7A,0x49,0xC2,0x67,0x33,0xFC,0x21,0x54,0x71,0xB5, +0xFC,0xAE,0xCD,0xE6,0x6E,0x61,0xDF,0xBE,0x3B,0x72,0x53,0x25,0xA4,0x97,0xF7,0x48, +0x4C,0x6B,0x58,0x1F,0xF0,0xF1,0x3C,0x53,0x50,0x8B,0xCD,0xC5,0x0F,0x3A,0xD0,0x26, +0xB4,0xDB,0x50,0x87,0xB7,0x46,0x94,0xFC,0x00,0xF7,0x41,0xF2,0x25,0xD8,0xB4,0xD7, +0xA6,0xDC,0xBA,0x2D,0x57,0x37,0xF5,0x6D,0xEC,0x23,0x12,0xB8,0x42,0xB1,0xE9,0xA5, +0x8C,0xDD,0x5E,0x4B,0xB8,0xA6,0x1A,0x15,0x5A,0xAD,0x56,0x8F,0x22,0xA5,0x6A,0x37, +0x07,0x4F,0x4F,0xC9,0x11,0x86,0xC7,0x1E,0xC6,0x56,0x4D,0xAF,0x53,0x2A,0x0D,0xFC, +0xDB,0xF7,0xA0,0xE4,0x2B,0x36,0x2A,0x0B,0xC9,0x9D,0x27,0x28,0xE2,0x17,0x6B,0xCE, +0x60,0x90,0x6D,0x21,0x34,0x1B,0xE3,0xCD,0xCA,0x23,0xF6,0x9B,0xDB,0x33,0x56,0xD7, +0x3B,0x96,0x42,0x99,0x5C,0x61,0x7B,0xD3,0x0F,0xDB,0x39,0x71,0x51,0x1E,0xC9,0x80, +0x68,0xE6,0xED,0x42,0xBD,0x32,0x8E,0x85,0x89,0xD6,0xE3,0x59,0xB7,0x9D,0x6B,0xAE, +0xC4,0x04,0x86,0x98,0xA9,0xBD,0x8C,0xEA,0x5A,0xD7,0x43,0x2B,0x5F,0xE3,0xE9,0x09, +0x01,0xA6,0x67,0xBE,0xA5,0xAB,0x97,0xE6,0xC0,0xC1,0xB7,0xA1,0x3E,0x5B,0x90,0x99, +0x00,0x7A,0x3D,0xBF,0x24,0xD0,0x0E,0x02,0x75,0x1A,0x45,0x5A,0x5A,0x29,0x8F,0xBE, +0x13,0xC9,0x4D,0x1B,0x80,0xE5,0x35,0x0C,0xE8,0x54,0xB4,0x07,0x10,0x52,0x6A,0x8F, +0x0C,0xBA,0x48,0x54,0x4A,0x75,0x23,0x22,0xE4,0x8B,0x7E,0x1A,0xBE,0x13,0xBB,0xAA, +0x3F,0x0C,0x94,0x4C,0x61,0xA7,0xCD,0xD3,0xDD,0xA6,0xD1,0x65,0xBB,0xF3,0x28,0x7B, +0x96,0x62,0x32,0x5B,0x1E,0xF6,0xD2,0xBE,0x24,0x4B,0x83,0x2D,0x80,0x17,0xB9,0xE7, +0xBD,0x45,0x65,0xF4,0xD2,0xAF,0xFE,0x2D,0xB6,0xE0,0x64,0x6E,0x01,0x3F,0xE6,0x19, +0xFA,0x8E,0x12,0xE0,0x2E,0x6D,0x81,0xD6,0x61,0xF8,0x7A,0x9E,0x15,0x3A,0xCA,0x8A, +0xF9,0x1A,0x9B,0xAF,0x49,0xD9,0x50,0xE5,0x92,0x90,0x7E,0xEB,0x6B,0x6F,0xCD,0x05, +0xCE,0xA2,0xA2,0xF0,0x52,0x9C,0x28,0x99,0x79,0x61,0x4A,0x6E,0x3A,0x51,0xD8,0x42, +0x94,0xA6,0xEC,0x98,0x04,0x5E,0x59,0xD1,0x0D,0xD7,0x06,0x81,0x7E,0xCF,0x33,0x41, +0x84,0x80,0x9F,0xFE,0xDF,0x42,0xF7,0xF4,0xD5,0xD0,0x97,0x52,0xC6,0xD5,0x1C,0x6A, +0xAE,0x5E,0xBC,0x40,0xA5,0xFD,0xB4,0xEA,0x2D,0x81,0x58,0xCE,0x9B,0x51,0xC3,0xB9, +0xF7,0x70,0x4B,0x63,0xD5,0xD4,0xD3,0x7D,0xD8,0x6D,0xB8,0x5C,0x62,0x76,0x73,0x0A, +0xE8,0xD4,0xFD,0xA0,0xA5,0x5B,0x8E,0x5D,0xBA,0xF0,0x69,0xA6,0x15,0xA9,0xD7,0x10, +0x42,0xDB,0x19,0x5A,0xDD,0x78,0x46,0x3B,0xCA,0x54,0x81,0x34,0xFC,0x71,0x1E,0x22, +0x0F,0x05,0x03,0x94,0x1E,0x50,0xE7,0x78,0xBA,0xA8,0x3D,0xD8,0x10,0x08,0x0F,0x51, +0xCD,0x90,0xCC,0xE8,0x5F,0xD1,0xD8,0xDF,0xD5,0x79,0x22,0x2B,0xB3,0x4D,0xED,0x81, +0x4F,0x75,0xB5,0xD4,0x32,0x31,0xA7,0x73,0xA5,0xF3,0xAD,0x7F,0xF4,0xAF,0xA1,0x1A, +0x26,0x64,0xD1,0xDC,0xC9,0x7C,0xC3,0x5C,0x78,0xD0,0x6D,0x09,0x35,0xB3,0x7F,0xA6, +0xA4,0xA8,0xD3,0xE8,0xEC,0x68,0x46,0x7D,0xDB,0x5F,0xFD,0x63,0xE3,0x86,0x98,0x29, +0x3B,0x27,0x92,0xDE,0x23,0x06,0x8F,0x9F,0xF2,0x65,0x10,0x20,0xB6,0x11,0xA3,0xAC, +0xED,0xF2,0x4D,0xFA,0x9B,0x95,0xE9,0xA3,0x4B,0x31,0xDD,0xE3,0xDB,0x7C,0x9B,0x69, +0xBE,0xFA,0xC0,0x02,0x11,0x3B,0xDE,0x76,0xC6,0xF3,0x85,0x32,0xB3,0xBE,0x11,0x6D, +0xE3,0xC1,0xA2,0x55,0xCE,0x31,0xE8,0x80,0xCE,0x6F,0x18,0x7B,0x13,0xFF,0x61,0xFF, +0x9D,0x56,0xE6,0x89,0x84,0xDB,0xE3,0x86,0xD7,0x1B,0x8F,0xCE,0xC2,0x46,0x73,0x56, +0xC1,0x50,0x33,0xA8,0x4F,0xB4,0xE3,0x4B,0xAF,0x84,0x7D,0x70,0x6E,0x9A,0xB6,0x1D, +0x77,0x5B,0x96,0xFF,0xDD,0x0A,0xEF,0x60,0x0F,0x65,0xE9,0x81,0x35,0xA7,0x5C,0x1B, +0x7C,0xAB,0xC8,0x21,0xB6,0x8B,0x3C,0xE0,0xE3,0xFC,0x02,0x64,0x22,0xA3,0x11,0x97, +0x24,0xCA,0x05,0x78,0x39,0x0A,0x22,0x26,0x97,0x34,0x43,0x5D,0x8E,0xF7,0x1B,0xA7, +0x52,0x40,0xDC,0x04,0xC0,0x0D,0xDF,0x28,0x35,0x68,0x88,0x81,0x8B,0xC2,0xA0,0xA9, +0x08,0x53,0x43,0x68,0x56,0x8E,0x2B,0xC7,0x75,0xE8,0xC6,0x1A,0xA2,0x0C,0x90,0x61, +0x6E,0x27,0xA7,0xC3,0x59,0xAA,0x97,0x9D,0xF7,0x29,0x3A,0xEA,0xF7,0x1D,0x7C,0x52, +0x54,0xE6,0x1F,0x19,0x5E,0xC9,0x2C,0x1B,0x73,0x79,0x84,0x45,0x23,0x8F,0xFF,0x5A, +0x10,0x39,0xF5,0xCF,0xD7,0xD0,0x8C,0xC8,0x55,0x97,0x7C,0x18,0x96,0xD1,0xF7,0x11, +0xF5,0x0F,0x40,0x6C,0x77,0x0E,0x5B,0xD0,0xB1,0xAB,0x4A,0xA5,0x67,0x28,0xCD,0x02, +0xDB,0xD5,0xE1,0x8B,0x1B,0xA1,0xB3,0xBB,0xB9,0xFE,0xF0,0x2E,0x1B,0x12,0xF0,0x49, +0x55,0xFE,0x5D,0x94,0xF4,0x06,0xF3,0x0D,0xD2,0x85,0xB4,0xBA,0x75,0xAF,0x8C,0x27, +0x53,0x0A,0x10,0xE8,0xE7,0x2B,0x7A,0x32,0x05,0x2B,0x77,0x09,0x45,0xDB,0x9F,0x02, +0x6D,0xDA,0xB2,0x13,0x67,0x85,0x7E,0xFD,0xE6,0x44,0x1B,0x23,0xAB,0x8B,0x79,0x68, +0x3D,0x82,0x27,0xFC,0x8A,0x5A,0xC6,0x8F,0x55,0x61,0xEB,0x4A,0xD2,0x6A,0xAE,0xE0, +0x28,0x3F,0x61,0x8D,0x45,0x83,0x3C,0xB4,0xD9,0x44,0x1E,0x6F,0xA5,0xBB,0x5F,0x75, +0x8D,0x5C,0x7B,0x45,0xCC,0xD5,0x5C,0x5A,0x4C,0xAA,0x9E,0x06,0x88,0x48,0xF7,0x0B, +0x7E,0x44,0x06,0xB6,0x4C,0x19,0xFB,0x30,0x3C,0x2F,0x64,0x66,0x48,0xA4,0x67,0x5D, +0x2F,0x73,0x90,0x05,0x9A,0xA2,0xEC,0x22,0x1F,0xA7,0xCA,0xDF,0x51,0x37,0x1F,0x1B, +0x9D,0x60,0xDD,0x1A,0xA1,0x72,0x64,0x9B,0x9C,0xAC,0xD7,0xF7,0x8F,0x60,0xE6,0x19, +0x00,0xDA,0xDA,0x8E,0xA8,0x68,0xC3,0xCC,0xE7,0x2D,0x88,0xD5,0x3C,0x03,0xF1,0xEC, +0x5E,0xE1,0x73,0x2E,0x58,0xB7,0xC5,0x6C,0x47,0x0B,0x9E,0x6C,0x14,0x80,0xCD,0xF6, +0xFA,0xDA,0xBD,0xFD,0x41,0xBA,0xD7,0x5F,0x68,0x57,0x2C,0xD8,0xF0,0x10,0x09,0x85, +0xDE,0x67,0x3E,0xBA,0x5B,0x60,0xC3,0x88,0xB3,0x26,0xF2,0x55,0x77,0x0E,0xEC,0x4F, +0x96,0xA8,0xC7,0x83,0x31,0x1A,0x68,0xFD,0x87,0x7A,0xAA,0xA7,0xF6,0xA7,0x97,0x23, +0x89,0x56,0x09,0x6D,0x3F,0x69,0x44,0x44,0xC9,0x6F,0x45,0x74,0xFE,0x8C,0xED,0xE0, +0x83,0x68,0x47,0x7A,0x76,0xAE,0xFC,0x02,0x0C,0x84,0x63,0x0D,0xC8,0x67,0xAC,0x1B, +0xBF,0x41,0xCE,0xF7,0x8B,0xB0,0xAA,0x99,0x81,0x7E,0x08,0xAA,0x19,0xF2,0x68,0xA4, +0x56,0x8C,0xE8,0xDD,0x19,0x72,0x7C,0x6F,0x4E,0xA4,0xF2,0x4F,0x20,0xC5,0xDF,0xF0, +0x93,0xF7,0xEF,0x7D,0x4D,0xA6,0x33,0x8D,0x26,0xF3,0x9D,0x2D,0xBC,0xEA,0xD5,0x0C, +0x85,0x16,0x48,0x05,0x14,0xAE,0x73,0x2A,0x80,0x2E,0x80,0x47,0x47,0x27,0xF7,0x42, +0x7E,0x8F,0xB0,0x0E,0xE4,0x06,0x4B,0xFF,0xF8,0xB9,0x9D,0x73,0x85,0x89,0xCA,0xDE, +0x9B,0x05,0x56,0x76,0x35,0x98,0x83,0x7B,0xF7,0xEF,0x14,0x4B,0xE1,0x0C,0x2E,0x5D, +0xCC,0x66,0x35,0x3C,0xEA,0x82,0xCA,0x7F,0x34,0xA3,0xF3,0x4B,0x6A,0xA2,0x39,0xBE, +0x20,0xDE,0x7A,0x32,0xDA,0xBB,0x70,0x16,0xEB,0xEA,0xC1,0xCF,0xCD,0xA2,0x4D,0xCF, +0x50,0x0B,0x10,0x77,0x70,0x17,0x57,0xBA,0x71,0xCC,0x6F,0xB4,0xA6,0xEA,0xE9,0x8F, +0xD0,0x78,0xA4,0xBC,0x0A,0x55,0x03,0x85,0x09,0x21,0x9D,0x7B,0xCE,0x6E,0xDC,0x9D, +0x08,0xF2,0x5F,0x62,0x70,0x27,0xAD,0x2B,0x28,0x84,0x8E,0x20,0xB7,0xE5,0x8F,0x5C, +0xBA,0x90,0x31,0xF2,0x3A,0x96,0x75,0x00,0x53,0x74,0xC6,0xCA,0x0B,0x28,0x3E,0xA4, +0x6E,0x10,0x02,0x02,0x86,0x25,0x60,0x84,0xBB,0x0F,0x6C,0x7A,0x95,0xE0,0x45,0x48, +0xEE,0x23,0x0A,0xFA,0xEB,0x93,0xB9,0x5C,0x19,0x37,0x50,0xD2,0xF4,0x5B,0xF3,0xCF, +0xAA,0xDE,0x4A,0x1A,0x08,0x6F,0xCA,0x4E,0xF8,0x7E,0x3E,0x01,0xCD,0x0B,0x71,0x81, +0xBB,0xF0,0xE3,0x12,0xAB,0x0A,0x97,0xF1,0x65,0x88,0x8F,0x3B,0x7F,0xEF,0xC8,0x5C, +0x76,0x52,0xEB,0x69,0x7E,0x56,0xB3,0x1E,0xD2,0x3F,0x3E,0x6E,0x43,0x42,0xE5,0xBB, +0x19,0x15,0x1B,0x9F,0x19,0x8F,0x36,0xCA,0x70,0xEE,0xD6,0xEB,0x1C,0x6A,0xD6,0x25, +0xDE,0xF7,0x43,0x1B,0xFC,0xE7,0x6E,0xC2,0x96,0x6F,0xA4,0xB3,0x66,0x86,0x2E,0x69, +0x07,0x25,0x4C,0xDC,0x15,0xF3,0xA7,0xBD,0xDF,0x00,0x08,0x02,0xEB,0x7B,0x8C,0xC3, +0xEC,0x81,0xF7,0x6F,0x65,0xA1,0x4F,0x87,0x8A,0x8F,0x86,0x31,0x4B,0xD1,0x7A,0xEC, +0xE3,0x00,0x76,0xB0,0xD8,0xB7,0x9C,0x92,0xCE,0x59,0x79,0x00,0x27,0xAD,0x9B,0xED, +0xFD,0xC4,0x89,0xEA,0x92,0x17,0xE7,0xD1,0x01,0xD8,0xC7,0x40,0x7F,0xF5,0xC6,0x36, +0xE6,0xF6,0xFE,0x2C,0x82,0x3E,0xE3,0xBE,0x3F,0x53,0xA9,0x15,0xB6,0xB3,0xA6,0x9F, +0x24,0x2E,0x9E,0xD4,0xD8,0x7D,0x52,0xB6,0xB1,0xE2,0x58,0x03,0xD9,0x2D,0x34,0x2E, +0x6B,0x9F,0x82,0x7B,0xD5,0x42,0x4D,0x4D,0x6D,0x7D,0x4D,0x2A,0x73,0x1B,0xDF,0x3C, +0xC7,0x2B,0x3C,0xB9,0xD7,0xF3,0xF9,0x91,0x0B,0xC8,0x27,0xA5,0x2C,0x1F,0xD0,0xEC, +0x9A,0xB3,0x64,0x9D,0x55,0x77,0x5E,0xB1,0x5C,0x32,0x17,0x1C,0x14,0x51,0x4F,0x3F, +0x4D,0x40,0xB4,0x3E,0x32,0x00,0x02,0x4C,0x56,0x7D,0x6A,0x60,0x0E,0x5B,0x9D,0x3F, +0xDD,0x94,0x27,0x14,0xE1,0x4A,0xCF,0xED,0x7D,0x67,0x6D,0x32,0x7D,0xEF,0x02,0xC9, +0xEA,0x49,0x85,0x3D,0xCA,0xBC,0xC7,0x14,0xB3,0x58,0x57,0x7E,0xBB,0x80,0x84,0x00, +0xA1,0x4F,0x39,0x7F,0x0E,0xB4,0xD1,0x70,0x2C,0xCA,0x56,0xF3,0xA5,0x85,0x46,0x48, +0x12,0x23,0xD1,0x88,0x29,0xCA,0x00,0xF0,0xD7,0xC6,0x74,0x29,0x33,0x36,0x17,0x52, +0x0A,0x46,0xE3,0xB7,0x4D,0xAE,0xD0,0x91,0xD9,0xCE,0x41,0x77,0x38,0x78,0xB5,0x0E, +0x34,0x78,0xDA,0x2E,0x70,0x4A,0x4A,0x2A,0x85,0xF6,0x34,0x61,0x8B,0x43,0xC2,0xB2, +0x00,0x08,0xC9,0x96,0xD5,0x15,0x31,0xEC,0xC8,0x6D,0xE7,0x4E,0x89,0x60,0xF9,0xC6, +0xE9,0x77,0x2C,0x2E,0xE2,0xA0,0x02,0xB9,0x76,0xB5,0xF9,0xB1,0xE1,0x90,0xB0,0x82, +0xCD,0x53,0x22,0x3D,0xF1,0xEA,0x94,0xF7,0x14,0x56,0xA8,0xEA,0xE6,0x52,0x33,0xD5, +0xEA,0x80,0xD3,0x55,0x02,0xBA,0x32,0xE3,0xCD,0xC0,0xDF,0xFC,0x0D,0xFF,0x9D,0x2A, +0x86,0x50,0xE9,0xAD,0x8D,0xF9,0xB9,0xE3,0x48,0x6F,0x5A,0xC0,0x47,0xD8,0x3A,0x96, +0x04,0x61,0xE3,0x41,0xE1,0x3A,0x20,0x3B,0x85,0x2D,0x62,0x60,0xBD,0xF9,0xF3,0x24, +0x99,0x78,0x52,0xA2,0xC0,0x4D,0xDD,0x7B,0x5E,0x29,0x5A,0xCB,0x87,0x6F,0xAF,0xBA, +0x38,0x56,0xD1,0xDB,0xB8,0xC9,0x91,0x87,0xC3,0x0F,0x8C,0x52,0x6C,0x6D,0xBF,0xF4, +0xA2,0xD8,0x7D,0x06,0x62,0xE0,0x0E,0xA5,0xA0,0x52,0xF1,0x2E,0x10,0x19,0xBD,0xEA, +0x1E,0x3E,0x87,0xA6,0x67,0xBE,0x2C,0x0B,0x13,0x88,0xD0,0xA9,0x53,0x42,0x43,0x6B, +0xC0,0xB4,0x1D,0x90,0xA9,0xC0,0xA9,0xA1,0x4A,0x42,0xB1,0x83,0x1A,0xDD,0x93,0x9C, +0xD7,0xC3,0x5A,0x5F,0x68,0x53,0xA2,0xC9,0x37,0xC6,0x77,0xBB,0x4E,0xF5,0x87,0x53, +0xB1,0xF4,0x8E,0x32,0x89,0xD1,0x53,0x85,0x99,0x87,0x5A,0x29,0x55,0x5B,0x39,0x0C, +0x59,0xE3,0x33,0xA7,0xFA,0x23,0x14,0x6D,0x9C,0x08,0xDC,0x97,0x6B,0xCD,0xC0,0x4B, +0x38,0x1E,0xE5,0xC2,0xB4,0x4A,0x19,0x07,0x08,0x86,0x5C,0xDA,0x7E,0x0A,0xA3,0x8E, +0xD5,0x77,0xCB,0xE5,0xF2,0x41,0x75,0x26,0x90,0x6F,0xF9,0xF0,0x98,0x15,0x9B,0x07, +0x30,0xA9,0xFB,0xF1,0xEE,0x09,0xA0,0x28,0xE0,0x56,0xE3,0xD4,0xCA,0x95,0xA1,0xBB, +0x71,0xA0,0x55,0xA0,0x62,0x1E,0xEF,0x42,0x55,0x76,0xAD,0xDF,0xB6,0x62,0xBE,0x14, +0xA3,0xA3,0xB7,0x60,0xD4,0x10,0xDB,0xCC,0x47,0x22,0x10,0xA7,0x9D,0xB9,0xA3,0x44, +0x11,0x2C,0x34,0xB8,0xFD,0xE9,0x26,0xFD,0x3D,0xEB,0x11,0x9F,0x15,0x55,0xF2,0x5C, +0xF5,0xA4,0x80,0x9A,0xFD,0x47,0x4A,0x1C,0x0E,0xC9,0x8D,0xF1,0xC4,0xE2,0x5E,0x25, +0x42,0xA2,0x3A,0xB7,0x17,0xDD,0x4B,0xD3,0x47,0xA2,0xA7,0x51,0x84,0xF6,0x9D,0x1C, +0x50,0x42,0x1F,0x83,0xC2,0xE4,0x37,0x13,0x5B,0xD1,0xFB,0x67,0x48,0xBE,0xFB,0x2E, +0x88,0x2A,0xAA,0xEA,0x2A,0x06,0x53,0xC8,0x55,0x5C,0x34,0x8F,0xC9,0x58,0x68,0xC4, +0x40,0x23,0xBD,0x1D,0xB9,0xF3,0x01,0x47,0x9A,0xD7,0xC1,0xD0,0xE5,0x37,0x48,0xA8, +0x4E,0xD5,0x84,0xF9,0x70,0xAB,0x3E,0xB0,0x8D,0x8B,0x74,0x73,0x93,0xE4,0x35,0xD1, +0x53,0x05,0xA3,0xA4,0x65,0x02,0xCD,0x9F,0x86,0xB9,0x7E,0x45,0xD8,0xB7,0x41,0xF1, +0x03,0xFD,0xD0,0x57,0x61,0x7A,0x24,0xC3,0x26,0x96,0x6F,0x0D,0x80,0xCA,0x06,0xA0, +0x28,0x44,0x0D,0x52,0xF2,0x8C,0xFE,0xF4,0x43,0xA2,0x81,0x77,0x70,0x9F,0xD4,0xD6, +0x42,0xFC,0xE2,0xCD,0xD3,0xD1,0x2E,0x67,0xB5,0x31,0xD1,0x3B,0xE3,0x21,0x88,0xDC, +0xAC,0xA6,0xBD,0x26,0xF8,0xCB,0x74,0x87,0x9C,0x51,0xE4,0x58,0x1D,0x84,0xAC,0xF2, +0xA2,0xE1,0x7F,0xC1,0x63,0xB1,0xA8,0x70,0xA6,0xFA,0x9F,0x26,0x2D,0x64,0xA6,0xDE, +0x67,0xFA,0xA2,0x3F,0x1D,0x74,0xDD,0xD8,0x43,0xA0,0x65,0x00,0x7D,0x80,0xB4,0x9F, +0x19,0xC9,0x85,0x48,0x6E,0x76,0xBA,0xCC,0x9B,0x13,0xE1,0x28,0x96,0x50,0xF0,0x73, +0xD2,0xB4,0x5E,0xB9,0x63,0x48,0x4C,0xBC,0xF0,0x66,0x5C,0x85,0x64,0x6B,0xB0,0x7F, +0x8D,0x0F,0xA7,0x8A,0x04,0xA9,0x72,0x92,0xE0,0x9A,0x29,0x04,0x49,0x33,0x8B,0x91, +0xC2,0x2A,0xE1,0xA1,0xAA,0xEE,0x4B,0x39,0x19,0x2A,0x2A,0x72,0x99,0xE1,0xCB,0xEA, +0xBD,0x63,0x1A,0x49,0x04,0xD2,0xE2,0x0E,0xB7,0xCF,0x90,0x80,0x98,0xD3,0x36,0x1E, +0x1C,0xAC,0xA2,0x46,0x4F,0x66,0x04,0x5F,0x06,0x16,0x65,0x7F,0x8F,0x88,0xF8,0xBD, +0xF6,0xD5,0x8A,0x3A,0xF1,0x10,0x1E,0xEE,0x46,0xDD,0xBF,0x05,0xAC,0x9F,0xEF,0xE1, +0xD9,0x73,0xDC,0x49,0x09,0x74,0x8F,0x6D,0x2B,0x26,0x24,0x9F,0x59,0xD9,0x37,0x88, +0x50,0x51,0x49,0xD6,0xC9,0xA6,0x5F,0x62,0xB6,0xC1,0x2E,0xCC,0xF7,0x47,0x91,0xA6, +0x86,0xB5,0xB7,0x30,0x6F,0x73,0x3B,0x98,0xE7,0x39,0xF4,0xE2,0x94,0xDD,0x71,0xB5, +0x55,0x3E,0xAB,0xA3,0xB5,0x63,0xF1,0x62,0xD3,0xCE,0xD2,0xAB,0x4D,0x12,0xF3,0xA8, +0x2E,0x14,0x1D,0x57,0x1E,0xEC,0x14,0xE7,0xC3,0xBA,0xFF,0x83,0x93,0xF3,0x03,0xC3, +0xD7,0x54,0x96,0x56,0x15,0x51,0xDD,0x4D,0x21,0xB8,0x3E,0x88,0xBD,0xCF,0xB3,0x80, +0x85,0x78,0x2F,0x3A,0x3E,0xBF,0xCC,0x23,0xD6,0xBD,0xA7,0x1D,0xDC,0xDD,0x2E,0x64, +0xDB,0x42,0x20,0xD5,0xBF,0x10,0x1E,0x6D,0x95,0x0A,0x53,0xBF,0x18,0x9C,0x73,0xAF, +0xC9,0x52,0x47,0x10,0x65,0xC5,0x65,0x16,0x94,0x3A,0xDA,0xA8,0xA0,0x56,0x02,0xD7, +0xD9,0x8A,0x55,0xBE,0x24,0x07,0x6B,0x3E,0x98,0x35,0xEB,0x7E,0x82,0xE6,0x50,0x58, +0x21,0xB5,0xEA,0x3E,0x04,0xF2,0x4D,0x7F,0x5B,0xC5,0xF5,0x6F,0x13,0x8F,0xDE,0x72, +0xB4,0xBD,0xA0,0x18,0xEC,0xA2,0x56,0x42,0xE9,0xDA,0xDE,0x17,0x75,0x31,0xC5,0x08, +0x45,0x41,0x79,0xA4,0x63,0x2E,0x0B,0xBB,0x48,0xFB,0xEC,0x18,0xCC,0xF8,0x5B,0xDE, +0x23,0x7A,0xD4,0xE8,0x1D,0xDE,0x77,0x87,0x9C,0xE9,0xD8,0x62,0xF5,0xDA,0x53,0xAC, +0x61,0x8E,0x6B,0x28,0x06,0x5C,0xD6,0xDF,0x51,0x97,0x13,0x21,0xC9,0xCA,0x11,0xE6, +0x81,0x6F,0x2A,0x03,0x26,0x91,0x59,0x80,0xD2,0xB5,0xFD,0xEC,0xD7,0xEC,0x94,0xE4, +0xB6,0x37,0x60,0xE8,0x89,0x22,0xC8,0x5A,0x3B,0x01,0xBD,0xB2,0xED,0xDE,0x8A,0x95, +0xCA,0x34,0xB4,0x8A,0x37,0x94,0xE1,0x50,0x8B,0x84,0xEE,0x14,0xB4,0xFF,0xD7,0x74, +0x9D,0x30,0xBB,0xEF,0xA4,0x2D,0xE4,0x9F,0x97,0x9C,0x7D,0xE7,0xED,0x0B,0xA6,0xCB, +0xBF,0x65,0x4E,0x1D,0x8F,0xCF,0x21,0xE8,0xEB,0xF1,0x74,0x2B,0x09,0x68,0x66,0x68, +0xBB,0x0F,0xA8,0xEF,0x34,0xE2,0xE4,0xF6,0x78,0xF0,0x7B,0x9B,0x00,0x90,0x10,0xE2, +0xE4,0x15,0x99,0xAF,0x8D,0x88,0x76,0xE4,0x0E,0x9F,0xD8,0xAB,0xAD,0x82,0x33,0x5A, +0x9E,0xC4,0x94,0xDE,0x61,0x61,0x20,0x53,0xCA,0xD1,0xC1,0x94,0x14,0xE4,0x9C,0x1B, +0x15,0x73,0x8F,0x7A,0x43,0x19,0xED,0xA4,0xFA,0x59,0x9E,0xB9,0x11,0x64,0xD7,0x3C, +0x18,0x1A,0x9B,0x2C,0xA6,0x30,0x9E,0xF3,0xC2,0xC0,0x02,0x1B,0x37,0x0D,0x0C,0x41, +0x28,0x2F,0xFA,0x59,0x95,0x2B,0x67,0x0D,0x8A,0xB0,0xEC,0xFE,0xC5,0xA6,0x87,0xC7, +0xDA,0x6E,0x9B,0xAF,0xE3,0x31,0xD1,0x7E,0xC5,0x86,0xF8,0x42,0x8C,0xBC,0xF4,0x43, +0xA1,0xBE,0xBE,0x72,0xD8,0x6E,0x80,0xF4,0x59,0x5B,0x5D,0xB7,0x76,0xA0,0x42,0xC5, +0xD9,0x00,0xF4,0x80,0x11,0x20,0x89,0x75,0x24,0xB8,0x7F,0x91,0x84,0x0C,0x92,0xA1, +0x68,0x38,0x17,0x52,0x7C,0x05,0xC7,0x13,0x2B,0xDB,0x63,0xCB,0xD0,0x40,0xB0,0xAF, +0x6C,0x98,0x7F,0x86,0x4F,0xA6,0xEB,0x4A,0x3E,0x0F,0xAC,0x8D,0x42,0x3D,0xFB,0x65, +0x05,0xC9,0x2F,0x81,0xF2,0x36,0x91,0x07,0xF7,0xE5,0xF2,0x6B,0x70,0x44,0x41,0xE0, +0x5B,0x0B,0x67,0xEE,0x03,0x5D,0x8A,0x3E,0xB3,0x91,0x97,0xF2,0xDB,0x5B,0x8B,0x7B, +0xA9,0x9B,0xE2,0x46,0x62,0x43,0x0A,0x15,0x22,0xB8,0x93,0xD5,0xFD,0xB1,0x76,0x74, +0x7A,0xCF,0x5A,0x49,0xFF,0xDD,0xBB,0x21,0x68,0xD8,0xA2,0xD5,0x27,0xDB,0x19,0x78, +0x40,0x74,0xE0,0xD0,0x0B,0x2D,0xB5,0x2F,0xE9,0x56,0xC7,0x43,0x8D,0x09,0xA8,0x3B, +0xC8,0x33,0xA3,0x93,0x47,0x17,0x79,0xE3,0x79,0x2D,0x14,0x69,0x88,0x91,0x8E,0xB0, +0x68,0xFA,0x5B,0x1A,0x94,0x6F,0xED,0xFA,0x3B,0x4B,0xF0,0x69,0xD6,0x26,0x35,0x42, +0x95,0x4A,0xB6,0x84,0x7B,0xEB,0xF8,0x18,0x42,0x07,0x09,0x79,0x9C,0x99,0x33,0xB8, +0xD8,0x72,0xB1,0x73,0x42,0x15,0xFF,0xBE,0x2D,0x22,0x96,0xAC,0x0D,0x92,0x86,0x7E, +0x8E,0x4A,0xA4,0xE9,0x6F,0xB2,0x84,0xA6,0x85,0x73,0x38,0xBD,0x10,0xC9,0x91,0x8A, +0x82,0x0A,0x6A,0x19,0xEB,0x90,0x8A,0x50,0x8C,0xC1,0xA3,0xB7,0x36,0x5D,0x43,0x9B, +0x3D,0x3F,0xD8,0x50,0x53,0x29,0x70,0x9C,0x23,0x12,0xF0,0xBB,0x01,0x94,0xDD,0x73, +0xA0,0x38,0xA1,0x93,0x89,0x91,0xD2,0x7E,0x99,0x1F,0xD4,0xEB,0x15,0xA8,0x04,0x3F, +0x48,0xC0,0xAF,0x1D,0x3F,0x14,0x12,0xD6,0xD0,0xAB,0x3E,0x16,0x9E,0x0C,0x9D,0x2F, +0x43,0x66,0x53,0x78,0xE8,0xEB,0x70,0x62,0xC0,0x98,0xCA,0x48,0xBD,0x59,0xA0,0xA9, +0x72,0xA7,0x6F,0xA2,0xE2,0xF7,0xF8,0x68,0xCD,0x2C,0x83,0x6E,0xFB,0xE5,0x2F,0xA7, +0x9E,0xE1,0xD8,0x7E,0x13,0x21,0x3D,0x69,0x0E,0x22,0x2E,0x9A,0xF8,0x70,0x4B,0x4E, +0x8B,0xC6,0x0C,0xD4,0x0F,0xC7,0xB6,0x99,0x05,0xE7,0x74,0x35,0x88,0xF9,0xA5,0x0F, +0x4A,0xC4,0xB0,0x70,0x84,0x0E,0xB9,0x8E,0x7B,0x64,0x2D,0x69,0x99,0x4F,0x52,0xA2, +0x67,0x4D,0x26,0x91,0x28,0x95,0xF7,0xF9,0x87,0xBE,0x69,0x6E,0x2E,0xB2,0xE6,0x7F, +0x43,0xE8,0xFB,0x62,0x7C,0x9E,0xFB,0x58,0x14,0x37,0x01,0x06,0xFB,0x0E,0xFF,0x54, +0xE0,0xA7,0xA7,0x38,0xF2,0xA1,0x8E,0x68,0x0B,0x9D,0x21,0xB8,0xD5,0xA8,0x0E,0xD9, +0xDA,0x51,0x3D,0x40,0x28,0xEC,0xFE,0x1E,0x15,0x06,0x95,0xBC,0x76,0xE5,0x9F,0x2F, +0xF2,0xC9,0x81,0x76,0x88,0x88,0xC9,0x40,0x36,0xF8,0x13,0x47,0x31,0xE5,0xE7,0x15, +0x6C,0x7B,0xE4,0x85,0xA6,0x75,0xE9,0xFC,0x5D,0x8D,0x67,0x02,0xEA,0x4B,0x8D,0xCF, +0xA6,0x6C,0x01,0x95,0x8C,0xB3,0xB1,0xB3,0x79,0xFC,0x4B,0xCE,0xF4,0x29,0x92,0x34, +0xFF,0x84,0x7F,0xC8,0x01,0x35,0xC2,0x18,0xDD,0x30,0x64,0x6A,0xFF,0xB9,0xD3,0x2C, +0xD1,0xBA,0x9F,0x00,0xC8,0x8B,0x10,0x83,0x85,0x5C,0x28,0xD0,0xAD,0xBA,0x17,0x10, +0x80,0x10,0x90,0xD7,0x1A,0xC1,0xF7,0x8D,0xE5,0xA3,0xE2,0x0C,0xD7,0x2D,0x5C,0x48, +0x26,0x27,0x6C,0xF1,0xD9,0x54,0xD4,0xAA,0xBD,0x46,0xEB,0x0B,0x70,0x8F,0x25,0xC8, +0xC7,0xC1,0x6E,0x7A,0x24,0xBE,0xA8,0xBF,0x57,0xBD,0x93,0xA8,0xA4,0xAF,0x68,0xD4, +0xD1,0xF8,0xE8,0x9D,0x01,0x1E,0xEF,0xE1,0xE7,0x22,0x18,0x18,0xD9,0x5A,0x43,0xEC, +0xA1,0x5F,0x93,0x3A,0xE9,0x63,0x12,0x45,0x64,0xF3,0x19,0x16,0xAD,0x9F,0xF8,0x51, +0x1A,0x95,0x14,0x67,0xC5,0x83,0xEB,0x8A,0x39,0x44,0xC3,0x2A,0x53,0xD5,0x86,0xE6, +0xE1,0xC7,0x16,0xF2,0xEB,0x24,0xE9,0x90,0xEF,0x74,0x3A,0x01,0xE9,0xFC,0x73,0x10, +0xB8,0xF7,0xB3,0x75,0xB6,0x3A,0xD6,0x32,0x62,0x2B,0x41,0xB0,0x09,0xF3,0xE9,0xAD, +0x9F,0xD1,0x0D,0xCF,0xF1,0x2B,0x1E,0x5E,0xCE,0x01,0xC3,0xF9,0xAC,0x79,0xA5,0x91, +0x3B,0xA2,0x11,0xEE,0xD9,0x00,0x6A,0x22,0xB2,0xBD,0xE2,0xE7,0xB1,0x5B,0xDD,0x65, +0x88,0x11,0x8A,0x15,0x2D,0x87,0xA7,0xDC,0xD0,0x76,0x61,0x1B,0xD7,0x6C,0x01,0xCA, +0x30,0xFA,0xD1,0x37,0xB8,0xB2,0x83,0x7E,0x5F,0x44,0xAA,0x68,0xE7,0x8E,0xA0,0xDD, +0x82,0x63,0x80,0xA6,0x73,0x4E,0xDB,0x20,0x0B,0xBF,0x9B,0x04,0xF4,0xEB,0xF1,0x5B, +0xE1,0x3C,0x06,0xD6,0xDA,0xE3,0xF6,0x39,0x18,0xB1,0xFC,0xE7,0x30,0xED,0x5E,0x26, +0x13,0x9A,0x37,0x7C,0xD2,0x1D,0xE5,0xF2,0x87,0x45,0x39,0x3C,0xD0,0xCE,0x08,0x5E, +0x99,0x91,0x9E,0x0B,0x21,0x0C,0x44,0xAB,0xBA,0xF9,0x2D,0x12,0xAD,0xEE,0x0F,0xD8, +0x72,0x24,0x70,0x22,0x49,0xBD,0x38,0xA9,0x72,0x02,0x74,0x9E,0x11,0x02,0x49,0xFE, +0x9B,0x58,0xC8,0xB8,0x9F,0xEC,0xDA,0x78,0x8E,0x04,0x42,0xF3,0x62,0xE5,0x84,0x19, +0x6C,0xA0,0x65,0x9C,0x5D,0x75,0xB4,0x92,0x41,0xF5,0x13,0xB7,0xFF,0x91,0xDC,0x27, +0x6A,0xFF,0xA9,0x20,0x09,0xC1,0x6A,0x3A,0x7C,0xA5,0x1A,0xA9,0x03,0xA0,0xC2,0x46, +0x70,0x81,0x48,0xDE,0x72,0x7A,0x89,0xAE,0xC4,0x4B,0x67,0x5C,0xE3,0xE5,0x22,0x07, +0xAD,0xB5,0x0C,0x98,0x84,0x94,0x06,0xA0,0x32,0x40,0x38,0x4A,0xD9,0x60,0xC4,0x55, +0x3B,0x5D,0x59,0x08,0x20,0x90,0xF0,0x7B,0xFF,0x66,0x71,0xFC,0x79,0x66,0x56,0xAE, +0x08,0x74,0x03,0x95,0x23,0xCE,0xCD,0x88,0x33,0x7B,0x09,0x44,0x0C,0x3C,0x06,0xCB, +0xFF,0xAE,0x8B,0x07,0x18,0x05,0xE8,0x28,0xF6,0x0D,0xC9,0xCD,0xE7,0x6E,0xCF,0x80, +0x33,0xF8,0x25,0x4F,0xAD,0x2B,0xF2,0xB4,0xFD,0x47,0x68,0x0D,0xCC,0x67,0x75,0xF5, +0xED,0x80,0x17,0x45,0x81,0x47,0xC9,0xF5,0x00,0x4A,0x5C,0x00,0x63,0x95,0xBC,0xBE, +0xA2,0xA4,0xC3,0x53,0x9C,0xA2,0xC3,0x60,0x14,0xCE,0xDA,0x9B,0xB2,0x3D,0x3C,0x8E, +0xA1,0x38,0x69,0x6F,0xD1,0xD0,0x02,0xFD,0xE2,0xA9,0x73,0x1E,0x3E,0x8C,0x64,0xE3, +0xAA,0x0A,0xF2,0x70,0xEA,0x87,0x26,0x12,0x79,0x32,0x52,0x06,0xAB,0x46,0xE4,0xBE, +0x8E,0x14,0x94,0x85,0xF7,0x91,0x6E,0x9B,0xB6,0xB1,0x1F,0xCC,0x88,0xC9,0xD0,0x94, +0x0B,0xA8,0xB5,0xA8,0x01,0x86,0x56,0xF2,0x3E,0xD8,0xAA,0x37,0x8C,0xD1,0xC9,0x4E, +0xFE,0x53,0x5C,0xD3,0xBA,0x57,0x94,0x3D,0x63,0x0B,0x12,0x0D,0x28,0x45,0xA5,0x1D, +0xF3,0x6A,0x7D,0xF0,0x96,0xD6,0x3F,0x93,0xF8,0x94,0x19,0xAB,0x13,0x52,0x34,0x03, +0x6C,0x7D,0xD5,0x67,0x31,0x56,0x18,0xBC,0xE1,0x7B,0xB0,0xAE,0x0D,0x9C,0xEE,0xF7, +0xD7,0x40,0xB0,0x8E,0x8F,0xA8,0x06,0x2A,0x9E,0x1A,0x07,0x1E,0xB3,0x94,0x97,0xE7, +0x4D,0x83,0x10,0x4C,0xF4,0xD6,0x19,0xD6,0x45,0x0C,0x58,0x70,0xED,0x3C,0x0F,0xE5, +0x44,0xE9,0x27,0x1D,0xCD,0x12,0xD1,0x7A,0xD8,0x0F,0x3F,0xE5,0x1B,0x1F,0x90,0x84, +0xE2,0xC8,0xAB,0xC6,0x70,0xDE,0xA6,0x65,0x0E,0xDB,0x90,0x96,0x64,0xB8,0xBD,0x6A, +0x94,0x9C,0x27,0x95,0x39,0x2B,0x32,0x8F,0xD1,0x5E,0x35,0x0E,0x27,0x42,0xF4,0xDD, +0x7F,0xA1,0xA9,0x91,0x79,0xD5,0xC0,0xB3,0x56,0x69,0x15,0x5E,0xA3,0xB3,0x9F,0x0F, +0x31,0xDD,0x66,0xC5,0xF4,0x3D,0x03,0xDA,0xBD,0x64,0x44,0xED,0xE0,0x8E,0x4C,0x63, +0x81,0x1F,0x7E,0xC5,0x7D,0xC8,0x54,0xE1,0x0C,0xF0,0x37,0x13,0x8F,0x80,0x9C,0x70, +0x9C,0x39,0x48,0x22,0x0F,0x20,0x12,0x55,0x76,0x0A,0x5C,0xF9,0x2B,0x6E,0xC3,0xBE, +0x20,0x17,0x77,0x2F,0x52,0x6B,0xFF,0x9F,0xBC,0x83,0x3F,0xBC,0xA0,0x5F,0x01,0x65, +0xFC,0xB0,0xE4,0x1E,0x09,0x79,0x9B,0xC8,0xE0,0xB5,0xE7,0x41,0x59,0x81,0xD9,0x80, +0x9A,0x8C,0xE1,0x0F,0xB3,0x30,0x02,0xD6,0x56,0x09,0x3C,0x35,0x06,0xA6,0x4D,0x7A, +0xA3,0xB1,0x00,0xE7,0x1A,0xA5,0xF0,0x9D,0x99,0x88,0x06,0xB8,0xFB,0xAF,0x30,0x1D, +0x7B,0xB2,0x10,0x0A,0x28,0x99,0x35,0x8C,0x0B,0xFF,0x9E,0x29,0x89,0xA6,0x0C,0x9E, +0xB1,0xDE,0x36,0x2E,0x23,0x44,0x9D,0xE3,0x4E,0xB7,0x91,0x1E,0xDE,0x31,0xDB,0x22, +0x22,0xB1,0x64,0x5E,0xF3,0x8E,0x8A,0x22,0x24,0xEC,0x58,0xBD,0x35,0x3C,0x67,0x0F, +0x1C,0x6B,0xD2,0xFE,0xC9,0xD4,0x09,0x13,0x59,0xF1,0xB3,0x7D,0xC4,0x41,0xAC,0xA3, +0x96,0xDB,0xBC,0x3E,0x23,0x03,0xAC,0x44,0xFC,0x1D,0x26,0x58,0x59,0x6A,0x5F,0x44, +0x29,0x1D,0x1A,0xE7,0x49,0xB4,0xA7,0xCF,0x93,0x1B,0x83,0x21,0x1C,0x7C,0x20,0x26, +0x01,0x23,0x26,0xE9,0xE2,0x6C,0x21,0x2B,0x31,0x42,0xC6,0x25,0x24,0x90,0xC3,0x4D, +0x07,0x7C,0xEB,0x6D,0x9B,0xA0,0x46,0x13,0x9B,0xD8,0x23,0xB1,0x51,0x43,0x56,0xC7, +0x51,0x9C,0x97,0xE2,0xAB,0xB3,0x15,0xF1,0x20,0xC5,0x83,0xFC,0x9B,0x32,0xB6,0x66, +0xDA,0x5D,0x4C,0x3D,0xAB,0xBB,0x61,0x29,0x07,0xFE,0x37,0x9B,0x39,0x59,0xD2,0x26, +0xA4,0xEA,0x08,0xFC,0xD8,0x95,0xE8,0x4C,0xDC,0x10,0x82,0xA9,0x80,0x1C,0x58,0xDE, +0x32,0x53,0x2B,0x12,0x0E,0x85,0x26,0xEC,0x42,0xE4,0x37,0xAA,0xB9,0x57,0x49,0xC3, +0x83,0xEE,0xD4,0x31,0xAC,0xA2,0xCD,0x32,0xA4,0x1A,0xBC,0x69,0xF3,0xA9,0x26,0x5C, +0x70,0xFB,0xC1,0xD2,0x1C,0xD1,0x32,0xFD,0x52,0xBF,0xBA,0xBE,0xD0,0xF1,0xA4,0xE2, +0xC8,0x73,0x59,0x46,0x21,0x9C,0x94,0xD6,0xAF,0xF1,0x86,0x7E,0xC5,0x16,0x85,0x85, +0xA5,0x32,0x8E,0x08,0x29,0x9E,0x31,0x02,0x34,0x5D,0x18,0x53,0xFD,0xB9,0x3A,0x65, +0xD1,0x03,0x78,0xB1,0x70,0xA5,0xFC,0x4A,0x33,0x9B,0x7B,0xAE,0x49,0xCC,0x40,0x5F, +0x30,0x84,0xF5,0x1D,0x3D,0x5B,0x20,0xC2,0x6B,0xE9,0x0E,0x17,0x96,0xC4,0x3B,0x24, +0x0E,0xE4,0x19,0x6D,0xB7,0x44,0x42,0xE4,0x82,0xEE,0x60,0xE5,0x91,0x62,0x11,0x71, +0x52,0x30,0x6F,0x22,0xEE,0xFA,0xEA,0x9B,0xBD,0xD4,0x47,0x9B,0xA7,0xC2,0x02,0xB2, +0x4A,0xC3,0x79,0x37,0xB5,0x34,0x1E,0x8C,0x75,0x99,0x92,0x29,0xDE,0x64,0x22,0x56, +0xF9,0xFA,0x40,0xB6,0xBE,0x77,0x20,0x45,0x00,0x1C,0x17,0x8A,0xA2,0xA6,0xB8,0x3B, +0xA8,0x9C,0xA0,0x9B,0x51,0x7C,0x32,0x8D,0x66,0x15,0xEF,0xF8,0x7D,0x87,0x33,0xB2, +0xD0,0x68,0x57,0xB1,0x82,0x16,0x94,0x4B,0x13,0xAA,0x12,0x68,0x16,0x32,0x48,0x2C, +0xDF,0x86,0x82,0xEE,0x72,0x88,0x22,0x20,0x84,0x8D,0xC6,0x17,0xD1,0x2F,0xEA,0x03, +0xEC,0x75,0x79,0x0A,0xAB,0x02,0xE3,0xB8,0xCC,0x33,0x31,0x32,0x91,0x7A,0xFE,0xA1, +0xB6,0xF7,0x00,0x0E,0x55,0xDE,0xB0,0x87,0x48,0x5E,0xAE,0xC7,0x9C,0x4C,0x3D,0xE2, +0x7E,0xAF,0xAD,0x53,0xB5,0xF0,0x13,0x4E,0x00,0x9B,0x4B,0x27,0xE4,0xF3,0x54,0xD0, +0x4A,0x94,0xDE,0x45,0xB7,0x0D,0x6B,0x3E,0x55,0xF1,0x44,0xC6,0x0A,0x99,0xAF,0x48, +0xF8,0x33,0x32,0xF5,0x64,0xE3,0x92,0xE8,0x91,0x31,0x3D,0x1E,0xD8,0xE9,0x28,0x7D, +0x41,0xE1,0x11,0x3C,0x52,0xC5,0xA2,0x38,0xC6,0x67,0x0F,0xBC,0x0B,0x62,0x70,0x32, +0x3E,0xA9,0x00,0xCD,0x03,0x3C,0x00,0x45,0xB7,0xB8,0x95,0xE6,0x72,0xD2,0xFF,0x77, +0xEC,0x7C,0xB7,0xB3,0x42,0x8E,0x25,0xFE,0x1F,0xE5,0x77,0xDA,0xFF,0x2D,0xD4,0x9B, +0x58,0x53,0x60,0xB1,0x78,0x42,0xED,0x98,0xD5,0xA8,0xA8,0x66,0x45,0xDE,0xF5,0x11, +0xCD,0x60,0x03,0xA4,0x93,0xC0,0xCE,0x95,0xF6,0xCB,0x5A,0x80,0x51,0xF5,0xFE,0xB1, +0xB2,0xBC,0x68,0x80,0x30,0x70,0x39,0x66,0xBD,0x92,0x5B,0x7B,0x2E,0x22,0x9B,0x1B, +0x05,0x23,0x29,0xD6,0xC2,0xA2,0xEC,0x36,0xFB,0x46,0xB9,0xD8,0x87,0x6E,0x9A,0xBA, +0x92,0xCF,0x63,0x46,0xE0,0xD9,0x28,0xB4,0xBC,0x31,0xEE,0x5F,0xAF,0x30,0x0E,0xDB, +0x37,0x54,0xA2,0xDA,0xF8,0xF5,0x59,0x62,0x12,0xF4,0x20,0x48,0x1B,0xE0,0x0A,0x53, +0xD8,0xF0,0x5B,0x89,0x71,0x43,0x5E,0xA1,0xAC,0x6E,0xA2,0xCC,0xD7,0x8B,0xA9,0xC3, +0x9A,0xE1,0xAC,0x46,0x99,0x15,0x3A,0x3E,0x67,0xE2,0xAA,0xA3,0x45,0x77,0x31,0x82, +0x0C,0x32,0x6D,0xC8,0xBF,0x9C,0x62,0x92,0xEC,0x12,0x33,0xFE,0xA0,0x07,0x58,0xE7, +0x70,0xFA,0x45,0x70,0x44,0x00,0xBA,0x69,0x1F,0x2A,0x4B,0xD0,0x5E,0x1C,0x9D,0xD1, +0xE1,0xA0,0xE3,0xC1,0x93,0x2A,0xAB,0xFD,0x82,0xD9,0xF9,0x12,0xEE,0xFC,0x9C,0xD5, +0xEF,0x5C,0x2C,0xDA,0x2D,0xD5,0x0F,0x4D,0x33,0xEB,0x2F,0x81,0xB5,0x4D,0x18,0x01, +0x0C,0x35,0x01,0xB2,0x78,0x90,0xB9,0xCB,0x82,0xC5,0x1D,0x36,0x9C,0xD7,0xEA,0xB0, +0xE4,0xF1,0x9C,0x99,0x99,0x25,0xD1,0x7D,0xFB,0xD1,0x18,0xE0,0x72,0x76,0x3C,0x3D, +0xE5,0x33,0x24,0x7C,0x2D,0xF7,0xE4,0xEB,0xC5,0x79,0x9C,0xE5,0xF1,0xAA,0x6B,0x63, +0x45,0xB0,0x6E,0xF8,0xA8,0xE1,0x91,0xBB,0xAA,0x6C,0xD7,0xA5,0xDE,0x3D,0x95,0x1D, +0x39,0x59,0xD8,0x81,0xED,0x35,0x2C,0x04,0xE0,0x1A,0xDE,0x21,0x15,0xC7,0x31,0x8B, +0x14,0x89,0x1B,0x91,0x27,0x49,0xC3,0x86,0x9B,0x35,0x3D,0x1B,0xD0,0x91,0x41,0x4E, +0xCB,0x81,0x95,0x23,0x87,0x53,0xEA,0xCC,0xD2,0x4C,0x00,0xB9,0x24,0xF1,0x29,0x8E, +0xAE,0x31,0x48,0x37,0xAB,0x67,0x4E,0x4A,0x48,0x47,0x4A,0x69,0x99,0x28,0x5A,0xF2, +0x72,0x3D,0x11,0xDB,0x5A,0x56,0x26,0x20,0xD8,0x11,0x54,0xD5,0xF6,0x1C,0x7D,0x29, +0xE5,0x8F,0xD5,0x27,0x80,0x29,0x70,0x26,0xA9,0x4E,0xB2,0xE1,0xB2,0x35,0x60,0x35, +0x73,0x51,0xB2,0x45,0xD3,0x80,0x24,0x70,0x1D,0xBA,0x6F,0x05,0xF7,0x0A,0xED,0x27, +0x27,0x5D,0x03,0x98,0xC8,0x7C,0xCC,0x69,0xBF,0xDF,0x64,0x33,0x6F,0x09,0x91,0xB8, +0x78,0xEF,0xA5,0x3E,0x7B,0xA8,0x99,0x1B,0xC8,0x2A,0x3A,0x38,0xC3,0x25,0x69,0x60, +0xDA,0x6E,0x46,0xAB,0xFC,0x5B,0xFB,0x0E,0x80,0x51,0x37,0x77,0x9C,0x63,0xEE,0x0D, +0x2E,0xE5,0x1C,0x49,0xF9,0x97,0xA6,0x95,0xC7,0x4B,0x2D,0x89,0xEA,0x71,0x63,0xAC, +0xE7,0xD0,0x52,0x88,0xE9,0x7C,0xA7,0x1F,0xE6,0x0D,0xC0,0xE0,0x06,0x01,0xDB,0x1B, +0x94,0x52,0x16,0xA7,0x5C,0xB7,0x96,0x0C,0xAB,0x43,0xC3,0x35,0x6C,0xC1,0xA9,0x2C, +0xE5,0x44,0xD5,0xA1,0x4F,0xD0,0x58,0xB1,0xD1,0x72,0x15,0x45,0x71,0xFF,0x33,0xE7, +0x60,0xEC,0xBE,0x55,0x61,0x4C,0xB1,0x98,0xDA,0x54,0x2C,0xE3,0xC9,0x4D,0xFE,0x6E, +0x32,0x60,0x4E,0x4B,0x4F,0x01,0x3F,0x64,0xD4,0x54,0x8C,0xD4,0x88,0x94,0x68,0xFD, +0xA3,0x14,0x43,0x0B,0x84,0x2E,0x36,0x76,0xA6,0xD8,0x19,0xDE,0xD9,0x56,0xC6,0x25, +0x64,0x72,0xFA,0x44,0xBB,0x36,0x99,0xAA,0xA6,0x88,0xDD,0x54,0xEA,0x02,0xB1,0xB5, +0xE7,0x59,0xF3,0xC3,0x0C,0xA6,0x9B,0xBB,0xED,0x7A,0xA9,0x58,0xD8,0xCF,0x0C,0x4D, +0xA1,0x2C,0x1A,0xF8,0x6A,0x6A,0x7C,0xE5,0x20,0x78,0x13,0xC1,0x97,0x9A,0x8B,0xFE, +0xD1,0xD5,0xA7,0x7A,0x7D,0xE1,0x81,0x3B,0x83,0x24,0xC8,0xC7,0x04,0x06,0xE1,0x27, +0x5F,0x41,0x96,0x5A,0xC5,0xB4,0xAD,0xCA,0x70,0xED,0xA3,0x39,0xC8,0xB9,0x53,0x6D, +0x64,0x97,0xC3,0x6E,0x88,0xB3,0xD8,0xB1,0xD9,0x1D,0x3C,0xA3,0xE6,0x83,0xBC,0xB7, +0xD7,0x08,0xFD,0xC5,0xA9,0x0D,0x91,0x2A,0x1C,0x2E,0x71,0xC9,0xDB,0xC0,0xB5,0xFD, +0xF1,0x21,0xFD,0xB3,0x8B,0x59,0x49,0xDB,0x92,0x18,0x28,0x97,0x3F,0x13,0x44,0x5F, +0x5B,0x7B,0xA9,0x80,0x24,0x5D,0x2C,0x18,0x27,0xAB,0xF2,0xB5,0x66,0x0D,0x72,0xC2, +0xE4,0x04,0xB2,0x66,0xDC,0xD6,0x2B,0xCD,0x7C,0x90,0xBA,0x89,0xCC,0x3A,0x56,0xDB, +0x9F,0x94,0xA2,0xB5,0x1B,0x22,0xB3,0xEF,0x99,0x1E,0x23,0x91,0x80,0xDC,0xD2,0xEF, +0x7C,0x5C,0x2D,0x84,0x96,0x8F,0x39,0xF8,0x78,0xFB,0x46,0x71,0x27,0x6D,0x90,0xE7, +0x6F,0xAA,0x98,0xB1,0xF0,0x89,0x2B,0x66,0x68,0x76,0xBA,0x6B,0x62,0x03,0xC0,0x0E, +0x71,0x20,0x54,0xBD,0x19,0xD1,0x9A,0x53,0x05,0xA4,0x29,0x96,0x3A,0x89,0xA3,0x2A, +0xF8,0xDB,0x05,0x86,0xDB,0xEE,0xF2,0x2F,0xC2,0x32,0xB9,0x10,0xFC,0x6C,0x4A,0xE3, +0x36,0xE3,0x7A,0x1A,0x55,0xDD,0x2B,0x4F,0xF6,0x3F,0xDC,0xCA,0x15,0x2A,0x22,0xE5, +0xE6,0xFE,0x9C,0x6B,0x1F,0x14,0x94,0x70,0x1A,0x52,0x32,0x77,0xAD,0xE6,0xCF,0xD3, +0x47,0x48,0x69,0xDC,0x10,0x41,0x94,0x28,0x71,0x59,0x6F,0x4A,0x40,0x43,0x39,0xF2, +0x52,0xDC,0x4F,0x5F,0x52,0xF2,0x86,0xFD,0x6F,0x5E,0xF4,0x14,0xEC,0xA0,0x3F,0x74, +0x78,0x3F,0x09,0xC6,0x15,0x31,0xCA,0x6D,0xF7,0xCD,0x7C,0xB9,0xA3,0x1F,0x8B,0xE8, +0x27,0x75,0xE0,0xE0,0x59,0x76,0x78,0x0E,0x20,0x80,0x3C,0x60,0x0D,0x61,0x17,0xC6, +0x94,0x1C,0xE9,0xDD,0xA3,0xBE,0xF2,0xB7,0xC5,0xFB,0xB4,0xAF,0xE7,0x36,0xAB,0x9F, +0x12,0x50,0x30,0x08,0xDC,0x3E,0x7A,0xE5,0x35,0xBE,0x23,0xDA,0x84,0xA4,0x44,0xAA, +0x27,0x11,0x2C,0xC5,0x0D,0xCA,0x6F,0xDE,0xAA,0x98,0xD7,0x9D,0xC8,0xA2,0xA6,0x6E, +0xEF,0xC3,0xB6,0xA6,0x5E,0xE8,0x19,0x12,0xB8,0x7A,0x15,0xCE,0xDA,0x18,0x1D,0x5C, +0x60,0x57,0x1F,0x80,0x27,0xF6,0x59,0xEB,0x8D,0x38,0xE2,0x43,0x64,0xB4,0x65,0xE9, +0x49,0xF1,0x7C,0x81,0xCC,0xEE,0x5B,0x62,0xC7,0xF5,0xE2,0x68,0xF0,0xB0,0x80,0xEC, +0xE5,0xD0,0xA5,0x90,0x84,0xC3,0xCC,0x16,0x0C,0x6A,0xCC,0x6F,0x1B,0x94,0x0F,0x98, +0xEF,0xB2,0xE9,0x8D,0xCE,0xE8,0x2D,0x4A,0xEA,0x05,0x32,0xF9,0xE5,0xC8,0xC9,0x69, +0x87,0x20,0xD6,0xE6,0x89,0xC7,0x42,0x36,0x31,0x85,0x7A,0x25,0x73,0x61,0xEE,0x02, +0x2E,0xFB,0xC1,0x0D,0x42,0x4B,0x44,0xE2,0xCD,0xE8,0xEB,0xAC,0x26,0xB4,0x2F,0x1F, +0xE2,0xDA,0x15,0x5D,0xAA,0x5C,0x78,0x1C,0x23,0x81,0xDF,0x0C,0xFE,0xEE,0xE6,0xE6, +0xCC,0xF5,0x59,0x75,0x39,0xE5,0x7E,0x50,0x0A,0x9A,0xA5,0xDB,0x65,0x3F,0xB5,0x7E, +0x6D,0x1A,0x13,0xEB,0x58,0x6D,0xB3,0x7F,0x05,0x70,0x99,0x60,0x6A,0xEC,0xDC,0x26, +0x32,0xB7,0x6B,0x07,0x7A,0x4C,0x39,0x2E,0xD0,0xE7,0x97,0x63,0x59,0x18,0x69,0x57, +0x7E,0x97,0x06,0x84,0x4E,0x10,0xF1,0x17,0xFD,0x26,0x1F,0x7F,0x27,0xA7,0x09,0xA7, +0x39,0xEE,0xDA,0xB2,0x15,0x64,0xE3,0xCB,0x15,0x05,0xF0,0x14,0x96,0xC5,0x48,0x26, +0x75,0x7B,0xE3,0xDA,0xEC,0xA9,0xD1,0xBA,0xDC,0x97,0x49,0xFC,0x77,0xA8,0x08,0xC3, +0x1E,0x77,0x1B,0x56,0xD2,0xA0,0x31,0xE7,0xD0,0xB7,0xB5,0xD0,0x74,0x96,0x46,0x29, +0x82,0x86,0x85,0x09,0x75,0xCD,0x35,0x10,0x3D,0x72,0x6F,0xE7,0x9D,0x3B,0x07,0x50, +0x66,0x0F,0x94,0x73,0x96,0x59,0xC4,0xA5,0xDE,0x6A,0xDC,0x97,0xAA,0x1B,0x4E,0x36, +0x38,0x67,0xA8,0xEB,0xDC,0xA8,0xF2,0xA0,0x53,0xBD,0xFA,0x3D,0x87,0x65,0xE5,0x75, +0x4B,0xDA,0x12,0x45,0xA0,0x56,0x51,0x0D,0xBE,0xC2,0xA4,0x7D,0x35,0xD6,0xC6,0xDD, +0x8F,0x74,0x88,0x42,0xCE,0x01,0x23,0xF5,0x90,0x8A,0xE5,0x86,0xAA,0x09,0x4F,0x1A, +0xBF,0x27,0xFD,0x15,0x27,0xC3,0x95,0xD6,0x16,0x01,0x14,0x6E,0xB2,0xB9,0xA8,0xE7, +0xA1,0x6D,0x9B,0xED,0x25,0xDE,0xF3,0x74,0x08,0x9C,0x35,0x46,0x61,0x19,0x36,0x37, +0x88,0x69,0x12,0xC1,0x48,0xD7,0x5F,0x08,0x21,0xA4,0x36,0x4B,0x9E,0xA3,0xEA,0x2B, +0xF6,0xCF,0x01,0x8D,0x23,0xE3,0x1B,0x33,0x94,0xDD,0x1A,0x69,0xFA,0x25,0x9A,0x42, +0x64,0x12,0x5E,0xFF,0xF3,0xA9,0x72,0xF4,0xE4,0x71,0x07,0xEE,0x98,0xC7,0x9F,0x85, +0x31,0x10,0x30,0xF8,0xD0,0x26,0xC8,0xC8,0x73,0xA0,0xBE,0x33,0xA3,0x88,0x39,0x83, +0x6C,0xCE,0xA2,0x10,0x60,0x55,0xC0,0x6D,0x59,0x43,0x47,0x9A,0x28,0xDF,0x36,0x0C, +0x62,0x99,0x6D,0xEF,0x53,0x8D,0x9F,0x59,0x12,0xE3,0x29,0x8B,0x36,0xD1,0x80,0xEC, +0xF2,0xC6,0x80,0x77,0x38,0xB0,0x71,0xA5,0xBB,0x0D,0x5C,0x81,0xBA,0xA4,0x09,0xAF, +0xE0,0xA1,0x8A,0x8E,0x42,0x67,0xCC,0xD5,0x99,0x12,0xAB,0xB6,0x18,0x3E,0xFE,0x51, +0xA1,0x25,0xF5,0x6C,0xB0,0xAF,0x16,0x4A,0x7D,0x25,0xB5,0x5E,0x6E,0x2F,0x06,0xA5, +0xD0,0x14,0xD9,0xDC,0x0A,0x1F,0x72,0x1D,0x81,0x70,0x1D,0x03,0x24,0x5E,0xCA,0xC6, +0x75,0xCB,0x58,0xBB,0x5C,0x71,0x4B,0xFD,0xA0,0xFE,0x35,0xD1,0x13,0xD8,0xD4,0xA9, +0x44,0xC0,0x6E,0x80,0x0C,0x61,0x3E,0x80,0x4A,0x12,0xBF,0xA2,0x47,0x1C,0x34,0x45, +0x39,0x65,0x25,0x68,0x0A,0x2C,0xD2,0xD7,0x23,0x58,0x9E,0x37,0x8E,0x40,0x77,0x2F, +0x11,0xE1,0xAB,0x58,0xC0,0x60,0xD8,0x8F,0x9E,0xF6,0x8B,0xDB,0x5C,0xBC,0xCF,0xDA, +0x8E,0x53,0x59,0x76,0x82,0xD0,0xEA,0x15,0x4E,0xC6,0x66,0xFD,0xD2,0x23,0xCE,0xDB, +0x25,0x65,0x2B,0xE5,0x67,0x2E,0x11,0x86,0x20,0xE6,0x3E,0x2C,0x49,0x96,0x99,0x09, +0x58,0x06,0x88,0x5A,0x11,0x38,0xAF,0x68,0x4E,0x90,0xF2,0x46,0x79,0xAB,0xED,0xDA, +0x05,0x97,0x54,0xFB,0x33,0x2C,0xC9,0x1B,0xF9,0x9D,0xF8,0x24,0x09,0x98,0xBF,0x1D, +0xCF,0xFB,0xB7,0x87,0x30,0xF2,0x55,0xF3,0x4B,0xB2,0x4E,0x1E,0x67,0x77,0x08,0xE4, +0xFE,0xB5,0xBD,0x30,0xA2,0xAC,0xF2,0xEB,0xA8,0x50,0xC6,0x25,0x6C,0xD9,0x6D,0x43, +0xED,0xCC,0x4B,0xF8,0x04,0xCC,0x6F,0x7D,0x3C,0x2E,0xBF,0x53,0xDC,0xEB,0x21,0x01, +0xD0,0x2B,0xE8,0xFA,0x26,0x24,0x13,0x5A,0x29,0xE1,0xD8,0x7E,0x0C,0x43,0x22,0xC6, +0x26,0xF8,0xA9,0xBE,0x11,0x8F,0xA1,0x23,0x9F,0x9A,0xB1,0x4E,0xAA,0xF7,0x5E,0x51, +0x15,0xEC,0x4D,0x64,0xCA,0xB4,0x9C,0x75,0x22,0x6B,0x9D,0x93,0xC0,0x8E,0x20,0x3A, +0xEC,0x86,0xFE,0xBE,0xCA,0xCD,0x71,0x40,0x74,0xE5,0x83,0x99,0x12,0xE4,0xCC,0x12, +0x14,0xD0,0x99,0x33,0xB1,0x0A,0x29,0x7D,0xA4,0x8F,0xF5,0x15,0xD1,0xA6,0x3E,0x35, +0xA0,0x9B,0xF4,0xAE,0x46,0x54,0xDC,0x31,0xF0,0xA0,0x67,0x41,0x11,0x10,0x2C,0x17, +0xBE,0x7D,0xA4,0xB5,0x65,0x20,0xAA,0xE2,0x83,0x4F,0x97,0x6D,0x14,0x75,0x2C,0xE8, +0x35,0x79,0x18,0xC0,0x4F,0xDF,0xC8,0x78,0x75,0x0C,0x40,0xB2,0xA6,0x68,0xB4,0x78, +0x78,0x41,0x73,0x8B,0x01,0x65,0x58,0xBB,0xA2,0x04,0x00,0x30,0x0E,0xCC,0x0F,0xEE, +0xDD,0xDA,0x7A,0xF6,0x6B,0xA4,0xEB,0x63,0xDA,0xCD,0xE2,0xE3,0xC6,0xD5,0xBA,0x95, +0x23,0x2C,0x1D,0x80,0xDA,0xE2,0xAD,0x1D,0xA6,0x14,0xCA,0x02,0x89,0xE6,0x07,0x26, +0x19,0xD7,0x12,0xAA,0x55,0x6A,0xDA,0x76,0x38,0xB9,0xBE,0x3A,0xF4,0x93,0xB3,0x4C, +0xB6,0xCA,0x03,0xC1,0xC7,0x0A,0xCE,0x86,0x8F,0x21,0x64,0x58,0xB7,0x83,0xBF,0x82, +0x8A,0xB9,0x08,0x73,0x98,0xCC,0xB3,0xCB,0xA1,0x33,0x35,0x6E,0xAC,0x0F,0x76,0x6D, +0x49,0x0C,0xE2,0x21,0xCC,0x71,0x0D,0xE2,0x79,0xC1,0x4A,0xD6,0x2A,0x6F,0x99,0x89, +0x12,0x26,0xA9,0x33,0xA0,0x0B,0x5D,0xD4,0xCE,0xA2,0x2A,0x79,0xA8,0x42,0x0F,0xF1, +0x6E,0x79,0x14,0xCE,0xBB,0x8C,0xF9,0x87,0x0D,0x83,0xD3,0x3A,0xDE,0x04,0x38,0x99, +0xCF,0x2E,0x25,0x6B,0xDF,0x0A,0x42,0x2F,0x62,0x99,0xBE,0x08,0xD1,0xC5,0xB3,0xEC, +0x75,0x0B,0x6B,0xEA,0x3E,0x83,0x72,0xC4,0xF6,0x3B,0x69,0x91,0xC0,0xA8,0x0D,0x21, +0xB7,0xF4,0x08,0x36,0xE9,0x9F,0xC0,0x08,0xF1,0xCD,0xE2,0x69,0x0A,0x44,0xAB,0x65, +0x1E,0x19,0xE8,0x4A,0xAA,0x1A,0x30,0x0C,0xF2,0xD2,0x6D,0x2D,0x4A,0xDF,0x7B,0x7D, +0x7C,0x03,0xCF,0xF3,0xB7,0x60,0xFD,0x8F,0x86,0xF6,0xF3,0xBC,0x64,0xA9,0xFB,0x70, +0xB5,0xCD,0xDE,0xC2,0xA9,0x18,0xCD,0x22,0x2A,0xF1,0xD2,0xA8,0x57,0x7B,0xE5,0x1B, +0x18,0xF0,0xF2,0x40,0x43,0x1F,0x0C,0x3E,0x9C,0x13,0x4D,0xA6,0xE5,0x35,0x50,0xB8, +0x5D,0xAC,0x00,0xC9,0x4F,0x71,0x38,0x78,0x3E,0x0A,0x84,0x61,0x3A,0x89,0xC3,0x05, +0x8A,0xD7,0xEF,0x56,0xDA,0xE8,0xA2,0xC6,0xA6,0xC0,0x09,0x2F,0xFF,0x71,0x4D,0xA5, +0x97,0xCC,0x1F,0x18,0xA1,0x04,0xCC,0x52,0x8F,0x89,0x93,0x1E,0x00,0xD5,0xA4,0xE6, +0xF0,0xA2,0xCB,0x98,0x0D,0x92,0x9A,0xB3,0x80,0x9C,0xBF,0xB1,0xD3,0x5D,0x37,0x5D, +0xF4,0x87,0xE9,0x6F,0x87,0x4E,0x3F,0x09,0x09,0xFA,0x52,0xC8,0x35,0x20,0x68,0x4E, +0x7D,0x39,0xE3,0xC8,0x1A,0x99,0xBE,0x60,0x96,0x23,0xCC,0xB9,0x91,0x86,0xF4,0xCE, +0x04,0x3A,0xAC,0x01,0x1D,0x72,0x57,0xE4,0x00,0x2B,0x1F,0xD6,0xE2,0x6A,0xFD,0x16, +0x36,0x07,0xE0,0xCC,0x15,0xBD,0xC1,0xAD,0x84,0x1D,0x42,0x1E,0xE7,0xEF,0xBA,0x7B, +0x61,0xED,0x08,0xDF,0x7F,0xE3,0xE1,0x79,0xE1,0x74,0x8F,0x4E,0x6E,0x4B,0x51,0xA4, +0xD0,0x93,0xA2,0x06,0xD6,0x35,0x65,0xF1,0x66,0x8E,0xC7,0x95,0xA8,0xC3,0xC0,0x0C, +0x86,0x53,0xCC,0x4A,0x54,0x39,0xF3,0x03,0x7C,0xB1,0x87,0x46,0x18,0x0D,0x79,0xF6, +0xEF,0xE3,0x59,0x50,0xFA,0xF9,0x3D,0x1C,0x62,0x20,0x3D,0x8D,0x3E,0x1E,0xFE,0x46, +0x58,0xBF,0xC2,0x57,0x96,0x49,0x49,0x7B,0xF4,0x4F,0x79,0xE3,0x41,0xB5,0x4A,0x05, +0x60,0x24,0xB1,0xF2,0xBE,0x0F,0x42,0x2C,0xBC,0xCE,0x5A,0x6C,0xC2,0x8E,0x7E,0x70, +0xB1,0x3C,0x29,0x43,0x95,0xFB,0xE2,0x23,0x5D,0xFE,0x96,0x64,0x4B,0x3B,0x29,0x66, +0xF0,0x89,0xC1,0xBF,0x28,0xDA,0x63,0xEF,0x56,0x4F,0xD2,0x92,0x10,0x17,0x23,0x7E, +0x08,0x32,0xDF,0xB2,0xF7,0x07,0x13,0x6B,0xF7,0x24,0x04,0x82,0x1B,0xD8,0x4F,0xBD, +0xA8,0xA8,0x07,0xB4,0x1B,0xD4,0x61,0xFB,0xBD,0xF5,0xDF,0x64,0xB5,0x81,0x07,0x87, +0x12,0xBA,0xA5,0x61,0x9B,0x6A,0x59,0x20,0xA2,0xDE,0x8E,0x6B,0xA6,0xC8,0xB1,0xAB, +0x1A,0x00,0xD0,0xF2,0xC9,0xC4,0x4B,0xC8,0x9D,0x2D,0x79,0x10,0xF2,0xFC,0xD1,0x7E, +0x32,0xE3,0x95,0x47,0xE6,0x9E,0x53,0xF4,0x25,0x02,0x1B,0xCC,0x7F,0x6B,0xA7,0x6C, +0x92,0xCC,0x44,0xDC,0x3F,0xA6,0x4E,0xAD,0x00,0xF7,0x41,0x56,0x3A,0xC8,0x2E,0xFE, +0xC5,0xC7,0x7A,0xAD,0x8A,0xE8,0xC3,0xB3,0x19,0xC6,0xFF,0x92,0x60,0x78,0x82,0x05, +0x19,0x8F,0x78,0xB7,0x02,0x46,0x44,0xE1,0xF1,0xBE,0x9A,0x2E,0x2B,0x43,0xB9,0x48, +0xD5,0x05,0x3D,0xEB,0x20,0xC1,0xDD,0x7D,0xE9,0xD0,0x66,0x6A,0xDE,0x43,0x34,0x0E, +0xCE,0x7F,0x51,0x71,0x3C,0x39,0xA6,0x61,0x2F,0x1A,0x3A,0xCC,0x44,0xE2,0x69,0x10, +0x0F,0x20,0xAC,0xE5,0xF8,0xE3,0xE1,0x19,0x1E,0x53,0x3A,0xB3,0x38,0x0A,0x3A,0xE2, +0xE7,0xB7,0x75,0xB1,0x0C,0x80,0x36,0x85,0x74,0x12,0xC4,0x5A,0xEC,0x3F,0xA7,0x3C, +0x7D,0x2B,0x3F,0x56,0xC6,0x13,0xB7,0x90,0xD0,0xCA,0xFD,0xE5,0x2B,0xD0,0x24,0x7E, +0xB9,0x59,0xA7,0x12,0x0C,0xAA,0x0C,0xD5,0xC4,0x0B,0xE3,0x07,0x31,0xA9,0x20,0xCA, +0x52,0xA3,0x1D,0x99,0x9C,0xA1,0xE0,0xC9,0xFF,0xB2,0x1F,0x40,0xA1,0x0D,0x9F,0x06, +0xB7,0x79,0x68,0x4B,0x77,0x9D,0x52,0x98,0xF0,0xDC,0xE2,0xAC,0xE7,0x96,0x10,0x55, +0x87,0xF5,0x97,0x55,0xDD,0x0E,0x46,0x79,0xCA,0xB5,0xAC,0xD1,0xB6,0x52,0x88,0x59, +0x36,0x82,0xC4,0x81,0x2A,0x67,0xCE,0x08,0xB2,0xE7,0x7E,0x5F,0xC8,0xB2,0x65,0xCA, +0xD4,0xD5,0x27,0x64,0x30,0x9B,0x61,0x9D,0x3F,0x22,0x2A,0x87,0x64,0x19,0xCD,0x85, +0x2D,0x1D,0xBF,0x0E,0x68,0x91,0x0C,0x49,0x01,0xD2,0x64,0x50,0x9A,0xB2,0x7C,0xBF, +0x6D,0x31,0x0F,0x7C,0x4A,0x0E,0xC3,0xCB,0x17,0x7A,0x80,0xF8,0xD0,0xE1,0xFC,0x4C, +0x5C,0x0D,0xF2,0xA8,0x5D,0x1A,0x45,0x7B,0xF5,0x9A,0x6E,0x7D,0x0D,0x04,0x70,0xF0, +0x6F,0x21,0x6F,0x98,0x03,0xFE,0xAE,0x18,0xEF,0x33,0x11,0x1F,0xA0,0x8A,0x88,0x5A, +0xBE,0x7D,0x6A,0xAF,0xAB,0x0C,0x42,0x60,0xC1,0x83,0xD5,0xF8,0xED,0x55,0x81,0x15, +0x7B,0xF6,0x6B,0xA2,0xD2,0xE7,0x72,0xFF,0x46,0xFB,0xF5,0x54,0x01,0xD3,0xA0,0xB3, +0x6D,0xF4,0x81,0x6D,0x8B,0xED,0xF9,0x87,0x33,0x9F,0x49,0x17,0x4A,0xCE,0xB4,0xA1, +0x63,0x50,0x66,0x14,0xD0,0xEC,0xE2,0x1B,0xCC,0x32,0xF7,0xD8,0xC5,0xEA,0x2E,0x60, +0x4A,0x42,0x47,0x9A,0x2E,0x34,0x5F,0x4D,0xD8,0x42,0x3A,0x34,0x0B,0x49,0x7D,0x58, +0x3E,0xAE,0x90,0xD7,0xF0,0x34,0xFA,0x90,0x2B,0x49,0x6C,0x36,0x32,0xC1,0xEE,0x3B, +0xE6,0x32,0x29,0x66,0x10,0x73,0x9D,0x83,0x48,0x5D,0x5C,0x6C,0xFF,0xF8,0x30,0xB3, +0xB3,0xA8,0xD1,0xA0,0xFB,0xEA,0xD8,0xE5,0x4E,0x31,0xEE,0x5D,0x49,0x9F,0x09,0x53, +0x88,0x3E,0xBD,0xEA,0xEF,0x3F,0x22,0x93,0xDC,0x0B,0x82,0xCB,0x26,0x0E,0xA8,0xBF, +0x79,0xD8,0x08,0xE4,0x19,0x1A,0x93,0xBD,0xB0,0xCE,0xF6,0x38,0xFC,0xAE,0x8C,0x76, +0xF4,0xA3,0xEB,0xD2,0xE8,0x03,0x0D,0xC7,0x1B,0x8B,0xA9,0xD4,0x4C,0x34,0xFF,0xEB, +0x8B,0xC2,0xC6,0xAD,0xCD,0x57,0x37,0xF1,0x3F,0xCA,0xE3,0x9F,0x56,0x19,0x11,0x9E, +0xB9,0x09,0x75,0xE2,0xF8,0xBE,0x1A,0x03,0x1A,0xA4,0x7A,0x76,0xE5,0x5B,0x72,0x5B, +0xE8,0xCD,0x53,0xFC,0x00,0x04,0xA5,0x8A,0x0F,0xF2,0x83,0x80,0xF2,0xE8,0xCC,0x70, +0x22,0x36,0xB7,0xB1,0xE2,0x1C,0x99,0xB5,0x21,0x09,0xDB,0x29,0x3E,0x95,0xE4,0x2B, +0xC6,0x06,0xC0,0xD2,0x97,0xF8,0x3F,0x6F,0xCA,0x20,0xBB,0x03,0x2A,0xE2,0x18,0x76, +0x32,0x5F,0xE5,0xB4,0x0C,0x7A,0xA4,0x6C,0xF5,0x15,0xB3,0x96,0xBC,0xA5,0xD0,0x05, +0x6D,0x86,0x58,0x71,0x28,0xB9,0x4E,0x7B,0x3C,0x67,0x67,0x87,0xF7,0xBC,0xFD,0x8C, +0x82,0x19,0xBA,0x47,0xA1,0x64,0xCB,0xA0,0x34,0x33,0xB7,0x6E,0xE0,0xA9,0x68,0x19, +0x60,0xCD,0xB8,0xEE,0x1F,0xF4,0xA3,0xB2,0x4E,0x7C,0x08,0xCC,0xE4,0xDF,0xCF,0x9D, +0x6A,0xCE,0x36,0x06,0xD1,0x4A,0x75,0xB5,0xE2,0xED,0x77,0x72,0x3C,0x9D,0xE6,0x8F, +0xDF,0x75,0xC2,0x7A,0x18,0xFD,0x57,0xAC,0xBC,0x75,0x47,0x2C,0x5B,0xDE,0x3F,0x3C, +0x7B,0xD0,0x79,0x3F,0x84,0x74,0x26,0xC5,0x97,0xEB,0x04,0xAF,0xCA,0xF6,0xCF,0x3F, +0x07,0xB5,0x43,0x31,0x04,0x5C,0xF5,0x9A,0xC1,0x1F,0xD4,0x59,0x00,0x0F,0xE4,0x53, +0x08,0xBD,0x58,0x0D,0x76,0x19,0xCB,0x7E,0x1B,0x04,0x0E,0x0C,0xE0,0xE8,0x89,0x88, +0xDA,0x0E,0xC5,0x64,0x3E,0x3E,0x1F,0xD1,0xF0,0xA9,0x70,0x84,0x5E,0xD9,0xCF,0xD9, +0x54,0x59,0x54,0x3D,0x47,0xC9,0xA8,0x66,0xC6,0xF2,0x42,0x73,0x76,0xC7,0xF2,0x5F, +0xE2,0xEC,0xB1,0xEE,0xF4,0x63,0xEF,0xC2,0x1E,0x02,0xA2,0x8D,0x2B,0x0B,0x3A,0x52, +0x3A,0x4F,0x11,0xC7,0xB0,0x96,0x97,0xD6,0xAB,0x44,0xFF,0xF1,0x8B,0x2E,0xD6,0xD5, +0xE2,0xAD,0x74,0xDF,0x1C,0x6A,0x43,0x19,0x87,0x19,0xD4,0x2F,0x13,0xD8,0x4F,0xC8, +0x9F,0x44,0x4D,0xA1,0xDC,0x8A,0xEF,0xC9,0x4C,0xFD,0xA3,0xFE,0x28,0xE9,0x9B,0xEA, +0x0E,0x61,0x67,0x2D,0x86,0xCF,0x08,0x41,0xAC,0x23,0x4A,0x03,0x97,0x56,0xB0,0x4B, +0x60,0xB3,0x70,0xCF,0xB2,0xAF,0x15,0x7C,0x80,0xA4,0x59,0x95,0x58,0x71,0x3F,0x8E, +0xF5,0x30,0xF4,0xF9,0x36,0x60,0xFD,0xCE,0x7B,0xC7,0xA0,0x7A,0xAD,0x67,0x87,0xDF, +0xF7,0x5F,0xCF,0x51,0x8A,0xD0,0xDB,0x06,0xC1,0x2E,0x55,0x82,0xD5,0x12,0xE0,0x04, +0xEE,0xAD,0x47,0xD3,0xDE,0x78,0xC9,0xED,0x26,0x6F,0xEC,0xCA,0xD1,0x96,0x4E,0x94, +0x6C,0x42,0x4F,0x15,0xDD,0x22,0xD3,0x65,0xDC,0x39,0x8B,0xEB,0x8F,0xB1,0x9F,0x50, +0x03,0x22,0x16,0xC3,0xDF,0x05,0xA7,0xAB,0x27,0xB4,0x11,0xEE,0x57,0x0B,0xF1,0x5D, +0x6B,0x63,0xE2,0x3B,0xDA,0x22,0x7A,0x8D,0x91,0x1E,0x7B,0x74,0x64,0xDA,0xBB,0x03, +0xE3,0xD3,0x80,0x87,0x19,0xDC,0xDB,0x3B,0xE3,0x1E,0xB6,0x14,0xC4,0x50,0x75,0x32, +0x85,0xB0,0xD7,0x6B,0x31,0x3D,0x72,0x18,0x32,0xF0,0x76,0x5D,0xA3,0x10,0x8A,0x46, +0x8C,0xFB,0x1D,0xF0,0x43,0xC0,0x00,0x85,0x3A,0xCB,0x7A,0x24,0x3A,0xB1,0x73,0xDE, +0x64,0xB6,0x5C,0xA7,0x14,0x02,0x63,0x4B,0x66,0xF5,0x0D,0x45,0xE4,0x0F,0xD9,0xB2, +0x86,0x49,0x6E,0x10,0x2F,0x02,0x21,0xA1,0x86,0xF0,0x31,0x9E,0xC9,0xE7,0x57,0x6F, +0xD8,0x6A,0x37,0x05,0x39,0x8F,0xA1,0x3D,0x8D,0x84,0xC1,0xA7,0x84,0x2C,0x39,0xE1, +0xFE,0x4C,0x5E,0xA8,0x37,0x30,0x40,0x9C,0x05,0x9E,0x4E,0x69,0x00,0x17,0x4A,0xAD, +0x0D,0x51,0x8A,0x2A,0x49,0x8C,0x66,0x99,0x01,0xED,0xA8,0x25,0xC1,0xBE,0x32,0x47, +0x41,0xFF,0x36,0x17,0x7D,0x96,0x0C,0x21,0xE7,0x07,0xA0,0x0F,0xC7,0xF1,0x03,0xAF, +0x4C,0x05,0x9E,0xE5,0xA9,0x2C,0x57,0x1C,0x68,0x67,0x61,0xB8,0x6C,0x23,0x14,0x6E, +0x04,0x1F,0x78,0x63,0x03,0xCD,0xA7,0xD6,0xE3,0xFE,0xAE,0xA4,0x56,0xE0,0x02,0x1A, +0x07,0xF2,0x18,0x1F,0x35,0x25,0xF5,0x20,0x5D,0x3E,0x50,0x5E,0x97,0xF3,0x0B,0x66, +0x0F,0x9C,0x42,0x80,0x97,0x6C,0x03,0x44,0x14,0x56,0xD9,0x29,0xF6,0x1A,0x9B,0xCF, +0xD3,0x7F,0xA1,0xD2,0x00,0x31,0x74,0xE6,0x03,0x32,0xEF,0x50,0xF9,0x06,0x30,0xFC, +0x33,0xF6,0xB7,0x60,0xE4,0x0F,0x12,0xC7,0x52,0x2E,0xF7,0x84,0x38,0x86,0xC3,0xFC, +0x63,0xA8,0xA2,0x41,0xFD,0xAB,0xD8,0xEB,0x99,0xFE,0x57,0x9C,0x67,0x55,0x78,0x1F, +0xD9,0xAE,0x97,0x3C,0x3B,0x15,0x95,0xE9,0xD8,0x03,0xC6,0xFD,0xB7,0xAA,0x40,0xCD, +0x6C,0xC4,0xD9,0x11,0x67,0x66,0x89,0xC4,0x09,0x5C,0x25,0x76,0x05,0xD7,0x0E,0x56, +0x4B,0x4B,0xCD,0x51,0x19,0xB5,0x1C,0x72,0x5C,0x6E,0x43,0xE7,0xB2,0x16,0x6C,0xF4, +0xE8,0x12,0x29,0x01,0x39,0x7C,0x4F,0x91,0x78,0x93,0x55,0x58,0x6C,0xE9,0x11,0x7F, +0x0D,0xED,0x90,0x9C,0x44,0xB7,0xA2,0xBC,0x3A,0x25,0xC3,0xBA,0xB0,0x00,0xF1,0xC7, +0xCF,0x26,0xD4,0x20,0xCF,0x47,0x50,0xFD,0x94,0x2D,0xFF,0xC6,0x14,0x00,0x75,0x98, +0x70,0xB7,0x22,0x86,0x4B,0xEA,0xD0,0x83,0xED,0xF0,0x2B,0xD8,0x5D,0xC1,0x15,0xF9, +0xCB,0x7C,0x5A,0xB1,0xEA,0x16,0x26,0xD7,0x3A,0x0E,0x89,0xF4,0x33,0xB1,0x06,0x20, +0x26,0x39,0x4F,0xEB,0xD4,0x35,0xF0,0xAE,0x9A,0x9F,0xB9,0x1C,0xA6,0x66,0x3E,0xF1, +0xCD,0x43,0x26,0xE8,0x15,0x86,0xE9,0xC2,0x37,0x61,0x26,0xC4,0xDA,0x03,0xE5,0x7A, +0x03,0x98,0x1B,0xD3,0x35,0x54,0x1F,0xB9,0xF5,0x1A,0x56,0x3E,0x48,0xD1,0xF7,0x11, +0x37,0x1C,0x42,0xB5,0x21,0x0E,0x68,0xA9,0x24,0x79,0x32,0x34,0x71,0xBB,0x0A,0x12, +0x19,0x61,0xBD,0x24,0xC0,0xE9,0x93,0x45,0x51,0xF6,0x0B,0x30,0x0F,0x19,0x85,0x63, +0x35,0xDB,0x1C,0x7A,0xFB,0x95,0xCE,0xAF,0x90,0xDD,0xE5,0x0A,0x82,0x06,0x13,0x9D, +0xEB,0x50,0x7D,0x4B,0x86,0x49,0x1A,0xD0,0x30,0x7B,0xE6,0x90,0x2C,0x9B,0x9A,0x27, +0xA3,0x80,0x7C,0xDD,0x5A,0xBC,0xB1,0xDE,0xE7,0x9C,0x44,0x6E,0x7A,0x3A,0x31,0x34, +0x87,0x85,0xFB,0x3C,0x04,0xAA,0xAE,0x0C,0x91,0xE3,0x10,0x28,0xD0,0x21,0x21,0xF0, +0xD9,0x29,0x5B,0x74,0xBB,0x3D,0x0E,0x4E,0x50,0xCA,0xE6,0xB4,0x48,0x31,0x3E,0x1B, +0xE5,0x8E,0x1D,0x88,0x09,0x82,0xE6,0x73,0x14,0x4F,0x2E,0x4A,0x07,0x92,0x6C,0x20, +0x4B,0xA1,0x5A,0xCD,0xC9,0x1D,0x09,0x3A,0xD2,0xE5,0x7F,0xF8,0x43,0x90,0x23,0x8F, +0x65,0x70,0xD0,0x27,0xA1,0x01,0xD3,0xBC,0x2E,0x2E,0x7B,0x94,0xD1,0xBB,0x95,0x7C, +0x4B,0xD7,0x71,0x94,0xB9,0x99,0x09,0x2B,0xC4,0xFD,0x5A,0xC5,0x93,0x85,0x42,0x15, +0xF2,0xAE,0x4A,0x8B,0x77,0x7B,0x2B,0x44,0x7A,0x13,0xE7,0xC2,0x6F,0x50,0x34,0x37, +0x3D,0x4C,0x36,0xC4,0x19,0x8F,0xFE,0x7D,0x21,0x0B,0x78,0x8C,0x7D,0xEE,0x88,0x23, +0x9C,0x9C,0xF9,0x2E,0x08,0x2E,0xB1,0x42,0x81,0x7E,0x55,0x70,0x6D,0x32,0xEA,0xE7, +0xE9,0xB9,0xED,0x8C,0x6D,0xB4,0xD6,0x9A,0x75,0xA9,0x50,0x2C,0xE4,0x29,0x4C,0x8A, +0x63,0xFE,0x74,0x29,0x36,0xBC,0x94,0x70,0xF4,0x5E,0xB6,0x4C,0xE1,0xAE,0xCE,0x47, +0xDD,0xAA,0xF4,0xD4,0x2E,0xFF,0x11,0x1B,0xE2,0xEC,0x40,0xD7,0xCC,0xF1,0x17,0xAB, +0x2D,0x11,0xED,0x9E,0x43,0x93,0xFA,0x70,0x14,0x74,0xF0,0x3A,0x89,0x20,0x6A,0x47, +0x3F,0x97,0x8D,0x6D,0x7F,0xCA,0xD4,0x9E,0x96,0xA6,0x86,0x93,0x04,0x76,0xAA,0x2D, +0xE2,0xF3,0x85,0xB2,0xB3,0x7B,0x8D,0xE4,0xC1,0xBF,0xF1,0xBF,0xB8,0x50,0xBE,0x00, +0x9C,0x6C,0xB0,0x4E,0xED,0x02,0xBC,0x9C,0x5A,0xCD,0x68,0x03,0x55,0xBB,0x99,0x47, +0x7E,0xEE,0x98,0x61,0xDE,0xB5,0x68,0x9E,0x21,0x06,0x9D,0x45,0x2D,0x38,0x14,0x85, +0x82,0xF4,0xAC,0x8F,0xCE,0xDC,0x7E,0x45,0x5E,0x15,0xCB,0xF2,0xD8,0xB6,0x8D,0x51, +0x6A,0x93,0x61,0xF8,0xB0,0x5A,0x1E,0x29,0xCB,0xF5,0x04,0x4F,0x62,0x8B,0xF3,0xB1, +0x49,0x5B,0x57,0x12,0x44,0xC3,0x9D,0x9E,0x29,0xB9,0x29,0x70,0x7D,0xA0,0x89,0x61, +0xBD,0xAF,0x50,0x4D,0x96,0x07,0x34,0x39,0x62,0xD6,0xEC,0x46,0xB0,0x85,0x14,0x91, +0x6F,0x69,0xA4,0x0C,0x22,0xBB,0x97,0x67,0x6E,0x20,0x7D,0xE1,0xBB,0x0C,0x9D,0x77, +0xCD,0x67,0xDD,0x1F,0xA6,0xF2,0x8D,0xBB,0xDC,0x84,0xDD,0x48,0xEA,0x33,0x0D,0x3A, +0x91,0xB9,0xCE,0x2E,0x13,0xFB,0x39,0x03,0x33,0x28,0xBD,0x85,0xAC,0x1E,0x48,0x22, +0x15,0x9B,0xA5,0xF4,0x18,0xE2,0xEF,0x15,0x2F,0xEC,0x1A,0x81,0xF1,0x7F,0x3D,0x94, +0x6C,0x8F,0xB2,0x1B,0xF4,0x10,0x84,0x1D,0xAD,0x05,0xE6,0xA8,0xA1,0xE2,0xC4,0x00, +0xEC,0xBD,0xFA,0xD2,0x75,0xBA,0xD9,0x57,0x32,0xE0,0xAF,0x7F,0x36,0x54,0x5A,0xA6, +0xCD,0xE7,0x4D,0xC1,0x04,0xCD,0x41,0x00,0x03,0x84,0x96,0xB5,0xC4,0x06,0x63,0xFE, +0xE9,0xDF,0x3E,0xF6,0x49,0xE6,0x85,0x10,0x26,0x29,0x17,0x2B,0xBF,0xDA,0x83,0x68, +0x2D,0x97,0x5C,0x72,0xF6,0xF1,0xCF,0xC5,0xEF,0xBD,0xA6,0x3E,0xAA,0x23,0x6C,0xF4, +0xDE,0x62,0xCD,0x6A,0xEA,0xAB,0x59,0x8B,0xBB,0xE0,0x12,0xD8,0x8D,0xA0,0xE8,0xA1, +0x56,0xDA,0x3E,0xE2,0xE4,0x2E,0x39,0x84,0x3D,0x6B,0xCC,0x3B,0xF5,0x02,0xD0,0x8A, +0xDE,0xC4,0x70,0x47,0x98,0x08,0xF9,0x05,0xB7,0xD2,0x71,0x23,0x8B,0x99,0x06,0x50, +0x2F,0xF3,0x19,0x4C,0x4C,0x66,0x17,0x5D,0x2D,0x53,0xB3,0xD7,0x14,0x54,0xCE,0x46, +0x31,0x0B,0x41,0x63,0xB0,0xE6,0x90,0xBF,0xEA,0x10,0xCD,0x06,0xC5,0x4C,0x87,0x0C, +0x2A,0x1C,0x4B,0x7F,0x2F,0x5D,0xDD,0x54,0xF1,0x35,0x97,0x07,0x56,0x5C,0xEF,0xF2, +0x6D,0x7C,0x75,0xF6,0x27,0xAE,0x29,0xD0,0x05,0x2B,0xEE,0xFF,0x9D,0x98,0xEC,0xE2, +0x2D,0x51,0x72,0x1A,0x53,0x3B,0x4D,0x30,0x0F,0x17,0xE8,0xEC,0x42,0x04,0x2A,0x1B, +0x5D,0xC2,0x39,0xC7,0x8E,0x53,0x5E,0x93,0xE2,0x0C,0x65,0x0E,0xB3,0x94,0x52,0xE0, +0xC7,0x61,0xE2,0x19,0xE6,0x50,0xB1,0x32,0x73,0x25,0x39,0xD9,0x57,0xF6,0x59,0xAA, +0x62,0x12,0x2E,0x74,0xB3,0x0F,0x71,0x19,0xC2,0x67,0x4C,0x2C,0x8D,0xE0,0xF0,0x0A, +0x8C,0x46,0x97,0xE6,0xD8,0xDC,0x4B,0x30,0xEC,0x0E,0x41,0xBF,0x56,0x7E,0xC8,0x65, +0x2B,0x9D,0xC8,0x85,0x9B,0xAC,0x30,0x07,0xFD,0xB8,0xDE,0x8F,0xBC,0x47,0xB0,0xF2, +0x73,0xCF,0xD6,0x03,0x2D,0x60,0x3D,0x62,0x69,0xDA,0x36,0x8B,0xD0,0x02,0x53,0x94, +0xDA,0x33,0x5A,0x6A,0x37,0x9C,0x16,0x0F,0xE3,0xFC,0x8A,0xBA,0xDF,0xD7,0xB1,0xF4, +0x90,0x8B,0x96,0x6F,0x79,0x5D,0x78,0xCE,0x19,0xC3,0xA2,0xA4,0xC2,0x39,0x2B,0xBA, +0xCA,0x5F,0x43,0x3F,0x8D,0xA5,0xCF,0x46,0x26,0x8E,0x1C,0xB5,0xA3,0x23,0xE0,0x35, +0xA3,0xB5,0x62,0xB1,0xFD,0x98,0x3A,0x15,0x36,0x20,0xFB,0x98,0x4F,0xFE,0xAB,0xC3, +0xD9,0xE4,0xE4,0x3D,0x84,0x87,0xEE,0xAB,0x2E,0x35,0x7C,0x8A,0x28,0x8B,0x5A,0x06, +0x4A,0xA7,0x41,0x6E,0xDC,0x92,0xD1,0xB3,0xFA,0xC7,0xB6,0x33,0x3B,0x1F,0x7F,0xE6, +0x19,0x22,0x89,0x2A,0x7C,0x17,0x7F,0xBC,0xBC,0x8B,0x3E,0x57,0x42,0xE0,0x52,0xA3, +0x1D,0x2F,0x4B,0x40,0xCE,0x43,0x2B,0xC4,0x75,0x71,0xE3,0x22,0x6C,0x47,0x40,0x5B, +0xB7,0xFB,0xC2,0xCE,0x65,0x8F,0xF0,0x97,0x21,0x74,0x7D,0x4E,0x92,0xA0,0x04,0xF4, +0x31,0x0A,0xD8,0xBB,0x83,0x13,0xB5,0x6F,0x84,0x88,0x25,0x76,0xBC,0xEE,0xCC,0x76, +0xD5,0xEB,0x4A,0x9A,0xA3,0xCE,0x38,0x4C,0x9B,0x56,0xD8,0x89,0x12,0x01,0x53,0x77, +0x30,0xBF,0xD9,0x0A,0x7D,0x3B,0xB6,0x11,0x3C,0x90,0x84,0xED,0xC1,0xB2,0x59,0x29, +0x35,0xCE,0x4B,0x07,0x72,0x3B,0x19,0xBE,0x74,0xAB,0x80,0xDF,0x08,0xB6,0x7A,0xBB, +0xE3,0x63,0xA9,0x97,0x14,0x1C,0x47,0x7C,0x76,0xE8,0x81,0x40,0xB0,0x57,0x09,0x9A, +0x86,0xB9,0x2F,0xC0,0x6C,0xE0,0x6B,0x96,0x55,0xA2,0xF5,0x51,0x20,0xD7,0x10,0x8A, +0x3C,0x0D,0x1D,0x25,0x23,0xA1,0x21,0xDA,0x1C,0x4B,0x21,0x7E,0x1E,0xBF,0x38,0x0D, +0xCF,0x2F,0xE7,0x2F,0xB6,0x0F,0xCA,0xC7,0x48,0x74,0xD1,0x46,0x23,0x1F,0xF3,0x16, +0xF3,0xD8,0xBB,0xA2,0x26,0x40,0x4E,0x3B,0x2D,0x73,0x02,0x89,0x5B,0xC2,0xCE,0x66, +0x4D,0x1A,0x8C,0xE4,0x5B,0x84,0x3B,0x02,0x0F,0x6F,0x53,0x35,0x9D,0x44,0xC0,0xB3, +0x47,0x94,0x95,0x54,0xF5,0x60,0xC6,0x88,0xB9,0x5C,0xA8,0xCF,0x09,0xE3,0x3E,0x2B, +0xE1,0xB9,0x15,0xB9,0xA2,0x1B,0x84,0xB4,0x25,0xB9,0x16,0xF7,0xF3,0xD8,0xE6,0x8B, +0x82,0x75,0x32,0x75,0xF1,0xA6,0x74,0x22,0x9A,0x68,0xDC,0x7E,0x37,0x25,0x9C,0x7D, +0xF0,0x8D,0x37,0x09,0xF2,0x68,0x25,0xA4,0x06,0x80,0x2E,0x2C,0x61,0xF1,0xEC,0x72, +0x9E,0xC4,0x94,0x47,0x87,0x7F,0x9C,0xA8,0xC8,0xA1,0x67,0xE9,0x06,0x0A,0x9F,0x0F, +0x0D,0x47,0x48,0x90,0x37,0xAD,0xBA,0x87,0x36,0xAF,0x88,0x45,0x1C,0x23,0xBE,0xC3, +0x6E,0xC4,0xCD,0x6B,0x82,0xCB,0x85,0x4A,0xE4,0x03,0x04,0xD7,0xAA,0x31,0x34,0x5A, +0x96,0x44,0xA2,0xD7,0xD8,0x38,0x1E,0x4B,0x0D,0xD0,0xE4,0xBC,0x80,0x7A,0xEF,0x19, +0x38,0xC5,0xF2,0xF1,0x30,0xA1,0x70,0xE2,0x77,0x7D,0xBE,0x73,0x61,0x29,0x41,0x39, +0x78,0x96,0x46,0x44,0xE1,0xC4,0x02,0x65,0x44,0x73,0x74,0x2A,0x97,0x6A,0x39,0x1E, +0xA1,0xB5,0xAC,0xA3,0x51,0xBD,0xF6,0xB0,0xE3,0x00,0xAD,0xF5,0xA3,0x7D,0xD9,0x7C, +0x62,0x3D,0xED,0x67,0x15,0x88,0x11,0xA2,0x60,0x49,0xDD,0x22,0x28,0xD6,0x5F,0xDC, +0x6A,0x14,0x4D,0x49,0xCE,0xB9,0xC6,0xBD,0xB4,0xCE,0x4C,0xB9,0x20,0xF3,0xFE,0xEE, +0x4F,0x91,0x77,0x44,0xBB,0x52,0x5B,0x38,0xE6,0x47,0x0C,0x01,0x40,0x3B,0x43,0xF6, +0x79,0x76,0x2B,0x83,0xDA,0x8A,0x10,0x9B,0x24,0x7A,0xFC,0x3B,0x4E,0x9F,0x28,0x90, +0xD6,0x65,0x48,0x48,0x72,0xC0,0xCA,0x62,0x5C,0x2F,0xC5,0x70,0x0B,0x5A,0x84,0xAE, +0xB5,0xF0,0xE8,0xE0,0xC2,0x44,0xCD,0x2A,0x7F,0x97,0x52,0x5B,0x28,0xDA,0x66,0xBA, +0x20,0xE2,0x41,0xF6,0x88,0xBE,0xD8,0xBF,0x49,0x41,0x38,0x3F,0xCB,0x7B,0xA2,0x13, +0xB4,0xE8,0xB9,0x58,0x80,0x85,0xAA,0x01,0x3D,0x3C,0xDB,0x2F,0x2B,0x27,0x6F,0x45, +0x3B,0xDF,0xAE,0x56,0xDF,0x2F,0x20,0xAB,0xF3,0xC2,0x56,0x97,0x16,0xBC,0x58,0x62, +0xDF,0xF5,0x4C,0xD8,0x63,0xF4,0x99,0x71,0x58,0xB5,0x67,0x8C,0x32,0x1F,0x9C,0x74, +0xB8,0xDB,0xF7,0xB1,0x10,0x95,0x80,0x64,0xB7,0x08,0xE1,0xE4,0x0F,0x7B,0xCD,0xE2, +0x34,0xD7,0xA6,0x37,0x6E,0x02,0x45,0x56,0xE5,0xBB,0x4F,0x74,0x07,0x5E,0xA8,0x10, +0x94,0x71,0x98,0x69,0x6E,0x81,0xB8,0x55,0x37,0xB4,0x33,0xF0,0x66,0x3B,0xA2,0xB3, +0x94,0x91,0xE9,0x1E,0xAE,0x0A,0x3A,0xA8,0xAA,0x25,0xA2,0x3F,0xCF,0xFC,0x9B,0x6C, +0x29,0xF7,0x59,0xD0,0xD8,0xD3,0x9E,0xF0,0xC2,0xCB,0x69,0x62,0x76,0x54,0x03,0x76, +0xF1,0xA9,0x5C,0x38,0x76,0x87,0x18,0x0C,0xB5,0x91,0x95,0x7A,0xBB,0x6D,0x65,0xE9, +0x89,0x75,0xC6,0x79,0x53,0x95,0xF9,0x73,0x6C,0x64,0x53,0xFE,0x58,0xAF,0x18,0xFA, +0x70,0xBC,0x6A,0x90,0xB7,0x84,0xD8,0xED,0xAA,0x23,0xB3,0x38,0x9D,0xB3,0x9C,0xB9, +0x67,0xF1,0x8C,0x31,0x8D,0xCA,0xEF,0xB8,0x25,0xDB,0x78,0xF8,0xC1,0x40,0x3B,0xBA, +0x4F,0x22,0x8E,0x5C,0x07,0x7D,0xC4,0xDE,0x2E,0x83,0xA6,0x76,0xB3,0x27,0x1E,0xD4, +0x13,0x04,0xAD,0x94,0x3A,0xE7,0x58,0x28,0xAD,0x31,0xA1,0xE6,0xBB,0xDE,0x24,0x95, +0xD1,0xE9,0x19,0x13,0xD7,0x28,0xB2,0x44,0x13,0x4F,0x29,0x7B,0x9C,0x58,0x5E,0x10, +0x17,0xD5,0x07,0xD4,0x55,0xA6,0xDE,0x52,0x29,0x7E,0xA0,0x2A,0xAE,0xE8,0x66,0x1E, +0xB8,0xFB,0xD4,0x74,0x6C,0x05,0x95,0xC3,0xD3,0x42,0x7A,0x12,0x76,0xFA,0x74,0xBA, +0x38,0x02,0x25,0x38,0xCD,0x6C,0x7E,0x5B,0x3A,0x99,0xDF,0x60,0x7F,0x1D,0x04,0xF0, +0x3C,0x79,0xB7,0xB9,0xBB,0x5F,0xED,0x66,0x93,0xA8,0x06,0x95,0xDF,0x26,0xAE,0xEE, +0x3E,0x9F,0x9E,0x8D,0xE0,0xC9,0xC4,0xC0,0x6A,0x74,0xFE,0xB5,0x13,0xDB,0xE4,0xFE, +0xE8,0x20,0x2F,0x68,0xA0,0x7D,0xAB,0x0F,0xC4,0x66,0xD9,0xFC,0x87,0x13,0xE9,0x71, +0x16,0x88,0x0B,0x5D,0x0D,0x19,0x1A,0xB1,0x1C,0x4C,0x1F,0x5B,0xFC,0x18,0x10,0xC2, +0xEC,0x6E,0x5D,0x33,0xD2,0x4A,0x55,0x2D,0x2E,0xA5,0x3D,0x74,0x30,0xCE,0x45,0xF8, +0x8B,0x51,0x26,0xF4,0x31,0xD5,0x4A,0xB0,0x14,0x23,0xF6,0x18,0x1A,0x3A,0x38,0x7F, +0x89,0xBF,0xE3,0xFE,0xBD,0x3A,0x2F,0x5B,0x8F,0x42,0x0E,0x70,0x69,0x1E,0x41,0x4F, +0xBE,0xDB,0xCA,0xF0,0x62,0x58,0x84,0x62,0x0E,0xBB,0x51,0xC5,0x14,0x6C,0xDB,0x69, +0x19,0x08,0x46,0x4C,0xCF,0x0B,0xA6,0x9E,0x77,0xC6,0xDE,0x96,0xF5,0x8A,0x5F,0x6E, +0x7C,0xE7,0xB2,0x8B,0x16,0x0F,0x60,0xA9,0x38,0x12,0xF6,0x0B,0xA3,0x2D,0xD2,0xEC, +0xAC,0x72,0xA9,0x77,0x94,0xA1,0x13,0x05,0x4B,0x33,0xEF,0x40,0xF2,0x2C,0x83,0xD0, +0x75,0x2C,0x10,0x48,0x29,0x9B,0x8B,0xCE,0x22,0xA5,0x31,0xE7,0x75,0xF2,0x77,0xF0, +0xFE,0xDE,0x39,0x43,0x9B,0x03,0x20,0x52,0x20,0x00,0xF9,0xFF,0xCF,0xB3,0x54,0xD2, +0xD7,0xF2,0x21,0x05,0x8E,0x31,0x2F,0x61,0x6A,0x9A,0x6B,0x95,0x4A,0x98,0x25,0x15, +0x98,0x90,0x3B,0x51,0xEA,0x18,0x0C,0x3B,0x20,0x7C,0x51,0xB3,0x97,0x81,0x3C,0x3F, +0x9D,0x24,0xE1,0x7D,0x12,0x08,0xC2,0x25,0xD3,0x42,0xF1,0xDB,0xD9,0xDE,0x9A,0x98, +0xBA,0x1B,0xEC,0x85,0xD0,0xC8,0xCF,0x35,0x07,0x32,0xF6,0xAB,0x17,0x71,0x41,0xB9, +0xC5,0x4E,0x11,0x03,0x65,0x24,0x6C,0x63,0x8D,0xB8,0x78,0xFA,0x00,0x7A,0xFC,0x9D, +0x57,0xC4,0x10,0x1B,0x10,0xC3,0x32,0x86,0x22,0x7C,0x46,0x8B,0xBA,0x7C,0x9E,0x79, +0x52,0xB7,0xCB,0x67,0x03,0x17,0x80,0xBC,0xF9,0xD5,0xF0,0x4C,0xFE,0xBF,0x6D,0x35, +0x30,0x55,0xF5,0x2D,0x85,0x22,0xBD,0xE5,0x59,0xC3,0xAC,0xB7,0x6D,0xEA,0x12,0x42, +0x2B,0xE9,0x7E,0x5A,0x87,0xA4,0x21,0x61,0x42,0xC4,0xBE,0x88,0x3A,0x72,0x73,0x98, +0x54,0x6C,0xF0,0x1C,0xE6,0x4C,0x0D,0xD1,0x12,0x5E,0xCA,0xFD,0x5A,0xAE,0x87,0x4B, +0xE7,0xFC,0xB1,0xD8,0xB8,0xEB,0x8C,0x28,0x5A,0xD9,0x43,0x2D,0xAC,0xF7,0x44,0xC8, +0x0B,0x56,0x92,0xED,0x22,0x0E,0x99,0x07,0xC7,0x52,0x23,0xDD,0xE1,0x24,0xA9,0x40, +0x6F,0x75,0xDF,0xF6,0xFA,0x49,0x6B,0x9D,0x35,0x1B,0x5D,0xEE,0xA1,0x2F,0xB6,0xFA, +0xE8,0xD2,0x07,0x43,0x2E,0xE5,0x58,0x52,0x04,0xBD,0x0D,0x2A,0x20,0x90,0xBC,0x96, +0xB2,0x12,0x11,0x45,0x02,0x01,0x72,0x40,0x92,0x27,0x41,0x8D,0x80,0x03,0x74,0x80, +0xFD,0xDD,0xE4,0x15,0xA7,0x8C,0xB9,0x1B,0x5B,0xEA,0x60,0x56,0xD1,0x8B,0x6D,0x1B, +0x3B,0x3E,0xB3,0x1E,0xDA,0x95,0xA0,0xB5,0x05,0xB8,0xAA,0x2A,0x0D,0xDC,0xDA,0x00, +0x8E,0x77,0xF9,0x42,0x71,0x98,0x0A,0x34,0x5E,0x9F,0xAE,0x36,0x6F,0x76,0xE8,0x11, +0x34,0xEB,0xD6,0x45,0x50,0x72,0x40,0x86,0xFB,0x50,0xED,0xBF,0x00,0xA4,0xB1,0xB4, +0x77,0x69,0x16,0xC7,0x27,0xB9,0x98,0xE1,0x1B,0xC7,0x95,0xB1,0x6D,0x4A,0x30,0x47, +0x97,0xDC,0xAD,0x04,0xDD,0x59,0xC1,0x7D,0x8D,0x5C,0xF4,0x5B,0x59,0x18,0x4C,0x5D, +0xD7,0x17,0xAB,0x34,0x51,0x5B,0x62,0xFD,0x77,0x15,0x4F,0xF9,0x13,0xFA,0xFE,0x28, +0x84,0xC2,0x5A,0xD2,0x42,0x96,0x68,0x5C,0x00,0xE7,0x5B,0xBA,0x7C,0x13,0xE9,0x77, +0xB6,0xFE,0x05,0x45,0xAA,0x02,0xD7,0xEE,0x70,0xCC,0xCE,0xC4,0x05,0x06,0x2F,0xDC, +0xB5,0x0E,0x23,0xA2,0x18,0xE1,0xD7,0xF9,0x9A,0xD3,0xBC,0xD0,0x6D,0x9A,0xCA,0x1D, +0x03,0x79,0xEA,0x5C,0x2C,0xEE,0xBD,0x7F,0x45,0xE5,0xF5,0x42,0x72,0x9A,0x9E,0xD9, +0xFC,0xCC,0x21,0xEE,0x32,0x17,0xE3,0x5D,0x9B,0x12,0x67,0xC3,0xB8,0x24,0x94,0xB1, +0x9A,0x52,0x17,0xEB,0xEC,0x0F,0x50,0x67,0x21,0xE9,0x58,0x74,0x02,0x9A,0xD4,0x1D, +0x83,0xC2,0x7F,0x27,0x0D,0x3E,0x89,0x6A,0xD4,0x5F,0xA9,0x5B,0x49,0xEB,0xF4,0x02, +0x54,0x3E,0xBA,0xE2,0x5E,0xDE,0x79,0xE2,0x7D,0x5F,0xF6,0xCC,0xBB,0x99,0x36,0x1B, +0x93,0xB1,0xFC,0x8E,0xE3,0x11,0x98,0x3B,0x3E,0xC1,0xF2,0x0F,0x29,0xF3,0xD0,0x8B, +0x28,0x8A,0x48,0xC6,0xEF,0xD7,0x1B,0x69,0x50,0xE5,0xB5,0x5A,0xD4,0x50,0x2E,0x5E, +0x70,0x53,0x38,0x8C,0xFC,0x6C,0x4C,0x32,0x91,0x3A,0xEE,0x9C,0xCA,0x50,0x30,0x20, +0x3D,0x67,0x70,0x88,0x41,0x82,0xDD,0x1B,0x74,0x5B,0x0E,0x90,0x14,0xC7,0x56,0xA5, +0x37,0xF9,0xA6,0x5E,0x0D,0x17,0xAE,0xE5,0xAA,0xB2,0x34,0x79,0x11,0xDF,0xD6,0xB3, +0xF2,0x03,0xA9,0x39,0xC1,0x0E,0x34,0xBA,0xD1,0xC8,0x62,0x1C,0x5E,0x94,0x84,0x5F, +0x6F,0x26,0xBF,0x01,0xDC,0x91,0x1C,0xCE,0xB9,0x64,0x0E,0x06,0xE6,0x17,0x35,0x43, +0xB7,0x30,0x39,0x11,0xD2,0x1C,0xB4,0x9C,0x52,0x76,0xE8,0x46,0x95,0x25,0x42,0x83, +0x4F,0x0B,0x16,0x7B,0xC2,0x73,0xC2,0x46,0xF6,0xBF,0x1B,0x3A,0xD6,0x6C,0xE6,0x00, +0xC5,0xB0,0xE0,0x67,0x85,0xF8,0x99,0x7D,0x10,0x56,0x80,0x73,0x17,0x30,0x30,0x8E, +0x3A,0xC3,0x53,0x6A,0x99,0x41,0xA4,0x5E,0xE2,0x4E,0x68,0x43,0x75,0x70,0x63,0xDC, +0x4F,0x30,0x25,0xB3,0x2A,0x33,0x3B,0x9B,0x46,0xF1,0x7A,0x89,0x52,0x96,0x70,0xBB, +0x7A,0xBE,0x15,0x77,0xEC,0xAD,0x8F,0x7F,0xBC,0x4C,0x61,0xBA,0x47,0x65,0x33,0x0F, +0xE7,0x41,0x97,0xDF,0x18,0x2D,0x7C,0x2E,0x8E,0x3F,0x3A,0x79,0x6B,0x9A,0xFE,0x7A, +0xF1,0xC9,0xAC,0xF5,0x9B,0x85,0xCC,0x82,0x25,0xB1,0x88,0xA7,0x00,0xC6,0x50,0xD4, +0x60,0x4A,0xAD,0xDE,0x71,0x99,0xFD,0x0A,0xEC,0x90,0x04,0x7F,0x8F,0x53,0xC4,0x63, +0x4F,0xAB,0x68,0x72,0xEF,0x5C,0xF4,0xF7,0x22,0x23,0x81,0x23,0xCE,0x02,0x6A,0x27, +0x13,0x94,0x43,0x96,0x21,0x06,0x23,0xC2,0x12,0xCB,0xFC,0x6E,0xCE,0x42,0xC2,0x28, +0x9C,0x83,0xB5,0x95,0x4E,0x4D,0xFE,0x7E,0x63,0x01,0x33,0x8E,0xF9,0x73,0xA4,0xAE, +0x0F,0x73,0xCC,0x59,0x02,0x90,0xA1,0x58,0xD3,0x57,0xF3,0x47,0xA1,0x64,0xFD,0xC9, +0x46,0x2E,0x3D,0xEB,0x61,0x58,0x06,0x90,0xAB,0x89,0x15,0x9E,0xA1,0x8B,0xAD,0x2A, +0xB3,0x40,0x92,0xFB,0x08,0x5A,0x88,0x83,0xFC,0xA1,0x97,0xAF,0x37,0xFF,0xF8,0xC4, +0x2E,0x42,0xF6,0x0D,0xD7,0x54,0x27,0x87,0xC9,0x75,0x78,0x59,0x56,0x2B,0x2B,0x2C, +0xE4,0x26,0xC7,0x2A,0x89,0x68,0x64,0x21,0xF0,0xEF,0xB2,0xDB,0x2C,0xD3,0x14,0x77, +0xDE,0xD6,0xEF,0x7E,0xD2,0x16,0x24,0x1F,0xFD,0x89,0x50,0xDD,0x62,0x42,0x76,0x80, +0xE2,0x5D,0xD7,0xF2,0x44,0x5A,0x5B,0x35,0xF2,0xA8,0xAB,0x32,0xC3,0x5C,0x8D,0x57, +0x08,0xB5,0x0D,0x6D,0x6D,0x1F,0x07,0x71,0xC9,0xD8,0xDB,0x3D,0x39,0xB1,0xAC,0xF9, +0xF7,0x8C,0x57,0xF0,0xB3,0xAD,0xBF,0x76,0xB5,0x2F,0xFE,0x61,0x78,0x3D,0x0F,0xBA, +0x5D,0xEF,0xC7,0xE8,0x2D,0x1C,0x5D,0x38,0x87,0xBD,0xEF,0x5F,0x95,0x8D,0x0C,0xB2, +0x95,0x1A,0x2D,0x03,0x8A,0xF6,0x8A,0x41,0x61,0x3E,0x18,0x59,0xA8,0xF5,0x2A,0xAD, +0x3E,0x48,0x02,0x0B,0x62,0x83,0xDD,0x70,0x93,0x64,0xFB,0x1C,0x87,0x44,0x8F,0x1F, +0xA8,0xED,0x80,0xA6,0x13,0x7D,0xA3,0xE3,0x55,0x35,0xD9,0x78,0xED,0x7D,0x81,0xBE, +0xD4,0xC4,0x82,0x0D,0x24,0xC7,0xD2,0x69,0xD9,0xBE,0x6B,0xAD,0x75,0x07,0x76,0x5A, +0x70,0xEF,0x3D,0xFC,0x76,0x0B,0x81,0xD4,0x71,0x4F,0x82,0x47,0xAA,0x9C,0x4C,0x91, +0x5E,0xB5,0x3F,0x1D,0x7D,0xDD,0x01,0x6A,0x1C,0xA6,0x96,0x9B,0x1A,0x42,0xF5,0x61, +0xC0,0x74,0x18,0xCA,0x6A,0xC4,0xA8,0x82,0xDF,0x46,0x9F,0x24,0x3A,0xC8,0xCA,0x3A, +0xCA,0x69,0xCC,0x9D,0x5B,0x57,0x40,0x6F,0x7B,0x1A,0xF7,0x46,0x65,0x3B,0x77,0x16, +0x64,0xD7,0x11,0x7E,0x93,0xAF,0x7E,0x75,0x00,0x47,0x12,0x6F,0xA6,0x74,0xDD,0x91, +0x8A,0x02,0x86,0x58,0xD2,0x33,0xC4,0x3A,0x8F,0x68,0x5C,0x88,0x3D,0x48,0xB5,0x37, +0x1D,0x98,0x53,0x01,0x9B,0x31,0x88,0x96,0x03,0xFC,0xA1,0xB4,0x16,0x8B,0x81,0xDC, +0xE7,0xD3,0x09,0xA4,0xFD,0xC3,0x57,0xCA,0x5F,0x26,0xCA,0x68,0x37,0xDE,0xA0,0xB6, +0xB4,0x8F,0x1F,0x56,0xE3,0xC7,0x20,0x7C,0xBD,0xAB,0xFA,0xE8,0x3F,0x0F,0x46,0x44, +0x8A,0xEA,0xE8,0x9D,0xD4,0xED,0xDF,0x35,0xED,0x12,0x7C,0x56,0xED,0x40,0x67,0x1B, +0x3A,0x9C,0x50,0xA8,0x6B,0xCE,0xCD,0xDC,0xAD,0x94,0x58,0x29,0xA1,0x6F,0x7A,0x01, +0x1C,0xC7,0x77,0x77,0xC3,0x4C,0xA2,0x52,0x8D,0xC5,0xB7,0x81,0xA3,0x79,0x92,0x33, +0xD9,0x81,0x7E,0xFF,0xC0,0x5F,0x46,0x73,0x67,0xDD,0x55,0x49,0x63,0xBF,0x0B,0xC3, +0x12,0x1A,0x64,0x19,0xBF,0xD5,0x48,0xD9,0x8B,0xCE,0x21,0xB8,0x81,0x95,0x3A,0xC5, +0xF2,0x0B,0x65,0x29,0x24,0xDF,0x00,0x94,0xB3,0x61,0xCC,0x29,0xDF,0x99,0xF5,0xB4, +0x4B,0x54,0x4D,0x3B,0x2E,0xDC,0xB4,0x1E,0xCB,0xE7,0x90,0x99,0x1F,0xF8,0x98,0x62, +0x62,0x55,0x4D,0x3E,0x29,0x84,0x45,0x31,0x9C,0xFA,0xDC,0x4B,0xDA,0x85,0x99,0x11, +0x88,0xC4,0xD7,0xB3,0x97,0xAC,0x3B,0x97,0x3A,0x29,0x86,0x79,0x1A,0x66,0x46,0xA5, +0x7C,0x44,0x0A,0x5C,0xAB,0xD3,0x65,0xFC,0x68,0x45,0xAE,0x9A,0xDE,0xE0,0xE3,0x0B, +0xB0,0x03,0x78,0x86,0xF6,0xDE,0x6D,0x8C,0xAC,0xD0,0x63,0x90,0x9E,0xA2,0x35,0xB5, +0x34,0xD6,0x0F,0x75,0x26,0x29,0xFA,0x7C,0x1B,0x1B,0x97,0x99,0x4C,0x1D,0x9B,0xD4, +0x39,0x6C,0x4C,0x90,0x36,0xE4,0xEA,0x2A,0xD6,0xEF,0xA1,0x34,0xA6,0x0A,0x66,0xCE, +0xFB,0xE4,0xEF,0x35,0x26,0x9F,0x49,0x29,0xEA,0x93,0x41,0x1D,0x7C,0x40,0xDD,0x68, +0x9E,0x01,0x73,0x47,0x48,0x77,0xD0,0xEF,0x7E,0x4D,0x3F,0xC4,0x45,0x1C,0x66,0xED, +0x0C,0xBC,0xA8,0x69,0x78,0xFE,0x91,0x35,0x9C,0xC2,0x3A,0xD7,0xFC,0x89,0x96,0xDB, +0x71,0x87,0xE3,0x96,0x72,0x02,0x02,0x00,0xA4,0xD7,0x8E,0x96,0x6B,0xEA,0x19,0xCE, +0x98,0x81,0x66,0x18,0x48,0x1F,0x9E,0xF4,0x57,0x32,0x3D,0x6A,0x95,0xBF,0x11,0x77, +0xB9,0x47,0x0B,0xB8,0x55,0xE1,0x86,0x25,0x9E,0xE5,0x8A,0xF8,0x2A,0xDA,0x0F,0x19, +0x9E,0x78,0xE5,0x2C,0x13,0x02,0x20,0xD5,0x49,0xC3,0x4A,0xB2,0xAF,0x37,0xAE,0xF7, +0x22,0x59,0x4E,0x39,0x18,0x27,0xE7,0x60,0xE8,0x74,0x9F,0x93,0xD5,0xBC,0x0B,0x35, +0xFA,0xB0,0xDB,0x41,0xED,0x39,0xF7,0x39,0x99,0x52,0x58,0x9C,0xAB,0x96,0xA3,0x96, +0xBC,0xA4,0xF8,0x6C,0x6A,0x99,0x76,0x0D,0x37,0x4B,0xC2,0x0D,0xFF,0xF0,0xA8,0x54, +0xF2,0xB8,0xD8,0x20,0x39,0x47,0x25,0x72,0x52,0x65,0x6E,0x0C,0xA1,0x0C,0x24,0xCC, +0x90,0x97,0xDD,0x5C,0xA2,0x12,0x2E,0xA9,0xE7,0x65,0xE9,0x1F,0x1A,0x10,0xFD,0xF5, +0x2E,0xAB,0x7D,0xFC,0xBC,0x61,0xA0,0x2C,0x2F,0x30,0x6F,0xA0,0x0B,0xBA,0x81,0x3B, +0x33,0x4C,0x3F,0xB2,0x97,0xA1,0x90,0x82,0x8C,0x78,0x4B,0xE0,0x74,0x1C,0xFE,0x9C, +0x71,0xEC,0x01,0x7F,0x18,0xC5,0x3F,0x40,0x9D,0x9B,0x29,0x87,0x04,0xAF,0xA7,0x57, +0xF7,0x44,0x72,0x6C,0xB0,0xA8,0x1D,0x7C,0xC8,0xD4,0x34,0x1D,0xE4,0xCE,0x69,0xF5, +0xC9,0x35,0xCB,0xDB,0x40,0x40,0x3F,0xFC,0x1F,0x14,0x94,0x34,0x00,0x09,0x3D,0xE8, +0x66,0x15,0xA5,0xAE,0x3A,0x43,0x09,0x48,0x44,0x6B,0x56,0x31,0xCF,0x42,0xAA,0xC2, +0xE5,0xE8,0x47,0xC0,0xA5,0x60,0x69,0x82,0x05,0x35,0x7F,0x5D,0xC5,0x81,0xC7,0x35, +0x3B,0x6B,0x15,0x63,0x07,0xC2,0xF0,0xEF,0x7C,0xE2,0x2E,0xC9,0xB7,0x39,0xDD,0x44, +0xD6,0x12,0x5C,0x14,0xF8,0xEE,0x90,0x82,0x6F,0xAA,0x0E,0xC9,0x2E,0x57,0x21,0x5C, +0x54,0x70,0x6A,0xBF,0xF8,0xC0,0xB1,0x1A,0xBB,0x4C,0xC9,0x1E,0x8B,0xB1,0x3E,0x25, +0x1E,0xAA,0x1A,0xB3,0x41,0x22,0xDE,0xA6,0x69,0x3F,0x6C,0x89,0x3B,0xF9,0xC8,0x09, +0x69,0x01,0xC7,0x17,0xCF,0x85,0x46,0x3D,0x72,0xFF,0x4B,0x8B,0xB6,0x78,0x32,0x5C, +0xA6,0xBC,0x1D,0x94,0x30,0x8A,0xB8,0x3F,0x24,0xF5,0x88,0xF0,0x1C,0xD9,0x9C,0xAA, +0x25,0x87,0xCC,0xB4,0x19,0xBC,0x57,0x90,0x40,0x9A,0xF0,0xA4,0xB7,0x28,0x77,0x18, +0xF6,0xB0,0x6D,0x85,0x96,0xA6,0xF6,0x99,0x9A,0xFD,0x86,0x02,0x85,0x90,0xE0,0x26, +0xF2,0x2B,0xFB,0x03,0xDE,0xBC,0xB8,0x25,0xC3,0x89,0xF2,0x7F,0x09,0xFE,0x25,0x97, +0x03,0x07,0xC1,0x58,0x57,0xA8,0x62,0xA5,0xB3,0x8E,0xE1,0x52,0x02,0x69,0x28,0x0D, +0x5B,0xBF,0x91,0x1D,0xFB,0x97,0xE2,0x84,0x74,0xAD,0x91,0xF4,0xF0,0xA7,0xBF,0x12, +0x1E,0xFD,0xBA,0xA0,0x8D,0x7B,0xC6,0x0A,0x2B,0x0C,0xAC,0x9C,0x98,0xD3,0x72,0x74, +0x4D,0x4B,0xE4,0x5C,0x3B,0x02,0xBA,0xD9,0x08,0x64,0x15,0x70,0x08,0x1F,0x59,0x77, +0x41,0x93,0xB3,0x73,0xC4,0x11,0x82,0xF3,0x72,0xF6,0xB4,0xBE,0x47,0x33,0x35,0x10, +0x90,0x78,0xC1,0x7A,0xD2,0x83,0x0B,0xC5,0x7B,0x0F,0x79,0x45,0xE5,0xD9,0xA0,0xA5, +0x50,0x64,0xD7,0x75,0x84,0xF2,0x7B,0xAA,0x99,0x19,0x47,0xA8,0xDE,0x28,0x2F,0x66, +0x07,0xA2,0xB3,0xA2,0x0A,0x65,0x89,0x9F,0x31,0xBA,0x88,0x2D,0x8C,0xC1,0xBE,0x3E, +0x98,0x13,0xF6,0x3D,0x59,0xED,0xE9,0x7B,0x92,0x15,0xF7,0x44,0x50,0x5E,0xAD,0x80, +0xD5,0x82,0xD1,0x41,0xF5,0x35,0x6A,0x1E,0xAD,0x82,0xA1,0xAF,0xE3,0x0E,0xF9,0x9F, +0x0B,0x44,0x1F,0x56,0xF6,0xFF,0xC8,0xC0,0xD7,0xC1,0xFF,0x8A,0x7B,0x5C,0x5A,0x86, +0x82,0x1D,0x77,0x4F,0x77,0xC2,0xD9,0x00,0xBC,0xFE,0xDC,0xEF,0xBA,0x55,0x78,0x56, +0x16,0x3D,0x2E,0x45,0x23,0x0F,0xBE,0xE8,0xE5,0xAE,0x19,0x14,0x8D,0x7A,0xAF,0x58, +0x47,0x2B,0x4E,0x0E,0x94,0x24,0x67,0x19,0x01,0x4F,0xC8,0xDA,0x78,0x56,0xF7,0xA1, +0x86,0x2A,0x79,0x62,0xEE,0x6A,0xB7,0x35,0xB6,0xEE,0xCB,0x78,0xA9,0xD1,0x52,0x86, +0x3A,0x6F,0xD6,0xFD,0xD9,0x9C,0xEE,0x94,0xAF,0xD6,0xE1,0x8E,0xE5,0xF1,0x56,0x89, +0x3A,0x6D,0xCE,0xE4,0x85,0x77,0xA6,0x1E,0x4F,0x2D,0x85,0x6C,0xF0,0x86,0x4B,0x31, +0xF5,0xFD,0xE8,0x9F,0x8F,0x3B,0xCB,0x94,0x7E,0xEC,0x95,0xBD,0xEC,0xC0,0xAE,0xBA, +0x9F,0x6C,0x14,0x4A,0x87,0x41,0x80,0xB6,0xC5,0xFB,0x35,0x8F,0xAC,0x78,0x98,0x4D, +0x73,0x95,0x49,0x0E,0xE2,0x60,0x0F,0x21,0x8A,0x57,0xD7,0xF9,0x6F,0x21,0xDC,0x1A, +0x5E,0x3F,0x91,0xB7,0xF3,0x6C,0xE1,0x2C,0x58,0x7C,0x1A,0xF1,0x4B,0x48,0xD8,0x68, +0x08,0x11,0x1C,0x94,0x8E,0xCE,0xFB,0x31,0x99,0x01,0x42,0xB9,0x94,0x4B,0x3E,0xE7, +0x8C,0xBD,0x29,0xC3,0x24,0xBD,0xC4,0xE7,0xEC,0xB3,0xF6,0x7B,0x67,0x3A,0x52,0x79, +0x9F,0xA9,0xCC,0xFD,0xF1,0xA0,0x7C,0x92,0x49,0x7C,0xC8,0xB1,0xF1,0x2B,0xC7,0xBA, +0x8D,0x35,0xDD,0x70,0x5C,0xA8,0xDD,0xF5,0xE2,0x3D,0xBD,0x8C,0x00,0x52,0x2B,0xA8, +0xE5,0x3A,0xE0,0xE4,0x2C,0xBB,0x06,0x8B,0x21,0xAE,0xE5,0x63,0xFC,0xB1,0xEF,0x25, +0xE1,0x47,0x2D,0x9E,0xCF,0xA8,0xA9,0x8F,0xCF,0x0C,0x88,0xD3,0xD8,0x75,0x8B,0xE7, +0xA7,0x97,0x44,0x9B,0x6D,0x93,0x1F,0xA2,0x66,0x75,0x66,0xD1,0x43,0x2F,0x27,0x86, +0x4D,0x35,0xC3,0xDC,0xDF,0xC5,0xDC,0xC7,0x95,0x16,0x6E,0x35,0x1F,0xCA,0xEB,0xF5, +0xA0,0x5F,0x1A,0x70,0x5B,0x81,0x18,0x48,0xAE,0x90,0x6A,0xE5,0xA3,0x32,0xAE,0x00, +0xEE,0x23,0x13,0xA9,0xBF,0xAA,0x60,0x4E,0xD8,0x39,0xCD,0x48,0x4B,0xA9,0x56,0x20, +0x7F,0x57,0x84,0x20,0x3B,0x0E,0x01,0xA1,0x98,0xF4,0xBF,0x4A,0x9D,0x30,0x72,0x12, +0xC0,0x0F,0x0C,0x3A,0x73,0xD9,0x5D,0xC5,0x31,0x69,0x72,0x64,0x94,0x2C,0xB2,0xBA, +0x1E,0xB7,0xEC,0xA3,0xB4,0xF5,0x7E,0xDB,0x5A,0x6E,0x13,0xED,0xEA,0xE0,0xD6,0x6C, +0x6F,0x62,0xBB,0x8A,0x86,0xE6,0x72,0xCD,0x94,0x69,0x86,0x66,0x62,0x7D,0x7A,0x5F, +0x9B,0xE1,0xC7,0x13,0xE7,0xD3,0x1B,0x8D,0xC8,0x28,0x4A,0x6E,0x97,0x44,0xEE,0xAB, +0x86,0xCC,0x4C,0x98,0xC0,0x60,0x62,0xB3,0x9D,0x1C,0x18,0x6C,0x47,0x24,0x82,0x3C, +0xB1,0xD2,0x56,0xAD,0xB9,0xF0,0xB9,0xC6,0x22,0x6E,0xD4,0x3F,0x9E,0x37,0x7C,0x56, +0x51,0x6A,0x73,0x88,0x48,0x4A,0xAE,0xE1,0x25,0x8D,0x4E,0x54,0x6B,0x11,0xB0,0xE0, +0xF9,0x8C,0xFB,0x23,0x5C,0xE0,0xE6,0xC6,0xFD,0x88,0x48,0x62,0xFF,0x3B,0x3A,0xA4, +0xCB,0xA6,0xD0,0xFE,0xBC,0xE4,0x8E,0xEB,0x68,0xC0,0xAB,0xCB,0x3B,0x11,0x50,0x81, +0xD4,0xF5,0x6F,0xD4,0x61,0x07,0x1C,0x52,0x08,0x7D,0x5C,0x2E,0x45,0x02,0x82,0x90, +0xA9,0x33,0xCA,0x00,0x4A,0x6E,0xF2,0xC2,0xEF,0xD3,0x2A,0xC2,0x99,0x96,0x22,0x45, +0xE6,0xC0,0xD0,0xF8,0x51,0x79,0x13,0x6C,0xD8,0x46,0x47,0xB4,0x91,0x98,0x42,0xF5, +0xF0,0x3C,0x82,0xF1,0x30,0xC8,0x45,0xDE,0x61,0xA0,0x0D,0xE5,0xD5,0xF4,0x41,0x65, +0x66,0xA5,0x25,0xEC,0xA3,0xC8,0xD6,0x65,0xED,0xDE,0x66,0x0E,0xDA,0xB3,0x19,0xC3, +0x34,0x34,0x17,0x2E,0x99,0xD7,0xDF,0x94,0x67,0xBC,0xD7,0x27,0xA9,0xD9,0xA5,0xF4, +0x85,0xDE,0x31,0x42,0x0D,0x8E,0xA1,0xFD,0xE5,0xC0,0x69,0x64,0x3F,0xF7,0x60,0x2A, +0xDE,0xA8,0x35,0xD9,0x92,0x9A,0x54,0x67,0x8E,0x18,0x86,0x36,0x0D,0x43,0xB9,0x39, +0x90,0x5C,0x6B,0xA7,0x9F,0x17,0x4A,0xE9,0xFC,0x6C,0xFC,0xC7,0xED,0x53,0xE8,0xF5, +0x44,0x52,0x0F,0xAD,0x6E,0x16,0xE2,0x60,0xD5,0xAA,0xA6,0x0C,0xF4,0x16,0x0D,0xC5, +0x2D,0x5E,0x26,0x46,0x6B,0xB0,0x0D,0x3F,0xB0,0xEE,0x87,0x6B,0x65,0x43,0xCB,0x24, +0x46,0xDA,0x07,0xF4,0xB4,0x0B,0xB7,0x47,0x2D,0x46,0x46,0x68,0xE7,0x1A,0x92,0x06, +0xE1,0x2D,0x34,0x6A,0x1E,0xA3,0xAD,0x2D,0x1B,0xFD,0x59,0xC8,0x2A,0xFE,0x4F,0xFB, +0x66,0x7B,0x5A,0xC6,0xC6,0xC3,0x3F,0x01,0x66,0x0F,0x9A,0xA0,0xFC,0x7C,0x3E,0x20, +0x52,0x4A,0x33,0xD0,0xAD,0xFD,0x96,0x0C,0xA8,0x71,0x0A,0x46,0xA1,0x80,0x97,0x2B, +0x9E,0xAF,0xF7,0x5B,0xA9,0xB9,0xD4,0xDA,0xC4,0xFA,0xD9,0xA2,0x4D,0x23,0x17,0x97, +0xBB,0x3C,0xB7,0x9A,0x27,0xCE,0x28,0xEA,0x50,0x7C,0x9E,0x4A,0x02,0x78,0xA7,0x8A, +0xE5,0xFE,0x3D,0x9C,0xC0,0x14,0x17,0x91,0x66,0xB7,0xEC,0x0C,0xB7,0x42,0x09,0x92, +0x3A,0xAE,0x86,0x3E,0x71,0x97,0x5A,0x2E,0x22,0xA3,0xF3,0x7B,0xE2,0xAA,0x3B,0x0F, +0x14,0x80,0x98,0x3E,0xDA,0xFA,0xCF,0x07,0x20,0x41,0xCC,0x59,0xC3,0xC1,0xDB,0x3E, +0x34,0xF2,0x10,0x6C,0x46,0xC3,0xB9,0xBB,0xAF,0x46,0x34,0x5A,0x02,0xA1,0xDA,0xD7, +0xB7,0xAB,0x49,0x88,0x5C,0x7F,0xA3,0xD9,0x4D,0x76,0xF0,0xA4,0xF8,0x1A,0xFD,0x5C, +0x52,0x0B,0xC0,0x0D,0xB7,0xF1,0xE2,0x24,0x00,0xE0,0x9A,0xF7,0x2E,0xA3,0xD1,0xC6, +0xE9,0xCC,0xC1,0x0A,0x4F,0xF2,0x87,0xDA,0x77,0x63,0x2B,0x7B,0xCB,0xDE,0xC5,0x0E, +0x92,0x4E,0xBB,0xD5,0x38,0x0B,0x90,0xAC,0xB9,0x4F,0xAF,0x14,0x6A,0x80,0xA4,0x5E, +0x5F,0x6D,0x5A,0x67,0xBD,0xC7,0x83,0xF7,0xF1,0x4D,0x9F,0xF5,0xDD,0x50,0x39,0x8F, +0xAC,0x01,0x06,0x1F,0x0B,0xA8,0x3D,0x66,0x0B,0x80,0x87,0x03,0x5E,0xF9,0xB9,0xD1, +0xC6,0xD8,0x8B,0xDF,0x7D,0x5A,0xE2,0x13,0x74,0x60,0xB1,0x9C,0x3C,0x07,0xEF,0xF3, +0xCB,0x62,0x77,0x6D,0x15,0xE8,0xEE,0x62,0x2E,0xB6,0x9B,0xA5,0x95,0xAF,0x69,0xF9, +0x8D,0x22,0x48,0xA8,0x79,0xA6,0xD1,0xDB,0xDB,0x29,0x7C,0xBD,0x53,0xB9,0x40,0x86, +0xA1,0xE4,0xF2,0xA9,0xC7,0x14,0x64,0x8A,0x39,0x24,0xF3,0xC6,0xAC,0x9E,0xCB,0x58, +0x0F,0x6C,0x76,0x39,0x8D,0x8D,0x20,0xD4,0x3D,0x8A,0x05,0xFB,0xD4,0x5B,0x16,0x74, +0xA7,0xD8,0x03,0x9E,0xCB,0x3A,0xD1,0x71,0xD6,0x6E,0x30,0x70,0x3B,0x5A,0xB9,0xB9, +0x1F,0xCE,0xDF,0x52,0xE8,0xAF,0xF8,0x59,0xE6,0xFA,0xF0,0xF9,0x96,0x23,0xF9,0xA1, +0xF5,0x33,0x2D,0xAE,0x5D,0xFD,0x84,0xAD,0xD9,0x50,0x6C,0x62,0xF6,0xB5,0x43,0x97, +0xA1,0x0C,0x40,0x23,0xD9,0x69,0xEF,0xBA,0x6B,0x5D,0x75,0x17,0xC7,0x9C,0x8D,0x58, +0xBB,0xD7,0x60,0x77,0x6A,0x5B,0x27,0x2E,0x40,0x8F,0x3F,0x57,0x33,0xF3,0xE9,0x58, +0x22,0xC0,0xA1,0x53,0x55,0x11,0x61,0x88,0x58,0x4F,0x5F,0x25,0x04,0x5C,0x90,0x7F, +0x21,0xD4,0xCA,0x44,0x94,0x8A,0x3A,0x55,0xFF,0xD1,0x5C,0x8E,0x97,0xF8,0x24,0x44, +0xDB,0x51,0xF0,0xA7,0xD1,0x0F,0x72,0x58,0xEE,0x57,0xA7,0x4B,0xF3,0xE6,0xA2,0x03, +0x65,0xAD,0x2E,0xA1,0x37,0x25,0x5A,0x87,0x33,0xF1,0x93,0x2A,0x75,0x97,0x57,0xC6, +0x12,0x73,0xC2,0x39,0xE2,0x32,0x4A,0xDF,0x9C,0x35,0x6B,0x8E,0x29,0x7B,0x73,0xA6, +0x92,0xE7,0x39,0xF5,0x58,0x4E,0x43,0xD2,0xAF,0x13,0x1D,0x9C,0x49,0x64,0x96,0xB9, +0x1C,0x79,0x31,0x12,0xD1,0xCF,0x0B,0xF7,0xB3,0x51,0xA2,0xAA,0x2E,0xCF,0x08,0x50, +0x19,0x81,0x77,0xE5,0x01,0x82,0xFB,0xE6,0x3B,0xC7,0x76,0xA0,0x51,0x62,0x5A,0x8D, +0x07,0xEC,0x40,0x02,0x93,0xB2,0xB5,0x54,0xEB,0xF0,0x54,0x41,0x62,0x0D,0xCC,0x6D, +0xC0,0xDC,0xF8,0x75,0xFB,0xB6,0x24,0xAC,0x88,0xD8,0x54,0x6A,0x80,0xE3,0x50,0x29, +0x56,0xBB,0x8E,0xA7,0x93,0xBE,0x46,0xCF,0x99,0x94,0xBD,0x76,0x7B,0x2C,0xE0,0x8B, +0x3D,0x0D,0xD1,0x05,0x68,0x8B,0x38,0xEE,0xED,0x82,0x10,0x9A,0xF5,0x7B,0xCD,0x4A, +0x44,0xA7,0x8C,0x90,0x61,0xA1,0x61,0xDA,0x65,0xFB,0x20,0x2B,0x6A,0xA4,0x9C,0xAA, +0xE8,0xE9,0x1B,0x6F,0x23,0x4F,0x5D,0x81,0x1C,0xDA,0xEC,0xA4,0x4B,0xB6,0x58,0xCC, +0xB4,0x6F,0xCA,0x81,0x8B,0xD7,0x03,0x29,0x85,0x5C,0x56,0xB7,0x8A,0xBE,0xED,0x8E, +0x29,0x76,0x78,0xCD,0x71,0xF1,0x7C,0x7F,0xCB,0x80,0xA8,0x40,0x92,0x7B,0x80,0xC3, +0xB1,0x31,0x1B,0x0E,0xB3,0xFF,0x4D,0x2B,0x95,0xF3,0xFD,0xF6,0xFD,0xF2,0xB2,0x5C, +0xCD,0xD6,0x3B,0xB3,0xCA,0x5A,0x07,0xFD,0x79,0x5C,0x8E,0x4B,0xA7,0x33,0x97,0x0C, +0x52,0x2A,0x71,0xA5,0x5E,0xDD,0x2F,0xC5,0x3B,0xA5,0x2B,0xC3,0xE1,0x15,0xB2,0x07, +0x77,0xDB,0xE4,0x02,0xD9,0x8F,0xFE,0xC7,0x0E,0xC8,0x5B,0xDB,0x45,0x12,0xEF,0x76, +0x83,0x1F,0x25,0xCA,0x38,0x91,0x52,0xCD,0x1D,0xC2,0x8A,0xC0,0x17,0x97,0x8D,0x7F, +0x92,0xC7,0x9F,0x18,0xA3,0xE7,0x52,0x82,0x15,0x71,0x30,0xCA,0xCA,0x6F,0xC4,0x81, +0xB5,0x52,0x83,0xBE,0xB2,0x8D,0x15,0x99,0xD4,0x60,0x82,0xB5,0x70,0x3C,0x13,0x39, +0x4F,0x17,0xD3,0x12,0x38,0x64,0x0E,0xCA,0x6E,0xFB,0xC0,0x74,0x4D,0xDC,0x11,0xD1, +0x27,0x8C,0x26,0xCF,0x3F,0x44,0x66,0x67,0x34,0x3D,0xEF,0xDB,0x9A,0xAB,0x2F,0x0B, +0x76,0xE9,0xD8,0xE8,0x11,0x10,0x98,0x8E,0x80,0x4A,0xE2,0x40,0x8D,0xC6,0x6D,0x15, +0xEA,0xB8,0x31,0xF7,0xCE,0x95,0xC9,0xB8,0x2B,0xD8,0x40,0x62,0x3B,0xF7,0xA3,0x5B, +0x3C,0xC9,0x7A,0x3C,0x9C,0xDB,0x57,0xE2,0x54,0xC8,0xB4,0xFD,0x05,0xEF,0x73,0xDF, +0x20,0x21,0xF9,0x97,0xED,0x2F,0xC5,0xE4,0x33,0x59,0x82,0x51,0x54,0xDE,0x17,0x4A, +0x76,0xD7,0x4B,0xA8,0xED,0x4A,0xDD,0x6C,0xFB,0xBE,0xE0,0x14,0x39,0x4B,0x35,0x86, +0x71,0x14,0x86,0xDA,0x83,0x8B,0x89,0x13,0x16,0xE5,0x30,0x24,0x34,0x39,0xA6,0xC0, +0x1A,0x2A,0x08,0xDA,0x27,0x82,0xAD,0x3D,0x56,0x41,0x19,0xBD,0x9C,0x4D,0x5E,0x38, +0x92,0x68,0x9D,0x61,0x6E,0x98,0xE3,0xFC,0x32,0xE7,0xDF,0x17,0xE1,0x4B,0x74,0xD3, +0xA5,0x89,0x9D,0xCA,0x29,0xFE,0x45,0xA9,0x1D,0x7D,0xA7,0x47,0xED,0xEF,0x0B,0x0D, +0xDB,0x9C,0x37,0x52,0x4E,0x40,0x2E,0x07,0x7A,0xBE,0x71,0xFE,0x7F,0x6C,0x6B,0xA7, +0x14,0x04,0x90,0x04,0x04,0x14,0x03,0x0A,0x05,0x38,0x04,0x80,0x07,0x83,0x40,0x83, +0x40,0x10,0x10,0x00,0x00,0x11,0x1E,0x01,0x1E,0x05,0x9C,0x16,0xA8,0x01,0x2D,0x06, +0x03,0x0E,0x03,0x6A,0xDB,0x02,0xED,0xAF,0x78,0xE6,0xF0,0x05,0x05,0x1E,0x1E,0xA0, +0x0A,0x0A,0x3C,0x01,0x01,0x01,0x07,0x04,0x01,0x0A,0xC0,0x0A,0x46,0x26,0x26,0x80, +0x80,0x00,0x00,0x8C,0x6E,0x40,0x80,0x4D,0x17,0x00,0x40,0x24,0x20,0xFF,0x00,0x18, +0x00,0x00,0x00,0x20,0x04,0x80,0x07,0x1E,0x28,0x18,0x00,0x18,0x00,0x20,0x04,0x68, +0x07,0x1E,0x05,0x1E,0x03,0x0A,0x00,0x0A,0x0F,0x04,0x05,0x0F,0x1E,0x28,0x03,0x01, +0x01,0x00,0x01,0x01,0x27,0x0A,0x05,0x0C,0xFA,0x19,0xFA,0x01,0x03,0x01,0x6B,0x0F, +0x4B,0x00,0x0C,0x0A,0xDC,0x05,0x0A,0x0C,0xC8,0xFF,0x00,0x18,0x82,0x18,0xC8,0x20, +0x82,0x2D,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x0C,0xC3,0x0C,0xFF,0x10, +0xC3,0x16,0xC3,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x19,0x10,0x10,0x03,0x03, +0x0C,0x1E,0x00,0xB8,0x00,0x80,0x03,0x1B,0x00,0x00,0xFF,0x46,0x00,0xFF,0xFF,0xBF, +0x96,0x00,0xE8,0x03,0x00,0xC0,0x80,0x01,0x80,0x0A,0x00,0x00,0x00,0x00,0x14,0x00, +0x00,0x00,0x41,0x01,0x37,0x1F,0x0C,0x0C,0x30,0x30,0x00,0x35,0x01,0x08,0x00,0x00, +0x64,0x00,0x01,0x00,0x06,0x06,0x07,0x07,0x00,0xC8,0x00,0x01,0x01,0x01,0x03,0x00, +0x14,0x00,0x14,0x00,0x00,0x00,0x05,0x00,0x03,0x2C,0x00,0x14,0x00,0x14,0x00,0x00, +0x01,0x02,0x00,0x01,0x28,0x00,0x14,0x00,0x14,0x00,0x00,0x02,0x02,0x00,0x01,0x29, +0x00,0x14,0x00,0x14,0x00,0x00,0x03,0x02,0x00,0x01,0x29,0x00,0x14,0x00,0x14,0x00, +0x00,0x04,0x02,0x00,0x01,0x2A,0x00,0x14,0x00,0x1C,0x00,0x00,0x05,0x02,0x00,0x01, +0x2B,0x80,0x1C,0x00,0x1C,0x00,0x00,0x00,0x05,0x00,0x03,0x2C,0x03,0x26,0x00,0x1C, +0x00,0x00,0x00,0x05,0x00,0x03,0x2C,0x03,0x26,0x00,0x1C,0x00,0x00,0x04,0x02,0x00, +0x01,0x2A,0x03,0x26,0x00,0x1C,0x00,0x00,0x07,0x02,0x00,0x01,0x2D,0x03,0x26,0x00, +0x1C,0x00,0x00,0x09,0x05,0x00,0x02,0x27,0x03,0x26,0x00,0x1C,0x00,0x00,0x0A,0x05, +0x00,0x02,0x28,0x02,0x21,0x00,0x1C,0x00,0x00,0x11,0x03,0x00,0x01,0x25,0x02,0x21, +0x00,0x1C,0x00,0x00,0x12,0x03,0x00,0x01,0x26,0x01,0x1C,0x00,0x1C,0x00,0x00,0x00, +0x09,0x00,0x02,0x25,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, +0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x0F,0x0F,0x07,0x01,0x05,0x0F,0x0F,0x00,0x00,0x00,0x1B,0x00,0x04,0x00,0x50, +0x00,0x0A,0x64,0x14,0x01,0x28,0x27,0x27,0x28,0x00,0x35,0x01,0x01,0x34,0x00,0x03, +0x00,0x02,0x00,0x00,0x0C,0x00,0x09,0x05,0x01,0x01,0x01,0x07,0x02,0x01,0x02,0x00, +0x00,0x02,0x07,0x00,0x00,0x03,0x03,0x00,0x1B,0x28,0x05,0x00,0x00,0x18,0x18,0x00, +0x05,0x02,0x01,0x10,0x08,0x03,0x12,0x04,0x96,0x3C,0x46,0x0A,0x20,0x01,0x94,0x05, +0x14,0x30,0x08,0x00,0x33,0x07,0x08,0x0A,0x0A,0x0A,0xFF,0xFF,0xFF,0xFF,0xA6,0x00, +0x14,0x00,0x05,0x5B,0x00,0x06,0x06,0x05,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, +0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, +0x0F,0x01,0x02,0xB3,0x04,0x10,0x46,0x32,0x0A,0x32,0x14,0x20,0x46,0x04,0x00,0x00, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x51,0x51,0x51,0x51,0xCD,0x0D,0x04,0x83, +0x10,0x10,0x10,0x10,0x0D,0x0F,0x12,0x0D,0x14,0x16,0x13,0x19,0x17,0x1B,0x1A,0x1F, +0x1C,0x1E,0x15,0x11,0x18,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1D,0x1C, +0x1B,0x1A,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x0F,0x0E,0x0D,0x0C, +0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x10,0x00,0x10,0x00,0x10,0x00, +0x10,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x8D,0xA6,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0xFF,0x00, +0x64,0x32,0x00,0x01,0x64,0x00,0x02,0x00,0x02,0x14,0x08,0x00,0x00,0x00,0x3C,0x00, +0x28,0x00,0x0A,0x04,0x50,0x05,0x00,0x64,0x02,0xC8,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE9,0xF0,0xD7,0xDF, +0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0x03, +0x02,0x05,0xAF,0x1E,0x05,0x01,0xC0,0x80,0x00,0x00,0x00,0x15,0x05,0x00,0x00,0xFF, +0xFF,0xFF,0x01,0x00,0x56,0x1D,0x10,0xC0,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x53,0x33,0x33,0x32,0x30,0x54,0x00,0x00,0x00,0x00,0x01,0x03,0x0F, +0x00,0x03,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, +0x14,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x00,0x12, +0x06,0x01,0x12,0x28,0x23,0x0D,0x04,0x01,0x01,0x24,0x00,0x09,0x00,0x21,0x34,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xAA,0x00,0x80,0x04,0x1B,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0x00,0xFF,0xFF,0x00,0xC0,0x80,0x00,0x80,0x0A,0x00,0x00,0x00,0x00,0x14,0x00,0x00, +0x00,0x01,0x01,0x32,0x21,0x0C,0x0C,0x30,0x30,0x00,0x31,0x01,0x06,0xFF,0x08,0x00, +0x00,0x00,0x00,0x1E,0x00,0xA6,0x01,0x00,0x00,0x1B,0x28,0x1C,0x00,0x80,0x28,0x04, +0x08,0xA6,0x01,0x0F,0x00,0x11,0x00,0x19,0x2B,0x44,0x50,0x2D,0x02,0x01,0x3A,0x00, +0x1E,0x54,0x44,0xC8,0x61,0xF8,0xFB,0x0F,0x0F,0xA5,0x05,0x7F,0x6E,0xBF,0xBF,0x80, +0xBE,0xC4,0x30,0x9F,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x56,0x11,0x00,0x01,0x54,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x51,0x51,0x51,0x51, +0xCD,0x0D,0x04,0x83,0x10,0x10,0x10,0x10,0x83,0xFF,0x03,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x01,0x00,0x01,0x1A,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0D,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0x00,0x19,0x2B,0x8B,0x85,0x88,0x10, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x09,0x00,0x00,0x01,0x55,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x32,0x00,0x01,0x1E,0x00,0x02, +0x00,0x02,0x19,0x0D,0x01,0x01,0x01,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00, +0x0C,0x96,0x1E,0x05,0x1E,0x05,0x18,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x18,0x00,0x01,0x51,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +#endif + diff --git a/drivers/input/touchscreen/synaptics_firmware_s1302.h b/drivers/input/touchscreen/synaptics_firmware_s1302.h new file mode 100755 index 0000000000000..4c289eed186ae --- /dev/null +++ b/drivers/input/touchscreen/synaptics_firmware_s1302.h @@ -0,0 +1,2969 @@ +#ifndef SYANPTICS_UPDATE_FIRMWARE_S1302_H +#define SYANPTICS_UPDATE_FIRMWARE_S1302_H + +#define FIRMWARE_VERSION (0x000000003) + +const unsigned char Syna_Firmware_Data[] = { +0xE6,0x17,0x60,0x55,0x00,0x00,0x01,0x05,0x00,0xB0,0x00,0x00,0x00,0x02,0x00,0x00, +0x53,0x31,0x33,0x30,0x32,0x00,0x00,0x00,0x00,0x00,0x16,0x05,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x44,0x53,0x34,0x20,0x52,0x34,0x2E,0x30,0x2E,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x1E,0x9F,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x49,0x32,0x43,0x00,0x0B,0x00,0xFF,0x00,0x0C,0x0D,0x20,0x00,0x00,0x00,0x00,0x00, +0x49,0x32,0x43,0x00,0x0B,0x00,0xFF,0x00,0x0C,0x0D,0x20,0x00,0x00,0x00,0x00,0x00, +0x91,0xD6,0x19,0x4E,0xC9,0xB5,0x1A,0x08,0x12,0xE1,0x40,0xE0,0x4A,0xF3,0x05,0xBC, +0x05,0xFB,0x77,0x02,0xF1,0x47,0x31,0x91,0x30,0x48,0x3D,0xC5,0xC8,0xB9,0x2D,0xA5, +0xE6,0x57,0xA8,0x32,0x08,0x81,0x17,0x75,0x35,0x78,0xE7,0x40,0x07,0x7D,0xF6,0xB2, +0x79,0xFC,0x99,0xE2,0xA1,0x4C,0x84,0xEA,0xC8,0x83,0x59,0xAB,0x13,0x21,0xBE,0x62, +0x5A,0x36,0xBC,0x1F,0xA6,0x67,0x54,0xC0,0x7F,0xA5,0x28,0xA5,0x95,0x08,0x97,0x72, +0x6F,0x28,0xF1,0x32,0xE2,0xB6,0x6E,0x25,0x39,0x16,0x64,0xC1,0xF9,0x4E,0xD2,0xAA, +0x3E,0xDA,0x84,0xD8,0x60,0xC6,0x5A,0x12,0x3A,0xE1,0x4B,0x2E,0xCC,0x32,0x1A,0x70, +0xE4,0xD9,0x76,0xF5,0xDF,0xF0,0x49,0xC6,0xDE,0x66,0xBE,0x99,0x0D,0x2A,0x2C,0xF7, +0x01,0x03,0xBB,0xE4,0x5B,0xC7,0x1F,0x95,0x7D,0x19,0xC8,0xD5,0xC4,0x82,0x0C,0x8F, +0x25,0x43,0xCD,0x3F,0x23,0x0A,0x5D,0x33,0xA1,0x44,0x1D,0x17,0x00,0xBD,0xE9,0x2F, +0x9F,0xAE,0x16,0x04,0xBA,0xAE,0xDF,0xAE,0xA7,0xFB,0x82,0xCA,0x62,0x08,0xC8,0xC3, +0x48,0x52,0x5F,0x3E,0xDE,0x6A,0xF5,0x78,0xC9,0xE6,0xDA,0x39,0xB6,0x51,0x60,0xED, +0x52,0xFA,0x69,0xE6,0x41,0xFD,0xAB,0x75,0xB5,0x90,0xC1,0xE8,0x0A,0x0A,0x87,0xC7, +0x28,0xD7,0xD3,0x85,0x37,0xE4,0x27,0x67,0xB7,0xA8,0x47,0x19,0x37,0xEB,0xDD,0x06, +0x8F,0x52,0xFD,0x58,0xD0,0xC0,0x27,0x7C,0xAB,0xE8,0x51,0xE9,0x9D,0x4C,0x3D,0x6A, +0xA1,0x20,0x7C,0xBD,0xAF,0xB0,0x4B,0x95,0xAA,0x2B,0x02,0xDC,0xAD,0x50,0xC9,0x36, +0x99,0x5E,0x92,0x41,0x8B,0x54,0x4D,0xEE,0x59,0xB8,0x8E,0x96,0xEC,0x9E,0x5B,0x54, +0xD4,0x52,0x56,0x85,0x92,0x00,0x3F,0x22,0x28,0x6C,0xE2,0x36,0x79,0x2E,0xAB,0x75, +0xED,0xD7,0x96,0x80,0xA5,0x0A,0xA1,0x8D,0xC0,0x94,0x4A,0x88,0x7E,0xC5,0x5E,0x5A, +0xD5,0x10,0x96,0xF8,0xCB,0x86,0x5A,0x2D,0x8D,0xCA,0xE7,0x1B,0xC7,0x70,0x1F,0x41, +0x55,0xB4,0xF0,0x96,0xC8,0x36,0xDB,0x2A,0x42,0x57,0x01,0xA5,0xA2,0xBB,0x2F,0x9D, +0xF7,0x84,0x38,0x79,0x89,0xD2,0x62,0xF6,0xD9,0xD7,0x64,0x88,0x47,0x52,0x7A,0x4C, +0xB5,0x38,0x7F,0xA5,0xF8,0x1E,0x6A,0xF9,0xB9,0x39,0xB1,0x39,0x5B,0x0A,0x10,0x7C, +0xDA,0x00,0x17,0xD6,0x14,0x9B,0x98,0x83,0x75,0x5E,0x05,0xFE,0x4C,0x50,0x28,0x09, +0x69,0x1A,0x65,0x0E,0xEC,0x59,0x53,0xCD,0x74,0x2B,0xA4,0xB8,0xCE,0xF3,0x5A,0x7C, +0xCC,0x29,0x8B,0x93,0x56,0xC3,0xEF,0xBB,0x12,0x69,0xB1,0xF0,0x26,0xE8,0x7F,0x4B, +0x23,0x34,0xE9,0x8A,0x71,0x38,0xE7,0x11,0xAC,0x37,0x3B,0x7B,0xA7,0xB4,0x86,0xF7, +0xE7,0x2C,0x68,0xE8,0xA1,0xDB,0xCC,0x39,0xC2,0x42,0xC0,0x51,0xBC,0xE9,0x44,0x73, +0x84,0xD4,0x4F,0xE4,0x60,0x3F,0x9B,0x0D,0xA5,0x8B,0x5D,0xBF,0xAF,0xE4,0x3D,0x24, +0xE0,0xC8,0x49,0xC2,0x5C,0xDB,0x9E,0x50,0x8F,0xA0,0x3D,0x33,0x00,0x65,0x43,0x72, +0x39,0x47,0x0B,0xA4,0x33,0x94,0x60,0xEC,0x4D,0x04,0x38,0x1C,0x40,0xAC,0x57,0xF0, +0x80,0xA6,0x99,0xCC,0x0E,0xEB,0x85,0x0C,0x0B,0x49,0x05,0xD3,0x1B,0x87,0x5C,0x2D, +0x69,0x9A,0xC4,0xBC,0x89,0x3C,0x04,0x5A,0x70,0xB5,0xA5,0x12,0x99,0xD0,0x1B,0xDC, +0x13,0x20,0x8D,0x07,0xA5,0x4C,0x0A,0xD7,0xAE,0x92,0x8F,0x4E,0xA9,0x91,0x08,0xB7, +0xA3,0x2A,0x3E,0xBC,0xD7,0x1E,0x05,0x6C,0x54,0xFD,0x50,0xC8,0x55,0x94,0x0E,0x42, +0x2B,0xA3,0x7D,0x61,0x33,0x11,0x06,0xEA,0xAA,0x32,0xC2,0x08,0x21,0xBF,0x77,0x2B, +0x69,0x5F,0xBF,0x6B,0x64,0x61,0x45,0xD9,0x04,0xC0,0x16,0xEA,0xE5,0x88,0x05,0x34, +0x5B,0xEC,0x08,0xF8,0x1A,0x26,0xA7,0x61,0x1D,0xAC,0x78,0xA7,0x0B,0x20,0xC2,0x52, +0x73,0x61,0xB5,0xFA,0xC1,0x4B,0xCF,0x95,0x26,0x14,0x2F,0x10,0x92,0x37,0xF5,0xF3, +0xD4,0x87,0x23,0x66,0x34,0xE9,0xEB,0xBF,0x47,0x51,0xB0,0x18,0xB5,0x68,0xE3,0xE8, +0xF2,0xBD,0x06,0x9F,0x9A,0xE4,0x5C,0xEB,0x81,0xAE,0x75,0x8B,0x7D,0x02,0x30,0x8A, +0xB2,0x29,0x40,0xB2,0x38,0x15,0x65,0xA8,0x56,0x23,0x5C,0x6F,0x55,0x97,0x9C,0x62, +0xBC,0x13,0x3D,0x87,0x31,0xE6,0x1C,0x05,0xA6,0x97,0xD0,0x3A,0xE2,0xC5,0x63,0x80, +0x0D,0x11,0x74,0xF5,0xAD,0xD4,0x00,0xD2,0x02,0x27,0x03,0xE5,0x15,0x56,0x07,0x78, +0x43,0x1D,0x8D,0xE2,0xF4,0x8B,0xE3,0x2E,0xCF,0x51,0xD7,0x9A,0xA6,0xD9,0x44,0xAF, +0x0A,0x49,0xF8,0x85,0x98,0x56,0x87,0xB9,0x41,0xED,0x58,0xC0,0x9B,0xEA,0xD1,0x83, +0x46,0x53,0x40,0xF0,0x3E,0x67,0x4B,0x2B,0x64,0xF0,0xBC,0xC8,0x0E,0xAB,0xA6,0x9A, +0xC3,0xE6,0xA8,0x77,0xAE,0xD3,0xD0,0xE6,0xA2,0x20,0x94,0xC5,0xDF,0x90,0xF4,0x16, +0xA3,0x0A,0x03,0x2A,0x0C,0xC0,0xA5,0x63,0xD3,0xCB,0x70,0x79,0x53,0xB5,0x64,0x06, +0xF3,0xE2,0xB9,0x9A,0xA9,0x3B,0x38,0xCA,0x6E,0x35,0x6B,0xF5,0x18,0xED,0x83,0x9D, +0x28,0x71,0xB0,0xB4,0x4B,0xFF,0xDD,0xDA,0x32,0xF9,0x62,0x8E,0xF8,0x40,0x2D,0x91, +0xB4,0xD4,0x43,0x26,0x45,0xAB,0x9C,0x7C,0xEF,0x05,0xB0,0x0B,0x8F,0xED,0x69,0x7D, +0xC5,0x5F,0xA7,0x6B,0x36,0x22,0x32,0x2B,0xD3,0xB1,0xCF,0x73,0xDD,0x5F,0x1D,0x0E, +0x0B,0x78,0xFA,0x6F,0x62,0x10,0x27,0xE4,0xF5,0x72,0x14,0x44,0x39,0xC2,0x9A,0x2F, +0x6A,0x93,0x4A,0x4D,0x25,0x3C,0xE2,0xF0,0x60,0x46,0x8C,0x72,0xA0,0x8B,0x68,0x81, +0xDE,0x56,0xCE,0x39,0xF7,0xA3,0x27,0x37,0x30,0x9D,0x0F,0x89,0x22,0xC2,0x13,0xFC, +0x6F,0x51,0xB8,0x4A,0x19,0xB5,0xFC,0x62,0x8B,0xC8,0x88,0x57,0x09,0x16,0x73,0x3F, +0x9F,0xE0,0x85,0x94,0xF3,0xEF,0xB1,0x14,0xE7,0xA1,0xCB,0x79,0x6B,0xC5,0x9B,0xD3, +0x45,0x6F,0x38,0x55,0xD3,0x83,0x3A,0x16,0x66,0xC4,0x70,0x2D,0xED,0x08,0x8A,0x01, +0x1F,0x96,0x85,0xA3,0x3E,0x87,0x54,0x65,0x5C,0xC5,0x64,0x7B,0x4B,0xDA,0x64,0x0C, +0xDF,0xDC,0x13,0xD0,0xE3,0xC2,0x81,0xDF,0xB8,0x3E,0x7A,0x24,0xAB,0x32,0x55,0xDB, +0xDA,0x28,0x47,0x6F,0x79,0x2A,0x43,0xF4,0x1C,0x26,0x0B,0x65,0xDF,0x2D,0x42,0xBD, +0x11,0x93,0x07,0xEF,0xFB,0x4C,0x50,0xD0,0x37,0x93,0x62,0x72,0x7B,0xCA,0x52,0xCB, +0x68,0x13,0xE7,0x5B,0x7D,0x3A,0x4A,0xDF,0xFB,0xC6,0x26,0xE6,0x99,0xED,0x6C,0x5D, +0x12,0x32,0x5B,0x62,0x06,0xAE,0x62,0xA5,0xD7,0x42,0xA6,0x15,0xDF,0x96,0x54,0xF7, +0xB9,0xD2,0xF0,0x27,0x38,0x47,0xB2,0xD4,0x0D,0x3E,0xAB,0xFE,0xCD,0x31,0xD4,0xBB, +0xDF,0x5C,0x5B,0x86,0xAB,0x23,0xB8,0x27,0xA0,0x07,0x74,0x56,0x92,0x0F,0xE1,0x4A, +0x41,0x4F,0x8B,0x88,0x9E,0xA3,0x07,0x13,0x12,0xF1,0x02,0xAF,0x6E,0xE1,0x9C,0xB3, +0xA1,0x07,0xAC,0xD2,0x73,0x7B,0xDE,0xA9,0x61,0xBD,0x9F,0xF4,0x4D,0x1B,0x94,0x6C, +0xA5,0xE5,0xDA,0x73,0xE0,0x55,0x26,0xF3,0x2C,0x0D,0xB3,0xAB,0xD0,0xF1,0xCE,0xAD, +0x15,0x78,0xAE,0x23,0xD7,0x97,0x42,0xCC,0xA2,0x6C,0x8E,0x31,0x70,0x7D,0x07,0x13, +0x86,0x39,0x9E,0x59,0xCB,0x6F,0x73,0x6D,0xF1,0x12,0x47,0x9F,0xBF,0xBE,0x8B,0x17, +0xF8,0x64,0x47,0xDC,0x33,0x93,0xD6,0xA9,0xEB,0x0B,0x6C,0xAC,0xDB,0xB9,0x5A,0x77, +0x2A,0x32,0x0E,0x4A,0x8F,0x60,0xAD,0x41,0xC3,0xEE,0xF9,0x42,0xD2,0x59,0x48,0x07, +0x80,0x4E,0x29,0x3B,0x98,0xE9,0x11,0xDB,0xBA,0x2E,0xB5,0xDE,0x66,0xF1,0x2E,0x7D, +0x6D,0x37,0x49,0xA4,0x19,0xEF,0x40,0xB8,0x2A,0x35,0x27,0xE6,0xEC,0x3E,0x96,0x31, +0x2F,0x74,0xCE,0xBA,0x43,0xD1,0x03,0xA4,0x24,0xC0,0xB2,0x8C,0xF2,0x8B,0x87,0xD0, +0x12,0xF9,0xB3,0xFF,0x93,0xB0,0xA4,0x24,0xBB,0x2F,0x2E,0x33,0xCA,0x0B,0x49,0xF3, +0x0C,0xF5,0x87,0x8E,0x89,0x28,0xE8,0xA2,0xAD,0xC1,0xD6,0x58,0x34,0x1A,0x43,0x77, +0xE8,0x7B,0x61,0x97,0xD8,0x85,0x84,0x1F,0x59,0xC2,0xA6,0x00,0x16,0xC5,0xAA,0x30, +0x5B,0xA4,0x1A,0x65,0xD6,0x52,0x93,0xBC,0xFE,0x24,0x66,0xDC,0x2D,0x2A,0x02,0xC5, +0xA0,0x18,0x9C,0xD2,0x8A,0xFA,0x28,0x7A,0x90,0xF2,0xB6,0x7C,0xC5,0x6F,0xAB,0xFC, +0x48,0xB4,0xEE,0x10,0x8D,0x26,0x4A,0xC2,0x13,0xDA,0x8E,0xE4,0x75,0xE2,0x70,0xD3, +0xFD,0x9C,0x49,0x35,0x13,0xF9,0xB0,0x6D,0xC6,0xE5,0x7E,0xFC,0xE1,0xC7,0x84,0x79, +0x6A,0xF6,0xBF,0x55,0xEA,0xFE,0x5A,0x13,0x47,0xCB,0x39,0xC0,0xFE,0xA5,0x1A,0xCA, +0xE7,0xEC,0x57,0xEC,0xB0,0x63,0x68,0xB4,0xCA,0x18,0xC2,0x40,0xC7,0xAF,0x96,0xAF, +0x04,0x82,0x7C,0xA3,0x91,0xED,0x97,0xD8,0x06,0x6E,0xA2,0x69,0xFD,0xE3,0x39,0xF5, +0x1A,0x08,0x68,0xD3,0xE1,0x81,0x65,0x8B,0xB7,0xC8,0xA9,0xD0,0x46,0xFD,0x6B,0x2D, +0x6B,0xF6,0xD2,0x9A,0x1E,0xE2,0xD5,0x99,0xF8,0x0C,0xD0,0x00,0xBF,0xBE,0x3D,0x7E, +0x61,0x20,0x86,0x40,0x0E,0x38,0x26,0x4F,0x08,0xDD,0x68,0xCC,0x18,0x28,0x84,0x2E, +0xA4,0x14,0xEA,0x6E,0x0E,0xF0,0x54,0xBB,0x3F,0x48,0xE3,0x7F,0x42,0xD7,0x4D,0x1F, +0x80,0x4D,0x61,0x6B,0x3A,0x43,0x57,0xCE,0x83,0x9D,0xC2,0x93,0xCD,0x38,0xC0,0x4C, +0xB7,0x51,0x11,0x00,0xA9,0x7B,0x3D,0x4F,0x2E,0x93,0x04,0xB4,0xF9,0xCD,0x89,0x6C, +0x9E,0xF2,0xF8,0x57,0x11,0x3F,0x2B,0xBF,0xC4,0x65,0xAF,0x2E,0xF7,0x29,0xEE,0xCB, +0x0C,0x68,0x91,0x54,0xC6,0x2A,0xB7,0x50,0x8F,0x00,0x5D,0x15,0x8B,0x18,0x16,0xC9, +0x2C,0x49,0x07,0x3C,0xB2,0x88,0x2A,0x34,0x44,0x3F,0x0B,0x19,0x72,0x5F,0x00,0x54, +0x1E,0x75,0x71,0xF3,0x2B,0xC8,0x51,0x85,0x55,0x81,0xAA,0xBE,0x86,0x5F,0x24,0x0D, +0x64,0x84,0x15,0x0C,0xBE,0x3E,0xD9,0xAB,0xFF,0x92,0x8C,0x15,0x76,0x3F,0xD8,0x63, +0x57,0x86,0x10,0x13,0x1D,0x1E,0x84,0x6F,0xE3,0x0E,0xCA,0xD7,0x88,0x39,0xA0,0xF5, +0x82,0x2B,0xFE,0x15,0xE6,0x22,0xE7,0xDA,0xEA,0x9A,0xEE,0xD4,0x4E,0x74,0x59,0x50, +0xB1,0x1C,0x3B,0xB0,0xD0,0x2B,0xD3,0x99,0x73,0x59,0xDA,0xD2,0x76,0x5D,0x92,0x2E, +0x2A,0x48,0x4D,0x3E,0xD3,0x71,0xBA,0xE5,0xEB,0x87,0x18,0xBF,0xC5,0x27,0x8E,0x9C, +0xA0,0x29,0xCD,0x03,0x31,0x7A,0x2E,0xCE,0x1A,0xDB,0xC3,0x05,0x71,0x34,0x9E,0xDD, +0x20,0x27,0xE3,0x29,0xA4,0x37,0x77,0x2B,0xCC,0xB9,0xCE,0xD9,0x12,0x00,0x77,0x88, +0x31,0xC9,0xCB,0x18,0xEE,0x31,0x0A,0x97,0x61,0xB1,0xB2,0xDB,0xF0,0x39,0x13,0x50, +0xA3,0x14,0x34,0x6A,0x7D,0x7C,0xF3,0x95,0xE7,0xCB,0xDC,0xF2,0x56,0xAF,0x21,0xDE, +0x6A,0xCF,0xDE,0x96,0xBB,0x05,0x7E,0xD3,0x47,0x22,0x1F,0xBE,0xCE,0x13,0x16,0x64, +0xEA,0xAB,0x8F,0x84,0xA3,0xC9,0xBD,0xC9,0xF6,0x93,0xC7,0x4D,0x61,0x73,0x69,0x50, +0xE2,0x45,0xF9,0x97,0x52,0x68,0xD9,0x0B,0xED,0x18,0x73,0x80,0xEA,0x2B,0x99,0x1F, +0xEE,0x12,0x41,0x79,0x13,0x2F,0x2D,0xCF,0x9F,0x81,0xB1,0xD5,0x75,0x79,0xB9,0xAA, +0x73,0x84,0xEA,0x2B,0xA0,0x2B,0x60,0xFA,0xA4,0x81,0x01,0x11,0x90,0xEB,0xF6,0xA1, +0x9F,0x24,0x81,0x7F,0xB3,0xC6,0xD9,0x66,0xF5,0xFD,0x93,0x3F,0xB4,0xB5,0xFE,0x0F, +0xC7,0xB7,0xFB,0x3D,0x43,0x59,0x24,0x11,0x84,0x31,0xD6,0xA2,0x04,0xE2,0xED,0x9E, +0x38,0x13,0x49,0x3B,0xE0,0x52,0x1C,0x74,0x69,0x1A,0xE2,0xA2,0xD3,0x41,0x8F,0x6F, +0xE4,0xA5,0x19,0xCB,0xE6,0x30,0x20,0x53,0x17,0x49,0xB1,0x4B,0x05,0xF3,0x42,0x68, +0xA3,0x81,0x31,0x0A,0x00,0x2E,0x9E,0x5C,0x0E,0x11,0x80,0x17,0xC2,0x89,0x3B,0x0D, +0x5F,0x51,0x84,0x73,0x80,0x3E,0x97,0xA1,0x8A,0xBE,0x33,0x57,0x75,0x43,0x23,0x2B, +0xD2,0x96,0x6D,0x39,0x64,0x85,0xE3,0xF7,0x96,0xA9,0x9A,0x9D,0x46,0x58,0x69,0xD3, +0x28,0x76,0xEC,0xB6,0xB0,0xE9,0xA9,0x15,0xD3,0x1B,0x36,0xD5,0xC1,0xA1,0x70,0x19, +0x26,0x5F,0x1B,0x4B,0xD7,0x9B,0x7A,0xD8,0xF4,0x79,0x0A,0x82,0x39,0x0F,0x3B,0xAF, +0xE3,0x8D,0x74,0xF3,0xEA,0xE3,0x62,0x97,0xA3,0x33,0x05,0x7D,0xF6,0x08,0xE9,0x05, +0x0A,0xE1,0x24,0x60,0xE1,0x94,0x0F,0x70,0x3E,0xB4,0xE0,0x76,0x34,0x64,0xAB,0x1E, +0x32,0x5D,0xD3,0x1D,0x77,0x10,0x6F,0xDC,0x1A,0x37,0x9D,0xD7,0x97,0x91,0x5C,0x31, +0x48,0xD8,0xA5,0x9D,0x68,0xE0,0xD9,0x50,0x78,0x24,0xFA,0x2D,0x40,0x77,0xC6,0xEF, +0x57,0x37,0x65,0x9E,0x56,0xAB,0x99,0x19,0x35,0x53,0xBA,0x83,0x48,0x46,0x94,0xC2, +0xEC,0x85,0x30,0xE6,0x39,0x38,0xBD,0xAA,0x5C,0x2D,0x95,0x47,0xAE,0xBF,0xE7,0x4A, +0x7D,0x3B,0x19,0xF9,0x11,0xF7,0x3B,0xCA,0x62,0x9F,0xA5,0xEE,0x36,0xBF,0xB2,0x15, +0x7B,0xBF,0x3C,0x36,0x50,0x33,0x55,0xBD,0xFE,0x25,0x12,0x42,0x62,0xE4,0xA7,0x76, +0x9C,0x7A,0x89,0x0A,0x65,0x1B,0x73,0xFF,0x42,0x14,0x37,0x93,0xB0,0xFB,0xAA,0x02, +0x1F,0xA0,0x18,0x79,0xA8,0x57,0x1C,0xE9,0x92,0x9E,0x74,0xED,0xEB,0x74,0x31,0xA4, +0x7C,0x74,0xCF,0xC2,0xB9,0x95,0xEE,0x1C,0xAD,0x31,0x25,0x4B,0x88,0x23,0x1D,0xDA, +0x61,0xE3,0x92,0x18,0x6B,0x80,0xEC,0xBC,0x7A,0x5F,0x1E,0x89,0x6E,0x02,0xF5,0xEE, +0xCB,0xF3,0x96,0xEC,0x11,0x39,0x01,0x9D,0x2C,0x14,0x8D,0xC7,0xA9,0xF9,0x2F,0x33, +0x49,0x8C,0x1F,0xD0,0x3D,0xC4,0xFB,0x40,0x35,0xE1,0x13,0x5A,0x8D,0xEE,0x25,0xBC, +0xD2,0xA0,0x31,0xE9,0x6C,0xB3,0x95,0x9D,0xBE,0xEA,0x1C,0x13,0x1E,0xE2,0x3D,0x28, +0x9D,0x5A,0x7E,0x45,0x66,0x19,0xE1,0xFD,0x43,0x7A,0x4C,0x07,0x42,0x15,0x53,0xF3, +0x6F,0xFD,0xC0,0x4F,0xC7,0xC4,0xD5,0x0D,0x9F,0xE0,0xC5,0x88,0x89,0x8B,0xD7,0xBB, +0xD3,0xAA,0x01,0xDC,0x86,0xD3,0x4C,0x21,0x5D,0xAA,0xDF,0x23,0xD6,0x3B,0x90,0x8B, +0x0D,0x2F,0x19,0x1F,0x1A,0x00,0x17,0xD0,0x11,0xD9,0xFB,0x95,0x01,0xB6,0x69,0xCC, +0xC1,0xA5,0x4E,0x05,0x1C,0x9C,0xA7,0x14,0x0B,0x51,0xEA,0xD3,0x93,0x9D,0x5D,0x99, +0xC4,0x45,0xC1,0xA2,0xBA,0x27,0x37,0xC0,0x25,0xAE,0x8E,0x52,0x5F,0x7E,0xAF,0x60, +0xED,0xE7,0xE9,0x8B,0xD2,0x12,0xAE,0xA8,0xB0,0x9C,0x01,0x7A,0xD0,0xD4,0xAF,0x17, +0x22,0x72,0x94,0x07,0x44,0xCD,0x5A,0x2C,0xD3,0x4A,0x08,0x7E,0x0C,0xA9,0xFB,0x44, +0x6D,0x48,0x1F,0x54,0xC9,0x95,0x68,0x9A,0xF4,0x47,0x0C,0x51,0x09,0x43,0x85,0x88, +0xC4,0xB6,0xAB,0xDD,0x38,0x74,0xC2,0x64,0x4F,0x43,0xC5,0xAD,0x8E,0xAC,0x9A,0x92, +0xEB,0xF4,0x88,0x51,0x88,0xEC,0x9F,0x80,0x4E,0xB1,0xF1,0x63,0xEE,0x63,0xF4,0xD6, +0x78,0x68,0x41,0x9D,0xE4,0x9A,0xC0,0x5E,0x94,0x3B,0x2A,0x1F,0x0B,0x2D,0xF6,0xD7, +0xC0,0x52,0xC7,0xDC,0xEF,0x24,0xB5,0xE5,0x7E,0x5A,0xE8,0xA5,0x48,0x8C,0x35,0xD2, +0xF8,0x1E,0x4D,0xF3,0x6E,0xB2,0x3B,0xA9,0x2D,0x9A,0xF4,0x00,0xF0,0x65,0x71,0xBA, +0x16,0xA5,0xD8,0xF4,0xAB,0xF9,0xA2,0xC3,0x0B,0xCC,0xEC,0xAF,0xD2,0x77,0x09,0xAD, +0x76,0x38,0x48,0x5E,0x26,0x5A,0x31,0x8F,0xB3,0x0E,0x71,0x68,0xBE,0x2C,0xB5,0x96, +0x07,0xCB,0x0D,0x49,0xE7,0xB6,0xCB,0x56,0x1A,0x07,0x24,0xC1,0x1E,0x2F,0x84,0xDD, +0xC5,0x30,0xAC,0x07,0xF1,0x37,0x5F,0xCF,0x0A,0x70,0xA8,0xB3,0x39,0x13,0xE8,0xC1, +0x66,0x84,0x5D,0x09,0x21,0x83,0xC0,0xDF,0x6B,0x4C,0xE4,0x81,0xA0,0x1D,0xF8,0x19, +0x31,0x8A,0xB2,0x3D,0xC0,0x6D,0x0F,0xEA,0x00,0x1D,0x75,0xD4,0x46,0x3C,0x5D,0x90, +0x31,0x2D,0x33,0x9E,0xE2,0xD5,0x10,0x71,0xDB,0xA7,0x0B,0xAF,0xC6,0x28,0xEE,0xAC, +0x28,0x86,0x94,0x61,0x1B,0xB7,0xDC,0x23,0x66,0x13,0x8A,0x36,0x05,0x1A,0x41,0x28, +0x57,0xB2,0x89,0x4F,0x4B,0xAD,0xD9,0x4F,0x6D,0xB7,0xE1,0x15,0x5A,0x37,0x19,0xD2, +0x7F,0x51,0x61,0x4F,0x6F,0xE5,0x9E,0x86,0x47,0xFC,0xB9,0x1F,0x69,0x84,0xF6,0x63, +0xF8,0x9F,0x52,0xD2,0x5D,0x67,0x98,0x5C,0x3F,0x09,0x65,0x49,0x95,0x7D,0x2D,0x6B, +0x16,0x1E,0xCC,0x9E,0xFC,0x81,0x00,0xC5,0xC0,0xA3,0xB0,0x01,0x00,0x2C,0xA5,0xFC, +0x6B,0xC7,0xCC,0xF8,0xA4,0x03,0x1C,0x41,0x7C,0x71,0x5C,0xE9,0x1C,0x66,0xB6,0xE7, +0xBD,0xF5,0x73,0x54,0x1D,0xAE,0xD8,0x52,0xF4,0x0D,0xDC,0x29,0x2F,0x3A,0xBF,0xF2, +0xBE,0x1C,0xFE,0xDE,0xA7,0xF2,0x2F,0x33,0xD7,0x91,0x60,0xBE,0x89,0x47,0xBE,0x6F, +0x8F,0xD6,0xA5,0xA8,0x38,0x3B,0x85,0x10,0xB3,0x18,0x43,0x4E,0xDB,0xC9,0x52,0x15, +0x30,0x4F,0x68,0xA6,0x96,0x10,0x30,0xE7,0x12,0x67,0x73,0x18,0xC3,0x94,0x2C,0x00, +0xAA,0x58,0xE5,0x8F,0x3A,0x68,0x94,0xA4,0x40,0xFF,0x28,0xB2,0xD9,0xD0,0x31,0x98, +0xC6,0x2B,0x6F,0x23,0xA6,0x14,0xF9,0x5B,0x5B,0xD4,0x67,0x20,0xBA,0x76,0x82,0x96, +0x4C,0xA4,0xA1,0xBC,0x6D,0x19,0xE4,0x27,0xF8,0x4A,0x09,0x9C,0xDD,0x4C,0xE3,0x46, +0x64,0x29,0xD0,0x18,0xEE,0x58,0xB8,0xA8,0x31,0xB7,0x41,0x05,0xF0,0xA4,0xAE,0x54, +0x57,0xD7,0xDC,0x6F,0xF2,0xD1,0xE5,0x07,0xD3,0xE1,0x9E,0x13,0x1A,0x65,0x82,0x7E, +0x77,0x6B,0x0A,0xB2,0x6B,0x62,0xDF,0x6C,0x12,0xC3,0xFE,0x42,0x34,0x7D,0x32,0x8A, +0x8E,0x97,0x90,0x07,0xA6,0x4B,0x40,0x4C,0x1C,0xA5,0xA6,0x68,0x05,0x56,0x0D,0x95, +0xE1,0x42,0xCE,0x26,0x33,0x8A,0x62,0x88,0x85,0x25,0x05,0xB0,0x8D,0xD0,0x53,0x02, +0xD0,0x21,0x62,0x82,0xB9,0x16,0xE6,0xE7,0x82,0xEB,0x30,0xAA,0x2A,0x9D,0x53,0xD1, +0x98,0x12,0x50,0x8F,0x1B,0xA7,0xA8,0x7B,0x5D,0xE1,0x18,0x70,0xA7,0xED,0xCB,0xFA, +0x14,0xAB,0x77,0xC7,0xD8,0x34,0x8D,0xD0,0xB9,0xC3,0x02,0x2A,0x14,0x19,0x8E,0xFF, +0x93,0x75,0x59,0x90,0x58,0x7D,0x2F,0xA3,0xF7,0x70,0xA9,0xDB,0xF7,0x84,0x5E,0x4E, +0x79,0x76,0x81,0xD0,0xA3,0xDB,0x4D,0x2E,0x05,0x2F,0x83,0x36,0x0B,0x30,0xA7,0x8C, +0xC2,0xE9,0xDE,0xB6,0xF6,0x26,0xD2,0xA5,0x97,0xA7,0x01,0x37,0xC8,0xFF,0x9F,0x25, +0x02,0x93,0x04,0x94,0x13,0x75,0xDD,0xCF,0x3D,0x94,0xB0,0xAA,0xE6,0xDD,0xCA,0x12, +0x32,0x57,0xA6,0x83,0xBB,0x6C,0x38,0x4C,0x27,0x46,0x5F,0x98,0xB0,0xCC,0x52,0x4E, +0xD2,0xD2,0x46,0x0E,0xCE,0x34,0x9E,0xD0,0x07,0x31,0xBB,0x9E,0x5E,0x16,0xEF,0x01, +0xE9,0x86,0xDB,0x5B,0x8F,0xE1,0x34,0x58,0x57,0x11,0xE0,0x77,0xB5,0xD6,0x96,0xE2, +0x51,0x29,0xD8,0x07,0x41,0x89,0xEB,0x06,0x7C,0x1A,0x88,0x77,0x6E,0xFF,0x1E,0x0F, +0x14,0x3D,0x5B,0x32,0x26,0xEF,0xD8,0x11,0x25,0x45,0xEA,0x89,0xB7,0xFA,0x4C,0xC0, +0x04,0xD3,0xAA,0x86,0xC4,0xA4,0x5F,0xF8,0x4D,0xBD,0x2D,0xB8,0x9E,0xA3,0x4A,0xEB, +0x25,0xF3,0x16,0x25,0xC7,0x4F,0x52,0x25,0x7D,0xB2,0xDB,0x91,0xB5,0x68,0xF3,0xB9, +0xB9,0xD3,0x4F,0x84,0xE5,0x8C,0x24,0xF0,0x5B,0xAE,0x20,0x50,0x43,0x26,0x31,0x14, +0x59,0xC5,0x91,0x89,0xDF,0x96,0x95,0x85,0xFD,0x0F,0x04,0xA2,0x12,0xD6,0xA8,0xE5, +0x0D,0x52,0x8B,0x6E,0x62,0xFD,0xFB,0xE9,0x72,0x1E,0xC7,0x54,0xCD,0x0B,0x78,0x34, +0x54,0x01,0xEA,0x45,0xCA,0x4F,0xDC,0x8D,0x75,0x73,0x4C,0xF0,0xB8,0x04,0x22,0x21, +0x86,0x00,0xA8,0x80,0x60,0xE0,0xCF,0x22,0x1C,0x31,0x37,0x27,0x22,0x82,0xC8,0xC0, +0xE9,0xC6,0x48,0xBA,0x20,0x4C,0x10,0xC9,0x1E,0x2F,0x98,0x77,0x47,0x5C,0xC1,0x25, +0x34,0xFC,0x99,0xDE,0xFA,0x37,0x41,0x45,0xED,0x11,0x1D,0xA7,0x14,0xEF,0xB0,0xBF, +0x3B,0x9A,0xCA,0xCE,0x90,0xDC,0xCD,0x9E,0x3C,0xC1,0x39,0x1C,0xC7,0xB9,0xEE,0x5C, +0xC4,0x80,0xE8,0x2A,0x95,0xCD,0x6E,0x02,0x2C,0xCE,0xA9,0x98,0x6C,0x0D,0x69,0x26, +0xFF,0x21,0x95,0x54,0xA7,0x2A,0x41,0xFD,0x67,0x03,0x99,0xE0,0xB9,0xB7,0xEA,0x20, +0x5D,0x88,0x40,0xC0,0x50,0xFD,0x76,0x0E,0xB5,0x0A,0xB2,0x45,0x16,0x8A,0x95,0x58, +0xCC,0x0D,0x7A,0x6E,0x84,0x91,0x27,0x6D,0x1C,0xD2,0x46,0x78,0x7F,0xD1,0xF1,0xC2, +0xAC,0xBC,0xB3,0x0A,0xBB,0x3A,0xE1,0x21,0xE3,0xC1,0x13,0x59,0xFB,0x86,0xAD,0xCF, +0x22,0x7F,0x7A,0xC6,0xD4,0x9C,0x0B,0x22,0x4A,0x2A,0xAA,0x3E,0x81,0x8A,0x64,0xA5, +0xB0,0x8D,0xA0,0xAE,0x8D,0x1F,0xB1,0x25,0xCB,0xE8,0xCF,0x84,0xEF,0x57,0x70,0x01, +0x01,0x49,0x9E,0xCE,0x77,0xCB,0x6B,0x67,0xAF,0xF0,0x43,0xBB,0x6D,0xEC,0x39,0x1B, +0x0D,0x18,0x8A,0x06,0xAE,0xC9,0x04,0xD8,0x37,0x58,0x87,0xBD,0xE8,0x8A,0xF9,0x06, +0x94,0x55,0x83,0xD7,0xBF,0xD0,0x58,0x59,0xAC,0xE9,0x67,0xB2,0x0A,0x34,0xC5,0xCD, +0xDC,0x60,0x10,0x45,0xF6,0x9E,0xD1,0x33,0x9F,0xA5,0x00,0x51,0x09,0x5F,0xB2,0x9A, +0x24,0x11,0x0B,0x8F,0x5D,0x33,0xB2,0xFF,0x19,0x4C,0x98,0xA7,0xE5,0xE9,0x31,0x0B, +0x01,0x18,0xC7,0x98,0x8B,0xD4,0x9A,0xDC,0x80,0x7E,0xDB,0x97,0x87,0x88,0x1B,0x32, +0x28,0xE1,0x14,0x32,0xA8,0xFE,0xBD,0xB8,0xBD,0xE9,0x62,0x3B,0x16,0xC0,0xF3,0x06, +0x3A,0x15,0x15,0xB7,0x1B,0x65,0xB1,0xD3,0xE1,0xD1,0xF0,0xCE,0xF2,0x06,0x47,0xE3, +0xB8,0x21,0x03,0xF3,0x46,0x90,0x4F,0xE9,0x97,0xDA,0x81,0x12,0xAC,0xFB,0x78,0xEE, +0x5F,0x43,0x57,0xF0,0xF4,0xA5,0x7F,0x0B,0x7B,0xB0,0x27,0xE7,0xED,0x42,0x72,0x69, +0xEC,0xFB,0x1F,0xC2,0x72,0xC8,0x69,0xDA,0xBE,0x24,0xA7,0x41,0xED,0x1A,0x1C,0x84, +0x65,0x67,0x94,0x00,0x3E,0xEE,0xC7,0x08,0x61,0xED,0x2B,0x64,0x0C,0x62,0xDD,0x52, +0xDE,0x16,0x28,0x46,0xE9,0x2A,0x3E,0xF3,0x78,0x53,0xF8,0xA4,0x18,0x6B,0x07,0x32, +0xB2,0x0E,0x9D,0x94,0x20,0x68,0x5F,0x52,0xAF,0x76,0x3F,0xDD,0x58,0xDF,0xA4,0x29, +0x0B,0x9E,0xC7,0xF2,0xA7,0x11,0x38,0x95,0xD0,0x75,0xF1,0xEC,0x53,0x61,0xAB,0x51, +0xE6,0x0D,0xAA,0xED,0xA6,0x22,0xD2,0x72,0xBA,0xCF,0x1F,0x2C,0xA8,0x79,0xAB,0x80, +0x81,0x1A,0xFB,0x0C,0x84,0x09,0x33,0x92,0x48,0x86,0xC7,0xB0,0x58,0x1C,0x87,0x1B, +0x50,0xC1,0x54,0xA6,0xE3,0x82,0x94,0x55,0x54,0xFE,0x0C,0xD6,0x3B,0x1B,0xA9,0x2D, +0x29,0xBE,0xE3,0x9A,0x4C,0x4B,0xDF,0x5F,0xF9,0x92,0x0D,0x24,0xDA,0x81,0xA9,0x32, +0xFA,0x4A,0xB3,0xF8,0x8B,0xB2,0x2B,0x52,0x2A,0xD5,0x14,0x14,0xBB,0x3D,0xA2,0x8E, +0xD5,0xE8,0x6F,0x27,0x1E,0x79,0x77,0xF1,0x02,0xBD,0xA4,0x9E,0x10,0x38,0xDE,0xB1, +0x58,0xC8,0x0C,0xBF,0x7C,0xC4,0xD7,0x41,0xF5,0x4C,0x9B,0x5A,0xBB,0x69,0xDF,0x90, +0xB5,0x0D,0xA1,0x6C,0x20,0xC8,0x60,0x87,0x17,0x1E,0xAF,0x46,0x54,0x7E,0x1C,0x03, +0x8F,0x66,0xAB,0x78,0x29,0x5E,0x98,0x6A,0xF6,0x0F,0xFD,0xF2,0x7D,0xE1,0x56,0x96, +0xE9,0x8B,0x76,0x87,0xB5,0xB6,0xDE,0x7F,0xBA,0x47,0x26,0x01,0x9B,0x7D,0xFB,0xD4, +0xB5,0xCA,0x52,0x3E,0xC0,0xF8,0xF6,0x6D,0x12,0x7F,0x84,0xFA,0xF4,0x46,0x2C,0x3A, +0x45,0x22,0x6B,0x20,0xC7,0xC4,0x73,0x13,0xB9,0x77,0xD5,0x58,0x15,0x8F,0x28,0x10, +0x57,0x9D,0xB1,0x40,0x63,0x49,0xEE,0x06,0x47,0x63,0xA3,0x97,0x83,0x20,0xFF,0x2B, +0x0D,0xF0,0x25,0x5D,0x22,0x7D,0xD2,0xC5,0xB2,0xF2,0x66,0xA8,0x8E,0xEA,0xBF,0x85, +0x8E,0x39,0x1B,0x6B,0xB9,0xF2,0x1A,0x8E,0xDA,0x5E,0x29,0x44,0x50,0xBD,0xB3,0x51, +0x80,0xCA,0x73,0x64,0xD0,0x5B,0xE5,0x94,0x94,0x6E,0x54,0x06,0xC7,0x32,0x1A,0x25, +0x9E,0x16,0xDE,0xB1,0xD7,0xA6,0xAB,0x79,0x53,0xCA,0x51,0x52,0x09,0x42,0x2B,0xE5, +0x2E,0xFD,0x13,0x45,0x83,0xFC,0x2C,0x94,0xE8,0xF1,0xB6,0x31,0x95,0x9B,0xA1,0x16, +0x9F,0xCC,0xAB,0x6C,0x1A,0x0B,0x73,0xCC,0x18,0xEB,0x97,0x98,0x82,0x41,0x3D,0x49, +0x3E,0x31,0x2D,0xEF,0x0D,0x54,0x09,0xBC,0x78,0xF7,0x7B,0xAC,0x62,0xB2,0xF6,0x52, +0x64,0x04,0x08,0x3E,0x40,0xED,0xD7,0xDD,0x1F,0x6B,0x1A,0x74,0x08,0x8E,0x37,0xC2, +0xE7,0x61,0xBE,0x11,0x87,0x57,0x18,0x3F,0x58,0xBF,0x7B,0x73,0x6C,0xFF,0x1B,0x9A, +0x83,0x04,0x54,0x29,0x5D,0xB1,0xF3,0x96,0x9A,0xB0,0x82,0xBB,0xD6,0x63,0x87,0xF0, +0xB5,0x36,0xA7,0xEF,0xB5,0x43,0x4D,0x13,0x1B,0x7F,0x0B,0x87,0xF3,0x82,0x20,0x7E, +0xF2,0x24,0x90,0x67,0xED,0xAB,0xCA,0x74,0x1F,0xD2,0xCC,0x89,0x46,0x0C,0x2A,0x12, +0x63,0x65,0x85,0x92,0x0F,0x31,0x2A,0x79,0xAF,0x84,0x20,0x58,0x17,0xBD,0x5A,0x4A, +0x31,0xFC,0x49,0x59,0x45,0xD4,0xD9,0x87,0x16,0xCC,0xDE,0x32,0xD5,0xF0,0x74,0x3F, +0xA9,0xBD,0xAE,0x80,0xCA,0xBA,0x85,0xF7,0x53,0xFF,0x13,0x07,0xDA,0xDC,0x9B,0x39, +0x0B,0x8F,0xF7,0xA0,0xC4,0xE3,0xAD,0xB4,0xD4,0x51,0x3C,0x48,0xC9,0xF4,0x42,0xDB, +0x39,0x98,0x44,0x50,0x6F,0x42,0x0E,0xAA,0x40,0xF3,0x55,0x2D,0xAA,0x44,0x0B,0x31, +0x27,0x84,0xA8,0x81,0x94,0x10,0x2B,0xF4,0xF6,0x35,0xBF,0x15,0x90,0xB0,0xC5,0x95, +0x39,0xF9,0x19,0xEF,0x3D,0x78,0x81,0x84,0x92,0xFC,0xFD,0xB9,0xF9,0x7E,0xF1,0x41, +0xE2,0xBE,0xBB,0x44,0x70,0x2E,0x60,0x70,0x9E,0x10,0x47,0x17,0xD0,0x63,0xBD,0x70, +0x75,0x11,0x44,0x52,0xB9,0x39,0x07,0x25,0x4B,0x00,0xAC,0xCC,0x69,0x5F,0x82,0x37, +0x3B,0xB7,0x1A,0x42,0x2C,0xA6,0x1E,0x0D,0x2F,0x70,0xED,0x27,0x39,0xB4,0x4D,0x03, +0xFA,0x51,0xF0,0x10,0x90,0x74,0x13,0x42,0x34,0x8B,0x87,0x78,0x57,0xF7,0x93,0x2D, +0xA3,0xF1,0x7D,0xAC,0x5D,0x56,0xE0,0x65,0x57,0x19,0x89,0x48,0xFA,0xE9,0x82,0x5E, +0x5A,0x70,0x47,0x68,0xDD,0xED,0x74,0x98,0xA2,0xFF,0x41,0x2B,0x92,0x24,0xA2,0xF1, +0xD8,0x6E,0x48,0x4F,0xA4,0x12,0x6C,0xB9,0x5F,0x83,0x40,0x0E,0x33,0x95,0x63,0xA7, +0xD0,0x68,0x94,0x28,0xFC,0x2A,0x17,0xFA,0x3D,0x66,0x2D,0x6A,0x33,0xD3,0x51,0xE9, +0xB8,0xFB,0xF5,0x05,0x6A,0x7A,0xB5,0x59,0x03,0x89,0x2C,0xDC,0x74,0x1D,0xED,0xE5, +0x82,0x19,0xA6,0x6C,0xCD,0xE2,0x77,0xD4,0xFC,0x47,0xC7,0x54,0x01,0x10,0xD7,0xE8, +0x0A,0xB3,0x50,0xC7,0x2F,0x44,0x65,0x95,0x4A,0xCC,0x2F,0xA1,0xFF,0x5F,0x31,0x33, +0x6B,0x7B,0x88,0xBB,0xC5,0x1D,0x0A,0x21,0x1D,0x5C,0xD3,0x10,0x23,0x4B,0x07,0x1E, +0xAC,0x28,0x32,0x5A,0x7A,0x1C,0x65,0x75,0x43,0xF8,0x05,0x51,0x5B,0x25,0xB6,0xD6, +0xEE,0x68,0xC5,0x53,0xAD,0xB6,0x90,0xB6,0x08,0x40,0x71,0x77,0x26,0xB0,0xCD,0x0C, +0xCB,0xF0,0xC9,0xBE,0xA3,0x1A,0x27,0x48,0x19,0x0E,0x1C,0x24,0x94,0x56,0xB2,0x2F, +0x0E,0x0F,0xFE,0x43,0xA5,0xB9,0xF8,0xF2,0x4F,0x61,0xFE,0xDE,0xF9,0x27,0x5A,0x86, +0x5B,0x0D,0x3F,0x49,0x27,0x0C,0x54,0x83,0x0C,0x41,0x8F,0xFE,0x48,0xFE,0x07,0x29, +0x44,0x0E,0x98,0x4A,0x24,0x1C,0x5A,0x85,0x92,0x7C,0xC8,0xF5,0xCC,0xBA,0xC1,0x7D, +0xD2,0xD7,0xAA,0xF2,0x2C,0x17,0x50,0x86,0x54,0x67,0x59,0xA6,0x26,0x14,0x72,0x95, +0xF1,0x8C,0x50,0xB7,0x8B,0xF4,0xD3,0x7E,0x76,0x27,0xB0,0xB2,0x93,0x9B,0xC9,0x21, +0x4B,0xB5,0x82,0x23,0x73,0x94,0x53,0x6D,0x98,0xEE,0xD4,0x83,0x10,0x90,0x69,0x27, +0x1D,0xB4,0xAA,0xEF,0x75,0x11,0xDB,0x2E,0x29,0xEB,0xB6,0x35,0x14,0xAE,0x9C,0xC3, +0xBF,0x14,0x8C,0xE3,0xC8,0xC7,0x60,0x7A,0x6B,0xB5,0x8C,0xB8,0xE7,0x43,0x84,0xED, +0xCF,0x84,0x3E,0x46,0x26,0xDB,0x04,0xFF,0x00,0xE7,0xD4,0x45,0x69,0x4A,0x93,0x15, +0xA8,0x25,0xAF,0xD8,0xCD,0x70,0xD0,0xA1,0x6C,0x4C,0x4B,0xF5,0x2A,0x9A,0x27,0x41, +0x49,0x43,0x7A,0x2E,0x80,0x60,0x2F,0xAE,0xB0,0x37,0x1B,0x37,0x65,0xE0,0x33,0x92, +0xFC,0xC8,0x14,0x66,0x03,0x6A,0x12,0xEE,0xCB,0xCD,0x0B,0xE2,0xCE,0x45,0x36,0x79, +0x6C,0xDD,0xCE,0x7E,0x05,0x48,0xDF,0x38,0xC6,0x4E,0x76,0xF5,0x6A,0x30,0x17,0xAF, +0x05,0x1F,0xBC,0x21,0xF3,0x5A,0xF7,0x10,0xD5,0x02,0x1D,0xBA,0x81,0xF5,0x0F,0xB9, +0x13,0x73,0x2A,0xDE,0x10,0x52,0xD4,0x59,0x12,0x51,0xA5,0x04,0x36,0x76,0xDF,0xA6, +0xA4,0xA3,0xDD,0x01,0x1A,0x5F,0x6B,0x47,0x00,0x84,0x09,0x3C,0x1F,0xCF,0xB6,0x01, +0xE2,0xBE,0x8B,0x4C,0x50,0xFC,0x9F,0x1D,0xAE,0x91,0xEA,0x89,0x51,0xAD,0xEE,0x93, +0xD7,0xFA,0x64,0x9A,0xBF,0x1A,0x93,0x29,0xB5,0xBC,0x8E,0x36,0xFE,0x03,0x64,0x0B, +0x1F,0x8D,0x4B,0x86,0x60,0xD4,0x18,0xA5,0x0C,0xED,0xDC,0x6A,0x32,0x79,0x16,0x60, +0xC6,0x1D,0x67,0xE3,0x94,0xFF,0xE3,0x87,0xEC,0x7D,0x88,0xB8,0xA4,0xD9,0x5A,0xEB, +0x09,0x0A,0x1F,0x76,0x7F,0x5A,0x3C,0x8E,0x4F,0xA3,0x54,0x7B,0x5F,0x44,0xB2,0xA8, +0x8F,0x62,0xF1,0xF5,0xC8,0x18,0xF0,0x13,0xE8,0x65,0x78,0x7B,0x18,0x02,0x62,0xEE, +0xFB,0xAE,0xAA,0x2C,0x3B,0x36,0x32,0x0E,0xA2,0x71,0x85,0xB0,0x02,0x51,0xBD,0x7B, +0xE4,0xDF,0x58,0x73,0xF9,0xE5,0xCF,0x2B,0x0F,0x23,0x12,0xB0,0x99,0x51,0x65,0x3D, +0x52,0xA6,0xC9,0x17,0xE9,0xC3,0xEF,0xC6,0x2F,0x1C,0x85,0xAF,0xED,0xE3,0x4A,0xDA, +0xAA,0x30,0x82,0x7E,0x06,0x5B,0x3C,0x1F,0x74,0x96,0xBC,0x6A,0x10,0x53,0x5E,0x06, +0x7B,0xF3,0x35,0xE4,0x28,0x6B,0xDD,0xC9,0x54,0xDD,0x7C,0x73,0x2A,0xE8,0x0B,0x7F, +0x55,0xC2,0x61,0xB0,0x89,0xFA,0x92,0x2A,0xD2,0xEC,0x4D,0x17,0x0F,0x83,0x19,0x3C, +0xE7,0x6D,0x09,0xC9,0x70,0xA7,0x93,0x82,0xFF,0xB1,0x29,0xFC,0xE8,0xB4,0xDC,0xEF, +0x6E,0x88,0x1D,0x5E,0x2A,0xE1,0x45,0x99,0x80,0xAA,0x43,0x75,0x4C,0x39,0xE7,0x13, +0x7A,0xF6,0x8E,0x3D,0x3E,0xC9,0xE5,0x23,0xEE,0xF7,0x39,0x7D,0xE7,0x20,0x50,0x70, +0xCF,0x1D,0x84,0xA3,0x82,0x88,0xFD,0x3E,0xE2,0x69,0xCB,0x7D,0x34,0xA1,0xD5,0x2A, +0xC1,0x86,0x31,0x77,0x61,0x7B,0xD3,0xEE,0xD4,0x20,0xD0,0xF5,0x95,0xF5,0x19,0x16, +0x1B,0x71,0x76,0x92,0x4B,0x84,0xC3,0x94,0x06,0x00,0x7F,0xF9,0xCD,0x02,0x84,0x83, +0x5B,0x20,0x50,0xA9,0x0B,0x40,0x6D,0xA3,0x2B,0xCC,0xF4,0x6F,0x8C,0xC9,0xBD,0x52, +0x9C,0x0E,0x2F,0x76,0xAE,0x01,0x22,0xFE,0x30,0x16,0x5D,0x6A,0x3A,0xD4,0xC7,0xE8, +0xC7,0x91,0xB6,0x49,0x39,0xA8,0x59,0x1E,0x8D,0xEC,0xDC,0x97,0xE5,0x1D,0xE9,0x5D, +0xA7,0xBF,0x42,0x98,0x37,0x04,0xFC,0x35,0x0A,0xE2,0xE5,0xDB,0xA1,0xC0,0xC6,0x97, +0x73,0xF5,0x2B,0x4E,0x0B,0x00,0x90,0xCE,0xD2,0xBB,0xAF,0xCB,0x01,0x3A,0xAA,0x33, +0x70,0xB0,0x1B,0x6E,0x2D,0x47,0x1E,0x35,0x0D,0xED,0x29,0x54,0x68,0xA2,0x27,0x31, +0x71,0xEA,0xA7,0x81,0xDD,0x74,0xFC,0x9A,0xF2,0x1F,0xB1,0xF4,0x59,0x9F,0x9A,0xD7, +0xA7,0x23,0x1C,0x81,0xFF,0xF7,0xC5,0x7B,0xF5,0x29,0x5E,0x16,0x46,0xCE,0x4F,0x30, +0x11,0xF5,0xE0,0x1B,0x41,0x0E,0x86,0x08,0xB1,0x4D,0xF8,0x83,0xBA,0x7C,0x39,0xB8, +0x5D,0x37,0x1E,0x44,0x22,0xDB,0x16,0x50,0x8C,0x3A,0x7B,0x7D,0x4A,0xF9,0x10,0x73, +0xF8,0xBF,0xED,0x21,0x00,0xE6,0x49,0xDF,0x7E,0x66,0x0E,0x4F,0xDB,0x91,0x98,0x66, +0x51,0x40,0x70,0x2D,0x90,0x23,0x20,0xDF,0xB6,0xCF,0x35,0xFE,0x07,0x58,0x5C,0x54, +0x35,0x38,0xF3,0xC7,0xA7,0xE4,0x15,0xDA,0x1A,0x6D,0xD3,0x24,0x3A,0x7B,0x59,0x13, +0x9E,0x4F,0x6E,0x89,0x9B,0xAE,0xD3,0x31,0xCB,0x69,0x72,0x1A,0xDB,0x62,0x89,0x8A, +0x24,0x86,0x89,0x37,0x32,0x94,0x09,0xED,0xC1,0xAD,0x3A,0xDD,0x18,0xD4,0xA5,0xAD, +0xFC,0x8E,0x5D,0x43,0xC1,0x38,0x62,0x71,0xE7,0x1E,0xEF,0x12,0x19,0x09,0xA9,0x17, +0x16,0x35,0xEB,0xFF,0x3B,0x42,0x1D,0x53,0x40,0x7F,0x8F,0x7E,0xB1,0xF1,0xD2,0xC7, +0x1D,0xC2,0x4B,0x29,0xB5,0x83,0xB0,0x0A,0x34,0x43,0x62,0x07,0x47,0x72,0x93,0x79, +0x24,0x89,0xD7,0x3A,0x02,0x39,0x1A,0xFC,0x97,0x13,0x8D,0x4B,0xBC,0x55,0xBC,0xCC, +0xBB,0xAE,0xF1,0x1F,0x61,0xDD,0x7C,0xB7,0xD7,0x0A,0x43,0x03,0x1C,0xA1,0x25,0x80, +0x78,0x3C,0xC9,0xE7,0xF5,0x1F,0x3B,0x5F,0xE4,0x08,0x1B,0xFE,0x27,0xE1,0xD3,0xB1, +0x00,0xB9,0x65,0x18,0x91,0xA1,0x92,0xDD,0x32,0xE3,0xC3,0x95,0x4A,0x98,0x9B,0x33, +0xA9,0x23,0xA8,0x7E,0x4E,0xF9,0x39,0x26,0xC0,0x21,0x6C,0xBB,0x8A,0x11,0x9C,0x22, +0x1F,0x3C,0xC5,0x84,0x98,0x68,0x19,0x72,0xB5,0x07,0xEB,0x16,0x42,0x36,0x68,0x2E, +0xA4,0x18,0x09,0x60,0x4F,0x46,0x84,0xCC,0x7C,0xE5,0xA5,0xBB,0x0C,0xBE,0xBF,0x17, +0xBD,0x66,0x0D,0x41,0x4A,0x42,0xD9,0x0A,0xA1,0xFE,0x71,0x0B,0x04,0x50,0xF0,0xDB, +0x54,0x4A,0x7F,0x2B,0xC4,0xE7,0x7E,0x11,0xA7,0x9F,0x7A,0xDA,0x6C,0x08,0x14,0x40, +0xC7,0x22,0x11,0xA7,0xFB,0xE5,0x36,0x74,0xE2,0x7E,0x50,0x4F,0xB8,0x05,0x68,0x43, +0x27,0xEA,0xAF,0x37,0x06,0x3E,0x7C,0x78,0xAE,0xE7,0x9A,0xE7,0x38,0x37,0x8A,0x58, +0xAB,0xF0,0x1F,0x5F,0xA6,0x90,0xBA,0x75,0xE5,0x80,0x2F,0x86,0x4F,0xF8,0xEB,0x3C, +0xF9,0x0C,0x42,0x36,0x08,0x31,0x98,0x29,0x72,0x2E,0x7E,0x12,0x0D,0xD8,0x77,0x80, +0xEE,0x27,0xA1,0x74,0xD1,0xE9,0x03,0x4A,0x34,0xDD,0xE6,0xF3,0xC0,0xDA,0x8D,0x65, +0xBD,0xDD,0x9A,0x8A,0x82,0xCD,0xAE,0x91,0x3E,0x6D,0x4B,0x5F,0x82,0x1B,0xB5,0x05, +0x98,0x7D,0x51,0x81,0xE6,0x89,0x3F,0x67,0x20,0x2D,0x5B,0xC5,0x64,0x5E,0x62,0xBB, +0x23,0xA5,0x71,0xA1,0xCA,0x67,0xD3,0xCE,0x35,0x0D,0x7E,0xBE,0xB3,0xF0,0xF6,0x81, +0x07,0x2D,0x8B,0x77,0xC7,0x28,0xB5,0xF7,0xDE,0xE5,0xB9,0x32,0xE9,0x9C,0x3E,0x45, +0x56,0xDD,0xC0,0x2F,0x10,0x0E,0x5F,0xB8,0xFA,0x7A,0x6E,0x3D,0x94,0xCA,0xC0,0x0C, +0x1A,0x2A,0x8D,0x65,0x22,0x28,0x97,0x88,0x09,0xF8,0x8A,0x19,0x97,0xCF,0xBD,0xC6, +0x4A,0x65,0x62,0x9A,0x76,0x51,0x27,0x0E,0x53,0x69,0x95,0xBF,0xC2,0x39,0x6F,0x6D, +0xB8,0x1A,0x9A,0x7F,0xB5,0xF3,0x6C,0x56,0x28,0x74,0x84,0x70,0xD0,0xF3,0x11,0x87, +0x82,0x05,0x88,0x27,0xA0,0x92,0xF5,0x84,0x90,0x62,0xC7,0x04,0x56,0xE1,0x0A,0x83, +0x12,0xC4,0x7E,0x6D,0xD8,0x67,0xD0,0xB3,0xAC,0xD6,0x57,0xCC,0x86,0x07,0x4F,0x5D, +0x4E,0x60,0xC4,0x9E,0xAB,0x8C,0x77,0x39,0xD6,0x97,0x6D,0xF1,0xF9,0xD3,0x04,0x8F, +0x56,0xD4,0xF9,0x63,0x4C,0x2F,0x76,0xFA,0xFD,0x09,0x2F,0xCB,0x21,0xFB,0xB7,0x31, +0xD0,0x85,0xA1,0xBE,0x65,0xB9,0xCB,0xEA,0xE6,0xE9,0x16,0xCC,0x4B,0xDE,0x30,0x87, +0xBA,0xDA,0xA9,0xDB,0x4A,0xC0,0x3E,0x2E,0xC3,0x5A,0xE2,0x20,0xA3,0xA2,0xBB,0x56, +0x6C,0x1D,0xDF,0x4E,0xE6,0x49,0x93,0xA2,0x11,0x6C,0x07,0x7D,0x27,0x81,0xB4,0x20, +0x7B,0x9C,0x84,0xC0,0xAC,0x45,0x11,0xC5,0x7A,0x1E,0xE2,0xDD,0x99,0xF4,0x5F,0x9D, +0x4E,0x4C,0x43,0xF4,0x56,0xEF,0xBE,0x7F,0x9A,0xA3,0x2B,0xE7,0xB7,0x38,0x9F,0x7D, +0x2A,0x2D,0x34,0x5A,0x0C,0x2F,0xAE,0x66,0x49,0x88,0x29,0x41,0x59,0xAF,0x18,0x5A, +0x1D,0x39,0x0A,0x31,0xFB,0x22,0x98,0x4C,0x18,0xB6,0x37,0xC1,0xFC,0x3A,0x10,0x06, +0x2E,0x84,0x5E,0xD4,0x3B,0xDB,0x90,0xCF,0x3B,0xBC,0x5B,0xF6,0x20,0xF0,0x41,0x3D, +0xE1,0x6C,0x03,0xAF,0x1A,0x4E,0x3B,0x3C,0xC6,0x4C,0x7A,0x10,0xA2,0x96,0x83,0xB9, +0xB1,0xAA,0xD8,0x8C,0xF2,0x91,0xBA,0xAC,0x9B,0xA8,0x09,0xE1,0x4A,0x44,0x20,0x38, +0xB8,0x03,0xCC,0xA9,0xDC,0x0A,0x68,0x12,0x5A,0xD8,0xEF,0xF0,0xB8,0xC0,0x03,0xE5, +0x6A,0xC6,0x91,0x69,0x9F,0x1F,0x6B,0x45,0x85,0x20,0xB9,0x83,0x39,0xAC,0x54,0xD5, +0x1C,0xC7,0x94,0xAE,0x3F,0xB7,0x6C,0x24,0xCC,0x39,0xB2,0x3F,0x19,0x0F,0x7F,0xFE, +0x58,0x62,0x4B,0xA2,0xC1,0x6D,0x0F,0x83,0x5E,0xFC,0x20,0x4E,0xEF,0x67,0x27,0x40, +0xC5,0xF7,0x8B,0x2B,0x4B,0xA9,0xB0,0xC5,0xA7,0xF8,0x30,0x12,0x99,0xF5,0xD5,0x4A, +0x19,0x14,0x6F,0x28,0x7D,0x08,0x04,0x38,0x7F,0xFD,0xD9,0x03,0x1E,0x78,0xB6,0x4E, +0x3D,0xB3,0x89,0x26,0x85,0xB6,0x97,0x00,0x55,0x9E,0xDF,0x52,0x82,0xF8,0xBD,0x75, +0x70,0x35,0x7F,0x38,0xEE,0xE5,0x57,0x6B,0x7C,0x09,0xAB,0x99,0x34,0x8C,0xE6,0x96, +0x1D,0x9B,0x04,0x18,0x05,0xF4,0x28,0x16,0xB8,0x89,0x38,0x50,0x6C,0x4E,0x96,0x37, +0xA3,0xB9,0xFF,0xCB,0x42,0x60,0x50,0xC2,0x54,0xCE,0x4C,0x41,0xF0,0xF3,0xD5,0xFF, +0x7E,0x8A,0x74,0xA5,0x07,0x09,0xC9,0x1D,0xED,0xE5,0x8F,0x3E,0x89,0x20,0xED,0x78, +0xDD,0xBA,0x93,0xEC,0x5C,0x5D,0x6F,0x30,0x6B,0xD1,0x2C,0xA8,0xF2,0x70,0x3F,0x97, +0xBE,0x06,0x90,0x16,0xAB,0xB5,0xEA,0x02,0x24,0xD7,0x09,0x45,0x7E,0xCF,0x8A,0x9C, +0x66,0x3B,0xC2,0x5D,0x10,0x38,0x9B,0x28,0x01,0x6A,0xD0,0xA2,0x6D,0x26,0x98,0x73, +0x6E,0x78,0x4F,0xDC,0xD3,0x92,0x59,0x61,0x3C,0x9E,0x1F,0xD3,0x81,0x61,0x58,0x9D, +0x32,0x47,0x23,0x65,0xC0,0xF5,0x5B,0x4A,0x10,0x34,0x6A,0x0B,0x1C,0xD6,0xE8,0xD6, +0xA2,0x80,0x36,0x74,0x78,0x63,0xA3,0x01,0xF5,0xCA,0x0D,0x08,0xEE,0x38,0x09,0x94, +0x90,0xD6,0x3A,0x8F,0x8C,0x29,0xA4,0x0B,0xD9,0xA4,0x31,0x4D,0xB5,0xD5,0x31,0x4F, +0x8E,0x5D,0x28,0x8C,0xF9,0x59,0xE5,0xA9,0xE0,0x40,0x5C,0x21,0x06,0x1C,0x66,0x2B, +0x4B,0x31,0x8E,0x35,0x4C,0xE6,0xB3,0x12,0xDD,0x3F,0x55,0x80,0x1B,0xDE,0x2E,0xCC, +0xA2,0x49,0xA1,0x1C,0xCE,0x74,0xC7,0x77,0xE5,0x2E,0xFB,0xAA,0x87,0xB3,0x0D,0x98, +0x98,0x25,0x39,0xA3,0xD2,0xD1,0x1F,0x55,0x28,0xF4,0xDE,0xE9,0xFB,0xA2,0xDA,0x61, +0xA7,0x53,0x3B,0x66,0xFB,0x6A,0xCC,0x69,0x84,0x7D,0xF6,0x23,0x0C,0xF9,0x5C,0x5B, +0xAA,0x7D,0x0B,0xDC,0xC5,0x32,0xDB,0x89,0x7A,0x18,0x5E,0x11,0x74,0xA5,0x81,0x77, +0x6D,0x42,0xE2,0xD7,0x85,0x26,0xD9,0xF9,0xCA,0x32,0x4F,0x4C,0x4A,0x64,0xED,0xF0, +0xD4,0x5A,0xA4,0xB7,0x0D,0xCF,0x61,0x88,0x66,0x39,0x2D,0x6D,0xB1,0x74,0xFF,0xF7, +0xDA,0x98,0x5B,0x80,0x6C,0xBB,0x41,0xCA,0x26,0x03,0x34,0x19,0xEE,0x40,0xBE,0x48, +0x16,0x3D,0xE1,0x05,0xB6,0xE4,0x0F,0xCE,0xCA,0xDF,0xCE,0xA1,0xB4,0x51,0xBF,0x38, +0xB2,0xD8,0xA5,0x91,0x10,0x35,0xE5,0x3D,0x8D,0x62,0xBC,0xD0,0x27,0xC1,0xA8,0x4E, +0x51,0xAC,0xCA,0xD2,0x00,0x42,0xB7,0xB9,0x14,0xDD,0xD8,0xE4,0x8A,0xAF,0xFC,0xBE, +0x7D,0xAD,0xE0,0x6A,0x16,0xED,0x32,0x98,0xB7,0xB9,0x62,0x24,0x2B,0xE6,0x60,0x0A, +0xCE,0xA5,0x79,0xED,0xF2,0xEE,0xC2,0xE5,0xF5,0x71,0xDB,0x27,0xD8,0xC4,0xD4,0x61, +0x99,0x9C,0x79,0x19,0x32,0x35,0xDC,0x3C,0x5E,0x53,0x4E,0xEC,0xB5,0x0F,0xEE,0x82, +0xEF,0x83,0x91,0xCF,0x87,0xD8,0x85,0x6B,0x43,0x34,0xBD,0x4A,0xFD,0x13,0xEB,0xD6, +0xE0,0x93,0x55,0xBF,0x43,0xFB,0x31,0xA5,0x0C,0xAC,0xE8,0x46,0x11,0x08,0x72,0x3A, +0xB3,0x9C,0xC9,0xD0,0x35,0x59,0xE4,0xC7,0x5A,0x0E,0xF6,0x33,0x60,0xA4,0x41,0xB9, +0xDD,0x4E,0xB8,0x33,0x9E,0x65,0x98,0x7E,0x65,0x5E,0x6C,0x49,0x51,0x7B,0xFC,0x29, +0x44,0x10,0x9F,0x57,0xDF,0xB5,0x99,0xFD,0x0D,0xE7,0x41,0xF3,0x7A,0x72,0xA1,0x0C, +0x18,0xB6,0x10,0xE9,0xD7,0x00,0xE6,0x0A,0x63,0xE7,0x78,0xAB,0x2B,0xC3,0x8A,0x73, +0x0A,0xB1,0xBD,0x95,0x11,0x4D,0xCA,0x19,0x8D,0x8E,0xB4,0xE5,0xC5,0xD3,0x26,0xC2, +0xA5,0xB5,0xB8,0x70,0xA6,0xC2,0x5B,0x96,0x0F,0x5D,0x07,0xC4,0x54,0xDB,0x9E,0xD9, +0x67,0xBE,0x5B,0x75,0x4F,0x0C,0xC5,0x56,0x17,0x67,0x73,0xF5,0xCA,0x28,0xB9,0x0B, +0x66,0xD3,0x3F,0x6F,0xB0,0xDF,0x76,0x6A,0xB9,0xB7,0xD4,0x49,0x25,0xEF,0x7F,0xF6, +0xCA,0x67,0x2A,0x4F,0xAE,0x23,0xC8,0xA8,0x14,0xFA,0xC0,0x52,0x2B,0xBE,0xBB,0xA4, +0x00,0xCC,0x23,0x86,0x5B,0xFD,0x80,0xA2,0x6F,0xC3,0x5F,0xC6,0x47,0x3E,0xEE,0x29, +0xAB,0xB9,0x78,0x6E,0xA5,0x0E,0xE5,0x23,0x7E,0xE8,0x58,0xA0,0x8A,0xBE,0xFD,0xE7, +0x27,0xF7,0xB9,0x23,0x54,0xC9,0x10,0x44,0xBD,0xC8,0xCB,0x74,0xE8,0xAC,0x41,0x1C, +0xB8,0x64,0x43,0x47,0x6A,0x4F,0x51,0xCA,0xBE,0x2E,0x19,0x9E,0x7E,0xBF,0x01,0x91, +0xEB,0xE2,0x01,0x78,0xB5,0x8D,0x28,0x51,0xF7,0x4D,0x87,0x4A,0xA3,0x74,0xCE,0x11, +0xC0,0x43,0xBD,0x7E,0xF6,0x96,0x98,0x63,0xAB,0x12,0xB7,0xB1,0xA4,0xCD,0x24,0x1E, +0xDB,0xAD,0x1C,0xCE,0x0B,0xB0,0xB2,0x6F,0x38,0x8B,0xB1,0xB8,0xC4,0x7C,0x8B,0x76, +0x63,0x3B,0x1A,0x42,0x02,0x05,0x90,0x2E,0xC4,0x17,0x92,0x8F,0x01,0x85,0xAA,0x88, +0xAF,0x42,0x80,0xEB,0x1A,0x79,0xF4,0xA4,0xDE,0xEF,0xBB,0xB9,0xD1,0xF1,0xEA,0xA8, +0x56,0x73,0x9F,0x56,0xE2,0x21,0x44,0xB6,0x29,0x93,0x0E,0xE0,0xB6,0x68,0x30,0x18, +0xF5,0x7A,0x8D,0x0C,0x6D,0x18,0x58,0x83,0x40,0x67,0xEC,0x29,0x1A,0xC6,0x29,0xBB, +0xB3,0xD0,0xF9,0xAA,0xBC,0x80,0x78,0x26,0xEF,0x65,0xFB,0x5C,0x43,0x3C,0xDF,0x87, +0xB7,0xED,0x29,0x28,0x98,0xFB,0xE6,0xA9,0xB2,0x60,0xE4,0xAF,0xB1,0xDB,0x91,0x9A, +0x36,0xAA,0x28,0x60,0xD0,0x19,0x75,0x32,0xBA,0x63,0xB9,0xE7,0x4F,0xC1,0x04,0x4C, +0xAB,0x13,0xB5,0x2A,0x1A,0xF2,0xDD,0x48,0x0B,0x2F,0x6E,0xE2,0x8B,0x4C,0x41,0x47, +0xC3,0xC5,0xB7,0xE9,0xD7,0x9A,0xC0,0xB6,0x93,0xC0,0x33,0x4E,0xBC,0x65,0x67,0x12, +0xF8,0xF0,0x89,0xAB,0x33,0xE8,0x43,0x6E,0x01,0x3C,0xBE,0x7B,0x12,0x94,0x2E,0x0C, +0x98,0xAB,0x75,0xF7,0xE4,0xEA,0x36,0x25,0xDE,0xE1,0x61,0xE0,0xCD,0x80,0x88,0x0D, +0x8F,0x68,0x9C,0x99,0x82,0x95,0xFD,0x0F,0xF5,0x67,0x62,0x1F,0x4B,0xCD,0xF5,0x2C, +0x22,0x5A,0x22,0xA7,0xB3,0x82,0x4B,0xAA,0xDE,0x4D,0x65,0x90,0x53,0x88,0x58,0x94, +0xF0,0x3E,0xD5,0x45,0xB3,0x1E,0xF7,0x1D,0xD9,0xFA,0x6F,0x0E,0x58,0xFF,0x95,0x90, +0x62,0x5C,0xC6,0xC6,0xC1,0x87,0x65,0xEF,0xF8,0xD3,0xDF,0x3A,0xDE,0x19,0xBF,0xA0, +0x9A,0xA2,0x88,0x23,0x90,0x0F,0xC7,0xCF,0xC9,0x0F,0xFA,0xD2,0x5C,0x4A,0x1F,0xFE, +0xF6,0xD2,0x2B,0xEF,0x73,0x2B,0x67,0xCB,0x6D,0xC2,0x8E,0x83,0xD1,0x8C,0xA9,0x46, +0x69,0x32,0x19,0xB9,0xEE,0x59,0xA5,0xF1,0x69,0x96,0xB0,0x74,0x64,0xE0,0xAF,0x91, +0x49,0x23,0xE3,0xE2,0x01,0xAC,0x67,0x29,0xB5,0xC7,0xC7,0x77,0x39,0x44,0x16,0x15, +0xA7,0x07,0x65,0xB5,0xB6,0x4E,0x95,0xCD,0x23,0xA7,0x1C,0xD3,0x68,0x4B,0xC4,0x64, +0x8E,0x95,0xA5,0x3D,0xC1,0xCB,0xF7,0x60,0xD7,0x8D,0x1B,0x8F,0x09,0xC1,0x01,0x62, +0xF4,0x52,0xBE,0x9C,0x2F,0x06,0x23,0xBC,0xCF,0xE1,0x07,0xAD,0x03,0x38,0xCC,0xE3, +0x5A,0xDC,0x02,0xA9,0xA9,0x24,0xBB,0xA8,0x96,0x2D,0x90,0x34,0xA2,0x6C,0x65,0x67, +0x2B,0x9C,0xEB,0xB5,0x58,0x22,0xBD,0x07,0x75,0xF4,0xE0,0xDF,0x97,0x78,0x77,0x76, +0x14,0x27,0x29,0x8F,0x4D,0x19,0xE7,0xB4,0x84,0x6E,0xA4,0xB7,0xDA,0x9F,0xFB,0xAF, +0xE2,0x19,0x86,0x57,0xC3,0x40,0xE1,0xA8,0x60,0x9B,0x2B,0x73,0x86,0x35,0xF2,0xED, +0x23,0x84,0x4C,0x78,0x6D,0xD1,0x17,0x79,0x9C,0x53,0xB6,0xE1,0xF8,0x68,0x71,0xDF, +0x49,0x91,0x77,0x68,0x8B,0xB0,0x28,0x66,0x3E,0xB4,0xE0,0x22,0xA9,0x6A,0x25,0xC3, +0x1B,0x63,0xA4,0x47,0xBD,0xE4,0xEA,0xC2,0xE4,0x92,0x06,0x38,0x04,0xAC,0xDF,0xE0, +0xBE,0x97,0xE8,0xE1,0x0E,0xE1,0xD6,0xB8,0x1B,0xDD,0x76,0x49,0xDF,0x4B,0xBE,0x50, +0xD7,0x51,0x32,0x1F,0x9D,0x0A,0xBD,0x3E,0x4E,0x07,0xB4,0x8F,0xF0,0xF6,0xAA,0xDA, +0xAF,0x48,0x51,0x1B,0x08,0x8C,0x52,0x71,0xA7,0x6F,0x69,0xFA,0x1B,0x38,0x57,0x21, +0xEE,0x12,0x05,0x62,0xB3,0x64,0xD8,0x5A,0x8D,0x8F,0x43,0x3C,0x3E,0xD0,0x81,0x58, +0xAA,0x22,0x47,0xA3,0x1A,0xCC,0x4C,0x0C,0xCC,0x38,0xD2,0xEB,0xFD,0x6E,0xEE,0x65, +0x22,0x4E,0xC3,0x5E,0x5B,0x24,0x94,0x44,0x68,0x64,0xBF,0x1D,0xFE,0xC9,0xBA,0xAE, +0x5B,0x25,0x5A,0x01,0x7F,0x2A,0xB1,0x8E,0x89,0xF2,0xEF,0x05,0x5F,0x32,0xF8,0x04, +0x62,0x26,0xC8,0x24,0x2F,0x4E,0x4B,0x7A,0x49,0x95,0xCA,0x09,0x9A,0x95,0x2D,0x80, +0x38,0x47,0xCD,0x1A,0xB2,0xD2,0x9C,0xBC,0x60,0x68,0xB9,0xAA,0xD0,0x1B,0xC4,0x8B, +0x39,0xD8,0x99,0x98,0x09,0x8B,0xCA,0x9C,0x85,0x27,0x25,0xDD,0x33,0x34,0x75,0x82, +0x25,0xD6,0x23,0x82,0x62,0x79,0x57,0x01,0xD1,0x9A,0x41,0x6B,0x97,0xD5,0x84,0xD8, +0xBD,0x36,0x79,0xF0,0xD2,0x32,0x51,0x4E,0x24,0xD2,0xC2,0x4A,0x4D,0x0D,0x0B,0x80, +0x81,0xFC,0x17,0x11,0x8D,0x8D,0x92,0xA2,0x0C,0xB2,0xE6,0xF5,0x0C,0x47,0x9A,0x83, +0x24,0x0D,0xC4,0x26,0x0F,0x4C,0xA3,0x61,0x57,0x4B,0x7A,0x2D,0x85,0x64,0xBD,0x88, +0xCB,0x37,0xD8,0x50,0xB6,0x2C,0xE7,0xE5,0x8C,0x80,0xDA,0x84,0x6C,0x15,0xA1,0x98, +0xDD,0xAC,0x7E,0x32,0x92,0x78,0xE0,0x5B,0x9E,0x77,0x39,0x9D,0xF9,0x2E,0xC1,0x1D, +0x41,0x46,0xE5,0x3C,0x32,0x40,0x83,0x88,0x90,0x83,0xF2,0xF7,0x29,0x72,0xD1,0x58, +0xCA,0xEC,0x42,0x6D,0x7E,0x0A,0x27,0x6B,0xD3,0x89,0xDD,0x93,0xD4,0x6F,0x08,0x77, +0xCB,0xDF,0x5E,0xC9,0xB3,0xC9,0x97,0xA9,0xCB,0xC6,0x90,0x20,0xC4,0x26,0x04,0x1F, +0xD6,0x3C,0xF8,0xAE,0x16,0x78,0x77,0xC0,0x1F,0x1E,0x24,0x12,0x50,0x0F,0xC3,0xB7, +0x32,0x8D,0x9A,0x58,0x20,0x20,0xE6,0xDE,0x7F,0xEA,0xE4,0x04,0xDB,0xA3,0x29,0x5A, +0xE7,0x88,0xD9,0xC1,0xFD,0x9E,0x8B,0x12,0x27,0x3B,0xBA,0x45,0x49,0xE9,0x8E,0x35, +0x31,0x74,0x8A,0x91,0xFF,0xAE,0x9B,0x9A,0x97,0x95,0x2A,0x3F,0x22,0x6F,0xF4,0x4C, +0xAA,0xFA,0x76,0x6B,0xE3,0xAD,0x7B,0xC8,0xE9,0x99,0xF0,0x78,0xB5,0x6B,0xEF,0xDF, +0xDF,0x64,0xC2,0xE0,0xBA,0x27,0xC8,0x5F,0xCC,0x81,0x33,0x86,0x1E,0x9B,0x69,0x6D, +0x8F,0xA3,0xE3,0xB2,0xDD,0xC0,0xFB,0x2E,0x93,0x82,0x90,0xA2,0xDB,0xE4,0xAE,0x27, +0x96,0xBF,0x7C,0xD5,0xBE,0x77,0x7E,0x1D,0xFB,0x57,0x29,0xB9,0x5E,0xAD,0xCB,0x62, +0x9F,0x6E,0x5C,0x9F,0x10,0x0E,0x97,0x6C,0xBF,0x66,0x9B,0x6B,0xE2,0x83,0x5D,0x6E, +0x8C,0x4E,0x3B,0x8F,0x84,0x79,0x06,0xA8,0x7E,0xB0,0x05,0xDA,0x4E,0xFD,0x10,0xF1, +0xDE,0x6E,0x25,0x76,0x8B,0xE5,0x16,0x8B,0xAB,0x1D,0xBD,0x62,0x1C,0x65,0x3E,0x46, +0x31,0x4E,0x51,0x4D,0x19,0x76,0x04,0xAD,0x0C,0x1A,0xC8,0x90,0xD6,0x96,0x86,0xD4, +0x51,0xBA,0x4F,0x37,0x6B,0xE7,0x0A,0xA2,0xB3,0xD9,0x80,0x3B,0xA9,0x35,0xAB,0x39, +0x4B,0x85,0x35,0x99,0x50,0xF1,0x75,0x65,0x7F,0x4D,0xD9,0x9A,0xE2,0x40,0xC5,0x94, +0x48,0xB3,0x05,0x9E,0x95,0xDE,0x86,0xA2,0xD0,0x2B,0xB3,0x07,0x32,0x05,0x03,0x66, +0xD4,0xFC,0x13,0x2E,0x6F,0xAB,0xFB,0xB7,0x1F,0xEC,0x5A,0x86,0x42,0xCD,0x8B,0x29, +0x7F,0xB1,0x80,0xA0,0x7F,0x75,0x69,0x46,0x52,0x02,0xCC,0x8C,0xD7,0x44,0xF2,0xA2, +0x9B,0x22,0x22,0x29,0x4C,0xDA,0x93,0x33,0x40,0x56,0xD5,0x61,0x6B,0x84,0x76,0x31, +0x80,0xB7,0x23,0xBE,0x97,0x16,0xF7,0xD5,0x80,0x59,0x0F,0x5C,0x6E,0x5E,0x67,0x76, +0x3A,0xF4,0xED,0x42,0x8A,0x23,0xF7,0xE6,0xA9,0xE7,0xAC,0x01,0x11,0xE0,0x92,0x06, +0x31,0x7E,0xE2,0xF5,0xA5,0x50,0x6A,0x78,0x5B,0x24,0xB1,0x4A,0x4D,0xEC,0x92,0x76, +0x37,0x55,0xCD,0x43,0x26,0x6E,0x80,0xB3,0x9F,0x52,0x31,0x2F,0xBC,0x36,0x81,0x57, +0xD2,0x9E,0x82,0xF0,0x4D,0x40,0x35,0x5E,0xD4,0x9B,0x1B,0x40,0x44,0x43,0x75,0x9A, +0xAE,0x24,0x2D,0x9A,0x1C,0x11,0xC3,0xB7,0x0B,0xF5,0xDE,0xE3,0xBA,0x0B,0x30,0xFC, +0xAA,0x1E,0x20,0x0A,0xE1,0xED,0x53,0x44,0x6E,0xDA,0x64,0x1F,0x53,0x11,0x5F,0xD1, +0x07,0xDD,0xDE,0x46,0x1B,0xE4,0xB9,0xED,0x48,0x5C,0x16,0x03,0xDD,0x98,0x12,0x57, +0x76,0xAD,0x1B,0xA3,0x34,0xE9,0xBF,0xBF,0xAB,0xBB,0xEB,0x90,0xCF,0x85,0x43,0x9C, +0x71,0x99,0x64,0xB2,0x10,0x2B,0x33,0x95,0xF5,0x92,0xD6,0x5D,0x3C,0x6C,0x14,0x20, +0x2D,0x23,0x89,0x43,0x9B,0xAC,0x17,0x30,0x9D,0x76,0x3A,0x5D,0x87,0x58,0x6A,0x15, +0xCA,0x39,0xC5,0x6E,0x2C,0x57,0x1D,0xF9,0x7C,0x41,0xEE,0x3D,0xF8,0x18,0x0B,0x8C, +0x36,0xAD,0xEC,0xFC,0x34,0xF3,0xEF,0x72,0x58,0xE7,0x60,0x19,0x87,0xDA,0x24,0xB7, +0xFF,0xCA,0xD7,0xAE,0xE9,0x6F,0x39,0x9E,0x65,0xA0,0x70,0xAA,0xB8,0x37,0xF6,0xDC, +0xC9,0xE8,0xE1,0x17,0x11,0xAA,0xAC,0xCB,0xF0,0x9F,0xEC,0x8D,0x9A,0x56,0x32,0xBD, +0x2A,0xD1,0x5A,0x22,0x33,0x0E,0xD4,0xC5,0x57,0xAF,0x94,0x4B,0x2A,0x7F,0xFB,0x8D, +0x07,0xDA,0x0D,0xBD,0x46,0x2E,0x0B,0xC5,0xCD,0xAD,0x65,0x53,0x62,0x8A,0x46,0xCC, +0xD5,0xF6,0x05,0xF2,0xDE,0x94,0x4E,0xDD,0xC0,0x33,0x87,0xE3,0x7E,0xBE,0xCC,0x1B, +0xDD,0x2E,0xD2,0x6D,0x85,0xEC,0x28,0xE0,0x79,0x20,0xC8,0x6B,0x5C,0x61,0xBC,0x13, +0x56,0xEC,0xF3,0x29,0xB9,0xCF,0x8F,0x12,0x73,0xF0,0x8C,0x6E,0xFF,0x6B,0xA2,0x68, +0x20,0x13,0xF4,0xD0,0xCF,0x81,0x00,0x29,0xE2,0x4D,0x70,0x17,0x20,0x3C,0xE1,0xAD, +0x6F,0xA9,0x22,0xC5,0x44,0x6E,0x74,0xC0,0xFC,0xAE,0x37,0x1F,0xED,0xCB,0x99,0x41, +0x22,0xD3,0x30,0x5B,0x60,0xA3,0x05,0xB9,0x0C,0xD8,0x79,0x46,0x1F,0xFE,0x26,0x5A, +0xB8,0xA5,0x41,0x9E,0x18,0x04,0xD7,0x67,0x06,0x54,0x8D,0xB7,0x9B,0x4F,0x4E,0x6F, +0x73,0x3D,0x04,0x0B,0x4E,0x03,0x4B,0x0B,0x36,0x0A,0xBD,0xA9,0x9A,0xF3,0x8A,0xC5, +0xAD,0x86,0x4B,0x00,0x9D,0x1C,0xAB,0xB3,0x6F,0x4C,0x55,0x5D,0xD0,0x3D,0x79,0xA7, +0xA4,0xAD,0x6F,0x85,0x25,0xEA,0x58,0xCC,0xCA,0x1F,0x30,0xA7,0x9E,0x25,0xD9,0x4D, +0x74,0xD8,0x55,0x19,0x87,0xA4,0x34,0xE8,0x09,0x64,0xBE,0xD8,0x40,0x5C,0x34,0xD1, +0x4A,0xCA,0x4C,0x5C,0x57,0x5E,0x05,0x2C,0xDC,0x35,0x3A,0x17,0xC8,0x23,0xDD,0x26, +0x7A,0x93,0x69,0x7E,0x17,0xA7,0x85,0x23,0x7F,0xEE,0xFD,0x0F,0xE8,0x08,0x09,0x0A, +0x00,0x9F,0x42,0xE0,0xBA,0xE9,0x9A,0x37,0x77,0x92,0xF6,0xB0,0x63,0xF2,0xCF,0x8A, +0x18,0x93,0x27,0xE0,0xA4,0xAD,0xD7,0xEE,0xFE,0x8A,0x09,0x11,0xE7,0xF3,0x6B,0xC5, +0xE4,0x65,0xA7,0x22,0x16,0x98,0x2B,0x75,0xE8,0x0B,0x22,0x91,0x49,0x85,0xE8,0x09, +0x74,0x4C,0xB8,0xFA,0x13,0xC3,0xEC,0x4E,0xD8,0xB6,0x70,0x8B,0x07,0xDD,0xB3,0x3C, +0xEA,0xE8,0xE2,0x4C,0xE2,0x73,0xB8,0x21,0x5A,0xA2,0x3E,0x13,0x98,0xBD,0xBD,0x0E, +0x16,0x15,0xF6,0xDD,0x31,0x88,0xCE,0x39,0x96,0xAE,0x9F,0xD3,0x01,0xB4,0xE2,0x96, +0x5A,0x96,0x46,0xE9,0x5F,0xFD,0x94,0x1C,0xA2,0xE8,0x0B,0xC0,0x08,0x87,0x21,0xE6, +0x9B,0x24,0x19,0xE3,0x1C,0xFA,0x1D,0x45,0x49,0x52,0x62,0x7B,0xCE,0xC0,0x6D,0xAE, +0x99,0x7C,0xF8,0xBB,0x4A,0x15,0x73,0xE5,0x96,0x59,0x6B,0x96,0x9F,0x61,0x81,0x55, +0xBB,0x0F,0xE4,0xC4,0xB9,0x39,0x11,0x1D,0x09,0xD0,0x3E,0x95,0x11,0x52,0x79,0xDD, +0xF9,0x83,0x65,0x68,0xEA,0x0F,0xCE,0x4A,0xA5,0xCC,0x99,0x22,0xC8,0xD9,0xC4,0xBF, +0xA7,0x20,0x72,0x1F,0xA4,0x52,0x23,0x97,0x5B,0x53,0xBD,0xB6,0x82,0x01,0xE0,0x2B, +0x9C,0xA4,0x54,0xFC,0x62,0xA4,0xDD,0x8F,0xA3,0x09,0x49,0xD6,0x0C,0x2E,0x46,0x93, +0xF6,0x0B,0x12,0x4E,0x4A,0x14,0xAD,0xE4,0xF4,0x03,0x8D,0x34,0x74,0x4A,0xD4,0xDB, +0xB7,0x9E,0x44,0x9E,0xD3,0x8F,0xD7,0x68,0x36,0x94,0xBF,0xC2,0x62,0xB5,0xE3,0x17, +0x23,0xA1,0xF5,0x7F,0x6A,0x4A,0xE7,0xF9,0xEC,0x4D,0x3B,0x9C,0x06,0x67,0x64,0x8A, +0xB4,0x33,0x5E,0x8C,0xDE,0xD1,0xB4,0xE1,0x0E,0x72,0xD3,0xF7,0xAC,0xFD,0x1C,0x67, +0x86,0x6D,0x50,0xD9,0xAF,0x1E,0xAF,0x76,0x44,0x45,0x7C,0x33,0x61,0x86,0x12,0xCC, +0xB1,0x3E,0xF6,0xB7,0x7D,0x2B,0x19,0x6D,0xC8,0x69,0xAF,0xDA,0x20,0x7C,0x00,0xFD, +0xFE,0xB9,0x09,0x8A,0x85,0x2A,0x02,0x4A,0x3D,0x97,0xB6,0x00,0x77,0xEA,0x3E,0xC2, +0x25,0x91,0xDC,0x2F,0x47,0x60,0xD5,0x93,0x41,0x74,0x63,0xA7,0xE5,0x27,0xFB,0xAD, +0x24,0x8B,0x4D,0x0E,0x68,0x9F,0x27,0x03,0x5E,0x55,0x66,0x94,0xB0,0x7E,0x00,0x90, +0x44,0xFA,0x6C,0x7B,0xC1,0xED,0x45,0x9C,0xD9,0x7F,0xE1,0xB9,0xB7,0x88,0x0A,0xE4, +0xE1,0x67,0x1F,0x79,0xA2,0x17,0xE8,0x16,0x41,0xD8,0xBA,0x9D,0x91,0x00,0x0C,0x8A, +0x59,0x1E,0xEA,0x1E,0xA4,0x84,0x69,0x5D,0x06,0x05,0xA6,0xDC,0x88,0xDC,0x9C,0xD9, +0x51,0x3B,0xBB,0x71,0xD8,0x13,0xA1,0xA7,0xFD,0xE4,0x3D,0x91,0xC8,0x2F,0x2F,0xB2, +0xA3,0x05,0x19,0x6A,0x83,0xF2,0x7E,0xC5,0x05,0xE5,0x1C,0xE8,0x76,0xBE,0xC7,0x73, +0x4D,0x18,0x1B,0xA3,0x35,0x62,0x71,0x64,0x79,0xEB,0x26,0x4A,0x7D,0x17,0x44,0x7A, +0xEE,0x1E,0x1A,0x0B,0xF2,0x63,0xDA,0x64,0xBF,0x65,0x46,0x27,0xEB,0xB2,0x04,0x00, +0x08,0x6D,0x73,0x87,0x4F,0x0E,0x9C,0xCD,0xA6,0x92,0xA5,0x33,0xF2,0x49,0x92,0xDE, +0x4C,0xA3,0xA6,0xF6,0xE0,0x05,0x03,0x5C,0x38,0xEF,0x52,0x8A,0x12,0xA8,0x9D,0x99, +0x07,0x26,0x7A,0x5F,0x9B,0x11,0x54,0xC8,0x4D,0x5C,0x85,0x2B,0xBE,0xE6,0x57,0x52, +0xD2,0x13,0x80,0x1D,0x96,0x1C,0x3D,0x02,0x2F,0x93,0xDD,0xEE,0xB6,0xBC,0x4F,0x08, +0xE3,0x89,0xB0,0xCF,0x69,0x53,0x8C,0x16,0x8A,0xCF,0x76,0x25,0x7F,0xBB,0x5E,0x09, +0x29,0xD5,0xB5,0x35,0xD6,0x43,0x97,0x2B,0x4B,0x5B,0x13,0x3C,0xB6,0x3A,0x0D,0x49, +0x19,0x66,0xA0,0xA8,0xD0,0x08,0x02,0xCF,0xE7,0x89,0x49,0x41,0x0D,0x58,0x34,0x18, +0x1B,0x3C,0x74,0x5C,0x24,0x91,0x13,0x29,0xBA,0x54,0x9A,0xE8,0xC4,0x8E,0xB6,0x31, +0xE8,0x31,0xF3,0x37,0x90,0xC0,0x13,0xFC,0x9A,0x31,0xB5,0x78,0xCA,0x40,0xEF,0xEB, +0xF3,0x80,0x4D,0x59,0xEF,0x76,0x44,0x41,0x97,0xDD,0x4F,0x43,0x66,0x5B,0xBB,0x5B, +0xDC,0x80,0x63,0x48,0x01,0xB6,0xDA,0x1F,0xD5,0xA3,0x98,0xC8,0x86,0x89,0x48,0xB1, +0xE0,0x7C,0xC2,0xBE,0x9F,0x64,0xB8,0x4E,0x6F,0xE4,0xE0,0x06,0x46,0xCE,0xF7,0x3D, +0x84,0x2E,0xBF,0x85,0x3A,0xAB,0xB6,0xC5,0x34,0xD0,0x4B,0x8F,0x70,0x48,0x92,0x5F, +0x2B,0xC9,0x5F,0x3B,0xA6,0x0F,0x7F,0x24,0x47,0x67,0x05,0x00,0xB1,0x6D,0xF1,0x5E, +0x0F,0x18,0x82,0x39,0x35,0xD0,0x86,0x5D,0xFE,0xE4,0x27,0xB6,0xF3,0x8A,0x5B,0xCA, +0x00,0x1C,0xBC,0xDB,0x98,0xAD,0x78,0xE4,0x12,0x6F,0xAA,0x11,0x93,0xD7,0xDE,0x8D, +0x38,0x99,0xDC,0x82,0xBE,0x91,0xE9,0x73,0x95,0xA1,0x3C,0x1F,0x0B,0xA6,0xE1,0x6E, +0xF6,0x5B,0xCA,0x1F,0x2E,0x7A,0xA9,0x62,0xAF,0x44,0x7F,0xAC,0x96,0xB3,0xDF,0xB1, +0xF5,0x0F,0xED,0x35,0xD3,0x0C,0x91,0x73,0xF9,0x23,0x8D,0xE2,0xBC,0xF8,0x34,0x27, +0x2D,0xB2,0xCD,0xF4,0xC4,0xA2,0xF4,0xAF,0x6D,0x76,0xF0,0x36,0x51,0x83,0xCF,0x58, +0x48,0x9F,0xC1,0x6B,0x10,0xA6,0x20,0xBE,0x62,0x36,0x23,0x77,0x1E,0x89,0x5A,0x2F, +0x30,0xF7,0xE2,0xCB,0x0C,0x1E,0xA0,0xCE,0x36,0x72,0x50,0xBB,0x30,0x43,0xA5,0x14, +0x21,0xB6,0x72,0x31,0x98,0xEA,0x63,0xB7,0x77,0xA7,0x8F,0x47,0x0E,0xD0,0xF5,0x4B, +0xD0,0x33,0xEE,0x7D,0x1C,0x17,0x22,0xDB,0x39,0xB9,0x95,0x60,0xDB,0xB1,0x87,0x26, +0x71,0x78,0x41,0xB9,0xB8,0x14,0x30,0xC4,0x25,0x0B,0xF4,0x66,0xF0,0x2F,0x14,0x8A, +0x8E,0xC9,0xB4,0xC7,0x2F,0xDB,0xFD,0x47,0x31,0xB4,0x79,0x6A,0x4F,0x4A,0xA3,0xC0, +0x73,0x67,0x81,0x95,0x28,0xE4,0xE0,0xEA,0x2D,0x64,0x5A,0x7B,0xAB,0x3A,0x51,0x87, +0x14,0x33,0x88,0x93,0xDF,0xB4,0x9E,0x5E,0xD5,0x34,0x9F,0x11,0xB1,0x12,0xC2,0x90, +0x08,0x3D,0x5E,0x9F,0xD0,0x45,0x77,0xC6,0x3D,0x93,0x34,0xC4,0xCA,0xDC,0xE8,0x0F, +0x16,0x1B,0x29,0xDA,0xE9,0x58,0x22,0xD6,0x08,0xC1,0x58,0x03,0x55,0x40,0x8A,0xEC, +0x11,0x88,0x84,0x4B,0x89,0x6D,0x59,0x72,0xCA,0xE7,0x77,0x3D,0x16,0x26,0x39,0x89, +0x72,0xBA,0x83,0x03,0x5C,0x8A,0x76,0xBF,0x35,0xA7,0x59,0x6C,0x29,0x52,0xEE,0xCD, +0x33,0x4C,0xCF,0xF5,0xAC,0x9A,0x77,0x55,0x44,0xDF,0x5A,0xA5,0xA0,0x54,0xED,0xEA, +0x51,0x45,0x5A,0x7C,0x77,0x2B,0x6B,0x1C,0xC6,0xFD,0x67,0x47,0x69,0x25,0x60,0xEB, +0xC5,0x21,0x48,0x28,0xD4,0xF9,0x61,0x77,0x2E,0x63,0xDD,0x93,0x47,0x65,0x26,0xFF, +0x1F,0xCA,0x36,0xBE,0x67,0xD4,0x81,0x1E,0xAD,0xC6,0x24,0x98,0x17,0xA8,0xFD,0xE6, +0x63,0x69,0x3E,0x83,0x57,0x3A,0xB6,0x57,0xC8,0xFB,0x48,0xCA,0x50,0x77,0x5A,0x64, +0x5D,0xC2,0xA3,0x62,0x96,0x28,0x53,0x87,0x3D,0x83,0x38,0x51,0x95,0xC5,0x81,0xD2, +0x6C,0xD4,0xCC,0x62,0xB9,0x1D,0x8F,0xF9,0x00,0x68,0xDB,0x60,0x47,0xDF,0x81,0xF1, +0x94,0x59,0x34,0x49,0x7E,0x95,0x31,0xA1,0x12,0x2A,0x6A,0xCA,0x5F,0x57,0x3B,0xB9, +0xB3,0xBD,0x3C,0x5A,0x81,0x40,0x0E,0x7F,0x6D,0x95,0x2B,0x9D,0x0F,0x14,0x22,0xA0, +0x12,0x12,0xFC,0xFE,0x0C,0xD5,0xEE,0xE5,0x9A,0x0E,0x0F,0x9F,0xB3,0x88,0x8E,0x1A, +0x29,0xC6,0x44,0x06,0x47,0x0A,0x2D,0xE7,0xDA,0xA0,0xDE,0xD0,0x12,0xC0,0xAD,0x46, +0x54,0x96,0xE3,0xA9,0x13,0xBE,0x9E,0x0D,0xDA,0xBF,0xF3,0x0B,0x87,0x32,0x57,0x33, +0xD9,0xCA,0x3C,0xE0,0xD8,0x05,0xE9,0x62,0x66,0xE9,0xAF,0xA4,0xE6,0xF0,0x99,0xE1, +0xC6,0x34,0xE4,0x5A,0xC8,0xBB,0x0C,0x01,0x7D,0xC8,0x10,0x45,0xD6,0x67,0x21,0x6A, +0xB6,0x16,0x3B,0xB5,0x9F,0xBE,0x4A,0xC5,0xFD,0x32,0x79,0xDC,0xF0,0xB7,0xD5,0xC8, +0x25,0x0B,0xAD,0x3D,0xD5,0xC5,0x69,0xFF,0x0B,0x2D,0xDB,0x50,0x36,0x9B,0xF3,0xA5, +0x16,0x95,0x05,0xC8,0x1E,0x30,0x9B,0x93,0xBA,0xEA,0x6B,0x81,0x10,0xF4,0x35,0x1E, +0x8B,0xE7,0x12,0xF6,0xBC,0x3B,0xA4,0x0B,0xE6,0x86,0xE0,0x4F,0x06,0x75,0xCA,0xE6, +0x92,0x30,0x93,0xE9,0x3E,0x13,0x51,0x1D,0xC7,0xD6,0x90,0x4E,0xAF,0x84,0x3A,0x85, +0x6F,0xA7,0xE8,0x95,0xE7,0x33,0xCA,0x61,0xE6,0x2D,0x78,0xEF,0x5A,0xB1,0x3A,0xFB, +0xA7,0x7A,0x71,0x95,0xD7,0xC2,0xA9,0x31,0x96,0xC8,0x85,0x99,0x28,0x9B,0x19,0x60, +0xD5,0xE8,0xC9,0xB3,0xD9,0x6B,0xA1,0xF2,0xBA,0xAC,0x05,0xCF,0x54,0x92,0xD9,0xC3, +0xF9,0x1D,0xC3,0xDB,0x72,0xD3,0x36,0xD0,0xD3,0x80,0x37,0xCB,0xF7,0x96,0x55,0x90, +0x98,0xBC,0x81,0x8F,0xA2,0x07,0x60,0xEF,0x1E,0x5A,0x8C,0xE6,0x3F,0x60,0x6E,0xEF, +0x82,0x76,0x7E,0x42,0x7A,0x00,0xBB,0x0C,0x62,0x6E,0x2D,0x7F,0x46,0x46,0x3D,0xE6, +0x3D,0xBB,0x5C,0x9E,0xDA,0x7A,0x57,0xDF,0xBA,0x1B,0xC9,0x7C,0xD6,0x92,0x3A,0x58, +0x45,0x5B,0xB4,0x69,0x79,0x19,0xED,0x16,0xA8,0xE4,0x9D,0xF6,0x6C,0x97,0xE2,0x30, +0x90,0x92,0x47,0x7E,0x48,0x0E,0x02,0xC1,0x64,0x04,0xC3,0xD1,0xF9,0x27,0x5F,0x61, +0x5B,0x8A,0xC8,0x98,0x41,0x95,0xC9,0x91,0xD9,0xFF,0x2D,0x71,0xA0,0x79,0x76,0x7F, +0x1E,0x22,0x63,0xF4,0x76,0x8B,0xA5,0x66,0x2A,0x8D,0x33,0x62,0x06,0xD6,0x96,0x09, +0x97,0xC3,0xBD,0x28,0x8E,0x74,0x2C,0x70,0x39,0xDA,0x54,0x2E,0xF9,0xD9,0x68,0xF3, +0x9A,0x00,0x69,0x74,0x0A,0xED,0x5E,0xD5,0x0E,0x09,0xB4,0x4D,0xBB,0xCD,0x59,0x30, +0xBC,0x3F,0xFA,0xB5,0xCB,0x97,0x93,0x3E,0x94,0x6F,0x39,0xCC,0xB4,0x71,0xB4,0xFC, +0x95,0xB4,0x85,0xFA,0x33,0xDA,0x4C,0x4F,0x3A,0x8B,0x76,0x89,0xE0,0x91,0xFF,0xB4, +0x50,0x86,0x6F,0xDB,0x4F,0x3B,0x21,0x37,0xDA,0x37,0xA4,0xE3,0xDB,0x37,0x9F,0x12, +0xB9,0x96,0xB7,0x23,0xAA,0xD0,0xAD,0xCD,0xB6,0x21,0xB9,0x14,0xB8,0x9B,0xA7,0xCC, +0xE0,0xE6,0xE1,0x2E,0x3F,0x87,0x0F,0xCE,0x54,0x8E,0x90,0xBA,0x8C,0x9F,0x0A,0xF2, +0x97,0x51,0xBC,0x89,0x0C,0x01,0xE5,0xD5,0x4C,0x88,0xAF,0xF3,0xE8,0x27,0x53,0x41, +0xC7,0x02,0xDB,0x94,0xC3,0x76,0xCD,0xB8,0x56,0xF0,0xF1,0x43,0xFB,0xCA,0x30,0x3D, +0x86,0xAB,0xCD,0x95,0x65,0xCD,0x7C,0x93,0x20,0xA8,0x3E,0x5A,0x6F,0xC9,0xE8,0xFF, +0xD0,0x03,0xC1,0x38,0x9B,0x4E,0x96,0xD1,0x4E,0x34,0x89,0x8D,0xCC,0xE4,0x86,0x35, +0x63,0xC3,0x2D,0xE2,0xB1,0x57,0x64,0x9C,0xA6,0x95,0xE6,0x1A,0x80,0x7E,0xAC,0x1D, +0x1A,0x9A,0x90,0x4A,0xA4,0xBB,0x16,0x3A,0xF2,0x00,0xF3,0x38,0x60,0x06,0xCB,0x5D, +0xAC,0x11,0x31,0x57,0x97,0x3A,0x76,0x5D,0x88,0xE3,0xD5,0xBD,0x82,0xF4,0x30,0x4C, +0xAE,0x7B,0xEB,0xBA,0x74,0xC1,0x4F,0xFF,0x85,0x7F,0x3C,0xCF,0xEC,0x3B,0xC8,0x84, +0x00,0xE3,0x64,0xDF,0x77,0x25,0x61,0x31,0xD8,0xF2,0x92,0xDF,0x70,0x6C,0x20,0x4D, +0x76,0xDD,0xF3,0xB3,0x33,0xA1,0xDE,0x7B,0x9F,0x48,0x01,0x5E,0xF4,0x3C,0x95,0xB0, +0x9E,0x67,0x92,0x56,0x0B,0xBC,0x66,0x9B,0x4F,0xE2,0x88,0x20,0x89,0xB8,0x5A,0xB3, +0x95,0x57,0xCF,0xE4,0x7B,0x2D,0xDA,0xE4,0xFD,0x4C,0x4D,0x56,0x2B,0x63,0x58,0x13, +0xE2,0x78,0x64,0x0D,0x8D,0x99,0xC7,0xCC,0x5E,0xA2,0x07,0x56,0xAC,0x82,0x1E,0x20, +0xC7,0xF4,0xD6,0xFB,0xBE,0x35,0x3F,0xDB,0x34,0x09,0x88,0x90,0x46,0x65,0x98,0x70, +0x98,0xA5,0xEE,0xB9,0xE3,0x68,0xD7,0xF9,0xCE,0xCA,0x48,0x80,0x97,0xBA,0x32,0x1C, +0xAF,0x1A,0x5F,0x4D,0x53,0xA0,0xB9,0x3C,0x8A,0x7E,0xD2,0x8E,0x5C,0xF2,0x68,0x1A, +0xCF,0x06,0xDA,0xDF,0x7C,0xF9,0x90,0xF6,0x16,0xB2,0x7D,0xDA,0xA9,0x38,0x71,0x7F, +0x79,0xDE,0x71,0xA7,0xE0,0xFF,0xA3,0x96,0x00,0xF0,0x3E,0x67,0x90,0x20,0x1D,0xF1, +0xB2,0xF6,0xCE,0x73,0xF9,0x8B,0x01,0x72,0xDC,0x0A,0xEF,0xA4,0xB4,0xED,0x46,0xBC, +0xA6,0x6F,0x25,0x13,0xB6,0x27,0xA7,0xC7,0x2E,0x88,0xD1,0x68,0x64,0xA9,0xDB,0x99, +0xC3,0xBD,0x4B,0x0E,0x25,0x2E,0x32,0x87,0xA5,0xA8,0x86,0x91,0xCE,0x95,0x8E,0x3E, +0x5C,0x28,0xE4,0xE2,0x60,0xBB,0xA4,0xFF,0x1F,0xE7,0x69,0x9F,0x05,0xC2,0xB7,0xBB, +0xBE,0x8A,0x62,0x73,0x7B,0x2A,0x77,0x5F,0x2E,0xBB,0x20,0xB9,0xFC,0x42,0xED,0x2A, +0x28,0xD4,0x9B,0xDD,0xB6,0x98,0xE8,0x9F,0x08,0x5C,0x37,0x5D,0xFD,0x74,0x95,0x4B, +0x25,0x9D,0x19,0xFA,0x95,0x63,0x74,0x61,0x91,0x2C,0x40,0x2A,0x5F,0x4B,0x0C,0xE6, +0xD1,0x9B,0xB0,0xD4,0x82,0x01,0xA0,0x35,0x85,0x2F,0xB9,0x64,0xA9,0x61,0x2C,0xD6, +0x0D,0x3C,0x58,0x8E,0x3E,0x59,0x97,0x93,0x7E,0x75,0xE7,0xDA,0x4D,0x12,0x28,0xBA, +0x8E,0xD5,0x83,0xB4,0x61,0x69,0x22,0xAF,0xD9,0xCE,0xEB,0x66,0x68,0x13,0x26,0xE0, +0x6D,0x90,0x82,0x2F,0x43,0x79,0xE6,0x01,0xC1,0x17,0x29,0x9B,0xB8,0x38,0xA6,0x14, +0xFB,0x34,0x28,0x96,0x1E,0x67,0x7A,0xD4,0x30,0x24,0xFF,0x57,0x4E,0x3E,0x25,0x46, +0xF9,0x1E,0x4C,0x26,0x85,0xB2,0x90,0x4A,0x3B,0x89,0x23,0xC4,0x0E,0x11,0xB1,0x5B, +0x3A,0x0D,0x22,0x70,0x1E,0x3F,0xC7,0x07,0x33,0x5E,0x10,0x47,0x9D,0xBD,0x6C,0x2F, +0x38,0x72,0xC5,0xF3,0x4A,0x97,0xD0,0x75,0xB3,0x51,0x34,0x1B,0x56,0xB3,0xC7,0x36, +0x8C,0x5D,0x58,0x01,0x04,0x8F,0x4D,0x06,0xA0,0xB1,0x16,0x4B,0x83,0x42,0xB2,0x96, +0xEB,0x8C,0x13,0xA2,0x8F,0xFD,0xFF,0x42,0xB9,0xBE,0x6B,0x48,0x14,0x29,0xD3,0xCE, +0xD4,0xD9,0x22,0x8B,0xA2,0xFF,0x38,0xB0,0x2A,0x5A,0x4C,0x8F,0x05,0x30,0x53,0x44, +0x66,0xC4,0xEE,0x2D,0xB0,0xC3,0x7E,0xE3,0x6D,0x2D,0xE9,0x0D,0xDE,0x65,0x65,0xF8, +0xAF,0x51,0x5C,0xCC,0xB3,0x23,0x67,0x87,0x3C,0x28,0xDF,0xA3,0x3F,0x73,0x9D,0xCC, +0x08,0xF8,0xA5,0x18,0x6D,0x7F,0x9A,0xA5,0x62,0x3D,0x0D,0xA2,0xDF,0xDA,0x87,0x08, +0xC0,0x5F,0x4F,0xF6,0x13,0x88,0xEC,0x47,0x1C,0xA8,0x35,0x04,0xC4,0xC2,0xC2,0x50, +0x5F,0x71,0x24,0x66,0xF8,0xBD,0x81,0xDF,0x54,0xFC,0x55,0xEE,0x1B,0xFB,0xBF,0x74, +0x9F,0xD6,0x67,0x6E,0x56,0xE6,0x28,0x8E,0x28,0xDE,0x5E,0x99,0xEE,0x30,0x39,0x0F, +0x13,0x86,0x59,0x90,0x6B,0xF2,0x4E,0x70,0x7E,0x2A,0x2E,0x54,0x77,0x04,0x68,0x92, +0x64,0xCA,0x3A,0x88,0xB2,0xFA,0xCD,0x23,0x8D,0x74,0x55,0x35,0x2E,0xD5,0xA3,0xD7, +0x61,0xE0,0x55,0x00,0xF0,0x00,0x31,0x1D,0x0E,0xE2,0x17,0xFD,0x5F,0x3E,0xE7,0xB1, +0x52,0xC8,0x85,0x0A,0x2E,0xC6,0x7E,0x21,0x78,0xFC,0x33,0xDD,0x56,0x28,0x07,0xC1, +0xD4,0x9F,0x79,0x54,0x94,0x62,0x04,0xA0,0x23,0x70,0x94,0x6B,0xAA,0x73,0x14,0xCE, +0x7F,0x9F,0x39,0x4D,0x2A,0xCE,0xE2,0xF4,0xE9,0x25,0xF9,0xE9,0x2A,0xBA,0x41,0x16, +0xD1,0x1D,0x27,0x86,0x43,0x11,0x0A,0x3F,0x9E,0xD7,0x8D,0x40,0x0E,0x5C,0x1C,0xA0, +0xA7,0x5C,0x69,0x77,0x5A,0xD3,0x89,0xE1,0xAF,0xBB,0xD7,0x09,0x29,0x3F,0x97,0x36, +0xDE,0x23,0x0C,0x60,0x32,0xFC,0xAB,0x4A,0xD6,0xC4,0x43,0x6D,0x33,0x33,0x0E,0xF9, +0xA3,0x69,0xB4,0xBC,0x1B,0x3B,0x00,0xA3,0x85,0x1A,0xE3,0x42,0x6F,0xD1,0x6E,0x98, +0xB5,0x73,0x18,0x46,0x67,0x9A,0x2F,0x28,0x9A,0xE9,0x11,0x96,0xF3,0xB5,0x1E,0x09, +0x8C,0xE0,0x02,0x67,0xCC,0x35,0x22,0x5C,0x96,0x46,0x25,0xA6,0x2D,0x1C,0xCB,0x75, +0x6F,0x04,0xDC,0xBF,0x7B,0x65,0xF4,0xD8,0x0B,0x43,0x17,0xAA,0x30,0x24,0x80,0xBC, +0x01,0x37,0xD9,0xE9,0xBD,0xA8,0x18,0x8A,0x70,0xF8,0xE6,0xEE,0x8D,0xDF,0xEC,0xB2, +0xEF,0xAE,0x13,0xD1,0x0C,0x60,0xF9,0x79,0x6F,0x95,0xF2,0x0C,0x69,0x35,0x45,0xA7, +0x8F,0xA8,0xF3,0x9A,0x60,0x76,0xBE,0xC9,0xEA,0xAC,0x83,0x91,0xD1,0x77,0x4D,0x3B, +0x4D,0x35,0x57,0x58,0x12,0xF9,0xBE,0x7F,0x86,0xB0,0x93,0x36,0xB1,0x8C,0x07,0xDB, +0x92,0x0F,0x8F,0xF7,0xE1,0xB1,0xD9,0x54,0xEE,0x9D,0x06,0x13,0xEC,0x79,0x56,0xA2, +0xB6,0x29,0xE4,0x77,0xDC,0x63,0xC2,0xAC,0x3F,0x48,0x47,0xD8,0x10,0x2B,0x05,0x40, +0x6B,0x21,0xAB,0x89,0x53,0xDB,0xA9,0x78,0xA0,0xAD,0x25,0xCE,0xC2,0x40,0x51,0x80, +0x1A,0x60,0xF3,0x7B,0x75,0xA8,0xE1,0x34,0x6F,0x1C,0xAB,0x63,0x34,0x74,0x31,0x75, +0xB8,0x26,0xD1,0xAE,0x62,0xD0,0x05,0x9B,0xED,0x41,0xEE,0xEC,0x17,0x52,0x0B,0x76, +0x47,0x64,0x17,0x5D,0xE1,0x94,0x43,0x0B,0xB2,0x19,0xA5,0x8B,0xA6,0x6D,0xDE,0xAA, +0x74,0xD4,0x56,0x64,0x6C,0x0B,0x53,0x6E,0xB2,0x4A,0xD6,0xEC,0xDC,0xDD,0xD0,0x32, +0xF6,0x8B,0x78,0xB7,0x47,0x57,0xE3,0xCC,0x26,0xA0,0x5C,0x50,0xED,0xBE,0x2A,0x89, +0x3E,0x04,0xA0,0x43,0xAE,0x98,0xDC,0x2B,0xDB,0xF7,0x90,0x2A,0x5E,0x1E,0xAB,0xA6, +0xB6,0x67,0x7D,0xC5,0xC5,0x12,0x8A,0x5C,0x09,0x3A,0xC2,0x24,0x20,0x4D,0x64,0x27, +0xC9,0xED,0xA4,0x72,0x9D,0x27,0x4C,0xE4,0xCC,0x95,0x6C,0xD1,0x97,0x43,0x2B,0x47, +0x7C,0xED,0x40,0xDA,0x7B,0xFE,0xE8,0x53,0x4F,0x48,0xF8,0xFE,0x72,0x3E,0xDD,0xAC, +0x7B,0x97,0x90,0x95,0x39,0x72,0x3F,0x9C,0xFD,0xE6,0x72,0x21,0x77,0x87,0x6E,0x3B, +0xA9,0x1A,0x6A,0xF0,0xC2,0xA4,0x6D,0xEF,0xA3,0x17,0x1F,0x0E,0x53,0xD2,0x34,0x98, +0xB2,0x15,0x78,0x12,0xBA,0x94,0x08,0x6F,0x8D,0x64,0xCF,0x48,0x7A,0x55,0x6A,0x16, +0x38,0xD1,0xD6,0xF6,0x66,0x90,0x9A,0x34,0x1D,0x83,0xA5,0x7F,0xC9,0x5B,0xE2,0x4A, +0x64,0x50,0x22,0x62,0x1E,0x68,0xC5,0x72,0xB8,0x66,0x3D,0x1E,0xD4,0x9B,0x07,0xC5, +0x6A,0x57,0x82,0x9C,0x90,0x11,0x3B,0x5E,0x03,0x51,0x25,0x4B,0xBB,0x54,0x51,0xED, +0x12,0x9C,0x1C,0x11,0x9D,0xB5,0x5E,0xEB,0x2A,0x16,0xDF,0x1F,0x03,0x14,0xC2,0xC4, +0xA1,0x78,0x0A,0x5A,0xD3,0x6A,0xA1,0x5C,0xAF,0x4F,0x56,0xDA,0x92,0x05,0x6C,0x20, +0xAF,0x6B,0xB0,0xF3,0xBD,0x04,0x61,0x44,0x49,0xB1,0xCF,0xB5,0xFB,0xA5,0xA2,0x90, +0x43,0x1E,0xA7,0x69,0x4A,0xB2,0x52,0xF0,0x7B,0x40,0x96,0x11,0xDD,0xFD,0x18,0x67, +0xCE,0x8A,0x43,0xE1,0xB0,0x6D,0x50,0xE2,0x42,0xED,0x7F,0x34,0x5D,0x54,0x41,0x06, +0x9D,0x65,0x11,0xC7,0xFC,0xF4,0xF4,0x5D,0xC7,0x6E,0x33,0x91,0x5F,0xDA,0x39,0x5C, +0x59,0x60,0xB5,0x84,0x05,0x89,0xFF,0xD8,0xFA,0x38,0xF4,0xD9,0x7A,0xAD,0x20,0x36, +0xDD,0xC7,0x65,0x2B,0x87,0xDC,0x34,0x3E,0xBA,0xC3,0xDA,0xE5,0xC4,0x7F,0xCA,0x02, +0xE6,0xE3,0x70,0xF9,0xF2,0x40,0x61,0x92,0x4E,0x52,0x63,0x41,0xCA,0x81,0x67,0x9E, +0xC6,0x5A,0x76,0x0E,0xFF,0xF0,0xC7,0x08,0x35,0xF8,0xE3,0x41,0xA9,0x44,0x95,0x89, +0xC6,0x98,0xD4,0x94,0x33,0x1D,0xE3,0x4F,0x3F,0x1E,0x9B,0x5A,0x9C,0xF2,0xB1,0x3D, +0x28,0x68,0x5C,0x48,0x99,0x4A,0x43,0x21,0xE1,0x48,0x71,0xA7,0xC7,0xFE,0x3B,0xC5, +0xBD,0x26,0xDA,0x47,0x14,0x54,0x85,0xC6,0x40,0x75,0x41,0x4D,0x7A,0x67,0x30,0x37, +0xF3,0xAD,0xAF,0x31,0xEF,0x35,0x5C,0x2F,0xFF,0x60,0xCC,0x80,0xB6,0xCE,0x02,0x2F, +0x6D,0x74,0xAD,0x71,0x5D,0x99,0xAD,0xA6,0xA1,0xDF,0x93,0x0B,0xD3,0xDC,0x05,0x0B, +0x04,0x1F,0x47,0x91,0x99,0x1E,0x7E,0xEE,0xCF,0x1A,0xDD,0xD8,0x22,0xA4,0x38,0xEB, +0x02,0x32,0x9A,0x98,0xC5,0x09,0x5E,0xF8,0x4A,0xB1,0x29,0x56,0x6B,0x2D,0x8D,0x07, +0x7D,0xF2,0x37,0xFE,0x1D,0x0B,0x73,0x33,0x40,0x14,0x1D,0xE7,0x21,0x04,0x25,0xDA, +0x5A,0x38,0x58,0x04,0xF0,0xED,0xB5,0x8A,0x3C,0x26,0x98,0x52,0xE4,0xD3,0x9D,0x85, +0xDE,0x97,0xCF,0x20,0x5A,0xA9,0xFD,0xAD,0x1E,0x21,0x7F,0x43,0x18,0x9E,0xC2,0xD5, +0x80,0xD5,0x78,0x63,0x13,0x98,0x0C,0xF1,0x5D,0x2A,0x04,0x02,0x41,0x9A,0xF6,0x8D, +0xB3,0x64,0x74,0xFE,0x33,0x6D,0x48,0x28,0x2B,0x7B,0xC0,0x34,0x58,0x1F,0x86,0x52, +0x62,0x60,0x7C,0x13,0x66,0x60,0x47,0xEB,0xB9,0x0A,0x1B,0xF2,0xB5,0x08,0x70,0x49, +0xAF,0xA2,0x27,0xB8,0xC1,0x73,0x04,0x23,0xFB,0x97,0xD3,0xC3,0x1E,0xA1,0xF5,0x17, +0xC3,0xA0,0x1B,0x3C,0x8C,0xC2,0x3E,0xCE,0x40,0x96,0x11,0x33,0x9E,0x70,0x88,0xA0, +0xAF,0x10,0xE9,0x76,0x3B,0x78,0xCD,0x04,0xDD,0x5A,0x2D,0xF5,0x60,0x52,0x0F,0x3E, +0xA2,0x77,0x9B,0xB8,0xFA,0xC2,0xCE,0xED,0x3C,0x04,0x5D,0x06,0xAA,0xE0,0x3B,0x2F, +0x4F,0xB7,0xB5,0x20,0x2D,0xC5,0xA0,0x9C,0x8E,0x5D,0x0A,0x60,0x51,0x0E,0xD8,0x3F, +0x1F,0x59,0x7F,0xE4,0x97,0x8D,0xD7,0xEC,0x31,0xEA,0x0A,0x78,0x9E,0xC8,0x9A,0x44, +0x04,0x81,0x50,0x73,0xC0,0x51,0xBB,0x15,0x09,0x97,0xD7,0xCA,0x3B,0x76,0x68,0x5D, +0x2F,0xA1,0x41,0xC0,0x7C,0x20,0xD2,0x6B,0x91,0x3F,0x4E,0xB9,0x37,0x4A,0x7D,0xAB, +0xEB,0xF7,0x2B,0xFC,0xAF,0x7B,0xD8,0x3B,0xFD,0xFA,0x1B,0x4F,0xF7,0xEA,0x73,0x89, +0xE4,0x70,0xDC,0xD4,0x45,0xA3,0xAB,0xBB,0xEC,0x70,0xD3,0x3D,0xCA,0xBA,0x5C,0x31, +0x3B,0x2D,0x54,0x19,0x52,0x55,0x19,0x22,0xA5,0x43,0x5C,0xBB,0x11,0x61,0xCA,0x34, +0x3C,0xEE,0x5E,0xA3,0xD8,0x0F,0xBA,0x01,0xA1,0x77,0x62,0x85,0xBB,0x72,0x00,0x5B, +0x5B,0xD8,0xFA,0xE7,0x86,0xAF,0x93,0xF6,0x14,0x54,0xBC,0xE9,0x72,0x72,0xB9,0x4B, +0xF0,0xB8,0x99,0x18,0xE5,0xC8,0xA3,0x69,0x53,0x3B,0xE9,0x80,0x5E,0xD1,0xE5,0x24, +0xA6,0x4C,0x80,0x94,0x6A,0x73,0xE1,0x0A,0x48,0x51,0xE2,0xF7,0x0E,0xDB,0x1A,0xFD, +0x8D,0x0D,0x66,0xDE,0xB8,0x1D,0x5D,0x92,0xA4,0x51,0xD7,0xC4,0x0C,0xF0,0xA2,0xAD, +0x55,0x37,0xF2,0x26,0xAC,0xBF,0x85,0x59,0x77,0x93,0x95,0xC6,0x6D,0x80,0xD6,0x2E, +0x4B,0x0A,0x60,0x84,0x2B,0x58,0xDF,0xCE,0x5D,0x2D,0x95,0xA2,0x59,0x09,0xAE,0xE7, +0x07,0x03,0xC5,0xD4,0x81,0x38,0xD7,0xBC,0x7E,0xD3,0xDC,0x1B,0x6C,0x60,0x90,0xB3, +0x22,0x85,0xAE,0x24,0xC0,0xC9,0xB5,0x31,0x35,0x78,0xD5,0x56,0xDE,0x4A,0x13,0x48, +0xE5,0x27,0xB6,0x91,0x84,0xA8,0x8A,0x72,0x6C,0xEA,0x13,0xAB,0xE8,0xB3,0x5C,0x55, +0x7B,0x5D,0x98,0x24,0x36,0x66,0x0A,0x40,0xBE,0x14,0x81,0xD0,0x52,0xDF,0x6A,0xA5, +0xDF,0x2A,0x28,0xF1,0x91,0x1C,0xAA,0xB2,0xA2,0xC1,0xB2,0x54,0x97,0x2A,0x4E,0x92, +0x42,0xB9,0x69,0x68,0x16,0x13,0xAF,0x99,0x94,0x79,0x81,0x12,0xF9,0xC9,0xD8,0x80, +0x83,0xDC,0x41,0x08,0x9C,0x94,0x27,0xD8,0x05,0x78,0x87,0x81,0xE9,0xC9,0xBA,0xE6, +0xA4,0xF5,0x42,0x1B,0x7E,0x67,0x13,0x8E,0x3F,0xD4,0xB0,0xA1,0xA1,0xEA,0x29,0xD0, +0xDA,0x57,0x3E,0xF0,0x51,0xF1,0xFA,0xC6,0xF3,0x5C,0xF0,0x4E,0x09,0xD5,0xB8,0x6D, +0x55,0x59,0xAD,0x8D,0xEF,0xDC,0x0B,0x8A,0xF4,0x47,0x65,0x52,0x70,0x82,0xAF,0x96, +0x22,0x0A,0xC4,0xE3,0xB9,0x9F,0xAB,0xFD,0x38,0x6D,0x01,0x84,0xE1,0x25,0x9B,0x34, +0xA7,0x62,0x81,0xC4,0xCF,0x2E,0xB0,0x29,0x09,0x66,0x28,0x6A,0xA9,0x62,0xB6,0x33, +0x43,0x67,0x10,0x4D,0x88,0xFE,0xDD,0xB5,0x45,0xEA,0xF3,0xF2,0xF7,0x9D,0x0F,0x1D, +0x1C,0x4F,0x12,0xDC,0x89,0x16,0xA7,0x74,0x4F,0x99,0x5C,0x33,0x5B,0x3C,0xAA,0xCA, +0x2E,0x98,0xAB,0xA8,0x5D,0x22,0x08,0xB6,0x21,0xF9,0x92,0xF1,0xF5,0x49,0x22,0x69, +0x43,0xB9,0x27,0x85,0xF8,0x80,0x74,0xB9,0x41,0x7E,0x0E,0x40,0xA4,0x42,0x8E,0x58, +0xD3,0x3B,0xAB,0x01,0x09,0xEC,0xF9,0x32,0x56,0x9F,0x8B,0x50,0x31,0xAD,0x4E,0x2D, +0x52,0xDD,0x1C,0x1F,0xEE,0xF3,0x11,0xE3,0xBC,0x01,0x29,0x73,0xC7,0xE3,0xF5,0x4A, +0x30,0x59,0x7C,0x56,0xEC,0xD9,0x03,0x43,0x1F,0xCC,0x25,0x5C,0x5E,0x88,0xA0,0x97, +0x2C,0xE3,0xEF,0x87,0xE4,0x44,0x55,0x4E,0xAF,0x22,0xB2,0xE8,0x40,0x5D,0x2E,0x09, +0x38,0x93,0x83,0x39,0xED,0xBF,0xAE,0x40,0xA4,0x44,0x82,0x7E,0x52,0xBD,0xE0,0xB8, +0xAB,0xC2,0x20,0x97,0x87,0x12,0x8E,0xB4,0x19,0xF7,0xD3,0xDD,0xD7,0xC4,0xB5,0x0B, +0xDE,0x54,0x6B,0x23,0x6E,0x13,0xE3,0xCB,0x61,0x4F,0xAF,0xFE,0x4D,0x7D,0xA7,0x6A, +0x26,0xBA,0x97,0xB4,0xD2,0xFE,0x01,0x8B,0xD7,0xE9,0x54,0x9E,0x89,0x38,0x5B,0xB8, +0x7A,0xF2,0x05,0x64,0xF2,0x95,0xD5,0xF3,0x02,0x08,0x62,0x93,0x3F,0x3E,0x87,0xF7, +0x23,0x73,0x29,0xAE,0xB9,0x8D,0x31,0x6D,0x60,0xCD,0x97,0x49,0x12,0xC0,0xB7,0xD1, +0x44,0x00,0xB6,0x24,0xE8,0x0A,0x1C,0x89,0xD0,0xCC,0xB9,0xCD,0xAA,0xBD,0x96,0xDF, +0x0E,0xBD,0xDC,0xCA,0x71,0xD6,0xD4,0xE4,0xFC,0x98,0xE9,0x2D,0x81,0x2C,0x89,0x03, +0x5D,0x75,0xEB,0xA1,0x58,0xA5,0x00,0xD6,0x84,0xD8,0xFD,0xF8,0x68,0x29,0xE6,0x60, +0x99,0x9B,0x79,0x14,0xD3,0x6C,0x99,0x47,0x53,0x9E,0xCB,0x1A,0x04,0x50,0xD8,0x2B, +0x56,0x2A,0xB1,0xB0,0x04,0xDF,0xD8,0xA8,0xE9,0x67,0x60,0xBE,0x78,0x03,0x5C,0x08, +0x9F,0x6E,0x24,0xF3,0xD5,0x62,0x68,0x4E,0x3B,0x28,0xA6,0xA5,0x22,0x93,0xBC,0x51, +0x30,0x4D,0x5C,0xBA,0xD6,0x52,0xF3,0x77,0x1A,0xC3,0xE4,0x03,0xB7,0x0D,0xD2,0x85, +0xF8,0x0E,0x85,0x7B,0x60,0xBF,0x20,0x80,0x27,0x32,0x36,0x42,0xED,0xF0,0x1F,0xD4, +0x88,0xF0,0xDB,0x5C,0xF8,0xEF,0x8D,0x10,0xCD,0x61,0xD5,0x73,0x12,0xE5,0xC8,0x9C, +0x96,0xE7,0x65,0x5E,0xBF,0x1F,0xA1,0x0E,0xCE,0x9D,0x02,0x3A,0x35,0x78,0xDF,0x65, +0x89,0x5E,0x16,0x54,0xA6,0x1D,0x36,0x5A,0x5A,0xC5,0x53,0x3A,0x33,0xF4,0xC1,0xF7, +0xA9,0x37,0x48,0x46,0x69,0xA2,0x24,0xE0,0xCC,0xC3,0xED,0xFB,0xEB,0x55,0xA2,0xA1, +0xDE,0x3C,0x5A,0x2B,0x55,0x75,0xB1,0xF0,0x7B,0xC4,0x90,0x08,0x2A,0x14,0xB3,0x2D, +0xC0,0x0D,0xD6,0x91,0x4D,0x94,0x42,0x09,0x19,0x68,0xDA,0xA3,0x4C,0x4E,0xD9,0xD0, +0x0F,0xD6,0xF5,0xAB,0x5D,0x68,0xE5,0x7B,0x91,0xBD,0xD0,0xC3,0xD2,0x49,0x55,0x19, +0xED,0x8E,0x69,0xA9,0xE5,0x48,0x97,0x32,0x78,0x44,0xB0,0xD3,0xCA,0x05,0x38,0xDB, +0x04,0x52,0x29,0x32,0x95,0xC8,0x0E,0xB7,0xF9,0xA0,0x80,0xF4,0xCA,0x04,0xBE,0x29, +0xEC,0x23,0x07,0x05,0x2B,0x9B,0x76,0x79,0xB4,0xEF,0x40,0x44,0x3E,0x4B,0x4F,0x5F, +0x19,0x89,0x7E,0x36,0xB8,0xD4,0xC5,0xA4,0x09,0x6D,0x35,0xEF,0x93,0xDA,0x6C,0x96, +0x3C,0x2C,0x17,0x15,0xD8,0x4C,0x1D,0x3E,0xE9,0x64,0x11,0xD5,0x60,0xD3,0x16,0x2B, +0xBD,0xD3,0x41,0xE9,0xB3,0xE1,0xA1,0x56,0x65,0x75,0xB5,0x12,0x03,0xBC,0x8C,0x7B, +0xC4,0x27,0x2E,0x7B,0x1E,0x43,0x86,0x3E,0xA9,0x2A,0xEA,0xCC,0xBC,0x27,0x11,0x5D, +0x6A,0x25,0xB1,0xE2,0xBD,0x14,0x6B,0xAB,0x71,0x69,0x43,0xC4,0x94,0xC0,0xFF,0xD8, +0x39,0x8A,0xF0,0x19,0x21,0x81,0xAD,0x9C,0x3C,0xFB,0x76,0x83,0x3A,0x5F,0x91,0xBB, +0x20,0xD9,0x1C,0x67,0x7F,0x3B,0x55,0xE1,0xBF,0xED,0x85,0x93,0xD2,0x2D,0xF9,0xC3, +0x24,0x0D,0xA7,0xE9,0xB8,0x6C,0x63,0x5F,0x95,0x01,0xC5,0x75,0x15,0x90,0x27,0x41, +0x48,0xF3,0x45,0x29,0x5C,0x51,0x77,0xB2,0x08,0xF2,0x37,0xDB,0x95,0xD7,0xD4,0xFA, +0x7E,0x0A,0x7F,0xA1,0x40,0xC8,0x4D,0xBB,0xAF,0xD2,0x7A,0xD8,0x78,0x61,0x07,0xDE, +0xA8,0xFD,0x9A,0x9D,0xF3,0xCD,0xB9,0xF8,0x15,0x1E,0x92,0x20,0x01,0x88,0x75,0x1E, +0x08,0x13,0x71,0x34,0x34,0x65,0xA3,0xA5,0x5A,0xBD,0xB0,0x04,0xA7,0x5F,0x95,0xAF, +0x31,0x7C,0x5B,0x7B,0xFB,0xF3,0x77,0x38,0xA8,0xC3,0x56,0x5D,0x5D,0xF2,0x07,0x02, +0xDB,0x8F,0x33,0x51,0x6A,0xBD,0x76,0xDF,0x9D,0xD1,0x49,0xB8,0x71,0xCD,0xBE,0x37, +0xF9,0x88,0x00,0x40,0x9C,0xC1,0xFD,0x7B,0x0C,0xF2,0xCB,0x11,0x84,0x03,0x79,0x57, +0x7D,0x91,0xCC,0x8E,0x8E,0xC0,0x8E,0x6F,0x88,0x94,0x2D,0xDD,0xCD,0xDA,0x17,0x06, +0xF1,0xE2,0x6A,0xD0,0x9E,0xDA,0xFB,0xC9,0xF1,0x6D,0x74,0x43,0xD5,0xB8,0xA6,0x47, +0x1D,0x31,0xC4,0xD5,0x61,0xFB,0x89,0x8A,0x04,0xCE,0xD4,0xCF,0x0E,0x54,0x02,0x73, +0x90,0x98,0xF9,0x68,0xD8,0x82,0x2F,0x5E,0xB8,0x69,0x6D,0x6D,0x95,0x25,0x87,0x69, +0xB7,0x5D,0xCE,0x86,0xF9,0xBE,0x34,0x49,0x9D,0x2E,0xB6,0xE4,0x39,0x54,0x77,0x95, +0x8A,0x4B,0x57,0x31,0x1F,0xF6,0xDA,0x0C,0xE0,0xC6,0x7F,0x77,0x68,0xD8,0xD0,0x3B, +0x53,0xC4,0xFE,0x3D,0xAB,0xEB,0xC7,0x8B,0xC8,0x74,0xF2,0xC6,0xCD,0x85,0x43,0xC6, +0xC7,0x59,0xA0,0xBF,0x99,0xF0,0x63,0xA0,0xE6,0xD3,0x6A,0xE3,0x91,0x44,0xF0,0x39, +0xBD,0x94,0xBA,0x07,0xD5,0x59,0x50,0x8F,0xAC,0x4B,0x9A,0x66,0xDF,0x52,0x70,0xD2, +0x2C,0x36,0xE4,0xBF,0x4E,0x37,0xDB,0x2D,0x7F,0x19,0x9B,0x7F,0x1E,0x8F,0x43,0x0C, +0xC5,0x16,0x08,0x12,0x7E,0x67,0x20,0x64,0x79,0x6F,0x2C,0x43,0x7D,0x8D,0x9B,0x3D, +0xBC,0x63,0xD5,0x20,0xB5,0x5A,0x8A,0x9D,0x0E,0x34,0xC2,0x7B,0xED,0x81,0x74,0x32, +0xF9,0x32,0xF4,0x4F,0x2A,0x47,0xF6,0x25,0x02,0xB6,0x54,0xD0,0x06,0xF6,0xAB,0x0C, +0x7A,0xD4,0x38,0x8A,0x7C,0xCE,0xE3,0x55,0x7E,0x2B,0x2D,0x28,0xBD,0xCB,0x1A,0xAE, +0xC0,0x08,0xD8,0x17,0x0E,0xA9,0xCB,0xC3,0x2A,0xB9,0xEA,0xC2,0xF9,0xD3,0x8F,0xDD, +0x02,0xB2,0xC6,0xDC,0x5D,0x0B,0x7A,0x28,0x1E,0x9A,0x7E,0x9E,0x80,0xAA,0xC5,0x04, +0x78,0xE8,0xB3,0x69,0xA6,0x0A,0x53,0xDF,0x55,0x64,0xE8,0x57,0xFC,0x86,0x56,0x95, +0x6C,0x93,0xAE,0x24,0xE5,0x16,0xB8,0x57,0x06,0x90,0x93,0xD0,0x72,0x4D,0x92,0xA9, +0x38,0x47,0x6F,0x07,0x0F,0x3F,0xF5,0xFE,0x68,0x42,0x09,0x0C,0x84,0x3B,0x87,0x41, +0x08,0xFF,0x46,0x67,0x7B,0xD8,0xFE,0x48,0x20,0x05,0xF7,0xE8,0xF6,0xFD,0xB3,0x1E, +0x09,0xD3,0x94,0x2A,0xE6,0xBE,0x06,0xAF,0xCF,0x98,0x90,0x68,0x09,0xA4,0xBC,0x41, +0x09,0xCB,0xC5,0x9C,0x6F,0x07,0xF6,0xD8,0xC6,0xD5,0x03,0x5E,0x06,0x35,0x87,0xA1, +0x7F,0x9B,0x64,0x08,0x1D,0xB1,0x0B,0xBA,0x93,0xCF,0x23,0x5D,0xE6,0xF8,0x01,0x0B, +0xFC,0x13,0xC9,0x41,0x5B,0x63,0xBC,0x94,0x89,0xBD,0x25,0x78,0x13,0x31,0xC9,0x96, +0x93,0x51,0x8A,0x39,0x1B,0x2B,0xE7,0x33,0x68,0x94,0xC8,0x20,0x59,0x84,0x87,0x7F, +0xFF,0x28,0xF7,0x8D,0x96,0x89,0x9E,0xD6,0x51,0xD6,0x43,0x1B,0x5C,0xBD,0xB3,0x9B, +0x3E,0x14,0x4F,0x16,0xEC,0xFC,0x1F,0xF5,0x1E,0x53,0xA2,0xEF,0x91,0x46,0xED,0x86, +0xBC,0x09,0xE6,0x11,0x67,0x4E,0xF8,0x88,0xC0,0x9A,0x50,0xEE,0xF0,0x98,0x46,0xEF, +0x34,0x8A,0x81,0x91,0xDC,0x51,0x42,0xEF,0x20,0xA0,0x81,0x45,0x62,0xC9,0x0A,0x9B, +0x2D,0x2B,0x80,0xF1,0x65,0x9E,0x62,0x48,0x33,0x99,0x04,0x1D,0x1A,0xB8,0xF5,0x32, +0x1C,0xE4,0x37,0xD3,0x1D,0xF1,0x33,0x25,0x1E,0x47,0x8E,0xC3,0x2F,0xB5,0x15,0xD8, +0x72,0x23,0xD2,0xEB,0x53,0xC8,0x62,0xF6,0x0A,0x00,0x98,0xCE,0x71,0xD7,0x0C,0xFD, +0xEC,0x6E,0x30,0x9C,0xE9,0xBE,0x9F,0xB8,0xED,0x4C,0xFD,0xF9,0xE9,0xAA,0x7B,0x5D, +0xF5,0x3B,0xE9,0xA8,0x1E,0x47,0xBD,0x09,0xF0,0xE2,0xD6,0x10,0x53,0x91,0x8E,0x7E, +0x68,0x31,0x7B,0x80,0x16,0x1D,0xEE,0xDB,0xB8,0x88,0xE1,0xBF,0x9D,0x74,0x39,0xA8, +0x38,0xD2,0xDD,0x70,0xDF,0x1A,0x76,0xE8,0x81,0x5E,0x83,0xFB,0xF0,0x17,0xBE,0x58, +0xD0,0xC4,0xA2,0x04,0x02,0x7B,0xC1,0xB3,0x67,0x6F,0x78,0x78,0x1C,0x9F,0xFC,0x74, +0x56,0xAA,0x75,0xA7,0xB3,0xB1,0x7A,0x35,0x70,0x10,0x8A,0x28,0x6D,0xCE,0xE0,0x92, +0x02,0xA0,0x9D,0x5A,0x9C,0xB2,0x59,0x96,0x34,0x70,0x2F,0x8B,0x85,0x77,0x8B,0x7A, +0x65,0x35,0x0B,0xEC,0x66,0x3F,0x00,0x2C,0x54,0x44,0x9A,0xE2,0x59,0x41,0x4A,0x03, +0xE8,0xFE,0xD0,0x0E,0x9D,0xD0,0xF6,0x4E,0xC3,0x9D,0xA7,0x66,0x56,0x66,0x84,0x61, +0x10,0x2B,0x1F,0xB8,0xB8,0x6C,0x5A,0x2F,0x54,0xE7,0x0A,0x50,0x00,0xD1,0x36,0x28, +0xCD,0xE2,0xDE,0xC8,0x7F,0xB0,0xF1,0x01,0xA3,0x76,0xDA,0x96,0xA4,0x91,0x01,0x77, +0xCF,0xDC,0x16,0x9E,0x4A,0x62,0x6C,0x06,0x4F,0xBB,0x97,0xFD,0x3C,0xFC,0x10,0x2B, +0x33,0x25,0xE1,0xA1,0xC9,0xC0,0xD2,0x27,0x09,0xDA,0xF8,0x79,0x62,0x4F,0xBB,0xA5, +0xD8,0x6C,0x6A,0xC2,0xFA,0xA2,0x6E,0xF9,0xC9,0x3C,0x86,0xFE,0x53,0x15,0xAB,0xA3, +0x76,0x64,0x16,0x75,0xB3,0x12,0x5A,0xE7,0x96,0x95,0x7E,0xEE,0xCD,0x7E,0x94,0x78, +0x88,0x5B,0x88,0x38,0x6B,0x71,0xFE,0xCE,0x87,0x4D,0x98,0xBA,0x1F,0x4D,0xC3,0xB8, +0xFC,0xAD,0x25,0xCB,0x3F,0x15,0xDC,0xC0,0xCE,0x13,0x68,0xEB,0x51,0xF0,0x5F,0xDE, +0xF6,0x62,0xA8,0xC7,0x93,0x1A,0x56,0x2E,0xB9,0xF7,0xCC,0x05,0x13,0x96,0x62,0xB1, +0x78,0x19,0x6B,0x6E,0x22,0x44,0x2E,0xFC,0xFF,0x6F,0x29,0xBF,0xED,0xB2,0xDC,0x21, +0x4D,0xF4,0x13,0x86,0x3C,0x81,0x4B,0xC9,0xF1,0x1F,0x3C,0xAA,0x20,0x4E,0x53,0x9C, +0xF2,0x84,0x2D,0x18,0x7A,0xE7,0x15,0xC9,0x4D,0x0A,0xF4,0x10,0xF4,0xCC,0xD2,0x33, +0x79,0xE4,0x64,0x27,0xDC,0x63,0x4F,0xE2,0x9A,0xDA,0x59,0x39,0x2E,0x29,0x47,0xA3, +0x82,0xCD,0x0B,0xA2,0x73,0x0D,0x9B,0x27,0x3D,0xD7,0x20,0x38,0x34,0xB2,0x54,0x78, +0x59,0x38,0x07,0xAD,0xBC,0x40,0x31,0xBF,0xFD,0x5B,0x9F,0x2A,0x58,0xEA,0x06,0xF8, +0xE2,0x9B,0x51,0xA5,0x85,0x50,0x07,0x34,0x1B,0x38,0x26,0x4A,0x01,0x9D,0x74,0xF3, +0x32,0x07,0x21,0xC3,0x6B,0x5E,0xF6,0xAD,0x3D,0x5B,0xEB,0x54,0xC1,0x69,0xFB,0x79, +0x72,0xB9,0x43,0xF0,0xCD,0xB4,0x96,0xF6,0xC0,0xE9,0x3B,0x92,0x03,0x80,0x7F,0x4C, +0x03,0x1E,0xCE,0x6D,0x4A,0x06,0xB8,0xD5,0xEA,0xA6,0x77,0xB3,0xF3,0xF6,0x62,0x68, +0xE1,0xED,0x5B,0xC4,0x6C,0xFF,0x47,0xBB,0x1D,0xD4,0xFA,0x08,0xAD,0xBC,0x16,0xB7, +0xED,0x51,0xC1,0xC3,0x6C,0x7B,0x8D,0xA5,0x34,0x48,0x63,0x79,0x24,0xBF,0x35,0x71, +0xBF,0xF6,0xAF,0x52,0x27,0xC2,0x96,0xE9,0x88,0xA4,0x40,0x3A,0xC8,0xA0,0x2B,0xE5, +0x91,0x6D,0xA5,0xE3,0x8E,0x40,0xD3,0x60,0x6A,0x12,0x9B,0x12,0xEF,0x49,0xA5,0x5C, +0xB5,0x7C,0x19,0xA0,0x1E,0x7D,0xC8,0x7A,0x9F,0xF6,0xBF,0x46,0x80,0x66,0xD6,0x59, +0x10,0xE2,0x3E,0xFB,0xDE,0x6C,0x02,0x4B,0xCB,0x91,0xBF,0x95,0xC8,0x71,0xB5,0xE8, +0xF8,0xA0,0x65,0x8B,0xF6,0x35,0xA1,0xA0,0x54,0x84,0x7A,0x76,0xE2,0x68,0xCE,0x26, +0x91,0x09,0x51,0xF1,0xB7,0x1F,0x98,0x8E,0x87,0x6C,0xA7,0x41,0x13,0xF6,0x69,0x44, +0x7B,0x54,0x50,0x7C,0xBA,0x7B,0xDC,0xD9,0xA7,0x63,0x82,0x5B,0xB9,0x8A,0x88,0x64, +0x47,0x4C,0x1C,0x8B,0x42,0xA7,0xCF,0x9F,0xC2,0x66,0x39,0x8E,0xCD,0xEA,0xE0,0x1C, +0xB4,0x62,0xE3,0x66,0x5E,0x72,0x7A,0x43,0x26,0x06,0xB5,0xDE,0x4A,0xD5,0x40,0x1D, +0xAD,0x89,0x37,0x11,0x25,0x20,0x49,0x32,0x24,0x60,0x66,0xFB,0xFC,0xAC,0xCA,0x43, +0x02,0xA2,0x9E,0x12,0x16,0x00,0x9F,0xD2,0x4E,0x84,0xA4,0xF9,0xE0,0xD5,0x78,0xA3, +0x0B,0x63,0xBB,0xD2,0xA7,0x6A,0xC8,0x34,0xE3,0x28,0x49,0xA1,0xA8,0xE4,0xF4,0x5B, +0x52,0x5F,0x78,0x0F,0x50,0xB4,0x84,0x6B,0x4D,0x45,0xC0,0x10,0xB5,0xF5,0xB4,0x07, +0x54,0x1B,0x6E,0x05,0x8C,0x88,0xE5,0x83,0x35,0x07,0x01,0x60,0x88,0x74,0x40,0xC5, +0x30,0x09,0x46,0xBA,0x4A,0xD9,0xB9,0xB4,0x8D,0x9C,0x16,0x87,0x33,0x0D,0x89,0xF3, +0xFE,0x60,0x7B,0xF9,0x88,0x43,0xEB,0x2A,0x9B,0x7F,0x08,0xEE,0x9B,0xF7,0xA1,0x44, +0xF3,0xED,0xB7,0xFE,0x93,0x00,0x34,0x67,0x41,0xF2,0x2D,0xC0,0x7A,0x43,0x5A,0x36, +0x5F,0x1B,0x37,0xFF,0xBD,0x4F,0x11,0xF3,0x33,0x31,0x1D,0xD9,0x13,0x82,0x83,0xDD, +0x0E,0x3A,0xAC,0xA1,0x48,0x28,0xC3,0xF4,0x31,0x9D,0xBE,0x9F,0xF4,0x43,0x68,0x01, +0xCA,0x00,0xF7,0x0C,0x3F,0xC3,0xCF,0x7E,0x87,0x76,0x37,0xAE,0x9F,0x22,0xA6,0x78, +0x0B,0xAB,0xD3,0xF5,0xA5,0xC5,0xDC,0x27,0x95,0xD3,0x98,0x75,0x48,0x06,0x62,0xFB, +0x73,0x72,0x81,0x6E,0xAF,0x73,0x63,0x86,0xFD,0xE3,0x4C,0x6F,0x4D,0xC7,0x82,0x19, +0xB8,0x75,0xED,0xF2,0xDC,0xF3,0xF4,0x40,0x4F,0x01,0xCF,0x9A,0x55,0x00,0x2A,0xEE, +0xA9,0x04,0xDA,0xF1,0xBB,0x94,0x3C,0xB1,0xB1,0x30,0x84,0xAB,0x6A,0x22,0xD1,0x05, +0xCC,0x7A,0xFB,0x7B,0x52,0xC5,0xB2,0xD6,0x49,0xD9,0xFD,0x77,0x09,0x4F,0xFA,0xD0, +0xFF,0xE3,0x7D,0x4F,0xBA,0x7B,0x01,0x98,0x1E,0x33,0x12,0x43,0x54,0x5D,0x3E,0x8F, +0x43,0x46,0x8B,0x5E,0x10,0x4D,0x39,0x09,0x83,0x2B,0xE3,0xA9,0xB3,0xDE,0xF4,0xFD, +0xAB,0x8B,0xDA,0x6C,0xF0,0x5C,0x2E,0xCB,0xBE,0xFD,0xBC,0xFE,0xFD,0xF7,0x6E,0x57, +0xBC,0x52,0xDD,0x00,0xCF,0xFC,0x6E,0x80,0xD8,0xE8,0x35,0x72,0xF6,0x0D,0x1F,0x39, +0xED,0x39,0x20,0x3A,0xA9,0x82,0xB9,0xDB,0xD3,0x8B,0x83,0xF9,0xBF,0xF6,0x44,0xCE, +0x5F,0x73,0xCF,0x2A,0x29,0x82,0x6A,0x69,0x80,0x01,0xBD,0xEE,0x76,0x54,0x8A,0xC4, +0x6C,0x7B,0x8C,0x5E,0x2D,0xE1,0xE1,0x9B,0x4D,0x2C,0x17,0xDC,0x5F,0x09,0x0B,0x6B, +0xD1,0xE8,0x5C,0x33,0x50,0x3A,0xBA,0xF2,0x98,0x5D,0xED,0xA3,0x3D,0x04,0x3E,0x7C, +0x0D,0x39,0xF6,0x20,0x2D,0xC3,0x92,0xF4,0x28,0x7A,0x3F,0xE8,0xA6,0x7E,0x73,0x95, +0x4A,0xAE,0x91,0xD0,0x0E,0x70,0x1C,0x4B,0x54,0xEB,0x3F,0x91,0x53,0x25,0x05,0x71, +0x3F,0x30,0xFF,0xA0,0x4E,0xCE,0x80,0x3F,0x24,0x06,0x48,0x9E,0x97,0xCB,0x56,0x45, +0x04,0x9D,0x9E,0x17,0x6C,0xF2,0x3D,0x11,0x0D,0x61,0xD6,0x68,0xBB,0xA7,0x1B,0x9B, +0x5A,0x03,0x73,0xC0,0x8A,0x95,0xD5,0x34,0x37,0x4A,0xA6,0x0D,0xF2,0x81,0x39,0xFC, +0x2C,0x05,0x6C,0x7A,0x4A,0xFF,0xE0,0xB0,0xDE,0x5F,0xB9,0x11,0xD0,0x21,0xA2,0x7D, +0x07,0x61,0x88,0xDA,0x80,0x2F,0xC5,0xDE,0x2E,0x26,0x9D,0x53,0x72,0xED,0x48,0x1A, +0x2B,0xBB,0xD3,0x80,0x60,0x86,0xDC,0x0C,0xAD,0x03,0xA6,0x6A,0xD2,0x9A,0xF5,0x97, +0x82,0x2E,0x9A,0xA2,0xC5,0xB3,0x3C,0xE2,0x26,0x7F,0x04,0xB7,0xC4,0xBE,0x48,0xDD, +0xEF,0x58,0xAE,0xA9,0x8D,0xB0,0x94,0xD3,0x34,0x63,0x4B,0x5B,0x1C,0xB7,0xA8,0x71, +0x01,0x61,0x53,0x94,0xE4,0x72,0x02,0x03,0xD4,0xFC,0xE1,0xD4,0x74,0xEE,0x9C,0x8D, +0x0A,0x6E,0x7B,0xBA,0x5D,0xA4,0x5F,0x90,0x2B,0x39,0xC4,0x02,0x58,0xE1,0x05,0xA8, +0x68,0x62,0x1D,0xBD,0x9C,0x86,0x79,0x04,0xD4,0xBF,0x31,0x94,0x70,0x82,0x29,0x02, +0x61,0x3A,0x6C,0x20,0x60,0x0B,0xB5,0x7F,0x7D,0x0C,0x1D,0xCF,0xE5,0x3E,0x93,0xD4, +0x80,0xA9,0xFB,0x4B,0x45,0x25,0xD2,0x6B,0x86,0x14,0xC8,0x48,0x47,0xE6,0x29,0xA4, +0x68,0xCA,0x4C,0x2F,0xBA,0x12,0x38,0xBD,0x83,0x2D,0x81,0xC3,0x8E,0x88,0x90,0x7B, +0x36,0xB9,0x3A,0x25,0x79,0xC3,0x15,0xB3,0x4F,0x85,0x9A,0x83,0x57,0xBB,0xDC,0xA2, +0x2A,0x75,0x5B,0x65,0x47,0x1D,0x83,0xBA,0x62,0x2A,0xD4,0x37,0x19,0x9D,0x37,0x06, +0x9C,0x49,0x72,0x8A,0xDC,0xD5,0xF6,0xBA,0x54,0x33,0xE1,0xA4,0x3C,0x9A,0x0D,0xC4, +0x04,0x18,0xB8,0xE7,0x4E,0x7E,0xBF,0x82,0x16,0xFF,0x01,0xFF,0x60,0xB0,0x1F,0x66, +0x0F,0x78,0x61,0x48,0xD7,0x8D,0xD9,0xDF,0x97,0x9A,0x2C,0x18,0xA8,0x03,0xF9,0xC0, +0xDD,0x1B,0x75,0x70,0xD4,0xD8,0x74,0xF7,0x37,0x6D,0x29,0x6D,0x61,0x72,0xC3,0xC8, +0x06,0x92,0x37,0x66,0xFB,0xC0,0x2F,0xB9,0x2B,0xFA,0x89,0x93,0x86,0xBE,0x03,0x11, +0x24,0x6D,0x24,0xDD,0x4F,0xA1,0xBA,0x89,0xC6,0x1A,0x39,0x29,0x8C,0xCB,0xF4,0x16, +0x3E,0xE2,0x96,0x4D,0x3F,0x6C,0x3C,0x60,0x94,0x1B,0x58,0xDF,0xBB,0x0F,0xC4,0x12, +0x1D,0xB4,0x80,0xCB,0x43,0x03,0xB5,0x2B,0x80,0x97,0x6A,0x12,0x01,0x2A,0x7F,0xEE, +0x4E,0xD0,0x7F,0x30,0xEF,0x01,0x6C,0x94,0x8A,0x3C,0x45,0xC1,0x9A,0x8D,0x3A,0x6D, +0xEE,0x71,0x00,0x44,0x80,0x70,0x5E,0x85,0xFD,0x0E,0x90,0x22,0x8B,0xCD,0x3B,0xBC, +0x11,0xFE,0x4C,0x3F,0x53,0x82,0xB3,0x5D,0x86,0x9B,0x62,0x69,0x1B,0xE3,0x1D,0xBC, +0xA8,0xB8,0xEF,0x00,0xB2,0xE5,0x37,0x34,0x33,0xEA,0xE4,0x96,0xF0,0x07,0x36,0x92, +0x35,0x23,0x76,0xC9,0x07,0xD6,0xEB,0x1D,0xA8,0x40,0x27,0xEE,0x2E,0x30,0x43,0x6E, +0x39,0x55,0xF0,0x3F,0x17,0x2E,0xF9,0xFD,0xAC,0x69,0x2D,0xDC,0x88,0x8D,0xB0,0x4C, +0x49,0x1C,0xEE,0x16,0xD2,0xD6,0x28,0x44,0x05,0xE2,0x07,0x20,0x3F,0x45,0x96,0x18, +0xF1,0xD3,0xE2,0x9D,0x34,0xC1,0x2C,0xF0,0x71,0xF0,0xA3,0x79,0xD7,0x47,0xC5,0x27, +0x46,0xE1,0x2B,0xB7,0xB2,0x58,0xF0,0xE5,0x2F,0x20,0x0A,0xFA,0x83,0x6D,0xC2,0x52, +0xBE,0x03,0x34,0xB2,0xBE,0xE6,0x46,0x22,0x63,0xA3,0x48,0x99,0x02,0x8F,0x50,0x23, +0x66,0x5D,0xAE,0x95,0x55,0x83,0x43,0x2F,0x9F,0x67,0xB8,0xFC,0x18,0xCE,0x16,0x47, +0xC3,0x9D,0x8C,0xE9,0x33,0x6E,0x5D,0xD6,0xBB,0x2C,0x8F,0xE1,0x85,0xE6,0xB1,0xB5, +0x98,0xB1,0xA1,0x76,0x7C,0xDE,0x22,0xEA,0xFA,0x4A,0x2E,0x62,0xA7,0xCE,0xFF,0xFB, +0xE4,0x43,0xB2,0xF0,0x56,0x6D,0x3F,0x9D,0x84,0x24,0xC5,0x80,0x5F,0x84,0xAE,0x3A, +0xE4,0x0D,0xB7,0xDF,0x93,0x12,0x9D,0x82,0xDB,0xB4,0xA1,0x8B,0x9B,0x97,0x28,0x19, +0x69,0xE1,0x70,0x58,0x49,0x34,0xBD,0x14,0xB2,0x97,0x54,0x39,0xDB,0x39,0x20,0x0F, +0x10,0xF5,0xD5,0x02,0x05,0xB1,0x0F,0x52,0xEE,0x38,0xE3,0x56,0xFF,0x86,0xEB,0xDA, +0x7C,0x50,0x25,0x48,0x32,0x58,0xB5,0x43,0x7D,0x5E,0x0E,0x01,0x85,0x45,0x92,0x71, +0xDA,0x94,0x78,0x82,0x61,0x90,0x83,0x30,0x5A,0xE5,0xCF,0xCF,0x8E,0x8F,0xAE,0x42, +0x51,0xBB,0xF2,0xC9,0xD7,0xCA,0x84,0xBE,0x80,0x90,0xD2,0xC0,0xBA,0xA2,0xC1,0xA3, +0x71,0x75,0x69,0xB5,0xBD,0x14,0x9C,0x21,0x6C,0x64,0x1A,0x20,0xE8,0xB6,0x09,0x54, +0xA7,0xFE,0xBC,0xFC,0xA3,0xB0,0x25,0xDD,0x2F,0xD2,0x31,0xD7,0x74,0x38,0x64,0x78, +0xB5,0x69,0x24,0xE8,0x27,0x0B,0xBA,0x98,0xA1,0x3C,0x75,0x87,0xE8,0xD4,0x59,0x9A, +0x7D,0x83,0xCA,0x2B,0xAF,0x4C,0xBE,0x59,0x97,0xF0,0x6D,0xC9,0xCD,0x05,0x21,0xC3, +0x5F,0x7F,0x13,0xAE,0x33,0xDC,0x54,0xAE,0xC9,0x9C,0x89,0x3E,0x6F,0xDF,0x4C,0x89, +0xFA,0x55,0x33,0xC6,0x7C,0x79,0x28,0x4E,0x4C,0x43,0x49,0x31,0x73,0xE7,0x85,0x69, +0x67,0x99,0x76,0x7B,0x1A,0x97,0x68,0x15,0x57,0xFA,0x71,0xD9,0x92,0xCA,0x2C,0x85, +0xE4,0x3A,0xF4,0xFD,0x01,0x1A,0xB3,0x89,0x01,0x06,0x8B,0xB5,0xB4,0xF0,0xB5,0x93, +0xF0,0x65,0x01,0xDF,0x2B,0x7D,0x50,0x09,0x21,0xD9,0x8E,0xF8,0xCB,0xA6,0x82,0x5D, +0xF6,0xAA,0x7B,0x89,0xD5,0x3D,0xB6,0x94,0x65,0x22,0x2D,0xA5,0xA8,0x8D,0x4D,0x2A, +0xEE,0x44,0xA8,0x14,0x0A,0x3D,0x85,0xAE,0xAE,0x96,0xBA,0x88,0x90,0xBE,0xFD,0x60, +0xF3,0x61,0x01,0x4A,0xEF,0xF3,0x5A,0xA0,0xCC,0x87,0x33,0x8E,0x04,0x1B,0xC4,0x3C, +0xEF,0xC6,0x8B,0x2F,0xA4,0x15,0x71,0xC3,0x6F,0xEC,0x65,0x32,0x7E,0x8E,0xF0,0xA8, +0xC0,0x0A,0x5B,0xF5,0x35,0x90,0x33,0x31,0x89,0xFE,0xBA,0xA4,0x98,0x33,0x05,0xE8, +0x37,0xE9,0x3E,0xCB,0x8A,0x3E,0x27,0x3A,0x9A,0x13,0x6C,0x86,0x65,0x08,0x81,0x30, +0x63,0xE8,0xD4,0xA9,0x5E,0x33,0xD5,0xBA,0xC5,0x96,0x52,0x0A,0x8F,0x59,0x35,0x48, +0xFF,0x31,0x59,0x95,0x6C,0xB7,0x3B,0x1B,0x05,0x46,0x3B,0x18,0x72,0xAF,0xD0,0x7F, +0x53,0x16,0x28,0x4E,0xF4,0x79,0x0D,0x60,0x21,0x7E,0x2C,0x71,0x6A,0xEC,0x63,0xE2, +0xC0,0x6E,0xB2,0x4E,0x2C,0x80,0x19,0x74,0x2E,0xF1,0x99,0xE2,0x97,0x54,0xBB,0xD8, +0xAE,0x7D,0x72,0xF9,0x05,0x7A,0x78,0xC1,0x85,0x35,0xE6,0x12,0xA7,0x6F,0xDF,0x03, +0xCA,0x5B,0xC9,0xD4,0xCB,0x48,0xAA,0x34,0xCF,0xE3,0xE7,0x18,0x55,0x28,0x0F,0x95, +0x8E,0x05,0xFB,0x7B,0x14,0x98,0xEE,0x9D,0x9F,0xD5,0xA0,0x3A,0x2E,0x20,0xEC,0xB2, +0x12,0x88,0x57,0x72,0x62,0xE8,0x24,0x1B,0xD9,0x1F,0x7A,0x29,0xE9,0x77,0xFB,0xC5, +0x30,0x39,0xC2,0x93,0xE6,0xA4,0x38,0xAB,0xA9,0xAA,0x16,0x10,0x0A,0x2C,0x9F,0x24, +0x92,0xA9,0xBD,0xF1,0x5B,0xD4,0xED,0x0F,0x00,0x62,0xF5,0xBC,0x65,0xE5,0xB2,0xA8, +0x3C,0x0F,0xD1,0x6A,0x93,0x3A,0xD9,0x35,0xA1,0x98,0x64,0x14,0xB7,0x62,0xC2,0xC4, +0x5E,0xDD,0x58,0x1B,0x1C,0xC1,0xB4,0x07,0xD0,0xC0,0xA2,0x8B,0xED,0x4D,0x14,0x99, +0x20,0x49,0x08,0x13,0x4E,0x37,0xFD,0x88,0x7F,0x85,0x62,0xB6,0xB0,0xCC,0x80,0x0E, +0xA2,0xCD,0x06,0xF7,0x92,0x50,0x68,0xE3,0x2A,0xA7,0x39,0xAD,0x65,0xC4,0x59,0xAF, +0xBC,0x84,0xC0,0x9E,0x9B,0xCE,0x94,0xC2,0x88,0xDF,0x8E,0xA0,0x8A,0xE2,0x7B,0xE7, +0x8A,0x5C,0x2A,0x92,0x3B,0xA8,0xA9,0x96,0xC4,0x18,0x39,0xC0,0x72,0x99,0x9C,0x74, +0x51,0xD9,0xD9,0x04,0x91,0x49,0xE3,0x94,0xD4,0x63,0xB7,0xDF,0x6B,0x43,0xB0,0x40, +0x0D,0xB7,0x44,0x67,0x73,0x76,0x86,0x59,0x82,0x36,0x87,0x57,0xFA,0x7B,0xC2,0x22, +0xDD,0x7F,0x1F,0xDC,0x39,0xA8,0x39,0x74,0x83,0x13,0x6C,0xB5,0xF7,0x71,0x60,0xA7, +0x59,0x61,0x20,0x95,0x52,0xA2,0x6E,0x06,0x41,0x07,0x56,0x18,0x09,0xCD,0xC6,0xB5, +0x51,0xF4,0x39,0x8F,0x7F,0x7E,0xB5,0xEC,0x98,0x36,0x9C,0xAF,0xA4,0x53,0x5B,0x8B, +0xCE,0x2F,0xDC,0xE4,0xA6,0xBB,0x21,0x30,0x00,0x9F,0x28,0x17,0x9E,0x2B,0x8B,0x47, +0xDC,0xB3,0x2A,0xD8,0xD6,0xCD,0xCF,0xD5,0xCF,0x35,0x45,0x9F,0x03,0x9A,0x38,0xDB, +0x8B,0x71,0xCD,0xD0,0x63,0xAA,0x2D,0x78,0x26,0x28,0xA3,0x84,0x84,0x42,0xA8,0xD5, +0xC8,0x57,0xB6,0xA6,0x09,0x59,0x34,0x09,0x54,0xCF,0x76,0xA3,0xF2,0x76,0x28,0x5B, +0x97,0x80,0xFD,0x32,0x15,0xE7,0xA9,0x13,0x4C,0x0A,0x00,0xC9,0x85,0xA1,0x22,0x95, +0xB1,0x8D,0xA7,0xFC,0xD4,0x93,0x3C,0x15,0x67,0x75,0x56,0x95,0xCA,0x7C,0xA4,0xE3, +0x45,0x61,0x66,0x72,0x78,0xD4,0x2A,0xDE,0xFE,0x86,0x16,0xC6,0xD3,0x85,0x8C,0x64, +0x58,0x73,0x09,0x42,0x14,0xE1,0x78,0x3A,0xD8,0x82,0x15,0x52,0x80,0x0F,0x69,0x73, +0x47,0x56,0xB8,0xD5,0xFA,0x58,0x05,0x39,0x83,0x48,0x37,0x5E,0xE0,0x58,0x4A,0x14, +0x49,0x66,0xF6,0xF2,0x18,0xE2,0xEE,0x54,0x29,0x41,0x95,0x07,0x55,0x61,0x6A,0x0D, +0x6E,0x79,0xD5,0xD0,0x24,0x6B,0x9C,0xB0,0x43,0x5A,0x0F,0x02,0x36,0xF1,0x00,0xEB, +0x38,0xE0,0x81,0xBE,0x71,0x8D,0xE6,0xD6,0xD7,0xDB,0x54,0xDA,0xA4,0x5B,0xE3,0x35, +0xB1,0xAE,0xBA,0x7B,0x31,0x02,0x9D,0x67,0xD1,0x99,0x04,0xC0,0x72,0xEA,0x68,0x27, +0x79,0xD8,0x67,0x83,0xDE,0x2F,0x94,0xC9,0x58,0x3A,0xA5,0xED,0x58,0xE6,0x04,0x74, +0xF1,0xFB,0x54,0x5A,0xCB,0xE9,0xAC,0x1B,0x91,0xF0,0xA6,0x2E,0xFA,0xA7,0xD5,0x8E, +0xD2,0x77,0xB6,0x9A,0xFF,0x53,0x8B,0xD2,0x80,0xC9,0x3C,0xAA,0x0E,0x61,0x47,0xCA, +0x5B,0xC2,0x83,0xCF,0xBB,0x1D,0xE7,0xC6,0x36,0x27,0x2B,0xFF,0xB8,0x32,0xDD,0x8C, +0xAC,0xEA,0xA8,0xF7,0xF9,0xE8,0x64,0xAE,0xAD,0x9A,0x9B,0xC5,0xE2,0x7C,0x98,0xB9, +0x8C,0x64,0x3F,0x39,0x58,0x3D,0x3D,0x83,0xE5,0x8D,0x48,0xC1,0xA8,0x0E,0xF3,0xBB, +0x92,0x83,0xC4,0xE2,0xBE,0xE8,0x7F,0xA4,0xC0,0x8D,0x1A,0x3B,0xE2,0xE0,0x19,0x16, +0xD5,0x6E,0xE2,0x6F,0x25,0x5D,0x4E,0x69,0x83,0x16,0x56,0x14,0x39,0x23,0x87,0x7B, +0xED,0x2E,0x92,0x90,0x1F,0x00,0xA2,0xB9,0x77,0x4D,0x00,0xA0,0x39,0x13,0x76,0x47, +0xED,0x1F,0x58,0x88,0x5A,0xAF,0xA1,0x9C,0x64,0xDD,0xA2,0xBC,0x23,0xF4,0xEE,0xB6, +0x0E,0xB6,0xA6,0x5D,0x5C,0x10,0x06,0x90,0x59,0x19,0x0B,0x58,0x1E,0x65,0x60,0x37, +0x48,0x15,0x68,0x58,0x8D,0xCC,0x93,0x72,0x1E,0x29,0xC6,0x9B,0x2D,0xB2,0xAE,0xF1, +0x75,0x23,0x41,0x41,0xD4,0x75,0x5A,0x74,0xC5,0xAA,0x28,0x92,0x4D,0xA2,0x9B,0x0B, +0xFC,0x51,0x6A,0x7A,0xA0,0xDC,0x3A,0xC6,0x32,0x3D,0x6A,0x55,0xB9,0xE0,0x48,0x97, +0x1E,0xC8,0xA7,0xA6,0x97,0x1C,0x9F,0x38,0x64,0x13,0xFC,0x5E,0xA0,0x9F,0x92,0xCA, +0xEC,0x89,0x72,0xFE,0xC6,0xAB,0x8B,0xFB,0x06,0x49,0xBC,0x2C,0xFD,0xEC,0x11,0x9B, +0x5A,0x84,0x6D,0xB3,0x90,0xA7,0x03,0x29,0x2F,0xB5,0x4F,0xE1,0xDC,0x08,0x28,0x66, +0x73,0x34,0xF4,0x80,0x8F,0xA2,0xC6,0x70,0x67,0xC0,0x94,0x44,0xDE,0x9A,0xFF,0x50, +0xD7,0x47,0x9E,0xB8,0xDC,0x47,0xA4,0x79,0xA4,0x59,0x54,0x87,0x92,0x72,0x0A,0x44, +0x9D,0x39,0x7C,0x48,0x74,0x1C,0x59,0x8C,0x77,0x9E,0x73,0x1D,0x17,0xCC,0x05,0xF8, +0xA4,0x1D,0x97,0xC2,0x66,0xD9,0xD9,0x57,0xBD,0x55,0x93,0x1F,0xE2,0xBA,0x82,0x4A, +0xD4,0xE6,0x79,0x3B,0x00,0xED,0x3E,0x8D,0xAF,0x4E,0x70,0x65,0x8D,0xE4,0x65,0xF6, +0x35,0x4B,0xAF,0x2E,0xBA,0xF9,0x14,0x43,0xF1,0x3C,0x23,0x9D,0x9D,0x49,0x05,0x8E, +0xF6,0x3A,0x07,0x17,0xFA,0xE0,0xCC,0x28,0x01,0xAE,0x0A,0xB6,0x90,0x19,0x48,0x82, +0x07,0xC2,0x40,0x03,0x58,0xE9,0xB7,0x93,0xC5,0x75,0x7A,0xA0,0x0C,0x17,0x07,0x11, +0x2F,0xCB,0xEC,0xE1,0x5E,0x4A,0xAB,0xDA,0xF4,0xCA,0x69,0xFF,0x31,0xF8,0x96,0x7E, +0x90,0xA3,0x45,0x79,0x58,0x23,0xD3,0x65,0xBF,0x9B,0xFE,0x45,0xD9,0x43,0x9E,0x1F, +0x34,0xF4,0xB5,0x7E,0xC4,0xBB,0x04,0x7D,0xA0,0x39,0x98,0x3F,0xDC,0x38,0xF7,0x61, +0x92,0x29,0x40,0x34,0x55,0x9E,0xA4,0x7B,0x73,0x64,0xC4,0x50,0x10,0x92,0xC8,0xEB, +0x79,0x85,0x41,0x22,0x11,0xE7,0xB2,0x2A,0xDC,0x4A,0x2E,0x13,0x9F,0x24,0xCB,0x6F, +0x5F,0x37,0x22,0xF1,0xC3,0x6A,0x4A,0xF4,0x31,0x6A,0x26,0x5A,0xA2,0x70,0xE8,0xF2, +0xC9,0x7F,0xBC,0x78,0x1C,0x5B,0x22,0x58,0x03,0x4A,0x1C,0x5C,0x28,0xCC,0x55,0x23, +0xB6,0x1B,0xC9,0x3D,0x99,0x75,0x57,0x94,0x11,0xCE,0x97,0x0D,0xC7,0xAB,0x70,0x25, +0xDA,0x87,0xB2,0xB8,0xD1,0xD7,0xB6,0xDD,0x09,0xB2,0xF2,0xA4,0x18,0x1A,0xAA,0x66, +0xF9,0x98,0x2A,0xFD,0xBE,0x4D,0x02,0xDB,0x5E,0x1C,0x5B,0x82,0xB7,0xDC,0x44,0x3D, +0x33,0xC8,0x6F,0x05,0xD8,0x10,0xD9,0xE5,0x3D,0x54,0x9A,0x12,0x54,0xB8,0xEC,0x04, +0x63,0x66,0x17,0x7A,0xE2,0xA9,0x98,0xC4,0x2C,0xF3,0x75,0x30,0xB5,0x68,0xAF,0x47, +0x54,0x99,0x72,0x53,0xC5,0x16,0x33,0xD1,0xFB,0x99,0x04,0x4E,0x3B,0xD6,0x16,0xED, +0x2C,0x03,0xE3,0x94,0x60,0xA9,0x7D,0x00,0x12,0x4F,0xFF,0x8D,0x57,0x5E,0xC6,0xC5, +0x8E,0x0D,0x1A,0x5C,0x64,0x9D,0xF7,0xC9,0x24,0x67,0x43,0xF8,0xA6,0xA3,0x4A,0xE9, +0x14,0xB8,0xFD,0x5B,0x41,0xCB,0x6A,0x4D,0xA2,0xDA,0x3C,0xBA,0x16,0xCA,0xBD,0x24, +0x3E,0x48,0x61,0xBD,0x9F,0x49,0x17,0xC5,0xB2,0x83,0xB4,0x42,0x2A,0x64,0xF3,0x12, +0xE4,0x05,0x3A,0x31,0x12,0x8C,0x3C,0x7F,0x2D,0x03,0x99,0xB3,0xD3,0x06,0xFA,0xFC, +0x3E,0xCB,0x96,0xE3,0xC3,0x50,0x14,0x6E,0xC5,0xE7,0x5D,0x45,0xA3,0xB7,0x6A,0xF5, +0xED,0xB9,0x47,0x4A,0xB0,0xDC,0x0E,0x0D,0x1F,0xAB,0xD5,0xD8,0x54,0x7D,0x22,0x0C, +0xCF,0x11,0x39,0x7B,0xA8,0xF5,0x8B,0x1C,0x94,0x51,0x06,0x2C,0x41,0xFD,0xE6,0xDA, +0xA3,0x21,0xAA,0x66,0x3B,0x55,0x41,0x38,0x7E,0x85,0x53,0xCD,0x83,0xA4,0xCA,0xEF, +0xD9,0xA8,0x66,0xBF,0xAB,0xFA,0x28,0x7B,0xC8,0x4A,0x9F,0x54,0x31,0x20,0x8B,0xC3, +0x4E,0x15,0x89,0xFC,0x47,0x34,0x74,0x0D,0xA1,0x9C,0xE7,0xA4,0x65,0x7D,0xF1,0xF1, +0x5F,0xEF,0x16,0xB4,0x62,0x40,0x06,0xD9,0x12,0x0C,0x80,0x94,0x0A,0xBA,0x46,0x1F, +0xF5,0xA9,0xFC,0x56,0xDB,0xB3,0x6F,0xDC,0x54,0x37,0x19,0x97,0x56,0x6D,0xB7,0x50, +0x34,0xA6,0x0A,0x36,0xEC,0x84,0x83,0xAE,0x37,0xE6,0x16,0xFD,0x43,0x6A,0x68,0xED, +0x13,0x96,0x28,0xBB,0xB4,0x8C,0x90,0x1E,0x23,0x57,0x57,0xA4,0x58,0xE6,0x3D,0xC0, +0xB4,0x00,0x1C,0x6B,0x02,0x42,0xD3,0xFA,0xD3,0xA0,0x6D,0x23,0xB3,0x0F,0x13,0x76, +0xF0,0x4B,0xD3,0xC6,0x45,0x5A,0x27,0x41,0x9C,0x94,0xC1,0x85,0x1B,0x7A,0xBF,0x6D, +0x33,0x9E,0x8F,0x7A,0xAC,0x00,0x99,0x02,0x64,0x98,0x4E,0x50,0x1A,0xD5,0x51,0x92, +0xB5,0x46,0x5E,0xAF,0xBF,0xD5,0x2E,0x86,0x06,0x22,0x00,0x51,0x3A,0xB6,0x48,0x6E, +0x18,0x4E,0xC6,0xDB,0x28,0x12,0x1B,0xB9,0x4F,0xA7,0x81,0x5D,0xE5,0x4E,0x2A,0x80, +0xCE,0x9A,0x61,0xDC,0x30,0x12,0x9A,0xBB,0x15,0x5E,0xA7,0xD0,0x3D,0xE4,0xD7,0x3D, +0x51,0xF2,0x30,0xBB,0x47,0x6A,0x6F,0xFB,0x69,0xA3,0x7B,0x1E,0x36,0x0A,0x5E,0x0F, +0xE5,0x44,0xEE,0x62,0x0A,0xC4,0xED,0x54,0x77,0x52,0x61,0xB7,0x4E,0xE1,0xF4,0xEA, +0x0C,0xC4,0x02,0x8F,0xB6,0xB9,0x41,0x14,0xF6,0x76,0xA7,0x0A,0xBB,0xD1,0xAD,0x64, +0x60,0x8C,0x31,0x41,0x31,0x90,0x87,0x1B,0xD6,0x13,0xEF,0xDA,0xA9,0x55,0x3F,0x5B, +0xFE,0xA9,0xDF,0x85,0x39,0x8C,0xE5,0x5A,0x2C,0x12,0x5C,0x3A,0xF4,0xE9,0x4F,0x16, +0xA0,0x95,0x9F,0xA8,0x3E,0x4B,0xB3,0xE4,0x9E,0xAC,0xC5,0xC8,0x90,0x1E,0x88,0x3B, +0xCE,0xE9,0x85,0x8B,0xC7,0xF2,0x10,0x60,0xD8,0xA0,0xED,0x8E,0x19,0xB3,0xA0,0x61, +0xB3,0x78,0x4E,0x9D,0xCC,0x67,0x9D,0x24,0x4B,0xE1,0x90,0x87,0x9F,0xFF,0xAF,0x7E, +0xA8,0x27,0x94,0x69,0xE8,0x88,0xEE,0x29,0x70,0x3D,0x60,0x6B,0x11,0x47,0x57,0xE7, +0xCD,0xB6,0x36,0x5E,0x4B,0x55,0x71,0x49,0xCC,0x2F,0xD4,0xEB,0x62,0x67,0xC0,0x14, +0xC6,0x41,0xBA,0x6B,0x42,0xA1,0x97,0xD0,0x32,0xB0,0x37,0x9E,0x83,0xF5,0x07,0x7D, +0x10,0x54,0x47,0xE0,0x18,0xFC,0xF4,0x32,0x0A,0x25,0x49,0xAD,0x5A,0xC9,0x39,0xE5, +0x57,0x1B,0x80,0xB9,0xAE,0xE5,0xAE,0x11,0x4F,0x86,0x70,0xE8,0x5E,0xC3,0x03,0x08, +0x21,0x70,0xC6,0x1A,0x9D,0x34,0xC5,0xFA,0x2A,0x9C,0x1A,0x9B,0xC6,0x24,0x7F,0x0E, +0x44,0x4C,0xDE,0xE4,0x3A,0xD6,0x2C,0x98,0x07,0x29,0xC6,0x45,0xD1,0x15,0x6F,0x27, +0x79,0x6D,0x96,0x39,0x42,0x54,0x8B,0x80,0x6B,0x6B,0x92,0xCD,0xEC,0x72,0x5A,0x11, +0x62,0x5A,0x26,0x2B,0x02,0xBD,0xA6,0x50,0xC2,0x24,0x2F,0xE4,0x8A,0xC6,0xD5,0xC8, +0x83,0x50,0x45,0x9A,0x23,0xFA,0xF8,0x87,0x20,0xF6,0x05,0x55,0x79,0xC0,0x03,0x8A, +0x8A,0x5D,0x90,0xFE,0xE3,0x44,0x19,0xFA,0xE8,0x76,0x1A,0x07,0xF4,0xC1,0x2E,0x43, +0xE1,0xE4,0x16,0xC3,0x15,0x32,0xB7,0x0A,0xB9,0x95,0xB4,0xF3,0x49,0xA9,0x64,0x47, +0x2A,0x62,0x8E,0xB8,0xD4,0x2A,0x98,0xFF,0x08,0x64,0xFF,0x30,0xCB,0x36,0x70,0x74, +0xAD,0x3D,0xB9,0xCD,0x27,0xF0,0xD7,0x27,0x0B,0xFD,0x41,0xF5,0x48,0xFF,0x66,0xEB, +0x6E,0x6F,0xF8,0x39,0xE2,0xA4,0xD8,0x4C,0xCC,0x28,0xC5,0x42,0xE0,0x4B,0x0B,0x55, +0xEC,0x2F,0xB4,0x2B,0xF6,0x22,0xC1,0x30,0xC3,0x43,0xEA,0x9C,0xF7,0xCE,0xAC,0x35, +0xB5,0x5E,0xBB,0x8F,0xA7,0xFA,0xDB,0x65,0xEA,0x35,0xD7,0x88,0xA3,0x8E,0xAA,0xAD, +0x16,0x62,0x32,0x5D,0x7F,0x1C,0x14,0x88,0x4C,0xC5,0xC3,0x75,0xAA,0x41,0x01,0x23, +0xE5,0x99,0xDD,0xE7,0x5E,0xF2,0x3C,0xA4,0x15,0x07,0x82,0xC9,0x67,0x1F,0x8B,0x22, +0xDB,0x1C,0x89,0x8A,0x98,0xCB,0x6E,0x31,0x0B,0x5A,0xC1,0x88,0x2E,0xBF,0x3D,0x1E, +0xC0,0x93,0xCE,0x29,0x41,0x27,0xF8,0x0D,0x7C,0xF7,0xA6,0xDB,0xD3,0x82,0x96,0x88, +0x1B,0x32,0x0C,0x1F,0x1D,0x99,0x8E,0xF4,0x8D,0x27,0xBE,0x73,0xA7,0xA7,0x61,0x50, +0xBB,0xF1,0x13,0x27,0xF2,0xB2,0x85,0xBE,0xB9,0x65,0x8B,0x8A,0x79,0xD3,0xCD,0xA4, +0xA5,0x08,0xBE,0xB6,0xEA,0x6E,0x98,0x3B,0x6C,0x47,0xC7,0x45,0x00,0x5B,0xE8,0x13, +0xC9,0xEE,0x3F,0x36,0x84,0x4E,0xEC,0xE1,0x2E,0x1D,0xA4,0x9D,0xAB,0xE8,0x34,0xA7, +0x33,0x8A,0xC2,0xE5,0xD4,0x64,0x2A,0xAF,0x82,0x9F,0xA7,0x25,0x89,0xC0,0x3F,0x96, +0xB7,0xD1,0x9C,0x4D,0x9C,0xAC,0xCD,0xDC,0x43,0xB5,0xF8,0x16,0x5F,0x5E,0xDC,0xB6, +0x5E,0xCC,0x0E,0xCE,0xD6,0xF7,0xAC,0x23,0x15,0x6E,0x8E,0x22,0x79,0xF5,0xF6,0x08, +0xAB,0xA2,0xFD,0x47,0xCA,0xF3,0xE5,0xE9,0xD7,0xB8,0xC9,0xCF,0xD4,0x20,0x20,0xE2, +0x41,0xC3,0xEE,0xCD,0x8C,0x6B,0x0A,0x3B,0x5C,0xD8,0xFA,0x0D,0xEB,0xE2,0x4E,0xD4, +0x9F,0x20,0x43,0x07,0x84,0x46,0xEE,0xD9,0x0B,0x78,0xD9,0xC0,0x95,0x5D,0x01,0xF8, +0x9C,0x8C,0x55,0xFF,0xDF,0xF0,0xB9,0xA8,0x57,0x47,0x83,0x49,0x7F,0x96,0x8E,0x7F, +0x79,0x02,0xB6,0x29,0x4D,0xA9,0x60,0x2D,0x10,0xC9,0x27,0xAB,0x50,0xFD,0xD5,0x4C, +0x26,0x70,0xA0,0x31,0x60,0xB0,0x7E,0x6F,0x77,0x34,0x66,0xEA,0x22,0x48,0x08,0x93, +0x65,0x32,0x57,0x14,0x58,0xEF,0x52,0x2B,0x1F,0xED,0x14,0x66,0x0F,0x6B,0xC3,0xD1, +0xB5,0x4D,0xD5,0xF5,0xD6,0xD7,0xEB,0x9B,0x76,0xD6,0x6B,0xD7,0xA1,0xE0,0x20,0x03, +0xE9,0xF0,0x6A,0x23,0xE7,0xB1,0x75,0xC3,0x87,0xE8,0xAC,0x66,0xA1,0xAE,0x2F,0xEA, +0x2D,0x6A,0x75,0x17,0xBD,0xDE,0x07,0xA7,0x6C,0x01,0xF4,0x47,0xBB,0x1E,0x8D,0x2E, +0x9A,0x16,0x39,0x19,0xF5,0x3A,0x49,0xDC,0xE7,0xAF,0x4E,0x8E,0xCD,0xFD,0xF2,0x5B, +0xB2,0xCC,0xA5,0x69,0xA1,0x3E,0x5A,0x1A,0x31,0xA5,0xC0,0xF9,0x86,0x2E,0xCF,0x07, +0x46,0xC3,0xA0,0xE1,0x9C,0xA2,0x5D,0x6F,0xE3,0x72,0x8E,0xB7,0x5A,0xDD,0x19,0xE1, +0xDA,0xED,0x61,0x7F,0x7E,0x95,0xC4,0x5E,0x8F,0x10,0xCA,0x49,0xA8,0xB4,0x0E,0xCA, +0xFB,0xE5,0x0C,0x09,0x15,0xF1,0x24,0xD7,0x40,0x3B,0xA1,0xF1,0xF3,0x75,0x1A,0xD5, +0xD0,0xA4,0x56,0x29,0xF2,0x74,0x9E,0x2B,0x9A,0xC9,0x35,0xBF,0x07,0xEA,0x3C,0x43, +0xEB,0xF0,0x26,0xFC,0x01,0x5B,0xF1,0x61,0x32,0x41,0xE0,0x87,0xD8,0x6D,0x3A,0x53, +0xF6,0x57,0x6A,0x7F,0xBC,0xCE,0x6B,0x24,0x7F,0xFB,0x13,0x19,0x1B,0x63,0xAA,0x13, +0x00,0x39,0x9F,0x4F,0x84,0xD8,0xD0,0x7E,0x91,0xCA,0x3B,0x88,0xE4,0x8C,0x4B,0x1A, +0x20,0x54,0x91,0x1B,0x79,0x55,0x57,0x40,0xA4,0x2F,0x45,0x30,0xE7,0xCB,0x90,0x06, +0xA5,0xE0,0x94,0xDE,0x3D,0x2B,0x70,0x73,0xE4,0xC6,0xAA,0xC8,0xF0,0x57,0x41,0x20, +0xDA,0xD7,0x98,0xED,0xCF,0xA8,0x51,0x63,0x1F,0x53,0x69,0xC6,0x70,0x61,0x98,0x59, +0xB7,0xA2,0x6E,0x82,0x73,0x99,0x28,0xC9,0x8A,0xD9,0x3A,0xBE,0x76,0x6F,0xA7,0x2B, +0xC1,0x4B,0x7C,0x10,0x77,0x8E,0x9D,0xAA,0x94,0xFE,0x65,0x19,0xBF,0x92,0xCB,0xF6, +0xCD,0x27,0xAD,0x34,0x62,0x91,0x7E,0x3D,0x04,0x99,0x4E,0xDC,0x96,0x08,0xBF,0x98, +0x99,0x43,0x00,0x39,0xEB,0x61,0x35,0xEA,0xD9,0xE8,0xB3,0xAE,0x86,0xC3,0xCC,0x2C, +0xA1,0xE5,0x3A,0xFA,0xBA,0x84,0x51,0x06,0x9D,0x7E,0x37,0xE5,0x53,0xA1,0x3C,0xEE, +0x08,0x85,0x37,0x15,0x40,0xD5,0xB3,0x44,0x07,0x6E,0x41,0x87,0xDF,0x12,0x1C,0x71, +0xAB,0x47,0x85,0x76,0x9A,0xB6,0xC8,0x9F,0x43,0xB7,0x85,0x2F,0x38,0xC5,0xE5,0xEE, +0x64,0x55,0x34,0x15,0x14,0x13,0x1E,0x54,0x17,0xB5,0x28,0x44,0xA1,0xA9,0x7C,0x29, +0xD6,0x85,0x90,0x98,0xEE,0x16,0x82,0xEE,0xC2,0x94,0x21,0xE3,0xE1,0x40,0xA7,0x5C, +0x30,0x48,0x6F,0xFC,0x1B,0xEE,0x0B,0xF6,0x06,0x78,0x91,0xF5,0xE8,0x14,0x42,0x25, +0x05,0xFA,0x91,0x85,0xC7,0xF9,0x14,0x95,0x04,0xF5,0x0C,0xDE,0xA1,0x45,0xEA,0xE4, +0x9E,0xF1,0x21,0xE7,0x2B,0xC8,0x48,0xB7,0x15,0x21,0xE9,0x43,0x10,0xD3,0xB3,0x30, +0x16,0xB1,0x93,0xCC,0x5A,0x4C,0x68,0x60,0x0C,0xC9,0x9F,0xFB,0xBE,0x0B,0x06,0x68, +0xC1,0x87,0x8A,0x16,0xAC,0xE8,0x90,0xFD,0x96,0x75,0xE3,0x78,0x8A,0xDB,0x09,0x04, +0xC8,0xED,0xB3,0x07,0x77,0x9B,0x10,0xD8,0x32,0x01,0x4C,0x07,0x0F,0x12,0x32,0x32, +0x80,0xB5,0xD9,0xD3,0xBF,0x8B,0x51,0x45,0xBF,0xF1,0xD7,0x44,0xFF,0x65,0x78,0x00, +0x42,0xFF,0x18,0x37,0xAE,0xD2,0xDB,0x51,0x02,0xFD,0x5F,0x9D,0x1E,0x1D,0x06,0x9C, +0x55,0x9F,0x57,0x98,0xE4,0x9F,0x14,0xF3,0xB2,0xB5,0xE8,0xDD,0x61,0xCF,0xE8,0x36, +0x6F,0x3A,0xE3,0x0B,0xB0,0x41,0x94,0xDB,0x3E,0x3C,0x04,0xE6,0x06,0x72,0xAA,0xCF, +0x77,0xB7,0x12,0xEF,0x32,0x6F,0x59,0x34,0x54,0x7C,0x83,0x2B,0xAE,0x76,0x79,0xC0, +0x11,0x8B,0x77,0xDD,0x1E,0x5B,0xB5,0xC5,0x32,0xE9,0x34,0x65,0xFD,0x67,0x88,0x3C, +0x06,0x75,0x4D,0x02,0x6A,0x24,0xCD,0xA9,0x3E,0xE7,0xDC,0x63,0x47,0xB3,0x3F,0x8C, +0x2E,0xC0,0x2E,0xA9,0x75,0x29,0x0C,0x1A,0x2B,0x06,0x94,0xC0,0xA9,0x7A,0x7E,0x0B, +0xDE,0x66,0x44,0xAA,0x91,0x32,0x55,0x94,0x8E,0x44,0xB5,0x9E,0x64,0x2D,0xF3,0x7D, +0x28,0x9B,0x82,0x83,0x25,0x2B,0x79,0xD5,0xFF,0x11,0x43,0x49,0xD4,0xA5,0x89,0x29, +0x91,0xCF,0xB3,0xAB,0xAE,0xB2,0x19,0x04,0x12,0x7F,0x84,0x69,0x87,0x0E,0x2C,0xCC, +0x08,0x80,0x3F,0x99,0xC4,0xCB,0x3F,0x26,0x8C,0x94,0x37,0x8E,0xD6,0x76,0xB3,0x52, +0x54,0x8C,0x2F,0xF3,0x35,0x05,0x4B,0xB5,0xF6,0x8D,0x64,0x25,0xEB,0x07,0x5C,0x1E, +0xA9,0xBF,0x0F,0x87,0xA6,0x51,0x63,0xCF,0x60,0xD0,0x8A,0x70,0xF9,0x8D,0x91,0xC6, +0x20,0x2A,0x49,0x8F,0xC7,0x42,0x55,0x2A,0xCF,0x5F,0x14,0x3E,0x74,0x0D,0xF9,0xBC, +0xF2,0xBB,0x47,0xEE,0x55,0xE3,0x39,0xA9,0xFD,0xB8,0xEF,0xA6,0x21,0x2F,0x43,0x15, +0x76,0xB8,0xB5,0xC5,0xD4,0xF1,0x33,0xDD,0x02,0x30,0xF7,0x8D,0x15,0xF3,0xED,0x8D, +0xA7,0x99,0xA6,0x44,0x20,0x71,0xBC,0x8B,0x64,0x8E,0x9B,0x07,0xA8,0xE5,0xFF,0x30, +0xA9,0xF4,0xD1,0xB7,0x93,0x03,0x9F,0x8E,0x64,0x83,0x52,0x2D,0xA7,0xEB,0x92,0x6B, +0x77,0x2E,0x04,0x51,0x5D,0xA9,0x50,0xA0,0x7F,0x62,0x3F,0xFF,0x1F,0x19,0xE6,0xB8, +0x1D,0xD4,0x97,0xD4,0x24,0x72,0x73,0x69,0xC0,0x5A,0x5F,0x7D,0xB1,0x9B,0xE6,0x49, +0x92,0x94,0x0B,0x72,0xE4,0xFF,0x60,0xCA,0x72,0x22,0x15,0x3A,0x23,0x9C,0xE4,0x7D, +0x21,0xDD,0xEC,0x2D,0x68,0x5B,0x69,0xA7,0xDC,0xD2,0x23,0x8C,0xA3,0x15,0x55,0x4E, +0x77,0xEC,0xB7,0x33,0x52,0xDD,0x65,0x1C,0xD6,0x15,0xA6,0x30,0x5D,0x43,0x6F,0x5D, +0xE1,0x85,0x85,0x77,0x2D,0x1D,0x8F,0x41,0x58,0x97,0xD1,0x7F,0x53,0x9E,0x22,0xB1, +0xA0,0xFB,0x9C,0x00,0x60,0x00,0x5D,0xC4,0x8F,0x04,0x91,0xA0,0xF8,0xDF,0xAF,0x67, +0xC7,0xF3,0x57,0xE3,0x42,0x2F,0xC2,0x5B,0x7C,0x07,0x2E,0xEA,0x69,0xA2,0x27,0x7A, +0x9E,0xFF,0x5E,0x7E,0xFA,0xA9,0x83,0xB8,0x86,0x52,0xA0,0xCE,0xCD,0xB6,0xE5,0x2C, +0x4E,0xF0,0x29,0x93,0xCF,0x81,0xD7,0x09,0xCE,0x82,0x6C,0x53,0x6A,0xD9,0xD1,0x35, +0xD2,0x12,0xD9,0xC7,0x71,0x12,0xDB,0x9A,0x6D,0x7A,0x08,0x68,0x6B,0x26,0x7B,0x4B, +0xDE,0x78,0xD7,0x27,0x25,0x42,0x53,0xC6,0x28,0x2C,0x7D,0x30,0x82,0xF1,0xD6,0xFE, +0x42,0xBA,0x06,0xBD,0x08,0xDC,0x05,0x56,0xD6,0x72,0xC3,0x6A,0x9A,0x95,0x4B,0x10, +0x51,0xA3,0x12,0x64,0xBF,0xB9,0x9F,0x95,0x44,0x8A,0x4D,0x63,0xC0,0xD2,0xF5,0xE9, +0x1F,0xE6,0xA8,0xD4,0xFB,0x93,0x65,0x9C,0x57,0x73,0x42,0xA9,0x20,0xC7,0xE9,0x4C, +0x32,0x88,0xF7,0xAC,0x22,0xC5,0x03,0x7C,0xB9,0x42,0x1B,0x86,0x4B,0xC2,0x6C,0x4D, +0x58,0x61,0xCF,0xE1,0xA1,0x49,0xB7,0xCF,0xDC,0x68,0xBE,0x04,0xDE,0x7E,0x30,0x76, +0x6A,0x33,0x09,0x9A,0x6E,0xD8,0x87,0x36,0xAC,0x4E,0xCE,0x36,0xEF,0x6D,0x6E,0x33, +0x57,0x10,0x1E,0x9F,0xC0,0x01,0x1D,0xD9,0x07,0x6E,0x91,0x24,0x94,0xDA,0xE1,0xF1, +0x85,0xE6,0x4A,0x3E,0x10,0xEF,0x72,0xA3,0xAC,0xD9,0xBB,0xD3,0x7A,0x69,0xB7,0xF7, +0x77,0xBC,0x1A,0x9A,0xDB,0x22,0x28,0x54,0xC4,0x42,0x02,0x60,0x70,0xBC,0xA1,0xAC, +0x49,0x50,0xE1,0x84,0x33,0xF6,0xEA,0xE3,0x8B,0x19,0x04,0x4D,0x2F,0xD2,0xBC,0x38, +0x1F,0xAB,0x6D,0xC1,0xA9,0x7C,0x9B,0x0F,0x70,0x11,0x0E,0xE7,0xAC,0xA0,0x82,0x81, +0xE7,0xE8,0x7B,0x21,0xEF,0xB9,0xED,0x59,0xA0,0x72,0xCF,0xEE,0xD5,0x4E,0x84,0xBE, +0x68,0xBD,0x7A,0xDA,0x17,0x16,0x75,0x2C,0xB9,0x27,0x1C,0xF3,0x5F,0x8E,0xDE,0x67, +0x0A,0x53,0x1F,0xD3,0x91,0x5B,0xA9,0x89,0x03,0x99,0x23,0xD9,0xF9,0x37,0x34,0x8A, +0x4F,0x56,0x01,0x6E,0xDF,0x2C,0x62,0x92,0x73,0x7F,0x03,0xD0,0xFD,0xE1,0x30,0x7E, +0x0C,0xF0,0x2F,0x70,0x20,0x79,0x0F,0xE7,0x9F,0xC8,0x0D,0xA7,0x45,0x2B,0xF0,0x2D, +0xD0,0xA4,0xB3,0x98,0x5C,0x21,0xF7,0x66,0x08,0x8D,0xAB,0xE9,0xFB,0xDC,0x0A,0x00, +0xA2,0xF1,0x89,0xEF,0xBA,0xE4,0xBA,0xAB,0xCA,0xAD,0xE0,0xE9,0x57,0x6F,0xE0,0x3B, +0x1A,0xFF,0x4A,0xD2,0xE5,0xC9,0x66,0x0C,0x75,0x63,0xE3,0xC1,0x5F,0x31,0x3A,0xAB, +0xA6,0x3F,0x69,0x0B,0x18,0x58,0x4A,0x71,0x38,0x3F,0x4C,0xA0,0x23,0x08,0xA0,0xEB, +0x85,0x73,0xC9,0x76,0x8C,0xCF,0xA6,0x46,0x23,0x1D,0x62,0x1A,0x3D,0x73,0xE0,0x02, +0xFB,0xEB,0xDE,0x25,0xB5,0x7D,0x34,0x7B,0x22,0xD9,0xC5,0x72,0xC1,0xEF,0xDC,0x69, +0x54,0xB6,0xAB,0x6F,0x10,0x71,0xED,0x06,0x9C,0xDD,0x1B,0x06,0x2A,0x2B,0x50,0x7C, +0x65,0xE9,0x7A,0x75,0x6A,0x1E,0xBF,0x10,0x60,0x36,0x15,0x27,0xC5,0xF1,0x10,0x49, +0x4A,0xB3,0x01,0xAC,0xFA,0x6D,0xA1,0x5F,0xC2,0x04,0xB4,0x66,0x89,0xFE,0x74,0xDB, +0xEE,0xF2,0x17,0x04,0xE8,0x2F,0xAE,0x85,0xF6,0x5A,0x4B,0x6E,0x3B,0xEE,0x00,0x63, +0x8F,0x41,0x9E,0x88,0x2C,0x34,0xF9,0x72,0x2C,0x7F,0x89,0xA8,0x08,0xDF,0xDB,0x42, +0x41,0x46,0x1E,0x6F,0x0F,0xA3,0xE9,0xF1,0xF6,0xBD,0xEC,0xDB,0x19,0xA4,0xB9,0xBB, +0x20,0xC7,0x76,0xAB,0x41,0x06,0xAC,0x0A,0xB4,0x0E,0x9A,0xC0,0x8D,0x83,0xD3,0x3F, +0x97,0xF6,0xC7,0x6B,0x60,0x28,0x85,0x6B,0xA1,0x7B,0x9E,0x81,0x9B,0x7E,0x2A,0xA5, +0x31,0x37,0xAD,0x84,0xE3,0xA8,0xA4,0xAE,0x67,0x41,0xB7,0x0A,0x5C,0xC1,0xB6,0xAE, +0x0F,0xC9,0xA7,0x35,0xD6,0xA0,0xD4,0x71,0x1D,0x93,0x22,0x49,0x40,0x08,0xAE,0x2B, +0x74,0xD2,0x0B,0x73,0x64,0x08,0x9B,0x35,0x1F,0xD3,0xB8,0x5A,0x30,0xF7,0x0C,0xE1, +0xD5,0xB0,0xCC,0x99,0xF6,0xF2,0xF2,0x27,0x94,0x8C,0xC5,0x44,0x1C,0xE3,0x9D,0x14, +0xC4,0x8D,0x74,0x03,0x78,0x75,0x9A,0xB8,0x3D,0x4E,0x16,0xD3,0x9E,0x55,0xEE,0x7E, +0x80,0x2C,0xD6,0xDF,0x3B,0x09,0x4B,0xCC,0x61,0x41,0x3A,0x4A,0x5B,0xD4,0x8E,0xCF, +0x84,0x86,0x75,0x52,0xA1,0x70,0x4A,0x7A,0x2D,0x27,0x8B,0x65,0xDB,0xC8,0x87,0xFD, +0xB4,0x0A,0x5B,0x13,0x17,0x6A,0xCE,0xBE,0x6C,0x34,0x1E,0x21,0xEA,0x56,0xF4,0x9A, +0x4B,0x2F,0x58,0x79,0xD6,0xFB,0x68,0xC1,0x54,0x69,0xD8,0x88,0x8E,0xE8,0x80,0x74, +0x90,0x7B,0xDE,0x3E,0xBB,0xEF,0xDA,0x22,0xA0,0x25,0x51,0xFC,0xB5,0x80,0xAE,0x1C, +0x73,0xCC,0xD2,0x46,0xEC,0x22,0xB6,0xDB,0x21,0xB8,0x98,0xA3,0xC4,0x0A,0x24,0x1F, +0x5C,0xCB,0x44,0x8F,0x8C,0x18,0x61,0xCB,0xAC,0x8C,0xE3,0xC3,0xCB,0x6D,0xB3,0x21, +0x3A,0x7D,0x4B,0x0D,0x58,0x11,0xAA,0x58,0x01,0xCE,0x87,0xC7,0x55,0x63,0xDF,0xEA, +0xA6,0x2B,0xA2,0x56,0x0F,0x94,0x8D,0xA6,0xF5,0xC0,0x4E,0xCB,0xB7,0x3E,0x83,0x17, +0xE4,0xC3,0xA6,0x63,0x19,0xAC,0xA4,0xB0,0xF2,0x64,0x51,0xFD,0xF2,0xA5,0x76,0x7C, +0x69,0x67,0x32,0x93,0xE1,0xEA,0x18,0xBC,0x56,0x81,0x97,0x65,0x41,0x1E,0x30,0x99, +0x20,0x59,0x72,0xA9,0x78,0xD5,0xF5,0x2F,0xDE,0x3C,0xE5,0xFA,0xC2,0xE2,0x20,0x3F, +0x56,0x45,0xFC,0x1B,0x00,0xDD,0xDD,0x2A,0x41,0x65,0x7C,0xB3,0xA8,0xC7,0xA6,0x6D, +0x99,0x73,0x8F,0x9B,0x3D,0x13,0xAC,0x89,0x01,0x92,0x17,0x62,0x4E,0xEF,0xEC,0x85, +0x58,0x8D,0xC8,0x78,0x8C,0xCA,0xC4,0xC8,0x7A,0x49,0x17,0x85,0xD4,0x06,0x09,0xE4, +0x88,0x52,0x10,0xB8,0xC6,0x5D,0x27,0xED,0xA5,0xDE,0xB1,0xFD,0x0A,0xF1,0x07,0xF7, +0xF0,0x96,0xE6,0x36,0xE0,0x8C,0xB0,0xC0,0x4A,0x02,0x03,0xDD,0x38,0x8E,0x40,0xDD, +0xC6,0x75,0x11,0x76,0x23,0x73,0x21,0xDE,0xFF,0x8B,0x93,0x22,0xEE,0x7B,0x69,0xA6, +0x88,0x5D,0xF4,0xA8,0x19,0x74,0xD0,0xBC,0xB6,0xAB,0x7D,0x28,0x5A,0xA9,0x3F,0x6D, +0x26,0x4E,0x6E,0x2D,0x82,0xC4,0xEC,0x1D,0xF0,0x7F,0x53,0x0A,0x03,0x02,0x7F,0x03, +0x3C,0x40,0x27,0xB8,0x1F,0x1A,0x9C,0x02,0x5E,0xAE,0x93,0x03,0x33,0xD1,0x5B,0xCE, +0x8C,0x63,0xCF,0x51,0x7A,0xE1,0x67,0xA9,0xC2,0xF0,0x88,0x7F,0x44,0xA2,0xD1,0x53, +0x86,0xAE,0x99,0x45,0x2B,0x8F,0x03,0xC2,0x77,0xA0,0x54,0x5F,0xD0,0x00,0xC7,0xF1, +0xFA,0x9B,0xBC,0xFE,0x30,0x80,0xB4,0xA2,0xF1,0xBD,0x7D,0x01,0x3F,0x54,0x19,0x97, +0x21,0x0D,0x68,0x7D,0x4A,0x65,0xE2,0x51,0x40,0x48,0xBA,0x04,0x9D,0xB8,0x0E,0x8F, +0x37,0xAF,0x33,0xD1,0x53,0x13,0xE0,0x89,0xA6,0x07,0xE1,0x2F,0xA0,0x6A,0xFD,0x55, +0x0F,0x73,0xB7,0xC0,0x0F,0xC9,0x9A,0x53,0xCD,0x55,0x11,0x9F,0xF1,0xFA,0xBF,0xAE, +0xEA,0xA8,0x6A,0x58,0xA8,0x6D,0x94,0xE6,0xE0,0x73,0xEA,0x2D,0x2A,0xC1,0xBF,0x8E, +0x5D,0x52,0x8A,0x88,0x97,0x20,0x93,0xF0,0xC6,0x67,0x17,0x52,0x94,0x10,0x56,0x25, +0x6B,0x38,0x72,0x2A,0x1B,0xDF,0x97,0xF6,0x27,0x95,0xBF,0xE6,0x51,0x69,0xD9,0xF2, +0x55,0x8C,0x30,0x7B,0x2E,0x78,0x70,0xAE,0xAC,0x7E,0xDF,0xEA,0xBE,0x32,0xB6,0x0F, +0x34,0x3D,0x6B,0xE5,0x68,0x2F,0xB8,0x44,0x68,0xEE,0x35,0x61,0xC1,0x52,0x78,0x1F, +0x0B,0x5D,0x40,0x23,0xFE,0x3C,0x26,0x85,0xE1,0xFD,0xFE,0x00,0x79,0x42,0x3F,0x1B, +0x2D,0x81,0x72,0x9B,0x04,0x4E,0xE4,0x1E,0xC4,0x95,0x71,0x51,0x7A,0x17,0x34,0xB1, +0xAF,0x11,0x90,0x2E,0x33,0x9C,0xEF,0x00,0x90,0x47,0xB9,0x82,0x58,0xA9,0x41,0xF0, +0x52,0x2D,0x83,0xEA,0x6D,0xE3,0x98,0xED,0xB3,0xEB,0xD1,0x24,0x99,0x61,0x33,0xF2, +0xD1,0xEC,0x91,0x02,0x9C,0xBE,0x6A,0x18,0x22,0x59,0xFC,0xA2,0x59,0xEC,0xA7,0xBA, +0x18,0x4D,0x75,0x6B,0x12,0x6D,0x3B,0x1A,0x02,0x6F,0xCF,0x2B,0xF7,0x35,0x8B,0xC9, +0xD3,0x13,0x3F,0x7A,0xC8,0xC0,0x3E,0xA3,0x17,0xFD,0x99,0xA1,0xFE,0x0C,0x67,0x9C, +0x1C,0xFE,0xFC,0x10,0x34,0xE0,0xB7,0xF7,0xCF,0x5A,0xF2,0x4C,0x62,0xA0,0xCD,0x6D, +0xE6,0xCD,0xE1,0x5A,0x53,0x8F,0x6D,0x88,0x79,0xA4,0x9B,0xA2,0xED,0xDC,0xA5,0xEF, +0x45,0x50,0x38,0x8A,0x01,0x18,0x7C,0xA8,0x81,0xCE,0xBB,0x5D,0x71,0x31,0x64,0x06, +0x59,0x27,0x92,0x49,0x37,0x73,0x10,0x22,0xC7,0xDC,0x25,0x0B,0x33,0xA1,0xED,0x39, +0x07,0x0F,0xDD,0xD9,0x17,0x01,0x89,0x5D,0x1C,0x73,0x2F,0x0E,0x8E,0xCA,0x10,0x8F, +0xFE,0xD9,0x9B,0x39,0xBC,0xBF,0x84,0x20,0xD2,0xF6,0x10,0xC8,0x19,0x6C,0xCB,0xA6, +0x64,0x46,0xD3,0x60,0x70,0xB1,0xB2,0x65,0xB8,0x1C,0xAB,0xFC,0x06,0x3B,0xB1,0x3A, +0xB7,0xE5,0xF0,0x83,0xBF,0x46,0xFC,0xA5,0x82,0x37,0xE3,0xBD,0x75,0x41,0xEF,0x89, +0x59,0x6D,0x42,0xC9,0x35,0x72,0x78,0x2B,0x44,0x54,0x80,0x85,0xA1,0xAC,0x4E,0x4E, +0xB4,0x23,0x69,0xA6,0x44,0xF8,0xF4,0xCB,0x6E,0xFB,0xE8,0x31,0xC8,0x78,0x56,0x75, +0x8E,0x9B,0xBF,0xF8,0x60,0x44,0xD0,0xDD,0xF1,0x3A,0xD9,0xED,0xAE,0x3F,0x3A,0x64, +0xBF,0xF5,0xF6,0x54,0x7B,0x2F,0x72,0x61,0x8C,0xCD,0xD3,0x8C,0x3A,0x59,0x5A,0xFD, +0x40,0xDE,0x66,0x98,0xA3,0xD6,0x04,0x03,0xBE,0x0C,0xE9,0xFF,0x2D,0xD9,0xCD,0x63, +0x46,0x37,0x96,0x82,0xA1,0xF0,0xE4,0x2F,0x08,0xEF,0xC5,0x3A,0xD2,0x5F,0x15,0xBD, +0x64,0xAE,0x8D,0x83,0xBD,0x23,0x3B,0xC0,0x52,0x54,0x73,0xC9,0x8F,0xFA,0xD9,0x6A, +0x97,0x51,0x0E,0xFF,0xAE,0x21,0xC2,0x5D,0x10,0xAB,0xA6,0xDE,0x12,0xB8,0x7B,0x6F, +0x23,0xB3,0x7F,0x00,0x93,0xEC,0xC4,0x0C,0xB1,0x59,0x46,0x76,0x9D,0x7B,0xA5,0x39, +0xDD,0x41,0x42,0x07,0x3B,0x91,0x80,0xBE,0xD5,0xFC,0x15,0x52,0x05,0x40,0xA3,0xCA, +0xED,0x55,0x07,0x93,0x68,0xF3,0x16,0xA1,0xA9,0x52,0x57,0x96,0x50,0xDA,0xB2,0xF8, +0xC2,0xE2,0x90,0x46,0xBF,0x6F,0x7B,0x36,0x94,0xC9,0x0B,0xD3,0x9D,0xB1,0xC9,0x86, +0x18,0x59,0x1A,0x34,0xED,0x4E,0xEA,0x2A,0x6C,0xF9,0x75,0x5C,0x7D,0xBB,0x8D,0x5E, +0x67,0xC0,0x26,0x3B,0xF1,0xE4,0xB1,0x12,0x57,0x80,0xC9,0xF6,0xF2,0xC7,0xF0,0xDF, +0x4A,0xAD,0x3E,0x8C,0x5E,0xDC,0x8C,0x0D,0x49,0xF0,0x3F,0xB8,0xBF,0xD0,0x83,0x40, +0xA7,0x19,0x46,0xC4,0x7B,0x0F,0x29,0x8C,0x76,0xD1,0xEF,0x0F,0xB6,0x96,0x05,0x53, +0x03,0x58,0x87,0xD8,0x3A,0xBC,0x48,0x01,0x9F,0x68,0xED,0x2E,0x7A,0x17,0xEE,0x3C, +0xFF,0xBD,0x11,0xAD,0xFE,0x67,0x61,0x64,0xAE,0xAD,0x2E,0xE8,0xEE,0xCB,0x04,0x00, +0x77,0xCC,0x12,0x16,0x2B,0x15,0xBE,0xD7,0x3F,0x6E,0x5F,0xDC,0x96,0x4A,0x1E,0x3C, +0xC7,0x6E,0x3E,0x16,0x71,0x7C,0x43,0xCA,0x4D,0xEA,0xE6,0xA9,0xAC,0x02,0x0A,0x77, +0xF9,0xBB,0xDD,0x02,0xEA,0x8D,0x27,0xF7,0x79,0x0B,0x46,0xB9,0x87,0xAE,0x8D,0x78, +0x4A,0x48,0x14,0xF8,0x3A,0x31,0x27,0x1A,0xA3,0x3B,0x05,0x55,0x97,0xD5,0x9C,0x6D, +0x72,0x78,0x38,0x76,0xFF,0xD0,0x3E,0xCF,0xFD,0x9F,0xF1,0xCD,0xDD,0x74,0x55,0x47, +0xF3,0x58,0x47,0x27,0x22,0xB9,0xD7,0xB7,0x60,0xEA,0xEE,0x70,0xCB,0x34,0x46,0x84, +0x34,0x66,0xA7,0x0E,0x15,0xE3,0xC3,0x93,0xEF,0xD8,0x72,0x07,0x8C,0x1E,0x77,0xCD, +0x1E,0xC4,0xEA,0x09,0x8A,0xC0,0xA8,0x23,0x02,0x30,0x6B,0xB5,0x8B,0x1C,0xD0,0x35, +0xEC,0x56,0x10,0xAD,0x0B,0x9B,0x15,0x88,0x03,0xFF,0x08,0xC6,0x29,0xDF,0x28,0x64, +0x09,0x05,0x2B,0xEF,0xB3,0x7F,0x1A,0xDA,0x54,0x89,0x45,0x5A,0x96,0x08,0x75,0x22, +0x7D,0xAE,0x02,0x88,0x28,0x5A,0x19,0x84,0x39,0x41,0x0E,0x6D,0xB0,0x66,0x42,0x0C, +0xE3,0x43,0xA3,0xF9,0x38,0xEB,0xBC,0x91,0x1B,0xBE,0x99,0x98,0xCB,0x6D,0xD6,0xA5, +0x7D,0x53,0xA2,0xDF,0xEA,0xD5,0x36,0x19,0xD0,0x59,0x87,0xAD,0xD6,0x8F,0xE1,0xC2, +0xE4,0x65,0x76,0xC9,0xDE,0x7E,0xC1,0xA0,0x67,0xE0,0xC6,0x7A,0x23,0xB3,0xD8,0xCE, +0xD1,0x18,0xA2,0x8A,0xF8,0xED,0xDF,0xEC,0x50,0xA4,0x52,0xA6,0xB9,0xC1,0xD2,0x92, +0x46,0xAD,0xFD,0xA1,0x3D,0xE6,0xFE,0x7C,0xE0,0xFD,0x75,0xB2,0xDD,0x12,0x53,0x65, +0x9D,0x96,0x7C,0x26,0x8A,0x81,0x17,0xDD,0xCB,0x5B,0x97,0xD5,0x29,0xB4,0x03,0x58, +0x33,0x3D,0x0F,0xC4,0x4E,0x54,0x7C,0x3C,0x2C,0x5F,0xFA,0x75,0x1C,0x67,0x97,0x72, +0x03,0xE2,0xB2,0x93,0xC6,0x6F,0xBA,0x2B,0xF5,0x87,0xC8,0xA0,0x0C,0x72,0xDC,0x7D, +0x47,0x4F,0x30,0xE3,0xC5,0x11,0x94,0x25,0x60,0x84,0xD1,0x42,0xC6,0x19,0x2B,0x4D, +0x53,0x43,0x46,0x9B,0xF7,0x61,0xB1,0x9D,0x32,0x0D,0xDF,0xD5,0x9A,0xC8,0x1E,0xC4, +0xFF,0xD0,0x96,0xDA,0xDB,0xC0,0x81,0xCD,0x68,0x20,0xE1,0x51,0x40,0xD9,0x7F,0xB7, +0x9C,0x92,0x44,0xD0,0x2A,0xFD,0x34,0x07,0xD6,0x6A,0x81,0x8A,0x78,0x70,0x80,0xFF, +0xA3,0x86,0x87,0x27,0xBC,0xA0,0x8F,0x0E,0x91,0xD5,0x10,0xF0,0x96,0x79,0x8A,0xC3, +0x9E,0xA5,0x3C,0x1E,0x90,0xCB,0xE2,0xAC,0x84,0x48,0xD4,0x0C,0x05,0x44,0xDF,0xC8, +0x70,0x18,0x66,0x5A,0x4F,0x15,0x33,0x0F,0x4D,0x3E,0xE1,0xF4,0x4E,0xC7,0xF1,0x8F, +0x22,0xDA,0x66,0xD1,0xC4,0x70,0x03,0x1B,0x46,0x0C,0x65,0x79,0xF8,0xA3,0x84,0x71, +0xB0,0x01,0xBF,0x95,0x20,0xEA,0x76,0x66,0x3D,0xE7,0xBC,0x97,0x54,0x37,0xB3,0x1E, +0xC1,0x44,0xE4,0x07,0x21,0x04,0x70,0x4E,0x45,0x4F,0xDC,0x91,0x0E,0x6F,0xB9,0x63, +0xFF,0x33,0x55,0xDB,0xB0,0xFC,0x67,0xFE,0xEC,0xC3,0xF0,0x40,0x1B,0xB2,0x2A,0x4C, +0x92,0x17,0xB6,0xA1,0xAD,0x5B,0x97,0x56,0x1D,0x44,0x2B,0x86,0x17,0xE2,0x21,0x24, +0xF9,0x7C,0xBA,0x53,0x48,0x96,0xAE,0x93,0x4F,0xCE,0x02,0x87,0x59,0xEB,0xF0,0xB8, +0x98,0x20,0x88,0xAE,0x11,0x86,0xB9,0xCA,0xBA,0xFE,0x40,0x3A,0xE3,0x4B,0xFA,0xD1, +0x7C,0x17,0x38,0x16,0xF4,0x82,0x6C,0x31,0x31,0x59,0xE9,0x4C,0xC9,0x51,0x42,0x25, +0x53,0x27,0x78,0x01,0x26,0x05,0xA1,0x24,0x69,0xC5,0x2D,0xF0,0xB9,0xCC,0x9E,0xB4, +0x12,0x56,0xA7,0xDE,0x03,0xA9,0x13,0x31,0x36,0xB4,0x85,0x52,0x82,0xA2,0x14,0x80, +0xBF,0x66,0x84,0x8B,0xB1,0xCA,0xEA,0xD8,0x0C,0x8B,0xC8,0x83,0xD4,0xCC,0xCE,0xD4, +0x67,0x27,0x02,0x84,0x66,0x72,0xDF,0x37,0x33,0x88,0xB7,0xC2,0xC1,0xA5,0x19,0x35, +0x56,0x86,0xE1,0x9D,0x65,0x41,0x00,0xBF,0x41,0x93,0x58,0xC2,0x4D,0x7B,0x6E,0xE2, +0x13,0x2E,0x76,0xDD,0x31,0x83,0x6C,0x73,0x79,0x53,0x58,0x8C,0x47,0x46,0xFC,0x7D, +0xC8,0x1A,0x3F,0x55,0x07,0x44,0x5C,0xB4,0xE7,0x37,0x79,0x88,0x29,0x0D,0x0A,0x5A, +0xA1,0x1D,0xB5,0x9B,0x2B,0xA1,0x43,0x03,0x8A,0x09,0x8B,0xD9,0xA3,0x11,0x97,0x3F, +0xF0,0x93,0x37,0xBD,0x54,0x76,0xF3,0x5C,0xD3,0x9A,0xBA,0x41,0x4D,0xC7,0xA7,0xC1, +0x27,0x2E,0x5F,0x73,0xA9,0xE9,0x89,0x40,0x5D,0xBB,0x46,0xCD,0xE7,0x2E,0x97,0x53, +0x84,0x78,0xD3,0xAA,0xC1,0xDC,0x80,0x9D,0xF1,0x62,0x3E,0x0C,0xDF,0x48,0x33,0x8B, +0xB6,0x53,0x9B,0xF1,0xF1,0x7C,0x9F,0xCA,0xD5,0x00,0xA3,0x32,0xEA,0x46,0xD4,0x91, +0x98,0xB3,0x1A,0xF0,0xA1,0x54,0x2E,0xE2,0xE4,0xA3,0x7C,0x5D,0xA1,0x19,0x68,0xD4, +0x1D,0x2D,0x87,0x8E,0xC0,0x2C,0xB0,0x0A,0x97,0xFC,0x05,0xA4,0x5D,0xA9,0xBD,0xA5, +0x7A,0x53,0x9D,0x96,0xB6,0xA6,0x5F,0xF8,0xA8,0x45,0xA9,0x2D,0x95,0x46,0x09,0x5D, +0x73,0x18,0xC3,0x5C,0xCA,0xB2,0x2F,0x19,0x20,0x82,0xCB,0x90,0x9C,0xCB,0x5D,0x73, +0xD1,0xA2,0x30,0xAF,0x3A,0x6A,0x5D,0x35,0x4A,0xD2,0x24,0x07,0x5C,0xA6,0x16,0x08, +0x34,0x0D,0x26,0x84,0xFE,0x3B,0x96,0xC6,0x62,0x98,0x94,0x8C,0xF9,0x54,0xC4,0xF9, +0xA0,0xBB,0x2B,0xB5,0x18,0x30,0x2C,0x58,0x20,0x56,0x13,0xF0,0xC2,0x58,0x65,0x8B, +0x53,0xC8,0xC3,0x2C,0x0D,0x1E,0x0C,0x0A,0x6A,0x04,0x19,0xC8,0xD2,0xD6,0x2D,0xE0, +0xE7,0xC5,0x50,0x6A,0xDE,0x1E,0x4E,0x83,0x1C,0x48,0xBC,0x3E,0x59,0xD0,0xC7,0x42, +0x05,0xDD,0x52,0x4E,0x41,0xFF,0xC3,0xCD,0xEC,0xBE,0x43,0x25,0xD6,0x27,0xB3,0xCE, +0x57,0x8A,0xE6,0xF0,0xF8,0xA6,0x03,0xFF,0x9D,0xBD,0x99,0x93,0xDB,0x54,0xB1,0x7D, +0x5C,0xC9,0x40,0x9F,0x9C,0x5C,0x28,0xED,0x52,0xAE,0xBF,0x21,0xCF,0x3C,0x8C,0xF2, +0x06,0xAE,0xAF,0xBA,0xFA,0xE2,0xC4,0x9E,0x88,0xD3,0x89,0xF1,0xE9,0x7F,0x22,0x61, +0x99,0x35,0x52,0xF2,0xA5,0x0B,0x6B,0x6B,0x29,0xF1,0x43,0x0C,0x59,0x5D,0x5E,0x8E, +0x9F,0x1D,0x17,0x39,0x4C,0xAB,0x73,0x90,0x7D,0x42,0x28,0x6F,0x9E,0x3A,0x93,0x00, +0xC8,0x6E,0x96,0x77,0x7F,0xB7,0xF4,0x79,0x04,0xD2,0x4E,0xF3,0x47,0x98,0x9C,0xA0, +0xD3,0x17,0x11,0x2D,0xE2,0x4B,0xA1,0x5A,0xEF,0x62,0x09,0xE8,0x28,0x72,0x9A,0x0F, +0xC6,0xEA,0x31,0xBC,0xCD,0x65,0x02,0x69,0x3B,0x4F,0xDD,0x47,0x8A,0x78,0xC8,0xBE, +0x4C,0xE1,0x74,0x62,0x14,0x92,0x65,0x88,0x09,0x13,0x21,0xEC,0xBD,0x84,0x26,0xE0, +0xE9,0x80,0x56,0xE6,0x83,0x40,0xB9,0x19,0xFC,0x97,0x32,0x93,0xF0,0x3F,0xA1,0xDB, +0x83,0x42,0xCB,0x76,0xFA,0x4B,0x6F,0x96,0xD2,0x35,0x41,0x98,0x3C,0xE3,0x37,0x60, +0xB8,0xF3,0x00,0x06,0x50,0x7B,0xE4,0x7A,0x67,0x9E,0x11,0xEE,0x86,0xE1,0x0E,0xCE, +0xBC,0x2D,0x42,0xA7,0x45,0x4A,0x74,0xE6,0xCD,0x05,0xC6,0xB0,0xEE,0x78,0x10,0x5C, +0x4F,0x3A,0xB6,0xC6,0xAC,0xCC,0x86,0xD1,0x25,0x49,0x4C,0x55,0x50,0x74,0x1C,0xB0, +0x94,0xE6,0xBD,0x0F,0x38,0x4A,0x9E,0x41,0xEC,0x0C,0x75,0xC1,0x6D,0x72,0x57,0xCA, +0x75,0x63,0x22,0xF3,0xD6,0x91,0xCE,0x38,0x44,0x76,0xCB,0xE1,0xDA,0x95,0xA7,0xF5, +0xB8,0x6E,0x0E,0x1A,0xF6,0xA1,0x01,0x4C,0xA6,0xFA,0xB4,0xB9,0x12,0x86,0x3B,0x42, +0x7A,0x32,0x4A,0x8F,0xE8,0x52,0x5C,0x27,0x84,0x32,0xF0,0xBB,0xC1,0x65,0x24,0x4A, +0x40,0xE6,0x77,0xC3,0x12,0x70,0xE3,0xB1,0x0E,0x28,0x27,0x07,0xE5,0xFD,0x68,0x45, +0x45,0x2E,0xC6,0xE7,0xCB,0x88,0x52,0xBC,0x24,0x6D,0xE6,0x5D,0xB2,0xB4,0x15,0x8E, +0x3B,0x17,0xE2,0x23,0xD3,0x41,0x52,0xF0,0x8A,0x52,0xB9,0x99,0x32,0x37,0x4D,0x9D, +0x3F,0x7F,0xC1,0x34,0x1A,0x6C,0x6A,0xE3,0xE5,0xD8,0x49,0x58,0x2F,0x25,0x25,0xBC, +0x64,0xAF,0x6A,0x08,0xDC,0x79,0xA4,0xF1,0x2E,0xD2,0xE1,0xFA,0xFD,0xAD,0x74,0xD1, +0x5C,0xD6,0xCB,0xBB,0xA9,0x2C,0x30,0xAD,0x7A,0x6A,0x36,0xC0,0xAB,0xAB,0x9E,0x42, +0xBA,0x90,0x56,0x36,0x73,0x5D,0xD3,0x10,0x70,0xC8,0x8A,0xC3,0xFA,0x42,0x5D,0xBB, +0xA3,0x45,0x84,0xCD,0x7C,0x25,0x90,0x01,0x67,0xC2,0xAE,0xE9,0xBF,0x31,0x18,0xFE, +0xF2,0xE3,0xF2,0xD6,0x03,0x58,0xD7,0x81,0x76,0x34,0xA8,0x1E,0x13,0x79,0x49,0x1F, +0x0E,0xDF,0xA6,0x5A,0xC4,0x25,0x7F,0x86,0x1A,0xFF,0x62,0x88,0xC9,0x3B,0x44,0x5E, +0x3E,0x83,0x15,0x32,0x67,0x8E,0x85,0x9B,0x0A,0x71,0xB4,0xBE,0x16,0xCA,0x41,0x09, +0xAC,0xD3,0x22,0x30,0x5D,0xD4,0xE4,0xA8,0xEE,0xD6,0x3B,0x97,0xD2,0x22,0xBE,0x82, +0xDE,0x58,0x61,0x35,0xE5,0x64,0xA7,0xDB,0x8B,0xC6,0x9F,0x49,0xD0,0xE6,0x1F,0x8D, +0x52,0x0E,0x69,0x9F,0x7A,0x6F,0xB5,0xC9,0xB9,0xE2,0xEC,0xB7,0xB9,0x97,0x84,0x31, +0x16,0xE1,0xA6,0x07,0x74,0x3F,0xBC,0x99,0x44,0x58,0xB6,0xB9,0xAB,0x39,0x41,0x79, +0x58,0xC8,0x07,0xB0,0x35,0xE4,0xDE,0x7F,0xA0,0x47,0x9F,0xA7,0xCA,0x53,0xA1,0xEA, +0x0B,0x14,0x31,0xA1,0x12,0x98,0xCC,0xB7,0x12,0x1D,0x9B,0x37,0x59,0x49,0x60,0x71, +0x7D,0x34,0x7B,0x94,0x7C,0x1E,0xD2,0x73,0x0F,0xF6,0xE5,0x42,0x21,0x69,0x51,0xDB, +0x5D,0x08,0x71,0xF7,0xB1,0x00,0x94,0xCA,0x42,0xA1,0x3F,0xE3,0x5A,0x76,0xF0,0x99, +0xC4,0x19,0x92,0x6E,0xD4,0xAA,0x0D,0x5E,0xF7,0x22,0x79,0x02,0x48,0x6E,0xDF,0x4A, +0x07,0xE3,0xBC,0x33,0x9D,0x03,0x3E,0x5E,0xE6,0xAA,0x45,0x74,0x7C,0x2D,0xA8,0x4B, +0xC6,0xBF,0x7A,0x07,0x61,0xEE,0x45,0x23,0xA9,0x09,0xB0,0x3B,0xBE,0x6C,0x3B,0xAA, +0x21,0x2F,0x93,0x17,0xFE,0x59,0x47,0x84,0x10,0xF4,0xE7,0x5D,0x71,0xA6,0xA7,0x58, +0x6E,0xA5,0x0B,0xAF,0xEF,0x4C,0x96,0x68,0x6D,0xD3,0xDA,0x45,0x57,0x98,0xD4,0xE9, +0xAE,0x34,0xE3,0xF2,0x0B,0xAB,0x41,0x44,0x41,0x40,0x42,0x35,0x8D,0xED,0x83,0x42, +0xA9,0x16,0xFE,0xF1,0xE0,0xBA,0x33,0x7F,0x59,0x56,0xA1,0x0D,0xDF,0x4C,0x31,0x59, +0x1E,0x69,0xB1,0x5F,0x19,0xB7,0x06,0xC4,0xA4,0x07,0x1E,0xFB,0x9B,0x6F,0xA8,0xA5, +0x9D,0x83,0x56,0x2A,0xFB,0x59,0xBE,0x08,0xBB,0x7D,0x2A,0xF0,0x2C,0x8F,0xD9,0x22, +0x5F,0x5A,0x1E,0xBA,0x97,0xEE,0x2B,0xFD,0xC8,0xCE,0x76,0x20,0x7F,0xE2,0x30,0xD2, +0x33,0x6C,0xB1,0x9B,0xD8,0x7C,0x8F,0x56,0x86,0xC9,0xE5,0xA3,0xBD,0xC4,0x32,0x41, +0xE4,0xE3,0x86,0xE8,0x01,0x2C,0xC8,0x13,0xF7,0xD4,0xC5,0x56,0xF0,0x67,0xC2,0xFE, +0x7D,0x77,0x40,0xA0,0xDD,0xED,0xA6,0x6C,0x40,0x4C,0xA2,0x50,0xA0,0x6A,0x02,0x20, +0x00,0x63,0xB4,0x03,0x3B,0x4D,0xD7,0xC4,0xA1,0x14,0x60,0xB8,0x7C,0xE9,0x27,0xF0, +0x78,0x08,0x42,0x7B,0xCE,0x32,0xAE,0xD3,0x86,0x03,0x43,0x4B,0xBD,0x3B,0x3E,0xF1, +0xB2,0xB6,0x30,0xD2,0xE3,0x1A,0x0C,0xFF,0x7B,0x68,0x02,0xBE,0xB4,0x23,0x0F,0xBC, +0xCD,0x8B,0x31,0x20,0x2A,0x6F,0x56,0x21,0xAA,0x7D,0x6A,0xB1,0xDF,0x0D,0x84,0x63, +0xCB,0xBF,0x8E,0x64,0x15,0x49,0x40,0xCA,0x93,0x77,0x0C,0x9B,0x1D,0x27,0x16,0x19, +0x42,0x51,0x67,0xA2,0x76,0x7A,0xFF,0xB9,0xC8,0x81,0xA5,0x51,0x1F,0x1E,0x92,0x99, +0x82,0xB8,0x2B,0x15,0xCD,0xAC,0xA8,0x3B,0x3C,0x2F,0xEC,0x07,0x2C,0xEC,0x9C,0x86, +0x37,0x29,0x87,0xE3,0xCC,0x50,0x06,0xE4,0xC9,0x20,0xDD,0x3A,0xEB,0x6D,0xEA,0x0A, +0x23,0xED,0x00,0x48,0xA0,0x5A,0x56,0x0E,0x1C,0x50,0x71,0x96,0xFF,0x8F,0x66,0xED, +0xB7,0x56,0x62,0x59,0x2D,0x82,0x8B,0xC3,0xC8,0x41,0xA9,0x0A,0x30,0x89,0xC6,0xDB, +0xC9,0x9F,0x89,0x39,0xB9,0xE8,0xD2,0xA1,0x62,0x94,0xF5,0xA1,0xD6,0x3A,0xD3,0x92, +0xD5,0xC2,0x76,0x6E,0x34,0xA6,0x4D,0xAD,0x86,0x0D,0xBE,0xD6,0x67,0xD2,0xF8,0x0C, +0x4A,0x9A,0x04,0x1D,0x10,0x13,0xD7,0x77,0x8C,0x51,0xCD,0xF0,0x52,0x2E,0xE7,0x54, +0xF7,0x19,0xA8,0xBA,0x6D,0x79,0x27,0x88,0x38,0xB6,0x6B,0x7F,0xDF,0x94,0x5F,0xFB, +0xEF,0x4F,0x02,0xC4,0xAC,0xD5,0x6D,0x48,0xBE,0x78,0x4A,0x24,0xE5,0x62,0xAD,0x13, +0x6E,0x74,0xD0,0x1A,0x1B,0xA7,0x6F,0x7F,0x53,0x09,0x3D,0x49,0x86,0x7C,0x5A,0xF9, +0x73,0x31,0x92,0x0A,0x96,0x0C,0x34,0x09,0x4E,0x3C,0x3D,0x11,0xA1,0xF9,0x74,0xF2, +0x94,0xDC,0x4C,0x76,0xF0,0x90,0x8A,0x90,0xF7,0x66,0x33,0xAE,0x00,0x15,0x7F,0x52, +0x54,0xF3,0xB1,0x6E,0xBA,0x46,0xC9,0xD2,0x72,0xFF,0xF5,0x61,0x9E,0xC5,0xFD,0xDE, +0xCC,0xE3,0x3D,0x05,0x66,0xF9,0xC8,0x2E,0x44,0x03,0x45,0xA1,0xE5,0xBA,0x86,0x23, +0xEE,0xEC,0x37,0x77,0xC3,0x9C,0xA8,0x41,0x70,0x4B,0x49,0x2B,0x92,0x45,0x83,0xCD, +0x6C,0x50,0x4A,0x70,0xF1,0x2C,0x3F,0xCF,0x4C,0x87,0x42,0x6B,0x57,0x6F,0x8E,0xBC, +0x75,0x78,0x8B,0x30,0x20,0x17,0xAA,0x13,0x57,0xA5,0xD0,0x27,0x72,0xC5,0xAC,0x99, +0x29,0x2D,0xA9,0xEF,0x31,0x8D,0x21,0x1D,0xC5,0x9A,0x5A,0xE5,0x42,0xE0,0x0B,0xB1, +0x5A,0x5B,0x66,0x47,0x0B,0xD5,0x96,0x7F,0x6B,0x8C,0x58,0xBD,0x0E,0x47,0x89,0x52, +0xB9,0x0F,0xFF,0x84,0x70,0x0D,0xF2,0xFD,0x40,0xAD,0xED,0x49,0x39,0x55,0xF8,0x15, +0x65,0xD6,0xA4,0x53,0x9F,0x7E,0xCF,0x4C,0x84,0x8E,0xC5,0x03,0x48,0xD6,0x79,0xA9, +0x02,0x5A,0x8A,0x6F,0xC7,0xBB,0xF9,0xD5,0x5D,0x0D,0xF1,0xD3,0x7D,0xDB,0xC3,0x3D, +0x77,0xA7,0x72,0xB8,0x0B,0xD5,0x88,0x83,0x6C,0xBB,0xF7,0xAB,0xAC,0xAA,0x7B,0x34, +0x8C,0xB1,0xFA,0xF0,0xB8,0x55,0xFA,0x0F,0xF2,0xBF,0x86,0x80,0xDF,0x19,0xB2,0x54, +0xDB,0xBB,0xD9,0xB3,0x57,0xA9,0x42,0x20,0x54,0xA6,0xB3,0x35,0xB6,0x07,0x16,0x34, +0x70,0xBB,0x43,0xF3,0x95,0xAE,0x35,0xA5,0x92,0xAE,0x40,0x8F,0x2C,0x4B,0x17,0x02, +0xC6,0x13,0x9E,0xD1,0xEE,0x4C,0x72,0x74,0x06,0x3E,0x1B,0xB5,0xFB,0xDC,0xD6,0x70, +0x4E,0xF4,0x6C,0x0A,0x65,0x7E,0xD3,0xE0,0xD4,0x45,0xA0,0x8A,0x56,0x05,0xA7,0x47, +0x7A,0x01,0xC8,0x53,0xCC,0x7D,0x5E,0x90,0x5E,0xF7,0x1E,0xB0,0x25,0xBE,0xA8,0xF1, +0x6D,0x96,0x90,0xB0,0xCA,0x06,0x2A,0xD9,0x75,0x0A,0x7C,0x2C,0x86,0x23,0x4C,0xB7, +0x05,0x4D,0x17,0xA1,0x0F,0xB4,0x6E,0x14,0x6D,0x9E,0x05,0x28,0xE6,0x30,0xF4,0xDB, +0xA9,0x6D,0x6C,0x2C,0xBC,0x45,0xA9,0x60,0xDB,0xA6,0x74,0x2A,0x1D,0x03,0x7E,0xC3, +0xB3,0x62,0x56,0x71,0x9B,0x64,0xA5,0x11,0xDA,0xFC,0xF8,0xB2,0xFC,0x4D,0xEB,0x81, +0xA8,0x2E,0x6B,0xEF,0x8F,0x1A,0x33,0xD6,0x08,0x61,0x4D,0xFE,0x34,0xB0,0x2F,0xC3, +0x4C,0xEA,0xF7,0xE7,0xA9,0x4D,0x07,0x16,0xEC,0x31,0x80,0x2E,0x02,0x10,0xBF,0xBC, +0x45,0x9D,0xBA,0xE6,0x73,0xBF,0xCC,0xAD,0x9C,0x55,0xE2,0x30,0xAF,0x5F,0x57,0x66, +0x3B,0x0D,0xEF,0xEA,0x0C,0x5F,0xB5,0x90,0x40,0x4D,0xD6,0x5C,0xDD,0xED,0x56,0x11, +0x66,0x75,0x2B,0x7D,0x5D,0x1E,0xD5,0xE2,0xC1,0x99,0x84,0x83,0x97,0xF4,0x3F,0x18, +0xC4,0x78,0xDB,0x98,0xC0,0x9D,0x3E,0x6E,0x51,0x39,0x42,0x8A,0x15,0x04,0xF8,0x34, +0x1F,0x24,0x55,0xDC,0x5B,0x6F,0x93,0xC6,0x46,0x21,0xBD,0xEB,0xBC,0x87,0x53,0xE3, +0xC4,0xAD,0xDD,0xE7,0xBA,0x84,0xCA,0x52,0x4C,0xB2,0x93,0x60,0xAF,0x85,0x59,0xDC, +0x01,0xD7,0x50,0x6E,0x25,0xB4,0x6C,0x71,0xB3,0xE2,0x70,0xDA,0x08,0x76,0x0F,0x66, +0xAC,0x6A,0x78,0x65,0x13,0xD3,0x7C,0x56,0x85,0xBC,0x3A,0x2B,0x8E,0x91,0x6A,0x9E, +0xE0,0x07,0x86,0x97,0x32,0xF9,0xD9,0xD6,0x79,0xAD,0xCE,0x61,0x62,0xBE,0x87,0x28, +0x83,0x5D,0x87,0xA5,0x46,0xEA,0x2F,0x8E,0xE8,0x23,0x94,0x92,0x7A,0x8D,0x83,0x9F, +0xC4,0x18,0x2F,0x71,0x89,0xA4,0xB1,0xF3,0x40,0xCD,0x64,0x9E,0xBF,0x3A,0xF5,0x7C, +0xB4,0x7C,0x27,0xB2,0xF3,0x8D,0x4D,0x55,0xFA,0xC1,0x06,0x49,0xA5,0x4C,0x87,0xB5, +0x6F,0x7E,0xF1,0x09,0x31,0x1F,0x70,0x21,0x92,0x4F,0x27,0x21,0xD8,0x6F,0x49,0x71, +0xBE,0xDD,0x5A,0x15,0x3B,0x9A,0x35,0x34,0xC8,0x62,0x87,0xDA,0x84,0xBD,0x28,0xA6, +0x47,0xA8,0xB2,0x43,0x06,0x8B,0x30,0x08,0xFE,0x76,0x1D,0x6F,0x8A,0xCC,0xF3,0x0A, +0x85,0xC4,0x9D,0x7F,0xE6,0xCE,0xA6,0x3A,0xA1,0x41,0x3A,0xD4,0x1D,0x81,0xA0,0xF1, +0xBC,0xC1,0x3D,0x07,0xF0,0xF4,0xA0,0x7B,0x76,0x6F,0x83,0x4B,0xEA,0x98,0xCE,0xB6, +0xFE,0xF9,0x41,0x56,0xCC,0x97,0x38,0x3A,0xF3,0x89,0x2A,0x01,0x6A,0xFC,0x31,0x8D, +0xD0,0x1D,0x74,0xDE,0xF3,0xB8,0x22,0x1D,0x4A,0xB3,0xDD,0x57,0x8E,0x20,0xAC,0xC9, +0x40,0xCF,0x36,0x32,0xD3,0xC2,0x56,0xF6,0xB1,0x36,0xCB,0x2D,0xAB,0x30,0x41,0x6C, +0xA7,0xFB,0xC5,0x21,0x13,0x70,0x50,0x50,0x62,0x99,0xC0,0xC4,0xE3,0x1D,0xD8,0xB3, +0xAA,0x00,0x84,0x10,0xC5,0x6A,0x81,0x6D,0x7D,0x8B,0x9B,0xB3,0x01,0x72,0x7B,0xDF, +0xF2,0x44,0xC2,0xDD,0x71,0x61,0xDF,0x23,0x25,0x53,0x5D,0x1A,0xDF,0x9C,0xAC,0xAF, +0xAE,0xB3,0xD2,0x76,0xAA,0x20,0x50,0x25,0xD9,0x49,0xA4,0x00,0x48,0x13,0x82,0xBF, +0x8E,0x99,0xCD,0xBF,0xDC,0x00,0x18,0xE9,0xCD,0x8C,0x2D,0x36,0x89,0x30,0x91,0x6A, +0x68,0xB8,0xC2,0xE9,0x60,0xDF,0x80,0xEB,0x0C,0x89,0xF3,0x10,0xA1,0x27,0x11,0xB0, +0xBF,0x93,0xCF,0xE2,0xEF,0x0D,0x4C,0x10,0xE3,0xB0,0x99,0x9B,0x9E,0xAB,0x67,0x7E, +0x85,0x41,0xC1,0xE7,0xE3,0xAC,0x58,0x69,0x0A,0xD6,0x94,0xC1,0x3F,0x75,0x62,0x3E, +0x95,0x34,0xCC,0x71,0x9C,0x02,0xD8,0x6B,0x92,0xB0,0xBA,0x2D,0xFF,0x0F,0x51,0x4A, +0x15,0x98,0x1E,0x91,0xE6,0xDB,0x0A,0xDB,0x6B,0xAD,0x95,0xA3,0xF0,0xCB,0x49,0x1F, +0xFB,0x89,0x3B,0xAF,0xC1,0x53,0x97,0xE5,0xB7,0x41,0xB9,0xF5,0x84,0x61,0xEF,0x89, +0x97,0x23,0x0A,0x28,0xC7,0xAC,0x7A,0x50,0xC1,0x2C,0x43,0xA2,0xEC,0xB3,0x0D,0x73, +0x3D,0xAA,0x39,0x23,0xE0,0x3F,0xFE,0x50,0x84,0x50,0x90,0xB7,0x0D,0x37,0x04,0x27, +0x46,0xC0,0xD6,0xD7,0x70,0x53,0x75,0x57,0xB5,0xFF,0x46,0xA9,0xF4,0xFC,0xC3,0xBD, +0xC7,0xF7,0x67,0x75,0x71,0xBE,0x04,0x4A,0x63,0xB4,0xE9,0x26,0xD9,0xBE,0x1F,0x13, +0xDB,0xEA,0xCA,0xD9,0x00,0xE1,0xB5,0xB4,0xE0,0xDC,0xDD,0xE0,0x1C,0x43,0x66,0x01, +0x12,0x0A,0xB9,0x1E,0x5B,0x84,0x82,0x60,0x1D,0x55,0x4D,0x31,0x91,0x08,0x0D,0xEA, +0x98,0x90,0x54,0xAA,0x73,0xB2,0xB4,0x1A,0x9F,0x8D,0x10,0xAD,0x38,0xCB,0x51,0x72, +0x02,0xFD,0x1C,0x27,0x92,0x9A,0x87,0x6F,0xFD,0x48,0xF3,0x57,0xF1,0xF6,0x27,0x75, +0x19,0x5E,0xA5,0x5F,0x36,0xA6,0x32,0x24,0x79,0x57,0x26,0x59,0x7D,0x47,0xE2,0xB5, +0xBA,0x66,0xB2,0x19,0x0E,0x3F,0x41,0x03,0xE1,0x2A,0x9B,0x2C,0xE0,0x53,0xF6,0x6D, +0x90,0xC4,0xA3,0xF7,0x1C,0xED,0x83,0x6E,0x80,0x74,0x2B,0x77,0x52,0x60,0x7F,0xD4, +0xAE,0xD6,0x7C,0x9E,0x02,0x64,0xA4,0x1B,0x8A,0xFE,0xEF,0x60,0x46,0xAE,0x3F,0xA4, +0x03,0x81,0xC5,0x12,0x0D,0x2E,0x9F,0x70,0x4C,0xBE,0xFD,0x29,0xDC,0x79,0x5C,0x63, +0x4D,0x71,0x84,0x89,0x94,0xF9,0x0E,0x5D,0xF0,0x1C,0xCE,0x34,0xF4,0xBF,0x5F,0xF4, +0x31,0xBE,0x09,0x43,0xEB,0x59,0xD8,0x46,0xE0,0x17,0xE7,0x27,0x1E,0x3C,0x88,0xD8, +0x0F,0xA6,0x4A,0x63,0xA3,0xAC,0x80,0x5E,0x23,0x85,0x5E,0x33,0x8A,0x70,0x0B,0x78, +0xBD,0xB7,0xA1,0x3F,0x78,0xD5,0x9C,0x23,0xE9,0xE9,0x9F,0xA3,0x0F,0xAF,0xF7,0x9C, +0x40,0x8C,0x5F,0x5F,0x1B,0x03,0xEB,0x9D,0xDB,0x61,0x41,0x16,0x1A,0x1C,0x23,0x87, +0xD6,0x2F,0x9F,0x73,0x7C,0x7F,0x7C,0xFA,0xBE,0x00,0x45,0xF4,0x74,0x02,0x50,0xC5, +0xB4,0x16,0x4C,0xD3,0xE6,0x43,0xDC,0xDB,0x71,0x14,0x96,0x71,0xF7,0xDA,0x84,0x57, +0x9E,0x1E,0xD5,0x07,0xFC,0x01,0xA9,0x35,0xE2,0x58,0x12,0x22,0xD4,0xB3,0x54,0x51, +0xA5,0x52,0xB1,0x14,0x04,0x54,0x56,0x5C,0x35,0x70,0x5E,0x16,0x6A,0x29,0xDD,0xB8, +0x31,0x8E,0xB1,0xD5,0xAA,0x78,0x14,0xDA,0x64,0x4F,0x6B,0xF7,0xA3,0xDF,0x5C,0x81, +0x9D,0x55,0xFF,0x5F,0xA5,0x91,0xB3,0xFB,0x7A,0xB2,0x97,0x90,0x53,0xB5,0x4E,0x95, +0x65,0xE0,0x60,0x5E,0x8D,0x4A,0x89,0xB7,0xC4,0x0D,0xAE,0xAB,0xEF,0xE7,0xF2,0x15, +0xD5,0x81,0x56,0xF5,0x2A,0x76,0xA6,0xB8,0x50,0xAE,0x70,0xDC,0xBD,0x68,0x31,0x01, +0xC3,0xB5,0xB3,0xBB,0xA7,0xFD,0x4A,0x5D,0xA0,0x59,0xC2,0x67,0x0C,0x99,0x85,0x4D, +0x1C,0x4A,0x57,0x6D,0xA3,0xB5,0x98,0x38,0x49,0x03,0x08,0x73,0x1D,0x57,0xB1,0x28, +0x28,0xA6,0x30,0xB6,0x89,0xEB,0xE9,0x39,0x4F,0xEE,0xA7,0xA0,0x4E,0x00,0x82,0xED, +0x18,0xAA,0xD7,0x75,0x9E,0xD4,0x8C,0x81,0x04,0x2C,0x92,0xDC,0xF0,0xCC,0x09,0x1F, +0x93,0x3B,0x62,0x4F,0x70,0x66,0x29,0xFB,0xAC,0x68,0xCB,0x17,0xAD,0x56,0x6F,0xB8, +0xDB,0x4A,0x4D,0x13,0x1A,0x6D,0x88,0xB7,0xB6,0xAE,0x06,0x79,0x50,0x43,0x5C,0xBF, +0x5D,0x3C,0xD5,0x0A,0xDA,0x4F,0xDC,0xA4,0xB9,0xC5,0x8C,0xBF,0xCC,0x8D,0x05,0x68, +0xA3,0x13,0x05,0xFC,0x50,0xD4,0x2D,0x2A,0x29,0xFB,0xB2,0x3A,0x95,0x51,0x2F,0x6C, +0x6A,0x19,0xE5,0x2B,0x1C,0xC0,0xC4,0xF6,0x9D,0xF0,0x00,0x38,0x69,0xA5,0x58,0xAD, +0xE4,0xD8,0x48,0x53,0x73,0x45,0x36,0x11,0x86,0x48,0xD4,0x1F,0x85,0xFF,0xA3,0xEB, +0x68,0xEE,0x71,0xD5,0xE9,0x7F,0x93,0xB0,0x92,0x4A,0x7E,0xC6,0x20,0x8E,0xA3,0x5E, +0xD3,0x61,0x2A,0x96,0xAC,0xF8,0x2A,0x51,0xC2,0xA3,0xB2,0x06,0x00,0x5F,0x9E,0x90, +0xAD,0x49,0x4E,0x43,0xC2,0xD2,0x95,0x7C,0xCF,0x3A,0xC4,0x11,0x09,0x4B,0x44,0xA2, +0x34,0xE9,0x18,0xBC,0xAC,0xEA,0xF3,0x7D,0x99,0x17,0xFF,0xE5,0xD2,0x3A,0x22,0xEF, +0x9C,0x0D,0xA1,0x99,0xE3,0x1C,0x58,0xFE,0xBC,0x06,0x6F,0xB2,0x89,0xD7,0x48,0xB6, +0x4D,0xC3,0x20,0xFD,0x13,0x57,0x4D,0x56,0x03,0xB4,0x5E,0x97,0x5E,0xFF,0xF0,0x7F, +0xDF,0x19,0xC0,0x2E,0xC5,0x47,0x2B,0x27,0x76,0x7F,0x55,0x3A,0x3A,0xD9,0x23,0xBC, +0xDB,0x3D,0x0D,0x96,0x52,0xF4,0xDC,0xE9,0x96,0xA1,0xD3,0x7C,0x41,0x8A,0x47,0x0C, +0x7E,0xF9,0xD1,0x2F,0x25,0x3B,0x4C,0x78,0x9E,0xA2,0x13,0x18,0x5A,0xC3,0x8B,0x65, +0x36,0x3B,0x75,0x00,0xB0,0x16,0x90,0x17,0x61,0xEE,0x3B,0xC8,0x9F,0x53,0x9F,0x06, +0x3C,0xE6,0x5F,0xB0,0xC4,0x22,0xFB,0x64,0x0A,0x11,0x99,0xEA,0xD5,0x46,0x51,0xB7, +0x3C,0x7A,0xF8,0x94,0x9F,0x41,0x7A,0xA8,0xD6,0xC8,0x37,0x82,0x1D,0x58,0x8B,0x04, +0xBD,0xB2,0x93,0xE9,0x2E,0x0D,0x63,0x19,0x6F,0xE4,0x66,0xED,0xFB,0xD3,0x56,0x16, +0xB3,0x50,0x03,0x71,0x92,0xE8,0xD6,0x8C,0xA9,0xC3,0x91,0xC7,0xC5,0xDA,0x79,0xEB, +0x6F,0x45,0x1A,0xA2,0xB1,0x6E,0x80,0xD4,0x73,0xF6,0x54,0xB1,0x05,0xF3,0xCF,0xF9, +0x66,0x0B,0xB8,0x23,0x8C,0xDE,0xE8,0xE1,0xA8,0x2E,0x4B,0xBA,0x88,0x8C,0x89,0x69, +0x0D,0x2A,0xFA,0x12,0xDA,0x1C,0x6C,0x69,0xED,0x65,0x38,0x28,0x9F,0x01,0x60,0xA7, +0x24,0x34,0xC4,0x9E,0x7C,0xFB,0xF2,0x96,0xE4,0x71,0x18,0x9E,0x00,0xE9,0xFA,0x6F, +0xB6,0x3C,0x1D,0xFA,0x5D,0xF8,0x1D,0x0B,0xBF,0x58,0x2F,0x65,0xE8,0xCC,0x94,0x98, +0xA7,0x19,0xCE,0x1A,0xE1,0xBF,0x44,0xFD,0x88,0x14,0x38,0xAD,0xCE,0xE2,0xEF,0xA8, +0xAE,0x22,0xAD,0x66,0x83,0x21,0x7D,0xB3,0x6D,0x19,0x14,0x05,0x92,0x46,0x66,0x79, +0x11,0xEE,0x1B,0x93,0x31,0xC5,0x3D,0x62,0xF2,0x62,0xDC,0x83,0xE0,0x3F,0x6E,0x7F, +0xEA,0xEA,0xB3,0xA0,0x2A,0xEE,0x5C,0x04,0xEF,0xD7,0x29,0x85,0xE4,0x55,0xA1,0x75, +0xE1,0x33,0xBC,0xD2,0xA2,0x87,0x31,0xAF,0x9A,0x15,0x3F,0x19,0x38,0x16,0xFE,0x52, +0x64,0xE8,0x5D,0xEB,0xC7,0xE9,0x69,0xA5,0x0D,0x9D,0xBE,0x32,0xB9,0x83,0xF4,0x64, +0xBC,0x86,0x2F,0x14,0x14,0x2F,0xFF,0xF3,0xD6,0x91,0xAC,0x2C,0x2B,0x24,0xBA,0xEE, +0x98,0x66,0xD6,0x02,0xD1,0x76,0xB9,0x71,0x9C,0x28,0x1C,0x86,0xAF,0x68,0xEB,0xF7, +0x09,0xA9,0x6F,0x65,0x71,0x7B,0xCB,0x6A,0x0B,0xA7,0xC0,0xD6,0xFB,0x2A,0xF8,0x25, +0x64,0xD0,0x70,0xC5,0x74,0x58,0x2D,0x44,0xA8,0x91,0x02,0x9A,0x1E,0xBC,0x27,0x2F, +0x89,0x25,0xA7,0x04,0x17,0xB2,0x17,0x96,0x24,0x49,0x73,0xC2,0x56,0x3E,0x84,0xCB, +0x5B,0x41,0x63,0x9E,0x0A,0x06,0xBF,0x83,0x8E,0x10,0x1F,0x85,0xF7,0x07,0x59,0xDE, +0xED,0x5E,0x92,0x47,0xE4,0xD1,0x7A,0x78,0xE4,0x61,0xB9,0x04,0x4E,0x03,0x83,0x51, +0x7F,0x7E,0xE1,0xE4,0x61,0x96,0x7F,0x74,0x05,0x81,0xD0,0xB5,0x0E,0x55,0x0B,0x51, +0x58,0xEF,0x79,0xDA,0xF5,0x07,0x52,0xAD,0x76,0x39,0xEF,0xE5,0x91,0xAF,0x53,0x33, +0x53,0xAF,0x6C,0x40,0xB6,0x54,0x5E,0x92,0xEE,0x7B,0x12,0x74,0x3B,0x7A,0x4A,0xE1, +0x4C,0xF2,0x85,0x2F,0x4F,0xEC,0xCC,0x22,0xE5,0x5E,0xA6,0xA1,0x91,0x0C,0x7C,0x1C, +0xFE,0x01,0x86,0x7A,0xD9,0x37,0x62,0x81,0xB3,0xC4,0xF3,0x82,0x31,0x2C,0x27,0xEF, +0xF8,0xB8,0xA4,0xEB,0xCC,0xFC,0xBE,0x55,0x2A,0xB6,0xA4,0x13,0x07,0xE7,0xD4,0xEC, +0x93,0x8C,0xA1,0xA8,0xEC,0x99,0xB5,0xDA,0x8F,0xEA,0x56,0xAC,0xDA,0x6C,0x6E,0x32, +0x4F,0xFC,0xE9,0xD6,0x12,0x0D,0x03,0xC5,0x84,0xB8,0xA0,0x5C,0xC7,0x14,0xFB,0xE6, +0x9C,0x10,0xB2,0xBB,0x85,0x8D,0x27,0x20,0x7E,0xD0,0x05,0x36,0x5C,0x86,0xF7,0xED, +0x67,0x90,0xE5,0x2E,0xC3,0xDB,0xFC,0x28,0x73,0x90,0x6B,0xFC,0xF9,0xFF,0xC6,0x37, +0xDD,0xCE,0x13,0x03,0xBF,0x57,0xFC,0x87,0x32,0x92,0x32,0x8B,0x8D,0x6D,0x56,0x8F, +0x1D,0xE8,0xA8,0x82,0x54,0x4C,0x35,0x9A,0xBB,0xDC,0xDE,0xEA,0x7F,0x2C,0x7F,0x27, +0x72,0x43,0x96,0xE9,0xEB,0x0D,0xA2,0xE8,0x12,0x5C,0x3C,0xF8,0x83,0x45,0xBB,0xA0, +0xFB,0x61,0x4F,0x68,0x55,0xA1,0xDE,0xF2,0xEB,0xAA,0x9B,0xB6,0xB2,0x8D,0x58,0x23, +0x51,0x2D,0xC0,0x5B,0x7B,0xC6,0x25,0x1A,0xE4,0x23,0xE0,0x53,0x9A,0x3C,0xBA,0x0A, +0xCC,0x99,0x9A,0xEE,0x2F,0x15,0xEC,0xFC,0x4A,0xE0,0x64,0x6D,0xFD,0x75,0x1F,0x38, +0xED,0x44,0x30,0x03,0x8B,0x94,0x11,0x0E,0x68,0x32,0x4C,0x98,0x1A,0xD8,0xF7,0xEA, +0x0A,0x01,0xC0,0x4B,0x84,0x3D,0xE7,0xA9,0x3D,0x2A,0x41,0x95,0x72,0xB2,0x52,0xE7, +0x96,0x15,0xF6,0xD6,0x2F,0x80,0xB5,0xF4,0x08,0x2A,0x84,0x7D,0x86,0x92,0xFF,0xD2, +0x88,0x45,0xE6,0x58,0x80,0xCA,0xB0,0x4F,0xA3,0xEE,0xAD,0x2B,0xE9,0xC4,0xB2,0x74, +0x07,0x31,0x1D,0x42,0x1A,0x9F,0x44,0xC4,0xB9,0xCB,0x1C,0x6B,0xEE,0x5F,0xFB,0x95, +0x7D,0x74,0x8D,0x6C,0x36,0xAB,0x8F,0x9B,0x8F,0x3C,0x2B,0xC3,0xFC,0x03,0x1A,0x11, +0x6B,0x7E,0x4B,0x33,0x84,0xE5,0xE3,0x5A,0x35,0xC3,0x05,0x3D,0x37,0xD4,0xD5,0x33, +0x32,0x8C,0xE3,0xCD,0xFB,0xD8,0x4F,0x08,0xF0,0xF8,0x10,0x0F,0xD5,0xDD,0x54,0x95, +0x80,0xD6,0x77,0x43,0x15,0x27,0xD1,0x78,0x41,0xEE,0x6A,0x3F,0xE2,0x53,0x05,0xF2, +0xC5,0xF0,0x2F,0x6D,0xF9,0x43,0xB5,0x41,0xB1,0xCC,0x59,0x6D,0x4E,0x12,0xBC,0x45, +0xB0,0x4F,0xA0,0x62,0xDB,0x03,0x1B,0xAB,0x46,0xE2,0x50,0x8C,0xC2,0xDA,0xE9,0xF5, +0x83,0xC1,0x17,0xF0,0x0F,0x72,0x95,0x3F,0x80,0x0A,0x4F,0x17,0x7C,0x79,0x07,0xB0, +0x3D,0x31,0x1B,0xD9,0xF2,0xA9,0x78,0xF2,0xA4,0x75,0x58,0x78,0xA0,0x3B,0xE6,0x18, +0xC7,0x57,0xD2,0x03,0xD4,0x8F,0xEA,0xD4,0x8B,0x1F,0xEA,0x4B,0x5B,0xA8,0x86,0x0C, +0xEE,0xE7,0x98,0x34,0x08,0xC2,0x4D,0x14,0xFD,0xBE,0x09,0x30,0xCD,0xFE,0x95,0x34, +0xCD,0x18,0x13,0x34,0x84,0xF2,0xD3,0x00,0x90,0x59,0xBB,0xA8,0x0B,0xFA,0x25,0xDC, +0xD4,0xC6,0xCA,0x3E,0x7D,0xBE,0x0E,0xBC,0x39,0x7B,0x86,0xBF,0x79,0x2C,0x5D,0x2C, +0x8D,0x1F,0x38,0xDA,0x13,0xC0,0xC1,0xB9,0x34,0xBD,0xD5,0x38,0xC8,0x5B,0xA7,0x57, +0x50,0xCF,0x17,0x87,0x7A,0x30,0x31,0x1D,0xD9,0x2F,0x5A,0xA5,0xF9,0x64,0x3B,0x14, +0xB2,0x4A,0xE3,0x5D,0xC0,0xC1,0x2F,0x1F,0x24,0xE5,0x01,0x4C,0x10,0x00,0x12,0x1B, +0x26,0x57,0x6C,0xB1,0xFF,0x07,0x4D,0xDA,0x19,0x64,0x73,0x05,0x33,0x46,0x42,0x92, +0x2A,0x98,0x8E,0x2F,0xFD,0x19,0x19,0x28,0x77,0x0D,0xB8,0x76,0x6A,0x97,0xD7,0x26, +0x0E,0xC6,0x89,0x00,0xDB,0xEC,0x75,0x40,0x1F,0x64,0x00,0x95,0xB6,0xD4,0xD2,0xA4, +0xE4,0xA3,0x5E,0xA5,0x40,0x23,0x22,0xC2,0xCC,0xB5,0x3D,0xAB,0x9A,0x64,0xD5,0xBA, +0xED,0x61,0xFC,0xCF,0xAC,0xD4,0x1D,0x3B,0x4B,0xD1,0xD9,0x36,0xF9,0xE9,0xDD,0x0F, +0x5E,0x48,0x54,0x9E,0x0D,0x33,0xAA,0x28,0x37,0xDF,0xC6,0x66,0xFB,0xC1,0xFC,0xD4, +0xE3,0xDF,0x00,0xF5,0xA9,0x14,0x7B,0x2F,0x58,0xEA,0xBF,0x5F,0xEE,0x7F,0x08,0x25, +0x2D,0xB5,0x97,0xEF,0x56,0x64,0x45,0x00,0x37,0xFF,0xA6,0x6F,0xC9,0xAB,0x2B,0x51, +0x98,0x13,0xC5,0xAD,0xE2,0x65,0x39,0x4B,0xBA,0x84,0x69,0x61,0x29,0x26,0x1F,0x86, +0xE5,0x8B,0xD6,0x8A,0x64,0x97,0x3A,0x20,0x22,0xB6,0x8B,0xA4,0x8D,0xA0,0x7C,0xA6, +0x8E,0x76,0xDF,0x2A,0x14,0xC1,0xCA,0xEF,0xF4,0xB0,0x46,0x3E,0x95,0x6F,0x90,0x64, +0x24,0x03,0x7A,0xEE,0x6C,0xE6,0xFA,0x1F,0xE1,0x97,0x5D,0x6D,0xA4,0xD0,0x03,0x41, +0x8E,0xEC,0x1B,0x5A,0x0E,0xDB,0x20,0x63,0xFA,0xD3,0x45,0x5D,0xBF,0x79,0x0C,0xA0, +0xA3,0x7F,0xB9,0xF6,0x17,0xD3,0xAE,0x05,0x54,0xFE,0xBF,0xDB,0x88,0xF2,0x26,0x3E, +0x92,0x25,0x8B,0x83,0x49,0x83,0x5C,0x7B,0xB2,0x5E,0xDD,0x68,0x33,0xE5,0xAF,0xD9, +0x35,0xBA,0xE0,0x91,0xA2,0xFC,0xC5,0x1F,0x77,0xD4,0x8F,0x80,0xDF,0xA6,0xC4,0x25, +0x1B,0x03,0xB2,0x79,0xC2,0xB1,0xD6,0x75,0xB6,0x66,0x8A,0x1A,0xD5,0xAB,0x57,0x48, +0x87,0x51,0x07,0xB0,0x05,0xE6,0x84,0xF2,0xBC,0xB1,0x6B,0xC6,0x2C,0xA4,0x32,0x75, +0x42,0x1B,0x77,0x27,0x28,0x61,0xDA,0x81,0x33,0x57,0x68,0x68,0x9D,0x09,0xC9,0x7E, +0x73,0xA9,0x98,0x7C,0x53,0x3F,0x03,0xFD,0x59,0x50,0xEC,0xF9,0x90,0x76,0xE1,0x85, +0x81,0x1A,0x2C,0x25,0x27,0xEB,0xE5,0x76,0x76,0x9B,0x47,0xE7,0x79,0x87,0x29,0x02, +0x09,0x87,0x76,0xD8,0xF3,0x6C,0x6B,0x5D,0x36,0xCC,0x34,0x46,0xD3,0x98,0xCA,0xC6, +0x11,0x1D,0x26,0x30,0x04,0xCD,0x0A,0xA1,0x66,0x56,0x7E,0xB5,0x8F,0xD5,0x89,0x90, +0xB7,0x22,0x9E,0x24,0xAC,0x8E,0xEE,0xDC,0xBC,0xA1,0x04,0x23,0x99,0xF9,0x31,0x2D, +0xA9,0x4E,0x1D,0xA4,0xF2,0x1A,0xF2,0xBC,0xBC,0x3C,0xC2,0xE6,0x20,0x1F,0x23,0x5B, +0xD9,0x39,0x0D,0xC6,0xE4,0xD7,0xDC,0x34,0x4B,0x63,0xBD,0x4E,0xF9,0x2F,0xF5,0xF3, +0xF9,0x6D,0xB5,0x99,0x0D,0x48,0x2B,0xAB,0x91,0x63,0x9B,0x1A,0xC4,0xCF,0x6A,0xD6, +0x33,0x14,0xEE,0xA4,0x80,0xF1,0x42,0xB9,0x08,0x07,0x0A,0xA5,0x01,0x59,0x6D,0xCB, +0xEE,0x44,0x4C,0xC9,0xBA,0xE6,0xB5,0x79,0x69,0x51,0xA2,0x1B,0xA9,0xB3,0x10,0x1B, +0x3F,0x52,0x9A,0x1E,0xA6,0x4C,0xEF,0xEA,0x49,0x1D,0xA1,0xF6,0xA8,0xB8,0x45,0x6C, +0x76,0x2F,0x12,0x9B,0xC5,0xBB,0xD8,0x55,0x33,0xED,0x85,0x10,0x5C,0x5F,0x03,0x7E, +0x90,0xFB,0xD4,0x1F,0x8E,0xE9,0x72,0x19,0xAC,0xD7,0x24,0x1E,0xB3,0xD3,0xCB,0xC2, +0x6E,0xA0,0x69,0xBA,0xDB,0xB3,0xC1,0x0B,0xDD,0x8D,0x6F,0x64,0xB4,0xA0,0x61,0x6A, +0x11,0x7A,0x37,0x3F,0xF7,0x9D,0x5B,0x09,0xEB,0x22,0xC7,0xF0,0xB4,0x2D,0x38,0xE4, +0x67,0x1D,0x86,0x60,0x1E,0x96,0x96,0x1A,0x4E,0xB1,0xBD,0xF8,0x3A,0xC7,0x4A,0xD9, +0x1C,0xD0,0x5B,0x8A,0x68,0x83,0x29,0xDB,0x2F,0x3D,0xE5,0x4F,0x39,0x6B,0x1E,0xDD, +0xF9,0xB8,0x19,0xF1,0x77,0xEA,0x69,0xB8,0xCB,0x8F,0xC4,0x1E,0xBE,0xFC,0x36,0xB5, +0x52,0x17,0x99,0x33,0x25,0x71,0x29,0x02,0xAF,0x12,0x9D,0xED,0xB5,0x4B,0x50,0x2D, +0xCA,0x3E,0x38,0xDB,0x97,0x83,0x34,0x15,0xEF,0x67,0x97,0xF0,0xA0,0xCC,0x1F,0x5E, +0x9A,0x9C,0x38,0x42,0x38,0x76,0x8B,0x2E,0x3A,0x42,0xBE,0x2C,0xC7,0xBD,0x41,0x24, +0x83,0x17,0xD3,0x2E,0xCF,0x9C,0x66,0x1D,0x1E,0x94,0xA3,0xD3,0xC7,0x69,0x1A,0x81, +0x7B,0x92,0xE8,0x51,0x0B,0x3D,0x8B,0xE3,0xD5,0xF4,0xCC,0x9D,0xC0,0xFD,0x2A,0x89, +0xF7,0x37,0x42,0xCE,0xAF,0x3B,0xB7,0xD4,0xC9,0x57,0x8D,0x1E,0x50,0x1C,0xBA,0x41, +0xE7,0x6D,0x7E,0x5B,0x9B,0x46,0xA5,0xFE,0x62,0x7C,0x28,0x5D,0xB2,0x8A,0x2E,0x30, +0x4E,0x87,0xAF,0x0B,0x3C,0xB8,0x3B,0xF1,0x11,0xE2,0x90,0x5A,0xE7,0xF2,0x74,0x45, +0x10,0xF9,0x90,0x6B,0xE4,0x49,0x77,0x44,0xB4,0xFE,0xDC,0x59,0x57,0xAF,0x4D,0x56, +0x0B,0x56,0xD6,0x50,0x6C,0x31,0x90,0xF2,0x4D,0x90,0xBD,0xFE,0xD6,0x93,0x33,0xC8, +0x11,0x6E,0xE8,0x35,0xB4,0x43,0x42,0x6C,0x7A,0x3A,0xC8,0xF6,0xB3,0x70,0x3A,0x15, +0xB6,0x71,0x28,0xEF,0x68,0x6B,0x63,0x8A,0xEF,0x4C,0xD7,0xA4,0x90,0xB0,0xDB,0xCE, +0x79,0x8E,0x0D,0x84,0xA0,0xD9,0xD8,0xCF,0xE9,0x23,0x68,0x58,0x13,0xB0,0x88,0xA9, +0x5A,0xD2,0x5F,0x03,0xF2,0xC2,0x14,0xD8,0xFF,0x5E,0x5D,0xA8,0x9B,0xCD,0x26,0x11, +0xA9,0x73,0x1E,0xEE,0x71,0xF2,0x97,0x0F,0x0D,0xEB,0x24,0x15,0x2C,0x0E,0x49,0x56, +0xB7,0xEC,0x6E,0x02,0x3E,0x5A,0x3D,0xAD,0x3E,0x5D,0xDD,0xB6,0x8A,0xF4,0xF7,0xFD, +0x18,0xD6,0x69,0xF4,0xD6,0x1A,0x25,0x56,0xAD,0x53,0xCF,0x87,0xD3,0x87,0xB8,0xE5, +0xB2,0x9C,0xB3,0x3A,0x30,0xBD,0x8A,0x1C,0x43,0xFC,0x3D,0x87,0xAA,0x5A,0x61,0xCA, +0x5F,0xDD,0x71,0xA0,0x81,0x91,0xFF,0x67,0x6A,0xBA,0xB7,0x4E,0x89,0x39,0xA4,0xD2, +0xB5,0x33,0xAD,0x25,0xF3,0x8E,0xB7,0x3A,0x6F,0x4B,0xBA,0x3B,0x9C,0x70,0x78,0xB1, +0xF6,0xAB,0xB5,0xC0,0x9B,0x80,0x97,0xD8,0x8F,0x24,0xDA,0x1A,0xA0,0xD3,0x55,0xC3, +0x23,0xC3,0xE2,0x0C,0xE0,0x99,0xC2,0xF2,0x60,0xF7,0xF5,0x1A,0x8E,0xE3,0x45,0x77, +0xD2,0x4C,0xB2,0xE1,0x81,0xDB,0xC7,0x6C,0x76,0x96,0xAE,0xE7,0xF8,0x05,0xC5,0x62, +0x4E,0x39,0x43,0x32,0x0E,0xF3,0x67,0x48,0x50,0xB8,0x6A,0xF1,0xE2,0xBF,0x62,0x9A, +0x24,0x6C,0x9A,0x8C,0xDF,0x86,0xF5,0xF2,0x44,0xD5,0x73,0xDE,0xF5,0xD8,0xCD,0x50, +0xEB,0x97,0xA7,0xED,0xDE,0x57,0x4B,0xC0,0x98,0x0F,0x00,0x35,0x64,0x29,0x8F,0xCF, +0x78,0xFE,0x36,0x6D,0x86,0x58,0x1B,0xD8,0x11,0xC6,0x52,0x04,0x1E,0x44,0xB2,0xA6, +0x4B,0xAB,0xEE,0x16,0x61,0xB3,0xBB,0x47,0xCB,0x62,0xBF,0x91,0xB2,0x42,0x6E,0xB4, +0x0E,0x1D,0x91,0x15,0x9D,0xBC,0xAF,0xEF,0x05,0x5C,0x42,0xB1,0x37,0x4E,0x4D,0xCD, +0xBD,0x8A,0x2C,0xA3,0xAF,0x4C,0x9D,0xBE,0x78,0xE3,0x4B,0x77,0x77,0x1C,0xC0,0x48, +0x12,0x6D,0x61,0x7A,0x12,0xA4,0xAE,0x8B,0xED,0xAC,0xC8,0x07,0xB6,0x16,0x6F,0x2A, +0x27,0x93,0x1B,0xBA,0x34,0xA7,0x9B,0xFD,0xB4,0x43,0x08,0x83,0x0E,0xD4,0xC4,0xCF, +0x74,0x22,0x1F,0x48,0xF3,0xAA,0xD5,0xF2,0x4D,0xC3,0x29,0xC8,0xCC,0x61,0x05,0x8C, +0x8A,0xB6,0xB7,0x72,0x47,0x15,0x83,0x3F,0xD2,0x94,0xC0,0xFD,0xDD,0x49,0x8A,0x9E, +0x2B,0x56,0x20,0xAE,0xEB,0x04,0x53,0x52,0x6E,0xB8,0x18,0x65,0xCF,0x83,0xF8,0x87, +0xA0,0xD9,0xCB,0xAE,0xA4,0xBC,0xA1,0x28,0x89,0x6C,0x72,0xEF,0xD4,0x81,0x21,0x99, +0xF3,0xCE,0x1B,0x45,0x80,0xCE,0x4D,0xB9,0x4E,0x17,0x75,0x2D,0x48,0x6A,0x14,0xBC, +0xE8,0xDD,0xF7,0x8C,0xBE,0xCC,0x9F,0x55,0x4A,0xE2,0xDA,0x51,0xEB,0xDD,0x69,0x13, +0xA9,0x69,0xEC,0xD6,0x33,0xA3,0x28,0xC0,0x59,0x89,0xBE,0xCE,0xE2,0xF2,0x52,0x0C, +0x7D,0x97,0xD5,0x18,0x9D,0x52,0x58,0x2B,0x55,0x46,0x37,0x6B,0xCA,0xC5,0xFA,0xDD, +0x68,0x48,0x29,0xF8,0x9D,0x1F,0x10,0xA7,0x7C,0x89,0x69,0x58,0x2E,0xB4,0xA3,0x0F, +0xC5,0xEB,0xCC,0x5A,0x0C,0x9A,0x8F,0x4A,0x10,0xEC,0xB0,0x34,0x92,0x5B,0x7C,0x40, +0x39,0x93,0xA0,0xF1,0xBD,0x0A,0xCF,0x4F,0xB2,0x65,0x0B,0x88,0x2D,0xDA,0x21,0x5F, +0xB3,0x01,0xD5,0xEE,0xBB,0x4C,0x29,0x97,0xCE,0x50,0x2C,0x79,0xB2,0xE6,0xD4,0x55, +0xD9,0x82,0x2B,0xD6,0xA1,0x02,0x9F,0x6C,0xE1,0x5B,0x49,0x74,0xB4,0x4F,0x7B,0x56, +0x13,0x54,0x19,0xF6,0x18,0x09,0xAB,0x6D,0x2A,0x71,0xE2,0xAA,0x03,0x72,0x64,0xF2, +0x72,0xD1,0xE1,0x5E,0xC5,0x79,0x46,0xBA,0xFB,0x5E,0xCE,0xA1,0xB3,0x52,0xE3,0x8B, +0xE6,0x1B,0x09,0xCA,0xAB,0x7C,0x71,0xE4,0xED,0x7D,0x85,0xB4,0x0B,0x21,0x2D,0x15, +0x31,0xA5,0xF9,0x82,0x69,0xBD,0x87,0xBA,0x68,0xFD,0x19,0x77,0x18,0xD7,0x6B,0xEE, +0xBD,0xCE,0x38,0x9F,0x45,0x57,0xAD,0x98,0xCB,0x2D,0xF2,0x08,0xB0,0x14,0xA8,0xE0, +0xD7,0x3C,0x9D,0xB1,0xB3,0x2F,0x7E,0x4E,0xAC,0xA5,0xC9,0x6B,0x08,0x78,0x22,0x25, +0x1E,0x53,0xEF,0x1D,0x14,0x15,0xBB,0x6F,0x22,0xC0,0x09,0x52,0xB2,0xD2,0x32,0xAF, +0xDE,0xDF,0xF6,0xD6,0xAC,0xE6,0x41,0x66,0xDA,0xF7,0x46,0x30,0x4D,0x9D,0xF1,0x1E, +0x4A,0x0F,0xBD,0xF0,0x3B,0xD0,0xE0,0x96,0x9E,0xA3,0x2C,0xE4,0xB7,0x58,0x0C,0x2C, +0xB0,0xA3,0xC9,0xE5,0xF5,0x08,0x1C,0xE5,0x48,0xBA,0xF5,0xC2,0x55,0x07,0x68,0x8E, +0x05,0x04,0x90,0x65,0xEA,0x2D,0x81,0xDF,0x95,0xEB,0x19,0x8F,0x0F,0x89,0xF3,0xF4, +0x6E,0xA2,0x64,0x7D,0x69,0xCB,0x12,0xBF,0x6C,0xC9,0x4A,0xE0,0x8D,0xC1,0xCF,0xCF, +0x9E,0x1A,0x03,0xCA,0x95,0x9D,0x7D,0xF4,0xAF,0x4D,0xE5,0x88,0xD1,0x5B,0xDA,0xA3, +0xC8,0xFD,0x5A,0x79,0xAC,0x67,0xD8,0x1C,0xD6,0x59,0xE6,0xDA,0x8B,0x00,0xED,0x21, +0xAA,0xC6,0x90,0x7D,0xF0,0xD5,0x16,0x76,0x6D,0x97,0xB2,0xC5,0xC1,0x71,0xBD,0x39, +0xF8,0x8B,0x91,0xF5,0xA3,0xF6,0x54,0x67,0x1B,0xCC,0x85,0x0F,0x23,0x51,0x35,0xA4, +0x39,0x42,0xB4,0x4F,0xE2,0xCD,0xD8,0x68,0xDE,0xCB,0x99,0x3D,0x01,0x90,0xF3,0xAE, +0x11,0x42,0x3C,0xB5,0x2A,0x39,0xDC,0x67,0x0A,0x9B,0x96,0xC6,0x99,0x80,0x7F,0xA4, +0x35,0xFD,0xBE,0x5F,0xD3,0x05,0x90,0x80,0x99,0x55,0xE9,0x5B,0xBF,0xAF,0x50,0xAB, +0xA3,0x70,0x15,0x7D,0x66,0x1F,0xE9,0x4D,0x8C,0x0E,0x58,0xD1,0x13,0x03,0x1F,0x63, +0x18,0xCF,0xC8,0x21,0xD5,0x4B,0x53,0xE7,0x4D,0x93,0xC6,0x2C,0x77,0x22,0x77,0x4E, +0x2C,0x45,0x34,0x39,0x97,0x8B,0x6D,0x13,0xCB,0x07,0x56,0x4B,0x99,0x34,0x71,0x7A, +0xCC,0x64,0x4C,0x2F,0xCB,0x52,0x5C,0x16,0x99,0x40,0x76,0xB8,0x3B,0xB9,0x0E,0x7B, +0x60,0x85,0x25,0xFE,0x26,0x01,0x70,0x1D,0x95,0xCF,0xE1,0xBB,0xB5,0xC0,0xDA,0x5A, +0x57,0x9B,0xA7,0x54,0xFF,0xBA,0x9D,0x73,0x89,0x01,0x03,0xC5,0x81,0xE9,0xD8,0x4C, +0xBB,0x81,0x80,0xF2,0x88,0xED,0xE4,0x09,0x75,0xD7,0x4C,0x3D,0x66,0x2A,0xE1,0x8D, +0xED,0xFB,0xCA,0x84,0x4E,0xAF,0xCB,0x8F,0xC8,0x20,0xD6,0x2A,0x94,0x84,0xB6,0xE5, +0x3D,0x79,0xC1,0x4F,0x93,0x12,0x3F,0x69,0x0B,0x0C,0x0B,0xA4,0x75,0xAD,0x7D,0x2C, +0x07,0xF0,0x09,0x57,0xC7,0x2E,0x02,0x3C,0x6F,0x65,0xCE,0x16,0x66,0x25,0x8D,0xF5, +0xC4,0x8B,0x04,0x10,0x16,0x59,0xB4,0x18,0xBC,0x82,0x66,0x21,0x09,0x3F,0x15,0x0F, +0x8E,0x81,0x14,0xC3,0x23,0xAC,0x06,0x77,0x76,0x6D,0xCC,0xF3,0x91,0x69,0x5F,0xF9, +0xDD,0xF6,0x27,0xB3,0x14,0xCC,0x98,0xE8,0xE9,0x1F,0xD6,0xC3,0xDB,0x37,0xCC,0xDA, +0xFB,0xBD,0x4E,0x6B,0x4A,0x44,0xE5,0xA8,0x21,0x9A,0xC8,0xDB,0xA2,0x88,0xEC,0x16, +0x94,0x64,0xD3,0x15,0xA9,0xC6,0xC6,0x74,0xC0,0x06,0xA5,0xC2,0x9F,0xE5,0x84,0xA7, +0xFE,0x6E,0xD4,0x03,0x43,0x11,0x8B,0xEA,0x40,0xDE,0xA5,0x60,0x9D,0x75,0x30,0x40, +0xF9,0xD5,0xDD,0x25,0x32,0x41,0x54,0x4B,0xE0,0x66,0x9E,0xE9,0x4F,0x49,0xD6,0x83, +0x74,0x85,0xAF,0x3F,0x85,0x9F,0x9A,0xDB,0x78,0x8D,0xFB,0xDD,0x1C,0x96,0xB0,0x78, +0x72,0xD8,0x21,0xBC,0xD6,0x1A,0xC6,0x8D,0xBA,0x7B,0xB8,0x25,0xF3,0x8A,0x3F,0x05, +0x43,0x62,0x85,0xF8,0x28,0x6E,0xC1,0xDB,0xA3,0xAA,0xB3,0x92,0x8E,0xED,0x2A,0x53, +0x0E,0xDD,0x1A,0x27,0x8D,0x98,0x40,0xDF,0x5B,0x1A,0x70,0xEC,0xB1,0xDC,0x8A,0x9E, +0x13,0x72,0x6F,0x3E,0xD7,0xA6,0x47,0xE1,0x38,0xD6,0x35,0x8D,0x4A,0xAE,0x83,0x36, +0xBC,0xB1,0x74,0x43,0x06,0x57,0x7C,0xA3,0x7B,0x0D,0x35,0x06,0xEB,0xB9,0xA3,0xBB, +0x51,0xB7,0x1F,0xA3,0x38,0xBC,0x60,0xD6,0x70,0x49,0xBC,0xDE,0xE6,0xAF,0x95,0x60, +0xAA,0x2C,0x61,0x28,0xC4,0xD8,0xA4,0x7A,0x57,0x65,0x88,0x6D,0x4C,0xEB,0xA2,0x8F, +0xD7,0x90,0x3D,0xC9,0x59,0x86,0xA8,0x2B,0xE1,0xD9,0x0F,0xBD,0x49,0xF8,0x27,0xBC, +0x32,0xD2,0xBC,0xF0,0x13,0xD9,0x36,0xB3,0xEC,0xFD,0xE8,0x91,0xF1,0xD3,0x5D,0x7D, +0x4F,0x98,0x66,0xF7,0xA7,0x11,0xA2,0xB4,0x2C,0x71,0x5B,0x92,0x58,0x9D,0xC5,0x82, +0x08,0x4A,0x44,0x22,0x35,0x56,0xCE,0x3A,0x37,0xE1,0x58,0xAF,0x27,0xEC,0x0C,0x09, +0x49,0xE6,0xAF,0xE3,0x07,0x42,0xEC,0x9D,0x50,0x2C,0x76,0x28,0x6C,0xD3,0x1F,0x59, +0x92,0xFB,0xCD,0x13,0xEF,0x1F,0x04,0x18,0x9C,0xA3,0xEE,0xD7,0x9D,0x48,0xAB,0xE6, +0xDD,0xD3,0x54,0xF9,0x04,0x5C,0x09,0x2C,0xEF,0xFA,0x2D,0xC1,0x80,0xE9,0xFD,0x92, +0x1D,0x5B,0xE3,0xEF,0xA8,0x43,0x93,0xC7,0x9D,0xDC,0x61,0xFD,0x3F,0x12,0x8D,0x5E, +0xD5,0xD7,0x9F,0xE9,0x6D,0xF9,0xC7,0xBC,0x15,0x27,0x28,0x49,0xC6,0x6F,0xB5,0x84, +0xD2,0x07,0x2C,0x10,0x26,0x1C,0x82,0xF0,0x6F,0xC1,0xA5,0x62,0x56,0xC5,0xA8,0x0A, +0xA5,0x04,0xC6,0xE2,0xCE,0x5C,0x2A,0xF4,0x79,0xC8,0x77,0xA3,0x8C,0xAB,0xF4,0xB2, +0x1D,0xDF,0x05,0x4D,0xA7,0x95,0x42,0xDC,0x44,0x65,0x0A,0xAF,0xD4,0xF5,0x4E,0x19, +0x3E,0xB0,0x78,0x7D,0x20,0x30,0x9B,0x51,0x7C,0x2A,0x60,0x03,0xF0,0x39,0xB8,0xDC, +0xFB,0x52,0x62,0x8C,0xE4,0x7A,0xFC,0x46,0x11,0x12,0xB1,0xC5,0xB3,0xC0,0x97,0x55, +0xB2,0x25,0x24,0xCE,0xE2,0x07,0xF7,0x41,0xC9,0x6C,0xFA,0x2F,0xD8,0x32,0x33,0x88, +0xDC,0xB9,0x67,0xB7,0xF3,0x0E,0x29,0x3D,0xF2,0x57,0xCB,0x42,0xF4,0xDA,0x0A,0x9D, +0x30,0x21,0x4D,0x5A,0x6B,0xF2,0x00,0x47,0xB7,0x1E,0x4A,0x28,0x6B,0x03,0x84,0x3D, +0x9D,0xCE,0x97,0xF4,0x39,0x6B,0xFC,0x38,0x40,0x75,0x1B,0x7D,0x74,0xE4,0xB4,0x69, +0x5B,0x95,0xB9,0xAB,0x8C,0xEA,0x5D,0xED,0xD8,0xF6,0xD4,0xD7,0xCE,0xAE,0x84,0x02, +0x41,0x66,0xBD,0x5B,0x65,0xEA,0x14,0x0C,0xA1,0x71,0x97,0xF3,0x8A,0x2D,0xA9,0x77, +0x15,0xFB,0x2B,0x5B,0x9B,0x87,0xA1,0xB2,0x53,0xB9,0x48,0xA9,0x3E,0x0C,0xBF,0x07, +0xEC,0xFC,0x57,0x4B,0x32,0xE0,0x41,0x55,0x29,0x19,0x01,0xD5,0x44,0x2A,0x22,0x41, +0x00,0x47,0xA5,0xEE,0x21,0x8D,0xEF,0x08,0x78,0x31,0x2B,0x72,0x28,0xFC,0x81,0xA6, +0x2E,0xAB,0x14,0x38,0xA5,0x18,0xE6,0x75,0x09,0x9A,0x9C,0xFB,0xEB,0x2C,0x69,0xB8, +0xEF,0xF1,0xB3,0x3B,0xC7,0xAA,0x56,0x67,0x85,0x10,0x8C,0x86,0xAF,0xB6,0x51,0xE8, +0xE0,0x48,0x01,0xC7,0x60,0x21,0x0A,0xCD,0xF3,0x54,0x4C,0xB0,0x2A,0x17,0x3B,0x5D, +0x21,0xFE,0x2D,0x29,0xF1,0xD4,0xB4,0xE9,0x55,0x2D,0xD6,0x83,0x85,0x41,0xC4,0x6B, +0x99,0xC2,0x6B,0xC2,0x62,0xDD,0x17,0x1D,0xA6,0x31,0x1B,0xA9,0xE0,0xFB,0x06,0xC3, +0xDC,0x4B,0x56,0x70,0xC0,0x61,0x24,0xFB,0xDB,0xC2,0x02,0xC8,0x97,0xA5,0x1E,0xA8, +0x2B,0x20,0x66,0x7C,0xFC,0x42,0x64,0x4D,0x09,0x4B,0x27,0x5F,0x7F,0x7E,0xD8,0x56, +0x1C,0x0A,0x14,0xE3,0xFF,0x0B,0x70,0x45,0xF8,0xAF,0x7D,0xEA,0x84,0x3D,0xA8,0x08, +0xB0,0x4D,0x33,0x3F,0xEC,0x5F,0xD4,0xBD,0x76,0x4A,0x9C,0x90,0x36,0xC1,0x27,0x05, +0x36,0x2B,0x8F,0xD4,0x22,0x89,0xE6,0x3C,0x43,0x14,0x1B,0x64,0x56,0x48,0xCE,0xF5, +0x33,0x07,0xE6,0xD7,0x55,0x13,0x0F,0x79,0x8F,0x87,0x1A,0xFD,0x7C,0x9F,0xEA,0x06, +0x39,0xA6,0xA0,0xD2,0x99,0x86,0x63,0xA4,0xE3,0xE3,0x22,0x57,0x12,0xC9,0x39,0xC4, +0x6A,0x78,0xA7,0xA9,0x2F,0xEB,0x1A,0x55,0x81,0x25,0xA4,0x80,0xEB,0x08,0x91,0xE7, +0xA4,0x4C,0x43,0xAC,0x6D,0x00,0x46,0xEC,0x9C,0x96,0x3A,0x20,0xDC,0xAE,0xE9,0x42, +0x0D,0xC6,0x47,0xAE,0x82,0x21,0x40,0xB2,0x38,0xD6,0xA0,0x3D,0x50,0x66,0xBF,0x81, +0xB7,0x0F,0x5B,0x43,0x65,0x37,0xEA,0x28,0xB4,0x77,0x49,0xBC,0x84,0x2E,0xC7,0xEC, +0xA1,0x71,0x2F,0xCD,0xBF,0xFC,0xF2,0xC0,0x7B,0x03,0x28,0x64,0x01,0x5A,0xCE,0xD5, +0x2C,0x69,0xFF,0xDE,0x61,0x1F,0x01,0x3E,0x03,0x56,0xB3,0x19,0xB9,0xA4,0x92,0x5C, +0x72,0xCE,0xAB,0x3F,0xEF,0x21,0x79,0xAC,0xDF,0x9E,0x07,0x1D,0x33,0xDD,0xFD,0x71, +0x42,0x72,0x52,0x08,0x98,0x6E,0x3C,0x29,0x5C,0x10,0xDB,0xEF,0xC3,0xF7,0xFC,0xC8, +0x37,0xFE,0xA7,0x77,0x9B,0x16,0xFE,0x70,0x01,0xA9,0x25,0x15,0x25,0x74,0xF7,0xDC, +0x05,0xB6,0xC8,0x95,0xFD,0xAB,0xAC,0x90,0xFB,0x3B,0x77,0xEA,0x1E,0x02,0xA7,0x57, +0x4C,0xBC,0x34,0x33,0x8A,0xE7,0x07,0xFD,0x2C,0xAD,0x77,0xE9,0xBE,0x03,0x26,0xF7, +0x21,0x1D,0x04,0xA8,0x99,0xD8,0x96,0x98,0x2A,0x6B,0x6A,0x2D,0x2C,0xBE,0x68,0xCD, +0xAA,0xC0,0xD8,0xB1,0x8E,0xE8,0x73,0xEF,0x08,0x18,0x0A,0x0B,0xA8,0x0A,0xE0,0x54, +0xBE,0xEC,0x75,0x9A,0x75,0x72,0xC6,0x24,0xD7,0x40,0xCB,0x85,0x3E,0x13,0x32,0x07, +0x05,0xF9,0x70,0x74,0x06,0x05,0xF1,0x4B,0x8C,0x1C,0x9C,0x65,0x2B,0xD8,0xCC,0xC2, +0xEC,0x7F,0xD6,0x5C,0x71,0x1F,0x6F,0x6B,0x77,0x8A,0x96,0x9E,0x44,0x3B,0xF0,0xA1, +0x0E,0x14,0x5C,0x21,0x77,0x34,0xF1,0xF1,0xC9,0xF1,0x48,0xAA,0xDA,0x71,0x1B,0x9E, +0xE6,0xA9,0x00,0x28,0x4E,0x70,0x7F,0xFA,0x51,0x0F,0xAB,0x0F,0xCB,0xDC,0xAA,0xBB, +0xB5,0x85,0x20,0xE5,0x13,0x93,0xFF,0x72,0x59,0x0B,0xF0,0x74,0x1F,0xD7,0xEC,0x25, +0x2D,0x1E,0x9F,0xE7,0x07,0xAC,0xAF,0xF3,0xB1,0x0F,0x19,0x18,0x33,0x87,0x9B,0x2C, +0x91,0x38,0x07,0x77,0xCB,0xDA,0x7E,0x32,0x0F,0x1A,0x5C,0x0D,0xD1,0x42,0x10,0xF8, +0xDD,0x4C,0x52,0xDE,0x1F,0xF8,0x7A,0x75,0x85,0x07,0x3E,0x7E,0xC5,0xB9,0xFE,0xD8, +0xA3,0x5E,0x2D,0x14,0xEE,0xB6,0x0B,0xA7,0x30,0x09,0x0D,0x6C,0x0C,0x2E,0xB1,0xAF, +0x73,0xE6,0xE6,0x26,0xD2,0xA8,0x67,0x37,0x10,0x0A,0xDA,0xF9,0xB7,0xA1,0x22,0x24, +0x37,0x1B,0x57,0x1B,0x1D,0x30,0x0D,0xE2,0xF6,0xFA,0xD9,0xE6,0xB9,0xA0,0x16,0xAF, +0x1C,0x29,0x3B,0x07,0x70,0x4B,0x03,0x13,0x48,0x3D,0x15,0x86,0xEC,0x1F,0xC7,0x59, +0xB5,0x8C,0x6E,0x01,0x43,0xB0,0xEF,0x0B,0x73,0xD4,0xAF,0xD2,0xCF,0x74,0x18,0x59, +0x3A,0xFF,0xD5,0xFD,0x38,0xDC,0x23,0xC7,0x0D,0xB1,0x14,0x45,0x28,0x4A,0xCE,0xBC, +0x83,0xA8,0x80,0x21,0x6C,0x07,0xF4,0xCF,0xED,0xD4,0x01,0x3F,0xD3,0x6A,0xEE,0x6D, +0x3F,0x84,0xDD,0xB2,0x03,0xA8,0x15,0x13,0xF8,0x93,0x55,0x40,0x2D,0x3F,0xA2,0xE8, +0xFC,0x7D,0x68,0x78,0x5A,0xD3,0xE9,0xF6,0x45,0x60,0x02,0x69,0x6B,0x7E,0x04,0xB3, +0xA7,0x05,0x7C,0x50,0x25,0x0E,0x65,0x7A,0x23,0x4E,0xF0,0xD6,0xBE,0xF7,0xB5,0x29, +0x06,0x87,0x95,0x57,0xE9,0x46,0x37,0xE3,0x81,0x09,0xFC,0xBA,0xE9,0x08,0x75,0xD9, +0x20,0x57,0x5F,0x4A,0xCE,0xB2,0x23,0xC2,0xCC,0xBB,0x04,0xA8,0x4C,0x05,0xE2,0x94, +0xDC,0x3F,0x72,0xBD,0x57,0x78,0xFE,0x60,0x10,0x11,0xFF,0xAC,0xC3,0x0C,0x97,0x0C, +0x5F,0x01,0x8B,0x1B,0xDC,0x35,0x58,0x96,0x50,0x92,0x19,0x5F,0x5D,0xF3,0xFA,0x88, +0x75,0x83,0x48,0x05,0x98,0x47,0xBE,0x5D,0xC3,0xB9,0xB2,0xB1,0xAA,0xA4,0x87,0xAF, +0x45,0x0C,0xE4,0x5C,0x02,0x37,0xC0,0x14,0x91,0x82,0xA4,0xD3,0x7B,0x88,0x9A,0xEE, +0xA0,0x3C,0x9E,0xE8,0xD9,0x14,0xD8,0x7E,0x99,0x03,0xB8,0x0B,0x0F,0x2F,0xF6,0xBE, +0x72,0xD0,0x4D,0xF1,0x37,0x49,0x64,0x9A,0x61,0x5A,0x9A,0x3E,0x51,0x43,0x96,0xBE, +0x4D,0x86,0x81,0x91,0xAC,0x0D,0xBB,0xB9,0xA9,0x5A,0xB9,0x7C,0x4B,0xFA,0xCE,0x3A, +0x45,0xDA,0x68,0x43,0x1F,0x65,0xCA,0xAB,0xF1,0x5B,0xAA,0x62,0x91,0xC6,0xD9,0x72, +0x72,0xA4,0x3E,0x6C,0x3D,0x69,0xF3,0x85,0x9E,0x41,0x29,0x94,0x41,0xFD,0x6E,0xE4, +0x79,0xAA,0x90,0xE7,0x46,0xF9,0xDA,0x13,0xD6,0xBD,0x7A,0x2B,0x60,0x9D,0x8D,0x6E, +0xD8,0xD3,0x00,0xF5,0xCB,0xBF,0x94,0x2D,0x4A,0x10,0xD1,0x6B,0x37,0xB4,0x9D,0x8D, +0x58,0x87,0x21,0x9F,0x36,0xB0,0x13,0x4D,0x5B,0x1A,0x4F,0x5B,0x55,0xCA,0xE4,0xA6, +0x93,0xC2,0xFE,0x06,0x04,0x8F,0x7A,0x3A,0x5C,0x7A,0x4D,0xA2,0xC4,0x4E,0x96,0x81, +0x0F,0x63,0x98,0xE3,0x1C,0x22,0x94,0xB4,0xE5,0x51,0x9B,0x12,0x68,0xDD,0x86,0x7B, +0x0A,0x8F,0x2C,0xB6,0x98,0x70,0x6F,0xF3,0xAD,0x7D,0xC2,0x2C,0x9A,0xA6,0x81,0xC3, +0xE7,0x90,0x76,0x36,0x8F,0xF5,0x13,0x66,0x9C,0x81,0x63,0x55,0x83,0xC9,0x97,0x16, +0x04,0x19,0xBF,0x93,0xAA,0x57,0x61,0xFF,0x37,0xEE,0x23,0xDB,0x18,0xB8,0xB4,0x10, +0x51,0x36,0xF2,0x1B,0x1A,0x90,0x50,0x49,0x59,0x3C,0x0E,0xBF,0x74,0x30,0xB9,0x7B, +0x25,0xB4,0xA9,0x7E,0x7E,0x36,0x7B,0xB8,0x98,0x77,0xF3,0x59,0x52,0xEF,0x32,0x66, +0xFC,0xFE,0x29,0xC8,0xA1,0x08,0xFC,0x21,0xDE,0xDE,0x6F,0xE3,0x35,0x9A,0xCA,0x4D, +0x89,0xD1,0xD7,0xFD,0x4C,0xC7,0x47,0x3E,0x5B,0xC9,0x5F,0xF1,0xE0,0xB0,0x57,0x69, +0x01,0x0C,0x12,0x56,0x54,0xD6,0x2B,0x59,0xB3,0xB6,0x21,0x34,0x92,0x99,0x39,0x9B, +0x66,0x06,0xED,0x33,0x1B,0x8F,0xB6,0x01,0x0F,0x20,0x2E,0x6A,0x1C,0x7C,0x11,0xD8, +0x5C,0x1E,0xCA,0xD2,0x9B,0xE4,0x0E,0x53,0xCB,0xD8,0xD6,0x22,0x71,0x25,0xF1,0x8A, +0xBD,0x7C,0xB5,0x9C,0x0E,0x8D,0x2E,0xEA,0x1F,0x3D,0xA6,0xD3,0x55,0x38,0xAE,0x23, +0x8B,0x8C,0x61,0x04,0xC8,0x48,0x1B,0x71,0x74,0x9F,0x4E,0x35,0xE6,0x7C,0xE2,0x66, +0x76,0x46,0xE6,0x66,0xB4,0x57,0x8F,0x4E,0xA8,0xD5,0x16,0xB7,0x65,0xB0,0x27,0x21, +0xB2,0xAF,0xCB,0xFF,0xBA,0xB0,0x07,0xF3,0xD9,0x88,0x4D,0xAE,0xDF,0x25,0x00,0x07, +0xB7,0xF0,0x35,0x80,0x95,0x64,0x9E,0x19,0x2C,0x8E,0x53,0x65,0x6A,0x73,0xD1,0x8F, +0x6B,0x6B,0xAC,0x26,0x69,0x69,0x12,0x90,0xF7,0x9A,0xEC,0x4A,0xC1,0x92,0xF7,0xAD, +0x2A,0x55,0x9C,0xDF,0x5B,0x4F,0xB5,0x7D,0xD2,0xED,0x2E,0x83,0xAE,0x68,0xE6,0x83, +0x74,0xBE,0x63,0xE6,0x59,0xDB,0x10,0x9F,0x96,0x5B,0xF9,0x39,0x01,0x5B,0xF0,0x60, +0x2F,0xBF,0xC6,0x30,0x63,0xD6,0xD9,0x12,0xFD,0x11,0x44,0x5B,0xEE,0xCB,0x44,0x1F, +0x26,0x80,0x63,0x49,0xEC,0x59,0x2C,0x18,0xDF,0xE1,0xE3,0x51,0xA8,0x89,0x20,0xC0, +0x5E,0x73,0x9C,0x25,0xFA,0xB0,0x41,0xC1,0x35,0x52,0x26,0x59,0xB6,0x08,0x5D,0xB0, +0x74,0xB8,0x79,0xA7,0x37,0x15,0xAA,0xBE,0xB9,0x31,0xE0,0x07,0x7C,0x14,0xE3,0xFD, +0x38,0xCD,0xBE,0x1B,0xD1,0x30,0x50,0x0D,0x46,0xCB,0x0B,0xA3,0x25,0x92,0xB8,0x82, +0xB4,0x3D,0xC6,0xD3,0xDA,0xA8,0x86,0x0F,0x73,0x40,0xF1,0xAC,0x1E,0x82,0x73,0x04, +0x6B,0x42,0xF0,0x5E,0x47,0x5E,0x5B,0x2F,0x33,0x93,0x25,0x60,0x85,0xFE,0x15,0x83, +0x88,0xAA,0x6B,0x56,0x89,0x70,0x94,0x9C,0xC3,0x39,0xCC,0x2F,0xFD,0x7B,0xDB,0x97, +0x01,0x1A,0xDA,0x51,0x39,0x23,0xDA,0x4C,0x54,0xE3,0xBC,0xBE,0x75,0x82,0xB6,0xAA, +0x03,0xBF,0x8F,0x60,0x8D,0x37,0x54,0xCD,0xA9,0xB2,0x8D,0x4F,0x11,0xDF,0x7B,0x12, +0x1A,0xA4,0xF9,0xF8,0x7E,0xDA,0x28,0xD6,0xE5,0x65,0xDA,0x6F,0x9D,0xEA,0x28,0x3B, +0xAA,0xA0,0x26,0x5C,0xF1,0xE4,0x5C,0x00,0x42,0x54,0xEC,0xB9,0xC6,0xC5,0xF2,0x88, +0xCE,0xDD,0x4D,0xC0,0x8F,0xA5,0x65,0x67,0x73,0x2D,0xCA,0x8E,0x39,0x37,0x33,0x2B, +0x50,0xA1,0x8B,0xB5,0x8B,0x95,0xB0,0x9E,0x68,0x1D,0xDB,0x77,0xB9,0xE3,0x23,0xE1, +0xAE,0xB3,0x57,0xB1,0xE8,0x06,0xDE,0xCC,0x97,0x0B,0xCD,0x14,0x25,0x3E,0x0C,0x6F, +0x50,0x9F,0x66,0x9D,0x76,0xD4,0x29,0xBA,0x92,0xBE,0x8D,0x82,0x85,0x1E,0x1C,0x97, +0x69,0x6D,0xC4,0xAD,0x42,0x14,0xBC,0x9B,0xA5,0x61,0x9B,0xA5,0x78,0x1B,0xA7,0xEB, +0x91,0xAD,0x45,0x6C,0x66,0x3D,0x0A,0xE2,0xCD,0x2D,0xF6,0x39,0x56,0x77,0x46,0xB7, +0x23,0xE4,0x52,0xB2,0x0E,0x61,0xB3,0xBA,0x51,0x14,0xAC,0x92,0xBD,0x22,0x62,0x2F, +0x9F,0xFD,0x4F,0x79,0xA4,0x82,0xCA,0x78,0xBC,0x5A,0x06,0x53,0xAD,0xB3,0xE8,0xBA, +0xDB,0xCD,0xEC,0x84,0x86,0xD4,0xA5,0x93,0x37,0x50,0x58,0xBE,0xDC,0x42,0x21,0x22, +0x55,0x80,0x2B,0x3F,0x02,0x03,0x05,0x0E,0x80,0x38,0x8A,0xD9,0xB1,0x9E,0x4F,0x42, +0x05,0xB1,0xC7,0x10,0x2B,0x2B,0xC5,0x09,0x29,0xAC,0x96,0xB3,0x16,0x67,0x0A,0x83, +0xC5,0x73,0x29,0xBA,0x0C,0x5D,0xC6,0xF4,0xF1,0x47,0x3B,0xCE,0xA3,0x2B,0xB8,0x94, +0xEB,0xF4,0xDA,0x79,0x8D,0xF8,0xEB,0x9E,0xFC,0x4C,0x77,0xB6,0x8B,0xC6,0x8C,0x70, +0x39,0x3D,0x57,0xF3,0xA6,0x0C,0xEC,0xF0,0xD1,0xA7,0x7D,0x2D,0x80,0x46,0xF2,0x61, +0xA4,0xBE,0x1E,0x33,0x9C,0x52,0x9F,0xCB,0x9C,0x49,0x3A,0x21,0x0E,0x49,0x88,0xDE, +0xEC,0xDF,0xD5,0xB9,0x5C,0xBC,0x6F,0x7D,0x52,0x9D,0x82,0x28,0x80,0xD1,0x43,0xF7, +0x3B,0xA0,0x2D,0xD3,0x86,0x77,0x92,0x13,0xAA,0xE6,0x16,0x1A,0x55,0xB6,0x07,0x6D, +0x51,0xB8,0x55,0x57,0xE7,0xC3,0xC6,0x61,0xC5,0xF6,0x5B,0xB3,0x54,0x92,0x2F,0xE5, +0x32,0x32,0x36,0x29,0x15,0x42,0x8A,0x92,0xB7,0x11,0xBC,0x2C,0xB0,0x01,0x9A,0xC0, +0x59,0x9D,0xB2,0x46,0x1A,0x02,0x0F,0x43,0x9B,0x43,0x73,0xD4,0xE9,0xAD,0x5D,0x61, +0xB7,0x0C,0xFA,0xD6,0xF8,0x6E,0x88,0x06,0x6A,0xF4,0x02,0x91,0xE7,0xA0,0x0E,0x6F, +0x19,0x65,0x5E,0xFF,0x92,0xD5,0x50,0xCA,0xBF,0xB5,0xC2,0x09,0x9A,0xCC,0x4B,0x62, +0xD8,0x45,0xAB,0x0B,0x5F,0x50,0x2A,0xE2,0x96,0x23,0x2D,0x5F,0x69,0xAB,0x9E,0x17, +0x67,0x1A,0xFF,0x4A,0xBA,0xF4,0xB7,0x15,0x72,0x74,0x40,0x01,0xE5,0xB3,0x20,0x7C, +0x34,0xD2,0x4A,0x5E,0x37,0xA8,0x58,0x16,0x81,0x6E,0x39,0x78,0x2E,0xE8,0xA2,0xD2, +0xFD,0x7F,0xE9,0x4D,0xE0,0x61,0xF4,0x74,0xFA,0x5D,0x23,0x8C,0xEA,0x0A,0xC4,0x2A, +0x8D,0x7B,0x53,0x84,0x21,0x45,0x51,0x56,0x87,0x13,0xE3,0xB4,0xC2,0xB2,0xF3,0x33, +0x03,0x30,0x09,0x52,0x6D,0xC1,0x58,0x01,0xEA,0x6D,0x99,0xF8,0x30,0xDC,0xCD,0x45, +0x5F,0x87,0xCE,0x9A,0x4C,0x86,0xDC,0x7D,0xC2,0xB8,0xC5,0x30,0xF7,0xA4,0x9C,0xE6, +0x14,0xBE,0x27,0xEC,0x0C,0x2A,0x00,0x7B,0x67,0x26,0x49,0xCC,0xBE,0x40,0x08,0x01, +0x7B,0x44,0xB8,0x8E,0x7B,0xCB,0xAD,0xF2,0xC4,0xAE,0x3F,0x23,0x81,0xAF,0x2F,0x5D, +0x18,0x04,0xA4,0x2F,0x62,0x4B,0x0B,0x08,0xD1,0x53,0x63,0x18,0x1B,0xCE,0x6D,0xD4, +0xE0,0x6D,0x5F,0xD2,0x61,0x89,0x92,0xA4,0x30,0x79,0x4C,0x02,0x96,0xAD,0xD2,0x68, +0x91,0x94,0x2C,0xB5,0xAD,0x8D,0x99,0xBF,0xFA,0xC5,0x7C,0xC6,0xF3,0x9B,0x85,0xD7, +0x05,0x1D,0x6C,0xFC,0x8C,0x4E,0xBB,0xB2,0x02,0x37,0xCD,0x2C,0x35,0x7B,0xBB,0x90, +0xAE,0xDB,0xF5,0x8B,0xF2,0x55,0xAC,0xA6,0xB6,0x7A,0x6E,0x8B,0xDF,0x16,0x7F,0x8A, +0x31,0x54,0xF4,0xB7,0x01,0x6D,0x57,0xF5,0x9D,0xE3,0xE9,0x0E,0xC8,0x81,0x29,0x77, +0xEA,0x33,0x2F,0x7F,0xC9,0x62,0xF6,0xA2,0xBD,0xC5,0x19,0x78,0x8A,0x60,0xA3,0x9B, +0x1C,0x3A,0x99,0x43,0x91,0x0F,0x6A,0x77,0x06,0x5D,0x23,0x58,0x78,0x7F,0xF1,0x1B, +0xAC,0x16,0xAB,0x26,0x2C,0xC8,0x30,0x16,0xE3,0x3A,0x83,0x67,0xDD,0x87,0xAA,0xC2, +0x20,0x91,0x85,0x4F,0x47,0xE8,0xE5,0xE4,0x9F,0xDF,0xF4,0xCC,0x75,0x94,0x96,0x02, +0x37,0xCA,0x9C,0x99,0xEC,0xBF,0x68,0xAB,0xB7,0x52,0xBC,0x90,0x57,0x79,0x91,0x2B, +0xBD,0xD5,0xE1,0xD3,0xEF,0xB1,0x61,0x21,0x24,0x1A,0xB7,0x0B,0xDD,0x3A,0x98,0x9A, +0xF4,0x06,0xE4,0x34,0x79,0xB0,0x7E,0x82,0x78,0x10,0x9F,0x59,0x79,0x77,0x47,0x53, +0x06,0xEE,0x59,0x77,0x68,0x6F,0xBA,0x0B,0x47,0x4C,0x28,0x38,0x51,0x0B,0xB9,0xF4, +0xA6,0xE6,0xC1,0xFF,0x54,0x3F,0x47,0x68,0x6F,0xF1,0xE3,0x42,0x72,0xB2,0x59,0xC3, +0x57,0xC7,0xAF,0xDD,0x4E,0x6C,0xC5,0x42,0xF1,0x75,0x47,0x53,0xFB,0x7C,0x01,0xE7, +0x99,0x4F,0x41,0x06,0x02,0xE9,0x91,0xED,0xEA,0x37,0x0A,0xCA,0x87,0xFF,0xFC,0x11, +0xAC,0xCA,0xD0,0xEA,0x73,0xD4,0xCB,0xAB,0x31,0x1D,0x45,0x31,0x88,0x5F,0xC2,0x1E, +0x97,0x05,0x4C,0xED,0x29,0xFF,0x24,0xD6,0xAE,0xC3,0x2E,0xF5,0x1B,0x7C,0x42,0xE7, +0x70,0x5F,0x51,0x96,0x72,0x99,0x79,0x41,0xA0,0x55,0xC7,0xB3,0x18,0xC0,0x60,0x62, +0xD5,0x67,0xDA,0xBF,0xCD,0xDF,0x5A,0x76,0xA0,0xEF,0x43,0xA9,0x01,0xD1,0x31,0x3A, +0xE4,0xD9,0x89,0xD7,0xC1,0x21,0xEE,0x8A,0x66,0xBC,0x94,0x6E,0xF5,0x29,0x0D,0xC3, +0xA7,0xCB,0x8D,0xDB,0x2D,0xF6,0x73,0x61,0x44,0xB3,0x50,0x01,0x56,0xB4,0x24,0x17, +0xD7,0xB1,0x9D,0x96,0x12,0xAC,0x41,0x1E,0x4B,0xC5,0xDC,0x59,0x22,0xF2,0x7A,0x3F, +0x75,0x5D,0x70,0xAA,0xAD,0x72,0x8A,0x51,0xA7,0x92,0x63,0x9D,0x76,0xA4,0xCB,0xE5, +0x53,0xFE,0x2E,0x82,0x7E,0x29,0x24,0x1A,0xB1,0x65,0x3F,0x52,0xE5,0xDF,0xA4,0xCF, +0x9F,0x7F,0x38,0xA4,0xF8,0xDF,0x5C,0xBF,0xC2,0x58,0x54,0xB1,0x34,0xD5,0x37,0x87, +0x85,0x6B,0x78,0x68,0x74,0xC8,0xA3,0x3F,0x37,0x47,0x6F,0x32,0xA6,0xA3,0x1E,0x10, +0x56,0xE4,0xDD,0xC5,0x7A,0xBC,0x08,0xCC,0xFB,0x71,0x44,0x48,0x86,0xEC,0x2D,0x8D, +0x07,0x1B,0x62,0x00,0xD9,0x26,0xDF,0xBC,0x4C,0x13,0x6C,0x75,0x2C,0x99,0x0D,0xE5, +0x2A,0xFD,0x5F,0xC1,0x16,0x0A,0x30,0x1A,0xDF,0xC6,0xDA,0xA0,0xFF,0x97,0x65,0x05, +0x88,0x1C,0xD2,0x97,0xF1,0x19,0x54,0x91,0x14,0x83,0xE4,0x40,0x17,0xCF,0x8D,0x3D, +0x5B,0x30,0x0E,0x8A,0x6F,0xA5,0x69,0x2D,0xF8,0xA0,0x99,0x3C,0x72,0x40,0x07,0x53, +0x1F,0xDE,0x4E,0x07,0x2F,0xCB,0xEE,0x53,0x80,0x1D,0x59,0xEB,0x42,0x99,0xAE,0xC9, +0xE1,0x91,0xE5,0x69,0x36,0x7C,0xEC,0xE8,0x1C,0xC7,0x41,0xAC,0x9F,0x8A,0x77,0x29, +0xD8,0x7D,0x1B,0xD1,0x14,0xF3,0xAE,0x34,0xA1,0xC3,0x3B,0x1B,0x0C,0x98,0xCC,0x15, +0x45,0x20,0xF1,0xF9,0x4B,0xE7,0x12,0xD6,0xF0,0xC7,0x4E,0x06,0xE0,0x91,0xE4,0xA0, +0xEC,0x30,0xF6,0xAB,0xE6,0x34,0x7C,0xFA,0x6A,0x2F,0xBF,0x4F,0x78,0xD3,0xCE,0x47, +0x09,0xFC,0x60,0xF5,0xEE,0x58,0xF6,0x13,0x4A,0x6B,0x54,0x68,0xA8,0x3C,0x8D,0xD7, +0x84,0xFF,0x1E,0x2E,0xF9,0x90,0xED,0x6B,0x8B,0xE1,0xD6,0xD9,0x7E,0x33,0x21,0x4B, +0xAE,0xF2,0xE1,0xA0,0xC3,0x16,0xF0,0x50,0x44,0x46,0xFC,0xF5,0xDD,0x6E,0xFF,0x96, +0xB3,0x8D,0xF4,0x9C,0x3D,0xFC,0xB5,0x20,0xE9,0xC5,0x7D,0x2A,0x9C,0xC3,0x35,0x36, +0xC7,0xA5,0x99,0x60,0xD0,0xD1,0xE4,0x4D,0xF5,0x05,0xFA,0x96,0x70,0x9C,0xAF,0x2D, +0xDF,0x5C,0xFA,0xB7,0x82,0x09,0x5F,0xC0,0x16,0x16,0x02,0xF2,0xCD,0x43,0x49,0x19, +0x6E,0x8E,0xB2,0x69,0x33,0x7E,0x51,0xDE,0x07,0x61,0xB0,0xEA,0x38,0xA4,0x96,0xFF, +0xCC,0x10,0x5F,0x26,0x16,0xE4,0x99,0x1A,0x34,0xCF,0x1E,0x1A,0xC8,0x5C,0x65,0x47, +0x7D,0x35,0x2A,0xD4,0xF7,0xD5,0xAE,0x88,0xFB,0xCC,0x49,0x7F,0x4A,0x32,0x91,0xA0, +0xD6,0x3A,0x9B,0x36,0x34,0xC5,0xED,0xC9,0xB4,0x83,0xC3,0xE7,0xD3,0x16,0xC5,0x1F, +0x93,0xD5,0xD5,0x61,0x11,0x33,0x7D,0xC0,0x10,0xDB,0x57,0x23,0x21,0xD1,0x87,0x4B, +0xCF,0x7F,0x4E,0xEA,0x6E,0x03,0xA3,0xE6,0x93,0x01,0x82,0xE2,0xE6,0x44,0xB7,0x8A, +0xFB,0xB2,0x6A,0x80,0x11,0x27,0xB8,0x3F,0x2F,0xF3,0xD4,0xEE,0x6B,0x8D,0xE8,0xC8, +0xE1,0x2C,0xDD,0x72,0xD7,0xB8,0xA3,0xA8,0x56,0xA9,0x67,0x90,0x94,0x83,0xF3,0x17, +0xF2,0x72,0x51,0xC6,0xB6,0x9E,0xCB,0x4F,0x90,0xD3,0xF7,0x26,0xF6,0x0A,0x3F,0xC4, +0x61,0xB8,0x2E,0x34,0xB0,0x15,0x5D,0x3A,0xBF,0xB6,0x90,0x8E,0xE9,0x27,0xFE,0x03, +0x0B,0x2B,0x50,0x3C,0x9B,0x00,0xD3,0x00,0xB3,0x6A,0x50,0x2C,0xB5,0x07,0xE4,0x75, +0x44,0x43,0x8D,0xEC,0x8D,0xBF,0x0A,0x41,0x83,0x00,0x4D,0x2E,0x98,0xA6,0x30,0x07, +0x73,0xAD,0x3A,0x2D,0x98,0x12,0xEC,0x28,0x9C,0x56,0xFB,0x31,0x6E,0x53,0x0A,0x40, +0x56,0x04,0x5B,0x7C,0x8F,0xFF,0x42,0x17,0x37,0xAA,0x79,0x78,0xE9,0x0A,0xC6,0x9D, +0x2F,0xE9,0x99,0x7F,0x0A,0x94,0x43,0x0F,0x66,0xC1,0x20,0x8A,0xBA,0x31,0xBA,0xBB, +0xEE,0xCC,0xD0,0x5C,0xB9,0x16,0x26,0xCE,0x99,0x15,0xCF,0xA5,0x3B,0x3D,0xDA,0x68, +0x70,0x14,0x55,0x73,0xCB,0x04,0x0C,0xE5,0xBC,0xE4,0x69,0x22,0xF2,0xB8,0xC6,0x06, +0xD4,0x64,0x7D,0x83,0x26,0x56,0x14,0xD7,0xFA,0x8A,0x8B,0xB4,0x13,0x6A,0xD6,0x45, +0xFB,0xD1,0xC4,0x75,0xB8,0x93,0xC5,0xDC,0x48,0x61,0x32,0x18,0x36,0x20,0xA6,0x93, +0x6C,0x2D,0x12,0xA7,0xFF,0x92,0xD5,0xCB,0xB3,0x4D,0xEF,0x33,0xB3,0x3F,0x4D,0xF1, +0x70,0x4E,0x32,0x8F,0x9B,0x71,0xC0,0x34,0xDF,0x8C,0xB9,0x83,0x71,0x6F,0xB7,0x33, +0x0C,0xE0,0x75,0x5B,0x81,0x63,0x84,0x08,0x84,0xDC,0x4B,0xDC,0x1F,0xBF,0xE1,0x4B, +0xB2,0x83,0xD0,0x0B,0x1D,0x03,0x4C,0xC0,0x3A,0x85,0x86,0xD8,0x80,0xB6,0x43,0x75, +0x80,0x5F,0x41,0xE3,0xEA,0x49,0x4A,0xA7,0xA3,0xA2,0xD1,0xA1,0xE2,0xD1,0x20,0x5D, +0xD4,0x6F,0x97,0x15,0x96,0x2D,0x14,0x00,0xE3,0x2E,0xC0,0xA2,0xE4,0x87,0x31,0x6F, +0xAE,0x4F,0xD5,0x53,0xA9,0xB8,0xAA,0xBA,0x98,0x70,0x27,0xCB,0x98,0x9E,0x63,0xBB, +0xF1,0x20,0xB5,0x28,0x7C,0xB7,0x3F,0xFE,0x1F,0x59,0x1F,0xEE,0x08,0xE2,0x94,0x7B, +0x7B,0x0A,0xCA,0x6E,0x94,0xE5,0x4E,0xDC,0xBD,0x03,0x91,0x2D,0xE2,0xA3,0x3B,0xC6, +0xE7,0x88,0xE0,0xF0,0x20,0x17,0xEC,0xEF,0xCD,0x33,0x55,0xA5,0xAA,0xBC,0xAD,0xF6, +0xE9,0xC9,0xB8,0xA5,0x28,0x5C,0x2C,0x40,0xBD,0xA7,0x37,0x28,0x0F,0x3E,0x56,0x65, +0x16,0xEB,0xAB,0x76,0x6B,0x59,0x78,0xFC,0x0F,0xBF,0x2B,0xC8,0x3E,0x8B,0x26,0xC6, +0x60,0x94,0x0A,0x28,0xA1,0x0E,0x17,0xBF,0xF8,0xA9,0x57,0x03,0x8B,0x0E,0xBF,0x73, +0x1E,0x84,0x0D,0x07,0xDD,0xE5,0xE7,0x95,0xAD,0x52,0x7F,0x40,0x1F,0x2B,0x57,0x33, +0x22,0x30,0x5E,0x73,0xB4,0x64,0x35,0xB8,0x2F,0x35,0xB0,0xAC,0x60,0x22,0xA6,0x9E, +0xA1,0xA7,0x0A,0x69,0x50,0x69,0xE1,0xF1,0xE3,0xA1,0x21,0xF2,0xB1,0xA3,0x35,0x61, +0x7E,0x13,0x40,0x31,0x9B,0xF1,0xE6,0xC7,0x53,0x26,0xED,0xBC,0x53,0xD6,0x50,0x5A, +0xA8,0xFB,0x4E,0x8F,0x35,0xD7,0xA1,0xB9,0x11,0x89,0x51,0x47,0x7B,0x6C,0xF7,0x62, +0x27,0xBB,0x0D,0x9A,0xB1,0xD8,0xDA,0xE5,0xFF,0x4B,0xF4,0x67,0x8C,0x38,0x45,0xF4, +0xB6,0x58,0x21,0xA9,0x9B,0x8E,0x97,0x25,0x0E,0x8A,0x0F,0x80,0xC8,0xBA,0x76,0x18, +0xE7,0x8B,0x66,0x5A,0x4A,0x02,0x1B,0x2E,0x38,0x7A,0x01,0x9A,0x9A,0x04,0xD8,0x39, +0x9E,0x92,0xC0,0x92,0x9D,0x64,0xEC,0xB8,0xD0,0xD4,0xEA,0x5A,0xE3,0x65,0xAE,0x20, +0xB4,0x25,0xD3,0x2C,0xAA,0x74,0xE4,0xA5,0x4F,0x0B,0xB1,0xAC,0x92,0xB1,0x63,0x74, +0x1A,0xFF,0xE8,0x46,0xD3,0x4B,0x6A,0xBE,0x68,0xCD,0xCF,0x50,0x52,0x69,0x27,0xD5, +0x1E,0x2C,0xD9,0xC6,0x13,0x90,0x84,0x15,0xD6,0x3F,0x25,0x97,0xDC,0x77,0x9F,0x6D, +0x87,0x90,0x9F,0x1F,0x82,0xB5,0x48,0xCC,0x41,0xC3,0x74,0x43,0x0E,0x62,0x02,0x09, +0xA0,0x18,0x4B,0xE2,0x5A,0xC0,0x7D,0xA0,0x9C,0xA8,0x36,0xB0,0x64,0x06,0x35,0x4F, +0xE6,0x68,0xC0,0xB3,0x5A,0xAC,0xC7,0xC2,0xD3,0xA3,0x10,0x0E,0x6F,0xA6,0xBE,0xBD, +0x31,0x65,0x9A,0x49,0xAC,0x7C,0xC4,0x2B,0xFC,0xBC,0x24,0x37,0x49,0x19,0x5F,0x92, +0x94,0x8B,0x70,0x42,0x3E,0x03,0x33,0xAF,0x63,0xDB,0x7B,0x9A,0x52,0x5A,0xE8,0xEE, +0x58,0x87,0xDE,0xD6,0x67,0x5D,0x02,0x32,0x3C,0xEA,0xA7,0x45,0xE8,0x01,0xF6,0xF9, +0x90,0x17,0x07,0xEB,0xA2,0xA2,0x49,0x18,0x13,0x48,0xB5,0x55,0x86,0xEE,0x02,0xBC, +0x19,0xF2,0x5D,0x5E,0x96,0xCA,0xAF,0xC2,0x87,0x23,0x5A,0xA1,0xC0,0x6F,0x0E,0xC9, +0x3D,0x72,0xCE,0xC4,0x5B,0x98,0xA9,0x36,0xFC,0x71,0x43,0x37,0xE9,0xCD,0x88,0x99, +0xF1,0xD7,0x8C,0x11,0xBE,0xA7,0xF0,0xEE,0xBE,0x5D,0x29,0x93,0x76,0x2C,0xF1,0xEB, +0x73,0xCB,0x78,0x26,0x60,0xA3,0xD4,0xBE,0x75,0x7B,0x88,0x7F,0x30,0xCA,0xB9,0xCF, +0xF3,0x1A,0xCA,0x52,0xC4,0x43,0x0D,0x0D,0x60,0xAF,0x00,0xDD,0x06,0x60,0xE3,0x8E, +0x0F,0x9E,0x1A,0xCC,0x78,0x1D,0x69,0x51,0x8E,0x72,0xB6,0x64,0xCA,0xCA,0x16,0x15, +0x47,0x2D,0x94,0xDF,0xE2,0x88,0xA2,0x15,0x46,0x81,0x28,0x6B,0xFF,0x4A,0x51,0xDC, +0xE8,0xEE,0x96,0xB9,0xED,0x04,0x93,0x54,0xA3,0x94,0xC7,0x5F,0x9E,0xAB,0x1B,0xA4, +0x01,0xBC,0x92,0x8B,0x76,0x17,0xEA,0x10,0x7B,0x97,0xAA,0x2D,0x51,0x26,0x26,0x9C, +0x71,0x0C,0xD8,0xE7,0x63,0xC2,0xC4,0x9B,0xD3,0x28,0x1F,0xAD,0x61,0x4D,0x92,0x24, +0x06,0xCA,0x6E,0x89,0xB8,0x00,0x2F,0x90,0x6A,0x5A,0xC8,0x18,0x1D,0x9B,0x4A,0xEF, +0x5D,0x12,0xFF,0xE6,0x99,0xE8,0xDE,0x42,0x18,0x8C,0x8F,0x73,0x16,0xD9,0x97,0x9D, +0x1F,0xBA,0xC2,0x79,0x18,0x70,0xA9,0x2F,0x3E,0x19,0xB9,0xC5,0x41,0x92,0xDB,0x78, +0x68,0x10,0x64,0x38,0xD7,0x23,0x41,0x2D,0x33,0x97,0x45,0xDB,0x0B,0x31,0xC1,0xEB, +0x32,0xCC,0x52,0xB8,0xE9,0xF9,0xD3,0xFE,0xB3,0x7E,0x67,0x56,0x65,0xB9,0x2E,0x8D, +0x08,0xF4,0x9F,0x58,0x6A,0xD1,0x41,0xF9,0x2B,0x76,0x76,0x6C,0xFE,0x80,0x2D,0x05, +0xDD,0x0C,0x8B,0x3F,0x23,0x40,0x65,0xED,0x5B,0x86,0x6C,0xA0,0x20,0x5F,0x0C,0x37, +0x05,0xAE,0x77,0xA9,0x36,0x35,0x1D,0xF7,0xA5,0x91,0x97,0x9C,0x09,0x83,0x90,0x80, +0x71,0xD2,0x12,0x7D,0x56,0x8D,0x44,0xBC,0x83,0xF1,0x95,0x53,0x37,0xC0,0x55,0xEB, +0x91,0x2C,0x84,0xC7,0xB6,0x9A,0x8C,0x65,0x65,0x0E,0xEE,0x39,0x7E,0x0A,0x23,0xF2, +0xF5,0xC3,0xD1,0xA4,0x20,0xAB,0x44,0x38,0xA8,0xFF,0x88,0x38,0x3C,0x7C,0x54,0x2C, +0xDF,0x2B,0x68,0xCE,0x1C,0x0D,0xB3,0x3C,0x73,0x25,0x74,0x5F,0xB9,0x86,0x4A,0x26, +0xE1,0x25,0x44,0xC6,0x8A,0x70,0xDC,0xBB,0x02,0xAD,0x18,0x4B,0x1A,0x10,0x99,0x1B, +0x78,0xE5,0x6A,0xB5,0xDD,0xE1,0x84,0x8D,0x92,0xE5,0x37,0x83,0x0B,0x09,0x42,0x36, +0x39,0xBB,0x9B,0xF0,0x02,0x5C,0xAB,0x94,0xA8,0x0A,0x04,0xB6,0x0E,0x33,0x46,0x06, +0xF1,0xAD,0x07,0x07,0x80,0x63,0x72,0x88,0x82,0xA6,0xFD,0x8A,0xD5,0xAC,0xD6,0x09, +0xC8,0xCA,0xC7,0xA6,0xFD,0x35,0x35,0x42,0xCE,0x16,0x28,0x97,0xB0,0xCA,0xEA,0xBE, +0x68,0xF1,0x16,0x9E,0xE0,0xEC,0x76,0x99,0x29,0xE8,0x43,0x1E,0x6D,0x5B,0xC8,0x7B, +0x1B,0xEC,0x85,0x0B,0x28,0x84,0x22,0x85,0x60,0xDD,0xDA,0xB4,0x5F,0x0F,0xD9,0xD5, +0xE0,0xC0,0x6F,0xE9,0x79,0xF2,0x13,0xD2,0x09,0x88,0xFD,0x60,0xF0,0xFE,0x72,0x47, +0x45,0xF5,0xFA,0x19,0xE0,0xB3,0xE3,0x47,0x14,0x8A,0x54,0x61,0xAF,0xF1,0xBB,0x98, +0x59,0xD0,0xBA,0x96,0x11,0xA8,0xCC,0x32,0x98,0xD8,0x4A,0x3B,0x8C,0x4C,0x7F,0x10, +0x60,0x08,0x33,0xBF,0x91,0x46,0xD3,0x24,0x89,0xAA,0xD9,0xBD,0xFB,0xDD,0x74,0x0C, +0x58,0x45,0xD1,0x25,0x79,0x88,0x86,0xE9,0xD2,0xFE,0x75,0x46,0x47,0xFA,0x85,0x22, +0x89,0x89,0x6C,0x26,0x0E,0x9E,0x8F,0xD2,0xC9,0x2D,0xDC,0x3D,0x16,0xC1,0xFA,0x73, +0x07,0x59,0xD7,0x1F,0xBC,0xE2,0x53,0xBE,0xB5,0xFB,0x46,0x0E,0xCF,0xA8,0x0C,0x23, +0x30,0x1D,0x7A,0xA3,0xBE,0xD9,0x4A,0xCB,0xC1,0x7E,0xA7,0x6C,0xA5,0xC4,0x66,0xA1, +0x52,0xF4,0x22,0x46,0x6E,0x91,0x42,0xC4,0xED,0xBD,0xC7,0xCF,0xA6,0x91,0x6E,0xE2, +0x7E,0x87,0x67,0xAD,0x13,0x9D,0xA8,0x9D,0xC4,0x39,0x98,0x52,0xA0,0x54,0xCB,0xD7, +0xDD,0xDF,0x27,0x14,0xAE,0xFB,0x23,0x2E,0x12,0xCD,0x90,0xFD,0xDE,0x51,0x03,0x4D, +0xE4,0x33,0xDE,0xD9,0xC7,0xAB,0xB9,0xCB,0x74,0x1D,0x09,0x6B,0xFC,0xEA,0x15,0x7A, +0x49,0xE1,0x40,0xB2,0xAD,0xDA,0x74,0x0B,0xD3,0x83,0xE5,0x14,0x2B,0x80,0xD8,0xFB, +0x6F,0x85,0xC0,0xA8,0xD0,0x07,0x08,0xED,0xB5,0x1E,0x77,0x03,0xD7,0x08,0x41,0xB7, +0xCA,0xF1,0xC3,0xD2,0x18,0xDC,0x2F,0x11,0xCA,0x35,0x44,0x9D,0x95,0x83,0x0F,0x63, +0x22,0xEA,0x15,0xD8,0xDE,0x93,0xA2,0xD1,0x17,0x7B,0x40,0x93,0xFD,0x01,0x0F,0x3C, +0xE1,0x02,0xE3,0xDB,0x77,0xF6,0xE9,0x0B,0xA2,0x01,0xCF,0x85,0x4A,0x4F,0x14,0x68, +0x7E,0x48,0x62,0xC4,0xA9,0x25,0xD2,0x5E,0x48,0x67,0x13,0x7D,0xBE,0x2C,0x8E,0x84, +0x4E,0xFF,0x2D,0x54,0x5E,0xAF,0x21,0x5A,0xD1,0x8C,0xC9,0x6C,0x95,0x43,0x06,0x66, +0xF2,0xAE,0xAB,0xC3,0x90,0x42,0x6D,0x3F,0xEE,0x36,0x27,0x78,0x47,0xD9,0x32,0x34, +0xDA,0xDD,0xDE,0x93,0x42,0x56,0xE7,0x8C,0xE7,0x68,0x0D,0xF0,0x5D,0x72,0x67,0x2A, +0xE6,0xC9,0xA2,0xF9,0xF1,0x7D,0x05,0x21,0x0F,0x84,0x67,0xD1,0x58,0x66,0x4C,0x77, +0x22,0xD9,0x90,0xCD,0x3C,0x6A,0x5C,0x74,0xB2,0xC4,0x40,0x69,0x4C,0xB7,0x9E,0xBF, +0xEA,0x9C,0x6B,0x6F,0xD4,0x70,0x88,0x08,0xF5,0x09,0xC5,0x8E,0x42,0x2E,0xA4,0x5D, +0x26,0x21,0x9B,0x99,0x08,0x90,0x5D,0x93,0x1D,0xB1,0xE7,0x68,0xE0,0x89,0x1B,0x02, +0x34,0x72,0x81,0x46,0xEF,0xD6,0x23,0x23,0x43,0xA4,0x92,0x03,0x1A,0xDF,0x26,0x58, +0x26,0x7E,0x04,0x7F,0xE5,0x6B,0x58,0x97,0x42,0xC6,0x74,0x8A,0x86,0x7E,0xA6,0x10, +0xFE,0xC3,0x62,0x77,0x3E,0x95,0x48,0xED,0x18,0x25,0x13,0x5A,0x92,0xAA,0x30,0x01, +0xDA,0xA0,0x9A,0xC0,0xF7,0x93,0x7E,0x51,0xC0,0x1E,0x3B,0x2B,0x2D,0x8E,0xB8,0x43, +0x09,0x0E,0x64,0x32,0xB2,0x67,0xE4,0x2E,0x92,0x72,0xA5,0x09,0x27,0xED,0xA1,0x4B, +0x05,0x54,0xCE,0xAB,0x79,0x4D,0xB0,0xDB,0x92,0x9F,0x9D,0x78,0xF9,0x2E,0xB3,0xDC, +0x94,0xC3,0x01,0x50,0x64,0x63,0x8E,0x3B,0xCA,0x6C,0x2D,0x95,0x8A,0x4C,0xDA,0xBC, +0x56,0x6B,0x09,0xE5,0x0E,0xCC,0x1B,0x03,0x1A,0x4B,0xB3,0x80,0x91,0x5D,0x49,0xD8, +0x74,0xB8,0x45,0xCD,0x9F,0x30,0x00,0xB7,0xE3,0x7D,0x17,0x84,0x20,0x69,0xE5,0xCB, +0x42,0x94,0xEB,0x01,0xFA,0x7B,0x7E,0x84,0x70,0x81,0x72,0xF1,0x3A,0x2E,0x09,0xDA, +0x19,0x98,0xB0,0x8E,0xF5,0xF9,0x0E,0x00,0x29,0xF9,0xBC,0xC8,0x3F,0x6A,0xAD,0xFB, +0x70,0xB8,0xA7,0x23,0x67,0x97,0xAE,0x63,0xC0,0xEE,0xA3,0xAE,0x1E,0x3F,0x08,0x0A, +0x71,0xB7,0xEE,0x38,0xAF,0x71,0x2C,0x9D,0x5D,0x37,0x85,0xC2,0x99,0x2B,0xC9,0x28, +0x56,0x2B,0x33,0x24,0xBD,0x35,0x01,0x91,0x7E,0x63,0xDB,0xA5,0x56,0x48,0x18,0xBA, +0xE4,0x96,0xB7,0x15,0xA9,0x7A,0x7F,0x6E,0xE0,0xAA,0x7B,0x0E,0x76,0xCD,0xB0,0x65, +0xCD,0xCE,0x2F,0xDF,0x41,0xE0,0xA6,0x98,0xF7,0x10,0x1D,0x5E,0xE0,0x2B,0xFA,0x6D, +0x66,0x53,0xF9,0xDB,0xC1,0x27,0x51,0x75,0x9C,0x33,0x6C,0x51,0x08,0x7A,0x26,0x00, +0x04,0x7C,0x1E,0x92,0x0D,0x7B,0xE1,0x02,0x99,0x42,0x2F,0xD2,0x82,0xEC,0x67,0x74, +0x9B,0xBE,0x80,0x13,0x43,0xEE,0x14,0x24,0xE2,0x8A,0x6E,0x07,0xC7,0x74,0x29,0x14, +0x7C,0x0E,0xF3,0x63,0xB0,0x7E,0x75,0x2D,0x3F,0x2F,0x49,0x2A,0x6B,0xE6,0xF3,0x73, +0x5A,0x23,0x0E,0xE1,0xF6,0x8E,0xAD,0x07,0x0D,0xA5,0x3C,0x66,0xBF,0x65,0xE0,0xB8, +0x6A,0x6B,0xF5,0xC3,0xBD,0x60,0x2D,0xA1,0x1C,0x15,0x00,0xB6,0x2D,0xE2,0xD0,0xDD, +0xD2,0x7E,0xB5,0xC3,0x79,0x33,0x02,0xC4,0x9A,0x2B,0xA1,0x4C,0xFE,0xA0,0x6A,0x79, +0xB9,0x7C,0x85,0xFD,0xF5,0x57,0xF5,0x4B,0xC8,0x87,0xAC,0xFB,0xBD,0xB0,0xF9,0x05, +0x79,0x08,0xDE,0x8E,0x4A,0xDE,0x8A,0x17,0xFF,0xF4,0xFC,0x21,0x90,0x30,0x14,0xF2, +0x2B,0xDC,0x80,0x0C,0xE6,0xF0,0x32,0xBC,0x72,0x63,0x1B,0xCE,0xDF,0xF3,0x03,0x43, +0xF3,0xA8,0x92,0x9E,0xB2,0xB7,0xDD,0x2D,0x35,0x61,0xAC,0x02,0x3E,0xFC,0x45,0xD6, +0xC0,0xD1,0x04,0xCB,0x74,0x79,0x62,0xEC,0xE6,0xCE,0x49,0xFF,0x84,0xA2,0xB7,0xC1, +0x48,0x17,0x54,0x7A,0x3C,0x79,0xEE,0xDC,0xC6,0xA4,0xDF,0xD1,0xB6,0xCE,0xF5,0x49, +0xA9,0xE2,0xD5,0x70,0x0E,0x29,0x3C,0xC2,0xD4,0x0B,0x60,0xE2,0x31,0x77,0x6C,0x43, +0x2F,0xDC,0x71,0x17,0xE5,0x19,0x62,0x46,0xE6,0x25,0xDB,0xE1,0xB6,0x3E,0x14,0x75, +0x3D,0x96,0x7C,0x24,0x08,0x7F,0xA0,0xD0,0x2E,0x9F,0x0B,0x5B,0xAA,0xE7,0xEE,0x90, +0x75,0x50,0x30,0x77,0xAA,0xCF,0x44,0x12,0x1E,0xF8,0xE1,0xD8,0xDB,0x3E,0x81,0x29, +0xC3,0xEE,0x8D,0x54,0xE1,0x4F,0xE3,0x49,0x27,0x8B,0x33,0x7C,0xA6,0x8F,0x35,0x29, +0x87,0x79,0xF2,0xB1,0xEB,0x57,0x97,0xF8,0xB6,0xC3,0x22,0x37,0xD2,0x55,0x84,0x1D, +0x72,0xDA,0x66,0xAD,0x74,0x0E,0x09,0xED,0xE8,0x83,0xCB,0x06,0xFC,0x34,0x64,0x8F, +0x67,0xAC,0xC2,0x08,0x72,0x04,0xE7,0x06,0xDE,0xFE,0x0B,0x6A,0x11,0xC7,0xDF,0x2D, +0x48,0x4D,0x20,0x1D,0x3C,0xCD,0x6B,0xAD,0x4C,0xAD,0x43,0x6C,0xCE,0xCD,0x5D,0x90, +0xBB,0xF4,0xFD,0xED,0xD2,0xA7,0x45,0x32,0x2F,0x32,0xE8,0x9B,0x5F,0x17,0x7C,0x35, +0x9B,0xEA,0xDD,0x55,0xBD,0xD4,0x63,0xFB,0x5C,0x6A,0xA8,0x63,0x12,0xEE,0xBF,0x81, +0x10,0x00,0x46,0x6F,0x66,0xF1,0xDE,0x00,0x22,0x41,0xC1,0x89,0x44,0xB6,0x41,0xF6, +0x9F,0x08,0x9E,0x8D,0x01,0x47,0x2F,0xDA,0xDE,0xCC,0x62,0xA9,0xF4,0x00,0x5C,0xF7, +0x96,0x4B,0xE0,0xE0,0x17,0x5D,0x90,0x7E,0x4D,0xB7,0x04,0xA9,0xFE,0xED,0x2D,0x6E, +0xA4,0x86,0xA2,0xAB,0xF2,0x42,0x2C,0x87,0x4A,0x18,0x34,0x85,0x1E,0x8C,0xDB,0xC3, +0x22,0x29,0xB8,0x6D,0x17,0x03,0xB6,0xCB,0xFB,0x31,0x5D,0x82,0xDB,0x35,0x12,0xD5, +0x28,0x1A,0x26,0xC1,0x59,0x60,0xAC,0x4D,0x56,0x45,0xBC,0xB0,0x5C,0x55,0x55,0x72, +0x6B,0x1F,0x85,0x03,0x14,0xFB,0x85,0x92,0x7C,0x89,0x13,0xB7,0x27,0x56,0x7A,0x3C, +0x03,0x2D,0xBB,0x04,0x76,0x37,0xC8,0xF7,0xDA,0xB0,0xE3,0x33,0xE3,0xB5,0x0F,0x41, +0xD6,0xFC,0x21,0x21,0x5A,0x97,0xFF,0x40,0x61,0x25,0x12,0x15,0x92,0xAA,0x54,0xEB, +0x77,0x2C,0x77,0xE6,0xAE,0xF1,0x1C,0xB3,0xF3,0x81,0x03,0x59,0xA4,0xDA,0xFF,0x00, +0xCB,0xD5,0x6B,0x3B,0xD5,0xBD,0x31,0x44,0xA6,0x9E,0x02,0xF4,0x29,0x1D,0x3D,0x0D, +0x64,0x81,0x72,0x0B,0x2E,0x4E,0x04,0xD3,0x81,0x78,0xB2,0x28,0x90,0x96,0x3D,0x9E, +0x60,0x95,0xF1,0x86,0xA8,0x60,0xDF,0x1B,0x10,0x78,0x01,0x43,0x67,0x95,0x2A,0x66, +0xEC,0xFF,0x2B,0xAC,0x1B,0xF0,0x3C,0xA6,0x03,0x4F,0xFE,0xEB,0x78,0x4D,0xA6,0xEB, +0xE3,0xB1,0xBB,0x77,0xBB,0x51,0x27,0x94,0x30,0xAD,0xD7,0xC1,0xCE,0x56,0x3B,0xBE, +0xEF,0xD3,0x78,0x58,0xC1,0xC0,0x73,0xED,0x43,0x35,0xFA,0xE0,0x7A,0x1E,0xD5,0xD0, +0x90,0xFB,0x62,0x97,0x60,0x2B,0x18,0x92,0xB6,0x43,0xF1,0x3B,0xD4,0x0B,0xAF,0xCC, +0x9E,0x63,0x60,0xBC,0x11,0xB5,0x47,0x67,0xA0,0x09,0x1B,0xEB,0x21,0x76,0xBB,0xCA, +0x03,0x3D,0x58,0x24,0xFF,0xC0,0x04,0xC5,0xB6,0x86,0x37,0x4D,0x02,0x1E,0xC8,0x2D, +0x03,0xB9,0x90,0xF0,0xDD,0xF3,0xFC,0x4F,0xBC,0x5F,0x92,0x1B,0x0D,0x5B,0xE4,0xB6, +0x36,0x35,0x1C,0x55,0x4D,0xC5,0x28,0xF2,0x0D,0x30,0x2E,0xA7,0x81,0x0D,0xCE,0x25, +0x93,0xAE,0xF5,0x6F,0x4F,0x08,0xD2,0x01,0x87,0x6A,0x4A,0x9A,0xA7,0x3F,0x3C,0xCF, +0xFB,0xA7,0x8C,0x97,0xAA,0x0B,0x5D,0xE2,0x13,0x4E,0x0F,0x30,0xD3,0x03,0x60,0x98, +0x48,0x63,0xE0,0xC3,0x7A,0x5B,0x20,0x22,0xF9,0x6D,0x17,0xF8,0x22,0x35,0xDD,0x4B, +0x6D,0x11,0x9F,0x1B,0x95,0x53,0x7C,0xCE,0x03,0x14,0xD3,0x8D,0x53,0xB1,0xAB,0x32, +0x5F,0x7C,0x80,0x59,0x87,0xE0,0xAD,0xCF,0xD6,0x07,0x5D,0xDD,0xF6,0x3E,0xF0,0xB8, +0x12,0x21,0x0F,0x9C,0x68,0xD0,0x32,0xC1,0x15,0xFF,0xDA,0x33,0x50,0x97,0x90,0xED, +0x0B,0x38,0xFE,0xC1,0x78,0xBB,0xDD,0x65,0xBF,0xD5,0x22,0xB7,0xF5,0xB6,0xB7,0x88, +0xAA,0xA7,0x84,0x55,0x60,0xD1,0x77,0x64,0x4F,0xAA,0x0A,0x42,0x9B,0xC7,0x8A,0x6F, +0x84,0xE0,0xD4,0x00,0x5A,0xFF,0xDC,0xD6,0x89,0x4D,0x8E,0x23,0x9A,0xA6,0x7E,0xF5, +0x21,0xA1,0x85,0x50,0xD0,0x04,0x91,0x86,0x82,0x42,0xCD,0xF3,0x29,0xE1,0x2C,0xCF, +0x26,0xBE,0xD1,0x60,0xE6,0x13,0xB4,0xD3,0x34,0x7D,0x84,0x53,0x66,0x93,0x52,0xE6, +0xD8,0xF9,0x75,0x91,0xF9,0x71,0xD1,0x0D,0xF7,0x88,0x85,0xA3,0xAF,0x9B,0x9D,0x45, +0xDB,0x40,0xC9,0x99,0x01,0xA9,0x50,0x21,0x04,0xA1,0xF4,0x0B,0x4E,0x9C,0xCD,0xED, +0xC3,0x84,0xB0,0x08,0xB9,0xF5,0x6D,0x44,0xF2,0x17,0x26,0x3E,0x56,0x5A,0xFF,0xD9, +0x10,0x3B,0xE2,0x4C,0x83,0xCD,0xAD,0x8E,0x23,0xAA,0x84,0x00,0xBF,0xEB,0xF3,0x15, +0x09,0x71,0x4A,0x6F,0xEB,0x64,0xF5,0xA2,0x68,0x80,0xAB,0x1F,0xCB,0x37,0x18,0x53, +0xA3,0xF5,0x3B,0x8F,0xD7,0x7F,0x49,0xD5,0x7C,0xFD,0xEF,0xBA,0xC7,0x29,0x78,0x22, +0x14,0x07,0xB9,0x04,0x50,0x97,0x12,0xC1,0x83,0x7C,0x37,0x3E,0x9D,0x1F,0x63,0xE4, +0xF3,0x45,0x53,0xAF,0x17,0xCE,0x8A,0x88,0x78,0x66,0x0E,0x82,0x46,0x9C,0x74,0x64, +0x16,0xEA,0x07,0xA0,0x6F,0xFA,0xD1,0xA3,0x05,0x3A,0x2B,0x07,0x06,0x1B,0xA4,0x57, +0xFF,0x8B,0xDB,0x20,0x85,0xBF,0x47,0xF3,0x7A,0x00,0x74,0x23,0xE2,0x36,0xFF,0xC6, +0x37,0x6C,0x33,0x19,0x00,0x5F,0x13,0x36,0xF5,0xB2,0xDA,0x1A,0x1D,0xE5,0x4E,0x63, +0x00,0x05,0xFB,0x31,0x0C,0x34,0x72,0x00,0x00,0xEA,0x70,0xD0,0x9F,0x13,0x71,0x3A, +0xA5,0xE4,0x3B,0x59,0xBA,0x03,0x73,0x51,0x14,0x34,0x79,0x08,0x79,0xF0,0x92,0xCF, +0x50,0xD4,0xAD,0x21,0xA5,0x43,0x29,0x91,0x1F,0x7E,0x69,0xB9,0x81,0xAF,0x5A,0x07, +0xC4,0x6C,0xCA,0x02,0x12,0xF5,0xF2,0x1E,0xC1,0x83,0xAB,0x09,0x75,0x25,0xC7,0x75, +0x39,0x3B,0x7A,0xD1,0x62,0x1C,0xC7,0x61,0xD2,0xBF,0xAF,0x9A,0x72,0x75,0xAE,0x49, +0xBF,0x88,0xA9,0xBF,0x80,0x64,0x0A,0x26,0xBE,0x60,0xB4,0x28,0x5A,0xB3,0x8A,0x32, +0x85,0x6A,0x7C,0x99,0x35,0x90,0x51,0x36,0x9A,0x94,0xFB,0x14,0x31,0xD4,0x1D,0x67, +0x6A,0x26,0xE3,0xAF,0xA3,0xD8,0x35,0x49,0x75,0x2D,0x5B,0x6B,0xC5,0x12,0xFF,0x7F, +0x25,0x92,0x8C,0x60,0x85,0x42,0x28,0x85,0xF3,0xBB,0x95,0x16,0x2F,0x54,0xC3,0x42, +0x18,0xBE,0x79,0x1B,0x8D,0x43,0x74,0x84,0xF1,0x68,0xDF,0xA7,0xEE,0x88,0x15,0x82, +0x36,0x41,0xF6,0x8C,0xFC,0x36,0x43,0x6A,0x41,0x2E,0x9E,0x9B,0xBF,0xE0,0x7E,0x91, +0xEF,0xCA,0x8F,0x2E,0xAA,0xE8,0xF9,0xDA,0xF2,0x59,0x78,0xDF,0x0E,0x27,0xEE,0x8A, +0xA0,0x72,0x0D,0x2F,0x49,0x60,0x15,0x92,0xF2,0x9A,0x69,0x4A,0x68,0x3A,0x35,0xE8, +0xAA,0xE0,0x79,0x6C,0x9E,0xFF,0x1C,0xF7,0xAC,0xAE,0x82,0x0C,0xF4,0x09,0x58,0x13, +0x5E,0x74,0xE0,0x1F,0x7F,0xCD,0x1E,0xC0,0x5D,0x39,0x0A,0x08,0xD2,0xF1,0xB6,0x1F, +0x36,0xBA,0x56,0x4D,0x9F,0xF4,0x6C,0xB7,0x47,0x6A,0xE0,0x98,0xFD,0x45,0xE6,0x7C, +0x8B,0xB1,0x8E,0x56,0xB4,0x56,0x7F,0x5A,0x5C,0xE7,0xF0,0x59,0x0A,0xC2,0x52,0xED, +0x07,0xD6,0x91,0x1B,0x01,0xC8,0x4A,0xE2,0x2E,0x54,0xCC,0x9A,0xFC,0xE7,0x96,0x5D, +0x02,0xAC,0x2A,0x56,0xB3,0x6D,0xED,0xA1,0x7F,0x93,0x00,0x74,0xE9,0xE5,0xE9,0x68, +0xA4,0x06,0xF1,0x45,0x67,0x6A,0xB4,0x0C,0x8A,0x1F,0xDB,0x73,0x37,0x07,0x91,0xF7, +0x30,0x16,0x42,0x41,0x2F,0x15,0x0B,0xC7,0x18,0xD0,0xEF,0x31,0x66,0x29,0xDC,0x34, +0x6A,0xE0,0x77,0x59,0xE7,0xAC,0xDC,0xCA,0xC6,0xC9,0xB6,0x98,0x77,0x9B,0x4F,0x61, +0x18,0x3B,0x53,0x44,0x51,0x64,0x37,0x36,0x0E,0xDB,0x65,0x4A,0x45,0x0E,0x5C,0xE1, +0x03,0x29,0x41,0xCF,0x69,0xC6,0xF2,0xB6,0x37,0x8D,0xA9,0xC6,0xB6,0xE9,0x51,0x15, +0x53,0x13,0xBE,0x24,0x9F,0xE3,0x62,0x0B,0xBD,0x1D,0x1D,0xE8,0x00,0x9A,0x1D,0x92, +0x51,0xE9,0x54,0x2A,0x44,0x8F,0xCF,0xF1,0x10,0x52,0xD0,0x37,0xDC,0x57,0x32,0x0F, +0xA2,0xF7,0x12,0xEA,0xA9,0x73,0x3C,0xBF,0x55,0xD4,0x73,0xA3,0x84,0xB6,0xCF,0xEF, +0x14,0x18,0xEB,0xF0,0xBB,0x42,0x43,0xB7,0x03,0xC0,0x0A,0xA4,0x3C,0xA0,0x0A,0x6A, +0x9C,0x2F,0x4C,0xE4,0x1A,0x3E,0x51,0x37,0xDB,0xD5,0x8C,0x5D,0x21,0x40,0x4E,0x9F, +0xFB,0x41,0xCB,0x91,0x58,0x37,0xB6,0x6B,0x7B,0x9D,0x52,0xE0,0x89,0x69,0x7D,0xE6, +0xEB,0xD8,0x0C,0x0F,0x98,0x51,0xB3,0xA7,0x5A,0xF7,0x00,0xFA,0xF6,0x2D,0xB3,0xC3, +0xAC,0x31,0x20,0x1F,0xE2,0xAA,0x0A,0x95,0xCF,0x28,0xC8,0x02,0x19,0x3A,0xB8,0xE4, +0x5D,0xBF,0x86,0x05,0x4F,0xAD,0xAE,0x8A,0xFE,0xCC,0x71,0x1B,0x2E,0x9B,0x48,0xD2, +0xC8,0x14,0x98,0xCE,0xF0,0x23,0x58,0x9B,0xEB,0x8E,0x5F,0x6A,0xC1,0x97,0x1B,0xDB, +0x13,0xC7,0x12,0x32,0x93,0xFB,0xF9,0x99,0xE2,0x9B,0x04,0xF8,0x66,0x3F,0xD4,0x92, +0xF6,0x43,0x35,0xD8,0xE3,0x68,0x9A,0x59,0x2A,0x43,0x29,0x0A,0xF7,0x3C,0x3D,0xBA, +0x93,0xAD,0xDE,0xC3,0xCD,0x46,0x1E,0x5A,0x1E,0xE6,0x81,0xF6,0xAD,0xD4,0xF3,0x7C, +0xDD,0x4F,0xC2,0x32,0x97,0xF5,0xEA,0x09,0x1C,0xDF,0x6A,0x9E,0xB0,0x8D,0xE8,0x73, +0xAA,0x19,0x3F,0xE1,0xD4,0xF9,0x6D,0x12,0x42,0x6F,0xC2,0xB4,0x4F,0x9D,0xCC,0xF8, +0x72,0xB4,0xCF,0x57,0x52,0x64,0x86,0x30,0x26,0x5E,0x87,0x77,0x25,0xC2,0x5A,0x3C, +0x67,0xFE,0x62,0x94,0x4F,0x31,0xA8,0x7C,0xB4,0xBE,0x63,0xDB,0x7C,0x95,0x06,0x1B, +0xAD,0x54,0x83,0x35,0x0F,0xBF,0x5E,0x75,0xCB,0x47,0xF9,0x71,0xB6,0xB2,0xF9,0x31, +0xC6,0x53,0x9E,0x8A,0x6C,0x8B,0x1C,0x39,0xF3,0x8F,0x48,0x7F,0x0F,0xBA,0x56,0xEC, +0x4E,0x82,0xCF,0x5C,0x99,0xF1,0x1A,0x05,0x37,0xBF,0xB6,0x69,0xAF,0x15,0xDE,0x5F, +0x8E,0xD6,0x35,0xD6,0x1E,0x96,0x7C,0x2C,0x1A,0xF2,0x1B,0x5C,0x54,0x85,0xD2,0x44, +0x9C,0xC4,0xE4,0xF8,0xDC,0x6A,0x18,0x70,0x0F,0x93,0xE0,0xD6,0xAB,0xA1,0xCD,0x30, +0xFB,0x31,0x25,0xFC,0xFC,0x07,0xE3,0x6E,0xE0,0x85,0xBF,0xE9,0x2A,0x2C,0xBD,0x65, +0x63,0x66,0x07,0x41,0x1E,0x5D,0xBC,0xAD,0xA4,0xCA,0x1E,0x9C,0xE3,0x66,0x4F,0xD4, +0x56,0xC4,0xDF,0x2A,0xA4,0x76,0x38,0x44,0x9B,0xF5,0x93,0x3A,0x0F,0x9C,0xAB,0xA1, +0xFB,0x37,0x14,0xD0,0x8F,0xBB,0x9D,0x58,0xB4,0x48,0x07,0x77,0xC2,0xBC,0xB6,0x2E, +0x68,0xA9,0x47,0x37,0xC0,0xDD,0x1E,0x53,0x18,0x34,0x50,0x31,0xB0,0x8F,0x3E,0xC2, +0xE8,0xDF,0x3B,0x04,0x66,0xE5,0xE6,0x5E,0x6E,0x1B,0x82,0x8F,0xD7,0x60,0x8A,0x42, +0x38,0x9D,0xB1,0x14,0xA5,0xE4,0x9D,0x96,0x45,0x79,0x7A,0x3D,0x0D,0x0F,0x85,0x26, +0x6A,0xFE,0x1D,0x26,0xE2,0x78,0x54,0x71,0xB0,0xC4,0xC0,0x01,0x82,0x4C,0xD3,0xBD, +0xEF,0x42,0x13,0x0B,0x31,0x73,0x85,0x70,0x2E,0x45,0xF2,0x9D,0x8E,0x72,0x1A,0xC9, +0x9B,0x08,0x95,0x5C,0x9C,0x9E,0xE0,0x2E,0x57,0x69,0x7A,0x18,0x70,0x07,0x1A,0x93, +0xD4,0x8C,0x88,0x8E,0x25,0xD0,0xB5,0x88,0xFB,0x52,0x77,0x9D,0xE2,0xBD,0x5C,0x63, +0x86,0xFB,0xB6,0x6C,0x10,0xC6,0xDC,0xF8,0x63,0x6D,0x42,0x05,0x91,0x85,0x86,0x27, +0x41,0x5F,0x94,0xAC,0x42,0x5A,0xD2,0x26,0x04,0x7C,0x5F,0x89,0x83,0x7A,0x3C,0x63, +0xCD,0x00,0x9E,0x66,0xEA,0x3A,0x3C,0x6D,0x78,0xE9,0xC9,0xB9,0xF3,0xE8,0xCA,0x86, +0x5E,0x6E,0x32,0x82,0xB5,0xB9,0x6B,0x36,0xE8,0xC5,0x47,0x02,0xA7,0xB8,0x2D,0x5A, +0x17,0xB1,0x7D,0xED,0x74,0x52,0x14,0x08,0xE0,0x43,0x27,0x7A,0x0B,0xC8,0x97,0xD8, +0x3A,0x1E,0x20,0x5D,0x3B,0x74,0x07,0xC3,0xEA,0x64,0xCF,0xE0,0x0F,0x98,0xFE,0xFD, +0x52,0x42,0xDC,0xFC,0x1B,0xCD,0x24,0xC6,0xFD,0xD3,0x7B,0xFF,0xFE,0xDA,0x60,0xB3, +0x4C,0x76,0xE9,0x70,0x96,0xE0,0xB5,0x74,0xDA,0x33,0x24,0x1E,0x32,0x3E,0xBF,0x51, +0xC2,0x3D,0x6A,0x76,0xB2,0x07,0x35,0x8E,0x26,0x0C,0x31,0xD6,0xEC,0x8C,0x3B,0xD1, +0x68,0x0D,0x75,0xBC,0xD3,0xBE,0x46,0x27,0xCF,0x32,0x47,0x9D,0x0B,0x60,0x3C,0xDA, +0x0D,0xC4,0xD9,0x97,0xC2,0x00,0x21,0xEF,0xA3,0x0B,0xBF,0xFF,0x0F,0xAA,0x82,0x9F, +0x33,0x76,0xE9,0x85,0xEC,0x71,0x91,0xBB,0xBB,0xD4,0x09,0xC0,0xD5,0x96,0x84,0x2C, +0x13,0xBC,0xAF,0xD0,0x88,0x8C,0x4C,0x17,0xA0,0xC5,0x35,0xCF,0x1D,0xC5,0x3C,0xD5, +0x35,0xF7,0x79,0xE8,0x87,0x05,0x08,0x5B,0xDE,0x1B,0x68,0x68,0x70,0xCB,0x69,0x09, +0xDB,0x41,0xA7,0xD6,0x4A,0xFC,0xDE,0xAA,0x22,0xFD,0x56,0x11,0x77,0x49,0x1C,0x42, +0x84,0x04,0x33,0xD7,0x7A,0xD7,0xBB,0x44,0x93,0x93,0xDB,0xCF,0xA5,0x7B,0x1E,0xB4, +0x78,0x90,0xEA,0x35,0x0F,0x54,0xBF,0x59,0xA3,0x34,0x00,0x79,0x90,0x07,0x2A,0x94, +0xFE,0xE2,0xD6,0xAF,0xF7,0x20,0x36,0x30,0xBC,0x77,0x86,0xCE,0x40,0xBB,0xB3,0xEB, +0x7E,0x76,0xDC,0x48,0x15,0x05,0x24,0xBF,0x24,0x54,0xB7,0x7C,0x6C,0xA3,0x4F,0xE8, +0x92,0x45,0x91,0xFF,0x5E,0x17,0xDB,0x0B,0xB7,0xF6,0x48,0xFC,0x5C,0x38,0x8C,0xBC, +0xFC,0xDC,0x96,0x3B,0x8E,0x65,0x32,0x6B,0x12,0xDB,0xCC,0xF8,0x35,0x5E,0x24,0x9B, +0xED,0xC6,0xD9,0x35,0x4A,0x7B,0x0A,0x23,0xFC,0xD8,0xD6,0x26,0x08,0xD0,0xDF,0x30, +0x8B,0x9F,0x99,0x62,0xB0,0x1B,0x8A,0xA1,0xB9,0xDE,0xE3,0x12,0xDF,0xEF,0x37,0x15, +0xE5,0x4C,0x5C,0xC7,0x88,0x1D,0x8D,0xF4,0xC1,0x54,0x96,0xF6,0xF8,0xC6,0x71,0x25, +0x4F,0x0A,0x12,0x16,0x49,0x43,0x23,0xE9,0xA2,0xCE,0xBF,0xD4,0x65,0xE2,0x04,0x27, +0xEE,0x55,0x4E,0x7E,0x11,0xA6,0xA0,0x4D,0xC9,0xD4,0x80,0xD3,0xD9,0x6B,0xC5,0x55, +0x98,0x97,0xE5,0x0D,0xF1,0x0F,0xD8,0x04,0xCC,0x3E,0x94,0xC1,0xE8,0xEB,0xF8,0x95, +0xE9,0x85,0xDF,0x0C,0x39,0x55,0x50,0x6D,0x28,0x5D,0x43,0x11,0xAD,0xBB,0x84,0x52, +0xE4,0xC8,0x27,0xDA,0x83,0x52,0x56,0xC3,0x43,0x4B,0xC8,0xD2,0xB4,0x16,0x71,0x84, +0x73,0x27,0x71,0x18,0xCC,0x26,0xE6,0xE0,0x54,0x37,0x71,0xEE,0xBC,0x0F,0xD1,0xB3, +0xE2,0x9F,0xEE,0x8E,0x1D,0xC0,0xE7,0xC9,0xDF,0x62,0x6E,0x18,0xC3,0x36,0xA4,0x91, +0x53,0xBE,0x44,0x65,0xD4,0x5C,0x76,0x4F,0x02,0x38,0x47,0x3C,0xB8,0x74,0x80,0x2D, +0xB9,0x2B,0x1E,0xF4,0x1F,0x1E,0x5F,0xFB,0xF0,0xEC,0x98,0x78,0xE9,0x18,0x74,0xE0, +0xC0,0x15,0xFA,0x2C,0xFC,0xCB,0xCA,0x9B,0x62,0x30,0x24,0xA1,0xFA,0x6F,0xFC,0xFD, +0x3D,0x56,0x1C,0x40,0x76,0x8E,0x2E,0x44,0xF4,0xAE,0xC6,0x1A,0x24,0x24,0x22,0xFA, +0x80,0xEB,0xE9,0x2B,0xC2,0xC0,0x7D,0xBD,0xDD,0x18,0x1F,0x2E,0xE5,0x47,0xB6,0x8C, +0x4F,0x76,0x00,0x64,0xB3,0x8D,0xEF,0x82,0x17,0x6A,0x35,0xC5,0x48,0x25,0xE6,0xF6, +0x36,0x93,0xCD,0xD9,0x68,0x2F,0x48,0x58,0xE8,0x64,0xF4,0xCE,0xBB,0x42,0xAE,0xB4, +0x1B,0x48,0x78,0xA1,0xE9,0xE0,0xA3,0x84,0x61,0x4E,0x51,0x72,0x86,0x02,0xF2,0x92, +0x5F,0x22,0xAD,0x9C,0x0E,0xA0,0x2B,0xDB,0x28,0xC1,0x42,0x7F,0x9F,0xA6,0x7C,0x03, +0x20,0xD6,0x94,0x5C,0xB4,0x27,0xB6,0x05,0x3E,0x85,0x06,0xFD,0x60,0x94,0x4E,0x4B, +0x7A,0x92,0x6B,0x83,0xCB,0x46,0x05,0x9D,0x82,0x2C,0x76,0x6A,0x9B,0x3F,0xFB,0xD6, +0xFD,0x14,0x51,0x9F,0x45,0x76,0x5B,0xDE,0xED,0x6E,0xF2,0xAA,0x3E,0x74,0x59,0x41, +0xC2,0xB2,0x24,0xD4,0xCD,0xED,0xE4,0xAD,0x52,0x6E,0x42,0x63,0xDA,0x50,0xED,0xDF, +0x07,0x0D,0x03,0x1F,0xF1,0x89,0xBE,0xAB,0x2B,0xC7,0xF5,0x07,0x4B,0x18,0x28,0x33, +0x51,0xD8,0x85,0x94,0x4B,0x6A,0xD6,0x09,0x57,0xE8,0xC3,0x31,0x43,0xFC,0x78,0x80, +0x6F,0xC1,0x0E,0xFE,0xF5,0xA7,0xE7,0x94,0x0E,0x4F,0xFC,0xF0,0x2F,0x13,0xEA,0x0D, +0x77,0xC7,0xC2,0x65,0xCC,0xAA,0xD1,0xB6,0x49,0x7E,0x2B,0x7D,0x8D,0xA9,0x44,0x77, +0x49,0x2D,0x0C,0xEA,0xF5,0xD5,0xA6,0xAA,0x33,0x63,0xA2,0xD8,0x3A,0xB0,0x33,0xBA, +0xD5,0x0B,0x66,0xE7,0x0E,0xAF,0xF1,0x1C,0x6C,0xF4,0xDA,0x72,0x1D,0x6E,0xCA,0x09, +0xAE,0x94,0xA7,0xBA,0xB0,0x8E,0x22,0x3D,0xED,0x93,0xBA,0xEF,0x5D,0xD5,0x80,0xA2, +0x41,0x93,0xB3,0x5D,0x3B,0xE8,0x3D,0xA0,0x59,0x74,0xFB,0xE3,0x3B,0x04,0xF4,0x0F, +0x23,0x74,0x3A,0xD1,0xAD,0xF6,0xF2,0x18,0x16,0x6D,0xB3,0x2E,0xAD,0xD5,0xD3,0x11, +0x22,0x0E,0xF1,0x4E,0x1F,0x9A,0x88,0xAD,0x85,0x1D,0xDE,0x2F,0x2D,0x4B,0x18,0x99, +0xC4,0x9D,0xA1,0x82,0x15,0x18,0xF0,0x48,0x80,0x2F,0xD2,0xAD,0x35,0x1E,0x7A,0x8D, +0xF7,0x84,0x3A,0xC3,0x08,0x98,0x4E,0x81,0x58,0x91,0x34,0xA6,0xC0,0x3C,0xE3,0x5C, +0x26,0xBF,0xBC,0x54,0xD5,0x75,0x81,0x58,0xE0,0xA6,0xD3,0x06,0x9A,0x22,0x9C,0x2F, +0x6E,0x99,0xB3,0x1D,0x78,0xDF,0x57,0x5A,0x25,0x64,0x74,0xDE,0x36,0xFD,0xA4,0x4C, +0x9C,0x0C,0xA4,0x37,0x5A,0x7E,0x4B,0xA8,0x30,0xB0,0x15,0xA7,0xAC,0xBE,0x6A,0xE9, +0xD5,0x8F,0x95,0xB9,0x74,0x3D,0xC6,0xD5,0x8E,0xD2,0x20,0xFA,0xB6,0x63,0x7E,0x5A, +0x2B,0xD6,0xD2,0x85,0xA1,0x27,0x2D,0xD4,0x76,0xCD,0x5C,0x42,0x1B,0xEC,0xD0,0x57, +0x2B,0x28,0xC0,0xF4,0x37,0x2B,0x01,0x26,0x6E,0x9E,0xA8,0x5A,0x27,0x72,0xE9,0x7D, +0x6A,0x4B,0x0D,0x3F,0x57,0x0B,0x4D,0x35,0x7C,0x33,0xCF,0xE5,0x8C,0xD3,0x42,0xB7, +0x84,0x7A,0x1C,0xA0,0xF8,0xE2,0x46,0x91,0x07,0xA1,0x4A,0xBA,0xAD,0x14,0x7B,0x01, +0x2A,0xB3,0xAD,0x0F,0x29,0xB6,0xDC,0x0E,0x02,0x5E,0xB1,0xAE,0xC8,0xBB,0x00,0xFB, +0x04,0xEC,0x1C,0x9D,0x12,0x68,0x4A,0x95,0x1B,0x09,0x5D,0x2F,0x24,0x63,0xBE,0x8B, +0x4E,0x39,0x96,0xA6,0x7F,0xDD,0xEC,0x81,0x39,0x57,0x50,0xB8,0x26,0xEE,0x5C,0x88, +0xCC,0x5E,0xA5,0x60,0xD0,0xCD,0xE7,0x0A,0x04,0x9C,0x80,0x33,0xDF,0x56,0x5A,0x91, +0x62,0xBD,0xCE,0x6D,0xB1,0x9F,0x85,0xFC,0xCD,0x5D,0x48,0xEA,0xD2,0xBE,0xCE,0x58, +0x17,0x4B,0xAD,0x40,0x1C,0x10,0x99,0x7E,0x74,0xD3,0x5E,0xCE,0xC7,0x52,0x40,0xFB, +0xA3,0x27,0xA1,0x14,0x5A,0xC7,0xBA,0x2D,0xA7,0xFE,0xA7,0xD5,0x58,0xAD,0x31,0xBD, +0xD0,0x54,0x46,0x18,0x94,0xFB,0xF2,0x8A,0xC7,0x3C,0x04,0x4F,0x73,0x6A,0x99,0x0C, +0x19,0x6A,0x58,0x70,0x5F,0x7D,0x05,0x36,0xD2,0xC5,0x41,0x6A,0x2E,0xF8,0x06,0x8C, +0x53,0x2C,0x41,0x5A,0xBD,0xCD,0xA2,0xE4,0x17,0x63,0xFA,0xF5,0xC3,0xDE,0x86,0x38, +0x7D,0x6B,0xCD,0x1C,0xA7,0x6C,0x41,0x7A,0xA9,0xEB,0xF3,0xCD,0x95,0xBE,0x4C,0x39, +0x1D,0x76,0x7D,0x01,0xEC,0x6B,0x91,0x3C,0x28,0x75,0x8B,0x10,0xE8,0xAA,0x92,0xEA, +0x6D,0xDF,0xBE,0x02,0x70,0x12,0x63,0x2E,0x45,0x11,0xE4,0x9D,0x0C,0xB5,0x87,0x57, +0xA8,0x5B,0x75,0xF4,0x49,0xD7,0x10,0x3C,0x9D,0xC1,0x30,0x7F,0x53,0x27,0xAE,0xB4, +0xC4,0xE0,0x82,0x18,0x06,0xA0,0xDE,0x6F,0x13,0x47,0x03,0x0F,0x30,0xC1,0x1E,0x36, +0x5B,0x4C,0x14,0x03,0x2A,0x74,0x9B,0x65,0x07,0x5D,0x90,0x31,0x5D,0x45,0x85,0x50, +0x7C,0x7E,0x76,0x9E,0x91,0x5E,0x02,0xE4,0x4F,0xE9,0x97,0x50,0x52,0xE8,0x3F,0x7D, +0xD2,0x56,0x1B,0x3E,0xAF,0x3D,0x43,0x5E,0xB1,0x89,0x92,0xC6,0x0D,0x8E,0xDA,0x05, +0x91,0x31,0x5E,0xCC,0xC0,0x03,0x17,0x4C,0x46,0x6D,0xC2,0x64,0xC6,0x3E,0x50,0x6C, +0x52,0x25,0x1E,0x0D,0x5B,0x05,0xAE,0xD9,0xF7,0xB2,0x2D,0x36,0x3F,0xF4,0x8A,0x88, +0x66,0x37,0x5D,0x92,0xD0,0x82,0x2B,0x6C,0x6C,0x66,0x06,0xDD,0x4A,0xF7,0x43,0x85, +0xF4,0xFC,0xA8,0x1C,0x55,0x7A,0x18,0x81,0x55,0x6B,0x65,0xAF,0x56,0x85,0x2A,0x79, +0x03,0x64,0x8A,0xB2,0xD1,0xB9,0x83,0xA0,0x72,0x52,0x14,0x14,0x63,0x5A,0xD6,0x4A, +0x1B,0xF8,0x4E,0xE0,0x15,0x04,0x33,0x34,0x59,0x04,0xD8,0x99,0x89,0x15,0x8F,0x14, +0x5D,0x83,0x2D,0xE7,0x26,0x37,0x6E,0x6F,0x8F,0x86,0xA1,0x02,0x02,0xEF,0x6E,0x10, +0xBD,0x6B,0x93,0x59,0x0B,0xA2,0x15,0xA3,0x30,0xB0,0x2C,0xDC,0x58,0x7B,0xCB,0x63, +0xAD,0x15,0x61,0xCE,0x17,0xBE,0x86,0x90,0xA3,0x5F,0x7E,0xAC,0x17,0x8E,0x1F,0x15, +0xA4,0xAB,0xA0,0x8F,0x05,0xC3,0x0F,0x63,0x1F,0xFC,0xE3,0xC3,0x86,0x32,0x0A,0xCD, +0x14,0x21,0x7E,0x93,0xCD,0x78,0x37,0xEE,0xA2,0xA7,0xD2,0xE7,0xC1,0xE5,0xF4,0x48, +0x99,0xED,0xF7,0x39,0x57,0xFB,0x73,0x6F,0x6A,0xDD,0x46,0x9C,0xEE,0xE4,0x76,0x1C, +0xB7,0xD4,0x42,0x55,0x0D,0xB5,0x36,0x6D,0xA3,0x7D,0xEA,0x2F,0x8A,0xA8,0xE7,0x93, +0x80,0x5D,0x92,0xB0,0x98,0x70,0x1F,0x62,0xBD,0xA3,0x65,0xFC,0x25,0x6F,0x45,0x05, +0x6E,0xFC,0x1A,0x86,0x53,0x7E,0x27,0x2D,0x1F,0x25,0x17,0x95,0xFB,0xF0,0xD1,0x26, +0x56,0xF5,0x12,0xBA,0xB6,0x53,0x78,0x5F,0xFC,0xBD,0x4E,0xBA,0x66,0xB9,0x9A,0xD7, +0xFC,0x92,0xE2,0x50,0x55,0x32,0xBD,0x1C,0x3A,0x7B,0x99,0xAB,0xE8,0xFA,0x0E,0x04, +0x47,0xEA,0x6A,0xDF,0x3F,0x77,0xDD,0x66,0x79,0xE1,0xC9,0xA2,0xA1,0x55,0x90,0xB7, +0x80,0x4A,0xBB,0x5D,0x6C,0x14,0x0B,0x41,0xA4,0x96,0x9D,0x94,0x60,0x4C,0xCA,0x4B, +0x7F,0x6C,0x8D,0xB3,0x9C,0xE5,0x4D,0x4A,0x9F,0x19,0x6C,0xE9,0x6A,0x65,0x44,0x50, +0x1D,0x20,0xB2,0x68,0xA5,0xDB,0xA1,0x0D,0xC5,0x93,0x73,0x7A,0xFA,0xF1,0x6D,0x68, +0x9B,0x3C,0x76,0x45,0x65,0x95,0x5F,0xCC,0xE4,0x81,0x60,0xEC,0x3E,0x34,0x29,0x0F, +0x86,0x8C,0xEE,0xF0,0xE2,0x88,0x9E,0xFD,0x6B,0x56,0xDB,0x65,0x30,0x18,0xAB,0x62, +0xC1,0x4D,0x2E,0x94,0x9B,0x93,0x77,0xD6,0xB5,0xD8,0xF5,0x24,0x4F,0x79,0xC4,0xF1, +0x96,0x94,0x9A,0x43,0x24,0x9B,0xBC,0xFF,0xE7,0x92,0x85,0xDE,0xE7,0x54,0xB0,0x3D, +0x0C,0xAF,0x8F,0x9E,0x75,0x76,0x06,0x47,0xFE,0xA6,0x50,0x93,0x2C,0x80,0x7E,0x29, +0x1D,0x0D,0x85,0x6F,0xF7,0xB5,0x72,0x57,0x4C,0x7F,0x5E,0x3A,0x23,0x88,0xA1,0x33, +0x0E,0x53,0x48,0x8D,0xC7,0xFB,0xD9,0xA0,0x26,0x61,0xBF,0x9C,0x0D,0x66,0x24,0x2B, +0xDF,0x61,0xF2,0xF8,0x59,0x67,0x12,0xB4,0x4D,0x12,0x22,0x85,0xE9,0x81,0x16,0x55, +0xB4,0xBF,0x43,0xF6,0x60,0x2A,0xCA,0xF7,0xA3,0xC2,0x54,0xF7,0x9D,0x49,0x4C,0x45, +0x48,0x03,0xDC,0x60,0xC0,0xEB,0x49,0x8F,0xE2,0xD1,0x3A,0x43,0x2C,0x05,0x5D,0x40, +0xA9,0xA6,0x7D,0x15,0xF5,0xDB,0xC0,0x58,0xFD,0x5F,0x51,0x5B,0x87,0x8E,0xF0,0x31, +0xE3,0xC6,0x1D,0x50,0xA6,0xAF,0x4B,0x37,0x45,0x63,0xBD,0xF2,0x90,0x2C,0x9B,0xA8, +0xD9,0xF2,0x21,0xE3,0xFA,0x2B,0x51,0x29,0x05,0x1E,0x7C,0xBD,0x1B,0x9F,0xF2,0x95, +0x58,0xF4,0x7D,0x44,0xE1,0x14,0xC3,0xA5,0x85,0x24,0x09,0x52,0xAF,0x0E,0x8A,0x32, +0x51,0x1B,0x70,0x4E,0xD4,0x0E,0x74,0x8F,0x69,0x61,0x94,0xA6,0x54,0x96,0xE1,0x6B, +0xB9,0x21,0xCB,0xFD,0x92,0xFF,0xC6,0x54,0x21,0x19,0x53,0x1F,0x43,0xA5,0xEC,0xA4, +0x0C,0xDA,0x28,0x62,0xF7,0x05,0x61,0xA9,0xE6,0xE1,0x38,0xC2,0xB1,0xCB,0x23,0xD6, +0x14,0x48,0x05,0xA1,0x42,0xE3,0xD5,0x1B,0xA4,0xCE,0x72,0x0D,0x9A,0xAB,0x1C,0xA3, +0xDF,0xC3,0xC9,0x56,0x30,0x5B,0x4D,0xE3,0xCA,0xF0,0x03,0x8C,0x03,0x5B,0x6F,0x47, +0x59,0xF6,0x56,0xE0,0x75,0xB9,0x60,0xF6,0x18,0x44,0x81,0x50,0x0B,0x96,0x1F,0xE8, +0xD1,0xEC,0x7E,0x10,0xB8,0x0C,0xB6,0xFD,0x35,0xB1,0x1B,0x60,0x4A,0x3D,0xFC,0x01, +0x06,0x4C,0x11,0xF1,0xA1,0x71,0xBA,0x67,0x2A,0x44,0x1C,0x03,0x0F,0xDA,0x1A,0xA4, +0xD8,0x00,0x54,0x52,0x97,0x5E,0x6D,0xB2,0xEC,0xD0,0x69,0x3A,0x3A,0x90,0x0B,0x2C, +0xDA,0xD7,0x07,0x4B,0xF0,0xF6,0xEE,0x30,0xB2,0xBB,0x07,0x20,0xED,0x8A,0x62,0x0B, +0xF3,0xA1,0xF7,0x07,0x31,0x9D,0xDA,0xC0,0x0F,0x7F,0xB2,0x5F,0x7A,0xF0,0xB9,0xF7, +0x29,0x4B,0x0D,0x6B,0x94,0xDF,0x9B,0x81,0x50,0xD6,0xAB,0xFC,0x1C,0x30,0xBF,0x6D, +0x7D,0xC0,0x97,0x4D,0xC8,0x84,0xC4,0x05,0x4A,0x34,0x93,0x26,0x02,0x36,0xC3,0xDA, +0x1A,0xF3,0xD4,0xC7,0xDF,0x82,0x9A,0xD8,0x44,0xE2,0x2B,0xC9,0x1A,0xFA,0x1D,0xDC, +0x3A,0xA8,0x14,0x86,0xD7,0x93,0xE1,0x01,0x1C,0x39,0xC4,0x7F,0x17,0x07,0x68,0x42, +0x95,0x44,0x3A,0x64,0x66,0xD8,0xB6,0xF2,0x5F,0x76,0x80,0x7B,0x64,0x05,0xED,0x92, +0x3D,0xDD,0x49,0x8A,0xD9,0x8B,0x39,0x7B,0x30,0x8F,0x72,0x57,0x53,0x49,0x58,0xB0, +0x1F,0x9C,0xA9,0xD8,0x8C,0x9E,0xB4,0x92,0x97,0x7D,0x69,0x45,0x1F,0x46,0x98,0x8B, +0x18,0x94,0x2C,0x80,0x0E,0xC6,0x2F,0xDF,0x8B,0x21,0xA8,0xE3,0x32,0x19,0x56,0x3E, +0x9D,0x91,0x28,0xA1,0xBA,0x85,0xB0,0x4B,0xDE,0xE0,0x2A,0x37,0x97,0xC5,0xAB,0xE3, +0xC8,0x8E,0x1A,0x40,0xF2,0x2C,0x4D,0xAB,0xAD,0x21,0x2D,0xC0,0x6C,0x9C,0x4B,0xDD, +0x8D,0x70,0xF2,0x1E,0xA9,0x10,0x97,0x26,0x98,0xF0,0x42,0x23,0x31,0xD8,0x84,0xB1, +0x38,0xB8,0x01,0xFF,0x3F,0xD7,0x8D,0x9E,0xF7,0x50,0x88,0xB3,0xDD,0x49,0x58,0xFB, +0xCB,0xDA,0x7B,0x3E,0xCC,0xF7,0x51,0x99,0xA8,0xD0,0x79,0x9B,0x86,0xD0,0x3F,0xA0, +0xEB,0x38,0xD3,0x25,0x4B,0xC4,0xF0,0xB7,0xE4,0x3B,0xBB,0x09,0xE4,0xAD,0x4A,0xEF, +0xE2,0x3B,0x4E,0x16,0x42,0xBD,0x15,0x45,0x84,0xDA,0xD6,0x80,0xEE,0x58,0x87,0xD9, +0xE1,0xC1,0xDE,0x95,0xD3,0xBC,0x39,0x6B,0x1C,0x55,0x1A,0xDC,0x5C,0xB0,0xA9,0xB8, +0x33,0x20,0x55,0x2E,0x8B,0x74,0xE7,0x2D,0x52,0xA4,0xD7,0x7B,0xF9,0xAE,0x1E,0xEF, +0x23,0x9C,0x6B,0xA7,0xE3,0x0F,0x78,0x71,0x5B,0xBC,0x3D,0x31,0xDC,0xC9,0xBA,0x95, +0xF0,0x9E,0x53,0xCF,0xFB,0x09,0x37,0xD5,0x24,0xBA,0x98,0x04,0x47,0x51,0xE9,0x4E, +0x02,0x38,0xCA,0x43,0x05,0x6F,0xBE,0x95,0x4E,0xD5,0x7C,0x23,0x44,0xAF,0xFC,0xC9, +0x6F,0x68,0x83,0xC3,0x02,0xBD,0xFD,0x90,0xA6,0x0C,0xF2,0x65,0xDD,0x7A,0x69,0xBC, +0xD0,0xBF,0x84,0x1E,0xEB,0x62,0xF7,0x22,0x1B,0x9C,0x30,0x0E,0xC6,0xDF,0xAB,0xE4, +0x6F,0x2F,0x48,0x84,0xAB,0x7D,0x52,0x86,0x27,0x53,0x9D,0x4F,0x30,0x11,0x35,0x73, +0x9F,0xD4,0x1B,0xDA,0x89,0xD3,0x6A,0x31,0xD4,0xC2,0x57,0x62,0xA7,0x24,0xA6,0x9F, +0x46,0x54,0x82,0x0E,0x61,0xFD,0x15,0x3B,0x4D,0x75,0x98,0x73,0xDD,0xA9,0xBA,0xCE, +0x94,0x0D,0x2E,0xD6,0x4F,0x62,0x6A,0xC0,0xFD,0x81,0xAC,0x1F,0x88,0x09,0x4D,0x88, +0xEE,0x61,0x62,0xB7,0x2D,0x75,0x45,0x5D,0x20,0x59,0x69,0x0C,0x89,0x1E,0x1D,0x4F, +0xC8,0xD1,0x38,0xF9,0xD4,0xB4,0x6D,0x63,0x73,0xD4,0xCA,0x8A,0xE7,0x07,0xF7,0x7E, +0xB3,0xA1,0x71,0xF0,0x8E,0x68,0x75,0xF2,0x68,0x0B,0x79,0x22,0xF8,0x57,0xB3,0xFF, +0x6C,0x28,0x79,0x0D,0x06,0x1E,0x16,0x21,0x1B,0x64,0xE4,0x5E,0x39,0x8E,0xBB,0x9D, +0x60,0x57,0x1B,0x8F,0x2C,0xCF,0x23,0xA3,0xEC,0xAD,0xA8,0xA0,0x3D,0xD5,0x22,0xB6, +0xCD,0xA0,0xE5,0x77,0x30,0x43,0xEA,0xAA,0x99,0xF4,0xEC,0x70,0x93,0x74,0x9B,0x9B, +0xB6,0x69,0xF0,0x04,0x5C,0xB8,0x6F,0x79,0xCE,0x6E,0x16,0x4F,0x84,0x92,0xA3,0x76, +0x26,0xF9,0x5F,0xBB,0x07,0x36,0xBE,0x94,0xCF,0x78,0x11,0x71,0xBB,0x0D,0x25,0x03, +0x15,0x50,0x6B,0xEB,0xC7,0x2E,0xA0,0x28,0xA5,0xFB,0x68,0xB5,0x94,0x5D,0x53,0x32, +0x2D,0x96,0x31,0x6B,0x7F,0xC8,0x12,0x0C,0x82,0x49,0xA3,0xAD,0x52,0xA2,0x0C,0xC5, +0x1D,0x4D,0x55,0x83,0x0B,0xCF,0x88,0xF2,0x84,0x55,0x30,0x9A,0x9B,0xB9,0xFA,0x36, +0x17,0x80,0x1A,0x1D,0x8C,0xF7,0x37,0xA2,0x9B,0xB8,0x3B,0x13,0x86,0x05,0xDC,0x3D, +0x36,0x61,0x28,0xFA,0x00,0xB6,0x8A,0x12,0xD5,0xAE,0xA5,0xDB,0x2A,0xD7,0x69,0x33, +0x5E,0x4D,0x2B,0xA3,0x0D,0x50,0x44,0x4E,0x72,0x77,0xB0,0x5B,0x98,0x3C,0x03,0x30, +0x68,0x84,0x82,0x6B,0xDF,0xD6,0x21,0x0B,0x1F,0xD0,0x9F,0x58,0x84,0xFE,0x36,0x38, +0xF7,0x65,0x8F,0x7A,0x4F,0x50,0x6F,0xA5,0xC1,0xA7,0xA7,0xA7,0xB6,0x9E,0x5B,0x58, +0xFD,0x93,0xE7,0x17,0x2D,0x7D,0x86,0x6F,0x0D,0x55,0x81,0x26,0xF9,0x46,0x5F,0x99, +0xC4,0x1D,0x61,0x55,0x01,0xA7,0x1D,0x57,0xB6,0x3C,0x60,0xDE,0xEE,0xA1,0x04,0x81, +0xB2,0x71,0xCF,0x00,0x7C,0x4A,0x9F,0xB6,0x70,0x7E,0x36,0xCB,0xB8,0xF4,0x46,0x39, +0xB3,0x94,0x28,0xB4,0xA3,0xED,0xE2,0x9E,0xF6,0x77,0xDD,0x2B,0x3D,0x50,0xBA,0x11, +0xA7,0x3C,0xCA,0xAA,0x59,0x40,0x6D,0x18,0xAF,0x77,0xCE,0x7E,0xEE,0x3E,0x33,0xD9, +0xE8,0x54,0xB8,0x3C,0x22,0xCC,0xD9,0xCD,0x7D,0x5B,0x01,0x82,0x65,0x8E,0x4C,0x36, +0xFF,0x98,0x10,0x89,0xBE,0x7A,0x7E,0x9E,0x85,0xE0,0x37,0x3A,0x31,0x10,0xC1,0x12, +0xBC,0xD4,0xBD,0x92,0xD9,0xFD,0x9B,0x6D,0x77,0xDB,0x34,0x23,0x18,0xFD,0xD4,0x7F, +0xDA,0xFF,0x2F,0xC5,0x13,0x3D,0xD5,0x5F,0x74,0xCD,0xC7,0x8C,0x6D,0x51,0xFF,0xC0, +0x8A,0xA9,0xC2,0x1E,0x36,0x9C,0x3A,0xD1,0x67,0x55,0xA1,0xD3,0xAA,0x88,0x53,0x29, +0x78,0x11,0xF8,0xC9,0x98,0x1F,0xC7,0x14,0x67,0x3B,0xE5,0xA0,0xF9,0x46,0x72,0xBD, +0x6E,0xFE,0x53,0xD1,0xED,0x1F,0xB0,0x17,0xB2,0x56,0xD0,0xC9,0xE1,0x37,0xFA,0xB2, +0x61,0xC5,0x6E,0x4E,0x68,0x05,0xB2,0xC6,0x2C,0x7B,0x57,0x33,0x19,0x0D,0x44,0x82, +0x73,0x16,0xFC,0x08,0x3B,0x8B,0xD8,0x01,0xC8,0x98,0x45,0x1C,0x68,0x46,0x55,0xBE, +0xC0,0x72,0x9F,0xBC,0x2F,0x69,0x62,0xF5,0x63,0xEB,0xBF,0xE5,0x70,0xC7,0xA6,0x3E, +0xD1,0x7A,0x2E,0x8E,0x77,0x9A,0x6C,0x79,0x24,0xB2,0x29,0xDF,0x32,0x56,0xF5,0x1A, +0x56,0xCA,0x92,0x61,0x7F,0x3F,0x55,0xB7,0xC1,0x1B,0xF6,0xE9,0x6B,0x2C,0x3E,0x6F, +0xC0,0xED,0x3E,0x56,0x0F,0x92,0x7E,0x7A,0x2D,0x99,0x86,0xE9,0x82,0x71,0x4D,0xEA, +0xEC,0x60,0x9B,0x93,0xA1,0xE9,0x83,0xC4,0xBB,0x61,0xFE,0xBC,0xA3,0x86,0x2A,0x49, +0x2D,0x35,0x48,0xD8,0x31,0x5A,0xAD,0x0F,0xA2,0x8C,0xBC,0xAF,0xA9,0x82,0x8E,0x93, +0x08,0x4D,0x48,0x03,0x83,0x76,0x40,0x59,0xB8,0xE2,0x3B,0x2D,0x71,0x1D,0xDA,0xE0, +0x7A,0x11,0x77,0x13,0x7B,0x62,0x92,0x69,0xBD,0x6E,0x50,0xA0,0x7D,0x0A,0x2C,0x1D, +0xC3,0x0F,0x8F,0xE6,0x08,0x9A,0x8D,0xE4,0x2B,0x65,0xB1,0x8F,0x24,0xAB,0x07,0x31, +0x3F,0x3E,0x37,0xD2,0xD8,0x0C,0x79,0x54,0xB5,0xDF,0xF3,0xD9,0x9E,0xBD,0xC7,0xEC, +0xE5,0xBF,0xC3,0x52,0x63,0x76,0x45,0xDD,0x86,0xC7,0x10,0x67,0x83,0x75,0x16,0x5B, +0x94,0x4D,0x62,0xCE,0xF6,0x08,0x53,0x90,0xFE,0xCD,0x04,0x81,0xF9,0x5E,0xA5,0x52, +0x8A,0x7E,0xCE,0xFE,0xFF,0x31,0xB0,0xD8,0x20,0x7D,0x1C,0x33,0xE1,0xAB,0x09,0xFF, +0xEB,0x66,0x41,0x57,0xB2,0xB8,0x0B,0x3C,0xCC,0x93,0x94,0xE1,0x9C,0x3D,0xBA,0xBD, +0xB0,0xA4,0x3F,0x0A,0x3D,0xA9,0x45,0x2B,0xE9,0x1A,0xEB,0xB8,0x27,0xEB,0x97,0xEE, +0xC9,0x9A,0x6B,0x67,0x27,0xD0,0xDA,0x58,0x64,0xA4,0x0A,0xA1,0xF1,0x52,0xD1,0x0E, +0x90,0x24,0x9E,0xEC,0xED,0xFD,0xE7,0x28,0x81,0xDA,0x2A,0x92,0x4E,0x1C,0xF2,0x59, +0x31,0x8E,0x95,0x61,0xC9,0x9E,0xF6,0xDB,0x21,0x91,0xC6,0x6E,0x5D,0x30,0xDC,0x5E, +0xC9,0x00,0x2F,0xDE,0x02,0xC7,0x58,0x16,0x4C,0x2C,0xEC,0x83,0x96,0x33,0x7B,0x4B, +0x60,0xDC,0x2A,0xF5,0xE9,0x6E,0x94,0x4B,0xFD,0x80,0x45,0xAD,0x1E,0x1F,0x80,0xCE, +0xB5,0xEB,0xA8,0x27,0x55,0x26,0x55,0x94,0xA3,0x3E,0x57,0x71,0x6F,0x53,0xA2,0x04, +0x44,0xA0,0x74,0x3C,0x04,0xC4,0x5F,0x7C,0x47,0xCF,0x62,0x48,0x3B,0x62,0x49,0x2E, +0x21,0x7F,0x72,0xAF,0xA8,0x91,0xFE,0x2F,0xD3,0xEA,0x86,0xC2,0xA7,0x54,0x3E,0x7B, +0x70,0xA6,0x86,0x12,0xAE,0xDD,0x99,0xB7,0xC9,0x5B,0xB6,0x17,0x45,0xA8,0x64,0x3B, +0x06,0x32,0xB5,0x6C,0x67,0x35,0x76,0x3C,0xF5,0x4C,0xB0,0xA6,0xF7,0x90,0x50,0x0D, +0x10,0xB1,0xC3,0xCD,0xF2,0x3B,0x0C,0x78,0x12,0x63,0xAF,0x0B,0x5A,0x03,0x2E,0x47, +0x6F,0x21,0xCF,0xC4,0xE9,0x20,0xE0,0x34,0xE4,0xFE,0xEF,0x25,0x15,0xB1,0x51,0xB3, +0x70,0x86,0x7B,0x5A,0x46,0xF9,0xD0,0x50,0x4B,0xA4,0x4A,0x88,0xD7,0xEF,0xDE,0x5F, +0x08,0x31,0x74,0x33,0x11,0x42,0xE2,0xE4,0xA5,0xE0,0xD6,0xA4,0x54,0x77,0xA1,0xAD, +0x89,0x54,0xB3,0xE4,0x8C,0xB6,0xB4,0x80,0x23,0x4A,0x12,0x89,0xA2,0x8B,0x25,0x79, +0x1E,0x49,0x2A,0x13,0xD7,0x76,0x74,0x70,0x62,0xF1,0x5B,0x0B,0x2A,0xCC,0x49,0x6B, +0x9D,0x36,0x4B,0x13,0x0C,0xB8,0x1B,0xAB,0x5F,0xBD,0xA1,0xC9,0xE5,0x7E,0x11,0x41, +0x18,0xAA,0x28,0xDA,0x29,0x38,0x75,0xDE,0xEF,0xB1,0x2F,0x2A,0x10,0x10,0x3A,0x25, +0x1A,0xA5,0x33,0x98,0x56,0xBD,0xD8,0x0A,0x07,0xAA,0x8B,0xFD,0xE5,0x56,0x62,0x70, +0x5B,0x09,0x3B,0x92,0xBC,0xBA,0x74,0x9E,0x88,0xE1,0x6E,0x6C,0xDD,0xA2,0x41,0xD3, +0x0F,0xC0,0xA7,0x74,0x33,0x0F,0xC2,0x6C,0x30,0x7A,0x6A,0xA4,0xCD,0x17,0x2B,0x31, +0x9B,0x9C,0x98,0x80,0xE6,0xD9,0xBF,0x5C,0x65,0x03,0xEA,0x3F,0x02,0xA2,0xB6,0xE2, +0x17,0x80,0x48,0x27,0x02,0xDF,0x1F,0x62,0xFD,0x7F,0xB9,0x4B,0x7A,0xC6,0xBE,0xD3, +0x6B,0xC3,0xC8,0xC2,0x66,0x0C,0x79,0x71,0x68,0x3A,0xD9,0x08,0xEA,0x54,0x72,0xEB, +0xD4,0x05,0xA2,0x90,0xB3,0xF3,0xAE,0xE2,0xFC,0x06,0xB9,0xDD,0x4E,0x80,0x97,0xEC, +0x6D,0x3F,0x0E,0xC6,0x17,0x02,0xE0,0x3B,0x3C,0x8A,0x9E,0x76,0x21,0x3B,0x3A,0x0F, +0x89,0x8A,0x6A,0x23,0x56,0xC2,0xCA,0x42,0x07,0x62,0x16,0xDA,0x82,0x7C,0x22,0xD7, +0x39,0xB3,0xD8,0x5D,0x8D,0xAE,0x18,0x51,0x71,0x1B,0x6A,0xF6,0xEE,0x91,0xEE,0x38, +0xE8,0xBC,0x75,0xD1,0x7D,0x2F,0xD8,0x15,0xDE,0x6B,0x2D,0xEA,0x27,0x6A,0xE2,0x38, +0x8B,0xB7,0xFB,0x9A,0xF3,0x88,0x0F,0xD3,0xC7,0x6E,0xE3,0x41,0x41,0x2D,0x0E,0xF5, +0xF0,0x97,0xBF,0x7E,0xE4,0x7C,0xB1,0x42,0x40,0xFA,0xBE,0x35,0x73,0x55,0x1C,0xDD, +0x09,0x62,0x9D,0xBA,0x5E,0x08,0xAC,0x49,0xEF,0x29,0xE3,0x54,0xE0,0x2C,0x92,0x89, +0x34,0x02,0xBA,0x5D,0x43,0x34,0x2B,0xA7,0x3C,0x3F,0xFB,0x67,0x0D,0xED,0x1A,0xB1, +0x8A,0x2C,0xEB,0x9E,0xEB,0x5E,0x18,0x50,0x49,0xEF,0x41,0x64,0xB0,0x65,0x28,0x63, +0x2E,0x45,0x7E,0xF6,0x9B,0x20,0x01,0x09,0x6C,0x73,0x43,0xF6,0xDD,0x53,0xA4,0x8E, +0x5A,0x78,0x2A,0xDA,0xA6,0x1A,0xF0,0xCE,0x5B,0x7D,0xBB,0xC0,0x66,0x19,0x47,0x04, +0xD0,0xD5,0x42,0xEC,0xED,0x68,0x8B,0xED,0x21,0x5A,0x37,0x8C,0x30,0x26,0xB1,0x20, +0x29,0x42,0x97,0xED,0xDA,0x71,0xE0,0xC2,0x1C,0x77,0xF8,0x39,0xF6,0x9F,0x34,0x4E, +0x83,0x33,0x7F,0x2B,0x58,0x6A,0xE9,0x61,0x95,0x2A,0x35,0x62,0xAD,0x88,0x7B,0x7B, +0xA9,0xEF,0xE6,0x4B,0x96,0xBF,0x0A,0x3A,0x3D,0xE6,0xFA,0xC5,0x84,0xBA,0xD7,0x9B, +0x1D,0x0B,0x35,0x55,0x69,0x3D,0xB3,0x19,0xD8,0xC2,0x1A,0x6A,0x4D,0x7E,0x52,0xFC, +0x18,0x73,0x4F,0x01,0xED,0x2C,0x65,0x68,0xBF,0x2C,0xA3,0xA5,0x8E,0xB8,0x14,0x14, +0x69,0xD6,0x95,0x94,0xF7,0x9B,0x7A,0x1F,0x2B,0x58,0xC3,0x79,0xC8,0xE8,0x33,0xCA, +0x8B,0x8E,0x12,0x92,0xF3,0x66,0xD9,0x2D,0x3E,0xFC,0x0F,0x56,0xDF,0xF2,0x60,0x73, +0x07,0x98,0x0C,0x85,0xC3,0x54,0x65,0xB9,0xF0,0x70,0x84,0xEB,0xD8,0x4A,0x49,0x8F, +0x65,0xBE,0x67,0x7F,0xE6,0x47,0xD6,0x0D,0x91,0x35,0xD7,0x75,0x49,0x01,0x28,0x4A, +0x97,0xF6,0x87,0x1A,0x1F,0x32,0x90,0xAB,0x1D,0xD1,0x7D,0x8D,0xD5,0xC0,0x5B,0x55, +0x3A,0x4F,0x5A,0xA4,0xD7,0x21,0x9A,0x80,0x4F,0x44,0x88,0x52,0x7B,0xFE,0x69,0xE6, +0x5D,0xAA,0x1D,0xCE,0xA9,0x62,0xBC,0xD2,0xA5,0x7F,0xBD,0x55,0x7E,0x1C,0x6C,0x2C, +0xC3,0x6E,0xAC,0xBB,0xF3,0x77,0x39,0x4A,0xE0,0x7B,0x67,0x9B,0x9A,0x33,0xD7,0xD5, +0xDD,0xFB,0x3B,0x42,0x8E,0xEF,0xCB,0x05,0x49,0xF5,0xF9,0x89,0xB5,0x56,0xB5,0x93, +0x77,0xE0,0x63,0x2A,0x4F,0x89,0x07,0x96,0x91,0x7C,0x88,0x54,0x2E,0x85,0x10,0x8E, +0xB1,0xB5,0xB4,0x57,0xC9,0xCB,0x27,0xEA,0x78,0xA1,0xA6,0xDA,0x75,0x99,0x0E,0x4F, +0x92,0xEB,0x79,0xDE,0x47,0x8F,0xDD,0x09,0x78,0xA6,0xE2,0xBD,0x3A,0x80,0xC3,0xD8, +0xB0,0xB9,0x8D,0xCB,0xD3,0x73,0xD7,0x73,0x86,0xCE,0x0B,0xD0,0x08,0xBE,0x8A,0x35, +0x82,0xB5,0xB1,0xC5,0xE0,0x2C,0x82,0xDB,0xB4,0x53,0xA7,0x0A,0xC6,0x31,0x25,0x0F, +0x07,0x83,0x20,0xB0,0xDF,0x98,0x51,0xF5,0x92,0x0A,0x51,0x3B,0x2B,0x18,0x2B,0x88, +0x2D,0x68,0x74,0xBE,0x57,0xEA,0x7F,0xDC,0x11,0x84,0x96,0x00,0x56,0x0D,0x94,0xCE, +0x9F,0x14,0x8E,0x40,0xD9,0x25,0x69,0x81,0x5D,0x78,0x7C,0x26,0xCC,0x19,0xBA,0x21, +0xD2,0x45,0xAA,0x5B,0xDC,0x52,0x86,0xC2,0xAE,0xA7,0x81,0x1A,0xED,0xEB,0xAE,0x9A, +0x67,0x3E,0xEC,0x41,0x1C,0x1C,0xF6,0xAF,0x20,0xD5,0xEF,0xB5,0xF8,0x41,0x41,0xF7, +0x51,0xDA,0xF1,0x92,0x30,0xAA,0x6B,0x2C,0xA0,0xAF,0x68,0x53,0x8A,0x21,0x4B,0x67, +0xB0,0x59,0x5E,0x1C,0x13,0xAA,0x65,0x49,0xDD,0xD2,0xDC,0xA4,0x69,0x0B,0xA4,0x60, +0x08,0x54,0xA5,0x9F,0xFB,0xA9,0x39,0x76,0xB0,0x2F,0x8E,0xEE,0x6F,0x0B,0x80,0xD2, +0x2F,0x57,0xDC,0xB6,0xB2,0x58,0x2F,0x33,0x11,0xB2,0x99,0x18,0x70,0x11,0x83,0x08, +0xBE,0x5B,0x14,0xC1,0x5F,0xE6,0xF2,0xE8,0x1F,0x44,0xDB,0x2F,0x63,0x44,0x4E,0xC8, +0xC9,0xD3,0xDD,0x36,0xFE,0xC8,0x44,0x9A,0x8F,0x75,0xAB,0xEF,0xED,0x97,0xA1,0xEC, +0xF9,0xCA,0x53,0x51,0x0C,0xEF,0xD7,0x90,0x42,0x5E,0x72,0xCC,0x8E,0x3F,0xD6,0xA4, +0x3B,0x50,0x97,0xD1,0xEF,0x5F,0xD2,0x38,0x69,0xA6,0x5C,0x9C,0xC2,0xD5,0x29,0xD3, +0x3A,0xD6,0xEA,0xFA,0x41,0x9D,0xC4,0x06,0x97,0xD7,0x5B,0x13,0xFE,0x53,0xB9,0xFB, +0xD2,0xD0,0x71,0xD5,0x2A,0x16,0x04,0x6F,0x74,0xEA,0x40,0xB0,0x87,0xB7,0x9E,0xD2, +0x61,0x9C,0x54,0x85,0xEC,0xCC,0x93,0x90,0xFE,0x7C,0xAE,0xB2,0x78,0x5E,0x85,0x4C, +0x92,0x5C,0xB8,0xA0,0x8C,0x2C,0x2C,0xAF,0xF2,0x92,0x55,0xA3,0x96,0x6B,0x53,0x61, +0xAF,0x4D,0x53,0x5F,0x91,0x72,0x74,0x11,0xC9,0xDB,0x63,0x54,0x6D,0x6A,0xAE,0xAC, +0xBC,0x72,0xDC,0x82,0x88,0x8B,0xDA,0xA6,0x9F,0x2B,0xFA,0xFF,0x0D,0x98,0x1A,0xCB, +0x53,0x45,0xB7,0x56,0xB7,0x58,0x6A,0x2B,0xA3,0xBB,0xF8,0x9C,0x39,0x32,0xE6,0x85, +0x2D,0x08,0xE8,0x75,0x39,0xDB,0x10,0x42,0x4A,0xF8,0xC3,0xA7,0x94,0xB8,0xDD,0x13, +0x91,0xD3,0x3B,0xAD,0x8A,0xC7,0xB7,0x72,0x32,0xF8,0xBB,0xF7,0xE9,0x10,0x06,0x1D, +0x91,0xA0,0x88,0xF2,0x18,0x3E,0x0E,0xA6,0x97,0xD3,0x12,0x45,0xCC,0xBB,0xE7,0x7D, +0x02,0xD3,0x07,0x28,0x85,0xA6,0xD0,0x46,0x62,0x04,0x52,0xC0,0x5F,0xA8,0x33,0xBD, +0x05,0x9F,0x79,0x2B,0x4C,0xD0,0x72,0x4F,0x4C,0x18,0xA8,0x61,0x51,0x86,0x8C,0x64, +0x40,0x74,0x82,0xA7,0x34,0xFF,0x47,0x0F,0x6E,0x2A,0xD3,0x5F,0xAA,0xA6,0xFD,0xA1, +0xCB,0xE4,0xDD,0xBF,0x6D,0x51,0xDB,0x4F,0x9D,0x97,0x51,0xC1,0xDE,0x56,0x40,0xEF, +0x7A,0x7A,0xA4,0xAA,0xFC,0x35,0x7C,0x4C,0x25,0x09,0x2F,0x06,0xCE,0x5B,0x54,0xB3, +0xD3,0x2C,0x26,0x56,0xD2,0x37,0xB3,0x52,0x3A,0xB1,0x1D,0x6E,0x5C,0x4D,0x22,0x7F, +0x68,0xFB,0x9E,0xBD,0x1A,0x3F,0x1C,0x47,0xEA,0xB9,0x0B,0x40,0x79,0x80,0x1A,0x48, +0xA5,0xA9,0xC7,0x71,0xD2,0xF0,0x51,0x76,0x7A,0xB9,0x75,0x11,0x21,0xE1,0xFD,0x4C, +0x97,0x74,0x42,0x0B,0xBF,0xE9,0xC7,0x1B,0x96,0x53,0x9C,0xB2,0x79,0xEA,0xB4,0xF5, +0x87,0xB1,0x3E,0x75,0xB2,0x48,0x0D,0x59,0xCD,0x63,0xBF,0x19,0x21,0x90,0x1F,0x2F, +0xE4,0x5E,0x64,0x4F,0x10,0xA8,0x3E,0x75,0x05,0x9D,0x1D,0xDC,0x61,0x03,0x97,0xB7, +0x49,0x9B,0x16,0xFC,0x27,0xC9,0x1D,0x97,0x79,0x1A,0x76,0xC2,0x18,0xA5,0xB5,0xD7, +0x28,0xE8,0xDC,0x84,0x44,0xFE,0x99,0x2B,0x43,0x02,0xB7,0x0B,0x68,0x17,0x20,0x02, +0x82,0xE6,0xC6,0x6A,0x65,0x4F,0x9E,0xA0,0x03,0xD4,0xC1,0x00,0x3D,0xC7,0x77,0xE5, +0xAB,0xA9,0x9A,0x48,0xB9,0x82,0xF7,0x46,0xF2,0xF5,0x1A,0xFD,0x54,0x60,0x79,0xD9, +0x5C,0x49,0x2D,0x02,0x8D,0x01,0x81,0xD8,0x37,0xDA,0x8A,0xB7,0xCD,0xE0,0x8D,0xB5, +0xCC,0x60,0x39,0x06,0x84,0x9B,0x0D,0xEF,0xB3,0x1A,0x76,0x58,0x8D,0x88,0x65,0x20, +0xD7,0x5B,0x18,0x16,0x77,0x35,0xC6,0x54,0xDC,0x08,0xA9,0xE8,0x4F,0xCC,0x1E,0x64, +0x7A,0xBD,0xD6,0xEC,0x69,0x3A,0xE9,0x27,0xDD,0xF8,0x5E,0x1E,0xD2,0x38,0xBE,0x10, +0xB5,0x29,0xE7,0x70,0xA1,0x53,0xED,0x3C,0xBE,0x09,0x72,0xE9,0xEA,0xFD,0xBD,0xB3, +0x53,0x62,0xBC,0x15,0x3E,0xA7,0x16,0x60,0xA3,0x08,0x37,0x40,0x59,0x60,0x5B,0xB7, +0xBD,0x3C,0x32,0xA8,0x49,0xA8,0xAA,0xAA,0xC4,0x6E,0x4D,0xCE,0xDD,0xC7,0x16,0xA6, +0xB9,0x05,0x4C,0xD7,0x0D,0x68,0xEC,0x1E,0xA6,0x28,0x85,0xBE,0x5D,0xF5,0x38,0x77, +0xBE,0x12,0xA7,0x54,0x4D,0x92,0x34,0x98,0x69,0xE8,0x98,0x91,0xAE,0x6F,0xC2,0x58, +0xF9,0xBB,0x56,0x87,0xC7,0xA1,0x19,0xA5,0xA6,0xD7,0xDD,0x3E,0x1D,0x44,0x31,0xC7, +0xB8,0x5A,0x10,0xDE,0xDD,0xBF,0x74,0xFA,0x0F,0xC0,0xC1,0xD7,0xD7,0x18,0xDB,0x5B, +0x44,0x52,0xA1,0x18,0x22,0x7C,0x5D,0x4E,0x99,0x42,0x5F,0xDF,0xDD,0xC4,0x32,0x43, +0x2E,0x0E,0x38,0x63,0xA4,0x5E,0xB2,0x3C,0x70,0x79,0xB6,0xB0,0x0C,0x5D,0x39,0xD3, +0xBF,0x22,0x95,0x2D,0xC3,0x56,0x35,0x15,0x0F,0x96,0xF2,0x56,0xF2,0x9D,0xC5,0x19, +0xE2,0x01,0x91,0x76,0x05,0xC9,0x79,0xC2,0x2C,0xC0,0x62,0x3D,0x0F,0x54,0x3B,0x3A, +0xEC,0x29,0xA0,0x17,0xD1,0x75,0xAD,0xAF,0xE6,0xD3,0xF2,0x50,0xEF,0x48,0x93,0x1A, +0xD6,0xA0,0xC4,0x1D,0x9A,0xE4,0x29,0xF5,0x10,0x8E,0x7C,0x8C,0xD9,0xB5,0xDE,0x65, +0xF9,0x76,0xA8,0x10,0x83,0x8A,0x90,0xE7,0x80,0x02,0xCA,0x28,0xA1,0xDA,0xF3,0x95, +0x81,0x0E,0xC9,0xAC,0x53,0xEE,0x03,0x12,0x60,0xF8,0x6C,0x14,0x82,0x79,0x3E,0xD9, +0x72,0xE6,0x2A,0xEF,0x54,0x5C,0x99,0x71,0xC7,0xBB,0x9D,0x40,0xB5,0xF0,0xEA,0x4D, +0x4B,0x26,0xF1,0xE4,0xD9,0x61,0x1C,0xE1,0x55,0x57,0xB7,0xBE,0xBF,0x06,0x42,0x5F, +0x73,0x4B,0x80,0xC4,0x71,0x3F,0x15,0x1B,0xB2,0xAE,0xFC,0xF4,0xF0,0xB6,0x06,0xD6, +0x36,0x43,0xEF,0x86,0xDC,0xCC,0xDC,0xCB,0x8D,0xF6,0xEF,0xF6,0x8B,0x53,0xB9,0x80, +0x57,0xED,0xFC,0x29,0x33,0xD2,0xF2,0x6F,0x66,0x5F,0xBB,0x8C,0x17,0x89,0x51,0x8A, +0xE5,0x44,0x87,0x66,0x89,0x54,0xD7,0xF2,0xDD,0x7C,0xC4,0x56,0x68,0x47,0x02,0x1D, +0x8C,0xC8,0x9A,0x8B,0x71,0x93,0x1A,0x6E,0x18,0xA2,0x6D,0xEA,0xE0,0x97,0x7C,0xC3, +0xFE,0xF1,0xF7,0x15,0xCD,0x3E,0xDB,0x41,0x98,0x26,0x33,0x66,0x09,0x72,0xC5,0x8A, +0xED,0x84,0x74,0xCA,0x73,0xC5,0x4C,0xFD,0xB9,0x1D,0x5A,0x60,0x72,0x38,0x27,0x79, +0x2E,0xD2,0xC7,0xC1,0x8A,0xCF,0x67,0x51,0xF1,0xC9,0xA6,0x94,0x43,0x10,0xE1,0x39, +0x64,0x37,0xC3,0x48,0xAA,0xD4,0x36,0x54,0x5D,0x3D,0x51,0xBE,0x66,0x7B,0x60,0xD1, +0xA8,0xF2,0xB3,0x64,0xD0,0xFE,0x09,0xC0,0xD6,0xF3,0xDB,0x03,0xD5,0x1F,0xA7,0x8D, +0xE0,0x4C,0xAD,0x9D,0x12,0x8F,0x19,0x57,0x3D,0x3A,0x4B,0xCB,0xB7,0x01,0xFD,0x9A, +0x62,0xA6,0xD0,0x77,0xDE,0x35,0x68,0x79,0x06,0x07,0xB1,0xA8,0xC9,0xA2,0x2E,0x25, +0x6D,0x52,0xD3,0x26,0xA7,0xFA,0xDF,0x87,0x57,0x32,0xA5,0x11,0x97,0x77,0x76,0xA9, +0x32,0xA9,0x96,0x28,0x0E,0x27,0xBA,0x40,0x21,0xC3,0x7D,0xEA,0xEB,0x55,0x77,0x9A, +0x26,0xB0,0xD9,0xD0,0x9D,0x88,0xFE,0xCC,0x7A,0xB3,0x10,0x25,0xC5,0x09,0xD7,0x80, +0x4F,0x33,0xA0,0x0D,0x6B,0x8A,0xFC,0xEF,0x35,0xC1,0x2C,0x65,0xB1,0x88,0x4B,0x79, +0x4F,0x3B,0x82,0xC9,0x7A,0xD2,0x55,0x2C,0xE3,0x12,0x4A,0xA6,0xF9,0x96,0xD6,0xA0, +0x50,0xC9,0xDF,0x95,0x4A,0x1D,0x3A,0x9A,0xA4,0xC0,0xC1,0xDE,0x79,0x56,0xF1,0xA6, +0x2A,0xD9,0x39,0xB4,0x26,0x9C,0x93,0xF5,0xCC,0xDA,0x0D,0x4A,0xC4,0x64,0xD8,0xFB, +0x9F,0xF8,0x0E,0x21,0x5D,0x48,0x6D,0xBE,0x91,0x8D,0xE4,0xF9,0xB8,0x89,0x54,0x78, +0xBF,0xE3,0x2D,0xDF,0x3D,0xC1,0xDC,0xFB,0xEE,0xE3,0xD4,0xC1,0x27,0x84,0xD4,0xDA, +0x00,0x91,0x27,0xA8,0xB5,0x56,0x53,0xD8,0x69,0x77,0x15,0x17,0xF1,0x62,0x76,0x85, +0x76,0x9D,0x55,0x26,0xC0,0x24,0x0D,0x82,0xEF,0x4D,0x5F,0xD1,0x3C,0xA6,0x05,0x9A, +0x07,0x4E,0xFD,0x17,0xA4,0x37,0xA8,0x44,0x86,0x5C,0xD1,0xE1,0xDF,0x4E,0x5B,0x4E, +0x17,0xD7,0x89,0x3A,0x66,0xD5,0xE9,0x58,0xC5,0xD7,0x6B,0x57,0xF5,0xF4,0x25,0xAC, +0x39,0x47,0x2B,0x4F,0x29,0x0B,0xBB,0x09,0x65,0x3E,0x72,0xBE,0xB4,0x46,0x1A,0x8E, +0x59,0x5B,0xA6,0x9D,0x6F,0x7A,0x07,0x5C,0x67,0x19,0x82,0xC9,0xA8,0x36,0x98,0x5D, +0x98,0x2D,0x5D,0xAA,0x9A,0x29,0x43,0x39,0x34,0x04,0x82,0x39,0x1C,0x69,0x3B,0xA6, +0x92,0x5D,0x6E,0x20,0xEE,0x89,0x5C,0x21,0x70,0x66,0x93,0xDF,0xCC,0x56,0xC1,0x08, +0x26,0x79,0xF3,0xEF,0xB6,0xAF,0x14,0x5F,0x76,0x3A,0x4D,0x9A,0xB3,0x55,0x39,0x08, +0xE0,0x77,0xAC,0xE8,0x0D,0x9C,0xA7,0x55,0x80,0x27,0x26,0xEF,0x5A,0x99,0xB1,0x87, +0xF3,0xDB,0xCE,0x1E,0x9C,0x79,0x12,0x9D,0xC0,0x7A,0x7D,0x13,0xB5,0xBF,0x0A,0x9C, +0xAD,0xA6,0x61,0x47,0x24,0x08,0x76,0xBC,0xC3,0x69,0x10,0x91,0xDB,0xB0,0xA2,0x66, +0x43,0xD4,0x63,0xAE,0x94,0x25,0x6A,0xD6,0xD2,0x6B,0x6C,0x24,0x17,0xA3,0xF7,0x6B, +0x36,0xE0,0x0D,0x04,0x06,0xC9,0x2C,0x60,0xDF,0xE4,0xF5,0xBE,0xD7,0xB6,0x04,0x7C, +0x7D,0x95,0xD8,0x91,0x67,0x69,0x90,0x91,0xF7,0x7D,0x0C,0xB9,0x60,0x98,0xE6,0x0C, +0xDF,0x1A,0xBD,0x23,0xB3,0x24,0x59,0xA7,0xD9,0xAE,0x5F,0x19,0x6F,0x39,0x7F,0x60, +0x89,0xFF,0x1A,0x56,0x0B,0x99,0x7C,0x77,0xD1,0x7C,0x91,0x92,0xDC,0x42,0xB7,0x0F, +0x3E,0x45,0x45,0x42,0x67,0x6C,0xE2,0x92,0x9D,0x48,0x3A,0xF4,0x6E,0xE9,0x6D,0x6D, +0x8E,0xB9,0x13,0x7A,0x68,0xF5,0xB8,0x7E,0x9A,0xAB,0x11,0x79,0x3E,0xD9,0xEE,0xEE, +0x93,0xB3,0x56,0xB7,0x34,0xA7,0xE1,0x92,0x03,0x39,0x4A,0x11,0x8F,0x86,0x91,0x48, +0xF3,0xE4,0xC1,0xEF,0x32,0xE2,0x98,0x8F,0x40,0x12,0xF6,0x79,0xDB,0x94,0xC7,0x43, +0xDD,0x49,0x4A,0x80,0xCF,0x1C,0xC2,0x65,0x74,0x96,0xFE,0x9E,0x12,0x5C,0x96,0xB2, +0xE1,0x52,0x2D,0xEC,0xEA,0x5A,0x1D,0x9E,0x85,0x73,0xDF,0x51,0x0A,0x61,0xCE,0x0D, +0xB5,0x73,0xDA,0x7F,0x03,0x7E,0x01,0xD1,0x12,0xFE,0x9E,0xA4,0x03,0xA9,0x7E,0x57, +0x85,0x00,0x89,0x67,0xB9,0xA6,0x4F,0xAA,0xF4,0x4B,0xEF,0xC6,0xCC,0xF4,0xDE,0x40, +0x50,0xFF,0x46,0xBA,0x5D,0x5C,0x85,0x9A,0xC4,0xC3,0xE7,0xF9,0x5D,0x20,0x2C,0x94, +0x76,0xCC,0x5D,0xFE,0xD6,0xA6,0xF9,0x87,0x29,0x5C,0xC2,0xD3,0xEE,0x9D,0xA1,0xA7, +0x04,0x5C,0x26,0x21,0xEC,0x5C,0x96,0xDC,0xB8,0xCB,0xCC,0x56,0xC0,0x2F,0x99,0xBF, +0x2B,0x96,0x7F,0x0D,0x0B,0x64,0x92,0x7D,0x67,0xE4,0x88,0x6C,0x6A,0x50,0x91,0xA4, +0xF7,0x7C,0x0E,0xB4,0x15,0x06,0x3D,0xF4,0x55,0xB2,0xB0,0x3C,0x58,0xE3,0x39,0xBD, +0x44,0x45,0x29,0x3B,0xE4,0x6B,0x99,0xB2,0x50,0xA3,0x5F,0x33,0x7C,0xC3,0xAA,0xD3, +0x61,0xF7,0x4B,0xCB,0x2F,0xE7,0x54,0x97,0xD5,0x67,0x91,0xCE,0x00,0x62,0x84,0x03, +0x0C,0x9B,0x40,0x8A,0x71,0x3A,0x2F,0xF9,0xF1,0x34,0x93,0x77,0x6E,0x35,0x6E,0xB2, +0xB9,0x6C,0x0D,0xAE,0x97,0x0D,0x11,0x11,0x70,0xDF,0xDD,0x6A,0xF7,0x0A,0xF1,0xA5, +0x11,0x40,0x43,0x4F,0xAD,0x0E,0x0C,0x2B,0xC8,0xC2,0xFE,0xC1,0x33,0xF7,0xE7,0xF9, +0x36,0xEF,0x15,0x89,0x2B,0xE2,0xCF,0x46,0x25,0xE2,0x6D,0x03,0xBE,0xD2,0x4E,0x5C, +0x1D,0x9C,0xF1,0x47,0x7F,0xE1,0x7B,0x05,0x28,0x47,0xCF,0xAF,0x91,0x27,0xD0,0x50, +0x96,0x4A,0x04,0x85,0x38,0x03,0xB9,0xAD,0xBE,0x9A,0xED,0xA8,0x78,0x3C,0x4A,0xF5, +0xD4,0xF8,0xA6,0x30,0xFA,0xA1,0x8F,0x1E,0xB0,0x33,0xA7,0xB2,0xBA,0x15,0xA3,0xB3, +0x35,0x6D,0xDA,0x13,0x92,0x45,0x05,0xBB,0x85,0x9F,0xCC,0x15,0x20,0xC5,0x32,0xCC, +0xF0,0xEB,0xF4,0x83,0x24,0x99,0xB4,0x35,0x1C,0x2C,0x92,0xBF,0x7E,0xDC,0xBB,0x08, +0xC5,0x0B,0xF0,0x2B,0x4B,0x64,0x6F,0xAB,0x56,0x20,0xE1,0x64,0xE9,0xF2,0xF1,0x2B, +0x03,0xD5,0xA3,0x28,0x3A,0xE5,0x47,0x9E,0xA1,0x0C,0x6F,0xA1,0x70,0xFA,0x7D,0x97, +0x93,0x6A,0xA0,0xBC,0x18,0x7B,0xF9,0xED,0xFE,0xB9,0x33,0x9A,0xAE,0xEC,0xE1,0x71, +0xB4,0x1D,0x4A,0x38,0xB4,0xC8,0x86,0x66,0x45,0x9A,0xAE,0x69,0x9D,0xC4,0x50,0x82, +0xEE,0xD8,0xA1,0xBD,0xFE,0x10,0xCD,0xCA,0x81,0x03,0xF3,0x39,0xA3,0x00,0x22,0xEE, +0x22,0x2C,0x9F,0x0E,0xB6,0x3D,0x8E,0x97,0xB6,0x7B,0xF9,0x12,0x78,0x35,0xE4,0x22, +0x18,0xD1,0x25,0x10,0xE4,0xCD,0xF6,0x81,0x1C,0xD0,0x28,0x02,0x8E,0x05,0xE7,0x92, +0x07,0x4F,0xDB,0x77,0x5D,0x62,0x53,0x11,0xCF,0xFD,0x3C,0xBF,0x6E,0xB2,0xCA,0x47, +0x6B,0xE0,0x25,0x8B,0x8E,0x71,0x31,0x38,0xF7,0x25,0x0C,0xC1,0x32,0xD1,0xAA,0x40, +0x7E,0x2A,0x40,0x10,0x28,0xC9,0xE7,0xBC,0x87,0x2C,0x43,0x13,0x2C,0x51,0x79,0xE0, +0x55,0x12,0x22,0xBF,0x25,0xF7,0x0E,0xB8,0xB7,0x01,0xC6,0x12,0x82,0x22,0x34,0x5F, +0xBF,0xE2,0x4B,0x56,0xD4,0x27,0xED,0x88,0x54,0xB7,0xA4,0x39,0xEE,0x94,0xA6,0x9D, +0x6C,0x25,0xF9,0x4B,0x3C,0xFF,0x93,0xE3,0xB4,0xC5,0x84,0xA6,0xE3,0xF9,0x23,0x79, +0x13,0x33,0xAE,0x02,0x5F,0xAE,0x64,0xC4,0x97,0xED,0x0F,0x04,0xB3,0x0B,0xB1,0x35, +0x06,0x84,0x00,0x04,0x73,0x81,0xCB,0xE6,0xD9,0x1C,0xFA,0xAB,0xE9,0xC1,0xC7,0x4B, +0x89,0x6A,0x3E,0x0E,0x59,0xA7,0xB8,0x80,0xD6,0x6D,0x4B,0x4F,0x54,0x47,0x9B,0xF6, +0x35,0xB6,0xFB,0xCB,0x71,0x4F,0xB7,0x56,0x1F,0xB4,0x72,0x1D,0x82,0xEB,0x47,0x99, +0x2B,0xD4,0x9C,0x3C,0x66,0x63,0xB8,0x6A,0x2E,0x7A,0x84,0xFF,0xB5,0x83,0x97,0xD9, +0xB7,0x80,0xF1,0x47,0x04,0x14,0xDB,0xCA,0xBF,0xE9,0x56,0xC4,0x10,0x18,0xA8,0x91, +0x20,0x17,0x1E,0x8A,0x78,0x2D,0x51,0x34,0xB4,0xF5,0x3C,0x66,0xB2,0xCC,0xE7,0x88, +0xE6,0x50,0x8A,0x15,0x1C,0x2F,0x68,0xD3,0x77,0xB4,0x35,0x2A,0xAE,0xCE,0xF5,0x4E, +0xB2,0x0F,0xA3,0x07,0x21,0x80,0xFC,0x6A,0xB6,0x1C,0xD7,0x12,0xA0,0x35,0x00,0x64, +0x12,0x33,0xB5,0xB0,0xD1,0x38,0xFD,0xF2,0x25,0x6D,0xA9,0x6A,0x7C,0xCB,0x67,0x2C, +0x3E,0x1C,0xD7,0x9C,0x44,0x7A,0xC8,0x66,0x88,0x44,0xE4,0xA1,0xD6,0x1D,0xD7,0x08, +0x84,0xFD,0xF5,0x3B,0x39,0xA0,0x4F,0x72,0xCF,0x1B,0x06,0x04,0x29,0x56,0x7A,0x4E, +0x49,0x88,0xD0,0x07,0x89,0x9A,0xE9,0xB8,0x5F,0xE5,0xAA,0x93,0x7B,0x40,0xA5,0xCB, +0x6E,0x04,0x0B,0x18,0x93,0xCC,0xAF,0xDC,0xFB,0x95,0x72,0x95,0x3A,0xFF,0x9D,0xE9, +0x35,0xC9,0xEF,0x5B,0x80,0x95,0x78,0x9A,0x74,0xE1,0xB6,0x24,0xE9,0x70,0xFC,0x4E, +0x87,0x26,0xDD,0x4F,0x6F,0xBE,0xE4,0x74,0xBD,0x5A,0x6B,0xDB,0xA9,0xC1,0x79,0x27, +0x50,0xBA,0x40,0x1B,0x7B,0xFB,0x7E,0x0B,0x6C,0xA0,0xBF,0x90,0xD2,0x7D,0xF1,0x07, +0x05,0xD4,0xD7,0x54,0x91,0x07,0x17,0xC6,0x8F,0xA2,0xA3,0x61,0x8C,0x9D,0x14,0xC1, +0x22,0x1D,0x16,0x06,0x28,0x5E,0x98,0x1E,0xAA,0x45,0x42,0x3E,0x8B,0x67,0x50,0x7C, +0x64,0x43,0x20,0x4C,0xE4,0x55,0x48,0x55,0x7A,0xDE,0x53,0x23,0x83,0xFB,0x22,0x85, +0x93,0x5F,0x33,0xAE,0xFD,0x94,0xD7,0x58,0x70,0x84,0xF2,0xE7,0xB3,0x7C,0x72,0x67, +0x87,0x23,0xF7,0xA7,0xDC,0xD7,0x15,0xE9,0x6C,0xC5,0x47,0x83,0x8C,0x31,0xEF,0x2B, +0x2B,0x45,0xD4,0x97,0xB3,0x27,0x67,0x87,0x98,0x73,0xF5,0x63,0xA1,0xA2,0x2A,0xD1, +0x24,0xC9,0x4D,0x30,0x98,0xEB,0xCA,0x20,0x87,0x08,0xBA,0x7C,0x42,0xB9,0xED,0x0E, +0xAF,0xD5,0x25,0xB6,0x2C,0xEE,0xD2,0xC8,0xA5,0xCC,0xD9,0xDB,0x9D,0x1D,0x77,0xF3, +0x74,0x03,0x4C,0x04,0xCF,0x88,0xED,0x3F,0xB6,0x7E,0xA5,0x6D,0x20,0x2A,0xCB,0x4F, +0xDA,0xF7,0xAB,0x02,0x90,0xC7,0xCE,0xB3,0x8B,0x50,0x08,0x7B,0x84,0xA2,0xF8,0x49, +0x31,0x59,0x59,0xA2,0x83,0xEF,0x14,0x14,0x1C,0xF6,0x1B,0x0D,0xD9,0xA9,0xC6,0x09, +0x70,0xD2,0x51,0x8D,0x14,0x73,0x22,0x9E,0x69,0x73,0x22,0x57,0x9A,0xDD,0x96,0x79, +0xBD,0x41,0xF3,0xDF,0x2F,0x38,0xDE,0x6D,0x84,0xC7,0x0D,0x81,0x42,0xD0,0x24,0x97, +0x6E,0x95,0x03,0x97,0xD6,0x77,0x8B,0x06,0xFF,0xE2,0xA2,0xB9,0xA1,0x26,0x0A,0x3C, +0xAE,0x27,0xA2,0x67,0x3B,0x67,0x5E,0xE3,0x00,0x54,0x90,0xAF,0xC4,0xBA,0x9A,0x6E, +0x4D,0x12,0x72,0x13,0x60,0xA1,0x39,0x4E,0x6F,0x9F,0x17,0xA8,0xC4,0xF7,0xCA,0x70, +0x21,0xF6,0x11,0xFF,0xCB,0x9E,0x98,0x55,0x12,0x75,0xD9,0x6B,0xE6,0xC2,0x12,0x60, +0x1D,0x22,0xB1,0xAB,0xCE,0xCD,0xAB,0x5E,0x3C,0xF0,0x4A,0x61,0xD7,0x95,0x0C,0x6F, +0x99,0x2F,0xB3,0xDD,0x45,0xB7,0x69,0x07,0xFB,0x10,0x45,0xD6,0x69,0x5B,0xEF,0xC3, +0x11,0xF8,0x11,0x37,0x16,0x09,0x43,0x1F,0x22,0x90,0x60,0x50,0xC9,0xD3,0x38,0x30, +0x3C,0xFC,0x91,0x35,0x6B,0xBF,0xBC,0xC5,0xC6,0x46,0x76,0x00,0xE9,0x27,0x81,0xBC, +0x05,0x7D,0x72,0x69,0xAB,0x87,0x48,0xA7,0x62,0xA0,0x09,0x1F,0xEC,0x8B,0x78,0xBA, +0x13,0x36,0xEF,0xE4,0x51,0x7E,0x40,0xF9,0x4B,0xDB,0x8C,0x2D,0x63,0xF3,0x09,0xD6, +0x0B,0xFE,0xEE,0x9B,0xF8,0x7F,0x0C,0xD6,0x60,0x6A,0x78,0xFA,0x18,0x78,0xFD,0x77, +0x02,0xE9,0xCC,0xD6,0xA2,0x06,0x92,0x86,0x46,0x78,0x55,0xB1,0x49,0xFB,0x6A,0xA7, +0x20,0x44,0xA9,0x3F,0x03,0xB7,0x5E,0x34,0xF5,0x75,0xFD,0xFA,0xE1,0xB7,0xFA,0x34, +0xBA,0x81,0x2F,0x5B,0x59,0xC1,0x85,0x0C,0xEE,0x86,0x2A,0xCB,0xC3,0xC6,0xAE,0x34, +0xE2,0xFE,0xD8,0x12,0xE3,0x70,0xE4,0x68,0x31,0x5D,0xEB,0x86,0x9C,0x06,0xB0,0x83, +0x65,0x13,0x5D,0x2E,0x28,0xC6,0x00,0x8D,0xEB,0xBC,0x0F,0x7E,0xA8,0x4B,0x88,0x2C, +0xB8,0x16,0x4F,0x4B,0x41,0x9D,0x7E,0x1C,0xC0,0x39,0x59,0x46,0xFC,0xB0,0xE9,0xAA, +0x57,0x65,0x8E,0xF0,0xC4,0xBA,0x07,0x18,0x6B,0x0F,0xA0,0x3C,0xCD,0x38,0x05,0x85, +0x7D,0x38,0xBA,0x37,0x99,0xAC,0x72,0x6E,0xB3,0x70,0x31,0xEA,0xBE,0x31,0x3E,0x7B, +0x2A,0x7D,0x82,0x7F,0x82,0xF2,0xC9,0xD5,0x92,0x6E,0xEE,0xC2,0x81,0xE2,0xE9,0xB3, +0x5F,0xAD,0xED,0xAE,0x3C,0xED,0xEA,0xDF,0x95,0x93,0xDB,0xB3,0xB4,0xE5,0x72,0x2D, +0xB8,0x0B,0x43,0xDB,0x96,0x09,0x7D,0xF2,0xCC,0x2D,0x02,0x47,0x20,0xAA,0x9D,0xAA, +0xC4,0x92,0xB6,0xEB,0xEA,0x7A,0xBF,0x86,0x77,0x7F,0xAB,0x20,0xB8,0x04,0x1B,0x03, +0x31,0x2B,0x98,0x0B,0x62,0xD2,0xDA,0x93,0x5F,0x99,0xBC,0x71,0x7B,0xD1,0x55,0xD4, +0xC7,0x50,0xB4,0xEC,0x5E,0x3F,0x48,0xF6,0xFA,0xE4,0x54,0x99,0x39,0xBD,0x5D,0x6B, +0xFB,0x01,0x00,0xCC,0x14,0x54,0x6C,0x8F,0x40,0x24,0x5B,0x75,0x26,0xBF,0xD4,0x9A, +0xD0,0xA8,0x38,0x93,0x9B,0x40,0xD0,0x75,0x5D,0x8C,0x70,0x71,0x2A,0xCB,0x82,0x3D, +0x22,0x96,0xD9,0x66,0x40,0x89,0xD1,0xE2,0x9F,0x30,0x6E,0x6C,0x5B,0x25,0x60,0xB3, +0xE7,0x87,0x89,0xE2,0x1D,0x20,0x1E,0x37,0xC1,0x7A,0xB9,0x33,0xF5,0xB5,0xC5,0x77, +0xD8,0x25,0xCC,0x93,0xE2,0x54,0x57,0x0F,0xAA,0x1E,0xF9,0xB7,0xCC,0x6C,0xCB,0x15, +0x04,0x8E,0x4B,0xCB,0x78,0xB9,0x0B,0xD9,0xA0,0x9B,0x59,0xEF,0x23,0x47,0xAD,0x27, +0x80,0x5B,0x8F,0x37,0xD5,0xB8,0x5B,0xFD,0x81,0x94,0xE6,0x73,0x59,0x9F,0x37,0xC5, +0x19,0xB8,0x10,0xBF,0x0D,0x10,0xDF,0x21,0x3B,0x95,0x4B,0xFC,0x8D,0xB3,0x80,0xDE, +0x06,0x2C,0xA8,0x6F,0x12,0x5D,0x3B,0x16,0x0A,0xA3,0xE9,0x38,0x5D,0x32,0x51,0x53, +0x70,0x2E,0xBB,0x57,0x07,0x4D,0xA3,0xD5,0xD8,0x10,0x00,0x8A,0x2A,0x3C,0xEA,0x1F, +0x1D,0xA0,0x80,0xB0,0xD4,0xF9,0x9B,0xED,0xB5,0xB1,0x56,0xED,0x32,0xDB,0x7E,0x68, +0x66,0x0B,0xA5,0x82,0x3A,0x91,0xD1,0xA7,0x07,0x3E,0xEB,0xBC,0x12,0xBB,0x39,0x2E, +0x3A,0x26,0xB2,0x53,0xD9,0xAA,0x93,0x2B,0xAE,0xE4,0xBC,0x92,0x3C,0x92,0xCF,0x80, +0xE8,0x04,0x75,0xD9,0x64,0x2E,0x97,0x35,0x89,0x88,0x6A,0x7E,0x26,0x23,0xFA,0x28, +0x53,0x64,0x21,0xC2,0x41,0xCA,0x37,0xDE,0xF5,0x67,0x08,0x93,0xBC,0xC3,0x18,0x42, +0x32,0x88,0x40,0x88,0x78,0xC8,0xE8,0x90,0xEF,0xE5,0x73,0x67,0x86,0x4F,0xD3,0x12, +0x43,0x54,0x48,0x5B,0x6E,0xEF,0xE4,0x98,0x9C,0x3A,0x32,0xC4,0x7A,0xD1,0x89,0x14, +0xBA,0x16,0x54,0x61,0x2C,0x6D,0x75,0x89,0xB6,0x7A,0xA3,0x8B,0xEE,0x42,0xF8,0xF8, +0xB7,0xF3,0x97,0xA6,0x75,0xA4,0x78,0x4D,0x9D,0x6E,0xD1,0xDD,0xAF,0x81,0xF1,0xEF, +0x5D,0x5E,0xBB,0x12,0x72,0x71,0xB4,0x57,0x65,0x6B,0x3C,0x2D,0x83,0x90,0x7B,0x17, +0x8B,0xAA,0xE6,0x49,0x37,0xC4,0x60,0xE3,0x2F,0xAE,0x3B,0x52,0x9F,0x0B,0x49,0xDE, +0xC8,0x96,0xB1,0xE1,0xCE,0xB3,0xCD,0x2F,0xCE,0xC8,0x91,0x0A,0x5F,0x5B,0x08,0x04, +0xB8,0x99,0xC2,0x33,0x86,0x73,0xE4,0x78,0x50,0x85,0xE5,0x81,0x5E,0xC1,0x89,0x85, +0x53,0x39,0x9D,0x5D,0x6B,0xC8,0x36,0x7F,0x70,0x08,0xD8,0xD7,0xEF,0x2C,0x25,0x2F, +0x28,0xF8,0xE0,0x62,0x50,0x4F,0x22,0x3D,0xAE,0x7E,0x8E,0xC3,0x87,0x81,0x74,0x65, +0x22,0x9A,0x6A,0xEE,0x7D,0xBC,0x8E,0x34,0x10,0x66,0xF1,0xDC,0x32,0x10,0xA8,0x3B, +0x3F,0xE6,0xA8,0x6C,0xF6,0x36,0x10,0x30,0x9F,0xFD,0x4F,0xB2,0xA5,0x53,0x96,0xD9, +0x10,0xB3,0xE5,0x08,0xD1,0x26,0x1B,0xB2,0x41,0xEB,0xA3,0x2B,0xF2,0xE9,0xDA,0xE8, +0x05,0xD3,0x41,0xDB,0x03,0x7A,0xCF,0x97,0x91,0x33,0xE1,0x0B,0xBE,0x0A,0xD5,0x26, +0x0E,0xCF,0x09,0x70,0xA5,0x27,0x0A,0x4E,0x6C,0x2C,0xCE,0x90,0xD2,0xA5,0x0B,0xE6, +0xA8,0x38,0x41,0xBC,0x1B,0x66,0x39,0x60,0x92,0x87,0x50,0xB2,0xE1,0x7D,0x4F,0x50, +0x82,0x4A,0x54,0x23,0x89,0xF3,0x6A,0x04,0x67,0x98,0xDA,0x3E,0xC3,0xBD,0xA9,0xB4, +0x14,0x9C,0x01,0xB8,0x36,0xA6,0x20,0x35,0xDB,0x60,0x1A,0xF0,0x16,0x03,0xCC,0xA1, +0x20,0x9F,0x04,0x9D,0x6D,0x02,0x7B,0xB0,0xD7,0x3F,0x69,0xB2,0xE6,0x48,0xA1,0xB2, +0x67,0xC5,0x77,0x70,0x5F,0xC8,0xF0,0x14,0xF1,0x40,0x03,0x05,0x59,0xA0,0x07,0x93, +0x26,0xD2,0xDA,0x4C,0xEF,0xF2,0xF0,0x65,0x2B,0xCB,0x45,0x07,0xE7,0x29,0xCD,0x6A, +0xFA,0xB1,0x25,0xF4,0x7F,0x45,0x79,0xB3,0x1A,0xCD,0xEF,0xFF,0x5A,0xD6,0xB8,0xAE, +0xEF,0x4B,0xF4,0x0F,0x3C,0xE5,0x54,0x93,0x99,0x5C,0x9C,0x55,0x45,0x93,0x5D,0xEF, +0xF5,0x18,0x59,0x75,0x19,0x90,0x9A,0x1F,0x79,0x2D,0x6F,0x86,0xD8,0x68,0x68,0x97, +0xC9,0x8E,0xE4,0x24,0x4B,0xC8,0x7D,0x12,0xFE,0xEE,0x66,0xAA,0xB0,0x39,0x5E,0xD4, +0xCD,0x2D,0x06,0x20,0xBA,0x55,0xAA,0x88,0x9B,0x27,0x48,0x24,0x9D,0x1C,0xCD,0xF8, +0x31,0xBF,0xDA,0xA9,0xD2,0xD4,0x00,0x26,0x9C,0xFB,0x95,0xDC,0x39,0xB8,0xE0,0xB0, +0x85,0x0B,0x77,0x44,0x76,0x57,0x41,0x72,0xE4,0x11,0xBA,0x58,0xD3,0x08,0x21,0x12, +0xB8,0xD7,0x57,0x7A,0x85,0xA8,0x9F,0x60,0xFD,0xD9,0x16,0x6A,0xB1,0xBE,0x16,0x9F, +0xC9,0xC3,0x88,0xCC,0xC3,0x97,0xF5,0xA1,0xD2,0x77,0xB5,0x8E,0x28,0xB1,0x87,0xD3, +0xAA,0x3B,0x55,0x61,0xE1,0x71,0x1F,0xDF,0xE9,0x86,0x2A,0x84,0x49,0xBD,0x77,0x31, +0x0D,0xDE,0x35,0x0B,0x8F,0x0B,0xF6,0x7A,0x91,0xC8,0x13,0x82,0x16,0x7C,0x8E,0x0F, +0xE4,0xAA,0xCD,0x1A,0x30,0xF2,0x94,0xAC,0xD8,0xE6,0xC2,0x1C,0x31,0xD8,0xFF,0x76, +0xC7,0x3E,0x70,0x42,0x0A,0x45,0xA2,0x52,0x4E,0xAD,0xC5,0x4D,0xF8,0x0F,0x8F,0x24, +0xEE,0x14,0x30,0xD2,0x22,0xE9,0xC8,0x32,0xAD,0xE7,0x41,0xD7,0x10,0xFA,0x22,0x15, +0xF7,0x04,0x0A,0xBB,0x8F,0xC6,0x99,0xAE,0x5F,0xC5,0x3E,0x7F,0x40,0xC0,0x44,0x3C, +0xCB,0xE0,0xF4,0x17,0x45,0x26,0x6A,0x5D,0xF9,0x63,0xC4,0x9F,0x58,0x22,0xBA,0x98, +0x6E,0x23,0xED,0x01,0xF7,0x0F,0xE4,0x9A,0x55,0x40,0xE1,0x2A,0x8A,0x73,0xEC,0xAF, +0xAA,0x1B,0x05,0x74,0xB2,0xFD,0xA6,0x03,0x5A,0x1A,0x35,0xEA,0x41,0x30,0xCD,0x2C, +0xAF,0x89,0x4B,0x9C,0xF2,0x8C,0xBC,0x7A,0xEC,0x60,0x15,0x1F,0xE5,0xC2,0x7C,0x48, +0x62,0x06,0x16,0xD2,0x75,0xCB,0x25,0x20,0xEB,0x5F,0xF9,0x64,0x6B,0x28,0x8A,0x4E, +0xD7,0xBC,0x51,0x1B,0x0D,0x21,0x03,0x00,0xF7,0x75,0x33,0xC8,0xC5,0x58,0x66,0xDD, +0xFB,0xF3,0xE6,0x97,0x83,0x69,0x37,0x9C,0xE3,0x3B,0x72,0x5A,0x06,0x39,0xF2,0xF4, +0x5B,0xC3,0xE7,0x95,0xAB,0xB3,0x66,0xDC,0x66,0x4C,0x8B,0xCE,0x9B,0xF6,0xB5,0x1E, +0xBB,0xDD,0x47,0x11,0x87,0x65,0xCB,0x7E,0x4A,0x74,0xEB,0x1C,0x44,0x1A,0x08,0x70, +0xD2,0x4B,0x54,0xCF,0x43,0x63,0xA7,0xAB,0x4B,0xA2,0xF7,0x64,0x3F,0xCD,0xBC,0x72, +0x79,0xBE,0xA0,0xED,0xA0,0x1B,0x83,0xE0,0xD2,0x73,0x61,0xFB,0x24,0x20,0x62,0x7A, +0xC4,0x9A,0x16,0xE2,0xE3,0x8E,0x77,0x1E,0xBF,0xF5,0x5F,0xE6,0x2F,0xC2,0x93,0xDE, +0x20,0xA5,0x47,0xD4,0x3D,0x8F,0x20,0xB4,0x3C,0xD4,0x4A,0x33,0xDB,0x48,0x2E,0x27, +0xEB,0x58,0xDF,0xD5,0x7C,0xA2,0xD9,0x8A,0x26,0xC7,0x92,0xCE,0x05,0xB9,0x5A,0x2A, +0x4C,0x18,0x8E,0x89,0x0B,0x34,0x66,0xEA,0x9F,0xD1,0xEE,0x69,0x43,0xDC,0x91,0x87, +0x39,0xD6,0x7D,0x86,0xA1,0x6F,0xCF,0x2A,0x3F,0xB4,0xA7,0x54,0x63,0x45,0xDB,0xD8, +0xD9,0x0F,0xF2,0xE5,0x2F,0xD2,0x87,0x08,0x2D,0x0B,0xA9,0x6D,0x41,0x8F,0xA4,0x5D, +0x9A,0x15,0xE9,0x7C,0xC2,0xEA,0x05,0xD2,0xB1,0x94,0xA8,0xAC,0x67,0x72,0x61,0x39, +0xDC,0xEC,0xC8,0x74,0xBF,0x74,0x7E,0xCC,0x1B,0x81,0x9B,0xFF,0x58,0x86,0x3E,0x01, +0x5C,0x5E,0xBE,0x33,0x8F,0x60,0x70,0xA1,0x86,0x3A,0x07,0x07,0xE2,0x7C,0x72,0x95, +0x38,0xDE,0xB4,0x9B,0xB8,0x59,0xAE,0xFF,0x2F,0x49,0x92,0xCB,0x99,0xE2,0x58,0x21, +0x1E,0x3B,0xE4,0xC5,0xB0,0x6B,0x6E,0x29,0x70,0x27,0xAF,0xA7,0x2E,0x6C,0xF8,0x1C, +0x7C,0x55,0xE4,0x9C,0x1D,0xA4,0x70,0xFD,0x5E,0xE1,0x75,0x75,0x21,0xAC,0x8A,0xC2, +0x0C,0xB9,0xC6,0x5A,0x7E,0xA1,0x78,0xFF,0x54,0xC0,0xD2,0x5D,0x1F,0x96,0x6A,0xE7, +0xCE,0x30,0xAF,0x91,0xBA,0xF8,0x96,0xDE,0xFB,0xDA,0x1F,0x03,0xDC,0x92,0x79,0x49, +0x08,0x44,0x90,0x67,0xF1,0xE5,0xED,0x2C,0x21,0x51,0xA3,0x9B,0xC9,0x16,0x03,0x6E, +0xF7,0xDB,0xFD,0xD2,0x7B,0x87,0x47,0xF3,0x95,0xB0,0xA1,0xB2,0xA0,0x7D,0xA0,0x3A, +0xCF,0xD8,0x7C,0x49,0xB9,0x31,0xB0,0xCD,0xF0,0x70,0x9E,0x57,0xF2,0x79,0x7F,0x6E, +0xC7,0xB1,0x71,0x5D,0x3F,0x6E,0x0C,0x83,0x10,0xB8,0xD2,0x61,0xF3,0xCD,0x18,0x09, +0xF0,0xE0,0xAA,0xE5,0xC6,0x54,0x1F,0x4E,0x1F,0xFF,0x11,0x06,0xED,0xAE,0xF4,0x9A, +0xA9,0xF4,0x05,0x7A,0xAB,0x26,0x7C,0x4E,0xA6,0x55,0xEB,0xFA,0x8F,0x6E,0x3C,0xCB, +0xD3,0x71,0xE8,0x3A,0x94,0xE1,0x16,0x33,0x80,0xBB,0x79,0xC0,0x3C,0xF0,0x28,0xC2, +0x81,0xFC,0xB5,0x73,0x09,0x48,0x6C,0x85,0x1C,0x01,0xEF,0x9B,0x5E,0xB0,0xF2,0xAA, +0x7E,0xCB,0x30,0x94,0xE5,0x1E,0x52,0xBC,0x5E,0x77,0x3B,0x86,0xC9,0x7D,0x3A,0x06, +0xEE,0xB3,0x98,0x91,0xBE,0xE4,0x04,0x64,0x9F,0x73,0x52,0x33,0x1A,0xBF,0x3E,0x18, +0x69,0xD1,0x77,0xE2,0x37,0xC9,0x31,0x1F,0xD6,0x4D,0x51,0x57,0xA7,0x9D,0xDE,0xCC, +0xA0,0x89,0xFC,0x01,0xEB,0xB6,0x10,0x16,0xC0,0x66,0x48,0x40,0xE0,0x9C,0x87,0x05, +0xE3,0x26,0x2C,0x02,0x0B,0x87,0x2A,0x62,0xB4,0x7F,0xA6,0x55,0x8B,0x48,0xF0,0x2E, +0x0F,0x96,0x82,0xC0,0x73,0x87,0xC8,0x52,0x38,0xCA,0xE4,0x3D,0x18,0x15,0x08,0xEC, +0xFF,0x19,0x27,0x3D,0xDA,0x22,0xF6,0x52,0x0C,0x1F,0xD2,0x8F,0x6B,0xEC,0x43,0xF8, +0xE0,0xE5,0x61,0x51,0xC6,0xD5,0x17,0xD4,0x15,0x40,0x1E,0x2D,0x26,0x9C,0xD0,0xDE, +0xAE,0x3E,0xD4,0xDF,0xB9,0x5F,0x2D,0x32,0xFE,0x4E,0xD0,0x18,0x9F,0x07,0x48,0xCD, +0x8C,0x28,0xD0,0x4A,0xE0,0xB2,0x67,0xF5,0xEF,0x01,0x5D,0x8F,0x8C,0x72,0x9E,0xE8, +0xF9,0x42,0x9C,0xF7,0xCD,0x49,0x6F,0xF9,0x89,0x29,0x1D,0x46,0x69,0xEA,0x20,0x3C, +0x3C,0xB8,0xB1,0xE9,0x2C,0x9E,0x53,0x51,0x06,0xFF,0x73,0x25,0xF7,0x2F,0xA7,0x6F, +0x04,0x7F,0x0A,0x0F,0x74,0xE4,0x07,0x60,0xA6,0xBA,0x0C,0x9D,0x46,0x4B,0x35,0x4E, +0xC0,0xDC,0x04,0xE7,0x51,0x23,0xC8,0x58,0xF5,0xCD,0x42,0xDD,0x1E,0xE6,0xD9,0x34, +0x87,0xA3,0x39,0x52,0x64,0x39,0x2B,0xA3,0x6D,0x80,0x4E,0xE8,0x13,0xB7,0xB5,0xA6, +0xAF,0x63,0x9D,0x22,0x6F,0xC7,0xFF,0xD6,0x34,0x27,0x59,0xC8,0xAA,0xC4,0xC7,0xB6, +0xDA,0x3F,0xCD,0xE7,0xA6,0x0A,0x81,0xA7,0xBA,0xCA,0xE1,0xBA,0xD4,0x45,0x3E,0x1A, +0x8D,0x2A,0x56,0xAD,0xB2,0x2F,0x4F,0x59,0x70,0xBC,0xB5,0xDF,0x78,0x13,0x36,0x93, +0x02,0x46,0xBE,0x72,0xCE,0x8C,0xE0,0x2E,0x39,0x74,0x99,0xC4,0x92,0x46,0xA3,0x7F, +0xBF,0xB2,0x1F,0x12,0x5A,0x96,0xD0,0xF2,0x9E,0x74,0x31,0x4B,0xEF,0x0C,0x10,0x3F, +0x99,0xBF,0xA1,0x32,0x80,0xDB,0x70,0x90,0xEE,0x26,0x2A,0x9F,0xF3,0xDE,0x6B,0x6D, +0x8D,0x58,0x6F,0x8A,0xE3,0x10,0x9D,0xE7,0x69,0xC5,0xEC,0x63,0x7C,0x18,0xD7,0x5C, +0x83,0x7C,0x49,0xD9,0x49,0xD1,0x5E,0x12,0xBC,0x00,0xC2,0x5E,0xD8,0x57,0x19,0x29, +0x37,0x8B,0xC9,0x3C,0xE5,0x61,0x9B,0x98,0xD9,0xAA,0xCC,0x79,0xD1,0xAC,0xD5,0x9F, +0xFC,0x8E,0x3D,0xC2,0x50,0xCE,0x34,0xA3,0xAA,0xCF,0x9B,0x82,0x80,0xB7,0x40,0xEF, +0x17,0x44,0xA0,0xC2,0x6A,0x24,0x79,0x39,0x3C,0xD0,0x01,0xDA,0xBF,0x8C,0x7E,0x52, +0x88,0x0F,0xDA,0x49,0x26,0x1E,0x1C,0xD7,0x17,0xD8,0xC4,0x3A,0x44,0x27,0x40,0x5E, +0xB1,0xC2,0x04,0xC4,0xDD,0x34,0x08,0x95,0x75,0x24,0x90,0x77,0x6F,0xB9,0xC5,0x44, +0xCD,0xC2,0x4A,0x7E,0xEA,0xC3,0x12,0x7A,0x00,0x2D,0xEA,0x07,0xC3,0x9F,0x5F,0xFD, +0x95,0xE5,0xB8,0x7E,0x70,0xB8,0x28,0xCF,0xF9,0xDE,0xA8,0xC6,0x54,0x15,0x04,0xD6, +0x78,0xA9,0xD5,0xBF,0xAD,0xED,0xEA,0xEE,0xA1,0xFF,0xB2,0x37,0xC8,0x19,0x12,0xA4, +0x61,0xF2,0x1E,0x71,0x74,0x46,0xCE,0x25,0x73,0x33,0xE6,0xCC,0xB8,0xA2,0xBD,0xEC, +0x33,0xD1,0x08,0xC1,0x1D,0x27,0xB4,0x1F,0xE7,0x09,0xE3,0xE8,0x3F,0xDF,0x1D,0x8B, +0x12,0x72,0xC7,0x38,0x8C,0xB1,0xB1,0x9F,0xF8,0x42,0xEF,0x56,0x03,0xE2,0x75,0x0C, +0x2A,0xE6,0x82,0x4D,0x6A,0x31,0xC3,0xE0,0x10,0x0A,0x8A,0xC4,0x30,0x99,0x82,0x9D, +0x39,0xD7,0x82,0x96,0xF1,0x76,0x68,0xAD,0x38,0x27,0x33,0x39,0x19,0xE1,0xDB,0x7F, +0xA6,0xF3,0xD8,0xF3,0xA0,0xCC,0xCF,0x57,0x1F,0x79,0x23,0x01,0x86,0x28,0x6A,0x95, +0x3C,0x67,0x95,0x4A,0x0F,0x0D,0x32,0xDB,0x20,0x29,0xAB,0x42,0x3B,0xFA,0xEE,0xD7, +0x18,0xED,0xAB,0x89,0x64,0x50,0xF4,0x10,0x46,0x1A,0x14,0x71,0x16,0xED,0x6E,0x71, +0xAD,0x36,0xB0,0x94,0x2C,0xCA,0xA3,0xA8,0x21,0x3E,0xF4,0x5B,0x5E,0xE7,0x1E,0x03, +0x0D,0xD2,0xD7,0x21,0xF8,0x49,0x3C,0x51,0x81,0x85,0x57,0x13,0xC8,0x37,0x17,0xB2, +0xEA,0x95,0xDC,0xE6,0x6C,0xB5,0xE6,0x3E,0x1A,0xBC,0x06,0xC5,0xD1,0x33,0x28,0xF9, +0xF7,0x73,0x7C,0x90,0x5B,0x48,0x11,0x22,0xD8,0xE7,0xAA,0xCD,0x6E,0xA4,0x87,0xE2, +0xB4,0xD8,0x23,0x2E,0x61,0x4B,0x30,0x5C,0xE1,0x4A,0xE4,0x96,0x66,0xDE,0x17,0x68, +0x05,0xFE,0x04,0x68,0x75,0x02,0x29,0x06,0x29,0x06,0x20,0x4F,0x52,0xA0,0x60,0xA7, +0xFD,0xFA,0x59,0xD2,0x3B,0x09,0x2E,0x45,0xDC,0x39,0x86,0x08,0x49,0xD6,0xAA,0xCD, +0x98,0x25,0x36,0x7B,0xCD,0x28,0x6E,0xC5,0x59,0x00,0x42,0xDC,0x05,0xE8,0x89,0xA6, +0x19,0xBA,0x7C,0xA5,0x73,0x9F,0x13,0x2A,0x93,0x42,0x96,0x75,0x07,0xC1,0x5F,0x55, +0x26,0xF8,0x6A,0x34,0x5B,0xF8,0x58,0xFB,0x64,0xAE,0xFC,0x62,0x3C,0x88,0xAD,0x01, +0x3C,0x2B,0xB4,0x1A,0x9E,0xBB,0x12,0x81,0x53,0x62,0x46,0x29,0x78,0x89,0x55,0xCE, +0xFC,0x44,0xE5,0x7F,0xC8,0x47,0x58,0xF7,0x5E,0x90,0xF4,0xBE,0x70,0x6E,0xEE,0xD6, +0xD3,0xF5,0x0B,0x94,0x74,0x13,0x56,0xE7,0x5D,0x57,0x97,0x0A,0xD9,0xAB,0xE3,0x20, +0xFB,0x08,0xB2,0x5B,0x14,0x2A,0xEF,0x3B,0x77,0xDC,0x7D,0x30,0xD5,0x66,0x01,0xA4, +0x19,0x8E,0xB2,0xB6,0x92,0x3B,0x2C,0x3F,0x59,0xC9,0x0F,0x35,0x8B,0x68,0xAB,0x6F, +0xCC,0x77,0x2E,0x76,0xB5,0x71,0xAD,0xBD,0xA6,0x7D,0xDF,0xF8,0x6F,0x09,0x6E,0x2E, +0x66,0x46,0x86,0xCA,0xCC,0xED,0x1D,0xD5,0x14,0xDE,0x75,0x8E,0xD9,0x33,0x0C,0xD4, +0x5D,0xDF,0x9E,0x8B,0xFB,0x96,0x22,0xA9,0xD8,0x77,0xCE,0x0F,0x71,0x97,0x24,0xFD, +0xDA,0xCB,0xB8,0xB2,0xE9,0x67,0xDA,0x31,0x2D,0xF0,0xBD,0x71,0x3C,0xAA,0x19,0x36, +0x04,0x4F,0xE9,0x1A,0x88,0xF7,0xCD,0x58,0xAA,0x05,0x15,0xC2,0x71,0xE6,0x33,0x3A, +0xCB,0x5A,0x70,0x94,0x3B,0x45,0x07,0xD5,0x79,0x6D,0xAC,0x4D,0x0D,0x51,0xBB,0x00, +0xA6,0xE3,0xE1,0xCD,0x59,0x29,0x2D,0x26,0xCC,0x38,0x83,0xF6,0x62,0x38,0x62,0xE3, +0xB0,0xEF,0x89,0xCE,0x29,0xC2,0x9B,0x64,0x3D,0x44,0x4F,0xDD,0x31,0x29,0x68,0xB6, +0xC9,0xFD,0xC2,0x88,0x91,0xD0,0x52,0xCF,0xF4,0x09,0xB5,0xE7,0xB0,0xD5,0xD9,0xE1, +0x37,0x26,0x70,0x08,0x7F,0x22,0x9C,0x85,0xAC,0x51,0xD6,0x5D,0x6E,0x3E,0x12,0x3A, +0x19,0xCA,0xC8,0x6A,0x95,0x94,0x35,0x0B,0xF0,0xAC,0xC7,0xBB,0x3B,0xCE,0x00,0x38, +0xB5,0x1F,0x84,0xC4,0x34,0x29,0x3C,0x8D,0x33,0xB2,0x9A,0x7A,0x65,0x24,0xA7,0xA9, +0x4F,0x8A,0x8A,0x66,0x9F,0xB5,0xAB,0xB5,0x71,0xF2,0xD1,0xDA,0x53,0xC3,0x08,0x6B, +0x25,0x3A,0x6A,0x8C,0x91,0x14,0x78,0x57,0x7A,0x98,0x22,0x56,0x61,0xBB,0xDB,0x43, +0x2D,0x08,0x84,0x3A,0xFE,0x9E,0xA6,0x4A,0x1B,0xB1,0x63,0xDD,0x09,0x40,0x3C,0x9D, +0x65,0x78,0x8C,0x31,0x2C,0x1D,0xD3,0x4F,0xA8,0x7C,0xF8,0x99,0x0A,0xA7,0xF6,0xAE, +0x10,0xBC,0xCE,0xB9,0x61,0xB7,0xAB,0x46,0xA3,0x2A,0xFC,0xB5,0xE6,0x76,0xC0,0x5D, +0xB4,0xA7,0xF9,0x47,0x29,0xF9,0x06,0xEA,0xA8,0xF7,0x6A,0x55,0xF3,0x97,0x99,0xBA, +0x80,0x8E,0x67,0xC9,0xD6,0x6F,0xD4,0xBB,0xBE,0xC1,0x5B,0x89,0x51,0x38,0x92,0xB1, +0x5B,0x20,0xF3,0xD2,0x3C,0x06,0x34,0xE6,0xF0,0xA5,0xA9,0x3C,0xF0,0x3C,0xB9,0x6A, +0x1C,0x9E,0x5B,0xE0,0xDE,0x49,0x06,0x13,0x42,0x57,0xD7,0xA0,0x91,0x60,0x78,0xF0, +0x40,0xCD,0x32,0x36,0x0F,0x3C,0x05,0xDF,0xEE,0xC4,0x2F,0x5D,0x42,0x0E,0xE5,0xB6, +0x4F,0xE4,0xD3,0x27,0x37,0xB3,0xD7,0x30,0xD4,0x34,0xED,0xC8,0x06,0x3D,0xC5,0x7C, +0x78,0x70,0x4E,0x33,0xB9,0xE8,0x06,0x03,0x89,0x4A,0xE1,0x18,0x7D,0xAA,0x2F,0xF3, +0x70,0x7C,0x13,0x99,0x54,0x6B,0x8A,0x43,0xBE,0x67,0x35,0xF4,0x79,0x33,0xD2,0x1A, +0x43,0x9A,0xDC,0x33,0x02,0xBE,0x27,0x61,0x60,0x98,0x8D,0x82,0xC8,0x02,0x3B,0xDF, +0xAC,0x67,0xE7,0x85,0xA5,0x16,0x34,0x62,0xEC,0x27,0x7C,0x9D,0xCA,0x21,0xE7,0x79, +0xBF,0xE4,0xAD,0xA3,0xAF,0x35,0xC4,0x51,0x86,0xDA,0xAF,0x54,0x3E,0x5D,0x88,0x23, +0x3D,0x72,0x3B,0x45,0x1B,0x69,0x79,0xA2,0x6A,0x28,0x6D,0x6D,0xE2,0xAB,0xC3,0xF2, +0xDD,0x9B,0xC5,0xFF,0x00,0x46,0x6E,0x7E,0x4C,0x7D,0x37,0x22,0x6F,0x0A,0x58,0xF6, +0xBF,0xDF,0x3D,0x5D,0x6E,0x43,0xA6,0xC8,0x76,0x15,0xB1,0x9D,0x29,0x2E,0xB4,0x3E, +0x37,0x35,0xED,0x91,0xA3,0x92,0x92,0xC8,0x6E,0xE7,0x1D,0x3F,0x90,0xE5,0xD0,0x16, +0x8C,0xD9,0xB9,0x3A,0x71,0x5A,0x4C,0x2F,0xD5,0x59,0x13,0x63,0x3B,0x88,0x09,0x11, +0x31,0x56,0x9A,0x4A,0xBE,0xF4,0x23,0xF7,0x3A,0xE7,0x4E,0xC9,0xF9,0x68,0x2E,0x94, +0x7B,0xF3,0x20,0xD5,0x68,0xF3,0xAD,0x08,0x37,0xB5,0x17,0xD8,0x0A,0x00,0x8B,0xB9, +0x17,0x2B,0xA3,0x77,0xC0,0x9F,0x0F,0x7C,0xBE,0x62,0xDF,0x95,0x01,0x2D,0xF2,0xD2, +0x8A,0x5A,0x6A,0xC9,0x47,0xB6,0xCB,0x0F,0x2E,0x55,0x62,0x20,0x47,0x09,0x21,0x65, +0xB0,0xD8,0xC5,0xE5,0xD4,0xD3,0x35,0xE4,0x61,0x70,0xA4,0xD6,0x66,0xBC,0x8E,0x1B, +0x5D,0x71,0xFC,0x0E,0x19,0xF3,0x5B,0xCE,0x75,0x4D,0x21,0x98,0xEE,0x53,0xFD,0x10, +0x77,0xBE,0xA5,0x31,0x0E,0x80,0x7A,0x02,0x00,0xF0,0xBA,0x15,0x1D,0xDC,0x74,0x10, +0x2B,0x08,0x58,0x3B,0xAC,0x37,0x62,0x4C,0x38,0x34,0x13,0x0A,0x10,0x82,0xD5,0x02, +0x80,0x5B,0x23,0x97,0x80,0x2B,0xA8,0x26,0x20,0xF8,0x11,0xC3,0xD3,0x15,0x6A,0x5F, +0x15,0xD2,0xE1,0x40,0xD0,0x1D,0x9F,0x0C,0xA0,0x49,0x78,0xF5,0x48,0xA0,0x15,0xB5, +0x85,0x64,0xB8,0xEB,0x7E,0xD4,0xB0,0x75,0x11,0x0A,0xAE,0x98,0x1C,0xDA,0xC5,0xE4, +0xDA,0x00,0xA3,0x73,0x2E,0xE7,0x8E,0x30,0x62,0xE2,0x36,0x12,0x2F,0x30,0x08,0x1A, +0xD0,0x2B,0x9D,0xFA,0x23,0xBC,0x6A,0x9F,0xB3,0x59,0x73,0x4D,0x48,0x55,0x08,0x04, +0x5F,0x75,0x8A,0xE9,0x34,0xB4,0x3A,0x33,0xEB,0xC3,0xC2,0xD8,0xDE,0x3B,0xB3,0xCA, +0x55,0xBA,0x19,0x2A,0x7D,0xB2,0xDA,0xB0,0x64,0xCA,0x5F,0xC4,0xD6,0xFD,0x2D,0x52, +0x50,0x51,0xCD,0x72,0x77,0x55,0xC6,0xDB,0x1A,0x1C,0x29,0x77,0x77,0x34,0x9F,0xE5, +0x91,0x2B,0x7C,0x6F,0x20,0x7E,0x84,0x97,0xAA,0xD4,0x2B,0x63,0x8D,0x2D,0xDC,0x07, +0xAF,0xCF,0xF2,0x8B,0xCE,0x8B,0x62,0xEB,0xC9,0xCE,0xA4,0xB8,0xFA,0x54,0x47,0xA6, +0x45,0x33,0x39,0x13,0xE1,0xA3,0x9B,0x32,0x6C,0x88,0xA9,0x46,0xD5,0x4D,0x98,0x03, +0xED,0xB3,0x92,0x88,0xC8,0x7A,0x92,0x81,0xA2,0x5F,0x8D,0x12,0xF4,0x32,0x1A,0xE8, +0x86,0x60,0x61,0x0E,0x70,0x03,0x3A,0x2A,0x08,0x9B,0xEE,0x05,0x0A,0x8D,0x5E,0x9B, +0x5E,0xA0,0xFC,0x17,0x3E,0x5D,0x13,0xA2,0x7F,0xF9,0x50,0x2C,0xCD,0x48,0xE4,0xAD, +0xBC,0x68,0x7B,0xA7,0x1A,0x22,0xAA,0x9F,0x30,0x42,0x53,0x20,0xAF,0x4F,0xFB,0xD5, +0x26,0xE8,0xC1,0x30,0x74,0xD1,0xA4,0x6F,0xBB,0xA9,0x9C,0xF7,0x1D,0x7B,0x2C,0x2A, +0x5A,0x57,0xF6,0xA3,0x22,0xF0,0xA1,0xDA,0xE4,0x25,0x0B,0xDB,0x99,0x36,0xF2,0x82, +0x6A,0xA2,0x4C,0x21,0xEB,0x4A,0x8E,0x2C,0x90,0x5F,0x1C,0x01,0xB4,0x99,0x85,0x3A, +0x4E,0x2A,0x3C,0x07,0x71,0xE0,0x25,0x96,0xDA,0x5B,0xF4,0xF4,0x13,0x29,0x0A,0x61, +0xEB,0xD8,0x79,0x02,0x75,0x9A,0x06,0xF7,0xC6,0x6C,0x07,0x35,0x20,0x4F,0x90,0xE3, +0xD8,0x4D,0x70,0x0B,0xA8,0xFD,0x5C,0x68,0x9E,0x12,0xA2,0x94,0xA5,0xFA,0x6A,0x7F, +0x40,0xEC,0x68,0x72,0x97,0x3D,0x2C,0xA8,0xE9,0xF5,0xD5,0xED,0x17,0x0E,0xB1,0x32, +0xE9,0x1B,0xF1,0x71,0x16,0x15,0xEF,0xA5,0xA6,0xD8,0x6B,0x0C,0xB0,0x89,0xBA,0x2B, +0xE6,0x51,0xD5,0x7F,0xBE,0x5F,0x93,0xB1,0x9F,0x3B,0x04,0xEE,0xDF,0x14,0xD2,0x83, +0x39,0x46,0x7E,0x68,0xB8,0x7A,0xEB,0x4D,0x60,0x5C,0xCE,0xD1,0xB5,0x21,0xB0,0x65, +0x79,0x24,0x18,0xEF,0x77,0xA1,0xB7,0x08,0xF8,0x62,0x4A,0xF2,0x18,0xDE,0xFB,0x36, +0x2D,0x96,0x68,0xC3,0xD9,0xA0,0xA0,0xA3,0x82,0xA0,0x6E,0x05,0x36,0x1B,0x60,0x2A, +0xE1,0x36,0x96,0x1F,0x1E,0x7A,0x5E,0x86,0x94,0x09,0xD7,0x3F,0x24,0xAB,0xC8,0x8D, +0x94,0x2D,0x1C,0xA8,0xFD,0x2D,0x21,0x3F,0xDB,0x04,0x12,0x91,0x87,0x6F,0xA1,0x73, +0xBB,0x6A,0x68,0x90,0xBF,0xE7,0x92,0x05,0x96,0x7E,0x20,0x2E,0x8F,0x90,0x4D,0x99, +0x7D,0xA5,0x76,0x7A,0x87,0x15,0x61,0x58,0xED,0xC9,0x05,0xFC,0x82,0x92,0xEC,0xAD, +0x91,0xA0,0x9A,0x65,0xC2,0x10,0x3C,0x0D,0x86,0x28,0x0F,0x2C,0x6E,0x3F,0xFE,0x97, +0x8E,0x85,0xAB,0x91,0x38,0xA9,0xE4,0x58,0x5B,0x6C,0x81,0x9D,0xB9,0x6D,0xD4,0x3E, +0xF9,0xB0,0xEA,0xC7,0x43,0xE5,0x5D,0x0A,0x6D,0xAB,0xFD,0xB3,0x87,0x2C,0xEC,0x9F, +0x4D,0x1C,0xBF,0x10,0x32,0x66,0x7F,0x33,0xC3,0xB8,0x18,0xF7,0x45,0x35,0x30,0x10, +0x47,0x1B,0x05,0x6E,0x36,0x7B,0x51,0x69,0x14,0x7B,0xF6,0x19,0x4B,0x40,0x86,0x93, +0x35,0x86,0x91,0x67,0xAB,0x7A,0x49,0xB2,0x59,0xD5,0x3F,0xD9,0xF7,0xA6,0xE9,0x39, +0x81,0xEB,0xFB,0xBF,0xC7,0x58,0xA5,0x26,0x44,0xBB,0xA2,0xA7,0x23,0xF4,0xDB,0x58, +0x90,0x21,0xB2,0x2F,0x30,0xF8,0x48,0x51,0x50,0x02,0xD2,0x9D,0xE7,0x69,0xEE,0x3D, +0x43,0x35,0xFA,0x9A,0x14,0x1B,0x91,0x92,0xC3,0x30,0x1D,0x82,0x76,0x89,0x72,0x9F, +0x25,0xB4,0x4F,0x54,0xAD,0xD0,0x5A,0xA1,0x2E,0xB0,0x41,0x48,0x2D,0x8D,0x62,0xF0, +0x16,0xD6,0xB2,0x84,0x7E,0x17,0xA6,0x7E,0x08,0xAC,0x9B,0xFD,0xED,0x60,0x63,0x8E, +0x14,0xB6,0x31,0xE0,0x3F,0x00,0xC7,0xDB,0x70,0x20,0x4A,0x36,0x39,0x7C,0x2B,0x5D, +0x07,0xA6,0x6F,0x6C,0x87,0x9E,0x34,0xD5,0xAB,0x9C,0xB7,0x00,0xD2,0x43,0x27,0xBD, +0x8C,0x13,0x46,0xA9,0x33,0xAF,0x79,0x87,0xC6,0x02,0x9C,0x51,0xE9,0x30,0x06,0x58, +0x4C,0x23,0x4D,0x2F,0xBB,0x89,0x3E,0xFE,0xE4,0x6D,0x8B,0x54,0x25,0xC9,0x10,0x88, +0x9B,0xFA,0xA4,0x68,0x63,0xFB,0x97,0x83,0x3F,0xFD,0x2D,0x43,0x6B,0xD1,0x5E,0xD5, +0x17,0x10,0xB7,0xAB,0xE1,0x96,0xB8,0x9E,0xF8,0x44,0x48,0xDB,0x9A,0xAE,0x5E,0xE7, +0x60,0xC3,0xBC,0x4C,0x6F,0x0D,0x16,0xEC,0x79,0x60,0xFB,0x80,0x03,0xF6,0xE3,0x86, +0xD0,0xE9,0xF6,0x73,0x74,0x58,0x86,0x0D,0xF3,0x9F,0xB0,0xD3,0xFE,0xE7,0xB7,0x67, +0xD4,0xB5,0x4D,0xAE,0xBB,0xE0,0x19,0x94,0x40,0xAE,0x15,0xE3,0x46,0xCC,0x8A,0xC7, +0xB1,0xD8,0xB9,0x2C,0x47,0x80,0xE4,0xB0,0x93,0x29,0xB4,0xE9,0xB5,0x84,0x3C,0x36, +0xB0,0xA7,0x04,0x85,0x6A,0x5F,0xB4,0x66,0x15,0x80,0x39,0x8E,0x3B,0x89,0x2C,0xEB, +0xAC,0xCB,0x04,0x25,0x1F,0x0E,0xA6,0x06,0x93,0x3E,0x96,0x60,0x2F,0x60,0xBE,0x92, +0x1C,0x47,0xB9,0xB8,0x14,0x76,0x89,0x36,0xEC,0x07,0x8D,0x24,0x36,0xE3,0xC4,0x77, +0x96,0x86,0x99,0xEF,0x97,0x90,0x27,0x68,0x8F,0x74,0xE5,0x5B,0x64,0x8B,0x8D,0x47, +0x04,0x51,0xED,0x5B,0x6B,0x96,0x2A,0xFF,0xBE,0x0B,0x4C,0xD6,0xA6,0x75,0x51,0x38, +0x2B,0xD3,0xBD,0x45,0xAD,0xD6,0x45,0x32,0xC3,0x01,0xC0,0xED,0x87,0x25,0xE5,0x69, +0xB9,0x5F,0x4D,0x39,0x5D,0x2A,0x1D,0xF0,0x72,0x28,0xB8,0x6D,0x99,0xE8,0xF9,0x13, +0x87,0xCD,0x75,0x61,0xBD,0xC1,0xEA,0x4D,0x75,0x53,0x44,0xA6,0x76,0xDF,0x31,0x1B, +0x15,0x2E,0x30,0xF9,0x88,0xEC,0xE1,0x45,0xFB,0xBC,0x80,0xF5,0xB1,0x74,0x88,0xA5, +0x83,0x86,0x6F,0x96,0xF5,0xAF,0x9F,0x6A,0xC0,0xEE,0x3A,0x58,0x3C,0x3E,0xC0,0x16, +0xF8,0x7D,0xE5,0xD3,0x6B,0x7E,0x20,0xF7,0xCC,0x04,0x81,0x7E,0x22,0x98,0x1E,0xA2, +0x78,0xC4,0xA6,0xCB,0x85,0x38,0xD4,0x39,0x98,0xE1,0x5D,0x6A,0x66,0xE6,0xAC,0x27, +0xA6,0x3C,0x1C,0x76,0x80,0xAD,0xBA,0x10,0x16,0x18,0x45,0xF9,0xC1,0x22,0x18,0x81, +0x3A,0xCC,0xEC,0x4C,0x09,0x7B,0x55,0xA4,0x62,0x01,0x41,0xC5,0xF7,0xB3,0x41,0x3D, +0x7F,0xB3,0xE8,0x95,0x53,0xFA,0x0B,0xDE,0x53,0xA6,0x6F,0x80,0x57,0xE1,0xDF,0x08, +0x1B,0xD6,0x2E,0x88,0xE1,0xE5,0xEB,0xF7,0xCB,0xFD,0x2A,0x38,0x67,0x8D,0x03,0xE7, +0x3C,0x0C,0xEE,0xFF,0x0E,0x40,0x38,0xA8,0xBB,0x89,0xEF,0xC0,0x5C,0x8E,0x7D,0x74, +0x6D,0x29,0x1A,0x64,0xB3,0x88,0xF8,0x9F,0xA9,0xEC,0xF9,0x84,0x3A,0x1A,0xAF,0x04, +0x10,0x13,0xBD,0xE1,0x01,0x85,0xF3,0x5C,0xB2,0x09,0x3B,0xF8,0x85,0x0D,0x1A,0x3B, +0x23,0x5B,0xCA,0xF7,0xE4,0x00,0x8E,0x0A,0x48,0x85,0x8B,0x6F,0xE8,0x7B,0x43,0xA9, +0x87,0xE8,0xB1,0x64,0x7D,0xA0,0xDB,0x0A,0xBF,0x01,0x66,0x72,0x31,0x34,0xF1,0x83, +0x71,0xD5,0xAA,0x36,0xC4,0xE7,0xC9,0xFC,0xDB,0x8D,0x1F,0x40,0xD3,0xED,0xF7,0xB4, +0x17,0x28,0xDA,0x5A,0xBF,0xDA,0xDD,0xCB,0xAC,0xE8,0x18,0x2C,0x62,0xC0,0xF0,0xAB, +0xAE,0x3D,0x42,0x54,0x4F,0x97,0xE3,0xB1,0x80,0x66,0x9C,0xF3,0x05,0x11,0x2B,0x4B, +0xA5,0x23,0xFD,0xDC,0x5A,0xDC,0xC0,0x09,0xA4,0x5A,0xDC,0x66,0xCE,0x55,0x31,0x70, +0xC1,0xCA,0xCA,0x1F,0x97,0x62,0x55,0x22,0x6D,0x70,0xA6,0xE1,0x70,0xF8,0x1B,0x24, +0x4D,0x43,0x73,0xBC,0xFD,0xFF,0x6B,0x64,0xE5,0xFD,0x54,0x72,0x51,0x24,0xEB,0xC1, +0xFC,0x01,0xE5,0x93,0x64,0x92,0x9B,0x2E,0x1A,0x57,0xDF,0xC0,0x78,0xB2,0x44,0x95, +0x35,0x31,0xAA,0x39,0x19,0x68,0x0B,0x62,0x66,0xA0,0xA9,0x05,0x1C,0x7A,0x03,0x89, +0x72,0xD6,0xD1,0x92,0x22,0x7E,0xFC,0x4D,0x19,0x26,0x1F,0x3A,0x28,0x8B,0xFC,0xFF, +0xC7,0xDB,0xA5,0x68,0x2E,0xDD,0xC3,0x52,0xE2,0x0E,0xBD,0xB6,0x9A,0x98,0x91,0x6E, +0xEF,0x64,0x7E,0xE1,0xE5,0xF4,0x09,0x96,0x7C,0xDB,0xBA,0x2C,0x90,0x13,0x89,0x1A, +0x4B,0xFF,0xEC,0x8E,0xAA,0x0F,0x66,0x50,0x3B,0x03,0x4C,0xBE,0x2C,0xFE,0xD2,0x39, +0x0F,0xD9,0x2B,0xB4,0xF9,0x17,0x59,0x8A,0xE4,0x62,0x56,0x4D,0xEE,0xA1,0x7E,0xDE, +0xAF,0xA1,0xDC,0x3C,0x56,0x7B,0x61,0xF1,0x80,0x5E,0x19,0x75,0x43,0x88,0x6F,0x87, +0xC7,0xF3,0x3F,0xD6,0x40,0x1B,0xCB,0xFA,0x6D,0x2F,0x73,0x51,0xC8,0xE5,0x3A,0xB0, +0x62,0x3F,0x6C,0x5C,0x7F,0x53,0xB4,0x56,0x1B,0x29,0x8F,0x33,0x37,0xF7,0x1D,0x16, +0x96,0x65,0xC6,0x98,0x6A,0xC5,0x4F,0x15,0xA5,0xCF,0x22,0xA0,0xA4,0x86,0xA0,0x5E, +0x44,0xF6,0xDD,0x84,0xD5,0x91,0x8C,0x69,0x4F,0x3A,0xF9,0x01,0xF4,0x5D,0xCD,0xBB, +0x49,0xA7,0xA1,0x00,0xD7,0xE8,0x63,0xBA,0xEB,0x4A,0xAC,0xB4,0x28,0x6A,0x39,0xD1, +0xC4,0x2A,0xA0,0xD6,0xD5,0x3D,0x04,0x5E,0xE6,0x7D,0x32,0x5B,0x68,0x6F,0x25,0x30, +0x55,0x42,0x96,0x73,0x05,0x1A,0x77,0x1E,0xC1,0x6D,0x19,0x72,0xA2,0xAA,0xDB,0xD8, +0x22,0x75,0xC3,0xB9,0x39,0x21,0x62,0xF1,0xA5,0xD5,0xD2,0x9C,0x7E,0xEF,0xE9,0x25, +0x6E,0xEA,0xA8,0x07,0x0B,0xF2,0x65,0x44,0x95,0x27,0xA6,0x92,0x6F,0x80,0x1D,0x53, +0x7A,0x99,0xE4,0x87,0xCA,0x4D,0xDC,0xA1,0x44,0x68,0x4B,0x11,0x6E,0x4B,0xA1,0x91, +0x2C,0x4B,0xE2,0xAD,0xA9,0xA5,0xD9,0x39,0xCE,0xA9,0x0D,0x22,0xBE,0xE1,0x8D,0x5F, +0x61,0x63,0x8C,0x75,0xC1,0x28,0x79,0x94,0x09,0xC0,0x35,0x39,0x8C,0x95,0x46,0x69, +0xCC,0x00,0x1F,0x84,0xD4,0xE2,0x24,0x43,0x4E,0xA8,0xCE,0x44,0x0D,0x12,0x20,0xF3, +0x3B,0x8C,0x4D,0xA4,0x6F,0x61,0x8E,0x67,0xA8,0x24,0x9F,0x73,0x03,0x49,0xBF,0xF4, +0x01,0xCF,0xA5,0x7C,0xFD,0x68,0x29,0xD9,0x7B,0x1D,0xC4,0x04,0x62,0x69,0x6A,0xAB, +0x5F,0xF5,0x11,0xC8,0x1A,0x90,0x9D,0x90,0x9A,0xDE,0xE7,0x30,0xBC,0xA9,0xDB,0x95, +0x97,0x18,0xBA,0x24,0x87,0x0B,0xCD,0x7B,0xE8,0xBB,0xC9,0x9F,0x8F,0x9D,0xCE,0x86, +0x93,0x01,0x3C,0xA8,0xAB,0xF7,0xAA,0xF2,0xC0,0x92,0x1B,0x68,0x4D,0x3C,0xC6,0x82, +0x7D,0x75,0xF1,0x41,0x96,0xF0,0xDD,0x71,0xDF,0x51,0xFF,0x7D,0xBF,0x0B,0x73,0xB7, +0x5D,0x0F,0x2B,0x84,0x92,0xF3,0x1F,0x37,0x07,0x8A,0xBF,0x0A,0x97,0x70,0xA8,0x6D, +0x53,0x13,0xB5,0xE7,0xA9,0xEF,0x30,0x60,0xFC,0x68,0x95,0x83,0x66,0x4C,0xC8,0x02, +0xAF,0x3B,0x96,0x71,0x63,0x44,0x1D,0x02,0xF5,0xA6,0x06,0x33,0xD1,0x34,0x81,0x0A, +0x79,0x90,0x3E,0xA7,0xC7,0xD8,0x1F,0x2D,0x82,0xD0,0x09,0x45,0x95,0x49,0x3B,0x8B, +0x86,0xBF,0xF0,0xC6,0xA6,0xCE,0x10,0xFC,0xBE,0xF2,0xA7,0x71,0xB4,0x07,0xEE,0x2D, +0xD1,0xAC,0xE7,0x76,0x41,0x23,0x90,0xDC,0xF4,0xFE,0x99,0x5B,0x7F,0xFA,0x7A,0x4F, +0x31,0xC9,0x56,0x9E,0xF6,0x8F,0x55,0x1B,0x0C,0xE9,0x3B,0xB2,0xED,0x7A,0x4F,0x5F, +0xDE,0x60,0x11,0x79,0x7B,0x24,0xA1,0x3B,0x98,0xF3,0x4F,0xD1,0x20,0xB7,0x10,0x37, +0x3D,0x60,0x52,0x59,0x01,0x12,0x0A,0x69,0x8A,0xF9,0x17,0x49,0x4F,0xD4,0x1C,0x66, +0x1A,0x9F,0xE2,0x14,0xAC,0xFF,0x66,0x55,0x3F,0xAD,0xD8,0x12,0xF4,0x68,0x38,0x41, +0x99,0x62,0x9F,0x89,0x81,0x84,0xEA,0xC0,0x56,0x52,0x65,0x02,0x99,0xA0,0x36,0x21, +0x9A,0xB2,0x62,0xEB,0x5B,0xF0,0x16,0x6A,0x06,0x38,0x8C,0xA7,0x29,0x63,0xE2,0x59, +0x2B,0xB8,0xBB,0x58,0x95,0x11,0xE3,0x88,0x9A,0xE3,0x3C,0xDA,0x89,0xB9,0x6A,0x87, +0x50,0xB0,0x11,0xFD,0x80,0x57,0xC5,0xAF,0x3C,0x45,0x05,0x20,0xF4,0x48,0x3A,0x7C, +0xB2,0x86,0xB2,0x34,0x3E,0xFF,0x4B,0x79,0xA7,0x1C,0xAA,0xD8,0xE3,0x61,0xE8,0x62, +0x9B,0x57,0xDC,0x52,0x15,0x97,0x6E,0xF2,0xFA,0x32,0x99,0x1E,0x32,0x83,0x03,0x7C, +0x68,0xF3,0x80,0x8F,0xD4,0x85,0xC6,0x42,0xB9,0xF2,0x52,0x70,0x49,0x9D,0x60,0x78, +0xBF,0xBE,0x13,0x48,0x29,0x69,0xAF,0x13,0xF3,0xA2,0x53,0x36,0x28,0xB2,0x71,0x24, +0xE1,0xB7,0x6F,0xBF,0x68,0xA1,0x01,0xDC,0xB1,0x9C,0x1B,0x4E,0x9E,0x60,0xEA,0x49, +0x78,0x68,0xC6,0x2B,0x25,0x9F,0xEF,0x8B,0x63,0x25,0x88,0xC5,0xD7,0xAE,0x1D,0x70, +0xC5,0x3C,0x08,0xC6,0xA2,0x94,0x99,0x4F,0x24,0x65,0xEB,0x94,0xA3,0xB6,0x42,0x52, +0x8C,0xF9,0x41,0x35,0x19,0xE6,0x22,0x59,0xC3,0xD0,0x5F,0x8F,0x0B,0xD9,0x14,0x64, +0xC8,0x08,0x9C,0x44,0xDB,0x07,0x0E,0x04,0xCC,0xFE,0x6C,0xB5,0xC3,0xA3,0x2A,0x70, +0x00,0x00,0x00,0x03,0x40,0x79,0x03,0x1E,0x05,0x0E,0x08,0x00,0x19,0x19,0x00,0x10, +0x4C,0x04,0x6C,0x07,0x1E,0x05,0x28,0xF5,0x28,0x1E,0x05,0x01,0x30,0x00,0x30,0x00, +0x00,0x48,0x00,0x48,0xF0,0xD2,0xF0,0xD2,0x00,0xE0,0x00,0x00,0x00,0x00,0x0A,0x04, +0xC0,0x03,0x02,0x05,0x64,0x07,0x66,0x64,0xC0,0x00,0x43,0x2A,0x05,0x00,0x00,0x00, +0x00,0x4C,0x6C,0x74,0x3C,0x32,0x00,0x00,0x00,0x4C,0x6C,0x74,0x1E,0x05,0x14,0x03, +0x06,0x0F,0x0A,0x00,0x00,0x10,0x01,0xF8,0x00,0x00,0x02,0xF4,0x01,0x80,0x01,0x0E, +0x1F,0x19,0x4B,0x00,0x19,0x04,0x1B,0x00,0x10,0x0A,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0, +0xC0,0xC0,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x00,0x00,0x00,0x00,0x00,0x01, +0x03,0x05,0x01,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x00, +0xC0,0x80,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x10,0x10,0x10,0x10,0x20,0x20, +0x20,0x20,0x39,0x3B,0x3D,0x3F,0x56,0x58,0x5A,0x5C,0x00,0xFF,0xFF,0x10,0x0A,0x19, +0x00,0x01,0x04,0x08,0x0C,0x0F,0x11,0x12,0x13,0x04,0x31,0x04,0x00,0x00,0x03,0x00, +0x03,0x00,0x01,0x07,0x01,0x0A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0x60,0x60,0x51,0x51,0x51,0x51,0x51,0x51,0xCD,0x0D,0x04,0x00,0x00,0x04, +0x08,0x07,0x0A,0xFF,0xFF,0xFF,0xFF,0x01,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x02,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0xFE,0x6D,0xE1, +0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0x03,0x1E,0x05,0x0E,0x08,0x00,0x19, +0x19,0x00,0x10,0x4C,0x04,0x6C,0x07,0x1E,0x05,0x28,0xF5,0x28,0x1E,0x05,0x01,0x30, +0x00,0x30,0x00,0x00,0x48,0x00,0x48,0xF0,0xD2,0xF0,0xD2,0x00,0xE0,0x00,0x00,0x00, +0x00,0x0A,0x04,0xC0,0x09,0x09,0x05,0x64,0x07,0x43,0x00,0x00,0x00,0x00,0x00,0x56, +0x35,0x1D,0x10,0x00,0x00,0x0B,0x20,0x00,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x53,0x31,0x33,0x30,0x32,0x00,0x00,0x00,0x00,0x00,0x29,0x03,0x0F, +0x00,0x03,0x00,0x00,0x00,0xF0,0x14,0x09,0x09,0x12,0x40,0xFF,0x48,0x18,0xDE,0x16, +0x27,0x05,0x04,0x90,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x6E,0x3D, +0x15,0x21,0x11,0x78,0x6D,0x37,0x13,0x01,0x01,0x6F,0x00,0x33,0x00,0x01,0x34,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, +0xF4,0x01,0x80,0x03,0x0E,0x1F,0x00,0xDF,0x01,0x19,0x04,0x1B,0x00,0x10,0x0A,0xC0, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0x00,0xFF,0xFF,0x00,0xC0,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFF,0xFF,0x10,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x31, +0x04,0x40,0x40,0x03,0x00,0x09,0x09,0x44,0x88,0x13,0x01,0x01,0xBE,0x00,0xDE,0x7D, +0xD8,0x81,0x08,0xC3,0x01,0x80,0x80,0x80,0x80,0x10,0x80,0x80,0x80,0x80,0x80,0x80, +0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0x74,0x0E,0x00,0x01,0x54,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +0xFF,0xFF,0xFF,0xFF,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0xCD,0x0D,0x04,0x07, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x01,0x00,0x01,0x1A,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x80,0xFF,0x00,0x09,0x09,0xCF,0x6B,0x05,0x08, +0x09,0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x09,0x01,0x00,0x01,0x55,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x51,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +#endif + diff --git a/drivers/input/touchscreen/synaptics_redremote.h b/drivers/input/touchscreen/synaptics_redremote.h new file mode 100755 index 0000000000000..57428a319d471 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_redremote.h @@ -0,0 +1,15 @@ +#ifndef _SYNAPTICS_REDREMOTE_H_ +#define _SYNAPTICS_REDREMOTE_H_ +struct remotepanel_data{ + struct i2c_client *client; + struct input_dev *input_dev; + struct input_dev *kpd; + struct mutex *pmutex; + int irq_gpio; + unsigned int irq; + int *enable_remote; +}; +struct remotepanel_data *remote_alloc_panel_data(void); +int register_remote_device(struct remotepanel_data *pdata); +void unregister_remote_device(void); +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/synaptics_s1302_redremote.c b/drivers/input/touchscreen/synaptics_s1302_redremote.c new file mode 100755 index 0000000000000..28a26b66fe2dd --- /dev/null +++ b/drivers/input/touchscreen/synaptics_s1302_redremote.c @@ -0,0 +1,984 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "synaptics_redremote.h" + + +#define CHAR_DEVICE_NAME "rem" +#define DEVICE_CLASS_NAME "remdev" +#define DEV_NUMBER 1 +#define REG_ADDR_LIMIT 0xFFFF + + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_address_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_length_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static int remote_rmi4_i2c_read(unsigned short addr, unsigned char *data, unsigned short length); +static int remote_rmi4_i2c_write(unsigned short addr, unsigned char *data, unsigned short length); +static int remote_rmi4_i2c_enable(bool enable); +static int remote_rmi4_get_irq_gpio(void); +static int remote_rmit_set_page(unsigned int address); +static int remote_rmit_put_page(void); + + +static struct input_dev *remote_rmi4_get_input(void); +static struct i2c_client *remote_rmi4_get_i2c_client(void); +static void remote_rmi4_delay_work(struct work_struct *work); +static struct remotepanel_data *remote_free_panel_data_s1302(struct remotepanel_data *pdata); + + +#define MASK_8BIT 0xFF ; +#define SYN_I2C_RETRY_TIMES 3; +#define BUFFER_SIZE 252 +struct rmidev_handle { + dev_t dev_no; + unsigned short address; + unsigned int length; + struct device dev; + struct kobject *sysfs_dir; + void *data; +}; + +struct rmidev_data { + int ref_count; + struct cdev main_dev; + struct class *device_class; + struct mutex file_mutex; + struct rmidev_handle *rmi_dev; + struct remotepanel_data *pdata; +}; + +static struct bin_attribute attr_data = { + .attr = { + .name = "data", + .mode = (S_IRUSR | S_IWUSR), + }, + .size = 0, + .read = rmidev_sysfs_data_show, + .write = rmidev_sysfs_data_store, +}; + +static struct device_attribute attrs[] = { + __ATTR(open, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_open_store), + __ATTR(release,S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_release_store), + __ATTR(address, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_address_store), + __ATTR(length, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_length_store), + __ATTR(attn_state, S_IRUSR | S_IWUSR, + rmidev_sysfs_attn_state_show, + NULL), +}; + +static int rmidev_major_num; + +static struct class *rmidev_device_class; + +static struct rmidev_handle *rmidev; + + +static struct device *device_ptr; +static struct delayed_work delay_work; + + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int data_length = rmidev->length; + + if (data_length > (REG_ADDR_LIMIT - rmidev->address)) + data_length = REG_ADDR_LIMIT - rmidev->address; + + if (count < data_length) { + dev_err(device_ptr, + "%s: Not enough space (%zd bytes) in buffer\n", + __func__, count); + return -EINVAL; + } + + if (data_length) { + retval = remote_rmi4_i2c_read( + rmidev->address, + (unsigned char *)buf, + data_length); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to read data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return data_length; +} + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int data_length = rmidev->length; + + if (data_length > (REG_ADDR_LIMIT - rmidev->address)) + data_length = REG_ADDR_LIMIT - rmidev->address; + + if (data_length) { + retval = remote_rmi4_i2c_write( + rmidev->address, + (unsigned char *)buf, + data_length); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to write data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return count; +} + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + remote_rmi4_i2c_enable(false); + dev_dbg(device_ptr, + "%s: Attention interrupt disabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + remote_rmi4_i2c_enable(true); + dev_dbg(device_ptr, + "%s: Attention interrupt enabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_address_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input > REG_ADDR_LIMIT) + return -EINVAL; + + rmidev->address = (unsigned short)input; + + return count; +} + +static ssize_t rmidev_sysfs_length_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input > REG_ADDR_LIMIT) + return -EINVAL; + + rmidev->length = input; + + return count; +} + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int attn_state; + + attn_state = gpio_get_value(remote_rmi4_get_irq_gpio()); + + return snprintf(buf, PAGE_SIZE, "%d\n", attn_state); +} + +static int remote_rmi4_get_irq_gpio(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->irq_gpio; +} + +static struct input_dev *remote_rmi4_get_input(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->input_dev; +} + +static struct i2c_client* remote_rmi4_get_i2c_client(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->client; +} + +static int remote_rmit_set_page(unsigned int address){ + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + unsigned char retry; + unsigned char buf[2]; + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 2, + .buf = buf, + } + }; + buf[0] = 0xff; + buf[1] = ((address >> 8) & 0xFF); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + break; + } + msleep(5); + } + + if (retry == 2) { + return -EIO; + } + + return 0; +} + +static int remote_rmit_put_page(void) +{ + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + unsigned char retry; + unsigned char buf[2]; + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 2, + .buf = buf, + } + }; + buf[0] = 0xff; + buf[1] = 0x00; + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + break; + } + msleep(5); + } + + if (retry == 2) { + return -EIO; + } + + return 0; +} + + +int remote_rmi4_i2c_read(unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = i2c_client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + + buf = addr & 0xff; + + retval = remote_rmit_set_page(addr); + if (retval < 0) + goto exit; + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 2) == 2) { + retval = length; + break; + } + msleep(5); + } + + if (retry == 2) { + retval = -EIO; + } + +exit: + remote_rmit_put_page(); + + return retval; +} + +int remote_rmi4_i2c_write(unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + + retval = remote_rmit_set_page(addr); + if (retval < 0) + goto exit; + + buf[0] = addr & 0xff; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + retval = length; + break; + } + msleep(5); + } + msleep(10); + if (retry == 2) { + retval = -EIO; + } + +exit: + remote_rmit_put_page(); + + return retval; +} + +int remote_rmi4_i2c_enable(bool enable) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + + if(enable){ + *(dev_data->pdata->enable_remote) = 0; + }else{ + *(dev_data->pdata->enable_remote) = 1; + } + return 0 ; +} + + +/* + * rmidev_llseek - used to set up register address + * + * @filp: file structure for seek + * @off: offset + * if whence == SEEK_SET, + * high 16 bits: page address + * low 16 bits: register address + * if whence == SEEK_CUR, + * offset from current position + * if whence == SEEK_END, + * offset from end position (0xFFFF) + * @whence: SEEK_SET, SEEK_CUR, or SEEK_END + */ +static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) +{ + loff_t newpos; + struct rmidev_data *dev_data = filp->private_data; + //printk("synap %s\n",__func__); + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + mutex_lock(&(dev_data->file_mutex)); + + switch (whence) { + case SEEK_SET: + newpos = off; + break; + case SEEK_CUR: + newpos = filp->f_pos + off; + break; + case SEEK_END: + newpos = REG_ADDR_LIMIT + off; + break; + default: + newpos = -EINVAL; + goto clean_up; + } + + if (newpos < 0 || newpos > REG_ADDR_LIMIT) { + dev_err(device_ptr, + "%s: New position 0x%04x is invalid\n", + __func__, (unsigned int)newpos); + newpos = -EINVAL; + goto clean_up; + } + + filp->f_pos = newpos; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + + return newpos; +} + +/* + * rmidev_read: - use to read data from rmi device + * + * @filp: file structure for read + * @buf: user space buffer pointer + * @count: number of bytes to read + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + //printk("synap %s\n",__func__); + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + mutex_lock(dev_data->pdata->pmutex); + mutex_lock(&(dev_data->file_mutex)); + + retval = remote_rmi4_i2c_read( + *f_pos, + tmpbuf, + count); + if (retval < 0) + goto clean_up; + + if (copy_to_user(buf, tmpbuf, count)) + retval = -EFAULT; + else + *f_pos += retval; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + mutex_unlock(dev_data->pdata->pmutex); + + return retval; +} + +/* + * rmidev_write: - used to write data to rmi device + * + * @filep: file structure for write + * @buf: user space buffer pointer + * @count: number of bytes to write + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + printk("synap %s\n",__func__); + + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + if (copy_from_user(tmpbuf, buf, count)) + return -EFAULT; + + mutex_lock(dev_data->pdata->pmutex); + mutex_lock(&(dev_data->file_mutex)); + + retval = remote_rmi4_i2c_write( + *f_pos, + tmpbuf, + count); + if (retval >= 0) + *f_pos += retval; + + + mutex_unlock(&(dev_data->file_mutex)); + mutex_unlock(dev_data->pdata->pmutex); + + return retval; +} + +static int rmidev_create_attr(bool create) { + int retval = 0; + unsigned char attr_count; + struct input_dev *input_dev = remote_rmi4_get_input(); + + printk("synap %s\n",__func__); + if(!create) + goto err_sysfs_attrs ; + + if(rmidev->sysfs_dir) + return 0 ; + + if(!input_dev) + return -1; + /* + retval = gpio_export(remote_rmi4_get_irq_gpio(), false); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to export attention gpio\n", + __func__); + } else { + retval = gpio_export_link(&(input_dev->dev), + "attn", remote_rmi4_get_irq_gpio()); + if (retval < 0) { + dev_err(device_ptr, + "%s Failed to create gpio symlink\n", + __func__); + } + } + */ + rmidev->sysfs_dir = kobject_create_and_add("remdev", + &input_dev->dev.kobj); + if (!rmidev->sysfs_dir) { + dev_err(device_ptr, + "%s: Failed to create sysfs directory\n", + __func__); + return -1; + } + + + retval = sysfs_create_bin_file(rmidev->sysfs_dir, + &attr_data); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to create sysfs bin file\n", + __func__); + goto err_sysfs_bin; + } + + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + retval = sysfs_create_file(rmidev->sysfs_dir, + &attrs[attr_count].attr); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to create sysfs attributes\n", + __func__); + retval = -ENODEV; + goto err_sysfs_attrs; + } + } + + return 0 ; + +err_sysfs_attrs: + if(!rmidev->sysfs_dir) + return 0 ; + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); + } + + sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); + +err_sysfs_bin: + kobject_put(rmidev->sysfs_dir); + rmidev->sysfs_dir = NULL; + + return retval; +} + +/* + * rmidev_open: enable access to rmi device + * @inp: inode struture + * @filp: file structure + */ +static int rmidev_open(struct inode *inp, struct file *filp) +{ + int retval = 0; + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + printk("synap %s\n",__func__); + + if (!dev_data) + return -EACCES; + + + rmidev_create_attr(true); + + filp->private_data = dev_data; + + mutex_lock(&(dev_data->file_mutex)); + *(dev_data->pdata->enable_remote) = 1; + //remote_rmi4_i2c_enable(false); + dev_dbg(device_ptr, + "%s: Attention interrupt disabled\n", + __func__); + + if (dev_data->ref_count < 1) + dev_data->ref_count++; + else + retval = -EACCES; + + mutex_unlock(&(dev_data->file_mutex)); + + return retval; +} + +/* + * rmidev_release: - release access to rmi device + * @inp: inode structure + * @filp: file structure + */ +static int rmidev_release(struct inode *inp, struct file *filp) +{ + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + + if (!dev_data) + return -EACCES; + + rmidev_create_attr(false); + + mutex_lock(&(dev_data->file_mutex)); + + dev_data->ref_count--; + if (dev_data->ref_count < 0) + dev_data->ref_count = 0; + + remote_rmi4_i2c_enable(true); + dev_dbg(device_ptr, + "%s: Attention interrupt enabled\n", + __func__); + + mutex_unlock(&(dev_data->file_mutex)); + + return 0; +} + +static const struct file_operations rmidev_fops = { + .owner = THIS_MODULE, + .llseek = rmidev_llseek, + .read = rmidev_read, + .write = rmidev_write, + .open = rmidev_open, + .release = rmidev_release, +}; + +static void rmidev_device_cleanup(struct rmidev_data *dev_data) +{ + dev_t devno; + + if (dev_data) { + devno = dev_data->main_dev.dev; + + if (dev_data->device_class) + device_destroy(dev_data->device_class, devno); + + cdev_del(&dev_data->main_dev); + + unregister_chrdev_region(devno, 1); + + remote_free_panel_data_s1302(dev_data->pdata); + + dev_dbg(device_ptr, + "%s: rmidev device removed\n", + __func__); + } + + return; +} + +static char *rmi_char_devnode(struct device *dev, umode_t *mode) +{ + if (!mode) + return NULL; + + *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); +} + +static int rmidev_create_device_class(void) +{ + rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); + + if (IS_ERR(rmidev_device_class)) { + pr_err("%s: Failed to create /dev/%s\n", + __func__, CHAR_DEVICE_NAME); + return -ENODEV; + } + + rmidev_device_class->devnode = rmi_char_devnode; + + return 0; +} + +static void remote_rmi4_delay_work(struct work_struct *work) { + rmidev_create_attr(true) ; +} + +struct remotepanel_data *remote_alloc_panel_data_s1302(void) +{ + if(rmidev) + { + printk("%s:remote panel data has alloc already null\n",__func__); + return NULL; + } + + return kzalloc(sizeof(struct remotepanel_data), GFP_KERNEL); +} + +static struct remotepanel_data *remote_free_panel_data_s1302(struct remotepanel_data *pdata) +{ + if(pdata) + kfree(pdata); + pdata = NULL; + return NULL; +} + + + +//int rmidev_init_device(void) +int register_remote_device_s1302(struct remotepanel_data *pdata) +{ + int retval; + dev_t dev_no; + struct rmidev_data *dev_data = NULL; + + if(pdata == NULL) + { + printk("%s:pdata is null\n",__func__); + return -1; + } + if(rmidev) + { + printk("%s:remote device has register already null\n",__func__); + return -1; + } + rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); + if (!rmidev) { + retval = -ENOMEM; + goto err_rmidev; + } + + retval = rmidev_create_device_class(); + if (retval < 0) { + goto err_device_class; + } + + + if (rmidev_major_num) { + dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); + retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); + } else { + retval = alloc_chrdev_region(&dev_no, 1, 1, CHAR_DEVICE_NAME); + if (retval < 0) { + goto err_device_region; + } + + rmidev_major_num = MAJOR(dev_no); + } + + + dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + if (!dev_data) { + retval = -ENOMEM; + goto err_dev_data; + } + + dev_data->pdata = pdata; + + mutex_init(&dev_data->file_mutex); + dev_data->rmi_dev = rmidev; + rmidev->data = dev_data; + + cdev_init(&dev_data->main_dev, &rmidev_fops); + + retval = cdev_add(&dev_data->main_dev, dev_no, 1); + if (retval < 0) { + goto err_char_device; + } + + + dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); + dev_data->device_class = rmidev_device_class; + + device_ptr = device_create(dev_data->device_class, NULL, dev_no, + NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); + if (IS_ERR(device_ptr)) { + pr_err("%s: Failed to create rmi char device\n",__func__); + retval = -ENODEV; + goto err_char_device; + } + + INIT_DELAYED_WORK(&delay_work, remote_rmi4_delay_work); + schedule_delayed_work(&delay_work, msecs_to_jiffies(8*1000)); + + return 0; + +err_char_device: + remote_free_panel_data_s1302(dev_data->pdata); + rmidev_device_cleanup(dev_data); + kfree(dev_data); + +err_dev_data: + unregister_chrdev_region(dev_no, 1); + +err_device_region: + class_destroy(rmidev_device_class); + +err_device_class: + kfree(rmidev); + rmidev = NULL; +err_rmidev: + return retval; +} + +//void rmidev_remove_device(void) +void unregister_remote_device_s1302(void) +{ + struct rmidev_data *dev_data; + + if (!rmidev) + return; + + dev_data = rmidev->data; + if (dev_data) { + rmidev_device_cleanup(dev_data); + kfree(dev_data); + } + + unregister_chrdev_region(rmidev->dev_no, 1); + + class_destroy(rmidev_device_class); + + kfree(rmidev); + + + return; +} + +/* +static int __init rmidev_module_init(void) +{ + rmidev_init_device(); + + return 0; +} + +static void __exit rmidev_module_exit(void) +{ + rmidev_remove_device(); + + return; +} + +module_init(rmidev_module_init); +module_exit(rmidev_module_exit); + +MODULE_AUTHOR("Synaptics, Inc."); +MODULE_DESCRIPTION("Synaptics DSX RMI Dev Module"); +MODULE_LICENSE("GPL v2"); +*/ + diff --git a/drivers/input/touchscreen/synaptics_s1302_redremote.h b/drivers/input/touchscreen/synaptics_s1302_redremote.h new file mode 100755 index 0000000000000..891915034f048 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_s1302_redremote.h @@ -0,0 +1,15 @@ +#ifndef _SYNAPTICS_REDREMOTE_H_ +#define _SYNAPTICS_REDREMOTE_H_ +struct remotepanel_data{ + struct i2c_client *client; + struct input_dev *input_dev; + struct input_dev *kpd; + struct mutex *pmutex; + int irq_gpio; + unsigned int irq; + int *enable_remote; +}; +struct remotepanel_data *remote_alloc_panel_data_s1302(void); +int register_remote_device_s1302(struct remotepanel_data *pdata); +void unregister_remote_device_s1302(void); +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/synaptics_s3320_redremote.c b/drivers/input/touchscreen/synaptics_s3320_redremote.c new file mode 100755 index 0000000000000..ad4df62c24637 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_s3320_redremote.c @@ -0,0 +1,984 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin + * Copyright (C) 2012 Scott Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "synaptics_redremote.h" + + +#define CHAR_DEVICE_NAME "rmi" +#define DEVICE_CLASS_NAME "rmidev" +#define DEV_NUMBER 1 +#define REG_ADDR_LIMIT 0xFFFF + + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count); + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_address_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_length_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf); + +static int remote_rmi4_i2c_read(unsigned short addr, unsigned char *data, unsigned short length); +static int remote_rmi4_i2c_write(unsigned short addr, unsigned char *data, unsigned short length); +static int remote_rmi4_i2c_enable(bool enable); +static int remote_rmi4_get_irq_gpio(void); +static int remote_rmit_set_page(unsigned int address); +static int remote_rmit_put_page(void); + + +static struct input_dev *remote_rmi4_get_input(void); +static struct i2c_client *remote_rmi4_get_i2c_client(void); +static void remote_rmi4_delay_work(struct work_struct *work); +static struct remotepanel_data *remote_free_panel_data(struct remotepanel_data *pdata); + + +#define MASK_8BIT 0xFF ; +#define SYN_I2C_RETRY_TIMES 3; +#define BUFFER_SIZE 252 +struct rmidev_handle { + dev_t dev_no; + unsigned short address; + unsigned int length; + struct device dev; + struct kobject *sysfs_dir; + void *data; +}; + +struct rmidev_data { + int ref_count; + struct cdev main_dev; + struct class *device_class; + struct mutex file_mutex; + struct rmidev_handle *rmi_dev; + struct remotepanel_data *pdata; +}; + +static struct bin_attribute attr_data = { + .attr = { + .name = "data", + .mode = (S_IRUSR | S_IWUSR), + }, + .size = 0, + .read = rmidev_sysfs_data_show, + .write = rmidev_sysfs_data_store, +}; + +static struct device_attribute attrs[] = { + __ATTR(open, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_open_store), + __ATTR(release,S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_release_store), + __ATTR(address, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_address_store), + __ATTR(length, S_IRUSR | S_IWUSR, + NULL, + rmidev_sysfs_length_store), + __ATTR(attn_state, S_IRUSR | S_IWUSR, + rmidev_sysfs_attn_state_show, + NULL), +}; + +static int rmidev_major_num; + +static struct class *rmidev_device_class; + +static struct rmidev_handle *rmidev; + + +static struct device *device_ptr; +static struct delayed_work delay_work; + + +static ssize_t rmidev_sysfs_data_show(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int data_length = rmidev->length; + + if (data_length > (REG_ADDR_LIMIT - rmidev->address)) + data_length = REG_ADDR_LIMIT - rmidev->address; + + if (count < data_length) { + dev_err(device_ptr, + "%s: Not enough space (%zd bytes) in buffer\n", + __func__, count); + return -EINVAL; + } + + if (data_length) { + retval = remote_rmi4_i2c_read( + rmidev->address, + (unsigned char *)buf, + data_length); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to read data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return data_length; +} + +static ssize_t rmidev_sysfs_data_store(struct file *data_file, + struct kobject *kobj, struct bin_attribute *attributes, + char *buf, loff_t pos, size_t count) +{ + int retval; + unsigned int data_length = rmidev->length; + + if (data_length > (REG_ADDR_LIMIT - rmidev->address)) + data_length = REG_ADDR_LIMIT - rmidev->address; + + if (data_length) { + retval = remote_rmi4_i2c_write( + rmidev->address, + (unsigned char *)buf, + data_length); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to write data\n", + __func__); + return retval; + } + } else { + return -EINVAL; + } + + return count; +} + +static ssize_t rmidev_sysfs_open_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + remote_rmi4_i2c_enable(false); + dev_dbg(device_ptr, + "%s: Attention interrupt disabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_release_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input != 1) + return -EINVAL; + + remote_rmi4_i2c_enable(true); + dev_dbg(device_ptr, + "%s: Attention interrupt enabled\n", + __func__); + + return count; +} + +static ssize_t rmidev_sysfs_address_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input > REG_ADDR_LIMIT) + return -EINVAL; + + rmidev->address = (unsigned short)input; + + return count; +} + +static ssize_t rmidev_sysfs_length_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int input; + + if (sscanf(buf, "%u", &input) != 1) + return -EINVAL; + + if (input > REG_ADDR_LIMIT) + return -EINVAL; + + rmidev->length = input; + + return count; +} + +static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int attn_state; + + attn_state = gpio_get_value(remote_rmi4_get_irq_gpio()); + + return snprintf(buf, PAGE_SIZE, "%d\n", attn_state); +} + +static int remote_rmi4_get_irq_gpio(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->irq_gpio; +} + +static struct input_dev *remote_rmi4_get_input(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->input_dev; +} + +static struct i2c_client* remote_rmi4_get_i2c_client(void) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + return dev_data->pdata->client; +} + +static int remote_rmit_set_page(unsigned int address){ + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + unsigned char retry; + unsigned char buf[2]; + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 2, + .buf = buf, + } + }; + buf[0] = 0xff; + buf[1] = ((address >> 8) & 0xFF); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + break; + } + msleep(5); + } + + if (retry == 2) { + return -EIO; + } + + return 0; +} + +static int remote_rmit_put_page(void) +{ + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + unsigned char retry; + unsigned char buf[2]; + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 2, + .buf = buf, + } + }; + buf[0] = 0xff; + buf[1] = 0x00; + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + break; + } + msleep(5); + } + + if (retry == 2) { + return -EIO; + } + + return 0; +} + + +int remote_rmi4_i2c_read(unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf; + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = 1, + .buf = &buf, + }, + { + .addr = i2c_client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + }, + }; + + buf = addr & 0xff; + + retval = remote_rmit_set_page(addr); + if (retval < 0) + goto exit; + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 2) == 2) { + retval = length; + break; + } + msleep(5); + } + + if (retry == 2) { + retval = -EIO; + } + +exit: + remote_rmit_put_page(); + + return retval; +} + +int remote_rmi4_i2c_write(unsigned short addr, unsigned char *data, unsigned short length) +{ + int retval; + unsigned char retry; + unsigned char buf[length + 1]; + struct i2c_client* i2c_client = remote_rmi4_get_i2c_client(); + struct i2c_msg msg[] = { + { + .addr = i2c_client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + + retval = remote_rmit_set_page(addr); + if (retval < 0) + goto exit; + + buf[0] = addr & 0xff; + memcpy(&buf[1], &data[0], length); + + for (retry = 0; retry < 2; retry++) { + if (i2c_transfer(i2c_client->adapter, msg, 1) == 1) { + retval = length; + break; + } + msleep(5); + } + msleep(10); + if (retry == 2) { + retval = -EIO; + } + +exit: + remote_rmit_put_page(); + + return retval; +} + +int remote_rmi4_i2c_enable(bool enable) +{ + struct rmidev_data *dev_data = (struct rmidev_data *)rmidev->data; + + if(enable){ + *(dev_data->pdata->enable_remote) = 0; + }else{ + *(dev_data->pdata->enable_remote) = 1; + } + return 0 ; +} + + +/* + * rmidev_llseek - used to set up register address + * + * @filp: file structure for seek + * @off: offset + * if whence == SEEK_SET, + * high 16 bits: page address + * low 16 bits: register address + * if whence == SEEK_CUR, + * offset from current position + * if whence == SEEK_END, + * offset from end position (0xFFFF) + * @whence: SEEK_SET, SEEK_CUR, or SEEK_END + */ +static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) +{ + loff_t newpos; + struct rmidev_data *dev_data = filp->private_data; + //printk("synap %s\n",__func__); + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + mutex_lock(&(dev_data->file_mutex)); + + switch (whence) { + case SEEK_SET: + newpos = off; + break; + case SEEK_CUR: + newpos = filp->f_pos + off; + break; + case SEEK_END: + newpos = REG_ADDR_LIMIT + off; + break; + default: + newpos = -EINVAL; + goto clean_up; + } + + if (newpos < 0 || newpos > REG_ADDR_LIMIT) { + dev_err(device_ptr, + "%s: New position 0x%04x is invalid\n", + __func__, (unsigned int)newpos); + newpos = -EINVAL; + goto clean_up; + } + + filp->f_pos = newpos; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + + return newpos; +} + +/* + * rmidev_read: - use to read data from rmi device + * + * @filp: file structure for read + * @buf: user space buffer pointer + * @count: number of bytes to read + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + //printk("synap %s\n",__func__); + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + mutex_lock(dev_data->pdata->pmutex); + mutex_lock(&(dev_data->file_mutex)); + + retval = remote_rmi4_i2c_read( + *f_pos, + tmpbuf, + count); + if (retval < 0) + goto clean_up; + + if (copy_to_user(buf, tmpbuf, count)) + retval = -EFAULT; + else + *f_pos += retval; + +clean_up: + mutex_unlock(&(dev_data->file_mutex)); + mutex_unlock(dev_data->pdata->pmutex); + + return retval; +} + +/* + * rmidev_write: - used to write data to rmi device + * + * @filep: file structure for write + * @buf: user space buffer pointer + * @count: number of bytes to write + * @f_pos: offset (starting register address) + */ +static ssize_t rmidev_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + ssize_t retval; + unsigned char tmpbuf[count + 1]; + struct rmidev_data *dev_data = filp->private_data; + printk("synap %s\n",__func__); + + if (IS_ERR(dev_data)) { + pr_err("%s: Pointer of char device data is invalid", __func__); + return -EBADF; + } + + + if (count == 0) + return 0; + + if (count > (REG_ADDR_LIMIT - *f_pos)) + count = REG_ADDR_LIMIT - *f_pos; + + if (copy_from_user(tmpbuf, buf, count)) + return -EFAULT; + + mutex_lock(dev_data->pdata->pmutex); + mutex_lock(&(dev_data->file_mutex)); + + retval = remote_rmi4_i2c_write( + *f_pos, + tmpbuf, + count); + if (retval >= 0) + *f_pos += retval; + + + mutex_unlock(&(dev_data->file_mutex)); + mutex_unlock(dev_data->pdata->pmutex); + + return retval; +} + +static int rmidev_create_attr(bool create) { + int retval = 0; + unsigned char attr_count; + struct input_dev *input_dev = remote_rmi4_get_input(); + + printk("synap %s\n",__func__); + if(!create) + goto err_sysfs_attrs ; + + if(rmidev->sysfs_dir) + return 0 ; + + if(!input_dev) + return -1; + /* + retval = gpio_export(remote_rmi4_get_irq_gpio(), false); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to export attention gpio\n", + __func__); + } else { + retval = gpio_export_link(&(input_dev->dev), + "attn", remote_rmi4_get_irq_gpio()); + if (retval < 0) { + dev_err(device_ptr, + "%s Failed to create gpio symlink\n", + __func__); + } + } + */ + rmidev->sysfs_dir = kobject_create_and_add("rmidev", + &input_dev->dev.kobj); + if (!rmidev->sysfs_dir) { + dev_err(device_ptr, + "%s: Failed to create sysfs directory\n", + __func__); + return -1; + } + + + retval = sysfs_create_bin_file(rmidev->sysfs_dir, + &attr_data); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to create sysfs bin file\n", + __func__); + goto err_sysfs_bin; + } + + + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + retval = sysfs_create_file(rmidev->sysfs_dir, + &attrs[attr_count].attr); + if (retval < 0) { + dev_err(device_ptr, + "%s: Failed to create sysfs attributes\n", + __func__); + retval = -ENODEV; + goto err_sysfs_attrs; + } + } + + return 0 ; + +err_sysfs_attrs: + if(!rmidev->sysfs_dir) + return 0 ; + for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { + sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); + } + + sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); + +err_sysfs_bin: + kobject_put(rmidev->sysfs_dir); + rmidev->sysfs_dir = NULL; + + return retval; +} + +/* + * rmidev_open: enable access to rmi device + * @inp: inode struture + * @filp: file structure + */ +static int rmidev_open(struct inode *inp, struct file *filp) +{ + int retval = 0; + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + printk("synap %s\n",__func__); + + if (!dev_data) + return -EACCES; + + + rmidev_create_attr(true); + + filp->private_data = dev_data; + + mutex_lock(&(dev_data->file_mutex)); + *(dev_data->pdata->enable_remote) = 1; + //remote_rmi4_i2c_enable(false); + dev_dbg(device_ptr, + "%s: Attention interrupt disabled\n", + __func__); + + if (dev_data->ref_count < 1) + dev_data->ref_count++; + else + retval = -EACCES; + + mutex_unlock(&(dev_data->file_mutex)); + + return retval; +} + +/* + * rmidev_release: - release access to rmi device + * @inp: inode structure + * @filp: file structure + */ +static int rmidev_release(struct inode *inp, struct file *filp) +{ + struct rmidev_data *dev_data = + container_of(inp->i_cdev, struct rmidev_data, main_dev); + + if (!dev_data) + return -EACCES; + + rmidev_create_attr(false); + + mutex_lock(&(dev_data->file_mutex)); + + dev_data->ref_count--; + if (dev_data->ref_count < 0) + dev_data->ref_count = 0; + + remote_rmi4_i2c_enable(true); + dev_dbg(device_ptr, + "%s: Attention interrupt enabled\n", + __func__); + + mutex_unlock(&(dev_data->file_mutex)); + + return 0; +} + +static const struct file_operations rmidev_fops = { + .owner = THIS_MODULE, + .llseek = rmidev_llseek, + .read = rmidev_read, + .write = rmidev_write, + .open = rmidev_open, + .release = rmidev_release, +}; + +static void rmidev_device_cleanup(struct rmidev_data *dev_data) +{ + dev_t devno; + + if (dev_data) { + devno = dev_data->main_dev.dev; + + if (dev_data->device_class) + device_destroy(dev_data->device_class, devno); + + cdev_del(&dev_data->main_dev); + + unregister_chrdev_region(devno, 1); + + remote_free_panel_data(dev_data->pdata); + + dev_dbg(device_ptr, + "%s: rmidev device removed\n", + __func__); + } + + return; +} + +static char *rmi_char_devnode(struct device *dev, umode_t *mode) +{ + if (!mode) + return NULL; + + *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); +} + +static int rmidev_create_device_class(void) +{ + rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); + + if (IS_ERR(rmidev_device_class)) { + pr_err("%s: Failed to create /dev/%s\n", + __func__, CHAR_DEVICE_NAME); + return -ENODEV; + } + + rmidev_device_class->devnode = rmi_char_devnode; + + return 0; +} + +static void remote_rmi4_delay_work(struct work_struct *work) { + rmidev_create_attr(true) ; +} + +struct remotepanel_data *remote_alloc_panel_data(void) +{ + if(rmidev) + { + printk("%s:remote panel data has alloc already null\n",__func__); + return NULL; + } + + return kzalloc(sizeof(struct remotepanel_data), GFP_KERNEL); +} + +static struct remotepanel_data *remote_free_panel_data(struct remotepanel_data *pdata) +{ + if(pdata) + kfree(pdata); + pdata = NULL; + return NULL; +} + + + +//int rmidev_init_device(void) +int register_remote_device(struct remotepanel_data *pdata) +{ + int retval; + dev_t dev_no; + struct rmidev_data *dev_data = NULL; + + if(pdata == NULL) + { + printk("%s:pdata is null\n",__func__); + return -1; + } + if(rmidev) + { + printk("%s:remote device has register already null\n",__func__); + return -1; + } + rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); + if (!rmidev) { + retval = -ENOMEM; + goto err_rmidev; + } + + retval = rmidev_create_device_class(); + if (retval < 0) { + goto err_device_class; + } + + + if (rmidev_major_num) { + dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); + retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); + } else { + retval = alloc_chrdev_region(&dev_no, 1, 1, CHAR_DEVICE_NAME); + if (retval < 0) { + goto err_device_region; + } + + rmidev_major_num = MAJOR(dev_no); + } + + + dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + if (!dev_data) { + retval = -ENOMEM; + goto err_dev_data; + } + + dev_data->pdata = pdata; + + mutex_init(&dev_data->file_mutex); + dev_data->rmi_dev = rmidev; + rmidev->data = dev_data; + + cdev_init(&dev_data->main_dev, &rmidev_fops); + + retval = cdev_add(&dev_data->main_dev, dev_no, 1); + if (retval < 0) { + goto err_char_device; + } + + + dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); + dev_data->device_class = rmidev_device_class; + + device_ptr = device_create(dev_data->device_class, NULL, dev_no, + NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); + if (IS_ERR(device_ptr)) { + pr_err("%s: Failed to create rmi char device\n",__func__); + retval = -ENODEV; + goto err_char_device; + } + + INIT_DELAYED_WORK(&delay_work, remote_rmi4_delay_work); + schedule_delayed_work(&delay_work, msecs_to_jiffies(8*1000)); + + return 0; + +err_char_device: + remote_free_panel_data(dev_data->pdata); + rmidev_device_cleanup(dev_data); + kfree(dev_data); + +err_dev_data: + unregister_chrdev_region(dev_no, 1); + +err_device_region: + class_destroy(rmidev_device_class); + +err_device_class: + kfree(rmidev); + rmidev = NULL; +err_rmidev: + return retval; +} + +//void rmidev_remove_device(void) +void unregister_remote_device(void) +{ + struct rmidev_data *dev_data; + + if (!rmidev) + return; + + dev_data = rmidev->data; + if (dev_data) { + rmidev_device_cleanup(dev_data); + kfree(dev_data); + } + + unregister_chrdev_region(rmidev->dev_no, 1); + + class_destroy(rmidev_device_class); + + kfree(rmidev); + + + return; +} + +/* +static int __init rmidev_module_init(void) +{ + rmidev_init_device(); + + return 0; +} + +static void __exit rmidev_module_exit(void) +{ + rmidev_remove_device(); + + return; +} + +module_init(rmidev_module_init); +module_exit(rmidev_module_exit); + +MODULE_AUTHOR("Synaptics, Inc."); +MODULE_DESCRIPTION("Synaptics DSX RMI Dev Module"); +MODULE_LICENSE("GPL v2"); +*/ + diff --git a/drivers/input/touchscreen/synaptics_test_rawdata.h b/drivers/input/touchscreen/synaptics_test_rawdata.h new file mode 100755 index 0000000000000..befe7a81d1c5d --- /dev/null +++ b/drivers/input/touchscreen/synaptics_test_rawdata.h @@ -0,0 +1,434 @@ +#ifndef SYNAPTICS_TEST_RAWDATA_H +#define SYNAPTICS_TEST_RAWDATA_H + +#define TX_NUM_TRULY (13) +#define RX_NUM_TRULY (25) +#define DiagonalUpperLimit_TRULY (1100) +#define DiagonalLowerLimit_TRULY (900) + +const int16_t raw_cap_data_truly_3035[TX_NUM_TRULY][RX_NUM_TRULY*2] = +{ + {1444,2407,1374,2291,1428,2381,1368,2281,1364,2273,1379,2298,1332,2221,1342,2236,1357,2261,1326,2210,1321,2201,1363,2271,1111,1852,1107,1846,1094,1823,1078,1797,1075,1791,1076,1792,1059,1765,1060,1766,1071,1785,1070,1783,1073,1788,1037,1729,1024,1707,}, + {1370,2283,1338,2230,1339,2232,1324,2207,1304,2173,1322,2204,1306,2177,1300,2167,1306,2176,1273,2122,1277,2128,1263,2106,1194,1990,1184,1973,1203,2005,1159,1932,1165,1941,1158,1930,1150,1916,1148,1914,1157,1929,1151,1919,1156,1927,1127,1878,1117,1862,}, + {1366,2277,1329,2214,1346,2243,1318,2196,1303,2172,1309,2181,1294,2156,1282,2136,1292,2153,1262,2103,1263,2105,1249,2082,1201,2002,1195,1992,1192,1986,1171,1952,1175,1959,1162,1937,1148,1914,1155,1925,1169,1948,1168,1946,1166,1943,1134,1890,1128,1879,}, + {1366,2276,1331,2218,1339,2232,1333,2222,1299,2165,1296,2161,1285,2141,1268,2113,1283,2138,1261,2102,1257,2094,1247,2078,1208,2013,1202,2004,1221,2036,1178,1963,1176,1960,1163,1938,1167,1945,1192,1986,1152,1921,1141,1901,1147,1911,1133,1889,1124,1873,}, + {1367,2278,1331,2218,1339,2231,1325,2209,1291,2152,1292,2154,1273,2122,1268,2114,1281,2135,1251,2085,1253,2089,1244,2074,1210,2017,1208,2013,1236,2059,1191,1985,1184,1973,1175,1959,1172,1954,1188,1980,1160,1933,1146,1910,1156,1927,1135,1892,1128,1881,}, + {1355,2258,1334,2223,1338,2230,1309,2182,1280,2134,1285,2142,1267,2112,1264,2108,1266,2109,1240,2066,1248,2081,1232,2052,1211,2017,1212,2020,1244,2073,1197,1995,1193,1988,1184,1973,1190,1984,1215,2025,1163,1938,1151,1918,1156,1926,1136,1892,1135,1891,}, + {1330,2217,1317,2194,1311,2185,1303,2171,1287,2145,1287,2146,1263,2106,1259,2099,1263,2105,1238,2064,1243,2071,1225,2040,1209,2015,1232,2053,1214,2023,1214,2023,1219,2030,1228,2046,1170,1950,1179,1966,1172,1954,1159,1932,1159,1932,1138,1896,1148,1913,}, + {1318,2197,1316,2194,1306,2177,1300,2166,1286,2143,1294,2157,1261,2102,1256,2094,1266,2110,1227,2045,1228,2046,1219,2032,1211,2019,1250,2083,1217,2028,1214,2023,1206,2010,1197,1995,1176,1960,1186,1976,1180,1966,1165,1941,1169,1948,1156,1927,1157,1928,}, + {1307,2178,1297,2162,1299,2164,1292,2153,1279,2131,1281,2135,1260,2100,1252,2086,1251,2084,1218,2030,1221,2033,1212,2019,1213,2022,1220,2033,1218,2030,1198,1996,1207,2010,1198,1997,1183,1972,1190,1984,1187,1978,1170,1950,1179,1966,1177,1962,1165,1942,}, + {1302,2170,1299,2165,1304,2173,1290,2150,1282,2137,1277,2128,1258,2097,1255,2092,1257,2095,1223,2038,1225,2042,1213,2022,1228,2046,1268,2113,1229,2049,1227,2045,1223,2038,1209,2015,1196,1994,1199,1999,1197,1995,1182,1969,1193,1989,1192,1987,1173,1954,}, + {1296,2160,1287,2145,1298,2163,1291,2152,1275,2125,1273,2121,1259,2099,1253,2088,1249,2081,1224,2040,1225,2042,1213,2020,1255,2091,1255,2091,1243,2071,1229,2048,1236,2059,1221,2036,1211,2019,1213,2022,1205,2007,1199,1998,1210,2016,1200,2000,1177,1961,}, + {1293,2156,1282,2136,1296,2161,1299,2165,1267,2112,1270,2116,1250,2083,1246,2077,1240,2067,1218,2029,1217,2028,1206,2009,1298,2163,1334,2224,1261,2101,1247,2079,1259,2099,1244,2074,1239,2066,1238,2063,1224,2040,1220,2033,1231,2052,1222,2036,1214,2023,}, + {1254,2090,1237,2061,1241,2068,1224,2040,1207,2012,1203,2006,1185,1975,1179,1964,1170,1950,1146,1910,1143,1905,1129,1882,1611,2684,1434,2391,1378,2297,1336,2227,1334,2223,1315,2192,1304,2174,1297,2162,1286,2143,1277,2128,1288,2146,1286,2144,1326,2210,}, +}; + + +#define TX_NUM_WINTEK (14) +#define RX_NUM_WINTEK (27) +#define DiagonalUpperLimit_WINTEK (1100) +#define DiagonalLowerLimit_WINTEK (900) + +const int16_t raw_cap_data_wintek_9093[2][TX_NUM_WINTEK][RX_NUM_WINTEK*2] = +{ + //update base line data, 2014/05/08 + //enable cbc + {{1279, 2656, 1221, 2536, 1208, 2509, 1200, 2492, 1194, 2479, 1189, 2469, 1183, 2457, 1179, 2449, 1177, 2444, 1171, 2432, 1169, 2427, 1162, 2413, 1157, 2403, 1566, 3253, 1374, 2854, 1309, 2718, 1289, 2678, 1272, 2642, 1264, 2626, 1255, 2607, 1251, 2598, 1248, 2592, 1246, 2588, 1245, 2587, 1248, 2592, 1331, 2764, 1357, 2818,}, + {1199, 2491, 1189, 2469, 1184, 2458, 1178, 2448, 1174, 2438, 1169, 2429, 1165, 2420, 1161, 2412, 1159, 2408, 1153, 2395, 1151, 2391, 1145, 2378, 1140, 2367, 1200, 2492, 1173, 2436, 1161, 2411, 1157, 2404, 1150, 2388, 1148, 2383, 1143, 2373, 1141, 2369, 1140, 2367, 1147, 2383, 1139, 2366, 1143, 2373, 1225, 2544, 1379, 2863,}, + {1196, 2483, 1188, 2468, 1182, 2455, 1177, 2445, 1173, 2436, 1168, 2426, 1164, 2418, 1161, 2411, 1159, 2406, 1153, 2394, 1151, 2390, 1144, 2376, 1139, 2365, 1180, 2451, 1161, 2412, 1151, 2391, 1149, 2387, 1142, 2372, 1140, 2368, 1136, 2359, 1134, 2355, 1133, 2354, 1133, 2353, 1134, 2355, 1138, 2363, 1219, 2531, 1292, 2684,}, + {1192, 2475, 1187, 2465, 1181, 2453, 1176, 2443, 1172, 2433, 1168, 2425, 1164, 2417, 1161, 2410, 1158, 2406, 1161, 2412, 1150, 2389, 1144, 2376, 1138, 2364, 1168, 2427, 1155, 2399, 1146, 2379, 1144, 2376, 1137, 2362, 1135, 2357, 1130, 2347, 1127, 2342, 1126, 2340, 1126, 2339, 1127, 2341, 1131, 2350, 1213, 2518, 1345, 2794,}, + {1194, 2480, 1188, 2468, 1182, 2455, 1177, 2444, 1173, 2436, 1169, 2427, 1166, 2421, 1163, 2415, 1159, 2408, 1154, 2396, 1152, 2392, 1145, 2378, 1140, 2367, 1155, 2399, 1146, 2380, 1148, 2384, 1138, 2363, 1132, 2352, 1131, 2349, 1126, 2340, 1124, 2335, 1123, 2332, 1123, 2332, 1124, 2334, 1129, 2344, 1211, 2515, 1313, 2726,}, + {1202, 2497, 1193, 2477, 1186, 2463, 1181, 2452, 1187, 2466, 1174, 2439, 1170, 2431, 1166, 2422, 1163, 2416, 1157, 2402, 1154, 2397, 1148, 2384, 1143, 2374, 1154, 2397, 1145, 2379, 1138, 2364, 1137, 2361, 1131, 2348, 1129, 2345, 1125, 2338, 1123, 2333, 1122, 2329, 1121, 2328, 1122, 2330, 1127, 2340, 1211, 2516, 1308, 2716,}, + {1204, 2500, 1192, 2476, 1185, 2461, 1180, 2451, 1177, 2444, 1174, 2438, 1169, 2428, 1165, 2420, 1162, 2414, 1155, 2399, 1153, 2394, 1147, 2383, 1143, 2374, 1151, 2391, 1142, 2372, 1135, 2357, 1134, 2355, 1136, 2360, 1127, 2340, 1122, 2330, 1120, 2325, 1118, 2323, 1117, 2320, 1118, 2323, 1123, 2332, 1204, 2501, 1309, 2718,}, + {1205, 2503, 1191, 2474, 1184, 2459, 1178, 2448, 1177, 2445, 1172, 2434, 1168, 2425, 1163, 2416, 1161, 2411, 1154, 2396, 1152, 2392, 1146, 2380, 1141, 2370, 1147, 2383, 1139, 2365, 1132, 2350, 1130, 2348, 1124, 2335, 1122, 2331, 1118, 2322, 1116, 2317, 1114, 2314, 1112, 2310, 1122, 2331, 1118, 2321, 1199, 2490, 1283, 2666,}, + {1210, 2513, 1193, 2477, 1185, 2461, 1179, 2448, 1175, 2441, 1171, 2433, 1167, 2425, 1163, 2416, 1160, 2410, 1153, 2395, 1152, 2392, 1145, 2379, 1141, 2370, 1145, 2378, 1136, 2359, 1128, 2344, 1127, 2341, 1121, 2328, 1119, 2325, 1114, 2315, 1112, 2311, 1111, 2307, 1109, 2304, 1111, 2307, 1123, 2333, 1196, 2485, 1284, 2667,}, + {1220, 2534, 1197, 2487, 1206, 2506, 1183, 2457, 1203, 2498, 1173, 2437, 1169, 2428, 1165, 2420, 1163, 2415, 1156, 2401, 1154, 2396, 1148, 2385, 1143, 2375, 1146, 2379, 1144, 2376, 1128, 2344, 1127, 2342, 1121, 2329, 1119, 2325, 1114, 2314, 1112, 2309, 1110, 2306, 1109, 2303, 1110, 2305, 1114, 2313, 1195, 2481, 1286, 2671,}, + {1227, 2548, 1201, 2495, 1192, 2475, 1185, 2461, 1179, 2448, 1173, 2437, 1169, 2428, 1165, 2420, 1162, 2413, 1155, 2400, 1154, 2396, 1148, 2384, 1143, 2374, 1152, 2392, 1133, 2353, 1125, 2336, 1124, 2334, 1118, 2321, 1116, 2317, 1111, 2307, 1108, 2301, 1107, 2300, 1106, 2297, 1107, 2299, 1111, 2307, 1191, 2473, 1335, 2773,}, + {1238, 2570, 1205, 2503, 1194, 2480, 1185, 2461, 1182, 2455, 1172, 2435, 1167, 2424, 1163, 2415, 1160, 2408, 1153, 2394, 1151, 2390, 1145, 2378, 1141, 2370, 1140, 2367, 1128, 2342, 1120, 2326, 1119, 2324, 1113, 2311, 1111, 2306, 1106, 2296, 1112, 2310, 1103, 2291, 1102, 2288, 1103, 2291, 1106, 2297, 1185, 2461, 1254, 2604,}, + {1271, 2640, 1223, 2540, 1209, 2511, 1198, 2489, 1191, 2473, 1185, 2460, 1178, 2448, 1174, 2438, 1171, 2432, 1164, 2417, 1161, 2412, 1157, 2403, 1153, 2395, 1153, 2395, 1136, 2360, 1127, 2341, 1126, 2338, 1120, 2326, 1126, 2339, 1113, 2311, 1111, 2307, 1110, 2306, 1109, 2303, 1110, 2305, 1112, 2309, 1192, 2475, 1212, 2518,}, + {1459, 3029, 1363, 2830, 1312, 2724, 1308, 2716, 1289, 2677, 1271, 2641, 1261, 2619, 1258, 2612, 1255, 2607, 1251, 2598, 1252, 2600, 1256, 2609, 1266, 2629, 1259, 2615, 1179, 2448, 1156, 2402, 1151, 2391, 1142, 2372, 1138, 2363, 1132, 2352, 1130, 2347, 1128, 2343, 1127, 2340, 1126, 2339, 1126, 2339, 1206, 2504, 1194, 2479,}, + }, + + //disable cbc + {{1454, 2584, 1388, 2467, 1373, 2441, 1365, 2427, 1358, 2415, 1353, 2405, 1349, 2398, 1342, 2387, 1337, 2377, 1334, 2371, 1328, 2362, 1324, 2354, 1319, 2345, 1771, 3149, 1557, 2768, 1487, 2643, 1461, 2598, 1445, 2569, 1434, 2550, 1427, 2536, 1422, 2528, 1418, 2520, 1415, 2516, 1415, 2515, 1419, 2523, 1511, 2686, 1540, 2738,}, + {1363, 2422, 1348, 2397, 1343, 2387, 1337, 2378, 1333, 2369, 1327, 2360, 1324, 2354, 1318, 2344, 1314, 2335, 1309, 2328, 1305, 2321, 1301, 2313, 1295, 2302, 1361, 2420, 1330, 2365, 1318, 2343, 1311, 2331, 1305, 2320, 1301, 2312, 1297, 2306, 1295, 2303, 1293, 2299, 1302, 2314, 1293, 2299, 1298, 2307, 1388, 2468, 1560, 2772,}, + {1360, 2418, 1350, 2399, 1343, 2387, 1338, 2379, 1334, 2371, 1329, 2362, 1325, 2356, 1320, 2347, 1316, 2339, 1312, 2332, 1308, 2324, 1303, 2316, 1297, 2306, 1343, 2388, 1320, 2347, 1311, 2330, 1305, 2319, 1299, 2310, 1295, 2302, 1292, 2297, 1290, 2294, 1289, 2291, 1288, 2290, 1289, 2291, 1293, 2299, 1384, 2460, 1465, 2604,}, + {1357, 2413, 1350, 2400, 1342, 2386, 1339, 2380, 1334, 2371, 1329, 2362, 1326, 2358, 1322, 2350, 1316, 2340, 1323, 2351, 1308, 2326, 1304, 2319, 1298, 2308, 1331, 2366, 1314, 2336, 1306, 2322, 1300, 2312, 1295, 2302, 1291, 2296, 1287, 2288, 1285, 2284, 1283, 2280, 1282, 2279, 1283, 2281, 1288, 2290, 1379, 2451, 1526, 2713,}, + {1359, 2416, 1351, 2401, 1343, 2388, 1339, 2381, 1335, 2373, 1330, 2365, 1328, 2361, 1323, 2352, 1318, 2343, 1314, 2336, 1309, 2326, 1305, 2320, 1299, 2309, 1316, 2339, 1304, 2319, 1308, 2325, 1294, 2300, 1289, 2291, 1285, 2285, 1282, 2279, 1279, 2274, 1278, 2272, 1277, 2270, 1279, 2273, 1285, 2284, 1376, 2446, 1490, 2648,}, + {1367, 2430, 1355, 2408, 1348, 2396, 1343, 2387, 1350, 2401, 1336, 2376, 1332, 2369, 1327, 2359, 1322, 2350, 1317, 2342, 1312, 2332, 1308, 2325, 1302, 2315, 1316, 2339, 1304, 2318, 1297, 2306, 1292, 2297, 1287, 2288, 1284, 2282, 1282, 2280, 1279, 2275, 1277, 2270, 1276, 2269, 1276, 2269, 1284, 2282, 1377, 2448, 1484, 2638,}, + {1365, 2426, 1350, 2399, 1341, 2385, 1336, 2376, 1333, 2369, 1329, 2363, 1325, 2355, 1320, 2346, 1314, 2337, 1309, 2328, 1304, 2318, 1301, 2313, 1296, 2304, 1304, 2319, 1293, 2298, 1287, 2287, 1282, 2278, 1286, 2287, 1275, 2266, 1272, 2261, 1269, 2257, 1267, 2252, 1265, 2249, 1267, 2252, 1272, 2262, 1363, 2424, 1481, 2632,}, + {1368, 2433, 1350, 2401, 1342, 2386, 1337, 2376, 1335, 2373, 1329, 2363, 1325, 2356, 1319, 2345, 1313, 2334, 1308, 2326, 1304, 2318, 1300, 2312, 1295, 2303, 1301, 2312, 1290, 2293, 1283, 2282, 1279, 2273, 1274, 2265, 1272, 2261, 1268, 2255, 1265, 2249, 1263, 2245, 1261, 2241, 1272, 2261, 1268, 2254, 1359, 2416, 1454, 2585,}, + {1376, 2445, 1354, 2408, 1345, 2391, 1339, 2380, 1335, 2372, 1331, 2366, 1327, 2359, 1321, 2349, 1316, 2339, 1311, 2331, 1306, 2322, 1302, 2314, 1297, 2306, 1301, 2313, 1289, 2292, 1283, 2281, 1279, 2273, 1274, 2265, 1271, 2259, 1267, 2253, 1264, 2247, 1262, 2244, 1261, 2241, 1261, 2242, 1276, 2269, 1358, 2415, 1456, 2588,}, + {1385, 2463, 1358, 2414, 1367, 2430, 1342, 2385, 1364, 2424, 1331, 2366, 1327, 2358, 1321, 2349, 1316, 2339, 1312, 2332, 1307, 2323, 1304, 2318, 1299, 2309, 1300, 2311, 1297, 2305, 1281, 2278, 1277, 2270, 1273, 2263, 1269, 2256, 1266, 2250, 1262, 2244, 1259, 2239, 1258, 2237, 1260, 2239, 1265, 2249, 1355, 2409, 1457, 2590,}, + {1394, 2478, 1363, 2423, 1352, 2404, 1346, 2392, 1339, 2381, 1333, 2370, 1330, 2364, 1323, 2352, 1318, 2343, 1313, 2334, 1308, 2326, 1305, 2319, 1299, 2310, 1310, 2328, 1286, 2287, 1280, 2275, 1275, 2267, 1270, 2258, 1267, 2252, 1263, 2245, 1260, 2239, 1257, 2235, 1256, 2233, 1257, 2235, 1262, 2244, 1351, 2402, 1512, 2687,}, + {1409, 2505, 1370, 2436, 1358, 2415, 1349, 2399, 1346, 2393, 1337, 2376, 1331, 2367, 1325, 2355, 1320, 2347, 1315, 2338, 1310, 2329, 1307, 2324, 1303, 2316, 1301, 2312, 1286, 2286, 1279, 2274, 1274, 2265, 1270, 2258, 1266, 2251, 1263, 2245, 1270, 2258, 1259, 2238, 1258, 2237, 1259, 2238, 1263, 2246, 1352, 2403, 1428, 2539,}, + {1441, 2562, 1386, 2465, 1370, 2435, 1359, 2417, 1351, 2401, 1344, 2389, 1338, 2378, 1331, 2367, 1326, 2357, 1321, 2348, 1316, 2340, 1314, 2335, 1310, 2329, 1309, 2328, 1289, 2291, 1281, 2278, 1276, 2269, 1271, 2260, 1277, 2270, 1265, 2248, 1262, 2243, 1260, 2241, 1259, 2239, 1259, 2238, 1263, 2246, 1352, 2404, 1375, 2444,}, + {1652, 2937, 1544, 2745, 1487, 2644, 1484, 2638, 1464, 2602, 1445, 2568, 1433, 2548, 1429, 2540, 1424, 2532, 1422, 2528, 1420, 2525, 1428, 2538, 1438, 2557, 1431, 2544, 1341, 2384, 1318, 2342, 1309, 2327, 1300, 2311, 1294, 2301, 1291, 2294, 1287, 2288, 1285, 2284, 1283, 2280, 1282, 2279, 1283, 2280, 1371, 2437, 1359, 2415,}, + }, +}; + +#define TX_NUM_WINTEK_N3 15 +#define RX_NUM_WINTEK_N3 28 + +const int16_t raw_cap_data_wintek_N3[2][TX_NUM_WINTEK_N3][RX_NUM_WINTEK_N3*2] = +{ + //update base line data, 2014/07/15 + //enable cbc + { + {1118, 2077, 1150, 2137, 1169, 2170, 1136, 2110, 1147, 2130, 1159, 2152, 1171, 2174, 1164, 2162, 1174, 2179, 1157, 2149, 1179, 2190, 1170, 2173, 1198, 2224, 1293, 2401, 1264, 2347, 1282, 2382, 1277, 2372, 1284, 2385, 1275, 2368, 1279, 2375, 1285, 2386, 1273, 2365, 1290, 2396, 1292, 2400, 1350, 2507, -2, -3, -1, -2, 9, 17,}, + {1159, 2152, 1193, 2216, 1211, 2250, 1188, 2205, 1187, 2204, 1199, 2226, 1210, 2248, 1204, 2235, 1211, 2248, 1196, 2222, 1218, 2263, 1209, 2245, 1237, 2296, 1233, 2290, 1230, 2283, 1254, 2330, 1251, 2323, 1266, 2352, 1254, 2328, 1262, 2345, 1266, 2352, 1260, 2339, 1274, 2367, 1281, 2380, 1319, 2450, -1, -1, -5, -9, -2, -5,}, + {1170, 2172, 1199, 2227, 1221, 2267, 1188, 2205, 1194, 2218, 1201, 2231, 1213, 2254, 1213, 2253, 1230, 2283, 1209, 2245, 1225, 2275, 1218, 2261, 1246, 2313, 1236, 2296, 1232, 2287, 1256, 2333, 1250, 2322, 1266, 2352, 1258, 2335, 1266, 2351, 1269, 2356, 1260, 2341, 1276, 2371, 1279, 2375, 1311, 2436, 1, 1, -3, -5, 0, -1,}, + {1176, 2185, 1209, 2245, 1227, 2278, 1191, 2212, 1200, 2229, 1223, 2270, 1223, 2270, 1220, 2267, 1228, 2280, 1212, 2250, 1231, 2286, 1223, 2271, 1249, 2320, 1239, 2301, 1240, 2302, 1262, 2343, 1256, 2333, 1267, 2354, 1259, 2338, 1267, 2352, 1267, 2354, 1259, 2338, 1271, 2361, 1275, 2367, 1304, 2423, -1, -1, -5, -9, -2, -5,}, + {1170, 2172, 1208, 2243, 1224, 2274, 1185, 2201, 1195, 2220, 1205, 2239, 1218, 2262, 1217, 2259, 1222, 2269, 1206, 2239, 1225, 2274, 1212, 2252, 1240, 2304, 1233, 2291, 1228, 2281, 1252, 2326, 1251, 2324, 1259, 2339, 1249, 2319, 1255, 2330, 1261, 2342, 1250, 2321, 1264, 2348, 1266, 2351, 1296, 2406, -1, -1, -2, -5, -3, -6,}, + {1176, 2185, 1210, 2247, 1231, 2285, 1195, 2219, 1214, 2254, 1216, 2258, 1227, 2278, 1223, 2272, 1228, 2280, 1215, 2256, 1233, 2290, 1223, 2271, 1247, 2316, 1237, 2296, 1233, 2290, 1255, 2332, 1250, 2322, 1263, 2345, 1254, 2329, 1260, 2341, 1264, 2347, 1253, 2327, 1262, 2344, 1268, 2355, 1286, 2388, -1, -2, -4, -7, -4, -7,}, + {1174, 2179, 1219, 2263, 1229, 2283, 1193, 2216, 1202, 2231, 1215, 2257, 1227, 2280, 1222, 2269, 1228, 2280, 1216, 2257, 1233, 2290, 1222, 2269, 1245, 2313, 1225, 2275, 1226, 2276, 1252, 2326, 1244, 2311, 1259, 2338, 1248, 2317, 1254, 2329, 1256, 2333, 1247, 2316, 1259, 2339, 1260, 2341, 1283, 2384, 1, 3, -2, -4, -3, -6,}, + {1188, 2207, 1220, 2265, 1248, 2317, 1205, 2238, 1216, 2257, 1228, 2280, 1241, 2304, 1237, 2298, 1243, 2308, 1225, 2276, 1246, 2315, 1237, 2296, 1261, 2341, 1238, 2300, 1236, 2296, 1261, 2342, 1257, 2335, 1267, 2352, 1255, 2332, 1261, 2343, 1263, 2345, 1253, 2327, 1261, 2342, 1265, 2349, 1282, 2380, -1, -3, -3, -5, -1, -2,}, + {1188, 2207, 1224, 2272, 1237, 2298, 1208, 2243, 1213, 2254, 1226, 2278, 1240, 2303, 1236, 2296, 1241, 2305, 1225, 2275, 1241, 2306, 1232, 2289, 1261, 2341, 1236, 2295, 1233, 2291, 1261, 2342, 1252, 2325, 1263, 2346, 1253, 2328, 1258, 2336, 1261, 2343, 1248, 2319, 1263, 2346, 1261, 2343, 1277, 2371, -1, -3, 5, 8, -5, -8,}, + {1190, 2211, 1222, 2269, 1240, 2303, 1209, 2246, 1216, 2259, 1227, 2280, 1242, 2307, 1237, 2296, 1245, 2313, 1232, 2289, 1249, 2320, 1237, 2297, 1264, 2347, 1239, 2302, 1238, 2300, 1261, 2341, 1256, 2332, 1267, 2354, 1256, 2333, 1258, 2336, 1265, 2348, 1254, 2328, 1264, 2347, 1260, 2341, 1275, 2368, -2, -3, -4, -8, -3, -6,}, + {1193, 2216, 1218, 2262, 1234, 2291, 1201, 2230, 1210, 2246, 1219, 2264, 1232, 2287, 1227, 2279, 1236, 2295, 1224, 2273, 1241, 2304, 1230, 2284, 1257, 2334, 1228, 2280, 1223, 2271, 1252, 2325, 1246, 2314, 1257, 2334, 1245, 2312, 1250, 2321, 1253, 2326, 1243, 2309, 1257, 2334, 1258, 2335, 1267, 2354, 0, -1, -3, -5, -1, -2,}, + {1205, 2239, 1240, 2303, 1260, 2339, 1222, 2269, 1236, 2296, 1245, 2312, 1255, 2331, 1252, 2326, 1257, 2334, 1247, 2317, 1267, 2352, 1257, 2334, 1295, 2405, 1245, 2312, 1243, 2309, 1265, 2349, 1258, 2336, 1269, 2357, 1260, 2339, 1265, 2348, 1265, 2348, 1254, 2329, 1268, 2355, 1273, 2363, 1272, 2362, -2, -4, -7, -13, -4, -7,}, + {1189, 2208, 1224, 2272, 1240, 2302, 1210, 2246, 1219, 2263, 1229, 2283, 1238, 2299, 1238, 2298, 1240, 2303, 1229, 2283, 1249, 2320, 1238, 2298, 1271, 2360, 1225, 2276, 1223, 2270, 1246, 2315, 1239, 2302, 1256, 2333, 1245, 2311, 1247, 2316, 1252, 2326, 1238, 2300, 1258, 2335, 1247, 2317, 1257, 2335, 0, 0, -2, -3, -2, -5,}, + {1294, 2403, 1299, 2412, 1313, 2438, 1280, 2376, 1292, 2399, 1298, 2411, 1311, 2435, 1311, 2434, 1316, 2445, 1309, 2430, 1336, 2481, 1343, 2495, 1462, 2714, 1196, 2220, 1193, 2216, 1218, 2262, 1213, 2252, 1224, 2272, 1212, 2251, 1216, 2259, 1221, 2267, 1214, 2254, 1221, 2268, 1222, 2269, 1232, 2289, 11, 21, -1, -3, -5, -8,}, + {-22, -41, -11, -20, 4, 7, -31, -58, -24, -45, -15, -28, -5, -10, -9, -17, -5, -10, -20, -38, -2, -4, -10, -18, 23, 42, -11, -21, -18, -33, 0, 0, -5, -10, 10, 18, -11, -20, -7, -14, -8, -16, -19, -36, -13, -25, -21, -38, -19, -35, 1120, 2081, 958, 1779, 856, 1590,}, + }, + + //disable cbc + { + {1118, 2077, 1150, 2137, 1169, 2170, 1136, 2110, 1147, 2130, 1159, 2152, 1171, 2174, 1164, 2162, 1174, 2179, 1157, 2149, 1179, 2190, 1170, 2173, 1198, 2224, 1293, 2401, 1264, 2347, 1282, 2382, 1277, 2372, 1284, 2385, 1275, 2368, 1279, 2375, 1285, 2386, 1273, 2365, 1290, 2396, 1292, 2400, 1350, 2507, -2, -3, -1, -2, 9, 17,}, + {1159, 2152, 1193, 2216, 1211, 2250, 1188, 2205, 1187, 2204, 1199, 2226, 1210, 2248, 1204, 2235, 1211, 2248, 1196, 2222, 1218, 2263, 1209, 2245, 1237, 2296, 1233, 2290, 1230, 2283, 1254, 2330, 1251, 2323, 1266, 2352, 1254, 2328, 1262, 2345, 1266, 2352, 1260, 2339, 1274, 2367, 1281, 2380, 1319, 2450, -1, -1, -5, -9, -2, -5,}, + {1170, 2172, 1199, 2227, 1221, 2267, 1188, 2205, 1194, 2218, 1201, 2231, 1213, 2254, 1213, 2253, 1230, 2283, 1209, 2245, 1225, 2275, 1218, 2261, 1246, 2313, 1236, 2296, 1232, 2287, 1256, 2333, 1250, 2322, 1266, 2352, 1258, 2335, 1266, 2351, 1269, 2356, 1260, 2341, 1276, 2371, 1279, 2375, 1311, 2436, 1, 1, -3, -5, 0, -1,}, + {1176, 2185, 1209, 2245, 1227, 2278, 1191, 2212, 1200, 2229, 1223, 2270, 1223, 2270, 1220, 2267, 1228, 2280, 1212, 2250, 1231, 2286, 1223, 2271, 1249, 2320, 1239, 2301, 1240, 2302, 1262, 2343, 1256, 2333, 1267, 2354, 1259, 2338, 1267, 2352, 1267, 2354, 1259, 2338, 1271, 2361, 1275, 2367, 1304, 2423, -1, -1, -5, -9, -2, -5,}, + {1170, 2172, 1208, 2243, 1224, 2274, 1185, 2201, 1195, 2220, 1205, 2239, 1218, 2262, 1217, 2259, 1222, 2269, 1206, 2239, 1225, 2274, 1212, 2252, 1240, 2304, 1233, 2291, 1228, 2281, 1252, 2326, 1251, 2324, 1259, 2339, 1249, 2319, 1255, 2330, 1261, 2342, 1250, 2321, 1264, 2348, 1266, 2351, 1296, 2406, -1, -1, -2, -5, -3, -6,}, + {1176, 2185, 1210, 2247, 1231, 2285, 1195, 2219, 1214, 2254, 1216, 2258, 1227, 2278, 1223, 2272, 1228, 2280, 1215, 2256, 1233, 2290, 1223, 2271, 1247, 2316, 1237, 2296, 1233, 2290, 1255, 2332, 1250, 2322, 1263, 2345, 1254, 2329, 1260, 2341, 1264, 2347, 1253, 2327, 1262, 2344, 1268, 2355, 1286, 2388, -1, -2, -4, -7, -4, -7,}, + {1174, 2179, 1219, 2263, 1229, 2283, 1193, 2216, 1202, 2231, 1215, 2257, 1227, 2280, 1222, 2269, 1228, 2280, 1216, 2257, 1233, 2290, 1222, 2269, 1245, 2313, 1225, 2275, 1226, 2276, 1252, 2326, 1244, 2311, 1259, 2338, 1248, 2317, 1254, 2329, 1256, 2333, 1247, 2316, 1259, 2339, 1260, 2341, 1283, 2384, 1, 3, -2, -4, -3, -6,}, + {1188, 2207, 1220, 2265, 1248, 2317, 1205, 2238, 1216, 2257, 1228, 2280, 1241, 2304, 1237, 2298, 1243, 2308, 1225, 2276, 1246, 2315, 1237, 2296, 1261, 2341, 1238, 2300, 1236, 2296, 1261, 2342, 1257, 2335, 1267, 2352, 1255, 2332, 1261, 2343, 1263, 2345, 1253, 2327, 1261, 2342, 1265, 2349, 1282, 2380, -1, -3, -3, -5, -1, -2,}, + {1188, 2207, 1224, 2272, 1237, 2298, 1208, 2243, 1213, 2254, 1226, 2278, 1240, 2303, 1236, 2296, 1241, 2305, 1225, 2275, 1241, 2306, 1232, 2289, 1261, 2341, 1236, 2295, 1233, 2291, 1261, 2342, 1252, 2325, 1263, 2346, 1253, 2328, 1258, 2336, 1261, 2343, 1248, 2319, 1263, 2346, 1261, 2343, 1277, 2371, -1, -3, 5, 8, -5, -8,}, + {1190, 2211, 1222, 2269, 1240, 2303, 1209, 2246, 1216, 2259, 1227, 2280, 1242, 2307, 1237, 2296, 1245, 2313, 1232, 2289, 1249, 2320, 1237, 2297, 1264, 2347, 1239, 2302, 1238, 2300, 1261, 2341, 1256, 2332, 1267, 2354, 1256, 2333, 1258, 2336, 1265, 2348, 1254, 2328, 1264, 2347, 1260, 2341, 1275, 2368, -2, -3, -4, -8, -3, -6,}, + {1193, 2216, 1218, 2262, 1234, 2291, 1201, 2230, 1210, 2246, 1219, 2264, 1232, 2287, 1227, 2279, 1236, 2295, 1224, 2273, 1241, 2304, 1230, 2284, 1257, 2334, 1228, 2280, 1223, 2271, 1252, 2325, 1246, 2314, 1257, 2334, 1245, 2312, 1250, 2321, 1253, 2326, 1243, 2309, 1257, 2334, 1258, 2335, 1267, 2354, 0, -1, -3, -5, -1, -2,}, + {1205, 2239, 1240, 2303, 1260, 2339, 1222, 2269, 1236, 2296, 1245, 2312, 1255, 2331, 1252, 2326, 1257, 2334, 1247, 2317, 1267, 2352, 1257, 2334, 1295, 2405, 1245, 2312, 1243, 2309, 1265, 2349, 1258, 2336, 1269, 2357, 1260, 2339, 1265, 2348, 1265, 2348, 1254, 2329, 1268, 2355, 1273, 2363, 1272, 2362, -2, -4, -7, -13, -4, -7,}, + {1189, 2208, 1224, 2272, 1240, 2302, 1210, 2246, 1219, 2263, 1229, 2283, 1238, 2299, 1238, 2298, 1240, 2303, 1229, 2283, 1249, 2320, 1238, 2298, 1271, 2360, 1225, 2276, 1223, 2270, 1246, 2315, 1239, 2302, 1256, 2333, 1245, 2311, 1247, 2316, 1252, 2326, 1238, 2300, 1258, 2335, 1247, 2317, 1257, 2335, 0, 0, -2, -3, -2, -5,}, + {1294, 2403, 1299, 2412, 1313, 2438, 1280, 2376, 1292, 2399, 1298, 2411, 1311, 2435, 1311, 2434, 1316, 2445, 1309, 2430, 1336, 2481, 1343, 2495, 1462, 2714, 1196, 2220, 1193, 2216, 1218, 2262, 1213, 2252, 1224, 2272, 1212, 2251, 1216, 2259, 1221, 2267, 1214, 2254, 1221, 2268, 1222, 2269, 1232, 2289, 11, 21, -1, -3, -5, -8,}, + {-22, -41, -11, -20, 4, 7, -31, -58, -24, -45, -15, -28, -5, -10, -9, -17, -5, -10, -20, -38, -2, -4, -10, -18, 23, 42, -11, -21, -18, -33, 0, 0, -5, -10, 10, 18, -11, -20, -7, -14, -8, -16, -19, -36, -13, -25, -21, -38, -19, -35, 1120, 2081, 958, 1779, 856, 1590,}, + }, +}; + +#define TX_NUM_TPK_N3 15 +#define RX_NUM_TPK_N3 28 + +const int16_t raw_cap_data_tpk_N3[2][TX_NUM_TPK_N3][RX_NUM_TPK_N3*2] = +{ + //update base line data, 2014/07/15 + //enable cbc + { + {960, 1782, 948, 1760, 939, 1745, 955, 1773, 967, 1797, 970, 1802, 963, 1789, 971, 1803, 977, 1815, 968, 1798, 973, 1807, 984, 1828, 1099, 2041, 1089, 2023, 1089, 2023, 1081, 2007, 1077, 2001, 1086, 2016, 1089, 2023, 1091, 2025, 1081, 2007, 1074, 1994, 1072, 1990, 1067, 1981, 1075, 1997, 145, 269, 169, 313, 190, 352,}, + {990, 1838, 982, 1824, 969, 1799, 984, 1827, 996, 1850, 997, 1851, 993, 1845, 1002, 1860, 995, 1849, 995, 1847, 998, 1854, 1009, 1875, 1039, 1929, 1036, 1924, 1037, 1925, 1033, 1918, 1031, 1915, 1042, 1934, 1050, 1950, 1051, 1951, 1049, 1949, 1050, 1950, 1058, 1964, 1062, 1972, 1073, 1993, 141, 261, 168, 312, 188, 350,}, + {991, 1841, 982, 1824, 970, 1801, 984, 1827, 995, 1849, 1000, 1858, 995, 1847, 1002, 1862, 994, 1846, 993, 1845, 1006, 1868, 1008, 1872, 1027, 1907, 1032, 1916, 1037, 1927, 1028, 1910, 1025, 1903, 1039, 1929, 1042, 1936, 1047, 1945, 1042, 1936, 1040, 1932, 1051, 1951, 1056, 1962, 1070, 1986, 138, 256, 167, 311, 190, 352,}, + {1002, 1860, 988, 1836, 977, 1815, 988, 1834, 1002, 1862, 1003, 1863, 1000, 1856, 1005, 1867, 998, 1853, 998, 1853, 1002, 1860, 1024, 1902, 1031, 1915, 1036, 1924, 1041, 1933, 1033, 1919, 1028, 1908, 1040, 1931, 1047, 1945, 1052, 1954, 1047, 1945, 1045, 1941, 1053, 1955, 1055, 1959, 1066, 1980, 139, 257, 168, 312, 188, 348,}, + {1006, 1868, 998, 1854, 988, 1834, 997, 1851, 1014, 1882, 1016, 1886, 1011, 1877, 1016, 1888, 1013, 1881, 1010, 1876, 1015, 1885, 1035, 1923, 1040, 1932, 1044, 1940, 1048, 1946, 1040, 1931, 1038, 1928, 1049, 1949, 1058, 1966, 1058, 1964, 1056, 1962, 1054, 1957, 1061, 1971, 1061, 1970, 1074, 1994, 141, 263, 167, 311, 190, 352,}, + {991, 1841, 984, 1828, 974, 1808, 985, 1829, 996, 1850, 996, 1850, 995, 1847, 1004, 1864, 995, 1849, 998, 1854, 1002, 1862, 1009, 1875, 1022, 1898, 1026, 1906, 1028, 1910, 1021, 1897, 1018, 1890, 1031, 1915, 1038, 1928, 1040, 1932, 1040, 1932, 1043, 1937, 1052, 1954, 1056, 1960, 1068, 1983, 141, 263, 165, 306, 189, 351,}, + {1011, 1877, 1009, 1873, 993, 1845, 1007, 1871, 1016, 1888, 1018, 1890, 1013, 1881, 1022, 1898, 1013, 1881, 1014, 1882, 1019, 1893, 1030, 1912, 1040, 1931, 1055, 1959, 1046, 1942, 1037, 1927, 1033, 1919, 1046, 1942, 1053, 1955, 1057, 1963, 1052, 1954, 1050, 1950, 1058, 1966, 1061, 1971, 1075, 1996, 141, 261, 165, 307, 190, 352,}, + {1012, 1880, 1009, 1873, 999, 1855, 1012, 1879, 1019, 1893, 1023, 1899, 1019, 1892, 1028, 1910, 1022, 1898, 1021, 1895, 1023, 1901, 1040, 1932, 1042, 1936, 1049, 1947, 1051, 1951, 1043, 1937, 1042, 1934, 1050, 1950, 1057, 1963, 1058, 1964, 1053, 1955, 1049, 1947, 1061, 1971, 1064, 1976, 1072, 1990, 144, 267, 165, 307, 189, 351,}, + {1022, 1898, 1018, 1890, 1002, 1862, 1015, 1885, 1027, 1907, 1029, 1911, 1026, 1906, 1035, 1921, 1028, 1910, 1028, 1910, 1030, 1912, 1043, 1937, 1043, 1937, 1048, 1946, 1052, 1954, 1043, 1937, 1040, 1931, 1054, 1957, 1062, 1972, 1063, 1975, 1054, 1958, 1051, 1953, 1060, 1968, 1075, 1997, 1070, 1986, 144, 267, 166, 308, 188, 350,}, + {1021, 1897, 1017, 1889, 1007, 1871, 1014, 1882, 1028, 1908, 1030, 1914, 1026, 1906, 1033, 1919, 1025, 1903, 1021, 1897, 1028, 1910, 1041, 1933, 1044, 1938, 1049, 1949, 1050, 1950, 1042, 1936, 1041, 1933, 1052, 1954, 1060, 1968, 1063, 1975, 1069, 1985, 1051, 1951, 1061, 1970, 1066, 1980, 1069, 1985, 145, 269, 168, 312, 188, 350,}, + {1030, 1912, 1018, 1890, 1005, 1867, 1018, 1890, 1031, 1915, 1030, 1914, 1029, 1911, 1037, 1927, 1028, 1908, 1025, 1903, 1030, 1912, 1041, 1933, 1072, 1992, 1044, 1940, 1051, 1951, 1044, 1940, 1041, 1933, 1052, 1954, 1058, 1966, 1058, 1966, 1053, 1955, 1050, 1950, 1064, 1976, 1066, 1980, 1072, 1990, 146, 270, 166, 308, 185, 343,}, + {1025, 1903, 1017, 1889, 1003, 1863, 1014, 1884, 1028, 1910, 1030, 1914, 1027, 1907, 1033, 1918, 1024, 1902, 1022, 1898, 1027, 1907, 1041, 1933, 1072, 1990, 1041, 1933, 1047, 1945, 1037, 1925, 1035, 1921, 1047, 1945, 1057, 1963, 1055, 1959, 1049, 1947, 1050, 1950, 1071, 1989, 1063, 1973, 1065, 1979, 144, 267, 169, 315, 186, 345,}, + {1039, 1929, 1033, 1918, 1019, 1892, 1026, 1906, 1042, 1934, 1044, 1938, 1037, 1927, 1049, 1947, 1041, 1933, 1041, 1933, 1047, 1945, 1067, 1981, 1047, 1945, 1053, 1955, 1054, 1958, 1051, 1951, 1047, 1944, 1058, 1966, 1060, 1968, 1066, 1980, 1061, 1970, 1062, 1972, 1070, 1986, 1071, 1989, 1075, 1996, 146, 270, 168, 312, 188, 348,}, + {1119, 2079, 1096, 2035, 1086, 2016, 1098, 2038, 1114, 2068, 1121, 2081, 1126, 2090, 1142, 2120, 1149, 2133, 1164, 2162, 1197, 2223, 1296, 2408, 1004, 1864, 1011, 1877, 1016, 1886, 1012, 1879, 1010, 1876, 1019, 1893, 1028, 1910, 1030, 1912, 1026, 1905, 1025, 1903, 1030, 1914, 1035, 1921, 1042, 1934, 145, 269, 169, 315, 188, 348,}, + {184, 342, 176, 328, 172, 319, 186, 345, 186, 345, 181, 335, 176, 328, 181, 337, 178, 330, 171, 317, 230, 428, 180, 334, 181, 337, 182, 338, 186, 345, 174, 324, 171, 317, 176, 326, 183, 339, 180, 334, 174, 324, 172, 319, 181, 335, 175, 325, 165, 306, 1437, 2669, 1355, 2516, 1104, 2050,}, + }, + + //disable cbc + { + {960, 1782, 948, 1760, 939, 1745, 955, 1773, 967, 1797, 970, 1802, 963, 1789, 971, 1803, 977, 1815, 968, 1798, 973, 1807, 984, 1828, 1099, 2041, 1089, 2023, 1089, 2023, 1081, 2007, 1077, 2001, 1086, 2016, 1089, 2023, 1091, 2025, 1081, 2007, 1074, 1994, 1072, 1990, 1067, 1981, 1075, 1997, 145, 269, 169, 313, 190, 352,}, + {990, 1838, 982, 1824, 969, 1799, 984, 1827, 996, 1850, 997, 1851, 993, 1845, 1002, 1860, 995, 1849, 995, 1847, 998, 1854, 1009, 1875, 1039, 1929, 1036, 1924, 1037, 1925, 1033, 1918, 1031, 1915, 1042, 1934, 1050, 1950, 1051, 1951, 1049, 1949, 1050, 1950, 1058, 1964, 1062, 1972, 1073, 1993, 141, 261, 168, 312, 188, 350,}, + {991, 1841, 982, 1824, 970, 1801, 984, 1827, 995, 1849, 1000, 1858, 995, 1847, 1002, 1862, 994, 1846, 993, 1845, 1006, 1868, 1008, 1872, 1027, 1907, 1032, 1916, 1037, 1927, 1028, 1910, 1025, 1903, 1039, 1929, 1042, 1936, 1047, 1945, 1042, 1936, 1040, 1932, 1051, 1951, 1056, 1962, 1070, 1986, 138, 256, 167, 311, 190, 352,}, + {1002, 1860, 988, 1836, 977, 1815, 988, 1834, 1002, 1862, 1003, 1863, 1000, 1856, 1005, 1867, 998, 1853, 998, 1853, 1002, 1860, 1024, 1902, 1031, 1915, 1036, 1924, 1041, 1933, 1033, 1919, 1028, 1908, 1040, 1931, 1047, 1945, 1052, 1954, 1047, 1945, 1045, 1941, 1053, 1955, 1055, 1959, 1066, 1980, 139, 257, 168, 312, 188, 348,}, + {1006, 1868, 998, 1854, 988, 1834, 997, 1851, 1014, 1882, 1016, 1886, 1011, 1877, 1016, 1888, 1013, 1881, 1010, 1876, 1015, 1885, 1035, 1923, 1040, 1932, 1044, 1940, 1048, 1946, 1040, 1931, 1038, 1928, 1049, 1949, 1058, 1966, 1058, 1964, 1056, 1962, 1054, 1957, 1061, 1971, 1061, 1970, 1074, 1994, 141, 263, 167, 311, 190, 352,}, + {991, 1841, 984, 1828, 974, 1808, 985, 1829, 996, 1850, 996, 1850, 995, 1847, 1004, 1864, 995, 1849, 998, 1854, 1002, 1862, 1009, 1875, 1022, 1898, 1026, 1906, 1028, 1910, 1021, 1897, 1018, 1890, 1031, 1915, 1038, 1928, 1040, 1932, 1040, 1932, 1043, 1937, 1052, 1954, 1056, 1960, 1068, 1983, 141, 263, 165, 306, 189, 351,}, + {1011, 1877, 1009, 1873, 993, 1845, 1007, 1871, 1016, 1888, 1018, 1890, 1013, 1881, 1022, 1898, 1013, 1881, 1014, 1882, 1019, 1893, 1030, 1912, 1040, 1931, 1055, 1959, 1046, 1942, 1037, 1927, 1033, 1919, 1046, 1942, 1053, 1955, 1057, 1963, 1052, 1954, 1050, 1950, 1058, 1966, 1061, 1971, 1075, 1996, 141, 261, 165, 307, 190, 352,}, + {1012, 1880, 1009, 1873, 999, 1855, 1012, 1879, 1019, 1893, 1023, 1899, 1019, 1892, 1028, 1910, 1022, 1898, 1021, 1895, 1023, 1901, 1040, 1932, 1042, 1936, 1049, 1947, 1051, 1951, 1043, 1937, 1042, 1934, 1050, 1950, 1057, 1963, 1058, 1964, 1053, 1955, 1049, 1947, 1061, 1971, 1064, 1976, 1072, 1990, 144, 267, 165, 307, 189, 351,}, + {1022, 1898, 1018, 1890, 1002, 1862, 1015, 1885, 1027, 1907, 1029, 1911, 1026, 1906, 1035, 1921, 1028, 1910, 1028, 1910, 1030, 1912, 1043, 1937, 1043, 1937, 1048, 1946, 1052, 1954, 1043, 1937, 1040, 1931, 1054, 1957, 1062, 1972, 1063, 1975, 1054, 1958, 1051, 1953, 1060, 1968, 1075, 1997, 1070, 1986, 144, 267, 166, 308, 188, 350,}, + {1021, 1897, 1017, 1889, 1007, 1871, 1014, 1882, 1028, 1908, 1030, 1914, 1026, 1906, 1033, 1919, 1025, 1903, 1021, 1897, 1028, 1910, 1041, 1933, 1044, 1938, 1049, 1949, 1050, 1950, 1042, 1936, 1041, 1933, 1052, 1954, 1060, 1968, 1063, 1975, 1069, 1985, 1051, 1951, 1061, 1970, 1066, 1980, 1069, 1985, 145, 269, 168, 312, 188, 350,}, + {1030, 1912, 1018, 1890, 1005, 1867, 1018, 1890, 1031, 1915, 1030, 1914, 1029, 1911, 1037, 1927, 1028, 1908, 1025, 1903, 1030, 1912, 1041, 1933, 1072, 1992, 1044, 1940, 1051, 1951, 1044, 1940, 1041, 1933, 1052, 1954, 1058, 1966, 1058, 1966, 1053, 1955, 1050, 1950, 1064, 1976, 1066, 1980, 1072, 1990, 146, 270, 166, 308, 185, 343,}, + {1025, 1903, 1017, 1889, 1003, 1863, 1014, 1884, 1028, 1910, 1030, 1914, 1027, 1907, 1033, 1918, 1024, 1902, 1022, 1898, 1027, 1907, 1041, 1933, 1072, 1990, 1041, 1933, 1047, 1945, 1037, 1925, 1035, 1921, 1047, 1945, 1057, 1963, 1055, 1959, 1049, 1947, 1050, 1950, 1071, 1989, 1063, 1973, 1065, 1979, 144, 267, 169, 315, 186, 345,}, + {1039, 1929, 1033, 1918, 1019, 1892, 1026, 1906, 1042, 1934, 1044, 1938, 1037, 1927, 1049, 1947, 1041, 1933, 1041, 1933, 1047, 1945, 1067, 1981, 1047, 1945, 1053, 1955, 1054, 1958, 1051, 1951, 1047, 1944, 1058, 1966, 1060, 1968, 1066, 1980, 1061, 1970, 1062, 1972, 1070, 1986, 1071, 1989, 1075, 1996, 146, 270, 168, 312, 188, 348,}, + {1119, 2079, 1096, 2035, 1086, 2016, 1098, 2038, 1114, 2068, 1121, 2081, 1126, 2090, 1142, 2120, 1149, 2133, 1164, 2162, 1197, 2223, 1296, 2408, 1004, 1864, 1011, 1877, 1016, 1886, 1012, 1879, 1010, 1876, 1019, 1893, 1028, 1910, 1030, 1912, 1026, 1905, 1025, 1903, 1030, 1914, 1035, 1921, 1042, 1934, 145, 269, 169, 315, 188, 348,}, + {184, 342, 176, 328, 172, 319, 186, 345, 186, 345, 181, 335, 176, 328, 181, 337, 178, 330, 171, 317, 230, 428, 180, 334, 181, 337, 182, 338, 186, 345, 174, 324, 171, 317, 176, 326, 183, 339, 180, 334, 174, 324, 172, 319, 181, 335, 175, 325, 165, 306, 1437, 2669, 1355, 2516, 1104, 2050,}, + }, +}; + +#define TX_NUM_TRULY_N3 15 +#define RX_NUM_TRULY_N3 28 + +const int16_t raw_cap_data_turly_N3[2][TX_NUM_TRULY_N3][RX_NUM_TRULY_N3*2] = +{ + //update base line data, 2014/07/15 + //enable cbc + { + {937, 2187, 971, 2265, 963, 2247, 968, 2258, 966, 2254, 980, 2286, 977, 2281, 988, 2304, 986, 2302, 1004, 2344, 994, 2320, 1015, 2367, 1030, 2404, 1069, 2493, 897, 2093, 910, 2124, 916, 2138, 917, 2139, 938, 2190, 955, 2229, 977, 2279, 977, 2279, 985, 2297, 1012, 2360, 988, 2306, -55, -129, -54, -126, -43, -99, }, + {867, 2023, 898, 2096, 897, 2093, 897, 2093, 905, 2113, 912, 2128, 916, 2138, 916, 2138, 928, 2166, 931, 2173, 940, 2194, 938, 2190, 970, 2264, 970, 2262, 914, 2132, 933, 2177, 934, 2178, 940, 2192, 958, 2236, 982, 2290, 994, 2318, 1003, 2341, 1010, 2358, 1028, 2398, 1006, 2348, -46, -108, -58, -134, -35, -83, }, + {848, 1978, 883, 2061, 878, 2050, 887, 2069, 886, 2066, 901, 2101, 901, 2101, 910, 2122, 910, 2122, 927, 2163, 920, 2146, 938, 2188, 947, 2209, 971, 2265, 927, 2163, 940, 2194, 946, 2208, 950, 2216, 968, 2260, 988, 2304, 1001, 2337, 1006, 2348, 1021, 2383, 1030, 2402, 1012, 2362, -55, -129, -57, -133, -59, -137,}, + {835, 1949, 867, 2023, 868, 2024, 878, 2050, 875, 2043, 884, 2062, 892, 2080, 894, 2086, 901, 2101, 910, 2122, 914, 2132, 920, 2146, 944, 2202, 945, 2205, 920, 2148, 940, 2194, 942, 2198, 948, 2212, 960, 2240, 980, 2286, 989, 2307, 998, 2330, 1006, 2348, 1020, 2380, 997, 2327, -44, -102, -54, -126, -31, -71, }, + {833, 1945, 872, 2036, 868, 2024, 874, 2040, 872, 2034, 887, 2069, 887, 2071, 895, 2089, 895, 2089, 912, 2128, 907, 2117, 923, 2155, 929, 2169, 949, 2213, 928, 2166, 945, 2205, 948, 2212, 948, 2212, 966, 2254, 980, 2286, 995, 2321, 997, 2325, 1012, 2360, 1019, 2379, 1004, 2344, -61, -141, -46, -106, -49, -113,}, + {826, 1926, 860, 2008, 861, 2009, 859, 2003, 860, 2008, 869, 2027, 875, 2043, 877, 2045, 886, 2066, 892, 2082, 896, 2092, 902, 2104, 917, 2141, 923, 2153, 923, 2153, 943, 2201, 940, 2192, 946, 2208, 962, 2244, 984, 2296, 994, 2318, 1004, 2344, 1015, 2367, 1033, 2411, 1012, 2362, -40, -92, -50, -118, -44, -104,}, + {824, 1922, 857, 1999, 852, 1988, 853, 1989, 846, 1974, 859, 2005, 860, 2008, 868, 2024, 871, 2031, 887, 2069, 881, 2055, 899, 2097, 904, 2110, 925, 2157, 932, 2174, 950, 2216, 950, 2216, 950, 2216, 971, 2267, 985, 2297, 1003, 2341, 1008, 2352, 1026, 2394, 1036, 2418, 1029, 2401, -47, -111, -49, -113, -51, -119,}, + {807, 1883, 841, 1963, 839, 1957, 835, 1947, 837, 1953, 844, 1968, 851, 1985, 856, 1996, 862, 2012, 872, 2036, 874, 2040, 884, 2062, 902, 2106, 910, 2124, 929, 2169, 950, 2216, 947, 2209, 953, 2225, 968, 2258, 989, 2309, 998, 2328, 1010, 2356, 1016, 2372, 1038, 2422, 1013, 2363, -37, -87, -62, -146, -41, -95, }, + {804, 1876, 837, 1953, 828, 1932, 834, 1946, 841, 1963, 845, 1973, 848, 1978, 857, 2001, 859, 2003, 874, 2038, 869, 2027, 885, 2065, 894, 2086, 907, 2115, 931, 2173, 943, 2201, 950, 2216, 951, 2219, 971, 2265, 985, 2297, 1003, 2341, 1006, 2348, 1022, 2384, 1026, 2394, 1029, 2401, -51, -119, -54, -126, -46, -108,}, + {806, 1880, 835, 1947, 832, 1942, 832, 1942, 837, 1953, 845, 1973, 852, 1988, 854, 1994, 861, 2009, 872, 2036, 874, 2038, 884, 2062, 899, 2097, 902, 2104, 934, 2178, 950, 2216, 953, 2225, 963, 2247, 974, 2274, 996, 2324, 1002, 2338, 1017, 2373, 1019, 2379, 1042, 2430, 1016, 2370, -46, -108, -56, -130, -43, -99, }, + {794, 1852, 831, 1939, 826, 1926, 830, 1938, 829, 1935, 842, 1966, 841, 1963, 845, 1973, 848, 1978, 867, 2023, 872, 2034, 881, 2055, 886, 2068, 899, 2097, 937, 2185, 946, 2208, 955, 2227, 958, 2236, 976, 2278, 982, 2290, 1000, 2332, 1000, 2334, 1021, 2383, 1028, 2400, 1028, 2398, -55, -129, -57, -133, -51, -119,}, + {794, 1852, 824, 1924, 823, 1919, 826, 1926, 826, 1928, 835, 1947, 838, 1954, 846, 1974, 844, 1970, 859, 2005, 860, 2008, 874, 2038, 884, 2062, 890, 2076, 938, 2190, 953, 2225, 953, 2225, 966, 2254, 974, 2274, 993, 2317, 994, 2318, 1013, 2363, 1018, 2376, 1052, 2456, 1016, 2370, -46, -106, -54, -126, -43, -99, }, + {796, 1856, 828, 1932, 830, 1938, 829, 1935, 824, 1924, 836, 1950, 835, 1947, 841, 1963, 844, 1970, 861, 2009, 856, 1996, 872, 2034, 879, 2051, 892, 2082, 950, 2216, 958, 2236, 965, 2251, 968, 2258, 989, 2309, 995, 2321, 1010, 2358, 1010, 2356, 1045, 2437, 1042, 2430, 1047, 2443, -54, -126, -56, -130, -51, -119,}, + {796, 1856, 820, 1912, 815, 1901, 817, 1907, 817, 1907, 821, 1915, 826, 1928, 828, 1932, 837, 1953, 856, 1996, 848, 1978, 859, 2003, 876, 2044, 887, 2069, 1004, 2344, 1021, 2381, 1016, 2370, 1029, 2401, 1036, 2416, 1057, 2467, 1049, 2449, 1075, 2507, 1074, 2506, 1112, 2594, 1047, 2443, -46, -106, -54, -126, -39, -91, }, + {-166, -386, -140, -326, -140, -326, -140, -326, -142, -330, -137, -319, -132, -308, -125, -293, -122, -284, -106, -246, -114, -266, -99, -231, -85, -197, -76, -176, 17, 41, 33, 77, 30, 70, 42, 98, 52, 120, 71, 167, 67, 157, 88, 206, 97, 225, 128, 298, 79, 185, 1186, 2768, 1253, 2923, 1201, 2803, }, + }, + + //disable cbc + { + {1161, 2157, 1161, 2155, 1178, 2188, 1176, 2184, 1186, 2202, 1184, 2200, 1212, 2252, 1189, 2209, 1217, 2259, 1238, 2298, 1276, 2370, 1075, 1996, 1095, 2033, 1103, 2049, 1099, 2041, 1128, 2096, 1146, 2128, 1178, 2188, 1169, 2171, 1184, 2198, 1217, 2259, 1180, 2192, -6, -10, -11, -20, 1, 1,}, + {1077, 1999, 1089, 2023, 1097, 2037, 1103, 2048, 1098, 2038, 1117, 2074, 1124, 2088, 1124, 2088, 1124, 2088, 1161, 2157, 1155, 2145, 1093, 2031, 1120, 2080, 1123, 2085, 1123, 2085, 1149, 2135, 1176, 2184, 1194, 2218, 1198, 2224, 1212, 2252, 1234, 2292, 1199, 2227, -13, -23, -11, -20, -6, -10,}, + {1069, 1985, 1069, 1985, 1088, 2020, 1087, 2019, 1096, 2035, 1096, 2035, 1122, 2084, 1103, 2048, 1128, 2094, 1138, 2113, 1159, 2153, 1110, 2062, 1130, 2098, 1140, 2116, 1138, 2113, 1163, 2159, 1184, 2198, 1205, 2239, 1203, 2235, 1225, 2275, 1238, 2298, 1207, 2241, -6, -10, -9, -17, 11, 20,}, + {1057, 1963, 1054, 1957, 1067, 1981, 1074, 1994, 1074, 1994, 1084, 2012, 1099, 2041, 1093, 2031, 1103, 2048, 1132, 2102, 1131, 2100, 1101, 2045, 1128, 2096, 1131, 2100, 1133, 2103, 1151, 2137, 1173, 2178, 1190, 2210, 1194, 2217, 1208, 2243, 1224, 2274, 1190, 2210, -11, -21, -11, -20, -6, -10,}, + {1049, 1947, 1044, 1938, 1065, 1977, 1064, 1976, 1072, 1992, 1072, 1992, 1096, 2035, 1080, 2006, 1103, 2048, 1111, 2063, 1128, 2096, 1105, 2053, 1128, 2094, 1134, 2106, 1128, 2096, 1155, 2145, 1168, 2170, 1194, 2218, 1188, 2206, 1213, 2253, 1224, 2274, 1196, 2220, 2, 4, -11, -20, 1, 1,}, + {1032, 1916, 1032, 1916, 1045, 1941, 1049, 1949, 1049, 1949, 1063, 1973, 1076, 1998, 1069, 1985, 1079, 2005, 1099, 2041, 1099, 2041, 1101, 2045, 1128, 2096, 1128, 2094, 1128, 2096, 1152, 2139, 1176, 2184, 1194, 2217, 1199, 2227, 1217, 2259, 1238, 2300, 1205, 2237, -11, -21, -9, -17, -4, -7,}, + {1030, 1912, 1022, 1898, 1038, 1928, 1040, 1931, 1046, 1942, 1049, 1949, 1076, 1998, 1058, 1966, 1082, 2009, 1091, 2027, 1110, 2062, 1120, 2080, 1144, 2124, 1146, 2128, 1143, 2123, 1171, 2175, 1186, 2202, 1212, 2252, 1210, 2246, 1234, 2292, 1248, 2318, 1231, 2285, -7, -13, -11, -20, 0, 0,}, + {1014, 1884, 1014, 1884, 1024, 1902, 1032, 1916, 1035, 1923, 1045, 1941, 1064, 1976, 1054, 1957, 1069, 1985, 1091, 2027, 1093, 2031, 1119, 2077, 1147, 2131, 1146, 2128, 1146, 2128, 1168, 2170, 1190, 2210, 1208, 2243, 1215, 2256, 1225, 2275, 1251, 2323, 1212, 2252, -11, -21, 0, 0, -6, -10,}, + {1007, 1871, 1020, 1894, 1026, 1905, 1028, 1908, 1037, 1927, 1040, 1931, 1064, 1976, 1046, 1942, 1067, 1981, 1082, 2009, 1088, 2020, 1119, 2077, 1140, 2116, 1146, 2128, 1143, 2123, 1170, 2174, 1184, 2200, 1212, 2252, 1208, 2243, 1231, 2285, 1236, 2296, 1231, 2285, -7, -13, -9, -17, 0, 0,}, + {1003, 1863, 1010, 1876, 1020, 1894, 1026, 1905, 1026, 1906, 1036, 1924, 1055, 1959, 1046, 1942, 1061, 1971, 1082, 2009, 1080, 2006, 1118, 2076, 1140, 2116, 1145, 2127, 1152, 2139, 1167, 2167, 1192, 2214, 1205, 2239, 1215, 2256, 1223, 2271, 1251, 2323, 1211, 2249, -11, -21, -9, -17, -4, -7,}, + {997, 1851, 998, 1853, 1012, 1880, 1011, 1877, 1014, 1884, 1020, 1894, 1047, 1945, 1041, 1933, 1056, 1962, 1064, 1976, 1072, 1990, 1117, 2074, 1131, 2100, 1144, 2124, 1143, 2123, 1167, 2167, 1173, 2178, 1199, 2227, 1194, 2217, 1223, 2271, 1234, 2292, 1224, 2274, -8, -14, -11, -21, -1, -3,}, + {988, 1834, 990, 1838, 1001, 1859, 1005, 1867, 1012, 1880, 1012, 1880, 1035, 1923, 1026, 1906, 1044, 1938, 1057, 1963, 1058, 1966, 1117, 2074, 1138, 2113, 1140, 2118, 1149, 2135, 1163, 2161, 1184, 2200, 1194, 2217, 1208, 2243, 1219, 2263, 1261, 2341, 1211, 2249, -11, -21, -11, -20, -6, -10,}, + {988, 1834, 985, 1829, 997, 1851, 995, 1849, 1001, 1859, 1005, 1867, 1032, 1916, 1014, 1884, 1036, 1924, 1047, 1945, 1058, 1966, 1126, 2092, 1140, 2116, 1151, 2137, 1147, 2131, 1177, 2185, 1184, 2198, 1208, 2243, 1202, 2232, 1246, 2314, 1246, 2314, 1243, 2309, -6, -10, -11, -20, 1, 1,}, + {981, 1823, 981, 1823, 988, 1834, 993, 1845, 992, 1842, 1005, 1866, 1032, 1916, 1011, 1877, 1026, 1906, 1049, 1949, 1055, 1959, 1194, 2218, 1220, 2266, 1213, 2253, 1224, 2274, 1238, 2298, 1259, 2339, 1257, 2335, 1279, 2375, 1286, 2388, 1332, 2474, 1248, 2318, -11, -21, -11, -20, -5, -9,}, + {1, 1, 38, 70, 7, 13, 12, 22, -3, -5, 32, 59, 13, 23, 8, 16, -1, -3, 81, 151, 1, 1, -6, -10, 3, 5, 3, 5, -7, -13, 2, 4, 1, 1, 7, 13, 5, 9, 2, 4, 10, 18, -4, -7, 1408, 2614, 1486, 2760, 1427, 2651,}, + }, +}; + +#define TX_NUM_TPK_GFF_N3 15 +#define RX_NUM_TPK_GFF_N3 28 + +const int16_t raw_cap_data_tpk_gff_N3[2][TX_NUM_TPK_GFF_N3][RX_NUM_TPK_GFF_N3*2] = +{ + //update base line data, 2014/07/15 + //enable cbc + { + {809 , 1887 , 848 , 1978 , 841 , 1961 , 841 , 1961 , 850 , 1984 , 847 , 1977 , 848 , 1978 , 854 , 1994 , 859 , 2005 , 860 , 2008 , 861 , 2009 , 879 , 2051 , 884 , 2062 , 902 , 2104 , 753 , 1757 , 756 , 1764 , 757 , 1765 , 767 , 1789 , 771 , 1799 , 776 , 1810 , 776 , 1812 , 778 , 1816 , 791 , 1845 , 791 , 1847 , 779 , 1819 , -8 , -18 , -11 , -25 , -20 , -48 ,}, + {736 , 1718 , 787 , 1835 , 781 , 1823 , 781 , 1823 , 790 , 1842 , 787 , 1835 , 788 , 1838 , 796 , 1856 , 797 , 1861 , 797 , 1861 , 805 , 1877 , 806 , 1882 , 802 , 1872 , 801 , 1869 , 781 , 1823 , 785 , 1831 , 786 , 1834 , 793 , 1849 , 797 , 1861 , 804 , 1876 , 806 , 1880 , 806 , 1880 , 811 , 1891 , 813 , 1897 , 798 , 1862 , -8 , -18 , -13 , -29 , -22 , -50 ,}, + {735 , 1715 , 783 , 1827 , 778 , 1816 , 782 , 1826 , 787 , 1835 , 784 , 1830 , 785 , 1831 , 791 , 1845 , 796 , 1858 , 796 , 1858 , 797 , 1861 , 805 , 1877 , 798 , 1862 , 798 , 1862 , 787 , 1835 , 789 , 1841 , 793 , 1849 , 800 , 1866 , 802 , 1872 , 809 , 1887 , 811 , 1891 , 813 , 1897 , 816 , 1904 , 819 , 1911 , 808 , 1884 , -9 , -21 , -13 , -29 , -22 , -52 ,}, + {733 , 1711 , 782 , 1826 , 776 , 1812 , 776 , 1810 , 782 , 1826 , 783 , 1827 , 784 , 1830 , 790 , 1842 , 794 , 1854 , 797 , 1861 , 800 , 1866 , 803 , 1873 , 796 , 1858 , 805 , 1877 , 791 , 1845 , 793 , 1851 , 794 , 1854 , 802 , 1872 , 806 , 1882 , 811 , 1893 , 813 , 1897 , 816 , 1904 , 819 , 1911 , 824 , 1922 , 801 , 1869 , -8 , -18 , -11 , -27 , -22 , -52 ,}, + {734 , 1712 , 781 , 1823 , 778 , 1814 , 776 , 1812 , 786 , 1834 , 782 , 1826 , 782 , 1826 , 789 , 1841 , 793 , 1849 , 798 , 1862 , 797 , 1861 , 803 , 1873 , 802 , 1872 , 800 , 1866 , 793 , 1849 , 796 , 1858 , 797 , 1861 , 806 , 1880 , 809 , 1887 , 812 , 1896 , 818 , 1908 , 819 , 1911 , 821 , 1915 , 826 , 1928 , 806 , 1880 , -1 , -3 , -11 , -27 , -23 , -55 ,}, + {733 , 1711 , 783 , 1827 , 780 , 1820 , 780 , 1820 , 786 , 1834 , 786 , 1834 , 784 , 1830 , 791 , 1845 , 794 , 1854 , 796 , 1856 , 797 , 1861 , 801 , 1869 , 803 , 1873 , 797 , 1861 , 793 , 1849 , 798 , 1862 , 798 , 1862 , 806 , 1882 , 809 , 1889 , 816 , 1904 , 821 , 1915 , 826 , 1926 , 829 , 1935 , 834 , 1946 , 811 , 1891 , -1 , -3 , -11 , -27 , -22 , -52 ,}, + {731 , 1707 , 779 , 1819 , 775 , 1807 , 776 , 1812 , 782 , 1826 , 780 , 1820 , 780 , 1820 , 788 , 1838 , 791 , 1845 , 790 , 1842 , 791 , 1847 , 798 , 1862 , 787 , 1835 , 791 , 1845 , 793 , 1849 , 794 , 1854 , 794 , 1854 , 804 , 1876 , 809 , 1889 , 818 , 1908 , 824 , 1922 , 826 , 1926 , 830 , 1938 , 833 , 1943 , 814 , 1900 , -16 , -38 , -13 , -29 , -23 , -55 ,}, + {735 , 1715 , 782 , 1826 , 776 , 1810 , 778 , 1814 , 783 , 1827 , 779 , 1819 , 781 , 1823 , 787 , 1835 , 791 , 1847 , 794 , 1854 , 791 , 1847 , 803 , 1873 , 789 , 1841 , 791 , 1845 , 797 , 1861 , 797 , 1861 , 796 , 1858 , 809 , 1887 , 811 , 1893 , 821 , 1915 , 823 , 1919 , 829 , 1935 , 831 , 1939 , 838 , 1954 , 817 , 1907 , -1 , -3 , -13 , -31 , -23 , -55 ,}, + {732 , 1708 , 778 , 1814 , 772 , 1800 , 773 , 1803 , 786 , 1834 , 779 , 1819 , 779 , 1819 , 784 , 1830 , 790 , 1842 , 790 , 1842 , 788 , 1838 , 796 , 1858 , 789 , 1841 , 788 , 1838 , 797 , 1861 , 800 , 1866 , 801 , 1869 , 809 , 1889 , 813 , 1897 , 821 , 1915 , 823 , 1919 , 826 , 1928 , 833 , 1943 , 837 , 1953 , 817 , 1907 , -10 , -22 , -13 , -29 , -15 , -35 ,}, + {730 , 1702 , 778 , 1814 , 770 , 1796 , 770 , 1796 , 778 , 1814 , 783 , 1827 , 783 , 1827 , 784 , 1830 , 788 , 1838 , 788 , 1838 , 788 , 1838 , 797 , 1861 , 789 , 1841 , 789 , 1841 , 804 , 1876 , 804 , 1876 , 805 , 1877 , 811 , 1893 , 815 , 1901 , 821 , 1915 , 823 , 1919 , 828 , 1932 , 832 , 1942 , 835 , 1947 , 815 , 1901 , -9 , -21 , -13 , -29 , -15 , -35 ,}, + {725 , 1693 , 771 , 1799 , 767 , 1789 , 767 , 1789 , 776 , 1810 , 776 , 1812 , 776 , 1810 , 783 , 1827 , 783 , 1827 , 785 , 1831 , 787 , 1835 , 796 , 1856 , 790 , 1842 , 791 , 1847 , 806 , 1880 , 808 , 1884 , 809 , 1887 , 814 , 1900 , 816 , 1904 , 821 , 1915 , 824 , 1922 , 826 , 1926 , 832 , 1942 , 834 , 1946 , 813 , 1897 , -7 , -15 , -11 , -25 , -29 , -67 ,}, + {725 , 1693 , 771 , 1799 , 767 , 1789 , 768 , 1792 , 776 , 1810 , 784 , 1830 , 779 , 1819 , 784 , 1830 , 784 , 1830 , 786 , 1834 , 789 , 1841 , 798 , 1862 , 790 , 1842 , 791 , 1845 , 811 , 1893 , 813 , 1897 , 813 , 1897 , 818 , 1908 , 821 , 1915 , 823 , 1919 , 824 , 1924 , 827 , 1931 , 832 , 1942 , 834 , 1946 , 813 , 1897 , -9 , -21 , -13 , -31 , -17 , -39 ,}, + {725 , 1693 , 772 , 1800 , 767 , 1789 , 768 , 1792 , 773 , 1805 , 775 , 1807 , 776 , 1812 , 783 , 1827 , 786 , 1834 , 789 , 1841 , 791 , 1845 , 796 , 1858 , 791 , 1847 , 791 , 1847 , 816 , 1904 , 818 , 1908 , 820 , 1912 , 824 , 1924 , 823 , 1919 , 829 , 1935 , 829 , 1935 , 833 , 1943 , 837 , 1953 , 842 , 1966 , 823 , 1919 , -9 , -21 , -19 , -45 , -14 , -32 ,}, + {703 , 1641 , 749 , 1749 , 745 , 1737 , 745 , 1737 , 751 , 1753 , 751 , 1753 , 750 , 1750 , 758 , 1770 , 758 , 1770 , 763 , 1781 , 767 , 1789 , 776 , 1810 , 769 , 1795 , 769 , 1795 , 878 , 2050 , 869 , 2027 , 868 , 2024 , 872 , 2034 , 872 , 2034 , 877 , 2047 , 874 , 2040 , 878 , 2050 , 877 , 2045 , 879 , 2051 , 856 , 1996 , -8 , -18 , -3 , -7 , -14 , -32 ,}, + {-252 , -588 , -206 , -480 , -211 , -491 , -209 , -489 , -203 , -473 , -199 , -465 , -200 , -466 , -194 , -454 , -193 , -449 , -190 , -442 , -186 , -434 , -178 , -414 , -186 , -434 , -186 , -434 , -115 , -269 , -119 , -277 , -118 , -276 , -114 , -266 , -116 , -272 , -110 , -258 , -112 , -262 , -109 , -253 , -109 , -253 , -103 , -241 , -125 , -293 , 976 , 2276 , 978 , 2282 , 930 , 2170 ,}, + }, + + //disable cbc + { + {937 , 1741 , 989 , 1837 , 978 , 1816 , 974 , 1808 , 991 , 1841 , 984 , 1827 , 984 , 1827 , 998 , 1853 , 1001 , 1859 , 1005 , 1867 , 1003 , 1863 , 1028 , 1908 , 1028 , 1908 , 1049 , 1949 , 874 , 1622 , 881 , 1637 , 878 , 1630 , 895 , 1663 , 899 , 1669 , 904 , 1680 , 904 , 1680 , 904 , 1680 , 923 , 1715 , 921 , 1710 , 905 , 1681 , -1 , -3 , -9 , -17 , -15 , -29, }, + {851 , 1580 , 918 , 1704 , 905 , 1681 , 905 , 1681 , 918 , 1706 , 910 , 1690 , 910 , 1690 , 926 , 1720 , 928 , 1723 , 928 , 1724 , 933 , 1733 , 937 , 1741 , 930 , 1726 , 930 , 1726 , 904 , 1680 , 912 , 1694 , 908 , 1686 , 923 , 1715 , 925 , 1719 , 933 , 1733 , 933 , 1733 , 934 , 1734 , 944 , 1752 , 945 , 1755 , 928 , 1724 , -1 , -3 , -8 , -14 , -17 , -31, }, + {847 , 1573 , 913 , 1695 , 900 , 1672 , 902 , 1676 , 910 , 1690 , 904 , 1680 , 904 , 1680 , 916 , 1702 , 922 , 1712 , 922 , 1712 , 921 , 1710 , 934 , 1734 , 920 , 1708 , 922 , 1712 , 907 , 1684 , 913 , 1695 , 912 , 1694 , 928 , 1723 , 931 , 1729 , 939 , 1743 , 939 , 1743 , 943 , 1751 , 949 , 1763 , 951 , 1765 , 939 , 1743 , -1 , -3 , -8 , -14 , -17 , -31, }, + {845 , 1569 , 912 , 1694 , 897 , 1667 , 897 , 1665 , 909 , 1687 , 907 , 1684 , 904 , 1680 , 918 , 1706 , 923 , 1715 , 926 , 1720 , 926 , 1720 , 933 , 1733 , 920 , 1708 , 932 , 1730 , 914 , 1698 , 921 , 1710 , 916 , 1702 , 932 , 1730 , 935 , 1737 , 942 , 1749 , 942 , 1749 , 947 , 1759 , 953 , 1769 , 955 , 1773 , 931 , 1729 , 1 , 1 , -7 , -13 , -15 , -29, }, + {849 , 1577 , 914 , 1698 , 902 , 1676 , 900 , 1672 , 916 , 1700 , 907 , 1684 , 907 , 1684 , 921 , 1710 , 924 , 1716 , 931 , 1729 , 928 , 1724 , 937 , 1741 , 933 , 1733 , 932 , 1730 , 918 , 1706 , 925 , 1719 , 922 , 1712 , 937 , 1741 , 939 , 1745 , 946 , 1758 , 951 , 1765 , 953 , 1769 , 956 , 1776 , 959 , 1781 , 937 , 1741 , 0 , 0 , -8 , -14 , -19 , -35, }, + {854 , 1586 , 921 , 1710 , 912 , 1694 , 910 , 1690 , 921 , 1710 , 918 , 1704 , 914 , 1698 , 930 , 1726 , 930 , 1726 , 931 , 1729 , 928 , 1724 , 939 , 1745 , 933 , 1733 , 930 , 1726 , 923 , 1715 , 931 , 1729 , 924 , 1716 , 943 , 1751 , 944 , 1752 , 953 , 1769 , 956 , 1776 , 963 , 1788 , 970 , 1801 , 970 , 1802 , 945 , 1755 , 1 , 1 , -7 , -13 , -15 , -29, }, + {844 , 1568 , 910 , 1690 , 899 , 1669 , 902 , 1676 , 908 , 1686 , 904 , 1680 , 901 , 1673 , 918 , 1704 , 918 , 1704 , 920 , 1708 , 918 , 1704 , 932 , 1730 , 911 , 1691 , 918 , 1704 , 921 , 1710 , 923 , 1715 , 918 , 1706 , 939 , 1743 , 944 , 1752 , 954 , 1772 , 958 , 1780 , 960 , 1784 , 970 , 1801 , 970 , 1801 , 949 , 1763 , 8 , 16 , -6 , -10 , -18 , -34, }, + {854 , 1586 , 918 , 1704 , 905 , 1681 , 907 , 1684 , 916 , 1700 , 909 , 1687 , 909 , 1687 , 923 , 1715 , 928 , 1723 , 928 , 1724 , 924 , 1716 , 942 , 1749 , 918 , 1706 , 922 , 1712 , 930 , 1726 , 931 , 1729 , 926 , 1720 , 946 , 1758 , 947 , 1759 , 962 , 1786 , 960 , 1784 , 967 , 1795 , 972 , 1806 , 978 , 1816 , 955 , 1773 , 2 , 4 , -6 , -10 , -13 , -25, }, + {853 , 1583 , 914 , 1698 , 903 , 1677 , 902 , 1676 , 922 , 1712 , 911 , 1691 , 907 , 1684 , 921 , 1710 , 925 , 1719 , 928 , 1723 , 922 , 1712 , 933 , 1733 , 918 , 1706 , 921 , 1710 , 928 , 1724 , 937 , 1741 , 931 , 1729 , 949 , 1762 , 951 , 1767 , 962 , 1786 , 959 , 1781 , 964 , 1790 , 974 , 1810 , 977 , 1815 , 955 , 1773 , -1 , -3 , -8 , -14 , -17 , -31, }, + {844 , 1568 , 908 , 1686 , 893 , 1659 , 893 , 1659 , 908 , 1686 , 909 , 1687 , 909 , 1687 , 916 , 1702 , 920 , 1708 , 921 , 1710 , 918 , 1704 , 933 , 1733 , 916 , 1700 , 916 , 1702 , 936 , 1738 , 941 , 1747 , 936 , 1738 , 951 , 1767 , 953 , 1769 , 959 , 1781 , 958 , 1780 , 966 , 1794 , 972 , 1806 , 972 , 1806 , 951 , 1767 , 0 , 0 , -8 , -14 , -13 , -25, }, + {841 , 1561 , 904 , 1680 , 895 , 1663 , 893 , 1659 , 907 , 1684 , 903 , 1677 , 901 , 1673 , 914 , 1698 , 913 , 1695 , 916 , 1702 , 916 , 1700 , 928 , 1724 , 916 , 1700 , 918 , 1706 , 933 , 1733 , 939 , 1745 , 936 , 1738 , 951 , 1765 , 949 , 1763 , 956 , 1776 , 956 , 1776 , 959 , 1781 , 970 , 1802 , 970 , 1802 , 946 , 1758 , 0 , 0 , -7 , -13 , -8 , -14, }, + {841 , 1563 , 903 , 1677 , 893 , 1659 , 891 , 1655 , 907 , 1684 , 914 , 1698 , 905 , 1681 , 916 , 1702 , 916 , 1702 , 920 , 1708 , 921 , 1710 , 934 , 1734 , 918 , 1706 , 918 , 1706 , 944 , 1752 , 949 , 1763 , 945 , 1755 , 955 , 1773 , 957 , 1777 , 962 , 1786 , 960 , 1784 , 963 , 1788 , 970 , 1802 , 970 , 1802 , 949 , 1762 , -1 , -3 , -8 , -14 , -17 , -31, }, + {839 , 1559 , 903 , 1677 , 893 , 1658 , 893 , 1658 , 902 , 1676 , 897 , 1667 , 900 , 1672 , 913 , 1695 , 912 , 1694 , 918 , 1704 , 916 , 1702 , 926 , 1720 , 914 , 1698 , 918 , 1704 , 944 , 1752 , 949 , 1762 , 944 , 1752 , 958 , 1780 , 955 , 1773 , 965 , 1791 , 963 , 1788 , 968 , 1798 , 974 , 1808 , 978 , 1816 , 956 , 1776 , 1 , 1 , 2 , 4 , -15 , -29, }, + {812 , 1508 , 874 , 1622 , 864 , 1604 , 864 , 1604 , 874 , 1622 , 872 , 1619 , 870 , 1616 , 886 , 1645 , 887 , 1647 , 893 , 1658 , 895 , 1663 , 909 , 1687 , 893 , 1658 , 895 , 1661 , 1023 , 1899 , 1014 , 1884 , 1010 , 1876 , 1021 , 1895 , 1018 , 1890 , 1023 , 1899 , 1022 , 1898 , 1023 , 1899 , 1024 , 1902 , 1026 , 1905 , 995 , 1849 , -1 , -3 , -7 , -13 , -15 , -29, }, + {-9 , -17 , 6 , 12 , -6 , -10 , -9 , -17 , 0 , 0 , -8 , -14 , -13 , -25 , -3 , -5 , -3 , -5 , -5 , -9 , -9 , -17 , 1 , 1 , -15 , -27 , 12 , 22 , -15 , -29 , -11 , -21 , -21 , -39 , -13 , -23 , -13 , -25 , -11 , -20 , -15 , -29 , -13 , -25 , -9 , -17 , 1 , 1 , -6 , -10 , 1151 , 2137 , 1152 , 2139 , 1103 , 2048,}, + }, +}; + +#define TX_NUM_TPK (15) +#define RX_NUM_TPK (28) +#define DiagonalUpperLimit_TPK (1100) +#define DiagonalLowerLimit_TPK (900) +const int16_t raw_cap_data_tpk[2][TX_NUM_TPK][RX_NUM_TPK*2] = +{ + //update base line data, 2014/04/10 + //update base line data, 2014/03/25 + //enable cbc + {{1506,3128,1465,3044,1452,3016,1441,2994,1430,2970,1419,2947,1410,2928,1401,2911,1394,2896,1390,2887,1385,2877,1378,2862,1373,2852,1377,2861,1218,2530,1203,2498,1193,2477,1186,2464,1178,2446,1170,2431,1167,2423,1161,2411,1157,2404,1153,2395,1152,2393,1151,2390,1143,2374,1145,2378,}, + {1459,3030,1436,2982,1421,2951,1409,2927,1399,2906,1385,2877,1371,2848,1361,2826,1361,2827,1347,2798,1342,2787,1334,2772,1328,2759,1319,2739,1276,2651,1271,2639,1262,2621,1256,2609,1248,2592,1242,2579,1238,2570,1233,2561,1230,2554,1225,2544,1222,2539,1221,2537,1210,2513,1301,2703,}, + {1435,2981,1421,2952,1411,2930,1402,2912,1392,2891,1377,2860,1365,2836,1356,2816,1349,2801,1342,2787,1335,2773,1327,2756,1329,2761,1311,2722,1279,2655,1273,2645,1265,2628,1259,2616,1251,2599,1245,2586,1242,2580,1238,2572,1234,2564,1229,2553,1226,2546,1224,2542,1220,2535,1265,2627,}, + {1413,2935,1407,2922,1400,2907,1391,2890,1380,2867,1368,2842,1357,2819,1347,2798,1339,2782,1332,2766,1326,2753,1317,2735,1311,2723,1300,2700,1276,2650,1271,2639,1262,2622,1257,2610,1249,2593,1243,2583,1241,2578,1237,2570,1235,2564,1238,2571,1226,2546,1222,2538,1210,2513,1299,2698,}, + {1392,2892,1394,2896,1389,2884,1393,2892,1376,2858,1365,2835,1354,2812,1344,2792,1335,2773,1329,2760,1323,2748,1315,2732,1309,2719,1298,2696,1282,2662,1276,2650,1267,2632,1262,2621,1254,2605,1249,2594,1246,2589,1243,2582,1241,2577,1235,2566,1232,2559,1228,2551,1207,2507,1301,2701,}, + {1386,2880,1389,2885,1384,2875,1380,2865,1373,2851,1362,2828,1350,2804,1340,2782,1331,2764,1324,2750,1317,2736,1309,2719,1303,2706,1296,2692,1284,2667,1277,2653,1269,2635,1263,2624,1266,2628,1250,2597,1248,2591,1244,2585,1242,2579,1236,2568,1233,2560,1228,2551,1205,2503,1299,2698,}, + {1392,2891,1386,2879,1382,2870,1377,2859,1369,2844,1366,2837,1347,2797,1336,2774,1327,2756,1319,2739,1312,2724,1303,2707,1297,2695,1286,2671,1283,2665,1277,2652,1268,2633,1262,2621,1254,2605,1249,2594,1247,2590,1245,2585,1242,2579,1237,2568,1233,2561,1228,2551,1206,2505,1334,2770,}, + {1384,2875,1379,2865,1374,2854,1368,2842,1361,2827,1350,2803,1338,2780,1327,2757,1318,2737,1310,2720,1302,2704,1303,2706,1288,2675,1277,2653,1281,2661,1275,2647,1266,2630,1260,2617,1254,2604,1247,2589,1246,2588,1242,2580,1239,2573,1234,2563,1231,2557,1227,2548,1204,2501,1238,2571,}, + {1383,2873,1379,2863,1372,2850,1366,2837,1358,2821,1347,2797,1335,2772,1323,2748,1314,2729,1306,2712,1307,2715,1291,2680,1285,2668,1274,2645,1284,2666,1276,2650,1267,2632,1261,2619,1254,2604,1249,2593,1246,2588,1243,2582,1240,2575,1234,2562,1230,2556,1227,2548,1204,2501,1287,2672,}, + {1393,2893,1380,2867,1374,2855,1369,2842,1360,2825,1349,2801,1337,2777,1326,2753,1316,2734,1308,2717,1301,2703,1293,2686,1288,2675,1277,2652,1296,2693,1285,2670,1292,2684,1270,2637,1288,2674,1257,2610,1254,2604,1250,2596,1246,2589,1240,2576,1237,2568,1233,2561,1210,2512,1301,2702,}, + {1385,2876,1388,2883,1373,2852,1367,2838,1358,2820,1349,2803,1338,2778,1325,2753,1316,2733,1308,2716,1301,2703,1293,2686,1288,2674,1277,2652,1303,2706,1292,2684,1282,2662,1275,2649,1268,2633,1261,2620,1259,2615,1255,2606,1251,2598,1245,2587,1242,2579,1238,2570,1215,2523,1316,2732,}, + {1381,2868,1374,2853,1367,2839,1360,2824,1351,2806,1341,2785,1339,2781,1320,2742,1311,2723,1303,2705,1295,2690,1287,2674,1282,2662,1271,2640,1307,2714,1295,2689,1284,2667,1276,2651,1270,2637,1260,2618,1258,2612,1255,2606,1251,2599,1246,2588,1243,2581,1238,2572,1225,2544,1355,2815,}, + {1386,2878,1376,2858,1368,2841,1362,2828,1362,2828,1342,2788,1333,2768,1323,2748,1315,2731,1307,2714,1299,2698,1291,2681,1284,2668,1273,2644,1321,2743,1306,2711,1294,2687,1287,2672,1277,2652,1270,2637,1267,2631,1264,2626,1262,2621,1257,2611,1254,2604,1251,2599,1239,2572,1269,2637,}, + {1387,2881,1377,2859,1366,2836,1357,2819,1348,2801,1338,2780,1329,2761,1320,2741,1311,2723,1303,2707,1296,2692,1288,2674,1281,2662,1278,2655,1375,2857,1368,2842,1328,2758,1327,2757,1307,2715,1288,2676,1282,2662,1280,2659,1278,2655,1276,2649,1274,2645,1272,2643,1251,2597,1267,2632,}, + {1343,2790,1333,2770,1318,2738,1307,2714,1296,2691,1284,2666,1272,2643,1260,2618,1249,2594,1238,2572,1229,2552,1219,2531,1211,2516,1208,2509,1622,3369,1485,3083,1433,2976,1403,2913,1378,2862,1371,2847,1353,2811,1347,2797,1342,2788,1337,2777,1336,2774,1334,2771,1308,2717,1321,2743,}, + }, + //update base line data, 2014/04/10 + //update base line data, 2014/03/19 + //update base line data, 2014/01/20 + //update base line data, 2013/12/22 + //update base line data, 2013/12/16 + //update base line data, 2013/11/25 + //disable cbc + {{1689,3003,1648,2930,1642,2920,1634,2905,1625,2888,1613,2868,1604,2852,1597,2838,1589,2825,1582,2812,1576,2801,1569,2790,1565,2781,1571,2793,1392,2475,1373,2440,1364,2424,1356,2411,1349,2399,1343,2388,1301,2416,1296,2406,1292,2400,1289,2394,1285,2387,1285,2386,1294,2404,1292,2400,}, + {1634,2906,1616,2872,1611,2863,1600,2844,1587,2821,1573,2797,1562,2776,1552,2759,1554,2762,1536,2731,1529,2718,1521,2704,1515,2694,1507,2679,1458,2593,1449,2576,1441,2562,1433,2548,1427,2537,1420,2525,1415,2515,1409,2506,1407,2501,1403,2494,1398,2485,1394,2478,1403,2494,1499,2665,}, + {1610,2863,1606,2854,1603,2851,1594,2834,1582,2812,1569,2790,1557,2769,1548,2752,1540,2739,1531,2722,1523,2708,1515,2693,1517,2696,1498,2663,1460,2596,1451,2579,1442,2563,1435,2552,1430,2542,1424,2532,1418,2520,1413,2511,1408,2504,1404,2497,1398,2486,1393,2477,1402,2492,1466,2607,}, + {1593,2832,1596,2838,1596,2838,1588,2824,1578,2805,1565,2782,1552,2759,1543,2743,1535,2729,1526,2712,1516,2696,1507,2680,1500,2666,1490,2649,1462,2598,1453,2583,1445,2569,1439,2558,1433,2548,1428,2538,1422,2527,1415,2516,1412,2510,1417,2520,1401,2491,1393,2477,1399,2487,1511,2686,}, + {1569,2790,1580,2810,1584,2817,1589,2824,1570,2791,1559,2772,1548,2752,1538,2735,1529,2719,1520,2702,1512,2688,1504,2673,1496,2660,1488,2645,1468,2610,1459,2594,1451,2580,1445,2569,1439,2559,1434,2550,1428,2538,1422,2528,1419,2522,1413,2513,1407,2501,1399,2486,1392,2476,1514,2692,}, + {1565,2782,1572,2795,1577,2804,1573,2796,1564,2781,1553,2762,1541,2740,1530,2721,1520,2703,1511,2686,1503,2671,1494,2656,1487,2644,1482,2636,1468,2610,1459,2594,1452,2581,1445,2569,1452,2581,1435,2550,1428,2539,1423,2529,1419,2522,1413,2512,1405,2497,1396,2482,1385,2462,1506,2678,}, + {1566,2784,1569,2790,1575,2800,1570,2791,1561,2776,1559,2772,1536,2732,1525,2711,1514,2692,1504,2674,1496,2660,1485,2641,1480,2631,1471,2614,1465,2604,1455,2587,1448,2575,1442,2564,1437,2554,1433,2547,1427,2537,1422,2527,1417,2520,1412,2510,1403,2495,1395,2480,1382,2456,1536,2732,}, + {1566,2783,1568,2788,1573,2797,1568,2787,1560,2774,1550,2755,1536,2731,1523,2708,1512,2689,1503,2671,1495,2657,1494,2657,1478,2628,1468,2610,1471,2614,1461,2597,1453,2583,1447,2573,1444,2566,1437,2555,1433,2547,1426,2536,1422,2528,1417,2518,1408,2504,1401,2491,1385,2463,1443,2566,}, + {1567,2786,1567,2786,1571,2792,1567,2786,1558,2769,1545,2747,1533,2725,1521,2703,1510,2684,1499,2665,1500,2667,1481,2633,1474,2620,1465,2604,1474,2621,1463,2601,1455,2587,1449,2575,1444,2567,1439,2559,1434,2549,1427,2537,1423,2530,1418,2520,1410,2506,1402,2492,1387,2466,1500,2667,}, + {1575,2799,1566,2783,1569,2790,1564,2781,1556,2766,1543,2743,1531,2721,1518,2700,1508,2680,1498,2662,1489,2646,1479,2629,1472,2616,1462,2600,1483,2637,1469,2611,1481,2633,1454,2585,1476,2625,1443,2565,1438,2556,1431,2544,1427,2538,1421,2527,1412,2511,1405,2498,1390,2472,1511,2687,}, + {1562,2777,1575,2799,1568,2787,1562,2776,1553,2760,1542,2741,1530,2720,1518,2699,1507,2680,1498,2663,1489,2648,1480,2631,1472,2617,1463,2600,1488,2646,1475,2622,1467,2608,1460,2595,1455,2586,1449,2575,1443,2566,1437,2555,1433,2547,1427,2536,1419,2523,1411,2508,1397,2484,1528,2716,}, + {1562,2777,1563,2778,1566,2783,1558,2769,1548,2752,1538,2734,1537,2732,1516,2694,1507,2680,1496,2660,1488,2645,1479,2629,1471,2615,1462,2598,1498,2663,1482,2634,1473,2618,1464,2603,1462,2598,1452,2582,1447,2572,1441,2562,1438,2556,1433,2547,1425,2533,1416,2518,1417,2519,1572,2795,}, + {1565,2782,1560,2773,1562,2777,1556,2765,1555,2765,1536,2730,1526,2712,1515,2694,1506,2676,1496,2659,1487,2643,1478,2628,1471,2616,1462,2598,1511,2686,1492,2652,1480,2631,1471,2615,1464,2603,1458,2591,1452,2581,1448,2575,1446,2571,1442,2563,1435,2551,1427,2538,1427,2537,1479,2630,}, + {1565,2782,1557,2768,1555,2764,1548,2752,1541,2740,1531,2721,1520,2702,1510,2685,1501,2668,1491,2651,1482,2635,1473,2619,1466,2607,1466,2607,1567,2786,1560,2773,1516,2696,1519,2700,1498,2663,1478,2628,1468,2610,1466,2607,1465,2605,1462,2599,1457,2590,1451,2579,1439,2559,1473,2618,}, + {1525,2711,1516,2695,1508,2681,1498,2662,1492,2652,1476,2624,1463,2601,1450,2577,1438,2556,1426,2536,1416,2518,1405,2498,1396,2482,1396,2481,1855,3297,1699,3020,1642,2919,1608,2859,1586,2819,1579,2807,1558,2770,1551,2757,1547,2750,1542,2742,1537,2732,1533,2724,1516,2695,1540,2738,}, + } +}; + +#define TX_NUM_TPK_FIND9 (14) +#define RX_NUM_TPK_FIND9 (27) +const int16_t raw_cap_data_tpk_find9[TX_NUM_TPK_FIND9*2][RX_NUM_TPK_FIND9*2] = +{ + //update base line data, 2014/03/25 + // enable cbc + {876,2044,846,1973,842,1964,853,1990,857,2000,857,2000,859,2004,857,1999,857,2000,853,1991,849,1981,856,1998,848,1980,854,1992,734,1712,724,1690,725,1692,718,1674,718,1675,716,1670,708,1653,698,1628,684,1596,681,1590,690,1610,700,1634,761,1775}, + {860,2006,832,1942,823,1920,826,1928,825,1924,824,1922,822,1917,818,1910,818,1908,813,1898,808,1886,816,1903,804,1875,800,1867,783,1828,762,1779,764,1782,755,1762,762,1778,744,1736,744,1736,736,1718,724,1690,727,1696,735,1716,755,1761,883,2060}, + {843,1968,819,1912,816,1904,820,1914,819,1912,818,1908,816,1904,812,1895,812,1896,806,1880,801,1870,802,1871,797,1860,792,1848,770,1798,762,1778,762,1778,763,1780,755,1762,747,1744,748,1746,738,1722,728,1698,736,1718,752,1754,777,1812,889,2074}, + {831,1938,815,1901,813,1898,820,1913,818,1908,817,1906,813,1896,809,1888,808,1886,804,1875,799,1864,799,1864,795,1854,789,1842,772,1801,765,1785,772,1801,758,1770,757,1766,752,1756,751,1752,742,1731,730,1704,730,1704,740,1726,765,1785,866,2020}, + {821,1916,809,1887,810,1889,816,1903,814,1900,813,1898,811,1891,806,1882,806,1882,800,1867,797,1860,797,1860,795,1855,787,1837,777,1814,777,1812,770,1796,762,1779,764,1782,756,1764,754,1760,745,1739,734,1713,744,1736,762,1778,789,1841,896,2090}, + {819,1910,806,1880,803,1874,812,1894,810,1890,809,1887,805,1878,802,1872,800,1867,795,1855,791,1846,792,1848,791,1845,782,1826,786,1834,770,1796,768,1792,762,1778,761,1775,756,1763,755,1762,745,1737,733,1709,735,1714,749,1747,775,1808,879,2050}, + {827,1930,808,1885,806,1880,819,1911,810,1890,809,1887,807,1884,803,1874,801,1868,794,1852,789,1842,791,1845,790,1844,782,1824,784,1829,774,1806,773,1803,764,1784,764,1783,758,1768,759,1772,747,1742,737,1719,737,1720,750,1751,775,1808,879,2052}, + {823,1921,802,1872,799,1865,806,1881,813,1896,803,1873,802,1871,798,1862,795,1855,789,1842,783,1828,785,1831,786,1833,778,1815,782,1826,774,1806,772,1802,765,1786,764,1782,758,1768,758,1768,747,1742,735,1716,737,1720,749,1747,774,1806,860,2006}, + {819,1912,799,1865,798,1862,804,1875,804,1875,809,1888,800,1866,794,1854,793,1849,787,1836,781,1822,782,1826,782,1826,773,1803,785,1832,776,1811,776,1810,769,1793,769,1794,760,1774,762,1778,751,1752,740,1727,740,1726,752,1756,777,1814,870,2029}, + {811,1893,794,1852,792,1848,799,1864,798,1862,796,1858,801,1870,790,1844,789,1842,783,1827,777,1812,778,1816,777,1814,768,1792,787,1835,778,1816,776,1810,769,1794,769,1793,761,1776,761,1776,751,1752,739,1724,740,1728,752,1755,777,1814,874,2040}, + {812,1894,792,1848,791,1845,794,1852,794,1854,792,1848,790,1844,796,1857,787,1836,781,1821,775,1809,776,1811,773,1804,764,1782,807,1882,780,1820,780,1820,771,1800,771,1799,764,1783,764,1784,754,1758,743,1734,744,1736,756,1763,781,1821,911,2125}, + {806,1881,787,1835,782,1826,787,1836,786,1834,784,1830,783,1826,779,1818,785,1832,773,1803,767,1790,768,1792,765,1785,758,1768,796,1856,780,1820,778,1815,770,1798,771,1798,764,1782,763,1780,753,1758,742,1731,743,1734,753,1758,778,1815,879,2052}, + {812,1894,789,1842,789,1840,791,1846,792,1847,789,1840,786,1834,781,1822,780,1820,782,1826,770,1796,771,1798,769,1793,760,1773,834,1945,800,1866,799,1865,788,1839,790,1844,782,1824,781,1822,771,1799,760,1773,760,1773,771,1800,788,1838,849,1982}, + {784,1830,759,1770,757,1767,765,1785,763,1780,759,1770,754,1760,749,1748,747,1744,742,1731,743,1734,735,1716,733,1710,726,1693,1044,2435,955,2228,934,2179,889,2073,881,2055,864,2016,859,2004,847,1975,829,1934,824,1924,834,1946,851,1986,923,2154}, + + //disable + {1022,1898,987,1832,982,1824,995,1847,1000,1857,1000,1857,1002,1860,1000,1856,1000,1857,996,1849,991,1839,999,1855,990,1838,996,1849,856,1589,845,1569,846,1571,837,1555,838,1555,835,1551,827,1535,814,1512,798,1482,795,1477,805,1495,817,1517,888,1648}, + {1003,1862,971,1803,960,1783,964,1791,962,1787,961,1785,959,1780,955,1773,954,1771,949,1762,943,1751,952,1767,938,1741,934,1734,914,1697,890,1652,891,1654,881,1636,889,1650,868,1612,868,1612,859,1595,845,1569,848,1575,858,1593,881,1635,1030,1912}, + {984,1827,956,1775,952,1768,957,1777,956,1775,954,1771,952,1768,948,1759,948,1760,940,1745,935,1737,936,1737,930,1727,924,1716,899,1669,889,1650,889,1650,890,1652,881,1636,872,1619,873,1621,861,1599,849,1577,859,1595,877,1629,906,1682,1037,1926}, + {969,1800,951,1765,949,1762,957,1776,954,1771,953,1769,948,1761,944,1753,943,1751,938,1741,932,1731,932,1731,927,1722,921,1710,901,1672,893,1658,901,1672,885,1643,883,1640,878,1630,876,1626,866,1608,852,1582,852,1582,863,1602,893,1658,1010,1876}, + {958,1779,944,1752,945,1754,952,1767,950,1764,949,1762,946,1756,941,1747,941,1747,934,1734,930,1727,930,1727,928,1722,919,1706,907,1684,906,1683,898,1667,890,1652,891,1654,882,1638,880,1634,870,1615,857,1591,868,1612,889,1651,921,1709,1045,1940}, + {955,1774,940,1745,937,1740,947,1759,945,1755,944,1752,939,1744,936,1738,934,1734,928,1722,923,1714,924,1716,923,1713,913,1695,917,1702,898,1667,896,1664,889,1650,888,1648,882,1637,881,1636,869,1613,855,1587,857,1591,874,1622,904,1678,1025,1904}, + {965,1792,943,1751,940,1745,956,1775,945,1755,944,1752,942,1749,937,1740,934,1735,926,1720,921,1710,923,1713,922,1712,912,1693,915,1698,903,1676,902,1674,892,1656,892,1656,884,1642,886,1645,871,1618,860,1596,860,1597,876,1626,904,1679,1026,1905}, + {961,1784,936,1738,933,1732,941,1747,948,1761,937,1739,936,1737,931,1729,928,1722,921,1710,914,1697,916,1700,917,1702,908,1685,913,1695,903,1676,901,1673,893,1658,891,1655,884,1642,884,1642,871,1618,858,1593,860,1597,874,1622,903,1677,1003,1863}, + {956,1775,933,1732,931,1729,938,1741,938,1741,944,1753,933,1733,927,1721,925,1717,918,1705,911,1692,913,1695,913,1695,902,1674,916,1701,906,1682,905,1680,897,1665,897,1666,887,1647,889,1650,876,1626,864,1604,863,1603,878,1630,907,1684,1015,1884}, + {947,1758,926,1719,924,1716,932,1731,931,1729,929,1725,935,1736,922,1712,921,1710,914,1696,906,1682,908,1686,907,1684,896,1664,918,1704,908,1686,905,1681,897,1666,897,1665,888,1649,888,1649,876,1626,862,1601,864,1604,878,1630,907,1684,1020,1894}, + {947,1759,924,1716,923,1713,926,1720,927,1721,924,1716,922,1712,929,1724,918,1704,911,1691,905,1680,906,1682,902,1675,891,1654,941,1748,910,1690,910,1690,900,1671,900,1670,892,1656,892,1656,879,1633,867,1610,868,1612,882,1637,911,1691,1063,1973}, + {941,1747,918,1704,913,1695,918,1704,917,1703,915,1700,913,1696,909,1688,916,1701,902,1674,895,1662,896,1664,893,1658,884,1642,928,1724,910,1690,908,1685,899,1669,899,1670,891,1654,890,1652,879,1632,866,1608,867,1610,879,1632,908,1685,1026,1905}, + {947,1759,921,1710,920,1708,923,1714,924,1715,920,1708,917,1703,911,1692,910,1690,913,1695,898,1667,899,1670,897,1665,887,1646,973,1806,933,1733,933,1732,920,1708,922,1712,912,1694,911,1692,900,1670,887,1646,887,1646,900,1671,919,1706,991,1840}, + {915,1700,885,1644,884,1641,893,1658,890,1652,885,1644,880,1634,874,1623,872,1619,866,1608,867,1610,858,1593,855,1588,847,1572,1218,2261,1114,2069,1090,2023,1037,1925,1028,1908,1008,1872,1002,1860,988,1834,967,1795,962,1786,973,1807,993,1843,1077,2000} +}; + +#define TX_NUM_YOUNGFAST (15) +#define RX_NUM_YOUNGFAST (28) +#define DiagonalUpperLimit_YOUNGFAST (1100) +#define DiagonalLowerLimit_YOUNGFAST (900) +const int16_t raw_cap_data_youngfast[TX_NUM_YOUNGFAST][RX_NUM_YOUNGFAST*2] = +{ + {1874,3123,1837,3062,1816,3027,1791,2985,1770,2949,1750,2917,1733,2888,1716,2859,1698,2830,1696,2826,1665,2775,1655,2758,1625,2708,1680,2800,1485,2475,1555,2592,1530,2551,1522,2537,1505,2509,1502,2503,1485,2476,1479,2465,1469,2448,1465,2442,1459,2432,1456,2426,1458,2430,1367,2279,}, + {1880,3133,1844,3074,1824,3040,1802,3003,1781,2968,1761,2934,1744,2906,1725,2875,1707,2845,1691,2818,1674,2790,1656,2760,1636,2726,1688,2814,1509,2516,1570,2616,1546,2577,1538,2563,1520,2534,1516,2527,1500,2500,1494,2490,1483,2472,1479,2465,1474,2456,1471,2451,1474,2456,1387,2312,}, + {1870,3117,1843,3071,1822,3036,1798,2996,1776,2960,1756,2927,1739,2899,1721,2868,1703,2838,1719,2865,1670,2782,1651,2752,1633,2721,1666,2777,1519,2531,1568,2613,1546,2577,1538,2564,1519,2531,1516,2526,1499,2499,1493,2488,1483,2471,1479,2466,1472,2454,1469,2448,1469,2449,1383,2304,}, + {1865,3108,1843,3071,1820,3033,1797,2996,1775,2958,1754,2924,1746,2911,1719,2865,1702,2836,1709,2849,1665,2774,1647,2745,1628,2714,1653,2754,1529,2548,1570,2617,1549,2582,1540,2568,1522,2536,1518,2530,1502,2503,1494,2490,1484,2474,1480,2467,1475,2458,1472,2453,1473,2455,1395,2326,}, + {1857,3096,1841,3069,1819,3031,1796,2993,1774,2956,1754,2923,1736,2894,1727,2878,1699,2832,1708,2846,1661,2769,1644,2741,1628,2713,1640,2733,1541,2568,1571,2618,1551,2585,1543,2572,1523,2538,1519,2532,1503,2504,1497,2495,1487,2479,1484,2473,1478,2464,1476,2460,1477,2461,1403,2339,}, + {1863,3104,1838,3064,1817,3028,1793,2988,1771,2952,1751,2919,1734,2890,1715,2859,1695,2826,1692,2819,1656,2761,1640,2733,1624,2706,1625,2708,1551,2584,1571,2618,1552,2586,1542,2571,1523,2539,1520,2534,1504,2506,1498,2497,1489,2481,1485,2475,1480,2466,1477,2461,1477,2462,1409,2349,}, + {1865,3109,1838,3063,1813,3022,1799,2998,1769,2948,1748,2914,1730,2884,1712,2853,1691,2819,1672,2786,1652,2753,1636,2727,1620,2700,1610,2683,1562,2602,1571,2618,1553,2588,1544,2573,1525,2541,1523,2538,1507,2512,1501,2501,1490,2484,1487,2479,1483,2471,1480,2466,1479,2465,1417,2362,}, + {1867,3111,1836,3061,1813,3022,1790,2984,1776,2960,1747,2911,1728,2879,1708,2847,1688,2813,1668,2780,1648,2746,1632,2720,1619,2698,1598,2664,1575,2625,1574,2623,1556,2594,1547,2579,1529,2549,1527,2545,1511,2518,1504,2508,1496,2493,1492,2487,1487,2478,1483,2471,1481,2468,1418,2363,}, + {1866,3110,1843,3071,1814,3024,1789,2981,1766,2943,1744,2908,1725,2875,1705,2842,1684,2807,1665,2775,1644,2740,1629,2716,1618,2697,1588,2647,1588,2647,1575,2625,1559,2598,1551,2585,1535,2558,1531,2552,1515,2526,1507,2512,1498,2497,1496,2493,1490,2484,1486,2477,1486,2477,1434,2389,}, + {1864,3107,1835,3058,1819,3031,1788,2979,1765,2942,1744,2906,1724,2873,1704,2840,1684,2807,1665,2775,1644,2740,1630,2716,1618,2697,1579,2632,1604,2673,1580,2633,1565,2608,1557,2596,1539,2565,1535,2559,1521,2535,1514,2523,1504,2507,1501,2501,1496,2493,1492,2486,1494,2489,1446,2410,}, + {1866,3110,1834,3057,1829,3048,1788,2980,1764,2941,1743,2904,1724,2873,1704,2840,1684,2807,1666,2776,1645,2741,1632,2720,1621,2702,1571,2619,1620,2700,1585,2642,1572,2619,1562,2604,1542,2571,1540,2567,1525,2541,1519,2531,1509,2516,1507,2511,1502,2503,1500,2499,1500,2501,1466,2443,}, + {1871,3118,1836,3060,1811,3018,1788,2980,1765,2942,1745,2908,1725,2874,1705,2842,1685,2809,1677,2796,1647,2745,1633,2722,1631,2718,1563,2605,1639,2731,1594,2656,1580,2633,1570,2616,1550,2583,1548,2580,1531,2551,1524,2541,1516,2527,1513,2522,1510,2516,1507,2512,1516,2526,1469,2448,}, + {1877,3128,1836,3059,1820,3033,1789,2981,1766,2943,1744,2906,1725,2875,1706,2843,1685,2809,1666,2777,1646,2743,1632,2721,1623,2705,1552,2586,1652,2753,1597,2661,1586,2643,1574,2623,1556,2594,1554,2589,1536,2560,1531,2551,1522,2536,1529,2549,1517,2529,1515,2524,1513,2522,1474,2456,}, + {1880,3134,1837,3062,1811,3019,1790,2984,1766,2944,1744,2907,1726,2876,1706,2843,1684,2807,1666,2777,1646,2743,1632,2721,1625,2708,1542,2571,1674,2790,1609,2681,1592,2653,1583,2639,1565,2608,1562,2603,1545,2575,1540,2566,1532,2553,1530,2550,1528,2546,1524,2540,1534,2556,1494,2490,}, + {1930,3216,1821,3035,1800,3001,1772,2953,1752,2920,1727,2879,1709,2849,1688,2814,1667,2779,1649,2748,1629,2715,1617,2695,1608,2681,1517,2529,1683,2805,1591,2652,1585,2641,1573,2622,1556,2593,1553,2588,1538,2563,1541,2569,1524,2540,1524,2539,1518,2530,1515,2526,1515,2524,1495,2492,}, +}; + +#define TX_NUM_JDI (30) +#define RX_NUM_JDI (17) +#define DiagonalUpperLimit_JDI (1100) +#define DiagonalLowerLimit_JDI (900) +const int16_t raw_cap_data_JDI[2][TX_NUM_JDI][RX_NUM_JDI*2] = +{ + //enable cbc + { + {1533,2299,1567,2351,1578,2366,1614,2422,1505,2257,1482,2224,1478,2216,1463,2195,1482,2224,1472,2208,1490,2234,1486,2230,1490,2236,1545,2317,1590,2386,1603,2405,1575,2363,}, + {1475,2213,1511,2267,1525,2287,1561,2341,1449,2173,1428,2142,1425,2137,1408,2112,1418,2126,1418,2126,1438,2158,1432,2148,1433,2149,1489,2233,1536,2304,1546,2320,1522,2284,}, + {1475,2213,1513,2269,1526,2290,1563,2345,1450,2176,1429,2143,1425,2137,1406,2110,1418,2126,1418,2128,1438,2158,1432,2148,1434,2152,1487,2231,1538,2308,1550,2324,1525,2287,}, + {1481,2221,1520,2280,1533,2299,1567,2351,1455,2183,1436,2154,1430,2146,1413,2119,1423,2135,1422,2134,1444,2166,1438,2158,1439,2159,1495,2243,1545,2317,1555,2333,1532,2298,}, + {1484,2226,1520,2280,1535,2303,1570,2354,1454,2182,1435,2153,1430,2146,1414,2122,1422,2134,1425,2137,1446,2168,1439,2159,1442,2162,1490,2236,1543,2315,1556,2334,1533,2299,}, + {1489,2233,1526,2288,1542,2312,1574,2362,1462,2192,1439,2159,1435,2153,1418,2126,1429,2143,1429,2143,1450,2176,1444,2166,1445,2167,1497,2245,1548,2322,1559,2339,1536,2304,}, + {1492,2238,1532,2298,1546,2318,1579,2369,1466,2198,1447,2171,1442,2162,1426,2138,1432,2148,1434,2152,1454,2180,1448,2172,1449,2173,1503,2255,1553,2329,1564,2346,1539,2309,}, + {1494,2240,1533,2299,1548,2322,1582,2372,1468,2202,1449,2173,1444,2166,1426,2138,1438,2156,1438,2158,1458,2186,1450,2176,1453,2179,1504,2256,1554,2332,1568,2352,1542,2314,}, + {1498,2246,1538,2306,1550,2324,1584,2376,1470,2206,1453,2179,1447,2171,1426,2140,1436,2154,1438,2158,1458,2186,1454,2180,1454,2182,1504,2256,1558,2338,1571,2357,1546,2318,}, + {1501,2251,1542,2314,1554,2332,1587,2381,1474,2212,1454,2182,1448,2172,1432,2148,1441,2161,1442,2162,1461,2191,1458,2186,1458,2186,1510,2266,1562,2342,1575,2363,1550,2324,}, + {1502,2254,1543,2315,1555,2333,1589,2383,1478,2216,1458,2188,1453,2179,1432,2148,1444,2166,1442,2164,1465,2197,1458,2188,1460,2190,1513,2269,1564,2346,1574,2362,1550,2324,}, + {1507,2261,1549,2323,1561,2341,1594,2392,1482,2224,1461,2191,1455,2183,1438,2158,1446,2168,1448,2172,1467,2201,1464,2196,1463,2195,1514,2270,1570,2354,1579,2369,1554,2332,}, + {1514,2270,1554,2332,1567,2351,1601,2401,1486,2230,1467,2201,1461,2191,1442,2162,1450,2176,1454,2180,1471,2207,1467,2201,1468,2202,1520,2280,1572,2358,1586,2378,1558,2338,}, + {1518,2278,1558,2338,1571,2357,1606,2410,1492,2238,1471,2207,1465,2197,1448,2172,1458,2186,1458,2188,1478,2216,1471,2207,1474,2210,1526,2288,1578,2368,1590,2386,1564,2346,}, + {1516,2274,1558,2336,1571,2357,1606,2408,1490,2236,1470,2206,1465,2197,1447,2171,1457,2185,1455,2183,1477,2215,1469,2203,1472,2208,1523,2285,1574,2362,1588,2382,1561,2341,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1494,2240,1474,2212,1469,2203,1450,2176,1458,2186,1460,2190,1481,2221,1474,2210,1474,2212,1526,2290,1578,2368,1590,2386,1565,2347,}, + {1520,2280,1561,2341,1574,2360,1609,2413,1493,2239,1474,2212,1468,2202,1449,2173,1458,2188,1461,2191,1480,2220,1475,2213,1475,2213,1526,2290,1577,2365,1589,2383,1565,2347,}, + {1520,2280,1564,2346,1577,2365,1612,2418,1496,2244,1478,2216,1471,2207,1454,2180,1462,2192,1462,2192,1482,2224,1478,2216,1477,2215,1528,2292,1579,2369,1592,2388,1566,2350,}, + {1519,2279,1563,2345,1575,2363,1610,2414,1497,2245,1475,2213,1471,2207,1451,2177,1460,2190,1462,2192,1482,2224,1475,2213,1475,2213,1526,2288,1578,2368,1592,2388,1564,2346,}, + {1522,2282,1564,2346,1577,2365,1612,2418,1496,2244,1477,2215,1470,2206,1454,2180,1462,2192,1462,2192,1481,2221,1477,2215,1478,2216,1526,2290,1579,2369,1592,2388,1564,2346,}, + {1522,2282,1564,2346,1577,2365,1610,2416,1498,2246,1477,2215,1470,2206,1454,2180,1462,2192,1462,2192,1481,2221,1477,2215,1477,2215,1528,2292,1581,2371,1592,2388,1564,2346,}, + {1519,2279,1562,2342,1574,2362,1609,2413,1495,2243,1474,2210,1469,2203,1449,2173,1458,2188,1461,2191,1480,2220,1474,2210,1474,2212,1522,2282,1577,2365,1590,2386,1562,2342,}, + {1522,2282,1562,2342,1577,2365,1610,2414,1495,2243,1474,2212,1468,2202,1451,2177,1458,2186,1461,2191,1480,2220,1474,2212,1474,2210,1523,2285,1577,2365,1589,2383,1564,2346,}, + {1516,2274,1559,2339,1572,2358,1606,2408,1492,2238,1470,2206,1466,2198,1449,2173,1455,2183,1455,2183,1475,2213,1470,2206,1470,2206,1520,2280,1572,2358,1586,2378,1559,2339,}, + {1515,2273,1558,2336,1572,2358,1604,2406,1490,2234,1470,2206,1464,2196,1446,2168,1454,2180,1455,2183,1475,2213,1468,2202,1469,2203,1517,2275,1571,2357,1582,2374,1555,2333,}, + {1510,2266,1555,2333,1570,2354,1600,2400,1486,2228,1465,2197,1462,2192,1442,2164,1454,2180,1454,2180,1472,2208,1466,2198,1466,2198,1517,2275,1568,2352,1578,2368,1553,2329,}, + {1507,2261,1549,2323,1561,2341,1596,2394,1480,2220,1461,2191,1455,2183,1435,2153,1444,2166,1445,2167,1467,2201,1461,2191,1460,2190,1510,2264,1562,2342,1574,2362,1546,2320,}, + {1502,2254,1542,2314,1558,2336,1589,2383,1474,2212,1454,2180,1450,2176,1429,2143,1438,2158,1441,2161,1460,2190,1454,2182,1455,2183,1502,2254,1559,2339,1570,2354,1543,2315,}, + {1499,2249,1539,2309,1550,2324,1584,2376,1469,2203,1448,2172,1444,2166,1425,2137,1435,2153,1435,2153,1454,2182,1450,2176,1448,2172,1499,2249,1551,2327,1563,2345,1538,2306,}, + {1529,2293,1572,2358,1585,2377,1619,2429,1502,2254,1484,2226,1481,2221,1461,2191,1469,2203,1469,2203,1490,2236,1482,2224,1482,2224,1529,2293,1585,2377,1597,2395,1571,2357,}, + }, + //disable cbc + { + {1534,2302,1567,2351,1578,2368,1614,2422,1505,2257,1483,2225,1475,2213,1463,2195,1482,2224,1474,2210,1492,2238,1487,2231,1490,2236,1546,2318,1589,2383,1602,2404,1577,2365,}, + {1474,2212,1511,2267,1526,2288,1561,2341,1449,2173,1429,2143,1423,2135,1408,2112,1418,2126,1418,2126,1438,2158,1433,2149,1435,2153,1489,2233,1536,2304,1548,2322,1523,2285,}, + {1475,2213,1515,2273,1529,2293,1562,2342,1451,2177,1430,2146,1426,2140,1408,2112,1419,2129,1419,2129,1438,2158,1432,2148,1435,2153,1490,2234,1538,2306,1551,2327,1526,2288,}, + {1480,2220,1518,2278,1532,2298,1567,2351,1455,2183,1435,2153,1429,2143,1411,2117,1422,2132,1422,2134,1442,2164,1438,2156,1438,2156,1492,2238,1542,2314,1556,2334,1531,2297,}, + {1482,2224,1520,2280,1535,2303,1568,2352,1454,2182,1435,2153,1429,2143,1413,2119,1425,2137,1422,2134,1444,2166,1438,2158,1438,2158,1492,2238,1543,2315,1556,2334,1531,2297,}, + {1487,2231,1526,2290,1538,2308,1572,2358,1462,2192,1442,2162,1436,2154,1419,2129,1428,2142,1429,2143,1448,2172,1444,2166,1446,2168,1498,2246,1546,2320,1559,2339,1538,2306,}, + {1493,2239,1530,2294,1543,2315,1578,2368,1466,2198,1447,2171,1442,2162,1423,2135,1434,2152,1435,2153,1455,2183,1449,2173,1448,2172,1501,2251,1551,2327,1565,2347,1540,2310,}, + {1494,2240,1534,2302,1546,2320,1582,2372,1468,2202,1451,2177,1446,2168,1429,2143,1438,2158,1438,2156,1455,2183,1450,2176,1453,2179,1504,2256,1555,2333,1568,2352,1540,2310,}, + {1494,2240,1536,2304,1550,2324,1586,2378,1472,2208,1454,2180,1447,2171,1429,2143,1438,2158,1438,2158,1458,2186,1453,2179,1454,2182,1506,2260,1556,2334,1570,2356,1546,2318,}, + {1499,2249,1539,2309,1551,2327,1587,2381,1474,2210,1454,2180,1446,2168,1430,2146,1439,2159,1441,2161,1458,2188,1457,2185,1457,2185,1507,2261,1561,2341,1572,2358,1546,2318,}, + {1504,2256,1545,2317,1558,2336,1589,2383,1477,2215,1458,2188,1453,2179,1433,2149,1442,2164,1447,2171,1464,2196,1458,2186,1462,2192,1513,2269,1565,2347,1577,2365,1551,2327,}, + {1510,2264,1550,2324,1562,2342,1594,2392,1480,2220,1461,2191,1455,2183,1438,2158,1447,2171,1448,2172,1469,2203,1464,2196,1465,2197,1516,2274,1568,2352,1579,2369,1555,2333,}, + {1513,2269,1552,2328,1566,2350,1599,2399,1486,2228,1466,2198,1460,2190,1441,2161,1451,2177,1453,2179,1474,2212,1467,2201,1466,2198,1520,2280,1572,2358,1582,2374,1558,2338,}, + {1511,2267,1552,2328,1568,2352,1604,2406,1486,2230,1467,2201,1464,2196,1442,2164,1451,2177,1454,2180,1474,2210,1468,2202,1469,2203,1520,2280,1572,2358,1585,2377,1558,2338,}, + {1516,2274,1558,2338,1571,2357,1606,2408,1490,2236,1470,2206,1467,2201,1448,2172,1457,2185,1458,2188,1478,2218,1471,2207,1472,2208,1525,2287,1575,2363,1588,2382,1563,2345,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1494,2240,1472,2208,1468,2202,1451,2177,1458,2188,1458,2188,1480,2220,1474,2212,1477,2215,1525,2287,1578,2366,1590,2386,1564,2346,}, + {1522,2282,1562,2342,1574,2362,1609,2413,1496,2244,1474,2212,1468,2202,1451,2177,1460,2190,1461,2191,1481,2221,1477,2215,1477,2215,1528,2292,1579,2369,1590,2386,1564,2346,}, + {1522,2282,1561,2341,1574,2362,1609,2413,1495,2243,1474,2210,1470,2206,1450,2176,1458,2188,1460,2190,1480,2220,1475,2213,1475,2213,1526,2288,1578,2366,1591,2387,1561,2341,}, + {1518,2278,1561,2341,1577,2365,1612,2418,1497,2245,1475,2213,1471,2207,1453,2179,1461,2191,1461,2191,1480,2220,1474,2210,1474,2212,1525,2287,1577,2365,1590,2386,1563,2345,}, + {1523,2285,1564,2346,1577,2365,1612,2418,1496,2244,1478,2216,1470,2206,1454,2180,1462,2192,1462,2192,1483,2225,1478,2216,1477,2215,1528,2292,1582,2372,1594,2390,1565,2347,}, + {1522,2282,1563,2345,1577,2365,1610,2414,1496,2244,1475,2213,1470,2206,1453,2179,1461,2191,1460,2190,1480,2220,1474,2212,1474,2212,1528,2292,1578,2366,1590,2386,1564,2346,}, + {1519,2279,1562,2342,1574,2360,1607,2411,1494,2240,1474,2212,1467,2201,1449,2173,1458,2186,1461,2191,1478,2218,1474,2210,1474,2212,1525,2287,1578,2366,1590,2386,1563,2345,}, + {1520,2280,1563,2345,1574,2360,1607,2411,1495,2243,1474,2210,1467,2201,1450,2176,1458,2188,1461,2191,1478,2216,1474,2210,1474,2210,1522,2284,1578,2366,1588,2382,1563,2345,}, + {1517,2275,1558,2338,1574,2360,1606,2408,1489,2233,1470,2206,1464,2196,1447,2171,1454,2182,1458,2186,1477,2215,1471,2207,1471,2207,1519,2279,1574,2360,1585,2377,1559,2339,}, + {1513,2269,1558,2336,1571,2357,1606,2408,1490,2234,1470,2206,1465,2197,1445,2167,1454,2182,1455,2183,1474,2212,1469,2203,1470,2206,1517,2275,1571,2357,1584,2376,1555,2333,}, + {1510,2266,1552,2328,1566,2350,1600,2400,1486,2228,1464,2196,1460,2190,1442,2162,1451,2177,1450,2176,1470,2206,1464,2196,1465,2197,1514,2270,1566,2350,1578,2366,1552,2328,}, + {1507,2261,1549,2323,1561,2341,1594,2390,1480,2220,1463,2195,1454,2182,1438,2156,1446,2168,1446,2168,1465,2197,1461,2191,1458,2188,1510,2264,1562,2342,1574,2360,1548,2322,}, + {1501,2251,1543,2315,1556,2334,1589,2383,1474,2210,1454,2182,1449,2173,1430,2146,1439,2159,1441,2161,1461,2191,1455,2183,1454,2182,1502,2254,1556,2334,1570,2354,1542,2314,}, + {1498,2246,1540,2310,1551,2327,1582,2374,1470,2206,1450,2176,1446,2168,1426,2138,1434,2152,1434,2152,1457,2185,1450,2176,1451,2177,1500,2250,1552,2328,1564,2346,1538,2308,}, + {1530,2294,1574,2360,1586,2378,1618,2426,1503,2255,1486,2230,1482,2224,1462,2192,1469,2203,1469,2203,1493,2239,1486,2228,1483,2225,1530,2294,1586,2378,1599,2399,1572,2358,}, + } +}; +#endif diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 95578dcf2fee0..350b3a41c8d54 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -268,6 +268,11 @@ void gic_show_pending_irq(void) } } +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ +extern char wakeup_reason[32]; +#endif /* VENDOR_EDIT */ + static void gic_show_resume_irq(struct gic_chip_data *gic) { unsigned int i; @@ -299,6 +304,11 @@ static void gic_show_resume_irq(struct gic_chip_data *gic) pr_warning("%s: %d triggered %s\n", __func__, i + gic->irq_offset, name); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + if(!wakeup_reason[0]) + strncpy(wakeup_reason,name,sizeof(wakeup_reason) -1); +#endif /* VENDOR_EDIT */ } } diff --git a/drivers/irqchip/msm_show_resume_irq.c b/drivers/irqchip/msm_show_resume_irq.c index 4a796207738fd..f32b876b56b22 100644 --- a/drivers/irqchip/msm_show_resume_irq.c +++ b/drivers/irqchip/msm_show_resume_irq.c @@ -15,7 +15,10 @@ #include #include -int msm_show_resume_irq_mask; +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ +int msm_show_resume_irq_mask =1; +#endif /* VENDOR_EDIT */ module_param_named( debug_mask, msm_show_resume_irq_mask, int, S_IRUGO | S_IWUSR | S_IWGRP diff --git a/drivers/leds/leds-qpnp-flash.c b/drivers/leds/leds-qpnp-flash.c index b1d24d284cb36..92ca1aaba6753 100644 --- a/drivers/leds/leds-qpnp-flash.c +++ b/drivers/leds/leds-qpnp-flash.c @@ -25,7 +25,17 @@ #include #include #include "leds.h" - +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150413 for product mode flashlight +#include +#include +struct qpnp_flash_led *proc_led =NULL ; +#endif /*VENDOR_EDIT*/ +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#include +#define FLASH_MAIN_CLOSE_BACKLIGHT +#endif #define FLASH_LED_PERIPHERAL_SUBTYPE(base) (base + 0x05) #define FLASH_SAFETY_TIMER(base) (base + 0x40) #define FLASH_MAX_CURRENT(base) (base + 0x41) @@ -160,6 +170,14 @@ struct flash_node_data { u8 trigger; u8 enable; bool flash_on; +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + bool backlight_flag; + char backlight_buf[10]; + struct delayed_work backlight_work; +#endif +#endif }; /* @@ -184,7 +202,13 @@ struct flash_led_platform_data { bool hdrm_sns_ch1_en; bool power_detect_en; }; +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150413 for product mode flashlight + +bool flash_blink_state; +int led_flash_state; +#endif /*VENDOR_EDIT*/ /* * Flash LED data structure containing flash LED attributes */ @@ -566,7 +590,63 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev) { return led_cdev->brightness; } - +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT +static int qpnp_flash_led_backlight_set(char *brightness_new) +{ + int fd = -1; + int ret = -1; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + fd = sys_open("/sys/class/leds/lcd-backlight/brightness", O_RDWR, 0); + if(fd < 0){ + pr_err("%s:failed to open the backlight node,fd = %d\n", __func__,fd); + set_fs(old_fs); + return -1; + } + ret = sys_write(fd, brightness_new, strlen(brightness_new)); + if(ret < 0){ + pr_err("%s:failed to set brightness,ret = %d\n",__func__,ret); + sys_close(fd); + set_fs(old_fs); + return -1; + } + pr_debug("%s:set the backlight brightness:%s\n", __func__,brightness_new); + sys_close(fd); + set_fs(old_fs); + return 0; +} +static int qpnp_flash_led_backlight_get(char *brightness_old) +{ + int fd = -1; + int ret = -1; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + fd = sys_open("/sys/class/leds/lcd-backlight/brightness", O_RDWR, 0); + if(fd < 0){ + pr_err("%s:failed to open the backlight node,fd = %d\n", __func__,fd); + set_fs(old_fs); + return -1; + } + ret = sys_read(fd, brightness_old, sizeof(brightness_old)); + if(ret < 0){ + pr_err("%s:failed to get brightness,ret = %d\n",__func__,ret); + sys_close(fd); + set_fs(old_fs); + return -1; + } + pr_debug("%s:get the backlight brightness:%s\n", __func__,brightness_old); + sys_close(fd); + set_fs(old_fs); + return 0; +} +#endif +#endif static void qpnp_flash_led_work(struct work_struct *work) { struct flash_node_data *flash_node = container_of(work, @@ -577,6 +657,12 @@ static void qpnp_flash_led_work(struct work_struct *work) int rc, brightness = flash_node->cdev.brightness; int max_curr_avail_ma; u8 val; +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + char brightness_new[10]="0"; +#endif +#endif mutex_lock(&led->flash_led_lock); @@ -724,7 +810,24 @@ static void qpnp_flash_led_work(struct work_struct *work) "Max current reg write failed\n"); goto exit_flash_led_work; } - +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + if(flash_node->prgm_current>LED_FULL&&!flash_node->backlight_flag&&!flash_node->id){ + flash_node->backlight_flag = true; + rc = qpnp_flash_led_backlight_get(flash_node->backlight_buf); + if(rc < 0){ + pr_err("Invalid get back light\n"); + goto turn_off; + } + rc = qpnp_flash_led_backlight_set(brightness_new); + if(rc < 0){ + pr_err("Invalid set back light\n"); + goto turn_off; + } + } +#endif +#endif val = (u8)(flash_node->prgm_current * FLASH_MAX_LEVEL / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, @@ -735,7 +838,6 @@ static void qpnp_flash_led_work(struct work_struct *work) "Current reg write failed\n"); goto exit_flash_led_work; } - rc = qpnp_led_masked_write(led->spmi_dev, FLASH_MODULE_ENABLE_CTRL(led->base), FLASH_MODULE_ENABLE | @@ -763,10 +865,10 @@ static void qpnp_flash_led_work(struct work_struct *work) flash_node->flash_on = true; mutex_unlock(&led->flash_led_lock); - return; turn_off: + rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), flash_node->trigger, FLASH_LED_DISABLE); @@ -791,12 +893,58 @@ static void qpnp_flash_led_work(struct work_struct *work) regulator_set_voltage(flash_node->boost_regulator, 0, flash_node->boost_voltage_max); } - +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + if(flash_node->backlight_flag&&LED_OFF == brightness&&!flash_node->id){ + flash_node->backlight_flag = false; + if(flash_node->backlight_buf){ + rc = qpnp_flash_led_backlight_set(flash_node->backlight_buf); + if(rc < 0){ + pr_err("Invalid set back light\n"); + } + }else{ + pr_err("%s:backlight buf is NULL!\n",__func__); + } + cancel_delayed_work_sync(&flash_node->backlight_work); + } +#endif +#endif flash_node->flash_on = false; + mutex_unlock(&led->flash_led_lock); return; } +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT +static void qpnp_flash_led_backlight_work(struct work_struct *work) +{ + struct flash_node_data *flash_node = container_of(work, + struct flash_node_data, backlight_work.work); + struct qpnp_flash_led *led = + dev_get_drvdata(&flash_node->spmi_dev->dev); + int rc; + + mutex_lock(&led->flash_led_lock); + if(flash_node->backlight_flag){ + flash_node->backlight_flag = false; + if(flash_node->backlight_buf){ + rc = qpnp_flash_led_backlight_set(flash_node->backlight_buf); + if(rc < 0){ + pr_err("Invalid set back light\n"); + } + }else{ + pr_err("%s:backlight buf is NULL!\n",__func__); + } + } + + mutex_unlock(&led->flash_led_lock); + return; +} +#endif +#endif static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) @@ -815,7 +963,15 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, flash_node->cdev.brightness = value; schedule_work(&flash_node->work); - +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + if(value>LED_FULL&&!flash_node->id){ + schedule_delayed_work(&flash_node->backlight_work, + msecs_to_jiffies(flash_node->duration+100)); + } +#endif +#endif return; } @@ -1288,7 +1444,140 @@ static int qpnp_flash_led_parse_common_dt( return 0; } +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150413 for product mode flashlight + +static void led_flash_blink_work(struct work_struct *work) +{ + + if (flash_blink_state) { + proc_led->flash_node[0].cdev.brightness = 53; + + qpnp_flash_led_work(&proc_led->flash_node[0].work); + proc_led->flash_node[1].cdev.brightness = 53; + qpnp_flash_led_work(&proc_led->flash_node[1].work); + schedule_delayed_work(&proc_led->flash_node[1].dwork, msecs_to_jiffies(1000)); + } else { + proc_led->flash_node[0].cdev.brightness = 0; + qpnp_flash_led_work(&proc_led->flash_node[0].work); + + proc_led->flash_node[1].cdev.brightness = 0; + + qpnp_flash_led_work(&proc_led->flash_node[1].work); + schedule_delayed_work(&proc_led->flash_node[1].dwork, msecs_to_jiffies(1000)); + + } + + flash_blink_state = !flash_blink_state; + + + return; +} +static void led_flash_blink_stop(void) +{ + + if (led_flash_state == 2) { + flash_blink_state = false; + + cancel_delayed_work_sync(&proc_led->flash_node[1].dwork); + + proc_led->flash_node[0].cdev.brightness = 0; + proc_led->flash_node[1].cdev.brightness = 0; + proc_led->flash_node[2].cdev.brightness = 0; + proc_led->flash_node[3].cdev.brightness = 0; + + qpnp_flash_led_work(&proc_led->flash_node[0].work); + qpnp_flash_led_work(&proc_led->flash_node[1].work); + qpnp_flash_led_work(&proc_led->flash_node[2].work); + qpnp_flash_led_work(&proc_led->flash_node[3].work); + + } else if(led_flash_state == 1 ) { + proc_led->flash_node[0].cdev.brightness = 0; + proc_led->flash_node[1].cdev.brightness = 0; + proc_led->flash_node[2].cdev.brightness = 0; + proc_led->flash_node[3].cdev.brightness = 0; + + qpnp_flash_led_work(&proc_led->flash_node[0].work); + qpnp_flash_led_work(&proc_led->flash_node[1].work); + qpnp_flash_led_work(&proc_led->flash_node[2].work); + qpnp_flash_led_work(&proc_led->flash_node[3].work); + } else { + proc_led->flash_node[0].cdev.brightness = 0; + proc_led->flash_node[1].cdev.brightness = 0; + proc_led->flash_node[2].cdev.brightness = 0; + proc_led->flash_node[3].cdev.brightness = 0; + + qpnp_flash_led_work(&proc_led->flash_node[0].work); + qpnp_flash_led_work(&proc_led->flash_node[1].work); + qpnp_flash_led_work(&proc_led->flash_node[2].work); + qpnp_flash_led_work(&proc_led->flash_node[3].work); + } + + led_flash_state = 0; + +} +int led_test_mode; + +static ssize_t flash_proc_read(struct file *filp, char __user *buff, + size_t len, loff_t *data) + +{ + char value[2] = {0}; + + snprintf(value, sizeof(value), "%d", led_test_mode); + return simple_read_from_buffer(buff, len, data, value,1); +} + +static ssize_t flash_proc_write(struct file *filp, const char __user *buff, + size_t len, loff_t *data) +{ + char temp[1] = {0}; + int state = 0; + + if (copy_from_user(temp, buff, 1)) + return -EFAULT; + sscanf(temp, "%d", &state); + + /*stop it first*/ + + led_flash_blink_stop();//zxw a + + if (state == 2) { + /*blink*/ + flash_blink_state = true; + + INIT_DELAYED_WORK(&proc_led->flash_node[1].dwork, led_flash_blink_work); + schedule_delayed_work(&proc_led->flash_node[1].dwork, msecs_to_jiffies(500)); + } else if(state == 1) { + /*lamp*/ + + led_flash_blink_stop(); + + proc_led->flash_node[2].cdev.brightness = 53; + + qpnp_flash_led_work(&proc_led->flash_node[2].work); + + proc_led->flash_node[3].cdev.brightness = 53; + + qpnp_flash_led_work(&proc_led->flash_node[3].work); + } + else + { + + led_flash_blink_stop(); + } + + led_flash_state = state; + return len; +} + +static const struct file_operations led_test_fops = { + .owner = THIS_MODULE, + .read = flash_proc_read, + .write = flash_proc_write, +}; +#endif /*VENDOR_EDIT*/ static int qpnp_flash_led_probe(struct spmi_device *spmi) { struct qpnp_flash_led *led; @@ -1296,7 +1585,10 @@ static int qpnp_flash_led_probe(struct spmi_device *spmi) struct device_node *node, *temp; int rc, i = 0, j, num_leds = 0; u32 val; - +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150413 for product mode flashlight + struct proc_dir_entry *proc_entry = NULL; +#endif /*VENDOR_EDIT*/ node = spmi->dev.of_node; if (node == NULL) { dev_info(&spmi->dev, "No flash device defined\n"); @@ -1373,6 +1665,13 @@ static int qpnp_flash_led_probe(struct spmi_device *spmi) led->flash_node[i].spmi_dev = spmi; INIT_WORK(&led->flash_node[i].work, qpnp_flash_led_work); +/*muyuezhong@camera,2015-07-23,add this for close backlight on the flash high*/ +#ifdef VENDOR_EDIT +#ifdef FLASH_MAIN_CLOSE_BACKLIGHT + INIT_DELAYED_WORK(&led->flash_node[i].backlight_work, qpnp_flash_led_backlight_work); + led->flash_node[i].backlight_flag = false; +#endif +#endif rc = of_property_read_string(temp, "qcom,led-name", &led->flash_node[i].cdev.name); if (rc < 0) { @@ -1431,7 +1730,20 @@ static int qpnp_flash_led_probe(struct spmi_device *spmi) led->num_leds = i; dev_set_drvdata(&spmi->dev, led); +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150413 for product mode flashlight + if (led->flash_node->id == FLASH_LED_0 || + led->flash_node->id == FLASH_LED_1) { + proc_entry = proc_create_data( "qcom_flash", 0666, NULL,&led_test_fops, NULL); + + if (proc_entry == NULL) { + pr_err("proc_entry create failed\n"); + return rc; + } + } +proc_led=led; +#endif /*VENDOR_EDIT*/ return 0; error_led_register: diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c old mode 100644 new mode 100755 index a6290b8ec3ba0..a4ac5a49f2dfa --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -22,6 +22,9 @@ #include #include #include +#ifdef VENDOR_EDIT +#include +#endif #define QPNP_IRQ_FLAGS (IRQF_TRIGGER_RISING | \ IRQF_TRIGGER_FALLING | \ @@ -685,6 +688,61 @@ int qpnp_ibb_enable(bool state) } EXPORT_SYMBOL(qpnp_ibb_enable); +#ifdef VENDOR_EDIT +/*ykl add set backlight max current in different ambient lux*/ + +#define HIGH_CURRENT 20000 +#define NORMAL_CURRENT 16000 + +static int high_backlight = 0; + +static ssize_t qpnp_wled_high_backlight_store(struct device *dev, struct device_attribute *attr,const char *buf,size_t count) +{ + struct qpnp_wled *wled = dev_get_drvdata(dev); + int data, i, rc, temp; + u8 reg; + + if(sscanf(buf,"%d",&high_backlight) != 1) + return -EINVAL; + + if(high_backlight) + data = HIGH_CURRENT; + else + data = NORMAL_CURRENT; + + for (i = 0; i < wled->num_strings; i++) { + if (data < QPNP_WLED_FS_CURR_MIN_UA) + data = QPNP_WLED_FS_CURR_MIN_UA; + else if (data > QPNP_WLED_FS_CURR_MAX_UA) + data = QPNP_WLED_FS_CURR_MAX_UA; + + rc = qpnp_wled_read_reg(wled, ®, + QPNP_WLED_FS_CURR_REG(wled->sink_base, + wled->strings[i])); + qpnp_wled_module_en(wled, wled->ctrl_base, 0); + if (rc < 0) + return rc; + reg &= QPNP_WLED_FS_CURR_MASK; + temp = data / QPNP_WLED_FS_CURR_STEP_UA; + reg |= temp; + rc = qpnp_wled_write_reg(wled, ®, + QPNP_WLED_FS_CURR_REG(wled->sink_base, + wled->strings[i])); + if (rc) + return rc; + } + qpnp_wled_module_en(wled, wled->ctrl_base, 1); + + wled->fs_curr_ua = data; + return count; +} + +static ssize_t qpnp_wled_high_backlight_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", high_backlight);; +} + +#endif /* sysfs store function for full scale current in ua*/ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -705,6 +763,10 @@ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev, rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_FS_CURR_REG(wled->sink_base, wled->strings[i])); + #ifdef VENDOR_EDIT + /*ykl add set backlight max current in different ambient lux*/ + qpnp_wled_module_en(wled, wled->ctrl_base, 0); + #endif if (rc < 0) return rc; reg &= QPNP_WLED_FS_CURR_MASK; @@ -716,9 +778,12 @@ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev, if (rc) return rc; } + #ifdef VENDOR_EDIT + /*ykl add set backlight max current in different ambient lux*/ + qpnp_wled_module_en(wled, wled->ctrl_base, 1); + #endif wled->fs_curr_ua = data; - return count; } @@ -742,6 +807,10 @@ static struct device_attribute qpnp_wled_attrs[] = { __ATTR(ramp_step, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_wled_ramp_step_show, qpnp_wled_ramp_step_store), + #ifdef VENDOR_EDIT + /*ykl add set backlight max current in different ambient lux*/ + __ATTR(high_bl_en, (S_IRUGO | S_IWUGO),qpnp_wled_high_backlight_show,qpnp_wled_high_backlight_store), + #endif }; /* worker for setting wled brightness */ @@ -1437,7 +1506,6 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) "qcom,en-phase-stag"); wled->en_cabc = of_property_read_bool(spmi->dev.of_node, "qcom,en-cabc"); - prop = of_find_property(spmi->dev.of_node, "qcom,led-strings-list", &temp_val); if (!prop || !temp_val || temp_val > QPNP_WLED_MAX_STRINGS) { diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c index a766bad3d92f0..a993a0c8778c0 100644 --- a/drivers/leds/leds-qpnp.c +++ b/drivers/leds/leds-qpnp.c @@ -2528,11 +2528,12 @@ static ssize_t duty_pcts_store(struct device *dev, struct led_classdev *led_cdev = dev_get_drvdata(dev); char *buffer; ssize_t ret; - int i = 0; + int rets; + //int i = 0; int max_duty_pcts; struct pwm_config_data *pwm_cfg; u32 previous_num_duty_pcts; - int value; + //int value; int *previous_duty_pcts; led = container_of(led_cdev, struct qpnp_led_data, cdev); @@ -2563,16 +2564,37 @@ static ssize_t duty_pcts_store(struct device *dev, buffer = (char *)buf; + #ifndef VENDOR_EDIT for (i = 0; i < max_duty_pcts; i++) { if (buffer == NULL) break; ret = sscanf((const char *)buffer, "%u,%s", &value, buffer); pwm_cfg->old_duty_pcts[i] = value; + printk("pwm_cfg->old_duty_pcts[%d] = %d\n",pwm_cfg->old_duty_pcts[i]); num_duty_pcts++; if (ret <= 1) break; } + #else + rets= sscanf((const char *)buffer, + "%x %x %x %x %x %x %x %x %x %x %x ", + &pwm_cfg->old_duty_pcts[0], &pwm_cfg->old_duty_pcts[1], + &pwm_cfg->old_duty_pcts[2], &pwm_cfg->old_duty_pcts[3], + &pwm_cfg->old_duty_pcts[4], &pwm_cfg->old_duty_pcts[5], + &pwm_cfg->old_duty_pcts[6],&pwm_cfg->old_duty_pcts[7], + &pwm_cfg->old_duty_pcts[8], &pwm_cfg->old_duty_pcts[9], + &pwm_cfg->old_duty_pcts[10]); + if(rets != 11) + { + pr_err("duty_pcts_store: Invalid paramter:%d\n", rets); + return -1; + } + + num_duty_pcts = 11; + + #endif /*VENDOR_EDIT*/ + if (num_duty_pcts >= max_duty_pcts) { dev_err(&led->spmi_dev->dev, "Number of duty pcts given exceeds max (%d)\n", @@ -3429,7 +3451,6 @@ static int qpnp_get_config_pwm(struct pwm_config_data *pwm_cfg, pwm_cfg->use_blink = of_property_read_bool(node, "qcom,use-blink"); - if (pwm_cfg->mode == LPG_MODE || pwm_cfg->use_blink) { pwm_cfg->duty_cycles = devm_kzalloc(&spmi_dev->dev, @@ -3528,6 +3549,7 @@ static int qpnp_get_config_pwm(struct pwm_config_data *pwm_cfg, else if (rc != -EINVAL) goto bad_lpg_params; + pwm_cfg->lut_params.ramp_step_ms = QPNP_LUT_RAMP_STEP_DEFAULT; rc = of_property_read_u32(node, "qcom,ramp-step-ms", &val); @@ -3672,6 +3694,7 @@ static int qpnp_get_config_rgb(struct qpnp_led_data *led, } else return rc; + rc = qpnp_get_config_pwm(led->rgb_cfg->pwm_cfg, led->spmi_dev, node); if (rc < 0) return rc; @@ -4035,6 +4058,12 @@ static int qpnp_leds_probe(struct spmi_device *spmi) } if (led->id == QPNP_ID_LED_MPP) { + #ifdef VENDOR_EDIT /* LiuPing@Phone.BSP.Sensor, 2014/12/23, add for turn off the button-backlight when boot. */ + if (!led->default_on && strcmp(led->cdev.name, "button-backlight") == 0) + { + __qpnp_led_work(led, led->cdev.brightness); + } + #endif /*VENDOR_EDIT*/ if (!led->mpp_cfg->pwm_cfg) break; if (led->mpp_cfg->pwm_cfg->mode == PWM_MODE) { @@ -4063,11 +4092,13 @@ static int qpnp_leds_probe(struct spmi_device *spmi) (led->id == QPNP_ID_RGB_GREEN) || (led->id == QPNP_ID_RGB_BLUE)) { if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) { + rc = sysfs_create_group(&led->cdev.dev->kobj, &pwm_attr_group); if (rc) goto fail_id_check; } + if (led->rgb_cfg->pwm_cfg->use_blink) { rc = sysfs_create_group(&led->cdev.dev->kobj, &blink_attr_group); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 492b3a3395497..ca92874edfc3c 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -47,8 +47,11 @@ #define VFE_PING_FLAG 0xFFFFFFFF #define VFE_PONG_FLAG 0x0 - +#ifdef VENDOR_EDIT +#define VFE_MAX_CFG_TIMEOUT 6000 +#else #define VFE_MAX_CFG_TIMEOUT 3000 +#endif #define VFE_CLK_INFO_MAX 16 #define STATS_COMP_BIT_MASK 0x1FF @@ -316,6 +319,7 @@ struct msm_vfe_axi_stream { struct msm_isp_buffer *buf[2]; uint32_t session_id; uint32_t stream_id; + uint32_t user_stream_id; uint32_t bufq_handle[VFE_BUF_QUEUE_MAX]; uint8_t controllable_output; uint8_t undelivered_request_cnt; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c old mode 100644 new mode 100755 index 50d6c6a2207a1..be9b08d961a07 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -729,7 +729,7 @@ static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev, } spin_lock_irqsave(&vfe_dev->reg_update_lock, flags); - if (vfe_dev->reg_update_requested == reg_updated) + if (reg_updated & BIT(VFE_PIX_0)) vfe_dev->reg_updated = 1; vfe_dev->reg_update_requested &= ~reg_updated; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c old mode 100644 new mode 100755 index 0582daaa3c963..9a200e88b0d4b --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -566,7 +566,7 @@ static void msm_vfe44_process_reg_update(struct vfe_device *vfe_dev, } spin_lock_irqsave(&vfe_dev->reg_update_lock, flags); - if (vfe_dev->reg_update_requested == reg_updated) + if (reg_updated & BIT(VFE_PIX_0)) vfe_dev->reg_updated = 1; vfe_dev->reg_update_requested &= ~reg_updated; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.h old mode 100644 new mode 100755 diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c old mode 100644 new mode 100755 index 4bc8e7d6fe418..d09cf70f56e0b --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -500,7 +500,7 @@ static void msm_vfe46_process_reg_update(struct vfe_device *vfe_dev, } spin_lock_irqsave(&vfe_dev->reg_update_lock, flags); - if (vfe_dev->reg_update_requested == reg_updated) + if (reg_updated & BIT(VFE_PIX_0)) vfe_dev->reg_updated = 1; vfe_dev->reg_update_requested &= ~reg_updated; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c old mode 100644 new mode 100755 index c8ec915abe3af..16abb615ffc1a --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -534,7 +534,7 @@ static void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev, } spin_lock_irqsave(&vfe_dev->reg_update_lock, flags); - if (vfe_dev->reg_update_requested == reg_updated) + if (reg_updated & BIT(VFE_PIX_0)) vfe_dev->reg_updated = 1; vfe_dev->reg_update_requested &= ~reg_updated; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c old mode 100644 new mode 100755 index 932cf5f29e14e..0cd8df296478b --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -552,7 +552,9 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, for (i = 0; i < MAX_NUM_STREAM; i++) { stream_info = &axi_data->stream_info[i]; if (stream_info->state != ACTIVE || - !stream_info->controllable_output) + !stream_info->controllable_output || + (SRC_TO_INTF(stream_info->stream_src) != + VFE_PIX_0)) continue; if (stream_info->undelivered_request_cnt) { @@ -588,21 +590,31 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, switch (event_type) { case ISP_EVENT_SOF: - msm_isp_check_for_output_error(vfe_dev, ts, - &event_data.u.output_info); + if (frame_src == VFE_PIX_0){ + + msm_isp_check_for_output_error(vfe_dev, ts, + &event_data.u.output_info); - if (frame_src == VFE_PIX_0) vfe_dev->axi_data.src_info[frame_src].frame_id += vfe_dev->axi_data.src_info[frame_src]. sof_counter_step; - else + }else{ vfe_dev->axi_data.src_info[frame_src].frame_id++; + } if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0) vfe_dev->axi_data.src_info[frame_src].frame_id = 1; + + #ifdef VENDOR_EDIT + if (vfe_dev->axi_data.src_info[frame_src].frame_id <= 5u) + pr_info("%s: frame_src %d frame id: %u\n", __func__, + frame_src, + vfe_dev->axi_data.src_info[frame_src].frame_id); + #else ISP_DBG("%s: frame_src %d frame id: %u\n", __func__, frame_src, vfe_dev->axi_data.src_info[frame_src].frame_id); + #endif break; default: @@ -768,6 +780,8 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) stream_info->memory_input = stream_cfg_cmd->memory_input; + vfe_dev->reg_update_requested &= + ~(BIT(stream_info->stream_src)); msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_info); @@ -1374,6 +1388,13 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, struct msm_isp_bufq *bufq = NULL; int rc = -1; + if (!vfe_dev || !stream_info || !ts || !output_info) { + pr_err("%s %d vfe_dev %p stream_info %p ts %p op_info %p\n", + __func__, __LINE__, vfe_dev, stream_info, ts, + output_info); + return -EINVAL; + } + pingpong_status = ~vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev); @@ -1396,17 +1417,17 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, done_buf->bufq_handle, done_buf->buf_idx, &ts->buf_time, frame_id, stream_info->runtime_output_format); - } - bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr, - done_buf->bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq buf_handle %x\n", - __func__, done_buf->bufq_handle); - return rc; + bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr, + done_buf->bufq_handle); + if (!bufq) { + pr_err("%s: Invalid bufq buf_handle %x\n", + __func__, done_buf->bufq_handle); + return rc; + } + output_info->output_err_mask |= + 1 << bufq->stream_id; } - output_info->output_err_mask |= - 1 << bufq->stream_id; return 0; } @@ -1993,6 +2014,8 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, stream_info = &axi_data->stream_info[ HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; msm_isp_deinit_stream_ping_pong_reg(vfe_dev, stream_info); + vfe_dev->reg_update_requested &= + ~(BIT(stream_info->stream_src)); } return rc; @@ -2025,7 +2048,7 @@ int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg) vfe_dev, stream_cfg_cmd, camif_update); } else { rc = msm_isp_stop_axi_stream( - vfe_dev, stream_cfg_cmd, camif_update); + vfe_dev, stream_cfg_cmd, /*camif_update*/DISABLE_CAMIF_IMMEDIATELY); //0825 Wesley add for axi wait msm_isp_axi_update_cgc_override(vfe_dev, stream_cfg_cmd, 0); } @@ -2109,8 +2132,8 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, } frame_src = SRC_TO_INTF(stream_info->stream_src); - if ((frame_id <= - vfe_dev->axi_data.src_info[frame_src].camif_sof_frame_id) || + if (((frame_src == VFE_PIX_0) && (frame_id <= + vfe_dev->axi_data.src_info[frame_src].camif_sof_frame_id)) || stream_info->undelivered_request_cnt >= 2) { pr_err("%s:%d invalid request_frame %d cur frame_id %d\n", __func__, __LINE__, frame_id, @@ -2123,11 +2146,13 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, __func__, __LINE__, frame_src); return 0; } - if (!stream_info->undelivered_request_cnt && + if ((frame_src == VFE_PIX_0) && !stream_info->undelivered_request_cnt && stream_info->prev_framedrop_pattern) { - pr_err("%s:%d frame_id %d prev_pattern is valid %d\n", - __func__, __LINE__, frame_id, - stream_info->prev_framedrop_pattern); + pr_err("%s:%d vfe %d frame_id %d prev_pattern %x stream_id %x\n", + __func__, __LINE__, vfe_dev->pdev->id, frame_id, + stream_info->prev_framedrop_pattern, + stream_info->stream_id); + rc = msm_isp_return_empty_buffer(vfe_dev, stream_info, user_stream_id, frame_id, frame_src); if (rc < 0) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h old mode 100644 new mode 100755 diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 01bcb9970fd53..fabdd34df8b0c 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1913,6 +1913,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info; vfe_dev->taskletq_idx = 0; vfe_dev->vt_enable = 0; + vfe_dev->reg_update_requested = 0; /* Register page fault handler */ iommu_set_fault_handler(vfe_dev->buf_mgr->iommu_domain, msm_vfe_iommu_fault_handler, vfe_dev); diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 47b7cee7dc6f5..b4186472862d0 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -696,7 +696,10 @@ static int cpp_init_mem(struct cpp_device *cpp_dev) int rc = 0; kref_init(&cpp_dev->refcount); - kref_get(&cpp_dev->refcount); + #ifndef VENDOR_EDIT + /*liuyan 2015/7/21 delete, memleak*/ + //kref_get(&cpp_dev->refcount); + #endif cpp_dev->client = msm_ion_client_create("cpp"); CPP_DBG("E\n"); diff --git a/drivers/media/platform/msm/camera_v2/sensor/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile index 09afb7b66fb8b..301311151661f 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/Makefile +++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile @@ -3,7 +3,8 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2 ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci -obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/ eeprom/ ois/ +# Add proximity by Likelong 2015.3.23 for proximity sensor +obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/ eeprom/ ois/ vl6180/ obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor_init.o msm_sensor_driver.o msm_sensor.o obj-$(CONFIG_MT9M114) += mt9m114.o obj-$(CONFIG_OV5645) += ov5645.o diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c old mode 100644 new mode 100755 index 479c06e8ab1e0..369f189996afb --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -44,6 +44,52 @@ static struct msm_actuator *actuators[] = { &msm_bivcm_actuator_table, }; +/* Add for rohm_bu63165gwl, tanrifei, 20150428 */ +#ifdef VENDOR_EDIT +static int32_t msm_actuator_write_sequence( + struct msm_actuator_ctrl_t *a_ctrl, + uint16_t addr, uint8_t *data, uint32_t data_size) +{ + struct msm_camera_i2c_seq_reg_setting seq_reg_setting; + struct msm_camera_i2c_seq_reg_array *seq_reg_array; + int32_t i; + int32_t rc = 0; + + if ((data_size > I2C_SEQ_REG_DATA_MAX) || !data) { + return -EFAULT; + } + seq_reg_array = kmalloc(sizeof(struct msm_camera_i2c_seq_reg_array), + GFP_KERNEL); + if (!seq_reg_array) { + return -ENOMEM; + } + + seq_reg_array->reg_addr = addr; + for (i=0; ireg_data[i] = data[i]; + } + seq_reg_array->reg_data_size = data_size; + + seq_reg_setting.reg_setting = seq_reg_array; + seq_reg_setting.addr_type = a_ctrl->i2c_client.addr_type; + seq_reg_setting.size = 1; + seq_reg_setting.delay = 0; + + rc = a_ctrl->i2c_client.i2c_func_tbl-> + i2c_write_seq_table( + &a_ctrl->i2c_client, &seq_reg_setting); + if (rc < 0) { + pr_err("%s Failed I2C write Line %d\n", + __func__, __LINE__); + kfree(seq_reg_array); + return rc; + } + kfree(seq_reg_array); + return rc; +} +#endif +/* end */ + static int32_t msm_actuator_piezo_set_default_focus( struct msm_actuator_ctrl_t *a_ctrl, struct msm_actuator_move_params_t *move_params) @@ -99,6 +145,48 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, write_arr[i].hw_shift); if (write_arr[i].reg_addr != 0xFFFF) { +#ifdef VENDOR_EDIT +/*Modify by zhuoshijie@camera 20150314 for rohm_bu63165gwl_actuator */ + if(!strcmp(a_ctrl->pdev->name,"1c.qcom,actuator")){ + i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = write_arr[i].reg_addr; + i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = 0x90; + i2c_tbl[a_ctrl->i2c_tbl_index].delay = 0; + a_ctrl->i2c_tbl_index++; + i++; + + i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = write_arr[i].reg_addr; + i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = 0x00; + i2c_tbl[a_ctrl->i2c_tbl_index].delay = 0; + a_ctrl->i2c_tbl_index++; + i++; + + i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = write_arr[i].reg_addr; + i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = (value & 0xFF00) >> 8; + i2c_tbl[a_ctrl->i2c_tbl_index].delay = 0; + a_ctrl->i2c_tbl_index++; + i++; + i2c_byte1 = write_arr[i].reg_addr; + i2c_byte2 = (value&0xFF); + }else{ + i2c_byte1 = write_arr[i].reg_addr; + i2c_byte2 = value; + if (size != (i+1)) { + i2c_byte2 = value & 0xFF; + CDBG("byte1:0x%x, byte2:0x%x\n", + i2c_byte1, i2c_byte2); + i2c_tbl[a_ctrl->i2c_tbl_index]. + reg_addr = i2c_byte1; + i2c_tbl[a_ctrl->i2c_tbl_index]. + reg_data = i2c_byte2; + i2c_tbl[a_ctrl->i2c_tbl_index]. + delay = 0; + a_ctrl->i2c_tbl_index++; + i++; + i2c_byte1 = write_arr[i].reg_addr; + i2c_byte2 = (value & 0xFF00) >> 8; + } + } +#else i2c_byte1 = write_arr[i].reg_addr; i2c_byte2 = value; if (size != (i+1)) { @@ -116,6 +204,7 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte1 = write_arr[i].reg_addr; i2c_byte2 = (value & 0xFF00) >> 8; } +#endif /*VENDOR_EDIT*/ } else { i2c_byte1 = (value & 0xFF00) >> 8; i2c_byte2 = value & 0xFF; @@ -617,6 +706,29 @@ static int32_t msm_actuator_move_focus( } move_params->curr_lens_pos = curr_lens_pos; + + /* Modify for rohm_bu63165gwl, tanrifei, 20150428 */ + #ifdef VENDOR_EDIT + if (!strcmp(a_ctrl->pdev->name,"1c.qcom,actuator")) { + uint8_t data[4]; + data[0] = 0x90; + data[1] = 0x00; + data[2] = move_params->curr_lens_pos>>8; + data[3] = move_params->curr_lens_pos & 0xFF; + rc = msm_actuator_write_sequence(a_ctrl, 0xF0, data, 4); + } else { + reg_setting.reg_setting = a_ctrl->i2c_reg_tbl; + reg_setting.data_type = a_ctrl->i2c_data_type; + reg_setting.size = a_ctrl->i2c_tbl_index; + rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay( + &a_ctrl->i2c_client, ®_setting); + if (rc < 0) { + pr_err("i2c write error:%d\n", rc); + return rc; + } + a_ctrl->i2c_tbl_index = 0; + } + #else reg_setting.reg_setting = a_ctrl->i2c_reg_tbl; reg_setting.data_type = a_ctrl->i2c_data_type; reg_setting.size = a_ctrl->i2c_tbl_index; @@ -627,6 +739,8 @@ static int32_t msm_actuator_move_focus( return rc; } a_ctrl->i2c_tbl_index = 0; + #endif + /* end */ CDBG("Exit\n"); return rc; @@ -1048,6 +1162,35 @@ static int32_t msm_actuator_set_position( for (index = 0; index < set_pos->number_of_steps; index++) { next_lens_position = set_pos->pos[index]; delay = set_pos->delay[index]; + + /* Modify for rohm_bu63165gwl, tanrifei, 20150428 */ + #ifdef VENDOR_EDIT + if (!strcmp(a_ctrl->pdev->name,"1c.qcom,actuator")) { + uint8_t data[4]; + data[0] = 0x90; + data[1] = 0x00; + data[2] = next_lens_position>>8; + data[3] = next_lens_position & 0xFF; + rc = msm_actuator_write_sequence(a_ctrl, 0xF0, data, 4); + } else { + a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl, + next_lens_position, hw_params, delay); + + reg_setting.reg_setting = a_ctrl->i2c_reg_tbl; + reg_setting.size = a_ctrl->i2c_tbl_index; + reg_setting.data_type = a_ctrl->i2c_data_type; + + rc = a_ctrl->i2c_client.i2c_func_tbl-> + i2c_write_table_w_microdelay( + &a_ctrl->i2c_client, ®_setting); + if (rc < 0) { + pr_err("%s Failed I2C write Line %d\n", + __func__, __LINE__); + return rc; + } + a_ctrl->i2c_tbl_index = 0; + } + #else a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl, next_lens_position, hw_params, delay); @@ -1064,6 +1207,8 @@ static int32_t msm_actuator_set_position( return rc; } a_ctrl->i2c_tbl_index = 0; + #endif + /* end */ } CDBG("%s exit %d\n", __func__, __LINE__); return rc; diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h index 059633bfd54ab..bf0da3663c542 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cam_cci_hwreg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,7 +19,8 @@ #define CCI_M0_RESET_RMSK 0x3F1 #define CCI_M1_RESET_RMSK 0x3F001 #define CCI_QUEUE_START_ADDR 0x00000008 -#define CCI_SET_CID_SYNC_TIMER_0_ADDR 0x00000010 +#define CCI_SET_CID_SYNC_TIMER_ADDR 0x00000010 +#define CCI_SET_CID_SYNC_TIMER_OFFSET 0x00000004 #define CCI_I2C_M0_SCL_CTL_ADDR 0x00000100 #define CCI_I2C_M0_SDA_CTL_0_ADDR 0x00000104 #define CCI_I2C_M0_SDA_CTL_1_ADDR 0x00000108 @@ -37,6 +38,7 @@ #define CCI_I2C_M1_MISC_CTL_ADDR 0x00000210 #define CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR 0x00000304 #define CCI_I2C_M0_Q0_CUR_CMD_ADDR 0x00000308 +#define CCI_I2C_M0_Q0_REPORT_STATUS_ADDR 0x0000030c #define CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR 0x00000300 #define CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x00000310 #define CCI_IRQ_MASK_0_ADDR 0x00000c04 diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c old mode 100644 new mode 100755 index 79c0db4e8d1a6..52dee6db5ab8e --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -29,7 +29,12 @@ #define CYCLES_PER_MICRO_SEC_DEFAULT 4915 #define CCI_MAX_DELAY 1000000 +#ifdef VENDOR_EDIT +//muyuezhong@camera,2015-4-22,modify it for more cci_timeout #define CCI_TIMEOUT msecs_to_jiffies(500) +#else +#define CCI_TIMEOUT msecs_to_jiffies(100) +#endif /* TODO move this somewhere else */ #define MSM_CCI_DRV_NAME "msm_cci" @@ -43,6 +48,10 @@ #define CCI_I2C_MAX_READ 8192 #define CCI_I2C_MAX_WRITE 8192 +#define PRIORITY_QUEUE (QUEUE_0) +#define SYNC_QUEUE (QUEUE_1) + + static struct v4l2_subdev *g_cci_subdev; static struct msm_cam_clk_info cci_clk_info[CCI_NUM_CLK_CASES][CCI_NUM_CLK_MAX]; @@ -150,18 +159,21 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + reg_offset); read_val++; - CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n", - __func__, __LINE__, read_val); + CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d, queue: %d\n", + __func__, __LINE__, read_val, queue); msm_camera_io_w_mb(read_val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); + atomic_set(&cci_dev->cci_master_info[master]. + done_pending[queue], 1); msm_camera_io_w_mb(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CDBG("%s line %d wait_for_completion_timeout\n", __func__, __LINE__); + atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); rc = wait_for_completion_timeout(&cci_dev-> - cci_master_info[master].reset_complete, CCI_TIMEOUT); + cci_master_info[master].report_q[queue], CCI_TIMEOUT); if (rc <= 0) { pr_err("%s: wait_for_completion_timeout %d\n", __func__, __LINE__); @@ -177,6 +189,294 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, return rc; } +static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev, + uint32_t val, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + int32_t rc = 0; + uint32_t reg_offset = master * 0x200 + queue * 0x100; + + if (!cci_dev) { + pr_err("%s: failed %d", __func__, __LINE__); + return -EINVAL; + } + + CDBG("%s:%d called\n", __func__, __LINE__); + rc = msm_cci_validate_queue(cci_dev, 1, master, queue); + if (rc < 0) { + pr_err("%s: failed %d", __func__, __LINE__); + return rc; + } + CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x\n", + __func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset, val); + msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset); + return rc; +} + +static uint32_t msm_cci_wait(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + int32_t rc = 0; + + if (!cci_dev) { + pr_err("%s: failed %d", __func__, __LINE__); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&cci_dev-> + cci_master_info[master].report_q[queue], CCI_TIMEOUT); + CDBG("%s line %d wait DONE_for_completion_timeout\n", + __func__, __LINE__); + + if (rc <= 0) { + pr_err("%s: %d wait for queue: %d\n", + __func__, __LINE__, queue); + if (rc == 0) + rc = -ETIMEDOUT; + msm_cci_flush_queue(cci_dev, master); + return rc; + } + rc = cci_dev->cci_master_info[master].status; + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + return 0; +} + +static int32_t msm_cci_addr_to_num_bytes( + enum msm_camera_i2c_reg_addr_type addr_type) +{ + int32_t retVal; + + switch (addr_type) { + case MSM_CAMERA_I2C_BYTE_ADDR: + retVal = 1; + break; + case MSM_CAMERA_I2C_WORD_ADDR: + retVal = 2; + break; + case MSM_CAMERA_I2C_3B_ADDR: + retVal = 3; + break; + default: + pr_err("%s: %d failed: %d\n", __func__, __LINE__, addr_type); + retVal = 1; + break; + } + return retVal; +} + +static int32_t msm_cci_data_to_num_bytes( + enum msm_camera_i2c_data_type data_type) +{ + int32_t retVal; + + switch (data_type) { + case MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA: + case MSM_CAMERA_I2C_SET_BYTE_MASK: + case MSM_CAMERA_I2C_UNSET_BYTE_MASK: + case MSM_CAMERA_I2C_BYTE_DATA: + retVal = 1; + break; + case MSM_CAMERA_I2C_SET_WORD_MASK: + case MSM_CAMERA_I2C_UNSET_WORD_MASK: + case MSM_CAMERA_I2C_WORD_DATA: + retVal = 2; + break; + case MSM_CAMERA_I2C_DWORD_DATA: + retVal = 4; + break; + default: + pr_err("%s: %d failed: %d\n", __func__, __LINE__, data_type); + retVal = 1; + break; + } + return retVal; +} + +static int32_t msm_cci_calc_cmd_len(struct cci_device *cci_dev, + struct msm_camera_cci_ctrl *c_ctrl, uint32_t cmd_size, + struct msm_camera_i2c_reg_array *i2c_cmd, uint32_t *pack) +{ + uint8_t i; + uint32_t len = 0; + uint8_t data_len = 0, addr_len = 0; + uint8_t pack_max_len; + struct msm_camera_i2c_reg_setting *msg; + struct msm_camera_i2c_reg_array *cmd = i2c_cmd; + uint32_t size = cmd_size; + + if (!cci_dev || !c_ctrl) { + pr_err("%s: failed %d", __func__, __LINE__); + return -EINVAL; + } + + msg = &c_ctrl->cfg.cci_i2c_write_cfg; + *pack = 0; + + if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) { + addr_len = msm_cci_addr_to_num_bytes(msg->addr_type); + len = (size + addr_len) <= (cci_dev->payload_size) ? + (size + addr_len):cci_dev->payload_size; + } else { + addr_len = msm_cci_addr_to_num_bytes(msg->addr_type); + data_len = msm_cci_data_to_num_bytes(msg->data_type); + len = data_len + addr_len; + pack_max_len = size < (cci_dev->payload_size-len) ? + size : (cci_dev->payload_size-len); + for (i = 0; i < pack_max_len;) { + if (cmd->delay) + break; + if (cmd->reg_addr + 1 == + (cmd+1)->reg_addr) { + len += data_len; + *pack += data_len; + } else + break; + i += data_len; + cmd++; + } + } + + if (len > cci_dev->payload_size) { + pr_err("Len error: %d", len); + return -EINVAL; + } + + len += 1; /*add i2c WR command*/ + len = len/4 + 1; + + return len; +} + +static void msm_cci_load_report_cmd(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + uint32_t reg_offset = master * 0x200 + queue * 0x100; + uint32_t read_val = msm_camera_io_r_mb(cci_dev->base + + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); + uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8); + + CDBG("%s:%d CCI_I2C_REPORT_CMD curr_w_cnt: %d\n", + __func__, __LINE__, read_val); + msm_camera_io_w_mb(report_val, + cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset); + read_val++; + + CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n", + __func__, __LINE__, read_val); + msm_camera_io_w_mb(read_val, cci_dev->base + + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); +} + +static int32_t msm_cci_wait_report_cmd(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + uint32_t reg_val = 1 << ((master * 2) + queue); + msm_cci_load_report_cmd(cci_dev, master, queue); + atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); + atomic_set(&cci_dev->cci_master_info[master].done_pending[queue], 1); + msm_camera_io_w_mb(reg_val, cci_dev->base + + CCI_QUEUE_START_ADDR); + return msm_cci_wait(cci_dev, master, queue); +} + +static void msm_cci_process_half_q(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + uint32_t reg_val = 1 << ((master * 2) + queue); + if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { + msm_cci_load_report_cmd(cci_dev, master, queue); + atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1); + msm_camera_io_w_mb(reg_val, cci_dev->base + + CCI_QUEUE_START_ADDR); + } +} + +static int32_t msm_cci_process_full_q(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + int32_t rc = 0; + if (1 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { + atomic_set(&cci_dev->cci_master_info[master]. + done_pending[queue], 1); + rc = msm_cci_wait(cci_dev, master, queue); + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + } else { + rc = msm_cci_wait_report_cmd(cci_dev, master, queue); + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + } + return rc; +} + +static int32_t msm_cci_lock_queue(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue, uint32_t en) +{ + uint32_t val; + + if (queue != PRIORITY_QUEUE) + return 0; + + val = en ? CCI_I2C_LOCK_CMD : CCI_I2C_UNLOCK_CMD; + return msm_cci_write_i2c_queue(cci_dev, val, master, queue); +} + +static int32_t msm_cci_transfer_end(struct cci_device *cci_dev, + enum cci_i2c_master_t master, + enum cci_i2c_queue_t queue) +{ + int32_t rc = 0; + + if (0 == atomic_read(&cci_dev->cci_master_info[master].q_free[queue])) { + rc = msm_cci_lock_queue(cci_dev, master, queue, 0); + if (rc < 0) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return rc; + } + rc = msm_cci_wait_report_cmd(cci_dev, master, queue); + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + } else { + atomic_set(&cci_dev->cci_master_info[master]. + done_pending[queue], 1); + rc = msm_cci_wait(cci_dev, master, queue); + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + rc = msm_cci_lock_queue(cci_dev, master, queue, 0); + if (rc < 0) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return rc; + } + rc = msm_cci_wait_report_cmd(cci_dev, master, queue); + if (rc < 0) { + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } + } + return rc; +} + static int32_t msm_cci_get_queue_free_size(struct cci_device *cci_dev, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) @@ -194,7 +494,8 @@ static int32_t msm_cci_get_queue_free_size(struct cci_device *cci_dev, } static int32_t msm_cci_data_queue(struct cci_device *cci_dev, - struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue) + struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue, + enum cci_i2c_sync sync_en) { uint16_t i = 0, j = 0, k = 0, h = 0, len = 0; int32_t rc = 0, free_size = 0, en_seq_write = 0; @@ -207,6 +508,11 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, struct msm_camera_i2c_reg_array *i2c_cmd = i2c_msg->reg_setting; enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master; + uint32_t read_val = 0; + uint32_t reg_offset; + uint32_t val = 0; + uint32_t max_queue_size; + if (i2c_cmd == NULL) { pr_err("%s:%d Failed line\n", __func__, __LINE__); @@ -218,8 +524,8 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, return -EINVAL; } - CDBG("%s addr type %d data type %d\n", __func__, - i2c_msg->addr_type, i2c_msg->data_type); + CDBG("%s addr type %d data type %d cmd_size %d\n", __func__, + i2c_msg->addr_type, i2c_msg->data_type, cmd_size); if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) { pr_err("%s failed line %d\n", __func__, __LINE__); @@ -229,12 +535,76 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, pr_err("%s failed line %d\n", __func__, __LINE__); return -EINVAL; } + reg_offset = master * 0x200 + queue * 0x100; + + msm_camera_io_w_mb(cci_dev->cci_wait_sync_cfg.cid, + cci_dev->base + CCI_SET_CID_SYNC_TIMER_ADDR + + cci_dev->cci_wait_sync_cfg.csid * + CCI_SET_CID_SYNC_TIMER_OFFSET); + + val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 | + c_ctrl->cci_info->retries << 16 | + c_ctrl->cci_info->id_map << 18; + CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x\n", + __func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset, val); + msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset); + + atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 0); + + max_queue_size = cci_dev->cci_i2c_queue_info[master][queue]. + max_queue_size; reg_addr = i2c_cmd->reg_addr; + + if (sync_en == MSM_SYNC_ENABLE && cci_dev->valid_sync && + cmd_size < max_queue_size) { + val = CCI_I2C_WAIT_SYNC_CMD | + ((cci_dev->cci_wait_sync_cfg.line) << 4); + msm_camera_io_w_mb(val, + cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + + reg_offset); + } + + rc = msm_cci_lock_queue(cci_dev, master, queue, 1); + if (rc < 0) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return rc; + } + while (cmd_size) { + uint32_t pack = 0; + len = msm_cci_calc_cmd_len(cci_dev, c_ctrl, cmd_size, + i2c_cmd, &pack); + if (len <= 0) { + pr_err("%s failed line %d\n", __func__, __LINE__); + return -EINVAL; + } + + read_val = msm_camera_io_r_mb(cci_dev->base + + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); + CDBG("%s line %d CUR_WORD_CNT_ADDR %d len %d max %d\n", + __func__, __LINE__, read_val, len, max_queue_size); + /* + 1 - space alocation for Report CMD*/ + if ((read_val + len + 1) > max_queue_size/2) { + if ((read_val + len + 1) > max_queue_size) { + rc = msm_cci_process_full_q(cci_dev, + master, queue); + if (rc < 0) { + pr_err("%s failed line %d\n", + __func__, __LINE__); + return rc; + } + continue; + } + msm_cci_process_half_q(cci_dev, master, queue); + } + CDBG("%s cmd_size %d addr 0x%x data 0x%x\n", __func__, cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data); delay = i2c_cmd->delay; + i = 0; data[i++] = CCI_I2C_WRITE_CMD; /* in case of multiple command @@ -243,7 +613,10 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, * MSM_CCI_I2C_WRITE_SEQ : address is continuous, need to keep * the incremented address for a * new packet */ - if (c_ctrl->cmd == MSM_CCI_I2C_WRITE) + if (c_ctrl->cmd == MSM_CCI_I2C_WRITE || + c_ctrl->cmd == MSM_CCI_I2C_WRITE_ASYNC || + c_ctrl->cmd == MSM_CCI_I2C_WRITE_SYNC || + c_ctrl->cmd == MSM_CCI_I2C_WRITE_SYNC_BLOCK) reg_addr = i2c_cmd->reg_addr; if (en_seq_write == 0) { @@ -272,7 +645,7 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, } i2c_cmd++; --cmd_size; - } while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) && + } while (((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) || pack--) && (cmd_size > 0) && (i <= cci_dev->payload_size)); free_size = msm_cci_get_queue_free_size(cci_dev, master, queue); @@ -287,21 +660,24 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, en_seq_write = 0; } len = ((i-1)/4) + 1; - rc = msm_cci_validate_queue(cci_dev, len, master, queue); - if (rc < 0) { - pr_err("%s: failed %d", __func__, __LINE__); - return rc; - } + + read_val = msm_camera_io_r_mb(cci_dev->base + + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); for (h = 0, k = 0; h < len; h++) { cmd = 0; for (j = 0; (j < 4 && k < i); j++) cmd |= (data[k++] << (j * 8)); - CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n", - __func__, cmd); + CDBG("%s LOAD_DATA_ADDR 0x%x, q: %d, len:%d, cnt: %d\n", + __func__, cmd, queue, len, read_val); msm_camera_io_w_mb(cmd, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + master * 0x200 + queue * 0x100); + + read_val += 1; + msm_camera_io_w_mb(read_val, cci_dev->base + + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); } + if ((delay > 0) && (delay < CCI_MAX_DELAY) && en_seq_write == 0) { cmd = (uint32_t)((delay * cci_dev->cycles_per_us) / @@ -313,30 +689,19 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev, msm_camera_io_w_mb(cmd, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + master * 0x200 + queue * 0x100); + read_val += 1; + msm_camera_io_w_mb(read_val, cci_dev->base + + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); } - i = 0; + } - return rc; -} -static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev, - uint32_t val, - enum cci_i2c_master_t master, - enum cci_i2c_queue_t queue) -{ - int32_t rc = 0; - uint32_t reg_offset = master * 0x200 + queue * 0x100; - CDBG("%s:%d called\n", __func__, __LINE__); - rc = msm_cci_validate_queue(cci_dev, 1, master, queue); + rc = msm_cci_transfer_end(cci_dev, master, queue); if (rc < 0) { - pr_err("%s: failed %d", __func__, __LINE__); + pr_err("%s: %d failed rc %d\n", __func__, __LINE__, rc); return rc; } - CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR:val 0x%x:0x%x\n", - __func__, CCI_I2C_M0_Q0_LOAD_DATA_ADDR + - reg_offset, val); - msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + - reg_offset); + return rc; } @@ -356,7 +721,7 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, cci_dev = v4l2_get_subdevdata(sd); master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; - mutex_lock(&cci_dev->cci_master_info[master].mutex); + mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * Call validate queue to make sure queue is empty before starting. @@ -494,7 +859,7 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, } } while (--read_words > 0); ERROR: - mutex_unlock(&cci_dev->cci_master_info[master].mutex); + mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; } @@ -565,13 +930,13 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd, } static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, - struct msm_camera_cci_ctrl *c_ctrl) + struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue, + enum cci_i2c_sync sync_en) { int32_t rc = 0; struct cci_device *cci_dev; - uint32_t val; enum cci_i2c_master_t master; - enum cci_i2c_queue_t queue = QUEUE_0; + cci_dev = v4l2_get_subdevdata(sd); if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX || c_ctrl->cci_info->cci_i2c_master < 0) { @@ -584,11 +949,9 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, return -EINVAL; } master = c_ctrl->cci_info->cci_i2c_master; - CDBG("%s master %d, queue %d\n", __func__, master, queue); CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__, c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, c_ctrl->cci_info->id_map); - mutex_lock(&cci_dev->cci_master_info[master].mutex); /* * Call validate queue to make sure queue is empty before starting. @@ -596,11 +959,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, * avoid overflow / underflow of queue */ rc = msm_cci_validate_queue(cci_dev, - cci_dev->cci_i2c_queue_info[master][queue].max_queue_size - 1, + cci_dev->cci_i2c_queue_info[master][queue].max_queue_size-1, master, queue); if (rc < 0) { - pr_err("%s:%d Initial validataion failed rc %d\n", __func__, - __LINE__, rc); + pr_err("%s:%d Initial validataion failed rc %d\n", + __func__, __LINE__, rc); goto ERROR; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { @@ -608,77 +971,101 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, __LINE__); goto ERROR; } - - val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 | - c_ctrl->cci_info->retries << 16 | - c_ctrl->cci_info->id_map << 18; - CDBG("%s:%d CCI_I2C_SET_PARAM_CMD\n", __func__, __LINE__); - rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue); + rc = msm_cci_data_queue(cci_dev, c_ctrl, queue, sync_en); if (rc < 0) { CDBG("%s failed line %d\n", __func__, __LINE__); goto ERROR; } - val = CCI_I2C_LOCK_CMD; - CDBG("%s:%d CCI_I2C_LOCK_CMD\n", __func__, __LINE__); - rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue); - if (rc < 0) { - CDBG("%s failed line %d\n", __func__, __LINE__); - goto ERROR; - } +ERROR: + return rc; +} - rc = msm_cci_data_queue(cci_dev, c_ctrl, queue); - if (rc < 0) { - CDBG("%s failed line %d\n", __func__, __LINE__); - goto ERROR; +static void msm_cci_write_async_helper(struct work_struct *work) +{ + int rc; + struct cci_device *cci_dev; + struct cci_write_async *write_async = + container_of(work, struct cci_write_async, work); + struct msm_camera_i2c_reg_setting *i2c_msg; + enum cci_i2c_master_t master; + struct msm_camera_cci_master_info *cci_master_info; + + cci_dev = write_async->cci_dev; + i2c_msg = &write_async->c_ctrl.cfg.cci_i2c_write_cfg; + master = write_async->c_ctrl.cci_info->cci_i2c_master; + cci_master_info = &cci_dev->cci_master_info[master]; + + mutex_lock(&cci_master_info->mutex_q[write_async->queue]); + rc = msm_cci_i2c_write(&cci_dev->msm_sd.sd, + &write_async->c_ctrl, write_async->queue, write_async->sync_en); + mutex_unlock(&cci_master_info->mutex_q[write_async->queue]); + if (rc < 0) + pr_err("%s: %d failed\n", __func__, __LINE__); + + kfree(write_async->c_ctrl.cfg.cci_i2c_write_cfg.reg_setting); + kfree(write_async); + + CDBG("%s: %d Exit\n", __func__, __LINE__); +} + +static int32_t msm_cci_i2c_write_async(struct v4l2_subdev *sd, + struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue, + enum cci_i2c_sync sync_en) +{ + struct cci_write_async *write_async; + struct cci_device *cci_dev; + struct msm_camera_i2c_reg_setting *cci_i2c_write_cfg; + struct msm_camera_i2c_reg_setting *cci_i2c_write_cfg_w; + + cci_dev = v4l2_get_subdevdata(sd); + + CDBG("%s: %d Enter\n", __func__, __LINE__); + + write_async = kzalloc(sizeof(*write_async), GFP_KERNEL); + if (!write_async) { + pr_err("%s: %d Couldn't allocate memory\n", __func__, __LINE__); + return -ENOMEM; } - val = CCI_I2C_UNLOCK_CMD; - CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__); - rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue); - if (rc < 0) { - CDBG("%s failed line %d\n", __func__, __LINE__); - goto ERROR; + + INIT_WORK(&write_async->work, msm_cci_write_async_helper); + write_async->cci_dev = cci_dev; + write_async->c_ctrl = *c_ctrl; + write_async->queue = queue; + write_async->sync_en = sync_en; + + cci_i2c_write_cfg = &c_ctrl->cfg.cci_i2c_write_cfg; + cci_i2c_write_cfg_w = &write_async->c_ctrl.cfg.cci_i2c_write_cfg; + + if (cci_i2c_write_cfg->size == 0) { + pr_err("%s: %d Size = 0\n", __func__, __LINE__); + kfree(write_async); + return -EINVAL; } - val = CCI_I2C_REPORT_CMD | (1 << 8); - CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__); - rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue); - if (rc < 0) { - CDBG("%s failed line %d\n", __func__, __LINE__); - goto ERROR; + cci_i2c_write_cfg_w->reg_setting = + kzalloc(sizeof(struct msm_camera_i2c_reg_array)* + cci_i2c_write_cfg->size, GFP_KERNEL); + if (!cci_i2c_write_cfg_w->reg_setting) { + pr_err("%s: %d Couldn't allocate memory\n", __func__, __LINE__); + kfree(write_async); + return -ENOMEM; } + memcpy(cci_i2c_write_cfg_w->reg_setting, + cci_i2c_write_cfg->reg_setting, + (sizeof(struct msm_camera_i2c_reg_array)* + cci_i2c_write_cfg->size)); - val = msm_camera_io_r_mb(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR - + master * 0x200 + queue * 0x100); - CDBG("%s:%d cur word count %d\n", __func__, __LINE__, val); - CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR\n", __func__, __LINE__); - msm_camera_io_w_mb(val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR - + master * 0x200 + queue * 0x100); + cci_i2c_write_cfg_w->addr_type = cci_i2c_write_cfg->addr_type; + cci_i2c_write_cfg_w->data_type = cci_i2c_write_cfg->data_type; + cci_i2c_write_cfg_w->size = cci_i2c_write_cfg->size; + cci_i2c_write_cfg_w->delay = cci_i2c_write_cfg->delay; - val = 1 << ((master * 2) + queue); - CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); - msm_camera_io_w_mb(val, cci_dev->base + CCI_QUEUE_START_ADDR); + queue_work(cci_dev->write_wq[write_async->queue], &write_async->work); - CDBG("%s:%d E wait_for_completion_timeout\n", - __func__, __LINE__); - rc = wait_for_completion_timeout(&cci_dev-> - cci_master_info[master].reset_complete, CCI_TIMEOUT); - if (rc <= 0) { - pr_err("%s: wait_for_completion_timeout %d\n", - __func__, __LINE__); - if (rc == 0) - rc = -ETIMEDOUT; - msm_cci_flush_queue(cci_dev, master); - goto ERROR; - } else { - rc = cci_dev->cci_master_info[master].status; - } - CDBG("%s:%d X wait_for_completion_timeout\n", __func__, - __LINE__); + CDBG("%s: %d Exit\n", __func__, __LINE__); -ERROR: - mutex_unlock(&cci_dev->cci_master_info[master].mutex); - return rc; + return 0; } static int msm_cci_subdev_g_chip_ident(struct v4l2_subdev *sd, @@ -777,20 +1164,39 @@ static struct msm_cam_clk_info *msm_cci_get_clk(struct cci_device *cci_dev, return NULL; } +static int32_t msm_cci_i2c_set_sync_prms(struct v4l2_subdev *sd, + struct msm_camera_cci_ctrl *c_ctrl) +{ + int32_t rc = 0; + struct cci_device *cci_dev; + + cci_dev = v4l2_get_subdevdata(sd); + if (!cci_dev || !c_ctrl) { + pr_err("%s:%d failed: invalid params %p %p\n", __func__, + __LINE__, cci_dev, c_ctrl); + rc = -EINVAL; + return rc; + } + cci_dev->cci_wait_sync_cfg = c_ctrl->cfg.cci_wait_sync_cfg; + cci_dev->valid_sync = cci_dev->cci_wait_sync_cfg.csid < 0 ? 0 : 1; + + return rc; +} + static int32_t msm_cci_init(struct v4l2_subdev *sd, struct msm_camera_cci_ctrl *c_ctrl) { uint8_t i = 0; int32_t rc = 0, ret = 0; struct cci_device *cci_dev; - enum cci_i2c_master_t master; + enum cci_i2c_master_t master = MASTER_0; struct msm_cam_clk_info *clk_info = NULL; cci_dev = v4l2_get_subdevdata(sd); if (!cci_dev || !c_ctrl) { pr_err("%s:%d failed: invalid params %p %p\n", __func__, __LINE__, cci_dev, c_ctrl); - rc = -ENOMEM; + rc = -EINVAL; return rc; } if (cci_dev->ref_count++) { @@ -800,6 +1206,13 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, msm_cci_set_clk_param(cci_dev, c_ctrl); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); + flush_workqueue(cci_dev->write_wq[master]); + /* Re-initialize the completion */ + INIT_COMPLETION(cci_dev-> + cci_master_info[master].reset_complete); + for (i = 0; i < NUM_QUEUES; i++) + INIT_COMPLETION(cci_dev-> + cci_master_info[master].report_q[i]); /* Set reset pending flag to TRUE */ cci_dev->cci_master_info[master].reset_pending = TRUE; /* Set proper mask to RESET CMD address */ @@ -868,6 +1281,10 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, CDBG("%s: clk enable failed\n", __func__); goto clk_enable_failed; } + /* Re-initialize the completion */ + INIT_COMPLETION(cci_dev->cci_master_info[master].reset_complete); + for (i = 0; i < NUM_QUEUES; i++) + INIT_COMPLETION(cci_dev->cci_master_info[master].report_q[i]); enable_irq(cci_dev->irq->start); cci_dev->hw_version = msm_camera_io_r_mb(cci_dev->base + CCI_HW_VERSION_ADDR); @@ -903,6 +1320,16 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, msm_camera_io_w_mb(CCI_IRQ_MASK_0_RMSK, cci_dev->base + CCI_IRQ_CLEAR_0_ADDR); msm_camera_io_w_mb(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); + + for (i = 0; i < MASTER_MAX; i++) { + if (!cci_dev->write_wq[i]) { + pr_err("Failed to flush write wq\n"); + rc = -ENOMEM; + goto reset_complete_failed; + } else { + flush_workqueue(cci_dev->write_wq[i]); + } + } cci_dev->cci_state = CCI_STATE_ENABLED; return 0; @@ -947,6 +1374,10 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd) CDBG("%s ref_count Exit %d\n", __func__, cci_dev->ref_count); return 0; } + for (i = 0; i < MASTER_MAX; i++) + if (cci_dev->write_wq[i]) + flush_workqueue(cci_dev->write_wq[i]); + disable_irq(cci_dev->irq->start); msm_cam_clk_enable(&cci_dev->pdev->dev, &cci_clk_info[0][0], cci_dev->cci_clk, cci_dev->num_clk, 0); @@ -967,6 +1398,7 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd) cci_dev->cci_gpio_tbl_size, 0); for (i = 0; i < MASTER_MAX; i++) cci_dev->master_clk_init[i] = 0; + cci_dev->cci_state = CCI_STATE_DISABLED; cci_dev->cycles_per_us = 0; cci_dev->cci_clk_src = 0; @@ -974,12 +1406,73 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd) return 0; } +static int32_t msm_cci_write(struct v4l2_subdev *sd, + struct msm_camera_cci_ctrl *c_ctrl) +{ + int32_t rc = 0; + struct cci_device *cci_dev; + enum cci_i2c_master_t master; + struct msm_camera_cci_master_info *cci_master_info; + uint32_t i; + + cci_dev = v4l2_get_subdevdata(sd); + if (!cci_dev || !c_ctrl) { + pr_err("%s:%d failed: invalid params %p %p\n", __func__, + __LINE__, cci_dev, c_ctrl); + rc = -EINVAL; + return rc; + } + + master = c_ctrl->cci_info->cci_i2c_master; + cci_master_info = &cci_dev->cci_master_info[master]; + + switch (c_ctrl->cmd) { + case MSM_CCI_I2C_WRITE_SYNC_BLOCK: + mutex_lock(&cci_master_info->mutex_q[SYNC_QUEUE]); + rc = msm_cci_i2c_write(sd, c_ctrl, + SYNC_QUEUE, MSM_SYNC_ENABLE); + mutex_unlock(&cci_master_info->mutex_q[SYNC_QUEUE]); + break; + case MSM_CCI_I2C_WRITE_SYNC: + rc = msm_cci_i2c_write_async(sd, c_ctrl, + SYNC_QUEUE, MSM_SYNC_ENABLE); + break; + case MSM_CCI_I2C_WRITE: + case MSM_CCI_I2C_WRITE_SEQ: + for (i = 0; i < NUM_QUEUES; i++) { + if (mutex_trylock(&cci_master_info->mutex_q[i])) { + rc = msm_cci_i2c_write(sd, c_ctrl, i, + MSM_SYNC_DISABLE); + mutex_unlock(&cci_master_info->mutex_q[i]); + return rc; + } + } + mutex_lock(&cci_master_info->mutex_q[PRIORITY_QUEUE]); + rc = msm_cci_i2c_write(sd, c_ctrl, + PRIORITY_QUEUE, MSM_SYNC_DISABLE); + mutex_unlock(&cci_master_info->mutex_q[PRIORITY_QUEUE]); + break; + case MSM_CCI_I2C_WRITE_ASYNC: + rc = msm_cci_i2c_write_async(sd, c_ctrl, + PRIORITY_QUEUE, MSM_SYNC_DISABLE); + break; + default: + rc = -ENOIOCTLCMD; + } + return rc; +} + static int32_t msm_cci_config(struct v4l2_subdev *sd, struct msm_camera_cci_ctrl *cci_ctrl) { int32_t rc = 0; + struct cci_device *cci_dev; + CDBG("%s line %d cmd %d\n", __func__, __LINE__, cci_ctrl->cmd); + + cci_dev = v4l2_get_subdevdata(sd); + mutex_lock(&cci_dev->mutex); switch (cci_ctrl->cmd) { case MSM_CCI_INIT: rc = msm_cci_init(sd, cci_ctrl); @@ -988,19 +1481,30 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd, rc = msm_cci_release(sd); break; case MSM_CCI_I2C_READ: + if (cci_dev->cci_state == CCI_STATE_DISABLED) + break; rc = msm_cci_i2c_read_bytes(sd, cci_ctrl); break; case MSM_CCI_I2C_WRITE: case MSM_CCI_I2C_WRITE_SEQ: - rc = msm_cci_i2c_write(sd, cci_ctrl); + case MSM_CCI_I2C_WRITE_SYNC: + case MSM_CCI_I2C_WRITE_ASYNC: + case MSM_CCI_I2C_WRITE_SYNC_BLOCK: + if (cci_dev->cci_state == CCI_STATE_DISABLED) + break; + rc = msm_cci_write(sd, cci_ctrl); break; case MSM_CCI_GPIO_WRITE: break; + case MSM_CCI_SET_SYNC_CID: + rc = msm_cci_i2c_set_sync_prms(sd, cci_ctrl); + break; default: rc = -ENOIOCTLCMD; } CDBG("%s line %d rc %d\n", __func__, __LINE__, rc); cci_ctrl->status = rc; + mutex_unlock(&cci_dev->mutex); return rc; } @@ -1027,18 +1531,54 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data) reset_complete); } } - if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) || - (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) || - (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) { + if (irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } - if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) || - (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) || - (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) { + if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { + struct msm_camera_cci_master_info *cci_master_info; + cci_master_info = &cci_dev->cci_master_info[MASTER_0]; + atomic_set(&cci_master_info->q_free[QUEUE_0], 0); + cci_master_info->status = 0; + if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { + complete(&cci_master_info->report_q[QUEUE_0]); + atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); + } + } + if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { + struct msm_camera_cci_master_info *cci_master_info; + cci_master_info = &cci_dev->cci_master_info[MASTER_0]; + atomic_set(&cci_master_info->q_free[QUEUE_1], 0); + cci_master_info->status = 0; + if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { + complete(&cci_master_info->report_q[QUEUE_1]); + atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); + } + } + if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } + if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { + struct msm_camera_cci_master_info *cci_master_info; + cci_master_info = &cci_dev->cci_master_info[MASTER_1]; + atomic_set(&cci_master_info->q_free[QUEUE_0], 0); + cci_master_info->status = 0; + if (atomic_read(&cci_master_info->done_pending[QUEUE_0]) == 1) { + complete(&cci_master_info->report_q[QUEUE_0]); + atomic_set(&cci_master_info->done_pending[QUEUE_0], 0); + } + } + if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { + struct msm_camera_cci_master_info *cci_master_info; + cci_master_info = &cci_dev->cci_master_info[MASTER_1]; + atomic_set(&cci_master_info->q_free[QUEUE_1], 0); + cci_master_info->status = 0; + if (atomic_read(&cci_master_info->done_pending[QUEUE_1]) == 1) { + complete(&cci_master_info->report_q[QUEUE_1]); + atomic_set(&cci_master_info->done_pending[QUEUE_1], 0); + } + } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; msm_camera_io_w_mb(CCI_M0_RESET_RMSK, @@ -1118,7 +1658,11 @@ static void msm_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex); init_completion(&new_cci_dev-> cci_master_info[i].reset_complete); + for (j = 0; j < NUM_QUEUES; j++) { + mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); + init_completion(&new_cci_dev-> + cci_master_info[i].report_q[j]); if (j == QUEUE_0) new_cci_dev->cci_i2c_queue_info[i][j]. max_queue_size = CCI_I2C_QUEUE_0_SIZE; @@ -1127,6 +1671,7 @@ static void msm_cci_init_cci_params(struct cci_device *new_cci_dev) max_queue_size = CCI_I2C_QUEUE_1_SIZE; } } + mutex_init(&new_cci_dev->mutex); return; } @@ -1399,7 +1944,7 @@ static int msm_cci_get_clk_info(struct cci_device *cci_dev, static int msm_cci_probe(struct platform_device *pdev) { struct cci_device *new_cci_dev; - int rc = 0; + int rc = 0, i = 0; CDBG("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id); new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL); if (!new_cci_dev) { @@ -1477,8 +2022,15 @@ static int msm_cci_probe(struct platform_device *pdev) pr_err("%s: failed to add child nodes, rc=%d\n", __func__, rc); new_cci_dev->cci_state = CCI_STATE_DISABLED; g_cci_subdev = &new_cci_dev->msm_sd.sd; + for (i = 0; i < MASTER_MAX; i++) { + new_cci_dev->write_wq[i] = create_singlethread_workqueue( + "msm_cci_wq"); + if (!new_cci_dev->write_wq[i]) + pr_err("Failed to create write wq\n"); + } CDBG("%s cci subdev %p\n", __func__, &new_cci_dev->msm_sd.sd); CDBG("%s line %d\n", __func__, __LINE__); + return 0; cci_release_mem: diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h index 29ab4385632f2..63a95d8c27535 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include "msm_sd.h" @@ -37,9 +38,16 @@ #define MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11 11 #define BURST_MIN_FREE_SIZE 8 +enum cci_i2c_sync { + MSM_SYNC_DISABLE, + MSM_SYNC_ENABLE, +}; + + enum cci_i2c_queue_t { QUEUE_0, QUEUE_1, + QUEUE_INVALID, }; struct msm_camera_cci_client { @@ -63,10 +71,15 @@ enum msm_cci_cmd_type { MSM_CCI_I2C_READ, MSM_CCI_I2C_WRITE, MSM_CCI_I2C_WRITE_SEQ, + MSM_CCI_I2C_WRITE_ASYNC, MSM_CCI_GPIO_WRITE, + MSM_CCI_I2C_WRITE_SYNC, + MSM_CCI_I2C_WRITE_SYNC_BLOCK, }; struct msm_camera_cci_wait_sync_cfg { + uint16_t cid; + int16_t csid; uint16_t line; uint16_t delay; }; @@ -104,9 +117,14 @@ struct msm_camera_cci_ctrl { struct msm_camera_cci_master_info { uint32_t status; + atomic_t q_free[NUM_QUEUES]; + uint8_t q_lock[NUM_QUEUES]; uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; + struct mutex mutex_q[NUM_QUEUES]; + struct completion report_q[NUM_QUEUES]; + atomic_t done_pending[NUM_QUEUES]; }; struct msm_cci_clk_params_t { @@ -142,6 +160,7 @@ struct cci_device { enum msm_cci_state_t cci_state; uint32_t num_clk; uint32_t num_clk_cases; + struct mutex mutex; struct clk *cci_clk[CCI_NUM_CLK_MAX]; struct msm_camera_cci_i2c_queue_info @@ -158,6 +177,9 @@ struct cci_device { uint32_t cci_clk_src; uint8_t payload_size; uint8_t support_seq_write; + struct workqueue_struct *write_wq[MASTER_MAX]; + struct msm_camera_cci_wait_sync_cfg cci_wait_sync_cfg; + uint8_t valid_sync; }; enum msm_cci_i2c_cmd_type { @@ -193,6 +215,14 @@ enum msm_cci_gpio_cmd_type { CCI_GPIO_INVALID_CMD, }; +struct cci_write_async { + struct cci_device *cci_dev; + struct msm_camera_cci_ctrl c_ctrl; + enum cci_i2c_queue_t queue; + struct work_struct work; + enum cci_i2c_sync sync_en; +}; + #ifdef CONFIG_MSM_CCI struct v4l2_subdev *msm_cci_get_subdev(void); #else diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c old mode 100644 new mode 100755 index 996ba17931fa8..ca8d797f0af89 --- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c +++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c @@ -920,10 +920,71 @@ static long msm_eeprom_subdev_fops_ioctl32(struct file *file, unsigned int cmd, #endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifdef VENDOR_EDIT +static void eeprom_read_work(struct work_struct *work) +{ + int rc = 0; + int j = 0; + struct msm_eeprom_ctrl_t *e_ctrl = + container_of(work, struct msm_eeprom_ctrl_t, + read_work); + + mutex_lock(&msm_eeprom_mutex); + + rc = msm_camera_power_up(&e_ctrl->eboard_info->power_info, + e_ctrl->eeprom_device_type, + &e_ctrl->i2c_client); + if (rc) { + pr_err("failed rc %d\n", rc); + goto memdata_free; + } + + rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data); + if (rc < 0) { + pr_err("%s read_eeprom_memory failed\n", __func__); + goto power_down; + } + + for (j = 0; j < e_ctrl->cal_data.num_data; j++) + CDBG("memory_data[%d] = 0x%X\n", j, + e_ctrl->cal_data.mapdata[j]); + + e_ctrl->is_supported |= msm_eeprom_match_crc(&e_ctrl->cal_data); + e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1; + + rc = msm_camera_power_down(&e_ctrl->eboard_info->power_info, + e_ctrl->eeprom_device_type, + &e_ctrl->i2c_client); + if (rc) { + pr_err("failed rc %d\n", rc); + goto memdata_free; + } + + mutex_unlock(&msm_eeprom_mutex); + + return; + +power_down: + msm_camera_power_down(&e_ctrl->eboard_info->power_info, + e_ctrl->eeprom_device_type, + &e_ctrl->i2c_client); +memdata_free: + kfree(e_ctrl->cal_data.mapdata); + kfree(e_ctrl->cal_data.map); + mutex_unlock(&msm_eeprom_mutex); +} +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end + static int msm_eeprom_platform_probe(struct platform_device *pdev) { int rc = 0; +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifndef VENDOR_EDIT int j = 0; +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end uint32_t temp; struct msm_camera_cci_client *cci_client = NULL; @@ -941,6 +1002,11 @@ static int msm_eeprom_platform_probe(struct platform_device *pdev) } e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops; e_ctrl->eeprom_mutex = &msm_eeprom_mutex; +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifdef VENDOR_EDIT + INIT_WORK(&e_ctrl->read_work, eeprom_read_work); +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end e_ctrl->is_supported = 0; if (!of_node) { @@ -1036,6 +1102,8 @@ static int msm_eeprom_platform_probe(struct platform_device *pdev) if (rc < 0) goto board_free; +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifndef VENDOR_EDIT rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type, &e_ctrl->i2c_client); if (rc) { @@ -1059,6 +1127,11 @@ static int msm_eeprom_platform_probe(struct platform_device *pdev) pr_err("failed rc %d\n", rc); goto memdata_free; } +#else + schedule_work(&e_ctrl->read_work); +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end + v4l2_subdev_init(&e_ctrl->msm_sd.sd, e_ctrl->eeprom_v4l2_subdev_ops); v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl); @@ -1079,16 +1152,25 @@ static int msm_eeprom_platform_probe(struct platform_device *pdev) e_ctrl->msm_sd.sd.devnode->fops = &msm_eeprom_v4l2_subdev_fops; #endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifndef VENDOR_EDIT e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1; +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end + CDBG("%s X\n", __func__); return rc; +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifndef VENDOR_EDIT power_down: msm_camera_power_down(power_info, e_ctrl->eeprom_device_type, &e_ctrl->i2c_client); memdata_free: kfree(e_ctrl->cal_data.mapdata); kfree(e_ctrl->cal_data.map); +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end board_free: kfree(e_ctrl->eboard_info); cciclient_free: diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h old mode 100644 new mode 100755 index 9a04f06ae6714..79dcce26f84df --- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h +++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h @@ -44,6 +44,11 @@ struct msm_eeprom_ctrl_t { uint8_t is_supported; struct msm_eeprom_board_info *eboard_info; uint32_t subdev_id; +//Add by likelong@camera 2015.5.19 to reduce the device bring up time start +#ifdef VENDOR_EDIT + struct work_struct read_work; +#endif +//Add by likelong@camera 2015.5.19 to reduce the device bring up time end }; #endif diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index 4b0bde9586eec..f7da972b73212 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -172,6 +172,123 @@ int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client, return rc; } +int32_t msm_camera_cci_i2c_write_table_async( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting) +{ + int32_t rc = -EFAULT; + struct msm_camera_cci_ctrl cci_ctrl; + + if (!client || !write_setting) + return rc; + + if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR + && write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR) + || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA + && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA)) + return rc; + + cci_ctrl.cmd = MSM_CCI_I2C_WRITE_ASYNC; + cci_ctrl.cci_info = client->cci_client; + cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = + write_setting->reg_setting; + cci_ctrl.cfg.cci_i2c_write_cfg.data_type = write_setting->data_type; + cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type; + cci_ctrl.cfg.cci_i2c_write_cfg.size = write_setting->size; + rc = v4l2_subdev_call(client->cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + if (rc < 0) { + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); + return rc; + } + rc = cci_ctrl.status; + if (write_setting->delay > 20) + msleep(write_setting->delay); + else if (write_setting->delay) + usleep_range(write_setting->delay * 1000, (write_setting->delay + * 1000) + 1000); + + return rc; +} + +int32_t msm_camera_cci_i2c_write_table_sync( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting) +{ + int32_t rc = -EFAULT; + struct msm_camera_cci_ctrl cci_ctrl; + + if (!client || !write_setting) + return rc; + + if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR + && write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR) + || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA + && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA)) + return rc; + + cci_ctrl.cmd = MSM_CCI_I2C_WRITE_SYNC; + cci_ctrl.cci_info = client->cci_client; + cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = + write_setting->reg_setting; + cci_ctrl.cfg.cci_i2c_write_cfg.data_type = write_setting->data_type; + cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type; + cci_ctrl.cfg.cci_i2c_write_cfg.size = write_setting->size; + rc = v4l2_subdev_call(client->cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + if (rc < 0) { + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); + return rc; + } + rc = cci_ctrl.status; + if (write_setting->delay > 20) + msleep(write_setting->delay); + else if (write_setting->delay) + usleep_range(write_setting->delay * 1000, (write_setting->delay + * 1000) + 1000); + + return rc; +} + +int32_t msm_camera_cci_i2c_write_table_sync_block( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting) +{ + int32_t rc = -EFAULT; + struct msm_camera_cci_ctrl cci_ctrl; + + if (!client || !write_setting) + return rc; + + if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR + && write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR) + || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA + && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA)) + return rc; + + cci_ctrl.cmd = MSM_CCI_I2C_WRITE_SYNC_BLOCK; + cci_ctrl.cci_info = client->cci_client; + cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = + write_setting->reg_setting; + cci_ctrl.cfg.cci_i2c_write_cfg.data_type = write_setting->data_type; + cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type; + cci_ctrl.cfg.cci_i2c_write_cfg.size = write_setting->size; + rc = v4l2_subdev_call(client->cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + if (rc < 0) { + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); + return rc; + } + rc = cci_ctrl.status; + if (write_setting->delay > 20) + msleep(write_setting->delay); + else if (write_setting->delay) + usleep_range(write_setting->delay * 1000, (write_setting->delay + * 1000) + 1000); + + return rc; +} + int32_t msm_camera_cci_i2c_write_table( struct msm_camera_i2c_client *client, struct msm_camera_i2c_reg_setting *write_setting) @@ -211,6 +328,7 @@ int32_t msm_camera_cci_i2c_write_table( return rc; } + int32_t msm_camera_cci_i2c_write_seq_table( struct msm_camera_i2c_client *client, struct msm_camera_i2c_seq_reg_setting *write_setting) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h index 98abe64241942..043cf48958f57 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h @@ -55,6 +55,12 @@ struct msm_camera_i2c_fn_t { struct msm_camera_i2c_reg_array *reg_setting, uint32_t reg_size, uint32_t buf_len, uint32_t addr, enum msm_camera_i2c_data_type data_type); + int32_t (*i2c_write_table_async)(struct msm_camera_i2c_client *, + struct msm_camera_i2c_reg_setting *); + int32_t (*i2c_write_table_sync)(struct msm_camera_i2c_client *, + struct msm_camera_i2c_reg_setting *); + int32_t (*i2c_write_table_sync_block)(struct msm_camera_i2c_client *, + struct msm_camera_i2c_reg_setting *); }; int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client, @@ -75,6 +81,18 @@ int32_t msm_camera_cci_i2c_write_table( struct msm_camera_i2c_client *client, struct msm_camera_i2c_reg_setting *write_setting); +int32_t msm_camera_cci_i2c_write_table_async( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting); + +int32_t msm_camera_cci_i2c_write_table_sync( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting); + +int32_t msm_camera_cci_i2c_write_table_sync_block( + struct msm_camera_i2c_client *client, + struct msm_camera_i2c_reg_setting *write_setting); + int32_t msm_camera_cci_i2c_write_seq_table( struct msm_camera_i2c_client *client, struct msm_camera_i2c_seq_reg_setting *write_setting); diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c index 0846017f02650..fc398989f9ba8 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c @@ -721,7 +721,10 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, cdata->cfg.sensor_init_params.position, cdata->cfg.sensor_init_params.sensor_mount_angle); break; - case CFG_WRITE_I2C_ARRAY: { + case CFG_WRITE_I2C_ARRAY: + case CFG_WRITE_I2C_ARRAY_SYNC: + case CFG_WRITE_I2C_ARRAY_SYNC_BLOCK: + case CFG_WRITE_I2C_ARRAY_ASYNC: { struct msm_camera_i2c_reg_setting32 conf_array32; struct msm_camera_i2c_reg_setting conf_array; struct msm_camera_i2c_reg_array *reg_setting = NULL; @@ -773,9 +776,24 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, conf_array.reg_setting = reg_setting; - rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> - i2c_write_table(s_ctrl->sensor_i2c_client, - &conf_array); + if (CFG_WRITE_I2C_ARRAY == cdata->cfgtype) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table(s_ctrl->sensor_i2c_client, + &conf_array); + else if (CFG_WRITE_I2C_ARRAY_ASYNC == cdata->cfgtype) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_async(s_ctrl->sensor_i2c_client, + &conf_array); + else if (CFG_WRITE_I2C_ARRAY_SYNC_BLOCK == cdata->cfgtype) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_sync_block( + s_ctrl->sensor_i2c_client, + &conf_array); + else + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_sync(s_ctrl->sensor_i2c_client, + &conf_array); + kfree(reg_setting); break; } @@ -982,6 +1000,41 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, break; } + case CFG_SET_I2C_SYNC_PARAM: { + struct msm_camera_cci_ctrl cci_ctrl; + + s_ctrl->sensor_i2c_client->cci_client->cid = + cdata->cfg.sensor_i2c_sync_params.cid; + s_ctrl->sensor_i2c_client->cci_client->id_map = + cdata->cfg.sensor_i2c_sync_params.csid; + + CDBG("I2C_SYNC_PARAM CID:%d, line:%d delay:%d, cdid:%d\n", + s_ctrl->sensor_i2c_client->cci_client->cid, + cdata->cfg.sensor_i2c_sync_params.line, + cdata->cfg.sensor_i2c_sync_params.delay, + cdata->cfg.sensor_i2c_sync_params.csid); + + cci_ctrl.cmd = MSM_CCI_SET_SYNC_CID; + cci_ctrl.cfg.cci_wait_sync_cfg.line = + cdata->cfg.sensor_i2c_sync_params.line; + cci_ctrl.cfg.cci_wait_sync_cfg.delay = + cdata->cfg.sensor_i2c_sync_params.delay; + cci_ctrl.cfg.cci_wait_sync_cfg.cid = + cdata->cfg.sensor_i2c_sync_params.cid; + cci_ctrl.cfg.cci_wait_sync_cfg.csid = + cdata->cfg.sensor_i2c_sync_params.csid; + rc = v4l2_subdev_call(s_ctrl->sensor_i2c_client-> + cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + if (rc < 0) { + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); + rc = -EFAULT; + break; + } + + } + break; + default: rc = -EFAULT; break; @@ -1050,7 +1103,11 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp) cdata->cfg.sensor_init_params.position, cdata->cfg.sensor_init_params.sensor_mount_angle); break; - case CFG_WRITE_I2C_ARRAY: { + + case CFG_WRITE_I2C_ARRAY: + case CFG_WRITE_I2C_ARRAY_SYNC: + case CFG_WRITE_I2C_ARRAY_SYNC_BLOCK: + case CFG_WRITE_I2C_ARRAY_ASYNC: { struct msm_camera_i2c_reg_setting conf_array; struct msm_camera_i2c_reg_array *reg_setting = NULL; @@ -1093,8 +1150,24 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp) } conf_array.reg_setting = reg_setting; - rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table( - s_ctrl->sensor_i2c_client, &conf_array); + if (cdata->cfgtype == CFG_WRITE_I2C_ARRAY) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table(s_ctrl->sensor_i2c_client, + &conf_array); + else if (CFG_WRITE_I2C_ARRAY_ASYNC == cdata->cfgtype) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_async(s_ctrl->sensor_i2c_client, + &conf_array); + else if (CFG_WRITE_I2C_ARRAY_SYNC_BLOCK == cdata->cfgtype) + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_sync_block( + s_ctrl->sensor_i2c_client, + &conf_array); + else + rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> + i2c_write_table_sync(s_ctrl->sensor_i2c_client, + &conf_array); + kfree(reg_setting); break; } @@ -1367,6 +1440,42 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp) } break; } + + case CFG_SET_I2C_SYNC_PARAM: { + struct msm_camera_cci_ctrl cci_ctrl; + + s_ctrl->sensor_i2c_client->cci_client->cid = + cdata->cfg.sensor_i2c_sync_params.cid; + s_ctrl->sensor_i2c_client->cci_client->id_map = + cdata->cfg.sensor_i2c_sync_params.csid; + + CDBG("I2C_SYNC_PARAM CID:%d, line:%d delay:%d, cdid:%d\n", + s_ctrl->sensor_i2c_client->cci_client->cid, + cdata->cfg.sensor_i2c_sync_params.line, + cdata->cfg.sensor_i2c_sync_params.delay, + cdata->cfg.sensor_i2c_sync_params.csid); + + cci_ctrl.cmd = MSM_CCI_SET_SYNC_CID; + cci_ctrl.cfg.cci_wait_sync_cfg.line = + cdata->cfg.sensor_i2c_sync_params.line; + cci_ctrl.cfg.cci_wait_sync_cfg.delay = + cdata->cfg.sensor_i2c_sync_params.delay; + cci_ctrl.cfg.cci_wait_sync_cfg.cid = + cdata->cfg.sensor_i2c_sync_params.cid; + cci_ctrl.cfg.cci_wait_sync_cfg.csid = + cdata->cfg.sensor_i2c_sync_params.csid; + rc = v4l2_subdev_call(s_ctrl->sensor_i2c_client-> + cci_client->cci_subdev, + core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl); + if (rc < 0) { + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc); + rc = -EFAULT; + break; + } + + } + break; + default: rc = -EFAULT; break; @@ -1449,6 +1558,10 @@ static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = { msm_camera_cci_i2c_write_table_w_microdelay, .i2c_util = msm_sensor_cci_i2c_util, .i2c_write_conf_tbl = msm_camera_cci_i2c_write_conf_tbl, + .i2c_write_table_async = msm_camera_cci_i2c_write_table_async, + .i2c_write_table_sync = msm_camera_cci_i2c_write_table_sync, + .i2c_write_table_sync_block = msm_camera_cci_i2c_write_table_sync_block, + }; static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = { @@ -1460,6 +1573,9 @@ static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = { .i2c_write_table_w_microdelay = msm_camera_qup_i2c_write_table_w_microdelay, .i2c_write_conf_tbl = msm_camera_qup_i2c_write_conf_tbl, + .i2c_write_table_async = msm_camera_qup_i2c_write_table, + .i2c_write_table_sync = msm_camera_qup_i2c_write_table, + .i2c_write_table_sync_block = msm_camera_qup_i2c_write_table, }; int32_t msm_sensor_platform_probe(struct platform_device *pdev, @@ -1495,6 +1611,7 @@ int32_t msm_sensor_platform_probe(struct platform_device *pdev, cci_client->cci_i2c_master = s_ctrl->cci_i2c_master; cci_client->sid = s_ctrl->sensordata->slave_info->sensor_slave_addr >> 1; + cci_client->cid = 0; cci_client->retries = 3; cci_client->id_map = 0; if (!s_ctrl->func_tbl) diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c old mode 100644 new mode 100755 index 1cce6d6282189..c0ea0827ac281 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -18,6 +18,12 @@ #include "msm_cci.h" #include "msm_camera_dt_util.h" +#ifdef VENDOR_EDIT +//added by zhangxiaowei@camera 20150331 for product informatio +#include +#endif /* VENDOR_EDIT */ + + /* Logging macro */ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) @@ -943,6 +949,11 @@ int32_t msm_sensor_driver_probe(void *setting, s_ctrl->sensordata->cam_slave_info = slave_info; msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name); + #ifdef VENDOR_EDIT + //added by zhangxiaowei@camera 20150331 for product informatio + push_component_info(F_CAMERA, "OV5648", "Omnivision"); + push_component_info(R_CAMERA, "OV13860", "Omnivision"); + #endif /* VENDOR_EDIT */ return rc; diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c old mode 100644 new mode 100755 index 111a65bc6feaa..06a6ad3500007 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -54,6 +54,21 @@ static int32_t msm_ois_write_settings(struct msm_ois_ctrl_t *o_ctrl, settings[i].reg_data, settings[i].data_type); break; + #ifdef VENDOR_EDIT + //added by zhangxiaowei@camera 20150310 for qcom OIS architecture + case MSM_CAMERA_I2C_NO_DATA: + o_ctrl->i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR; + settings[i].reg_data = (settings[i].reg_addr & 0xFF); + settings[i].reg_addr = (settings[i].reg_addr >> 8); + settings[i].data_type = MSM_CAMERA_I2C_BYTE_DATA; + rc = o_ctrl->i2c_client.i2c_func_tbl->i2c_write( + &o_ctrl->i2c_client, + settings[i].reg_addr, + settings[i].reg_data, + settings[i].data_type); + o_ctrl->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; + break; + #endif /*VENDOR_EDIT*/ case MSM_CAMERA_I2C_DWORD_DATA: reg_setting.reg_addr = settings[i].reg_addr; reg_setting.reg_data[0] = (uint8_t) @@ -290,6 +305,8 @@ static int32_t msm_ois_config(struct msm_ois_ctrl_t *o_ctrl, sizeof(struct msm_camera_i2c_seq_reg_setting)); } else #endif +#ifndef VENDOR_EDIT +/*oem hufeng 20150303 modify*/ if (copy_from_user(&conf_array, (void *)cdata->cfg.settings, sizeof(struct msm_camera_i2c_seq_reg_setting))) { @@ -297,7 +314,16 @@ static int32_t msm_ois_config(struct msm_ois_ctrl_t *o_ctrl, rc = -EFAULT; break; } - +#else + rc =copy_from_user(&conf_array, + (void *)cdata->cfg.settings, + sizeof(struct msm_camera_i2c_seq_reg_setting)); + if (rc) { + pr_err("%s:%d failed\n", __func__, __LINE__); + rc = -EFAULT; + break; + } + #endif /*VENDOR_EDIT*/ if (!conf_array.size) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -EFAULT; @@ -674,6 +700,12 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) cci_client = msm_ois_t->i2c_client.cci_client; cci_client->cci_subdev = msm_cci_get_subdev(); cci_client->cci_i2c_master = msm_ois_t->cci_master; +#ifndef VENDOR_EDIT +/*oem hufeng 20150303 modify*/ + cci_client->cci_i2c_master = MASTER_MAX; +#else + cci_client->cci_i2c_master = msm_ois_t->cci_master; + #endif /*VENDOR_EDIT*/ v4l2_subdev_init(&msm_ois_t->msm_sd.sd, msm_ois_t->ois_v4l2_subdev_ops); v4l2_set_subdevdata(&msm_ois_t->msm_sd.sd, msm_ois_t); diff --git a/drivers/media/platform/msm/camera_v2/sensor/proximity/Makefile b/drivers/media/platform/msm/camera_v2/sensor/proximity/Makefile new file mode 100755 index 0000000000000..4bf2bd6137501 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/proximity/Makefile @@ -0,0 +1,4 @@ +ccflags-y += -Idrivers/media/platform/msm/camera_v2 +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci +obj-$(CONFIG_MSMB_CAMERA) += stmvl6180.o diff --git a/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.c b/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.c new file mode 100644 index 0000000000000..30d016f775c9e --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.c @@ -0,0 +1,1491 @@ +/* + * stmvl6180.c - Linux kernel module for STM VL6180 FlightSense Time-of-Flight + * + * Copyright (C) 2014 STMicroelectronics Imaging Division. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stmvl6180.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cci.h" + +//#define DEBUG_I2C_LOG +//debug + + +#define DEFAULT_CROSSTALK 0//4 // Already coded in 9.7 format + +//distance filter +#define DISTANCE_FILTER + +struct stmvl6180_data *vl6180_data_g; +struct mutex vl6180_mutex; + +#ifdef DISTANCE_FILTER +void VL6180_InitDistanceFilter(struct stmvl6180_data *vl6180_data); +uint16_t VL6180_DistanceFilter(struct stmvl6180_data *vl6180_data, + uint16_t m_trueRange_mm, uint16_t m_rawRange_mm, + uint32_t m_rtnSignalRate, uint32_t m_rtnAmbientRate, uint16_t errorCode); +uint32_t VL6180_StdDevDamper(uint32_t AmbientRate, uint32_t SignalRate, + uint32_t StdDevLimitLowLight, uint32_t StdDevLimitLowLightSNR, + uint32_t StdDevLimitHighLight, uint32_t StdDevLimitHighLightSNR); +#endif + +/* + * Communication functions + */ +#if 0 +static int stmvl6180_write(struct stmvl6180_data *vl6180_data, unsigned int reg_addr, + unsigned int reg_bytes, unsigned int reg_data) +{ + int err=0; + unsigned char write_buffer[6] = { 0, 0, 0, 0, 0,0 }; + + unsigned int i=0; + struct i2c_msg msg[1]; + + struct i2c_client *client = vl6180_data->i2c_client.client; + +#ifdef DEBUG_I2C_LOG + vl6180_dbgmsg("WRITE REG: 0x%x , VAL: 0x%x \n", reg_addr, reg_data); +#endif + //set register address + write_buffer[i++]=reg_addr >> 8; + write_buffer[i++]=reg_addr; + + switch (reg_bytes) { + case 4: + write_buffer[i++] = (unsigned char)(reg_data >> 24); + write_buffer[i++] = (unsigned char)(reg_data >> 16); + write_buffer[i++] = (unsigned char)(reg_data >> 8); + write_buffer[i++] = (unsigned char)(reg_data); + break; + case 2: + write_buffer[i++] = (unsigned char)(reg_data >> 8); + write_buffer[i++] = (unsigned char)(reg_data); + break; + case 1: + write_buffer[i++] = (unsigned char)(reg_data); + break; + default: + return -1; + } + + msg[0].addr = client->addr; + msg[0].flags = I2C_M_WR; + msg[0].buf= &write_buffer[0]; + msg[0].len=i; + + err = i2c_transfer(client->adapter,msg,1); //return the actual messages transfer + if(err != 1) { + pr_err("%s: i2c_transfer err:%d, addr:0x%x, reg:0x%x\n", __func__, err, client->addr, reg_addr); + return -1; + } + return 0; +} +#endif + +static int stmvl6180_read(struct stmvl6180_data *vl6180_data, unsigned int reg_addr, + unsigned int reg_bytes, unsigned int *reg_data, unsigned int bitMask) +{ + int err=0; + unsigned char read_buffer[4] = { 0, 0, 0, 0 }; + + + + err = vl6180_data->i2c_client.i2c_func_tbl->i2c_read_seq( + &vl6180_data->i2c_client, reg_addr, read_buffer, reg_bytes); + + if(err < 0) { + pr_err("%s: i2c_transfer err:%d, addr:0x%x, reg:0x%x\n", __func__, err, reg_addr, reg_addr); + return -1; + } + switch (reg_bytes) { + case 4: + *reg_data = (unsigned int)( (unsigned int)(read_buffer[0] <<24) + | (unsigned int)((read_buffer[1])<<16) + | (unsigned int)((read_buffer[2])<<8) + | (unsigned int)(read_buffer[3]) ); + break; + case 2: + *reg_data = (unsigned int)( (unsigned int)(read_buffer[0]<<8) + | (unsigned int)(read_buffer[1]) ); + break; + case 1: + *reg_data = (unsigned int)(read_buffer[0]); + break; + default: + return -1; + } +#ifdef DEBUG_I2C_LOG + vl6180_dbgmsg("READ REG: 0x%x , VAL: 0x%x BITMASK:0x%x\n", reg_addr, *reg_data, bitMask); +#endif + *reg_data &= bitMask; + return 0; +} +// 8 bits cci read +int vl6180_i2c_read_8bits(struct stmvl6180_data *vl6180_data, unsigned int addr, uint16_t *pdata) +{ + uint16_t tmp=0; + int rc = 0; + + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_read( + &vl6180_data->i2c_client, addr, + &tmp, MSM_CAMERA_I2C_BYTE_DATA); + + *pdata = (uint16_t)tmp; + return rc; +} +// 8 bits cci write +int vl6180_i2c_write_8bits(struct stmvl6180_data *vl6180_data, uint32_t addr, uint16_t data) +{ + int rc = 0; + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_write( + &vl6180_data->i2c_client, addr, data, MSM_CAMERA_I2C_BYTE_DATA); + + return rc; +} +// 16 bits cci write +int vl6180_i2c_write_16bits(struct stmvl6180_data *vl6180_data, uint32_t addr, uint16_t data) +{ + int rc = 0; + uint8_t write_buffer[2] = { 0, 0}; + write_buffer[1] = (uint8_t)(data & 0xFF); + write_buffer[0] = (uint8_t)(data >> 8); + + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_write_seq( + &vl6180_data->i2c_client, addr, write_buffer, MSM_CAMERA_I2C_WORD_DATA); + + return rc; +} + +// 32 bits cci read +int vl6180_i2c_read_32bits(struct stmvl6180_data *vl6180_data, unsigned int addr, unsigned int *pdata) +{ + unsigned char read_buffer[4] = { 0, 0, 0, 0 }; + int rc = 0; + + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_read_seq( + &vl6180_data->i2c_client, addr,read_buffer, 4); + + *pdata = (unsigned int)( (unsigned int)(read_buffer[0] <<24) + | (unsigned int)((read_buffer[1])<<16) + | (unsigned int)((read_buffer[2])<<8) + | (unsigned int)(read_buffer[3]) ); + + return rc; +} + +int stmvl6180_power_enable(struct stmvl6180_data *vl6180_data, unsigned int enable) +{ + int rc = 0; + + printk("%s %d\n",__func__, enable); + + if(enable) { + if(vl6180_data->enable == 0) { + if (regulator_count_voltages(vl6180_data->vdd_regulator) > 0) { + rc = regulator_set_voltage(vl6180_data->vdd_regulator, 2850000, 2850000); + if (rc) { + printk( "regulator set_vtg failed rc=%d\n", rc); + return -1; + } + } + rc = regulator_enable(vl6180_data->vdd_regulator); + printk("stmvl6180 power on vdd regulator %d\n", rc); + + if (regulator_count_voltages(vl6180_data->vdd_regulator_i2c) > 0) { + rc = regulator_set_voltage(vl6180_data->vdd_regulator_i2c, 1800000, 1800000); + if (rc) { + printk( "regulator set_vtg failed rc=%d\n", rc); + regulator_disable(vl6180_data->vdd_regulator); + return -1; + } + } + rc = regulator_enable(vl6180_data->vdd_regulator_i2c); + printk("stmvl6180 power on i2c regulator %d\n", rc); + + vl6180_data->enable = 1; + } + + msleep(20); + + gpio_direction_output(vl6180_data->ce_gpio,1); + + if (vl6180_data->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) { + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_util( + &vl6180_data->i2c_client, MSM_CCI_INIT); + if (rc < 0) + pr_err("cci_init failed\n"); + } + + } else { + + if (vl6180_data->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) { + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_util( + &vl6180_data->i2c_client, MSM_CCI_RELEASE); + if (rc < 0) + pr_err("cci_init failed\n"); + } + + gpio_direction_output(vl6180_data->ce_gpio,0); + + if(vl6180_data->enable) { + if (vl6180_data->vdd_regulator) { + regulator_disable(vl6180_data->vdd_regulator); + } + + if (vl6180_data->vdd_regulator_i2c) { + regulator_disable(vl6180_data->vdd_regulator_i2c); + } + vl6180_data->enable = 0; + } + } + return 0; +} + +int vl6180_init(struct stmvl6180_data *vl6180_data) +{ + int rc = 0; + int i; + int8_t offsetByte; + uint16_t modelID = 0; + uint16_t revID = 0; + int8_t rangeTemp = 0; + uint16_t chipidRange = 0; + uint16_t CrosstalkHeight; + uint16_t IgnoreThreshold; + uint16_t IgnoreThresholdHeight; + uint16_t dataByte; + uint16_t ambpart2partCalib1 = 0; + uint16_t ambpart2partCalib2 = 0; +#ifdef USE_INTERRUPTS + uint16_t chipidgpio = 0; +#endif + pr_err("vl6180_init ENTER!\n"); + + stmvl6180_power_enable(vl6180_data, 1); + + vl6180_i2c_read_8bits(vl6180_data, IDENTIFICATION__MODEL_ID, &modelID); + vl6180_i2c_read_8bits(vl6180_data, IDENTIFICATION__REVISION_ID, &revID); + pr_err("Model ID : 0x%X, REVISION ID : 0x%X\n", modelID, revID); + + //waitForStandby + for(i=0; i<100; i++) { + vl6180_i2c_read_8bits(vl6180_data, FIRMWARE__BOOTUP, &modelID); + if( (modelID & 0x01) == 1 ) { + i=100; + } + } + + //range device ready + for(i=0; i<100; i++) { + vl6180_i2c_read_8bits(vl6180_data, RESULT__RANGE_STATUS, &modelID); + if( (modelID & 0x01) == 1) { + i = 100; + } + } + + vl6180_i2c_write_8bits(vl6180_data, 0x0207, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x0208, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x0133, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x0096, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x0097, 0x54); + vl6180_i2c_write_8bits(vl6180_data, 0x00e3, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x00e4, 0x04); + vl6180_i2c_write_8bits(vl6180_data, 0x00e5, 0x02); + vl6180_i2c_write_8bits(vl6180_data, 0x00e6, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x00e7, 0x03); + vl6180_i2c_write_8bits(vl6180_data, 0x00f5, 0x02); + vl6180_i2c_write_8bits(vl6180_data, 0x00D9, 0x05); + + // AMB P2P calibration + vl6180_i2c_read_8bits(vl6180_data, SYSTEM__FRESH_OUT_OF_RESET, &dataByte); + if(dataByte==0x01) { + vl6180_i2c_read_8bits(vl6180_data, 0x26, &dataByte); + ambpart2partCalib1 = dataByte<<8; + vl6180_i2c_read_8bits(vl6180_data, 0x27, &dataByte); + ambpart2partCalib1 = ambpart2partCalib1 + dataByte; + vl6180_i2c_read_8bits(vl6180_data, 0x28, &dataByte); + ambpart2partCalib2 = dataByte<<8; + vl6180_i2c_read_8bits(vl6180_data, 0x29, &dataByte); + ambpart2partCalib2 = ambpart2partCalib2 + dataByte; + if(ambpart2partCalib1!=0) { + // p2p calibrated + vl6180_i2c_write_8bits(vl6180_data, 0xDA, (ambpart2partCalib1>>8)&0xFF); + vl6180_i2c_write_8bits(vl6180_data, 0xDB, ambpart2partCalib1&0xFF); + vl6180_i2c_write_8bits(vl6180_data, 0xDC, (ambpart2partCalib2>>8)&0xFF); + vl6180_i2c_write_8bits(vl6180_data, 0xDD, ambpart2partCalib2&0xFF); + } else { + // No p2p Calibration, use default settings + vl6180_i2c_write_8bits(vl6180_data, 0xDB, 0xCE); + vl6180_i2c_write_8bits(vl6180_data, 0xDC, 0x03); + vl6180_i2c_write_8bits(vl6180_data, 0xDD, 0xF8); + } + } + + vl6180_i2c_write_8bits(vl6180_data, 0x009f, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x00a3, 0x28); + vl6180_i2c_write_8bits(vl6180_data, 0x00b7, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x00bb, 0x28); + vl6180_i2c_write_8bits(vl6180_data, 0x00b2, 0x09); + vl6180_i2c_write_8bits(vl6180_data, 0x00ca, 0x09); + vl6180_i2c_write_8bits(vl6180_data, 0x0198, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x01b0, 0x17); + vl6180_i2c_write_8bits(vl6180_data, 0x01ad, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x00FF, 0x05); + vl6180_i2c_write_8bits(vl6180_data, 0x0100, 0x05); + vl6180_i2c_write_8bits(vl6180_data, 0x0199, 0x05); + vl6180_i2c_write_8bits(vl6180_data, 0x0109, 0x07); + vl6180_i2c_write_8bits(vl6180_data, 0x010a, 0x30); + vl6180_i2c_write_8bits(vl6180_data, 0x003f, 0x46); + vl6180_i2c_write_8bits(vl6180_data, 0x01a6, 0x1b); + vl6180_i2c_write_8bits(vl6180_data, 0x01ac, 0x3e); + vl6180_i2c_write_8bits(vl6180_data, 0x01a7, 0x1f); + vl6180_i2c_write_8bits(vl6180_data, 0x0103, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x0030, 0x00); + vl6180_i2c_write_8bits(vl6180_data, 0x001b, 0x0A); + vl6180_i2c_write_8bits(vl6180_data, 0x003e, 0x0A); + vl6180_i2c_write_8bits(vl6180_data, 0x0131, 0x04); + vl6180_i2c_write_8bits(vl6180_data, 0x0011, 0x10); + vl6180_i2c_write_8bits(vl6180_data, 0x0014, 0x24); + vl6180_i2c_write_8bits(vl6180_data, 0x0031, 0xFF); + vl6180_i2c_write_8bits(vl6180_data, 0x00d2, 0x01); + vl6180_i2c_write_8bits(vl6180_data, 0x00f2, 0x01); + + // RangeSetMaxConvergenceTime + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__MAX_CONVERGENCE_TIME, 0x3F); + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__MAX_AMBIENT_LEVEL_MULT, 0xFF);//SNR + + vl6180_i2c_read_8bits(vl6180_data, SYSTEM__FRESH_OUT_OF_RESET, &dataByte); + if(dataByte==0x01) { + //readRangeOffset + vl6180_i2c_read_8bits(vl6180_data, SYSRANGE__PART_TO_PART_RANGE_OFFSET, &dataByte); + rangeTemp = (int8_t)dataByte; + if(dataByte > 0x7F) { + rangeTemp -= 0xFF; + } + rangeTemp /= 3; + rangeTemp = rangeTemp +1; //roundg + //Range_Set_Offset + offsetByte = *((u8*)(&rangeTemp)); // round + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__PART_TO_PART_RANGE_OFFSET,(u8)offsetByte); + } + + // ClearSystemFreshOutofReset + vl6180_i2c_write_8bits(vl6180_data, SYSTEM__FRESH_OUT_OF_RESET, 0x0); + + // VL6180 CrossTalk + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__CROSSTALK_COMPENSATION_RATE, + (DEFAULT_CROSSTALK>>8)&0xFF); + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__CROSSTALK_COMPENSATION_RATE+1, + DEFAULT_CROSSTALK&0xFF); + + CrosstalkHeight = 40; + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__CROSSTALK_VALID_HEIGHT,CrosstalkHeight&0xFF); + + + // Will ignore all low distances (<100mm) with a low return rate + IgnoreThreshold = 64; // 64 = 0.5Mcps + IgnoreThresholdHeight = 33; // 33 * scaler3 = 99mm + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__RANGE_IGNORE_THRESHOLD, (IgnoreThreshold>>8)&0xFF); + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__RANGE_IGNORE_THRESHOLD+1,IgnoreThreshold&0xFF); + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__RANGE_IGNORE_VALID_HEIGHT,IgnoreThresholdHeight&0xFF); + + vl6180_i2c_read_8bits(vl6180_data, SYSRANGE__RANGE_CHECK_ENABLES, &dataByte); + dataByte = dataByte & 0xFE; // off ECE + dataByte = dataByte | 0x02; // on ignore thr + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__RANGE_CHECK_ENABLES, dataByte); + + // Init of Averaging samples + for(i=0; i<8;i++) { + vl6180_data->LastMeasurements[i]=65535; // 65535 means no valid data + } + vl6180_data->CurrentIndex = 0; + +#ifdef USE_INTERRUPTS + // SetSystemInterruptConfigGPIORanging + vl6180_i2c_read_8bits(vl6180_data, SYSTEM__INTERRUPT_CONFIG_GPIO, &chipidgpio); + vl6180_i2c_write_8bits(vl6180_data, SYSTEM__INTERRUPT_CONFIG_GPIO, (chipidgpio | 0x04)); +#endif + + //RangeSetSystemMode + chipidRange = 0x01; + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__START, chipidRange); + +#ifdef DISTANCE_FILTER + VL6180_InitDistanceFilter(vl6180_data); +#endif + + return rc; +} + +int vl6180_release(struct stmvl6180_data *vl6180_data) { + + stmvl6180_power_enable(vl6180_data, 0); + + return 0; +} + + +uint16_t vl6180_getDistance(struct stmvl6180_data *vl6180_data) +{ + uint16_t dist = 0; + uint16_t chipidcount = 0; + uint32_t m_rawRange_mm=0; + uint32_t m_rtnConvTime=0; + uint32_t m_rtnSignalRate=0; + uint32_t m_rtnAmbientRate=0; + uint32_t m_rtnSignalCount = 0; + uint32_t m_refSignalCount = 0; + uint32_t m_rtnAmbientCount =0; + uint32_t m_refAmbientCount =0; + uint32_t m_refConvTime =0; + uint32_t m_refSignalRate =0; + uint32_t m_refAmbientRate =0; + uint32_t cRtnSignalCountMax = 0x7FFFFFFF; + uint32_t cDllPeriods = 6; + uint32_t rtnSignalCountUInt = 0; + uint32_t calcConvTime = 0; + uint16_t chipidRangeStart = 0; + uint16_t statusCode = 0; + uint16_t errorCode = 0; + uint16_t m_rangeOffset; + unsigned int m_crossTalk; + + + vl6180_i2c_read_8bits(vl6180_data, SYSRANGE__START, &chipidRangeStart); + //Read Error Code + vl6180_i2c_read_8bits(vl6180_data, RESULT__RANGE_STATUS, &statusCode); + errorCode = statusCode>>4; + + printk("status code 0x%x, chipidRangeStart %x\n",statusCode,chipidRangeStart); + + if(((statusCode&0x01)==0x01)&&(chipidRangeStart==0x00)){ + + vl6180_i2c_read_8bits(vl6180_data, RESULT__RANGE_VAL, &dist); + + dist *= 3; + + vl6180_i2c_read_8bits(vl6180_data, RESULT__RANGE_RAW, &chipidcount); + m_rawRange_mm = (uint32_t)chipidcount; + + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_RETURN_SIGNAL_COUNT, &rtnSignalCountUInt); + + if(rtnSignalCountUInt > cRtnSignalCountMax){ + rtnSignalCountUInt = 0; + } + + m_rtnSignalCount = rtnSignalCountUInt; + + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_REFERENCE_SIGNAL_COUNT, &m_refSignalCount); + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_RETURN_AMB_COUNT, &m_rtnAmbientCount); + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_REFERENCE_AMB_COUNT, &m_refAmbientCount); + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_RETURN_CONV_TIME, &m_rtnConvTime); + vl6180_i2c_read_32bits(vl6180_data, RESULT__RANGE_REFERENCE_CONV_TIME, &m_refConvTime); + vl6180_i2c_read_8bits(vl6180_data, SYSRANGE__PART_TO_PART_RANGE_OFFSET, &m_rangeOffset); + stmvl6180_read(vl6180_data, SYSRANGE__CROSSTALK_COMPENSATION_RATE, 2, &m_crossTalk, 0xFFFF); + stmvl6180_read(vl6180_data, RESULT__RANGE_RETURN_RATE, 2, &m_rtnSignalRate, 0xFFFF); + stmvl6180_read(vl6180_data, RESULT__RANGE_REFERENCE_RATE, 2, &m_refSignalRate, 0xFFFF); + + vl6180_i2c_write_8bits(vl6180_data, SYSTEM__INTERRUPT_CLEAR, 0x07); + + calcConvTime = m_refConvTime; + if (m_rtnConvTime > m_refConvTime){ + calcConvTime = m_rtnConvTime; + } + if(calcConvTime==0) + calcConvTime=63000; +// m_rtnSignalRate = (m_rtnSignalCount*1000)/calcConvTime; +// m_refSignalRate = (m_refSignalCount*1000)/calcConvTime; + m_rtnAmbientRate = (m_rtnAmbientCount * cDllPeriods*1000)/calcConvTime; + m_refAmbientRate = (m_rtnAmbientCount * cDllPeriods*1000)/calcConvTime; + //printk("m_rtnSignalRate is %d, m_rtnAmbientRate is %d\n",m_rtnSignalRate,m_rtnAmbientRate); +#ifdef DISTANCE_FILTER + dist = VL6180_DistanceFilter(vl6180_data, dist, m_rawRange_mm*3, + m_rtnSignalRate, m_rtnAmbientRate, errorCode); +#endif + + // Start new measurement + //vl6180_i2c_write_8bits( SYSRANGE__START, 0x03); + vl6180_i2c_write_8bits(vl6180_data, SYSRANGE__START, 0x01); + vl6180_data->m_chipid = dist; + vl6180_data->rangeData.m_range = dist; + vl6180_data->rangeData.m_rtnRate = m_rtnSignalRate; + vl6180_data->rangeData.m_refRate = m_refSignalRate; + vl6180_data->rangeData.m_rtnAmbRate = m_rtnAmbientRate; + vl6180_data->rangeData.m_refAmbRate = m_refAmbientRate; + vl6180_data->rangeData.m_rawRange_mm = m_rawRange_mm*3; + vl6180_data->rangeData.m_convTime = calcConvTime; + + vl6180_data->rangeData.m_rtnSignalCount = m_rtnSignalCount; + vl6180_data->rangeData.m_refSignalCount = m_refSignalCount; + vl6180_data->rangeData.m_rtnAmbientCount = m_rtnAmbientCount; + vl6180_data->rangeData.m_refAmbientCount = m_refAmbientCount; + vl6180_data->rangeData.m_errorCode = statusCode; + vl6180_data->rangeData.m_rtnConvTime = m_rtnConvTime; + vl6180_data->rangeData.m_refConvTime = m_refConvTime; + vl6180_data->rangeData.m_rangeOffset = m_rangeOffset; + vl6180_data->rangeData.m_crossTalk = m_crossTalk; + + printk("dist %d, rate %d, ambi rate%d\n",dist, m_rtnSignalRate, m_rtnAmbientRate); + + } + else{ + // Return immediately with previous value + dist = vl6180_data->m_chipid; + } + return dist; + +} + +#ifdef DISTANCE_FILTER +void VL6180_InitDistanceFilter(struct stmvl6180_data *vl6180_data) +{ + int i; + + vl6180_data->MeasurementIndex = 0; + + vl6180_data->Default_ZeroVal = 0; + vl6180_data->Default_VAVGVal = 0; + vl6180_data->NoDelay_ZeroVal = 0; + vl6180_data->NoDelay_VAVGVal = 0; + vl6180_data->Previous_VAVGDiff = 0; + + vl6180_data->StdFilteredReads = 0; + vl6180_data->PreviousRangeStdDev = 0; + vl6180_data->PreviousReturnRateStdDev = 0; + + for (i = 0; i < FILTERNBOFSAMPLES; i++){ + vl6180_data->LastTrueRange[i] = FILTERINVALIDDISTANCE; + vl6180_data->LastReturnRates[i] = 0; + } +} + +uint32_t VL6180_StdDevDamper(uint32_t AmbientRate, uint32_t SignalRate, + uint32_t StdDevLimitLowLight, uint32_t StdDevLimitLowLightSNR, + uint32_t StdDevLimitHighLight, uint32_t StdDevLimitHighLightSNR) +{ + uint32_t newStdDev; + uint16_t SNR; + + if (AmbientRate > 0) + SNR = (uint16_t)((100 * SignalRate) / AmbientRate); + else + SNR = 9999; + + if (SNR >= StdDevLimitLowLightSNR){ + newStdDev = StdDevLimitLowLight; + } + else{ + if (SNR <= StdDevLimitHighLightSNR) + newStdDev = StdDevLimitHighLight; + else{ + newStdDev = (uint32_t)(StdDevLimitHighLight + + (SNR - StdDevLimitHighLightSNR) * (int)(StdDevLimitLowLight - StdDevLimitHighLight) / + (StdDevLimitLowLightSNR - StdDevLimitHighLightSNR)); + } + } + + return newStdDev; +} +uint16_t VL6180_DistanceFilter(struct stmvl6180_data *vl6180_data, uint16_t m_trueRange_mm, + uint16_t m_rawRange_mm, uint32_t m_rtnSignalRate, uint32_t m_rtnAmbientRate, uint16_t errorCode) +{ + uint16_t m_newTrueRange_mm = 0; + + uint16_t i; + uint16_t bypassFilter = 0; + + uint16_t registerValue; + // uint16_t dataByte; + uint32_t register32BitsValue1; + uint32_t register32BitsValue2; + + uint16_t ValidDistance = 0; + uint16_t MaxOrInvalidDistance = 0; + + uint16_t WrapAroundFlag = 0; + uint16_t NoWrapAroundFlag = 0; + uint16_t NoWrapAroundHighConfidenceFlag = 0; + + uint16_t FlushFilter = 0; + uint32_t RateChange = 0; + + uint16_t StdDevSamples = 0; + uint32_t StdDevDistanceSum = 0; + uint32_t StdDevDistanceMean = 0; + uint32_t StdDevDistance = 0; + uint32_t StdDevRateSum = 0; + uint32_t StdDevRateMean = 0; + uint32_t StdDevRate = 0; + uint32_t StdDevLimitWithTargetMove = 0; + + uint32_t VAVGDiff; + uint32_t IdealVAVGDiff; + uint32_t MinVAVGDiff; + uint32_t MaxVAVGDiff; + + // Filter Parameters + uint16_t WrapAroundLowRawRangeLimit = 20; + uint32_t WrapAroundLowReturnRateLimit = 800; + uint16_t WrapAroundLowRawRangeLimit2 = 55; + uint32_t WrapAroundLowReturnRateLimit2 = 300; + + uint32_t WrapAroundLowReturnRateFilterLimit = 600; + uint16_t WrapAroundHighRawRangeFilterLimit = 350; + uint32_t WrapAroundHighReturnRateFilterLimit = 900; + + uint32_t WrapAroundMaximumAmbientRateFilterLimit = 7500; + + // Temporal filter data and flush values + uint32_t MinReturnRateFilterFlush = 75; + uint32_t MaxReturnRateChangeFilterFlush = 50; + + // STDDEV values and damper values + uint32_t StdDevLimit = 300; + uint32_t StdDevLimitLowLight = 300; + uint32_t StdDevLimitLowLightSNR = 30; // 0.3 + uint32_t StdDevLimitHighLight = 2500; + uint32_t StdDevLimitHighLightSNR = 5; //0.05 + + uint32_t StdDevHighConfidenceSNRLimit = 8; + + uint32_t StdDevMovingTargetStdDevLimit = 90000; + uint32_t StdDevMovingTargetReturnRateLimit = 3500; + uint32_t StdDevMovingTargetStdDevForReturnRateLimit = 5000; + + uint32_t MAX_VAVGDiff = 1800; + + // WrapAroundDetection variables + uint16_t WrapAroundNoDelayCheckPeriod = 2; + + // Reads Filtering values + uint16_t StdFilteredReadsIncrement = 2; + uint16_t StdMaxFilteredReads = 4; + + // End Filter Parameters + + MaxOrInvalidDistance = (uint16_t)(255 * 3); + + // Check if distance is Valid or not + switch (errorCode){ + case 0x0C: + m_trueRange_mm = MaxOrInvalidDistance; + ValidDistance = 0; + break; + case 0x0D: + m_trueRange_mm = MaxOrInvalidDistance; + ValidDistance = 1; + break; + default: + if (m_rawRange_mm >= MaxOrInvalidDistance){ + ValidDistance = 0; + } + else{ + ValidDistance = 1; + } + break; + } + m_newTrueRange_mm = m_trueRange_mm; + + // Checks on low range data + if ((m_rawRange_mm < WrapAroundLowRawRangeLimit) && + (m_rtnSignalRate < WrapAroundLowReturnRateLimit)){ + //Not Valid distance + m_newTrueRange_mm = MaxOrInvalidDistance; + bypassFilter = 1; + } + if ((m_rawRange_mm < WrapAroundLowRawRangeLimit2) && + (m_rtnSignalRate < WrapAroundLowReturnRateLimit2)){ + //Not Valid distance + m_newTrueRange_mm = MaxOrInvalidDistance; + bypassFilter = 1; + } + + // Checks on Ambient rate level + if (m_rtnAmbientRate > WrapAroundMaximumAmbientRateFilterLimit){ + // Too high ambient rate + FlushFilter = 1; + bypassFilter = 1; + } + // Checks on Filter flush + if (m_rtnSignalRate < MinReturnRateFilterFlush){ + // Completely lost target, so flush the filter + FlushFilter = 1; + bypassFilter = 1; + } + if (vl6180_data->LastReturnRates[0] != 0){ + if (m_rtnSignalRate > vl6180_data->LastReturnRates[0]) + RateChange = (100 * (m_rtnSignalRate - vl6180_data->LastReturnRates[0])) / + vl6180_data->LastReturnRates[0]; + else + RateChange = (100 * (vl6180_data->LastReturnRates[0] - m_rtnSignalRate)) / + vl6180_data->LastReturnRates[0]; + } + else + RateChange = 0; + if (RateChange > MaxReturnRateChangeFilterFlush){ + FlushFilter = 1; + } + + if (FlushFilter == 1){ + vl6180_data->MeasurementIndex = 0; + for (i = 0; i < FILTERNBOFSAMPLES; i++){ + vl6180_data->LastTrueRange[i] = FILTERINVALIDDISTANCE; + vl6180_data->LastReturnRates[i] = 0; + } + } + else{ + for (i = (uint16_t)(FILTERNBOFSAMPLES - 1); i > 0; i--){ + vl6180_data->LastTrueRange[i] = vl6180_data->LastTrueRange[i - 1]; + vl6180_data->LastReturnRates[i] = vl6180_data->LastReturnRates[i - 1]; + } + } + if (ValidDistance == 1) + vl6180_data->LastTrueRange[0] = m_trueRange_mm; + else + vl6180_data->LastTrueRange[0] = FILTERINVALIDDISTANCE; + vl6180_data->LastReturnRates[0] = m_rtnSignalRate; + + // Check if we need to go through the filter or not + if (!(((m_rawRange_mm < WrapAroundHighRawRangeFilterLimit) && + (m_rtnSignalRate < WrapAroundLowReturnRateFilterLimit)) || + ((m_rawRange_mm >= WrapAroundHighRawRangeFilterLimit) && + (m_rtnSignalRate < WrapAroundHighReturnRateFilterLimit)))) + bypassFilter = 1; + + // Check which kind of measurement has been made + vl6180_i2c_read_8bits(vl6180_data, 0x01AC, ®isterValue); + + // Read data for filtering + vl6180_i2c_read_32bits(vl6180_data, 0x010C, ®ister32BitsValue1); + vl6180_i2c_read_32bits(vl6180_data, 0x0110, ®ister32BitsValue2); + if (registerValue == 0x3E){ + vl6180_data->Default_ZeroVal = register32BitsValue1; + vl6180_data->Default_VAVGVal = register32BitsValue2; + } + else{ + vl6180_data->NoDelay_ZeroVal = register32BitsValue1; + vl6180_data->NoDelay_VAVGVal = register32BitsValue2; + } + + if (bypassFilter == 1) { + // Do not go through the filter + if (registerValue != 0x3E) + { + vl6180_i2c_write_8bits(vl6180_data, 0x01AC, 0x3E); + } + // Set both Defaut and NoDelay To same value + vl6180_data->Default_ZeroVal = register32BitsValue1; + vl6180_data->Default_VAVGVal = register32BitsValue2; + vl6180_data->NoDelay_ZeroVal = register32BitsValue1; + vl6180_data->NoDelay_VAVGVal = register32BitsValue2; + vl6180_data->MeasurementIndex = 0; + + // Return immediately + return m_newTrueRange_mm; + } + + if (vl6180_data->MeasurementIndex % WrapAroundNoDelayCheckPeriod == 0){ + vl6180_i2c_write_8bits(vl6180_data, 0x01AC, 0x3F); + } + else{ + vl6180_i2c_write_8bits(vl6180_data, 0x01AC, 0x3E); + } + + vl6180_data->MeasurementIndex = (uint16_t)(vl6180_data->MeasurementIndex + 1); + + // Computes current VAVGDiff + if (vl6180_data->Default_VAVGVal > vl6180_data->NoDelay_VAVGVal) + VAVGDiff = vl6180_data->Default_VAVGVal - vl6180_data->NoDelay_VAVGVal; + else + VAVGDiff = 0; + vl6180_data->Previous_VAVGDiff = VAVGDiff; + + // Check the VAVGDiff + if(vl6180_data->Default_ZeroVal > vl6180_data->NoDelay_ZeroVal) + IdealVAVGDiff = vl6180_data->Default_ZeroVal - vl6180_data->NoDelay_ZeroVal; + else + IdealVAVGDiff = vl6180_data->NoDelay_ZeroVal - vl6180_data->Default_ZeroVal; + if (IdealVAVGDiff > MAX_VAVGDiff) + MinVAVGDiff = IdealVAVGDiff - MAX_VAVGDiff; + else + MinVAVGDiff = 0; + MaxVAVGDiff = IdealVAVGDiff + MAX_VAVGDiff; + if (VAVGDiff < MinVAVGDiff || VAVGDiff > MaxVAVGDiff){ + WrapAroundFlag = 1; + } + else{ + // Go through filtering check + + // StdDevLimit Damper on SNR + StdDevLimit = VL6180_StdDevDamper(m_rtnAmbientRate, m_rtnSignalRate, + StdDevLimitLowLight, StdDevLimitLowLightSNR, + StdDevLimitHighLight, StdDevLimitHighLightSNR); + + // Standard deviations computations + StdDevSamples = 0; + StdDevDistanceSum = 0; + StdDevDistanceMean = 0; + StdDevDistance = 0; + StdDevRateSum = 0; + StdDevRateMean = 0; + StdDevRate = 0; + for (i = 0; (i < FILTERNBOFSAMPLES) && (StdDevSamples < FILTERSTDDEVSAMPLES); i++){ + if (vl6180_data->LastTrueRange[i] != FILTERINVALIDDISTANCE){ + StdDevSamples = (uint16_t)(StdDevSamples + 1); + StdDevDistanceSum = (uint32_t)(StdDevDistanceSum + vl6180_data->LastTrueRange[i]); + StdDevRateSum = (uint32_t)(StdDevRateSum + vl6180_data->LastReturnRates[i]); + } + } + if (StdDevSamples > 0){ + StdDevDistanceMean = (uint32_t)(StdDevDistanceSum / StdDevSamples); + StdDevRateMean = (uint32_t)(StdDevRateSum / StdDevSamples); + } + StdDevSamples = 0; + StdDevDistanceSum = 0; + StdDevRateSum = 0; + for (i = 0; (i < FILTERNBOFSAMPLES) && (StdDevSamples < FILTERSTDDEVSAMPLES); i++){ + if (vl6180_data->LastTrueRange[i] != FILTERINVALIDDISTANCE){ + StdDevSamples = (uint16_t)(StdDevSamples + 1); + StdDevDistanceSum = (uint32_t)(StdDevDistanceSum + + (int)(vl6180_data->LastTrueRange[i] - StdDevDistanceMean) * + (int)(vl6180_data->LastTrueRange[i] - StdDevDistanceMean)); + StdDevRateSum = (uint32_t)(StdDevRateSum + (int)(vl6180_data->LastReturnRates[i] - + StdDevRateMean) * (int)(vl6180_data->LastReturnRates[i] - StdDevRateMean)); + } + } + if (StdDevSamples >= MINFILTERSTDDEVSAMPLES){ + StdDevDistance = (uint16_t)(StdDevDistanceSum / StdDevSamples); + StdDevRate = (uint16_t)(StdDevRateSum / StdDevSamples); + } + else{ + StdDevDistance = 0; + StdDevRate = 0; + } + + // Check Return rate standard deviation + if (StdDevRate < StdDevMovingTargetStdDevLimit){ + if (StdDevSamples < MINFILTERVALIDSTDDEVSAMPLES){ + m_newTrueRange_mm = MaxOrInvalidDistance; + } + else{ + // Check distance standard deviation + if (StdDevRate < StdDevMovingTargetReturnRateLimit) + StdDevLimitWithTargetMove = StdDevLimit + + (((StdDevMovingTargetStdDevForReturnRateLimit - StdDevLimit) * StdDevRate) / + StdDevMovingTargetReturnRateLimit); + else + StdDevLimitWithTargetMove = StdDevMovingTargetStdDevForReturnRateLimit; + + if ((StdDevDistance * StdDevHighConfidenceSNRLimit) < StdDevLimitWithTargetMove){ + NoWrapAroundHighConfidenceFlag = 1; + } + else{ + if (StdDevDistance < StdDevLimitWithTargetMove){ + if (StdDevSamples >= MINFILTERVALIDSTDDEVSAMPLES){ + NoWrapAroundFlag = 1; + } + else{ + m_newTrueRange_mm = MaxOrInvalidDistance; + } + } + else{ + WrapAroundFlag = 1; + } + } + } + } + else{ + WrapAroundFlag = 1; + } + } + + if (m_newTrueRange_mm == MaxOrInvalidDistance){ + if (vl6180_data->StdFilteredReads > 0) + vl6180_data->StdFilteredReads = (uint16_t)(vl6180_data->StdFilteredReads - 1); + } + else{ + if (WrapAroundFlag == 1){ + m_newTrueRange_mm = MaxOrInvalidDistance; + vl6180_data->StdFilteredReads = (uint16_t)(vl6180_data->StdFilteredReads + + StdFilteredReadsIncrement); + if (vl6180_data->StdFilteredReads > StdMaxFilteredReads) + vl6180_data->StdFilteredReads = StdMaxFilteredReads; + } + else{ + if (NoWrapAroundFlag == 1){ + if (vl6180_data->StdFilteredReads > 0){ + m_newTrueRange_mm = MaxOrInvalidDistance; + if (vl6180_data->StdFilteredReads > StdFilteredReadsIncrement) + vl6180_data->StdFilteredReads = (uint16_t)(vl6180_data->StdFilteredReads - + StdFilteredReadsIncrement); + else + vl6180_data->StdFilteredReads = 0; + } + } + else{ + if (NoWrapAroundHighConfidenceFlag == 1){ + vl6180_data->StdFilteredReads = 0; + } + } + } + } + vl6180_data->PreviousRangeStdDev = StdDevDistance; + vl6180_data->PreviousReturnRateStdDev = StdDevRate; + vl6180_data->PreviousStdDevLimit = StdDevLimitWithTargetMove; + + return m_newTrueRange_mm; +} + +#endif + + +static int stmvl6180_parse_dt(struct device *dev, struct stmvl6180_data *vl6180_data) +{ + int ret = 0; + + if (dev->of_node) { + struct device_node *np = dev->of_node; + + /* reset, irq gpio info */ + vl6180_data->irq_gpio = of_get_named_gpio(np, "st,irq-gpio", 0); + if( vl6180_data->irq_gpio < 0 ) { + printk(KERN_ERR"vl6180 irq_gpio not specified\n"); + return -1; + } + vl6180_data->ce_gpio = of_get_named_gpio(np, "st,standby-gpio", 0); + if( vl6180_data->ce_gpio < 0 ) { + printk(KERN_ERR"vl6180 ce gpio not specified\n"); + return -1; + } + printk("%s irq_gpio:%d ce_gpio:%d\n", __func__, vl6180_data->irq_gpio, vl6180_data->ce_gpio); + + ret = gpio_request(vl6180_data->ce_gpio, "vl_6180-ce"); + if (ret < 0) { + printk(KERN_ERR"%s: gpio request failed for vl6180\n", __func__); + return ret; + } + + ret = gpio_request(vl6180_data->irq_gpio,"vl_6180-int"); + if(ret < 0) { + printk(KERN_ERR "%s: gpio_request, err=%d", __func__, ret); + gpio_free(vl6180_data->ce_gpio); + return ret; + } + + vl6180_data->vdd_regulator = regulator_get(dev, "vdd_1v8"); + if(IS_ERR(vl6180_data->vdd_regulator)) { + printk(KERN_ERR"%s Regulator get failed vdd rc=%d\n", __func__, ret); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + return -1; + } + + vl6180_data->vdd_regulator_i2c = regulator_get(dev, "vcc_i2c_1v8"); + if(IS_ERR(vl6180_data->vdd_regulator_i2c) ) { + printk(KERN_ERR"%s Regulator get failed vdd_i2c rc=%d\n", __func__, ret); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_put(vl6180_data->vdd_regulator); + return -1; + } + + } + return ret; +} + +/* + * misc device file operation functions + */ +static int stmvl6180_ioctl_handler(struct file *file, + unsigned int cmd, unsigned long arg, void __user *p) +{ + + int rc=0; + struct stmvl6180_data *vl6180_data = file->private_data; + void __user *argp = (void __user *)p; + unsigned long data=0; + RegisterInfo register_data; + switch (cmd) { + case VL6180_IOCTL_INIT: /* init. */ + { + unsigned long *distance = (unsigned long *)argp; + data = vl6180_getDistance(vl6180_data); + *distance = data; + printk("vl6180_getDistance init return %ld\n",*distance); + return 0; + } + case VL6180_IOCTL_GETDATA: /* Get proximity value only */ + { + data = vl6180_getDistance(vl6180_data); + printk("vl6180_getDistance return %ld\n",data); + //return put_user(data, (unsigned long *)p); + return 0; + } + case VL6180_IOCTL_GETDATAS: /* Get all range data */ + { + data = vl6180_getDistance(vl6180_data); + + if (copy_to_user((RangeData *)p, &(vl6180_data->rangeData), sizeof(RangeData))) { + printk("error copy to user\n"); + rc = -EFAULT; + } + return rc; + } + case VL6180_IOCTL_CONFIG: /* Get all range data */ + { + if (copy_from_user(®ister_data, argp, sizeof(RegisterInfo))) { + printk("error copy from user\n"); + rc = -EFAULT; + } + printk("%s:%d wirte register 0x%x:0x%x\n", __func__, __LINE__, register_data.addr, register_data.data); + + if(register_data.size == 1) + rc = vl6180_i2c_write_8bits(vl6180_data, register_data.addr, register_data.data); + else if(register_data.size == 2) + rc = vl6180_i2c_write_16bits(vl6180_data, register_data.addr, register_data.data); + + if(rc) + printk("%s:%d failed to wirte register 0x%x:0x%x\n", __func__, __LINE__, register_data.addr, register_data.data); + return rc; + } + + default: + return -EINVAL; + } + return rc; +} + +static int stmvl6180_open(struct inode *inode, struct file *file) +{ + file->private_data = vl6180_data_g; + //vl6180_init(i2c_get_clientdata(file->private_data)); + if(vl6180_data_g!=NULL){ + vl6180_init(vl6180_data_g); + } + return 0; +} + +static int stmvl6180_release(struct inode *inode, struct file *file) +{ + //vl6180_release(i2c_get_clientdata(file->private_data)); + if(vl6180_data_g!=NULL){ + vl6180_release(vl6180_data_g); + } + return 0; +} + +static long stmvl6180_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + mutex_lock(&vl6180_mutex); + ret = stmvl6180_ioctl_handler(file, cmd, arg, (void __user *)arg); + mutex_unlock(&vl6180_mutex); + + return ret; +} + +static const struct file_operations stmvl6180_ranging_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = stmvl6180_ioctl, + .open = stmvl6180_open, + .release = stmvl6180_release, +}; + +static struct miscdevice stmvl6180_ranging_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "stmvl6180_ranging", + .fops = &stmvl6180_ranging_fops +}; + +static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = { + .i2c_read = msm_camera_cci_i2c_read, + .i2c_read_seq = msm_camera_cci_i2c_read_seq, + .i2c_write = msm_camera_cci_i2c_write, + .i2c_write_seq = msm_camera_cci_i2c_write_seq, + .i2c_write_table = msm_camera_cci_i2c_write_table, + .i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table, + .i2c_write_table_w_microdelay = + msm_camera_cci_i2c_write_table_w_microdelay, + .i2c_util = msm_sensor_cci_i2c_util, + .i2c_poll = msm_camera_cci_i2c_poll, +}; + +static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = { + .i2c_read = msm_camera_qup_i2c_read, + .i2c_read_seq = msm_camera_qup_i2c_read_seq, + .i2c_write = msm_camera_qup_i2c_write, + .i2c_write_table = msm_camera_qup_i2c_write_table, + .i2c_write_seq_table = msm_camera_qup_i2c_write_seq_table, + .i2c_write_table_w_microdelay = + msm_camera_qup_i2c_write_table_w_microdelay, + .i2c_poll = msm_camera_qup_i2c_poll, +}; + +/* + * Initialization function + */ + +static int stmvl6180_init_client(struct stmvl6180_data *vl6180_data) +{ + int err; + int id=0,module_major=0,module_minor=0; + int model_major=0,model_minor=0; + int i=0,val; + + vl6180_data->is_6180 = 1; + err = stmvl6180_read(vl6180_data, + VL6180_MODEL_ID_REG, + 1, + &id, + 0xFF); + if (id == 0xb4) { + printk("STM VL6180 Found\n"); + } + else if (id==0) { + printk("Not found STM VL6180\n"); + return -EIO; + } + + // Read Model Version + err = stmvl6180_read(vl6180_data, + VL6180_MODEL_REV_MAJOR_REG, + 1, + &model_major, + 0x07); + err = stmvl6180_read(vl6180_data, + VL6180_MODEL_REV_MINOR_REG, + 1, + &model_minor, + 0x07); + printk("STM VL6180 Model Version : %d.%d\n", model_major,model_minor); + + // Read Module Version + err = stmvl6180_read(vl6180_data, + VL6180_MODULE_REV_MAJOR_REG, + 1, + &module_major, + 0xFF); + err = stmvl6180_read(vl6180_data, + VL6180_MODULE_REV_MINOR_REG, + 1, + &module_minor, + 0xFF); + printk("STM VL6180 Module Version : %d.%d\n",module_major,module_minor); + + // Read Identification + printk("STM VL6180 Serial Number: "); + for (i=0; i<=(VL6180_FIRMWARE_REVISION_ID_REG-VL6180_REVISION_ID_REG);i++) { + err = stmvl6180_read(vl6180_data, + (VL6180_REVISION_ID_REG+i), + 1, + &val, + 0xFF); + printk("0x%x-",val); + } + printk("\n"); + + //set up i2c client + vl6180_data_g = vl6180_data; + return 0; +} + + +/* + * I2C init/probing/exit functions + */ + +static int32_t stmvl6180_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int rc = 0; + struct stmvl6180_data *vl6180_data = NULL; + printk("%s Enter\n",__func__); + + if (client == NULL) { + pr_err("msm_actuator_i2c_probe: client is null\n"); + return -EINVAL; + } + + vl6180_data = kzalloc(sizeof(struct stmvl6180_data), + GFP_KERNEL); + if (!vl6180_data) { + pr_err("%s:%d failed no memory\n", __func__, __LINE__); + return -ENOMEM; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + pr_err("i2c_check_functionality failed\n"); + goto probe_failure; + } + + rc = of_property_read_u32(client->dev.of_node, "cell-index", + &vl6180_data->subdev_id); + if (rc < 0) { + pr_err("failed rc %d\n", rc); + goto probe_failure; + } + + printk("%s cell-index %d, rc %d\n",__func__, vl6180_data->subdev_id, rc); + + rc = stmvl6180_parse_dt(&client->dev, vl6180_data); + if (rc < 0) { + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + + vl6180_data->i2c_client.client = client; + /* Set device type as I2C */ + vl6180_data->act_device_type = MSM_CAMERA_I2C_DEVICE; + vl6180_data->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl; + + vl6180_data->i2c_client.client->addr = 0x29; + vl6180_data->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; + + mutex_init(&vl6180_mutex); + vl6180_data->enable = 0; /* default mode is standard */ + + rc = stmvl6180_power_enable(vl6180_data, 1); + if(rc) { + printk(KERN_ERR "%s vl6180 power on error\n", __func__); + goto probe_failure; + } + + /* Initialize the STM VL6180 chip */ + rc = stmvl6180_init_client(vl6180_data); + if (rc) { + stmvl6180_power_enable(vl6180_data, 0); + goto probe_failure; + } + + stmvl6180_power_enable(vl6180_data, 0); + + //to register as a misc device + if (misc_register(&stmvl6180_ranging_dev) != 0) + printk(KERN_INFO "Could not register misc. dev for stmvl6180 ranging\n"); + + pr_info("stmvl6180_i2c_probe: succeeded\n"); + printk("%s Exit\n",__func__); + + return 0; + +probe_failure: + kfree(vl6180_data); + return rc; +} + +static int32_t stmvl6180_platform_probe(struct platform_device *pdev) +{ + int32_t rc = 0; + struct msm_camera_cci_client *cci_client = NULL; + struct stmvl6180_data *vl6180_data = NULL; + printk("%s Enter\n",__func__); + + if (!pdev->dev.of_node) { + pr_err("of_node NULL\n"); + return -EINVAL; + } + + vl6180_data = kzalloc(sizeof(struct stmvl6180_data), + GFP_KERNEL); + if (!vl6180_data) { + pr_err("%s:%d failed no memory\n", __func__, __LINE__); + return -ENOMEM; + } + rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index", + &pdev->id); + if (rc < 0) { + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + printk("%s cell-index %d, rc %d\n",__func__, pdev->id, rc); + + rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master", + &vl6180_data->cci_master); + if (rc < 0) { + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + printk("%s qcom,cci-master %d, rc %d\n",__func__, vl6180_data->cci_master, rc); + + /* Set platform device handle */ + vl6180_data->pdev = pdev; + + rc = stmvl6180_parse_dt(&pdev->dev, vl6180_data); + if (rc < 0) { + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + + vl6180_data->subdev_id = pdev->id; + + /* Set device type as platform device */ + vl6180_data->act_device_type = MSM_CAMERA_PLATFORM_DEVICE; + vl6180_data->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl; + vl6180_data->i2c_client.cci_client = kzalloc(sizeof( + struct msm_camera_cci_client), GFP_KERNEL); + if (!vl6180_data->i2c_client.cci_client) { + kfree(vl6180_data); + pr_err("failed no memory\n"); + return -ENOMEM; + } + + cci_client = vl6180_data->i2c_client.cci_client; + cci_client->cci_subdev = msm_cci_get_subdev(); + cci_client->sid = 0x29; + cci_client->retries = 3; + cci_client->id_map = 0; + cci_client->cci_i2c_master = vl6180_data->cci_master; + vl6180_data->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; + + mutex_init(&vl6180_mutex); + vl6180_data->enable = 0; /* default mode is standard */ + + rc = stmvl6180_power_enable(vl6180_data, 1); + if(rc) { + kfree(vl6180_data->i2c_client.cci_client); + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + + /* Initialize the STM VL6180 chip */ + rc = stmvl6180_init_client(vl6180_data); + if (rc) { + stmvl6180_power_enable(vl6180_data, 0); + kfree(vl6180_data->i2c_client.cci_client); + kfree(vl6180_data); + pr_err("failed rc %d\n", rc); + return rc; + } + + stmvl6180_power_enable(vl6180_data, 0); + + //to register as a misc device + if (misc_register(&stmvl6180_ranging_dev) != 0) + printk(KERN_INFO "Could not register misc. dev for stmvl6180 ranging\n"); + + printk("%s Exit\n",__func__); + return rc; +} + +static int stmvl6180_remove(struct i2c_client *client) +{ + struct stmvl6180_data *vl6180_data = i2c_get_clientdata(client); + + /* Power down the device */ + + stmvl6180_power_enable(vl6180_data, 0); + + regulator_put(vl6180_data->vdd_regulator); + regulator_put(vl6180_data->vdd_regulator_i2c); + + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + + misc_deregister(&stmvl6180_ranging_dev); + + kfree(vl6180_data); + + return 0; +} + +static const struct i2c_device_id stmvl6180_id[] = { + { STMVL6180_DRV_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, stmvl6180_id); + + + +static const struct of_device_id stmvl6180_dt_match[] = { + {.compatible = "stmv,vl6180", .data=NULL}, + {} +}; + +static struct i2c_driver stmvl6180_i2c_driver = { + .driver = { + .name = STMVL6180_DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = stmvl6180_dt_match, + }, + .probe = stmvl6180_i2c_probe, + .remove = stmvl6180_remove, + .id_table = stmvl6180_id, +}; + +MODULE_DEVICE_TABLE(of, stmvl6180_dt_match); + +static struct platform_driver stmvl6180_platform_driver = { + .driver = { + .name = "stmv,vl6180", + .owner = THIS_MODULE, + .of_match_table = stmvl6180_dt_match, + }, +}; + +static int __init stmvl6180_init(void) +{ + int32_t rc = 0; + printk("Enter %s:%d\n", __func__, __LINE__); + rc = platform_driver_probe(&stmvl6180_platform_driver, + stmvl6180_platform_probe); + if (!rc) + return rc; + + printk("%s:%d rc %d\n", __func__, __LINE__, rc); + return i2c_add_driver(&stmvl6180_i2c_driver); +} + +static void __exit stmvl6180_exit(void) +{ + i2c_del_driver(&stmvl6180_i2c_driver); +} + +MODULE_AUTHOR("STM"); +MODULE_DESCRIPTION("ST FlightSense Time-of-Flight sensor driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); + +module_init(stmvl6180_init); +module_exit(stmvl6180_exit); + diff --git a/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.h b/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.h new file mode 100644 index 0000000000000..f1534da50e595 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/proximity/stmvl6180.h @@ -0,0 +1,198 @@ +/* + * stmvl6180.c - Linux kernel module for STM VL6180 FlightSense Time-of-Flight + * + * Copyright (C) 2014 STMicroelectronics Imaging Division. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Defines + */ + + +#include +#include +#include +#include +#include +#include "msm_camera_i2c.h" +#include "msm_camera_dt_util.h" +#include "msm_camera_io_util.h" + + +#define STMVL6180_DRV_NAME "stmvl6180" + + +#define DRIVER_VERSION "1.1" +#define I2C_M_WR 0x00 + + +//if don't want to have output from vl6180_dbgmsg, comment out #DEBUG macro +#define DEBUG +#define vl6180_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args) + +//Device Registers +#define VL6180_MODEL_ID_REG 0x0000 +#define VL6180_MODEL_REV_MAJOR_REG 0x0001 +#define VL6180_MODEL_REV_MINOR_REG 0x0002 +#define VL6180_MODULE_REV_MAJOR_REG 0x0003 +#define VL6180_MODULE_REV_MINOR_REG 0x0004 + +#define VL6180_REVISION_ID_REG 0x0005 +#define VL6180_REVISION_ID_REG_BYTES 1 +#define VL6180_DATE_HI_REG 0x0006 +#define VL6180_DATE_HI_REG_BYTES 1 +#define VL6180_DATE_LO_REG 0x0007 +#define VL6180_DATE_LO_REG_BYTES 1 +#define VL6180_TIME_REG 0x0008 +#define VL6180_TIME_REG_BYTES 2 +#define VL6180_CODE_REG 0x000a +#define VL6180_CODE_REG_BYTES 1 +#define VL6180_FIRMWARE_REVISION_ID_REG 0x000b +#define VL6180_FIRMWARE_REVISION_ID_REG_BYTES 1 +/** + * range data structure + */ + +/* + * Global data + */ +//******************************** IOCTL definitions +#define VL6180_IOCTL_INIT _IO('p', 0x01) +#define VL6180_IOCTL_GETDATA _IO('p', 0x02) +#define VL6180_IOCTL_GETDATAS _IO('p', 0x03) +#define VL6180_IOCTL_CONFIG _IO('p', 0x04) +//******************************** VL6180 registers +#define IDENTIFICATION__MODEL_ID 0x000 +#define IDENTIFICATION__REVISION_ID 0x002 +#define FIRMWARE__BOOTUP 0x119 +#define RESULT__RANGE_STATUS 0x04D +#define GPIO_HV_PAD01__CONFIG 0x132 +#define SYSRANGE__MAX_CONVERGENCE_TIME 0x01C +#define SYSRANGE__RANGE_CHECK_ENABLES 0x02D +#define SYSRANGE__MAX_CONVERGENCE_TIME 0x01C +#define SYSRANGE__EARLY_CONVERGENCE_ESTIMATE 0x022 +#define SYSTEM__FRESH_OUT_OF_RESET 0x016 +#define SYSRANGE__PART_TO_PART_RANGE_OFFSET 0x024 +#define SYSRANGE__CROSSTALK_COMPENSATION_RATE 0x01E +#define SYSRANGE__CROSSTALK_VALID_HEIGHT 0x021 +#define SYSRANGE__RANGE_IGNORE_VALID_HEIGHT 0x025 +#define SYSRANGE__RANGE_IGNORE_THRESHOLD 0x026 +#define SYSRANGE__MAX_AMBIENT_LEVEL_MULT 0x02C +#define SYSALS__INTERMEASUREMENT_PERIOD 0x03E +#define SYSRANGE__INTERMEASUREMENT_PERIOD 0x01B +#define SYSRANGE__START 0x018 +#define RESULT__RANGE_VAL 0x062 +#define RESULT__RANGE_STRAY 0x063 +#define RESULT__RANGE_RAW 0x064 +#define RESULT__RANGE_RETURN_RATE 0x066 +#define RESULT__RANGE_REFERENCE_RATE 0x068 +#define RESULT__RANGE_RETURN_SIGNAL_COUNT 0x06C +#define RESULT__RANGE_REFERENCE_SIGNAL_COUNT 0x070 +#define RESULT__RANGE_RETURN_AMB_COUNT 0x074 +#define RESULT__RANGE_REFERENCE_AMB_COUNT 0x078 +#define RESULT__RANGE_RETURN_CONV_TIME 0x07C +#define RESULT__RANGE_REFERENCE_CONV_TIME 0x080 +#define SYSTEM__INTERRUPT_CLEAR 0x015 +#define RESULT__INTERRUPT_STATUS_GPIO 0x04F +#define SYSTEM__MODE_GPIO1 0x011 +#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x014 +#define RANGE__RANGE_SCALER 0x096 +#define SYSRANGE__PART_TO_PART_RANGE_OFFSET 0x024 +//******************************** VL6180 registers + +// Filter defines +#define FILTERNBOFSAMPLES 10 +#define FILTERSTDDEVSAMPLES 6 +#define MINFILTERSTDDEVSAMPLES 3 +#define MINFILTERVALIDSTDDEVSAMPLES 4 +#define FILTERINVALIDDISTANCE 65535 + +typedef struct +{ + unsigned int m_range; + unsigned int m_trueRange_mm; + unsigned int m_rawRange_mm; + unsigned int m_rtnRate; + unsigned int m_refRate; + unsigned int m_rtnAmbRate; + unsigned int m_refAmbRate; + unsigned int m_convTime; + unsigned int m_rtnSignalCount; + unsigned int m_refSignalCount; + unsigned int m_rtnAmbientCount; + unsigned int m_refAmbientCount; + unsigned int m_rtnConvTime; + unsigned int m_refConvTime; + int m_strayLightFactor; + unsigned int m_errorCode; + unsigned int m_rangeOffset; + unsigned int m_crossTalk; +}RangeData; + +/* + * driver data structs + */ +struct stmvl6180_data { + struct msm_camera_i2c_client i2c_client; + enum msm_camera_device_type_t act_device_type; + enum cci_i2c_master_t cci_master; + struct platform_device *pdev; + + int subdev_id; + + unsigned int is_6180; + unsigned int enable; + /* Range Data */ + RangeData rangeData; + + /* Register Data for tool */ + unsigned int register_addr; + unsigned int register_bytes; + + uint32_t MeasurementIndex; + // Distance Filter global variables + uint32_t Default_ZeroVal; + uint32_t Default_VAVGVal; + uint32_t NoDelay_ZeroVal; + uint32_t NoDelay_VAVGVal; + uint32_t Previous_VAVGDiff; + uint16_t LastTrueRange[FILTERNBOFSAMPLES]; + uint32_t LastReturnRates[FILTERNBOFSAMPLES]; + uint32_t PreviousRangeStdDev; + uint32_t PreviousStdDevLimit; + uint32_t PreviousReturnRateStdDev; + uint16_t StdFilteredReads; + uint32_t m_chipid; + uint16_t LastMeasurements[8]; + uint16_t AverageOnXSamples; + uint16_t CurrentIndex; + + /* Debug */ + unsigned int enableDebug; + + int irq_gpio; + int ce_gpio; + struct regulator *vdd_regulator; + struct regulator *vdd_regulator_i2c; +}; +typedef struct +{ + uint32_t addr; + unsigned int size; + uint16_t data; +}RegisterInfo; + diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/Makefile b/drivers/media/platform/msm/camera_v2/sensor/vl6180/Makefile new file mode 100755 index 0000000000000..8b6c922ec4fab --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the vl6180 drivers. +# + +# Each configuration option enables a list of files. + +ccflags-y += -Idrivers/media/platform/msm/camera_v2 +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/vl6180/inc +obj-$(CONFIG_MSMB_CAMERA) += stmvl6180.o +stmvl6180-objs := stmvl6180_module.o src/vl6180x_api.o src/vl6180x_i2c.o src/vl6180x_port_i2c.o + diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_api.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_api.h new file mode 100755 index 0000000000000..82992c21aed2c --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_api.h @@ -0,0 +1,1002 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ +/* + * @file VL6180x_api.h + * $Date: 2015-01-14 06:37:10 -0800 (Wed, 14 Jan 2015) $ + * $Revision: 2047 $ + */ + + + +#ifndef VL6180x_API_H_ +#define VL6180x_API_H_ + +#include "vl6180x_def.h" +#include "vl6180x_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup api_ll API Low Level Functions + * @brief API Low level functions + */ + +/** @defgroup api_hl API High Level Functions + * @brief API High level functions + */ + + +/* + * Check and set default platform dependent configuration + */ +#ifndef VL6180x_SINGLE_DEVICE_DRIVER +#error "VL6180x_SINGLE_DEVICE_DRIVER not defined" +/* TODO you may remove or comment these #error but it is best you update your vl6180x_platform.h file to define it*/ +#endif + + +#ifndef VL6180x_RANGE_STATUS_ERRSTRING +#warning "VL6180x_RANGE_STATUS_ERRSTRING not defined ?" +/* TODO you may remove or comment these #warning and keep the default below to keep compatibility + or update your vl6180x_platform.h file */ +/** + * force VL6180x_RANGE_STATUS_ERRSTRING to not supported when not part of any cfg file + */ +#define VL6180x_RANGE_STATUS_ERRSTRING 0 +#endif + +#ifndef VL6180X_SAFE_POLLING_ENTER +#warning "VL6180X_SAFE_POLLING_ENTER not defined, likely old vl6180x_cfg.h file ?" +/* TODO you may remove or comment these #warning and keep the default below to keep compatibility + or update your vl6180x_platform.h file */ +/** + * force VL6180X_SAFE_POLLING_ENTER to off when not in cfg file + */ +#define VL6180X_SAFE_POLLING_ENTER 0 /* off by default as in api 2.0 */ +#endif + +#ifndef VL6180X_LOG_ENABLE +/** + * Force VL6180X_LOG_ENABLE to none as default + */ +#define VL6180X_LOG_ENABLE 0 +#endif + +#if VL6180x_RANGE_STATUS_ERRSTRING +/**@def VL6180x_HAVE_RANGE_STATUS_ERRSTRING + * @brief is defined when @a #VL6180x_RANGE_STATUS_ERRSTRING is enable + */ +#define VL6180x_HAVE_RANGE_STATUS_ERRSTRING +#endif + + +/** @brief Get API version as "hex integer" 0xMMnnss + */ +#define VL6180x_ApiRevInt ((VL6180x_API_REV_MAJOR<<24)+(VL6180x_API_REV_MINOR<<16)+VL6180x_API_REV_SUB) + +/** Get API version as string for exe "2.1.12" " + */ +#define VL6180x_ApiRevStr VL6180X_STR(VL6180x_API_REV_MAJOR) "." VL6180X_STR(VL6180x_API_REV_MINOR) "." VL6180X_STR(VL6180x_API_REV_SUB) + +/** @defgroup api_init Init functions + * @brief API init functions + * @ingroup api_hl + * @{ + */ +/** + * @brief Wait for device booted after chip enable (hardware standby) + * @par Function Description + * After Chip enable Application you can also simply wait at least 1ms to ensure device is ready + * @warning After device chip enable (gpio0) de-asserted user must wait gpio1 to get asserted (hardware standby). + * or wait at least 400usec prior to do any low level access or api call . + * + * This function implements polling for standby but you must ensure 400usec from chip enable passed\n + * @warning if device get prepared @a VL6180x_Prepare() re-using these function can hold indefinitely\n + * + * @param dev The device + * @return 0 on success + */ +int VL6180x_WaitDeviceBooted(VL6180xDev_t dev); + +/** + * + * @brief One time device initialization + * + * To be called once and only once after device is brought out of reset (Chip enable) and booted see @a VL6180x_WaitDeviceBooted() + * + * @par Function Description + * When not used after a fresh device "power up" or reset, it may return @a #CALIBRATION_WARNING + * meaning wrong calibration data may have been fetched from device that can result in ranging offset error\n + * If application cannot execute device reset or need to run VL6180x_InitData multiple time + * then it must ensure proper offset calibration saving and restore on its own + * by using @a VL6180x_GetOffsetCalibrationData() on first power up and then @a VL6180x_SetOffsetCalibrationData() all all subsequent init + * + * @param dev The device + * @return 0 on success, @a #CALIBRATION_WARNING if failed + */ +int VL6180x_InitData(VL6180xDev_t dev ); + +/** + * @brief Configure GPIO1 function and set polarity. + * @par Function Description + * To be used prior to arm single shot measure or start continuous mode. + * + * The function uses @a VL6180x_SetupGPIOx() for setting gpio 1. + * @warning changing polarity can generate a spurious interrupt on pins. + * It sets an interrupt flags condition that must be cleared to avoid polling hangs. \n + * It is safe to run VL6180x_ClearAllInterrupt() just after. + * + * @param dev The device + * @param IntFunction The interrupt functionality to use one of :\n + * @a #GPIOx_SELECT_OFF \n + * @a #GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT + * @param ActiveHigh The interrupt line polarity see ::IntrPol_e + * use @a #INTR_POL_LOW (falling edge) or @a #INTR_POL_HIGH (rising edge) + * @return 0 on success + */ +int VL6180x_SetupGPIO1(VL6180xDev_t dev, uint8_t IntFunction, int ActiveHigh); + + /** + * @brief Prepare device for operation + * @par Function Description + * Does static initialization and reprogram common default settings \n + * Device is prepared for new measure, ready single shot ranging or ALS typical polling operation\n + * After prepare user can : \n + * @li Call other API function to set other settings\n + * @li Configure the interrupt pins, etc... \n + * @li Then start ranging or ALS operations in single shot or continuous mode + * + * @param dev The device + * @return 0 on success + */ + int VL6180x_Prepare(VL6180xDev_t dev); + + /** @} */ + + +/** @defgroup api_hl_range Ranging functions + * @brief Ranging functions + * @ingroup api_hl + * @{ + */ + + /** + * @brief Start continuous ranging mode + * + * @details End user should ensure device is in idle state and not already running + */ +int VL6180x_RangeStartContinuousMode(VL6180xDev_t dev); + +/** + * @brief Start single shot ranging measure + * + * @details End user should ensure device is in idle state and not already running + */ +int VL6180x_RangeStartSingleShot(VL6180xDev_t dev); + +/** + * @brief Set maximum convergence time + * + * @par Function Description + * Setting a low convergence time can impact maximal detectable distance. + * Refer to VL6180x Datasheet Table 7 : Typical range convergence time. + * A typical value for up to x3 scaling is 50 ms + * + * @param dev + * @param MaxConTime_msec + * @return 0 on success. <0 on error. >0 for calibration warning status + */ +int VL6180x_RangeSetMaxConvergenceTime(VL6180xDev_t dev, uint8_t MaxConTime_msec); + +/** + * @brief Single shot Range measurement in polling mode. + * + * @par Function Description + * Kick off a new single shot range then wait for ready to retrieve it by polling interrupt status \n + * Ranging must be prepared by a first call to @a VL6180x_Prepare() and it is safer to clear very first poll call \n + * This function reference VL6180x_PollDelay(dev) porting macro/call on each polling loop, + * but PollDelay(dev) may never be called if measure in ready on first poll loop \n + * Should not be use in continuous mode operation as it will stop it and cause stop/start misbehaviour \n + * \n This function clears Range Interrupt status , but not error one for that uses @a VL6180x_ClearErrorInterrupt() \n + * This range error is not related VL6180x_RangeData_t::errorStatus that refer measure status \n + * + * @param dev The device + * @param pRangeData Will be populated with the result ranging data @a VL6180x_RangeData_t + * @return 0 on success , @a #RANGE_ERROR if device reports an error case in it status (not cleared) use + * + * \sa ::VL6180x_RangeData_t + */ +int VL6180x_RangePollMeasurement(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData); + +/** + * @brief Check for measure readiness and get it if ready + * + * @par Function Description + * + * \n This function clears Range Interrupt for measure ready , but not error one for that uses @a VL6180x_ClearErrorInterrupt() \n + * \n This function do not start nor restart new single shot measure , for that use @a VL6180x_RangeStartSingleShot() \n + * + * @param dev The device + * @param pRangeData Will be populated with the result ranging data if available + * @return 0 when measure is ready pRange data is updated (untouched when not ready), >0 for warning and @a #NOT_READY if measurement not yet ready, <0 for error @a #RANGE_ERROR if device report an error, + */ +int VL6180x_RangeGetMeasurementIfReady(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData); + +/** + * @brief Retrieve range measurements set from device + * + * @par Function Description + * The measurement is made of range_mm status and error code @a VL6180x_RangeData_t \n + * Based on configuration selected extra measures are included. + * + * @warning should not be used in continuous if wrap around filter is active \n + * Does not perform any wait nor check for result availability or validity. + *\sa VL6180x_RangeGetResult for "range only" measurement + * + * @param dev The device + * @param pRangeData Pointer to the data structure to fill up + * @return 0 on success + */ +int VL6180x_RangeGetMeasurement(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData); +int VL6180x_RangeGetMeasurement_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pRangeData); +/** + * @brief Get ranging result and only that + * + * @par Function Description + * Unlike @a VL6180x_RangeGetMeasurement() this function only retrieves the range in millimeter \n + * It does any required up-scale translation\n + * It can be called after success status polling or in interrupt mode \n + * @warning these function is not doing wrap around filtering \n + * This function doesn't perform any data ready check! + * + * @param dev The device + * @param pRange_mm Pointer to range distance + * @return 0 on success + */ +int VL6180x_RangeGetResult(VL6180xDev_t dev, int32_t *pRange_mm); +int VL6180x_RangeGetResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, int32_t *pRange_mm); + +/** + * @brief Configure ranging interrupt reported to application + * + * @param dev The device + * @param ConfigGpioInt Select ranging report\n select one (and only one) of:\n + * @a #CONFIG_GPIO_INTERRUPT_DISABLED \n + * @a #CONFIG_GPIO_INTERRUPT_LEVEL_LOW \n + * @a #CONFIG_GPIO_INTERRUPT_LEVEL_HIGH \n + * @a #CONFIG_GPIO_INTERRUPT_OUT_OF_WINDOW \n + * @a #CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY + * @return 0 on success + */ +int VL6180x_RangeConfigInterrupt(VL6180xDev_t dev, uint8_t ConfigGpioInt); + + +/** + * @brief Clear range interrupt + * + * @param dev The device + * @return 0 On success + */ +#define VL6180x_RangeClearInterrupt(dev) VL6180x_ClearInterrupt(dev, INTERRUPT_CLEAR_RANGING) + +/** + * @brief Return ranging error interrupt status + * + * @par Function Description + * Appropriate Interrupt report must have been selected first by @a VL6180x_RangeConfigInterrupt() or @a VL6180x_Prepare() \n + * + * Can be used in polling loop to wait for a given ranging event or in interrupt to read the trigger \n + * Events triggers are : \n + * @a #RES_INT_STAT_GPIO_LOW_LEVEL_THRESHOLD \n + * @a #RES_INT_STAT_GPIO_HIGH_LEVEL_THRESHOLD \n + * @a #RES_INT_STAT_GPIO_OUT_OF_WINDOW \n (RES_INT_STAT_GPIO_LOW_LEVEL_THRESHOLD|RES_INT_STAT_GPIO_HIGH_LEVEL_THRESHOLD) + * @a #RES_INT_STAT_GPIO_NEW_SAMPLE_READY \n + * + * @sa IntrStatus_t + * @param dev The device + * @param pIntStatus Pointer to status variable to update + * @return 0 on success + */ +int VL6180x_RangeGetInterruptStatus(VL6180xDev_t dev, uint8_t *pIntStatus); + +#if VL6180x_RANGE_STATUS_ERRSTRING + +extern const char * ROMABLE_DATA VL6180x_RangeStatusErrString[]; +/** + * @brief Human readable error string for range error status + * + * @param RangeErrCode The error code as stored on @a VL6180x_RangeData_t::errorStatus + * @return error string , NULL for invalid RangeErrCode + * @sa ::RangeError_u + */ +const char * VL6180x_RangeGetStatusErrString(uint8_t RangeErrCode); +#else +#define VL6180x_RangeGetStatusErrString(...) NULL +#endif + +/** @} */ + +#if VL6180x_ALS_SUPPORT + +/** @defgroup api_hl_als ALS functions + * @brief ALS functions + * @ingroup api_hl + * @{ + */ + +/** + * @brief Run a single ALS measurement in single shot polling mode + * + * @par Function Description + * Kick off a new single shot ALS then wait new measurement ready to retrieve it ( polling system interrupt status register for als) \n + * ALS must be prepared by a first call to @a VL6180x_Prepare() \n + * \n Should not be used in continuous or interrupt mode it will break it and create hazard in start/stop \n + * + * @param dev The device + * @param pAlsData Als data structure to fill up @a VL6180x_AlsData_t + * @return 0 on success + */ +int VL6180x_AlsPollMeasurement(VL6180xDev_t dev, VL6180x_AlsData_t *pAlsData); + + +/** + * @brief Get actual ALS measurement + * + * @par Function Description + * Can be called after success status polling or in interrupt mode to retrieve ALS measurement from device \n + * This function doesn't perform any data ready check ! + * + * @param dev The device + * @param pAlsData Pointer to measurement struct @a VL6180x_AlsData_t + * @return 0 on success + */ +int VL6180x_AlsGetMeasurement(VL6180xDev_t dev, VL6180x_AlsData_t *pAlsData); + +/** + * @brief Configure ALS interrupts provide to application + * + * @param dev The Device + * @param ConfigGpioInt Select one (and only one) of : \n + * @a #CONFIG_GPIO_INTERRUPT_DISABLED \n + * @a #CONFIG_GPIO_INTERRUPT_LEVEL_LOW \n + * @a #CONFIG_GPIO_INTERRUPT_LEVEL_HIGH \n + * @a #CONFIG_GPIO_INTERRUPT_OUT_OF_WINDOW \n + * @a #CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY + * @return 0 on success may return #INVALID_PARAMS for invalid mode + */ +int VL6180x_AlsConfigInterrupt(VL6180xDev_t dev, uint8_t ConfigGpioInt); + + +/** + * @brief Set ALS integration period + * + * @param dev The device + * @param period_ms Integration period in msec. Value in between 50 to 100 msec is recommended\n + * @return 0 on success + */ +int VL6180x_AlsSetIntegrationPeriod(VL6180xDev_t dev, uint16_t period_ms); + +/** + * @brief Set ALS "inter-measurement period" + * + * @par Function Description + * The so call data-sheet "inter measurement period" is actually an extra inter-measurement delay + * + * @param dev The device + * @param intermeasurement_period_ms Inter measurement time in milli second\n + * @warning applied value is clipped to 2550 ms\n + * @return 0 on success if value is + */ +int VL6180x_AlsSetInterMeasurementPeriod(VL6180xDev_t dev, uint16_t intermeasurement_period_ms); + +/** + * @brief Set ALS analog gain code + * + * @par Function Description + * ALS gain code value programmed in @a SYSALS_ANALOGUE_GAIN . + * @param dev The device + * @param gain Gain code see datasheet or AlsGainLookUp for real value. Value is clipped to 7. + * @return 0 on success + */ + +int VL6180x_AlsSetAnalogueGain(VL6180xDev_t dev, uint8_t gain); +/** + * @brief Set thresholds for ALS continuous mode + * @warning Threshold are raw device value not lux! + * + * @par Function Description + * Basically value programmed in @a SYSALS_THRESH_LOW and @a SYSALS_THRESH_HIGH registers + * @param dev The device + * @param low ALS low raw threshold for @a SYSALS_THRESH_LOW + * @param high ALS high raw threshold for @a SYSALS_THRESH_HIGH + * @return 0 on success + */ +int VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high); + +/** + * @brief Clear ALS interrupt + * + * @param dev The device + * @return 0 On success + */ + #define VL6180x_AlsClearInterrupt(dev) VL6180x_ClearInterrupt(dev, INTERRUPT_CLEAR_ALS) + +/** + * Read ALS interrupt status + * @param dev Device + * @param pIntStatus Pointer to status + * @return 0 on success + */ +int VL6180x_AlsGetInterruptStatus(VL6180xDev_t dev, uint8_t *pIntStatus); + +/** @} */ +#endif + +/** @defgroup api_ll_init Init functions + * @brief Init functions + * @ingroup api_ll + * @{ + */ + +/** + * @brief Low level ranging and ALS register static settings (you should call @a VL6180x_Prepare() function instead) + * + * @param dev + * @return 0 on success + */ +int VL6180x_StaticInit(VL6180xDev_t dev); + + /** @} */ + +/** @defgroup api_ll_range Ranging functions + * @brief Ranging Low Level functions + * @ingroup api_ll + * @{ + */ + +/** + * @brief Wait for device to be ready (before a new ranging command can be issued by application) + * @param dev The device + * @param MaxLoop Max Number of i2c polling loop see @a #msec_2_i2cloop + * @return 0 on success. <0 when fail \n + * @ref VL6180x_ErrCode_t::TIME_OUT for time out \n + * @ref VL6180x_ErrCode_t::INVALID_PARAMS if MaxLop<1 + */ +int VL6180x_RangeWaitDeviceReady(VL6180xDev_t dev, int MaxLoop ); + +/** + * @brief Program Inter measurement period (used only in continuous mode) + * + * @par Function Description + * When trying to set too long time, it returns #INVALID_PARAMS + * + * @param dev The device + * @param InterMeasTime_msec Requires inter-measurement time in msec + * @return 0 on success + */ +int VL6180x_RangeSetInterMeasPeriod(VL6180xDev_t dev, uint32_t InterMeasTime_msec); + + +/** + * @brief Set device ranging scaling factor + * + * @par Function Description + * The ranging scaling factor is applied on the raw distance measured by the device to increase operating ranging at the price of the precision. + * Changing the scaling factor when device is not in f/w standby state (free running) is not safe. + * It can be source of spurious interrupt, wrongly scaled range etc ... + * @warning __This function doesns't update high/low threshold and other programmed settings linked to scaling factor__. + * To ensure proper operation, threshold and scaling changes should be done following this procedure: \n + * @li Set Group hold : @a VL6180x_SetGroupParamHold() \n + * @li Get Threshold @a VL6180x_RangeGetThresholds() \n + * @li Change scaling : @a VL6180x_UpscaleSetScaling() \n + * @li Set Threshold : @a VL6180x_RangeSetThresholds() \n + * @li Unset Group Hold : @a VL6180x_SetGroupParamHold() + * + * @param dev The device + * @param scaling Scaling factor to apply (1,2 or 3) + * @return 0 on success when up-scale support is not configured it fail for any + * scaling than the one statically configured. + */ +int VL6180x_UpscaleSetScaling(VL6180xDev_t dev, uint8_t scaling); + +/** + * @brief Get current ranging scaling factor + * + * @param dev The device + * @return The current scaling factor + */ +int VL6180x_UpscaleGetScaling(VL6180xDev_t dev); + + +/** + * @brief Give filtered state (wrap-around filter) of a range measurement + * @param pRangeData Range measurement data + * @return 0 means measure was not filtered, when not 0 range from device got filtered by filter post processing + */ +#define VL6180x_RangeIsFilteredMeasurement(pRangeData) ((pRangeData)->errorStatus == RangingFiltered) + +/** + * @brief Get the maximal distance for actual scaling + * @par Function Description + * Do not use prior to @a VL6180x_Prepare() or at least @a VL6180x_InitData() + * + * Any range value more than the value returned by this function is to be considered as "no target detected" + * or "no target in detectable range" \n + * @warning The maximal distance depends on the scaling + * + * @param dev The device + * @return The maximal range limit for actual mode and scaling + */ +uint16_t VL6180x_GetUpperLimit(VL6180xDev_t dev); + +/** + * @brief Apply low and high ranging thresholds that are considered only in continuous mode + * + * @par Function Description + * This function programs low and high ranging thresholds that are considered in continuous mode : + * interrupt will be raised only when an object is detected at a distance inside this [low:high] range. + * The function takes care of applying current scaling factor if any.\n + * To be safe, in continuous operation, thresholds must be changed under "group parameter hold" cover. + * Group hold can be activated/deactivated directly in the function or externally (then set 0) + * using /a VL6180x_SetGroupParamHold() function. + * + * @param dev The device + * @param low Low threshold in mm + * @param high High threshold in mm + * @param SafeHold Use of group parameters hold to surround threshold programming. + * @return 0 On success + */ +int VL6180x_RangeSetThresholds(VL6180xDev_t dev, uint16_t low, uint16_t high, int SafeHold); + +/** + * @brief Get scaled high and low threshold from device + * + * @par Function Description + * Due to scaling factor, the returned value may be different from what has been programmed first (precision lost). + * For instance VL6180x_RangeSetThresholds(dev,11,22) with scale 3 + * will read back 9 ((11/3)x3) and 21 ((22/3)x3). + + * @param dev The device + * @param low scaled low Threshold ptr can be NULL if not needed + * @param high scaled High Threshold ptr can be NULL if not needed + * @return 0 on success, return value is undefined if both low and high are NULL + * @warning return value is undefined if both low and high are NULL + */ +int VL6180x_RangeGetThresholds(VL6180xDev_t dev, uint16_t *low, uint16_t *high); + +/** + * @brief Set ranging raw thresholds (scaling not considered so not recommended to use it) + * + * @param dev The device + * @param low raw low threshold set to raw register + * @param high raw high threshold set to raw register + * @return 0 on success + */ +int VL6180x_RangeSetRawThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high); + +/** + * @brief Set Early Convergence Estimate ratio + * @par Function Description + * For more information on ECE check datasheet + * @warning May return a calibration warning in some use cases + * + * @param dev The device + * @param FactorM ECE factor M in M/D + * @param FactorD ECE factor D in M/D + * @return 0 on success. <0 on error. >0 on warning + */ +int VL6180x_RangeSetEceFactor(VL6180xDev_t dev, uint16_t FactorM, uint16_t FactorD); + +/** + * @brief Set Early Convergence Estimate state (See #SYSRANGE_RANGE_CHECK_ENABLES register) + * @param dev The device + * @param enable State to be set 0=disabled, otherwise enabled + * @return 0 on success + */ +int VL6180x_RangeSetEceState(VL6180xDev_t dev, int enable ); + +/** + * @brief Set activation state of the wrap around filter + * @param dev The device + * @param state New activation state (0=off, otherwise on) + * @return 0 on success + */ +int VL6180x_FilterSetState(VL6180xDev_t dev, int state); + +/** + * Get activation state of the wrap around filter + * @param dev The device + * @return Filter enabled or not, when filter is not supported it always returns 0S + */ +int VL6180x_FilterGetState(VL6180xDev_t dev); + +/** + * @brief Set ranging mode and start/stop measure (use high level functions instead : @a VL6180x_RangeStartSingleShot() or @a VL6180x_RangeStartContinuousMode()) + * + * @par Function Description + * When used outside scope of known polling single shot stopped state, \n + * user must ensure the device state is "idle" before to issue a new command. + * + * @param dev The device + * @param mode A combination of working mode (#MODE_SINGLESHOT or #MODE_CONTINUOUS) and start/stop condition (#MODE_START_STOP) \n + * @return 0 on success + */ +int VL6180x_RangeSetSystemMode(VL6180xDev_t dev, uint8_t mode); + +/** @} */ + +/** @defgroup api_ll_range_calibration Ranging calibration functions + * @brief Ranging calibration functions + * @ingroup api_ll + * @{ + */ +/** + * @brief Get part to part calibration offset + * + * @par Function Description + * Should only be used after a successful call to @a VL6180x_InitData to backup device nvm value + * + * @param dev The device + * @return part to part calibration offset from device + */ +int8_t VL6180x_GetOffsetCalibrationData(VL6180xDev_t dev); + +/** + * Set or over-write part to part calibration offset + * \sa VL6180x_InitData(), VL6180x_GetOffsetCalibrationData() + * @param dev The device + * @param offset Offset + */ +void VL6180x_SetOffsetCalibrationData(VL6180xDev_t dev, int8_t offset); + +/** + * @brief Set Cross talk compensation rate + * + * @par Function Description + * It programs register @a #SYSRANGE_CROSSTALK_COMPENSATION_RATE + * + * @param dev The device + * @param Rate Compensation rate (9.7 fix point) see datasheet for details + * @return 0 on success + */ +int VL6180x_SetXTalkCompensationRate(VL6180xDev_t dev, FixPoint97_t Rate); + +/** + * Set user configured part to part calibration offset + * \sa VL6180x_InitData() VL6180x_GetOffsetCalibrationData() + * @param dev The device + * @param offset Offset + * @ingroup api_adv + */ +void VL6180x_SetUserOffsetCalibration(VL6180xDev_t dev, int8_t offset); + +/** + * Set or over-hide part to part calibration offset and program the + * after scaling offset into register + * \sa VL6180x_InitData() VL6180x_GetOffsetCalibrationData() + * @param dev The device + * @param offset Offset + * @ingroup api_adv + */ +void VL6180x_SetOffset(VL6180xDev_t dev, int8_t offset); + +/** + * @brief Set User configured Cross talk compensation rate + * + * @par Function Description + * It sets the user_xatalk_calib variable vaule + * + * @param dev The device + * @param Rate Compensation rate (9.7 fix point) see datasheet for details + * @return 0 on success + * @ingroup api_adv + */ +void VL6180x_SetUserXTalkCompensationRate(VL6180xDev_t dev, FixPoint97_t offset); +/** @} */ + + + +#if VL6180x_ALS_SUPPORT +/** @defgroup api_ll_als ALS functions + * @brief ALS functions + * @ingroup api_ll + * @{ + */ + +/** + * @brief Wait for device to be ready for new als operation or max pollign loop (time out) + * @param dev The device + * @param MaxLoop Max Number of i2c polling loop see @a #msec_2_i2cloop + * @return 0 on success. <0 when @a VL6180x_ErrCode_t::TIME_OUT if timed out + */ +int VL6180x_AlsWaitDeviceReady(VL6180xDev_t dev, int MaxLoop ); + +/** + * @brief Set ALS system mode and start/stop measure + * + * @warning When used outside after single shot polling, \n + * User must ensure the device state is ready before issuing a new command (using @a VL6180x_AlsWaitDeviceReady()). \n + * Non respect of this, can cause loss of interrupt or device hanging. + * + * @param dev The device + * @param mode A combination of working mode (#MODE_SINGLESHOT or #MODE_CONTINUOUS) and start condition (#MODE_START_STOP) \n + * @return 0 on success + */ +int VL6180x_AlsSetSystemMode(VL6180xDev_t dev, uint8_t mode); + +/** @} */ +#endif + +/** @defgroup api_ll_misc Misc functions + * @brief Misc functions + * @ingroup api_ll + * @{ + */ + +/** + * Set Group parameter Hold state + * + * @par Function Description + * Group parameter holds @a #SYSTEM_GROUPED_PARAMETER_HOLD enable safe update (non atomic across multiple measure) by host + * \n The critical register group is composed of: \n + * #SYSTEM_INTERRUPT_CONFIG_GPIO \n + * #SYSRANGE_THRESH_HIGH \n + * #SYSRANGE_THRESH_LOW \n + * #SYSALS_INTEGRATION_PERIOD \n + * #SYSALS_ANALOGUE_GAIN \n + * #SYSALS_THRESH_HIGH \n + * #SYSALS_THRESH_LOW + * + * + * @param dev The device + * @param Hold Group parameter Hold state to be set (on/off) + * @return 0 on success + */ +int VL6180x_SetGroupParamHold(VL6180xDev_t dev, int Hold); + +/** + * @brief Set new device i2c address + * + * After completion the device will answer to the new address programmed. + * + * @sa AN4478: Using multiple VL6180X's in a single design + * @param dev The device + * @param NewAddr The new i2c address (7bit) + * @return 0 on success + */ +int VL6180x_SetI2CAddress(VL6180xDev_t dev, uint8_t NewAddr); + +/** + * @brief Fully configure gpio 0/1 pin : polarity and functionality + * + * @param dev The device + * @param pin gpio pin 0 or 1 + * @param IntFunction Pin functionality : either #GPIOx_SELECT_OFF or #GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT (refer to #SYSTEM_MODE_GPIO1 register definition) + * @param ActiveHigh Set active high polarity, or active low see @a ::IntrPol_e + * @return 0 on success + */ +int VL6180x_SetupGPIOx(VL6180xDev_t dev, int pin, uint8_t IntFunction, int ActiveHigh); + + +/** + * @brief Set interrupt pin polarity for the given GPIO + * + * @param dev The device + * @param pin Pin 0 or 1 + * @param active_high select active high or low polarity using @ref IntrPol_e + * @return 0 on success + */ +int VL6180x_SetGPIOxPolarity(VL6180xDev_t dev, int pin, int active_high); + +/** + * Select interrupt functionality for the given GPIO + * + * @par Function Description + * Functionality refer to @a SYSTEM_MODE_GPIO0 + * + * @param dev The device + * @param pin Pin to configure 0 or 1 (gpio0 or gpio1)\nNote that gpio0 is chip enable at power up ! + * @param functionality Pin functionality : either #GPIOx_SELECT_OFF or #GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT (refer to #SYSTEM_MODE_GPIO1 register definition) + * @return 0 on success + */ +int VL6180x_SetGPIOxFunctionality(VL6180xDev_t dev, int pin, uint8_t functionality); + +/** + * #brief Disable and turn to Hi-Z gpio output pin + * + * @param dev The device + * @param pin The pin number to disable 0 or 1 + * @return 0 on success + */ +int VL6180x_DisableGPIOxOut(VL6180xDev_t dev, int pin); + +/** + * @def msec_2_i2cloop + * @brief Number of I2C polling loop (an 8 bit register) to run for maximal wait time. + * + * @par Function Description + * When polling via I2C the overall time is mainly the I2C transaction time because it is a slow bus + * one 8 bit register poll on I2C bus timing is shown below: \n + * start + addr_w(a) + 2x8bit index(a) + stop + start + addr_rd(a) + 1x8bit data_rd(a) + stop \n + * 1 8 1 2*(8+1) 1 1 8 1 8 1 1 \n + * so 49 serial bits + * + * @param time_ms Time to wait in milli second 10 + * @param i2c_khz I2C bus frequencies in KHz for instance 400 + * @return The number of loops (at least 1) + */ +#define msec_2_i2cloop( time_ms, i2c_khz ) (((time_ms)*(i2c_khz)/49)+1) + +/** @} */ + + + +/** + * polarity use in @a VL6180x_SetupGPIOx() , @a VL6180x_SetupGPIO1() + */ +typedef enum { + INTR_POL_LOW =0, /*!< set active low polarity best setup for falling edge */ + INTR_POL_HIGH =1, /*!< set active high polarity best setup for rising edge */ +}IntrPol_e; + +/** @defgroup api_ll_intr Interrupts management functions + * @brief Interrupts management functions + * @ingroup api_ll + * @{ + */ + +/** + * @brief Get all interrupts cause + * + * @param dev The device + * @param status Ptr to interrupt status. You can use @a IntrStatus_t::val + * @return 0 on success + */ +int VL6180x_GetInterruptStatus(VL6180xDev_t dev, uint8_t *status); + +/** + * @brief Clear given system interrupt condition + * + * @par Function Description + * Clear given interrupt cause by writing into register #SYSTEM_INTERRUPT_CLEAR register. + * @param dev The device + * @param IntClear Which interrupt source to clear. Use any combinations of #INTERRUPT_CLEAR_RANGING , #INTERRUPT_CLEAR_ALS , #INTERRUPT_CLEAR_ERROR. + * @return 0 On success + */ +int VL6180x_ClearInterrupt(VL6180xDev_t dev, uint8_t IntClear ); + +/** + * @brief Clear error interrupt + * + * @param dev The device + * @return 0 On success + */ + #define VL6180x_ClearErrorInterrupt(dev) VL6180x_ClearInterrupt(dev, INTERRUPT_CLEAR_ERROR) + +/** + * @brief Clear All interrupt causes (als+range+error) + * + * @param dev The device + * @return 0 On success + */ +#define VL6180x_ClearAllInterrupt(dev) VL6180x_ClearInterrupt(dev, INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING|INTERRUPT_CLEAR_ALS) + +/** @} */ + + +/** @defgroup api_reg API Register access functions + * @brief Registers access functions called by API core functions + * @ingroup api_ll + * @{ + */ + +/** + * Write VL6180x single byte register + * @param dev The device + * @param index The register index + * @param data 8 bit register data + * @return success + */ +int VL6180x_WrByte(VL6180xDev_t dev, uint16_t index, uint8_t data); +/** + * Thread safe VL6180x Update (rd/modify/write) single byte register + * + * Final_reg = (Initial_reg & and_data) |or_data + * + * @param dev The device + * @param index The register index + * @param AndData 8 bit and data + * @param OrData 8 bit or data + * @return 0 on success + */ +int VL6180x_UpdateByte(VL6180xDev_t dev, uint16_t index, uint8_t AndData, uint8_t OrData); +/** + * Write VL6180x word register + * @param dev The device + * @param index The register index + * @param data 16 bit register data + * @return 0 on success + */ +int VL6180x_WrWord(VL6180xDev_t dev, uint16_t index, uint16_t data); +/** + * Write VL6180x double word (4 byte) register + * @param dev The device + * @param index The register index + * @param data 32 bit register data + * @return 0 on success + */ +int VL6180x_WrDWord(VL6180xDev_t dev, uint16_t index, uint32_t data); + +/** + * Read VL6180x single byte register + * @param dev The device + * @param index The register index + * @param data pointer to 8 bit data + * @return 0 on success + */ +int VL6180x_RdByte(VL6180xDev_t dev, uint16_t index, uint8_t *data); + +/** + * Read VL6180x word (2byte) register + * @param dev The device + * @param index The register index + * @param data pointer to 16 bit data + * @return 0 on success + */ +int VL6180x_RdWord(VL6180xDev_t dev, uint16_t index, uint16_t *data); + +/** + * Read VL6180x dword (4byte) register + * @param dev The device + * @param index The register index + * @param data pointer to 32 bit data + * @return 0 on success + */ +int VL6180x_RdDWord(VL6180xDev_t dev, uint16_t index, uint32_t *data); + +/** + * Read VL6180x a sequnce of registers + * @param dev The device + * @param index The register index + * @param pdata pointer to buffer + * @param count number of registers to read + * @return 0 on success + */ +int VL6180x_RdBuffer(VL6180xDev_t dev, uint16_t index, uint8_t *pdata, uint8_t count); + +/** @} */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* VL6180x_API_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_appcfg.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_appcfg.h new file mode 100755 index 0000000000000..e2ccf4868ef12 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_appcfg.h @@ -0,0 +1,92 @@ + +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ + + +/* + * vl6180x_appcfg.h + * + */ + +#ifndef VL6180X_APPCFG_H_ +#define VL6180X_APPCFG_H_ + + +/** + * @def VL6180x_SINGLE_DEVICE_DRIVER + * @brief enable lightweight single vl6180x device driver + * + * value 1 => single device capable + * Configure optimized APi for single device driver with static data and minimal use of ref pointer \n + * limited to single device driver or application in non multi thread/core environment \n + * + * value 0 => multiple device capable user must review "device" structure and type in porting files + * @ingroup Configuration + */ +#define VL6180x_SINGLE_DEVICE_DRIVER 1 + + +/** + * @def VL6180x_RANGE_STATUS_ERRSTRING + * @brief when define include range status Error string and related + * + * The string table lookup require some space in read only area + * @ingroup Configuration + */ +#define VL6180x_RANGE_STATUS_ERRSTRING 1 + +/** + * @def VL6180X_SAFE_POLLING_ENTER + * + * @brief Ensure safe polling method when set + * + * Polling for a condition can be hazardous and result in infinite looping if any previous interrupt status + * condition is not cleared. \n + * Setting these flags enforce error clearing on start of polling method to avoid it. + * the drawback are : \n + * @li extra use-less i2c bus usage and traffic + * @li potentially slower measure rate. + * If application ensure interrupt get clear on mode or interrupt configuration change + * then keep option disabled. \n + * To be safe set these option to 1 + * @ingroup Configuration + */ +#define VL6180X_SAFE_POLLING_ENTER 0 + + +/** + * @brief Enable function start/end logging + * + * requires porting @a #LOG_FUNCTION_START @a #LOG_FUNCTION_END @a #LOG_FUNCTION_END_FMT + * @ingroup Configuration + */ +#define VL6180X_LOG_ENABLE 0 + + + +#endif /* VL6180X_APPCFG_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_cfg.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_cfg.h new file mode 100755 index 0000000000000..1a7ebf6e8f97b --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_cfg.h @@ -0,0 +1,119 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ +/* + * $Date: 2015-01-08 05:27:09 -0800 (Thu, 08 Jan 2015) $ + * $Revision: 2038 $ + */ + +/** + * @file VL6180x_cfg.h + * + * Extended range configuration (for Hybrid AF applications for instance) + */ + +#ifndef VL6180x_CFG_H_ +#define VL6180x_CFG_H_ + + +/** @defgroup api_config Configuration + * @brief API static configuration + */ + + + +/** @ingroup api_config + * @{*/ + + +/** + * @def VL6180x_UPSCALE_SUPPORT + * @brief Configure up-scale capabilities and default up-scale factor for ranging operations + * + * @li 1 : Fixed scaling by 1 (no up-scaling support) + * @li 2 : Fixed scaling by 2 + * @li 3 : Fixed scaling by 3 + * @li -1 -2 -3 : Run time programmable through @a VL6180x_UpscaleSetScaling(). Default scaling factore is -VL6180x_UPSCALE_SUPPORT \n + */ +#define VL6180x_UPSCALE_SUPPORT -3 + +/** + * @def VL6180x_ALS_SUPPORT + * @brief Enable ALS support + * + * Set to 0 if ALS is not used in application. This can help reducing code size if it is a concern. + */ +#define VL6180x_ALS_SUPPORT 0 + +/** + * @def VL6180x_HAVE_DMAX_RANGING + * @brief Enable DMax calculation for ranging applications. + * + * When set to 1, __Dmax__ is returned by API typically when @a VL6180x_RangePollMeasurement() high level + * function is called (this is returned in @a VL6180x_RangeData_t structure). + * __Dmax__ is an estimation of the maximum distance (in mm) the product can report a valid distance of a 17% target for + * the current ambient light conditions (__Dmax__ decreases when ambient light increases). __Dmax__ should be used only + * when the product is not able to return a valid distance (no object or object is too far from the ranging sensor). + * Typically, this is done by checking the __errorStatus__ field of the @a VL6180x_RangeData_t structure returned by + * the @a VL6180x_RangePollMeasurement() function. + * You may refer to ::RangeError_u to get full list of supported error codes. + * @warning Dmax is estimated for a 17% grey target. If the real target has a reflectance lower than 17%, report Dmax could be over-estimated + */ +#define VL6180x_HAVE_DMAX_RANGING 1 + +/** + * @def VL6180x_WRAP_AROUND_FILTER_SUPPORT + * @brief Enable wrap around filter (WAF) feature + * + * In specific conditions, when targeting a mirror or a very reflective metal, a __wrap around__ effect can occur internally to the + * ranging product which results in returning a wrong distance (under-estimated). Goal of the WAF is to detect this wrap arround effect + * and to filter it by returning a non-valid distance : __errorStatus__ set to 16 (see ::RangeError_u) + * @warning Wrap-around filter can not be used when device is running in continuous mode + * + * @li 0 : Filter is not supported, no filtering code is included in API + * @li 1 : Filter is supported and active by default + * @li -1 : Filter is supported but is not active by default @a VL6180x_FilterSetState() can turn it on and off at any time + */ +#define VL6180x_WRAP_AROUND_FILTER_SUPPORT 1 + +/** + * @def VL6180x_EXTENDED_RANGE + * @brief Enable extended ranging support + * + * Device that do not formally support extended ranging should only be used with a scaling factor of 1. + * Correct operation with scaling factor other than 1 (>200mm ) is not granted by ST. + */ +#define VL6180x_EXTENDED_RANGE 1 + +#if (VL6180x_EXTENDED_RANGE) && (VL6180x_ALS_SUPPORT) +#warning "Als support should be OFF for extended range" +#endif + +#endif +/** @} */ // end of api_config + +/* VL6180x_CFG_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_def.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_def.h new file mode 100755 index 0000000000000..031ff6c4252d9 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_def.h @@ -0,0 +1,782 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ + +/* + * $Date: 2015-01-14 06:37:10 -0800 (Wed, 14 Jan 2015) $ + * $Revision: 2047 $ + */ + +/** + * @file VL6180x_def.h + * + * @brief Type definitions for vl6180x api. + * + */ + + +#ifndef _VL6180x_DEF +#define _VL6180x_DEF + +/** API major version */ +#define VL6180x_API_REV_MAJOR 3 +/** API minor version */ +#define VL6180x_API_REV_MINOR 0 +/** API sub version */ +#define VL6180x_API_REV_SUB 0xB3 + +#define VL6180X_STR_HELPER(x) #x +#define VL6180X_STR(x) VL6180X_STR_HELPER(x) + +#include "vl6180x_cfg.h" +#include "vl6180x_types.h" +#include "vl6180x_appcfg.h" + +/* + * check configuration macro raise error or warning and suggest a default value + */ + +#ifndef VL6180x_UPSCALE_SUPPORT +#error "VL6180x_UPSCALE_SUPPORT not defined" +/* TODO you must define value for upscale support in your vl6180x_cfg.h */ +#endif + +#ifndef VL6180x_ALS_SUPPORT +#error "VL6180x_ALS_SUPPORT not defined" +/* TODO you must define VL6180x_ALS_SUPPORT with a value in your vl6180x_cfg.h set to 0 do disable*/ +#endif + +#ifndef VL6180x_HAVE_DMAX_RANGING +#error "VL6180x_HAVE_DMAX_RANGING not defined" +/* TODO you may remove or comment these #error and keep the default below or update your vl6180x_cfg.h .h file */ +/** + * force VL6180x_HAVE_DMAX_RANGING to not supported when not part of cfg file + */ +#define VL6180x_HAVE_DMAX_RANGING 0 +#endif + +#ifndef VL6180x_EXTENDED_RANGE +#define VL6180x_EXTENDED_RANGE 0 +#endif + +#ifndef VL6180x_WRAP_AROUND_FILTER_SUPPORT +#error "VL6180x_WRAP_AROUND_FILTER_SUPPORT not defined ?" +/* TODO you may remove or comment these #error and keep the default below or update vl6180x_cfg.h file */ +/** + * force VL6180x_WRAP_AROUND_FILTER_SUPPORT to not supported when not part of cfg file + */ +#define VL6180x_WRAP_AROUND_FILTER_SUPPORT 0 +#endif + + + + +/**************************************** + * PRIVATE define do not edit + ****************************************/ + +/** Maximal buffer size ever use in i2c */ +#define VL6180x_MAX_I2C_XFER_SIZE 8 /* At present time it 6 byte max but that can change */ + +#if VL6180x_UPSCALE_SUPPORT < 0 +/** + * @def VL6180x_HAVE_UPSCALE_DATA + * @brief is defined if device data structure has data so when user configurable up-scale is active + */ +#define VL6180x_HAVE_UPSCALE_DATA /* have data only for user configurable up-scale config */ +#endif + +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT +/** + * @def VL6180x_HAVE_WRAP_AROUND_DATA + * @brief is defined if device data structure has filter data so when active in cfg file + */ +#define VL6180x_HAVE_WRAP_AROUND_DATA +#endif + +#if VL6180x_ALS_SUPPORT != 0 +/** + * @def VL6180x_HAVE_ALS_DATA + * @brief is defined when als data are include in device data structure so when als suport if configured + */ +#define VL6180x_HAVE_ALS_DATA +#endif + + +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT || VL6180x_HAVE_DMAX_RANGING + #define VL6180x_HAVE_RATE_DATA +#endif + +/** Error and warning code returned by API + * + * negative value are true error mostly fatal\n + * positive value are warning most of time it's ok to continue\n + */ +enum VL6180x_ErrCode_t{ + API_NO_ERROR = 0, + CALIBRATION_WARNING = 1, /*!< warning invalid calibration data may be in used \a VL6180x_InitData() \a VL6180x_GetOffsetCalibrationData \a VL6180x_SetOffsetCalibrationData*/ + MIN_CLIPED = 2, /*!< warning parameter passed was clipped to min before to be applied */ + NOT_GUARANTEED = 3, /*!< Correct operation is not guaranteed typically using extended ranging on vl6180x */ + NOT_READY = 4, /*!< the data is not ready retry */ + + API_ERROR = -1, /*!< Unqualified error */ + INVALID_PARAMS = -2, /*!< parameter passed is invalid or out of range */ + NOT_SUPPORTED = -3, /*!< function is not supported in current mode or configuration */ + RANGE_ERROR = -4, /*!< device report a ranging error interrupt status */ + TIME_OUT = -5, /*!< aborted due to time out */ +}; + +/** + * Filtered result data structure range data is to be used + */ +typedef struct RangeFilterResult_tag { + uint16_t range_mm; /*!< Filtered ranging value */ + uint16_t rawRange_mm; /*!< raw range value (scaled) */ +} RangeFilterResult_t; + +/** + * "small" unsigned data type used in filter + * + * if data space saving is not a concern it can be change to platform native unsigned int + */ +typedef uint8_t FilterType1_t; + +/** + * @def FILTER_NBOF_SAMPLES + * @brief sample history len used for wrap around filtering + */ +#define FILTER_NBOF_SAMPLES 10 +/** + * Wrap around filter internal data + */ +struct FilterData_t { + uint32_t MeasurementIndex; /*!< current measurement index */ + uint16_t LastTrueRange[FILTER_NBOF_SAMPLES]; /*!< filtered/corrected distance history */ + uint32_t LastReturnRates[FILTER_NBOF_SAMPLES]; /*!< Return rate history */ + uint16_t StdFilteredReads; /*!< internal use */ + FilterType1_t Default_ZeroVal; /*!< internal use */ + FilterType1_t Default_VAVGVal; /*!< internal use */ + FilterType1_t NoDelay_ZeroVal; /*!< internal use */ + FilterType1_t NoDelay_VAVGVal; /*!< internal use */ + FilterType1_t Previous_VAVGDiff; /*!< internal use */ +}; + +#if VL6180x_HAVE_DMAX_RANGING +typedef int32_t DMaxFix_t; +struct DMaxData_t { + int ambTuningWindowFactor_K; /*!< internal algo tuning (*1000) */ + + DMaxFix_t retSignalAt0mm; /*!< intermediate dmax computation value caching @a #SYSRANGE_CROSSTALK_COMPENSATION_RATE and private reg 0x02A */ + int32_t RegB8; /*!< register 0xB8 cached to speed reduce i2c traffic for dmax computation */ + /* place all word data below to optimize struct packing */ + + /* place all byte data below to optimize packing */ + uint8_t MaxConvTime; /*!< cached max convergence time @a #SYSRANGE_MAX_CONVERGENCE_TIME*/ +}; +#endif + +/** + * @struct VL6180xDevData_t + * + * @brief Per VL6180x device St private data structure \n + * End user should never access any of these field directly + * + * These must never access directly but only via VL6180xDev/SetData(dev, field) macro + */ +struct VL6180xDevData_t { + uint16_t EceFactorM; /*!< Ece Factor M numerator */ + uint16_t EceFactorD; /*!< Ece Factor D denominator*/ + +#ifdef VL6180x_HAVE_ALS_DATA + uint16_t IntegrationPeriod; /*!< cached als Integration period avoid slow read from device at each measure */ + uint16_t AlsGainCode; /*!< cached Als gain avoid slow read from device at each measure */ + uint16_t AlsScaler; /*!< cached Als scaler avoid slow read from device at each measure */ +#endif + +#ifdef VL6180x_HAVE_UPSCALE_DATA + uint8_t UpscaleFactor; /*!< up-scaling factor*/ +#endif + +#ifdef VL6180x_HAVE_WRAP_AROUND_DATA + uint8_t WrapAroundFilterActive; /*!< Filter on/off */ + struct FilterData_t FilterData; /*!< Filter internal data state history ... */ +#endif + +#if VL6180x_HAVE_DMAX_RANGING + struct DMaxData_t DMaxData; +#endif + int8_t Part2PartOffsetNVM; /*!< backed up NVM value */ +}; + +#if VL6180x_SINGLE_DEVICE_DRIVER +extern struct VL6180xDevData_t SingleVL6180xDevData; +#define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field) +/* is also used as direct accessor like VL6180xDevDataGet(dev, x)++*/ +#define VL6180xDevDataSet(dev, field, data) (SingleVL6180xDevData.field)=(data) +#endif + + +/** + * @struct VL6180x_RangeData_t + * @brief Range and any optional measurement data. + */ +typedef struct { + int32_t range_mm; /*!< range distance in mm. */ + int32_t signalRate_mcps; /*!< signal rate (MCPS)\n these is a 9.7 fix point value, which is effectively a measure of target reflectance.*/ + uint32_t errorStatus; /*!< Error status of the current measurement. \n + see @a ::RangeError_u @a VL6180x_GetRangeStatusErrString() */ + + +#ifdef VL6180x_HAVE_RATE_DATA + uint32_t rtnAmbRate; /*!< Return Ambient rate in KCount per sec related to \a RESULT_RANGE_RETURN_AMB_COUNT */ + uint32_t rtnRate; /*!< Return rate in KCount per sec related to \a RESULT_RANGE_RETURN_SIGNAL_COUNT */ + uint32_t rtnConvTime; /*!< Return Convergence time \a RESULT_RANGE_RETURN_CONV_TIME */ + uint32_t refConvTime; /*!< Reference convergence time \a RESULT_RANGE_REFERENCE_CONV_TIME */ +#endif + + +#if VL6180x_HAVE_DMAX_RANGING + uint32_t DMax; /*!< DMax when applicable */ +#endif + +#ifdef VL6180x_HAVE_WRAP_AROUND_DATA + RangeFilterResult_t FilteredData; /*!< Filter result main range_mm is updated */ +#endif + +//add for debug + uint32_t m_refAmbRate; + uint32_t m_convTime; + uint32_t m_rtnSignalCount; + uint32_t m_refSignalCount; + uint32_t m_rtnAmbientCount; + uint32_t m_refAmbientCount; + uint16_t m_refRate; + uint16_t m_crossTalk; + uint8_t m_rangeOffset; + uint8_t m_rawRange_mm; +//add for debug +}VL6180x_RangeData_t; + +/** + * @struct VL6180x_RangeResultData_t + * @brief Range Result data from device. + + */ +typedef struct { + uint8_t Result_range_status; + uint8_t Result_interrupt_status; + uint8_t Result_range_val; + uint8_t Result_range_raw; + uint16_t Result_range_return_rate; + uint16_t Result_range_reference_rate; + uint32_t Result_range_return_amb_rate; + uint32_t Result_range_reference_amb_rate; + uint32_t Result_range_return_signal_count; + uint32_t Result_range_reference_signal_count; + uint32_t Result_range_return_amb_count; + uint32_t Result_range_reference_amb_count; + uint32_t Result_range_return_conv_time; + uint32_t Result_range_reference_conv_time; + uint32_t Result_range_conv_time; + uint16_t Sys_range_cross_talk; + uint8_t Sys_range_range_offset; +}VL6180x_RangeResultData_t; + +/** use where fix point 9.7 bit values are expected + * + * given a floating point value f it's .7 bit point is (int)(f*(1<<7))*/ +typedef uint16_t FixPoint97_t; + +/** lux data type */ +typedef uint32_t lux_t; + +/** + * @brief This data type defines als measurement data. + */ +typedef struct VL6180x_AlsData_st{ + lux_t lux; /**< Light measurement (Lux) */ + uint32_t errorStatus; /**< Error status of the current measurement. \n + * No Error := 0. \n + * Refer to product sheets for other error codes. */ +}VL6180x_AlsData_t; + +/** + * @brief Range status Error code + * + * @a VL6180x_GetRangeStatusErrString() if configured ( @a #VL6180x_RANGE_STATUS_ERRSTRING ) + * related to register @a #RESULT_RANGE_STATUS and additional post processing + */ +typedef enum { + NoError_=0, /*!< 0 0b0000 NoError */ + VCSEL_Continuity_Test, /*!< 1 0b0001 VCSEL_Continuity_Test */ + VCSEL_Watchdog_Test, /*!< 2 0b0010 VCSEL_Watchdog_Test */ + VCSEL_Watchdog, /*!< 3 0b0011 VCSEL_Watchdog */ + PLL1_Lock, /*!< 4 0b0100 PLL1_Lock */ + PLL2_Lock, /*!< 5 0b0101 PLL2_Lock */ + Early_Convergence_Estimate,/*!< 6 0b0110 Early_Convergence_Estimate */ + Max_Convergence, /*!< 7 0b0111 Max_Convergence */ + No_Target_Ignore, /*!< 8 0b1000 No_Target_Ignore */ + Not_used_9, /*!< 9 0b1001 Not_used */ + Not_used_10, /*!< 10 0b1010 Not_used_ */ + Max_Signal_To_Noise_Ratio, /*!< 11 0b1011 Max_Signal_To_Noise_Ratio*/ + Raw_Ranging_Algo_Underflow,/*!< 12 0b1100 Raw_Ranging_Algo_Underflow*/ + Raw_Ranging_Algo_Overflow, /*!< 13 0b1101 Raw_Ranging_Algo_Overflow */ + Ranging_Algo_Underflow, /*!< 14 0b1110 Ranging_Algo_Underflow */ + Ranging_Algo_Overflow, /*!< 15 0b1111 Ranging_Algo_Overflow */ + + /* code below are addition for API/software side they are not hardware*/ + RangingFiltered =0x10, /*!< 16 0b10000 filtered by post processing*/ + +} RangeError_u; + + +/** @defgroup device_regdef Device registers & masks definitions + * @brief Device registers and masks definitions + */ + + +/** @ingroup device_regdef + * @{*/ + +/** + * The device model ID + */ +#define IDENTIFICATION_MODEL_ID 0x000 +/** + * Revision identifier of the Device for major change. + */ +#define IDENTIFICATION_MODULE_REV_MAJOR 0x003 +/** + * Revision identifier of the Device for minor change. + */ +#define IDENTIFICATION_MODULE_REV_MINOR 0x004 + + +/** + * @def SYSTEM_MODE_GPIO0 + * @brief Configures polarity and select which function gpio 0 serves. + * Gpio0 is chip enable at power up ! Be aware of all h/w implication of turning it to output. + * Same definition as #SYSTEM_MODE_GPIO1 + * @ingroup device_regdef + */ +#define SYSTEM_MODE_GPIO0 0x010 +/** + * @def SYSTEM_MODE_GPIO1 + * @brief Configures polarity and select what als or ranging functionality gpio pin serves. + * + * Function can be #GPIOx_SELECT_OFF #GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT.\n + * Same definition apply to register GPIO0 that is used as chip enable at power up. + * @ingroup device_regdef + */ +#define SYSTEM_MODE_GPIO1 0x011 + /** gpio pad POLARITY mask in #SYSTEM_MODE_GPIO1 (and/or 0) write 1 to set active high polarity (positive edge) */ + #define GPIOx_POLARITY_SELECT_MASK 0x20 + /** gpio pad Function select shift in #SYSTEM_MODE_GPIO1 or 0 */ + #define GPIOx_FUNCTIONALITY_SELECT_SHIFT 1 + /** gpio pad Function select mask in #SYSTEM_MODE_GPIO1 or 0 */ + #define GPIOx_FUNCTIONALITY_SELECT_MASK (0xF<i2c_lock, flags) +#define DoneI2CAccess(dev) spin_unlock_irqrestore(dev->i2c_lock,flags) +@endcode + +* __POSIX pthread__ application porting could be as follows :\n +* @code +struct MyVL6180Dev_t { + struct VL6180xDevData_t StData; + ... + pthread_mutex_t *lock; +}; +typedef struct MyVL6180Dev_t *VL6180xDev_t; + +#define VL6180x_I2C_USER_VAR //no need +#define VL6180x_GetI2CAccess(dev) pthread_mutex_lock(dev->lock) +#define VL6180x_DoneI2CAcces(dev) pthread_mutex_unlock(dev->lock) + * @endcode + */ + +struct i2c_client* i2c_getclient(void); + +/** + * @def I2C_BUFFER_CONFIG + * + * @brief Configure device register I2C access + * + * @li 0 : one GLOBAL buffer \n + * Use one global buffer of MAX_I2C_XFER_SIZE byte in data space \n + * This solution is not multi-device compliant nor multi-thread cpu safe \n + * It can be the best option for small 8/16 bit MCU without stack and limited ram (STM8s, 80C51 ...) + * + * @li 1 : ON_STACK/local \n + * Use local variable (on stack) buffer \n + * This solution is multi-thread with use of i2c resource lock or mutex see @a VL6180x_GetI2CAccess() \n + * + * @li 2 : User defined \n + * Per device potentially dynamic allocated. Requires @a VL6180x_GetI2cBuffer() to be implemented. + * @ingroup Configuration + */ +#define I2C_BUFFER_CONFIG 1 + +/** + * @brief Write data buffer to VL6180x device via i2c + * @param dev The device to write to + * @param buff The data buffer + * @param len The length of the transaction in byte + * @return 0 on success + * @ingroup cci_i2c + */ +int VL6180x_I2CWrite(VL6180xDev_t dev, uint8_t *buff, uint8_t len); + +/** + * + * @brief Read data buffer from VL6180x device via i2c + * @param dev The device to read from + * @param buff The data buffer to fill + * @param len The length of the transaction in byte + * @return 0 on success + * @ingroup cci_i2c + */ +int VL6180x_I2CRead(VL6180xDev_t dev, uint8_t *buff, uint8_t len); + + +/** + * @brief Declare any required variables used by i2c lock (@a VL6180x_DoneI2CAccess() and @a VL6180x_GetI2CAccess()) + * and buffer access : @a VL6180x_GetI2cBuffer() + * + * @ingroup cci_i2c + */ +#define VL6180x_I2C_USER_VAR + +/** + * @brief Acquire lock or mutex for access to i2c data buffer and bus.\n + * Delete the default VL6180x_GetI2CAccess 'do-nothing' macro below if you decide to implement this function. + * + * This function is used to perform i2c bus level and multiple access locking required for multi thread/proccess system.\n + * Multiple access (read and update) will lock once and do multiple basic i2c rd/wr to complete the overall transfer.\n + * When no locking is needed this can be a void macro.\n + * + * @param dev the device + * @ingroup cci_i2c + */ +void VL6180x_GetI2CAccess(VL6180xDev_t dev); + +/** + * @def VL6180x_GetI2CAccess + * @brief Default 'do-nothing' macro for @a VL6180x_GetI2CAccess(). Delete if used. + * @ingroup cci_i2c + */ +#define VL6180x_GetI2CAccess(dev) (void)0 /* TODO delete if function used */ + +/** + * @brief Release acquired lock or mutex for i2c access.\n + * Delete default VL6180x_DoneI2CAccess 'do-nothing' macro below if implementing that function. + * + * This function is used to release the acquired lock. + * @param dev The device + * @ingroup cci_i2c + */ +void VL6180x_DoneI2CAccess(VL6180xDev_t dev); + +/** @def VL6180x_DoneI2CAcces + * @brief Default 'do-nothing' macro for @a VL6180x_DoneI2CAcces(). Delete if used. + * @ingroup cci_i2c + */ +#define VL6180x_DoneI2CAcces(dev) (void)0 /*TODO delete if function used */ + +/** + * @brief Provided data buffer for i2c access for at least n_byte. + * + * You must implement it when i2c @a #I2C_BUFFER_CONFIG is set to 2 (User defined).\n + * This is used used in the context of #VL6180x_I2C_USER_VAR + * + * @param dev The device + * @param n_byte Minimal number of byte + * @return The buffer (cannot fail return not checked) + * @ingroup cci_i2c + */ +uint8_t *VL6180x_GetI2cBuffer(VL6180xDev_t dev, int n_byte); +#if I2C_BUFFER_CONFIG == 2 +#error /* TODO add your macro of code here for VL6180x_GetI2cBuffer */ +#endif + + + + + +#endif /* VL6180_I2C_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_platform.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_platform.h new file mode 100755 index 0000000000000..a3be06a82cd13 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_platform.h @@ -0,0 +1,107 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ + + +#ifndef VL6180x_PLATFORM_H +#define VL6180x_PLATFORM_H + + +#include "vl6180x_appcfg.h" +#include "vl6180x_def.h" + + + +#define VL6180x_DEV_DATA_ATTR + +#define ROMABLE_DATA +/* #define ROMABLE_DATA __attribute__ ((section ("user_rom"))) */ + +//#define VL6180X_LOG_ENABLE 1 + +#if VL6180X_LOG_ENABLE +#include +#define LOG_GET_TIME() (int)0 /* add your code here expect to be an integer native (%d) type value */ + + + + +#define LOG_FUNCTION_START(fmt, ... ) \ + printk("beg %s start @%d\t" fmt "\n", __func__, LOG_GET_TIME(), ##__VA_ARGS__) + +#define LOG_FUNCTION_END(status)\ + printk("end %s @%d %d\n", __func__, LOG_GET_TIME(), (int)status) + +#define LOG_FUNCTION_END_FMT(status, fmt, ... )\ + printk("End %s @%d %d\t"fmt"\n" , __func__, LOG_GET_TIME(), (int)status, ##__VA_ARGS__) + +#define VL6180x_ErrLog(msg, ... )\ + do{\ + printk("ERR in %s line %d\n" msg, __func__, __LINE__, ##__VA_ARGS__);\ + }while(0) + +#else /* VL6180X_LOG_ENABLE no logging */ + + #define LOG_FUNCTION_START(...) (void)0 + #define LOG_FUNCTION_END(...) (void)0 + #define LOG_FUNCTION_END_FMT(...) (void)0 + #define VL6180x_ErrLog(... ) (void)0 +#endif + + +#if VL6180x_SINGLE_DEVICE_DRIVER + typedef uint8_t VL6180xDev_t; + typedef VL6180xDev_t stmvl6180x_dev; + +#else /* VL6180x_SINGLE_DEVICE_DRIVER */ + + struct MyVL6180Dev_t { + struct VL6180xDevData_t Data; + #if I2C_BUFFER_CONFIG == 2 + uint8_t i2c_buffer[VL6180x_MAX_I2C_XFER_SIZE]; + #define VL6180x_GetI2cBuffer(dev, n) ((dev)->i2c_buffer) + #endif + uint32_t I2cAddress; + }; + typedef struct MyVL6180Dev_t *VL6180xDev_t; + typedef struct MyVL6180Dev_t stmvl6180x_dev; + +#define VL6180xDevDataGet(dev, field) (dev->Data.field) +#define VL6180xDevDataSet(dev, field, data) (dev->Data.field)=(data) + +#endif /* #else VL6180x_SINGLE_DEVICE_DRIVER */ + +void VL6180x_PollDelay(VL6180xDev_t dev); + +void DISP_ExecLoopBody(void); +#define VL6180x_PollDelay(dev) msleep(5) + + +#endif /* VL6180x_PLATFORM_H */ + + + diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_types.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_types.h new file mode 100755 index 0000000000000..44edf9d5d742b --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/inc/vl6180x_types.h @@ -0,0 +1,63 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ + +#ifndef VL6180x_TYPES_H_ +#define VL6180x_TYPES_H_ + + +//#include +#include + +#ifndef NULL +#error "TODO review NULL definition or add required include " +#define NULL 0 +#endif + +#if !defined(STDINT_H) && !defined(_GCC_STDINT_H) && !defined(_STDINT_H) && !defined(_LINUX_TYPES_H) + +#pragma message("Please review type definition of STDINT define for your platform and add to list above ") + + /* + * target platform do not provide stdint or use a different #define than above + * to avoid seeing the message below addapt the #define list above or implement + * all type and delete these pragma + */ + +typedef unsigned int uint32_t; +typedef int int32_t; + +typedef unsigned short uint16_t; +typedef short int16_t; + +typedef unsigned char uint8_t; + +typedef signed char int8_t; + +#endif /* _STDINT_H */ + +#endif /* VL6180x_TYPES_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_api.c b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_api.c new file mode 100755 index 0000000000000..d1437df7ed17f --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_api.c @@ -0,0 +1,2469 @@ +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ + +/* + * $Date: 2015-01-14 06:37:10 -0800 (Wed, 14 Jan 2015) $ + * $Revision: 2047 $ + */ +#include "vl6180x_api.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VL6180x_9to7Conv(x) (x) + +/* TODO when set all "cached" value with "default init" are updated after init from register read back */ +#define REFRESH_CACHED_DATA_AFTER_INIT 1 + + +#define IsValidGPIOFunction(x) ((x)==GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT || (x)==GPIOx_SELECT_OFF) + + +/** default value ECE factor Molecular */ +#define DEF_ECE_FACTOR_M 85 +/** default value ECE factor Denominator */ +#define DEF_ECE_FACTOR_D 100 +/** default value ALS integration time */ +#define DEF_INT_PEFRIOD 100 +/** default value ALS gain */ +#define DEF_ALS_GAIN 1 +/** default value ALS scaler */ +#define DEF_ALS_SCALER 1 + +/****CALIBRATION DATA*****/ +#define CALIBRATE_CONFIG 1 +int user_offset_calib=0xffffffff; //changed to int data type for default value +int user_xtalk_calib=0xffffffff; //changed to int data type for default value + +#if VL6180x_SINGLE_DEVICE_DRIVER +extern struct VL6180xDevData_t SingleVL6180xDevData; +#define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field) +#define VL6180xDevDataSet(dev, field, data) (SingleVL6180xDevData.field)=(data) +#endif + +#define LUXRES_FIX_PREC 8 +#define GAIN_FIX_PREC 8 /* ! if not sme as LUX_PREC then :( adjust GetLux */ +#define AN_GAIN_MULT (1<scalar 1x2x 3x */ +/** + * scaling factor to Upper limit look up + */ +static const uint16_t UpperLimitLookUP[] ROMABLE_DATA ={ 185, 370, 580}; /* lookup table for scaling->limit 1x2x3x */ +/** + * Als Code gain to fix point gain lookup + */ +static const uint16_t AlsGainLookUp[8] ROMABLE_DATA = { + (uint16_t)(20.0f * AN_GAIN_MULT), + (uint16_t)(10.0f * AN_GAIN_MULT), + (uint16_t)(5.0f * AN_GAIN_MULT), + (uint16_t)(2.5f * AN_GAIN_MULT), + (uint16_t)(1.67f * AN_GAIN_MULT), + (uint16_t)(1.25f * AN_GAIN_MULT), + (uint16_t)(1.0f * AN_GAIN_MULT), + (uint16_t)(40.0f * AN_GAIN_MULT), +}; + + +#if VL6180x_RANGE_STATUS_ERRSTRING +const char * ROMABLE_DATA VL6180x_RangeStatusErrString[]={ + "No Error", + "VCSEL Continuity Test", + "VCSEL Watchdog Test", + "VCSEL Watchdog", + "PLL1 Lock", + "PLL2 Lock", + "Early Convergence Estimate", + "Max Convergence", + "No Target Ignore", + "Not used 9", + "Not used 10", + "Max Signal To Noise Ratio", + "Raw Ranging Algo Underflow", + "Raw Ranging Algo Overflow", + "Ranging Algo Underflow", + "Ranging Algo Overflow", + + "Filtered by post processing" +}; + +const char * VL6180x_RangeGetStatusErrString(uint8_t RangeErrCode){ + if( RangeErrCode > sizeof(VL6180x_RangeStatusErrString)/sizeof(VL6180x_RangeStatusErrString[0]) ) + return NULL; + return VL6180x_RangeStatusErrString[RangeErrCode]; +} +#endif + +#if VL6180x_UPSCALE_SUPPORT == 1 + #define _GetUpscale(dev, ... ) 1 + #define _SetUpscale(...) -1 + #define DEF_UPSCALE 1 +#elif VL6180x_UPSCALE_SUPPORT == 2 + #define _GetUpscale(dev, ... ) 2 + #define _SetUpscale(...) + #define DEF_UPSCALE 2 +#elif VL6180x_UPSCALE_SUPPORT == 3 + #define _GetUpscale(dev, ... ) 3 + #define _SetUpscale(...) + #define DEF_UPSCALE 3 +#else + #define DEF_UPSCALE (-(VL6180x_UPSCALE_SUPPORT)) + #define _GetUpscale(dev, ... ) VL6180xDevDataGet(dev, UpscaleFactor) + #define _SetUpscale(dev, Scaling ) VL6180xDevDataSet(dev, UpscaleFactor, Scaling) +#endif + + +#if VL6180x_SINGLE_DEVICE_DRIVER +/** + * the unique driver data When single device driver is active + */ +struct VL6180xDevData_t VL6180x_DEV_DATA_ATTR SingleVL6180xDevData={ + .EceFactorM = DEF_ECE_FACTOR_M, + .EceFactorD = DEF_ECE_FACTOR_D, +#ifdef VL6180x_HAVE_UPSCALE_DATA + .UpscaleFactor = DEF_UPSCALE, +#endif +#ifdef VL6180x_HAVE_ALS_DATA + .IntegrationPeriod = DEF_INT_PEFRIOD, + .AlsGainCode = DEF_ALS_GAIN, + .AlsScaler = DEF_ALS_SCALER, +#endif +}; +#endif /* VL6180x_SINGLE_DEVICE_DRIVER */ + + + +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT || VL6180x_HAVE_DMAX_RANGING +static int _GetRateResult(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData); +static int _GetRateResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pRangeData); +#endif + +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT +static int _filter_Init(VL6180xDev_t dev); +static int _filter_GetResult(VL6180xDev_t dev, VL6180x_RangeData_t *pData); +static int _filter_GetResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pData); + #define _IsWrapArroundActive(dev) VL6180xDevDataGet(dev,WrapAroundFilterActive) +#else + #define _IsWrapArroundActive(dev) 0 +#endif + + +#if VL6180x_HAVE_DMAX_RANGING + void _DMax_OneTimeInit(VL6180xDev_t dev); + static int _DMax_InitData(VL6180xDev_t dev); + static int _DMax_Compute(VL6180xDev_t dev, VL6180x_RangeData_t *pRange); + +#else + #define _DMax_InitData(...) 0 /* success */ + #define _DMax_OneTimeInit(...) (void)0 + +#endif + +static int VL6180x_RangeStaticInit(VL6180xDev_t dev); +static int VL6180x_UpscaleStaticInit(VL6180xDev_t dev); + +int VL6180x_WaitDeviceBooted(VL6180xDev_t dev){ + uint8_t FreshOutReset; + int status; + LOG_FUNCTION_START(""); + do{ + status = VL6180x_RdByte(dev,SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset); + } + while( FreshOutReset!=1 && status==0); + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_InitData(VL6180xDev_t dev){ + int status, dmax_status ; + int8_t offset; + uint8_t FreshOutReset; + + LOG_FUNCTION_START(""); + + VL6180xDevDataSet(dev, EceFactorM , DEF_ECE_FACTOR_M); + VL6180xDevDataSet(dev, EceFactorD , DEF_ECE_FACTOR_D); + +#ifdef VL6180x_HAVE_UPSCALE_DATA + VL6180xDevDataSet(dev, UpscaleFactor , DEF_UPSCALE); +#endif + +#ifdef VL6180x_HAVE_ALS_DATA + VL6180xDevDataSet(dev, IntegrationPeriod, DEF_INT_PEFRIOD); + VL6180xDevDataSet(dev, AlsGainCode, DEF_ALS_GAIN); + VL6180xDevDataSet(dev, AlsScaler, DEF_ALS_SCALER); +#endif + +#ifdef VL6180x_HAVE_WRAP_AROUND_DATA + VL6180xDevDataSet(dev, WrapAroundFilterActive, (VL6180x_WRAP_AROUND_FILTER_SUPPORT >0)); +#endif + + _DMax_OneTimeInit(dev); + do{ + + /* backup offset initial value from nvm these must be done prior any over call that use offset */ + status = VL6180x_RdByte(dev,SYSRANGE_PART_TO_PART_RANGE_OFFSET, (uint8_t*)&offset); + if( status ){ + VL6180x_ErrLog("SYSRANGE_PART_TO_PART_RANGE_OFFSET rd fail"); + break; + } + VL6180xDevDataSet(dev, Part2PartOffsetNVM, offset); +#ifdef CALIBRATE_CONFIG + if (user_offset_calib != 0xffffffff){ + VL6180xDevDataSet(dev, Part2PartOffsetNVM, (int8_t)user_offset_calib); + } + if (user_xtalk_calib != 0xffffffff) + VL6180x_WrWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, (int16_t)user_xtalk_calib); +#endif + + dmax_status = _DMax_InitData(dev); + if( dmax_status < 0 ){ + VL6180x_ErrLog("DMax init failure"); + break; + } + + /* Read or wait for fresh out of reset */ + status = VL6180x_RdByte(dev,SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset); + if( status ) { + VL6180x_ErrLog("SYSTEM_FRESH_OUT_OF_RESET rd fail"); + break; + } + if( FreshOutReset!= 1 || dmax_status ) + status = CALIBRATION_WARNING; + + } + while(0); + + LOG_FUNCTION_END(status); + return status; +} + +int8_t VL6180x_GetOffsetCalibrationData(VL6180xDev_t dev) +{ + int8_t offset; + LOG_FUNCTION_START(""); + offset = VL6180xDevDataGet(dev, Part2PartOffsetNVM); + LOG_FUNCTION_END( offset ); + return offset; +} + +void VL6180x_SetOffsetCalibrationData(VL6180xDev_t dev, int8_t offset) +{ + LOG_FUNCTION_START("%d", offset); + VL6180xDevDataSet(dev, Part2PartOffsetNVM, offset); + LOG_FUNCTION_END(0); +} + +#ifdef CALIBRATE_CONFIG +void VL6180x_SetUserOffsetCalibration(VL6180xDev_t dev, int8_t offset) +{ + LOG_FUNCTION_START("%d", offset); + user_offset_calib = offset; + + LOG_FUNCTION_END(0); +} + +void VL6180x_SetOffset(VL6180xDev_t dev, int8_t offset) +{ + int8_t scaling; + int8_t Offset; + LOG_FUNCTION_START("%d", offset); + VL6180xDevDataSet(dev, Part2PartOffsetNVM, offset); + scaling = _GetUpscale(dev); + + /* Apply scaling on part-2-part offset */ + Offset = VL6180xDevDataGet(dev, Part2PartOffsetNVM)/scaling; + + VL6180x_WrByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, Offset); + + LOG_FUNCTION_END(0); +} + +void VL6180x_SetUserXTalkCompensationRate(VL6180xDev_t dev, FixPoint97_t rate) +{ + LOG_FUNCTION_START("%d", rate); + user_xtalk_calib = rate; + + LOG_FUNCTION_END(0); +} +#endif + +int VL6180x_SetXTalkCompensationRate(VL6180xDev_t dev, FixPoint97_t Rate) +{ + int status; + LOG_FUNCTION_START("%d", Rate); + status = VL6180x_WrWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, Rate); + if( status ==0 ){ + /* update dmax whenever xtalk rate changes */ + status = _DMax_InitData(dev); + } + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_SetI2CAddress(VL6180xDev_t dev, uint8_t NewAddress){ + int status; + LOG_FUNCTION_START(""); + + status = VL6180x_WrByte(dev, I2C_SLAVE_DEVICE_ADDRESS, NewAddress/2); + if( status ){ + VL6180x_ErrLog("new i2c addr Wr fail"); + } + LOG_FUNCTION_END(status); + return status; +} + +uint16_t VL6180x_GetUpperLimit(VL6180xDev_t dev) { + uint16_t limit; + int scaling; + + LOG_FUNCTION_START(""); + + scaling = _GetUpscale(dev); + /* FIXME we do assume here _GetUpscale is valid if user call us prior to init we may overflow the LUT mem area */ + limit = UpperLimitLookUP[scaling - 1]; + + LOG_FUNCTION_END((int )limit); + return limit; +} + + + +int VL6180x_StaticInit(VL6180xDev_t dev){ + int status, init_status; + status = 0; + init_status = 0; + + LOG_FUNCTION_START(""); + + /* TODO doc When using configurable scaling but using 1x as start condition + * load tunning upscale or not ??? */ + if( _GetUpscale(dev) == 1 && !(VL6180x_UPSCALE_SUPPORT<0)){ + init_status=VL6180x_RangeStaticInit(dev); + } + else{ + init_status=VL6180x_UpscaleStaticInit(dev); + } + + if( init_status <0 ){ + VL6180x_ErrLog("StaticInit fail"); + goto error; + } + else if(init_status > 0){ + VL6180x_ErrLog("StaticInit warning"); + } + +#if REFRESH_CACHED_DATA_AFTER_INIT + /* update cached value after tuning applied */ + do{ +#ifdef VL6180x_HAVE_ALS_DATA + uint8_t data; + status= VL6180x_RdByte(dev, FW_ALS_RESULT_SCALER, &data); + if( status ) break; + VL6180xDevDataSet(dev, AlsScaler, data); + + status= VL6180x_RdByte(dev, SYSALS_ANALOGUE_GAIN, &data); + if( status ) break; + + VL6180x_AlsSetAnalogueGain(dev, data); +#endif + } + while(0); +#endif /* REFRESH_CACHED_DATA_AFTER_INIT */ + if( status < 0 ){ + VL6180x_ErrLog("StaticInit fail"); + } + if( !status && init_status){ + status = init_status; + } +error: + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_SetGroupParamHold(VL6180xDev_t dev, int Hold) +{ + int status; + uint8_t value; + + LOG_FUNCTION_START("%d", Hold); + if( Hold ) + value = 1; + else + value = 0; + status = VL6180x_WrByte(dev, SYSTEM_GROUPED_PARAMETER_HOLD, value); + + LOG_FUNCTION_END(status); + return status; + +} + +int VL6180x_Prepare(VL6180xDev_t dev) +{ + int status; + LOG_FUNCTION_START(""); + + do{ + status=VL6180x_StaticInit(dev); + if( status<0) + break; + + /* set range InterruptMode to new sample */ + status=VL6180x_RangeConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY ); + if( status) + break; + + /* set default threshold */ + status=VL6180x_RangeSetRawThresholds(dev, 10, 200); + if( status ){ + VL6180x_ErrLog("VL6180x_RangeSetRawThresholds fail"); + break; + } +#if VL6180x_ALS_SUPPORT + status =VL6180x_AlsSetIntegrationPeriod(dev, 100); + if( status ) break; + status = VL6180x_AlsSetInterMeasurementPeriod(dev, 200); + if( status ) break; + status = VL6180x_AlsSetAnalogueGain(dev, 0); + if( status ) break; + status = VL6180x_AlsSetThresholds(dev, 0, 0xFF); + if( status ) break; + /* set Als InterruptMode to new sample */ + status=VL6180x_AlsConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY); + if( status ) { + VL6180x_ErrLog("VL6180x_AlsConfigInterrupt fail"); + break; + } +#endif +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + _filter_Init(dev); +#endif + /* make sure to reset any left previous condition that can hangs first poll */ + status=VL6180x_ClearAllInterrupt(dev); + } + while(0); + LOG_FUNCTION_END(status); + + return status; +} + +#if VL6180x_ALS_SUPPORT +int VL6180x_AlsGetLux(VL6180xDev_t dev, lux_t *pLux) +{ + int status; + uint16_t RawAls; + uint32_t luxValue = 0; + uint32_t IntPeriod; + uint32_t AlsAnGain; + uint32_t GainFix; + uint32_t AlsScaler; + +#if LUXRES_FIX_PREC != GAIN_FIX_PREC +#error "LUXRES_FIX_PREC != GAIN_FIX_PREC review these code to be correct" +#endif + const uint32_t LuxResxIntIme =(uint32_t)(0.56f* DEF_INT_PEFRIOD *(1<lux); + if( !status ){ + status = VL6180x_RdByte(dev, RESULT_ALS_STATUS, & ErrStatus); + pAlsData->errorStatus = ErrStatus>>4; + } + LOG_FUNCTION_END_FMT(status,"%d %d", (int)pAlsData->lux, (int)pAlsData->errorStatus); + + return status; +} + + +int VL6180x_AlsPollMeasurement(VL6180xDev_t dev, VL6180x_AlsData_t *pAlsData) { + int status; + int ClrStatus; + uint8_t IntStatus; + + LOG_FUNCTION_START("%p", pAlsData); +#if VL6180X_SAFE_POLLING_ENTER + /* if device get stopped with left interrupt uncleared , it is required to clear them now or poll for new condition will never occur*/ + status=VL6180x_AlsClearInterrupt(dev); + if(status){ + VL6180x_ErrLog("VL6180x_AlsClearInterrupt fail"); + goto over; + } +#endif + + status=VL6180x_AlsSetSystemMode(dev, MODE_START_STOP|MODE_SINGLESHOT); + if( status){ + VL6180x_ErrLog("VL6180x_AlsSetSystemMode fail"); + goto over; + } + + /* poll for new sample ready */ + while (1 ) { + status = VL6180x_AlsGetInterruptStatus(dev, &IntStatus); + if (status) { + break; + } + if (IntStatus == RES_INT_STAT_GPIO_NEW_SAMPLE_READY) { + break; /* break on new data (status is 0) */ + } + + VL6180x_PollDelay(dev); + }; + + if (!status) { + status = VL6180x_AlsGetMeasurement(dev, pAlsData); + } + + ClrStatus = VL6180x_AlsClearInterrupt(dev); + if (ClrStatus) { + VL6180x_ErrLog("VL6180x_AlsClearInterrupt fail"); + if (!status) { + status = ClrStatus; /* leave previous if already on error */ + } + } +over: + LOG_FUNCTION_END(status); + + return status; +} + +int VL6180x_AlsGetInterruptStatus(VL6180xDev_t dev, uint8_t *pIntStatus) { + int status; + uint8_t IntStatus; + LOG_FUNCTION_START("%p", pIntStatus); + + status = VL6180x_RdByte(dev, RESULT_INTERRUPT_STATUS_GPIO, &IntStatus); + *pIntStatus= (IntStatus>>3)&0x07; + + LOG_FUNCTION_END_FMT(status, "%d", (int)*pIntStatus); + return status; +} + +int VL6180x_AlsWaitDeviceReady(VL6180xDev_t dev, int MaxLoop ){ + int status; + int n; + uint8_t u8; + LOG_FUNCTION_START("%d", (int)MaxLoop); + if( MaxLoop<1){ + status=INVALID_PARAMS; + } + else{ + for( n=0; n < MaxLoop ; n++){ + status=VL6180x_RdByte(dev, RESULT_ALS_STATUS, &u8); + if( status) + break; + u8 = u8 & ALS_DEVICE_READY_MASK; + if( u8 ) + break; + + } + if( !status && !u8 ){ + status = TIME_OUT; + } + } + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_AlsSetSystemMode(VL6180xDev_t dev, uint8_t mode) +{ + int status; + LOG_FUNCTION_START("%d", (int)mode); + /* FIXME if we are called back to back real fast we are not checking + * if previous mode "set" got absorbed => bit 0 must be 0 so that wr 1 work */ + if( mode <= 3){ + status=VL6180x_WrByte(dev, SYSALS_START, mode); + } + else{ + status = INVALID_PARAMS; + } + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_AlsConfigInterrupt(VL6180xDev_t dev, uint8_t ConfigGpioInt) +{ + int status; + + if( ConfigGpioInt<= CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY){ + status = VL6180x_UpdateByte(dev, SYSTEM_INTERRUPT_CONFIG_GPIO, (uint8_t)(~CONFIG_GPIO_ALS_MASK), (ConfigGpioInt<<3)); + } + else{ + VL6180x_ErrLog("Invalid config mode param %d", (int)ConfigGpioInt); + status = INVALID_PARAMS; + } + LOG_FUNCTION_END(status); + return status; +} + + + +int VL6180x_AlsSetThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high) { + int status; + + LOG_FUNCTION_START("%d %d", (int )low, (int)high); + + status = VL6180x_WrByte(dev, SYSALS_THRESH_LOW, low); + if(!status ){ + status = VL6180x_WrByte(dev, SYSALS_THRESH_HIGH, high); + } + + LOG_FUNCTION_END(status) ; + return status; +} + + +int VL6180x_AlsSetAnalogueGain(VL6180xDev_t dev, uint8_t gain) { + int status; + uint8_t GainTotal; + + LOG_FUNCTION_START("%d", (int )gain); + gain&=~0x40; + if (gain > 7) { + gain = 7; + } + GainTotal = gain|0x40; + + status = VL6180x_WrByte(dev, SYSALS_ANALOGUE_GAIN, GainTotal); + if( !status){ + VL6180xDevDataSet(dev, AlsGainCode, gain); + } + + LOG_FUNCTION_END_FMT(status, "%d %d", (int ) gain, (int )GainTotal); + return status; +} + +int VL6180x_AlsSetInterMeasurementPeriod(VL6180xDev_t dev, uint16_t intermeasurement_period_ms) +{ + int status; + + LOG_FUNCTION_START("%d",(int)intermeasurement_period_ms); + /* clipping: range is 0-2550ms */ + if (intermeasurement_period_ms >= 255 *10) + intermeasurement_period_ms = 255 *10; + status=VL6180x_WrByte(dev, SYSALS_INTERMEASUREMENT_PERIOD, (uint8_t)(intermeasurement_period_ms/10)); + + LOG_FUNCTION_END_FMT(status, "%d", (int) intermeasurement_period_ms); + return status; +} + + +int VL6180x_AlsSetIntegrationPeriod(VL6180xDev_t dev, uint16_t period_ms) +{ + int status; + uint16_t SetIntegrationPeriod; + + LOG_FUNCTION_START("%d", (int)period_ms); + + if( period_ms>=1 ) + SetIntegrationPeriod = period_ms - 1; + else + SetIntegrationPeriod = period_ms; + + if (SetIntegrationPeriod > 464) { + SetIntegrationPeriod = 464; + } + else if (SetIntegrationPeriod == 255) { + SetIntegrationPeriod++; /* can't write 255 since this causes the device to lock out.*/ + } + + status =VL6180x_WrWord(dev, SYSALS_INTEGRATION_PERIOD, SetIntegrationPeriod); + if( !status ){ + VL6180xDevDataSet(dev, IntegrationPeriod, SetIntegrationPeriod) ; + } + LOG_FUNCTION_END_FMT(status, "%d", (int)SetIntegrationPeriod); + return status; +} + +#endif /* HAVE_ALS_SUPPORT */ + + +int VL6180x_RangePollMeasurement(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData) +{ + int status; + int ClrStatus; + IntrStatus_t IntStatus; + + LOG_FUNCTION_START(""); + /* start single range measurement */ + + +#if VL6180X_SAFE_POLLING_ENTER + /* if device get stopped with left interrupt uncleared , it is required to clear them now or poll for new condition will never occur*/ + status=VL6180x_RangeClearInterrupt(dev); + if(status){ + VL6180x_ErrLog("VL6180x_RangeClearInterrupt fail"); + goto done; + } +#endif + /* //![single_shot_snipet] */ + status=VL6180x_RangeSetSystemMode(dev, MODE_START_STOP|MODE_SINGLESHOT); + if( status ){ + VL6180x_ErrLog("VL6180x_RangeSetSystemMode fail"); + goto done; + } + + + /* poll for new sample ready */ + while(1 ){ + status=VL6180x_RangeGetInterruptStatus(dev, &IntStatus.val); + if( status ){ + break; + } + if( IntStatus.status.Error !=0 ){ + VL6180x_ErrLog("GPIO int Error report %d",(int)IntStatus.val); + status = RANGE_ERROR; + break; + } + else + if( IntStatus.status.Range == RES_INT_STAT_GPIO_NEW_SAMPLE_READY){ + break; + } + + VL6180x_PollDelay(dev); + } + /* //![single_shot_snipet] */ + + if ( !status ){ + status = VL6180x_RangeGetMeasurement(dev, pRangeData); + } + + /* clear range interrupt source */ + ClrStatus = VL6180x_RangeClearInterrupt(dev); + if( ClrStatus ){ + VL6180x_ErrLog("VL6180x_RangeClearInterrupt fail"); + /* leave initial status if already in error */ + if( !status ){ + status=ClrStatus; + } + } +done: + LOG_FUNCTION_END(status); + return status; +} + + + +int VL6180x_RangeGetMeasurement(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData) +{ + int status; + uint16_t RawRate; + uint8_t RawStatus; + + LOG_FUNCTION_START(""); + + status = VL6180x_RangeGetResult(dev, &pRangeData->range_mm); + if( !status ){ + status = VL6180x_RdWord(dev,RESULT_RANGE_SIGNAL_RATE, &RawRate ); + if( !status ){ + pRangeData->signalRate_mcps = VL6180x_9to7Conv(RawRate); + status = VL6180x_RdByte(dev, RESULT_RANGE_STATUS, &RawStatus); + if( !status ){ + pRangeData->errorStatus = RawStatus >>4; + } + else{ + VL6180x_ErrLog("Rd RESULT_RANGE_STATUS fail"); + } + #if VL6180x_WRAP_AROUND_FILTER_SUPPORT || VL6180x_HAVE_DMAX_RANGING + status = _GetRateResult(dev, pRangeData); + if( status ) + goto error; + #endif + #if VL6180x_WRAP_AROUND_FILTER_SUPPORT + /* if enabled run filter */ + if( _IsWrapArroundActive(dev) ){ + status=_filter_GetResult(dev, pRangeData); + if( !status){ + /* patch the range status and measure if it is filtered */ + if( pRangeData->range_mm != pRangeData->FilteredData.range_mm) { + pRangeData->errorStatus=RangingFiltered; + pRangeData->range_mm = pRangeData->FilteredData.range_mm; + } + } + } + #endif + +#if VL6180x_HAVE_DMAX_RANGING + _DMax_Compute(dev, pRangeData); +#endif + } + else{ + VL6180x_ErrLog("Rd RESULT_RANGE_SIGNAL_RATE fail"); + } + } + else{ + VL6180x_ErrLog("VL6180x_GetRangeResult fail"); + } +error: + LOG_FUNCTION_END_FMT(status, "%d %d %d", (int)pRangeData->range_mm, (int)pRangeData->signalRate_mcps, (int)pRangeData->errorStatus) ; + return status; +} + +int VL6180x_RangeGetMeasurement_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pRangeData) +{ + int status=0; + //uint16_t RawRate; + //uint8_t RawStatus; + + LOG_FUNCTION_START(""); + + VL6180x_RangeGetResult_ext(dev, pResultData, &pRangeData->range_mm); + pRangeData->signalRate_mcps = VL6180x_9to7Conv(pResultData->Result_range_return_rate); + pRangeData->errorStatus = pResultData->Result_range_status >>4; +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT || VL6180x_HAVE_DMAX_RANGING + _GetRateResult_ext(dev, pResultData, pRangeData); +#endif +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + /* if enabled run filter */ + if( _IsWrapArroundActive(dev) ){ + status = _filter_GetResult_ext(dev, pResultData, pRangeData); + if( !status){ + /* patch the range status and measure if it is filtered */ + if( pRangeData->range_mm != pRangeData->FilteredData.range_mm) { + pRangeData->errorStatus=RangingFiltered; + pRangeData->range_mm = pRangeData->FilteredData.range_mm; + } + } + } +#endif + +#if VL6180x_HAVE_DMAX_RANGING + _DMax_Compute(dev, pRangeData); +#endif + + LOG_FUNCTION_END_FMT(status, "%d %d %d", (int)pRangeData->range_mm, (int)pRangeData->signalRate_mcps, (int)pRangeData->errorStatus) ; + return status; +} + +int VL6180x_RangeGetMeasurementIfReady(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData) +{ + int status; + IntrStatus_t IntStatus; + + LOG_FUNCTION_START(); + + status = VL6180x_RangeGetInterruptStatus(dev, &IntStatus.val); + if( status ==0 ){ + if( IntStatus.status.Error !=0 ){ + VL6180x_ErrLog("GPIO int Error report %d",(int)IntStatus.val); + status = RANGE_ERROR; + } + else + if( IntStatus.status.Range == RES_INT_STAT_GPIO_NEW_SAMPLE_READY){ + status = VL6180x_RangeGetMeasurement(dev,pRangeData ); + if( status == 0){ + /* clear range interrupt source */ + status = VL6180x_RangeClearInterrupt(dev); + if( status ){ + VL6180x_ErrLog("VL6180x_RangeClearInterrupt fail"); + } + } + } + else{ + status = NOT_READY; + } + } + else{ + VL6180x_ErrLog("fail to get interrupt status"); + } + LOG_FUNCTION_END(status) ; + return status; +} + +int VL6180x_FilterSetState(VL6180xDev_t dev, int state){ + int status; + LOG_FUNCTION_START("%d", state); +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + VL6180xDevDataSet(dev,WrapAroundFilterActive, state); + status = 0; +#else + status = NOT_SUPPORTED; +#endif + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_FilterGetState(VL6180xDev_t dev){ + int status; + LOG_FUNCTION_START(""); +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + status = VL6180xDevDataGet(dev,WrapAroundFilterActive); +#else + status = 0; +#endif + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeGetResult(VL6180xDev_t dev, int32_t *pRange_mm) { + int status; + uint8_t RawRange; + int32_t Upscale; + + LOG_FUNCTION_START("%p",pRange_mm); + + status = VL6180x_RdByte(dev, RESULT_RANGE_VAL, &RawRange); + if( !status ){ + Upscale = _GetUpscale(dev); + *pRange_mm= Upscale*(int32_t)RawRange; + } + LOG_FUNCTION_END_FMT(status, "%d", (int)*pRange_mm); + return status; +} + +int VL6180x_RangeGetResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, int32_t *pRange_mm) { +// int status; +// uint8_t RawRange; + int32_t Upscale; + + LOG_FUNCTION_START("%p",pRange_mm); + + Upscale = _GetUpscale(dev); + *pRange_mm= Upscale*(int32_t)(pResultData->Result_range_val); + + LOG_FUNCTION_END_FMT(status, "%d", (int)*pRange_mm); + return 0; +} + +int VL6180x_RangeSetRawThresholds(VL6180xDev_t dev, uint8_t low, uint8_t high) +{ + int status; + LOG_FUNCTION_START("%d %d", (int) low, (int)high); + /* TODO we can optimize here grouping high/low in a word but that's cpu endianness dependent */ + status=VL6180x_WrByte(dev, SYSRANGE_THRESH_HIGH,high); + if( !status){ + status=VL6180x_WrByte(dev, SYSRANGE_THRESH_LOW, low); + } + + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeSetThresholds(VL6180xDev_t dev, uint16_t low, uint16_t high, int UseSafeParamHold) +{ + int status; + int scale; + LOG_FUNCTION_START("%d %d", (int) low, (int)high); + scale=_GetUpscale(dev,UpscaleFactor); + if( low>scale*255 || high >scale*255){ + status = INVALID_PARAMS; + } + else{ + do{ + if( UseSafeParamHold ){ + status=VL6180x_SetGroupParamHold(dev, 1); + if( status ) + break; + } + status=VL6180x_RangeSetRawThresholds(dev, (uint8_t)(low/scale), (uint8_t)(high/scale)); + if( status ){ + VL6180x_ErrLog("VL6180x_RangeSetRawThresholds fail"); + } + if( UseSafeParamHold ){ + int HoldStatus; + /* tryt to unset param hold vene if previous fail */ + HoldStatus=VL6180x_SetGroupParamHold(dev, 0); + if( !status) + status=HoldStatus; + } + } + while(0); + } + + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_RangeGetThresholds(VL6180xDev_t dev, uint16_t *low, uint16_t *high) +{ + int status; + uint8_t RawLow, RawHigh; + int scale; + + LOG_FUNCTION_START("%p %p", low , high); + + scale=_GetUpscale(dev,UpscaleFactor); + do{ + if( high != NULL ){ + status=VL6180x_RdByte(dev, SYSRANGE_THRESH_HIGH,&RawHigh); + if( status ){ + VL6180x_ErrLog("rd SYSRANGE_THRESH_HIGH fail"); + break; + } + *high=(uint16_t)RawHigh*scale; + } + if( low != NULL ) { + status=VL6180x_RdByte(dev, SYSRANGE_THRESH_LOW, &RawLow); + if( status ){ + VL6180x_ErrLog("rd SYSRANGE_THRESH_LOW fail"); + break; + } + *low=(uint16_t)RawLow*scale; + } + } + while(0); + LOG_FUNCTION_END_FMT(status, "%d %d",(int)*low ,(int)*high); + return status; +} + + +int VL6180x_RangeGetInterruptStatus(VL6180xDev_t dev, uint8_t *pIntStatus) { + int status; + uint8_t IntStatus; + LOG_FUNCTION_START("%p", pIntStatus); + /* FIXME we are grouping "error" with over status the user must check implicitly for it + * not just new sample or over status , that will nevr show up in case of error*/ + status = VL6180x_RdByte(dev, RESULT_INTERRUPT_STATUS_GPIO, &IntStatus); + *pIntStatus= IntStatus&0xC7; + + LOG_FUNCTION_END_FMT(status, "%d", (int)*pIntStatus); + return status; +} + + +int VL6180x_GetInterruptStatus(VL6180xDev_t dev, uint8_t *IntStatus) +{ + int status; + LOG_FUNCTION_START("%p" , IntStatus); + status = VL6180x_RdByte(dev, RESULT_INTERRUPT_STATUS_GPIO, IntStatus); + LOG_FUNCTION_END_FMT(status, "%d", (int)*IntStatus); + return status; +} + +int VL6180x_ClearInterrupt(VL6180xDev_t dev, uint8_t IntClear ) +{ + int status; + LOG_FUNCTION_START("%d" ,(int)IntClear); + if( IntClear <= 7 ){ + status=VL6180x_WrByte( dev, SYSTEM_INTERRUPT_CLEAR, IntClear); + } + else{ + status = INVALID_PARAMS; + } + LOG_FUNCTION_END(status); + return status; +} + + +static int VL6180x_RangeStaticInit(VL6180xDev_t dev) +{ + int status; + LOG_FUNCTION_START(""); + + /* REGISTER_TUNING_SR03_270514_CustomerView.txt */ + VL6180x_WrByte( dev, 0x0207, 0x01); + VL6180x_WrByte( dev, 0x0208, 0x01); + VL6180x_WrByte( dev, 0x0096, 0x00); + VL6180x_WrByte( dev, 0x0097, 0xfd); + VL6180x_WrByte( dev, 0x00e3, 0x00); + VL6180x_WrByte( dev, 0x00e4, 0x04); + VL6180x_WrByte( dev, 0x00e5, 0x02); + VL6180x_WrByte( dev, 0x00e6, 0x01); + VL6180x_WrByte( dev, 0x00e7, 0x03); + VL6180x_WrByte( dev, 0x00f5, 0x02); + VL6180x_WrByte( dev, 0x00d9, 0x05); + VL6180x_WrByte( dev, 0x00db, 0xce); + VL6180x_WrByte( dev, 0x00dc, 0x03); + VL6180x_WrByte( dev, 0x00dd, 0xf8); + VL6180x_WrByte( dev, 0x009f, 0x00); + VL6180x_WrByte( dev, 0x00a3, 0x3c); + VL6180x_WrByte( dev, 0x00b7, 0x00); + VL6180x_WrByte( dev, 0x00bb, 0x3c); + VL6180x_WrByte( dev, 0x00b2, 0x09); + VL6180x_WrByte( dev, 0x00ca, 0x09); + VL6180x_WrByte( dev, 0x0198, 0x01); + VL6180x_WrByte( dev, 0x01b0, 0x17); + VL6180x_WrByte( dev, 0x01ad, 0x00); + VL6180x_WrByte( dev, 0x00ff, 0x05); + VL6180x_WrByte( dev, 0x0100, 0x05); + VL6180x_WrByte( dev, 0x0199, 0x05); + VL6180x_WrByte( dev, 0x01a6, 0x1b); + VL6180x_WrByte( dev, 0x01ac, 0x3e); + VL6180x_WrByte( dev, 0x01a7, 0x1f); + VL6180x_WrByte( dev, 0x0030, 0x00); + + /* Recommended : Public registers - See data sheet for more detail */ + VL6180x_WrByte( dev, 0x0011, 0x10); /* Enables polling for New Sample ready when measurement completes */ + VL6180x_WrByte( dev, 0x010a, 0x30); /* Set the averaging sample period (compromise between lower noise and increased execution time) */ + VL6180x_WrByte( dev, 0x003f, 0x46); /* Sets the light and dark gain (upper nibble). Dark gain should not be changed.*/ + VL6180x_WrByte( dev, 0x0031, 0xFF); /* sets the # of range measurements after which auto calibration of system is performed */ + VL6180x_WrByte( dev, 0x0040, 0x63); /* Set ALS integration time to 100ms */ + VL6180x_WrByte( dev, 0x002e, 0x01); /* perform a single temperature calibration of the ranging sensor */ + + /* Optional: Public registers - See data sheet for more detail */ + VL6180x_WrByte( dev, 0x001b, 0x09); /* Set default ranging inter-measurement period to 100ms */ + VL6180x_WrByte( dev, 0x003e, 0x31); /* Set default ALS inter-measurement period to 500ms */ + VL6180x_WrByte( dev, 0x0014, 0x24); /* Configures interrupt on New sample ready */ + + + status=VL6180x_RangeSetMaxConvergenceTime(dev, 50); /* Calculate ece value on initialization (use max conv) */ + LOG_FUNCTION_END(status); + + return status; +} + +#if VL6180x_UPSCALE_SUPPORT != 1 + +static int _UpscaleInitPatch0(VL6180xDev_t dev){ + int status; + uint32_t CalValue=0; + status=VL6180x_RdDWord( dev, 0x26, &CalValue); + + if( CalValue ==0 ){ + /* no nvm cal data set default ! be/le */ + CalValue= 0x00CE03F8; + } + status=VL6180x_WrDWord( dev, 0xDA, CalValue); + return status; +} + +/* only include up-scaling register setting when up-scale support is configured in */ +int VL6180x_UpscaleRegInit(VL6180xDev_t dev) +{ + /* apply REGISTER_TUNING_ER02_100614_CustomerView.txt */ + VL6180x_WrByte( dev, 0x0207, 0x01); + VL6180x_WrByte( dev, 0x0208, 0x01); + VL6180x_WrByte( dev, 0x0096, 0x00); + VL6180x_WrByte( dev, 0x0097, 0x54); + VL6180x_WrByte( dev, 0x00e3, 0x00); + VL6180x_WrByte( dev, 0x00e4, 0x04); + VL6180x_WrByte( dev, 0x00e5, 0x02); + VL6180x_WrByte( dev, 0x00e6, 0x01); + VL6180x_WrByte( dev, 0x00e7, 0x03); + VL6180x_WrByte( dev, 0x00f5, 0x02); + VL6180x_WrByte( dev, 0x00d9, 0x05); + _UpscaleInitPatch0(dev); + VL6180x_WrByte( dev, 0x009f, 0x00); + VL6180x_WrByte( dev, 0x00a3, 0x28); + VL6180x_WrByte( dev, 0x00b7, 0x00); + VL6180x_WrByte( dev, 0x00bb, 0x28); + VL6180x_WrByte( dev, 0x00b2, 0x09); + VL6180x_WrByte( dev, 0x00ca, 0x09); + VL6180x_WrByte( dev, 0x0198, 0x01); + VL6180x_WrByte( dev, 0x01b0, 0x17); + VL6180x_WrByte( dev, 0x01ad, 0x00); + VL6180x_WrByte( dev, 0x00ff, 0x05); + VL6180x_WrByte( dev, 0x0100, 0x05); + VL6180x_WrByte( dev, 0x0199, 0x05); + VL6180x_WrByte( dev, 0x01a6, 0x1b); + VL6180x_WrByte( dev, 0x01ac, 0x3e); + VL6180x_WrByte( dev, 0x01a7, 0x1f); + VL6180x_WrByte( dev, 0x0030, 0x00); + VL6180x_WrByte( dev, 0x0011, 0x10); + VL6180x_WrByte( dev, 0x010a, 0x30); + VL6180x_WrByte( dev, 0x003f, 0x46); + VL6180x_WrByte( dev, 0x0031, 0xFF); + VL6180x_WrByte( dev, 0x0040, 0x63); + VL6180x_WrByte( dev, 0x002e, 0x01); + VL6180x_WrByte( dev, 0x002c, 0xff); + VL6180x_WrByte( dev, 0x001b, 0x09); + VL6180x_WrByte( dev, 0x003e, 0x31); + VL6180x_WrByte( dev, 0x0014, 0x24); +#if VL6180x_EXTENDED_RANGE + VL6180x_RangeSetMaxConvergenceTime(dev, 63); +#else + + VL6180x_RangeSetMaxConvergenceTime(dev, 50); +#endif + return 0; +} +#else +#define VL6180x_UpscaleRegInit(...) -1 +#endif + +int VL6180x_UpscaleSetScaling(VL6180xDev_t dev, uint8_t scaling) +{ + int status; + uint16_t Scaler; + int8_t Offset; + + LOG_FUNCTION_START("%d",(int) scaling); + +#ifdef VL6180x_HAVE_UPSCALE_DATA + #define min_scaling 1 + #define max_scaling sizeof(ScalerLookUP)/sizeof(ScalerLookUP[0]) +#else + /* we are in fixed config so only allow configured factor */ + #define min_scaling VL6180x_UPSCALE_SUPPORT + #define max_scaling VL6180x_UPSCALE_SUPPORT +#endif + + if( scaling>=min_scaling && scaling<= max_scaling ){ + + Scaler = ScalerLookUP[scaling-1]; + status = VL6180x_WrWord(dev, RANGE_SCALER, Scaler); + _SetUpscale(dev, scaling ); + + /* Apply scaling on part-2-part offset */ + Offset = VL6180xDevDataGet(dev, Part2PartOffsetNVM)/scaling; + status = VL6180x_WrByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, Offset); +//kelong add to write cross talk to sensor + if (user_xtalk_calib != 0xffffffff) + VL6180x_WrWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, (int16_t)user_xtalk_calib); +//kelong add to write cross talk to sensor + +#if ! VL6180x_EXTENDED_RANGE + if( status == 0 && !VL6180x_EXTENDED_RANGE && scaling!=1 ){ + status = NOT_GUARANTEED ; + } +#endif + } + else{ + status = INVALID_PARAMS; + } +#undef min_scaling +#undef max_scaling + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_UpscaleGetScaling(VL6180xDev_t dev) +{ + int status; + LOG_FUNCTION_START(""); + status=_GetUpscale(dev ); + LOG_FUNCTION_END(status); + + return status; +} + + +static int VL6180x_UpscaleStaticInit(VL6180xDev_t dev) +{ + /* todo make these a fail macro in case only 1x is suppoted */ + int status; + + LOG_FUNCTION_START(""); + do{ + status=VL6180x_UpscaleRegInit(dev); + if( status){ + VL6180x_ErrLog("regInit fail"); + break; + } +#if VL6180x_EXTENDED_RANGE + status = VL6180x_RangeSetEceState(dev, 0); + if( status){ + VL6180x_ErrLog("VL6180x_RangeSetEceState fail"); + break; + } +#endif + } while(0); + if( !status){ + /* must write the scaler at least once to the device to ensure the scaler is in a known state. */ + + status=VL6180x_UpscaleSetScaling(dev, _GetUpscale(dev)); + VL6180x_WrByte( dev, 0x016, 0x00); /* change fresh out of set status to 0 */ + } + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_SetGPIOxPolarity(VL6180xDev_t dev, int pin, int active_high) +{ + int status; + LOG_FUNCTION_START("%d %d",(int) pin, (int)active_high); + + if( pin ==0 || pin ==1 ){ + uint16_t RegIndex; + uint8_t DataSet; + if( pin==0 ) + RegIndex= SYSTEM_MODE_GPIO0; + else + RegIndex= SYSTEM_MODE_GPIO1; + + if (active_high ) + DataSet = GPIOx_POLARITY_SELECT_MASK; + else + DataSet = 0; + + status = VL6180x_UpdateByte(dev, RegIndex, (uint8_t)~GPIOx_POLARITY_SELECT_MASK, DataSet); + } + else{ + VL6180x_ErrLog("Invalid pin param %d", (int)pin); + status = INVALID_PARAMS; + } + + LOG_FUNCTION_END(status); + + return status; +} + +int VL6180x_SetGPIOxFunctionality(VL6180xDev_t dev, int pin, uint8_t functionality) +{ + int status; + + LOG_FUNCTION_START("%d %d",(int) pin, (int)functionality); + + if( ((pin ==0) || (pin ==1)) && IsValidGPIOFunction(functionality) ){ + uint16_t RegIndex; + + if( pin==0 ) + RegIndex= SYSTEM_MODE_GPIO0; + else + RegIndex= SYSTEM_MODE_GPIO1; + + status = VL6180x_UpdateByte(dev, RegIndex, (uint8_t)~GPIOx_FUNCTIONALITY_SELECT_MASK, functionality<= 0 */ + if( FactorM <= FactorD && FactorD> 0){ + VL6180xDevDataSet(dev, EceFactorM, FactorM); + VL6180xDevDataSet(dev, EceFactorD, FactorD); + /* read and re-apply max conv time to get new ece factor set */ + status = VL6180x_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &u8); + if( status){ + VL6180x_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail "); + break; + } + status = VL6180x_RangeSetMaxConvergenceTime(dev, u8); + if( status <0 ){ + VL6180x_ErrLog("fail to apply time after ece m/d change"); + break; + } + } + else{ + VL6180x_ErrLog("invalid factor %d/%d", (int)FactorM, (int)FactorD ); + status = INVALID_PARAMS; + } + } + while(0); + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeSetEceState(VL6180xDev_t dev, int enable ){ + int status; + uint8_t or_mask; + + LOG_FUNCTION_START("%d", (int)enable); + if( enable ) + or_mask = RANGE_CHECK_ECE_ENABLE_MASK; + else + or_mask = 0; + + status =VL6180x_UpdateByte(dev, SYSRANGE_RANGE_CHECK_ENABLES, ~RANGE_CHECK_ECE_ENABLE_MASK, or_mask); + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_RangeSetMaxConvergenceTime(VL6180xDev_t dev, uint8_t MaxConTime_msec) +{ + int status = 0; + LOG_FUNCTION_START("%d",(int)MaxConTime_msec); + do{ + status=VL6180x_WrByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, MaxConTime_msec); + if( status ){ + break; + } + status=VL6180x_RangeSetEarlyConvergenceEestimateThreshold(dev); + if( status){ + break; + } + status = _DMax_InitData(dev); + } + while(0); + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeSetInterMeasPeriod(VL6180xDev_t dev, uint32_t InterMeasTime_msec){ + uint8_t SetTime; + int status; + + LOG_FUNCTION_START("%d",(int)InterMeasTime_msec); + do { + if( InterMeasTime_msec > 2550 ){ + status = INVALID_PARAMS; + break; + } + /* doc in not 100% clear and confusing about the limit practically all value are OK but 0 + * that can hang device in continuous mode */ + if( InterMeasTime_msec < 10 ) { + InterMeasTime_msec=10; + } + SetTime=(uint8_t)(InterMeasTime_msec/10); + status=VL6180x_WrByte(dev, SYSRANGE_INTERMEASUREMENT_PERIOD, SetTime); + if( status ){ + VL6180x_ErrLog("SYSRANGE_INTERMEASUREMENT_PERIOD wr fail"); + } + else + if( SetTime != InterMeasTime_msec /10 ) { + status = MIN_CLIPED; /* on success change status to clip if it did */ + } + }while(0); + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_RangeGetDeviceReady(VL6180xDev_t dev, int * Ready){ + int status; + uint8_t u8; + LOG_FUNCTION_START("%p",Ready); + status=VL6180x_RdByte(dev, RESULT_RANGE_STATUS, &u8); + if( !status) + *Ready = u8&RANGE_DEVICE_READY_MASK; + LOG_FUNCTION_END_FMT(status,"%d", *Ready); + return status; +} + + +int VL6180x_RangeWaitDeviceReady(VL6180xDev_t dev, int MaxLoop ){ + int status; /* if user specify an invalid <=0 loop count we'll return error */ + int n; + uint8_t u8; + LOG_FUNCTION_START("%d", (int)MaxLoop); + if( MaxLoop<1){ + status=INVALID_PARAMS; + } + else{ + for( n=0; n < MaxLoop ; n++){ + status=VL6180x_RdByte(dev, RESULT_RANGE_STATUS, &u8); + if( status) + break; + u8 = u8 & RANGE_DEVICE_READY_MASK; + if( u8 ) + break; + + } + if( !status && !u8 ){ + status = TIME_OUT; + } + } + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeSetSystemMode(VL6180xDev_t dev, uint8_t mode) +{ + int status; + LOG_FUNCTION_START("%d", (int)mode); + /* FIXME we are not checking device is ready via @a VL6180x_RangeWaitDeviceReady + * so if called back to back real fast we are not checking + * if previous mode "set" got absorbed => bit 0 must be 0 so that it work + */ + if( mode <= 3){ + status=VL6180x_WrByte(dev, SYSRANGE_START, mode); + if( status ){ + VL6180x_ErrLog("SYSRANGE_START wr fail"); + } + }else{ + status = INVALID_PARAMS; + } + LOG_FUNCTION_END(status); + return status; +} + + +int VL6180x_RangeStartContinuousMode(VL6180xDev_t dev) +{ + int status; + LOG_FUNCTION_START(""); + status= VL6180x_RangeSetSystemMode(dev, MODE_START_STOP | MODE_CONTINUOUS); + LOG_FUNCTION_END(status); + return status; +} + +int VL6180x_RangeStartSingleShot(VL6180xDev_t dev) { + int status; + LOG_FUNCTION_START(""); + status = VL6180x_RangeSetSystemMode(dev, MODE_START_STOP|MODE_SINGLESHOT); + LOG_FUNCTION_END(status); + return status; +} + + +static int VL6180x_RangeSetEarlyConvergenceEestimateThreshold(VL6180xDev_t dev) +{ + int status; + + const uint32_t cMicroSecPerMilliSec = 1000; + const uint32_t cEceSampleTime_us = 500; + uint32_t ece_factor_m = VL6180xDevDataGet(dev, EceFactorM); + uint32_t ece_factor_d = VL6180xDevDataGet(dev, EceFactorD); + uint32_t convergTime_us; + uint32_t fineThresh; + uint32_t eceThresh; + uint8_t u8; + uint32_t maxConv_ms; + int32_t AveTime; + + LOG_FUNCTION_START(""); + + do{ + status = VL6180x_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &u8); + if( status ){ + VL6180x_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail"); + break; + } + maxConv_ms = u8; + AveTime = _GetAveTotalTime(dev); + if( AveTime <0 ){ + status=-1; + break; + } + + convergTime_us = maxConv_ms * cMicroSecPerMilliSec - AveTime; + status = VL6180x_RdDWord(dev, 0xB8, &fineThresh); + if( status ) { + VL6180x_ErrLog("reg 0xB8 rd fail"); + break; + } + fineThresh*=256; + eceThresh = ece_factor_m * cEceSampleTime_us * fineThresh/(convergTime_us * ece_factor_d); + + status=VL6180x_WrWord(dev, SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, (uint16_t)eceThresh); + } + while(0); + + LOG_FUNCTION_END(status); + return status; +} + +/* + * Return >0 = time + * <0 1 if fail to get read data from device to compute time + */ +static int32_t _GetAveTotalTime(VL6180xDev_t dev) { + uint32_t cFwOverhead_us = 24; + uint32_t cVcpSetupTime_us = 70; + uint32_t cPLL2_StartupDelay_us = 200; + uint8_t cMeasMask = 0x07; + uint32_t Samples; + uint32_t SamplePeriod; + uint32_t SingleTime_us; + int32_t TotalAveTime_us; + uint8_t u8; + int status; + + LOG_FUNCTION_START(""); + + status = VL6180x_RdByte(dev, 0x109, &u8); + if (status) { + VL6180x_ErrLog("rd 0x109 fail"); + return -1; + } + Samples = u8 & cMeasMask; + status = VL6180x_RdByte(dev, READOUT_AVERAGING_SAMPLE_PERIOD, &u8); + if (status) { + VL6180x_ErrLog("i2c READOUT_AVERAGING_SAMPLE_PERIOD fail"); + return -1; + } + SamplePeriod = u8; + SingleTime_us = cFwOverhead_us + cVcpSetupTime_us + (SamplePeriod * 10); + TotalAveTime_us = (Samples + 1) * SingleTime_us + cPLL2_StartupDelay_us; + + LOG_FUNCTION_END(TotalAveTime_us); + return TotalAveTime_us; +} + + +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + +#define FILTER_STDDEV_SAMPLES 6 +#define MIN_FILTER_STDDEV_SAMPLES 3 +#define MIN_FILTER_VALID_STDDEV_SAMPLES 4 +#define FILTER_INVALID_DISTANCE 65535 + +#define _FilterData(field) VL6180xDevDataGet(dev, FilterData.field) +/* + * One time init + */ +int _filter_Init( VL6180xDev_t dev) { + int i; + _FilterData(MeasurementIndex) = 0; + + _FilterData(Default_ZeroVal) = 0; + _FilterData(Default_VAVGVal) = 0; + _FilterData(NoDelay_ZeroVal) = 0; + _FilterData(NoDelay_VAVGVal) = 0; + _FilterData(Previous_VAVGDiff) = 0; + + _FilterData(StdFilteredReads) = 0; + + for (i = 0; i < FILTER_NBOF_SAMPLES; i++) { + _FilterData(LastTrueRange)[i] = FILTER_INVALID_DISTANCE; + _FilterData(LastReturnRates)[i] = 0; + } + return 0; +} + + +static uint32_t _filter_StdDevDamper(uint32_t AmbientRate, uint32_t SignalRate, const uint32_t StdDevLimitLowLight, const uint32_t StdDevLimitLowLightSNR, const uint32_t StdDevLimitHighLight, const uint32_t StdDevLimitHighLightSNR) { + uint32_t newStdDev; + uint16_t SNR; + + if (AmbientRate > 0) + SNR = (uint16_t) ((100 * SignalRate) / AmbientRate); + else + SNR = 9999; + + if (SNR >= StdDevLimitLowLightSNR) { + newStdDev = StdDevLimitLowLight; + } else { + if (SNR <= StdDevLimitHighLightSNR) + newStdDev = StdDevLimitHighLight; + else { + newStdDev = (uint32_t) (StdDevLimitHighLight + (SNR - StdDevLimitHighLightSNR) * (int) (StdDevLimitLowLight - StdDevLimitHighLight) / (StdDevLimitLowLightSNR - StdDevLimitHighLightSNR)); + } + } + + return newStdDev; +} + +/* + * Return <0 on error + */ +static int32_t _filter_Start(VL6180xDev_t dev, uint16_t m_trueRange_mm, uint16_t m_rawRange_mm, uint32_t m_rtnSignalRate, uint32_t m_rtnAmbientRate, uint16_t errorCode) { + int status; + uint16_t m_newTrueRange_mm = 0; + + uint16_t i; + uint16_t bypassFilter = 0; + + uint16_t registerValue; + + uint32_t register32BitsValue1; + uint32_t register32BitsValue2; + + uint16_t ValidDistance = 0; + + uint16_t WrapAroundFlag = 0; + uint16_t NoWrapAroundFlag = 0; + uint16_t NoWrapAroundHighConfidenceFlag = 0; + + uint16_t FlushFilter = 0; + uint32_t RateChange = 0; + + uint16_t StdDevSamples = 0; + uint32_t StdDevDistanceSum = 0; + uint32_t StdDevDistanceMean = 0; + uint32_t StdDevDistance = 0; + uint32_t StdDevRateSum = 0; + uint32_t StdDevRateMean = 0; + uint32_t StdDevRate = 0; + uint32_t StdDevLimitWithTargetMove = 0; + + uint32_t VAVGDiff; + uint32_t IdealVAVGDiff; + uint32_t MinVAVGDiff; + uint32_t MaxVAVGDiff; + + /* Filter Parameters */ + static const uint16_t ROMABLE_DATA WrapAroundLowRawRangeLimit = 60; + static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateLimit = 800; + static const uint16_t ROMABLE_DATA WrapAroundLowRawRangeLimit2 = 165; + static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateLimit2 = 300; + + static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateFilterLimit = 600; + static const uint16_t ROMABLE_DATA WrapAroundHighRawRangeFilterLimit = 350; + static const uint32_t ROMABLE_DATA WrapAroundHighReturnRateFilterLimit = 900; + + static const uint32_t ROMABLE_DATA WrapAroundMaximumAmbientRateFilterLimit = 7500; + + /* Temporal filter data and flush values */ + static const uint32_t ROMABLE_DATA MinReturnRateFilterFlush = 75; + static const uint32_t ROMABLE_DATA MaxReturnRateChangeFilterFlush = 50; + + /* STDDEV values and damper values */ + + static const uint32_t ROMABLE_DATA StdDevLimitLowLight = 300; + static const uint32_t ROMABLE_DATA StdDevLimitLowLightSNR = 30; /* 0.3 */ + static const uint32_t ROMABLE_DATA StdDevLimitHighLight = 2500; + static const uint32_t ROMABLE_DATA StdDevLimitHighLightSNR = 5; /* 0.05 */ + + static const uint32_t ROMABLE_DATA StdDevHighConfidenceSNRLimit = 8; + + static const uint32_t ROMABLE_DATA StdDevMovingTargetStdDevLimit = 90000; + + static const uint32_t ROMABLE_DATA StdDevMovingTargetReturnRateLimit = 3500; + static const uint32_t ROMABLE_DATA StdDevMovingTargetStdDevForReturnRateLimit = 5000; + + static const uint32_t ROMABLE_DATA MAX_VAVGDiff = 1800; + + /* WrapAroundDetection variables */ + static const uint16_t ROMABLE_DATA WrapAroundNoDelayCheckPeriod = 2; + static const uint16_t ROMABLE_DATA StdFilteredReadsIncrement = 2; + static const uint16_t ROMABLE_DATA StdMaxFilteredReads = 4; + + uint8_t u8; + uint32_t StdDevLimit = 300; + uint32_t MaxOrInvalidDistance = 255*_GetUpscale(dev); + /* #define MaxOrInvalidDistance (uint16_t) (255 * 3) */ + + /* Check if distance is Valid or not */ + switch (errorCode) { + case 0x0C: + m_trueRange_mm = MaxOrInvalidDistance; + ValidDistance = 0; + break; + case 0x0D: + m_trueRange_mm = MaxOrInvalidDistance; + ValidDistance = 1; + break; + default: + if (m_rawRange_mm >= MaxOrInvalidDistance) { + ValidDistance = 0; + } else { + ValidDistance = 1; + } + break; + } + m_newTrueRange_mm = m_trueRange_mm; + + /* Checks on low range data */ + if ((m_rawRange_mm < WrapAroundLowRawRangeLimit) && (m_rtnSignalRate < WrapAroundLowReturnRateLimit)) { + m_newTrueRange_mm = MaxOrInvalidDistance; + bypassFilter = 1; + } + if ((m_rawRange_mm < WrapAroundLowRawRangeLimit2) && (m_rtnSignalRate < WrapAroundLowReturnRateLimit2)) { + m_newTrueRange_mm = MaxOrInvalidDistance; + bypassFilter = 1; + } + + /* Checks on Ambient rate level */ + if (m_rtnAmbientRate > WrapAroundMaximumAmbientRateFilterLimit) { + /* Too high ambient rate */ + FlushFilter = 1; + bypassFilter = 1; + } + /* Checks on Filter flush */ + if (m_rtnSignalRate < MinReturnRateFilterFlush) { + /* Completely lost target, so flush the filter */ + FlushFilter = 1; + bypassFilter = 1; + } + if (_FilterData(LastReturnRates)[0] != 0) { + if (m_rtnSignalRate > _FilterData(LastReturnRates)[0]) + RateChange = (100 * (m_rtnSignalRate - _FilterData(LastReturnRates)[0])) / _FilterData(LastReturnRates)[0]; + else + RateChange = (100 * (_FilterData(LastReturnRates)[0] - m_rtnSignalRate)) / _FilterData(LastReturnRates)[0]; + } else + RateChange = 0; + if (RateChange > MaxReturnRateChangeFilterFlush) { + FlushFilter = 1; + } +/* TODO optimize filter using circular buffer */ + if (FlushFilter == 1) { + _FilterData(MeasurementIndex) = 0; + for (i = 0; i < FILTER_NBOF_SAMPLES; i++) { + _FilterData(LastTrueRange)[i] = FILTER_INVALID_DISTANCE; + _FilterData(LastReturnRates)[i] = 0; + } + } else { + for (i = (uint16_t) (FILTER_NBOF_SAMPLES - 1); i > 0; i--) { + _FilterData(LastTrueRange)[i] = _FilterData(LastTrueRange)[i - 1]; + _FilterData(LastReturnRates)[i] = _FilterData(LastReturnRates)[i - 1]; + } + } + if (ValidDistance == 1) + _FilterData(LastTrueRange)[0] = m_trueRange_mm; + else + _FilterData(LastTrueRange)[0] = FILTER_INVALID_DISTANCE; + _FilterData(LastReturnRates)[0] = m_rtnSignalRate; + + /* Check if we need to go through the filter or not */ + if (!(((m_rawRange_mm < WrapAroundHighRawRangeFilterLimit) && (m_rtnSignalRate < WrapAroundLowReturnRateFilterLimit)) || ((m_rawRange_mm >= WrapAroundHighRawRangeFilterLimit) && (m_rtnSignalRate < WrapAroundHighReturnRateFilterLimit)))) + bypassFilter = 1; + + /* Check which kind of measurement has been made */ + status = VL6180x_RdByte(dev, 0x01AC, &u8 ); + if( status ){ + VL6180x_ErrLog("0x01AC rd fail"); + goto done_err; + } + registerValue =u8; + + /* Read data for filtering */ + status = VL6180x_RdByte(dev, 0x10C, &u8 ); /* read only 8 lsb bits */ + if( status ){ + VL6180x_ErrLog("0x010C rd fail"); + goto done_err; + } + register32BitsValue1=u8; + status = VL6180x_RdByte(dev, 0x0110, &u8); /* read only 8 lsb bits */ + if( status ){ + VL6180x_ErrLog("0x0110 rd fail"); + goto done_err; + } + register32BitsValue2 = u8; + + if (registerValue == 0x3E) { + _FilterData(Default_ZeroVal) = register32BitsValue1; + _FilterData(Default_VAVGVal) = register32BitsValue2; + } else { + _FilterData(NoDelay_ZeroVal) = register32BitsValue1; + _FilterData(NoDelay_VAVGVal) = register32BitsValue2; + } + + if (bypassFilter == 1) { + /* Do not go through the filter */ + if (registerValue != 0x3E) { + status = VL6180x_WrByte(dev, 0x1AC, 0x3E); + if( status ){ + VL6180x_ErrLog("0x01AC wr fail"); + goto done_err; + } + } + /* Set both Default and NoDelay To same value */ + _FilterData(Default_ZeroVal) = register32BitsValue1; + _FilterData(Default_VAVGVal) = register32BitsValue2; + _FilterData(NoDelay_ZeroVal) = register32BitsValue1; + _FilterData(NoDelay_VAVGVal) = register32BitsValue2; + _FilterData(MeasurementIndex) = 0; + + return m_newTrueRange_mm; + } + + if (_FilterData(MeasurementIndex) % WrapAroundNoDelayCheckPeriod == 0) { + u8=0x3C; + } else { + u8=0x3E; + } + status = VL6180x_WrByte(dev, 0x01AC, u8); + if( status ){ + VL6180x_ErrLog("0x01AC wr fail"); + goto done_err; + } + + _FilterData(MeasurementIndex)++; + + /* Computes current VAVGDiff */ + if (_FilterData(Default_VAVGVal) > _FilterData(NoDelay_VAVGVal)) + VAVGDiff = _FilterData(Default_VAVGVal) - _FilterData(NoDelay_VAVGVal); + else + VAVGDiff = 0; + _FilterData(Previous_VAVGDiff) = VAVGDiff; + + /* Check the VAVGDiff */ + if (_FilterData(Default_ZeroVal) > _FilterData(NoDelay_ZeroVal)) + IdealVAVGDiff = _FilterData(Default_ZeroVal) - _FilterData(NoDelay_ZeroVal); + else + IdealVAVGDiff = _FilterData(NoDelay_ZeroVal) - _FilterData(Default_ZeroVal); + if (IdealVAVGDiff > MAX_VAVGDiff) + MinVAVGDiff = IdealVAVGDiff - MAX_VAVGDiff; + else + MinVAVGDiff = 0; + MaxVAVGDiff = IdealVAVGDiff + MAX_VAVGDiff; + if (VAVGDiff < MinVAVGDiff || VAVGDiff > MaxVAVGDiff) { + WrapAroundFlag = 1; + } else { + /* Go through filtering check */ + + /* StdDevLimit Damper on SNR */ + StdDevLimit = _filter_StdDevDamper(m_rtnAmbientRate, m_rtnSignalRate, StdDevLimitLowLight, StdDevLimitLowLightSNR, StdDevLimitHighLight, StdDevLimitHighLightSNR); + + /* Standard deviations computations */ + StdDevSamples = 0; + StdDevDistanceSum = 0; + StdDevDistanceMean = 0; + StdDevDistance = 0; + StdDevRateSum = 0; + StdDevRateMean = 0; + StdDevRate = 0; + for (i = 0; (i < FILTER_NBOF_SAMPLES) && (StdDevSamples < FILTER_STDDEV_SAMPLES); i++) { + if (_FilterData(LastTrueRange)[i] != FILTER_INVALID_DISTANCE) { + StdDevSamples = (uint16_t) (StdDevSamples + 1); + StdDevDistanceSum = (uint32_t) (StdDevDistanceSum + _FilterData(LastTrueRange)[i]); + StdDevRateSum = (uint32_t) (StdDevRateSum + _FilterData(LastReturnRates)[i]); + } + } + if (StdDevSamples > 0) { + StdDevDistanceMean = (uint32_t) (StdDevDistanceSum / StdDevSamples); + StdDevRateMean = (uint32_t) (StdDevRateSum / StdDevSamples); + } + /* TODO optimize shorten Std dev in aisngle loop computation using sum of x2 - (sum of x)2 */ + StdDevSamples = 0; + StdDevDistanceSum = 0; + StdDevRateSum = 0; + for (i = 0; (i < FILTER_NBOF_SAMPLES) && (StdDevSamples < FILTER_STDDEV_SAMPLES); i++) { + if (_FilterData(LastTrueRange)[i] != FILTER_INVALID_DISTANCE) { + StdDevSamples = (uint16_t) (StdDevSamples + 1); + StdDevDistanceSum = (uint32_t) (StdDevDistanceSum + (int) (_FilterData(LastTrueRange)[i] - StdDevDistanceMean) * (int) (_FilterData(LastTrueRange)[i] - StdDevDistanceMean)); + StdDevRateSum = (uint32_t) (StdDevRateSum + (int) (_FilterData(LastReturnRates)[i] - StdDevRateMean) * (int) (_FilterData(LastReturnRates)[i] - StdDevRateMean)); + } + } + if (StdDevSamples >= MIN_FILTER_STDDEV_SAMPLES) { + StdDevDistance = (uint16_t) (StdDevDistanceSum / StdDevSamples); + StdDevRate = (uint16_t) (StdDevRateSum / StdDevSamples); + } else { + StdDevDistance = 0; + StdDevRate = 0; + } + + /* Check Return rate standard deviation */ + if (StdDevRate < StdDevMovingTargetStdDevLimit) { + if (StdDevSamples < MIN_FILTER_VALID_STDDEV_SAMPLES) { + m_newTrueRange_mm = MaxOrInvalidDistance; + } else { + /* Check distance standard deviation */ + if (StdDevRate < StdDevMovingTargetReturnRateLimit) + StdDevLimitWithTargetMove = StdDevLimit + (((StdDevMovingTargetStdDevForReturnRateLimit - StdDevLimit) * StdDevRate) / StdDevMovingTargetReturnRateLimit); + else + StdDevLimitWithTargetMove = StdDevMovingTargetStdDevForReturnRateLimit; + + if ((StdDevDistance * StdDevHighConfidenceSNRLimit) < StdDevLimitWithTargetMove) { + NoWrapAroundHighConfidenceFlag = 1; + } else { + if (StdDevDistance < StdDevLimitWithTargetMove) { + if (StdDevSamples >= MIN_FILTER_VALID_STDDEV_SAMPLES) { + NoWrapAroundFlag = 1; + } else { + m_newTrueRange_mm = MaxOrInvalidDistance; + } + } else { + WrapAroundFlag = 1; + } + } + } + } else { + WrapAroundFlag = 1; + } + } + + if (m_newTrueRange_mm == MaxOrInvalidDistance) { + if (_FilterData(StdFilteredReads) > 0) + _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) - 1); + } else { + if (WrapAroundFlag == 1) { + m_newTrueRange_mm = MaxOrInvalidDistance; + _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) + StdFilteredReadsIncrement); + if (_FilterData(StdFilteredReads) > StdMaxFilteredReads) + _FilterData(StdFilteredReads) = StdMaxFilteredReads; + } else { + if (NoWrapAroundFlag == 1) { + if (_FilterData(StdFilteredReads) > 0) { + m_newTrueRange_mm = MaxOrInvalidDistance; + if (_FilterData(StdFilteredReads) > StdFilteredReadsIncrement) + _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) - StdFilteredReadsIncrement); + else + _FilterData(StdFilteredReads) = 0; + } + } else { + if (NoWrapAroundHighConfidenceFlag == 1) { + _FilterData(StdFilteredReads) = 0; + } + } + } + } + + return m_newTrueRange_mm; + done_err: + return -1; + + #undef MaxOrInvalidDistance +} + + +static int _filter_GetResult(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData) { + uint32_t m_rawRange_mm = 0; + int32_t FilteredRange; + const uint8_t scaler = _GetUpscale(dev); + uint8_t u8; + int status; + + do { + status = VL6180x_RdByte(dev, RESULT_RANGE_RAW, &u8); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_RAW rd fail"); + break; + } + m_rawRange_mm = u8; + + FilteredRange = _filter_Start(dev, pRangeData->range_mm, (m_rawRange_mm * scaler), pRangeData->rtnRate, pRangeData->rtnAmbRate, pRangeData->errorStatus); + if( FilteredRange<0 ){ + status = -1; + break; + } + pRangeData->FilteredData.range_mm= FilteredRange; + pRangeData->FilteredData.rawRange_mm = m_rawRange_mm * scaler; + } while (0); + return status; +} + +static int _filter_GetResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pRangeData) { + uint32_t m_rawRange_mm = 0; + int32_t FilteredRange; + const uint8_t scaler = _GetUpscale(dev); + //uint8_t u8; + int status=0; + + do { + m_rawRange_mm = pResultData->Result_range_raw; + + FilteredRange = _filter_Start(dev, pRangeData->range_mm, (m_rawRange_mm * scaler), pRangeData->rtnRate, pRangeData->rtnAmbRate, pRangeData->errorStatus); + if( FilteredRange<0 ){ + status = -1; + break; + } + pRangeData->FilteredData.range_mm= FilteredRange; + pRangeData->FilteredData.rawRange_mm = m_rawRange_mm * scaler; + } while (0); + return status; +} +#undef _FilterData +#undef FILTER_STDDEV_SAMPLES +#undef MIN_FILTER_STDDEV_SAMPLES +#undef MIN_FILTER_VALID_STDDEV_SAMPLES +#undef FILTER_INVALID_DISTANCE + +#endif /* VL6180x_WRAP_AROUND_FILTER_SUPPORT */ + +#ifdef VL6180x_HAVE_RATE_DATA + +static int _GetRateResult(VL6180xDev_t dev, VL6180x_RangeData_t *pRangeData) { + uint32_t m_rtnConvTime = 0; + uint32_t m_rtnSignalRate = 0; + uint32_t m_rtnAmbientRate = 0; + uint32_t m_rtnSignalCount = 0; + uint32_t m_rtnAmbientCount = 0; + uint32_t m_refConvTime = 0; + uint32_t cRtnSignalCountMax = 0x7FFFFFFF; + uint32_t cDllPeriods = 6; + uint32_t calcConvTime = 0; + + int status; + + do { + + status = VL6180x_RdDWord(dev, RESULT_RANGE_RETURN_SIGNAL_COUNT, &m_rtnSignalCount); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_RETURN_SIGNAL_COUNT rd fail"); + break; + } + if (m_rtnSignalCount > cRtnSignalCountMax) { + m_rtnSignalCount = 0; + } + + status = VL6180x_RdDWord(dev, RESULT_RANGE_RETURN_AMB_COUNT, &m_rtnAmbientCount); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_RETURN_AMB_COUNTrd fail"); + break; + } + + + status = VL6180x_RdDWord(dev, RESULT_RANGE_RETURN_CONV_TIME, &m_rtnConvTime); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_RETURN_CONV_TIME rd fail"); + break; + } + + status = VL6180x_RdDWord(dev, RESULT_RANGE_REFERENCE_CONV_TIME, &m_refConvTime); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_REFERENCE_CONV_TIME rd fail"); + break; + } + + pRangeData->rtnConvTime = m_rtnConvTime; + pRangeData->refConvTime = m_refConvTime; + + calcConvTime = m_refConvTime; + if (m_rtnConvTime > m_refConvTime) { + calcConvTime = m_rtnConvTime; + } + if (calcConvTime == 0) + calcConvTime = 63000; + + m_rtnSignalRate = (m_rtnSignalCount * 1000) / calcConvTime; + m_rtnAmbientRate = (m_rtnAmbientCount * cDllPeriods * 1000) / calcConvTime; + + pRangeData->rtnRate = m_rtnSignalRate; + pRangeData->rtnAmbRate = m_rtnAmbientRate; +//read other data for debug + pRangeData->m_rtnSignalCount = m_rtnSignalCount; + pRangeData->m_rtnAmbientCount = m_rtnAmbientCount; + status = VL6180x_RdByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, &(pRangeData->m_rangeOffset)); + if (status) { + VL6180x_ErrLog("SYSRANGE_PART_TO_PART_RANGE_OFFSET rd fail"); + break; + } + status = VL6180x_RdWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, &(pRangeData->m_crossTalk)); + if (status) { + VL6180x_ErrLog("SYSRANGE_CROSSTALK_COMPENSATION_RATE rd fail"); + break; + } + status = VL6180x_RdWord(dev, RESULT_RANGE_REFERENCE_RATE, &(pRangeData->m_refRate)); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_REFERENCE_RATE rd fail"); + break; + } + status = VL6180x_RdDWord(dev, RESULT_RANGE_RETURN_CONV_TIME, &(pRangeData->m_convTime)); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_RETURN_CONV_TIME rd fail"); + break; + } + status = VL6180x_RdDWord(dev, RESULT_RANGE_REFERENCE_SIGNAL_COUNT, &(pRangeData->m_refSignalCount)); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_REFERENCE_SIGNAL_COUNT rd fail"); + break; + } + status = VL6180x_RdDWord(dev, RESULT_RANGE_REFERENCE_AMB_COUNT, &(pRangeData->m_refAmbientCount)); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_REFERENCE_AMB_COUNT rd fail"); + break; + } + pRangeData->m_refAmbRate = (pRangeData->m_refAmbientCount * cDllPeriods * 1000) / calcConvTime; +//read other data for debug + + } while (0); + return status; +} + +static int _GetRateResult_ext(VL6180xDev_t dev, VL6180x_RangeResultData_t *pResultData, VL6180x_RangeData_t *pRangeData) { + uint32_t m_rtnConvTime = pResultData->Result_range_return_conv_time; + uint32_t m_rtnSignalRate = 0; + uint32_t m_rtnAmbientRate = 0; + uint32_t m_rtnSignalCount = pResultData->Result_range_return_signal_count; + uint32_t m_rtnAmbientCount = pResultData->Result_range_return_amb_count; + uint32_t m_refConvTime = pResultData->Result_range_reference_conv_time; + uint32_t cRtnSignalCountMax = 0x7FFFFFFF; + uint32_t cDllPeriods = 6; + uint32_t calcConvTime = 0; + + int status=0; + + do { + + if (m_rtnSignalCount > cRtnSignalCountMax) { + m_rtnSignalCount = 0; + } + + pRangeData->rtnConvTime = m_rtnConvTime; + pRangeData->refConvTime = m_refConvTime; + + calcConvTime = m_refConvTime; + if (m_rtnConvTime > m_refConvTime) { + calcConvTime = m_rtnConvTime; + } + if (calcConvTime == 0) + calcConvTime = 63000; + + m_rtnSignalRate = (m_rtnSignalCount * 1000) / calcConvTime; + m_rtnAmbientRate = (m_rtnAmbientCount * cDllPeriods * 1000) / calcConvTime; + + pRangeData->rtnRate = m_rtnSignalRate; + pRangeData->rtnAmbRate = m_rtnAmbientRate; + pRangeData->m_refRate = (pResultData->Result_range_reference_signal_count*1000)/calcConvTime; + pRangeData->m_refAmbRate = (pResultData->Result_range_reference_amb_count*1000)/calcConvTime; + + } while (0); + return status; +} +#endif /* VL6180x_HAVE_RATE_DATA */ + +#if VL6180x_HAVE_DMAX_RANGING + +#define _DMaxData(field) VL6180xDevDataGet(dev, DMaxData.field) + +#define Fix7_2_KCPs(x) ((((uint32_t)(x))*1000)>>7) + +/* DMax one time init */ +void _DMax_OneTimeInit(VL6180xDev_t dev){ + _DMaxData(ambTuningWindowFactor_K)=200; +} + +/* + * fetch static data from register to avoid re-read + * to be re-used/call on changes of : + * 0x2A + * SYSRANGE_CROSSTALK_COMPENSATION_RATE + * SYSRANGE_MAX_CONVERGENCE_TIME + * range 0xb8-0xbb (0xbb) + */ +static int _DMax_InitData(VL6180xDev_t dev){ + int status, warning; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint32_t Reg2A_KCps; + uint32_t XTalkCompRate_KCps; + warning=0; + LOG_FUNCTION_START(""); + do{ + status = VL6180x_RdByte(dev, 0x02A ,&u8); + if( status ){ + VL6180x_ErrLog("Reg 0x02A rd fail"); + break; + } + + if( u8 == 0 ) { + warning = CALIBRATION_WARNING; + u8 = 40; /* use a default average value */ + } + Reg2A_KCps = Fix7_2_KCPs(u8); /* convert to KCPs */ + + status = VL6180x_RdWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE ,&u16); + if( status){ + VL6180x_ErrLog("SYSRANGE_CROSSTALK_COMPENSATION_RATE rd fail "); + break; + } + XTalkCompRate_KCps = Fix7_2_KCPs(u16); + + status = VL6180x_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &u8); + if( status){ + VL6180x_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail "); + break; + } + _DMaxData(MaxConvTime)=u8; + + status = VL6180x_RdDWord(dev, 0x0B8, &u32); + if( status ){ + VL6180x_ErrLog("reg 0x0B8 rd fail "); + break; + } + _DMaxData(RegB8)=u32; + + if( Reg2A_KCps >= XTalkCompRate_KCps){ + _DMaxData(retSignalAt0mm)=( Reg2A_KCps - XTalkCompRate_KCps); + } + else{ + _DMaxData(retSignalAt0mm)=0; /* Reg2A_K - XTalkCompRate_KCp <0 is invalid */ + } + + } + while(0); + if( !status ) + status = warning; + LOG_FUNCTION_END(status); + return status; +} + + +#ifndef VL6180x_PLATFORM_PROVIDE_SQRT +/* + * 32 bit integer square root with not so bad precision (integer result) and is quite fast + * see http://en.wikipedia.org/wiki/Methods_of_computing_square_roots + */ +uint32_t VL6180x_SqrtUint32(uint32_t num) { + uint32_t res = 0; + uint32_t bit = 1 << 30; /* The second-to-top bit is set: 1 << 30 for 32 bits */ + + /* "bit" starts at the highest power of four <= the argument. */ + while (bit > num) + bit >>= 2; + + while (bit != 0) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1) + bit; + } + else + res >>= 1; + bit >>= 2; + } + return res; +} +#endif + +static int _DMax_Compute(VL6180xDev_t dev, VL6180x_RangeData_t *pRange){ + DMaxFix_t regB8; + + + DMaxFix_t retSignalAt0mm; + uint32_t rtnAmbRate; + int32_t maxConvTime; + int32_t minSignalNeeded; + int32_t DMaxSq; + int32_t DMax; + + static const int ROMABLE_DATA maxConvTimeAdjust=-4; + static const int ROMABLE_DATA rtnAmbLowLimit_KCps=330*1000; + int ambTuningWindowFactor_K = _DMaxData(ambTuningWindowFactor_K); + /* TODO rtnAmbRate to be moved out of filter data */ + rtnAmbRate = pRange->rtnAmbRate; + if( rtnAmbRate < rtnAmbLowLimit_KCps ){ + DMaxFix_t signalAtRateRatio; + + retSignalAt0mm = _DMaxData(retSignalAt0mm); + /* signalAtRateRatio = retSignalAt0mm*rtnAmbRate => 12 + 18 bits */ + signalAtRateRatio = (retSignalAt0mm*rtnAmbRate)/rtnAmbLowLimit_KCps; /* 30 bits - 18 bits = 12 Bits*/ + + regB8 = _DMaxData(RegB8); + maxConvTime = _DMaxData(MaxConvTime); + + minSignalNeeded = (regB8*256)/(maxConvTime+maxConvTimeAdjust); /* KCps 8+8 bit -(1 to 6 bit) => 15-10 bit */ + DMaxSq = (retSignalAt0mm -signalAtRateRatio)*400*400/ (minSignalNeeded + (rtnAmbRate*ambTuningWindowFactor_K)/1000); /* 11 + (9+9) - (15 to 10) bits ok on 32 bits final in range 20-15 bit*/ + DMax = VL6180x_SqrtUint32(DMaxSq); + if( DMax > 400 ) + pRange->DMax=400; + else + pRange->DMax=DMax; + } + else{ + pRange->DMax = 0; + } + return 0; +} + +#undef _DMaxData +#undef Fix7_2_KCPs + +#endif /* VL6180x_HAVE_DMAX_RANGING */ + + + diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_i2c.c new file mode 100755 index 0000000000000..3e8ca940d3906 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_i2c.c @@ -0,0 +1,329 @@ + +/******************************************************************************* +Copyright © 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of STMicroelectronics nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND +NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED. +IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +********************************************************************************/ +/* + * $Date: 2015-01-08 05:30:24 -0800 (Thu, 08 Jan 2015) $ + * $Revision: 2039 $ + */ + +/** + * @file vl6180x_i2c.c + * + * Copyright (C) 2014 ST MicroElectronics + * + * provide variable word size byte/Word/dword VL6180x register access via i2c + * + */ +#include "vl6180x_i2c.h" + +#ifndef I2C_BUFFER_CONFIG +#error "I2C_BUFFER_CONFIG not defined" +/* TODO you must define value for I2C_BUFFER_CONFIG in configuration or platform h */ +#endif + + +#if I2C_BUFFER_CONFIG == 0 + /* GLOBAL config buffer */ + uint8_t i2c_global_buffer[VL6180x_MAX_I2C_XFER_SIZE]; + + #define DECL_I2C_BUFFER + #define VL6180x_GetI2cBuffer(dev, n_byte) i2c_global_buffer + +#elif I2C_BUFFER_CONFIG == 1 + /* ON STACK */ + #define DECL_I2C_BUFFER uint8_t LocBuffer[VL6180x_MAX_I2C_XFER_SIZE]; + #define VL6180x_GetI2cBuffer(dev, n_byte) LocBuffer +#elif I2C_BUFFER_CONFIG == 2 + /* user define buffer type declare DECL_I2C_BUFFER as access via VL6180x_GetI2cBuffer */ + #define DECL_I2C_BUFFER +#else +#error "invalid I2C_BUFFER_CONFIG " +#endif + +extern struct stmvl6180_data *vl6180_data_g; + +int VL6180x_WrByte(VL6180xDev_t dev, uint16_t index, uint8_t data){ + int rc; + uint8_t *buffer; + DECL_I2C_BUFFER + VL6180x_I2C_USER_VAR +//Laser sensor conected on CCI bus + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_write(&vl6180_data_g->i2c_client, index, data, 1); + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + + buffer=VL6180x_GetI2cBuffer(dev,3); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + buffer[2]=data; + + rc=VL6180x_I2CWrite(dev, buffer,(uint8_t)3); + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_WrWord(VL6180xDev_t dev, uint16_t index, uint16_t data){ + int rc = 0; + uint8_t write_buffer[2] = { 0, 0}; + DECL_I2C_BUFFER + uint8_t *buffer; + VL6180x_I2C_USER_VAR + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + write_buffer[1] = (uint8_t)(data & 0xFF); + write_buffer[0] = (uint8_t)(data >> 8); + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_write_seq( + &vl6180_data_g->i2c_client, index, write_buffer, 2); + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + buffer=VL6180x_GetI2cBuffer(dev,4); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + buffer[2]=data>>8; + buffer[3]=data&0xFF; + + rc=VL6180x_I2CWrite(dev, buffer,(uint8_t)4); + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_WrDWord(VL6180xDev_t dev, uint16_t index, uint32_t data){ + int rc = 0; + uint8_t write_buffer[4] = { 0, 0, 0, 0}; + VL6180x_I2C_USER_VAR + DECL_I2C_BUFFER + uint8_t *buffer; + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + write_buffer[3] = (uint8_t)(data & 0xFF); + write_buffer[2] = (uint8_t)((data >> 8) & 0xFF); + write_buffer[1] = (uint8_t)((data >> 16) & 0xFF); + write_buffer[0] = (uint8_t)((data >> 24) & 0xFF); + + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_write_seq( + &vl6180_data_g->i2c_client, index, write_buffer, 4); + + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + buffer=VL6180x_GetI2cBuffer(dev,6); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + buffer[2]=data>>24; + buffer[3]=(data>>16)&0xFF; + buffer[4]=(data>>8)&0xFF;; + buffer[5]=data&0xFF; + rc=VL6180x_I2CWrite(dev, buffer,(uint8_t)6); + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_UpdateByte(VL6180xDev_t dev, uint16_t index, uint8_t AndData, uint8_t OrData){ + int rc; + uint16_t tmp=0; + VL6180x_I2C_USER_VAR + uint8_t *buffer; + DECL_I2C_BUFFER + + VL6180x_GetI2CAccess(dev); + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_read( + &(vl6180_data_g->i2c_client), index, &tmp, 1); + if(rc){ + pr_err("%s:%d i2c_read failed", __func__, __LINE__); + return rc; + } + + tmp = (tmp&AndData)|OrData; + + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_write( + &vl6180_data_g->i2c_client, index, tmp, 1); + if(rc){ + pr_err("%s:%d i2c_write failed", __func__, __LINE__); + return rc; + } + return 0; + }else{ + buffer=VL6180x_GetI2cBuffer(dev,3); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + + rc=VL6180x_I2CWrite(dev, (uint8_t *)buffer,(uint8_t)2); + if( !rc ){ + /* read data direct onto buffer */ + rc=VL6180x_I2CRead(dev, &buffer[2],1); + if( !rc ){ + buffer[2]=(buffer[2]&AndData)|OrData; + rc=VL6180x_I2CWrite(dev, buffer, (uint8_t)3); + } + } + + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_RdByte(VL6180xDev_t dev, uint16_t index, uint8_t *data){ + int rc; + uint16_t tmp=0; + VL6180x_I2C_USER_VAR + uint8_t *buffer; + DECL_I2C_BUFFER + VL6180x_GetI2CAccess(dev); + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_read( + &(vl6180_data_g->i2c_client), index, &tmp, 1); + *data = (uint8_t)tmp; + return rc; + }else{ + buffer=VL6180x_GetI2cBuffer(dev,2); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + + rc=VL6180x_I2CWrite(dev, buffer, (uint8_t)2); + if( !rc ){ + rc=VL6180x_I2CRead(dev, buffer,1); + if( !rc ){ + *data=buffer[0]; + } + } + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_RdWord(VL6180xDev_t dev, uint16_t index, uint16_t *data){ + int rc; + uint8_t read_buffer[2] = { 0, 0}; + VL6180x_I2C_USER_VAR + uint8_t *buffer; + DECL_I2C_BUFFER + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_read_seq( + &(vl6180_data_g->i2c_client), index, read_buffer, 2); + *data = (uint16_t)( (unsigned int)(read_buffer[0] <<8) |(unsigned int)((read_buffer[1])) ); + + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + + buffer=VL6180x_GetI2cBuffer(dev,2); + buffer[0]=index>>8; + buffer[1]=index&0xFF; + + rc=VL6180x_I2CWrite(dev, buffer, (uint8_t)2); + if( !rc){ + rc=VL6180x_I2CRead(dev, buffer,2); + if( !rc ){ + /* VL6180x register are Big endian if cpu is be direct read direct into *data is possible */ + *data=((uint16_t)buffer[0]<<8)|(uint16_t)buffer[1]; + } + } + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_RdDWord(VL6180xDev_t dev, uint16_t index, uint32_t *data){ + int rc; + uint8_t read_buffer[4] = { 0, 0, 0, 0 }; + VL6180x_I2C_USER_VAR + uint8_t *buffer; + DECL_I2C_BUFFER + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_read_seq( + &(vl6180_data_g->i2c_client), index, read_buffer, 4); + *data = (uint32_t)( (unsigned int)(read_buffer[0] <<24) + | (unsigned int)((read_buffer[1])<<16) + | (unsigned int)((read_buffer[2])<<8) + | (unsigned int)(read_buffer[3]) ); + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + buffer=VL6180x_GetI2cBuffer(dev,4); + + buffer[0]=index>>8; + buffer[1]=index&0xFF; + + rc=VL6180x_I2CWrite(dev, (uint8_t *) buffer, (uint8_t)2); + if( !rc ){ + rc=VL6180x_I2CRead(dev, buffer,4); + if( !rc ){ + /* VL6180x register are Big endian if cpu is be direct read direct into data is possible */ + *data=((uint32_t)buffer[0]<<24)|((uint32_t)buffer[1]<<16)|((uint32_t)buffer[2]<<8)|((uint32_t)buffer[3]); + } + } + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + +int VL6180x_RdBuffer(VL6180xDev_t dev, uint16_t index, uint8_t *data, uint8_t count){ + int rc; + VL6180x_I2C_USER_VAR + uint8_t *buffer; + DECL_I2C_BUFFER + + if (vl6180_data_g->act_device_type == MSM_CAMERA_PLATFORM_DEVICE){ + rc = vl6180_data_g->i2c_client.i2c_func_tbl->i2c_read_seq( + &(vl6180_data_g->i2c_client), index, data, count); + return rc; + }else{ + VL6180x_GetI2CAccess(dev); + buffer=VL6180x_GetI2cBuffer(dev,4); + + buffer[0]=index>>8; + buffer[1]=index&0xFF; + + rc=VL6180x_I2CWrite(dev, (uint8_t *) buffer, (uint8_t)2); + if( !rc ){ + rc=VL6180x_I2CRead(dev, data,count); + } + VL6180x_DoneI2CAcces(dev); + + return rc; + } +} + diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_port_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_port_i2c.c new file mode 100755 index 0000000000000..6086871321362 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/src/vl6180x_port_i2c.c @@ -0,0 +1,99 @@ +/* + * vl6180x_port_i2c.c + * + * Created on: Oct 22, 2014 + * Author: Teresa Tao + */ + +#include "vl6180x_i2c.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../stmvl6180.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cci.h" + +#define I2C_M_WR 0x00 +static struct i2c_client *pclient=NULL; + +void i2c_setclient(struct i2c_client *client) +{ + pclient = client; + +} +struct i2c_client* i2c_getclient() +{ + return pclient; +} + +/** int VL6180x_I2CWrite(VL6180xDev_t dev, void *buff, uint8_t len); + * @brief Write data buffer to VL6180x device via i2c + * @param dev The device to write to + * @param buff The data buffer + * @param len The length of the transaction in byte + * @return 0 on success + */ +int VL6180x_I2CWrite(VL6180xDev_t dev, uint8_t *buff, uint8_t len) +{ + struct i2c_msg msg[1]; + int err=0; + + msg[0].addr = pclient->addr; + msg[0].flags = I2C_M_WR; + msg[0].buf= buff; + msg[0].len=len; + + err = i2c_transfer(pclient->adapter,msg,1); //return the actual messages transfer + if(err != 1) + { + pr_err("%s: i2c_transfer err:%d, addr:0x%x, reg:0x%x\n", __func__, err, pclient->addr, + (buff[0]<<8|buff[1])); + return -1; + } + return 0; +} + + +/** int VL6180x_I2CRead(VL6180xDev_t dev, void *buff, uint8_t len); + * @brief Read data buffer from VL6180x device via i2c + * @param dev The device to read from + * @param buff The data buffer to fill + * @param len The length of the transaction in byte + * @return transaction status + */ +int VL6180x_I2CRead(VL6180xDev_t dev, uint8_t *buff, uint8_t len) +{ + struct i2c_msg msg[1]; + int err=0; + + msg[0].addr = pclient->addr; + msg[0].flags = I2C_M_RD|pclient->flags; + msg[0].buf= buff; + msg[0].len=len; + + err = i2c_transfer(pclient->adapter,&msg[0],1); //return the actual mesage transfer + if(err != 1) + { + pr_err("%s: Read i2c_transfer err:%d, addr:0x%x\n", __func__, err, pclient->addr); + return -1; + } + return 0; +} diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180.h b/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180.h new file mode 100755 index 0000000000000..9773dda701c14 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180.h @@ -0,0 +1,196 @@ +/* + * stmvl6180.h - Linux kernel modules for STM VL6180 FlightSense Time-of-Flight sensor + * + * Copyright (C) 2014 STMicroelectronics Imaging Division + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Defines + */ +#ifndef STMVL6180 +#define STMVL6180 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stmvl6180.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cci.h" +#include "msm_camera_i2c.h" + +#define STMVL6180_DRV_NAME "stmvl6180" + +#define DRIVER_VERSION "1.0" +#define I2C_M_WR 0x00 +//#define INT_POLLING_DELAY 20 +#define RESULT_REG_COUNT 56 + +//if don't want to have output from vl6180_dbgmsg, comment out #DEBUG macro +#define DEBUG +//#define vl6180_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args) +#define vl6180_dbgmsg(str, args...) printk("%s: " str, __func__, ##args) + +/** + * VL6180 register addresses + */ +//Device Registers +#define VL6180_MODEL_ID_REG 0x0000 +#define VL6180_MODEL_REV_MAJOR_REG 0x0001 +#define VL6180_MODEL_REV_MINOR_REG 0x0002 +#define VL6180_MODULE_REV_MAJOR_REG 0x0003 +#define VL6180_MODULE_REV_MINOR_REG 0x0004 + +#define VL6180_REVISION_ID_REG 0x0005 +#define VL6180_REVISION_ID_REG_BYTES 1 +#define VL6180_DATE_HI_REG 0x0006 +#define VL6180_DATE_HI_REG_BYTES 1 +#define VL6180_DATE_LO_REG 0x0007 +#define VL6180_DATE_LO_REG_BYTES 1 +#define VL6180_TIME_REG 0x0008 +#define VL6180_TIME_REG_BYTES 2 +#define VL6180_CODE_REG 0x000a +#define VL6180_CODE_REG_BYTES 1 +#define VL6180_FIRMWARE_REVISION_ID_REG 0x000b +#define VL6180_FIRMWARE_REVISION_ID_REG_BYTES 1 + +// Result Registers +#define VL6180_RESULT__RANGE_RAW_REG 0x0064 +#define VL6180_RESULT__RANGE_RAW_REG_BYTES 1 +#define VL6180_RESULT__RANGE_RETURN_RATE_REG 0x0066 +#define VL6180_RESULT__RANGE_RETURN_RATE_REG_BYTES 2 +#define VL6180_RESULT__RANGE_REFERENCE_RATE_REG 0x0068 +#define VL6180_RESULT__RANGE_REFERENCE_RATE_REG_BYTES 2 +#define VL6180_RESULT__RANGE_RETURN_VCSEL_COUNT_REG 0x006c +#define VL6180_RESULT__RANGE_RETURN_VCSEL_COUNT_REG_BYTES 4 +#define VL6180_RESULT__RANGE_REFERENCE_VCSEL_COUNT_REG 0x0070 +#define VL6180_RESULT__RANGE_REFERENCE_VCSEL_COUNT_REG_BYTES 4 +#define VL6180_RESULT__RANGE_RETURN_AMB_COUNT_REG 0x0074 +#define VL6180_RESULT__RANGE_RETURN_AMB_COUNT_REG_BYTES 4 +#define VL6180_RESULT__RANGE_REFERENCE_AMB_COUNT_REG 0x0078 +#define VL6180_RESULT__RANGE_REFERENCE_AMB_COUNT_REG_BYTES 4 +#define VL6180_RESULT__RANGE_RETURN_CONV_TIME_REG 0x007c +#define VL6180_RESULT__RANGE_RETURN_CONV_TIME_REG_BYTES 4 +#define VL6180_RESULT__RANGE_REFERENCE_CONV_TIME_REG 0x0080 +#define VL6180_RESULT__RANGE_REFERENCE_CONV_TIME_REG_BYTES 4 + +// Filter defines +#define FILTERNBOFSAMPLES 10 +#define FILTERSTDDEVSAMPLES 6 +#define MINFILTERSTDDEVSAMPLES 3 +#define MINFILTERVALIDSTDDEVSAMPLES 4 +#define FILTERINVALIDDISTANCE 65535 + +/* + * driver data structs + */ +struct stmvl6180_data { + struct i2c_client *client; + struct mutex update_lock; + struct delayed_work dwork; /* for PS work handler */ + struct input_dev *input_dev_ps; + + int irq; + unsigned int enable; + + /* control flag from HAL */ + unsigned int enable_ps_sensor; + + /* PS parameters */ + unsigned int ps_is_singleshot; + unsigned int ps_data; /* to store PS data */ + unsigned int enable_distance_filter; + + /* Range Data */ + VL6180x_RangeData_t rangeData; + + /* Range Result Register Data */ + VL6180x_RangeResultData_t rangeResult; + uint8_t ResultBuffer[RESULT_REG_COUNT]; + + /* delay time */ + uint8_t delay_ms; // work handler delay time in miniseconds + + struct mutex work_mutex; + unsigned int ps_count; + /* Debug */ + unsigned int enableDebug; + + unsigned int force_reset_cnt; + struct msm_sd_subdev msm_sd; + struct v4l2_subdev_ops *v4l2_subdev_ops; + +//old struct + struct msm_camera_i2c_client i2c_client; + enum msm_camera_device_type_t act_device_type; + enum cci_i2c_master_t cci_master; + struct platform_device *pdev; + + int subdev_id; + + unsigned int is_6180; +// unsigned int enable; + /* Range Data */ + + /* Register Data for tool */ + unsigned int register_addr; + unsigned int register_bytes; + + uint32_t MeasurementIndex; + // Distance Filter global variables + uint32_t Default_ZeroVal; + uint32_t Default_VAVGVal; + uint32_t NoDelay_ZeroVal; + uint32_t NoDelay_VAVGVal; + uint32_t Previous_VAVGDiff; + uint16_t LastTrueRange[FILTERNBOFSAMPLES]; + uint32_t LastReturnRates[FILTERNBOFSAMPLES]; + uint32_t PreviousRangeStdDev; + uint32_t PreviousStdDevLimit; + uint32_t PreviousReturnRateStdDev; + uint16_t StdFilteredReads; + uint32_t m_chipid; + uint16_t LastMeasurements[8]; + uint16_t AverageOnXSamples; + uint16_t CurrentIndex; + + /* Debug */ +// unsigned int enableDebug; + + int irq_gpio; + int ce_gpio; + struct regulator *vdd_regulator; + struct regulator *vdd_regulator_i2c; + int id; +}; + +#endif diff --git a/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180_module.c b/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180_module.c new file mode 100755 index 0000000000000..5af0f48377b1f --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/vl6180/stmvl6180_module.c @@ -0,0 +1,1833 @@ +/* + * stmvl6180.c - Linux kernel modules for STM VL6180 FlightSense Time-of-Flight sensor + * + * Copyright (C) 2014 STMicroelectronics Imaging Division. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//API includes +#include "vl6180x_api.h" +#include "vl6180x_def.h" +#include "vl6180x_platform.h" +#include "stmvl6180.h" +#include "linux/workqueue.h" + +#include + +//#define VL6180_DEBUG +#undef CDBG +#ifdef VL6180_DEBUG +#define CDBG(fmt, args...) pr_err(fmt, ##args) + +#else +#define CDBG(fmt, args...) do{}while(0) +#endif + +stmvl6180x_dev vl6180x_dev; +//#define USE_INT +#define IRQ_NUM 59 +#define VL6180_I2C_ADDRESS (0x52>>1) +static struct i2c_client *client; + +/* + * Global data + */ +//******************************** IOCTL definitions +#define VL6180_IOCTL_INIT _IO('p', 0x01) +#define VL6180_IOCTL_XTALKCALB _IO('p', 0x02) +#define VL6180_IOCTL_OFFCALB _IO('p', 0x03) +#define VL6180_IOCTL_STOP _IO('p', 0x05) +#define VL6180_IOCTL_SETXTALK _IOW('p', 0x06, unsigned int) +#define VL6180_IOCTL_SETOFFSET _IOW('p', 0x07, int8_t) +#define VL6180_IOCTL_GETDATA _IOR('p', 0x0a, unsigned long) +#define VL6180_IOCTL_GETDATAS _IOR('p', 0x0b, VL6180x_RangeData_t) +struct mutex vl6180_mutex; +#define MULTI_READ 1 +#define CALIBRATION_FILE 1 +#ifdef CALIBRATION_FILE +int8_t offset_calib=0; +int16_t xtalk_calib=0; +#endif +#ifdef MULTI_READ +static uint32_t get_unsigned_int_from_buffer(uint8_t *pdata, int8_t count); +static uint16_t get_unsigned_short_from_buffer(uint8_t *pdata, int8_t count); +static int stmvl6180_ps_read_result(struct i2c_client *client); +static void stmvl6180_ps_parse_result(struct i2c_client *client); +#endif +extern void i2c_setclient(struct i2c_client *client); +extern struct i2c_client* i2c_getclient(void); +int stmvl6180_power_enable(struct stmvl6180_data *vl6180_data, unsigned int enable); +static int stmvl6180_init_client(struct stmvl6180_data *vl6180_data); + +struct stmvl6180_data *vl6180_data_g; + +static int stmvl6180_set_enable(struct i2c_client *client, unsigned int enable) +{ + return 0; +} +#ifdef CALIBRATION_FILE + +static void stmvl6180_read_calibration_file(void) +{ +#if 1 + uint32 offset = 0; + uint32 cross_talk = 0; + + if(get_param_camera_laser_sensor_offset(&offset) < 0){ + pr_err("%s:%d get_param_camera_laser_sensor_offset failed\n", __func__, __LINE__); + return; + } + if(get_param_camera_laser_sensor_cross_talk(&cross_talk) < 0){ + pr_err("%s:%d get_param_camera_laser_sensor_cross_talk failed\n", __func__, __LINE__); + return; + } + + if(offset >= 128) + offset_calib = offset - 256; + else + offset_calib = offset; + + xtalk_calib = cross_talk; + + CDBG("%s:%d, offset_calib as %d\n", __func__, __LINE__, offset_calib); + VL6180x_SetUserOffsetCalibration(vl6180x_dev, offset_calib); + + CDBG("%s:%d xtalk_calib as %d\n", __func__, __LINE__, xtalk_calib); + VL6180x_SetUserXTalkCompensationRate(vl6180x_dev, xtalk_calib); + +#else + + struct file *f; + char buf[8]; + mm_segment_t fs; + int i,is_sign=0; +#ifdef CALIBRATION_FILE + int8_t offset_calib_t=0; + int16_t xtalk_calib_t=0; +#endif + + f = filp_open("/persist/camera/LaserFocusOffset.txt", O_RDONLY, 0); + if (f!= NULL && !IS_ERR(f) && f->f_dentry!=NULL) + { + fs = get_fs(); + set_fs(get_ds()); + //init the buffer with 0 + for (i=0;i<8;i++) + buf[i]=0; + f->f_op->read(f, buf, 8, &f->f_pos); + set_fs(fs); + CDBG("offset:%d, offset as:%s, buf[0]:%c\n", offset_calib_t, buf, buf[0]); + for (i=0;i<8;i++) + { + if (i==0 && buf[0]=='-') + is_sign=1; + else if (buf[i]>='0' && buf[i]<='9') + offset_calib_t = offset_calib_t*10 + (buf[i]-'0'); + else + break; + } + CDBG("is_sign:%d, offset_calib:%d\n", is_sign, offset_calib_t); + + if (is_sign) + offset_calib_t = -offset_calib_t; + offset_calib = offset_calib_t; + + CDBG("offset_calib as %d\n", offset_calib); + VL6180x_SetUserOffsetCalibration(vl6180x_dev, offset_calib); + filp_close(f, NULL); + } + else + pr_err("no offset calibration file exist!\n"); + + is_sign=0; + f = filp_open("/persist/camera/LaserFocusCrossTalk.txt", O_RDONLY, 0); + if (f!= NULL && !IS_ERR(f) && f->f_dentry!=NULL) + { + fs = get_fs(); + set_fs(get_ds()); + //init the buffer with 0 + for (i=0;i<8;i++) + buf[i]=0; + f->f_op->read(f, buf, 8, &f->f_pos); + set_fs(fs); + CDBG("xtalk_calib:%d, xtalk as:%s, buf[0]:%c\n", xtalk_calib_t, buf, buf[0]); + for (i=0;i<8;i++) + { + if (i==0 && buf[0]=='-') + is_sign=1; + else if (buf[i]>='0' && buf[i]<='9') + xtalk_calib_t = xtalk_calib_t*10 + (buf[i]-'0'); + else + break; + } + if (is_sign==1) + xtalk_calib_t = -xtalk_calib_t; + xtalk_calib = xtalk_calib_t; + CDBG("xtalk_calib as %d\n", xtalk_calib); + VL6180x_SetUserXTalkCompensationRate(vl6180x_dev, xtalk_calib); + filp_close(f, NULL); + } + else + pr_err("no xtalk calibration file exist!\n"); + + return; +#endif +} +static void stmvl6180_write_offset_calibration_file(void) +{ +#if 1 + uint offset = 0; + if(offset_calib > 127 || offset_calib < -128){ + pr_err("%s:%d wrong offset value\n", __func__, __LINE__); + return; + } +//offset_calib is int8_t type, but the data is saved as unsigned int, so need to convert + if(offset_calib < 0) + offset = (uint)(256+offset_calib); + else + offset = offset_calib; + if(set_param_camera_laser_sensor_offset(&offset) < 0) + pr_err("%s:%d set_param_camera_laser_sensor_offset failed\n", __func__, __LINE__); + + return; + +#else + struct file *f; + char buf[8]={0}; + mm_segment_t fs; + + f = filp_open("/persist/camera/LaserFocusOffset.txt", O_WRONLY|O_CREAT, 0644); + if (f!= NULL) + { + fs = get_fs(); + set_fs(get_ds()); + sprintf(buf,"%d",offset_calib); + CDBG("write offset as:%s, buf[0]:%c\n",buf, buf[0]); + f->f_op->write(f, buf, 8, &f->f_pos); + set_fs(fs); + VL6180x_SetUserOffsetCalibration(vl6180x_dev, offset_calib); + }else + pr_err("%s:%d open /persist/camera/LaserFocusOffset.txt failed\n", __func__, __LINE__); + + if(f) + filp_close(f, NULL); + + return; +#endif + +} +static void stmvl6180_write_xtalk_calibration_file(void) +{ +#if 1 + uint cross_talk = 0; +//cross talk is always positive + if(xtalk_calib < 0){ + pr_err("%s:%d xtalk_calib = %d, convert it to positive\n", __func__, __LINE__, xtalk_calib); + cross_talk = (uint)(-xtalk_calib); + }else + cross_talk = (uint)(xtalk_calib); + if(set_param_camera_laser_sensor_cross_talk(&cross_talk) < 0) + pr_err("%s:%d set_param_camera_laser_sensor_cross_talk failed\n", __func__, __LINE__); + + return; +#else + + struct file *f; + char buf[8]={0}; + mm_segment_t fs; + + f = filp_open("/persist/camera/LaserFocusCrossTalk.txt", O_WRONLY|O_CREAT, 0644); + if (f!= NULL) + { + fs = get_fs(); + set_fs(get_ds()); + sprintf(buf,"%d",xtalk_calib); + CDBG("write xtalk as:%s, buf[0]:%c\n",buf, buf[0]); + f->f_op->write(f, buf, 8, &f->f_pos); + set_fs(fs); + VL6180x_SetUserXTalkCompensationRate(vl6180x_dev, xtalk_calib); + }else + pr_err("%s:%d open /persist/camera/LaserFocusCrossTalk.txt failed\n", __func__, __LINE__); + + if(f) + filp_close(f, NULL); + + return; +#endif +} + +#endif +#ifdef MULTI_READ +static uint32_t get_unsigned_int_from_buffer(uint8_t *pdata, int8_t count) +{ + uint32_t value=0; + while (count-- > 0) + { + value = (value << 8) | (uint32_t)*pdata++; + } + return value; +} +static uint16_t get_unsigned_short_from_buffer(uint8_t *pdata, int8_t count) +{ + uint16_t value=0; + while (count-- > 0) + { + value = (value << 8) | (uint16_t)*pdata++; + } + return value; +} +static int stmvl6180_ps_read_result(struct i2c_client *client) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + int status=0; + + status = VL6180x_RdBuffer(vl6180x_dev, RESULT_RANGE_STATUS , vl6180_data->ResultBuffer,RESULT_REG_COUNT); + if (status) { + VL6180x_ErrLog("RESULT_RANGE_STATUS rd fail status is:%d\n",status); + return status; + } + status = VL6180x_RdByte(vl6180x_dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, &(vl6180_data->rangeData.m_rangeOffset)); + if (status) { + VL6180x_ErrLog("SYSRANGE_PART_TO_PART_RANGE_OFFSET rd failstatus is:%d\n",status); + return status; + } + status = VL6180x_RdWord(vl6180x_dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, &(vl6180_data->rangeData.m_crossTalk)); + if (status) { + VL6180x_ErrLog("SYSRANGE_CROSSTALK_COMPENSATION_RATE rd failstatus is:%d\n",status); + return status; + } + + return status; +} +static void stmvl6180_ps_parse_result(struct i2c_client *client) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + //RESULT_RANGE_STATUS:0x004D + vl6180_data->rangeResult.Result_range_status = vl6180_data->ResultBuffer[0]; + //RESULT_INTERRUPT_STATUS:0x004F + vl6180_data->rangeResult.Result_interrupt_status = vl6180_data->ResultBuffer[1]; + //RESULT_RANGE_VAL:0x0062 + vl6180_data->rangeResult.Result_range_val = vl6180_data->ResultBuffer[(0x62-0x4d)]; + //RESULT_RANGE_RAW:0x0064 + vl6180_data->rangeResult.Result_range_raw = vl6180_data->ResultBuffer[(0x64-0x4d)]; + //RESULT_RANGE_RETURN_RATE:0x0066 + vl6180_data->rangeResult.Result_range_return_rate = get_unsigned_short_from_buffer(vl6180_data->ResultBuffer+(0x66-0x4d),2); + //RESULT_RANGE_REFERENCE_RATE:0x0068 + vl6180_data->rangeResult.Result_range_reference_rate = get_unsigned_short_from_buffer(vl6180_data->ResultBuffer+(0x68-0x4d),2); + //RESULT_RANGE_RETURN_SIGNAL_COUNT:0x006c + vl6180_data->rangeResult.Result_range_return_signal_count = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x6c-0x4d),4); + //RESULT_RANGE_REFERENCE_SIGNAL_COUNT:0x0070 + vl6180_data->rangeResult.Result_range_reference_signal_count = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x70-0x4d),4); + //RESULT_RANGE_RETURN_AMB_COUNT:0x0074 + vl6180_data->rangeResult.Result_range_return_amb_count = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x74-0x4d),4); + //RESULT_RANGE_REFERENCE_AMB_COUNT:0x0078 + vl6180_data->rangeResult.Result_range_reference_amb_count = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x78-0x4d),4); + //RESULT_RANGE_RETURN_CONV_TIME:0x007c + vl6180_data->rangeResult.Result_range_return_conv_time = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x7c-0x4d),4); + //RESULT_RANGE_REFERENCE_CONV_TIME:0x0080 + vl6180_data->rangeResult.Result_range_reference_conv_time = get_unsigned_int_from_buffer(vl6180_data->ResultBuffer+(0x80-0x4d),4); + + +// data->rangeData.m_refRate = data->rangeResult.Result_range_reference_rate; +// data->rangeData.m_refRate = data->rangeResult.Result_range_reference_rate; + vl6180_data->rangeData.m_rtnSignalCount = vl6180_data->rangeResult.Result_range_return_signal_count; + vl6180_data->rangeData.m_refSignalCount = vl6180_data->rangeResult.Result_range_reference_signal_count; + vl6180_data->rangeData.m_rtnAmbientCount = vl6180_data->rangeResult.Result_range_return_amb_count; + vl6180_data->rangeData.m_refAmbientCount = vl6180_data->rangeResult.Result_range_reference_amb_count; + vl6180_data->rangeData.m_rawRange_mm = vl6180_data->rangeResult.Result_range_raw; + + if(vl6180_data->rangeResult.Result_range_return_conv_time < vl6180_data->rangeResult.Result_range_reference_conv_time) + vl6180_data->rangeData.m_convTime = vl6180_data->rangeResult.Result_range_reference_conv_time; + else + vl6180_data->rangeData.m_convTime = vl6180_data->rangeResult.Result_range_return_conv_time; + + return; +} +#endif +static void stmvl6180_ps_read_measurement(struct i2c_client *client) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + struct timeval tv; + +#ifdef MULTI_READ + VL6180x_RangeGetMeasurement_ext(vl6180x_dev, &(vl6180_data->rangeResult), &(vl6180_data->rangeData)); +#else + VL6180x_RangeGetMeasurement(vl6180x_dev, &(vl6180_data->rangeData)); +#endif + do_gettimeofday(&tv); + + vl6180_data->ps_data = vl6180_data->rangeData.range_mm; + + input_report_abs(vl6180_data->input_dev_ps, ABS_DISTANCE, (int)(vl6180_data->ps_data+5)/10); //range in cm +// input_report_abs(data->input_dev_ps, ABS_HAT0X, data->rangeData.rtnConvTime/1000000); //tv_sec +// input_report_abs(data->input_dev_ps, ABS_HAT0Y, data->rangeData.rtnConvTime); //tv_usec + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT0X,tv.tv_sec); + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT0Y,tv.tv_usec); + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT1X,vl6180_data->rangeData.range_mm); + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT1Y,vl6180_data->rangeData.errorStatus); +#ifdef VL6180x_HAVE_RATE_DATA + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT2X,vl6180_data->rangeData.signalRate_mcps); + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT2Y,vl6180_data->rangeData.rtnAmbRate); + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT3X,vl6180_data->rangeData.rtnConvTime); +#endif +#if VL6180x_HAVE_DMAX_RANGING + input_report_abs(vl6180_data->input_dev_ps, ABS_HAT3Y,vl6180_data->rangeData.DMax); +#endif + + input_sync(vl6180_data->input_dev_ps); + if (vl6180_data->enableDebug) + CDBG("range:%d, signalrate_mcps:%d, error:0x%x,rtnsgnrate:%u, rtnambrate:%u,rtnconvtime:%u\n", + vl6180_data->rangeData.range_mm, + vl6180_data->rangeData.signalRate_mcps, + vl6180_data->rangeData.errorStatus, + vl6180_data->rangeData.rtnRate, + vl6180_data->rangeData.rtnAmbRate, + vl6180_data->rangeData.rtnConvTime); + +} +/* interrupt work handler */ +static void stmvl6180_work_handler(struct work_struct *work) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + struct i2c_client *client=vl6180_data->client; + int ret=0; +#ifndef MULTI_READ + uint8_t gpio_status=0, range_start=0, range_status=0; +#endif + uint8_t to_startPS=0; + + mutex_lock(&vl6180_data->work_mutex); + +//likelong added + if( !vl6180_data->enable_ps_sensor){ + mutex_unlock(&vl6180_data->work_mutex); + return; + } + +#ifdef MULTI_READ + ret = stmvl6180_ps_read_result(client); + if (ret == 0 && ((vl6180_data->ResultBuffer[0]&0x01) == 0x01)){ + if( vl6180_data->enable_ps_sensor){ + stmvl6180_ps_parse_result(client); + stmvl6180_ps_read_measurement(client); + if (vl6180_data->ps_is_singleshot) + to_startPS = 1; + } + } +#else + VL6180x_RangeGetInterruptStatus(vl6180x_dev, &gpio_status); + VL6180x_RdByte(vl6180x_dev, RESULT_RANGE_STATUS, &range_status); + VL6180x_RdByte(vl6180x_dev, SYSRANGE_START, &range_start); + + //if (gpio_status == RES_INT_STAT_GPIO_NEW_SAMPLE_READY) + if (((range_status&0x01)==0x01) && (range_start== 0x00)){ + if( vl6180_data->enable_ps_sensor){ + CDBG("stmvl6180_ps_read_measurement"); + stmvl6180_ps_read_measurement(client); + if (vl6180_data->ps_is_singleshot) + to_startPS = 1; + } + VL6180x_RangeClearInterrupt(vl6180x_dev); + + } +#endif + if (to_startPS){ + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP | MODE_SINGLESHOT); + } + + schedule_delayed_work(&vl6180_data->dwork, msecs_to_jiffies((vl6180_data->delay_ms))); // restart timer + + mutex_unlock(&vl6180_data->work_mutex); + + return; +} + +#ifdef USE_INT +static irqreturn_t stmvl6180_interrupt_handler(int vec, void *info) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + if (vl6180_data->irq == vec){ + CDBG("==>interrupt_handler\n"); + schedule_delayed_work(&vl6180_data->dwork, 0); + } + return IRQ_HANDLED; +} +#endif + +/* + * SysFS support + */ +static ssize_t stmvl6180_show_enable_ps_sensor(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + return sprintf(buf, "%d\n", vl6180_data->enable_ps_sensor); +} + +static ssize_t stmvl6180_store_enable_ps_sensor(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long flags; + int rc = 0; + + CDBG("enable %ld\n", val); + if ((val != 0) && (val != 1)) { + pr_err("%s:%d store unvalid value=%ld\n", __func__, __LINE__, val); + return count; + } + mutex_lock(&vl6180_data->work_mutex); + + if(val == 1){ + //turn on p sensor + if (vl6180_data->enable_ps_sensor==0) { + stmvl6180_set_enable(client,0); /* Power Off */ + rc = stmvl6180_power_enable(vl6180_data, 1); + if(rc){ + mutex_unlock(&vl6180_data->work_mutex); + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + return rc; + } +// mutex_lock(&vl6180_data->work_mutex); + + //re-init + VL6180x_Prepare(vl6180x_dev); + VL6180x_UpscaleSetScaling(vl6180x_dev, 3); + + //set parameters + //VL6180x_RangeSetInterMeasPeriod(vl6180x_dev, 10); //10ms + //set interrupt mode + //VL6180x_RangeSetupGPIO1(vl6180x_dev, GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT, INTR_POL_HIGH); + VL6180x_RangeConfigInterrupt(vl6180x_dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY); + + //start + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP|MODE_SINGLESHOT); + vl6180_data->ps_is_singleshot = 1; + vl6180_data->enable_ps_sensor= 1; + + /* we need this polling timer routine for house keeping*/ + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + cancel_delayed_work(&vl6180_data->dwork); + //schedule_delayed_work(&data->dwork, msecs_to_jiffies(INT_POLLING_DELAY)); + schedule_delayed_work(&vl6180_data->dwork, msecs_to_jiffies(vl6180_data->delay_ms)); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + + stmvl6180_set_enable(client, 1); /* Power On */ +// mutex_unlock(&vl6180_data->work_mutex); + } + } + else { + if (vl6180_data->enable_ps_sensor==1) { //#tt999 + //turn off p sensor +// mutex_lock(&vl6180_data->work_mutex); + vl6180_data->enable_ps_sensor = 0; + if (vl6180_data->ps_is_singleshot == 0) + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP); + VL6180x_RangeClearInterrupt(vl6180x_dev); + + stmvl6180_set_enable(client, 0); + + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + cancel_delayed_work(&vl6180_data->dwork); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); +// mutex_unlock(&vl6180_data->work_mutex); +// kelong need to check + rc = stmvl6180_power_enable(vl6180_data_g, 0); + if(rc) { + pr_err("failed rc %d\n", rc); +// return rc; + } + } + } + mutex_unlock(&vl6180_data->work_mutex); + + return count; +} + +static DEVICE_ATTR(enable_ps_sensor, S_IWUGO | S_IRUGO, + stmvl6180_show_enable_ps_sensor, stmvl6180_store_enable_ps_sensor); + +static ssize_t stmvl6180_show_enable_debug(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + return sprintf(buf, "%d\n", vl6180_data->enableDebug); +} + +//for als integration time setup +static ssize_t stmvl6180_store_enable_debug(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + long on = simple_strtol(buf, NULL, 10); + if ((on !=0) && (on !=1)){ + pr_err("%s: set debug=%ld\n", __func__, on); + return count; + } + vl6180_data->enableDebug=on; + + return count; +} + +//DEVICE_ATTR(name,mode,show,store) +static DEVICE_ATTR(enable_debug, S_IWUSR | S_IRUGO, + stmvl6180_show_enable_debug, stmvl6180_store_enable_debug); + + +static ssize_t stmvl6180_show_set_delay_ms(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + return sprintf(buf, "%d\n", vl6180_data->delay_ms); +} + +//for als integration time setup +static ssize_t stmvl6180_store_set_delay_ms(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + long delay_ms = simple_strtol(buf, NULL, 10); + + CDBG("stmvl6180_store_set_delay_ms as %ld\n",delay_ms); + if (delay_ms == 0){ + pr_err("%s: set delay_ms=%ld\n", __func__, delay_ms); + return count; + } + mutex_lock(&vl6180_data->work_mutex); + vl6180_data->delay_ms=delay_ms; + mutex_unlock(&vl6180_data->work_mutex); + return count; +} + +static DEVICE_ATTR(set_delay_ms, S_IWUSR | S_IRUGO, + stmvl6180_show_set_delay_ms, stmvl6180_store_set_delay_ms); + +static struct attribute *stmvl6180_attributes[] = { + &dev_attr_enable_ps_sensor.attr, + &dev_attr_enable_debug.attr, + &dev_attr_set_delay_ms.attr , + NULL +}; + +static const struct attribute_group stmvl6180_attr_group = { + .attrs = stmvl6180_attributes, +}; + +/* + * misc device file operation functions + */ +static int stmvl6180_ioctl_handler(struct file *file, + unsigned int cmd, unsigned long arg, void __user *p) +{ + int rc=0; + unsigned long flags; + unsigned long distance=0; + struct i2c_client *client; + + switch (cmd) { + case VL6180_IOCTL_INIT: /* init. */ + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + client = i2c_getclient(); + + CDBG("ioclt INIT\n"); + //turn on p sensor only if it's not enabled by other client + if (vl6180_data->enable_ps_sensor==0) { + stmvl6180_set_enable(client,0); /* Power Off */ + + //re-init + VL6180x_Prepare(vl6180x_dev); + VL6180x_UpscaleSetScaling(vl6180x_dev, 3); +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + VL6180x_FilterSetState(vl6180x_dev, 1); // turn on wrap around filter +#endif + //set parameters + //VL6180x_RangeSetInterMeasPeriod(vl6180x_dev, 10); //10ms + //set interrupt mode + //VL6180x_RangeSetupGPIO1(vl6180x_dev, GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT, INTR_POL_HIGH); + + VL6180x_RangeConfigInterrupt(vl6180x_dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY); + VL6180x_RangeClearInterrupt(vl6180x_dev); + + //start + //range_set_systemMode(client->addr, RANGE_START_SINGLESHOT); + //data->ps_is_singleshot = 1; + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP|MODE_SINGLESHOT); + vl6180_data->ps_is_singleshot = 1; + vl6180_data->enable_ps_sensor= 1; + + /* we need this polling timer routine for house keeping*/ + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + + cancel_delayed_work(&vl6180_data->dwork); + //schedule_delayed_work(&data->dwork, msecs_to_jiffies(INT_POLLING_DELAY)); + + schedule_delayed_work(&vl6180_data->dwork, msecs_to_jiffies(vl6180_data->delay_ms)); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + + stmvl6180_set_enable(client, 1); /* Power On */ + } + + return 0; + } + case VL6180_IOCTL_XTALKCALB: /*crosstalk calibration*/ + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + client = i2c_getclient(); + CDBG("ioclt VL6180_IOCTL_XTALKCALB\n"); + + //turn on p sensor only if it's not enabled by other client + if (vl6180_data->enable_ps_sensor==0) { + stmvl6180_set_enable(client,0); /* Power Off */ + //re-init + VL6180x_Prepare(vl6180x_dev); + VL6180x_UpscaleSetScaling(vl6180x_dev, 3); +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + VL6180x_FilterSetState(vl6180x_dev, 1); // turn off wrap around filter +#endif + VL6180x_RangeConfigInterrupt(vl6180x_dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY); + VL6180x_RangeClearInterrupt(vl6180x_dev); + VL6180x_WrWord(vl6180x_dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, 0); + + //start + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP|MODE_SINGLESHOT); + vl6180_data->ps_is_singleshot = 1; + vl6180_data->enable_ps_sensor= 1; + + /* we need this polling timer routine for house keeping*/ + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + + cancel_delayed_work(&vl6180_data->dwork); + //schedule_delayed_work(&data->dwork, msecs_to_jiffies(INT_POLLING_DELAY)); + + schedule_delayed_work(&vl6180_data->dwork, msecs_to_jiffies(vl6180_data->delay_ms)); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + + stmvl6180_set_enable(client, 1); /* Power On */ + } + + return 0; + } + case VL6180_IOCTL_SETXTALK: + { + unsigned int xtalkint=0; + CDBG("ioctl SETXTALK as 0x%x\n", xtalkint); + + if (copy_from_user(&xtalkint, (unsigned int *)p, sizeof(unsigned int))) { + rc = -EFAULT; + } + +#ifdef CALIBRATION_FILE + xtalk_calib = xtalkint; + stmvl6180_write_xtalk_calibration_file(); +#endif + VL6180x_SetXTalkCompensationRate(vl6180x_dev, xtalkint); + + return 0; + } + case VL6180_IOCTL_OFFCALB: /*offset calibration*/ + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + client = i2c_getclient(); + + CDBG("ioclt OFFCALB to enable PS sensor for offset calibration\n"); + + //turn on p sensor only if it's not enabled by other client + if (vl6180_data->enable_ps_sensor==0) { + stmvl6180_set_enable(client,0); /* Power Off */ + //re-init + VL6180x_Prepare(vl6180x_dev); + VL6180x_UpscaleSetScaling(vl6180x_dev, 1); +#if VL6180x_WRAP_AROUND_FILTER_SUPPORT + VL6180x_FilterSetState(vl6180x_dev, 0); // turn off wrap around filter +#endif + VL6180x_RangeConfigInterrupt(vl6180x_dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY); + VL6180x_RangeClearInterrupt(vl6180x_dev); + VL6180x_WrWord(vl6180x_dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, 0); + VL6180x_WrWord(vl6180x_dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, 0); + + //start + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP|MODE_SINGLESHOT); + vl6180_data->ps_is_singleshot = 1; + vl6180_data->enable_ps_sensor= 1; + + /* we need this polling timer routine for house keeping*/ + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + + cancel_delayed_work(&vl6180_data->dwork); + //schedule_delayed_work(&data->dwork, msecs_to_jiffies(INT_POLLING_DELAY)); + + schedule_delayed_work(&vl6180_data->dwork, msecs_to_jiffies(vl6180_data->delay_ms)); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + + stmvl6180_set_enable(client, 1); /* Power On */ + } + + return 0; + } + case VL6180_IOCTL_SETOFFSET: + { + int8_t offsetint=0; + CDBG("ioctl SETOFFSET as %d\n", offsetint); + + if (copy_from_user(&offsetint, (int8_t *)p, sizeof(int8_t))) { + rc = -EFAULT; + } + +#ifdef CALIBRATION_FILE + offset_calib = offsetint; + stmvl6180_write_offset_calibration_file(); +#endif + VL6180x_SetOffset(vl6180x_dev,offsetint); + + return 0; + } + case VL6180_IOCTL_STOP: + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + client = i2c_getclient(); + CDBG("ioclt VL6180_IOCTL_STOP\n"); + + //turn off p sensor only if it's enabled by other client + if (vl6180_data->enable_ps_sensor==1) { + //turn off p sensor + vl6180_data->enable_ps_sensor = 0; + if (vl6180_data->ps_is_singleshot == 0) + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP); + VL6180x_RangeClearInterrupt(vl6180x_dev); + + stmvl6180_set_enable(client, 0); + + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + /* + * If work is already scheduled then subsequent schedules will not + * change the scheduled time that's why we have to cancel it first. + */ + + cancel_delayed_work(&vl6180_data->dwork); + + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + } + + return 0; + } + case VL6180_IOCTL_GETDATA: /* Get proximity value only */ + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + CDBG("vl6180_getDistance return %ld\n",distance); + + mutex_lock(&vl6180_data->work_mutex); + distance = vl6180_data->rangeData.FilteredData.range_mm; + mutex_unlock(&vl6180_data->work_mutex); + rc = put_user(distance, (unsigned long *)p); + + return rc; + } + case VL6180_IOCTL_GETDATAS: /* Get all range data */ + { + struct stmvl6180_data *vl6180_data = vl6180_data_g; + CDBG("IOCTL_GETDATAS, m_range_mm:%d\n", vl6180_data->rangeData.range_mm); + + mutex_lock(&vl6180_data->work_mutex); + rc = copy_to_user((VL6180x_RangeData_t *)p, &(vl6180_data->rangeData), sizeof(VL6180x_RangeData_t)); + mutex_unlock(&vl6180_data->work_mutex); + return rc; + } + default: + return -EINVAL; + } + + return rc; +} + +static int stmvl6180_open(struct inode *inode, struct file *file) +{ + int rc = 0; + if(vl6180_data_g&&(!vl6180_data_g->enable)){ + rc = stmvl6180_power_enable(vl6180_data_g, 1); + if(rc){ + pr_err("%s:%d %d vl6180 power up failed\n", __func__, __LINE__, rc); + } + + return rc; + }else if(vl6180_data_g->enable){ + pr_err("%s:%d vl6180 was already opened, return false\n", __func__, __LINE__); + return -1; + } + + return -1; +} + +static int stmvl6180_flush(struct file *file, fl_owner_t id) +{ + unsigned long flags; + struct i2c_client *client; + struct stmvl6180_data *vl6180_data = vl6180_data_g; + client = i2c_getclient(); + + if (vl6180_data->enable_ps_sensor==1){ +//turn off p sensor if it's enabled + vl6180_data->enable_ps_sensor = 0; + VL6180x_RangeClearInterrupt(vl6180x_dev); + + stmvl6180_set_enable(client, 0); + + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); +/* +* If work is already scheduled then subsequent schedules will not +* change the scheduled time that's why we have to cancel it first. +*/ + cancel_delayed_work(&vl6180_data->dwork); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + } + + return 0; +} +static long stmvl6180_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + mutex_lock(&vl6180_mutex); + ret = stmvl6180_ioctl_handler(file, cmd, arg, (void __user *)arg); + mutex_unlock(&vl6180_mutex); + return ret; +} + +static int stmvl6180_release(struct inode *inode, struct file *file) +{ + int rc = 0; + + if(vl6180_data_g){ + rc = stmvl6180_power_enable(vl6180_data_g, 0); + if(rc<0) + pr_err("%s:%d stmvl6180 power down failed %d\n", __func__, __LINE__, rc); + } + + return 0; +} + +static const struct file_operations stmvl6180_ranging_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = stmvl6180_ioctl, + .open = stmvl6180_open, + .flush = stmvl6180_flush, + .release = stmvl6180_release, +}; + +static struct miscdevice stmvl6180_ranging_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "stmvl6180_ranging", + .fops = &stmvl6180_ranging_fops +}; + +//cci driver related code +static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = { + .i2c_read = msm_camera_cci_i2c_read, + .i2c_read_seq = msm_camera_cci_i2c_read_seq, + .i2c_write = msm_camera_cci_i2c_write, + .i2c_write_seq = msm_camera_cci_i2c_write_seq, + .i2c_write_table = msm_camera_cci_i2c_write_table, + .i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table, + .i2c_write_table_w_microdelay = msm_camera_cci_i2c_write_table_w_microdelay, + .i2c_util = msm_sensor_cci_i2c_util, + .i2c_poll = msm_camera_cci_i2c_poll, +}; +#ifdef VENDOR_EDIT +static long msm_stmvl6180_subdev_ioctl(struct v4l2_subdev *sd, + unsigned int cmd, void *arg) +{ + unsigned long flags; + struct i2c_client *client; + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + CDBG("%s:%d Enter\n", __func__, __LINE__); +// CDBG("%s:%d o_ctrl %p argp %p\n", __func__, __LINE__, o_ctrl, argp); + switch (cmd) { + case MSM_SD_SHUTDOWN: + client = i2c_getclient(); + CDBG("ioclt VL6180_IOCTL_STOP\n"); + mutex_lock(&vl6180_data->work_mutex); + + //turn off p sensor only if it's enabled by other client + if (vl6180_data->enable_ps_sensor==1) { + //turn off p sensor + vl6180_data->enable_ps_sensor = 0; + if (vl6180_data->ps_is_singleshot == 0) + VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP); + VL6180x_RangeClearInterrupt(vl6180x_dev); + + stmvl6180_set_enable(client, 0); + + spin_lock_irqsave(&vl6180_data->update_lock.wait_lock, flags); + cancel_delayed_work(&vl6180_data->dwork); + spin_unlock_irqrestore(&vl6180_data->update_lock.wait_lock, flags); + } + mutex_unlock(&vl6180_data->work_mutex); + default: + return -ENOIOCTLCMD; + } +} +static int32_t msm_stmvl6180_power(struct v4l2_subdev *sd, int on) +{ + int rc = 0; + if(vl6180_data_g){ + rc = stmvl6180_power_enable(vl6180_data_g, on); + if(rc<0) + pr_err("%s:%d stmvl6180 power down failed %d\n", __func__, __LINE__, rc); + } + return rc; +} +static struct v4l2_subdev_core_ops msm_stmvl6180_subdev_core_ops = { + .ioctl = msm_stmvl6180_subdev_ioctl, + .s_power = msm_stmvl6180_power, +}; +static struct v4l2_subdev_ops msm_stmvl6180_subdev_ops = { + .core = &msm_stmvl6180_subdev_core_ops, +}; +#endif +/* + * Initialization function + */ +static int stmvl6180_init_client(struct stmvl6180_data *vl6180_data) +{ + uint8_t id=0,module_major=0,module_minor=0; + uint8_t model_major=0,model_minor=0; + uint8_t i=0,val; + + while(vl6180_data->force_reset_cnt++ < 3){ + // Read Model ID + VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_ID_REG, &id); + CDBG("read MODLE_ID: 0x%x, i2cAddr:0x%x\n", id, vl6180_data->i2c_client.cci_client->sid); + if (id == 0xb4) { + pr_err("STM VL6180 Found\n"); + break; + } + else{ + if((vl6180_data->act_device_type == MSM_CAMERA_I2C_DEVICE) && (vl6180_data->force_reset_cnt < 3)){// CCI device didn't need this, as the retries paramter of cci is 3. + pr_err("Not found STM VL6180, will reset and try again\n"); + stmvl6180_power_enable(vl6180_data, 0); + msleep(10); + stmvl6180_power_enable(vl6180_data, 1); + } + else if(vl6180_data->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) + break; + } + } + if (id != 0xb4){ + pr_err("Not found STM VL6180\n"); + return -EIO; + } + + // Read Model Version + VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_REV_MAJOR_REG, &model_major); + model_major &= 0x07; + VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_REV_MINOR_REG, &model_minor); + model_minor &= 0x07; + CDBG("STM VL6180 Model Version : %d.%d\n", model_major,model_minor); + + // Read Module Version + VL6180x_RdByte(vl6180x_dev, VL6180_MODULE_REV_MAJOR_REG, &module_major); + VL6180x_RdByte(vl6180x_dev, VL6180_MODULE_REV_MINOR_REG, &module_minor); + CDBG("STM VL6180 Module Version : %d.%d\n", module_major,module_minor); + + // Read Identification + printk("STM VL6180 Serial Numbe: "); + for (i=0; i<=(VL6180_FIRMWARE_REVISION_ID_REG-VL6180_REVISION_ID_REG);i++) + { + VL6180x_RdByte(vl6180x_dev, (VL6180_REVISION_ID_REG+i), &val); + printk("0x%x-",val); + } + printk("\n"); + + + vl6180_data->delay_ms=20; //init to 20ms + vl6180_data->ps_data=0; + vl6180_data->enableDebug=0; + vl6180_data->force_reset_cnt = 0; +#ifdef CALIBRATION_FILE + stmvl6180_read_calibration_file(); +#endif + + //VL6180 Initialization + VL6180x_WaitDeviceBooted(vl6180x_dev); + VL6180x_InitData(vl6180x_dev); + //VL6180x_FilterSetState(vl6180x_dev, 1); /* activate wrap around filter */ + //VL6180x_DisableGPIOxOut(vl6180x_dev, 1); /* diable gpio 1 output, not needed when polling */ + + return 0; +} + +int stmvl6180_power_enable(struct stmvl6180_data *vl6180_data, unsigned int enable) +{ + int rc = 0; + + CDBG("enable %d\n", enable); + + if(enable) { +#ifdef CALIBRATION_FILE + stmvl6180_read_calibration_file();// read calibration file while power up Laser sensor +#endif + + if(vl6180_data->enable == 0){ + rc = gpio_request(vl6180_data->ce_gpio, "vl_6180-ce"); + if (rc < 0){ + pr_err("%s:%d gpio request failed for vl6180 rc = %d\n", __func__, __LINE__, rc); + return rc; + } + rc = gpio_request(vl6180_data->irq_gpio,"vl_6180-int"); + if(rc < 0){ + pr_err("%s:%d gpio_request failed, rc=%d", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + return rc; + } + + if (regulator_count_voltages(vl6180_data->vdd_regulator) > 0){ + rc = regulator_set_voltage(vl6180_data->vdd_regulator, 2850000, 2850000); + if (rc) { + pr_err( "%s:%d vdd regulator set failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + return rc; + } + } + rc = regulator_enable(vl6180_data->vdd_regulator); + if (rc) { + pr_err("%s:%d stmvl6180 enable vdd_regulator failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + return rc; + } + + if (regulator_count_voltages(vl6180_data->vdd_regulator_i2c) > 0) { + rc = regulator_set_voltage(vl6180_data->vdd_regulator_i2c, 1800000, 1800000); + if (rc) { + pr_err( "%s:%d vdd_regulator_i2c set failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + } + rc = regulator_enable(vl6180_data->vdd_regulator_i2c); + if(rc){ + pr_err("%s:%d stmvl6180 power on i2c regulator failed rc=%d \n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + + //just cci device need this + if (vl6180_data->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) { + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_util(&vl6180_data->i2c_client, MSM_CCI_INIT); + if (rc < 0){ + pr_err("%s:%d cci_init failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator_i2c); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + } + msleep(5); +#if 0 + rc = gpio_direction_output(vl6180_data->ce_gpio,1); + if(rc){ + pr_err("%s:%d stmvl6180 gpip output failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator_i2c); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + msleep(1); + rc = gpio_direction_output(vl6180_data->ce_gpio,0); + if(rc){ + pr_err("%s:%d stmvl6180 gpip output failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator_i2c); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + msleep(1); +#endif + rc = gpio_direction_output(vl6180_data->ce_gpio,1); + if(rc){ + pr_err("%s:%d stmvl6180 gpip output failed rc=%d\n", __func__, __LINE__, rc); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + regulator_disable(vl6180_data->vdd_regulator_i2c); + regulator_disable(vl6180_data->vdd_regulator); + return rc; + } + msleep(1); + vl6180_data->enable = 1; + } + } else { + if(vl6180_data->enable){ + rc = gpio_direction_output(vl6180_data->ce_gpio,0); + if(rc < 0){ + pr_err("%s:%d stmvl6180 ce_gpio output failed %d\n", __func__, __LINE__, rc); +// return -1; + } + +//just cci device need this + if (vl6180_data->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) { +// mutex_lock(&vl6180_data->work_mutex); + rc = vl6180_data->i2c_client.i2c_func_tbl->i2c_util(&vl6180_data->i2c_client, MSM_CCI_RELEASE); +// mutex_unlock(&vl6180_data->work_mutex); + if (rc < 0){ + pr_err("%s:%d cci_release failed\n", __func__, __LINE__); +// return -1; + } + } + + if (vl6180_data->vdd_regulator_i2c) { + rc = regulator_disable(vl6180_data->vdd_regulator_i2c); + if(rc){ + pr_err("%s:%d stmvl6180 vdd_regulator_i2c disable failed %d\n", __func__, __LINE__, rc); +// return -1; + } + } + + if (vl6180_data->vdd_regulator) { + rc = regulator_disable(vl6180_data->vdd_regulator); + if(rc){ + pr_err("%s:%d stmvl6180 vdd_regulator disable failed %d\n", __func__, __LINE__, rc); + // return -1; + } + } + + if(gpio_is_valid(vl6180_data->ce_gpio)){ + gpio_free(vl6180_data->ce_gpio); + } + if(gpio_is_valid(vl6180_data->irq_gpio)){ + gpio_free(vl6180_data->irq_gpio); + } + + vl6180_data->enable = 0; + vl6180_data->enable_ps_sensor = 0; + } + } + return rc; +} + +static int stmvl6180_parse_dt(struct device *dev, struct stmvl6180_data *vl6180_data) +{ + int ret = 0; + + if (dev->of_node) { + struct device_node *np = dev->of_node; + + /* reset, irq gpio info */ + vl6180_data->irq_gpio = of_get_named_gpio(np, "st,irq-gpio", 0); + if( vl6180_data->irq_gpio < 0 ) { + pr_err("%s:%d get vl6180 irq_gpio failed\n", __func__, __LINE__); + return -1; + } + vl6180_data->ce_gpio = of_get_named_gpio(np, "st,standby-gpio", 0); + if( vl6180_data->ce_gpio < 0 ) { + pr_err("%s:%d get vl6180 ce gpio fained\n", __func__, __LINE__); + return -1; + } + CDBG("irq_gpio:%d ce_gpio:%d\n", vl6180_data->irq_gpio, vl6180_data->ce_gpio); + + vl6180_data->vdd_regulator = regulator_get(dev, "vdd_1v8"); + if(IS_ERR(vl6180_data->vdd_regulator)) { + pr_err("%s:%d Regulator vdd_1v8 get failed\n", __func__, __LINE__); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + return -1; + } + + vl6180_data->vdd_regulator_i2c = regulator_get(dev, "vcc_i2c_1v8"); + if(IS_ERR(vl6180_data->vdd_regulator_i2c) ) { + pr_err("%s:%d Regulator vcc_i2c_1v8 get failed\n", __func__, __LINE__); + regulator_put(vl6180_data->vdd_regulator); + gpio_free(vl6180_data->ce_gpio); + gpio_free(vl6180_data->irq_gpio); + return -1; + } + }else{ + pr_err("%s:%d of_node is NULL", __func__, __LINE__); + return -EFAULT; + } + return ret; +} + +static int32_t stmvl6180_platform_probe(struct platform_device *pdev) +{ + int32_t rc = 0; + struct msm_camera_cci_client *cci_client = NULL; + struct stmvl6180_data *vl6180_data = NULL; + CDBG("Enter\n"); + + if (!pdev->dev.of_node) { + pr_err("%s:%d of_node NULL\n", __func__, __LINE__); + return -EINVAL; + } + + vl6180_data = kzalloc(sizeof(struct stmvl6180_data), GFP_KERNEL); + if (!vl6180_data) { + pr_err("%s:%d kzalloc failed\n", __func__, __LINE__); + return -ENOMEM; + } + vl6180_data_g = vl6180_data; + +//new driver start + vl6180_data->enable = 0; /* default mode is standard */ + CDBG("enable = %x\n", vl6180_data->enable); + + mutex_init(&vl6180_data->update_lock); + mutex_init(&vl6180_data->work_mutex); + mutex_init(&vl6180_mutex); + +#ifdef USE_INT + gpio_request(IRQ_NUM,"vl6180_gpio_int"); + gpio_direction_input(IRQ_NUM); + irq = gpio_to_irq(IRQ_NUM); + if (irq < 0) + { + pr_err("%s:%d filed to map GPIO :%d to interrupt:%d\n", __func__, __LINE__, IRQ_NUM, irq); + } + else + { + int result; + vl6180_dbgmsg("%s:%d register_irq:%d\n",__func__, __LINE__, irq); + if ((result = request_threaded_irq(irq, NULL, stmvl6180_interrupt_handler, IRQF_TRIGGER_RISING, //IRQF_TRIGGER_FALLING- poliarity:0 IRQF_TRIGGER_RISNG - poliarty:1 + "vl6180_lb_gpio_int", (void *)client))) + { + pr_err("%s:%d Could not allocate STMVL6180_INT ! result:%d\n", __func__, __LINE__, result); + + goto exit_kfree; + } + } + //disable_irq(irq); + vl6180_data->irq = irq; + vl6180_dbgmsg("%s:%d interrupt is hooked\n", __func__, __LINE__); +#endif +//new driver end + + rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id); + if (rc < 0) { + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_free_irq; + } + CDBG("cell-index %d, rc %d\n", pdev->id, rc); + + rc = of_property_read_u32(pdev->dev.of_node, "qcom,cci-master", &vl6180_data->cci_master); + if (rc < 0) { + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_free_irq; + } + CDBG("qcom,cci-master %d, rc %d\n", vl6180_data->cci_master, rc); + + rc = stmvl6180_parse_dt(&pdev->dev, vl6180_data); + if (rc < 0) { + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_free_irq; + } + + /* Set platform device handle */ + vl6180_data->pdev = pdev; + vl6180_data->subdev_id = pdev->id; + + /* Set device type as platform device */ + vl6180_data->act_device_type = MSM_CAMERA_PLATFORM_DEVICE; + vl6180_data->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl; + vl6180_data->v4l2_subdev_ops = &msm_stmvl6180_subdev_ops; + vl6180_data->i2c_client.cci_client = kzalloc(sizeof(struct msm_camera_cci_client), GFP_KERNEL); + if (!vl6180_data->i2c_client.cci_client) { + rc = -ENOMEM; + pr_err("%s:%d failed no memory\n", __func__, __LINE__); + goto exit_free_irq; + } + + cci_client = vl6180_data->i2c_client.cci_client; + cci_client->cci_subdev = msm_cci_get_subdev(); + cci_client->sid = VL6180_I2C_ADDRESS; + cci_client->retries = 3; + cci_client->id_map = 0; + cci_client->cci_i2c_master = vl6180_data->cci_master; + vl6180_data->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; + vl6180_data->force_reset_cnt = 0; + + rc = stmvl6180_power_enable(vl6180_data, 1); + if(rc){ + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_kfree_client; + } + + /* Initialize the STM VL6180 chip */ + rc = stmvl6180_init_client(vl6180_data); + if (rc){ + stmvl6180_power_enable(vl6180_data, 0); + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_kfree_client; + } + + rc = stmvl6180_power_enable(vl6180_data, 0); + if(rc){ + pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); + goto exit_kfree_client; + } +#ifdef VENDOR_EDIT + v4l2_subdev_init(&vl6180_data->msm_sd.sd, + vl6180_data->v4l2_subdev_ops); + vl6180_data->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(vl6180_data->msm_sd.sd.name, + ARRAY_SIZE(vl6180_data->msm_sd.sd.name), "msm_laser"); + media_entity_init(&vl6180_data->msm_sd.sd.entity, 0, NULL, 0); + vl6180_data->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + vl6180_data->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x3; + msm_sd_register(&vl6180_data->msm_sd); +#endif + + //to register as a misc device + rc = misc_register(&stmvl6180_ranging_dev); + if (rc){ + pr_err(KERN_INFO "%s:%d Could not register misc. dev for stmvl6180 ranging\n", __func__, __LINE__); + goto exit_kfree_client; + } + +//new driver start +/* Register to Input Device */ + vl6180_data->input_dev_ps = input_allocate_device(); + if (!vl6180_data->input_dev_ps) { + rc = -ENOMEM; + pr_err("%s:%d Failed to allocate input device ps\n", __func__, __LINE__); + goto exit_kfree_client; + } + + vl6180_data->input_dev_ps->name = "STM VL6180 proximity sensor"; + set_bit(EV_ABS, vl6180_data->input_dev_ps->evbit); + + input_set_abs_params(vl6180_data->input_dev_ps, ABS_DISTANCE, 0, 76, 0, 0); //range in cm + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT0X, 0, 0xffffffff, 0, 0); //timeval.tv_sec + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT0Y, 0, 0xffffffff, 0, 0); //timeval.tv_usec + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT1X, 0, 765, 0, 0); //range in mm + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT1Y, 0, 0xffffffff, 0, 0); //errorStatus + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT2X, 0, 0xffffffff, 0, 0); //signal rate (MCPS) + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT2Y, 0, 0xffffffff, 0, 0); //Return Ambient rate in KCPS + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT3X, 0, 0xffffffff, 0, 0); // Return Convergence time + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT3Y, 0, 0xffffffff, 0, 0); //DMax + + rc = input_register_device(vl6180_data->input_dev_ps); + if (rc<0){ + rc = -ENOMEM; + pr_err("%s:%d Unable to register input device ps: %s\n",__func__, __LINE__, vl6180_data->input_dev_ps->name); + goto exit_free_dev_ps; + } + +/* Register sysfs hooks */ + rc = sysfs_create_group(&vl6180_data->pdev->dev.kobj, &stmvl6180_attr_group); + if (rc<0){ + pr_err("%s%d Unable to create sysfs group\n",__func__, __LINE__); + goto exit_unregister_dev_ps; + } + + INIT_DELAYED_WORK(&vl6180_data->dwork, stmvl6180_work_handler); + + CDBG("support ver. %s enabled\n", DRIVER_VERSION); + +//new driver end + return 0; + +exit_unregister_dev_ps: + input_unregister_device(vl6180_data->input_dev_ps); +exit_free_dev_ps: + input_free_device(vl6180_data->input_dev_ps); +exit_kfree_client: + kfree(vl6180_data->i2c_client.cci_client); +exit_free_irq: +#ifdef USE_INT + free_irq(irq, client); +#endif +//exit_kfree: + kfree(vl6180_data); + vl6180_data_g = NULL; +//exit: + return rc; +} + + +static const struct of_device_id stmvl6180_dt_match[] = { + {.compatible = "stmv,vl6180", .data=NULL}, + {} +}; + +static struct platform_driver stmvl6180_platform_driver = { + .driver = { + .name = "stmv,vl6180", + .owner = THIS_MODULE, + .of_match_table = stmvl6180_dt_match, + }, +}; + +static int stmvl6180_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct stmvl6180_data *vl6180_data; + struct msm_camera_cci_client *cci_client = NULL; + int err = 0; + CDBG("start\n"); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { + err = -EIO; + pr_err("%s:%d check i2c functionality failed\n", __func__, __LINE__); + goto exit; + } + + vl6180_data = kzalloc(sizeof(struct stmvl6180_data), GFP_KERNEL); + if (!vl6180_data) { + err = -ENOMEM; + pr_err("%s:%d kzalloc failed\n", __func__, __LINE__); + goto exit; + } + +//parse dtsi file + if (client->dev.of_node) { + err = stmvl6180_parse_dt(&client->dev, vl6180_data); + if (err < 0) { + pr_err("%s:%d parse dt failed err %d\n", __func__, __LINE__, err); + goto exit_kfree; + } + } else { + pr_err("%s:%d of_node NULL\n", __func__, __LINE__); + goto exit_kfree; + } + + vl6180_data->client = client; + i2c_set_clientdata(client, vl6180_data); + vl6180_data->enable = 0; /* default mode is standard */ + vl6180_data_g = vl6180_data; + + // setup platform i2c client + i2c_setclient(client); + //vl6180x_dev.I2cAddress = client->addr; + + mutex_init(&vl6180_data->update_lock); + mutex_init(&vl6180_data->work_mutex); + mutex_init(&vl6180_mutex); + + //interrupt set up +#ifdef USE_INT + gpio_request(IRQ_NUM,"vl6180_gpio_int"); + gpio_direction_input(IRQ_NUM); + irq = gpio_to_irq(IRQ_NUM); + if (irq < 0) + { + pr_err("filed to map GPIO :%d to interrupt:%d\n",IRQ_NUM,irq); + } + else + { + int result; + vl6180_dbgmsg("register_irq:%d\n",irq); + if ((result = request_threaded_irq(irq, NULL, stmvl6180_interrupt_handler, IRQF_TRIGGER_RISING, //IRQF_TRIGGER_FALLING- poliarity:0 IRQF_TRIGGER_RISNG - poliarty:1 + "vl6180_lb_gpio_int", (void *)client))) + { + pr_err("%s Could not allocate STMVL6180_INT ! result:%d\n", __func__,result); + goto exit_kfree; + } + } + //disable_irq(irq); + vl6180_data->irq = irq; + vl6180_dbgmsg("%s interrupt is hooked\n", __func__); +#endif + +#ifdef VENDOR_EDIT + vl6180_data->act_device_type = MSM_CAMERA_I2C_DEVICE;//define I2C device + vl6180_data->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl; + vl6180_data->v4l2_subdev_ops = &msm_stmvl6180_subdev_ops; + vl6180_data->i2c_client.cci_client = kzalloc(sizeof(struct msm_camera_cci_client), GFP_KERNEL); + if (!vl6180_data->i2c_client.cci_client) { + err = -ENOMEM; + pr_err("%s:%d failed no memory\n", __func__, __LINE__); + goto exit_free_irq; + } + cci_client = vl6180_data->i2c_client.cci_client; + cci_client->cci_subdev = msm_cci_get_subdev(); + cci_client->sid = VL6180_I2C_ADDRESS; + cci_client->retries = 3; + cci_client->id_map = 0; + cci_client->cci_i2c_master = vl6180_data->cci_master; + vl6180_data->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR; +#endif + + err = stmvl6180_power_enable(vl6180_data, 1); + if(err) { + pr_err("%s:%d failed err %d\n", __func__, __LINE__, err); + goto exit_kfree_client; + } + vl6180_data->force_reset_cnt = 0; + + /* Initialize the STM VL6180 chip */ + err = stmvl6180_init_client(vl6180_data); + if (err) { + stmvl6180_power_enable(vl6180_data, 0); + pr_err("%s:%d failed err %d\n", __func__, __LINE__, err); + goto exit_kfree_client; + } + + err = stmvl6180_power_enable(vl6180_data, 0); + if(err) { + pr_err("%s:%d failed err %d\n", __func__, __LINE__, err); + goto exit_kfree_client; + } + INIT_DELAYED_WORK(&vl6180_data->dwork, stmvl6180_work_handler); +#ifdef VENDOR_EDIT + v4l2_subdev_init(&vl6180_data->msm_sd.sd, + vl6180_data->v4l2_subdev_ops); + vl6180_data->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(vl6180_data->msm_sd.sd.name, + ARRAY_SIZE(vl6180_data->msm_sd.sd.name), "msm_laser"); + media_entity_init(&vl6180_data->msm_sd.sd.entity, 0, NULL, 0); + vl6180_data->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + vl6180_data->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x3; + msm_sd_register(&vl6180_data->msm_sd); +#endif + + //to register as a misc device + err = misc_register(&stmvl6180_ranging_dev); + if (err){ + pr_err("%s:%d Could not register misc. dev for stmvl6180 ranging\n", __func__, __LINE__); + goto exit_kfree_client; + } + + /* Register to Input Device */ + vl6180_data->input_dev_ps = input_allocate_device(); + if (!vl6180_data->input_dev_ps) { + err = -ENOMEM; + pr_err("%s:%d Failed to allocate input device ps\n",__func__, __LINE__); + goto exit_kfree_client; + } + vl6180_data->input_dev_ps->name = "STM VL6180 proximity sensor"; + set_bit(EV_ABS, vl6180_data->input_dev_ps->evbit); + + input_set_abs_params(vl6180_data->input_dev_ps, ABS_DISTANCE, 0, 76, 0, 0); //range in cm + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT0X, 0, 0xffffffff, 0, 0); //timeval.tv_sec + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT0Y, 0, 0xffffffff, 0, 0); //timeval.tv_usec + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT1X, 0, 765, 0, 0); //range in mm + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT1Y, 0, 0xffffffff, 0, 0); //errorStatus + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT2X, 0, 0xffffffff, 0, 0); //signal rate (MCPS) + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT2Y, 0, 0xffffffff, 0, 0); //Return Ambient rate in KCPS + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT3X, 0, 0xffffffff, 0, 0); // Return Convergence time + input_set_abs_params(vl6180_data->input_dev_ps, ABS_HAT3Y, 0, 0xffffffff, 0, 0); //DMax + + err = input_register_device(vl6180_data->input_dev_ps); + if (err) { + err = -ENOMEM; + pr_err("%s:%d Unable to register input device ps: %s\n",__func__, __LINE__, vl6180_data->input_dev_ps->name); + goto exit_free_dev_ps; + } + + /* Register sysfs hooks */ + err = sysfs_create_group(&client->dev.kobj, &stmvl6180_attr_group); + if (err){ + pr_err("%s%d Unable to create sysfs group\n",__func__, __LINE__); + goto exit_unregister_dev_ps; + } + + CDBG("%s successfully! support ver. %s enabled\n", __func__, DRIVER_VERSION); + + return 0; + +exit_unregister_dev_ps: + input_unregister_device(vl6180_data->input_dev_ps); +exit_free_dev_ps: + input_free_device(vl6180_data->input_dev_ps); +exit_kfree_client: + kfree(vl6180_data->i2c_client.cci_client); +exit_free_irq: +#ifdef USE_INT + free_irq(irq, client); +#endif +exit_kfree: + kfree(vl6180_data); +exit: + return err; +} + +static int stmvl6180_i2c_remove(struct i2c_client *client) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + input_unregister_device(vl6180_data->input_dev_ps); + input_free_device(vl6180_data->input_dev_ps); + +#ifdef USE_INT + free_irq(vl6180_data->irq, client); +#endif + + sysfs_remove_group(&client->dev.kobj, &stmvl6180_attr_group); + + /* Power down the device */ + stmvl6180_set_enable(client, 0); + + kfree(vl6180_data); + vl6180_data_g = NULL; + + return 0; +} + +#ifdef CONFIG_PM + +static int stmvl6180_i2c_suspend(struct i2c_client *client, pm_message_t mesg) +{ + return stmvl6180_set_enable(client, 0); +} + +static int stmvl6180_i2c_resume(struct i2c_client *client) +{ + return stmvl6180_set_enable(client, 0); +} + +#else + +#define stmvl6180_i2c_suspend NULL +#define stmvl6180_i2c_resume NULL + +#endif /* CONFIG_PM */ + +static const struct i2c_device_id stmvl6180_i2c_id[] = { + { "vl6180", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, stmvl6180_id); + +static struct i2c_driver stmvl6180_i2c_driver = { + .driver = { + .name = "vl6180", + .owner = THIS_MODULE, + }, + .suspend = stmvl6180_i2c_suspend, + .resume = stmvl6180_i2c_resume, + .probe = stmvl6180_i2c_probe, + .remove = stmvl6180_i2c_remove, + .id_table = stmvl6180_i2c_id, +}; + +static int __init stmvl6180_init(void) +{ + int rc=0; +#if 0 + struct i2c_adapter *adapter; + struct i2c_board_info info = { + .type = "stmvl6180", + .addr = VL6180_I2C_ADDRESS, + }; +#endif + CDBG("start stmvl6180_init\n"); + rc = platform_driver_probe(&stmvl6180_platform_driver, stmvl6180_platform_probe); + + if(rc){ + pr_err("%s:%d platform device register failed, try to register as I2C device\n", __func__, __LINE__); + rc = i2c_add_driver(&stmvl6180_i2c_driver); + } + +#if 0 + if(ret){ + ret = i2c_add_driver(&stmvl6180_driver); + if (ret) + return ret; + adapter = i2c_get_adapter(4); + if (!adapter) + return -EINVAL; + + client = i2c_new_device(adapter, &info); + if (!client) + return -EINVAL; + } +#endif + return rc; +} + +static void __exit stmvl6180_exit(void) +{ + struct stmvl6180_data *vl6180_data = vl6180_data_g; + + CDBG("exit\n"); + input_unregister_device(vl6180_data->input_dev_ps); + input_free_device(vl6180_data->input_dev_ps); + +#ifdef USE_INT + free_irq(vl6180_data->irq, client); +#endif + + sysfs_remove_group(&client->dev.kobj, &stmvl6180_attr_group); + + /* Power down the device */ + stmvl6180_set_enable(client, 0); + + if(vl6180_data_g->i2c_client.cci_client) + kfree(vl6180_data_g->i2c_client.cci_client); + if(vl6180_data_g){ + kfree(vl6180_data_g); + vl6180_data_g = NULL; + } + + platform_driver_unregister(&stmvl6180_platform_driver); + i2c_del_driver(&stmvl6180_i2c_driver); +} + +module_init(stmvl6180_init); +module_exit(stmvl6180_exit); +MODULE_AUTHOR("STMicroelectronics Imaging Division"); +MODULE_DESCRIPTION("ST FlightSense Time-of-Flight sensor driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b8ec86787806c..5b50aaf0bb36e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -611,7 +611,19 @@ config TI_DRV2667 To compile this driver as a module, choose M here: the module will be called ti_drv2667. +#ifdef VENDOR_EDIT +#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support +config TI_DRV2605 + tristate "TI's DRV2605 haptic controller support" + depends on I2C + help + The DRV2605 is a piezo haptic controller chip. It can drive + piezo haptics either in digital mode or analog mode. This chip + can be used in variety of devices to provide haptic support. + To compile this driver as a module, choose M here: the + module will be called ti_drv2605. +#endif VENDOR_EDIT config QCOM_LIQUID_DOCK tristate "QTI LiQUID Docking Station USB/Ethernet support" depends on OF_GPIO diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 56a4234610e1a..e898cacfa8dbc 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -67,3 +67,8 @@ obj-$(CONFIG_TI_DRV2667) += ti_drv2667.o obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o obj-$(CONFIG_QCOM_LIQUID_DOCK) += qcom_liquid_dock.o obj-y += qcom/ +#ifdef VENDOR_EDIT +#shankai@bsp, 2015/2/2, Add for :drv2605 kernel support +obj-$(CONFIG_TI_DRV2605) += ti_drv2605.o +#endif VENDOR_EDIT + diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c index 2833910f59fb1..37ac5c53c85f4 100644 --- a/drivers/misc/qcom/qdsp6v2/aac_in.c +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -242,8 +242,8 @@ static long aac_in_ioctl_shared(struct file *file, unsigned int cmd, void *arg) if (min_bitrate > 24000) min_bitrate = 24000; max_bitrate = 6*(cfg->sample_rate)*(cfg->channels); - if (max_bitrate > 192000) - max_bitrate = 192000; + if (max_bitrate > 320000) + max_bitrate = 320000; if ((cfg->bit_rate < min_bitrate) || (cfg->bit_rate > max_bitrate)) { pr_err("%s: bitrate permissible: max=%d, min=%d\n", diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 73b7e25c4b159..6db7519dcbf43 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -1939,7 +1939,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_buf_cfg cfg; struct msm_audio_buf_cfg32 cfg_32; mutex_lock(&audio->lock); - if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", __func__); rc = -EFAULT; diff --git a/drivers/misc/ti_drv2605.c b/drivers/misc/ti_drv2605.c new file mode 100644 index 0000000000000..42e7ee2710b89 --- /dev/null +++ b/drivers/misc/ti_drv2605.c @@ -0,0 +1,1242 @@ +/* +** ============================================================================= +** Copyright (c) 2014 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +** File: +** drv2605.c +** +** Description: +** DRV2605 chip driver +** +** ============================================================================= +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ti_drv2605.h" + +static struct drv2605_data *pDRV2605data = NULL; + + + +static int drv2605_reg_read(struct drv2605_data *pDrv2605data, unsigned int reg) +{ + unsigned int val; + int ret; + + ret = regmap_read(pDrv2605data->regmap, reg, &val); + + if (ret < 0) + return ret; + else + return val; +} + +static int drv2605_reg_write(struct drv2605_data *pDrv2605data, unsigned char reg, char val) +{ + return regmap_write(pDrv2605data->regmap, reg, val); +} + +static int drv2605_bulk_read(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned int count, u8 *buf) +{ + return regmap_bulk_read(pDrv2605data->regmap, reg, buf, count); +} + +static int drv2605_bulk_write(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned int count, const u8 *buf) +{ + return regmap_bulk_write(pDrv2605data->regmap, reg, buf, count); +} + +static int drv2605_set_bits(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned char mask, unsigned char val) +{ + return regmap_update_bits(pDrv2605data->regmap, reg, mask, val); +} + +static int drv2605_set_go_bit(struct drv2605_data *pDrv2605data, unsigned char val) +{ + return drv2605_reg_write(pDrv2605data, GO_REG, (val&0x01)); +} + +static void drv2605_poll_go_bit(struct drv2605_data *pDrv2605data) +{ + while (drv2605_reg_read(pDrv2605data, GO_REG) == GO) + { + schedule_timeout_interruptible(msecs_to_jiffies(GO_BIT_POLL_INTERVAL)); + //pr_err("shankai555----%s:%d\n" ,__func__,__LINE__); + } + +} + +static int drv2605_select_library(struct drv2605_data *pDrv2605data, unsigned char lib) +{ + return drv2605_reg_write(pDrv2605data, LIBRARY_SELECTION_REG, (lib&0x07)); +} + +static int drv2605_set_rtp_val(struct drv2605_data *pDrv2605data, char value) +{ + /* please be noted: in unsigned mode, maximum is 0xff, in signed mode, maximum is 0x7f */ + return drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, value); +} + +static int drv2605_set_waveform_sequence(struct drv2605_data *pDrv2605data, unsigned char* seq, unsigned int size) +{ + return drv2605_bulk_write(pDrv2605data, WAVEFORM_SEQUENCER_REG, (size>WAVEFORM_SEQUENCER_MAX)?WAVEFORM_SEQUENCER_MAX:size, seq); +} + +static void drv2605_change_mode(struct drv2605_data *pDrv2605data, char work_mode, char dev_mode) +{ + /* please be noted : LRA open loop cannot be used with analog input mode */ + if(dev_mode == DEV_IDLE){ + pDrv2605data->dev_mode = dev_mode; + pDrv2605data->work_mode = work_mode; + }else if(dev_mode == DEV_STANDBY){ + if(pDrv2605data->dev_mode != DEV_STANDBY){ + pDrv2605data->dev_mode = DEV_STANDBY; + drv2605_reg_write(pDrv2605data, MODE_REG, MODE_STANDBY); + schedule_timeout_interruptible(msecs_to_jiffies(WAKE_STANDBY_DELAY)); + } + pDrv2605data->work_mode = WORK_IDLE; + }else if(dev_mode == DEV_READY){ + if((work_mode != pDrv2605data->work_mode) + ||(dev_mode != pDrv2605data->dev_mode)){ + pDrv2605data->work_mode = work_mode; + pDrv2605data->dev_mode = dev_mode; + if((pDrv2605data->work_mode == WORK_VIBRATOR) + ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON) + ||(pDrv2605data->work_mode == WORK_SEQ_RTP_ON) + ||(pDrv2605data->work_mode == WORK_RTP)){ + drv2605_reg_write(pDrv2605data, MODE_REG, MODE_REAL_TIME_PLAYBACK); + }else if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){ + drv2605_reg_write(pDrv2605data, MODE_REG, MODE_AUDIOHAPTIC); + }else if(pDrv2605data->work_mode == WORK_CALIBRATION){ + drv2605_reg_write(pDrv2605data, MODE_REG, AUTO_CALIBRATION); + }else{ + drv2605_reg_write(pDrv2605data, MODE_REG, MODE_INTERNAL_TRIGGER); + schedule_timeout_interruptible(msecs_to_jiffies(STANDBY_WAKE_DELAY)); + } + } + } +} + + + + +static void setAudioHapticsEnabled(struct drv2605_data *pDrv2605data, int enable) +{ + if (enable) + { + if(pDrv2605data->work_mode != WORK_AUDIO2HAPTIC){ + pDrv2605data->vibrator_is_playing = YES; + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY); + + drv2605_set_bits(pDrv2605data, + Control1_REG, + Control1_REG_AC_COUPLE_MASK, + AC_COUPLE_ENABLED ); + + drv2605_set_bits(pDrv2605data, + Control3_REG, + Control3_REG_PWMANALOG_MASK, + INPUT_ANALOG); + + drv2605_change_mode(pDrv2605data, WORK_AUDIO2HAPTIC, DEV_READY); + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_AUDIO2HAPTIC); + } + } else { + // Chip needs to be brought out of standby to change the registers + if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){ + pDrv2605data->vibrator_is_playing = NO; + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY); + + drv2605_set_bits(pDrv2605data, + Control1_REG, + Control1_REG_AC_COUPLE_MASK, + AC_COUPLE_DISABLED ); + + drv2605_set_bits(pDrv2605data, + Control3_REG, + Control3_REG_PWMANALOG_MASK, + INPUT_PWM); + + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE); + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); // Disable audio-to-haptics + } + } +} + +static void play_effect(struct drv2605_data *pDrv2605data) +{ + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_SEQUENCE_PLAYBACK); + drv2605_change_mode(pDrv2605data, WORK_SEQ_PLAYBACK, DEV_READY); + drv2605_set_waveform_sequence(pDrv2605data, pDrv2605data->sequence, WAVEFORM_SEQUENCER_MAX); + pDrv2605data->vibrator_is_playing = YES; + drv2605_set_go_bit(pDrv2605data, GO); + + while((drv2605_reg_read(pDrv2605data, GO_REG) == GO) && (pDrv2605data->should_stop == NO)){ + schedule_timeout_interruptible(msecs_to_jiffies(GO_BIT_POLL_INTERVAL)); + } + + if(pDrv2605data->should_stop == YES){ + drv2605_set_go_bit(pDrv2605data, STOP); + } + + if (pDrv2605data->audio_haptics_enabled){ + setAudioHapticsEnabled(pDrv2605data, YES); + } else { + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE); + pDrv2605data->vibrator_is_playing = NO; + wake_unlock(&pDrv2605data->wklock); + } +} + +static void play_Pattern_RTP(struct drv2605_data *pDrv2605data) +{ + if(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON){ + drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_OFF, DEV_READY); + if(pDrv2605data->repeat_times == 0){ + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); + pDrv2605data->vibrator_is_playing = NO; + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE); + wake_unlock(&pDrv2605data->wklock); + }else{ + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->silience_time * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + }else if(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF){ + pDrv2605data->repeat_times--; + drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_ON, DEV_READY); + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->vibration_time * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } +} + +static void play_Seq_RTP(struct drv2605_data *pDrv2605data) +{ + if(pDrv2605data->RTPSeq.RTPindex < pDrv2605data->RTPSeq.RTPCounts){ + int RTPTime = pDrv2605data->RTPSeq.RTPData[pDrv2605data->RTPSeq.RTPindex] >> 8; + int RTPVal = pDrv2605data->RTPSeq.RTPData[pDrv2605data->RTPSeq.RTPindex] & 0x00ff ; + + pDrv2605data->vibrator_is_playing = YES; + pDrv2605data->RTPSeq.RTPindex++; + drv2605_change_mode(pDrv2605data, WORK_SEQ_RTP_ON, DEV_READY); + drv2605_set_rtp_val(pDrv2605data, RTPVal); + + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)RTPTime * NSEC_PER_MSEC), HRTIMER_MODE_REL); + }else{ + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); + pDrv2605data->vibrator_is_playing = NO; + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE); + wake_unlock(&pDrv2605data->wklock); + } +} + +static void vibrator_off(struct drv2605_data *pDrv2605data) +{ + if (pDrv2605data->vibrator_is_playing) { + if(pDrv2605data->audio_haptics_enabled == YES){ + setAudioHapticsEnabled(pDrv2605data, YES); + }else{ + pDrv2605data->vibrator_is_playing = NO; + drv2605_set_go_bit(pDrv2605data, STOP); + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE); + wake_unlock(&pDrv2605data->wklock); + } + } +} + +static void drv2605_stop(struct drv2605_data *pDrv2605data) +{ + if(pDrv2605data->vibrator_is_playing){ + if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){ + setAudioHapticsEnabled(pDrv2605data, NO); + }else if((pDrv2605data->work_mode == WORK_VIBRATOR) + ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON) + ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF) + ||(pDrv2605data->work_mode == WORK_SEQ_RTP_ON) + ||(pDrv2605data->work_mode == WORK_SEQ_RTP_OFF) + ||(pDrv2605data->work_mode == WORK_RTP)){ + //printk("shankai555-------------------------------pDrv2605data work_mode is %d \n ",pDrv2605data->work_mode ); + vibrator_off(pDrv2605data); + }else if(pDrv2605data->work_mode == WORK_SEQ_PLAYBACK){ + }else{ + //printk("shankai555------------------------------------%s, err mode=%d \n", __FUNCTION__, pDrv2605data->work_mode); + } + + + } +} + +static int vibrator_get_time(struct timed_output_dev *dev) +{ + struct drv2605_data *pDrv2605data = container_of(dev, struct drv2605_data, to_dev); + + if (hrtimer_active(&pDrv2605data->timer)) { + ktime_t r = hrtimer_get_remaining(&pDrv2605data->timer); + return ktime_to_ms(r); + + } + + return 0; +} +static int dev_auto_calibrate(struct drv2605_data *pDrv2605data); +static void vibrator_enable( struct timed_output_dev *dev, int value) +{ + + struct drv2605_data *pDrv2605data = container_of(dev, struct drv2605_data, to_dev); + + pDrv2605data->should_stop = YES; + hrtimer_cancel(&pDrv2605data->timer); + cancel_work_sync(&pDrv2605data->vibrator_work); + + mutex_lock(&pDrv2605data->lock); + + drv2605_stop(pDrv2605data); + + + if (value > 0) { + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + + drv2605_change_mode(pDrv2605data, WORK_VIBRATOR, DEV_READY); + + + pDrv2605data->vibrator_is_playing = YES; + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK); + + value = (value>MAX_TIMEOUT)?MAX_TIMEOUT:value; + //printk("shankai555--------------------------------%s--%d\n",__func__,__LINE__); + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL); + //printk("shankai555--------------------------------%s--%d\n",__func__,__LINE__); + } + + mutex_unlock(&pDrv2605data->lock); +} + +static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer) +{ + struct drv2605_data *pDrv2605data = container_of(timer, struct drv2605_data, timer); + + // printk("shankai555-------------vibrator_work--------------------%s--%d\n",__func__,__LINE__); + schedule_work(&pDrv2605data->vibrator_work); + + + return HRTIMER_NORESTART; +} + +static void vibrator_work_routine(struct work_struct *work) +{ + struct drv2605_data *pDrv2605data = container_of(work, struct drv2605_data, vibrator_work); + + mutex_lock(&pDrv2605data->lock); + //printk("shankai555--------pDrv2605data->work_mode=%x------%s:%d-----------\n",pDrv2605data->work_mode,__func__,__LINE__); + if((pDrv2605data->work_mode == WORK_VIBRATOR) + ||(pDrv2605data->work_mode == WORK_RTP)){ + vibrator_off(pDrv2605data);//shankai add + //play_Pattern_RTP(pDrv2605data); + }else if(pDrv2605data->work_mode == WORK_SEQ_PLAYBACK){ + play_effect(pDrv2605data); + }else if((pDrv2605data->work_mode == WORK_PATTERN_RTP_ON)||(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF)){ + play_Pattern_RTP(pDrv2605data); + }else if((pDrv2605data->work_mode == WORK_SEQ_RTP_ON)||(pDrv2605data->work_mode == WORK_SEQ_RTP_OFF)){ + play_Seq_RTP(pDrv2605data); + } + + + mutex_unlock(&pDrv2605data->lock); +} + +static int dev2605_open (struct inode * i_node, struct file * filp) +{ + if(pDRV2605data == NULL){ + return -ENODEV; + } + + filp->private_data = pDRV2605data; + return 0; +} + +static ssize_t dev2605_read(struct file* filp, char* buff, size_t length, loff_t* offset) +{ + struct drv2605_data *pDrv2605data = (struct drv2605_data *)filp->private_data; + int ret = 0; + + if(pDrv2605data->ReadLen > 0){ + ret = copy_to_user(buff, pDrv2605data->ReadBuff, pDrv2605data->ReadLen); + if (ret != 0){ + printk("%s, copy_to_user err=%d \n", __FUNCTION__, ret); + }else{ + ret = pDrv2605data->ReadLen; + } + pDrv2605data->ReadLen = 0; + } + + return ret; +} + +static bool isforDebug(int cmd){ + return ((cmd == HAPTIC_CMDID_REG_WRITE) + ||(cmd == HAPTIC_CMDID_REG_READ) + ||(cmd == HAPTIC_CMDID_REG_SETBIT)); +} + +static ssize_t dev2605_write(struct file* filp, const char* buff, size_t len, loff_t* off) +{ + struct drv2605_data *pDrv2605data = (struct drv2605_data *)filp->private_data; + + if(isforDebug(buff[0])){ + }else{ + pDrv2605data->should_stop = YES; + hrtimer_cancel(&pDrv2605data->timer); + cancel_work_sync(&pDrv2605data->vibrator_work); + } + + mutex_lock(&pDrv2605data->lock); + + if(isforDebug(buff[0])){ + }else{ + drv2605_stop(pDrv2605data); + } + + switch(buff[0]) + { + case HAPTIC_CMDID_PLAY_SINGLE_EFFECT: + case HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE: + { + memset(&pDrv2605data->sequence, 0, WAVEFORM_SEQUENCER_MAX); + if (!copy_from_user(&pDrv2605data->sequence, &buff[1], len - 1)) + { + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + pDrv2605data->should_stop = NO; + drv2605_change_mode(pDrv2605data, WORK_SEQ_PLAYBACK, DEV_IDLE); + schedule_work(&pDrv2605data->vibrator_work); + } + break; + } + case HAPTIC_CMDID_PLAY_TIMED_EFFECT: + { + unsigned int value = 0; + value = buff[2]; + value <<= 8; + value |= buff[1]; + + if (value > 0) + { + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK); + pDrv2605data->vibrator_is_playing = YES; + value = (value > MAX_TIMEOUT)?MAX_TIMEOUT:value; + drv2605_change_mode(pDrv2605data, WORK_RTP, DEV_READY); + + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + break; + } + + case HAPTIC_CMDID_PATTERN_RTP: + { + unsigned char strength = 0; + + pDrv2605data->vibration_time = (int)((((int)buff[2])<<8) | (int)buff[1]); + pDrv2605data->silience_time = (int)((((int)buff[4])<<8) | (int)buff[3]); + strength = buff[5]; + pDrv2605data->repeat_times = buff[6]; + + if(pDrv2605data->vibration_time > 0){ + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK); + pDrv2605data->vibrator_is_playing = YES; + if(pDrv2605data->repeat_times > 0) + pDrv2605data->repeat_times--; + if (pDrv2605data->vibration_time > MAX_TIMEOUT) + pDrv2605data->vibration_time = MAX_TIMEOUT; + drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_ON, DEV_READY); + drv2605_set_rtp_val(pDrv2605data, strength); + + hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->vibration_time * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + break; + } + + case HAPTIC_CMDID_RTP_SEQUENCE: + { + memset(&pDrv2605data->RTPSeq, 0, sizeof(struct RTP_Seq)); + if(((len-1)%2) == 0){ + pDrv2605data->RTPSeq.RTPCounts = (len-1)/2; + if((pDrv2605data->RTPSeq.RTPCounts <= MAX_RTP_SEQ)&&(pDrv2605data->RTPSeq.RTPCounts>0)){ + if(copy_from_user(pDrv2605data->RTPSeq.RTPData, &buff[1], pDrv2605data->RTPSeq.RTPCounts*2) != 0){ + printk("%s, rtp_seq copy seq err\n", __FUNCTION__); + break; + } + + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK); + drv2605_change_mode(pDrv2605data, WORK_SEQ_RTP_OFF, DEV_IDLE); + schedule_work(&pDrv2605data->vibrator_work); + }else{ + printk("%s, rtp_seq count error,maximum=%d\n", __FUNCTION__,MAX_RTP_SEQ); + } + }else{ + printk("%s, rtp_seq len error\n", __FUNCTION__); + } + break; + } + + case HAPTIC_CMDID_STOP: + { + break; + } + + case HAPTIC_CMDID_AUDIOHAPTIC_ENABLE: + { + if(pDrv2605data->audio_haptics_enabled == NO){ + wake_lock(&pDrv2605data->wklock); + } + pDrv2605data->audio_haptics_enabled = YES; + setAudioHapticsEnabled(pDrv2605data, YES); + break; + } + + case HAPTIC_CMDID_AUDIOHAPTIC_DISABLE: + { + if(pDrv2605data->audio_haptics_enabled == YES){ + pDrv2605data->audio_haptics_enabled = NO; + wake_unlock(&pDrv2605data->wklock); + } + break; + } + + case HAPTIC_CMDID_REG_READ: + { + if(len == 2){ + pDrv2605data->ReadLen = 1; + pDrv2605data->ReadBuff[0] = drv2605_reg_read(pDrv2605data, buff[1]); + }else if(len == 3){ + pDrv2605data->ReadLen = (buff[2]>MAX_READ_BYTES)?MAX_READ_BYTES:buff[2]; + drv2605_bulk_read(pDrv2605data, buff[1], pDrv2605data->ReadLen, pDrv2605data->ReadBuff); + }else{ + printk("%s, reg_read len error\n", __FUNCTION__); + } + break; + } + + case HAPTIC_CMDID_REG_WRITE: + { + if((len-1) == 2){ + drv2605_reg_write(pDrv2605data, buff[1], buff[2]); + }else if((len-1)>2){ + unsigned char *data = (unsigned char *)kzalloc(len-2, GFP_KERNEL); + if(data != NULL){ + if(copy_from_user(data, &buff[2], len-2) != 0){ + printk("%s, reg copy err\n", __FUNCTION__); + }else{ + drv2605_bulk_write(pDrv2605data, buff[1], len-2, data); + } + kfree(data); + } + }else{ + printk("%s, reg_write len error\n", __FUNCTION__); + } + break; + } + + case HAPTIC_CMDID_REG_SETBIT: + { + int i=1; + for(i=1; i< len; ){ + drv2605_set_bits(pDrv2605data, buff[i], buff[i+1], buff[i+2]); + i += 3; + } + break; + } + default: + printk("%s, unknown HAPTIC cmd\n", __FUNCTION__); + break; + } + + mutex_unlock(&pDrv2605data->lock); + + return len; +} + + +static struct file_operations fops = +{ + .open = dev2605_open, + .read = dev2605_read, + .write = dev2605_write, +}; + +//add by shankai +void drv2605_suspend(struct device *dev){ + struct drv2605_data *pDrv2605data = dev_get_drvdata(dev); + + pDrv2605data->should_stop = YES; + hrtimer_cancel(&pDrv2605data->timer); + cancel_work_sync(&pDrv2605data->vibrator_work); + + mutex_lock(&pDrv2605data->lock); + + drv2605_stop(pDrv2605data); + if(pDrv2605data->audio_haptics_enabled == YES){ + wake_unlock(&pDrv2605data->wklock); + } + mutex_unlock(&pDrv2605data->lock); + return ; +} + +void drv2605_resume(struct device *dev) { + struct drv2605_data *pDrv2605data = dev_get_drvdata(dev); + mutex_lock(&pDrv2605data->lock); + if(pDrv2605data->audio_haptics_enabled == YES){ + wake_lock(&pDrv2605data->wklock); + setAudioHapticsEnabled(pDrv2605data, YES); + } + mutex_unlock(&pDrv2605data->lock); + return ; + } +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct drv2605_data *pDrv2605data = container_of(self, struct drv2605_data, fb_notif); + + + if (evdata && evdata->data && event == FB_EVENT_BLANK && + pDrv2605data && pDrv2605data->client) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) + drv2605_resume(&pDrv2605data->client->dev); + else if (*blank == FB_BLANK_POWERDOWN) + drv2605_suspend(&pDrv2605data->client->dev); + } + return 0; +} +#elif defined(CONFIG_HAS_EARLYSUSPEND) +void drv2605_early_suspend(struct early_suspend *h){ + struct drv2605_data *pDrv2605data = container_of(h, struct drv2605_data, early_suspend); + drv2605_suspend(&pDrv2605data->client->dev); + + return ; +} + +void drv2605_late_resume(struct early_suspend *h) { + struct drv2605_data *pDrv2605data = container_of(h, struct drv2605_data, early_suspend); + + drv2605_resume(&pDrv2605data->client->dev); + return ; + } +#endif + + +static int Haptics_init(struct drv2605_data *pDrv2605data) +{ + int reval = -ENOMEM; + + pDrv2605data->version = MKDEV(0,0); + reval = alloc_chrdev_region(&pDrv2605data->version, 0, 1, HAPTICS_DEVICE_NAME); + if (reval < 0) + { + printk(KERN_ALERT"drv2605: error getting major number %d\n", reval); + goto fail0; + } + + pDrv2605data->class = class_create(THIS_MODULE, HAPTICS_DEVICE_NAME); + if (!pDrv2605data->class) + { + printk(KERN_ALERT"drv2605: error creating class\n"); + goto fail1; + } + + pDrv2605data->device = device_create(pDrv2605data->class, NULL, pDrv2605data->version, NULL, HAPTICS_DEVICE_NAME); + if (!pDrv2605data->device) + { + printk(KERN_ALERT"drv2605: error creating device 2605\n"); + goto fail2; + } + + cdev_init(&pDrv2605data->cdev, &fops); + pDrv2605data->cdev.owner = THIS_MODULE; + pDrv2605data->cdev.ops = &fops; + reval = cdev_add(&pDrv2605data->cdev, pDrv2605data->version, 1); + if (reval) + { + printk(KERN_ALERT"drv2605: fail to add cdev\n"); + goto fail3; + } + + pDrv2605data->sw_dev.name = "haptics"; + reval = switch_dev_register(&pDrv2605data->sw_dev); + if (reval < 0) { + printk(KERN_ALERT"drv2605: fail to register switch\n"); + goto fail4; + } + + pDrv2605data->to_dev.name = "vibrator"; + pDrv2605data->to_dev.get_time = vibrator_get_time; + pDrv2605data->to_dev.enable = vibrator_enable; + + if (timed_output_dev_register(&(pDrv2605data->to_dev)) < 0) + { + printk(KERN_ALERT"drv2605: fail to create timed output dev\n"); + goto fail3; + } +#if defined(CONFIG_FB) + pDrv2605data->fb_notif.notifier_call = fb_notifier_callback; + + reval = fb_register_client(&pDrv2605data->fb_notif); + + if (reval) + dev_err(&pDrv2605data->client->dev, "Unable to register fb_notifier: %d\n", + reval); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + pDrv2605data->early_suspend.suspend = drv2605_early_suspend; + pDrv2605data->early_suspend.resume = drv2605_late_resume; + pDrv2605data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1; + register_early_suspend(&pDrv2605data->early_suspend); +#endif + + hrtimer_init(&pDrv2605data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pDrv2605data->timer.function = vibrator_timer_func; + + INIT_WORK(&pDrv2605data->vibrator_work, vibrator_work_routine); + + wake_lock_init(&pDrv2605data->wklock, WAKE_LOCK_SUSPEND, "vibrator"); + mutex_init(&pDrv2605data->lock); + + +/* + +*/ + + + return 0; + +fail4: + switch_dev_unregister(&pDrv2605data->sw_dev); +fail3: + device_destroy(pDrv2605data->class, pDrv2605data->version); +fail2: + class_destroy(pDrv2605data->class); +fail1: + unregister_chrdev_region(pDrv2605data->version, 1); +fail0: + return reval; +} + +static void dev_init_platform_data(struct drv2605_data *pDrv2605data) +{ + struct drv2605_platform_data *pDrv2605Platdata = &pDrv2605data->PlatData; + struct actuator_data actuator = pDrv2605Platdata->actuator; + struct audio2haptics_data a2h = pDrv2605Platdata->a2h; + unsigned char temp = 0; + + drv2605_select_library(pDrv2605data, actuator.g_effect_bank); + + //OTP memory saves data from 0x16 to 0x1a + if(pDrv2605data->OTP == 0) { + if(actuator.rated_vol != 0){ + drv2605_reg_write(pDrv2605data, RATED_VOLTAGE_REG, actuator.rated_vol); + }else{ + printk("%s, ERROR Rated ZERO\n", __FUNCTION__); + } + + if(actuator.over_drive_vol != 0){ + drv2605_reg_write(pDrv2605data, OVERDRIVE_CLAMP_VOLTAGE_REG, actuator.over_drive_vol); + }else{ + printk("%s, ERROR OverDriveVol ZERO\n", __FUNCTION__); + } + + drv2605_set_bits(pDrv2605data, + FEEDBACK_CONTROL_REG, + FEEDBACK_CONTROL_DEVICE_TYPE_MASK, + (actuator.device_type == LRA)?FEEDBACK_CONTROL_MODE_LRA:FEEDBACK_CONTROL_MODE_ERM); + }else{ + printk("%s, OTP programmed\n", __FUNCTION__); + } + + if(pDrv2605Platdata->loop == OPEN_LOOP){ + temp = BIDIR_INPUT_BIDIRECTIONAL; + }else{ + if(pDrv2605Platdata->BIDIRInput == UniDirectional){ + temp = BIDIR_INPUT_UNIDIRECTIONAL; + }else{ + temp = BIDIR_INPUT_BIDIRECTIONAL; + } + } + + if(actuator.device_type == LRA){ + unsigned char DriveTime = 5*(1000 - actuator.LRAFreq)/actuator.LRAFreq; + drv2605_set_bits(pDrv2605data, + Control1_REG, + Control1_REG_DRIVE_TIME_MASK, + DriveTime); + printk("%s, LRA = %d, DriveTime=0x%x\n", __FUNCTION__, actuator.LRAFreq, DriveTime); + } + + drv2605_set_bits(pDrv2605data, + Control2_REG, + Control2_REG_BIDIR_INPUT_MASK, + temp); + + if((pDrv2605Platdata->loop == OPEN_LOOP)&&(actuator.device_type == LRA)) + { + temp = LRA_OpenLoop_Enabled; + } + else if((pDrv2605Platdata->loop == OPEN_LOOP)&&(actuator.device_type == ERM)) + { + temp = ERM_OpenLoop_Enabled; + } + else + { + temp = ERM_OpenLoop_Disable|LRA_OpenLoop_Disable; + } + + if((pDrv2605Platdata->loop == CLOSE_LOOP) &&(pDrv2605Platdata->BIDIRInput == UniDirectional)) + { + temp |= RTP_FORMAT_UNSIGNED; + drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0xff); + } + else + { + if(pDrv2605Platdata->RTPFormat == Signed) + { + temp |= RTP_FORMAT_SIGNED; + drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0x7f); + } + else + { + temp |= RTP_FORMAT_UNSIGNED; + drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0xff); + } + } + drv2605_set_bits(pDrv2605data, + Control3_REG, + Control3_REG_LOOP_MASK|Control3_REG_FORMAT_MASK, + temp); + temp=drv2605_reg_read(pDrv2605data, Control3_REG); + //pr_err("shankai555----Control3_REG value is :%d ---%s:%d\n", temp ,__func__,__LINE__); + drv2605_reg_write(pDrv2605data, Control3_REG, 0xa0); + //pr_err("shankai555----Control3_REG value is :%d ---%s:%d\n", temp ,__func__,__LINE__); + + //for audio to haptics + if(pDrv2605Platdata->GpioTrigger == 0) //not used as external trigger + { + drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MIN_INPUT_REG, a2h.a2h_min_input); + drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MAX_INPUT_REG, a2h.a2h_max_input); + drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MIN_OUTPUT_REG, a2h.a2h_min_output); + drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MAX_OUTPUT_REG, a2h.a2h_max_output); + } +} + + +static int dev_auto_calibrate(struct drv2605_data *pDrv2605data) +{ + int err = 0, status=0; + + #ifdef VENDOR_EDIT + //shankai@bsp 2015-4-4 return 0 for shorten the power up time + return 0; + #endif //VENDOR_EDIT + + drv2605_change_mode(pDrv2605data, WORK_CALIBRATION, DEV_READY); + + drv2605_set_go_bit(pDrv2605data, GO); + // pr_err("shankai555----%s:%d\n" ,__func__,__LINE__); + + /* Wait until the procedure is done */ + drv2605_poll_go_bit(pDrv2605data); + + // pr_err("shankai555----%s:%d\n" ,__func__,__LINE__); + + + /* Read status */ + status = drv2605_reg_read(pDrv2605data, STATUS_REG); + + pr_err("%s, calibration status =0x%x\n", __FUNCTION__, status); + + /* Read calibration results */ + drv2605_reg_read(pDrv2605data, AUTO_CALI_RESULT_REG); + drv2605_reg_read(pDrv2605data, AUTO_CALI_BACK_EMF_RESULT_REG); + drv2605_reg_read(pDrv2605data, FEEDBACK_CONTROL_REG); + + return err; +} + +static struct regmap_config drv2605_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_NONE, +}; +#ifdef CONFIG_OF + +static int drv2605_parse_dt(struct device *dev, + struct drv2605_platform_data *pDrv2605Platdata) +{ + int rc; + u32 temp_val; + struct device_node *np = dev->of_node; + + /* reset, irq gpio info */ + + pDrv2605Platdata->GpioEnable = of_get_named_gpio_flags(np, "drv2605,enable-gpio", + 0, NULL); + if (pDrv2605Platdata->GpioEnable < 0) + return pDrv2605Platdata->GpioEnable; + + rc = of_property_read_u32(np, "BIDIRInput", &temp_val); + if (!rc) + pDrv2605Platdata->BIDIRInput = temp_val; + else + pDrv2605Platdata->BIDIRInput =0; + + + rc = of_property_read_u32(np, "loop", &temp_val); + if (!rc) + pDrv2605Platdata->loop = temp_val; + else + pDrv2605Platdata->loop =0; + + + + rc = of_property_read_u32(np, "RTPFormat", &temp_val); + if (!rc) + pDrv2605Platdata->RTPFormat = temp_val; + else + pDrv2605Platdata->RTPFormat=0; + + + rc = of_property_read_u32(np, "actuator.device_type", &temp_val); + if (!rc) + pDrv2605Platdata->actuator.device_type = temp_val; + else + pDrv2605Platdata->actuator.device_type =0; + + + + + rc = of_property_read_u32(np, "actuator.rated_vol", &temp_val); + if (!rc) + pDrv2605Platdata->actuator.rated_vol = temp_val; + else + pDrv2605Platdata->actuator.rated_vol =0; + + + + rc = of_property_read_u32(np, "actuator.g_effect_bank", &temp_val); + if (!rc) + pDrv2605Platdata->actuator.g_effect_bank= temp_val; + else + pDrv2605Platdata->actuator.g_effect_bank =0; + + + rc = of_property_read_u32(np, "actuator.over_drive_vol", &temp_val); + if (!rc) + pDrv2605Platdata->actuator.over_drive_vol = temp_val; + else + pDrv2605Platdata->actuator.over_drive_vol=0; + + + rc = of_property_read_u32(np, "actuator.LRAFreq", &temp_val); + if (!rc) + pDrv2605Platdata->actuator.LRAFreq = temp_val; + else + pDrv2605Platdata->actuator.LRAFreq=0; + + + + rc = of_property_read_u32(np, "a2h.a2h_min_input", &temp_val); + if (!rc) + pDrv2605Platdata->a2h.a2h_min_input = temp_val; + else + pDrv2605Platdata->a2h.a2h_min_input =0; + + + rc = of_property_read_u32(np, "a2h.a2h_max_input", &temp_val); + if (!rc) + pDrv2605Platdata->a2h.a2h_max_input = temp_val; + else + pDrv2605Platdata->a2h.a2h_max_input =0; + + + + + rc = of_property_read_u32(np, "a2h.a2h_min_output", &temp_val); + if (!rc) + pDrv2605Platdata->a2h.a2h_min_output = temp_val; + else + pDrv2605Platdata->a2h.a2h_min_output =0; + + + rc = of_property_read_u32(np, "a2h.a2h_max_output", &temp_val); + if (!rc) + pDrv2605Platdata->a2h.a2h_max_output = temp_val; + else + pDrv2605Platdata->a2h.a2h_max_output =0; + + + return 0; +} +#else +static int drv2605_parse_dt(struct device *dev, + struct drv2605_platform_data *pDrv2605Platdata) +{ + return -ENODEV; +} +#endif +static int drv2605_probe(struct i2c_client* client, const struct i2c_device_id* id) +{ + struct drv2605_data *pDrv2605data; + struct drv2605_platform_data *pDrv2605Platdata = client->dev.platform_data; + + int err = 0; + int status = 0; + + + if (client->dev.of_node) { + pDrv2605Platdata = devm_kzalloc(&client->dev, sizeof(struct drv2605_platform_data), GFP_KERNEL); + if (pDrv2605Platdata == NULL){ + printk(KERN_ERR"%s:no memory\n", __FUNCTION__); + return -ENOMEM; + } + err = drv2605_parse_dt(&client->dev, pDrv2605Platdata); + if (err) { + dev_err(&client->dev, "DT parsing failed\n"); + return err; + } + } else + pDrv2605Platdata = client->dev.platform_data; + + if (!pDrv2605Platdata) { + dev_err(&client->dev, "Invalid pdata\n"); + return -EINVAL; + } + + pDrv2605data = devm_kzalloc(&client->dev, + sizeof(struct drv2605_data), GFP_KERNEL); + if (!pDrv2605data) { + dev_err(&client->dev, "Not enough memory\n"); + return -ENOMEM; + } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + { + printk(KERN_ERR"%s:I2C check failed\n", __FUNCTION__); + return -ENODEV; + } + + + + pDrv2605data->regmap = devm_regmap_init_i2c(client, &drv2605_i2c_regmap); + if (IS_ERR(pDrv2605data->regmap)) { + err = PTR_ERR(pDrv2605data->regmap); + printk(KERN_ERR"%s:Failed to allocate register map: %d\n",__FUNCTION__,err); + return err; + } + pDrv2605data->client = client; + memcpy(&pDrv2605data->PlatData, pDrv2605Platdata, sizeof(struct drv2605_platform_data)); + i2c_set_clientdata(client,pDrv2605data); + + if(pDrv2605data->PlatData.GpioTrigger){ + err = gpio_request(pDrv2605data->PlatData.GpioTrigger,HAPTICS_DEVICE_NAME"Trigger"); + if(err < 0){ + printk(KERN_ERR"%s: GPIO request Trigger error\n", __FUNCTION__); + goto exit_gpio_request_failed; + } + } + + if(pDrv2605data->PlatData.GpioEnable){ + err = gpio_request(pDrv2605data->PlatData.GpioEnable,HAPTICS_DEVICE_NAME"Enable"); + if(err < 0){ + printk(KERN_ERR"%s: GPIO request enable error\n", __FUNCTION__); + goto exit_gpio_request_failed; + } + + /* Enable power to the chip */ + gpio_direction_output(pDrv2605data->PlatData.GpioEnable, 1); + + /* Wait 30 us */ + udelay(30); + } +//¶ÁÈ¡¼Ä´æÆ÷ + err = drv2605_reg_read(pDrv2605data, STATUS_REG); + if(err < 0){ + printk("%s, i2c bus fail (%d)\n", __FUNCTION__, err); + goto exit_gpio_request_failed; + }else{ + printk("%s, i2c status (0x%x)\n", __FUNCTION__, err); + status = err; + } + /* Read device ID */ + pDrv2605data->device_id = (status & DEV_ID_MASK); + switch (pDrv2605data->device_id) + { + case DRV2605_VER_1DOT1: + printk("drv2605 driver found: drv2605 v1.1.\n"); + break; + case DRV2605_VER_1DOT0: + printk("drv2605 driver found: drv2605 v1.0.\n"); + break; + case DRV2604: + printk(KERN_ALERT"drv2605 driver found: drv2604.\n"); + break; + default: + printk(KERN_ERR"drv2605 driver found: unknown.\n"); + break; + } + + if((pDrv2605data->device_id != DRV2605_VER_1DOT1) + &&(pDrv2605data->device_id != DRV2605_VER_1DOT0)){ + printk("%s, status(0x%x),device_id(%d) fail\n", + __FUNCTION__, status, pDrv2605data->device_id); + goto exit_gpio_request_failed; + } + + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY); + schedule_timeout_interruptible(msecs_to_jiffies(STANDBY_WAKE_DELAY)); + + pDrv2605data->OTP = drv2605_reg_read(pDrv2605data, AUTOCAL_MEM_INTERFACE_REG) & AUTOCAL_MEM_INTERFACE_REG_OTP_MASK; + + dev_init_platform_data(pDrv2605data); + //pr_err("shankai555---pDrv2605data->OTP :%d\n",pDrv2605data->OTP); + if(pDrv2605data->OTP == 0){ + //pr_err("shankai555---pDrv2605data->OTP :%d\n",pDrv2605data->OTP); + err = dev_auto_calibrate(pDrv2605data); + if(err < 0){ + pr_err("%s, ERROR, calibration fail\n", __FUNCTION__); + } + } + + /* Put hardware in standby */ + drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); + + Haptics_init(pDrv2605data); + + + + + + + pDRV2605data = pDrv2605data; + printk("drv2605 probe succeeded\n"); + return 0; + +exit_gpio_request_failed: + if(pDrv2605data->PlatData.GpioTrigger){ + gpio_free(pDrv2605data->PlatData.GpioTrigger); + } + + if(pDrv2605data->PlatData.GpioEnable){ + gpio_free(pDrv2605data->PlatData.GpioEnable); + } + + printk(KERN_ERR"%s failed, err=%d\n",__FUNCTION__, err); + return err; +} + +static int drv2605_remove(struct i2c_client* client) +{ + struct drv2605_data *pDrv2605data = i2c_get_clientdata(client); + + device_destroy(pDrv2605data->class, pDrv2605data->version); + class_destroy(pDrv2605data->class); + unregister_chrdev_region(pDrv2605data->version, 1); + + if(pDrv2605data->PlatData.GpioTrigger) + gpio_free(pDrv2605data->PlatData.GpioTrigger); + + if(pDrv2605data->PlatData.GpioEnable) + gpio_free(pDrv2605data->PlatData.GpioEnable); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&pDrv2605data->early_suspend); +#endif + + printk(KERN_ALERT"drv2605 remove"); + + return 0; +} + +static struct i2c_device_id drv2605_id_table[] = +{ + {HAPTICS_DEVICE_NAME, 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, drv2605_id_table); + + +static struct of_device_id drv2605_of_match_table[] = { + { .compatible = "ti,drv2605",}, + { }, +}; + + + +static struct i2c_driver drv2605_driver = +{ + .driver = { + .name = HAPTICS_DEVICE_NAME, + .owner = THIS_MODULE, + .of_match_table = drv2605_of_match_table, + }, + .id_table = drv2605_id_table, + .probe = drv2605_probe, + .remove = drv2605_remove, +}; + +static int __init drv2605_init(void) +{ + + return i2c_add_driver(&drv2605_driver); +} + +static void __exit drv2605_exit(void) +{ + i2c_del_driver(&drv2605_driver); +} + +module_init(drv2605_init); +module_exit(drv2605_exit); + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("Driver for "HAPTICS_DEVICE_NAME); diff --git a/drivers/misc/ti_drv2605.h b/drivers/misc/ti_drv2605.h new file mode 100644 index 0000000000000..21cd9416ae84a --- /dev/null +++ b/drivers/misc/ti_drv2605.h @@ -0,0 +1,471 @@ +#ifndef __DRV2605_H__ +#define __DRV2605_H__ +/* +** ============================================================================= +** Copyright (c)2014 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +** File: +** drv2605.h +** +** Description: +** Header file for drv2605.c +** +** ============================================================================= +*/ + +#include +#include +#include +#include +#include <../../../drivers/staging/android/timed_output.h> +#include +#include +#include +#include +#if defined(CONFIG_FB) +#include +#include + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include + +#endif + +#define HAPTICS_DEVICE_NAME "drv2605" + +#define LIBRARY_A 0x01 +#define LIBRARY_B 0x02 +#define LIBRARY_C 0x03 +#define LIBRARY_D 0x04 +#define LIBRARY_E 0x05 +#define LIBRARY_F 0x06 + +//#define GO_BIT_POLL_INTERVAL 15 +#define GO_BIT_POLL_INTERVAL 100 +#define STANDBY_WAKE_DELAY 1 +#define WAKE_STANDBY_DELAY 3 + +/* Commands */ +#define HAPTIC_CMDID_PLAY_SINGLE_EFFECT 0x01 +#define HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE 0x02 +#define HAPTIC_CMDID_PLAY_TIMED_EFFECT 0x03 +#define HAPTIC_CMDID_GET_DEV_ID 0x04 +#define HAPTIC_CMDID_RUN_DIAG 0x05 +#define HAPTIC_CMDID_AUDIOHAPTIC_ENABLE 0x06 +#define HAPTIC_CMDID_AUDIOHAPTIC_DISABLE 0x07 +#define HAPTIC_CMDID_AUDIOHAPTIC_GETSTATUS 0x08 + +#define HAPTIC_CMDID_REG_WRITE 0x09 +#define HAPTIC_CMDID_REG_READ 0x0a +#define HAPTIC_CMDID_REG_SETBIT 0x0b + +#define HAPTIC_CMDID_PATTERN_RTP 0x0c +#define HAPTIC_CMDID_RTP_SEQUENCE 0x0d +#define HAPTIC_CMDID_GET_EFFECT_COUNT 0x10 +#define HAPTIC_CMDID_UPDATE_FIRMWARE 0x11 +#define HAPTIC_CMDID_READ_FIRMWARE 0x12 +#define HAPTIC_CMDID_STOP 0xFF + +/* +** Go +*/ +#define GO_REG 0x0C +#define GO_MASK 0x01 +#define GO 0x01 +#define STOP 0x00 + +/* +** Status +*/ +#define STATUS_REG 0x00 +#define STATUS_DEFAULT 0x00 + +#define DIAG_RESULT_MASK (1 << 3) +#define AUTO_CAL_PASSED (0 << 3) +#define AUTO_CAL_FAILED (1 << 3) +#define DIAG_GOOD (0 << 3) +#define DIAG_BAD (1 << 3) + +#define DEV_ID_MASK (7 << 5) + +#define DRV2605_VER_1DOT1 (3 << 5) +#define DRV2605_VER_1DOT0 (5 << 5) +#define DRV2604 (4 << 5) +#define DRV2604L (6 << 5) +#define DRV2605L (7 << 5) + +/* +** Mode +*/ +#define MODE_REG 0x01 +#define MODE_STANDBY_MASK 0x40 +#define MODE_STANDBY 0x40 +#define MODE_RESET 0x80 +#define DRV2605_MODE_MASK 0x07 +#define MODE_INTERNAL_TRIGGER 0 +#define MODE_EXTERNAL_TRIGGER_EDGE 1 +#define MODE_EXTERNAL_TRIGGER_LEVEL 2 +#define MODE_PWM_OR_ANALOG_INPUT 3 +#define MODE_AUDIOHAPTIC 4 +#define MODE_REAL_TIME_PLAYBACK 5 +#define MODE_DIAGNOSTICS 6 +#define AUTO_CALIBRATION 7 + +/* +** Real Time Playback +*/ +#define REAL_TIME_PLAYBACK_REG 0x02 + +/* +** Library Selection +*/ +#define LIBRARY_SELECTION_REG 0x03 +#define LIBRARY_SELECTION_DEFAULT 0x00 +#define LIBRARY_SELECTION_HIZ_MASK 0x10 +#define LIBRARY_SELECTION_HIZ_EN 1 +#define LIBRARY_SELECTION_HIZ_DIS 0 + +/* +** Waveform Sequencer +*/ +#define WAVEFORM_SEQUENCER_REG 0x04 +#define WAVEFORM_SEQUENCER_REG2 0x05 +#define WAVEFORM_SEQUENCER_REG3 0x06 +#define WAVEFORM_SEQUENCER_REG4 0x07 +#define WAVEFORM_SEQUENCER_REG5 0x08 +#define WAVEFORM_SEQUENCER_REG6 0x09 +#define WAVEFORM_SEQUENCER_REG7 0x0A +#define WAVEFORM_SEQUENCER_REG8 0x0B +#define WAVEFORM_SEQUENCER_MAX 8 +#define WAVEFORM_SEQUENCER_DEFAULT 0x00 + +/* +** OverDrive Time Offset +*/ +#define OVERDRIVE_TIME_OFFSET_REG 0x0D + +/* +** Sustain Time Offset, postive +*/ +#define SUSTAIN_TIME_OFFSET_POS_REG 0x0E + +/* +** Sustain Time Offset, negative +*/ +#define SUSTAIN_TIME_OFFSET_NEG_REG 0x0F + +/* +** Brake Time Offset +*/ +#define BRAKE_TIME_OFFSET_REG 0x10 + +/* +** Audio to Haptics Control +*/ +#define AUDIO_HAPTICS_CONTROL_REG 0x11 + +#define AUDIO_HAPTICS_RECT_10MS (0 << 2) +#define AUDIO_HAPTICS_RECT_20MS (1 << 2) +#define AUDIO_HAPTICS_RECT_30MS (2 << 2) +#define AUDIO_HAPTICS_RECT_40MS (3 << 2) + +#define AUDIO_HAPTICS_FILTER_100HZ 0 +#define AUDIO_HAPTICS_FILTER_125HZ 1 +#define AUDIO_HAPTICS_FILTER_150HZ 2 +#define AUDIO_HAPTICS_FILTER_200HZ 3 + +/* +** Audio to Haptics Minimum Input Level +*/ +#define AUDIO_HAPTICS_MIN_INPUT_REG 0x12 + +/* +** Audio to Haptics Maximum Input Level +*/ +#define AUDIO_HAPTICS_MAX_INPUT_REG 0x13 + +/* +** Audio to Haptics Minimum Output Drive +*/ +#define AUDIO_HAPTICS_MIN_OUTPUT_REG 0x14 + +/* +** Audio to Haptics Maximum Output Drive +*/ +#define AUDIO_HAPTICS_MAX_OUTPUT_REG 0x15 + +/* +** Rated Voltage +*/ +#define RATED_VOLTAGE_REG 0x16 + +/* +** Overdrive Clamp Voltage +*/ +#define OVERDRIVE_CLAMP_VOLTAGE_REG 0x17 + +/* +** Auto Calibrationi Compensation Result +*/ +#define AUTO_CALI_RESULT_REG 0x18 + +/* +** Auto Calibration Back-EMF Result +*/ +#define AUTO_CALI_BACK_EMF_RESULT_REG 0x19 + +/* +** Feedback Control +*/ +#define FEEDBACK_CONTROL_REG 0x1A +#define FEEDBACK_CONTROL_DEVICE_TYPE_MASK 0x80 +#define FEEDBACK_CONTROL_BEMF_ERM_GAIN0 0 // 0.33x +#define FEEDBACK_CONTROL_BEMF_ERM_GAIN1 1 // 1.0x +#define FEEDBACK_CONTROL_BEMF_ERM_GAIN2 2 // 1.8x +#define FEEDBACK_CONTROL_BEMF_ERM_GAIN3 3 // 4.0x + +#define FEEDBACK_CONTROL_BEMF_LRA_GAIN0 0 // 5x +#define FEEDBACK_CONTROL_BEMF_LRA_GAIN1 1 // 10x +#define FEEDBACK_CONTROL_BEMF_LRA_GAIN2 2 // 20x +#define FEEDBACK_CONTROL_BEMF_LRA_GAIN3 3 // 30x + +#define LOOP_RESPONSE_SLOW (0 << 2) +#define LOOP_RESPONSE_MEDIUM (1 << 2) // default +#define LOOP_RESPONSE_FAST (2 << 2) +#define LOOP_RESPONSE_VERY_FAST (3 << 2) + +#define FB_BRAKE_FACTOR_1X (0 << 4) // 1x +#define FB_BRAKE_FACTOR_2X (1 << 4) // 2x +#define FB_BRAKE_FACTOR_3X (2 << 4) // 3x (default) +#define FB_BRAKE_FACTOR_4X (3 << 4) // 4x +#define FB_BRAKE_FACTOR_6X (4 << 4) // 6x +#define FB_BRAKE_FACTOR_8X (5 << 4) // 8x +#define FB_BRAKE_FACTOR_16X (6 << 4) // 16x +#define FB_BRAKE_DISABLED (7 << 4) + +#define FEEDBACK_CONTROL_MODE_ERM 0 // default +#define FEEDBACK_CONTROL_MODE_LRA (1 << 7) + +/* +** Control1 +*/ +#define Control1_REG 0x1B +#define Control1_REG_AC_COUPLE_MASK 0x20 +#define Control1_REG_DRIVE_TIME_MASK 0x1f + +#define STARTUP_BOOST_ENABLED (1 << 7) +#define STARTUP_BOOST_DISABLED (0 << 7) // default +#define AC_COUPLE_ENABLED (1 << 5) +#define AC_COUPLE_DISABLED (0 << 5) // default + +#define DEFAULT_DRIVE_TIME 0x13 +#define AUDIOHAPTIC_DRIVE_TIME 0x13 + +/* +** Control2 +*/ +#define Control2_REG 0x1C +#define Control2_REG_BIDIR_INPUT_MASK 0x80 + +#define BIDIR_INPUT_UNIDIRECTIONAL (0<<7) +#define BIDIR_INPUT_BIDIRECTIONAL (1<<7) +#define IDISS_TIME_MASK 0x03 +#define IDISS_TIME_VERY_SHORT 0 +#define IDISS_TIME_SHORT 1 +#define IDISS_TIME_MEDIUM 2 // default +#define IDISS_TIME_LONG 3 + +#define BLANKING_TIME_MASK 0x0C +#define BLANKING_TIME_VERY_SHORT (0 << 2) +#define BLANKING_TIME_SHORT (1 << 2) +#define BLANKING_TIME_MEDIUM (2 << 2) // default +#define BLANKING_TIME_VERY_LONG (3 << 2) + +#define AUTO_RES_GAIN_MASK 0x30 +#define AUTO_RES_GAIN_VERY_LOW (0 << 4) +#define AUTO_RES_GAIN_LOW (1 << 4) +#define AUTO_RES_GAIN_MEDIUM (2 << 4) // default +#define AUTO_RES_GAIN_HIGH (3 << 4) + +#define SOFT_BRAKE_MASK 0x40 + +#define BIDIR_INPUT_MASK 0x80 +#define UNIDIRECT_INPUT (0 << 7) +#define BRAKE_STABLIZER (1<<6) +#define BIDIRECT_INPUT (1 << 7) // default + +/* +** Control3 +*/ +#define Control3_REG 0x1D +#define Control3_REG_LOOP_MASK 0x21 +#define Control3_REG_PWMANALOG_MASK 0x02 +#define Control3_REG_FORMAT_MASK 0x08 +#define INPUT_PWM (0 << 1) // default +#define INPUT_ANALOG (1 << 1) +#define ERM_OpenLoop_Enabled (1 << 5) +#define ERM_OpenLoop_Disable (0 << 5) +#define LRA_OpenLoop_Enabled (1 << 0) +#define LRA_OpenLoop_Disable (0 << 0) +#define RTP_FORMAT_SIGNED (0 << 3) +#define RTP_FORMAT_UNSIGNED (1 << 3) +#define NG_Thresh_DISABLED (0 << 6) +#define NG_Thresh_1 (1 << 6) +#define NG_Thresh_2 (2 << 6) +#define NG_Thresh_3 (3 << 6) + +/* +** Auto Calibration Memory Interface +*/ +#define AUTOCAL_MEM_INTERFACE_REG 0x1E +#define AUTOCAL_MEM_INTERFACE_REG_OTP_MASK 0x04 + +#define AUTOCAL_TIME_150MS (0 << 4) +#define AUTOCAL_TIME_250MS (1 << 4) +#define AUTOCAL_TIME_500MS (2 << 4) +#define AUTOCAL_TIME_1000MS (3 << 4) + +#define SILICON_REVISION_REG 0x3B +#define SILICON_REVISION_MASK 0x07 + +//reset values +#define AUDIO_HAPTICS_MIN_INPUT_VOLTAGE 0x19 +#define AUDIO_HAPTICS_MAX_INPUT_VOLTAGE 0xff +#define AUDIO_HAPTICS_MIN_OUTPUT_VOLTAGE 0x19 +#define AUDIO_HAPTICS_MAX_OUTPUT_VOLTAGE 0xFF + +#define MAX_TIMEOUT 10000 /* 10s */ +#define MAX_READ_BYTES 0xff + +#define SW_STATE_IDLE 0x00 +#define SW_STATE_AUDIO2HAPTIC 0x01 +#define SW_STATE_SEQUENCE_PLAYBACK 0x02 +#define SW_STATE_RTP_PLAYBACK 0x05 + +#define DEV_IDLE 0 // default +#define DEV_STANDBY 1 +#define DEV_READY 2 + +#define WORK_IDLE 0x00 +#define WORK_AUDIO2HAPTIC 0x05 +#define WORK_RTP 0x06 +#define WORK_CALIBRATION 0x07 +#define WORK_VIBRATOR 0x08 +#define WORK_PATTERN_RTP_ON 0x09 +#define WORK_PATTERN_RTP_OFF 0x0a +#define WORK_SEQ_RTP_ON 0x0b +#define WORK_SEQ_RTP_OFF 0x0c +#define WORK_SEQ_PLAYBACK 0x0d + +#define YES 1 +#define NO 0 + +enum actuator_type { + ERM, + LRA +}; + +enum loop_type { + OPEN_LOOP, + CLOSE_LOOP +}; + +enum RTP_Format { + Signed, + Unsigned +}; + +enum BIDIR_Input { + UniDirectional, + BiDirectional +}; + +struct actuator_data { + enum actuator_type device_type; + unsigned char g_effect_bank; + unsigned char rated_vol; + unsigned char over_drive_vol; + unsigned char LRAFreq; +}; + +struct audio2haptics_data { + unsigned char a2h_min_input; + unsigned char a2h_max_input; + unsigned char a2h_min_output; + unsigned char a2h_max_output; +}; + +struct drv2605_platform_data { + int GpioEnable; + int GpioTrigger; + enum loop_type loop; + enum RTP_Format RTPFormat; + enum BIDIR_Input BIDIRInput; + struct actuator_data actuator; + struct audio2haptics_data a2h; +}; + +#define MAX_RTP_SEQ 16 + +struct RTP_Seq{ + unsigned short RTPData[MAX_RTP_SEQ]; //RTPTime<<8||RTPAmp + int RTPCounts; + int RTPindex; +}; + +struct drv2605_data { + struct drv2605_platform_data PlatData; + int device_id; + struct i2c_client *client; + struct regmap *regmap; + + struct class* class; + struct device* device; + dev_t version; + struct semaphore sem; + struct cdev cdev; + struct switch_dev sw_dev; + volatile int audio_haptics_enabled; + volatile int vibrator_is_playing; + char ReadBuff[MAX_READ_BYTES]; + int ReadLen; + + int vibration_time; + int silience_time; + char repeat_times; + volatile char work_mode; + char dev_mode; + + struct RTP_Seq RTPSeq; + + int OTP; + + struct wake_lock wklock; + struct hrtimer timer; + struct mutex lock; + struct work_struct vibrator_work; + unsigned char sequence[WAVEFORM_SEQUENCER_MAX]; + volatile int should_stop; + struct timed_output_dev to_dev; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif +}; + +#endif diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index d0773bed7301a..d85885b7f401b 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "core.h" #include "bus.h" @@ -72,13 +73,13 @@ static const struct mmc_fixup mmc_fixups[] = { END_FIXUP }; - /* * Given the decoded CSD structure, decode the raw CID to our CID structure. */ static int mmc_decode_cid(struct mmc_card *card) { u32 *resp = card->raw_cid; + char *manufactureid; /* * The selection of the format here is based upon published @@ -124,6 +125,27 @@ static int mmc_decode_cid(struct mmc_card *card) mmc_hostname(card->host), card->csd.mmca_vsn); return -EINVAL; } +#ifdef VENDOR_EDIT + //push emmc card information, added by liwei + if(!strncmp(mmc_hostname(card->host),"mmc0",4)){ + switch(card->cid.manfid){ + case 0x11: + manufactureid = "TOSHIBA"; + break; + case 0x15: + manufactureid = "SAMSUNG"; + break; + case 0x45: + manufactureid = "SANDISK"; + break; + default: + manufactureid = "unknown"; + break; + } + push_component_info(EMMC, manufactureid, card->cid.prod_name); + } + //end by liwei for pushing emmc card information +#endif /*VENDOR_EDIT*/ return 0; } diff --git a/drivers/net/wireless/cnss/cnss.c b/drivers/net/wireless/cnss/cnss.c index 8e033df0ab238..2fc97ab088e05 100644 --- a/drivers/net/wireless/cnss/cnss.c +++ b/drivers/net/wireless/cnss/cnss.c @@ -48,6 +48,14 @@ #include #include +//#ifdef VENDOR_EDIT +#include +#include +static u32 fw_version; +static uint evmFlag = 0; +//#endif /* VENDOR_EDIT */ + + #define subsys_to_drv(d) container_of(d, struct cnss_data, subsys_desc) #define VREG_ON 1 @@ -92,6 +100,12 @@ static struct cnss_fw_files FW_FILES_QCA6174_FW_1_3 = { static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = { "qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin", "utfbd30.bin", "epping30.bin", "evicted30.bin"}; +//#ifdef VENDOR_EDIT +/* Only for evm chip */ +static struct cnss_fw_files FW_FILES_QCA6174_FW_3_1 = { +"qwlan30.bin", "bdwlan31.bin", "otp30.bin", "utf30.bin", +"utfbd30.bin", "epping30.bin", "evicted30.bin"}; +//#endif /* VENDOR_EDIT */ static struct cnss_fw_files FW_FILES_DEFAULT = { "qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin", "utfbd.bin", "epping.bin", "evicted.bin"}; @@ -813,8 +827,17 @@ void cnss_setup_fw_files(u16 revision) case QCA6174_FW_3_2: strlcpy(penv->fw_files.image_file, "qwlan30.bin", CNSS_MAX_FILE_NAME); - strlcpy(penv->fw_files.board_data, "bdwlan30.bin", - CNSS_MAX_FILE_NAME); + //#ifdef VENDOR_EDIT + /* Only for evm chip */ + if (evmFlag == 1) { + pr_info("cnss boarddata 31"); + strlcpy(penv->fw_files.board_data, "bdwlan31.bin", + CNSS_MAX_FILE_NAME); + } else { + strlcpy(penv->fw_files.board_data, "bdwlan30.bin", + CNSS_MAX_FILE_NAME); + } + //#endif /* VENDOR_EDIT */ strlcpy(penv->fw_files.otp_data, "otp30.bin", CNSS_MAX_FILE_NAME); strlcpy(penv->fw_files.utf_file, "utf30.bin", @@ -868,7 +891,15 @@ int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, break; case AR6320_REV3_VERSION: case AR6320_REV3_2_VERSION: - memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files)); + //#ifdef VENDOR_EDIT + /* Only for evm chip */ + if (evmFlag == 1) { + pr_info("evm FW_FILES_QCA6174_FW_3_1"); + memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_1, sizeof(*pfw_files)); + } else { + memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files)); + } + //#endif /* VENDOR_EDIT */ break; default: memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files)); @@ -1188,6 +1219,25 @@ int cnss_get_fw_image(struct image_desc_info *image_desc_info) } EXPORT_SYMBOL(cnss_get_fw_image); +//#ifdef VENDOR_EDIT +/* Initial and show wlan firmware build version */ +void cnss_set_fw_version(u32 version) { + fw_version = version; +} +EXPORT_SYMBOL(cnss_set_fw_version); + +static ssize_t cnss_version_information_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (!penv) + return -ENODEV; + return scnprintf(buf, PAGE_SIZE, "%u\n", fw_version); +} + +static DEVICE_ATTR(cnss_version_information, 0444, + cnss_version_information_show, NULL); +//#endif /* VENDOR_EDIT */ + static ssize_t wlan_setup_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1240,6 +1290,11 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, break; case QCA6174_DEVICE_ID: + //#ifdef VENDOR_EDIT + /* Only for evm chip */ + get_param_nvm_boarddata(&evmFlag); + pr_info("cnss evmFlag = %u\n", evmFlag); + //#endif /* VENDOR_EDIT */ pci_read_config_word(pdev, QCA6174_REV_ID_OFFSET, &penv->revision_id); cnss_setup_fw_files(penv->revision_id); @@ -1282,6 +1337,14 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev, pr_err("Can't Create Device file\n"); goto err_pcie_suspend; } + //#ifdef VENDOR_EDIT + /* Create device file */ + ret = device_create_file(&penv->pldev->dev, &dev_attr_cnss_version_information); + if (ret) { + pr_err("Can't Create Device file\n"); + goto err_pcie_suspend; + } + //#endif /* VENDOR_EDIT */ if (cnss_wlan_is_codeswap_supported(penv->revision_id)) { pr_debug("Code-swap not enabled: %d\n", penv->revision_id); @@ -1331,6 +1394,9 @@ static void cnss_wlan_pci_remove(struct pci_dev *pdev) return; dev = &penv->pldev->dev; + //#ifdef VENDOR_EDIT + device_remove_file(dev, &dev_attr_cnss_version_information); + //#endif /* VENDOR_EDIT */ device_remove_file(dev, &dev_attr_wlan_setup); } @@ -2564,6 +2630,12 @@ static int cnss_probe(struct platform_device *pdev) pr_err("cnss: fw_image_setup sys file creation failed\n"); goto err_bus_reg; } + + //#ifdef VENDOR_EDIT + /* product information */ + push_component_info(WCN, "QCA6164A", "QualComm"); + //#endif /* VENDOR_EDIT */ + pr_info("cnss: Platform driver probed successfully.\n"); return ret; diff --git a/drivers/oem_debug/Kconfig b/drivers/oem_debug/Kconfig new file mode 100644 index 0000000000000..c9162dc14adab --- /dev/null +++ b/drivers/oem_debug/Kconfig @@ -0,0 +1,10 @@ +#add by jiachenghui for support oem trace,2015/05/09 + +config OEM_TRACE_SUPORT + default y + depends on OEM_DEBUG_SUPORT + bool "OEM debug function, enable it will register the device, which under /dev/otracer." + +config OEM_FORCE_DUMP + default y + bool "OEM force dump function, it will enable goto the force dump" diff --git a/drivers/oem_debug/Makefile b/drivers/oem_debug/Makefile new file mode 100644 index 0000000000000..b0e1241740c77 --- /dev/null +++ b/drivers/oem_debug/Makefile @@ -0,0 +1,8 @@ +#add by jiachenghui for support oem trace,2015/05/09 +ifdef CONFIG_OEM_DEBUG_SUPORT +# oem trace +obj-$(CONFIG_OEM_TRACE_SUPORT) += oem_trace.o + +obj-$(CONFIG_OEM_FORCE_DUMP) += oem_force_dump.o + +endif diff --git a/drivers/oem_debug/oem_force_dump.c b/drivers/oem_debug/oem_force_dump.c new file mode 100644 index 0000000000000..ce38806f1277b --- /dev/null +++ b/drivers/oem_debug/oem_force_dump.c @@ -0,0 +1,82 @@ +/* + * oem_force_dump.c + * + * drivers supporting debug functions for Oneplus device. + * + * hefaxi@filesystems, 2015/07/03. + */ +#include +#include + +extern int oem_get_download_mode(void); + +/* + * press the voluemup key and volumedown key, then + * long press volumeup key, and at the same time, + * press twice power key,it will goto the force dump. + */ +void oem_check_force_dump_key(unsigned int code, int value) +{ + static enum { NONE, STEP1, STEP2, STEP3,STEP4, + STEP5,STEP6,STEP7} state = NONE; + + if(!oem_get_download_mode()) + return ; + + //printk(KERN_INFO "%s code %d value %d state %d\n",__func__,code,value,state); + switch(state){ + case NONE: + if(code == KEY_VOLUMEUP && value){ + state = STEP1; + }else{ + state = NONE; + } + break; + case STEP1: + if(code == KEY_VOLUMEUP && !value){ + state = STEP2; + }else{ + state = NONE; + } + break; + case STEP2: + if(code == KEY_VOLUMEDOWN && value){ + state = STEP3; + }else{ + state = NONE; + } + break; + case STEP3: + if(code == KEY_VOLUMEDOWN && !value){ + state = STEP4; + }else{ + state = NONE; + } + break; + case STEP4: + if(code == KEY_VOLUMEUP && value){ + state = STEP5; + }else{ + state = NONE; + } + break; + case STEP5: + if(code == KEY_POWER && value){ + state = STEP6; + }else + state = NONE; + case STEP6: + if(code == KEY_POWER && !value){ + state = STEP7; + }else{ + state = NONE; + } + case STEP7: + if(code == KEY_POWER && value){ + panic("Force Dump"); + }else{ + state = NONE; + } + break; + } +} \ No newline at end of file diff --git a/drivers/oem_debug/oem_trace.c b/drivers/oem_debug/oem_trace.c new file mode 100755 index 0000000000000..4f9b771292e1b --- /dev/null +++ b/drivers/oem_debug/oem_trace.c @@ -0,0 +1,593 @@ +/* + * Copyright (C) 2010 OPPO, Inc. + * Author: Andy + * Merge by jiachenghui for support oem trace,2015/05/09 + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +#include "oem_trace.h" + + +#define IOCTL_OTRACER_TEST (1<<0) +#define IOCTL_OTRACER_STACK (1<<1) +#define IOCTL_OTRACER_MEMINFO (1<<2) +#define IOCTL_OTRACER_TASKINFO (1<<3) +#define IOCTL_OTRACER_ALLINFO (1<<4) +#define IOCTL_OTRACER_TOLCD (1<<5) + +#define IOCTL_OTRACER_PANIC (1<<12) + +struct vmalloc_info { + unsigned long used; + unsigned long largest_chunk; +}; + +#ifdef CONFIG_MMU +#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) +extern void get_vmalloc_info(struct vmalloc_info *vmi); +#endif + + +/* OPPO 2012-10-11 chendx Delete begin for debugtools Todo */ +#if 0 +extern unsigned reboot_reason; +extern void *restart_reason; +#endif +/* OPPO 2012-10-11 chendx Delete end */ + +void backtrace_test_saved(void) +{ + struct stack_trace trace; + unsigned long entries[8]; + + printk("\nThe following trace is a kernel self test and not a bug!\n"); + + trace.nr_entries = 0; + trace.max_entries = ARRAY_SIZE(entries); + trace.entries = entries; + trace.skip = 0; + + printk("Testing a dump_stack.\n"); + dump_stack(); + //printk("Testing a save_stack_trace.\n"); + //save_stack_trace(&trace); + printk("Testing a print_stack_trace.\n"); + print_stack_trace(&trace, 0); +} + +void tasks_mem_get(struct mm_struct *mm, unsigned long *vsize, unsigned long *vrss) +{ + unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; + + hiwater_vm = total_vm = mm->total_vm; + if (hiwater_vm < mm->hiwater_vm) + hiwater_vm = mm->hiwater_vm; + hiwater_rss = total_rss = get_mm_rss(mm); + if (hiwater_rss < mm->hiwater_rss) + hiwater_rss = mm->hiwater_rss; + + *vsize = total_vm << (PAGE_SHIFT-10); + *vrss = total_rss << (PAGE_SHIFT-10); +} + +static const char *task_state_array[] = { + "R-0", /* 0 (running) */ + "S-1", /* 1 (sleeping) */ + "D-2", /* 2 (disk sleep) */ + "T-4", /* 4 (stopped) */ + "T-8", /* 8 (tracing stop) */ + "Z-F", /* 16 (zombie) */ + "X-" /* 32 (dead) */ +}; + +static inline const char *get_task_state(struct task_struct *tsk) +{ + unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state; + const char **p = &task_state_array[0]; + + while (state) { + p++; + state >>= 1; + } + return *p; +} + +void tasks_test_saved(void) +{ + struct task_struct *p; + struct cred *cred =NULL; + struct mm_struct *mm; + unsigned long vsize = 0, vrss = 0; + + printk("\nThe following trace is a kernel tasks test and not a bug!\n"); + + printk("USER\tPID\tVSIZE\tRSS\tSTATE\tNAME\n"); + write_lock_irq(&tasklist_lock); + for_each_process(p) { + + cred = (struct cred *)get_cred((struct cred *) __task_cred(p)); + + vsize = 0; + vrss = 0; + mm = get_task_mm(p); + if (mm) { + tasks_mem_get(mm, &vsize, &vrss); + } + printk("%d\t%d\t%ld\t%ld\t%s\t%s\n", + cred->uid, + task_pid_nr(p), + vsize, + vrss, + get_task_state(p), + p->comm); + } + write_unlock_irq(&tasklist_lock); +} + +void meminfo_test_saved(void) +{ +struct sysinfo i; + unsigned long committed; + unsigned long allowed; + struct vmalloc_info vmi; + long cached; + unsigned long pages[NR_LRU_LISTS]; + int lru; + +/* + * display in kilobytes. + */ +#define K(x) ((x) << (PAGE_SHIFT - 10)) + si_meminfo(&i); + si_swapinfo(&i); + committed = percpu_counter_read_positive(&vm_committed_as); + allowed = ((totalram_pages - hugetlb_total_pages()) + * sysctl_overcommit_ratio / 100) + total_swap_pages; + + cached = global_page_state(NR_FILE_PAGES) - + total_swapcache_pages() - i.bufferram; + if (cached < 0) + cached = 0; + + get_vmalloc_info(&vmi); + + for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++) + pages[lru] = global_page_state(NR_LRU_BASE + lru); + + /* + * Tagged format, for easy grepping and expansion. + */ + printk("Meminfo:\n" + "MemTotal: %8lu kB\n" + "MemFree: %8lu kB\n" + "Buffers: %8lu kB\n" + "Cached: %8lu kB\n" + "SwapCached: %8lu kB\n" + "Active: %8lu kB\n" + "Inactive: %8lu kB\n" + "Active(anon): %8lu kB\n" + "Inactive(anon): %8lu kB\n" + "Active(file): %8lu kB\n" + "Inactive(file): %8lu kB\n" + "Unevictable: %8lu kB\n" + "Mlocked: %8lu kB\n" +#ifdef CONFIG_HIGHMEM + "HighTotal: %8lu kB\n" + "HighFree: %8lu kB\n" + "LowTotal: %8lu kB\n" + "LowFree: %8lu kB\n" +#endif +#ifndef CONFIG_MMU + "MmapCopy: %8lu kB\n" +#endif + "SwapTotal: %8lu kB\n" + "SwapFree: %8lu kB\n" + "Dirty: %8lu kB\n" + "Writeback: %8lu kB\n" + "AnonPages: %8lu kB\n" + "Mapped: %8lu kB\n" + "Shmem: %8lu kB\n" + "Slab: %8lu kB\n" + "SReclaimable: %8lu kB\n" + "SUnreclaim: %8lu kB\n" + "KernelStack: %8lu kB\n" + "PageTables: %8lu kB\n" +#ifdef CONFIG_QUICKLIST + "Quicklists: %8lu kB\n" +#endif + "NFS_Unstable: %8lu kB\n" + "Bounce: %8lu kB\n" + "WritebackTmp: %8lu kB\n" + "CommitLimit: %8lu kB\n" + "Committed_AS: %8lu kB\n" + "VmallocTotal: %8lu kB\n" + "VmallocUsed: %8lu kB\n" + "VmallocChunk: %8lu kB\n" +#ifdef CONFIG_MEMORY_FAILURE + "HardwareCorrupted: %5lu kB\n" +#endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + "AnonHugePages: %8lu kB\n" +#endif + , + K(i.totalram), + K(i.freeram), + K(i.bufferram), + K(cached), + K(total_swapcache_pages()), + K(pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]), + K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]), + K(pages[LRU_ACTIVE_ANON]), + K(pages[LRU_INACTIVE_ANON]), + K(pages[LRU_ACTIVE_FILE]), + K(pages[LRU_INACTIVE_FILE]), + K(pages[LRU_UNEVICTABLE]), + K(global_page_state(NR_MLOCK)), +#ifdef CONFIG_HIGHMEM + K(i.totalhigh), + K(i.freehigh), + K(i.totalram-i.totalhigh), + K(i.freeram-i.freehigh), +#endif +#ifndef CONFIG_MMU + K((unsigned long) atomic_long_read(&mmap_pages_allocated)), +#endif + K(i.totalswap), + K(i.freeswap), + K(global_page_state(NR_FILE_DIRTY)), + K(global_page_state(NR_WRITEBACK)), +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + K(global_page_state(NR_ANON_PAGES) + + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * + HPAGE_PMD_NR), +#else + K(global_page_state(NR_ANON_PAGES)), +#endif + K(global_page_state(NR_FILE_MAPPED)), + K(global_page_state(NR_SHMEM)), + K(global_page_state(NR_SLAB_RECLAIMABLE) + + global_page_state(NR_SLAB_UNRECLAIMABLE)), + K(global_page_state(NR_SLAB_RECLAIMABLE)), + K(global_page_state(NR_SLAB_UNRECLAIMABLE)), + global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024, + K(global_page_state(NR_PAGETABLE)), +#ifdef CONFIG_QUICKLIST + K(quicklist_total_size()), +#endif + K(global_page_state(NR_UNSTABLE_NFS)), + K(global_page_state(NR_BOUNCE)), + K(global_page_state(NR_WRITEBACK_TEMP)), + K(allowed), + K(committed), + (unsigned long)VMALLOC_TOTAL >> 10, + vmi.used >> 10, + vmi.largest_chunk >> 10 +#ifdef CONFIG_MEMORY_FAILURE + ,atomic_long_read(&num_poisoned_pages) << (PAGE_SHIFT - 10) +#endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * + HPAGE_PMD_NR) +#endif + ); +#undef K +} + +#if 0 +extern int oppo_con_write(const unsigned char *buf, int count); +extern void console_activate(void); +#else +int oppo_con_write(const unsigned char *buf, int count) +{ + return 0; +} + +void console_activate(void) +{ + return; +} +#endif + + +static ssize_t otracer_read(struct file *filp, char __user *buf, + size_t size, loff_t *offp) +{ + printk(KERN_INFO "otracer_read: initialized\n"); + return 0; +} + +/* OPPO 2010-11-25 Laijl Modify begin for reason buf overflaot*/ +#if 0 +static ssize_t otracer_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offp) +{ + printk(KERN_INFO "otracer_write: initialized\n"); + if (!count) + return -EIO; + console_activate(); + printk( "otracer_write console_activate pass\n"); + oppo_con_write(buf, count); + printk( "otracer_write oppo_con_write pass\n"); + return count; +} +#else +/* OPPO 2011-03-02 huanggd Add begin for oppo logo display */ +extern int fbcon_takeover_global(int show_logo) ; +/* OPPO 2011-03-02 huanggd Add end */ +/* OPPO 2013-01-30 zhenwx Add begin for modem fatal error enter ramdump */ +#ifdef CONFIG_MODEM_ERR_ENTER_RAMDUMP + bool otrace_on = false; +#else + static bool otrace_on = false; +#endif +/* OPPO 2013-01-30 zhenwx Modify end */ +bool is_otrace_on(void) +{ + return otrace_on; +} +static ssize_t otracer_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offp) +{ + char *kbuf = NULL; + + if(!is_otrace_on()) + return count; + + printk(KERN_INFO "otracer_write \n"); + kbuf = kzalloc( PAGE_SIZE, GFP_KERNEL ); + if(kbuf == NULL) + { + goto end; + } + if (!count) + { + goto free_buf; + } + if( copy_from_user( kbuf, buf, ((count > PAGE_SIZE) ? PAGE_SIZE : count )) ) + { + goto free_buf; + } + oppo_con_write(kbuf, ((count > PAGE_SIZE) ? PAGE_SIZE : count )); + kfree(kbuf); + return count; +free_buf: + kfree(kbuf); +end: + printk( KERN_ERR "otracer_write fail! \n"); + return ( -EFAULT); +} + +#endif +/* OPPO 2010-11-25 Laijl Modify end */ +static long otracer_ioctl(struct file * filp, + unsigned int cmd, unsigned long arg) +{ + unsigned int cmdv = cmd; + int i; + + cmdv = cmd; + + printk(KERN_INFO "otracer_ioctl: initialized. cmd=0x%x\n", cmd); + + /* mwalker give a chance to change reboot result to android for android framework. */ + if (cmd == IOCTL_TRACE_UPDATE_REBOOTFLAG) { + printk (KERN_INFO "android update reboot flag\n"); + +/* OPPO 2012-10-11 chendx Delete begin for debug tools Todo */ +#if 0 + reboot_reason = 0x7766550c; + writel(0x7766550c, restart_reason); +#endif +/* OPPO 2012-10-11 chendx Delete end */ + + goto end; + } + + for(i = 0; i < 16; i++) + { + if(cmdv == 0) + break; + if(cmdv & IOCTL_OTRACER_TOLCD) + { + //console_activate(); + cmdv &= (~IOCTL_OTRACER_TOLCD); + } + if(cmdv & IOCTL_OTRACER_STACK) + { + backtrace_test_saved(); + cmdv &= (~IOCTL_OTRACER_STACK); + } + if(cmdv & IOCTL_OTRACER_MEMINFO) + { + meminfo_test_saved(); + cmdv &= (~IOCTL_OTRACER_MEMINFO); + } + if(cmdv & IOCTL_OTRACER_TASKINFO) + { + tasks_test_saved(); + cmdv &= (~IOCTL_OTRACER_TASKINFO); + } + if(cmdv & IOCTL_OTRACER_ALLINFO) + { + backtrace_test_saved(); + meminfo_test_saved(); + tasks_test_saved(); + cmdv &= (~IOCTL_OTRACER_ALLINFO); + } + if(cmdv & IOCTL_OTRACER_PANIC) + { + pr_info("ioctl panic reboot\n"); + panic("android"); + cmdv &= (~IOCTL_OTRACER_PANIC); + } + + } +end: + return 0; +} +static int otracer_open(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + return nonseekable_open(inode, file); +} +static int otracer_close(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + return 0; +} +static struct file_operations otracer_fops = { + .owner = THIS_MODULE, + .open = otracer_open, + .release = otracer_close, + .read = otracer_read, + .write = otracer_write, + .unlocked_ioctl = otracer_ioctl, +}; + +static struct miscdevice otracer_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "otracer", + .fops = &otracer_fops, +}; +static int otrace_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "\notrace_on:%d\n", is_otrace_on()); + return 0; +} +static int otrace_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, otrace_proc_show, NULL); +} +static ssize_t otrace_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + unsigned char *lbuf; + size_t local_count; + unsigned long val; + + if (count <= 0) + return 0; + +#define LBUFSIZE 1200UL + lbuf = kmalloc(LBUFSIZE, GFP_KERNEL); + if (!lbuf) + return 0; + + local_count = (LBUFSIZE - 1)>count?count:(LBUFSIZE - 1); + if (copy_from_user(lbuf, buffer, local_count) != 0) { + kfree(lbuf); + return -EFAULT; + } + + lbuf[local_count] = '\0'; + val = simple_strtoul(lbuf, NULL, 10); + + if(val == 7978) + otrace_on = true; + else + otrace_on = false; + + pr_info("val:%ld, otrace_on:%d\n", val, otrace_on); + + kfree(lbuf); + return count; +} + + + +static const struct file_operations otrace_proc_fops = { + .owner = THIS_MODULE, + .open = otrace_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = otrace_proc_write, +}; + +static struct proc_dir_entry *otrace_entry; +static int __init otracer_init(void) +{ + int ret; + + ret = misc_register(&otracer_misc); + if (unlikely(ret)) { + printk(KERN_ERR "otracer: failed to register misc device!\n"); + return ret; + } + + /* Set up the proc file system */ + otrace_entry = proc_create("otrace_on", 0666, NULL, &otrace_proc_fops); + if (!otrace_entry) { + ret = -ENOMEM; + goto out_misc; + } + + printk(KERN_INFO "otracer: initialized\n"); + + return 0; +out_misc: + misc_deregister(&otracer_misc); + return ret; +} + +static void __exit otracer_exit(void) +{ + int ret; + + remove_proc_entry("otrace_on", NULL); + + ret = misc_deregister(&otracer_misc); + if (unlikely(ret)) + printk(KERN_ERR "otracer: failed to unregister misc device!\n"); + + printk(KERN_INFO "otracer: exit\n"); +} + +module_init(otracer_init); +module_exit(otracer_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("oem tracer"); +MODULE_AUTHOR("Andy "); + + diff --git a/drivers/oem_debug/oem_trace.h b/drivers/oem_debug/oem_trace.h new file mode 100755 index 0000000000000..d7105943d7466 --- /dev/null +++ b/drivers/oem_debug/oem_trace.h @@ -0,0 +1,10 @@ +/*add by jiachenghui for support oem trace,2015/05/09*/ +#ifndef _OEM_TRACE_H +#define _OEM_TRACE_H + +#include + +#define IOCTL_TRACE_UPDATE_REBOOTFLAG _IO('t', 3) + + +#endif diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c old mode 100644 new mode 100755 index e31816d49c7a7..e8a7690a64168 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include /* for COMMAND_LINE_SIZE */ #include @@ -593,11 +594,28 @@ int __init of_flat_dt_match(unsigned long node, const char *const *compat) return of_fdt_match(initial_boot_params, node, compat); } +static void __init of_flat_dt_get_project_info(void) +{ + const __be32 *prop; + const char *name; + int hw_ver = 0; + + unsigned long dt_root = of_get_flat_dt_root(); + + prop = of_get_flat_dt_prop(dt_root, "qcom,hw-ver", NULL); + if (prop) + hw_ver = be32_to_cpup(prop); + + name = of_get_flat_dt_prop(dt_root, "qcom,product-name", NULL); + pr_info("qcom,product-name: %s hw_ver : %d\n",name,hw_ver); +} + const char * __init of_flat_dt_get_machine_name(void) { const char *name; unsigned long dt_root = of_get_flat_dt_root(); + of_flat_dt_get_project_info(); name = of_get_flat_dt_prop(dt_root, "model", NULL); if (!name) name = of_get_flat_dt_prop(dt_root, "compatible", NULL); @@ -780,6 +798,9 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp) /** * early_init_dt_scan_memory - Look for an parse memory nodes */ +static unsigned long ddr_size = 0; +module_param(ddr_size, ulong, S_IRUGO); +MODULE_PARM_DESC(ddr_size, "ddr size"); int __init early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) { @@ -819,7 +840,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, continue; pr_debug(" - %llx , %llx\n", (unsigned long long)base, (unsigned long long)size); - + ddr_size += size; early_init_dt_add_memory_arch(base, size); } diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c old mode 100644 new mode 100755 index e2bc79f6ba850..f080726450fbb --- a/drivers/of/of_batterydata.c +++ b/drivers/of/of_batterydata.c @@ -330,8 +330,11 @@ struct device_node *of_batterydata_get_best_profile( pr_err("failed to retrieve resistance value rc=%d\n", rc); return ERR_PTR(-ENOSYS); } - - batt_id_kohm = ret.intval / 1000; +#ifdef VENDOR_EDIT + batt_id_kohm = ret.intval ; +#else + batt_id_kohm = ret.intval / 1000; +#endif /* read battery id range percentage for best profile */ rc = of_property_read_u32(batterydata_container_node, @@ -365,8 +368,15 @@ struct device_node *of_batterydata_get_best_profile( if (rc) continue; for (i = 0; i < batt_ids.num; i++) { - delta = abs(batt_ids.kohm[i] - batt_id_kohm); - limit = (batt_ids.kohm[i] * id_range_pct) / 100; +#ifdef VENDOR_EDIT + delta = abs(batt_ids.kohm[i]*1000 - batt_id_kohm); + limit = (batt_ids.kohm[i]*1000 * id_range_pct)/100 ; + +#else + delta = abs(batt_ids.kohm[i] - batt_id_kohm); + limit = (batt_ids.kohm[i] * id_range_pct) / 100; + +#endif in_range = (delta <= limit); /* * Check if the delta is the lowest one @@ -382,11 +392,37 @@ struct device_node *of_batterydata_get_best_profile( } } } +#ifdef VENDOR_EDIT + if (best_node == NULL) { + pr_err("Go to set default battery cure\n"); + for_each_child_of_node(batterydata_container_node, node){ + rc = of_property_read_string(node, "qcom,battery-type", + &battery_type); + if (!rc && strcmp(battery_type, "Unknown Battery") == 0) { + best_node = node; + return best_node; + } + } + } +#else if (best_node == NULL) { pr_err("No battery data found\n"); return best_node; } +#endif +#ifdef VENDOR_EDIT +/* check that profile id is in range of the measured batt_id */ +if (abs(best_id_kohm*1000 - batt_id_kohm) > + ((best_id_kohm*1000 * id_range_pct) / 100)) { + pr_err("out of range: profile id %d batt id %d pct %d", + best_id_kohm, batt_id_kohm, id_range_pct); + return NULL; +} + + +#else + /* check that profile id is in range of the measured batt_id */ if (abs(best_id_kohm - batt_id_kohm) > @@ -395,7 +431,7 @@ struct device_node *of_batterydata_get_best_profile( best_id_kohm, batt_id_kohm, id_range_pct); return NULL; } - +#endif rc = of_property_read_string(best_node, "qcom,battery-type", &battery_type); if (!rc) diff --git a/drivers/param_read_write/Kconfig b/drivers/param_read_write/Kconfig new file mode 100644 index 0000000000000..5527917c67088 --- /dev/null +++ b/drivers/param_read_write/Kconfig @@ -0,0 +1,6 @@ +config PARAM_READ_WRITE + bool "Param partition read/write support" + default n + help + if you want to read/write the param partition in kernel, + then you must say Y here. diff --git a/drivers/param_read_write/Makefile b/drivers/param_read_write/Makefile new file mode 100644 index 0000000000000..0c099c5b06e8b --- /dev/null +++ b/drivers/param_read_write/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PARAM_READ_WRITE) += param_read_write.o diff --git a/drivers/param_read_write/param_read_write.c b/drivers/param_read_write/param_read_write.c new file mode 100755 index 0000000000000..4c7bccf91c5b5 --- /dev/null +++ b/drivers/param_read_write/param_read_write.c @@ -0,0 +1,501 @@ +/* + * drivers/param_read_write/param_read_write.c + * + * hefaxi@filesystems,2015/04/30 + * + * This program is used to read/write param partition in kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define PARAM_PARTITION "/dev/block/bootdevice/by-name/param" +static uint default_param_data_dump_size= DEFAULT_PARAM_DUMP_SIZE; + +typedef struct{ + phys_addr_t paddr; + size_t size; + void *vaddr; + void *buffer; + struct mutex mutex; +}param_ram_zone_t; + +static DEFINE_MUTEX(param_lock); +static bool param_init_done = 0; +static param_ram_zone_t param_ram_zone; + +static int write_param_partition(const char *buf, unsigned long count, + loff_t offset) +{ + struct file *filp; + mm_segment_t fs; + int ret = 0; + + filp = filp_open(PARAM_PARTITION,O_RDWR|O_SYNC,0); + if(IS_ERR(filp)) { + ret = PTR_ERR(filp); + pr_err("open file %s failed.(%d)\n",PARAM_PARTITION,ret); + return ret; + } + + fs = get_fs(); + set_fs(get_ds()); + + ret = filp->f_op->llseek(filp, offset, SEEK_SET); + if(ret < 0){ + pr_err("%s: llseek failed.(%d)\n",__func__,ret); + goto out; + } + ret = filp->f_op->write(filp,(char __user *)buf,count,&filp->f_pos); + +out: + set_fs(fs); + filp_close(filp,NULL); + return ret; +} + +static int get_param_by_index_and_offset(uint32 sid_index, + uint32 offset, void * buf, int length) +{ + int ret = length; + uint32 file_offset; + mutex_lock(¶m_ram_zone.mutex); + pr_info("%s[%d] sid_index = %d offset = %d buf = %p length = %d\n", + __func__, __LINE__,sid_index,offset,buf,length); + + file_offset = PARAM_SID_LENGTH*sid_index+ offset; + + if(buf && (sid_index < PARAM_SID_INVALID) && ((offset + length) + <= PARAM_SID_LENGTH)) + memcpy(buf,(param_ram_zone.buffer +file_offset), length); + else{ + pr_info("%s:invaild argument,sid_index=%d offset=%d buf=%p length=%d\n", + __func__,sid_index,offset,buf,length); + ret = -EINVAL; + } + + mutex_unlock(¶m_ram_zone.mutex); + return ret; +} + +static int set_param_by_index_and_offset(uint32 sid_index, + uint32 offset, void * buf, int length) +{ + int ret; + uint32 file_offset; + mutex_lock(¶m_ram_zone.mutex); + pr_info("%s[%d]sid_index = %d offset = %d buf = %p length = %d\n", + __func__, __LINE__,sid_index,offset,buf,length); + + file_offset = PARAM_SID_LENGTH*sid_index + offset; + + if(buf && (sid_index < PARAM_SID_INVALID) && + ((offset + length) <= PARAM_SID_LENGTH)) + memcpy((param_ram_zone.buffer+file_offset),buf,length); + else{ + pr_info("%s:invaild argument,sid_index=%d offset=%d buf=%p length=%d\n", + __func__,sid_index,offset,buf,length); + ret = -EINVAL; + goto out; + } + + ret = write_param_partition((param_ram_zone.buffer+file_offset), + length,file_offset); + if ( ret < 0){ + pr_info("Error write param partition.(%d)\n",ret); + } +out: + mutex_unlock(¶m_ram_zone.mutex); + return ret; +} + +static void *persistent_ram_vmap(phys_addr_t start, size_t size) +{ + struct page **pages; + phys_addr_t page_start; + unsigned int page_count; + pgprot_t prot; + unsigned int i; + void *vaddr; + + page_start = start - offset_in_page(start); + page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE); + + prot = pgprot_noncached(PAGE_KERNEL); + + pages = kmalloc(sizeof(struct page *) * page_count, GFP_KERNEL); + if (!pages) { + pr_err("%s: Failed to allocate array for %u pages\n", __func__, + page_count); + return NULL; + } + + for (i = 0; i < page_count; i++) { + phys_addr_t addr = page_start + i * PAGE_SIZE; + pages[i] = pfn_to_page(addr >> PAGE_SHIFT); + } + vaddr = vmap(pages, page_count, VM_MAP, prot); + kfree(pages); + return vaddr; +} + +static int param_ram_buffer_map(phys_addr_t start, phys_addr_t size, + param_ram_zone_t *prz) +{ + prz->paddr = start; + prz->size = size; + prz->vaddr = persistent_ram_vmap(start, size); + + if (!prz->vaddr) { + pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__, + (unsigned long long)size, (unsigned long long)start); + return -ENOMEM; + } + + prz->buffer = prz->vaddr + offset_in_page(start); + return 0; +} + +//This function just for test +static int set_param_gamma_select(uint * lcd_gamma_select) +{ + int ret; + uint32 sid_index= PARAM_SID_LCD; + uint32 offset = offsetof(param_lcd_t, gamma_select); + + ret = set_param_by_index_and_offset(sid_index,offset,lcd_gamma_select, sizeof(*lcd_gamma_select)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + return ret; +} + +static int param_test = 0; +static int param_set_test(const char *val, struct kernel_param *kp) +{ + int ret; + ret = param_set_int(val, kp); + + if (ret) + return ret; + + ret = set_param_gamma_select(¶m_test); + pr_info("%s[%d] param_test = %d ret = %d\n", + __func__, __LINE__, param_test,ret); + return 0; +} + +module_param_call(param_test, param_set_test, param_get_int, ¶m_test, 0644); + +static ssize_t param_read(struct file *file, char __user *buff, + size_t count, loff_t *pos) +{ + void * temp_buffer; + int ret; + if (mutex_lock_interruptible(¶m_lock)) + return -ERESTARTSYS; + + temp_buffer = kzalloc(count, GFP_KERNEL); + ret = get_param_by_index_and_offset(*pos/PARAM_SID_LENGTH, + *pos%PARAM_SID_LENGTH, temp_buffer, count); + if(ret < 0){ + pr_err("get_param_by_index_and_offset failure %d\n",ret); + goto out; + } + + ret =copy_to_user(buff, temp_buffer, count); + if (ret < 0) { + pr_info("copy_to_user failure %d\n", ret ); + goto out; + } + *pos += ret; + +out: + kfree(temp_buffer); + mutex_unlock(¶m_lock); + return ret; +} + +static ssize_t param_write(struct file *file, const char __user *buff, + size_t count, loff_t *pos) +{ + void * temp_buffer; + int ret; + if (mutex_lock_interruptible(¶m_lock)) + return -ERESTARTSYS; + + temp_buffer = kzalloc(count, GFP_KERNEL); + + ret =copy_from_user(temp_buffer, buff, count); + if (ret < 0) { + pr_info("copy_from_user failure %d\n", ret); + goto out; + } + + ret = set_param_by_index_and_offset(*pos/PARAM_SID_LENGTH, + *pos%PARAM_SID_LENGTH, temp_buffer, count); + if(ret < 0){ + pr_err("set_param_by_index_and_offset failure %d\n",ret); + goto out; + } + + *pos += ret; +out: + kfree(temp_buffer); + mutex_unlock(¶m_lock); + return ret; + +} + +static const struct file_operations param_fops = { + .owner = THIS_MODULE, + .read = param_read, + .write = param_write, + .llseek = default_llseek, +}; + +struct miscdevice param_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "param", + .fops = ¶m_fops, +}; + +static int __init param_core_init(void) +{ + int i; + if(param_ram_buffer_map((phys_addr_t)param_ram_zone.paddr, + param_ram_zone.size, (param_ram_zone_t *)¶m_ram_zone)){ + pr_err("param_ram_buffer_map failred\n"); + return -1; + } + mutex_init(¶m_ram_zone.mutex); + for(i = 0 ; i < PARAM_SID_INVALID; i ++){ + break;//do not dump param + printk("===dump chunk %d===\n", i); + print_hex_dump (KERN_ERR, "",DUMP_PREFIX_OFFSET,16, 4, + param_ram_zone.buffer +1024*i, default_param_data_dump_size,1); + } + param_init_done= 1; + return 0; +} +pure_initcall(param_core_init); + + +static int dump_index = -1; +static int convert_to_hex(char *dst, const char *src, size_t len) +{ + int i; + int rowsize = 16; + int groupsize = 4; + int ret = 0; + int count; + int linelen; + int ascii = 1; + int remaining = len; + + unsigned char linebuf[64]; + for (i = 0; i < len; i += rowsize) { + linelen = min(remaining, rowsize); + remaining -= rowsize; + hex_dump_to_buffer(src + i, linelen, rowsize, groupsize, + linebuf, sizeof(linebuf), ascii); + count = strlen(linebuf); + sprintf(dst+ret,"%s\n",linebuf); + ret += count+1; + }; + + return ret; +} + +static ssize_t param_dump_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count = 0; + char *tmp_buf; + int ret; + + tmp_buf = kzalloc(PAGE_SIZE,GFP_KERNEL); + if(!tmp_buf){ + pr_err("%s: kzalloc failed.\n",__func__); + return -ENOMEM; + } + + if(dump_index >= 0 && dump_index < PARAM_SID_INVALID){ + count = get_param_by_index_and_offset(dump_index, + 0,tmp_buf,PARAM_SID_LENGTH); + }else{ + int i,ret; + for(i = 0; i < PARAM_SID_INVALID; ++i){ + ret = get_param_by_index_and_offset(i, + 0,tmp_buf+count,DEFAULT_PARAM_DUMP_SIZE); + count += ret; + } + } + + if(count > 0) + ret = convert_to_hex(buf,tmp_buf,count); + + kfree(tmp_buf); + return ret; +} +static ssize_t param_dump_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + if(!strncmp("all",buf,3)){ + dump_index = -1; + }else{ + dump_index = simple_strtoul(buf,NULL,10); + } + + return strnlen(buf,size); +} +static DEVICE_ATTR(param_dump,0666, + param_dump_show,param_dump_store); + +static int __init param_device_init(void) +{ + int ret; + ret = misc_register(¶m_misc); + if(ret){ + pr_err("misc_register failure %d\n",ret); + return -1; + } + + if(device_create_file(param_misc.this_device, + &dev_attr_param_dump) < 0) + { + pr_err("Failed to create device file!(%s)!\n", + dev_attr_param_dump.attr.name); + ret = -1; + } + + return ret; +} +device_initcall(param_device_init); + +void init_param_mem_base_size(phys_addr_t base, unsigned long size) +{ + param_ram_zone.paddr = base; + param_ram_zone.size = size; +} +EXPORT_SYMBOL(init_param_mem_base_size); + +/* +*Add more function here +* +*/ +int get_param_camera_laser_sensor_offset(uint * laser_sensor_offset) +{ + int ret; + uint32 sid_index= PARAM_SID_CAMERA; + uint32 offset = offsetof(param_camera_t, laser_sensor_offset); + + ret = get_param_by_index_and_offset(sid_index,offset, + laser_sensor_offset, sizeof(*laser_sensor_offset)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + pr_info("laser_sensor_offset = %d\n", *laser_sensor_offset); + return ret; +} +EXPORT_SYMBOL(get_param_camera_laser_sensor_offset); + +int set_param_camera_laser_sensor_offset(uint * laser_sensor_offset) +{ + int ret; + uint32 sid_index= PARAM_SID_CAMERA; + uint32 offset = offsetof(param_camera_t, laser_sensor_offset); + + ret = set_param_by_index_and_offset(sid_index,offset, + laser_sensor_offset, sizeof(*laser_sensor_offset)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + pr_info("set laser_sensor_offset = %d\n", *laser_sensor_offset); + return ret; +} +EXPORT_SYMBOL(set_param_camera_laser_sensor_offset); + +int get_param_camera_laser_sensor_cross_talk(uint * laser_sensor_cross_talk) +{ + int ret; + uint32 sid_index= PARAM_SID_CAMERA; + uint32 offset = offsetof(param_camera_t, laser_sensor_cross_talk); + + ret = get_param_by_index_and_offset(sid_index,offset, + laser_sensor_cross_talk, sizeof(*laser_sensor_cross_talk)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + pr_info("laser_sensor_cross_talk = %d\n", *laser_sensor_cross_talk); + return ret; +} +EXPORT_SYMBOL(get_param_camera_laser_sensor_cross_talk); + +int set_param_camera_laser_sensor_cross_talk(uint * laser_sensor_cross_talk) +{ + int ret; + uint32 sid_index= PARAM_SID_CAMERA; + uint32 offset = offsetof(param_camera_t, laser_sensor_cross_talk); + + ret = set_param_by_index_and_offset(sid_index,offset, + laser_sensor_cross_talk, sizeof(*laser_sensor_cross_talk)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + pr_info("set laser_sensor_cross_talk = %d\n", *laser_sensor_cross_talk); + return ret; +} +EXPORT_SYMBOL(set_param_camera_laser_sensor_cross_talk); + +int get_param_gamma_select(uint * gamma_select) +{ + int ret; + uint32 sid_index= PARAM_SID_LCD; + uint32 offset = offsetof(param_lcd_t, gamma_select); + + ret = get_param_by_index_and_offset(sid_index,offset,gamma_select, + sizeof(*gamma_select)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + return ret; +} +EXPORT_SYMBOL(get_param_gamma_select); + +//#ifdef VENDOR_EDIT +/* Only for wlan evm chip */ +int get_param_nvm_boarddata(uint * nvm_boarddata_select) +{ + int ret; + uint32 sid_index= PARAM_SID_MISC; + uint32 offset = offsetof(param_misc_t, use_special_boarddata); + + ret = get_param_by_index_and_offset(sid_index,offset,nvm_boarddata_select, + sizeof(*nvm_boarddata_select)); + if(ret < 0){ + pr_info("%s[%d] failed\n",__func__, __LINE__); + return ret; + } + return ret; +} +EXPORT_SYMBOL(get_param_nvm_boarddata); +//#endif /* VENDOR_EDIT */ diff --git a/drivers/pinctrl/pinctrl-msm-tlmm.c b/drivers/pinctrl/pinctrl-msm-tlmm.c old mode 100644 new mode 100755 index fc8076162a0fc..a3140d39670d4 --- a/drivers/pinctrl/pinctrl-msm-tlmm.c +++ b/drivers/pinctrl/pinctrl-msm-tlmm.c @@ -960,6 +960,15 @@ static void msm_tlmm_gp_irq_resume(void) for_each_set_bit(i, ic->wake_irqs, num_irqs) msm_tlmm_set_intr_cfg_enable(ic, i, 0); +#ifdef VENDOR_EDIT +/* Jialong.Wu,add 2015/5/9 Add for wakeup analysis */ + for_each_set_bit(i, ic->wake_irqs, ic->num_irqs){ + if (msm_tlmm_get_intr_status(ic, i)) + dev_info(ic->dev, "hwirq %s %d[%d] triggered\n", + irq_to_desc(gpio_to_irq((unsigned int)(i+878)))->action->name, + (gpio_to_irq((unsigned int)(i+878))), (unsigned int)i); + } +#endif /* VENDOR_EDIT */ for_each_set_bit(i, ic->enabled_irqs, num_irqs) msm_tlmm_set_intr_cfg_enable(ic, i, 1); mb(); @@ -1095,6 +1104,90 @@ static struct msm_pintype_info tlmm_pininfo[] = { } }; +#ifdef VENDOR_EDIT +static uint need_dump_pinctrl; +module_param(need_dump_pinctrl, uint, 0644); +MODULE_PARM_DESC(need_dump_pinctrl, "need_dump_pinctrl"); + +#define PINCTRL_START 0 +#define PINCTRL_END 145 +char * gpio_pull(int pull) +{ + switch(pull){ + case 0: + return "NP"; + case 1: + return "PD"; + case 2: + return "keeper"; + case 3: + return "PU"; + } + return "N/A"; +} + +static void msm_tlmm_gp_func_cfg_get(uint pin_no, const struct msm_pintype_info *pinfo, unsigned int * gp_func_cfg, unsigned int * gpio_value) +{ + void __iomem *cfg_reg = TLMM_GP_CFG(pinfo, pin_no); + void __iomem *inout_reg = TLMM_GP_INOUT(pinfo, pin_no); + + *gp_func_cfg = readl_relaxed(cfg_reg); + *gpio_value = readl_relaxed(inout_reg); +} + + +struct pinctrl_config_table_t { + int gp_no; + int suspend_pull_config; + int resume_pull_config; +}; + +//Provided by HW Linyoude and Chenbiao +static struct pinctrl_config_table_t pinctrl_config_table[]= { + {23, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP}, + {24, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP}, + {38, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP}, + {43, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_DISABLE}, + {44, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_DISABLE}, + {54, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP}, + {72, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP}, + {73, PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_PULL_UP} +}; +void pinctrl_suspend_resume_config(bool to_suspend) +{ + int i; + + for(i = 0 ; i < sizeof(pinctrl_config_table)/sizeof(pinctrl_config_table[0]); i ++){ + if(to_suspend) + msm_tlmm_gp_cfg(pinctrl_config_table[i].gp_no, (unsigned long *)&(pinctrl_config_table[i].suspend_pull_config), 1, &tlmm_pininfo[0]); + else + msm_tlmm_gp_cfg(pinctrl_config_table[i].gp_no, (unsigned long *)&(pinctrl_config_table[i].resume_pull_config), 1, &tlmm_pininfo[0]); + } +} +EXPORT_SYMBOL(pinctrl_suspend_resume_config); + +void pinctrl_suspend_dump(void) +{ + int i ; + unsigned int gp_func_cfg, gpio_value; + if(need_dump_pinctrl){ + for(i = PINCTRL_START ; i <= PINCTRL_END; i ++){ + msm_tlmm_gp_func_cfg_get(i ,&tlmm_pininfo[0], &gp_func_cfg, &gpio_value); + + pr_info("pin %3d gpio %4d FS:%d, %3s PULL:%7s DRV: %2dmA VALUE %ld\n", + i, 878+ i, + (gp_func_cfg & 0x3C) >>2, + (gp_func_cfg & 0x200)>>9?"OUT":"IN", + gpio_pull(gp_func_cfg & 0x3), + (((gp_func_cfg &0x1c0)>>6) + 1)*2, + (gp_func_cfg & 0x200)>>9? ((gpio_value&BIT(1))>>1):(gpio_value&BIT(0))); + //pr_info("pin %d: 0x%x 0x%x\n",i,gp_func_cfg, gpio_value); + } + } +} +EXPORT_SYMBOL(pinctrl_suspend_dump); +#endif /* VENDOR_EDIT */ + #define DECLARE_PINTYPE_DATA_GP(name, offset, regsize) \ static const struct msm_pintype_data name = { \ .reg_base_offset = offset, \ diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index 294e468da88c7..1059e14b24a2c 100644 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -243,7 +243,13 @@ struct qpnp_hap { bool en_brake; bool sup_brake_pat; }; - +/*shankai 2015-07-7 add begin for optimizing the response speed of the +vibrator*/ +#ifdef VENDOR_EDIT +static struct workqueue_struct *vibqueue; +#endif //VENDOR_EDIT +/*shankai 2015-07-7 add end for optimizing the response speed of the +vibrator*/ /* helper to read a pmic register */ static int qpnp_hap_read_reg(struct qpnp_hap *hap, u8 *data, u16 addr) { @@ -572,6 +578,9 @@ static int qpnp_hap_sc_deb_config(struct qpnp_hap *hap) temp = fls(hap->sc_deb_cycles) - 1; reg |= temp - QPNP_HAP_SC_DEB_SUB; } + //add by shankai + else + reg = 0; rc = qpnp_hap_write_reg(hap, ®, QPNP_HAP_SC_DEB_REG(hap->base)); if (rc) return rc; @@ -1021,6 +1030,44 @@ static ssize_t qpnp_hap_play_mode_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", str); } +static ssize_t qpnp_hap_vmax_mv_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vmax_mv); +} + +static ssize_t qpnp_hap_vmax_mv_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + u32 data; + int rc; + + if (sscanf(buf, "%d", &data) != 1) + return -EINVAL; + + if (data < QPNP_HAP_VMAX_MIN_MV) { + pr_err("%s: mv %d not in range (%d - %d), using min.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); + data = QPNP_HAP_VMAX_MIN_MV; + } else if (data > QPNP_HAP_VMAX_MAX_MV) { + pr_err("%s: mv %d not in range (%d - %d), using max.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); + data = QPNP_HAP_VMAX_MAX_MV; + } + + hap->vmax_mv = data; + rc = qpnp_hap_vmax_config(hap); + if (rc) + pr_info("qpnp: error while writing vibration control register\n"); + + return strnlen(buf, count); +} + /* sysfs attributes */ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(wf_s0, (S_IRUGO | S_IWUSR | S_IWGRP), @@ -1062,6 +1109,9 @@ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(dump_regs, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_hap_dump_regs_show, NULL), + __ATTR(vmax_mv, (S_IRUGO | S_IWUSR | S_IWGRP), + qpnp_hap_vmax_mv_show, + qpnp_hap_vmax_mv_store), }; /* set api for haptics */ @@ -1101,10 +1151,11 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) mutex_lock(&hap->lock); hrtimer_cancel(&hap->hap_timer); - if (value == 0) hap->state = 0; else { + if (value < 50) + value += 29; value = (value > hap->timeout_ms ? hap->timeout_ms : value); hap->state = 1; @@ -1112,8 +1163,16 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL); } + #ifndef VENDOR_EDIT mutex_unlock(&hap->lock); schedule_work(&hap->work); + #else //#ifdef VENDOR_EDIT + queue_work(vibqueue,&hap->work); + msleep(1); + mutex_unlock(&hap->lock); + #endif //VENDOR_EDIT + /* shankai 2015-07-7 modify end for optimizing the response speed of the vibrator*/ + } /* worker to opeate haptics */ @@ -1145,7 +1204,14 @@ static enum hrtimer_restart qpnp_hap_timer(struct hrtimer *timer) hap_timer); hap->state = 0; + /*shankai@bsp.2015-07-16 modify begin for optimizing the response speed of the vibrator*/ +#ifndef VENDOR_EDIT schedule_work(&hap->work); +#else + //#ifdef VENDOR_EDIT + queue_work(vibqueue,&hap->work); +#endif //VENDOR_EDIT + /*shankai@bsp.2015-07-16 modify end for optimizing the response speed of the vibrator*/ return HRTIMER_NORESTART; } @@ -1625,6 +1691,11 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) mutex_init(&hap->lock); mutex_init(&hap->wf_lock); + + #ifdef VENDOR_EDIT + vibqueue = create_singlethread_workqueue("vibthread"); + #endif //VENDOR_EDIT + INIT_WORK(&hap->work, qpnp_hap_worker); hrtimer_init(&hap->hap_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c old mode 100644 new mode 100755 index 533101a5dd93d..6a9b2c5cad5c1 --- a/drivers/platform/msm/qpnp-power-on.c +++ b/drivers/platform/msm/qpnp-power-on.c @@ -27,6 +27,16 @@ #include #include +#ifdef VENDOR_EDIT +/*Add by yangrujin@bsp 2015/7/30, fix SND-8480 avoid : sometimes, device will goto sleep without respond PWR KEY event*/ +#include +#endif + +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/07/03, add for force dump function +#include +#endif + #define CREATE_MASK(NUM_BITS, POS) \ ((unsigned char) (((1 << (NUM_BITS)) - 1) << (POS))) #define PON_MASK(MSB_BIT, LSB_BIT) \ @@ -170,6 +180,12 @@ struct qpnp_pon { }; static struct qpnp_pon *sys_reset_dev; + +#ifdef VENDOR_EDIT +/*Add by yangrujin@bsp 2015/7/30, fix SND-8480 avoid : sometimes, device will goto sleep without respond PWR KEY event*/ +static struct wake_lock pwr_wakelock; +#endif + static DEFINE_MUTEX(spon_list_mutex); static LIST_HEAD(spon_dev_list); @@ -217,6 +233,174 @@ static const char * const qpnp_poff_reason[] = { static int warm_boot; module_param(warm_boot, int, 0); +#ifdef VENDOR_EDIT +static bool created_pwr_on_off_obj; + +#define PMIC_SID_NUM 3 +static struct qpnp_pon *g_pon[PMIC_SID_NUM]; +static bool g_is_cold_boot[PMIC_SID_NUM]; + +static ssize_t pwron_reason_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int i; + int j; + int index; + u8 pon_sts; + int rc; + char *pbuf = buf; + int ret = 0; + + sprintf(pbuf, "qpnp_pon_reason :\n"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + + for(i=0; ispmi==NULL || g_pon[i]->spmi->ctrl==NULL){ + continue; + } + + rc = spmi_ext_register_readl(g_pon[i]->spmi->ctrl, g_pon[i]->spmi->sid, + QPNP_PON_REASON1(g_pon[i]->base), &pon_sts, 1); + if (rc){ + sprintf(pbuf, "PMIC@SID%d: Unable to read PON_RESASON1 reg rc: %d\n", g_pon[i]->spmi->sid, rc); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + continue; + } + index = ffs(pon_sts)-1; + if (index >= ARRAY_SIZE(qpnp_pon_reason) || index < 0){ + sprintf(pbuf, "PMIC@SID%d Power-on reason: Unknown and '%s' boot\n", + g_pon[i]->spmi->sid, g_is_cold_boot[g_pon[i]->spmi->sid]?"cold":"warm"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + continue; + }else{ + sprintf(pbuf, "PMIC@SID%d Power-on reason: '%s' boot and ", g_pon[i]->spmi->sid, + g_is_cold_boot[g_pon[i]->spmi->sid]?"cold":"warm"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + + for(j=0; j>j)&0x1)?j:-1; + + if(index>=0){ + sprintf(pbuf, "[%d] ", index); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + } + + sprintf(pbuf, "\n"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + + if(ret){ + *(buf+ret-1) = '\n'; + } + + return ret; +} + +static ssize_t pwroff_reason_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int i; + int j; + int index; + int rc; + u8 temp_buf[2]; + u8 poff_sts; + char *pbuf = buf; + int ret = 0; + + sprintf(pbuf, "qpnp_poff_reason :\n"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + + for(j=0; jspmi==NULL || g_pon[i]->spmi->ctrl==NULL){ + continue; + } + + /* POFF reason */ + rc = spmi_ext_register_readl(g_pon[i]->spmi->ctrl, g_pon[i]->spmi->sid, + QPNP_POFF_REASON1(g_pon[i]->base), temp_buf, 2); + if (rc){ + sprintf(pbuf, "PMIC@SID%d: Unable to read QPNP_POFF_REASON1 reg ret: %d\n", g_pon[i]->spmi->sid, rc); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + continue; + } + + poff_sts = temp_buf[0] | (temp_buf[1] << 8); + index = ffs(poff_sts) - 1; + + if (index >= ARRAY_SIZE(qpnp_poff_reason) || index < 0) { + sprintf(pbuf, "PMIC@SID%d Power-off eason: Unknown\n", g_pon[i]->spmi->sid); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + continue; + }else{ + sprintf(pbuf, "PMIC@SID%d Power-off reason: ", g_pon[i]->spmi->sid); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + + for(j=0; j>j)&0x1)?j:-1; + if(index>=0){ + sprintf(pbuf, "[%d] ", index); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + } + + sprintf(pbuf, "\n"); + ret += strlen(pbuf); + pbuf += strlen(pbuf); + } + + if(ret){ + *(buf+ret-1) = '\n'; + } + + return ret; +} + +static struct kobj_attribute pwron_reason_attribute = + __ATTR(pwron_reason, 0444, pwron_reason_show, NULL); +static struct kobj_attribute pwroff_reason_attribute = + __ATTR(pwroff_reason, 0444, pwroff_reason_show, NULL); + +static struct attribute *pwr_on_off_attrs[] = { + &pwron_reason_attribute.attr, + &pwroff_reason_attribute.attr, + NULL, +}; + +static struct attribute_group pwr_on_off_attrs_group = { + .attrs = pwr_on_off_attrs, +}; +static struct kobject *pwr_on_off_kobj; +#endif + static int qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) { @@ -636,8 +820,8 @@ qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) return -EINVAL; } - pr_debug("PMIC input: code=%d, sts=0x%hhx\n", - cfg->key_code, pon_rt_sts); + printk("PMIC input: code=%d, sts=0x%hhx, pon_rt_bit=0x%x, cfg->old_state=0x%x\n", + cfg->key_code, pon_rt_sts, pon_rt_bit, cfg->old_state); key_status = pon_rt_sts & pon_rt_bit; /* simulate press event in case release event occured @@ -653,6 +837,10 @@ qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) cfg->old_state = !!key_status; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/07/03, add for force dump function + oem_check_force_dump_key(cfg->key_code,key_status); +#endif return 0; } @@ -660,7 +848,10 @@ static irqreturn_t qpnp_kpdpwr_irq(int irq, void *_pon) { int rc; struct qpnp_pon *pon = _pon; - +#ifdef VENDOR_EDIT +/*Add by yangrujin@bsp 2015/7/30, fix SND-8480 avoid : sometimes, device will goto sleep without respond PWR KEY event*/ + wake_lock_timeout(&pwr_wakelock, HZ); +#endif rc = qpnp_pon_input_dispatch(pon, PON_KPDPWR); if (rc) dev_err(&pon->spmi->dev, "Unable to send input event\n"); @@ -948,6 +1139,10 @@ qpnp_pon_request_irqs(struct qpnp_pon *pon, struct qpnp_pon_config *cfg) switch (cfg->pon_type) { case PON_KPDPWR: +#ifdef VENDOR_EDIT +/*Add by yangrujin@bsp 2015/7/30, fix SND-8480 avoid : sometimes, device will goto sleep without respond PWR KEY event*/ + wake_lock_init(&pwr_wakelock, WAKE_LOCK_SUSPEND, "pwr_key"); +#endif rc = devm_request_irq(&pon->spmi->dev, cfg->state_irq, qpnp_kpdpwr_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, @@ -1607,6 +1802,13 @@ static int qpnp_pon_probe(struct spmi_device *spmi) cold_boot ? "cold" : "warm"); } +#ifdef VENDOR_EDIT + if((pon->spmi->sid)>=0 && (pon->spmi->sid)spmi->sid] = pon; + g_is_cold_boot[pon->spmi->sid] = cold_boot; + } +#endif + /* POFF reason */ rc = spmi_ext_register_readl(pon->spmi->ctrl, pon->spmi->sid, QPNP_POFF_REASON1(pon->base), @@ -1754,6 +1956,21 @@ static int qpnp_pon_probe(struct spmi_device *spmi) spmi->dev.of_node, "qcom,store-hard-reset-reason"); +#ifdef VENDOR_EDIT + if(!created_pwr_on_off_obj){ + pwr_on_off_kobj = kobject_create_and_add("pwr_on_off_reason", NULL); + if (!pwr_on_off_kobj){ + dev_err(&spmi->dev, "kobject_create_and_add for pwr_on_off_reason failed.\n"); + return -ENOMEM; + } + if (sysfs_create_group(pwr_on_off_kobj, &pwr_on_off_attrs_group)){ + dev_err(&spmi->dev, "sysfs_create_group for pwr_on_off_reason failed.\n"); + kobject_put(pwr_on_off_kobj); + } + created_pwr_on_off_obj = true; + } +#endif + qpnp_pon_debugfs_init(spmi); return 0; } @@ -1761,7 +1978,10 @@ static int qpnp_pon_probe(struct spmi_device *spmi) static int qpnp_pon_remove(struct spmi_device *spmi) { struct qpnp_pon *pon = dev_get_drvdata(&spmi->dev); - +#ifdef VENDOR_EDIT +/*Add by yangrujin@bsp 2015/7/30, fix SND-8480 avoid : sometimes, device will goto sleep without respond PWR KEY event*/ + wake_lock_destroy(&pwr_wakelock); +#endif device_remove_file(&spmi->dev, &dev_attr_debounce_us); cancel_delayed_work_sync(&pon->bark_work); diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c index 53b3a346ac690..496762c361c43 100644 --- a/drivers/platform/msm/qpnp-revid.c +++ b/drivers/platform/msm/qpnp-revid.c @@ -208,7 +208,7 @@ static void __exit qpnp_revid_exit(void) return spmi_driver_unregister(&qpnp_revid_driver); } -module_init(qpnp_revid_init); +subsys_initcall(qpnp_revid_init); module_exit(qpnp_revid_exit); MODULE_DESCRIPTION("QPNP REVID DRIVER"); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 6ef076fbea6cd..f5fafdc7cce2a 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -464,6 +464,14 @@ config QPNP_SMBCHARGER supports USB detection and battery charging up to 3A. The driver also offers relevant information to userspace via the power supply framework. +#ifdef VENDOR_EDIT +#Add by yangrujin@bsp, set pmi reset type, avoid pmi warm reset but pm shutdown, +#to fix issue that handset die but no dump port. +config SET_PMI8994_RESET_TYPE + tristate "Set PMI8994 reset type" + help + Say Y here to enable set pmi8994 reset type +#endif config QPNP_FG tristate "QPNP fuel gauge driver" diff --git a/drivers/power/battery_current_limit.c b/drivers/power/battery_current_limit.c index 9992d73063dbc..0303a22e151de 100644 --- a/drivers/power/battery_current_limit.c +++ b/drivers/power/battery_current_limit.c @@ -192,6 +192,7 @@ static enum bcl_threshold_state bcl_vph_state = BCL_THRESHOLD_DISABLED, static DEFINE_MUTEX(bcl_notify_mutex); static uint32_t bcl_hotplug_request, bcl_hotplug_mask, bcl_soc_hotplug_mask; static uint32_t bcl_frequency_mask; +static bool bcl_hotplug_thrash_free; static struct work_struct bcl_hotplug_work; static DEFINE_MUTEX(bcl_hotplug_mutex); static bool bcl_hotplug_enabled; @@ -245,15 +246,23 @@ static void __ref bcl_handle_hotplug(struct work_struct *work) } else { if (cpu_online(_cpu)) continue; - ret = cpu_up(_cpu); - if (ret) - pr_err("Error %d onlining core %d\n", - ret, _cpu); - else - pr_info("Allow Online CPU:%d\n", _cpu); + + /* let actual demand decide it rather than free run */ + if (!bcl_hotplug_thrash_free) { + ret = cpu_up(_cpu); + if (ret) + pr_err("Error %d onlining core %d\n", + ret, _cpu); + else + pr_info("Allow Online CPU:%d\n", _cpu); + } } } + /* force online mask to be refreshed next time */ + if (bcl_hotplug_thrash_free) + cpumask_clear(bcl_cpu_online_mask); + mutex_unlock(&bcl_hotplug_mutex); return; } @@ -900,6 +909,7 @@ show_bcl(ibat_state, bcl_ibat_state, "%d\n") show_bcl(hotplug_mask, bcl_hotplug_mask, "%d\n") show_bcl(hotplug_soc_mask, bcl_soc_hotplug_mask, "%d\n") show_bcl(hotplug_status, bcl_hotplug_request, "%d\n") +show_bcl(hotplug_thrash_free, bcl_hotplug_thrash_free, "%d\n"); static ssize_t mode_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1256,6 +1266,25 @@ static ssize_t hotplug_soc_mask_store(struct device *dev, return count; } + +static ssize_t hotplug_thrash_free_store( + struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret = 0, val = 0; + + ret = kstrtoint(buf, 10, &val); + if (ret || (val < 0)) + return -EINVAL; + + bcl_hotplug_thrash_free = val; + pr_info("bcl hotplug thrash-free enable: %d\n", + bcl_hotplug_thrash_free); + + return count; +} + /* * BCL device attributes */ @@ -1298,6 +1327,8 @@ static struct device_attribute btm_dev_attr[] = { __ATTR(hotplug_mask, 0644, hotplug_mask_show, hotplug_mask_store), __ATTR(hotplug_soc_mask, 0644, hotplug_soc_mask_show, hotplug_soc_mask_store), + __ATTR(hotplug_thrash_free, 0644, hotplug_thrash_free_show, + hotplug_thrash_free_store), }; static int create_bcl_sysfs(struct bcl_context *bcl) @@ -1738,6 +1769,7 @@ static int bcl_probe(struct platform_device *pdev) "qcom,bcl-hotplug-list"); bcl_soc_hotplug_mask = get_mask_from_core_handle(pdev, "qcom,bcl-soc-hotplug-list"); + bcl_hotplug_thrash_free = 0; if (!bcl_hotplug_mask && !bcl_soc_hotplug_mask) bcl_hotplug_enabled = false; diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c index 406f097102520..f016f7afe01eb 100644 --- a/drivers/power/qcom/msm-core.c +++ b/drivers/power/qcom/msm-core.c @@ -191,6 +191,38 @@ static void core_temp_notify(enum thermal_trip_type type, complete(&sampling_completion); } +#ifdef VENDOR_EDIT +/* ic, provide pcost based on requested frequency and temperature */ +unsigned int power_cost_at_freq_at_temp( + unsigned int cpu, + unsigned int freq, + long temp) +{ + struct cpu_activity_info *cpu_node = &activity[cpu]; + int temp_point, i; + + if (!cpu_node->sp->table || !cpu_node->sp->num_of_freqs) + return 0; + + /* come out temp point at intervals */ + if (temp < TEMP_BASE_POINT) + temp_point = 0; + else if (temp > TEMP_MAX_POINT) + temp_point = TEMP_DATA_POINTS - 1; + else + temp_point = (temp - TEMP_BASE_POINT) / 5; + + /* locate temp. then come out cost at that temp. and freq. */ + for (i = 0; i < cpu_node->sp->num_of_freqs; i++) { + if (cpu_node->sp->table[i].frequency >= freq) + return cpu_node->sp->power[temp_point][i]; + } + + return 0; +} +EXPORT_SYMBOL(power_cost_at_freq_at_temp); +#endif + static void repopulate_stats(int cpu) { int i; diff --git a/drivers/power/qpnp-fg.c b/drivers/power/qpnp-fg.c old mode 100644 new mode 100755 index bdf6d9aee94bb..6e1958556e060 --- a/drivers/power/qpnp-fg.c +++ b/drivers/power/qpnp-fg.c @@ -33,6 +33,7 @@ #include #include #include +#include /* Register offsets */ @@ -42,18 +43,6 @@ /* SPMI Register offsets */ #define SOC_MONOTONIC_SOC 0x09 -#define MEM_INTF_CFG 0x40 -#define MEM_INTF_CTL 0x41 -#define MEM_INTF_ADDR_LSB 0x42 -#define MEM_INTF_ADDR_MSB 0x43 -#define MEM_INTF_WR_DATA0 0x48 -#define MEM_INTF_WR_DATA1 0x49 -#define MEM_INTF_WR_DATA2 0x4A -#define MEM_INTF_WR_DATA3 0x4B -#define MEM_INTF_RD_DATA0 0x4C -#define MEM_INTF_RD_DATA1 0x4D -#define MEM_INTF_RD_DATA2 0x4E -#define MEM_INTF_RD_DATA3 0x4F #define OTP_CFG1 0xE2 #define SOC_BOOT_MOD 0x50 #define SOC_RESTART 0x51 @@ -98,6 +87,16 @@ enum { FG_AGING = BIT(7), /* Show FG aging algorithm */ }; +enum dig_major { + DIG_REV_8994_1 = 0x1, + DIG_REV_8994_2 = 0x2, +}; + +enum pmic_subtype { + PMI8994 = 10, + PMI8950 = 17, +}; + struct fg_mem_setting { u16 address; u8 offset; @@ -126,6 +125,19 @@ struct fg_learning_data { int max_temp; }; +struct fg_rslow_data { + u8 rslow_cfg; + u8 rslow_thr; + u8 rs_to_rslow[2]; + u8 rslow_comp[4]; + uint32_t chg_rs_to_rslow; + uint32_t chg_rslow_comp_c1; + uint32_t chg_rslow_comp_c2; + uint32_t chg_rslow_comp_thr; + bool active; + struct mutex lock; +}; + /* FG_MEMIF setting index */ enum fg_mem_setting_index { FG_MEM_SOFT_COLD = 0, @@ -164,7 +176,26 @@ enum fg_mem_data_index { FG_DATA_BATT_ID_INFO, FG_DATA_MAX, }; - +#ifdef VENDOR_EDIT +typedef enum{ + /*! Battery is cold */ + CV_BATTERY_TEMP_REGION__COLD, + /*! Battery is little cold */ + CV_BATTERY_TEMP_REGION_LITTLE__COLD, + /*! Battery is cool */ + CV_BATTERY_TEMP_REGION__COOL, + /*! Battery is little cool */ + CV_BATTERY_TEMP_REGION__LITTLE_COOL, + /*! Battery is normal */ + CV_BATTERY_TEMP_REGION__NORMAL, + /*! Battery is warm */ + CV_BATTERY_TEMP_REGION__WARM, + /*! Battery is hot */ + CV_BATTERY_TEMP_REGION__HOT, + /*! Invalid battery temp region */ + CV_BATTERY_TEMP_REGION__INVALID, +}chg_cv_battery_temp_region_type; +#endif #define SETTING(_idx, _address, _offset, _value) \ [FG_MEM_##_idx] = { \ .address = _address, \ @@ -174,10 +205,19 @@ enum fg_mem_data_index { static struct fg_mem_setting settings[FG_MEM_SETTING_MAX] = { /* ID Address, Offset, Value*/ +#ifdef VENDOR_EDIT +/* yangfangbiao@oneplus.cn, 2015/03/11 Modify for PMI8994 charge*/ + + SETTING(SOFT_COLD, 0x454, 0, -30), + SETTING(SOFT_HOT, 0x454, 1, 550), + SETTING(HARD_COLD, 0x454, 2, -40), + SETTING(HARD_HOT, 0x454, 3, 560), +#else SETTING(SOFT_COLD, 0x454, 0, 100), SETTING(SOFT_HOT, 0x454, 1, 400), SETTING(HARD_COLD, 0x454, 2, 50), SETTING(HARD_HOT, 0x454, 3, 450), +#endif /*VENDOR_EDIT*/ SETTING(RESUME_SOC, 0x45C, 1, 0), SETTING(BCL_LM_THRESHOLD, 0x47C, 2, 50), SETTING(BCL_MH_THRESHOLD, 0x47C, 3, 752), @@ -274,6 +314,37 @@ enum fg_batt_aging_mode { FG_AGING_CC, }; +enum register_type { + MEM_INTF_CFG, + MEM_INTF_CTL, + MEM_INTF_ADDR_LSB, + MEM_INTF_RD_DATA0, + MEM_INTF_WR_DATA0, + MAX_ADDRESS, +}; + +struct register_offset { + u16 address[MAX_ADDRESS]; +}; + +static struct register_offset offset[] = { + [0] = { + /* CFG CTL LSB RD0 WD0 */ + .address = {0x40, 0x41, 0x42, 0x4C, 0x48}, + }, +}; + +#define MEM_INTF_CFG(chip) \ + ((chip)->mem_base + (chip)->offset[MEM_INTF_CFG]) +#define MEM_INTF_CTL(chip) \ + ((chip)->mem_base + (chip)->offset[MEM_INTF_CTL]) +#define MEM_INTF_ADDR_LSB(chip) \ + ((chip)->mem_base + (chip)->offset[MEM_INTF_ADDR_LSB]) +#define MEM_INTF_RD_DATA0(chip) \ + ((chip)->mem_base + (chip)->offset[MEM_INTF_RD_DATA0]) +#define MEM_INTF_WR_DATA0(chip) \ + ((chip)->mem_base + (chip)->offset[MEM_INTF_WR_DATA0]) + struct fg_wakeup_source { struct wakeup_source source; unsigned long enabled; @@ -299,6 +370,8 @@ static void fg_relax(struct fg_wakeup_source *source) struct fg_chip { struct device *dev; struct spmi_device *spmi; + u8 pmic_subtype; + u8 revision[4]; u16 soc_base; u16 batt_base; u16 mem_base; @@ -322,6 +395,7 @@ struct fg_chip { struct work_struct battery_age_work; struct work_struct update_esr_work; struct work_struct set_resume_soc_work; + struct work_struct rslow_comp_work; struct work_struct init_work; struct power_supply *batt_psy; struct power_supply *usb_psy; @@ -377,6 +451,18 @@ struct fg_chip { struct fg_learning_data learning_data; struct alarm fg_cap_learning_alarm; struct work_struct fg_cap_learning_work; + #ifdef VENDOR_EDIT + int saltate_counter; + int soc_pre; + int batt_vol_pre; + bool allow_get_real_fg_soc; + unsigned long enter_suspend_time; + unsigned long soc_continue_time; + #endif + /* rslow compensation */ + struct fg_rslow_data rslow_comp; + /* interleaved memory access */ + u16 *offset; }; /* FG_MEMIF DEBUGFS structures */ @@ -445,7 +531,9 @@ static char *fg_supplicants[] = { "bcl", "fg_adc" }; - +#ifdef VENDOR_EDIT +static int get_sram_prop_now(struct fg_chip *chip, unsigned int type); +#endif #define DEBUG_PRINT_BUFFER_SIZE 64 static void fill_string(char *str, size_t str_len, u8 *buf, int buf_len) { @@ -559,7 +647,7 @@ static inline bool fg_check_sram_access(struct fg_chip *chip) if ((mem_if_sts & BIT(FG_MEM_AVAIL)) == 0) return false; - rc = fg_read(chip, &mem_if_sts, chip->mem_base + MEM_INTF_CFG, 1); + rc = fg_read(chip, &mem_if_sts, MEM_INTF_CFG(chip), 1); if (rc) { pr_err("failed to read mem status rc=%d\n", rc); return 0; @@ -588,7 +676,7 @@ static inline int fg_assert_sram_access(struct fg_chip *chip) return -EINVAL; } - rc = fg_read(chip, &mem_if_sts, chip->mem_base + MEM_INTF_CFG, 1); + rc = fg_read(chip, &mem_if_sts, MEM_INTF_CFG(chip), 1); if (rc) { pr_err("failed to read mem status rc=%d\n", rc); return rc; @@ -622,7 +710,7 @@ static int fg_config_access(struct fg_chip *chip, bool write, intf_ctl = (write ? INTF_CTL_WR_EN : 0) | (burst ? INTF_CTL_BURST : 0); - rc = fg_write(chip, &intf_ctl, chip->mem_base + MEM_INTF_CTL, 1); + rc = fg_write(chip, &intf_ctl, MEM_INTF_CTL(chip), 1); if (rc) { pr_err("failed to set mem access bit\n"); return -EIO; @@ -637,8 +725,8 @@ static int fg_req_and_wait_access(struct fg_chip *chip, int timeout) bool tried_again = false; if (!fg_check_sram_access(chip)) { - rc = fg_masked_write(chip, chip->mem_base + MEM_INTF_CFG, - RIF_MEM_ACCESS_REQ, RIF_MEM_ACCESS_REQ, 1); + rc = fg_masked_write(chip, MEM_INTF_CFG(chip), + RIF_MEM_ACCESS_REQ, RIF_MEM_ACCESS_REQ, 1); if (rc) { pr_err("failed to set mem access bit\n"); return -EIO; @@ -668,7 +756,7 @@ static int fg_release_access(struct fg_chip *chip) { int rc; - rc = fg_masked_write(chip, chip->mem_base + MEM_INTF_CFG, + rc = fg_masked_write(chip, MEM_INTF_CFG(chip), RIF_MEM_ACCESS_REQ, 0, 1); fg_relax(&chip->memif_wakeup_source); INIT_COMPLETION(chip->sram_access_granted); @@ -709,10 +797,10 @@ static int fg_set_ram_addr(struct fg_chip *chip, u16 *address) int rc; rc = fg_write(chip, (u8 *) address, - chip->mem_base + MEM_INTF_ADDR_LSB, 2); + chip->mem_base + chip->offset[MEM_INTF_ADDR_LSB], 2); if (rc) { pr_err("spmi write failed: addr=%03X, rc=%d\n", - chip->mem_base + MEM_INTF_ADDR_LSB, rc); + chip->mem_base + chip->offset[MEM_INTF_ADDR_LSB], rc); return rc; } @@ -745,12 +833,11 @@ static int fg_sub_mem_read(struct fg_chip *chip, u8 *val, u16 address, int len, total_len = len; while (len > 0) { if (!offset) { - rc = fg_read(chip, rd_data, - chip->mem_base + MEM_INTF_RD_DATA0, - min(len, BUF_LEN)); + rc = fg_read(chip, rd_data, MEM_INTF_RD_DATA0(chip), + min(len, BUF_LEN)); } else { rc = fg_read(chip, rd_data, - chip->mem_base + MEM_INTF_RD_DATA0 + offset, + MEM_INTF_RD_DATA0(chip) + offset, min(len, BUF_LEN - offset)); /* manually set address to allow continous reads */ @@ -762,7 +849,7 @@ static int fg_sub_mem_read(struct fg_chip *chip, u8 *val, u16 address, int len, } if (rc) { pr_err("spmi read failed: addr=%03x, rc=%d\n", - chip->mem_base + MEM_INTF_RD_DATA0, rc); + MEM_INTF_RD_DATA0(chip) + offset, rc); return rc; } rd_data += (BUF_LEN - offset); @@ -777,8 +864,8 @@ static int fg_sub_mem_read(struct fg_chip *chip, u8 *val, u16 address, int len, return rc; } -static int fg_mem_read(struct fg_chip *chip, u8 *val, u16 address, int len, - int offset, bool keep_access) +static int fg_mem_read(struct fg_chip *chip, u8 *val, u16 address, + int len, int offset, bool keep_access) { int rc = 0, user_cnt = 0, orig_address = address; @@ -900,11 +987,10 @@ static int fg_mem_write(struct fg_chip *chip, u8 *val, u16 address, pr_err("Invalid length: %d\n", len); break; } - rc = fg_write(chip, word, - chip->mem_base + MEM_INTF_WR_DATA0, 4); + rc = fg_write(chip, word, MEM_INTF_WR_DATA0(chip), 4); if (rc) { pr_err("spmi write failed: addr=%03x, rc=%d\n", - chip->mem_base + MEM_INTF_RD_DATA0, rc); + MEM_INTF_WR_DATA0(chip), rc); goto out; } len -= sublen; @@ -1016,19 +1102,33 @@ static int get_current_time(unsigned long *now_tm_sec) return rc; } +#define BATTERY_SOC_REG 0x56C +#define BATTERY_SOC_OFFSET 1 +#define FULL_PERCENT_3B 0xFFFFFF +static int get_battery_soc_raw(struct fg_chip *chip) +{ + int rc; + u8 buffer[3]; + + rc = fg_mem_read(chip, buffer, BATTERY_SOC_REG, 3, 1, 0); + if (rc) { + pr_err("Unable to read battery soc: %d\n", rc); + return 0; + } + return (int)(buffer[2] << 16 | buffer[1] << 8 | buffer[0]); +} + #define COUNTER_IMPTR_REG 0X558 #define COUNTER_PULSE_REG 0X55C #define SOC_FULL_REG 0x564 -#define BATTERY_SOC_REG 0x56C #define COUNTER_IMPTR_OFFSET 2 #define COUNTER_PULSE_OFFSET 0 #define SOC_FULL_OFFSET 3 -#define BATTERY_SOC_OFFSET 1 #define ESR_PULSE_RECONFIG_SOC 0xFFF971 static int fg_configure_soc(struct fg_chip *chip) { u32 batt_soc; - u8 reg[3], cntr[2] = {0, 0}; + u8 cntr[2] = {0, 0}; int rc = 0; mutex_lock(&chip->rw_lock); @@ -1036,13 +1136,7 @@ static int fg_configure_soc(struct fg_chip *chip) mutex_unlock(&chip->rw_lock); /* Read Battery SOC */ - rc = fg_mem_read(chip, reg, BATTERY_SOC_REG, 3, BATTERY_SOC_OFFSET, 1); - if (rc) { - pr_err("Failed to read battery soc rc: %d\n", rc); - goto out; - } - - batt_soc = reg[0] | reg[1] << 8 | reg[2] << 16; + batt_soc = get_battery_soc_raw(chip); if (batt_soc > ESR_PULSE_RECONFIG_SOC) { if (fg_debug_mask & FG_POWER_SUPPLY) @@ -1096,6 +1190,233 @@ static bool fg_is_batt_empty(struct fg_chip *chip) return (fg_soc_sts & SOC_EMPTY) != 0; } +#ifdef VENDOR_EDIT +#define SOC_SHUTDOWN_VALID_LIMITS 20 +#define TEN_MINUTES 600 +#define CAPACITY_SALTATE_COUNTER_60 30//40 1min +#define CAPACITY_SALTATE_COUNTER_95 70//60 2.5min +#define CAPACITY_SALTATE_COUNTER_FULL 200//150//120 5min +#define CAPACITY_SALTATE_COUNTER_CHARGING_TERM 30//30 1min +#define CAPACITY_SALTATE_COUNTER 4 +#define CAPACITY_SALTATE_COUNTER_NOT_CHARGING 24// >=40sec +#define LOW_BATTERY_PROTECT_VOLTAGE 3450*1000 +#define CAPACITY_CALIBRATE_TIME_60_PERCENT 45 //45s + +extern int get_charging_status(void); +extern int fuelgauge_battery_temp_region_get(void); +extern int load_soc(void); +extern void backup_soc_ex(int soc); +extern bool get_oem_charge_done_status(void); + +static int fg_soc_calibrate(struct fg_chip *di, int soc) +{ + union power_supply_propval ret = {0,}; + unsigned int soc_calib; + int counter_temp = 0; + static int charging_status = 0; + static int charging_status_pre = 0; + static int i=0; + int soc_load; + int soc_temp; + static unsigned long soc_pre_time; + unsigned long soc_current_time,time_last; + if(4> i)/* FG may do not prepare soc ok, do not calibrate soc 3 times*/ + { + i=i+1; + if(4==i) + { + soc_load = load_soc(); //get the soc before reboot + + di->batt_psy = power_supply_get_by_name("battery"); + if(di->batt_psy ){ + + //soc_load = load_soc(); + pr_err("soc=%d,soc_load:%d\n", soc,soc_load); + if (soc_load == -1) { + //get last soc error + di->soc_pre = soc; + } else if(abs(soc - soc_load) > SOC_SHUTDOWN_VALID_LIMITS) { + //the battery maybe changed + di->soc_pre = soc; + } else { + //compare the soc and the last soc + if(soc_load > soc +3) { + di->soc_pre = soc_load -1; + } else { + di->soc_pre = soc_load; + } + } + + if (!di->batt_psy) { + + pr_info(": %d di->soc_pre %d\n",__LINE__,di->soc_pre); + return di->soc_pre; + } + //store the soc when boot first time + backup_soc_ex(di->soc_pre); + get_current_time(&soc_pre_time); + } + } + else + return soc; + } + + soc_temp = di->soc_pre; + + if(di->batt_psy){ + ret.intval = get_charging_status(); + di->batt_vol_pre= get_sram_prop_now(di, FG_DATA_VOLTAGE); + if((fuelgauge_battery_temp_region_get() == CV_BATTERY_TEMP_REGION__LITTLE_COOL + || fuelgauge_battery_temp_region_get() == CV_BATTERY_TEMP_REGION__NORMAL)&&(get_oem_charge_done_status( )==true)) + { + ret.intval = POWER_SUPPLY_STATUS_FULL; /* when battery temperature is cool or normal,we disable charge after charge done,in this case battery status must deal with FULL*/ + + } + + if(ret.intval == POWER_SUPPLY_STATUS_CHARGING || ret.intval == POWER_SUPPLY_STATUS_FULL) { // is charging + charging_status = 1; + } else { + charging_status = 0; + } + if (charging_status ^ charging_status_pre) { + charging_status_pre = charging_status; + di->saltate_counter = 0; + } + get_current_time(&soc_current_time); + time_last= soc_current_time - soc_pre_time; + if (charging_status) { // is charging + if (ret.intval == POWER_SUPPLY_STATUS_FULL) { + soc_calib = di->soc_pre; + if (di->soc_pre < 100 + && (fuelgauge_battery_temp_region_get() == CV_BATTERY_TEMP_REGION__LITTLE_COOL + || fuelgauge_battery_temp_region_get() == CV_BATTERY_TEMP_REGION__NORMAL)) { + if (di->saltate_counter < CAPACITY_SALTATE_COUNTER_CHARGING_TERM) { + di->saltate_counter++; + } else { + soc_calib = di->soc_pre + 1; + di->saltate_counter = 0; + } + } + } else { + + if(soc - di->soc_pre > 0) { + di->saltate_counter++; + if(di->saltate_counter < CAPACITY_SALTATE_COUNTER) + return di->soc_pre; + else + di->saltate_counter = 0; + soc_calib = di->soc_pre + 1; + } + else if(soc < (di->soc_pre - 1)){ + di->saltate_counter++; + + if (di->soc_pre == 100) { + counter_temp = CAPACITY_SALTATE_COUNTER_FULL;//t>=5min + } else if (di->soc_pre > 95) { + counter_temp = CAPACITY_SALTATE_COUNTER_95;///t>=2.5min + } else if (di->soc_pre > 60) { + counter_temp = CAPACITY_SALTATE_COUNTER_60;//t>=1min + }else { + if(time_last > CAPACITY_CALIBRATE_TIME_60_PERCENT && (soc - di->soc_pre)<0) + counter_temp = 0; + else + counter_temp = CAPACITY_SALTATE_COUNTER_NOT_CHARGING;//t>=40sec + } + //pr_err("YFB ELSE counter_temp=%d\n",counter_temp); + /* when batt_vol is too low(and soc is jumping), decrease faster to avoid dead battery shutdown */ + if(di->batt_vol_pre <= LOW_BATTERY_PROTECT_VOLTAGE && di->batt_vol_pre > 2500 * 1000 && di->soc_pre <= 10) { + if (get_sram_prop_now(di, FG_DATA_VOLTAGE) <= LOW_BATTERY_PROTECT_VOLTAGE && get_sram_prop_now(di, FG_DATA_VOLTAGE) > 2500 * 1000) {//check again + counter_temp = CAPACITY_SALTATE_COUNTER - 1;//about 9s + } + } + + if(di->saltate_counter < counter_temp) + return di->soc_pre; + else + di->saltate_counter = 0; + + soc_calib = di->soc_pre - 1; + + } + else if((soc ==0 && soc < di->soc_pre )&&(di->soc_pre <=2 )){ + di->saltate_counter++; + if(time_last > CAPACITY_CALIBRATE_TIME_60_PERCENT && (soc - di->soc_pre)<0) + counter_temp = 0; + else + counter_temp = CAPACITY_SALTATE_COUNTER_NOT_CHARGING;//t>=40sec + if(di->saltate_counter < counter_temp) + return di->soc_pre; + else + di->saltate_counter = 0; + soc_calib = di->soc_pre - 1; + } + else { + soc_calib = di->soc_pre; + } + + + } + } else { // not charging + if ((abs(soc - di->soc_pre) > 0) + || (di->batt_vol_pre <= LOW_BATTERY_PROTECT_VOLTAGE && di->batt_vol_pre > 2500 * 1000)) {// add for batt_vol is too low but soc is not jumping + di->saltate_counter++; + if(di->soc_pre == 100) { + counter_temp = CAPACITY_SALTATE_COUNTER_FULL;//t>=5min + } else if (di->soc_pre > 95) { + counter_temp = CAPACITY_SALTATE_COUNTER_95;///t>=2.5min + } else if (di->soc_pre > 60) { + counter_temp = CAPACITY_SALTATE_COUNTER_60;//t>=1min + } else { + if(time_last > CAPACITY_CALIBRATE_TIME_60_PERCENT && (soc - di->soc_pre)<0) + { + counter_temp = 0; + } + else + counter_temp = CAPACITY_SALTATE_COUNTER_NOT_CHARGING;//t>=40sec + } + /* when batt_vol is too low(and soc is jumping), decrease faster to avoid dead battery shutdown */ + if (di->batt_vol_pre <= LOW_BATTERY_PROTECT_VOLTAGE && di->batt_vol_pre > 2500 * 1000 && di->soc_pre <= 10) { + if (get_sram_prop_now(di, FG_DATA_VOLTAGE) <= LOW_BATTERY_PROTECT_VOLTAGE && get_sram_prop_now(di, FG_DATA_VOLTAGE) > 2500 * 1000) {//check again + counter_temp = CAPACITY_SALTATE_COUNTER - 1;//about 9s + } + } + + if(di->saltate_counter < counter_temp) + return di->soc_pre; + else + di->saltate_counter = 0; + } + else + di->saltate_counter = 0; + + if(soc < di->soc_pre) + soc_calib = di->soc_pre - 1; + else if (di->batt_vol_pre <= LOW_BATTERY_PROTECT_VOLTAGE && di->batt_vol_pre > 2500 * 1000 && di->soc_pre > 0)// add for batt_vol is too low but soc is not jumping + soc_calib = di->soc_pre - 1; + else + soc_calib = di->soc_pre; + + } + } else { + + soc_calib = soc; + } + if(soc_calib > 100) + soc_calib = 100; + if(soc_calib < 0) + soc_calib = 0; + di->soc_pre = soc_calib; + + if(soc_temp != soc_calib) { + get_current_time(&soc_pre_time); + //store when soc changed + backup_soc_ex(soc_calib); + pr_info("soc:%d, soc_calib:%d\n", soc, soc_calib); + } + + return soc_calib; +} +#endif #define EMPTY_CAPACITY 0 #define DEFAULT_CAPACITY 50 @@ -1108,12 +1429,27 @@ static int get_prop_capacity(struct fg_chip *chip) if (chip->battery_missing) return MISSING_CAPACITY; if (!chip->profile_loaded && !chip->use_otp_profile) - return DEFAULT_CAPACITY; + { +#ifdef VENDOR_EDIT /* modify to fix bug:SND-2282,*/ + capacity=load_soc(); + if(capacity >= 0) + return capacity;//report backup soc + else + return DEFAULT_CAPACITY; +#else + return DEFAULT_CAPACITY; +#endif + } if (chip->soc_empty) { if (fg_debug_mask & FG_POWER_SUPPLY) pr_info_ratelimited("capacity: %d, EMPTY\n", EMPTY_CAPACITY); + #ifdef VENDOR_EDIT + capacity =0; + goto OEM_SOC_CALIBRATE; + #else return EMPTY_CAPACITY; + #endif } while (tries < MAX_TRIES_SOC) { rc = fg_read(chip, cap, @@ -1141,6 +1477,13 @@ static int get_prop_capacity(struct fg_chip *chip) if (fg_debug_mask & FG_POWER_SUPPLY) pr_info_ratelimited("capacity: %d, raw: 0x%02x\n", capacity, cap[0]); + #ifdef VENDOR_EDIT + OEM_SOC_CALIBRATE: + if(chip->allow_get_real_fg_soc == false) + { + capacity =fg_soc_calibrate(chip, capacity); + } + #endif return capacity; } @@ -1156,6 +1499,7 @@ static u8 bias_ua[] = { static int64_t get_batt_id(unsigned int battery_id_uv, u8 bid_info) { u64 battery_id_ohm; + pr_info("qpnp-fg battery_id_uv= %d\n",battery_id_uv); if (!(bid_info & 0x3) >= 1) { pr_err("can't determine battery id %d\n", bid_info); @@ -1163,7 +1507,7 @@ static int64_t get_batt_id(unsigned int battery_id_uv, u8 bid_info) } battery_id_ohm = div_u64(battery_id_uv, bias_ua[bid_info & 0x3]); - + pr_info("qpnp-fg battery_id_ohm= %lld\n",battery_id_ohm); return battery_id_ohm; } @@ -1271,6 +1615,63 @@ static int64_t float_decode(u16 reg) return final_val; } +#define MIN_HALFFLOAT_EXP_N -15 +#define MAX_HALFFLOAT_EXP_N 16 +static int log2_floor(int64_t uval) +{ + int n = 0; + int64_t i = MICRO_UNIT; + + if (uval > i) { + while (uval > i && n > MIN_HALFFLOAT_EXP_N) { + i <<= 1; + n += 1; + } + if (uval < i) + n -= 1; + } else if (uval < i) { + while (uval < i && n < MAX_HALFFLOAT_EXP_N) { + i >>= 1; + n -= 1; + } + } + + return n; +} + +static int64_t exp2_int(int64_t n) +{ + int p = n - 1; + + if (p > 0) + return (2 * MICRO_UNIT) << p; + else + return (2 * MICRO_UNIT) >> abs(p); +} + +static u16 float_encode(int64_t uval) +{ + int sign = 0, n, exp, mantissa; + u16 half = 0; + + if (uval < 0) { + sign = 1; + uval = abs(uval); + } + n = log2_floor(uval); + exp = n + 15; + mantissa = div_s64(div_s64((uval - exp2_int(n)) * exp2_int(10 - n), + MICRO_UNIT) + MICRO_UNIT / 2, MICRO_UNIT); + + half = (mantissa & MANTISSA_MASK) | ((sign << 10) & SIGN) + | ((exp << 11) & EXPONENT_MASK); + + if (fg_debug_mask & FG_STATUS) + pr_info("uval = %lld, m = 0x%02x, sign = 0x%02x, exp = 0x%02x, half = 0x%04x\n", + uval, mantissa, sign, exp, half); + return half; +} + #define BATT_IDED BIT(3) static int fg_is_batt_id_valid(struct fg_chip *chip) { @@ -1312,10 +1713,13 @@ static int64_t twos_compliment_extend(int64_t val, int nbytes) #define LSB_8B 9800 #define TEMP_LSB_16B 625 #define DECIKELVIN 2730 +#ifdef VENDOR_EDIT +#define SRAM_PERIOD_UPDATE_MS 5000 +#else #define SRAM_PERIOD_UPDATE_MS 30000 +#endif #define SRAM_PERIOD_NO_ID_UPDATE_MS 100 #define FULL_PERCENT_28BIT 0xFFFFFFF -#define FULL_PERCENT_3B 0xFFFFFF static void update_sram_data(struct fg_chip *chip, int *resched_ms) { int i, j, rc = 0; @@ -1642,6 +2046,15 @@ static int fg_get_cycle_count(struct fg_chip *chip) return cyc_count; } +static void half_float_to_buffer(int64_t uval, u8 *buffer) +{ + u16 raw; + + raw = float_encode(uval); + buffer[0] = (u8)(raw & 0xFF); + buffer[1] = (u8)((raw >> 8) & 0xFF); +} + static int64_t half_float(u8 *buffer) { u16 val; @@ -1759,9 +2172,7 @@ static int estimate_battery_age(struct fg_chip *chip, int *actual_capacity) goto done; } - rc = fg_mem_read(chip, buffer, BATTERY_SOC_REG, 3, 1, 0); - battery_soc = ((int)(buffer[2] << 16 | buffer[1] << 8 | buffer[0])) - * 100 / FULL_PERCENT_3B; + battery_soc = get_battery_soc_raw(chip) * 100 / FULL_PERCENT_3B; if (rc) { goto error_done; } else if (battery_soc < 25 || battery_soc > 75) { @@ -2232,16 +2643,7 @@ static int fg_cap_learning_check(struct fg_chip *chip) goto fail; fg_mem_lock(chip); - - rc = fg_mem_read(chip, data, BATTERY_SOC_REG, 3, 1, 0); - if (rc) { - pr_err("Failed to read Battery SOC: %d\n", rc); - fg_mem_release(chip); - fg_cap_learning_stop(chip); - goto fail; - } - - battery_soc = (int)(data[2] << 16 | data[1] << 8 | data[0]); + battery_soc = get_battery_soc_raw(chip); if (fg_debug_mask & FG_AGING) pr_info("checking battery soc (%d vs %d)\n", battery_soc * 100 / FULL_PERCENT_3B, @@ -2383,6 +2785,7 @@ static int fg_power_set_property(struct power_supply *psy, case POWER_SUPPLY_PROP_UPDATE_NOW: if (val->intval) update_sram_data(chip, &unused); + pr_err("update_sram_data by set property\n"); break; case POWER_SUPPLY_PROP_STATUS: chip->status = val->intval; @@ -2470,7 +2873,7 @@ static void dump_sram(struct work_struct *work) for (i = 0; i < SRAM_DUMP_LEN; i += 4) { str[0] = '\0'; fill_string(str, DEBUG_PRINT_BUFFER_SIZE, buffer + i, 4); - pr_info("%03X %s\n", SRAM_DUMP_START + i, str); + pr_debug("%03X %s\n", SRAM_DUMP_START + i, str); } devm_kfree(chip->dev, buffer); } @@ -2656,6 +3059,10 @@ static irqreturn_t fg_soc_irq_handler(int irq, void *_chip) if (chip->power_supply_registered) power_supply_changed(&chip->bms_psy); + if (chip->rslow_comp.chg_rs_to_rslow > 0 && + chip->rslow_comp.chg_rslow_comp_c1 > 0 && + chip->rslow_comp.chg_rslow_comp_c2 > 0) + schedule_work(&chip->rslow_comp_work); if (chip->cyc_ctr_en) schedule_work(&chip->cycle_count_work); schedule_work(&chip->update_esr_work); @@ -2709,6 +3116,11 @@ static void fg_external_power_changed(struct power_supply *psy) { struct fg_chip *chip = container_of(psy, struct fg_chip, bms_psy); + if (is_input_present(chip) && chip->rslow_comp.active && + chip->rslow_comp.chg_rs_to_rslow > 0 && + chip->rslow_comp.chg_rslow_comp_c1 > 0 && + chip->rslow_comp.chg_rslow_comp_c2 > 0) + schedule_work(&chip->rslow_comp_work); if (!is_input_present(chip) && chip->resume_soc_lowered) { fg_stay_awake(&chip->resume_soc_wakeup_source); schedule_work(&chip->set_resume_soc_work); @@ -2772,7 +3184,15 @@ static void set_resume_soc_work(struct work_struct *work) #define OCV_JUNCTION_REG 0x4D8 #define NOM_CAP_REG 0x4F4 #define CUTOFF_VOLTAGE_REG 0x40C -static int populate_learning_data(struct fg_chip *chip) +#define RSLOW_CFG_REG 0x538 +#define RSLOW_CFG_OFFSET 2 +#define RSLOW_THRESH_REG 0x52C +#define RSLOW_THRESH_OFFSET 0 +#define TEMP_RS_TO_RSLOW_OFFSET 2 +#define RSLOW_COMP_REG 0x528 +#define RSLOW_COMP_C1_OFFSET 0 +#define RSLOW_COMP_C2_OFFSET 2 +static int populate_system_data(struct fg_chip *chip) { u8 buffer[24]; int rc, i; @@ -2826,11 +3246,158 @@ static int populate_learning_data(struct fg_chip *chip) chip->cutoff_voltage, chip->nom_cap_uah, chip->ocv_junction_p1p2, chip->ocv_junction_p2p3); + + rc = fg_mem_read(chip, buffer, RSLOW_CFG_REG, 1, RSLOW_CFG_OFFSET, 0); + if (rc) { + pr_err("unable to read rslow cfg: %d\n", rc); + goto done; + } + chip->rslow_comp.rslow_cfg = buffer[0]; + rc = fg_mem_read(chip, buffer, RSLOW_THRESH_REG, 1, + RSLOW_THRESH_OFFSET, 0); + if (rc) { + pr_err("unable to read rslow thresh: %d\n", rc); + goto done; + } + chip->rslow_comp.rslow_thr = buffer[0]; + rc = fg_mem_read(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2, + RSLOW_THRESH_OFFSET, 0); + if (rc) { + pr_err("unable to read rs to rslow: %d\n", rc); + goto done; + } + memcpy(chip->rslow_comp.rs_to_rslow, buffer, 2); + rc = fg_mem_read(chip, buffer, RSLOW_COMP_REG, 4, + RSLOW_COMP_C1_OFFSET, 0); + if (rc) { + pr_err("unable to read rslow comp: %d\n", rc); + goto done; + } + memcpy(chip->rslow_comp.rslow_comp, buffer, 4); + done: fg_mem_release(chip); return rc; } +#define RSLOW_CFG_MASK (BIT(2) | BIT(3) | BIT(4) | BIT(5)) +#define RSLOW_CFG_ON_VAL (BIT(2) | BIT(3)) +#define RSLOW_THRESH_FULL_VAL 0xFF +static int fg_rslow_charge_comp_set(struct fg_chip *chip) +{ + int rc; + u8 buffer[2]; + + mutex_lock(&chip->rslow_comp.lock); + fg_mem_lock(chip); + + rc = fg_mem_masked_write(chip, RSLOW_CFG_REG, + RSLOW_CFG_MASK, RSLOW_CFG_ON_VAL, RSLOW_CFG_OFFSET); + if (rc) { + pr_err("unable to write rslow cfg: %d\n", rc); + goto done; + } + rc = fg_mem_masked_write(chip, RSLOW_THRESH_REG, + 0xFF, RSLOW_THRESH_FULL_VAL, RSLOW_THRESH_OFFSET); + if (rc) { + pr_err("unable to write rslow thresh: %d\n", rc); + goto done; + } + + half_float_to_buffer(chip->rslow_comp.chg_rs_to_rslow, buffer); + rc = fg_mem_write(chip, buffer, + TEMP_RS_TO_RSLOW_REG, 2, TEMP_RS_TO_RSLOW_OFFSET, 0); + if (rc) { + pr_err("unable to write rs to rslow: %d\n", rc); + goto done; + } + half_float_to_buffer(chip->rslow_comp.chg_rslow_comp_c1, buffer); + rc = fg_mem_write(chip, buffer, + RSLOW_COMP_REG, 2, RSLOW_COMP_C1_OFFSET, 0); + if (rc) { + pr_err("unable to write rslow comp: %d\n", rc); + goto done; + } + half_float_to_buffer(chip->rslow_comp.chg_rslow_comp_c2, buffer); + rc = fg_mem_write(chip, buffer, + RSLOW_COMP_REG, 2, RSLOW_COMP_C2_OFFSET, 0); + if (rc) { + pr_err("unable to write rslow comp: %d\n", rc); + goto done; + } + chip->rslow_comp.active = true; + if (fg_debug_mask & FG_STATUS) + pr_info("Activated rslow charge comp values\n"); + +done: + fg_mem_release(chip); + mutex_unlock(&chip->rslow_comp.lock); + return rc; +} + +#define RSLOW_CFG_ORIG_MASK (BIT(4) | BIT(5)) +static int fg_rslow_charge_comp_clear(struct fg_chip *chip) +{ + u8 reg; + int rc; + + mutex_lock(&chip->rslow_comp.lock); + fg_mem_lock(chip); + + reg = chip->rslow_comp.rslow_cfg & RSLOW_CFG_ORIG_MASK; + rc = fg_mem_masked_write(chip, RSLOW_CFG_REG, + RSLOW_CFG_MASK, reg, RSLOW_CFG_OFFSET); + if (rc) { + pr_err("unable to write rslow cfg: %d\n", rc); + goto done; + } + rc = fg_mem_masked_write(chip, RSLOW_THRESH_REG, + 0xFF, chip->rslow_comp.rslow_thr, RSLOW_THRESH_OFFSET); + if (rc) { + pr_err("unable to write rslow thresh: %d\n", rc); + goto done; + } + + rc = fg_mem_write(chip, chip->rslow_comp.rs_to_rslow, + TEMP_RS_TO_RSLOW_REG, 2, TEMP_RS_TO_RSLOW_OFFSET, 0); + if (rc) { + pr_err("unable to write rs to rslow: %d\n", rc); + goto done; + } + rc = fg_mem_write(chip, chip->rslow_comp.rslow_comp, + RSLOW_COMP_REG, 4, RSLOW_COMP_C1_OFFSET, 0); + if (rc) { + pr_err("unable to write rslow comp: %d\n", rc); + goto done; + } + chip->rslow_comp.active = false; + if (fg_debug_mask & FG_STATUS) + pr_info("Cleared rslow charge comp values\n"); + +done: + fg_mem_release(chip); + mutex_unlock(&chip->rslow_comp.lock); + return rc; +} + +static void rslow_comp_work(struct work_struct *work) +{ + int battery_soc_1b; + struct fg_chip *chip = container_of(work, + struct fg_chip, + rslow_comp_work); + + battery_soc_1b = get_battery_soc_raw(chip) >> 16; + if (battery_soc_1b > chip->rslow_comp.chg_rslow_comp_thr + && chip->status == POWER_SUPPLY_STATUS_CHARGING) { + if (!chip->rslow_comp.active) + fg_rslow_charge_comp_set(chip); + } else { + if (chip->rslow_comp.active) + fg_rslow_charge_comp_clear(chip); + } +} + #define MICROUNITS_TO_ADC_RAW(units) \ div64_s64(units * LSB_16B_DENMTR, LSB_16B_NUMRTR) static int update_chg_iterm(struct fg_chip *chip) @@ -2925,6 +3492,36 @@ static int fg_batt_profile_init(struct fg_chip *chip) goto fail; } + /* read rslow compensation values if they're available */ + rc = of_property_read_u32(profile_node, "qcom,chg-rs-to-rslow", + &chip->rslow_comp.chg_rs_to_rslow); + if (rc) { + chip->rslow_comp.chg_rs_to_rslow = -EINVAL; + if (rc != -EINVAL) + pr_err("Could not read rs to rslow: %d\n", rc); + } + rc = of_property_read_u32(profile_node, "qcom,chg-rslow-comp-c1", + &chip->rslow_comp.chg_rslow_comp_c1); + if (rc) { + chip->rslow_comp.chg_rslow_comp_c1 = -EINVAL; + if (rc != -EINVAL) + pr_err("Could not read rslow comp c1: %d\n", rc); + } + rc = of_property_read_u32(profile_node, "qcom,chg-rslow-comp-c2", + &chip->rslow_comp.chg_rslow_comp_c2); + if (rc) { + chip->rslow_comp.chg_rslow_comp_c2 = -EINVAL; + if (rc != -EINVAL) + pr_err("Could not read rslow comp c2: %d\n", rc); + } + rc = of_property_read_u32(profile_node, "qcom,chg-rslow-comp-thr", + &chip->rslow_comp.chg_rslow_comp_thr); + if (rc) { + chip->rslow_comp.chg_rslow_comp_thr = -EINVAL; + if (rc != -EINVAL) + pr_err("Could not read rslow comp thr: %d\n", rc); + } + rc = of_property_read_u32(profile_node, "qcom,max-voltage-uv", &chip->batt_max_voltage_uv); @@ -2937,7 +3534,6 @@ static int fg_batt_profile_init(struct fg_chip *chip) rc = 0; goto no_profile; } - if (len != FG_PROFILE_LEN) { pr_err("battery profile incorrect size: %d\n", len); rc = -EINVAL; @@ -3044,8 +3640,8 @@ static int fg_batt_profile_init(struct fg_chip *chip) goto unlock_and_fail; } - rc = fg_masked_write(chip, chip->mem_base + MEM_INTF_CFG, - LOW_LATENCY, LOW_LATENCY, 1); + rc = fg_masked_write(chip, MEM_INTF_CFG(chip), + LOW_LATENCY, LOW_LATENCY, 1); if (rc) { pr_err("failed to set low latency access bit\n"); goto unlock_and_fail; @@ -3068,8 +3664,7 @@ static int fg_batt_profile_init(struct fg_chip *chip) mutex_lock(&chip->rw_lock); fg_release_access(chip); - rc = fg_masked_write(chip, chip->mem_base + MEM_INTF_CFG, - LOW_LATENCY, 0, 1); + rc = fg_masked_write(chip, MEM_INTF_CFG(chip), LOW_LATENCY, 0, 1); if (rc) { pr_err("failed to set low latency access bit\n"); goto unlock_and_fail; @@ -3157,7 +3752,7 @@ static int fg_batt_profile_init(struct fg_chip *chip) chip->battery_missing = is_battery_missing(chip); update_chg_iterm(chip); update_cc_cv_setpoint(chip); - rc = populate_learning_data(chip); + rc = populate_system_data(chip); if (rc) { pr_err("failed to read ocv properties=%d\n", rc); return rc; @@ -3610,6 +4205,7 @@ static void fg_cleanup(struct fg_chip *chip) cancel_delayed_work_sync(&chip->update_jeita_setting); cancel_delayed_work_sync(&chip->check_empty_work); alarm_try_to_cancel(&chip->fg_cap_learning_alarm); + cancel_work_sync(&chip->rslow_comp_work); cancel_work_sync(&chip->set_resume_soc_work); cancel_work_sync(&chip->fg_cap_learning_work); cancel_work_sync(&chip->batt_profile_init); @@ -3619,6 +4215,7 @@ static void fg_cleanup(struct fg_chip *chip) cancel_work_sync(&chip->update_esr_work); cancel_work_sync(&chip->init_work); power_supply_unregister(&chip->bms_psy); + mutex_destroy(&chip->rslow_comp.lock); mutex_destroy(&chip->rw_lock); wakeup_source_trash(&chip->resume_soc_wakeup_source.source); wakeup_source_trash(&chip->empty_check_wakeup_source.source); @@ -4102,27 +4699,16 @@ static int bcl_trim_workaround(struct fg_chip *chip) #define FG_ADC_CONFIG_REG 0x4B8 #define FG_BCL_CONFIG_OFFSET 0x3 #define BCL_FORCED_HPM_IN_CHARGE BIT(2) -static int fg_hw_init(struct fg_chip *chip) +static int fg_common_hw_init(struct fg_chip *chip) { + int rc; u8 resume_soc; - u8 data[4]; - u64 esr_value; - int rc = 0; update_iterm(chip); update_cutoff_voltage(chip); update_irq_volt_empty(chip); update_bcl_thresholds(chip); - rc = fg_mem_masked_write(chip, EXTERNAL_SENSE_SELECT, - PATCH_NEG_CURRENT_BIT, - PATCH_NEG_CURRENT_BIT, - EXTERNAL_SENSE_OFFSET); - if (rc) { - pr_err("failed to write patch current bit rc=%d\n", rc); - return rc; - } - resume_soc = settings[FG_MEM_RESUME_SOC].value; if (resume_soc > 0) { resume_soc = resume_soc * 255 / 100; @@ -4176,6 +4762,30 @@ static int fg_hw_init(struct fg_chip *chip) return rc; } + if (chip->use_thermal_coefficients) { + fg_mem_write(chip, chip->thermal_coefficients, + THERMAL_COEFF_ADDR, THERMAL_COEFF_N_BYTES, + THERMAL_COEFF_OFFSET, 0); + } + + return 0; +} + +static int fg_8994_hw_init(struct fg_chip *chip) +{ + int rc = 0; + u8 data[4]; + u64 esr_value; + + rc = fg_mem_masked_write(chip, EXTERNAL_SENSE_SELECT, + PATCH_NEG_CURRENT_BIT, + PATCH_NEG_CURRENT_BIT, + EXTERNAL_SENSE_OFFSET); + if (rc) { + pr_err("failed to write patch current bit rc=%d\n", rc); + return rc; + } + rc = bcl_trim_workaround(chip); if (rc) { pr_err("failed to redo bcl trim rc=%d\n", rc); @@ -4191,14 +4801,7 @@ static int fg_hw_init(struct fg_chip *chip) return rc; } - if (chip->use_thermal_coefficients) { - fg_mem_write(chip, chip->thermal_coefficients, - THERMAL_COEFF_ADDR, THERMAL_COEFF_N_BYTES, - THERMAL_COEFF_OFFSET, 0); - } - - fg_mem_masked_write(chip, FG_ALG_SYSCTL_1, I_TERM_QUAL_BIT, - I_TERM_QUAL_BIT, 0); + fg_mem_masked_write(chip, FG_ALG_SYSCTL_1, I_TERM_QUAL_BIT, 0, 0); data[0] = 0xA2; data[1] = 0x12; @@ -4233,6 +4836,111 @@ static int fg_hw_init(struct fg_chip *chip) return 0; } +static int fg_8950_hw_init(struct fg_chip *chip) +{ + int rc; + + rc = fg_mem_masked_write(chip, FG_ADC_CONFIG_REG, + BCL_FORCED_HPM_IN_CHARGE, + BCL_FORCED_HPM_IN_CHARGE, + FG_BCL_CONFIG_OFFSET); + if (rc) + pr_err("failed to force hpm in charge rc=%d\n", rc); + + return rc; +} + +static int fg_hw_init(struct fg_chip *chip) +{ + int rc = 0; + + rc = fg_common_hw_init(chip); + if (rc) { + pr_err("Unable to initilize FG HW rc=%d\n", rc); + return rc; + } + + /* add PMIC specific hw init */ + switch (chip->pmic_subtype) { + case PMI8994: + rc = fg_8994_hw_init(chip); + break; + case PMI8950: + rc = fg_8950_hw_init(chip); + break; + } + if (rc) + pr_err("Unable to initialize PMIC specific FG HW rc=%d\n", rc); + + return rc; +} + +#define DIG_MINOR 0x0 +#define DIG_MAJOR 0x1 +#define ANA_MINOR 0x2 +#define ANA_MAJOR 0x3 +static int fg_setup_memif_offset(struct fg_chip *chip) +{ + int rc; + u8 dig_major; + + rc = fg_read(chip, chip->revision, chip->mem_base + DIG_MINOR, 4); + if (rc) { + pr_err("Unable to read FG revision rc=%d\n", rc); + return rc; + } + + switch (chip->revision[DIG_MAJOR]) { + case DIG_REV_8994_1: + case DIG_REV_8994_2: + chip->offset = offset[0].address; + break; + default: + pr_err("Digital Major rev=%d not supported\n", dig_major); + return -EINVAL; + } + + return 0; +} + +static int fg_detect_pmic_type(struct fg_chip *chip) +{ + struct pmic_revid_data *pmic_rev_id; + struct device_node *revid_dev_node; + + revid_dev_node = of_parse_phandle(chip->spmi->dev.of_node, + "qcom,pmic-revid", 0); + if (!revid_dev_node) { + pr_err("Missing qcom,pmic-revid property - driver failed\n"); + return -EINVAL; + } + + pmic_rev_id = get_revid_data(revid_dev_node); + if (IS_ERR(pmic_rev_id)) { + pr_err("Unable to get pmic_revid rc=%ld\n", + PTR_ERR(pmic_rev_id)); + /* + * the revid peripheral must be registered, any failure + * here only indicates that the rev-id module has not + * probed yet. + */ + return -EPROBE_DEFER; + } + + switch (pmic_rev_id->pmic_subtype) { + case PMI8994: + case PMI8950: + chip->pmic_subtype = pmic_rev_id->pmic_subtype; + break; + default: + pr_err("PMIC subtype %d not supported\n", + pmic_rev_id->pmic_subtype); + return -EINVAL; + } + + return 0; +} + #define INIT_JEITA_DELAY_MS 1000 static void delayed_init_work(struct work_struct *work) @@ -4256,9 +4964,12 @@ static void delayed_init_work(struct work_struct *work) schedule_delayed_work( &chip->update_jeita_setting, msecs_to_jiffies(INIT_JEITA_DELAY_MS)); - - if (chip->last_sram_update_time == 0) - update_sram_data_work(&chip->update_sram_data.work); +#ifdef VENDOR_EDIT //yangfangbiao@oneplus.cn modified to save bug:SND-9288,SND-8082 + //do nothing ,sometimes ,charger will update sram data before schedule_delayed_work ,that cause update_sram_data_work does not work noraml +#else +if (chip->last_sram_update_time == 0) +#endif + update_sram_data_work(&chip->update_sram_data.work); if (chip->last_temp_update_time == 0) update_temp_data(&chip->update_temp_work.work); @@ -4315,10 +5026,12 @@ static int fg_probe(struct spmi_device *spmi) mutex_init(&chip->rw_lock); mutex_init(&chip->cyc_ctr_lock); mutex_init(&chip->learning_data.learning_lock); + mutex_init(&chip->rslow_comp.lock); INIT_DELAYED_WORK(&chip->update_jeita_setting, update_jeita_setting); INIT_DELAYED_WORK(&chip->update_sram_data, update_sram_data_work); INIT_DELAYED_WORK(&chip->update_temp_work, update_temp_data); INIT_DELAYED_WORK(&chip->check_empty_work, check_empty_work); + INIT_WORK(&chip->rslow_comp_work, rslow_comp_work); INIT_WORK(&chip->fg_cap_learning_work, fg_cap_learning_work); INIT_WORK(&chip->batt_profile_init, batt_profile_init); INIT_WORK(&chip->dump_sram, dump_sram); @@ -4388,6 +5101,18 @@ static int fg_probe(struct spmi_device *spmi) } } + rc = fg_detect_pmic_type(chip); + if (rc) { + pr_err("Unable to detect PMIC type rc=%d\n", rc); + return rc; + } + + rc = fg_setup_memif_offset(chip); + if (rc) { + pr_err("Unable to setup mem_if offsets rc=%d\n", rc); + goto of_init_fail; + } + rc = fg_of_init(chip); if (rc) { pr_err("failed to parse devicetree rc%d\n", rc); @@ -4439,9 +5164,16 @@ static int fg_probe(struct spmi_device *spmi) goto power_supply_unregister; } } +#ifdef VENDOR_EDIT + #define REDO_BATID_DURING_FIRST_EST BIT(4) + reg = REDO_BATID_DURING_FIRST_EST | RESTART_GO; + rc = fg_masked_write(chip, chip->soc_base + SOC_RESTART, + reg, reg, 1); + pr_info("%s == redetect battery ID rc = %d\n",__func__,rc); +#endif/* VENDOR_EDIT */ schedule_work(&chip->init_work); - + chip->allow_get_real_fg_soc =false; pr_info("probe success\n"); return rc; @@ -4460,8 +5192,10 @@ static int fg_probe(struct spmi_device *spmi) cancel_work_sync(&chip->status_change_work); cancel_work_sync(&chip->cycle_count_work); cancel_work_sync(&chip->update_esr_work); + cancel_work_sync(&chip->rslow_comp_work); cancel_work_sync(&chip->init_work); of_init_fail: + mutex_destroy(&chip->rslow_comp.lock); mutex_destroy(&chip->rw_lock); mutex_destroy(&chip->cyc_ctr_lock); mutex_destroy(&chip->learning_data.learning_lock); @@ -4507,6 +5241,7 @@ static int fg_suspend(struct device *dev) { struct fg_chip *chip = dev_get_drvdata(dev); + get_current_time(&chip->enter_suspend_time); if (!chip->sw_rbias_ctrl) return 0; @@ -4515,10 +5250,27 @@ static int fg_suspend(struct device *dev) return 0; } - +#define ONE_MIN 60 //1min static int fg_resume(struct device *dev) { + unsigned long reusme_time; + unsigned long suspend_last_time; + int soc; struct fg_chip *chip = dev_get_drvdata(dev); +#ifdef VENDOR_EDIT //add for sleep long time ,soc not jump + chip->allow_get_real_fg_soc =true;//do not calibrate soc + soc = get_prop_capacity(chip); + chip->allow_get_real_fg_soc =false; + if(soc >= 90) + soc += 2; + get_current_time(&reusme_time); + suspend_last_time=reusme_time - chip->enter_suspend_time; + if((suspend_last_time >= ONE_MIN) && (chip->soc_pre - soc) >= 1) //sleep time > 1min,calibrate soc set to fg real soc + { + pr_err("chip->soc_pre=%d,soc=%d,suspend_last_time=%ld\n",chip->soc_pre,soc,suspend_last_time); + chip->soc_pre = soc; + } +#endif if (!chip->sw_rbias_ctrl) return 0; diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c old mode 100644 new mode 100755 index c6469e672f53d..66a7783c4bbab --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -37,6 +37,11 @@ #include #include #include +#if defined(CONFIG_FB) +/* yangfangbiao@oneplus.cn,20150519 Add for reset charge current when screen is off */ +#include +#include +#endif/*CONFIG_FB*/ /* Mask/Bit helpers */ #define _SMB_MASK(BITS, POS) \ @@ -44,6 +49,89 @@ #define SMB_MASK(LEFT_BIT_POS, RIGHT_BIT_POS) \ _SMB_MASK((LEFT_BIT_POS) - (RIGHT_BIT_POS) + 1, \ (RIGHT_BIT_POS)) + +#ifdef VENDOR_EDIT +#define AICL_INIT_FUNCTION_MASK BIT(7) + +static bool use_fake_temp = false; +static int fake_temp = 300; +static bool use_fake_chgvol = false; +static int fake_chgvol = 0; +static bool use_fake_authentic = false; +static int fake_authentic = 0; + + +/*Modify for V2.4 charge standard */ +#define BATT_HEARTBEAT_INTERVAL 6000//6S +#define AUTO_CHARGING_BATT_TEMP_T0 -30 +#define AUTO_CHARGING_BATT_TEMP_T1 0 +#define AUTO_CHARGING_BATT_TEMP_T2 100 +#define AUTO_CHARGING_BATT_TEMP_T3 200 +#define AUTO_CHARGING_BATT_TEMP_T4 450 +#define AUTO_CHARGING_BATT_TEMP_T5 550 +#define AUTO_CHARGING_BATT_REMOVE_TEMP -400 +#define AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_HOT_TO_WARM 20 +#define AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_WARM_TO_NORMAL 20 +#define AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COOL_TO_NORMAL 20 +#define AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COLD_TO_COOL 20 +#define CHG_CURRENT_500MA 500 +#define CHG_CURRENT_300MA 300 +#define CHG_CURRENT_900MA 900 +#define CHG_CURRENT_1500MA 1500 +#define CHARGER_SOFT_OVP_VOLTAGE 5800 +#define CHARGER_SOFT_UVP_VOLTAGE 4300 +#define CHARGER_VOLTAGE_NORMAL 5000 +#define BATTERY_SOFT_OVP_VOLTAGE 4500 * 1000 +#define BATT_CHG_TIMEOUT_COUNT_DCP 10*10*60// //6*10*60//4 //10HOURS +#define BATT_CHG_TIMEOUT_COUNT_USB_PRO 10*10*60 //10HOURS + + +typedef enum{ + /* The charger is good */ + CHARGER_STATUS_GOOD, + /* The charger is bad */ + CHARGER_STATUS_BAD, + /* The charger is weak */ + CHARGER_STATUS_WEAK, + CHARGER_STATUS_OVER, + /* Invalid charger status. */ + CHARGER_STATUS_INVALID +}chg_charger_status_type; +enum chg_battery_status_type { + /* The battery is good */ + BATTERY_STATUS_GOOD, + /* The battery is cold/hot */ + BATTERY_STATUS_BAD_TEMP, + /* The battery is bad */ + BATTERY_STATUS_BAD, + /* The battery is removed */ + BATTERY_STATUS_REMOVED, /* on v2.2 only */ + BATTERY_STATUS_INVALID_v1 = BATTERY_STATUS_REMOVED, + /* Invalid battery status. */ + BATTERY_STATUS_INVALID +}; + +typedef enum{ + /*! Battery is cold */ + CV_BATTERY_TEMP_REGION__COLD, + /*! Battery is little cold */ + CV_BATTERY_TEMP_REGION_LITTLE__COLD, + /*! Battery is cool */ + CV_BATTERY_TEMP_REGION__COOL, + /*! Battery is little cool */ + CV_BATTERY_TEMP_REGION__LITTLE_COOL, + /*! Battery is normal */ + CV_BATTERY_TEMP_REGION__NORMAL, + /*! Battery is warm */ + CV_BATTERY_TEMP_REGION__WARM, + /*! Battery is hot */ + CV_BATTERY_TEMP_REGION__HOT, + /*! Invalid battery temp region */ + CV_BATTERY_TEMP_REGION__INVALID, +}chg_cv_battery_temp_region_type; + +#endif + /* Config registers */ struct smbchg_regulator { struct regulator_desc rdesc; @@ -131,6 +219,7 @@ struct smbchg_chip { struct ilim_map wipower_pt; struct ilim_map wipower_div2; struct qpnp_vadc_chip *vadc_dev; + struct qpnp_vadc_chip *vadc_dev_pm8994; bool wipower_dyn_icl_avail; struct ilim_entry current_ilim; struct mutex wipower_config; @@ -232,9 +321,65 @@ struct smbchg_chip { struct mutex usb_status_lock; /* apsd workaround */ struct work_struct rerun_apsd_work; + bool do_apsd_reruns; bool apsd_rerun; bool apsd_rerun_ignore_uv_irq; struct completion apsd_src_det_lowered; + bool oem_lcd_is_on; + int lcd_on_iusb; +#ifdef VENDOR_EDIT +/*Modify for V2.4 charge standard */ +chg_cv_battery_temp_region_type mBatteryTempRegion; +chg_charger_status_type charger_status; +enum chg_battery_status_type battery_status; + +short mBatteryTempBoundT0; +short mBatteryTempBoundT1; +short mBatteryTempBoundT2; +short mBatteryTempBoundT3; +short mBatteryTempBoundT4; +short mBatteryTempBoundT5; +bool oem_disable_charge; +bool oem_enable_charge; +bool chg_done; +bool recharge_pending; +bool recharge_status; + +int temp_more_cool_vbatdel ; +int temp_more_cool_rechgvbat; +int temp_cool_vbatdel ; +int temp_cool_recharge_vbatdel; + + +int temp_littel_cool_vbatdel; +int temp_littel_cool_recharge_vbatdel; + + + +int temp_normal_vbatdel ; +int temp_normal_recharge_vbatdel; + +int temp_warm_vbatdel ; +int temp_warm_recharge_vbatdel; + + +int temp_more_cool_current ;// 300 +int temp_cool_current ; // 900 +int temp_littel_cool_current;// 1500 +int temp_normal_current ;// 2000 +int temp_warm_current ;// 900 + +struct delayed_work update_heartbeat_work; +int batt_health; +bool is_power_changed; +unsigned int aicl_current; +bool time_out; +#endif +#if defined(CONFIG_FB) + /* yangfangbiao@oneplus.cn,20150519 Add for reset charge current when screen is off */ + struct notifier_block fb_notif; +#endif /*CONFIG_FB*/ + }; enum print_reason { @@ -258,7 +403,7 @@ module_param_named( debug_mask, smbchg_debug_mask, int, S_IRUSR | S_IWUSR ); -static int smbchg_parallel_en; +static int smbchg_parallel_en = 1; module_param_named( parallel_en, smbchg_parallel_en, int, S_IRUSR | S_IWUSR ); @@ -298,6 +443,22 @@ module_param_named( pr_debug_ratelimited(fmt, ##__VA_ARGS__); \ } while (0) +#ifdef VENDOR_EDIT +struct smbchg_chip *g_chip; +static int smbchg_charging_en(struct smbchg_chip *chip, bool en); +static int get_prop_charger_voltage_now(struct smbchg_chip *chip); +static chg_cv_battery_temp_region_type qpnp_battery_temp_region_get(struct smbchg_chip *chip); +static void qpnp_check_charger_uovp(struct smbchg_chip *chip); +static int qpnp_check_battery_temp(struct smbchg_chip *chip); +static int get_prop_charger_voltage_now(struct smbchg_chip *chip); +static int smbchg_set_high_usb_chg_current(struct smbchg_chip *chip, + int current_ma); +static int smbchg_set_fastchg_current(struct smbchg_chip *chip, + int current_ma); +static void qpnp_battery_temp_region_set(struct smbchg_chip *chip, + chg_cv_battery_temp_region_type batt_temp_region); +#endif + static int smbchg_read(struct smbchg_chip *chip, u8 *val, u16 addr, int count) { @@ -645,7 +806,7 @@ static inline char *get_usb_type_name(int type) static enum power_supply_type usb_type_enum[] = { POWER_SUPPLY_TYPE_USB, /* bit 0 */ - POWER_SUPPLY_TYPE_UNKNOWN, /* bit 1 */ + POWER_SUPPLY_TYPE_USB_DCP, /* bit 1 */ POWER_SUPPLY_TYPE_USB_DCP, /* bit 2 */ POWER_SUPPLY_TYPE_USB_CDP, /* bit 3 */ POWER_SUPPLY_TYPE_USB, /* bit 4 error case, report SDP */ @@ -671,6 +832,10 @@ static enum power_supply_property smbchg_battery_properties[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, +#ifdef VENDOR_EDIT + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_AUTHENTIC, +#endif POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -847,10 +1012,183 @@ static int get_prop_batt_capacity(struct smbchg_chip *chip) return capacity; } +#ifdef VENDOR_EDIT +#define MAX_COUNT 50 +#define SOFT_AICL_VOL 4465 //4555 + +static int soft_aicl(struct smbchg_chip *chip) +{ + int i, current_ma,chg_vol; + pr_debug("soft aicl s2:%s\n", __func__); + //qpnp_chg_vinmin_set(chip, 4440); + smbchg_set_high_usb_chg_current(chip, 400); + smbchg_set_fastchg_current(chip, chip->target_fastchg_current_ma); + smbchg_charging_en(chip, 1); + for (i = 0; i < MAX_COUNT / 5; i++) { + chg_vol = get_prop_charger_voltage_now(chip); + if (chg_vol < (SOFT_AICL_VOL - 50)) { + chip->aicl_current = 300; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + pr_info("soft aicl s1:%d\n", chg_vol); + smbchg_set_high_usb_chg_current(chip, 300); + return 0; + } + } +for(current_ma=500;current_ma< 1200;current_ma+= 100) +{ + smbchg_set_high_usb_chg_current(chip, current_ma); + for (i = 0; i < MAX_COUNT / 5; i++) { + if (!chip->usb_present) + goto aicl_err; + chg_vol = get_prop_charger_voltage_now(chip); + if (chg_vol < (SOFT_AICL_VOL - 50)) { + pr_info("soft aicl s2:%d\n", chg_vol); + smbchg_set_high_usb_chg_current(chip, current_ma-100); + chip->aicl_current = current_ma-100; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + return 0; + } + } +} +for(current_ma=1200;current_ma< 1900;current_ma+= 100) +{ + smbchg_set_high_usb_chg_current(chip, current_ma); + for (i = 0; i < MAX_COUNT + 30; i++) { + if (!chip->usb_present) { + //goto aicl_err; + smbchg_set_high_usb_chg_current(chip, current_ma-100); + chip->aicl_current = current_ma-100; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + //chip->aicl_interrupt = true; + return 0; + } + if (i == 20) + smbchg_set_fastchg_current(chip, current_ma-300); + else if (i == 40) + smbchg_set_fastchg_current(chip, current_ma-200); + else if (i == 60) + smbchg_set_fastchg_current(chip, current_ma); + chg_vol = get_prop_charger_voltage_now(chip); + if (chg_vol < SOFT_AICL_VOL) { + smbchg_set_high_usb_chg_current(chip, current_ma-100); + chip->aicl_current = current_ma-100; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + if (!chip->usb_present) { + //chip->aicl_interrupt = true; + } + return 0; + } + } +} + + smbchg_set_high_usb_chg_current(chip, 2000); + for (i = 0; i < MAX_COUNT + 30; i++) { + if (!chip->usb_present) { + //goto aicl_err; + smbchg_set_high_usb_chg_current(chip, 1500); + chip->aicl_current = 1500; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + //chip->aicl_interrupt = true; + return 0; + } + if (i == 20) + smbchg_set_fastchg_current(chip, 1600); + else if (i == 40) + smbchg_set_fastchg_current(chip, 1850); + else if (i == 60) + smbchg_set_fastchg_current(chip, 2000); + chg_vol = get_prop_charger_voltage_now(chip); + if (chg_vol < SOFT_AICL_VOL - 30) { + + smbchg_set_high_usb_chg_current(chip, 1850); + chip->aicl_current = 1850; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + if (!chip->usb_present) { + //chip->aicl_interrupt = true; + } + return 0; + } + } + + smbchg_set_high_usb_chg_current(chip, 2000); + chip->aicl_current = 2000; + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + return 0; + +aicl_err: + chip->aicl_current = 0; + return 0; +} + +static ssize_t test_chg_vol_show(struct device *dev, + struct device_attribute *attr, char *buf) { + return sprintf(buf, "%d\n", fake_chgvol); +} +static ssize_t test_chg_vol_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) { + long val = simple_strtol(buf, NULL, 10); + + if(val == 9898) { + use_fake_chgvol= false; + fake_chgvol= 0; + }else { + use_fake_chgvol = true; + fake_chgvol = val; + } + + return size; +} +static DEVICE_ATTR(test_chg_vol, S_IRUGO | S_IWUSR, test_chg_vol_show, test_chg_vol_store); + +static ssize_t test_temp_show(struct device *dev,struct device_attribute *attr, char *buf){ + return sprintf(buf, "%d\n", fake_temp); +} +static ssize_t test_temp_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size) +{ + long val = simple_strtol(buf, NULL, 10); + + if(val == 9898) { + use_fake_temp = false; + fake_temp = 300; + }else { + use_fake_temp = true; + fake_temp = val; + } + + return size; +} + +static DEVICE_ATTR(test_temp, S_IRUGO | S_IWUSR, test_temp_show, test_temp_store); +static ssize_t test_authentic_show(struct device *dev,struct device_attribute *attr, char *buf){ + return sprintf(buf, "%d\n", fake_authentic); +} +static ssize_t test_authentic_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size) +{ + long val = simple_strtol(buf, NULL, 10); + + if(val == 9898) { + use_fake_authentic = false; + fake_authentic = 4000; + }else { + use_fake_authentic = true; + fake_authentic = val; + } + + return size; +} + +static DEVICE_ATTR(test_authentic, S_IRUGO | S_IWUSR, test_authentic_show, test_authentic_store); + +#endif + #define DEFAULT_BATT_TEMP 200 static int get_prop_batt_temp(struct smbchg_chip *chip) { int temp, rc; +#ifdef VENDOR_EDIT + if(use_fake_temp) + return fake_temp; +#endif rc = get_property_from_fg(chip, POWER_SUPPLY_PROP_TEMP, &temp); if (rc) { @@ -899,7 +1237,26 @@ static int get_prop_batt_voltage_max_design(struct smbchg_chip *chip) } return uv; } +#ifdef VENDOR_EDIT //if battery is not present , report POWER_SUPPLY_HEALTH_UNKNOWN +static int get_prop_batt_health(struct smbchg_chip *chip) + { + int temp; + + temp = get_prop_batt_temp(chip); + if(( AUTO_CHARGING_BATT_REMOVE_TEMP > temp)||(1 !=get_prop_batt_present(chip))) { + return POWER_SUPPLY_HEALTH_UNKNOWN; + } else if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT) { + return POWER_SUPPLY_HEALTH_OVERHEAT; + } else if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) { + return POWER_SUPPLY_HEALTH_COLD; + } + else { + return POWER_SUPPLY_HEALTH_GOOD; + } + } + +#else static int get_prop_batt_health(struct smbchg_chip *chip) { if (chip->batt_hot) @@ -913,7 +1270,7 @@ static int get_prop_batt_health(struct smbchg_chip *chip) else return POWER_SUPPLY_HEALTH_GOOD; } - +#endif static const int usb_current_table[] = { 300, 400, @@ -989,9 +1346,13 @@ static int calc_thermal_limited_current(struct smbchg_chip *chip, int current_ma) { int therm_ma; - +#ifdef VENDOR_EDIT//when thermal system temperature level is 3,do not suspend usb,just set iusb to 300MA if (chip->therm_lvl_sel > 0 + && chip->therm_lvl_sel <= (chip->thermal_levels - 1)) { +#else +if (chip->therm_lvl_sel > 0 && chip->therm_lvl_sel < (chip->thermal_levels - 1)) { +#endif /* * consider thermal limit only when it is active and not at * the highest level @@ -1012,6 +1373,7 @@ static int calc_thermal_limited_current(struct smbchg_chip *chip, #define EN_BAT_CHG_BIT BIT(1) static int smbchg_charging_en(struct smbchg_chip *chip, bool en) { + pr_err("chg_en %s:en =%d\n",__func__,en); /* The en bit is configured active low */ return smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG, EN_BAT_CHG_BIT, en ? 0 : EN_BAT_CHG_BIT); @@ -1027,7 +1389,7 @@ static int smbchg_charging_en(struct smbchg_chip *chip, bool en) static int smbchg_usb_suspend(struct smbchg_chip *chip, bool suspend) { int rc; - + pr_err("%s:suspend =%d\n",__func__,suspend); rc = smbchg_masked_write(chip, chip->usb_chgpth_base + CMD_IL, USBIN_SUSPEND_BIT, suspend ? USBIN_SUSPEND_BIT : 0); if (rc < 0) @@ -1173,6 +1535,9 @@ static int smbchg_battchg_en(struct smbchg_chip *chip, bool enable, enum battchg_enable_reason reason, bool *changed) { int rc = 0, battchg_disabled; +#ifdef VENDOR_EDIT /* yangfangbiao@oneplus.cn,20150710 Add to avoid enable charge when temp is unnormal or charge time out */ + int temp = get_prop_batt_temp(chip); +#endif pr_smb(PR_STATUS, "battchg %s, susp = %02x, en? = %d, reason = %02x\n", chip->battchg_disabled == 0 ? "enabled" : "disabled", @@ -1189,8 +1554,17 @@ static int smbchg_battchg_en(struct smbchg_chip *chip, bool enable, *changed = false; goto out; } - +#ifdef VENDOR_EDIT + /* yangfangbiao@oneplus.cn,20150710 Add to avoid enable charge when temp is unnormal or charge time out */ + pr_err("chg_en %s:enable =%d\n",__func__, enable); + rc = smbchg_charging_en(chip, + (!battchg_disabled + && ((temp > chip->mBatteryTempBoundT0) + && (temp < chip->mBatteryTempBoundT5 ) + && chip->time_out != true))); +#else rc = smbchg_charging_en(chip, !battchg_disabled); +#endif if (rc < 0) { dev_err(chip->dev, "Couldn't configure batt chg: 0x%x rc = %d\n", @@ -1272,7 +1646,7 @@ static int smbchg_dc_en(struct smbchg_chip *chip, bool enable, goto out; } - if (chip->psy_registered) + if (chip->dc_psy_type != -EINVAL) power_supply_changed(&chip->dc_psy); pr_smb(PR_STATUS, "dc charging %s, suspended = %02x\n", suspended == 0 ? "enabled" @@ -1299,7 +1673,9 @@ static int smbchg_set_high_usb_chg_current(struct smbchg_chip *chip, { int i, rc; u8 usb_cur_val; - + if (current_ma != chip->usb_max_current_ma) { //#ifdef VENDOR_EDIT if set current is the same with before value do not print + pr_err("%s:%d\n",__func__,current_ma); + } for (i = ARRAY_SIZE(usb_current_table) - 1; i >= 0; i--) { if (current_ma >= usb_current_table[i]) break; @@ -1573,7 +1949,7 @@ static int smbchg_set_fastchg_current_raw(struct smbchg_chip *chip, } pr_smb(PR_STATUS, "fastcharge current requested %d, set to %d\n", current_ma, usb_current_table[cur_val]); - + pr_err("%s:%d\n",__func__,current_ma); chip->fastchg_current_ma = usb_current_table[cur_val]; return rc; } @@ -1625,6 +2001,12 @@ static int smbchg_sw_esr_pulse_en(struct smbchg_chip *chip, bool en) #define USB_AICL_CFG 0xF3 #define AICL_EN_BIT BIT(2) +#ifdef VENDOR_EDIT //disable aicl +static void smbchg_rerun_aicl(struct smbchg_chip *chip) +{ +//do nothing ,we do not use hw aicl +} +#else static void smbchg_rerun_aicl(struct smbchg_chip *chip) { pr_smb(PR_STATUS, "Rerunning AICL...\n"); @@ -1635,6 +2017,7 @@ static void smbchg_rerun_aicl(struct smbchg_chip *chip) smbchg_sec_masked_write(chip, chip->usb_chgpth_base + USB_AICL_CFG, AICL_EN_BIT, AICL_EN_BIT); } +#endif static void taper_irq_en(struct smbchg_chip *chip, bool en) { @@ -2248,6 +2631,44 @@ static int force_dcin_icl_write(void *data, u64 val) DEFINE_SIMPLE_ATTRIBUTE(force_dcin_icl_ops, NULL, force_dcin_icl_write, "0x%02llx\n"); +#define SHIP_MODE_OFFSET 0x40 +static int ship_mode_read(void *data, u64 *val) +{ + struct smbchg_chip *chip = data; + int ret; + u8 reg; + ret = smbchg_read(chip, ®, + chip->bat_if_base + SHIP_MODE_OFFSET, 1); + + if(ret){ + pr_err("ship_mode_read failure %d\n",ret); + goto out; + } + *val = reg; + +out: + return 0; +} + +static int ship_mode_write(void *data, u64 val) +{ + struct smbchg_chip *chip = data; + int ret; + + pr_info("%s val = %llu\n", __func__, val); + if(0 == val) + ret = smbchg_sec_masked_write(chip, chip->bat_if_base + SHIP_MODE_OFFSET,BIT(0), 0); + //0 means enable ship mode and phone will cut off + + if(ret) + pr_err("enable ship mode failure\n"); + + return ret; +} + +DEFINE_SIMPLE_ATTRIBUTE(ship_mode_ops, ship_mode_read, + ship_mode_write, "0x%02llx\n"); + /* * set the dc charge path's maximum allowed current draw * that may be limited by the system's thermal level @@ -2277,14 +2698,13 @@ static int smbchg_set_thermal_limited_usb_current_max(struct smbchg_chip *chip, return rc; } - pr_smb(PR_STATUS, "AICL = %d, ICL = %d\n", + pr_err("AICL = %d, ICL = %d\n", aicl_ma, chip->usb_max_current_ma); if (chip->usb_max_current_ma > aicl_ma && smbchg_is_aicl_complete(chip)) smbchg_rerun_aicl(chip); smbchg_parallel_usb_check_ok(chip); return rc; } - static int smbchg_system_temp_level_set(struct smbchg_chip *chip, int lvl_sel) { @@ -2313,6 +2733,9 @@ static int smbchg_system_temp_level_set(struct smbchg_chip *chip, mutex_lock(&chip->current_change_lock); prev_therm_lvl = chip->therm_lvl_sel; chip->therm_lvl_sel = lvl_sel; +#ifdef VENDOR_EDIT //when thermal system temperature level is 3,do not suspend usb,just set iusb to 300MA + //do nothing +#else if (chip->therm_lvl_sel == (chip->thermal_levels - 1)) { /* * Disable charging if highest value selected by @@ -2332,7 +2755,7 @@ static int smbchg_system_temp_level_set(struct smbchg_chip *chip, } goto out; } - +#endif rc = smbchg_set_thermal_limited_usb_current_max(chip, chip->usb_target_current_ma); rc = smbchg_set_thermal_limited_dc_current_max(chip, @@ -2632,11 +3055,13 @@ static int smbchg_battery_set_property(struct power_supply *psy, case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: smbchg_battchg_en(chip, val->intval, REASON_BATTCHG_USER, &unused); + pr_err("chg_en form userspace battery charging enable: %d\n",val->intval); break; case POWER_SUPPLY_PROP_CHARGING_ENABLED: smbchg_usb_en(chip, val->intval, REASON_USER); smbchg_dc_en(chip, val->intval, REASON_USER); chip->chg_enabled = val->intval; + pr_err("chg_en form userspace charging enable: %d\n",chip->chg_enabled); schedule_work(&chip->usb_set_online_work); break; case POWER_SUPPLY_PROP_CAPACITY: @@ -2645,12 +3070,16 @@ static int smbchg_battery_set_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL: smbchg_system_temp_level_set(chip, val->intval); + pr_err("system_temp_level_set_form_userspace:%d\n",val->intval); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smbchg_set_fastchg_current_user(chip, val->intval / 1000); + rc = smbchg_set_fastchg_current(chip, val->intval / 1000); + pr_err("set_fastchg_current_form_userspace:%d\n",val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smbchg_float_voltage_set(chip, val->intval); + pr_err("float_voltage_set_form_userspace:%d\n",val->intval); break; case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE: rc = smbchg_safety_timer_enable(chip, val->intval); @@ -2686,6 +3115,54 @@ static int smbchg_battery_is_writeable(struct power_supply *psy, } return rc; } +enum chg_protect_status_type { + CHG_PROTECT_CHARGER_VOP=1, //VCHG >5.8V + CHG_PROTECT_BATTERY_STATUS_BAD,// 2 battery miss + CHG_PROTECT_CHG_OVER_TIME, // 3 charge time too long + CHG_PROTECT_BATTERY_OVER_VOLTAGE, // 4 vbat >= 4.5 + CHG_PROTECT_TEMP_REGION__HOT, // 5 t >55 + CHG_PROTECT_TEMP_REGION__COLD, // 6 -3 >= t + CHG_PROTECT_TEMP_LITTLE__COLD, //7 -3 <= t < 0 + CHG_PROTECT_TEMP_REGION__COOL, // 8 0<= t < 10 + CHG_PROTECT_TEMP_REGION__WARM //9 45 <= t < 55 +}; + +static int get_prop_authentic(struct smbchg_chip *chip) +{ + int charger_present = 0; + int temp; +#ifdef VENDOR_EDIT + if(use_fake_authentic) + return fake_authentic; +#endif + //chg_done_status = chip->chg_done; + charger_present = is_usb_present(chip) | is_dc_present(chip); + if (!charger_present) + return 0; + temp = get_prop_batt_temp(chip); + if((CHARGER_STATUS_OVER==chip->charger_status)&&(CHARGER_SOFT_OVP_VOLTAGE -100 <= get_prop_charger_voltage_now(chip)))//charger over voltage + return CHG_PROTECT_CHARGER_VOP; + else if(( AUTO_CHARGING_BATT_REMOVE_TEMP > temp)||(1 !=get_prop_batt_present(chip))) //battery remove + return CHG_PROTECT_BATTERY_STATUS_BAD; + else if(BATTERY_STATUS_BAD == chip->battery_status) //battery over voltage + return CHG_PROTECT_BATTERY_OVER_VOLTAGE; + else if(true == chip->time_out) //chg time too long + return CHG_PROTECT_CHG_OVER_TIME; + else if(CV_BATTERY_TEMP_REGION__HOT== qpnp_battery_temp_region_get(chip)) //temp hot + return CHG_PROTECT_TEMP_REGION__HOT; + else if(CV_BATTERY_TEMP_REGION__COLD==qpnp_battery_temp_region_get(chip)) //temp cold + return CHG_PROTECT_TEMP_REGION__COLD; + else if(CV_BATTERY_TEMP_REGION_LITTLE__COLD==qpnp_battery_temp_region_get(chip) && (true==chip->chg_done || chip->recharge_status==true))//-3 <= t < 0 + return CHG_PROTECT_TEMP_LITTLE__COLD; + else if(CV_BATTERY_TEMP_REGION__COOL == qpnp_battery_temp_region_get(chip)&& (true==chip->chg_done || chip->recharge_status==true)) //0<= t < 10 + return CHG_PROTECT_TEMP_REGION__COOL; + else if(CV_BATTERY_TEMP_REGION__WARM == qpnp_battery_temp_region_get(chip)&& (true==chip->chg_done || chip->recharge_status==true))// 45 <= t < 55 + return CHG_PROTECT_TEMP_REGION__WARM; + else + return 0; + + +} static int smbchg_battery_get_property(struct power_supply *psy, enum power_supply_property prop, @@ -2697,6 +3174,13 @@ static int smbchg_battery_get_property(struct power_supply *psy, switch (prop) { case POWER_SUPPLY_PROP_STATUS: val->intval = get_prop_batt_status(chip); +#ifdef VENDOR_EDIT /* if battery full but capacity not 100%,report status full*/ + if ((true==chip->chg_done || chip->recharge_status==true) + &&(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__LITTLE_COOL + || qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__NORMAL) + && (90 < get_prop_batt_capacity(chip))) + val->intval = POWER_SUPPLY_STATUS_FULL; +#endif break; case POWER_SUPPLY_PROP_PRESENT: val->intval = get_prop_batt_present(chip); @@ -2753,6 +3237,14 @@ static int smbchg_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE: val->intval = chip->safety_timer_en; break; +#ifdef VENDOR_EDIT + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = get_prop_charger_voltage_now(chip); + break; + case POWER_SUPPLY_PROP_AUTHENTIC: + val->intval = get_prop_authentic(chip); + break; +#endif case POWER_SUPPLY_PROP_FLASH_ACTIVE: val->intval = chip->otg_pulse_skip_en; break; @@ -3119,7 +3611,7 @@ static int smbchg_config_chg_battery_type(struct smbchg_chip *chip) if (chip->battery_type && !strcmp(prop.strval, chip->battery_type)) return 0; - batt_node = of_parse_phandle(node, "qcom,battery-data", 0); + batt_node = of_find_node_by_name(node, "qcom,battery-data"); if (!batt_node) { pr_smb(PR_MISC, "No batterydata available\n"); return 0; @@ -3165,9 +3657,9 @@ static void check_battery_type(struct smbchg_chip *chip) if (chip->bms_psy) { chip->bms_psy->get_property(chip->bms_psy, POWER_SUPPLY_PROP_BATTERY_TYPE, &prop); - en = (strcmp(prop.strval, UNKNOWN_BATT_TYPE) != 0 + en = ((strcmp(prop.strval, UNKNOWN_BATT_TYPE) != 0 && !chip->charge_unknown_battery) - || strcmp(prop.strval, LOADING_BATT_TYPE) != 0; + || strcmp(prop.strval, LOADING_BATT_TYPE) != 0); smbchg_battchg_en(chip, en, REASON_BATTCHG_UNKNOWN_BATTERY, &unused); } @@ -3179,7 +3671,7 @@ static void smbchg_external_power_changed(struct power_supply *psy) struct smbchg_chip, batt_psy); union power_supply_propval prop = {0,}; int rc, current_limit = 0, soc; - + static int pre_current_limit_value=0; if (chip->bms_psy_name) chip->bms_psy = power_supply_get_by_name((char *)chip->bms_psy_name); @@ -3193,13 +3685,16 @@ static void smbchg_external_power_changed(struct power_supply *psy) smbchg_soc_changed(chip); } - rc = smbchg_config_chg_battery_type(chip); - if (rc) - pr_smb(PR_MISC, - "Couldn't update charger configuration rc=%d\n", - rc); + if(0){//do not config battery + rc = smbchg_config_chg_battery_type(chip); + if (rc) + pr_smb(PR_MISC, + "Couldn't update charger configuration rc=%d\n", + rc); + } } +#if 0 rc = chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_CHARGING_ENABLED, &prop); if (rc < 0) @@ -3207,6 +3702,7 @@ static void smbchg_external_power_changed(struct power_supply *psy) rc); else smbchg_usb_en(chip, prop.intval, REASON_POWER_SUPPLY); +#endif rc = chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop); @@ -3215,8 +3711,38 @@ static void smbchg_external_power_changed(struct power_supply *psy) "could not read USB current_max property, rc=%d\n", rc); else current_limit = prop.intval / 1000; - + if(0!=current_limit) + pr_err("current_limit = %d\n", current_limit); pr_smb(PR_MISC, "current_limit = %d\n", current_limit); +#ifdef VENDOR_EDIT + if (prop.intval <= 2 && get_prop_batt_present(chip)) { + + //smbchg_charging_en(chip, 0); + pre_current_limit_value=0; //charger removed,set pre_current_limit_value 0 + chip->charger_status = CHARGER_STATUS_GOOD; + chip->aicl_current = 0; + } +if((current_limit != 0)&&(current_limit != pre_current_limit_value)) +{ + //if current_limmit is the same with before value ,do not check qpnp_check_battery_temp + chip->is_power_changed =true; + qpnp_check_battery_temp(chip); + //use oem temp control logic + mutex_lock(&chip->current_change_lock); + pr_info("changed chip->usb_target_current_ma = %d\n", + chip->usb_target_current_ma); + rc = smbchg_set_thermal_limited_usb_current_max(chip, + chip->usb_target_current_ma); + if (rc < 0) + dev_err(chip->dev, + "Couldn't set usb current rc = %d\n", rc); + pre_current_limit_value = current_limit; + mutex_unlock(&chip->current_change_lock); +} +#endif + +#ifndef VENDOR_EDIT + //use oem temp control logic mutex_lock(&chip->current_change_lock); if (current_limit != chip->usb_target_current_ma) { pr_smb(PR_STATUS, "changed current_limit = %d\n", @@ -3230,6 +3756,9 @@ static void smbchg_external_power_changed(struct power_supply *psy) } mutex_unlock(&chip->current_change_lock); +#endif + + smbchg_vfloat_adjust_check(chip); power_supply_changed(&chip->batt_psy); @@ -3291,6 +3820,10 @@ struct regulator_ops smbchg_otg_reg_ops = { #define USBIN_ADAPTER_9V 0x3 #define USBIN_ADAPTER_5V_9V_UNREG 0x5 #define HVDCP_EN_BIT BIT(3) +#ifdef VENDOR_EDIT /* modified for one of moto charger can not charge */ +#define HVDCP_ADAPTER_SEL_BIT4 BIT(4) +#define HVDCP_ADAPTER_SEL_BIT5 BIT(5) +#endif static int smbchg_external_otg_regulator_enable(struct regulator_dev *rdev) { bool changed; @@ -3906,13 +4439,18 @@ static void smbchg_hvdcp_det_work(struct work_struct *work) return; } + pr_smb(PR_STATUS, "HVDCP_STS = 0x%02x\n", reg); /* * If a valid HVDCP is detected, notify it to the usb_psy only * if USB is still present. */ if ((reg & USBIN_HVDCP_SEL_BIT) && is_usb_present(chip)) { +#ifndef VENDOR_EDIT + pr_smb(PR_MISC, "setting usb psy type = %d\n", + POWER_SUPPLY_TYPE_USB_HVDCP); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB_HVDCP); +#endif smbchg_aicl_deglitch_wa_check(chip); } } @@ -3929,6 +4467,14 @@ static irqreturn_t chg_term_handler(int irq, void *_chip) power_supply_changed(&chip->batt_psy); smbchg_charging_status_change(chip); set_property_on_fg(chip, POWER_SUPPLY_PROP_CHARGE_DONE, 1); + #ifdef VENDOR_EDIT /* charge done ,disable charge in software also*/ + if(0x80==reg)// check if charge done triggered this irq + { + chip->chg_done =true; + pr_err("chg_term_handler: chip->chg_done\n"); + smbchg_charging_en(chip, 0); + } + #endif return IRQ_HANDLED; } @@ -4045,10 +4591,12 @@ static void handle_usb_removal(struct smbchg_chip *chip) if (chip->usb_psy) { pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_UNKNOWN); +#ifndef VENDOR_EDIT power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_UNKNOWN); pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); +#endif power_supply_set_present(chip->usb_psy, chip->usb_present); pr_smb(PR_MISC, "setting usb psy allow detection 0\n"); power_supply_set_allow_detection(chip->usb_psy, 0); @@ -4110,6 +4658,16 @@ static void handle_usb_insertion(struct smbchg_chip *chip) char *usb_type_name = "null"; pr_smb(PR_STATUS, "triggered\n"); + #ifdef VENDOR_EDIT + if(chip->chg_done==true || chip->time_out == true ) + { + chip->chg_done=false;// usb plug in agin ,set chg_done false + + chip->time_out = false;// usb plug agin ,set charge time_out false + chip->recharge_status=false;// usb plug agin ,set recharge_status false + smbchg_charging_en(chip, 1);// usb plug in agin ,enable charge + } + #endif /* usb inserted */ read_usb_type(chip, &usb_type_name, &usb_supply_type); pr_smb(PR_STATUS, @@ -4120,18 +4678,23 @@ static void handle_usb_insertion(struct smbchg_chip *chip) pr_smb(PR_MISC, "setting usb psy allow detection 1\n"); power_supply_set_allow_detection(chip->usb_psy, 1); } - - if (!chip->apsd_rerun && usb_supply_type == POWER_SUPPLY_TYPE_USB) { +#ifdef VENDOR_EDIT /* modfied to slave bug:SND-5521*/ +//Do nothing +#else + if (chip->do_apsd_reruns && !chip->apsd_rerun + && usb_supply_type == POWER_SUPPLY_TYPE_USB) { chip->apsd_rerun = true; schedule_work(&chip->rerun_apsd_work); return; } - +#endif smbchg_aicl_deglitch_wa_check(chip); if (chip->usb_psy) { pr_smb(PR_MISC, "setting usb psy type = %d\n", usb_supply_type); +#ifndef VENDOR_EDIT power_supply_set_supply_type(chip->usb_psy, usb_supply_type); +#endif pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); @@ -4152,9 +4715,11 @@ static void handle_usb_insertion(struct smbchg_chip *chip) POWER_SUPPLY_HEALTH_GOOD, rc); } schedule_work(&chip->usb_set_online_work); + } + + if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP) schedule_delayed_work(&chip->hvdcp_det_work, msecs_to_jiffies(HVDCP_NOTIFY_MS)); - } if (parallel_psy) power_supply_set_present(parallel_psy, true); @@ -4178,6 +4743,9 @@ void update_usb_status(struct smbchg_chip *chip, bool usb_present, bool force) chip->usb_present = usb_present; handle_usb_insertion(chip); } else if (chip->usb_present && !usb_present) { + chip->chg_done=false;// usb unplug,set chg_done false + chip->time_out = false;// usb unplug agin ,set charge time_out false + chip->recharge_status=false;// usb unplug agin ,set charge time_out false chip->usb_present = usb_present; handle_usb_removal(chip); } @@ -4783,15 +5351,38 @@ static int smbchg_hw_init(struct smbchg_chip *chip) return rc; } +#ifdef VENDOR_EDIT // init aicl + rc = smbchg_sec_masked_write(chip, + chip->misc_base + MISC_TRIM_OPT_15_8, + AICL_INIT_FUNCTION_MASK|AICL_RERUN_MASK, AICL_RERUN_ON); + if (rc < 0) { + dev_err(chip->dev, "Couldn't init aicl rc=%d\n", + rc); + return rc; + } + //disable aicl + rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + USB_AICL_CFG, + AICL_EN_BIT, 0); + if (rc < 0) { + dev_err(chip->dev, "Couldn't disable AICL rc=%d\n", + rc); + return rc; + } + +#endif /* * Do not force using current from the register i.e. use auto * power source detect (APSD) mA ratings for the initial current values. * * If this is set, AICL will not rerun at 9V for HVDCPs */ +#ifdef VENDOR_EDIT // force using current from the register + rc = smbchg_masked_write(chip, chip->usb_chgpth_base + CMD_IL, + USE_REGISTER_FOR_CURRENT, USE_REGISTER_FOR_CURRENT); +#else rc = smbchg_masked_write(chip, chip->usb_chgpth_base + CMD_IL, USE_REGISTER_FOR_CURRENT, 0); - +#endif if (rc < 0) { dev_err(chip->dev, "Couldn't set input limit cmd rc=%d\n", rc); return rc; @@ -4843,6 +5434,14 @@ static int smbchg_hw_init(struct smbchg_chip *chip) dev_err(chip->dev, "Couldn't set usb_chgpth cfg rc=%d\n", rc); return rc; } +#ifdef VENDOR_EDIT /* modified for one of moto charger can not charge */ + rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, + HVDCP_EN_BIT | HVDCP_ADAPTER_SEL_BIT4 | HVDCP_ADAPTER_SEL_BIT5,0); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set usb_chgpth hvdcp cfg rc=%d\n", rc); + return rc; + } +#endif check_battery_type(chip); @@ -5308,6 +5907,8 @@ static int smb_parse_dt(struct smbchg_chip *chip) "qcom,low-volt-dcin"); chip->force_aicl_rerun = of_property_read_bool(node, "qcom,force-aicl-rerun"); + chip->do_apsd_reruns = of_property_read_bool(node, + "qcom,rerun-apsd"); /* parse the battery missing detection pin source */ rc = of_property_read_string(chip->spmi->dev.of_node, @@ -5672,15 +6273,1298 @@ static int create_debugfs_entries(struct smbchg_chip *chip) "Couldn't create force dcin icl check file\n"); return -EINVAL; } + + ent = debugfs_create_file("ship_mode", + S_IFREG | S_IWUSR | S_IRUGO, + chip->debug_root, chip, + &ship_mode_ops); + if (!ent) { + dev_err(chip->dev, + "Couldn't create ship_mode file\n"); + return -EINVAL; + } + return 0; } +#ifdef VENDOR_EDIT +static chg_cv_battery_temp_region_type qpnp_battery_temp_region_get(struct smbchg_chip *chip) +{ + return chip->mBatteryTempRegion; +} +static void qpnp_battery_temp_region_set(struct smbchg_chip *chip, + chg_cv_battery_temp_region_type batt_temp_region) +{ + chip->mBatteryTempRegion = batt_temp_region; +} +int get_charging_status(void) +{ + if (!g_chip) + return POWER_SUPPLY_STATUS_DISCHARGING; + return get_prop_batt_status(g_chip); +} + +int fuelgauge_battery_temp_region_get(void) +{ + if (!g_chip) + return CV_BATTERY_TEMP_REGION__NORMAL; + return qpnp_battery_temp_region_get(g_chip); +} + +static int set_prop_batt_health(struct smbchg_chip *chip, int batt_health) +{ + chip->batt_health = batt_health; + return 0; +} + +static int +get_prop_charger_voltage_now(struct smbchg_chip *chip) +{ + int rc = 0; + struct qpnp_vadc_result results; +#ifdef VENDOR_EDIT + if(use_fake_chgvol) + return fake_chgvol; +#endif + + if (chip->revision == 0 ) { + pr_err("vchg reading not supported for 1.0 rc=%d\n", rc); + return 0; + } else { + rc = qpnp_vadc_read(chip->vadc_dev, USBIN, &results); + if (rc) { + pr_err("Unable to read vchg rc=%d\n", rc); + return 0; + } + return (int)results.physical/1000; + } +} + +#if 0 +static int +get_prop_vph_voltage_now(struct smbchg_chip *chip) +{ + int rc = 0; + struct qpnp_vadc_result results; + + if (chip->revision == 0 ) { + pr_err("VSYS reading not supported for 1.0 rc=%d\n", rc); + return 0; + } else { + rc = qpnp_vadc_read(chip->vadc_dev_pm8994, VSYS, &results); + if (rc) { + pr_err("Unable to read VSYS rc=%d\n", rc); + return 0; + } + return (int)results.physical/1000; + } +} +#endif + +static inline enum power_supply_type qpnp_charger_type(struct smbchg_chip *chip) +{ + u8 reg; + int type; + int rc = -1; + + enum power_supply_type usb_supply_type; + char *usb_type_name = "null"; + rc = smbchg_read(chip, ®, chip->misc_base + IDEV_STS, 1); + if (rc < 0) { + dev_err(chip->dev, "Couldn't read status 5 rc = %d\n", rc); + return false; + } + type = get_type(reg); + + usb_supply_type = get_usb_supply_type(type); + usb_type_name = get_usb_type_name(type); + pr_smb(PR_STATUS, "inserted %s, usb psy type = %d stat_5 = 0x%02x\n", + usb_type_name, usb_supply_type, reg); + + return usb_type_enum[type]; +} +static int qpnp_set_recharge(struct smbchg_chip *chip,int resume_delta_mv) + +{ + int reg,rc; + if (resume_delta_mv < 100) + reg = CHG_INHIBIT_50MV_VAL; + else if (resume_delta_mv < 200) + reg = CHG_INHIBIT_100MV_VAL; + else if (resume_delta_mv < 300) + reg = CHG_INHIBIT_200MV_VAL; + else + reg = CHG_INHIBIT_300MV_VAL; + + rc = smbchg_sec_masked_write(chip, + chip->chgr_base + CHG_INHIB_CFG_REG, + CHG_INHIBIT_MASK, reg); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set inhibit val rc = %d\n", + rc); + return rc; + } + return 0; +} + +static int qpnp_start_charging(struct smbchg_chip *chip) +{ + int rc = -1; + unsigned int chg_current = chip->fastchg_current_ma; + union power_supply_propval ret = {0,}; + int batt_temp = get_prop_batt_temp(chip); + bool charger_present; + u8 reg; + int type; + charger_present = is_usb_present(chip) | is_dc_present(chip); + pr_err("%s:starting to enable charging\n", __func__); + + if (!charger_present){ + pr_err("%s:charger maybe removed \n", __func__); + return rc; + } + + rc = smbchg_read(chip, ®, chip->misc_base + IDEV_STS, 1); + if (rc < 0) { + dev_err(chip->dev, "Couldn't read status 5 rc = %d\n", rc); + return false; + } + type = get_type(reg); + if (batt_temp <= chip->mBatteryTempBoundT0){ // -3 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__COLD); + smbchg_charging_en(chip, 0); + + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_COLD); + return rc; + }else if (batt_temp <= chip->mBatteryTempBoundT1){ // -3 ~ 0 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION_LITTLE__COLD); + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + + smbchg_float_voltage_set(chip, chip->temp_more_cool_vbatdel); + smbchg_set_fastchg_current(chip, chip->temp_more_cool_current); + smbchg_set_usb_current_max(chip, chip->temp_more_cool_current); + smbchg_rerun_aicl(chip); + }else if (batt_temp <= chip->mBatteryTempBoundT2){ // 0 ~ 10 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__COOL); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + smbchg_rerun_aicl(chip); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + } else { + if (chip->aicl_current >= chip->temp_cool_current ) { + smbchg_set_usb_current_max(chip, chip->temp_cool_current); + smbchg_rerun_aicl(chip); + } else { + smbchg_set_usb_current_max(chip, chip->aicl_current); + smbchg_rerun_aicl(chip); + } + } + } + + smbchg_float_voltage_set(chip, chip->temp_cool_vbatdel); + if(ret.intval / 1000 == 1500){ + chg_current = chip->temp_cool_current; + } + else{ + chg_current = 500; + } + smbchg_set_fastchg_current(chip, chg_current); + } else if(batt_temp <= chip->mBatteryTempBoundT3){ //10-20 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__LITTLE_COOL); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + } else { + if (chip->aicl_current >= chip->temp_littel_cool_current) { + + smbchg_set_usb_current_max(chip, chip->temp_littel_cool_current); + } else { + smbchg_set_usb_current_max(chip, chip->aicl_current); + } + } + } + smbchg_rerun_aicl(chip); + smbchg_float_voltage_set(chip, chip->temp_littel_cool_vbatdel); + if(ret.intval / 1000 == 1500){ + smbchg_set_fastchg_current(chip, chip->temp_littel_cool_current); + }else { + smbchg_set_fastchg_current(chip, 500); + } + + } else if (batt_temp <= chip->mBatteryTempBoundT4){ // 20 ~ 45 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__NORMAL); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + //smbchg_set_high_usb_chg_current(chip, ret.intval / 1000); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + } else { + if (chip->aicl_current >= chip->temp_normal_current) { + + smbchg_set_usb_current_max(chip, chip->temp_normal_current); + } else { + smbchg_set_usb_current_max(chip, chip->aicl_current); + } + } + } + smbchg_rerun_aicl(chip); + smbchg_float_voltage_set(chip, chip->vfloat_mv); + if(ret.intval / 1000 == 1500){ + + smbchg_set_fastchg_current(chip,chip->temp_normal_current); + }else { + smbchg_set_fastchg_current(chip, 500); + } + }else if (batt_temp <= chip->mBatteryTempBoundT5){ // 45 ~ 55 + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__WARM); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + } else { + if (chip->aicl_current >= chip->temp_warm_current) { + + smbchg_set_usb_current_max(chip, chip->temp_warm_current); + } else { + smbchg_set_usb_current_max(chip, chip->aicl_current); + } + } + } + smbchg_rerun_aicl(chip); + smbchg_float_voltage_set(chip, chip->temp_warm_vbatdel); + if(ret.intval / 1000 == 1500){ + chg_current = chip->temp_warm_current; + } + else { + chg_current = 500; + } + smbchg_set_fastchg_current(chip, chg_current); + }else{ + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__HOT); + smbchg_charging_en(chip, 0); + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_OVERHEAT); + return rc; + } + rc = smbchg_charging_en(chip, 1); + //chip->chg_done = false; + //chip->time_out = false; + if (rc){ + pr_err("%s:starting charging failed\n", __func__); + } + + return rc; +} +static void qpnp_check_charge_timeout(struct smbchg_chip *chip) +{ + static int count = 0; + int rc = -1; + union power_supply_propval ret = {0,}; + if (chip->chg_done) + return; + + if((is_usb_present(chip) | is_dc_present(chip))&& (POWER_SUPPLY_STATUS_CHARGING== get_prop_batt_status(chip)))//usb plug in && charging + count++; + else + count = 0; + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + + if(((ret.intval / 1000 != 500) && count > BATT_CHG_TIMEOUT_COUNT_DCP) + ||((ret.intval / 1000 == 500) && count > BATT_CHG_TIMEOUT_COUNT_USB_PRO)){ + pr_err("%s:chg timeout stop chaging\n", __func__); + + rc = smbchg_charging_en(chip, 0); + + if (!rc) + count= 0; + chip->time_out = true; + } +} +static enum chg_battery_status_type qpnp_battery_status_get(struct smbchg_chip *chip) +{ + return chip->battery_status; +} +static void qpnp_battery_status_set(struct smbchg_chip *chip, + enum chg_battery_status_type battery_status) +{ + chip->battery_status = battery_status; +} +static int qpnp_handle_battery_uovp(struct smbchg_chip *chip) +{ + pr_info("%s\n", __func__); + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_OVERVOLTAGE); + smbchg_charging_en(chip, 0); + return 0; +} + +static int qpnp_handle_battery_restore_from_uovp(struct smbchg_chip *chip) +{ + pr_info("%s\n", __func__); + /*restore charging form battery ovp*/ + smbchg_charging_en(chip, 1); + + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + + return 0; +} + +static void qpnp_check_battery_uovp(struct smbchg_chip *chip) +{ + int battery_voltage=0; + enum chg_battery_status_type battery_status_pre; + + if (!(is_usb_present(chip) | is_dc_present(chip))) + return; + battery_status_pre = qpnp_battery_status_get(chip); + + battery_voltage = get_prop_batt_voltage_now(chip); + pr_debug("%s bat vol:%d\n", __func__, battery_voltage); + if(battery_voltage > BATTERY_SOFT_OVP_VOLTAGE) { + if (battery_status_pre == BATTERY_STATUS_GOOD) { + + pr_debug("%s BATTERY_SOFT_OVP_VOLTAGE\n", __func__); + qpnp_battery_status_set(chip, BATTERY_STATUS_BAD); + qpnp_handle_battery_uovp(chip); + } + } + else { + if (battery_status_pre == BATTERY_STATUS_BAD) { + + pr_debug("%s battery_restore_from_uovp\n", __func__); + qpnp_battery_status_set(chip, BATTERY_STATUS_GOOD); + qpnp_handle_battery_restore_from_uovp(chip); + } + } + + return; +} + +static void qpnp_check_charger_uovp(struct smbchg_chip *chip) +{ + int vchg_mv = CHARGER_VOLTAGE_NORMAL; + bool charger_present; + static int over_volt_cout=0,not_over_volt_cout=0; + static bool uovp_satus,pre_uovp_satus; + int detect_time = 5;// 5*6s=30s + charger_present = is_usb_present(chip) | is_dc_present(chip); + if (!charger_present) { + return; + } + + vchg_mv = get_prop_charger_voltage_now(chip); + + pr_debug("%s %d %d\n", __func__, vchg_mv, chip->charger_status); + + if(chip->charger_status == CHARGER_STATUS_GOOD) { + if(vchg_mv > CHARGER_SOFT_OVP_VOLTAGE || + vchg_mv <= CHARGER_SOFT_UVP_VOLTAGE) { + pr_err("charger over voltage\n"); + uovp_satus = true; + if(pre_uovp_satus == true) + over_volt_cout = over_volt_cout+1; + else + over_volt_cout =0; + + pr_err("uovp_satus=%d, pre_uovp_satus=%d,over_volt_cout=%d\n",uovp_satus,pre_uovp_satus,over_volt_cout); + if(detect_time < over_volt_cout)//vchg continuous higher than 5.8v + { + + pr_err("charger over voltage true\n"); + smbchg_charging_en(chip, 0); + + chip->charger_status = CHARGER_STATUS_OVER; + } + } + }else if(chip->charger_status == CHARGER_STATUS_OVER){ + + pr_debug("charger not over voltage\n"); + if(vchg_mv < (CHARGER_SOFT_OVP_VOLTAGE - 100) && + vchg_mv > (CHARGER_SOFT_UVP_VOLTAGE + 100)) { + + uovp_satus = false; + if(pre_uovp_satus == false) + not_over_volt_cout = not_over_volt_cout+1; + else + not_over_volt_cout =0; + + pr_err("uovp_satus=%d, pre_uovp_satus=%d,not_over_volt_cout=%d\n",uovp_satus,pre_uovp_satus,not_over_volt_cout); + if(detect_time < not_over_volt_cout)//vchg continuous lower than 5.7v + { + + pr_err("charger not over voltage true \n"); + smbchg_charging_en(chip, 1); + qpnp_start_charging(chip); + chip->charger_status = CHARGER_STATUS_GOOD; + } + } + } + pre_uovp_satus =uovp_satus; + return ; +} + + +/*Tbatt <-3C*/ +static int handle_batt_temp_cold(struct smbchg_chip *chip) +{ + if ((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION__COLD)||( chip->is_power_changed== true)) + { + pr_debug("%s\n", __func__); + chip->is_power_changed=false; + + smbchg_charging_en(chip, 0); + + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__COLD); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0 + AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COLD_TO_COOL; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1 ; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2 ; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_COLD); + } + return 0; +} + +/* -3 C <=Tbatt <= 0C*/ +static int handle_batt_temp_little_cold(struct smbchg_chip *chip) +{ + union power_supply_propval ret = {0,}; + if(chip->charger_status == CHARGER_STATUS_OVER) + return 0; + + if ((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION_LITTLE__COLD)||( chip->is_power_changed== true)||(chip->recharge_pending==true)) + { + pr_debug("%s\n", __func__); + chip->recharge_pending=false; + chip->is_power_changed=false; + + if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT || + qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) + smbchg_charging_en(chip, 1); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + + smbchg_set_usb_current_max(chip, ret.intval / 1000); + smbchg_rerun_aicl(chip); + chip->usb_target_current_ma=500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip, chip->lcd_on_iusb); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_rerun_aicl(chip); + } + } else { + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip,chip->lcd_on_iusb); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + else + { + smbchg_set_usb_current_max(chip, chip->aicl_current); + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + smbchg_rerun_aicl(chip); + } + } + + smbchg_float_voltage_set(chip, chip->temp_more_cool_vbatdel); + //qpnp_set_recharge(chip,100);//chip->temp_more_cool_vbatdel -3700); + smbchg_set_fastchg_current(chip, chip->temp_more_cool_current); + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION_LITTLE__COLD); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1 + AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COOL_TO_NORMAL; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + + + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + + } + return 0; +} + +/* 0 C fastchg_current_ma; + union power_supply_propval ret = {0,}; + + if(chip->charger_status == CHARGER_STATUS_OVER) + return 0; + + if ((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION__COOL)||( chip->is_power_changed== true)||(chip->recharge_pending==true)) + { + pr_debug("%s\n", __func__); + + chip->recharge_pending=false; + chip->is_power_changed = false; + if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT || + qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) + smbchg_charging_en(chip, 1); + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + chip->usb_target_current_ma=500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_set_usb_current_max(chip, ret.intval / 1000); + smbchg_rerun_aicl(chip); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + smbchg_rerun_aicl(chip); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + } else { + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip,calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + else + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + smbchg_rerun_aicl(chip); + } + } + + if(ret.intval / 1000 == 1500){ + + smbchg_float_voltage_set(chip, chip->temp_cool_vbatdel); + smbchg_set_fastchg_current(chip, chip->temp_cool_current); + + /* Update battery temp region */ + }else{ + + smbchg_float_voltage_set(chip, chip->temp_cool_vbatdel); + smbchg_set_fastchg_current(chip, 500); + //smbchg_set_high_usb_chg_current(chip, 500); + } + + qpnp_set_recharge(chip,chip->resume_delta_mv); + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__COOL); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1 ; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2 + AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COOL_TO_NORMAL; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + + } + return 0; +} +/* 10 C fastchg_current_ma; + union power_supply_propval ret = {0,}; + + if(chip->charger_status == CHARGER_STATUS_OVER) + return 0; + + if ((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION__LITTLE_COOL)||( chip->is_power_changed== true)||(chip->recharge_pending==true)) + { + pr_debug("%s\n", __func__); + + chip->recharge_pending=false; + chip->is_power_changed = false; + if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT || + qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) + smbchg_charging_en(chip, 1); + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + chip->usb_target_current_ma=500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_rerun_aicl(chip); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + smbchg_rerun_aicl(chip); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + } else { + + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip,calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + else + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + smbchg_rerun_aicl(chip); + } + } + + if(ret.intval / 1000 == 1500){ + + smbchg_float_voltage_set(chip, chip->temp_littel_cool_vbatdel); + smbchg_set_fastchg_current(chip, chip->temp_littel_cool_current); + }else{ + smbchg_float_voltage_set(chip, chip->temp_littel_cool_vbatdel); + smbchg_set_fastchg_current(chip, 500); + //smbchg_set_high_usb_chg_current(chip, 500); + } + + qpnp_set_recharge(chip,chip->resume_delta_mv); + /* Update battery temp region */ + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__LITTLE_COOL); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2 ; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3 + AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_COOL_TO_NORMAL; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + + } + return 0; +} +/* 15 C charger_status == CHARGER_STATUS_OVER) + return 0; + + if ((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION__NORMAL)||( chip->is_power_changed== true)||(chip->recharge_pending==true)) + { + pr_debug("%s\n", __func__); + + chip->recharge_pending=false; + chip->is_power_changed = false; + if (qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT || + qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) + smbchg_charging_en(chip, 1); + + /* Update battery temp region */ + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__NORMAL); + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + chip->usb_target_current_ma=500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_rerun_aicl(chip); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + smbchg_rerun_aicl(chip); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + } else { + + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip,calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + else + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + smbchg_rerun_aicl(chip); + } + } + + + if(ret.intval / 1000 == 1500) + { + if (chip->aicl_current != 0 && chip->aicl_current <= 1500) + smbchg_set_fastchg_current(chip, chip->aicl_current); + else + smbchg_set_fastchg_current(chip, chip->temp_normal_current); + smbchg_float_voltage_set(chip, chip->temp_normal_vbatdel); + + }else{ + smbchg_set_fastchg_current(chip, 500); + smbchg_float_voltage_set(chip, chip->temp_normal_vbatdel); + + } + qpnp_set_recharge(chip,chip->resume_delta_mv); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + } + return 0; +} + +/* 45C <=Tbatt <=55C*/ +static int handle_batt_temp_warm(struct smbchg_chip *chip) +{ + //unsigned int chg_current = chip->fastchg_current_ma; + union power_supply_propval ret = {0,}; + + if(chip->charger_status == CHARGER_STATUS_OVER) + return 0; + + if((qpnp_battery_temp_region_get(chip) != CV_BATTERY_TEMP_REGION__WARM)||( chip->is_power_changed== true)||(chip->recharge_pending==true)) + { + chip->is_power_changed = false; + chip->recharge_pending=false; + pr_debug("%s\n", __func__); + if(qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__HOT || + qpnp_battery_temp_region_get(chip) == CV_BATTERY_TEMP_REGION__COLD) + smbchg_charging_en(chip, 1); + + chip->usb_psy->get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &ret); + if(ret.intval / 1000 == 500) { + smbchg_set_usb_current_max(chip, ret.intval / 1000); + chip->usb_target_current_ma=500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_rerun_aicl(chip); + } else { + if(chip->aicl_current == 0) { + soft_aicl(chip); + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + smbchg_rerun_aicl(chip); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + } else { + if((chip->oem_lcd_is_on==true)&&(chip->aicl_current > chip->lcd_on_iusb)) + { + smbchg_set_usb_current_max(chip,calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + chip->usb_target_current_ma=chip->lcd_on_iusb;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + else + { + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + chip->usb_target_current_ma=chip->aicl_current;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + } + smbchg_rerun_aicl(chip); + } + } + + + if(ret.intval / 1000 == 1500){ + smbchg_float_voltage_set(chip, chip->temp_warm_vbatdel); + + smbchg_set_fastchg_current(chip, chip->temp_warm_current); + + }else{ + smbchg_float_voltage_set(chip, chip->temp_warm_vbatdel); + smbchg_set_fastchg_current(chip, 500); + } + qpnp_set_recharge(chip,chip->resume_delta_mv); + /* Update battery temp region */ + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__WARM); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4 - AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_WARM_TO_NORMAL; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_GOOD); + } + return 0; +} + +/* 55C is_power_changed== true)) + { + chip->is_power_changed = false; + pr_debug("%s\n", __func__); + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, 1500)); + chip->usb_target_current_ma=1500;/* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_rerun_aicl(chip); + smbchg_charging_en(chip, 0); + + /* Update battery temp region */ + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__HOT); + + /* Update the temperature boundaries */ + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5 - AUTO_CHARGING_BATTERY_TEMP_HYST_FROM_HOT_TO_WARM; + set_prop_batt_health(chip, POWER_SUPPLY_HEALTH_OVERHEAT); + } + return 0; +} + +static int qpnp_check_battery_temp(struct smbchg_chip *chip) +{ + int rc = -1; + int temperature = 0; + bool charger_present; + charger_present = is_usb_present(chip) | is_dc_present(chip); + pr_debug("%s charger_present:%d\n", __func__, charger_present); + + if (!charger_present) + return rc; + temperature = get_prop_batt_temp(chip); + pr_debug("%s temp:%d\n", __func__, temperature); + + if(temperature < chip->mBatteryTempBoundT0) /* battery is cold */ + { + rc = handle_batt_temp_cold(chip); + } + else if( (temperature >= chip->mBatteryTempBoundT0) && + (temperature <= chip->mBatteryTempBoundT1) ) /* battery is more cool */ + { + rc = handle_batt_temp_little_cold(chip); + } + else if( (temperature > chip->mBatteryTempBoundT1) && + (temperature <= chip->mBatteryTempBoundT2) ) /* battery is cool */ + { + rc = handle_batt_temp_cool(chip); + } + else if( (temperature > chip->mBatteryTempBoundT2) && + (temperature <= chip->mBatteryTempBoundT3) ) /* battery is little cool */ + { + rc = handle_batt_temp_little_cool(chip); + } + else if( (temperature > chip->mBatteryTempBoundT3) && + (temperature < chip->mBatteryTempBoundT4) ) /* battery is normal */ + { + rc = handle_batt_temp_normal(chip); + } + else if( (temperature >= chip->mBatteryTempBoundT4) && + (temperature < chip->mBatteryTempBoundT5) ) /* battery is warm */ + { + rc = handle_batt_temp_warm(chip); + } + else if(temperature >= chip->mBatteryTempBoundT5)/* battery is hot */ + { + rc = handle_batt_temp_hot(chip); + } + + return rc; +} +static void qpnp_charge_info_init(struct smbchg_chip *chip) +{ + + + qpnp_battery_temp_region_set(chip, CV_BATTERY_TEMP_REGION__NORMAL); + + chip->mBatteryTempBoundT0 = AUTO_CHARGING_BATT_TEMP_T0; + chip->mBatteryTempBoundT1 = AUTO_CHARGING_BATT_TEMP_T1; + chip->mBatteryTempBoundT2 = AUTO_CHARGING_BATT_TEMP_T2; + chip->mBatteryTempBoundT3 = AUTO_CHARGING_BATT_TEMP_T3; + chip->mBatteryTempBoundT4 = AUTO_CHARGING_BATT_TEMP_T4; + chip->mBatteryTempBoundT5 = AUTO_CHARGING_BATT_TEMP_T5; + chip->charger_status = CHARGER_STATUS_GOOD; + chip->is_power_changed =false; + chip->chg_done=false; + chip->recharge_pending=false; + chip->recharge_status=false; + + chip->temp_more_cool_rechgvbat=3700; // -10 <= T < 0 + chip->temp_more_cool_vbatdel=4000; // -10 <= T < 0 + chip->temp_cool_vbatdel=4200; //0 <= T < 10 + chip->temp_cool_recharge_vbatdel=4100; + chip->temp_littel_cool_vbatdel=4320; // 10 <= T < 20 + chip->temp_littel_cool_recharge_vbatdel=4220; + chip->temp_normal_vbatdel=4320; //20 <= T < = 45 + chip->temp_normal_recharge_vbatdel=4220; + chip->temp_warm_vbatdel = 4100; //45 <= T < 55 + chip->temp_warm_recharge_vbatdel=4000; + + chip->temp_more_cool_current = 300; // Vterm=4.0V I=300 , -10 <= T < 0 + chip->temp_cool_current = 900; // Vterm=4.2V I=0.3C , 0 <= T < 10 + chip->temp_littel_cool_current = 1300; // Vterm=4.32V I=0.5C , 10 <= T < 20 + chip->temp_normal_current = 1910; // Vterm=4.3V I=1.5C/2C , 20 <= T < = 45 + chip->temp_warm_current =900; // Vterm=4.0V I=0.5c , 45 <= T < 55 + chip->lcd_on_iusb = 2100; + + chip->oem_lcd_is_on =false; + chip->time_out = false; + chip->battery_status=BATTERY_STATUS_GOOD; +} + +#if defined(CONFIG_FB) +/* yangfangbiao@oneplus.cn,20150519 Add for reset charge current when screen is off */ +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct smbchg_chip *chip = + container_of(self, struct smbchg_chip, fb_notif); + //union power_supply_propval ret = {0,}; + pr_debug(" %s enter\n",__func__); + + if (evdata && evdata->data && chip) { + if (event == FB_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) { + chip->oem_lcd_is_on =true ; + /* yangfangbiao@oneplus.cn,20150519 Add for auto adapt current by software. */ + pr_debug(" %s FB_BLANK_UNBLANK\n",__func__); + if(chip->aicl_current != 0) { + if (chip->aicl_current >= chip->lcd_on_iusb) { + /* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->lcd_on_iusb)); + smbchg_rerun_aicl(chip); + + } else { + /* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + smbchg_rerun_aicl(chip); + } + } + } + + else if (*blank == FB_BLANK_POWERDOWN) { + /* yangfangbiao@oneplus.cn,20150519 Add for auto adapt current by software. */ + chip->oem_lcd_is_on =false; + pr_debug(" %s FB_BLANK_POWERDOWN\n",__func__); + if(chip->aicl_current != 0) { + /* yangfangbiao@oneplus.cn,20150710 Add for usb thermal current limit */ + smbchg_set_usb_current_max(chip, calc_thermal_limited_current(chip, chip->aicl_current)); + smbchg_rerun_aicl(chip); + } + + } + } + + } + + return 0; +} +#endif /*CONFIG_FB*/ + +static void update_heartbeat(struct work_struct *work) +{ + + struct delayed_work *dwork = to_delayed_work(work); + struct smbchg_chip *chip = container_of(dwork, + struct smbchg_chip, update_heartbeat_work); + static int batt_temp=0; + + qpnp_check_charger_uovp(chip); + qpnp_check_battery_uovp(chip); + + qpnp_check_charge_timeout(chip); + + batt_temp = get_prop_batt_temp(chip); + if(((AUTO_CHARGING_BATT_TEMP_T0 <= batt_temp) &&(batt_temp < AUTO_CHARGING_BATT_TEMP_T1))&&(chip->charger_status == CHARGER_STATUS_GOOD)) + { + if((chip->temp_more_cool_rechgvbat >= get_prop_batt_voltage_now(chip)/1000)&&(chip->chg_done==true)) + { + chip->chg_done=false; + chip->recharge_pending=true; + chip->recharge_status=true; + + smbchg_charging_en(chip, 1); + pr_debug("ctemp_more_cool hip->recharge_pending\n"); + } + + + } + else if(((AUTO_CHARGING_BATT_TEMP_T1 <= batt_temp) &&(batt_temp < AUTO_CHARGING_BATT_TEMP_T2))&&(chip->charger_status == CHARGER_STATUS_GOOD)) + { + if((chip->temp_cool_recharge_vbatdel >= get_prop_batt_voltage_now(chip)/1000)&&(chip->chg_done==true)) + { + chip->chg_done=false; + chip->recharge_pending=true; + chip->recharge_status=true; + + smbchg_charging_en(chip, 1); + pr_debug("temp_cool chip->recharge_pending\n"); + } + + + } + else if(((AUTO_CHARGING_BATT_TEMP_T2 <= batt_temp) &&(batt_temp < AUTO_CHARGING_BATT_TEMP_T3))&&(chip->charger_status == CHARGER_STATUS_GOOD)) + { + /*temp_littel_cool vchg can reach 4.32v ,chg_done will be set in chg_term_handler( ) */ + if((chip->temp_littel_cool_recharge_vbatdel >= get_prop_batt_voltage_now(chip)/1000)&&(chip->chg_done==true)) + { + chip->chg_done=false; + chip->recharge_pending=true; + chip->recharge_status=true; + + smbchg_charging_en(chip, 1); + pr_debug("temp_littel_cool chip->recharge_pending\n"); + } + + + } + else if(((AUTO_CHARGING_BATT_TEMP_T3 <= batt_temp) &&(batt_temp < AUTO_CHARGING_BATT_TEMP_T4))&&(chip->charger_status == CHARGER_STATUS_GOOD)) + { + /*temp_normal vchg can reach 4.32v ,chg_done will be set in chg_term_handler( ) */ + if((chip->temp_normal_recharge_vbatdel >= get_prop_batt_voltage_now(chip)/1000)&&(chip->chg_done==true)) + { + chip->chg_done=false; + chip->recharge_pending=true; + chip->recharge_status=true; + + smbchg_charging_en(chip, 1); + pr_debug("temp_normal chip->recharge_pending\n"); + } + + + } + else if(((AUTO_CHARGING_BATT_TEMP_T4 <= batt_temp) &&(batt_temp < AUTO_CHARGING_BATT_TEMP_T5))&&(chip->charger_status == CHARGER_STATUS_GOOD)) + { + if((chip->temp_warm_recharge_vbatdel >= get_prop_batt_voltage_now(chip)/1000)&&(chip->chg_done==true)) + { + chip->chg_done=false; + chip->recharge_pending=true; + chip->recharge_status=true; + + smbchg_charging_en(chip, 1); + pr_debug("temp_warm chip->recharge_pending\n"); + } + + + } + if((chip->charger_status == CHARGER_STATUS_GOOD)&&(chip->battery_status == BATTERY_STATUS_GOOD)&&(chip->time_out != true)){ + qpnp_check_battery_temp(chip); + } +// qpnp_check_recharging(chip); + + dump_regs(chip); + + power_supply_changed(&chip->batt_psy); + + /*update time 6s*/ + schedule_delayed_work(&chip->update_heartbeat_work, + round_jiffies_relative(msecs_to_jiffies + (BATT_HEARTBEAT_INTERVAL))); + //qpnp_dump_info(chip); + +} +/* yangfangbiao@oneplus.cn, 2015/05/11 Modify for backup soc Begin */ +#define SOC_INVALID 0x7E +#define SOC_DATA_REG_0 0x88D +static int load_data(struct smbchg_chip *chip) +{ + u8 stored_soc = 0; + int rc = 0; + int shutdown_soc = 0; + + if (chip == NULL) { + printk(KERN_ERR "%s: chip is NULL !\n", __func__); + return SOC_INVALID; + } + + + rc = smbchg_read(chip, &stored_soc, SOC_DATA_REG_0, 1); + if (0 != rc) { + printk(KERN_ERR "%s: failed to read addr[0x%x], rc=%d\n", __func__, SOC_DATA_REG_0, rc); + return SOC_INVALID; + } + + if ((stored_soc%2 )==1)//the fist time connect battery ,the reg 0x88d is 0x0,we do not need load this data. + shutdown_soc = (stored_soc >> 1 );//get data from bit1~bit7 + else + shutdown_soc = SOC_INVALID; + printk(KERN_ERR "%s: stored_soc[0x%x], shutdown_soc[%d]\n", __func__, stored_soc, shutdown_soc); + return shutdown_soc; +} + +int load_soc(void) +{ + int soc = 0; + + soc = load_data(g_chip); + if (soc == SOC_INVALID || soc < 0 || soc > 100) + return -1; + return soc; +} + +static void backup_soc(struct smbchg_chip *chip, int soc) +{ + int rc = 0; + u8 invalid_soc = SOC_INVALID; + u8 soc_temp = (soc << 1) +1;//store data in bit1~bit7 + if (chip == NULL || soc < 0 || soc > 100) { + printk(KERN_ERR "%s: chip or soc invalid, store an invalid soc\n", __func__); + if(chip != NULL){ + rc = smbchg_write(chip, &invalid_soc, SOC_DATA_REG_0, 1); + } + return; + } + + printk(KERN_ERR "%s: backup_soc[%d]\n", __func__, soc); + rc = smbchg_write(chip, &soc_temp, SOC_DATA_REG_0,1); + if (rc) { + printk(KERN_ERR "%s: failed to write addr[0x%x], rc=%d\n", __func__, SOC_DATA_REG_0, rc); + } +} +void backup_soc_ex(int soc) +{ + backup_soc(g_chip, soc); +} +/* yangfangbiao@oneplus.cn, 2015/05/11 Modify for backup soc End */ +bool get_oem_charge_done_status(void)/* yangfangbiao@oneplus.cn, 2015/05/15,add for notifiy chg_done status */ +{ + return g_chip->chg_done; +} +#endif /*VENDOR_EDIT*/ + +#ifdef VENDOR_EDIT +#ifdef CONFIG_SET_PMI8994_RESET_TYPE +/* +Add by yangrujin@bsp 2015/7/21, avoid handset goto unkown mode without usb port and not reboot in aging test +*/ +#define PMI_PON_PS_HOLD_RESET_CTL (0x85A) +static u8 default_pmi_reset_type=0x1; +static int pmi_reset_type; + +enum PMI_RESET_TYPE{ + WARM_RESET=0x1, + SHUTDOWN=0x4, + HARD_RESET=0x7, + DEFAULT, +}; + +static int get_pmi_reset_type(char *buffer, const struct kernel_param *kp) +{ + u8 reg; + int ret = 0; + + if(g_chip==NULL || g_chip->spmi==NULL || g_chip->spmi->sid!=2){ + pr_info("g_chip not right. sid :%d\n", g_chip->spmi?g_chip->spmi->sid:-1); + return -1; + } + + ret = smbchg_read(g_chip, ®, PMI_PON_PS_HOLD_RESET_CTL, 1); + if(ret){ + pr_err("Failed to read addr[0x%x], ret=%d,reg=%02X\n", + PMI_PON_PS_HOLD_RESET_CTL, ret, reg); + reg = pmi_reset_type; + } + ret = snprintf(buffer, 1, "%d", reg); + if(reg==WARM_RESET){ + pr_info("The pmi_reset_type is WARM_RESET\n"); + }else if(reg==SHUTDOWN){ + pr_info("The pmi_reset_type is SHUTDOWN\n"); + }else if(reg==HARD_RESET){ + pr_info("The pmi_reset_type is HARD_RESET\n"); + }else{ + pr_info("We not set pmi_reset_type, it is default\n"); + } + + return ret; +} + +static int set_pmi_reset_type(const char *val, struct kernel_param *kp) +{ + int ret = 0; + u8 rst_type = 0; + static bool read_pmi_reset_type = false; + + if(g_chip==NULL || g_chip->spmi==NULL || g_chip->spmi->sid!=2){ + if(g_chip){ + pr_info("%s : g_chip not right. sid :%d\n", __func__, g_chip->spmi?g_chip->spmi->sid:-1); + }else{ + pr_info("%s : g_chip is NULL\n", __func__); + } + return -1; + } + + if(!read_pmi_reset_type){ + ret = smbchg_read(g_chip, &default_pmi_reset_type, PMI_PON_PS_HOLD_RESET_CTL, 1); + if(ret){ + pr_err("%s : Failed to read addr[0x%x], ret=%d,reg=%02X\n", + __func__, PMI_PON_PS_HOLD_RESET_CTL, ret, default_pmi_reset_type); + read_pmi_reset_type = false; + }else{ + pr_info("%s : default_pmi_reset_type=%d\n", __func__, default_pmi_reset_type); + read_pmi_reset_type = true; + } + } + + ret = sscanf(val, "%d", &pmi_reset_type); + + if(pmi_reset_type!=WARM_RESET && pmi_reset_type!=SHUTDOWN && pmi_reset_type!=HARD_RESET){ + rst_type = read_pmi_reset_type?default_pmi_reset_type:WARM_RESET; + }else{ + rst_type = pmi_reset_type; + } + pr_info("%s : Pass pmi_reset_type %d from userspace, set pmi reset type to %d\n", + __func__, pmi_reset_type, rst_type); + + ret = smbchg_write(g_chip, &rst_type, PMI_PON_PS_HOLD_RESET_CTL, 1); + if(ret){ + pr_err("%s : Failed to write addr[0x%x], ret=%d,reg=%02X\n", + __func__, PMI_PON_PS_HOLD_RESET_CTL, ret, rst_type); + } + + return ret; +} + +module_param_call(pmi_reset_type, set_pmi_reset_type, + get_pmi_reset_type, &pmi_reset_type, 0664); +#endif +#endif + static int smbchg_probe(struct spmi_device *spmi) { int rc; struct smbchg_chip *chip; struct power_supply *usb_psy; - struct qpnp_vadc_chip *vadc_dev; + struct qpnp_vadc_chip *vadc_dev, *vadc_dev_pm8994; usb_psy = power_supply_get_by_name("usb"); if (!usb_psy) { @@ -5693,12 +7577,24 @@ static int smbchg_probe(struct spmi_device *spmi) if (IS_ERR(vadc_dev)) { rc = PTR_ERR(vadc_dev); if (rc != -EPROBE_DEFER) - dev_err(&spmi->dev, "Couldn't get vadc rc=%d\n", + dev_err(&spmi->dev, "Couldn't get vadc_dev rc=%d\n", rc); return rc; } } + if (of_find_property(spmi->dev.of_node, "qcom,vph-vadc", NULL)) { + vadc_dev_pm8994 = qpnp_get_vadc(&spmi->dev, "vph"); + if (IS_ERR(vadc_dev_pm8994)) { + rc = PTR_ERR(vadc_dev_pm8994); + if (rc != -EPROBE_DEFER) + dev_err(&spmi->dev, "Couldn't get vadc_dev_pm8994 rc=%d\n", + rc); + return rc; + } + } + + chip = devm_kzalloc(&spmi->dev, sizeof(*chip), GFP_KERNEL); if (!chip) { dev_err(&spmi->dev, "Unable to allocate memory\n"); @@ -5712,6 +7608,7 @@ static int smbchg_probe(struct spmi_device *spmi) INIT_DELAYED_WORK(&chip->hvdcp_det_work, smbchg_hvdcp_det_work); init_completion(&chip->apsd_src_det_lowered); chip->vadc_dev = vadc_dev; + chip->vadc_dev_pm8994 = vadc_dev_pm8994; chip->spmi = spmi; chip->dev = &spmi->dev; chip->usb_psy = usb_psy; @@ -5810,6 +7707,44 @@ static int smbchg_probe(struct spmi_device *spmi) power_supply_set_present(chip->usb_psy, chip->usb_present); dump_regs(chip); + +#ifdef VENDOR_EDIT + g_chip = chip; + + qpnp_charge_info_init(chip); + + INIT_DELAYED_WORK(&chip->update_heartbeat_work, + update_heartbeat); + schedule_delayed_work(&chip->update_heartbeat_work, + round_jiffies_relative(msecs_to_jiffies + (BATT_HEARTBEAT_INTERVAL))); + + rc = device_create_file(chip->dev, &dev_attr_test_chg_vol); + if (rc < 0) { + pr_err("%s: creat test_chg_vol file failed ret = %d\n", + __func__, rc); + } + rc = device_create_file(chip->dev, &dev_attr_test_temp); + if (rc < 0) { + pr_err("%s: creat test temp file failed ret = %d\n", + __func__, rc); + } + rc = device_create_file(chip->dev, &dev_attr_test_authentic); + if (rc < 0) { + pr_err("%s: creat test vbat file failed ret = %d\n", + __func__, rc); + } +#endif +#if defined(CONFIG_FB) + /* yangfangbiao@oneplus.cn,20150519 Add for reset charge current when screen is off */ + chip->fb_notif.notifier_call = fb_notifier_callback; + + rc = fb_register_client(&chip->fb_notif); + + if (rc) + pr_err("Unable to register fb_notifier: %d\n", rc); +#endif /*CONFIG_FB*/ + create_debugfs_entries(chip); dev_info(chip->dev, "SMBCHG successfully probed batt=%d dc = %d usb = %d\n", get_prop_batt_present(chip), @@ -5832,6 +7767,17 @@ static int smbchg_remove(struct spmi_device *spmi) debugfs_remove_recursive(chip->debug_root); +#ifdef VENDOR_EDIT + device_remove_file(chip->dev, &dev_attr_test_chg_vol); + device_remove_file(chip->dev, &dev_attr_test_temp); + device_remove_file(chip->dev, &dev_attr_test_authentic); +#endif +#if defined(CONFIG_FB) + /* yangfangbiao@oneplus.cn,20150519 Add for reset charge current when screen is off */ + if (fb_unregister_client(&chip->fb_notif)) + pr_err("Error occurred while unregistering fb_notifier.\n"); +#endif /*CONFIG_FB*/ + if (chip->dc_psy_type != -EINVAL) power_supply_unregister(&chip->dc_psy); diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c old mode 100644 new mode 100755 index b0aa6b0bebfca..b2505eb863bcc --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -77,6 +77,14 @@ static struct notifier_block panic_blk = { .notifier_call = panic_prep_restart, }; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/07/03, add for force dump function +int oem_get_download_mode(void) +{ + return download_mode; +} +#endif + int scm_set_dload_mode(int arg1, int arg2) { struct scm_desc desc = { @@ -99,15 +107,29 @@ int scm_set_dload_mode(int arg1, int arg2) return scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_BOOT, SCM_DLOAD_CMD), &desc); } - +#ifdef VENDOR_EDIT/*Liwei@BSP added the varient for getting console address start and size*/ +typedef unsigned int uint32; +extern phys_addr_t ram_console_address_start; +extern ssize_t ram_console_address_size; +#endif /*VENDOR_EDIT*/ static void set_dload_mode(int on) { int ret; - +#ifdef VENDOR_EDIT/*Add print log*/ + pr_info("Set dload mode:%s\n",on?"true":"false"); +#endif/*ifdef VENDOR_EDIT*/ if (dload_mode_addr) { __raw_writel(on ? 0xE47B337D : 0, dload_mode_addr); __raw_writel(on ? 0xCE14091A : 0, dload_mode_addr + sizeof(unsigned int)); + __raw_writel(on ? (uint32)ram_console_address_start : 0, dload_mode_addr + 10*sizeof(uint32)); + __raw_writel(on ? (uint32)ram_console_address_size : 0, dload_mode_addr + 11*sizeof(uint32)); + // #ifdef VENDOR_EDIT + // neiltsai, 20150812, add for ram dump kernel version + __raw_writel(on ? (uint32)(virt_to_phys(linux_banner)): 0, dload_mode_addr + 12*sizeof(uint32)); + __raw_writel(on ? (uint32)(strlen(linux_banner)): 0, dload_mode_addr + 13*sizeof(uint32)); + // neil end + // #endif mb(); } @@ -212,6 +234,15 @@ static void halt_spmi_pmic_arbiter(void) } } +#ifdef VENDOR_EDIT +#define FACTORY_MODE 0x77665504 +#define WLAN_MODE 0x77665505 +#define RF_MODE 0x77665506 +#define MOS_MODE 0x77665507 +#define RECOVERY_MODE 0x77665502 +#define FASTBOOT_MODE 0x77665500 +#endif + static void msm_restart_prepare(const char *cmd) { bool need_warm_reset = false; @@ -249,6 +280,40 @@ static void msm_restart_prepare(const char *cmd) qpnp_pon_system_pwr_off(PON_POWER_OFF_HARD_RESET); } +#ifdef VENDOR_EDIT + if (cmd != NULL) { + if (!strncmp(cmd, "bootloader", 10)) { + __raw_writel(FASTBOOT_MODE, restart_reason); + } else if (!strncmp(cmd, "recovery", 8)) { + __raw_writel(RECOVERY_MODE, restart_reason); + } else if (!strncmp(cmd, "rf", 2)) { + __raw_writel(RF_MODE, restart_reason); + } else if (!strncmp(cmd, "wlan", 4)) { + __raw_writel(WLAN_MODE, restart_reason); + } else if (!strncmp(cmd, "mos", 3)) { + __raw_writel(MOS_MODE, restart_reason); + } else if (!strncmp(cmd, "ftm", 3)) { + __raw_writel(FACTORY_MODE, restart_reason); + } else if (!strncmp(cmd, "oem-", 4)) { + unsigned long code; + code = simple_strtoul(cmd + 4, NULL, 16) & 0xff; + __raw_writel(0x6f656d00 | code, restart_reason); + } else if (!strncmp(cmd, "kernel", 6)) { + __raw_writel(0x7766550a, restart_reason); + } else if (!strncmp(cmd, "modem", 5)) { + __raw_writel(0x7766550b, restart_reason); + } else if (!strncmp(cmd, "android", 7)) { + __raw_writel(0x7766550c, restart_reason); + } else if (!strncmp(cmd, "edl", 3)) { + enable_emergency_dload_mode(); + } else { + __raw_writel(0x77665501, restart_reason); + } + }else { + __raw_writel(0x77665501, restart_reason); + } + +#else if (cmd != NULL) { if (!strncmp(cmd, "bootloader", 10)) { qpnp_pon_set_restart_reason( @@ -275,7 +340,7 @@ static void msm_restart_prepare(const char *cmd) __raw_writel(0x77665501, restart_reason); } } - +#endif flush_cache_all(); /*outer_flush_all is not supported by 64bit kernel*/ diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c old mode 100644 new mode 100755 index 040c5dcdbff4f..03420c614aa0f --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4221,6 +4221,34 @@ int regulator_suspend_finish(void) } EXPORT_SYMBOL_GPL(regulator_suspend_finish); +#ifdef VENDOR_EDIT +static uint need_dump_regulator; +module_param(need_dump_regulator, uint, 0644); +MODULE_PARM_DESC(need_dump_regulator, "need_dump_regulator"); + +void regulator_suspend_dump(void) +{ + struct regulator_dev *rdev; + struct regulator *regulator; + + if(!need_dump_regulator) + return; + //mutex_lock(®ulator_list_mutex); + list_for_each_entry(rdev, ®ulator_list, list) { + //mutex_lock(&rdev->mutex); + pr_info("Supply_name: %s ===>%s\n", + rdev_get_name(rdev), _regulator_is_enabled(rdev)?"enable":"disable"); + list_for_each_entry(regulator, &rdev->consumer_list, list){ + pr_info("supply to %s [%s]\n",regulator->supply_name, regulator->enabled?"Y":"N"); + } + pr_info("======================="); + //mutex_unlock(&rdev->mutex); + } + //mutex_unlock(®ulator_list_mutex); +} +EXPORT_SYMBOL_GPL(regulator_suspend_dump); +#endif /* VENDOR_EDIT */ + /** * regulator_has_full_constraints - the system has fully specified constraints * diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c index a0eea26c617f3..03d9e238d30a1 100644 --- a/drivers/regulator/qpnp-labibb-regulator.c +++ b/drivers/regulator/qpnp-labibb-regulator.c @@ -924,6 +924,11 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb) pr_err("%s: failed for IBB %x\n", __func__, val); return -EINVAL; } +#ifdef VENDOR_EDIT + /*add by qualcomm provide the patch in 2015-03-02 guozhiming@oem.cn add*/ + rc = qpnp_labibb_write(labibb, + labibb->lab_base + REG_LAB_ENABLE_CTL, &val, 1); +#endif labibb->lab_vreg.vreg_enabled = 0; labibb->ibb_vreg.vreg_enabled = 0; diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 51f75705b8785..ac25e7fa9be0a 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -87,3 +87,7 @@ obj-$(CONFIG_MSM_SYSTEM_HEALTH_MONITOR) += system_health_monitor.o obj-$(CONFIG_MSM_RTB) += msm_rtb-hotplug.o obj-$(CONFIG_QCOM_EARLY_RANDOM) += early_random.o obj-$(CONFIG_MSM_PACMAN) += msm_pacman.o +#VENDOR_EDIT +obj-y += project_info.o +obj-y += boot_mode.o +## diff --git a/drivers/soc/qcom/boot_mode.c b/drivers/soc/qcom/boot_mode.c new file mode 100644 index 0000000000000..83995ef1a17ed --- /dev/null +++ b/drivers/soc/qcom/boot_mode.c @@ -0,0 +1,40 @@ +#include +#include +#include + +static enum oem_boot_mode boot_mode = MSM_BOOT_MODE__NORMAL; + +char *enum_ftm_mode[] = {"normal", "fastboot","recovery", "ftm_at", "ftm_rf", +"ftm_wlan","ftm_mos","charge"}; + +enum oem_boot_mode get_boot_mode(void) +{ + return boot_mode; +} +EXPORT_SYMBOL(get_boot_mode); + +static int __init boot_mode_init(void) +{ + char *substr = strstr(boot_command_line, "androidboot.ftm_mode="); + + if(NULL == substr) + return 0; + + substr += strlen("androidboot.ftm_mode="); + if(substr) { + if(strncmp(substr, "ftm_at", 6) == 0) + boot_mode = MSM_BOOT_MODE__FACTORY; + else if(strncmp(substr, "ftm_rf", 6) == 0) + boot_mode = MSM_BOOT_MODE__RF; + else if(strncmp(substr, "ftm_wlan", 8) == 0) + boot_mode = MSM_BOOT_MODE__WLAN; + else if(strncmp(substr, "ftm_mos", 7) == 0) + boot_mode = MSM_BOOT_MODE__MOS; + else if(strncmp(substr, "ftmrecovery", 11) == 0) + boot_mode = MSM_BOOT_MODE__RECOVERY; + } + + pr_info("kernel boot_mode = %s[%d]\n",enum_ftm_mode[boot_mode],boot_mode); + return 0; +} +arch_initcall(boot_mode_init); diff --git a/drivers/soc/qcom/core_ctl_helper.c b/drivers/soc/qcom/core_ctl_helper.c index 3b25d9811cf70..2f9ab43cf4de9 100644 --- a/drivers/soc/qcom/core_ctl_helper.c +++ b/drivers/soc/qcom/core_ctl_helper.c @@ -17,7 +17,11 @@ #include #include #include +#include #include +#ifdef CONFIG_SCHED_HMP +#include <../kernel/sched/sched.h> +#endif void core_ctl_block_hotplug(void) { @@ -60,3 +64,44 @@ int __ref core_ctl_online_core(unsigned int cpu) return cpu_up(cpu); } EXPORT_SYMBOL(core_ctl_online_core); + +#ifdef VENDOR_EDIT +/* ic, extend core ctrl helper functionalities */ +int __ref core_ctl_is_online_idle_core(unsigned int cpu) +{ + int ret = idle_cpu(cpu) && !nr_iowait_cpu(cpu); + return ret; +} +EXPORT_SYMBOL(core_ctl_is_online_idle_core); + +unsigned int __ref core_ctl_get_freq_cost(unsigned int cpu, unsigned int freq) +{ +#ifdef CONFIG_SCHED_HMP + return power_cost_at_freq(cpu, freq); +#else + /* NOT supported */ + return 0; +#endif +} +EXPORT_SYMBOL(core_ctl_get_freq_cost); + +unsigned int core_ctl_get_cost_at_temp( + unsigned int cpu, + unsigned int freq, + long temp) +{ +#ifdef CONFIG_SCHED_HMP + return power_cost_at_freq_at_temp(cpu, freq, temp); +#else + /* NOT supported */ + return 0; +#endif +} +EXPORT_SYMBOL(core_ctl_get_cost_at_temp); + +struct cpufreq_frequency_table *core_ctl_get_freq_tbl(unsigned int cpu) +{ + return cpufreq_frequency_get_table(cpu); +} +EXPORT_SYMBOL(core_ctl_get_freq_tbl); +#endif diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c old mode 100644 new mode 100755 index ea6e6b629aa0a..5eb55a642bca2 --- a/drivers/soc/qcom/pil-msa.c +++ b/drivers/soc/qcom/pil-msa.c @@ -57,11 +57,14 @@ #define CMD_META_DATA_READY 0x1 #define CMD_LOAD_READY 0x2 -#define CMD_PILFAIL_NFY_MBA 0xffffdead + +//liyunbing@BSP, 2015-05-14, pil load modem fail +#define CMD_PILFAIL_NFY_MBA 0xffffdead #define STATUS_META_DATA_AUTH_SUCCESS 0x3 #define STATUS_AUTH_COMPLETE 0x4 -#define STATUS_MBA_UNLOCKED 0x6 +//liyunbing@BSP, 2015-05-14, pil load modem fail +#define STATUS_MBA_UNLOCKED 0x6 /* External BHS */ #define EXTERNAL_BHS_ON BIT(0) @@ -278,13 +281,16 @@ int pil_mss_shutdown(struct pil_desc *pil) return ret; } +//liyunbing@BSP, 2015-05-14, pil load modem fail +//int pil_mss_deinit_image(struct pil_desc *pil) int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path) { struct modem_data *drv = dev_get_drvdata(pil->dev); struct q6v5_data *q6_drv = container_of(pil, struct q6v5_data, desc); int ret = 0; - s32 status; + + s32 status; if (err_path) { writel_relaxed(CMD_PILFAIL_NFY_MBA, diff --git a/drivers/soc/qcom/pil-msa.h b/drivers/soc/qcom/pil-msa.h old mode 100644 new mode 100755 index 7c0cf3e5c06f5..0f7498e9d4a52 --- a/drivers/soc/qcom/pil-msa.h +++ b/drivers/soc/qcom/pil-msa.h @@ -43,5 +43,6 @@ int pil_mss_make_proxy_votes(struct pil_desc *pil); void pil_mss_remove_proxy_votes(struct pil_desc *pil); int pil_mss_shutdown(struct pil_desc *pil); int pil_mss_deinit_image(struct pil_desc *pil); +//liyunbing@BSP, 2015-05-14, pil load modem fail int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path); #endif diff --git a/drivers/soc/qcom/pil-q6v5-mss.c b/drivers/soc/qcom/pil-q6v5-mss.c old mode 100644 new mode 100755 index 15224a68783f3..459360420d88b --- a/drivers/soc/qcom/pil-q6v5-mss.c +++ b/drivers/soc/qcom/pil-q6v5-mss.c @@ -180,8 +180,9 @@ static int modem_ramdump(int enable, const struct subsys_desc *subsys) ret = pil_do_ramdump(&drv->q6->desc, drv->ramdump_dev); if (ret < 0) pr_err("Unable to dump modem fw memory (rc = %d).\n", ret); - - ret = __pil_mss_deinit_image(&drv->q6->desc, false); +//liyunbing@BSP, 2015-05-14, pil load modem fail +// ret = pil_mss_deinit_image(&drv->q6->desc); + ret = __pil_mss_deinit_image(&drv->q6->desc, false); if (ret < 0) pr_err("Unable to free up resources (rc = %d).\n", ret); diff --git a/drivers/soc/qcom/project_info.c b/drivers/soc/qcom/project_info.c new file mode 100755 index 0000000000000..72d3f17d2a315 --- /dev/null +++ b/drivers/soc/qcom/project_info.c @@ -0,0 +1,340 @@ +/*For OEM project information +*such as project name, hardware ID +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +typedef __u32 uint32; + +struct project_info{ + char project_name[8]; //eg, 14049 + uint32 hw_version; //PCB number, T0, EVT + uint32 rf_v1; + uint32 rf_v2; + uint32 rf_v3; + uint32 modem; + uint32 operator; + uint32 ddr_manufacture_info; + uint32 ddr_raw; + uint32 ddr_column; + uint32 ddr_reserve_info; +}; + +struct component_info{ + char *version; + char *manufacture; +}; + +static struct component_info component_info_desc[COMPONENT_MAX]; + +static struct kobject *project_info_kobj; +static struct project_info * project_info_desc; + +static struct kobject *component_info; + +static ssize_t project_info_get(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t component_info_get(struct device *dev, struct device_attribute *attr, char *buf); + +static DEVICE_ATTR(project_name, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(hw_id, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(rf_id_v1, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(rf_id_v2, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(rf_id_v3, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(modem, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(operator_no, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(ddr_manufacture_info, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(ddr_raw, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(ddr_column, S_IRUGO, project_info_get, NULL); +static DEVICE_ATTR(ddr_reserve_info, S_IRUGO, project_info_get, NULL); + +static ssize_t project_info_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (attr == &dev_attr_project_name) + return sprintf(buf, "%s\n", project_info_desc->project_name); + if (attr == &dev_attr_hw_id) + return sprintf(buf, "%d\n", project_info_desc->hw_version); + if (attr == &dev_attr_rf_id_v1) + return sprintf(buf, "%d\n", project_info_desc->rf_v1); + if (attr == &dev_attr_rf_id_v2) + return sprintf(buf, "%d\n", project_info_desc->rf_v2); + if (attr == &dev_attr_rf_id_v3) + return sprintf(buf, "%d\n", project_info_desc->rf_v3); + if (attr == &dev_attr_modem) + return sprintf(buf, "%d\n", project_info_desc->modem); + if (attr == &dev_attr_operator_no) + return sprintf(buf, "%d\n", project_info_desc->operator); + if (attr == &dev_attr_ddr_manufacture_info) + return sprintf(buf, "%d\n", project_info_desc->ddr_manufacture_info); + if (attr == &dev_attr_ddr_raw) + return sprintf(buf, "%d\n", project_info_desc->ddr_raw); + if (attr == &dev_attr_ddr_column) + return sprintf(buf, "%d\n", project_info_desc->ddr_column); + if (attr == &dev_attr_ddr_reserve_info) + return sprintf(buf, "%d\n", project_info_desc->ddr_reserve_info); + + return -EINVAL; + +} + +static struct attribute *project_info_sysfs_entries[] = { + &dev_attr_project_name.attr, + &dev_attr_hw_id.attr, + &dev_attr_rf_id_v1.attr, + &dev_attr_rf_id_v2.attr, + &dev_attr_rf_id_v3.attr, + &dev_attr_modem.attr, + &dev_attr_operator_no.attr, + &dev_attr_ddr_manufacture_info.attr, + &dev_attr_ddr_raw.attr, + &dev_attr_ddr_column.attr, + &dev_attr_ddr_reserve_info.attr, + NULL, +}; + +static struct attribute_group project_info_attr_group = { + .attrs = project_info_sysfs_entries, +}; + +static DEVICE_ATTR(ddr, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(emmc, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(f_camera, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(r_camera, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(tp, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(lcd, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(wcn, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(l_sensor, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(g_sensor, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(m_sensor, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(gyro, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(backlight, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(mainboard, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(fingerprints, S_IRUGO, component_info_get, NULL); +static DEVICE_ATTR(touch_key, S_IRUGO, component_info_get, NULL); + +char *get_component_version( enum COMPONENT_TYPE type) +{ + if(type >= COMPONENT_MAX){ + pr_err("%s == type %d invalid\n",__func__,type); + return "N/A"; + } + return component_info_desc[type].version?:"N/A"; +} + +char *get_component_manufacture( enum COMPONENT_TYPE type) +{ + if(type >= COMPONENT_MAX){ + pr_err("%s == type %d invalid\n",__func__,type); + return "N/A"; + } + return component_info_desc[type].manufacture?:"N/A"; + +} + +int push_component_info(enum COMPONENT_TYPE type, char *version, char * manufacture) +{ + if(type >= COMPONENT_MAX){ + pr_err("%s == type %d invalid\n",__func__,type); + return -1; + } + component_info_desc[type].version = version; + component_info_desc[type].manufacture = manufacture; + + return 0; +} +EXPORT_SYMBOL(push_component_info); + +int reset_component_info(enum COMPONENT_TYPE type) +{ + if(type >= COMPONENT_MAX){ + pr_err("%s == type %d invalid\n",__func__,type); + return -1; + } + component_info_desc[type].version = NULL; + component_info_desc[type].manufacture = NULL; + + return 0; +} +EXPORT_SYMBOL(reset_component_info); + + +static struct attribute *component_info_sysfs_entries[] = { + &dev_attr_ddr.attr, + &dev_attr_emmc.attr, + &dev_attr_f_camera.attr, + &dev_attr_r_camera.attr, + &dev_attr_tp.attr, + &dev_attr_lcd.attr, + &dev_attr_wcn.attr, + &dev_attr_l_sensor.attr, + &dev_attr_g_sensor.attr, + &dev_attr_m_sensor.attr, + &dev_attr_gyro.attr, + &dev_attr_backlight.attr, + &dev_attr_mainboard.attr, + &dev_attr_fingerprints.attr, + &dev_attr_touch_key.attr, + NULL, +}; + +static struct attribute_group component_info_attr_group = { + .attrs = component_info_sysfs_entries, +}; + +static ssize_t component_info_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (attr == &dev_attr_ddr) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(DDR), get_component_manufacture(DDR)); + if (attr == &dev_attr_emmc) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(EMMC), get_component_manufacture(EMMC)); + if (attr == &dev_attr_f_camera) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(F_CAMERA), get_component_manufacture(F_CAMERA)); + if (attr == &dev_attr_r_camera) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(R_CAMERA), get_component_manufacture(R_CAMERA)); + if (attr == &dev_attr_tp) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(TP), get_component_manufacture(TP)); + if (attr == &dev_attr_lcd) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(LCD), get_component_manufacture(LCD)); + if (attr == &dev_attr_wcn) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(WCN), get_component_manufacture(WCN)); + if (attr == &dev_attr_l_sensor) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(I_SENSOR), get_component_manufacture(I_SENSOR)); + if (attr == &dev_attr_g_sensor) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(G_SENSOR), get_component_manufacture(G_SENSOR)); + if (attr == &dev_attr_m_sensor) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(M_SENSOR), get_component_manufacture(M_SENSOR)); + if (attr == &dev_attr_gyro) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(GYRO), get_component_manufacture(GYRO)); + if (attr == &dev_attr_backlight) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(BACKLIGHT), get_component_manufacture(BACKLIGHT)); + if (attr == &dev_attr_mainboard) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(MAINBOARD), get_component_manufacture(MAINBOARD)); + if (attr == &dev_attr_fingerprints) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(FINGERPRINTS), get_component_manufacture(FINGERPRINTS)); + if (attr == &dev_attr_touch_key) + return sprintf(buf, "VER:\t%s\nMANU:\t%s\n", get_component_version(TOUCH_KEY), get_component_manufacture(TOUCH_KEY)); + + return -EINVAL; +} + +static int __init project_info_init_sysfs(void) +{ + int error = 0; + + project_info_kobj = kobject_create_and_add("project_info", NULL); + if (!project_info_kobj) + return -ENOMEM; + error = sysfs_create_group(project_info_kobj, &project_info_attr_group); + if (error){ + pr_err("project_info_init_sysfs project_info_attr_group failure\n"); + return error; + } + + component_info = kobject_create_and_add("component_info", project_info_kobj); + pr_info("project_info_init_sysfs success\n"); + if (!component_info) + return -ENOMEM; + + error = sysfs_create_group(component_info, &component_info_attr_group); + if (error){ + pr_err("project_info_init_sysfs project_info_attr_group failure\n"); + return error; + } + return 0; +} + +late_initcall(project_info_init_sysfs); + +struct ddr_manufacture{ + int id; + char name[20]; +}; +//ddr id and ddr name +static char ddr_version[32] = {0}; +static char ddr_manufacture[20] = {0}; + +struct ddr_manufacture ddr_manufacture_list[]={ + {1,"Samsung "}, + {2,"Qimonda "}, + {3,"Elpida "}, + {4,"Etpon "}, + {5,"Nanya "}, + {6,"Hynix "}, + {7,"Mosel "}, + {8,"Winbond "}, + {9,"Esmt "}, + {0,}, +}; + +void get_ddr_manufacture_name(void){ + int i; + int id = project_info_desc->ddr_manufacture_info; + for(i = 0; i < (sizeof(ddr_manufacture_list)/sizeof(ddr_manufacture_list[0])); i++) + { + if(ddr_manufacture_list[i].id == id) + { + sprintf(ddr_manufacture, "%s", ddr_manufacture_list[i].name); + break; + } + } +} + +static char mainboard_version[4] = {0}; +static char mainboard_manufacture[8] = {'O', 'N', 'E', 'P', 'L', 'U', 'S','\0'}; +//extern unsigned long totalram_pages __read_mostly; + +int __init init_project_info(void) +{ + static bool project_info_init_done; + int ddr_size; + + if (project_info_init_done) + return 0; + + project_info_desc = smem_find(SMEM_PROJECT_INFO, + sizeof(struct project_info), + 0, + SMEM_ANY_HOST_FLAG); + + if (IS_ERR_OR_NULL(project_info_desc)) + pr_err("%s: get project_info failure\n",__func__); + else + pr_err("%s: project_name: %s hw_version: %d rf_v1: %d rf_v2: %d: rf_v3: %d\n", + __func__, project_info_desc->project_name, project_info_desc->hw_version, + project_info_desc->rf_v1, project_info_desc->rf_v2, project_info_desc->rf_v3); + + snprintf(mainboard_version, sizeof(mainboard_version), "%d",project_info_desc->hw_version); + push_component_info(MAINBOARD,mainboard_version, mainboard_manufacture); + + //add ddr row, column information and manufacture name information + get_ddr_manufacture_name(); + if(totalram_pages > 3*(1<<18)){ + ddr_size = 4; + }else if(totalram_pages > 2*(1<<18)){ + ddr_size = 3; + }else if(totalram_pages > 1*(1<<18)){ + ddr_size = 2; + } + snprintf(ddr_version, sizeof(ddr_version), "size_%dG_r_%d_c_%d", ddr_size, project_info_desc->ddr_raw,project_info_desc->ddr_column); + push_component_info(DDR,ddr_version, ddr_manufacture); + + project_info_init_done = true; + + return 0; +} +subsys_initcall(init_project_info); diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index f0a21b8fe652b..f09549e982850 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -209,6 +209,7 @@ static union { struct socinfo_v10 v10; } *socinfo; + static struct msm_soc_info cpu_of_id[] = { /* 7x01 IDs */ diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c index a6488969975c6..c2fa9b50dafe7 100644 --- a/drivers/soc/qcom/subsystem_restart.c +++ b/drivers/soc/qcom/subsystem_restart.c @@ -637,6 +637,88 @@ static struct subsys_device *find_subsys(const char *str) return dev ? to_subsys(dev) : NULL; } +//add by jiachenghui for restart level debug, 2015-4-17 +#ifdef VENDOR_EDIT +#include +static int val = 0; +static ssize_t proc_restart_level_all_read(struct file *f, char __user *buf,size_t count, loff_t *ppos) +{ + char values[] = { '0' + val, '\n' }; + printk("SSR: the restart level switch is:%d\n",val); + return simple_read_from_buffer(buf, count, ppos, values, sizeof(values)); + +} +static ssize_t proc_restart_level_all_write(struct file *f, const char __user *buf, size_t count, loff_t *ppos) +{ + char temp[1] = {0}; + struct subsys_device *subsys; + + if (copy_from_user(temp, buf, 1)) + return -EFAULT; + + sscanf(temp, "%d", &val); + + if (!strncasecmp(&temp[0], "0", 1)) { + subsys = find_subsys("adsp"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SUBSYS_COUPLED; + subsys = find_subsys("modem"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SUBSYS_COUPLED; + subsys = find_subsys("AR6320"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SUBSYS_COUPLED; + subsys = find_subsys("venus"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SUBSYS_COUPLED; + }else if (!strncasecmp(&temp[0], "1", 1)){ + subsys = find_subsys("adsp"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SOC; + subsys = find_subsys("modem"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SOC; + subsys = find_subsys("AR6320"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SOC; + subsys = find_subsys("venus"); + if (!subsys) + return ENODEV; + subsys->restart_level = RESET_SOC; + } + + printk("SSR:write the restart level switch to :%d\n",val); + return count; +} + +static const struct file_operations ssr_knob_fops = { + .open = simple_open, + .read = proc_restart_level_all_read, + .write = proc_restart_level_all_write, +}; + +static int init_restart_level_all_node( void ) +{ + int ret = 0; + if (!proc_create("restart_level_all", ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ), NULL,&ssr_knob_fops)){ + printk("SSR: Couldn't create proc entry\n"); + ret = -ENOMEM; + } + else { + printk(KERN_CRIT "SSR: Module loaded.\n"); + } + return ret; +} +#endif /* VENDOR_EDIT */ +//end add by jiachenghui for restart level debug, 2015-4-17 + static int subsys_start(struct subsys_device *subsys) { int ret; @@ -1692,6 +1774,14 @@ static int __init subsys_restart_init(void) if (ret) goto err_soc; +//add by jiachenghui for restart level debug, 2015-4-17 +#ifdef VENDOR_EDIT + ret = init_restart_level_all_node(); + if (ret) + printk("SSR:The restart level all node init failed.\n"); +#endif /* VENDOR_EDIT */ +//end add by jiachenghui for restart level debug, 2015-4-17 + return 0; err_soc: diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c index 6379528f963d0..797a9bba58bb6 100644 --- a/drivers/spmi/qpnp-int.c +++ b/drivers/spmi/qpnp-int.c @@ -594,6 +594,11 @@ int qpnpint_unregister_controller(struct device_node *node) } EXPORT_SYMBOL(qpnpint_unregister_controller); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ +extern char wakeup_reason[32]; +#endif /* VENDOR_EDIT */ + static int __qpnpint_handle_irq(struct spmi_controller *spmi_ctrl, struct qpnp_irq_spec *spec, bool show) @@ -633,6 +638,11 @@ static int __qpnpint_handle_irq(struct spmi_controller *spmi_ctrl, pr_warn("%d triggered [0x%01x, 0x%02x,0x%01x] %s\n", irq, spec->slave, spec->per, spec->irq, name); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + if(!wakeup_reason[0]) + strncpy(wakeup_reason,name,sizeof(wakeup_reason) -1); +#endif /* VENDOR_EDIT */ } else { generic_handle_irq(irq); } diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index aefe820a80055..91fd51a7848e4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -140,4 +140,6 @@ source "drivers/staging/netlogic/Kconfig" source "drivers/staging/dwc2/Kconfig" +source "drivers/staging/qcacld-2.0/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5f3c10934aac7..b30bb27fe5700 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_USB_DWC2) += dwc2/ +obj-$(CONFIG_QCA_CLD_WLAN) += qcacld-2.0/ diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index c552ab68079d3..0b0b12a5c114e 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -29,6 +29,12 @@ #define ANDROID_ALARM_PRINT_IO (1U << 1) #define ANDROID_ALARM_PRINT_INT (1U << 2) +#ifdef VENDOR_EDIT +/*shankai 2015-4-2 add begin for alarm_powerup (temporary solution)*/ +#define ANDROID_ALARM_RTC_POWEROFF_WAKEUP_TEMP 5 + +#endif + static int debug_mask = ANDROID_ALARM_PRINT_INFO; module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); @@ -111,9 +117,12 @@ static void alarm_clear(enum android_alarm_type alarm_type, struct timespec *ts) } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); - - if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) + + #ifdef VENDOR_EDIT //shankai@bsp ,modify for rtc power off wakeup support + if ((alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP_TEMP)||(alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)) set_power_on_alarm(ts->tv_sec, 0); + #endif /* VENDOR_EDIT */ + mutex_unlock(&alarm_mutex); } @@ -131,8 +140,11 @@ static void alarm_set(enum android_alarm_type alarm_type, devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); spin_unlock_irqrestore(&alarm_slock, flags); - if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) + #ifdef VENDOR_EDIT //shankai@bsp ,modify for rtc power off wakeup support + if ((alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP_TEMP)||(alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)) set_power_on_alarm(ts->tv_sec, 1); + #endif /* VENDOR_EDIT */ + mutex_unlock(&alarm_mutex); } diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index c76dd401b38d5..7dfc500f33962 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -3517,13 +3517,24 @@ static int binder_transactions_show(struct seq_file *m, void *unused) static int binder_proc_show(struct seq_file *m, void *unused) { + struct binder_proc *itr; struct binder_proc *proc = m->private; int do_lock = !binder_debug_no_lock; + bool valid_proc = false; if (do_lock) binder_lock(__func__); - seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, proc, 1); + + hlist_for_each_entry(itr, &binder_procs, proc_node) { + if (itr == proc) { + valid_proc = true; + break; + } + } + if (valid_proc) { + seq_puts(m, "binder proc state:\n"); + print_binder_proc(m, proc, 1); + } if (do_lock) binder_unlock(__func__); return 0; diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c old mode 100644 new mode 100755 index 9144db918c1cd..737facb496edb --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -372,6 +372,9 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) lowmem_print(3, "select '%s' (%d), adj %hd, size %d, to kill\n", p->comm, p->pid, oom_score_adj, tasksize); } + +//add by huruihuan for memory debug +#ifdef VENDOR_EDIT if (selected) { lowmem_print(1, "Killing '%s' (%d), adj %hd,\n" \ " to free %ldkB on behalf of '%s' (%d) because\n" \ @@ -384,6 +387,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) " Slab Reclaimable is %ldkB\n" \ " Slab UnReclaimable is %ldkB\n" \ " Total Slab is %ldkB\n" \ + " AnonPages is %ldkB\n" \ " GFP mask is 0x%x\n", selected->comm, selected->pid, selected_oom_score_adj, @@ -408,8 +412,50 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) (long)(PAGE_SIZE / 1024) + global_page_state(NR_SLAB_UNRECLAIMABLE) * (long)(PAGE_SIZE / 1024), + global_page_state(NR_ANON_PAGES) * + (long)(PAGE_SIZE / 1024), sc->gfp_mask); +#else + if (selected) { + lowmem_print(1, "Killing '%s' (%d), adj %hd,\n" \ + " to free %ldkB on behalf of '%s' (%d) because\n" \ + " cache %ldkB is below limit %ldkB for oom_score_adj %hd\n" \ + " Free memory is %ldkB above reserved.\n" \ + " Free CMA is %ldkB\n" \ + " Total reserve is %ldkB\n" \ + " Total free pages is %ldkB\n" \ + " Total file cache is %ldkB\n" \ + " Slab Reclaimable is %ldkB\n" \ + " Slab UnReclaimable is %ldkB\n" \ + " Total Slab is %ldkB\n" \ + " GFP mask is 0x%x\n", + selected->comm, selected->pid, + selected_oom_score_adj, + selected_tasksize * (long)(PAGE_SIZE / 1024), + current->comm, current->pid, + other_file * (long)(PAGE_SIZE / 1024), + minfree * (long)(PAGE_SIZE / 1024), + min_score_adj, + other_free * (long)(PAGE_SIZE / 1024), + global_page_state(NR_FREE_CMA_PAGES) * + (long)(PAGE_SIZE / 1024), + totalreserve_pages * (long)(PAGE_SIZE / 1024), + global_page_state(NR_FREE_PAGES) * + (long)(PAGE_SIZE / 1024), + global_page_state(NR_FILE_PAGES) * + (long)(PAGE_SIZE / 1024), + global_page_state(NR_SLAB_RECLAIMABLE) * + (long)(PAGE_SIZE / 1024), + global_page_state(NR_SLAB_UNRECLAIMABLE) * + (long)(PAGE_SIZE / 1024), + global_page_state(NR_SLAB_RECLAIMABLE) * + (long)(PAGE_SIZE / 1024) + + global_page_state(NR_SLAB_UNRECLAIMABLE) * + (long)(PAGE_SIZE / 1024), + sc->gfp_mask); +#endif + if (lowmem_debug_level >= 2 && selected_oom_score_adj == 0) { show_mem(SHOW_MEM_FILTER_NODES); dump_tasks(NULL, NULL); diff --git a/drivers/staging/qcacld-2.0/Android.mk b/drivers/staging/qcacld-2.0/Android.mk new file mode 100644 index 0000000000000..acaf71fa3f77c --- /dev/null +++ b/drivers/staging/qcacld-2.0/Android.mk @@ -0,0 +1,122 @@ +# Android makefile for the WLAN Module + +# Assume no targets will be supported +WLAN_CHIPSET := + +ifeq ($(BOARD_HAS_QCOM_WLAN), true) +# Build/Package options for 8084/8092/8960/8992/8994 target +ifeq ($(call is-board-platform-in-list, apq8084 mpq8092 msm8960 msm8992 msm8994),true) + WLAN_CHIPSET := qca_cld + WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m +endif + +# Build/Package only in case of supported target +ifneq ($(WLAN_CHIPSET),) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +# Determine if we are Proprietary or Open Source +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + WLAN_PROPRIETARY := 0 + WLAN_OPEN_SOURCE := 1 +else + WLAN_PROPRIETARY := 1 + WLAN_OPEN_SOURCE := 0 +endif + +ifeq ($(WLAN_PROPRIETARY),1) + WLAN_BLD_DIR := vendor/qcom/proprietary/wlan-noship +else + WLAN_BLD_DIR := vendor/qcom/opensource/wlan +endif + +# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16) +ifeq ($(call is-platform-sdk-version-at-least,16),true) + DLKM_DIR := $(TOP)/device/qcom/common/dlkm +else + DLKM_DIR := build/dlkm +endif + +# Copy WCNSS_cfg.dat and WCNSS_qcom_cfg.ini file from firmware_bin/ folder to target out directory. +ifeq ($(call is-board-platform-in-list, msm8960),true) +$(shell rm -f $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/WCNSS_cfg.dat) +$(shell rm -f $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/WCNSS_qcom_cfg.ini) +$(shell cp $(LOCAL_PATH)/firmware_bin/WCNSS_cfg.dat $(TARGET_OUT_ETC)/firmware/wlan/qca_cld) +$(shell cp $(LOCAL_PATH)/firmware_bin/WCNSS_qcom_cfg.ini $(TARGET_OUT_ETC)/firmware/wlan/qca_cld) +endif + +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := WLAN_ROOT=../$(WLAN_BLD_DIR)/qcacld-2.0 +# We are actually building wlan.ko here, as per the +# requirement we are specifying _wlan.ko as LOCAL_MODULE. +# This means we need to rename the module to _wlan.ko +# after wlan.ko is built. +KBUILD_OPTIONS += MODNAME=wlan +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(WLAN_SELECT) +KBUILD_OPTIONS += WLAN_OPEN_SOURCE=$(WLAN_OPEN_SOURCE) + +include $(CLEAR_VARS) +LOCAL_MODULE := $(WLAN_CHIPSET)_wlan.ko +LOCAL_MODULE_KBUILD_NAME := wlan.ko +LOCAL_MODULE_TAGS := debug +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET) +include $(DLKM_DIR)/AndroidKernelModule.mk +ifeq ($(WLAN_OPEN_SOURCE),1) +# Build the tools component only if ONE_SHOT_MAKEFILE +# variable is not defined. +ifeq ($(ONE_SHOT_MAKEFILE),) +include $(WLAN_BLD_DIR)/qcacld-2.0/tools/athdiag/Android.mk +include $(WLAN_BLD_DIR)/qcacld-2.0/tools/fwdebuglog/Android.mk +include $(WLAN_BLD_DIR)/qcacld-2.0/tools/pktlog/Android.mk +endif +endif +########################################################### + +# Create Symbolic link for built _wlan.ko driver from +# standard module location. +# TO-DO: This step needs to be moved to a post-build make target instead +# TO-DO: as this may run multiple times +$(shell mkdir -p $(TARGET_OUT)/lib/modules; \ + ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \ + $(TARGET_OUT)/lib/modules/wlan.ko) +$(shell ln -sf /persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin) + +ifeq ($(call is-board-platform-in-list, msm8960),true) +$(shell ln -sf /firmware/image/bdwlan20.bin $(TARGET_OUT_ETC)/firmware/fakeboar.bin) +$(shell ln -sf /firmware/image/otp20.bin $(TARGET_OUT_ETC)/firmware/otp.bin) +$(shell ln -sf /firmware/image/utf20.bin $(TARGET_OUT_ETC)/firmware/utf.bin) +$(shell ln -sf /firmware/image/qwlan20.bin $(TARGET_OUT_ETC)/firmware/athwlan.bin) + +$(shell ln -sf /firmware/image/bdwlan20.bin $(TARGET_OUT_ETC)/firmware/bdwlan20.bin) +$(shell ln -sf /firmware/image/otp20.bin $(TARGET_OUT_ETC)/firmware/otp20.bin) +$(shell ln -sf /firmware/image/utf20.bin $(TARGET_OUT_ETC)/firmware/utf20.bin) +$(shell ln -sf /firmware/image/qwlan20.bin $(TARGET_OUT_ETC)/firmware/qwlan20.bin) + +$(shell ln -sf /firmware/image/bdwlan30.bin $(TARGET_OUT_ETC)/firmware/bdwlan30.bin) +$(shell ln -sf /firmware/image/otp30.bin $(TARGET_OUT_ETC)/firmware/otp30.bin) +$(shell ln -sf /firmware/image/utf30.bin $(TARGET_OUT_ETC)/firmware/utf30.bin) +$(shell ln -sf /firmware/image/qwlan30.bin $(TARGET_OUT_ETC)/firmware/qwlan30.bin) +endif + +# Copy config ini files to target +ifeq ($(call is-board-platform-in-list, msm8994),false) +ifeq ($(WLAN_PROPRIETARY),1) +$(shell mkdir -p $(TARGET_OUT)/etc/firmware/wlan/$(WLAN_CHIPSET)) +$(shell mkdir -p $(TARGET_OUT)/etc/wifi) +$(shell rm -f $(TARGET_OUT)/etc/wifi/WCNSS_qcom_cfg.ini) +$(shell rm -f $(TARGET_OUT)/etc/firmware/wlan/$(WLAN_SHIPSET)/WCNSS_cfg.dat) +$(shell cp $(LOCAL_PATH)/firmware_bin/WCNSS_qcom_cfg.ini $(TARGET_OUT)/etc/wifi) +$(shell cp $(LOCAL_PATH)/firmware_bin/WCNSS_cfg.dat $(TARGET_OUT)/etc/firmware/wlan/$(WLAN_CHIPSET)) +endif +endif + +endif # DLKM check + +endif # supported target check +endif # WLAN enabled check diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/inc/bapApi.h b/drivers/staging/qcacld-2.0/CORE/BAP/inc/bapApi.h new file mode 100644 index 0000000000000..c5a2eaf1de0ca --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/inc/bapApi.h @@ -0,0 +1,2947 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_H +#define WLAN_QCT_WLANBAP_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan BT-AMP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/inc/bapApi.h,v 1.21 2009/03/09 08:58:26 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/01/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +/* BT-AMP PAL API structure types - FramesC generated */ +#include "btampHCI.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * HCI Interface supported + * + * Here we list the HCI Commands and Events which our 802.11 BT-AMP PAL + * supports. + * + * -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Supported HCI Commands +---------------------------------------------------------------------------*/ +#if 0 +/** BT v3.0 Link Control commands */ + BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD, + BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD, +/* +Host Controller and Baseband Commands +*/ + BTAMP_TLV_HCI_RESET_CMD, + BTAMP_TLV_HCI_SET_EVENT_MASK_CMD, + BTAMP_TLV_HCI_FLUSH_CMD, + BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD, +/* v3.0 Host Controller and Baseband Commands */ + BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD, + BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD, + BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD, + BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD, + BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD, + BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TO_CMD, + BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TO_CMD, +/** opcode definition for this command from AMP HCI CR D9r4 markup */ + BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD, +/* End of v3.0 Host Controller and Baseband Commands */ +/* +Informational Parameters +*/ + BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFORMATION_CMD, + BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_COMMANDS_CMD, + BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD, +/* v3.0 Informational commands */ + BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD, +/* +Status Parameters +*/ + BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD, + BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD, + BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD, + BTAMP_TLV_HCI_READ_RSSI_CMD, + BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD, + BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD, + BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD, +/* +Debug Commands +*/ + BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD, + BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD, +#endif + +/*--------------------------------------------------------------------------- + Supported HCI Events +---------------------------------------------------------------------------*/ +#if 0 +/** BT events */ + BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT, + BTAMP_TLV_HCI_COMMAND_STATUS_EVENT, + BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT, + BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT, + BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT, + BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT, + BTAMP_TLV_HCI_QOS_VIOLATION_EVENT, +/** BT v3.0 events */ + BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT, + BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT , + BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT , + BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT , + BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT , + BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT , +#endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + Packet type defines for the AMP to PAL packet encapsulation. +---------------------------------------------------------------------------*/ +#define WLANBAP_HCI_COMMAND_PACKET 0x01 /**< HCI command packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_ACL_DATA_PACKET 0x02 /**< HCI ACL data packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_SCO_DATA_PACKET 0x03 /**< HCI SCO data packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_EVENT_PACKET 0x04 /**< HCI event packet type, characterizing packet types over the + UART and RS232 transports */ +/*--------------------------------------------------------------------------- + HCI Data packet size limitation. +---------------------------------------------------------------------------*/ +#define WLANBAP_MAX_80211_PAL_PDU_SIZE 1492 + +/*--------------------------------------------------------------------------- + HCI Flow Control Modes. +---------------------------------------------------------------------------*/ +#define WLANBAP_FLOW_CONTROL_MODE_PACKET_BASED 0x00 +#define WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED 0x01 + +/*--------------------------------------------------------------------------- + BT "assigned numbers" +---------------------------------------------------------------------------*/ +// Qualcomm Company ID +#define WLANBAP_QUALCOMM_COMPANY_ID 29 + +// HCI Interface version +// Parameter Name Assigned Values +// HCI_Version 0 => Bluetooth HCI Specification 1.0B +// 1 => Bluetooth HCI Specification 1.1 +// 2 => Bluetooth HCI Specification 1.2 +// 3 => Bluetooth HCI Specification 2.0 +// 4 => Bluetooth HCI Specification 2.1 +// 5 => Bluetooth HCI Specification 3.0 +#define WLANBAP_HCI_VERSION 5 +#define WLANBAP_HCI_REVISION 0 +#define WLANBAP_PAL_VERSION 0x01 +#define WLANBAP_PAL_SUBVERSION 0x00 + +// AMP device status +#define WLANBAP_HCI_AMP_STATUS_POWERED_DOWN 0x00 +#define WLANBAP_HCI_AMP_STATUS_NOT_SHARED 0x01 +#define WLANBAP_HCI_AMP_STATUS_SHARED 0x02 +#define WLANBAP_HCI_AMP_STATUS_RESERVED 0x03 + +// ACL Packet types (AMP only uses 0x03) +#define WLANBAP_HCI_PKT_START_NON_FLUSH 0x00 +#define WLANBAP_HCI_PKT_CONT 0x01 +#define WLANBAP_HCI_PKT_START_FLUSH 0x02 +#define WLANBAP_HCI_PKT_AMP 0x03 + +/*--------------------------------------------------------------------------- + BT-AMP PAL supported commands defines + + The Supported Commands configuration parameter lists which HCI commands the +local controller supports. It is implied that if a command is listed as +supported, the feature underlying that command is also supported. + The Supported Commands is a 64 octet bit field. If a bit is set to 1, then +this command is supported. + +---------------------------------------------------------------------------*/ +// 0 1 2 3 4 5 6 7 + +#define WLANBAP_PAL_SUPPORTED_HCI_CMDS { \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x0c, \ + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x88, 0x3c, \ + 0x00, 0x00, 0x00, 0x40, 0x00, 0xff, 0xff, 0x07, \ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ +} + +/*--------------------------------------------------------------------------- + BT-AMP PAL "status" and "reason" error code defines +---------------------------------------------------------------------------*/ +#define WLANBAP_STATUS_SUCCESS (0x00) /* Success. Section 3.1.7 */ + +#define WLANBAP_ERROR_UNKNOWN_HCI_CMND (0x01) +#define WLANBAP_ERROR_NO_CNCT (0x02) /* AMP HCI Section 7.1.39 */ +#define WLANBAP_ERROR_HARDWARE_FAILURE (0x03) +#define WLANBAP_ERROR_PAGE_TIMEOUT (0x04) +/* Section 3.1.10 has this mis-identified as 0x08 */ +#define WLANBAP_ERROR_AUTHENT_FAILURE (0x05) +#define WLANBAP_ERROR_KEY_MISSING (0x06) +#define WLANBAP_ERROR_MEMORY_FULL (0x07) +#define WLANBAP_ERROR_CNCT_TIMEOUT (0x08) /* Section 3.1.8 */ +#define WLANBAP_ERROR_MAX_NUM_CNCTS (0x09) /* Section 3.1.8 */ +#define WLANBAP_ERROR_MAX_NUM_SCO_CNCTS (0x0a) +#define WLANBAP_ERROR_MAX_NUM_ACL_CNCTS (0x0b) +#define WLANBAP_ERROR_CMND_DISALLOWED (0x0c) /* Section 4.1 */ +#define WLANBAP_ERROR_HOST_REJ_RESOURCES (0x0d) /* Section 3.1.7 */ +#define WLANBAP_ERROR_HOST_REJ_SECURITY (0x0e) +#define WLANBAP_ERROR_HOST_REJ_PERSONAL_DEV (0x0f) +#define WLANBAP_ERROR_HOST_TIMEOUT (0x10) +#define WLANBAP_ERROR_UNSUPPORT_FEAT_PARAM (0x11) +#define WLANBAP_ERROR_INVALID_HCI_CMND_PARAM (0x12) +#define WLANBAP_ERROR_TERM_CNCT_USER_ENDED (0x13) +#define WLANBAP_ERROR_TERM_CNCT_LOW_RESOURCE (0x14) +#define WLANBAP_ERROR_TERM_CNCT_POWER_OFF (0x15) +/* Section 3.1.9 has a contradictory semantics of "failed connection" */ +#define WLANBAP_ERROR_TERM_BY_LOCAL_HOST (0x16) /* Section 3.1.8 */ +#define WLANBAP_ERROR_REPEATED_ATTEMPTS (0x17) +#define WLANBAP_ERROR_PAIRING_NOT_ALLOWED (0x18) +#define WLANBAP_ERROR_UNKNOWN_LMP_PDU (0x19) +#define WLANBAP_ERROR_UNSUPPORTED_REMOTE_FEAT (0x1a) +#define WLANBAP_ERROR_SCO_REJ (0x1b) +#define WLANBAP_ERROR_SCO_INTERVAL_REJ (0x1c) +#define WLANBAP_ERROR_SCO_AIR_MODE_REJ (0x1d) +#define WLANBAP_ERROR_INVALID_LMP_PARAMETER (0x1e) +#define WLANBAP_ERROR_UNSPECIFIED_ERROR (0x1f) +#define WLANBAP_ERROR_UNSUPPORTED_LMP_PARAM (0x20) +#define WLANBAP_ERROR_ROLE_CHANGE_NOT_ALLOWED (0x21) +#define WLANBAP_ERROR_LMP_RESPONSE_TIMEOUT (0x22) +#define WLANBAP_ERROR_LMP_ERROR_TRANS_COLLISION (0x23) +#define WLANBAP_ERROR_LMP_PDU_NOT_ALLOWED (0x24) +#define WLANBAP_ERROR_ENCRYPTION_MODE_NOT_ACCEPTABLE (0x25) +#define WLANBAP_ERROR_UNIT_KEY_USED (0x26) +#define WLANBAP_ERROR_QOS_IS_NOT_SUPPORTED (0x27) +#define WLANBAP_ERROR_INSTANT_PASSED (0x28) +#define WLANBAP_ERROR_UNIT_KEY_PAIRING_UNSUPPORTED (0x29) + +#define WLANBAP_ERROR_DIFFERENT_TRANS_COLLISION (0x2A) + +/* reserved (0x2B) */ + +#define WLANBAP_ERROR_QOS_UNACCEPTABLE_PARAMETER (0x2C) +#define WLANBAP_ERROR_QOS_REJECTED (0x2D) +#define WLANBAP_ERROR_CHANNEL_CLASSIFICATION_NS (0x2E) +#define WLANBAP_ERROR_INSUFFICIENT_SECURITY (0x2F) +#define WLANBAP_ERROR_PARM_OUT_OF_MANDATORY_RANGE (0x30) + +/* reserved (0x31) */ + +#define WLANBAP_ERROR_ROLE_SWITCH_PENDING (0x32) + +/* reserved (0x33) */ + +#define WLANBAP_ERROR_RESERVED_SLOT_VIOLATION (0x34) +#define WLANBAP_ERROR_ROLE_SWITCH_FAILED (0x35) +#define WLANBAP_ERROR_EIR_TOO_LARGE (0x36) +#define WLANBAP_ERROR_SSP_NOT_SUPPORTED_BY_HOST (0x37) +#define WLANBAP_ERROR_HOST_BUSY_PAIRING (0x38) +#define WLANBAP_ERROR_NO_SUITABLE_CHANNEL (0x39) +#define WLANBAP_ERROR_CONTROLLER_BUSY (0x3A) + +/*---------------------------------------------------------------------------- + * Event_Mask_Page_2 defines for events + * -------------------------------------------------------------------------*/ +#define WLANBAP_EVENT_MASK_NONE 0x0000000000000000 //No events specified (default) +#define WLANBAP_EVENT_MASK_PHY_LINK_COMPLETE_EVENT 0x0000000000000001 //Physical Link Complete Event +#define WLANBAP_EVENT_MASK_CHANNEL_SELECTED_EVENT 0x0000000000000002 //Channel Selected Event +#define WLANBAP_EVENT_MASK_DISC_PHY_LINK_EVENT 0x0000000000000004 //Disconnection Physical Link Event +#define WLANBAP_EVENT_MASK_PHY_LINK_LOSS_EARLY_WARNING_EVENT 0x0000000000000008 //Physical Link Loss Early Warning Event +#define WLANBAP_EVENT_MASK_PHY_LINK_RECOVERY_EVENT 0x0000000000000010 //Physical Link Recovery Event +#define WLANBAP_EVENT_MASK_LOG_LINK_COMPLETE_EVENT 0x0000000000000020 //Logical Link Complete Event +#define WLANBAP_EVENT_MASK_DISC_LOG_LINK_COMPLETE_EVENT 0x0000000000000040 //Disconnection Logical Link Complete Event +#define WLANBAP_EVENT_MASK_FLOW_SPEC_MOD_COMPLETE_EVENT 0x0000000000000080 //Flow Spec Modify Complete Event +#define WLANBAP_EVENT_MASK_NUM_COMPLETED_DATA_BLOCKS_EVENT 0x0000000000000100 //Number of Completed Data Blocks Event +#define WLANBAP_EVENT_MASK_AMP_START_TEST_EVENT 0x0000000000000200 //AMP Start Test Event +#define WLANBAP_EVENT_MASK_AMP_TEST_END_EVENT 0x0000000000000400 //AMP Test End Event +#define WLANBAP_EVENT_MASK_AMP_RCVR_REPORT_EVENT 0x0000000000000800 //AMP Receiver Report Event +#define WLANBAP_EVENT_MASK_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT 0x0000000000001000 //Short Range Mode Change Complete Event +#define WLANBAP_EVENT_MASK_AMP_STATUS_CHANGE_EVENT 0x0000000000002000 //AMP Status Change Event +#define WLANBAP_EVENT_MASK_RESERVED 0xFFFFFFFFFFFFC000 //Reserved for future use + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Opaque BAP handle Type Declaration + * -------------------------------------------------------------------------*/ +typedef v_PVOID_t tBtampHandle, *ptBtampHandle; + +/*---------------------------------------------------------------------------- + * BAP per-session Context Data Type Declaration + * -------------------------------------------------------------------------*/ +// Move this to bapInternal.h, where it belongs. +// For now, it is just the same thing as the per application context. +//typedef struct sBtampContext tBtampSessCtx; + + +/*--------------------------------------------------------------------------- + HCI Event union +---------------------------------------------------------------------------*/ +typedef struct sBtampHCI_Event { + v_U8_t bapHCIEventCode; /* The event code. To dis-ambiguate. */ + union { + tBtampTLVHCI_Channel_Selected_Event btampChannelSelectedEvent; + tBtampTLVHCI_Command_Complete_Event btampCommandCompleteEvent ; + tBtampTLVHCI_Command_Status_Event btampCommandStatusEvent ; + tBtampTLVHCI_Data_Buffer_Overflow_Event btampDataBufferOverflowEvent ; + tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event btampDisconnectLogicalLinkCompleteEvent ; + tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event btampDisconnectPhysicalLinkCompleteEvent ; + /* Flow_Spec_Modify_Complete_Event is generated after the flow spec modify cmd completes */ + tBtampTLVHCI_Flow_Spec_Modify_Complete_Event btampFlowSpecModifyCompleteEvent ; + /* Asynchronous Flush_Occurred Event CAN ALSO BE generated after the flush cmd completes */ + tBtampTLVHCI_Flush_Occurred_Event btampFlushOccurredEvent ; + tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event btampGenericAMPLinkKeyNotificationEvent ; + tBtampTLVHCI_Hardware_Error_Event btampHardwareErrorEvent ; + tBtampTLVHCI_Logical_Link_Complete_Event btampLogicalLinkCompleteEvent ; + tBtampTLVHCI_Loopback_Command_Event btampLoopbackCommandEvent ; + tBtampTLVHCI_Physical_Link_Complete_Event btampPhysicalLinkCompleteEvent ; + tBtampTLVHCI_Physical_Link_Loss_Warning_Event btampPhysicalLinkLossWarningEvent ; + tBtampTLVHCI_Physical_Link_Recovery_Event btampPhysicalLinkRecoveryEvent ; + tBtampTLVHCI_Qos_Violation_Event btampQosViolationEvent ; + tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event btampShortRangeModeChangeCompleteEvent ; + tBtampTLVHCI_Num_Completed_Pkts_Event btampNumOfCompletedPktsEvent; + tBtampTLVHCI_Num_Completed_Data_Blocks_Event btampNumOfCompletedDataBlocksEvent; + tBtampTLVHCI_Enhanced_Flush_Complete_Event btampEnhancedFlushCompleteEvent ; + } u; +} tBtampHCI_Event, *tpBtampHCI_Event; + +/* 802.3 header */ +typedef struct +{ + /* Destination address field */ + v_U8_t vDA[VOS_MAC_ADDR_SIZE]; + + /* Source address field */ + v_U8_t vSA[VOS_MAC_ADDR_SIZE]; + + /* Length field */ + v_U16_t usLenType; /* Num bytes in info field (i.e., exclude 802.3 hdr) */ + /* Max length 1500 (0x5dc) (What about 0x5ee? That + * includes 802.3 Header and FCS.) */ +}WLANBAP_8023HeaderType; + + +/* + * A list of Command Complete event msgs which will be + * signalled by the Event Callback + */ +#if 0 +/* The tBtampTLVHCI_Command_Complete_Event structure includes each of these*/ +/* HCI Reset: status */ +/* HCI Flush: status, log_link_handle */ + +#endif + +/* + * Command Complete event msgs which will be formed by the caller + * Now an invocation of btampPackTlvHCI_Command_Complete_Event() + * supports generating command complete event messages for all commands... + */ +/* The tBtampTLVHCI_Command_Complete_Event structure includes each of these*/ +#if 0 +/* HCI Cancel Logical Link: status, phy_link_handle, tx_flow_spec_id */ +/* HCI Set Event Mask: status */ +/* HCI Read Connection Accept Timeout: status, connection_accept_timeout */ +/* HCI Write Connection Accept Timeout: status */ +/* HCI Read Link Supervision Timeout: status, log_link_handle (8 sig bits only), link_supervision_timeout */ +/* HCI Write Link Supervision Timeout: status, log_link_handle (8 bits sig only) */ +/* HCI Read Logical Link Accept Timeout: status, logical_link_accept_timeout */ +/* HCI Write Logical Link Accept Timeout: status */ +/* HCI Set Event Mask Page 2: status */ +/* HCI Read Location Data: status, loc_domain_aware, loc_domain, loc_options */ +/* HCI Write Location Data: status */ +/* HCI Read Flow Control Mode: status, flow_control_mode */ +/* HCI Write Flow Control Mode: status */ +/* HCI Read Best Effort Flush Timeout: status, (logical_link_handle ? No!), best_effort_flush_timeout */ +/* HCI Write Best Effort Flush Timeout: status */ +/* HCI Set Short Range Mode: status */ +/* HCI Read Local Version Info: status, HC_HCI_Version, HC_HCI_Revision, HC_PAL_Version, HC_Manufac_Name, HC_PAL_Sub_Version */ +/* HCI Read Local supported commands: status, HC_Support_Cmds */ +/* HCI Read Buffer Size: status, HC_ACL_Data_Packet_Length, HC_SCO_Packet_Length, HC_Total_Num_ACL_Packets, HC_Total_Num_SCO_Packets */ +/* HCI Read Data Block Size: status, HC_Max_ACL_Data_Packet_Length, HC_Data_Block_Length, HC_Total_Num_Data_Blocks */ +/* HCI Read Failed Contact Counter: status, log_link_handle, *pFailedContactCounter */ +/* HCI Reset Failed Contact Counter: status, log_link_handle */ +/* HCI Read Link Quality: status, log_link_handle(?Yes!?), link_quality */ +/* HCI Read RSSI: status, phy_link_handle, rssi */ +/* HCI Read Local AMP Info: status, HC_AMP_Status, HC_Total_BW, HC_Max_Guaranteed_BW, HC_Min_Latency, HC_Max_PDU_Size, HC_Controller_Type, HC_PAL_Capabilities, HC_AMP_Assoc_Length, HC_Max_Flush_Timeout, HC_BE_Flush_Timeout */ +/* HCI Read Local AMP Assoc: status, phy_link_handle, AMP ASSOC remaining length (just actual length, in practice), AMP ASSOC fragment (byte string) */ +/* where AMP Assoc consists of: HC_mac_addr, pref channel (HC_pref_country, HC_pref_triplets), Cnct channel (HC_cnct_country, HC_cnct_triplets), HC_pal_capabilities, HC_pal_version */ +/* HCI Write Remote AMP Assoc: status, phy_link_handle */ +/* HCI Read Loopback Mode: status, loopback_mode */ +/* HCI Write Loopback Mode: status */ + +#endif + +/* BT AMP configuration items */ +typedef struct +{ + /* user preferred channel on which we start the link */ + v_U8_t ucPreferredChannel; + +}WLANBAP_ConfigType; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + VOSS interfaces - Device initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). BAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Open +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). BAP will + use this call to register with TL as the BAP entity for + BT-AMP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in BAP, before close. BAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. BAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Close +( + v_PVOID_t pvosGCtx +); + +/*---------------------------------------------------------------------------- + HDD interfaces - Per instance initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetNewHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Open). BAP will initialize + allocate a per-instance "file handle" equivalent for this specific + open call. + + There should only ever be one call to BSL_Open. Since + the open app user is the BT stack. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle to return btampHandle value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetNewHndl +( + ptBtampHandle *hBtampHandle /* Handle to return btampHandle value in */ +); + +/*========================================================================== + + FUNCTION WLANBAP_ReleaseHndl + + DESCRIPTION + Called by HDD at driver close (BSL_Close). BAP will reclaim (invalidate) + the "file handle" passed into this call. + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: btampHandle value to invalidate. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to btampHandle is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_ReleaseHndl +( + ptBtampHandle btampHandle /* btamp handle value to release */ +); + +/*---------------------------------------------------------------------------- + HDD interfaces - Data plane + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + HDD Data callbacks + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_STAFetchPktCBType)() + + DESCRIPTION + Type of the fetch packet callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STAFetchPktCBType routine being called. Which is called by + TL when the scheduling algorithms allows for transmission of another + packet to the module. + + This function is here to "wrap" or abstract WLANTL_STAFetchPktCBType. + Because the BAP-specific HDD "shim" layer (BSL) doesn't know anything + about STAIds, or other parameters required by TL. + + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STAFetchCBType + to retreive this value. + + IN/OUT + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ + +typedef VOS_STATUS (*WLANBAP_STAFetchPktCBType)( + v_PVOID_t pHddHdl, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo); + + + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_STARxCBType)( ) + + DESCRIPTION + Type of the receive callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STARxCBType routine being called. Which is called by + TL to notify when a packet was received for a registered STA. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STARxCBType + to retrieve this value. + + vosDataBuff: pointer to the VOSS data buffer that was received + (it may be a linked list) + pRxMetaInfo: Rx meta info related to the data frame + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANBAP_STARxCBType)( v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + WLANTL_RxMetaInfoType* pRxMetaInfo); + + + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_TxCompCBType)() + + DESCRIPTION + Type of the tx complete callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_TxCompCBType routine being called. Which is called by + TL to notify when a transmission for a packet has ended. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + <> + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANBAP_TxCompCBType)( v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus ); + +/*---------------------------------------------------------------------------- + HDD Data plane API + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_RegisterDataPlane + + DESCRIPTION + The HDD calls this routine to register the "data plane" routines + for Tx, Rx, and Tx complete with BT-AMP. For now, with only one + physical association supported at a time, this COULD be called + by HDD at the same time as WLANBAP_GetNewHndl. But, in general + it needs to be called upon each new physical link establishment. + + This registration is really two part. The routines themselves are + registered here. But, the mapping between the BSL context and the + actual physical link takes place during WLANBAP_PhysicalLinkCreate. + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RegisterDataPlane +( + ptBtampHandle btampHandle, /* BTAMP context */ + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB, + WLANBAP_STARxCBType pfnBtamp_STARxCB, + WLANBAP_TxCompCBType pfnBtampTxCompCB, + // phy_link_handle, of course, doesn't come until much later. At Physical Link create. + v_PVOID_t pHddHdl /* BSL specific context */ +); +//#endif + +/*=========================================================================== + + FUNCTION WLANBAP_XlateTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet and it wants + to translate it into a 802.3 LLC frame - ready to send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the BT-AMP packet to be + translated to an 802.3 LLC frame + tlMetaInfo: return meta info gleaned from the outgoing frame, here. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here */ + WLANTL_MetaInfoType *tlMetaInfo, /* Return the MetaInfo here. An assist to WLANBAP_STAFetchPktCBType */ + vos_pkt_t *vosDataBuff +); + +/*=========================================================================== + + FUNCTION WLANBAP_XlateRxDataPkt + + DESCRIPTION + + HDD will call this API when it has received a 802.3 (TL/UMA has + Xlated from 802.11) frame from TL and it wants to form a + BT HCI Data Packet - ready to signal up to the BT stack application. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateRxDataPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here. I don't think this is needed */ + vos_pkt_t *vosDataBuff +); + +/*=========================================================================== + + FUNCTION WLANBAP_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. HDD uses this instead of WLANTL_STAPktPending because he is + not aware of the mapping from session to STA ID. + + DEPENDENCIES + + HDD must have called WLANBAP_GetNewHndl before calling this API. + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + BSL can obtain this from the physical handle value in the + downgoing HCI Data Packet. He, after all, was there + when the PhysicalLink was created. He knew the btampHandle + value returned by WLANBAP_GetNewHndl. He knows as well, his + own pHddHdl (see next). + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + ucAc: The access category for the pending frame + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_STAPktPending +( + ptBtampHandle btampHandle, /* Used by BAP to identify the app context and VOSS ctx (!?) */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType ucAc /* This is the first instance of a TL type in bapApi.h */ +); + +/*---------------------------------------------------------------------------- + * BT-AMP PAL HCI Event callback types + *--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION (*tpWLAN_BAPEventCB)() + + DESCRIPTION + Implements the callback for ALL asynchronous events. + Including Events resulting from: + * HCI Create Physical Link, + * Disconnect Physical Link, + * Create Logical Link, + * Flow Spec Modify, + * HCI Reset, + * HCI Flush,... + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + BSL gets this from the downgoing packets Physical handle + value. + pBapHCIEvent: pointer to the union of "HCI Event" structures. Contains all info + needed for HCI event. + assoc_specific_event: flag indicates assoc-specific (1) or global (0) event + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*tpWLAN_BAPEventCB) +( + v_PVOID_t pHddHdl, /* this could refer to either the BSL per + association context which got passed in during + register data plane OR the BSL per application + context passed in during register BAP callbacks + based on setting of the Boolean flag below */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpBtampHCI_Event pBapHCIEvent, /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + v_BOOL_t assoc_specific_event /* Flag to indicate global or assoc-specific event */ +); + + +/*---------------------------------------------------------------------------- + HCI Event Callback Registration routine + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPRegisterBAPCallbacks() + + DESCRIPTION + Register the BAP "Event" callbacks. + Return the per instance handle. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pBapHCIEventCB: pointer to the Event callback + pAppHdl: The context passed in by caller. (I.E., BSL app specific context.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEventCB is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPRegisterBAPCallbacks +( + ptBtampHandle btampHandle, /* BSL uses my handle to talk to me */ + /* Returned from WLANBAP_GetNewHndl() */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpWLAN_BAPEventCB pBapHCIEventCB, /*Implements the callback for ALL asynchronous events. */ + v_PVOID_t pAppHdl // Per-app BSL context +); + + + +/*---------------------------------------------------------------------------- + Host Controller Interface Procedural API + ---------------------------------------------------------------------------*/ + +/** BT v3.0 Link Control commands */ + +/*---------------------------------------------------------------------------- + Each of the next eight command result in asynchronous events (e.g., + HCI_PHYSICAL_LINK_COMPLETE_EVENT, HCI_LOGICAL_LINK_COMPLETE_EVENT, etc...) + These are signalled thru the event callback. (I.E., (*tpWLAN_BAPEventCB).) + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + WLANBAP_GetNewHndl has to be called before every call to + WLAN_BAPPhysicalLinkCreate. Since the context is per + physical link. + pBapHCIPhysLinkCreate: pointer to the "HCI Create Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkAccept: pointer to the "HCI Accept Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkDisconnect: pointer to the "HCI Disconnect Physical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pBapHCIPhysLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCreate: pointer to the "HCI Create Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Logical_Link_Cmd *pBapHCILogLinkCreate, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkAccept: pointer to the "HCI Accept Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pBapHCILogLinkAccept, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkDisconnect: pointer to the "HCI Disconnect Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pBapHCILogLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCancel() + + DESCRIPTION + Implements the actual HCI Cancel Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCancel: pointer to the "HCI Cancel Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + (BTW, the required "HCI Logical Link Complete Event" + will be generated by the BAP state machine and sent up + via the (*tpWLAN_BAPEventCB).) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCancel is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCancel +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pBapHCILogLinkCancel, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlowSpecModify() + + DESCRIPTION + Implements the actual HCI Modify Logical Link command + Produces an asynchronous flow spec modify complete event. Through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlowSpecModify: pointer to the "HCI Flow Spec Modify" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlowSpecModify is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlowSpecModify +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pBapHCIFlowSpecModify, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* Host Controller and Baseband Commands */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReset() + + DESCRIPTION + Implements the actual HCI Reset command. + Produces an asynchronous command complete event. Through the + command complete callback. (I.E., (*tpWLAN_BAPEventCB).) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReset +( + ptBtampHandle btampHandle +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMask() + + DESCRIPTION + Implements the actual HCI Set Event Mask command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMask: pointer to the "HCI Set Event Mask" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMask is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMask +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Cmd *pBapHCISetEventMask, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlush() + + DESCRIPTION + Implements the actual HCI Flush command + Produces an asynchronous command complete event. Through the + event callback. And an asynchronous Flush occurred event. Also through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Flush" Structure. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flush_Cmd *pBapHCIFlush +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_EnhancedBAPFlush() + + DESCRIPTION + Implements the actual HCI Enhanced Flush command + Produces an asynchronous command complete event. Through the command status + event callback. And an asynchronous Enhanced Flush Complete event. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Enhanced Flush" Structure. + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_EnhancedBAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Enhanced_Flush_Cmd *pBapHCIFlush, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete */ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteConnectionAcceptTimeout: pointer to the "HCI Connection Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pBapHCIWriteConnectionAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Read Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + /* Only 8 bits (phy_link_handle) of this log_link_handle are valid. */ + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pBapHCIReadLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Write Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLinkSupervisionTimeout: pointer to the "HCI Link Supervision Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pBapHCIWriteLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* v3.0 Host Controller and Baseband Commands */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLogicalLinkAcceptTimeout: pointer to the "HCI Logical Link Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pBapHCIWriteLogicalLinkAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMaskPage2() + + DESCRIPTION + Implements the actual HCI Set Event Mask Page 2 command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMaskPage2: pointer to the "HCI Set Event Mask Page 2" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMaskPage2 is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMaskPage2 +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pBapHCISetEventMaskPage2, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocationData() + + DESCRIPTION + Implements the actual HCI Read Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocationData +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLocationData() + + DESCRIPTION + Implements the actual HCI Write Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLocationData: pointer to the "HCI Write Location Data" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLocationData +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Location_Data_Cmd *pBapHCIWriteLocationData, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFlowControlMode() + + DESCRIPTION + Implements the actual HCI Read Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFlowControlMode +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteFlowControlMode() + + DESCRIPTION + Implements the actual HCI Write Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteFlowControlMode: pointer to the "HCI Write Flow Control Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteFlowControlMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pBapHCIWriteFlowControlMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Read Best Effort Flush Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + /* The log_link_hanlde identifies which logical link's BE TO*/ + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pBapHCIReadBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Write Best Effort Flush TO command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteBEFlushTO: pointer to the "HCI Write BE Flush TO" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pBapHCIWriteBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetShortRangeMode() + + DESCRIPTION + Implements the actual HCI Set Short Range Mode command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIShortRangeMode: pointer to the "HCI Set Short Range Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIShortRangeMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetShortRangeMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pBapHCIShortRangeMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd0() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 0 (OGF 0x3f, OCF 0x0000). + There is no need for a callback because when this call returns the action has + been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd0 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd1() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 1 (OGF 0x3f, OCF 0x0001). + There is no need for a callback because when this call returns the action has + been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd1 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* End of v3.0 Host Controller and Baseband Commands */ + + +/* Informational Parameters */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalVersionInfo() + + DESCRIPTION + Implements the actual HCI Read Local Version Info command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalVersionInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalVersionInfo +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalSupportedCmds() + + DESCRIPTION + Implements the actual HCI Read Local Supported Commands. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalSupportedCmds is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalSupportedCmds +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBufferSize() + + DESCRIPTION + Implements the actual HCI Read Buffer Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBufferSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBufferSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadDataBlockSize() + + DESCRIPTION + Implements the actual HCI Read Data Block Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadDataBlockSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadDataBlockSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/* +Status Parameters +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Read Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadFailedContactCounter: pointer to the "HCI Read Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFailedContactCounter or + pFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pBapHCIReadFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPResetFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Reset Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIResetFailedContactCounter: pointer to the "HCI Reset Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIResetFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPResetFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pBapHCIResetFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkQuality() + + DESCRIPTION + Implements the actual HCI Read Link Quality command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLinkQuality: pointer to the "HCI Read Link Quality" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkQuality or + pBapHCILinkQuality is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkQuality +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Link_Quality_Cmd *pBapHCIReadLinkQuality, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadRSSI() + + DESCRIPTION + Implements the actual HCI Read RSSI command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadRSSI or + pBapHCIRSSI is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadRSSI +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_RSSI_Cmd *pBapHCIReadRSSI, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPInfo() + + DESCRIPTION + Implements the actual HCI Read Local AMP Information command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPInfo: pointer to the "HCI Read Local AMP Info" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPInfo or + pBapHCILocalAMPInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPInfo +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pBapHCIReadLocalAMPInfo, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPAssoc() + + DESCRIPTION + Implements the actual HCI Read Local AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPAssoc: pointer to the "HCI Read Local AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPAssoc + (or pBapHCILocalAMPAssoc) is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pBapHCIReadLocalAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteRemoteAMPAssoc() + + DESCRIPTION + Implements the actual HCI Write Remote AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteRemoteAMPAssoc: pointer to the "HCI Write Remote AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteRemoteAMPAssoc is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteRemoteAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* +Debug Commands +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLoopbackMode() + + DESCRIPTION + Implements the actual HCI Read Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLoopbackMode: pointer to the "HCI Read Loopback Mode". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLoopbackMode or + pBapHCILoopbackMode is NULL. + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pBapHCIReadLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLoopbackMode() + + DESCRIPTION + Implements the actual HCI Write Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLoopbackMode: pointer to the "HCI Write Loopback Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLoopbackMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pBapHCIWriteLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetConfig() + + DESCRIPTION + The function updates some configuration for BAP module in SME during SMEs + close -> open sequence. + + BAP applies the new configuration at the next transaction. + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN + pConfig: a pointer to a caller allocated object of typedef struct WLANBAP_ConfigType. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pConfig or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetConfig +( + ptBtampHandle btampHandle, + WLANBAP_ConfigType *pConfig +); + +/*=========================================================================== + + FUNCTION WLANBAP_GetAcFromTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet (SKB) and it wants + to find AC type of the data frame from the HCI header on the data pkt + - to be send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + pHciData: Pointer to the HCI data frame + + pucAC: Pointer to return the access category + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetAcFromTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + void *pHciData, /* Pointer to the HCI data frame */ + WLANTL_ACEnumType *pucAC /* Return the AC here */ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPGetMask() + + DESCRIPTION + The function gets the updated event mask from BAP core. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + IN + pEvent_mask_page_2: a pointer to a caller allocated object of 8 bytes. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pEvent_mask_page_2 or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPGetMask( ptBtampHandle btampHandle, + v_U8_t *pEvent_mask_page_2); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPDisconnect() + + DESCRIPTION + The function to request to BAP core to disconnect currecnt AMP connection. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPDisconnect +( + ptBtampHandle btampHandle +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSessionOn() + + DESCRIPTION + The function to check from BAP core if AMP connection is up right now. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +v_BOOL_t WLAN_BAPSessionOn +( + ptBtampHandle btampHandle +); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/inc/btampHCI.h b/drivers/staging/qcacld-2.0/CORE/BAP/inc/btampHCI.h new file mode 100644 index 0000000000000..d0fb4a6142bfe --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/inc/btampHCI.h @@ -0,0 +1,2126 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef BTAMPHCI_H +#define BTAMPHCI_H + +/** + * \file btampHCI.h + * + * \brief Structures, function prototypes & definitions + * for working with 802.11 Frames + * + * + * + * + * This file was automatically generated by 'framesc' + * Mon Mar 02 14:06:14 2009 from the following file(s): + * + * btampHCI.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * Instead, please update the input files & re-run + * 'framesc' For more information on 'framesc' & the + * frames language, run 'framesc --help'. + * + * + */ + + +#define WLANBAP_MAX_LOG_LINKS 16 /* Logical links are assigned by BAP */ + + +#if 0 + +/* Calling conventions: The General format of the Unpack and Pack routines */ + +/*========================================================================== + + FUNCTION Unpack_XxxMessage + + DESCRIPTION + Unpack from a Message buffer into a structured type. + + + DEPENDENCIES + + + PARAMETERS + + + IN + void * : halHandle (passed down to the MAC layer and below) + v_U8_t* : Pointer to the source message buffer + v_U16_t : Length in bytes of the contents of the message buffer. + tXxxMessage* : Pointer to the structure in which to return the unpacked values. + + RETURN VALUE + + The result code associated with performing the operation + + + SIDE EFFECTS + +============================================================================*/ +v_U32_t Unpack_XxxMessage(void *, v_U8_t*,v_U16_t, tXxxMessage*); + + +/*========================================================================== + + FUNCTION Pack_XxxMessage + + DESCRIPTION + Pack the data from a structure into a Message buffer. + + + DEPENDENCIES + + + PARAMETERS + + + IN + void * : halHandle (passed down to the MAC layer and below) + tXxxMessage* : Pointer to the structure from which to obtain values. + v_U8_t* : Pointer to the destination message buffer. + v_U32_t : Length in bytes of the destination message buffer. + v_U32_t* : Pointer to return the actual length of the encoded message buffer in. + + + RETURN VALUE + + The result code associated with performing the operation + + SIDE EFFECTS + + +============================================================================*/ +v_U32_t Pack_XxxMessage(void *, tXxxMessage*, v_U8_t*, v_U32_t, v_U32_t*); + +#endif + + +typedef v_U32_t tBTAMP_U64[2]; + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4214) /* nonstandard extension used */ +#endif /* Microsoft C/C++ bit field types other than int */ + +/* + * Frames Return Codes: + * + * Success is indicated by a return value of zero. Failure is indicated + * by the presence of the high bit. Warnings encountered in the course + * of a successful parse are indicated by various bits in the lower 31 + * being turned on. + * + * For instance, a return value of 0x0000000a would indicate that the + * parse succeeded, but that a mandatory IE wasn't present, and some IE + * was found to be corrupt. + * + * + */ + +#define BTAMP_PARSE_SUCCESS ( 0x00000000 ) +#define BTAMP_UNKNOWN_IES ( 0x00000001 ) +#define BTAMP_MANDATORY_IE_MISSING ( 0x00000002 ) +#define BTAMP_INCOMPLETE_IE ( 0x00000004 ) +#define BTAMP_SKIPPED_BAD_IE ( 0x00000008 ) +#define BTAMP_LAST_IE_TOO_LONG ( 0x00000010 ) +#define BTAMP_DUPLICATE_IE ( 0x00000020 ) +#define BTAMP_BAD_FIXED_VALUE ( 0x00000040 ) +#define BTAMP_INCOMPLETE_TLV ( 0x00000080 ) +#define BTAMP_INVALID_TLV_LENGTH ( 0x00000100 ) +#define BTAMP_SKIPPED_BAD_TLV ( 0x00000200 ) +#define BTAMP_UNKNOWN_TLVS ( 0x00000400 ) +#define BTAMP_LAST_TLV_TOO_LONG ( 0x00000800 ) +#define BTAMP_INTERNAL_ERROR ( 0x10000001 ) +#define BTAMP_MISSING_FIXED_FIELD ( 0x10000002 ) +#define BTAMP_BAD_INPUT_BUFFER ( 0x10000003 ) +#define BTAMP_BAD_OUTPUT_BUFFER ( 0x10000004 ) +#define BTAMP_BUFFER_OVERFLOW ( 0x10000005 ) +#define BTAMP_MANDATORY_TLV_MISSING ( 0x00001000 ) +#define BTAMP_FAILED(code) ( (code) & 0x10000000 ) +#define BTAMP_WARNED(code) ( ( ( 0 == (code) ) & 0x10000000 ) && code) +#define BTAMP_SUCCEEDED(code) ( (code) == 0 ) + +/********************************************************************* + * Fixed Fields * + ********************************************************************/ + +/********************************************************************* + * TLVs * + ********************************************************************/ + +// ID 3 (0x0003) +typedef struct sBtampTLVAMP_Assoc_Connected_Channel { + v_U8_t present; + v_U8_t country[3]; + v_U8_t num_triplets; + v_U8_t triplets[5][3]; +} tBtampTLVAMP_Assoc_Connected_Channel; + +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL_MIN_LEN ( 5 ) + +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL_MAX_LEN ( 11 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_Connected_Channel(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_Connected_Channel*); + +v_U32_t btampPackTlvAMP_Assoc_Connected_Channel(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_Connected_Channel(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1 (0x0001) +typedef struct sBtampTLVAMP_Assoc_MAC_Addr { + v_U8_t present; + v_U8_t mac_addr[6]; +} tBtampTLVAMP_Assoc_MAC_Addr; + +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR_MIN_LEN ( 8 ) + +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_MAC_Addr(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_MAC_Addr*); + +v_U32_t btampPackTlvAMP_Assoc_MAC_Addr(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_MAC_Addr(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4 (0x0004) +typedef struct sBtampTLVAMP_Assoc_PAL_Capabilities { + v_U8_t present; + v_U32_t pal_capabilities; +} tBtampTLVAMP_Assoc_PAL_Capabilities; + +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES ( 4 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES_MIN_LEN ( 6 ) + +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Capabilities(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_PAL_Capabilities*); + +v_U32_t btampPackTlvAMP_Assoc_PAL_Capabilities(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Capabilities(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5 (0x0005) +typedef struct sBtampTLVAMP_Assoc_PAL_Version { + v_U8_t present; + v_U8_t pal_version; + v_U16_t pal_CompanyID; + v_U16_t pal_subversion; +} tBtampTLVAMP_Assoc_PAL_Version; + +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION ( 5 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION_MIN_LEN ( 7 ) + +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Version(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_PAL_Version*); + +v_U32_t btampPackTlvAMP_Assoc_PAL_Version(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Version(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 2 (0x0002) +typedef struct sBtampTLVAMP_Assoc_Preferred_Channel_List { + v_U8_t present; + v_U8_t country[3]; + v_U8_t num_triplets; + v_U8_t triplets[5][3]; +} tBtampTLVAMP_Assoc_Preferred_Channel_List; + +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST ( 2 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST_MIN_LEN ( 5 ) + +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST_MAX_LEN ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_Preferred_Channel_List(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_Preferred_Channel_List*); + +v_U32_t btampPackTlvAMP_Assoc_Preferred_Channel_List(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6 (0x0006) +typedef struct sBtampTLVFlow_Spec { + v_U8_t present; + v_U8_t flow_spec_id; + v_U8_t service_type; + v_U16_t max_sdu; + v_U32_t sdu_inter_arrival; + v_U32_t access_latency; + v_U32_t flush_timeout; +} tBtampTLVFlow_Spec; + +#define BTAMP_TLV_FLOW_SPEC ( 6 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_FLOW_SPEC_MIN_LEN ( 18 ) + +#define BTAMP_TLV_FLOW_SPEC_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvFlow_Spec(void *, v_U8_t*,v_U16_t, tBtampTLVFlow_Spec*); + +v_U32_t btampPackTlvFlow_Spec(void *, tBtampTLVFlow_Spec*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvFlow_Spec(void *, tBtampTLVFlow_Spec*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1081 (0x0439) +typedef struct sBtampTLVHCI_Accept_Logical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Accept_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD ( 1081 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD_MIN_LEN ( 39 ) + +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Accept_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Accept_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Accept_Logical_Link_Cmd(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1078 (0x0436) +typedef struct sBtampTLVHCI_Accept_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t key_length; + v_U8_t key_type; + v_U8_t key_material[32]; +} tBtampTLVHCI_Accept_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD ( 1078 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD_MAX_LEN ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Accept_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Accept_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Accept_Physical_Link_Cmd(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 65 (0x0041) +typedef struct sBtampTLVHCI_Channel_Selected_Event { + v_U8_t present; + v_U8_t phy_link_handle; +} tBtampTLVHCI_Channel_Selected_Event; + +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT ( 65 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Channel_Selected_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Channel_Selected_Event*); + +v_U32_t btampPackTlvHCI_Channel_Selected_Event(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Channel_Selected_Event(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 14 (0x000e) +typedef struct sBtampTLVHCI_Command_Complete_Event { + v_U8_t present; + v_U8_t num_hci_command_packets; + v_U16_t command_opcode; + union + { + struct + { + v_U8_t status; + } Reset; /* command_opcode = c03 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Flush; /* command_opcode = c08 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec_id; + } Logical_Link_Cancel; /* command_opcode = 43b */ + struct + { + v_U8_t status; + } Set_Event_Mask; /* command_opcode = c05 */ + struct + { + v_U8_t status; + v_U16_t connection_accept_timeout; + } Read_Connection_Accept_TO; /* command_opcode = c15 */ + struct + { + v_U8_t status; + } Write_Connection_Accept_TO; /* command_opcode = c16 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U16_t link_supervision_timeout; + } Read_Link_Supervision_TO; /* command_opcode = c36 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Write_Link_Supervision_TO; /* command_opcode = c37 */ + struct + { + v_U8_t status; + v_U16_t logical_link_accept_timeout; + } Read_Logical_Link_Accept_TO; /* command_opcode = c61 */ + struct + { + v_U8_t status; + } Write_Logical_Link_Accept_TO; /* command_opcode = c62 */ + struct + { + v_U8_t status; + } Set_Event_Mask_Page_2; /* command_opcode = c63 */ + struct + { + v_U8_t status; + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; + } Read_Location_Data; /* command_opcode = 3172 */ + struct + { + v_U8_t status; + } Write_Location_Data; /* command_opcode = 3173 */ + struct + { + v_U8_t status; + v_U8_t flow_control_mode; + } Read_Flow_Control_Mode; /* command_opcode = 3174 */ + struct + { + v_U8_t status; + } Write_Flow_Control_Mode; /* command_opcode = 3175 */ + struct + { + v_U8_t status; + v_U32_t best_effort_flush_timeout; + } Read_BE_Flush_TO; /* command_opcode = 3177 */ + struct + { + v_U8_t status; + } Write_BE_Flush_TO; /* command_opcode = 3178 */ + struct + { + v_U8_t status; + } Set_Short_Range_Mode; /* command_opcode = 3179 */ + struct + { + v_U8_t status; + v_U8_t HC_HCI_Version; + v_U16_t HC_HCI_Revision; + v_U8_t HC_PAL_Version; + v_U16_t HC_Manufac_Name; + v_U16_t HC_PAL_Sub_Version; + } Read_Local_Version_Info; /* command_opcode = 4097 */ + struct + { + v_U8_t status; + v_U8_t HC_Support_Cmds[64]; + } Read_Local_Supported_Cmds; /* command_opcode = 4098 */ + struct + { + v_U8_t status; + v_U16_t HC_ACL_Data_Packet_Length; + v_U8_t HC_SCO_Packet_Length; + v_U16_t HC_Total_Num_ACL_Packets; + v_U16_t HC_Total_Num_SCO_Packets; + } Read_Buffer_Size; /* command_opcode = 4101 */ + struct + { + v_U8_t status; + v_U16_t HC_Max_ACL_Data_Packet_Length; + v_U16_t HC_Data_Block_Length; + v_U16_t HC_Total_Num_Data_Blocks; + } Read_Data_Block_Size; /* command_opcode = 4106 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U16_t failed_contact_counter; + } Read_Failed_Contact_Counter; /* command_opcode = 5121 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Reset_Failed_Contact_Counter; /* command_opcode = 5122 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t link_quality; + } Read_Link_Quality; /* command_opcode = 5123 */ + struct + { + v_U8_t status; + /* 2 bytes handle to comply with spec, (lower byte valid) */ + v_U16_t phy_link_handle; + v_S7_t rssi; + } Read_RSSI; /* command_opcode = 5125 */ + struct + { + v_U8_t status; + v_U8_t HC_AMP_Status; + v_U32_t HC_Total_BW; + v_U32_t HC_Max_Guaranteed_BW; + v_U32_t HC_Min_Latency; + v_U32_t HC_Max_PDU_Size; + v_U8_t HC_Controller_Type; + v_U16_t HC_PAL_Capabilities; + v_U16_t HC_AMP_Assoc_Length; + v_U32_t HC_Max_Flush_Timeout; + v_U32_t HC_BE_Flush_Timeout; + } Read_Local_AMP_Info; /* command_opcode = 5129 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + v_U16_t remaining_length; + v_U8_t AMP_assoc_fragment[248]; + } Read_Read_Local_AMP_Assoc; /* command_opcode = 5130 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + } Write_Remote_AMP_Assoc; /* command_opcode = 5131 */ + struct + { + v_U8_t status; + v_U8_t loopback_mode; + } Read_Loopback_Mode; /* command_opcode = 6145 */ + struct + { + v_U8_t status; + } Write_Loopback_Mode; /* command_opcode = 6146 */ + struct + { + v_U8_t status; + } Vendor_Specific_Cmd_0; /* command_opcode = fc00 */ + struct + { + v_U8_t status; + } Vendor_Specific_Cmd_1; /* command_opcode = fc01 */ + } cc_event; +} tBtampTLVHCI_Command_Complete_Event; + +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT ( 14 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT_MAX_LEN ( 257 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Command_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Command_Complete_Event*); + +v_U32_t btampPackTlvHCI_Command_Complete_Event(void *, tBtampTLVHCI_Command_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Command_Complete_Event(void *, tBtampTLVHCI_Command_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 15 (0x000f) +typedef struct sBtampTLVHCI_Command_Status_Event { + v_U8_t present; + v_U8_t status; + v_U8_t num_hci_command_packets; + v_U16_t command_opcode; +} tBtampTLVHCI_Command_Status_Event; + +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT ( 15 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Command_Status_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Command_Status_Event*); + +v_U32_t btampPackTlvHCI_Command_Status_Event(void *, tBtampTLVHCI_Command_Status_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Command_Status_Event(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1080 (0x0438) +typedef struct sBtampTLVHCI_Create_Logical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Create_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD ( 1080 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD_MIN_LEN ( 39 ) + +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Create_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Create_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Create_Logical_Link_Cmd(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Create_Logical_Link_Cmd(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1077 (0x0435) +typedef struct sBtampTLVHCI_Create_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t key_length; + v_U8_t key_type; + v_U8_t key_material[32]; +} tBtampTLVHCI_Create_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD ( 1077 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD_MAX_LEN ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Create_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Create_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Create_Physical_Link_Cmd(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Create_Physical_Link_Cmd(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 26 (0x001a) +typedef struct sBtampTLVHCI_Data_Buffer_Overflow_Event { + v_U8_t present; + v_U8_t link_type; +} tBtampTLVHCI_Data_Buffer_Overflow_Event; + +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT ( 26 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Data_Buffer_Overflow_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Data_Buffer_Overflow_Event*); + +v_U32_t btampPackTlvHCI_Data_Buffer_Overflow_Event(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1082 (0x043a) +typedef struct sBtampTLVHCI_Disconnect_Logical_Link_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Disconnect_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD ( 1082 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 70 (0x0046) +typedef struct sBtampTLVHCI_Disconnect_Logical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT ( 70 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1079 (0x0437) +typedef struct sBtampTLVHCI_Disconnect_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD ( 1079 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 66 (0x0042) +typedef struct sBtampTLVHCI_Disconnect_Physical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT ( 66 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1084 (0x043c) +typedef struct sBtampTLVHCI_Flow_Spec_Modify_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U8_t be_aggr_counter; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Flow_Spec_Modify_Cmd; + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD ( 1084 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD_MIN_LEN ( 41 ) + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Cmd*); + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Cmd(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 71 (0x0047) +typedef struct sBtampTLVHCI_Flow_Spec_Modify_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flow_Spec_Modify_Complete_Event; + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT ( 71 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*); + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Complete_Event(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3080 (0x0c08) +typedef struct sBtampTLVHCI_Flush_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flush_Cmd; + +#define BTAMP_TLV_HCI_FLUSH_CMD ( 3080 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLUSH_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_FLUSH_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flush_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flush_Cmd*); + +v_U32_t btampPackTlvHCI_Flush_Cmd(void *, tBtampTLVHCI_Flush_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flush_Cmd(void *, tBtampTLVHCI_Flush_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 17 (0x0011) +typedef struct sBtampTLVHCI_Flush_Occurred_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flush_Occurred_Event; + +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT ( 17 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flush_Occurred_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flush_Occurred_Event*); + +v_U32_t btampPackTlvHCI_Flush_Occurred_Event(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flush_Occurred_Event(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3167 (0x0C5F) +typedef struct sBtampTLVHCI_Enhanced_Flush_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U8_t packet_type; +} tBtampTLVHCI_Enhanced_Flush_Cmd; + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD ( 3167 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Enhanced_Flush_Cmd*); + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Cmd(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Cmd(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 57 (0x0039) +typedef struct sBtampTLVHCI_Enhanced_Flush_Complete_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Enhanced_Flush_Complete_Event; + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT ( 57 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Enhanced_Flush_Complete_Event*); + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Complete_Event(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ + +// ID 62 (0x003e) +typedef struct sBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event { + v_U8_t present; + v_U8_t bd_addr[6]; + v_U8_t generic_amp_link_key[32]; + v_U8_t key_type; +} tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event; + +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT ( 62 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT_MIN_LEN ( 41 ) + +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*); + +v_U32_t btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 16 (0x0010) +typedef struct sBtampTLVHCI_Hardware_Error_Event { + v_U8_t present; + v_U8_t hardware_code; +} tBtampTLVHCI_Hardware_Error_Event; + +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT ( 16 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Hardware_Error_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Hardware_Error_Event*); + +v_U32_t btampPackTlvHCI_Hardware_Error_Event(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Hardware_Error_Event(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1083 (0x043b) +typedef struct sBtampTLVHCI_Logical_Link_Cancel_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec_id; +} tBtampTLVHCI_Logical_Link_Cancel_Cmd; + +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD ( 1083 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Logical_Link_Cancel_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Logical_Link_Cancel_Cmd*); + +v_U32_t btampPackTlvHCI_Logical_Link_Cancel_Cmd(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 69 (0x0045) +typedef struct sBtampTLVHCI_Logical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t phy_link_handle; + v_U8_t flow_spec_id; +} tBtampTLVHCI_Logical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT ( 69 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Logical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Logical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 25 (0x0019) +typedef struct sBtampTLVHCI_Loopback_Command_Event { + v_U8_t present; + v_U8_t hci_command_packet[64]; +} tBtampTLVHCI_Loopback_Command_Event; + +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT ( 25 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT_MIN_LEN ( 66 ) + +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT_MAX_LEN ( 66 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Loopback_Command_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Loopback_Command_Event*); + +v_U32_t btampPackTlvHCI_Loopback_Command_Event(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Loopback_Command_Event(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 64 (0x0040) +typedef struct sBtampTLVHCI_Physical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t ch_number; +} tBtampTLVHCI_Physical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT ( 64 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 67 (0x0043) +typedef struct sBtampTLVHCI_Physical_Link_Loss_Warning_Event { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Physical_Link_Loss_Warning_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT ( 67 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Loss_Warning_Event(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 68 (0x0044) +typedef struct sBtampTLVHCI_Physical_Link_Recovery_Event { + v_U8_t present; + v_U8_t phy_link_handle; +} tBtampTLVHCI_Physical_Link_Recovery_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT ( 68 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Recovery_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Recovery_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Recovery_Event(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Recovery_Event(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 30 (0x001e) +typedef struct sBtampTLVHCI_Qos_Violation_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Qos_Violation_Event; + +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT ( 30 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Qos_Violation_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Qos_Violation_Event*); + +v_U32_t btampPackTlvHCI_Qos_Violation_Event(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Qos_Violation_Event(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3177 (0x0c69) +typedef struct sBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD ( 3177 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4101 (0x1005) +typedef struct sBtampTLVHCI_Read_Buffer_Size_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Buffer_Size_Cmd; + +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD ( 4101 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Buffer_Size_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Buffer_Size_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Buffer_Size_Cmd(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3093 (0x0c15) +typedef struct sBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD ( 3093 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4106 (0x100a) +typedef struct sBtampTLVHCI_Read_Data_Block_Size_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Data_Block_Size_Cmd; + +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD ( 4106 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Data_Block_Size_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Data_Block_Size_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Data_Block_Size_Cmd(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5121 (0x1401) +typedef struct sBtampTLVHCI_Read_Failed_Contact_Counter_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd; + +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD ( 5121 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3174 (0x0c66) +typedef struct sBtampTLVHCI_Read_Flow_Control_Mode_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Flow_Control_Mode_Cmd; + +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD ( 3174 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5123 (0x1403) +typedef struct sBtampTLVHCI_Read_Link_Quality_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Link_Quality_Cmd; + +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD ( 5123 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Link_Quality_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Link_Quality_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Link_Quality_Cmd(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Link_Quality_Cmd(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3126 (0x0c36) +typedef struct sBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD ( 3126 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5130 (0x140a) +typedef struct sBtampTLVHCI_Read_Local_AMP_Assoc_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U16_t length_so_far; + v_U16_t max_remote_amp_assoc_length; +} tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD ( 5130 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5129 (0x1409) +typedef struct sBtampTLVHCI_Read_Local_AMP_Information_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_AMP_Information_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD ( 5129 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Information_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4098 (0x1002) +typedef struct sBtampTLVHCI_Read_Local_Supported_Cmds_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD ( 4098 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4097 (0x1001) +typedef struct sBtampTLVHCI_Read_Local_Version_Info_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_Version_Info_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD ( 4097 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_Version_Info_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_Version_Info_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_Version_Info_Cmd(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3172 (0x0c64) +typedef struct sBtampTLVHCI_Read_Location_Data_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Location_Data_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD ( 3172 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Location_Data_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Location_Data_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Location_Data_Cmd(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Location_Data_Cmd(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3169 (0x0c61) +typedef struct sBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD ( 3169 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6145 (0x1801) +typedef struct sBtampTLVHCI_Read_Loopback_Mode_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Loopback_Mode_Cmd; + +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD ( 6145 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Loopback_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Loopback_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5125 (0x1405) +typedef struct sBtampTLVHCI_Read_RSSI_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_RSSI_Cmd; + +#define BTAMP_TLV_HCI_READ_RSSI_CMD ( 5125 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_RSSI_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_RSSI_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_RSSI_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_RSSI_Cmd*); + +v_U32_t btampPackTlvHCI_Read_RSSI_Cmd(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_RSSI_Cmd(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3075 (0x0c03) +typedef struct sBtampTLVHCI_Reset_Cmd { + v_U8_t present; +} tBtampTLVHCI_Reset_Cmd; + +#define BTAMP_TLV_HCI_RESET_CMD ( 3075 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_RESET_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_RESET_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Reset_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Reset_Cmd*); + +v_U32_t btampPackTlvHCI_Reset_Cmd(void *, tBtampTLVHCI_Reset_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Reset_Cmd(void *, tBtampTLVHCI_Reset_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5122 (0x1402) +typedef struct sBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd; + +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD ( 5122 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*); + +v_U32_t btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3077 (0x0c05) +typedef struct sBtampTLVHCI_Set_Event_Mask_Cmd { + v_U8_t present; + v_U8_t event_mask[8]; +} tBtampTLVHCI_Set_Event_Mask_Cmd; + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD ( 3077 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD_MIN_LEN ( 10 ) + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Event_Mask_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3171 (0x0c63) +typedef struct sBtampTLVHCI_Set_Event_Mask_Page_2_Cmd { + v_U8_t present; + v_U8_t event_mask_page_2[8]; +} tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd; + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD ( 3171 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD_MIN_LEN ( 10 ) + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3179 (0x0c6b) +typedef struct sBtampTLVHCI_Set_Short_Range_Mode_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t short_range_mode; +} tBtampTLVHCI_Set_Short_Range_Mode_Cmd; + +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD ( 3179 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Short_Range_Mode_Cmd(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 76 (0x004c) +typedef struct sBtampTLVHCI_Short_Range_Mode_Change_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t short_range_mode; +} tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event; + +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT ( 76 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*); + +v_U32_t btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3178 (0x0c6a) +typedef struct sBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U32_t best_effort_flush_timeout; +} tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD ( 3178 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MIN_LEN ( 8 ) + +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3094 (0x0c16) +typedef struct sBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd { + v_U8_t present; + v_U16_t connection_accept_timeout; +} tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD ( 3094 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3175 (0x0c67) +typedef struct sBtampTLVHCI_Write_Flow_Control_Mode_Cmd { + v_U8_t present; + v_U8_t flow_control_mode; +} tBtampTLVHCI_Write_Flow_Control_Mode_Cmd; + +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD ( 3175 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3127 (0x0c37) +typedef struct sBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U16_t link_supervision_timeout; +} tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD ( 3127 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3173 (0x0c65) +typedef struct sBtampTLVHCI_Write_Location_Data_Cmd { + v_U8_t present; + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; +} tBtampTLVHCI_Write_Location_Data_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD ( 3173 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Location_Data_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Location_Data_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Location_Data_Cmd(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Location_Data_Cmd(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3170 (0x0c62) +typedef struct sBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd { + v_U8_t present; + v_U16_t logical_link_accept_timeout; +} tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD ( 3170 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6146 (0x1802) +typedef struct sBtampTLVHCI_Write_Loopback_Mode_Cmd { + v_U8_t present; + v_U8_t loopback_mode; +} tBtampTLVHCI_Write_Loopback_Mode_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD ( 6146 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Loopback_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Loopback_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5131 (0x140b) +typedef struct sBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U16_t length_so_far; + v_U16_t amp_assoc_remaining_length; + v_U8_t amp_assoc_fragment[248]; +} tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd; + +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD ( 5131 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 64512 (0xfc00) +typedef struct sBtampTLVHCI_Vendor_Specific_Cmd_0 { + v_U8_t present; +} tBtampTLVHCI_Vendor_Specific_0_Cmd; + +#define BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0 ( 64512 ) + +// ID 64513 (0xfc01) +typedef struct sBtampTLVHCI_Vendor_Specific_Cmd_1 { + v_U8_t present; +} tBtampTLVHCI_Vendor_Specific_1_Cmd; + +#define BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1 ( 64513 ) + +/********************************************************************* + * Information Elements * + ********************************************************************/ + +/************************************************************************ + * Frames + **********************************************************************/ + +typedef struct sBtampAMP_ASSOC{ + tBtampTLVAMP_Assoc_MAC_Addr AMP_Assoc_MAC_Addr; + tBtampTLVAMP_Assoc_Preferred_Channel_List AMP_Assoc_Preferred_Channel_List; + tBtampTLVAMP_Assoc_Connected_Channel AMP_Assoc_Connected_Channel; + tBtampTLVAMP_Assoc_PAL_Capabilities AMP_Assoc_PAL_Capabilities; + tBtampTLVAMP_Assoc_PAL_Version AMP_Assoc_PAL_Version; +} tBtampAMP_ASSOC; + +#define BTAMP_AMP_ASSOC ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +v_U32_t btampUnpackAMP_ASSOC(void * pCtx, v_U8_t *pBuf, v_U32_t nBuf, tBtampAMP_ASSOC *pFrm); +v_U32_t btampPackAMP_ASSOC(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U8_t *pBuf, v_U32_t nBuf, v_U32_t *pnConsumed); +v_U32_t btampGetPackedAMP_ASSOCSize(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U32_t *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +/* HCI Number of Completed Packets Event*/ +typedef struct sBtampTLVHCI_Num_Completed_Pkts_Event +{ + v_U8_t present; + /* + The number of Connection Handles and Num_Data_Packets + parameters pairs contained in this event.Range: 0-255 + */ + + v_U8_t num_handles; + + /* + Size , Number of Handles * 2 Octets,Range: 0x0000-0x0EFF + */ + v_U16_t conn_handles[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of HCI Data Packets that have been completed (transmitted + or flushed) for the associated Connection Handle since the previous time + the event was returned.Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_pkts[WLANBAP_MAX_LOG_LINKS]; +} tBtampTLVHCI_Num_Completed_Pkts_Event; + +#define BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT ( 19 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Pkts_Event(void *, tBtampTLVHCI_Num_Completed_Pkts_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Pkts_Event(void *, tBtampTLVHCI_Num_Completed_Pkts_Event*, v_U32_t*); + +/*Length of the value field expected in a TLV of type Flow SPec*/ +#define WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN 16 + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +/* HCI Number of Completed Data Blocks Event*/ +typedef struct sBtampTLVHCI_Num_Completed_Data_Blocks_Event +{ + v_U8_t present; + /* + Total number of data block buffers available in the Controller for the + storage of data packets scheduled for transmission. This indicates + the existing value is unchanged, or increased, or reduced by up to + the sum of the Num_Of_Completed_Blocks values in this command + */ + + v_U16_t total_num_data_blocks; + + /* + The number of Connection Handles and Num_Data_Packets + parameters pairs contained in this event.Range: 0-255 + */ + + v_U8_t num_handles; + + /* + Size , Number of Handles * 2 Octets,Range: 0x0000-0x0EFF + */ + v_U16_t conn_handles[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of HCI Data Packets that have been completed (transmitted + or flushed) for the associated Connection Handle since the previous time + the event was returned.Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_pkts[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of data blocks that have been freed for the associated + Handle since the previous time that a Number Of Completed Data + Blocks event provided information about this Handle. + Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_blocks[WLANBAP_MAX_LOG_LINKS]; + +} tBtampTLVHCI_Num_Completed_Data_Blocks_Event; + +#define BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT ( 72 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Data_Blocks_Event(void *, tBtampTLVHCI_Num_Completed_Data_Blocks_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(void *, tBtampTLVHCI_Num_Completed_Data_Blocks_Event*, v_U32_t*); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#endif /* BTAMPHCI_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiData.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiData.c new file mode 100644 index 0000000000000..c515e908f3413 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiData.c @@ -0,0 +1,1179 @@ +/* + * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i D a t a . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + "platform independent" Data path functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiData.c,v 1.4 2008/11/10 22:34:22 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +#include "wlan_qct_hal.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "bapApiTimer.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +/*Endian-ness definitions*/ + +#undef BAP_LITTLE_BIT_ENDIAN +#define BAP_LITTLE_BIT_ENDIAN + +/*LLC header definitions*/ + +/* Length of the LLC header*/ +#define WLANBAP_LLC_HEADER_LEN 8 +#if 0 +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_OFFSET 3 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_SIZE 3 + +/*Offset of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_OFFSET (WLANBAP_LLC_OUI_OFFSET + WLANBAP_LLC_OUI_SIZE) + +/*Size of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_SIZE 2 +#endif + +/*BT-AMP protocol type values*/ +/*BT-AMP packet of type data*/ +#define WLANBAP_BT_AMP_TYPE_DATA 0x0001 + +/*BT-AMP packet of type activity report*/ +#define WLANBAP_BT_AMP_TYPE_AR 0x0002 + +/*BT-AMP packet of type security frame*/ +#define WLANBAP_BT_AMP_TYPE_SEC 0x0003 + +/*802.3 header definitions*/ +#define WLANBAP_802_3_HEADER_LEN 14 + +/* Offset of DA field in a 802.3 header*/ +#define WLANBAP_802_3_HEADER_DA_OFFSET 0 + +//*BT-AMP packet LLC OUI value*/ +const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +/*LLC header value*/ +static v_U8_t WLANBAP_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; + +/* HCI header definitions*/ + +// Define the length of the ACL data packet HCI header +#define WLANBAP_HCI_ACL_HEADER_LEN 4 + +// Debug related defines +//#define DBGLOG printf +#define DUMPLOG_ON +#ifdef DUMPLOG_ON +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +#if 0 +// Debug related defines +#define DBGLOG printf +#define DUMPLOG +#if defined DUMPLOG +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + DBGLOG("%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + DBGLOG("%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + DBGLOG("\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif +#endif + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +// Don't we have this type defined somewhere? +#if 0 +/* 802.3 header */ +typedef struct +{ + /* Destination address field */ + v_U8_t vDA[VOS_MAC_ADDR_SIZE]; + + /* Source address field */ + v_U8_t vSA[VOS_MAC_ADDR_SIZE]; + + /* Length field */ + v_U16_t usLenType; /* Num bytes in info field (i.e., exclude 802.3 hdr) */ + /* Max length 1500 (0x5dc) (What about 0x5ee? That + * includes 802.3 Header and FCS.) */ +}WLANBAP_8023HeaderType; +#endif + +/** + * \brief HCI ACL Data packet format + * + * 0 7 8 15 16 23 24 31 + * +--------+----+----+--------+--------+ + * | phy_ |log_| PB/| Data Total | + * | link_ |lnk_| BC | Length | + * | handle |hndl|Flag| | + * +--------+----+----+--------+--------+ + * | | + * | Data | + * ~ ~ + * +--------+---------+--------+--------+ + * + * NB: + * This is in little-endian + * 1) phy_link_handle is the first 8 bits + * 2) log_link_handle is the next 4 bits + * 3) PB flag is the next 2 bits + * 4) BC flags is the next 2 bits + * 5) Total length of the data field is the next 16 bits + * + */ + +typedef struct +{ + +#ifndef BAP_LITTLE_BIT_ENDIAN + + v_U8_t phyLinkHandle; /* do I have to reverse the byte? I think so... */ + + v_U8_t BCFlag :2; + v_U8_t PBFlag :2; + v_U8_t logLinkHandle :4; + + v_U16_t dataLength; /* do I have to reverse each byte? and then reverse the two bytes? I think so... */ + +#else + + v_U8_t phyLinkHandle; + + v_U8_t logLinkHandle :4; + v_U8_t PBFlag :2; + v_U8_t BCFlag :2; + + v_U16_t dataLength; /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */ + +#endif + +} WLANBAP_HCIACLHeaderType; + + + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +#define WLANBAP_DEBUG_FRAME_BYTE_PER_LINE 16 +#define WLANBAP_DEBUG_FRAME_BYTE_PER_BYTE 4 + +/*=========================================================================== + + FUNCTION WLANBAP_XlateTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet and it wants + to translate it into a 802.3 LLC frame - ready to send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the BT-AMP packet to be + translated to an 802.3 LLC frame + tlMetaInfo: return meta info gleaned from the outgoing frame, here. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here */ + WLANTL_MetaInfoType *tlMetaInfo, /* Return the MetaInfo here. An assist to WLANBAP_STAFetchPktCBType */ + vos_pkt_t *vosDataBuff +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + tpBtampLogLinkCtx pLogLinkContext; + WLANBAP_8023HeaderType w8023Header; + WLANBAP_HCIACLHeaderType hciACLHeader = { 0 }; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + VOS_STATUS vosStatus; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_U16_t headerLength; /* The 802.3 frame length*/ + v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ + uintptr_t value = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // Here, I have to make the assumption that this is an + // HCI ACL Data packet that I am being handed. + vosStatus = vos_pkt_pop_head( vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop HCI ACL header from packet %d", + vosStatus); + + return vosStatus; + } + + // JEZ081003: Remove this after debugging + // Sanity check the phy_link_handle value + + if ( phy_link_handle != hciACLHeader.phyLinkHandle ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: phy_link_handle mismatch in %s phy_link_handle=%d hciACLHeader.phyLinkHandle=%d", + __func__, phy_link_handle, hciACLHeader.phyLinkHandle); + return VOS_STATUS_E_INVAL; + } + + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // JEZ081003: Remove this after debugging + // Sanity check the log_link_handle value + if (!BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link handle (%d) in %s. Corrected.", + hciACLHeader.logLinkHandle, + __func__); + + // JEZ090123: Insure that the logical link value is good + hciACLHeader.logLinkHandle = 1; + //return VOS_STATUS_E_INVAL; + } + + /* Use the log_link_handle to retrieve the logical link context */ + /* JEZ081006: abstract this with a proc. So you can change the impl later */ + pLogLinkContext = &(pBtampCtx->btampLogLinkCtx[ hciACLHeader.logLinkHandle ]); + + // JEZ081003: Remove this after debugging + // Sanity check the log_link_handle value + // JEZ081113: I changed this to fail on an UNOCCUPIED entry + if ( pLogLinkContext->present != VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link entry in %s", + __func__); + + return VOS_STATUS_E_INVAL; + } + + // Return the AC and MetaInfo + + // Now copy the AC values from the Logical Link context + *pucAC = pLogLinkContext->btampAC; + // Now copy the values from the Logical Link context to the MetaInfo + tlMetaInfo->ucTID = pLogLinkContext->ucTID; + tlMetaInfo->ucUP = pLogLinkContext->ucUP; + tlMetaInfo->ucIsEapol = VOS_FALSE; + tlMetaInfo->ucDisableFrmXtl = VOS_FALSE; + tlMetaInfo->ucBcast = VOS_FALSE; /* hciACLHeader.BCFlag; */ /* Don't I want to use the BCFlag? */ + tlMetaInfo->ucMcast = VOS_FALSE; + tlMetaInfo->ucType = 0x00; /* What is this really ?? */ +// tlMetaInfo->usTimeStamp = 0x00; /* Ravi, shouldn't you be setting this? It's in the VOS packet. */ + + // Form the 802.3 header + + vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); + + /* Now this length passed down in HCI...is in little-endian */ + headerLength = vos_le16_to_cpu(hciACLHeader.dataLength); + headerLength += WLANBAP_LLC_HEADER_LEN; + /* Now the 802.3 length field is big-endian?! */ + w8023Header.usLenType = vos_cpu_to_be16(headerLength); + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + + /* Now form the LLC header */ + vos_mem_copy(aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER)); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_DATA + WLANBAP_LLC_PROTO_TYPE_SIZE); + + /* Push on the LLC header */ + vos_pkt_push_head(vosDataBuff, + aucLLCHeader, + WLANBAP_LLC_HEADER_LEN); + + /* Push on the 802.3 header */ + vos_pkt_push_head(vosDataBuff, &w8023Header, sizeof(w8023Header)); + + + /*Set the logical link handle as user data so that we can retrieve it on + Tx Complete */ + value = (uintptr_t)hciACLHeader.logLinkHandle; + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, + (v_VOID_t *)value); + + return VOS_STATUS_SUCCESS; +}/*WLANBAP_XlateTxDataPkt*/ + +/*=========================================================================== + + FUNCTION WLANBAP_GetAcFromTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet (SKB) and it wants + to find AC type of the data frame from the HCI header on the data pkt + - to be send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + pHciData: Pointer to the HCI data frame + + pucAC: Pointer to return the access category + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetAcFromTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + void *pHciData, /* Pointer to the HCI data frame */ + WLANTL_ACEnumType *pucAC /* Return the AC here */ +) +{ + ptBtampContext pBtampCtx; + tpBtampLogLinkCtx pLogLinkContext; + WLANBAP_HCIACLHeaderType hciACLHeader; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if (( NULL == btampHandle) || (NULL == pHciData) || (NULL == pucAC)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid params in %s", __func__); + return VOS_STATUS_E_FAULT; + } + pBtampCtx = (ptBtampContext) btampHandle; + + vos_mem_copy( &hciACLHeader, pHciData, WLANBAP_HCI_ACL_HEADER_LEN); + // Sanity check the log_link_handle value + if (!BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link handle (%d) in %s", + hciACLHeader.logLinkHandle, + __func__); + + return VOS_STATUS_E_INVAL; + } + + /* Use the log_link_handle to retrieve the logical link context */ + /* JEZ081006: abstract this with a proc. So you can change the impl later */ + pLogLinkContext = &(pBtampCtx->btampLogLinkCtx[ hciACLHeader.logLinkHandle ]); + + // Sanity check the log_link_handle value + // JEZ081113: I changed this to fail on an UNOCCUPIED entry + if ( pLogLinkContext->present != VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link entry in %s", + __func__); + + return VOS_STATUS_E_INVAL; + } + + // Return the AC + + // Now copy the AC values from the Logical Link context + *pucAC = pLogLinkContext->btampAC; + + return VOS_STATUS_SUCCESS; +} + +/*=========================================================================== + + FUNCTION WLANBAP_XlateRxDataPkt + + DESCRIPTION + + HDD will call this API when it has received a 802.3 (TL/UMA has + Xlated from 802.11) frame from TL and it wants to form a + BT HCI Data Packet - ready to signal up to the BT stack application. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateRxDataPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here. I don't think this is needed */ + vos_pkt_t *vosDataBuff +) +{ + WLANBAP_8023HeaderType w8023Header; + WLANBAP_HCIACLHeaderType hciACLHeader; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + VOS_STATUS vosStatus; + //v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_U16_t hciDataLength; /* The HCI packet data length*/ + v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // Here, I have to make the assumption that this is an + // 802.3 header followed by an LLC/SNAP packet. + vos_mem_set( &w8023Header, sizeof(w8023Header), 0 ); + vosStatus = vos_pkt_pop_head( vosDataBuff, &w8023Header, sizeof(w8023Header)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop 802.3 header from packet %d", + vosStatus); + + return vosStatus; + } + + // Here, is that LLC/SNAP header. + // With the BT SIG OUI that I am being handed. + vos_mem_set( aucLLCHeader, WLANBAP_LLC_HEADER_LEN, 0 ); + vosStatus = vos_pkt_pop_head( vosDataBuff, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop LLC/SNAP header from packet %d", + vosStatus); + + return vosStatus; + } + +#ifdef BAP_DEBUG + // JEZ081003: Remove this after debugging + // Should I double check that I am getting the BT SIG OUI ? + if ( !(vos_mem_compare( aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER) + - WLANBAP_LLC_OUI_SIZE) /* Don't check the last three bytes here */ + && vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + (v_VOID_t*)WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE))) /* check them here */ + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid LLC header for BT-AMP packet in %s", __func__); + return VOS_STATUS_E_FAULT; + } +#endif //BAP_DEBUG + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + // check if this is a data frame or other, internal to BAP, type... + // we are only handling data frames in here... + // The others (Security and AR) are handled by TLs BAP client API. + // (Verify with TL) + if ( !(vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_DATA + WLANBAP_LLC_PROTO_TYPE_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid (non-data) frame type in %s", __func__); + return VOS_STATUS_E_FAULT; + } + +#ifdef BAP_DEBUG + // JEZ081003: Remove this after debugging + /*------------------------------------------------------------------------ + Sanity check the MAC address in the physical link context + against the value in the incoming Rx Frame. + ------------------------------------------------------------------------*/ + if ( !(vos_mem_compare( w8023Header.vDA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE) + && vos_mem_compare( w8023Header.vSA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "MAC address mismatch in %s", __func__); + return VOS_STATUS_E_FAULT; + } +#endif //BAP_DEBUG + + /* No lookup is needed. Because TL has already told WLANBAP_STARxCB + * the StaId. And I told WLANBAP_STARxCBType the corresponding BSL context + * Which he used to lookup the phy_link_handle value. + */ + + + // Start filling in the HCI header + hciACLHeader.phyLinkHandle = phy_link_handle; + + // Continue filling in the HCI header + //JEZ100913: On Rx the Logical Link is ALWAYS 0. See Vol 2, Sec E, 5.4.2 of spec. + hciACLHeader.logLinkHandle = 0; + hciACLHeader.PBFlag = WLANBAP_HCI_PKT_AMP; + hciACLHeader.BCFlag = 0; + + /* Now the length field is big-endian?! */ + hciDataLength = vos_be16_to_cpu(w8023Header.usLenType); + /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */ + hciDataLength -= WLANBAP_LLC_HEADER_LEN; + /* The HCI packet data length is Little-endian */ + hciACLHeader.dataLength = vos_cpu_to_le16(hciDataLength); + + /* Return the AC here. + * (I can't because there is no way to figure out what it is.) + */ + *pucAC = 0; + + /* Push on the HCI header */ + vos_pkt_push_head(vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); + + return VOS_STATUS_SUCCESS; +} /* WLANBAP_XlateRxDataPkt */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STAFetchPktCB + + DESCRIPTION + The fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STAFetchPktCB +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + v_U8_t ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +) +{ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + ptBtampContext bapContext; /* Holds the btampContext value returned */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + + /* Lookup the BSL and BAP contexts using the StaId */ + + vosStatus = WLANBAP_GetCtxFromStaId ( + *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &bapHdl, /* "handle" to return ptBtampHandle value in */ + &bapContext, /* "handle" to return ptBtampContext value in */ + &pHddHdl); /* "handle" to return BSL context in */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_STAFetchPktCB"); + return VOS_STATUS_E_FAULT; + } + + /* Invoke the callback that BSL registered with me */ + vosStatus = (*bapContext->pfnBtampFetchPktCB)( + pHddHdl, + (WLANTL_ACEnumType) ucAC, /* typecast it for now */ + vosDataBuff, + tlMetaInfo); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Callback registered by BSL failed to fetch pkt in WLANNBAP_STAFetchPktCB"); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +} /* WLANBAP_STAFetchPktCB */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STARxCB + + DESCRIPTION + The receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + rxBufChain pointer to adf_nbuf rx chain + ucSTAId: station id + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STARxCB(v_PVOID_t pvosGCtx, + adf_nbuf_t rxBufChain, + v_U8_t ucSTAId) +{ + + /* TBD */ + return VOS_STATUS_SUCCESS; +} /* WLANBAP_STARxCB */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxCompCB + + DESCRIPTION + The tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxCompCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +) +{ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + ptBtampContext bapContext; /* Holds the btampContext value returned */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_PVOID_t pvlogLinkHandle = NULL; + uintptr_t value; + + WLANBAP_HCIACLHeaderType hciACLHeader; + + /* retrieve the BSL and BAP contexts */ + + /* I don't really know how to do this - in the general case. */ + /* So, for now, I will just use something that works. */ + /* (In general, I will have to keep a list of the outstanding transmit */ + /* buffers, in order to determine which assoc they are with.) */ + //vosStatus = WLANBAP_GetCtxFromStaId ( + // ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + // &bapHdl, /* "handle" to return ptBtampHandle value in */ + // &bapContext, /* "handle" to return ptBtampContext value in */ + // &pHddHdl); /* "handle" to return BSL context in */ + /* Temporarily we do the following*/ + //bapHdl = &btampCtx; + bapHdl = (v_PVOID_t)gpBtampCtx; + /* Typecast the handle into a context. Works as we have only one link*/ + bapContext = ((ptBtampContext) bapHdl); + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid vosDataBuff value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == bapContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid bapContext value in %s", __func__); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAULT; + } + + pHddHdl = bapContext->pHddHdl; + vosStatus = VOS_STATUS_SUCCESS; + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_TxCompCB"); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAULT; + } + + /*Get the logical link handle from the vos user data*/ + vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, + &pvlogLinkHandle); + + value = (uintptr_t)pvlogLinkHandle; + hciACLHeader.logLinkHandle = value; + +#ifdef BAP_DEBUG + /* Trace the bapContext referenced. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: bapContext value = %p in %s:%d. vosDataBuff=%p", bapContext, __func__, __LINE__, vosDataBuff ); +#endif //BAP_DEBUG + + // Sanity check the log_link_handle value +// JEZ100722: Temporary changes. + if (BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + vos_atomic_increment_U32( + &bapContext->btampLogLinkCtx[hciACLHeader.logLinkHandle].uTxPktCompleted); +// &bapContext->btampLogLinkCtx[0].uTxPktCompleted); +// vos_atomic_increment_U32( +// &bapContext->btampLogLinkCtx[1].uTxPktCompleted); + } else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In %s:%d: Invalid logical link handle: %d", __func__, __LINE__, hciACLHeader.logLinkHandle); + } + + /* Invoke the callback that BSL registered with me */ + vosStatus = (*bapContext->pfnBtampTxCompCB)( + pHddHdl, + vosDataBuff, + wTxSTAtus); + + return vosStatus; +} /* WLANBAP_TxCompCB */ + +/*========================================================================== + + FUNCTION WLANBAP_RegisterDataPlane + + DESCRIPTION + The HDD calls this routine to register the "data plane" routines + for Tx, Rx, and Tx complete with BT-AMP. For now, with only one + physical association supported at a time, this COULD be called + by HDD at the same time as WLANBAP_GetNewHndl. But, in general + it needs to be called upon each new physical link establishment. + + This registration is really two part. The routines themselves are + registered here. But, the mapping between the BSL context and the + actual physical link takes place during WLANBAP_PhysicalLinkCreate. + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RegisterDataPlane +( + ptBtampHandle btampHandle, /* BTAMP context */ + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB, + WLANBAP_STARxCBType pfnBtamp_STARxCB, + WLANBAP_TxCompCBType pfnBtampTxCompCB, + // phy_link_handle, of course, doesn't come until much later. At Physical Link create. + v_PVOID_t pHddHdl /* BSL specific context */ +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_RegisterDataPlane"); + return VOS_STATUS_E_FAULT; + } + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + pBtampCtx->pfnBtampFetchPktCB = pfnBtampFetchPktCB; + pBtampCtx->pfnBtamp_STARxCB = pfnBtamp_STARxCB; + pBtampCtx->pfnBtampTxCompCB = pfnBtampTxCompCB; + + // (Right now, there is only one) + pBtampCtx->pHddHdl = pHddHdl; + /* Set the default data transfer mode */ + pBtampCtx->ucDataTrafficMode = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +} /* WLANBAP_RegisterDataPlane */ + + +/*=========================================================================== + + FUNCTION WLANBAP_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. HDD uses this instead of WLANTL_STAPktPending because he is + not aware of the mapping from session to STA ID. + + DEPENDENCIES + + HDD must have called WLANBAP_GetNewHndl before calling this API. + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + BSL can obtain this from the physical handle value in the + downgoing HCI Data Packet. He, after all, was there + when the PhysicalLink was created. He knew the btampHandle + value returned by WLANBAP_GetNewHndl. He knows as well, his + own pHddHdl (see next). + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + ucAc: The access category for the pending frame + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_STAPktPending +( + ptBtampHandle btampHandle, /* Used by BAP to identify the app context and VOSS ctx (!?) */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType ucAc /* This is the first instance of a TL type in bapApi.h */ +) +{ + VOS_STATUS vosStatus; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + v_PVOID_t pvosGCtx; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %p in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_STAPktPending"); + return VOS_STATUS_E_FAULT; + } + + // Retrieve the VOSS context + pvosGCtx = pBtampCtx->pvosGCtx; + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in WLANBAP_STAPktPending"); + return VOS_STATUS_E_FAULT; + } + + + // Let TL know we have a packet to send... + vosStatus = WLANTL_STAPktPending( + pvosGCtx, + ucSTAId, + ucAc); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Tx: Packet rejected by TL in WLANBAP_STAPktPending"); + return vosStatus; + } + pBtampCtx->dataPktPending = VOS_TRUE;//Indication for LinkSupervision module that data is pending + return VOS_STATUS_SUCCESS; +} /* WLANBAP_STAPktPending */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPRegisterBAPCallbacks() + + DESCRIPTION + Register the BAP "Event" callbacks. + Return the per instance handle. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pBapHCIEventCB: pointer to the Event callback + pAppHdl: The context passed in by caller. (I.E., BSL app specific context.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEventCB is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPRegisterBAPCallbacks +( + ptBtampHandle btampHandle, /* BSL uses my handle to talk to me */ + /* Returned from WLANBAP_GetNewHndl() */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpWLAN_BAPEventCB pBapHCIEventCB, /*Implements the callback for ALL asynchronous events. */ + v_PVOID_t pAppHdl // Per-app BSL context +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLAN_BAPRegisterBAPCallbacks"); + return VOS_STATUS_E_FAULT; + } + + // Save the Event callback + pBtampCtx->pBapHCIEventCB = pBapHCIEventCB; + + // (Right now, there is only one) + pBtampCtx->pAppHdl = pAppHdl; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPRegisterBAPCallbacks */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiDebug.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiDebug.c new file mode 100644 index 0000000000000..f3fb5a677eee8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiDebug.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i D e b u g . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Debug functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiDebug.c,v 1.2 2008/11/10 22:37:58 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +// +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/* +Debug Commands +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLoopbackMode() + + DESCRIPTION + Implements the actual HCI Read Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLoopbackMode: pointer to the "HCI Read Loopback Mode". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLoopbackMode or + pBapHCILoopbackMode is NULL. + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pBapHCIReadLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLoopbackMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLoopbackMode() + + DESCRIPTION + Implements the actual HCI Write Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLoopbackMode: pointer to the "HCI Write Loopback Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLoopbackMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pBapHCIWriteLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLoopbackMode */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.c new file mode 100644 index 0000000000000..2335965a2f009 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i E x t . C + + OVERVIEW: + + This software unit holds the implementation of the external interfaces + required by the WLAN BAP module. It is currently a temporary + respository for API routines which should be furnished by CSR + or TL, but aren't yet implemented. + + The functions provide by this module are called by the rest of + the BT-AMP PAL module. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiExt.c,v 1.1 2008/11/21 20:28:18 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-22 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// I think this pulls in everything +#include "bapApiExt.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetCurrentChannel + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + channel: current configured channel number. + activeFlag: flag indicating whether there is an active link. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to return channel is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCurrentChannel +( + ptBtampContext pBtampCtx, + v_U32_t *channel, // return current channel here + v_U32_t *activeFlag // return active flag here +) +{ + //v_U32_t cb_enabled; + tHalHandle halHandle; + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if (( NULL == pBtampCtx ) || (NULL == channel) || (NULL == activeFlag)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + halHandle = VOS_GET_HAL_CB(pBtampCtx->pvosGCtx); + + if(NULL == halHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "halHandle is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if (ccmCfgGetInt(halHandle, WNI_CFG_CURRENT_CHANNEL, channel) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Get CFG failed in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + *activeFlag = FALSE; // return active flag here + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_GetCurrentChannel */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.h new file mode 100644 index 0000000000000..4efd898561380 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiExt.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_API_EXT_H +#define WLAN_QCT_WLANBAP_API_EXT_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external APIs used by the wlan BT-AMP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiExt.h,v 1.1 2008/11/21 20:29:13 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/22/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pick up all the BT-AMP internal definitions +// And underlying supporting types. (Including VOSS, CSR, and...) +#include "bapInternal.h" + +/* Pick up the SIRIUS and HAL types */ +// Already taken care of, above +//#include "sirApi.h" +//#include "halTypes.h" + +/* Pick up the CCM API def'n */ +#include "ccmApi.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary +//#define BAP_DEBUG + +// How do I get BAP context from voss context? +//#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) +// How do I get halHandle from voss context? +//#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_HAL, ctx) + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetCurrentChannel + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + channel: current configured channel number. + activeFlag: flag indicating whether there is an active link. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to return channel is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCurrentChannel +( + ptBtampContext pBtampCtx, + v_U32_t *channel, // return current channel here + v_U32_t *activeFlag // return active flag here +); + + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_API_EXT_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiHCBB.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiHCBB.c new file mode 100644 index 0000000000000..565e9fa2d0a85 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiHCBB.c @@ -0,0 +1,1691 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i H C B B . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Host Controller and Baseband functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/Android/ampBlueZ_6/CORE/BAP/src/bapApiHCBB.c,v 1.7 2011/05/06 00:59:27 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_trace.h" + +// Pick up the sme callback registration API +#include "sme_Api.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + + +/* Host Controller and Baseband Commands */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReset() + + DESCRIPTION + Implements the actual HCI Reset command. + Produces an asynchronous command complete event. Through the + command complete callback. (I.E., (*tpWLAN_BAPEventCB).) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReset +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tHalHandle hHal = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampHandle is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + /* Perform a "reset" */ + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //csrRoamDisconnect(); + /* To avoid sending Disassoc on STA interface */ + if( TRUE == btampContext->isBapSessionOpen ) + { + sme_RoamDisconnect(hHal, + btampContext->sessionId, + // Danlin, where are the richer reason codes? + // I want to be able to convey everything 802.11 supports... + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + + /* Need to reset the timers as well*/ + /* Connection Accept Timer interval*/ + btampContext->bapConnectionAcceptTimerInterval = WLANBAP_CONNECTION_ACCEPT_TIMEOUT; + /* Link Supervision Timer interval*/ + btampContext->bapLinkSupervisionTimerInterval = WLANBAP_LINK_SUPERVISION_TIMEOUT; + /* Logical Link Accept Timer interval*/ + btampContext->bapLogicalLinkAcceptTimerInterval = WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT; + /* Best Effort Flush timer interval*/ + btampContext->bapBEFlushTimerInterval = WLANBAP_BE_FLUSH_TIMEOUT; + + + /* Form and immediately return the command complete event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + bapHCIEvent.u.btampCommandCompleteEvent.present = 1; + bapHCIEvent.u.btampCommandCompleteEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_RESET_CMD; + bapHCIEvent.u.btampCommandCompleteEvent.cc_event.Reset.status + = WLANBAP_STATUS_SUCCESS; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_BAPReset */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMask() + + DESCRIPTION + Implements the actual HCI Set Event Mask command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMask: pointer to the "HCI Set Event Mask" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMask is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMask +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Cmd *pBapHCISetEventMask, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetEventMask */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlush() + + DESCRIPTION + Implements the actual HCI Flush command + Produces an asynchronous command complete event. Through the + event callback. And an asynchronous Flush occurred event. Also through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Flush" Structure. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flush_Cmd *pBapHCIFlush +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Form and immediately return the command complete event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + bapHCIEvent.u.btampCommandCompleteEvent.present = 1; + bapHCIEvent.u.btampCommandCompleteEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_FLUSH_CMD; + bapHCIEvent.u.btampCommandCompleteEvent.cc_event.Flush.status + = WLANBAP_STATUS_SUCCESS; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_BAPFlush */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_EnhancedBAPFlush() + + DESCRIPTION + Implements the actual HCI Enhanced Flush command + Produces an asynchronous command complete event. Through the command status + event callback. And an asynchronous Enhanced Flush Complete event. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Enhanced Flush" Structure. + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_EnhancedBAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Enhanced_Flush_Cmd *pBapHCIFlush, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + /* Form and return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Form and immediately return the command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT; + pBapHCIEvent->u.btampEnhancedFlushCompleteEvent.present = 1; + pBapHCIEvent->u.btampEnhancedFlushCompleteEvent.log_link_handle = + pBapHCIFlush->log_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_EnhancedBAPFlush */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete */ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Connection_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Connection_Accept_TO.connection_accept_timeout + = btampContext->bapConnectionAcceptTimerInterval; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadConnectionAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteConnectionAcceptTimeout: pointer to the "HCI Connection Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pBapHCIWriteConnectionAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteConnectionAcceptTimeout) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the allowed timeout interval range */ + if ((pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout > + WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE) || + (pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout < + WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Out of range for connection accept timeout parameters in %s", + __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Connection_Accept_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the Physical link connection accept timeout value */ + btampContext->bapConnectionAcceptTimerInterval = + pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout; + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Connection_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteConnectionAcceptTimeout */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Read Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + /* Only 8 bits (phy_link_handle) of this log_link_handle are valid. */ + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pBapHCIReadLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadLinkSupervisionTimeout) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the phyiscal link handle extracted from + logical link handle (lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadLinkSupervisionTimeout->log_link_handle; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.link_supervision_timeout + = 0x00; /* Invalid value */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.log_link_handle + = pBapHCIReadLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.link_supervision_timeout + = btampContext->bapLinkSupervisionTimerInterval; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.log_link_handle + = pBapHCIReadLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLinkSupervisionTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Write Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLinkSupervisionTimeout: pointer to the "HCI Link Supervision Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pBapHCIWriteLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLinkSupervisionTimeout) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the phyiscal link handle extracted from + logical link handle (lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.log_link_handle + = pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the LS timeout interval */ + btampContext->bapLinkSupervisionTimerInterval = + pBapHCIWriteLinkSupervisionTimeout->link_supervision_timeout; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.log_link_handle + = pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLinkSupervisionTimeout */ + +/* v3.0 Host Controller and Baseband Commands */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Logical_Link_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout + = btampContext->bapLogicalLinkAcceptTimerInterval; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLogicalLinkAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLogicalLinkAcceptTimeout: pointer to the "HCI Logical Link Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pBapHCIWriteLogicalLinkAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLogicalLinkAcceptTimeout) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the allowed timeout interval range */ + if ((pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout > + WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE) || + (pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout < + WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Out of range for logical connection accept timeout parameters in %s", + __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Logical_Link_Accept_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the Physical link connection accept timeout value */ + btampContext->bapLogicalLinkAcceptTimerInterval = + pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout; + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Logical_Link_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLogicalLinkAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMaskPage2() + + DESCRIPTION + Implements the actual HCI Set Event Mask Page 2 command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMaskPage2: pointer to the "HCI Set Event Mask Page 2" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMaskPage2 is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMaskPage2 +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pBapHCISetEventMaskPage2, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCISetEventMaskPage2) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + /* Save away the event mask */ + vos_mem_copy( + btampContext->event_mask_page_2, + pBapHCISetEventMaskPage2->event_mask_page_2, + 8 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Set_Event_Mask_Page_2.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetEventMaskPage2 */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocationData() + + DESCRIPTION + Implements the actual HCI Read Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocationData +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_domain_aware + = btampContext->btamp_Location_Data_Info.loc_domain_aware; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_options + = btampContext->btamp_Location_Data_Info.loc_options; + + vos_mem_copy( + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_domain, + btampContext->btamp_Location_Data_Info.loc_domain, + 3 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocationData */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLocationData() + + DESCRIPTION + Implements the actual HCI Write Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLocationData: pointer to the "HCI Write Location Data" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLocationData +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Location_Data_Cmd *pBapHCIWriteLocationData, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLocationData) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + btampContext->btamp_Location_Data_Info.loc_domain_aware = + pBapHCIWriteLocationData->loc_domain_aware; + + btampContext->btamp_Location_Data_Info.loc_options = + pBapHCIWriteLocationData->loc_options; + + vos_mem_copy( + btampContext->btamp_Location_Data_Info.loc_domain, + pBapHCIWriteLocationData->loc_domain, + 3 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Location_Data.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLocationData */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFlowControlMode() + + DESCRIPTION + Implements the actual HCI Read Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFlowControlMode +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Flow_Control_Mode.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Flow_Control_Mode.flow_control_mode + = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadFlowControlMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteFlowControlMode() + + DESCRIPTION + Implements the actual HCI Write Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteFlowControlMode: pointer to the "HCI Write Flow Control Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteFlowControlMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pBapHCIWriteFlowControlMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteFlowControlMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Read Best Effort Flush Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + /* The log_link_hanlde identifies which logical link's BE TO*/ + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pBapHCIReadBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadBestEffortFlushTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Write Best Effort Flush TO command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteBEFlushTO: pointer to the "HCI Write BE Flush TO" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pBapHCIWriteBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteBestEffortFlushTimeout */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetShortRangeMode() + + DESCRIPTION + Implements the actual HCI Set Short Range Mode command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIShortRangeMode: pointer to the "HCI Set Short Range Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIShortRangeMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetShortRangeMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pBapHCIShortRangeMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the BAP state to accept the Short Range Mode set request; + SRM set requests are allowed only in CONNECTED state */ + + /* Form and return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD; + + if (CONNECTED != instanceVar->stateVar) + { + /* Short Range Mode request in invalid state */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + return VOS_STATUS_SUCCESS; + } + else if (pBapHCIShortRangeMode->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_NO_CNCT; + return VOS_STATUS_SUCCESS; + } + else if (pBapHCIShortRangeMode->short_range_mode > 0x01) + { + /* Invalid mode requested */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_SUCCESS; + } + + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Send the Command Status event (success) here, since Change Complete is next */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + pBapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Short Range Mode Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT; + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.present = 1; + + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.status = + WLANBAP_STATUS_SUCCESS; /* Assumption for now */ + + /* The input parameters will go out in the CC Event */ + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.phy_link_handle = + pBapHCIShortRangeMode->phy_link_handle; + + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.short_range_mode = + pBapHCIShortRangeMode->short_range_mode; /* Assumption for now */ + + /* If the requested setting is different from the current setting... */ + if (pBapHCIShortRangeMode->short_range_mode != btampContext->phy_link_srm) + { + /* ... then change the SRM according to the requested value. + * If the attempt fails, the assumptions above need to be corrected. + */ + #if 0 + // Suggested API, needs to be created + if (VOS_STATUS_SUCCESS != HALSetShortRangeMode(pBapHCIShortRangeMode->short_range_mode)) + #else + if (0) + #endif + { + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.status = + WLANBAP_ERROR_HARDWARE_FAILURE; + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.short_range_mode = + btampContext->phy_link_srm; /* Switch back to current value */ + } + else + { + /* Update the SRM setting for this physical link, since it worked */ + btampContext->phy_link_srm = pBapHCIShortRangeMode->short_range_mode; + } + } + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetShortRangeMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd0() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 0 (OGF 0x3f, OCF 0x0000). + There is no need for a callback because when this call returns the action has + been completed. + + The command is received when: + - The A2MP Create Phy Link Response has been rx'd by the Bluetooth stack (initiator) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd0 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the BAP state to accept the Vendor Specific Cmd 0: + this is only allowed for the BT_INITIATOR in the CONNECTING state */ + + /* Form and return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0; + + if ( (BT_INITIATOR != btampContext->BAPDeviceRole) || + (CONNECTING != instanceVar->stateVar) ) + { + /* Vendor Specific Command 0 happened in invalid state */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + return VOS_STATUS_SUCCESS; + } + + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority(btampContext, 1); + + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Send the Command Status event (success) here, since Command Complete is next */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + pBapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Vendor Specific Command 0 Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Vendor_Specific_Cmd_0.status + = WLANBAP_STATUS_SUCCESS; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPVendorSpecificCmd0 */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd1() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 1 (OGF 0x3f, OCF 0x0001). + There is no need for a callback because when this call returns the action has + been completed. + + The command is received when: + - HCI wants to enable testability + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd1 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + btampContext->btamp_async_logical_link_create = TRUE; + + + /* Format the Vendor Specific Command 1 Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Vendor_Specific_Cmd_1.status + = WLANBAP_STATUS_SUCCESS; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPVendorSpecificCmd1 */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required in order for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucStaId: station identifier for the requested value + ucTid: identifier of the tspec + status: status of the Flush operation + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_TLFlushCompCallback +( + v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status +) +{ + + return VOS_STATUS_SUCCESS; +} // WLANBAP_TLFlushCompCallback + + +/* End of v3.0 Host Controller and Baseband Commands */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiInfo.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiInfo.c new file mode 100644 index 0000000000000..29b29314cd4cb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiInfo.c @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i I n f o . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Information functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/c/Dropbox/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_PAL/CORE/BAP/src/bapApiInfo.c,v 1.2 2008/11/10 22:55:24 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +#include "sme_Api.h" +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + + +/* Informational Parameters */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalVersionInfo() + + DESCRIPTION + Implements the actual HCI Read Local Version Info command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalVersionInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalVersionInfo +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_HCI_Version + = WLANBAP_HCI_VERSION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_HCI_Revision + = WLANBAP_HCI_REVISION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_PAL_Version + = WLANBAP_PAL_VERSION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_Manufac_Name + = WLANBAP_QUALCOMM_COMPANY_ID; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version + = WLANBAP_PAL_SUBVERSION; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalVersionInfo */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalSupportedCmds() + + DESCRIPTION + Implements the actual HCI Read Local Supported Commands. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalSupportedCmds is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalSupportedCmds +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + v_U8_t supportedCmds[] = WLANBAP_PAL_SUPPORTED_HCI_CMDS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Supported_Cmds.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported commands bitmask */ + vos_mem_copy( + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, + supportedCmds, + sizeof( supportedCmds)); + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalSupportedCmds */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBufferSize() + + DESCRIPTION + Implements the actual HCI Read Buffer Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadBufferSize: pointer to the "HCI Read Buffer Size" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBufferSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBufferSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported Buffer sizes */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_SCO_Packet_Length + = 0; /* Invalid assignment to Uint8, makes 0 */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets + = 16; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets + = 0; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadBufferSize */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadDataBlockSize() + + DESCRIPTION + Implements the actual HCI Read Data Block Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadDataBlockSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadDataBlockSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /* Validate params */ + if ((btampHandle == NULL) || (NULL == pBapHCIEvent)) + { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported Block sizes */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Data_Block_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks + = 16; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadDataBlockSize */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetConfig() + + DESCRIPTION + The function updates some configuration for BAP module in SME during SMEs + close -> open sequence. + + BAP applies the new configuration at the next transaction. + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN + pConfig: a pointer to a caller allocated object of typedef struct WLANBAP_ConfigType. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pConfig or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetConfig +( + ptBtampHandle btampHandle, + WLANBAP_ConfigType *pConfig +) +{ + ptBtampContext btampContext; + /* Validate params */ + if ((NULL == btampHandle)|| (NULL == pConfig)) + { + return VOS_STATUS_E_FAULT; + } + btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + + btampContext->config.ucPreferredChannel = pConfig->ucPreferredChannel; + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPGetMask() + + DESCRIPTION + The function gets the updated event mask from BAP core. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + IN + pEvent_mask_page_2: a pointer to a caller allocated object of 8 bytes. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pEvent_mask_page_2 or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPGetMask( ptBtampHandle btampHandle, + v_U8_t *pEvent_mask_page_2) +{ + ptBtampContext btampContext; + /* Validate params */ + if ((NULL == btampHandle)|| (NULL == pEvent_mask_page_2)) + { + return VOS_STATUS_E_FAULT; + } + btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + + vos_mem_copy( pEvent_mask_page_2, + btampContext->event_mask_page_2, + 8 ); + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPDisconnect() + + DESCRIPTION + The function to request to BAP core to disconnect currecnt AMP connection. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPDisconnect +( + ptBtampHandle btampHandle +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tWLAN_BAPEvent bapEvent; /* State machine event */ + v_U8_t status; /* return the BT-AMP status here */ + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, + "btampHandle is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = NULL; + + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSessionOn() + + DESCRIPTION + The function to check from BAP core if AMP connection is up right now. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +v_BOOL_t WLAN_BAPSessionOn +( + ptBtampHandle btampHandle +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampHandle is NULL in %s", __func__); + + //?? shall we say true or false + return VOS_FALSE; + } + + return btampContext->btamp_session_on; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkCntl.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkCntl.c new file mode 100644 index 0000000000000..7531a017eef80 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkCntl.c @@ -0,0 +1,1936 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i L i n k C n t l . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Link Control functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapApiLinkCntl.c,v 1.1 2010/10/23 23:40:28 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +// Pick up the CSR callback definition +#include "csrApi.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "btampFsm.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pCsrRoamInfo: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +#if 0 +eCSR_ROAM_RESULT_WDS_STARTED +#define eWLAN_BAP_MAC_START_BSS_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + +eCSR_ROAM_RESULT_FAILURE +eCSR_ROAM_RESULT_NOT_ASSOCIATED +#define eWLAN_BAP_MAC_START_FAILS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + +eCSR_ROAM_RESULT_WDS_ASSOCIATED +#define eWLAN_BAP_MAC_CONNECT_COMPLETED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ + + +eCSR_ROAM_RESULT_FAILURE +eCSR_ROAM_RESULT_NOT_ASSOCIATED +#define eWLAN_BAP_MAC_CONNECT_FAILED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + + +eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND +#define eWLAN_BAP_MAC_CONNECT_INDICATION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ + + +eCSR_ROAM_RESULT_KEY_SET +#define eWLAN_BAP_MAC_KEY_SET_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ + + +eCSR_ROAM_RESULT_WDS_DISASSOC_IND +#define eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOC_IND */ + + +eCSR_ROAM_RESULT_WDS_STOPPED +#define eWLAN_BAP_MAC_READY_FOR_CONNECTIONS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ + +#endif //0 + + +eHalStatus +WLANBAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + /* btampContext value */ + ptBtampContext btampContext = (ptBtampContext) pContext; + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t status; /* return the BT-AMP status here */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamStatus = %d", __func__, roamStatus); + + switch (roamStatus) { + //JEZ081110: For testing purposes, with Infra STA as BT STA, this + //actually takes care of the "eCSR_ROAM_RESULT_WDS_STARTED" case, + //below, better than "eCSR_ROAM_RESULT_IBSS_STARTED". + //case eCSR_ROAM_ROAMING_START: + case eCSR_ROAM_ASSOCIATION_START: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_ROAMING_START", roamResult); + // This only gets called when CSR decides to roam on its own - due to lostlink. +#if 0 + if ((pCsrRoamInfo) && (pCsrRoamInfo->pConnectedProfile) && (pCsrRoamInfo->pConnectedProfile->pBssDesc)) + { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pConnectedProfile->pBssDesc->bssId, + sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: willRoam returns\n", __func__); + } +#endif //0 + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_START_BSS_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + case eCSR_ROAM_SET_KEY_COMPLETE: + /* bapRoamCompleteCallback with eCSR_ROAM_SET_KEY_COMPLETE */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_SET_KEY_COMPLETE", roamStatus); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_KEY_SET_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + case eCSR_ROAM_DISASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_DISASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_DISASSOCIATED", roamStatus); + case eCSR_ROAM_LOSTLINK: + /* bapRoamCompleteCallback with eCSR_ROAM_LOSTLINK */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_LOSTLINK", roamStatus); + + if (roamResult != eCSR_ROAM_RESULT_NONE) { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + } + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, unsupported CSR roamStatus = %d", __func__, roamStatus); + + break; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamResult = %d", __func__, roamResult); + + switch (roamResult) { + //JEZ081110: Commented out for testing. Test relies upon IBSS. + case eCSR_ROAM_RESULT_IBSS_STARTED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_STARTED", roamResult); + case eCSR_ROAM_RESULT_WDS_STARTED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_STARTED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_START_BSS_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + //JEZ081110: But I cannot rely upon IBSS for the initial testing. + case eCSR_ROAM_RESULT_FAILURE: + //case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + //case eCSR_ROAM_RESULT_IBSS_START_FAILED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_FAILURE", roamResult); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + break; +#endif + case eCSR_ROAM_RESULT_WDS_START_FAILED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_START_FAILED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_START_FAILED", roamResult); + + /* Fill in the event structure */ + /* I don't think I should signal a eCSR_ROAM_RESULT_FAILURE + * as a eWLAN_BAP_MAC_START_FAILS + */ + bapEvent.event = eWLAN_BAP_MAC_START_FAILS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. This handles both Infra STA and IBSS STA. + case eCSR_ROAM_RESULT_IBSS_CONNECT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT", roamResult); + case eCSR_ROAM_RESULT_ASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_ASSOCIATED", roamResult); + case eCSR_ROAM_RESULT_WDS_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_ASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_COMPLETED; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + //JEZ081110: But I cannot rely upon IBSS for the initial testing. + //case eCSR_ROAM_RESULT_FAILURE: + case eCSR_ROAM_RESULT_IBSS_START_FAILED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_START_FAILED", roamResult); + case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED", roamResult); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + break; +#endif + case eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_FAILED; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: I think I have to check for the bssType to + //differentiate between IBSS Start and IBSS Join success. + //case eCSR_ROAM_RESULT_IBSS_CONNECT: + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT", roamResult); + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + // No longer commented out. + case eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_INDICATION; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* If BAP doesn't like the incoming association, signal SME/CSR */ + if ( status != WLANBAP_STATUS_SUCCESS) + halStatus = eHAL_STATUS_FAILURE; + + break; + + //JEZ081110: Not supported in SME and CSR, yet. +#if 0 + case eCSR_ROAM_RESULT_KEY_SET: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_KEY_SET", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_KEY_SET_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; +#endif //0 + + case eCSR_ROAM_RESULT_DISASSOC_IND: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND", roamResult); + case eCSR_ROAM_RESULT_WDS_DISASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_DISASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE", roamResult); + case eCSR_ROAM_RESULT_WDS_STOPPED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_STOPPED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, unsupported CSR roamResult = %d", __func__, roamResult); + + break; + } + +#if 0 + switch (roamResult) { + case eCSR_ROAM_RESULT_IBSS_CONNECT: + // we have an IBSS connection... + + // update our state + btampContext->mAssociatedStatus = WLANBAP_STATUS_SUCCESS; + btampContext->mAssociated = VOS_TRUE; + // update "assocBssid" with the BSSID of the IBSS + if (pCsrRoamInfo) + memcpy(btampContext->assocBssid, pCsrRoamInfo->peerMacOrBssidForIBSS, 6); + + // We must update the system role to match that of the + // lower layers in case the upper layers decided to try + // joining the network in infrastructure mode if the + // initial join in IBSS mode fails. Andreas Wolf + // (awolf@apple.com) explains the behavior as follows: + // "If the client attempts to join an open network and it fails + // on the first attempt, it reverts back to b-only mode. This + // workaround was specifically put in place to allow the client + // to associate to some third party b-only infrastructure APs. + // It did not take IBSS into account, it seems that the fallback + // always forces infrastructure." + + btampContext->systemRole = eSYSTEM_STA_IN_IBSS_ROLE; + + if (mLinkStatus == 0) + { + // enable the flow of data + DBGLOG("%s: marking link as up in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT"); + mLinkStatus = 1; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkUp); + outputQueue->setCapacity(TRANSMIT_QUEUE_SIZE); + outputQueue->start(); + // Let them know we are ready + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_ASSOC_DONE); + } + else + { + DBGLOG("%s: link is already up in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT"); + } + break; + + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + // we have no more IBSS peers, so disable the flow of data + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE"); + mLinkStatus = (tANI_U8) 0; + // JEZ070627: Revisit ? + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + outputQueue->stop(); + outputQueue->setCapacity(0); + + // update our state + btampContext->mAssociated = false; + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE"); + } + + break; + + case eCSR_ROAM_RESULT_ASSOCIATED: + btampContext->mAssociatedStatus = APPLE80211_STATUS_SUCCESS; + btampContext->mAssociated = true; + + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc)) { + ccpCsrToAppleScanResult(mPMacObject, pCsrRoamInfo->pBssDesc, &scanResult); + + /* Save away the IEs used by the AP */ + ccpCsrToAssocApiedata( mPMacObject, pCsrRoamInfo->pBssDesc, &(btampContext->apiedata)); + + if (BssidChanged((tCsrBssid*) btampContext->assocBssid, (ether_addr*) scanResult.asr_bssid)) { + memcpy(btampContext->assocBssid, scanResult.asr_bssid, 6); + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_BSSID_CHANGED ); + } + } + + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_ASSOC_DONE); + + if (mLinkStatus == 0) + { + mLinkStatus = (tANI_U8) 1; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkUp); + DBGLOG("%s: marking link as up in %s\n", __func__, "eCSR_ROAM_RESULT_ASSOCIATED"); + outputQueue->setCapacity(TRANSMIT_QUEUE_SIZE); + outputQueue->start(); + } + else + { + DBGLOG("%s: link is already up in %s\n", __func__, "eCSR_ROAM_RESULT_ASSOCIATED"); + } + break; + case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNAVAILABLE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED"); + } + break; + + case eCSR_ROAM_RESULT_FAILURE: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNSPECIFIED_FAILURE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_FAILURE"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_FAILURE"); + } + break; + + case eCSR_ROAM_RESULT_DISASSOC_IND: + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND"); + } + + //if (pCsrRoamInfo) // For now, leave this commented out. Until CSR changes integrated. + { + // Now set the reason and status codes. + // Actually, the "result code" field in the tSirSmeDisassocInd should be named reasonCode and NOT statusCode. + // "Reason Codes" are found in DisAssoc or DeAuth Ind. "Status Code" fields are found in Rsp Mgmt Frame. + // For now, we are going to have to (painfully) map the only "result code" type information we have + // available at ALL from LIM/CSR. And that is the statusCode field of type tSirResultCodes + // BTW, tSirResultCodes is the COMPLETELY WRONG TYPE for this "result code" field. It SHOULD be + // of type tSirMacReasonCodes. + // Right now, we don't even have that. So, I have to just make up some "reason code" that I will + // pretend I found in the incoming DisAssoc Indication. + //btampContext->statusCode = ((tpSirSmeDisassocInd) pCallbackInfo)->statusCode; // tSirResultCodes + //btampContext->reasonCode = ((tpSirSmeDisassocInd) pCallbackInfo)->statusCode; // tSirResultCodes + btampContext->reasonCode = (tANI_U16) eSIR_MAC_UNSPEC_FAILURE_REASON; //tANI_U16 // tSirMacReasonCodes + btampContext->deAuthReasonCode = 0; // tANI_U16 // eSIR_SME_DEAUTH_FROM_PEER + // Shouldn't the next line really use a tANI_U16? //0; // tANI_U16 // eSIR_SME_DISASSOC_FROM_PEER + btampContext->disassocReasonCode = btampContext->reasonCode; // tSirMacReasonCodes + // Let's remember the peer who just disassoc'd us + //memcpy(btampContext->peerMacAddr, pCsrRoamInfo->peerMacOrBssidForIBSS, 6); + } + } + break; + + case eCSR_ROAM_RESULT_DEAUTH_IND: + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_DEAUTH_IND"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_DEAUTH_IND"); + } + + //if (pCsrRoamInfo) // For now, leave this commented out. Until CSR changes integrated. + { + // Now set the reason and status codes. + // Actually, the "result code" field in the tSirSmeDeauthInd should be named reasonCode and NOT statusCode. + // "Reason Codes" are found in DisAssoc or DeAuth Ind. "Status Code" fields are found in Rsp Mgmt Frame. + // For now, we are going to have to (painfully) map the only "result code" type information we have + // available at ALL from LIM/CSR. And that is the statusCode field of type tSirResultCodes + // BTW, tSirResultCodes is the COMPLETELY WRONG TYPE for this "result code" field. It SHOULD be + // of type tSirMacReasonCodes. + // Right now, we don't even have that. So, I have to just make up some "reason code" that I will + // pretend I found in the incoming DeAuth Indication. + //btampContext->statusCode = ((tpSirSmeDeauthInd) pCallbackInfo)->statusCode; // tSirResultCodes + //btampContext->reasonCode = ((tpSirSmeDeauthInd) pCallbackInfo)->statusCode; // tSirResultCodes + btampContext->reasonCode = (tANI_U16) eSIR_MAC_UNSPEC_FAILURE_REASON; //tANI_U16 // tSirMacReasonCodes + btampContext->disassocReasonCode = 0; // tANI_U16 // eSIR_SME_DISASSOC_FROM_PEER + // Shouldn't the next line really use a tANI_U16? //0; // tANI_U16 // eSIR_SME_DEAUTH_FROM_PEER + btampContext->deAuthReasonCode = btampContext->reasonCode; // tSirMacReasonCodes + // Let's remember the peer who just de-auth'd us + //memcpy(btampContext->peerMacAddr, ((tpSirSmeDeauthInd) pCallbackInfo)->peerMacAddr, 6); + } + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST: + + //if (eCSR_ROAM_MIC_ERROR_IND == roamStatus) // Make sure + { + if (btampContext->mTKIPCounterMeasures) + { + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_MIC_ERROR_UCAST); + DBGLOG("%s: TKIP Countermeasures in effect in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST"); + } + else + { + DBGLOG("%s: TKIP Countermeasures disabled in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST"); + } + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_GROUP: + + //if (eCSR_ROAM_MIC_ERROR_IND == roamStatus) // Make sure + { + if (btampContext->mTKIPCounterMeasures) + { + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_MIC_ERROR_MCAST); + DBGLOG("%s: TKIP Countermeasures in effect in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_GROUP"); + } + else + { + DBGLOG("%s: TKIP Countermeasures disabled in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_GROUP"); + } + } + break; + + default: + break; + } + switch (roamStatus) { + case eCSR_ROAM_ROAMING_START: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ROAMING_START"); + // This only gets called when CSR decides to roam on its own - due to lostlink. + // Apple still needs to be told. + if ((pCsrRoamInfo) && (pCsrRoamInfo->pConnectedProfile) && (pCsrRoamInfo->pConnectedProfile->pBssDesc)) + { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pConnectedProfile->pBssDesc->bssId, + sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam returns\n", __func__); + } + break; + + case eCSR_ROAM_SHOULD_ROAM: + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc)) { + // pCallbackInfo points to the BSS desc. Convert to Apple Scan Result. + halStatus = ccpCsrToAppleScanResult( + mPMacObject, + pCsrRoamInfo->pBssDesc, + &scanResult); + if ( halStatus != 0 ) + return eHAL_STATUS_FAILURE; + roamAccepted = apple80211Interface->shouldRoam(&scanResult); // Return result is crucial + if (roamAccepted == true) { + // If the roam is acceptable, return SUCCESS + DBGLOG("%s: shouldRoam returns \"acceptable\"\n", __func__); +//#if 0 + // Actually, before returning, immediately signal willRoam + // This is a workaround for a CSR bug. Eventually, when + // eCSR_ROAM_ASSOCIATION_START gets called WITH callback param p1 + // pointing to a tBssDescription, this work-around can be removed. + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pBssDesc->bssId, sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam (called out of order) returns\n", __func__); + DBGLOG(" with BSSID = " MAC_ADDR_STRING(bssid.ether_addr_octet)); +//#endif + return eHAL_STATUS_SUCCESS; + } else { + // If the roam is NOT acceptable, return FAILURE + DBGLOG("%s: shouldRoam returns \"NOT acceptable\"\n", __func__); + return eHAL_STATUS_FAILURE; + } + } + break; + + case eCSR_ROAM_DISASSOCIATED: + //if (eCSR_ROAM_RESULT_FORCED == roamResult || eCSR_ROAM_RESULT_MIC_ERROR == roamResult) + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_DISASSOCIATED"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_DISASSOCIATED"); + } + } + break; + + case eCSR_ROAM_LOSTLINK: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNSPECIFIED_FAILURE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_LOSTLINK"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_LOSTLINK"); + } + break; + + case eCSR_ROAM_ASSOCIATION_START: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ASSOCIATION_START"); +#if 0 + // This is the right place to call willRoam - for an "initial" association. + // But, unfortunately, when eCSR_ROAM_ASSOCIATION_START gets called, + // it doesn't have a pointer to the tBssDescription in the roaming callback + // routines parameter p1 (pCallbackInfo in SetWextState). So, don't use this code, yet. + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc) { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pBssDesc->bssId, 6); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam returns\n", __func__); + DBGLOG(" with BSSID = " MAC_ADDR_STRING(bssid.ether_addr_octet)); + } +#endif //0 + break; + + case eCSR_ROAM_ASSOCIATION_COMPLETION: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ASSOCIATION_COMPLETION"); + break; + + case eCSR_ROAM_MIC_ERROR_IND: // Handled in eCSR_ROAM_RESULT_MIC_ERROR_UNICAST and GROUP, above + case eCSR_ROAM_CANCELLED: + case eCSR_ROAM_ROAMING_COMPLETION: + case eCSR_ROAM_SCAN_FOUND_NEW_BSS: + default: + break; + } +#endif //0 + + return halStatus; +} + +/*---------------------------------------------------------------------------- + Host Controller Interface Procedural API + ---------------------------------------------------------------------------*/ + +/** BT v3.0 Link Control commands */ + +/*---------------------------------------------------------------------------- + Each of the next eight command result in asynchronous events (e.g., + HCI_PHYSICAL_LINK_COMPLETE_EVENT, HCI_LOGICAL_LINK_COMPLETE_EVENT, etc...) + These are signalled thru the event callback. (I.E., (*tpWLAN_BAPEventCB).) + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + WLANBAP_GetNewHndl has to be called before every call to + WLAN_BAPPhysicalLinkCreate. Since the context is per + physical link. + pBapHCIPhysLinkCreate: pointer to the "HCI Create Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + + /* Validate params */ + if ((pBapHCIPhysLinkCreate == NULL) || (NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: btampHandle value: %p, pBapHCIPhysLinkCreate is %p", + __func__, btampHandle, pBapHCIPhysLinkCreate); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + if(DISCONNECTED != instanceVar->stateVar) + { + /* Create/Accept Phy link request in invalid state */ + status = WLANBAP_ERROR_MAX_NUM_CNCTS; + + } + else + { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE; + bapEvent.params = pBapHCIPhysLinkCreate; + //bapEvent.callback = pBapHCIPhysLinkCreateCB; + + /* Allocate a new state machine instance */ + /* There will only ever be one of these (NB: Don't assume this.) */ + /* So for now this returns a pointer to a static structure */ + /* (With all state set to initial values) */ + vosStatus = WLANBAP_CreateNewPhyLinkCtx ( + btampHandle, + pBapHCIPhysLinkCreate->phy_link_handle, /* I get phy_link_handle from the Command */ + pHddHdl, /* BSL passes in its specific context */ + &btampContext, /* Handle to return per assoc btampContext value in */ + BT_INITIATOR); /* BT_INITIATOR */ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + } + + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkCreate */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkAccept: pointer to the "HCI Accept Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + BTAMPFSM_INSTANCEDATA_T *instanceVar; + + /* Validate params */ + if ((pBapHCIPhysLinkAccept == NULL) || (NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: btampHandle value: %p, pBapHCIPhysLinkAccept is %p", + __func__, btampHandle, pBapHCIPhysLinkAccept); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + instanceVar = &(btampContext->bapPhysLinkMachine); + if(DISCONNECTED != instanceVar->stateVar) + { + /* Create/Accept Phy link request in invalid state */ + status = WLANBAP_ERROR_MAX_NUM_CNCTS; + + } + else + { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT; + bapEvent.params = pBapHCIPhysLinkAccept; + //bapEvent.callback = pBapHCIPhysLinkAcceptCB; + + /* Allocate a new state machine instance */ + /* There will only ever be one of these (NB: Don't assume this.) */ + /* So for now this returns a pointer to a static structure */ + /* (With all state set to initial values) */ + vosStatus = WLANBAP_CreateNewPhyLinkCtx ( + btampHandle, + pBapHCIPhysLinkAccept->phy_link_handle, /* I get phy_link_handle from the Command */ + pHddHdl, /* BSL passes in its specific context */ + &btampContext, /* Handle to return per assoc btampContext value in */ + BT_RESPONDER); /* BT_RESPONDER */ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + } + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkAccept */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkDisconnect: pointer to the "HCI Disconnect Physical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pBapHCIPhysLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + + /* Validate params */ + if (pBapHCIPhysLinkDisconnect == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the Physical link handle */ + if (pBapHCIPhysLinkDisconnect->phy_link_handle != btampContext->phy_link_handle) + { + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD; + return VOS_STATUS_SUCCESS; + } + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT; + bapEvent.params = pBapHCIPhysLinkDisconnect; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pBapHCIPhysLinkDisconnect; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkDisconnect */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCreate: pointer to the "HCI Create Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Logical_Link_Cmd *pBapHCILogLinkCreate, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U16_t log_link_index = 0; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + VOS_STATUS retval; + v_U16_t index_for_logLinkCtx = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCILogLinkCreate == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the BAP state to accept the logical link request + Logical Link create/accept requests are allowed only in + CONNECTED state */ + /* Form and immediately return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD; + + retval = VOS_STATUS_E_FAILURE; + if(DISCONNECTED == instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + + } + else if (CONNECTED != instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_CMND_DISALLOWED; + } + else if (pBapHCILogLinkCreate->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkInProgress; + + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_NO_CNCT; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* If btamp_async_logical_link_create is set, we will seralize the req + on MC thread & handle it there after; If the above flag is not set + respond to HCI the sync way as before */ + if(FALSE == btampContext->btamp_async_logical_link_create) + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + pBapHCILogLinkCreate->phy_link_handle, /* I get phy_link_handle from the Command */ + pBapHCILogLinkCreate->tx_flow_spec, /* I get tx_flow_spec from the Command */ + pBapHCILogLinkCreate->rx_flow_spec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + retval = VOS_STATUS_SUCCESS; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + else + { + btampContext->btamp_logical_link_req_info.phyLinkHandle = + pBapHCILogLinkCreate->phy_link_handle; + vos_mem_copy(btampContext->btamp_logical_link_req_info.txFlowSpec, + pBapHCILogLinkCreate->tx_flow_spec, 18); + vos_mem_copy(btampContext->btamp_logical_link_req_info.rxFlowSpec, + pBapHCILogLinkCreate->rx_flow_spec, 18); + btampContext->btamp_async_logical_link_create = FALSE; + vosStatus = btampEstablishLogLink(btampContext); + if(VOS_STATUS_SUCCESS == vosStatus) + { + retval = VOS_STATUS_E_BUSY;//this will make sure event complete is not sent to HCI + } + else + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + } + } + } + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + index_for_logLinkCtx = log_link_index >> 8; + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.present = 1; + + /* Return the logical link index here */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.phy_link_handle + = pBapHCILogLinkCreate->phy_link_handle; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + /* ... */ + + return retval; +} /* WLAN_BAPLogicalLinkCreate */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkAccept: pointer to the "HCI Accept Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pBapHCILogLinkAccept, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U16_t log_link_index = 0; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + VOS_STATUS retval; + v_U16_t index_for_logLinkCtx; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCILogLinkAccept == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the BAP state to accept the logical link request + Logical Link create/accept requests are allowed only in + CONNECTED state */ + /* Form and immediately return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD; + + retval = VOS_STATUS_E_FAILURE; + if(DISCONNECTED == instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + + } + else if (CONNECTED != instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_CMND_DISALLOWED; + } + else if (pBapHCILogLinkAccept->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkInProgress; + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_NO_CNCT; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* If btamp_async_logical_link_create is set, we will seralize the req + on MC thread & handle it there after; If the above flag is not set + respond to HCI the sync way as before */ + if(FALSE == btampContext->btamp_async_logical_link_create) + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + pBapHCILogLinkAccept->phy_link_handle, /* I get phy_link_handle from the Command */ + pBapHCILogLinkAccept->tx_flow_spec, /* I get tx_flow_spec from the Command */ + pBapHCILogLinkAccept->rx_flow_spec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + retval = VOS_STATUS_SUCCESS; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + else + { + btampContext->btamp_logical_link_req_info.phyLinkHandle = + pBapHCILogLinkAccept->phy_link_handle; + vos_mem_copy(btampContext->btamp_logical_link_req_info.txFlowSpec, + pBapHCILogLinkAccept->tx_flow_spec, 18); + vos_mem_copy(btampContext->btamp_logical_link_req_info.rxFlowSpec, + pBapHCILogLinkAccept->rx_flow_spec, 18); + btampContext->btamp_async_logical_link_create = FALSE; + vosStatus = btampEstablishLogLink(btampContext); + if(VOS_STATUS_SUCCESS == vosStatus) + { + retval = VOS_STATUS_E_BUSY;//this will make sure event complete is not sent to HCI + } + else + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + } + } + } + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + index_for_logLinkCtx = log_link_index >> 8; + + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.present = 1; + /* Return the logical link index here */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.phy_link_handle + = pBapHCILogLinkAccept->phy_link_handle; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + /* ... */ + + return retval; +} /* WLAN_BAPLogicalLinkAccept */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkDisconnect: pointer to the "HCI Disconnect Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pBapHCILogLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tpBtampLogLinkCtx pLogLinkContext; + VOS_STATUS retval = VOS_STATUS_SUCCESS; + v_U8_t log_link_index; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pBapHCILogLinkDisconnect ) || + ( NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Critical error: Invalid input parameter on %s", + __func__); + return VOS_STATUS_E_FAULT; + } + + /* Derive logical link index from handle */ + log_link_index = ((pBapHCILogLinkDisconnect->log_link_handle) >> 8); + + if( log_link_index >= WLANBAP_MAX_LOG_LINKS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Critical error: Invalid input parameter on %s", + __func__); + /* Fill in the event code to propagate the event notification to BRM + BRM generates the Command status Event based on this.*/ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_E_INVAL; + + } + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: btampContext value = %p in %s:%d", btampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD; + + /*------------------------------------------------------------------------ + FIXME: Validate the Logical Link handle, Generation and freeing... + Here the Logical link is not validated and assumed that it is correct to. + get the Logical link context. . + ------------------------------------------------------------------------*/ + pLogLinkContext = + &(btampContext->btampLogLinkCtx[log_link_index]); + + // Validate whether the context is active. + if ((VOS_FALSE == pLogLinkContext->present) || + (pBapHCILogLinkDisconnect->log_link_handle != pLogLinkContext->log_link_handle)) + { + /* If status is failed, the platform specific layer generates the + command status event with proper status */ + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + retval = VOS_STATUS_E_FAILURE; +#ifdef BAP_DEBUG + /* Log the error. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s:%d Invalid Logical Link handle(should be) = %d(%d)", __func__, __LINE__, + pBapHCILogLinkDisconnect->log_link_handle, pLogLinkContext->log_link_handle); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " Logical Link index = %d", log_link_index); +#endif //BAP_DEBUG + } + else + { + /* Form and return the command status event... */ + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status + = WLANBAP_STATUS_SUCCESS; + + + pLogLinkContext->present = VOS_FALSE; + pLogLinkContext->uTxPktCompleted = 0; + pLogLinkContext->log_link_handle = 0; + /* Decrement the total logical link count */ + btampContext->total_log_link_index--; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + /* Notify the Command status Event */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + /* Return the logical link index here */ + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.log_link_handle + = pBapHCILogLinkDisconnect->log_link_handle; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.reason + = WLANBAP_ERROR_TERM_BY_LOCAL_HOST; + + return retval; +} /* WLAN_BAPLogicalLinkDisconnect */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCancel() + + DESCRIPTION + Implements the actual HCI Cancel Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCancel: pointer to the "HCI Cancel Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + (BTW, the required "HCI Logical Link Complete Event" + will be generated by the BAP state machine and sent up + via the (*tpWLAN_BAPEventCB).) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCancel is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCancel +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pBapHCILogLinkCancel, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext; + BTAMPFSM_INSTANCEDATA_T *instanceVar; + /* Validate params */ + if ((btampHandle == NULL) || (pBapHCILogLinkCancel == NULL) || + (pBapHCIEvent == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + instanceVar = &(btampContext->bapPhysLinkMachine); + + /* Form and immediately return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode = + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + + if (pBapHCILogLinkCancel->phy_link_handle != btampContext->phy_link_handle) + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + else + { + /* As the logical link create is returned immediately, the logical link is + created and so cancel can not return success. + And it returns WLANBAP_ERROR_NO_CNCT if not connected or + WLANBAP_ERROR_MAX_NUM_ACL_CNCTS if connected */ + if(WLAN_BAPLogLinkClosed == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in invalid state */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + else if(WLAN_BAPLogLinkOpen == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in conected state */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_MAX_NUM_ACL_CNCTS; + } + else if(WLAN_BAPLogLinkInProgress == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in progress state, need to fail logical link + creation as well */ + btampContext->btamp_logical_link_cancel_pending = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_STATUS_SUCCESS; + } + else + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + } + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.phy_link_handle = + pBapHCILogLinkCancel->phy_link_handle; + /* Since the status is not success, the Tx flow spec Id is not meaningful and + filling with 0 */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.tx_flow_spec_id = + pBapHCILogLinkCancel->tx_flow_spec_id; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPLogicalLinkCancel */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlowSpecModify() + + DESCRIPTION + Implements the actual HCI Modify Logical Link command + Produces an asynchronous flow spec modify complete event. Through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlowSpecModify: pointer to the "HCI Flow Spec Modify" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlowSpecModify is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlowSpecModify +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pBapHCIFlowSpecModify, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + v_U16_t index_for_logLinkHandle = 0; + ptBtampContext btampContext; + tpBtampLogLinkCtx pLogLinkContext; + v_U32_t retval; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Validate params */ + if ((btampHandle == NULL) || (pBapHCIFlowSpecModify == NULL) || + (pBapHCIEvent == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + index_for_logLinkHandle = pBapHCIFlowSpecModify->log_link_handle >> 8; /* Return the logical link index here */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " %s:index_for_logLinkHandle=%d", __func__,index_for_logLinkHandle); + + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD; + + /*------------------------------------------------------------------------ + Evaluate the Tx and Rx Flow specification for this logical link. + ------------------------------------------------------------------------*/ + // Currently we only support flow specs with service types of BE (0x01) + + /*------------------------------------------------------------------------ + Now configure the Logical Link context. + ------------------------------------------------------------------------*/ + pLogLinkContext = &(btampContext->btampLogLinkCtx[index_for_logLinkHandle]); + + /* Extract Tx flow spec into the context structure */ + retval = btampUnpackTlvFlow_Spec((void *)btampContext, pBapHCIFlowSpecModify->tx_flow_spec, + WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN, + &pLogLinkContext->btampFlowSpec); + if (retval != BTAMP_PARSE_SUCCESS) + { + /* Flow spec parsing failed, return failure */ + vosStatus = VOS_STATUS_E_FAILURE; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.status + = WLANBAP_STATUS_SUCCESS; + + } + /* Notify the Command status Event */ + vosStatus = + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + /* Form and immediately return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.present = 1; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.log_link_handle = + pBapHCIFlowSpecModify->log_link_handle; + + return vosStatus; +} /* WLAN_BAPFlowSpecModify */ + + +void WLAN_BAPEstablishLogicalLink(ptBtampContext btampContext) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U16_t log_link_index = 0; + v_U16_t index_for_logLinkCtx = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (btampContext == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return; + } + + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + btampContext->btamp_logical_link_req_info.phyLinkHandle, /* I get phy_link_handle from the Command */ + btampContext->btamp_logical_link_req_info.txFlowSpec, /* I get tx_flow_spec from the Command */ + btampContext->btamp_logical_link_req_info.rxFlowSpec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + bapHCIEvent.u.btampLogicalLinkCompleteEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + bapHCIEvent.u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + + index_for_logLinkCtx = log_link_index >> 8; + /* Format the Logical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.present = 1; + + /* Return the logical link index here */ + bapHCIEvent.u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.phy_link_handle + = btampContext->btamp_logical_link_req_info.phyLinkHandle; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkSupervision.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkSupervision.c new file mode 100644 index 0000000000000..4425e2fcd06d4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiLinkSupervision.c @@ -0,0 +1,631 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i LinkSupervision . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + "platform independent" Data path functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-03-25 arulv Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "bapApiTimer.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +#if 1 +//*BT-AMP packet LLC OUI value*/ +static const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +/*LLC header value*/ +static v_U8_t WLANBAP_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; +#endif + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_AcquireLSPacket( ptBtampContext pBtampCtx, vos_pkt_t **ppPacket, v_U16_t size, tANI_BOOLEAN isLsReq ) +{ + VOS_STATUS vosStatus; + vos_pkt_t *pPacket = NULL; + WLANBAP_8023HeaderType w8023Header; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + v_U16_t headerLength; /* The 802.3 frame length*/ + v_U16_t protoType; + v_U8_t *pData = NULL; + + + if(isLsReq) + { + protoType = WLANTL_BT_AMP_TYPE_LS_REQ; + } + else + { + protoType = WLANTL_BT_AMP_TYPE_LS_REP; + } + + //If success, vosTxLsPacket is the packet and pData points to the head. + vosStatus = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT,size, 1, + VOS_TRUE, NULL, NULL ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + vosStatus = vos_pkt_reserve_head( pPacket, (v_VOID_t *)&pData, size ); + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: failed to reserve size = %d\n",__func__, size ); + vos_pkt_return_packet( pPacket ); + } + } + + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_LinkSupervisionTimerHandler failed to get vos_pkt\n" ); + return vosStatus; + } + + // Form the 802.3 header + vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); + + headerLength = WLANBAP_LLC_HEADER_LEN; + /* Now the 802.3 length field is big-endian?! */ + w8023Header.usLenType = vos_cpu_to_be16(headerLength); + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + /* Now form the LLC header */ + vos_mem_copy(aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER)); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_LS_REQ + WLANBAP_LLC_PROTO_TYPE_SIZE); + + /* Push on the LLC header */ + vos_pkt_push_head(pPacket, + aucLLCHeader, + WLANBAP_LLC_HEADER_LEN); + + /* Push on the 802.3 header */ + vos_pkt_push_head(pPacket, &w8023Header, sizeof(w8023Header)); + *ppPacket = pPacket; + return vosStatus; +} + + + +/*=========================================================================== + + FUNCTION WLANBAP_InitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be initialized when connected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +#define TX_LS_DATALEN 32 + +VOS_STATUS +WLANBAP_InitLinkSupervision +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + vos_pkt_t *pLSReqPacket; + vos_pkt_t *pLSRepPacket; + v_U16_t lsPktln; + + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + +#if 0 + /* Initialize Link supervision data structure */ + vos_mem_set(pLsInfo, sizeof(tBtampLS),0); + + /* Allocate memory for Static Tx Data */ + pLsInfo->pTxPktData = vos_mem_malloc(sizeof(tBtampLsPktData)+TX_LS_DATALEN); + + /* Initialize Static data for LS pkt Tx */ + pLsInfo->pTxPktData->BufLen = TX_LS_DATALEN; + vos_mem_copy (&pLsInfo->pTxPktData->pBuf, LsTxData, pLsInfo->pTxPktData->BufLen); +#endif + pBtampCtx->lsReqPktPending = VOS_FALSE; + pBtampCtx->retries = 0; + + vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSReqPacket,32, TRUE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + pBtampCtx->lsReqPacket = pLSReqPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + pBtampCtx->lsReqPacket = NULL; + return vosStatus; + } + + vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSRepPacket,32,FALSE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + pBtampCtx->lsRepPacket = pLSRepPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + pBtampCtx->lsRepPacket = NULL; + return vosStatus; + } + + vosStatus = vos_pkt_get_packet_length(pBtampCtx->lsRepPacket,&lsPktln); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:vos_pkt_get_length error",__func__); + return VOS_STATUS_E_FAULT; + } + pBtampCtx->lsPktln = lsPktln; + + /* Start Link Supervision Timer if not configured for infinite */ + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:No LS configured for infinite",__func__); + } + + return vosStatus; +} + +/*=========================================================================== + + FUNCTION WLANBAP_DeInitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be stopped after disconnected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeInitLinkSupervision +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In: %s", __func__); + + vosStatus = WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + + + /*Free the vos packet*/ + if ( pBtampCtx->lsRepPacket ) + { + vosStatus = vos_pkt_return_packet(pBtampCtx->lsRepPacket); + pBtampCtx->lsRepPacket = NULL; + } + + if ( pBtampCtx->lsReqPacket ) + { + vosStatus = vos_pkt_return_packet(pBtampCtx->lsReqPacket); + pBtampCtx->lsReqPacket = NULL; + } + + + return vosStatus; +} + +/*=========================================================================== + + FUNCTION WLANBAP_RxProcLsPkt + + DESCRIPTION + + This API will be called when Link Supervision frames are received at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RxProcLsPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + v_U16_t RxProtoType, /* Protocol Type from the frame received */ + vos_pkt_t *vosRxLsBuff +) +{ + VOS_STATUS vosStatus; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + WLANBAP_8023HeaderType w8023Header; + v_SIZE_t HeaderLen = sizeof(w8023Header); + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In %s Received RxProtoType=%x", __func__,RxProtoType); + + vos_pkt_extract_data(vosRxLsBuff,0,(v_VOID_t*)&w8023Header,&HeaderLen); + if ( !(vos_mem_compare( w8023Header.vDA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE) + && vos_mem_compare( w8023Header.vSA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "MAC address mismatch in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Free the vos packet*/ + vosStatus = vos_pkt_return_packet( vosRxLsBuff ); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Failed to free VOS packet in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + /* Reset Link Supervision timer */ + if (RxProtoType == WLANTL_BT_AMP_TYPE_LS_REP) + { + pBtampCtx->lsReqPktPending = FALSE; + pBtampCtx->retries = 0; + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + } + else if(RxProtoType == WLANTL_BT_AMP_TYPE_LS_REQ) + { + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + pBtampCtx->pPacket = pBtampCtx->lsRepPacket; + // Handle LS rep frame + vosStatus = WLANBAP_TxLinkSupervision( btampHandle, phy_link_handle, pBtampCtx->pPacket, WLANTL_BT_AMP_TYPE_LS_REP); + } + + return vosStatus; + +} + +/* Tx callback function for LS packet */ +static VOS_STATUS WLANBAP_TxLinkSupervisionCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + VOS_STATUS retStatus +) +{ + VOS_STATUS vosStatus; + ptBtampContext bapContext; /* Holds the btampContext value returned */ + vos_pkt_t *pLSPacket; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "TxCompCB reached for LS Pkt"); + + /* Get the BT AMP context from the global */ + bapContext = gpBtampCtx; + + if (!VOS_IS_STATUS_SUCCESS (retStatus)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "TxCompCB:Transmit status Failure"); + } + + if ( pPacket == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_TxCompCB bad input\n" ); + return VOS_STATUS_E_FAILURE; + } + + + /* Return the packet & reallocate */ + + if( pPacket == bapContext->lsReqPacket ) + { + vosStatus = WLANBAP_AcquireLSPacket( bapContext, &pLSPacket,32, TRUE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + bapContext->lsReqPacket = pLSPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + bapContext->lsReqPacket = NULL; + return vosStatus; + } + } + else + { + vosStatus = WLANBAP_AcquireLSPacket( bapContext, &pLSPacket,32, FALSE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + bapContext->lsRepPacket = pLSPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + bapContext->lsRepPacket = NULL; + return vosStatus; + } + } + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:Returned Vos Packet:%p\n", __func__, pPacket ); + + vos_pkt_return_packet( pPacket ); + + return (VOS_STATUS_SUCCESS ); +} + +/*=========================================================================== + + FUNCTION WLANBAP_TxLinkSupervision + + DESCRIPTION + + This API will be called to process Link Supervision Request received + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_TxLinkSupervision +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + vos_pkt_t *pPacket, + v_U16_t protoType +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)btampHandle; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + v_PVOID_t pvosGCtx; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + WLANTL_MetaInfoType metaInfo; + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In : %s protoType=%x", __func__,protoType); + + // Retrieve the VOSS context + pvosGCtx = pBtampCtx->pvosGCtx; + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to retrieve STA Id from BAP context and phy_link_handle in WLANBAP_TxLinKSupervisionReq"); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero( &metaInfo, sizeof( WLANTL_MetaInfoType ) ); + + metaInfo.ucTID = 0x00 ; + metaInfo.ucUP = 0x00; + metaInfo.ucIsEapol = VOS_FALSE;//Notify TL that this is NOT an EAPOL frame + metaInfo.ucDisableFrmXtl = VOS_FALSE; + metaInfo.ucType = 0x00; + pBtampCtx->metaInfo = metaInfo; + + vosStatus = WLANTL_TxBAPFrm( pvosGCtx, pPacket, &metaInfo, WLANBAP_TxLinkSupervisionCB ); + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Tx: Packet rejected by TL in WLANBAP_TxLinkSupervisionReq"); + return vosStatus; + } + + if(protoType == WLANTL_BT_AMP_TYPE_LS_REQ) + { + pBtampCtx->lsReqPktPending = TRUE; + pBtampCtx->retries++; + } + + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_TxLinkSupervisionReq failed to Start LinkSupervision Timer\n" ); + return vosStatus; + } + + return vosStatus; +} /* WLANBAP_RxLinkSupervisionReq */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiStatus.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiStatus.c new file mode 100644 index 0000000000000..7fdf1dfc5b876 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiStatus.c @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i S t a t u s . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Status functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/src/bapApiStatus.c,v 1.7 2009/03/09 08:45:04 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/* +Status Parameters +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Read Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadFailedContactCounter: pointer to the "HCI Read Failed Contact Counter" structure. + pFailedContactCounter: pointer to return value for the "Failed Contact Counter" + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFailedContactCounter or + pFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pBapHCIReadFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadFailedContactCounter */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPResetFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Reset Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIResetFailedContactCounter: pointer to the "HCI Reset Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIResetFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPResetFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pBapHCIResetFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPResetFailedContactCounter */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkQuality() + + DESCRIPTION + Implements the actual HCI Read Link Quality command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLinkQuality: pointer to the "HCI Read Link Quality" structure. + pBapHCILinkQuality: pointer to return value for the "Link Quality" + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkQuality or + pBapHCILinkQuality is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkQuality +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Link_Quality_Cmd *pBapHCIReadLinkQuality, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadLinkQuality) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the physical link handle extracted from + input parameter. This parameter has 2 bytes for physical handle + (only lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadLinkQuality->log_link_handle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.log_link_handle + = phyLinkHandle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.link_quality = 0; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Get the Link quality indication status from control block. + Link quality value is being updated on the SME callback */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.link_quality + = btampContext->link_quality; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLinkQuality */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadRSSI() + + DESCRIPTION + Implements the actual HCI Read RSSI command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + pBapHCIRSSI: pointer to return value for the "RSSI". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadRSSI or + pBapHCIRSSI is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadRSSI +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_RSSI_Cmd *pBapHCIReadRSSI, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadRSSI) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the physical link handle extracted from + input parameter. This parameter has 2 bytes for physical handle + (only lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadRSSI->log_link_handle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.phy_link_handle + = phyLinkHandle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.rssi = 0; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Get the RSSI value for this station (physical link) */ + vosStatus = WLANTL_GetRssi(btampContext->pvosGCtx, btampContext->ucSTAId, + &pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.rssi,NULL); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* GetRssi success, indicate the to upper layer */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_STATUS_SUCCESS; + } + else + { + /* API failed, indicate unspecified error to upper layer */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_ERROR_UNSPECIFIED_ERROR; + } + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_RSSI_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadRSSI */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPInfo() + + DESCRIPTION + Implements the actual HCI Read Local AMP Information command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPInfo: pointer to the "HCI Read Local AMP Info" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPInfo or + pBapHCILocalAMPInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPInfo +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pBapHCIReadLocalAMPInfo, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCIReadLocalAMPInfo == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_AMP_Status + = WLANBAP_HCI_AMP_STATUS_NOT_SHARED; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Total_BW + = 24000; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW + = 12000; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Min_Latency + = 100; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Controller_Type + = 1; +#if 0 +AMP Info PAL_Capabilities: Size: 2 Octets + +Value Parameter Description +0xXXXX Bit 0: "Service Type = Guaranteed" is not supported by PAL = 0 + "Service Type = Guaranteed" is supported by PAL = 1 + Bits 15-1: Reserved (shall be set to 0) + (See EFS in Generic AMP FIPD [1]) +#endif //0 + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities + = 0x00; // was 0x03. Completely wrong. + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length + = 248; + //= 40; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout + = 10000; //10; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout + = 10000; //8; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalAMPInfo */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPAssoc() + + DESCRIPTION + Implements the actual HCI Read Local AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPAssoc: pointer to the "HCI Read Local AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPAssoc + (or pBapHCILocalAMPAssoc) is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pBapHCIReadLocalAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + tHalHandle hHal; + tBtampAMP_ASSOC btamp_ASSOC; + v_U32_t nConsumed = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if ((pBapHCIReadLocalAMPAssoc == NULL) || (NULL == btampHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, phy_link_handle = %d", __func__, + pBapHCIReadLocalAMPAssoc->phy_link_handle); + + /* Update the MAC address and SSID if in case the Read Local AMP Assoc + * Request is made before Create Physical Link creation. + */ + WLANBAP_ReadMacConfig (btampContext); + + /* Fill in the contents of an AMP_Assoc structure in preparation + * for Packing it into the AMP_assoc_fragment field of the Read + * Local AMP Assoc Command Complete Event + */ + /* Return the local MAC address */ + btamp_ASSOC.AMP_Assoc_MAC_Addr.present = 1; + vos_mem_copy( + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + btampContext->self_mac_addr, + sizeof(btampContext->self_mac_addr)); + + /*Save the local AMP assoc info*/ + vos_mem_copy(btampContext->btamp_AMP_Assoc.HC_mac_addr, + btampContext->self_mac_addr, + sizeof(btampContext->self_mac_addr)); + + + /* JEZ090303: This logic should return a single channel list with the */ + /* selected channel, if we have one. */ + //if (btampContext->channel) + if (1) + { + /* Return the local Preferred Channel List */ + /* Return both the Regulatory Info and one channel list */ + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present = 1; + memcpy (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, "XXX", 3); + /*Save the local AMP assoc info*/ + vos_mem_copy(btampContext->btamp_AMP_Assoc.HC_pref_country, "XXX", 3); + + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets = 2; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2] = 0; + + if (( BT_INITIATOR == btampContext->BAPDeviceRole ) && + ( 0 != btampContext->channel )) + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = btampContext->channel; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = 0x01; //we are AP - we start on their 1st preferred channel + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2] = 0x11; + } + else + { + if (btampContext->config.ucPreferredChannel) + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = btampContext->config.ucPreferredChannel; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = + 0x0B - btampContext->config.ucPreferredChannel + 1; + } + else + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = 0x01; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = 0x0B; //all channels for 1 to 11 + } + + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2] = 0x11; + } + } else + { + /* Return the local Preferred Channel List */ + /* Return only the Regulatory Info */ + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present = 1; + memcpy (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, "XXX", 3); + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets = 1; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2] = 0; + + } + + /*Save the local AMP assoc info*/ + btampContext->btamp_AMP_Assoc.HC_pref_num_triplets = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][0] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][1] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][2] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][2] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2]; + + /* Also, at this point, lie and tell the other side we are connected on */ + /* the one channel we support. I hope this convinces the peer as BT-AMP AP */ + /* We really want him to use our channel. Since we only support one.*/ + /* Return the local Connected Channel */ + btamp_ASSOC.AMP_Assoc_Connected_Channel.present = 1; + memcpy (btamp_ASSOC.AMP_Assoc_Connected_Channel.country, "XXX", 3); + btamp_ASSOC.AMP_Assoc_Connected_Channel.num_triplets = 2; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][2] = 0; + //btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][0] = 0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][0] = (0 != btampContext->channel)?btampContext->channel:0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][1] = 0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][2] = 0x11; + + + /* Return the local PAL Capabilities */ + btamp_ASSOC.AMP_Assoc_PAL_Capabilities.present = 1; + +#if 0 +AMP ASSOC Pal Capabilities: Size: 4 Octets + + Value Description + 4 TypeID for 802.11 PAL Capabilities + + 4 Length + + 0xXXXXXXXX Bit 0: + 0 signifies the PAL is not capable of utilizing + received Activity Reports + 1 signifies the PAL is capable of utilizing + received Activity Reports + Bit 1: + 0 signifies the PAL is not capable of utilizing + scheduling information sent in an Activity Report + 1 signifies the PAL is capable of utilizing + scheduling information sent in an Activity Report + Bits 2..31 Reserved + +#endif //0 + + btamp_ASSOC.AMP_Assoc_PAL_Capabilities.pal_capabilities +// = btampContext->btamp_Remote_AMP_Assoc.HC_pal_capabilities; + //= 0x03; + = 0x00; + + /* Return the local PAL Version */ + btamp_ASSOC.AMP_Assoc_PAL_Version.present = 1; + + /* Return the version and company ID data */ + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_version = WLANBAP_PAL_VERSION; + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_CompanyID = WLANBAP_QUALCOMM_COMPANY_ID; // Qualcomm Company ID + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_subversion = WLANBAP_PAL_SUBVERSION; + + //Pack the AMP Assoc structure + vosStatus = btampPackAMP_ASSOC( + hHal, + &btamp_ASSOC, + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment, + 248, + &nConsumed); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: nConsumed value: %d", __func__, nConsumed); + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD; + /*Validate the Physical handle*/ + if(pBapHCIReadLocalAMPAssoc->phy_link_handle != + btampContext->phy_link_handle) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Wrong Physical Link handle in Read Local AMP Assoc cmd: current: %x, new: %x", __func__, + btampContext->phy_link_handle, + pBapHCIReadLocalAMPAssoc->phy_link_handle); + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.status + = WLANBAP_ERROR_NO_CNCT; + } else + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle + = pBapHCIReadLocalAMPAssoc->phy_link_handle; + /* We will fit in one fragment, so remaining is exactly equal to encoded size*/ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.remaining_length + = nConsumed; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalAMPAssoc */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteRemoteAMPAssoc() + + DESCRIPTION + Implements the actual HCI Write Remote AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteRemoteAMPAssoc: pointer to the "HCI Write Remote AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteRemoteAMPAssoc is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteRemoteAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; + + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + + /* Validate params */ + if (pBapHCIWriteRemoteAMPAssoc == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC; + bapEvent.params = pBapHCIWriteRemoteAMPAssoc; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Remote_AMP_Assoc.status + = status; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Remote_AMP_Assoc.phy_link_handle + = pBapHCIWriteRemoteAMPAssoc->phy_link_handle; + + if(WLANBAP_ERROR_NO_SUITABLE_CHANNEL == status) + { + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = 0; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteRemoteAMPAssoc */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.c new file mode 100644 index 0000000000000..bc234b1dbfdf1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i T i m e r . C + + OVERVIEW: + + This software unit holds the implementation of the timer routines + required by the WLAN BAP module. + + The functions provide by this module are called by the rest of + the BT-AMP PAL module. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/btamp-label9/CORE/BAP/src/bapApiTimer.c,v 1.5 2010/09/04 00:14:37 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-23 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// I think this pulls in everything +#include "vos_types.h" +#include "bapApiTimer.h" + +//#define BAP_DEBUG + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WLAN_BAP_TX_PKT_MONITOR_TIME 100 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +#if 1 +//*BT-AMP packet LLC OUI value*/ +static const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +#endif + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_InitConnectionAcceptTimer + + DESCRIPTION + Initialize the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_InitConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize the timer */ + vosStatus = vos_timer_init( + &pBtampCtx->bapConnectionAcceptTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_ConnectionAcceptTimerHandler, + pBtampCtx); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_InitConnectionAcceptTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_DeinitConnectionAcceptTimer + + DESCRIPTION + Destroy the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeinitConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize and then Start the timer */ + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapConnectionAcceptTimer ); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_DeinitConnectionAcceptTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StartConnectionAcceptTimer + + DESCRIPTION + Start the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartConnectionAcceptTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +) +{ + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Start the connection accept timer*/ + vos_timer_start( + &pBtampCtx->bapConnectionAcceptTimer, + interval); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StartConnectionAcceptTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_StopConnectionAcceptTimer + + DESCRIPTION + Stop the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( + &pBtampCtx->bapConnectionAcceptTimer); + + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StopConnectionAcceptTimer */ + + + +/*========================================================================== + + FUNCTION WLANBAP_ConnectionAcceptTimerHandler + + DESCRIPTION + Callback function registered with vos timer for the Connection + Accept timer + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_ConnectionAcceptTimerHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t status; /* return the BT-AMP status here */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + + /*--------------------------------------------------------------------- + Feed this timeout to the BTAMP FSM + ---------------------------------------------------------------------*/ + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, &status); + + /* Now transition to fully disconnected and notify phy link disconnect*/ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, &status); + + +}/*WLANBAP_ConnectionAcceptTimerHandler*/ + +/*========================================================================== + + FUNCTION WLANBAP_InitLinkSupervisionTimer + + DESCRIPTION + Initialize the Link Supervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_InitLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize the timer */ + vosStatus = vos_timer_init( + &pBtampCtx->bapLinkSupervisionTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_LinkSupervisionTimerHandler, + pBtampCtx); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_InitLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_DeinitLinkSupervisionTimer + + DESCRIPTION + Destroy the Link Supervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeinitLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize and then Start the timer */ + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapLinkSupervisionTimer ); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_DeinitLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StartLinkSupervisionTimer + + DESCRIPTION + Start the LinkSupervisionTimer Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartLinkSupervisionTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +) +{ + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + vos_timer_start( + &pBtampCtx->bapLinkSupervisionTimer, + interval); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StartLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StopLinkSupervisionTimer + + DESCRIPTION + Stop the LinkSupervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( + &pBtampCtx->bapLinkSupervisionTimer); + + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StopLinkSupervisionTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_LinkSupervisionTimerHandler + + DESCRIPTION + Callback function registered with vos timer for the LinkSupervision timer + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_LinkSupervisionTimerHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = (ptBtampHandle)userData; + tWLAN_BAPEvent bapEvent; /* State machine event */ + v_U8_t phy_link_handle; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + + phy_link_handle = pBtampCtx->phy_link_handle; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP:In LinkSupervision Timer handler %s", __func__ ); + + if(pBtampCtx->dataPktPending == VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Data seen. Do nothing", __func__ ); + + pBtampCtx->dataPktPending = VOS_FALSE; + pBtampCtx->lsReqPktPending = VOS_FALSE; + pBtampCtx->retries = 0; + vosStatus = WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + + //Data is seen. or our previous packet is not yet fetched by TL.Don't do any thing.Just return; + return; + } + else if((pBtampCtx->lsReqPktPending == VOS_TRUE ) + && (pBtampCtx->retries == WLANBAP_LINK_SUPERVISION_RETRIES)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "#########WLAN BAP: LinkSupervision Timed OUT######## %s", __func__ ); + + /*--------------------------------------------------------------------- + Feed this timeout to the BTAMP FSM + ---------------------------------------------------------------------*/ + /* Fill in the event structure */ + /* JEZ110307: Which should this be? */ + //bapEvent.event =eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT; + bapEvent.event =eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, (v_U8_t *)&vosStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Resend the LS packet", __func__ ); + + /* If we have transmit pkt pending and the time out occurred,resend the ls packet */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + pBtampCtx->pPacket = pBtampCtx->lsReqPacket; + vosStatus = WLANBAP_TxLinkSupervision( btampHandle, + phy_link_handle, + pBtampCtx->pPacket , + WLANTL_BT_AMP_TYPE_LS_REQ); + } + +}/*WLANBAP_LinkSupervisionTimerHandler*/ + +/*========================================================================== + + FUNCTION WLANBAP_StartTxPacketMonitorTimer + + DESCRIPTION + Start the Tx Packet Monitor Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t uInterval = WLAN_BAP_TX_PKT_MONITOR_TIME; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Start the timer */ + vosStatus = vos_timer_start( &pBtampCtx->bapTxPktMonitorTimer, + uInterval); + + return vosStatus; +}/* WLANBAP_StartTxPacketMonitorTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_StopTxPacketMonitorTimer + + DESCRIPTION + Stop the Tx Packet Monitor Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( &pBtampCtx->bapTxPktMonitorTimer); + + + return vosStatus; +}/* WLANBAP_StopTxPacketMonitorTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_SendCompletedPktsEvent + + DESCRIPTION + Utility function for sending the NUM_OF_COMPLETED_PKTS_EVENT to HCI + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_SendCompletedPktsEvent +( + ptBtampContext pBtampCtx +) +{ + v_U8_t i, j; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U32_t uTxCompleted = 0; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Format the Number of completed packets event */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_handles = 0; + + /*--------------------------------------------------------------------- + Check if LL still exists, if TRUE generate num_pkt_event and + restart the timer + ---------------------------------------------------------------------*/ + for (i = 0, j = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + if ( pLogLinkContext->present ) + { + uTxCompleted = pLogLinkContext->uTxPktCompleted; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.conn_handles[j] = + pLogLinkContext->log_link_handle; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_completed_pkts[j] = + uTxCompleted; + + j++; + + vos_atomic_decrement_U32_by_value((v_U32_t *) &pLogLinkContext->uTxPktCompleted, + (v_U32_t) uTxCompleted); + + if (uTxCompleted) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "wlan bap: %s Log Link handle - %d No Of Pkts - %d", __func__, + pLogLinkContext->log_link_handle, uTxCompleted); + } + } + } + + /* Indicate only if at least one logical link is present and number of + completed packets is non zero */ + if (j && uTxCompleted) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Indicating Num Completed packets Event"); + + /*issue num_pkt_event for uTxCompleted*/ + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_handles = j; + (*pBtampCtx->pBapHCIEventCB) + ( + pBtampCtx->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + +} + +/*========================================================================== + + FUNCTION WLANBAP_SendCompletedDataBlksEvent + + DESCRIPTION + Utility function for sending the NUM_OF_COMPLETED_DATA_BLOCKS_EVENT to HCI + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_SendCompletedDataBlksEvent +( + ptBtampContext pBtampCtx +) +{ + v_U8_t i, j; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U32_t uTxCompleted = 0; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Format the Number of completed data blocks event */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_handles = 0; + + /*--------------------------------------------------------------------- + Check if LL still exists, if TRUE generate num_data_blocks_event and + restart the timer + ---------------------------------------------------------------------*/ + for (i = 0, j = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + if ( pLogLinkContext->present ) + { + uTxCompleted = pLogLinkContext->uTxPktCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.conn_handles[j] = + pLogLinkContext->log_link_handle; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_completed_pkts[j] = + uTxCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_completed_blocks[j] = + uTxCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.total_num_data_blocks = 16; + + j++; + + vos_atomic_decrement_U32_by_value((v_U32_t *) &pLogLinkContext->uTxPktCompleted, + (v_U32_t) uTxCompleted); + + if (uTxCompleted) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "wlan bap: %s Log Link handle - %d No Of Pkts - %d", __func__, + pLogLinkContext->log_link_handle, uTxCompleted); + } + } + } + + /* Indicate only if at least one logical link is present and number of + completed data blocks is non zero */ + if (j && uTxCompleted) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Indicating Num Completed Data Blocks Event"); + + /*issue num_data_blocks_event for uTxCompleted*/ + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_handles = j; + (*pBtampCtx->pBapHCIEventCB) + ( + pBtampCtx->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + +} + +/*========================================================================== + + FUNCTION WLANBAP_TxPacketMonitorHandler + + DESCRIPTION + Callback function registered with vos timer for the Tx Packet Monitor + Timer. + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_TxPacketMonitorHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &pBtampCtx->bapPhysLinkMachine; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + +#if 0 //BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %x in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + if(WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED == pBtampCtx->ucDataTrafficMode) + { + WLANBAP_SendCompletedDataBlksEvent(pBtampCtx); + } + else + { + WLANBAP_SendCompletedPktsEvent(pBtampCtx); + } + + /* Restart the Packet monitoring timer if still Physical link + * is present. + * It is possible that when the physical link is tear down, + * timer start request is in Q and could start again. + */ + if (CONNECTED == instanceVar->stateVar) + { + WLANBAP_StartTxPacketMonitorTimer(pBtampCtx); + } +}/*WLANBAP_TxPacketMonitorHandler*/ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.h new file mode 100644 index 0000000000000..5c4a3662a3683 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapApiTimer.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_API_TIMER_H +#define WLAN_QCT_WLANBAP_API_TIMER_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + T I M E R S E R V I C E S A P I + + +DESCRIPTION + This file contains the timer APIs used by the wlan BT-AMP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiTimer.h,v 1.1 2008/11/21 20:30:20 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/23/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pick up all the BT-AMP internal definitions +// And underlying supporting types. (Including VOSS, CSR, and...) +#include "bapInternal.h" + +/* Pick up the SIRIUS and HAL types */ +// Already taken care of, above +//#include "sirApi.h" +//#include "halTypes.h" + +/* Pick up the CCM API def'n */ +#include "ccmApi.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary +//#define BAP_DEBUG + + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +#if 0 +/*========================================================================== + + FUNCTION WLANBAP_StartConnectionAcceptTimer + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartConnectionAcceptTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +); +#endif // 0 + +/* Connection Accept timer*/ +VOS_STATUS WLANBAP_InitConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartConnectionAcceptTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_ConnectionAcceptTimerHandler + ( v_PVOID_t userData ); + +/* Link Supervision timer*/ +VOS_STATUS WLANBAP_InitLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartLinkSupervisionTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_LinkSupervisionTimerHandler + ( v_PVOID_t userData ); + +/* Logical Link Accept timer*/ +VOS_STATUS WLANBAP_InitLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartLogicalLinkAcceptTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_LogicalLinkAcceptTimerHandler + ( v_PVOID_t userData ); + +/* Best Effort Flush timer*/ +VOS_STATUS WLANBAP_InitBEFlushTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitBEFlushTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartBEFlushTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopBEFlushTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_BEFlushTimerHandler + ( v_PVOID_t userData ); + +/* Tx Packet monitor timer handler */ +v_VOID_t +WLANBAP_TxPacketMonitorHandler +( + v_PVOID_t userData +); + +/* Tx Packet monitor start timer */ +VOS_STATUS +WLANBAP_StartTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +); + +/* Tx Packet monitor stop timer */ +VOS_STATUS +WLANBAP_StopTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_API_TIMER_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapInternal.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapInternal.h new file mode 100644 index 0000000000000..0e4f5274354cc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapInternal.h @@ -0,0 +1,1304 @@ +/* + * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_INTERNAL_H +#define WLAN_QCT_WLANBAP_INTERNAL_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal API exposed by the wlan BT-AMP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapInternal.h,v 1.3 2010/07/12 20:40:18 labuser Exp labuser $ $DateTime: $ $Author: labuser $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/15/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" + +// Pick up the CSR API definitions +#include "csrApi.h" + +/* BT-AMP PAL API structure types - FramesC generated */ +#include "btampHCI.h" +#include "bapApi.h" + +// Pick up the BTAMP FSM definitions +#include "fsmDefs.h" +//#include "btampFsm.h" +#include "btampFsm_ext.h" +#include "bapRsn8021xFsm.h" +#include "bapRsnErrors.h" + +#include "csrApi.h" +#include "sirApi.h" +#include "wniApi.h" +#include "palApi.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary so that I can compile +//#define VOS_MODULE_ID_BAP 9 +// Temporary +//#define BAP_DEBUG + +// Used to enable or disable security on the BT-AMP link +#define WLANBAP_SECURITY_ENABLED_STATE VOS_TRUE + +// How do I get BAP context from voss context? +#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) +// How do I get halHandle from voss context? +#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_SME, ctx) + +// Default timeout values (in BR/EDR baseband slots) +// Physical Link Connection Accept Timer interval (0x1FA0 * 0.625 = 5.06 sec) +/* chose to double it to 3FFF as we saw conn timeout in lab*/ +//#define WLANBAP_CONNECTION_ACCEPT_TIMEOUT 0xFFFF +// Set default to 0x1F40. Which is ~5 secs. +#define WLANBAP_CONNECTION_ACCEPT_TIMEOUT 0x1F40 + +/* Link Supervision Timer interval (0x7D00 * 0.625 = 20 sec) */ +#ifdef FEATURE_WLAN_BTAMP_UT +#define WLANBAP_LINK_SUPERVISION_TIMEOUT 0x7D00 +#else +#define WLANBAP_LINK_SUPERVISION_TIMEOUT 0x3E80 // 10 seconds +#endif +#define WLANBAP_LINK_SUPERVISION_RETRIES 2 + +/* Logical Link Accept Timer interval (0x1FA0 * 0.625 = 5.06 sec)*/ +#define WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT 0x1F40 + +/* BR/EDR baseband 1 slot time period */ +#define WLANBAP_BREDR_BASEBAND_SLOT_TIME 1 // 0.625 + +/* Maximum allowed range for connection accept timeout interval */ +#define WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE 0xB540 + +/* Minimum allowed range for connection accept timeout interval */ +#define WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE 0x01 + +/* Best Effort Flush timer interval*/ +#define WLANBAP_BE_FLUSH_TIMEOUT 10 + +/* Length of the LLC header*/ +#define WLANBAP_LLC_HEADER_LEN 8 + +/*Size of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_SIZE 2 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_SIZE 3 + +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_OFFSET 3 + +/*Offset of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_OFFSET (WLANBAP_LLC_OUI_OFFSET + WLANBAP_LLC_OUI_SIZE) + +#define WLANBAP_MAX_NUM_TRIPLETS 5 + +#define WLANBAP_MAX_SIZE_TRIPLETS 3 +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Type Declarations - For internal BAP context information + * -------------------------------------------------------------------------*/ +typedef struct sBtampHCI_Buffer_Size { +// v_U8_t present; + /* D9r14 says Max80211PALPDUSize 1492 */ + v_U16_t HC_ACL_Data_Packet_Length; + v_U8_t HC_SCO_Packet_Length; + v_U16_t HC_Total_Num_ACL_Packets; + v_U16_t HC_Total_Num_SCO_Packets; +} tBtampHCI_Buffer_Size; + +typedef struct sBtampHCI_Data_Block_Size { +// v_U8_t present; + v_U8_t status; + /* D9r14 says Max80211PALPDUSize 1492 */ + v_U16_t HC_Max_ACL_Data_Packet_Length; + v_U16_t HC_Data_Block_Length; + v_U16_t HC_Total_Num_Data_Blocks; +} tBtampHCI_Data_Block_Size; + +typedef struct sBtampHCI_Version_Info { +// v_U8_t present; + v_U8_t HC_HCI_Version; + v_U16_t HC_HCI_Revision; + v_U8_t HC_PAL_Version; /* for 802.11 AMP: 0x01 */ + v_U16_t HC_PAL_Sub_Version; /* for 802.11 AMP: Vendor specific */ + v_U16_t HC_Manufac_Name; /* See BT assigned numbers */ +} tBtampHCI_Version_Info; + +typedef struct sBtampHCI_Supported_Cmds { +// v_U8_t present; + v_U8_t HC_Support_Cmds[64]; /* a bitmask of cmds */ +} tBtampHCI_Supported_Cmds; + +typedef struct sBtampHCI_AMP_Info { +// v_U8_t present; + v_U8_t HC_AMP_Status; + v_U32_t HC_Total_BW; /* combined uplink and downlink */ + v_U32_t HC_Max_Guaranteed_BW; /* upper bound */ + v_U32_t HC_Min_Latency; /* AMP HCI latency + DIFS + CWMin */ + v_U32_t HC_Max_PDU_Size; /* Equal to Max80211PALPDUSize */ + v_U8_t HC_Controller_Type; /* 0x01 for 802.11 BT-AMP PAL */ + v_U16_t HC_PAL_Capabilities; /* Bit 0: 0 = No Guarantee; 1 = Guarantee */ + v_U16_t HC_AMP_Assoc_Length; /* Length of AMP Assoc Info */ + /* Equal to Max80211AMPASSOCLen (672) */ + v_U16_t HC_Max_Flush_Timeout; /* Maximum time Tx attempted. 0 is inf retry */ + v_U16_t HC_BE_Flush_Timeout; /* Maximum time BE Tx attempted. 0 is inf retry */ +} tBtampHCI_AMP_Info; + +typedef struct sBtampHCI_AMP_Assoc { +// v_U8_t present; + v_U8_t HC_cnct_country[3]; /* Connected channel */ + v_U8_t HC_cnct_num_triplets; + v_U8_t HC_cnct_triplets[WLANBAP_MAX_NUM_TRIPLETS][WLANBAP_MAX_SIZE_TRIPLETS]; + v_U8_t HC_mac_addr[6]; + v_U32_t HC_pal_capabilities; + v_U8_t HC_pref_country[3]; /* Preferred channels */ + v_U8_t HC_pref_num_triplets; + v_U8_t HC_pref_triplets[WLANBAP_MAX_NUM_TRIPLETS][WLANBAP_MAX_SIZE_TRIPLETS]; + v_U8_t HC_pal_version; + v_U16_t HC_pal_CompanyID; + v_U16_t HC_pal_subversion; +} tBtampHCI_AMP_Assoc, *tpBtampHCI_AMP_Assoc ; + +typedef struct sBtampTLVHCI_Location_Data_Info { + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; +} tBtampTLVHCI_Location_Data_Info; + +/*---------------------------------------------------------------------------- + * Type Declarations - For BAP logical link context information + * -------------------------------------------------------------------------*/ +typedef struct sBtampLogLinkCtx { + v_U8_t present; /* In use? */ + + v_U8_t log_link_index; /* small integer (<16) value assigned by us */ + v_U16_t log_link_handle; /* 8 bits of phy_link_handle and our index */ + + /* The flow spec (From section 5.6 of Generic AMP spec) */ + tBtampTLVFlow_Spec btampFlowSpec; + + /* The Access category */ + WLANTL_ACEnumType btampAC; + + /* The TID */ + v_U8_t ucTID; + + /* UP of the packet being sent */ + v_U8_t ucUP; + + /*Number of packets completed since the last time num pkt complete event + was issued*/ + v_U32_t uTxPktCompleted; + +} tBtampLogLinkCtx, *tpBtampLogLinkCtx ; + +/*---------------------------------------------------------------------------- + * Type Declarations - QOS related + * -------------------------------------------------------------------------*/ +/* BT-AMP QOS config */ +typedef struct sBtampQosCfg { + v_U8_t bWmmIsEnabled; +} tBtampQosCfg; + +/*---------------------------------------------------------------------------- + * Opaque BAP context Type Declaration + * -------------------------------------------------------------------------*/ +// We were only using this syntax, when this was truly opaque. +// (I.E., it was defined in a different file.) +//typedef struct sBtampContext tBtampContext, *ptBtampContext; + + +// Validity check the logical link value +#define BTAMP_VALID_LOG_LINK(a) ( a > 0 && a < WLANBAP_MAX_LOG_LINKS ? 1 : 0) + +/* Instance data definition of state machine */ +// Moved here from the BTAMP FSM definitions in btampFsm.h +typedef struct{ + BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + BTAMPFSM_STATEVAR_T stateVar; + BTAMPFSM_INST_ID_T inst_id; +} BTAMPFSM_INSTANCEDATA_T; + +/* BT-AMP device role */ +typedef enum{ + BT_RESPONDER, + BT_INITIATOR +} tWLAN_BAPRole; + +/* BT-AMP device role */ +typedef enum{ + WLAN_BAPLogLinkClosed, + WLAN_BAPLogLinkOpen, + WLAN_BAPLogLinkInProgress, +} tWLAN_BAPLogLinkState; + +typedef struct{ + v_U8_t phyLinkHandle; + v_U8_t txFlowSpec[18]; + v_U8_t rxFlowSpec[18]; +} tBtampLogLinkReqInfo; + +/*---------------------------------------------------------------------------- + * BAP context Data Type Declaration + * -------------------------------------------------------------------------*/ +#undef BTAMP_MULTIPLE_PHY_LINKS +typedef struct sBtampContext { +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // include the phy link state machine structure here + tWLAN_BAPbapPhysLinkMachine bapPhysLinkMachine; + + // BAP device role + tWLAN_BAPRole BAPDeviceRole; + // Include the SME(CSR) sessionId here + v_U8_t sessionId; + + // Actual storage for AP and self (STA) SSID + //tSirMacSSid SSID[2]; + tCsrSSIDInfo SSIDList[2]; + // Actual storage for AP bssid + tCsrBssid bssid; + // Include the SME(CSR) context here + tCsrRoamProfile csrRoamProfile; + tANI_U32 csrRoamId; + + // QOS config + tBtampQosCfg bapQosCfg; + + /*Flag for signaling if security is enabled*/ + v_U8_t ucSecEnabled; + + // associated boolean flag + v_U8_t mAssociated; + // associated status + v_U8_t mAssociatedStatus; + tCsrBssid assocBssid; + tBssSystemRole systemRole; + + // own SSID + v_U8_t ownSsid[32]; + v_U32_t ownSsidLen; + + // incoming Assoc SSID + v_U8_t assocSsid[32]; + v_U32_t assocSsidLen; + + // gNeedPhysLinkCompEvent + v_U8_t gNeedPhysLinkCompEvent; + // gPhysLinkStatus + v_U8_t gPhysLinkStatus; + // gDiscRequested + v_U8_t gDiscRequested; + // gDiscReason + v_U8_t gDiscReason; + + // Include the BSL per-application context here + v_PVOID_t pAppHdl; // Per-app BSL context + // Include the BSL per-association contexts here. + // (Right now, there is only one) + v_PVOID_t pHddHdl; + /* 8 bits of phy_link_handle identifies this association */ + v_U8_t phy_link_handle; + // Short Range Mode setting for this physical link + v_U8_t phy_link_srm; + + // Include the key material for this physical link + v_U8_t key_type; + v_U8_t key_length; + v_U8_t key_material[32]; + + /* Physical link quality status + After the physical link is up, SME indicates the link quality through + callback. This value is returned to upper layer on request. + */ + v_U8_t link_quality; + + /* Connection Accept timer*/ + vos_timer_t bapConnectionAcceptTimer; + /* Link Supervision timer*/ + vos_timer_t bapLinkSupervisionTimer; + /* Logical Link Accept timer*/ + vos_timer_t bapLogicalLinkAcceptTimer; + /* Best Effort Flush timer*/ + vos_timer_t bapBEFlushTimer; + + /* TX Packet Monitoring timer*/ + vos_timer_t bapTxPktMonitorTimer; + + /* Connection Accept Timer interval (in BR/EDR baseband slots) + * Interval length = N * 0.625 msec (1 BR/EDR baseband slot) + */ + v_U16_t bapConnectionAcceptTimerInterval; + + /* Link Supervision Timer interval (in BR/EDR baseband slots) */ + v_U16_t bapLinkSupervisionTimerInterval; + + /* Logical Link Accept Timer interval (in BR/EDR baseband slots) */ + v_U16_t bapLogicalLinkAcceptTimerInterval; + + /* Best Effort Flush timer interval*/ + v_U32_t bapBEFlushTimerInterval; + + // Include the current channel here + v_U32_t channel; + + // Include the associations STA Id + v_U8_t ucSTAId; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[6]; + v_U8_t peer_mac_addr[6]; + + // The array of logical links + /* the last small integer (<16) value assigned by us */ + v_U8_t current_log_link_index; /* assigned mod 16 */ + v_U8_t total_log_link_index; /* should never be >16 */ + /* The actual array */ + tBtampLogLinkCtx btampLogLinkCtx[WLANBAP_MAX_LOG_LINKS]; + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB; + WLANBAP_STARxCBType pfnBtamp_STARxCB; + WLANBAP_TxCompCBType pfnBtampTxCompCB; + + /* Implements the callback for ALL asynchronous events. */ + tpWLAN_BAPEventCB pBapHCIEventCB; + + // Save Page2 of the event mask. + v_U8_t event_mask_page_2[8]; + + // Include the Local Assoc structure. + // (This gets filled during initialization. It is used, for example, to + // obtain the local MAC address for forming the 802.3 frame.) + // <> + tBtampHCI_AMP_Assoc btamp_AMP_Assoc; + + // Remote AMP Assoc + tBtampHCI_AMP_Assoc btamp_Remote_AMP_Assoc; + + tBtampTLVHCI_Location_Data_Info btamp_Location_Data_Info; + + union + { + tAuthRsnFsm authFsm; + tSuppRsnFsm suppFsm; + }uFsm; + //LinkSupervision packet + tANI_BOOLEAN lsReqPktPending; + tANI_BOOLEAN dataPktPending; + tANI_U8 retries; + vos_pkt_t *pPacket; + vos_pkt_t *lsReqPacket; + vos_pkt_t *lsRepPacket; + v_U16_t lsPktln; + v_U16_t lsPending; + WLANTL_MetaInfoType metaInfo; + tANI_BOOLEAN isBapSessionOpen; + + tWLAN_BAPLogLinkState btamp_logical_link_state; + + tBtampLogLinkReqInfo btamp_logical_link_req_info; + + tANI_BOOLEAN btamp_async_logical_link_create; + + tANI_BOOLEAN btamp_logical_link_cancel_pending; + + tANI_BOOLEAN btamp_session_on; + +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // include the state machine structure here + + // Include the BSL per-application context here + v_PVOID_t pAppHdl; // Per-app BSL context + // Include the BSL per-association contexts here. + // (Right now, there is only one) + v_PVOID_t pHddHdl; + /* 8 bits of phy_link_handle identifies this association */ + v_U8_t phy_link_handle; + // Short Range Mode setting for this physical link + v_U8_t phy_link_srm; + + // Include the associations STA Id + v_U8_t ucSTAId; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[6]; + v_U8_t peer_mac_addr[6]; + + // The array of logical links + /* the last small integer (<16) value assigned by us */ + v_U8_t current_log_link_index; /* assigned mod 16 */ + v_U8_t total_log_link_index; /* should never be >16 */ + /* The actual array */ + tBtampLogLinkCtx btampLogLinkCtx[WLANBAP_MAX_LOG_LINKS]; + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB; + WLANBAP_STARxCBType pfnBtamp_STARxCB; + WLANBAP_TxCompCBType pfnBtampTxCompCB; + + /* Implements the callback for ALL asynchronous events. */ + tpWLAN_BAPEventCB pBapHCIEventCB; + + // Include the Local Assoc structure. + // (This gets filled during initialization. It is used, for example, to + // obtain the local MAC address for forming the 802.3 frame.) + // <> + tBtampHCI_AMP_Assoc btamp_AMP_Assoc; + //LinkSupervision packet + tANI_BOOLEAN lsReqPktPending; + tANI_U8 retries; + vos_pkt_t *pPacket; + vos_pkt_t *lsReqPacket; + vos_pkt_t *lsRepPacket; + v_U16_t lsPktln; + WLANTL_MetaInfoType* metaInfo; + tANI_BOOLEAN isBapSessionOpen; + //End of LinkSupervision packet +#endif //BTAMP_MULTIPLE_PHY_LINKS + WLANBAP_ConfigType config; + /*multiple data structures getting accessed/written from both north & south + bound entities. To avoid multiple access, need a lock*/ + vos_lock_t bapLock; + // Either Block mode or Pkt mode + v_U8_t ucDataTrafficMode; +}*ptBtampContext; +//tBtampContext, *ptBtampContext; + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +typedef struct sBtampLsPktData { + v_U32_t BufLen; + v_U8_t pBuf[1]; // ptr to Data Buffer +}tBtampLsPktData, *ptBtampLsPktData; + +typedef struct sBtampLsPkt { + v_U8_t SrcMac[6]; + v_U8_t DstMac[6]; + tBtampLsPktData Data; +} tBtampLsPkt, *ptBtampLsPkt; + +/*---------------------------------------------------------------------------- + * BAP per-session Context Data Type Declaration + * -------------------------------------------------------------------------*/ +// For now, it is just the same thing as the per application context. +typedef struct sBtampContext tBtampSessCtx; + +/*---------------------------------------------------------------------------- + * BAP state machine event definition + * -------------------------------------------------------------------------*/ +/* The event structure */ +typedef struct sWLAN_BAPEvent { + v_U32_t event; /* State machine input event message */ + v_PVOID_t params; /* A VOID pointer type for all possible inputs */ + v_U32_t u1; /* introduced to handle csrRoamCompleteCallback roamStatus */ + v_U32_t u2; /* introduced to handle csrRoamCompleteCallback roamResult */ +} tWLAN_BAPEvent, *ptWLAN_BAPEvent; + +// Pick up the BTAMP FSM definitions +#include "btampFsm.h" + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// The main per-Physical Link (per WLAN association) context. +//extern tBtampContext btampCtx; +extern ptBtampContext gpBtampCtx; + +// Include the Local AMP Info structure. +extern tBtampHCI_AMP_Info btampHCI_AMP_Info; +// Include the Local Data Block Size info structure. +extern tBtampHCI_Data_Block_Size btampHCI_Data_Block_Size; +// Include the Local Version info structure. +extern tBtampHCI_Version_Info btampHCI_Version_Info; +// Include the Local Supported Cmds info structure. +extern tBtampHCI_Supported_Cmds btampHCI_Supported_Cmds; + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/* I don't think any of this is needed */ + +/* TL data path callbacks passed into WLANTL_RegisterSTAClient */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STAFetchPktCB + + DESCRIPTION + The fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STAFetchPktCB +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + v_U8_t ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STARxCB + + DESCRIPTION + The receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + rxBufChain : pointer to adf_nbuf rx chain + ucSTAId: station id + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STARxCB(v_PVOID_t pvosGCtx, adf_nbuf_t rxBufChain, v_U8_t ucSTAId); + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxCompCB + + DESCRIPTION + The tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxCompCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +); + +/* Callbacks Registered with TL by WLANTL_RegisterBAPClient */ + +/* RSN Callback */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + The receive callback registered with TL for BAP. + + The registered reception callback is being triggered by TL whenever a + frame was received and it was filtered as a non-data BT AMP packet. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +WLANTL_BAPRxCBType WLANBAP_TLRsnRxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff +); + +/* Flush complete Callback */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required inorder for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucStaId: station identifier for the requested value + ucTid: identifier of the tspec + status: status of the Flush operation + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_TLFlushCompCallback +( + v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status +); + +/*---------------------------------------------------------------------------- + * CSR Roam (Connection Status) callback + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pParam: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The result code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +eHalStatus +WLANBAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +); + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_CleanCB + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CleanCB +( + ptBtampContext pBtampCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +); + +/*========================================================================== + + FUNCTION WLANBAP_GetCtxFromStaId + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need either the + BSL context or the BTAMP context from the StaId. + + + DEPENDENCIES + + PARAMETERS + + IN + ucSTAId: The StaId (used by TL, PE, and HAL) + + OUT + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCtxFromStaId +( + v_U8_t ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + ptBtampHandle *hBtampHandle, /* Handle to return per app btampHandle value in */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + v_PVOID_t *hHddHdl /* Handle to return BSL context in */ +); + +/*========================================================================== + + FUNCTION WLANBAP_GetStaIdFromLinkCtx + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need the + StaId (or hHddHdl) from the BTAMP context and phy_link_handle. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + phy_link_handle: physical link handle value. Unique per assoc. + + OUT + pucSTAId: The StaId (used by TL, PE, and HAL) + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetStaIdFromLinkCtx +( + ptBtampHandle btampHandle, /* btampHandle value in */ + v_U8_t phy_link_handle, /* phy_link_handle value in */ + v_U8_t *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t *hHddHdl /* Handle to return BSL context */ +); + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewPhyLinkCtx + + DESCRIPTION + Called in order to create (or update) a BAP Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: BAP app context handle + phy_link_handle: phy_link_handle from the Command + pHddHdl: BSL passes in its specific context + + OUT + hBtampContext: Handle (pointer to a pointer) to return the + per "Phy Link" ptBtampContext value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewPhyLinkCtx +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + tWLAN_BAPRole BAPDeviceRole /* Needed to determine which MAC address to use for self MAC */ +); + +/*========================================================================== + + FUNCTION WLANBAP_UpdatePhyLinkCtxStaId + + DESCRIPTION + Called to update the STAId value associated with Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: ptBtampContext to update. + ucSTAId: The StaId (used by TL, PE, and HAL) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_UpdatePhyLinkCtxStaId +( + ptBtampContext pBtampContext, /* btampContext value in */ + v_U8_t ucSTAId +); + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewLogLinkCtx + + DESCRIPTION + Called in order to allocate a BAP Logical Link "context" and "index" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: Pointer to the ptBtampContext value in. + phy_link_handle: phy_link_handle involved + + OUT + pLog_link_handle: return the log_link_handle here + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewLogLinkCtx +( + ptBtampContext pBtampContext, /* pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_U8_t tx_flow_spec[18], + v_U8_t rx_flow_spec[18], + v_U16_t *pLog_link_handle /* Return the logical link index here */ +); + + /*========================================================================== + + FUNCTION WLANBAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +); + +/*=========================================================================== + + FUNCTION WLANBAP_RxProcLsPkt + + DESCRIPTION + + This API will be called when Link Supervision frames are received at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + RxProtoType: Protocol type of Received Packet + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RxProcLsPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + v_U16_t RxProtoType, /* Protocol Type from the frame received */ + vos_pkt_t *vosRxLsBuff +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxLinkSupervisionReq() + + DESCRIPTION + Implements the LinkSupervision Tx Request procedure.This will be called by APIs that want + to transmit LinkSupervision Packets + Calls PktPending CB to indicate a packet is pending for transmission + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + vosDataBuff:The actual packet being sent in Tx request + protoType : specifies if it is a LS REQ or LS REP packet + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Failure of Transmit procedure + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxLinkSupervision +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + vos_pkt_t *vosDataBuff, + v_U16_t protoType +); + +/*========================================================================== + + FUNCTION WLANBAP_ReadMacConfig + + DESCRIPTION + This function sets the MAC config (Address and SSID to BT-AMP context + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_ReadMacConfig +( + ptBtampContext pBtampCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_NeedBTCoexPriority + + DESCRIPTION + This function will cause a message to be sent to BTC firmware + if a change in priority has occurred. (From AMP's point-of-view.) + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to HAL's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_NeedBTCoexPriority +( + ptBtampContext pBtampCtx, + v_U32_t needCoexPriority +); + + +/*========================================================================== + + FUNCTION WLANBAP_RxCallback + + DESCRIPTION + This function is called by TL call this function for all frames except for Data frames + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + pPacket Vos packet + frameType Frame type + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANBAP_RxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + WLANTL_BAPFrameEnumType frameType +); + + +/*=========================================================================== + + FUNCTION WLANBAP_InitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be initialized when connected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +#define TX_LS_DATALEN 32 + +VOS_STATUS +WLANBAP_InitLinkSupervision +( + ptBtampHandle btampHandle +); + + +/*=========================================================================== + + FUNCTION WLANBAP_DeInitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be stopped after disconnected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeInitLinkSupervision +( + ptBtampHandle btampHandle +); + +void WLAN_BAPEstablishLogicalLink(ptBtampContext btampContext); + + #ifdef __cplusplus + } + + +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_INTERNAL_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapModule.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapModule.c new file mode 100644 index 0000000000000..bb52a4af8fa07 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapModule.c @@ -0,0 +1,1405 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p M o d u l e . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Module support functions. It is also where the global BAP module + context, and per-instance (returned in BAP_Open device open) contexts. + + The functions externalized by this module are to be called by the device + specific BAP Shim Layer (BSL) (in HDD) which implements a stream device on a + particular platform. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapModule.c,v 1.1 2010/07/12 19:05:35 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pull in some message types used by BTC +#include "sirParams.h" +//#include "halFwApi.h" + +#include "wlan_qct_tl.h" +#include "vos_trace.h" +// Pick up the sme callback registration API +#include "sme_Api.h" +#include "ccmApi.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +// Pick up the BTAMP RSN definitions +#include "bapRsnTxRx.h" +//#include "assert.h" +#include "bapApiTimer.h" + +#if defined(ANI_OS_TYPE_ANDROID) +#include "bap_hdd_main.h" +#endif + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +//#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +// include the phy link state machine structure here +static tWLAN_BAPbapPhysLinkMachine bapPhysLinkMachineInitial + = BTAMPFSM_INSTANCEDATA_INIT; + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// No! Get this from VOS. +// The main per-Physical Link (per WLAN association) context. +//tBtampContext btampCtx; +ptBtampContext gpBtampCtx; + +// Include the Local AMP Info structure. +tBtampHCI_AMP_Info btampHCI_AMP_Info; +// Include the Local Data Block Size info structure. +tBtampHCI_Data_Block_Size btampHCI_Data_Block_Size; +// Include the Local Version info structure. +tBtampHCI_Version_Info btampHCI_Version_Info; +// Include the Local Supported Cmds info structure. +tBtampHCI_Supported_Cmds btampHCI_Supported_Cmds; + +static unsigned char pBtStaOwnMacAddr[VOS_MAC_ADDR_SIZE]; + + /*BT-AMP SSID; per spec should have this format: "AMP-00-0a-f5-04-05-08" */ +#define WLAN_BAP_SSID_MAX_LEN 21 +static char pBtStaOwnSsid[WLAN_BAP_SSID_MAX_LEN]; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). BAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Open +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) BAP control block + ------------------------------------------------------------------------*/ + vos_alloc_context(pvosGCtx, VOS_MODULE_ID_BAP, (v_VOID_t**)&pBtampCtx, sizeof(tBtampContext)); + + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Open"); + //"Failed to allocate BAP pointer from pvosGCtx on WLANBAP_Open"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up BAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Open"); + + WLANBAP_CleanCB(pBtampCtx, 0 /*do not empty*/); + + // Setup the "link back" to the VOSS context + pBtampCtx->pvosGCtx = pvosGCtx; + + // Store a pointer to the BAP context provided by VOSS + gpBtampCtx = pBtampCtx; + + /*------------------------------------------------------------------------ + Allocate internal resources + ------------------------------------------------------------------------*/ + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Open */ + + +/*========================================================================== + + FUNCTION WLANBAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). BAP will + use this call to register with TL as the BAP entity for + BT-AMP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Start +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Start"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Register with TL as an BT-AMP RSN client + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Start TL register"); + + /*------------------------------------------------------------------------ + Register with CSR for Roam (connection status) Events + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Start CSR Register"); + + + /* Initialize the BAP Tx packet monitor timer */ + WLANBAP_InitConnectionAcceptTimer (pBtampCtx ); + WLANBAP_InitLinkSupervisionTimer(pBtampCtx); + + vosStatus = vos_timer_init( + &pBtampCtx->bapTxPktMonitorTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_TxPacketMonitorHandler, + pBtampCtx); + + vosStatus = vos_lock_init(&pBtampCtx->bapLock); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"Lock Init Fail"); + } + + return vosStatus; +}/* WLANBAP_Start */ + +/*========================================================================== + + FUNCTION WLANBAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in BAP, before close. BAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Stop +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Stop"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Stop BAP (de-register RSN handler!?) + ------------------------------------------------------------------------*/ + vosStatus = WLANBAP_DeinitConnectionAcceptTimer(pBtampCtx); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapConnectionAcceptTimer"); + } + + vosStatus = WLANBAP_DeinitLinkSupervisionTimer(pBtampCtx); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapLinkSupervisionTimer"); + } + + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapTxPktMonitorTimer ); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapTxPktMonitorTimer"); + } + vos_lock_destroy(&pBtampCtx->bapLock); + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Stop */ + +/*========================================================================== + + FUNCTION WLANBAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. BAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Close +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Close"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Cleanup BAP control block. + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Close"); + WLANBAP_CleanCB(pBtampCtx, 1 /* empty queues/lists/pkts if any*/); +#if defined(ANI_OS_TYPE_ANDROID) && defined(WLAN_BTAMP_FEATURE) + BSL_Deinit(pvosGCtx); +#endif + /*------------------------------------------------------------------------ + Free BAP context from VOSS global + ------------------------------------------------------------------------*/ + vos_free_context(pvosGCtx, VOS_MODULE_ID_BAP, pBtampCtx); + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Close */ + +/*---------------------------------------------------------------------------- + HDD interfaces - Per instance initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetNewHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Open). BAP will initialize + allocate a per-instance "file handle" equivalent for this specific + open call. + + There should only ever be one call to BSL_Open. Since + the open app user is the BT stack. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle to return btampHandle value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANBAP_GetNewHndl +( + ptBtampHandle *hBtampHandle /* Handle to return btampHandle value in */ +) +{ + ptBtampContext btampContext = NULL; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == hBtampHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle pointer in WLANBAP_GetNewHndl"); + return VOS_STATUS_E_FAULT; + } + +#ifndef BTAMP_MULTIPLE_PHY_LINKS + /*------------------------------------------------------------------------ + Sanity check the BAP control block pointer + ------------------------------------------------------------------------*/ + if ( NULL == gpBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in WLANBAP_GetNewHndl"); + return VOS_STATUS_E_FAULT; + } + + //*hBtampHandle = (ptBtampHandle) &btampCtx; + /* return a pointer to the tBtampContext structure - allocated by VOS for us */ + *hBtampHandle = (ptBtampHandle) gpBtampCtx; + btampContext = gpBtampCtx; + + /* Update the MAC address and SSID if in case the Read Local AMP Assoc + * Request is made before Create Physical Link creation. + */ + WLANBAP_ReadMacConfig (btampContext); + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetNewHndl */ + + +/*========================================================================== + + FUNCTION WLANBAP_ReleaseHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Close). BAP will reclaim (invalidate) + the "file handle" passed into this call. + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: btampHandle value to invalidate. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_ReleaseHndl +( + ptBtampHandle btampHandle /* btamp handle value to release */ +) +{ + /* obtain btamp Context */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tHalHandle halHandle; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == btampHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_ReleaseHndl"); + return VOS_STATUS_E_FAULT; + } + + /* JEZ081001: TODO: Major: */ + /* Check to see if any wireless associations are still active */ + /* ...if so, I have to call + * sme_RoamDisconnect(VOS_GET_HAL_CB(btampHandle->pvosGCtx), + * btampHandle->sessionId, + * eCSR_DISCONNECT_REASON_UNSPECIFIED); + * on all of them */ + + halHandle = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if(NULL == halHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "halHandle is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if( btampContext->isBapSessionOpen == TRUE ) + { + halStatus = sme_CloseSession(halHandle, + btampContext->sessionId, NULL, NULL); + if(eHAL_STATUS_SUCCESS == halStatus) + { + btampContext->isBapSessionOpen = FALSE; + } + } + + /* release the btampHandle */ + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_ReleaseHndl */ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_CleanCB + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CleanCB +( + ptBtampContext pBtampCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +) +{ + v_U16_t i; /* Logical Link index */ + tpBtampLogLinkCtx pLogLinkContext = NULL; + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in WLANBAP_CleanCB"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up BAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_CleanCB"); + + // First, clear out EVERYTHING in the BT-AMP context + vos_mem_set( pBtampCtx, sizeof( *pBtampCtx), 0); + + pBtampCtx->pvosGCtx = NULL; + + // Initialize physical link state machine to DISCONNECTED state + //pBtampCtx->bapPhysLinkMachine = BTAMPFSM_INSTANCEDATA_INIT; + + // Initialize physical link state machine to DISCONNECTED state + vos_mem_copy( + &pBtampCtx->bapPhysLinkMachine, + &bapPhysLinkMachineInitial, /* BTAMPFSM_INSTANCEDATA_INIT; */ + sizeof( pBtampCtx->bapPhysLinkMachine)); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initializing State: %d", __func__, bapPhysLinkMachineInitial.stateVar); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initialized State: %d", __func__, pBtampCtx->bapPhysLinkMachine.stateVar); + + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %x", __func__, pBtampCtx); +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %x in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + + pBtampCtx->sessionId = 0; + pBtampCtx->pAppHdl = NULL; // Per-app BSL context + pBtampCtx->pHddHdl = NULL; // Per-app BSL context + /* 8 bits of phy_link_handle identifies this association */ + pBtampCtx->phy_link_handle = 0; + pBtampCtx->channel = 0; + pBtampCtx->BAPDeviceRole = BT_RESPONDER; + pBtampCtx->ucSTAId = 0; + + // gNeedPhysLinkCompEvent + pBtampCtx->gNeedPhysLinkCompEvent = VOS_FALSE; + // gPhysLinkStatus + pBtampCtx->gPhysLinkStatus = WLANBAP_STATUS_SUCCESS; + // gDiscRequested + pBtampCtx->gDiscRequested = VOS_FALSE; + // gDiscReason + pBtampCtx->gDiscReason = WLANBAP_STATUS_SUCCESS; + + /* Connection Accept Timer interval*/ + pBtampCtx->bapConnectionAcceptTimerInterval = WLANBAP_CONNECTION_ACCEPT_TIMEOUT; + /* Link Supervision Timer interval*/ + pBtampCtx->bapLinkSupervisionTimerInterval = WLANBAP_LINK_SUPERVISION_TIMEOUT; + /* Logical Link Accept Timer interval*/ + pBtampCtx->bapLogicalLinkAcceptTimerInterval = WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT; + /* Best Effort Flush timer interval*/ + pBtampCtx->bapBEFlushTimerInterval = WLANBAP_BE_FLUSH_TIMEOUT; + + // Include the associations MAC addresses + vos_mem_copy( + pBtampCtx->self_mac_addr, + pBtStaOwnMacAddr, /* Where do I get the current MAC address? */ + sizeof(pBtampCtx->self_mac_addr)); + + vos_mem_set( + pBtampCtx->peer_mac_addr, + sizeof(pBtampCtx->peer_mac_addr), + 0); + + // The array of logical links + pBtampCtx->current_log_link_index = 0; /* assigned mod 16 */ + pBtampCtx->total_log_link_index = 0; /* should never be >16 */ + + // Clear up the array of logical links + for (i = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + pLogLinkContext->present = 0; + pLogLinkContext->uTxPktCompleted = 0; + pLogLinkContext->log_link_handle = 0; + } + + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + pBtampCtx->pfnBtampFetchPktCB = NULL; + pBtampCtx->pfnBtamp_STARxCB = NULL; + pBtampCtx->pfnBtampTxCompCB = NULL; + /* Implements the callback for ALL asynchronous events. */ + pBtampCtx->pBapHCIEventCB = NULL; + + /* Set the default for event mask */ + vos_mem_set( + pBtampCtx->event_mask_page_2, + sizeof(pBtampCtx->event_mask_page_2), + 0); + + /* Set the default for location data. */ + pBtampCtx->btamp_Location_Data_Info.loc_options = 0x58; + /* Set the default data transfer mode */ + pBtampCtx->ucDataTrafficMode = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_CleanCB */ + +/*========================================================================== + + FUNCTION WLANBAP_GetCtxFromStaId + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need either the + BSL context or the BTAMP context from the StaId. + + + DEPENDENCIES + + PARAMETERS + + IN + ucSTAId: The StaId (used by TL, PE, and HAL) + + OUT + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCtxFromStaId +( + v_U8_t ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + ptBtampHandle *hBtampHandle, /* Handle to return per app btampHandle value in */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + v_PVOID_t *hHddHdl /* Handle to return BSL context in */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + /* For now, we know there is only one application context */ + /* ...and only one physical link context */ + //*hBtampHandle = &((ptBtampContext) btampCtx); + //*hBtampHandle = &btampCtx; + *hBtampHandle = (v_VOID_t*)gpBtampCtx; + + //*hBtampContext = &btampCtx; + *hBtampContext = gpBtampCtx; + + /* Handle to return BSL context in */ + //*hHddHdl = btampCtx.pHddHdl; + *hHddHdl = gpBtampCtx->pHddHdl; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetCtxFromStaId */ + +/*========================================================================== + + FUNCTION WLANBAP_GetStaIdFromLinkCtx + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need the + StaId (or hHddHdl) from the BTAMP context and phy_link_handle. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + phy_link_handle: physical link handle value. Unique per assoc. + + OUT + pucSTAId: The StaId (used by TL, PE, and HAL) + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetStaIdFromLinkCtx +( + ptBtampHandle btampHandle, /* btampHandle value in */ + v_U8_t phy_link_handle, /* phy_link_handle value in */ + v_U8_t *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t *hHddHdl /* Handle to return BSL context */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Since there is only one physical link...we have stored all + * the physical link specific context in the application context + */ + /* The StaId (used by TL, PE, and HAL) */ + *pucSTAId = pBtampCtx->ucSTAId; + + /* Handle to return BSL context */ + *hHddHdl = pBtampCtx->pHddHdl; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetStaIdFromLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewPhyLinkCtx + + DESCRIPTION + Called in order to create (or update) a BAP Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: BAP app context handle + phy_link_handle: phy_link_handle from the Command + pHddHdl: BSL passes in its specific context + + OUT + hBtampContext: Handle (pointer to a pointer) to return the + per "Phy Link" ptBtampContext value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewPhyLinkCtx +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + tWLAN_BAPRole BAPDeviceRole +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + ptBtampContext pBtampCtx = gpBtampCtx; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Read and Set MAC address and SSID to BT-AMP context */ + WLANBAP_ReadMacConfig (pBtampCtx); + + /*------------------------------------------------------------------------ + For now, presume security is not enabled. + ------------------------------------------------------------------------*/ + pBtampCtx->ucSecEnabled = WLANBAP_SECURITY_ENABLED_STATE; + + /*------------------------------------------------------------------------ + Initial Short Range Mode for this physical link is 'disabled' + ------------------------------------------------------------------------*/ + pBtampCtx->phy_link_srm = 0; + + /*------------------------------------------------------------------------ + Clear out the logical links. + ------------------------------------------------------------------------*/ + pBtampCtx->current_log_link_index = 0; + pBtampCtx->total_log_link_index = 0; + + /*------------------------------------------------------------------------ + Now configure the roaming profile links. To SSID and bssid. + ------------------------------------------------------------------------*/ + // We have room for two SSIDs. + pBtampCtx->csrRoamProfile.SSIDs.numOfSSIDs = 1; // This is true for now. + pBtampCtx->csrRoamProfile.SSIDs.SSIDList = pBtampCtx->SSIDList; //Array of two + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].SSID.length = 0; + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].handoffPermitted = VOS_FALSE; + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].ssidHidden = VOS_FALSE; + + pBtampCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; // This is true for now. + pBtampCtx->csrRoamProfile.BSSIDs.bssid = &pBtampCtx->bssid; + + // Now configure the auth type in the roaming profile. To open. + //pBtampCtx->csrRoamProfile.AuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + //pBtampCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + pBtampCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_RSN_PSK; + pBtampCtx->csrRoamProfile.negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_AES; + + pBtampCtx->phy_link_handle = phy_link_handle; + /* For now, we know there is only one physical link context */ + //*hBtampContext = &btampCtx; + + pBtampCtx->pHddHdl = pHddHdl; + + *hBtampContext = pBtampCtx; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Btamp Ctxt = %p", pBtampCtx); + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_CreateNewPhyLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_UpdatePhyLinkCtxStaId + + DESCRIPTION + Called to update the STAId value associated with Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: ptBtampContext to update. + ucSTAId: The StaId (used by TL, PE, and HAL) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_UpdatePhyLinkCtxStaId +( + ptBtampContext pBtampContext, /* btampContext value in */ + v_U8_t ucSTAId +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* The StaId (used by TL, PE, and HAL) */ + pBtampContext->ucSTAId = ucSTAId; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_UpdatePhyLinkCtxStaId */ + +v_U8_t +bapAllocNextLogLinkIndex +( + ptBtampContext pBtampContext, /* Pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle /* I get phy_link_handle from the Command */ +) +{ + return ++(pBtampContext->current_log_link_index) % WLANBAP_MAX_LOG_LINKS; +}/* bapAllocNextLogLinkIndex */ + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewLogLinkCtx + + DESCRIPTION + Called in order to allocate a BAP Logical Link "context" and "index" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: Pointer to the ptBtampContext value in. + phy_link_handle: phy_link_handle involved + + OUT + pLog_link_handle: return the log_link_handle here + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewLogLinkCtx +( + ptBtampContext pBtampContext, /* Pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_U8_t tx_flow_spec[18], + v_U8_t rx_flow_spec[18], + v_U16_t *pLog_link_handle /* Return the logical link index here */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + v_U16_t i; /* Logical Link index */ + tpBtampLogLinkCtx pLogLinkContext; + v_U32_t retval; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + For now, allocate the logical links serially. + ------------------------------------------------------------------------*/ + i = pBtampContext->current_log_link_index + = bapAllocNextLogLinkIndex(pBtampContext, phy_link_handle); + pBtampContext->total_log_link_index++; + + *pLog_link_handle = (i << 8) + ( v_U16_t ) phy_link_handle ; /* Return the logical link index here */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " %s:*pLog_link_handle=%x", __func__,*pLog_link_handle); + + /*------------------------------------------------------------------------ + Evaluate the Tx and Rx Flow specification for this logical link. + ------------------------------------------------------------------------*/ + // Currently we only support flow specs with service types of BE (0x01) + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampContext value = %p in %s:%d", pBtampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /*------------------------------------------------------------------------ + Now configure the Logical Link context. + ------------------------------------------------------------------------*/ + pLogLinkContext = &(pBtampContext->btampLogLinkCtx[i]); + + /* Extract Tx flow spec into the context structure */ + retval = btampUnpackTlvFlow_Spec((void *)pBtampContext, tx_flow_spec, + WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN, + &pLogLinkContext->btampFlowSpec); + if (retval != BTAMP_PARSE_SUCCESS) + { + /* Flow spec parsing failed, return failure */ + return VOS_STATUS_E_BADMSG; + } + + /* Save the Logical link handle in the logical link context + As of now, only the index is saved as logical link handle since + same is returned in the event. + FIXME: Decide whether this index has to be combined with physical + link handle to generate the Logical link handle. + */ + pLogLinkContext->log_link_handle = *pLog_link_handle; + + // Mark this entry as OCCUPIED + pLogLinkContext->present = VOS_TRUE; + // Now initialize the Logical Link context + pLogLinkContext->btampAC = 1; + // Now initialize the values in the Logical Link context + pLogLinkContext->ucTID = 0; // Currently we only support BE TID (0x00) + pLogLinkContext->ucUP = 0; + pLogLinkContext->uTxPktCompleted = 0; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_CreateNewLogLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +) +{ + +}/* WLANBAP_pmcFullPwrReqCB */ + + +/*========================================================================== + + FUNCTION WLANBAP_ReadMacConfig + + DESCRIPTION + This function sets the MAC config (Address and SSID to BT-AMP context + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_ReadMacConfig +( + ptBtampContext pBtampCtx +) +{ + tANI_U32 len = VOS_MAC_ADDR_SIZE; + tHalHandle pMac = NULL; + + /*------------------------------------------------------------------------ + Temporary method to get the self MAC address + ------------------------------------------------------------------------*/ + if (NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pBtampCtx is NULL in %s", __func__); + + return; + } + + pMac = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pBtampCtx->pvosGCtx); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pMac is NULL in %s", __func__); + + return; + } + + ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pBtStaOwnMacAddr, &len ); + + if (VOS_MAC_ADDR_SIZE != len) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "len is improper %s", __func__); + return; + } + + /* Form the SSID from Mac address */ + VOS_SNPRINTF( pBtStaOwnSsid, WLAN_BAP_SSID_MAX_LEN, + "AMP-%02x-%02x-%02x-%02x-%02x-%02x", + pBtStaOwnMacAddr[0], pBtStaOwnMacAddr[1], pBtStaOwnMacAddr[2], + pBtStaOwnMacAddr[3], pBtStaOwnMacAddr[4], pBtStaOwnMacAddr[5]); + + /*------------------------------------------------------------------------ + Set the MAC address for this instance + ------------------------------------------------------------------------*/ + vos_mem_copy( + pBtampCtx->self_mac_addr, + pBtStaOwnMacAddr, + sizeof(pBtampCtx->self_mac_addr)); + + /*------------------------------------------------------------------------ + Set our SSID value + ------------------------------------------------------------------------*/ + pBtampCtx->ownSsidLen = 21; + vos_mem_copy( + pBtampCtx->ownSsid, + pBtStaOwnSsid, + pBtampCtx->ownSsidLen); +} + +/*========================================================================== + + FUNCTION WLANBAP_NeedBTCoexPriority + + DESCRIPTION + This function will cause a message to be sent to BTC firmware + if a change in priority has occurred. (From AMP's point-of-view.) + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to HAL's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +// Global +static int gBapCoexPriority; + +void +WLANBAP_NeedBTCoexPriority +( + ptBtampContext pBtampCtx, + v_U32_t needCoexPriority +) +{ + tHalHandle pMac = NULL; + tSmeBtAmpEvent btAmpEvent; + + + /*------------------------------------------------------------------------ + Retrieve the pMac (HAL context) + ------------------------------------------------------------------------*/ + pMac = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pBtampCtx->pvosGCtx); + + // Is re-entrancy protection needed for this? + if (needCoexPriority != gBapCoexPriority) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Calling %s with needCoexPriority=%d.", __func__, needCoexPriority); + + gBapCoexPriority = needCoexPriority; + switch ( needCoexPriority) + { + case 0: /* Idle */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_TERMINATED; + pBtampCtx->btamp_session_on = FALSE; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + case 1: /* Associating */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_START; + pBtampCtx->btamp_session_on = TRUE; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + case 2: /* Post-assoc */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_STOP; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Coexistence priority request: %d", + __func__, needCoexPriority); + } + + } +} + + +/*========================================================================== + + FUNCTION WLANBAP_RxCallback + + DESCRIPTION + This function is called by TL call this function for all frames except for Data frames + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + pPacket Vos packet + frameType Frame type + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANBAP_RxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + WLANTL_BAPFrameEnumType frameType +) +{ + ptBtampContext pBtampCtx = NULL; + + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Start"); + return VOS_STATUS_E_FAULT; + } + + switch (frameType) + { + case WLANTL_BT_AMP_TYPE_LS_REQ: /* Fall through */ + case WLANTL_BT_AMP_TYPE_LS_REP: + { + /* Link supervision frame, process this frame */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: link Supervision packet received over TL: %d, => BAP", + __func__, frameType); + WLANBAP_RxProcLsPkt((ptBtampHandle)pBtampCtx, + pBtampCtx->phy_link_handle, + frameType, + pPacket); + break; + } + + case WLANTL_BT_AMP_TYPE_AR: /* Fall through */ + case WLANTL_BT_AMP_TYPE_SEC: + { + /* Call the RSN callback handler */ + bapRsnRxCallback (pvosGCtx, pPacket); + break; + } + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid frametype from TL: %d, => BAP", + __func__, frameType); + } + + return ( VOS_STATUS_SUCCESS ); +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.c new file mode 100644 index 0000000000000..9d67cd899f874 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.c @@ -0,0 +1,1625 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xAuthRsnFsm.c $ + * + */ +/* + * Contains definitions for the RSN EAPOL-Key FSM on the + * authenticator side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" +#include "bapRsn8021xAuthFsm.h" +#include "vos_utils.h" +#include "vos_memory.h" +#include "vos_timer.h" +#include "bapRsnTxRx.h" +#include "bapRsnSsmAesKeyWrap.h" +#include "btampFsm.h" + +// The different states that this FSM transitions through +#define DISCONNECT 0 +#define DISCONNECTED 1 +#define INITIALIZE 2 +#define AUTHENTICATION 3 +#define AUTHENTICATION_2 4 +#define GET_PSK 5 +#define GET_EAP_KEY 6 +#define PTK_START 7 +#define PTK_INIT_NEGO 8 +#define PTK_INIT_NEGO_TX 9 +#define PTK_INIT_DONE 10 +#define UPDATE_KEYS_REQ 11 +#define INTEG_FAILURE 12 +#define KEY_UPDATE 13 +#define NUM_STATES (KEY_UPDATE + 1) + + + +static tAuthRsnFsmConsts authConsts = { 2000, 3 }; //timeout, retry limit +static v_U8_t aniSsmIeRsnOui[] = ANI_SSM_IE_RSN_OUI; + + +/************************************** + * Static functions in this module + **************************************/ + +static +int zeroOutPtk(tAuthRsnFsm *fsm); +static +int stopAllTimers(tAuthRsnFsm *fsm); + +static +int checkMic(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkLocalReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); +static +int checkPeerReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static int checkInfoElement(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int derivePtk(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + + +static int checkTransition(tAuthRsnFsm *fsm, void *arg); + +static int +gotoStateInit(tAuthRsnFsm *fsm); + +static void msg2TimerCallback( void * ); +static void msg4TimerCallback( void * ); + +static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); +static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); + +/******************************** + * Functions Forward Declarations + ********************************/ + +int authRsnAuthStartEventHandler( tAuthRsnFsm *fsm ); +int authRsnAuthDisconEventHandler( tAuthRsnFsm *fsm ); + +/************************* + * The exported functions + *************************/ + +/** + * authRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param consts the various constant values needed by this FSM + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmInit(tAuthRsnFsmConsts *constsIn) +{ + // TODO: Read the constants in from config + // authConsts = *constsIn; + authConsts.timeoutPeriod = 2000; //ms + authConsts.maxTries = 3; + + return ANI_OK; +} + +/** + * authRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given STA context. + * + * @parm staCtx the STA context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this STA is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmCreate(tBtampContext *ctx) +{ + int retVal = ANI_OK; + tAuthRsnFsm *fsm = &ctx->uFsm.authFsm; + + // First, clear everything out + vos_mem_zero( fsm, sizeof(tAuthRsnFsm)); + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterTxRxCallbacks( authRsnTxCompleteHandler, + authRsnRxFrameHandler ) ) ) + { + return ANI_ERROR; + } + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterRxCallback( ctx->pvosGCtx ) ) ) + { + return ANI_ERROR; + } + + // Allocate the station context + fsm->staCtx = (tStaContext *)vos_mem_malloc( sizeof(tStaContext) ); + if (fsm->staCtx == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + // Clear out the station context + vos_mem_zero( fsm->staCtx, sizeof(tStaContext) ); + + fsm->ctx = ctx; + fsm->staCtx->authRsnFsm = fsm; + //Only support CCMP + fsm->staCtx->pwCipherType = eCSR_ENCRYPT_TYPE_AES; + + if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg2Timer, VOS_TIMER_TYPE_SW, msg2TimerCallback, fsm ) ) ) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg4Timer, VOS_TIMER_TYPE_SW, msg4TimerCallback, fsm ) ) ) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocate(&fsm->staCtx->pmk); + if (fsm->staCtx->pmk == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocateExplicit(&fsm->staCtx->ieSta, + RSN_IE_MAX_PACKET_SIZE, + RSN_IE_HEADER_SIZE ); + if (fsm->staCtx->ieSta == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->cryptHandle = 0; + if( !VOS_IS_STATUS_SUCCESS( vos_crypto_init( &fsm->cryptHandle ) ) ) + { + retVal = ANI_E_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->currentState = INITIALIZE; + gotoStateInit(fsm); + + //We can call this function here because it is connected at this time + authRsnFsmProcessEvent( fsm, RSN_FSM_AUTH_START, NULL ); + + return ANI_OK; + + error: + authRsnFsmFree(ctx); + + return retVal; + +} + +/** + * authRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a STA context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the STA context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmFree(tBtampContext *ctx) +{ + tAuthRsnFsm *fsm = &ctx->uFsm.authFsm; + + VOS_ASSERT(fsm); + + if( fsm->cryptHandle) + { + vos_crypto_deinit( fsm->cryptHandle ); + } + + bapRsnClearTxRxCallbacks(); + + if ( fsm->staCtx ) + { + fsm->staCtx->authRsnFsm = NULL; + } + + if ( VOS_TIMER_STATE_UNUSED != fsm->msg2Timer.state ) vos_timer_destroy( &fsm->msg2Timer ); + if ( VOS_TIMER_STATE_UNUSED != fsm->msg4Timer.state ) vos_timer_destroy( &fsm->msg4Timer ); + + if (fsm->lastEapol) + { + aniAsfPacketFree(fsm->lastEapol); + fsm->lastEapol = NULL; + } + + if( fsm->staCtx ) + { + if( fsm->staCtx->pmk ) + { + aniAsfPacketFree( fsm->staCtx->pmk ); + fsm->staCtx->pmk = NULL; + } + vos_mem_free(fsm->staCtx); + fsm->staCtx = NULL; + } + + vos_mem_zero( fsm, sizeof(tAuthRsnFsm) ); + + return ANI_OK; +} + +/** + * authRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmProcessEvent(tAuthRsnFsm *fsm, tRsnFsmEvent eventId, void *arg) +{ + VOS_ASSERT(fsm); + + switch (eventId) { + case RSN_FSM_TIMER_EXPIRED: + // Proceed straight to checkTransition + break; + case RSN_FSM_AUTH_START: + fsm->authReq = eANI_BOOLEAN_TRUE; + authRsnAuthStartEventHandler(fsm); + break; + case RSN_FSM_EAPOL_FRAME_AVAILABLE: + fsm->eapolAvail = eANI_BOOLEAN_TRUE; + break; + case RSN_FSM_DISCONNECT: + fsm->disconnect = eANI_BOOLEAN_TRUE; + authRsnAuthDisconEventHandler(fsm); + break; + case RSN_FSM_INTEG_FAILED: + fsm->integFailed = eANI_BOOLEAN_TRUE; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unknown event for Auth RSN Key Fsm: %d\n", eventId); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + break; + } + + checkTransition(fsm, arg); + + return ANI_OK; +} + + +int +authRsnAuthStartEventHandler(tAuthRsnFsm *fsm) +{ + static v_U8_t btampStaRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 }; + // Copy required info + vos_mem_copy( &fsm->staCtx->authMac, fsm->ctx->self_mac_addr, 6); + vos_mem_copy( &fsm->staCtx->suppMac, fsm->ctx->peer_mac_addr, 6); + aniAsfPacketAppendBuffer( fsm->staCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); + + aniAsfPacketAppendBuffer( fsm->staCtx->ieSta, btampStaRSNIE, sizeof(btampStaRSNIE)); + return ANI_OK; +} + +int +authRsnAuthDisconEventHandler(tAuthRsnFsm *fsm) +{ + // Free Stactx .? + return ANI_OK; +} + +/*********************** + * The static functions + ***********************/ + +static int +gotoStateInit(tAuthRsnFsm *fsm) +{ + fsm->currentState = INITIALIZE; + + // TODO: Move this to a global position which applies to WEP as + // well + //initGlobalKeys = eANI_BOOLEAN_FALSE; + + fsm->authReq = eANI_BOOLEAN_FALSE; + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + fsm->disconnect = eANI_BOOLEAN_FALSE; + fsm->integFailed = eANI_BOOLEAN_FALSE; + + fsm->numTries = 0; + + // Create two replay counter's..one for our requests, and another + // for STA's requests. Initialize the first one randomly. + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->localReplayCtr, + ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->peerReplayCtr, + ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + + return ANI_OK; +} + +static int +gotoStateAuthentication(tAuthRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION; + + zeroOutPtk(fsm); + fsm->authReq = eANI_BOOLEAN_FALSE; + + checkTransition(fsm, NULL); // UCT rule + + return ANI_OK; +} + +static int +gotoStateAuthentication2(tAuthRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION_2; + + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "gotoStateAuthentication2 fail to get random number. Disconnect\n" ); + bapAuthDisconnect( fsm->ctx ); + return ANI_ERROR; + } + fsm->numTries = 0; + + checkTransition(fsm, NULL); // UCT rule + + return ANI_OK; +} + + +static int +gotoStateGetPsk(tAuthRsnFsm *fsm) +{ + //This is simply a transaction because we already have the PMK. We always do. + fsm->currentState = GET_PSK; + + fsm->numTries = 0; + + checkTransition(fsm, NULL); + + return ANI_OK; +} + +static int +gotoStatePtkStart(tAuthRsnFsm *fsm) +{ + tAniEapolRsnKeyDesc txDesc; + int retVal; + + fsm->msg2TimeOut = VOS_FALSE; + fsm->currentState = PTK_START; + + // Create a new packet if we don't have one to retransmit + //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) +#if 0 + if( fsm->lastEapol ) + { + aniAsfPacketFree( fsm->lastEapol ); + fsm->lastEapol = NULL; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); +#endif + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + //} + // if (1) + //{ + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + else { + return ANI_E_ILLEGAL_ARG; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.ackFlag = eANI_BOOLEAN_TRUE; + + // The other fields... + txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType); + aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter); + vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->staCtx->suppMac, + fsm->staCtx->authMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + NULL, 0); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } +#if 0 + } + else { + retransmit = eANI_BOOLEAN_TRUE; + } +#endif + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + //we fail to send the eapol frame disconnect + bapAuthDisconnect( fsm->ctx ); + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStatePtkInitNego(tAuthRsnFsm *fsm, void *arg) +{ + fsm->currentState = PTK_INIT_NEGO; + + // Replay counter will be automatically updated when we create a + // new packet + + fsm->numTries = 0; + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + + checkTransition(fsm, arg); + + return ANI_OK; +} + +// Use this only with trusted IE like the one we generated locally +static int +getRsnIeFromAdvertizedIes(tAuthRsnFsm *fsm, v_U8_t **rsnIe) +{ + int retVal = ANI_E_ILLEGAL_ARG; + v_U8_t *ptr = fsm->advertizedRsnIe; + + if (*ptr == ANI_SSM_IE_RSN_ELEM_ID) + { + retVal = *(ptr + 1) + 2; // The L field from the TLV + 2B TL + *rsnIe = ptr; + } + + return retVal; +} + +// Use this only with trusted IE like the one we generated locally +static void +addPad( + v_U8_t *dataBytes, + int dataLen, + int padLen) +{ + int i; + + // The first byte of padding is 0xdd. The rest are 0x00's + // See 802.11i section 8.5.2 subsection "Key Data Encapsulation" + + for ( i=dataLen ; i < dataLen+padLen; i++) + { + if ( i == dataLen ) + { + dataBytes[i] = 0xdd; + } + else { + dataBytes[i] = 0x00; + } + } + + return; +} + +/** + * aagAppendGroupKeyForRsn + * + * Appends the group key to the packet in the RSN key encapulation format. + * + * @param packet - the packet to append to + * @param radioId - the radio whose group key needs to be appended + * + * @return ANI_OK if the operation succeeds + */ +#define STATIC_WEP_KEY_LEN 16 +#define GROUP_KEY_ID 0 +#define ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID 0xDD +#define ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID 1 + +int +aagAppendGroupKeyForRsn(tAniPacket *packet) +{ +#if 0 + tAniPacket *groupKey = NULL; +#else + tANI_U8 groupKey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; +#endif + tANI_U8 *groupKeyBytes = NULL; + tANI_U8 *lenPtr = NULL; + tANI_U8 *endPtr = NULL; + int groupKeyLen; + int retVal; + +#if 0 + groupKey = AAG_GROUP_KEY(radioId); + if (groupKey == NULL) { + ANI_AAG_LOG_E("Group key is not yet set on radio %d, id %d!", + radioId, AAG_GROUP_KEY_ID(radioId)); + assert(0 && "Group key is still NULL!"); + return ANI_E_FAILED; + } + + groupKeyLen = aniAsfPacketGetBytes(groupKey, &groupKeyBytes); + CHECK_NO_ERROR(groupKeyLen); + + if (aagConfig.logLevel >= LOG_INFO) { + ANI_AAG_LOG_D("Will encapsulate group key bytes %s", + aniAsfHexStr(groupKeyBytes, groupKeyLen)); + } +#else + groupKeyBytes = groupKey; + + groupKeyLen = STATIC_WEP_KEY_LEN; +#endif + + /* + * Add the key data encapsulation needed for RSN/WPA2 + */ + + // The IE ID + retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID); + //CHECK_NO_ERROR(retVal); + + // Obtain the position for the length + aniAsfPacketGetBytesFromTail(packet, &lenPtr); + + // Write out a dummy length - we'll fill this in later. It will be + // 6 bytes more than the length of the GTK + retVal = aniAsfPacketAppend8(packet, 0); + //CHECK_NO_ERROR(retVal); + + // Copy the RSN OUI + retVal = aniAsfPacketAppendBuffer(packet, aniSsmIeRsnOui, sizeof(aniSsmIeRsnOui)); + //CHECK_NO_ERROR(retVal); + + // Indicate that the key type is group key + retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID); + //CHECK_NO_ERROR(retVal); + + // Copy the key-id to the first two bits of the next byte + // Copy the Tx bit the third bit of the same byte + // (Here, I assume the Group Key is to be used for both STA Tx and Rx) + retVal = aniAsfPacketAppend8( + packet, + GROUP_KEY_ID ); + //AAG_GROUP_KEY_ID(radioId) ); + //CHECK_NO_ERROR(retVal); + + retVal = aniAsfPacketMoveRight(packet, 1); // Reserved bits (1 byte) + //CHECK_NO_ERROR(retVal); + + // Copy the real key bytes + retVal = aniAsfPacketAppendBuffer(packet, groupKeyBytes, groupKeyLen); + //CHECK_NO_ERROR(retVal); + + // Calculate and enter the length of the entire encoding + aniAsfPacketGetBytesFromTail(packet, &endPtr); + *lenPtr = endPtr - (lenPtr + 1) ; // subtract one to avoid tail + + return retVal; +} + +static int +gotoStatePtkInitNegoTx(tAuthRsnFsm *fsm) +{ + tAniEapolRsnKeyDesc txDesc; + v_BOOL_t retransmit = eANI_BOOLEAN_FALSE; + v_U8_t *rsnWpaIe = NULL; + int rsnWpaIeLen; + static tAniPacket *keyData; + // The longest length...the extra 8 bytes account for RSN key data + // encapsulation + v_U8_t paddedGroupKeyEncaps[1024]; + int padLen = 0; + v_U8_t *groupKeyBytes; + int groupKeyLen; + v_U8_t *wrappedKey = NULL; + // Variables used for RC4 GTK wrap + //v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE]; + //v_U32_t keyIvLsb; + int retVal = 0; + + //invalidate this + fsm->msg4TimeOut = VOS_FALSE; + fsm->currentState = PTK_INIT_NEGO_TX ; + + if (keyData == NULL) + { + // Allocate the packet the first time around that you enter + retVal = aniAsfPacketAllocateExplicit(&keyData, 1024, 10); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + } + else { + // Just empty out the packet + aniAsfPacketEmptyExplicit(keyData, 10); + } + + do + { + // Create a new EAPOL frame if we don't have one to retransmit + //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) +#if 0 + if( fsm->lastEapol ) + { + aniAsfPacketFree( fsm->lastEapol ); + fsm->lastEapol = NULL; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); +#endif + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + // } + + if (1) + { + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + else { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_RC4; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.installFlag = eANI_BOOLEAN_TRUE; + txDesc.info.ackFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + + txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType); + aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter); + vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce)); + + // Add the RSN IE (but not any WPA IE) + rsnWpaIeLen = getRsnIeFromAdvertizedIes(fsm, &rsnWpaIe); + + if( !ANI_IS_STATUS_SUCCESS( rsnWpaIeLen) ) break; + + retVal = aniAsfPacketAppendBuffer(keyData, rsnWpaIe, rsnWpaIeLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + // Add the RSN group key encapsulation + retVal = aagAppendGroupKeyForRsn ( keyData ); + + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + groupKeyLen = aniAsfPacketGetBytes(keyData, &groupKeyBytes); + if( !ANI_IS_STATUS_SUCCESS( groupKeyLen ) ) + { + retVal = ANI_E_FAILED; + break; + } + + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.info.encKeyDataFlag = eANI_BOOLEAN_TRUE; + + if ( fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES ) + { + /* + * Use the AES key wrap algorithm if either one of the pairwise + * key or the group key is an AES key. + * + * If the key being sent is not a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then pad it with + * zeroes. e.g., if we are sending a WEP key of 5 or 13 + * bytes. + */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "AES Key Wrap invoked. groupKeyLen = %d", groupKeyLen); + + padLen = groupKeyLen % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if (padLen != 0) { + padLen = ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - padLen; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Before AES Key Wrap: padLen = %d", padLen); + + if (groupKeyLen + padLen > sizeof(paddedGroupKeyEncaps)) { +#if 0 + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Cannot encode group key encapsulation of len %d and cipher type %s " + "to send to %s %s (aid %d, radio %d, user %s)", + groupKeyLen, + aniSsmIntGetCipherStr(AAG_GROUP_CIPHER(fsm->ctx->radioId)), + (fsm->ctx->bpIndicator ? "BP" : "STA"), + aniAsfHexStr(fsm->ctx->suppMac, sizeof(tAniMacAddr)), + fsm->ctx->aid, + fsm->ctx->radioId, + aagGetStaUserId(fsm->ctx)); +#endif + retVal = ANI_E_FAILED; + } + // OK, after you compute the pad length, you need to + // add the padding - 0xdd followed by 0x00's + addPad( groupKeyBytes , groupKeyLen , padLen ); + // add the padding length + groupKeyLen += padLen; + // IMMEDIATELY adjust the packet size to reflect the pad + aniAsfPacketMoveRight(keyData, padLen); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Before AES Key Wrap: padded groupKeyLen = %d", groupKeyLen); + + retVal = aniSsmAesKeyWrap(fsm->cryptHandle, groupKeyBytes, groupKeyLen, + fsm->staCtx->ptk + ANI_EAPOL_KEY_RSN_MIC_SIZE, + ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE, + &wrappedKey); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + // This doesn't work... + //groupKeyBytes = wrappedKey; + //groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + // ...here is the right way to do it + // Add the length of the prepended IV A[0] + if (NULL == wrappedKey) + { + break; + } + groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + memcpy( groupKeyBytes, wrappedKey, groupKeyLen); + // Free the array used to hold the wrapped key + if (wrappedKey) vos_mem_free( wrappedKey); + // IMMEDIATELY adjust the packet size to reflect the IV + aniAsfPacketMoveRight(keyData, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth RC4 Key Wrap invoked. groupKeyLen = %d", groupKeyLen); + } + txDesc.keyDataLen = aniAsfPacketGetBytes(keyData, &txDesc.keyData); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->staCtx->suppMac, + fsm->staCtx->authMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->staCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + } + else { + retransmit = eANI_BOOLEAN_TRUE; + } + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + //we fail to send the eapol frame disconnect + bapAuthDisconnect( fsm->ctx ); + retVal = ANI_ERROR; + } + + }while( 0 ); + + return retVal; +} + +static int +gotoStatePtkInitDone(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + int retVal; + tAniEapolRsnKeyDesc *rxDesc; + tCsrRoamSetKey setKeyInfo; + + fsm->currentState = PTK_INIT_DONE; + + rxDesc = data->keyDesc; + + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->staCtx->suppMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->staCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + if( VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + //Done + aniAsfPacketEmptyExplicit(fsm->lastEapol, EAPOL_TX_HEADER_SIZE); + retVal = ANI_OK; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth: gotoStatePtkInitDone fail to set key\n" ); + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateUpdateKeysReq(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *rxDesc; + + fsm->currentState = UPDATE_KEYS_REQ; + + rxDesc = data->keyDesc; + + aniSsmReplayCtrUpdate(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter); + + checkTransition(fsm, data); + + return ANI_OK; +} + +static int +gotoStateIntegFailure(tAuthRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + fsm->currentState = INTEG_FAILURE; + + fsm->integFailed = eANI_BOOLEAN_FALSE; + + checkTransition(fsm, NULL); // UCT + + return ANI_OK; +} + +static int +gotoStateKeyUpdate(tAuthRsnFsm *fsm) +{ + fsm->currentState = KEY_UPDATE; + + if( VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) ) ) + { + + // Replay counter will be automatically updated when we create a + // new packet + + checkTransition(fsm, NULL); // UCT + + return ANI_OK; + } + return ANI_ERROR; +} + +static int +gotoStateDisconnect(tAuthRsnFsm *fsm) +{ + fsm->currentState = DISCONNECT; + + //What else do we need to clean up? Or BAP will call our vleanup function? + + // FSM does not exist after this... + bapAuthDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static +int zeroOutPtk(tAuthRsnFsm *fsm) +{ + return ANI_OK; +} + +static +int stopAllTimers(tAuthRsnFsm *fsm) +{ + vos_timer_stop( &fsm->msg2Timer ); + vos_timer_stop( &fsm->msg4Timer ); + + return ANI_OK; +} + +static +int derivePtk(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + v_U32_t prfLen; + tAniEapolRsnKeyDesc *rxDesc; + + if (NULL == fsm->staCtx->pmk) + { + VOS_ASSERT(0); + return ANI_E_NULL_VALUE; + } + + switch (fsm->staCtx->pwCipherType) + { + case eCSR_ENCRYPT_TYPE_AES: + prfLen = AAG_RSN_PTK_PRF_LEN_CCMP; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth cannot generate PTK for invalid algorithm %d\n", + fsm->staCtx->pwCipherType); + return ANI_E_ILLEGAL_ARG; + break; + }; + + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + return aagPtkPrf(fsm->cryptHandle, + fsm->staCtx->ptk, + prfLen, + fsm->staCtx->pmk, + fsm->staCtx->authMac, + fsm->staCtx->suppMac, + fsm->aNonce, + rxDesc->keyNonce); +} + +static int +checkMic(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal; + + retVal = aniEapolKeyCheckMic(fsm->cryptHandle, + data->eapolFrame, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + data->keyDesc, + fsm->staCtx->ptk, + CSR_AES_KEY_LEN); + + if (retVal == ANI_E_MIC_FAILED) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed EAPOL-MIC check in pairwise key exchange!\n"); + } + + return retVal; +} + +static int +checkLocalReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal = ANI_E_NULL_VALUE; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( rxDesc ) + { + cmp = aniSsmReplayCtrCmp(fsm->staCtx->localReplayCtr, rxDesc->replayCounter); + + // The STA should have sent back the same replay ctr as in our request + if (cmp != 0) + { + retVal = ANI_E_REPLAY_CHECK_FAILED; + } + else + { + retVal = ANI_OK; + } + } + + return retVal; +} + +static +int checkPeerReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal = ANI_E_NULL_VALUE; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( rxDesc ) + { + cmp = aniSsmReplayCtrCmp(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter); + + // The STA should have sent a newer replay ctr than its old + // request. The first message is exempted from the check. + if (fsm->staCtx->pastFirstPeerRequest && cmp >= 0) + { + retVal = ANI_E_REPLAY_CHECK_FAILED; + } + + fsm->staCtx->pastFirstPeerRequest = eANI_BOOLEAN_TRUE; + } + + return retVal; +} + +static int checkInfoElement(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *desc; + v_U8_t *ieStaBytes; + int ieStaLen; + + desc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( desc ) + { + ieStaLen = aniAsfPacketGetBytes(fsm->staCtx->ieSta, &ieStaBytes); + if( !ANI_IS_STATUS_SUCCESS( ieStaLen ) ) + { + return ieStaLen; + } + + if ((desc->keyDataLen != ieStaLen) || + ( !vos_mem_compare(desc->keyData, ieStaBytes, ieStaLen-2) )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth STA sent inconsistent RSN IE!\n"); + return ANI_E_FAILED; + } + // Copy RSN IE + //vos_mem_copy(fsm->advertizedRsnIe, desc->keyData, ieStaLen); + vos_mem_copy(fsm->advertizedRsnIe, ieStaBytes, ieStaLen); + + return ANI_OK; + } + else + { + return ANI_E_NULL_VALUE; + } + +} + +static +int checkTransition(tAuthRsnFsm *fsm, void *arg) +{ + int retVal; + tAniEapolKeyAvailEventData *data; + tAniEapolRsnKeyDesc *rxDesc; + tSirMicFailureInfo *micFailureInfo; + + if (fsm->disconnect) + { + stopAllTimers(fsm); + gotoStateDisconnect(fsm); + return ANI_OK; + } + + if (fsm->authReq) + { + stopAllTimers(fsm); + gotoStateAuthentication(fsm); + return ANI_OK; + } + + switch (fsm->currentState) + { + case INITIALIZE: + break; + case AUTHENTICATION: + gotoStateAuthentication2(fsm); + break; + case AUTHENTICATION_2: + gotoStateGetPsk( fsm ); + break; + case GET_PSK: + //We always have PMK otherwise BAP won't let us here + gotoStatePtkStart(fsm); + break; + case PTK_START: + if ( fsm->eapolAvail ) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkLocalReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + retVal = derivePtk(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth derivePtk failed with code %d!\n", retVal); + return retVal; + } + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx ); + return retVal; + } + retVal = gotoStatePtkInitNego(fsm, arg); + } + else if ( fsm->msg2TimeOut ) + { + if (fsm->numTries <= authConsts.maxTries) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth Retransmitting EAPOL-Key Msg1\n"); + // Stay in the same state but repeat actions + gotoStatePtkStart(fsm); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed to recv EAPOL-Key Msg2 " + "Disconnecting...\n"); + + gotoStateDisconnect(fsm); + } + } + break; + case PTK_INIT_NEGO: + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkInfoElement(fsm, data); + if (retVal != ANI_OK) + { + gotoStateDisconnect(fsm); + } + else { + gotoStatePtkInitNegoTx(fsm); + } + break; + case PTK_INIT_NEGO_TX: + if (fsm->eapolAvail) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkLocalReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx ); + return retVal; + } + retVal = gotoStatePtkInitDone(fsm, data); + } else if ( fsm->msg4TimeOut ) + { + if (fsm->numTries <= authConsts.maxTries) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth retransmitting EAPOL-Key Msg3 \n"); + // Stay in the same state but repeat actions + gotoStatePtkInitNegoTx(fsm); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed to recv EAPOL-Key Msg4 " + "Disconnecting...\n" ); + + gotoStateDisconnect(fsm); + } + } + break; + case PTK_INIT_DONE: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.requestFlag) + { + + retVal = checkPeerReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx->pvosGCtx ); + return retVal; + } + + retVal = gotoStateUpdateKeysReq(fsm, arg); + } + } + else if (fsm->integFailed) { + + micFailureInfo = (tSirMicFailureInfo *) arg; + gotoStateIntegFailure(fsm, arg); + + } + break; + case UPDATE_KEYS_REQ: + + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.errorFlag) + { + + /* + * This was generated by a unicast packet sent from the AP to the STA/BP. + * The TX address is the AP's address. The src address is lost. + * If the STA is a BP, then the true dst is lost. We will treat + * the dst field as the address of the reporter of the MIC failure. + */ + + micFailureInfo = (tSirMicFailureInfo *) vos_mem_malloc( sizeof(tSirMicFailureInfo) ); + if( NULL == micFailureInfo ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Fail to allocate memory for AuthRsnFsm: %d\n", + fsm->currentState); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(micFailureInfo->taMacAddr, fsm->staCtx->authMac, sizeof(tAniMacAddr)); + vos_mem_copy(micFailureInfo->dstMacAddr, fsm->staCtx->suppMac, sizeof(tAniMacAddr)); + micFailureInfo->multicast = eANI_BOOLEAN_FALSE; + // Copy whatever sequence number came in the EAPOL-key message + vos_mem_copy(micFailureInfo->TSC, rxDesc->keyRecvSeqCounter, SIR_CIPHER_SEQ_CTR_SIZE); + gotoStateIntegFailure(fsm, micFailureInfo); + vos_mem_free(micFailureInfo); + } + else { + // TBD: Untested. Why are local aNonce and local replyCtr not incremented in spec? + gotoStatePtkStart(fsm); + } + break; + case INTEG_FAILURE: + gotoStateKeyUpdate(fsm); + break; + case KEY_UPDATE: + gotoStatePtkStart(fsm); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Nothing to do in this state for AuthRsnFsm: %d\n", + fsm->currentState); + // Catch all for states that need no change: + // assert(eANI_BOOLEAN_FALSE && "Illegal AuthRsnFsm state!"); + return ANI_E_FAILED; + } + + return ANI_OK; +} + + +static void msg2TimerCallback( void *pv ) +{ + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return; + } + + //Only when waiting for msg2 + if( PTK_START == fsm->currentState ) + { + fsm->msg2TimeOut = eANI_BOOLEAN_TRUE; + } + //We may need to synchronize this call + authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL ); +} + +static void msg4TimerCallback( void *pv ) +{ + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return; + } + + //Only when we are waiting for msg4 + if( PTK_INIT_NEGO_TX == fsm->currentState ) + { + fsm->msg4TimeOut = eANI_BOOLEAN_TRUE; + } + //We may need to synchronize this call + authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL ); +} + + +// +//This function alwasy assume the incoming vos_packet is 802_3 frame. +static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + int retVal = ANI_ERROR; + tAniPacket *pAniPacket; + tBtampContext *ctx; + tAuthRsnFsm *fsm; + + /* Validate params */ + if ((pvosGCtx == NULL) || (NULL == pPacket)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return retVal; + } + + ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return retVal; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return retVal; + } + + do + { + //ToDO: We need to synchronize this. For now, use the simplest form, drop the packet comes later. + if( fsm->fReceiving ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " ******authRsnRxFrameHandler receive eapol packet while processing. Drop the new comer\n" ); + break; + } + fsm->fReceiving = VOS_TRUE; + retVal = bapRsnFormPktFromVosPkt( &pAniPacket, pPacket ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Now we can process the eapol frame + //handler will free the pAniPacket + bapRsnEapolHandler( fsm, pAniPacket, VOS_TRUE ); + }while( 0 ); + + fsm->fReceiving = VOS_FALSE; + vos_pkt_return_packet( pPacket ); + + return retVal; +} + + +static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + tBtampContext *ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + tAuthRsnFsm *fsm; + + vos_pkt_return_packet( pPacket ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return ANI_ERROR; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return ANI_ERROR; + } + + if(!VOS_IS_STATUS_SUCCESS( retStatus ) ) + { + //No need to do anything. Retransmit is handled by timeout + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth: TL Tx complete with error %d current state is %d \n", retStatus, fsm->currentState ); + } + if( PTK_START == fsm->currentState ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " Auth: start msg2 timer\n" ); + //Start msg2Timer + fsm->numTries++; + vos_timer_stop( &fsm->msg2Timer ); + vos_timer_start(&fsm->msg2Timer, authConsts.timeoutPeriod); + } + else if( ( PTK_INIT_NEGO == fsm->currentState ) || + ( PTK_INIT_NEGO_TX == fsm->currentState ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " Auth: start msg4 timer\n" ); + fsm->numTries++; + vos_timer_stop( &fsm->msg4Timer ); + vos_timer_start(&fsm->msg4Timer, authConsts.timeoutPeriod); + } + + return ANI_OK; +} + + +static int +authEapolKeyHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, tAniMacAddr staMac ) +{ + int retVal; + + int descType; + void *keyDesc; + tAniEapolRsnKeyDesc *rsnDesc; + tAniEapolKeyAvailEventData data; + + do + { + retVal = aniEapolParseKey(eapolFrame, &descType, &keyDesc); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + rsnDesc = (tAniEapolRsnKeyDesc *) keyDesc; + data.keyDesc = keyDesc; + data.eapolFrame = eapolFrame; + // Pass on the event to the RSN FSM only if it is for a pairwise key + if (rsnDesc->info.unicastFlag) + { + retVal = authRsnFsmProcessEvent(fsm, + RSN_FSM_EAPOL_FRAME_AVAILABLE, + &data); + } + else { + //Not worry about GTK stuff + } + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Got unexpected legacy 802.1x RC4 Key message \n" ); + retVal = ANI_E_FAILED; + break; + } + }while( 0 ); + + aniEapolKeyFreeDesc(descType, keyDesc); + return retVal; +} + + +void authEapolHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type) +{ + switch (*type) + { + case ANI_EAPOL_TYPE_START: + //No doing anything because we only support WPA2-PSK + break; + case ANI_EAPOL_TYPE_LOGOFF: + //ignore + break; + case ANI_EAPOL_TYPE_KEY: + authEapolKeyHandler(fsm, eapolFrame, srcMac); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth: EAPOL type not implemented: 0x%.2x\n", *type); + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.h new file mode 100644 index 0000000000000..9758cca7a6757 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xAuthFsm.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xAuthRsnFsm.h $ + * + * Contains declarations for the RSN EAPOL-Key FSM on the + * authenticator side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_AUTH_RSN_FSM_H +#define __AAG_AUTH_RSN_FSM_H + +#include "vos_types.h" +#include "vos_timer.h" + +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" + + + +/** + * authRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param consts the various constant values needed by this FSM + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmInit(tAuthRsnFsmConsts *consts); + +/** + * authRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given STA context. + * + * @parm ctx the STA context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this STA is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmCreate(tBtampContext *ctx); + + + +int +authRsnFsmSetPmk(tStaContext *ctx, v_U8_t *pmk); + +#endif //__AAG_AUTH_RSN_FSM_H diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xFsm.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xFsm.h new file mode 100644 index 0000000000000..bbfab979d8d60 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xFsm.h @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xFsm.h $ + * Contains the declarations for the Auth Agent's FSM's to work. + * + * Author: Mayank D. Upadhyay + * Date: 21-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_FSM_H_ +#define __AAG_FSM_H_ + +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_timer.h" +#include +#include +#include +#include "bapRsn8021xPrf.h" +//#include "bapInternal.h" +#include "csrApi.h" + +typedef struct sBtampContext tBtampContext; +typedef struct tStaContext tStaContext; +typedef struct tSuppContext tSuppContext; + +#define RSN_MAX_PACKET_SIZE 512 +#define RSN_80211_KEY_LEN 16 +#define RSN_IE_MAX_PACKET_SIZE 256 +#define RSN_IE_HEADER_SIZE 0 +#define ACCTG_SESSION_ID_SIZE 8 +#define ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE 8 // Bytes + +#define BAP_SET_RSN_KEY 1 +#define BAP_RESET_RSN_KEY 0 + + +#define AAG_ACL_LOOKUP_NEEDED(ctx) \ + ((ctx)->authType == eANI_SSM_AT_NONE || \ + (ctx)->authType == eANI_SSM_AT_RSN_PSK || \ + (ctx)->authType == eANI_SSM_AT_SHARED_KEY) + +#define AAG_ACL_LOOKUP_PENDING(ctx) \ + ((ctx)->aclLookupFsm != NULL && (ctx)->radiusInfo.req != NULL) + +#define AAG_STA_AWAITING_CLEANUP(ctx) \ + ((ctx)->ssid == NULL) + +#define AAG_MARK_STA_AS_AWAITING_CLEANUP(ctx) \ + ((ctx)->ssid = NULL) + +/************************ + * AuthRsnFsm structure: + *************************/ +typedef struct tagAuthRsnFsm +{ + v_U8_t currentState; + + tBtampContext *ctx; + tStaContext *staCtx; + + // Variables used for EAPOL-Key messages + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + + // Flags set by external events + v_U8_t authReq; + v_U8_t eapolAvail; + v_U8_t disconnect; + v_U8_t integFailed; + v_U8_t pmkAvailable; + + // Variables maintained internally + v_U8_t numTries; + tAniPacket *lastEapol; //Tx + v_BOOL_t fReceiving; + v_U32_t cryptHandle; + + // Timers used..alternate them in different states + vos_timer_t msg2Timer; + vos_timer_t msg4Timer; + v_BOOL_t msg2TimeOut; + v_BOOL_t msg4TimeOut; + v_U8_t advertizedRsnIe[256]; +} tAuthRsnFsm; + +/************************ + * SuppRsnFsm structure: + *************************/ + +typedef struct tagSuppRsnFsm { + + v_U8_t currentState; + + tBtampContext *ctx; + tSuppContext *suppCtx; + + // Variables used for EAPOL-Key messages + tAniSsmReplayCtr *localReplayCtr; + tAniSsmReplayCtr *peerReplayCtr; + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + + // Flags set by external events + v_U8_t authReq; + v_U8_t pmkAvail; + v_U8_t eapolAvail; + v_U8_t integFailed; + v_U8_t updateKeys; + + // Variables maintained internally + int numTries; + tAniPacket *lastEapol; + v_BOOL_t fReceiving; + v_U32_t cryptHandle; +} tSuppRsnFsm; + + +typedef struct sAagZoneEntry tAagZoneEntry; +typedef struct sAagSsidEntry tAagSsidEntry; + +typedef enum +{ + //Internal to RSN + //This event is triggered by RSN’s timers + RSN_FSM_TIMER_EXPIRED, + //BAP use this event to inform auth/supp to start processing + //authentication. When BAP send this event to RSN, it is presumed + //that the PMK is available. + RSN_FSM_AUTH_START, + //Internal to RSN + //This event is triggered by the Rx routine when called by TL + RSN_FSM_EAPOL_FRAME_AVAILABLE, + //BAP use this event to inform RSN that the connection is lost + RSN_FSM_DISCONNECT, + //Internal to RSN + //This event hannpens when RSN detect key integraty check fails + RSN_FSM_INTEG_FAILED, + +}tRsnFsmEvent; + +/** + * Stores information about an EAP message that was last received or + * EAPOL messages that were last sent. + * + * 1. EAP messages last received are stripped out of their outer + * encapsulation which may be either EAPOL or RADIUS, and are + * preserved within this structure for the lifetime of one event: + * - EAPOL_MESSAGE_AVAILABLE => process and send to RADIUS + * - RADIUS_MESSAGE_AVAILABLE => process and send to STA + * When the event is fully handled, the incoming packet is freed, + * therefore, the contents of this structure are no longer valid. + * + * 2. EAPOL messages last sent are stored in their entirety. They are + * created and delete a little differently on the AP and BP sides: + * - AP side: The EAPOL message contains the last EAP message + * that was sent to the STA. As soon as a new EAP message arrives + * from RADIUS, this EAPOL mesage is freed because a new one will + * be generated. + * - BP side: The EAPOL message contains the last EAP message + * generated by the local supplicant. As soon as a new EAPOL + * message is generated, this one is freed and the new one is + * stored. + */ +typedef struct tEapInfo + +{ + tAniPacket *message; + v_U8_t id; +} tEapInfo; + + +typedef enum eAniSsmAuthState { + eANI_SSM_AUTH_STATE_INIT = 0, + eANI_SSM_AS_PW_KEY_CONF_AWAITED, + eANI_SSM_AS_PW_KEY_SET, +} tAniSsmAuthState; + + +/** + * The Station's context is stored in this structure. It contains + * pointers to the FSM's used by the STA (which in turn point back to + * the context). It also contains the transient event data like + * EAP-Message and RADIUS state that is obtained from various network + * packets. + */ +struct tStaContext { + + // STA identification information + tAniMacAddr suppMac; + v_BOOL_t bpIndicator; + + // Local association point + tAniMacAddr authMac; + v_U8_t ssidName[SIR_MAC_MAX_SSID_LENGTH + 1]; + tAagSsidEntry *ssid; + + // The different FSM's that can be instantiated for the STA + tAuthRsnFsm *authRsnFsm; + + // Keys derived for STA + v_U8_t ptk[AAG_PRF_MAX_OUTPUT_SIZE]; + tAniPacket *pmk; // MS-MPPE-Recv-Key + tAniPacket *serverKey; // MS-MPPE-Send-Key + v_U8_t keyId; + + // STA context timers + v_U32_t sessionTimeout; + vos_timer_t reAuthTimer; + vos_timer_t sessionCleanupTimer; + + // Radius Authentication attributes + v_U8_t *authClassAttr; + + // Misc. authentication related state + eCsrAuthType authType; + eCsrEncryptionType pwCipherType; + tAniPacket *ieSta; + tAniSsmAuthState authState; + v_BOOL_t prmLookupInProgress; + v_BOOL_t firstTimeAuth; + v_BOOL_t secureLink; // 4-way h/s requries this to be 0 at startup or on MIC failures + tAniSsmReplayCtr *localReplayCtr; + tAniSsmReplayCtr *peerReplayCtr; // Goes hand in hand with flag below + v_BOOL_t pastFirstPeerRequest; // For use with peer replay counter + + tAniPacket *cachedPmk; // MS-MPPE-Recv-Key + tAniPacket *cachedServerKey; // MS-MPPE-Send-Key + v_U8_t cachedKeyId; + +}; + + +struct tSuppContext { + + // AP (peer) identification information + tAniMacAddr authMac; + v_U8_t *ssidStr; + + // Local association point + tAniMacAddr suppMac; + + // Keys derived on supplicant + v_U8_t ptk[AAG_PRF_MAX_OUTPUT_SIZE]; + v_U8_t pwKeyLen; // # of bytes of PTK to send to LIM + tAniPacket *pmk; // MS-MPPE-Recv-Key + tAniPacket *serverKey; // MS-MPPE-Send-Key + + // Misc. authentication related state + eCsrAuthType authType; + eCsrEncryptionType pwCipherType; + eCsrEncryptionType grpCipherType; + tAniPacket *ieBp; + tAniPacket *ieAp; + v_BOOL_t firstTimeAuth; + +}; + +typedef struct tAniEapolKeyAvailEventData { + void *keyDesc; + tAniPacket *eapolFrame; +} tAniEapolKeyAvailEventData; + +typedef struct tAniAagTimerEventData { + vos_timer_t timer; + void *appData; +} tAniAagTimerEventData; + + +/** + * Callback funtion that sets some status for a given STA context, + * e.g., the status of the controlled port. + */ +#if 0 +typedef int (*tAagSetStatus)(tStaContext *ctx); + +typedef int (*tAagTxEapolSupp)(tSuppContext *ctx); +typedef int (*tAagSetStatusSupp)(tSuppContext *ctx); +typedef int (*tAagSendEventToFsmSupp)(tSuppContext *ctx); +#endif + +/** + * Callback function that posts a XXX_TIMER_EXPIRED event when a timer + * goes off. XXX represents the kind of timer that caused the event. + */ +typedef void (*tAagTimerCallback)(void *data); + +/** + * Callbacks provided to the GroupKeyFsm module from the FSM Manager + * module so that it can access procedures needed for network + * transmission, inter-FSM signalling, and communication with the main + * application. + */ +/*typedef struct tGroupKeyFsmCallbacks { + int (*getDefaultWepKeyId)(v_U32_t radioId); + int (*copyDefaultWepKey)(v_U32_t radioId); + int (*updateAllSta)(v_U32_t radioId); +} tGroupKeyFsmCallbacks;*/ + +/** + * This structure stores contants used by the AuthFsm as defined in + * [802.1X]. + */ +typedef struct tAuthFsmConsts { + // Amount of time to ignore a misbehaving STA + v_U16_t quietPeriod; + // Number of reauthentication attempts allowed before ignoring STA + v_U8_t reAuthMax; + // Amount of time to wait for response from STA + v_U16_t txPeriod; +} tAuthFsmConsts; + + + +/** + * This structure stores constants used by the AuthRsnFsm as defined in + * [802.11i]. + */ +typedef struct tAuthRsnFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tAuthRsnFsmConsts; + + +/** + * This structure stores contants used by the SuppFsm as defined in + * [802.1X]. + */ +typedef struct tSuppFsmConsts { + v_U16_t authPeriod; + v_U16_t heldPeriod; + v_U16_t startPeriod; + v_U8_t maxStart; +} tSuppFsmConsts; + +/** + * This structure stores constants used by the SuppRsnFsm as defined in + * [802.11i]. + */ +typedef struct tSuppRsnFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tSuppRsnFsmConsts; + + +/** + * This structure stores constants used by the AuthRsnGroupKeyFsm as + * defined in [802.11i]. + */ +typedef struct tAuthRsnGroupKeyFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tAuthRsnGroupKeyFsmConsts; + +/** + * authRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a STA context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the STA context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmFree(tBtampContext *ctx); + +/** + * authRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmProcessEvent(tAuthRsnFsm *fsm, tRsnFsmEvent eventId, void *arg); + + +/** + * suppFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an SuppFsm instance for the + * given STA context. + * + * @parm ctx the supplicant context whose SuppFsm is being created + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmCreate(tBtampContext *ctx); + +/** + * suppFsmFree + * + * FUNCTION + * Frees a previously allocated SuppFsm. + * + * @param suppCtx the supplicant context whose suppFsm is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmFree(tBtampContext *ctx); + +/** + * suppFsmProcessEvent + * + * FUNCTION + * Passes an event to the suppFsm for immediate processing. + * + * Note: The pertinent event data is already stored in the context. + * + * @param suppFsm the suppFsm + * @param eventId the AAG event to process + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmProcessEvent(tSuppRsnFsm *fsm, tRsnFsmEvent eventId, void *arg); + +#endif // __AAG_FSM_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.c new file mode 100644 index 0000000000000..156f7f6b99d7e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xPrf.c $ + * + */ +/* + * Contains definitions for routines to calculate the 802.11i PRF + * functions. + * + * Author: Mayank D. Upadhyay + * Date: 19-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + */ + +/*#include +#include +#include +*/ +#include "vos_utils.h" +#include "vos_memory.h" +#include "bapRsn8021xPrf.h" +#include "bapRsnErrors.h" +//#include "ani8021xUtils.h" + +#define AAG_PTK_PRF_ADD_PARAM 159 +#define AAG_PTK_PRF_DIV_PARAM 160 + +#define AAG_PTK_PRF_CONST "Pairwise key expansion" +#define AAG_PTK_PRF_CONST_LEN 22 + +#define AAG_PTK_PRF_LM_POS 0 +#define AAG_PTK_PRF_HM_POS 6 +#define AAG_PTK_PRF_LN_POS 12 +#define AAG_PTK_PRF_HN_POS (AAG_PTK_PRF_LN_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +#define AAG_PTK_PRF_TEXT_LEN (AAG_PTK_PRF_HN_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +#define AAG_GTK_PRF_CONST "Group key expansion" +#define AAG_GTK_PRF_CONST_LEN 19 + +#define AAG_GTK_PRF_MAC_POS 0 +#define AAG_GTK_PRF_NONCE_POS 6 + +#define AAG_GTK_PRF_TEXT_LEN (AAG_GTK_PRF_NONCE_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +/** + * aagGetKeyMaterialLen + * + * Returns the number of bytes of the PTK that have to be provided to + * the MAC layer for a given cipher type. + * + * @param cipherType the cipher-type + * + * @return the number of bytes of key material for this cipher type, + * or 0 for invalid cipher types. + */ +int +aagGetKeyMaterialLen(eCsrEncryptionType cipherType) +{ + switch (cipherType) { + case eCSR_ENCRYPT_TYPE_AES: + return AAG_RSN_KEY_MATERIAL_LEN_CCMP; + break; + default: + return 0; + break; + }; +} + +/** + * aagPtkPrf + * + * The PRF used for calculating the pairwise temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param pmk the pairwise master-key + * @param authAddr the MAC address of the authenticator + * @param suppAddr the MAC address of the supplicant + * @param aNonce the nonce generated by the authenticator + * @param sNonce the nonce generated by the supplicant + * + * @return ANI_OK if the operation succeeds + */ +int +aagPtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + tAniPacket *pmk, + tAniMacAddr authAddr, + tAniMacAddr suppAddr, + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE], + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]) +{ + v_U8_t *lowMac; + v_U8_t *highMac; + v_U8_t *lowNonce; + v_U8_t *highNonce; + + v_U8_t *keyBytes; + int keyLen; + + v_U8_t text[AAG_PTK_PRF_TEXT_LEN]; + + //Cannot use voss function here because vos_mem_compare doesn't tell whihc is larger + if (vos_mem_compare2(authAddr, suppAddr, sizeof(tAniMacAddr)) < 0) { + lowMac = authAddr; + highMac = suppAddr; + } else { + lowMac = suppAddr; + highMac = authAddr; + } + + if (vos_mem_compare2(aNonce, sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) < 0) { + lowNonce = aNonce; + highNonce = sNonce; + } else { + lowNonce = sNonce; + highNonce = aNonce; + } + + vos_mem_copy(text + AAG_PTK_PRF_LM_POS, lowMac, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_PTK_PRF_HM_POS, highMac, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_PTK_PRF_LN_POS, lowNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + vos_mem_copy(text + AAG_PTK_PRF_HN_POS, highNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + + keyLen = aniAsfPacketGetBytes(pmk, &keyBytes); + if( !ANI_IS_STATUS_SUCCESS( keyLen ) ) + { + return keyLen; + } + + return aagPrf(cryptHandle, + result, + keyBytes, keyLen, + (v_U8_t *)AAG_PTK_PRF_CONST, AAG_PTK_PRF_CONST_LEN, + text, sizeof(text), + prfLen); +} + +/** + * aagGtkPrf + * + * The PRF used for calculating the group temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param gmk the group master-key + * @param authAddr the MAC address of the authenticator + * @param gNonce the nonce generated by the authenticator for this purpose + * + * @return ANI_OK if the operation succeeds + */ +int +aagGtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + v_U8_t gmk[AAG_RSN_GMK_SIZE], + tAniMacAddr authAddr, + v_U8_t gNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]) +{ + v_U8_t text[AAG_GTK_PRF_TEXT_LEN]; + + vos_mem_copy(text + AAG_GTK_PRF_MAC_POS, authAddr, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_GTK_PRF_NONCE_POS, gNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + + return aagPrf(cryptHandle, + result, + gmk, AAG_RSN_GMK_SIZE, + (v_U8_t *)AAG_GTK_PRF_CONST, AAG_GTK_PRF_CONST_LEN, + text, sizeof(text), + prfLen); + +} + +/** + * aagPrf + * + * The raw PRF function that is used in IEEE 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param key the key to use in the PRF + * @param keyLen the length of the key + * @param a the parameter A which is usually a unique label + * @param aLen the length of the parameter A + * @ param b the parameter B + * @param bLen the length of parameter B + * @param prfLen the number to BITS desired from the PRF result + * + * @return ANI_OK if the operation succeeds + */ +int +aagPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U8_t *key, v_U8_t keyLen, + v_U8_t *a, v_U8_t aLen, + v_U8_t *b, v_U8_t bLen, + v_U32_t prfLen) +{ + static v_U8_t y; + + v_U8_t *hmacText = NULL; + v_U8_t *resultOffset = result; + int numLoops; + int loopCtrPos; + int i, retVal=0; + + hmacText = vos_mem_malloc( aLen + bLen + 2 ); + if( NULL == hmacText ) + { + return ANI_E_NULL_VALUE; + } + + vos_mem_copy(hmacText + 0, a, aLen); + hmacText[aLen] = y; + vos_mem_copy(hmacText + aLen + 1, b, bLen); + loopCtrPos = aLen + 1 + bLen; + + numLoops = prfLen + AAG_PTK_PRF_ADD_PARAM; + numLoops /= AAG_PTK_PRF_DIV_PARAM; + + for (i = 0; i < numLoops; i++) + { + if ((resultOffset - result + VOS_DIGEST_SHA1_SIZE) > AAG_PRF_MAX_OUTPUT_SIZE) + { + VOS_ASSERT(0); + return ANI_ERROR; + } + + hmacText[loopCtrPos] = i; + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, hmacText, loopCtrPos + 1, key, keyLen, resultOffset) ) ) + { + resultOffset += VOS_DIGEST_SHA1_SIZE; + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + } + + vos_mem_free(hmacText); + + return retVal; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.h new file mode 100644 index 0000000000000..de4ffea3a482a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xPrf.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xPrf.h $ + * + */ +/* + * Contains declarations for routines to calculate the 802.11i PRF + * functions. + * + * Author: Mayank D. Upadhyay + * Date: 19-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + */ + +#ifndef __AAG_PRF_H_ +#define __AAG_PRF_H_ + +#include "vos_types.h" +#include +#include +#include "csrApi.h" + + +/* + * Define the maximum size needed for the result array so that SHA-1 + * overflow is accounted for. + */ +#define AAG_PRF_MAX_OUTPUT_SIZE 80 + +#define AAG_RSN_PTK_TK1_OFFSET \ + (AAG_RSN_EAPOL_MIC_KEY_LEN + AAG_RSN_EAPOL_ENC_KEY_LEN) + +// Pairwise key related definitions... + +#define AAG_RSN_PTK_PRF_LEN_TKIP 512 //bits +#define AAG_RSN_PTK_PRF_LEN_CCMP 384 //bits +#define AAG_RSN_PTK_PRF_LEN_WEP104 384 //bits +#define AAG_RSN_PTK_PRF_LEN_WEP40 384 //bits + +// Group key related definitions... + +#define AAG_RSN_GMK_SIZE 16 + +#define AAG_RSN_GTK_PRF_LEN_TKIP 256 //bits +#define AAG_RSN_GTK_PRF_LEN_CCMP 128 //bits +#define AAG_RSN_GTK_PRF_LEN_WEP104 128 //bits +#define AAG_RSN_GTK_PRF_LEN_WEP40 128 //bits + +// Key material length that is sent to the MAC layer... + +#define AAG_RSN_KEY_MATERIAL_LEN_CCMP 16 +#define AAG_RSN_KEY_MATERIAL_LEN_TKIP 32 +#define AAG_RSN_KEY_MATERIAL_LEN_WEP104 13 +#define AAG_RSN_KEY_MATERIAL_LEN_WEP40 5 + +/** + * aagGetKeyMaterialLen + * + * Returns the number of bytes of the PTK that have to be provided to + * the MAC layer for a given cipher type. + * + * @param cipherType the cipher-type + * + * @return the number of bytes of key material for this cipher type, + * or 0 for invalid cipher types. + */ +int +aagGetKeyMaterialLen(eCsrEncryptionType cipherType); + +/** + * aagPtkPrf + * + * The PRF used for calculating the pairwise temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param pmk the pairwise master-key + * @param authAddr the MAC address of the authenticator + * @param suppAddr the MAC address of the supplicant + * @param aNonce the nonce generated by the authenticator + * @param sNonce the nonce generated by the supplicant + * + * @return ANI_OK if the operation succeeds + */ +int +aagPtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + tAniPacket *pmk, + tAniMacAddr authAddr, + tAniMacAddr suppAddr, + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE], + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]); + + +/** + * aagGtkPrf + * + * The PRF used for calculating the group temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param gmk the group master-key + * @param authAddr the MAC address of the authenticator + * @param gNonce the nonce generated by the authenticator for this purpose + * + * @return ANI_OK if the operation succeeds + */ +int +aagGtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + v_U8_t gmk[AAG_RSN_GMK_SIZE], + tAniMacAddr authAddr, + v_U8_t gNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]); + +/** + * aagPrf + * + * The raw PRF function that is used in IEEE 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param key the key to use in the PRF + * @param keyLen the length of the key + * @param a the parameter A which is usually a unique label + * @param aLen the length of the parameter A + * @ param b the parameter B + * @param bLen the length of parameter B + * @param prfLen the number to BITS desired from the PRF result + * + * @return ANI_OK if the operation succeeds + */ +int +aagPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U8_t *key, v_U8_t keyLen, + v_U8_t *a, v_U8_t aLen, + v_U8_t *b, v_U8_t bLen, + v_U32_t prfLen); + +#endif //__AAG_PRF_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c new file mode 100644 index 0000000000000..6071ab73a70c8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c @@ -0,0 +1,1166 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xSuppRsnFsm.c $ + * + */ +/* + * Contains definitions for the RSN EAPOL-Key FSM on the + * supplicant side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapRsn8021xSuppRsnFsm.h" +#include "vos_utils.h" +#include "bapRsnTxRx.h" +#include "btampFsm.h" + +// The different states that this FSM transitions through +#define INITIALIZE 0 +#define AUTHENTICATION 1 +#define GOT_PMK 2 +#define STA_KEY_START 3 +#define STA_KEY_SET 4 +#define KEY_UPDATE 5 +#define REKEY_MSG 6 +#define GROUP_KEY_SET 7 +#define NUM_STATES (GROUP_KEY_SET + 1) + + +static tSuppRsnFsmConsts suppConsts = { 2000, 3 }; //timeout, retry limit + +int gReadToSetKey; + +/************************************** + * Static functions in this module + **************************************/ + +static +int zeroOutPtk(tSuppRsnFsm *fsm); + +static +int checkMic(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t pwKeyExchange); + +static int checkInfoElement(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkPeerReplayCounter(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t *retransmit, + v_BOOL_t actualMicFlag, + v_BOOL_t reTxMicFlag + ); + +static +int derivePtk(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkTransition(tSuppRsnFsm *fsm, void *arg); + +static int +gotoStateInit(tSuppRsnFsm *fsm); + +static int suppRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); +static int suppRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); + +/************************* + * Internal Functions + *************************/ +int suppRsnAuthStartEventHandler(tSuppRsnFsm *fsm); + +/************************* + * The exported functions + *************************/ + +/** + * suppRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmInit(void) +{ + // TODO: Read the constants in from config + // consts = constsIn; + suppConsts.timeoutPeriod = 2000; + suppConsts.maxTries = 3; + + return ANI_OK; +} + +/** + * suppRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given BP context. + * + * @parm ctx the BP context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this BP is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmCreate(tBtampContext *ctx) +{ + int retVal = ANI_OK; + tSuppRsnFsm *fsm = &ctx->uFsm.suppFsm; + + // First, clear everything out + vos_mem_zero( fsm, sizeof(tSuppRsnFsm)); + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterTxRxCallbacks( suppRsnTxCompleteHandler, + suppRsnRxFrameHandler ) ) ) + { + return ANI_ERROR; + } + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterRxCallback( ctx->pvosGCtx ) ) ) + { + return ANI_ERROR; + } + + // Allocate the supplicant context + fsm->suppCtx = (tSuppContext *)vos_mem_malloc( sizeof(tSuppContext) ); + if (fsm->suppCtx == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + // Clear out the supplicant context + vos_mem_zero( fsm->suppCtx, sizeof(tSuppContext)); + + fsm->ctx = ctx; + //Only support CCMP + fsm->suppCtx->pwCipherType = eCSR_ENCRYPT_TYPE_AES; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocate(&fsm->suppCtx->pmk); + if (fsm->suppCtx->pmk == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->suppCtx->ieAp = NULL; + + fsm->cryptHandle = 0; + if( !VOS_IS_STATUS_SUCCESS( vos_crypto_init( &fsm->cryptHandle ) ) ) + { + retVal = ANI_E_FAILED; + VOS_ASSERT( 0 ); + } + + fsm->currentState = INITIALIZE; + gotoStateInit(fsm); + + suppRsnFsmProcessEvent( fsm, RSN_FSM_AUTH_START, NULL ); + + return ANI_OK; + + error: + suppRsnFsmFree( ctx ); + + return retVal; + +} + +/** + * suppRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a BP context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the BP context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmFree(tBtampContext *ctx) +{ + tSuppRsnFsm *fsm; + + fsm = &ctx->uFsm.suppFsm; + + if( fsm->cryptHandle ) + { + vos_crypto_deinit( fsm->cryptHandle ); + } + + bapRsnClearTxRxCallbacks(); + + if (fsm->lastEapol) + aniAsfPacketFree(fsm->lastEapol); + + if( fsm->suppCtx ) + { + if ( fsm->suppCtx->pmk ) + { + aniAsfPacketFree(fsm->suppCtx->pmk); + } + vos_mem_free( fsm->suppCtx ); + } + + // Finally, clear everything out + vos_mem_zero( fsm, sizeof(tSuppRsnFsm)); + + return ANI_OK; +} + +/** + * suppRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmProcessEvent(tSuppRsnFsm *fsm, tRsnFsmEvent eventId, void *arg) +{ + + switch (eventId) + { + case RSN_FSM_TIMER_EXPIRED: + // Proceed straight to checkTransition + break; + case RSN_FSM_AUTH_START: + fsm->authReq = eANI_BOOLEAN_TRUE; + suppRsnAuthStartEventHandler(fsm); + break; + case RSN_FSM_EAPOL_FRAME_AVAILABLE: + fsm->eapolAvail = eANI_BOOLEAN_TRUE; + break; + case RSN_FSM_INTEG_FAILED: + fsm->integFailed = eANI_BOOLEAN_TRUE; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp unknown event for SuppFsm: %d\n", + eventId); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + break; + } + + checkTransition(fsm, arg); + + return ANI_OK; +} + +int +suppRsnAuthStartEventHandler(tSuppRsnFsm *fsm) +{ + // Copy required info + vos_mem_copy( &fsm->suppCtx->authMac, fsm->ctx->peer_mac_addr, 6); + vos_mem_copy( &fsm->suppCtx->suppMac, fsm->ctx->self_mac_addr, 6); + aniAsfPacketAppendBuffer( fsm->suppCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); + + return ANI_OK; +} + +/*********************** + * The static functions + ***********************/ + +static int +gotoStateInit(tSuppRsnFsm *fsm) +{ + fsm->currentState = INITIALIZE; + + fsm->authReq = eANI_BOOLEAN_FALSE; + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + fsm->integFailed = eANI_BOOLEAN_FALSE; + fsm->pmkAvail = eANI_BOOLEAN_FALSE; + + // Create two replay counter's..one for our requests, and another + // for STA's requests. Initialize the first one randomly. + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->localReplayCtr, ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->peerReplayCtr, ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + + return ANI_OK; +} + +static int +gotoStateAuthentication(tSuppRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION; + + if( VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( fsm->cryptHandle, fsm->sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE ) ) ) + { + zeroOutPtk(fsm); + // TODO: Zero out all GTK's + fsm->authReq = eANI_BOOLEAN_FALSE; + /////getPmk(fsm->suppCtx); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp fail to random number\n" ); + return ANI_ERROR; + } + + return ANI_OK; +} + +static int +gotoStateGotPmk(tSuppRsnFsm *fsm) +{ + fsm->currentState = GOT_PMK; + + return ANI_OK; +} + +static int +gotoStateStaKeyStart(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t retransmit) +{ + int retVal; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc; + static v_U8_t btampRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 }; + + fsm->currentState = STA_KEY_START; + + // Create a new EAPOL frame if we don't have to retransmit + // if (!retransmit) + //{ + + rxDesc = data->keyDesc; + if( NULL == rxDesc) + { + return ANI_E_NULL_VALUE; + } + aniAsfPacketEmptyExplicit( fsm->lastEapol, EAPOL_TX_HEADER_SIZE ); + retVal = derivePtk(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp derivePtk failed with code %d!\n", retVal); + return retVal; + } + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = 0; //RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + vos_mem_copy(txDesc.keyNonce, fsm->sNonce, sizeof(txDesc.keyNonce)); + txDesc.keyDataLen = sizeof(btampRSNIE);//aniAsfPacketGetBytes(fsm->suppCtx->ieBp, + //&txDesc.keyData); + txDesc.keyData = btampRSNIE; + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp gotoStateStaKeyStart fail to write key %d\n", + retVal); + return retVal; + } + //} + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateStaKeySet(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t retransmit) +{ + int retVal=0; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc = NULL; + + fsm->currentState = STA_KEY_SET; + + if (data == NULL) + { + // We don't need to do anything + return ANI_OK; + } + + // Create a new EAPOL frame if we don't have to retransmit + if (!retransmit) + { + // First check the IE that the AP sent + retVal = checkInfoElement(fsm, data); + if (retVal != ANI_OK) + { + //FIX_RSN aagSetSuppFailureAndCleanup(fsm->suppCtx); + + // FSM does not exist after this... + + return retVal; + } + + // Create a new EAPOL frame + + rxDesc = data->keyDesc; + if( NULL == rxDesc ) + return ANI_E_NULL_VALUE; + + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = 0; //RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + } + gReadToSetKey = BAP_SET_RSN_KEY; + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + /* making it global to access in bapTxRx file */ +#if 0 + tCsrRoamSetKey setKeyInfo; + + + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + /* + We will move the Set key to EAPOL Completion handler. We found a race condition betweem + sending EAPOL frame and setting Key */ + + + if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" ); + retVal = ANI_ERROR; + } +#endif + gReadToSetKey = BAP_RESET_RSN_KEY; + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateGroupKeySet(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc; + + int groupKeyLen; + + fsm->currentState = GROUP_KEY_SET; + + do + { + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( NULL == rxDesc) + { + retVal = ANI_E_NULL_VALUE; + break; + } + + if (rxDesc->keyDataLen == 0 || rxDesc->keyData == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent no group key in group EAPOL-Key message!\n" ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + if ( rxDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES ) + { + groupKeyLen = rxDesc->keyDataLen - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if( groupKeyLen <= 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent GTK too short\n" ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent unsupported keyDescVer %d!\n", rxDesc->info.keyDescVers ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + // Always create a new EAPOL frame + + aniAsfPacketEmptyExplicit( fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->grpCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + + txDesc.info.unicastFlag = eANI_BOOLEAN_FALSE; + txDesc.info.keyId = rxDesc->info.keyId; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_ERROR; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp could not send eapol. Disconnect\n" ); + break; + } + + //FIX_RSN there is no need to set GTK retVal = setGtk(fsm->suppCtx, rxDesc->keyRecvSeqCounter); + + // This is never retransmitted + aniAsfPacketEmptyExplicit( fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + checkTransition(fsm, NULL); // UCT rule + }while( 0 ); + + return retVal; +} + +static int +gotoStateKeyUpdate(tSuppRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + //we don't update keys + bapSuppDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static int +gotoStateRekeyMsg(tSuppRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + //We don't support rekey, simply disconnect + bapSuppDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static +int zeroOutPtk(tSuppRsnFsm *fsm) +{ + return ANI_OK; +} + +static +int derivePtk(tSuppRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + v_U32_t prfLen; + tAniEapolRsnKeyDesc *rxDesc; + + switch (fsm->suppCtx->pwCipherType) + { + case eCSR_ENCRYPT_TYPE_AES: + prfLen = AAG_RSN_PTK_PRF_LEN_CCMP; + fsm->suppCtx->pwKeyLen = AAG_RSN_KEY_MATERIAL_LEN_CCMP; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Cannot generate PTK for BP for invalid algorithm %d\n", + fsm->suppCtx->pwCipherType); + return ANI_E_ILLEGAL_ARG; + break; + }; + + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + return aagPtkPrf(fsm->cryptHandle, + fsm->suppCtx->ptk, + prfLen, + fsm->suppCtx->pmk, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + rxDesc->keyNonce, + fsm->sNonce); +} + +static +int checkMic(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t pwKeyExchange) +{ + int retVal; + + retVal = aniEapolKeyCheckMic(fsm->cryptHandle, + data->eapolFrame, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + data->keyDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + + return retVal; +} + + +static int checkInfoElement(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *desc; + v_U8_t *ieApBytes; + int ieApLen; + + desc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( NULL == desc ) + { + return ANI_E_NULL_VALUE; + } + + ieApLen = aniAsfPacketGetBytes(fsm->suppCtx->ieAp, &ieApBytes); + if( ANI_IS_STATUS_SUCCESS( ieApLen ) ) + { + + if ((desc->keyDataLen != ieApLen) || + ( vos_mem_compare(desc->keyData, ieApBytes, ieApLen) )) + { + // TODO: Send a fault here + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp AP sent inconsistent RSN IE!\n" ); + return ANI_E_FAILED; + } + } + + return ANI_OK; +} + +static +int checkPeerReplayCounter(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t *retransmit, + v_BOOL_t actualMicFlag, + v_BOOL_t reTxMicFlag) +{ + int retVal = ANI_OK; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( NULL == rxDesc ) + { + return ANI_E_NULL_VALUE; + } + + *retransmit = eANI_BOOLEAN_FALSE; + + cmp = aniSsmReplayCtrCmp(fsm->peerReplayCtr, rxDesc->replayCounter); + + // The AP should send us a replay counter greater than or equal to + // the last one it sent + /*Unless we are forgiving with this we will have interop issues with some vendros like CSR*/ + if (cmp > 0) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "BP got old EAPOL replay counter from AP" ); + retVal = ANI_E_REPLAY_CHECK_FAILED; + + } + else if (cmp <= 0) + { + if ( actualMicFlag == reTxMicFlag ) + { + *retransmit = eANI_BOOLEAN_TRUE; + } + } + + return retVal; +} + +static +int checkTransition(tSuppRsnFsm *fsm, void *arg) +{ + tAniEapolKeyAvailEventData *data; + tAniEapolRsnKeyDesc *rxDesc; + v_BOOL_t retransmit; + int retVal; + + if (fsm->authReq) + { + gotoStateAuthentication(fsm); + return ANI_OK; + } + + switch (fsm->currentState) + { + case INITIALIZE: + break; + case AUTHENTICATION: + gotoStateGotPmk(fsm); + checkTransition(fsm, arg); + break; + case GOT_PMK: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.ackFlag) + { + + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + // Going from one state to another cannot be a retransmit + retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_FALSE); + + } + } + break; + case STA_KEY_START: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.ackFlag) { + + retVal = checkPeerReplayCounter( + fsm, + data, + &retransmit, + rxDesc->info.micFlag, + 0); // MIC not set means check for re-Tx M1. + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + if (retransmit) { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Resending EAPOL-Key Msg2 from " + "supplicant to AP" ); + retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_TRUE); + + } + else { + retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); + if (retVal != ANI_OK) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_FALSE); + + } + } + } + break; + case STA_KEY_SET: + if (fsm->eapolAvail) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + retVal = checkPeerReplayCounter( + fsm, + data, + &retransmit, + rxDesc->info.micFlag, + 1); // MIC set means check for re-Tx M3. + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + if (!retransmit) + { + retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); + if (retVal != ANI_OK) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + } + + if (rxDesc->info.unicastFlag) + { + /* + * Handle pairwise key message...in this state + * pairwise key messages can only be for retransmissions. + */ + if (retransmit) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Resending EAPOL-Key Msg4 from " + "supplicant \n" ); + retVal = gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_TRUE); + } + } + else + { + /* + * Handle group key message...with group key messages, + * the replay counter has to change on + * retransmissions. + */ + if (!retransmit) + { + retVal = gotoStateGroupKeySet(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + } + } + } + else { + if (fsm->integFailed) + { + gotoStateKeyUpdate(fsm, arg); + } + } + break; + case GROUP_KEY_SET: + gotoStateStaKeySet(fsm, NULL, eANI_BOOLEAN_FALSE); + break; + case KEY_UPDATE: + gotoStateRekeyMsg(fsm, arg); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Illegal state for SuppRsnFsm: %d", + fsm->currentState); + VOS_ASSERT( 0 ); + return ANI_E_FAILED; + } + + return ANI_OK; +} + + + +static int +suppEapolKeyHandler( tSuppRsnFsm *fsm, + tAniPacket *eapolFrame, + tAniMacAddr suppMac) +{ + int retVal; + + int descType; + void *keyDesc; + tAniEapolRsnKeyDesc *rsnDesc; + tAniEapolKeyAvailEventData data; + + do + { + retVal = aniEapolParseKey(eapolFrame, &descType, &keyDesc); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + if (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + rsnDesc = (tAniEapolRsnKeyDesc *) keyDesc; + /* + * Pass on the event to the RSN FSM irrespective if it is + * pairwise or not. + */ + data.keyDesc = keyDesc; + data.eapolFrame = eapolFrame; + retVal = suppRsnFsmProcessEvent(fsm, + RSN_FSM_EAPOL_FRAME_AVAILABLE, + &data); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: Got unexpected 802.1x RC4 Key message \n" ); + retVal = ANI_E_FAILED; + break; + } + }while( 0 ); + + aniEapolKeyFreeDesc(descType, keyDesc); + return retVal; +} + + + +// +//This function alwasy assume the incoming vos_packet is 802_3 frame. +static int suppRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + int retVal = ANI_ERROR; + tAniPacket *pAniPacket; + tBtampContext *ctx; + tSuppRsnFsm *fsm; + /* Validate params */ + if ((pvosGCtx == NULL) || (NULL == pPacket)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return retVal; + } + ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return retVal; + } + + fsm = &ctx->uFsm.suppFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return retVal; + } + + do + { + //ToDO: We need to synchronize this. For now, use the simplest form, drop the packet comes later. + if( fsm->fReceiving ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " ******suppRsnRxFrameHandler receive eapol packet while processing. Drop the new comer\n" ); + break; + } + fsm->fReceiving = VOS_TRUE; + retVal = bapRsnFormPktFromVosPkt( &pAniPacket, pPacket ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Now we can process the eapol frame + //handler will free the pAniPacket + bapRsnEapolHandler( fsm, pAniPacket, VOS_FALSE ); + }while( 0 ); + + fsm->fReceiving = VOS_FALSE; + vos_pkt_return_packet( pPacket ); + + return retVal; +} + + +static int suppRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + tBtampContext *ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + tAuthRsnFsm *fsm; + + vos_pkt_return_packet( pPacket ); + if (pvosGCtx == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return ANI_ERROR; + } + + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return ANI_ERROR; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return ANI_ERROR; + } + + //Synchronization needed + + if(!VOS_IS_STATUS_SUCCESS( retStatus ) ) + { + //This is bad. + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: TL Tx complete with error %d current state is %d\n", retStatus, fsm->currentState ); + if( fsm->numTries <= suppConsts.maxTries ) + { + //retransmit + fsm->numTries++; + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + bapSuppDisconnect( fsm->ctx->pvosGCtx ); + } + } + else + { + bapSuppDisconnect( fsm->ctx->pvosGCtx ); + } + } + + return ANI_OK; +} + + +/** + * suppEapolHandler + * + * Handles an incoming EAPOL frame on the supplicant side. + * + * @param eapolFrame the packet containing the EAPOL frame, with the + * head of the packet still at the start of the EAPOL frame + * @param dstMac the dstMac pointing inside the frame + * @param srcMac the srcMac pointing inside the frame + * @param type the type pointing inside the frame at the type field + * + * @return ANI_OK if the operation succeeds + */ +void suppEapolHandler( tSuppRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type ) +{ + switch (*type) + { + case ANI_EAPOL_TYPE_PACKET: + // Ignore EAP becasue it is only WPA2-PSK + break; + case ANI_EAPOL_TYPE_KEY: + suppEapolKeyHandler( fsm, eapolFrame, dstMac ); + break; + case ANI_EAPOL_TYPE_ASF_ALERT: + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: EAPOL type not implemented: %.2x\n", *type); + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h new file mode 100644 index 0000000000000..88994b10fbced --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xSuppRsnFsm.h $ + * + */ +/* + * Contains declarations for the RSN EAPOL-Key FSM on the + * supplicant side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_SUPP_RSN_FSM_H +#define __AAG_SUPP_RSN_FSM_H + +#include "bapRsn8021xFsm.h" +#include "bapInternal.h" + +/** + * suppRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmInit(void); + +int +suppRsnFsmSetPmk(tSuppContext *ctx, v_U8_t *pmk); + +#endif //__AAG_SUPP_RSN_FSM_H diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.c new file mode 100644 index 0000000000000..d6561ea7c65ab --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.c @@ -0,0 +1,1019 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/nova_phase1/ap/apps/asf/aniAsfPacket.c $ + * Contains definitions for packet manipulation routines that make it + * easy to create and parse multi-layered network frames. This module + * minimizes buffer copies while adding or removing headers, and + * adding or removing payload. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "vos_trace.h" +#include +#include +#include "vos_memory.h" +#include "vos_packet.h" + +/* + * Allocate one more than required because the last bytes is waste. We + * waste the last byte because in the adopted model, the tail always + * points to the next location where data should be stored. In a full + * buffer we don't want to position the tail to memory we haven't + * allocated ourself. + */ +#define ANI_INTERNAL_DEFAULT_PACKET_SIZE (ANI_DEFAULT_PACKET_SIZE + 4) + +#define TAIL_SPACE(packet) \ + ((packet)->buf + (packet)->size - (packet)->tail) + +#define HEAD_SPACE(packet) \ + ((packet)->head - (packet)->buf) + +#define ANI_CHECK_RANGE(x , upper) \ + ( (x) <= (upper) ) + +/** + * Opaque packet structure with internal storage for raw bytes. + * Conceptually, a tAniPacket is a pre-allocated buffer that contains + * data in the middle and free space on either side. The start of the + * data is called the head. Routines are provided to add data at the + * front or at the rear. The length of the packet is the total number + * of valid data bytes contained in it. The size of the packet is the + * total number of preallocated bytes. + */ +struct tAniPacket { + v_U8_t *buf; + v_U32_t size; + v_U8_t *head; + v_U8_t *tail; + v_U8_t *recordHeader; + v_U32_t len; +}; + +/** + * aniAsfPacketAllocate + * + * FUNCTION: + * Create a packet of size 2*ANI_DEFAULT_PACKET_SIZE and positions the + * head of the packet in the center. The allocated storage can be free + * with a call to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tAniPacket and its internal raw data + * buffer. Positions the head and tail pointers in the middle of the + * raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tAniPacket if the operation succeeds. + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocate(tAniPacket **packetPtr) +{ + return aniAsfPacketAllocateExplicit(packetPtr, + ANI_INTERNAL_DEFAULT_PACKET_SIZE, + ANI_INTERNAL_DEFAULT_PACKET_SIZE/2); +} + +/** + * aniAsfPacketAllocateExplicit + * + * FUNCTION: + * Create a packet of the desired size and position the head of the + * packet at the desired offset in the internal raw data buffer. An + * application would normally set this offset to the expected length + * of the protocol header, then append the payload, and finally, + * prepend the header. The allocated storage can be free with a call + * to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tAniPacket and its internal raw data + * buffer. Positions the head and tail pointers at the given offset in + * the internal raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tAniPacket if the operation succeeds. + * @param size the size of the internal raw data buffer + * @param offset the offset in the internal raw data buffer where the + * head of the packet will be positioned initially + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocateExplicit(tAniPacket **packetPtr, + v_U32_t size, + v_U32_t offset) +{ + tAniPacket *packet = NULL; + v_U32_t maxHead = size; + + *packetPtr = NULL; + if (size == 0) + return ANI_E_ILLEGAL_ARG; + + VOS_ASSERT(ANI_CHECK_RANGE(offset, maxHead)); + if (!ANI_CHECK_RANGE(offset, maxHead)) + return ANI_E_ILLEGAL_ARG; + + packet = (tAniPacket *) vos_mem_malloc( sizeof(tAniPacket) ); + + if (packet == NULL) + { + VOS_ASSERT( 0 ); + return ANI_E_MALLOC_FAILED; + } + + // transparently add one to the size since last byte is wasted + size = (size + 4) & 0xfffffffc; + + packet->buf = (v_U8_t *)vos_mem_malloc( sizeof(v_U8_t) * size ); + if (packet->buf == NULL) + { + vos_mem_free( packet ); + VOS_ASSERT( 0 ); + return ANI_E_MALLOC_FAILED; + } + + packet->size = size; // Should not be visible to the user + packet->head = packet->buf + offset; + packet->tail = packet->head; + packet->len = 0; + + *packetPtr = packet; + return ANI_OK; +} + +/** + * aniAsfPacketDuplicate + * + * Duplicates a given packet exactly. That is, the contents, the size + * of the packet, and the positions of the pointers are maintained in + * the new copy. + * + * @param newPacketPtr is set to a newly allocated packet that is a + * duplicate of oldPacket + * @param oldPacket the original packet that should be duplicated + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL if oldPacket + * is NULL; + */ +int +aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket) +{ + int retVal; + int recordPos; + tAniPacket *packet = NULL; + + if (oldPacket == NULL) + return ANI_E_NULL_VALUE; + + retVal = aniAsfPacketAllocateExplicit(&packet, + oldPacket->size, + oldPacket->head - oldPacket->buf); + if (retVal != ANI_OK) + return retVal; + + retVal = aniAsfPacketAppendBuffer(packet, + oldPacket->head, + oldPacket->len); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + aniAsfPacketFree(packet); + return ANI_E_FAILED; + } + + if (oldPacket->recordHeader != NULL) + { + recordPos = oldPacket->recordHeader - oldPacket->buf; + packet->recordHeader = packet->buf + recordPos; + } + *newPacketPtr = packet; + + return ANI_OK; +} + +/** + * aniAsfPacketFree + * + * FUNCTION: + * Free a previously allocated tAniPacket and its internal raw data + * buffer. + * + * @param packet the packet to free + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL_VALUE if an + * unexpected NULL pointer is encountered + */ +int +aniAsfPacketFree(tAniPacket *packet) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (packet->buf != NULL) + vos_mem_free( packet->buf ); + + vos_mem_free( packet ); + + return ANI_OK; +} + + +/** + * aniAsfPacketAppendBuffer + * + * FUNCTION: + * Appends the data contained in buf to the end of the data in + * destAniPacket. The head of destAniPacket remains unchanged, while its + * length increases by len. + * + * If there isn't enough free space in destAniPacket for all len bytes + * then the routine fails and the length of destAniPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to append the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to append to + * @param buf the buffer containing data to be appended to the packet + * @param len the number of bytes to append + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketPrependBuffer + */ +int +aniAsfPacketAppendBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len) +{ + if (aniAsfPacketCanAppendBuffer(destPacket, len) != ANI_OK) + return ANI_E_FAILED; + + if (buf == NULL) + return ANI_E_NULL_VALUE; + + vos_mem_copy(destPacket->tail, buf, len); + destPacket->tail += len; + destPacket->len += len; + return ANI_OK; +} + +/** + * aniAsfPacketPrependBuffer + * + * FUNCTION: + * Prepends the data contained in buf to the start of the data in + * destPacket. The head of destPacket is repositioned and the length + * of destPacket increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to prepend the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to prepend to + * @param buf the buffer containing data to be prepended to the packet + * @param len the number of bytes to prepend + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketAppendBuffer + */ +int +aniAsfPacketPrependBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len) +{ + if (aniAsfPacketCanPrependBuffer(destPacket, len) != ANI_OK) + return ANI_E_FAILED; + + if (buf == NULL) + return ANI_E_NULL_VALUE; + + destPacket->head -= len; + destPacket->len += len; + vos_mem_copy(destPacket->head, buf, len); + return ANI_OK; + +} + +/** + * aniAsfPacketCanAppendBuffer + * + * FUNCTION: + * Determines if len bytes can be safely appended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet tail plus len of buffer should not exceed packet + * start plus packet size + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to append to + * @param len the number of bytes to append + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanAppendBuffer(tAniPacket *destPacket, + v_U32_t len) +{ + if (destPacket == NULL) + return ANI_E_FAILED; + + if ((int)len <= TAIL_SPACE(destPacket)) + return ANI_OK; + else + return ANI_E_FAILED; +} + +/** + * aniAsfPacketCanPrependBuffer + * + * FUNCTION: + * Determines if len bytes can be safely prepended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet head minus len of buffer should not be less than + * start of packet. + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to prepend to + * @param len the number of bytes to prepend + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanPrependBuffer(tAniPacket *destPacket, + v_U32_t len) +{ + if (destPacket == NULL) + return ANI_E_FAILED; + + if (!(len > 0)) + return ANI_E_FAILED; + + if ((int)len <= HEAD_SPACE(destPacket)) + return ANI_OK; + else + return ANI_E_FAILED; +} + +/** + * aniAsfPacketTruncateFromFront + * + * FUNCTION: + * Removes len bytes from the front of the packet by moving its + * head. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the front + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromFront(tAniPacket *packet, + v_U32_t len) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (!ANI_CHECK_RANGE(len, packet->len)) + return ANI_E_FAILED; + + packet->head += len; + packet->len -= len; + + return ANI_OK; +} + +/** + * aniAsfPacketTruncateFromRear + * + * FUNCTION: + * Removes len bytes from the rear of the packet by moving its + * tail. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the rear + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromRear(tAniPacket *packet, + v_U32_t len) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (!ANI_CHECK_RANGE(len, packet->len)) + return ANI_E_FAILED; + + packet->tail -= len; + packet->len -= len; + + return ANI_OK; +} + +/** + * aniAsfPacketGetLen + * + * FUNCTION: + * Returns the number of valid data bytes stored in the packet. + * + * @param packet the packet whose len we need + * + * @return the non-negative number of bytes stored in the packet + */ +int +aniAsfPacketGetLen(tAniPacket *packet) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + return packet->len; +} + +/** + * aniAsfPacketGetBytes + * + * FUNCTION: + * Returns a pointer to the head of the valid data stored in the + * packet. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytes(tAniPacket *packet, v_U8_t **rawBytesPtr) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + *rawBytesPtr = packet->head; + return packet->len; +} + +/** + * aniAsfPacketGetN + * + * Returns N bytes from the packet and moves the head of the packet + * beyond those bytes. + * + * @param packet the packet to read from + * @param n the number of bytes to read + * @param bytesPtr is set to the start of the octets + * + * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the + * packet does not have n bytes. + */ +int +aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr) +{ + int retVal; + v_U8_t *bytes = NULL; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + retVal = aniAsfPacketGetBytes(packet, &bytes); + if (retVal < n) + return ANI_E_SHORT_PACKET; + + aniAsfPacketTruncateFromFront(packet, n); + + *bytesPtr = bytes; + + return ANI_OK; +} + +/** + * aniAsfPacketEmpty + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the middle and + * setting the length to zero. + * + * @param packet the packet to empty + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmpty(tAniPacket *packet) +{ + return aniAsfPacketEmptyExplicit(packet, packet->size/2); +} + +/** + * aniAsfPacketEmptyExplicit + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the desired + * offset and setting the length to zero. + * + * @param packet the packet to empty + * @param offset the offset that the head of the packet should be set + * to. An application will be able to prepend and append data relative + * to this offset. + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmptyExplicit(tAniPacket *packet, + v_U32_t offset) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + VOS_ASSERT(ANI_CHECK_RANGE(offset, packet->size)); + if (!ANI_CHECK_RANGE(offset, packet->size)) + return ANI_E_ILLEGAL_ARG; + + packet->head = packet->buf + offset; + packet->tail = packet->head; + packet->len = 0; + + return ANI_OK; +} + + + +/** + * aniAsfPacketPrependHdr + * + * FUNCTION: + * Prepends a tAniHdr at the start of the packet. All host to network + * byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param msgType the message type to write as part of the header + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrependHdr(tAniPacket *packet, v_U16_t msgType) +{ + int retVal; + int length; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + length = 4; + + length = 2 + 2 + packet->len; + + retVal = aniAsfPacketPrepend16(packet, length); + if (retVal < 0) + return retVal; + + retVal = aniAsfPacketPrepend16(packet, msgType); + if (retVal < 0) + return retVal; + + return ANI_OK; +} + +/** + * aniAsfPacketGet32 + * + * FUNCTION: + * Reads a ANI_U32 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet32(tAniPacket *packet, v_U32_t *val) +{ + v_U8_t u32Arr[4]; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 4) + return ANI_E_SHORT_PACKET; + + //packet is in network order, make sure it is align + u32Arr[0] = packet->head[0]; + u32Arr[1] = packet->head[1]; + u32Arr[2] = packet->head[2]; + u32Arr[3] = packet->head[3]; + *val = vos_be32_to_cpu( *(v_U32_t *)u32Arr ); + aniAsfPacketTruncateFromFront(packet, 4); + + return ANI_OK; +} + +/** + * aniAsfPacketAppend32 + * + * FUNCTION: + * Appends a ANI_U32 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend32(tAniPacket *packet, v_U32_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 4) + return ANI_E_FAILED; + + val = vos_cpu_to_be32( val ); + p8 = (v_U8_t *)&val; + packet->tail[0] = p8[0]; + packet->tail[1] = p8[1]; + packet->tail[2] = p8[2]; + packet->tail[3] = p8[3]; + aniAsfPacketMoveRight(packet, 4); + + return ANI_OK; +} + +/** + * aniAsfPacketGet16 + * + * FUNCTION: + * Reads a ANI_U16 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val) +{ + v_U8_t u16Arr[2]; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 2) + return ANI_E_SHORT_PACKET; + + u16Arr[0] = packet->head[0]; + u16Arr[1] = packet->head[1]; + *val = vos_be16_to_cpu( *(v_U16_t *)u16Arr ); + aniAsfPacketTruncateFromFront(packet, 2); + + return ANI_OK; +} + +/** + * aniAsfPacketPrepend16 + * + * FUNCTION: + * Prepends a ANI_U16 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (HEAD_SPACE(packet) < 2) + return ANI_E_FAILED; + + aniAsfPacketMoveLeft(packet, 2); + val = vos_cpu_to_be16( val ); + p8 = (v_U8_t *)&val; + packet->head[0] = p8[0]; + packet->head[1] = p8[1]; + + return ANI_OK; +} + +/** + * aniAsfPacketAppend16 + * + * FUNCTION: + * Appends a ANI_U16 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 2) + return ANI_E_FAILED; + + val = vos_cpu_to_be16( val ); + p8 = (v_U8_t *)&val; + packet->tail[0] = p8[0]; + packet->tail[1] = p8[1]; + aniAsfPacketMoveRight(packet, 2); + + return ANI_OK; +} + +/** + * aniAsfPacketGet8 + * + * FUNCTION: + * Reads a ANI_U8 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet8(tAniPacket *packet, v_U8_t *val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 1) + return ANI_E_SHORT_PACKET; + + *val = *(packet->head); + aniAsfPacketTruncateFromFront(packet, 1); + + return ANI_OK; +} + +/** + * aniAsfPacketPrepend8 + * + * FUNCTION: + * Prepends a ANI_U8 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend8(tAniPacket *packet, v_U8_t val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + VOS_ASSERT(HEAD_SPACE(packet) >= 1); + if (HEAD_SPACE(packet) < 1) + return ANI_E_FAILED; + + aniAsfPacketMoveLeft(packet, 1); + *(packet->head) = val; + + return ANI_OK; +} + +/** + * aniAsfPacketAppend8 + * + * FUNCTION: + * Appends a ANI_U8 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend8(tAniPacket *packet, v_U8_t val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 1) + return ANI_E_FAILED; + + *(packet->tail) = val; + aniAsfPacketMoveRight(packet, 1); + + return ANI_OK; +} + +/** + * aniAsfPacketGetMac + * + * FUNCTION: + * Returns a tAniMacAddr from the start of the packet. + * + * @param packet the packet to read from + * @param macAddr the destination to copy the MAC address to + * + * @return ANI_OK if the operation succeeds. Also, the packet head + * pointer is advanced past the MAC address. + */ +int +aniAsfPacketGetMac(tAniPacket *packet, tAniMacAddr macAddr) +{ + if (packet->len < sizeof(tAniMacAddr)) + return ANI_E_SHORT_PACKET; + + vos_mem_copy(macAddr, packet->head, sizeof(tAniMacAddr)); + + packet->head += sizeof(tAniMacAddr); + packet->len -= sizeof(tAniMacAddr); + + return ANI_OK; +} + +/** + * aniAsfPacketMoveLeft + * + * FUNCTION: + * Pretends that a certain number of bytes have been prepended to the + * packet, without actually copying any bytes in. The packet head and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move head and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveLeft(tAniPacket *packet, v_U32_t count) +{ + if (aniAsfPacketCanPrependBuffer(packet, count) != ANI_OK) + return ANI_E_FAILED; + + packet->head -= count; + packet->len += count; + + return ANI_OK; +} + +/** + * aniAsfPacketMoveRight + * + * FUNCTION: + * Pretends that a certain number of bytes have been appended to the + * packet, without actually copying any bytes in. The packet tail and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move tail and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveRight(tAniPacket *packet, v_U32_t count) +{ + if (aniAsfPacketCanAppendBuffer(packet, count) != ANI_OK) + return ANI_E_FAILED; + + packet->tail += count; + packet->len += count; + + return ANI_OK; +} + +/** + * aniAsfPacketGetBytesFromTail + * + * FUNCTION: + * Returns a pointer to the tail of the valid data stored + * in the packet. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a three-step process - one: call this + * routine to obtain a pointer to the current tail of the packet. + * two: treat this returned pointer like a simple array and copy + * some bytes to the packet's internal buffer, and finally + * three: move tail and length. This violates the encapsulation + * the packet library aims to provide. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytesFromTail(tAniPacket *packet, v_U8_t **rawBytesPtr) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + *rawBytesPtr = packet->tail; + return 0; // The length of used bytes returned is zero +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.h new file mode 100644 index 0000000000000..c38c8d32caaa7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnAsfPacket.h @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/nova_phase1/ap/apps/include/aniAsfPacket.h $ + * Contains declarations for packet manipulation routines that make it + * easy to create and parse multi-layered network frames. This module + * minimizes buffer copies while adding or removing headers, and + * adding or removing payload. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_ASF_PACKET_H_ +#define _ANI_ASF_PACKET_H_ + +#include "vos_types.h" +#include "palTypes.h" + +#define ANI_ETH_FRAME_LEN 1516 +#define ANI_DEFAULT_PACKET_SIZE (ANI_ETH_FRAME_LEN*2) + +/** + * Opaque packet structure with internal storage for raw bytes. + * Conceptually, a tPacket is a pre-allocated buffer that contains + * data in the middle and free space on either side. The start of the + * data is called the head. Routines are provided to add data at the + * front or at the rear. The length of the packet is the total number + * of valid data bytes contained in it. The size of the packet is the + * total number of preallocated bytes. + */ +typedef struct tAniPacket tAniPacket; + +/** + * aniAsfPacketAllocate + * + * FUNCTION: + * Create a packet of size 2*ANI_DEFAULT_PACKET_SIZE and positions the + * head of the packet in the center. The allocated storage can be free + * with a call to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tPacket and its internal raw data + * buffer. Positions the head and tail pointers in the middle of the + * raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tPacket if the operation succeeds. + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocate(tAniPacket **packetPtr); + +/** + * aniAsfPacketDuplicate + * + * Duplicates a given packet exactly. That is, the contents, the size + * of the packet, and the positions of the pointers are maintained in + * the new copy. + * + * @param newPacketPtr is set to a newly allocated packet that is a + * duplicate of oldPacket + * @param oldPacket the original packet that should be duplicated + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket); + +/** + * aniAsfPacketAllocateExplicit + * + * FUNCTION: + * Create a packet of the desired size and position the head of the + * packet at the desired offset in the internal raw data buffer. An + * application would normally set this offset to the expected length + * of the protocol header, then append the payload, and finally, + * prepend the header. The allocated storage can be free with a call + * to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tPacket and its internal raw data + * buffer. Positions the head and tail pointers at the given offset in + * the internal raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tPacket if the operation succeeds. + * @param size the size of the internal raw data buffer + * @param offset the offset in the internal raw data buffer where the + * head of the packet will be positioned initially + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocateExplicit(tAniPacket **packetPtr, + v_U32_t size, + v_U32_t offset); + +/** + * aniAsfPacketFree + * + * FUNCTION: + * Free a previously allocated tPacket and its internal raw data + * buffer. + * + * @param packet the packet to free + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL_VALUE if an + * unexpected NULL pointer is encountered + */ +int +aniAsfPacketFree(tAniPacket *packet); + +/** + * aniAsfPacket2Str + * + * FUNCTION: + * Returns a printable representation of the data contained in the + * packet. + * Note: This function returns a static buffer used by aniAsfHexStr. + * + * @param packet the packet whose contents need to be printed + */ +v_U8_t *aniAsfPacket2Str(tAniPacket *packet); + +/** + * aniAsfPacketAppendBuffer + * + * FUNCTION: + * Appends the data contained in buf to the end of the data in + * destPacket. The head of destPacket remains unchanged, while its + * length increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to append the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to append to + * @param buf the buffer containing data to be appended to the packet + * @param len the number of bytes to append + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketPrependBuffer + */ +int +aniAsfPacketAppendBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len); + +/** + * aniAsfPacketPrependBuffer + * + * FUNCTION: + * Prepends the data contained in buf to the start of the data in + * destPacket. The head of destPacket is repositioned and the length + * of destPacket increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to prepend the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to prepend to + * @param buf the buffer containing data to be prepended to the packet + * @param len the number of bytes to prepend + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketAppendBuffer + */ +int +aniAsfPacketPrependBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len); + +/** + * aniAsfPacketCanAppendBuffer + * + * FUNCTION: + * Determines if len bytes can be safely appended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet tail plus len of buffer should not exceed packet + * start plus packet size + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to append to + * @param len the number of bytes to append + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanAppendBuffer(tAniPacket *destPacket, + v_U32_t len); + +/** + * aniAsfPacketCanPrependBuffer + * + * FUNCTION: + * Determines if len bytes can be safely prepended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet head minus len of buffer should not be less than + * start of packet. + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to prepend to + * @param len the number of bytes to prepend + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanPrependBuffer(tAniPacket *destPacket, + v_U32_t len); + +/** + * aniAsfPacketTruncateFromFront + * + * FUNCTION: + * Removes len bytes from the front of the packet by moving its + * head. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the front + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromFront(tAniPacket *packet, + v_U32_t len); + +/** + * aniAsfPacketTruncateFromRear + * + * FUNCTION: + * Removes len bytes from the rear of the packet by moving its + * tail. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the rear + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromRear(tAniPacket *packet, + v_U32_t len); + +/** + * aniAsfPacketGetLen + * + * FUNCTION: + * Returns the number of valid data bytes stored in the packet. + * + * @param packet the packet whose len we need + * + * @return the non-negative number of bytes stored in the packet + */ +int +aniAsfPacketGetLen(tAniPacket *packet); + +/** + * aniAsfPacketGetBytes + * + * FUNCTION: + * Returns a pointer to the head of the valid data stored in the + * packet. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytes(tAniPacket *packet, v_U8_t **rawBytesPtr); + +/** + * aniAsfPacketGetN + * + * Returns N bytes from the packet and moves the head of the packet + * beyond those bytes. + * + * @param packet the packet to read from + * @param n the number of bytes to read + * @param bytesPtr is set to the start of the octets + * + * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the + * packet does not have n bytes. + */ +int +aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr); + +/** + * aniAsfPacketEmpty + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the middle and + * setting the length to zero. + * + * @param packet the packet to empty + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmpty(tAniPacket *packet); + +/** + * aniAsfPacketEmptyExplicit + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the desired + * offset and setting the length to zero. + * + * @param packet the packet to empty + * @param offset the offset that the head of the packet should be set + * to. An application will be able to prepend and append data relative + * to this offset. + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmptyExplicit(tAniPacket *packet, + v_U32_t offset); + + +/** + * aniAsfPacketPrependHdr + * + * FUNCTION: + * Prepends a tAniHdr at the start of the packet. All host to network + * byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param msgType the message type to write as part of the header + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrependHdr(tAniPacket *packet, v_U16_t msgType); + +/** + * aniAsfPacketGet32 + * + * FUNCTION: + * Reads a ANI_U32 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet32(tAniPacket *packet, v_U32_t *val); + +/** + * aniAsfPacketAppend32 + * + * FUNCTION: + * Appends a ANI_U32 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend32(tAniPacket *packet, v_U32_t val); + +/** + * aniAsfPacketGet16 + * + * FUNCTION: + * Reads a ANI_U16 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val); + +/** + * aniAsfPacketPrepend16 + * + * FUNCTION: + * Prepends a ANI_U16 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val); + +/** + * aniAsfPacketAppend16 + * + * FUNCTION: + * Appends a ANI_U16 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val); + +/** + * aniAsfPacketGet8 + * + * FUNCTION: + * Reads a ANI_U8 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet8(tAniPacket *packet, v_U8_t *val); + +/** + * aniAsfPacketPrepend8 + * + * FUNCTION: + * Prepends a ANI_U8 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend8(tAniPacket *packet, v_U8_t val); + +/** + * aniAsfPacketAppend8 + * + * FUNCTION: + * Appends a ANI_U8 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend8(tAniPacket *packet, v_U8_t val); + +/** + * aniAsfPacketGetMac + * + * FUNCTION: + * Returns a tAniMacAddr from the start of the packet. + * + * @param packet the packet to read from + * @param macAddr the destination to copy the MAC address to + * + * @return ANI_OK if the operation succeeds. Also, the packet head + * pointer is advanced past the MAC address. + */ +int +aniAsfPacketGetMac(tAniPacket *packet, tAniMacAddr macAddr); + +/** + * aniAsfPacketMoveLeft + * + * FUNCTION: + * Pretends that a certain number of bytes have been prepended to the + * packet, without actually copying any bytes in. The packet head and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move head and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveLeft(tAniPacket *packet, v_U32_t count); + +/** + * aniAsfPacketMoveRight + * + * FUNCTION: + * Pretends that a certain number of bytes have been appended to the + * packet, without actually copying any bytes in. The packet tail and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move tail and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveRight(tAniPacket *packet, v_U32_t count); + +/** + * aniAsfPacketGetBytesFromTail + * + * FUNCTION: + * Returns a pointer to the tail of the valid data stored + * in the packet. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a three-step process - one: call this + * routine to obtain a pointer to the current tail of the packet. + * two: treat this returned pointer like a simple array and copy + * some bytes to the packet's internal buffer, and finally + * three: move tail and length. This violates the encapsulation + * the packet library aims to provide. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytesFromTail(tAniPacket *packet, v_U8_t **rawBytesPtr); + + +#endif // _ANI_ASF_PACKET_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnErrors.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnErrors.h new file mode 100644 index 0000000000000..a1f9712fe9f22 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnErrors.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniErrors.h $ + * + */ +/* + * Contains definitions of error codes that are globally visible + * across WNI applications. There are two kinds of error codes: + * generic error codes and module specific error codes. Module specific + * error codes can further be of two kinds: those that are used + * internally within sub-modules, and those that are made visible + * to other modules. Each module will be pre-allocated a range of + * negative integers from which to choose both internal and external + * error codes uniquely. Note that internally used error codes need + * not be defined in this file so long as they adhere to the allocated + * range. + * + * Author: Mayank D. Upadhyay + * Date: 17-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_ERRORS_H_ +#define _ANI_ERRORS_H_ + +/** + * Indicates that the function returned successfully and no error was + * reported. + */ +#define ANI_OK 0 +#define ANI_ERROR ANI_E_FAILED + +/** + * The range -1 to -1024 is reserved for generic error codes that are + * applicable to all modules. + */ + +#define ANI_E_FAILED -1 /// Generic error code for failure +#define ANI_E_MALLOC_FAILED -2 /// Mem allocation failed +#define ANI_E_ILLEGAL_ARG -3 /// Function argument is illegal +#define ANI_E_NULL_VALUE -4 /// Encountered unexpected NULL value +#define ANI_E_RAND_FAILED -5 /// RNG failed +#define ANI_E_SHORT_PACKET -6 /// Packet is too small to contain data +#define ANI_E_ELEM_NOT_FND -7 /// Element not found +#define ANI_E_INVALID_LEN -8 /// Element has invalid Length +#define ANI_E_INVALID_DT -9 /// Invalid Data Type +#define ANI_E_TIMEOUT -10 /// Timeout occurred +#define ANI_E_DBM_INVALID_ID -11 /// Invalid DB id sent to server +#define ANI_E_DBM_KEY_NOT_FOUND -12 /// Key's mapping was not found +#define ANI_E_FILE_EMPTY -13 /// file empty +#define ANI_E_INVALID_MT -14 /// Invalid ANI message type +#define ANI_E_NOT_IMPLEMENTED -15 /// Feature not implemented +#define ANI_E_INVALID_PT -16 /// Invalid Parameter Type +#define ANI_E_INVALID_PV -17 /// Invalid Paramter Value +#define ANI_E_IPCOPEN -18 /// IPC open failed +#define ANI_E_IPCCONNECT -19 /// IPC connect failed +#define ANI_E_IPCSEND -20 /// IPC send failed +#define ANI_E_FILE_NOT_FOUND -21 /// file not found +#define ANI_E_FILE_INVALID_CONTENT -22 /// invalid file content +#define ANI_E_FILE_READ_FAILED -23 /// file read failed + +// ***** SSM libraries and applications use the range -1025 to -2999 ***** + +/* + * The range -1025 to -2048 is reserved for use by the + * authentication agent and its sub-modules. The sub-range -1029 to + * -1150 is reserved for CLI usage. + */ +#define ANI_E_RANGE_START_AAG -1025 + +// CLI Range starts here... +#define ANI_E_RANGE_START_AAG_CLI -1029 +#define ANI_E_CLI_ARG_MISSING -1029 // CLI command param missing +#define ANI_E_CLI_ARG_INVALID -1030 // CLI command param invalid +#define ANI_E_CLI_PAM_RADIUS_DB_UPDATE_FAILURE -1031 // Failure to update PAM RADIUS DB +#define ANI_E_CLI_AUTH_SERVER_NOT_FOUND -1032 // Auth server not found +#define ANI_E_CLI_SYS_INTERNAL_ERROR_PACKET_NULL -1033 // Internal error +#define ANI_E_CLI_INVALID_DEVICE -1034 // Invalid device +#define ANI_E_CLI_AUTH_SERVER_INVALID_IPADDR -1035 // Invalid IP addr +#define ANI_E_CLI_AUTH_ZONE_NOT_EMPTY -1036 // zone not empty +#define ANI_E_CLI_AUTH_ZONE_AUTH_SERVERS_NOT_COPIED -1037 // zone not copied +#define ANI_E_CLI_AUTH_ZONE_NAME_MISSING -1038 // zone name missing +#define ANI_E_CLI_AUTH_ZONE_EMPTY -1039 // zone empty +#define ANI_E_CLI_AUTH_ZONE_NOT_FOUND -1040 // zone not found +#define ANI_E_CLI_AUTH_SERVER_ARG_NOT_FOUND -1041 // Cli Auth server arg missing +#define ANI_E_CLI_IFNAME_ARG_NOT_FOUND -1042 // Ifname arg missing +#define ANI_E_CLI_KEYINDEX_ARG_NOT_FOUND -1043 // Keyindex arg missing +#define ANI_E_CLI_KEYLENGTH_ARG_NOT_FOUND -1044 // KeyLength arg missing +#define ANI_E_CLI_KEYLENGTH_ARG_INVALID -1045 // KeyLength arg invalid +#define ANI_E_CLI_SET_WEP_KEY_FAILED -1046 // Set Wep key failed +#define ANI_E_CLI_SYS_INTERNAL_ERROR -1047 // Internal error +#define ANI_E_CLI_OLD_PASSWORD_MISSING -1048 // Old password missing +#define ANI_E_CLI_NEW_PASSWORD_MISSING -1049 // New password + // missing +#define ANI_E_CLI_WEP_KEY_LEN_ERROR -1051 // key length error +#define ANI_E_CLI_WEP_KEY_HEX_ERROR -1052 // no hex character +#define ANI_E_CLI_WPA_MODES_CFG_ERROR -1053 // WPA config error +#define ANI_E_CLI_WEP_AND_OPEN_CFG_ERROR -1054 // WEP and open error +#define ANI_E_CLI_OPEN_AND_WEP_CFG_ERROR -1055 // open and WEP error +#define ANI_E_CLI_LEGACY_WEP_AND_OPEN_CFG_ERROR -1056 // WEP and open error +#define ANI_E_CLI_OPEN_AND_LEGACY_WEP_CFG_ERROR -1057 // open and WEP error +#define ANI_E_CLI_WPA_MODES_NOT_AVAILABLE -1058 // WPA modes not active +#define ANI_E_CLI_INVALID_LISENCE_KEY -1059 // invalid license +#define ANI_E_CLI_EXISTING_LISENCE_KEY -1060 // duplicated license +#define ANI_E_CLI_WEP_INVALID_LENGTH_CHANGE -1061 // invalid length change +#define ANI_E_CLI_CNF_PASSWORD_MISMATCH -1062 // confirm password mismatch +#define ANI_E_CLI_INVALID_DISABLE -1063 // cannot disable all sec modes +#define ANI_E_CLI_PACKNUM_RANGE_ERROR -1064 // cannot disable all sec modes +#define ANI_E_CLI_IP_ADDR_INVALID -1065 // IP address invalid +#define ANI_E_CLI_AUTH_ZONE_NAME_INVALID -1066 // zone name invalid +#define ANI_E_CLI_OLD_PASSWORD_INVALID -1067 // Old password invalid +#define ANI_E_CLI_NO_EXT_RAD_ON_NONSECP -1068 // Cannot add ext auth-server on + // non-SEC/P with RAD proxying on +#define ANI_E_CLI_NO_EXT_AUTH_ZONE_ALLOWED -1069 // Cannot add ext auth-zone on + // with RAD proxying on +#define ANI_E_CLI_PORTAL_ZONE_AUTO_CONFIGURED -1070 // Cannot manage portal auth-zone +#define ANI_E_CLI_DEL_REQ_ON_REF_AUTH_SERVER -1071 // Cannot delete auth-server + // that is in a zone +#define ANI_E_CLI_DEL_REQ_ON_REF_AUTH_ZONE -1072 // Cannot delete auth-zone + // that is used by SSID +#define ANI_E_CLI_INVALID_INTERIM_UPDT_VALUE -1073 // Invalid Accounting interim update interval +#define ANI_E_RANGE_END_AAG_CLI -1199 +// ...CLI Range ends here + +// Non-CLI related error codes.. +#define ANI_E_MIC_FAILED -1200 // A MIC check failed +#define ANI_E_REPLAY_CHECK_FAILED -1201 // Replay Ctr mismatch +#define ANI_E_RADIUS_PROFILE_MISSING -1202 // User profile + // not found +#define ANI_E_AUTH_FAILED -1203 // Authentication failed +#define ANI_E_RADIUS_PRIV_LEVEL_MISSING -1204 // ANI_ADMIN_LEVEL is missing +#define ANI_E_RADIUS_PRIV_LEVEL_INCORRECT -1205 // ANI_ADMIN_LEVEL is incorrect + +// For some reason this is not contiguous with the other error codes(???) +#define ANI_E_INVALID_COOKIE -1300 // Invalid cookie + +#define ANI_E_RANGE_END_AAG -2048 + +/* + * The range -2049 to -2148 is reserved for use by the + * RADIUS client side library. + */ +#define ANI_E_RANGE_START_RAD -2049 +#define ANI_E_RAD_FAILED -2049 /// RADIUS operation failed +#define ANI_E_RAD_ATTR_TOO_LONG -2050 /// Attribute too long +#define ANI_E_RAD_UNSOLICITED_RESP -2051 /// Unsolicited response +#define ANI_E_RAD_BAD_RESP_AUTH -2052 /// Response auth check failed +#define ANI_E_RAD_BAD_MESSG_AUTH -2053 /// Response signature invalid +#define ANI_E_RAD_ATTR_NOT_FOUND -2054 /// Requested attr not found +#define ANI_E_RAD_TIMEOUT -2055 /// Request timed out waiting for server +#define ANI_E_RAD_REJECT -2056 /// Radius server did not accept user +#define ANI_E_RANGE_END_RAD -2148 + +/* + * The range -2149 to -2999 is reserved for use by the SSM library. + */ +#define ANI_E_RANGE_START_SSM -2149 +#define ANI_E_SSM_CERT_UNPARSEABLE (ANI_E_RANGE_START_SSM - 1) +#define ANI_E_SSM_CERT_EXPIRED (ANI_E_RANGE_START_SSM - 2) +#define ANI_E_SSM_CERT_THUMBPRINT_MISMATCH (ANI_E_RANGE_START_SSM - 3) +#define ANI_E_SSM_CERT_NEW_ID (ANI_E_RANGE_START_SSM - 4) +#define ANI_E_RANGE_END_SSM -2999 + +/* + * The range -3000 to -3500 is reserved for use by the + * NetSim Server, Client, Client Modules and Pseudo driver + */ +#define ANI_E_RANGE_START_NETSIM -3000 +#define ANI_E_RANGE_END_NETSIM -3500 + +/* + * The range -3501 to -4000 is reserved for use by the + * Discovery Server and its libraries. + */ +#define ANI_E_RANGE_START_DISC -3501 +#define ANI_E_RANGE_END_DISC -4000 + +/* + * The range -4001 to -4500 is reserved for use by the + * Ezcfg Server + */ +#define ANI_E_RANGE_START_EZC -4001 + +// See file aniNmpEzcSvcMsgs.h for EZC specific error codes and messages +#define ANI_E_RANGE_END_EZC -4500 + +/* + * The range -4501 to -4600 is reserved for use by the + * Software Download (SWD) Server + */ +#define ANI_E_RANGE_START_SWD -4501 + +// See file aniSwdSvcMsgs.h for SWD specific error codes and messages +#define ANI_E_RANGE_END_SWD -4600 + +/* + * The range -4601 to -4700 is reserved for use by the + * Data Distribution Service (DDS) Server + */ +#define ANI_E_RANGE_START_DDS -4601 + +// See file aniDdsSvcMsgs.h for DDS specific error codes and messages +#define ANI_E_RANGE_END_DDS -4700 + +/* + * The range -4701 to -4800 is reserved for use by + * HTTPS components. + */ +#define ANI_E_RANGE_START_HTTPS -4701 +#define ANI_E_HTTPS_UNREACHABLE (ANI_E_RANGE_START_HTTPS - 0) +#define ANI_E_HTTPS_UNTRUSTED_CERT (ANI_E_RANGE_START_HTTPS - 1) +#define ANI_E_HTTPS_RECVD_ALERT (ANI_E_RANGE_START_HTTPS - 2) +#define ANI_E_HTTPS_FAILED (ANI_E_RANGE_START_HTTPS - 3) +#define ANI_E_RANGE_END_HTTPS -4800 + +/* + * The range -4801 to -4900 is reserved for use by + * enrollment components. + */ +#define ANI_E_RANGE_START_ENROLLMENT -4801 +#define ANI_E_ENROLL_TP_AVAILABLE (ANI_E_RANGE_START_ENROLLMENT - 0) +#define ANI_E_ENROLL_ALREADY_TRUSTED (ANI_E_RANGE_START_ENROLLMENT - 1) +#define ANI_E_ENROLL_NOT_FOUND (ANI_E_RANGE_START_ENROLLMENT - 2) +#define ANI_E_ENROLL_PWD_FAILED (ANI_E_RANGE_START_ENROLLMENT - 3) +#define ANI_E_ENROLL_FAILED (ANI_E_RANGE_START_ENROLLMENT - 4) +#define ANI_E_ENROLL_NOT_PRISTINE (ANI_E_RANGE_START_ENROLLMENT - 5) +#define ANI_E_RANGE_END_ENROLLMENT -4900 + + +/* + * The range -4901 to -5000 is reserved for use by NSM. + */ +#define ANI_E_RANGE_START_NSM -4901 +#define ANI_E_NSM_IPADDR_ASSIGNED (ANI_E_RANGE_START_NSM - 0) +#define ANI_E_RANGE_END_NSM -5000 + +/* + * The range -5001 to -5100 is reserved for use by the image + * validation library. + */ +#define ANI_E_RANGE_START_IMAGE -5001 +#define ANI_E_IMAGE_INVALID (ANI_E_RANGE_START_IMAGE - 0) +#define ANI_E_IMAGE_UNSUPPORTED (ANI_E_RANGE_START_IMAGE - 1) +#define ANI_E_RANGE_END_IMAGE -5100 + +/* + * The range -5101 to -5200 is reserved for use by CM + */ +#define ANI_E_RANGE_START_CM -5101 +#define ANI_E_MESG_UNAVAILABLE (ANI_E_RANGE_START_IMAGE - 0) +#define ANI_E_RANGE_END_CM -5200 + + +#define ANI_IS_STATUS_SUCCESS( retVal ) ( ( retVal >= 0 ) ) + +#endif //_ANI_ERRORS_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.c new file mode 100644 index 0000000000000..1f826c4cd69d2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmAesKeyWrap.c $ + * + */ +/* + * Contains definitions for the AES Key Wrap algorithm from RFC 3394. + * + * Author: Mayank D. Upadhyay + * Date: 31-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#include "vos_types.h" +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" +#include "bapRsn8021xAuthFsm.h" +#include "vos_utils.h" +#include "vos_memory.h" +#include "vos_timer.h" +#include "bapRsnTxRx.h" +#include "bapRsnSsmAesKeyWrap.h" + +#if 0 + +#include +#include +#include + +#include +#include +#include +#include + +#include "aniSsmAesKeyWrap.h" +#include "aniSsmUtils.h" +#endif + +#define ANI_SSM_AES_KEY_WRAP_IC_SIZE ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE + +typedef struct tag_aes_key { + tANI_U32 eK[64], dK[64]; + int Nr; +} AES_KEY; + +static tANI_U8 gAniSsmAesKeyWrapIv[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 +}; + +static int +aes(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]); + +static int +aes_1(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 at[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]); + +static int +xor(tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], tANI_U32 t); + +/** + * Implements the AES Key Wrap algorithm described in RFC 3394. + * If n is the number of blocks in plainText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The first block is the IV from section 2.2.3 o the + * RFC. Note: It is the caller's responsibility to free the returned + * value. + * + * @param plainText the plaintext data to wrap + * @param len the length of the plaintext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param cipherTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyWrap(v_U32_t cryptHandle, tANI_U8 *plainText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **cipherTextPtr) +{ + int i, j, n; + int retVal; + + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE]; + tANI_U8 *r = NULL; + tANI_U32 t; + + tANI_U8 b[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2]; + + n = len / ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if ((len % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Illegal number of input bytes to AES Key Wrap!"); + return ANI_E_ILLEGAL_ARG; + } + + // Allocate enough storage for 'A' as well as 'R' + r = vos_mem_malloc((n + 1) * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + if (r == NULL) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Could not allocate space for R"); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(a, gAniSsmAesKeyWrapIv, sizeof(a)); + vos_mem_copy(r + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, plainText, len); + + for (j = 0; j <= 5; j++) { + for (i = 1; i <= n; i++) { + + retVal = aes(cryptHandle, keyEncKey, keyEncKeyLen, + a, + r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b); + + if( !ANI_IS_STATUS_SUCCESS( retVal) ) goto error; + + vos_mem_copy(a, b, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + t = n*j + i; + xor(a, t); + vos_mem_copy(r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b + sizeof(b) - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + } + + vos_mem_copy(r, a, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + *cipherTextPtr = r; + + return ANI_OK; + + error: + if (r != NULL) + vos_mem_free(r); + + return retVal; + +} + +/** + * Implements the AES Key Unwrap algorithm described in RFC 3394. + * If (n+1) is the number of blocks in cipherText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The actual plaintext consists of n blocks that start at the + * second block. Note: It is the caller's responsibility to free the + * returned value. + * + * @param cipherText the cipertext data to unwrap + * @param len the length of the ciphertext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param plainTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyUnwrap(v_U32_t cryptHandle, tANI_U8 *cipherText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **plainTextPtr) +{ + int i, j; + int retVal; + + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE]; + tANI_U8 *r = NULL; + tANI_U32 n; + tANI_U32 t; + + tANI_U8 b[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2]; + + n = len / ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - 1; + if ((len % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Illegal number of input bytes to AES Key Unwrap!"); + return ANI_E_ILLEGAL_ARG; + } + + // Allocate enough storage for 'A' as well as 'R' + r = vos_mem_malloc((n + 1) * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + if (r == NULL) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Could not allocate space for R"); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(a, cipherText, sizeof(a)); + vos_mem_copy(r + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + cipherText + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + len - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + + for (j = 5; j >= 0; j--) { + for (i = n; i >= 1; i--) { + + t = n*j + i; + xor(a, t); + retVal = aes_1(cryptHandle, keyEncKey, keyEncKeyLen, + a, + r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) goto error; + + vos_mem_copy(a, b, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b + sizeof(b) - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + } + + if (vos_mem_compare2(a, gAniSsmAesKeyWrapIv, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + retVal = ANI_E_MIC_FAILED; + goto error; + } + + *plainTextPtr = r; + + return ANI_OK; + + error: + if (r != NULL) + vos_mem_free(r); + + return retVal; +} + +static int +aes(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]) { + + int retVal = 0; + +// AES_KEY aesKey; + + tANI_U8 in[AES_BLOCK_SIZE]; + tANI_U8 *out; + + // Concatenate A and R[i] + vos_mem_copy(in, a, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(in + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ri, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + out = b; + +#if 0 + retVal = AES_set_encrypt_key(keyBytes, keyLen*8, &aesKey); + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "AES_set_encrypt_key returned %d", retVal); + return ANI_E_FAILED; + } + + AES_encrypt(in, out, &aesKey); +#else // Enable to use VOS function + retVal = vos_encrypt_AES(cryptHandle, /* Handle */ + in, /* input */ + out, /* output */ + keyBytes); /* key */ + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "vos_encrypt_AES returned %d", retVal); + return ANI_E_FAILED; + } +#endif + return ANI_OK; +} + +static int +aes_1(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 at[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]) { + + int retVal; + +// AES_KEY aesKey; + + tANI_U8 in[AES_BLOCK_SIZE]; + tANI_U8 *out; + + // Concatenate A and R[i] + vos_mem_copy(in, at, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(in + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ri, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + out = b; + +#if 0 + retVal = AES_set_decrypt_key(keyBytes, keyLen*8, &aesKey); + if (retVal != 0) { + ANI_SSM_LOG_E("AES_set_encrypt_key returned %d", retVal); + assert(0 && "AES_set_encrypt_key failed!"); + return ANI_E_FAILED; + } + + AES_decrypt(in, out, &aesKey); +#else + retVal = vos_decrypt_AES(cryptHandle, /* Handle */ + in, /* input */ + out, /* output */ + keyBytes); /* key */ + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "vos_decrypt_AES returned %d", retVal); + } +#endif + return ANI_OK; +} + +// From File : aniAsfHdr.h + + + +/* + * Put a long in host order into a char array in network order. + * + */ +static inline char *aniAsfWr32(char *cp, tANI_U32 x) +{ + tAniU32ValAry r; + int i; + + r.val = vos_cpu_to_be32(x); + i = sizeof(tANI_U32) - 1; + cp[3] = r.ary[i--]; + cp[2] = r.ary[i--]; + cp[1] = r.ary[i--]; + cp[0] = r.ary[i]; + + return (cp + sizeof(tANI_U32)); +} + +// From file : aniAsfMisc.c + +/* + * Put a long in host order into a char array in network order. + * + */ +char *aniAsfPut32(char *cp, tANI_U32 x) +{ + return(aniAsfWr32(cp, x)); +} + + +static int +xor(tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], tANI_U32 t) +{ + tANI_U8 tmp[4]; + aniAsfPut32((char *)tmp, t); + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-1] ^= tmp[3]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-2] ^= tmp[2]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-3] ^= tmp[1]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-4] ^= tmp[0]; + return ANI_OK; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.h new file mode 100644 index 0000000000000..b3a3e95b615d8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmAesKeyWrap.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Ref File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/include/aniSsmAesKeyWrap.h $ + * + */ +/* + * Contains SSM-private declarations related to the AES key WRAP + * algorithm described in RFC 3394. + * + * Author: Arul V Raj + * Date: 27-February-2009 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_SSM_AES_KEY_WRAP_H_ +#define _ANI_SSM_AES_KEY_WRAP_H_ + +#define ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE 8 // Bytes +#define AES_BLOCK_SIZE 16 // Bytes + +typedef union uAniU32ValAry{ + tANI_U32 val; + char ary[sizeof(tANI_U32)]; +} tAniU32ValAry; + +/** + * Implements the AES Key Wrap algorithm described in RFC 3394. + * If n is the number of blocks in plainText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The first block is the IV from section 2.2.3 o the + * RFC. Note: It is the caller's responsibility to free the returned + * value. + * + * @param plainText the plaintext data to wrap + * @param len the length of the plaintext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param cipherTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyWrap(v_U32_t cryptHandle, tANI_U8 *plainText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **cipherTextPtr); + +/** + * Implements the AES Key Unwrap algorithm described in RFC 3394. + * If (n+1) is the number of blocks in cipherText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The actual plaintext consists of n blocks that start at the + * second block. Note: It is the caller's responsibility to free the + * returned value. + * + * @param cipherText the cipertext data to unwrap + * @param len the length of the ciphertext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param plainTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyUnwrap(v_U32_t cryptHandle, tANI_U8 *cipherText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **plainTextPtr); + + +#endif //_ANI_SSM_AES_KEY_WRAP_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.c new file mode 100644 index 0000000000000..bf42b8b3593e0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.c @@ -0,0 +1,1134 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmEapol.c#2 $ + * + */ +/* + * Contains definitions of various utilities for EAPoL frame + * parsing and creation. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_utils.h" +#include +#include +#include +#include "bapRsn8021xFsm.h" +#include "vos_memory.h" + +//#include "aniSsmUtils.h" + + +//TODO: Put these in an array after EAPOL_TYPE is made an enum +#define ANI_EAPOL_TYPE_PACKET_STR "EAP" +#define ANI_EAPOL_TYPE_START_STR "START" +#define ANI_EAPOL_TYPE_LOGOFF_STR "LOGOFF" +#define ANI_EAPOL_TYPE_KEY_STR "KEY" +#define ANI_EAPOL_TYPE_ASF_ALERT_STR "ALERT" +#define ANI_EAPOL_TYPE_UNKNOWN_STR "UNKNOWN" + +/** + * The EAPOL packet is structured as follows: + */ +#define DST_MAC_POS 0 +#define SRC_MAC_POS 6 +#define ETHER_PROTO_POS 12 +#define EAPOL_VERSION_POS 14 +#define ANI_EAPOL_TYPE_POS 15 +#define EAPOL_BODY_LEN_POS 16 +#define EAPOL_BODY_POS EAPOL_RX_HEADER_SIZE + +#define EAPOL_BODY_LEN_SIZE 2 + +#define ANI_SSM_LEGACY_RC4_KEY_SIGN_OFFSET (EAPOL_BODY_POS + 28) + +/** + * Bitmasks for the RSN Key Information field + */ +#define ANI_SSM_RSN_KEY_DESC_VERS_MASK 0x0007 +#define ANI_SSM_RSN_UNICAST_MASK 0x0008 +#define ANI_SSM_RSN_KEY_INDEX_MASK 0x0030 +#define ANI_SSM_RSN_INSTALL_MASK 0x0040 +#define ANI_SSM_RSN_ACK_MASK 0x0080 +#define ANI_SSM_RSN_MIC_MASK 0x0100 +#define ANI_SSM_RSN_SECURE_MASK 0x0200 +#define ANI_SSM_RSN_ERROR_MASK 0x0400 +#define ANI_SSM_RSN_REQUEST_MASK 0x0800 +#define ANI_SSM_RSN_ENC_KEY_DATA_MASK 0x1000 + +#define ANI_SSM_RSN_KEY_DESC_VERS_OFFSET 0 +#define ANI_SSM_RSN_KEY_INDEX_OFFSET 4 + +#define ANI_SSM_RSN_KEY_MIC_OFFSET (EAPOL_BODY_POS + 77) + +/** + * Other hard coded values for convenience: + */ +static const v_U8_t +ANI_ETH_P_EAPOL_BYTES[2] = {0x00, 0x03};//BT-AMP security type{0x88, 0x8e}; +static const v_U8_t +EAPOL_VERSION_BYTES[1] = {EAPOL_VERSION_1}; +static const v_U8_t +ANI_EAPOL_TYPE_PACKET_BYTES[1] = {ANI_EAPOL_TYPE_PACKET}; +static const v_U8_t +ANI_EAPOL_TYPE_START_BYTES[1] = {ANI_EAPOL_TYPE_START}; +static const v_U8_t +ANI_EAPOL_TYPE_LOGOFF_BYTES[1] = {ANI_EAPOL_TYPE_LOGOFF}; +static const v_U8_t +ANI_EAPOL_TYPE_KEY_BYTES[1] = {ANI_EAPOL_TYPE_KEY}; +static const v_U8_t +ANI_EAPOL_TYPE_ASF_ALERT_BYTES[1] = {ANI_EAPOL_TYPE_ASF_ALERT}; +static const v_U8_t +ZERO_BYTES[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static v_U8_t BAP_RSN_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x19, 0x58 }; + + + +static int +parseRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc **rsnDescPtr); + +static int +parseRsnKeyInfo(tAniPacket *packet, + tAniRsnKeyInfo *info); + +static int +writeRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t keyDescType); + +static int +writeRsnKeyInfo(tAniPacket *packet, tAniRsnKeyInfo *info); + +static int +writeRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen); + +static int +checkRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen); + +extern void authEapolHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type); +extern void suppEapolHandler( tSuppRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type); + +/** + * addEapolHeaders + * + * FUNCTION: + * Prepends the EAPOL header to a packet. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the EAPOL + * header. + * + * @param packet the packet to prepend to + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * @param eapolType the EAPOL-Type field + * + * @return ANI_OK if the operation succeeds + */ +static int +addEapolHeaders(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t eapolType) +{ + int retVal; + v_U16_t len; + + do + { + retVal = aniAsfPacketGetLen(packet); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + len = retVal; + retVal = aniAsfPacketPrepend16(packet, len); + + retVal = aniAsfPacketPrepend8(packet, eapolType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, EAPOL_VERSION_BYTES, 1); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, ANI_ETH_P_EAPOL_BYTES, 2); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + //Since TL expects SNAP header in all packets we send, put it in + retVal = aniAsfPacketPrependBuffer(packet, BAP_RSN_LLC_HEADER, sizeof(BAP_RSN_LLC_HEADER)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + //packet length + len += 6/*length + eapolType+version + eth_type*/ + sizeof(BAP_RSN_LLC_HEADER); + retVal = aniAsfPacketPrepend16(packet, len); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, srcMac, sizeof(tAniMacAddr)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, dstMac, sizeof(tAniMacAddr)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + }while( 0 ); + + return retVal; +} + +/** + * aniEapolWriteStart + * + * FUNCTION: + * Writes an EAPOL-Start frame to the packet. It is only used by the + * supplicant. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. There is no + * EAPOL payload for this kind of frame. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the header. + * + * @param packet the packet to which the frame should be written + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteStart(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac) +{ + return ( addEapolHeaders(packet, dstMac, srcMac, ANI_EAPOL_TYPE_START) ); +} + +/** + * aniEapolWriteEapPacket + * + * FUNCTION: + * Writes the EAPOL/EAP-Packet frame headers. It is used + * by both the authenticator and the supplicant. This creates an EAPOL + * frame that is carrying an EAP message as its payload. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. + * + * ASSUMPTIONS: + * The EAP message (ie., the payload) is already available in the + * packet and that the packet has enough space available for + * prepending the EAPOL header. + * + * @param packet the packet containing the EAP message + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteEapPacket(tAniPacket *eapPacket, + tAniMacAddr dstMac, + tAniMacAddr srcMac) +{ + return( addEapolHeaders(eapPacket, dstMac, srcMac, ANI_EAPOL_TYPE_PACKET) ); +} + +/** + * aniEapolParse + * + * FUNCTION: + * Parses an EAPoL frame to the first level of headers (no EAP + * headers are parsed). + * + * NOTE: This is a non-destructive read, that is the + * headers are not stripped off the packet. However, any additional + * data at the end of the packet, beyond what the EAPoL headers encode + * will be stripped off. + * + * @param packet the packet containing the EAPoL frame to parse + * @param dstMac a pointer to set to the location of the destination + * MAC address + * @param srcMac a pointer to set to the location of the source + * MAC address + * @param type a pointer to set to the location of the EAPOL type + * field. + * + * @return the non-negative length of the EAPOL payload if the operation + * succeeds + */ +int +aniEapolParse(tAniPacket *packet, + v_U8_t **dstMac, + v_U8_t **srcMac, + v_U8_t **type) +{ + v_U16_t frameType; + v_U8_t *ptr; + int retVal; + int tmp; + + if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS) + return ANI_E_ILLEGAL_ARG; + + retVal = aniAsfPacketGetBytes(packet, &ptr); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Supp parsing EAPOL packet of len %d: \n", + retVal); + + frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1]; + + /* + * Validate the EAPOL-FRAME + */ + + if (frameType != ANI_ETH_P_EAPOL) + return ANI_E_ILLEGAL_ARG; + + *dstMac = ptr + DST_MAC_POS; + *srcMac = ptr + SRC_MAC_POS; + + // if (ptr[EAPOL_VERSION_POS] != EAPOL_VERSION_1) + // return ANI_E_ILLEGAL_ARG; + + *type = ptr + ANI_EAPOL_TYPE_POS; + retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1]; + + /* + * Validate the length of the body. Allow for longer + * packets than encoded, but encoding should not be larger than + * packet. + * Note: EAPOL body len does not include headers + */ + tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE; + if (retVal > tmp) + { + retVal = ANI_E_ILLEGAL_ARG; + } + else { + if (retVal < tmp) + { + retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal); + } + } + + return retVal; +} + +/** + * aniEapolWriteKey + * + * Writes out a complete EAPOL-Key frame. The key descriptor is + * appended to the packet and the EAPOL header is prepended to it. If + * a micKey is passed in, then a MIC is calculated and inserted into + * the frame. + * + * @param packet the packet to write to + * @param dstMac the destination MAC address + * @param srcMac the source MAC address + * @param descType the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData the key descriptor data corresponding to the + * above descType. The signature field is ignored and will be + * generated in the packet. The key bytes are expected to be encrypted + * if they need to be encrypted. + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds + * + */ +int +aniEapolWriteKey(v_U32_t cryptHandle, + tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + do + { + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + + retVal = writeRsnKeyDesc(packet, + (tAniEapolRsnKeyDesc *) keyDescData, + // Indicate + // ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW + // or ANI_EAPOL_KEY_DESC_TYPE_RSN + descType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + break; + } + + retVal = addEapolHeaders(packet, dstMac, srcMac, ANI_EAPOL_TYPE_KEY); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + retVal = writeRsnKeyMic(cryptHandle, + packet, + (tAniEapolRsnKeyDesc *) keyDescData, + micKey, micKeyLen); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + } + else { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + }while( 0 ); + + return retVal; +} + + +/** + * aniEapolParseKey + * + * Parses and verifies a complete EAPOL-Key frame. The key descriptor + * type is returned and so is a newly allocated key descriptor structure + * that is appropriate for the type. + * + * NOTE: This is a non-destructive read. That is, the packet headers + * will be unchanged at the end of this read operation. This is so + * that a followup MIC check may be done on the complete packet. If + * the packet parsing fails, the packet headers are not guaranteed to + * be unchanged. + * + * @param packet the packet to read from. Note that the frame is not + * expected to contain any additional padding at the end other than + * the exact number of key bytes. (The aniEapolParse function will + * ensure this.) + * @param descType is set to the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData is set to a newly allocated key descriptor + * corresponding to the above descType. The signature field is + * verified. The key bytes will be returned encrypted. It is the + * responsibility of the caller to free this structure and the data + * contained therein. + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolParseKey(tAniPacket *packet, + int *descType, + void **keyDescData) +{ + int retVal; + v_U8_t *bytes; + v_U32_t eapolFrameLen; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + do + { + eapolFrameLen = aniAsfPacketGetLen(packet); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL-Key frame of len %d\n", + eapolFrameLen); + + retVal = aniAsfPacketTruncateFromFront(packet, EAPOL_RX_HEADER_SIZE); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + retVal = aniAsfPacketGetBytes(packet, &bytes); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + if (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN || + *bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + tAniEapolRsnKeyDesc *rsnDesc = NULL; + + //*descType = ANI_EAPOL_KEY_DESC_TYPE_RSN; + *descType = (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW ? + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW : ANI_EAPOL_KEY_DESC_TYPE_RSN) ; + retVal = parseRsnKeyDesc(packet, &rsnDesc); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + *keyDescData = rsnDesc; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp received unknown EAPOL-Key descriptor: %d\n", + *bytes); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + aniAsfPacketMoveLeft(packet, eapolFrameLen); + }while( 0 ); + + return retVal; +} + + + +static int +parseRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc **rsnDescPtr) +{ + int retVal = ANI_OK; + int len; + v_U8_t *bytes; + tAniEapolRsnKeyDesc *rsnDesc = NULL; + + do + { + aniAsfPacketTruncateFromFront(packet, 1); // Desc-Type + + rsnDesc = (tAniEapolRsnKeyDesc *) + vos_mem_malloc( sizeof(tAniEapolRsnKeyDesc) ); + + if (rsnDesc == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp could not malloc EAPOL-Key Descriptor for RSN\n"); + retVal = ANI_E_MALLOC_FAILED; + break; + } + + retVal = parseRsnKeyInfo(packet, &rsnDesc->info); + if (retVal != ANI_OK) break; + + retVal = aniAsfPacketGet16(packet, &rsnDesc->keyLen); + if (retVal != ANI_OK) + { + break; + } + + len = sizeof(rsnDesc->replayCounter); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->replayCounter, bytes, len); + + len = sizeof(rsnDesc->keyNonce); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyNonce, bytes, len); + + len = sizeof(rsnDesc->keyIv); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyIv, bytes, len); + + len = sizeof(rsnDesc->keyRecvSeqCounter); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyRecvSeqCounter, bytes, len); + + len = sizeof(rsnDesc->keyId); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyId, bytes, len); + + len = sizeof(rsnDesc->keyMic); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyMic, bytes, len); + + retVal = aniAsfPacketGet16(packet, &rsnDesc->keyDataLen); + if (retVal != ANI_OK) + { + break; + } + + len = rsnDesc->keyDataLen; + if (len > 0) { + // We have a key + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + rsnDesc->keyData = (v_U8_t*)vos_mem_malloc(len); + if (rsnDesc->keyData == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Could not allocate RSN key bytes!\n"); + VOS_ASSERT( 0 ); + retVal = ANI_E_MALLOC_FAILED; + break; + } + vos_mem_copy(rsnDesc->keyData, bytes, len); + } + else { + rsnDesc->keyData = NULL; + } + + *rsnDescPtr = rsnDesc; + + }while( 0 ); + + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + vos_mem_free(rsnDesc); + } + + return retVal; +} + +static int +parseRsnKeyInfo(tAniPacket *packet, + tAniRsnKeyInfo *info) +{ + v_U16_t tmp; + int retVal; + + retVal = aniAsfPacketGet16(packet, &tmp); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + info->keyDescVers = (tmp & ANI_SSM_RSN_KEY_DESC_VERS_MASK) + >> ANI_SSM_RSN_KEY_DESC_VERS_OFFSET; + if (info->keyDescVers != ANI_EAPOL_KEY_DESC_VERS_RC4 && + info->keyDescVers != ANI_EAPOL_KEY_DESC_VERS_AES) + return ANI_E_ILLEGAL_ARG; + + info->unicastFlag = (tmp & ANI_SSM_RSN_UNICAST_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->keyId = (tmp & ANI_SSM_RSN_KEY_INDEX_MASK) + >> ANI_SSM_RSN_KEY_INDEX_OFFSET; + info->installFlag = (tmp & ANI_SSM_RSN_INSTALL_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->ackFlag = (tmp & ANI_SSM_RSN_ACK_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->micFlag = (tmp & ANI_SSM_RSN_MIC_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->secureFlag = (tmp & ANI_SSM_RSN_SECURE_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->errorFlag = (tmp & ANI_SSM_RSN_ERROR_MASK) ? + eANI_BOOLEAN_TRUE: eANI_BOOLEAN_FALSE; + info->requestFlag = (tmp & ANI_SSM_RSN_REQUEST_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->encKeyDataFlag = (tmp & ANI_SSM_RSN_ENC_KEY_DATA_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + + return ANI_OK; +} + + +static int +writeRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t keyDescType) +{ + int retVal; + + do + { + // This can be either ANI_EAPOL_KEY_DESC_TYPE_RSN + // or ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW + retVal = aniAsfPacketAppend8(packet, keyDescType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = writeRsnKeyInfo(packet, &rsnDesc->info); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppend16(packet, rsnDesc->keyLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->replayCounter, + sizeof(rsnDesc->replayCounter)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyNonce, + sizeof(rsnDesc->keyNonce)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyIv, + sizeof(rsnDesc->keyIv)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyRecvSeqCounter, + sizeof(rsnDesc->keyRecvSeqCounter)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyId, + sizeof(rsnDesc->keyId)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + // Zero out the key MIC + retVal = aniAsfPacketAppendBuffer(packet, + ZERO_BYTES, + sizeof(rsnDesc->keyMic)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppend16(packet, rsnDesc->keyDataLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if (rsnDesc->keyDataLen != 0) + { + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyData, + rsnDesc->keyDataLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + } + }while( 0 ); + + return retVal; +} + +static int +writeRsnKeyInfo(tAniPacket *packet, tAniRsnKeyInfo *info) +{ + int retVal; + v_U16_t tmp; + v_U16_t infoValue; + + infoValue = 0; + + tmp = (v_U16_t)info->keyDescVers; + tmp = tmp << ANI_SSM_RSN_KEY_DESC_VERS_OFFSET; + infoValue |= (tmp & ANI_SSM_RSN_KEY_DESC_VERS_MASK); + + if (info->unicastFlag) + infoValue |= ANI_SSM_RSN_UNICAST_MASK; + + tmp = info->keyId; + tmp = tmp << ANI_SSM_RSN_KEY_INDEX_OFFSET; + infoValue |= (tmp & ANI_SSM_RSN_KEY_INDEX_MASK); + + if (info->installFlag) + infoValue |= ANI_SSM_RSN_INSTALL_MASK; + + if (info->ackFlag) + infoValue |= ANI_SSM_RSN_ACK_MASK; + + if (info->micFlag) + infoValue |= ANI_SSM_RSN_MIC_MASK; + + if (info->secureFlag) + infoValue |= ANI_SSM_RSN_SECURE_MASK; + + if (info->errorFlag) + infoValue |= ANI_SSM_RSN_ERROR_MASK; + + if (info->requestFlag) + infoValue |= ANI_SSM_RSN_REQUEST_MASK; + + if (info->encKeyDataFlag) + infoValue |= ANI_SSM_RSN_ENC_KEY_DATA_MASK; + + retVal = aniAsfPacketAppend16(packet, infoValue); + + return retVal; +} + + +static int +writeRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal = ANI_OK; + int len; + + v_U8_t *ptr = NULL; + v_U8_t *micPos = NULL; + v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two + + // Sanity check the arguments and return if no MIC generation is + // needed + if (micKey != NULL) + { + if (micKeyLen == 0 || !rsnDesc->info.micFlag) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp MIC key provided but micKeyLen or micFlag is not set!\n"); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + } + else { + if (rsnDesc->info.micFlag) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp micFlag is set but MIC key not provided!\n"); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + // Normal condition where MIC is not desired by the caller + return ANI_OK; + } + + len = aniAsfPacketGetBytes(eapolFrame, &ptr); + if( !ANI_IS_STATUS_SUCCESS( len ) ) + { + return len; + } + + micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE; + + // Clear the MIC field in the packet before the MIC computation + vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE); + + // Skip to the EAPOL version field for MIC computation + ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE; + len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE); + + if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) + { + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) + { + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + } + else { + VOS_ASSERT( 0 ); + retVal = ANI_E_ILLEGAL_ARG; + } + + if (retVal == ANI_OK) + { + // Copy only 16B which is the smaller of the two and the same as + // ANI_EAPOL_KEY_RSN_MIC_SIZE + vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE); + } + + return retVal; +} + +/** + * aniEapolKeyCheckMic + * + * @param eapolFrame the complete EAPOL-Key packet + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds; ANI_E_MIC_FAILED if the + * MIC check fails. + */ +int +aniEapolKeyCheckMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + if (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + return checkRsnKeyMic(cryptHandle, eapolFrame, keyDescData, micKey, micKeyLen); + } + else { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } +} + + +static int +checkRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal = ANI_ERROR; + int len; + + v_U8_t *ptr = NULL; + v_U8_t *micPos = NULL; + + v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two + v_U8_t incomingMic[ANI_EAPOL_KEY_RSN_MIC_SIZE]; + + if (!rsnDesc->info.micFlag) + { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + + len = aniAsfPacketGetBytes(eapolFrame, &ptr); + if( ANI_IS_STATUS_SUCCESS( len ) ) + { + micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET; + + // Skip to the EAPOL version field for MIC computation + ptr += EAPOL_VERSION_POS; + len -= EAPOL_VERSION_POS; + + // Copy existing MIC to temporary location and zero it out + vos_mem_copy( incomingMic, micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); + vos_mem_zero( micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); + + if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) + { + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) + { + retVal = ANI_OK; + } + } + else { + VOS_ASSERT( 0 ); + retVal = ANI_E_ILLEGAL_ARG; + } + + if (retVal == ANI_OK) + { + if ( !vos_mem_compare(incomingMic, result, ANI_EAPOL_KEY_RSN_MIC_SIZE)) + { + retVal = ANI_E_MIC_FAILED; + } + } + } + + return retVal; +} + +/** + * aniEapolKeyFreeDesc + * + * Frees the EAPOL key descriptor and the key bytes contained within it. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyFreeDesc(int descType, void *keyDescData) +{ + tAniEapolRsnKeyDesc *rsnDesc; + + if( keyDescData ) + { + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + + rsnDesc = (tAniEapolRsnKeyDesc *) keyDescData; + if (rsnDesc->keyData != NULL) + vos_mem_free(rsnDesc->keyData); + + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp asked to free illegal type: %d\n", descType); + + } + + vos_mem_free(keyDescData); + } + + return ANI_OK; +} + +v_U8_t * +aniEapolType2Str(v_U8_t type) +{ + switch (type) + { + case ANI_EAPOL_TYPE_PACKET: + return (v_U8_t *)ANI_EAPOL_TYPE_PACKET_STR; + break; + case ANI_EAPOL_TYPE_START: + return (v_U8_t *)ANI_EAPOL_TYPE_START_STR; + break; + case ANI_EAPOL_TYPE_LOGOFF: + return (v_U8_t *)ANI_EAPOL_TYPE_LOGOFF_STR; + break; + case ANI_EAPOL_TYPE_KEY: + return (v_U8_t *)ANI_EAPOL_TYPE_KEY_STR; + break; + case ANI_EAPOL_TYPE_ASF_ALERT: + return (v_U8_t *)ANI_EAPOL_TYPE_ASF_ALERT_STR; + break; + default: + return (v_U8_t *)ANI_EAPOL_TYPE_UNKNOWN_STR; + break; + } +} + + +void bapRsnEapolHandler( v_PVOID_t pvFsm, tAniPacket *packet, v_BOOL_t fIsAuth ) +{ + int retVal; + v_U8_t *dstMac = NULL; + v_U8_t *srcMac = NULL; + v_U8_t *type = NULL; + + retVal = aniEapolParse(packet, &dstMac, &srcMac, &type); + if ( retVal >= 0 ) + { + retVal = ANI_OK; + + // Sanity check that a PAE role has been assigned to it, + // and then dispatch to the appropriate handler + + if( fIsAuth ) + { + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pvFsm; + authEapolHandler( fsm, packet, dstMac, srcMac, type ); + } + else + { + tSuppRsnFsm *fsm = (tSuppRsnFsm *)pvFsm; + suppEapolHandler(fsm, packet, dstMac, srcMac, type); + } // switch statement + } // Successfully parsed EAPOL + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "eapolHandler Received bad EAPOL message of len %d (status=%d)\n", + aniAsfPacketGetLen(packet), retVal ); + } + aniAsfPacketFree( packet ); +} + + +int bapRsnFormPktFromVosPkt( tAniPacket **ppPacket, vos_pkt_t *pVosPacket ) +{ + int retVal = ANI_ERROR; + VOS_STATUS status; + v_U16_t uPktLen; +#define BAP_RSN_SNAP_TYPE_OFFSET 20 +#define BAP_RSN_ETHERNET_3_HEADER_LEN 22 + v_U8_t *pFrame = NULL; + tAniPacket *pAniPacket = NULL; + + do + { + status = vos_pkt_get_packet_length( pVosPacket, &uPktLen ); + if( !VOS_IS_STATUS_SUCCESS(status) ) break; + if( (uPktLen < BAP_RSN_ETHERNET_3_HEADER_LEN) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler receive eapol packet size (%d) too small (%d)\n", + uPktLen, BAP_RSN_ETHERNET_3_HEADER_LEN ); + break; + } + status = vos_pkt_peek_data( pVosPacket, 0, (v_VOID_t *)&pFrame, uPktLen ); + if( !VOS_IS_STATUS_SUCCESS(status) || (NULL == pFrame) ) break; + retVal = aniAsfPacketAllocateExplicit(&pAniPacket, uPktLen, 0 ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler failed to get buffer size (%d) \n", + uPktLen ); + break; + } + aniAsfPacketEmptyExplicit( pAniPacket, 0 ); + pFrame[ETHER_PROTO_POS] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET]; + pFrame[ETHER_PROTO_POS + 1] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET + 1]; + //push ethernet II header in + retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame, ETHER_PROTO_POS + 2 ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Get the rest of the data in + uPktLen -= BAP_RSN_ETHERNET_3_HEADER_LEN; + if (uPktLen <= 0){ + VOS_ASSERT(0); + retVal = ANI_ERROR; + break; + } + + retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame + BAP_RSN_ETHERNET_3_HEADER_LEN, + uPktLen ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler cannot retrieve eapol payload size (%d)\n", + uPktLen ); + break; + } + }while( 0 ); + + if( ANI_IS_STATUS_SUCCESS( retVal ) ) + { + *ppPacket = pAniPacket; + } + else if( pAniPacket ) + { + aniAsfPacketFree( pAniPacket ); + } + + return retVal; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.h new file mode 100644 index 0000000000000..8cbff43643730 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmEapol.h @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmEapol.h#1 $ + * Contains declarations of various utilities for EAPoL frame + * parsing and creation. + * range. + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_SSM_EAPOL_H_ +#define _ANI_SSM_EAPOL_H_ + +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_packet.h" +#include + +#define ANI_ETH_P_EAPOL 0x0003 +#define ANI_ETH_P_IP 0x0800 + +/** + * The EAPOL type field is one of the following: + */ +#define ANI_EAPOL_TYPE_PACKET 0 +#define ANI_EAPOL_TYPE_START 1 +#define ANI_EAPOL_TYPE_LOGOFF 2 +#define ANI_EAPOL_TYPE_KEY 3 +#define ANI_EAPOL_TYPE_ASF_ALERT 4 + +#define EAPOL_VERSION_1 0x01 + +#define EAPOL_RX_HEADER_SIZE 18 +#define EAPOL_TX_HEADER_SIZE 26 //include LLC_SNAP +#define SNAP_HEADER_SIZE 8 + +#define ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 1 +// JEZ20041012 This needs to be fixed. This needs to support BOTH +// the older WPA Key Descriptor type of 254 AS WELL AS the newer +// Key Descriptor type of 2 +#define ANI_EAPOL_KEY_DESC_TYPE_RSN 254 +//#define ANI_EAPOL_KEY_DESC_TYPE_RSN 2 +#define ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW 2 + +#define ANI_EAPOL_KEY_RSN_REPLAY_CTR_SIZE 8 +#define ANI_EAPOL_KEY_RSN_NONCE_SIZE 32 +#define ANI_EAPOL_KEY_RSN_IV_SIZE 16 +#define ANI_EAPOL_KEY_RSN_RSC_SIZE 8 +#define ANI_EAPOL_KEY_RSN_ID_SIZE 8 +#define ANI_EAPOL_KEY_RSN_MIC_SIZE 16 +#define ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE 16 + +#define ANI_EAPOL_KEY_DESC_VERS_RC4 1 +#define ANI_EAPOL_KEY_DESC_VERS_AES 2 + +#define ANI_EAPOL_KEY_RC4_REPLAY_CTR_SIZE 8 +#define ANI_EAPOL_KEY_RC4_IV_SIZE 16 +#define ANI_EAPOL_KET_RC4_SIGN_SIZE 16 + +#define ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID 0xDD +#define ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID 1 +#define ANI_SSM_GROUP_KEY_KDE_TX_BIT 0x04 + +typedef struct sAniEapolLegacyRc4KeyDesc { + v_U16_t keyLen; + v_U8_t replayCounter[ANI_EAPOL_KEY_RC4_REPLAY_CTR_SIZE]; + v_U8_t keyIv[ANI_EAPOL_KEY_RC4_IV_SIZE]; + tANI_BOOLEAN unicastFlag; // The high order 1 bit of key-index + v_U8_t keyId; // The lower order 7 bits of key-index (but 0..3 based) + v_U8_t signature[ANI_EAPOL_KET_RC4_SIGN_SIZE]; + v_U8_t *key; +} tAniEapolLegacyRc4KeyDesc; + +typedef struct sAniRsnKeyInfo { + v_U32_t keyDescVers; + tANI_BOOLEAN unicastFlag; // Pair-wise key + v_U16_t keyId; + tANI_BOOLEAN installFlag; + tANI_BOOLEAN ackFlag; + tANI_BOOLEAN micFlag; + tANI_BOOLEAN secureFlag; + tANI_BOOLEAN errorFlag; + tANI_BOOLEAN requestFlag; + tANI_BOOLEAN encKeyDataFlag; // RSN only (Is 0 in WPA) +} tAniRsnKeyInfo; + +typedef struct sAniEapolRsnKeyDesc { + tAniRsnKeyInfo info; + v_U16_t keyLen; + v_U8_t replayCounter[ANI_EAPOL_KEY_RSN_REPLAY_CTR_SIZE]; + v_U8_t keyNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE]; + v_U8_t keyRecvSeqCounter[ANI_EAPOL_KEY_RSN_RSC_SIZE]; + v_U8_t keyId[ANI_EAPOL_KEY_RSN_ID_SIZE]; + v_U8_t keyMic[ANI_EAPOL_KEY_RSN_MIC_SIZE]; + v_U16_t keyDataLen; + v_U8_t *keyData; +} tAniEapolRsnKeyDesc; + +/** + * aniEapolWriteStart + * + * FUNCTION: + * Writes an EAPOL-Start frame to the packet. It is only used by the + * supplicant. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. There is no + * EAPOL payload for this kind of frame. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the header. + * + * @param packet the packet to which the frame should be written + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteStart(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac); + +/** + * aniEapolWriteEapPacket + * + * FUNCTION: + * Writes the EAPOL/EAP-Packet frame headers. It is used + * by both the authenticator and the supplicant. This creates an EAPOL + * frame that is carrying an EAP message as its payload. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. + * + * ASSUMPTIONS: + * The EAP message (ie., the payload) is already available in the + * packet and that the packet has enough space available for + * prepending the EAPOL header. + * + * @param packet the packet containing the EAP message + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteEapPacket(tAniPacket *eapPacket, + tAniMacAddr dstMac, + tAniMacAddr srcMac); + +/** + * aniEapolParse + * + * FUNCTION: + * Parses an EAPoL frame to the first level of headers (no EAP + * headers are parsed). + * + * NOTE: This is a non-destructive read, that is the + * headers are not stripped off the packet. However, any additional + * data at the end of the packet, beyond what the EAPoL headers encode + * will be stripped off. + * + * @param packet the packet containing the EAPoL frame to parse + * @param dstMac a pointer to set to the location of the destination + * MAC address + * @param srcMac a pointer to set to the location of the source + * MAC address + * @param type a pointer to set to the location of the EAPOL type + * field. + * + * @return the non-negative length of the EAPOL payload if the operation + * succeeds + */ +int +aniEapolParse(tAniPacket *packet, + v_U8_t **dstMac, + v_U8_t **srcMac, + v_U8_t **type); + +/** + * aniEapolWriteKey + * + * Writes out a complete EAPOL-Key frame. The key descriptor is + * appended to the packet and the EAPOL header is prepended to it. If + * a micKey is passed in, then a MIC is calculated and inserted into + * the frame. + * + * @param packet the packet to write to + * @param dstMac the destination MAC address + * @param srcMac the source MAC address + * @param descType the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData the key descriptor data corresponding to the + * above descType. The signature field is ignored and will be + * generated in the packet. The key bytes are expected to be enctypted + * is they need to be encrypted. + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds + * + */ +int +aniEapolWriteKey(v_U32_t cryptHandle, + tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen); + +/** + * aniEapolParseKey + * + * Parses and verifies a complete EAPOL-Key frame. The key descriptor + * type is returned and so is a newly allocated key descriptor structure + * that is appropriate for the type. + * + * NOTE: This is a non-destructive read. That is, the packet headers + * will be unchanged at the end of this read operation. This is so + * that a followup MIC check may be done on the complete packet. If + * the packet parsing fails, the packet headers are not guaranteed to + * be unchanged. + * + * @param packet the packet to read from. Note that the frame is not + * expected to contain any additional padding at the end other than + * the exact number of key bytes. (The aniEapolParse function will + * ensure this.) + * @param descType is set to the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData is set to a newly allocated key descriptor + * corresponding to the above descType. The signature field is + * verified. The key bytes will be returned encrypted. It is the + * responsibility of the caller to free this structure and the data + * contained therein. + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolParseKey(tAniPacket *packet, + int *descType, + void **keyDescData); + +/** + * aniEapolKeyCheckMic + * + * @param eapolFrame the complete EAPOL-Key packet + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds; ANI_E_MIC_FAILED if the + * MIC check fails. + */ +int +aniEapolKeyCheckMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen); + +/** + * aniEapolKeyFreeDesc + * + * Frees the EAPOL key descriptor and the key bytes contained within it. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyFreeDesc(int descType, void *keyDescData); + +v_U8_t * +aniEapolType2Str(v_U8_t type); + +v_U8_t * +aniEapolHdr2Str(v_U8_t *hdr); + +/** + * aniEapolKeyLogDesc + * + * Logs information about the given EAPOL key desctiptor. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyLogDesc(int descType, void *keyDescData); + +void bapRsnEapolHandler( v_PVOID_t pvFsm, tAniPacket *packet, v_BOOL_t fIsAuth ); +//Transfer from pVosPacket to tAniPacket. +int bapRsnFormPktFromVosPkt( tAniPacket **ppPacket, vos_pkt_t *pVosPacket ); + +#endif //_ANI_SSM_EAPOL_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.c new file mode 100644 index 0000000000000..c59de68626362 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmReplayCtr.c#2 $ + * + */ +/* + * Contains definitions of various utilities for EAPoL frame + * parsing and creation. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "vos_trace.h" +#include + +#include +#include "vos_status.h" +#include "vos_memory.h" +#include "vos_utils.h" +#include "vos_packet.h" + +//#include "aniSsmUtils.h" + +/* + * Opaque replay counter type. Does TX and RX side replay counter + * tracking. On the TX side, it returns monotonically increasing values + * of the counter and checks that the peer returned a value matching + * the one we sent. On the RX side, it makes sure that the peer sent a + * replay counter greater than the last one seen (excepting for the + * first time a check is made which the application has to special case.) + */ +struct sAniSsmReplayCtr { + v_U8_t size; + v_U8_t *buf; + v_U32_t currentValue; + v_U8_t init; +}; + +static int +updateCtrBuf(tAniSsmReplayCtr *ctr); + +/** + * aniSsmReplayCtrCreate + * + * Creates a replay counter and initializes it for first time + * use. The initialization can be done randomly or with a passed in + * value like 0. In case this is going to be used on the RX side, it + * doesn't matter what the initialization is and can be optimized to + * a fixed value so as to avoid the overhead of obtaining a random + * value. + * + * @param ctrPtr a pointer that will be set to the newly allocated + * counter if the operation succeeds + * @param size the number of bytes that are desired in the counter + * @param initValue if this is negative and size is greater than 4, + * the initialization is done randomly. Otherwise, these bytes are + * copied into the least significant four or less octets of the + * counter, depending on the size of the counter. i.e., if the counter + * is only 2B, then the least significant 2B of initValue will be + * copied over. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrCreate(v_U32_t cryptHandle, tAniSsmReplayCtr **ctrPtr, + v_U8_t size, + int initValue) +{ + tAniSsmReplayCtr *ctr; + + ctr = vos_mem_malloc( sizeof(tAniSsmReplayCtr) ); + if( NULL == ctr ) + { + return ANI_E_MALLOC_FAILED; + } + + ctr->buf = vos_mem_malloc( size ); + if (ctr->buf == NULL) + { + VOS_ASSERT( 0 ); + vos_mem_free(ctr); + return ANI_E_MALLOC_FAILED; + } + + ctr->size = size; + + // We cannot randomly generate the most significant bytes if the + // total number of bytes is not greater than 4 (sizeof ANI_U32). + if (initValue < 0 && ctr->size <= 4) + initValue = 0; + + // If initValue is negative, initialize the ctr randomly, else + // initialize it to what the user specified. + if (initValue < 0) + { + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(cryptHandle, ctr->buf, ctr->size) ) ) + { + return ANI_ERROR; + } + } + else { + ctr->currentValue = initValue - 1; + } + + *ctrPtr = ctr; + + return ANI_OK; +} + +static int +updateCtrBuf(tAniSsmReplayCtr *ctr) +{ + + v_U32_t numBytes; + v_U32_t offset; + v_U32_t tmp; + + tmp = vos_cpu_to_be32( ctr->currentValue ); + + numBytes = (4 <= ctr->size) ? 4 : ctr->size; + offset = 4 - numBytes; + vos_mem_copy(ctr->buf + ctr->size - numBytes, + ((v_U8_t *) &tmp) + offset, numBytes); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrCmp + * + * Used to check if the passed in value is greater + * than, less than, or the same as the previous value. + * + * Can be used on the TX side to determine if the response to a + * request contains the same counter as the one in the request. + * + * Can be used on the RX side to determine if the request has a + * counter greater than the previous request, or if this is a + * retransmission of the previous request. The application should + * special-case the first time this is called on the RX side. + * + * @param ctr the current replay counter + * @param value the value to check against + * + * @return a negative value if current ctr is less than the + * given value, zero if they are the same, and a positive value if the + * current counter is greater than that of the given value. + */ +int +aniSsmReplayCtrCmp(tAniSsmReplayCtr *ctr, v_U8_t *value) +{ + return vos_mem_compare2(ctr->buf, value, ctr->size); +} + +/** + * aniSsmReplayCtrUpdate + * + * Used on the RX side to update the value of the current replay + * counter to that received in the next request. Typically this is + * called after it is determined that this is not a retransmission, + * and some sort of integrity checking is done on it. + * + * @param ctr the current replay counter + * @param value the value that it should be set to + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrUpdate(tAniSsmReplayCtr *ctr, + v_U8_t *value) +{ + vos_mem_copy(ctr->buf, value, ctr->size); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrNext + * + * Used on the RX side to obtain the next value that should be sent + * with a request. After this call, the current value is incremented + * by one. + * + * @param ctr the current replay counter + * @param value where the next counter value should be copied + * into. The caller must allocated enough storage for this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrNext(tAniSsmReplayCtr *ctr, + v_U8_t *value) +{ + ctr->currentValue++; + updateCtrBuf(ctr); + vos_mem_copy(value, ctr->buf, ctr->size); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrFree + * + * Frees the replay counter context. + * + * @param ctr the replay counter to free. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrFree(tAniSsmReplayCtr *ctr) +{ + + if (ctr->buf != NULL) + vos_mem_free(ctr->buf); + + vos_mem_free(ctr); + + return ANI_OK; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.h new file mode 100644 index 0000000000000..59c8429296171 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmReplayCtr.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmReplayCtr.h $ + * + */ +/* + * Contains declarations of various utilities for SSM replay counter + * module. + * + * Author: Mayank D. Upadhyay + * Date: 15-June-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_SSM_REPLAY_CTR_H_ +#define _ANI_SSM_REPLAY_CTR_H_ + +#include "vos_types.h" +#include + +/* + * Opaque replay counter type. Does TX and RX side replay counter + * tracking. On the TX side, it returns monotonicall increasing values + * of the counter and checks that the peer returned a value matching + * the one we sent. On the RX side, it makes sure that the peer sent a + * replay counter greater than the last one seen (excepting for the + * first time a check is made which the application has to special case.) + */ +typedef struct sAniSsmReplayCtr tAniSsmReplayCtr; + +/** + * aniSsmReplayCtrCreate + * + * Creates a replay counter and initializes it for first time + * use. The initialization can be done randomly or with a passed in + * value like 0. In case this is going to be used on the RX side, it + * doesn't matter what the initiaalization is and can be optimized to + * a fixed value so as to avoid the overhead of obtaining a random + * value. + * + * @param ctrPtr a pointer that will be set to the newly allocated + * counter if the operation succeeds + * @param size the number of bytes that are desired in the counter + * @param initValue if this is negative and size is greater than 4, + * the initialization is done randomly. Otherwise, these bytes are + * copied into the least significant four or less octets of the + * counter, depending on the size of the counter. i.e., if the counter + * is only 2B, then the least significant 2B of initValue will be + * copied over. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrCreate(v_U32_t cryptHandle, tAniSsmReplayCtr **ctrPtr, + v_U8_t size, + int initValue); + +/** + * aniSsmReplayCtrCmp + * + * Used to check if the passed in value is greater + * than, less than, or the same as the previous value. + * + * Can be used on the TX side to determine if the response to a + * request contains the same counter as the one in the request. + * + * Can be used on the RX side to determine if the request has a + * counter greater than the previous request, or if this is a + * retransmission of the previous request. The application should + * special-case the first time this is called on the RX side. + * + * @param ctr the current replay counter + * @param value the value to check against + * + * @return A negative error code if value is less than the + * current value of the counter, zero if they are the same, and a + * positive value if the current value is greater than that of the + * counter. + */ +int +aniSsmReplayCtrCmp(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrUpdate + * + * Used on the RX side to update the value of the current replay + * counter to that received in the next request. Typically this is + * called after it is determined that this is not a retransmission, + * and some sort of integrity checking is done on it. + * + * @param ctr the current replay counter + * @param value the value that it should be set to + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrUpdate(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrNext + * + * Used on the RX side to obtain the next value that should be sent + * with a request. After this call, the current value is incremented + * by one. + * + * @param ctr the current replay counter + * @param value where the next counter value should be copied + * into. The caller must allocated enough storage for this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrNext(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrFree + * + * Frees the replay counter context. + * + * @param ctr the replay counter to free. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrFree(tAniSsmReplayCtr *ctr); + +#endif //_ANI_SSM_REPLAY_CTR_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmServices.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmServices.h new file mode 100644 index 0000000000000..41ad739264612 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnSsmServices.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmServices.h $ + * + * Contains definitions of common types that the SSM exports to other + * modules. + * + * Author: Mayank D. Upadhyay + * Date: 23-January-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_SSM_SERVICES_H_ +#define _ANI_SSM_SERVICES_H_ + +#include "vos_types.h" +#include "sirApi.h" + +#define ANI_SSM_MAX_KEYS_INFO_SIZE 512 +#define ANI_SSM_MAX_GROUP_SIZE 32 +#define ANI_SSM_MAX_USERID_SIZE 64 + +#define ANI_SSM_RSN_PMK_LEN 32 +#define ANI_SSM_RSN_PSK_LEN ANI_SSM_RSN_PMK_LEN +#define ANI_SSM_RSN_PSK_LEN_HEX (ANI_SSM_RSN_PSK_LEN + ANI_SSM_RSN_PSK_LEN) +#define ANI_SSM_MAX_PASSPHRASE_LEN 128 +#define ANI_SSM_MAX_AUTHZONE_LEN 32 +#define ANI_SSM_MAX_LANDPG_URL_LEN 128 +#define ANI_SSM_MAX_GUEST_PORTAL_PWD_LEN 32 + +#define ANI_SSM_IE_RSN_OUI {0x00, 0x0F, 0xAC} +#define ANI_SSM_IE_WPA_OUI {0x00, 0x50, 0xF2} + +#define ANI_SSM_IE_RSN_ELEM_ID 48 +#define ANI_SSM_IE_WPA_ELEM_ID 221 + +/* + * The total length of an RSN IE may be no longer than these many + * octets, including the two bytes for type and len. + */ +#define ANI_RSN_IE_MAX_LEN 257 + +/* + * PMKSA ID data type + * (PMKID is an HMAC-SHA1-128 value) + */ +#define ANI_AAG_PMKID_SIZE 16 + +#define ANI_SSM_AUTH_BITMASK 0x00010000 +#define ANI_SSM_IEMODE_BITMASK 0xC0000000 +#define ANI_SSM_ENCR_BITMASK 0x00000001 +#define ANI_SSM_IEMODE_SHIFT (30) + + +// Upper level authentication types used by AA +typedef enum eAniSsmAuthType { + eANI_SSM_AT_UNDERFLOW = -1, + + // The numbers are fixed so that they can be re-used in the XCLI + // config file and 1x.conf. + eANI_SSM_AT_NONE = 0, + eANI_SSM_AT_SHARED_KEY = 1, + eANI_SSM_AT_LEGACY_EAP = 2, + eANI_SSM_AT_RSN_PSK = 3, + eANI_SSM_AT_RSN_EAP = 4, + + eANI_SSM_AT_OVERFLOW +} tAniSsmAuthType; + +// Upper level encryption types used by AA +typedef enum eAniSsmCipherType { + eANI_SSM_CT_UNDERFLOW = -1, + + // The numbers are fixed so that they can be re-used in the XCLI + // config file and 1x.conf. + eANI_SSM_CT_NONE = 0, + eANI_SSM_CT_WEP40 = 1, + eANI_SSM_CT_WEP104 = 2, + eANI_SSM_CT_WPA_WEP40 = 3, + eANI_SSM_CT_WPA_WEP104 = 4, + eANI_SSM_CT_TKIP = 5, + eANI_SSM_CT_CCMP = 6, + + eANI_SSM_CT_OVERFLOW +} tAniSsmCipherType; + + +// WPA modes +typedef enum eAniSsmWpaModes { + eANI_SSM_WPA_UNDERFLOW = -1, + + eANI_SSM_WPA_DISABLE = 0, + eANI_SSM_WPA_1 = 1, + eANI_SSM_WPA_2 = 2, + + eANI_SSM_WPA_OVERFLOW = ((eANI_SSM_WPA_2 | eANI_SSM_WPA_1) + 1) +} tAniSsmWpaModes; + +typedef struct sAniSsmGroup { + v_U16_t len; // Valid range: 0..ANI_SSM_MAX_GROUP_SIZE + v_U8_t group[1]; +} tAniSsmGroup; + +typedef struct sAniSsmUserId { + v_U16_t len; // Valid range: 0..ANI_SSM_MAX_USERID_SIZE + v_U8_t userId[1]; +} tAniSsmUserId; + +/* + * PMKSA ID data type + * (PMKID is an HMAC-SHA1-128 value) + */ +typedef v_U8_t tAniSsmPmkId[ANI_AAG_PMKID_SIZE]; + +/** + * aniSsmInitStaticConf + * + * (Re-)Initializes the SSM internal static configuration. This may be + * from a static configuration file and will include items such as + * local MAC-ACL lists. + * + * @param configFileName - an optional filename to read from. If this is + * NULL, the default AAG static conf file is read. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmInitStaticConf(char *configFileName); + +/** + * aniSsmIsStaMacAllowed + * + * Determines if a given STA passes the local MAC-ACL check. If + * MAC-ACL lookup is enabled, it may be either positive (whitelist) or + * negative (blacklist). If positive MAC-ACLs are on, then only those + * STAs that are in the whitelist are allowed in. If negative MAC-ACLs + * are on, then those STAs that are in the blacklist are not allowed in. + * + * Note that local MAC-ACLs may be maintained per SSID. + * + * @param staMac - the MAC address of the STA + * @param ssid - the SSID that the STA is associating on + * + * @return ANI_OK if the operation succeeds + */ +v_BOOL_t +aniSsmIsStaMacAllowed(const tAniMacAddr staMac, const tAniSSID *ssid); + +/** + * aniSsmIsSecModeAllowed + * + * Determines if the security suites requested by an RSN station or + * non-RSN station are allowed under the security mode in force at the + * moment. + * + * An RSN IE needs to be passed in if RSN is being used. Otherwise the + * ieLen field should be set to 0 or ieData set to NULL to indicate + * that no IE is present. If the RSN IE is present it is used to check + * both the authentication type and the cipher type for the group and + * pairwise keys. Special rules might apply in the case of a + * BP. Therefore, a separate flag indicates if the STA is a BP. + * + * If the station is not using RSN, the authentication type is + * tightly bound to the cipher type. For instance, when using + * shared-key MAC authentication, the cipher type will be assumed to + * be WEP. (Both WEP-40 and WEP-104 fall under the same security + * level.) When using open-system MAC authentication, the cipher type + * will be assumed to be WEP if the security level requires WEP, + * otherwise the cipher will be determined later. (When performing + * open-auth in the lowest security level, the STA is required to + * initiate EAPOL in order to establish WEP keys, or WEP cannot be not + * used.) + * + * @param secMode the security mode that is in force + * @param macAuthType the MAC-level authentication type to check + * @param ieLen is set 0 if no RSN IE is present, or to the number of + * octets in the RSN IE. + * @param ieData the optional IE data bytes, or NULL if no IE is + * present. + * @param bpIndicator eANI_BOOLEAN_TRUE if the STA is a BP, + * eANI_BOOLEAN_FALSE otherwise. + * + * @return eANI_BOOLEAN_TRUE if the authentication type is allowed, + * eANI_BOOLEAN_FALSE if not. + * + * @see aniSsmIsRsnSuiteAllowed + */ +v_BOOL_t +aniSsmIsSecModeAllowed(v_U32_t secMode, + tAniAuthType macAuthType, + v_U8_t ieLen, + v_U8_t *ieData, + v_BOOL_t bpIndicator, + v_BOOL_t wpsEnabled); + +/** + * aniSsmGenRsnSuiteList + * + * Generates a RSN information element containing a list of RSN suites + * that conform to the specified security level. This is generally + * used on the AP to generate the RSN information element it + * advertizes. + * + * @param secMode the security mode in force + * @param ieData the buffer in which to store the generated IE + * + * @return the non-negative number of bytes written into the buffer if + * the operation succeeds, or a negative error code. + */ +int +aniSsmGenRsnSuiteList(v_U32_t secMode, + v_U8_t ieData[ANI_RSN_IE_MAX_LEN]); + +/** + * aniSsmGenRsnSuiteForBp + * + * Generates a RSN information element containing exactly one RSN + * suite selector for authentication and exactly one for the + * cipher. This is generally used on the BP side while associating + * with an upstream AP. + * + * If RSN is turned off on the BP, then the IE is of length 0. + * + * NOTE: As per 802.11/D3.0, the BP has to send back the exact group + * key cipher that the AP indicated in its IE. + * + * @param apIeData contains the IE sent by the AP and is used to read + * the group key cipher that the AP wants us to use. + * @param apIeLen the length of the AP's IE + * @param bpRsnFlag should be 0 for no RSN, 1 for AES, 2 for TKIP + * @param bpPskFlag should be eANI_BOOLEAN_TRUE if RSN with PSK is + * desired. This is only relevant if bpRsnFlag is not zero. + * @param ieData the buffer in which to store the generated IE + * + * @return the non-negative number of bytes written into the buffer if + * the operation succeeds, or a negative error code. + */ +int +aniSsmGenRsnSuiteForBp(const v_U8_t *apIeData, + v_U8_t apIeLen, + v_U32_t bpRsnFlag, + v_BOOL_t bpPskFlag, + v_U8_t ieData[ANI_RSN_IE_MAX_LEN]); + +/** + * aniSsmSecMode2Str + * + * Returns a descriptive string that can be used for logging the + * security mode. + * + * @param secMode the secMode to be printed + * + * @return a printable ASCII string representing the secMode + */ +v_U8_t * +aniSsmSecMode2Str(v_U32_t secMode); + +/** + * aniSsmIe2Str + * + * Parses and returns a printable form of the IE (WPA/RSN). + * + * @param ieData the IE bytes + * @param ieLen the length of the IE + * + * @return ANI_OK if the operation succeeds + */ +v_U8_t * +aniSsmIe2Str(const v_U8_t *ieData, v_U8_t ieLen); + +#endif /* _ANI_SSM_SERVICES_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.c new file mode 100644 index 0000000000000..654e8eefbeed2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + + bapRsnTxRx.c + + \brief + + Description... + + ============================================================================== */ +/* $HEADER$ */ +#include "bapRsnTxRx.h" +#include "bapRsn8021xFsm.h" +#include "bapInternal.h" +#include "vos_trace.h" +#include "wlan_qct_tl.h" +#include "vos_memory.h" + + +static pnfTxCompleteHandler bapRsnFsmTxCmpHandler; +static pnfRxFrameHandler bapRsnFsmRxFrameHandler; + +extern int gReadToSetKey; + + +VOS_STATUS bapRsnRegisterTxRxCallbacks( pnfTxCompleteHandler pfnTxCom, pnfRxFrameHandler pnfRxFrame ) +{ + if( bapRsnFsmTxCmpHandler || bapRsnFsmRxFrameHandler ) + { + return VOS_STATUS_E_ALREADY; + } + + bapRsnFsmTxCmpHandler = pfnTxCom; + bapRsnFsmRxFrameHandler = pnfRxFrame; + + return ( VOS_STATUS_SUCCESS ); +} + +void bapRsnClearTxRxCallbacks(void) +{ + bapRsnFsmTxCmpHandler = NULL; + bapRsnFsmRxFrameHandler = NULL; +} + + +//To reserve a vos_packet for Tx eapol frame +//If success, pPacket is the packet and pData points to the head. +static VOS_STATUS bapRsnAcquirePacket( vos_pkt_t **ppPacket, v_U8_t **ppData, v_U16_t size ) +{ + VOS_STATUS status; + vos_pkt_t *pPacket = NULL; + + status = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT, size, 1, + VOS_TRUE, NULL, NULL ); + if( VOS_IS_STATUS_SUCCESS( status ) ) + { + status = vos_pkt_reserve_head( pPacket, (v_VOID_t **)ppData, size ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnAcquirePacket failed to reserve size = %d\n", size ); + vos_pkt_return_packet( pPacket ); + } + else + { + *ppPacket = pPacket; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnAcquirePacket failed to get vos_pkt\n" ); + } + + return ( status ); +} + + +static VOS_STATUS bapRsnTxCompleteCallback( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + int retVal; + ptBtampContext btampContext; // use btampContext value + tCsrRoamSetKey setKeyInfo; + tSuppRsnFsm *fsm; + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pvosGCtx is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + btampContext = VOS_GET_BAP_CB(pvosGCtx); + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + fsm = &btampContext->uFsm.suppFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //If we get a disconect from upper layer before getting the pkt from TL the + //bapRsnFsmTxCmpHandler could be NULL + //VOS_ASSERT( bapRsnFsmTxCmpHandler ); + + if( bapRsnFsmTxCmpHandler ) + { + //Change the state + //Call auth or supp FSM's handler + bapRsnFsmTxCmpHandler( pvosGCtx, pPacket, retStatus ); + } + else + { + vos_pkt_return_packet( pPacket ); + return (VOS_STATUS_SUCCESS ); + } + + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + /* + We will move the Set key to EAPOL Completion handler. We found a race condition betweem + sending EAPOL frame and setting Key */ + if (BAP_SET_RSN_KEY == gReadToSetKey) { + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + + if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" ); + retVal = ANI_ERROR; + } + gReadToSetKey = BAP_RESET_RSN_KEY; + } + + return (VOS_STATUS_SUCCESS ); +} + + +static VOS_STATUS bapRsnTxFrame( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + VOS_STATUS status; + WLANTL_MetaInfoType metaInfo; + + vos_mem_zero( &metaInfo, sizeof( WLANTL_MetaInfoType ) ); + metaInfo.ucIsEapol = 1; //only send eapol frame + status = WLANTL_TxBAPFrm( pvosGCtx, pPacket, &metaInfo, bapRsnTxCompleteCallback ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnTxFrame failed to send vos_pkt status = %d\n", status ); + } + + return ( status ); +} + + +/* + \brief bapRsnSendEapolFrame + To push an eapol frame to TL. + + \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format +*/ +VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt ) +{ + VOS_STATUS status; + vos_pkt_t *pPacket = NULL; + v_U8_t *pData = NULL, *pSrc = NULL; + int pktLen = aniAsfPacketGetBytes( pAniPkt, &pSrc ); + + if( pktLen <= 0 ) + { + return VOS_STATUS_E_EMPTY; + } + status = bapRsnAcquirePacket( &pPacket, &pData, pktLen ); + if( VOS_IS_STATUS_SUCCESS( status ) && ( NULL != pPacket )) + { + vos_mem_copy( pData, pSrc, pktLen ); + //Send the packet, need to check whether we have an outstanding packet first. + status = bapRsnTxFrame( pvosGCtx, pPacket ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + vos_pkt_return_packet( pPacket ); + } + } + + return ( status ); +} + + +//TL call this function on Rx frames, should only be EAPOL frames +VOS_STATUS bapRsnRxCallback( v_PVOID_t pv, vos_pkt_t *pPacket ) +{ + //Callback to auth or supp FSM's handler + VOS_ASSERT( bapRsnFsmRxFrameHandler ); + if( bapRsnFsmRxFrameHandler ) + { + bapRsnFsmRxFrameHandler( pv, pPacket ); + } + else + { + //done + vos_pkt_return_packet( pPacket ); + } + + return ( VOS_STATUS_SUCCESS ); +} + + + +VOS_STATUS bapRsnRegisterRxCallback( v_PVOID_t pvosGCtx ) +{ + VOS_STATUS status; + + status = WLANTL_RegisterBAPClient( pvosGCtx, WLANBAP_RxCallback, WLANBAP_TLFlushCompCallback ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + if( VOS_STATUS_E_EXISTS != status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnRegisterRxCallback failed with status = %d\n", status ); + } + else + { + //We consider it ok to register it multiple times because only BAP's RSN should call this + status = VOS_STATUS_SUCCESS; + } + } + + return ( status ); +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.h new file mode 100644 index 0000000000000..61ce6f0bff71d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/bapRsnTxRx.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __BAPRSN_TXRX_H ) +#define __BAPRSN_TXRX_H + +/**============================================================================= + + bapRsnTxRx.h + + \brief + + Description... + + ==============================================================================*/ + +#include "vos_types.h" +#include "vos_status.h" +#include "vos_packet.h" +#include "bapRsnAsfPacket.h" + + +typedef int (*pnfTxCompleteHandler)( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); +typedef int (*pnfRxFrameHandler)( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); + +/* + \brief bapRsnSendEapolFrame + To push an eapol frame to TL. + + \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format +*/ +VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt ); + + +/* + \brief bapRsnRegisterTxRxCallbacks + To register two callbacks for txcomplete and rxFrames . + + \param pfnTxCom - pointer to a function to handle the tx completion. + \param pnfRxFrame - point to a function to handle rx frames +*/ +VOS_STATUS bapRsnRegisterTxRxCallbacks( pnfTxCompleteHandler pfnTxCom, pnfRxFrameHandler pnfRxFrame ); + +//To set the callbaks to NULL so it can be change later +void bapRsnClearTxRxCallbacks(void); + +/* + \brief bapRsnRegisterRxCallback + To register the RX frame callbacks to TL to receive EAPOL frames . + + \param pvosGCtx - pointer to global VOSS context. +*/ +VOS_STATUS bapRsnRegisterRxCallback( v_PVOID_t pvosGCtx ); + +VOS_STATUS bapRsnRxCallback(v_PVOID_t pv, vos_pkt_t *pPacket); + +#endif //__BAPRSN_TXRX_H diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.c new file mode 100644 index 0000000000000..449a1117fd4a7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.c @@ -0,0 +1,2703 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b t a m p F s m . C + + OVERVIEW: + + This software unit holds the implementation of the Finite State Machine that + controls the operation of each individual AMP Physical link. + (Currently, this is limited to ONE link.) + + The btampFsm() routine provided by this module is called by the rest of + the BT-AMP PAL module whenever a control plane operation occurs that requires a + major state transition. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/gb-bluez/vendor/qcom/proprietary/wlan/libra/CORE/BAP/src/btampFsm.c,v 1.11 2011/03/30 21:52:10 jzmuda Exp jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-16 jez Created module + +===========================================================================*/ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 / version 1.2 Beta 1 */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + + +#include "fsmDefs.h" +//#include "btampFsm.h" +#include "bapInternal.h" +#include "btampFsm_ext.h" + +// Pick up the BTAMP Timer API definitions +#include "bapApiTimer.h" + +// Pick up the BTAMP RSN definitions +#include "bapRsn8021xFsm.h" + +#include "bapRsn8021xAuthFsm.h" +// Pick up the SME API definitions +#include "sme_Api.h" + +// Pick up the PMC API definitions +#include "pmcApi.h" + +// Pick up the BTAMP API defintions for interfacing to External subsystems +#include "bapApiExt.h" + +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" + +// Pick up the DOT11 Frames compiler +// I just need these one "opaque" type definition in order to use the "frames" code +typedef struct sAniSirGlobal *tpAniSirGlobal; +#include "dot11f.h" + +#if 0 +/* + * Event-related Defines. + * - Ultimately, these events will be values + * - from an enumeration. That are set by some + * - of the following events. + */ +#define eWLAN_BAP_MAC_START_BSS_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ +#define eWLAN_BAP_MAC_START_FAILS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ +#define eWLAN_BAP_MAC_SCAN_COMPLETE /* bapScanCompleteCallback */ +#define eWLAN_BAP_CHANNEL_NOT_SELECTED /* No existing Infra assoc - e.g., use HAL to access the STA LIST and find nothing */ +#define eWLAN_BAP_MAC_CONNECT_COMPLETED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ +#define eWLAN_BAP_MAC_CONNECT_FAILED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ +#define eWLAN_BAP_MAC_CONNECT_INDICATION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ +#define eWLAN_BAP_RSN_SUCCESS /* setKey IOCTL from the Auth/Supp App */ +#define eWLAN_BAP_RSN_FAILURE /* deAuth IOCTL from the Auth/Supp App */ +#define eWLAN_BAP_MAC_KEY_SET_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ +#define eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOC_IND */ +#define eWLAN_BAP_MAC_READY_FOR_CONNECTIONS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ +#define eWLAN_BAP_CHANNEL_SELECTION_FAILED /* ??? */ + +#endif /* 0 */ + +/*Min and max channel values in 2.4GHz band for operational channel validation + on connect*/ +#define WLAN_BAP_MIN_24G_CH 1 +#define WLAN_BAP_MAX_24G_CH 14 + + +/* The HCI Disconnect Logical Link Complete Event signalling routine*/ +VOS_STATUS +signalHCIDiscLogLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U16_t log_link_handle, /* The Logical Link that disconnected*/ + v_U8_t reason /* the BT-AMP reason code */ +); + + +/* Stubs - TODO : Remove once the functions are available */ +int +bapSuppDisconnect(tBtampContext *ctx) +{ + // Disconnect function is called internally + // TODO : Need to find, if it disconnect will be issued from bap for supplicant + return ANI_OK; +} + +int +bapAuthDisconnect(tBtampContext *ctx) +{ + // Disconnect function is called internally + // TODO : Need to find, if it disconnect will be issued from bap for supplicant + return ANI_OK; +} + +VOS_STATUS +bapSetKey( v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo ) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext btampContext; /* use btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + eHalStatus halStatus; + v_U32_t roamId = 0xFF; + tHalHandle hHal = NULL; + v_U8_t groupMac[ANI_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + /* Validate params */ + if ((pvosGCtx == NULL) || (pSetKeyInfo == NULL)) + { + return VOS_STATUS_E_FAULT; + } + + btampContext = VOS_GET_BAP_CB(pvosGCtx); + /* Validate params */ + if ( btampContext == NULL) + { + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_RSN_SUCCESS; + bapEvent.params = NULL; + + /* Signal the successful RSN auth and key exchange event */ + /* (You have to signal BEFORE calling sme_RoamSetKey) */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Set the Pairwise Key */ + halStatus = sme_RoamSetKey( + hHal, + btampContext->sessionId, + pSetKeyInfo, + &roamId ); + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus ); + return VOS_STATUS_E_FAULT; + } + + /* Set the Group Key */ + vos_mem_copy( pSetKeyInfo->peerMac, groupMac, sizeof( tAniMacAddr ) ); + halStatus = sme_RoamSetKey( + hHal, + btampContext->sessionId, + pSetKeyInfo, + &roamId ); + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus ); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +} + +/* + * Debug-related Defines. + * - Ultimately, these events will be values + * - from an enumeration. That are set by some + * - of the following events. + */ +#define DUMPLOG_ON +#if defined DUMPLOG_ON +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +/* + * State transition procedures + */ + +VOS_STATUS +gotoS1 +( + ptBtampContext btampContext, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + tWLAN_BAPRole BAPDeviceRole, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate + = (tBtampTLVHCI_Create_Physical_Link_Cmd *) bapEvent->params; + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept + = (tBtampTLVHCI_Accept_Physical_Link_Cmd *) bapEvent->params; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t conAcceptTOInterval; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Remember role */ + btampContext->BAPDeviceRole = BAPDeviceRole; + + switch(BAPDeviceRole) + { + case BT_INITIATOR: + /* Copy down the phy_link_handle value */ + btampContext->phy_link_handle = pBapHCIPhysLinkCreate->phy_link_handle; + /* Copy out the key material from the HCI command */ + btampContext->key_type = pBapHCIPhysLinkCreate->key_type; + btampContext->key_length = pBapHCIPhysLinkCreate->key_length; + vos_mem_copy( + btampContext->key_material, + pBapHCIPhysLinkCreate->key_material, + 32); /* Need a key size define */ + break; + case BT_RESPONDER: + /* Copy down the phy_link_handle value */ + btampContext->phy_link_handle = pBapHCIPhysLinkAccept->phy_link_handle; + /* Copy out the key material from the HCI command */ + btampContext->key_type = pBapHCIPhysLinkAccept->key_type; + btampContext->key_length = pBapHCIPhysLinkAccept->key_length; + vos_mem_copy( + btampContext->key_material, + pBapHCIPhysLinkAccept->key_material, + 32); /* Need a key size define */ + break; + default: + *status = WLANBAP_ERROR_HOST_REJ_RESOURCES; /* return the BT-AMP status here */ + return VOS_STATUS_E_RESOURCES; + } + + conAcceptTOInterval = (btampContext->bapConnectionAcceptTimerInterval * 5)/ 8; + /* Start the Connection Accept Timer */ + vosStatus = WLANBAP_StartConnectionAcceptTimer ( + btampContext, + conAcceptTOInterval); + + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return VOS_STATUS_SUCCESS; +} //gotoS1 + +VOS_STATUS +gotoScanning +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + /* Initiate a SCAN request */ + //csrScanRequest(); + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return VOS_STATUS_SUCCESS; +} + + +#if 0 +/*========================================================================== + + FUNCTION: convertRoleToBssType + + DESCRIPTION: Return one of the following values: + + eCSR_BSS_TYPE_INFRASTRUCTURE, + eCSR_BSS_TYPE_IBSS, // an IBSS network we will NOT start + eCSR_BSS_TYPE_START_IBSS, // an IBSS network we will start if no partners detected. + eCSR_BSS_TYPE_WDS_AP, // BT-AMP AP + eCSR_BSS_TYPE_WDS_STA, // BT-AMP station + eCSR_BSS_TYPE_ANY, +============================================================================*/ +#endif +eCsrRoamBssType +convertRoleToBssType +( + tWLAN_BAPRole bapRole /* BT-AMP role */ +) +{ + switch (bapRole) + { + case BT_RESPONDER: + // an WDS network we will join + return eCSR_BSS_TYPE_WDS_STA; + //return eCSR_BSS_TYPE_INFRASTRUCTURE; + //return eCSR_BSS_TYPE_IBSS; // Initial testing with IBSS on both ends makes more sense + case BT_INITIATOR: + // an WDS network we will start if no partners detected. + return eCSR_BSS_TYPE_WDS_AP; + //return eCSR_BSS_TYPE_START_IBSS; // I really should try IBSS on both ends + default: + return eCSR_BSS_TYPE_INFRASTRUCTURE; + } +} // convertRoleToBssType + + +char hexValue[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + +#define BAP_MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX_BYTES 8 +// Each byte will be converted to hex digits followed by a +// punctuation (which is specified in the "delimiter" param.) Thus +// allocate three times the storage. +v_U8_t * +bapBin2Hex(const v_U8_t *bytes, v_U32_t len, char delimiter) +{ + static v_U8_t buf[MAX_BYTES*(2+1)]; + v_U32_t i; + v_U8_t *ptr; + + len = BAP_MIN(len, MAX_BYTES); + for (i = 0, ptr = buf; i < len; i++) + { + *ptr++ = hexValue[ (bytes[i] >> 4) & 0x0f]; + *ptr++ = hexValue[ bytes[i] & 0x0f]; + *ptr++ = delimiter; + //sprintf(ptr, "%.2x%c", bytes[i], delimiter); + //ptr += 3; + } + + // Delete the extra punctuation and null terminate the string + if (len > 0) + ptr--; + *ptr = '\0'; + + return buf; +}// bapBin2Hex + +char bapSsidPrefixValue[] = {'A', 'M', 'P', '-'}; + +v_U8_t * +convertBSSIDToSSID +( + v_U8_t *bssid /* BSSID value */ +) +{ + static v_U8_t ssId[32]; + + vos_mem_copy( + ssId, + bapSsidPrefixValue, + 4); + + vos_mem_copy( + &ssId[4], + bapBin2Hex(bssid, 6, '-'), + 17); + + return ssId; +} // convertBSSIDToSSID + +VOS_STATUS +convertToCsrProfile +( + ptBtampContext btampContext, /* btampContext value */ + eCsrRoamBssType bssType, + tCsrRoamProfile *pProfile /* return the profile info here */ +) +{ + static v_U8_t btampRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 + }; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_S7_t sessionid = -1; + tHalHandle hHal = NULL; + v_U32_t triplet; + v_U8_t regulatoryClass; + v_U8_t firstChannel; + v_U8_t numChannels; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //Zero out entire roamProfile structure to avoid problems in uninitialized pointers as the structure expands */ + //vos_mem_zero(pProfile,sizeof(tCsrRoamProfile)); + + //Set the BSS Type + //pProfile->BSSType = convertRoleToBssType(btampContext->BAPDeviceRole ); + pProfile->BSSType = bssType; + //pProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + + //Set the SSID + + if ( bssType == eCSR_BSS_TYPE_WDS_STA) + { + pProfile->SSIDs.numOfSSIDs = 2; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_STA", convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + + vos_mem_zero(pProfile->SSIDs.SSIDList[1].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[1].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[1].SSID.ssId, + convertBSSIDToSSID(btampContext->self_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[1].SSID.length = 21; + + //Set the BSSID to the Remote AP + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + sizeof( tCsrBssid ) ); + + } + else if ( bssType == eCSR_BSS_TYPE_WDS_AP) + { + pProfile->SSIDs.numOfSSIDs = 1; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_AP", convertBSSIDToSSID(btampContext->self_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->self_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + +#if 0 + //In case you are an AP, don't set the BSSID + pProfile->BSSIDs.numOfBSSIDs = 0; +#endif //0 + + //Set the BSSID to your "self MAC Addr" + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->self_mac_addr, + sizeof( tCsrBssid ) ); + + } + else + // Handle everything else as bssType eCSR_BSS_TYPE_INFRASTRUCTURE + { + pProfile->SSIDs.numOfSSIDs = 1; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_STA", convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + + //Set the BSSID to the Remote AP + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + sizeof( tCsrBssid ) ); + + } + + //Always set the Auth Type + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_RSN_PSK; + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_NONE; + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pProfile->AuthType.numEntries = 1; + //pProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK; + + //Always set the Encryption Type + //pProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_AES; + //pProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pProfile->EncryptionType.numEntries = 1; + //pProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES; + + pProfile->mcEncryptionType.numEntries = 1; + //pProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES; + + //set the RSN IE + //This is weird, but it works + pProfile->pRSNReqIE = &btampRSNIE[0]; + pProfile->nRSNReqIELength = 0x16; //TODO + //pProfile->pRSNReqIE = NULL; + + /** We don't use the WPAIE.But NULL it to avoid being used **/ + pProfile->pWPAReqIE = NULL; + pProfile->nWPAReqIELength = 0; + + // Identify the operation channel + + /* Choose the operation channel from the preferred channel list */ + pProfile->operationChannel = 0; + regulatoryClass = 0; + for (triplet = 0; triplet < btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets; triplet++) + { + firstChannel = 0; + numChannels = 0; + + /* is this a regulatory class triplet? */ + if (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][0] == 201) + { + /* identify supported 2.4GHz regulatory classes */ + switch (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][1]) + { + case 254: + { + /* class 254 is special regulatory class defined by BT HS+3.0 spec that + is valid only for unknown/'mobile' country */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'X') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'X')) + { + regulatoryClass = 254; + firstChannel = 1; + numChannels = 11; + } + break; + } + case 12: + { + /* class 12 in the US regulatory domain is 2.4GHz channels 1-11 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'U') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'S')) + { + regulatoryClass = 12; + firstChannel = 1; + numChannels = 11; + } + break; + } + case 4: + { + /* class 4 in the Europe regulatory domain is 2.4GHz channels 1-13 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'G') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'B')) + { + regulatoryClass = 4; + firstChannel = 1; + numChannels = 13; + } + break; + } + case 30: + { + /* class 30 in the Japan regulatory domain is 2.4GHz channels 1-13 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'J') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'P')) + { + regulatoryClass = 30; + firstChannel = 1; + numChannels = 13; + } + break; + } + default: + { + break; + } + } + /* if the next triplet is not another regulatory class triplet then it must be a sub-band + triplet. Skip processing the default channels for this regulatory class triplet and let + the sub-band triplet restrict the available channels */ + if (((triplet+1) < btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets) && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet+1][0] != 201)) + { + continue; + } + } + else + { + /* if the regulatory class is valid then this is a sub-band triplet */ + if (regulatoryClass) + { + firstChannel = btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][0]; + numChannels = btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][1]; + } + } + + if (firstChannel && numChannels) + { + if (!btampContext->btamp_AMP_Assoc.HC_pref_num_triplets) + { + pProfile->operationChannel = firstChannel; + break; + } + else if (((btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1]) <= firstChannel) || + ((firstChannel + numChannels ) <= btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0])) + { + continue; + } + else if ((btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1]) > firstChannel) + { + pProfile->operationChannel = firstChannel; + break; + } + else if ((firstChannel + numChannels) > btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0]) + { + pProfile->operationChannel = btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0]; + break; + } + } + } + + if (!pProfile->operationChannel) + { + return VOS_STATUS_E_INVAL; + } + + /*Set the selected channel */ + sessionid = sme_GetInfraSessionId(hHal); + /*if there is infra session up already, use that channel only for BT AMP + connection, else we can use the user preferred one*/ + if(-1 != sessionid) + { + pProfile->operationChannel = + sme_GetInfraOperationChannel(hHal, + sessionid); + } + + if(sme_IsChannelValid(hHal, pProfile->operationChannel)) + { + btampContext->channel = pProfile->operationChannel; + } + else + { + //no valid channel, not proceeding with connection + return VOS_STATUS_E_INVAL; + } + + if ( BT_INITIATOR == btampContext->BAPDeviceRole ) + { + pProfile->ChannelInfo.numOfChannels = 1; + pProfile->ChannelInfo.ChannelList = &pProfile->operationChannel; + } + else + { + pProfile->ChannelInfo.numOfChannels = 1; + pProfile->ChannelInfo.ChannelList = &pProfile->operationChannel; + } + + + // Turn off CB mode + pProfile->CBMode = eCSR_CB_OFF; + + //set the phyMode to accept anything + //Taurus means everything because it covers all the things we support + pProfile->phyMode = eCSR_DOT11_MODE_11n; //eCSR_DOT11_MODE_TAURUS; //eCSR_DOT11_MODE_AUTO; /*eCSR_DOT11_MODE_BEST;*/ + + //set the mode in CFG as well + sme_CfgSetInt(hHal, WNI_CFG_DOT11_MODE, WNI_CFG_DOT11_MODE_11N, NULL, eANI_BOOLEAN_FALSE); + + pProfile->bWPSAssociation = eANI_BOOLEAN_FALSE; + + //Make sure we DON'T request UAPSD + pProfile->uapsd_mask = 0; + + //return the vosStatus + return vosStatus; +} //convertToCsrProfile + +VOS_STATUS +gotoStarting +( + ptBtampContext btampContext, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + eCsrRoamBssType bssType, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus halStatus; + v_U32_t parseStatus, type, subType; + /* tHalHandle */ + tHalHandle hHal; + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc + = (tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *) bapEvent->params; + tBtampAMP_ASSOC btamp_ASSOC; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //If we are a BT-Responder, we are assuming we are a BT "slave" and we HAVE + //to "squelch" the slaves frequent (every 1.25ms) polls. + + if (eCSR_BSS_TYPE_WDS_STA == bssType) + { + /* Sleep for 300(200) milliseconds - to allow BT through */ + vos_sleep( 200 ); + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + } + + + //Tell PMC to exit BMPS; + halStatus = pmcRequestFullPower( + hHal, + WLANBAP_pmcFullPwrReqCB, + btampContext, + eSME_REASON_OTHER); + // JEZ081210: This has to wait until we sync down from + // /main/latest as of 12/4. We are currently at 12/3. + //eSME_FULL_PWR_NEEDED_BY_BAP); + //Need to check the result...because Host may have been told by + //OS to go to standby (D2) device state. In that case, I have to + //fail the HCI Create Physical Link + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, amp_assoc_remaining_length = %d", __func__, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_remaining_length); +#if 0 + DUMPLOG(1, __func__, "amp_assoc_fragment", + pBapHCIWriteRemoteAMPAssoc->amp_assoc_fragment, + 64); +#endif //0 + + //What about parsing the AMP Assoc structure? + parseStatus = btampUnpackAMP_ASSOC( + hHal, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_fragment, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_remaining_length, + &btamp_ASSOC); + + /* Unknown or Reserved TLVs are allowed in the write AMP assoc fragment */ + if ((BTAMP_PARSE_SUCCESS != parseStatus ) && (BTAMP_UNKNOWN_TLVS != parseStatus)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, parseStatus = %d", __func__, parseStatus); + *status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_E_BADMSG; + } + + //What about writing the peer MAC address, and other info to the BTAMP + //context for this physical link? + if (btamp_ASSOC.AMP_Assoc_MAC_Addr.present == 1) + { + /* Save the peer MAC address */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + /* Save it in the peer MAC address field */ + vos_mem_copy( + btampContext->peer_mac_addr, + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + sizeof(btampContext->peer_mac_addr)); + } + + if (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present == 1) + { + /* Save the peer Preferred Channel List */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_pref_country, + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_pref_country)); + /* Save the peer Preferred Channel List */ + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets = + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets; + if(WLANBAP_MAX_NUM_TRIPLETS < + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets) + { + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets = + WLANBAP_MAX_NUM_TRIPLETS; + } + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets, + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[0]) * + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets + ); + } + + if (btamp_ASSOC.AMP_Assoc_Connected_Channel.present == 1) + { + /* Save the peer Connected Channel */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_country, + btamp_ASSOC.AMP_Assoc_Connected_Channel.country, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_cnct_country)); + /* Save the peer Connected Channel */ + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets = + btamp_ASSOC.AMP_Assoc_Connected_Channel.num_triplets; + if(WLANBAP_MAX_NUM_TRIPLETS < + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets) + { + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets = + WLANBAP_MAX_NUM_TRIPLETS; + } + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_triplets, + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_cnct_triplets[0]) * + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets + ); + } + + if (btamp_ASSOC.AMP_Assoc_PAL_Capabilities.present == 1) + { + /* Save the peer PAL Capabilities */ + btampContext->btamp_Remote_AMP_Assoc.HC_pal_capabilities + = btamp_ASSOC.AMP_Assoc_PAL_Capabilities.pal_capabilities; + } + + if (btamp_ASSOC.AMP_Assoc_PAL_Version.present == 1) + { + /* Save the peer PAL Version */ + btampContext->btamp_Remote_AMP_Assoc.HC_pal_version + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_version; + + btampContext->btamp_Remote_AMP_Assoc.HC_pal_CompanyID + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_CompanyID; + + btampContext->btamp_Remote_AMP_Assoc.HC_pal_subversion + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_subversion; + } + + //Set Connection Accept Timeout; + /* Already done in gotoS1() */ + //Set gNeedPhysLinkCompEvent; + //JEZ081114: This needs to happen earlier. In gotoS1. Right at HCI Create Physical Link + btampContext->gNeedPhysLinkCompEvent = VOS_TRUE; + //Clear gDiscRequested; + btampContext->gDiscRequested = VOS_FALSE; + //Set gPhysLinkStatus to 0 (no error); + btampContext->gPhysLinkStatus = WLANBAP_STATUS_SUCCESS; + //Set gDiscReason to 0 (no reason); + btampContext->gDiscReason = WLANBAP_STATUS_SUCCESS; + /* Initiate the link as either START or JOIN */ + //halStatus = csrRoamOpenSession(&newSession); + /*Added by Luiza:*/ + + if (btampContext->isBapSessionOpen == FALSE) + { + + vosStatus = vos_get_vdev_types(VOS_STA_SAP_MODE, &type, &subType); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "failed to get vdev type"); + return VOS_STATUS_E_FAILURE; + } + halStatus = sme_OpenSession(hHal, + WLANBAP_RoamCallback, + btampContext, + // <=== JEZ081210: FIXME + //(tANI_U8 *) btampContext->self_mac_addr, + btampContext->self_mac_addr, + &btampContext->sessionId, + type,subType); + if(eHAL_STATUS_SUCCESS == halStatus) + { + btampContext->isBapSessionOpen = TRUE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "sme_OpenSession failed in %s", __func__); + *status = WLANBAP_ERROR_NO_CNCT; + return VOS_STATUS_E_FAILURE; + } + } + /* Update the SME Session info for this Phys Link (i.e., for this Phys State Machine instance) */ + //bapUpdateSMESessionForThisPhysLink(newSession, PhysLinkHandle); + // Taken care of, above + //halStatus = csrRoamConnect(newSession, bssType); + // Final + vosStatus = convertToCsrProfile ( + btampContext, /* btampContext value */ + bssType, + &btampContext->csrRoamProfile); /* return the profile info here */ + if(VOS_STATUS_E_INVAL == vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Incorrect channel to create AMP link %s", __func__); + *status = WLANBAP_ERROR_NO_SUITABLE_CHANNEL; + return VOS_STATUS_E_INVAL; + } +#if 0 + halStatus = sme_RoamConnect(VOS_GET_HAL_CB(btampContext->pvosGCtx), + &btampContext->csrRoamProfile, + NULL, /* tScanResultHandle hBssListIn, */ + &btampContext->csrRoamId); +#endif //0 +//#if 0 + halStatus = sme_RoamConnect(hHal, + btampContext->sessionId, + &btampContext->csrRoamProfile, + &btampContext->csrRoamId); +//#endif //0 + + //Map the halStatus into a vosStatus + return vosStatus; +} //gotoStarting + +VOS_STATUS +gotoConnecting( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* No longer needed. This call has been made in gotoStarting(). */ + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + + return vosStatus; +} //gotoConnecting + +VOS_STATUS +gotoAuthenticating( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + + return vosStatus; +} //gotoAuthenticating + +#if 0 +VOID initRsnSupplicant() +{ +/* This is a NO-OP. The Supplicant waits for MSG 1 */ +} +#endif /* 0 */ +VOS_STATUS +initRsnSupplicant +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* This is a NO-OP. The Supplicant waits for MSG 1 */ + /* Init RSN FSM */ + if (!(suppRsnFsmCreate(btampContext))) + { + /* Send Start Event */ + /* RSN_FSM_AUTH_START */ + } + else + { + /* RSN Init Failed */ + vosStatus = VOS_STATUS_E_FAILURE; + } + /* This is a NO-OP. The Supplicant waits for MSG 1 */ + return vosStatus; +} + +#if 0 +VOID initRsnAuthenticator() +{ +/* Signal the Authenticator/Supplicant App that we are associated. */ +/* Use an IOCTL? That the app is hanging a read on? Or use a "special" data packet. Again, that the app is waiting on a receive for. */ +} +#endif /* 0 */ +VOS_STATUS +initRsnAuthenticator +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /* Init RSN FSM */ + if (!(authRsnFsmCreate(btampContext))) + { + /* Send Start Event */ + } + else + { + /* RSN Init Failed */ + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +/* Signal the Authenticator/Supplicant App that we are associated. */ +/* Use an IOCTL? That the app is hanging a read on? Or use a "special" data packet. Again, that the app is waiting on a receive for. */ +} + +/* We have to register our STA with TL */ +VOS_STATUS +regStaWithTl +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + tCsrRoamInfo *pCsrRoamInfo +) +{ + VOS_STATUS vosStatus; + WLAN_STADescType staDesc; + tANI_S8 rssi = 0; + + vos_mem_zero(&staDesc, sizeof(WLAN_STADescType)); + /* Fill in everything I know about the STA */ + btampContext->ucSTAId = staDesc.ucSTAId = pCsrRoamInfo->staId; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BAP register TL ucSTAId=%d\n", + staDesc.ucSTAId ); + + /* Fill in the peer MAC address */ + vos_mem_copy( + staDesc.vSTAMACAddress.bytes, + btampContext->peer_mac_addr, + sizeof(btampContext->peer_mac_addr)); + + /* Fill in the self MAC address */ + vos_mem_copy( + staDesc.vSelfMACAddress.bytes, + btampContext->self_mac_addr, + sizeof(btampContext->peer_mac_addr)); + + /* Set the STA Type */ + staDesc.wSTAType = WLAN_STA_BT_AMP; + + // Set the QoS field appropriately, if the info available + if( pCsrRoamInfo->u.pConnectedProfile) + { + btampContext->bapQosCfg.bWmmIsEnabled = //1; + pCsrRoamInfo->u.pConnectedProfile->qosConnection; + } + else + { + btampContext->bapQosCfg.bWmmIsEnabled = 0; + } + + // set the QoS field appropriately + if( btampContext->bapQosCfg.bWmmIsEnabled ) + { + staDesc.ucQosEnabled = 1; + } + else + { + staDesc.ucQosEnabled = 0; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BAP register TL QoS_enabled=%d\n", + staDesc.ucQosEnabled ); + + // UMA is ready we inform TL not to do frame + // translation for WinMob 6.1 + //*** Not to enabled UMA. + /* Enable UMA for TX translation only when there is no concurrent session active */ + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 0; + + if ( btampContext->ucSecEnabled ) + { + staDesc.ucProtectedFrame = 1; + } + else + { + staDesc.ucProtectedFrame = 0; + } + + staDesc.ucUcastSig = pCsrRoamInfo->ucastSig; + staDesc.ucBcastSig = pCsrRoamInfo->bcastSig; + staDesc.ucInitState = ( btampContext->ucSecEnabled)? + WLANTL_STA_CONNECTED:WLANTL_STA_AUTHENTICATED; + staDesc.ucIsReplayCheckValid = VOS_FALSE; + if(NULL != pCsrRoamInfo->pBssDesc) + { + rssi = pCsrRoamInfo->pBssDesc->rssi; + } + /* register our STA with TL */ + vosStatus = WLANTL_RegisterSTAClient + ( + btampContext->pvosGCtx, + WLANBAP_STARxCB, + WLANBAP_TxCompCB, + (WLANTL_STAFetchPktCBType)WLANBAP_STAFetchPktCB, + &staDesc , + rssi); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + __func__, vosStatus, vosStatus ); + } + + if ( ! btampContext->ucSecEnabled ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", btampContext->ucSTAId); + + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState(btampContext->pvosGCtx, + staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED, VOS_FALSE); + } + else + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", btampContext->ucSTAId ); + + vosStatus = WLANTL_ChangeSTAState(btampContext->pvosGCtx, + staDesc.ucSTAId, + WLANTL_STA_CONNECTED, VOS_FALSE); + } + + return VOS_STATUS_SUCCESS; +} /* regStaWithTl */ + +#if 0 +/*========================================================================== + + FUNCTION: determineChan + + DESCRIPTION: Return the current channel we are to operate on + +============================================================================*/ +#endif + +VOS_STATUS +determineChan +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + v_U32_t *channel, /* Current channel */ + v_U8_t *status /* return the BT-AMP status here */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t activeFlag; /* Channel active flag */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + switch(BAPDeviceRole) + { + case BT_INITIATOR: + /* if an Infra assoc already exists, return that channel. */ + /* or use the results from the Scan to determine the least busy channel. How? */ + /* For now, just do this. */ + vosStatus = WLANBAP_GetCurrentChannel (btampContext, channel, &activeFlag); + break; + case BT_RESPONDER: + /* return the value obtained from the Preferred Channels field of the AMP Assoc structure from the BT-AMP peer (device A) */ + /* No! I don't have that yet. */ + /* For now, just do this. */ + vosStatus = WLANBAP_GetCurrentChannel (btampContext, channel, &activeFlag); + break; + default: + *status = WLANBAP_ERROR_HOST_REJ_RESOURCES; /* return the BT-AMP status here */ + return VOS_STATUS_E_RESOURCES; + } + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return vosStatus; +} // determineChan + +VOS_STATUS +gotoDisconnected +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + //Is it legitimate to always make this call? + //What if pmcRequestFullPower wasn't called? + //Tell PMC to resume BMPS; /* Whatever the previous BMPS "state" was */ + //Comment this out until such time as we have PMC support + //halStatus = pmcResumePower ( hHal); + + /* Signal BT Coexistence code in firmware to no longer prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 0); + + //Map the halStatus into a vosStatus + return vosStatus; +} // gotoDisconnected + +VOS_STATUS +gotoDisconnecting +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t needPhysLinkCompEvent, + v_U8_t physLinkStatus, /* BT-AMP disconnecting status */ +// v_U8_t statusPresent, /* BT-AMP disconnecting status present */ + v_U8_t discRequested, + v_U8_t discReason /* BT-AMP disconnecting reason */ +) +{ + + // gNeedPhysLinkCompEvent + btampContext->gNeedPhysLinkCompEvent = needPhysLinkCompEvent; + // gPhysLinkStatus + btampContext->gPhysLinkStatus = physLinkStatus; /* BT-AMP disconnecting status */ + // gDiscRequested + btampContext->gDiscRequested = discRequested; + // gDiscReason + btampContext->gDiscReason = discReason; /* BT-AMP disconnecting reason */ + + //WLANBAP_DeInitLinkSupervision( btampHandle); + //WLANBAP_StopLinkSupervisionTimer(btampContext); + + /* Inform user space that no AMP channel is in use, for AFH purposes */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, + "Calling send_btc_nlink_msg() with AMP channel = 0"); + send_btc_nlink_msg(WLAN_AMP_ASSOC_DONE_IND, 0); + + return VOS_STATUS_SUCCESS; +} //gotoDisconnecting + +VOS_STATUS +gotoConnected +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = ( ptBtampHandle)btampContext; +//#if 0 + /* Stop the Connection Accept Timer */ + vosStatus = WLANBAP_StopConnectionAcceptTimer (btampContext); +//#endif + ///*De-initialize the timer */ + //vosStatus = WLANBAP_DeinitConnectionAcceptTimer(btampContext); + + /* Signal BT Coex in firmware to now honor only priority BT requests */ + WLANBAP_NeedBTCoexPriority ( btampContext, 2); + + // If required after successful Upper layer auth, transition TL + // to 'Authenticated' state. + if ( btampContext->ucSecEnabled ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", btampContext->ucSTAId); + + vosStatus = WLANTL_ChangeSTAState(btampContext->pvosGCtx, + btampContext->ucSTAId, + WLANTL_STA_AUTHENTICATED, VOS_FALSE); + } + + btampContext->dataPktPending = VOS_FALSE; + vosStatus = WLANBAP_InitLinkSupervision( btampHandle); + + /* Inform user space of the AMP channel selected, for AFH purposes */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, + "Calling send_btc_nlink_msg() with AMP channel %d", btampContext->channel); + send_btc_nlink_msg(WLAN_AMP_ASSOC_DONE_IND, btampContext->channel); + + return vosStatus; +} //gotoConnected + + +/* the HCI Event signalling routine*/ +VOS_STATUS +signalHCIPhysLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status /* the BT-AMP status */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = btampContext->channel; + + if(WLANBAP_STATUS_SUCCESS == status) + { + /* Start the Tx packet monitoring timer */ + WLANBAP_StartTxPacketMonitorTimer(btampContext); + } + else + { //reset the PL handle + btampContext->phy_link_handle = 0; + } + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIPhysLinkCompEvent */ + +/* the HCI Disconnect Complete Event signalling routine*/ +VOS_STATUS +signalHCIPhysLinkDiscEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U8_t reason /* the BT-AMP reason code */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U8_t i; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: btampContext value = %p in %s:%d", btampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /* Loop disconnecting all Logical Links on this Physical Link */ + for (i = 0 ; i < WLANBAP_MAX_LOG_LINKS; i++) + { + pLogLinkContext = &(btampContext->btampLogLinkCtx[i]); + + if (pLogLinkContext->present == VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Deleting logical link entry %d in %s", i, + __func__); + + /* Mark this Logical Link index value as free */ + pLogLinkContext->present = VOS_FALSE; + + // signalHCIDiscLogLink(status = SUCCESS, reason = CONNECTION_TERM_BY_REMOTE_HOST); + signalHCIDiscLogLinkCompEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + i, // logical link + // I don't know how to signal CONNECTION_TERM_BY_REMOTE_HOST + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + } + + /*Reset current_log_link_index and total_log_link_index values*/ + btampContext->current_log_link_index = 0; + btampContext->total_log_link_index = 0; + + /* Format the Physical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.reason = reason;//uncommented to debug + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + + /* Stop the Tx packet monitoring timer */ + WLANBAP_StopTxPacketMonitorTimer(btampContext); + + /*Need to clean up the phy link handle as we are disconnected at this + point + ?? - do we need to do any more cleanup on this*/ + btampContext->phy_link_handle = 0; + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIPhysLinkDiscEvent */ + +/* the HCI Channel Select Event signalling routine*/ +VOS_STATUS +signalHCIChanSelEvent +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Physical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT; + bapHCIEvent.u.btampChannelSelectedEvent.present = 1; + bapHCIEvent.u.btampChannelSelectedEvent.phy_link_handle + = btampContext->phy_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIChanSelEvent */ + + +/* the HCI Disconnect Logical Link Complete Event signalling routine*/ +VOS_STATUS +signalHCIDiscLogLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U16_t log_link_handle, /* The Logical Link that disconnected*/ + v_U8_t reason /* the BT-AMP reason code */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Logical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.reason = reason; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.log_link_handle + = (log_link_handle << 8) + btampContext->phy_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIDiscLogLinkCompEvent */ + + +// These are needed to recognize RSN suite types +#define WLANBAP_RSN_OUI_SIZE 4 +tANI_U8 pRSNOui00[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher +tANI_U8 pRSNOui01[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN +tANI_U8 pRSNOui02[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK +tANI_U8 pRSNOui03[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved +tANI_U8 pRSNOui04[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP +tANI_U8 pRSNOui05[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104 + +/* Incoming Association indication validation predicate */ +v_U32_t +validAssocInd +( + ptBtampContext btampContext, /* btampContext value */ + tCsrRoamInfo *pRoamInfo +) +{ + /* tHalHandle */ + tHalHandle hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + v_U32_t ieLen; + + /* For now, always return true */ + return VOS_TRUE; + + /* Check for a valid peer MAC address */ + /* For an incoming Assoc Indication, the peer MAC address + * should match the value that the BlueTooth AMP + * configured us with. + */ + if ( !vos_mem_compare( btampContext->peer_mac_addr, + pRoamInfo->peerMac, + sizeof(btampContext->peer_mac_addr) )) + { + /* Return not valid */ + return VOS_FALSE; + } + + /* JEZ081115: For now, ignore the RSN IE */ + /* Otherwise, it is valid */ + return VOS_TRUE; + + /* Check for a trivial case: IEs missing */ + if( pRoamInfo->prsnIE == NULL ) + { + //btampContext->ieFields = NULL; + //btampContext->ieLen = 0; + /* Return not valid */ + return VOS_FALSE; + } + + //btampContext->ieLen = GET_IE_LEN_IN_BSS( pBssDesc->length ); + //ieLen = GET_IE_LEN_IN_BSS( pBssDesc->length ); + ieLen = pRoamInfo->rsnIELen; + + /* Check for a trivial case: IEs zero length */ + //if( btampContext->ieLen == 0 ) + if( ieLen == 0 ) + { + //btampContext->ieFields = NULL; + //btampContext->ieLen = 0; + /* Return not valid */ + return VOS_FALSE; + } + + { + // --- Start of block --- + tDot11fBeaconIEs dot11BeaconIEs; + tDot11fIESSID *pDot11SSID; + tDot11fIERSN *pDot11RSN; + + // JEZ081215: This really needs to be updated to just validate the RSN IE. + // Validating the SSID can be done directly from... + + // "Unpack" really wants tpAniSirGlobal (pMac) as its first param. + // But since it isn't used, I just pass in some arbitrary "context" pointer. + // So hHalHandle will make it happy. + dot11fUnpackBeaconIEs((tpAniSirGlobal) hHal, + (tANI_U8 *) pRoamInfo->prsnIE, + ieLen, + &dot11BeaconIEs); + + //DUMPLOG(9, __func__, "dot11BeaconIEs", &dot11BeaconIEs, 64); + + pDot11SSID = &dot11BeaconIEs.SSID; + + // Assume there wasn't an SSID in the Assoc Request + btampContext->assocSsidLen = 0; + + if (pDot11SSID->present ) + { + + //DUMPLOG(10, __func__, "pDot11SSID present", pDot11SSID, 64); + + btampContext->assocSsidLen = pDot11SSID->num_ssid; + vos_mem_copy(btampContext->assocSsid, + pDot11SSID->ssid, + btampContext->assocSsidLen ); + } + else + return VOS_FALSE; + + // Check the validity of the SSID against our SSID value + if ( !vos_mem_compare( btampContext->ownSsid, + pDot11SSID->ssid, + btampContext->ownSsidLen )) + { + /* Return not valid */ + return VOS_FALSE; + } + + pDot11RSN = &dot11BeaconIEs.RSN; + + // Assume there wasn't an RSN IE in the Assoc Request + //btampContext->assocRsnIeLen = 0; + + if (pDot11RSN->present ) + { + + //DUMPLOG(10, __func__, "pDot11RSN present", pDot11RSN, 64); + + //The 802.11 BT-AMP PAL only supports WPA2-PSK + if (!vos_mem_compare(pRSNOui02, // RSN-PSK + pDot11RSN->akm_suites[0], + WLANBAP_RSN_OUI_SIZE)) + return VOS_FALSE; + + //The 802.11 BT-AMP PAL only supports AES-CCMP Unicast + if (!vos_mem_compare(pRSNOui04, // AES-CCMP + pDot11RSN->pwise_cipher_suites[0], + WLANBAP_RSN_OUI_SIZE)) + return VOS_FALSE; + } + else + return VOS_FALSE; + + + } // --- End of block --- + + /* Otherwise, it is valid */ + return VOS_TRUE; +} /* validAssocInd */ + +/* the change state function*/ +void +btampfsmChangeToState +( + BTAMPFSM_INSTANCEDATA_T *instance, + BTAMPFSM_STATES_T state +) +{ + instance->stateVar = state; + //BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + +} + +/* Physical Link state machine function */ +//int +VOS_STATUS +btampFsm +( + //BTAMPFSM_INSTANCEDATA_T *instanceVar + ptBtampContext btampContext, /* btampContext value */ +// tBtampSessCtx *tpBtampSessCtx, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + v_U8_t *status /* return the BT-AMP status here */ +) +{ + /* Retrieve the phy link state machine structure + * from the btampContext value + */ + BTAMPFSM_INSTANCEDATA_T *instanceVar; + v_U32_t msg = bapEvent->event; /* State machine input event message */ + v_U32_t channel; /* Current channel */ + v_U32_t activeFlag; /* Channel active flag */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = ( ptBtampHandle)btampContext; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + tHalHandle hHal = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Validate params */ + if (btampHandle == NULL) + { + return VOS_STATUS_E_FAULT; + } + instanceVar = &(btampContext->bapPhysLinkMachine); + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + + +#define CHANNEL_NOT_SELECTED (WLANBAP_GetCurrentChannel (btampContext, &channel, &activeFlag) != VOS_STATUS_SUCCESS) + + /*Initialize BTAMP PAL status code being returned to the btampFsm caller */ + *status = WLANBAP_STATUS_SUCCESS; + + switch(instanceVar->stateVar) + { + + case DISCONNECTED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE)) + { + /*Transition from DISCONNECTED to S1 (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTED", "S1"); + +#if 0 + /* This will have issues in multisession. Need not close the session */ + /* TODO : Need to have better handling */ + if(btampContext->isBapSessionOpen == TRUE)//We want to close only BT-AMP Session + { + sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId); + /*Added by Luiza:*/ + btampContext->isBapSessionOpen = FALSE; + } +#endif + + /* Set BAP device role */ + vosStatus = gotoS1( btampContext, bapEvent, BT_INITIATOR, status); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, cmd status is %d", __func__, *status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,S1); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT)) + { + /*Transition from DISCONNECTED to S1 (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTED", "S1"); + +#if 0 + if(btampContext->isBapSessionOpen == TRUE) + { + sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId); + /*Added by Luiza:*/ + btampContext->isBapSessionOpen = FALSE; + } + /*Action code for transition */ +#endif + + /* Set BAP device role */ + vosStatus = gotoS1(btampContext, bapEvent, BT_RESPONDER, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,S1); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "DISCONNECTED", msg); + /* Intentionally left blank */ + } + break; + + case S1: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_INITIATOR && !(CHANNEL_NOT_SELECTED))) + { + /*Transition from S1 to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "STARTING"); + + /*Action code for transition */ + vosStatus = determineChan(btampContext, BT_INITIATOR, &channel, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,STARTING); + // This has to be commented out until I get the BT-AMP SME/CSR changes + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_AP, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, S1); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from S1 to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "DISCONNECTED"); + + /*Action code for transition */ + /* Set everything back as dis-connected */ + gotoDisconnected( btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Signal the disconnect */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_TIMEOUT); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from S1 to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Signal the successful physical link disconnect */ + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Signal the unsuccessful physical link creation */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_NO_CNCT ); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from S1 to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "STARTING"); + + /*Action code for transition */ + //determineChan(BT_RESPONDER); + vosStatus = determineChan(btampContext, BT_RESPONDER, &channel, status); + btampfsmChangeToState(instanceVar,STARTING);//Moved to here to debug + // This has to be commented out until I get the BT-AMP SME/CSR changes + /*Advance outer statevar */ + // btampfsmChangeToState(instanceVar,STARTING); + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_STA, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, S1); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_INITIATOR && CHANNEL_NOT_SELECTED)) + { + /*Transition from S1 to SCANNING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "SCANNING"); + + /*Action code for transition */ + gotoScanning(btampContext, BT_RESPONDER, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,SCANNING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "S1", msg); + /* Intentionally left blank */ + } + break; + + case STARTING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_BSS_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from STARTING to CONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "CONNECTING"); + + btampfsmChangeToState(instanceVar,CONNECTING);//Moved to debug + + /*Set the selected channel */ + /*should have been already set */ + btampContext->channel = ( 0 == btampContext->channel )?1:btampContext->channel; + + /*Action code for transition */ + signalHCIChanSelEvent(btampContext); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from STARTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + // Danlin, where are the richer reason codes? + // I want to be able to convey everything 802.11 supports... + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_CHANNEL_SELECTION_FAILED)) + { + /*Transition from STARTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTED"); + + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Action code for transition */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_REJ_RESOURCES ); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_BSS_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from STARTING to CONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "CONNECTING"); + + /* Set the selected channel */ + /*should have been already set */ + btampContext->channel = ( 0 == btampContext->channel )?1:btampContext->channel; + + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTING); + /*Action code for transition */ + gotoConnecting(btampContext); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from STARTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_FAILS)) + { + /*Transition from STARTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_MAX_NUM_CNCTS ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "STARTING", msg); + /* Intentionally left blank */ + } + break; + + case CONNECTING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_COMPLETED + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from CONNECTING to AUTHENTICATING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "AUTHENTICATING"); + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "CONNECTED"); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnSupplicant(btampContext, BT_RESPONDER); +#if 1 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,AUTHENTICATING); +#else + /*Action code for transition */ + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); +#endif + /* register our STA with TL */ + regStaWithTl ( + btampContext, /* btampContext value */ + BT_RESPONDER, + (tCsrRoamInfo *)bapEvent->params); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_INDICATION + //) && (bssDesc indicates an invalid peer MAC Addr or SecParam)){ + ) && !validAssocInd(btampContext, (tCsrRoamInfo *)bapEvent->params)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + /*Action code for transition */ + //csrRoamDisconnect(DEAUTH); + //JEZ081120: Danlin points out that I could just ignore this + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_DEAUTH); + //eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_AUTHENT_FAILURE, + VOS_FALSE, + 0); + + /*Set the status code being returned to the btampFsm caller */ + *status = WLANBAP_ERROR_AUTHENT_FAILURE; + + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_INDICATION + //) && (bssDesc indicates a valid MAC Addr and SecParam)){ + ) && validAssocInd(btampContext, (tCsrRoamInfo *)bapEvent->params)) + { + /*Transition from CONNECTING to VALIDATED (both without substates)*/ + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "VALIDATED"); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "AUTHENTICATING"); + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "CONNECTED"); + + /*Action code for transition */ + // JEZ081027: This one is a pain. Since we are responding in the + // callback itself. This messes up my state machine. + //csrRoamAccept(); + + // No! This is fine. + /*Set the status code being returned to the btampFsm caller */ + *status = WLANBAP_STATUS_SUCCESS; + + /* JEZ081215: N.B.: Currently, I don't get the + * eCSR_ROAM_RESULT_WDS_ASSOCIATED as an AP. + * So, I have to register with TL, here. This + * seems weird. + */ + + /* register our STA with TL */ + regStaWithTl ( + btampContext, /* btampContext value */ + BT_INITIATOR, + (tCsrRoamInfo *)bapEvent->params ); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnAuthenticator(btampContext, BT_INITIATOR); + +#if 1 + /*Advance outer statevar */ + //btampfsmChangeToState(instanceVar,VALIDATED); + btampfsmChangeToState(instanceVar,AUTHENTICATING); +#else + /*Action code for transition */ + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); +#endif + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_FAILED)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + sme_RoamDisconnect(hHal, + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /* Section 3.1.8 and section 3.1.9 have contradictory semantics for 0x16. + * 3.1.8 is "connection terminated by local host". 3.1.9 is "failed connection". + */ + //gotoDisconnecting(FAILED_CONNECTION); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST, //FAILED_CONNECTION + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "CONNECTING", msg); + /* Intentionally left blank */ + } + break; + + case AUTHENTICATING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from AUTHENTICATING to KEYING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "AUTHENTICATING", "KEYING"); + + /*Action code for transition */ + //sme_RoamSetContext(); +#if 0 + sme_RoamSetKey( + VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId, + tSirMacAddr peerBssId, + eCsrEncryptionType encryptType, + tANI_U16 keyLength, + tANI_U8 *pKey, + VOS_TRUE, // TRUE + tANI_U8 paeRole); +#endif //0 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,KEYING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from AUTHENTICATING to KEYING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "AUTHENTICATING", "KEYING"); + + /*Action code for transition */ + //sme_RoamSetContext(); +#if 0 + sme_RoamSetKey( + VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId, + tSirMacAddr peerBssId, + eCsrEncryptionType encryptType, + tANI_U16 keyLength, + tANI_U8 *pKey, + VOS_TRUE, // TRUE + tANI_U8 paeRole); +#endif //0 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,KEYING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s ConnectAcceptTimeout", __func__, "AUTHENTICATING", "DISCONNECTING"); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + /*Action code for transition */ + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s Physicallink Disconnect", __func__, "AUTHENTICATING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_FAILURE)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s RSN Failure", __func__, "AUTHENTICATING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(DEAUTH); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_DEAUTH); + //eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_AUTHENT_FAILURE, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "AUTHENTICATING", msg); + /* Intentionally left blank */ + } + break; + + case CONNECTED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from CONNECTED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTED", "DISCONNECTING"); + + gotoDisconnecting( + btampContext, + VOS_FALSE, + 0, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + WLANBAP_DeInitLinkSupervision(( ptBtampHandle)btampContext); + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION)) + { + + /*Transition from CONNECTED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTED", "DISCONNECTING"); + WLANBAP_DeInitLinkSupervision(( ptBtampHandle)btampContext); + + gotoDisconnecting( + btampContext, + VOS_FALSE, + 0, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Action code for transition */ + sme_RoamDisconnect(hHal, + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "CONNECTED", msg); + /* Intentionally left blank */ + } + break; + +/* JEZ081107: This will only work if I have already signalled the disconnect complete + * event in every case where a physical link complete event is required. And a + * disconnect was requested. + * - - - + * And only if I check for gNeedPhysLinkCompEvent BEFORE I check gDiscRequested. + * Naw! Not necessary. + */ + case DISCONNECTING: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Entered DISCONNECTING:", __func__);//Debug statement + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_READY_FOR_CONNECTIONS + ) && (btampContext->gDiscRequested == VOS_TRUE)) + { + /*Transition from DISCONNECTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTING", "DISCONNECTED"); + + //Clear gDiscRequested; + btampContext->gDiscRequested = VOS_FALSE; + + if(btampContext->BAPDeviceRole == BT_INITIATOR) + { + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Get LOCK Fail"); + } + authRsnFsmFree(btampContext); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Release LOCK Fail"); + } + } + else if(btampContext->BAPDeviceRole == BT_RESPONDER) + { + suppRsnFsmFree(btampContext); + } + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + btampContext->phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + WLANTL_ClearSTAClient(btampContext->pvosGCtx, ucSTAId); + + // gotoDisconnected(btampContext); + + // VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:In DISCONNECTING-changing outer state var to DISCONNECTED", __func__); + /*Advance outer statevar */ + // btampfsmChangeToState(instanceVar,DISCONNECTED); + + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + btampContext->gDiscReason); + /*sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId);*/ + /*Action code for transition */ + gotoDisconnected(btampContext); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:In DISCONNECTING-changing outer state var to DISCONNECTED", __func__); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_READY_FOR_CONNECTIONS + ) && (btampContext->gNeedPhysLinkCompEvent == VOS_TRUE)) + { + /*Transition from DISCONNECTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s gNeedPhysLinkComp TRUE", __func__, "DISCONNECTING", "DISCONNECTED"); + if(btampContext->BAPDeviceRole == BT_INITIATOR) + { + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Get LOCK Fail"); + } + authRsnFsmFree(btampContext); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Release LOCK Fail"); + } + + } + else if(btampContext->BAPDeviceRole == BT_RESPONDER) + { + suppRsnFsmFree(btampContext); + } + /* Lookup the StaId using the phy_link_handle and the BAP context */ + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + btampContext->phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + WLANTL_ClearSTAClient(btampContext->pvosGCtx, ucSTAId); + + + /*Action code for transition */ + // signalHCIPhysLinkCompEvent(btampContext, WLANBAP_ERROR_NO_CNCT/*btampContext->gPhysLinkStatus*/); + signalHCIPhysLinkCompEvent(btampContext, btampContext->gPhysLinkStatus); + gotoDisconnected(btampContext); + /*sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId);*/ + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + // signalHCIPhysLinkCompEvent(btampContext, btampContext->gPhysLinkStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "DISCONNECTING", msg); + /* Intentionally left blank */ + } + break; + + case KEYING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from KEYING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from KEYING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_KEY_SET_SUCCESS)) + { + /*Transition from KEYING to CONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "CONNECTED"); + + /*Action code for transition */ + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "KEYING", msg); + /* Intentionally left blank */ + } + break; + + case SCANNING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_SCAN_COMPLETE)) + { + /*Transition from SCANNING to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "STARTING"); + + /*Action code for transition */ + vosStatus = determineChan(btampContext, BT_INITIATOR, &channel, status); + // This has to be commented out until I get the BT-AMP SME/CSR changes + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,STARTING); + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_AP, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, SCANNING); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from SCANNING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_TIMEOUT); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from SCANNING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_NO_CNCT); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "SCANNING", msg); + /* Intentionally left blank */ + } + break; + + case VALIDATED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_COMPLETED + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from VALIDATED to AUTHENTICATING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "AUTHENTICATING"); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnAuthenticator(btampContext, BT_INITIATOR); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,AUTHENTICATING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from VALIDATED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from VALIDATED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "VALIDATED", msg); + /* Intentionally left blank */ + } + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, invalid state %d", __func__, instanceVar->stateVar); + /*Intentionally left blank*/ + break; + } + + return vosStatus; +} + +VOS_STATUS btampEstablishLogLink(ptBtampContext btampContext) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t msg; + + tAniBtAmpLogLinkReq *pMsg; + + pMsg = vos_mem_malloc(sizeof(tAniBtAmpLogLinkReq)); + if ( NULL == pMsg ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, failed to allocate mem for req", __func__); + return VOS_STATUS_E_NOMEM; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_BTAMP_LOG_LINK_IND); + pMsg->msgLen = (tANI_U16)sizeof(tAniBtAmpLogLinkReq); + pMsg->sessionId = btampContext->sessionId; + pMsg->btampHandle = btampContext; + + msg.type = eWNI_SME_BTAMP_LOG_LINK_IND; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, failed to post msg to self", __func__); + vos_mem_free(pMsg); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +void btampEstablishLogLinkHdlr(void* pMsg) +{ + tAniBtAmpLogLinkReq *pBtAmpLogLinkReq = (tAniBtAmpLogLinkReq*)pMsg; + ptBtampContext btampContext; + + if(pBtAmpLogLinkReq) + { + btampContext = (ptBtampContext)pBtAmpLogLinkReq->btampHandle; + if(NULL != btampContext) + { + vos_sleep( 200 ); + WLAN_BAPEstablishLogicalLink(btampContext); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, btampContext is NULL", __func__); + return; + } + + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, pBtAmpLogLinkReq is NULL", __func__); + } + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.h new file mode 100644 index 0000000000000..e9a92614d02ae --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/* This file is generated from btampFsm - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 / version 1.2 Beta 1 */ + + +#ifndef __BTAMPFSM_H__ +#define __BTAMPFSM_H__ + +#include "bapRsn8021xFsm.h" + +/* State definitions */ +typedef enum +{ + AUTHENTICATING, + DISCONNECTED, + CONNECTING, + DISCONNECTING, + SCANNING, + CONNECTED, + S1, + KEYING, + VALIDATED, + STARTING, +} BTAMPFSM_STATES_T; + + +#if 0 +/* Instance data definition of state machine */ +typedef struct +{ + BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + BTAMPFSM_STATEVAR_T stateVar; + BTAMPFSM_INST_ID_T inst_id; +} BTAMPFSM_INSTANCEDATA_T; +#endif //0 + +/* Helper to initialize the machine's instance data */ +#define BTAMPFSM_INSTANCEDATA_INIT { 1, DISCONNECTED/* set init state */, 0 /* instance id */}; + +/*Prototype for the change state function*/ +void btampfsmChangeToState(BTAMPFSM_INSTANCEDATA_T *instance, BTAMPFSM_STATES_T state); + + + +/*Prototype of the state machine function */ +//int +VOS_STATUS +btampFsm +( + //BTAMPFSM_INSTANCEDATA_T *instanceVar + ptBtampContext btampContext, /* btampContext value */ +// tBtampSessCtx *tpBtampSessCtx, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + v_U8_t *status /* return the BT-AMP status here */ +); + +VOS_STATUS +bapSetKey( v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo ); + +int bapSuppDisconnect(tBtampContext *ctx); +int bapAuthDisconnect(tBtampContext *ctx); +VOS_STATUS btampEstablishLogLink(ptBtampContext btampContext); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm_ext.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm_ext.h new file mode 100644 index 0000000000000..d45f89311a484 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampFsm_ext.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 */ + + +#ifndef __BTAMPFSM_EXT_H__ +#define __BTAMPFSM_EXT_H__ + +/* Events that can be sent to the state-machine */ +typedef enum +{ + eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT=0U, + eWLAN_BAP_MAC_CONNECT_COMPLETED +, + eWLAN_BAP_CHANNEL_SELECTION_FAILED, + eWLAN_BAP_MAC_CONNECT_FAILED, + eWLAN_BAP_MAC_CONNECT_INDICATION +, + eWLAN_BAP_MAC_KEY_SET_SUCCESS, + eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT, + eWLAN_BAP_RSN_FAILURE, + eWLAN_BAP_MAC_SCAN_COMPLETE, + eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE, + eWLAN_BAP_MAC_READY_FOR_CONNECTIONS +, + eWLAN_BAP_MAC_START_BSS_SUCCESS +, + eWLAN_BAP_RSN_SUCCESS, + eWLAN_BAP_MAC_START_FAILS, + eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT, + eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION, + eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC +, + NO_MSG +}MESSAGE_T; + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/btampHCI.c b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampHCI.c new file mode 100644 index 0000000000000..05d3c14bd56d3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/btampHCI.c @@ -0,0 +1,9310 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * \file btampHCI.c + * + * \brief Structures, functions & definitions for + * working with 802.11 Frames + * + * + * + * + * This file was automatically generated by 'framesc' + * Fri Feb 27 17:29:19 2009 from the following file(s): + * + * btampHCI.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * + */ + +#include /* For memcpy */ +#include /* For offsetof */ + +#define _vsnprintf vsnprintf + +#include "vos_api.h" +#include "btampHCI.h" + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4244) +# pragma warning (disable: 4505) +# pragma warning (disable: 4702) +# pragma warning (disable: 4996) /* ... was declared deprecated */ +#endif /* Microsoft C/C++ */ + +/*Length of the value field expected in a TLV of type Connected Channel in an + AMP Assoc*/ +#define WLAN_BAP_PAL_AMP_ASSOC_CONN_CH_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Preferred Channel in an + AMP Assoc*/ +#define WLAN_BAP_PAL_AMP_ASSOC_PREF_CH_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type MAC Address*/ +#define WLAN_BAP_PAL_MAC_ADDR_TLV_LEN 6 + +/*Length of the value field expected in a TLV of type Capabilities*/ +#define WLAN_BAP_PAL_CAPABILITIES_TLV_LEN 4 + +/*Length of the value field expected in a TLV of type Version*/ +#define WLAN_BAP_PAL_VERSION_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Accept Phy Link*/ +#define WLAN_BAP_PAL_ACC_PHY_LINK_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Accept Log Link*/ +#define WLAN_BAP_PAL_ACC_LOG_LINK_TLV_LEN 37 + +/*Length of the value field expected in a TLV of type Create Log Link*/ +#define WLAN_BAP_PAL_CREATE_LOG_LINK_TLV_LEN 37 + +/*Length of the value field expected in a TLV of type Create Phy Link*/ +#define WLAN_BAP_PAL_CREATE_PHY_LINK_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Disconnect Log Link*/ +#define WLAN_BAP_PAL_DISC_LOG_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Disconnect Phy Link*/ +#define WLAN_BAP_PAL_DISC_PHY_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Flow Spec Modify*/ +#define WLAN_BAP_PAL_FLOW_SPEC_MOD_TLV_LEN 34 + +/*Length of the value field expected in a TLV of type Flush*/ +#define WLAN_BAP_PAL_FLUSH_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type enhanced Flush*/ +#define WLAN_BAP_PAL_ENHANCED_FLUSH_TLV_LEN 3 + +/*Length of the value field expected in a TLV of type Cancel Log Link*/ +#define WLAN_BAP_PAL_CANCEL_LOG_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Best Effort Flush + Timeout*/ +#define WLAN_BAP_PAL_READ_BE_FLUSH_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Failed Contact + Counter*/ +#define WLAN_BAP_PAL_READ_FAILED_CONTACT_CNT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Link Quality*/ +#define WLAN_BAP_PAL_READ_LINK_QUALITY_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Link Supervision + Timeout*/ +#define WLAN_BAP_PAL_READ_LINK_SVISISON_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Local AMP Assoc*/ +#define WLAN_BAP_PAL_READ_LOCAL_AMP_ASSOC_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Read RSSI*/ +#define WLAN_BAP_PAL_READ_RSSI_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Reset Failed Contact + Counter*/ +#define WLAN_BAP_PAL_RESET_FAILED_CONTACT_CNT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Set Event Mask*/ +#define WLAN_BAP_PAL_SET_EVENT_MASK_TLV_LEN 8 + +/*Length of the value field expected in a TLV of type Set Event Mask2*/ +#define WLAN_BAP_PAL_SET_EVENT_MASK2_TLV_LEN 8 + +/*Length of the value field expected in a TLV of type Set SHort Range Mode*/ +#define WLAN_BAP_PAL_SET_SHORT_RANGE_MODE_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Best Effort Flush + Timeout*/ +#define WLAN_BAP_PAL_WRITE_BE_FLUSH_TIMEOUT_TLV_LEN 6 + +/*Length of the value field expected in a TLV of type Write Connection Accept + Timeout*/ +#define WLAN_BAP_PAL_WRITE_CON_ACC_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Flow Control Mode*/ +#define WLAN_BAP_PAL_WRITE_FLOW_CTRL_MODE_TLV_LEN 1 + +/*Length of the value field expected in a TLV of type Write Link Supervision + Timeout*/ +#define WLAN_BAP_PAL_WRITE_LINK_SVISION_TIMEOUT_TLV_LEN 4 + +/*Length of the value field expected in a TLV of type Write Location Data*/ +#define WLAN_BAP_PAL_WRITE_LOCATION_DATA_CMD_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Write LL Acc Timeout*/ +#define WLAN_BAP_PAL_WRITE_LOG_LINK_ACC_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Loopback Mode*/ +#define WLAN_BAP_PAL_WRITE_LOOOPBACK_MODE_TLV_LEN 1 + +/*Length of the value field expected in a TLV of type Write Remote AMP Assoc*/ +#define WLAN_BAP_PAL_WRITE_REMOTE_AMP_ASSOC_MIN_TLV_LEN 5 + +/* As per AMP specification */ +/* Regulatory Extension Identifier for channel list */ +#define WLAN_BAP_PAL_REG_EXTN_ID_VAL 201 + +/* Regulatory Class for channel list */ +#define WLAN_BAP_PAL_REG_CLASS_VAL 254 + +/* Coverage ClASS for channel list */ +#define WLAN_BAP_PAL_COVERAGE_CLASS_VAL 0 + + +/* LOGGING and VALIDITY_CHECKING control */ +//#define WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING +//#define WLAN_BAPHCI_ENABLE_LOGGING + +typedef unsigned char tFRAMES_BOOL; +typedef void (*pfnGeneric_t)(void); + + +typedef struct sFFDefn { + v_U8_t size; + size_t offset; + v_U16_t sig; + pfnGeneric_t pfn; + const char *name; +} tFFDefn; + +typedef struct sIEDefn { + v_U8_t eid; + v_U16_t minSize; + v_U16_t maxSize; + size_t offset; + size_t presenceOffset; + size_t countOffset; + v_U16_t arraybound; + unsigned char oui[5]; + unsigned char noui; + v_U16_t sig; + pfnGeneric_t pfn; + const char *name; + tFRAMES_BOOL fMandatory; +} tIEDefn; + +#if !defined(countof) +#define countof(x) ( sizeof( (x) ) / sizeof( (x)[0] ) ) +#endif + +#if ! defined(BTAMP_MEMCPY) +# define BTAMP_MEMCPY(ctx, dst, src, len) \ + memcpy( (dst), (src), (len) ) \ + +#endif + +#if ! defined(BTAMP_MEMCMP) +# define BTAMP_MEMCMP(ctx, lhs, rhs, len) \ + memcmp( (lhs), (rhs), (len) ) \ + +#endif + +#ifndef BTAMP_HAVE_LOG_SEVERITIES +# define FRLOG_OFF ( 0 ) +# define FRLOGP ( 1 ) +# define FRLOGE ( 2 ) +# define FRLOGW ( 3 ) +# define FRLOG1 ( 4 ) +# define FRLOG2 ( 5 ) +# define FRLOG3 ( 6 ) +# define FRLOG4 ( 7 ) +#endif + +#define FRFL(x) x + +#ifdef BTAMP_ENABLE_LOGGING + +#ifndef BTAMP_HAVE_LOG_MACROS + +#include +#include + +#ifndef BTAMP_LOG_GATE +# define BTAMP_LOG_GATE FRLOGW +#endif // BTAMP_LOG_GATE + +#ifdef WIN32 + +#if defined ( _CONSOLE ) || defined ( _WINDOWS ) || defined ( _DLL ) || defined ( _LIB ) +#include +#define DBGPRINT OutputDebugStringA +#else /* Not User mode */ +#define DBGPRINT DbgPrint +#endif /* User mode */ + + + +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{ + va_list val; + char buffer[1024]; + (void)pCtx; + if ( nSev <= BTAMP_LOG_GATE ) + { + va_start(val, lpszFormat); + _vsnprintf(buffer, 1024, lpszFormat, val); + va_end(val); + DBGPRINT(buffer); + } +} +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ + char buffer[35]; + int i, offset; + pCtx; + offset = 0; + if ( nSev > BTAMP_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + _snprintf(buffer, 35, "%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + DBGPRINT(buffer); + } + _snprintf(buffer, 35, "%08x: ", offset); + DBGPRINT(buffer); + for (i = 0; i < nBuf % 8; ++i) + { + _snprintf(buffer, 35, "%02x ", *pBuf); + ++pBuf; + DBGPRINT(buffer); + } + DBGPRINT("\n"); +} + +#elif defined OS_X /* Not WIN32 */ +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{// To fill in when needed using IOLog + +} + +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ +} + +#elif defined LINUX + +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{ + va_list marker; + (void)pCtx; + if ( nSev <= BTAMP_LOG_GATE ) + { + va_start( marker, lpszFormat ); + vprintf(lpszFormat, marker); + va_end( marker ); + } +} + +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ + char buffer[35]; + int i, offset; + (void)pCtx; + offset = 0; + if ( nSev > BTAMP_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + printf("%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + } + printf("%08x: ", offset); + for (i = 0; i < nBuf % 8; ++i) + { + printf("%02x ", *pBuf); + ++pBuf; + } + printf("\n"); +} + +#endif /* WIN32 */ + +#define FRAMES_LOG0(ctx, sev, fmt) \ + framesLog((ctx), (sev), (fmt)); +#define FRAMES_LOG1(ctx, sev, fmt, p1) \ + framesLog((ctx), (sev), (fmt), (p1)); +#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + framesLog((ctx), (sev), (fmt), (p1), (p2)); +#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + framesLog((ctx), (sev), (fmt), (p1), (p2), (p3)); +#define FRAMES_DUMP(ctx, sev, p, n) \ + framesDump((ctx), (sev), (p), (n)); +#ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +#endif + +#endif /* End BTAMP_HAVE_LOG_MACROS */ + +#else // ! BTAMP_ENABLE_LOGGING +# define FRAMES_LOG0(ctx, sev, fmt) +# define FRAMES_LOG1(ctx, sev, fmt, p1) +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) +# define FRAMES_DUMP(ctx, sev, p, n) +# ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +# endif +#endif // BTAMP_ENABLE_LOGGING + +#if defined( BTAMP_ENABLE_DBG_BREAK ) && defined ( WIN32 ) +# define FRAMES_DBG_BREAK() { _asm int 3 } +#else +# define FRAMES_DBG_BREAK() +#endif + +#if ! defined(BTAMP_PARAMETER_CHECK2) +# if defined (BTAMP_HAVE_WIN32_API) + +# define BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) do { \ + if (!pSrc || IsBadReadPtr(pSrc, 4)) return BTAMP_BAD_INPUT_BUFFER; \ + if (!pBuf || IsBadWritePtr(pBuf, nBuf)) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (IsBadWritePtr(pnConsumed, 4)) return BTAMP_BAD_OUTPUT_BUFFER; \ + } while (0) + +# else + +# define BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) do { \ + if (!pSrc) return BTAMP_BAD_INPUT_BUFFER; \ + if (!pBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!pnConsumed) return BTAMP_BAD_OUTPUT_BUFFER; \ + } while (0) +# endif +#endif + +static void framesntohs(void * pCtx, + v_U16_t *pOut, + v_U8_t *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, ( v_U16_t* )pOut, pIn, 2); + } + else + { + *pOut = ( v_U16_t )( *pIn << 8 ) | *( pIn + 1 ); + } +# else + if ( !fMsb ) + { + *pOut = ( v_U16_t )( *pIn | ( *( pIn + 1 ) << 8 ) ); + } + else + { + BTAMP_MEMCPY(pCtx, ( v_U16_t* )pOut, pIn, 2); + } +# endif +} + +static void framesntohl(void * pCtx, + v_U32_t *pOut, + v_U8_t *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + *pOut = * ( v_U32_t* )pIn; + } + else + { + *pOut = ( v_U32_t )( *pIn << 24 ) | + ( *( pIn + 1 ) << 16 ) | + ( *( pIn + 2 ) << 8 ) | + ( *( pIn + 3 ) ); + } +# else + if ( !fMsb ) + { + *pOut = ( v_U32_t )( *( pIn + 3 ) << 24 ) | + ( *( pIn + 2 ) << 16 ) | + ( *( pIn + 1 ) << 8 ) | + ( *( pIn ) ); + } + else + { + *pOut = * ( v_U32_t* )pIn; + } +# endif +} + +static void frameshtons(void * pCtx +, v_U8_t *pOut, + v_U16_t pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +# else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 2); + } +# endif +} + +static void frameshtonl(void * pCtx, + v_U8_t *pOut, + v_U32_t pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +# else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 4); + } +# endif +} + +typedef struct sTLVDefn { + v_U32_t id; + v_U32_t pec; + v_U32_t minSize; + v_U32_t maxSize; + size_t offset; + size_t presenceOffset; + v_U16_t sig; + pfnGeneric_t pfn; + const char * name; + v_U8_t fMandatory; +} tTLVDefn; + +static tTLVDefn* FindTLVDefn( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ] ) +{ + tTLVDefn *pTlv; + v_U32_t sType, sLen; + v_U32_t pec; + v_U16_t id; + + sType = 1; + sLen = 2; + + (void)pCtx; + + if (sType == 2) + framesntohs( pCtx, &id, pBuf, 2 ); + else { + id = *pBuf; + } + + pTlv = &( TLVs[ 0 ] ); + while ( 0xffff != pTlv->id ) + { + if ( id == pTlv->id ) + { + if ( 0 == pTlv->pec ) return pTlv; + + if( nBuf > 5 ) + { + pec = ( ( * ( pBuf + 4 ) ) << 16 ) | + ( ( * ( pBuf + 5 ) ) << 8 ) | + * ( pBuf + 6 ); + if ( pec == pTlv->pec ) + { + return pTlv; + } + } + } + + ++pTlv; + } + + return NULL; +} + +static v_U32_t UnpackTlvCore( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ], + v_U8_t *pFrm, + size_t nFrm ); +static v_U32_t PackTlvCore(void * pCtx, + v_U8_t *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed, + tTLVDefn TLVs[], + v_U32_t *pidx); +static v_U32_t GetPackedSizeTlvCore(void * pCtx, + v_U8_t *pFrm, + v_U32_t *pnNeeded, + tTLVDefn TLVs[]); + +v_U32_t btampUnpackTlvAMP_Assoc_Connected_Channel(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_Connected_Channel *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_AMP_ASSOC_CONN_CH_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + + + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + if ( ! tlvlen ) + { + pDst->num_triplets = 0U; + return 0U; + } + else + { + /* Maximum of 5 triplets allowed, based on size of triplets definition */ + if (tlvlen / 3 > 5) + { + tlvlen = 15; + } + pDst->num_triplets = (v_U8_t)( tlvlen / 3 ); + + BTAMP_MEMCPY(pCtx, pDst->triplets, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + } + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_Connected_Channel_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_Connected_Channel*); + +#define SigUnpackTlvAMP_Assoc_Connected_Channel ( 0x0001 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_MAC_Addr(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_MAC_Addr *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_MAC_ADDR_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->mac_addr, pBuf, 6); + pBuf += 6; + tlvlen -= (v_U8_t)6; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_MAC_Addr_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_MAC_Addr*); + +#define SigUnpackTlvAMP_Assoc_MAC_Addr ( 0x0002 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Capabilities(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_PAL_Capabilities *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CAPABILITIES_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohl(pCtx, &pDst->pal_capabilities, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_PAL_Capabilities_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_PAL_Capabilities*); + +#define SigUnpackTlvAMP_Assoc_PAL_Capabilities ( 0x0003 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Version(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_PAL_Version *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_VERSION_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->pal_version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->pal_CompanyID, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->pal_subversion, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_PAL_Version_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_PAL_Version*); + +#define SigUnpackTlvAMP_Assoc_PAL_Version ( 0x0004 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_Preferred_Channel_List *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_AMP_ASSOC_PREF_CH_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + /* Contry String - 3 bytes */ + BTAMP_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + + if ( ! tlvlen ) + { + pDst->num_triplets = 0U; + return status; + } + else + { + /* Maximum of 5 triplets allowed, based on size of triplets definition */ + if (tlvlen / 3 > 5) + { + tlvlen = 15; + } + pDst->num_triplets = (v_U8_t)( tlvlen / 3 ); + + BTAMP_MEMCPY(pCtx, pDst->triplets, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + } + return status; +} /* End btampUnpackTlvAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_Preferred_Channel_List_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_Preferred_Channel_List*); + +#define SigUnpackTlvAMP_Assoc_Preferred_Channel_List ( 0x0005 ) + + +v_U32_t btampUnpackTlvFlow_Spec(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVFlow_Spec *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->service_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->max_sdu, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->sdu_inter_arrival, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->access_latency, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvFlow_Spec. */ + +typedef v_U32_t (*pfnUnpackTlvFlow_Spec_t)(void *, v_U8_t*, v_U16_t, tBtampTLVFlow_Spec*); + +#define SigUnpackTlvFlow_Spec ( 0x0006 ) + + +v_U32_t btampUnpackTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Accept_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_ACC_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Accept_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Accept_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Accept_Logical_Link_Cmd ( 0x0007 ) + + +v_U32_t btampUnpackTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Accept_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_ACC_PHY_LINK_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + if (pDst->key_length > 32){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->key_material, pBuf, ( pDst->key_length ) ); + pBuf += ( pDst->key_length ); + tlvlen -= ( pDst->key_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Accept_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Accept_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Accept_Physical_Link_Cmd ( 0x0008 ) + + +v_U32_t btampUnpackTlvHCI_Channel_Selected_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Channel_Selected_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Channel_Selected_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Channel_Selected_Event*); + +#define SigUnpackTlvHCI_Channel_Selected_Event ( 0x0009 ) + + +v_U32_t btampUnpackTlvHCI_Command_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Command_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + pDst->present = 1; + pDst->num_hci_command_packets = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->command_opcode, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + switch (pDst->command_opcode) + { + case 0x0c03: + pDst->cc_event.Reset.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c08: + pDst->cc_event.Flush.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Flush.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x043b: + pDst->cc_event.Logical_Link_Cancel.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Logical_Link_Cancel.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Logical_Link_Cancel.tx_flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c05: + pDst->cc_event.Set_Event_Mask.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c15: + pDst->cc_event.Read_Connection_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Connection_Accept_TO.connection_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c16: + pDst->cc_event.Write_Connection_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c36: + pDst->cc_event.Read_Link_Supervision_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Supervision_TO.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Supervision_TO.link_supervision_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c37: + pDst->cc_event.Write_Link_Supervision_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Write_Link_Supervision_TO.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c61: + pDst->cc_event.Read_Logical_Link_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c62: + pDst->cc_event.Write_Logical_Link_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c63: + pDst->cc_event.Set_Event_Mask_Page_2.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c64: + pDst->cc_event.Read_Location_Data.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Location_Data.loc_domain_aware = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Location_Data.loc_domain, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + pDst->cc_event.Read_Location_Data.loc_options = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3173: + pDst->cc_event.Write_Location_Data.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3174: + pDst->cc_event.Read_Flow_Control_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Flow_Control_Mode.flow_control_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3175: + pDst->cc_event.Write_Flow_Control_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3177: + pDst->cc_event.Read_BE_Flush_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohl(pCtx, &pDst->cc_event.Read_BE_Flush_TO.best_effort_flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + break; + case 3178: + pDst->cc_event.Write_BE_Flush_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3179: + pDst->cc_event.Set_Short_Range_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 4097: + pDst->cc_event.Read_Local_Version_Info.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Local_Version_Info.HC_HCI_Version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_HCI_Revision, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Local_Version_Info.HC_PAL_Version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_Manufac_Name, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 4098: + pDst->cc_event.Read_Local_Supported_Cmds.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, pBuf, 64); + pBuf += 64; + tlvlen -= (v_U8_t)64; + break; + case 4101: + pDst->cc_event.Read_Buffer_Size.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Buffer_Size.HC_SCO_Packet_Length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 4106: + pDst->cc_event.Read_Data_Block_Size.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Data_Block_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5121: + pDst->cc_event.Read_Failed_Contact_Counter.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Failed_Contact_Counter.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Failed_Contact_Counter.failed_contact_counter, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5122: + pDst->cc_event.Reset_Failed_Contact_Counter.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Reset_Failed_Contact_Counter.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5123: + pDst->cc_event.Read_Link_Quality.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Quality.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Link_Quality.link_quality = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 5125: + pDst->cc_event.Read_RSSI.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_RSSI.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_RSSI.rssi = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 5129: + pDst->cc_event.Read_Local_AMP_Info.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Local_AMP_Info.HC_AMP_Status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Total_BW, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Min_Latency, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + pDst->cc_event.Read_Local_AMP_Info.HC_Controller_Type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + break; + case 5130: + pDst->cc_event.Read_Read_Local_AMP_Assoc.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + if (pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length > 248){ + // pDst->cc_event.Read_Read_Local_AMP_Assoc.present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment, pBuf, ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ) ); + pBuf += ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + tlvlen -= ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + break; + case 5131: + pDst->cc_event.Write_Remote_AMP_Assoc.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Write_Remote_AMP_Assoc.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 6145: + pDst->cc_event.Read_Loopback_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Loopback_Mode.loopback_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 6146: + pDst->cc_event.Write_Loopback_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + } + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Command_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Command_Complete_Event*); + +#define SigUnpackTlvHCI_Command_Complete_Event ( 0x000a ) + + +v_U32_t btampUnpackTlvHCI_Command_Status_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Command_Status_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->num_hci_command_packets = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->command_opcode, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Command_Status_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Command_Status_Event*); + +#define SigUnpackTlvHCI_Command_Status_Event ( 0x000b ) + + +v_U32_t btampUnpackTlvHCI_Create_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Create_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_CREATE_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Create_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Create_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Create_Logical_Link_Cmd ( 0x000c ) + + +v_U32_t btampUnpackTlvHCI_Create_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Create_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CREATE_PHY_LINK_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + if (pDst->key_length > 32){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->key_material, pBuf, ( pDst->key_length ) ); + pBuf += ( pDst->key_length ); + tlvlen -= ( pDst->key_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Create_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Create_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Create_Physical_Link_Cmd ( 0x000d ) + + +v_U32_t btampUnpackTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Data_Buffer_Overflow_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->link_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Data_Buffer_Overflow_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Data_Buffer_Overflow_Event*); + +#define SigUnpackTlvHCI_Data_Buffer_Overflow_Event ( 0x000e ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_DISC_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Disconnect_Logical_Link_Cmd ( 0x000f ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x0010 ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_DISC_PHY_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Disconnect_Physical_Link_Cmd ( 0x0011 ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x0012 ) + + +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flow_Spec_Modify_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLOW_SPEC_MOD_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->be_aggr_counter = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Cmd*); + +#define SigUnpackTlvHCI_Flow_Spec_Modify_Cmd ( 0x0013 ) + + +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*); + +#define SigUnpackTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x0014 ) + + +v_U32_t btampUnpackTlvHCI_Flush_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flush_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLUSH_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flush_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flush_Cmd*); + +#define SigUnpackTlvHCI_Flush_Cmd ( 0x0015 ) + + +v_U32_t btampUnpackTlvHCI_Flush_Occurred_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flush_Occurred_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flush_Occurred_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flush_Occurred_Event*); + +#define SigUnpackTlvHCI_Flush_Occurred_Event ( 0x0016 ) + + +v_U32_t btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->bd_addr, pBuf, 6); + pBuf += 6; + tlvlen -= (v_U8_t)6; + BTAMP_MEMCPY(pCtx, pDst->generic_amp_link_key, pBuf, 32); + pBuf += 32; + tlvlen -= (v_U8_t)32; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*); + +#define SigUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0017 ) + + +v_U32_t btampUnpackTlvHCI_Hardware_Error_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Hardware_Error_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->hardware_code = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Hardware_Error_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Hardware_Error_Event*); + +#define SigUnpackTlvHCI_Hardware_Error_Event ( 0x0018 ) + + +v_U32_t btampUnpackTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Logical_Link_Cancel_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CANCEL_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->tx_flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Logical_Link_Cancel_Cmd*); + +#define SigUnpackTlvHCI_Logical_Link_Cancel_Cmd ( 0x0019 ) + + +v_U32_t btampUnpackTlvHCI_Logical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Logical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Logical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Logical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Logical_Link_Complete_Event ( 0x001a ) + + +v_U32_t btampUnpackTlvHCI_Loopback_Command_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Loopback_Command_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->hci_command_packet, pBuf, 64); + pBuf += 64; + tlvlen -= (v_U8_t)64; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Loopback_Command_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Loopback_Command_Event*); + +#define SigUnpackTlvHCI_Loopback_Command_Event ( 0x001b ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Complete_Event ( 0x001c ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Loss_Warning_Event ( 0x001d ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Recovery_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Recovery_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Recovery_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Recovery_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Recovery_Event ( 0x001e ) + + +v_U32_t btampUnpackTlvHCI_Qos_Violation_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Qos_Violation_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Qos_Violation_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Qos_Violation_Event*); + +#define SigUnpackTlvHCI_Qos_Violation_Event ( 0x001f ) + + +v_U32_t btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_BE_FLUSH_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x0020 ) + + +v_U32_t btampUnpackTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Buffer_Size_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Buffer_Size_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Buffer_Size_Cmd*); + +#define SigUnpackTlvHCI_Read_Buffer_Size_Cmd ( 0x0021 ) + + +v_U32_t btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x0022 ) + + +v_U32_t btampUnpackTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Data_Block_Size_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Data_Block_Size_Cmd*); + +#define SigUnpackTlvHCI_Read_Data_Block_Size_Cmd ( 0x0023 ) + + +v_U32_t btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_FAILED_CONTACT_CNT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*); + +#define SigUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x0024 ) + + +v_U32_t btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*); + +#define SigUnpackTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x0025 ) + + +v_U32_t btampUnpackTlvHCI_Read_Link_Quality_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Link_Quality_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_LINK_QUALITY_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Link_Quality_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Link_Quality_Cmd*); + +#define SigUnpackTlvHCI_Read_Link_Quality_Cmd ( 0x0026 ) + + +v_U32_t btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_LINK_SVISISON_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x0027 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s. tlvlen=%d.", __func__, tlvlen); + +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_READ_LOCAL_AMP_ASSOC_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->length_so_far, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->max_remote_amp_assoc_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x0028 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_AMP_Information_Cmd ( 0x0029 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x002a ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_Version_Info_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_Version_Info_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_Version_Info_Cmd ( 0x002b ) + + +v_U32_t btampUnpackTlvHCI_Read_Location_Data_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Location_Data_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Location_Data_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Location_Data_Cmd*); + +#define SigUnpackTlvHCI_Read_Location_Data_Cmd ( 0x002c ) + + +v_U32_t btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x002d ) + + +v_U32_t btampUnpackTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Loopback_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Loopback_Mode_Cmd*); + +#define SigUnpackTlvHCI_Read_Loopback_Mode_Cmd ( 0x002e ) + + +v_U32_t btampUnpackTlvHCI_Read_RSSI_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_RSSI_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_RSSI_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_RSSI_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_RSSI_Cmd*); + +#define SigUnpackTlvHCI_Read_RSSI_Cmd ( 0x002f ) + + +v_U32_t btampUnpackTlvHCI_Reset_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Reset_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Reset_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Reset_Cmd*); + +#define SigUnpackTlvHCI_Reset_Cmd ( 0x0030 ) + + +v_U32_t btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_RESET_FAILED_CONTACT_CNT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*); + +#define SigUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x0031 ) + + +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Event_Mask_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_SET_EVENT_MASK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->event_mask, pBuf, 8); + pBuf += 8; + tlvlen -= (v_U8_t)8; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Event_Mask_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Event_Mask_Cmd*); + +#define SigUnpackTlvHCI_Set_Event_Mask_Cmd ( 0x0032 ) + + +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s. tlvlen=%d.", __func__, tlvlen); +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_SET_EVENT_MASK2_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->event_mask_page_2, pBuf, 8); + pBuf += 8; + tlvlen -= (v_U8_t)8; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*); + +#define SigUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x0033 ) + + +v_U32_t btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_SET_SHORT_RANGE_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->short_range_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*); + +#define SigUnpackTlvHCI_Set_Short_Range_Mode_Cmd ( 0x0034 ) + + +v_U32_t btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->short_range_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*); + +#define SigUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x0035 ) + + +v_U32_t btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_BE_FLUSH_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->best_effort_flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x0036 ) + + +v_U32_t btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_CON_ACC_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->connection_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x0037 ) + + +v_U32_t btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_FLOW_CTRL_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->flow_control_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*); + +#define SigUnpackTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x0038 ) + + +v_U32_t btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LINK_SVISION_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->link_supervision_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x0039 ) + + +v_U32_t btampUnpackTlvHCI_Write_Location_Data_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Location_Data_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOCATION_DATA_CMD_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->loc_domain_aware = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->loc_domain, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + pDst->loc_options = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Location_Data_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Location_Data_Cmd*); + +#define SigUnpackTlvHCI_Write_Location_Data_Cmd ( 0x003a ) + + +v_U32_t btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOG_LINK_ACC_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->logical_link_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x003b ) + + +v_U32_t btampUnpackTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Loopback_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOOOPBACK_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->loopback_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Loopback_Mode_Cmd*); + +#define SigUnpackTlvHCI_Write_Loopback_Mode_Cmd ( 0x003c ) + + +v_U32_t btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_REMOTE_AMP_ASSOC_MIN_TLV_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->length_so_far, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->amp_assoc_remaining_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + if (pDst->amp_assoc_remaining_length > 248){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->amp_assoc_fragment, pBuf, ( pDst->amp_assoc_remaining_length ) ); + pBuf += ( pDst->amp_assoc_remaining_length ); + tlvlen -= ( pDst->amp_assoc_remaining_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*); + +#define SigUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x003d ) + +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Enhanced_Flush_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_ENHANCED_FLUSH_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->packet_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Enhanced_Flush_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Enhanced_Flush_Cmd*); + +#define SigUnpackTlvHCI_Enhanced_Flush_Cmd ( 0x003e ) + + +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Enhanced_Flush_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Enhanced_Flush_Completed_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Enhanced_Flush_Complete_Event*); + +#define SigUnpackTlvHCI_Enhanced_Flush_Complete_Event ( 0x003f ) + + +v_U32_t btampUnpackAMP_ASSOC(void * pCtx, v_U8_t *pBuf, v_U32_t nBuf, tBtampAMP_ASSOC *pFrm) +{ + v_U32_t i; + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigUnpackTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 0xFF/*12*/, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigUnpackTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 0xFF/*12*/, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigUnpackTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigUnpackTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigUnpackTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t status = 0; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampUnpackAMP_ASSOC. nBuf - %d\n", nBuf); +#endif + + status |= UnpackTlvCore(pCtx,pBuf,nBuf,TLVS,(v_U8_t*)pFrm,sizeof(*pFrm)); + + (void)i; +# ifdef BTAMP_DUMP_FRAMES + if (!BTAMP_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Unpacked the AMP_ASSOC:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_MAC_Addr:\n")); + if (!pFrm->AMP_Assoc_MAC_Addr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_MAC_Addr.mac_addr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Preferred_Channel_List:\n")); + if (!pFrm->AMP_Assoc_Preferred_Channel_List.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Preferred_Channel_List.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Preferred_Channel_List.triplets, 3 * pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Connected_Channel:\n")); + if (!pFrm->AMP_Assoc_Connected_Channel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Connected_Channel.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Connected_Channel.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Connected_Channel.triplets, 3 * pFrm->AMP_Assoc_Connected_Channel.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Capabilities:\n")); + if (!pFrm->AMP_Assoc_PAL_Capabilities.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Capabilities.pal_capabilities, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Version:\n")); + if (!pFrm->AMP_Assoc_PAL_Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_CompanyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_subversion, 2); + } + } +# endif // BTAMP_DUMP_FRAMES + return status; + +} /* End btampUnpackAMP_ASSOC. */ + +static v_U32_t UnpackTlvCore( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ], + v_U8_t *pFrm, + size_t nFrm ) +{ + tTLVDefn *pTlv; + v_U32_t nBufRemaining, status, status2, npec; + v_U32_t sType, sLen; + v_U16_t id, len; + v_U8_t *pBufRemaining, *pfFound; + + (void)pCtx; // Shutup the compiler + (void)nFrm; + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In UnpackTlvCore, nBufRemaining - %d\n", nBufRemaining); +#endif + + // While we have data... + while ( nBufRemaining ) + { + if ( 3 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL( "This frame reports " + "fewer three byte(s) remaining.\n" ) ); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + npec = 0U; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "Calling FindTLVDefn...\n", nBufRemaining); +#endif + + // Look for a matching TLV definition, + pTlv = FindTLVDefn( pCtx, pBufRemaining, nBufRemaining, TLVs ); + sType = 1; + sLen = 2; + // consume the type, + if (sType == 2) + framesntohs(pCtx, &id, pBufRemaining, 1); + else { + id = *pBufRemaining; + } + pBufRemaining += sType; + nBufRemaining -= sType; + // & length, + framesntohs(pCtx, &len, pBufRemaining, 1); + pBufRemaining += sLen; + nBufRemaining -= sLen; + + if ( pTlv && pTlv->pec ) + { + npec = 3U; + if ( 3 > nBufRemaining ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "3 > nBufRemaining\n"); +#endif + + FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length" + "%d, but it has a Private Enterprise Code (3 byte" + "s.\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes" + "of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 3; + nBufRemaining -= 3; + len -= 3; + } +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "Len - %d nBufRemaining - %d\n", len, nBufRemaining); +#endif + + // Whether we found a hit or not, we can validate the reported + // length of this TLV: + if ( len > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %" + "d, but there are only %d bytes remaining in this f" + "rame.\n"), id, len, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL( "We've parsed %d bytes" + " of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + // Now, *if* we found a hit... + if ( pTlv ) + { + if ( nBufRemaining < pTlv->minSize - npec - (sType + sLen)) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are only " + "%d bytes remaining in this frame.\n"), + pTlv->name, pTlv->minSize, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + else if ( len > pTlv->maxSize - npec - (sType + sLen)) + { + FRAMES_LOG1( pCtx, FRLOGW, FRFL("The TLV %s reports " + "an illegally large size; this TLV is presumably" + "corrupt or otherwise invalid & will be skipped " + "ipped.\n"), pTlv->name ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + FRAMES_DBG_BREAK(); + status |= BTAMP_SKIPPED_BAD_TLV; + } + else + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "pTlv->sig - %d\n", pTlv->sig); +#endif + + switch (pTlv->sig) + { + case SigUnpackTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnUnpackTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnUnpackTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnUnpackTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnUnpackTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_PAL_Version* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnUnpackTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvFlow_Spec: + status2 = ( (pfnUnpackTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVFlow_Spec* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Channel_Selected_Event: + status2 = ( (pfnUnpackTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Channel_Selected_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Command_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Command_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Command_Status_Event: + status2 = ( (pfnUnpackTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Command_Status_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnUnpackTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnUnpackTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flush_Cmd: + status2 = ( (pfnUnpackTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flush_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnUnpackTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flush_Occurred_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Hardware_Error_Event: + status2 = ( (pfnUnpackTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Hardware_Error_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnUnpackTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Loopback_Command_Event: + status2 = ( (pfnUnpackTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Loopback_Command_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Qos_Violation_Event: + status2 = ( (pfnUnpackTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Qos_Violation_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Reset_Cmd: + status2 = ( (pfnUnpackTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Reset_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pFrm + pTlv->offset )); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I" + " don't know about the TLV signature %d-- thi" + "s is most likely a 'framesc' bug.\n"), + pTlv->sig); + FRAMES_DBG_BREAK(); + return BTAMP_INTERNAL_ERROR; + } // End switch on sig. + } // End if on length check. + + status |= status2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "status - %x\n", status); +#endif + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d (" + "length %d)\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (sType + sLen), len); + status |= BTAMP_UNKNOWN_TLVS; + } + + // Advance to the next TLV + pBufRemaining += len; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "len - %d nBufRemaining - %d\n", len, nBufRemaining); +#endif + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th" + "e buffer as it was defined to us. This could mean " + "a corrupt frame, or just an incorrect length parame" + "ter.\n")); + FRAMES_DBG_BREAK(); + status |= BTAMP_LAST_TLV_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } // End iteration over TLVs. + +MandatoryCheck: + pTlv = &TLVs[0]; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "pTlv->id - %x\n", pTlv->id); +#endif + + while (0xffff != pTlv->id) + { + if (pTlv->fMandatory) + { + pfFound = (v_U8_t*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory " + "TLV %s wasn't seen.\n"), + pTlv->name); + FRAMES_DBG_BREAK(); + status |= BTAMP_MANDATORY_TLV_MISSING; + } + + } + ++pTlv; + } + + return status; +} /* End UnpacTlvkCore. */ +v_U32_t btampGetPackedTlvAMP_Assoc_Connected_Channel(void * pCtx, tBtampTLVAMP_Assoc_Connected_Channel *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_Connected_Channel\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 3; + if ( pTlv->num_triplets ) + { + *pnNeeded += ( pTlv->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_Connected_Channel_t)(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_Connected_Channel ( 0x003e ) + +v_U32_t btampGetPackedTlvAMP_Assoc_MAC_Addr(void * pCtx, tBtampTLVAMP_Assoc_MAC_Addr *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_MAC_Addr\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 6; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_MAC_Addr_t)(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_MAC_Addr ( 0x003f ) + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Capabilities(void * pCtx, tBtampTLVAMP_Assoc_PAL_Capabilities *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_PAL_Capabilities\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_PAL_Capabilities_t)(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_PAL_Capabilities ( 0x0040 ) + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Version(void * pCtx, tBtampTLVAMP_Assoc_PAL_Version *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_PAL_Version_t)(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_PAL_Version ( 0x0041 ) + +v_U32_t btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, tBtampTLVAMP_Assoc_Preferred_Channel_List *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_Preferred_Channel_List\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 3; + if ( pTlv->num_triplets ) + { + *pnNeeded += ( pTlv->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_Preferred_Channel_List_t)(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_Preferred_Channel_List ( 0x0042 ) + +v_U32_t btampGetPackedTlvFlow_Spec(void * pCtx, tBtampTLVFlow_Spec *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVFlow_Spec. */ + +typedef v_U32_t (*pfnPackSizeTlvFlow_Spec_t)(void *, tBtampTLVFlow_Spec*, v_U32_t*); +#define SigPackSizeTlvFlow_Spec ( 0x0043 ) + +v_U32_t btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Accept_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Accept_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Accept_Logical_Link_Cmd ( 0x0044 ) + +v_U32_t btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Accept_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += pTlv->key_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Accept_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Accept_Physical_Link_Cmd ( 0x0045 ) + +v_U32_t btampGetPackedTlvHCI_Channel_Selected_Event(void * pCtx, tBtampTLVHCI_Channel_Selected_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Channel_Selected_Event_t)(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Channel_Selected_Event ( 0x0046 ) + +v_U32_t btampGetPackedTlvHCI_Command_Complete_Event(void * pCtx, tBtampTLVHCI_Command_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + switch (pTlv->command_opcode) + { + case 3075: + *pnNeeded += 1; + break; + case 3080: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 1083: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 3077: + *pnNeeded += 1; + break; + case 3093: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3094: + *pnNeeded += 1; + break; + case 3126: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 3127: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3169: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3170: + *pnNeeded += 1; + break; + case 3171: + *pnNeeded += 1; + break; + case 3172: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 3; + *pnNeeded += 1; + break; + case 3173: + *pnNeeded += 1; + break; + case 3174: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 3175: + *pnNeeded += 1; + break; + case 3177: + *pnNeeded += 1; + *pnNeeded += 4; + break; + case 3178: + *pnNeeded += 1; + break; + case 3179: + *pnNeeded += 1; + break; + case 4097: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 4098: + *pnNeeded += 1; + *pnNeeded += 64; + break; + case 4101: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 4106: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 5121: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 5122: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 5123: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 5125: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 5129: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 4; + *pnNeeded += 4; + break; + case 5130: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += pTlv->cc_event.Read_Read_Local_AMP_Assoc.remaining_length; + break; + case 5131: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6145: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6146: + *pnNeeded += 1; + break; + } + break; + } + return status; +} /* End btampGetPackedTLVHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Command_Complete_Event_t)(void *, tBtampTLVHCI_Command_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Command_Complete_Event ( 0x0047 ) + +v_U32_t btampGetPackedTlvHCI_Command_Status_Event(void * pCtx, tBtampTLVHCI_Command_Status_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Command_Status_Event_t)(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Command_Status_Event ( 0x0048 ) + +v_U32_t btampGetPackedTlvHCI_Create_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Create_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Create_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Create_Logical_Link_Cmd ( 0x0049 ) + +v_U32_t btampGetPackedTlvHCI_Create_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Create_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += pTlv->key_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Create_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Create_Physical_Link_Cmd ( 0x004a ) + +v_U32_t btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, tBtampTLVHCI_Data_Buffer_Overflow_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Data_Buffer_Overflow_Event_t)(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Data_Buffer_Overflow_Event ( 0x004b ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Logical_Link_Cmd ( 0x004c ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x004d ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Physical_Link_Cmd ( 0x004e ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x004f ) + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, tBtampTLVHCI_Flow_Spec_Modify_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Flow_Spec_Modify_Cmd ( 0x0050 ) + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x0051 ) + +v_U32_t btampGetPackedTlvHCI_Flush_Cmd(void * pCtx, tBtampTLVHCI_Flush_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flush_Cmd_t)(void *, tBtampTLVHCI_Flush_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Flush_Cmd ( 0x0052 ) + +v_U32_t btampGetPackedTlvHCI_Flush_Occurred_Event(void * pCtx, tBtampTLVHCI_Flush_Occurred_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flush_Occurred_Event_t)(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Flush_Occurred_Event ( 0x0053 ) + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Pkts_Event(void * pCtx, tBtampTLVHCI_Num_Completed_Pkts_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +// while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; +#if 0 +// New + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; +// End of New +#endif +// break; + } + return status; +} /* End btampGetPackedTLVHCI_Num_Completed_Pkts_Event. */ + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(void * pCtx, tBtampTLVHCI_Num_Completed_Data_Blocks_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +// while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; +// break; + } + return status; +} /* End btampGetPackedTLVHCI_Num_Completed_Data_Blocks_Event. */ + +//typedef v_U32_t (*pfnPackSizeTlvHCI_Num_Completed_Pkts_Event_t)(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); +//#define SigPackSizeTlvHCI_Num_Completed_Pkts_Event ( 0x0048 ) + +v_U32_t btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 6; + *pnNeeded += 32; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0054 ) + +v_U32_t btampGetPackedTlvHCI_Hardware_Error_Event(void * pCtx, tBtampTLVHCI_Hardware_Error_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Hardware_Error_Event_t)(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Hardware_Error_Event ( 0x0055 ) + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, tBtampTLVHCI_Logical_Link_Cancel_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Logical_Link_Cancel_Cmd ( 0x0056 ) + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Logical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Logical_Link_Complete_Event ( 0x0057 ) + +v_U32_t btampGetPackedTlvHCI_Loopback_Command_Event(void * pCtx, tBtampTLVHCI_Loopback_Command_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 64; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Loopback_Command_Event_t)(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Loopback_Command_Event ( 0x0058 ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Complete_Event ( 0x0059 ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Loss_Warning_Event ( 0x005a ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Recovery_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Recovery_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Recovery_Event_t)(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Recovery_Event ( 0x005b ) + +v_U32_t btampGetPackedTlvHCI_Qos_Violation_Event(void * pCtx, tBtampTLVHCI_Qos_Violation_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Qos_Violation_Event_t)(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Qos_Violation_Event ( 0x005c ) + +v_U32_t btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x005d ) + +v_U32_t btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, tBtampTLVHCI_Read_Buffer_Size_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Buffer_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Buffer_Size_Cmd ( 0x005e ) + +v_U32_t btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x005f ) + +v_U32_t btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, tBtampTLVHCI_Read_Data_Block_Size_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Data_Block_Size_Cmd ( 0x0060 ) + +v_U32_t btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x0061 ) + +v_U32_t btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x0062 ) + +v_U32_t btampGetPackedTlvHCI_Read_Link_Quality_Cmd(void * pCtx, tBtampTLVHCI_Read_Link_Quality_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Link_Quality_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Link_Quality_Cmd ( 0x0063 ) + +v_U32_t btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x0064 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x0065 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_AMP_Information_Cmd ( 0x0066 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x0067 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_Version_Info_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_Version_Info_Cmd ( 0x0068 ) + +v_U32_t btampGetPackedTlvHCI_Read_Location_Data_Cmd(void * pCtx, tBtampTLVHCI_Read_Location_Data_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Location_Data_Cmd ( 0x0069 ) + +v_U32_t btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x006a ) + +v_U32_t btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, tBtampTLVHCI_Read_Loopback_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Loopback_Mode_Cmd ( 0x006b ) + +v_U32_t btampGetPackedTlvHCI_Read_RSSI_Cmd(void * pCtx, tBtampTLVHCI_Read_RSSI_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_RSSI_Cmd_t)(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_RSSI_Cmd ( 0x006c ) + +v_U32_t btampGetPackedTlvHCI_Reset_Cmd(void * pCtx, tBtampTLVHCI_Reset_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Reset_Cmd_t)(void *, tBtampTLVHCI_Reset_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Reset_Cmd ( 0x006d ) + +v_U32_t btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x006e ) + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Cmd(void * pCtx, tBtampTLVHCI_Set_Event_Mask_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 8; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Event_Mask_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Event_Mask_Cmd ( 0x006f ) + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 8; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x0070 ) + +v_U32_t btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Short_Range_Mode_Cmd ( 0x0071 ) + +v_U32_t btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x0072 ) + +v_U32_t btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x0073 ) + +v_U32_t btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x0074 ) + +v_U32_t btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x0075 ) + +v_U32_t btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x0076 ) + +v_U32_t btampGetPackedTlvHCI_Write_Location_Data_Cmd(void * pCtx, tBtampTLVHCI_Write_Location_Data_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 3; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Location_Data_Cmd ( 0x0077 ) + +v_U32_t btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x0078 ) + +v_U32_t btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, tBtampTLVHCI_Write_Loopback_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Loopback_Mode_Cmd ( 0x0079 ) + +v_U32_t btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += pTlv->amp_assoc_remaining_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x007a ) + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Cmd(void * pCtx, tBtampTLVHCI_Enhanced_Flush_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Enhanced_Flush_Cmd_t)(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Enhanced_Flush_Cmd ( 0x007b ) + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, tBtampTLVHCI_Enhanced_Flush_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Enhanced_Flush_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Enhanced_Flush_Complete_Event ( 0x007c ) + +v_U32_t btampGetPackedAMP_ASSOCSize(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U32_t *pnNeeded) +{ + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigPackSizeTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigPackSizeTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigPackSizeTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigPackSizeTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigPackSizeTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t status = 0; + *pnNeeded = 0; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedAMP_ASSOCSize\n"); +#endif + + status |= GetPackedSizeTlvCore(pCtx,(v_U8_t*)pFrm,pnNeeded,TLVS); + return status; +} /* End btampGetPackedAMP_ASSOCSize. */ + +static v_U32_t GetPackedSizeTlvCore(void * pCtx, + v_U8_t *pFrm, + v_U32_t *pnNeeded, + tTLVDefn TLVs[]) +{ + tTLVDefn *pTlv; + v_U32_t status, status2; + tFRAMES_BOOL *pfFound; + + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In GetPackedSizeTlvCore\n"); +#endif + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound ) + { + *pnNeeded += 4U; + if ( pTlv->pec ) *pnNeeded += 3U; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In GetPackedSizeTlvCore, pTlv->sig - %d\n", pTlv->sig); +#endif + + switch (pTlv->sig) + { + case SigPackSizeTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnPackSizeTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnPackSizeTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnPackSizeTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnPackSizeTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Version* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnPackSizeTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvFlow_Spec: + status2 = ( (pfnPackSizeTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, ( tBtampTLVFlow_Spec* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Channel_Selected_Event: + status2 = ( (pfnPackSizeTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Channel_Selected_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Command_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Command_Status_Event: + status2 = ( (pfnPackSizeTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Status_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnPackSizeTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flush_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnPackSizeTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Occurred_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Hardware_Error_Event: + status2 = ( (pfnPackSizeTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Hardware_Error_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Loopback_Command_Event: + status2 = ( (pfnPackSizeTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Loopback_Command_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Qos_Violation_Event: + status2 = ( (pfnPackSizeTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Qos_Violation_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Reset_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the TLV signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pTlv->sig); + return BTAMP_INTERNAL_ERROR; + } + } + ++pTlv; + } + return status; +} +v_U32_t btampPackTlvAMP_Assoc_Connected_Channel(void * pCtx, + tBtampTLVAMP_Assoc_Connected_Channel *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_Connected_Channel\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_Connected_Channel(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3, 0); + else *pBuf = 3; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + if ( pSrc->num_triplets ) { + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + pBuf += ( ( pSrc->num_triplets * 3 ) ); + nBuf -= ( ( pSrc->num_triplets * 3 ) ); + } + else break; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } + else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_Connected_Channel_t)(void *, tBtampTLVAMP_Assoc_Connected_Channel *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_Connected_Channel ( 0x007b ) + +v_U32_t btampPackTlvAMP_Assoc_MAC_Addr(void * pCtx, + tBtampTLVAMP_Assoc_MAC_Addr *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_MAC_Addr\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_MAC_Addr(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1, 0); + else *pBuf = 1; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->mac_addr, 6); + *pnConsumed += 6; + pBuf += 6; + nBuf -= 6; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_MAC_Addr_t)(void *, tBtampTLVAMP_Assoc_MAC_Addr *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_MAC_Addr ( 0x007c ) + +v_U32_t btampPackTlvAMP_Assoc_PAL_Capabilities(void * pCtx, + tBtampTLVAMP_Assoc_PAL_Capabilities *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_PAL_Capabilities\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_PAL_Capabilities(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4, 0); + else *pBuf = 4; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtonl(pCtx, pBuf, pSrc->pal_capabilities, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_PAL_Capabilities_t)(void *, tBtampTLVAMP_Assoc_PAL_Capabilities *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_PAL_Capabilities ( 0x007d ) + +v_U32_t btampPackTlvAMP_Assoc_PAL_Version(void * pCtx, + tBtampTLVAMP_Assoc_PAL_Version *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_PAL_Version\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_PAL_Version(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5, 0); + else *pBuf = 5; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->pal_version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->pal_CompanyID, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->pal_subversion, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_PAL_Version_t)(void *, tBtampTLVAMP_Assoc_PAL_Version *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_PAL_Version ( 0x007e ) + +v_U32_t btampPackTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, + tBtampTLVAMP_Assoc_Preferred_Channel_List *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_Preferred_Channel_List\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 2, 0); + else *pBuf = 2; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + if ( pSrc->num_triplets ) { + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + pBuf += ( ( pSrc->num_triplets * 3 ) ); + nBuf -= ( ( pSrc->num_triplets * 3 ) ); + } + else break; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_Preferred_Channel_List_t)(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_Preferred_Channel_List ( 0x007f ) + +v_U32_t btampPackTlvFlow_Spec(void * pCtx, + tBtampTLVFlow_Spec *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvFlow_Spec(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6, 0); + else *pBuf = 6; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->service_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->max_sdu, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->sdu_inter_arrival, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->access_latency, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvFlow_Spec. */ + +typedef v_U32_t (*pfnPackTlvFlow_Spec_t)(void *, tBtampTLVFlow_Spec *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvFlow_Spec ( 0x0080 ) + +v_U32_t btampPackTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1081, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Accept_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Accept_Logical_Link_Cmd ( 0x0081 ) + +v_U32_t btampPackTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1078, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->key_material ), pSrc->key_length); + *pnConsumed += pSrc->key_length; + pBuf += ( pSrc->key_length ); + nBuf -= ( pSrc->key_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Accept_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Accept_Physical_Link_Cmd ( 0x0082 ) + +v_U32_t btampPackTlvHCI_Channel_Selected_Event(void * pCtx, + tBtampTLVHCI_Channel_Selected_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Channel_Selected_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 65, 0); + else *pBuf = 65; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Channel_Selected_Event_t)(void *, tBtampTLVHCI_Channel_Selected_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Channel_Selected_Event ( 0x0083 ) + +v_U32_t btampPackTlvHCI_Command_Complete_Event(void * pCtx, + tBtampTLVHCI_Command_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Command_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 14, 0); + else *pBuf = 14; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->num_hci_command_packets; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->command_opcode, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + switch (pSrc->command_opcode) + { + case 3075: + *pBuf = pSrc->cc_event.Reset.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3080: + *pBuf = pSrc->cc_event.Flush.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Flush.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 1083: + *pBuf = pSrc->cc_event.Logical_Link_Cancel.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Logical_Link_Cancel.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Logical_Link_Cancel.tx_flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3077: + *pBuf = pSrc->cc_event.Set_Event_Mask.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3093: + *pBuf = pSrc->cc_event.Read_Connection_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Connection_Accept_TO.connection_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3094: + *pBuf = pSrc->cc_event.Write_Connection_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3126: + *pBuf = pSrc->cc_event.Read_Link_Supervision_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Supervision_TO.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Supervision_TO.link_supervision_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3127: + *pBuf = pSrc->cc_event.Write_Link_Supervision_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Write_Link_Supervision_TO.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3169: + *pBuf = pSrc->cc_event.Read_Logical_Link_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3170: + *pBuf = pSrc->cc_event.Write_Logical_Link_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3171: + *pBuf = pSrc->cc_event.Set_Event_Mask_Page_2.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3172: + *pBuf = pSrc->cc_event.Read_Location_Data.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Location_Data.loc_domain_aware; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->cc_event.Read_Location_Data.loc_domain, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + *pBuf = pSrc->cc_event.Read_Location_Data.loc_options; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3173: + *pBuf = pSrc->cc_event.Write_Location_Data.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3174: + *pBuf = pSrc->cc_event.Read_Flow_Control_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Flow_Control_Mode.flow_control_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3175: + *pBuf = pSrc->cc_event.Write_Flow_Control_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3177: + *pBuf = pSrc->cc_event.Read_BE_Flush_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_BE_Flush_TO.best_effort_flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + case 3178: + *pBuf = pSrc->cc_event.Write_BE_Flush_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3179: + *pBuf = pSrc->cc_event.Set_Short_Range_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 4097: + *pBuf = pSrc->cc_event.Read_Local_Version_Info.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Local_Version_Info.HC_HCI_Version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_HCI_Revision, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Local_Version_Info.HC_PAL_Version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_Manufac_Name, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 4098: + *pBuf = pSrc->cc_event.Read_Local_Supported_Cmds.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, 64); + *pnConsumed += 64; + pBuf += 64; + nBuf -= 64; + break; + case 4101: + *pBuf = pSrc->cc_event.Read_Buffer_Size.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Buffer_Size.HC_SCO_Packet_Length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 4106: + *pBuf = pSrc->cc_event.Read_Data_Block_Size.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Data_Block_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5121: + *pBuf = pSrc->cc_event.Read_Failed_Contact_Counter.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Failed_Contact_Counter.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Failed_Contact_Counter.failed_contact_counter, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5122: + *pBuf = pSrc->cc_event.Reset_Failed_Contact_Counter.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Reset_Failed_Contact_Counter.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5123: + *pBuf = pSrc->cc_event.Read_Link_Quality.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Quality.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Link_Quality.link_quality; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 5125: + *pBuf = pSrc->cc_event.Read_RSSI.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_RSSI.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_RSSI.rssi; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 5129: + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.HC_AMP_Status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Total_BW, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Min_Latency, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.HC_Controller_Type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + case 5130: + *pBuf = pSrc->cc_event.Read_Read_Local_AMP_Assoc.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment ), pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length); + *pnConsumed += pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length; + pBuf += ( pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + nBuf -= ( pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + break; + case 5131: + *pBuf = pSrc->cc_event.Write_Remote_AMP_Assoc.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Write_Remote_AMP_Assoc.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 6145: + *pBuf = pSrc->cc_event.Read_Loopback_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Loopback_Mode.loopback_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 6146: + *pBuf = pSrc->cc_event.Write_Loopback_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Command_Complete_Event_t)(void *, tBtampTLVHCI_Command_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Command_Complete_Event ( 0x0084 ) + +v_U32_t btampPackTlvHCI_Command_Status_Event(void * pCtx, + tBtampTLVHCI_Command_Status_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Command_Status_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 15, 0); + else *pBuf = 15; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->num_hci_command_packets; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->command_opcode, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Command_Status_Event_t)(void *, tBtampTLVHCI_Command_Status_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Command_Status_Event ( 0x0085 ) + +v_U32_t btampPackTlvHCI_Create_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Create_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + status = btampGetPackedTlvHCI_Create_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1080, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Create_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Create_Logical_Link_Cmd ( 0x0086 ) + +v_U32_t btampPackTlvHCI_Create_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Create_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Create_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1077, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->key_material ), pSrc->key_length); + *pnConsumed += pSrc->key_length; + pBuf += ( pSrc->key_length ); + nBuf -= ( pSrc->key_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Create_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Create_Physical_Link_Cmd ( 0x0087 ) + +v_U32_t btampPackTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, + tBtampTLVHCI_Data_Buffer_Overflow_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 26, 0); + else *pBuf = 26; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->link_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Data_Buffer_Overflow_Event_t)(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Data_Buffer_Overflow_Event ( 0x0088 ) + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1082, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Logical_Link_Cmd ( 0x0089 ) + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 70, 0); + else *pBuf = 70; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x008a ) + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1079, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Physical_Link_Cmd ( 0x008b ) + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 66, 0); + else *pBuf = 66; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x008c ) + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1084, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->be_aggr_counter; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flow_Spec_Modify_Cmd ( 0x008d ) + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, + tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 71, 0); + else *pBuf = 71; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x008e ) + +v_U32_t btampPackTlvHCI_Flush_Cmd(void * pCtx, + tBtampTLVHCI_Flush_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flush_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3080, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flush_Cmd_t)(void *, tBtampTLVHCI_Flush_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flush_Cmd ( 0x008f ) + +v_U32_t btampPackTlvHCI_Flush_Occurred_Event(void * pCtx, + tBtampTLVHCI_Flush_Occurred_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flush_Occurred_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 17, 0); + else *pBuf = 17; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flush_Occurred_Event_t)(void *, tBtampTLVHCI_Flush_Occurred_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flush_Occurred_Event ( 0x0090 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Pkts_Event(void * pCtx, + tBtampTLVHCI_Num_Completed_Pkts_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Num_Completed_Pkts_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; +// while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 19, 0); + else *pBuf = 19; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->num_handles; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->conn_handles[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_pkts[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +#if 0 + // New + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +// End of new +#endif +// break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Num_Completed_Pkts_Event. */ + +v_U32_t btampPackTlvHCI_Num_Completed_Data_Blocks_Event(void * pCtx, + tBtampTLVHCI_Num_Completed_Data_Blocks_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; +// while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 72, 0); + else *pBuf = 72; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->total_num_data_blocks, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->num_handles; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->conn_handles[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_pkts[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_blocks[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +#if 0 + // New + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +// End of new +#endif +// break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Num_Completed_Data_Blocks_Event. */ + +//typedef v_U32_t (*pfnPackTlvHCI_Num_Completed_Pkts_Event_t)(void *, tBtampTLVHCI_Num_Completed_Pkts_Event *, v_U8_t*, v_U32_t, v_U32_t*); +//#define SigPackTlvHCI_Num_Completed_Pkts_Event ( 0x0085 ) + +v_U32_t btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, + tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 62, 0); + else *pBuf = 62; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->bd_addr, 6); + *pnConsumed += 6; + pBuf += 6; + nBuf -= 6; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->generic_amp_link_key, 32); + *pnConsumed += 32; + pBuf += 32; + nBuf -= 32; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0091 ) + +v_U32_t btampPackTlvHCI_Hardware_Error_Event(void * pCtx, + tBtampTLVHCI_Hardware_Error_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Hardware_Error_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 16, 0); + else *pBuf = 16; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->hardware_code; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Hardware_Error_Event_t)(void *, tBtampTLVHCI_Hardware_Error_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Hardware_Error_Event ( 0x0092 ) + +v_U32_t btampPackTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1083, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->tx_flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Logical_Link_Cancel_Cmd ( 0x0093 ) + +v_U32_t btampPackTlvHCI_Logical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Logical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Logical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 69, 0); + else *pBuf = 69; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Logical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Logical_Link_Complete_Event ( 0x0094 ) + +v_U32_t btampPackTlvHCI_Loopback_Command_Event(void * pCtx, + tBtampTLVHCI_Loopback_Command_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Loopback_Command_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 25, 0); + else *pBuf = 25; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->hci_command_packet, 64); + *pnConsumed += 64; + pBuf += 64; + nBuf -= 64; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Loopback_Command_Event_t)(void *, tBtampTLVHCI_Loopback_Command_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Loopback_Command_Event ( 0x0095 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 64, 0); + else *pBuf = 64; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Physical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Complete_Event ( 0x0096 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 67, 0); + else *pBuf = 67; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Loss_Warning_Event ( 0x0097 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Recovery_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Recovery_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Recovery_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 68, 0); + else *pBuf = 68; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Recovery_Event_t)(void *, tBtampTLVHCI_Physical_Link_Recovery_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Recovery_Event ( 0x0098 ) + +v_U32_t btampPackTlvHCI_Qos_Violation_Event(void * pCtx, + tBtampTLVHCI_Qos_Violation_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Qos_Violation_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 30, 0); + else *pBuf = 30; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Qos_Violation_Event_t)(void *, tBtampTLVHCI_Qos_Violation_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Qos_Violation_Event ( 0x0099 ) + +v_U32_t btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3177, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x009a ) + +v_U32_t btampPackTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, + tBtampTLVHCI_Read_Buffer_Size_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4101, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Buffer_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Buffer_Size_Cmd ( 0x009b ) + +v_U32_t btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3093, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x009c ) + +v_U32_t btampPackTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, + tBtampTLVHCI_Read_Data_Block_Size_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4106, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Data_Block_Size_Cmd ( 0x009d ) + +v_U32_t btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5121, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x009e ) + +v_U32_t btampPackTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3174, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x009f ) + +v_U32_t btampPackTlvHCI_Read_Link_Quality_Cmd(void * pCtx, + tBtampTLVHCI_Read_Link_Quality_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Link_Quality_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5123, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Link_Quality_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Quality_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Link_Quality_Cmd ( 0x00a0 ) + +v_U32_t btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3126, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x00a1 ) + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5130, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->length_so_far, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->max_remote_amp_assoc_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x00a2 ) + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5129, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_AMP_Information_Cmd ( 0x00a3 ) + +v_U32_t btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4098, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x00a4 ) + +v_U32_t btampPackTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_Version_Info_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4097, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_Version_Info_Cmd ( 0x00a5 ) + +v_U32_t btampPackTlvHCI_Read_Location_Data_Cmd(void * pCtx, + tBtampTLVHCI_Read_Location_Data_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Location_Data_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3172, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Read_Location_Data_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Location_Data_Cmd ( 0x00a6 ) + +v_U32_t btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3169, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x00a7 ) + +v_U32_t btampPackTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6145, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Loopback_Mode_Cmd ( 0x00a8 ) + +v_U32_t btampPackTlvHCI_Read_RSSI_Cmd(void * pCtx, + tBtampTLVHCI_Read_RSSI_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_RSSI_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5125, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_RSSI_Cmd_t)(void *, tBtampTLVHCI_Read_RSSI_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_RSSI_Cmd ( 0x00a9 ) + +v_U32_t btampPackTlvHCI_Reset_Cmd(void * pCtx, + tBtampTLVHCI_Reset_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Reset_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3075, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Reset_Cmd_t)(void *, tBtampTLVHCI_Reset_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Reset_Cmd ( 0x00aa ) + +v_U32_t btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5122, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x00ab ) + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Cmd(void * pCtx, + tBtampTLVHCI_Set_Event_Mask_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Event_Mask_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3077, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->event_mask, 8); + *pnConsumed += 8; + pBuf += 8; + nBuf -= 8; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Event_Mask_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Event_Mask_Cmd ( 0x00ac ) + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3171, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->event_mask_page_2, 8); + *pnConsumed += 8; + pBuf += 8; + nBuf -= 8; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x00ad ) + +v_U32_t btampPackTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3179, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->short_range_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Short_Range_Mode_Cmd ( 0x00ae ) + +v_U32_t btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, + tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 76, 0); + else *pBuf = 76; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->short_range_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x00af ) + +v_U32_t btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3178, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->best_effort_flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x00b0 ) + +v_U32_t btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3094, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->connection_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x00b1 ) + +v_U32_t btampPackTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3175, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->flow_control_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x00b2 ) + +v_U32_t btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3127, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->link_supervision_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x00b3 ) + +v_U32_t btampPackTlvHCI_Write_Location_Data_Cmd(void * pCtx, + tBtampTLVHCI_Write_Location_Data_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Location_Data_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3173, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->loc_domain_aware; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->loc_domain, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + *pBuf = pSrc->loc_options; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Write_Location_Data_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Location_Data_Cmd ( 0x00b4 ) + +v_U32_t btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3170, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->logical_link_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x00b5 ) + +v_U32_t btampPackTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6146, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->loopback_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Loopback_Mode_Cmd ( 0x00b6 ) + +v_U32_t btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5131, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->length_so_far, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->amp_assoc_remaining_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->amp_assoc_fragment ), pSrc->amp_assoc_remaining_length); + *pnConsumed += pSrc->amp_assoc_remaining_length; + pBuf += ( pSrc->amp_assoc_remaining_length ); + nBuf -= ( pSrc->amp_assoc_remaining_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x00b7 ) + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Cmd(void * pCtx, + tBtampTLVHCI_Enhanced_Flush_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Enhanced_Flush_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3167, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->packet_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Enhanced_Flush_Cmd_t)(void *, tBtampTLVHCI_Enhanced_Flush_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Enhanced_Flush_Cmd ( 0x00b8 ) + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, + tBtampTLVHCI_Enhanced_Flush_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 57, 0); + else *pBuf = 57; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Enhanced_Flush_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Enhanced_Flush_Complete_Event ( 0x00b9 ) + +v_U32_t btampPackAMP_ASSOC(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U8_t *pBuf, v_U32_t nBuf, v_U32_t *pnConsumed) +{ + v_U32_t i; + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigPackTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampPackTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigPackTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampPackTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigPackTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampPackTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigPackTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampPackTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigPackTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampPackTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t idx = 0; + v_U32_t status = 0; + (void)i; + *pnConsumed = 0U; + status |= PackTlvCore(pCtx,(v_U8_t*)pFrm,pBuf,nBuf,pnConsumed,TLVS,&idx); + +# ifdef BTAMP_DUMP_FRAMES + if (!BTAMP_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Packed the AMP_ASSOC:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_MAC_Addr:\n")); + if (!pFrm->AMP_Assoc_MAC_Addr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_MAC_Addr.mac_addr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Preferred_Channel_List:\n")); + if (!pFrm->AMP_Assoc_Preferred_Channel_List.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Preferred_Channel_List.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Preferred_Channel_List.triplets, 3 * pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Connected_Channel:\n")); + if (!pFrm->AMP_Assoc_Connected_Channel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Connected_Channel.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Connected_Channel.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Connected_Channel.triplets, 3 * pFrm->AMP_Assoc_Connected_Channel.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Capabilities:\n")); + if (!pFrm->AMP_Assoc_PAL_Capabilities.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Capabilities.pal_capabilities, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Version:\n")); + if (!pFrm->AMP_Assoc_PAL_Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_CompanyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_subversion, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), pBuf, nBuf); + } +# endif // BTAMP_DUMP_FRAMES + return status; + +} /* End btampUnpackAMP_ASSOC. */ + + +static v_U32_t PackTlvCore(void * pCtx, + v_U8_t *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed, + tTLVDefn TLVs[], + v_U32_t *pidx) +{ + tTLVDefn *pTlv; + tFRAMES_BOOL *pfFound; + v_U8_t *pBufRemaining; + v_U32_t nBufRemaining, status, status2, len; + + BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + (void)pCtx; + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound && pTlv->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least" + " %d bytes, but there are only %d left in the buffer." + "\n"), pTlv->name, pTlv->minSize, nBufRemaining); + return BTAMP_BUFFER_OVERFLOW; + } + + len = 0U; + + if ( *pfFound ) { + switch ( pTlv->sig ) + { + case SigPackTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnPackTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnPackTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnPackTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnPackTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Version* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnPackTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvFlow_Spec: + status2 = ( (pfnPackTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, ( tBtampTLVFlow_Spec* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Channel_Selected_Event: + status2 = ( (pfnPackTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Channel_Selected_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Command_Complete_Event: + status2 = ( (pfnPackTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Command_Status_Event: + status2 = ( (pfnPackTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Status_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnPackTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnPackTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnPackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flush_Cmd: + status2 = ( (pfnPackTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnPackTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Occurred_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnPackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Hardware_Error_Event: + status2 = ( (pfnPackTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Hardware_Error_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnPackTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Loopback_Command_Event: + status2 = ( (pfnPackTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Loopback_Command_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Qos_Violation_Event: + status2 = ( (pfnPackTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Qos_Violation_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnPackTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Reset_Cmd: + status2 = ( (pfnPackTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnPackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't " + "know about the TLV %d; this is most likely a bug in " + "'framesc'.\n"), pTlv->sig); + return BTAMP_INTERNAL_ERROR; + } + + } /* End if on *pfFound */ + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + ++pTlv; + if(len) ++*pidx; + } + + return status; + +} diff --git a/drivers/staging/qcacld-2.0/CORE/BAP/src/fsmDefs.h b/drivers/staging/qcacld-2.0/CORE/BAP/src/fsmDefs.h new file mode 100644 index 0000000000000..8705a98c328c4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/BAP/src/fsmDefs.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +// Project/System dependant defines and typedefs + +#ifndef __FSMDEFS_H__ +#define __FSMDEFS_H__ + +/* Temporary fix until I clean up all the type names */ +#define BTAMPFSM_INSTANCEDATA_T tWLAN_BAPbapPhysLinkMachine + +typedef unsigned char BTAMPFSM_ENTRY_FLAG_T; +typedef unsigned char BTAMPFSM_STATEVAR_T; +typedef unsigned char BTAMPFSM_INST_ID_T; +typedef unsigned char BTAMPFSM_EVENT_T; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.c new file mode 100644 index 0000000000000..c3b4caee3d7d3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.c @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt.c + * @brief Provide functions to create+init and destroy a HTT instance. + * @details + * This file contains functions for creating a HTT instance; initializing + * the HTT instance, e.g. by allocating a pool of HTT tx descriptors and + * connecting the HTT service with HTC; and deleting a HTT instance. + */ + +#include /* adf_os_mem_alloc */ +#include /* adf_os_device_t, adf_os_print */ + +#include /* htt_tx_msdu_desc_t */ +#include +#include /* ol_tx_dowload_done_ll, etc. */ +#include + +#include +#if defined(HIF_PCI) +#include "if_pci.h" +#endif + +#define HTT_HTC_PKT_POOL_INIT_SIZE 100 /* enough for a large A-MPDU */ + +A_STATUS +htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev); + +A_STATUS +htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev); + +A_STATUS (*htt_h2t_rx_ring_cfg_msg)( + struct htt_pdev_t *pdev); + +#ifdef IPA_UC_OFFLOAD +A_STATUS +htt_ipa_config(htt_pdev_handle pdev, A_STATUS status) +{ + if ((A_OK == status) && + ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev)) { + status = htt_h2t_ipa_uc_rsc_cfg_msg(pdev); + } + return status; +} + +#define HTT_IPA_CONFIG htt_ipa_config +#else +#define HTT_IPA_CONFIG(pdev, status) status /* no-op */ +#endif /* IPA_UC_OFFLOAD */ + + +struct htt_htc_pkt * +htt_htc_pkt_alloc(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt_union *pkt = NULL; + + HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex); + if (pdev->htt_htc_pkt_freelist) { + pkt = pdev->htt_htc_pkt_freelist; + pdev->htt_htc_pkt_freelist = pdev->htt_htc_pkt_freelist->u.next; + } + HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex); + + if (pkt == NULL) { + pkt = adf_os_mem_alloc(pdev->osdev, sizeof(*pkt)); + } + return &pkt->u.pkt; /* not actually a dereference */ +} + +void +htt_htc_pkt_free(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt) +{ + struct htt_htc_pkt_union *u_pkt = (struct htt_htc_pkt_union *) pkt; + + HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex); + u_pkt->u.next = pdev->htt_htc_pkt_freelist; + pdev->htt_htc_pkt_freelist = u_pkt; + HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex); +} + +void +htt_htc_pkt_pool_free(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt_union *pkt, *next; + pkt = pdev->htt_htc_pkt_freelist; + while (pkt) { + next = pkt->u.next; + adf_os_mem_free(pkt); + pkt = next; + } + pdev->htt_htc_pkt_freelist = NULL; +} + +#ifdef ATH_11AC_TXCOMPACT +void +htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt) +{ + struct htt_htc_pkt_union *u_pkt = (struct htt_htc_pkt_union *) pkt; + + HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex); + if (pdev->htt_htc_pkt_misclist) { + u_pkt->u.next = pdev->htt_htc_pkt_misclist; + pdev->htt_htc_pkt_misclist = u_pkt; + } else { + pdev->htt_htc_pkt_misclist = u_pkt; + } + HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex); +} + +void +htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt_union *pkt, *next; + adf_nbuf_t netbuf; + pkt = pdev->htt_htc_pkt_misclist; + + while (pkt) { + next = pkt->u.next; + netbuf = (adf_nbuf_t)(pkt->u.pkt.htc_pkt.pNetBufContext); + adf_nbuf_unmap(pdev->osdev, netbuf, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(netbuf); + adf_os_mem_free(pkt); + pkt = next; + } + pdev->htt_htc_pkt_misclist = NULL; +} +#endif + +/*---*/ + +htt_pdev_handle +htt_attach( + ol_txrx_pdev_handle txrx_pdev, + ol_pdev_handle ctrl_pdev, + HTC_HANDLE htc_pdev, + adf_os_device_t osdev, + int desc_pool_size) +{ + struct htt_pdev_t *pdev; + int i; + + pdev = adf_os_mem_alloc(osdev, sizeof(*pdev)); + + if (!pdev) { + goto fail1; + } + + pdev->osdev = osdev; + pdev->ctrl_pdev = ctrl_pdev; + pdev->txrx_pdev = txrx_pdev; + pdev->htc_pdev = htc_pdev; + + adf_os_mem_set(&pdev->stats, 0, sizeof(pdev->stats)); + pdev->htt_htc_pkt_freelist = NULL; +#ifdef ATH_11AC_TXCOMPACT + pdev->htt_htc_pkt_misclist = NULL; +#endif + + /* for efficiency, store a local copy of the is_high_latency flag */ + pdev->cfg.is_high_latency = ol_cfg_is_high_latency(pdev->ctrl_pdev); + pdev->cfg.default_tx_comp_req = + !ol_cfg_tx_free_at_download(pdev->ctrl_pdev); + + pdev->cfg.is_full_reorder_offload = + ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev); + adf_os_print("is_full_reorder_offloaded? %d\n", + (int)pdev->cfg.is_full_reorder_offload); + pdev->targetdef = htc_get_targetdef(htc_pdev); + /* + * Connect to HTC service. + * This has to be done before calling htt_rx_attach, + * since htt_rx_attach involves sending a rx ring configure + * message to the target. + */ +//AR6004 don't need HTT layer. +#ifndef AR6004_HW + if (htt_htc_attach(pdev)) { + goto fail2; + } +#endif + if (htt_tx_attach(pdev, desc_pool_size)) { + goto fail2; + } + + if (htt_rx_attach(pdev)) { + goto fail3; + } + + HTT_TX_MUTEX_INIT(&pdev->htt_tx_mutex); + HTT_TX_NBUF_QUEUE_MUTEX_INIT(pdev); + + /* pre-allocate some HTC_PACKET objects */ + for (i = 0; i < HTT_HTC_PKT_POOL_INIT_SIZE; i++) { + struct htt_htc_pkt_union *pkt; + pkt = adf_os_mem_alloc(pdev->osdev, sizeof(*pkt)); + if (! pkt) { + break; + } + htt_htc_pkt_free(pdev, &pkt->u.pkt); + } + + if (pdev->cfg.is_high_latency) { + /* + * HL - download the whole frame. + * Specify a download length greater than the max MSDU size, + * so the downloads will be limited by the actual frame sizes. + */ + pdev->download_len = 5000; + if (ol_cfg_tx_free_at_download(pdev->ctrl_pdev)) { + pdev->tx_send_complete_part2 = ol_tx_download_done_hl_free; + } else { + pdev->tx_send_complete_part2 = ol_tx_download_done_hl_retain; + } + + /* + * For LL, the FW rx desc directly referenced at its location + * inside the rx indication message. + */ +/* + * CHECK THIS LATER: does the HL HTT version of htt_rx_mpdu_desc_list_next + * (which is not currently implemented) present the adf_nbuf_data(rx_ind_msg) + * as the abstract rx descriptor? + * If not, the rx_fw_desc_offset initialization here will have to be + * adjusted accordingly. + * NOTE: for HL, because fw rx desc is in ind msg, not in rx desc, so the + * offset should be negtive value + */ + pdev->rx_fw_desc_offset = + HTT_ENDIAN_BYTE_IDX_SWAP( + HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET + - HTT_RX_IND_HL_BYTES); + + htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_hl; + + /* initialize the txrx credit count */ + ol_tx_target_credit_update( + pdev->txrx_pdev, ol_cfg_target_tx_credit(ctrl_pdev)); + } else { + /* + * LL - download just the initial portion of the frame. + * Download enough to cover the encapsulation headers checked + * by the target's tx classification descriptor engine. + */ + enum wlan_frm_fmt frm_type; + + /* account for the 802.3 or 802.11 header */ + frm_type = ol_cfg_frame_type(pdev->ctrl_pdev); + if (frm_type == wlan_frm_fmt_native_wifi) { + pdev->download_len = HTT_TX_HDR_SIZE_NATIVE_WIFI; + } else if (frm_type == wlan_frm_fmt_802_3) { + pdev->download_len = HTT_TX_HDR_SIZE_ETHERNET; + } else { + adf_os_print("Unexpected frame type spec: %d\n", frm_type); + HTT_ASSERT0(0); + } + /* + * Account for the optional L2 / ethernet header fields: + * 802.1Q, LLC/SNAP + */ + pdev->download_len += + HTT_TX_HDR_SIZE_802_1Q + HTT_TX_HDR_SIZE_LLC_SNAP; + + /* + * Account for the portion of the L3 (IP) payload that the + * target needs for its tx classification. + */ + pdev->download_len += ol_cfg_tx_download_size(pdev->ctrl_pdev); + + /* + * Account for the HTT tx descriptor, including the + * HTC header + alignment padding. + */ + pdev->download_len += sizeof(struct htt_host_tx_desc_t); + + /* + * The TXCOMPACT htt_tx_sched function uses pdev->download_len + * to apply for all requeued tx frames. Thus, pdev->download_len + * has to be the largest download length of any tx frame that will + * be downloaded. + * This maximum download length is for management tx frames, + * which have an 802.11 header. + */ + #ifdef ATH_11AC_TXCOMPACT + pdev->download_len = + sizeof(struct htt_host_tx_desc_t) + + HTT_TX_HDR_SIZE_OUTER_HDR_MAX + /* worst case */ + HTT_TX_HDR_SIZE_802_1Q + + HTT_TX_HDR_SIZE_LLC_SNAP + + ol_cfg_tx_download_size(pdev->ctrl_pdev); + #endif + pdev->tx_send_complete_part2 = ol_tx_download_done_ll; + + /* + * For LL, the FW rx desc is alongside the HW rx desc fields in + * the htt_host_rx_desc_base struct/. + */ + pdev->rx_fw_desc_offset = RX_STD_DESC_FW_MSDU_OFFSET; + + htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_ll; + } + + return pdev; + +fail3: + htt_tx_detach(pdev); + +fail2: + adf_os_mem_free(pdev); + +fail1: + return NULL; +} + +A_STATUS +htt_attach_target(htt_pdev_handle pdev) +{ + A_STATUS status; + status = htt_h2t_ver_req_msg(pdev); + if (status != A_OK) { + return status; + } + /* + * If applicable, send the rx ring config message to the target. + * The host could wait for the HTT version number confirmation message + * from the target before sending any further HTT messages, but it's + * reasonable to assume that the host and target HTT version numbers + * match, and proceed immediately with the remaining configuration + * handshaking. + */ + + status = htt_h2t_rx_ring_cfg_msg(pdev); + status = HTT_IPA_CONFIG(pdev, status); + + return status; +} + +void +htt_detach(htt_pdev_handle pdev) +{ + htt_rx_detach(pdev); + htt_tx_detach(pdev); + htt_htc_pkt_pool_free(pdev); +#ifdef ATH_11AC_TXCOMPACT + htt_htc_misc_pkt_pool_free(pdev); +#endif + HTT_TX_MUTEX_DESTROY(&pdev->htt_tx_mutex); + HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(pdev); + adf_os_mem_free(pdev); +} + +void +htt_detach_target(htt_pdev_handle pdev) +{ +} + +int +htt_htc_attach(struct htt_pdev_t *pdev) +{ + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP response; + A_STATUS status; + + adf_os_mem_set(&connect, 0, sizeof(connect)); + adf_os_mem_set(&response, 0, sizeof(response)); + + connect.pMetaData = NULL; + connect.MetaDataLength = 0; + connect.EpCallbacks.pContext = pdev; + connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete; + connect.EpCallbacks.EpTxCompleteMultiple = NULL; + connect.EpCallbacks.EpRecv = htt_t2h_msg_handler; + + /* rx buffers currently are provided by HIF, not by EpRecvRefill */ + connect.EpCallbacks.EpRecvRefill = NULL; + connect.EpCallbacks.RecvRefillWaterMark = 1; /* N/A, fill is done by HIF */ + + connect.EpCallbacks.EpSendFull = htt_h2t_full; + /* + * Specify how deep to let a queue get before HTCSendPkt will + * call the EpSendFull function due to excessive send queue depth. + */ + connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH; + + /* disable flow control for HTT data message service */ +#ifndef HIF_SDIO + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; +#endif + + /* connect to control service */ + connect.ServiceID = HTT_DATA_MSG_SVC; + + status = HTCConnectService(pdev->htc_pdev, &connect, &response); + + if (status != A_OK) { + return 1; /* failure */ + } + pdev->htc_endpoint = response.Endpoint; +#if defined(HIF_PCI) + hif_pci_save_htc_htt_config_endpoint(pdev->htc_endpoint); +#endif + +#ifdef QCA_TX_HTT2_SUPPORT + /* Start TX HTT2 service if the target support it. */ + if (pdev->cfg.is_high_latency) { + adf_os_mem_set(&connect, 0, sizeof(connect)); + adf_os_mem_set(&response, 0, sizeof(response)); + + /* The same as HTT service but no RX. */ + connect.EpCallbacks.pContext = pdev; + connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete; + connect.EpCallbacks.EpSendFull = htt_h2t_full; + connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH; + + /* Should NOT support credit flow control. */ + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; + + connect.ServiceID = HTT_DATA2_MSG_SVC; + + status = HTCConnectService(pdev->htc_pdev, &connect, &response); + if (status != A_OK) { + pdev->htc_tx_htt2_endpoint = ENDPOINT_UNUSED; + pdev->htc_tx_htt2_max_size = 0; + } else { + pdev->htc_tx_htt2_endpoint = response.Endpoint; + pdev->htc_tx_htt2_max_size = HTC_TX_HTT2_MAX_SIZE; + } + + adf_os_print("TX HTT %s, ep %d size %d\n", + (status == A_OK ? "ON" : "OFF"), + pdev->htc_tx_htt2_endpoint, + pdev->htc_tx_htt2_max_size); + } +#endif /* QCA_TX_HTT2_SUPPORT */ + + return 0; /* success */ +} + +#if HTT_DEBUG_LEVEL > 5 +void +htt_display(htt_pdev_handle pdev, int indent) +{ + adf_os_print("%*s%s:\n", indent, " ", "HTT"); + adf_os_print( + "%*stx desc pool: %d elems of %d bytes, " + "%d currently allocated\n", indent+4, " ", + pdev->tx_descs.pool_elems, + pdev->tx_descs.size, + pdev->tx_descs.alloc_cnt); + adf_os_print( + "%*srx ring: space for %d elems, filled with %d buffers\n", + indent+4, " ", + pdev->rx_ring.size, + pdev->rx_ring.fill_level); + adf_os_print("%*sat %p (%#x paddr)\n", indent+8, " ", + pdev->rx_ring.buf.paddrs_ring, + pdev->rx_ring.base_paddr); + adf_os_print("%*snetbuf ring @ %p\n", indent+8, " ", + pdev->rx_ring.buf.netbufs_ring); + adf_os_print("%*sFW_IDX shadow register: vaddr = %p, paddr = %#x\n", + indent+8, " ", + pdev->rx_ring.alloc_idx.vaddr, + pdev->rx_ring.alloc_idx.paddr); + adf_os_print( + "%*sSW enqueue index = %d, SW dequeue index: desc = %d, buf = %d\n", + indent+8, " ", + *pdev->rx_ring.alloc_idx.vaddr, + pdev->rx_ring.sw_rd_idx.msdu_desc, + pdev->rx_ring.sw_rd_idx.msdu_payld); +} +#endif + +/* Disable ASPM : Disable PCIe low power */ +void htt_htc_disable_aspm(void) +{ + htc_disable_aspm(); +} + +#ifdef IPA_UC_OFFLOAD +/* + * Attach resource for micro controller data path + */ +int +htt_ipa_uc_attach(struct htt_pdev_t *pdev) +{ + int error; + + /* TX resource attach */ + error = htt_tx_ipa_uc_attach(pdev, + ol_cfg_ipa_uc_tx_buf_size(pdev->ctrl_pdev), + ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev), + ol_cfg_ipa_uc_tx_partition_base(pdev->ctrl_pdev)); + if (error) { + adf_os_print("HTT IPA UC TX attach fail code %d\n", error); + HTT_ASSERT0(0); + return error; + } + + /* RX resource attach */ + error = htt_rx_ipa_uc_attach(pdev, + ol_cfg_ipa_uc_rx_ind_ring_size(pdev->ctrl_pdev)); + if (error) { + adf_os_print("HTT IPA UC RX attach fail code %d\n", error); + htt_tx_ipa_uc_detach(pdev); + HTT_ASSERT0(0); + return error; + } + + return 0; /* success */ +} + +void +htt_ipa_uc_detach(struct htt_pdev_t *pdev) +{ + /* TX IPA micro controller detach */ + htt_tx_ipa_uc_detach(pdev); + + /* RX IPA micro controller detach */ + htt_rx_ipa_uc_detach(pdev); +} + +/* + * Distribute micro controller resource to control module + */ +int +htt_ipa_uc_get_resource(htt_pdev_handle pdev, + u_int32_t *ce_sr_base_paddr, + u_int32_t *ce_sr_ring_size, + u_int32_t *ce_reg_paddr, + u_int32_t *tx_comp_ring_base_paddr, + u_int32_t *tx_comp_ring_size, + u_int32_t *tx_num_alloc_buffer, + u_int32_t *rx_rdy_ring_base_paddr, + u_int32_t *rx_rdy_ring_size, + u_int32_t *rx_proc_done_idx_paddr) +{ + /* Release allocated resource to client */ + *tx_comp_ring_base_paddr = + (u_int32_t)pdev->ipa_uc_tx_rsc.tx_comp_base.paddr; + *tx_comp_ring_size = + (u_int32_t)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev); + *tx_num_alloc_buffer = + (u_int32_t)pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt; + *rx_rdy_ring_base_paddr = + (u_int32_t)pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr; + *rx_rdy_ring_size = + (u_int32_t)pdev->ipa_uc_rx_rsc.rx_ind_ring_size; + *rx_proc_done_idx_paddr = + (u_int32_t)pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr; + + /* Get copy engine, bus resource */ + HTCIpaGetCEResource(pdev->htc_pdev, + ce_sr_base_paddr, ce_sr_ring_size, ce_reg_paddr); + + + return 0; +} + +/* + * Distribute micro controller doorbell register to firmware + */ +int +htt_ipa_uc_set_doorbell_paddr(htt_pdev_handle pdev, + u_int32_t ipa_uc_tx_doorbell_paddr, + u_int32_t ipa_uc_rx_doorbell_paddr) +{ + pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr = ipa_uc_tx_doorbell_paddr; + pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr = ipa_uc_rx_doorbell_paddr; + return 0; +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.h new file mode 100644 index 0000000000000..cdd73badc10df --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt.h @@ -0,0 +1,6424 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt.h + * + * @details the public header file of HTT layer + */ + +#ifndef _HTT_H_ +#define _HTT_H_ + +#include /* A_UINT32 */ +#include /* PREPACK, POSTPACK */ +#ifdef ATHR_WIN_NWF +#pragma warning( disable:4214 ) //bit field types other than int +#endif +#include "wlan_defs.h" +#include + +/* + * Unless explicitly specified to use 64 bits to represent physical addresses + * (or more precisely, bus addresses), default to 32 bits. + */ +#ifndef HTT_PADDR64 + #define HTT_PADDR64 0 +#endif + +#ifndef offsetof +#define offsetof(type, field) ((unsigned int)(&((type *)0)->field)) +#endif + +/* + * HTT version history: + * 1.0 initial numbered version + * 1.1 modifications to STATS messages. + * These modifications are not backwards compatible, but since the + * STATS messages themselves are non-essential (they are for debugging), + * the 1.1 version of the HTT message library as a whole is compatible + * with the 1.0 version. + * 1.2 reset mask IE added to STATS_REQ message + * 1.3 stat config IE added to STATS_REQ message + *---- + * 2.0 FW rx PPDU desc added to RX_IND message + * 2.1 Enable msdu_ext/frag_desc banking change for WIFI2.0 + *---- + * 3.0 Remove HTT_H2T_MSG_TYPE_MGMT_TX message + * 3.1 Added HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND message + * 3.2 Added HTT_H2T_MSG_TYPE_WDI_IPA_CFG, + * HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQUEST messages + * 3.3 Added HTT_H2T_MSG_TYPE_AGGR_CFG_EX message + * 3.4 Added tx_compl_req flag in HTT tx descriptor + * 3.5 Added flush and fail stats in rx_reorder stats structure + * 3.6 Added frag flag in HTT RX INORDER PADDR IND header + * 3.7 Made changes to support EOS Mac_core 3.0 + * 3.8 Added txq_group information element definition; + * added optional txq_group suffix to TX_CREDIT_UPDATE_IND message + * 3.9 Added HTT_T2H CHAN_CHANGE message; + * Allow buffer addresses in bus-address format to be stored as + * either 32 bits or 64 bits. + * 3.10 Add optional TLV extensions to the VERSION_REQ and VERSION_CONF + * messages to specify which HTT options to use. + * Initial TLV options cover: + * - whether to use 32 or 64 bits to represent LL bus addresses + * - whether to use TX_COMPL_IND or TX_CREDIT_UPDATE_IND in HL systems + * - how many tx queue groups to use + * 3.11 Expand rx debug stats: + * - Expand the rx_reorder_stats struct with stats about successful and + * failed rx buffer allcoations. + * - Add a new rx_remote_buffer_mgmt_stats struct with stats about + * the supply, allocation, use, and recycling of rx buffers for the + * "remote ring" of rx buffers in host member in LL systems. + * Add RX_REMOTE_RING_BUFFER_INFO stats type for uploading these stats. + * 3.12 Add "rx offload packet error" message with initial "MIC error" subtype + * 3.13 Add constants + macros to support 64-bit address format for the + * tx fragments descriptor, the rx ring buffer, and the rx ring + * index shadow register. + * 3.14 Add a method for the host to provide detailed per-frame tx specs: + * - Add htt_tx_msdu_desc_ext_t struct def. + * - Add TLV to specify whether the target supports the HTT tx MSDU + * extension descriptor. + * - Change a reserved bit in the HTT tx MSDU descriptor to an + * "extension" bit, to specify whether a HTT tx MSDU extension + * descriptor is present. + * 3.15 Add HW rx desc info to per-MSDU info elems in RX_IN_ORD_PADDR_IND msg. + * (This allows the host to obtain key information about the MSDU + * from a memory location already in the cache, rather than taking a + * cache miss for each MSDU by reading the HW rx descs.) + * 3.16 Add htt_pkt_type_eth2 and define pkt_subtype flags to indicate + * whether a copy-engine classification result is appended to TX_FRM. + * 3.17 Add a version of the WDI_IPA_CFG message; add RX_RING2 to WDI_IPA_CFG + * 3.18 Add a PEER_DEL tx completion indication status, for HL cleanup of + * tx frames in the target after the peer has already been deleted. + * 3.19 Add HTT_DBG_STATS_RX_RATE_INFO_V2 and HTT_DBG_STATS_TX_RATE_INFO_V2 + * 3.20 Expand rx_reorder_stats. + * 3.21 Expand rx_reorder_stats + * (distinguish duplicates within vs. outside block ack window) + */ +#define HTT_CURRENT_VERSION_MAJOR 3 +#define HTT_CURRENT_VERSION_MINOR 20 + +#define HTT_NUM_TX_FRAG_DESC 1024 + +#define HTT_WIFI_IP_VERSION(x,y) ((x) == (y)) + +#define HTT_CHECK_SET_VAL(field, val) \ + A_ASSERT(!((val) & ~((field ## _M) >> (field ## _S)))) + +/* macros to assist in sign-extending fields from HTT messages */ +#define HTT_SIGN_BIT_MASK(field) \ + ((field ## _M + (1 << field ## _S)) >> 1) +#define HTT_SIGN_BIT(_val, field) \ + (_val & HTT_SIGN_BIT_MASK(field)) +#define HTT_SIGN_BIT_UNSHIFTED(_val, field) \ + (HTT_SIGN_BIT(_val, field) >> field ## _S) +#define HTT_SIGN_BIT_UNSHIFTED_MINUS_ONE(_val, field) \ + (HTT_SIGN_BIT_UNSHIFTED(_val, field) - 1) +#define HTT_SIGN_BIT_EXTENSION(_val, field) \ + (~(HTT_SIGN_BIT_UNSHIFTED(_val, field) | \ + HTT_SIGN_BIT_UNSHIFTED_MINUS_ONE(_val, field))) +#define HTT_SIGN_BIT_EXTENSION_MASK(_val, field) \ + (HTT_SIGN_BIT_EXTENSION(_val, field) & ~(field ## _M >> field ## _S)) + + +/* + * TEMPORARY: + * Provide HTT_H2T_MSG_TYPE_MGMT_TX as an alias for + * DEPRECATED_HTT_H2T_MSG_TYPE_MGMT_TX until all code + * that refers to HTT_H2T_MSG_TYPE_MGMT_TX has been + * updated. + */ +#define HTT_H2T_MSG_TYPE_MGMT_TX DEPRECATED_HTT_H2T_MSG_TYPE_MGMT_TX + +/* + * TEMPORARY: + * Provide HTT_T2H_MSG_TYPE_RC_UPDATE_IND as an alias for + * DEPRECATED_HTT_T2H_MSG_TYPE_RC_UPDATE_IND until all code + * that refers to HTT_T2H_MSG_TYPE_RC_UPDATE_IND has been + * updated. + */ +#define HTT_T2H_MSG_TYPE_RC_UPDATE_IND DEPRECATED_HTT_T2H_MSG_TYPE_RC_UPDATE_IND + +/* HTT Access Category values */ +enum HTT_AC_WMM { + /* WMM Access Categories */ + HTT_AC_WMM_BE = 0x0, + HTT_AC_WMM_BK = 0x1, + HTT_AC_WMM_VI = 0x2, + HTT_AC_WMM_VO = 0x3, + /* extension Access Categories */ + HTT_AC_EXT_NON_QOS = 0x4, + HTT_AC_EXT_UCAST_MGMT = 0x5, + HTT_AC_EXT_MCAST_DATA = 0x6, + HTT_AC_EXT_MCAST_MGMT = 0x7, +}; +enum HTT_AC_WMM_MASK { + /* WMM Access Categories */ + HTT_AC_WMM_BE_MASK = (1 << HTT_AC_WMM_BE), + HTT_AC_WMM_BK_MASK = (1 << HTT_AC_WMM_BK), + HTT_AC_WMM_VI_MASK = (1 << HTT_AC_WMM_VI), + HTT_AC_WMM_VO_MASK = (1 << HTT_AC_WMM_VO), + /* extension Access Categories */ + HTT_AC_EXT_NON_QOS_MASK = (1 << HTT_AC_EXT_NON_QOS), + HTT_AC_EXT_UCAST_MGMT_MASK = (1 << HTT_AC_EXT_UCAST_MGMT), + HTT_AC_EXT_MCAST_DATA_MASK = (1 << HTT_AC_EXT_MCAST_DATA), + HTT_AC_EXT_MCAST_MGMT_MASK = (1 << HTT_AC_EXT_MCAST_MGMT), +}; +#define HTT_AC_MASK_WMM \ + (HTT_AC_WMM_BE_MASK | HTT_AC_WMM_BK_MASK | \ + HTT_AC_WMM_VI_MASK | HTT_AC_WMM_VO_MASK) +#define HTT_AC_MASK_EXT \ + (HTT_AC_EXT_NON_QOS_MASK | HTT_AC_EXT_UCAST_MGMT_MASK | \ + HTT_AC_EXT_MCAST_DATA_MASK | HTT_AC_EXT_MCAST_MGMT_MASK) +#define HTT_AC_MASK_ALL (HTT_AC_MASK_WMM | HTT_AC_MASK_EXT) + +/* + * htt_dbg_stats_type - + * bit positions for each stats type within a stats type bitmask + * The bitmask contains 24 bits. + */ +enum htt_dbg_stats_type { + HTT_DBG_STATS_WAL_PDEV_TXRX = 0, /* bit 0 -> 0x1 */ + HTT_DBG_STATS_RX_REORDER = 1, /* bit 1 -> 0x2 */ + HTT_DBG_STATS_RX_RATE_INFO = 2, /* bit 2 -> 0x4 */ + HTT_DBG_STATS_TX_PPDU_LOG = 3, /* bit 3 -> 0x8 */ + HTT_DBG_STATS_TX_RATE_INFO = 4, /* bit 4 -> 0x10 */ + HTT_DBG_STATS_TIDQ = 5, /* bit 5 -> 0x20 */ + HTT_DBG_STATS_TXBF_INFO = 6, /* bit 6 -> 0x40 */ + HTT_DBG_STATS_SND_INFO = 7, /* bit 7 -> 0x80 */ + HTT_DBG_STATS_ERROR_INFO = 8, /* bit 8 -> 0x100 */ + HTT_DBG_STATS_TX_SELFGEN_INFO = 9, /* bit 9 -> 0x200 */ + HTT_DBG_STATS_TX_MU_INFO = 10, /* bit 10 -> 0x400 */ + HTT_DBG_STATS_SIFS_RESP_INFO = 11, /* bit 11 -> 0x800 */ + HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO = 12, /* bit 12 -> 0x1000*/ + HTT_DBG_STATS_RX_RATE_INFO_V2 = 13, /* bit 13 -> 0x2000 */ + HTT_DBG_STATS_TX_RATE_INFO_V2 = 14, /* bit 14 -> 0x4000 */ + /* bits 15-23 currently reserved */ + + /* keep this last */ + HTT_DBG_NUM_STATS +}; + +/*=== HTT option selection TLVs === + * Certain HTT messages have alternatives or options. + * For such cases, the host and target need to agree on which option to use. + * Option specification TLVs can be appended to the VERSION_REQ and + * VERSION_CONF messages to select options other than the default. + * These TLVs are entirely optional - if they are not provided, there is a + * well-defined default for each option. If they are provided, they can be + * provided in any order. Each TLV can be present or absent independent of + * the presence / absence of other TLVs. + * + * The HTT option selection TLVs use the following format: + * |31 16|15 8|7 0| + * |---------------------------------+----------------+----------------| + * | value (payload) | length | tag | + * |-------------------------------------------------------------------| + * The value portion need not be only 2 bytes; it can be extended by any + * integer number of 4-byte units. The total length of the TLV, including + * the tag and length fields, must be a multiple of 4 bytes. The length + * field specifies the total TLV size in 4-byte units. Thus, the typical + * TLV, with a 1-byte tag field, a 1-byte length field, and a 2-byte value + * field, would store 0x1 in its length field, to show that the TLV occupies + * a single 4-byte unit. + */ + +/*--- TLV header format - applies to all HTT option TLVs ---*/ + +enum HTT_OPTION_TLV_TAGS { + HTT_OPTION_TLV_TAG_RESERVED0 = 0x0, + HTT_OPTION_TLV_TAG_LL_BUS_ADDR_SIZE = 0x1, + HTT_OPTION_TLV_TAG_HL_SUPPRESS_TX_COMPL_IND = 0x2, + HTT_OPTION_TLV_TAG_MAX_TX_QUEUE_GROUPS = 0x3, + HTT_OPTION_TLV_TAG_SUPPORT_TX_MSDU_DESC_EXT = 0x4, +}; + +PREPACK struct htt_option_tlv_header_t { + A_UINT8 tag; + A_UINT8 length; +} POSTPACK; + +#define HTT_OPTION_TLV_TAG_M 0x000000ff +#define HTT_OPTION_TLV_TAG_S 0 +#define HTT_OPTION_TLV_LENGTH_M 0x0000ff00 +#define HTT_OPTION_TLV_LENGTH_S 8 +/* + * value0 - 16 bit value field stored in word0 + * The TLV's value field may be longer than 2 bytes, in which case + * the remainder of the value is stored in word1, word2, etc. + */ +#define HTT_OPTION_TLV_VALUE0_M 0xffff0000 +#define HTT_OPTION_TLV_VALUE0_S 16 + +#define HTT_OPTION_TLV_TAG_SET(word, tag) \ + do { \ + HTT_CHECK_SET_VAL(HTT_OPTION_TLV_TAG, tag); \ + (word) |= ((tag) << HTT_OPTION_TLV_TAG_S); \ + } while (0) +#define HTT_OPTION_TLV_TAG_GET(word) \ + (((word) & HTT_OPTION_TLV_TAG_M) >> HTT_OPTION_TLV_TAG_S) + +#define HTT_OPTION_TLV_LENGTH_SET(word, tag) \ + do { \ + HTT_CHECK_SET_VAL(HTT_OPTION_TLV_LENGTH, tag); \ + (word) |= ((tag) << HTT_OPTION_TLV_LENGTH_S); \ + } while (0) +#define HTT_OPTION_TLV_LENGTH_GET(word) \ + (((word) & HTT_OPTION_TLV_LENGTH_M) >> HTT_OPTION_TLV_LENGTH_S) + +#define HTT_OPTION_TLV_VALUE0_SET(word, tag) \ + do { \ + HTT_CHECK_SET_VAL(HTT_OPTION_TLV_VALUE0, tag); \ + (word) |= ((tag) << HTT_OPTION_TLV_VALUE0_S); \ + } while (0) +#define HTT_OPTION_TLV_VALUE0_GET(word) \ + (((word) & HTT_OPTION_TLV_VALUE0_M) >> HTT_OPTION_TLV_VALUE0_S) + +/*--- format of specific HTT option TLVs ---*/ + +/* + * HTT option TLV for specifying LL bus address size + * Some chips require bus addresses used by the target to access buffers + * within the host's memory to be 32 bits; others require bus addresses + * used by the target to access buffers within the host's memory to be + * 64 bits. + * The LL_BUS_ADDR_SIZE TLV can be sent from the target to the host as + * a suffix to the VERSION_CONF message to specify which bus address format + * the target requires. + * If this LL_BUS_ADDR_SIZE TLV is not sent by the target, the host should + * default to providing bus addresses to the target in 32-bit format. + */ +enum HTT_OPTION_TLV_LL_BUS_ADDR_SIZE_VALUES { + HTT_OPTION_TLV_LL_BUS_ADDR_SIZE32 = 0x0, + HTT_OPTION_TLV_LL_BUS_ADDR_SIZE64 = 0x1, +}; +PREPACK struct htt_option_tlv_ll_bus_addr_size_t { + struct htt_option_tlv_header_t hdr; + A_UINT16 ll_bus_addr_size; /* LL_BUS_ADDR_SIZE_VALUES enum */ +} POSTPACK; + +/* + * HTT option TLV for specifying whether HL systems should indicate + * over-the-air tx completion for individual frames, or should instead + * send a bulk TX_CREDIT_UPDATE_IND except when the host explicitly + * requests an OTA tx completion for a particular tx frame. + * This option does not apply to LL systems, where the TX_COMPL_IND + * is mandatory. + * This option is primarily intended for HL systems in which the tx frame + * downloads over the host --> target bus are as slow as or slower than + * the transmissions over the WLAN PHY. For cases where the bus is faster + * than the WLAN PHY, the target will transmit relatively large A-MPDUs, + * and consquently will send one TX_COMPL_IND message that covers several + * tx frames. For cases where the WLAN PHY is faster than the bus, + * the target will end up transmitting very short A-MPDUs, and consequently + * sending many TX_COMPL_IND messages, which each cover a very small number + * of tx frames. + * The HL_SUPPRESS_TX_COMPL_IND TLV can be sent by the host to the target as + * a suffix to the VERSION_REQ message to request whether the host desires to + * use TX_CREDIT_UPDATE_IND rather than TX_COMPL_IND. The target can then + * send a HTT_SUPPRESS_TX_COMPL_IND TLV to the host as a suffix to the + * VERSION_CONF message to confirm whether TX_CREDIT_UPDATE_IND will be used + * rather than TX_COMPL_IND. TX_CREDIT_UPDATE_IND shall only be used if the + * host sends a HL_SUPPRESS_TX_COMPL_IND TLV requesting use of + * TX_CREDIT_UPDATE_IND, and the target sends a HL_SUPPRESS_TX_COMPLE_IND TLV + * back to the host confirming use of TX_CREDIT_UPDATE_IND. + * Lack of a HL_SUPPRESS_TX_COMPL_IND TLV from either host --> target or + * target --> host is equivalent to a HL_SUPPRESS_TX_COMPL_IND that + * explicitly specifies HL_ALLOW_TX_COMPL_IND in the value payload of the + * TLV. + */ +enum HTT_OPTION_TLV_HL_SUPPRESS_TX_COMPL_IND_VALUES { + HTT_OPTION_TLV_HL_ALLOW_TX_COMPL_IND = 0x0, + HTT_OPTION_TLV_HL_SUPPRESS_TX_COMPL_IND = 0x1, +}; +PREPACK struct htt_option_tlv_hl_suppress_tx_compl_ind_t { + struct htt_option_tlv_header_t hdr; + A_UINT16 hl_suppress_tx_compl_ind; /* HL_SUPPRESS_TX_COMPL_IND enum */ +} POSTPACK; + +/* + * HTT option TLV for specifying how many tx queue groups the target + * may establish. + * This TLV specifies the maximum value the target may send in the + * txq_group_id field of any TXQ_GROUP information elements sent by + * the target to the host. This allows the host to pre-allocate an + * appropriate number of tx queue group structs. + * + * The MAX_TX_QUEUE_GROUPS_TLV can be sent from the host to the target as + * a suffix to the VERSION_REQ message to specify whether the host supports + * tx queue groups at all, and if so if there is any limit on the number of + * tx queue groups that the host supports. + * The MAX_TX_QUEUE_GROUPS TLV can be sent from the target to the host as + * a suffix to the VERSION_CONF message. If the host has specified in the + * VER_REQ message a limit on the number of tx queue groups the host can + * supprt, the target shall limit its specification of the maximum tx groups + * to be no larger than this host-specified limit. + * + * If the target does not provide a MAX_TX_QUEUE_GROUPS TLV, then the host + * shall preallocate 4 tx queue group structs, and the target shall not + * specify a txq_group_id larger than 3. + */ +enum HTT_OPTION_TLV_MAX_TX_QUEUE_GROUPS_VALUES { + HTT_OPTION_TLV_TX_QUEUE_GROUPS_UNSUPPORTED = 0, + /* + * values 1 through N specify the max number of tx queue groups + * the sender supports + */ + HTT_OPTION_TLV_TX_QUEUE_GROUPS_UNLIMITED = 0xffff, +}; +/* TEMPORARY backwards-compatibility alias for a typo fix - + * The htt_option_tlv_mac_tx_queue_groups_t typo has been corrected + * to htt_option_tlv_max_tx_queue_groups_t, but an alias is provided + * to support the old name (with the typo) until all references to the + * old name are replaced with the new name. + */ +#define htt_option_tlv_mac_tx_queue_groups_t htt_option_tlv_max_tx_queue_groups_t +PREPACK struct htt_option_tlv_max_tx_queue_groups_t { + struct htt_option_tlv_header_t hdr; + A_UINT16 max_tx_queue_groups; /* max txq_group_id + 1 */ +} POSTPACK; + +/* + * HTT option TLV for specifying whether the target supports an extended + * version of the HTT tx descriptor. If the target provides this TLV + * and specifies in the TLV that the target supports an extended version + * of the HTT tx descriptor, the target must check the "extension" bit in + * the HTT tx descriptor, and if the extension bit is set, to expect a + * HTT tx MSDU extension descriptor immediately following the HTT tx MSDU + * descriptor. Furthermore, the target must provide room for the HTT + * tx MSDU extension descriptor in the target's TX_FRM buffer. + * This option is intended for systems where the host needs to explicitly + * control the transmission parameters such as tx power for individual + * tx frames. + * The SUPPORT_TX_MSDU_DESC_EXT TLB can be sent by the target to the host + * as a suffix to the VERSION_CONF message to explicitly specify whether + * the target supports the HTT tx MSDU extension descriptor. + * Lack of a SUPPORT_TX_MSDU_DESC_EXT from the target shall be interpreted + * by the host as lack of target support for the HTT tx MSDU extension + * descriptor; the host shall provide HTT tx MSDU extension descriptors in + * the HTT_H2T TX_FRM messages only if the target indicates it supports + * the HTT tx MSDU extension descriptor. + * The host is not required to provide the HTT tx MSDU extension descriptor + * just because the target supports it; the target must check the + * "extension" bit in the HTT tx MSDU descriptor to determine whether an + * extension descriptor is present. + */ +enum HTT_OPTION_TLV_SUPPORT_TX_MSDU_DESC_EXT_VALUES { + HTT_OPTION_TLV_TX_MSDU_DESC_EXT_NO_SUPPORT = 0x0, + HTT_OPTION_TLV_TX_MSDU_DESC_EXT_SUPPORT = 0x1, +}; +PREPACK struct htt_option_tlv_support_tx_msdu_desc_ext_t { + struct htt_option_tlv_header_t hdr; + A_UINT16 tx_msdu_desc_ext_support; /* SUPPORT_TX_MSDU_DESC_EXT enum */ +} POSTPACK; + + +/*=== host -> target messages ===============================================*/ + +enum htt_h2t_msg_type { + HTT_H2T_MSG_TYPE_VERSION_REQ = 0x0, + HTT_H2T_MSG_TYPE_TX_FRM = 0x1, + HTT_H2T_MSG_TYPE_RX_RING_CFG = 0x2, + HTT_H2T_MSG_TYPE_STATS_REQ = 0x3, + HTT_H2T_MSG_TYPE_SYNC = 0x4, + HTT_H2T_MSG_TYPE_AGGR_CFG = 0x5, + HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG = 0x6, + DEPRECATED_HTT_H2T_MSG_TYPE_MGMT_TX = 0x7, /* no longer used */ + HTT_H2T_MSG_TYPE_WDI_IPA_CFG = 0x8, + HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ = 0x9, + HTT_H2T_MSG_TYPE_AGGR_CFG_EX = 0xa, /* per vdev amsdu subfrm limit */ + /* keep this last */ + HTT_H2T_NUM_MSGS +}; + +/* + * HTT host to target message type - + * stored in bits 7:0 of the first word of the message + */ +#define HTT_H2T_MSG_TYPE_M 0xff +#define HTT_H2T_MSG_TYPE_S 0 + +#define HTT_H2T_MSG_TYPE_SET(word, msg_type) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_MSG_TYPE, msg_type); \ + (word) |= ((msg_type) << HTT_H2T_MSG_TYPE_S); \ + } while (0) +#define HTT_H2T_MSG_TYPE_GET(word) \ + (((word) & HTT_H2T_MSG_TYPE_M) >> HTT_H2T_MSG_TYPE_S) + +/** + * @brief target -> host version number request message definition + * + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | reserved | msg type | + * |-------------------------------------------------------------------| + * : option request TLV (optional) | + * :...................................................................: + * + * The VER_REQ message may consist of a single 4-byte word, or may be + * extended with TLVs that specify which HTT options the host is requesting + * from the target. + * The following option TLVs may be appended to the VER_REQ message: + * - HL_SUPPRESS_TX_COMPL_IND + * - HL_MAX_TX_QUEUE_GROUPS + * These TLVs may appear in an arbitrary order. Any number of these TLVs + * may be appended to the VER_REQ message (but only one TLV of each type). + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a version number request message + * Value: 0x0 + */ + +#define HTT_VER_REQ_BYTES 4 + +/* TBDXXX: figure out a reasonable number */ +#define HTT_HL_DATA_SVC_PIPE_DEPTH 24 +#define HTT_LL_DATA_SVC_PIPE_DEPTH 64 + +/** + * @brief HTT tx MSDU descriptor + * + * @details + * The HTT tx MSDU descriptor is created by the host HTT SW for each + * tx MSDU. The HTT tx MSDU descriptor contains the information that + * the target firmware needs for the FW's tx processing, particularly + * for creating the HW msdu descriptor. + * The same HTT tx descriptor is used for HL and LL systems, though + * a few fields within the tx descriptor are used only by LL or + * only by HL. + * The HTT tx descriptor is defined in two manners: by a struct with + * bitfields, and by a series of [dword offset, bit mask, bit shift] + * definitions. + * The target should use the struct def, for simplicitly and clarity, + * but the host shall use the bit-mast + bit-shift defs, to be endian- + * neutral. Specifically, the host shall use the get/set macros built + * around the mask + shift defs. + */ +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_80211_HDR_S 0 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_80211_HDR_M 0x1 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S 1 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_M 0x2 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S 2 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_M 0x4 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_CLASSIFY_S 3 +#define HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_CLASSIFY_M 0x8 + +#define HTT_TX_VDEV_ID_WORD 0 +#define HTT_TX_VDEV_ID_MASK 0x3f +#define HTT_TX_VDEV_ID_SHIFT 16 + +#define HTT_TX_L3_CKSUM_OFFLOAD 1 +#define HTT_TX_L4_CKSUM_OFFLOAD 2 + +#define HTT_TX_MSDU_LEN_DWORD 1 +#define HTT_TX_MSDU_LEN_MASK 0xffff; + +/* + * HTT_VAR_PADDR macros + * Allow physical / bus addresses to be either a single 32-bit value, + * or a 64-bit value, stored as a little-endian lo,hi pair of 32-bit parts + */ +#define HTT_VAR_PADDR32(var_name) \ + A_UINT32 var_name +#define HTT_VAR_PADDR64_LE(var_name) \ + struct { \ + /* little-endian: lo precedes hi */ \ + A_UINT32 lo; \ + A_UINT32 hi; \ + } var_name + +/* + * TEMPLATE_HTT_TX_MSDU_DESC_T: + * This macro defines a htt_tx_msdu_descXXX_t in which any physical + * addresses are stored in a XXX-bit field. + * This macro is used to define both htt_tx_msdu_desc32_t and + * htt_tx_msdu_desc64_t structs. + */ +#define TEMPLATE_HTT_TX_MSDU_DESC_T(_paddr_bits_, _paddr__frags_desc_ptr_) \ +PREPACK struct htt_tx_msdu_desc ## _paddr_bits_ ## _t \ +{ \ + /* DWORD 0: flags and meta-data */ \ + A_UINT32 \ + msg_type: 8, /* HTT_H2T_MSG_TYPE_TX_FRM */ \ + \ + /* pkt_subtype - \ + * Detailed specification of the tx frame contents, extending the \ + * general specification provided by pkt_type. \ + * FIX THIS: ADD COMPLETE SPECS FOR THIS FIELDS VALUE, e.g. \ + * pkt_type | pkt_subtype \ + * ============================================================== \ + * 802.3 | bit 0:3 - Reserved \ + * | bit 4: 0x0 - Copy-Engine Classification Results \ + * | not appended to the HTT message \ + * | 0x1 - Copy-Engine Classification Results \ + * | appended to the HTT message in the \ + * | format: \ + * | [HTT tx desc, frame header, \ + * | CE classification results] \ + * | The CE classification results begin \ + * | at the next 4-byte boundary after \ + * | the frame header. \ + * ------------+------------------------------------------------- \ + * Eth2 | bit 0:3 - Reserved \ + * | bit 4: 0x0 - Copy-Engine Classification Results \ + * | not appended to the HTT message \ + * | 0x1 - Copy-Engine Classification Results \ + * | appended to the HTT message. \ + * | See the above specification of the \ + * | CE classification results location. \ + * ------------+------------------------------------------------- \ + * native WiFi | bit 0:3 - Reserved \ + * | bit 4: 0x0 - Copy-Engine Classification Results \ + * | not appended to the HTT message \ + * | 0x1 - Copy-Engine Classification Results \ + * | appended to the HTT message. \ + * | See the above specification of the \ + * | CE classification results location. \ + * ------------+------------------------------------------------- \ + * mgmt | 0x0 - 802.11 MAC header absent \ + * | 0x1 - 802.11 MAC header present \ + * ------------+------------------------------------------------- \ + * raw | bit 0: 0x0 - 802.11 MAC header absent \ + * | 0x1 - 802.11 MAC header present \ + * | bit 1: 0x0 - allow aggregation \ + * | 0x1 - don't allow aggregation \ + * | bit 2: 0x0 - perform encryption \ + * | 0x1 - don't perform encryption \ + * | bit 3: 0x0 - perform tx classification / queuing \ + * | 0x1 - don't perform tx classification; \ + * | insert the frame into the "misc" \ + * | tx queue \ + * | bit 4: 0x0 - Copy-Engine Classification Results \ + * | not appended to the HTT message \ + * | 0x1 - Copy-Engine Classification Results \ + * | appended to the HTT message. \ + * | See the above specification of the \ + * | CE classification results location. \ + */ \ + pkt_subtype: 5, \ + \ + /* pkt_type - \ + * General specification of the tx frame contents. \ + * The htt_pkt_type enum should be used to specify and check the \ + * value of this field. \ + */ \ + pkt_type: 3, \ + \ + /* vdev_id - \ + * ID for the vdev that is sending this tx frame. \ + * For certain non-standard packet types, e.g. pkt_type == raw \ + * and (pkt_subtype >> 3) == 1, this field is not relevant/valid. \ + * This field is used primarily for determining where to queue \ + * broadcast and multicast frames. \ + */ \ + vdev_id: 6, \ + /* ext_tid - \ + * The extended traffic ID. \ + * If the TID is unknown, the extended TID is set to \ + * HTT_TX_EXT_TID_INVALID. \ + * If the tx frame is QoS data, then the extended TID has the 0-15 \ + * value of the QoS TID. \ + * If the tx frame is non-QoS data, then the extended TID is set to \ + * HTT_TX_EXT_TID_NON_QOS. \ + * If the tx frame is multicast or broadcast, then the extended TID \ + * is set to HTT_TX_EXT_TID_MCAST_BCAST. \ + */ \ + ext_tid: 5, \ + \ + /* postponed - \ + * This flag indicates whether the tx frame has been downloaded to \ + * the target before but discarded by the target, and now is being \ + * downloaded again; or if this is a new frame that is being \ + * downloaded for the first time. \ + * This flag allows the target to determine the correct order for \ + * transmitting new vs. old frames. \ + * value: 0 -> new frame, 1 -> re-send of a previously sent frame \ + * This flag only applies to HL systems, since in LL systems, \ + * the tx flow control is handled entirely within the target. \ + */ \ + postponed: 1, \ + \ + /* extension - \ + * This flag indicates whether a HTT tx MSDU extension descriptor \ + * (htt_tx_msdu_desc_ext_t) follows this HTT tx MSDU descriptor. \ + * \ + * 0x0 - no extension MSDU descriptor is present \ + * 0x1 - an extension MSDU descriptor immediately follows the \ + * regular MSDU descriptor \ + */ \ + extension: 1, \ + \ + /* cksum_offload - \ + * This flag indicates whether checksum offload is enabled or not \ + * for this frame. Target FW use this flag to turn on HW checksumming \ + * 0x0 - No checksum offload \ + * 0x1 - L3 header checksum only \ + * 0x2 - L4 checksum only \ + * 0x3 - L3 header checksum + L4 checksum \ + */ \ + cksum_offload: 2, \ + \ + /* tx_comp_req - \ + * This flag indicates whether Tx Completion \ + * from fw is required or not. \ + * This flag is only relevant if tx completion is not \ + * universally enabled. \ + * For all LL systems, tx completion is mandatory, \ + * so this flag will be irrelevant. \ + * For HL systems tx completion is optional, but HL systems in which \ + * the bus throughput exceeds the WLAN throughput will \ + * probably want to always use tx completion, and thus \ + * would not check this flag. \ + * This flag is required when tx completions are not used universally, \ + * but are still required for certain tx frames for which \ + * an OTA delivery acknowledgment is needed by the host. \ + * In practice, this would be for HL systems in which the \ + * bus throughput is less than the WLAN throughput. \ + * \ + * 0x0 - Tx Completion Indication from Fw not required \ + * 0x1 - Tx Completion Indication from Fw is required \ + */ \ + tx_compl_req: 1; \ + \ + \ + /* DWORD 1: MSDU length and ID */ \ + A_UINT32 \ + len: 16, /* MSDU length, in bytes */ \ + id: 16; /* MSDU ID used to identify the MSDU to the host, \ + * and this id is used to calculate fragmentation \ + * descriptor pointer inside the target based on \ + * the base address, configured inside the target. \ + */ \ + \ + /* DWORD 2 (or 2-3): fragmentation descriptor bus address */ \ + /* frags_desc_ptr - \ + * The fragmentation descriptor pointer tells the HW's MAC DMA \ + * where the tx frame's fragments reside in memory. \ + * This field only applies to LL systems, since in HL systems the \ + * (degenerate single-fragment) fragmentation descriptor is created \ + * within the target. \ + */ \ + _paddr__frags_desc_ptr_; \ + \ + /* DWORD 3 (or 4): peerid, chanfreq */ \ + /* \ + * Peer ID : Target can use this value to know which peer-id packet \ + * destined to. \ + * It's intended to be specified by host in case of NAWDS. \ + */ \ + A_UINT16 peerid; \ + \ + /* \ + * Channel frequency: This identifies the desired channel \ + * frequency (in mhz) for tx frames. This is used by FW to help \ + * determine when it is safe to transmit or drop frames for \ + * off-channel operation. \ + * The default value of zero indicates to FW that the corresponding \ + * VDEV's home channel (if there is one) is the desired channel \ + * frequency. \ + */ \ + A_UINT16 chanfreq; \ + \ + /* Reason reserved is commented is increasing the htt structure size \ + * leads to some wierd issues. Contact Raj/Kyeyoon for more info \ + * A_UINT32 reserved_dword3_bits0_31; \ + */ \ +} POSTPACK +/* define a htt_tx_msdu_desc32_t type */ +TEMPLATE_HTT_TX_MSDU_DESC_T(32, HTT_VAR_PADDR32(frags_desc_ptr)); +/* define a htt_tx_msdu_desc64_t type */ +TEMPLATE_HTT_TX_MSDU_DESC_T(64, HTT_VAR_PADDR64_LE(frags_desc_ptr)); +/* + * Make htt_tx_msdu_desc_t be an alias for either + * htt_tx_msdu_desc32_t or htt_tx_msdu_desc64_t + */ +#if HTT_PADDR64 + #define htt_tx_msdu_desc_t htt_tx_msdu_desc64_t +#else + #define htt_tx_msdu_desc_t htt_tx_msdu_desc32_t +#endif + +/* decriptor information for Management frame*/ +/* + * THIS htt_mgmt_tx_desc_t STRUCT IS DEPRECATED - DON'T USE IT. + * BOTH MANAGEMENT AND DATA FRAMES SHOULD USE htt_tx_msdu_desc_t. + */ +#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32 +extern A_UINT32 mgmt_hdr_len; +PREPACK struct htt_mgmt_tx_desc_t { + A_UINT32 msg_type; +#if HTT_PADDR64 + A_UINT64 frag_paddr; /* DMAble address of the data */ +#else + A_UINT32 frag_paddr; /* DMAble address of the data */ +#endif + A_UINT32 desc_id; /* returned to host during completion + * to free the meory*/ + A_UINT32 len; /* Fragment length */ + A_UINT32 vdev_id; /* virtual device ID*/ + A_UINT8 hdr[HTT_MGMT_FRM_HDR_DOWNLOAD_LEN]; /* frm header */ +} POSTPACK; + +PREPACK struct htt_mgmt_tx_compl_ind { + A_UINT32 desc_id; + A_UINT32 status; +} POSTPACK; + +/* + * This SDU header size comes from the summation of the following: + * 1. Max of: + * a. Native WiFi header, for native WiFi frames: 24 bytes + * (frame control, duration / ID, addr1, addr2, addr3, seq ctrl, addr4) + * b. 802.11 header, for raw frames: 36 bytes + * (frame control, duration / ID, addr1, addr2, addr3, seq ctrl, addr4, + * QoS header, HT header) + * c. 802.3 header, for ethernet frames: 14 bytes + * (destination address, source address, ethertype / length) + * 2. Max of: + * a. IPv4 header, up through the DiffServ Code Point: 2 bytes + * b. IPv6 header, up through the Traffic Class: 2 bytes + * 3. 802.1Q VLAN header: 4 bytes + * 4. LLC/SNAP header: 8 bytes + */ +#define HTT_TX_HDR_SIZE_NATIVE_WIFI 30 +#define HTT_TX_HDR_SIZE_802_11_RAW 36 +#define HTT_TX_HDR_SIZE_ETHERNET 14 + +#define HTT_TX_HDR_SIZE_OUTER_HDR_MAX HTT_TX_HDR_SIZE_802_11_RAW +A_COMPILE_TIME_ASSERT( + htt_encap_hdr_size_max_check_nwifi, + HTT_TX_HDR_SIZE_OUTER_HDR_MAX >= HTT_TX_HDR_SIZE_NATIVE_WIFI); +A_COMPILE_TIME_ASSERT( + htt_encap_hdr_size_max_check_enet, + HTT_TX_HDR_SIZE_OUTER_HDR_MAX >= HTT_TX_HDR_SIZE_ETHERNET); + +#define HTT_HL_TX_HDR_SIZE_IP 1600 /* also include payload */ +#define HTT_LL_TX_HDR_SIZE_IP 16 /* up to the end of UDP header for IPv4 case */ + +#define HTT_TX_HDR_SIZE_802_1Q 4 +#define HTT_TX_HDR_SIZE_LLC_SNAP 8 + + +#define HTT_COMMON_TX_FRM_HDR_LEN \ + (HTT_TX_HDR_SIZE_OUTER_HDR_MAX + \ + HTT_TX_HDR_SIZE_802_1Q + \ + HTT_TX_HDR_SIZE_LLC_SNAP) + +#define HTT_HL_TX_FRM_HDR_LEN \ + (HTT_COMMON_TX_FRM_HDR_LEN + HTT_HL_TX_HDR_SIZE_IP) + +#define HTT_LL_TX_FRM_HDR_LEN \ + (HTT_COMMON_TX_FRM_HDR_LEN + HTT_LL_TX_HDR_SIZE_IP) + +#define HTT_TX_DESC_LEN sizeof(struct htt_tx_msdu_desc_t) + +/* dword 0 */ +#define HTT_TX_DESC_PKT_SUBTYPE_OFFSET_BYTES 0 +#define HTT_TX_DESC_PKT_SUBTYPE_OFFSET_DWORD 0 +#define HTT_TX_DESC_PKT_SUBTYPE_M 0x00001f00 +#define HTT_TX_DESC_PKT_SUBTYPE_S 8 + +#define HTT_TX_DESC_NO_ENCRYPT_OFFSET_BYTES 0 +#define HTT_TX_DESC_NO_ENCRYPT_OFFSET_DWORD 0 +#define HTT_TX_DESC_NO_ENCRYPT_M 0x00000400 +#define HTT_TX_DESC_NO_ENCRYPT_S 10 + +#define HTT_TX_DESC_PKT_TYPE_OFFSET_BYTES 0 +#define HTT_TX_DESC_PKT_TYPE_OFFSET_DWORD 0 +#define HTT_TX_DESC_PKT_TYPE_M 0x0000e000 +#define HTT_TX_DESC_PKT_TYPE_S 13 + +#define HTT_TX_DESC_VDEV_ID_OFFSET_BYTES 0 +#define HTT_TX_DESC_VDEV_ID_OFFSET_DWORD 0 +#define HTT_TX_DESC_VDEV_ID_M 0x003f0000 +#define HTT_TX_DESC_VDEV_ID_S 16 + +#define HTT_TX_DESC_EXT_TID_OFFSET_BYTES 0 +#define HTT_TX_DESC_EXT_TID_OFFSET_DWORD 0 +#define HTT_TX_DESC_EXT_TID_M 0x07c00000 +#define HTT_TX_DESC_EXT_TID_S 22 + +#define HTT_TX_DESC_POSTPONED_OFFSET_BYTES 0 +#define HTT_TX_DESC_POSTPONED_OFFSET_DWORD 0 +#define HTT_TX_DESC_POSTPONED_M 0x08000000 +#define HTT_TX_DESC_POSTPONED_S 27 + +#define HTT_TX_DESC_CKSUM_OFFLOAD_OFFSET_BYTES 0 +#define HTT_TX_DESC_CKSUM_OFFLOAD_OFFSET_DWORD 0 +#define HTT_TX_DESC_CKSUM_OFFLOAD_M 0x60000000 +#define HTT_TX_DESC_CKSUM_OFFLOAD_S 29 + +#define HTT_TX_DESC_TX_COMP_OFFSET_BYTES 0 +#define HTT_TX_DESC_TX_COMP_OFFSET_DWORD 0 +#define HTT_TX_DESC_TX_COMP_M 0x80000000 +#define HTT_TX_DESC_TX_COMP_S 31 + +/* dword 1 */ +#define HTT_TX_DESC_FRM_LEN_OFFSET_BYTES 4 +#define HTT_TX_DESC_FRM_LEN_OFFSET_DWORD 1 +#define HTT_TX_DESC_FRM_LEN_M 0x0000ffff +#define HTT_TX_DESC_FRM_LEN_S 0 + +#define HTT_TX_DESC_FRM_ID_OFFSET_BYTES 4 +#define HTT_TX_DESC_FRM_ID_OFFSET_DWORD 1 +#define HTT_TX_DESC_FRM_ID_M 0xffff0000 +#define HTT_TX_DESC_FRM_ID_S 16 + +/* dword 2 */ +#define HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_BYTES 8 +#define HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_DWORD 2 +/* for systems using 64-bit format for bus addresses */ +#define HTT_TX_DESC_FRAGS_DESC_PADDR_HI_M 0xffffffff +#define HTT_TX_DESC_FRAGS_DESC_PADDR_HI_S 0 +#define HTT_TX_DESC_FRAGS_DESC_PADDR_LO_M 0xffffffff +#define HTT_TX_DESC_FRAGS_DESC_PADDR_LO_S 0 +/* for systems using 32-bit format for bus addresses */ +#define HTT_TX_DESC_FRAGS_DESC_PADDR_M 0xffffffff +#define HTT_TX_DESC_FRAGS_DESC_PADDR_S 0 + +/* dword 3 */ +#define HTT_TX_DESC_PEER_ID_OFFSET_BYTES_64 16 +#define HTT_TX_DESC_PEER_ID_OFFSET_BYTES_32 12 +#define HTT_TX_DESC_PEER_ID_OFFSET_DWORD_64 \ + (HTT_TX_DESC_PEER_ID_OFFSET_BYTES_64 >> 2) +#define HTT_TX_DESC_PEER_ID_OFFSET_DWORD_32 \ + (HTT_TX_DESC_PEER_ID_OFFSET_BYTES_32 >> 2) + +#if HTT_PADDR64 +#define HTT_TX_DESC_PEER_ID_OFFSET_BYTES HTT_TX_DESC_PEER_ID_OFFSET_BYTES_64 +#define HTT_TX_DESC_PEER_ID_OFFSET_DWORD HTT_TX_DESC_PEER_ID_OFFSET_DWORD_64 +#else +#define HTT_TX_DESC_PEER_ID_OFFSET_BYTES HTT_TX_DESC_PEER_ID_OFFSET_BYTES_32 +#define HTT_TX_DESC_PEER_ID_OFFSET_DWORD HTT_TX_DESC_PEER_ID_OFFSET_DWORD_32 +#endif + +#define HTT_TX_DESC_PEER_ID_M 0x0000ffff +#define HTT_TX_DESC_PEER_ID_S 0 + /* + * TEMPORARY: + * The original definitions for the PEER_ID fields contained typos + * (with _DESC_PADDR appended to this PEER_ID field name). + * Retain deprecated original names for PEER_ID fields until all code that + * refers to them has been updated. + */ + #define HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES \ + HTT_TX_DESC_PEER_ID_OFFSET_BYTES + #define HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_DWORD \ + HTT_TX_DESC_PEER_ID_OFFSET_DWORD + #define HTT_TX_DESC_PEERID_DESC_PADDR_M \ + HTT_TX_DESC_PEER_ID_M + #define HTT_TX_DESC_PEERID_DESC_PADDR_S \ + HTT_TX_DESC_PEER_ID_S + +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_64 16 // to dword with chan freq +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_32 12 // to dword with chan freq +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD_64 \ + (HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_64 >> 2) +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD_32 \ + (HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_32 >> 2) + +#if HTT_PADDR64 +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_64 +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD_64 +#else +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES_32 +#define HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD HTT_TX_DESC_CHAN_FREQ_OFFSET_DWORD_32 +#endif + +#define HTT_TX_DESC_CHAN_FREQ_M 0xffff0000 +#define HTT_TX_DESC_CHAN_FREQ_S 16 + +#define HTT_TX_DESC_PKT_SUBTYPE_GET(_var) \ + (((_var) & HTT_TX_DESC_PKT_SUBTYPE_M) >> HTT_TX_DESC_PKT_SUBTYPE_S) +#define HTT_TX_DESC_PKT_SUBTYPE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_PKT_SUBTYPE, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_PKT_SUBTYPE_S)); \ + } while (0) + +#define HTT_TX_DESC_NO_ENCRYPT_GET(_var) \ + (((_var) & HTT_TX_DESC_NO_ENCRYPT_M) >> HTT_TX_DESC_NO_ENCRYPT_S) +#define HTT_TX_DESC_NO_ENCRYPT_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_NO_ENCRYPT, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_NO_ENCRYPT_S)); \ + } while (0) + +#define HTT_TX_DESC_PKT_TYPE_GET(_var) \ + (((_var) & HTT_TX_DESC_PKT_TYPE_M) >> HTT_TX_DESC_PKT_TYPE_S) +#define HTT_TX_DESC_PKT_TYPE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_PKT_TYPE, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_PKT_TYPE_S)); \ + } while (0) + +#define HTT_TX_DESC_VDEV_ID_GET(_var) \ + (((_var) & HTT_TX_DESC_VDEV_ID_M) >> HTT_TX_DESC_VDEV_ID_S) +#define HTT_TX_DESC_VDEV_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_VDEV_ID, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_VDEV_ID_S)); \ + } while (0) + +#define HTT_TX_DESC_EXT_TID_GET(_var) \ + (((_var) & HTT_TX_DESC_EXT_TID_M) >> HTT_TX_DESC_EXT_TID_S) +#define HTT_TX_DESC_EXT_TID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_EXT_TID, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_EXT_TID_S)); \ + } while (0) + +#define HTT_TX_DESC_POSTPONED_GET(_var) \ + (((_var) & HTT_TX_DESC_POSTPONED_M) >> HTT_TX_DESC_POSTPONED_S) +#define HTT_TX_DESC_POSTPONED_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_POSTPONED, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_POSTPONED_S)); \ + } while (0) + +#define HTT_TX_DESC_FRM_LEN_GET(_var) \ + (((_var) & HTT_TX_DESC_FRM_LEN_M) >> HTT_TX_DESC_FRM_LEN_S) +#define HTT_TX_DESC_FRM_LEN_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_FRM_LEN, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_FRM_LEN_S)); \ + } while (0) + +#define HTT_TX_DESC_FRM_ID_GET(_var) \ + (((_var) & HTT_TX_DESC_FRM_ID_M) >> HTT_TX_DESC_FRM_ID_S) +#define HTT_TX_DESC_FRM_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_FRM_ID, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_FRM_ID_S)); \ + } while (0) + +#define HTT_TX_DESC_CKSUM_OFFLOAD_GET(_var) \ + (((_var) & HTT_TX_DESC_CKSUM_OFFLOAD_M) >> HTT_TX_DESC_CKSUM_OFFLOAD_S) +#define HTT_TX_DESC_CKSUM_OFFLOAD_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_CKSUM_OFFLOAD, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_CKSUM_OFFLOAD_S)); \ + } while (0) + +#define HTT_TX_DESC_TX_COMP_GET(_var) \ + (((_var) & HTT_TX_DESC_TX_COMP_M) >> HTT_TX_DESC_TX_COMP_S) +#define HTT_TX_DESC_TX_COMP_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_TX_COMP, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_TX_COMP_S)); \ + } while (0) + +#define HTT_TX_DESC_PEER_ID_GET(_var) \ + (((_var) & HTT_TX_DESC_PEER_ID_M) >> HTT_TX_DESC_PEER_ID_S) +#define HTT_TX_DESC_PEER_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_PEER_ID, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_PEER_ID_S)); \ + } while (0) + +#define HTT_TX_DESC_CHAN_FREQ_GET(_var) \ + (((_var) & HTT_TX_DESC_CHAN_FREQ_M) >> HTT_TX_DESC_CHAN_FREQ_S) +#define HTT_TX_DESC_CHAN_FREQ_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_DESC_CHAN_FREQ, _val); \ + ((_var) |= ((_val) << HTT_TX_DESC_CHAN_FREQ_S)); \ + } while (0) + + +/* enums used in the HTT tx MSDU extension descriptor */ +enum { + htt_tx_guard_interval_regular = 0, + htt_tx_guard_interval_short = 1, +}; + +enum { + htt_tx_preamble_type_ofdm = 0, + htt_tx_preamble_type_cck = 1, + htt_tx_preamble_type_ht = 2, + htt_tx_preamble_type_vht = 3, +}; + +enum { + htt_tx_bandwidth_5MHz = 0, + htt_tx_bandwidth_10MHz = 1, + htt_tx_bandwidth_20MHz = 2, + htt_tx_bandwidth_40MHz = 3, + htt_tx_bandwidth_80MHz = 4, + htt_tx_bandwidth_160MHz = 5, /* includes 80+80 */ +}; + +/** + * @brief HTT tx MSDU extension descriptor + * @details + * If the target supports HTT tx MSDU extension descriptors, the host has + * the option of appending the following struct following the regular + * HTT tx MSDU descriptor (and setting the "extension" flag in the regular + * HTT tx MSDU descriptor, to show that the extension descriptor is present). + * The HTT tx MSDU extension descriptors allows the host to provide detailed + * tx specs for each frame. + */ +PREPACK struct htt_tx_msdu_desc_ext_t { + /* DWORD 0: flags */ + A_UINT32 + valid_pwr: 1, /* bit 0: if set, tx pwr spec is valid */ + valid_mcs_mask: 1, /* bit 1: if set, tx MCS mask spec is valid */ + valid_nss_mask: 1, /* bit 2: if set, tx Nss mask spec is valid */ + valid_guard_interval: 1, /* bit 3: if set, tx guard intv spec is valid*/ + valid_preamble_type_mask: 1, /* 4: if set, tx preamble mask is valid */ + valid_chainmask: 1, /* bit 5: if set, tx chainmask spec is valid */ + valid_retries: 1, /* bit 6: if set, tx retries spec is valid */ + valid_bandwidth: 1, /* bit 7: if set, tx bandwidth spec is valid */ + valid_expire_tsf: 1, /* bit 8: if set, tx expire TSF spec is valid*/ + is_dsrc: 1, /* bit 9: if set, MSDU is a DSRC frame */ + reserved0_31_7: 22; /* bits 31:10 - unused, set to 0x0 */ + + /* DWORD 1: tx power, tx rate, tx BW */ + A_UINT32 + /* pwr - + * Specify what power the tx frame needs to be transmitted at. + * The power a signed (two's complement) value is in units of 0.5 dBm. + * The value needs to be appropriately sign-extended when extracting + * the value from the message and storing it in a variable that is + * larger than A_INT8. (The HTT_TX_MSDU_EXT_DESC_FLAG_PWR_GET macro + * automatically handles this sign-extension.) + * If the transmission uses multiple tx chains, this power spec is + * the total transmit power, assuming incoherent combination of + * per-chain power to produce the total power. + */ + pwr: 8, + + /* mcs_mask - + * Specify the allowable values for MCS index (modulation and coding) + * to use for transmitting the frame. + * + * For HT / VHT preamble types, this mask directly corresponds to + * the HT or VHT MCS indices that are allowed. For each bit N set + * within the mask, MCS index N is allowed for transmitting the frame. + * For legacy CCK and OFDM rates, separate bits are provided for CCK + * rates versus OFDM rates, so the host has the option of specifying + * that the target must transmit the frame with CCK or OFDM rates + * (not HT or VHT), but leaving the decision to the target whether + * to use CCK or OFDM. + * + * For CCK and OFDM, the bits within this mask are interpreted as + * follows: + * bit 0 -> CCK 1 Mbps rate is allowed + * bit 1 -> CCK 2 Mbps rate is allowed + * bit 2 -> CCK 5.5 Mbps rate is allowed + * bit 3 -> CCK 11 Mbps rate is allowed + * bit 4 -> OFDM BPSK modulation, 1/2 coding rate is allowed + * bit 5 -> OFDM BPSK modulation, 3/4 coding rate is allowed + * bit 6 -> OFDM QPSK modulation, 1/2 coding rate is allowed + * bit 7 -> OFDM QPSK modulation, 3/4 coding rate is allowed + * bit 8 -> OFDM 16-QAM modulation, 1/2 coding rate is allowed + * bit 9 -> OFDM 16-QAM modulation, 3/4 coding rate is allowed + * bit 10 -> OFDM 64-QAM modulation, 2/3 coding rate is allowed + * bit 11 -> OFDM 64-QAM modulation, 3/4 coding rate is allowed + * + * The MCS index specification needs to be compatible with the + * bandwidth mask specification. For example, a MCS index == 9 + * specification is inconsistent with a preamble type == VHT, + * Nss == 1, and channel bandwidth == 20 MHz. + * + * Furthermore, the host has only a limited ability to specify to + * the target to select from HT + legacy rates, or VHT + legacy rates, + * since this mcs_mask can specify either HT/VHT rates or legacy rates. + */ + mcs_mask: 12, + + /* nss_mask - + * Specify which numbers of spatial streams (MIMO factor) are permitted. + * Each bit in this mask corresponds to a Nss value: + * bit 0: if set, Nss = 1 (non-MIMO) is permitted + * bit 1: if set, Nss = 2 (2x2 MIMO) is permitted + * bit 2: if set, Nss = 3 (3x3 MIMO) is permitted + * bit 3: if set, Nss = 4 (4x4 MIMO) is permitted + * The values in the Nss mask must be suitable for the recipient, e.g. + * a value of 0x4 (Nss = 3) cannot be specified for a tx frame to a + * recipient which only supports 2x2 MIMO. + */ + nss_mask: 4, + + /* guard_interval - + * Specify a htt_tx_guard_interval enum value to indicate whether + * the transmission should use a regular guard interval or a + * short guard interval. + */ + guard_interval: 1, + + /* preamble_type_mask - + * Specify which preamble types (CCK, OFDM, HT, VHT) the target + * may choose from for transmitting this frame. + * The bits in this mask correspond to the values in the + * htt_tx_preamble_type enum. For example, to allow the target + * to transmit the frame as either CCK or OFDM, this field would + * be set to + * (1 << htt_tx_preamble_type_ofdm) | + * (1 << htt_tx_preamble_type_cck) + */ + preamble_type_mask: 4, + + reserved1_31_29: 3; /* unused, set to 0x0 */ + + /* DWORD 2: tx chain mask, tx retries */ + A_UINT32 + /* chain_mask - specify which chains to transmit from */ + chain_mask: 4, + + /* retry_limit - + * Specify the maximum number of transmissions, including the + * initial transmission, to attempt before giving up if no ack + * is received. + * If the tx rate is specified, then all retries shall use the + * same rate as the initial transmission. + * If no tx rate is specified, the target can choose whether to + * retain the original rate during the retransmissions, or to + * fall back to a more robust rate. + */ + retry_limit: 4, + + /* bandwidth_mask - + * Specify what channel widths may be used for the transmission. + * A value of zero indicates "don't care" - the target may choose + * the transmission bandwidth. + * The bits within this mask correspond to the htt_tx_bandwidth + * enum values - bit 0 is for 5 MHz, bit 1 is for 10 MHz, etc. + * The bandwidth_mask must be consistent with the preamble_type_mask + * and mcs_mask specs, if they are provided. For example, 80 MHz and + * 160 MHz can only be enabled in the mask if preamble_type == VHT. + */ + bandwidth_mask: 6, + + reserved2_31_14: 18; /* unused, set to 0x0 */ + + /* DWORD 3: tx expiry time (TSF) LSBs */ + A_UINT32 expire_tsf_lo; + + /* DWORD 4: tx expiry time (TSF) MSBs */ + A_UINT32 expire_tsf_hi; + + A_UINT32 reserved_for_future_expansion_set_to_zero[3]; +} POSTPACK; + +/* DWORD 0 */ +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_M 0x00000001 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_S 0 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_M 0x00000002 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_S 1 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_NSS_MASK_M 0x00000004 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_NSS_MASK_S 2 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_M 0x00000008 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_S 3 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_M 0x00000010 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_S 4 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_M 0x00000020 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_S 5 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_M 0x00000040 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_S 6 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_M 0x00000080 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_S 7 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_M 0x00000100 +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_S 8 +#define HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_M 0x00000200 +#define HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_S 9 + +/* DWORD 1 */ +#define HTT_TX_MSDU_EXT_DESC_PWR_M 0x000000ff +#define HTT_TX_MSDU_EXT_DESC_PWR_S 0 +#define HTT_TX_MSDU_EXT_DESC_MCS_MASK_M 0x000fff00 +#define HTT_TX_MSDU_EXT_DESC_MCS_MASK_S 8 +#define HTT_TX_MSDU_EXT_DESC_NSS_MASK_M 0x00f00000 +#define HTT_TX_MSDU_EXT_DESC_NSS_MASK_S 20 +#define HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_M 0x01000000 +#define HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_S 24 +#define HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_M 0x1c000000 +#define HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_S 25 + +/* DWORD 2 */ +#define HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_M 0x0000000f +#define HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_S 0 +#define HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_M 0x000000f0 +#define HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_S 4 +#define HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_M 0x00003f00 +#define HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_S 8 + + +/* DWORD 0 */ +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PWR_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_MCS_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL( \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL, _val); \ + ((_var) |= ((_val) \ + << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_GUARD_INTERVAL_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL( \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK, _val); \ + ((_var) |= ((_val) \ + << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_PREAMBLE_TYPE_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_CHAIN_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_RETRIES_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_BANDWIDTH_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_VALID_EXPIRE_TIME_S));\ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_M) >> \ + HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_S) +#define HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_FLAG_IS_DSRC_S)); \ + } while (0) + + +/* DWORD 1 */ +#define HTT_TX_MSDU_EXT_DESC_PWR_GET_BASE(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_PWR_M) >> \ + HTT_TX_MSDU_EXT_DESC_PWR_S) +#define HTT_TX_MSDU_EXT_DESC_PWR_GET(_var) \ + (HTT_TX_MSDU_EXT_DESC_PWR_GET_BASE(_var) | \ + HTT_SIGN_BIT_EXTENSION_MASK(_var, HTT_TX_MSDU_EXT_DESC_PWR)) +#define HTT_TX_MSDU_EXT_DESC_PWR_SET(_var, _val) \ + ((_var) |= (((_val) << HTT_TX_MSDU_EXT_DESC_PWR_S)) & \ + HTT_TX_MSDU_EXT_DESC_PWR_M) + +#define HTT_TX_MSDU_EXT_DESC_MCS_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_MCS_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_MCS_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_MCS_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_MCS_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_MCS_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_NSS_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_NSS_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_NSS_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_NSS_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_NSS_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_NSS_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_M) >> \ + HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_S) +#define HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_GUARD_INTERVAL_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_PREAMBLE_TYPE_MASK_S)); \ + } while (0) + + +/* DWORD 2 */ +#define HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_CHAIN_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_CHAIN_MASK_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_M) >> \ + HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_S) +#define HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_RETRY_LIMIT_S)); \ + } while (0) + +#define HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_GET(_var) \ + (((_var) & HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_M) >> \ + HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_S) +#define HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK, _val); \ + ((_var) |= ((_val) << HTT_TX_MSDU_EXT_DESC_BANDWIDTH_MASK_S)); \ + } while (0) + + +/** + * @brief MAC DMA rx ring setup specification + * @details + * To allow for dynamic rx ring reconfiguration and to avoid race + * conditions, the host SW never directly programs the MAC DMA rx ring(s) + * it uses. Instead, it sends this message to the target, indicating how + * the rx ring used by the host should be set up and maintained. + * The message consists of a 4-octet header followed by 1 or 2 rx ring setup + * specifications. + * + * |31 16|15 8|7 0| + * |---------------------------------------------------------------| + * header: | reserved | num rings | msg type | + * |---------------------------------------------------------------| + * payload 1: | FW_IDX shadow register physical address (bits 31:0) | +#if HTT_PADDR64 + * | FW_IDX shadow register physical address (bits 63:32) | +#endif + * |---------------------------------------------------------------| + * | rx ring base physical address (bits 31:0) | +#if HTT_PADDR64 + * | rx ring base physical address (bits 63:32) | +#endif + * |---------------------------------------------------------------| + * | rx ring buffer size | rx ring length | + * |---------------------------------------------------------------| + * | FW_IDX initial value | enabled flags | + * |---------------------------------------------------------------| + * | MSDU payload offset | 802.11 header offset | + * |---------------------------------------------------------------| + * | PPDU end offset | PPDU start offset | + * |---------------------------------------------------------------| + * | MPDU end offset | MPDU start offset | + * |---------------------------------------------------------------| + * | MSDU end offset | MSDU start offset | + * |---------------------------------------------------------------| + * | frag info offset | rx attention offset | + * |---------------------------------------------------------------| + * payload 2, if present, has the same format as payload 1 + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx ring configuration message + * Value: 0x2 + * - NUM_RINGS + * Bits 15:8 + * Purpose: indicates whether the host is setting up one rx ring or two + * Value: 1 or 2 + * Payload: + * for systems using 64-bit format for bus addresses: + * - IDX_SHADOW_REG_PADDR_LO + * Bits 31:0 + * Value: lower 4 bytes of physical address of the host's + * FW_IDX shadow register + * - IDX_SHADOW_REG_PADDR_HI + * Bits 31:0 + * Value: upper 4 bytes of physical address of the host's + * FW_IDX shadow register + * - RING_BASE_PADDR_LO + * Bits 31:0 + * Value: lower 4 bytes of physical address of the host's rx ring + * - RING_BASE_PADDR_HI + * Bits 31:0 + * Value: uppper 4 bytes of physical address of the host's rx ring + * for systems using 32-bit format for bus addresses: + * - IDX_SHADOW_REG_PADDR + * Bits 31:0 + * Value: physical address of the host's FW_IDX shadow register + * - RING_BASE_PADDR + * Bits 31:0 + * Value: physical address of the host's rx ring + * - RING_LEN + * Bits 15:0 + * Value: number of elements in the rx ring + * - RING_BUF_SZ + * Bits 31:16 + * Value: size of the buffers referenced by the rx ring, in byte units + * - ENABLED_FLAGS + * Bits 15:0 + * Value: 1-bit flags to show whether different rx fields are enabled + * bit 0: 802.11 header enabled (1) or disabled (0) + * bit 1: MSDU payload enabled (1) or disabled (0) + * bit 2: PPDU start enabled (1) or disabled (0) + * bit 3: PPDU end enabled (1) or disabled (0) + * bit 4: MPDU start enabled (1) or disabled (0) + * bit 5: MPDU end enabled (1) or disabled (0) + * bit 6: MSDU start enabled (1) or disabled (0) + * bit 7: MSDU end enabled (1) or disabled (0) + * bit 8: rx attention enabled (1) or disabled (0) + * bit 9: frag info enabled (1) or disabled (0) + * bit 10: unicast rx enabled (1) or disabled (0) + * bit 11: multicast rx enabled (1) or disabled (0) + * bit 12: ctrl rx enabled (1) or disabled (0) + * bit 13: mgmt rx enabled (1) or disabled (0) + * bit 14: null rx enabled (1) or disabled (0) + * bit 15: phy data rx enabled (1) or disabled (0) + * - IDX_INIT_VAL + * Bits 31:16 + * Purpose: Specify the initial value for the FW_IDX. + * Value: the number of buffers initially present in the host's rx ring + * - OFFSET_802_11_HDR + * Bits 15:0 + * Value: offset in QUAD-bytes of 802.11 header from the buffer start + * - OFFSET_MSDU_PAYLOAD + * Bits 31:16 + * Value: offset in QUAD-bytes of MSDU payload from the buffer start + * - OFFSET_PPDU_START + * Bits 15:0 + * Value: offset in QUAD-bytes of PPDU start rx desc from the buffer start + * - OFFSET_PPDU_END + * Bits 31:16 + * Value: offset in QUAD-bytes of PPDU end rx desc from the buffer start + * - OFFSET_MPDU_START + * Bits 15:0 + * Value: offset in QUAD-bytes of MPDU start rx desc from the buffer start + * - OFFSET_MPDU_END + * Bits 31:16 + * Value: offset in QUAD-bytes of MPDU end rx desc from the buffer start + * - OFFSET_MSDU_START + * Bits 15:0 + * Value: offset in QUAD-bytes of MSDU start rx desc from the buffer start + * - OFFSET_MSDU_END + * Bits 31:16 + * Value: offset in QUAD-bytes of MSDU end rx desc from the buffer start + * - OFFSET_RX_ATTN + * Bits 15:0 + * Value: offset in QUAD-bytes of rx attention word from the buffer start + * - OFFSET_FRAG_INFO + * Bits 31:16 + * Value: offset in QUAD-bytes of frag info table + */ +/* header fields */ +#define HTT_RX_RING_CFG_NUM_RINGS_M 0xff00 +#define HTT_RX_RING_CFG_NUM_RINGS_S 8 + +/* payload fields */ +/* for systems using a 64-bit format for bus addresses */ +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_M 0xffffffff +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_S 0 +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_M 0xffffffff +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_S 0 +#define HTT_RX_RING_CFG_BASE_PADDR_HI_M 0xffffffff +#define HTT_RX_RING_CFG_BASE_PADDR_HI_S 0 +#define HTT_RX_RING_CFG_BASE_PADDR_LO_M 0xffffffff +#define HTT_RX_RING_CFG_BASE_PADDR_LO_S 0 + +/* for systems using a 32-bit format for bus addresses */ +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_M 0xffffffff +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_S 0 +#define HTT_RX_RING_CFG_BASE_PADDR_M 0xffffffff +#define HTT_RX_RING_CFG_BASE_PADDR_S 0 + +#define HTT_RX_RING_CFG_LEN_M 0xffff +#define HTT_RX_RING_CFG_LEN_S 0 +#define HTT_RX_RING_CFG_BUF_SZ_M 0xffff0000 +#define HTT_RX_RING_CFG_BUF_SZ_S 16 +#define HTT_RX_RING_CFG_ENABLED_802_11_HDR_M 0x1 +#define HTT_RX_RING_CFG_ENABLED_802_11_HDR_S 0 +#define HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_M 0x2 +#define HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_S 1 +#define HTT_RX_RING_CFG_ENABLED_PPDU_START_M 0x4 +#define HTT_RX_RING_CFG_ENABLED_PPDU_START_S 2 +#define HTT_RX_RING_CFG_ENABLED_PPDU_END_M 0x8 +#define HTT_RX_RING_CFG_ENABLED_PPDU_END_S 3 +#define HTT_RX_RING_CFG_ENABLED_MPDU_START_M 0x10 +#define HTT_RX_RING_CFG_ENABLED_MPDU_START_S 4 +#define HTT_RX_RING_CFG_ENABLED_MPDU_END_M 0x20 +#define HTT_RX_RING_CFG_ENABLED_MPDU_END_S 5 +#define HTT_RX_RING_CFG_ENABLED_MSDU_START_M 0x40 +#define HTT_RX_RING_CFG_ENABLED_MSDU_START_S 6 +#define HTT_RX_RING_CFG_ENABLED_MSDU_END_M 0x80 +#define HTT_RX_RING_CFG_ENABLED_MSDU_END_S 7 +#define HTT_RX_RING_CFG_ENABLED_RX_ATTN_M 0x100 +#define HTT_RX_RING_CFG_ENABLED_RX_ATTN_S 8 +#define HTT_RX_RING_CFG_ENABLED_FRAG_INFO_M 0x200 +#define HTT_RX_RING_CFG_ENABLED_FRAG_INFO_S 9 +#define HTT_RX_RING_CFG_ENABLED_UCAST_M 0x400 +#define HTT_RX_RING_CFG_ENABLED_UCAST_S 10 +#define HTT_RX_RING_CFG_ENABLED_MCAST_M 0x800 +#define HTT_RX_RING_CFG_ENABLED_MCAST_S 11 +#define HTT_RX_RING_CFG_ENABLED_CTRL_M 0x1000 +#define HTT_RX_RING_CFG_ENABLED_CTRL_S 12 +#define HTT_RX_RING_CFG_ENABLED_MGMT_M 0x2000 +#define HTT_RX_RING_CFG_ENABLED_MGMT_S 13 +#define HTT_RX_RING_CFG_ENABLED_NULL_M 0x4000 +#define HTT_RX_RING_CFG_ENABLED_NULL_S 14 +#define HTT_RX_RING_CFG_ENABLED_PHY_M 0x8000 +#define HTT_RX_RING_CFG_ENABLED_PHY_S 15 +#define HTT_RX_RING_CFG_IDX_INIT_VAL_M 0xffff0000 +#define HTT_RX_RING_CFG_IDX_INIT_VAL_S 16 +#define HTT_RX_RING_CFG_OFFSET_802_11_HDR_M 0xffff +#define HTT_RX_RING_CFG_OFFSET_802_11_HDR_S 0 +#define HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_M 0xffff0000 +#define HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_S 16 +#define HTT_RX_RING_CFG_OFFSET_PPDU_START_M 0xffff +#define HTT_RX_RING_CFG_OFFSET_PPDU_START_S 0 +#define HTT_RX_RING_CFG_OFFSET_PPDU_END_M 0xffff0000 +#define HTT_RX_RING_CFG_OFFSET_PPDU_END_S 16 +#define HTT_RX_RING_CFG_OFFSET_MPDU_START_M 0xffff +#define HTT_RX_RING_CFG_OFFSET_MPDU_START_S 0 +#define HTT_RX_RING_CFG_OFFSET_MPDU_END_M 0xffff0000 +#define HTT_RX_RING_CFG_OFFSET_MPDU_END_S 16 +#define HTT_RX_RING_CFG_OFFSET_MSDU_START_M 0xffff +#define HTT_RX_RING_CFG_OFFSET_MSDU_START_S 0 +#define HTT_RX_RING_CFG_OFFSET_MSDU_END_M 0xffff0000 +#define HTT_RX_RING_CFG_OFFSET_MSDU_END_S 16 +#define HTT_RX_RING_CFG_OFFSET_RX_ATTN_M 0xffff +#define HTT_RX_RING_CFG_OFFSET_RX_ATTN_S 0 +#define HTT_RX_RING_CFG_OFFSET_FRAG_INFO_M 0xffff0000 +#define HTT_RX_RING_CFG_OFFSET_FRAG_INFO_S 16 + +#define HTT_RX_RING_CFG_HDR_BYTES 4 +#define HTT_RX_RING_CFG_PAYLD_BYTES_64 44 +#define HTT_RX_RING_CFG_PAYLD_BYTES_32 36 +#if HTT_PADDR64 + #define HTT_RX_RING_CFG_PAYLD_BYTES HTT_RX_RING_CFG_PAYLD_BYTES_64 +#else + #define HTT_RX_RING_CFG_PAYLD_BYTES HTT_RX_RING_CFG_PAYLD_BYTES_32 +#endif +#define HTT_RX_RING_CFG_BYTES(num_rings) \ + (HTT_RX_RING_CFG_HDR_BYTES + (num_rings) * HTT_RX_RING_CFG_PAYLD_BYTES) + + +#define HTT_RX_RING_CFG_NUM_RINGS_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_NUM_RINGS_M) >> HTT_RX_RING_CFG_NUM_RINGS_S) +#define HTT_RX_RING_CFG_NUM_RINGS_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_NUM_RINGS, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_NUM_RINGS_S)); \ + } while (0) + +/* degenerate case for 32-bit fields */ +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_GET(_var) (_var) +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_SET(_var, _val) (_var) = (_val) +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_GET(_var) (_var) +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_SET(_var, _val) (_var) = (_val) +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_GET(_var) (_var) +#define HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(_var, _val) (_var) = (_val) + +/* degenerate case for 32-bit fields */ +#define HTT_RX_RING_CFG_BASE_PADDR_HI_GET(_var) (_var) +#define HTT_RX_RING_CFG_BASE_PADDR_HI_SET(_var, _val) (_var) = (_val) +#define HTT_RX_RING_CFG_BASE_PADDR_LO_GET(_var) (_var) +#define HTT_RX_RING_CFG_BASE_PADDR_LO_SET(_var, _val) (_var) = (_val) +#define HTT_RX_RING_CFG_BASE_PADDR_GET(_var) (_var) +#define HTT_RX_RING_CFG_BASE_PADDR_SET(_var, _val) (_var) = (_val) + +#define HTT_RX_RING_CFG_LEN_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_LEN_M) >> HTT_RX_RING_CFG_LEN_S) +#define HTT_RX_RING_CFG_LEN_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_LEN, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_LEN_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_BUF_SZ_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_BUF_SZ_M) >> HTT_RX_RING_CFG_BUF_SZ_S) +#define HTT_RX_RING_CFG_BUF_SZ_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_BUF_SZ, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_BUF_SZ_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_IDX_INIT_VAL_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_IDX_INIT_VAL_M) >> \ + HTT_RX_RING_CFG_IDX_INIT_VAL_S) +#define HTT_RX_RING_CFG_IDX_INIT_VAL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_IDX_INIT_VAL, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_IDX_INIT_VAL_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_802_11_HDR_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_802_11_HDR_M) >> \ + HTT_RX_RING_CFG_ENABLED_802_11_HDR_S) +#define HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_802_11_HDR, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_802_11_HDR_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_M) >> \ + HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_S) +#define HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_PPDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_PPDU_START_M) >> \ + HTT_RX_RING_CFG_ENABLED_PPDU_START_S) +#define HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_PPDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_PPDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_PPDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_PPDU_END_M) >> \ + HTT_RX_RING_CFG_ENABLED_PPDU_END_S) +#define HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_PPDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_PPDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MPDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MPDU_START_M) >> \ + HTT_RX_RING_CFG_ENABLED_MPDU_START_S) +#define HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MPDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MPDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MPDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MPDU_END_M) >> \ + HTT_RX_RING_CFG_ENABLED_MPDU_END_S) +#define HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MPDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MPDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MSDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MSDU_START_M) >> \ + HTT_RX_RING_CFG_ENABLED_MSDU_START_S) +#define HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MSDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MSDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MSDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MSDU_END_M) >> \ + HTT_RX_RING_CFG_ENABLED_MSDU_END_S) +#define HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MSDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MSDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_RX_ATTN_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_RX_ATTN_M) >> \ + HTT_RX_RING_CFG_ENABLED_RX_ATTN_S) +#define HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_RX_ATTN, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_RX_ATTN_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_FRAG_INFO_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_FRAG_INFO_M) >> \ + HTT_RX_RING_CFG_ENABLED_FRAG_INFO_S) +#define HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_FRAG_INFO, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_FRAG_INFO_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_UCAST_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_UCAST_M) >> \ + HTT_RX_RING_CFG_ENABLED_UCAST_S) +#define HTT_RX_RING_CFG_ENABLED_UCAST_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_UCAST, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_UCAST_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_ENABLED_MCAST_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MCAST_M) >> \ + HTT_RX_RING_CFG_ENABLED_MCAST_S) +#define HTT_RX_RING_CFG_ENABLED_MCAST_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MCAST, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MCAST_S)); \ + } while (0) +#define HTT_RX_RING_CFG_ENABLED_CTRL_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_CTRL_M) >> \ + HTT_RX_RING_CFG_ENABLED_CTRL_S) +#define HTT_RX_RING_CFG_ENABLED_CTRL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_CTRL, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_CTRL_S)); \ + } while (0) +#define HTT_RX_RING_CFG_ENABLED_MGMT_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_MGMT_M) >> \ + HTT_RX_RING_CFG_ENABLED_MGMT_S) +#define HTT_RX_RING_CFG_ENABLED_MGMT_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_MGMT, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_MGMT_S)); \ + } while (0) +#define HTT_RX_RING_CFG_ENABLED_NULL_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_NULL_M) >> \ + HTT_RX_RING_CFG_ENABLED_NULL_S) +#define HTT_RX_RING_CFG_ENABLED_NULL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_NULL, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_NULL_S)); \ + } while (0) +#define HTT_RX_RING_CFG_ENABLED_PHY_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_ENABLED_PHY_M) >> \ + HTT_RX_RING_CFG_ENABLED_PHY_S) +#define HTT_RX_RING_CFG_ENABLED_PHY_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_ENABLED_PHY, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_ENABLED_PHY_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_802_11_HDR_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_802_11_HDR_M) >> \ + HTT_RX_RING_CFG_OFFSET_802_11_HDR_S) +#define HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_802_11_HDR, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_802_11_HDR_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_M) >> \ + HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_S) +#define HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_PPDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_PPDU_START_M) >> \ + HTT_RX_RING_CFG_OFFSET_PPDU_START_S) +#define HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_PPDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_PPDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_PPDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_PPDU_END_M) >> \ + HTT_RX_RING_CFG_OFFSET_PPDU_END_S) +#define HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_PPDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_PPDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_MPDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_MPDU_START_M) >> \ + HTT_RX_RING_CFG_OFFSET_MPDU_START_S) +#define HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_MPDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_MPDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_MPDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_MPDU_END_M) >> \ + HTT_RX_RING_CFG_OFFSET_MPDU_END_S) +#define HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_MPDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_MPDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_MSDU_START_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_MSDU_START_M) >> \ + HTT_RX_RING_CFG_OFFSET_MSDU_START_S) +#define HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_MSDU_START, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_MSDU_START_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_MSDU_END_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_MSDU_END_M) >> \ + HTT_RX_RING_CFG_OFFSET_MSDU_END_S) +#define HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_MSDU_END, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_MSDU_END_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_RX_ATTN_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_RX_ATTN_M) >> \ + HTT_RX_RING_CFG_OFFSET_RX_ATTN_S) +#define HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_RX_ATTN, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_RX_ATTN_S)); \ + } while (0) + +#define HTT_RX_RING_CFG_OFFSET_FRAG_INFO_GET(_var) \ + (((_var) & HTT_RX_RING_CFG_OFFSET_FRAG_INFO_M) >> \ + HTT_RX_RING_CFG_OFFSET_FRAG_INFO_S) +#define HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_RING_CFG_OFFSET_FRAG_INFO, _val); \ + ((_var) |= ((_val) << HTT_RX_RING_CFG_OFFSET_FRAG_INFO_S)); \ + } while (0) + +/** + * @brief host -> target FW statistics retrieve + * + * @details + * The following field definitions describe the format of the HTT host + * to target FW stats retrieve message. The message specifies the type of + * stats host wants to retrieve. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | stats types request bitmask | msg type | + * |-----------------------------------------------------------| + * | stats types reset bitmask | reserved | + * |-----------------------------------------------------------| + * | stats type | config value | + * |-----------------------------------------------------------| + * | cookie LSBs | + * |-----------------------------------------------------------| + * | cookie MSBs | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a stats upload request message + * Value: 0x3 + * - UPLOAD_TYPES + * Bits 31:8 + * Purpose: identifies which types of FW statistics to upload + * Value: mask with bits set in positions defined by htt_dbg_stats_type + * - RESET_TYPES + * Bits 31:8 + * Purpose: identifies which types of FW statistics to reset + * Value: mask with bits set in positions defined by htt_dbg_stats_type + * - CFG_VAL + * Bits 23:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * if stats type == tx PPDU log, then CONFIG_VAL has the format: + * bits 7:0 - how many per-MPDU byte counts to include in a record + * bits 15:8 - how many per-MPDU MSDU counts to include in a record + * bits 23:16 - how many per-MSDU byte counts to include in a record + * - CFG_STAT_TYPE + * Bits 31:24 + * Purpose: specify which stats type (if any) the config value applies to + * Value: htt_dbg_stats_type value, or 0xff if the message doesn't have + * a valid configuration specification + * - COOKIE_LSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: LSBs of the opaque cookie specified by the host-side requestor + * - COOKIE_MSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: MSBs of the opaque cookie specified by the host-side requestor + */ + +#define HTT_H2T_STATS_REQ_MSG_SZ 20 /* bytes */ + +#define HTT_H2T_STATS_REQ_CFG_STAT_TYPE_INVALID 0xff + +#define HTT_H2T_STATS_REQ_UPLOAD_TYPES_M 0xffffff00 +#define HTT_H2T_STATS_REQ_UPLOAD_TYPES_S 8 + +#define HTT_H2T_STATS_REQ_RESET_TYPES_M 0xffffff00 +#define HTT_H2T_STATS_REQ_RESET_TYPES_S 8 + +#define HTT_H2T_STATS_REQ_CFG_VAL_M 0x00ffffff +#define HTT_H2T_STATS_REQ_CFG_VAL_S 0 + +#define HTT_H2T_STATS_REQ_CFG_STAT_TYPE_M 0xff000000 +#define HTT_H2T_STATS_REQ_CFG_STAT_TYPE_S 24 + +#define HTT_H2T_STATS_REQ_UPLOAD_TYPES_GET(_var) \ + (((_var) & HTT_H2T_STATS_REQ_UPLOAD_TYPES_M) >> \ + HTT_H2T_STATS_REQ_UPLOAD_TYPES_S) +#define HTT_H2T_STATS_REQ_UPLOAD_TYPES_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_STATS_REQ_UPLOAD_TYPES, _val); \ + ((_var) |= ((_val) << HTT_H2T_STATS_REQ_UPLOAD_TYPES_S)); \ + } while (0) + +#define HTT_H2T_STATS_REQ_RESET_TYPES_GET(_var) \ + (((_var) & HTT_H2T_STATS_REQ_RESET_TYPES_M) >> \ + HTT_H2T_STATS_REQ_RESET_TYPES_S) +#define HTT_H2T_STATS_REQ_RESET_TYPES_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_STATS_REQ_RESET_TYPES, _val); \ + ((_var) |= ((_val) << HTT_H2T_STATS_REQ_RESET_TYPES_S)); \ + } while (0) + +#define HTT_H2T_STATS_REQ_CFG_VAL_GET(_var) \ + (((_var) & HTT_H2T_STATS_REQ_CFG_VAL_M) >> \ + HTT_H2T_STATS_REQ_CFG_VAL_S) +#define HTT_H2T_STATS_REQ_CFG_VAL_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_STATS_REQ_CFG_VAL, _val); \ + ((_var) |= ((_val) << HTT_H2T_STATS_REQ_CFG_VAL_S)); \ + } while (0) + +#define HTT_H2T_STATS_REQ_CFG_STAT_TYPE_GET(_var) \ + (((_var) & HTT_H2T_STATS_REQ_CFG_STAT_TYPE_M) >> \ + HTT_H2T_STATS_REQ_CFG_STAT_TYPE_S) +#define HTT_H2T_STATS_REQ_CFG_STAT_TYPE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_STATS_REQ_CFG_STAT_TYPE, _val); \ + ((_var) |= ((_val) << HTT_H2T_STATS_REQ_CFG_STAT_TYPE_S)); \ + } while (0) + +/** + * @brief host -> target HTT out-of-band sync request + * + * @details + * The HTT SYNC tells the target to suspend processing of subsequent + * HTT host-to-target messages until some other target agent locally + * informs the target HTT FW that the current sync counter is equal to + * or greater than (in a modulo sense) the sync counter specified in + * the SYNC message. + * This allows other host-target components to synchronize their operation + * with HTT, e.g. to ensure that tx frames don't get transmitted until a + * security key has been downloaded to and activated by the target. + * In the absence of any explicit synchronization counter value + * specification, the target HTT FW will use zero as the default current + * sync value. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | reserved | sync count | msg type | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a sync message + * Value: 0x4 + * - SYNC_COUNT + * Bits 15:8 + * Purpose: specifies what sync value the HTT FW will wait for from + * an out-of-band specification to resume its operation + * Value: in-band sync counter value to compare against the out-of-band + * counter spec. + * The HTT target FW will suspend its host->target message processing + * as long as + * 0 < (in-band sync counter - out-of-band sync counter) & 0xff < 128 + */ + +#define HTT_H2T_SYNC_MSG_SZ 4 + +#define HTT_H2T_SYNC_COUNT_M 0x0000ff00 +#define HTT_H2T_SYNC_COUNT_S 8 + +#define HTT_H2T_SYNC_COUNT_GET(_var) \ + (((_var) & HTT_H2T_SYNC_COUNT_M) >> \ + HTT_H2T_SYNC_COUNT_S) +#define HTT_H2T_SYNC_COUNT_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_SYNC_COUNT, _val); \ + ((_var) |= ((_val) << HTT_H2T_SYNC_COUNT_S)); \ + } while (0) + + +/** + * @brief HTT aggregation configuration + */ +#define HTT_AGGR_CFG_MSG_SZ 4 + +#define HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_M 0xff00 +#define HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_S 8 +#define HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_M 0x1f0000 +#define HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_S 16 + +#define HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_GET(_var) \ + (((_var) & HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_M) >> \ + HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_S) +#define HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM, _val); \ + ((_var) |= ((_val) << HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_S)); \ + } while (0) + +#define HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_GET(_var) \ + (((_var) & HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_M) >> \ + HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_S) +#define HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM, _val); \ + ((_var) |= ((_val) << HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_S)); \ + } while (0) + + +/** + * @brief host -> target HTT configure max amsdu info per vdev + * + * @details + * The HTT AGGR CFG EX tells the target to configure max_amsdu info per vdev + * + * |31 21|20 16|15 8|7 0| + * |-----------------------------------------------------------| + * | reserved | vdev id | max amsdu | msg type | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a aggr cfg ex message + * Value: 0xa + * - MAX_NUM_AMSDU_SUBFRM + * Bits 15:8 + * Purpose: max MSDUs per A-MSDU + * - VDEV_ID + * Bits 20:16 + * Purpose: ID of the vdev to which this limit is applied + */ +#define HTT_AGGR_CFG_EX_MSG_SZ 4 + +#define HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_M 0xff00 +#define HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_S 8 +#define HTT_AGGR_CFG_EX_VDEV_ID_M 0x1f0000 +#define HTT_AGGR_CFG_EX_VDEV_ID_S 16 + +#define HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_GET(_var) \ + (((_var) & HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_M) >> \ + HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_S) +#define HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM, _val); \ + ((_var) |= ((_val) << HTT_AGGR_CFG_EX_MAX_NUM_AMSDU_SUBFRM_S)); \ + } while (0) + +#define HTT_AGGR_CFG_EX_VDEV_ID_GET(_var) \ + (((_var) & HTT_AGGR_CFG_EX_VDEV_ID_M) >> \ + HTT_AGGR_CFG_EX_VDEV_ID_S) +#define HTT_AGGR_CFG_EX_VDEV_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_AGGR_CFG_EX_VDEV_ID, _val); \ + ((_var) |= ((_val) << HTT_AGGR_CFG_EX_VDEV_ID_S)); \ + } while (0) + +/** + * @brief HTT WDI_IPA Config Message + * + * @details + * The HTT WDI_IPA config message is created/sent by host at driver + * init time. It contains information about data structures used on + * WDI_IPA TX and RX path. + * TX CE ring is used for pushing packet metadata from IPA uC + * to WLAN FW + * TX Completion ring is used for generating TX completions from + * WLAN FW to IPA uC + * RX Indication ring is used for indicating RX packets from FW + * to IPA uC + * RX Ring2 is used as either completion ring or as second + * indication ring. when Ring2 is used as completion ring, IPA uC + * puts completed RX packet meta data to Ring2. when Ring2 is used + * as second indication ring, RX packets for LTE-WLAN aggregation are + * indicated in Ring2, other RX packets (e.g. hotspot related) are + * indicated in RX Indication ring. Please see WDI_IPA specification + * for more details. + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | tx pkt pool size | Rsvd | msg_type | + * |-------------------------------------------------------------------| + * | tx comp ring base (bits 31:0) | +#if HTT_PADDR64 + * | tx comp ring base (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | tx comp ring size | + * |-------------------------------------------------------------------| + * | tx comp WR_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | tx comp WR_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | tx CE WR_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | tx CE WR_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | rx indication ring base (bits 31:0) | +#if HTT_PADDR64 + * | rx indication ring base (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | rx indication ring size | + * |-------------------------------------------------------------------| + * | rx ind RD_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | rx ind RD_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | rx ind WR_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | rx ind WR_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * |-------------------------------------------------------------------| + * | rx ring2 base (bits 31:0) | +#if HTT_PADDR64 + * | rx ring2 base (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | rx ring2 size | + * |-------------------------------------------------------------------| + * | rx ring2 RD_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | rx ring2 RD_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * | rx ring2 WR_IDX physical address (bits 31:0) | +#if HTT_PADDR64 + * | rx ring2 WR_IDX physical address (bits 63:32) | +#endif + * |-------------------------------------------------------------------| + * + * Header fields: + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this as WDI_IPA config message + * value: = 0x8 + * - TX_PKT_POOL_SIZE + * Bits 15:0 + * Purpose: Total number of TX packet buffer pool allocated by Host for + * WDI_IPA TX path + * For systems using 32-bit format for bus addresses: + * - TX_COMP_RING_BASE_ADDR + * Bits 31:0 + * Purpose: TX Completion Ring base address in DDR + * - TX_COMP_RING_SIZE + * Bits 31:0 + * Purpose: TX Completion Ring size (must be power of 2) + * - TX_COMP_WR_IDX_ADDR + * Bits 31:0 + * Purpose: IPA doorbell register address OR DDR address where WIFI FW + * updates the Write Index for WDI_IPA TX completion ring + * - TX_CE_WR_IDX_ADDR + * Bits 31:0 + * Purpose: DDR address where IPA uC + * updates the WR Index for TX CE ring + * (needed for fusion platforms) + * - RX_IND_RING_BASE_ADDR + * Bits 31:0 + * Purpose: RX Indication Ring base address in DDR + * - RX_IND_RING_SIZE + * Bits 31:0 + * Purpose: RX Indication Ring size + * - RX_IND_RD_IDX_ADDR + * Bits 31:0 + * Purpose: DDR address where IPA uC updates the Read Index for WDI_IPA + * RX indication ring + * - RX_IND_WR_IDX_ADDR + * Bits 31:0 + * Purpose: IPA doorbell register address OR DDR address where WIFI FW + * updates the Write Index for WDI_IPA RX indication ring + * - RX_RING2_BASE_ADDR + * Bits 31:0 + * Purpose: Second RX Ring(Indication or completion)base address in DDR + * - RX_RING2_SIZE + * Bits 31:0 + * Purpose: Second RX Ring size (must be >= RX_IND_RING_SIZE) + * - RX_RING2_RD_IDX_ADDR + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, DDR address where + * IPA uC updates the Read Index for Ring2. + * If Second RX ring is completion ring, this is NOT used + * - RX_RING2_WR_IDX_ADDR + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, DDR address where + * WIFI FW updates the Write Index for WDI_IPA RX ring2 + * If second RX ring is completion ring, DDR address where + * IPA uC updates the Write Index for Ring 2. + * For systems using 64-bit format for bus addresses: + * - TX_COMP_RING_BASE_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of TX Completion Ring base physical address in DDR + * - TX_COMP_RING_BASE_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of TX Completion Ring base physical address in DDR + * - TX_COMP_RING_SIZE + * Bits 31:0 + * Purpose: TX Completion Ring size (must be power of 2) + * - TX_COMP_WR_IDX_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of IPA doorbell register address OR + * Lower 4 bytes of DDR address where WIFI FW + * updates the Write Index for WDI_IPA TX completion ring + * - TX_COMP_WR_IDX_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of IPA doorbell register address OR + * Higher 4 bytes of DDR address where WIFI FW + * updates the Write Index for WDI_IPA TX completion ring + * - TX_CE_WR_IDX_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of DDR address where IPA uC + * updates the WR Index for TX CE ring + * (needed for fusion platforms) + * - TX_CE_WR_IDX_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of DDR address where IPA uC + * updates the WR Index for TX CE ring + * (needed for fusion platforms) + * - RX_IND_RING_BASE_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of RX Indication Ring base address in DDR + * - RX_IND_RING_BASE_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of RX Indication Ring base address in DDR + * - RX_IND_RING_SIZE + * Bits 31:0 + * Purpose: RX Indication Ring size + * - RX_IND_RD_IDX_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of DDR address where IPA uC updates the Read Index + * for WDI_IPA RX indication ring + * - RX_IND_RD_IDX_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of DDR address where IPA uC updates the Read Index + * for WDI_IPA RX indication ring + * - RX_IND_WR_IDX_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of IPA doorbell register address OR + * Lower 4 bytes of DDR address where WIFI FW + * updates the Write Index for WDI_IPA RX indication ring + * - RX_IND_WR_IDX_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of IPA doorbell register address OR + * Higher 4 bytes of DDR address where WIFI FW + * updates the Write Index for WDI_IPA RX indication ring + * - RX_RING2_BASE_ADDR_LO + * Bits 31:0 + * Purpose: Lower 4 bytes of Second RX Ring(Indication OR completion)base address in DDR + * - RX_RING2_BASE_ADDR_HI + * Bits 31:0 + * Purpose: Higher 4 bytes of Second RX Ring(Indication OR completion)base address in DDR + * - RX_RING2_SIZE + * Bits 31:0 + * Purpose: Second RX Ring size (must be >= RX_IND_RING_SIZE) + * - RX_RING2_RD_IDX_ADDR_LO + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, lower 4 bytes of + * DDR address where IPA uC updates the Read Index for Ring2. + * If Second RX ring is completion ring, this is NOT used + * - RX_RING2_RD_IDX_ADDR_HI + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, higher 4 bytes of + * DDR address where IPA uC updates the Read Index for Ring2. + * If Second RX ring is completion ring, this is NOT used + * - RX_RING2_WR_IDX_ADDR_LO + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, lower 4 bytes of + * DDR address where WIFI FW updates the Write Index + * for WDI_IPA RX ring2 + * If second RX ring is completion ring, lower 4 bytes of + * DDR address where IPA uC updates the Write Index for Ring 2. + * - RX_RING2_WR_IDX_ADDR_HI + * Bits 31:0 + * Purpose: If Second RX ring is Indication ring, higher 4 bytes of + * DDR address where WIFI FW updates the Write Index + * for WDI_IPA RX ring2 + * If second RX ring is completion ring, higher 4 bytes of + * DDR address where IPA uC updates the Write Index for Ring 2. + */ + +#if HTT_PADDR64 +#define HTT_WDI_IPA_CFG_SZ 88 /* bytes */ +#else +#define HTT_WDI_IPA_CFG_SZ 52 /* bytes */ +#endif + +#define HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_M 0xffff0000 +#define HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_S 16 + +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_SIZE_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_SIZE_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_S 0 + +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_M 0xffffffff +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_S 0 + +#define HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_M) >> HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_S) +#define HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_M) >> HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_S) +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_M) >> HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_M) >> HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_S)); \ + } while (0) + +#define HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_M) >> HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_S) +#define HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_S)); \ + } while (0) + + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_M) >> HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_S)); \ + } while (0) + +#define HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_M) >> HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_S) +#define HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RING_SIZE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_M) >> HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_S)); \ + } while (0) + +#define HTT_WDI_IPA_CFG_RX_RING2_SIZE_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_SIZE_M) >> HTT_WDI_IPA_CFG_RX_RING2_SIZE_S) +#define HTT_WDI_IPA_CFG_RX_RING2_SIZE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_SIZE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_SIZE_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_S)); \ + } while (0) + +/* for systems using 32-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_M) >> HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_S) +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_M) >> HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_S) +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_S)); \ + } while (0) + +/* for systems using 64-bit format for bus addr */ +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_GET(_var) \ + (((_var) & HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_M) >> HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_S) +#define HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_S)); \ + } while (0) + +/* + * TEMPLATE_HTT_WDI_IPA_CONFIG_T: + * This macro defines a htt_wdi_ipa_configXXX_t in which any physical + * addresses are stored in a XXX-bit field. + * This macro is used to define both htt_wdi_ipa_config32_t and + * htt_wdi_ipa_config64_t structs. + */ +#define TEMPLATE_HTT_WDI_IPA_CONFIG_T(_paddr_bits_, \ + _paddr__tx_comp_ring_base_addr_, \ + _paddr__tx_comp_wr_idx_addr_, \ + _paddr__tx_ce_wr_idx_addr_, \ + _paddr__rx_ind_ring_base_addr_, \ + _paddr__rx_ind_rd_idx_addr_, \ + _paddr__rx_ind_wr_idx_addr_, \ + _paddr__rx_ring2_base_addr_,\ + _paddr__rx_ring2_rd_idx_addr_,\ + _paddr__rx_ring2_wr_idx_addr_) \ +PREPACK struct htt_wdi_ipa_cfg ## _paddr_bits_ ## _t \ +{ \ + /* DWORD 0: flags and meta-data */ \ + A_UINT32 \ + msg_type: 8, /* HTT_H2T_MSG_TYPE_WDI_IPA_CFG */ \ + reserved: 8, \ + tx_pkt_pool_size: 16;\ + /* DWORD 1 */\ + _paddr__tx_comp_ring_base_addr_;\ + /* DWORD 2 (or 3)*/\ + A_UINT32 tx_comp_ring_size;\ + /* DWORD 3 (or 4)*/\ + _paddr__tx_comp_wr_idx_addr_;\ + /* DWORD 4 (or 6)*/\ + _paddr__tx_ce_wr_idx_addr_;\ + /* DWORD 5 (or 8)*/\ + _paddr__rx_ind_ring_base_addr_;\ + /* DWORD 6 (or 10)*/\ + A_UINT32 rx_ind_ring_size;\ + /* DWORD 7 (or 11)*/\ + _paddr__rx_ind_rd_idx_addr_;\ + /* DWORD 8 (or 13)*/\ + _paddr__rx_ind_wr_idx_addr_;\ + /* DWORD 9 (or 15)*/\ + _paddr__rx_ring2_base_addr_;\ + /* DWORD 10 (or 17) */\ + A_UINT32 rx_ring2_size;\ + /* DWORD 11 (or 18) */\ + _paddr__rx_ring2_rd_idx_addr_;\ + /* DWORD 12 (or 20) */\ + _paddr__rx_ring2_wr_idx_addr_;\ +} POSTPACK + +/* define a htt_wdi_ipa_config32_t type */ +TEMPLATE_HTT_WDI_IPA_CONFIG_T(32, HTT_VAR_PADDR32(tx_comp_ring_base_addr), HTT_VAR_PADDR32(tx_comp_wr_idx_addr), HTT_VAR_PADDR32(tx_ce_wr_idx_addr), HTT_VAR_PADDR32(rx_ind_ring_base_addr), HTT_VAR_PADDR32(rx_ind_rd_idx_addr),HTT_VAR_PADDR32(rx_ind_wr_idx_addr), HTT_VAR_PADDR32(rx_ring2_base_addr), HTT_VAR_PADDR32(rx_ring2_rd_idx_addr), HTT_VAR_PADDR32(rx_ring2_wr_idx_addr)); + +/* define a htt_wdi_ipa_config64_t type */ +TEMPLATE_HTT_WDI_IPA_CONFIG_T(64, HTT_VAR_PADDR64_LE(tx_comp_ring_base_addr), HTT_VAR_PADDR64_LE(tx_comp_wr_idx_addr), HTT_VAR_PADDR64_LE(tx_ce_wr_idx_addr), HTT_VAR_PADDR64_LE(rx_ind_ring_base_addr), HTT_VAR_PADDR64_LE(rx_ind_rd_idx_addr), HTT_VAR_PADDR64_LE(rx_ind_wr_idx_addr), HTT_VAR_PADDR64_LE(rx_ring2_base_addr), HTT_VAR_PADDR64_LE(rx_ring2_rd_idx_addr), HTT_VAR_PADDR64_LE(rx_ring2_wr_idx_addr)); + +#if HTT_PADDR64 + #define htt_wdi_ipa_cfg_t htt_wdi_ipa_cfg64_t +#else + #define htt_wdi_ipa_cfg_t htt_wdi_ipa_cfg32_t +#endif + +enum htt_wdi_ipa_op_code { + HTT_WDI_IPA_OPCODE_TX_SUSPEND = 0, + HTT_WDI_IPA_OPCODE_TX_RESUME = 1, + HTT_WDI_IPA_OPCODE_RX_SUSPEND = 2, + HTT_WDI_IPA_OPCODE_RX_RESUME = 3, + HTT_WDI_IPA_OPCODE_DBG_STATS = 4, + /* keep this last */ + HTT_WDI_IPA_OPCODE_MAX +}; + +/** + * @brief HTT WDI_IPA Operation Request Message + * + * @details + * HTT WDI_IPA Operation Request message is sent by host + * to either suspend or resume WDI_IPA TX or RX path. + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | op_code | Rsvd | msg_type | + * |-------------------------------------------------------------------| + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this as WDI_IPA Operation Request message + * value: = 0x9 + * - OP_CODE + * Bits 31:16 + * Purpose: Identifies operation host is requesting (e.g. TX suspend) + * value: = enum htt_wdi_ipa_op_code + */ + +PREPACK struct htt_wdi_ipa_op_request_t +{ + /* DWORD 0: flags and meta-data */ + A_UINT32 + msg_type: 8, /* HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQUEST */ + reserved: 8, + op_code: 16; +} POSTPACK; + +#define HTT_WDI_IPA_OP_REQUEST_SZ 4 /* bytes */ + +#define HTT_WDI_IPA_OP_REQUEST_OP_CODE_M 0xffff0000 +#define HTT_WDI_IPA_OP_REQUEST_OP_CODE_S 16 + +#define HTT_WDI_IPA_OP_REQUEST_OP_CODE_GET(_var) \ + (((_var) & HTT_WDI_IPA_OP_REQUEST_OP_CODE_M) >> HTT_WDI_IPA_OP_REQUEST_OP_CODE_S) +#define HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_OP_REQUEST_OP_CODE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_OP_REQUEST_OP_CODE_S)); \ + } while (0) + + + + +/*=== target -> host messages ===============================================*/ + + +enum htt_t2h_msg_type { + HTT_T2H_MSG_TYPE_VERSION_CONF = 0x0, + HTT_T2H_MSG_TYPE_RX_IND = 0x1, + HTT_T2H_MSG_TYPE_RX_FLUSH = 0x2, + HTT_T2H_MSG_TYPE_PEER_MAP = 0x3, + HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4, + HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5, + HTT_T2H_MSG_TYPE_RX_DELBA = 0x6, + HTT_T2H_MSG_TYPE_TX_COMPL_IND = 0x7, + HTT_T2H_MSG_TYPE_PKTLOG = 0x8, + HTT_T2H_MSG_TYPE_STATS_CONF = 0x9, + HTT_T2H_MSG_TYPE_RX_FRAG_IND = 0xa, + HTT_T2H_MSG_TYPE_SEC_IND = 0xb, + DEPRECATED_HTT_T2H_MSG_TYPE_RC_UPDATE_IND = 0xc, /* no longer used */ + HTT_T2H_MSG_TYPE_TX_INSPECT_IND = 0xd, + HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND = 0xe, + /* only used for HL, add HTT MSG for HTT CREDIT update */ + HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND = 0xf, + HTT_T2H_MSG_TYPE_RX_PN_IND = 0x10, + HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND = 0x11, + HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND = 0x12, + /* 0x13 is reserved for RX_RING_LOW_IND (RX Full reordering related) */ + HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE = 0x14, + HTT_T2H_MSG_TYPE_CHAN_CHANGE = 0x15, + HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR = 0x16, + + HTT_T2H_MSG_TYPE_TEST, + /* keep this last */ + HTT_T2H_NUM_MSGS +}; + +/* + * HTT target to host message type - + * stored in bits 7:0 of the first word of the message + */ +#define HTT_T2H_MSG_TYPE_M 0xff +#define HTT_T2H_MSG_TYPE_S 0 + +#define HTT_T2H_MSG_TYPE_SET(word, msg_type) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_MSG_TYPE, msg_type); \ + (word) |= ((msg_type) << HTT_T2H_MSG_TYPE_S); \ + } while (0) +#define HTT_T2H_MSG_TYPE_GET(word) \ + (((word) & HTT_T2H_MSG_TYPE_M) >> HTT_T2H_MSG_TYPE_S) + +/** + * @brief target -> host version number confirmation message definition + * + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | reserved | major number | minor number | msg type | + * |-------------------------------------------------------------------| + * : option request TLV (optional) | + * :...................................................................: + * + * The VER_CONF message may consist of a single 4-byte word, or may be + * extended with TLVs that specify HTT options selected by the target. + * The following option TLVs may be appended to the VER_CONF message: + * - LL_BUS_ADDR_SIZE + * - HL_SUPPRESS_TX_COMPL_IND + * - MAX_TX_QUEUE_GROUPS + * These TLVs may appear in an arbitrary order. Any number of these TLVs + * may be appended to the VER_CONF message (but only one TLV of each type). + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a version number confirmation message + * Value: 0x0 + * - VER_MINOR + * Bits 15:8 + * Purpose: Specify the minor number of the HTT message library version + * in use by the target firmware. + * The minor number specifies the specific revision within a range + * of fundamentally compatible HTT message definition revisions. + * Compatible revisions involve adding new messages or perhaps + * adding new fields to existing messages, in a backwards-compatible + * manner. + * Incompatible revisions involve changing the message type values, + * or redefining existing messages. + * Value: minor number + * - VER_MAJOR + * Bits 15:8 + * Purpose: Specify the major number of the HTT message library version + * in use by the target firmware. + * The major number specifies the family of minor revisions that are + * fundamentally compatible with each other, but not with prior or + * later families. + * Value: major number + */ + +#define HTT_VER_CONF_MINOR_M 0x0000ff00 +#define HTT_VER_CONF_MINOR_S 8 +#define HTT_VER_CONF_MAJOR_M 0x00ff0000 +#define HTT_VER_CONF_MAJOR_S 16 + + +#define HTT_VER_CONF_MINOR_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_VER_CONF_MINOR, value); \ + (word) |= (value) << HTT_VER_CONF_MINOR_S; \ + } while (0) +#define HTT_VER_CONF_MINOR_GET(word) \ + (((word) & HTT_VER_CONF_MINOR_M) >> HTT_VER_CONF_MINOR_S) + +#define HTT_VER_CONF_MAJOR_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_VER_CONF_MAJOR, value); \ + (word) |= (value) << HTT_VER_CONF_MAJOR_S; \ + } while (0) +#define HTT_VER_CONF_MAJOR_GET(word) \ + (((word) & HTT_VER_CONF_MAJOR_M) >> HTT_VER_CONF_MAJOR_S) + + +#define HTT_VER_CONF_BYTES 4 + + +/** + * @brief - target -> host HTT Rx In order indication message + * + * @details + * + * |31 24|23 |15|14|13|12|11|10|9|8|7|6|5|4 0| + * |----------------+-------------------+---------------------+---------------| + * | peer ID | | F| O| ext TID | msg type | + * |--------------------------------------------------------------------------| + * | MSDU count | Reserved | vdev id | + * |--------------------------------------------------------------------------| + * | MSDU 0 bus address (bits 31:0) | +#if HTT_PADDR64 + * | MSDU 0 bus address (bits 63:32) | +#endif + * |--------------------------------------------------------------------------| + * | MSDU info | MSDU 0 FW Desc | MSDU 0 Length | + * |--------------------------------------------------------------------------| + * | MSDU 1 bus address (bits 31:0) | +#if HTT_PADDR64 + * | MSDU 1 bus address (bits 63:32) | +#endif + * |--------------------------------------------------------------------------| + * | MSDU info | MSDU 1 FW Desc | MSDU 1 Length | + * |--------------------------------------------------------------------------| + */ + + +/** @brief - MSDU info byte for TCP_CHECKSUM_OFFLOAD use + * + * @details + * bits + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * |-----+----+-------+--------+--------+---------+---------+-----------| + * | reserved | is IP | is UDP | is TCP | is IPv6 |IP chksum| TCP/UDP | + * | | frag | | | | fail |chksum fail| + * |-----+----+-------+--------+--------+---------+---------+-----------| + * (see fw_rx_msdu_info def in wal_rx_desc.h) + */ + +struct htt_rx_in_ord_paddr_ind_hdr_t +{ + A_UINT32 /* word 0 */ + msg_type: 8, + ext_tid: 5, + offload: 1, + frag: 1, + reserved_0: 1, + peer_id: 16; + + A_UINT32 /* word 1 */ + vap_id: 8, + reserved_1: 8, + msdu_cnt: 16; +}; + +struct htt_rx_in_ord_paddr_ind_msdu32_t +{ + A_UINT32 dma_addr; + A_UINT32 + length: 16, + fw_desc: 8, + msdu_info:8; +}; +struct htt_rx_in_ord_paddr_ind_msdu64_t +{ + A_UINT32 dma_addr_lo; + A_UINT32 dma_addr_hi; + A_UINT32 + length: 16, + fw_desc: 8, + msdu_info:8; +}; +#if HTT_PADDR64 + #define htt_rx_in_ord_paddr_ind_msdu_t htt_rx_in_ord_paddr_ind_msdu64_t +#else + #define htt_rx_in_ord_paddr_ind_msdu_t htt_rx_in_ord_paddr_ind_msdu32_t +#endif + + +#define HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES (sizeof(struct htt_rx_in_ord_paddr_ind_hdr_t)) +#define HTT_RX_IN_ORD_PADDR_IND_HDR_DWORDS (HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES >> 2) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTE_OFFSET HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORD_OFFSET HTT_RX_IN_ORD_PADDR_IND_HDR_DWORDS +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES_64 (sizeof(struct htt_rx_in_ord_paddr_ind_msdu64_t)) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS_64 (HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES_64 >> 2) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES_32 (sizeof(struct htt_rx_in_ord_paddr_ind_msdu32_t)) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS_32 (HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES_32 >> 2) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES (sizeof(struct htt_rx_in_ord_paddr_ind_msdu_t)) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS (HTT_RX_IN_ORD_PADDR_IND_MSDU_BYTES >> 2) + +#define HTT_RX_IN_ORD_PADDR_IND_EXT_TID_M 0x00001f00 +#define HTT_RX_IN_ORD_PADDR_IND_EXT_TID_S 8 +#define HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_M 0x00002000 +#define HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_S 13 +#define HTT_RX_IN_ORD_PADDR_IND_FRAG_M 0x00004000 +#define HTT_RX_IN_ORD_PADDR_IND_FRAG_S 14 +#define HTT_RX_IN_ORD_PADDR_IND_PEER_ID_M 0xffff0000 +#define HTT_RX_IN_ORD_PADDR_IND_PEER_ID_S 16 +#define HTT_RX_IN_ORD_PADDR_IND_VAP_ID_M 0x000000ff +#define HTT_RX_IN_ORD_PADDR_IND_VAP_ID_S 0 +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_M 0xffff0000 +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_S 16 +/* for systems using 64-bit format for bus addresses */ +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_M 0xffffffff +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_S 0 +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_M 0xffffffff +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_S 0 +/* for systems using 32-bit format for bus addresses */ +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_M 0xffffffff +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_S 0 +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_M 0x0000ffff +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_S 0 +#define HTT_RX_IN_ORD_PADDR_IND_FW_DESC_M 0x00ff0000 +#define HTT_RX_IN_ORD_PADDR_IND_FW_DESC_S 16 +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_M 0xff000000 +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_S 24 + + +#define HTT_RX_IN_ORD_PADDR_IND_EXT_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_EXT_TID, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_EXT_TID_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_EXT_TID_M) >> HTT_RX_IN_ORD_PADDR_IND_EXT_TID_S) + +#define HTT_RX_IN_ORD_PADDR_IND_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_PEER_ID, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_PEER_ID_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_PEER_ID_M) >> HTT_RX_IN_ORD_PADDR_IND_PEER_ID_S) + +#define HTT_RX_IN_ORD_PADDR_IND_VAP_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_VAP_ID, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_VAP_ID_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_VAP_ID_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_VAP_ID_M) >> HTT_RX_IN_ORD_PADDR_IND_VAP_ID_S) + +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_M) >> HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_S) + +/* for systems using 64-bit format for bus addresses */ +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_PADDR_HI, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_M) >> HTT_RX_IN_ORD_PADDR_IND_PADDR_HI_S) +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_PADDR_LO, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_M) >> HTT_RX_IN_ORD_PADDR_IND_PADDR_LO_S) + +/* for systems using 32-bit format for bus addresses */ +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_PADDR, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_PADDR_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_PADDR_M) >> HTT_RX_IN_ORD_PADDR_IND_PADDR_S) + +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_M) >> HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_S) + +#define HTT_RX_IN_ORD_PADDR_IND_FW_DESC_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_FW_DESC, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_FW_DESC_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_FW_DESC_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_FW_DESC_M) >> HTT_RX_IN_ORD_PADDR_IND_FW_DESC_S) + +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO, value); \ + (word) |= (value) << HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_M) >> HTT_RX_IN_ORD_PADDR_IND_MSDU_INFO_S) + +#define HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_IND_OFFLOAD, value); \ + (word) |= (value) << HTT_RX_IN_ORD_IND_OFFLOAD_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_M) >> HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_S) + +#define HTT_RX_IN_ORD_PADDR_IND_FRAG_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IN_ORD_IND_FRAG, value); \ + (word) |= (value) << HTT_RX_IN_ORD_IND_FRAG_S; \ + } while (0) +#define HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(word) \ + (((word) & HTT_RX_IN_ORD_PADDR_IND_FRAG_M) >> HTT_RX_IN_ORD_PADDR_IND_FRAG_S) + +/* definitions used within target -> host rx indication message */ + +PREPACK struct htt_rx_ind_hdr_prefix_t +{ + A_UINT32 /* word 0 */ + msg_type: 8, + ext_tid: 5, + release_valid: 1, + flush_valid: 1, + reserved0: 1, + peer_id: 16; + + A_UINT32 /* word 1 */ + flush_start_seq_num: 6, + flush_end_seq_num: 6, + release_start_seq_num: 6, + release_end_seq_num: 6, + num_mpdu_ranges: 8; +} POSTPACK; + +#define HTT_RX_IND_HDR_PREFIX_BYTES (sizeof(struct htt_rx_ind_hdr_prefix_t)) +#define HTT_RX_IND_HDR_PREFIX_SIZE32 (HTT_RX_IND_HDR_PREFIX_BYTES >> 2) + +#define HTT_TGT_RSSI_INVALID 0x80 + +PREPACK struct htt_rx_ppdu_desc_t +{ + #define HTT_RX_IND_PPDU_OFFSET_WORD_RSSI_CMB 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_TIMESTAMP_SUBMICROSEC 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_PHY_ERR_CODE 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_PHY_ERR 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_LEGACY_RATE 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_LEGACY_RATE_SEL 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_END_VALID 0 + #define HTT_RX_IND_PPDU_OFFSET_WORD_START_VALID 0 + A_UINT32 /* word 0 */ + rssi_cmb: 8, + timestamp_submicrosec: 8, + phy_err_code: 8, + phy_err: 1, + legacy_rate: 4, + legacy_rate_sel: 1, + end_valid: 1, + start_valid: 1; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_RSSI0 1 + union { + A_UINT32 /* word 1 */ + rssi0_pri20: 8, + rssi0_ext20: 8, + rssi0_ext40: 8, + rssi0_ext80: 8; + A_UINT32 rssi0; /* access all 20/40/80 per-bandwidth RSSIs together */ + } u0; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_RSSI1 2 + union { + A_UINT32 /* word 2 */ + rssi1_pri20: 8, + rssi1_ext20: 8, + rssi1_ext40: 8, + rssi1_ext80: 8; + A_UINT32 rssi1; /* access all 20/40/80 per-bandwidth RSSIs together */ + } u1; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_RSSI2 3 + union { + A_UINT32 /* word 3 */ + rssi2_pri20: 8, + rssi2_ext20: 8, + rssi2_ext40: 8, + rssi2_ext80: 8; + A_UINT32 rssi2; /* access all 20/40/80 per-bandwidth RSSIs together */ + } u2; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_RSSI3 4 + union { + A_UINT32 /* word 4 */ + rssi3_pri20: 8, + rssi3_ext20: 8, + rssi3_ext40: 8, + rssi3_ext80: 8; + A_UINT32 rssi3; /* access all 20/40/80 per-bandwidth RSSIs together */ + } u3; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_TSF32 5 + A_UINT32 tsf32; /* word 5 */ + + #define HTT_RX_IND_PPDU_OFFSET_WORD_TIMESTAMP_MICROSEC 6 + A_UINT32 timestamp_microsec; /* word 6 */ + + #define HTT_RX_IND_PPDU_OFFSET_WORD_PREAMBLE_TYPE 7 + #define HTT_RX_IND_PPDU_OFFSET_WORD_VHT_SIG_A1 7 + A_UINT32 /* word 7 */ + vht_sig_a1: 24, + preamble_type: 8; + + #define HTT_RX_IND_PPDU_OFFSET_WORD_VHT_SIG_A2 8 + A_UINT32 /* word 8 */ + vht_sig_a2: 24, + reserved0: 8; +} POSTPACK; + +#define HTT_RX_PPDU_DESC_BYTES (sizeof(struct htt_rx_ppdu_desc_t)) +#define HTT_RX_PPDU_DESC_SIZE32 (HTT_RX_PPDU_DESC_BYTES >> 2) + +PREPACK struct htt_rx_ind_hdr_suffix_t +{ + A_UINT32 /* word 0 */ + fw_rx_desc_bytes: 16, + reserved0: 16; +} POSTPACK; + +#define HTT_RX_IND_HDR_SUFFIX_BYTES (sizeof(struct htt_rx_ind_hdr_suffix_t)) +#define HTT_RX_IND_HDR_SUFFIX_SIZE32 (HTT_RX_IND_HDR_SUFFIX_BYTES >> 2) + +PREPACK struct htt_rx_ind_hdr_t +{ + struct htt_rx_ind_hdr_prefix_t prefix; + struct htt_rx_ppdu_desc_t rx_ppdu_desc; + struct htt_rx_ind_hdr_suffix_t suffix; +} POSTPACK; + +#define HTT_RX_IND_HDR_BYTES (sizeof(struct htt_rx_ind_hdr_t)) +#define HTT_RX_IND_HDR_SIZE32 (HTT_RX_IND_HDR_BYTES >> 2) + +/* confirm that HTT_RX_IND_HDR_BYTES is a multiple of 4 */ +A_COMPILE_TIME_ASSERT(HTT_RX_IND_hdr_size_quantum, + (HTT_RX_IND_HDR_BYTES & 0x3) == 0); + +/* + * HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET: + * the offset into the HTT rx indication message at which the + * FW rx PPDU descriptor resides + */ +#define HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET HTT_RX_IND_HDR_PREFIX_BYTES + +/* + * HTT_RX_IND_HDR_SUFFIX_BYTE_OFFSET: + * the offset into the HTT rx indication message at which the + * header suffix (FW rx MSDU byte count) resides + */ +#define HTT_RX_IND_HDR_SUFFIX_BYTE_OFFSET \ + (HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET + HTT_RX_PPDU_DESC_BYTES) + +/* + * HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET: + * the offset into the HTT rx indication message at which the per-MSDU + * information starts + * Bytes 0-7 are the message header; bytes 8-11 contain the length of the + * per-MSDU information portion of the message. The per-MSDU info itself + * starts at byte 12. + */ +#define HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET HTT_RX_IND_HDR_BYTES + + +/** + * @brief target -> host rx indication message definition + * + * @details + * The following field definitions describe the format of the rx indication + * message sent from the target to the host. + * The message consists of three major sections: + * 1. a fixed-length header + * 2. a variable-length list of firmware rx MSDU descriptors + * 3. one or more 4-octet MPDU range information elements + * The fixed length header itself has two sub-sections + * 1. the message meta-information, including identification of the + * sender and type of the received data, and a 4-octet flush/release IE + * 2. the firmware rx PPDU descriptor + * + * The format of the message is depicted below. + * in this depiction, the following abbreviations are used for information + * elements within the message: + * - SV - start valid: this flag is set if the FW rx PPDU descriptor + * elements associated with the PPDU start are valid. + * Specifically, the following fields are valid only if SV is set: + * RSSI (all variants), L, legacy rate, preamble type, service, + * VHT-SIG-A + * - EV - end valid: this flag is set if the FW rx PPDU descriptor + * elements associated with the PPDU end are valid. + * Specifically, the following fields are valid only if EV is set: + * P, PHY err code, TSF, microsec / sub-microsec timestamp + * - L - Legacy rate selector - if legacy rates are used, this flag + * indicates whether the rate is from a CCK (L == 1) or OFDM + * (L == 0) PHY. + * - P - PHY error flag - boolean indication of whether the rx frame had + * a PHY error + * + * |31 24|23 18|17|16|15|14|13|12|11|10|9|8|7|6|5|4 0| + * |----------------+-------------------+---------------------+---------------| + * | peer ID | |RV|FV| ext TID | msg type | + * |--------------------------------------------------------------------------| + * | num | release | release | flush | flush | + * | MPDU | end | start | end | start | + * | ranges | seq num | seq num | seq num | seq num | + * |==========================================================================| + * |S|E|L| legacy |P| PHY err code | sub-microsec | combined | + * |V|V| | rate | | | timestamp | RSSI | + * |--------------------------------------------------------------------------| + * | RSSI rx0 ext80 | RSSI rx0 ext40 | RSSI rx0 ext20 | RSSI rx0 pri20| + * |--------------------------------------------------------------------------| + * | RSSI rx1 ext80 | RSSI rx1 ext40 | RSSI rx1 ext20 | RSSI rx1 pri20| + * |--------------------------------------------------------------------------| + * | RSSI rx2 ext80 | RSSI rx2 ext40 | RSSI rx2 ext20 | RSSI rx2 pri20| + * |--------------------------------------------------------------------------| + * | RSSI rx3 ext80 | RSSI rx3 ext40 | RSSI rx3 ext20 | RSSI rx3 pri20| + * |--------------------------------------------------------------------------| + * | TSF LSBs | + * |--------------------------------------------------------------------------| + * | microsec timestamp | + * |--------------------------------------------------------------------------| + * | preamble type | HT-SIG / VHT-SIG-A1 | + * |--------------------------------------------------------------------------| + * | service | HT-SIG / VHT-SIG-A2 | + * |==========================================================================| + * | reserved | FW rx desc bytes | + * |--------------------------------------------------------------------------| + * | MSDU Rx | MSDU Rx | MSDU Rx | MSDU Rx | + * | desc B3 | desc B2 | desc B1 | desc B0 | + * |--------------------------------------------------------------------------| + * : : : + * |--------------------------------------------------------------------------| + * | alignment | MSDU Rx | + * | padding | desc Bn | + * |--------------------------------------------------------------------------| + * | reserved | MPDU range status | MPDU count | + * |--------------------------------------------------------------------------| + * : reserved : MPDU range status : MPDU count : + * :- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - : + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx indication message + * Value: 0x1 + * - EXT_TID + * Bits 12:8 + * Purpose: identify the traffic ID of the rx data, including + * special "extended" TID values for multicast, broadcast, and + * non-QoS data frames + * Value: 0-15 for regular TIDs, or >= 16 for bcast/mcast/non-QoS + * - FLUSH_VALID (FV) + * Bit 13 + * Purpose: indicate whether the flush IE (start/end sequence numbers) + * is valid + * Value: + * 1 -> flush IE is valid and needs to be processed + * 0 -> flush IE is not valid and should be ignored + * - REL_VALID (RV) + * Bit 13 + * Purpose: indicate whether the release IE (start/end sequence numbers) + * is valid + * Value: + * 1 -> release IE is valid and needs to be processed + * 0 -> release IE is not valid and should be ignored + * - PEER_ID + * Bits 31:16 + * Purpose: Identify, by ID, which peer sent the rx data + * Value: ID of the peer who sent the rx data + * - FLUSH_SEQ_NUM_START + * Bits 5:0 + * Purpose: Indicate the start of a series of MPDUs to flush + * Not all MPDUs within this series are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * This field is only valid if the FV bit is set. + * Value: + * The sequence number for the first MPDUs to check to flush. + * The sequence number is masked by 0x3f. + * - FLUSH_SEQ_NUM_END + * Bits 11:6 + * Purpose: Indicate the end of a series of MPDUs to flush + * Value: + * The sequence number one larger than the sequence number of the + * last MPDU to check to flush. + * The sequence number is masked by 0x3f. + * Not all MPDUs within this series are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * This field is only valid if the FV bit is set. + * - REL_SEQ_NUM_START + * Bits 17:12 + * Purpose: Indicate the start of a series of MPDUs to release. + * All MPDUs within this series are present and valid - the host + * need not check each sequence number within this range to see if + * the corresponding MPDU is actually present. + * This field is only valid if the RV bit is set. + * Value: + * The sequence number for the first MPDUs to check to release. + * The sequence number is masked by 0x3f. + * - REL_SEQ_NUM_END + * Bits 23:18 + * Purpose: Indicate the end of a series of MPDUs to release. + * Value: + * The sequence number one larger than the sequence number of the + * last MPDU to check to release. + * The sequence number is masked by 0x3f. + * All MPDUs within this series are present and valid - the host + * need not check each sequence number within this range to see if + * the corresponding MPDU is actually present. + * This field is only valid if the RV bit is set. + * - NUM_MPDU_RANGES + * Bits 31:24 + * Purpose: Indicate how many ranges of MPDUs are present. + * Each MPDU range consists of a series of contiguous MPDUs within the + * rx frame sequence which all have the same MPDU status. + * Value: 1-63 (typically a small number, like 1-3) + * + * Rx PPDU descriptor fields: + * - RSSI_CMB + * Bits 7:0 + * Purpose: Combined RSSI from all active rx chains, across the active + * bandwidth. + * Value: RSSI dB units w.r.t. noise floor + * - TIMESTAMP_SUBMICROSEC + * Bits 15:8 + * Purpose: high-resolution timestamp + * Value: + * Sub-microsecond time of PPDU reception. + * This timestamp ranges from [0,MAC clock MHz). + * This timestamp can be used in conjunction with TIMESTAMP_MICROSEC + * to form a high-resolution, large range rx timestamp. + * - PHY_ERR_CODE + * Bits 23:16 + * Purpose: + * If the rx frame processing resulted in a PHY error, indicate what + * type of rx PHY error occurred. + * Value: + * This field is valid if the "P" (PHY_ERR) flag is set. + * TBD: document/specify the values for this field + * - PHY_ERR + * Bit 24 + * Purpose: indicate whether the rx PPDU had a PHY error + * Value: 0 -> no rx PHY error, 1 -> rx PHY error encountered + * - LEGACY_RATE + * Bits 28:25 + * Purpose: + * If the rx frame used a legacy rate rather than a HT or VHT rate, + * specify which rate was used. + * Value: + * The LEGACY_RATE field's value depends on the "L" (LEGACY_RATE_SEL) + * flag. + * If LEGACY_RATE_SEL is 0: + * 0x8: OFDM 48 Mbps + * 0x9: OFDM 24 Mbps + * 0xA: OFDM 12 Mbps + * 0xB: OFDM 6 Mbps + * 0xC: OFDM 54 Mbps + * 0xD: OFDM 36 Mbps + * 0xE: OFDM 18 Mbps + * 0xF: OFDM 9 Mbps + * If LEGACY_RATE_SEL is 1: + * 0x8: CCK 11 Mbps long preamble + * 0x9: CCK 5.5 Mbps long preamble + * 0xA: CCK 2 Mbps long preamble + * 0xB: CCK 1 Mbps long preamble + * 0xC: CCK 11 Mbps short preamble + * 0xD: CCK 5.5 Mbps short preamble + * 0xE: CCK 2 Mbps short preamble + * - LEGACY_RATE_SEL + * Bit 29 + * Purpose: if rx used a legacy rate, specify whether it was OFDM or CCK + * Value: + * This field is valid if the PREAMBLE_TYPE field indicates the rx + * used a legacy rate. + * 0 -> OFDM, 1 -> CCK + * - END_VALID + * Bit 30 + * Purpose: Indicate whether the FW rx PPDU desc fields associated with + * the start of the PPDU are valid. Specifically, the following + * fields are only valid if END_VALID is set: + * PHY_ERR, PHY_ERR_CODE, TSF32, TIMESTAMP_MICROSEC, + * TIMESTAMP_SUBMICROSEC + * Value: + * 0 -> rx PPDU desc end fields are not valid + * 1 -> rx PPDU desc end fields are valid + * - START_VALID + * Bit 31 + * Purpose: Indicate whether the FW rx PPDU desc fields associated with + * the end of the PPDU are valid. Specifically, the following + * fields are only valid if START_VALID is set: + * RSSI, LEGACY_RATE_SEL, LEGACY_RATE, PREAMBLE_TYPE, SERVICE, + * VHT-SIG-A + * Value: + * 0 -> rx PPDU desc start fields are not valid + * 1 -> rx PPDU desc start fields are valid + * - RSSI0_PRI20 + * Bits 7:0 + * Purpose: RSSI from chain 0 on the primary 20 MHz channel + * Value: RSSI dB units w.r.t. noise floor + * + * - RSSI0_EXT20 + * Bits 7:0 + * Purpose: RSSI from chain 0 on the bonded extension 20 MHz channel + * (if the rx bandwidth was >= 40 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI0_EXT40 + * Bits 7:0 + * Purpose: RSSI from chain 0 on the bonded extension 40 MHz channel + * (if the rx bandwidth was >= 80 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI0_EXT80 + * Bits 7:0 + * Purpose: RSSI from chain 0 on the bonded extension 80 MHz channel + * (if the rx bandwidth was >= 160 MHz) + * Value: RSSI dB units w.r.t. noise floor + * + * - RSSI1_PRI20 + * Bits 7:0 + * Purpose: RSSI from chain 1 on the primary 20 MHz channel + * Value: RSSI dB units w.r.t. noise floor + * - RSSI1_EXT20 + * Bits 7:0 + * Purpose: RSSI from chain 1 on the bonded extension 20 MHz channel + * (if the rx bandwidth was >= 40 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI1_EXT40 + * Bits 7:0 + * Purpose: RSSI from chain 1 on the bonded extension 40 MHz channel + * (if the rx bandwidth was >= 80 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI1_EXT80 + * Bits 7:0 + * Purpose: RSSI from chain 1 on the bonded extension 80 MHz channel + * (if the rx bandwidth was >= 160 MHz) + * Value: RSSI dB units w.r.t. noise floor + * + * - RSSI2_PRI20 + * Bits 7:0 + * Purpose: RSSI from chain 2 on the primary 20 MHz channel + * Value: RSSI dB units w.r.t. noise floor + * - RSSI2_EXT20 + * Bits 7:0 + * Purpose: RSSI from chain 2 on the bonded extension 20 MHz channel + * (if the rx bandwidth was >= 40 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI2_EXT40 + * Bits 7:0 + * Purpose: RSSI from chain 2 on the bonded extension 40 MHz channel + * (if the rx bandwidth was >= 80 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI2_EXT80 + * Bits 7:0 + * Purpose: RSSI from chain 2 on the bonded extension 80 MHz channel + * (if the rx bandwidth was >= 160 MHz) + * Value: RSSI dB units w.r.t. noise floor + * + * - RSSI3_PRI20 + * Bits 7:0 + * Purpose: RSSI from chain 3 on the primary 20 MHz channel + * Value: RSSI dB units w.r.t. noise floor + * - RSSI3_EXT20 + * Bits 7:0 + * Purpose: RSSI from chain 3 on the bonded extension 20 MHz channel + * (if the rx bandwidth was >= 40 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI3_EXT40 + * Bits 7:0 + * Purpose: RSSI from chain 3 on the bonded extension 40 MHz channel + * (if the rx bandwidth was >= 80 MHz) + * Value: RSSI dB units w.r.t. noise floor + * - RSSI3_EXT80 + * Bits 7:0 + * Purpose: RSSI from chain 3 on the bonded extension 80 MHz channel + * (if the rx bandwidth was >= 160 MHz) + * Value: RSSI dB units w.r.t. noise floor + * + * - TSF32 + * Bits 31:0 + * Purpose: specify the time the rx PPDU was received, in TSF units + * Value: 32 LSBs of the TSF + * - TIMESTAMP_MICROSEC + * Bits 31:0 + * Purpose: specify the time the rx PPDU was received, in microsecond units + * Value: PPDU rx time, in microseconds + * - VHT_SIG_A1 + * Bits 23:0 + * Purpose: Provide the HT-SIG (initial 24 bits) or VHT-SIG-A1 field + * from the rx PPDU + * Value: + * If PREAMBLE_TYPE specifies VHT, then this field contains the + * VHT-SIG-A1 data. + * If PREAMBLE_TYPE specifies HT, then this field contains the + * first 24 bits of the HT-SIG data. + * Otherwise, this field is invalid. + * Refer to the the 802.11 protocol for the definition of the + * HT-SIG and VHT-SIG-A1 fields + * - VHT_SIG_A2 + * Bits 23:0 + * Purpose: Provide the HT-SIG (final 24 bits) or VHT-SIG-A2 field + * from the rx PPDU + * Value: + * If PREAMBLE_TYPE specifies VHT, then this field contains the + * VHT-SIG-A2 data. + * If PREAMBLE_TYPE specifies HT, then this field contains the + * last 24 bits of the HT-SIG data. + * Otherwise, this field is invalid. + * Refer to the the 802.11 protocol for the definition of the + * HT-SIG and VHT-SIG-A2 fields + * - PREAMBLE_TYPE + * Bits 31:24 + * Purpose: indicate the PHY format of the received burst + * Value: + * 0x4: Legacy (OFDM/CCK) + * 0x8: HT + * 0x9: HT with TxBF + * 0xC: VHT + * 0xD: VHT with TxBF + * - SERVICE + * Bits 31:24 + * Purpose: TBD + * Value: TBD + * + * Rx MSDU descriptor fields: + * - FW_RX_DESC_BYTES + * Bits 15:0 + * Purpose: Indicate how many bytes in the Rx indication are used for + * FW Rx descriptors + * + * Payload fields: + * - MPDU_COUNT + * Bits 7:0 + * Purpose: Indicate how many sequential MPDUs share the same status. + * All MPDUs within the indicated list are from the same RA-TA-TID. + * - MPDU_STATUS + * Bits 15:8 + * Purpose: Indicate whether the (group of sequential) MPDU(s) were + * received successfully. + * Value: + * 0x1: success + * 0x2: FCS error + * 0x3: duplicate error + * 0x4: replay error + * 0x5: invalid peer + */ +/* header fields */ +#define HTT_RX_IND_EXT_TID_M 0x1f00 +#define HTT_RX_IND_EXT_TID_S 8 +#define HTT_RX_IND_FLUSH_VALID_M 0x2000 +#define HTT_RX_IND_FLUSH_VALID_S 13 +#define HTT_RX_IND_REL_VALID_M 0x4000 +#define HTT_RX_IND_REL_VALID_S 14 +#define HTT_RX_IND_PEER_ID_M 0xffff0000 +#define HTT_RX_IND_PEER_ID_S 16 + +#define HTT_RX_IND_FLUSH_SEQ_NUM_START_M 0x3f +#define HTT_RX_IND_FLUSH_SEQ_NUM_START_S 0 +#define HTT_RX_IND_FLUSH_SEQ_NUM_END_M 0xfc0 +#define HTT_RX_IND_FLUSH_SEQ_NUM_END_S 6 +#define HTT_RX_IND_REL_SEQ_NUM_START_M 0x3f000 +#define HTT_RX_IND_REL_SEQ_NUM_START_S 12 +#define HTT_RX_IND_REL_SEQ_NUM_END_M 0xfc0000 +#define HTT_RX_IND_REL_SEQ_NUM_END_S 18 +#define HTT_RX_IND_NUM_MPDU_RANGES_M 0xff000000 +#define HTT_RX_IND_NUM_MPDU_RANGES_S 24 + +/* rx PPDU descriptor fields */ +#define HTT_RX_IND_RSSI_CMB_M 0x000000ff +#define HTT_RX_IND_RSSI_CMB_S 0 +#define HTT_RX_IND_TIMESTAMP_SUBMICROSEC_M 0x0000ff00 +#define HTT_RX_IND_TIMESTAMP_SUBMICROSEC_S 8 +#define HTT_RX_IND_PHY_ERR_CODE_M 0x00ff0000 +#define HTT_RX_IND_PHY_ERR_CODE_S 16 +#define HTT_RX_IND_PHY_ERR_M 0x01000000 +#define HTT_RX_IND_PHY_ERR_S 24 +#define HTT_RX_IND_LEGACY_RATE_M 0x1e000000 +#define HTT_RX_IND_LEGACY_RATE_S 25 +#define HTT_RX_IND_LEGACY_RATE_SEL_M 0x20000000 +#define HTT_RX_IND_LEGACY_RATE_SEL_S 29 +#define HTT_RX_IND_END_VALID_M 0x40000000 +#define HTT_RX_IND_END_VALID_S 30 +#define HTT_RX_IND_START_VALID_M 0x80000000 +#define HTT_RX_IND_START_VALID_S 31 + +#define HTT_RX_IND_RSSI_PRI20_M 0x000000ff +#define HTT_RX_IND_RSSI_PRI20_S 0 +#define HTT_RX_IND_RSSI_EXT20_M 0x0000ff00 +#define HTT_RX_IND_RSSI_EXT20_S 8 +#define HTT_RX_IND_RSSI_EXT40_M 0x00ff0000 +#define HTT_RX_IND_RSSI_EXT40_S 16 +#define HTT_RX_IND_RSSI_EXT80_M 0xff000000 +#define HTT_RX_IND_RSSI_EXT80_S 24 + +#define HTT_RX_IND_VHT_SIG_A1_M 0x00ffffff +#define HTT_RX_IND_VHT_SIG_A1_S 0 +#define HTT_RX_IND_VHT_SIG_A2_M 0x00ffffff +#define HTT_RX_IND_VHT_SIG_A2_S 0 +#define HTT_RX_IND_PREAMBLE_TYPE_M 0xff000000 +#define HTT_RX_IND_PREAMBLE_TYPE_S 24 +#define HTT_RX_IND_SERVICE_M 0xff000000 +#define HTT_RX_IND_SERVICE_S 24 + +/* rx MSDU descriptor fields */ +#define HTT_RX_IND_FW_RX_DESC_BYTES_M 0xffff +#define HTT_RX_IND_FW_RX_DESC_BYTES_S 0 + +/* payload fields */ +#define HTT_RX_IND_MPDU_COUNT_M 0xff +#define HTT_RX_IND_MPDU_COUNT_S 0 +#define HTT_RX_IND_MPDU_STATUS_M 0xff00 +#define HTT_RX_IND_MPDU_STATUS_S 8 + + +#define HTT_RX_IND_EXT_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_EXT_TID, value); \ + (word) |= (value) << HTT_RX_IND_EXT_TID_S; \ + } while (0) +#define HTT_RX_IND_EXT_TID_GET(word) \ + (((word) & HTT_RX_IND_EXT_TID_M) >> HTT_RX_IND_EXT_TID_S) + +#define HTT_RX_IND_FLUSH_VALID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_FLUSH_VALID, value); \ + (word) |= (value) << HTT_RX_IND_FLUSH_VALID_S; \ + } while (0) +#define HTT_RX_IND_FLUSH_VALID_GET(word) \ + (((word) & HTT_RX_IND_FLUSH_VALID_M) >> HTT_RX_IND_FLUSH_VALID_S) + +#define HTT_RX_IND_REL_VALID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_REL_VALID, value); \ + (word) |= (value) << HTT_RX_IND_REL_VALID_S; \ + } while (0) +#define HTT_RX_IND_REL_VALID_GET(word) \ + (((word) & HTT_RX_IND_REL_VALID_M) >> HTT_RX_IND_REL_VALID_S) + +#define HTT_RX_IND_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_PEER_ID, value); \ + (word) |= (value) << HTT_RX_IND_PEER_ID_S; \ + } while (0) +#define HTT_RX_IND_PEER_ID_GET(word) \ + (((word) & HTT_RX_IND_PEER_ID_M) >> HTT_RX_IND_PEER_ID_S) + + +#define HTT_RX_IND_FW_RX_DESC_BYTES_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_FW_RX_DESC_BYTES, value); \ + (word) |= (value) << HTT_RX_IND_FW_RX_DESC_BYTES_S; \ + } while (0) +#define HTT_RX_IND_FW_RX_DESC_BYTES_GET(word) \ + (((word) & HTT_RX_IND_FW_RX_DESC_BYTES_M) >> HTT_RX_IND_FW_RX_DESC_BYTES_S) + + +#define HTT_RX_IND_FLUSH_SEQ_NUM_START_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_FLUSH_SEQ_NUM_START, value); \ + (word) |= (value) << HTT_RX_IND_FLUSH_SEQ_NUM_START_S; \ + } while (0) +#define HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(word) \ + (((word) & HTT_RX_IND_FLUSH_SEQ_NUM_START_M) >> \ + HTT_RX_IND_FLUSH_SEQ_NUM_START_S) + +#define HTT_RX_IND_FLUSH_SEQ_NUM_END_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_FLUSH_SEQ_NUM_END, value); \ + (word) |= (value) << HTT_RX_IND_FLUSH_SEQ_NUM_END_S; \ + } while (0) +#define HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(word) \ + (((word) & HTT_RX_IND_FLUSH_SEQ_NUM_END_M) >> \ + HTT_RX_IND_FLUSH_SEQ_NUM_END_S) + +#define HTT_RX_IND_REL_SEQ_NUM_START_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_REL_SEQ_NUM_START, value); \ + (word) |= (value) << HTT_RX_IND_REL_SEQ_NUM_START_S; \ + } while (0) +#define HTT_RX_IND_REL_SEQ_NUM_START_GET(word) \ + (((word) & HTT_RX_IND_REL_SEQ_NUM_START_M) >> \ + HTT_RX_IND_REL_SEQ_NUM_START_S) + +#define HTT_RX_IND_REL_SEQ_NUM_END_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_REL_SEQ_NUM_END, value); \ + (word) |= (value) << HTT_RX_IND_REL_SEQ_NUM_END_S; \ + } while (0) +#define HTT_RX_IND_REL_SEQ_NUM_END_GET(word) \ + (((word) & HTT_RX_IND_REL_SEQ_NUM_END_M) >> \ + HTT_RX_IND_REL_SEQ_NUM_END_S) + +#define HTT_RX_IND_NUM_MPDU_RANGES_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_NUM_MPDU_RANGES, value); \ + (word) |= (value) << HTT_RX_IND_NUM_MPDU_RANGES_S; \ + } while (0) +#define HTT_RX_IND_NUM_MPDU_RANGES_GET(word) \ + (((word) & HTT_RX_IND_NUM_MPDU_RANGES_M) >> \ + HTT_RX_IND_NUM_MPDU_RANGES_S) + +/* FW rx PPDU descriptor fields */ +#define HTT_RX_IND_RSSI_CMB_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_RSSI_CMB, value); \ + (word) |= (value) << HTT_RX_IND_RSSI_CMB_S; \ + } while (0) +#define HTT_RX_IND_RSSI_CMB_GET(word) \ + (((word) & HTT_RX_IND_RSSI_CMB_M) >> \ + HTT_RX_IND_RSSI_CMB_S) + +#define HTT_RX_IND_TIMESTAMP_SUBMICROSEC_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_TIMESTAMP_SUBMICROSEC, value); \ + (word) |= (value) << HTT_RX_IND_TIMESTAMP_SUBMICROSEC_S; \ + } while (0) +#define HTT_RX_IND_TIMESTAMP_SUBMICROSEC_GET(word) \ + (((word) & HTT_RX_IND_TIMESTAMP_SUBMICROSEC_M) >> \ + HTT_RX_IND_TIMESTAMP_SUBMICROSEC_S) + +#define HTT_RX_IND_PHY_ERR_CODE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_PHY_ERR_CODE, value); \ + (word) |= (value) << HTT_RX_IND_PHY_ERR_CODE_S; \ + } while (0) +#define HTT_RX_IND_PHY_ERR_CODE_GET(word) \ + (((word) & HTT_RX_IND_PHY_ERR_CODE_M) >> \ + HTT_RX_IND_PHY_ERR_CODE_S) + +#define HTT_RX_IND_PHY_ERR_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_PHY_ERR, value); \ + (word) |= (value) << HTT_RX_IND_PHY_ERR_S; \ + } while (0) +#define HTT_RX_IND_PHY_ERR_GET(word) \ + (((word) & HTT_RX_IND_PHY_ERR_M) >> \ + HTT_RX_IND_PHY_ERR_S) + +#define HTT_RX_IND_LEGACY_RATE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_LEGACY_RATE, value); \ + (word) |= (value) << HTT_RX_IND_LEGACY_RATE_S; \ + } while (0) +#define HTT_RX_IND_LEGACY_RATE_GET(word) \ + (((word) & HTT_RX_IND_LEGACY_RATE_M) >> \ + HTT_RX_IND_LEGACY_RATE_S) + +#define HTT_RX_IND_LEGACY_RATE_SEL_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_LEGACY_RATE_SEL, value); \ + (word) |= (value) << HTT_RX_IND_LEGACY_RATE_SEL_S; \ + } while (0) +#define HTT_RX_IND_LEGACY_RATE_SEL_GET(word) \ + (((word) & HTT_RX_IND_LEGACY_RATE_SEL_M) >> \ + HTT_RX_IND_LEGACY_RATE_SEL_S) + +#define HTT_RX_IND_END_VALID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_END_VALID, value); \ + (word) |= (value) << HTT_RX_IND_END_VALID_S; \ + } while (0) +#define HTT_RX_IND_END_VALID_GET(word) \ + (((word) & HTT_RX_IND_END_VALID_M) >> \ + HTT_RX_IND_END_VALID_S) + +#define HTT_RX_IND_START_VALID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_START_VALID, value); \ + (word) |= (value) << HTT_RX_IND_START_VALID_S; \ + } while (0) +#define HTT_RX_IND_START_VALID_GET(word) \ + (((word) & HTT_RX_IND_START_VALID_M) >> \ + HTT_RX_IND_START_VALID_S) + +#define HTT_RX_IND_RSSI_PRI20_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_RSSI_PRI20, value); \ + (word) |= (value) << HTT_RX_IND_RSSI_PRI20_S; \ + } while (0) +#define HTT_RX_IND_RSSI_PRI20_GET(word) \ + (((word) & HTT_RX_IND_RSSI_PRI20_M) >> \ + HTT_RX_IND_RSSI_PRI20_S) + +#define HTT_RX_IND_RSSI_EXT20_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_RSSI_EXT20, value); \ + (word) |= (value) << HTT_RX_IND_RSSI_EXT20_S; \ + } while (0) +#define HTT_RX_IND_RSSI_EXT20_GET(word) \ + (((word) & HTT_RX_IND_RSSI_EXT20_M) >> \ + HTT_RX_IND_RSSI_EXT20_S) + +#define HTT_RX_IND_RSSI_EXT40_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_RSSI_EXT40, value); \ + (word) |= (value) << HTT_RX_IND_RSSI_EXT40_S; \ + } while (0) +#define HTT_RX_IND_RSSI_EXT40_GET(word) \ + (((word) & HTT_RX_IND_RSSI_EXT40_M) >> \ + HTT_RX_IND_RSSI_EXT40_S) + +#define HTT_RX_IND_RSSI_EXT80_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_RSSI_EXT80, value); \ + (word) |= (value) << HTT_RX_IND_RSSI_EXT80_S; \ + } while (0) +#define HTT_RX_IND_RSSI_EXT80_GET(word) \ + (((word) & HTT_RX_IND_RSSI_EXT80_M) >> \ + HTT_RX_IND_RSSI_EXT80_S) + +#define HTT_RX_IND_VHT_SIG_A1_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_VHT_SIG_A1, value); \ + (word) |= (value) << HTT_RX_IND_VHT_SIG_A1_S; \ + } while (0) +#define HTT_RX_IND_VHT_SIG_A1_GET(word) \ + (((word) & HTT_RX_IND_VHT_SIG_A1_M) >> \ + HTT_RX_IND_VHT_SIG_A1_S) + +#define HTT_RX_IND_VHT_SIG_A2_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_VHT_SIG_A2, value); \ + (word) |= (value) << HTT_RX_IND_VHT_SIG_A2_S; \ + } while (0) +#define HTT_RX_IND_VHT_SIG_A2_GET(word) \ + (((word) & HTT_RX_IND_VHT_SIG_A2_M) >> \ + HTT_RX_IND_VHT_SIG_A2_S) + +#define HTT_RX_IND_PREAMBLE_TYPE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_PREAMBLE_TYPE, value); \ + (word) |= (value) << HTT_RX_IND_PREAMBLE_TYPE_S; \ + } while (0) +#define HTT_RX_IND_PREAMBLE_TYPE_GET(word) \ + (((word) & HTT_RX_IND_PREAMBLE_TYPE_M) >> \ + HTT_RX_IND_PREAMBLE_TYPE_S) + +#define HTT_RX_IND_SERVICE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_SERVICE, value); \ + (word) |= (value) << HTT_RX_IND_SERVICE_S; \ + } while (0) +#define HTT_RX_IND_SERVICE_GET(word) \ + (((word) & HTT_RX_IND_SERVICE_M) >> \ + HTT_RX_IND_SERVICE_S) + + +#define HTT_RX_IND_MPDU_COUNT_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_MPDU_COUNT, value); \ + (word) |= (value) << HTT_RX_IND_MPDU_COUNT_S; \ + } while (0) +#define HTT_RX_IND_MPDU_COUNT_GET(word) \ + (((word) & HTT_RX_IND_MPDU_COUNT_M) >> HTT_RX_IND_MPDU_COUNT_S) + +#define HTT_RX_IND_MPDU_STATUS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_IND_MPDU_STATUS, value); \ + (word) |= (value) << HTT_RX_IND_MPDU_STATUS_S; \ + } while (0) +#define HTT_RX_IND_MPDU_STATUS_GET(word) \ + (((word) & HTT_RX_IND_MPDU_STATUS_M) >> HTT_RX_IND_MPDU_STATUS_S) + + +#define HTT_RX_IND_HL_BYTES \ + (HTT_RX_IND_HDR_BYTES + \ + 4 /* single FW rx MSDU descriptor, plus padding */ + \ + 4 /* single MPDU range information element */) +#define HTT_RX_IND_HL_SIZE32 (HTT_RX_IND_HL_BYTES >> 2) + +// Could we use one macro entry? +#define HTT_WORD_SET(word, field, value) \ + do { \ + HTT_CHECK_SET_VAL(field, value); \ + (word) |= ((value) << field ## _S); \ + } while (0) +#define HTT_WORD_GET(word, field) \ + (((word) & field ## _M) >> field ## _S) + +PREPACK struct hl_htt_rx_ind_base { + A_UINT32 rx_ind_msg[HTT_RX_IND_HL_SIZE32]; /* algin with LL case rx indication message, but reduced to 5 words */ +} POSTPACK; + +/* + * HTT_RX_IND_HL_RX_DESC_BASE_OFFSET + * Currently, we use a resv field in hl_htt_rx_ind_base to store some + * HL host needed info. The field is just after the msdu fw rx desc. + */ +#define HTT_RX_IND_HL_RX_DESC_BASE_OFFSET (HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET + 1) +struct htt_rx_ind_hl_rx_desc_t { + A_UINT8 ver; + A_UINT8 len; + struct { + A_UINT8 + first_msdu: 1, + last_msdu: 1, + c3_failed: 1, + c4_failed: 1, + ipv6: 1, + tcp: 1, + udp: 1, + reserved: 1; + } flags; +}; + +#define HTT_RX_IND_HL_RX_DESC_VER_OFFSET \ + (HTT_RX_IND_HL_RX_DESC_BASE_OFFSET \ + + offsetof(struct htt_rx_ind_hl_rx_desc_t, ver)) +#define HTT_RX_IND_HL_RX_DESC_VER 0 + +#define HTT_RX_IND_HL_RX_DESC_LEN_OFFSET \ + (HTT_RX_IND_HL_RX_DESC_BASE_OFFSET \ + + offsetof(struct htt_rx_ind_hl_rx_desc_t, len)) + +#define HTT_RX_IND_HL_FLAG_OFFSET \ + (HTT_RX_IND_HL_RX_DESC_BASE_OFFSET \ + + offsetof(struct htt_rx_ind_hl_rx_desc_t, flags)) + +#define HTT_RX_IND_HL_FLAG_FIRST_MSDU (0x01 << 0) +#define HTT_RX_IND_HL_FLAG_LAST_MSDU (0x01 << 1) +#define HTT_RX_IND_HL_FLAG_C3_FAILED (0x01 << 2) // L3 checksum failed +#define HTT_RX_IND_HL_FLAG_C4_FAILED (0x01 << 3) // L4 checksum failed +#define HTT_RX_IND_HL_FLAG_IPV6 (0x01 << 4) // is ipv6, or else ipv4 +#define HTT_RX_IND_HL_FLAG_TCP (0x01 << 5) // is tcp +#define HTT_RX_IND_HL_FLAG_UDP (0x01 << 6) // is udp +/* This structure is used in HL, the basic descriptor information + * used by host. the structure is translated by FW from HW desc + * or generated by FW. But in HL monitor mode, the host would use + * the same structure with LL. + */ +PREPACK struct hl_htt_rx_desc_base { + A_UINT32 + seq_num:12, + encrypted:1, + resv0:3, + mcast_bcast:1, + fragment:1, + key_id_oct:8, + resv1:6; + A_UINT32 + pn_31_0; + union { + struct { + A_UINT16 pn_47_32; + A_UINT16 pn_63_48; + } pn16; + A_UINT32 pn_63_32; + } u0; + A_UINT32 + pn_95_64; + A_UINT32 + pn_127_96; +} POSTPACK; + +#define HL_RX_DESC_SIZE (sizeof(struct hl_htt_rx_desc_base)) +#define HL_RX_DESC_SIZE_DWORD (HL_RX_STD_DESC_SIZE >> 2) + +#define HTT_HL_RX_DESC_MPDU_SEQ_NUM_M 0xfff +#define HTT_HL_RX_DESC_MPDU_SEQ_NUM_S 0 +#define HTT_HL_RX_DESC_MPDU_ENC_M 0x1000 +#define HTT_HL_RX_DESC_MPDU_ENC_S 12 +#define HTT_HL_RX_DESC_MCAST_BCAST_M 0x10000 +#define HTT_HL_RX_DESC_MCAST_BCAST_S 16 +#define HTT_HL_RX_DESC_FRAGMENT_M 0x20000 +#define HTT_HL_RX_DESC_FRAGMENT_S 17 +#define HTT_HL_RX_DESC_KEY_ID_OCT_M 0x3fc0000 +#define HTT_HL_RX_DESC_KEY_ID_OCT_S 18 + +#define HTT_HL_RX_DESC_PN_OFFSET offsetof(struct hl_htt_rx_desc_base, pn_31_0) +#define HTT_HL_RX_DESC_PN_WORD_OFFSET (HTT_HL_RX_DESC_PN_OFFSET >> 2) + +/* + * @brief target -> host rx reorder flush message definition + * + * @details + * The following field definitions describe the format of the rx flush + * message sent from the target to the host. + * The message consists of a 4-octet header, followed by one or more + * 4-octet payload information elements. + * + * |31 24|23 8|7 0| + * |--------------------------------------------------------------| + * | TID | peer ID | msg type | + * |--------------------------------------------------------------| + * | seq num end | seq num start | MPDU status | reserved | + * |--------------------------------------------------------------| + * First DWORD: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx flush message + * Value: 0x2 + * - PEER_ID + * Bits 23:8 (only bits 18:8 actually used) + * Purpose: identify which peer's rx data is being flushed + * Value: (rx) peer ID + * - TID + * Bits 31:24 (only bits 27:24 actually used) + * Purpose: Specifies which traffic identifier's rx data is being flushed + * Value: traffic identifier + * Second DWORD: + * - MPDU_STATUS + * Bits 15:8 + * Purpose: + * Indicate whether the flushed MPDUs should be discarded or processed. + * Value: + * 0x1: send the MPDUs from the rx reorder buffer to subsequent + * stages of rx processing + * other: discard the MPDUs + * It is anticipated that flush messages will always have + * MPDU status == 1, but the status flag is included for + * flexibility. + * - SEQ_NUM_START + * Bits 23:16 + * Purpose: + * Indicate the start of a series of consecutive MPDUs being flushed. + * Not all MPDUs within this range are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * Value: + * The sequence number for the first MPDU in the sequence. + * This sequence number is the 6 LSBs of the 802.11 sequence number. + * - SEQ_NUM_END + * Bits 30:24 + * Purpose: + * Indicate the end of a series of consecutive MPDUs being flushed. + * Value: + * The sequence number one larger than the sequence number of the + * last MPDU being flushed. + * This sequence number is the 6 LSBs of the 802.11 sequence number. + * The range of MPDUs from [SEQ_NUM_START,SEQ_NUM_END-1] inclusive + * are to be released for further rx processing. + * Not all MPDUs within this range are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + */ +/* first DWORD */ +#define HTT_RX_FLUSH_PEER_ID_M 0xffff00 +#define HTT_RX_FLUSH_PEER_ID_S 8 +#define HTT_RX_FLUSH_TID_M 0xff000000 +#define HTT_RX_FLUSH_TID_S 24 +/* second DWORD */ +#define HTT_RX_FLUSH_MPDU_STATUS_M 0x0000ff00 +#define HTT_RX_FLUSH_MPDU_STATUS_S 8 +#define HTT_RX_FLUSH_SEQ_NUM_START_M 0x00ff0000 +#define HTT_RX_FLUSH_SEQ_NUM_START_S 16 +#define HTT_RX_FLUSH_SEQ_NUM_END_M 0xff000000 +#define HTT_RX_FLUSH_SEQ_NUM_END_S 24 + +#define HTT_RX_FLUSH_BYTES 8 + +#define HTT_RX_FLUSH_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_FLUSH_PEER_ID, value); \ + (word) |= (value) << HTT_RX_FLUSH_PEER_ID_S; \ + } while (0) +#define HTT_RX_FLUSH_PEER_ID_GET(word) \ + (((word) & HTT_RX_FLUSH_PEER_ID_M) >> HTT_RX_FLUSH_PEER_ID_S) + +#define HTT_RX_FLUSH_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_FLUSH_TID, value); \ + (word) |= (value) << HTT_RX_FLUSH_TID_S; \ + } while (0) +#define HTT_RX_FLUSH_TID_GET(word) \ + (((word) & HTT_RX_FLUSH_TID_M) >> HTT_RX_FLUSH_TID_S) + +#define HTT_RX_FLUSH_MPDU_STATUS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_FLUSH_MPDU_STATUS, value); \ + (word) |= (value) << HTT_RX_FLUSH_MPDU_STATUS_S; \ + } while (0) +#define HTT_RX_FLUSH_MPDU_STATUS_GET(word) \ + (((word) & HTT_RX_FLUSH_MPDU_STATUS_M) >> HTT_RX_FLUSH_MPDU_STATUS_S) + +#define HTT_RX_FLUSH_SEQ_NUM_START_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_FLUSH_SEQ_NUM_START, value); \ + (word) |= (value) << HTT_RX_FLUSH_SEQ_NUM_START_S; \ + } while (0) +#define HTT_RX_FLUSH_SEQ_NUM_START_GET(word) \ + (((word) & HTT_RX_FLUSH_SEQ_NUM_START_M) >> HTT_RX_FLUSH_SEQ_NUM_START_S) + +#define HTT_RX_FLUSH_SEQ_NUM_END_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_FLUSH_SEQ_NUM_END, value); \ + (word) |= (value) << HTT_RX_FLUSH_SEQ_NUM_END_S; \ + } while (0) +#define HTT_RX_FLUSH_SEQ_NUM_END_GET(word) \ + (((word) & HTT_RX_FLUSH_SEQ_NUM_END_M) >> HTT_RX_FLUSH_SEQ_NUM_END_S) + +/* + * @brief target -> host rx pn check indication message + * + * @details + * The following field definitions describe the format of the Rx PN check + * indication message sent from the target to the host. + * The message consists of a 4-octet header, followed by the start and + * end sequence numbers to be released, followed by the PN IEs. Each PN + * IE is one octet containing the sequence number that failed the PN + * check. + * + * |31 24|23 8|7 0| + * |--------------------------------------------------------------| + * | TID | peer ID | msg type | + * |--------------------------------------------------------------| + * | Reserved | PN IE count | seq num end | seq num start| + * |--------------------------------------------------------------| + * l : PN IE 2 | PN IE 1 | PN IE 0 | + * |--------------------------------------------------------------| + + * First DWORD: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this as an rx pn check indication message + * Value: 0x2 + * - PEER_ID + * Bits 23:8 (only bits 18:8 actually used) + * Purpose: identify which peer + * Value: (rx) peer ID + * - TID + * Bits 31:24 (only bits 27:24 actually used) + * Purpose: identify traffic identifier + * Value: traffic identifier + * Second DWORD: + * - SEQ_NUM_START + * Bits 7:0 + * Purpose: + * Indicates the starting sequence number of the MPDU in this + * series of MPDUs that went though PN check. + * Value: + * The sequence number for the first MPDU in the sequence. + * This sequence number is the 6 LSBs of the 802.11 sequence number. + * - SEQ_NUM_END + * Bits 15:8 + * Purpose: + * Indicates the ending sequence number of the MPDU in this + * series of MPDUs that went though PN check. + * Value: + * The sequence number one larger then the sequence number of the last + * MPDU being flushed. + * This sequence number is the 6 LSBs of the 802.11 sequence number. + * The range of MPDUs from [SEQ_NUM_START,SEQ_NUM_END-1] have been checked + * for invalid PN numbers and are ready to be released for further processing. + * Not all MPDUs within this range are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * - PN_IE_COUNT + * Bits 23:16 + * Purpose: + * Used to determine the variable number of PN information elements in this + * message + * + * PN information elements: + * - PN_IE_x- + * Purpose: + * Each PN information element contains the sequence number of the MPDU that + * has failed the target PN check. + * Value: + * Contains the 6 LSBs of the 802.11 sequence number corresponding to the MPDU + * that failed the PN check. + */ +/* first DWORD */ +#define HTT_RX_PN_IND_PEER_ID_M 0xffff00 +#define HTT_RX_PN_IND_PEER_ID_S 8 +#define HTT_RX_PN_IND_TID_M 0xff000000 +#define HTT_RX_PN_IND_TID_S 24 +/* second DWORD */ +#define HTT_RX_PN_IND_SEQ_NUM_START_M 0x000000ff +#define HTT_RX_PN_IND_SEQ_NUM_START_S 0 +#define HTT_RX_PN_IND_SEQ_NUM_END_M 0x0000ff00 +#define HTT_RX_PN_IND_SEQ_NUM_END_S 8 +#define HTT_RX_PN_IND_PN_IE_CNT_M 0x00ff0000 +#define HTT_RX_PN_IND_PN_IE_CNT_S 16 + +#define HTT_RX_PN_IND_BYTES 8 + +#define HTT_RX_PN_IND_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PN_IND_PEER_ID, value); \ + (word) |= (value) << HTT_RX_PN_IND_PEER_ID_S; \ + } while (0) +#define HTT_RX_PN_IND_PEER_ID_GET(word) \ + (((word) & HTT_RX_PN_IND_PEER_ID_M) >> HTT_RX_PN_IND_PEER_ID_S) + +#define HTT_RX_PN_IND_EXT_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PN_IND_TID, value); \ + (word) |= (value) << HTT_RX_PN_IND_TID_S; \ + } while (0) +#define HTT_RX_PN_IND_EXT_TID_GET(word) \ + (((word) & HTT_RX_PN_IND_TID_M) >> HTT_RX_PN_IND_TID_S) + +#define HTT_RX_PN_IND_SEQ_NUM_START_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PN_IND_SEQ_NUM_START, value); \ + (word) |= (value) << HTT_RX_PN_IND_SEQ_NUM_START_S; \ + } while (0) +#define HTT_RX_PN_IND_SEQ_NUM_START_GET(word) \ + (((word) & HTT_RX_PN_IND_SEQ_NUM_START_M) >> HTT_RX_PN_IND_SEQ_NUM_START_S) + +#define HTT_RX_PN_IND_SEQ_NUM_END_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PN_IND_SEQ_NUM_END, value); \ + (word) |= (value) << HTT_RX_PN_IND_SEQ_NUM_END_S; \ + } while (0) +#define HTT_RX_PN_IND_SEQ_NUM_END_GET(word) \ + (((word) & HTT_RX_PN_IND_SEQ_NUM_END_M) >> HTT_RX_PN_IND_SEQ_NUM_END_S) + +#define HTT_RX_PN_IND_PN_IE_CNT_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PN_IND_PN_IE_CNT, value); \ + (word) |= (value) << HTT_RX_PN_IND_PN_IE_CNT_S; \ + } while(0) +#define HTT_RX_PN_IND_PN_IE_CNT_GET(word) \ + (((word) & HTT_RX_PN_IND_PN_IE_CNT_M) >> HTT_RX_PN_IND_PN_IE_CNT_S) + +/* + * @brief target -> host rx offload deliver message for LL system + * + * @details + * In a low latency system this message is sent whenever the offload + * manager flushes out the packets it has coalesced in its coalescing buffer. + * The DMA of the actual packets into host memory is done before sending out + * this message. This message indicates only how many MSDUs to reap. The + * peer ID, vdev ID, tid and MSDU length are copied inline into the header + * portion of the MSDU while DMA'ing into the host memory. Unlike the packets + * DMA'd by the MAC directly into host memory these packets do not contain + * the MAC descriptors in the header portion of the packet. Instead they contain + * the peer ID, vdev ID, tid and MSDU length. Also when the host receives this + * message, the packets are delivered directly to the NW stack without going + * through the regular reorder buffering and PN checking path since it has + * already been done in target. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------------------| + * | Total MSDU count | reserved | msg type | + * |-----------------------------------------------------------------------| + * + * @brief target -> host rx offload deliver message for HL system + * + * @details + * In a high latency system this message is sent whenever the offload manager + * flushes out the packets it has coalesced in its coalescing buffer. The + * actual packets are also carried along with this message. When the host + * receives this message, it is expected to deliver these packets to the NW + * stack directly instead of routing them through the reorder buffering and + * PN checking path since it has already been done in target. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------------------| + * | Total MSDU count | reserved | msg type | + * |-----------------------------------------------------------------------| + * | peer ID | MSDU length | + * |-----------------------------------------------------------------------| + * | MSDU payload | FW Desc | tid | vdev ID | + * |-----------------------------------------------------------------------| + * | MSDU payload contd. | + * |-----------------------------------------------------------------------| + * | peer ID | MSDU length | + * |-----------------------------------------------------------------------| + * | MSDU payload | FW Desc | tid | vdev ID | + * |-----------------------------------------------------------------------| + * | MSDU payload contd. | + * |-----------------------------------------------------------------------| + * + */ +/* first DWORD */ +#define HTT_RX_OFFLOAD_DELIVER_IND_HDR_BYTES 4 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES 7 + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_M 0xffff0000 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_S 16 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_M 0x0000ffff +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_S 0 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_M 0xffff0000 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_S 16 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_M 0x000000ff +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_S 0 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_M 0x0000ff00 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_S 8 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_M 0x00ff0000 +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_S 16 + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_S; \ + } while(0) \ + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_S; \ + } while(0) \ + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_S; \ + } while(0) \ + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_S; \ + } while(0) \ + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_S; \ + } while(0) \ + +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(word) \ + (((word) & HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_M) >> HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_S) +#define HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC, value); \ + (word) |= (value) << HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_S; \ + } while(0) \ + +/** + * @brief target -> host rx peer map/unmap message definition + * + * @details + * The following diagram shows the format of the rx peer map message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------------------| + * | peer ID | VDEV ID | msg type | + * |-----------------------------------------------------------------------| + * | MAC addr 3 | MAC addr 2 | MAC addr 1 | MAC addr 0 | + * |-----------------------------------------------------------------------| + * | reserved | MAC addr 5 | MAC addr 4 | + * |-----------------------------------------------------------------------| + * + * + * The following diagram shows the format of the rx peer unmap message sent + * from the target to the host. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------------------| + * | peer ID | VDEV ID | msg type | + * |-----------------------------------------------------------------------| + * + * The following field definitions describe the format of the rx peer map + * and peer unmap messages sent from the target to the host. + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx peer map or peer unmap message + * Value: peer map -> 0x3, peer unmap -> 0x4 + * - VDEV_ID + * Bits 15:8 + * Purpose: Indicates which virtual device the peer is associated + * with. + * Value: vdev ID (used in the host to look up the vdev object) + * - PEER_ID + * Bits 31:16 + * Purpose: The peer ID (index) that WAL is allocating (map) or + * freeing (unmap) + * Value: (rx) peer ID + * - MAC_ADDR_L32 (peer map only) + * Bits 31:0 + * Purpose: Identifies which peer node the peer ID is for. + * Value: lower 4 bytes of peer node's MAC address + * - MAC_ADDR_U16 (peer map only) + * Bits 15:0 + * Purpose: Identifies which peer node the peer ID is for. + * Value: upper 2 bytes of peer node's MAC address + */ +#define HTT_RX_PEER_MAP_VDEV_ID_M 0xff00 +#define HTT_RX_PEER_MAP_VDEV_ID_S 8 +#define HTT_RX_PEER_MAP_PEER_ID_M 0xffff0000 +#define HTT_RX_PEER_MAP_PEER_ID_S 16 +#define HTT_RX_PEER_MAP_MAC_ADDR_L32_M 0xffffffff +#define HTT_RX_PEER_MAP_MAC_ADDR_L32_S 0 +#define HTT_RX_PEER_MAP_MAC_ADDR_U16_M 0xffff +#define HTT_RX_PEER_MAP_MAC_ADDR_U16_S 0 + +#define HTT_RX_PEER_MAP_VAP_ID_SET HTT_RX_PEER_MAP_VDEV_ID_SET /* deprecated */ +#define HTT_RX_PEER_MAP_VDEV_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PEER_MAP_VDEV_ID, value); \ + (word) |= (value) << HTT_RX_PEER_MAP_VDEV_ID_S; \ + } while (0) +#define HTT_RX_PEER_MAP_VAP_ID_GET HTT_RX_PEER_MAP_VDEV_ID_GET /* deprecated */ +#define HTT_RX_PEER_MAP_VDEV_ID_GET(word) \ + (((word) & HTT_RX_PEER_MAP_VDEV_ID_M) >> HTT_RX_PEER_MAP_VDEV_ID_S) + +#define HTT_RX_PEER_MAP_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_PEER_MAP_PEER_ID, value); \ + (word) |= (value) << HTT_RX_PEER_MAP_PEER_ID_S; \ + } while (0) +#define HTT_RX_PEER_MAP_PEER_ID_GET(word) \ + (((word) & HTT_RX_PEER_MAP_PEER_ID_M) >> HTT_RX_PEER_MAP_PEER_ID_S) + +#define HTT_RX_PEER_MAP_MAC_ADDR_OFFSET 4 /* bytes */ + +#define HTT_RX_PEER_MAP_BYTES 12 + + +#define HTT_RX_PEER_UNMAP_PEER_ID_M HTT_RX_PEER_MAP_PEER_ID_M +#define HTT_RX_PEER_UNMAP_PEER_ID_S HTT_RX_PEER_MAP_PEER_ID_S + +#define HTT_RX_PEER_UNMAP_PEER_ID_SET HTT_RX_PEER_MAP_PEER_ID_SET +#define HTT_RX_PEER_UNMAP_PEER_ID_GET HTT_RX_PEER_MAP_PEER_ID_GET + +#define HTT_RX_PEER_UNMAP_VDEV_ID_SET HTT_RX_PEER_MAP_VDEV_ID_SET +#define HTT_RX_PEER_UNMAP_VDEV_ID_GET HTT_RX_PEER_MAP_VDEV_ID_GET + +#define HTT_RX_PEER_UNMAP_BYTES 4 + + +/** + * @brief target -> host message specifying security parameters + * + * @details + * The following diagram shows the format of the security specification + * message sent from the target to the host. + * This security specification message tells the host whether a PN check is + * necessary on rx data frames, and if so, how large the PN counter is. + * This message also tells the host about the security processing to apply + * to defragmented rx frames - specifically, whether a Message Integrity + * Check is required, and the Michael key to use. + * + * |31 24|23 16|15|14 8|7 0| + * |-----------------------------------------------------------------------| + * | peer ID | U| security type | msg type | + * |-----------------------------------------------------------------------| + * | Michael Key K0 | + * |-----------------------------------------------------------------------| + * | Michael Key K1 | + * |-----------------------------------------------------------------------| + * | WAPI RSC Low0 | + * |-----------------------------------------------------------------------| + * | WAPI RSC Low1 | + * |-----------------------------------------------------------------------| + * | WAPI RSC Hi0 | + * |-----------------------------------------------------------------------| + * | WAPI RSC Hi1 | + * |-----------------------------------------------------------------------| + * + * The following field definitions describe the format of the security + * indication message sent from the target to the host. + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a security specification message + * Value: 0xb + * - SEC_TYPE + * Bits 14:8 + * Purpose: specifies which type of security applies to the peer + * Value: htt_sec_type enum value + * - UNICAST + * Bit 15 + * Purpose: whether this security is applied to unicast or multicast data + * Value: 1 -> unicast, 0 -> multicast + * - PEER_ID + * Bits 31:16 + * Purpose: The ID number for the peer the security specification is for + * Value: peer ID + * - MICHAEL_KEY_K0 + * Bits 31:0 + * Purpose: 4-byte word that forms the 1st half of the TKIP Michael key + * Value: Michael Key K0 (if security type is TKIP) + * - MICHAEL_KEY_K1 + * Bits 31:0 + * Purpose: 4-byte word that forms the 2nd half of the TKIP Michael key + * Value: Michael Key K1 (if security type is TKIP) + * - WAPI_RSC_LOW0 + * Bits 31:0 + * Purpose: 4-byte word that forms the 1st quarter of the 16 byte WAPI RSC + * Value: WAPI RSC Low0 (if security type is WAPI) + * - WAPI_RSC_LOW1 + * Bits 31:0 + * Purpose: 4-byte word that forms the 2nd quarter of the 16 byte WAPI RSC + * Value: WAPI RSC Low1 (if security type is WAPI) + * - WAPI_RSC_HI0 + * Bits 31:0 + * Purpose: 4-byte word that forms the 3rd quarter of the 16 byte WAPI RSC + * Value: WAPI RSC Hi0 (if security type is WAPI) + * - WAPI_RSC_HI1 + * Bits 31:0 + * Purpose: 4-byte word that forms the 4th quarter of the 16 byte WAPI RSC + * Value: WAPI RSC Hi1 (if security type is WAPI) + */ + +#define HTT_SEC_IND_SEC_TYPE_M 0x00007f00 +#define HTT_SEC_IND_SEC_TYPE_S 8 +#define HTT_SEC_IND_UNICAST_M 0x00008000 +#define HTT_SEC_IND_UNICAST_S 15 +#define HTT_SEC_IND_PEER_ID_M 0xffff0000 +#define HTT_SEC_IND_PEER_ID_S 16 + +#define HTT_SEC_IND_SEC_TYPE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_SEC_IND_SEC_TYPE, value); \ + (word) |= (value) << HTT_SEC_IND_SEC_TYPE_S; \ + } while (0) +#define HTT_SEC_IND_SEC_TYPE_GET(word) \ + (((word) & HTT_SEC_IND_SEC_TYPE_M) >> HTT_SEC_IND_SEC_TYPE_S) + +#define HTT_SEC_IND_UNICAST_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_SEC_IND_UNICAST, value); \ + (word) |= (value) << HTT_SEC_IND_UNICAST_S; \ + } while (0) +#define HTT_SEC_IND_UNICAST_GET(word) \ + (((word) & HTT_SEC_IND_UNICAST_M) >> HTT_SEC_IND_UNICAST_S) + +#define HTT_SEC_IND_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_SEC_IND_PEER_ID, value); \ + (word) |= (value) << HTT_SEC_IND_PEER_ID_S; \ + } while (0) +#define HTT_SEC_IND_PEER_ID_GET(word) \ + (((word) & HTT_SEC_IND_PEER_ID_M) >> HTT_SEC_IND_PEER_ID_S) + + +#define HTT_SEC_IND_BYTES 28 + + +/** + * @brief target -> host rx ADDBA / DELBA message definitions + * + * @details + * The following diagram shows the format of the rx ADDBA message sent + * from the target to the host: + * + * |31 20|19 16|15 8|7 0| + * |---------------------------------------------------------------------| + * | peer ID | TID | window size | msg type | + * |---------------------------------------------------------------------| + * + * The following diagram shows the format of the rx DELBA message sent + * from the target to the host: + * + * |31 20|19 16|15 8|7 0| + * |---------------------------------------------------------------------| + * | peer ID | TID | reserved | msg type | + * |---------------------------------------------------------------------| + * + * The following field definitions describe the format of the rx ADDBA + * and DELBA messages sent from the target to the host. + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx ADDBA or DELBA message + * Value: ADDBA -> 0x5, DELBA -> 0x6 + * - WIN_SIZE + * Bits 15:8 (ADDBA only) + * Purpose: Specifies the length of the block ack window (max = 64). + * Value: + * block ack window length specified by the received ADDBA + * management message. + * - TID + * Bits 19:16 + * Purpose: Specifies which traffic identifier the ADDBA / DELBA is for. + * Value: + * TID specified by the received ADDBA or DELBA management message. + * - PEER_ID + * Bits 31:20 + * Purpose: Identifies which peer sent the ADDBA / DELBA. + * Value: + * ID (hash value) used by the host for fast, direct lookup of + * host SW peer info, including rx reorder states. + */ +#define HTT_RX_ADDBA_WIN_SIZE_M 0xff00 +#define HTT_RX_ADDBA_WIN_SIZE_S 8 +#define HTT_RX_ADDBA_TID_M 0xf0000 +#define HTT_RX_ADDBA_TID_S 16 +#define HTT_RX_ADDBA_PEER_ID_M 0xfff00000 +#define HTT_RX_ADDBA_PEER_ID_S 20 + +#define HTT_RX_ADDBA_WIN_SIZE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_ADDBA_WIN_SIZE, value); \ + (word) |= (value) << HTT_RX_ADDBA_WIN_SIZE_S; \ + } while (0) +#define HTT_RX_ADDBA_WIN_SIZE_GET(word) \ + (((word) & HTT_RX_ADDBA_WIN_SIZE_M) >> HTT_RX_ADDBA_WIN_SIZE_S) + +#define HTT_RX_ADDBA_TID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_ADDBA_TID, value); \ + (word) |= (value) << HTT_RX_ADDBA_TID_S; \ + } while (0) +#define HTT_RX_ADDBA_TID_GET(word) \ + (((word) & HTT_RX_ADDBA_TID_M) >> HTT_RX_ADDBA_TID_S) + +#define HTT_RX_ADDBA_PEER_ID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_ADDBA_PEER_ID, value); \ + (word) |= (value) << HTT_RX_ADDBA_PEER_ID_S; \ + } while (0) +#define HTT_RX_ADDBA_PEER_ID_GET(word) \ + (((word) & HTT_RX_ADDBA_PEER_ID_M) >> HTT_RX_ADDBA_PEER_ID_S) + +#define HTT_RX_ADDBA_BYTES 4 + + +#define HTT_RX_DELBA_TID_M HTT_RX_ADDBA_TID_M +#define HTT_RX_DELBA_TID_S HTT_RX_ADDBA_TID_S +#define HTT_RX_DELBA_PEER_ID_M HTT_RX_ADDBA_PEER_ID_M +#define HTT_RX_DELBA_PEER_ID_S HTT_RX_ADDBA_PEER_ID_S + +#define HTT_RX_DELBA_TID_SET HTT_RX_ADDBA_TID_SET +#define HTT_RX_DELBA_TID_GET HTT_RX_ADDBA_TID_GET +#define HTT_RX_DELBA_PEER_ID_SET HTT_RX_ADDBA_PEER_ID_SET +#define HTT_RX_DELBA_PEER_ID_GET HTT_RX_ADDBA_PEER_ID_GET + +#define HTT_RX_DELBA_BYTES 4 + +/** + * @brief tx queue group information element definition + * + * @details + * The following diagram shows the format of the tx queue group + * information element, which can be included in target --> host + * messages to specify the number of tx "credits" (tx descriptors + * for LL, or tx buffers for HL) available to a particular group + * of host-side tx queues, and which host-side tx queues belong to + * the group. + * + * |31|30 24|23 16|15|14|13 0| + * |------------------------------------------------------------------------| + * | X| reserved | tx queue grp ID | A| S| credit count | + * |------------------------------------------------------------------------| + * | vdev ID mask | AC mask | + * |------------------------------------------------------------------------| + * + * The following definitions describe the fields within the tx queue group + * information element: + * - credit_count + * Bits 13:1 + * Purpose: specify how many tx credits are available to the tx queue group + * Value: An absolute or relative, positive or negative credit value + * The 'A' bit specifies whether the value is absolute or relative. + * The 'S' bit specifies whether the value is positive or negative. + * A negative value can only be relative, not absolute. + * An absolute value replaces any prior credit value the host has for + * the tx queue group in question. + * A relative value is added to the prior credit value the host has for + * the tx queue group in question. + * - sign + * Bit 14 + * Purpose: specify whether the credit count is positive or negative + * Value: 0 -> positive, 1 -> negative + * - absolute + * Bit 15 + * Purpose: specify whether the credit count is absolute or relative + * Value: 0 -> relative, 1 -> absolute + * - txq_group_id + * Bits 23:16 + * Purpose: indicate which tx queue group's credit and/or membership are + * being specified + * Value: 0 to max_tx_queue_groups-1 + * - reserved + * Bits 30:16 + * Value: 0x0 + * - eXtension + * Bit 31 + * Purpose: specify whether another tx queue group info element follows + * Value: 0 -> no more tx queue group information elements + * 1 -> another tx queue group information element immediately follows + * - ac_mask + * Bits 15:0 + * Purpose: specify which Access Categories belong to the tx queue group + * Value: bit-OR of masks for the ACs (WMM and extension) that belong to + * the tx queue group. + * The AC bit-mask values are obtained by left-shifting by the + * corresponding HTT_AC_WMM enum values, e.g. (1 << HTT_AC_WMM_BE) == 0x1 + * - vdev_id_mask + * Bits 31:16 + * Purpose: specify which vdev's tx queues belong to the tx queue group + * Value: bit-OR of masks based on the IDs of the vdevs whose tx queues + * belong to the tx queue group. + * For example, if vdev IDs 1 and 4 belong to a tx queue group, the + * vdev_id_mask would be (1 << 1) | (1 << 4) = 0x12 + */ +PREPACK struct htt_txq_group { + A_UINT32 + credit_count: 14, + sign: 1, + absolute: 1, + tx_queue_group_id: 8, + reserved0: 7, + extension: 1; + A_UINT32 + ac_mask: 16, + vdev_id_mask: 16; +} POSTPACK; + +/* first word */ +#define HTT_TXQ_GROUP_CREDIT_COUNT_S 0 +#define HTT_TXQ_GROUP_CREDIT_COUNT_M 0x00003fff +#define HTT_TXQ_GROUP_SIGN_S 14 +#define HTT_TXQ_GROUP_SIGN_M 0x00004000 +#define HTT_TXQ_GROUP_ABS_S 15 +#define HTT_TXQ_GROUP_ABS_M 0x00008000 +#define HTT_TXQ_GROUP_ID_S 16 +#define HTT_TXQ_GROUP_ID_M 0x00ff0000 +#define HTT_TXQ_GROUP_EXT_S 31 +#define HTT_TXQ_GROUP_EXT_M 0x80000000 +/* second word */ +#define HTT_TXQ_GROUP_AC_MASK_S 0 +#define HTT_TXQ_GROUP_AC_MASK_M 0x0000ffff +#define HTT_TXQ_GROUP_VDEV_ID_MASK_S 16 +#define HTT_TXQ_GROUP_VDEV_ID_MASK_M 0xffff0000 + +#define HTT_TXQ_GROUP_CREDIT_COUNT_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_CREDIT_COUNT, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_CREDIT_COUNT_S)); \ + } while (0) +#define HTT_TXQ_GROUP_CREDIT_COUNT_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_CREDIT_COUNT_M) >> HTT_TXQ_GROUP_CREDIT_COUNT_S) + +#define HTT_TXQ_GROUP_SIGN_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_SIGN, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_SIGN_S)); \ + } while (0) +#define HTT_TXQ_GROUP_SIGN_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_SIGN_M) >> HTT_TXQ_GROUP_SIGN_S) + +#define HTT_TXQ_GROUP_ABS_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_ABS, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_ABS_S)); \ + } while (0) +#define HTT_TXQ_GROUP_ABS_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_ABS_M) >> HTT_TXQ_GROUP_ABS_S) + +#define HTT_TXQ_GROUP_ID_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_ID, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_ID_S)); \ + } while (0) +#define HTT_TXQ_GROUP_ID_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_ID_M) >> HTT_TXQ_GROUP_ID_S) + +#define HTT_TXQ_GROUP_EXT_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_EXT, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_EXT_S)); \ + } while (0) +#define HTT_TXQ_GROUP_EXT_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_EXT_M) >> HTT_TXQ_GROUP_EXT_S) + +#define HTT_TXQ_GROUP_AC_MASK_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_AC_MASK, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_AC_MASK_S)); \ + } while (0) +#define HTT_TXQ_GROUP_AC_MASK_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_AC_MASK_M) >> HTT_TXQ_GROUP_AC_MASK_S) + +#define HTT_TXQ_GROUP_VDEV_ID_MASK_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TXQ_GROUP_VDEV_ID_MASK, _val); \ + ((_info) |= ((_val) << HTT_TXQ_GROUP_VDEV_ID_MASK_S)); \ + } while (0) +#define HTT_TXQ_GROUP_VDEV_ID_MASK_GET(_info) \ + (((_info) & HTT_TXQ_GROUP_VDEV_ID_MASK_M) >> HTT_TXQ_GROUP_VDEV_ID_MASK_S) + +/** + * @brief target -> host TX completion indication message definition + * + * @details + * The following diagram shows the format of the TX completion indication sent + * from the target to the host + * + * |31 25| 24|23 16| 15 |14 11|10 8|7 0| + * |-------------------------------------------------------------| + * header: | reserved |append| num | t_i| tid |status| msg_type | + * |-------------------------------------------------------------| + * payload: | MSDU1 ID | MSDU0 ID | + * |-------------------------------------------------------------| + * : MSDU3 ID : MSDU2 ID : + * |-------------------------------------------------------------| + * | struct htt_tx_compl_ind_append_retries | + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * + * The following field definitions describe the format of the TX completion + * indication sent from the target to the host + * Header fields: + * - msg_type + * Bits 7:0 + * Purpose: identifies this as HTT TX completion indication + * Value: 0x7 + * - status + * Bits 10:8 + * Purpose: the TX completion status of payload fragmentations descriptors + * Value: could be HTT_TX_COMPL_IND_STAT_OK or HTT_TX_COMPL_IND_STAT_DISCARD + * - tid + * Bits 14:11 + * Purpose: the tid associated with those fragmentation descriptors. It is + * valid or not, depending on the tid_invalid bit. + * Value: 0 to 15 + * - tid_invalid + * Bits 15:15 + * Purpose: this bit indicates whether the tid field is valid or not + * Value: 0 indicates valid; 1 indicates invalid + * - num + * Bits 23:16 + * Purpose: the number of payload in this indication + * Value: 1 to 255 + * - append + * Bits 24:24 + * Purpose: append the struct htt_tx_compl_ind_append_retries which contains + * the number of tx retries for one MSDU at the end of this message + * Value: 0 indicates no appending; 1 indicates appending + * Payload fields: + * - hmsdu_id + * Bits 15:0 + * Purpose: this ID is used to track the Tx buffer in host + * Value: 0 to "size of host MSDU descriptor pool - 1" + */ + +#define HTT_TX_COMPL_IND_STATUS_S 8 +#define HTT_TX_COMPL_IND_STATUS_M 0x00000700 +#define HTT_TX_COMPL_IND_TID_S 11 +#define HTT_TX_COMPL_IND_TID_M 0x00007800 +#define HTT_TX_COMPL_IND_TID_INV_S 15 +#define HTT_TX_COMPL_IND_TID_INV_M 0x00008000 +#define HTT_TX_COMPL_IND_NUM_S 16 +#define HTT_TX_COMPL_IND_NUM_M 0x00ff0000 +#define HTT_TX_COMPL_IND_APPEND_S 24 +#define HTT_TX_COMPL_IND_APPEND_M 0x01000000 + +#define HTT_TX_COMPL_IND_STATUS_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_COMPL_IND_STATUS, _val); \ + ((_info) |= ((_val) << HTT_TX_COMPL_IND_STATUS_S)); \ + } while (0) +#define HTT_TX_COMPL_IND_STATUS_GET(_info) \ + (((_info) & HTT_TX_COMPL_IND_STATUS_M) >> HTT_TX_COMPL_IND_STATUS_S) +#define HTT_TX_COMPL_IND_NUM_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_COMPL_IND_NUM, _val); \ + ((_info) |= ((_val) << HTT_TX_COMPL_IND_NUM_S)); \ + } while (0) +#define HTT_TX_COMPL_IND_NUM_GET(_info) \ + (((_info) & HTT_TX_COMPL_IND_NUM_M) >> HTT_TX_COMPL_IND_NUM_S) +#define HTT_TX_COMPL_IND_TID_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_COMPL_IND_TID, _val); \ + ((_info) |= ((_val) << HTT_TX_COMPL_IND_TID_S)); \ + } while (0) +#define HTT_TX_COMPL_IND_TID_GET(_info) \ + (((_info) & HTT_TX_COMPL_IND_TID_M) >> HTT_TX_COMPL_IND_TID_S) +#define HTT_TX_COMPL_IND_TID_INV_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_COMPL_IND_TID_INV, _val); \ + ((_info) |= ((_val) << HTT_TX_COMPL_IND_TID_INV_S)); \ + } while (0) +#define HTT_TX_COMPL_IND_TID_INV_GET(_info) \ + (((_info) & HTT_TX_COMPL_IND_TID_INV_M) >> \ + HTT_TX_COMPL_IND_TID_INV_S) +#define HTT_TX_COMPL_IND_APPEND_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_COMPL_IND_APPEND, _val); \ + ((_info) |= ((_val) << HTT_TX_COMPL_IND_APPEND_S)); \ + } while (0) +#define HTT_TX_COMPL_IND_APPEND_GET(_info) \ + (((_info) & HTT_TX_COMPL_IND_APPEND_M) >> HTT_TX_COMPL_IND_APPEND_S) + +#define HTT_TX_COMPL_CTXT_SZ sizeof(A_UINT16) +#define HTT_TX_COMPL_CTXT_NUM(_bytes) ((_bytes) >> 1) + +#define HTT_TX_COMPL_INV_MSDU_ID 0xffff + +#define HTT_TX_COMPL_IND_STAT_OK 0 +#define HTT_TX_COMPL_IND_STAT_DISCARD 1 +#define HTT_TX_COMPL_IND_STAT_NO_ACK 2 +#define HTT_TX_COMPL_IND_STAT_POSTPONE 3 +/* + * The PEER_DEL tx completion status is used for HL cases + * where the peer the frame is for has been deleted. + * The host has already discarded its copy of the frame, but + * it still needs the tx completion to restore its credit. + */ +#define HTT_TX_COMPL_IND_STAT_PEER_DEL 4 + + +#define HTT_TX_COMPL_IND_APPEND_SET_MORE_RETRY(f) ((f) |= 0x1) +#define HTT_TX_COMPL_IND_APPEND_CLR_MORE_RETRY(f) ((f) &= (~0x1)) + +PREPACK struct htt_tx_compl_ind_base { + A_UINT32 hdr; + A_UINT16 payload[1/*or more*/]; +} POSTPACK; + +PREPACK struct htt_tx_compl_ind_append_retries { + A_UINT16 msdu_id; + A_UINT8 tx_retries; + A_UINT8 flag; /* Bit 0, 1: another append_retries struct is appended + 0: this is the last append_retries struct */ +} POSTPACK; + +/** + * @brief target -> host rate-control update indication message + * + * @details + * The following diagram shows the format of the RC Update message + * sent from the target to the host, while processing the tx-completion + * of a transmitted PPDU. + * + * |31 24|23 16|15 8|7 0| + * |-------------------------------------------------------------| + * | peer ID | vdev ID | msg_type | + * |-------------------------------------------------------------| + * | MAC addr 3 | MAC addr 2 | MAC addr 1 | MAC addr 0 | + * |-------------------------------------------------------------| + * | reserved | num elems | MAC addr 5 | MAC addr 4 | + * |-------------------------------------------------------------| + * | : | + * : HTT_RC_TX_DONE_PARAMS (DWORD-aligned) : + * | : | + * |-------------------------------------------------------------| + * | : | + * : HTT_RC_TX_DONE_PARAMS (DWORD-aligned) : + * | : | + * |-------------------------------------------------------------| + * : : + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * + */ + +typedef struct { + A_UINT32 rate_code; /* rate code, bw, chain mask sgi */ + A_UINT32 rate_code_flags; + A_UINT32 flags; /* Encodes information such as excessive + retransmission, aggregate, some info + from .11 frame control, + STBC, LDPC, (SGI and Tx Chain Mask + are encoded in ptx_rc->flags field), + AMPDU truncation (BT/time based etc.), + RTS/CTS attempt */ + + A_UINT32 num_enqued; /* # of MPDUs (for non-AMPDU 1) for this rate */ + A_UINT32 num_retries; /* Total # of transmission attempt for this rate */ + A_UINT32 num_failed; /* # of failed MPDUs in A-MPDU, 0 otherwise */ + A_UINT32 ack_rssi; /* ACK RSSI: b'7..b'0 avg RSSI across all chain */ + A_UINT32 time_stamp ; /* ACK timestamp (helps determine age) */ + A_UINT32 is_probe; /* Valid if probing. Else, 0 */ +} HTT_RC_TX_DONE_PARAMS; + +#define HTT_RC_UPDATE_CTXT_SZ (sizeof(HTT_RC_TX_DONE_PARAMS)) /* bytes */ +#define HTT_RC_UPDATE_HDR_SZ (12) /* bytes */ + +#define HTT_RC_UPDATE_MAC_ADDR_OFFSET (4) /* bytes */ +#define HTT_RC_UPDATE_MAC_ADDR_LENGTH IEEE80211_ADDR_LEN /* bytes */ + +#define HTT_RC_UPDATE_VDEVID_S 8 +#define HTT_RC_UPDATE_VDEVID_M 0xff00 +#define HTT_RC_UPDATE_PEERID_S 16 +#define HTT_RC_UPDATE_PEERID_M 0xffff0000 + +#define HTT_RC_UPDATE_NUM_ELEMS_S 16 +#define HTT_RC_UPDATE_NUM_ELEMS_M 0x00ff0000 + +#define HTT_RC_UPDATE_VDEVID_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RC_UPDATE_VDEVID, _val); \ + ((_info) |= ((_val) << HTT_RC_UPDATE_VDEVID_S)); \ + } while (0) + +#define HTT_RC_UPDATE_VDEVID_GET(_info) \ + (((_info) & HTT_RC_UPDATE_VDEVID_M) >> HTT_RC_UPDATE_VDEVID_S) + +#define HTT_RC_UPDATE_PEERID_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RC_UPDATE_PEERID, _val); \ + ((_info) |= ((_val) << HTT_RC_UPDATE_PEERID_S)); \ + } while (0) + +#define HTT_RC_UPDATE_PEERID_GET(_info) \ + (((_info) & HTT_RC_UPDATE_PEERID_M) >> HTT_RC_UPDATE_PEERID_S) + +#define HTT_RC_UPDATE_NUM_ELEMS_SET(_info, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RC_UPDATE_NUM_ELEMS, _val); \ + ((_info) |= ((_val) << HTT_RC_UPDATE_NUM_ELEMS_S)); \ + } while (0) + +#define HTT_RC_UPDATE_NUM_ELEMS_GET(_info) \ + (((_info) & HTT_RC_UPDATE_NUM_ELEMS_M) >> HTT_RC_UPDATE_NUM_ELEMS_S) + +/** + * @brief target -> host rx fragment indication message definition + * + * @details + * The following field definitions describe the format of the rx fragment + * indication message sent from the target to the host. + * The rx fragment indication message shares the format of the + * rx indication message, but not all fields from the rx indication message + * are relevant to the rx fragment indication message. + * + * + * |31 24|23 18|17|16|15|14|13|12|11|10|9|8|7|6|5|4 0| + * |-----------+-------------------+---------------------+-------------| + * | peer ID | |FV| ext TID | msg type | + * |-------------------------------------------------------------------| + * | | flush | flush | + * | | end | start | + * | | seq num | seq num | + * |-------------------------------------------------------------------| + * | reserved | FW rx desc bytes | + * |-------------------------------------------------------------------| + * | | FW MSDU Rx | + * | | desc B0 | + * |-------------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx fragment indication message + * Value: 0xa + * - EXT_TID + * Bits 12:8 + * Purpose: identify the traffic ID of the rx data, including + * special "extended" TID values for multicast, broadcast, and + * non-QoS data frames + * Value: 0-15 for regular TIDs, or >= 16 for bcast/mcast/non-QoS + * - FLUSH_VALID (FV) + * Bit 13 + * Purpose: indicate whether the flush IE (start/end sequence numbers) + * is valid + * Value: + * 1 -> flush IE is valid and needs to be processed + * 0 -> flush IE is not valid and should be ignored + * - PEER_ID + * Bits 31:16 + * Purpose: Identify, by ID, which peer sent the rx data + * Value: ID of the peer who sent the rx data + * - FLUSH_SEQ_NUM_START + * Bits 5:0 + * Purpose: Indicate the start of a series of MPDUs to flush + * Not all MPDUs within this series are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * This field is only valid if the FV bit is set. + * Value: + * The sequence number for the first MPDUs to check to flush. + * The sequence number is masked by 0x3f. + * - FLUSH_SEQ_NUM_END + * Bits 11:6 + * Purpose: Indicate the end of a series of MPDUs to flush + * Value: + * The sequence number one larger than the sequence number of the + * last MPDU to check to flush. + * The sequence number is masked by 0x3f. + * Not all MPDUs within this series are necessarily valid - the host + * must check each sequence number within this range to see if the + * corresponding MPDU is actually present. + * This field is only valid if the FV bit is set. + * Rx descriptor fields: + * - FW_RX_DESC_BYTES + * Bits 15:0 + * Purpose: Indicate how many bytes in the Rx indication are used for + * FW Rx descriptors + * Value: 1 + */ +#define HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32 2 + +#define HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET 12 + +#define HTT_RX_FRAG_IND_EXT_TID_SET HTT_RX_IND_EXT_TID_SET +#define HTT_RX_FRAG_IND_EXT_TID_GET HTT_RX_IND_EXT_TID_GET + +#define HTT_RX_FRAG_IND_PEER_ID_SET HTT_RX_IND_PEER_ID_SET +#define HTT_RX_FRAG_IND_PEER_ID_GET HTT_RX_IND_PEER_ID_GET + +#define HTT_RX_FRAG_IND_FLUSH_VALID_SET HTT_RX_IND_FLUSH_VALID_SET +#define HTT_RX_FRAG_IND_FLUSH_VALID_GET HTT_RX_IND_FLUSH_VALID_GET + +#define HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_START_SET \ + HTT_RX_IND_FLUSH_SEQ_NUM_START_SET +#define HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_START_GET \ + HTT_RX_IND_FLUSH_SEQ_NUM_START_GET + +#define HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_END_SET \ + HTT_RX_IND_FLUSH_SEQ_NUM_END_SET +#define HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_END_GET \ + HTT_RX_IND_FLUSH_SEQ_NUM_END_GET + +#define HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET HTT_RX_IND_FW_RX_DESC_BYTES_GET + +#define HTT_RX_FRAG_IND_BYTES \ + (4 /* msg hdr */ + \ + 4 /* flush spec */ + \ + 4 /* (unused) FW rx desc bytes spec */ + \ + 4 /* FW rx desc */) + +/** + * @brief target -> host test message definition + * + * @details + * The following field definitions describe the format of the test + * message sent from the target to the host. + * The message consists of a 4-octet header, followed by a variable + * number of 32-bit integer values, followed by a variable number + * of 8-bit character values. + * + * |31 16|15 8|7 0| + * |-----------------------------------------------------------| + * | num chars | num ints | msg type | + * |-----------------------------------------------------------| + * | int 0 | + * |-----------------------------------------------------------| + * | int 1 | + * |-----------------------------------------------------------| + * | ... | + * |-----------------------------------------------------------| + * | char 3 | char 2 | char 1 | char 0 | + * |-----------------------------------------------------------| + * | | | ... | char 4 | + * |-----------------------------------------------------------| + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a test message + * Value: HTT_MSG_TYPE_TEST + * - NUM_INTS + * Bits 15:8 + * Purpose: indicate how many 32-bit integers follow the message header + * - NUM_CHARS + * Bits 31:16 + * Purpose: indicate how many 8-bit charaters follow the series of integers + */ +#define HTT_RX_TEST_NUM_INTS_M 0xff00 +#define HTT_RX_TEST_NUM_INTS_S 8 +#define HTT_RX_TEST_NUM_CHARS_M 0xffff0000 +#define HTT_RX_TEST_NUM_CHARS_S 16 + +#define HTT_RX_TEST_NUM_INTS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_TEST_NUM_INTS, value); \ + (word) |= (value) << HTT_RX_TEST_NUM_INTS_S; \ + } while (0) +#define HTT_RX_TEST_NUM_INTS_GET(word) \ + (((word) & HTT_RX_TEST_NUM_INTS_M) >> HTT_RX_TEST_NUM_INTS_S) + +#define HTT_RX_TEST_NUM_CHARS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_TEST_NUM_CHARS, value); \ + (word) |= (value) << HTT_RX_TEST_NUM_CHARS_S; \ + } while (0) +#define HTT_RX_TEST_NUM_CHARS_GET(word) \ + (((word) & HTT_RX_TEST_NUM_CHARS_M) >> HTT_RX_TEST_NUM_CHARS_S) + +/** + * @brief target -> host packet log message + * + * @details + * The following field definitions describe the format of the packet log + * message sent from the target to the host. + * The message consists of a 4-octet header,followed by a variable number + * of 32-bit character values. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | | | | msg type | + * |-----------------------------------------------------------| + * | payload | + * |-----------------------------------------------------------| + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a test message + * Value: HTT_MSG_TYPE_PACKETLOG + */ +PREPACK struct htt_pktlog_msg { + A_UINT32 header; + A_UINT32 payload[1/* or more */]; +} POSTPACK; + + +/* + * Rx reorder statistics + * NB: all the fields must be defined in 4 octets size. + */ +struct rx_reorder_stats { + /* Non QoS MPDUs received */ + A_UINT32 deliver_non_qos; + /* MPDUs received in-order */ + A_UINT32 deliver_in_order; + /* Flush due to reorder timer expired */ + A_UINT32 deliver_flush_timeout; + /* Flush due to move out of window */ + A_UINT32 deliver_flush_oow; + /* Flush due to DELBA */ + A_UINT32 deliver_flush_delba; + /* MPDUs dropped due to FCS error */ + A_UINT32 fcs_error; + /* MPDUs dropped due to monitor mode non-data packet */ + A_UINT32 mgmt_ctrl; + /* Unicast-data MPDUs dropped due to invalid peer */ + A_UINT32 invalid_peer; + /* MPDUs dropped due to duplication (non aggregation) */ + A_UINT32 dup_non_aggr; + /* MPDUs dropped due to processed before */ + A_UINT32 dup_past; + /* MPDUs dropped due to duplicate in reorder queue */ + A_UINT32 dup_in_reorder; + /* Reorder timeout happened */ + A_UINT32 reorder_timeout; + /* invalid bar ssn */ + A_UINT32 invalid_bar_ssn; + /* reorder reset due to bar ssn */ + A_UINT32 ssn_reset; + /* Flush due to delete peer */ + A_UINT32 deliver_flush_delpeer; + /* Flush due to offload*/ + A_UINT32 deliver_flush_offload; + /* Flush due to out of buffer*/ + A_UINT32 deliver_flush_oob; + /* MPDUs dropped due to PN check fail */ + A_UINT32 pn_fail; + /* MPDUs dropped due to unable to allocate memory */ + A_UINT32 store_fail; + /* Number of times the tid pool alloc succeeded */ + A_UINT32 tid_pool_alloc_succ; + /* Number of times the MPDU pool alloc succeeded */ + A_UINT32 mpdu_pool_alloc_succ; + /* Number of times the MSDU pool alloc succeeded */ + A_UINT32 msdu_pool_alloc_succ; + /* Number of times the tid pool alloc failed */ + A_UINT32 tid_pool_alloc_fail; + /* Number of times the MPDU pool alloc failed */ + A_UINT32 mpdu_pool_alloc_fail; + /* Number of times the MSDU pool alloc failed */ + A_UINT32 msdu_pool_alloc_fail; + /* Number of times the tid pool freed */ + A_UINT32 tid_pool_free; + /* Number of times the MPDU pool freed */ + A_UINT32 mpdu_pool_free; + /* Number of times the MSDU pool freed */ + A_UINT32 msdu_pool_free; + /* number of MSDUs undelivered to HTT and queued to Data Rx MSDU free list*/ + A_UINT32 msdu_queued; + /* Number of MSDUs released from Data Rx MSDU list to MAC ring */ + A_UINT32 msdu_recycled; + /* Number of MPDUs with invalid peer but A2 found in AST */ + A_UINT32 invalid_peer_a2_in_ast; + /* Number of MPDUs with invalid peer but A3 found in AST */ + A_UINT32 invalid_peer_a3_in_ast; + /* Number of MPDUs with invalid peer, Broadcast or Multicast frame */ + A_UINT32 invalid_peer_bmc_mpdus; + /* Number of MSDUs with err attention word */ + A_UINT32 rxdesc_err_att; + /* Number of MSDUs with flag of peer_idx_invalid */ + A_UINT32 rxdesc_err_peer_idx_inv; + /* Number of MSDUs with flag of peer_idx_timeout */ + A_UINT32 rxdesc_err_peer_idx_to; + /* Number of MSDUs with flag of overflow */ + A_UINT32 rxdesc_err_ov; + /* Number of MSDUs with flag of msdu_length_err */ + A_UINT32 rxdesc_err_msdu_len; + /* Number of MSDUs with flag of mpdu_length_err */ + A_UINT32 rxdesc_err_mpdu_len; + /* Number of MSDUs with flag of tkip_mic_err */ + A_UINT32 rxdesc_err_tkip_mic; + /* Number of MSDUs with flag of decrypt_err */ + A_UINT32 rxdesc_err_decrypt; + /* Number of MSDUs with flag of fcs_err */ + A_UINT32 rxdesc_err_fcs; + /* Number of Unicast (bc_mc bit is not set in attention word) + * frames with invalid peer handler + */ + A_UINT32 rxdesc_uc_msdus_inv_peer; + /* Number of unicast frame directly (direct bit is set in attention word) + * to DUT with invalid peer handler + */ + A_UINT32 rxdesc_direct_msdus_inv_peer; + /* Number of Broadcast/Multicast (bc_mc bit set in attention word) + * frames with invalid peer handler + */ + A_UINT32 rxdesc_bmc_msdus_inv_peer; + /* Number of MSDUs dropped due to no first MSDU flag */ + A_UINT32 rxdesc_no_1st_msdu; + /* Number of MSDUs droped due to ring overflow */ + A_UINT32 msdu_drop_ring_ov; + /* Number of MSDUs dropped due to FC mismatch */ + A_UINT32 msdu_drop_fc_mismatch; + /* Number of MSDUs dropped due to mgt frame in Remote ring */ + A_UINT32 msdu_drop_mgmt_remote_ring; + /* Number of MSDUs dropped due to errors not reported in attention word */ + A_UINT32 msdu_drop_misc; + /* Number of MSDUs go to offload before reorder */ + A_UINT32 offload_msdu_wal; + /* Number of data frame dropped by offload after reorder */ + A_UINT32 offload_msdu_reorder; + /* Number of MPDUs with sequence number in the past and within + the BA window */ + A_UINT32 dup_past_within_window; + /* Number of MPDUs with sequence number in the past and + * outside the BA window */ + A_UINT32 dup_past_outside_window; +}; + + +/* + * Rx Remote buffer statistics + * NB: all the fields must be defined in 4 octets size. + */ +struct rx_remote_buffer_mgmt_stats { + /* Total number of MSDUs reaped for Rx processing */ + A_UINT32 remote_reaped; + /* MSDUs recycled within firmware */ + A_UINT32 remote_recycled; + /* MSDUs stored by Data Rx */ + A_UINT32 data_rx_msdus_stored; + /* Number of HTT indications from WAL Rx MSDU */ + A_UINT32 wal_rx_ind; + /* Number of unconsumed HTT indications from WAL Rx MSDU */ + A_UINT32 wal_rx_ind_unconsumed; + /* Number of HTT indications from Data Rx MSDU */ + A_UINT32 data_rx_ind; + /* Number of unconsumed HTT indications from Data Rx MSDU */ + A_UINT32 data_rx_ind_unconsumed; + /* Number of HTT indications from ATHBUF */ + A_UINT32 athbuf_rx_ind; + /* Number of remote buffers requested for refill */ + A_UINT32 refill_buf_req; + /* Number of remote buffers filled by the host */ + A_UINT32 refill_buf_rsp; + /* Number of times MAC hw_index = f/w write_index */ + A_INT32 mac_no_bufs; + /* Number of times f/w write_index = f/w read_index for MAC Rx ring */ + A_INT32 fw_indices_equal; + /* Number of times f/w finds no buffers to post */ + A_INT32 host_no_bufs; +}; + + +/* + * htt_dbg_stats_status - + * present - The requested stats have been delivered in full. + * This indicates that either the stats information was contained + * in its entirety within this message, or else this message + * completes the delivery of the requested stats info that was + * partially delivered through earlier STATS_CONF messages. + * partial - The requested stats have been delivered in part. + * One or more subsequent STATS_CONF messages with the same + * cookie value will be sent to deliver the remainder of the + * information. + * error - The requested stats could not be delivered, for example due + * to a shortage of memory to construct a message holding the + * requested stats. + * invalid - The requested stat type is either not recognized, or the + * target is configured to not gather the stats type in question. + * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * series_done - This special value indicates that no further stats info + * elements are present within a series of stats info elems + * (within a stats upload confirmation message). + */ +enum htt_dbg_stats_status { + HTT_DBG_STATS_STATUS_PRESENT = 0, + HTT_DBG_STATS_STATUS_PARTIAL = 1, + HTT_DBG_STATS_STATUS_ERROR = 2, + HTT_DBG_STATS_STATUS_INVALID = 3, + + + HTT_DBG_STATS_STATUS_SERIES_DONE = 7 +}; + +/** + * @brief target -> host statistics upload + * + * @details + * The following field definitions describe the format of the HTT target + * to host stats upload confirmation message. + * The message contains a cookie echoed from the HTT host->target stats + * upload request, which identifies which request the confirmation is + * for, and a series of tag-length-value stats information elements. + * The tag-length header for each stats info element also includes a + * status field, to indicate whether the request for the stat type in + * question was fully met, partially met, unable to be met, or invalid + * (if the stat type in question is disabled in the target). + * A special value of all 1's in this status field is used to indicate + * the end of the series of stats info elements. + * + * + * |31 16|15 8|7 5|4 0| + * |------------------------------------------------------------| + * | reserved | msg type | + * |------------------------------------------------------------| + * | cookie LSBs | + * |------------------------------------------------------------| + * | cookie MSBs | + * |------------------------------------------------------------| + * | stats entry length | reserved | S |stat type| + * |------------------------------------------------------------| + * | | + * | type-specific stats info | + * | | + * |------------------------------------------------------------| + * | stats entry length | reserved | S |stat type| + * |------------------------------------------------------------| + * | | + * | type-specific stats info | + * | | + * |------------------------------------------------------------| + * | n/a | reserved | 111 | n/a | + * |------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a statistics upload confirmation message + * Value: 0x9 + * - COOKIE_LSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: LSBs of the opaque cookie specified by the host-side requestor + * - COOKIE_MSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: MSBs of the opaque cookie specified by the host-side requestor + * + * Stats Information Element tag-length header fields: + * - STAT_TYPE + * Bits 4:0 + * Purpose: identifies the type of statistics info held in the + * following information element + * Value: htt_dbg_stats_type + * - STATUS + * Bits 7:5 + * Purpose: indicate whether the requested stats are present + * Value: htt_dbg_stats_status, including a special value (0x7) to mark + * the completion of the stats entry series + * - LENGTH + * Bits 31:16 + * Purpose: indicate the stats information size + * Value: This field specifies the number of bytes of stats information + * that follows the element tag-length header. + * It is expected but not required that this length is a multiple of + * 4 bytes. Even if the length is not an integer multiple of 4, the + * subsequent stats entry header will begin on a 4-byte aligned + * boundary. + */ +#define HTT_T2H_STATS_COOKIE_SIZE 8 + +#define HTT_T2H_STATS_CONF_TAIL_SIZE 4 + +#define HTT_T2H_STATS_CONF_HDR_SIZE 4 + +#define HTT_T2H_STATS_CONF_TLV_HDR_SIZE 4 + +#define HTT_T2H_STATS_CONF_TLV_TYPE_M 0x0000001f +#define HTT_T2H_STATS_CONF_TLV_TYPE_S 0 +#define HTT_T2H_STATS_CONF_TLV_STATUS_M 0x000000e0 +#define HTT_T2H_STATS_CONF_TLV_STATUS_S 5 +#define HTT_T2H_STATS_CONF_TLV_LENGTH_M 0xffff0000 +#define HTT_T2H_STATS_CONF_TLV_LENGTH_S 16 + +#define HTT_T2H_STATS_CONF_TLV_TYPE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_STATS_CONF_TLV_TYPE, value); \ + (word) |= (value) << HTT_T2H_STATS_CONF_TLV_TYPE_S; \ + } while (0) +#define HTT_T2H_STATS_CONF_TLV_TYPE_GET(word) \ + (((word) & HTT_T2H_STATS_CONF_TLV_TYPE_M) >> \ + HTT_T2H_STATS_CONF_TLV_TYPE_S) + +#define HTT_T2H_STATS_CONF_TLV_STATUS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_STATS_CONF_TLV_STATUS, value); \ + (word) |= (value) << HTT_T2H_STATS_CONF_TLV_STATUS_S; \ + } while (0) +#define HTT_T2H_STATS_CONF_TLV_STATUS_GET(word) \ + (((word) & HTT_T2H_STATS_CONF_TLV_STATUS_M) >> \ + HTT_T2H_STATS_CONF_TLV_STATUS_S) + +#define HTT_T2H_STATS_CONF_TLV_LENGTH_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_T2H_STATS_CONF_TLV_LENGTH, value); \ + (word) |= (value) << HTT_T2H_STATS_CONF_TLV_LENGTH_S; \ + } while (0) +#define HTT_T2H_STATS_CONF_TLV_LENGTH_GET(word) \ + (((word) & HTT_T2H_STATS_CONF_TLV_LENGTH_M) >> \ + HTT_T2H_STATS_CONF_TLV_LENGTH_S) + +#define HL_HTT_FW_RX_DESC_RSVD_SIZE 18 +#define HTT_MAX_AGGR 64 +#define HTT_HL_MAX_AGGR 18 + +/** + * @brief host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank + * + * @details + * The following field definitions describe the format of the HTT host + * to target frag_desc/msdu_ext bank configuration message. + * The message contains the based address and the min and max id of the + * MSDU_EXT/FRAG_DESC that will be used by the HTT to map MSDU DESC and + * MSDU_EXT/FRAG_DESC. + * HTT will use id in HTT descriptor instead sending the frag_desc_ptr. + * In peregrine the firmware will use fragment_desc_ptr but in WIFI2.0 + * the hardware does the mapping/translation. + * + * Total banks that can be configured is configured to 16. + * + * This should be called before any TX has be initiated by the HTT + * + * |31 16|15 8|7 5|4 0| + * |------------------------------------------------------------| + * | DESC_SIZE | NUM_BANKS | RES |SWP|pdev| msg type | + * |------------------------------------------------------------| + * | BANK0_BASE_ADDRESS (bits 31:0) | +#if HTT_PADDR64 + * | BANK0_BASE_ADDRESS (bits 63:32) | +#endif + * |------------------------------------------------------------| + * | ... | + * |------------------------------------------------------------| + * | BANK15_BASE_ADDRESS (bits 31:0) | +#if HTT_PADDR64 + * | BANK15_BASE_ADDRESS (bits 63:32) | +#endif + * |------------------------------------------------------------| + * | BANK0_MAX_ID | BANK0_MIN_ID | + * |------------------------------------------------------------| + * | ... | + * |------------------------------------------------------------| + * | BANK15_MAX_ID | BANK15_MIN_ID | + * |------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Value: 0x6 + * for systems with 64-bit format for bus addresses: + * - BANKx_BASE_ADDRESS_LO + * Bits 31:0 + * Purpose: Provide a mechanism to specify the base address of the + * MSDU_EXT bank physical/bus address. + * Value: lower 4 bytes of MSDU_EXT bank physical / bus address + * - BANKx_BASE_ADDRESS_HI + * Bits 31:0 + * Purpose: Provide a mechanism to specify the base address of the + * MSDU_EXT bank physical/bus address. + * Value: higher 4 bytes of MSDU_EXT bank physical / bus address + * for systems with 32-bit format for bus addresses: + * - BANKx_BASE_ADDRESS + * Bits 31:0 + * Purpose: Provide a mechanism to specify the base address of the + * MSDU_EXT bank physical/bus address. + * Value: MSDU_EXT bank physical / bus address + * - BANKx_MIN_ID + * Bits 15:0 + * Purpose: Provide a mechanism to specify the min index that needs to + * mapped. + * - BANKx_MAX_ID + * Bits 31:16 + * Purpose: Provide a mechanism to specify the max index that needs to + * mapped. + * + */ + +/** @todo Compress the fields to fit MAX HTT Message size, until then configure to a + * safe value. + * @note MAX supported banks is 16. + */ +#define HTT_TX_MSDU_EXT_BANK_MAX 4 + +#define HTT_H2T_FRAG_DESC_BANK_PDEVID_M 0x300 +#define HTT_H2T_FRAG_DESC_BANK_PDEVID_S 8 + +#define HTT_H2T_FRAG_DESC_BANK_SWAP_M 0x400 +#define HTT_H2T_FRAG_DESC_BANK_SWAP_S 10 + +#define HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_M 0xff0000 +#define HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_S 16 + +#define HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_M 0xff000000 +#define HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_S 24 + +#define HTT_H2T_FRAG_DESC_BANK_MIN_IDX_M 0xffff +#define HTT_H2T_FRAG_DESC_BANK_MIN_IDX_S 0 + +#define HTT_H2T_FRAG_DESC_BANK_MAX_IDX_M 0xffff0000 +#define HTT_H2T_FRAG_DESC_BANK_MAX_IDX_S 16 + +#define HTT_H2T_FRAG_DESC_BANK_PDEVID_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_PDEVID, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_PDEVID_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_PDEVID_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_PDEVID_M) >> HTT_H2T_FRAG_DESC_BANK_PDEVID_S) + +#define HTT_H2T_FRAG_DESC_BANK_SWAP_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_SWAP, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_SWAP_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_SWAP_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_SWAP_M) >> HTT_H2T_FRAG_DESC_BANK_SWAP_S) + +#define HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_NUM_BANKS, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_M) >> HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_S) + +#define HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_DESC_SIZE, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_M) >> HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_S) + +#define HTT_H2T_FRAG_DESC_BANK_MIN_IDX_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_MIN_IDX, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_MIN_IDX_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_MIN_IDX_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_MIN_IDX_M) >> HTT_H2T_FRAG_DESC_BANK_MIN_IDX_S) + +#define HTT_H2T_FRAG_DESC_BANK_MAX_IDX_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_H2T_FRAG_DESC_BANK_MAX_IDX, value); \ + (word) |= ((value) << HTT_H2T_FRAG_DESC_BANK_MAX_IDX_S); \ + } while (0) +#define HTT_H2T_FRAG_DESC_BANK_MAX_IDX_GET(word) \ + (((word) & HTT_H2T_FRAG_DESC_BANK_MAX_IDX_M) >> HTT_H2T_FRAG_DESC_BANK_MAX_IDX_S) + + +/* + * TEMPLATE_HTT_TX_FRAG_DESC_BANK_CFG_T: + * This macro defines a htt_tx_frag_descXXX_bank_cfg_t in which any physical + * addresses are stored in a XXX-bit field. + * This macro is used to define both htt_tx_frag_desc32_bank_cfg_t and + * htt_tx_frag_desc64_bank_cfg_t structs. + */ +#define TEMPLATE_HTT_TX_FRAG_DESC_BANK_CFG_T( \ + _paddr_bits_, \ + _paddr__bank_base_address_) \ +PREPACK struct htt_tx_frag_desc ## _paddr_bits_ ## _bank_cfg_t { \ + /** word 0 \ + * msg_type: 8, \ + * pdev_id: 2, \ + * swap: 1, \ + * reserved0: 5, \ + * num_banks: 8, \ + * desc_size: 8; \ + */ \ + A_UINT32 word0; \ + /* \ + * If bank_base_address is 64 bits, the upper / lower halves are stored \ + * in little-endian order (bytes 0-3 in the first A_UINT32, bytes 4-7 in \ + * the second A_UINT32). \ + */ \ + _paddr__bank_base_address_[HTT_TX_MSDU_EXT_BANK_MAX]; \ + A_UINT32 bank_info[HTT_TX_MSDU_EXT_BANK_MAX]; \ +} POSTPACK +/* define htt_tx_frag_desc32_bank_cfg_t */ +TEMPLATE_HTT_TX_FRAG_DESC_BANK_CFG_T(32, HTT_VAR_PADDR32(bank_base_address)); +/* define htt_tx_frag_desc64_bank_cfg_t */ +TEMPLATE_HTT_TX_FRAG_DESC_BANK_CFG_T(64, HTT_VAR_PADDR64_LE(bank_base_address)); +/* + * Make htt_tx_frag_desc_bank_cfg_t be an alias for either + * htt_tx_frag_desc32_bank_cfg_t or htt_tx_frag_desc64_bank_cfg_t + */ +#if HTT_PADDR64 + #define htt_tx_frag_desc_bank_cfg_t htt_tx_frag_desc64_bank_cfg_t +#else + #define htt_tx_frag_desc_bank_cfg_t htt_tx_frag_desc32_bank_cfg_t +#endif + + +/** + * @brief target -> host HTT TX Credit total count update message definition + * + *|31 16|15|14 9| 8 |7 0 | + *|---------------------+--+----------+-------+----------| + *|cur htt credit delta | Q| reserved | sign | msg type | + *|------------------------------------------------------| + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a htt tx credit delta update message + * Value: 0xe + * - SIGN + * Bits 8 + * identifies whether credit delta is positive or negative + * Value: + * - 0x0: credit delta is positive, rebalance in some buffers + * - 0x1: credit delta is negative, rebalance out some buffers + * - reserved + * Bits 14:9 + * Value: 0x0 + * - TXQ_GRP + * Bit 15 + * Purpose: indicates whether any tx queue group information elements + * are appended to the tx credit update message + * Value: 0 -> no tx queue group information element is present + * 1 -> a tx queue group information element immediately follows + * - DELTA_COUNT + * Bits 31:16 + * Purpose: Specify current htt credit delta absolute count + */ + +#define HTT_TX_CREDIT_SIGN_BIT_M 0x00000100 +#define HTT_TX_CREDIT_SIGN_BIT_S 8 +#define HTT_TX_CREDIT_TXQ_GRP_M 0x00008000 +#define HTT_TX_CREDIT_TXQ_GRP_S 15 +#define HTT_TX_CREDIT_DELTA_ABS_M 0xffff0000 +#define HTT_TX_CREDIT_DELTA_ABS_S 16 + + +#define HTT_TX_CREDIT_SIGN_BIT_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_CREDIT_SIGN_BIT, value); \ + (word) |= (value) << HTT_TX_CREDIT_SIGN_BIT_S; \ + } while (0) + +#define HTT_TX_CREDIT_SIGN_BIT_GET(word) \ + (((word) & HTT_TX_CREDIT_SIGN_BIT_M) >> HTT_TX_CREDIT_SIGN_BIT_S) + +#define HTT_TX_CREDIT_TXQ_GRP_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_CREDIT_TXQ_GRP, value); \ + (word) |= (value) << HTT_TX_CREDIT_TXQ_GRP_S; \ + } while (0) + +#define HTT_TX_CREDIT_TXQ_GRP_GET(word) \ + (((word) & HTT_TX_CREDIT_TXQ_GRP_M) >> HTT_TX_CREDIT_TXQ_GRP_S) + +#define HTT_TX_CREDIT_DELTA_ABS_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_TX_CREDIT_DELTA_ABS, value); \ + (word) |= (value) << HTT_TX_CREDIT_DELTA_ABS_S; \ + } while (0) + +#define HTT_TX_CREDIT_DELTA_ABS_GET(word) \ + (((word) & HTT_TX_CREDIT_DELTA_ABS_M) >> HTT_TX_CREDIT_DELTA_ABS_S) + + +#define HTT_TX_CREDIT_MSG_BYTES 4 + +#define HTT_TX_CREDIT_SIGN_BIT_POSITIVE 0x0 +#define HTT_TX_CREDIT_SIGN_BIT_NEGATIVE 0x1 + + +/** + * @brief HTT WDI_IPA Operation Response Message + * + * @details + * HTT WDI_IPA Operation Response message is sent by target + * to host confirming suspend or resume operation. + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | op_code | Rsvd | msg_type | + * |-------------------------------------------------------------------| + * | Rsvd | Response len | + * |-------------------------------------------------------------------| + * | | + * | Response-type specific info | + * | | + * | | + * |-------------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this as WDI_IPA Operation Response message + * value: = 0x13 + * - OP_CODE + * Bits 31:16 + * Purpose: Identifies the operation target is responding to (e.g. TX suspend) + * value: = enum htt_wdi_ipa_op_code + * - RSP_LEN + * Bits 16:0 + * Purpose: length for the response-type specific info + * value: = length in bytes for response-type specific info + * For example, if OP_CODE == HTT_WDI_IPA_OPCODE_DBG_STATS, the + * length value will be sizeof(struct wlan_wdi_ipa_dbg_stats_t). + */ + +PREPACK struct htt_wdi_ipa_op_response_t +{ + /* DWORD 0: flags and meta-data */ + A_UINT32 + msg_type: 8, /* HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE */ + reserved1: 8, + op_code: 16; + A_UINT32 + rsp_len: 16, + reserved2: 16; +} POSTPACK; + +#define HTT_WDI_IPA_OP_RESPONSE_SZ 8 /* bytes */ + +#define HTT_WDI_IPA_OP_RESPONSE_OP_CODE_M 0xffff0000 +#define HTT_WDI_IPA_OP_RESPONSE_OP_CODE_S 16 + +#define HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_M 0x0000ffff +#define HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_S 0 + +#define HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(_var) \ + (((_var) & HTT_WDI_IPA_OP_RESPONSE_OP_CODE_M) >> HTT_WDI_IPA_OP_RESPONSE_OP_CODE_S) +#define HTT_WDI_IPA_OP_RESPONSE_OP_CODE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_OP_RESPONSE_OP_CODE, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_OP_RESPONSE_OP_CODE_S)); \ + } while (0) + +#define HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(_var) \ + (((_var) & HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_M) >> HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_S) +#define HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_WDI_IPA_OP_RESPONSE_RSP_LEN, _val); \ + ((_var) |= ((_val) << HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_S)); \ + } while (0) + + +enum htt_phy_mode { + htt_phy_mode_11a = 0, + htt_phy_mode_11g = 1, + htt_phy_mode_11b = 2, + htt_phy_mode_11g_only = 3, + htt_phy_mode_11na_ht20 = 4, + htt_phy_mode_11ng_ht20 = 5, + htt_phy_mode_11na_ht40 = 6, + htt_phy_mode_11ng_ht40 = 7, + htt_phy_mode_11ac_vht20 = 8, + htt_phy_mode_11ac_vht40 = 9, + htt_phy_mode_11ac_vht80 = 10, + htt_phy_mode_11ac_vht20_2g = 11, + htt_phy_mode_11ac_vht40_2g = 12, + htt_phy_mode_11ac_vht80_2g = 13, + htt_phy_mode_11ac_vht80_80 = 14, /* 80+80 */ + htt_phy_mode_11ac_vht160 = 15, + + htt_phy_mode_max, +}; + +/** + * @brief target -> host HTT channel change indication + * @details + * Specify when a channel change occurs. + * This allows the host to precisely determine which rx frames arrived + * on the old channel and which rx frames arrived on the new channel. + * + *|31 |7 0 | + *|-------------------------------------------+----------| + *| reserved | msg type | + *|------------------------------------------------------| + *| primary_chan_center_freq_mhz | + *|------------------------------------------------------| + *| contiguous_chan1_center_freq_mhz | + *|------------------------------------------------------| + *| contiguous_chan2_center_freq_mhz | + *|------------------------------------------------------| + *| phy_mode | + *|------------------------------------------------------| + * + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as a htt channel change indication message + * Value: 0x15 + * - PRIMARY_CHAN_CENTER_FREQ_MHZ + * Bits 31:0 + * Purpose: identify the (center of the) new 20 MHz primary channel + * Value: center frequency of the 20 MHz primary channel, in MHz units + * - CONTIG_CHAN1_CENTER_FREQ_MHZ + * Bits 31:0 + * Purpose: identify the (center of the) contiguous frequency range + * comprising the new channel. + * For example, if the new channel is a 80 MHz channel extending + * 60 MHz beyond the primary channel, this field would be 30 larger + * than the primary channel center frequency field. + * Value: center frequency of the contiguous frequency range comprising + * the full channel in MHz units + * (80+80 channels also use the CONTIG_CHAN2 field) + * - CONTIG_CHAN2_CENTER_FREQ_MHZ + * Bits 31:0 + * Purpose: Identify the (center of the) 80 MHz extension frequency range + * within a VHT 80+80 channel. + * This field is only relevant for VHT 80+80 channels. + * Value: center frequency of the 80 MHz extension channel in a VHT 80+80 + * channel (arbitrary value for cases besides VHT 80+80) + * - PHY_MODE + * Bits 31:0 + * Purpose: specify the PHY channel's type (legacy vs. HT vs. VHT), width, + * and band + * Value: htt_phy_mode enum value + */ + +PREPACK struct htt_chan_change_t +{ + /* DWORD 0: flags and meta-data */ + A_UINT32 + msg_type: 8, /* HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE */ + reserved1: 24; + A_UINT32 primary_chan_center_freq_mhz; + A_UINT32 contig_chan1_center_freq_mhz; + A_UINT32 contig_chan2_center_freq_mhz; + A_UINT32 phy_mode; +} POSTPACK; + +#define HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_M 0xffffffff +#define HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_S 0 +#define HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_M 0xffffffff +#define HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_S 0 +#define HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_M 0xffffffff +#define HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_S 0 +#define HTT_CHAN_CHANGE_PHY_MODE_M 0xffffffff +#define HTT_CHAN_CHANGE_PHY_MODE_S 0 + + +#define HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ, value);\ + (word) |= (value) << HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_S; \ + } while (0) +#define HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_GET(word) \ + (((word) & HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_M) \ + >> HTT_CHAN_CHANGE_PRIMARY_CHAN_CENTER_FREQ_MHZ_S) + +#define HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ, value);\ + (word) |= (value) << HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_S; \ + } while (0) +#define HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_GET(word) \ + (((word) & HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_M) \ + >> HTT_CHAN_CHANGE_CONTIG_CHAN1_CENTER_FREQ_MHZ_S) + +#define HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ, value);\ + (word) |= (value) << HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_S; \ + } while (0) +#define HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_GET(word) \ + (((word) & HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_M) \ + >> HTT_CHAN_CHANGE_CONTIG_CHAN2_CENTER_FREQ_MHZ_S) + +#define HTT_CHAN_CHANGE_PHY_MODE_SET(word, value) \ + do { \ + HTT_CHECK_SET_VAL(HTT_CHAN_CHANGE_PHY_MODE, value);\ + (word) |= (value) << HTT_CHAN_CHANGE_PHY_MODE_S; \ + } while (0) +#define HTT_CHAN_CHANGE_PHY_MODE_GET(word) \ + (((word) & HTT_CHAN_CHANGE_PHY_MODE_M) \ + >> HTT_CHAN_CHANGE_PHY_MODE_S) + +#define HTT_CHAN_CHANGE_BYTES sizeof(struct htt_chan_change_t) + + +/** + * @brief rx offload packet error message + * + * @details + * HTT_RX_OFLD_PKT_ERR message is sent by target to host to indicate err + * of target payload like mic err. + * + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | tid | vdev_id | msg_sub_type | msg_type | + * |-------------------------------------------------------------------| + * : (sub-type dependent content) : + * :- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -: + * Header fields: + * - msg_type + * Bits 7:0 + * Purpose: Identifies this as HTT_RX_OFLD_PKT_ERR message + * value: 0x16 (HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR) + * - msg_sub_type + * Bits 15:8 + * Purpose: Identifies which type of rx error is reported by this message + * value: htt_rx_ofld_pkt_err_type + * - vdev_id + * Bits 23:16 + * Purpose: Identifies which vdev received the erroneous rx frame + * value: + * - tid + * Bits 31:24 + * Purpose: Identifies the traffic type of the rx frame + * value: + * + * - The payload fields used if the sub-type == MIC error are shown below. + * Note - MIC err is per MSDU, while PN is per MPDU. + * The FW will discard the whole MPDU if any MSDU within the MPDU is marked + * with MIC err in A-MSDU case, so FW will send only one HTT message + * with the PN of this MPDU attached to indicate MIC err for one MPDU + * instead of sending separate HTT messages for each wrong MSDU within + * the MPDU. + * + * |31 24|23 16|15 8|7 0| + * |----------------+----------------+----------------+----------------| + * | Rsvd | key_id | peer_id | + * |-------------------------------------------------------------------| + * | receiver MAC addr 31:0 | + * |-------------------------------------------------------------------| + * | Rsvd | receiver MAC addr 47:32 | + * |-------------------------------------------------------------------| + * | transmitter MAC addr 31:0 | + * |-------------------------------------------------------------------| + * | Rsvd | transmitter MAC addr 47:32 | + * |-------------------------------------------------------------------| + * | PN 31:0 | + * |-------------------------------------------------------------------| + * | Rsvd | PN 47:32 | + * |-------------------------------------------------------------------| + * - peer_id + * Bits 15:0 + * Purpose: identifies which peer is frame is from + * value: + * - key_id + * Bits 23:16 + * Purpose: identifies key_id of rx frame + * value: + * - RA_31_0 (receiver MAC addr 31:0) + * Bits 31:0 + * Purpose: identifies by MAC address which vdev received the frame + * value: MAC address lower 4 bytes + * - RA_47_32 (receiver MAC addr 47:32) + * Bits 15:0 + * Purpose: identifies by MAC address which vdev received the frame + * value: MAC address upper 2 bytes + * - TA_31_0 (transmitter MAC addr 31:0) + * Bits 31:0 + * Purpose: identifies by MAC address which peer transmitted the frame + * value: MAC address lower 4 bytes + * - TA_47_32 (transmitter MAC addr 47:32) + * Bits 15:0 + * Purpose: identifies by MAC address which peer transmitted the frame + * value: MAC address upper 2 bytes + * - PN_31_0 + * Bits 31:0 + * Purpose: Identifies pn of rx frame + * value: PN lower 4 bytes + * - PN_47_32 + * Bits 15:0 + * Purpose: Identifies pn of rx frame + * value: + * TKIP or CCMP: PN upper 2 bytes + * WAPI: PN bytes 6:5 (bytes 15:7 not included in this message) + */ + +enum htt_rx_ofld_pkt_err_type { + HTT_RX_OFLD_PKT_ERR_TYPE_NONE = 0, + HTT_RX_OFLD_PKT_ERR_TYPE_MIC_ERR, +}; + +/* definition for HTT_RX_OFLD_PKT_ERR msg hdr */ +#define HTT_RX_OFLD_PKT_ERR_HDR_BYTES 4 + +#define HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_M 0x0000ff00 +#define HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_S 8 + +#define HTT_RX_OFLD_PKT_ERR_VDEV_ID_M 0x00ff0000 +#define HTT_RX_OFLD_PKT_ERR_VDEV_ID_S 16 + +#define HTT_RX_OFLD_PKT_ERR_TID_M 0xff000000 +#define HTT_RX_OFLD_PKT_ERR_TID_S 24 + +#define HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_M) \ + >> HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_S) +#define HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_VDEV_ID_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_VDEV_ID_M) >> HTT_RX_OFLD_PKT_ERR_VDEV_ID_S) +#define HTT_RX_OFLD_PKT_ERR_VDEV_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_VDEV_ID, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_VDEV_ID_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_TID_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_TID_M) >> HTT_RX_OFLD_PKT_ERR_TID_S) +#define HTT_RX_OFLD_PKT_ERR_TID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_TID, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_TID_S)); \ + } while (0) + +/* definition for HTT_RX_OFLD_PKT_ERR_MIC_ERR msg sub-type payload */ +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_BYTES 28 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_M 0x0000ffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_M 0x00ff0000 +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_S 16 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_M 0xffffffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_M 0x0000ffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_M 0xffffffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_M 0x0000ffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_M 0xffffffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_M 0x0000ffff +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_S 0 + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_31_0_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_RA_47_32_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_31_0_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_TA_47_32_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_31_0_S)); \ + } while (0) + +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_GET(_var) \ + (((_var) & HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_M) >> \ + HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_S) +#define HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_SET(_var, _val) \ + do { \ + HTT_CHECK_SET_VAL(HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32, _val); \ + ((_var) |= ((_val) << HTT_RX_OFLD_PKT_ERR_MIC_ERR_PN_47_32_S)); \ + } while (0) + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_common.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_common.h new file mode 100644 index 0000000000000..d187adebcdc6f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_common.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_common.h + * + * @details the public header file of HTT layer shared between host and firmware + */ + +#ifndef _HTT_COMMON_H_ +#define _HTT_COMMON_H_ + +enum htt_sec_type { + htt_sec_type_none, + htt_sec_type_wep128, + htt_sec_type_wep104, + htt_sec_type_wep40, + htt_sec_type_tkip, + htt_sec_type_tkip_nomic, + htt_sec_type_aes_ccmp, + htt_sec_type_wapi, + + /* keep this last! */ + htt_num_sec_types +}; + + +enum htt_rx_ind_mpdu_status { + HTT_RX_IND_MPDU_STATUS_UNKNOWN = 0x0, + HTT_RX_IND_MPDU_STATUS_OK, + HTT_RX_IND_MPDU_STATUS_ERR_FCS, + HTT_RX_IND_MPDU_STATUS_ERR_DUP, + HTT_RX_IND_MPDU_STATUS_ERR_REPLAY, + HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER, + HTT_RX_IND_MPDU_STATUS_UNAUTH_PEER, /* only accept EAPOL frames */ + HTT_RX_IND_MPDU_STATUS_OUT_OF_SYNC, + HTT_RX_IND_MPDU_STATUS_MGMT_CTRL, /* Non-data in promiscous mode */ + HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR, + + /* + * MISC: discard for unspecified reasons. + * Leave this enum value last. + */ + HTT_RX_IND_MPDU_STATUS_ERR_MISC = 0xFF +}; + + +#endif /* _HTT_COMMON_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c new file mode 100644 index 0000000000000..cb7608f5d3ce3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_fw_stats.c @@ -0,0 +1,847 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_fw_stats.c + * @brief Provide functions to process FW status retrieved from FW. + */ + +#include /* HTC_PACKET */ +#include /* HTT_T2H_MSG_TYPE, etc. */ +#include /* adf_nbuf_t */ +#include /* adf_os_mem_set */ +#include /* ol_fw_tx_dbg_ppdu_base */ + +#include +#include /* htt_tx_status */ + +#include + +#include + +#define ROUND_UP_TO_4(val) (((val) + 3) & ~0x3) + +static void htt_t2h_stats_tx_rate_stats_print( + wlan_dbg_tx_rate_info_t *tx_rate_info, int concise) +{ + adf_os_print("TX Rate Info:\n"); + + /* MCS */ + adf_os_print("MCS counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + tx_rate_info->mcs[0], + tx_rate_info->mcs[1], + tx_rate_info->mcs[2], + tx_rate_info->mcs[3], + tx_rate_info->mcs[4], + tx_rate_info->mcs[5], + tx_rate_info->mcs[6], + tx_rate_info->mcs[7], + tx_rate_info->mcs[8], + tx_rate_info->mcs[9] + ); + + /* SGI */ + adf_os_print("SGI counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + tx_rate_info->sgi[0], + tx_rate_info->sgi[1], + tx_rate_info->sgi[2], + tx_rate_info->sgi[3], + tx_rate_info->sgi[4], + tx_rate_info->sgi[5], + tx_rate_info->sgi[6], + tx_rate_info->sgi[7], + tx_rate_info->sgi[8], + tx_rate_info->sgi[9] + ); + + /* NSS */ + adf_os_print("NSS counts: "); + adf_os_print("1x1 %d, 2x2 %d, 3x3 %d\n", + tx_rate_info->nss[0], + tx_rate_info->nss[1], + tx_rate_info->nss[2] + ); + + /* BW */ + adf_os_print("BW counts: "); + adf_os_print("20MHz %d, 40MHz %d, 80MHz %d\n", + tx_rate_info->bw[0], + tx_rate_info->bw[1], + tx_rate_info->bw[2] + ); + + /* Preamble */ + adf_os_print("Preamble (O C H V) counts: "); + adf_os_print("%d, %d, %d, %d\n", + tx_rate_info->pream[0], + tx_rate_info->pream[1], + tx_rate_info->pream[2], + tx_rate_info->pream[3] + ); + + /* STBC rate counts */ + adf_os_print("STBC rate counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + tx_rate_info->stbc[0], + tx_rate_info->stbc[1], + tx_rate_info->stbc[2], + tx_rate_info->stbc[3], + tx_rate_info->stbc[4], + tx_rate_info->stbc[5], + tx_rate_info->stbc[6], + tx_rate_info->stbc[7], + tx_rate_info->stbc[8], + tx_rate_info->stbc[9] + ); + + /* LDPC and TxBF counts */ + adf_os_print("LDPC Counts: "); + adf_os_print("%d\n", tx_rate_info->ldpc); + adf_os_print("RTS Counts: "); + adf_os_print("%d\n", tx_rate_info->rts_cnt); + /* RSSI Values for last ack frames */ + adf_os_print("Ack RSSI: %d\n",tx_rate_info->ack_rssi); +} + +static void htt_t2h_stats_rx_rate_stats_print( + wlan_dbg_rx_rate_info_t *rx_phy_info, int concise) +{ + adf_os_print("RX Rate Info:\n"); + + /* MCS */ + adf_os_print("MCS counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + rx_phy_info->mcs[0], + rx_phy_info->mcs[1], + rx_phy_info->mcs[2], + rx_phy_info->mcs[3], + rx_phy_info->mcs[4], + rx_phy_info->mcs[5], + rx_phy_info->mcs[6], + rx_phy_info->mcs[7], + rx_phy_info->mcs[8], + rx_phy_info->mcs[9] + ); + + /* SGI */ + adf_os_print("SGI counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + rx_phy_info->sgi[0], + rx_phy_info->sgi[1], + rx_phy_info->sgi[2], + rx_phy_info->sgi[3], + rx_phy_info->sgi[4], + rx_phy_info->sgi[5], + rx_phy_info->sgi[6], + rx_phy_info->sgi[7], + rx_phy_info->sgi[8], + rx_phy_info->sgi[9] + ); + + /* NSS */ + adf_os_print("NSS counts: "); + /* nss[0] just holds the count of non-stbc frames that were sent at 1x1 + * rates and nsts holds the count of frames sent with stbc. It was decided + * to not include PPDUs sent w/ STBC in nss[0] since it would be easier to + * change the value that needs to be printed (from "stbc+non-stbc count to + * only non-stbc count") if needed in the future. Hence the addition in the + * host code at this line. */ + adf_os_print("1x1 %d, 2x2 %d, 3x3 %d, 4x4 %d\n", + rx_phy_info->nss[0] + rx_phy_info->nsts, + rx_phy_info->nss[1], + rx_phy_info->nss[2], + rx_phy_info->nss[3] + ); + + /* NSTS */ + adf_os_print("NSTS count: "); + adf_os_print("%d\n", rx_phy_info->nsts); + + /* BW */ + adf_os_print("BW counts: "); + adf_os_print("20MHz %d, 40MHz %d, 80MHz %d\n", + rx_phy_info->bw[0], + rx_phy_info->bw[1], + rx_phy_info->bw[2] + ); + + /* Preamble */ + adf_os_print("Preamble counts: "); + adf_os_print("%d, %d, %d, %d, %d, %d\n", + rx_phy_info->pream[0], + rx_phy_info->pream[1], + rx_phy_info->pream[2], + rx_phy_info->pream[3], + rx_phy_info->pream[4], + rx_phy_info->pream[5] + ); + + /* STBC rate counts */ + adf_os_print("STBC rate counts (0..9): "); + adf_os_print("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", + rx_phy_info->stbc[0], + rx_phy_info->stbc[1], + rx_phy_info->stbc[2], + rx_phy_info->stbc[3], + rx_phy_info->stbc[4], + rx_phy_info->stbc[5], + rx_phy_info->stbc[6], + rx_phy_info->stbc[7], + rx_phy_info->stbc[8], + rx_phy_info->stbc[9] + ); + + /* LDPC and TxBF counts */ + adf_os_print("LDPC TXBF Counts: "); + adf_os_print("%d, %d\n", rx_phy_info->ldpc, rx_phy_info->txbf); + /* RSSI Values for last received frames */ + adf_os_print("RSSI (data, mgmt): %d, %d\n",rx_phy_info->data_rssi, + rx_phy_info->mgmt_rssi); + + adf_os_print("RSSI Chain 0 (0x%02x 0x%02x 0x%02x 0x%02x)\n", + ((rx_phy_info->rssi_chain0 >> 24) & 0xff), + ((rx_phy_info->rssi_chain0 >> 16) & 0xff), + ((rx_phy_info->rssi_chain0 >> 8) & 0xff), + ((rx_phy_info->rssi_chain0 >> 0) & 0xff)); + + adf_os_print("RSSI Chain 1 (0x%02x 0x%02x 0x%02x 0x%02x)\n", + ((rx_phy_info->rssi_chain1 >> 24) & 0xff), + ((rx_phy_info->rssi_chain1 >> 16) & 0xff), + ((rx_phy_info->rssi_chain1 >> 8) & 0xff), + ((rx_phy_info->rssi_chain1 >> 0) & 0xff)); + + adf_os_print("RSSI Chain 2 (0x%02x 0x%02x 0x%02x 0x%02x)\n", + ((rx_phy_info->rssi_chain2 >> 24) & 0xff), + ((rx_phy_info->rssi_chain2 >> 16) & 0xff), + ((rx_phy_info->rssi_chain2 >> 8) & 0xff), + ((rx_phy_info->rssi_chain2 >> 0) & 0xff)); +} + + +static void +htt_t2h_stats_pdev_stats_print( + struct wlan_dbg_stats *wlan_pdev_stats, int concise) +{ + struct wlan_dbg_tx_stats *tx = &wlan_pdev_stats->tx; + struct wlan_dbg_rx_stats *rx = &wlan_pdev_stats->rx; + + adf_os_print("WAL Pdev stats:\n"); + adf_os_print("\n### Tx ###\n"); + + /* Num HTT cookies queued to dispatch list */ + adf_os_print("comp_queued :\t%d\n",tx->comp_queued); + /* Num HTT cookies dispatched */ + adf_os_print("comp_delivered :\t%d\n",tx->comp_delivered); + /* Num MSDU queued to WAL */ + adf_os_print("msdu_enqued :\t%d\n",tx->msdu_enqued); + /* Num MPDU queued to WAL */ + adf_os_print("mpdu_enqued :\t%d\n",tx->mpdu_enqued); + /* Num MSDUs dropped by WMM limit */ + adf_os_print("wmm_drop :\t%d\n",tx->wmm_drop); + /* Num Local frames queued */ + adf_os_print("local_enqued :\t%d\n",tx->local_enqued); + /* Num Local frames done */ + adf_os_print("local_freed :\t%d\n",tx->local_freed); + /* Num queued to HW */ + adf_os_print("hw_queued :\t%d\n",tx->hw_queued); + /* Num PPDU reaped from HW */ + adf_os_print("hw_reaped :\t%d\n",tx->hw_reaped); + /* Num underruns */ + adf_os_print("mac underrun :\t%d\n",tx->underrun); + /* Num underruns */ + adf_os_print("phy underrun :\t%d\n",tx->phy_underrun); + /* Num PPDUs cleaned up in TX abort */ + adf_os_print("tx_abort :\t%d\n",tx->tx_abort); + /* Num MPDUs requed by SW */ + adf_os_print("mpdus_requed :\t%d\n",tx->mpdus_requed); + /* Excessive retries */ + adf_os_print("excess retries :\t%d\n",tx->tx_ko); + /* last data rate */ + adf_os_print("last rc :\t%d\n",tx->data_rc); + /* scheduler self triggers */ + adf_os_print("sched self trig :\t%d\n",tx->self_triggers); + /* SW retry failures */ + adf_os_print("ampdu retry failed:\t%d\n",tx->sw_retry_failure); + /* ilegal phy rate errirs */ + adf_os_print("illegal rate errs :\t%d\n",tx->illgl_rate_phy_err); + /* pdev continous excessive retries */ + adf_os_print("pdev cont xretry :\t%d\n",tx->pdev_cont_xretry); + /* pdev continous excessive retries */ + adf_os_print("pdev tx timeout :\t%d\n",tx->pdev_tx_timeout); + /* pdev resets */ + adf_os_print("pdev resets :\t%d\n",tx->pdev_resets); + /* PPDU > txop duration */ + adf_os_print("ppdu txop ovf :\t%d\n",tx->txop_ovf); + + adf_os_print("\n### Rx ###\n"); + /* Cnts any change in ring routing mid-ppdu */ + adf_os_print("ppdu_route_change :\t%d\n",rx->mid_ppdu_route_change); + /* Total number of statuses processed */ + adf_os_print("status_rcvd :\t%d\n",rx->status_rcvd); + /* Extra frags on rings 0-3 */ + adf_os_print("r0_frags :\t%d\n",rx->r0_frags); + adf_os_print("r1_frags :\t%d\n",rx->r1_frags); + adf_os_print("r2_frags :\t%d\n",rx->r2_frags); + adf_os_print("r3_frags :\t%d\n",rx->r3_frags); + /* MSDUs / MPDUs delivered to HTT */ + adf_os_print("htt_msdus :\t%d\n",rx->htt_msdus); + adf_os_print("htt_mpdus :\t%d\n",rx->htt_mpdus); + /* MSDUs / MPDUs delivered to local stack */ + adf_os_print("loc_msdus :\t%d\n",rx->loc_msdus); + adf_os_print("loc_mpdus :\t%d\n",rx->loc_mpdus); + /* AMSDUs that have more MSDUs than the status ring size */ + adf_os_print("oversize_amsdu :\t%d\n",rx->oversize_amsdu); + /* Number of PHY errors */ + adf_os_print("phy_errs :\t%d\n",rx->phy_errs); + /* Number of PHY errors dropped */ + adf_os_print("phy_errs dropped :\t%d\n",rx->phy_err_drop); + /* Number of mpdu errors - FCS, MIC, ENC etc. */ + adf_os_print("mpdu_errs :\t%d\n",rx->mpdu_errs); + +} + +static void +htt_t2h_stats_rx_reorder_stats_print( + struct rx_reorder_stats *stats_ptr, int concise) +{ + adf_os_print("Rx reorder statistics:\n"); + adf_os_print(" %u non-QoS frames received\n", + stats_ptr->deliver_non_qos); + adf_os_print(" %u frames received in-order\n", + stats_ptr->deliver_in_order); + adf_os_print(" %u frames flushed due to timeout\n", + stats_ptr->deliver_flush_timeout); + adf_os_print(" %u frames flushed due to moving out of window\n", + stats_ptr->deliver_flush_oow); + adf_os_print(" %u frames flushed due to receiving DELBA\n", + stats_ptr->deliver_flush_delba); + adf_os_print(" %u frames discarded due to FCS error\n", + stats_ptr->fcs_error); + adf_os_print(" %u frames discarded due to invalid peer\n", + stats_ptr->invalid_peer); + adf_os_print(" %u frames discarded due to duplication (non aggregation)\n", + stats_ptr->dup_non_aggr); + adf_os_print(" %u frames discarded due to duplication in " + "reorder queue\n", stats_ptr->dup_in_reorder); + adf_os_print(" %u frames discarded due to processed before\n", + stats_ptr->dup_past); + adf_os_print(" %u times reorder timeout happened\n", + stats_ptr->reorder_timeout); + adf_os_print(" %u times incorrect bar received\n", + stats_ptr->invalid_bar_ssn); + adf_os_print(" %u times bar ssn reset happened\n", + stats_ptr->ssn_reset); + adf_os_print(" %u times flushed due to peer delete\n", + stats_ptr->deliver_flush_delpeer); + adf_os_print(" %u times flushed due to offload\n", + stats_ptr->deliver_flush_offload); + adf_os_print(" %u times flushed due to ouf of buffer\n", + stats_ptr->deliver_flush_oob); + adf_os_print(" %u MPDU's dropped due to PN check fail\n", + stats_ptr->pn_fail); + adf_os_print(" %u MPDU's dropped due to lack of memory\n", + stats_ptr->store_fail); + adf_os_print(" %u times tid pool alloc succeeded\n", + stats_ptr->tid_pool_alloc_succ); + adf_os_print(" %u times MPDU pool alloc succeeded\n", + stats_ptr->mpdu_pool_alloc_succ); + adf_os_print(" %u times MSDU pool alloc succeeded\n", + stats_ptr->msdu_pool_alloc_succ); + adf_os_print(" %u times tid pool alloc failed\n", + stats_ptr->tid_pool_alloc_fail); + adf_os_print(" %u times MPDU pool alloc failed\n", + stats_ptr->mpdu_pool_alloc_fail); + adf_os_print(" %u times MSDU pool alloc failed\n", + stats_ptr->msdu_pool_alloc_fail); + adf_os_print(" %u times tid pool freed\n", + stats_ptr->tid_pool_free); + adf_os_print(" %u times MPDU pool freed\n", + stats_ptr->mpdu_pool_free); + adf_os_print(" %u times MSDU pool freed\n", + stats_ptr->msdu_pool_free); + adf_os_print(" %u MSDUs undelivered to HTT, queued to Rx MSDU free list\n", + stats_ptr->msdu_queued); + adf_os_print(" %u MSDUs released from Rx MSDU list to MAC ring\n", + stats_ptr->msdu_recycled); + adf_os_print(" %u MPDUs with invalid peer but A2 found in AST\n", + stats_ptr->invalid_peer_a2_in_ast); + adf_os_print(" %u MPDUs with invalid peer but A3 found in AST\n", + stats_ptr->invalid_peer_a3_in_ast); + adf_os_print(" %u MPDUs with invalid peer, Broadcast or Mulitcast frame\n", + stats_ptr->invalid_peer_bmc_mpdus); + adf_os_print(" %u MSDUs with err attention word\n", + stats_ptr->rxdesc_err_att); + adf_os_print(" %u MSDUs with flag of peer_idx_invalid\n", + stats_ptr->rxdesc_err_peer_idx_inv); + adf_os_print(" %u MSDUs with flag of peer_idx_timeout\n", + stats_ptr->rxdesc_err_peer_idx_to); + adf_os_print(" %u MSDUs with flag of overflow\n", + stats_ptr->rxdesc_err_ov); + adf_os_print(" %u MSDUs with flag of msdu_length_err\n", + stats_ptr->rxdesc_err_msdu_len); + adf_os_print(" %u MSDUs with flag of mpdu_length_err\n", + stats_ptr->rxdesc_err_mpdu_len); + adf_os_print(" %u MSDUs with flag of tkip_mic_err\n", + stats_ptr->rxdesc_err_tkip_mic); + adf_os_print(" %u MSDUs with flag of decrypt_err\n", + stats_ptr->rxdesc_err_decrypt); + adf_os_print(" %u MSDUs with flag of fcs_err\n", + stats_ptr->rxdesc_err_fcs); + adf_os_print(" %u Unicast frames with invalid peer handler\n", + stats_ptr->rxdesc_uc_msdus_inv_peer); + adf_os_print(" %u unicast frame directly to DUT with invalid peer handler\n", + stats_ptr->rxdesc_direct_msdus_inv_peer); + adf_os_print(" %u Broadcast/Multicast frames with invalid peer handler\n", + stats_ptr->rxdesc_bmc_msdus_inv_peer); + adf_os_print(" %u MSDUs dropped due to no first MSDU flag\n", + stats_ptr->rxdesc_no_1st_msdu); + adf_os_print(" %u MSDUs dropped due to ring overflow\n", + stats_ptr->msdu_drop_ring_ov); + adf_os_print(" %u MSDUs dropped due to FC mismatch\n", + stats_ptr->msdu_drop_fc_mismatch); + adf_os_print(" %u MSDUs dropped due to mgt frame in Remote ring\n", + stats_ptr->msdu_drop_mgmt_remote_ring); + adf_os_print(" %u MSDUs dropped due to misc non error\n", + stats_ptr->msdu_drop_misc); + adf_os_print(" %u MSDUs go to offload before reorder\n", + stats_ptr->offload_msdu_wal); + adf_os_print(" %u data frame dropped by offload after reorder\n", + stats_ptr->offload_msdu_reorder); + adf_os_print(" %u MPDUs with SN in the past & within BA window\n", + stats_ptr->dup_past_within_window); + adf_os_print(" %u MPDUs with SN in the past & outside BA window\n", + stats_ptr->dup_past_outside_window); +} + +static void +htt_t2h_stats_rx_rem_buf_stats_print( + struct rx_remote_buffer_mgmt_stats *stats_ptr, int concise) +{ + adf_os_print("Rx Remote Buffer Statistics:\n"); + adf_os_print(" %u MSDU's reaped for Rx processing\n", + stats_ptr->remote_reaped); + adf_os_print(" %u MSDU's recycled within firmware\n", + stats_ptr->remote_recycled); + adf_os_print(" %u MSDU's stored by Data Rx\n", + stats_ptr->data_rx_msdus_stored); + adf_os_print(" %u HTT indications from WAL Rx MSDU\n", + stats_ptr->wal_rx_ind); + adf_os_print(" %u HTT indications unconsumed from WAL Rx MSDU\n", + stats_ptr->wal_rx_ind_unconsumed); + adf_os_print(" %u HTT indications from Data Rx MSDU\n", + stats_ptr->data_rx_ind); + adf_os_print(" %u HTT indications unconsumed from Data Rx MSDU\n", + stats_ptr->data_rx_ind_unconsumed); + adf_os_print(" %u HTT indications from ATHBUF\n", + stats_ptr->athbuf_rx_ind); + adf_os_print(" %u Remote buffers requested for refill\n", + stats_ptr->refill_buf_req); + adf_os_print(" %u Remote buffers filled by host\n", + stats_ptr->refill_buf_rsp); + adf_os_print(" %u times MAC has no buffers\n", + stats_ptr->mac_no_bufs); + adf_os_print(" %u times f/w write & read indices on MAC ring are equal\n", + stats_ptr->fw_indices_equal); + adf_os_print(" %u times f/w has no remote buffers to post to MAC\n", + stats_ptr->host_no_bufs); +} + +#define HTT_T2H_STATS_TX_PPDU_TIME_TO_MICROSEC(ticks, microsec_per_tick) \ + (ticks * microsec_per_tick) +static inline int +HTT_T2H_STATS_TX_PPDU_RATE_FLAGS_TO_MHZ(u_int8_t rate_flags) +{ + if (rate_flags & 0x20) return 40; /* WHAL_RC_FLAG_40MHZ */ + if (rate_flags & 0x40) return 80; /* WHAL_RC_FLAG_80MHZ */ + if (rate_flags & 0x80) return 160; /* WHAL_RC_FLAG_160MHZ */ + return 20; +} + +#define HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW 64 + +static void +htt_t2h_tx_ppdu_log_bitmaps_print( + u_int32_t *queued_ptr, + u_int32_t *acked_ptr) +{ + char queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW+1]; + char acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW+1]; + int i, j, word; + + adf_os_mem_set(queued_str, '0', HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW); + adf_os_mem_set(acked_str, '-', HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW); + i = 0; + for (word = 0; word < 2; word++) { + u_int32_t queued = *(queued_ptr + word); + u_int32_t acked = *(acked_ptr + word); + for (j = 0; j < 32; j++, i++) { + if (queued & (1 << j)) { + queued_str[i] = '1'; + acked_str[i] = (acked & (1 << j)) ? 'y' : 'N'; + } + } + } + queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0'; + acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0'; + adf_os_print("%s\n", queued_str); + adf_os_print("%s\n", acked_str); +} + +static inline u_int16_t htt_msg_read16(u_int16_t *p16) +{ +#ifdef BIG_ENDIAN_HOST + /* + * During upload, the bytes within each u_int32_t word were + * swapped by the HIF HW. This results in the lower and upper bytes + * of each u_int16_t to be in the correct big-endian order with + * respect to each other, but for each even-index u_int16_t to + * have its position switched with its successor neighbor u_int16_t. + * Undo this u_int16_t position swapping. + */ + return (((size_t) p16) & 0x2) ? *(p16 - 1) : *(p16 + 1); +#else + return *p16; +#endif +} + +static inline u_int8_t htt_msg_read8(u_int8_t *p8) +{ +#ifdef BIG_ENDIAN_HOST + /* + * During upload, the bytes within each u_int32_t word were + * swapped by the HIF HW. + * Undo this byte swapping. + */ + switch (((size_t) p8) & 0x3) { + case 0: + return *(p8 + 3); + case 1: + return *(p8 + 1); + case 2: + return *(p8 - 1); + default /* 3 */: + return *(p8 - 3); + } +#else + return *p8; +#endif +} + +void htt_make_u8_list_str( + u_int32_t *aligned_data, + char *buffer, + int space, + int max_elems) +{ + u_int8_t *p8 = (u_int8_t *) aligned_data; + char *buf_p = buffer; + while (max_elems-- > 0) { + int bytes; + u_int8_t val; + + val = htt_msg_read8(p8); + if (val == 0) { + break; /* not enough data to fill the reserved msg buffer space */ + } + bytes = adf_os_snprint(buf_p, space, "%d,", val); + space -= bytes; + if (space > 0) { + buf_p += bytes; + } else { + break; /* not enough print buffer space for all the data */ + } + p8++; + } + if (buf_p == buffer) { + *buf_p = '\0'; /* nothing was written */ + } else { + *(buf_p - 1) = '\0'; /* erase the final comma */ + } +} + +void htt_make_u16_list_str( + u_int32_t *aligned_data, + char *buffer, + int space, + int max_elems) +{ + u_int16_t *p16 = (u_int16_t *) aligned_data; + char *buf_p = buffer; + while (max_elems-- > 0) { + int bytes; + u_int16_t val; + + val = htt_msg_read16(p16); + if (val == 0) { + break; /* not enough data to fill the reserved msg buffer space */ + } + bytes = adf_os_snprint(buf_p, space, "%d,", val); + space -= bytes; + if (space > 0) { + buf_p += bytes; + } else { + break; /* not enough print buffer space for all the data */ + } + p16++; + } + if (buf_p == buffer) { + *buf_p = '\0'; /* nothing was written */ + } else { + *(buf_p - 1) = '\0'; /* erase the final comma */ + } +} + +void +htt_t2h_tx_ppdu_log_print( + struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr, + struct ol_fw_tx_dbg_ppdu_base *record, + int length, int concise) +{ + int i; + int record_size; + int num_records; + + record_size = + sizeof(*record) + + hdr->mpdu_bytes_array_len * sizeof(u_int16_t) + + hdr->mpdu_msdus_array_len * sizeof(u_int8_t) + + hdr->msdu_bytes_array_len * sizeof(u_int16_t); + num_records = (length - sizeof(*hdr)) / record_size; + adf_os_print("Tx PPDU log elements:\n"); + + for (i = 0; i < num_records; i++) { + u_int16_t start_seq_num; + u_int16_t start_pn_lsbs; + u_int8_t num_mpdus; + u_int16_t peer_id; + u_int8_t ext_tid; + u_int8_t rate_code; + u_int8_t rate_flags; + u_int8_t tries; + u_int8_t complete; + u_int32_t time_enqueue_us; + u_int32_t time_completion_us; + u_int32_t *msg_word = (u_int32_t *) record; + + /* fields used for both concise and complete printouts */ + start_seq_num = + ((*(msg_word + OL_FW_TX_DBG_PPDU_START_SEQ_NUM_WORD)) & + OL_FW_TX_DBG_PPDU_START_SEQ_NUM_M) >> + OL_FW_TX_DBG_PPDU_START_SEQ_NUM_S; + complete = + ((*(msg_word + OL_FW_TX_DBG_PPDU_COMPLETE_WORD)) & + OL_FW_TX_DBG_PPDU_COMPLETE_M) >> + OL_FW_TX_DBG_PPDU_COMPLETE_S; + + /* fields used only for complete printouts */ + if (! concise) { + #define BUF_SIZE 80 + char buf[BUF_SIZE]; + u_int8_t *p8; + time_enqueue_us = HTT_T2H_STATS_TX_PPDU_TIME_TO_MICROSEC( + record->timestamp_enqueue, hdr->microsec_per_tick); + time_completion_us = HTT_T2H_STATS_TX_PPDU_TIME_TO_MICROSEC( + record->timestamp_completion, hdr->microsec_per_tick); + + start_pn_lsbs = + ((*(msg_word + OL_FW_TX_DBG_PPDU_START_PN_LSBS_WORD)) & + OL_FW_TX_DBG_PPDU_START_PN_LSBS_M) >> + OL_FW_TX_DBG_PPDU_START_PN_LSBS_S; + num_mpdus = + ((*(msg_word + OL_FW_TX_DBG_PPDU_NUM_MPDUS_WORD)) & + OL_FW_TX_DBG_PPDU_NUM_MPDUS_M) >> + OL_FW_TX_DBG_PPDU_NUM_MPDUS_S; + peer_id = + ((*(msg_word + OL_FW_TX_DBG_PPDU_PEER_ID_WORD)) & + OL_FW_TX_DBG_PPDU_PEER_ID_M) >> + OL_FW_TX_DBG_PPDU_PEER_ID_S; + ext_tid = + ((*(msg_word + OL_FW_TX_DBG_PPDU_EXT_TID_WORD)) & + OL_FW_TX_DBG_PPDU_EXT_TID_M) >> + OL_FW_TX_DBG_PPDU_EXT_TID_S; + rate_code = + ((*(msg_word + OL_FW_TX_DBG_PPDU_RATE_CODE_WORD)) & + OL_FW_TX_DBG_PPDU_RATE_CODE_M) >> + OL_FW_TX_DBG_PPDU_RATE_CODE_S; + rate_flags = + ((*(msg_word + OL_FW_TX_DBG_PPDU_RATE_FLAGS_WORD)) & + OL_FW_TX_DBG_PPDU_RATE_FLAGS_M) >> + OL_FW_TX_DBG_PPDU_RATE_FLAGS_S; + tries = + ((*(msg_word + OL_FW_TX_DBG_PPDU_TRIES_WORD)) & + OL_FW_TX_DBG_PPDU_TRIES_M) >> + OL_FW_TX_DBG_PPDU_TRIES_S; + + adf_os_print(" - PPDU tx to peer %d, TID %d\n", peer_id, ext_tid); + adf_os_print(" start seq num = %u, start PN LSBs = %#04x\n", + start_seq_num, start_pn_lsbs); + adf_os_print(" PPDU is %d MPDUs, (unknown) MSDUs, %d bytes\n", + num_mpdus, + //num_msdus, /* not yet being computed in target */ + record->num_bytes); + if (complete) { + adf_os_print(" enqueued at %u, completed at %u (microsec)\n", + time_enqueue_us, time_completion_us); + adf_os_print( + " %d total tries, last tx used rate %d " + "on %d MHz chan (flags = %#x)\n", + tries, rate_code, + HTT_T2H_STATS_TX_PPDU_RATE_FLAGS_TO_MHZ(rate_flags), + rate_flags); + adf_os_print(" enqueued and acked MPDU bitmaps:\n"); + htt_t2h_tx_ppdu_log_bitmaps_print( + msg_word + OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD, + msg_word + OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD); + } else { + adf_os_print( + " enqueued at %d ms (microsec), not yet completed\n", + time_enqueue_us); + } + /* skip past the regular message fields to reach the tail area */ + p8 = (u_int8_t *) record; + p8 += sizeof(struct ol_fw_tx_dbg_ppdu_base); + if (hdr->mpdu_bytes_array_len) { + htt_make_u16_list_str( + (u_int32_t *) p8, buf, BUF_SIZE, hdr->mpdu_bytes_array_len); + adf_os_print(" MPDU bytes: %s\n", buf); + } + p8 += hdr->mpdu_bytes_array_len * sizeof(u_int16_t); + if (hdr->mpdu_msdus_array_len) { + htt_make_u8_list_str( + (u_int32_t *) p8, buf, BUF_SIZE, hdr->mpdu_msdus_array_len); + adf_os_print(" MPDU MSDUs: %s\n", buf); + } + p8 += hdr->mpdu_msdus_array_len * sizeof(u_int8_t); + if (hdr->msdu_bytes_array_len) { + htt_make_u16_list_str( + (u_int32_t *) p8, buf, BUF_SIZE, hdr->msdu_bytes_array_len); + adf_os_print(" MSDU bytes: %s\n", buf); + } + } else { + /* concise */ + adf_os_print( + "start seq num = %u, enqueued and acked MPDU bitmaps:\n", + start_seq_num); + if (complete) { + htt_t2h_tx_ppdu_log_bitmaps_print( + msg_word + OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD, + msg_word + OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD); + } else { + adf_os_print("(not completed)\n"); + } + } + record = (struct ol_fw_tx_dbg_ppdu_base *) + (((u_int8_t *) record) + record_size); + } +} + +void +htt_t2h_stats_print(u_int8_t *stats_data, int concise) +{ + u_int32_t *msg_word = (u_int32_t *)stats_data; + enum htt_dbg_stats_type type; + enum htt_dbg_stats_status status; + int length; + + type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word); + status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word); + length = HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word); + + /* check that we've been given a valid stats type */ + if (status == HTT_DBG_STATS_STATUS_SERIES_DONE) { + return; + } else if (status == HTT_DBG_STATS_STATUS_INVALID) { + adf_os_print( + "Target doesn't support stats type %d\n", type); + return; + } else if (status == HTT_DBG_STATS_STATUS_ERROR) { + adf_os_print( + "Target couldn't upload stats type %d (no mem?)\n", type); + return; + } + /* got valid (though perhaps partial) stats - process them */ + switch (type) { + case HTT_DBG_STATS_WAL_PDEV_TXRX: + { + struct wlan_dbg_stats *wlan_dbg_stats_ptr; + + wlan_dbg_stats_ptr = (struct wlan_dbg_stats *)(msg_word + 1); + htt_t2h_stats_pdev_stats_print(wlan_dbg_stats_ptr, concise); + break; + } + case HTT_DBG_STATS_RX_REORDER: + { + struct rx_reorder_stats *rx_reorder_stats_ptr; + + rx_reorder_stats_ptr = (struct rx_reorder_stats *)(msg_word + 1); + htt_t2h_stats_rx_reorder_stats_print(rx_reorder_stats_ptr, concise); + break; + } + + case HTT_DBG_STATS_RX_RATE_INFO: + { + wlan_dbg_rx_rate_info_t *rx_phy_info; + rx_phy_info = (wlan_dbg_rx_rate_info_t *)(msg_word + 1); + htt_t2h_stats_rx_rate_stats_print(rx_phy_info, concise); + break; + } + case HTT_DBG_STATS_TX_PPDU_LOG: + { + struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr; + struct ol_fw_tx_dbg_ppdu_base *record; + + if (status == HTT_DBG_STATS_STATUS_PARTIAL && length == 0) { + adf_os_print("HTT_DBG_STATS_TX_PPDU_LOG -- length = 0!\n"); + break; + } + hdr = (struct ol_fw_tx_dbg_ppdu_msg_hdr *)(msg_word + 1); + record = (struct ol_fw_tx_dbg_ppdu_base *)(hdr + 1); + htt_t2h_tx_ppdu_log_print(hdr, record, length, concise); + } + break; + case HTT_DBG_STATS_TX_RATE_INFO: + { + wlan_dbg_tx_rate_info_t *tx_rate_info; + tx_rate_info = (wlan_dbg_tx_rate_info_t *)(msg_word + 1); + htt_t2h_stats_tx_rate_stats_print(tx_rate_info, concise); + break; + } + case HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO: + { + + struct rx_remote_buffer_mgmt_stats *rx_rem_buf; + + rx_rem_buf = (struct rx_remote_buffer_mgmt_stats *)(msg_word + 1); + htt_t2h_stats_rx_rem_buf_stats_print(rx_rem_buf, concise); + break; + } + default: + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_h2t.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_h2t.c new file mode 100644 index 0000000000000..f723e927e5e88 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_h2t.c @@ -0,0 +1,950 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_h2t.c + * @brief Provide functions to send host->target HTT messages. + * @details + * This file contains functions related to host->target HTT messages. + * There are a couple aspects of this host->target messaging: + * 1. This file contains the function that is called by HTC when + * a host->target send completes. + * This send-completion callback is primarily relevant to HL, + * to invoke the download scheduler to set up a new download, + * and optionally free the tx frame whose download is completed. + * For both HL and LL, this completion callback frees up the + * HTC_PACKET object used to specify the download. + * 2. This file contains functions for creating messages to send + * from the host to the target. + */ + +#include /* adf_os_mem_copy */ +#include /* adf_nbuf_map_single */ +#include /* HTC_PACKET */ +#include /* HTC_HDR_ALIGNMENT_PADDING */ +#include /* HTT host->target msg defs */ +#include /* ol_tx_completion_handler, htt_tx_status */ +#include + + +#include + +#define HTT_MSG_BUF_SIZE(msg_bytes) \ + ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING) + +#ifndef container_of +#define container_of(ptr, type, member) ((type *)( \ + (char *)(ptr) - (char *)(&((type *)0)->member) ) ) +#endif + +static void +htt_h2t_send_complete_free_netbuf( + void *pdev, A_STATUS status, adf_nbuf_t netbuf, u_int16_t msdu_id) +{ + adf_nbuf_free(netbuf); +} + +void +htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt) +{ + void (*send_complete_part2)( + void *pdev, A_STATUS status, adf_nbuf_t msdu, u_int16_t msdu_id); + struct htt_pdev_t *pdev = (struct htt_pdev_t *) context; + struct htt_htc_pkt *htt_pkt; + adf_nbuf_t netbuf; + + send_complete_part2 = htc_pkt->pPktContext; + + htt_pkt = container_of(htc_pkt, struct htt_htc_pkt, htc_pkt); + + /* process (free or keep) the netbuf that held the message */ + netbuf = (adf_nbuf_t) htc_pkt->pNetBufContext; + if (send_complete_part2 != NULL) { + send_complete_part2( + htt_pkt->pdev_ctxt, htc_pkt->Status, netbuf, htt_pkt->msdu_id); + } + /* free the htt_htc_pkt / HTC_PACKET object */ + htt_htc_pkt_free(pdev, htt_pkt); +} + +HTC_SEND_FULL_ACTION +htt_h2t_full(void *context, HTC_PACKET *pkt) +{ +/* FIX THIS */ + return HTC_SEND_FULL_KEEP; +} + +A_STATUS +htt_h2t_ver_req_msg(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_ERROR; /* failure */ + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_VER_REQ_BYTES), + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_ERROR; /* failure */ + } + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to adf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + adf_nbuf_put_tail(msg, HTT_VER_REQ_BYTES); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } + return A_OK; +} + +A_STATUS +htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + int enable_ctrl_data, enable_mgmt_data, + enable_null_data, enable_phy_data, enable_hdr, + enable_ppdu_start, enable_ppdu_end; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_ERROR; /* failure */ + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)), + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_ERROR; /* failure */ + } + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to adf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + adf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1)); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG); + HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET( + *msg_word, pdev->rx_ring.alloc_idx.paddr); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size); + HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE); + +/* FIX THIS: if the FW creates a complete translated rx descriptor, then the MAC DMA of the HW rx descriptor should be disabled. */ + msg_word++; + *msg_word = 0; +#ifndef REMOVE_PKT_LOG + if (ol_cfg_is_packet_log_enabled(pdev->ctrl_pdev)) + { + enable_ctrl_data = 1; + enable_mgmt_data = 1; + enable_null_data = 1; + enable_phy_data = 1; + enable_hdr = 1; + enable_ppdu_start= 1; + enable_ppdu_end = 1; + /* Disable ASPM when pkt log is enabled */ + adf_os_print("Pkt log is enabled\n"); + htt_htc_disable_aspm(); + } + else + { + adf_os_print("Pkt log is disabled\n"); + enable_ctrl_data = 0; + enable_mgmt_data = 0; + enable_null_data = 0; + enable_phy_data = 0; + enable_hdr = 0; + enable_ppdu_start= 0; + enable_ppdu_end = 0; + } +#else + enable_ctrl_data = 0; + enable_mgmt_data = 0; + enable_null_data = 0; + enable_phy_data = 0; + enable_hdr = 0; + enable_ppdu_start= 0; + enable_ppdu_end = 0; +#endif + HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr); + HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start); + HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, enable_ppdu_end); + HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 1); /* always present? */ + HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1); + /* Must change to dynamic enable at run time + * rather than at compile time + */ + HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, enable_ctrl_data); + HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, enable_mgmt_data); + HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, enable_null_data); + HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, enable_phy_data); + HTT_RX_RING_CFG_IDX_INIT_VAL_SET(*msg_word, + *pdev->rx_ring.alloc_idx.vaddr); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word, + RX_STD_DESC_HDR_STATUS_OFFSET_DWORD); + HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word, + HTT_RX_STD_DESC_RESERVATION_DWORD); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word, + RX_STD_DESC_PPDU_START_OFFSET_DWORD); + HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word, + RX_STD_DESC_PPDU_END_OFFSET_DWORD); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word, + RX_STD_DESC_MPDU_START_OFFSET_DWORD); + HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word, + RX_STD_DESC_MPDU_END_OFFSET_DWORD); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word, + RX_STD_DESC_MSDU_START_OFFSET_DWORD); + HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word, + RX_STD_DESC_MSDU_END_OFFSET_DWORD); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word, + RX_STD_DESC_ATTN_OFFSET_DWORD); + HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word, + RX_STD_DESC_FRAG_INFO_OFFSET_DWORD); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + return A_OK; +} + +A_STATUS +htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_ERROR; /* failure */ + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)), + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_ERROR; /* failure */ + } + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to adf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + adf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1)); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG); + HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET( + *msg_word, pdev->rx_ring.alloc_idx.paddr); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size); + HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE); + +/* FIX THIS: if the FW creates a complete translated rx descriptor, then the MAC DMA of the HW rx descriptor should be disabled. */ + msg_word++; + *msg_word = 0; + + HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 0); /* always present? */ + HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1); + HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1); + /* Must change to dynamic enable at run time + * rather than at compile time + */ + HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, 0); + HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, 0); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word, + 0); + HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word, + 0); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word, + 0); + HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word, + 0); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word, + 0); + HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word, + 0); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word, + 0); + HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word, + 0); + + msg_word++; + *msg_word = 0; + HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word, + 0); + HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word, + 0); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + if (!pdev->cfg.default_tx_comp_req) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } + return A_OK; +} + +int +htt_h2t_dbg_stats_get( + struct htt_pdev_t *pdev, + u_int32_t stats_type_upload_mask, + u_int32_t stats_type_reset_mask, + u_int8_t cfg_stat_type, + u_int32_t cfg_val, + u_int64_t cookie) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return -1; /* failure */ + } + + if (stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS || + stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) + { + /* FIX THIS - add more details? */ + adf_os_print("%#x %#x stats not supported\n", + stats_type_upload_mask, stats_type_reset_mask); + return -1; /* failure */ + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_H2T_STATS_REQ_MSG_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return -1; /* failure */ + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_H2T_STATS_REQ_MSG_SZ); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_STATS_REQ); + HTT_H2T_STATS_REQ_UPLOAD_TYPES_SET(*msg_word, stats_type_upload_mask); + + msg_word++; + *msg_word = 0; + HTT_H2T_STATS_REQ_RESET_TYPES_SET(*msg_word, stats_type_reset_mask); + + msg_word++; + *msg_word = 0; + HTT_H2T_STATS_REQ_CFG_VAL_SET(*msg_word, cfg_val); + HTT_H2T_STATS_REQ_CFG_STAT_TYPE_SET(*msg_word, cfg_stat_type); + + /* cookie LSBs */ + msg_word++; + *msg_word = cookie & 0xffffffff; + + /* cookie MSBs */ + msg_word++; + *msg_word = cookie >> 32; + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } + return 0; +} + +A_STATUS +htt_h2t_sync_msg(struct htt_pdev_t *pdev, u_int8_t sync_cnt) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_NO_MEMORY; + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_H2T_SYNC_MSG_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_NO_MEMORY; + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_H2T_SYNC_MSG_SZ); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SYNC); + HTT_H2T_SYNC_COUNT_SET(*msg_word, sync_cnt); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } + return A_OK; +} + +int +htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev, + int max_subfrms_ampdu, + int max_subfrms_amsdu) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return -1; /* failure */ + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_AGGR_CFG_MSG_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return -1; /* failure */ + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_AGGR_CFG_MSG_SZ); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_AGGR_CFG); + + if (max_subfrms_ampdu && (max_subfrms_ampdu <= 64)) { + HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_SET(*msg_word, max_subfrms_ampdu); + } + + if (max_subfrms_amsdu && (max_subfrms_amsdu < 32)) { + HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_SET(*msg_word, max_subfrms_amsdu); + } + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } + return 0; +} + +#ifdef IPA_UC_OFFLOAD +int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_NO_MEMORY; + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_NO_MEMORY; + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word, + pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt); + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_base.paddr); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(*msg_word, + (unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev)); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word, + (unsigned int)ol_cfg_ipa_uc_rx_ind_ring_size(pdev->ctrl_pdev)); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr); + + msg_word++; + *msg_word = 0; + HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(*msg_word, + (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) + htt_htc_misc_pkt_list_add(pdev, pkt); +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + + return A_OK; +} + + +int htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev, + a_bool_t uc_active, + a_bool_t is_tx) +{ + struct htt_htc_pkt *pkt; + adf_nbuf_t msg; + u_int32_t *msg_word; + u_int8_t active_target = 0; + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_NO_MEMORY; + } + + /* show that this is not a tx frame download (not required, but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_NO_MEMORY; + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + *msg_word = 0; + if (uc_active && is_tx) + { + active_target = HTT_WDI_IPA_OPCODE_TX_RESUME; + } + else if (!uc_active && is_tx) + { + active_target = HTT_WDI_IPA_OPCODE_TX_SUSPEND; + } + else if (uc_active && !is_tx) + { + active_target = HTT_WDI_IPA_OPCODE_RX_RESUME; + } + else if (!uc_active && !is_tx) + { + active_target = HTT_WDI_IPA_OPCODE_RX_SUSPEND; + } + HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, + active_target); + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) + htt_htc_misc_pkt_list_add(pdev, pkt); +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + + return A_OK; +} + + +int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev) +{ + static struct htt_htc_pkt *pkt = NULL; + static adf_nbuf_t msg = NULL; + u_int32_t *msg_word; + + if ((!pkt) || (!msg)) { + /* New buffer alloc send */ + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return A_NO_MEMORY; + } + + /* show that this is not a tx frame download (not required, + * but helpful) */ + pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; + pkt->pdev_ctxt = NULL; /* not used during send-done callback */ + + msg = adf_nbuf_alloc( + pdev->osdev, + HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ), + /* reserve room for HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); + if (!msg) { + htt_htc_pkt_free(pdev, pkt); + return A_NO_MEMORY; + } + /* set the length of the message */ + adf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ); + /* rewind beyond alignment pad to get to the HTC header reserved area */ + adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + + /* fill in the message contents */ + msg_word = (u_int32_t *) adf_nbuf_data(msg); + *msg_word = 0; + HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, + HTT_WDI_IPA_OPCODE_DBG_STATS); + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + htt_h2t_send_complete_free_netbuf, + adf_nbuf_data(msg), + adf_nbuf_len(msg), + pdev->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) + htt_htc_misc_pkt_list_add(pdev, pkt); +#else + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif + } else { + /* Cached MSG send */ + adf_nbuf_pull_head(msg, sizeof(HTC_FRAME_HDR)); + HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); + } + return A_OK; +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_internal.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_internal.h new file mode 100644 index 0000000000000..7ec53bfffc6a3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_internal.h @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _HTT_INTERNAL__H_ +#define _HTT_INTERNAL__H_ + +#include /* A_STATUS */ +#include /* adf_nbuf_t */ +#include /* adf_os_assert */ +#include /* HTC_PACKET */ + +#include + +#ifndef offsetof +#define offsetof(type, field) ((size_t)(&((type *)0)->field)) +#endif + +#undef MS +#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) +#undef SM +#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) +#undef WO +#define WO(_f) ((_f##_OFFSET) >> 2) + +#define GET_FIELD(_addr, _f) MS(*((A_UINT32 *)(_addr) + WO(_f)), _f) + +#include +#include /* struct rx_attention, etc */ + +struct htt_host_fw_desc_base { + union { + struct fw_rx_desc_base val; + A_UINT32 dummy_pad; /* make sure it is DOWRD aligned */ + } u; +}; + +/* + * This struct defines the basic descriptor information used by host, + * which is written either by the 11ac HW MAC into the host Rx data + * buffer ring directly or generated by FW and copied from Rx indication + */ +#define RX_HTT_HDR_STATUS_LEN 64 +struct htt_host_rx_desc_base { + struct htt_host_fw_desc_base fw_desc; + struct rx_attention attention; + struct rx_frag_info frag_info; + struct rx_mpdu_start mpdu_start; + struct rx_msdu_start msdu_start; + struct rx_msdu_end msdu_end; + struct rx_mpdu_end mpdu_end; + struct rx_ppdu_start ppdu_start; + struct rx_ppdu_end ppdu_end; + char rx_hdr_status[RX_HTT_HDR_STATUS_LEN]; +}; + +#define RX_STD_DESC_ATTN_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, attention)) +#define RX_STD_DESC_FRAG_INFO_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, frag_info)) +#define RX_STD_DESC_MPDU_START_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, mpdu_start)) +#define RX_STD_DESC_MSDU_START_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, msdu_start)) +#define RX_STD_DESC_MSDU_END_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, msdu_end)) +#define RX_STD_DESC_MPDU_END_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, mpdu_end)) +#define RX_STD_DESC_PPDU_START_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, ppdu_start)) +#define RX_STD_DESC_PPDU_END_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, ppdu_end)) +#define RX_STD_DESC_HDR_STATUS_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, rx_hdr_status)) + +#define RX_STD_DESC_FW_MSDU_OFFSET \ + (offsetof(struct htt_host_rx_desc_base, fw_desc)) + +#define RX_STD_DESC_SIZE (sizeof(struct htt_host_rx_desc_base)) + + +#define RX_STD_DESC_ATTN_OFFSET_DWORD (RX_STD_DESC_ATTN_OFFSET >> 2) +#define RX_STD_DESC_FRAG_INFO_OFFSET_DWORD (RX_STD_DESC_FRAG_INFO_OFFSET >> 2) +#define RX_STD_DESC_MPDU_START_OFFSET_DWORD (RX_STD_DESC_MPDU_START_OFFSET >> 2) +#define RX_STD_DESC_MSDU_START_OFFSET_DWORD (RX_STD_DESC_MSDU_START_OFFSET >> 2) +#define RX_STD_DESC_MSDU_END_OFFSET_DWORD (RX_STD_DESC_MSDU_END_OFFSET >> 2) +#define RX_STD_DESC_MPDU_END_OFFSET_DWORD (RX_STD_DESC_MPDU_END_OFFSET >> 2) +#define RX_STD_DESC_PPDU_START_OFFSET_DWORD (RX_STD_DESC_PPDU_START_OFFSET >> 2) +#define RX_STD_DESC_PPDU_END_OFFSET_DWORD (RX_STD_DESC_PPDU_END_OFFSET >> 2) +#define RX_STD_DESC_HDR_STATUS_OFFSET_DWORD (RX_STD_DESC_HDR_STATUS_OFFSET >> 2) + +#define RX_STD_DESC_SIZE_DWORD (RX_STD_DESC_SIZE >> 2) + +/* + * Make sure there is a minimum headroom provided in the rx netbufs + * for use by the OS shim and OS and rx data consumers. + */ +#define HTT_RX_BUF_OS_MIN_HEADROOM 32 +#define HTT_RX_STD_DESC_RESERVATION \ + ((HTT_RX_BUF_OS_MIN_HEADROOM > RX_STD_DESC_SIZE) ? \ + HTT_RX_BUF_OS_MIN_HEADROOM : RX_STD_DESC_SIZE) +#define HTT_RX_STD_DESC_RESERVATION_DWORD \ + (HTT_RX_STD_DESC_RESERVATION >> 2) + +#define HTT_RX_DESC_ALIGN_MASK 7 /* 8-byte alignment */ +static inline +struct htt_host_rx_desc_base * +htt_rx_desc(adf_nbuf_t msdu) +{ + return + (struct htt_host_rx_desc_base *) + (((size_t) (adf_nbuf_head(msdu) + HTT_RX_DESC_ALIGN_MASK)) & + ~HTT_RX_DESC_ALIGN_MASK); +} + +static inline +void +htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc) +{ + adf_os_print("----------------------RX DESC----------------------------\n"); + adf_os_print("attention: %#010x\n", + (unsigned int)(*(u_int32_t *) &rx_desc->attention)); + adf_os_print("frag_info: %#010x\n", + (unsigned int)(*(u_int32_t *) &rx_desc->frag_info)); + adf_os_print("mpdu_start: %#010x %#010x %#010x\n", + (unsigned int)(((u_int32_t *) &rx_desc->mpdu_start)[0]), + (unsigned int)(((u_int32_t *) &rx_desc->mpdu_start)[1]), + (unsigned int)(((u_int32_t *) &rx_desc->mpdu_start)[2])); + adf_os_print("msdu_start: %#010x %#010x %#010x\n", + (unsigned int)(((u_int32_t *) &rx_desc->msdu_start)[0]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_start)[1]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_start)[2])); + adf_os_print("msdu_end: %#010x %#010x %#010x %#010x %#010x\n", + (unsigned int)(((u_int32_t *) &rx_desc->msdu_end)[0]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_end)[1]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_end)[2]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_end)[3]), + (unsigned int)(((u_int32_t *) &rx_desc->msdu_end)[4])); + adf_os_print("mpdu_end: %#010x\n", + (unsigned int)(*(u_int32_t *) &rx_desc->mpdu_end)); + adf_os_print("ppdu_start: " + "%#010x %#010x %#010x %#010x %#010x\n" + "%#010x %#010x %#010x %#010x %#010x\n", + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[0]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[1]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[2]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[3]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[4]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[5]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[6]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[7]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[8]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_start)[9])); + adf_os_print("ppdu_end:" + "%#010x %#010x %#010x %#010x %#010x\n" + "%#010x %#010x %#010x %#010x %#010x\n" + "%#010x,%#010x %#010x %#010x %#010x\n" + "%#010x %#010x %#010x %#010x %#010x\n" + "%#010x %#010x\n", + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[0]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[1]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[2]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[3]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[4]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[5]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[6]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[7]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[8]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[9]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[10]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[11]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[12]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[13]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[14]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[15]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[16]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[17]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[18]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[19]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[20]), + (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[21])); + adf_os_print("---------------------------------------------------------\n"); +} + + +#ifndef HTT_ASSERT_LEVEL +#define HTT_ASSERT_LEVEL 3 +#endif + +#define HTT_ASSERT_ALWAYS(condition) adf_os_assert_always((condition)) + +#define HTT_ASSERT0(condition) adf_os_assert((condition)) +#if HTT_ASSERT_LEVEL > 0 +#define HTT_ASSERT1(condition) adf_os_assert((condition)) +#else +#define HTT_ASSERT1(condition) +#endif + +#if HTT_ASSERT_LEVEL > 1 +#define HTT_ASSERT2(condition) adf_os_assert((condition)) +#else +#define HTT_ASSERT2(condition) +#endif + +#if HTT_ASSERT_LEVEL > 2 +#define HTT_ASSERT3(condition) adf_os_assert((condition)) +#else +#define HTT_ASSERT3(condition) +#endif + + +#define HTT_MAC_ADDR_LEN 6 + + +/* + * HTT_MAX_SEND_QUEUE_DEPTH - + * How many packets HTC should allow to accumulate in a send queue + * before calling the EpSendFull callback to see whether to retain + * or drop packets. + * This is not relevant for LL, where tx descriptors should be immediately + * downloaded to the target. + * This is not very relevant for HL either, since it is anticipated that + * the HL tx download scheduler will not work this far in advance - rather, + * it will make its decisions just-in-time, so it can be responsive to + * changing conditions. + * Hence, this queue depth threshold spec is mostly just a formality. + */ +#define HTT_MAX_SEND_QUEUE_DEPTH 64 + + +#define IS_PWR2(value) (((value) ^ ((value)-1)) == ((value) << 1) - 1) + + +/* FIX THIS + * Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size, + * rounded up to a cache line size. + */ +#define HTT_RX_BUF_SIZE 1920 +/* + * DMA_MAP expects the buffer to be an integral number of cache lines. + * Rather than checking the actual cache line size, this code makes a + * conservative estimate of what the cache line size could be. + */ +#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ +#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) + +#ifdef BIG_ENDIAN_HOST +/* + * big-endian: bytes within a 4-byte "word" are swapped: + * pre-swap post-swap + * index index + * 0 3 + * 1 2 + * 2 1 + * 3 0 + * 4 7 + * 5 6 + * etc. + * To compute the post-swap index from the pre-swap index, compute + * the byte offset for the start of the word (index & ~0x3) and add + * the swapped byte offset within the word (3 - (index & 0x3)). + */ +#define HTT_ENDIAN_BYTE_IDX_SWAP(idx) (((idx) & ~0x3) + (3 - ((idx) & 0x3))) +#else +/* little-endian: no adjustment needed */ +#define HTT_ENDIAN_BYTE_IDX_SWAP(idx) idx +#endif + + +#define HTT_TX_MUTEX_INIT(_mutex) \ + adf_os_spinlock_init(_mutex) + +#define HTT_TX_MUTEX_ACQUIRE(_mutex) \ + adf_os_spin_lock_bh(_mutex) + +#define HTT_TX_MUTEX_RELEASE(_mutex) \ + adf_os_spin_unlock_bh(_mutex) + +#define HTT_TX_MUTEX_DESTROY(_mutex) \ + adf_os_spinlock_destroy(_mutex) + +#define HTT_TX_DESC_PADDR(_pdev, _tx_desc_vaddr) \ + ((_pdev)->tx_descs.pool_paddr + (u_int32_t) \ + ((char *)(_tx_desc_vaddr) - \ + (char *)((_pdev)->tx_descs.pool_vaddr))) + +#ifdef ATH_11AC_TXCOMPACT + +#define HTT_TX_NBUF_QUEUE_MUTEX_INIT(_pdev) \ + adf_os_spinlock_init(&_pdev->txnbufq_mutex) + +#define HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(_pdev) \ + HTT_TX_MUTEX_DESTROY(&_pdev->txnbufq_mutex) + +#define HTT_TX_NBUF_QUEUE_REMOVE(_pdev, _msdu) \ + HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex); \ + _msdu = adf_nbuf_queue_remove(&_pdev->txnbufq);\ + HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex) + +#define HTT_TX_NBUF_QUEUE_ADD(_pdev, _msdu) \ + HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex); \ + adf_nbuf_queue_add(&_pdev->txnbufq, _msdu);\ + HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex) + +#define HTT_TX_NBUF_QUEUE_INSERT_HEAD(_pdev, _msdu) \ + HTT_TX_MUTEX_ACQUIRE(&_pdev->txnbufq_mutex); \ + adf_nbuf_queue_insert_head(&_pdev->txnbufq, _msdu);\ + HTT_TX_MUTEX_RELEASE(&_pdev->txnbufq_mutex) +#else + +#define HTT_TX_NBUF_QUEUE_MUTEX_INIT(_pdev) +#define HTT_TX_NBUF_QUEUE_REMOVE(_pdev, _msdu) +#define HTT_TX_NBUF_QUEUE_ADD(_pdev, _msdu) +#define HTT_TX_NBUF_QUEUE_INSERT_HEAD(_pdev, _msdu) +#define HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(_pdev) + +#endif + +#ifdef ATH_11AC_TXCOMPACT +#define HTT_TX_SCHED htt_tx_sched +#else +#define HTT_TX_SCHED(pdev) /* no-op */ +#endif + +int +htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems); + +void +htt_tx_detach(struct htt_pdev_t *pdev); + +int +htt_rx_attach(struct htt_pdev_t *pdev); + +void +htt_rx_detach(struct htt_pdev_t *pdev); + +int +htt_htc_attach(struct htt_pdev_t *pdev); + +void +htt_t2h_msg_handler(void *context, HTC_PACKET *pkt); + +void +htt_h2t_send_complete(void *context, HTC_PACKET *pkt); + +A_STATUS +htt_h2t_ver_req_msg(struct htt_pdev_t *pdev); + +extern A_STATUS (*htt_h2t_rx_ring_cfg_msg)( + struct htt_pdev_t *pdev); + +HTC_SEND_FULL_ACTION +htt_h2t_full(void *context, HTC_PACKET *pkt); + +struct htt_htc_pkt * +htt_htc_pkt_alloc(struct htt_pdev_t *pdev); + +void +htt_htc_pkt_free(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt); + +void +htt_htc_pkt_pool_free(struct htt_pdev_t *pdev); + +#ifdef ATH_11AC_TXCOMPACT +void +htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt); + +void +htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev); +#endif + +void htt_htc_disable_aspm(void); + +int +htt_rx_hash_list_insert(struct htt_pdev_t *pdev, u_int32_t paddr, + adf_nbuf_t netbuf); + +adf_nbuf_t +htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, u_int32_t paddr); + +#ifdef IPA_UC_OFFLOAD +int +htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev, + unsigned int uc_tx_buf_sz, + unsigned int uc_tx_buf_cnt, + unsigned int uc_tx_partition_base); + +int +htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev, + unsigned int rx_ind_ring_size); + +int +htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev); + +int +htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev); +#endif /* IPA_UC_OFFLOAD */ + +#endif /* _HTT_INTERNAL__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_isoc.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_isoc.h new file mode 100644 index 0000000000000..3285a844cfd91 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_isoc.h @@ -0,0 +1,1101 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_isoc.h + * + * @details + * This file defines the target --> host messages that configure the + * host data-path SW with the information required for data transfers + * to and from the target. + */ + +#ifndef _HTT_ISOC_H_ +#define _HTT_ISOC_H_ + +#include /* A_UINT32, A_UINT8 */ + +#ifdef ATHR_WIN_NWF +#pragma warning( disable:4214 ) //bit field types other than int +#endif + +#include "htt_common.h" + +/*=== definitions that apply to all messages ================================*/ + +typedef enum htt_isoc_t2h_msg_type { + /* 0x0 reserved for VERSION message (probably not needed) */ + + /* PEER_INFO - specify ID and parameters of a new peer */ + HTT_ISOC_T2H_MSG_TYPE_PEER_INFO = 0x1, + + /* PEER_UNMAP - deallocate the ID that refers to a peer */ + HTT_ISOC_T2H_MSG_TYPE_PEER_UNMAP = 0x2, + + /* ADDBA - start rx aggregation for the specified peer-TID */ + HTT_ISOC_T2H_MSG_TYPE_RX_ADDBA = 0x3, + + /* DELBA - stop rx aggregation for the specified peer-TID */ + HTT_ISOC_T2H_MSG_TYPE_RX_DELBA = 0x4, + + /* TX_COMPL_IND - over-the-air tx completion notification for a tx frame */ + HTT_ISOC_T2H_MSG_TYPE_TX_COMPL_IND = 0x5, + + /* SEC_IND - notification of the type of security used for a new peer */ + HTT_ISOC_T2H_MSG_TYPE_SEC_IND = 0x6, + + /* PEER_TX_READY - the target is ready to transmit to a new peer */ + HTT_ISOC_T2H_MSG_TYPE_PEER_TX_READY = 0x7, + + /* RX_ERR - notification that an rx frame was discarded due to errors */ + HTT_ISOC_T2H_MSG_TYPE_RX_ERR = 0x8, + + + /* keep this last */ + HTT_ISOC_T2H_NUM_MSGS +} htt_isoc_t2h_msg_type; + +/* + * HTT ISOC target to host message type - + * stored in bits 7:0 of the first word of the message + */ +#define HTT_ISOC_T2H_MSG_TYPE_M 0xff +#define HTT_ISOC_T2H_MSG_TYPE_S 0 + +#define HTT_ISOC_T2H_MSG_TYPE_SET(msg_addr, msg_type) \ + (*((A_UINT8 *) msg_addr) = (msg_type)) +#define HTT_ISOC_T2H_MSG_TYPE_GET(msg_addr) \ + (*((A_UINT8 *) msg_addr)) + +#ifndef INLINE +/* target FW */ +#define INLINE __inline +#define HTT_ISOC_INLINE_DEF +#endif /* INLINE */ + +static INLINE void +htt_isoc_t2h_field_set( + A_UINT32 *msg_addr32, + unsigned offset32, + unsigned mask, + unsigned shift, + unsigned value) +{ + /* sanity check: make sure the value fits within the field */ + //adf_os_assert(value << shift == (value << shift) | mask); + + msg_addr32 += offset32; + /* clear the field */ + *msg_addr32 &= ~mask; + /* write the new value */ + *msg_addr32 |= (value << shift); +} + +#ifdef HTT_ISOC_INLINE_DEF +#undef HTT_ISOC_INLINE_DEF +#undef INLINE +#endif + +#define HTT_ISOC_T2H_FIELD_GET(msg_addr32, offset32, mask, shift) \ + (((*(msg_addr32 + offset32)) & mask) >> shift) + +typedef enum { + /* ASSOC - "real" peer from STA-AP association */ + HTT_ISOC_T2H_PEER_TYPE_ASSOC = 0x0, + + /* SELF - self-peer for unicast tx to unassociated peer */ + HTT_ISOC_T2H_PEER_TYPE_SELF = 0x1, + + /* BSSID - reserved for FW use for BT-AMP+IBSS */ + HTT_ISOC_T2H_PEER_TYPE_BSSID = 0x2, + + /* BCAST - self-peer for multicast / broadcast tx */ + HTT_ISOC_T2H_PEER_TYPE_BCAST = 0x3 +} HTT_ISOC_T2H_PEER_TYPE_ENUM; + +enum { + HTT_ISOC_NON_QOS = 0, + HTT_ISOC_QOS = 1 +}; + +enum { + HTT_ISOC_RMF_DISABLED = 0, + HTT_ISOC_RMF_ENABLED = 1 +}; + +enum { + HTT_ISOC_TID_MGMT = 7 +}; + + +/*=== definitions for specific messages =====================================*/ + +/*=== PEER_INFO message ===*/ + +/** + * @brief target -> host peer info message definition + * + * @details + * The following diagram shows the format of the peer info message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 25|24|23 18|17|16|15 11|10|9|8|7|6| 0| + * |-----------------------------------------------------------------------| + * | mgmt DPU idx | bcast DPU idx | DPU idx | msg type | + * |-----------------------------------------------------------------------| + * | mgmt DPU sig |bcast DPU sig | DPU sig | peer ID | + * |-----------------------------------------------------------------------| + * | MAC addr 1 | MAC addr 0 | vdev ID | |R| peer type | + * |-----------------------------------------------------------------------| + * | MAC addr 5 | MAC addr 4 | MAC addr 3 | MAC addr 2 | + * |-----------------------------------------------------------------------| + * + * + * The following field definitions describe the format of the peer info + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as peer info message + * Value: 0x1 + * - DPU_IDX + * Bits 15:8 + * Purpose: specify the DPU index (a.k.a. security key ID) to use for + * unicast data frames sent to this peer + * Value: key ID + * - BCAST_DPU_IDX + * Bits 23:16 + * Purpose: specify the DPU index (a.k.a. security key ID) to use for + * broadcast data frames sent by this (self) peer + * Value: key ID + * - MGMT_DPU_IDX + * Bits 31:24 + * Purpose: specify the DPU index (a.k.a. security key ID) to use for + * unicast management frames sent by this (self) peer + * Value: key ID + * WORD 1: + * - PEER_ID + * Bits 10:0 + * Purpose: The ID that the target has allocated to refer to the peer + * - DPU_SIG + * Bits 17:11 + * Purpose: specify the DPU signature (a.k.a. security key validity + * magic number) to specify for unicast data frames sent to this peer + * - BCAST_DPU_SIG + * Bits 24:18 + * Purpose: specify the DPU signature (a.k.a. security key validity + * magic number) to specify for broadcast data frames sent by this + * (self) peer + * - MGMT_DPU_SIG + * Bits 31:25 + * Purpose: specify the DPU signature (a.k.a. security key validity + * magic number) to specify for unicast management frames sent by this + * (self) peer + * WORD 2: + * - PEER_TYPE + * Bits 5:0 + * Purpose: specify whether the peer in question is a real peer or + * one of the types of "self-peer" created for the vdev + * Value: HTT_ISOC_T2H_PEER_TYPE enum + * - RMF_ENABLED (R) + * Bit 6 + * Purpose: specify whether the peer in question has enable robust + * management frames, to encrypt certain managment frames + * Value: HTT_ISOC_RMF enum + * Value: HTT_ISOC_NON_QOS or HTT_ISOC_QOS + * - VDEV_ID + * Bits 15:8 + * Purpose: For a real peer, the vdev ID indicates which virtual device + * the peer is associated with. For a self-peer, the vdev ID shows + * which virtual device the self-peer represents. + * - MAC_ADDR_L16 + * Bits 31:16 + * Purpose: Identifies which peer the peer ID is for. + * Value: lower 2 bytes of the peer's MAC address + * For a self-peer, the peer's MAC address is the MAC address of the + * vdev the self-peer represents. + * WORD 3: + * - MAC_ADDR_U32 + * Bits 31:0 + * Purpose: Identifies which peer the peer ID is for. + * Value: upper 4 bytes of the peer's MAC address + * For a self-peer, the peer's MAC address is the MAC address of the + * vdev the self-peer represents. + */ +typedef struct htt_isoc_t2h_peer_info_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_PEER_INFO */ + dpu_idx: 8, + bcast_dpu_idx: 8, + mgmt_dpu_idx: 8; + /* word 1 */ + A_UINT32 + peer_id: 11, + dpu_sig: 7, + bcast_dpu_sig: 7, + mgmt_dpu_sig: 7; + /* word 2 */ + A_UINT32 + peer_type: 6, + rmf_enabled: 1, + reserved0: 1, + vdev_id: 8, + mac_addr_l16: 16; + /* word 3 */ + A_UINT32 mac_addr_u32; +} htt_isoc_t2h_peer_info_t; + +/* word 0 */ +#define HTT_ISOC_T2H_PEER_INFO_DPU_IDX_OFFSET32 0 +#define HTT_ISOC_T2H_PEER_INFO_DPU_IDX_M 0x0000ff00 +#define HTT_ISOC_T2H_PEER_INFO_DPU_IDX_S 8 + +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_OFFSET32 0 +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_M 0x00ff0000 +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_S 16 + +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_OFFSET32 0 +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_M 0xff000000 +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_S 24 + +/* word 1 */ +#define HTT_ISOC_T2H_PEER_INFO_PEER_ID_OFFSET32 1 +#define HTT_ISOC_T2H_PEER_INFO_PEER_ID_M 0x000007ff +#define HTT_ISOC_T2H_PEER_INFO_PEER_ID_S 0 + +#define HTT_ISOC_T2H_PEER_INFO_DPU_SIG_OFFSET32 1 +#define HTT_ISOC_T2H_PEER_INFO_DPU_SIG_M 0x0003f800 +#define HTT_ISOC_T2H_PEER_INFO_DPU_SIG_S 11 + +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_OFFSET32 1 +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_M 0x01fc0000 +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_S 18 + +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_OFFSET32 1 +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_M 0xfe000000 +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_S 25 + +/* word 2 */ +#define HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_OFFSET32 2 +#define HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_M 0x0000003f +#define HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_S 0 + +#define HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_OFFSET32 2 +#define HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_M 0x00000040 +#define HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_S 6 + +#define HTT_ISOC_T2H_PEER_INFO_VDEV_ID_OFFSET32 2 +#define HTT_ISOC_T2H_PEER_INFO_VDEV_ID_M 0x0000ff00 +#define HTT_ISOC_T2H_PEER_INFO_VDEV_ID_S 8 + +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_OFFSET32 2 +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_M 0xffff0000 +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_S 16 + +/* word 3 */ +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_U32_OFFSET32 3 +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_U32_M 0xffffffff +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_U32_S 0 + + +/* general field access macros */ + +#define HTT_ISOC_T2H_PEER_INFO_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_PEER_INFO_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_INFO_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_PEER_INFO_DPU_IDX_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(DPU_IDX, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_DPU_IDX_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(DPU_IDX, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(BCAST_DPU_IDX, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(BCAST_DPU_IDX, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(MGMT_DPU_IDX, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(MGMT_DPU_IDX, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(PEER_ID, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_DPU_SIG_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(DPU_SIG, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_DPU_SIG_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(DPU_SIG, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(BCAST_DPU_SIG, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(BCAST_DPU_SIG, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(MGMT_DPU_SIG, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(MGMT_DPU_SIG, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(PEER_TYPE, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(PEER_TYPE, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_QOS_CAPABLE_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(QOS_CAPABLE, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_QOS_CAPABLE_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(QOS_CAPABLE, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(RMF_ENABLED, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(RMF_ENABLED, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_VDEV_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(VDEV_ID, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_VDEV_ID_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(VDEV_ID, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(MAC_ADDR_L16, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(MAC_ADDR_L16, msg_addr) + +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_U32_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_SET(MAC_ADDR_U32, msg_addr, value) +#define HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_U32_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_INFO_FIELD_GET(MAC_ADDR_U32, msg_addr) + +/*=== PEER_UNMAP message ===*/ + +/** + * @brief target -> host peer unmap message definition + * + * @details + * The following diagram shows the format of the peer unmap message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 19|18 8|7 0| + * |-----------------------------------------------------------------------| + * | reserved | peer ID | msg type | + * |-----------------------------------------------------------------------| + * + * + * The following field definitions describe the format of the peer info + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as peer unmap message + * Value: 0x2 + * - PEER_ID + * Bits 18:8 + * Purpose: The ID that the target has allocated to refer to the peer + */ +typedef struct htt_isoc_t2h_peer_unmap_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_PEER_UNMAP */ + peer_id: 11, + reserved0: 13; +} htt_isoc_t2h_peer_unmap_t; + +/* word 0 */ +#define HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_M 0x0007ff00 +#define HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_S 8 + + +/* general field access macros */ + +#define HTT_ISOC_T2H_PEER_UNMAP_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_PEER_UNMAP_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_UNMAP_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_UNMAP_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_UNMAP_FIELD_GET(PEER_ID, msg_addr) + +/*=== ADDBA message ===*/ +enum { + htt_isoc_addba_success = 0, + /* TBD: use different failure values to specify failure causes? */ + htt_isoc_addba_fail = 1, +}; + +/** + * @brief target -> host ADDBA message definition + * + * @details + * The following diagram shows the format of the rx ADDBA message sent + * from the target to the host: + * + * |31 20|19 16|15 12|11 8|7 0| + * |---------------------------------------------------------------------| + * | peer ID | TID | window size | msg type | + * |---------------------------------------------------------------------| + * | reserved |S| start seq num | + * |---------------------------------------------------------------------| + * + * The following field definitions describe the format of the ADDBA + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an ADDBA message + * Value: 0x3 + * - WIN_SIZE + * Bits 15:8 + * Purpose: Specifies the length of the block ack window (max = 64). + * Value: + * block ack window length specified by the received ADDBA + * management message. + * - TID + * Bits 19:16 + * Purpose: Specifies which traffic identifier the ADDBA is for. + * Value: + * TID specified by the received ADDBA management message. + * - PEER_ID + * Bits 31:20 + * Purpose: Identifies which peer sent the ADDBA. + * Value: + * ID (hash value) used by the host for fast, direct lookup of + * host SW peer info, including rx reorder states. + * - START_SEQ_NUM + * Bits 11:0 + * Purpose: Specifies the initial location of the block ack window + * Value: start sequence value specified by the ADDBA-request message + * - STATUS + * Bit 12 + * Purpose: status of the WMI ADDBA request + * Value: 0 - SUCCESS, 1 - FAILURE + */ +typedef struct htt_isoc_t2h_addba_s { + /* word 0 */ + A_UINT32 msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_ADDBA */ + win_size: 8, + tid: 4, + peer_id: 12; + /* word 1 */ + A_UINT32 start_seq_num: 12, + status: 1, + reserved0: 19; +} htt_isoc_t2h_addba_t; + +/* word 0 */ +#define HTT_ISOC_T2H_ADDBA_WIN_SIZE_OFFSET32 0 +#define HTT_ISOC_T2H_ADDBA_WIN_SIZE_M 0x0000ff00 +#define HTT_ISOC_T2H_ADDBA_WIN_SIZE_S 8 + +#define HTT_ISOC_T2H_ADDBA_TID_OFFSET32 0 +#define HTT_ISOC_T2H_ADDBA_TID_M 0x000f0000 +#define HTT_ISOC_T2H_ADDBA_TID_S 16 + +#define HTT_ISOC_T2H_ADDBA_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_ADDBA_PEER_ID_M 0xfff00000 +#define HTT_ISOC_T2H_ADDBA_PEER_ID_S 20 + +/* word 1 */ +#define HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_OFFSET32 1 +#define HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_M 0x00000fff +#define HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_S 0 + +#define HTT_ISOC_T2H_ADDBA_STATUS_OFFSET32 1 +#define HTT_ISOC_T2H_ADDBA_STATUS_M 0x00001000 +#define HTT_ISOC_T2H_ADDBA_STATUS_S 12 + +/* general field access macros */ +#define HTT_ISOC_T2H_ADDBA_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_ADDBA_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_ADDBA_ ## field ## _M, \ + HTT_ISOC_T2H_ADDBA_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_ADDBA_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_ADDBA_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_ADDBA_ ## field ## _M, \ + HTT_ISOC_T2H_ADDBA_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_ADDBA_WIN_SIZE_SET(msg_addr, value) \ + HTT_ISOC_T2H_ADDBA_FIELD_SET(WIN_SIZE, msg_addr, value) +#define HTT_ISOC_T2H_ADDBA_WIN_SIZE_GET(msg_addr) \ + HTT_ISOC_T2H_ADDBA_FIELD_GET(WIN_SIZE, msg_addr) + +#define HTT_ISOC_T2H_ADDBA_TID_SET(msg_addr, value) \ + HTT_ISOC_T2H_ADDBA_FIELD_SET(TID, msg_addr, value) +#define HTT_ISOC_T2H_ADDBA_TID_GET(msg_addr) \ + HTT_ISOC_T2H_ADDBA_FIELD_GET(TID, msg_addr) + +#define HTT_ISOC_T2H_ADDBA_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_ADDBA_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_ADDBA_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_ADDBA_FIELD_GET(PEER_ID, msg_addr) + +#define HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_SET(msg_addr, value) \ + HTT_ISOC_T2H_ADDBA_FIELD_SET(START_SEQ_NUM, msg_addr, value) +#define HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_GET(msg_addr) \ + HTT_ISOC_T2H_ADDBA_FIELD_GET(START_SEQ_NUM, msg_addr) + +#define HTT_ISOC_T2H_ADDBA_STATUS_SET(msg_addr, value) \ + HTT_ISOC_T2H_ADDBA_FIELD_SET(STATUS, msg_addr, value) +#define HTT_ISOC_T2H_ADDBA_STATUS_GET(msg_addr) \ + HTT_ISOC_T2H_ADDBA_FIELD_GET(STATUS, msg_addr) + +/*=== DELBA message ===*/ + +/** + * @brief target -> host DELBA message definition + * + * @details + * The following diagram shows the format of the rx DELBA message sent + * from the target to the host: + * + * |31 20|19 16|15 12|11 8|7 0| + * |---------------------------------------------------------------------| + * | peer ID | TID | reserved |S| msg type | + * |---------------------------------------------------------------------| + * + * The following field definitions describe the format of the ADDBA + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an DELBA message + * Value: 0x4 + * - TID + * Bits 19:16 + * Purpose: Specifies which traffic identifier the DELBA is for. + * Value: + * TID specified by the received DELBA management message. + * - PEER_ID + * Bits 31:20 + * Purpose: Identifies which peer sent the DELBA. + * Value: + * ID (hash value) used by the host for fast, direct lookup of + * host SW peer info, including rx reorder states. + * - STATUS + * Bit 8 + * Purpose: status of the WMI DELBA request + * Value: 0 - SUCCESS, 1 - FAILURE + */ +typedef struct htt_isoc_t2h_delba_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_DELBA */ + status: 1, + reserved0: 7, + tid: 4, + peer_id: 12; +} htt_isoc_t2h_delba_t; + +/* word 0 */ +#define HTT_ISOC_T2H_DELBA_TID_OFFSET32 0 +#define HTT_ISOC_T2H_DELBA_TID_M 0x000f0000 +#define HTT_ISOC_T2H_DELBA_TID_S 16 + +#define HTT_ISOC_T2H_DELBA_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_DELBA_PEER_ID_M 0xfff00000 +#define HTT_ISOC_T2H_DELBA_PEER_ID_S 20 + +#define HTT_ISOC_T2H_DELBA_STATUS_OFFSET32 0 +#define HTT_ISOC_T2H_DELBA_STATUS_M 0x00000100 +#define HTT_ISOC_T2H_DELBA_STATUS_S 8 + +/* general field access macros */ + +#define HTT_ISOC_T2H_DELBA_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_DELBA_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_DELBA_ ## field ## _M, \ + HTT_ISOC_T2H_DELBA_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_DELBA_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_DELBA_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_DELBA_ ## field ## _M, \ + HTT_ISOC_T2H_DELBA_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_DELBA_TID_SET(msg_addr, value) \ + HTT_ISOC_T2H_DELBA_FIELD_SET(TID, msg_addr, value) +#define HTT_ISOC_T2H_DELBA_TID_GET(msg_addr) \ + HTT_ISOC_T2H_DELBA_FIELD_GET(TID, msg_addr) + +#define HTT_ISOC_T2H_DELBA_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_DELBA_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_DELBA_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_DELBA_FIELD_GET(PEER_ID, msg_addr) + +#define HTT_ISOC_T2H_DELBA_STATUS_SET(msg_addr, value) \ + HTT_ISOC_T2H_DELBA_FIELD_SET(STATUS, msg_addr, value) +#define HTT_ISOC_T2H_DELBA_STATUS_GET(msg_addr) \ + HTT_ISOC_T2H_DELBA_FIELD_GET(STATUS, msg_addr) + +/*=== SEC_IND message ===*/ + +/** + * @brief target -> host Security indication message definition + * + * @details + * The following diagram shows the format of the SEC_IND message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 25|24|23 18|17|16|15 11|10|9|8|7|6| 0| + * |-----------------------------------------------------------------------| + * | is unicast | sec type | Peer id | msg type | + * |-----------------------------------------------------------------------| + * | mic key1 | + * |-----------------------------------------------------------------------| + * | mic key2 | + * |-----------------------------------------------------------------------| + * + * + * The following field definitions describe the format of the peer info + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as SEC_IND message + * Value: 0x6 + * - PEER_ID + * Bits 15:8 + * Purpose: The ID that the target has allocated to refer to the peer + * Value: Peer ID + * - SEC_TYPE + * Bits 23:16 + * Purpose: specify the security encryption type + * Value: htt_sec_type + * - is unicast + * Bits 31:24 + * Purpose: specify unicast/bcast + * Value: 1-unicast/0-bcast + * WORD 1: + * - MIC1 + * Bits 31:0 + * Purpose: Mickey1 + * WORD 2: + * - MIC2 + * Bits 31:0 + * Purpose: Mickey2 + */ +typedef struct htt_isoc_t2h_sec_ind_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_SEC_IND */ + peer_id: 8, + sec_type: 8, + is_unicast: 8; + /* word 1 */ + A_UINT32 mic_key1; + /* word 2 */ + A_UINT32 mic_key2; + /* word 3 */ + A_UINT32 status; +} htt_isoc_t2h_sec_ind_t; + +/* word 0 */ +#define HTT_ISOC_T2H_SEC_IND_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_SEC_IND_PEER_ID_M 0x0000ff00 +#define HTT_ISOC_T2H_SEC_IND_PEER_ID_S 8 + +#define HTT_ISOC_T2H_SEC_IND_SEC_TYPE_OFFSET32 0 +#define HTT_ISOC_T2H_SEC_IND_SEC_TYPE_M 0x00ff0000 +#define HTT_ISOC_T2H_SEC_IND_SEC_TYPE_S 16 + +#define HTT_ISOC_T2H_SEC_IND_IS_UNICAST_OFFSET32 0 +#define HTT_ISOC_T2H_SEC_IND_IS_UNICAST_M 0xff000000 +#define HTT_ISOC_T2H_SEC_IND_IS_UNICAST_S 24 + +/* word 1 */ +#define HTT_ISOC_T2H_SEC_IND_MIC1_OFFSET32 1 +#define HTT_ISOC_T2H_SEC_IND_MIC1_M 0xffffffff +#define HTT_ISOC_T2H_SEC_IND_MIC1_S 0 + +/* word 2 */ +#define HTT_ISOC_T2H_SEC_IND_MIC2_OFFSET32 2 +#define HTT_ISOC_T2H_SEC_IND_MIC2_M 0xffffffff +#define HTT_ISOC_T2H_SEC_IND_MIC2_S 0 + + +/* general field access macros */ +#define HTT_ISOC_T2H_SEC_IND_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _M, \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_SEC_IND_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _M, \ + HTT_ISOC_T2H_SEC_IND_ ## field ## _S) + +/* access macros for specific fields */ +#define HTT_ISOC_T2H_SEC_IND_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_SEC_IND_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_SEC_IND_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_SEC_IND_FIELD_GET(PEER_ID, msg_addr) + +#define HTT_ISOC_T2H_SEC_IND_SEC_TYPE_SET(msg_addr, value) \ + HTT_ISOC_T2H_SEC_IND_FIELD_SET(SEC_TYPE, msg_addr, value) +#define HTT_ISOC_T2H_SEC_IND_SEC_TYPE_GET(msg_addr) \ + HTT_ISOC_T2H_SEC_IND_FIELD_GET(SEC_TYPE, msg_addr) + +#define HTT_ISOC_T2H_SEC_IND_IS_UNICAST_SET(msg_addr, value) \ + HTT_ISOC_T2H_SEC_IND_FIELD_SET(IS_UNICAST, msg_addr, value) +#define HTT_ISOC_T2H_SEC_IND_IS_UNICAST_GET(msg_addr) \ + HTT_ISOC_T2H_SEC_IND_FIELD_GET(IS_UNICAST, msg_addr) + +#define HTT_ISOC_T2H_SEC_IND_MIC1_SET(msg_addr, value) \ + HTT_ISOC_T2H_SEC_IND_FIELD_SET(MIC1, msg_addr, value) +#define HTT_ISOC_T2H_SEC_IND_MIC1_GET(msg_addr) \ + HTT_ISOC_T2H_SEC_IND_FIELD_GET(MIC1, msg_addr) + +#define HTT_ISOC_T2H_SEC_IND_MIC2_SET(msg_addr, value) \ + HTT_ISOC_T2H_SEC_IND_FIELD_SET(MIC2, msg_addr, value) +#define HTT_ISOC_T2H_SEC_IND_MIC2_GET(msg_addr) \ + HTT_ISOC_T2H_SEC_IND_FIELD_GET(MIC2, msg_addr) + +/*=== PEER_TX_READY message ===*/ + +/** + * @brief target -> host peer tx ready message definition + * + * @details + * The following diagram shows the format of the peer tx ready message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 19|18 8|7 0| + * |-----------------------------------------------------------------------| + * | reserved | peer ID | msg type | + * |-----------------------------------------------------------------------| + * + * + * The following field definitions describe the format of the peer info + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as peer tx ready message + * Value: 0x7 + * - PEER_ID + * Bits 18:8 + * Purpose: The ID assigned to the peer by the PEER_INFO message + */ +typedef struct htt_isoc_t2h_peer_tx_ready_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_PEER_TX_READY */ + peer_id: 11, + reserved0: 13; +} htt_isoc_t2h_peer_tx_ready_t; + +/* word 0 */ +#define HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_M 0x0007ff00 +#define HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_S 8 + + +/* general field access macros */ + +#define HTT_ISOC_T2H_PEER_TX_READY_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_PEER_TX_READY_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _M, \ + HTT_ISOC_T2H_PEER_TX_READY_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_PEER_TX_READY_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_PEER_TX_READY_FIELD_GET(PEER_ID, msg_addr) + + +/*=== RX_ERR message ===*/ + +/** + * @brief target -> host rx error notification message definition + * + * @details + * The following diagram shows the format of the rx err message sent + * from the target to the host. This layout assumes the target operates + * as little-endian. + * + * |31 16|15 8|7|6|5|4 0| + * |---------------------------------------------------------------------| + * | peer ID | rx err type | msg type | + * |---------------------------------------------------------------------| + * | reserved | rx err count |M| r | ext TID | + * |---------------------------------------------------------------------| + * M = multicast + * r = reserved + * + * The following field definitions describe the format of the peer info + * message sent from the target to the host. + * + * WORD 0: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this as an rx err message + * Value: 0x8 + * - RX_ERR_TYPE + * Bits 15:8 + * Purpose: specifies which type of rx error is being reported + * Value: htt_rx_ind_mpdu_status enum + * - PEER_ID + * Bits 31:16 + * Purpose: specify which peer sent the frame that resulted in an error + * WORD 1: + * - EXT_TID + * Bits 4:0 + * Purpose: specifies which traffic type had the rx error + * Value: 0-15 for a real TID value, 16 for non-QoS data, 31 for unknown + * - MCAST + * Bit 6 + * Purpose: specify whether the rx error frame was unicast or multicast + * Value: 0 -> unicast, 1 -> multicast + * - L2_HDR_IS_80211 + * Bit 7 + * Purpose: specifies whether the included L2 header (if present) is in + * 802.3 or 802.11 format + * Value: 0 -> 802.3, 1 -> 802.11 + * - L2_HDR_BYTES + * Bits 15:8 + * Purpose: Specify the size of the L2 header in this rx error report. + * Value: + * If no L2 header is included, this field shall be 0. + * If a 802.3 + LLC/SNAP header is included, this field shall be + * 14 (ethernet header) + 8 (LLC/SNAP). + * If a 802.11 header is included, this field shall be 24 bytes for + * a basic header, or 26 bytes if a QoS control field is included, + * or 30 bytes if a 4th address is included, or 32 bytes if a 4th + * address and a QoS control field are included, etc. + * Though the L2 header included in the message needs to include + * padding up to a 4-byte boundary, this L2 header size field need + * not account for the padding following the L2 header. + * - SEC_HDR_BYTES + * Bits 23:16 + * Purpose: Specify the size of the security encapsulation header in + * this rx error report. + * Value: + * If no security header is included, this field shall be 0. + * If a security header is included, this field depends on the + * security type, which can be inferred from the rx error type. + * For TKIP MIC errors, the security header could be any of: + * 8 - if IV / KeyID and Extended IV are included + * 16 - if MIC is also included + * 20 - if ICV is also included + * - RX_ERR_CNT + * Bits 31:24 + * Purpose: specifies how many rx errors are reported in this message + * Value: + * Rx error reports that include a L2 header and/or security header + * will set this field to 1, to indicate that the error notification + * is for a single frame. + * Rx error reports that don't include a L2 header or security header + * can use this field to send a single message to report multiple + * erroneous rx frames. + */ +typedef struct htt_isoc_t2h_rx_err_s { + /* word 0 */ + A_UINT32 + msg_type: 8, /* HTT_ISOC_T2H_MSG_TYPE_RX_ERR */ + rx_err_type: 8, + peer_id: 16; + /* word 1 */ + A_UINT32 + ext_tid: 5, + reserved1: 1, + mcast: 1, + l2_hdr_is_80211: 1, + l2_hdr_bytes: 8, + sec_hdr_bytes: 8, + rx_err_cnt: 8; + /* words 2 - M-1: L2 header */ + /* words M - N: security header */ +} htt_isoc_t2h_rx_err_t; + +/* word 0 */ +#define HTT_ISOC_T2H_RX_ERR_TYPE_OFFSET32 0 +#define HTT_ISOC_T2H_RX_ERR_TYPE_M 0x0000ff00 +#define HTT_ISOC_T2H_RX_ERR_TYPE_ID_S 8 + +#define HTT_ISOC_T2H_RX_ERR_PEER_ID_OFFSET32 0 +#define HTT_ISOC_T2H_RX_ERR_PEER_ID_M 0xffff0000 +#define HTT_ISOC_T2H_RX_ERR_PEER_ID_S 16 + +/* word 1 */ +#define HTT_ISOC_T2H_RX_ERR_EXT_TID_OFFSET32 1 +#define HTT_ISOC_T2H_RX_ERR_EXT_TID_M 0x0000001f +#define HTT_ISOC_T2H_RX_ERR_EXT_TID_ID_S 0 + +#define HTT_ISOC_T2H_RX_ERR_MCAST_OFFSET32 1 +#define HTT_ISOC_T2H_RX_ERR_MCAST_M 0x00000040 +#define HTT_ISOC_T2H_RX_ERR_MCAST_ID_S 6 + +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_IS_80211_OFFSET32 1 +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_IS_80211_M 0x00000080 +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_IS_80211_ID_S 7 + +#define HTT_ISOC_T2H_RX_L2_HDR_BYTES_OFFSET32 1 +#define HTT_ISOC_T2H_RX_L2_HDR_BYTES_M 0x0000ff00 +#define HTT_ISOC_T2H_RX_L2_HDR_BYTES_ID_S 8 + +#define HTT_ISOC_T2H_RX_SEC_HDR_BYTES_OFFSET32 1 +#define HTT_ISOC_T2H_RX_SEC_HDR_BYTES_M 0x00ff0000 +#define HTT_ISOC_T2H_RX_SEC_HDR_BYTES_ID_S 16 + +#define HTT_ISOC_T2H_RX_ERR_CNT_OFFSET32 1 +#define HTT_ISOC_T2H_RX_ERR_CNT_M 0xff000000 +#define HTT_ISOC_T2H_RX_ERR_CNT_ID_S 24 + + +/* general field access macros */ + +#define HTT_ISOC_T2H_RX_ERR_FIELD_SET(field, msg_addr, value) \ + htt_isoc_t2h_field_set( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _M, \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _S, \ + value) + +#define HTT_ISOC_T2H_RX_ERR_FIELD_GET(field, msg_addr) \ + HTT_ISOC_T2H_FIELD_GET( \ + ((A_UINT32 *) msg_addr), \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _OFFSET32, \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _M, \ + HTT_ISOC_T2H_RX_ERR_ ## field ## _S) + +/* access macros for specific fields */ + +#define HTT_ISOC_T2H_RX_ERR_TYPE_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(TYPE, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_TYPE_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(TYPE, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_PEER_ID_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(PEER_ID, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_PEER_ID_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(PEER_ID, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_EXT_TID_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(EXT_TID, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_EXT_TID_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(EXT_TID, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_MCAST_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(MCAST, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_MCAST_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(MCAST, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_IS_80211_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(L2_HDR_IS_80211, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_IS_80211_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(L2_HDR_IS_80211, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_BYTES_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(L2_HDR_BYTES, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_L2_HDR_BYTES_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(L2_HDR_BYTES, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_SEC_HDR_BYTES_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(SEC_HDR_BYTES, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_SEC_HDR_BYTES_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(SEC_HDR_BYTES, msg_addr) + +#define HTT_ISOC_T2H_RX_ERR_CNT_SET(msg_addr, value) \ + HTT_ISOC_T2H_RX_ERR_FIELD_SET(CNT, msg_addr, value) +#define HTT_ISOC_T2H_RX_ERR_CNT_GET(msg_addr) \ + HTT_ISOC_T2H_RX_ERR_FIELD_GET(CNT, msg_addr) + + +#endif /* _HTT_ISOC_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_rx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_rx.c new file mode 100644 index 0000000000000..8018055d5279b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_rx.c @@ -0,0 +1,2659 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_rx.c + * @brief Implement receive aspects of HTT. + * @details + * This file contains three categories of HTT rx code: + * 1. An abstraction of the rx descriptor, to hide the + * differences between the HL vs. LL rx descriptor. + * 2. Functions for providing access to the (series of) + * rx descriptor(s) and rx frame(s) associated with + * an rx indication message. + * 3. Functions for setting up and using the MAC DMA + * rx ring (applies to LL only). + */ + +#include /* adf_os_mem_alloc,free, etc. */ +#include /* adf_os_print, a_bool_t */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_timer_free */ + +#include /* HTT_HL_RX_DESC_SIZE */ +#include +#include +#include +#include /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */ +#include "regtable.h" + +#include /* ieee80211_frame, ieee80211_qoscntl */ +#include /* ieee80211_rx_status */ + +#ifdef DEBUG_DMA_DONE +#include +#include +#endif + +#ifdef DEBUG_DMA_DONE +extern int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev); +#endif + +/* AR9888v1 WORKAROUND for EV#112367 */ +/* FIX THIS - remove this WAR when the bug is fixed */ +#define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR + +/*--- setup / tear-down functions -------------------------------------------*/ + +#ifndef HTT_RX_RING_SIZE_MIN +#define HTT_RX_RING_SIZE_MIN 128 /* slightly larger than one large A-MPDU */ +#endif + +#ifndef HTT_RX_RING_SIZE_MAX +#define HTT_RX_RING_SIZE_MAX 2048 /* roughly 20 ms @ 1 Gbps of 1500B MSDUs */ +#endif + +#ifndef HTT_RX_AVG_FRM_BYTES +#define HTT_RX_AVG_FRM_BYTES 1000 +#endif + +#ifndef HTT_RX_HOST_LATENCY_MAX_MS +#define HTT_RX_HOST_LATENCY_MAX_MS 20 /* ms */ /* very conservative */ +#endif + +#ifndef HTT_RX_HOST_LATENCY_WORST_LIKELY_MS +#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10 /* ms */ /* conservative */ +#endif + +#ifndef HTT_RX_RING_REFILL_RETRY_TIME_MS +#define HTT_RX_RING_REFILL_RETRY_TIME_MS 50 +#endif + +void +htt_rx_hash_deinit(struct htt_pdev_t *pdev); + +static int +CEIL_PWR2(int value) +{ + int log2; + if (IS_PWR2(value)) { + return value; + } + log2 = 0; + while (value) { + value >>= 1; + log2++; + } + return (1 << log2); +} + +/* + * This function is used both below within this file (which the compiler + * will hopefully inline), and out-line from other files via the + * htt_rx_msdu_first_msdu_flag function pointer. + */ +static inline a_bool_t +htt_rx_msdu_first_msdu_flag_hl(htt_pdev_handle pdev, void *msdu_desc) +{ + return ((u_int8_t*)msdu_desc - sizeof(struct hl_htt_rx_ind_base)) + [HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_FLAG_OFFSET)] & + HTT_RX_IND_HL_FLAG_FIRST_MSDU ? A_TRUE : A_FALSE; +} + +static a_bool_t +htt_rx_msdu_first_msdu_flag_ll(htt_pdev_handle pdev, void *msdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) msdu_desc; + return (a_bool_t) + (((*(((u_int32_t *) &rx_desc->msdu_end) + 4)) & + RX_MSDU_END_4_FIRST_MSDU_MASK) >> + RX_MSDU_END_4_FIRST_MSDU_LSB); +} + +u_int16_t +htt_rx_msdu_rx_desc_size_hl( + htt_pdev_handle pdev, + void *msdu_desc + ) +{ + return ((u_int8_t*)(msdu_desc) - HTT_RX_IND_HL_BYTES) + [HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)]; +} + +static int +htt_rx_ring_size(struct htt_pdev_t *pdev) +{ + int size; + + /* + * It is expected that the host CPU will typically be able to service + * the rx indication from one A-MPDU before the rx indication from + * the subsequent A-MPDU happens, roughly 1-2 ms later. + * However, the rx ring should be sized very conservatively, to + * accomodate the worst reasonable delay before the host CPU services + * a rx indication interrupt. + * The rx ring need not be kept full of empty buffers. In theory, + * the htt host SW can dynamically track the low-water mark in the + * rx ring, and dynamically adjust the level to which the rx ring + * is filled with empty buffers, to dynamically meet the desired + * low-water mark. + * In contrast, it's difficult to resize the rx ring itself, once + * it's in use. + * Thus, the ring itself should be sized very conservatively, while + * the degree to which the ring is filled with empty buffers should + * be sized moderately conservatively. + */ + size = + ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) * + 1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ / + (8 * HTT_RX_AVG_FRM_BYTES) * + HTT_RX_HOST_LATENCY_MAX_MS; + + if (size < HTT_RX_RING_SIZE_MIN) { + size = HTT_RX_RING_SIZE_MIN; + } + if (size > HTT_RX_RING_SIZE_MAX) { + size = HTT_RX_RING_SIZE_MAX; + } + size = CEIL_PWR2(size); + return size; +} + +static int +htt_rx_ring_fill_level(struct htt_pdev_t *pdev) +{ + int size; + + size = + ol_cfg_max_thruput_mbps(pdev->ctrl_pdev) * + 1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ / + (8 * HTT_RX_AVG_FRM_BYTES) * + HTT_RX_HOST_LATENCY_WORST_LIKELY_MS; + /* + * Make sure the fill level is at least 1 less than the ring size. + * Leaving 1 element empty allows the SW to easily distinguish + * between a full ring vs. an empty ring. + */ + if (size >= pdev->rx_ring.size) { + size = pdev->rx_ring.size - 1; + } + return size; +} + +static void +htt_rx_ring_refill_retry(void *arg) +{ + htt_pdev_handle pdev = (htt_pdev_handle)arg; + htt_rx_msdu_buff_replenish(pdev); +} + +void +htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) +{ + int idx; + a_status_t status; + struct htt_host_rx_desc_base *rx_desc; + + idx = *(pdev->rx_ring.alloc_idx.vaddr); + while (num > 0) { + u_int32_t paddr; + adf_nbuf_t rx_netbuf; + int headroom; + + rx_netbuf = adf_nbuf_alloc(pdev->osdev, HTT_RX_BUF_SIZE, 0, 4, FALSE); + if (!rx_netbuf) { + adf_os_timer_cancel(&pdev->rx_ring.refill_retry_timer); + /* + * Failed to fill it to the desired level - + * we'll start a timer and try again next time. + * As long as enough buffers are left in the ring for + * another A-MPDU rx, no special recovery is needed. + */ +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_refill_cnt++; +#endif + adf_os_timer_start(&pdev->rx_ring.refill_retry_timer, + HTT_RX_RING_REFILL_RETRY_TIME_MS); + goto fail; + } + + /* Clear rx_desc attention word before posting to Rx ring */ + rx_desc = htt_rx_desc(rx_netbuf); + *(u_int32_t *)&rx_desc->attention = 0; + +#ifdef DEBUG_DMA_DONE + *(u_int32_t *)&rx_desc->msdu_end = 1; + + #define MAGIC_PATTERN 0xDEADBEEF + *(u_int32_t *)&rx_desc->msdu_start = MAGIC_PATTERN; + + /* To ensure that attention bit is reset and msdu_end is set before + calling dma_map */ + smp_mb(); +#endif + /* + * Adjust adf_nbuf_data to point to the location in the buffer + * where the rx descriptor will be filled in. + */ + headroom = adf_nbuf_data(rx_netbuf) - (u_int8_t *) rx_desc; + adf_nbuf_push_head(rx_netbuf, headroom); + +#ifdef DEBUG_DMA_DONE + status = adf_nbuf_map(pdev->osdev, rx_netbuf, ADF_OS_DMA_BIDIRECTIONAL); +#else + status = adf_nbuf_map(pdev->osdev, rx_netbuf, ADF_OS_DMA_FROM_DEVICE); +#endif + if (status != A_STATUS_OK) { + adf_nbuf_free(rx_netbuf); + goto fail; + } + paddr = adf_nbuf_get_frag_paddr_lo(rx_netbuf, 0); + if (pdev->cfg.is_full_reorder_offload) { + if(adf_os_unlikely( + htt_rx_hash_list_insert(pdev, paddr, rx_netbuf))) { + adf_os_print("%s: hash insert failed!\n", __FUNCTION__); +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap(pdev->osdev, rx_netbuf, + ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap(pdev->osdev, rx_netbuf, ADF_OS_DMA_FROM_DEVICE); +#endif + adf_nbuf_free(rx_netbuf); + goto fail; + } + } else { + pdev->rx_ring.buf.netbufs_ring[idx] = rx_netbuf; + } + pdev->rx_ring.buf.paddrs_ring[idx] = paddr; + pdev->rx_ring.fill_cnt++; + + num--; + idx++; + idx &= pdev->rx_ring.size_mask; + } + +fail: + *(pdev->rx_ring.alloc_idx.vaddr) = idx; + return; +} + +unsigned +htt_rx_ring_elems(struct htt_pdev_t *pdev) +{ + return + (*pdev->rx_ring.alloc_idx.vaddr - pdev->rx_ring.sw_rd_idx.msdu_payld) & + pdev->rx_ring.size_mask; +} + +unsigned int +htt_rx_in_order_ring_elems(struct htt_pdev_t *pdev) +{ + return + (*pdev->rx_ring.alloc_idx.vaddr - *pdev->rx_ring.target_idx.vaddr) & + pdev->rx_ring.size_mask; +} + +void +htt_rx_detach(struct htt_pdev_t *pdev) +{ + + if (pdev->cfg.is_high_latency) { + return; + } + + adf_os_timer_cancel(&pdev->rx_ring.refill_retry_timer); + adf_os_timer_free(&pdev->rx_ring.refill_retry_timer); + + if (pdev->cfg.is_full_reorder_offload) { + adf_os_mem_free_consistent( + pdev->osdev, + sizeof(u_int32_t), + pdev->rx_ring.target_idx.vaddr, + pdev->rx_ring.target_idx.paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.target_idx), memctx)); + htt_rx_hash_deinit(pdev); + } else { + int sw_rd_idx = pdev->rx_ring.sw_rd_idx.msdu_payld; + + while (sw_rd_idx != *(pdev->rx_ring.alloc_idx.vaddr)) { +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap( + pdev->osdev, pdev->rx_ring.buf.netbufs_ring[sw_rd_idx], + ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap( + pdev->osdev, pdev->rx_ring.buf.netbufs_ring[sw_rd_idx], + ADF_OS_DMA_FROM_DEVICE); +#endif + adf_nbuf_free(pdev->rx_ring.buf.netbufs_ring[sw_rd_idx]); + sw_rd_idx++; + sw_rd_idx &= pdev->rx_ring.size_mask; + } + adf_os_mem_free(pdev->rx_ring.buf.netbufs_ring); + } + + adf_os_mem_free_consistent( + pdev->osdev, + sizeof(u_int32_t), + pdev->rx_ring.alloc_idx.vaddr, + pdev->rx_ring.alloc_idx.paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.alloc_idx), memctx)); + + adf_os_mem_free_consistent( + pdev->osdev, + pdev->rx_ring.size * sizeof(u_int32_t), + pdev->rx_ring.buf.paddrs_ring, + pdev->rx_ring.base_paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.buf), memctx)); +} + +/*--- rx descriptor field access functions ----------------------------------*/ +/* + * These functions need to use bit masks and shifts to extract fields + * from the rx descriptors, rather than directly using the bitfields. + * For example, use + * (desc & FIELD_MASK) >> FIELD_LSB + * rather than + * desc.field + * This allows the functions to work correctly on either little-endian + * machines (no endianness conversion needed) or big-endian machines + * (endianness conversion provided automatically by the HW DMA's + * byte-swizzling). + */ +/* FIX THIS: APPLIES TO LL ONLY */ +u_int16_t +htt_rx_mpdu_desc_seq_num_ll(htt_pdev_handle pdev, void *mpdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) mpdu_desc; + + return + (u_int16_t)(((*((u_int32_t *) &rx_desc->mpdu_start)) & + RX_MPDU_START_0_SEQ_NUM_MASK) >> + RX_MPDU_START_0_SEQ_NUM_LSB); +} + +u_int16_t +htt_rx_mpdu_desc_seq_num_hl(htt_pdev_handle pdev, void *mpdu_desc) +{ + if (pdev->rx_desc_size_hl) { + return pdev->cur_seq_num_hl = + (u_int16_t)(HTT_WORD_GET(*(u_int32_t*)mpdu_desc, + HTT_HL_RX_DESC_MPDU_SEQ_NUM)); + } else { + return (u_int16_t)(pdev->cur_seq_num_hl); + } +} + +/* FIX THIS: APPLIES TO LL ONLY */ +void +htt_rx_mpdu_desc_pn_ll( + htt_pdev_handle pdev, + void *mpdu_desc, + union htt_rx_pn_t *pn, + int pn_len_bits) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) mpdu_desc; + + switch (pn_len_bits) { + case 24: + /* bits 23:0 */ + pn->pn24 = + rx_desc->mpdu_start.pn_31_0 & 0xffffff; + break; + case 48: + /* bits 31:0 */ + pn->pn48 = rx_desc->mpdu_start.pn_31_0; + /* bits 47:32 */ + pn->pn48 |= + ((u_int64_t) ((*(((u_int32_t *) &rx_desc->mpdu_start) + 2)) + & RX_MPDU_START_2_PN_47_32_MASK)) + << (32 - RX_MPDU_START_2_PN_47_32_LSB); + break; + case 128: + /* bits 31:0 */ + pn->pn128[0] = rx_desc->mpdu_start.pn_31_0; + /* bits 47:32 */ + pn->pn128[0] |= + ((u_int64_t) ((*(((u_int32_t *) &rx_desc->mpdu_start) + 2)) + & RX_MPDU_START_2_PN_47_32_MASK)) + << (32 - RX_MPDU_START_2_PN_47_32_LSB); + /* bits 63:48 */ + pn->pn128[0] |= + ((u_int64_t) ((*(((u_int32_t *) &rx_desc->msdu_end) + 2)) + & RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK)) + << (48 - RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB); + /* bits 95:64 */ + pn->pn128[1] = rx_desc->msdu_end.ext_wapi_pn_95_64; + /* bits 127:96 */ + pn->pn128[1] |= + ((u_int64_t) rx_desc->msdu_end.ext_wapi_pn_127_96) << 32; + break; + default: + adf_os_print( + "Error: invalid length spec (%d bits) for PN\n", pn_len_bits); + }; +} + +/* HL case */ +void +htt_rx_mpdu_desc_pn_hl( + htt_pdev_handle pdev, + void *mpdu_desc, + union htt_rx_pn_t *pn, + int pn_len_bits) +{ + if (htt_rx_msdu_first_msdu_flag_hl(pdev, mpdu_desc) == A_TRUE) { + /* Fix Me: only for little endian */ + struct hl_htt_rx_desc_base *rx_desc = + (struct hl_htt_rx_desc_base *) mpdu_desc; + u_int32_t *word_ptr = (u_int32_t *)pn->pn128; + + /* TODO: for Host of big endian */ + switch (pn_len_bits) { + case 128: + /* bits 128:64 */ + *(word_ptr + 3) = rx_desc->pn_127_96; + /* bits 63:0 */ + *(word_ptr + 2) = rx_desc->pn_95_64; + case 48: + /* bits 48:0 + * copy 64 bits + */ + *(word_ptr + 1) = rx_desc->u0.pn_63_32; + case 24: + /* bits 23:0 + * copy 32 bits + */ + *(word_ptr + 0) = rx_desc->pn_31_0; + break; + default: + adf_os_print( + "Error: invalid length spec (%d bits) for PN\n", pn_len_bits); + adf_os_assert(0); + }; + } else { + /* not first msdu, no pn info */ + adf_os_print( + "Error: get pn from a not-first msdu.\n"); + adf_os_assert(0); + } +} + +u_int32_t +htt_rx_mpdu_desc_tsf32( + htt_pdev_handle pdev, + void *mpdu_desc) +{ +/* FIX THIS */ +return 0; +} + +/* FIX THIS: APPLIES TO LL ONLY */ +char * +htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev_handle pdev, void *mpdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) mpdu_desc; + return rx_desc->rx_hdr_status; +} + +/* FIX THIS: APPLIES TO LL ONLY */ +a_bool_t +htt_rx_msdu_desc_completes_mpdu_ll(htt_pdev_handle pdev, void *msdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) msdu_desc; + return (a_bool_t) + (((*(((u_int32_t *) &rx_desc->msdu_end) + 4)) & + RX_MSDU_END_4_LAST_MSDU_MASK) >> + RX_MSDU_END_4_LAST_MSDU_LSB); +} + +a_bool_t +htt_rx_msdu_desc_completes_mpdu_hl(htt_pdev_handle pdev, void *msdu_desc) +{ + return ( + ((u_int8_t*)(msdu_desc) - sizeof(struct hl_htt_rx_ind_base)) + [HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_FLAG_OFFSET)] + & HTT_RX_IND_HL_FLAG_LAST_MSDU) + ? A_TRUE : A_FALSE; +} + +/* FIX THIS: APPLIES TO LL ONLY */ +int +htt_rx_msdu_has_wlan_mcast_flag_ll(htt_pdev_handle pdev, void *msdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) msdu_desc; + /* HW rx desc: the mcast_bcast flag is only valid if first_msdu is set */ + return + ((*(((u_int32_t *) &rx_desc->msdu_end) + 4)) & + RX_MSDU_END_4_FIRST_MSDU_MASK) >> + RX_MSDU_END_4_FIRST_MSDU_LSB; +} + +int +htt_rx_msdu_has_wlan_mcast_flag_hl(htt_pdev_handle pdev, void *msdu_desc) +{ + /* currently, only first msdu has hl rx_desc */ + return htt_rx_msdu_first_msdu_flag_hl(pdev, msdu_desc) == A_TRUE; +} + +/* FIX THIS: APPLIES TO LL ONLY */ +a_bool_t +htt_rx_msdu_is_wlan_mcast_ll(htt_pdev_handle pdev, void *msdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) msdu_desc; + return + ((*((u_int32_t *) &rx_desc->attention)) & + RX_ATTENTION_0_MCAST_BCAST_MASK) >> + RX_ATTENTION_0_MCAST_BCAST_LSB; +} + +a_bool_t +htt_rx_msdu_is_wlan_mcast_hl(htt_pdev_handle pdev, void *msdu_desc) +{ + struct hl_htt_rx_desc_base *rx_desc = + (struct hl_htt_rx_desc_base *) msdu_desc; + return + HTT_WORD_GET(*(u_int32_t*)rx_desc, HTT_HL_RX_DESC_MCAST_BCAST); +} + +/* FIX THIS: APPLIES TO LL ONLY */ +int +htt_rx_msdu_is_frag_ll(htt_pdev_handle pdev, void *msdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = + (struct htt_host_rx_desc_base *) msdu_desc; + return + ((*((u_int32_t *) &rx_desc->attention)) & + RX_ATTENTION_0_FRAGMENT_MASK) >> + RX_ATTENTION_0_FRAGMENT_LSB; +} + +int +htt_rx_msdu_is_frag_hl(htt_pdev_handle pdev, void *msdu_desc) +{ + struct hl_htt_rx_desc_base *rx_desc = + (struct hl_htt_rx_desc_base *) msdu_desc; + + return + HTT_WORD_GET(*(u_int32_t*)rx_desc, HTT_HL_RX_DESC_MCAST_BCAST); +} + +static inline +u_int8_t +htt_rx_msdu_fw_desc_get(htt_pdev_handle pdev, void *msdu_desc) +{ + /* + * HL and LL use the same format for FW rx desc, but have the FW rx desc + * in different locations. + * In LL, the FW rx descriptor has been copied into the same + * htt_host_rx_desc_base struct that holds the HW rx desc. + * In HL, the FW rx descriptor, along with the MSDU payload, + * is in the same buffer as the rx indication message. + * + * Use the FW rx desc offset configured during startup to account for + * this difference between HL vs. LL. + * + * An optimization would be to define the LL and HL msdu_desc pointer + * in such a way that they both use the same offset to the FW rx desc. + * Then the following functions could be converted to macros, without + * needing to expose the htt_pdev_t definition outside HTT. + */ + return *(((u_int8_t *) msdu_desc) + pdev->rx_fw_desc_offset); +} + +int +htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc) +{ + return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_DISCARD_M; +} + +int +htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc) +{ + return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_FORWARD_M; +} + +int +htt_rx_msdu_inspect(htt_pdev_handle pdev, void *msdu_desc) +{ + return htt_rx_msdu_fw_desc_get(pdev, msdu_desc) & FW_RX_DESC_INSPECT_M; +} + +void +htt_rx_msdu_actions( + htt_pdev_handle pdev, + void *msdu_desc, + int *discard, + int *forward, + int *inspect) +{ + u_int8_t rx_msdu_fw_desc = htt_rx_msdu_fw_desc_get(pdev, msdu_desc); +#ifdef HTT_DEBUG_DATA + HTT_PRINT("act:0x%x ",rx_msdu_fw_desc); +#endif + *discard = rx_msdu_fw_desc & FW_RX_DESC_DISCARD_M; + *forward = rx_msdu_fw_desc & FW_RX_DESC_FORWARD_M; + *inspect = rx_msdu_fw_desc & FW_RX_DESC_INSPECT_M; +} + +static inline adf_nbuf_t +htt_rx_netbuf_pop( + htt_pdev_handle pdev) +{ + int idx; + adf_nbuf_t msdu; + + HTT_ASSERT1(htt_rx_ring_elems(pdev) != 0); + +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_ring_idx++; + pdev->rx_ring.dbg_ring_idx &= pdev->rx_ring.size_mask; +#endif + + idx = pdev->rx_ring.sw_rd_idx.msdu_payld; + msdu = pdev->rx_ring.buf.netbufs_ring[idx]; + idx++; + idx &= pdev->rx_ring.size_mask; + pdev->rx_ring.sw_rd_idx.msdu_payld = idx; + pdev->rx_ring.fill_cnt--; + return msdu; +} + +static inline adf_nbuf_t +htt_rx_in_order_netbuf_pop( + htt_pdev_handle pdev, u_int32_t paddr) +{ + HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); + pdev->rx_ring.fill_cnt--; + return htt_rx_hash_list_lookup(pdev, paddr); +} + +/* FIX ME: this function applies only to LL rx descs. An equivalent for HL rx descs is needed. */ +#ifdef CHECKSUM_OFFLOAD +static inline +void +htt_set_checksum_result_ll(htt_pdev_handle pdev, adf_nbuf_t msdu, + struct htt_host_rx_desc_base *rx_desc) +{ +#define MAX_IP_VER 2 +#define MAX_PROTO_VAL 4 + struct rx_msdu_start *rx_msdu = &rx_desc->msdu_start; + unsigned int proto = (rx_msdu->tcp_proto) | (rx_msdu->udp_proto << 1); + + /* + * HW supports TCP & UDP checksum offload for ipv4 and ipv6 + */ + static const adf_nbuf_l4_rx_cksum_type_t + cksum_table[][MAX_PROTO_VAL][MAX_IP_VER] = + { + { + /* non-fragmented IP packet */ + /* non TCP/UDP packet */ + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + /* TCP packet */ + { ADF_NBUF_RX_CKSUM_TCP, ADF_NBUF_RX_CKSUM_TCPIPV6}, + /* UDP packet */ + { ADF_NBUF_RX_CKSUM_UDP, ADF_NBUF_RX_CKSUM_UDPIPV6 }, + /* invalid packet type */ + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + }, + { + /* fragmented IP packet */ + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + { ADF_NBUF_RX_CKSUM_NONE, ADF_NBUF_RX_CKSUM_NONE }, + } + }; + + adf_nbuf_rx_cksum_t cksum = { + cksum_table[rx_msdu->ip_frag][proto][rx_msdu->ipv6_proto], + ADF_NBUF_RX_CKSUM_NONE, + 0 + } ; + + if (cksum.l4_type != (adf_nbuf_l4_rx_cksum_type_t)ADF_NBUF_RX_CKSUM_NONE) { + cksum.l4_result = ((*(u_int32_t *) &rx_desc->attention) & + RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK) ? + ADF_NBUF_RX_CKSUM_NONE : + ADF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY; + } + adf_nbuf_set_rx_cksum(msdu, &cksum ); +#undef MAX_IP_VER +#undef MAX_PROTO_VAL +} + +static inline +void +htt_set_checksum_result_hl(adf_nbuf_t msdu, + struct htt_host_rx_desc_base *rx_desc) +{ + u_int8_t flag = ((u_int8_t*)rx_desc - sizeof(struct hl_htt_rx_ind_base))[HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_HL_FLAG_OFFSET)]; + int is_ipv6 = flag & HTT_RX_IND_HL_FLAG_IPV6 ? 1:0; + int is_tcp = flag & HTT_RX_IND_HL_FLAG_TCP ? 1:0; + int is_udp = flag & HTT_RX_IND_HL_FLAG_UDP ? 1:0; + + adf_nbuf_rx_cksum_t cksum = { + ADF_NBUF_RX_CKSUM_NONE, + ADF_NBUF_RX_CKSUM_NONE, + 0 + } ; + + switch ((is_udp << 2) | (is_tcp << 1) | (is_ipv6 << 0)) { + case 0x4: + cksum.l4_type = ADF_NBUF_RX_CKSUM_UDP; + break; + case 0x2: + cksum.l4_type = ADF_NBUF_RX_CKSUM_TCP; + break; + case 0x5: + cksum.l4_type = ADF_NBUF_RX_CKSUM_UDPIPV6; + break; + case 0x3: + cksum.l4_type = ADF_NBUF_RX_CKSUM_TCPIPV6; + break; + default: + cksum.l4_type = ADF_NBUF_RX_CKSUM_NONE; + break; + } + if (cksum.l4_type != (adf_nbuf_l4_rx_cksum_type_t)ADF_NBUF_RX_CKSUM_NONE) { + cksum.l4_result = flag & HTT_RX_IND_HL_FLAG_C4_FAILED ? + ADF_NBUF_RX_CKSUM_NONE : ADF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY; + } + adf_nbuf_set_rx_cksum(msdu, &cksum ); +} + +#else +#define htt_set_checksum_result_ll(pdev, msdu, rx_desc) /* no-op */ +#define htt_set_checksum_result_hl(msdu, rx_desc) /* no-op */ +#endif + +#ifdef DEBUG_DMA_DONE +void +htt_rx_print_rx_indication( + adf_nbuf_t rx_ind_msg, + htt_pdev_handle pdev) +{ + u_int32_t *msg_word; + int byte_offset; + int mpdu_range, num_mpdu_range; + + msg_word = (u_int32_t *)adf_nbuf_data(rx_ind_msg); + + adf_os_print("------------------HTT RX IND-----------------------------\n"); + adf_os_print("alloc idx paddr %x (*vaddr) %d\n", + pdev->rx_ring.alloc_idx.paddr, + *pdev->rx_ring.alloc_idx.vaddr); + + adf_os_print("sw_rd_idx msdu_payld %d msdu_desc %d\n", + pdev->rx_ring.sw_rd_idx.msdu_payld, + pdev->rx_ring.sw_rd_idx.msdu_desc); + + adf_os_print("dbg_ring_idx %d\n", pdev->rx_ring.dbg_ring_idx); + + adf_os_print("fill_level %d fill_cnt %d\n",pdev->rx_ring.fill_level, + pdev->rx_ring.fill_cnt); + + adf_os_print("initial msdu_payld %d curr mpdu range %d curr mpdu cnt %d\n", + pdev->rx_ring.dbg_initial_msdu_payld, + pdev->rx_ring.dbg_mpdu_range, + pdev->rx_ring.dbg_mpdu_count); + + /* Print the RX_IND contents */ + + adf_os_print("peer id %x RV %x FV %x ext_tid %x msg_type %x\n", + HTT_RX_IND_PEER_ID_GET(*msg_word), + HTT_RX_IND_REL_VALID_GET(*msg_word), + HTT_RX_IND_FLUSH_VALID_GET(*msg_word), + HTT_RX_IND_EXT_TID_GET(*msg_word), + HTT_T2H_MSG_TYPE_GET(*msg_word)); + + adf_os_print("num_mpdu_ranges %x rel_seq_num_end %x rel_seq_num_start %x\n" + " flush_seq_num_end %x flush_seq_num_start %x\n", + HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)), + HTT_RX_IND_REL_SEQ_NUM_END_GET(*(msg_word + 1)), + HTT_RX_IND_REL_SEQ_NUM_START_GET(*(msg_word + 1)), + HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(*(msg_word + 1)), + HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(*(msg_word + 1))); + + adf_os_print("fw_rx_desc_bytes %x\n", HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32))); + + /* receive MSDU desc for current frame */ + byte_offset = HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET + + pdev->rx_ind_msdu_byte_idx); + + adf_os_print("msdu byte idx %x msdu desc %x\n", pdev->rx_ind_msdu_byte_idx, + HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32))); + + num_mpdu_range = HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)); + + for (mpdu_range = 0; mpdu_range < num_mpdu_range; mpdu_range++) { + enum htt_rx_status status; + int num_mpdus; + + htt_rx_ind_mpdu_range_info( + pdev, rx_ind_msg, mpdu_range, &status, &num_mpdus); + + adf_os_print("mpdu_range %x status %x num_mpdus %x\n", + pdev->rx_ind_msdu_byte_idx, status, num_mpdus); + } + adf_os_print("---------------------------------------------------------\n"); +} +#endif + +#ifdef DEBUG_DMA_DONE +#define MAX_DONE_BIT_CHECK_ITER 5 +#endif + +int +htt_rx_amsdu_pop_ll( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu) +{ + int msdu_len, msdu_chaining = 0; + adf_nbuf_t msdu; + struct htt_host_rx_desc_base *rx_desc; + u_int8_t *rx_ind_data; + u_int32_t *msg_word, num_msdu_bytes; + enum htt_t2h_msg_type msg_type; + + HTT_ASSERT1(htt_rx_ring_elems(pdev) != 0); + rx_ind_data = adf_nbuf_data(rx_ind_msg); + msg_word = (u_int32_t *)rx_ind_data; + + msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); + + if (adf_os_unlikely(HTT_T2H_MSG_TYPE_RX_FRAG_IND == msg_type)) { + num_msdu_bytes = HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32)); + } else { + num_msdu_bytes = HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + HTT_RX_IND_HDR_PREFIX_SIZE32 + + HTT_RX_PPDU_DESC_SIZE32)); + } + msdu = *head_msdu = htt_rx_netbuf_pop(pdev); + while (1) { + int last_msdu, msdu_len_invalid, msdu_chained; + int byte_offset; + + /* + * Set the netbuf length to be the entire buffer length initially, + * so the unmap will unmap the entire buffer. + */ + adf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE); +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_FROM_DEVICE); +#endif + + /* cache consistency has been taken care of by the adf_nbuf_unmap */ + + /* + * Now read the rx descriptor. + * Set the length to the appropriate value. + * Check if this MSDU completes a MPDU. + */ + rx_desc = htt_rx_desc(msdu); + + /* + * Make the netbuf's data pointer point to the payload rather + * than the descriptor. + */ + adf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION); + + /* + * Sanity check - confirm the HW is finished filling in the rx data. + * If the HW and SW are working correctly, then it's guaranteed that + * the HW's MAC DMA is done before this point in the SW. + * To prevent the case that we handle a stale Rx descriptor, just + * assert for now until we have a way to recover. + */ + +#ifdef DEBUG_DMA_DONE + if (adf_os_unlikely(!((*(u_int32_t *) &rx_desc->attention) + & RX_ATTENTION_0_MSDU_DONE_MASK))) { + + int dbg_iter = MAX_DONE_BIT_CHECK_ITER; + + + adf_os_print("malformed frame\n"); + + while (dbg_iter && + (!((*(u_int32_t *) &rx_desc->attention) & + RX_ATTENTION_0_MSDU_DONE_MASK))) { + adf_os_mdelay(1); + + adf_os_invalidate_range((void *)rx_desc, + (void*)((char *)rx_desc + + HTT_RX_STD_DESC_RESERVATION)); + + adf_os_print("debug iter %d success %d\n", dbg_iter, + pdev->rx_ring.dbg_sync_success); + + dbg_iter--; + } + + if (adf_os_unlikely(!((*(u_int32_t *) &rx_desc->attention) + & RX_ATTENTION_0_MSDU_DONE_MASK))) + { + +#ifdef HTT_RX_RESTORE + adf_os_print("RX done bit error detected!\n"); + adf_nbuf_set_next(msdu, NULL); + *tail_msdu = msdu; + pdev->rx_ring.rx_reset = 1; + return msdu_chaining; +#else + process_wma_set_command(0,(int)GEN_PARAM_CRASH_INJECT, + 0, GEN_CMD); + HTT_ASSERT_ALWAYS(0); +#endif + } + pdev->rx_ring.dbg_sync_success++; + adf_os_print("debug iter %d success %d\n", dbg_iter, + pdev->rx_ring.dbg_sync_success); + } +#else + HTT_ASSERT_ALWAYS( + (*(u_int32_t *) &rx_desc->attention) & + RX_ATTENTION_0_MSDU_DONE_MASK); +#endif + /* + * Copy the FW rx descriptor for this MSDU from the rx indication + * message into the MSDU's netbuf. + * HL uses the same rx indication message definition as LL, and + * simply appends new info (fields from the HW rx desc, and the + * MSDU payload itself). + * So, the offset into the rx indication message only has to account + * for the standard offset of the per-MSDU FW rx desc info within + * the message, and how many bytes of the per-MSDU FW rx desc info + * have already been consumed. (And the endianness of the host, + * since for a big-endian host, the rx ind message contents, + * including the per-MSDU rx desc bytes, were byteswapped during + * upload.) + */ + if (pdev->rx_ind_msdu_byte_idx < num_msdu_bytes) { + if (adf_os_unlikely(HTT_T2H_MSG_TYPE_RX_FRAG_IND == msg_type)) { + byte_offset = HTT_ENDIAN_BYTE_IDX_SWAP( + HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET); + } else { + byte_offset = HTT_ENDIAN_BYTE_IDX_SWAP( + HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET + + pdev->rx_ind_msdu_byte_idx); + } + + *((u_int8_t *) &rx_desc->fw_desc.u.val) = rx_ind_data[byte_offset]; + /* + * The target is expected to only provide the basic per-MSDU rx + * descriptors. Just to be sure, verify that the target has not + * attached extension data (e.g. LRO flow ID). + */ + /* + * The assertion below currently doesn't work for RX_FRAG_IND + * messages, since their format differs from the RX_IND format + * (no FW rx PPDU desc in the current RX_FRAG_IND message). + * If the RX_FRAG_IND message format is updated to match the + * RX_IND message format, then the following assertion can be + * restored. + */ + //adf_os_assert((rx_ind_data[byte_offset] & FW_RX_DESC_EXT_M) == 0); + pdev->rx_ind_msdu_byte_idx += 1; // or more, if there's ext data + } else { + /* + * When an oversized AMSDU happened, FW will lost some of + * MSDU status - in this case, the FW descriptors provided + * will be less than the actual MSDUs inside this MPDU. + * Mark the FW descriptors so that it will still deliver to + * upper stack, if no CRC error for this MPDU. + * + * FIX THIS - the FW descriptors are actually for MSDUs in + * the end of this A-MSDU instead of the beginning. + */ + *((u_int8_t *) &rx_desc->fw_desc.u.val) = 0; + } + + /* + * TCP/UDP checksum offload support + */ + htt_set_checksum_result_ll(pdev, msdu, rx_desc); + + msdu_len_invalid = (*(u_int32_t *) &rx_desc->attention) & + RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK; + msdu_chained = (((*(u_int32_t *) &rx_desc->frag_info) & + RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK) >> + RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB); + msdu_len = + ((*((u_int32_t *) &rx_desc->msdu_start)) & + RX_MSDU_START_0_MSDU_LENGTH_MASK) >> + RX_MSDU_START_0_MSDU_LENGTH_LSB; + + do { + if (!msdu_len_invalid && !msdu_chained) { +#if defined(PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR) + if (msdu_len > 0x3000) { + break; + } +#endif + adf_nbuf_trim_tail( + msdu, HTT_RX_BUF_SIZE - (RX_STD_DESC_SIZE + msdu_len)); + } + } while (0); + + while (msdu_chained--) { + adf_nbuf_t next = + htt_rx_netbuf_pop(pdev); + adf_nbuf_set_pktlen(next, HTT_RX_BUF_SIZE); + msdu_len -= HTT_RX_BUF_SIZE; + adf_nbuf_set_next(msdu, next); + msdu = next; + msdu_chaining = 1; + + if (msdu_chained == 0) { + /* Trim the last one to the correct size - accounting for + * inconsistent HW lengths cuasing length overflows and + * underflows + */ + if (((unsigned)msdu_len) > + ((unsigned)(HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE))) { + msdu_len = (HTT_RX_BUF_SIZE - RX_STD_DESC_SIZE); + } + + adf_nbuf_trim_tail( + next, HTT_RX_BUF_SIZE - (RX_STD_DESC_SIZE + msdu_len)); + } + } + + last_msdu = + ((*(((u_int32_t *) &rx_desc->msdu_end) + 4)) & + RX_MSDU_END_4_LAST_MSDU_MASK) >> + RX_MSDU_END_4_LAST_MSDU_LSB; + + if (last_msdu) { + adf_nbuf_set_next(msdu, NULL); + break; + } else { + adf_nbuf_t next = htt_rx_netbuf_pop(pdev); + adf_nbuf_set_next(msdu, next); + msdu = next; + } + } + *tail_msdu = msdu; + + /* + * Don't refill the ring yet. + * First, the elements popped here are still in use - it is + * not safe to overwrite them until the matching call to + * mpdu_desc_list_next. + * Second, for efficiency it is preferable to refill the rx ring + * with 1 PPDU's worth of rx buffers (something like 32 x 3 buffers), + * rather than one MPDU's worth of rx buffers (something like 3 buffers). + * Consequently, we'll rely on the txrx SW to tell us when it is done + * pulling all the PPDU's rx buffers out of the rx ring, and then + * refill it just once. + */ + return msdu_chaining; +} + +int +htt_rx_amsdu_pop_hl( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu) +{ + pdev->rx_desc_size_hl = + (adf_nbuf_data(rx_ind_msg)) + [HTT_ENDIAN_BYTE_IDX_SWAP( + HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)]; + + /* point to the rx desc */ + adf_nbuf_pull_head(rx_ind_msg, + sizeof(struct hl_htt_rx_ind_base)); + *head_msdu = *tail_msdu = rx_ind_msg; + +#ifdef CHECKSUM_OFFLOAD + htt_set_checksum_result_hl(rx_ind_msg, (struct htt_host_rx_desc_base *)(adf_nbuf_data(rx_ind_msg))); +#endif + + adf_nbuf_set_next(*tail_msdu, NULL); + return 0; +} + +int +htt_rx_frag_pop_hl( + htt_pdev_handle pdev, + adf_nbuf_t frag_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu) +{ + adf_nbuf_pull_head(frag_msg, HTT_RX_FRAG_IND_BYTES); + pdev->rx_desc_size_hl = + (adf_nbuf_data(frag_msg)) + [HTT_ENDIAN_BYTE_IDX_SWAP( + HTT_RX_IND_HL_RX_DESC_LEN_OFFSET)]; + + /* point to the rx desc */ + adf_nbuf_pull_head(frag_msg, + sizeof(struct hl_htt_rx_ind_base)); + *head_msdu = *tail_msdu = frag_msg; + + adf_nbuf_set_next(*tail_msdu, NULL); + return 0; +} + +int +htt_rx_offload_msdu_pop_ll( + htt_pdev_handle pdev, + adf_nbuf_t offload_deliver_msg, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf) +{ + adf_nbuf_t buf; + u_int32_t *msdu_hdr, msdu_len; + + *head_buf = *tail_buf = buf = htt_rx_netbuf_pop(pdev); + /* Fake read mpdu_desc to keep desc ptr in sync */ + htt_rx_mpdu_desc_list_next(pdev, NULL); + adf_nbuf_set_pktlen(buf, HTT_RX_BUF_SIZE); +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap(pdev->osdev, buf, ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap(pdev->osdev, buf, ADF_OS_DMA_FROM_DEVICE); +#endif + msdu_hdr = (u_int32_t *)adf_nbuf_data(buf); + + /* First dword */ + msdu_len = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(*msdu_hdr); + *peer_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(*msdu_hdr); + + /* Second dword */ + msdu_hdr++; + *vdev_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(*msdu_hdr); + *tid = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(*msdu_hdr); + *fw_desc = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(*msdu_hdr); + + adf_nbuf_pull_head(buf, HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES); + adf_nbuf_set_pktlen(buf, msdu_len); + return 0; +} + +int +htt_rx_offload_paddr_msdu_pop_ll( + htt_pdev_handle pdev, + u_int32_t * msg_word, + int msdu_iter, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf) +{ + adf_nbuf_t buf; + u_int32_t *msdu_hdr, msdu_len; + u_int32_t * curr_msdu; + u_int32_t paddr; + + curr_msdu = msg_word + (msdu_iter * HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS); + paddr = HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*curr_msdu); + *head_buf = *tail_buf = buf = htt_rx_in_order_netbuf_pop(pdev, paddr); + + if (adf_os_unlikely(NULL == buf)) { + adf_os_print("%s: netbuf pop failed!\n", __FUNCTION__); + return 0; + } + adf_nbuf_set_pktlen(buf, HTT_RX_BUF_SIZE); +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap(pdev->osdev, buf, ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap(pdev->osdev, buf, ADF_OS_DMA_FROM_DEVICE); +#endif + msdu_hdr = (u_int32_t *)adf_nbuf_data(buf); + + /* First dword */ + msdu_len = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_LEN_GET(*msdu_hdr); /* 2 bytes */ + *peer_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_PEER_ID_GET(*msdu_hdr); /* 2 bytes */ + + /* Second dword */ + msdu_hdr++; + *vdev_id = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_VDEV_ID_GET(*msdu_hdr); /* 1 bytes */ + *tid = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_TID_GET(*msdu_hdr); /* 1 bytes */ + *fw_desc = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_DESC_GET(*msdu_hdr); + + adf_nbuf_pull_head(buf, HTT_RX_OFFLOAD_DELIVER_IND_MSDU_HDR_BYTES); + adf_nbuf_set_pktlen(buf, msdu_len); + return 0; +} + +int +htt_rx_offload_msdu_pop_hl( + htt_pdev_handle pdev, + adf_nbuf_t offload_deliver_msg, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf) +{ + return 0; +} + +#ifdef RX_HASH_DEBUG +#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count) +#else +#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) /* no-op */ +#endif + +/* Return values: 1 - success, 0 - failure */ +int +htt_rx_amsdu_rx_in_order_pop_ll( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu) +{ + adf_nbuf_t msdu, next, prev = NULL; + u_int8_t *rx_ind_data; + u_int32_t *msg_word; + unsigned int msdu_count = 0; + u_int8_t offload_ind; + struct htt_host_rx_desc_base *rx_desc; + + HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); + + rx_ind_data = adf_nbuf_data(rx_ind_msg); + msg_word = (u_int32_t *)rx_ind_data; + + offload_ind = HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(*msg_word); + + /* Get the total number of MSDUs */ + msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); + HTT_RX_CHECK_MSDU_COUNT(msdu_count); + + msg_word = (u_int32_t *)(rx_ind_data + HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES); + if (offload_ind) { + ol_rx_offload_paddr_deliver_ind_handler(pdev, msdu_count, + msg_word); + *head_msdu = *tail_msdu = NULL; + return 0; + } + + (*head_msdu) = msdu = + htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word)); + + if (adf_os_unlikely(NULL == msdu)) { + adf_os_print("%s: netbuf pop failed!\n", __FUNCTION__); + *tail_msdu = NULL; + return 0; + } + + while (msdu_count > 0) { + + /* + * Set the netbuf length to be the entire buffer length initially, + * so the unmap will unmap the entire buffer. + */ + adf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE); +#ifdef DEBUG_DMA_DONE + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_BIDIRECTIONAL); +#else + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_FROM_DEVICE); +#endif + + /* cache consistency has been taken care of by the adf_nbuf_unmap */ + + rx_desc = htt_rx_desc(msdu); + /* + * Make the netbuf's data pointer point to the payload rather + * than the descriptor. + */ + adf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION); + + adf_nbuf_trim_tail( + msdu, HTT_RX_BUF_SIZE - (RX_STD_DESC_SIZE + + HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word + 1)))); + + *((u_int8_t *) &rx_desc->fw_desc.u.val) = + HTT_RX_IN_ORD_PADDR_IND_FW_DESC_GET(*(msg_word + 1)); + + msdu_count--; + + if (adf_os_unlikely((*((u_int8_t *) &rx_desc->fw_desc.u.val)) & + FW_RX_DESC_MIC_ERR_M)) { + u_int8_t tid = + HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(*(u_int32_t *)rx_ind_data); + u_int16_t peer_id = + HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(*(u_int32_t *)rx_ind_data); + ol_rx_mic_error_handler(pdev->txrx_pdev, tid, peer_id, rx_desc, msdu); + + htt_rx_desc_frame_free(pdev, msdu); + + /* if this is the last msdu */ + if (!msdu_count) { + /* if this is the only msdu */ + if (!prev) { + *head_msdu = *tail_msdu = NULL; + return 0; + } else { + *tail_msdu = prev; + adf_nbuf_set_next(prev, NULL); + return 1; + } + } else { /* if this is not the last msdu */ + /* get the next msdu */ + msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS; + next = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word)); + if (adf_os_unlikely(NULL == next)) { + adf_os_print("%s: netbuf pop failed!\n", __FUNCTION__); + *tail_msdu = NULL; + return 0; + } + + /* if this is not the first msdu, update the next pointer of the + preceding msdu */ + if (prev) { + adf_nbuf_set_next(prev, next); + } else {/* if this is the first msdu, update the head pointer */ + *head_msdu = next; + } + msdu = next; + continue; + } + } + + /* check if this is the last msdu */ + if (msdu_count) { + msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS; + next = htt_rx_in_order_netbuf_pop(pdev, + HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*msg_word)); + if (adf_os_unlikely(NULL == next)) { + adf_os_print("%s: netbuf pop failed!\n", __FUNCTION__); + *tail_msdu = NULL; + return 0; + } + adf_nbuf_set_next(msdu, next); + prev = msdu; + msdu = next; + } + else { + *tail_msdu = msdu; + adf_nbuf_set_next(msdu, NULL); + } + } + + return 1; +} + +/* Util fake function that has same prototype as adf_nbuf_clone that just + * retures the same nbuf + */ +adf_nbuf_t +htt_rx_adf_noclone_buf(adf_nbuf_t buf) +{ + return buf; +} + +/* FIXME: This is a HW definition not provded by HW, where does it go ? */ +enum { + HW_RX_DECAP_FORMAT_RAW = 0, + HW_RX_DECAP_FORMAT_NWIFI, + HW_RX_DECAP_FORMAT_8023, + HW_RX_DECAP_FORMAT_ETH2, +}; + +#define HTT_FCS_LEN (4) + +static void +htt_rx_parse_ppdu_start_status( + struct htt_host_rx_desc_base *rx_desc, + struct ieee80211_rx_status *rs) +{ + + struct rx_ppdu_start *ppdu_start = &rx_desc->ppdu_start; + + /* RSSI */ + rs->rs_rssi = ppdu_start->rssi_comb; + + /* PHY rate */ + /* rs_ratephy coding + [b3 - b0] + 0 -> OFDM + 1 -> CCK + 2 -> HT + 3 -> VHT + OFDM / CCK + [b7 - b4 ] => LSIG rate + [b23 - b8 ] => service field (b'12 static/dynamic, b'14..b'13 BW for VHT) + [b31 - b24 ] => Reserved + HT / VHT + [b15 - b4 ] => SIG A_2 12 LSBs + [b31 - b16] => SIG A_1 16 LSBs + + */ + if (ppdu_start->preamble_type == 0x4 ) { + rs->rs_ratephy = ppdu_start->l_sig_rate_select; + rs->rs_ratephy |= ppdu_start->l_sig_rate << 4; + rs->rs_ratephy |= ppdu_start->service << 8; + } else { + rs->rs_ratephy = + (ppdu_start->preamble_type & 0x4) ? 3 : 2; + rs->rs_ratephy |= + (ppdu_start->ht_sig_vht_sig_a_2 & 0xFFF) << 4; + rs->rs_ratephy |= + (ppdu_start->ht_sig_vht_sig_a_1 & 0xFFFF) << 16; + } + + return; +} + + +/* This function is used by montior mode code to restitch an MSDU list + * corresponding to an MPDU back into an MPDU by linking up the skbs. + */ +adf_nbuf_t +htt_rx_restitch_mpdu_from_msdus( + htt_pdev_handle pdev, + adf_nbuf_t head_msdu, + struct ieee80211_rx_status *rx_status, + unsigned clone_not_reqd) +{ + + adf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list_cloned; + adf_nbuf_t (*clone_nbuf_fn)(adf_nbuf_t buf); + unsigned decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len, + mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir, + is_amsdu, is_first_frag, amsdu_pad, msdu_len; + struct htt_host_rx_desc_base *rx_desc; + char *hdr_desc; + unsigned char *dest; + struct ieee80211_frame *wh; + struct ieee80211_qoscntl*qos; + + /* If this packet does not go up the normal stack path we dont need to + * waste cycles cloning the packets + */ + clone_nbuf_fn = + clone_not_reqd ? htt_rx_adf_noclone_buf : adf_nbuf_clone; + + /* The nbuf has been pulled just beyond the status and points to the + * payload + */ + msdu_orig = head_msdu; + rx_desc = htt_rx_desc(msdu_orig); + + /* Fill out the rx_status from the PPDU start and end fields */ + if (rx_desc->attention.first_mpdu) { + htt_rx_parse_ppdu_start_status(rx_desc, rx_status); + + /* The timestamp is no longer valid - It will be valid only for the + * last MPDU + */ + rx_status->rs_tstamp.tsf = ~0; + } + + decap_format = + GET_FIELD(&rx_desc->msdu_start, RX_MSDU_START_2_DECAP_FORMAT); + + head_frag_list_cloned = NULL; + + /* Easy case - The MSDU status indicates that this is a non-decapped + * packet in RAW mode. + * return + */ + if (decap_format == HW_RX_DECAP_FORMAT_RAW) { + /* Note that this path might suffer from headroom unavailabilty - + * but the RX status is usually enough + */ + mpdu_buf = clone_nbuf_fn(head_msdu); + + prev_buf = mpdu_buf; + + frag_list_sum_len = 0; + is_first_frag = 1; + msdu_len = adf_nbuf_len(mpdu_buf); + + /* Drop the zero-length msdu */ + if (!msdu_len) { + goto mpdu_stitch_fail; + } + msdu_orig = adf_nbuf_next(head_msdu); + + while (msdu_orig) { + + /* TODO: intra AMSDU padding - do we need it ??? */ + msdu = clone_nbuf_fn(msdu_orig); + if (!msdu) { + goto mpdu_stitch_fail; + } + + if (is_first_frag) { + is_first_frag = 0; + head_frag_list_cloned = msdu; + } + + msdu_len = adf_nbuf_len(msdu); + /* Drop the zero-length msdu */ + if (!msdu_len) { + goto mpdu_stitch_fail; + } + + frag_list_sum_len += msdu_len; + + /* Maintain the linking of the cloned MSDUS */ + adf_nbuf_set_next_ext(prev_buf, msdu); + + /* Move to the next */ + prev_buf = msdu; + msdu_orig = adf_nbuf_next(msdu_orig); + } + + /* The last msdu length need be larger than HTT_FCS_LEN */ + if (msdu_len < HTT_FCS_LEN) { + goto mpdu_stitch_fail; + } + + adf_nbuf_trim_tail(prev_buf, HTT_FCS_LEN); + + /* If there were more fragments to this RAW frame */ + if (head_frag_list_cloned) { + adf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned, + frag_list_sum_len); + } + + goto mpdu_stitch_done; + } + + /* Decap mode: + * Calculate the amount of header in decapped packet to knock off based + * on the decap type and the corresponding number of raw bytes to copy + * status header + */ + + hdr_desc = &rx_desc->rx_hdr_status[0]; + + /* Base size */ + wifi_hdr_len = sizeof(struct ieee80211_frame); + wh = (struct ieee80211_frame*)hdr_desc; + + dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; + if (dir == IEEE80211_FC1_DIR_DSTODS) { + wifi_hdr_len += 6; + } + + is_amsdu = 0; + if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + qos = (struct ieee80211_qoscntl*) + (hdr_desc + wifi_hdr_len); + wifi_hdr_len += 2; + + is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU); + } + + /* TODO: Any security headers associated with MPDU */ + sec_hdr_len = 0; + + /* MSDU related stuff LLC - AMSDU subframe header etc */ + msdu_llc_len = is_amsdu ? (14 + 8) : 8; + + mpdu_buf_len = wifi_hdr_len + sec_hdr_len + msdu_llc_len; + + /* "Decap" header to remove from MSDU buffer */ + decap_hdr_pull_bytes = 14; + + /* Allocate a new nbuf for holding the 802.11 header retrieved from the + * status of the now decapped first msdu. Leave enough headroom for + * accomodating any radio-tap /prism like PHY header + */ +#define HTT_MAX_MONITOR_HEADER (512) + mpdu_buf = adf_nbuf_alloc(pdev->osdev, + HTT_MAX_MONITOR_HEADER + mpdu_buf_len, + HTT_MAX_MONITOR_HEADER, 4, FALSE); + + if (!mpdu_buf) { + goto mpdu_stitch_fail; + } + + /* Copy the MPDU related header and enc headers into the first buffer + * - Note that there can be a 2 byte pad between heaader and enc header + */ + + prev_buf = mpdu_buf; + dest = adf_nbuf_put_tail(prev_buf, wifi_hdr_len); + if (!dest) { + goto mpdu_stitch_fail; + } + adf_os_mem_copy(dest, hdr_desc, wifi_hdr_len); + hdr_desc += wifi_hdr_len; + + /* NOTE - This padding is present only in the RAW header status - not + * when the MSDU data payload is in RAW format. + */ + /* Skip the "IV pad" */ + if (wifi_hdr_len & 0x3) { + hdr_desc += 2; + } + +#if 0 + dest = adf_nbuf_put_tail(prev_buf, sec_hdr_len); + adf_os_mem_copy(dest, hdr_desc, sec_hdr_len); + hdr_desc += sec_hdr_len; +#endif + + /* The first LLC len is copied into the MPDU buffer */ + frag_list_sum_len = 0; + frag_list_sum_len -= msdu_llc_len; + + msdu_orig = head_msdu; + is_first_frag = 1; + amsdu_pad = 0; + + while (msdu_orig) { + + /* TODO: intra AMSDU padding - do we need it ??? */ + + msdu = clone_nbuf_fn(msdu_orig); + if (!msdu) { + goto mpdu_stitch_fail; + } + + if (is_first_frag) { + is_first_frag = 0; + head_frag_list_cloned = msdu; + } else { + + /* Maintain the linking of the cloned MSDUS */ + adf_nbuf_set_next_ext(prev_buf, msdu); + + /* Reload the hdr ptr only on non-first MSDUs */ + rx_desc = htt_rx_desc(msdu_orig); + hdr_desc = &rx_desc->rx_hdr_status[0]; + + } + + /* Copy this buffers MSDU related status into the prev buffer */ + dest = adf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad); + dest += amsdu_pad; + adf_os_mem_copy(dest, hdr_desc, msdu_llc_len); + + + /* Push the MSDU buffer beyond the decap header */ + adf_nbuf_pull_head(msdu, decap_hdr_pull_bytes); + frag_list_sum_len += msdu_llc_len + adf_nbuf_len(msdu) + amsdu_pad; + + /* Set up intra-AMSDU pad to be added to start of next buffer - + * AMSDU pad is 4 byte pad on AMSDU subframe */ + amsdu_pad = (msdu_llc_len + adf_nbuf_len(msdu)) & 0x3; + amsdu_pad = amsdu_pad ? ( 4 - amsdu_pad) : 0; + + /* TODO FIXME How do we handle MSDUs that have fraglist - Should + * probably iterate all the frags cloning them along the way and + * and also updating the prev_buf pointer + */ + + /* Move to the next */ + prev_buf = msdu; + msdu_orig = adf_nbuf_next(msdu_orig); + + } + +#if 0 + /* Add in the trailer section - encryption trailer + FCS */ + adf_nbuf_put_tail(prev_buf, HTT_FCS_LEN); + frag_list_sum_len += HTT_FCS_LEN; +#endif + + /* TODO: Convert this to suitable adf routines */ + adf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned, + frag_list_sum_len); + +mpdu_stitch_done: + /* Check if this buffer contains the PPDU end status for TSF */ + if (rx_desc->attention.last_mpdu) { + rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp; + } + + /* All the nbufs have been linked into the ext list and then unlink the nbuf list */ + if (clone_not_reqd) { + msdu = head_msdu; + while (msdu) { + msdu_orig = msdu; + msdu = adf_nbuf_next(msdu); + adf_nbuf_set_next(msdu_orig, NULL); + } + } + + return (mpdu_buf); + + +mpdu_stitch_fail: + /* Free these alloced buffers and the orig buffers in non-clone case */ + if (!clone_not_reqd) { + /* Free the head buffer */ + if (mpdu_buf) { + adf_nbuf_free(mpdu_buf); + } + + /* Free the partial list */ + while (head_frag_list_cloned) { + msdu = head_frag_list_cloned; + head_frag_list_cloned = adf_nbuf_next_ext(head_frag_list_cloned); + adf_nbuf_free(msdu); + } + } else { + /* Free the alloced head buffer */ + if (decap_format != HW_RX_DECAP_FORMAT_RAW) { + if (mpdu_buf) { + adf_nbuf_free(mpdu_buf); + } + } + + /* Free the orig buffers */ + msdu = head_msdu; + while (msdu) { + msdu_orig = msdu; + msdu = adf_nbuf_next(msdu); + adf_nbuf_free(msdu_orig); + } + } + + return NULL; +} + +int16_t +htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc) +{ + /* + * Currently the RSSI is provided only as a field in the + * HTT_T2H_RX_IND message, rather than in each rx descriptor. + */ + return HTT_RSSI_INVALID; +} + + +/* + * htt_rx_amsdu_pop - + * global function pointer that is programmed during attach to point + * to either htt_rx_amsdu_pop_ll or htt_rx_amsdu_pop_hl or + * htt_rx_amsdu_rx_in_order_pop_ll. + */ +int (*htt_rx_amsdu_pop)( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu); + +/* + * htt_rx_frag_pop - + * global function pointer that is programmed during attach to point + * to either htt_rx_amsdu_pop_ll or htt_rx_frag_pop_hl. + */ +int (*htt_rx_frag_pop)( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu); + +int +(*htt_rx_offload_msdu_pop)( + htt_pdev_handle pdev, + adf_nbuf_t offload_deliver_msg, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf); + +void *(*htt_rx_mpdu_desc_list_next)( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg); + +u_int16_t (*htt_rx_mpdu_desc_seq_num)( + htt_pdev_handle pdev, void *mpdu_desc); + +void (*htt_rx_mpdu_desc_pn)( + htt_pdev_handle pdev, + void *mpdu_desc, + union htt_rx_pn_t *pn, + int pn_len_bits); + +a_bool_t (*htt_rx_msdu_desc_completes_mpdu)( + htt_pdev_handle pdev, void *msdu_desc); + +a_bool_t (*htt_rx_msdu_first_msdu_flag)( + htt_pdev_handle pdev, void *msdu_desc); + +int (*htt_rx_msdu_has_wlan_mcast_flag)( + htt_pdev_handle pdev, void *msdu_desc); + +a_bool_t (*htt_rx_msdu_is_wlan_mcast)( + htt_pdev_handle pdev, void *msdu_desc); + +int (*htt_rx_msdu_is_frag)( + htt_pdev_handle pdev, void *msdu_desc); + +void *(*htt_rx_msdu_desc_retrieve)( + htt_pdev_handle pdev, adf_nbuf_t msdu); + +a_bool_t (*htt_rx_mpdu_is_encrypted)( + htt_pdev_handle pdev, + void *mpdu_desc); + +a_bool_t (*htt_rx_msdu_desc_key_id)( + htt_pdev_handle pdev, + void *mpdu_desc, u_int8_t *key_id); + +void * +htt_rx_mpdu_desc_list_next_ll(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg) +{ + int idx = pdev->rx_ring.sw_rd_idx.msdu_desc; + adf_nbuf_t netbuf = pdev->rx_ring.buf.netbufs_ring[idx]; + pdev->rx_ring.sw_rd_idx.msdu_desc = pdev->rx_ring.sw_rd_idx.msdu_payld; + return (void *) htt_rx_desc(netbuf); +} + +void * +htt_rx_in_ord_mpdu_desc_list_next_ll(htt_pdev_handle pdev, adf_nbuf_t netbuf) +{ + return (void*)htt_rx_desc(netbuf); +} + +void * +htt_rx_mpdu_desc_list_next_hl(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg) +{ + /* + * for HL, the returned value is not mpdu_desc, + * it's translated hl_rx_desc just after the hl_ind_msg + */ + void *mpdu_desc = (void *) adf_nbuf_data(rx_ind_msg); + + /* for HL AMSDU, we can't point to payload now, because + * hl rx desc is not fixed, we can't retrive the desc + * by minus rx_desc_size when release. keep point to hl rx desc + * now. + */ +#if 0 + adf_nbuf_pull_head(rx_ind_msg, pdev->rx_desc_size_hl); +#endif + + return mpdu_desc; +} + +void * +htt_rx_msdu_desc_retrieve_ll(htt_pdev_handle pdev, adf_nbuf_t msdu) +{ + return htt_rx_desc(msdu); +} + +void * +htt_rx_msdu_desc_retrieve_hl(htt_pdev_handle pdev, adf_nbuf_t msdu) +{ + /* currently for HL AMSDU, we don't point to payload. + * we shift to payload in ol_rx_deliver later + */ + return adf_nbuf_data(msdu); +} + +a_bool_t htt_rx_mpdu_is_encrypted_ll(htt_pdev_handle pdev, void *mpdu_desc) +{ + struct htt_host_rx_desc_base *rx_desc = (struct htt_host_rx_desc_base *) mpdu_desc; + + return (((*((u_int32_t *) &rx_desc->mpdu_start)) & + RX_MPDU_START_0_ENCRYPTED_MASK) >> + RX_MPDU_START_0_ENCRYPTED_LSB) ? A_TRUE : A_FALSE; +} + +a_bool_t htt_rx_mpdu_is_encrypted_hl(htt_pdev_handle pdev, void *mpdu_desc) +{ + if (htt_rx_msdu_first_msdu_flag_hl(pdev, mpdu_desc) == A_TRUE) { + /* Fix Me: only for little endian */ + struct hl_htt_rx_desc_base *rx_desc = + (struct hl_htt_rx_desc_base *) mpdu_desc; + + return HTT_WORD_GET(*(u_int32_t*)rx_desc, HTT_HL_RX_DESC_MPDU_ENC); + }else { + /* not first msdu, no encrypt info for hl */ + adf_os_print( + "Error: get encrypted from a not-first msdu.\n"); + adf_os_assert(0); + return -1; + } +} + +a_bool_t +htt_rx_msdu_desc_key_id_ll(htt_pdev_handle pdev, void *mpdu_desc, + u_int8_t *key_id) +{ + struct htt_host_rx_desc_base *rx_desc = (struct htt_host_rx_desc_base *) + mpdu_desc; + + if (!htt_rx_msdu_first_msdu_flag_ll(pdev, mpdu_desc)) + return A_FALSE; + + *key_id = ((*(((u_int32_t *) &rx_desc->msdu_end) + 1)) & + (RX_MSDU_END_1_KEY_ID_OCT_MASK >> RX_MSDU_END_1_KEY_ID_OCT_LSB)); + + return A_TRUE; +} + +a_bool_t +htt_rx_msdu_desc_key_id_hl(htt_pdev_handle htt_pdev, void *mpdu_desc, u_int8_t *key_id) +{ + if (htt_rx_msdu_first_msdu_flag_hl(htt_pdev, mpdu_desc) == A_TRUE) { + /* Fix Me: only for little endian */ + struct hl_htt_rx_desc_base *rx_desc = + (struct hl_htt_rx_desc_base *) mpdu_desc; + + *key_id = rx_desc->key_id_oct; + return A_TRUE; + } + + return A_FALSE; +} + +void +htt_rx_desc_frame_free( + htt_pdev_handle htt_pdev, + adf_nbuf_t msdu) +{ + adf_nbuf_free(msdu); +} + +void +htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, adf_nbuf_t msdu) +{ + /* + * The rx descriptor is in the same buffer as the rx MSDU payload, + * and does not need to be freed separately. + */ +} + +void +htt_rx_msdu_buff_replenish(htt_pdev_handle pdev) +{ + if (adf_os_atomic_dec_and_test(&pdev->rx_ring.refill_ref_cnt)) { + if (!pdev->cfg.is_high_latency) { + int num_to_fill; + num_to_fill = pdev->rx_ring.fill_level - pdev->rx_ring.fill_cnt; + htt_rx_ring_fill_n(pdev, num_to_fill /* okay if <= 0 */); + } + } + adf_os_atomic_inc(&pdev->rx_ring.refill_ref_cnt); +} + +#define AR600P_ASSEMBLE_HW_RATECODE(_rate, _nss, _pream) \ + (((_pream) << 6) | ((_nss) << 4) | (_rate)) + +enum AR600P_HW_RATECODE_PREAM_TYPE { + AR600P_HW_RATECODE_PREAM_OFDM, + AR600P_HW_RATECODE_PREAM_CCK, + AR600P_HW_RATECODE_PREAM_HT, + AR600P_HW_RATECODE_PREAM_VHT, +}; + +#if 0 +void htt_rx_get_vowext_stats(adf_nbuf_t msdu, struct vow_extstats *vowstats) +{ + u_int32_t *ppdu; + u_int8_t preamble_type; + u_int8_t rate = 0, nss=0, bw=0, sgi = 0, mcs = 0, rs_flags=0; + struct htt_host_rx_desc_base *rx_desc; + rx_desc = htt_rx_desc(msdu); + + ppdu = ((u_int32_t *)&rx_desc->ppdu_start); + preamble_type = (ppdu[5] & 0xff000000) >> 24; + switch(preamble_type) + { + /* HT */ + case 8: /* HT w/o TxBF */ + case 9:/* HT w/ TxBF */ + mcs = (u_int8_t)(ppdu[6] & 0x7f); + nss = mcs>>3; + mcs %= 8; + bw = (u_int8_t)((ppdu[6] >> 7) & 1); + sgi = (u_int8_t)((ppdu[6] >> 7) & 1); + rate = AR600P_ASSEMBLE_HW_RATECODE(mcs, nss, AR600P_HW_RATECODE_PREAM_HT); + if (bw) { + rs_flags |= HAL_RX_40; + } + if (sgi) { + rs_flags |= HAL_RX_GI; + } + break; + /* VHT */ + case 0x0c: /* VHT w/o TxBF */ + case 0x0d: /* VHT w/ TxBF */ + mcs = (u_int8_t)((ppdu[7] >> 4) & 0xf); + nss = (u_int8_t)((ppdu[6] >> 10) & 0x7); + bw = (u_int8_t)((ppdu[6] & 3)); + sgi = (u_int8_t)((ppdu[7]) & 1); + rate = AR600P_ASSEMBLE_HW_RATECODE(mcs, nss, AR600P_HW_RATECODE_PREAM_VHT); + break; + } + + vowstats->rx_bw = bw; /* band width 0 - 20 , 1 - 40 , 2 - 80 */ + vowstats->rx_sgi = sgi; /* 1 - short GI */ + vowstats->rx_nss= nss; /* Nss */ + vowstats->rx_mcs = mcs; + vowstats->rx_ratecode = rate; + vowstats->rx_rs_flags= rs_flags; /* rsflags */ + + vowstats->rx_rssi_ctl0 = (ppdu[0] & 0x000000ff); /* rssi ctl0 */ + vowstats->rx_rssi_ctl1 = (ppdu[1] & 0x000000ff); /* rssi ctl1 */ + vowstats->rx_rssi_ctl2 = (ppdu[2] & 0x000000ff); /* rssi ctl2 */ + vowstats->rx_rssi_ext0 = (ppdu[0] & 0x0000ff00) >> 8; /* rssi ext0 */ + vowstats->rx_rssi_ext1 = (ppdu[1] & 0x0000ff00) >> 8; /* rssi ext1 */ + vowstats->rx_rssi_ext2 = (ppdu[2] & 0x0000ff00) >> 8; /* rssi ext2 */ + vowstats->rx_rssi_comb = (ppdu[4] & 0x000000ff); /* rssi comb */ + + ppdu = ((u_int32_t *)&rx_desc->ppdu_end); + /* Time stamp */ + vowstats->rx_macTs = ppdu[16]; + + ppdu = ((u_int32_t *)&rx_desc->attention); + /* more data */ + vowstats->rx_moreaggr = (ppdu[0] & RX_ATTENTION_0_MORE_DATA_MASK); + + /* sequence number */ + ppdu = ((u_int32_t *)&rx_desc->mpdu_start); + vowstats->rx_seqno = (ppdu[0] & 0x0fff0000) >> 16; + +} + +#endif + +/*--- RX In Order Hash Code --------------------------------------------------*/ + +/* Number of buckets in the hash table */ +#define RX_NUM_HASH_BUCKETS 1024 /* This should always be a power of 2 */ +#define RX_NUM_HASH_BUCKETS_MASK (RX_NUM_HASH_BUCKETS - 1) + +/* Number of hash entries allocated per bucket */ +#define RX_ENTRIES_SIZE 10 + +#define RX_HASH_FUNCTION(a) (((a >> 14) ^ (a >> 4)) & RX_NUM_HASH_BUCKETS_MASK) + +#ifdef RX_HASH_DEBUG_LOG +#define RX_HASH_LOG(x) x +#else +#define RX_HASH_LOG(x) /* no-op */ +#endif + +/* Initializes the circular linked list */ +static inline void htt_list_init(htt_list_head * head) +{ + head->prev = head; + head->next = head; +} + +/* Adds entry to the end of the linked list */ +static inline void +htt_list_add_tail(htt_list_head * head, htt_list_node * node) +{ + head->prev->next = node; + node->prev = head->prev; + node->next = head; + head->prev = node; +} + +/* Removes the entry corresponding to the input node from the linked list */ +static inline void +htt_list_remove(htt_list_node * node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; +} + +/* Helper macro to iterate through the linked list */ +#define HTT_LIST_ITER_FWD(iter, head) for( iter=(head)->next; \ + (iter)!=(head); (iter)=(iter)->next ) \ + +#ifdef RX_HASH_DEBUG +/* Hash cookie related macros */ +#define HTT_RX_HASH_COOKIE 0xDEED + +#define HTT_RX_HASH_COOKIE_SET(hash_element)\ + hash_element->cookie = HTT_RX_HASH_COOKIE + +#define HTT_RX_HASH_COOKIE_CHECK(hash_element)\ + HTT_ASSERT_ALWAYS(hash_element->cookie == HTT_RX_HASH_COOKIE) + +/* Hash count related macros */ +#define HTT_RX_HASH_COUNT_INCR(hash_bucket)\ + hash_bucket.count++ + +#define HTT_RX_HASH_COUNT_DECR(hash_bucket)\ + hash_bucket.count-- + +#define HTT_RX_HASH_COUNT_RESET(hash_bucket) hash_bucket.count = 0 + +#define HTT_RX_HASH_COUNT_PRINT(hash_bucket)\ + RX_HASH_LOG(adf_os_print(" count %d\n", hash_bucket.count)) +#else /* RX_HASH_DEBUG */ +/* Hash cookie related macros */ +#define HTT_RX_HASH_COOKIE_SET(hash_element) /* no-op */ +#define HTT_RX_HASH_COOKIE_CHECK(hash_element) /* no-op */ +/* Hash count related macros */ +#define HTT_RX_HASH_COUNT_INCR(hash_bucket) /* no-op */ +#define HTT_RX_HASH_COUNT_DECR(hash_bucket) /* no-op */ +#define HTT_RX_HASH_COUNT_PRINT(hash_bucket) /* no-op */ +#define HTT_RX_HASH_COUNT_RESET(hash_bucket) /* no-op */ +#endif /* RX_HASH_DEBUG */ + + +/* Inserts the given "physical address - network buffer" pair into the + hash table for the given pdev. This function will do the following: + 1. Determine which bucket to insert the pair into + 2. First try to allocate the hash entry for this pair from the pre-allocated + entries list + 3. If there are no more entries in the pre-allocated entries list, allocate + the hash entry from the hash memory pool + Note: this function is not thread-safe + Returns 0 - success, 1 - failure */ +int +htt_rx_hash_list_insert(struct htt_pdev_t *pdev, u_int32_t paddr, + adf_nbuf_t netbuf) +{ + int i; + struct htt_rx_hash_entry * hash_element = NULL; + + i = RX_HASH_FUNCTION(paddr); + + /* Check if there are any entries in the pre-allocated free list */ + if( pdev->rx_ring.hash_table[i].freepool.next != + &pdev->rx_ring.hash_table[i].freepool) { + + hash_element = + (struct htt_rx_hash_entry *)((char *)pdev->rx_ring.hash_table[i] + .freepool.next - + pdev->rx_ring.listnode_offset); + if (adf_os_unlikely(NULL == hash_element)) { + HTT_ASSERT_ALWAYS(0); + return 1; + } + + htt_list_remove(pdev->rx_ring.hash_table[i].freepool.next); + } + else { + hash_element = adf_os_mem_alloc(pdev->osdev, + sizeof(struct htt_rx_hash_entry)); + if (adf_os_unlikely(NULL == hash_element)) { + HTT_ASSERT_ALWAYS(0); + return 1; + } + hash_element->fromlist = 0; + } + + hash_element->netbuf = netbuf; + hash_element->paddr = paddr; + HTT_RX_HASH_COOKIE_SET(hash_element); + + htt_list_add_tail(&pdev->rx_ring.hash_table[i].listhead, + &hash_element->listnode); + + RX_HASH_LOG(adf_os_print("rx hash: %s: paddr 0x%x netbuf %p bucket %d\n", + __FUNCTION__, paddr, netbuf,(int)i)); + + HTT_RX_HASH_COUNT_INCR(pdev->rx_ring.hash_table[i]); + HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]); + + return 0; +} + +/* Given a physical address this function will find the corresponding network + buffer from the hash table. + Note: this function is not thread-safe */ +adf_nbuf_t +htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, u_int32_t paddr) +{ + u_int32_t i; + htt_list_node * list_iter = NULL; + adf_nbuf_t netbuf = NULL; + struct htt_rx_hash_entry * hash_entry; + + i = RX_HASH_FUNCTION(paddr); + + HTT_LIST_ITER_FWD(list_iter, &pdev->rx_ring.hash_table[i].listhead) + { + hash_entry = (struct htt_rx_hash_entry *) + ((char *)list_iter - pdev->rx_ring.listnode_offset); + + HTT_RX_HASH_COOKIE_CHECK(hash_entry); + + if (hash_entry->paddr == paddr) { + /* Found the entry corresponding to paddr */ + netbuf = hash_entry->netbuf; + htt_list_remove(&hash_entry->listnode); + HTT_RX_HASH_COUNT_DECR(pdev->rx_ring.hash_table[i]); + /* if the rx entry is from the pre-allocated list, return it */ + if (hash_entry->fromlist) { + htt_list_add_tail(&pdev->rx_ring.hash_table[i].freepool, + &hash_entry->listnode); + } + else { + adf_os_mem_free(hash_entry); + } + break; + } + } + + RX_HASH_LOG(adf_os_print("rx hash: %s: paddr 0x%x, netbuf %p, bucket %d\n", + __FUNCTION__, paddr, netbuf,(int)i)); + HTT_RX_HASH_COUNT_PRINT(pdev->rx_ring.hash_table[i]); + + if (netbuf == NULL) { + adf_os_print("rx hash: %s: no entry found for 0x%x!!!\n", + __FUNCTION__, paddr); + HTT_ASSERT_ALWAYS(0); + } + + return netbuf; +} + +/* Initialization function of the rx buffer hash table. This function will + allocate a hash table of a certain pre-determined size and initialize all + the elements */ +int +htt_rx_hash_init(struct htt_pdev_t *pdev) +{ + int i,j; + + HTT_ASSERT2(IS_PWR2(RX_NUM_HASH_BUCKETS)); + + pdev->rx_ring.hash_table = adf_os_mem_alloc( + pdev->osdev, RX_NUM_HASH_BUCKETS * sizeof(struct htt_rx_hash_bucket)); + + if ( NULL == pdev->rx_ring.hash_table) { + adf_os_print("rx hash table allocation failed!\n"); + return 1; + } + + for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) { + HTT_RX_HASH_COUNT_RESET(pdev->rx_ring.hash_table[i]); + + /* initialize the hash table buckets */ + htt_list_init(&pdev->rx_ring.hash_table[i].listhead); + + /* initialize the hash table free pool per bucket */ + htt_list_init(&pdev->rx_ring.hash_table[i].freepool); + + /* pre-allocate a pool of entries for this bucket */ + pdev->rx_ring.hash_table[i].entries = adf_os_mem_alloc( + pdev->osdev, RX_ENTRIES_SIZE * sizeof(struct htt_rx_hash_entry)); + + if (NULL == pdev->rx_ring.hash_table[i].entries) { + adf_os_print("rx hash entries allocation for bucket %d failed!\n", + (int)i); + while (i) { + i--; + adf_os_mem_free(pdev->rx_ring.hash_table[i].entries); + } + adf_os_mem_free(pdev->rx_ring.hash_table); + pdev->rx_ring.hash_table = NULL; + return 1; + } + + /* initialize the free list with pre-allocated entries */ + for (j = 0; j < RX_ENTRIES_SIZE; j++) { + pdev->rx_ring.hash_table[i].entries[j].fromlist = 1; + htt_list_add_tail(&pdev->rx_ring.hash_table[i].freepool, + &pdev->rx_ring.hash_table[i].entries[j].listnode); + } + } + + pdev->rx_ring.listnode_offset = + adf_os_offsetof(struct htt_rx_hash_entry, listnode); + + return 0; +} + +/* De -initialization function of the rx buffer hash table. This function will + free up the hash table which includes freeing all the pending rx buffers*/ +void +htt_rx_hash_deinit(struct htt_pdev_t *pdev) +{ + + u_int32_t i; + struct htt_rx_hash_entry * hash_entry; + htt_list_node * list_iter = NULL; + + if (NULL == pdev->rx_ring.hash_table) { + return; + } + + for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) { + /* Free the hash entries in hash bucket i */ + list_iter = pdev->rx_ring.hash_table[i].listhead.next; + while (list_iter != &pdev->rx_ring.hash_table[i].listhead) { + hash_entry = + (struct htt_rx_hash_entry *)((char *)list_iter - + pdev->rx_ring.listnode_offset); + if (hash_entry->netbuf) { + adf_nbuf_free(hash_entry->netbuf); + hash_entry->paddr = 0; + } + list_iter = list_iter->next; + + if (!hash_entry->fromlist) { + adf_os_mem_free(hash_entry); + } + } + + adf_os_mem_free(pdev->rx_ring.hash_table[i].entries); + + } + if (NULL != pdev->rx_ring.hash_table) { + adf_os_mem_free(pdev->rx_ring.hash_table); + pdev->rx_ring.hash_table = NULL; + } +} + +void +htt_rx_hash_dump_table(struct htt_pdev_t *pdev) +{ + u_int32_t i; + struct htt_rx_hash_entry * hash_entry; + htt_list_node * list_iter = NULL; + + for (i = 0; i < RX_NUM_HASH_BUCKETS; i++) { + HTT_LIST_ITER_FWD(list_iter, &pdev->rx_ring.hash_table[i].listhead) + { + hash_entry = + (struct htt_rx_hash_entry *)((char *)list_iter - + pdev->rx_ring.listnode_offset); + adf_os_print("hash_table[%d]: netbuf %p paddr 0x%x\n", + i, hash_entry->netbuf, hash_entry->paddr); + } + } +} + +/*--- RX In Order Hash Code --------------------------------------------------*/ + +/* move the function to the end of file + * to omit ll/hl pre-declaration + */ +int +htt_rx_attach(struct htt_pdev_t *pdev) +{ + adf_os_dma_addr_t paddr; + if (!pdev->cfg.is_high_latency) { + pdev->rx_ring.size = htt_rx_ring_size(pdev); + HTT_ASSERT2(IS_PWR2(pdev->rx_ring.size)); + pdev->rx_ring.size_mask = pdev->rx_ring.size - 1; + + /* + * Set the initial value for the level to which the rx ring should + * be filled, based on the max throughput and the worst likely + * latency for the host to fill the rx ring with new buffers. + * In theory, this fill level can be dynamically adjusted from + * the initial value set here, to reflect the actual host latency + * rather than a conservative assumption about the host latency. + */ + pdev->rx_ring.fill_level = htt_rx_ring_fill_level(pdev); + + if (pdev->cfg.is_full_reorder_offload) { + if (htt_rx_hash_init(pdev)) { + goto fail1; + } + + /* allocate the target index */ + pdev->rx_ring.target_idx.vaddr = adf_os_mem_alloc_consistent( + pdev->osdev, + sizeof(u_int32_t), + &paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.target_idx), memctx)); + if (!pdev->rx_ring.target_idx.vaddr) { + goto fail1; + } + pdev->rx_ring.target_idx.paddr = paddr; + *pdev->rx_ring.target_idx.vaddr = 0; + } else { + pdev->rx_ring.buf.netbufs_ring = adf_os_mem_alloc( + pdev->osdev, pdev->rx_ring.size * sizeof(adf_nbuf_t)); + if (!pdev->rx_ring.buf.netbufs_ring) { + goto fail1; + } + + pdev->rx_ring.sw_rd_idx.msdu_payld = 0; + pdev->rx_ring.sw_rd_idx.msdu_desc = 0; + } + + pdev->rx_ring.buf.paddrs_ring = adf_os_mem_alloc_consistent( + pdev->osdev, + pdev->rx_ring.size * sizeof(u_int32_t), + &paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.buf), memctx)); + if (!pdev->rx_ring.buf.paddrs_ring) { + goto fail2; + } + pdev->rx_ring.base_paddr = paddr; + pdev->rx_ring.alloc_idx.vaddr = adf_os_mem_alloc_consistent( + pdev->osdev, + sizeof(u_int32_t), + &paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.alloc_idx), memctx)); + if (!pdev->rx_ring.alloc_idx.vaddr) { + goto fail3; + } + pdev->rx_ring.alloc_idx.paddr = paddr; + *pdev->rx_ring.alloc_idx.vaddr = 0; + + /* + * Initialize the Rx refill reference counter to be one so that + * only one thread is allowed to refill the Rx ring. + */ + adf_os_atomic_init(&pdev->rx_ring.refill_ref_cnt); + adf_os_atomic_inc(&pdev->rx_ring.refill_ref_cnt); + + /* Initialize the Rx refill retry timer */ + adf_os_timer_init(pdev->osdev, &pdev->rx_ring.refill_retry_timer, + htt_rx_ring_refill_retry, (void *)pdev, + ADF_DEFERRABLE_TIMER); + + pdev->rx_ring.fill_cnt = 0; +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_ring_idx = 0; + pdev->rx_ring.dbg_refill_cnt = 0; + pdev->rx_ring.dbg_sync_success = 0; +#endif +#ifdef HTT_RX_RESTORE + pdev->rx_ring.rx_reset = 0; + pdev->rx_ring.htt_rx_restore = 0; +#endif + htt_rx_ring_fill_n(pdev, pdev->rx_ring.fill_level); + + if (pdev->cfg.is_full_reorder_offload) { + adf_os_print("HTT: full reorder offload enabled\n"); + htt_rx_amsdu_pop = htt_rx_amsdu_rx_in_order_pop_ll; + htt_rx_frag_pop = htt_rx_amsdu_rx_in_order_pop_ll; + htt_rx_mpdu_desc_list_next = htt_rx_in_ord_mpdu_desc_list_next_ll; + } else { + htt_rx_amsdu_pop = htt_rx_amsdu_pop_ll; + htt_rx_frag_pop = htt_rx_amsdu_pop_ll; + htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_ll; + } + htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll; + htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll; + htt_rx_mpdu_desc_pn = htt_rx_mpdu_desc_pn_ll; + htt_rx_msdu_desc_completes_mpdu = htt_rx_msdu_desc_completes_mpdu_ll; + htt_rx_msdu_first_msdu_flag = htt_rx_msdu_first_msdu_flag_ll; + htt_rx_msdu_has_wlan_mcast_flag = htt_rx_msdu_has_wlan_mcast_flag_ll; + htt_rx_msdu_is_wlan_mcast = htt_rx_msdu_is_wlan_mcast_ll; + htt_rx_msdu_is_frag = htt_rx_msdu_is_frag_ll; + htt_rx_msdu_desc_retrieve = htt_rx_msdu_desc_retrieve_ll; + htt_rx_mpdu_is_encrypted = htt_rx_mpdu_is_encrypted_ll; + htt_rx_msdu_desc_key_id = htt_rx_msdu_desc_key_id_ll; + } else { + pdev->rx_ring.size = HTT_RX_RING_SIZE_MIN; + HTT_ASSERT2(IS_PWR2(pdev->rx_ring.size)); + pdev->rx_ring.size_mask = pdev->rx_ring.size - 1; + + /* host can force ring base address if it wish to do so */ + pdev->rx_ring.base_paddr = 0; + htt_rx_amsdu_pop = htt_rx_amsdu_pop_hl; + htt_rx_frag_pop = htt_rx_frag_pop_hl; + htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_hl; + htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_hl; + htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_hl; + htt_rx_mpdu_desc_pn = htt_rx_mpdu_desc_pn_hl; + htt_rx_msdu_desc_completes_mpdu = htt_rx_msdu_desc_completes_mpdu_hl; + htt_rx_msdu_first_msdu_flag = htt_rx_msdu_first_msdu_flag_hl; + htt_rx_msdu_has_wlan_mcast_flag = htt_rx_msdu_has_wlan_mcast_flag_hl; + htt_rx_msdu_is_wlan_mcast = htt_rx_msdu_is_wlan_mcast_hl; + htt_rx_msdu_is_frag = htt_rx_msdu_is_frag_hl; + htt_rx_msdu_desc_retrieve = htt_rx_msdu_desc_retrieve_hl; + htt_rx_mpdu_is_encrypted = htt_rx_mpdu_is_encrypted_hl; + htt_rx_msdu_desc_key_id = htt_rx_msdu_desc_key_id_hl; + + /* + * HL case, the rx descriptor can be different sizes for + * different sub-types of RX_IND messages, e.g. for the + * initial vs. interior vs. final MSDUs within a PPDU. + * The size of each RX_IND message's rx desc is read from + * a field within the RX_IND message itself. + * In the meantime, until the rx_desc_size_hl variable is + * set to its real value based on the RX_IND message, + * initialize it to a reasonable value (zero). + */ + pdev->rx_desc_size_hl = 0; + } + return 0; /* success */ + +fail3: + adf_os_mem_free_consistent( + pdev->osdev, + pdev->rx_ring.size * sizeof(u_int32_t), + pdev->rx_ring.buf.paddrs_ring, + pdev->rx_ring.base_paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.buf), memctx)); + +fail2: + if (pdev->cfg.is_full_reorder_offload) { + adf_os_mem_free_consistent( + pdev->osdev, + sizeof(u_int32_t), + pdev->rx_ring.target_idx.vaddr, + pdev->rx_ring.target_idx.paddr, + adf_os_get_dma_mem_context((&pdev->rx_ring.target_idx), memctx)); + htt_rx_hash_deinit(pdev); + } else { + adf_os_mem_free(pdev->rx_ring.buf.netbufs_ring); + } + +fail1: + return 1; /* failure */ +} + +#ifdef IPA_UC_OFFLOAD +int htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev, + unsigned int rx_ind_ring_elements) +{ + /* Allocate RX indication ring */ + /* RX IND ring element + * 4bytes: pointer + * 2bytes: VDEV ID + * 2bytes: length */ + pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr = + adf_os_mem_alloc_consistent(pdev->osdev, + rx_ind_ring_elements * sizeof(struct ipa_uc_rx_ring_elem_t), + &pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_rx_rsc.rx_ind_ring_base), memctx)); + if (!pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) { + adf_os_print("%s: RX IND RING alloc fail", __func__); + return -1; + } + + /* RX indication ring size, by bytes */ + pdev->ipa_uc_rx_rsc.rx_ind_ring_size = rx_ind_ring_elements * + sizeof(struct ipa_uc_rx_ring_elem_t); + + /* Allocate RX process done index */ + pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr = + adf_os_mem_alloc_consistent(pdev->osdev, + 4, + &pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx), memctx)); + if (!pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) { + adf_os_print("%s: RX PROC DONE IND alloc fail", __func__); + adf_os_mem_free_consistent(pdev->osdev, + pdev->ipa_uc_rx_rsc.rx_ind_ring_size, + pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr, + pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_rx_rsc.rx_ind_ring_base), memctx)); + return -2; + } + + return 0; +} + +int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev) +{ + if (pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) { + adf_os_mem_free_consistent(pdev->osdev, + pdev->ipa_uc_rx_rsc.rx_ind_ring_size, + pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr, + pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_rx_rsc.rx_ind_ring_base), memctx)); + } + + if (pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) { + adf_os_mem_free_consistent(pdev->osdev, + 4, + pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr, + pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx), memctx)); + } + + return 0; +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c new file mode 100644 index 0000000000000..aebc2cb7b233a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -0,0 +1,743 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_t2h.c + * @brief Provide functions to process target->host HTT messages. + * @details + * This file contains functions related to target->host HTT messages. + * There are two categories of functions: + * 1. A function that receives a HTT message from HTC, and dispatches it + * based on the HTT message type. + * 2. functions that provide the info elements from specific HTT messages. + */ + +#include /* HTC_PACKET */ +#include /* HTT_T2H_MSG_TYPE, etc. */ +#include /* adf_nbuf_t */ + +#include +#include +#include /* htt_tx_status */ + +#include /* HTT_TX_SCHED, etc. */ +#include +#include +#include +#include +/*--- target->host HTT message dispatch function ----------------------------*/ + +#ifndef DEBUG_CREDIT +#define DEBUG_CREDIT 0 +#endif + +static u_int8_t * +htt_t2h_mac_addr_deswizzle(u_int8_t *tgt_mac_addr, u_int8_t *buffer) +{ +#ifdef BIG_ENDIAN_HOST + /* + * The host endianness is opposite of the target endianness. + * To make u_int32_t elements come out correctly, the target->host + * upload has swizzled the bytes in each u_int32_t element of the + * message. + * For byte-array message fields like the MAC address, this + * upload swizzling puts the bytes in the wrong order, and needs + * to be undone. + */ + buffer[0] = tgt_mac_addr[3]; + buffer[1] = tgt_mac_addr[2]; + buffer[2] = tgt_mac_addr[1]; + buffer[3] = tgt_mac_addr[0]; + buffer[4] = tgt_mac_addr[7]; + buffer[5] = tgt_mac_addr[6]; + return buffer; +#else + /* + * The host endianness matches the target endianness - + * we can use the mac addr directly from the message buffer. + */ + return tgt_mac_addr; +#endif +} + +#if defined(CONFIG_HL_SUPPORT) +#define HTT_RX_FRAG_SET_LAST_MSDU(pdev, msg) /* no-op */ +#else +static void HTT_RX_FRAG_SET_LAST_MSDU( + struct htt_pdev_t *pdev, adf_nbuf_t msg) +{ + u_int32_t *msg_word; + unsigned num_msdu_bytes; + adf_nbuf_t msdu; + struct htt_host_rx_desc_base *rx_desc; + int start_idx; + u_int8_t *p_fw_msdu_rx_desc = 0; + + msg_word = (u_int32_t *) adf_nbuf_data(msg); + num_msdu_bytes = HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET(*(msg_word + + HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32)); + /* + * 1 word for the message header, + * 1 word to specify the number of MSDU bytes, + * 1 word for every 4 MSDU bytes (round up), + * 1 word for the MPDU range header + */ + pdev->rx_mpdu_range_offset_words = 3 + ((num_msdu_bytes + 3) >> 2); + pdev->rx_ind_msdu_byte_idx = 0; + + p_fw_msdu_rx_desc = ((u_int8_t *)(msg_word) + + HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET)); + + /* + * Fix for EV126710, in which BSOD occurs due to last_msdu bit + * not set while the next pointer is deliberately set to NULL + * before calling ol_rx_pn_check_base() + * + * For fragment frames, the HW may not have set the last_msdu bit + * in the rx descriptor, but the SW expects this flag to be set, + * since each fragment is in a separate MPDU. Thus, set the flag here, + * just in case the HW didn't. + */ + start_idx = pdev->rx_ring.sw_rd_idx.msdu_payld; + msdu = pdev->rx_ring.buf.netbufs_ring[start_idx]; + adf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE); + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_FROM_DEVICE); + rx_desc = htt_rx_desc(msdu); + *((u_int8_t *) &rx_desc->fw_desc.u.val) = *p_fw_msdu_rx_desc; + rx_desc->msdu_end.last_msdu = 1; + adf_nbuf_map(pdev->osdev, msdu, ADF_OS_DMA_FROM_DEVICE); +} +#endif /* CONFIG_HL_SUPPORT */ + +/* Target to host Msg/event handler for low priority messages*/ +void +htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) +{ + struct htt_pdev_t *pdev = (struct htt_pdev_t *) context; + u_int32_t *msg_word; + enum htt_t2h_msg_type msg_type; + + msg_word = (u_int32_t *) adf_nbuf_data(htt_t2h_msg); + msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); + switch (msg_type) { + case HTT_T2H_MSG_TYPE_VERSION_CONF: + { + pdev->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word); + pdev->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word); + adf_os_print("target uses HTT version %d.%d; host uses %d.%d\n", + pdev->tgt_ver.major, pdev->tgt_ver.minor, + HTT_CURRENT_VERSION_MAJOR, HTT_CURRENT_VERSION_MINOR); + if (pdev->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR) { + adf_os_print("*** Incompatible host/target HTT versions!\n"); + } + /* abort if the target is incompatible with the host */ + adf_os_assert(pdev->tgt_ver.major == HTT_CURRENT_VERSION_MAJOR); + if (pdev->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) { + adf_os_print( + "*** Warning: host/target HTT versions are different, " + "though compatible!\n"); + } + break; + } + case HTT_T2H_MSG_TYPE_RX_FLUSH: + { + u_int16_t peer_id; + u_int8_t tid; + int seq_num_start, seq_num_end; + enum htt_rx_flush_action action; + + peer_id = HTT_RX_FLUSH_PEER_ID_GET(*msg_word); + tid = HTT_RX_FLUSH_TID_GET(*msg_word); + seq_num_start = HTT_RX_FLUSH_SEQ_NUM_START_GET(*(msg_word+1)); + seq_num_end = HTT_RX_FLUSH_SEQ_NUM_END_GET(*(msg_word+1)); + action = + HTT_RX_FLUSH_MPDU_STATUS_GET(*(msg_word+1)) == 1 ? + htt_rx_flush_release : htt_rx_flush_discard; + ol_rx_flush_handler( + pdev->txrx_pdev, + peer_id, tid, + seq_num_start, + seq_num_end, + action); + break; + } + case HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND: + { + int msdu_cnt; + msdu_cnt = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word); + ol_rx_offload_deliver_ind_handler( + pdev->txrx_pdev, + htt_t2h_msg, + msdu_cnt); + break; + } + case HTT_T2H_MSG_TYPE_RX_FRAG_IND: + { + u_int16_t peer_id; + u_int8_t tid; + + peer_id = HTT_RX_FRAG_IND_PEER_ID_GET(*msg_word); + tid = HTT_RX_FRAG_IND_EXT_TID_GET(*msg_word); + HTT_RX_FRAG_SET_LAST_MSDU(pdev, htt_t2h_msg); + + ol_rx_frag_indication_handler( + pdev->txrx_pdev, + htt_t2h_msg, + peer_id, + tid); + break; + } + case HTT_T2H_MSG_TYPE_RX_ADDBA: + { + u_int16_t peer_id; + u_int8_t tid; + u_int8_t win_sz; + u_int16_t start_seq_num; + + /* + * FOR NOW, the host doesn't need to know the initial + * sequence number for rx aggregation. + * Thus, any value will do - specify 0. + */ + start_seq_num = 0; + peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word); + tid = HTT_RX_ADDBA_TID_GET(*msg_word); + win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word); + ol_rx_addba_handler( + pdev->txrx_pdev, peer_id, tid, win_sz, start_seq_num, + 0 /* success */); + break; + } + case HTT_T2H_MSG_TYPE_RX_DELBA: + { + u_int16_t peer_id; + u_int8_t tid; + + peer_id = HTT_RX_DELBA_PEER_ID_GET(*msg_word); + tid = HTT_RX_DELBA_TID_GET(*msg_word); + ol_rx_delba_handler(pdev->txrx_pdev, peer_id, tid); + break; + } + case HTT_T2H_MSG_TYPE_PEER_MAP: + { + u_int8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN]; + u_int8_t *peer_mac_addr; + u_int16_t peer_id; + u_int8_t vdev_id; + + peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word); + vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word); + peer_mac_addr = htt_t2h_mac_addr_deswizzle( + (u_int8_t *) (msg_word+1), &mac_addr_deswizzle_buf[0]); + + ol_rx_peer_map_handler( + pdev->txrx_pdev, peer_id, vdev_id, peer_mac_addr, 1/*can tx*/); + break; + } + case HTT_T2H_MSG_TYPE_PEER_UNMAP: + { + u_int16_t peer_id; + peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word); + + ol_rx_peer_unmap_handler(pdev->txrx_pdev, peer_id); + break; + } + case HTT_T2H_MSG_TYPE_SEC_IND: + { + u_int16_t peer_id; + enum htt_sec_type sec_type; + int is_unicast; + + peer_id = HTT_SEC_IND_PEER_ID_GET(*msg_word); + sec_type = HTT_SEC_IND_SEC_TYPE_GET(*msg_word); + is_unicast = HTT_SEC_IND_UNICAST_GET(*msg_word); + msg_word++; /* point to the first part of the Michael key */ + ol_rx_sec_ind_handler( + pdev->txrx_pdev, peer_id, sec_type, is_unicast, msg_word, msg_word+2); + break; + } + case HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND: + { + struct htt_mgmt_tx_compl_ind *compl_msg; + + compl_msg = (struct htt_mgmt_tx_compl_ind *)(msg_word + 1); + if (pdev->cfg.is_high_latency) { + ol_tx_target_credit_update(pdev->txrx_pdev, 1); + } + ol_tx_single_completion_handler( + pdev->txrx_pdev, compl_msg->status, compl_msg->desc_id); + HTT_TX_SCHED(pdev); + break; + } +#if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF + case HTT_T2H_MSG_TYPE_STATS_CONF: + { + u_int64_t cookie; + u_int8_t *stats_info_list; + + cookie = *(msg_word + 1); + cookie |= ((u_int64_t) (*(msg_word + 2))) << 32; + + stats_info_list = (u_int8_t *) (msg_word + 3); + ol_txrx_fw_stats_handler(pdev->txrx_pdev, cookie, stats_info_list); + break; + } +#endif +#ifndef REMOVE_PKT_LOG + case HTT_T2H_MSG_TYPE_PKTLOG: + { + u_int32_t *pl_hdr; + u_int32_t log_type; + pl_hdr = (msg_word + 1); + log_type = (*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + if (log_type == PKTLOG_TYPE_TX_CTRL || + (log_type) == PKTLOG_TYPE_TX_STAT || + (log_type) == PKTLOG_TYPE_TX_MSDU_ID || + (log_type) == PKTLOG_TYPE_TX_FRM_HDR || + (log_type) == PKTLOG_TYPE_TX_VIRT_ADDR) { + wdi_event_handler(WDI_EVENT_TX_STATUS, pdev->txrx_pdev, pl_hdr); + } else if ((log_type) == PKTLOG_TYPE_RC_FIND) { + wdi_event_handler(WDI_EVENT_RATE_FIND, pdev->txrx_pdev, pl_hdr); + } else if ((log_type) == PKTLOG_TYPE_RC_UPDATE) { + wdi_event_handler( + WDI_EVENT_RATE_UPDATE, pdev->txrx_pdev, pl_hdr); + } else if ((log_type) == PKTLOG_TYPE_RX_STAT) { + wdi_event_handler(WDI_EVENT_RX_DESC, pdev->txrx_pdev, pl_hdr); + } + break; + } +#endif + case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: + { + u_int32_t htt_credit_delta_abs; + int32_t htt_credit_delta; + int sign; + + htt_credit_delta_abs = HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word); + sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1; + htt_credit_delta = sign * htt_credit_delta_abs; + ol_tx_credit_completion_handler(pdev->txrx_pdev, htt_credit_delta); + break; + } + +#ifdef IPA_UC_OFFLOAD + case HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE: + { + u_int8_t op_code; + u_int16_t len; + u_int8_t *op_msg_buffer; + u_int8_t *msg_start_ptr; + + msg_start_ptr = (u_int8_t *)msg_word; + op_code = HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word); + msg_word++; + len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*msg_word); + + op_msg_buffer = adf_os_mem_alloc(NULL, + sizeof(struct htt_wdi_ipa_op_response_t) + len); + if (!op_msg_buffer) { + adf_os_print("OPCODE messsage buffer alloc fail"); + break; + } + adf_os_mem_copy(op_msg_buffer, + msg_start_ptr, + sizeof(struct htt_wdi_ipa_op_response_t) + len); + ol_txrx_ipa_uc_op_response(pdev->txrx_pdev, op_msg_buffer); + break; + } +#endif /* IPA_UC_OFFLOAD */ + + default: + break; + }; + /* Free the indication buffer */ + adf_nbuf_free(htt_t2h_msg); +} + +/* Generic Target to host Msg/event handler for low priority messages + Low priority message are handler in a different handler called from + this function . So that the most likely succes path like Rx and + Tx comp has little code foot print + */ +void +htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) +{ + struct htt_pdev_t *pdev = (struct htt_pdev_t *) context; + adf_nbuf_t htt_t2h_msg = (adf_nbuf_t) pkt->pPktContext; + u_int32_t *msg_word; + enum htt_t2h_msg_type msg_type; + + /* check for successful message reception */ + if (pkt->Status != A_OK) { + if (pkt->Status != A_ECANCELED) { + pdev->stats.htc_err_cnt++; + } + adf_nbuf_free(htt_t2h_msg); + return; + } + +#ifdef HTT_RX_RESTORE +if (adf_os_unlikely(pdev->rx_ring.rx_reset)) { + adf_os_print("rx restore ..\n"); + adf_nbuf_free(htt_t2h_msg); + return; + } +#endif + + /* confirm alignment */ + HTT_ASSERT3((((unsigned long) adf_nbuf_data(htt_t2h_msg)) & 0x3) == 0); + + msg_word = (u_int32_t *) adf_nbuf_data(htt_t2h_msg); + msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word); + switch (msg_type) { + case HTT_T2H_MSG_TYPE_RX_IND: + { + unsigned num_mpdu_ranges; + unsigned num_msdu_bytes; + u_int16_t peer_id; + u_int8_t tid; + + if (adf_os_unlikely(pdev->cfg.is_full_reorder_offload)) { + adf_os_print("HTT_T2H_MSG_TYPE_RX_IND not supported with full " + "reorder offload\n"); + break; + } + peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word); + tid = HTT_RX_IND_EXT_TID_GET(*msg_word); + + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + adf_os_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n", tid); + break; + } + + num_msdu_bytes = HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32)); + /* + * 1 word for the message header, + * HTT_RX_PPDU_DESC_SIZE32 words for the FW rx PPDU desc + * 1 word to specify the number of MSDU bytes, + * 1 word for every 4 MSDU bytes (round up), + * 1 word for the MPDU range header + */ + pdev->rx_mpdu_range_offset_words = + (HTT_RX_IND_HDR_BYTES + num_msdu_bytes + 3) >> 2; + num_mpdu_ranges = HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)); + pdev->rx_ind_msdu_byte_idx = 0; + + if (pdev->cfg.is_high_latency) { + /* + * TODO: remove copy after stopping reuse skb on HIF layer + * because SDIO HIF may reuse skb before upper layer release it + */ + ol_rx_indication_handler( + pdev->txrx_pdev, htt_t2h_msg, peer_id, tid, + num_mpdu_ranges); + + return; + } else { + ol_rx_indication_handler( + pdev->txrx_pdev, htt_t2h_msg, peer_id, tid, + num_mpdu_ranges); + } + break; + } + case HTT_T2H_MSG_TYPE_TX_COMPL_IND: + { + int num_msdus; + enum htt_tx_status status; + + /* status - no enum translation needed */ + status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word); + num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + if (num_msdus & 0x1) { + struct htt_tx_compl_ind_base *compl = (void *)msg_word; + + /* + * Host CPU endianness can be different from FW CPU. This + * can result in even and odd MSDU IDs being switched. If + * this happens, copy the switched final odd MSDU ID from + * location payload[size], to location payload[size-1], + * where the message handler function expects to find it + */ + if (compl->payload[num_msdus] != HTT_TX_COMPL_INV_MSDU_ID) { + compl->payload[num_msdus - 1] = + compl->payload[num_msdus]; + } + } + if (pdev->cfg.is_high_latency) { + ol_tx_target_credit_update( + pdev->txrx_pdev, num_msdus /* 1 credit per MSDU */); + } + ol_tx_completion_handler( + pdev->txrx_pdev, num_msdus, status, msg_word + 1); + HTT_TX_SCHED(pdev); + break; + } + case HTT_T2H_MSG_TYPE_RX_PN_IND: + { + u_int16_t peer_id; + u_int8_t tid, pn_ie_cnt, *pn_ie=NULL; + int seq_num_start, seq_num_end; + + /*First dword */ + peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word); + tid = HTT_RX_PN_IND_EXT_TID_GET(*msg_word); + + msg_word++; + /*Second dword */ + seq_num_start = HTT_RX_PN_IND_SEQ_NUM_START_GET(*msg_word); + seq_num_end = HTT_RX_PN_IND_SEQ_NUM_END_GET(*msg_word); + pn_ie_cnt = HTT_RX_PN_IND_PN_IE_CNT_GET(*msg_word); + + msg_word++; + /*Third dword*/ + if (pn_ie_cnt) { + pn_ie = (u_int8_t *)msg_word; + } + + ol_rx_pn_ind_handler( + pdev->txrx_pdev, peer_id, tid, seq_num_start, seq_num_end, + pn_ie_cnt, pn_ie); + + break; + } + case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: + { + int num_msdus; + + num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word); + if (num_msdus & 0x1) { + struct htt_tx_compl_ind_base *compl = (void *)msg_word; + + /* + * Host CPU endianness can be different from FW CPU. This + * can result in even and odd MSDU IDs being switched. If + * this happens, copy the switched final odd MSDU ID from + * location payload[size], to location payload[size-1], + * where the message handler function expects to find it + */ + if (compl->payload[num_msdus] != HTT_TX_COMPL_INV_MSDU_ID) { + compl->payload[num_msdus - 1] = + compl->payload[num_msdus]; + } + } + ol_tx_inspect_handler(pdev->txrx_pdev, num_msdus, msg_word + 1); + HTT_TX_SCHED(pdev); + break; + } + case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: + { + u_int16_t peer_id; + u_int8_t tid; + u_int8_t offload_ind, frag_ind; + + if (adf_os_unlikely(!pdev->cfg.is_full_reorder_offload)) { + adf_os_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported" + " when full reorder offload is disabled\n"); + break; + } + + if (adf_os_unlikely(pdev->cfg.is_high_latency)) { + adf_os_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported" + " on high latency\n"); + break; + } + + peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(*msg_word); + tid = HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(*msg_word); + offload_ind = HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(*msg_word); + frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(*msg_word); + + if (adf_os_unlikely(frag_ind)) { + ol_rx_frag_indication_handler(pdev->txrx_pdev, htt_t2h_msg, + peer_id, tid); + break; + } + + ol_rx_in_order_indication_handler(pdev->txrx_pdev, htt_t2h_msg, + peer_id, tid, offload_ind); + break; + } + + default: + htt_t2h_lp_msg_handler(context, htt_t2h_msg); + return ; + + }; + + /* Free the indication buffer */ + adf_nbuf_free(htt_t2h_msg); +} + +/*--- target->host HTT message Info Element access methods ------------------*/ + +/*--- tx completion message ---*/ + +u_int16_t +htt_tx_compl_desc_id(void *iterator, int num) +{ + /* + * The MSDU IDs are packed , 2 per 32-bit word. + * Iterate on them as an array of 16-bit elements. + * This will work fine if the host endianness matches + * the target endianness. + * If the host endianness is opposite of the target's, + * this iterator will produce descriptor IDs in a different + * order than the target inserted them into the message - + * if the target puts in [0, 1, 2, 3, ...] the host will + * put out [1, 0, 3, 2, ...]. + * This is fine, except for the last ID if there are an + * odd number of IDs. But the TX_COMPL_IND handling code + * in the htt_t2h_msg_handler already added a duplicate + * of the final ID, if there were an odd number of IDs, + * so this function can safely treat the IDs as an array + * of 16-bit elements. + */ + return *(((u_int16_t *) iterator) + num); +} + +/*--- rx indication message ---*/ + +int +htt_rx_ind_flush(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_ind_msg); + return HTT_RX_IND_FLUSH_VALID_GET(*msg_word); +} + +void +htt_rx_ind_flush_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + unsigned *seq_num_start, + unsigned *seq_num_end) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_ind_msg); + msg_word++; + *seq_num_start = HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(*msg_word); + *seq_num_end = HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(*msg_word); +} + +int +htt_rx_ind_release(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_ind_msg); + return HTT_RX_IND_REL_VALID_GET(*msg_word); +} + +void +htt_rx_ind_release_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + unsigned *seq_num_start, + unsigned *seq_num_end) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_ind_msg); + msg_word++; + *seq_num_start = HTT_RX_IND_REL_SEQ_NUM_START_GET(*msg_word); + *seq_num_end = HTT_RX_IND_REL_SEQ_NUM_END_GET(*msg_word); +} + +void +htt_rx_ind_mpdu_range_info( + struct htt_pdev_t *pdev, + adf_nbuf_t rx_ind_msg, + int mpdu_range_num, + enum htt_rx_status *status, + int *mpdu_count) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_ind_msg); + msg_word += pdev->rx_mpdu_range_offset_words + mpdu_range_num; + *status = HTT_RX_IND_MPDU_STATUS_GET(*msg_word); + *mpdu_count = HTT_RX_IND_MPDU_COUNT_GET(*msg_word); +} + +#define HTT_TGT_NOISE_FLOOR_DBM (-95) /* approx */ +int16_t +htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg) +{ + int16_t rssi; + u_int32_t *msg_word; + + msg_word = (u_int32_t *) + (adf_nbuf_data(rx_ind_msg) + HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET); + + /* check if the RX_IND message contains valid rx PPDU start info */ + if (!HTT_RX_IND_START_VALID_GET(*msg_word)) { + return HTT_RSSI_INVALID; + } + + rssi = HTT_RX_IND_RSSI_CMB_GET(*msg_word); + return (HTT_TGT_RSSI_INVALID == rssi) ? + HTT_RSSI_INVALID : + rssi + HTT_TGT_NOISE_FLOOR_DBM; +} + + +/*--- stats confirmation message ---*/ + +void +htt_t2h_dbg_stats_hdr_parse( + u_int8_t *stats_info_list, + enum htt_dbg_stats_type *type, + enum htt_dbg_stats_status *status, + int *length, + u_int8_t **stats_data) +{ + u_int32_t *msg_word = (u_int32_t *) stats_info_list; + *type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word); + *status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word); + *length = HTT_T2H_STATS_CONF_TLV_HDR_SIZE + /* header length */ + HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word); /* data length */ + *stats_data = stats_info_list + HTT_T2H_STATS_CONF_TLV_HDR_SIZE; +} + +void +htt_rx_frag_ind_flush_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_frag_ind_msg, + int *seq_num_start, + int *seq_num_end) +{ + u_int32_t *msg_word; + + msg_word = (u_int32_t *) adf_nbuf_data(rx_frag_ind_msg); + msg_word++; + *seq_num_start = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_START_GET(*msg_word); + *seq_num_end = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_END_GET(*msg_word); +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_tx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_tx.c new file mode 100644 index 0000000000000..6caab2b799b0f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_tx.c @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file htt_tx.c + * @brief Implement transmit aspects of HTT. + * @details + * This file contains three categories of HTT tx code: + * 1. An abstraction of the tx descriptor, to hide the + * differences between the HL vs. LL tx descriptor. + * 2. Functions for allocating and freeing HTT tx descriptors. + * 3. The function that accepts a tx frame from txrx and sends the + * tx frame to HTC. + */ +#include /* u_int32_t, offsetof, etc. */ +#include /* adf_os_dma_addr_t */ +#include /* adf_os_mem_alloc_consistent,free_consistent */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_mdelay */ + +#include /* htt_tx_msdu_desc_t */ +#include /* HTC_HDR_LENGTH */ +#include /* HTCFlushSurpriseRemove */ +#include /* ol_cfg_netbuf_frags_max, etc. */ +#include /* HTT_TX_DESC_VADDR_OFFSET */ +#include /* ol_tx_msdu_id_storage */ +#include + +#ifdef IPA_UC_OFFLOAD +/* IPA Micro controler TX data packet HTT Header Preset */ +/* 31 | 30 29 | 28 | 27 | 26 22 | 21 16 | 15 13 | 12 8 | 7 0 + *------------------------------------------------------------------------------ + * R | CS OL | R | PP | ext TID | vdev ID | pkt type | pkt subtype | msg type + * 0 | 0 | 0 | | 0x1F | 0 | 2 | 0 | 0x01 + *------------------------------------------------------------------------------ + * pkt ID | pkt length + *------------------------------------------------------------------------------ + * frag_desc_ptr + *------------------------------------------------------------------------------ + * peer_id + *------------------------------------------------------------------------------ + */ +#define HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT 0x07C04001 +#endif /* IPA_UC_OFFLOAD */ + +/*--- setup / tear-down functions -------------------------------------------*/ + +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS +u_int32_t *g_dbg_htt_desc_end_addr, *g_dbg_htt_desc_start_addr; +#endif + +int +htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems) +{ + int i, pool_size; + u_int32_t **p; + adf_os_dma_addr_t pool_paddr = {0}; + + if (pdev->cfg.is_high_latency) { + pdev->tx_descs.size = sizeof(struct htt_host_tx_desc_t); + } else { + pdev->tx_descs.size = + /* + * Start with the size of the base struct + * that actually gets downloaded. + */ + sizeof(struct htt_host_tx_desc_t) + /* + * Add the fragmentation descriptor elements. + * Add the most that the OS may deliver, plus one more in + * case the txrx code adds a prefix fragment (for TSO or + * audio interworking SNAP header) + */ + + (ol_cfg_netbuf_frags_max(pdev->ctrl_pdev)+1) * 8 // 2x u_int32_t + + 4; /* u_int32_t fragmentation list terminator */ + } + + /* + * Make sure tx_descs.size is a multiple of 4-bytes. + * It should be, but round up just to be sure. + */ + pdev->tx_descs.size = (pdev->tx_descs.size + 3) & (~0x3); + + pdev->tx_descs.pool_elems = desc_pool_elems; + pdev->tx_descs.alloc_cnt = 0; + + pool_size = pdev->tx_descs.pool_elems * pdev->tx_descs.size; + + if (pdev->cfg.is_high_latency) + pdev->tx_descs.pool_vaddr = adf_os_mem_alloc(pdev->osdev, pool_size); + else + pdev->tx_descs.pool_vaddr = + adf_os_mem_alloc_consistent( pdev->osdev, pool_size, &pool_paddr, + adf_os_get_dma_mem_context((&pdev->tx_descs), memctx)); + + pdev->tx_descs.pool_paddr = pool_paddr; + + if (!pdev->tx_descs.pool_vaddr) { + return 1; /* failure */ + } + + adf_os_print("%s:htt_desc_start:0x%p htt_desc_end:0x%p\n", __func__, + pdev->tx_descs.pool_vaddr, + (u_int32_t *) (pdev->tx_descs.pool_vaddr + pool_size)); + +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + g_dbg_htt_desc_end_addr = (u_int32_t *) + (pdev->tx_descs.pool_vaddr + pool_size); + g_dbg_htt_desc_start_addr = (u_int32_t *) pdev->tx_descs.pool_vaddr; +#endif + + /* link tx descriptors into a freelist */ + pdev->tx_descs.freelist = (u_int32_t *) pdev->tx_descs.pool_vaddr; + p = (u_int32_t **) pdev->tx_descs.freelist; + for (i = 0; i < desc_pool_elems - 1; i++) { + *p = (u_int32_t *) (((char *) p) + pdev->tx_descs.size); + p = (u_int32_t **) *p; + } + *p = NULL; + + return 0; /* success */ +} + +void +htt_tx_detach(struct htt_pdev_t *pdev) +{ + if (pdev){ + if (pdev->cfg.is_high_latency) + adf_os_mem_free(pdev->tx_descs.pool_vaddr); + else + adf_os_mem_free_consistent( + pdev->osdev, + pdev->tx_descs.pool_elems * pdev->tx_descs.size, /* pool_size */ + pdev->tx_descs.pool_vaddr, + pdev->tx_descs.pool_paddr, + adf_os_get_dma_mem_context((&pdev->tx_descs), memctx)); + } +} + + +/*--- descriptor allocation functions ---------------------------------------*/ + +void * +htt_tx_desc_alloc(htt_pdev_handle pdev, u_int32_t *paddr_lo) +{ + struct htt_host_tx_desc_t *htt_host_tx_desc; /* includes HTC hdr space */ + struct htt_tx_msdu_desc_t *htt_tx_desc; /* doesn't include HTC hdr */ + + htt_host_tx_desc = (struct htt_host_tx_desc_t *) pdev->tx_descs.freelist; + if (! htt_host_tx_desc) { + return NULL; /* pool is exhausted */ + } + htt_tx_desc = &htt_host_tx_desc->align32.tx_desc; + + if (pdev->tx_descs.freelist) { + pdev->tx_descs.freelist = *((u_int32_t **) pdev->tx_descs.freelist); + pdev->tx_descs.alloc_cnt++; + } + /* + * For LL, set up the fragmentation descriptor address. + * Currently, this HTT tx desc allocation is performed once up front. + * If this is changed to have the allocation done during tx, then it + * would be helpful to have separate htt_tx_desc_alloc functions for + * HL vs. LL, to remove the below conditional branch. + */ + if (!pdev->cfg.is_high_latency) { + u_int32_t *fragmentation_descr_field_ptr; + + fragmentation_descr_field_ptr = (u_int32_t *) + ((u_int32_t *) htt_tx_desc) + + HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_DWORD; + /* + * The fragmentation descriptor is allocated from consistent mem. + * Therefore, we can use the address directly rather than having + * to map it from a virtual/CPU address to a physical/bus address. + */ + *fragmentation_descr_field_ptr = + HTT_TX_DESC_PADDR(pdev, htt_tx_desc) + HTT_TX_DESC_LEN; + } + /* + * Include the headroom for the HTC frame header when specifying the + * physical address for the HTT tx descriptor. + */ + *paddr_lo = (u_int32_t) HTT_TX_DESC_PADDR(pdev, htt_host_tx_desc); + /* + * The allocated tx descriptor space includes headroom for a + * HTC frame header. Hide this headroom, so that we don't have + * to jump past the headroom each time we program a field within + * the tx desc, but only once when we download the tx desc (and + * the headroom) to the target via HTC. + * Skip past the headroom and return the address of the HTT tx desc. + */ + return (void *) htt_tx_desc; +} + +void +htt_tx_desc_free(htt_pdev_handle pdev, void *tx_desc) +{ + char *htt_host_tx_desc = tx_desc; + /* rewind over the HTC frame header space */ + htt_host_tx_desc -= offsetof(struct htt_host_tx_desc_t, align32.tx_desc); + *((u_int32_t **) htt_host_tx_desc) = pdev->tx_descs.freelist; + pdev->tx_descs.freelist = (u_int32_t *) htt_host_tx_desc; + pdev->tx_descs.alloc_cnt--; +} + +/*--- descriptor field access methods ---------------------------------------*/ + +void htt_tx_desc_frags_table_set( + htt_pdev_handle pdev, + void *htt_tx_desc, + u_int32_t paddr, + int reset) +{ + u_int32_t *fragmentation_descr_field_ptr; + + /* fragments table only applies to LL systems */ + if (pdev->cfg.is_high_latency) { + return; + } + fragmentation_descr_field_ptr = (u_int32_t *) + ((u_int32_t *) htt_tx_desc) + HTT_TX_DESC_FRAGS_DESC_PADDR_OFFSET_DWORD; + if (reset) { + *fragmentation_descr_field_ptr = + HTT_TX_DESC_PADDR(pdev, htt_tx_desc) + HTT_TX_DESC_LEN; + } else { + *fragmentation_descr_field_ptr = paddr; + } +} + +/* PUT THESE AS INLINE IN ol_htt_tx_api.h */ + +void +htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc) +{ +} + +#if !defined(CONFIG_HL_SUPPORT) +void +htt_tx_pending_discard(htt_pdev_handle pdev) +{ + HTCFlushSurpriseRemove(pdev->htc_pdev); +} +#endif + +void +htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc) +{ +} + +/*--- tx send function ------------------------------------------------------*/ + +#ifdef ATH_11AC_TXCOMPACT + +/* Scheduling the Queued packets in HTT which could not be sent out because of No CE desc*/ +void +htt_tx_sched(htt_pdev_handle pdev) +{ + adf_nbuf_t msdu; + int download_len = pdev->download_len; + int packet_len; + + HTT_TX_NBUF_QUEUE_REMOVE(pdev, msdu); + while (msdu != NULL){ + int not_accepted; + /* packet length includes HTT tx desc frag added above */ + packet_len = adf_nbuf_len(msdu); + if (packet_len < download_len) { + /* + * This case of packet length being less than the nominal download + * length can happen for a couple reasons: + * In HL, the nominal download length is a large artificial value. + * In LL, the frame may not have the optional header fields + * accounted for in the nominal download size (LLC/SNAP header, + * IPv4 or IPv6 header). + */ + download_len = packet_len; + } + + + not_accepted = HTCSendDataPkt( + pdev->htc_pdev, msdu, pdev->htc_endpoint, download_len); + if (not_accepted) { + HTT_TX_NBUF_QUEUE_INSERT_HEAD(pdev, msdu); + return; + } + HTT_TX_NBUF_QUEUE_REMOVE(pdev, msdu); + } +} + + +int +htt_tx_send_std( + htt_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + + int download_len = pdev->download_len; + + int packet_len; + + /* packet length includes HTT tx desc frag added above */ + packet_len = adf_nbuf_len(msdu); + if (packet_len < download_len) { + /* + * This case of packet length being less than the nominal download + * length can happen for a couple reasons: + * In HL, the nominal download length is a large artificial value. + * In LL, the frame may not have the optional header fields + * accounted for in the nominal download size (LLC/SNAP header, + * IPv4 or IPv6 header). + */ + download_len = packet_len; + } + + if (adf_nbuf_queue_len(&pdev->txnbufq) > 0) { + HTT_TX_NBUF_QUEUE_ADD(pdev, msdu); + htt_tx_sched(pdev); + return 0; + } + + adf_nbuf_trace_update(msdu, "HT:T:"); + if (HTCSendDataPkt(pdev->htc_pdev, msdu, pdev->htc_endpoint, download_len)){ + HTT_TX_NBUF_QUEUE_ADD(pdev, msdu); + } + + return 0; /* success */ + +} + +adf_nbuf_t +htt_tx_send_batch(htt_pdev_handle pdev, adf_nbuf_t head_msdu, int num_msdus) +{ + adf_os_print("*** %s curently only applies for HL systems\n", __func__); + adf_os_assert(0); + return head_msdu; + +} + +int +htt_tx_send_nonstd( + htt_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id, + enum htt_pkt_type pkt_type) +{ + int download_len; + + /* + * The pkt_type could be checked to see what L2 header type is present, + * and then the L2 header could be examined to determine its length. + * But for simplicity, just use the maximum possible header size, + * rather than computing the actual header size. + */ + download_len = + sizeof(struct htt_host_tx_desc_t) + + HTT_TX_HDR_SIZE_OUTER_HDR_MAX + /* worst case */ + HTT_TX_HDR_SIZE_802_1Q + + HTT_TX_HDR_SIZE_LLC_SNAP + + ol_cfg_tx_download_size(pdev->ctrl_pdev); + adf_os_assert(download_len <= pdev->download_len); + return htt_tx_send_std(pdev, msdu, msdu_id); +} + +#else /*ATH_11AC_TXCOMPACT*/ + +#ifdef QCA_TX_HTT2_SUPPORT +static inline HTC_ENDPOINT_ID +htt_tx_htt2_get_ep_id( + htt_pdev_handle pdev, + adf_nbuf_t msdu) +{ + /* + * TX HTT2 service mainly for small sized frame and check if + * this candidate frame allow or not. + */ + if ((pdev->htc_tx_htt2_endpoint != ENDPOINT_UNUSED) && + adf_nbuf_get_tx_parallel_dnload_frm(msdu) && + (adf_nbuf_len(msdu) < pdev->htc_tx_htt2_max_size)) + return pdev->htc_tx_htt2_endpoint; + else + return pdev->htc_endpoint; +} +#else +#define htt_tx_htt2_get_ep_id(pdev, msdu) (pdev->htc_endpoint) +#endif /* QCA_TX_HTT2_SUPPORT */ + +static inline int +htt_tx_send_base( + htt_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id, + int download_len, + u_int8_t more_data) +{ + struct htt_host_tx_desc_t *htt_host_tx_desc; + struct htt_htc_pkt *pkt; + int packet_len; + HTC_ENDPOINT_ID ep_id; + + /* + * The HTT tx descriptor was attached as the prefix fragment to the + * msdu netbuf during the call to htt_tx_desc_init. + * Retrieve it so we can provide its HTC header space to HTC. + */ + htt_host_tx_desc = (struct htt_host_tx_desc_t *) + adf_nbuf_get_frag_vaddr(msdu, 0); + + pkt = htt_htc_pkt_alloc(pdev); + if (!pkt) { + return 1; /* failure */ + } + + pkt->msdu_id = msdu_id; + pkt->pdev_ctxt = pdev->txrx_pdev; + + /* packet length includes HTT tx desc frag added above */ + packet_len = adf_nbuf_len(msdu); + if (packet_len < download_len) { + /* + * This case of packet length being less than the nominal download + * length can happen for a couple reasons: + * In HL, the nominal download length is a large artificial value. + * In LL, the frame may not have the optional header fields + * accounted for in the nominal download size (LLC/SNAP header, + * IPv4 or IPv6 header). + */ + download_len = packet_len; + } + + ep_id = htt_tx_htt2_get_ep_id(pdev, msdu); + + SET_HTC_PACKET_INFO_TX( + &pkt->htc_pkt, + pdev->tx_send_complete_part2, + (unsigned char *) htt_host_tx_desc, + download_len - HTC_HDR_LENGTH, + ep_id, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msdu); + + adf_nbuf_trace_update(msdu, "HT:T:"); + HTCSendDataPkt(pdev->htc_pdev, &pkt->htc_pkt, more_data); + + return 0; /* success */ +} + +adf_nbuf_t +htt_tx_send_batch( + htt_pdev_handle pdev, + adf_nbuf_t head_msdu, int num_msdus) +{ + adf_nbuf_t rejected = NULL; + u_int16_t *msdu_id_storage; + u_int16_t msdu_id; + adf_nbuf_t msdu; + /* + * FOR NOW, iterate through the batch, sending the frames singly. + * Eventually HTC and HIF should be able to accept a batch of + * data frames rather than singles. + */ + msdu = head_msdu; + while (num_msdus--) + { + adf_nbuf_t next_msdu = adf_nbuf_next(msdu); + msdu_id_storage = ol_tx_msdu_id_storage(msdu); + msdu_id = *msdu_id_storage; + + /* htt_tx_send_base returns 0 as success and 1 as failure */ + if (htt_tx_send_base(pdev, msdu, msdu_id, pdev->download_len, + num_msdus)) { + adf_nbuf_set_next(msdu, rejected); + rejected = msdu; + } + msdu = next_msdu; + } + return rejected; +} + +int +htt_tx_send_nonstd( + htt_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id, + enum htt_pkt_type pkt_type) +{ + int download_len; + + /* + * The pkt_type could be checked to see what L2 header type is present, + * and then the L2 header could be examined to determine its length. + * But for simplicity, just use the maximum possible header size, + * rather than computing the actual header size. + */ + download_len = + sizeof(struct htt_host_tx_desc_t) + + HTT_TX_HDR_SIZE_OUTER_HDR_MAX + /* worst case */ + HTT_TX_HDR_SIZE_802_1Q + + HTT_TX_HDR_SIZE_LLC_SNAP + + ol_cfg_tx_download_size(pdev->ctrl_pdev); + return htt_tx_send_base(pdev, msdu, msdu_id, download_len, 0); +} + +int +htt_tx_send_std( + htt_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + return htt_tx_send_base(pdev, msdu, msdu_id, pdev->download_len, 0); +} + +#endif /*ATH_11AC_TXCOMPACT*/ +#ifdef HTT_DBG +void +htt_tx_desc_display(void *tx_desc) +{ + struct htt_tx_msdu_desc_t *htt_tx_desc; + + htt_tx_desc = (struct htt_tx_msdu_desc_t *) tx_desc; + + /* only works for little-endian */ + adf_os_print("HTT tx desc (@ %p):\n", htt_tx_desc); + adf_os_print(" msg type = %d\n", htt_tx_desc->msg_type); + adf_os_print(" pkt subtype = %d\n", htt_tx_desc->pkt_subtype); + adf_os_print(" pkt type = %d\n", htt_tx_desc->pkt_type); + adf_os_print(" vdev ID = %d\n", htt_tx_desc->vdev_id); + adf_os_print(" ext TID = %d\n", htt_tx_desc->ext_tid); + adf_os_print(" postponed = %d\n", htt_tx_desc->postponed); + adf_os_print(" batch more = %d\n", htt_tx_desc->more_in_batch); + adf_os_print(" length = %d\n", htt_tx_desc->len); + adf_os_print(" id = %d\n", htt_tx_desc->id); + adf_os_print(" frag desc addr = %#x\n", htt_tx_desc->frags_desc_ptr); + if (htt_tx_desc->frags_desc_ptr) { + int frag = 0; + u_int32_t *base; + u_int32_t addr; + u_int32_t len; + do { + base = ((u_int32_t *) htt_tx_desc->frags_desc_ptr) + (frag * 2); + addr = *base; + len = *(base + 1); + if (addr) { + adf_os_print( + " frag %d: addr = %#x, len = %d\n", frag, addr, len); + } + frag++; + } while (addr); + } +} +#endif + +#ifdef IPA_UC_OFFLOAD +int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev, + unsigned int uc_tx_buf_sz, + unsigned int uc_tx_buf_cnt, + unsigned int uc_tx_partition_base) +{ + unsigned int tx_buffer_count; + adf_nbuf_t buffer_vaddr; + u_int32_t buffer_paddr; + u_int32_t *header_ptr; + u_int32_t *ring_vaddr; + int return_code = 0; + + /* Allocate CE Write Index WORD */ + pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr = + adf_os_mem_alloc_consistent(pdev->osdev, + 4, + &pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_ce_idx), memctx)); + if (!pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr) { + adf_os_print("%s: CE Write Index WORD alloc fail", __func__); + return -1; + } + + /* Allocate TX COMP Ring */ + pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr = + adf_os_mem_alloc_consistent(pdev->osdev, + uc_tx_buf_cnt * 4, + &pdev->ipa_uc_tx_rsc.tx_comp_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_comp_base), memctx)); + if (!pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr) { + adf_os_print("%s: TX COMP ring alloc fail", __func__); + return_code = -2; + goto free_tx_ce_idx; + } + + adf_os_mem_zero(pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr, uc_tx_buf_cnt * 4); + + /* Allocate TX BUF vAddress Storage */ + pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg = + (adf_nbuf_t *)adf_os_mem_alloc(pdev->osdev, + uc_tx_buf_cnt * sizeof(adf_nbuf_t)); + if (!pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg) { + adf_os_print("%s: TX BUF POOL vaddr storage alloc fail", + __func__); + return_code = -3; + goto free_tx_comp_base; + } + adf_os_mem_zero(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg, + uc_tx_buf_cnt * sizeof(adf_nbuf_t)); + + ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr; + /* Allocate TX buffers as many as possible */ + for (tx_buffer_count = 0; + tx_buffer_count < (uc_tx_buf_cnt - 1); + tx_buffer_count++) { + buffer_vaddr = adf_nbuf_alloc(pdev->osdev, + uc_tx_buf_sz, 0, 4, FALSE); + if (!buffer_vaddr) + { + adf_os_print("%s: TX BUF alloc fail, allocated buffer count %d", + __func__, tx_buffer_count); + return 0; + } + + /* Init buffer */ + adf_os_mem_zero(adf_nbuf_data(buffer_vaddr), uc_tx_buf_sz); + header_ptr = (u_int32_t *)adf_nbuf_data(buffer_vaddr); + + *header_ptr = HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT; + header_ptr++; + *header_ptr |= ((u_int16_t)uc_tx_partition_base + tx_buffer_count) << 16; + + adf_nbuf_map(pdev->osdev, buffer_vaddr, ADF_OS_DMA_BIDIRECTIONAL); + buffer_paddr = adf_nbuf_get_frag_paddr_lo(buffer_vaddr, 0); + header_ptr++; + *header_ptr = (u_int32_t)(buffer_paddr + 16); + + header_ptr++; + *header_ptr = 0xFFFFFFFF; + + /* FRAG Header */ + header_ptr++; + *header_ptr = buffer_paddr + 32; + + *ring_vaddr = buffer_paddr; + pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[tx_buffer_count] = + buffer_vaddr; + /* Memory barrier to ensure actual value updated */ + + ring_vaddr++; + } + + pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count; + + return 0; + +free_tx_comp_base: + adf_os_mem_free_consistent(pdev->osdev, + ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev) * 4, + pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr, + pdev->ipa_uc_tx_rsc.tx_comp_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_comp_base), memctx)); +free_tx_ce_idx: + adf_os_mem_free_consistent(pdev->osdev, + 4, + pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr, + pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_ce_idx), memctx)); + return return_code; +} + +int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev) +{ + u_int16_t idx; + + if (pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr) { + adf_os_mem_free_consistent(pdev->osdev, + 4, + pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr, + pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_ce_idx), memctx)); + } + + if (pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr) { + adf_os_mem_free_consistent(pdev->osdev, + ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev) * 4, + pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr, + pdev->ipa_uc_tx_rsc.tx_comp_base.paddr, + adf_os_get_dma_mem_context( + (&pdev->ipa_uc_tx_rsc.tx_comp_base), memctx)); + } + + /* Free each single buffer */ + for(idx = 0; idx < pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) { + if (pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[idx]) { + adf_nbuf_unmap(pdev->osdev, + pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[idx], + ADF_OS_DMA_FROM_DEVICE); + adf_nbuf_free(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[idx]); + } + } + + /* Free storage */ + adf_os_mem_free(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg); + + return 0; +} +#endif /* IPA_UC_OFFLOAD */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_types.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_types.h new file mode 100644 index 0000000000000..ea26bfc0193e1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/htt_types.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _HTT_TYPES__H_ +#define _HTT_TYPES__H_ + +#include /* u_int16_t, dma_addr_t */ +#include /* adf_os_device_t */ +#include /* adf_os_spinlock_t */ +#include /* adf_os_timer_t */ +#include /* adf_os_atomic_inc */ +#include /* adf_nbuf_t */ +#include /* HTC_PACKET */ + +#include /* ol_pdev_handle */ +#include /* ol_txrx_pdev_handle */ + +#define DEBUG_DMA_DONE + +#define HTT_TX_MUTEX_TYPE adf_os_spinlock_t + +#ifdef QCA_TX_HTT2_SUPPORT +#ifndef HTC_TX_HTT2_MAX_SIZE +/* Should sync to the target's implementation. */ +#define HTC_TX_HTT2_MAX_SIZE (120) +#endif +#endif /* QCA_TX_HTT2_SUPPORT */ + +#define HTT_INVALID_PEER 0xffff +#define HTT_INVALID_VDEV 0xff +#define HTT_NON_QOS_TID 16 +#define HTT_INVALID_TID 31 + +#define HTT_TX_EXT_TID_DEFAULT 0 +#define HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST 16 +#define HTT_TX_EXT_TID_MGMT 17 +#define HTT_TX_EXT_TID_INVALID 31 +#define HTT_TX_EXT_TID_NONPAUSE 19 + +/** + * @brief General specification of the tx frame contents + * + * @details + * for efficiency, the HTT packet type values correspond + * to the bit positions of the WAL packet type values, so the + * translation is a simple shift operation. + */ +enum htt_pkt_type { + htt_pkt_type_raw = 0, + htt_pkt_type_native_wifi = 1, + htt_pkt_type_ethernet = 2, + htt_pkt_type_mgmt = 3, + + /* keep this last */ + htt_pkt_num_types +}; + +struct htt_pdev_t; + +struct htt_htc_pkt { + void *pdev_ctxt; + dma_addr_t nbuf_paddr; + HTC_PACKET htc_pkt; + u_int16_t msdu_id; +}; + +struct htt_htc_pkt_union { + union { + struct htt_htc_pkt pkt; + struct htt_htc_pkt_union *next; + } u; +}; + +/* + * HTT host descriptor: + * Include the htt_tx_msdu_desc that gets downloaded to the target, + * but also include the HTC_FRAME_HDR and alignment padding that + * precede the htt_tx_msdu_desc. + * HTCSendDataPkt expects this header space at the front of the + * initial fragment (i.e. tx descriptor) that is downloaded. + */ +struct htt_host_tx_desc_t { + u_int8_t htc_header[HTC_HEADER_LEN]; + /* force the tx_desc field to begin on a 4-byte boundary */ + union { + u_int32_t dummy_force_align; + struct htt_tx_msdu_desc_t tx_desc; + } align32; +}; + +struct htt_tx_mgmt_desc_buf { + adf_nbuf_t msg_buf; + A_BOOL is_inuse; + adf_nbuf_t mgmt_frm; +}; + +struct htt_tx_mgmt_desc_ctxt { + struct htt_tx_mgmt_desc_buf *pool; + A_UINT32 pending_cnt; +}; + +typedef struct _htt_list_node { + struct _htt_list_node * prev; + struct _htt_list_node * next; +} htt_list_node; + +typedef htt_list_node htt_list_head; + +struct htt_rx_hash_entry { + A_UINT32 paddr; + adf_nbuf_t netbuf; + A_UINT8 fromlist; + htt_list_node listnode; +#ifdef RX_HASH_DEBUG + A_UINT32 cookie; +#endif +}; + +struct htt_rx_hash_bucket { + htt_list_head listhead; + struct htt_rx_hash_entry * entries; + htt_list_head freepool; +#ifdef RX_HASH_DEBUG + A_UINT32 count; +#endif +}; + +#ifdef IPA_UC_OFFLOAD + +/* IPA micro controller + wlan host driver + firmware shared memory structure */ +struct uc_shared_mem_t +{ + u_int32_t *vaddr; + adf_os_dma_addr_t paddr; + adf_os_dma_mem_context(memctx); +}; + +/* Micro controller datapath offload + * WLAN TX resources */ +struct htt_ipa_uc_tx_resource_t +{ + struct uc_shared_mem_t tx_ce_idx; + struct uc_shared_mem_t tx_comp_base; + + u_int32_t tx_comp_idx_paddr; + adf_nbuf_t *tx_buf_pool_vaddr_strg; + u_int32_t alloc_tx_buf_cnt; +}; + +/* Micro controller datapath offload + * WLAN RX resources */ +struct htt_ipa_uc_rx_resource_t +{ + adf_os_dma_addr_t rx_rdy_idx_paddr; + struct uc_shared_mem_t rx_ind_ring_base; + struct uc_shared_mem_t rx_ipa_prc_done_idx; + u_int32_t rx_ind_ring_size; +}; + +struct ipa_uc_rx_ring_elem_t +{ + u_int32_t rx_packet_paddr; + u_int16_t vdev_id; + u_int16_t rx_packet_leng; +}; +#endif /* IPA_UC_OFFLOAD */ + +struct htt_pdev_t { + ol_pdev_handle ctrl_pdev; + ol_txrx_pdev_handle txrx_pdev; + HTC_HANDLE htc_pdev; + adf_os_device_t osdev; + + HTC_ENDPOINT_ID htc_endpoint; + +#ifdef QCA_TX_HTT2_SUPPORT + HTC_ENDPOINT_ID htc_tx_htt2_endpoint; + u_int16_t htc_tx_htt2_max_size; +#endif /* QCA_TX_HTT2_SUPPORT */ + +#ifdef ATH_11AC_TXCOMPACT + HTT_TX_MUTEX_TYPE txnbufq_mutex; + adf_nbuf_queue_t txnbufq; + struct htt_htc_pkt_union *htt_htc_pkt_misclist; +#endif + + struct htt_htc_pkt_union *htt_htc_pkt_freelist; + struct { + int is_high_latency; + int is_full_reorder_offload; + int default_tx_comp_req; + } cfg; + struct { + u_int8_t major; + u_int8_t minor; + } tgt_ver; + struct { + struct { + /* + * Ring of network buffer objects - + * This ring is used exclusively by the host SW. + * This ring mirrors the dev_addrs_ring that is shared + * between the host SW and the MAC HW. + * The host SW uses this netbufs ring to locate the network + * buffer objects whose data buffers the HW has filled. + */ + adf_nbuf_t *netbufs_ring; + /* + * Ring of buffer addresses - + * This ring holds the "physical" device address of the + * rx buffers the host SW provides for the MAC HW to fill. + */ + u_int32_t *paddrs_ring; + adf_os_dma_mem_context(memctx); + } buf; + /* + * Base address of ring, as a "physical" device address rather than a + * CPU address. + */ + u_int32_t base_paddr; + int size; /* how many elems in the ring (power of 2) */ + unsigned size_mask; /* size - 1 */ + + int fill_level; /* how many rx buffers to keep in the ring */ + int fill_cnt; /* how many rx buffers (full+empty) are in the ring */ + + /* + * target_idx - + * Without reorder offload: + * not used + * With reorder offload: + * points to the location in the rx ring from which rx buffers are + * available to copy into the MAC DMA ring + */ + struct { + u_int32_t *vaddr; + u_int32_t paddr; + adf_os_dma_mem_context(memctx); + } target_idx; + + /* + * alloc_idx/host_idx - + * Without reorder offload: + * where HTT SW has deposited empty buffers + * This is allocated in consistent mem, so that the FW can read + * this variable, and program the HW's FW_IDX reg with the value + * of this shadow register + * With reorder offload: + * points to the end of the available free rx buffers + */ + struct { + u_int32_t *vaddr; + u_int32_t paddr; + adf_os_dma_mem_context(memctx); + } alloc_idx; + + /* sw_rd_idx - where HTT SW has processed bufs filled by rx MAC DMA */ + struct { + unsigned msdu_desc; + unsigned msdu_payld; + } sw_rd_idx; + + /* + * refill_retry_timer - timer triggered when the ring is not + * refilled to the level expected + */ + adf_os_timer_t refill_retry_timer; + + /* + * refill_ref_cnt - ref cnt for Rx buffer replenishment - this + * variable is used to guarantee that only one thread tries + * to replenish Rx ring. + */ + adf_os_atomic_t refill_ref_cnt; +#ifdef DEBUG_DMA_DONE + u_int32_t dbg_initial_msdu_payld; + u_int32_t dbg_mpdu_range; + u_int32_t dbg_mpdu_count; + u_int32_t dbg_ring_idx; + u_int32_t dbg_refill_cnt; + u_int32_t dbg_sync_success; +#endif +#ifdef HTT_RX_RESTORE + int rx_reset; + u_int8_t htt_rx_restore; +#endif + struct htt_rx_hash_bucket * hash_table; + u_int32_t listnode_offset; + } rx_ring; + int rx_desc_size_hl; + long rx_fw_desc_offset; + int rx_mpdu_range_offset_words; + int rx_ind_msdu_byte_idx; + + struct { + int size; /* of each HTT tx desc */ + int pool_elems; + int alloc_cnt; + char *pool_vaddr; + u_int32_t pool_paddr; + u_int32_t *freelist; + adf_os_dma_mem_context(memctx); + } tx_descs; + int download_len; + void (*tx_send_complete_part2)( + void *pdev, A_STATUS status, adf_nbuf_t msdu, u_int16_t msdu_id); + + HTT_TX_MUTEX_TYPE htt_tx_mutex; + + struct { + int htc_err_cnt; + } stats; + + int cur_seq_num_hl; + struct htt_tx_mgmt_desc_ctxt tx_mgmt_desc_ctxt; + struct targetdef_s *targetdef; + +#ifdef IPA_UC_OFFLOAD + struct htt_ipa_uc_tx_resource_t ipa_uc_tx_rsc; + struct htt_ipa_uc_rx_resource_t ipa_uc_rx_rsc; +#endif /* IPA_UC_OFFLOAD */ +}; + +#endif /* _HTT_TYPES__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/rx_desc.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/rx_desc.h new file mode 100644 index 0000000000000..6d656f7cc4868 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/HTT/rx_desc.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _RX_DESC_H_ +#define _RX_DESC_H_ + +/* + * REMIND: Copy one of rx_desc related structures here for export, + * hopes they are always the same between Peregrine and Rome in future... + */ +struct rx_attention { + volatile uint32_t first_mpdu : 1, //[0] + last_mpdu : 1, //[1] + mcast_bcast : 1, //[2] + peer_idx_invalid : 1, //[3] + peer_idx_timeout : 1, //[4] + power_mgmt : 1, //[5] + non_qos : 1, //[6] + null_data : 1, //[7] + mgmt_type : 1, //[8] + ctrl_type : 1, //[9] + more_data : 1, //[10] + eosp : 1, //[11] + u_apsd_trigger : 1, //[12] + fragment : 1, //[13] + order : 1, //[14] + classification : 1, //[15] + overflow_err : 1, //[16] + msdu_length_err : 1, //[17] + tcp_udp_chksum_fail : 1, //[18] + ip_chksum_fail : 1, //[19] + sa_idx_invalid : 1, //[20] + da_idx_invalid : 1, //[21] + sa_idx_timeout : 1, //[22] + da_idx_timeout : 1, //[23] + encrypt_required : 1, //[24] + directed : 1, //[25] + buffer_fragment : 1, //[26] + mpdu_length_err : 1, //[27] + tkip_mic_err : 1, //[28] + decrypt_err : 1, //[29] + fcs_err : 1, //[30] + msdu_done : 1; //[31] +}; + +struct rx_frag_info { + volatile uint32_t ring0_more_count : 8, //[7:0] + ring1_more_count : 8, //[15:8] + ring2_more_count : 8, //[23:16] + ring3_more_count : 8; //[31:24] +}; + +struct rx_mpdu_start { + volatile uint32_t peer_idx : 11, //[10:0] + fr_ds : 1, //[11] + to_ds : 1, //[12] + encrypted : 1, //[13] + retry : 1, //[14] + txbf_h_info : 1, //[15] + seq_num : 12, //[27:16] + encrypt_type : 4; //[31:28] + volatile uint32_t pn_31_0 : 32; //[31:0] + volatile uint32_t pn_47_32 : 16, //[15:0] + directed : 1, //[16] + reserved_2 : 11, //[27:17] + tid : 4; //[31:28] +}; + +struct rx_msdu_start { + volatile uint32_t msdu_length : 14, //[13:0] + ip_offset : 6, //[19:14] + ring_mask : 4, //[23:20] + tcp_udp_offset : 7, //[30:24] + reserved_0c : 1; //[31] + volatile uint32_t flow_id_crc : 32; //[31:0] + volatile uint32_t msdu_number : 8, //[7:0] + decap_format : 2, //[9:8] + ipv4_proto : 1, //[10] + ipv6_proto : 1, //[11] + tcp_proto : 1, //[12] + udp_proto : 1, //[13] + ip_frag : 1, //[14] + tcp_only_ack : 1, //[15] + sa_idx : 11, //[26:16] + reserved_2b : 5; //[31:27] +}; + +struct rx_msdu_end { + volatile uint32_t ip_hdr_chksum : 16, //[15:0] + tcp_udp_chksum : 16; //[31:16] + volatile uint32_t key_id_octet : 8, //[7:0] + classification_filter : 8, //[15:8] + ext_wapi_pn_63_48 : 16; //[31:16] + volatile uint32_t ext_wapi_pn_95_64 : 32; //[31:0] + volatile uint32_t ext_wapi_pn_127_96 : 32; //[31:0] + volatile uint32_t reported_mpdu_length : 14, //[13:0] + first_msdu : 1, //[14] + last_msdu : 1, //[15] + reserved_3a : 14, //[29:16] + pre_delim_err : 1, //[30] + reserved_3b : 1; //[31] +}; + +struct rx_mpdu_end { + volatile uint32_t reserved_0 : 13, //[12:0] + overflow_err : 1, //[13] + last_mpdu : 1, //[14] + post_delim_err : 1, //[15] + post_delim_cnt : 12, //[27:16] + mpdu_length_err : 1, //[28] + tkip_mic_err : 1, //[29] + decrypt_err : 1, //[30] + fcs_err : 1; //[31] +}; + +struct rx_ppdu_start { + volatile uint32_t rssi_chain0_pri20 : 8, //[7:0] + rssi_chain0_sec20 : 8, //[15:8] + rssi_chain0_sec40 : 8, //[23:16] + rssi_chain0_sec80 : 8; //[31:24] + volatile uint32_t rssi_chain1_pri20 : 8, //[7:0] + rssi_chain1_sec20 : 8, //[15:8] + rssi_chain1_sec40 : 8, //[23:16] + rssi_chain1_sec80 : 8; //[31:24] + volatile uint32_t rssi_chain2_pri20 : 8, //[7:0] + rssi_chain2_sec20 : 8, //[15:8] + rssi_chain2_sec40 : 8, //[23:16] + rssi_chain2_sec80 : 8; //[31:24] + volatile uint32_t rssi_chain3_pri20 : 8, //[7:0] + rssi_chain3_sec20 : 8, //[15:8] + rssi_chain3_sec40 : 8, //[23:16] + rssi_chain3_sec80 : 8; //[31:24] + volatile uint32_t rssi_comb : 8, //[7:0] + reserved_4a : 16, //[23:8] + is_greenfield : 1, //[24] + reserved_4b : 7; //[31:25] + volatile uint32_t l_sig_rate : 4, //[3:0] + l_sig_rate_select : 1, //[4] + l_sig_length : 12, //[16:5] + l_sig_parity : 1, //[17] + l_sig_tail : 6, //[23:18] + preamble_type : 8; //[31:24] + volatile uint32_t ht_sig_vht_sig_a_1 : 24, //[23:0] + reserved_6 : 8; //[31:24] + volatile uint32_t ht_sig_vht_sig_a_2 : 24, //[23:0] + txbf_h_info : 1, //[24] + reserved_7 : 7; //[31:25] + volatile uint32_t vht_sig_b : 29, //[28:0] + reserved_8 : 3; //[31:29] + volatile uint32_t service : 16, //[15:0] + reserved_9 : 16; //[31:16] +}; + +struct rx_ppdu_end { + volatile uint32_t evm_p0 : 32; //[31:0] + volatile uint32_t evm_p1 : 32; //[31:0] + volatile uint32_t evm_p2 : 32; //[31:0] + volatile uint32_t evm_p3 : 32; //[31:0] + volatile uint32_t evm_p4 : 32; //[31:0] + volatile uint32_t evm_p5 : 32; //[31:0] + volatile uint32_t evm_p6 : 32; //[31:0] + volatile uint32_t evm_p7 : 32; //[31:0] + volatile uint32_t evm_p8 : 32; //[31:0] + volatile uint32_t evm_p9 : 32; //[31:0] + volatile uint32_t evm_p10 : 32; //[31:0] + volatile uint32_t evm_p11 : 32; //[31:0] + volatile uint32_t evm_p12 : 32; //[31:0] + volatile uint32_t evm_p13 : 32; //[31:0] + volatile uint32_t evm_p14 : 32; //[31:0] + volatile uint32_t evm_p15 : 32; //[31:0] + volatile uint32_t tsf_timestamp : 32; //[31:0] + volatile uint32_t wb_timestamp : 32; //[31:0] + volatile uint32_t locationing_timestamp : 8, //[7:0] + phy_err_code : 8, //[15:8] + phy_err : 1, //[16] + rx_location : 1, //[17] + txbf_h_info : 1, //[18] + reserved_18 : 13; //[31:19] + volatile uint32_t rx_antenna : 24, //[23:0] + tx_ht_vht_ack : 1, //[24] + bb_captured_channel : 1, //[25] + reserved_19 : 6; //[31:26] + volatile uint32_t rtt_correction_value : 24, //[23:0] + reserved_20 : 7, //[30:24] + rtt_normal_mode : 1; //[31] + volatile uint32_t bb_length : 16, //[15:0] + reserved_21 : 15, //[30:16] + ppdu_done : 1; //[31] +}; + +#endif /*_RX_DESC_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c new file mode 100644 index 0000000000000..bf16c031cb92b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -0,0 +1,2585 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "vos_sched.h" +#include "wlan_qct_tl.h" +#include "wdi_in.h" +#include "ol_txrx_peer_find.h" +#include "tl_shim.h" +#include "wma.h" +#include "wmi_unified_api.h" +#include "vos_packet.h" +#include "vos_memory.h" +#include "adf_os_types.h" +#include "adf_nbuf.h" +#include "adf_os_mem.h" +#include "adf_os_lock.h" +#include "adf_nbuf.h" +#include "wma_api.h" +#include "vos_utils.h" +#include "wdi_out.h" + +#define TLSHIM_PEER_AUTHORIZE_WAIT 10 + +#define ENTER() VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__) + +#define TLSHIM_LOGD(args...) \ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, ## args) +#define TLSHIM_LOGW(args...) \ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, ## args) +#define TLSHIM_LOGE(args...) \ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, ## args) +#define TLSHIM_LOGP(args...) \ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, ## args) + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + +/************************/ +/* Internal defines */ +/************************/ +#define SIZEOF_80211_HDR (sizeof(struct ieee80211_frame)) +#define LLC_SNAP_SIZE 8 + +/* Cisco Aironet SNAP hdr */ +static u_int8_t AIRONET_SNAP_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, + 0x96, 0x00, 0x00 }; + +/* + * @brief: Creates vos_pkt_t for IAPP packet and routes them to PE/LIM. + * @detail: This function will be executed by new deferred task. It calls + * in the function to process and route IAPP frame. After IAPP + * has been processed, it will free the passed adb_nbuf_t pointer. + * This function will run in non interrupt context + * @param: ptr_work - pointer to work struct containing passed parameters + * from calling function. + */ +void +tlshim_mgmt_over_data_rx_handler(struct work_struct *ptr_work) +{ + struct deferred_iapp_work *ptr_my_work + = container_of(ptr_work, struct deferred_iapp_work, deferred_work); + pVosContextType pVosGCtx = ptr_my_work->pVosGCtx; + u_int8_t *data = adf_nbuf_data(ptr_my_work->nbuf); + u_int32_t data_len = adf_nbuf_len(ptr_my_work->nbuf); + struct ol_txrx_vdev_t *vdev = ptr_my_work->vdev; + + /* + * data : is a either data starting from snap hdr or 802.11 frame + * data_len : length of above data + */ + + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + pVosGCtx); + vos_pkt_t *rx_pkt; + adf_nbuf_t wbuf; + struct ieee80211_frame *wh; + + if (!tl_shim->mgmt_rx) { + TLSHIM_LOGE("Not registered for Mgmt rx, dropping the frame"); + /* this buffer is used now, free it */ + adf_nbuf_free(ptr_my_work->nbuf); + /* set inUse to false, so that next IAPP frame can be processed */ + ptr_my_work->inUse = false; + return; + } + + /* + * allocate rx_packet: this will be used for encapsulating a + * sk_buff which then is passed to peHandleMgmtFrame(ptr fn) + * along with vos_ctx. + */ + rx_pkt = vos_mem_malloc(sizeof(*rx_pkt)); + if (!rx_pkt) { + TLSHIM_LOGE("Failed to allocate rx packet"); + /* this buffer is used now, free it */ + adf_nbuf_free(ptr_my_work->nbuf); + /* set inUse to false, so that next IAPP frame can be processed */ + ptr_my_work->inUse = false; + return; + } + + vos_mem_zero(rx_pkt, sizeof(*rx_pkt)); + + /* + * TODO: also check if following is used for IAPP + * if yes, find out how to populate this + * rx_pkt->pkt_meta.channel = 0; + */ + rx_pkt->pkt_meta.snr = rx_pkt->pkt_meta.rssi = 0; + + rx_pkt->pkt_meta.timestamp = (u_int32_t) jiffies; + rx_pkt->pkt_meta.mpdu_hdr_len = SIZEOF_80211_HDR; + + /* + * mpdu len and data len will be different for native and non native + * format + */ + if (vdev->pdev->frame_format == wlan_frm_fmt_native_wifi) { + rx_pkt->pkt_meta.mpdu_len = data_len; + rx_pkt->pkt_meta.mpdu_data_len = data_len - + rx_pkt->pkt_meta.mpdu_hdr_len; + } + else { + rx_pkt->pkt_meta.mpdu_len = data_len + + rx_pkt->pkt_meta.mpdu_hdr_len - ETHERNET_HDR_LEN; + rx_pkt->pkt_meta.mpdu_data_len = data_len - ETHERNET_HDR_LEN; + } + + /* allocate a sk_buff with enough memory for 802.11 IAPP frame */ + wbuf = adf_nbuf_alloc(NULL, roundup(rx_pkt->pkt_meta.mpdu_len, 4), + 0, 4, FALSE); + if (!wbuf) { + TLSHIM_LOGE("Failed to allocate wbuf for mgmt rx"); + vos_mem_free(rx_pkt); + /* this buffer is used now, free it */ + adf_nbuf_free(ptr_my_work->nbuf); + /* set inUse to false, so that next IAPP frame can be processed */ + ptr_my_work->inUse = false; + return; + } + + adf_nbuf_put_tail(wbuf, data_len); + adf_nbuf_set_protocol(wbuf, ETH_P_SNAP); + + /* wh will contain 802.11 frame, it will be encpsulated inside sk_buff */ + wh = (struct ieee80211_frame *) adf_nbuf_data(wbuf); + + /* set mpdu hdr pointre to data of sk_buff */ + rx_pkt->pkt_meta.mpdu_hdr_ptr = adf_nbuf_data(wbuf); + /* set mpdu data pointer to appropriate offset from hdr */ + rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr + + rx_pkt->pkt_meta.mpdu_hdr_len; + /* encapsulate newly allocated sk_buff in rx_pkt */ + rx_pkt->pkt_buf = wbuf; + + if (vdev->pdev->frame_format == wlan_frm_fmt_native_wifi) { + /* if native wifi: copy full frame */ + adf_os_mem_copy(wh, data, data_len); + } + else { + /* + * if not native wifi populate: copy just part after 802.11 hdr + * i.e. part starting from snap header + */ + tpEseIappHdr iapp_hdr_ptr = (tpEseIappHdr)&data[ETHERNET_HDR_LEN]; + u_int8_t *snap_hdr_ptr = &(((u_int8_t*)wh)[SIZEOF_80211_HDR]); + tpSirMacFrameCtl ptr_80211_FC = (tpSirMacFrameCtl)&wh->i_fc; + ptr_80211_FC->protVer = SIR_MAC_PROTOCOL_VERSION; + ptr_80211_FC->type = SIR_MAC_DATA_FRAME; + ptr_80211_FC->subType = SIR_MAC_DATA_QOS_DATA; + ptr_80211_FC->toDS = 0; + ptr_80211_FC->fromDS = 1; + ptr_80211_FC->moreFrag = 0; + ptr_80211_FC->retry = 0; + ptr_80211_FC->powerMgmt = 0; + ptr_80211_FC->moreData = 0; + ptr_80211_FC->wep = 0; + ptr_80211_FC->order = 0; + + wh->i_dur[0] = 0; + wh->i_dur[1] = 0; + + adf_os_mem_copy(&wh->i_addr1, &iapp_hdr_ptr->DestMac[0], + ETHERNET_ADDR_LEN); + adf_os_mem_copy(&wh->i_addr2, &iapp_hdr_ptr->SrcMac[0], + ETHERNET_ADDR_LEN); + adf_os_mem_copy(&wh->i_addr3, &vdev->last_real_peer->mac_addr.raw[0], + ETHERNET_ADDR_LEN); + + wh->i_seq[0] = 0; + wh->i_seq[1] = 0; + + adf_os_mem_copy( snap_hdr_ptr, &data[ETHERNET_HDR_LEN], + data_len - ETHERNET_HDR_LEN); + } + + tl_shim->mgmt_rx(pVosGCtx, rx_pkt); + /* this buffer is used now, free it */ + adf_nbuf_free(ptr_my_work->nbuf); + /* set inUse to false, so that next IAPP frame can be processed */ + ptr_my_work->inUse = false; +} + +/* + * @brief: This function creates the deferred task and schedules it. this is + * still in interrrupt context. The deferred task is created to run + * in non interrut context as a memory allocation of vos_pkt_t is + * needed and memory allocation should not be done in interrupt + * context. + * @param - pVosGCtx - vos context + * @param - data - data containing ieee80211 IAPP frame + * @param - data_len - data len containing ieee80211 IAPP frame + * @param - vdev - virtual device + */ +void +tlshim_mgmt_over_data_rx_handler_non_interrupt_ctx(pVosContextType pVosGCtx, + adf_nbuf_t nbuf, struct ol_txrx_vdev_t *vdev) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + pVosGCtx); + + /* + * if there is already a deferred IAPP processing, do not start + * another. Instead drop it as IAPP frames are not critical and + * can be dropped without any disruptive effects. + */ + if(tl_shim->iapp_work.inUse == false) { + tl_shim->iapp_work.pVosGCtx = pVosGCtx; + tl_shim->iapp_work.nbuf = nbuf; + tl_shim->iapp_work.vdev = vdev; + tl_shim->iapp_work.inUse = true; + schedule_work(&(tl_shim->iapp_work.deferred_work)); + return; + } + + /* Previous IAPP frame is not yet processed, drop this frame */ + TLSHIM_LOGE("Dropping IAPP frame because previous is yet unprocessed"); + /* + * TODO: If needed this can changed to have queue rather + * than drop frame + */ + adf_nbuf_free(nbuf); + return; +} + +/* + * @brief: This checks if frame is IAPP and if yes routes them to PE/LIM + * @param - pVosGCtx - vos context + * @param - msdu - frame + * @param - sta_id - station ID + */ +bool +tlshim_check_n_process_iapp_frame (pVosContextType pVosGCtx, + adf_nbuf_t *msdu, u_int16_t sta_id) +{ + u_int8_t *data; + u_int8_t offset_snap_header; + struct ol_txrx_pdev_t *pdev = pVosGCtx->pdev_txrx_ctx; + struct ol_txrx_peer_t *peer = + ol_txrx_peer_find_by_local_id(pVosGCtx->pdev_txrx_ctx, sta_id); + struct ol_txrx_vdev_t *vdev = peer->vdev; + adf_nbuf_t new_head = NULL, buf, new_list = NULL, next_buf; + + /* frame format is natve wifi */ + if(pdev->frame_format == wlan_frm_fmt_native_wifi) + offset_snap_header = SIZEOF_80211_HDR; + else + offset_snap_header = ETHERNET_HDR_LEN; + + buf = *msdu; + while (buf) { + data = adf_nbuf_data(buf); + next_buf = adf_nbuf_queue_next(buf); + if (vos_mem_compare( &data[offset_snap_header], + &AIRONET_SNAP_HEADER[0], LLC_SNAP_SIZE) == VOS_TRUE) { + /* process IAPP frames */ + tlshim_mgmt_over_data_rx_handler_non_interrupt_ctx(pVosGCtx, + buf, vdev); + } else { /* Add the packet onto a new list */ + if (new_list == NULL) + new_head = buf; + else + adf_nbuf_set_next(new_list, buf); + new_list = buf; + adf_nbuf_set_next(buf, NULL); + } + buf = next_buf; + } + + if (!new_list) + return true; + + *msdu = new_head; + /* if returned false the packet will be handled by the upper layer */ + return false; +} +#endif /* defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) */ + + +/*AR9888/AR6320 noise floor approx value*/ +#define TLSHIM_TGT_NOISE_FLOOR_DBM (-96) + +#ifdef WLAN_FEATURE_11W + +/* + * @brief - This routine will find the iface based on vdev id of provided bssid + * @param - vos_ctx - vos context + * @param - mac_addr - bss MAC address of received frame + * @param - vdev_id - virtual device id + */ +static struct wma_txrx_node* +tlshim_mgmt_find_iface(void *vos_ctx, u_int8_t *mac_addr, u_int32_t *vdev_id) +{ + struct ol_txrx_vdev_t *vdev = NULL; + struct wma_txrx_node *iface = NULL; + tp_wma_handle wma = NULL; + + wma = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (wma) { + /* + * Based on received frame's bssid, we will try to + * retrieve the vdev id. If we find the vdev then we will + * override with found vdev_id else we will use supplied + * vdev_id + */ + vdev = tl_shim_get_vdev_by_addr(vos_ctx, mac_addr); + if (vdev) { + *vdev_id = vdev->vdev_id; + } + iface = &wma->interfaces[*vdev_id]; + } + return iface; +} + +/* + * @brief - This routine will extract 6 byte PN from the CCMP header + * @param - ccmp_ptr - pointer to ccmp header + */ +static u_int64_t +tl_shim_extract_ccmp_pn(u_int8_t *ccmp_ptr) +{ + u_int8_t rsvd, key, pn[6]; + u_int64_t new_pn; + + /* + * +-----+-----+------+----------+-----+-----+-----+-----+ + * | PN0 | PN1 | rsvd | rsvd/key | PN2 | PN3 | PN4 | PN5 | + * +-----+-----+------+----------+-----+-----+-----+-----+ + * CCMP Header Format + */ + + /* Extract individual bytes */ + pn[0] = (u_int8_t)*ccmp_ptr; + pn[1] = (u_int8_t)*(ccmp_ptr+1); + rsvd = (u_int8_t)*(ccmp_ptr+2); + key = (u_int8_t)*(ccmp_ptr+3); + pn[2] = (u_int8_t)*(ccmp_ptr+4); + pn[3] = (u_int8_t)*(ccmp_ptr+5); + pn[4] = (u_int8_t)*(ccmp_ptr+6); + pn[5] = (u_int8_t)*(ccmp_ptr+7); + + /* Form 6 byte PN with 6 individual bytes of PN */ + new_pn = ((uint64_t)pn[5] << 40) | + ((uint64_t)pn[4] << 32) | + ((uint64_t)pn[3] << 24) | + ((uint64_t)pn[2] << 16) | + ((uint64_t)pn[1] << 8) | + ((uint64_t)pn[0] << 0); + + TLSHIM_LOGD("PN of received packet is %llu", new_pn); + return new_pn; +} + +/* + * @brief - This routine is used to detect replay attacking using PN in CCMP + * @param - vos_ctx - vos context + * @param - wh - frame header + * @param - ccmp_ptr - pointer to ccmp header + */ +static bool +is_ccmp_pn_replay_attack(void *vos_ctx, struct ieee80211_frame *wh, + u_int8_t *ccmp_ptr) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + u_int8_t peer_id; + u_int8_t *last_pn_valid; + u_int64_t *last_pn, new_pn; + u_int32_t *rmf_pn_replays; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_ctx); + if (!pdev) { + TLSHIM_LOGE("%s: Failed to find pdev", __func__); + TLSHIM_LOGE("%s: Not able to validate PN", __func__); + return true; + } + + vdev = tl_shim_get_vdev_by_addr(vos_ctx, wh->i_addr2); + if (!vdev) { + TLSHIM_LOGE("%s: Failed to find vdev", __func__); + TLSHIM_LOGE("%s: Not able to validate PN", __func__); + return true; + } + + /* Retrieve the peer based on vdev and addr */ + peer = ol_txrx_find_peer_by_addr_and_vdev(pdev, vdev, wh->i_addr2, + &peer_id); + + if (NULL == peer) { + TLSHIM_LOGE( + "%s: Failed to find peer, Not able to validate PN", __func__); + return true; + } + + new_pn = tl_shim_extract_ccmp_pn(ccmp_ptr); + last_pn_valid = &peer->last_rmf_pn_valid; + last_pn = &peer->last_rmf_pn; + rmf_pn_replays = &peer->rmf_pn_replays; + + if (*last_pn_valid) { + if (new_pn > *last_pn) { + *last_pn = new_pn; + TLSHIM_LOGD("%s: PN validation successful", __func__); + } else { + TLSHIM_LOGE("%s: PN Replay attack detected", __func__); + /* per 11W amendment, keeping track of replay attacks */ + *rmf_pn_replays += 1; + return true; + } + } else { + *last_pn_valid = 1; + *last_pn = new_pn; + } + + return false; +} +#endif + +static int tlshim_mgmt_rx_process(void *context, u_int8_t *data, + u_int32_t data_len, bool saved_beacon, u_int32_t vdev_id) +{ + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL); + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); +#ifdef FEATURE_WLAN_D0WOW + tp_wma_handle wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); +#endif + WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL; + wmi_mgmt_rx_hdr *hdr = NULL; +#ifdef WLAN_FEATURE_11W + struct wma_txrx_node *iface = NULL; + u_int8_t *efrm, *orig_hdr; + u_int16_t key_id; + u_int8_t *ccmp; +#endif /* WLAN_FEATURE_11W */ + + vos_pkt_t *rx_pkt; + adf_nbuf_t wbuf; + struct ieee80211_frame *wh; + u_int8_t mgt_type, mgt_subtype; + + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return 0; + } + +#ifdef FEATURE_WLAN_D0WOW + if (!wma_handle) { + TLSHIM_LOGE("%s: Failed to get WMA context!", __func__); + return 0; + } +#endif + + param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) data; + if (!param_tlvs) { + TLSHIM_LOGE("Get NULL point message from FW"); + return 0; + } + + hdr = param_tlvs->hdr; + if (!hdr) { + TLSHIM_LOGE("Rx event is NULL"); + return 0; + } + + if (hdr->buf_len < sizeof(struct ieee80211_frame)) { + TLSHIM_LOGE("Invalid rx mgmt packet"); + return 0; + } + + rx_pkt = vos_mem_malloc(sizeof(*rx_pkt)); + if (!rx_pkt) { + TLSHIM_LOGE("Failed to allocate rx packet"); + return 0; + } + + vos_mem_zero(rx_pkt, sizeof(*rx_pkt)); + + /* + * Fill in meta information needed by pe/lim + * TODO: Try to maintain rx metainfo as part of skb->data. + */ + rx_pkt->pkt_meta.channel = hdr->channel; + rx_pkt->pkt_meta.scan_src = hdr->flags; + + /* Get the rssi value from the current snr value + * using standard noise floor of -96. + */ + rx_pkt->pkt_meta.rssi = hdr->snr + TLSHIM_TGT_NOISE_FLOOR_DBM; + rx_pkt->pkt_meta.snr = hdr->snr; + + /* If absolute rssi is available from firmware, use it */ + if (hdr->rssi != 0) + rx_pkt->pkt_meta.rssi_raw = hdr->rssi; + else + rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi; + + /* + * FIXME: Assigning the local timestamp as hw timestamp is not + * available. Need to see if pe/lim really uses this data. + */ + rx_pkt->pkt_meta.timestamp = (u_int32_t) jiffies; + rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame); + rx_pkt->pkt_meta.mpdu_len = hdr->buf_len; + rx_pkt->pkt_meta.mpdu_data_len = hdr->buf_len - + rx_pkt->pkt_meta.mpdu_hdr_len; + + /* + * saved_beacon means this beacon is a duplicate of one + * sent earlier. roamCandidateInd flag is used to indicate to + * PE that roam scan finished and a better candidate AP + * was found. + */ + rx_pkt->pkt_meta.roamCandidateInd = saved_beacon ? 1 : 0; + rx_pkt->pkt_meta.sessionId = vdev_id; + /* Why not just use rx_event->hdr.buf_len? */ + wbuf = adf_nbuf_alloc(NULL, + roundup(hdr->buf_len, 4), + 0, 4, FALSE); + if (!wbuf) { + TLSHIM_LOGE("%s: Failed to allocate wbuf for mgmt rx len(%u)", + __func__, hdr->buf_len); + vos_mem_free(rx_pkt); + return 0; + } + + adf_nbuf_put_tail(wbuf, hdr->buf_len); + adf_nbuf_set_protocol(wbuf, ETH_P_CONTROL); + wh = (struct ieee80211_frame *) adf_nbuf_data(wbuf); + + rx_pkt->pkt_meta.mpdu_hdr_ptr = adf_nbuf_data(wbuf); + rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr + + rx_pkt->pkt_meta.mpdu_hdr_len; + rx_pkt->pkt_buf = wbuf; + +#ifdef BIG_ENDIAN_HOST + { + /* + * for big endian host, copy engine byte_swap is enabled + * But the rx mgmt frame buffer content is in network byte order + * Need to byte swap the mgmt frame buffer content - so when + * copy engine does byte_swap - host gets buffer content in the + * correct byte order. + */ + int i; + u_int32_t *destp, *srcp; + destp = (u_int32_t *) wh; + srcp = (u_int32_t *) param_tlvs->bufp; + for (i = 0; + i < (roundup(hdr->buf_len, sizeof(u_int32_t)) / 4); + i++) { + *destp = cpu_to_le32(*srcp); + destp++; srcp++; + } + } +#else + adf_os_mem_copy(wh, param_tlvs->bufp, hdr->buf_len); +#endif + + TLSHIM_LOGD( + "%s: BSSID: "MAC_ADDRESS_STR" snr = %d, rssi = %d, rssi_raw = %d", + __func__, MAC_ADDR_ARRAY(wh->i_addr3), + hdr->snr, rx_pkt->pkt_meta.rssi, + rx_pkt->pkt_meta.rssi_raw); + + if (!tl_shim->mgmt_rx) { + TLSHIM_LOGE("Not registered for Mgmt rx, dropping the frame"); + vos_pkt_return_packet(rx_pkt); + return 0; + } + + /* If it is a beacon/probe response, save it for future use */ + mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + +#ifdef FEATURE_WLAN_D0WOW + if (wma_read_d0wow_flag(wma_handle)) { + TLSHIM_LOGE("%s: Frame subtype is 0x%x", __func__, mgt_subtype); + wma_set_d0wow_flag(wma_handle, FALSE); + } +#endif + + if (!saved_beacon && mgt_type == IEEE80211_FC0_TYPE_MGT && + (mgt_subtype == IEEE80211_FC0_SUBTYPE_BEACON || mgt_subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + { + /* remember this beacon to be used later for better_ap event */ + WMI_MGMT_RX_EVENTID_param_tlvs *last_tlvs = + (WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data; + if (tl_shim->last_beacon_data) { + /* Free the previously allocated buffers */ + if (last_tlvs->hdr) + vos_mem_free(last_tlvs->hdr); + if (last_tlvs->bufp) + vos_mem_free(last_tlvs->bufp); + vos_mem_free(tl_shim->last_beacon_data); + tl_shim->last_beacon_data = NULL; + tl_shim->last_beacon_len = 0; + } + if((tl_shim->last_beacon_data = vos_mem_malloc(sizeof(WMI_MGMT_RX_EVENTID_param_tlvs)))) { + u_int32_t buf_len = roundup(hdr->buf_len, sizeof(u_int32_t)); + + vos_mem_copy(tl_shim->last_beacon_data, data, sizeof(WMI_MGMT_RX_EVENTID_param_tlvs)); + tl_shim->last_beacon_len = sizeof(WMI_MGMT_RX_EVENTID_param_tlvs); + last_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data; + if ((last_tlvs->hdr = vos_mem_malloc(sizeof(wmi_mgmt_rx_hdr)))) { + vos_mem_copy(last_tlvs->hdr, hdr, sizeof(wmi_mgmt_rx_hdr)); + if ((last_tlvs->bufp = vos_mem_malloc(buf_len))) { + vos_mem_copy(last_tlvs->bufp, param_tlvs->bufp, buf_len); + } else { + vos_mem_free(last_tlvs->hdr); + vos_mem_free(tl_shim->last_beacon_data); + tl_shim->last_beacon_data = NULL; + tl_shim->last_beacon_len = 0; + } + } else { + vos_mem_free(tl_shim->last_beacon_data); + tl_shim->last_beacon_data = NULL; + tl_shim->last_beacon_len = 0; + } + } + } + +#ifdef WLAN_FEATURE_11W + if (mgt_type == IEEE80211_FC0_TYPE_MGT && + (mgt_subtype == IEEE80211_FC0_SUBTYPE_DISASSOC || + mgt_subtype == IEEE80211_FC0_SUBTYPE_DEAUTH || + mgt_subtype == IEEE80211_FC0_SUBTYPE_ACTION)) + { + iface = tlshim_mgmt_find_iface(vos_ctx, wh->i_addr3, &vdev_id); + if (iface && iface->rmfEnabled) + { + if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) + { + if (IEEE80211_IS_BROADCAST(wh->i_addr1) || + IEEE80211_IS_MULTICAST(wh->i_addr1)) { + TLSHIM_LOGE("Encrypted BC/MC frame" + " dropping the frame"); + vos_pkt_return_packet(rx_pkt); + return 0; + } + + orig_hdr = (u_int8_t*) adf_nbuf_data(wbuf); + /* Pointer to head of CCMP header */ + ccmp = orig_hdr + sizeof(*wh); + if (is_ccmp_pn_replay_attack(vos_ctx, wh, + ccmp)) { + TLSHIM_LOGE("Dropping the frame"); + vos_pkt_return_packet(rx_pkt); + return 0; + } + + /* Strip privacy headers (and trailer) + for a received frame */ + vos_mem_move(orig_hdr + IEEE80211_CCMP_HEADERLEN, + wh, sizeof(*wh)); + adf_nbuf_pull_head(wbuf, IEEE80211_CCMP_HEADERLEN); + adf_nbuf_trim_tail(wbuf, IEEE80211_CCMP_MICLEN); + + rx_pkt->pkt_meta.mpdu_hdr_ptr = adf_nbuf_data(wbuf); + rx_pkt->pkt_meta.mpdu_len = adf_nbuf_len(wbuf); + rx_pkt->pkt_meta.mpdu_data_len = + rx_pkt->pkt_meta.mpdu_len - + rx_pkt->pkt_meta.mpdu_hdr_len; + rx_pkt->pkt_meta.mpdu_data_ptr = + rx_pkt->pkt_meta.mpdu_hdr_ptr + + rx_pkt->pkt_meta.mpdu_hdr_len; + rx_pkt->pkt_buf = wbuf; + } + else + { + if (IEEE80211_IS_BROADCAST(wh->i_addr1) || + IEEE80211_IS_MULTICAST(wh->i_addr1)) + { + efrm = adf_nbuf_data(wbuf) + adf_nbuf_len(wbuf); + + key_id = (u_int16_t)*(efrm - vos_get_mmie_size() + 2); + if (!((key_id == WMA_IGTK_KEY_INDEX_4) || + (key_id == WMA_IGTK_KEY_INDEX_5))) { + TLSHIM_LOGE("Invalid KeyID(%d)" + " dropping the frame", key_id); + vos_pkt_return_packet(rx_pkt); + return 0; + } + + if (vos_is_mmie_valid(iface->key.key, + iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn, + (u_int8_t *)wh, efrm)) + { + TLSHIM_LOGD("Protected BC/MC frame MMIE" + " validation successful"); + + /* Remove MMIE */ + adf_nbuf_trim_tail(wbuf, + vos_get_mmie_size()); + } + else + { + TLSHIM_LOGE("BC/MC MIC error or MMIE" + " not present, dropping the frame"); + vos_pkt_return_packet(rx_pkt); + return 0; + } + } + else + { + TLSHIM_LOGD("Rx unprotected unicast mgmt frame"); + rx_pkt->pkt_meta.dpuFeedback = + DPU_FEEDBACK_UNPROTECTED_ERROR; + } + + } + } + } +#endif /* WLAN_FEATURE_11W */ + return tl_shim->mgmt_rx(vos_ctx, rx_pkt); +} + +static int tlshim_mgmt_rx_wmi_handler(void *context, u_int8_t *data, + u_int32_t data_len) +{ + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL); + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + VOS_STATUS ret = VOS_STATUS_SUCCESS; + + if (vos_is_logp_in_progress(VOS_MODULE_ID_TL, NULL)) { + TLSHIM_LOGE("%s: LOPG in progress\n", __func__); + return (-1); + } + + adf_os_spin_lock_bh(&tl_shim->mgmt_lock); + ret = tlshim_mgmt_rx_process(context, data, data_len, FALSE, 0); + adf_os_spin_unlock_bh(&tl_shim->mgmt_lock); + + return ret; +} +/* + * tlshim_mgmt_roam_event_ind() is called from WMA layer when + * BETTER_AP_FOUND event is received from roam engine. + */ +int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id) +{ + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL); + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + VOS_STATUS ret = VOS_STATUS_SUCCESS; + + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return ret; + } + + if (tl_shim->last_beacon_data && tl_shim->last_beacon_len) + { + adf_os_spin_lock_bh(&tl_shim->mgmt_lock); + ret = tlshim_mgmt_rx_process(context, tl_shim->last_beacon_data, tl_shim->last_beacon_len, TRUE, vdev_id); + adf_os_spin_unlock_bh(&tl_shim->mgmt_lock); + } + return ret; +} + +static void tl_shim_flush_rx_frames(void *vos_ctx, + struct txrx_tl_shim_ctx *tl_shim, + u_int8_t sta_id, bool drop) +{ + struct tlshim_sta_info *sta_info = &tl_shim->sta_info[sta_id]; + struct tlshim_buf *cache_buf, *tmp; + VOS_STATUS ret; + WLANTL_STARxCBType data_rx = NULL; + + if (test_and_set_bit(TLSHIM_FLUSH_CACHE_IN_PROGRESS, &sta_info->flags)) + return; + + adf_os_spin_lock_bh(&sta_info->stainfo_lock); + if (sta_info->registered) + data_rx = sta_info->data_rx; + else + drop = true; + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + list_for_each_entry_safe(cache_buf, tmp, + &sta_info->cached_bufq, list) { + list_del(&cache_buf->list); + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + if (drop) + adf_nbuf_free(cache_buf->buf); + else { + /* Flush the cached frames to HDD */ + ret = data_rx(vos_ctx, cache_buf->buf, sta_id); + if (ret != VOS_STATUS_SUCCESS) + adf_nbuf_free(cache_buf->buf); + } + adf_os_mem_free(cache_buf); + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + } + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + clear_bit(TLSHIM_FLUSH_CACHE_IN_PROGRESS, &sta_info->flags); +} + +static void tlshim_data_rx_cb(struct txrx_tl_shim_ctx *tl_shim, + adf_nbuf_t buf_list, u_int16_t staid) +{ + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, tl_shim); + struct tlshim_sta_info *sta_info; + adf_nbuf_t buf, next_buf; + VOS_STATUS ret; + WLANTL_STARxCBType data_rx = NULL; + + if (unlikely(!vos_ctx)) + goto free_buf; + + sta_info = &tl_shim->sta_info[staid]; + adf_os_spin_lock_bh(&sta_info->stainfo_lock); + if (unlikely(!sta_info->registered)) { + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + goto free_buf; + } + data_rx = sta_info->data_rx; + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + if (!list_empty(&sta_info->cached_bufq)) { + sta_info->suspend_flush = 1; + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + /* Flush the cached frames to HDD before passing new rx frame */ + tl_shim_flush_rx_frames(vos_ctx, tl_shim, staid, 0); + } else + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + + ret = data_rx(vos_ctx, buf_list, staid); + if (ret != VOS_STATUS_SUCCESS) { + TLSHIM_LOGE("Frame Rx to HDD failed"); + goto free_buf; + } + return; + +free_buf: + TLSHIM_LOGW("%s:Dropping frames", __func__); + buf = buf_list; + while (buf) { + next_buf = adf_nbuf_queue_next(buf); + adf_nbuf_free(buf); + buf = next_buf; + } +} + +/* + * Rx callback from txrx module for data reception. + */ +static void tlshim_data_rx_handler(void *context, u_int16_t staid, + adf_nbuf_t rx_buf_list) +{ + struct txrx_tl_shim_ctx *tl_shim; + /* Firmware data path active response will use shim RX thread + * T2H MSG running on SIRQ context, + * IPA kernel module API should not be called on SIRQ CTXT */ +#if (defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD))|| \ + (defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)) + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, context); +#endif + struct tlshim_sta_info *sta_info; + adf_nbuf_t buf, next_buf; + WLANTL_STARxCBType data_rx = NULL; + + if (staid >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id :%d", staid); + goto drop_rx_buf; + } + + tl_shim = (struct txrx_tl_shim_ctx *) context; + sta_info = &tl_shim->sta_info[staid]; + + adf_os_spin_lock_bh(&sta_info->stainfo_lock); + if (sta_info->registered) + data_rx = sta_info->data_rx; + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + + /* + * If there is a data frame from peer before the peer is + * registered for data service, enqueue them on to pending queue + * which will be flushed to HDD once that station is registered. + */ + if (!data_rx) { + struct tlshim_buf *cache_buf; + buf = rx_buf_list; + while (buf) { + next_buf = adf_nbuf_queue_next(buf); + cache_buf = adf_os_mem_alloc(NULL, sizeof(*cache_buf)); + if (!cache_buf) { + TLSHIM_LOGE("Failed to allocate buf to cache the rx frames"); + adf_nbuf_free(buf); + } else { + /* Add NULL terminator */ + adf_nbuf_set_next(buf, NULL); + cache_buf->buf = buf; + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + list_add_tail(&cache_buf->list, + &sta_info->cached_bufq); + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + } + buf = next_buf; + } + } else { /* Send rx packet to HDD if there is no frame pending in cached_bufq */ + /* Suspend frames flush from timer */ + /* + * TODO: Need to see if acquiring/releasing lock even when + * there is no cached frames have any significant impact on + * performance. + */ +#if defined (IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + VOS_STATUS ret; + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + sta_info->suspend_flush = 1; + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + + /* Flush the cached frames to HDD before passing new rx frame */ + tl_shim_flush_rx_frames(vos_ctx, tl_shim, staid, 0); + + if (!adf_os_atomic_read(&tl_shim->vdev_active[sta_info->vdev_id])) { + TLSHIM_LOGW("INACTIVE VDEV"); + goto drop_rx_buf; + } + ret = data_rx(vos_ctx, rx_buf_list, staid); + if (ret == VOS_STATUS_E_INVAL) { +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + /* + * in case following returns true, a defered task was created + * inside function, which does following: + * 1) create vos packet + * 2) send to PE/LIM + * 3) free the involved sk_buff + */ + if (tlshim_check_n_process_iapp_frame(vos_ctx, + &rx_buf_list, staid)) + return; + + /* + * above returned false, the packet was not IAPP. + * process normally + */ +#endif +#ifdef QCA_CONFIG_SMP + /* + * If the kernel is SMP, schedule rx thread to + * better use multicores. + */ + if (!tl_shim->enable_rxthread) { + tlshim_data_rx_cb(tl_shim, rx_buf_list, staid); + } else { + pVosSchedContext sched_ctx = + get_vos_sched_ctxt(); + struct VosTlshimPkt *pkt; + + if (unlikely(!sched_ctx)) + goto drop_rx_buf; + + pkt = vos_alloc_tlshim_pkt(sched_ctx); + if (!pkt) { + TLSHIM_LOGW("No available Rx message buffer"); + goto drop_rx_buf; + } + pkt->callback = (vos_tlshim_cb) + tlshim_data_rx_cb; + pkt->context = (void *) tl_shim; + pkt->Rxpkt = (void *) rx_buf_list; + pkt->staId = staid; + vos_indicate_rxpkt(sched_ctx, pkt); + } +#else /* QCA_CONFIG_SMP */ + tlshim_data_rx_cb(tl_shim, rx_buf_list, staid); +#endif /* QCA_CONFIG_SMP */ +#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + } +#endif + } + + return; + +drop_rx_buf: + TLSHIM_LOGW("Dropping rx packets"); + buf = rx_buf_list; + while (buf) { + next_buf = adf_nbuf_queue_next(buf); + adf_nbuf_free(buf); + buf = next_buf; + } +} + +static void tl_shim_cache_flush_work(struct work_struct *work) +{ + struct txrx_tl_shim_ctx *tl_shim = container_of(work, + struct txrx_tl_shim_ctx, cache_flush_work); + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL); + struct tlshim_sta_info *sta_info; + u_int8_t i; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + sta_info = &tl_shim->sta_info[i]; + adf_os_spin_lock_bh(&sta_info->stainfo_lock); + if (!sta_info->registered) { + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + continue; + } + + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + if (sta_info->suspend_flush) { + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + continue; + } + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + + tl_shim_flush_rx_frames(vos_ctx, tl_shim, i, 0); + } +} + +/*************************/ +/* TL APIs */ +/*************************/ + +/* + * TL API called from WMA to register a vdev for data service with + * txrx. This API is called once vdev create succeeds. + */ +void WLANTL_RegisterVdev(void *vos_ctx, void *vdev) +{ + struct txrx_tl_shim_ctx *tl_shim; + struct ol_txrx_osif_ops txrx_ops; + struct ol_txrx_vdev_t *vdev_handle = (struct ol_txrx_vdev_t *) vdev; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return; + } + +#ifdef QCA_LL_TX_FLOW_CT + txrx_ops.tx.flow_control_cb = WLANTL_TXFlowControlCb; + tl_shim->session_flow_control[vdev_handle->vdev_id].vdev = vdev; +#endif /* QCA_LL_TX_FLOW_CT */ + txrx_ops.rx.std = tlshim_data_rx_handler; + wdi_in_osif_vdev_register(vdev_handle, tl_shim, &txrx_ops); + /* TODO: Keep vdev specific tx callback, if needed */ + tl_shim->tx = txrx_ops.tx.std; + adf_os_atomic_set(&tl_shim->vdev_active[vdev_handle->vdev_id], 1); +} + +/* + * TL API called from WMA to un-register a vdev for data service with + * txrx. This API is called once vdev delete. + */ +void WLANTL_UnRegisterVdev(void *vos_ctx, u_int8_t vdev_id) +{ + struct txrx_tl_shim_ctx *tl_shim; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return; + } + + adf_os_atomic_set(&tl_shim->vdev_active[vdev_id], 0); +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_DeRegisterTXFlowControl(vos_ctx, vdev_id); +#endif /* QCA_LL_TX_FLOW_CT */ +} + +/* + * TL API to transmit a frame given by HDD. Returns NULL + * in case of success, skb pointer in case of failure. + */ +adf_nbuf_t WLANTL_SendSTA_DataFrame(void *vos_ctx, u_int8_t sta_id, + adf_nbuf_t skb +#ifdef QCA_PKT_PROTO_TRACE + , v_U8_t proto_type +#endif /* QCA_PKT_PROTO_TRACE */ + ) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + void *adf_ctx = vos_get_context(VOS_MODULE_ID_ADF, vos_ctx); + adf_nbuf_t ret; + struct ol_txrx_peer_t *peer; + + ENTER(); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return skb; + } + + if (!adf_ctx) { + TLSHIM_LOGE("adf_ct is NULL"); + return skb; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_TL, NULL)) { + TLSHIM_LOGW("%s: Driver load/unload in progress", __func__); + return skb; + } + /* + * TODO: How sta_id is created and used for IBSS mode?. + */ + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id for data tx"); + return skb; + } + + if (!tl_shim->sta_info[sta_id].registered) { + TLSHIM_LOGW("Staion is not yet registered for data service"); + return skb; + } + + peer = ol_txrx_peer_find_by_local_id( + ((pVosContextType) vos_ctx)->pdev_txrx_ctx, + sta_id); + if (!peer) { + TLSHIM_LOGW("Invalid peer"); + return skb; + } + + /* Zero out skb's context buffer for the driver to use */ + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + adf_nbuf_map_single(adf_ctx, skb, ADF_OS_DMA_TO_DEVICE); + +#ifdef QCA_PKT_PROTO_TRACE + adf_nbuf_trace_set_proto_type(skb, proto_type); +#endif /* QCA_PKT_PROTO_TRACE */ + + if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP)) + && (skb->ip_summed == CHECKSUM_PARTIAL)) + skb->ip_summed = CHECKSUM_COMPLETE; + + /* Terminate the (single-element) list of tx frames */ + skb->next = NULL; + ret = tl_shim->tx(peer->vdev, skb); + if (ret) { + TLSHIM_LOGW("Failed to tx"); + adf_nbuf_unmap_single(adf_ctx, ret, ADF_OS_DMA_TO_DEVICE); + return ret; + } + + return NULL; +} + +#ifdef IPA_OFFLOAD +adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev, + adf_nbuf_t skb, v_U8_t interface_id) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + adf_nbuf_t ret; + + ENTER(); + if (NULL == tl_shim) { + TLSHIM_LOGW("INVALID TL SHIM CONTEXT"); + return skb; + } + + if (!adf_os_atomic_read(&tl_shim->vdev_active[interface_id])) { + TLSHIM_LOGW("INACTIVE VDEV"); + return skb; + } + + if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP)) + && (skb->ip_summed == CHECKSUM_PARTIAL)) + skb->ip_summed = CHECKSUM_COMPLETE; + + /* Terminate the (single-element) list of tx frames */ + skb->next = NULL; + ret = tl_shim->tx((struct ol_txrx_vdev_t *)vdev, skb); + if (ret) { + TLSHIM_LOGW("Failed to tx"); + return ret; + } + + return NULL; +} +#endif + +VOS_STATUS WLANTL_ResumeDataTx(void *vos_ctx, u_int8_t *sta_id) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_SuspendDataTx(void *vos_ctx, u_int8_t *sta_id, + WLANTL_SuspendCBType suspend_tx_cb) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_TxBAPFrm(void *vos_ctx, vos_pkt_t *buf, + WLANTL_MetaInfoType *meta_info, + WLANTL_TxCompCBType txcomp_cb) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +void WLANTL_AssocFailed(u_int8_t sta_id) +{ + /* Not needed */ +} + +VOS_STATUS WLANTL_Finish_ULA(void (*cb) (void *cb_ctx), void *cb_ctx) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +void WLANTLPrintPktsRcvdPerRssi(void *vos_ctx, u_int8_t sta_id, bool flush) +{ + /* TBD */ +} + +void WLANTLPrintPktsRcvdPerRateIdx(void *vos_ctx, u_int8_t sta_id, bool flush) +{ + /* TBD */ +} + +VOS_STATUS WLANTL_TxProcessMsg(void *vos_ctx, vos_msg_t *msg) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_McProcessMsg(void *vos_ctx, vos_msg_t *message) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_McFreeMsg(void *vos_ctx, vos_msg_t *message) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_TxFreeMsg(void *vos_ctx, vos_msg_t *message) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_RegisterBAPClient(void *vos_ctx, + WLANTL_BAPRxCBType bap_rx, + WLANTL_FlushOpCompCBType flush_cb) +{ + /* Not needed */ + return VOS_STATUS_SUCCESS; +} + +/* + * Txrx does weighted RR scheduling, set/get ac weights does not + * apply here, this is no operation. + */ +VOS_STATUS WLANTL_SetACWeights(void *vos_ctx, u_int8_t *ac_weight) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_GetACWeights(void *vos_ctx, u_int8_t *ac_weight) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_GetSoftAPStatistics(void *vos_ctx, + WLANTL_TRANSFER_STA_TYPE *stats_sum, + v_BOOL_t reset) +{ + /* TBD */ + return VOS_STATUS_SUCCESS; +} + +/* + * Return txrx stats for a given sta_id + */ +VOS_STATUS WLANTL_GetStatistics(void *vos_ctx, + WLANTL_TRANSFER_STA_TYPE *stats_buf, + u_int8_t sta_id) +{ + /* + * TODO: Txrx to be modified to maintain per peer stats which + * TL shim can return whenever requested. + */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_DeregRSSIIndicationCB(void *adapter, v_S7_t rssi, + u_int8_t trig_evt, + WLANTL_RSSICrossThresholdCBType func, + VOS_MODULE_ID mod_id) +{ + /* TBD */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_RegRSSIIndicationCB(void *adapter, v_S7_t rssi, + u_int8_t trig_evt, + WLANTL_RSSICrossThresholdCBType func, + VOS_MODULE_ID mod_id, void *usr_ctx) +{ + /* TBD */ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_EnableUAPSDForAC(void *vos_ctx, u_int8_t sta_id, + WLANTL_ACEnumType ac, u_int8_t tid, + u_int8_t pri, v_U32_t srvc_int, + v_U32_t sus_int, WLANTL_TSDirType dir, + u_int8_t psb, v_U32_t sessionId) +{ + tp_wma_handle wma_handle; + t_wma_trigger_uapsd_params uapsd_params; + struct txrx_tl_shim_ctx *tl_shim; + enum uapsd_ac access_category; + + ENTER(); + + if (!psb) { + TLSHIM_LOGD("No need to configure auto trigger:psb is 0"); + return VOS_STATUS_SUCCESS; + } + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (!wma_handle) { + TLSHIM_LOGE("wma_handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return VOS_STATUS_E_FAILURE; + } + + switch (ac) { + case WLANTL_AC_BK: + access_category = UAPSD_BK; + break; + case WLANTL_AC_BE: + access_category = UAPSD_BE; + break; + case WLANTL_AC_VI: + access_category = UAPSD_VI; + break; + case WLANTL_AC_VO: + access_category = UAPSD_VO; + break; + default: + return VOS_STATUS_E_FAILURE; + } + + uapsd_params.wmm_ac = access_category; + uapsd_params.user_priority = pri; + uapsd_params.service_interval = srvc_int; + uapsd_params.delay_interval = tl_shim->delay_interval; + uapsd_params.suspend_interval = sus_int; + + if(VOS_STATUS_SUCCESS != + wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) + { + TLSHIM_LOGE("Failed to Trigger Uapsd params for sessionId %d", + sessionId); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_DisableUAPSDForAC(void *vos_ctx, u_int8_t sta_id, + WLANTL_ACEnumType ac, v_U32_t sessionId) +{ + tp_wma_handle wma_handle; + enum uapsd_ac access_category; + ENTER(); + + switch (ac) { + case WLANTL_AC_BK: + access_category = UAPSD_BK; + break; + case WLANTL_AC_BE: + access_category = UAPSD_BE; + break; + case WLANTL_AC_VI: + access_category = UAPSD_VI; + break; + case WLANTL_AC_VO: + access_category = UAPSD_VO; + break; + default: + return VOS_STATUS_E_FAILURE; + } + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (!wma_handle) { + TLSHIM_LOGE("wma handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + if (VOS_STATUS_SUCCESS != + wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) { + TLSHIM_LOGE("Failed to disable uapsd for ac %d for sessionId %d", + ac, sessionId); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_DeRegisterMgmtFrmClient(void *vos_ctx) +{ + struct txrx_tl_shim_ctx *tl_shim; + tp_wma_handle wma_handle; + ENTER(); + +#ifdef QCA_WIFI_FTM + if (vos_get_conparam() == VOS_FTM_MODE) + return VOS_STATUS_SUCCESS; +#endif + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return VOS_STATUS_E_FAILURE; + } + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (!wma_handle) { + TLSHIM_LOGE("%s: Failed to get WMA context", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (wmi_unified_unregister_event_handler(wma_handle->wmi_handle, + WMI_MGMT_RX_EVENTID) != 0) { + TLSHIM_LOGE("Failed to Unregister rx mgmt handler with wmi"); + return VOS_STATUS_E_FAILURE; + } + tl_shim->mgmt_rx = NULL; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_RegisterMgmtFrmClient(void *vos_ctx, + WLANTL_MgmtFrmRxCBType mgmt_frm_rx) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + + tp_wma_handle wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (!wma_handle) { + TLSHIM_LOGE("%s: Failed to get WMA context", __func__); + return VOS_STATUS_E_FAILURE; + } + if (wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_MGMT_RX_EVENTID, + tlshim_mgmt_rx_wmi_handler) + != 0) { + TLSHIM_LOGE("Failed to register rx mgmt handler with wmi"); + return VOS_STATUS_E_FAILURE; + } + tl_shim->mgmt_rx = mgmt_frm_rx; + + return VOS_STATUS_SUCCESS; +} + +/* + * Return the data rssi for the given peer. + */ +VOS_STATUS WLANTL_GetRssi(void *vos_ctx, u_int8_t sta_id, v_S7_t *rssi, void *pGetRssiReq) +{ + tp_wma_handle wma_handle; + struct txrx_tl_shim_ctx *tl_shim; + struct tlshim_sta_info *sta_info; + v_S7_t first_rssi; + + ENTER(); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + if (!wma_handle) { + TLSHIM_LOGE("wma_handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return VOS_STATUS_E_FAULT; + } + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id :%d", sta_id); + return VOS_STATUS_E_INVAL; + } + + sta_info = &tl_shim->sta_info[sta_id]; + first_rssi = sta_info->first_rssi; + + if(VOS_STATUS_SUCCESS != + wma_send_snr_request(wma_handle, pGetRssiReq, first_rssi)) { + TLSHIM_LOGE("Failed to Trigger wma stats request"); + return VOS_STATUS_E_FAILURE; + } + + /* dont send success, otherwise call back + * will released with out values */ + return VOS_STATUS_E_BUSY; +} + +/* + * HDD will directly call tx function with the skb for transmission. + * Txrx is reponsible to enqueue the packet and schedule it for Hight + * Latency devices, so this API is not used for CLD. + */ +VOS_STATUS WLANTL_STAPktPending(void *vos_ctx, u_int8_t sta_id, + WLANTL_ACEnumType ac) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_UpdateSTABssIdforIBSS(void *vos_ctx, u_int8_t sta_id, + u_int8_t *bssid) +{ + /* TBD */ + return VOS_STATUS_SUCCESS; +} + +/* + * In CLD, sec_type along with the peer_state will be used to + * make sure EAPOL frame after PTK is installed is getting encrypted. + * So this API is no-op. + */ +VOS_STATUS WLANTL_STAPtkInstalled(void *vos_ctx, u_int8_t sta_id) +{ + return VOS_STATUS_SUCCESS; +} + +/* + * HDD calls this to notify the state change in client. + * Txrx will do frame filtering. + */ +VOS_STATUS WLANTL_ChangeSTAState(void *vos_ctx, u_int8_t sta_id, + WLANTL_STAStateType sta_state, + v_BOOL_t roam_synch_in_progress) +{ + struct ol_txrx_peer_t *peer; + enum ol_txrx_peer_state txrx_state = ol_txrx_peer_state_invalid; + int err; + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + + ENTER(); + + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id :%d", sta_id); + return VOS_STATUS_E_INVAL; + } + peer = ol_txrx_peer_find_by_local_id( + ((pVosContextType) vos_ctx)->pdev_txrx_ctx, + sta_id); + + if ((peer == NULL) || + (adf_os_atomic_read(&peer->delete_in_progress) == 1)) + return VOS_STATUS_E_FAULT; + + if (sta_state == WLANTL_STA_CONNECTED) + txrx_state = ol_txrx_peer_state_conn; + else if (sta_state == WLANTL_STA_AUTHENTICATED) + txrx_state = ol_txrx_peer_state_auth; + + ol_txrx_peer_state_update(peer->vdev->pdev, + (u_int8_t *) peer->mac_addr.raw, + txrx_state); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (roam_synch_in_progress) + return VOS_STATUS_SUCCESS; +#endif + + + if (txrx_state == ol_txrx_peer_state_auth) { +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + /* make sure event is reset */ + vos_event_reset(&tl_shim->peer_authorized_events[peer->vdev->vdev_id]); +#endif + err = wma_set_peer_param( + ((pVosContextType) vos_ctx)->pWDAContext, + peer->mac_addr.raw, WMI_PEER_AUTHORIZE, + 1, peer->vdev->vdev_id); + if (err) { + TLSHIM_LOGE("Failed to set the peer state to authorized"); + return VOS_STATUS_E_FAULT; + } + + if (peer->vdev->opmode == wlan_op_mode_sta) { +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + /* + * TODO: following code waits on event without + * checking if the event was already set. Currently + * there is no vos api to check if event was already + * set fix it cleanly later. + */ + /* wait for event from firmware to set the event */ + vos_wait_single_event(&tl_shim->peer_authorized_events[peer->vdev->vdev_id], + TLSHIM_PEER_AUTHORIZE_WAIT); + wdi_in_vdev_unpause(peer->vdev, + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); +#endif + } + } + + return VOS_STATUS_SUCCESS; +} + +/* + * Clear the station information. + */ +VOS_STATUS WLANTL_ClearSTAClient(void *vos_ctx, u_int8_t sta_id) +{ + struct txrx_tl_shim_ctx *tl_shim; + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id :%d", sta_id); + return VOS_STATUS_E_INVAL; + } + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return VOS_STATUS_E_FAILURE; + } + +#ifdef QCA_CONFIG_SMP + { + pVosSchedContext sched_ctx = get_vos_sched_ctxt(); + /* Drop pending Rx frames in VOSS */ + if (sched_ctx) + vos_drop_rxpkt_by_staid(sched_ctx, sta_id); + } +#endif + + /* Purge the cached rx frame queue */ + tl_shim_flush_rx_frames(vos_ctx, tl_shim, sta_id, 1); + adf_os_spin_lock_bh(&tl_shim->bufq_lock); + tl_shim->sta_info[sta_id].suspend_flush = 0; + adf_os_spin_unlock_bh(&tl_shim->bufq_lock); + + adf_os_spin_lock_bh(&tl_shim->sta_info[sta_id].stainfo_lock); + tl_shim->sta_info[sta_id].registered = 0; + tl_shim->sta_info[sta_id].data_rx = NULL; + tl_shim->sta_info[sta_id].first_rssi = 0; + adf_os_spin_unlock_bh(&tl_shim->sta_info[sta_id].stainfo_lock); + + return VOS_STATUS_SUCCESS; +} + +/* + * Register a station for data service. This API gives flexibility + * to register different callbacks for different client though it is + * needed to register different callbacks for every vdev. Only rxcb + * is used. + */ +VOS_STATUS WLANTL_RegisterSTAClient(void *vos_ctx, + WLANTL_STARxCBType rxcb, + WLANTL_TxCompCBType tx_comp, + WLANTL_STAFetchPktCBType txpkt_fetch, + WLAN_STADescType *sta_desc, v_S7_t rssi) +{ + struct txrx_tl_shim_ctx *tl_shim; + struct ol_txrx_peer_t *peer; + ol_txrx_peer_update_param_t param; + struct tlshim_sta_info *sta_info; + privacy_exemption privacy_filter; + + ENTER(); + if (sta_desc->ucSTAId >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id :%d", sta_desc->ucSTAId); + return VOS_STATUS_E_INVAL; + } + peer = ol_txrx_peer_find_by_local_id( + ((pVosContextType) vos_ctx)->pdev_txrx_ctx, + sta_desc->ucSTAId); + if (!peer) + return VOS_STATUS_E_FAULT; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return VOS_STATUS_E_FAULT; + } + + sta_info = &tl_shim->sta_info[sta_desc->ucSTAId]; + adf_os_spin_lock_bh(&sta_info->stainfo_lock); + sta_info->data_rx = rxcb; + sta_info->registered = true; + sta_info->first_rssi = rssi; + sta_info->vdev_id = peer->vdev->vdev_id; + adf_os_spin_unlock_bh(&sta_info->stainfo_lock); + + param.qos_capable = sta_desc->ucQosEnabled; + wdi_in_peer_update(peer->vdev, peer->mac_addr.raw, ¶m, + ol_txrx_peer_update_qos_capable); + if (sta_desc->ucIsWapiSta) { + /*Privacy filter to accept unencrypted WAI frames*/ + privacy_filter.ether_type = ETHERTYPE_WAI; + privacy_filter.filter_type = PRIVACY_FILTER_ALWAYS; + privacy_filter.packet_type = PRIVACY_FILTER_PACKET_BOTH; + ol_txrx_set_privacy_filters(peer->vdev, &privacy_filter, 1); + /* param.sec_type = ol_sec_type_wapi; */ + /* + * TODO: Peer update also updates the other security types + * but HDD will not pass this information. + + wdi_in_peer_update(peer->vdev, peer->mac_addr.raw, ¶m, + ol_txrx_peer_update_peer_security); + */ + } + + /* Schedule a worker to flush cached rx frames */ + schedule_work(&tl_shim->cache_flush_work); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANTL_Stop(void *vos_ctx) +{ + /* Nothing to do really */ + return VOS_STATUS_SUCCESS; +} + +/* + * Make txrx module ready + */ +VOS_STATUS WLANTL_Start(void *vos_ctx) +{ + ENTER(); + if (wdi_in_pdev_attach_target(((pVosContextType) + vos_ctx)->pdev_txrx_ctx)) + return VOS_STATUS_E_FAULT; + return VOS_STATUS_SUCCESS; +} + +/* + * Deinit txrx module + */ +VOS_STATUS WLANTL_Close(void *vos_ctx) +{ + struct txrx_tl_shim_ctx *tl_shim; +#ifdef QCA_LL_TX_FLOW_CT + u_int8_t i; +#endif /* QCA_LL_TX_FLOW_CT */ + + ENTER(); + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return VOS_STATUS_E_FAILURE; + } + +#ifdef QCA_LL_TX_FLOW_CT + for (i = 0; + i < wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx); + i++) { + adf_os_spinlock_destroy(&tl_shim->session_flow_control[i].fc_lock); + } + adf_os_mem_free(tl_shim->session_flow_control); +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + for (i = 0; + i < wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx); + i++) { + vos_event_destroy(&tl_shim->peer_authorized_events[i]); + } + adf_os_mem_free(tl_shim->peer_authorized_events); +#endif + + adf_os_mem_free(tl_shim->vdev_active); +#ifdef FEATURE_WLAN_ESE + vos_flush_work(&tl_shim->iapp_work.deferred_work); +#endif + vos_flush_work(&tl_shim->cache_flush_work); + + wdi_in_pdev_detach(((pVosContextType) vos_ctx)->pdev_txrx_ctx, 1); + // Delete beacon buffer hanging off tl_shim + if (tl_shim->last_beacon_data) { + if (((WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data)->hdr) + vos_mem_free(((WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data)->hdr); + if (((WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data)->bufp) + vos_mem_free(((WMI_MGMT_RX_EVENTID_param_tlvs *) tl_shim->last_beacon_data)->bufp); + vos_mem_free(tl_shim->last_beacon_data); + } + vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); + return VOS_STATUS_SUCCESS; +} + +/* + * Allocate and Initialize transport layer (txrx) + */ +VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg) +{ + struct txrx_tl_shim_ctx *tl_shim; + VOS_STATUS status; + u_int8_t i; + int max_vdev; + + ENTER(); + status = vos_alloc_context(vos_ctx, VOS_MODULE_ID_TL, + (void *) &tl_shim, sizeof(*tl_shim)); + if (status != VOS_STATUS_SUCCESS) + return status; + + ((pVosContextType) vos_ctx)->pdev_txrx_ctx = + wdi_in_pdev_attach( + ((pVosContextType) vos_ctx)->cfg_ctx, + ((pVosContextType) vos_ctx)->htc_ctx, + ((pVosContextType) vos_ctx)->adf_ctx); + if (!((pVosContextType) vos_ctx)->pdev_txrx_ctx) { + TLSHIM_LOGE("Failed to allocate memory for pdev txrx handle"); + vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); + return VOS_STATUS_E_NOMEM; + } + + adf_os_spinlock_init(&tl_shim->bufq_lock); + adf_os_spinlock_init(&tl_shim->mgmt_lock); + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + tl_shim->sta_info[i].suspend_flush = 0; + adf_os_spinlock_init(&tl_shim->sta_info[i].stainfo_lock); + tl_shim->sta_info[i].flags = 0; + INIT_LIST_HEAD(&tl_shim->sta_info[i].cached_bufq); + } + +#ifdef CONFIG_CNSS + cnss_init_work(&tl_shim->cache_flush_work, tl_shim_cache_flush_work); +#else + INIT_WORK(&tl_shim->cache_flush_work, tl_shim_cache_flush_work); +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#ifdef CONFIG_CNSS + cnss_init_work(&(tl_shim->iapp_work.deferred_work), + tlshim_mgmt_over_data_rx_handler); +#else + INIT_WORK(&(tl_shim->iapp_work.deferred_work), + tlshim_mgmt_over_data_rx_handler); +#endif +#endif + /* + * TODO: Allocate memory for tx callback for maximum supported + * vdevs to maintain tx callbacks per vdev. + */ + max_vdev = wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx); + tl_shim->vdev_active = adf_os_mem_alloc(NULL, + max_vdev * sizeof(adf_os_atomic_t)); + for (i = 0; i < max_vdev; i++) { + adf_os_atomic_init(&tl_shim->vdev_active[i]); + adf_os_atomic_set(&tl_shim->vdev_active[i], 0); + } + +#ifdef QCA_LL_TX_FLOW_CT + tl_shim->session_flow_control = adf_os_mem_alloc(NULL, + max_vdev * sizeof(struct tlshim_session_flow_Control)); + if (!tl_shim->session_flow_control) { + TLSHIM_LOGE("Failed to allocate memory for tx flow control"); + vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); + return VOS_STATUS_E_NOMEM; + } + + for (i = 0; i < max_vdev; i++) { + tl_shim->session_flow_control[i].flowControl = NULL; + tl_shim->session_flow_control[i].sessionId = 0xFF; + tl_shim->session_flow_control[i].adpaterCtxt = NULL; + tl_shim->session_flow_control[i].vdev = NULL; + adf_os_spinlock_init(&tl_shim->session_flow_control[i].fc_lock); + } +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + tl_shim->peer_authorized_events = adf_os_mem_alloc(NULL, + max_vdev * sizeof(vos_event_t)); + if (!tl_shim->peer_authorized_events) { + TLSHIM_LOGE("Failed to allocate memory for events"); +#ifdef QCA_LL_TX_FLOW_CT + adf_os_mem_free(tl_shim->session_flow_control); +#endif + vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); + return VOS_STATUS_E_NOMEM; + } + for (i = 0; i < max_vdev; i++) { + status = vos_event_init(&tl_shim->peer_authorized_events[i]); + if (!VOS_IS_STATUS_SUCCESS(status)) { + TLSHIM_LOGE("%s: Failed to initialized a event.", + __func__); + adf_os_mem_free(tl_shim->peer_authorized_events); +#ifdef QCA_LL_TX_FLOW_CT + adf_os_mem_free(tl_shim->session_flow_control); +#endif + vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); + return status; + } + } +#endif + + tl_shim->ip_checksum_offload = tl_cfg->ip_checksum_offload; + tl_shim->delay_interval = tl_cfg->uDelayedTriggerFrmInt; + tl_shim->enable_rxthread = tl_cfg->enable_rxthread; + return status; +} + +/* + * Funtion to retrieve BSSID for peer sta. + */ +VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id) +{ + if(!peer) { + TLSHIM_LOGE("peer argument is null!!"); + return VOS_STATUS_E_FAILURE; + } + + *vdev_id = peer->vdev->vdev_id; + return VOS_STATUS_SUCCESS; +} + +/* + * Function to get vdev(tl_context) given the MAC address. + */ +void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr) +{ + struct ol_txrx_peer_t *peer = NULL; + ol_txrx_pdev_handle pdev = NULL; + uint8_t peer_id; + + if (vos_context == NULL || mac_addr == NULL) { + TLSHIM_LOGE("Invalid argument %p, %p", vos_context, mac_addr); + return NULL; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context); + if (!pdev) { + TLSHIM_LOGE("PDEV [%pM] not found", mac_addr); + return NULL; + } + + peer = ol_txrx_find_peer_by_addr(pdev, mac_addr, &peer_id); + + if (!peer) { + TLSHIM_LOGE("PEER [%pM] not found", mac_addr); + return NULL; + } + + return peer->vdev; +} + +/* + * Function to get vdev(tl_context) given the TL station ID. + */ +void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id) +{ + struct ol_txrx_peer_t *peer = NULL; + ol_txrx_pdev_handle pdev = NULL; + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id passed"); + return NULL; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context); + if (!pdev) { + TLSHIM_LOGE("PDEV not found for sta_id [%d]", sta_id); + return NULL; + } + + peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); + + if (!peer) { + TLSHIM_LOGE("PEER [%d] not found", sta_id); + return NULL; + } + + return peer->vdev; +} + +void +WLANTL_PauseUnPauseQs(void *vos_context, v_BOOL_t flag) +{ + ol_txrx_pdev_handle pdev = vos_get_context(VOS_MODULE_ID_TXRX, + vos_context); + + if (true == flag) + wdi_in_pdev_pause(pdev, + OL_TXQ_PAUSE_REASON_VDEV_SUSPEND); + else + wdi_in_pdev_unpause(pdev, + OL_TXQ_PAUSE_REASON_VDEV_SUSPEND); +} + +#ifdef QCA_LL_TX_FLOW_CT +/*============================================================================= + FUNCTION WLANTL_GetTxResource + + DESCRIPTION + This function will query WLAN kernel driver TX resource availability. + Per STA/VDEV instance, if TX resource is not available, should back + pressure to OS NET layer. + + DEPENDENCIES + NONE + + PARAMETERS + IN + vos_context : Pointer to VOS global context + sessionId : VDEV instance to query TX resource + low_watermark : Low threashold to block OS Q + high_watermark_offset : Offset to high watermark from low watermark + + RETURN VALUE + VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q + VOS_FALSE : TX resource is not enough, stop OS TX Q + + SIDE EFFECTS + +==============================================================================*/ +v_BOOL_t WLANTL_GetTxResource +( + void *vos_context, + v_U8_t sessionId, + unsigned int low_watermark, + unsigned int high_watermark_offset +) +{ + struct txrx_tl_shim_ctx *tl_shim; + v_BOOL_t enough_resource = VOS_TRUE; + struct ol_txrx_vdev_t *vdev; + + /* If low watermark is zero, TX flow control is not enabled at all + * return TRUE by default */ + if ((!vos_context) || (!low_watermark)) { + return VOS_TRUE; + } + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_context); + if (!tl_shim) { + TLSHIM_LOGD("%s, tl_shim is NULL", + __func__); + /* Invalid instace */ + return VOS_TRUE; + } + + adf_os_spin_lock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + if (!tl_shim->session_flow_control[sessionId].vdev) { + TLSHIM_LOGD("%s, session id %d, VDEV NULL", + __func__, sessionId); + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + return VOS_TRUE; + } + vdev = (struct ol_txrx_vdev_t *)tl_shim->session_flow_control[sessionId].vdev; + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + + enough_resource = (v_BOOL_t)wdi_in_get_tx_resource(vdev, + low_watermark, + high_watermark_offset); + + return enough_resource; +} + +/*============================================================================= + FUNCTION WLANTL_TXFlowControlCb + + DESCRIPTION + This function will be called bu TX resource management unit. + If TC resource management unit reserved enough resource for TX session, + Call this function to resume OS TX Q. + + PARAMETERS + IN + tlContext : Pointer to TL SHIM context + sessionId : STA/VDEV instance to query TX resource + resume_tx : Resume OS TX Q or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_TXFlowControlCb +( + void *tlContext, + v_U8_t sessionId, + v_BOOL_t resume_tx +) +{ + struct txrx_tl_shim_ctx *tl_shim; + WLANTL_TxFlowControlCBType flow_control_cb = NULL; + void *adpter_ctxt = NULL; + + tl_shim = (struct txrx_tl_shim_ctx *)tlContext; + if (!tl_shim) { + TLSHIM_LOGE("%s, tl_shim is NULL", __func__); + /* Invalid instace */ + return; + } + + adf_os_spin_lock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + if ((tl_shim->session_flow_control[sessionId].sessionId == sessionId) && + (tl_shim->session_flow_control[sessionId].flowControl)) { + flow_control_cb = tl_shim->session_flow_control[sessionId].flowControl; + adpter_ctxt = tl_shim->session_flow_control[sessionId].adpaterCtxt; + } + + if ((flow_control_cb) && (adpter_ctxt)) { + flow_control_cb(adpter_ctxt, resume_tx); + } + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + + return; +} + +/*============================================================================= + FUNCTION WLANTL_RegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to enable TX flow control, should register Cb function + And needed information into TL SHIM + + PARAMETERS + IN + vos_ctx : Global OS context context + sta_id : STA/VDEV instance index + flowControl : Flow control callback function pointer + sessionId : VDEV ID + adpaterCtxt : VDEV os interface adapter context + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterTXFlowControl +( + void *vos_ctx, + WLANTL_TxFlowControlCBType flowControl, + v_U8_t sessionId, + void *adpaterCtxt +) +{ + struct txrx_tl_shim_ctx *tl_shim; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if ((!tl_shim) || (!tl_shim->session_flow_control)) { + TLSHIM_LOGE("%s : Invalid ARG", __func__); + return; + } + + if (sessionId >= wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx)) { + TLSHIM_LOGE("%s : Invalid session id", __func__); + return; + } + + adf_os_spin_lock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + tl_shim->session_flow_control[sessionId].flowControl = flowControl; + tl_shim->session_flow_control[sessionId].sessionId = sessionId; + tl_shim->session_flow_control[sessionId].adpaterCtxt = adpaterCtxt; + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + + return; +} + +/*============================================================================= + FUNCTION WLANTL_DeRegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to close TX flow control, should de-register Cb function + And needed information into TL SHIM + + PARAMETERS + IN + vos_ctx : Global OS context context + sessionId : VDEV instance index + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_DeRegisterTXFlowControl +( + void *vos_ctx, + v_U8_t sessionId +) +{ + struct txrx_tl_shim_ctx *tl_shim; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("%s : Invalid ARG", __func__); + return; + } + + if (sessionId >= wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx)) { + TLSHIM_LOGE("%s : Invalid session id", __func__); + return; + } + + adf_os_spin_lock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + tl_shim->session_flow_control[sessionId].flowControl = NULL; + tl_shim->session_flow_control[sessionId].sessionId = 0xFF; + tl_shim->session_flow_control[sessionId].adpaterCtxt = NULL; + tl_shim->session_flow_control[sessionId].vdev = NULL; + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + + return; +} + +/*============================================================================= + FUNCTION WLANTL_SetAdapterMaxQDepth + + DESCRIPTION + This function will be called by TL client. + Based on the adapter TX available bandwidth, set different TX Pause Q size + Low Bandwidth adapter will have less count of TX Pause Q size to prevent + reserve all TX descriptors which shared with FW. + High Bandwidth adapter will have more count of TX Pause Q size + + PARAMETERS + IN + vos_ctx : Global OS context context + sessionId : adapter instance index + max_q_depth : Max pause Q depth for adapter + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetAdapterMaxQDepth +( + void *vos_ctx, + v_U8_t sessionId, + int max_q_depth +) +{ + struct txrx_tl_shim_ctx *tl_shim; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if ((!tl_shim) || (!tl_shim->session_flow_control)) { + TLSHIM_LOGE("%s: TLSHIM NULL or FC main context NULL", + __func__); + return; + } + + adf_os_spin_lock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + if (!tl_shim->session_flow_control[sessionId].vdev) { + TLSHIM_LOGD("%s, session id %d, VDEV NULL", + __func__, sessionId); + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + return; + } + wdi_in_ll_set_tx_pause_q_depth( + (struct ol_txrx_vdev_t *)tl_shim->session_flow_control[sessionId].vdev, + max_q_depth); + adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock); + + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL +void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t session_id) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + + if (!tl_shim) { + TLSHIM_LOGE("%s: Failed to get TLSHIM context", __func__); + return; + } + + vos_event_set(&tl_shim->peer_authorized_events[session_id]); +} +#endif + +#ifdef IPA_UC_OFFLOAD +/*============================================================================= + FUNCTION WLANTL_GetIpaUcResource + + DESCRIPTION + This function will be called by TL client. + Data path resource will be used by FW should be allocated within lower layer. + Shared resource information should be propagated to IPA. + To propagate resource information, client will use this API + + PARAMETERS + IN + vos_ctx : Global OS context context + ce_sr_base_paddr : Copy Engine Source Ring base address + ce_sr_ring_size : Copy Engine Source Ring size + ce_reg_paddr : Copy engine register address + tx_comp_ring_base_paddr : TX COMP ring base address + tx_comp_ring_size : TX COMP ring size + tx_num_alloc_buffer : Number of TX allocated buffer + rx_rdy_ring_base_paddr : RX ready ring base address + rx_rdy_ring_size : RX ready ring size + rx_proc_done_idx_paddr : RX process done index physical address + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_GetIpaUcResource(void *vos_ctx, + v_U32_t *ce_sr_base_paddr, + v_U32_t *ce_sr_ring_size, + v_U32_t *ce_reg_paddr, + v_U32_t *tx_comp_ring_base_paddr, + v_U32_t *tx_comp_ring_size, + v_U32_t *tx_num_alloc_buffer, + v_U32_t *rx_rdy_ring_base_paddr, + v_U32_t *rx_rdy_ring_size, + v_U32_t *rx_proc_done_idx_paddr) +{ + if (!vos_ctx || !((pVosContextType)vos_ctx)->pdev_txrx_ctx) { + TLSHIM_LOGE("%s: Invalid context", __func__); + return; + } + + wdi_in_ipa_uc_get_resource(((pVosContextType)vos_ctx)->pdev_txrx_ctx, + ce_sr_base_paddr, + ce_sr_ring_size, + ce_reg_paddr, + tx_comp_ring_base_paddr, + tx_comp_ring_size, + tx_num_alloc_buffer, + rx_rdy_ring_base_paddr, + rx_rdy_ring_size, + rx_proc_done_idx_paddr); +} + +/*============================================================================= + FUNCTION WLANTL_SetUcDoorbellPaddr + + DESCRIPTION + This function will be called by TL client. + UC controller should provide doorbell register address to firmware + TL client will call this API to pass doorbell register address to firmware + + PARAMETERS + IN + vos_ctx : Global OS context context + ipa_tx_uc_doorbell_paddr : Micro Controller WLAN TX COMP doorbell regiser + ipa_rx_uc_doorbell_paddr : Micro Controller WLAN RX REDY doorbell regiser + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetUcDoorbellPaddr(void *vos_ctx, + v_U32_t ipa_tx_uc_doorbell_paddr, + v_U32_t ipa_rx_uc_doorbell_paddr) +{ + if (!vos_ctx || !((pVosContextType)vos_ctx)->pdev_txrx_ctx) { + TLSHIM_LOGE("%s: Invalid context", __func__); + return; + } + + wdi_in_ipa_uc_set_doorbell_paddr(((pVosContextType)vos_ctx)->pdev_txrx_ctx, + ipa_tx_uc_doorbell_paddr, + ipa_rx_uc_doorbell_paddr); +} + +/*============================================================================= + FUNCTION WLANTL_SetUcActive + + DESCRIPTION + This function will be called by TL client. + Send Micro controller data path active or inactive notification to firmware + + PARAMETERS + IN + vos_ctx : Global OS context context + uc_active : Micro Controller data path is active or not + is_tx : Micro Controller WLAN TX data path is active or not + is_rx : Micro Controller WLAN RX data path is active or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetUcActive(void *vos_ctx, + v_BOOL_t uc_active, + v_BOOL_t is_tx +) +{ + if (!vos_ctx || !((pVosContextType)vos_ctx)->pdev_txrx_ctx) { + TLSHIM_LOGE("%s: Invalid context", __func__); + return; + } + + TLSHIM_LOGD("%s, ACTIVE %d, TX %d", + __func__, uc_active, is_tx); + wdi_in_ipa_uc_set_active(((pVosContextType)vos_ctx)->pdev_txrx_ctx, + uc_active, is_tx); +} + +/*============================================================================= + FUNCTION WLANTL_IpaUcFwOpEventHandler + + DESCRIPTION + This function will be called by TL client. + Firmware data path activation response handler. + Firmware response will be routed to upper layer + + PARAMETERS + IN + context : pre-registered shim context + rxpkt : message pointer from firmware + staid : STA ID, not used + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_IpaUcFwOpEventHandler(void *context, + void *rxpkt, + u_int16_t staid) +{ + struct txrx_tl_shim_ctx *tl_shim = (struct txrx_tl_shim_ctx *)context; + + if (!tl_shim) { + TLSHIM_LOGE("%s: Invalid context", __func__); + return; + } + + if (tl_shim->fw_op_cb) { + tl_shim->fw_op_cb(rxpkt, tl_shim->usr_ctxt); + } +} + +/*============================================================================= + FUNCTION WLANTL_IpaUcOpEventHandler + + DESCRIPTION + This function will be called by TL client. + This API will be registered into OL layer and if firmware send any + Activity related notification, OL layer will call this function. + firmware indication will be serialized within TLSHIM RX Thread + + PARAMETERS + IN + op_code : OP Code from firmware + shim_ctxt : shim context pointer + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_IpaUcOpEventHandler(v_U8_t *op_msg, void *shim_ctxt) +{ + pVosSchedContext sched_ctx = get_vos_sched_ctxt(); + struct VosTlshimPkt *pkt; + + if (unlikely(!sched_ctx)) + return; + + pkt = vos_alloc_tlshim_pkt(sched_ctx); + if (!pkt) { + TLSHIM_LOGW("No available Rx message buffer"); + return; + } + + pkt->callback = (vos_tlshim_cb) WLANTL_IpaUcFwOpEventHandler; + pkt->context = shim_ctxt; + pkt->Rxpkt = (void *)op_msg; + pkt->staId = 0; + vos_indicate_rxpkt(sched_ctx, pkt); +} + +/*============================================================================= + FUNCTION WLANTL_RegisterOPCbFnc + + DESCRIPTION + This function will be called by TL client. + + PARAMETERS + IN + vos_ctx : Global OS context context + func : callback function pointer + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterOPCbFnc(void *vos_ctx, + void (*func)(v_U8_t *op_msg, void *usr_ctxt), void *usr_ctxt) +{ + struct txrx_tl_shim_ctx *tl_shim; + + if (!vos_ctx) { + TLSHIM_LOGE("%s: Invalid context", __func__); + return; + } + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (NULL == tl_shim) { + TLSHIM_LOGW("Invalid TL Shim context"); + return; + } + + tl_shim->fw_op_cb = func; + tl_shim->usr_ctxt = usr_ctxt; + wdi_in_ipa_uc_register_op_cb(((pVosContextType)vos_ctx)->pdev_txrx_ctx, + WLANTL_IpaUcOpEventHandler, (void *)tl_shim); +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.h new file mode 100644 index 0000000000000..617bc5b267c5a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef TXRX_TL_SHIM_H +#define TXRX_TL_SHIM_H + +#include +#include +#include + +#ifdef FEATURE_WLAN_ESE +typedef struct deferred_iapp_work { + pVosContextType pVosGCtx; + adf_nbuf_t nbuf; + struct ol_txrx_vdev_t *vdev; + bool inUse; + struct work_struct deferred_work; +} deferred_iapp_work; +#endif + +struct tlshim_buf { + struct list_head list; + adf_nbuf_t buf; +}; + +#define TLSHIM_FLUSH_CACHE_IN_PROGRESS 0 +struct tlshim_sta_info { + bool registered; + bool suspend_flush; + WLANTL_STARxCBType data_rx; + /* To protect stainfo data like registered and data_rx */ + adf_os_spinlock_t stainfo_lock; + struct list_head cached_bufq; + unsigned long flags; + v_S7_t first_rssi; + v_U8_t vdev_id; +}; + +#ifdef QCA_LL_TX_FLOW_CT +struct tlshim_session_flow_Control { + WLANTL_TxFlowControlCBType flowControl; + v_U8_t sessionId; + void *adpaterCtxt; + void *vdev; + adf_os_spinlock_t fc_lock; +}; +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef IPA_UC_OFFLOAD +typedef void(*ipa_uc_fw_op_cb)(v_U8_t *op_msg, void *usr_ctxt); +#endif /* IPA_UC_OFFLOAD */ + +struct txrx_tl_shim_ctx { + void *cfg_ctx; + ol_txrx_tx_fp tx; + WLANTL_MgmtFrmRxCBType mgmt_rx; + struct tlshim_sta_info sta_info[WLAN_MAX_STA_COUNT]; + adf_os_spinlock_t bufq_lock; + adf_os_spinlock_t mgmt_lock; + struct work_struct cache_flush_work; + +#ifdef FEATURE_WLAN_ESE + /* + * work structures to defer IAPP processing to + * non interrupt context + */ +struct deferred_iapp_work iapp_work; +#endif + v_BOOL_t ip_checksum_offload; + u_int8_t *last_beacon_data; + u_int32_t last_beacon_len; + u_int32_t delay_interval; + v_BOOL_t enable_rxthread; + adf_os_atomic_t *vdev_active; +#ifdef QCA_LL_TX_FLOW_CT + struct tlshim_session_flow_Control *session_flow_control; +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + vos_event_t *peer_authorized_events; +#endif +#ifdef IPA_UC_OFFLOAD + ipa_uc_fw_op_cb fw_op_cb; + void *usr_ctxt; +#endif /* IPA_UC_OFFLOAD */ +}; + +/* + * APIs used by CLD specific components, as of now these are used only + * in WMA. + */ +void WLANTL_RegisterVdev(void *vos_ctx, void *vdev); +void WLANTL_UnRegisterVdev(void *vos_ctx, u_int8_t vdev_id); +VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id); + +/* + * tlshim_mgmt_roam_event_ind() is called from WMA layer when + * BETTER_AP_FOUND event is received from roam engine. + */ +int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id); +void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr); +void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id); + +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL +void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t session_id); +#else +static inline void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t session_id) +{ +} +#endif +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_cfg.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_cfg.c new file mode 100644 index 0000000000000..038c0da013b71 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_cfg.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include + +unsigned int vow_config = 0; +module_param(vow_config, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(vow_config, "Do VoW Configuration"); +EXPORT_SYMBOL(vow_config); + +/* FIX THIS - + * For now, all these configuration parameters are hardcoded. + * Many of these should actually be determined dynamically instead. + */ + +ol_pdev_handle ol_pdev_cfg_attach(adf_os_device_t osdev, + struct txrx_pdev_cfg_param_t cfg_param) +{ + struct txrx_pdev_cfg_t *cfg_ctx; + + cfg_ctx = adf_os_mem_alloc(osdev, sizeof(*cfg_ctx)); + if (!cfg_ctx) { + printk(KERN_ERR "cfg ctx allocation failed\n"); + return NULL; + } + +#ifdef CONFIG_HL_SUPPORT + cfg_ctx->is_high_latency = 1; + /* 802.1Q and SNAP / LLC headers are accounted for elsewhere */ + cfg_ctx->tx_download_size = 1500; + cfg_ctx->tx_free_at_download = 0; +#else + /* + * Need to change HTT_LL_TX_HDR_SIZE_IP accordingly. + * Include payload, up to the end of UDP header for IPv4 case + */ + cfg_ctx->tx_download_size = 16; +#endif + /* temporarily diabled PN check for Riva/Pronto */ + cfg_ctx->rx_pn_check = 1; +#if CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK + cfg_ctx->defrag_timeout_check = 1; +#else + cfg_ctx->defrag_timeout_check = 0; +#endif + cfg_ctx->max_peer_id = 511; + cfg_ctx->max_vdev = CFG_TGT_NUM_VDEV; + cfg_ctx->pn_rx_fwd_check = 1; + cfg_ctx->frame_type = wlan_frm_fmt_802_3; + cfg_ctx->max_thruput_mbps = 800; + cfg_ctx->max_nbuf_frags = 1; + cfg_ctx->vow_config = vow_config; + cfg_ctx->target_tx_credit = CFG_TGT_NUM_MSDU_DESC; + cfg_ctx->throttle_period_ms = 40; + cfg_ctx->rx_fwd_disabled = 0; + cfg_ctx->is_packet_log_enabled = 0; + cfg_ctx->is_full_reorder_offload = cfg_param.is_full_reorder_offload; +#ifdef IPA_UC_OFFLOAD + cfg_ctx->ipa_uc_rsc.uc_offload_enabled = cfg_param.is_uc_offload_enabled; + cfg_ctx->ipa_uc_rsc.tx_max_buf_cnt = cfg_param.uc_tx_buffer_count; + cfg_ctx->ipa_uc_rsc.tx_buf_size = cfg_param.uc_tx_buffer_size; + cfg_ctx->ipa_uc_rsc.rx_ind_ring_size = cfg_param.uc_rx_indication_ring_count; + cfg_ctx->ipa_uc_rsc.tx_partition_base = cfg_param.uc_tx_partition_base; +#endif /* IPA_UC_OFFLOAD */ + return (ol_pdev_handle) cfg_ctx; +} + +int ol_cfg_is_high_latency(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->is_high_latency; +} + +int ol_cfg_max_peer_id(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + /* + * TBDXXX - this value must match the peer table + * size allocated in FW + */ + return cfg->max_peer_id; +} + +int ol_cfg_max_vdevs(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->max_vdev; +} + +int ol_cfg_rx_pn_check(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->rx_pn_check; +} + +int ol_cfg_rx_fwd_check(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->pn_rx_fwd_check; +} + +void ol_set_cfg_rx_fwd_disabled(ol_pdev_handle pdev, u_int8_t disable_rx_fwd) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + cfg->rx_fwd_disabled = disable_rx_fwd; +} + +void ol_set_cfg_packet_log_enabled(ol_pdev_handle pdev, u_int8_t val) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + cfg->is_packet_log_enabled = val; +} + +u_int8_t ol_cfg_is_packet_log_enabled(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->is_packet_log_enabled; +} + +int ol_cfg_rx_fwd_disabled(ol_pdev_handle pdev) +{ +#if defined(ATHR_WIN_NWF) + /* for Windows, let the OS handle the forwarding */ + return 1; +#else + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->rx_fwd_disabled; +#endif +} + +int ol_cfg_rx_fwd_inter_bss(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->rx_fwd_inter_bss; +} + +enum wlan_frm_fmt ol_cfg_frame_type(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->frame_type; +} + +int ol_cfg_max_thruput_mbps(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->max_thruput_mbps; +} + +int ol_cfg_netbuf_frags_max(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->max_nbuf_frags; +} + +int ol_cfg_tx_free_at_download(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->tx_free_at_download; +} + +u_int16_t ol_cfg_target_tx_credit(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; +#ifndef CONFIG_HL_SUPPORT + u_int16_t vow_max_sta = (cfg->vow_config & 0xffff0000) >> 16; + u_int16_t vow_max_desc_persta = cfg->vow_config & 0x0000ffff; + + return (cfg->target_tx_credit + + (vow_max_sta * vow_max_desc_persta)); +#else + return cfg->target_tx_credit; +#endif +} + +int ol_cfg_tx_download_size(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->tx_download_size; +} + +int ol_cfg_rx_host_defrag_timeout_duplicate_check(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->defrag_timeout_check; +} + +int ol_cfg_throttle_period_ms(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->throttle_period_ms; +} + +int ol_cfg_is_full_reorder_offload(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->is_full_reorder_offload; +} + +#ifdef IPA_UC_OFFLOAD +unsigned int ol_cfg_ipa_uc_offload_enabled(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return (unsigned int)cfg->ipa_uc_rsc.uc_offload_enabled; +} + +unsigned int ol_cfg_ipa_uc_tx_buf_size(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->ipa_uc_rsc.tx_buf_size; +} + +unsigned int ol_cfg_ipa_uc_tx_max_buf_cnt(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->ipa_uc_rsc.tx_max_buf_cnt; +} + +unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->ipa_uc_rsc.rx_ind_ring_size; +} + +unsigned int ol_cfg_ipa_uc_tx_partition_base(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->ipa_uc_rsc.tx_partition_base; +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_ctrl_txrx_api.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_ctrl_txrx_api.h new file mode 100644 index 0000000000000..e945870476bff --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_ctrl_txrx_api.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_ctrl_txrx_api.h + * @brief Define the host control API functions called by the host data SW. + */ +#ifndef _OL_CTRL_TXRX_API__H_ +#define _OL_CTRL_TXRX_API__H_ + +//#include /* u_int8_t */ +#include /* u_int8_t */ +#include /* adf_nbuf_t */ + +#include /* ol_vdev_handle */ +#include /* ol_txrx_peer_handle, etc. */ +#include /*ieee80211_frame */ + +enum ol_rx_err_type { + OL_RX_ERR_DEFRAG_MIC, + OL_RX_ERR_PN, + OL_RX_ERR_UNKNOWN_PEER, + OL_RX_ERR_MALFORMED, + OL_RX_ERR_TKIP_MIC, + OL_RX_ERR_DECRYPT, + OL_RX_ERR_MPDU_LENGTH, + OL_RX_ERR_ENCRYPT_REQUIRED, + OL_RX_ERR_DUP, + OL_RX_ERR_UNKNOWN, + OL_RX_ERR_FCS, + OL_RX_ERR_PRIVACY, + OL_RX_ERR_NONE_FRAG, + OL_RX_ERR_NONE = 0xFF +}; + +#ifdef SUPPORT_HOST_STATISTICS +/** * @brief Update tx statistics + * @details + * Update tx statistics after tx complete. + * + * @param pdev - ol_pdev_handle instance + * @param vdev_id - ID of the virtual device that tx frame + * @param had_error - whether there is error when tx + */ +void ol_tx_statistics(ol_pdev_handle pdev, + u_int16_t vdev_id, + int had_error); +#else +#define ol_tx_statistics(pdev, vdev_id, had_error) +#endif + +/** * @brief Count on received packets for invalid peer case + * + * @param pdev - txrx pdev handle + * @param wh - received frame + * @param err_type - what kind of error occurred + */ +void ol_rx_err_inv_peer_statistics(ol_pdev_handle pdev, + struct ieee80211_frame *wh, + enum ol_rx_err_type err_type); + +/** + * @brief Count on received packets, both success and failed + * + * @param pdev - ol_pdev_handle handle + * @param vdev_id - ID of the virtual device received the erroneous rx frame + * @param err_type - what kind of error occurred + * @param sec_type - The cipher type the peer is using + * @param is_mcast - whether this is one multi cast frame + */ +void ol_rx_err_statistics(ol_pdev_handle pdev, + u_int8_t vdev_id, + enum ol_rx_err_type err_type, + enum ol_sec_type sec_type, + int is_mcast); + +/** + * @brief Provide notification of failure during host rx processing + * @details + * Indicate an error during host rx data processing, including what + * kind of error happened, when it happened, which peer and TID the + * erroneous rx frame is from, and what the erroneous rx frame itself + * is. + * + * @param pdev - handle to the ctrl SW's physical device object + * @param vdev_id - ID of the virtual device received the erroneous rx frame + * @param peer_mac_addr - MAC address of the peer that sent the erroneous + * rx frame + * @param tid - which TID within the peer sent the erroneous rx frame + * @param tsf32 - the timstamp in TSF units of the erroneous rx frame, or + * one of the fragments that when reassembled, constitute the rx frame + * @param err_type - what kind of error occurred + * @param rx_frame - the rx frame that had an error + * @pn - Packet sequence number + * @key_id - Key index octet received in IV of the frame + */ +void +ol_rx_err( + ol_pdev_handle pdev, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tid, + u_int32_t tsf32, + enum ol_rx_err_type err_type, + adf_nbuf_t rx_frame, + u_int64_t *pn, + u_int8_t key_id); + + +enum ol_rx_notify_type { + OL_RX_NOTIFY_IPV4_IGMP, +}; + + +/** + * @brief Provide notification of reception of data of special interest. + * @details + * Indicate when "special" data has been received. The nature of the + * data that results in it being considered special is specified in the + * notify_type argument. + * This function is currently used by the data-path SW to notify the + * control path SW when the following types of rx data are received: + * + IPv4 IGMP frames + * The control SW can use these to learn about multicast group + * membership, if it so chooses. + * + * @param pdev - handle to the ctrl SW's physical device object + * @param vdev_id - ID of the virtual device received the special data + * @param peer_mac_addr - MAC address of the peer that sent the special data + * @param tid - which TID within the peer sent the special data + * @param tsf32 - the timstamp in TSF units of the special data + * @param notify_type - what kind of special data was received + * @param rx_frame - the rx frame containing the special data + */ +void +ol_rx_notify( + ol_pdev_handle pdev, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tid, + u_int32_t tsf32, + enum ol_rx_notify_type notify_type, + adf_nbuf_t rx_frame); + +/** + * @brief Indicate when a paused STA has tx data available. + * @details + * Indicate to the control SW when a paused peer that previously + * has all its peer-TID queues empty gets a MSDU to transmit. + * Conversely, indicate when a paused peer that had data in one or more of + * its peer-TID queues has all queued data removed (e.g. due to a U-APSD + * triggered transmission), but is still paused. + * It is up to the control SW to determine whether the peer is paused due to + * being in power-save sleep, or some other reason, and thus whether it is + * necessary to set the TIM in beacons to notify a sleeping STA that it has + * data. + * The data SW will also issue this ol_tx_paused_peer_data call when an + * unpaused peer that currently has tx data in one or more of its + * peer-TID queues becomes paused. + * The data SW will not issue this ol_tx_paused_peer_data call when a + * peer with data in one or more of its peer-TID queues becomes unpaused. + * + * @param peer - the paused peer + * @param has_tx_data - + * 1 -> a paused peer that previously had no tx data now does, -OR- + * 0 -> a paused peer that previously had tx data now doesnt + */ +void +ol_tx_paused_peer_data(ol_peer_handle peer, int has_tx_data); + + +#define ol_ctrl_addba_req(pdev, peer_mac_addr, tid) ol_addba_req_reject +#define ol_ctrl_rx_addba_complete(pdev, peer_mac_addr, tid, failed) /* no-op */ + + + +#endif /* _OL_CTRL_TXRX_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_osif_txrx_api.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_osif_txrx_api.h new file mode 100644 index 0000000000000..bee1f1d4b1c60 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_osif_txrx_api.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_osif_txrx_api.h + * @brief Define the OS specific API functions called by txrx SW. + */ +#ifndef _OL_OSIF_TXRX_API_H_ +#define _OL_OSIF_TXRX_API_H_ + +#include /* adf_nbuf_t */ + +/** + * @brief Call tx completion handler to release the buffers + * @details + * + * Invoke tx completion handler when the tx credit goes below low water mark. + * This eliminate the packet drop in the host driver due to send routine not yielding + * the cpu when the amount of traffic pumped from the network layer is very high. + * + * @param osdev + */ + +void ol_osif_ath_tasklet(adf_os_device_t osdev); + +#endif /* _OL_OSIF_TXRX_API_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c new file mode 100644 index 0000000000000..5fe67c40ec2aa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -0,0 +1,1306 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_cpu_to_le64 */ +#include /* a_bool_t */ +#include /* ieee80211_frame */ + +/* external API header files */ +#include /* ol_rx_notify */ +#include /* htt_pdev_handle */ +#include /* ol_txrx_pdev_handle */ +#include /* ol_rx_indication_handler */ +#include /* htt_rx_peer_id, etc. */ + +/* internal API header files */ +#include /* ol_txrx_vdev_t, etc. */ +#include /* ol_txrx_peer_find_by_id */ +#include /* ol_rx_reorder_store, etc. */ +#include /* OL_RX_REORDER_TIMEOUT_UPDATE */ +#include /* ol_rx_defrag_waitlist_flush */ +#include +#include +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP +#include /* ol_rx_decap_info_t, etc*/ +#endif + +/* FIX THIS: txrx should not include private header files of other modules */ +#include +#include +#include /* ethernet + SNAP/LLC header defs and ethertype values */ +#include /* IP protocol values */ +#include /* IPv4 header defs */ +#include /* IPv6 header defs */ +#include + +#ifdef HTT_RX_RESTORE +#if defined(CONFIG_CNSS) +#include +#endif +#endif + +#ifdef OSIF_NEED_RX_PEER_ID +#define OL_RX_OSIF_DELIVER(vdev, peer, msdus) \ + vdev->osif_rx(vdev->osif_dev, peer->local_id, msdus) +#else +#define OL_RX_OSIF_DELIVER(vdev, peer, msdus) \ + vdev->osif_rx(vdev->osif_dev, msdus) +#endif /* OSIF_NEED_RX_PEER_ID */ + +#ifdef HTT_RX_RESTORE + +static void ol_rx_restore_handler(struct work_struct *htt_rx) +{ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "Enter: %s", __func__); + cnss_device_self_recovery(); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "Exit: %s", __func__); +} + +static DECLARE_WORK(ol_rx_restore_work, ol_rx_restore_handler); + +void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, adf_nbuf_t head_msdu, + adf_nbuf_t tail_msdu) +{ + adf_nbuf_t next; + + while (head_msdu) { + next = adf_nbuf_next(head_msdu); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "freeing %p\n", head_msdu); + adf_nbuf_free(head_msdu); + head_msdu = next; + } + + if ( !htt_pdev->rx_ring.htt_rx_restore){ + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + htt_pdev->rx_ring.htt_rx_restore = 1; + schedule_work(&ol_rx_restore_work); + } +} +#endif + +static void ol_rx_process_inv_peer( + ol_txrx_pdev_handle pdev, + void *rx_mpdu_desc, + adf_nbuf_t msdu + ) +{ + a_uint8_t a1[IEEE80211_ADDR_LEN]; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + struct ol_txrx_vdev_t *vdev = NULL; + struct ieee80211_frame *wh; + struct wdi_event_rx_peer_invalid_msg msg; + + wh = (struct ieee80211_frame *) + htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev, rx_mpdu_desc); + /* + * Klocwork issue #6152 + * All targets that send a "INVALID_PEER" rx status provide a + * 802.11 header for each rx MPDU, so it is certain that + * htt_rx_mpdu_wifi_hdr_retrieve will succeed. + * However, both for robustness, e.g. if this function is given a + * MSDU descriptor rather than a MPDU descriptor, and to make it + * clear to static analysis that this code is safe, add an explicit + * check that htt_rx_mpdu_wifi_hdr_retrieve provides a non-NULL value. + */ + if (wh == NULL || !IEEE80211_IS_DATA(wh)) { + return; + } + + /* ignore frames for non-existent bssids */ + adf_os_mem_copy(a1, wh->i_addr1, IEEE80211_ADDR_LEN); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (adf_os_mem_cmp(a1, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) { + break; + } + } + if (!vdev) { + return; + } + msg.wh = wh; + msg.msdu = msdu; + msg.vdev_id = vdev->vdev_id; + #ifdef WDI_EVENT_ENABLE + wdi_event_handler(WDI_EVENT_RX_PEER_INVALID, pdev, &msg); + #endif +} + +#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI +static inline int16_t +ol_rx_rssi_avg(struct ol_txrx_pdev_t *pdev, int16_t rssi_old, int16_t rssi_new) +{ + int rssi_old_weight; + + if (rssi_new == HTT_RSSI_INVALID) { + return rssi_old; + } + if (rssi_old == HTT_RSSI_INVALID) { + return rssi_new; + } + rssi_old_weight = (1 << pdev->rssi_update_shift) - pdev->rssi_new_weight; + return (rssi_new * pdev->rssi_new_weight + rssi_old * rssi_old_weight) >> + pdev->rssi_update_shift; +} + +static void +OL_RX_IND_RSSI_UPDATE( + struct ol_txrx_peer_t *peer, + adf_nbuf_t rx_ind_msg) +{ + struct ol_txrx_pdev_t *pdev = peer->vdev->pdev; + peer->rssi_dbm = ol_rx_rssi_avg( + pdev, peer->rssi_dbm, + htt_rx_ind_rssi_dbm(pdev->htt_pdev, rx_ind_msg)); +} + +static void +OL_RX_MPDU_RSSI_UPDATE( + struct ol_txrx_peer_t *peer, + void *rx_mpdu_desc) +{ + struct ol_txrx_pdev_t *pdev = peer->vdev->pdev; + if (! peer) { + return; + } + peer->rssi_dbm = ol_rx_rssi_avg( + pdev, peer->rssi_dbm, + htt_rx_mpdu_desc_rssi_dbm(pdev->htt_pdev, rx_mpdu_desc)); +} + +#else +#define OL_RX_IND_RSSI_UPDATE(peer, rx_ind_msg) /* no-op */ +#define OL_RX_MPDU_RSSI_UPDATE(peer, rx_mpdu_desc) /* no-op */ +#endif /* QCA_SUPPORT_PEER_DATA_RX_RSSI */ + +void +ol_rx_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + u_int16_t peer_id, + u_int8_t tid, + int num_mpdu_ranges) +{ + int mpdu_range; + unsigned seq_num_start = 0, seq_num_end = 0; + a_bool_t rx_ind_release = A_FALSE; + struct ol_txrx_vdev_t *vdev = NULL; + struct ol_txrx_peer_t *peer; + htt_pdev_handle htt_pdev; + + htt_pdev = pdev->htt_pdev; + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer) { + vdev = peer->vdev; + OL_RX_IND_RSSI_UPDATE(peer, rx_ind_msg); + } + + TXRX_STATS_INCR(pdev, priv.rx.normal.ppdus); + + OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev); + + if (htt_rx_ind_flush(pdev->htt_pdev, rx_ind_msg) && peer) { + htt_rx_ind_flush_seq_num_range( + pdev->htt_pdev, rx_ind_msg, &seq_num_start, &seq_num_end); + if (tid == HTT_INVALID_TID) { + /* + * host/FW reorder state went out-of sync + * for a while because FW ran out of Rx indication + * buffer. We have to discard all the buffers in + * reorder queue. + */ + ol_rx_reorder_peer_cleanup(vdev, peer); + } else { + ol_rx_reorder_flush( + vdev, peer, tid, seq_num_start, + seq_num_end, htt_rx_flush_release); + } + } + + if (htt_rx_ind_release(pdev->htt_pdev, rx_ind_msg)) { + /* the ind info of release is saved here and do release at the end. + * This is for the reason of in HL case, the adf_nbuf_t for msg and + * payload are the same buf. And the buf will be changed during + * processing */ + rx_ind_release = A_TRUE; + htt_rx_ind_release_seq_num_range( + pdev->htt_pdev, rx_ind_msg, &seq_num_start, &seq_num_end); + } + +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_initial_msdu_payld = + pdev->htt_pdev->rx_ring.sw_rd_idx.msdu_payld; +#endif + + for (mpdu_range = 0; mpdu_range < num_mpdu_ranges; mpdu_range++) { + enum htt_rx_status status; + int i, num_mpdus; + adf_nbuf_t head_msdu, tail_msdu, msdu; + void *rx_mpdu_desc; + +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_mpdu_range = mpdu_range; +#endif + + htt_rx_ind_mpdu_range_info( + pdev->htt_pdev, rx_ind_msg, mpdu_range, &status, &num_mpdus); + if ((status == htt_rx_status_ok) && peer) { + TXRX_STATS_ADD(pdev, priv.rx.normal.mpdus, num_mpdus); + /* valid frame - deposit it into the rx reordering buffer */ + for (i = 0; i < num_mpdus; i++) { + int msdu_chaining; + /* + * Get a linked list of the MSDUs that comprise this MPDU. + * This also attaches each rx MSDU descriptor to the + * corresponding rx MSDU network buffer. + * (In some systems, the rx MSDU desc is already in the + * same buffer as the MSDU payload; in other systems they + * are separate, so a pointer needs to be set in the netbuf + * to locate the corresponding rx descriptor.) + * + * It is neccessary to call htt_rx_amsdu_pop before + * htt_rx_mpdu_desc_list_next, because the (MPDU) rx + * descriptor has the DMA unmapping done during the + * htt_rx_amsdu_pop call. The rx desc should not be + * accessed until this DMA unmapping has been done, + * since the DMA unmapping involves making sure the + * cache area for the mapped buffer is flushed, so the + * data written by the MAC DMA into memory will be + * fetched, rather than garbage from the cache. + */ + +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_mpdu_count = i; +#endif + + msdu_chaining = htt_rx_amsdu_pop( + htt_pdev, rx_ind_msg, &head_msdu, &tail_msdu); +#ifdef HTT_RX_RESTORE + if (htt_pdev->rx_ring.rx_reset) { + ol_rx_trigger_restore(htt_pdev, head_msdu, tail_msdu); + return; + } +#endif + rx_mpdu_desc = + htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg); + + /* Pktlog */ + #ifdef WDI_EVENT_ENABLE + wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev, head_msdu); + #endif + + if (msdu_chaining) { + /* + * TBDXXX - to deliver SDU with chaining, we need to + * stitch those scattered buffers into one single buffer. + * Just discard it now. + */ + while (1) { + adf_nbuf_t next; + next = adf_nbuf_next(head_msdu); + htt_rx_desc_frame_free(htt_pdev, head_msdu); + if (head_msdu == tail_msdu) { + break; + } + head_msdu = next; + } + } else { + enum htt_rx_status mpdu_status; + int reorder_idx; + reorder_idx = + htt_rx_mpdu_desc_reorder_idx(htt_pdev, rx_mpdu_desc); + OL_RX_REORDER_TRACE_ADD( + pdev, tid, reorder_idx, + htt_rx_mpdu_desc_seq_num(htt_pdev, rx_mpdu_desc), 1); + OL_RX_MPDU_RSSI_UPDATE(peer, rx_mpdu_desc); + /* + * In most cases, out-of-bounds and duplicate sequence + * number detection is performed by the target, but in + * some cases it is done by the host. + * Specifically, the host does rx out-of-bounds sequence + * number detection for: + * 1. Peregrine or Rome target for peer-TIDs that do + * not have aggregation enabled, if the + * RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK flag + * is set during the driver build. + * 2. Riva-family targets, which have rx reorder timeouts + * handled by the host rather than the target. + * (The target already does duplicate detection, but + * the host may have given up waiting for a particular + * sequence number before it arrives. In this case, + * the out-of-bounds sequence number of the late frame + * allows the host to discard it, rather than sending + * it out of order. + */ + mpdu_status = OL_RX_REORDER_SEQ_NUM_CHECK( + pdev, peer, tid, rx_mpdu_desc); + if (mpdu_status != htt_rx_status_ok) { + /* + * If the sequence number was out of bounds, + * the MPDU needs to be discarded. + */ + while (1) { + adf_nbuf_t next; + next = adf_nbuf_next(head_msdu); + htt_rx_desc_frame_free(htt_pdev, head_msdu); + if (head_msdu == tail_msdu) { + break; + } + head_msdu = next; + } + + /* + * For Peregrine and Rome, + * OL_RX_REORDER_SEQ_NUM_CHECK should only fail for + * the case of (duplicate) non-aggregates. + * + * For Riva, Pronto, and Northstar, + * there should be only one MPDU delivered at a time. + * Thus, there are no further MPDUs that need to be + * processed here. + * Just to be sure this is true, check the assumption + * that this was the only MPDU referenced by the rx + * indication. + */ + TXRX_ASSERT2(num_mpdu_ranges == 1 && num_mpdus == 1); + + /* + * The MPDU was not stored in the rx reorder array, + * so there's nothing to release. + */ + rx_ind_release = A_FALSE; + } else { + ol_rx_reorder_store( + pdev, peer, tid, reorder_idx, head_msdu, tail_msdu); + if (peer->tids_rx_reorder[tid].win_sz_mask == 0) { + peer->tids_last_seq[tid] = + htt_rx_mpdu_desc_seq_num(htt_pdev, + rx_mpdu_desc); + } + } + } + } + } else { + /* invalid frames - discard them */ + OL_RX_REORDER_TRACE_ADD( + pdev, tid, TXRX_SEQ_NUM_ERR(status), + TXRX_SEQ_NUM_ERR(status), num_mpdus); + TXRX_STATS_ADD(pdev, priv.rx.err.mpdu_bad, num_mpdus); + for (i = 0; i < num_mpdus; i++) { + /* pull the MPDU's MSDUs off the buffer queue */ + htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &msdu, &tail_msdu); +#ifdef HTT_RX_RESTORE + if (htt_pdev->rx_ring.rx_reset) { + ol_rx_trigger_restore(htt_pdev, msdu, tail_msdu); + return; + } +#endif + /* pull the MPDU desc off the desc queue */ + rx_mpdu_desc = + htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg); + OL_RX_ERR_STATISTICS_2( + pdev, vdev, peer, rx_mpdu_desc, msdu, status); + + if (status == htt_rx_status_tkip_mic_err && + vdev != NULL && peer != NULL) + { + union htt_rx_pn_t pn; + u_int8_t key_id; + htt_rx_mpdu_desc_pn(pdev->htt_pdev, + htt_rx_msdu_desc_retrieve(pdev->htt_pdev, + msdu), &pn, 48); + if (htt_rx_msdu_desc_key_id(pdev->htt_pdev, + htt_rx_msdu_desc_retrieve(pdev->htt_pdev, + msdu), &key_id) == A_TRUE) { + ol_rx_err(pdev->ctrl_pdev, vdev->vdev_id, + peer->mac_addr.raw, tid, 0, + OL_RX_ERR_TKIP_MIC, msdu, &pn.pn48, key_id); + } + } + + #ifdef WDI_EVENT_ENABLE + if (status != htt_rx_status_ctrl_mgmt_null) { + /* Pktlog */ + wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev, msdu); + } + #endif + if (status == htt_rx_status_err_inv_peer) { + /* once per mpdu */ + ol_rx_process_inv_peer(pdev, rx_mpdu_desc, msdu); + } + while (1) { + /* Free the nbuf */ + adf_nbuf_t next; + next = adf_nbuf_next(msdu); + htt_rx_desc_frame_free(htt_pdev, msdu); + if (msdu == tail_msdu) { + break; + } + msdu = next; + } + } + } + } + /* + * Now that a whole batch of MSDUs have been pulled out of HTT + * and put into the rx reorder array, it is an appropriate time + * to request HTT to provide new rx MSDU buffers for the target + * to fill. + * This could be done after the end of this function, but it's + * better to do it now, rather than waiting until after the driver + * and OS finish processing the batch of rx MSDUs. + */ + htt_rx_msdu_buff_replenish(htt_pdev); + + if ((A_TRUE == rx_ind_release) && peer && vdev) { + ol_rx_reorder_release(vdev, peer, tid, seq_num_start, seq_num_end); + } + OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid); + OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev); + + if (pdev->rx.flags.defrag_timeout_check) { + ol_rx_defrag_waitlist_flush(pdev); + } +} + +void +ol_rx_sec_ind_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + enum htt_sec_type sec_type, + int is_unicast, + u_int32_t *michael_key, + u_int32_t *rx_pn) +{ + struct ol_txrx_peer_t *peer; + int sec_index, i; + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (! peer) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "Couldn't find peer from ID %d - skipping security inits\n", + peer_id); + return; + } + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "sec spec for peer %p (%02x:%02x:%02x:%02x:%02x:%02x): " + "%s key of type %d\n", + peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], peer->mac_addr.raw[2], + peer->mac_addr.raw[3], peer->mac_addr.raw[4], peer->mac_addr.raw[5], + is_unicast ? "ucast" : "mcast", + sec_type); + sec_index = is_unicast ? txrx_sec_ucast : txrx_sec_mcast; + peer->security[sec_index].sec_type = sec_type; + /* michael key only valid for TKIP, but for simplicity, copy it anyway */ + adf_os_mem_copy( + &peer->security[sec_index].michael_key[0], + michael_key, + sizeof(peer->security[sec_index].michael_key)); + + if (sec_type != htt_sec_type_wapi) { + adf_os_mem_set(peer->tids_last_pn_valid, 0x00, OL_TXRX_NUM_EXT_TIDS); + } else if (sec_index == txrx_sec_mcast) { + for (i = 0; i < OL_TXRX_NUM_EXT_TIDS; i++) { + /* + * Setting PN valid bit for WAPI sec_type, + * since WAPI PN has to be started with predefined value + */ + peer->tids_last_pn_valid[i] = 1; + adf_os_mem_copy( + (u_int8_t *) &peer->tids_last_pn[i], + (u_int8_t *) rx_pn, sizeof(union htt_rx_pn_t)); + peer->tids_last_pn[i].pn128[1] = + adf_os_cpu_to_le64(peer->tids_last_pn[i].pn128[1]); + peer->tids_last_pn[i].pn128[0] = + adf_os_cpu_to_le64(peer->tids_last_pn[i].pn128[0]); + } + } +} + +#if defined(PERE_IP_HDR_ALIGNMENT_WAR) + +#include + +static void +transcap_nwifi_to_8023(adf_nbuf_t msdu) +{ + struct ieee80211_frame *wh; + a_uint32_t hdrsize; + struct llc *llchdr; + struct ether_header *eth_hdr; + a_uint16_t ether_type = 0; + a_uint8_t a1[IEEE80211_ADDR_LEN]; + a_uint8_t a2[IEEE80211_ADDR_LEN]; + a_uint8_t a3[IEEE80211_ADDR_LEN]; + a_uint8_t fc1; + + wh = (struct ieee80211_frame *)adf_nbuf_data(msdu); + adf_os_mem_copy(a1, wh->i_addr1, IEEE80211_ADDR_LEN); + adf_os_mem_copy(a2, wh->i_addr2, IEEE80211_ADDR_LEN); + adf_os_mem_copy(a3, wh->i_addr3, IEEE80211_ADDR_LEN); + fc1 = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; + /* Native Wifi header is 80211 non-QoS header */ + hdrsize = sizeof(struct ieee80211_frame); + + llchdr = (struct llc *)(((a_uint8_t *)adf_nbuf_data(msdu)) + hdrsize); + ether_type = llchdr->llc_un.type_snap.ether_type; + + /* + * Now move the data pointer to the beginning of the mac header : + * new-header = old-hdr + (wifhdrsize + llchdrsize - ethhdrsize) + */ + adf_nbuf_pull_head( + msdu, (hdrsize + sizeof(struct llc) - sizeof(struct ether_header))); + eth_hdr = (struct ether_header *)(adf_nbuf_data(msdu)); + switch (fc1) { + case IEEE80211_FC1_DIR_NODS: + adf_os_mem_copy(eth_hdr->ether_dhost, a1, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->ether_shost, a2, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_TODS: + adf_os_mem_copy(eth_hdr->ether_dhost, a3, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->ether_shost, a2, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_FROMDS: + adf_os_mem_copy(eth_hdr->ether_dhost, a1, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->ether_shost, a3, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_DSTODS: + break; + } + eth_hdr->ether_type = ether_type; +} +#endif + +void ol_rx_notify(ol_pdev_handle pdev, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tid, + u_int32_t tsf32, + enum ol_rx_notify_type notify_type, + adf_nbuf_t rx_frame) +{ + /* + * NOTE: This is used in qca_main for AP mode to handle IGMP + * packets specially. Umac has a corresponding handler for this + * not sure if we need to have this for CLD as well. + */ +} + +/** + * @brief Look into a rx MSDU to see what kind of special handling it requires + * @details + * This function is called when the host rx SW sees that the target + * rx FW has marked a rx MSDU as needing inspection. + * Based on the results of the inspection, the host rx SW will infer + * what special handling to perform on the rx frame. + * Currently, the only type of frames that require special handling + * are IGMP frames. The rx data-path SW checks if the frame is IGMP + * (it should be, since the target would not have set the inspect flag + * otherwise), and then calls the ol_rx_notify function so the + * control-path SW can perform multicast group membership learning + * by sniffing the IGMP frame. + */ +#define SIZEOF_80211_HDR (sizeof(struct ieee80211_frame)) +void +ol_rx_inspect( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu, + void *rx_desc) +{ + ol_txrx_pdev_handle pdev = vdev->pdev; + u_int8_t *data, *l3_hdr; + u_int16_t ethertype; + int offset; + + data = adf_nbuf_data(msdu); + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + offset = SIZEOF_80211_HDR + LLC_SNAP_HDR_OFFSET_ETHERTYPE; + l3_hdr = data + SIZEOF_80211_HDR + LLC_SNAP_HDR_LEN; + } else { + offset = ETHERNET_ADDR_LEN * 2; + l3_hdr = data + ETHERNET_HDR_LEN; + } + ethertype = (data[offset] << 8) | data[offset+1]; + if (ethertype == ETHERTYPE_IPV4) { + offset = IPV4_HDR_OFFSET_PROTOCOL; + if (l3_hdr[offset] == IP_PROTOCOL_IGMP) { + ol_rx_notify( + pdev->ctrl_pdev, + vdev->vdev_id, + peer->mac_addr.raw, + tid, + htt_rx_mpdu_desc_tsf32(pdev->htt_pdev, rx_desc), + OL_RX_NOTIFY_IPV4_IGMP, + msdu); + } + } +} + +void +ol_rx_offload_deliver_ind_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msg, + int msdu_cnt) +{ + int vdev_id, peer_id, tid; + adf_nbuf_t head_buf, tail_buf, buf; + struct ol_txrx_peer_t *peer; + struct ol_txrx_vdev_t *vdev = NULL; + u_int8_t fw_desc; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + + while (msdu_cnt) { + htt_rx_offload_msdu_pop( + htt_pdev, msg, &vdev_id, &peer_id, + &tid, &fw_desc, &head_buf, &tail_buf); + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer && peer->vdev) { + vdev = peer->vdev; + OL_RX_OSIF_DELIVER(vdev, peer, head_buf); + } else { + buf = head_buf; + while (1) { + adf_nbuf_t next; + next = adf_nbuf_next(buf); + htt_rx_desc_frame_free(htt_pdev, buf); + if (buf == tail_buf) { + break; + } + buf = next; + } + } + msdu_cnt--; + } + htt_rx_msdu_buff_replenish(htt_pdev); +} + +/** + * @brief Check the first msdu to decide whether the a-msdu should be accepted. + */ +a_bool_t +ol_rx_filter( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + void *rx_desc) +{ + #define FILTER_STATUS_REJECT 1 + #define FILTER_STATUS_ACCEPT 0 + u_int8_t *wh; + u_int32_t offset = 0; + u_int16_t ether_type = 0; + a_bool_t is_encrypted = A_FALSE, is_mcast = A_FALSE; + u_int8_t i; + privacy_filter_packet_type packet_type = PRIVACY_FILTER_PACKET_UNICAST; + ol_txrx_pdev_handle pdev = vdev->pdev; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + int sec_idx; + + /* + * Safemode must avoid the PrivacyExemptionList and + * ExcludeUnencrypted checking + */ + if (vdev->safemode) { + return FILTER_STATUS_ACCEPT; + } + + is_mcast = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc); + if (vdev->num_filters > 0) { + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + offset = SIZEOF_80211_HDR + LLC_SNAP_HDR_OFFSET_ETHERTYPE; + } else { + offset = ETHERNET_ADDR_LEN * 2; + } + /* get header info from msdu */ + wh = adf_nbuf_data(msdu); + + /* get ether type */ + ether_type = (wh[offset] << 8) | wh[offset+1]; + /* get packet type */ + if (A_TRUE == is_mcast) { + packet_type = PRIVACY_FILTER_PACKET_MULTICAST; + } else { + packet_type = PRIVACY_FILTER_PACKET_UNICAST; + } + } + /* get encrypt info */ + is_encrypted = htt_rx_mpdu_is_encrypted(htt_pdev, rx_desc); +#ifdef ATH_SUPPORT_WAPI + if ((A_TRUE == is_encrypted) && ( ETHERTYPE_WAI == ether_type )) + { + /* We expect the WAI frames to be always unencrypted when the UMAC + * gets it.*/ + return FILTER_STATUS_REJECT; + } +#endif //ATH_SUPPORT_WAPI + + for (i = 0; i < vdev->num_filters; i++) { + privacy_filter filter_type; + privacy_filter_packet_type filter_packet_type; + + /* skip if the ether type does not match */ + if (vdev->privacy_filters[i].ether_type != ether_type) { + continue; + } + + /* skip if the packet type does not match */ + filter_packet_type = vdev->privacy_filters[i].packet_type; + if (filter_packet_type != packet_type && + filter_packet_type != PRIVACY_FILTER_PACKET_BOTH) + { + continue; + } + + + filter_type = vdev->privacy_filters[i].filter_type; + if (filter_type == PRIVACY_FILTER_ALWAYS) { + /* + * In this case, we accept the frame if and only if it was + * originally NOT encrypted. + */ + if (A_TRUE == is_encrypted) { + return FILTER_STATUS_REJECT; + } else { + return FILTER_STATUS_ACCEPT; + } + } else if (filter_type == PRIVACY_FILTER_KEY_UNAVAILABLE) { + /* + * In this case, we reject the frame if it was originally NOT + * encrypted but we have the key mapping key for this frame. + */ + if (!is_encrypted && !is_mcast && + peer->security[txrx_sec_ucast].sec_type != htt_sec_type_none && + (peer->keyinstalled || !ETHERTYPE_IS_EAPOL_WAPI(ether_type))) + { + return FILTER_STATUS_REJECT; + } else { + return FILTER_STATUS_ACCEPT; + } + } else { + /* + * The privacy exemption does not apply to this frame. + */ + break; + } + } + + /* + * If the privacy exemption list does not apply to the frame, + * check ExcludeUnencrypted. + * If ExcludeUnencrypted is not set, or if this was oringially + * an encrypted frame, it will be accepted. + */ + if (!vdev->drop_unenc || (A_TRUE == is_encrypted)) { + return FILTER_STATUS_ACCEPT; + } + + /* + * If this is a open connection, it will be accepted. + */ + sec_idx = (A_TRUE == is_mcast) ? txrx_sec_mcast : txrx_sec_ucast; + if (peer->security[sec_idx].sec_type == htt_sec_type_none) { + return FILTER_STATUS_ACCEPT; + } + if ((A_FALSE == is_encrypted) && vdev->drop_unenc) { + OL_RX_ERR_STATISTICS( + pdev, vdev, OL_RX_ERR_PRIVACY, + pdev->sec_types[htt_sec_type_none], is_mcast); + } + return FILTER_STATUS_REJECT; +} + +void +ol_rx_deliver( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + ol_txrx_pdev_handle pdev = vdev->pdev; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + adf_nbuf_t deliver_list_head = NULL; + adf_nbuf_t deliver_list_tail = NULL; + adf_nbuf_t msdu; + a_bool_t filter = A_FALSE; +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + struct ol_rx_decap_info_t info; + adf_os_mem_set(&info, 0, sizeof(info)); +#endif + + msdu = msdu_list; + /* + * Check each MSDU to see whether it requires special handling, + * and free each MSDU's rx descriptor + */ + while (msdu) { + void *rx_desc; + int discard, inspect, dummy_fwd; + adf_nbuf_t next = adf_nbuf_next(msdu); + + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu); + // for HL, point to payload right now + if (pdev->cfg.is_high_latency) { + adf_nbuf_pull_head(msdu, + htt_rx_msdu_rx_desc_size_hl(htt_pdev, + rx_desc)); + } + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + info.is_msdu_cmpl_mpdu = + htt_rx_msdu_desc_completes_mpdu(htt_pdev, rx_desc); + info.is_first_subfrm = htt_rx_msdu_first_msdu_flag(htt_pdev, rx_desc); + if (OL_RX_DECAP(vdev, peer, msdu, &info) != A_OK) { + discard = 1; + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "decap error %p from peer %p " + "(%02x:%02x:%02x:%02x:%02x:%02x) len %d\n", + msdu, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5], + adf_nbuf_len(msdu)); + goto DONE; + } +#endif + htt_rx_msdu_actions( + pdev->htt_pdev, rx_desc, &discard, &dummy_fwd, &inspect); + if (inspect) { + ol_rx_inspect(vdev, peer, tid, msdu, rx_desc); + } + + /* + * Check the first msdu in the mpdu, if it will be filtered out, + * then discard the entire mpdu. + */ + if (htt_rx_msdu_first_msdu_flag(htt_pdev, rx_desc)) { + filter = ol_rx_filter(vdev, peer, msdu, rx_desc); + } + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP +DONE: +#endif + htt_rx_msdu_desc_free(htt_pdev, msdu); + if (discard || (A_TRUE == filter)) { + OL_TXRX_FRMS_DUMP( + "rx discarding:", + pdev, deliver_list_head, + ol_txrx_frm_dump_tcp_seq | ol_txrx_frm_dump_contents, + 0 /* don't print contents */); + adf_nbuf_free(msdu); + /* If discarding packet is last packet of the delivery list,NULL terminator should be added for delivery list. */ + if (next == NULL && deliver_list_head){ + adf_nbuf_set_next(deliver_list_tail, NULL); /* add NULL terminator */ + } + } else { + OL_RX_PEER_STATS_UPDATE(peer, msdu); + OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, OL_RX_ERR_NONE); + TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu); + OL_TXRX_LIST_APPEND(deliver_list_head, deliver_list_tail, msdu); + } + msdu = next; + } + /* sanity check - are there any frames left to give to the OS shim? */ + if (!deliver_list_head) { + return; + } + +#if defined(PERE_IP_HDR_ALIGNMENT_WAR) + if (pdev->host_80211_enable) { + for (msdu = deliver_list_head; msdu; msdu = adf_nbuf_next(msdu)) { + transcap_nwifi_to_8023(msdu); + } + } +#endif + + OL_TXRX_FRMS_DUMP( + "rx delivering:", + pdev, deliver_list_head, + ol_txrx_frm_dump_tcp_seq | ol_txrx_frm_dump_contents, + 0 /* don't print contents */); + + OL_RX_OSIF_DELIVER(vdev, peer, deliver_list_head); +} + +void +ol_rx_discard( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + ol_txrx_pdev_handle pdev = vdev->pdev; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + + while (msdu_list) { + adf_nbuf_t msdu = msdu_list; + + msdu_list = adf_nbuf_next(msdu_list); + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "discard rx %p from partly-deleted peer %p " + "(%02x:%02x:%02x:%02x:%02x:%02x)\n", + msdu, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + htt_rx_desc_frame_free(htt_pdev, msdu); + } +} + +void +ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer) +{ + u_int8_t tid; + for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) { + ol_rx_reorder_init(&peer->tids_rx_reorder[tid], tid); + + /* invalid sequence number */ + peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; + } + /* + * Set security defaults: no PN check, no security. + * The target may send a HTT SEC_IND message to overwrite these defaults. + */ + peer->security[txrx_sec_ucast].sec_type = + peer->security[txrx_sec_mcast].sec_type = htt_sec_type_none; + peer->keyinstalled = 0; + adf_os_atomic_init(&peer->fw_pn_check); +} + +void +ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer) +{ + peer->keyinstalled = 0; + ol_rx_reorder_peer_cleanup(vdev, peer); +} + +/* + * Free frames including both rx descriptors and buffers + */ +void +ol_rx_frames_free( + htt_pdev_handle htt_pdev, + adf_nbuf_t frames) +{ + adf_nbuf_t next, frag = frames; + + while (frag) { + next = adf_nbuf_next(frag); + htt_rx_desc_frame_free(htt_pdev, frag); + frag = next; + } +} + +void +ol_rx_in_order_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + u_int16_t peer_id, + u_int8_t tid, + u_int8_t is_offload ) +{ + struct ol_txrx_vdev_t *vdev = NULL; + struct ol_txrx_peer_t *peer = NULL; + htt_pdev_handle htt_pdev = NULL; + int status; + adf_nbuf_t head_msdu, tail_msdu = NULL; + + if (pdev) { + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + htt_pdev = pdev->htt_pdev; + } else { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: Invalid pdev passed!\n", __FUNCTION__); + adf_os_assert_always(pdev); + return; + } + + /* + * Get a linked list of the MSDUs in the rx in order indication. + * This also attaches each rx MSDU descriptor to the + * corresponding rx MSDU network buffer. + */ + status = htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &head_msdu, &tail_msdu); + if (adf_os_unlikely(0 == status)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "%s: Pop status is 0, returning here\n", __FUNCTION__); + return; + } + + /* Replenish the rx buffer ring first to provide buffers to the target + rather than waiting for the indeterminate time taken by the OS to consume + the rx frames */ + htt_rx_msdu_buff_replenish(htt_pdev); + + /* Send the chain of MSDUs to the OS */ + /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ + adf_nbuf_set_next(tail_msdu, NULL); + + /* Pktlog */ +#ifdef WDI_EVENT_ENABLE + wdi_event_handler(WDI_EVENT_RX_DESC_REMOTE, pdev, head_msdu); +#endif + + /* if this is an offload indication, peer id is carried in the rx buffer */ + if (peer) { + vdev = peer->vdev; + } else { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, + "%s: Couldn't find peer from ID 0x%x\n", __FUNCTION__, + peer_id); + while (head_msdu) { + adf_nbuf_t msdu = head_msdu; + + head_msdu = adf_nbuf_next(head_msdu); + htt_rx_desc_frame_free(htt_pdev, msdu); + } + return; + } + + peer->rx_opt_proc(vdev, peer, tid, head_msdu); +} + +/* the msdu_list passed here must be NULL terminated */ +void +ol_rx_in_order_deliver( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + adf_nbuf_t msdu; + + msdu = msdu_list; + /* + * Currently, this does not check each MSDU to see whether it requires + * special handling. MSDUs that need special handling (example: IGMP frames) + * should be sent via a seperate HTT message. Also, this does not do rx->tx + * forwarding or filtering. + */ + + while (msdu) { + adf_nbuf_t next = adf_nbuf_next(msdu); + + OL_RX_PEER_STATS_UPDATE(peer, msdu); + OL_RX_ERR_STATISTICS_1(vdev->pdev, vdev, peer, rx_desc, OL_RX_ERR_NONE); + TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu); + + msdu = next; + } + + OL_TXRX_FRMS_DUMP( + "rx delivering:", + pdev, deliver_list_head, + ol_txrx_frm_dump_tcp_seq | ol_txrx_frm_dump_contents, + 0 /* don't print contents */); + + OL_RX_OSIF_DELIVER(vdev, peer, msdu_list); +} + +void +ol_rx_offload_paddr_deliver_ind_handler( + htt_pdev_handle htt_pdev, + u_int32_t msdu_count, + u_int32_t * msg_word ) +{ + int vdev_id, peer_id, tid; + adf_nbuf_t head_buf, tail_buf, buf; + struct ol_txrx_peer_t *peer; + struct ol_txrx_vdev_t *vdev = NULL; + u_int8_t fw_desc; + int msdu_iter = 0; + + while (msdu_count) { + htt_rx_offload_paddr_msdu_pop_ll( + htt_pdev, msg_word, msdu_iter, &vdev_id, + &peer_id, &tid, &fw_desc, &head_buf, &tail_buf); + + peer = ol_txrx_peer_find_by_id(htt_pdev->txrx_pdev, peer_id); + if (peer && peer->vdev) { + vdev = peer->vdev; + OL_RX_OSIF_DELIVER(vdev, peer, head_buf); + } else { + buf = head_buf; + while (1) { + adf_nbuf_t next; + next = adf_nbuf_next(buf); + htt_rx_desc_frame_free(htt_pdev, buf); + if (buf == tail_buf) { + break; + } + buf = next; + } + } + msdu_iter++; + msdu_count--; + } + htt_rx_msdu_buff_replenish(htt_pdev); +} + +void +ol_rx_mic_error_handler( + ol_txrx_pdev_handle pdev, + u_int8_t tid, + u_int16_t peer_id, + void * msdu_desc, + adf_nbuf_t msdu ) +{ + union htt_rx_pn_t pn = {0}; + u_int8_t key_id = 0; + + struct ol_txrx_peer_t *peer = NULL; + struct ol_txrx_vdev_t *vdev = NULL; + + if (pdev) { + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer) { + vdev = peer->vdev; + if (vdev) { + htt_rx_mpdu_desc_pn(vdev->pdev->htt_pdev, msdu_desc, &pn, 48); + + if (htt_rx_msdu_desc_key_id(vdev->pdev->htt_pdev, msdu_desc, &key_id) + == A_TRUE) { + ol_rx_err(vdev->pdev->ctrl_pdev, vdev->vdev_id, + peer->mac_addr.raw, tid, 0, + OL_RX_ERR_TKIP_MIC, msdu, &pn.pn48, key_id); + } + } + } + } +} +#if 0 +/** + * @brief populates vow ext stats in given network buffer. + * @param msdu - network buffer handle + * @param pdev - handle to htt dev. + */ +void ol_ath_add_vow_extstats(htt_pdev_handle pdev, adf_nbuf_t msdu) +{ + /* FIX THIS: + * txrx should not be directly using data types (scn) + * that are internal to other modules. + */ + struct ol_ath_softc_net80211 *scn = + (struct ol_ath_softc_net80211 *)pdev->ctrl_pdev; + + if (scn->vow_extstats == 0) { + return; + } else { + u_int8_t *data, *l3_hdr, *bp; + u_int16_t ethertype; + int offset; + struct vow_extstats vowstats; + + data = adf_nbuf_data(msdu); + + offset = ETHERNET_ADDR_LEN * 2; + l3_hdr = data + ETHERNET_HDR_LEN; + ethertype = (data[offset] << 8) | data[offset+1]; + if (ethertype == ETHERTYPE_IPV4) { + offset = IPV4_HDR_OFFSET_PROTOCOL; + if ((l3_hdr[offset] == IP_PROTOCOL_UDP) && + (l3_hdr[0] == IP_VER4_N_NO_EXTRA_HEADERS)) + { + bp = data+EXT_HDR_OFFSET; + + if ( (data[RTP_HDR_OFFSET] == UDP_PDU_RTP_EXT) && + (bp[0] == 0x12) && + (bp[1] == 0x34) && + (bp[2] == 0x00) && + (bp[3] == 0x08)) + { + /* + * Clear UDP checksum so we do not have to recalculate it + * after filling in status fields. + */ + data[UDP_CKSUM_OFFSET] = 0; + data[(UDP_CKSUM_OFFSET+1)] = 0; + + bp += IPERF3_DATA_OFFSET; + + htt_rx_get_vowext_stats(msdu, &vowstats); + + /* control channel RSSI */ + *bp++ = vowstats.rx_rssi_ctl0; + *bp++ = vowstats.rx_rssi_ctl1; + *bp++ = vowstats.rx_rssi_ctl2; + + /* rx rate info */ + *bp++ = vowstats.rx_bw; + *bp++ = vowstats.rx_sgi; + *bp++ = vowstats.rx_nss; + + *bp++ = vowstats.rx_rssi_comb; + *bp++ = vowstats.rx_rs_flags; /* rsflags */ + + /* Time stamp Lo*/ + *bp++ = (u_int8_t) + ((vowstats.rx_macTs & 0x0000ff00) >> 8); + *bp++ = (u_int8_t) + (vowstats.rx_macTs & 0x000000ff); + /* rx phy errors */ + *bp++ = (u_int8_t) + ((scn->chan_stats.phy_err_cnt >> 8) & 0xff); + *bp++ = (u_int8_t)(scn->chan_stats.phy_err_cnt & 0xff); + /* rx clear count */ + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.rx_clear_count >> 24) & 0xff); + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.rx_clear_count >> 16) & 0xff); + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.rx_clear_count >> 8) & 0xff); + *bp++ = (u_int8_t) + (scn->mib_cycle_cnts.rx_clear_count & 0xff); + /* rx cycle count */ + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.cycle_count >> 24) & 0xff); + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.cycle_count >> 16) & 0xff); + *bp++ = (u_int8_t) + ((scn->mib_cycle_cnts.cycle_count >> 8) & 0xff); + *bp++ = (u_int8_t) + (scn->mib_cycle_cnts.cycle_count & 0xff); + + *bp++ = vowstats.rx_ratecode; + *bp++ = vowstats.rx_moreaggr; + + /* sequence number */ + *bp++ = (u_int8_t)((vowstats.rx_seqno >> 8) & 0xff); + *bp++ = (u_int8_t)(vowstats.rx_seqno & 0xff); + } + } + } + } +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.h new file mode 100644 index 0000000000000..db4a0fabf3f33 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX__H_ +#define _OL_RX__H_ + +#include /* adf_nbuf_t */ +#include /* ol_txrx_vdev_t, etc. */ + +void +ol_rx_deliver( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t head_msdu); + +void +ol_rx_discard( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t head_msdu); + +void +ol_rx_frames_free( + htt_pdev_handle htt_pdev, + adf_nbuf_t frames); + +void +ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer); + +void +ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer); + +void +ol_rx_in_order_deliver( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t head_msdu); + +void +ol_rx_offload_paddr_deliver_ind_handler( + htt_pdev_handle htt_pdev, + u_int32_t msdu_count, + u_int32_t * msg_word ); + +void +ol_rx_mic_error_handler( + ol_txrx_pdev_handle pdev, + u_int8_t tid, + u_int16_t peer_id, + void * msdu_desc, + adf_nbuf_t msdu ); + +#endif /* _OL_RX__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c new file mode 100644 index 0000000000000..cdbcc7667d073 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c @@ -0,0 +1,1195 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*- +* Copyright (c) 2002-2007 Sam Leffler, Errno Consulting +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* adf_os_time */ + + +#define DEFRAG_IEEE80211_ADDR_EQ(a1, a2) \ + (adf_os_mem_cmp(a1, a2, IEEE80211_ADDR_LEN) == 0) + +#define DEFRAG_IEEE80211_ADDR_COPY(dst, src) \ + adf_os_mem_copy(dst, src, IEEE80211_ADDR_LEN) + +#define DEFRAG_IEEE80211_QOS_HAS_SEQ(wh) \ + (((wh)->i_fc[0] & \ + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +#define DEFRAG_IEEE80211_QOS_GET_TID(_x) \ + ((_x)->i_qos[0] & IEEE80211_QOS_TID) + +const struct ol_rx_defrag_cipher f_ccmp = { + "AES-CCM", + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN, + IEEE80211_WEP_MICLEN, + 0, +}; + +const struct ol_rx_defrag_cipher f_tkip = { + "TKIP", + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN, + IEEE80211_WEP_CRCLEN, + IEEE80211_WEP_MICLEN, +}; + +const struct ol_rx_defrag_cipher f_wep = { + "WEP", + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN, + IEEE80211_WEP_CRCLEN, + 0, +}; + +#if defined(CONFIG_HL_SUPPORT) +static inline struct ieee80211_frame *OL_RX_FRAG_GET_MAC_HDR( + htt_pdev_handle htt_pdev, adf_nbuf_t frag) +{ + void *rx_desc; + int rx_desc_len; + + rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag); + rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc); + return (struct ieee80211_frame *) (adf_nbuf_data(frag) + rx_desc_len); +} +static inline void OL_RX_FRAG_PULL_HDR(htt_pdev_handle htt_pdev, + adf_nbuf_t frag, int hdrsize) +{ + void *rx_desc; + int rx_desc_len; + + rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag); + rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc); + adf_nbuf_pull_head(frag, rx_desc_len + hdrsize); +} +#define OL_RX_FRAG_CLONE(frag) \ + adf_nbuf_clone(frag) +#else +#define OL_RX_FRAG_GET_MAC_HDR(pdev, frag) \ + (struct ieee80211_frame *) adf_nbuf_data(frag) +#define OL_RX_FRAG_PULL_HDR(pdev, frag, hdrsize) \ + adf_nbuf_pull_head(frag, hdrsize); +#define OL_RX_FRAG_CLONE(frag) NULL/* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +static inline void +ol_rx_frag_desc_adjust( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msdu, + void **rx_desc_old_position, + void **ind_old_position, + int *rx_desc_len) +{ + if (pdev->cfg.is_high_latency) { + *rx_desc_old_position = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu); + *ind_old_position = *rx_desc_old_position - HTT_RX_IND_HL_BYTES; + *rx_desc_len = htt_rx_msdu_rx_desc_size_hl(pdev->htt_pdev, + *rx_desc_old_position); + } else { + *rx_desc_old_position = NULL; + *ind_old_position = NULL; + *rx_desc_len = 0; + } +} + +static inline void +ol_rx_frag_restructure( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msdu, + void *rx_desc_old_position, + void *ind_old_position, + const struct ol_rx_defrag_cipher *f_type, + int rx_desc_len) +{ + if (pdev->cfg.is_high_latency) { + if ((ind_old_position == NULL) || (rx_desc_old_position == NULL)) { + printk(KERN_ERR "ind_old_position,rx_desc_old_position is NULL\n"); + ASSERT(0); + return; + } + /* move rx description*/ + adf_os_mem_move(rx_desc_old_position + f_type->ic_header, + rx_desc_old_position, rx_desc_len); + /* move rx indication*/ + adf_os_mem_move(ind_old_position + f_type->ic_header, ind_old_position, + HTT_RX_IND_HL_BYTES); + } else { + /* no op */ + } +} + +/* + * Process incoming fragments + */ +void +ol_rx_frag_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_frag_ind_msg, + u_int16_t peer_id, + u_int8_t tid) +{ + u_int16_t seq_num; + int seq_num_start, seq_num_end; + struct ol_txrx_peer_t *peer; + htt_pdev_handle htt_pdev; + adf_nbuf_t head_msdu, tail_msdu; + void *rx_mpdu_desc; + + htt_pdev = pdev->htt_pdev; + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + + /* In case of reorder offload, we will never get a flush indication */ + if (!ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) && + htt_rx_ind_flush(pdev->htt_pdev, rx_frag_ind_msg) && peer) { + htt_rx_frag_ind_flush_seq_num_range( + pdev->htt_pdev, rx_frag_ind_msg, &seq_num_start, &seq_num_end); + /* + * Assuming flush indication for frags sent from target is seperate + * from normal frames + */ + ol_rx_reorder_flush_frag(htt_pdev, peer, tid, seq_num_start); + } + if (peer) { + htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu, &tail_msdu); + adf_os_assert(head_msdu == tail_msdu); + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) { + rx_mpdu_desc = htt_rx_mpdu_desc_list_next(htt_pdev, head_msdu); + } else { + rx_mpdu_desc = htt_rx_mpdu_desc_list_next(htt_pdev, rx_frag_ind_msg); + } + seq_num = htt_rx_mpdu_desc_seq_num(htt_pdev, rx_mpdu_desc); + OL_RX_ERR_STATISTICS_1(pdev, peer->vdev, peer, rx_mpdu_desc, OL_RX_ERR_NONE_FRAG); + ol_rx_reorder_store_frag(pdev, peer, tid, seq_num, head_msdu); + } else { + /* invalid frame - discard it */ + htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu, &tail_msdu); + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) { + htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu); + } else { + htt_rx_mpdu_desc_list_next(htt_pdev, rx_frag_ind_msg); + } + htt_rx_desc_frame_free(htt_pdev, head_msdu); + } + /* request HTT to provide new rx MSDU buffers for the target to fill. */ + htt_rx_msdu_buff_replenish(htt_pdev); +} + +/* + * Flushing fragments + */ +void +ol_rx_reorder_flush_frag( + htt_pdev_handle htt_pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + int seq_num) +{ + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + int seq; + + seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask; + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[seq]; + if (rx_reorder_array_elem->head) { + ol_rx_frames_free(htt_pdev, rx_reorder_array_elem->head); + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + } +} + +/* + * Reorder and store fragments + */ +void +ol_rx_reorder_store_frag( + ol_txrx_pdev_handle pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + u_int16_t seq_num, + adf_nbuf_t frag) +{ + struct ieee80211_frame *fmac_hdr, *mac_hdr; + u_int8_t fragno, more_frag, all_frag_present = 0; + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + u_int16_t frxseq, rxseq, seq; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + + seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask; + adf_os_assert(seq == 0); + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[seq]; + + mac_hdr = (struct ieee80211_frame *)OL_RX_FRAG_GET_MAC_HDR(htt_pdev, frag); + rxseq = adf_os_le16_to_cpu(*(u_int16_t *) mac_hdr->i_seq) >> + IEEE80211_SEQ_SEQ_SHIFT; + fragno = adf_os_le16_to_cpu(*(u_int16_t *) mac_hdr->i_seq) & + IEEE80211_SEQ_FRAG_MASK; + more_frag = mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG; + + if ((!more_frag) && (!fragno) && (!rx_reorder_array_elem->head)) { + rx_reorder_array_elem->head = frag; + rx_reorder_array_elem->tail = frag; + adf_nbuf_set_next(frag, NULL); + ol_rx_defrag(pdev, peer, tid, rx_reorder_array_elem->head); + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + return; + } + if (rx_reorder_array_elem->head) { + fmac_hdr = (struct ieee80211_frame *)OL_RX_FRAG_GET_MAC_HDR(htt_pdev, + rx_reorder_array_elem->head); + frxseq = adf_os_le16_to_cpu(*(u_int16_t *) fmac_hdr->i_seq) >> + IEEE80211_SEQ_SEQ_SHIFT; + if (rxseq != frxseq || + !DEFRAG_IEEE80211_ADDR_EQ(mac_hdr->i_addr1, fmac_hdr->i_addr1) || + !DEFRAG_IEEE80211_ADDR_EQ(mac_hdr->i_addr2, fmac_hdr->i_addr2)) + { + ol_rx_frames_free(htt_pdev, rx_reorder_array_elem->head); + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_reorder_store: %s mismatch \n", + (rxseq == frxseq) ? "address" : "seq number"); + } + } + + ol_rx_fraglist_insert(htt_pdev, &rx_reorder_array_elem->head, + &rx_reorder_array_elem->tail, frag, &all_frag_present); + + if (pdev->rx.flags.defrag_timeout_check) { + ol_rx_defrag_waitlist_remove(peer, tid); + } + + if (all_frag_present) { + ol_rx_defrag(pdev, peer, tid, rx_reorder_array_elem->head); + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + peer->tids_rx_reorder[tid].defrag_timeout_ms = 0; + peer->tids_last_seq[tid] = seq_num; + } else if (pdev->rx.flags.defrag_timeout_check) { + u_int32_t now_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + + peer->tids_rx_reorder[tid].defrag_timeout_ms = now_ms + pdev->rx.defrag.timeout_ms; + ol_rx_defrag_waitlist_add(peer, tid); + } +} + +/* + * Insert and store fragments + */ +void +ol_rx_fraglist_insert( + htt_pdev_handle htt_pdev, + adf_nbuf_t *head_addr, + adf_nbuf_t *tail_addr, + adf_nbuf_t frag, + u_int8_t *all_frag_present) +{ + adf_nbuf_t next, prev = NULL, cur = *head_addr; + struct ieee80211_frame *mac_hdr, *cmac_hdr, *next_hdr, *lmac_hdr; + u_int8_t fragno, cur_fragno, lfragno, next_fragno; + u_int8_t last_morefrag = 1, count = 0; + adf_nbuf_t frag_clone; + + adf_os_assert(frag); + frag_clone = OL_RX_FRAG_CLONE(frag); + frag = frag_clone ? frag_clone : frag; + + mac_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR(htt_pdev, frag); + fragno = adf_os_le16_to_cpu(*(u_int16_t *) mac_hdr->i_seq) & + IEEE80211_SEQ_FRAG_MASK; + + if (!(*head_addr)) { + *head_addr = frag; + *tail_addr = frag; + adf_nbuf_set_next(*tail_addr, NULL); + return; + } + /* For efficiency, compare with tail first */ + lmac_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR(htt_pdev, + *tail_addr); + lfragno = adf_os_le16_to_cpu(*(u_int16_t *) lmac_hdr->i_seq) & + IEEE80211_SEQ_FRAG_MASK; + if (fragno > lfragno) { + adf_nbuf_set_next(*tail_addr, frag); + *tail_addr = frag; + adf_nbuf_set_next(*tail_addr, NULL); + } else { + do { + cmac_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR( + htt_pdev, cur); + cur_fragno = adf_os_le16_to_cpu(*(u_int16_t *) cmac_hdr->i_seq) & + IEEE80211_SEQ_FRAG_MASK; + prev = cur; + cur = adf_nbuf_next(cur); + } while (fragno > cur_fragno); + + if (fragno == cur_fragno) { + htt_rx_desc_frame_free(htt_pdev, frag); + *all_frag_present = 0; + return; + } else { + adf_nbuf_set_next(prev, frag); + adf_nbuf_set_next(frag, cur); + } + } + next = adf_nbuf_next(*head_addr); + lmac_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR(htt_pdev, + *tail_addr); + last_morefrag = lmac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG; + if (!last_morefrag) { + do { + next_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR( + htt_pdev, next); + next_fragno = adf_os_le16_to_cpu(*(u_int16_t *) next_hdr->i_seq) & + IEEE80211_SEQ_FRAG_MASK; + count++; + if (next_fragno != count) { + break; + } + next = adf_nbuf_next(next); + } while (next); + + if (!next) { + *all_frag_present = 1; + return; + } + } + *all_frag_present = 0; +} + +/* + * add tid to pending fragment wait list + */ +void +ol_rx_defrag_waitlist_add( + struct ol_txrx_peer_t *peer, + unsigned tid) +{ + struct ol_txrx_pdev_t *pdev = peer->vdev->pdev; + struct ol_rx_reorder_t *rx_reorder = &peer->tids_rx_reorder[tid]; + + TAILQ_INSERT_TAIL(&pdev->rx.defrag.waitlist, rx_reorder, + defrag_waitlist_elem); +} + +/* + * remove tid from pending fragment wait list + */ +void +ol_rx_defrag_waitlist_remove( + struct ol_txrx_peer_t *peer, + unsigned tid) +{ + struct ol_txrx_pdev_t *pdev = peer->vdev->pdev; + struct ol_rx_reorder_t *rx_reorder = &peer->tids_rx_reorder[tid]; + + if (rx_reorder->defrag_waitlist_elem.tqe_prev != NULL) { + + TAILQ_REMOVE(&pdev->rx.defrag.waitlist, rx_reorder, + defrag_waitlist_elem); + + rx_reorder->defrag_waitlist_elem.tqe_next = NULL; + rx_reorder->defrag_waitlist_elem.tqe_prev = NULL; + } else if (rx_reorder->defrag_waitlist_elem.tqe_next != NULL) { + TXRX_PRINT(TXRX_PRINT_LEVEL_FATAL_ERR, "waitlist->tqe_prv = NULL\n"); + VOS_ASSERT(0); + rx_reorder->defrag_waitlist_elem.tqe_next = NULL; + } +} + +#ifndef container_of +#define container_of(ptr, type, member) ((type *)( \ + (char *)(ptr) - (char *)(&((type *)0)->member) ) ) +#endif + +/* + * flush stale fragments from the waitlist + */ +void +ol_rx_defrag_waitlist_flush( + struct ol_txrx_pdev_t *pdev) +{ + struct ol_rx_reorder_t *rx_reorder, *tmp; + u_int32_t now_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + + TAILQ_FOREACH_SAFE(rx_reorder, &pdev->rx.defrag.waitlist, + defrag_waitlist_elem, tmp) { + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_t *rx_reorder_base; + unsigned tid; + + if (rx_reorder->defrag_timeout_ms > now_ms) { + break; + } + + tid = rx_reorder->tid; + /* get index 0 of the rx_reorder array */ + rx_reorder_base = rx_reorder - tid; + peer = container_of(rx_reorder_base, struct ol_txrx_peer_t, tids_rx_reorder[0]); + + ol_rx_defrag_waitlist_remove(peer, tid); + ol_rx_reorder_flush_frag(pdev->htt_pdev, peer, tid, 0 /* fragments always stored at seq 0*/); + } +} + +/* + * Handling security checking and processing fragments + */ +void +ol_rx_defrag( + ol_txrx_pdev_handle pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t frag_list) +{ + struct ol_txrx_vdev_t *vdev = NULL; + adf_nbuf_t tmp_next, msdu, prev = NULL, cur = frag_list; + u_int8_t index, tkip_demic = 0; + u_int16_t hdr_space; + void *rx_desc; + struct ieee80211_frame *wh; + u_int8_t key[DEFRAG_IEEE80211_KEY_LEN]; + + htt_pdev_handle htt_pdev = pdev->htt_pdev; + vdev = peer->vdev; + + /* bypass defrag for safe mode */ + if (vdev->safemode) { + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) { + ol_rx_in_order_deliver(vdev, peer, tid, frag_list); + } else { + ol_rx_deliver(vdev, peer, tid, frag_list); + } + return; + } + + while (cur) { + tmp_next = adf_nbuf_next(cur); + adf_nbuf_set_next(cur, NULL); + if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) { + /* PN check failed,discard frags */ + if (prev) { + adf_nbuf_set_next(prev, NULL); + ol_rx_frames_free(htt_pdev, frag_list); + } + ol_rx_frames_free(htt_pdev, tmp_next); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "ol_rx_defrag: PN Check failed\n"); + return; + } + /* remove FCS from each fragment */ + adf_nbuf_trim_tail(cur, DEFRAG_IEEE80211_FCS_LEN); + prev = cur; + adf_nbuf_set_next(cur, tmp_next); + cur = tmp_next; + } + cur = frag_list; + wh = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR(htt_pdev, cur); + hdr_space = ol_rx_frag_hdrsize(wh); + rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag_list); + adf_os_assert(htt_rx_msdu_has_wlan_mcast_flag(htt_pdev, rx_desc)); + index = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc) ? + txrx_sec_mcast : txrx_sec_ucast; + + switch (peer->security[index].sec_type) { + case htt_sec_type_tkip: + tkip_demic = 1; + /* fall-through to rest of tkip ops */ + case htt_sec_type_tkip_nomic: + while (cur) { + tmp_next = adf_nbuf_next(cur); + if (!ol_rx_frag_tkip_decap(pdev, cur, hdr_space)) { + /* TKIP decap failed, discard frags */ + ol_rx_frames_free(htt_pdev, frag_list); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_defrag: TKIP decap failed\n"); + return; + } + cur = tmp_next; + } + break; + + case htt_sec_type_aes_ccmp: + while (cur) { + tmp_next = adf_nbuf_next(cur); + if (!ol_rx_frag_ccmp_demic(pdev, cur, hdr_space)) { + /* CCMP demic failed, discard frags */ + ol_rx_frames_free(htt_pdev, frag_list); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_defrag: CCMP demic failed\n"); + return; + } + if (!ol_rx_frag_ccmp_decap(pdev, cur, hdr_space)) { + /* CCMP decap failed, discard frags */ + ol_rx_frames_free(htt_pdev, frag_list); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_defrag: CCMP decap failed\n"); + return; + } + cur = tmp_next; + } + break; + + case htt_sec_type_wep40: + case htt_sec_type_wep104: + case htt_sec_type_wep128: + while (cur) { + tmp_next = adf_nbuf_next(cur); + if (!ol_rx_frag_wep_decap(pdev, cur, hdr_space)) { + /* wep decap failed, discard frags */ + ol_rx_frames_free(htt_pdev, frag_list); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_defrag: wep decap failed\n"); + return; + } + cur = tmp_next; + } + break; + + default: + break; + } + + msdu = ol_rx_defrag_decap_recombine(htt_pdev, frag_list, hdr_space); + if (!msdu) { + return; + } + + if (tkip_demic) { + adf_os_mem_copy( + key, + peer->security[index].michael_key, + sizeof(peer->security[index].michael_key)); + if (!ol_rx_frag_tkip_demic(pdev, key, msdu, hdr_space)) { + htt_rx_desc_frame_free(htt_pdev, msdu); + ol_rx_err( + pdev->ctrl_pdev, + vdev->vdev_id, peer->mac_addr.raw, tid, 0, OL_RX_DEFRAG_ERR, + msdu, NULL, 0); + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "\n ol_rx_defrag: TKIP demic failed\n"); + return; + } + } + wh = (struct ieee80211_frame *)OL_RX_FRAG_GET_MAC_HDR(htt_pdev, msdu); + if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh)) { + ol_rx_defrag_qos_decap(pdev, msdu, hdr_space); + } + if (ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_802_3) { + ol_rx_defrag_nwifi_to_8023(pdev, msdu); + } + ol_rx_fwd_check(vdev, peer, tid, msdu); +} + +/* + * Handling TKIP processing for defragmentation + */ +int +ol_rx_frag_tkip_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t hdrlen) +{ + u_int8_t *ivp, *origHdr; + + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + msdu, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + /* Header should have extended IV */ + origHdr = (u_int8_t*) (adf_nbuf_data(msdu) + rx_desc_len); + + ivp = origHdr + hdrlen; + if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)) { + return OL_RX_DEFRAG_ERR; + } + adf_os_mem_move(origHdr + f_tkip.ic_header, origHdr, hdrlen); + + ol_rx_frag_restructure( + pdev, + msdu, + rx_desc_old_position, + ind_old_position, + &f_tkip, + rx_desc_len); + + adf_nbuf_pull_head(msdu, f_tkip.ic_header); + adf_nbuf_trim_tail(msdu, f_tkip.ic_trailer); + return OL_RX_DEFRAG_OK; +} + +/* + * Handling WEP processing for defragmentation + */ +int +ol_rx_frag_wep_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t hdrlen) +{ + u_int8_t *origHdr; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + msdu, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + origHdr = (u_int8_t*) (adf_nbuf_data(msdu) + rx_desc_len); + adf_os_mem_move(origHdr + f_wep.ic_header, origHdr, hdrlen); + + ol_rx_frag_restructure( + pdev, + msdu, + rx_desc_old_position, + ind_old_position, + &f_wep, + rx_desc_len); + adf_nbuf_pull_head(msdu, f_wep.ic_header); + adf_nbuf_trim_tail(msdu, f_wep.ic_trailer); + return OL_RX_DEFRAG_OK; +} + +/* + * Verify and strip MIC from the frame. + */ +int +ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const u_int8_t *key, + adf_nbuf_t msdu, u_int16_t hdrlen) +{ + int status; + u_int32_t pktlen; + u_int8_t mic[IEEE80211_WEP_MICLEN]; + u_int8_t mic0[IEEE80211_WEP_MICLEN]; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + msdu, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + pktlen = ol_rx_defrag_len(msdu) - rx_desc_len; + + status = ol_rx_defrag_mic(pdev, key, msdu, hdrlen, + pktlen - (hdrlen + f_tkip.ic_miclen), mic); + if (status != OL_RX_DEFRAG_OK) { + return OL_RX_DEFRAG_ERR; + } + ol_rx_defrag_copydata( + msdu, pktlen - f_tkip.ic_miclen + rx_desc_len, f_tkip.ic_miclen, + (caddr_t) mic0); + if (adf_os_mem_cmp(mic, mic0, f_tkip.ic_miclen)) { + return OL_RX_DEFRAG_ERR; + } + adf_nbuf_trim_tail(msdu, f_tkip.ic_miclen); + return OL_RX_DEFRAG_OK; +} + +/* + * Handling CCMP processing for defragmentation + */ +int +ol_rx_frag_ccmp_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t nbuf, + u_int16_t hdrlen) +{ + u_int8_t *ivp, *origHdr; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + nbuf, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + origHdr = (u_int8_t *) (adf_nbuf_data(nbuf) + rx_desc_len); + ivp = origHdr + hdrlen; + if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)) { + return OL_RX_DEFRAG_ERR; + } + adf_os_mem_move(origHdr + f_ccmp.ic_header, origHdr, hdrlen); + + ol_rx_frag_restructure( + pdev, + nbuf, + rx_desc_old_position, + ind_old_position, + &f_ccmp, + rx_desc_len); + + adf_nbuf_pull_head(nbuf, f_ccmp.ic_header); + + return OL_RX_DEFRAG_OK; +} + +/* + * Verify and strip MIC from the frame. + */ +int +ol_rx_frag_ccmp_demic( + ol_txrx_pdev_handle pdev, + adf_nbuf_t wbuf, + u_int16_t hdrlen) +{ + u_int8_t *ivp, *origHdr; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + wbuf, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + origHdr = (u_int8_t *) (adf_nbuf_data(wbuf) + rx_desc_len); + + ivp = origHdr + hdrlen; + if (!(ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)) { + return OL_RX_DEFRAG_ERR; + } + adf_nbuf_trim_tail(wbuf, f_ccmp.ic_trailer); + + return OL_RX_DEFRAG_OK; +} + +/* + * Craft pseudo header used to calculate the MIC. + */ +void +ol_rx_defrag_michdr( + const struct ieee80211_frame *wh0, + u_int8_t hdr[]) +{ + const struct ieee80211_frame_addr4 *wh = + (const struct ieee80211_frame_addr4 *) wh0; + + switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { + case IEEE80211_FC1_DIR_NODS: + DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */ + DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2); + break; + case IEEE80211_FC1_DIR_TODS: + DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */ + DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2); + break; + case IEEE80211_FC1_DIR_FROMDS: + DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */ + DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3); + break; + case IEEE80211_FC1_DIR_DSTODS: + DEFRAG_IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */ + DEFRAG_IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4); + break; + } + /* + * Bit 7 is IEEE80211_FC0_SUBTYPE_QOS for data frame, but + * it could also be set for deauth, disassoc, action, etc. for + * a mgt type frame. It comes into picture for MFP. + */ + if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + const struct ieee80211_qosframe *qwh = + (const struct ieee80211_qosframe *) wh; + hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID; + } else { + hdr[12] = 0; + } + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ +} + +/* + * Michael_mic for defragmentation + */ +int +ol_rx_defrag_mic( + ol_txrx_pdev_handle pdev, + const u_int8_t *key, + adf_nbuf_t wbuf, + u_int16_t off, + u_int16_t data_len, + u_int8_t mic[]) +{ + u_int8_t hdr[16] = {0,}; + u_int32_t l, r; + const u_int8_t *data; + u_int32_t space; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + + ol_rx_frag_desc_adjust( + pdev, + wbuf, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + ol_rx_defrag_michdr((struct ieee80211_frame *) (adf_nbuf_data(wbuf) + + rx_desc_len), hdr); + l = get_le32(key); + r = get_le32(key + 4); + + /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ + l ^= get_le32(hdr); + michael_block(l, r); + l ^= get_le32(&hdr[4]); + michael_block(l, r); + l ^= get_le32(&hdr[8]); + michael_block(l, r); + l ^= get_le32(&hdr[12]); + michael_block(l, r); + + /* first buffer has special handling */ + data = (u_int8_t *)adf_nbuf_data(wbuf) + rx_desc_len + off; + space = ol_rx_defrag_len(wbuf) - rx_desc_len - off; + for (;;) { + if (space > data_len) { + space = data_len; + } + /* collect 32-bit blocks from current buffer */ + while (space >= sizeof(u_int32_t)) { + l ^= get_le32(data); + michael_block(l, r); + data += sizeof(u_int32_t); + space -= sizeof(u_int32_t); + data_len -= sizeof(u_int32_t); + } + if (data_len < sizeof(u_int32_t)) { + break; + } + wbuf = adf_nbuf_next(wbuf); + if (wbuf == NULL) { + return OL_RX_DEFRAG_ERR; + } + if (pdev->cfg.is_high_latency) { + rx_desc_old_position = htt_rx_msdu_desc_retrieve(htt_pdev, wbuf); + rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, + rx_desc_old_position); + } else { + rx_desc_len = 0; + } + if (space != 0) { + const u_int8_t *data_next; + /* + * Block straddles buffers, split references. + */ + data_next = (u_int8_t *)adf_nbuf_data(wbuf) + rx_desc_len; + if ((ol_rx_defrag_len(wbuf) - rx_desc_len) < + sizeof(u_int32_t) - space) { + return OL_RX_DEFRAG_ERR; + } + switch (space) { + case 1: + l ^= get_le32_split( + data[0], data_next[0], data_next[1], data_next[2]); + data = data_next + 3; + space = (ol_rx_defrag_len(wbuf) - rx_desc_len) - 3; + break; + case 2: + l ^= get_le32_split( + data[0], data[1], data_next[0], data_next[1]); + data = data_next + 2; + space = (ol_rx_defrag_len(wbuf) - rx_desc_len) - 2; + break; + case 3: + l ^= get_le32_split( + data[0], data[1], data[2], data_next[0]); + data = data_next + 1; + space = (ol_rx_defrag_len(wbuf) - rx_desc_len) - 1; + break; + } + michael_block(l, r); + data_len -= sizeof(u_int32_t); + } else { + /* + * Setup for next buffer. + */ + data = (u_int8_t*) adf_nbuf_data(wbuf) + rx_desc_len; + space = ol_rx_defrag_len(wbuf) - rx_desc_len; + } + } + /* Last block and padding (0x5a, 4..7 x 0) */ + switch (data_len) { + case 0: + l ^= get_le32_split(0x5a, 0, 0, 0); + break; + case 1: + l ^= get_le32_split(data[0], 0x5a, 0, 0); + break; + case 2: + l ^= get_le32_split(data[0], data[1], 0x5a, 0); + break; + case 3: + l ^= get_le32_split(data[0], data[1], data[2], 0x5a); + break; + } + michael_block(l, r); + michael_block(l, r); + put_le32(mic, l); + put_le32(mic + 4, r); + + return OL_RX_DEFRAG_OK; +} + +/* + * Calculate headersize + */ +u_int16_t +ol_rx_frag_hdrsize(const void *data) +{ + const struct ieee80211_frame *wh = (const struct ieee80211_frame *) data; + u_int16_t size = sizeof(struct ieee80211_frame); + + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { + size += IEEE80211_ADDR_LEN; + } + if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh)) { + size += sizeof(u_int16_t); + if (wh->i_fc[1] & IEEE80211_FC1_ORDER) { + size += sizeof(struct ieee80211_htc); + } + } + return size; +} + +/* + * Recombine and decap fragments + */ +adf_nbuf_t +ol_rx_defrag_decap_recombine( + htt_pdev_handle htt_pdev, + adf_nbuf_t frag_list, + u_int16_t hdrsize) +{ + adf_nbuf_t tmp; + adf_nbuf_t msdu = frag_list; + adf_nbuf_t rx_nbuf = frag_list; + struct ieee80211_frame* wh; + + msdu = adf_nbuf_next(msdu); + adf_nbuf_set_next(rx_nbuf, NULL); + while (msdu) { + htt_rx_msdu_desc_free(htt_pdev, msdu); + tmp = adf_nbuf_next(msdu); + adf_nbuf_set_next(msdu, NULL); + OL_RX_FRAG_PULL_HDR(htt_pdev, msdu, hdrsize); + if (!ol_rx_defrag_concat(rx_nbuf, msdu)) { + ol_rx_frames_free(htt_pdev, tmp); + htt_rx_desc_frame_free(htt_pdev, rx_nbuf); + adf_nbuf_free(msdu); /* msdu rx desc already freed above */ + return NULL; + } + msdu = tmp; + } + wh = (struct ieee80211_frame *)OL_RX_FRAG_GET_MAC_HDR(htt_pdev, rx_nbuf); + wh->i_fc[1] &= ~IEEE80211_FC1_MORE_FRAG; + *(u_int16_t *) wh->i_seq &= ~IEEE80211_SEQ_FRAG_MASK; + + return rx_nbuf; +} + +void +ol_rx_defrag_nwifi_to_8023(ol_txrx_pdev_handle pdev, adf_nbuf_t msdu) +{ + struct ieee80211_frame wh; + a_uint32_t hdrsize; + struct llc_snap_hdr_t llchdr; + struct ethernet_hdr_t *eth_hdr; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + struct ieee80211_frame *wh_ptr; + + ol_rx_frag_desc_adjust( + pdev, + msdu, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + wh_ptr = (struct ieee80211_frame *) (adf_nbuf_data(msdu) + rx_desc_len); + adf_os_mem_copy(&wh, wh_ptr, sizeof(wh)); + hdrsize = sizeof(struct ieee80211_frame); + adf_os_mem_copy(&llchdr, ((a_uint8_t *) (adf_nbuf_data(msdu) + + rx_desc_len)) + hdrsize, sizeof(struct llc_snap_hdr_t)); + + /* + * Now move the data pointer to the beginning of the mac header : + * new-header = old-hdr + (wifhdrsize + llchdrsize - ethhdrsize) + */ + adf_nbuf_pull_head(msdu, (rx_desc_len + hdrsize + + sizeof(struct llc_snap_hdr_t) - sizeof(struct ethernet_hdr_t))); + eth_hdr = (struct ethernet_hdr_t *)(adf_nbuf_data(msdu)); + switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { + case IEEE80211_FC1_DIR_NODS: + adf_os_mem_copy(eth_hdr->dest_addr, wh.i_addr1, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->src_addr, wh.i_addr2, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_TODS: + adf_os_mem_copy(eth_hdr->dest_addr, wh.i_addr3, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->src_addr, wh.i_addr2, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_FROMDS: + adf_os_mem_copy(eth_hdr->dest_addr, wh.i_addr1, IEEE80211_ADDR_LEN); + adf_os_mem_copy(eth_hdr->src_addr, wh.i_addr3, IEEE80211_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_DSTODS: + break; + } + + adf_os_mem_copy( + eth_hdr->ethertype, llchdr.ethertype, sizeof(llchdr.ethertype)); + if (pdev->cfg.is_high_latency) { + adf_nbuf_push_head(msdu, rx_desc_len); + adf_os_mem_move( + adf_nbuf_data(msdu), rx_desc_old_position, rx_desc_len); + adf_os_mem_move( + adf_nbuf_data(msdu) - HTT_RX_IND_HL_BYTES, ind_old_position, + HTT_RX_IND_HL_BYTES); + } +} + +/* + * Handling QOS for defragmentation + */ +void +ol_rx_defrag_qos_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t nbuf, + u_int16_t hdrlen) +{ + struct ieee80211_frame *wh; + u_int16_t qoslen; + void *rx_desc_old_position = NULL; + void *ind_old_position = NULL; + int rx_desc_len = 0; + + ol_rx_frag_desc_adjust( + pdev, + nbuf, + &rx_desc_old_position, + &ind_old_position, + &rx_desc_len); + + wh = (struct ieee80211_frame *) (adf_nbuf_data(nbuf)+rx_desc_len); + if (DEFRAG_IEEE80211_QOS_HAS_SEQ(wh)) { + qoslen = sizeof(struct ieee80211_qoscntl); + /* Qos frame with Order bit set indicates a HTC frame */ + if (wh->i_fc[1] & IEEE80211_FC1_ORDER) { + qoslen += sizeof(struct ieee80211_htc); + } + + /* remove QoS filed from header */ + hdrlen -= qoslen; + adf_os_mem_move((u_int8_t *) wh + qoslen, wh, hdrlen); + wh = (struct ieee80211_frame *) adf_nbuf_pull_head(nbuf, + rx_desc_len + qoslen); + /* clear QoS bit */ + /* + * KW# 6154 'adf_nbuf_pull_head' in turn calls __adf_nbuf_pull_head, + * which returns NULL if there is not sufficient data to pull. + * It's guaranteed that adf_nbuf_pull_head will succeed rather than + * returning NULL, since the entire rx frame is already present in the + * rx buffer. + * However, to make it obvious to static analyzers that this code is + * safe, add an explicit check that adf_nbuf_pull_head returns a + * non-NULL value. + * Since this part of the code is not performance-critical, adding this + * explicit check is okay. + */ + if (wh) { + wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS; + } + if (pdev->cfg.is_high_latency) { + adf_nbuf_push_head(nbuf, rx_desc_len); + adf_os_mem_move( + adf_nbuf_data(nbuf), rx_desc_old_position, rx_desc_len); + adf_os_mem_move( + adf_nbuf_data(nbuf)-HTT_RX_IND_HL_BYTES, ind_old_position, + HTT_RX_IND_HL_BYTES); + } + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h new file mode 100644 index 0000000000000..737c299873057 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_defrag.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX_DEFRAG_H_ +#define _OL_RX_DEFRAG_H_ + +#include +#include +#include +#include +#include +#include +#include + + +#define DEFRAG_IEEE80211_ADDR_LEN 6 +#define DEFRAG_IEEE80211_KEY_LEN 8 +#define DEFRAG_IEEE80211_FCS_LEN 4 + +struct ol_rx_defrag_cipher { + const char *ic_name; + u_int16_t ic_header; + u_int8_t ic_trailer; + u_int8_t ic_miclen; +}; + +enum { + OL_RX_DEFRAG_ERR, + OL_RX_DEFRAG_OK, + OL_RX_DEFRAG_PN_ERR +}; + +#define ol_rx_defrag_copydata(buf, offset, len, _to) \ + adf_nbuf_copy_bits(buf, offset, len, _to) + +#define ol_rx_defrag_len(buf) \ + adf_nbuf_len(buf) + +void +ol_rx_fraglist_insert( + htt_pdev_handle htt_pdev, + adf_nbuf_t *head_addr, + adf_nbuf_t *tail_addr, + adf_nbuf_t frag, + u_int8_t *all_frag_present); + +void +ol_rx_defrag_waitlist_add( + struct ol_txrx_peer_t *peer, + unsigned tid); + +void +ol_rx_defrag_waitlist_remove( + struct ol_txrx_peer_t *peer, + unsigned tid); + +void +ol_rx_defrag_waitlist_flush( + struct ol_txrx_pdev_t *pdev); + +void +ol_rx_defrag( + ol_txrx_pdev_handle pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t frag_list); + +int +ol_rx_frag_tkip_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msdu, + u_int16_t hdrlen); + +int +ol_rx_frag_wep_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t nbuf, + u_int16_t hdrlen); + +void +ol_rx_defrag_nwifi_to_8023(ol_txrx_pdev_handle pdev, adf_nbuf_t msdu); + +void +ol_rx_defrag_qos_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t nbuf, + u_int16_t hdrlen); + +int +ol_rx_frag_tkip_demic( + ol_txrx_pdev_handle pdev, + const u_int8_t *key, + adf_nbuf_t msdu, + u_int16_t hdrlen); + +int +ol_rx_frag_ccmp_decap( + ol_txrx_pdev_handle pdev, + adf_nbuf_t nbuf, + u_int16_t hdrlen); + +int +ol_rx_frag_ccmp_demic( + ol_txrx_pdev_handle pdev, + adf_nbuf_t wbuf, + u_int16_t hdrlen); + +u_int16_t +ol_rx_frag_hdrsize(const void *data); + +void +ol_rx_defrag_michdr( + const struct ieee80211_frame *wh0, + u_int8_t hdr[]); + +void +ol_rx_reorder_store_frag( + ol_txrx_pdev_handle pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + u_int16_t seq_num, + adf_nbuf_t frag); + +adf_nbuf_t +ol_rx_defrag_decap_recombine( + htt_pdev_handle htt_pdev, + adf_nbuf_t frag_list, + u_int16_t hdrsize); + +int +ol_rx_defrag_mic( + ol_txrx_pdev_handle pdev, + const u_int8_t *key, + adf_nbuf_t wbuf, + u_int16_t off, + u_int16_t data_len, + u_int8_t mic[]); + +void +ol_rx_reorder_flush_frag( + htt_pdev_handle htt_pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + int seq_num); + +static inline void +xor_block( + u_int8_t *b, + const u_int8_t *a, + adf_os_size_t len) +{ + adf_os_size_t i; + + for (i = 0; i < len; i++) { + b[i] ^= a[i]; + } +} + +static inline u_int32_t +rotl( + u_int32_t val, + int bits) +{ + return (val << bits) | (val >> (32 - bits)); +} + +static inline u_int32_t +rotr( + u_int32_t val, + int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +static inline u_int32_t +xswap(u_int32_t val) +{ + return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); +} + +static inline u_int32_t +get_le32_split( + u_int8_t b0, + u_int8_t b1, + u_int8_t b2, + u_int8_t b3) +{ + return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); +} + +static inline u_int32_t +get_le32(const u_int8_t *p) +{ + return get_le32_split(p[0], p[1], p[2], p[3]); +} + +static inline void +put_le32( + u_int8_t *p, + u_int32_t v) +{ + p[0] = (v) & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; +} + +static inline u_int8_t +ol_rx_defrag_concat( + adf_nbuf_t dst, + adf_nbuf_t src) +{ + /* + * Inside adf_nbuf_cat, if it is necessary to reallocate dst + * to provide space for src, the headroom portion is copied from + * the original dst buffer to the larger new dst buffer. + * (This is needed, because the headroom of the dst buffer + * contains the rx desc.) + */ + if (adf_nbuf_cat(dst, src)) { + return OL_RX_DEFRAG_ERR; + } + + return OL_RX_DEFRAG_OK; +} + +#define michael_block(l, r) \ + do { \ + r ^= rotl(l, 17); \ + l += r; \ + r ^= xswap(l); \ + l += r; \ + r ^= rotl(l, 3); \ + l += r; \ + r ^= rotr(l, 2); \ + l += r; \ + } while (0) + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c new file mode 100644 index 0000000000000..a55035c64217d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* standard header files */ +#include /* adf_nbuf_map */ +#include /* adf_os_mem_cmp */ + +/* external header files */ +#include /* wlan_op_mode_ap, etc. */ +#include /* htt_rx_msdu_desc_retrieve */ +#include /* ieee80211_frame, etc. */ + +/* internal header files */ +#include /* ol_txrx_dev_t, etc. */ +#include /* our own defs */ +#include /* ol_rx_deliver */ +#include /* TXRX_ASSERT1 */ + +/* + * Porting from Ap11PrepareForwardedPacket. + * This routine is called when a RX data frame from an associated station is + * to be forwarded to another associated station. We will prepare the + * received packet so that it is suitable for transmission again. + * Check that this Packet is suitable for forwarding. If yes, then + * prepare the new 802.11 header. + */ +static inline +void +ol_ap_fwd_check(struct ol_txrx_vdev_t *vdev, adf_nbuf_t msdu) +{ + struct ieee80211_frame *mac_header; + unsigned char tmp_addr[6]; + unsigned char type; + unsigned char subtype; + unsigned char fromds; + unsigned char tods; + + mac_header = (struct ieee80211_frame *) (adf_nbuf_data(msdu)); + TXRX_ASSERT1(mac_header); + + type = mac_header->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + subtype = mac_header->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; + tods = mac_header->i_fc[1] & IEEE80211_FC1_DIR_TODS; + fromds = mac_header->i_fc[1] & IEEE80211_FC1_DIR_FROMDS; + + /* + * Make sure no QOS or any other non-data subtype + * Should be a ToDs data frame. + * Make sure that this frame is unicast and not for us. + * These packets should come up through the normal rx path and not forwarded. + */ + if (type != IEEE80211_FC0_TYPE_DATA || + subtype != 0x0 || + ((tods != 1) || (fromds != 0)) || + (adf_os_mem_cmp( + mac_header->i_addr3, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0)) + { +#ifdef DEBUG_HOST_RC + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "Exit: %s | Unnecessary to adjust mac header\n", __func__); +#endif + } + else + { + // Flip the ToDs bit to FromDs + mac_header->i_fc[1] &= 0xfe; + mac_header->i_fc[1] |= 0x2; + + /* + * Flip the addresses + * (ToDs, addr1, RA=BSSID) move to (FrDs, addr2, TA=BSSID) + * (ToDs, addr2, SA) move to (FrDs, addr3, SA) + * (ToDs, addr3, DA) move to (FrDs, addr1, DA) + */ + + memcpy(tmp_addr, + mac_header->i_addr2, + sizeof (tmp_addr)); + + memcpy(mac_header->i_addr2, + mac_header->i_addr1, + sizeof (tmp_addr)); + + memcpy(mac_header->i_addr1, + mac_header->i_addr3, + sizeof (tmp_addr)); + + memcpy(mac_header->i_addr3, + tmp_addr, + sizeof (tmp_addr)); + } +} + +static inline +void +ol_rx_fwd_to_tx(struct ol_txrx_vdev_t *vdev, adf_nbuf_t msdu) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + if (pdev->frame_format == wlan_frm_fmt_native_wifi) + { + ol_ap_fwd_check(vdev, msdu); + } + /* + * Map the netbuf, so it's accessible to the DMA that + * sends it to the target. + */ + adf_nbuf_map_single(pdev->osdev, msdu, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_set_next(msdu, NULL); /* add NULL terminator */ + TXRX_STATS_MSDU_INCR(vdev->pdev, rx.forwarded, msdu); + + /* for HL, point to payload before send to tx again.*/ + if (pdev->cfg.is_high_latency) { + void *rx_desc; + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu); + + adf_nbuf_pull_head(msdu, + htt_rx_msdu_rx_desc_size_hl(pdev->htt_pdev, + rx_desc)); + } + + msdu = vdev->tx(vdev, msdu); + + if (msdu) { + /* + * The frame was not accepted by the tx. + * We could store the frame and try again later, + * but the simplest solution is to discard the frames. + */ + adf_nbuf_unmap_single(pdev->osdev, msdu, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(msdu); + } +} + +void +ol_rx_fwd_check( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + adf_nbuf_t deliver_list_head = NULL; + adf_nbuf_t deliver_list_tail = NULL; + adf_nbuf_t msdu; + + msdu = msdu_list; + while (msdu) { + struct ol_txrx_vdev_t *tx_vdev; + void *rx_desc; + /* + * Remember the next list elem, because our processing + * may cause the MSDU to get linked into a different list. + */ + msdu_list = adf_nbuf_next(msdu); + + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu); + + if (!vdev->disable_intrabss_fwd && + htt_rx_msdu_forward(pdev->htt_pdev, rx_desc)) { + /* + * Use the same vdev that received the frame to + * transmit the frame. + * This is exactly what we want for intra-BSS forwarding, + * like STA-to-STA forwarding and multicast echo. + * If this is a intra-BSS forwarding case (which is not + * currently supported), then the tx vdev is different + * from the rx vdev. + * On the LL host the vdevs are not actually used for tx, + * so it would still work to use the rx vdev rather than + * the tx vdev. + * For HL, the tx classification searches for the DA within + * the given vdev, so we would want to get the DA peer ID + * from the target, so we can locate the tx vdev. + */ + tx_vdev = vdev; + /* + * Copying TID value of RX packet to forwarded + * packet if the tid is other than non qos tid. + * But for non qos tid fill invalid tid so that + * Fw will take care of filling proper tid. + */ + if (tid != HTT_NON_QOS_TID) { + adf_nbuf_set_tid(msdu, tid); + } else { + adf_nbuf_set_tid(msdu, ADF_NBUF_TX_EXT_TID_INVALID); + } + /* + * This MSDU needs to be forwarded to the tx path. + * Check whether it also needs to be sent to the OS shim, + * in which case we need to make a copy (or clone?). + */ + if (htt_rx_msdu_discard(pdev->htt_pdev, rx_desc)) { + htt_rx_msdu_desc_free(pdev->htt_pdev, msdu); + ol_rx_fwd_to_tx(tx_vdev, msdu); + msdu = NULL; /* already handled this MSDU */ + } else { + adf_nbuf_t copy; + copy = adf_nbuf_copy(msdu); + if (copy) { + ol_rx_fwd_to_tx(tx_vdev, copy); + } + } + } + if (msdu) { + /* send this frame to the OS */ + OL_TXRX_LIST_APPEND(deliver_list_head, deliver_list_tail, msdu); + } + msdu = msdu_list; + } + if (deliver_list_head) { + adf_nbuf_set_next(deliver_list_tail, NULL); /* add NULL terminator */ + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) { + ol_rx_in_order_deliver(vdev, peer, tid, deliver_list_head); + } else { + ol_rx_deliver(vdev, peer, tid, deliver_list_head); + } + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h new file mode 100644 index 0000000000000..928c151625f92 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX_FWD_H_ +#define _OL_RX_FWD_H_ + +#include /* adf_nbuf_t, etc. */ + +#include /* ol_txrx_peer_t, etc. */ + +adf_nbuf_t +ol_rx_fwd_mcast_check_sta( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + void *rx_desc, + int is_wlan_mcast); + +adf_nbuf_t +ol_rx_fwd_mcast_check_ap( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + void *rx_desc, + int is_wlan_mcast); + +/** + * @brief Check if rx frames should be transmitted over WLAN. + * @details + * Check if rx frames should be transmitted back over WLAN, instead of + * or in addition to delivering the rx frames to the OS. + * Rx frames will be forwarded to the transmit path under the following + * conditions: + * 1. If the destination is a STA associated to the same virtual device + * within this physical device, the rx frame will be forwarded to the + * tx path rather than being sent to the OS. If the destination is a + * STA associated to a different virtual device within this physical + * device, then the rx frame will optionally be forwarded to the tx path. + * 2. If the frame is received by an AP, but the destination is for another + * AP that the current AP is associated with for WDS forwarding, the + * intermediate AP will forward the rx frame to the tx path to transmit + * to send to the destination AP, rather than sending it to the OS. + * 3. If the AP receives a multicast frame, it will retransmit the frame + * within the BSS, in addition to sending the frame to the OS. + * + * @param vdev - which virtual device the frames were addressed to + * @param peer - which peer the rx frames belong to + * @param tid - which TID within the peer the rx frames belong to + * @param msdu_list - NULL-terminated list of MSDUs to perform the rx->tx + * forwarding check on + */ +void +ol_rx_fwd_check( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + + +#endif /* _OL_RX_FWD_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.c new file mode 100644 index 0000000000000..a45f2e3b854cf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_nbuf_t */ + +#include /* htt_rx_pn_t, etc. */ +#include /* ol_rx_err */ + +#include /* ol_rx_mpdu_list_next */ +#include /* ol_txrx_vdev_t, etc. */ +#include /* our own defs */ +#include /* ol_rx_fwd_check */ +#include /* ol_rx_deliver */ + +/* add the MSDUs from this MPDU to the list of good frames */ +#define ADD_MPDU_TO_LIST(head, tail, mpdu, mpdu_tail) do { \ + if (!head) { \ + head = mpdu; \ + } else { \ + adf_nbuf_set_next(tail, mpdu); \ + } \ + tail = mpdu_tail; \ + } while(0); + +int ol_rx_pn_cmp24( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode) +{ + return ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff)); +} + + +int ol_rx_pn_cmp48( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode) +{ + return + ((new_pn->pn48 & 0xffffffffffffULL) <= + (old_pn->pn48 & 0xffffffffffffULL)); +} + +int ol_rx_pn_wapi_cmp( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode) +{ + int pn_is_replay = 0; + + if (new_pn->pn128[1] == old_pn->pn128[1]) { + pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]); + } else { + pn_is_replay = (new_pn->pn128[1] < old_pn->pn128[1]); + } + + if (is_unicast) { + if (opmode == wlan_op_mode_ap) { + pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 0); + } else { + pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 1); + } + } + return pn_is_replay; +} + +adf_nbuf_t +ol_rx_pn_check_base( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + union htt_rx_pn_t *last_pn; + adf_nbuf_t out_list_head = NULL; + adf_nbuf_t out_list_tail = NULL; + adf_nbuf_t mpdu; + int index; /* unicast vs. multicast */ + int pn_len; + void *rx_desc; + int last_pn_valid; + + /* Make sure host pn check is not redundant */ + if (adf_os_atomic_read(&peer->fw_pn_check)) { + return msdu_list; + } + + /* First, check whether the PN check applies */ + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu_list); + adf_os_assert(htt_rx_msdu_has_wlan_mcast_flag(pdev->htt_pdev, rx_desc)); + index = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc) ? + txrx_sec_mcast : txrx_sec_ucast; + pn_len = pdev->rx_pn[peer->security[index].sec_type].len; + if (pn_len == 0) { + return msdu_list; + } + + last_pn_valid = peer->tids_last_pn_valid[tid]; + last_pn = &peer->tids_last_pn[tid]; + mpdu = msdu_list; + while (mpdu) { + adf_nbuf_t mpdu_tail, next_mpdu; + union htt_rx_pn_t new_pn; + int pn_is_replay = 0; + + rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, mpdu); + + /* + * Find the last MSDU within this MPDU, and + * the find the first MSDU within the next MPDU. + */ + ol_rx_mpdu_list_next(pdev, mpdu, &mpdu_tail, &next_mpdu); + + /* Don't check the PN replay for non-encrypted frames */ + if (!vdev->drop_unenc && !htt_rx_mpdu_is_encrypted(pdev->htt_pdev, rx_desc)) { + ADD_MPDU_TO_LIST(out_list_head, out_list_tail, mpdu, mpdu_tail); + mpdu = next_mpdu; + continue; + } + + /* retrieve PN from rx descriptor */ + htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &new_pn, pn_len); + + /* if there was no prior PN, there's nothing to check */ + if (last_pn_valid) { + pn_is_replay = pdev->rx_pn[peer->security[index].sec_type].cmp( + &new_pn, last_pn, index == txrx_sec_ucast, vdev->opmode); + } else { + last_pn_valid = peer->tids_last_pn_valid[tid] = 1; + } + + if (pn_is_replay) { + adf_nbuf_t msdu; + static u_int32_t last_pncheck_print_time = 0; + int log_level; + u_int32_t current_time_ms; + + /* + * This MPDU failed the PN check: + * 1. Notify the control SW of the PN failure + * (so countermeasures can be taken, if necessary) + * 2. Discard all the MSDUs from this MPDU. + */ + msdu = mpdu; + current_time_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS < + (current_time_ms - last_pncheck_print_time)) { + last_pncheck_print_time = current_time_ms; + log_level = TXRX_PRINT_LEVEL_WARN; + } + else { + log_level = TXRX_PRINT_LEVEL_INFO2; + } + + TXRX_PRINT(log_level, + "PN check failed - TID %d, peer %p " + "(%02x:%02x:%02x:%02x:%02x:%02x) %s\n" + " old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" + " new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" + " new seq num = %d\n", + tid, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5], + (index == txrx_sec_ucast) ? "ucast" : "mcast", + last_pn->pn128[1], + last_pn->pn128[0], + last_pn->pn128[0] & 0xffffffffffffULL, + new_pn.pn128[1], + new_pn.pn128[0], + new_pn.pn128[0] & 0xffffffffffffULL, + htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_desc)); +#if defined(ENABLE_RX_PN_TRACE) + ol_rx_pn_trace_display(pdev, 1); +#endif /* ENABLE_RX_PN_TRACE */ + ol_rx_err( + pdev->ctrl_pdev, + vdev->vdev_id, peer->mac_addr.raw, tid, + htt_rx_mpdu_desc_tsf32(pdev->htt_pdev, rx_desc), + OL_RX_ERR_PN, mpdu, NULL, 0); + /* free all MSDUs within this MPDU */ + do { + adf_nbuf_t next_msdu; + OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, OL_RX_ERR_PN); + next_msdu = adf_nbuf_next(msdu); + htt_rx_desc_frame_free(pdev->htt_pdev, msdu); + if (msdu == mpdu_tail) { + break; + } else { + msdu = next_msdu; + } + } while (1); + } else { + ADD_MPDU_TO_LIST(out_list_head, out_list_tail, mpdu, mpdu_tail); + /* + * Remember the new PN. + * For simplicity, just do 2 64-bit word copies to cover the worst + * case (WAPI), regardless of the length of the PN. + * This is more efficient than doing a conditional branch to copy + * only the relevant portion. + */ + last_pn->pn128[0] = new_pn.pn128[0]; + last_pn->pn128[1] = new_pn.pn128[1]; + OL_RX_PN_TRACE_ADD(pdev, peer, tid, rx_desc); + } + + mpdu = next_mpdu; + } + /* make sure the list is null-terminated */ + if (out_list_tail) { + adf_nbuf_set_next(out_list_tail, NULL); + } + return out_list_head; +} + +void +ol_rx_pn_check( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); + ol_rx_fwd_check(vdev, peer, tid, msdu_list); +} + +void +ol_rx_pn_check_only( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list) +{ + msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list); + ol_rx_deliver(vdev, peer, tid, msdu_list); +} + +#if defined(ENABLE_RX_PN_TRACE) + +A_STATUS +ol_rx_pn_trace_attach(ol_txrx_pdev_handle pdev) +{ + int num_elems; + + num_elems = 1 << TXRX_RX_PN_TRACE_SIZE_LOG2; + pdev->rx_pn_trace.idx = 0; + pdev->rx_pn_trace.cnt = 0; + pdev->rx_pn_trace.mask = num_elems - 1; + pdev->rx_pn_trace.data = adf_os_mem_alloc( + pdev->osdev, sizeof(*pdev->rx_pn_trace.data) * num_elems); + if (! pdev->rx_pn_trace.data) { + return A_ERROR; + } + return A_OK; +} + +void +ol_rx_pn_trace_detach(ol_txrx_pdev_handle pdev) +{ + adf_os_mem_free(pdev->rx_pn_trace.data); +} + +void +ol_rx_pn_trace_add( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + u_int16_t tid, + void *rx_desc) +{ + u_int32_t idx = pdev->rx_pn_trace.idx; + union htt_rx_pn_t pn; + u_int32_t pn32; + u_int16_t seq_num; + u_int8_t unicast; + + htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &pn, 48); + pn32 = pn.pn48 & 0xffffffff; + seq_num = htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_desc); + unicast = ! htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc); + + pdev->rx_pn_trace.data[idx].peer = peer; + pdev->rx_pn_trace.data[idx].tid = tid; + pdev->rx_pn_trace.data[idx].seq_num = seq_num; + pdev->rx_pn_trace.data[idx].unicast = unicast; + pdev->rx_pn_trace.data[idx].pn32 = pn32; + pdev->rx_pn_trace.cnt++; + idx++; + pdev->rx_pn_trace.idx = idx & pdev->rx_pn_trace.mask; +} + +void +ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once) +{ + static int print_count = 0; + u_int32_t i, start, end; + u_int64_t cnt; + int elems; + int limit = 0; /* move this to the arg list? */ + + if (print_count != 0 && just_once) { + return; + } + print_count++; + + end = pdev->rx_pn_trace.idx; + if (pdev->rx_pn_trace.cnt <= pdev->rx_pn_trace.mask) { + /* trace log has not yet wrapped around - start at the top */ + start = 0; + cnt = 0; + } else { + start = end; + cnt = pdev->rx_pn_trace.cnt - (pdev->rx_pn_trace.mask + 1); + } + elems = (end - 1 - start) & pdev->rx_pn_trace.mask; + if (limit > 0 && elems > limit) { + int delta; + delta = elems - limit; + start += delta; + start &= pdev->rx_pn_trace.mask; + cnt += delta; + } + + i = start; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " seq PN\n"); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " count idx peer tid uni num LSBs\n"); + do { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " %6lld %4d %p %2d %d %4d %8d\n", + cnt, i, + pdev->rx_pn_trace.data[i].peer, + pdev->rx_pn_trace.data[i].tid, + pdev->rx_pn_trace.data[i].unicast, + pdev->rx_pn_trace.data[i].seq_num, + pdev->rx_pn_trace.data[i].pn32); + cnt++; + i++; + i &= pdev->rx_pn_trace.mask; + } while (i != end); +} +#endif /* ENABLE_RX_PN_TRACE */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.h new file mode 100644 index 0000000000000..24ba9d09c422c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_pn.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX_PN_H_ +#define _OL_RX_PN_H_ + +#include /* adf_nbuf_t, etc. */ + +#include /* ol_txrx_peer_t, etc. */ + +int ol_rx_pn_cmp24( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode); + +int ol_rx_pn_cmp48( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode); + +int ol_rx_pn_wapi_cmp( + union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn, + int is_unicast, + int opmode); + +/** + * @brief If applicable, check the Packet Number to detect replays. + * @details + * Determine whether a PN check is needed, and if so, what the PN size is. + * (A PN size of 0 is used to indirectly bypass the PN check for security + * methods that don't involve a PN check.) + * This function produces event notifications for any PN failures, via the + * ol_rx_err function. + * After the PN check, call the next stage of rx processing (rx --> tx + * forwarding check). + * + * @param vdev - which virtual device the frames were addressed to + * @param peer - which peer the rx frames belong to + * @param tid - which TID within the peer the rx frames belong to + * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on + * (if PN check is applicable, i.e. PN length > 0) + */ +void +ol_rx_pn_check( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + +/** + * @brief If applicable, check the Packet Number to detect replays. + * @details + * Determine whether a PN check is needed, and if so, what the PN size is. + * (A PN size of 0 is used to indirectly bypass the PN check for security + * methods that don't involve a PN check.) + * This function produces event notifications for any PN failures, via the + * ol_rx_err function. + * After the PN check, deliver the valid rx frames to the OS shim. + * (Don't perform a rx --> tx forwarding check.) + * + * @param vdev - which virtual device the frames were addressed to + * @param peer - which peer the rx frames belong to + * @param tid - which TID within the peer the rx frames belong to + * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on + * (if PN check is applicable, i.e. PN length > 0) + */ +void +ol_rx_pn_check_only( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + +/** + * @brief If applicable, check the Packet Number to detect replays. + * @details + * Same as ol_rx_pn_check but return valid rx netbufs + * rather than invoking the rx --> tx forwarding check. + * + * @param vdev - which virtual device the frames were addressed to + * @param peer - which peer the rx frames belong to + * @param tid - which TID within the peer the rx frames belong to + * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on + * (if PN check is applicable, i.e. PN length > 0) + * @return list of netbufs that didn't fail the PN check + */ +adf_nbuf_t +ol_rx_pn_check_base( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + + +#endif /* _OL_RX_PN_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c new file mode 100644 index 0000000000000..f5da6d44d47e1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=== header file includes ===*/ +/* generic utilities */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_mem_alloc */ + +#include /* IEEE80211_SEQ_MAX */ + +/* external interfaces */ +#include /* ol_txrx_pdev_handle */ +#include /* ol_rx_addba_handler, etc. */ +#include /* ol_ctrl_rx_addba_complete */ +#include /* htt_rx_desc_frame_free */ +#include /* ol_rx_err */ + +/* datapath internal interfaces */ +#include /* ol_txrx_peer_find_by_id */ +#include /* TXRX_ASSERT */ +#include /* OL_RX_REORDER_TIMEOUT_REMOVE, etc. */ +#include +#include + + +/*=== data types and defines ===*/ +#define OL_RX_REORDER_ROUND_PWR2(value) g_log2ceil[value] + +/*=== global variables ===*/ + +static char g_log2ceil[] = { + 1, // 0 -> 1 + 1, // 1 -> 1 + 2, // 2 -> 2 + 4, 4, // 3-4 -> 4 + 8, 8, 8, 8, // 5-8 -> 8 + 16, 16, 16, 16, 16, 16, 16, 16, // 9-16 -> 16 + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, // 17-32 -> 32 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 33-64 -> 64 +}; + + +/*=== function definitions ===*/ + +/*---*/ + +#define QCA_SUPPORT_RX_REORDER_RELEASE_CHECK 0 +#define OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, idx_start) /* no-op */ +#define OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask) idx &= win_sz_mask; +#define OL_RX_REORDER_IDX_MAX(win_sz, win_sz_mask) win_sz_mask +#define OL_RX_REORDER_IDX_INIT(seq_num, win_sz, win_sz_mask) 0 /* n/a */ +#define OL_RX_REORDER_NO_HOLES(rx_reorder) 0 +#define OL_RX_REORDER_MPDU_CNT_INCR(rx_reorder, incr) /* n/a */ +#define OL_RX_REORDER_MPDU_CNT_DECR(rx_reorder, decr) /* n/a */ + + +/*---*/ + +/* reorder array elements are known to be non-NULL */ +#define OL_RX_REORDER_PTR_CHECK(ptr) /* no-op */ +#define OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu, rx_reorder_array_elem) \ + do { \ + if (tail_msdu) { \ + adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head); \ + } \ + } while (0) + + +/* functions called by txrx components */ + +void ol_rx_reorder_init(struct ol_rx_reorder_t *rx_reorder, u_int8_t tid) +{ + rx_reorder->win_sz = 1; + rx_reorder->win_sz_mask = 0; + rx_reorder->array = &rx_reorder->base; + rx_reorder->base.head = rx_reorder->base.tail = NULL; + rx_reorder->tid = tid; + rx_reorder->defrag_timeout_ms = 0; + + rx_reorder->defrag_waitlist_elem.tqe_next = NULL; + rx_reorder->defrag_waitlist_elem.tqe_prev = NULL; +} + + +enum htt_rx_status +ol_rx_reorder_seq_num_check( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned seq_num) +{ + unsigned seq_num_delta; + + /* don't check the new seq_num against last_seq if last_seq is not valid */ + if (peer->tids_last_seq[tid] == IEEE80211_SEQ_MAX) { + return htt_rx_status_ok; + } + /* + * For duplicate detection, it might be helpful to also check + * whether the retry bit is set or not - a strict duplicate packet + * should be the one with retry bit set. + * However, since many implementations do not set the retry bit, + * and since this same function is also used for filtering out + * late-arriving frames (frames that arive after their rx reorder + * timeout has expired) which are not retries, don't bother checking + * the retry bit for now. + */ + /* note: if new seq_num == old seq_num, seq_num_delta = 4095 */ + seq_num_delta = (seq_num - 1 - peer->tids_last_seq[tid]) & + (IEEE80211_SEQ_MAX-1); /* account for wraparound */ + + if (seq_num_delta > (IEEE80211_SEQ_MAX >> 1)) { + return htt_rx_status_err_replay; /* or maybe htt_rx_status_err_dup */ + } + return htt_rx_status_ok; +} + +void +ol_rx_reorder_store( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned idx, + adf_nbuf_t head_msdu, + adf_nbuf_t tail_msdu) +{ + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + + idx &= peer->tids_rx_reorder[tid].win_sz_mask; + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx]; + if (rx_reorder_array_elem->head) { + adf_nbuf_set_next(rx_reorder_array_elem->tail, head_msdu); + } else { + rx_reorder_array_elem->head = head_msdu; + OL_RX_REORDER_MPDU_CNT_INCR(&peer->tids_rx_reorder[tid], 1); + } + rx_reorder_array_elem->tail = tail_msdu; +} + +void +ol_rx_reorder_release( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned idx_start, + unsigned idx_end) +{ + unsigned idx; + unsigned win_sz, win_sz_mask; + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + adf_nbuf_t head_msdu; + adf_nbuf_t tail_msdu; + + OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start); + peer->tids_next_rel_idx[tid] = (u_int16_t)idx_end; /* may get reset below */ + + win_sz = peer->tids_rx_reorder[tid].win_sz; + win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask; + idx_start &= win_sz_mask; + idx_end &= win_sz_mask; + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx_start]; + + head_msdu = rx_reorder_array_elem->head; + tail_msdu = rx_reorder_array_elem->tail; + rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL; + OL_RX_REORDER_PTR_CHECK(head_msdu) { + OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1); + } + + idx = (idx_start + 1); + OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask); + while (idx != idx_end) { + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx]; + OL_RX_REORDER_PTR_CHECK(rx_reorder_array_elem->head) { + OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1); + OL_RX_REORDER_LIST_APPEND( + head_msdu, tail_msdu, rx_reorder_array_elem); + tail_msdu = rx_reorder_array_elem->tail; + } + rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL; + idx++; + OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask); + } + OL_RX_REORDER_PTR_CHECK(head_msdu) { + u_int16_t seq_num; + htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev; + + /* + * This logic is not quite correct - the last_seq value should be + * the sequence number of the final MPDU released rather than the + * initial MPDU released. + * However, tracking the sequence number of the first MPDU in the + * released batch works well enough: + * For Peregrine and Rome, the last_seq is checked only for + * non-aggregate cases, where only one MPDU at a time is released. + * For Riva, Pronto, and Northstar, the last_seq is checked to + * filter out late-arriving rx frames, whose sequence number will + * be less than the first MPDU in this release batch. + */ + seq_num = htt_rx_mpdu_desc_seq_num( + htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu)); + peer->tids_last_seq[tid] = seq_num; + /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ + adf_nbuf_set_next(tail_msdu, NULL); + peer->rx_opt_proc(vdev, peer, tid, head_msdu); + } + /* + * If the rx reorder timeout is handled by host SW rather than the + * target's rx reorder logic, then stop the timer here. + * (If there are remaining rx holes, then the timer will be restarted.) + */ + OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid); +} + +void +ol_rx_reorder_flush( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned idx_start, + unsigned idx_end, + enum htt_rx_flush_action action) +{ + struct ol_txrx_pdev_t *pdev; + unsigned win_sz; + u_int8_t win_sz_mask; + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + adf_nbuf_t head_msdu = NULL; + adf_nbuf_t tail_msdu = NULL; + + pdev = vdev->pdev; + win_sz = peer->tids_rx_reorder[tid].win_sz; + win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask; + + OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start); + /* a idx_end value of 0xffff means to flush the entire array */ + if (idx_end == 0xffff) { + idx_end = idx_start; + /* + * The array is being flushed in entirety because the block + * ack window has been shifted to a new position that does not + * overlap with the old position. (Or due to reception of a + * DELBA.) + * Thus, since the block ack window is essentially being reset, + * reset the "next release index". + */ + peer->tids_next_rel_idx[tid] = OL_RX_REORDER_IDX_INIT( + 0/*n/a*/, win_sz, win_sz_mask); + } else { + peer->tids_next_rel_idx[tid] = (u_int16_t)idx_end; + } + + idx_start &= win_sz_mask; + idx_end &= win_sz_mask; + + do { + rx_reorder_array_elem = + &peer->tids_rx_reorder[tid].array[idx_start]; + idx_start = (idx_start + 1); + OL_RX_REORDER_IDX_WRAP(idx_start, win_sz, win_sz_mask); + + if (rx_reorder_array_elem->head) { + OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1); + if (head_msdu == NULL) { + head_msdu = rx_reorder_array_elem->head; + tail_msdu = rx_reorder_array_elem->tail; + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + continue; + } + adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head); + tail_msdu = rx_reorder_array_elem->tail; + rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL; + } + } while (idx_start != idx_end); + + ol_rx_defrag_waitlist_remove(peer, tid); + + if (head_msdu) { + u_int16_t seq_num; + htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev; + + seq_num = htt_rx_mpdu_desc_seq_num( + htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu)); + peer->tids_last_seq[tid] = seq_num; + /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ + adf_nbuf_set_next(tail_msdu, NULL); + if (action == htt_rx_flush_release) { + peer->rx_opt_proc(vdev, peer, tid, head_msdu); + } else { + do { + adf_nbuf_t next; + next = adf_nbuf_next(head_msdu); + htt_rx_desc_frame_free(pdev->htt_pdev, head_msdu); + head_msdu = next; + } while (head_msdu); + } + } + /* + * If the rx reorder array is empty, then reset the last_seq value - + * it is likely that a BAR or a sequence number shift caused the + * sequence number to jump, so the old last_seq value is not relevant. + */ + if (OL_RX_REORDER_NO_HOLES(&peer->tids_rx_reorder[tid])) { + peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; /* invalid */ + } + + OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid); +} + +void +ol_rx_reorder_first_hole( + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned *idx_end) +{ + unsigned win_sz, win_sz_mask; + unsigned idx_start = 0, tmp_idx = 0; + + win_sz = peer->tids_rx_reorder[tid].win_sz; + win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask; + + OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start); + tmp_idx++; + OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask); + /* bypass the initial hole */ + while (tmp_idx != idx_start && + !peer->tids_rx_reorder[tid].array[tmp_idx].head) + { + tmp_idx++; + OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask); + } + /* bypass the present frames following the initial hole */ + while (tmp_idx != idx_start && + peer->tids_rx_reorder[tid].array[tmp_idx].head) + { + tmp_idx++; + OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask); + } + /* + * idx_end is exclusive rather than inclusive. + * In other words, it is the index of the first slot of the second + * hole, rather than the index of the final present frame following + * the first hole. + */ + *idx_end = tmp_idx; +} + +void +ol_rx_reorder_peer_cleanup( + struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer) +{ + int tid; + for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) { + ol_rx_reorder_flush(vdev, peer, tid, 0, 0, htt_rx_flush_discard); + } + OL_RX_REORDER_TIMEOUT_PEER_CLEANUP(peer); +} + + +/* functions called by HTT */ + +void +ol_rx_addba_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + u_int8_t win_sz, + u_int16_t start_seq_num, + u_int8_t failed) +{ + u_int8_t round_pwr2_win_sz; + unsigned array_size; + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_t *rx_reorder; + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer == NULL) { + return; + } + + if (pdev->cfg.host_addba) { + ol_ctrl_rx_addba_complete( + pdev->ctrl_pdev, &peer->mac_addr.raw[0], tid, failed); + } + if (failed) { + return; + } + + peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; /* invalid */ + rx_reorder = &peer->tids_rx_reorder[tid]; + + TXRX_ASSERT2(win_sz <= 64); + rx_reorder->win_sz = win_sz; + round_pwr2_win_sz = OL_RX_REORDER_ROUND_PWR2(win_sz); + array_size = round_pwr2_win_sz * sizeof(struct ol_rx_reorder_array_elem_t); + rx_reorder->array = adf_os_mem_alloc(pdev->osdev, array_size); + TXRX_ASSERT1(rx_reorder->array); + adf_os_mem_set(rx_reorder->array, 0x0, array_size); + + rx_reorder->win_sz_mask = round_pwr2_win_sz - 1; + rx_reorder->num_mpdus = 0; + + peer->tids_next_rel_idx[tid] = OL_RX_REORDER_IDX_INIT( + start_seq_num, rx_reorder->win_sz, rx_reorder->win_sz_mask); +} + +void +ol_rx_delba_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid) +{ + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_t *rx_reorder; + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer == NULL) { + return; + } + peer->tids_next_rel_idx[tid] = 0xffff; /* invalid value */ + rx_reorder = &peer->tids_rx_reorder[tid]; + + /* check that there really was a block ack agreement */ + TXRX_ASSERT1(rx_reorder->win_sz_mask != 0); + /* + * Deallocate the old rx reorder array. + * The call to ol_rx_reorder_init below + * will reset rx_reorder->array to point to + * the single-element statically-allocated reorder array + * used for non block-ack cases. + */ + if (rx_reorder->array != &rx_reorder->base) { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "%s, delete reorder array, tid:%d\n", + __func__, tid); + adf_os_mem_free(rx_reorder->array); + } + + /* set up the TID with default parameters (ARQ window size = 1) */ + ol_rx_reorder_init(rx_reorder, tid); +} + +void +ol_rx_flush_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + u_int16_t idx_start, + u_int16_t idx_end, + enum htt_rx_flush_action action) +{ + struct ol_txrx_vdev_t *vdev = NULL; + void *rx_desc; + struct ol_txrx_peer_t *peer; + int idx; + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer) { + vdev = peer->vdev; + } else { + return; + } + + OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev); + + idx = idx_start & peer->tids_rx_reorder[tid].win_sz_mask; + rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx]; + if (rx_reorder_array_elem->head) { + rx_desc = + htt_rx_msdu_desc_retrieve(htt_pdev, rx_reorder_array_elem->head); + if (htt_rx_msdu_is_frag(htt_pdev, rx_desc)) { + ol_rx_reorder_flush_frag(htt_pdev, peer, tid, idx_start); + /* + * Assuming flush message sent seperately for frags + * and for normal frames + */ + OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev); + return; + } + } + ol_rx_reorder_flush( + vdev, peer, tid, idx_start, idx_end, action); + /* + * If the rx reorder timeout is handled by host SW, see if there are + * remaining rx holes that require the timer to be restarted. + */ + OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid); + OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev); +} + +void +ol_rx_pn_ind_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + int seq_num_start, + int seq_num_end, + u_int8_t pn_ie_cnt, + u_int8_t *pn_ie) +{ + struct ol_txrx_vdev_t *vdev = NULL; + void *rx_desc; + struct ol_txrx_peer_t *peer; + struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem; + unsigned win_sz_mask; + adf_nbuf_t head_msdu = NULL; + adf_nbuf_t tail_msdu = NULL; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + int seq_num, i=0; + + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer) { + vdev = peer->vdev; + } else { + return; + } + + adf_os_atomic_set(&peer->fw_pn_check, 1); + /*TODO: Fragmentation case*/ + win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask; + seq_num_start &= win_sz_mask; + seq_num_end &= win_sz_mask; + seq_num = seq_num_start; + + do { + rx_reorder_array_elem = + &peer->tids_rx_reorder[tid].array[seq_num]; + + if (rx_reorder_array_elem->head) { + if (pn_ie_cnt && seq_num == (int)(pn_ie[i])) { + adf_nbuf_t msdu, next_msdu, mpdu_head, mpdu_tail; + static u_int32_t last_pncheck_print_time = 0; + int log_level; + u_int32_t current_time_ms; + union htt_rx_pn_t pn = {0}; + int index, pn_len; + + mpdu_head = msdu = rx_reorder_array_elem->head; + mpdu_tail = rx_reorder_array_elem->tail; + + pn_ie_cnt--; + i++; + rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, msdu); + index = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc) ? + txrx_sec_mcast : txrx_sec_ucast; + pn_len = pdev->rx_pn[peer->security[index].sec_type].len; + htt_rx_mpdu_desc_pn(htt_pdev, rx_desc, &pn, pn_len); + + current_time_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS < + (current_time_ms - last_pncheck_print_time)) { + last_pncheck_print_time = current_time_ms; + log_level = TXRX_PRINT_LEVEL_WARN; + } + else { + log_level = TXRX_PRINT_LEVEL_INFO2; + } + TXRX_PRINT(log_level, + "Tgt PN check failed - TID %d, peer %p " + "(%02x:%02x:%02x:%02x:%02x:%02x)\n" + " PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n" + " new seq num = %d\n", + tid, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5], + pn.pn128[1], + pn.pn128[0], + pn.pn128[0] & 0xffffffffffffULL, + htt_rx_mpdu_desc_seq_num(htt_pdev, rx_desc)); + ol_rx_err( + pdev->ctrl_pdev, + vdev->vdev_id, peer->mac_addr.raw, tid, + htt_rx_mpdu_desc_tsf32(htt_pdev, rx_desc), + OL_RX_ERR_PN, mpdu_head, NULL, 0); + + /* free all MSDUs within this MPDU */ + do { + next_msdu = adf_nbuf_next(msdu); + htt_rx_desc_frame_free(htt_pdev, msdu); + if (msdu == mpdu_tail) { + break; + } else { + msdu = next_msdu; + } + }while(1); + + } else { + if (head_msdu == NULL) { + head_msdu = rx_reorder_array_elem->head; + tail_msdu = rx_reorder_array_elem->tail; + } else { + adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head); + tail_msdu = rx_reorder_array_elem->tail; + } + } + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + } + seq_num = (seq_num + 1) & win_sz_mask; + } while (seq_num != seq_num_end); + + if (head_msdu) { + /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ + adf_nbuf_set_next(tail_msdu, NULL); + peer->rx_opt_proc(vdev, peer, tid, head_msdu); + } +} + +#if defined(ENABLE_RX_REORDER_TRACE) + +A_STATUS +ol_rx_reorder_trace_attach(ol_txrx_pdev_handle pdev) +{ + int num_elems; + + num_elems = 1 << TXRX_RX_REORDER_TRACE_SIZE_LOG2; + pdev->rx_reorder_trace.idx = 0; + pdev->rx_reorder_trace.cnt = 0; + pdev->rx_reorder_trace.mask = num_elems - 1; + pdev->rx_reorder_trace.data = adf_os_mem_alloc( + pdev->osdev, sizeof(*pdev->rx_reorder_trace.data) * num_elems); + if (! pdev->rx_reorder_trace.data) { + return A_ERROR; + } + while (--num_elems >= 0) { + pdev->rx_reorder_trace.data[num_elems].seq_num = 0xffff; + } + + return A_OK; +} + +void +ol_rx_reorder_trace_detach(ol_txrx_pdev_handle pdev) +{ + adf_os_mem_free(pdev->rx_reorder_trace.data); +} + +void +ol_rx_reorder_trace_add( + ol_txrx_pdev_handle pdev, + u_int8_t tid, + u_int16_t reorder_idx, + u_int16_t seq_num, + int num_mpdus) +{ + u_int32_t idx = pdev->rx_reorder_trace.idx; + + pdev->rx_reorder_trace.data[idx].tid = tid; + pdev->rx_reorder_trace.data[idx].reorder_idx = reorder_idx; + pdev->rx_reorder_trace.data[idx].seq_num = seq_num; + pdev->rx_reorder_trace.data[idx].num_mpdus = num_mpdus; + pdev->rx_reorder_trace.cnt++; + idx++; + pdev->rx_reorder_trace.idx = idx & pdev->rx_reorder_trace.mask; +} + +void +ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit) +{ + static int print_count = 0; + u_int32_t i, start, end; + u_int64_t cnt; + int elems; + + if (print_count != 0 && just_once) { + return; + } + print_count++; + + end = pdev->rx_reorder_trace.idx; + if (pdev->rx_reorder_trace.data[end].seq_num == 0xffff) { + /* trace log has not yet wrapped around - start at the top */ + start = 0; + cnt = 0; + } else { + start = end; + cnt = pdev->rx_reorder_trace.cnt - (pdev->rx_reorder_trace.mask + 1); + } + elems = (end - 1 - start) & pdev->rx_reorder_trace.mask; + if (limit > 0 && elems > limit) { + int delta; + delta = elems - limit; + start += delta; + start &= pdev->rx_reorder_trace.mask; + cnt += delta; + } + + i = start; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " log array seq\n"); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " count idx tid idx num (LSBs)\n"); + do { + u_int16_t seq_num, reorder_idx; + seq_num = pdev->rx_reorder_trace.data[i].seq_num; + reorder_idx = pdev->rx_reorder_trace.data[i].reorder_idx; + if (seq_num < (1 << 14)) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " %6lld %4d %3d %4d %4d (%d)\n", + cnt, i, pdev->rx_reorder_trace.data[i].tid, + reorder_idx, seq_num, seq_num & 63); + } else { + int err = TXRX_SEQ_NUM_ERR(seq_num); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " %6lld %4d err %d (%d MPDUs)\n", + cnt, i, err, pdev->rx_reorder_trace.data[i].num_mpdus); + } + cnt++; + i++; + i &= pdev->rx_reorder_trace.mask; + } while (i != end); +} + +#endif /* ENABLE_RX_REORDER_TRACE */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.h new file mode 100644 index 0000000000000..920717b0da858 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX_REORDER__H_ +#define _OL_RX_REORDER__H_ + +#include /* adf_nbuf_t, etc. */ + +#include /* ol_txrx_peer_t, etc. */ + +#include /* ol_rx_reorder_t */ + +void +ol_rx_reorder_store( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned reorder_array_index, + adf_nbuf_t head_msdu, + adf_nbuf_t tail_msdu); + +void +ol_rx_reorder_release( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned seq_num_start, + unsigned seq_num_end); + +void +ol_rx_reorder_flush( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned seq_num_start, + unsigned seq_num_end, + enum htt_rx_flush_action action); + +/** + * @brief - find end of first range of present MPDUs after the initial rx hole + * @param[in] peer - which sender's data is being checked + * @param[in] tid - which type of data is being checked + * @param[out] idx_end - the reorder array index holding the last MPDU in the + * range of in-order MPDUs that following the initial hole. + * Note that this is the index of the last in-order MPDU following the + * first hole, rather than the starting index of the second hole. + */ +void +ol_rx_reorder_first_hole( + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned *idx_end); + +void +ol_rx_reorder_peer_cleanup( + struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer); + +void +ol_rx_reorder_init(struct ol_rx_reorder_t *rx_reorder, u_int8_t tid); + +enum htt_rx_status +ol_rx_reorder_seq_num_check( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + unsigned seq_num); + + +/* + * Peregrine and Rome: do sequence number checking in the host + * for peer-TIDs without aggregation enabled + */ +#define OL_RX_REORDER_SEQ_NUM_CHECK(pdev, peer, tid, rx_mpdu_desc) \ + (pdev->rx.flags.dup_check && peer->tids_rx_reorder[tid].win_sz_mask == 0) ? \ + ol_rx_reorder_seq_num_check( \ + pdev, peer, tid, \ + htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_mpdu_desc)) : \ + htt_rx_status_ok + + + +#endif /* _OL_RX_REORDER__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.c new file mode 100644 index 0000000000000..a1deb5ccb1e29 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=== header file includes ===*/ +/* generic utilities */ +#include /* adf_nbuf_t, etc. */ +#include +#include + +/* datapath internal interfaces */ +#include /* ol_txrx_pdev_t, etc. */ +#include /* TXRX_ASSERT, etc. */ +#include /* ol_rx_reorder_flush, etc. */ + +#ifdef QCA_SUPPORT_OL_RX_REORDER_TIMEOUT + +void +ol_rx_reorder_timeout_remove(struct ol_txrx_peer_t *peer, unsigned tid) +{ + struct ol_txrx_pdev_t *pdev; + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac; + struct ol_rx_reorder_timeout_list_elem_t *list_elem; + int ac; + + pdev = peer->vdev->pdev; + ac = TXRX_TID_TO_WMM_AC(tid); + rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac]; + list_elem = &peer->tids_rx_reorder[tid].timeout; + if (!list_elem->active) { + /* this element has already been removed */ + return; + } + list_elem->active = 0; + TAILQ_REMOVE( + &rx_reorder_timeout_ac->virtual_timer_list, list_elem, + reorder_timeout_list_elem); +} + +static void +ol_rx_reorder_timeout_start( + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac, + u_int32_t time_now_ms) +{ + u_int32_t duration_ms; + struct ol_rx_reorder_timeout_list_elem_t *list_elem; + + list_elem = TAILQ_FIRST(&rx_reorder_timeout_ac->virtual_timer_list); + + duration_ms = list_elem->timestamp_ms - time_now_ms; + adf_os_timer_start(&rx_reorder_timeout_ac->timer, duration_ms); +} + +static inline void +ol_rx_reorder_timeout_add(struct ol_txrx_peer_t *peer, u_int8_t tid) +{ + u_int32_t time_now_ms; + struct ol_txrx_pdev_t *pdev; + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac; + struct ol_rx_reorder_timeout_list_elem_t *list_elem; + int ac; + int start; + + pdev = peer->vdev->pdev; + ac = TXRX_TID_TO_WMM_AC(tid); + rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac]; + list_elem = &peer->tids_rx_reorder[tid].timeout; + + list_elem->active = 1; + list_elem->peer = peer; + list_elem->tid = tid; + + /* set the expiration timestamp */ + time_now_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + list_elem->timestamp_ms = time_now_ms + rx_reorder_timeout_ac->duration_ms; + + /* add to the queue */ + start = TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list); + TAILQ_INSERT_TAIL( + &rx_reorder_timeout_ac->virtual_timer_list, + list_elem, reorder_timeout_list_elem); + if (start) { + ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms); + } +} + +void +ol_rx_reorder_timeout_update(struct ol_txrx_peer_t *peer, u_int8_t tid) +{ + if (!peer) return; + + /* + * If there are no holes, i.e. no queued frames, + * then timeout doesn't apply. + */ + if (peer->tids_rx_reorder[tid].num_mpdus == 0) return; + + /* + * If the virtual timer for this peer-TID is already running, + * then leave it. + */ + if (peer->tids_rx_reorder[tid].timeout.active) return; + + ol_rx_reorder_timeout_add(peer, tid); +} + +static void +ol_rx_reorder_timeout(void *arg) +{ + struct ol_txrx_pdev_t *pdev; + struct ol_rx_reorder_timeout_list_elem_t *list_elem, *tmp; + u_int32_t time_now_ms; + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac; + + rx_reorder_timeout_ac = (struct ol_tx_reorder_cat_timeout_t *) arg; + time_now_ms = adf_os_ticks_to_msecs(adf_os_ticks()); + + pdev = rx_reorder_timeout_ac->pdev; + adf_os_spin_lock(&pdev->rx.mutex); +// TODO: conditionally take mutex lock during regular rx + TAILQ_FOREACH_SAFE( + list_elem, &rx_reorder_timeout_ac->virtual_timer_list, + reorder_timeout_list_elem, tmp) + { + unsigned idx_start, idx_end; + struct ol_txrx_peer_t *peer; + + if (list_elem->timestamp_ms > time_now_ms) { + break; /* time has not expired yet for this element */ + } + + list_elem->active = 0; + /* remove the expired element from the list */ + TAILQ_REMOVE( + &rx_reorder_timeout_ac->virtual_timer_list, list_elem, + reorder_timeout_list_elem); + + peer = list_elem->peer; + + idx_start = 0xffff; /* start from next_rel_idx */ + ol_rx_reorder_first_hole(peer, list_elem->tid, &idx_end); + ol_rx_reorder_flush( + peer->vdev, + peer, + list_elem->tid, + idx_start, + idx_end, + htt_rx_flush_release); + } + /* restart the timer if unexpired elements are left in the list */ + if (!TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list)) { + ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms); + } + adf_os_spin_unlock(&pdev->rx.mutex); +} + +void +ol_rx_reorder_timeout_init(struct ol_txrx_pdev_t *pdev) +{ + int i; + + for (i = 0; i < ARRAY_LEN(pdev->rx.reorder_timeout.access_cats); i++) { + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac; + rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[i]; + /* init the per-AC timers */ + adf_os_timer_init( + pdev->osdev, &rx_reorder_timeout_ac->timer, + ol_rx_reorder_timeout, rx_reorder_timeout_ac, ADF_DEFERRABLE_TIMER); + /* init the virtual timer list */ + TAILQ_INIT(&rx_reorder_timeout_ac->virtual_timer_list); + rx_reorder_timeout_ac->pdev = pdev; + } + pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VO].duration_ms = 40; + pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VI].duration_ms = 100; + pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BE].duration_ms = 100; + pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BK].duration_ms = 100; +} + +void +ol_rx_reorder_timeout_peer_cleanup(struct ol_txrx_peer_t *peer) +{ + int tid; + + for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) { + if (peer->tids_rx_reorder[tid].timeout.active) { + ol_rx_reorder_timeout_remove(peer, tid); + } + } +} + +void +ol_rx_reorder_timeout_cleanup(struct ol_txrx_pdev_t *pdev) +{ + int i; + + for (i = 0; i < ARRAY_LEN(pdev->rx.reorder_timeout.access_cats); i++) { + struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac; + rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[i]; + adf_os_timer_cancel(&rx_reorder_timeout_ac->timer); + adf_os_timer_free(&rx_reorder_timeout_ac->timer); + } +} + +#endif /* QCA_SUPPORT_OL_RX_REORDER_TIMEOUT */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.h new file mode 100644 index 0000000000000..1b9f34735bfb1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_rx_reorder_timeout.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_RX_REORDER_TIMEOUT__H_ +#define _OL_RX_REORDER_TIMEOUT__H_ + +#include /* ol_txrx_pdev_t, etc. */ + +#ifdef QCA_SUPPORT_OL_RX_REORDER_TIMEOUT + +void +ol_rx_reorder_timeout_init(struct ol_txrx_pdev_t *pdev); +void +ol_rx_reorder_timeout_cleanup(struct ol_txrx_pdev_t *pdev); +void +ol_rx_reorder_timeout_remove(struct ol_txrx_peer_t *peer, unsigned tid); +void +ol_rx_reorder_timeout_update(struct ol_txrx_peer_t *peer, u_int8_t tid); +void +ol_rx_reorder_timeout_peer_cleanup(struct ol_txrx_peer_t *peer); + +#define OL_RX_REORDER_TIMEOUT_INIT ol_rx_reorder_timeout_init +#define OL_RX_REORDER_TIMEOUT_PEER_CLEANUP ol_rx_reorder_timeout_peer_cleanup +#define OL_RX_REORDER_TIMEOUT_CLEANUP ol_rx_reorder_timeout_cleanup +#define OL_RX_REORDER_TIMEOUT_REMOVE ol_rx_reorder_timeout_remove +#define OL_RX_REORDER_TIMEOUT_UPDATE ol_rx_reorder_timeout_update +#define OL_RX_REORDER_TIMEOUT_PEER_TID_INIT(peer, tid) \ + (peer)->tids_rx_reorder[(tid)].timeout.active = 0 +#define OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev) \ + adf_os_spin_lock(&(pdev)->rx.mutex) +#define OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev) \ + adf_os_spin_unlock(&(pdev)->rx.mutex) + +#else + +#define OL_RX_REORDER_TIMEOUT_INIT(pdev) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_PEER_CLEANUP(peer) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_CLEANUP(pdev) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_PEER_TID_INIT(peer, tid) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev) /* no-op */ +#define OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev) /* no-op */ + +#endif /* QCA_SUPPORT_OL_RX_REORDER_TIMEOUT */ + +#endif /* _OL_RX_REORDER_TIMEOUT__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.c new file mode 100644 index 0000000000000..7e469e43596fe --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -0,0 +1,911 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* OS abstraction libraries */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_atomic_read, etc. */ +#include /* adf_os_unlikely */ + +/* APIs for other modules */ +#include /* HTT_TX_EXT_TID_MGMT */ +#include /* htt_tx_desc_tid */ +#include /* ol_txrx_vdev_handle */ +#include /* ol_txrx_sync */ + +/* internal header files relevant for all systems */ +#include /* TXRX_ASSERT1 */ +#include /* pdev stats */ +#include /* ol_tx_desc */ +#include /* ol_tx_send */ +#include + +/* internal header files relevant only for HL systems */ +#include /* ol_tx_classify, ol_tx_classify_mgmt */ +#include /* ol_tx_enqueue */ +#include /* ol_tx_sched */ + +/* internal header files relevant only for specific systems (Pronto) */ +#include /* OL_TX_ENCAP, etc */ + +#define ol_tx_prepare_ll(tx_desc, vdev, msdu, msdu_info) \ + do { \ + struct ol_txrx_pdev_t *pdev = vdev->pdev; \ + /* + * The TXRX module doesn't accept tx frames unless the target has + * enough descriptors for them. + * For LL, the TXRX descriptor pool is sized to match the target's + * descriptor pool. Hence, if the descriptor allocation in TXRX + * succeeds, that guarantees that the target has room to accept + * the new tx frame. + */ \ + (msdu_info)->htt.info.frame_type = pdev->htt_pkt_type; \ + tx_desc = ol_tx_desc_ll(pdev, vdev, msdu, msdu_info); \ + if (adf_os_unlikely(! tx_desc)) { \ + TXRX_STATS_MSDU_LIST_INCR( \ + pdev, tx.dropped.host_reject, msdu); \ + return msdu; /* the list of unaccepted MSDUs */ \ + } \ + } while (0) + +adf_nbuf_t +ol_tx_ll(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) +{ + adf_nbuf_t msdu = msdu_list; + struct ol_txrx_msdu_info_t msdu_info; + + msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; + msdu_info.htt.action.tx_comp_req = 0; + /* + * The msdu_list variable could be used instead of the msdu var, + * but just to clarify which operations are done on a single MSDU + * vs. a list of MSDUs, use a distinct variable for single MSDUs + * within the list. + */ + while (msdu) { + adf_nbuf_t next; + struct ol_tx_desc_t *tx_desc; + + msdu_info.htt.info.ext_tid = adf_nbuf_get_tid(msdu); + msdu_info.peer = NULL; + ol_tx_prepare_ll(tx_desc, vdev, msdu, &msdu_info); + + /* + * If debug display is enabled, show the meta-data being + * downloaded to the target via the HTT tx descriptor. + */ + htt_tx_desc_display(tx_desc->htt_tx_desc); + /* + * The netbuf may get linked into a different list inside the + * ol_tx_send function, so store the next pointer before the + * tx_send call. + */ + next = adf_nbuf_next(msdu); + ol_tx_send(vdev->pdev, tx_desc, msdu); + msdu = next; + } + return NULL; /* all MSDUs were accepted */ +} + +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ + +#define OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN 400 +#define OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS 5 + +/** + * ol_tx_vdev_ll_pause_start_timer() - Start ll-q pause timer for specific virtual device + * @vdev: the virtual device + * + * When system comes out of suspend, it is necessary to start the timer + * which will ensure to pull out all the queued packets after expiry. + * This function restarts the ll-pause timer, for the specific vdev device. + * + * + * Return: None + */ +void +ol_tx_vdev_ll_pause_start_timer(struct ol_txrx_vdev_t *vdev) +{ + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + if (vdev->ll_pause.txq.depth) { + adf_os_timer_cancel(&vdev->ll_pause.timer); + adf_os_timer_start(&vdev->ll_pause.timer, + OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS); + } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); +} + +static void +ol_tx_vdev_ll_pause_queue_send_base(struct ol_txrx_vdev_t *vdev) +{ + int max_to_accept; + + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + if (vdev->ll_pause.paused_reason) { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + return; + } + + /* + * Send as much of the backlog as possible, but leave some margin + * of unallocated tx descriptors that can be used for new frames + * being transmitted by other vdevs. + * Ideally there would be a scheduler, which would not only leave + * some margin for new frames for other vdevs, but also would + * fairly apportion the tx descriptors between multiple vdevs that + * have backlogs in their pause queues. + * However, the fairness benefit of having a scheduler for frames + * from multiple vdev's pause queues is not sufficient to outweigh + * the extra complexity. + */ + max_to_accept = + vdev->pdev->tx_desc.num_free - OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN; + while (max_to_accept > 0 && vdev->ll_pause.txq.depth) { + adf_nbuf_t tx_msdu; + max_to_accept--; + vdev->ll_pause.txq.depth--; + tx_msdu = vdev->ll_pause.txq.head; + if (tx_msdu) { + vdev->ll_pause.txq.head = adf_nbuf_next(tx_msdu); + if (NULL == vdev->ll_pause.txq.head) { + vdev->ll_pause.txq.tail = NULL; + } + adf_nbuf_set_next(tx_msdu, NULL); + tx_msdu = ol_tx_ll(vdev, tx_msdu); + /* + * It is unexpected that ol_tx_ll would reject the frame, + * since we checked that there's room for it, though there's + * an infinitesimal possibility that between the time we checked + * the room available and now, a concurrent batch of tx frames + * used up all the room. + * For simplicity, just drop the frame. + */ + if (tx_msdu) { + adf_nbuf_unmap(vdev->pdev->osdev, tx_msdu, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_tx_free(tx_msdu, 1 /* error */); + } + } + } + if (vdev->ll_pause.txq.depth) { + adf_os_timer_cancel(&vdev->ll_pause.timer); + adf_os_timer_start( + &vdev->ll_pause.timer, OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS); + } + + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); +} + +static adf_nbuf_t +ol_tx_vdev_pause_queue_append( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu_list, + u_int8_t start_timer) +{ + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + while (msdu_list && + vdev->ll_pause.txq.depth < vdev->ll_pause.max_q_depth) + { + adf_nbuf_t next = adf_nbuf_next(msdu_list); + + vdev->ll_pause.txq.depth++; + if (!vdev->ll_pause.txq.head) { + vdev->ll_pause.txq.head = msdu_list; + vdev->ll_pause.txq.tail = msdu_list; + } else { + adf_nbuf_set_next(vdev->ll_pause.txq.tail, msdu_list); + } + vdev->ll_pause.txq.tail = msdu_list; + + msdu_list = next; + } + if (vdev->ll_pause.txq.tail) { + adf_nbuf_set_next(vdev->ll_pause.txq.tail, NULL); + } + + adf_os_timer_cancel(&vdev->ll_pause.timer); + if (start_timer) { + adf_os_timer_start( + &vdev->ll_pause.timer, OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS); + } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + + return msdu_list; +} + +/* + * Store up the tx frame in the vdev's tx queue if the vdev is paused. + * If there are too many frames in the tx queue, reject it. + */ +adf_nbuf_t +ol_tx_ll_queue(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) +{ + u_int16_t eth_type; + u_int32_t paused_reason; + + if (msdu_list == NULL) + return NULL; + + paused_reason = vdev->ll_pause.paused_reason; + if (paused_reason) { + if (adf_os_unlikely((paused_reason & + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED) == paused_reason)) { + eth_type = (((struct ethernet_hdr_t *) + adf_nbuf_data(msdu_list))->ethertype[0] << 8) | + (((struct ethernet_hdr_t *) + adf_nbuf_data(msdu_list))->ethertype[1]); + if (ETHERTYPE_IS_EAPOL_WAPI(eth_type)) { + msdu_list = ol_tx_ll(vdev, msdu_list); + return msdu_list; + } + } + if (paused_reason & OL_TXQ_PAUSE_REASON_VDEV_SUSPEND) + msdu_list = ol_tx_vdev_pause_queue_append(vdev, msdu_list, 0); + else + msdu_list = ol_tx_vdev_pause_queue_append(vdev, msdu_list, 1); + } else { + if (vdev->ll_pause.txq.depth > 0 || + vdev->pdev->tx_throttle.current_throttle_level != + THROTTLE_LEVEL_0) { + /* not paused, but there is a backlog of frms from a prior pause or + throttle off phase */ + msdu_list = ol_tx_vdev_pause_queue_append(vdev, msdu_list, 0); + /* if throttle is disabled or phase is "on" send the frame */ + if (vdev->pdev->tx_throttle.current_throttle_level == + THROTTLE_LEVEL_0 || + vdev->pdev->tx_throttle.current_throttle_phase == + THROTTLE_PHASE_ON) { + /* send as many frames as possible from the vdevs backlog */ + ol_tx_vdev_ll_pause_queue_send_base(vdev); + } + } else { + /* not paused, no throttle and no backlog - send the new frames */ + msdu_list = ol_tx_ll(vdev, msdu_list); + } + } + return msdu_list; +} + +/* + * Run through the transmit queues for all the vdevs and send the pending frames + */ +void +ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev) +{ + int max_to_send; /* tracks how many frames have been sent*/ + adf_nbuf_t tx_msdu; + struct ol_txrx_vdev_t *vdev = NULL; + u_int8_t more; + + if (NULL == pdev) { + return; + } + + if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF) { + return; + } + + /* ensure that we send no more than tx_threshold frames at once */ + max_to_send = pdev->tx_throttle.tx_threshold; + + /* round robin through the vdev queues for the given pdev */ + + /* Potential improvement: download several frames from the same vdev at a + time, since it is more likely that those frames could be aggregated + together, remember which vdev was serviced last, so the next call to + this function can resume the round-robin traversing where the current + invocation left off*/ + do { + more = 0; + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + if (vdev->ll_pause.txq.depth) { + if (vdev->ll_pause.paused_reason) { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + continue; + } + + tx_msdu = vdev->ll_pause.txq.head; + if (NULL == tx_msdu) { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + continue; + } + + max_to_send--; + vdev->ll_pause.txq.depth--; + + vdev->ll_pause.txq.head = adf_nbuf_next(tx_msdu); + + if (NULL == vdev->ll_pause.txq.head) { + vdev->ll_pause.txq.tail = NULL; + } + adf_nbuf_set_next(tx_msdu, NULL); + tx_msdu = ol_tx_ll(vdev, tx_msdu); + /* + * It is unexpected that ol_tx_ll would reject the frame, + * since we checked that there's room for it, though there's + * an infinitesimal possibility that between the time we checked + * the room available and now, a concurrent batch of tx frames + * used up all the room. + * For simplicity, just drop the frame. + */ + if (tx_msdu) { + adf_nbuf_unmap(pdev->osdev, tx_msdu, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_tx_free(tx_msdu, 1 /* error */); + } + } + /*check if there are more msdus to transmit*/ + if (vdev->ll_pause.txq.depth) { + more = 1; + } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } + } while(more && max_to_send); + + vdev = NULL; + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + if (vdev->ll_pause.txq.depth) { + adf_os_timer_cancel(&pdev->tx_throttle.tx_timer); + adf_os_timer_start(&pdev->tx_throttle.tx_timer, + OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS); + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + return; + } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } +} +#endif + +void ol_tx_vdev_ll_pause_queue_send(void *context) +{ + struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *) context; + +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ + if (vdev->pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0 && + vdev->pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF) { + return; + } +#endif + + ol_tx_vdev_ll_pause_queue_send_base(vdev); +} + +static inline int +OL_TXRX_TX_IS_RAW(enum ol_tx_spec tx_spec) +{ + return + tx_spec & + (ol_tx_spec_raw | + ol_tx_spec_no_aggr | + ol_tx_spec_no_encrypt); +} + +static inline u_int8_t +OL_TXRX_TX_RAW_SUBTYPE(enum ol_tx_spec tx_spec) +{ + u_int8_t sub_type = 0x1; /* 802.11 MAC header present */ + + if (tx_spec & ol_tx_spec_no_aggr) { + sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_AGGR_S; + } + if (tx_spec & ol_tx_spec_no_encrypt) { + sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S; + } + if (tx_spec & ol_tx_spec_nwifi_no_encrypt) { + sub_type |= 0x1 << HTT_TX_MSDU_DESC_RAW_SUBTYPE_NO_ENCRYPT_S; + } + return sub_type; +} + +adf_nbuf_t +ol_tx_non_std_ll( + ol_txrx_vdev_handle vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list) +{ + adf_nbuf_t msdu = msdu_list; + htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev; + struct ol_txrx_msdu_info_t msdu_info; + + msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; + msdu_info.htt.action.tx_comp_req = 0; + + /* + * The msdu_list variable could be used instead of the msdu var, + * but just to clarify which operations are done on a single MSDU + * vs. a list of MSDUs, use a distinct variable for single MSDUs + * within the list. + */ + while (msdu) { + adf_nbuf_t next; + struct ol_tx_desc_t *tx_desc; + + msdu_info.htt.info.ext_tid = adf_nbuf_get_tid(msdu); + msdu_info.peer = NULL; + + ol_tx_prepare_ll(tx_desc, vdev, msdu, &msdu_info); + + /* + * The netbuf may get linked into a different list inside the + * ol_tx_send function, so store the next pointer before the + * tx_send call. + */ + next = adf_nbuf_next(msdu); + + if (tx_spec != ol_tx_spec_std) { + if (tx_spec & ol_tx_spec_no_free) { + tx_desc->pkt_type = ol_tx_frm_no_free; + } else if (tx_spec & ol_tx_spec_tso) { + tx_desc->pkt_type = ol_tx_frm_tso; + } else if (tx_spec & ol_tx_spec_nwifi_no_encrypt) { + u_int8_t sub_type = OL_TXRX_TX_RAW_SUBTYPE(tx_spec); + htt_tx_desc_type( + htt_pdev, tx_desc->htt_tx_desc, + htt_pkt_type_native_wifi, sub_type); + } else if (OL_TXRX_TX_IS_RAW(tx_spec)) { + /* different types of raw frames */ + u_int8_t sub_type = OL_TXRX_TX_RAW_SUBTYPE(tx_spec); + htt_tx_desc_type( + htt_pdev, tx_desc->htt_tx_desc, + htt_pkt_type_raw, sub_type); + } + } + /* + * If debug display is enabled, show the meta-data being + * downloaded to the target via the HTT tx descriptor. + */ + htt_tx_desc_display(tx_desc->htt_tx_desc); + ol_tx_send(vdev->pdev, tx_desc, msdu); + msdu = next; + } + return NULL; /* all MSDUs were accepted */ +} + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP +#define OL_TX_ENCAP_WRAPPER(pdev, vdev, tx_desc, msdu, tx_msdu_info) \ + do { \ + if (OL_TX_ENCAP(vdev, tx_desc, msdu, &tx_msdu_info) != A_OK) { \ + adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); \ + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1); \ + if (tx_msdu_info.peer) { \ + /* remove the peer reference added above */ \ + ol_txrx_peer_unref_delete(tx_msdu_info.peer); \ + } \ + goto MSDU_LOOP_BOTTOM; \ + } \ + } while (0) +#else +#define OL_TX_ENCAP_WRAPPER(pdev, vdev, tx_desc, msdu, tx_msdu_info) /* no-op */ +#endif + +/* tx filtering is handled within the target FW */ +#define TX_FILTER_CHECK(tx_msdu_info) 0 /* don't filter */ + +static inline adf_nbuf_t +ol_tx_hl_base( + ol_txrx_vdev_handle vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list, + int tx_comp_req) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + adf_nbuf_t msdu = msdu_list; + struct ol_txrx_msdu_info_t tx_msdu_info; + htt_pdev_handle htt_pdev = pdev->htt_pdev; + tx_msdu_info.peer = NULL; + + /* + * The msdu_list variable could be used instead of the msdu var, + * but just to clarify which operations are done on a single MSDU + * vs. a list of MSDUs, use a distinct variable for single MSDUs + * within the list. + */ + while (msdu) { + adf_nbuf_t next; + struct ol_tx_frms_queue_t *txq; + struct ol_tx_desc_t *tx_desc; + + /* + * The netbuf will get stored into a (peer-TID) tx queue list + * inside the ol_tx_classify_store function or else dropped, + * so store the next pointer immediately. + */ + next = adf_nbuf_next(msdu); + +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + if (adf_os_atomic_read(&vdev->tx_desc_count) > + ((ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) >> 1) + - TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED)) { +#ifdef QCA_LL_TX_FLOW_CT + /* Give tx desc to avoid drop because net_if will stop later */ + tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); + + adf_os_spin_lock_bh(&pdev->tx_mutex); + if ( !(adf_os_atomic_read(&vdev->os_q_paused)) ) { + /* pause netif_queue */ + adf_os_atomic_set(&vdev->os_q_paused, 1); + adf_os_spin_unlock_bh(&pdev->tx_mutex); + vdev->osif_flow_control_cb(vdev->osif_dev, + vdev->vdev_id, A_FALSE); + } else { + adf_os_spin_unlock_bh(&pdev->tx_mutex); + } +#else + tx_desc = NULL; +#endif /* QCA_LL_TX_FLOW_CT */ + } else { + tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); + } +#else /* CONFIG_PER_VDEV_TX_DESC_POOL */ + tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); +#endif /* CONFIG_PER_VDEV_TX_DESC_POOL */ + + if (! tx_desc) { + /* + * If we're out of tx descs, there's no need to try to allocate + * tx descs for the remaining MSDUs. + */ + TXRX_STATS_MSDU_LIST_INCR(pdev, tx.dropped.host_reject, msdu); + return msdu; /* the list of unaccepted MSDUs */ + } + +// OL_TXRX_PROT_AN_LOG(pdev->prot_an_tx_sent, msdu); + + if (tx_spec != ol_tx_spec_std) { + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + if (tx_spec & ol_tx_spec_no_free) { + tx_desc->pkt_type = ol_tx_frm_no_free; + } else if (tx_spec & ol_tx_spec_tso) { + #else + if (tx_spec & ol_tx_spec_tso) { + #endif + tx_desc->pkt_type = ol_tx_frm_tso; + } + if (OL_TXRX_TX_IS_RAW(tx_spec)) { + // CHECK THIS: does this need to happen after htt_tx_desc_init? + /* different types of raw frames */ + u_int8_t sub_type = OL_TXRX_TX_RAW_SUBTYPE(tx_spec); + htt_tx_desc_type( + htt_pdev, tx_desc->htt_tx_desc, + htt_pkt_type_raw, sub_type); + } + } + + tx_msdu_info.htt.info.ext_tid = adf_nbuf_get_tid(msdu); + tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; + tx_msdu_info.htt.info.frame_type = htt_frm_type_data; + tx_msdu_info.htt.info.l2_hdr_type = pdev->htt_pkt_type; + tx_msdu_info.htt.action.tx_comp_req = tx_comp_req; + + txq = ol_tx_classify(vdev, tx_desc, msdu, &tx_msdu_info); + + if ((!txq) || TX_FILTER_CHECK(&tx_msdu_info)) { + /* drop this frame, but try sending subsequent frames */ + //TXRX_STATS_MSDU_LIST_INCR(pdev, tx.dropped.no_txq, msdu); + adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1); + if (tx_msdu_info.peer) { + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + } + goto MSDU_LOOP_BOTTOM; + } + + if(tx_msdu_info.peer) { + /*If the state is not associated then drop all the data packets + received for that peer*/ + if(tx_msdu_info.peer->state == ol_txrx_peer_state_disc) { + adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1); + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + msdu = next; + continue; + } + else if (tx_msdu_info.peer->state != ol_txrx_peer_state_auth) { + + if (tx_msdu_info.htt.info.ethertype != ETHERTYPE_PAE && tx_msdu_info.htt.info.ethertype != ETHERTYPE_WAI) { + adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1); + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + msdu = next; + continue; + } + } + } + /* + * Initialize the HTT tx desc l2 header offset field. + * htt_tx_desc_mpdu_header needs to be called to make sure, + * the l2 header size is initialized correctly to handle cases + * where TX ENCAP is disabled or Tx Encap fails to perform Encap + */ + htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, 0); + + /* + * Note: when the driver is built without support for SW tx encap, + * the following macro is a no-op. When the driver is built with + * support for SW tx encap, it performs encap, and if an error is + * encountered, jumps to the MSDU_LOOP_BOTTOM label. + */ + OL_TX_ENCAP_WRAPPER(pdev, vdev, tx_desc, msdu, tx_msdu_info); + + /* initialize the HW tx descriptor */ + htt_tx_desc_init( + pdev->htt_pdev, tx_desc->htt_tx_desc, + tx_desc->htt_tx_desc_paddr, + ol_tx_desc_id(pdev, tx_desc), + msdu, + &tx_msdu_info.htt); + /* + * If debug display is enabled, show the meta-data being + * downloaded to the target via the HTT tx descriptor. + */ + htt_tx_desc_display(tx_desc->htt_tx_desc); + + ol_tx_enqueue(pdev, txq, tx_desc, &tx_msdu_info); + if (tx_msdu_info.peer) { + OL_TX_PEER_STATS_UPDATE(tx_msdu_info.peer, msdu); + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + } +MSDU_LOOP_BOTTOM: + msdu = next; + } + ol_tx_sched(pdev); + + return NULL; /* all MSDUs were accepted */ +} + +adf_nbuf_t +ol_tx_hl(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + return ol_tx_hl_base(vdev, ol_tx_spec_std, msdu_list, tx_comp_req); +} + +adf_nbuf_t +ol_tx_non_std_hl( + ol_txrx_vdev_handle vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + if (!tx_comp_req) { + if ((tx_spec == ol_tx_spec_no_free) && + (pdev->tx_data_callback.func)) { + tx_comp_req = 1; + } + } + return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req); +} + +adf_nbuf_t +ol_tx_non_std( + ol_txrx_vdev_handle vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list) +{ + if (vdev->pdev->cfg.is_high_latency) { + return ol_tx_non_std_hl(vdev, tx_spec, msdu_list); + } else { + return ol_tx_non_std_ll(vdev, tx_spec, msdu_list); + } +} + +void +ol_txrx_data_tx_cb_set( + ol_txrx_vdev_handle vdev, + ol_txrx_data_tx_cb callback, + void *ctxt) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + pdev->tx_data_callback.func = callback; + pdev->tx_data_callback.ctxt = ctxt; +} + +void +ol_txrx_mgmt_tx_cb_set( + ol_txrx_pdev_handle pdev, + u_int8_t type, + ol_txrx_mgmt_tx_cb download_cb, + ol_txrx_mgmt_tx_cb ota_ack_cb, + void *ctxt) +{ + TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES); + pdev->tx_mgmt.callbacks[type].download_cb = download_cb; + pdev->tx_mgmt.callbacks[type].ota_ack_cb = ota_ack_cb; + pdev->tx_mgmt.callbacks[type].ctxt = ctxt; +} + +int +ol_txrx_mgmt_send( + ol_txrx_vdev_handle vdev, + adf_nbuf_t tx_mgmt_frm, + u_int8_t type, + u_int8_t use_6mbps, + u_int16_t chanfreq) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_tx_desc_t *tx_desc; + struct ol_txrx_msdu_info_t tx_msdu_info; + + tx_msdu_info.htt.action.use_6mbps = use_6mbps; + tx_msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_MGMT; + tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; + tx_msdu_info.htt.action.do_tx_complete = + pdev->tx_mgmt.callbacks[type].ota_ack_cb ? 1 : 0; + + /* + * FIX THIS: l2_hdr_type should only specify L2 header type + * The Peregrine/Rome HTT layer provides the FW with a "pkt type" + * that is a combination of L2 header type and 802.11 frame type. + * If the 802.11 frame type is "mgmt", then the HTT pkt type is "mgmt". + * But if the 802.11 frame type is "data", then the HTT pkt type is + * the L2 header type (more or less): 802.3 vs. Native WiFi (basic 802.11). + * (Or the header type can be "raw", which is any version of the 802.11 + * header, and also implies that some of the offloaded tx data processing + * steps may not apply.) + * For efficiency, the Peregrine/Rome HTT uses the msdu_info's l2_hdr_type + * field to program the HTT pkt type. Thus, this txrx SW needs to overload + * the l2_hdr_type to indicate whether the frame is data vs. mgmt, as well + * as 802.3 L2 header vs. 802.11 L2 header. + * To fix this, the msdu_info's l2_hdr_type should be left specifying just + * the L2 header type. For mgmt frames, there should be a separate function + * to patch the HTT pkt type to store a "mgmt" value rather than the + * L2 header type. Then the HTT pkt type can be programmed efficiently + * for data frames, and the msdu_info's l2_hdr_type field won't be + * confusingly overloaded to hold the 802.11 frame type rather than the + * L2 header type. + */ + /* + * FIX THIS: remove duplication of htt_frm_type_mgmt and htt_pkt_type_mgmt + * The htt module expects a "enum htt_pkt_type" value. + * The htt_dxe module expects a "enum htt_frm_type" value. + * This needs to be cleaned up, so both versions of htt use a + * consistent method of specifying the frame type. + */ +#ifdef QCA_SUPPORT_INTEGRATED_SOC + /* tx mgmt frames always come with a 802.11 header */ + tx_msdu_info.htt.info.l2_hdr_type = htt_pkt_type_native_wifi; + tx_msdu_info.htt.info.frame_type = htt_frm_type_mgmt; +#else + tx_msdu_info.htt.info.l2_hdr_type = htt_pkt_type_mgmt; + tx_msdu_info.htt.info.frame_type = htt_pkt_type_mgmt; +#endif + + tx_msdu_info.peer = NULL; + + adf_nbuf_map_single(pdev->osdev, tx_mgmt_frm, ADF_OS_DMA_TO_DEVICE); + if (pdev->cfg.is_high_latency) { + tx_msdu_info.htt.action.tx_comp_req = 1; + tx_desc = ol_tx_desc_hl(pdev, vdev, tx_mgmt_frm, &tx_msdu_info); + } else { + /* For LL tx_comp_req is not used so initialized to 0 */ + tx_msdu_info.htt.action.tx_comp_req = 0; + tx_desc = ol_tx_desc_ll(pdev, vdev, tx_mgmt_frm, &tx_msdu_info); + /* FIX THIS - + * The FW currently has trouble using the host's fragments table + * for management frames. Until this is fixed, rather than + * specifying the fragment table to the FW, specify just the + * address of the initial fragment. + */ + if (tx_desc) { + /* + * Following the call to ol_tx_desc_ll, frag 0 is the HTT + * tx HW descriptor, and the frame payload is in frag 1. + */ + htt_tx_desc_frags_table_set( + pdev->htt_pdev, tx_desc->htt_tx_desc, + adf_nbuf_get_frag_paddr_lo(tx_mgmt_frm, 1), 0); + } + } + if (! tx_desc) { + adf_nbuf_unmap_single(pdev->osdev, tx_mgmt_frm, ADF_OS_DMA_TO_DEVICE); + return 1; /* can't accept the tx mgmt frame */ + } + TXRX_STATS_MSDU_INCR(pdev, tx.mgmt, tx_mgmt_frm); + TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES); + tx_desc->pkt_type = type + OL_TXRX_MGMT_TYPE_BASE; + + if (pdev->cfg.is_high_latency) { + struct ol_tx_frms_queue_t *txq; + /* + * 1. Look up the peer and queue the frame in the peer's mgmt queue. + * 2. Invoke the download scheduler. + */ + txq = ol_tx_classify_mgmt(vdev, tx_desc, tx_mgmt_frm, &tx_msdu_info); + if (!txq) { + //TXRX_STATS_MSDU_LIST_INCR(vdev->pdev, tx.dropped.no_txq, msdu); + adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(vdev->pdev, tx_desc, 1 /* error */); + if (tx_msdu_info.peer) { + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + } + return 1; /* can't accept the tx mgmt frame */ + } + /* Initialize the HTT tx desc l2 header offset field. + * Even though tx encap does not apply to mgmt frames, + * htt_tx_desc_mpdu_header still needs to be called, + * to specifiy that there was no L2 header added by tx encap, + * so the frame's length does not need to be adjusted to account for + * an added L2 header. + */ + htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, 0); + htt_tx_desc_init( + pdev->htt_pdev, tx_desc->htt_tx_desc, + tx_desc->htt_tx_desc_paddr, + ol_tx_desc_id(pdev, tx_desc), + tx_mgmt_frm, + &tx_msdu_info.htt); + htt_tx_desc_display(tx_desc->htt_tx_desc); + htt_tx_desc_set_chanfreq(tx_desc->htt_tx_desc, chanfreq); + + ol_tx_enqueue(vdev->pdev, txq, tx_desc, &tx_msdu_info); + if (tx_msdu_info.peer) { + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(tx_msdu_info.peer); + } + ol_tx_sched(vdev->pdev); + } else { + htt_tx_desc_set_chanfreq(tx_desc->htt_tx_desc, chanfreq); + ol_tx_send_nonstd(pdev, tx_desc, tx_mgmt_frm, htt_pkt_type_mgmt); + } + + return 0; /* accepted the tx mgmt frame */ +} + +void +ol_txrx_sync(ol_txrx_pdev_handle pdev, u_int8_t sync_cnt) +{ + htt_h2t_sync_msg(pdev->htt_pdev, sync_cnt); +} + +adf_nbuf_t ol_tx_reinject( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu, u_int16_t peer_id) +{ + struct ol_tx_desc_t *tx_desc; + struct ol_txrx_msdu_info_t msdu_info; + + msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; + msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_INVALID; + msdu_info.peer = NULL; + msdu_info.htt.action.tx_comp_req = 0; + + ol_tx_prepare_ll(tx_desc, vdev, msdu, &msdu_info); + HTT_TX_DESC_POSTPONED_SET(*((u_int32_t *)(tx_desc->htt_tx_desc)), TRUE); + + htt_tx_desc_set_peer_id(tx_desc->htt_tx_desc, peer_id); + + ol_tx_send(vdev->pdev, tx_desc, msdu); + + return NULL; +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.h new file mode 100644 index 0000000000000..f099b1a58fbcd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx.h + * @brief Internal definitions for the high-level tx module. + */ +#ifndef _OL_TX__H_ +#define _OL_TX__H_ + +#include /* adf_nbuf_t */ +#include +#include /* ol_txrx_vdev_handle */ + +#include /* ol_tx_desc_t, ol_txrx_msdu_info_t */ + +adf_nbuf_t +ol_tx_ll(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list); + +adf_nbuf_t +ol_tx_ll_queue(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list); + +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ +#define OL_TX_LL ol_tx_ll_queue +#else +#define OL_TX_LL ol_tx_ll +#endif + +void ol_tx_vdev_ll_pause_queue_send(void *context); + +adf_nbuf_t +ol_tx_non_std_ll( + ol_txrx_vdev_handle data_vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list); + +adf_nbuf_t +ol_tx_hl(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list); + +adf_nbuf_t +ol_tx_non_std_hl( + ol_txrx_vdev_handle data_vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list); + +adf_nbuf_t +ol_tx_reinject(struct ol_txrx_vdev_t *vdev, adf_nbuf_t msdu, u_int16_t peer_id); + +void +ol_txrx_mgmt_tx_complete(void *ctxt, adf_nbuf_t netbuf, int err); + +/** + * ol_tx_vdev_ll_pause_start_timer() - Start ll-q pause timer for specific virtual device + * @vdev: the virtual device + * + * When system comes out of suspend, it is necessary to start the timer + * which will ensure to pull out all the queued packets after expiry. + * This function restarts the ll-pause timer, for the specific vdev device. + * + * + * Return: None + */ +void +ol_tx_vdev_ll_pause_start_timer(struct ol_txrx_vdev_t *vdev); + +void +ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev); +#endif /* _OL_TX__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.c new file mode 100644 index 0000000000000..960d24de34c36 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.c @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_nbuf_t, etc. */ +#include /* HTT_TX_EXT_TID_MGMT */ +#include /* htt_tx_desc_tid */ +#include /* ol_txrx_vdev_handle */ +#include /* ol_txrx_sync */ +#include +#include /* TXRX_ASSERT1 */ +#include /* pdev stats */ +#include /* ol_tx_desc */ +#include /* ol_tx_send */ +#include +#include +#include +#include +#include +#include +#include /* ETHERTYPE_VLAN, etc. */ +#include /* ieee80211_frame */ + +/* + * In theory, this tx classify code could be used on the host or in the target. + * Thus, this code uses generic OS primitives, that can be aliased to either + * the host's OS primitives or the target's OS primitives. + * For now, the following #defines set up these host-specific or + * target-specific aliases. + */ + +#if defined(CONFIG_HL_SUPPORT) + +#define OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq) +#define OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq) + +#ifdef QCA_TX_HTT2_SUPPORT +static void +ol_tx_classify_htt2_frm( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t tx_nbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + struct htt_msdu_info_t *htt = &tx_msdu_info->htt; + A_UINT8 candi_frm = 0; + + /* + * Offload the frame re-order to L3 protocol and ONLY support + * TCP protocol now. + */ + if ((htt->info.l2_hdr_type == htt_pkt_type_ethernet) && + (htt->info.frame_type == htt_frm_type_data) && + htt->info.is_unicast && + (htt->info.ethertype == ETHERTYPE_IPV4)) + { + struct ipv4_hdr_t *ipHdr; + + ipHdr = (struct ipv4_hdr_t *)(adf_nbuf_data(tx_nbuf) + + htt->info.l3_hdr_offset); + if (ipHdr->protocol == IP_PROTOCOL_TCP) { + candi_frm = 1; + } + } + + adf_nbuf_set_tx_parallel_dnload_frm(tx_nbuf, candi_frm); +} + +#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info) \ + ol_tx_classify_htt2_frm(vdev, netbuf, msdu_info); +#else +#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info) /* no-op */ +#endif /* QCA_TX_HTT2_SUPPORT */ + +/* EAPOL go with voice priority: WMM_AC_TO_TID1(WMM_AC_VO);*/ +#define TX_EAPOL_TID 6 + +/* ARP go with voice priority: WMM_AC_TO_TID1(pdev->arp_ac_override)*/ +#define TX_ARP_TID 6 + +/* For non-IP case, use default TID */ +#define TX_DEFAULT_TID 0 + +/* + * Determine IP TOS priority + * IP Tos format : + * (Refer Pg 57 WMM-test-plan-v1.2) + * IP-TOS - 8bits + * : DSCP(6-bits) ECN(2-bits) + * : DSCP - P2 P1 P0 X X X + * where (P2 P1 P0) form 802.1D + */ +static inline A_UINT8 +ol_tx_tid_by_ipv4( + A_UINT8 *pkt) +{ + A_UINT8 ipPri, tid; + struct ipv4_hdr_t *ipHdr = (struct ipv4_hdr_t *)pkt; + + ipPri = ipHdr->tos >> 5; + tid = ipPri & 0x7; + + return tid; +} + +static inline A_UINT8 +ol_tx_tid_by_ipv6( + A_UINT8 *pkt) +{ + return (IPV6_TRAFFIC_CLASS((struct ipv6_hdr_t *) pkt) >> 5) & 0x7; +} + +static inline void +ol_tx_set_ether_type( + A_UINT8 *datap, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + A_UINT16 typeorlength; + A_UINT8 * ptr; + A_UINT8 *l3_data_ptr; + + if (tx_msdu_info->htt.info.l2_hdr_type == htt_pkt_type_raw) { + /* adjust hdr_ptr to RA */ + struct ieee80211_frame *wh = (struct ieee80211_frame *)datap; + + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) { + struct llc_snap_hdr_t *llc; + /* dot11 encapsulated frame */ + struct ieee80211_qosframe *whqos = (struct ieee80211_qosframe *)datap; + if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + tx_msdu_info->htt.info.l3_hdr_offset = + sizeof(struct ieee80211_qosframe); + } else { + tx_msdu_info->htt.info.l3_hdr_offset = + sizeof(struct ieee80211_frame); + } + llc = (struct llc_snap_hdr_t *) + (datap + tx_msdu_info->htt.info.l3_hdr_offset); + tx_msdu_info->htt.info.ethertype = + (llc->ethertype[0] << 8) | llc->ethertype[1]; + /* + * l3_hdr_offset refers to the end of the 802.3 or 802.11 header, + * which may be a LLC/SNAP header rather than the IP header. + * Thus, don't increment l3_hdr_offset += sizeof(*llc); rather, + * leave it as is. + */ + } else { + /* + * This function should only be applied to data frames. + * For management frames, we already know to use HTT_TX_EXT_TID_MGMT. + */ + TXRX_ASSERT2(0); + } + } else if (tx_msdu_info->htt.info.l2_hdr_type == htt_pkt_type_ethernet) { + ptr = (datap + ETHERNET_ADDR_LEN * 2); + typeorlength = (ptr[0] << 8) | ptr[1]; + l3_data_ptr = datap + sizeof(struct ethernet_hdr_t);//ETHERNET_HDR_LEN; + + if (typeorlength == ETHERTYPE_VLAN) { + ptr = (datap + ETHERNET_ADDR_LEN * 2 + ETHERTYPE_VLAN_LEN); + typeorlength = (ptr[0] << 8) | ptr[1]; + l3_data_ptr += ETHERTYPE_VLAN_LEN; + } + + if (!IS_ETHERTYPE(typeorlength)) { // 802.3 header + struct llc_snap_hdr_t *llc_hdr = (struct llc_snap_hdr_t *) l3_data_ptr; + typeorlength = (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1]; + l3_data_ptr += sizeof(struct llc_snap_hdr_t); + } + + tx_msdu_info->htt.info.l3_hdr_offset = (A_UINT8)(l3_data_ptr - datap); + tx_msdu_info->htt.info.ethertype = typeorlength; + } +} + +static inline A_UINT8 +ol_tx_tid_by_ether_type( + A_UINT8 *datap, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + A_UINT8 tid; + A_UINT8 *l3_data_ptr; + A_UINT16 typeorlength; + + l3_data_ptr = datap + tx_msdu_info->htt.info.l3_hdr_offset; + typeorlength = tx_msdu_info->htt.info.ethertype; + + /* IP packet, do packet inspection for TID */ + if (typeorlength == ETHERTYPE_IPV4) { + tid = ol_tx_tid_by_ipv4(l3_data_ptr); + } else if (typeorlength == ETHERTYPE_IPV6) { + tid = ol_tx_tid_by_ipv6(l3_data_ptr); + } else if (ETHERTYPE_IS_EAPOL_WAPI(typeorlength)) { + /* EAPOL go with voice priority*/ + tid = TX_EAPOL_TID; + } else if (typeorlength == ETHERTYPE_ARP) { + tid = TX_ARP_TID; + } else { + /* For non-IP case, use default TID */ + tid = TX_DEFAULT_TID; + } + return tid; +} + +static inline A_UINT8 +ol_tx_tid_by_raw_type( + A_UINT8 *datap, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + A_UINT8 tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST; + + /* adjust hdr_ptr to RA */ + struct ieee80211_frame *wh = (struct ieee80211_frame *)datap; + + /* FIXME: This code does not handle 4 address formats. The QOS field + * is not at usual location. + */ + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) { + /* dot11 encapsulated frame */ + struct ieee80211_qosframe *whqos = (struct ieee80211_qosframe *)datap; + if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + tid = whqos->i_qos[0] & IEEE80211_QOS_TID; + } else { + tid = HTT_NON_QOS_TID; + } + } else { + /* + * This function should only be applied to data frames. + * For management frames, we already know to use HTT_TX_EXT_TID_MGMT. + */ + adf_os_assert(0); + } + return tid; +} + +static A_UINT8 +ol_tx_tid( + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t tx_nbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + A_UINT8 *datap = adf_nbuf_data(tx_nbuf); + A_UINT8 tid; + + if (pdev->frame_format == wlan_frm_fmt_raw) { + tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_raw; + + ol_tx_set_ether_type(datap, tx_msdu_info); + tid = tx_msdu_info->htt.info.ext_tid == ADF_NBUF_TX_EXT_TID_INVALID ? + ol_tx_tid_by_raw_type(datap, tx_msdu_info) : + tx_msdu_info->htt.info.ext_tid; + } else if (pdev->frame_format == wlan_frm_fmt_802_3) { + tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_ethernet; + + ol_tx_set_ether_type(datap, tx_msdu_info); + tid = tx_msdu_info->htt.info.ext_tid == ADF_NBUF_TX_EXT_TID_INVALID ? + ol_tx_tid_by_ether_type(datap, tx_msdu_info) : + tx_msdu_info->htt.info.ext_tid; + } else if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + struct llc_snap_hdr_t *llc; + + tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_native_wifi; + tx_msdu_info->htt.info.l3_hdr_offset = sizeof(struct ieee80211_frame); + llc = (struct llc_snap_hdr_t *) + (datap + tx_msdu_info->htt.info.l3_hdr_offset); + tx_msdu_info->htt.info.ethertype = + (llc->ethertype[0] << 8) | llc->ethertype[1]; + /* + * Native WiFi is a special case of "raw" 802.11 header format. + * However, we expect that for all cases that use native WiFi, + * the TID will be directly specified out of band. + */ + tid = tx_msdu_info->htt.info.ext_tid; + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "Invalid standard frame type: %d\n", pdev->frame_format); + adf_os_assert(0); + tid = HTT_TX_EXT_TID_INVALID; + } + return tid; +} + +struct ol_tx_frms_queue_t * +ol_tx_classify( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t tx_nbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_peer_t *peer = NULL; + struct ol_tx_frms_queue_t *txq = NULL; + A_UINT8 *dest_addr; + A_UINT8 tid; +#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + u_int8_t peer_id; +#endif + + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf); + if (IEEE80211_IS_MULTICAST(dest_addr)) { + txq = &vdev->txqs[OL_TX_VDEV_MCAST_BCAST]; + tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST; + if (vdev->opmode == wlan_op_mode_sta) { + /* + * The STA sends a frame with a broadcast dest addr (DA) as a + * unicast frame to the AP's receive addr (RA). + * Find the peer object that represents the AP that the STA + * is associated with. + */ + peer = ol_txrx_assoc_peer_find(vdev); + if (!peer) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Error: STA %p (%02x:%02x:%02x:%02x:%02x:%02x) " + "trying to send bcast DA tx data frame " + "w/o association\n", + vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], + vdev->mac_addr.raw[2], vdev->mac_addr.raw[3], + vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + return NULL; /* error */ + } + /* + * The following line assumes each peer object has a single ID. + * This is currently true, and is expected to remain true. + */ + tx_msdu_info->htt.info.peer_id = peer->peer_ids[0]; + } else { + tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID; + /* + * Look up the vdev's BSS peer, so that the classify_extension + * function can check whether to encrypt multicast / broadcast + * frames. + */ + peer = ol_txrx_peer_find_hash_find(pdev, vdev->mac_addr.raw, 0, 1); + if (!peer) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Error: vdev %p (%02x:%02x:%02x:%02x:%02x:%02x) " + "trying to send bcast/mcast, but no self-peer found\n", + vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], + vdev->mac_addr.raw[2], vdev->mac_addr.raw[3], + vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + return NULL; /* error */ + } + } + tx_msdu_info->htt.info.is_unicast = FALSE; + } else { + /* tid would be overwritten for non QoS case*/ + tid = ol_tx_tid(pdev, tx_nbuf, tx_msdu_info); + if ((HTT_TX_EXT_TID_INVALID == tid) || (tid >= OL_TX_NUM_TIDS)) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "%s Error: could not classify packet into valid TID(%d).\n", + __func__, tid); + return NULL; + } + #ifdef ATH_SUPPORT_WAPI + /* Check to see if a frame is a WAI frame */ + if (tx_msdu_info->htt.info.ethertype == ETHERTYPE_WAI) { + /* WAI frames should not be encrypted */ + tx_msdu_info->htt.action.do_encrypt = 0; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "Tx Frame is a WAI frame\n"); + } + #endif /* ATH_SUPPORT_WAPI */ + + /* + * Find the peer and increment its reference count. + * If this vdev is an AP, use the dest addr (DA) to determine + * which peer STA this unicast data frame is for. + * If this vdev is a STA, the unicast data frame is for the + * AP the STA is associated with. + */ + if (vdev->opmode == wlan_op_mode_sta) { + /* + * TO DO: + * To support TDLS, first check if there is a TDLS peer STA, + * and if so, check if the DA matches the TDLS peer STA's + * MAC address. + * If there is no peer TDLS STA, or if the DA is not the + * TDLS STA's address, then the frame is either for the AP + * itself, or is supposed to be sent to the AP for forwarding. + */ + #if 0 + if (vdev->num_tdls_peers > 0) { + peer = NULL; + for (i = 0; i < vdev->num_tdls_peers); i++) { + int differs = adf_os_mem_cmp( + vdev->tdls_peers[i]->mac_addr.raw, + dest_addr, OL_TXRX_MAC_ADDR_LEN); + if (!differs) { + peer = vdev->tdls_peers[i]; + break; + } + } + } else { + /* send to AP */ + peer = ol_txrx_assoc_peer_find(vdev); + } + #endif + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + if (vdev->hlTdlsFlag) { + peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id); + if (peer && (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) + peer = NULL; + else { + if (peer) + adf_os_atomic_inc(&peer->ref_cnt); + } + } + if (!peer) + peer = ol_txrx_assoc_peer_find(vdev); + #else + peer = ol_txrx_assoc_peer_find(vdev); + #endif + } else { + peer = ol_txrx_peer_find_hash_find(pdev, dest_addr, 0, 1); + } + tx_msdu_info->htt.info.is_unicast = TRUE; + if (!peer) { + /* + * Unicast data xfer can only happen to an associated peer. + * It is illegitimate to send unicast data if there is no peer + * to send it to. + */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Error: vdev %p (%02x:%02x:%02x:%02x:%02x:%02x) " + "trying to send unicast tx data frame to an unknown peer\n", + vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], + vdev->mac_addr.raw[2], vdev->mac_addr.raw[3], + vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + return NULL; /* error */ + } + TX_SCHED_DEBUG_PRINT("Peer found\n"); + if (!peer->qos_capable) { + tid = OL_TX_NON_QOS_TID; + } + /* Only allow encryption when in authenticated state */ + if (ol_txrx_peer_state_auth != peer->state) { + tx_msdu_info->htt.action.do_encrypt = 0; + } + txq = &peer->txqs[tid]; + tx_msdu_info->htt.info.ext_tid = tid; + /* + * The following line assumes each peer object has a single ID. + * This is currently true, and is expected to remain true. + */ + tx_msdu_info->htt.info.peer_id = peer->peer_ids[0]; + /* + * WORKAROUND - check that the peer ID is valid. + * If tx data is provided before ol_rx_peer_map_handler is called + * to record the peer ID specified by the target, then we could + * end up here with an invalid peer ID. + * TO DO: rather than dropping the tx frame, pause the txq it + * goes into, then fill in the peer ID for the entries in the + * txq when the peer_map event provides the peer ID, and then + * unpause the txq. + */ + if (tx_msdu_info->htt.info.peer_id == HTT_INVALID_PEER_ID) { + if (peer) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: remove the peer for invalid peer_id %p\n", + __func__, peer); + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(peer); + tx_msdu_info->peer = NULL; + } + return NULL; + } + } + tx_msdu_info->peer = peer; + /* + * If relevant, do a deeper inspection to determine additional + * characteristics of the tx frame. + * If the frame is invalid, then the txq will be set to NULL to + * indicate an error. + */ + OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, tx_nbuf, tx_msdu_info, txq); + if (IEEE80211_IS_MULTICAST(dest_addr) && vdev->opmode != wlan_op_mode_sta) { + + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: remove the peer reference %p\n", __func__, peer); + /* remove the peer reference added above */ + ol_txrx_peer_unref_delete(tx_msdu_info->peer); + /* Making peer NULL in case if multicast non STA mode */ + tx_msdu_info->peer = NULL; + } + + /* Whether this frame can download though HTT2 data pipe or not. */ + OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info); + + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); + return txq; +} + +struct ol_tx_frms_queue_t * +ol_tx_classify_mgmt( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t tx_nbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_peer_t *peer = NULL; + struct ol_tx_frms_queue_t *txq = NULL; + A_UINT8 *dest_addr; + + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf); + if (IEEE80211_IS_MULTICAST(dest_addr)) { + /* + * AP: beacons are broadcast, + * public action frames (e.g. extended channel switch announce) + * may be broadcast + * STA: probe requests can be either broadcast or unicast + */ + txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT]; + tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID; + tx_msdu_info->peer = NULL; + tx_msdu_info->htt.info.is_unicast = 0; + } else { + /* + * Find the peer and increment its reference count. + * If this vdev is an AP, use the receiver addr (RA) to determine + * which peer STA this unicast mgmt frame is for. + * If this vdev is a STA, the unicast mgmt frame is for the + * AP the STA is associated with. + * Probe request / response and Assoc request / response are + * sent before the peer exists - in this case, use the + * vdev's default tx queue. + */ + if (vdev->opmode == wlan_op_mode_sta) { + /* + * TO DO: + * To support TDLS, first check if there is a TDLS peer STA, + * and if so, check if the DA matches the TDLS peer STA's + * MAC address. + */ + peer = ol_txrx_assoc_peer_find(vdev); + } else { + /* find the peer and increment its reference count */ + peer = ol_txrx_peer_find_hash_find(pdev, dest_addr, 0, 1); + } + tx_msdu_info->peer = peer; + if (!peer) { + txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT]; + tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID; + } else { + txq = &peer->txqs[HTT_TX_EXT_TID_MGMT]; + tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_MGMT; + /* + * The following line assumes each peer object has a single ID. + * This is currently true, and is expected to remain true. + */ + tx_msdu_info->htt.info.peer_id = peer->peer_ids[0]; + } + tx_msdu_info->htt.info.is_unicast = 1; + } + /* + * If relevant, do a deeper inspection to determine additional + * characteristics of the tx frame. + * If the frame is invalid, then the txq will be set to NULL to + * indicate an error. + */ + OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, tx_nbuf, tx_msdu_info, txq); + + /* Whether this frame can download though HTT2 data pipe or not. */ + OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info); + + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); + return txq; +} + +A_STATUS +ol_tx_classify_extension( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t tx_msdu, + struct ol_txrx_msdu_info_t *msdu_info) +{ + A_UINT8 *datap = adf_nbuf_data(tx_msdu); + struct ol_txrx_peer_t *peer; + int which_key; + + /* + * The following msdu_info fields were already filled in by the + * ol_tx entry function or the regular ol_tx_classify function: + * htt.info.vdev_id (ol_tx_hl or ol_tx_non_std_hl) + * htt.info.ext_tid (ol_tx_non_std_hl or ol_tx_classify) + * htt.info.frame_type (ol_tx_hl or ol_tx_non_std_hl) + * htt.info.l2_hdr_type (ol_tx_hl or ol_tx_non_std_hl) + * htt.info.is_unicast (ol_tx_classify) + * htt.info.peer_id (ol_tx_classify) + * peer (ol_tx_classify) + * if (is_unicast) { + * htt.info.ethertype (ol_tx_classify) + * htt.info.l3_hdr_offset (ol_tx_classify) + * } + * The following fields need to be filled in by this function: + * if (!is_unicast) { + * htt.info.ethertype + * htt.info.l3_hdr_offset + * } + * htt.action.band (NOT CURRENTLY USED) + * htt.action.do_encrypt + * htt.action.do_tx_complete + * The following fields are not needed for data frames, and can + * be left uninitialized: + * htt.info.frame_subtype + */ + + if (!msdu_info->htt.info.is_unicast) { + int l2_hdr_size; + A_UINT16 ethertype; + + if (msdu_info->htt.info.l2_hdr_type == htt_pkt_type_ethernet) { + struct ethernet_hdr_t *eh; + + eh = (struct ethernet_hdr_t *) datap; + l2_hdr_size = sizeof(*eh); + ethertype = (eh->ethertype[0] << 8) | eh->ethertype[1]; + + if (ethertype == ETHERTYPE_VLAN) { + struct ethernet_vlan_hdr_t *evh; + + evh = (struct ethernet_vlan_hdr_t *) datap; + l2_hdr_size = sizeof(*evh); + ethertype = (evh->ethertype[0] << 8) | evh->ethertype[1]; + } + + if (!IS_ETHERTYPE(ethertype)) { // 802.3 header + struct llc_snap_hdr_t *llc = + (struct llc_snap_hdr_t *) (datap + l2_hdr_size); + ethertype = (llc->ethertype[0] << 8) | llc->ethertype[1]; + l2_hdr_size += sizeof(*llc); + } + msdu_info->htt.info.l3_hdr_offset = l2_hdr_size; + msdu_info->htt.info.ethertype = ethertype; + } else { /* 802.11 */ + struct llc_snap_hdr_t *llc; + l2_hdr_size = ol_txrx_ieee80211_hdrsize(datap); + llc = (struct llc_snap_hdr_t *) (datap + l2_hdr_size); + ethertype = (llc->ethertype[0] << 8) | llc->ethertype[1]; + /* + * Don't include the LLC/SNAP header in l2_hdr_size, because + * l3_hdr_offset is actually supposed to refer to the header + * after the 802.3 or 802.11 header, which could be a LLC/SNAP + * header rather than the L3 header. + */ + } + msdu_info->htt.info.l3_hdr_offset = l2_hdr_size; + msdu_info->htt.info.ethertype = ethertype; + which_key = txrx_sec_mcast; + } else { + which_key = txrx_sec_ucast; + } + peer = msdu_info->peer; + /* + * msdu_info->htt.action.do_encrypt is initially set in ol_tx_desc_hl. + * Add more check here. + */ + msdu_info->htt.action.do_encrypt = (!peer) ? 0 : + (peer->security[which_key].sec_type == htt_sec_type_none) ? 0 : + msdu_info->htt.action.do_encrypt; + /* + * For systems that have a frame by frame spec for whether to receive + * a tx completion notification, use the tx completion notification only + * for certain management frames, not for data frames. + * (In the future, this may be changed slightly, e.g. to request a + * tx completion notification for the final EAPOL message sent by a + * STA during the key delivery handshake.) + */ + msdu_info->htt.action.do_tx_complete = 0; + + return A_OK; +} + +A_STATUS +ol_tx_classify_mgmt_extension( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t tx_msdu, + struct ol_txrx_msdu_info_t *msdu_info) +{ + struct ieee80211_frame *wh; + + /* + * The following msdu_info fields were already filled in by the + * ol_tx entry function or the regular ol_tx_classify_mgmt function: + * htt.info.vdev_id (ol_txrx_mgmt_send) + * htt.info.frame_type (ol_txrx_mgmt_send) + * htt.info.l2_hdr_type (ol_txrx_mgmt_send) + * htt.action.do_tx_complete (ol_txrx_mgmt_send) + * htt.info.peer_id (ol_tx_classify_mgmt) + * htt.info.ext_tid (ol_tx_classify_mgmt) + * htt.info.is_unicast (ol_tx_classify_mgmt) + * peer (ol_tx_classify_mgmt) + * The following fields need to be filled in by this function: + * htt.info.frame_subtype + * htt.info.l3_hdr_offset + * htt.action.band (NOT CURRENTLY USED) + * The following fields are not needed for mgmt frames, and can + * be left uninitialized: + * htt.info.ethertype + * htt.action.do_encrypt + * (This will be filled in by other SW, which knows whether + * the peer has robust-managment-frames enabled.) + */ + wh = (struct ieee80211_frame *) adf_nbuf_data(tx_msdu); + msdu_info->htt.info.frame_subtype = + (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >> + IEEE80211_FC0_SUBTYPE_SHIFT; + msdu_info->htt.info.l3_hdr_offset = sizeof(struct ieee80211_frame); + + return A_OK; +} + +#endif /* defined(CONFIG_HL_SUPPORT) */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.h new file mode 100644 index 0000000000000..06e4350b5873a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_classify.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx_classify.h + * @brief API definitions for the tx classify module within the data SW. + */ +#ifndef _OL_TX_CLASSIFY__H_ +#define _OL_TX_CLASSIFY__H_ + +#include /* adf_nbuf_t */ +#include /* ol_txrx_vdev_t, etc. */ + +static inline u_int8_t * +ol_tx_dest_addr_find( + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t tx_nbuf) +{ + u_int8_t *hdr_ptr; + void *datap = adf_nbuf_data(tx_nbuf); + + if (pdev->frame_format == wlan_frm_fmt_raw) { + /* adjust hdr_ptr to RA */ + struct ieee80211_frame *wh = (struct ieee80211_frame *)datap; + hdr_ptr = wh->i_addr1; + } else if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + /* adjust hdr_ptr to RA */ + struct ieee80211_frame *wh = (struct ieee80211_frame *)datap; + hdr_ptr = wh->i_addr1; + } else if (pdev->frame_format == wlan_frm_fmt_802_3) { + hdr_ptr = datap; + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid standard frame type: %d\n", + pdev->frame_format); + adf_os_assert(0); + hdr_ptr = NULL; + } + return hdr_ptr; +} + +#if defined(CONFIG_HL_SUPPORT) + +/** + * @brief Classify a tx frame to which tid queue. + * + * @param vdev - the virtual device sending the data + * (for specifying the transmitter address for multicast / broadcast data) + * @param tx_desc - descriptor object with meta-data about the tx frame + * @param netbuf - the tx frame + * @param tx_msdu_info - characteristics of the tx frame + */ +struct ol_tx_frms_queue_t * +ol_tx_classify( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info); + +struct ol_tx_frms_queue_t * +ol_tx_classify_mgmt( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *tx_msdu_info); + +#else + +#define ol_tx_classify(vdev, tx_desc, netbuf, tx_msdu_info) NULL +#define ol_tx_classify_mgmt(vdev, tx_desc, netbuf, tx_msdu_info) NULL + +#endif /* defined(CONFIG_HL_SUPPORT) */ + + +#endif /* _OL_TX_CLASSIFY__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.c new file mode 100644 index 0000000000000..45fbc598fbd4d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* ADF_NBUF_EXEMPT_NO_EXEMPTION, etc. */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_assert */ +#include /* adf_os_spinlock */ +#ifdef QCA_COMPUTE_TX_DELAY +#include /* adf_os_ticks */ +#endif +#include /* TAILQ */ + +#include /* htt_tx_desc_id */ + +#include /* ol_txrx_pdev_t */ +#include +#include +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP +#include /* OL_TX_RESTORE_HDR, etc*/ +#endif +#include + +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS +extern u_int32_t *g_dbg_htt_desc_end_addr, *g_dbg_htt_desc_start_addr; +#endif + +#ifdef QCA_COMPUTE_TX_DELAY +static inline void +OL_TX_TIMESTAMP_SET(struct ol_tx_desc_t *tx_desc) +{ + tx_desc->entry_timestamp_ticks = adf_os_ticks(); +} +#else +#define OL_TX_TIMESTAMP_SET(tx_desc) /* no-op */ +#endif + +static inline struct ol_tx_desc_t * +ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) +{ + struct ol_tx_desc_t *tx_desc = NULL; + + adf_os_spin_lock_bh(&pdev->tx_mutex); + if (pdev->tx_desc.freelist) { + pdev->tx_desc.num_free--; + tx_desc = &pdev->tx_desc.freelist->tx_desc; + pdev->tx_desc.freelist = pdev->tx_desc.freelist->next; +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + if (tx_desc->pkt_type != 0xff +#ifdef QCA_COMPUTE_TX_DELAY + || tx_desc->entry_timestamp_ticks != 0xffffffff +#endif + ) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s Potential tx_desc corruption pkt_type:0x%x pdev:0x%p", + __func__, tx_desc->pkt_type, pdev); +#ifdef QCA_COMPUTE_TX_DELAY + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s Timestamp:0x%x\n", + __func__, tx_desc->entry_timestamp_ticks); +#endif + adf_os_assert(0); + } + if ((u_int32_t *) tx_desc->htt_tx_desc < g_dbg_htt_desc_start_addr || + (u_int32_t *) tx_desc->htt_tx_desc > g_dbg_htt_desc_end_addr) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s Potential htt_desc curruption:0x%p pdev:0x%p\n", + __func__, tx_desc->htt_tx_desc, pdev); + adf_os_assert(0); + } +#endif + } + adf_os_spin_unlock_bh(&pdev->tx_mutex); + if (!tx_desc) { + return NULL; + } +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + tx_desc->vdev = vdev; + adf_os_atomic_inc(&vdev->tx_desc_count); +#endif + + OL_TX_TIMESTAMP_SET(tx_desc); + + return tx_desc; +} + +static inline struct ol_tx_desc_t * +ol_tx_desc_alloc_hl(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) +{ + struct ol_tx_desc_t *tx_desc; + + tx_desc = ol_tx_desc_alloc(pdev, vdev); + if (!tx_desc) return NULL; + + + adf_os_atomic_dec(&pdev->tx_queue.rsrc_cnt); + + return tx_desc; +} + +/* TBD: make this inline in the .h file? */ +struct ol_tx_desc_t * +ol_tx_desc_find(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id) +{ + return &pdev->tx_desc.array[tx_desc_id].tx_desc; +} + +void +ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) +{ + adf_os_spin_lock_bh(&pdev->tx_mutex); +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + tx_desc->pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + tx_desc->entry_timestamp_ticks = 0xffffffff; +#endif +#endif + ((union ol_tx_desc_list_elem_t *) tx_desc)->next = pdev->tx_desc.freelist; + pdev->tx_desc.freelist = (union ol_tx_desc_list_elem_t *) tx_desc; + pdev->tx_desc.num_free++; +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) +#ifdef QCA_LL_TX_FLOW_CT + if ( (adf_os_atomic_read(&tx_desc->vdev->os_q_paused)) && + (adf_os_atomic_read(&tx_desc->vdev->tx_desc_count) < + TXRX_HL_TX_FLOW_CTRL_VDEV_LOW_WATER_MARK) ) { + /* wakeup netif_queue */ + adf_os_atomic_set(&tx_desc->vdev->os_q_paused, 0); + tx_desc->vdev->osif_flow_control_cb(tx_desc->vdev->osif_dev, + tx_desc->vdev->vdev_id, A_TRUE); + } +#endif /* QCA_LL_TX_FLOW_CT */ + adf_os_atomic_dec(&tx_desc->vdev->tx_desc_count); + tx_desc->vdev = NULL; +#endif + adf_os_spin_unlock_bh(&pdev->tx_mutex); +} + +struct ol_tx_desc_t * +ol_tx_desc_ll( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *msdu_info) +{ + struct ol_tx_desc_t *tx_desc; + unsigned int i; + u_int32_t num_frags; + + msdu_info->htt.info.vdev_id = vdev->vdev_id; + msdu_info->htt.action.cksum_offload = adf_nbuf_get_tx_cksum(netbuf); + switch (adf_nbuf_get_exemption_type(netbuf)) { + case ADF_NBUF_EXEMPT_NO_EXEMPTION: + case ADF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE: + /* We want to encrypt this frame */ + msdu_info->htt.action.do_encrypt = 1; + break; + case ADF_NBUF_EXEMPT_ALWAYS: + /* We don't want to encrypt this frame */ + msdu_info->htt.action.do_encrypt = 0; + break; + default: + adf_os_assert(0); + break; + } + + /* allocate the descriptor */ + tx_desc = ol_tx_desc_alloc(pdev, vdev); + if (!tx_desc) return NULL; + + /* initialize the SW tx descriptor */ + tx_desc->netbuf = netbuf; + /* fix this - get pkt_type from msdu_info */ + tx_desc->pkt_type = ol_tx_frm_std; + + /* initialize the HW tx descriptor */ + htt_tx_desc_init( + pdev->htt_pdev, tx_desc->htt_tx_desc, + tx_desc->htt_tx_desc_paddr, + ol_tx_desc_id(pdev, tx_desc), + netbuf, + &msdu_info->htt); + + /* + * Initialize the fragmentation descriptor. + * Skip the prefix fragment (HTT tx descriptor) that was added + * during the call to htt_tx_desc_init above. + */ + num_frags = adf_nbuf_get_num_frags(netbuf); + /* num_frags are expected to be 2 max */ + num_frags = (num_frags > CVG_NBUF_MAX_EXTRA_FRAGS) ? CVG_NBUF_MAX_EXTRA_FRAGS : num_frags; + htt_tx_desc_num_frags(pdev->htt_pdev, tx_desc->htt_tx_desc, num_frags-1); + for (i = 1; i < num_frags; i++) { + adf_os_size_t frag_len; + u_int32_t frag_paddr; + + frag_len = adf_nbuf_get_frag_len(netbuf, i); + frag_paddr = adf_nbuf_get_frag_paddr_lo(netbuf, i); + htt_tx_desc_frag( + pdev->htt_pdev, tx_desc->htt_tx_desc, i-1, frag_paddr, frag_len); + } + return tx_desc; +} + +struct ol_tx_desc_t * +ol_tx_desc_hl( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *msdu_info) +{ + struct ol_tx_desc_t *tx_desc; + + /* FIX THIS: these inits should probably be done by tx classify */ + msdu_info->htt.info.vdev_id = vdev->vdev_id; + msdu_info->htt.info.frame_type = pdev->htt_pkt_type; + msdu_info->htt.action.cksum_offload = adf_nbuf_get_tx_cksum(netbuf); + switch (adf_nbuf_get_exemption_type(netbuf)) { + case ADF_NBUF_EXEMPT_NO_EXEMPTION: + case ADF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE: + /* We want to encrypt this frame */ + msdu_info->htt.action.do_encrypt = 1; + break; + case ADF_NBUF_EXEMPT_ALWAYS: + /* We don't want to encrypt this frame */ + msdu_info->htt.action.do_encrypt = 0; + break; + default: + adf_os_assert(0); + break; + } + + /* allocate the descriptor */ + tx_desc = ol_tx_desc_alloc_hl(pdev, vdev); + if (!tx_desc) return NULL; + + /* initialize the SW tx descriptor */ + tx_desc->netbuf = netbuf; + /* fix this - get pkt_type from msdu_info */ + tx_desc->pkt_type = ol_tx_frm_std; + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + tx_desc->orig_l2_hdr_bytes = 0; +#endif + /* the HW tx descriptor will be initialized later by the caller */ + + return tx_desc; +} + +void ol_tx_desc_frame_list_free( + struct ol_txrx_pdev_t *pdev, + ol_tx_desc_list *tx_descs, + int had_error) +{ + struct ol_tx_desc_t *tx_desc, *tmp; + adf_nbuf_t msdus = NULL; + + TAILQ_FOREACH_SAFE(tx_desc, tx_descs, tx_desc_list_elem, tmp) { + adf_nbuf_t msdu = tx_desc->netbuf; + + adf_os_atomic_init(&tx_desc->ref_cnt); /* clear the ref cnt */ +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + OL_TX_RESTORE_HDR(tx_desc, msdu); /* restore original hdr offset */ +#endif + adf_nbuf_unmap(pdev->osdev, msdu, ADF_OS_DMA_TO_DEVICE); + /* free the tx desc */ + ol_tx_desc_free(pdev, tx_desc); + /* link the netbuf into a list to free as a batch */ + adf_nbuf_set_next(msdu, msdus); + msdus = msdu; + } + /* free the netbufs as a batch */ + adf_nbuf_tx_free(msdus, had_error); +} + +void ol_tx_desc_frame_free_nonstd( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + int had_error) +{ + int mgmt_type; + ol_txrx_mgmt_tx_cb ota_ack_cb; + char *trace_str; + + adf_os_atomic_init(&tx_desc->ref_cnt); /* clear the ref cnt */ +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + OL_TX_RESTORE_HDR(tx_desc, (tx_desc->netbuf)); /* restore original hdr offset */ +#endif + trace_str = (had_error) ? "OT:C:F:" : "OT:C:S:"; + adf_nbuf_trace_update(tx_desc->netbuf, trace_str); + if (tx_desc->pkt_type == ol_tx_frm_no_free) { + /* free the tx desc but don't unmap or free the frame */ + if (pdev->tx_data_callback.func) { + adf_nbuf_set_next(tx_desc->netbuf, NULL); + pdev->tx_data_callback.func( + pdev->tx_data_callback.ctxt, tx_desc->netbuf, had_error); + ol_tx_desc_free(pdev, tx_desc); + return; + } + /* let the code below unmap and free the frame */ + } + adf_nbuf_unmap(pdev->osdev, tx_desc->netbuf, ADF_OS_DMA_TO_DEVICE); + /* check the frame type to see what kind of special steps are needed */ + if (tx_desc->pkt_type == ol_tx_frm_tso) { +#if 0 + /* + * Free the segment's customized ethernet+IP+TCP header. + * Fragment 0 added by the WLAN driver is the HTT+HTC tx descriptor. + * Fragment 1 added by the WLAN driver is the Ethernet+IP+TCP header + * added for this TSO segment. + */ + tso_tcp_hdr = adf_nbuf_get_frag_vaddr(tx_desc->netbuf, 1); + ol_tx_tso_hdr_free(pdev, tso_tcp_hdr); +#endif + /* free the netbuf */ + adf_nbuf_set_next(tx_desc->netbuf, NULL); + adf_nbuf_tx_free(tx_desc->netbuf, had_error); + } else if ((tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) && + (tx_desc->pkt_type != 0xff)) { + /* FIX THIS - + * The FW currently has trouble using the host's fragments table + * for management frames. Until this is fixed, rather than + * specifying the fragment table to the FW, the host SW will + * specify just the address of the initial fragment. + * Now that the mgmt frame is done, the HTT tx desc's frags table + * pointer needs to be reset. + */ + htt_tx_desc_frags_table_set(pdev->htt_pdev, tx_desc->htt_tx_desc, 0, 1); + + mgmt_type = tx_desc->pkt_type - OL_TXRX_MGMT_TYPE_BASE; + /* + * we already checked the value when the mgmt frame was provided to the txrx layer. + * no need to check it a 2nd time. + */ + ota_ack_cb = pdev->tx_mgmt.callbacks[mgmt_type].ota_ack_cb; + if (ota_ack_cb) { + void *ctxt; + ctxt = pdev->tx_mgmt.callbacks[mgmt_type].ctxt; + ota_ack_cb(ctxt, tx_desc->netbuf, had_error); + } + /* free the netbuf */ + adf_nbuf_free(tx_desc->netbuf); + } else { + /* single regular frame */ + adf_nbuf_set_next(tx_desc->netbuf, NULL); + adf_nbuf_tx_free(tx_desc->netbuf, had_error); + } + /* free the tx desc */ + ol_tx_desc_free(pdev, tx_desc); +} diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.h new file mode 100644 index 0000000000000..a31095464c9d6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_desc.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx_desc.h + * @brief API definitions for the tx descriptor module within the data SW. + */ +#ifndef _OL_TX_DESC__H_ +#define _OL_TX_DESC__H_ + +#include /* TAILQ_HEAD */ +#include /* adf_nbuf_t */ +#include /* ol_tx_desc_t */ +#include /*TXRX_ASSERT2 */ + +/** + * @brief Allocate and initialize a tx descriptor for a LL system. + * @details + * Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor + * for private use within the host data SW, and a HTT tx descriptor for + * downloading tx meta-data to the target FW/HW. + * Fill in the fields of this pair of tx descriptors based on the + * information in the netbuf. + * For LL, this includes filling in a fragmentation descriptor to + * specify to the MAC HW where to find the tx frame's fragments. + * + * @param pdev - the data physical device sending the data + * (for accessing the tx desc pool) + * @param vdev - the virtual device sending the data + * (for specifying the transmitter address for multicast / broadcast data) + * @param netbuf - the tx frame + * @param msdu_info - tx meta-data + */ +struct ol_tx_desc_t * +ol_tx_desc_ll( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *msdu_info); + +/** + * @brief Allocate and initialize a tx descriptor for a HL system. + * @details + * Allocate a tx descriptor pair for a new tx frame - a SW tx descriptor + * for private use within the host data SW, and a HTT tx descriptor for + * downloading tx meta-data to the target FW/HW. + * Fill in the fields of this pair of tx descriptors based on the + * information in the netbuf. + * + * @param pdev - the data physical device sending the data + * (for accessing the tx desc pool) + * @param vdev - the virtual device sending the data + * (for specifying the transmitter address for multicast / broadcast data) + * @param netbuf - the tx frame + * @param msdu_info - tx meta-data + */ +struct ol_tx_desc_t * +ol_tx_desc_hl( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t netbuf, + struct ol_txrx_msdu_info_t *msdu_info); + +/** + * @brief Use a tx descriptor ID to find the corresponding desriptor object. + * + * @param pdev - the data physical device sending the data + * @param tx_desc_id - the ID of the descriptor in question + * @return the descriptor object that has the specified ID + */ +struct ol_tx_desc_t * +ol_tx_desc_find(struct ol_txrx_pdev_t *pdev, u_int16_t tx_desc_id); + +/** + * @brief Free a list of tx descriptors and the tx frames they refer to. + * @details + * Free a batch of "standard" tx descriptors and their tx frames. + * Free each tx descriptor, by returning it to the freelist. + * Unmap each netbuf, and free the netbufs as a batch. + * Irregular tx frames like TSO or managment frames that require + * special handling are processed by the ol_tx_desc_frame_free_nonstd + * function rather than this function. + * + * @param pdev - the data physical device that sent the data + * @param tx_descs - a list of SW tx descriptors for the tx frames + * @param had_error - boolean indication of whether the transmission failed. + * This is provided to callback functions that get notified of + * the tx frame completion. + */ +void ol_tx_desc_frame_list_free( + struct ol_txrx_pdev_t *pdev, + ol_tx_desc_list *tx_descs, + int had_error); + +/** + * @brief Free a non-standard tx frame and its tx descriptor. + * @details + * Check the tx frame type (e.g. TSO vs. management) to determine what + * special steps, if any, need to be performed prior to freeing the + * tx frame and its tx descriptor. + * This function can also be used to free single standard tx frames. + * After performing any special steps based on tx frame type, free the + * tx descriptor, i.e. return it to the freelist, and unmap and + * free the netbuf referenced by the tx descriptor. + * + * @param pdev - the data physical device that sent the data + * @param tx_desc - the SW tx descriptor for the tx frame that was sent + * @param had_error - boolean indication of whether the transmission failed. + * This is provided to callback functions that get notified of + * the tx frame completion. + */ +void ol_tx_desc_frame_free_nonstd( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + int had_error); + +/* + * @brief Determine the ID of a tx descriptor. + * + * @param pdev - the physical device that is sending the data + * @param tx_desc - the descriptor whose ID is being determined + * @return numeric ID that uniquely identifies the tx descriptor + */ +static inline u_int16_t +ol_tx_desc_id(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) +{ + TXRX_ASSERT2( + ((union ol_tx_desc_list_elem_t *) tx_desc - pdev->tx_desc.array) < + pdev->tx_desc.pool_size); + return (u_int16_t) + ((union ol_tx_desc_list_elem_t *)tx_desc - pdev->tx_desc.array); +} +/* + * @brief Retrieves the beacon headr for the vdev + * @param pdev - opaque pointe to scn + * @param vdevid - vdev id + * @return void pointer to the beacon header for the given vdev + */ + +void * +ol_ath_get_bcn_header(ol_pdev_handle pdev, A_UINT32 vdev_id); + +/* + * @brief Free a tx descriptor, without freeing the matching frame. + * @details + * This function is using during the function call that submits tx frames + * into the txrx layer, for cases where a tx descriptor is successfully + * allocated, but for other reasons the frame could not be accepted. + * + * @param pdev - the data physical device that is sending the data + * @param tx_desc - the descriptor being freed + */ +void +ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc); + +#endif /* _OL_TX_DESC__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.c new file mode 100644 index 0000000000000..0936b0504d321 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -0,0 +1,1265 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_atomic_add, etc. */ +#include /* ol_cfg_addba_retry */ +#include /* HTT_TX_EXT_TID_MGMT */ +#include /* htt_tx_desc_tid */ +#include /* ol_txrx_vdev_handle */ +#include /* ol_txrx_sync, ol_tx_addba_conf */ +#include /* ol_ctrl_addba_req */ +#include /* TXRX_ASSERT1, etc. */ +#include /* pdev stats */ +#include /* ol_tx_desc, ol_tx_desc_frame_list_free */ +#include /* ol_tx_vdev_ll_pause_queue_send */ +#include /* ol_tx_sched_notify, etc. */ +#include +#include /* ENABLE_TX_QUEUE_LOG */ +#include /* ol_tx_desc_pool_size_hl */ +#include /* a_bool_t */ + + +#if defined(CONFIG_HL_SUPPORT) + +#ifndef offsetof +#define offsetof(type, field) ((adf_os_size_t)(&((type *)0)->field)) +#endif + +/*--- function prototypes for optional queue log feature --------------------*/ +#if defined(ENABLE_TX_QUEUE_LOG) + +void +ol_tx_queue_log_enqueue( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_msdu_info_t *msdu_info, + int frms, int bytes); +void +ol_tx_queue_log_dequeue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int frms, int bytes); +void +ol_tx_queue_log_free( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid, int frms, int bytes); +#define OL_TX_QUEUE_LOG_ENQUEUE ol_tx_queue_log_enqueue +#define OL_TX_QUEUE_LOG_DEQUEUE ol_tx_queue_log_dequeue +#define OL_TX_QUEUE_LOG_FREE ol_tx_queue_log_free + +#else + +#define OL_TX_QUEUE_LOG_ENQUEUE(pdev, msdu_info, frms, bytes) /* no-op */ +#define OL_TX_QUEUE_LOG_DEQUEUE(pdev, txq, frms, bytes) /* no-op */ +#define OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes) /* no-op */ + +#endif /* TXRX_DEBUG_LEVEL > 5 */ + + +/*--- function prototypes for optional host ADDBA negotiation ---------------*/ + +#define OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info) /* no-op */ + + +#ifndef container_of +#define container_of(ptr, type, member) ((type *)( \ + (char *)(ptr) - (char *)(&((type *)0)->member) ) ) +#endif +/*--- function definitions --------------------------------------------------*/ + +/* + * Try to flush pending frames in the tx queues + * no matter it's queued in the TX scheduler or not. + */ +static inline void +ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) +{ +#define PEER_ARRAY_COUNT 10 + struct ol_tx_frms_queue_t *txq; + struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT]; + int i, j, peer_count; + + /* flush VDEV TX queues */ + for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { + txq = &vdev->txqs[i]; + ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS)); + } + /* flush PEER TX queues */ + do { + peer_count = 0; + /* select candidate peers */ + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + for (i = 0; i < OL_TX_NUM_TIDS; i++) { + txq = &peer->txqs[i]; + if (txq->frms) { + adf_os_atomic_inc(&peer->ref_cnt); + peers[peer_count++] = peer; + break; + } + } + if (peer_count >= PEER_ARRAY_COUNT) { + break; + } + } + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + /* flush TX queues of candidate peers */ + for (i = 0; i < peer_count; i++) { + for (j = 0; j < OL_TX_NUM_TIDS; j++) { + txq = &peers[i]->txqs[j]; + if (txq->frms) { + ol_tx_queue_free(pdev, txq, j); + } + } + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: Delete Peer %p\n", __func__, peer); + ol_txrx_peer_unref_delete(peers[i]); + } + } while (peer_count >= PEER_ARRAY_COUNT); +} + +static inline void +ol_tx_queue_flush(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + ol_tx_queue_vdev_flush(pdev, vdev); + } +} + +void +ol_tx_queue_discard( + struct ol_txrx_pdev_t *pdev, + a_bool_t flush_all, + ol_tx_desc_list *tx_descs) +{ + u_int16_t num; + u_int16_t discarded, actual_discarded = 0; + + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + + if (flush_all == A_TRUE) { + /* flush all the pending tx queues in the scheduler */ + num = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) - + adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt); + } else { + num = pdev->tx_queue.rsrc_threshold_hi - + pdev->tx_queue.rsrc_threshold_lo; + } + TX_SCHED_DEBUG_PRINT("+%s : %u\n,", __FUNCTION__, + adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt)); + while (num > 0) { + discarded = ol_tx_sched_discard_select( + pdev, (u_int16_t)num, tx_descs, flush_all); + if (discarded == 0) { + /* + * No more packets could be discarded. + * Probably tx queues are empty. + */ + break; + } + num -= discarded; + actual_discarded += discarded; + } + adf_os_atomic_add(actual_discarded, &pdev->tx_queue.rsrc_cnt); + TX_SCHED_DEBUG_PRINT("-%s \n",__FUNCTION__); + + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + + if (flush_all == A_TRUE && num > 0) { + /* + * try to flush pending frames in the tx queues + * which are not queued in the TX scheduler. + */ + ol_tx_queue_flush(pdev); + } +} + +void +ol_tx_enqueue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + struct ol_tx_desc_t *tx_desc, + struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + int bytes; + struct ol_tx_sched_notify_ctx_t notify_ctx; + + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + /* + * If too few tx descriptors are available, drop some currently-queued + * tx frames, to provide enough tx descriptors for new frames, which + * may be higher priority than the current frames. + */ + if (adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt) <= + pdev->tx_queue.rsrc_threshold_lo) + { + ol_tx_desc_list tx_descs; + TAILQ_INIT(&tx_descs); + ol_tx_queue_discard(pdev, A_FALSE, &tx_descs); + //Discard Frames in Discard List + ol_tx_desc_frame_list_free(pdev, &tx_descs, 1 /* error */); + } + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + TAILQ_INSERT_TAIL(&txq->head, tx_desc, tx_desc_list_elem); + + bytes = adf_nbuf_len(tx_desc->netbuf); + txq->frms++; + txq->bytes += bytes; + OL_TX_QUEUE_LOG_ENQUEUE(pdev, tx_msdu_info, 1, bytes); + + if (txq->flag != ol_tx_queue_paused) { + notify_ctx.event = OL_TX_ENQUEUE_FRAME; + notify_ctx.frames = 1; + notify_ctx.bytes = adf_nbuf_len(tx_desc->netbuf); + notify_ctx.txq = txq; + notify_ctx.info.tx_msdu_info = tx_msdu_info; + ol_tx_sched_notify(pdev, ¬ify_ctx); + txq->flag = ol_tx_queue_active; + } + + if (!ETHERTYPE_IS_EAPOL_WAPI(tx_msdu_info->htt.info.ethertype)) { + OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info); + } + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +u_int16_t +ol_tx_dequeue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + ol_tx_desc_list *head, + u_int16_t max_frames, + u_int32_t *credit, + int *bytes) +{ + u_int16_t num_frames; + int bytes_sum; + unsigned credit_sum; + + TXRX_ASSERT2(txq->flag != ol_tx_queue_paused); + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + if (txq->frms < max_frames) { + max_frames = txq->frms; + } + bytes_sum = 0; + credit_sum = 0; + for (num_frames = 0; num_frames < max_frames; num_frames++) { + unsigned frame_credit; + struct ol_tx_desc_t *tx_desc; + tx_desc = TAILQ_FIRST(&txq->head); + + frame_credit = htt_tx_msdu_credit(tx_desc->netbuf); + if (credit_sum + frame_credit > *credit) { + break; + } + credit_sum += frame_credit; + bytes_sum += adf_nbuf_len(tx_desc->netbuf); + TAILQ_REMOVE(&txq->head, tx_desc, tx_desc_list_elem); + TAILQ_INSERT_TAIL(head, tx_desc, tx_desc_list_elem); + } + txq->frms -= num_frames; + txq->bytes -= bytes_sum; + /* a paused queue remains paused, regardless of whether it has frames */ + if (txq->frms == 0 && txq->flag == ol_tx_queue_active) { + txq->flag = ol_tx_queue_empty; + } + OL_TX_QUEUE_LOG_DEQUEUE(pdev, txq, num_frames, bytes_sum); + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); + + *bytes = bytes_sum; + *credit = credit_sum; + return num_frames; +} + +void +ol_tx_queue_free( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid) +{ + int frms = 0, bytes = 0; + struct ol_tx_desc_t *tx_desc; + struct ol_tx_sched_notify_ctx_t notify_ctx; + ol_tx_desc_list tx_tmp_list; + + TAILQ_INIT(&tx_tmp_list); + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + + notify_ctx.event = OL_TX_DELETE_QUEUE; + notify_ctx.txq = txq; + notify_ctx.info.ext_tid = tid; + ol_tx_sched_notify(pdev, ¬ify_ctx); + + frms = txq->frms; + tx_desc = TAILQ_FIRST(&txq->head); + while (txq->frms) { + bytes += adf_nbuf_len(tx_desc->netbuf); + txq->frms--; + tx_desc = TAILQ_NEXT(tx_desc, tx_desc_list_elem); + } + OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes); + txq->bytes -= bytes; + OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes); + txq->flag = ol_tx_queue_empty; + /* txq->head gets reset during the TAILQ_CONCAT call */ + TAILQ_CONCAT(&tx_tmp_list, &txq->head, tx_desc_list_elem); + + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + /* free tx frames without holding tx_queue_spinlock */ + adf_os_atomic_add(frms, &pdev->tx_queue.rsrc_cnt); + while (frms) { + tx_desc = TAILQ_FIRST(&tx_tmp_list); + TAILQ_REMOVE(&tx_tmp_list, tx_desc, tx_desc_list_elem); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 0); + frms--; + } + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + + +/*--- queue pause / unpause functions ---------------------------------------*/ + +static inline void +ol_txrx_peer_tid_pause_base( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + int tid) +{ + struct ol_tx_frms_queue_t *txq = &peer->txqs[tid]; + + if (txq->paused_count.total++ == 0) { + struct ol_tx_sched_notify_ctx_t notify_ctx; + + notify_ctx.event = OL_TX_PAUSE_QUEUE; + notify_ctx.txq = txq; + notify_ctx.info.ext_tid = tid; + ol_tx_sched_notify(pdev, ¬ify_ctx); + txq->flag = ol_tx_queue_paused; + } +} + +static inline void +ol_txrx_peer_pause_base( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + int i; + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + ol_txrx_peer_tid_pause_base(pdev, peer, i); + } +} + +static inline void +ol_txrx_peer_tid_unpause_base( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + int tid) +{ + struct ol_tx_frms_queue_t *txq = &peer->txqs[tid]; + /* + * Don't actually unpause the tx queue until all pause requests + * have been removed. + */ + TXRX_ASSERT2(txq->paused_count.total > 0); + if (--txq->paused_count.total == 0) { + struct ol_tx_sched_notify_ctx_t notify_ctx; + + notify_ctx.event = OL_TX_UNPAUSE_QUEUE; + notify_ctx.txq = txq; + notify_ctx.info.ext_tid = tid; + ol_tx_sched_notify(pdev, ¬ify_ctx); + + if (txq->frms == 0) { + txq->flag = ol_tx_queue_empty; + } else { + txq->flag = ol_tx_queue_active; + /* + * Now that the are new tx frames available to download, + * invoke the scheduling function, to see if it wants to + * download the new frames. + * Since the queue lock is currently held, and since + * the scheduler function takes the lock, temporarily + * release the lock. + */ + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + ol_tx_sched(pdev); + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + } + } +} + + +void +ol_txrx_peer_tid_unpause(ol_txrx_peer_handle peer, int tid) +{ + struct ol_txrx_pdev_t *pdev = peer->vdev->pdev; + + /* TO DO: log the queue unpause */ + + /* acquire the mutex lock, since we'll be modifying the queues */ + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + + if (tid == -1) { + int i; + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + ol_txrx_peer_tid_unpause_base(pdev, peer, i); + } + } else { + ol_txrx_peer_tid_unpause_base(pdev, peer, tid); + } + + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +void +ol_txrx_throttle_pause(ol_txrx_pdev_handle pdev) +{ +#if defined(QCA_SUPPORT_TX_THROTTLE) + adf_os_spin_lock_bh(&pdev->tx_throttle.mutex); + + if (pdev->tx_throttle.is_paused == TRUE) { + adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex); + return; + } + + pdev->tx_throttle.is_paused = TRUE; + adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex); +#endif + ol_txrx_pdev_pause(pdev, 0); +} + +void +ol_txrx_throttle_unpause(ol_txrx_pdev_handle pdev) +{ +#if defined(QCA_SUPPORT_TX_THROTTLE) + adf_os_spin_lock_bh(&pdev->tx_throttle.mutex); + + if (pdev->tx_throttle.is_paused == FALSE) { + adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex); + return; + } + + pdev->tx_throttle.is_paused = FALSE; + adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex); +#endif + ol_txrx_pdev_unpause(pdev, 0); +} +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +/** + * ol_txrx_pdev_pause() - Suspend all tx data for the specified physical device. + * @data_pdev: the physical device being paused. + * @reason: pause reason. + * + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * In some systems it is necessary to be able to temporarily + * suspend all WLAN traffic, e.g. to allow another device such as bluetooth + * to temporarily have exclusive access to shared RF chain resources. + * This function suspends tx traffic within the specified physical device. + * + * + * Return: None + */ +void +ol_txrx_pdev_pause(ol_txrx_pdev_handle pdev, u_int32_t reason) +{ + struct ol_txrx_vdev_t *vdev = NULL, *tmp; + + TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { + ol_txrx_vdev_pause(vdev, reason); + } +} + +/** + * ol_txrx_pdev_unpause() - Resume tx for the specified physical device.. + * @data_pdev: the physical device being paused. + * @reason: pause reason. + * + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * + * + * Return: None + */ +void +ol_txrx_pdev_unpause(ol_txrx_pdev_handle pdev, u_int32_t reason) +{ + struct ol_txrx_vdev_t *vdev = NULL, *tmp; + + TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { + ol_txrx_vdev_unpause(vdev, reason); + } +} + +void +ol_txrx_vdev_pause(ol_txrx_vdev_handle vdev, u_int32_t reason) +{ + /* TO DO: log the queue pause */ + /* acquire the mutex lock, since we'll be modifying the queues */ + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + if (vdev->pdev->cfg.is_high_latency) { +#if defined(CONFIG_HL_SUPPORT) + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_peer_t *peer; + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + ol_txrx_peer_pause_base(pdev, peer); + } + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); +#endif /* defined(CONFIG_HL_SUPPORT) */ + } else { + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + vdev->ll_pause.paused_reason |= reason; + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } + + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +void +ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev, u_int32_t reason) +{ + /* TO DO: log the queue unpause */ + /* acquire the mutex lock, since we'll be modifying the queues */ + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + if (vdev->pdev->cfg.is_high_latency) { +#if defined(CONFIG_HL_SUPPORT) + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ol_txrx_peer_t *peer; + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + int i; + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + ol_txrx_peer_tid_unpause_base(pdev, peer, i); + } + } + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); +#endif /* defined(CONFIG_HL_SUPPORT) */ + } else { + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + if (vdev->ll_pause.paused_reason & reason) + { + vdev->ll_pause.paused_reason &= ~reason; + if (reason == OL_TXQ_PAUSE_REASON_VDEV_SUSPEND) { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + ol_tx_vdev_ll_pause_start_timer(vdev); + } + else if (!vdev->ll_pause.paused_reason) { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + ol_tx_vdev_ll_pause_queue_send(vdev); + } else { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } + } else { + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } + } + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +void +ol_txrx_vdev_flush(ol_txrx_vdev_handle vdev) +{ + if (vdev->pdev->cfg.is_high_latency) { + #if defined(CONFIG_HL_SUPPORT) + ol_tx_queue_vdev_flush(vdev->pdev, vdev); + #endif + } else { + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + adf_os_timer_cancel(&vdev->ll_pause.timer); + while (vdev->ll_pause.txq.head) { + adf_nbuf_t next = adf_nbuf_next(vdev->ll_pause.txq.head); + adf_nbuf_set_next(vdev->ll_pause.txq.head, NULL); + adf_nbuf_unmap(vdev->pdev->osdev, vdev->ll_pause.txq.head, + ADF_OS_DMA_TO_DEVICE); + adf_nbuf_tx_free(vdev->ll_pause.txq.head, 1 /* error */); + vdev->ll_pause.txq.head = next; + } + vdev->ll_pause.txq.tail = NULL; + vdev->ll_pause.txq.depth = 0; + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } +} + +#endif // defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) + +/*--- LL tx throttle queue code --------------------------------------------*/ +#if defined(QCA_SUPPORT_TX_THROTTLE) +u_int8_t ol_tx_pdev_is_target_empty(void) +{ + /* TM TODO */ + return 1; +} + +void ol_tx_pdev_throttle_phase_timer(void *context) +{ + struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context; + int ms = 0; + throttle_level cur_level; + throttle_phase cur_phase; + + /* update the phase */ + pdev->tx_throttle.current_throttle_phase++; + + if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_MAX) { + pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; + } + + if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF) { + if (ol_tx_pdev_is_target_empty(/*pdev*/)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "throttle phase --> OFF\n"); + + if (pdev->cfg.is_high_latency) + ol_txrx_throttle_pause(pdev); + + cur_level = pdev->tx_throttle.current_throttle_level; + cur_phase = pdev->tx_throttle.current_throttle_phase; + ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase]; + if (pdev->tx_throttle.current_throttle_level != + THROTTLE_LEVEL_0) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms); + adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + } + } + } + else /* THROTTLE_PHASE_ON */ + { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "throttle phase --> ON\n"); + + if (pdev->cfg.is_high_latency) + ol_txrx_throttle_unpause(pdev); +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ + else + ol_tx_pdev_ll_pause_queue_send_all(pdev); +#endif + + cur_level = pdev->tx_throttle.current_throttle_level; + cur_phase = pdev->tx_throttle.current_throttle_phase; + ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase]; + if (pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms); + adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + } + } +} + +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ +void ol_tx_pdev_throttle_tx_timer(void *context) +{ + struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context; + ol_tx_pdev_ll_pause_queue_send_all(pdev); +} +#endif + +void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level) +{ + int ms = 0; + + if (level >= THROTTLE_LEVEL_MAX) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "%s invalid throttle level set %d, ignoring\n", + __func__, level); + return; + } + + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Setting throttle level %d\n", level); + + /* Set the current throttle level */ + pdev->tx_throttle.current_throttle_level = (throttle_level)level; + + if (pdev->cfg.is_high_latency) { + + adf_os_timer_cancel(&pdev->tx_throttle.phase_timer); + + /* Set the phase */ + if (level != THROTTLE_LEVEL_0) { + pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; + ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF]; + /* pause all */ + ol_txrx_throttle_pause(pdev); + } else { + pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_ON; + ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_ON]; + /* unpause all */ + ol_txrx_throttle_unpause(pdev); + } + } else { + /* Reset the phase */ + pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; + + /* Start with the new time */ + ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF]; + + adf_os_timer_cancel(&pdev->tx_throttle.phase_timer); + } + + if (level != THROTTLE_LEVEL_0) { + adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + } +} + +/* This table stores the duty cycle for each level. + Example "on" time for level 2 with duty period 100ms is: + "on" time = duty_period_ms >> throttle_duty_cycle_table[2] + "on" time = 100 ms >> 2 = 25ms */ +static u_int8_t g_throttle_duty_cycle_table[THROTTLE_LEVEL_MAX] = +{ 0, 1, 2, 4 }; + +void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev, int period) +{ + int i; + + /* Set the current throttle level */ + pdev->tx_throttle.throttle_period_ms = period; + + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "level OFF ON\n"); + for (i = 0; i < THROTTLE_LEVEL_MAX; i++) { + pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON] = + pdev->tx_throttle.throttle_period_ms >> + g_throttle_duty_cycle_table[i]; + pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_OFF] = + pdev->tx_throttle.throttle_period_ms - + pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON]; + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "%d %d %d\n", i, + pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_OFF], + pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON]); + } +} + +void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev) +{ + u_int32_t throttle_period; + + pdev->tx_throttle.current_throttle_level = THROTTLE_LEVEL_0; + pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; + adf_os_spinlock_init(&pdev->tx_throttle.mutex); + + throttle_period = ol_cfg_throttle_period_ms(pdev->ctrl_pdev); + + ol_tx_throttle_init_period(pdev, throttle_period); + + adf_os_timer_init( + pdev->osdev, + &pdev->tx_throttle.phase_timer, + ol_tx_pdev_throttle_phase_timer, + pdev, ADF_DEFERRABLE_TIMER); + +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ + adf_os_timer_init( + pdev->osdev, + &pdev->tx_throttle.tx_timer, + ol_tx_pdev_throttle_tx_timer, + pdev, ADF_DEFERRABLE_TIMER); +#endif + + pdev->tx_throttle.tx_threshold = THROTTLE_TX_THRESHOLD; +} +#endif /* QCA_SUPPORT_TX_THROTTLE */ +/*--- End of LL tx throttle queue code ---------------------------------------*/ + +#if defined(CONFIG_HL_SUPPORT) + +/*--- ADDBA triggering functions --------------------------------------------*/ + + +/*=== debug functions =======================================================*/ + +/*--- queue event log -------------------------------------------------------*/ + +#if defined(ENABLE_TX_QUEUE_LOG) + +static void +ol_tx_queue_log_entry_type_info( + u_int8_t *type, int *size, int *align, int var_size) +{ + switch (*type) { + case ol_tx_log_entry_type_enqueue: + case ol_tx_log_entry_type_dequeue: + case ol_tx_log_entry_type_queue_free: + *size = sizeof(struct ol_tx_log_queue_add_t); + *align = 2; + break; + + case ol_tx_log_entry_type_queue_state: + *size = offsetof(struct ol_tx_log_queue_state_var_sz_t, data); + *align = 4; + if (var_size) { + /* read the variable-sized record, to see how large it is */ + int align_pad; + struct ol_tx_log_queue_state_var_sz_t *record; + + align_pad = + (*align - ((((u_int32_t) type) + 1))) & (*align - 1); + record = (struct ol_tx_log_queue_state_var_sz_t *) + (type + 1 + align_pad); + *size += record->num_cats_active * + (sizeof(u_int32_t) /* bytes */ + sizeof(u_int16_t) /* frms */); + } + break; + + //case ol_tx_log_entry_type_drop: + default: + *size = 0; + *align = 0; + }; +} + +static void +ol_tx_queue_log_oldest_update(struct ol_txrx_pdev_t *pdev, int offset) +{ + int oldest_record_offset; + + /* + * If the offset of the oldest record is between the current and + * new values of the offset of the newest record, then the oldest + * record has to be dropped from the log to provide room for the + * newest record. + * Advance the offset of the oldest record until it points to a + * record that is beyond the new value of the offset of the newest + * record. + */ + if (!pdev->txq_log.wrapped) { + /* + * The log has not even filled up yet - no need to remove + * the oldest record to make room for a new record. + */ + return; + } + + if (offset > pdev->txq_log.offset) { + /* + * not wraparound - + * The oldest record offset may have already wrapped around, + * even if the newest record has not. In this case, then + * the oldest record offset is fine where it is. + */ + if (pdev->txq_log.oldest_record_offset == 0) { + return; + } + oldest_record_offset = pdev->txq_log.oldest_record_offset; + } else { + /* wraparound */ + oldest_record_offset = 0; + } + + while (oldest_record_offset < offset) { + int size, align, align_pad; + u_int8_t type; + + type = pdev->txq_log.data[oldest_record_offset]; + if (type == ol_tx_log_entry_type_wrap) { + oldest_record_offset = 0; + break; + } + ol_tx_queue_log_entry_type_info( + &pdev->txq_log.data[oldest_record_offset], &size, &align, 1); + align_pad = + (align - ((oldest_record_offset + 1/*type*/))) & (align - 1); + /* + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "TXQ LOG old alloc: offset %d, type %d, size %d (%d)\n", + oldest_record_offset, type, size, size + 1 + align_pad); + */ + oldest_record_offset += size + 1 + align_pad; + } + if (oldest_record_offset >= pdev->txq_log.size) { + oldest_record_offset = 0; + } + pdev->txq_log.oldest_record_offset = oldest_record_offset; +} + +void* +ol_tx_queue_log_alloc( + struct ol_txrx_pdev_t *pdev, + u_int8_t type /* ol_tx_log_entry_type */, + int extra_bytes) +{ + int size, align, align_pad; + int offset; + + ol_tx_queue_log_entry_type_info(&type, &size, &align, 0); + size += extra_bytes; + + offset = pdev->txq_log.offset; + align_pad = (align - ((offset + 1/*type*/))) & (align - 1); + + if (pdev->txq_log.size - offset >= size + 1 + align_pad) { + /* no need to wrap around */ + goto alloc_found; + } + if (! pdev->txq_log.allow_wrap) { + return NULL; /* log is full and can't wrap */ + } + /* handle wrap-around */ + pdev->txq_log.wrapped = 1; + offset = 0; + align_pad = (align - ((offset + 1/*type*/))) & (align - 1); + /* sanity check that the log is large enough to hold this entry */ + if (pdev->txq_log.size <= size + 1 + align_pad) { + return NULL; + } + +alloc_found: + ol_tx_queue_log_oldest_update(pdev, offset + size + 1 + align_pad); + if (offset == 0) { + pdev->txq_log.data[pdev->txq_log.offset] = ol_tx_log_entry_type_wrap; + } + /* + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "TXQ LOG new alloc: offset %d, type %d, size %d (%d)\n", + offset, type, size, size + 1 + align_pad); + */ + pdev->txq_log.data[offset] = type; + pdev->txq_log.offset = offset + size + 1 + align_pad; + if (pdev->txq_log.offset >= pdev->txq_log.size) { + pdev->txq_log.offset = 0; + pdev->txq_log.wrapped = 1; + } + return &pdev->txq_log.data[offset + 1 + align_pad]; +} + +static int +ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset) +{ + int size, align, align_pad; + u_int8_t type; + + type = pdev->txq_log.data[offset]; + ol_tx_queue_log_entry_type_info( + &pdev->txq_log.data[offset], &size, &align, 1); + align_pad = (align - ((offset + 1/*type*/))) & (align - 1); + + switch (type) { + case ol_tx_log_entry_type_enqueue: + { + struct ol_tx_log_queue_add_t *record; + record = (struct ol_tx_log_queue_add_t *) + &pdev->txq_log.data[offset + 1 + align_pad]; + if (record->peer_id != 0xffff) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " added %d frms (%d bytes) for peer %d, tid %d\n", + record->num_frms, record->num_bytes, + record->peer_id, record->tid); + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " added %d frms (%d bytes) vdev tid %d\n", + record->num_frms, record->num_bytes, record->tid); + } + break; + } + case ol_tx_log_entry_type_dequeue: + { + struct ol_tx_log_queue_add_t *record; + record = (struct ol_tx_log_queue_add_t *) + &pdev->txq_log.data[offset + 1 + align_pad]; + if (record->peer_id != 0xffff) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " download %d frms (%d bytes) from peer %d, tid %d\n", + record->num_frms, record->num_bytes, + record->peer_id, record->tid); + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " download %d frms (%d bytes) from vdev tid %d\n", + record->num_frms, record->num_bytes, record->tid); + } + break; + } + case ol_tx_log_entry_type_queue_free: + { + struct ol_tx_log_queue_add_t *record; + record = (struct ol_tx_log_queue_add_t *) + &pdev->txq_log.data[offset + 1 + align_pad]; + if (record->peer_id != 0xffff) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " peer %d, tid %d queue removed (%d frms, %d bytes)\n", + record->peer_id, record->tid, + record->num_frms, record->num_bytes); + } else { + /* shouldn't happen */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "Unexpected vdev queue removal\n"); + } + break; + } + + case ol_tx_log_entry_type_queue_state: + { + int i, j; + u_int32_t active_bitmap; + struct ol_tx_log_queue_state_var_sz_t *record; + u_int8_t *data; + + record = (struct ol_tx_log_queue_state_var_sz_t *) + &pdev->txq_log.data[offset + 1 + align_pad]; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " credit = %d, active category bitmap = %#x\n", + record->credit, record->active_bitmap); + data = &record->data[0]; + j = 0; + i = 0; + active_bitmap = record->active_bitmap; + while (active_bitmap) { + if (active_bitmap & 0x1) { + u_int16_t frms; + u_int32_t bytes; + + frms = data[0] | (data[1] << 8); + bytes = (data[2] << 0) | (data[3] << 8) | + (data[4] << 16) | (data[5] << 24); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " cat %d: %d frms, %d bytes\n", + i, frms, bytes); + data += 6; + j++; + } + i++; + active_bitmap >>= 1; + } + break; + } + + //case ol_tx_log_entry_type_drop: + + case ol_tx_log_entry_type_wrap: + return -1 * offset; /* go back to the top */ + + default: + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " *** invalid tx log entry type (%d)\n", type); + return 0; /* error */ + }; + + return size + 1 + align_pad; +} + +void +ol_tx_queue_log_display(struct ol_txrx_pdev_t *pdev) +{ + int offset; + int unwrap; + offset = pdev->txq_log.oldest_record_offset; + + /* + * In theory, this should use mutex to guard against the offset + * being changed while in use, but since this is just for debugging, + * don't bother. + */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "tx queue log:\n"); + unwrap = pdev->txq_log.wrapped; + while (unwrap || offset != pdev->txq_log.offset) { + int delta = ol_tx_queue_log_record_display(pdev, offset); + if (delta == 0) { + return; /* error */ + } + if (delta < 0) { + unwrap = 0; + } + offset += delta; + } +} + +void +ol_tx_queue_log_enqueue( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_msdu_info_t *msdu_info, + int frms, int bytes) +{ + int tid; + u_int16_t peer_id = msdu_info->htt.info.peer_id; + struct ol_tx_log_queue_add_t *log_elem; + tid = msdu_info->htt.info.ext_tid; + + log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_enqueue, 0); + if (!log_elem) { + return; + } + + log_elem->num_frms = frms; + log_elem->num_bytes = bytes; + log_elem->peer_id = peer_id; + log_elem->tid = tid; +} + +void +ol_tx_queue_log_dequeue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int frms, int bytes) +{ + int ext_tid; + u_int16_t peer_id; + struct ol_tx_log_queue_add_t *log_elem; + + ext_tid = txq->ext_tid; + log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_dequeue, 0); + if (!log_elem) { + return; + } + + if (ext_tid < OL_TX_NUM_TIDS) { + struct ol_txrx_peer_t *peer; + struct ol_tx_frms_queue_t *txq_base; + + txq_base = txq - ext_tid; + peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]); + peer_id = peer->peer_ids[0]; + } else { + peer_id = ~0; + } + + log_elem->num_frms = frms; + log_elem->num_bytes = bytes; + log_elem->peer_id = peer_id; + log_elem->tid = ext_tid; +} + +void +ol_tx_queue_log_free( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid, int frms, int bytes) +{ + u_int16_t peer_id; + struct ol_tx_log_queue_add_t *log_elem; + + log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_queue_free, 0); + if (!log_elem) { + return; + } + + if (tid < OL_TX_NUM_TIDS) { + struct ol_txrx_peer_t *peer; + struct ol_tx_frms_queue_t *txq_base; + + txq_base = txq - tid; + peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]); + peer_id = peer->peer_ids[0]; + } else { + peer_id = ~0; + } + + log_elem->num_frms = frms; + log_elem->num_bytes = bytes; + log_elem->peer_id = peer_id; + log_elem->tid = tid; +} + +void +ol_tx_queue_log_sched( + struct ol_txrx_pdev_t *pdev, + int credit, + int *num_cats, + u_int32_t **active_bitmap, + u_int8_t **data) +{ + int data_size; + struct ol_tx_log_queue_state_var_sz_t *log_elem; + + data_size = sizeof(u_int32_t) /* bytes */ + sizeof(u_int16_t) /* frms */; + data_size *= *num_cats; + + log_elem = ol_tx_queue_log_alloc( + pdev, ol_tx_log_entry_type_queue_state, data_size); + if (!log_elem) { + *num_cats = 0; + return; + } + log_elem->num_cats_active = *num_cats; + log_elem->active_bitmap = 0; + log_elem->credit = credit; + + *active_bitmap = &log_elem->active_bitmap; + *data = &log_elem->data[0]; +} + +#endif /* defined(ENABLE_TX_QUEUE_LOG) */ + +/*--- queue state printouts -------------------------------------------------*/ + +#if TXRX_DEBUG_LEVEL > 5 + +void +ol_tx_queue_display(struct ol_tx_frms_queue_t *txq, int indent) +{ + char *state; + + state = (txq->flag == ol_tx_queue_active) ? "active" : "paused"; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*stxq %p (%s): %d frms, %d bytes\n", + indent, " ", txq, state, txq->frms, txq->bytes); +} + +void +ol_tx_queues_display(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "pdev %p tx queues:\n", pdev); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + struct ol_txrx_peer_t *peer; + int i; + for (i = 0; i < ARRAY_LEN(vdev->txqs); i++) { + if (vdev->txqs[i].frms == 0) { + continue; + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " vdev %d (%p), txq %d\n", vdev->vdev_id, vdev, i); + ol_tx_queue_display(&vdev->txqs[i], 4); + } + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + if (peer->txqs[i].frms == 0) { + continue; + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " peer %d (%p), txq %d\n", + peer->peer_ids[0], vdev, i); + ol_tx_queue_display(&peer->txqs[i], 6); + } + } + } +} + +#endif + +#endif /* defined(CONFIG_HL_SUPPORT) */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.h new file mode 100644 index 0000000000000..94ec2e39b8210 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_queue.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx_queue.h + * @brief API definitions for the tx frame queue module within the data SW. + */ +#ifndef _OL_TX_QUEUE__H_ +#define _OL_TX_QUEUE__H_ + +#include /* adf_nbuf_t */ +#include /* ol_txrx_vdev_t, etc. */ +#include /* a_bool_t */ + +#if defined(CONFIG_HL_SUPPORT) + +/** + * @brief Queue a tx frame to the tid queue. + * + * @param pdev - the data virtual device sending the data + * (for storing the tx desc in the virtual dev's tx_target_list, + * and for accessing the phy dev) + * @param txq - which queue the tx frame gets stored in + * @param tx_desc - tx meta-data, including prev and next ptrs + * @param tx_msdu_info - characteristics of the tx frame + */ +void +ol_tx_enqueue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + struct ol_tx_desc_t *tx_desc, + struct ol_txrx_msdu_info_t *tx_msdu_info); + +/** + * @brief - remove the specified number of frames from the head of a tx queue + * @details + * This function removes frames from the head of a tx queue, + * and returns them as a NULL-terminated linked list. + * The function will remove frames until one of the following happens: + * 1. The tx queue is empty + * 2. The specified number of frames have been removed + * 3. Removal of more frames would exceed the specified credit limit + * + * @param pdev - the physical device object + * @param txq - which tx queue to remove frames from + * @param head - which contains return linked-list of tx frames (descriptors) + * @param num_frames - maximum number of frames to remove + * @param[in/out] credit - + * input: max credit the dequeued frames can consume + * output: how much credit the dequeued frames consume + * @param[out] bytes - the sum of the sizes of the dequeued frames + * @return number of frames dequeued +*/ +u_int16_t +ol_tx_dequeue( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + ol_tx_desc_list *head, + u_int16_t num_frames, + u_int32_t *credit, + int *bytes); + +/** + * @brief - free all of frames from the tx queue while deletion + * @details + * This function frees all of frames from the tx queue. + * This function is called during peer or vdev deletion. + * This function notifies the scheduler, so the scheduler can update + * its state to account for the absence of the queue. + * + * @param pdev - the physical device object, which stores the txqs + * @param txq - which tx queue to free frames from + * @param tid - the extended TID that the queue belongs to + */ +void +ol_tx_queue_free( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid); + +/** + * @brief - discard pending tx frames from the tx queue + * @details + * This function is called if there are too many queues in tx scheduler. + * This function is called if we wants to flush all pending tx + * queues in tx scheduler. + * + * @param pdev - the physical device object, which stores the txqs + * @param flush_all - flush all pending tx queues if set to true + * @param tx_descs - List Of tx_descs to be discarded will be returned by this function + */ + +void +ol_tx_queue_discard( + struct ol_txrx_pdev_t *pdev, + a_bool_t flush_all, + ol_tx_desc_list *tx_descs); + +#else + +#define ol_tx_enqueue(pdev, txq, tx_desc, tx_msdu_info) /* no-op */ +#define ol_tx_dequeue(pdev, ext_tid, txq, head, num_frames, credit, bytes) 0 +#define ol_tx_queue_free(pdev, txq, tid) /* no-op */ +#define ol_tx_queue_discard(pdev, flush, tx_descs) /* no-op */ + +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#if defined(CONFIG_HL_SUPPORT) && defined(ENABLE_TX_QUEUE_LOG) + +void +ol_tx_queue_log_sched( + struct ol_txrx_pdev_t *pdev, + int credit, + int *num_active_tids, + u_int32_t **active_bitmap, + u_int8_t **data); + +#define OL_TX_QUEUE_LOG_SCHED ol_tx_queue_log_sched + +#else + +#define OL_TX_QUEUE_LOG_SCHED(\ + pdev, credit, num_active_tids, active_bitmap, data) + +#endif /* defined(CONFIG_HL_SUPPORT) && defined(ENABLE_TX_QUEUE_LOG) */ + +#if defined(CONFIG_HL_SUPPORT) && TXRX_DEBUG_LEVEL > 5 +/** + * @brief - show current state of all tx queues + * @param pdev - the physical device object, which stores the txqs + */ +void +ol_tx_queues_display(struct ol_txrx_pdev_t *pdev); +#else +#define ol_tx_queues_display(pdev) /* no-op */ +#endif + +#define ol_tx_queue_decs_reinit(peer, peer_id) /* no-op */ + +#ifdef QCA_SUPPORT_TX_THROTTLE +/** + * @brief - initialize the throttle context + * @param pdev - the physical device object, which stores the txqs + */ +void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev); +#else +#define ol_tx_throttle_init(pdev) /*no op*/ +#endif +#endif /* _OL_TX_QUEUE__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.c new file mode 100644 index 0000000000000..c60b7ea4acb53 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.c @@ -0,0 +1,1411 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_nbuf_t, etc. */ +#include /* HTT_TX_EXT_TID_MGMT */ +#include /* htt_tx_desc_tid */ +#include /* ol_txrx_vdev_handle */ +#include /* ol_txrx_sync */ +#include /* TXRX_ASSERT1 */ +#include /* pdev stats, etc. */ +#include /* ol_tx_desc */ +#include /* ol_tx_send */ +#include /* OL_TX_SCHED, etc. */ +#include +#include +#include /* a_bool_t */ + +#ifndef DEBUG_SCHED_STAT +#define DEBUG_SCHED_STAT 0 +#endif + +#if defined(CONFIG_HL_SUPPORT) + +#if defined(ENABLE_TX_QUEUE_LOG) +static void +ol_tx_sched_log(struct ol_txrx_pdev_t *pdev); +#define OL_TX_SCHED_LOG ol_tx_sched_log +#else +#define OL_TX_SCHED_LOG(pdev) /* no-op */ +#endif /* defined(ENABLE_TX_QUEUE_LOG) */ + +#if DEBUG_HTT_CREDIT +#define OL_TX_DISPATCH_LOG_CREDIT() \ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, \ + " TX %d bytes\n", adf_nbuf_len(msdu)); \ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, \ + " Decrease credit %d - 1 = %d, len:%d.\n", \ + adf_os_atomic_read(&pdev->target_tx_credit), \ + adf_os_atomic_read(&pdev->target_tx_credit) -1, \ + adf_nbuf_len(msdu)); +#else +#define OL_TX_DISPATCH_LOG_CREDIT() +#endif + +/*--- generic definitions used by the scheduler framework for all algs ---*/ + +struct ol_tx_sched_ctx { + ol_tx_desc_list head; + int frms; +}; + +typedef TAILQ_HEAD(ol_tx_frms_queue_list_s, ol_tx_frms_queue_t) + ol_tx_frms_queue_list; + +#define OL_A_MAX(_x, _y) ((_x) > (_y) ? (_x) : (_y)) + +#define OL_A_MIN(_x, _y) ((_x) < (_y) ? (_x) : (_y)) + +/*--- scheduler algorithm selection ---*/ + +/*--- scheduler options --------------------------------------------------- + * 1. Round-robin scheduler: + * Select the TID that is at the head of the list of active TIDs. + * Select the head tx queue for this TID. + * Move the tx queue to the back of the list of tx queues for this TID. + * Move the TID to the back of the list of active TIDs. + * Send as many frames from the tx queue as credit allows. + * 2. Weighted-round-robin advanced scheduler: + * Keep an ordered list of which TID gets selected next. + * Use a weighted-round-robin scheme to determine when to promote a TID + * within this list. + * If a TID at the head of the list is inactive, leave it at the head, + * but check the next TIDs. + * If the credit available is less than the credit threshold for the + * next active TID, don't send anything, and leave the TID at the head + * of the list. + * After a TID is selected, move it to the back of the list. + * Select the head tx queue for this TID. + * Move the tx queue to the back of the list of tx queues for this TID. + * Send no more frames than the limit specified for the TID. + */ +#define OL_TX_SCHED_RR 1 +#define OL_TX_SCHED_WRR_ADV 2 + +#ifndef OL_TX_SCHED +//#define OL_TX_SCHED OL_TX_SCHED_RR +#define OL_TX_SCHED OL_TX_SCHED_WRR_ADV /* default */ +#endif + + +#if OL_TX_SCHED == OL_TX_SCHED_RR + +#define ol_tx_sched_rr_t ol_tx_sched_t + +#define OL_TX_SCHED_NUM_CATEGORIES (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES) + +#define ol_tx_sched_init ol_tx_sched_init_rr +#define ol_tx_sched_select_init(pdev) /* no-op */ +#define ol_tx_sched_select_batch ol_tx_sched_select_batch_rr +#define ol_tx_sched_txq_enqueue ol_tx_sched_txq_enqueue_rr +#define ol_tx_sched_txq_deactivate ol_tx_sched_txq_deactivate_rr +#define ol_tx_sched_category_tx_queues ol_tx_sched_category_tx_queues_rr +#define ol_tx_sched_txq_discard ol_tx_sched_txq_discard_rr +#define ol_tx_sched_category_info ol_tx_sched_category_info_rr +#define ol_tx_sched_discard_select_category \ + ol_tx_sched_discard_select_category_rr + +#elif OL_TX_SCHED == OL_TX_SCHED_WRR_ADV + +#define ol_tx_sched_wrr_adv_t ol_tx_sched_t + +#define OL_TX_SCHED_NUM_CATEGORIES OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES + +#define ol_tx_sched_init ol_tx_sched_init_wrr_adv +#define ol_tx_sched_select_init(pdev) \ + do { \ + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); \ + ol_tx_sched_select_init_wrr_adv(pdev); \ + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); \ + } while (0) +#define ol_tx_sched_select_batch ol_tx_sched_select_batch_wrr_adv +#define ol_tx_sched_txq_enqueue ol_tx_sched_txq_enqueue_wrr_adv +#define ol_tx_sched_txq_deactivate ol_tx_sched_txq_deactivate_wrr_adv +#define ol_tx_sched_category_tx_queues ol_tx_sched_category_tx_queues_wrr_adv +#define ol_tx_sched_txq_discard ol_tx_sched_txq_discard_wrr_adv +#define ol_tx_sched_category_info ol_tx_sched_category_info_wrr_adv +#define ol_tx_sched_discard_select_category \ + ol_tx_sched_discard_select_category_wrr_adv + +#else + +#error Unknown OL TX SCHED specification + +#endif /* OL_TX_SCHED */ + +/*--- round-robin scheduler -------------------------------------------------*/ +#if OL_TX_SCHED == OL_TX_SCHED_RR + +/*--- definitions ---*/ + +struct ol_tx_active_queues_in_tid_t { + /* list_elem is used to queue up into up level queues*/ + TAILQ_ENTRY(ol_tx_active_queues_in_tid_t) list_elem; + u_int32_t frms; + u_int32_t bytes; + ol_tx_frms_queue_list head; + bool active; + int tid; +}; + +typedef TAILQ_HEAD(ol_tx_active_tids_s, ol_tx_active_queues_in_tid_t) + ol_tx_active_tids_list; + +struct ol_tx_sched_rr_t { + struct ol_tx_active_queues_in_tid_t + tx_active_queues_in_tid_array[OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES]; + ol_tx_active_tids_list tx_active_tids_list; + u_int8_t discard_weights[OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES]; +}; + +#define TX_SCH_MAX_CREDIT_FOR_THIS_TID(tidq) 16 + +/*--- functions ---*/ + +/* + * The scheduler sync spinlock has been acquired outside this function, + * so there is no need to worry about mutex within this function. + */ +static int +ol_tx_sched_select_batch_rr( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_sched_ctx *sctx, + u_int32_t credit) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + struct ol_tx_frms_queue_t *next_tq; + u_int16_t frames, used_credits; + int bytes; + + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + + if (TAILQ_EMPTY(&scheduler->tx_active_tids_list)) return; + + txq_queue = TAILQ_FIRST(&scheduler->tx_active_tids_list); + + TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = FALSE; + + next_tq = TAILQ_FIRST(&txq_queue->head); + TAILQ_REMOVE(&txq_queue->head, next_tq, list_elem); + + credit = OL_A_MIN(credit, TX_SCH_MAX_CREDIT_FOR_THIS_TID(next_tq)); + frames = next_tq->frms; /* download as many frames as credit allows */ + frames = ol_tx_dequeue( + pdev, txq, &sctx->head, category->specs.send_limit, &credit, &bytes); + + used_credits = credit; + txq_queue->frms -= frames; + txq_queue->bytes -= bytes; + + if (next_tq->frms > 0) { + TAILQ_INSERT_TAIL(&txq_queue->head, next_tq, list_elem); + TAILQ_INSERT_TAIL( + &scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = TRUE; + } else if (!TAILQ_EMPTY(&txq_queue->head)) { + /* + * This tx queue is empty, but there's another tx queue for the + * same TID that is not empty. Thus, the TID as a whole is active. + */ + TAILQ_INSERT_TAIL( + &scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = TRUE; + } + sctx->frms += frames; + + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); + return used_credits; +} + +static inline void +ol_tx_sched_txq_enqueue_rr( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid, + int frms, + int bytes) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + + txq_queue = &scheduler->tx_active_queues_in_tid_array[tid]; + if (txq->flag != ol_tx_queue_active) + { + TAILQ_INSERT_TAIL(&txq_queue->head, txq, list_elem); + } + txq_queue->frms += frms; + txq_queue->bytes += bytes; + + if (!txq_queue->active) { + TAILQ_INSERT_TAIL( + &scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = TRUE; + } +} + +static inline void +ol_tx_sched_txq_deactivate_rr( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + + txq_queue = &scheduler->tx_active_queues_in_tid_array[tid]; + txq_queue->frms -= txq->frms; + txq_queue->bytes -= txq->bytes; + + TAILQ_REMOVE(&txq_queue->head, txq, list_elem); + //if (txq_queue->frms == 0 && txq_queue->active) { + if (TAILQ_EMPTY(&txq_queue->head) && txq_queue->active) { + TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = FALSE; + } +} + +ol_tx_frms_queue_list * +ol_tx_sched_category_tx_queues_rr(struct ol_txrx_pdev_t *pdev, int tid) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + + txq_queue = &scheduler->tx_active_queues_in_tid_array[tid]; + return &txq_queue->head; +} + +int +ol_tx_sched_discard_select_category_rr(struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_rr_t *scheduler; + u_int8_t i, tid = 0; + int max_score = 0; + + scheduler = pdev->tx_sched.scheduler; + /* + * Choose which TID's tx frames to drop next based on two factors: + * 1. Which TID has the most tx frames present + * 2. The TID's priority (high-priority TIDs have a low discard_weight) + */ + for (i = 0; i < (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES); i++) { + int score; + score = + scheduler->tx_active_queues_in_tid_array[i].frms * + scheduler->discard_weights[i]; + if (max_score == 0 || score > max_score) { + max_score = score; + tid = i; + } + } + return tid; +} + +void +ol_tx_sched_txq_discard_rr( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid, int frames, int bytes) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + + txq_queue = &scheduler->tx_active_queues_in_tid_array[tid]; + + if (0 == txq->frms) { + TAILQ_REMOVE(&txq_queue->head, txq, list_elem); + } + + txq_queue->frms -= frames; + txq_queue->bytes -= bytes; + if (txq_queue->active == TRUE && txq_queue->frms == 0) { + TAILQ_REMOVE(&scheduler->tx_active_tids_list, txq_queue, list_elem); + txq_queue->active = FALSE; + } +} + +void +ol_tx_sched_category_info_rr( + struct ol_txrx_pdev_t *pdev, int cat, int *active, int *frms, int *bytes) +{ + struct ol_tx_sched_rr_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_active_queues_in_tid_t *txq_queue; + + txq_queue = &scheduler->tx_active_queues_in_tid_array[cat]; + + *active = txq_queue->active; + *frms = txq_queue->frms; + *bytes = txq_queue->bytes; +} + +enum { + ol_tx_sched_discard_weight_voice = 1, + ol_tx_sched_discard_weight_video = 4, + ol_tx_sched_discard_weight_ucast_default = 8, + ol_tx_sched_discard_weight_mgmt_non_qos = 1, /* 0? */ + ol_tx_sched_discard_weight_mcast = 1, /* 0? also for probe & assoc */ +}; + +void * +ol_tx_sched_init_rr( + struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_rr_t *scheduler; + int i; + + scheduler = adf_os_mem_alloc(pdev->osdev, sizeof(struct ol_tx_sched_rr_t)); + if (scheduler == NULL) { + return scheduler; + } + + for (i = 0; i < (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES); i++) { + scheduler->tx_active_queues_in_tid_array[i].tid = i; + TAILQ_INIT(&scheduler->tx_active_queues_in_tid_array[i].head); + scheduler->tx_active_queues_in_tid_array[i].active = 0; + scheduler->tx_active_queues_in_tid_array[i].frms = 0; + scheduler->tx_active_queues_in_tid_array[i].bytes = 0; + } + for (i = 0; i < OL_TX_NUM_TIDS; i++) { + scheduler->tx_active_queues_in_tid_array[i].tid = i; + if (i < OL_TX_NON_QOS_TID) { + int ac = TXRX_TID_TO_WMM_AC(i); + switch (ac) { + case TXRX_WMM_AC_VO: + scheduler->discard_weights[i] = + ol_tx_sched_discard_weight_voice; + case TXRX_WMM_AC_VI: + scheduler->discard_weights[i] = + ol_tx_sched_discard_weight_video; + default: + scheduler->discard_weights[i] = + ol_tx_sched_discard_weight_ucast_default; + }; + } else { + scheduler->discard_weights[i] = + ol_tx_sched_discard_weight_mgmt_non_qos; + } + } + for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { + int j = i + OL_TX_NUM_TIDS; + scheduler->tx_active_queues_in_tid_array[j].tid = OL_TX_NUM_TIDS - 1; + scheduler->discard_weights[j] = ol_tx_sched_discard_weight_mcast; + } + TAILQ_INIT(&scheduler->tx_active_tids_list); + + return scheduler; +} + +void +ol_txrx_set_wmm_param(ol_txrx_pdev_handle data_pdev, struct ol_tx_wmm_param_t wmm_param) +{ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "Dummy function when OL_TX_SCHED_RR is enabled\n"); +} + +#endif /* OL_TX_SCHED == OL_TX_SCHED_RR */ + +/*--- advanced scheduler ----------------------------------------------------*/ +#if OL_TX_SCHED == OL_TX_SCHED_WRR_ADV + +/*--- definitions ---*/ + +enum { + OL_TX_SCHED_WRR_ADV_CAT_VO, + OL_TX_SCHED_WRR_ADV_CAT_VI, + OL_TX_SCHED_WRR_ADV_CAT_BK, + OL_TX_SCHED_WRR_ADV_CAT_BE, + OL_TX_SCHED_WRR_ADV_CAT_NON_QOS_DATA, + OL_TX_SCHED_WRR_ADV_CAT_UCAST_MGMT, + OL_TX_SCHED_WRR_ADV_CAT_MCAST_DATA, + OL_TX_SCHED_WRR_ADV_CAT_MCAST_MGMT, + + OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES /* must be last */ +}; + +struct ol_tx_sched_wrr_adv_category_info_t { + struct { + int wrr_skip_weight; + u_int32_t credit_threshold; + u_int16_t send_limit; + int credit_reserve; + int discard_weight; + } specs; + struct { + int wrr_count; + int frms; + int bytes; + ol_tx_frms_queue_list head; + bool active; + } state; +#if DEBUG_SCHED_STAT + struct + { + char *cat_name; + unsigned int queued; + unsigned int dispatched; + unsigned int discard; + } stat; +#endif +}; + +#define OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(cat, \ + wrr_skip_weight, \ + credit_threshold, \ + send_limit, \ + credit_reserve, \ + discard_weights) \ + enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _WRR_SKIP_WEIGHT = \ + (wrr_skip_weight) }; \ + enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _CREDIT_THRESHOLD = \ + (credit_threshold) }; \ + enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _SEND_LIMIT = \ + (send_limit) }; \ + enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _CREDIT_RESERVE = \ + (credit_reserve) }; \ + enum { OL_TX_SCHED_WRR_ADV_ ## cat ## _DISCARD_WEIGHT = \ + (discard_weights) } + +/* Rome: + * For high-volume traffic flows (VI, BE, BK), use a credit threshold + * roughly equal to a large A-MPDU (occupying half the target memory + * available for holding tx frames) to download AMPDU-sized batches + * of traffic. + * For high-priority, low-volume traffic flows (VO and mgmt), use no + * credit threshold, to minimize download latency. + */ +// WRR send +// skip credit limit credit disc +// wts thresh (frms) reserv wts +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VO, 1, 16, 24, 0, 1); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VI, 3, 16, 16, 1, 4); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BE, 10, 12, 12, 1, 8); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BK, 12, 6, 6, 1, 8); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(NON_QOS_DATA,12, 6, 4, 1, 8); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(UCAST_MGMT, 1, 1, 4, 0, 1); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_DATA, 10, 16, 4, 1, 4); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(MCAST_MGMT, 1, 1, 4, 0, 1); + + +#if DEBUG_SCHED_STAT + +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler) \ + do { \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category].stat.queued = 0; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category].stat.discard = 0; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category].stat.dispatched = 0; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category].stat.cat_name = #category; \ + } while (0) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms) \ + category->stat.queued += frms +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frms) \ + category->stat.discard += frms +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISPATCHED(category, frms) \ + category->stat.dispatched += frms +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler) \ + ol_tx_sched_wrr_adv_cat_stat_dump(scheduler) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_ROTATE_DBG(scheduler, index) \ + ol_tx_sched_wrr_adv_cat_stat_rotate_dbg(scheduler, index) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_IGNORE_EMPTY_QUEUE(scheduler) \ + do { \ + int i, empty = 1; \ + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i ++){ \ + if (scheduler->categories[i].state.frms != 0){ \ + empty = 0; \ + break; \ + } \ + } \ + if (empty){ \ + return 0; \ + } \ + } while (0) + +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_CURR_DBG(category_index, category) \ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, \ + "\t +++ cat[%d], " \ + "wrr:%d, frms:%d spec[resv:%d,cred:%d,wrr:%d]\n", \ + category_index, \ + category->state.wrr_count, \ + category->state.frms, \ + category->specs.credit_reserve, \ + category->specs.credit_threshold, \ + category->specs.wrr_skip_weight) + +#else /* DEBUG_SCHED_STAT */ + +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frms) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISPATCHED(category, frms) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_ROTATE_DBG(scheduler, index) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_IGNORE_EMPTY_QUEUE(scheduler) +#define OL_TX_SCHED_WRR_ADV_CAT_STAT_CURR_DBG(category_index, category) +#endif /* DEBUG_SCHED_STAT */ + +#define OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(category, scheduler) \ + do { \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \ + .specs.wrr_skip_weight = \ + OL_TX_SCHED_WRR_ADV_ ## category ## _WRR_SKIP_WEIGHT; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \ + .specs.credit_threshold = \ + OL_TX_SCHED_WRR_ADV_ ## category ## _CREDIT_THRESHOLD; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \ + .specs.send_limit = \ + OL_TX_SCHED_WRR_ADV_ ## category ## _SEND_LIMIT; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \ + .specs.credit_reserve = \ + OL_TX_SCHED_WRR_ADV_ ## category ## _CREDIT_RESERVE; \ + scheduler->categories[OL_TX_SCHED_WRR_ADV_CAT_ ## category] \ + .specs.discard_weight = \ + OL_TX_SCHED_WRR_ADV_ ## category ## _DISCARD_WEIGHT; \ + OL_TX_SCHED_WRR_ADV_CAT_STAT_INIT(category, scheduler); \ + } while (0) + +struct ol_tx_sched_wrr_adv_t { + int order[OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES]; + int index; + int tid_to_category[OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES]; + struct ol_tx_sched_wrr_adv_category_info_t + categories[OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES]; +}; + +#define OL_TX_AIFS_DEFAULT_VO 2 +#define OL_TX_AIFS_DEFAULT_VI 2 +#define OL_TX_AIFS_DEFAULT_BE 3 +#define OL_TX_AIFS_DEFAULT_BK 7 +#define OL_TX_CW_MIN_DEFAULT_VO 3 +#define OL_TX_CW_MIN_DEFAULT_VI 7 +#define OL_TX_CW_MIN_DEFAULT_BE 15 +#define OL_TX_CW_MIN_DEFAULT_BK 15 + +/*--- functions ---*/ + +#if DEBUG_SCHED_STAT +static void ol_tx_sched_wrr_adv_cat_stat_dump(struct ol_tx_sched_wrr_adv_t *scheduler) +{ + int i; + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "==== Queued Discard Dispatched frms wrr === \n"); + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; ++ i){ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%12s: %6d %7d %10d %4d %3d\n", + scheduler->categories[i].stat.cat_name, + scheduler->categories[i].stat.queued, + scheduler->categories[i].stat.discard, + scheduler->categories[i].stat.dispatched, + scheduler->categories[i].state.frms, + scheduler->categories[i].state.wrr_count); + } +} + +static void ol_tx_sched_wrr_adv_cat_stat_rotate_dbg(struct ol_tx_sched_wrr_adv_t *scheduler, int index) +{ + int i; + if (index < 0){ //less than 0 means just output order + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "order["); + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "rotate %d, order[", index); + } + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i ++){ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%d ", scheduler->order[i]); + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, "]\n"); +} +#endif + +static void +ol_tx_sched_select_init_wrr_adv(struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + /* start selection from the front of the ordered list */ + scheduler->index = 0; +} + +static void +ol_tx_sched_wrr_adv_rotate_order_list_tail( + struct ol_tx_sched_wrr_adv_t *scheduler, int idx) +{ + int value; + /* remember the value of the specified element */ + value = scheduler->order[idx]; + /* shift all further elements up one space */ + for (; idx < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES-1; idx++) { + scheduler->order[idx] = scheduler->order[idx + 1]; + } + /* put the specified element at the end */ + scheduler->order[idx] = value; + OL_TX_SCHED_WRR_ADV_CAT_STAT_ROTATE_DBG(scheduler, idx); +} + +static void +ol_tx_sched_wrr_adv_credit_sanity_check(struct ol_txrx_pdev_t *pdev, u_int32_t credit) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + int i; + int okay = 1; + + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) { + if (scheduler->categories[i].specs.credit_threshold > credit) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "*** Config error: credit (%d) not enough " + "to support category %d threshold (%d)\n", + credit, i, scheduler->categories[i].specs.credit_threshold); + okay = 0; + } + } + adf_os_assert(okay); +} + +/* + * The scheduler sync spinlock has been acquired outside this function, + * so there is no need to worry about mutex within this function. + */ +static int +ol_tx_sched_select_batch_wrr_adv( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_sched_ctx *sctx, + u_int32_t credit) +{ + static int first = 1; + int category_index = 0; + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_frms_queue_t *txq; + int index; + struct ol_tx_sched_wrr_adv_category_info_t *category = NULL; + int frames, bytes, used_credits; + /* + * the macro may end up the function if all tx_queue is empty + */ + OL_TX_SCHED_WRR_ADV_CAT_STAT_IGNORE_EMPTY_QUEUE(scheduler); + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + OL_TX_SCHED_WRR_ADV_CAT_STAT_ROTATE_DBG(scheduler, -1); + OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler); + /* + * Just for good measure, do a sanity check that the initial credit + * is enough to cover every category's credit threshold. + */ + if (first) { + first = 0; + ol_tx_sched_wrr_adv_credit_sanity_check(pdev, credit); + } + + /* choose the traffic category from the ordered list */ + index = scheduler->index; + while (index < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES) { + category_index = scheduler->order[index]; + category = &scheduler->categories[category_index]; + if (!category->state.active) { + /* move on to the next category */ + index++; + continue; + } + if (++category->state.wrr_count < category->specs.wrr_skip_weight) { + /* skip this cateogry (move it to the back) */ + ol_tx_sched_wrr_adv_rotate_order_list_tail(scheduler, index); + /* try again (iterate) on the new element that was moved up */ + continue; + } + /* found the first active category whose WRR turn is present */ + break; + } + if (index >= OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES) { + /* no categories are active */ + return 0; + } + OL_TX_SCHED_WRR_ADV_CAT_STAT_CURR_DBG(category_index, category); + /* is there enough credit for the selected category? */ + if (credit < category->specs.credit_threshold) { + /* + * Can't send yet - wait until more credit becomes available. + * In the meantime, restore the WRR counter (since we didn't + * service this category after all). + */ + category->state.wrr_count = category->state.wrr_count - 1; + return 0; + } + /* enough credit is available - go ahead and send some frames */ + /* + * This category was serviced - reset the WRR counter, and move this + * category to the back of the order list. + */ + category->state.wrr_count = 0; + ol_tx_sched_wrr_adv_rotate_order_list_tail(scheduler, index); + /* + * With this category moved to the back, if there's still any credit + * left, set up the next invocation of this function to start from + * where this one left off, by looking at the category that just got + * shifted forward into the position the service category was + * occupying. + */ + scheduler->index = index; + + /* + * Take the tx queue from the head of the category list. + */ + txq = TAILQ_FIRST(&category->state.head); + if (txq){ + TAILQ_REMOVE(&category->state.head, txq, list_elem); + credit -= category->specs.credit_reserve; + frames = ol_tx_dequeue( + pdev, txq, &sctx->head, category->specs.send_limit, &credit, &bytes); + used_credits = credit; + category->state.frms -= frames; + category->state.bytes -= bytes; + if (txq->frms > 0) { + TAILQ_INSERT_TAIL(&category->state.head, txq, list_elem); + } else { + if (category->state.frms == 0) { + category->state.active = 0; + } + } + sctx->frms += frames; + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); + } else { + used_credits = 0; + /* TODO: find its reason */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "ol_tx_sched_select_batch_wrr_adv: error, no TXQ can be popped."); + } + OL_TX_SCHED_WRR_ADV_CAT_STAT_DUMP(scheduler); + return used_credits; +} + +static inline void +ol_tx_sched_txq_enqueue_wrr_adv( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid, + int frms, + int bytes) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_sched_wrr_adv_category_info_t *category; + + category = &scheduler->categories[scheduler->tid_to_category[tid]]; + category->state.frms += frms; + category->state.bytes += bytes; + OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_QUEUED(category, frms); + if (txq->flag != ol_tx_queue_active) + { + TAILQ_INSERT_TAIL(&category->state.head, txq, list_elem); + category->state.active = 1; /* may have already been active */ + } +} + +static inline void +ol_tx_sched_txq_deactivate_wrr_adv( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int tid) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_sched_wrr_adv_category_info_t *category; + + category = &scheduler->categories[scheduler->tid_to_category[tid]]; + category->state.frms -= txq->frms; + category->state.bytes -= txq->bytes; + + TAILQ_REMOVE(&category->state.head, txq, list_elem); + + if (category->state.frms == 0 && category->state.active) { + category->state.active = 0; + } +} + +ol_tx_frms_queue_list * +ol_tx_sched_category_tx_queues_wrr_adv(struct ol_txrx_pdev_t *pdev, int cat) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_sched_wrr_adv_category_info_t *category; + + category = &scheduler->categories[cat]; + return &category->state.head; +} + +int +ol_tx_sched_discard_select_category_wrr_adv(struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_wrr_adv_t *scheduler; + u_int8_t i, cat = 0; + int max_score = 0; + + scheduler = pdev->tx_sched.scheduler; + /* + * Choose which category's tx frames to drop next based on two factors: + * 1. Which category has the most tx frames present + * 2. The category's priority (high-priority categories have a low + * discard_weight) + */ + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) { + int score; + score = + scheduler->categories[i].state.frms * + scheduler->categories[i].specs.discard_weight; + if (max_score == 0 || score > max_score) { + max_score = score; + cat = i; + } + } + return cat; +} + +void +ol_tx_sched_txq_discard_wrr_adv( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_frms_queue_t *txq, + int cat, int frames, int bytes) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_sched_wrr_adv_category_info_t *category; + + category = &scheduler->categories[cat]; + + if (0 == txq->frms) { + TAILQ_REMOVE(&category->state.head, txq, list_elem); + } + + category->state.frms -= frames; + category->state.bytes -= bytes; + OL_TX_SCHED_WRR_ADV_CAT_STAT_INC_DISCARD(category, frames); + if (category->state.frms == 0) { + category->state.active = 0; + } +} + +void +ol_tx_sched_category_info_wrr_adv( + struct ol_txrx_pdev_t *pdev, int cat, int *active, int *frms, int *bytes) +{ + struct ol_tx_sched_wrr_adv_t *scheduler = pdev->tx_sched.scheduler; + struct ol_tx_sched_wrr_adv_category_info_t *category; + + category = &scheduler->categories[cat]; + *active = category->state.active; + *frms = category->state.frms; + *bytes = category->state.bytes; +} + +void * +ol_tx_sched_init_wrr_adv( + struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_wrr_adv_t *scheduler; + int i, tid; + + scheduler = adf_os_mem_alloc( + pdev->osdev, sizeof(struct ol_tx_sched_wrr_adv_t)); + if (scheduler == NULL) { + return scheduler; + } + adf_os_mem_zero(scheduler, sizeof(*scheduler)); + + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VO, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VI, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BE, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BK, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(NON_QOS_DATA, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(UCAST_MGMT, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(MCAST_DATA, scheduler); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(MCAST_MGMT, scheduler); + + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) { + scheduler->categories[i].state.active = 0; + scheduler->categories[i].state.frms = 0; + //scheduler->categories[i].state.bytes = 0; + TAILQ_INIT(&scheduler->categories[i].state.head); + /* init categories to not be skipped before their initial selection */ + scheduler->categories[i].state.wrr_count = + scheduler->categories[i].specs.wrr_skip_weight - 1; + } + + /* + * Init the tid --> category table. + * Regular tids (0-15) map to their AC. + * Extension tids get their own categories. + */ + for (tid = 0; tid < OL_TX_NUM_QOS_TIDS; tid++) { + int ac = TXRX_TID_TO_WMM_AC(tid); + scheduler->tid_to_category[tid] = ac; + } + scheduler->tid_to_category[OL_TX_NON_QOS_TID] = + OL_TX_SCHED_WRR_ADV_CAT_NON_QOS_DATA; + scheduler->tid_to_category[OL_TX_MGMT_TID] = + OL_TX_SCHED_WRR_ADV_CAT_UCAST_MGMT; + scheduler->tid_to_category[OL_TX_NUM_TIDS + OL_TX_VDEV_MCAST_BCAST] = + OL_TX_SCHED_WRR_ADV_CAT_MCAST_DATA; + scheduler->tid_to_category[OL_TX_NUM_TIDS + OL_TX_VDEV_DEFAULT_MGMT] = + OL_TX_SCHED_WRR_ADV_CAT_MCAST_MGMT; + + /* + * Init the order array - the initial ordering doesn't matter, as the + * order array will get reshuffled as data arrives. + */ + for (i = 0; i < OL_TX_SCHED_WRR_ADV_NUM_CATEGORIES; i++) { + scheduler->order[i] = i; + } + + return scheduler; +} + + +/* WMM parameters are suppposed to be passed when associate with AP. + * According to AIFS+CWMin, the function maps each queue to one of four default + * settings of the scheduler, ie. VO, VI, BE, or BK. + */ +void +ol_txrx_set_wmm_param(ol_txrx_pdev_handle data_pdev, struct ol_tx_wmm_param_t wmm_param) +{ + struct ol_tx_sched_wrr_adv_t def_cfg; + struct ol_tx_sched_wrr_adv_t *scheduler = data_pdev->tx_sched.scheduler; + u_int32_t i, ac_selected, weight[OL_TX_NUM_WMM_AC], default_edca[OL_TX_NUM_WMM_AC]; + + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VO, (&def_cfg)); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(VI, (&def_cfg)); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BE, (&def_cfg)); + OL_TX_SCHED_WRR_ADV_CAT_CFG_STORE(BK, (&def_cfg)); + + // default_eca = AIFS + CWMin + default_edca[OL_TX_SCHED_WRR_ADV_CAT_VO] = + OL_TX_AIFS_DEFAULT_VO + OL_TX_CW_MIN_DEFAULT_VO; + default_edca[OL_TX_SCHED_WRR_ADV_CAT_VI] = + OL_TX_AIFS_DEFAULT_VI + OL_TX_CW_MIN_DEFAULT_VI; + default_edca[OL_TX_SCHED_WRR_ADV_CAT_BE] = + OL_TX_AIFS_DEFAULT_BE + OL_TX_CW_MIN_DEFAULT_BE; + default_edca[OL_TX_SCHED_WRR_ADV_CAT_BK] = + OL_TX_AIFS_DEFAULT_BK + OL_TX_CW_MIN_DEFAULT_BK; + + weight[OL_TX_SCHED_WRR_ADV_CAT_VO] = + wmm_param.ac[OL_TX_WMM_AC_VO].aifs + wmm_param.ac[OL_TX_WMM_AC_VO].cwmin; + weight[OL_TX_SCHED_WRR_ADV_CAT_VI] = + wmm_param.ac[OL_TX_WMM_AC_VI].aifs + wmm_param.ac[OL_TX_WMM_AC_VI].cwmin; + weight[OL_TX_SCHED_WRR_ADV_CAT_BK] = + wmm_param.ac[OL_TX_WMM_AC_BK].aifs + wmm_param.ac[OL_TX_WMM_AC_BK].cwmin; + weight[OL_TX_SCHED_WRR_ADV_CAT_BE] = + wmm_param.ac[OL_TX_WMM_AC_BE].aifs + wmm_param.ac[OL_TX_WMM_AC_BE].cwmin; + + for (i = 0; i < OL_TX_NUM_WMM_AC; i++) { + + if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_VO] >= weight[i]) { + ac_selected = OL_TX_SCHED_WRR_ADV_CAT_VO; + } else if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_VI] >= weight[i]) { + ac_selected = OL_TX_SCHED_WRR_ADV_CAT_VI; + } else if (default_edca[OL_TX_SCHED_WRR_ADV_CAT_BE] >= weight[i]) { + ac_selected = OL_TX_SCHED_WRR_ADV_CAT_BE; + } else { + ac_selected = OL_TX_SCHED_WRR_ADV_CAT_BK; + } + + scheduler->categories[i].specs.wrr_skip_weight = + def_cfg.categories[ac_selected].specs.wrr_skip_weight; + scheduler->categories[i].specs.credit_threshold = + def_cfg.categories[ac_selected].specs.credit_threshold; + scheduler->categories[i].specs.send_limit = + def_cfg.categories[ac_selected].specs.send_limit; + scheduler->categories[i].specs.credit_reserve = + def_cfg.categories[ac_selected].specs.credit_reserve; + scheduler->categories[i].specs.discard_weight = + def_cfg.categories[ac_selected].specs.discard_weight; + } +} + +#endif /* OL_TX_SCHED == OL_TX_SCHED_WRR_ADV */ + +/*--- congestion control discard --------------------------------------------*/ + +struct ol_tx_frms_queue_t * +ol_tx_sched_discard_select_txq( + struct ol_txrx_pdev_t *pdev, + ol_tx_frms_queue_list *tx_queues) +{ + struct ol_tx_frms_queue_t *txq; + struct ol_tx_frms_queue_t *selected_txq = NULL; + int max_frms = 0; + + /* return the tx queue with the most frames */ + TAILQ_FOREACH(txq, tx_queues, list_elem) { + if (txq->frms > max_frms) { + max_frms = txq->frms; + selected_txq = txq; + } + } + return selected_txq; +} + +u_int16_t +ol_tx_sched_discard_select( + struct ol_txrx_pdev_t *pdev, + u_int16_t frms, + ol_tx_desc_list *tx_descs, + a_bool_t force) +{ + int cat; + struct ol_tx_frms_queue_t *txq; + int bytes; + u_int32_t credit; + struct ol_tx_sched_notify_ctx_t notify_ctx; + + /* first decide what category of traffic (e.g. TID or AC) to discard next */ + cat = ol_tx_sched_discard_select_category(pdev); + + /* then decide which peer within this category to discard from next */ + txq = ol_tx_sched_discard_select_txq( + pdev, ol_tx_sched_category_tx_queues(pdev, cat)); + if (NULL == txq) + { + /* No More pending Tx Packets in Tx Queue. Exit Discard loop */ + return 0; + } + + if (force == A_FALSE) { + /* + * Now decide how many frames to discard from this peer-TID. + * Don't discard more frames than the caller has specified. + * Don't discard more than a fixed quantum of frames at a time. + * Don't discard more than 50% of the queue's frames at a time, + * but if there's only 1 frame left, go ahead and discard it. + */ + #define OL_TX_DISCARD_QUANTUM 10 + if (OL_TX_DISCARD_QUANTUM < frms) { + frms = OL_TX_DISCARD_QUANTUM; + } + + if (txq->frms > 1 && frms >= (txq->frms >> 1)) { + frms = txq->frms >> 1; + } + } + + /* + * Discard from the head of the queue, because: + * 1. Front-dropping gives applications like TCP that include ARQ + * an early notification of congestion. + * 2. For time-sensitive applications like RTP, the newest frames are + * most relevant. + */ + credit = 10000; /* no credit limit */ + frms = ol_tx_dequeue(pdev, txq, tx_descs, frms, &credit, &bytes); + + notify_ctx.event = OL_TX_DISCARD_FRAMES; + notify_ctx.frames = frms; + notify_ctx.bytes = bytes; + notify_ctx.txq = txq; + notify_ctx.info.ext_tid = cat; + ol_tx_sched_notify(pdev, ¬ify_ctx); + + TX_SCHED_DEBUG_PRINT("%s Tx Drop : %d\n",__func__,frms); + return frms; +} + +/*--- scheduler framework ---------------------------------------------------*/ + +/* + * The scheduler mutex spinlock has been acquired outside this function, + * so there is need to take locks inside this function. + */ +void +ol_tx_sched_notify( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_sched_notify_ctx_t *ctx) +{ + struct ol_tx_frms_queue_t *txq = ctx->txq; + int tid; + + if (!pdev->tx_sched.scheduler) { + return; + } + + switch (ctx->event) { + case OL_TX_ENQUEUE_FRAME: + tid = ctx->info.tx_msdu_info->htt.info.ext_tid; + ol_tx_sched_txq_enqueue(pdev, txq, tid, 1, ctx->bytes); + break; + case OL_TX_DELETE_QUEUE: + tid = ctx->info.ext_tid; + if (txq->flag == ol_tx_queue_active) { + ol_tx_sched_txq_deactivate(pdev, txq, tid); + } + break; + case OL_TX_PAUSE_QUEUE: + tid = ctx->info.ext_tid; + if (txq->flag == ol_tx_queue_active) { + ol_tx_sched_txq_deactivate(pdev, txq, tid); + } + break; + case OL_TX_UNPAUSE_QUEUE: + tid = ctx->info.ext_tid; + if (txq->frms != 0) { + ol_tx_sched_txq_enqueue(pdev, txq, tid, txq->frms, txq->bytes); + } + break; + case OL_TX_DISCARD_FRAMES: + tid = ctx->info.ext_tid; /* not necessarily TID, could be category */ + ol_tx_sched_txq_discard(pdev, txq, tid, ctx->frames, ctx->bytes); + break; + default: + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Error: unknown sched notification (%d)\n", ctx->event); + adf_os_assert(0); + break; + } +} + +#define OL_TX_MSDU_ID_STORAGE_ERR(ptr) (NULL == ptr) + +void +ol_tx_sched_dispatch( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_sched_ctx *sctx) +{ + adf_nbuf_t msdu, prev = NULL, head_msdu = NULL; + struct ol_tx_desc_t *tx_desc; + + u_int16_t *msdu_id_storage; + u_int16_t msdu_id; + int num_msdus = 0; + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + while (sctx->frms) + { + tx_desc = TAILQ_FIRST(&sctx->head); + if (tx_desc == NULL){ + /* TODO: find its reason */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "%s: err, no enough tx_desc from stx->head.\n", __func__); + break; + } + msdu = tx_desc->netbuf; + TAILQ_REMOVE(&sctx->head, tx_desc, tx_desc_list_elem); + if (NULL == head_msdu) + { + head_msdu = msdu; + } + if (prev) + { + adf_nbuf_set_next(prev, msdu); + } + prev = msdu; + +#ifndef ATH_11AC_TXCOMPACT + /* + * When the tx frame is downloaded to the target, there are two + * outstanding references: + * 1. The host download SW (HTT, HTC, HIF) + * This reference is cleared by the ol_tx_send_done callback + * functions. + * 2. The target FW + * This reference is cleared by the ol_tx_completion_handler + * function. + * It is extremely probable that the download completion is processed + * before the tx completion message. However, under exceptional + * conditions the tx completion may be processed first. Thus, rather + * that assuming that reference (1) is done before reference (2), + * explicit reference tracking is needed. + * Double-increment the ref count to account for both references + * described above. + */ + adf_os_atomic_init(&tx_desc->ref_cnt); + adf_os_atomic_inc(&tx_desc->ref_cnt); + adf_os_atomic_inc(&tx_desc->ref_cnt); +#endif + + //Store the MSDU Id for each MSDU + /* store MSDU ID */ + msdu_id = ol_tx_desc_id(pdev, tx_desc); + msdu_id_storage = ol_tx_msdu_id_storage(msdu); + if (OL_TX_MSDU_ID_STORAGE_ERR(msdu_id_storage)) { + /* + * Send the prior frames as a batch, then send this as a single, + * then resume handling the remaining frames. + */ + if (head_msdu){ + ol_tx_send_batch(pdev, head_msdu, num_msdus); + } + head_msdu = prev = NULL; + num_msdus = 0; + + if (htt_tx_send_std(pdev->htt_pdev, msdu, msdu_id)) { + OL_TX_TARGET_CREDIT_INCR(pdev, msdu); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* error */); + } + } else { + *msdu_id_storage = msdu_id; + num_msdus++; + } + sctx->frms--; + } + + //Send Batch Of Frames + if (head_msdu) + { + ol_tx_send_batch(pdev,head_msdu,num_msdus); + } + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +void +ol_tx_sched(struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_sched_ctx sctx; + u_int32_t credit; + + TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + if (pdev->tx_sched.tx_sched_status != ol_tx_scheduler_idle) { + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + return; + } + pdev->tx_sched.tx_sched_status = ol_tx_scheduler_running; + + OL_TX_SCHED_LOG(pdev); + //adf_os_print("BEFORE tx sched:\n"); + //ol_tx_queues_display(pdev); + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + + TAILQ_INIT(&sctx.head); + sctx.frms = 0; + + ol_tx_sched_select_init(pdev); + while (adf_os_atomic_read(&pdev->target_tx_credit) > 0) { + int num_credits; + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + credit = adf_os_atomic_read(&pdev->target_tx_credit); + num_credits = ol_tx_sched_select_batch(pdev, &sctx, credit); + if (num_credits > 0){ +#if DEBUG_HTT_CREDIT + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " Decrease credit %d - %d = %d.\n", + adf_os_atomic_read(&pdev->target_tx_credit), + num_credits, + adf_os_atomic_read(&pdev->target_tx_credit) - num_credits); +#endif + adf_os_atomic_add(-num_credits, &pdev->target_tx_credit); + } + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + + if (num_credits == 0) break; + } + ol_tx_sched_dispatch(pdev, &sctx); + + adf_os_spin_lock_bh(&pdev->tx_queue_spinlock); + //adf_os_print("AFTER tx sched:\n"); + //ol_tx_queues_display(pdev); + + pdev->tx_sched.tx_sched_status = ol_tx_scheduler_idle; + adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock); + TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); +} + +void * +ol_tx_sched_attach( + struct ol_txrx_pdev_t *pdev) +{ + pdev->tx_sched.tx_sched_status = ol_tx_scheduler_idle; + return ol_tx_sched_init(pdev); +} + +void +ol_tx_sched_detach( + struct ol_txrx_pdev_t *pdev) +{ + if (pdev->tx_sched.scheduler) { + adf_os_mem_free(pdev->tx_sched.scheduler); + pdev->tx_sched.scheduler = NULL; + } +} + +/*--- debug functions -------------------------------------------------------*/ + +#if defined(ENABLE_TX_QUEUE_LOG) + +static void +ol_tx_sched_log(struct ol_txrx_pdev_t *pdev) +{ + u_int8_t *buf; + u_int32_t *active_bitmap; + int i, j, num_cats_active; + int active, frms, bytes; + int credit; + + /* don't bother recording state if credit is zero */ + credit = adf_os_atomic_read(&pdev->target_tx_credit); + if (credit == 0) { + return; + } + + /* + * See how many TIDs are active, so queue state can be stored only + * for those TIDs. + * Do an initial iteration through all categories to see if any + * are active. Doing an extra iteration is inefficient, but + * efficiency is not a dominant concern when logging is enabled. + */ + num_cats_active = 0; + for (i = 0; i < OL_TX_SCHED_NUM_CATEGORIES; i++) { + ol_tx_sched_category_info(pdev, i, &active, &frms, &bytes); + if (active) { + num_cats_active++; + } + } + /* don't bother recording state if there are no active queues */ + if (num_cats_active == 0) { + return; + } + + OL_TX_QUEUE_LOG_SCHED(pdev, credit, &num_cats_active, &active_bitmap, &buf); + + if (num_cats_active == 0) { + return; + } + *active_bitmap = 0; + for (i = 0, j = 0; + i < OL_TX_SCHED_NUM_CATEGORIES && j < num_cats_active; + i++) + { + u_int8_t *p; + ol_tx_sched_category_info(pdev, i, &active, &frms, &bytes); + if (!active) { + continue; + } + p = &buf[j*6]; + p[0] = (frms >> 0) & 0xff; + p[1] = (frms >> 8) & 0xff; + + p[2] = (bytes >> 0) & 0xff; + p[3] = (bytes >> 8) & 0xff; + p[4] = (bytes >> 16) & 0xff; + p[5] = (bytes >> 24) & 0xff; + j++; + *active_bitmap |= 1 << i; + } +} + +#endif /* defined(ENABLE_TX_QUEUE_LOG) */ + +#endif /* defined(CONFIG_HL_SUPPORT) */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.h new file mode 100644 index 0000000000000..b01acf9965c87 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_sched.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx_sched.h + * @brief API definitions for the tx scheduler module within the data SW. + */ +#ifndef _OL_TX_SCHED__H_ +#define _OL_TX_SCHED__H_ + +#include /* a_bool_t */ + +enum ol_tx_queue_action { + OL_TX_ENQUEUE_FRAME, + OL_TX_DELETE_QUEUE, + OL_TX_PAUSE_QUEUE, + OL_TX_UNPAUSE_QUEUE, + OL_TX_DISCARD_FRAMES, +}; + +struct ol_tx_sched_notify_ctx_t { + int event; + struct ol_tx_frms_queue_t *txq; + union { + int ext_tid; + struct ol_txrx_msdu_info_t *tx_msdu_info; + } info; + int frames; + int bytes; +}; + +#if defined(CONFIG_HL_SUPPORT) + +void +ol_tx_sched_notify( + struct ol_txrx_pdev_t *pdev, struct ol_tx_sched_notify_ctx_t *ctx); + +void +ol_tx_sched(struct ol_txrx_pdev_t *pdev); + +u_int16_t +ol_tx_sched_discard_select( + struct ol_txrx_pdev_t *pdev, + u_int16_t frms, + ol_tx_desc_list *tx_descs, + a_bool_t force); + +void * +ol_tx_sched_attach(struct ol_txrx_pdev_t *pdev); + +void +ol_tx_sched_detach(struct ol_txrx_pdev_t *pdev); + +#else + +#define ol_tx_notify_sched(pdev, ctx) /* no-op */ +#define ol_tx_sched(pdev) /* no-op */ +#define ol_tx_sched_discard_select(pdev, frms, tx_descs, force) 0 +#define ol_tx_sched_attach(pdev) NULL +#define ol_tx_sched_detach(pdev) /* no-op */ + +#endif /* defined(CONFIG_HL_SUPPORT) */ + + +#if defined(CONFIG_HL_SUPPORT) || defined(TX_CREDIT_RECLAIM_SUPPORT) +/* + * HL needs to keep track of the amount of credit available to download + * tx frames to the target - the download scheduler decides when to + * download frames, and which frames to download, based on the credit + * availability. + * LL systems that use TX_CREDIT_RECLAIM_SUPPORT also need to keep track + * of the target_tx_credit, to determine when to poll for tx completion + * messages. + */ +#define OL_TX_TARGET_CREDIT_ADJUST(factor, pdev, msdu) \ + adf_os_atomic_add( \ + factor * htt_tx_msdu_credit(msdu), &pdev->target_tx_credit) +#define OL_TX_TARGET_CREDIT_DECR(pdev, msdu) \ + OL_TX_TARGET_CREDIT_ADJUST(-1, pdev, msdu) +#define OL_TX_TARGET_CREDIT_INCR(pdev, msdu) \ + OL_TX_TARGET_CREDIT_ADJUST(1, pdev, msdu) +#else +/* + * LL does not need to keep track of target credit. + * Since the host tx descriptor pool size matches the target's, + * we know the target has space for the new tx frame if the host's + * tx descriptor allocation succeeded. + */ +#define OL_TX_TARGET_CREDIT_DECR(pdev, msdu) /* no-op */ +#define OL_TX_TARGET_CREDIT_INCR(pdev, msdu) /* no-op */ +#define OL_TX_TARGET_CREDIT_ADJUST(factor, pdev, msdu) /* no-op */ + +#endif + +#endif /* _OL_TX_SCHED__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c new file mode 100644 index 0000000000000..6fd4792a91ce2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -0,0 +1,982 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* adf_os_atomic_inc, etc. */ +#include /* adf_os_spinlock */ +#include /* adf_os_ticks, etc. */ +#include /* adf_nbuf_t */ +#include /* ADF_NBUF_TX_EXT_TID_INVALID */ + +#include /* TAILQ */ +#ifdef QCA_COMPUTE_TX_DELAY +#include /* ieee80211_frame, etc. */ +#include /* ethernet_hdr_t, etc. */ +#include /* IPV6_TRAFFIC_CLASS */ +#endif + +#include /* ol_txrx_vdev_handle, etc. */ +#include /* htt_tx_compl_desc_id */ +#include /* htt_tx_status */ + +#include +#include /* ol_txrx_vdev_t, etc */ +#include /* ol_tx_desc_find, ol_tx_desc_frame_free */ +#ifdef QCA_COMPUTE_TX_DELAY +#include /* ol_tx_dest_addr_find */ +#endif +#include /* OL_TX_DESC_NO_REFS, etc. */ +#include +#include /* ol_tx_reinject */ + +#include /* ol_cfg_is_high_latency */ +#include +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP +#include /* OL_TX_RESTORE_HDR, etc*/ +#endif + +#ifdef TX_CREDIT_RECLAIM_SUPPORT + +#define OL_TX_CREDIT_RECLAIM(pdev) \ + do { \ + if (adf_os_atomic_read(&pdev->target_tx_credit) < \ + ol_cfg_tx_credit_lwm(pdev->ctrl_pdev)) { \ + ol_osif_ath_tasklet(pdev->osdev); \ + } \ + } while (0) + +#else + +#define OL_TX_CREDIT_RECLAIM(pdev) + +#endif /* TX_CREDIT_RECLAIM_SUPPORT */ + +#if defined(CONFIG_HL_SUPPORT) || defined(TX_CREDIT_RECLAIM_SUPPORT) +/* + * HL needs to keep track of the amount of credit available to download + * tx frames to the target - the download scheduler decides when to + * download frames, and which frames to download, based on the credit + * availability. + * LL systems that use TX_CREDIT_RECLAIM_SUPPORT also need to keep track + * of the target_tx_credit, to determine when to poll for tx completion + * messages. + */ +#define OL_TX_TARGET_CREDIT_ADJUST(factor, pdev, msdu) \ + adf_os_atomic_add( \ + factor * htt_tx_msdu_credit(msdu), &pdev->target_tx_credit) +#define OL_TX_TARGET_CREDIT_DECR(pdev, msdu) \ + OL_TX_TARGET_CREDIT_ADJUST(-1, pdev, msdu) +#define OL_TX_TARGET_CREDIT_INCR(pdev, msdu) \ + OL_TX_TARGET_CREDIT_ADJUST(1, pdev, msdu) +#define OL_TX_TARGET_CREDIT_DECR_INT(pdev, delta) \ + adf_os_atomic_add(-1 * delta, &pdev->target_tx_credit) +#define OL_TX_TARGET_CREDIT_INCR_INT(pdev, delta) \ + adf_os_atomic_add(delta, &pdev->target_tx_credit) +#else +/* + * LL does not need to keep track of target credit. + * Since the host tx descriptor pool size matches the target's, + * we know the target has space for the new tx frame if the host's + * tx descriptor allocation succeeded. + */ +#define OL_TX_TARGET_CREDIT_ADJUST(factor, pdev, msdu) /* no-op */ +#define OL_TX_TARGET_CREDIT_DECR(pdev, msdu) /* no-op */ +#define OL_TX_TARGET_CREDIT_INCR(pdev, msdu) /* no-op */ +#define OL_TX_TARGET_CREDIT_DECR_INT(pdev, delta) /* no-op */ +#define OL_TX_TARGET_CREDIT_INCR_INT(pdev, delta) /* no-op */ +#endif + +#ifdef QCA_LL_TX_FLOW_CT +#define OL_TX_FLOW_CT_UNPAUSE_OS_Q(pdev) \ +do { \ + struct ol_txrx_vdev_t *vdev; \ + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { \ + if (adf_os_atomic_read(&vdev->os_q_paused) && \ + (vdev->tx_fl_hwm != 0)) { \ + adf_os_spin_lock(&pdev->tx_mutex); \ + if (pdev->tx_desc.num_free > vdev->tx_fl_hwm) { \ + adf_os_atomic_set(&vdev->os_q_paused, 0); \ + adf_os_spin_unlock(&pdev->tx_mutex); \ + vdev->osif_flow_control_cb(vdev->osif_dev, \ + vdev->vdev_id, A_TRUE); \ + } \ + else { \ + adf_os_spin_unlock(&pdev->tx_mutex); \ + } \ + } \ + } \ +} while(0) +#else +#define OL_TX_FLOW_CT_UNPAUSE_OS_Q(pdev) +#endif /* QCA_LL_TX_FLOW_CT */ + + +static inline u_int16_t +ol_tx_send_base( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu) +{ + int msdu_credit_consumed; + + TX_CREDIT_DEBUG_PRINT("TX %d bytes\n", adf_nbuf_len(msdu)); + TX_CREDIT_DEBUG_PRINT(" Decrease credit %d - 1 = %d, len:%d.\n", + adf_os_atomic_read(&pdev->target_tx_credit), + adf_os_atomic_read(&pdev->target_tx_credit) - 1, + adf_nbuf_len(msdu)); + + msdu_credit_consumed = htt_tx_msdu_credit(msdu); + OL_TX_TARGET_CREDIT_DECR_INT(pdev, msdu_credit_consumed); + OL_TX_CREDIT_RECLAIM(pdev); + + /* + * When the tx frame is downloaded to the target, there are two + * outstanding references: + * 1. The host download SW (HTT, HTC, HIF) + * This reference is cleared by the ol_tx_send_done callback + * functions. + * 2. The target FW + * This reference is cleared by the ol_tx_completion_handler + * function. + * It is extremely probable that the download completion is processed + * before the tx completion message. However, under exceptional + * conditions the tx completion may be processed first. Thus, rather + * that assuming that reference (1) is done before reference (2), + * explicit reference tracking is needed. + * Double-increment the ref count to account for both references + * described above. + */ + + OL_TX_DESC_REF_INIT(tx_desc); + OL_TX_DESC_REF_INC(tx_desc); + OL_TX_DESC_REF_INC(tx_desc); + + return msdu_credit_consumed; +} + +void +ol_tx_send( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu) +{ + int msdu_credit_consumed; + u_int16_t id; + int failed; + + msdu_credit_consumed = ol_tx_send_base(pdev, tx_desc, msdu); + id = ol_tx_desc_id(pdev, tx_desc); + failed = htt_tx_send_std(pdev->htt_pdev, msdu, id); + if (adf_os_unlikely(failed)) { + OL_TX_TARGET_CREDIT_INCR_INT(pdev, msdu_credit_consumed); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */); + } +} + +void +ol_tx_send_batch( + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t head_msdu, int num_msdus) +{ + adf_nbuf_t rejected; + OL_TX_CREDIT_RECLAIM(pdev); + + rejected = htt_tx_send_batch(pdev->htt_pdev, head_msdu, num_msdus); + while (adf_os_unlikely(rejected)) { + struct ol_tx_desc_t *tx_desc; + u_int16_t *msdu_id_storage; + adf_nbuf_t next; + + next = adf_nbuf_next(rejected); + msdu_id_storage = ol_tx_msdu_id_storage(rejected); + tx_desc = ol_tx_desc_find(pdev, *msdu_id_storage); + + OL_TX_TARGET_CREDIT_INCR(pdev, rejected); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */); + + rejected = next; + } +} + +void +ol_tx_send_nonstd( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + enum htt_pkt_type pkt_type) +{ + int msdu_credit_consumed; + u_int16_t id; + int failed; + + msdu_credit_consumed = ol_tx_send_base(pdev, tx_desc, msdu); + id = ol_tx_desc_id(pdev, tx_desc); + failed = htt_tx_send_nonstd( + pdev->htt_pdev, msdu, id, pkt_type); + if (failed) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "Error: freeing tx frame after htt_tx failed"); + OL_TX_TARGET_CREDIT_INCR_INT(pdev, msdu_credit_consumed); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* had error */); + } +} + +static inline void +ol_tx_download_done_base( + struct ol_txrx_pdev_t *pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + struct ol_tx_desc_t *tx_desc; + + tx_desc = ol_tx_desc_find(pdev, msdu_id); + adf_os_assert(tx_desc); + + /* + * If the download is done for + * the Management frame then + * call the download callback if registered + */ + if (tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) { + int tx_mgmt_index = tx_desc->pkt_type - OL_TXRX_MGMT_TYPE_BASE; + ol_txrx_mgmt_tx_cb download_cb = + pdev->tx_mgmt.callbacks[tx_mgmt_index].download_cb; + + if (download_cb) { + download_cb(pdev->tx_mgmt.callbacks[tx_mgmt_index].ctxt, + tx_desc->netbuf, status != A_OK); + } + } + + if (status != A_OK) { + OL_TX_TARGET_CREDIT_INCR(pdev, msdu); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1 /* download err */); + } else { + if (OL_TX_DESC_NO_REFS(tx_desc)) { + /* + * The decremented value was zero - free the frame. + * Use the tx status recorded previously during + * tx completion handling. + */ + ol_tx_desc_frame_free_nonstd( + pdev, tx_desc, tx_desc->status != htt_tx_status_ok); + } + } +} + +void +ol_tx_download_done_ll( + void *pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + ol_tx_download_done_base( + (struct ol_txrx_pdev_t *) pdev, status, msdu, msdu_id); +} + +void +ol_tx_download_done_hl_retain( + void *txrx_pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + struct ol_txrx_pdev_t *pdev = txrx_pdev; + ol_tx_download_done_base(pdev, status, msdu, msdu_id); +#if 0 /* TODO: Advanced feature */ + //ol_tx_dwl_sched(pdev, OL_TX_HL_SCHED_DOWNLOAD_DONE); +adf_os_assert(0); +#endif +} + +void +ol_tx_download_done_hl_free( + void *txrx_pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id) +{ + struct ol_txrx_pdev_t *pdev = txrx_pdev; + struct ol_tx_desc_t *tx_desc; + + tx_desc = ol_tx_desc_find(pdev, msdu_id); + adf_os_assert(tx_desc); + + ol_tx_download_done_base(pdev, status, msdu, msdu_id); + + if ((tx_desc->pkt_type != ol_tx_frm_no_free) && + (tx_desc->pkt_type < OL_TXRX_MGMT_TYPE_BASE)) { + adf_os_atomic_add(1, &pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != A_OK); + } +#if 0 /* TODO: Advanced feature */ + //ol_tx_dwl_sched(pdev, OL_TX_HL_SCHED_DOWNLOAD_DONE); +adf_os_assert(0); +#endif +} + +void +ol_tx_target_credit_init(struct ol_txrx_pdev_t *pdev, int credit_delta) +{ + adf_os_atomic_add(credit_delta, &pdev->orig_target_tx_credit); +} + +void +ol_tx_target_credit_update(struct ol_txrx_pdev_t *pdev, int credit_delta) +{ + TX_CREDIT_DEBUG_PRINT(" Increase credit %d + %d = %d\n", + adf_os_atomic_read(&pdev->target_tx_credit), + credit_delta, + adf_os_atomic_read(&pdev->target_tx_credit) + credit_delta); + adf_os_atomic_add(credit_delta, &pdev->target_tx_credit); +} + +#ifdef QCA_COMPUTE_TX_DELAY + +static void +ol_tx_delay_compute( + struct ol_txrx_pdev_t *pdev, + enum htt_tx_status status, + u_int16_t *desc_ids, + int num_msdus); +#define OL_TX_DELAY_COMPUTE ol_tx_delay_compute +#else +#define OL_TX_DELAY_COMPUTE(pdev, status, desc_ids, num_msdus) /* no-op */ +#endif /* QCA_COMPUTE_TX_DELAY */ + +#ifndef OL_TX_RESTORE_HDR +#define OL_TX_RESTORE_HDR(__tx_desc, __msdu) +#endif +/* + * The following macros could have been inline functions too. + * The only rationale for choosing macros, is to force the compiler to inline + * the implementation, which cannot be controlled for actual "inline" functions, + * since "inline" is only a hint to the compiler. + * In the performance path, we choose to force the inlining, in preference to + * type-checking offered by the actual inlined functions. + */ +#define ol_tx_msdu_complete_batch(_pdev, _tx_desc, _tx_descs, _status) \ + do { \ + TAILQ_INSERT_TAIL(&(_tx_descs), (_tx_desc), tx_desc_list_elem); \ + } while (0) +#ifndef ATH_11AC_TXCOMPACT +#define ol_tx_msdu_complete_single(_pdev, _tx_desc, _netbuf, _lcl_freelist, _tx_desc_last) \ + do { \ + adf_os_atomic_init(&(_tx_desc)->ref_cnt); /* clear the ref cnt */ \ + OL_TX_RESTORE_HDR((_tx_desc), (_netbuf)); /* restore orginal hdr offset */ \ + adf_nbuf_unmap((_pdev)->osdev, (_netbuf), ADF_OS_DMA_TO_DEVICE); \ + adf_nbuf_free((_netbuf)); \ + ((union ol_tx_desc_list_elem_t *)(_tx_desc))->next = (_lcl_freelist); \ + if (adf_os_unlikely(!lcl_freelist)) { \ + (_tx_desc_last) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \ + } \ + (_lcl_freelist) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \ + } while (0) +#else /*!ATH_11AC_TXCOMPACT*/ + +#define ol_tx_msdu_complete_single(_pdev, _tx_desc, _netbuf, _lcl_freelist, _tx_desc_last) \ + do { \ + OL_TX_RESTORE_HDR((_tx_desc), (_netbuf)); /* restore orginal hdr offset */ \ + adf_nbuf_unmap((_pdev)->osdev, (_netbuf), ADF_OS_DMA_TO_DEVICE); \ + adf_nbuf_free((_netbuf)); \ + ((union ol_tx_desc_list_elem_t *)(_tx_desc))->next = (_lcl_freelist); \ + if (adf_os_unlikely(!lcl_freelist)) { \ + (_tx_desc_last) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \ + } \ + (_lcl_freelist) = (union ol_tx_desc_list_elem_t *)(_tx_desc); \ + } while (0) + + +#endif /*!ATH_11AC_TXCOMPACT*/ + +#ifdef QCA_TX_SINGLE_COMPLETIONS + #ifdef QCA_TX_STD_PATH_ONLY + #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, _netbuf, _lcl_freelist, \ + _tx_desc_last, _status) \ + ol_tx_msdu_complete_single((_pdev), (_tx_desc), (_netbuf), (_lcl_freelist), \ + _tx_desc_last) + #else /* !QCA_TX_STD_PATH_ONLY */ + #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, _netbuf, _lcl_freelist, \ + _tx_desc_last, _status) \ + do { \ + if (adf_os_likely((_tx_desc)->pkt_type == ol_tx_frm_std)) { \ + ol_tx_msdu_complete_single((_pdev), (_tx_desc), (_netbuf), (_lcl_freelist), \ + (_tx_desc_last)); \ + } else { \ + ol_tx_desc_frame_free_nonstd( \ + (_pdev), (_tx_desc), (_status) != htt_tx_status_ok); \ + } \ + } while (0) + #endif /* !QCA_TX_STD_PATH_ONLY */ +#else /* !QCA_TX_SINGLE_COMPLETIONS */ + #ifdef QCA_TX_STD_PATH_ONLY + #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, _netbuf, _lcl_freelist, \ + _tx_desc_last, _status) \ + ol_tx_msdus_complete_batch((_pdev), (_tx_desc), (_tx_descs), (_status)) + #else /* !QCA_TX_STD_PATH_ONLY */ + #define ol_tx_msdu_complete(_pdev, _tx_desc, _tx_descs, _netbuf, _lcl_freelist, \ + _tx_desc_last, _status) \ + do { \ + if (adf_os_likely((_tx_desc)->pkt_type == ol_tx_frm_std)) { \ + ol_tx_msdu_complete_batch((_pdev), (_tx_desc), (_tx_descs), (_status)); \ + } else { \ + ol_tx_desc_frame_free_nonstd( \ + (_pdev), (_tx_desc), (_status) != htt_tx_status_ok); \ + } \ + } while (0) + #endif /* !QCA_TX_STD_PATH_ONLY */ +#endif /* QCA_TX_SINGLE_COMPLETIONS */ + +void +ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev) +{ + int i = 0; + for (i = 0; i < pdev->tx_desc.pool_size; i++) { + + /* + * Confirm that each tx descriptor is "empty", i.e. it has + * no tx frame attached. + * In particular, check that there are no frames that have + * been given to the target to transmit, for which the + * target has never provided a response. + */ + if (adf_os_atomic_read(&pdev->tx_desc.array[i].tx_desc.ref_cnt)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "Warning: freeing tx frame " + "(no tx completion from the target)\n"); + ol_tx_desc_frame_free_nonstd( + pdev, &pdev->tx_desc.array[i].tx_desc, 1); + } + } +} + +void +ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits) +{ + ol_tx_target_credit_update(pdev, credits); + if (pdev->cfg.is_high_latency) { + ol_tx_sched(pdev); + } + /* UNPAUSE OS Q */ + OL_TX_FLOW_CT_UNPAUSE_OS_Q(pdev); +} + +/* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of ol_tx_completion_handler(). + * any change in ol_tx_completion_handler() must be mirrored in ol_tx_inspect_handler(). + */ +void +ol_tx_completion_handler( + ol_txrx_pdev_handle pdev, + int num_msdus, + enum htt_tx_status status, + void *tx_desc_id_iterator) +{ + int i; + u_int16_t *desc_ids = (u_int16_t *)tx_desc_id_iterator; + u_int16_t tx_desc_id; + struct ol_tx_desc_t *tx_desc; + char *trace_str; + + uint32_t byte_cnt = 0; + union ol_tx_desc_list_elem_t *td_array = pdev->tx_desc.array; + adf_nbuf_t netbuf; + + union ol_tx_desc_list_elem_t *lcl_freelist = NULL; + union ol_tx_desc_list_elem_t *tx_desc_last = NULL; + ol_tx_desc_list tx_descs; + TAILQ_INIT(&tx_descs); + + OL_TX_DELAY_COMPUTE(pdev, status, desc_ids, num_msdus); + + trace_str = (status) ? "OT:C:F:" : "OT:C:S:"; + for (i = 0; i < num_msdus; i++) { + tx_desc_id = desc_ids[i]; + tx_desc = &td_array[tx_desc_id].tx_desc; + tx_desc->status = status; + netbuf = tx_desc->netbuf; + + adf_nbuf_trace_update(netbuf, trace_str); + /* Per SDU update of byte count */ + byte_cnt += adf_nbuf_len(netbuf); + if (OL_TX_DESC_NO_REFS(tx_desc)) { + ol_tx_statistics(pdev->ctrl_pdev, + HTT_TX_DESC_VDEV_ID_GET(*((u_int32_t *)(tx_desc->htt_tx_desc))), + status != htt_tx_status_ok); + ol_tx_msdu_complete( + pdev, tx_desc, tx_descs, netbuf, + lcl_freelist, tx_desc_last, status); + } +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + tx_desc->pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + tx_desc->entry_timestamp_ticks = 0xffffffff; +#endif +#endif + } + + /* One shot protected access to pdev freelist, when setup */ + if (lcl_freelist) { + adf_os_spin_lock(&pdev->tx_mutex); + tx_desc_last->next = pdev->tx_desc.freelist; + pdev->tx_desc.freelist = lcl_freelist; + adf_os_spin_unlock(&pdev->tx_mutex); + pdev->tx_desc.num_free += (u_int16_t) num_msdus; + } else { + ol_tx_desc_frame_list_free(pdev, &tx_descs, status != htt_tx_status_ok); + } + if (pdev->cfg.is_high_latency) { + /* + * Credit was already explicitly updated by HTT, + * but update the number of available tx descriptors, + * then invoke the scheduler, since new credit is probably + * available now. + */ + adf_os_atomic_add(num_msdus, &pdev->tx_queue.rsrc_cnt); + ol_tx_sched(pdev); + } else { + OL_TX_TARGET_CREDIT_ADJUST(num_msdus, pdev, NULL); + } + + /* UNPAUSE OS Q */ + OL_TX_FLOW_CT_UNPAUSE_OS_Q(pdev); + /* Do one shot statistics */ + TXRX_STATS_UPDATE_TX_STATS(pdev, status, num_msdus, byte_cnt); +} + +/* + * ol_tx_single_completion_handler performs the same tx completion + * processing as ol_tx_completion_handler, but for a single frame. + * ol_tx_completion_handler is optimized to handle batch completions + * as efficiently as possible; in contrast ol_tx_single_completion_handler + * handles single frames as simply and generally as possible. + * Thus, this ol_tx_single_completion_handler function is suitable for + * intermittent usage, such as for tx mgmt frames. + */ +void +ol_tx_single_completion_handler( + ol_txrx_pdev_handle pdev, + enum htt_tx_status status, + u_int16_t tx_desc_id) +{ + struct ol_tx_desc_t *tx_desc; + union ol_tx_desc_list_elem_t *td_array = pdev->tx_desc.array; + adf_nbuf_t netbuf; + + tx_desc = &td_array[tx_desc_id].tx_desc; + tx_desc->status = status; + netbuf = tx_desc->netbuf; + + /* Do one shot statistics */ + TXRX_STATS_UPDATE_TX_STATS(pdev, status, 1, adf_nbuf_len(netbuf)); + + if (OL_TX_DESC_NO_REFS(tx_desc)) { + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != htt_tx_status_ok); + } + + TX_CREDIT_DEBUG_PRINT( + " Increase credit %d + %d = %d\n", + adf_os_atomic_read(&pdev->target_tx_credit), + 1, adf_os_atomic_read(&pdev->target_tx_credit) + 1); + + if (pdev->cfg.is_high_latency) { + /* + * Credit was already explicitly updated by HTT, + * but update the number of available tx descriptors, + * then invoke the scheduler, since new credit is probably + * available now. + */ + adf_os_atomic_add(1, &pdev->tx_queue.rsrc_cnt); + ol_tx_sched(pdev); + } else { + adf_os_atomic_add(1, &pdev->target_tx_credit); + } +} + +/* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of ol_tx_completion_handler(). + * any change in ol_tx_completion_handler() must be mirrored here. + */ +void +ol_tx_inspect_handler( + ol_txrx_pdev_handle pdev, + int num_msdus, + void *tx_desc_id_iterator) +{ + u_int16_t vdev_id, i; + struct ol_txrx_vdev_t *vdev; + u_int16_t *desc_ids = (u_int16_t *)tx_desc_id_iterator; + u_int16_t tx_desc_id; + struct ol_tx_desc_t *tx_desc; + union ol_tx_desc_list_elem_t *td_array = pdev->tx_desc.array; + union ol_tx_desc_list_elem_t *lcl_freelist = NULL; + union ol_tx_desc_list_elem_t *tx_desc_last = NULL; + adf_nbuf_t netbuf; + ol_tx_desc_list tx_descs; + TAILQ_INIT(&tx_descs); + + for (i = 0; i < num_msdus; i++) { + tx_desc_id = desc_ids[i]; + tx_desc = &td_array[tx_desc_id].tx_desc; + netbuf = tx_desc->netbuf; + + /* find the "vdev" this tx_desc belongs to */ + vdev_id = HTT_TX_DESC_VDEV_ID_GET(*((u_int32_t *)(tx_desc->htt_tx_desc))); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (vdev->vdev_id == vdev_id) + break; + } + + /* vdev now points to the vdev for this descriptor. */ + +#ifndef ATH_11AC_TXCOMPACT + /* save this multicast packet to local free list */ + if (adf_os_atomic_dec_and_test(&tx_desc->ref_cnt)) +#endif + { + /* for this function only, force htt status to be "htt_tx_status_ok" + * for graceful freeing of this multicast frame + */ + ol_tx_msdu_complete(pdev, tx_desc, tx_descs, netbuf, lcl_freelist, + tx_desc_last, htt_tx_status_ok); + } + } + + if (lcl_freelist) { + adf_os_spin_lock(&pdev->tx_mutex); + tx_desc_last->next = pdev->tx_desc.freelist; + pdev->tx_desc.freelist = lcl_freelist; + adf_os_spin_unlock(&pdev->tx_mutex); + } else { + ol_tx_desc_frame_list_free(pdev, &tx_descs, htt_tx_status_discard); + } + TX_CREDIT_DEBUG_PRINT(" Increase HTT credit %d + %d = %d..\n", + adf_os_atomic_read(&pdev->target_tx_credit), + num_msdus, + adf_os_atomic_read(&pdev->target_tx_credit) + num_msdus); + + if (pdev->cfg.is_high_latency) { + /* credit was already explicitly updated by HTT */ + ol_tx_sched(pdev); + } else { + OL_TX_TARGET_CREDIT_ADJUST(num_msdus, pdev, NULL) ; + } +} + +#ifdef QCA_COMPUTE_TX_DELAY + +void +ol_tx_set_compute_interval( + ol_txrx_pdev_handle pdev, + u_int32_t interval) +{ + pdev->tx_delay.avg_period_ticks = adf_os_msecs_to_ticks(interval); +} + +void +ol_tx_packet_count( + ol_txrx_pdev_handle pdev, + u_int16_t *out_packet_count, + u_int16_t *out_packet_loss_count, + int category) +{ + *out_packet_count = pdev->packet_count[category]; + *out_packet_loss_count = pdev->packet_loss_count[category]; + pdev->packet_count[category] = 0; + pdev->packet_loss_count[category] = 0; +} + +u_int32_t +ol_tx_delay_avg(u_int64_t sum, u_int32_t num) +{ + u_int32_t sum32; + int shift = 0; + /* + * To avoid doing a 64-bit divide, shift the sum down until it is + * no more than 32 bits (and shift the denominator to match). + */ + while ((sum >> 32) != 0) { + sum >>= 1; + shift++; + } + sum32 = (u_int32_t) sum; + num >>= shift; + return (sum32 + (num >> 1)) / num; /* round to nearest */ +} + +void +ol_tx_delay( + ol_txrx_pdev_handle pdev, + u_int32_t *queue_delay_microsec, + u_int32_t *tx_delay_microsec, + int category) +{ + int index; + u_int32_t avg_delay_ticks; + struct ol_tx_delay_data *data; + + adf_os_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES); + + adf_os_spin_lock_bh(&pdev->tx_delay.mutex); + index = 1 - pdev->tx_delay.cats[category].in_progress_idx; + + data = &pdev->tx_delay.cats[category].copies[index]; + + if (data->avgs.transmit_num > 0) { + avg_delay_ticks = ol_tx_delay_avg( + data->avgs.transmit_sum_ticks, data->avgs.transmit_num); + *tx_delay_microsec = adf_os_ticks_to_msecs(avg_delay_ticks * 1000); + } else { + /* + * This case should only happen if there's a query + * within 5 sec after the first tx data frame. + */ + *tx_delay_microsec = 0; + } + if (data->avgs.queue_num > 0) { + avg_delay_ticks = ol_tx_delay_avg( + data->avgs.queue_sum_ticks, data->avgs.queue_num); + *queue_delay_microsec = adf_os_ticks_to_msecs(avg_delay_ticks * 1000); + } else { + /* + * This case should only happen if there's a query + * within 5 sec after the first tx data frame. + */ + *queue_delay_microsec = 0; + } + + adf_os_spin_unlock_bh(&pdev->tx_delay.mutex); +} + +void +ol_tx_delay_hist( + ol_txrx_pdev_handle pdev, + u_int16_t *report_bin_values, + int category) +{ + int index, i, j; + struct ol_tx_delay_data *data; + + adf_os_assert(category >= 0 && category < QCA_TX_DELAY_NUM_CATEGORIES); + + adf_os_spin_lock_bh(&pdev->tx_delay.mutex); + index = 1 - pdev->tx_delay.cats[category].in_progress_idx; + + data = &pdev->tx_delay.cats[category].copies[index]; + + for (i = 0, j = 0; i < QCA_TX_DELAY_HIST_REPORT_BINS-1; i++) { + u_int16_t internal_bin_sum = 0; + while (j < (1 << i)) { + internal_bin_sum += data->hist_bins_queue[j++]; + } + report_bin_values[i] = internal_bin_sum; + } + report_bin_values[i] = data->hist_bins_queue[j]; /* overflow */ + + adf_os_spin_unlock_bh(&pdev->tx_delay.mutex); +} + +#ifdef QCA_COMPUTE_TX_DELAY_PER_TID +static u_int8_t +ol_tx_delay_tid_from_l3_hdr( + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t msdu, + struct ol_tx_desc_t *tx_desc) +{ + u_int16_t ethertype; + u_int8_t *dest_addr, *l3_hdr; + int is_mgmt, is_mcast; + int l2_hdr_size; + + dest_addr = ol_tx_dest_addr_find(pdev, msdu); + if (NULL == dest_addr) { + return ADF_NBUF_TX_EXT_TID_INVALID; + } + is_mcast = IEEE80211_IS_MULTICAST(dest_addr); + is_mgmt = tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE; + if (is_mgmt) { + return (is_mcast) ? + OL_TX_NUM_TIDS + OL_TX_VDEV_DEFAULT_MGMT : + HTT_TX_EXT_TID_MGMT; + } + if (is_mcast) { + return OL_TX_NUM_TIDS + OL_TX_VDEV_MCAST_BCAST; + } + if (pdev->frame_format == wlan_frm_fmt_802_3) { + struct ethernet_hdr_t *enet_hdr; + enet_hdr = (struct ethernet_hdr_t *) adf_nbuf_data(msdu); + l2_hdr_size = sizeof(struct ethernet_hdr_t); + ethertype = (enet_hdr->ethertype[0] << 8) | enet_hdr->ethertype[1]; + if (!IS_ETHERTYPE(ethertype)) { + struct llc_snap_hdr_t *llc_hdr; + llc_hdr = (struct llc_snap_hdr_t *) + (adf_nbuf_data(msdu) + l2_hdr_size); + l2_hdr_size += sizeof(struct llc_snap_hdr_t); + ethertype = (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1]; + } + } else { + struct llc_snap_hdr_t *llc_hdr; + l2_hdr_size = sizeof(struct ieee80211_frame); + llc_hdr = (struct llc_snap_hdr_t *) (adf_nbuf_data(msdu) + + l2_hdr_size); + l2_hdr_size += sizeof(struct llc_snap_hdr_t); + ethertype = (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1]; + } + l3_hdr = adf_nbuf_data(msdu) + l2_hdr_size; + if (ETHERTYPE_IPV4 == ethertype) { + return (((struct ipv4_hdr_t *) l3_hdr)->tos >> 5) & 0x7; + } else if (ETHERTYPE_IPV6 == ethertype) { + return (IPV6_TRAFFIC_CLASS((struct ipv6_hdr_t *) l3_hdr) >> 5) & 0x7; + } else { + return ADF_NBUF_TX_EXT_TID_INVALID; + } +} +#endif + +static int +ol_tx_delay_category(struct ol_txrx_pdev_t *pdev, u_int16_t msdu_id) +{ +#ifdef QCA_COMPUTE_TX_DELAY_PER_TID + struct ol_tx_desc_t *tx_desc = &pdev->tx_desc.array[msdu_id].tx_desc; + u_int8_t tid; + + adf_nbuf_t msdu = tx_desc->netbuf; + tid = adf_nbuf_get_tid(msdu); + if (tid == ADF_NBUF_TX_EXT_TID_INVALID) { + tid = ol_tx_delay_tid_from_l3_hdr(pdev, msdu, tx_desc); + if (tid == ADF_NBUF_TX_EXT_TID_INVALID) { + /* TID could not be determined (this is not an IP frame?) */ + return -1; + } + } + return tid; +#else + return 0; +#endif +} + +static inline int +ol_tx_delay_hist_bin(struct ol_txrx_pdev_t *pdev, u_int32_t delay_ticks) +{ + int bin; + /* + * For speed, multiply and shift to approximate a divide. This causes + * a small error, but the approximation error should be much less + * than the other uncertainties in the tx delay computation. + */ + bin = (delay_ticks * pdev->tx_delay.hist_internal_bin_width_mult) >> + pdev->tx_delay.hist_internal_bin_width_shift; + if (bin >= QCA_TX_DELAY_HIST_INTERNAL_BINS) { + bin = QCA_TX_DELAY_HIST_INTERNAL_BINS - 1; + } + return bin; +} + +static void +ol_tx_delay_compute( + struct ol_txrx_pdev_t *pdev, + enum htt_tx_status status, + u_int16_t *desc_ids, + int num_msdus) +{ + int i, index, cat; + u_int32_t now_ticks = adf_os_ticks(); + u_int32_t tx_delay_transmit_ticks, tx_delay_queue_ticks; + u_int32_t avg_time_ticks; + struct ol_tx_delay_data *data; + + adf_os_assert(num_msdus > 0); + + /* + * keep static counters for total packet and lost packets + * reset them in ol_tx_delay(), function used to fetch the stats + */ + + cat = ol_tx_delay_category(pdev, desc_ids[0]); + if (cat < 0 || cat >= QCA_TX_DELAY_NUM_CATEGORIES) + return; + + pdev->packet_count[cat] = pdev->packet_count[cat] + num_msdus; + if (status != htt_tx_status_ok) { + for (i = 0; i < num_msdus; i++) { + cat = ol_tx_delay_category(pdev, desc_ids[i]); + if (cat < 0 || cat >= QCA_TX_DELAY_NUM_CATEGORIES) + return; + pdev->packet_loss_count[cat]++; + } + return; + } + + /* since we may switch the ping-pong index, provide mutex w. readers */ + adf_os_spin_lock_bh(&pdev->tx_delay.mutex); + index = pdev->tx_delay.cats[cat].in_progress_idx; + + data = &pdev->tx_delay.cats[cat].copies[index]; + + if (pdev->tx_delay.tx_compl_timestamp_ticks != 0) { + tx_delay_transmit_ticks = + now_ticks - pdev->tx_delay.tx_compl_timestamp_ticks; + /* + * We'd like to account for the number of MSDUs that were + * transmitted together, but we don't know this. All we know + * is the number of MSDUs that were acked together. + * Since the frame error rate is small, this is nearly the same as + * the number of frames transmitted together. + */ + data->avgs.transmit_sum_ticks += tx_delay_transmit_ticks; + data->avgs.transmit_num += num_msdus; + } + pdev->tx_delay.tx_compl_timestamp_ticks = now_ticks; + + for (i = 0; i < num_msdus; i++) { + u_int16_t id = desc_ids[i]; + struct ol_tx_desc_t *tx_desc = &pdev->tx_desc.array[id].tx_desc; + int bin; + + tx_delay_queue_ticks = now_ticks - tx_desc->entry_timestamp_ticks; + + data->avgs.queue_sum_ticks += tx_delay_queue_ticks; + data->avgs.queue_num++; + bin = ol_tx_delay_hist_bin(pdev, tx_delay_queue_ticks); + data->hist_bins_queue[bin]++; + } + + /* check if it's time to start a new average */ + avg_time_ticks = + now_ticks - pdev->tx_delay.cats[cat].avg_start_time_ticks; + if (avg_time_ticks > pdev->tx_delay.avg_period_ticks) { + pdev->tx_delay.cats[cat].avg_start_time_ticks = now_ticks; + index = 1 - index; + pdev->tx_delay.cats[cat].in_progress_idx = index; + adf_os_mem_zero( + &pdev->tx_delay.cats[cat].copies[index], + sizeof(pdev->tx_delay.cats[cat].copies[index])); + } + + adf_os_spin_unlock_bh(&pdev->tx_delay.mutex); +} + +#endif /* QCA_COMPUTE_TX_DELAY */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.h new file mode 100644 index 0000000000000..2d20da995b4d6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_tx_send.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_tx_send.h + * @brief API definitions for the tx sendriptor module within the data SW. + */ +#ifndef _OL_TX_SEND__H_ +#define _OL_TX_SEND__H_ + +#include /* adf_nbuf_t */ +#include /* ol_tx_send_t */ + +#if defined(CONFIG_HL_SUPPORT) +#define ol_tx_discard_target_frms(pdev) /* no-op */ +#else + +/** + * @flush the ol tx when surprise remove. + * + */ +void +ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev); +#endif + +/** + * @brief Send a tx frame to the target. + * @details + * + * @param pdev - the phy dev + * @param vdev - the virtual device sending the data + * (for specifying the transmitter address for multicast / broadcast data) + * @param netbuf - the tx frame + */ +void +ol_tx_send( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu); + +/** + * @brief Send a tx batch download to the target. + * @details + * This function is different from above in that + * it accepts a list of msdu's to be downloaded as a batch + * + * @param pdev - the phy dev + * @param msdu_list - the Head pointer to the Tx Batch + * @param num_msdus - Total msdus chained in msdu_list + */ + +int +ol_tx_send_batch( + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t msdu_list, int num_msdus); + +/** + * @brief Send a tx frame with a non-std header or payload type to the target. + * @details + * + * @param pdev - the phy dev + * @param vdev - the virtual device sending the data + * (for specifying the transmitter address for multicast / broadcast data) + * @param netbuf - the tx frame + * @param pkt_type - what kind of non-std frame is being sent + */ +void +ol_tx_send_nonstd( + struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + enum htt_pkt_type pkt_type); +#endif /* _OL_TX_SEND__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.c new file mode 100644 index 0000000000000..90efd304aee3d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -0,0 +1,2217 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=== includes ===*/ +/* header files for OS primitives */ +#include /* u_int32_t, etc. */ +#include /* adf_os_mem_alloc,free */ +#include /* adf_os_device_t, adf_os_print */ +#include /* adf_os_spinlock */ +#include /* adf_os_atomic_read */ + +/* header files for utilities */ +#include /* TAILQ */ + +/* header files for configuration API */ +#include /* ol_cfg_is_high_latency */ +#include + +/* header files for HTT API */ +#include +#include + +/* header files for OS shim API */ +#include + +/* header files for our own APIs */ +#include +#include +#include +#include +/* header files for our internal definitions */ +#include /* TXRX_ASSERT, etc. */ +#include /* WDI events */ +#include /* ol_txrx_pdev_t, etc. */ +#include +#include /* ol_tx_hl, ol_tx_ll */ +#include /* ol_rx_deliver */ +#include /* ol_txrx_peer_find_attach, etc. */ +#include /* ol_rx_pn_check, etc. */ +#include /* ol_rx_fwd_check, etc. */ +#include /* OL_RX_REORDER_TIMEOUT_INIT, etc. */ +#include +#include /* ol_tx_discard_target_frms */ +#include /* ol_tx_desc_frame_free */ +#include +#include /* ol_tx_sched_attach, etc. */ +#include + +/*=== function definitions ===*/ + +u_int16_t +ol_tx_desc_pool_size_hl(ol_pdev_handle ctrl_pdev) +{ + u_int16_t desc_pool_size; + u_int16_t steady_state_tx_lifetime_ms; + u_int16_t safety_factor; + + /* + * Steady-state tx latency: + * roughly 1-2 ms flight time + * + roughly 1-2 ms prep time, + * + roughly 1-2 ms target->host notification time. + * = roughly 6 ms total + * Thus, steady state number of frames = + * steady state max throughput / frame size * tx latency, e.g. + * 1 Gbps / 1500 bytes * 6 ms = 500 + * + */ + steady_state_tx_lifetime_ms = 6; + + safety_factor = 8; + + desc_pool_size = + ol_cfg_max_thruput_mbps(ctrl_pdev) * + 1000 /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ / + (8 * OL_TX_AVG_FRM_BYTES) * + steady_state_tx_lifetime_ms * + safety_factor; + + /* minimum */ + if (desc_pool_size < OL_TX_DESC_POOL_SIZE_MIN_HL) { + desc_pool_size = OL_TX_DESC_POOL_SIZE_MIN_HL; + } + /* maximum */ + if (desc_pool_size > OL_TX_DESC_POOL_SIZE_MAX_HL) { + desc_pool_size = OL_TX_DESC_POOL_SIZE_MAX_HL; + } + return desc_pool_size; +} +#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID +ol_txrx_peer_handle +ol_txrx_find_peer_by_addr_and_vdev(ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, + u_int8_t *peer_addr, + u_int8_t *peer_id) +{ + struct ol_txrx_peer_t *peer; + + peer = ol_txrx_peer_vdev_find_hash(pdev, vdev, peer_addr, 0, 1); + if (!peer) + return NULL; + *peer_id = peer->local_id; + adf_os_atomic_dec(&peer->ref_cnt); + return peer; +} + +ol_txrx_peer_handle ol_txrx_find_peer_by_addr(ol_txrx_pdev_handle pdev, + u_int8_t *peer_addr, + u_int8_t *peer_id) +{ + struct ol_txrx_peer_t *peer; + + peer = ol_txrx_peer_find_hash_find(pdev, peer_addr, 0, 1); + if (!peer) + return NULL; + *peer_id = peer->local_id; + adf_os_atomic_dec(&peer->ref_cnt); + return peer; +} + +u_int16_t +ol_txrx_local_peer_id(ol_txrx_peer_handle peer) +{ + return peer->local_id; +} + +ol_txrx_peer_handle +ol_txrx_peer_find_by_local_id( + struct ol_txrx_pdev_t *pdev, + u_int8_t local_peer_id) +{ + struct ol_txrx_peer_t *peer; + if ((local_peer_id == OL_TXRX_INVALID_LOCAL_PEER_ID) || + (local_peer_id >= OL_TXRX_NUM_LOCAL_PEER_IDS)) { + return NULL; + } + + adf_os_spin_lock_bh(&pdev->local_peer_ids.lock); + peer = pdev->local_peer_ids.map[local_peer_id]; + adf_os_spin_unlock_bh(&pdev->local_peer_ids.lock); + return peer; +} + +static void +OL_TXRX_LOCAL_PEER_ID_POOL_INIT(struct ol_txrx_pdev_t *pdev) +{ + int i; + + /* point the freelist to the first ID */ + pdev->local_peer_ids.freelist = 0; + + /* link each ID to the next one */ + for (i = 0; i < OL_TXRX_NUM_LOCAL_PEER_IDS; i++) { + pdev->local_peer_ids.pool[i] = i + 1; + pdev->local_peer_ids.map[i] = NULL; + } + + /* link the last ID to itself, to mark the end of the list */ + i = OL_TXRX_NUM_LOCAL_PEER_IDS; + pdev->local_peer_ids.pool[i] = i; + + adf_os_spinlock_init(&pdev->local_peer_ids.lock); +} + +static void +OL_TXRX_LOCAL_PEER_ID_ALLOC( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + int i; + + adf_os_spin_lock_bh(&pdev->local_peer_ids.lock); + i = pdev->local_peer_ids.freelist; + if (pdev->local_peer_ids.pool[i] == i) { + /* the list is empty, except for the list-end marker */ + peer->local_id = OL_TXRX_INVALID_LOCAL_PEER_ID; + } else { + /* take the head ID and advance the freelist */ + peer->local_id = i; + pdev->local_peer_ids.freelist = pdev->local_peer_ids.pool[i]; + pdev->local_peer_ids.map[i] = peer; + } + adf_os_spin_unlock_bh(&pdev->local_peer_ids.lock); +} + +static void +OL_TXRX_LOCAL_PEER_ID_FREE( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + int i = peer->local_id; + if ((i == OL_TXRX_INVALID_LOCAL_PEER_ID) || + (i >= OL_TXRX_NUM_LOCAL_PEER_IDS)) { + return; + } + /* put this ID on the head of the freelist */ + adf_os_spin_lock_bh(&pdev->local_peer_ids.lock); + pdev->local_peer_ids.pool[i] = pdev->local_peer_ids.freelist; + pdev->local_peer_ids.freelist = i; + pdev->local_peer_ids.map[i] = NULL; + adf_os_spin_unlock_bh(&pdev->local_peer_ids.lock); +} + +static void +OL_TXRX_LOCAL_PEER_ID_CLEANUP(struct ol_txrx_pdev_t *pdev) +{ + adf_os_spinlock_destroy(&pdev->local_peer_ids.lock); +} + +#else +#define OL_TXRX_LOCAL_PEER_ID_POOL_INIT(pdev) /* no-op */ +#define OL_TXRX_LOCAL_PEER_ID_ALLOC(pdev, peer) /* no-op */ +#define OL_TXRX_LOCAL_PEER_ID_FREE(pdev, peer) /* no-op */ +#define OL_TXRX_LOCAL_PEER_ID_CLEANUP(pdev) /* no-op */ +#endif + +ol_txrx_pdev_handle +ol_txrx_pdev_attach( + ol_pdev_handle ctrl_pdev, + HTC_HANDLE htc_pdev, + adf_os_device_t osdev) +{ + int i; + struct ol_txrx_pdev_t *pdev; +#ifdef WDI_EVENT_ENABLE + A_STATUS ret; +#endif + u_int16_t desc_pool_size; + + pdev = adf_os_mem_alloc(osdev, sizeof(*pdev)); + if (!pdev) { + goto fail0; + } + adf_os_mem_zero(pdev, sizeof(*pdev)); + + /* init LL/HL cfg here */ + pdev->cfg.is_high_latency = ol_cfg_is_high_latency(ctrl_pdev); + pdev->cfg.default_tx_comp_req = !ol_cfg_tx_free_at_download(ctrl_pdev); + + /* store provided params */ + pdev->ctrl_pdev = ctrl_pdev; + pdev->osdev = osdev; + + for (i = 0; i < htt_num_sec_types; i++) { + pdev->sec_types[i] = (enum ol_sec_type)i; + } + + TXRX_STATS_INIT(pdev); + + TAILQ_INIT(&pdev->vdev_list); + + /* do initial set up of the peer ID -> peer object lookup map */ + if (ol_txrx_peer_find_attach(pdev)) { + goto fail1; + } + + if (ol_cfg_is_high_latency(ctrl_pdev)) { + desc_pool_size = ol_tx_desc_pool_size_hl(ctrl_pdev); + adf_os_atomic_init(&pdev->tx_queue.rsrc_cnt); + adf_os_atomic_add(desc_pool_size, &pdev->tx_queue.rsrc_cnt); +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + /* + * 5% margin of unallocated desc is too much for per vdev mechanism. + * Define the value seperately. + */ + pdev->tx_queue.rsrc_threshold_lo = TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED; +#else + /* always maintain a 5% margin of unallocated descriptors */ + pdev->tx_queue.rsrc_threshold_lo = (5 * desc_pool_size)/100; +#endif + /* when freeing up descriptors, keep going until there's a 15% margin */ + pdev->tx_queue.rsrc_threshold_hi = (15 * desc_pool_size)/100; + } else { + /* + * For LL, limit the number of host's tx descriptors to match the + * number of target FW tx descriptors. + * This simplifies the FW, by ensuring the host will never download + * more tx descriptors than the target has space for. + * The FW will drop/free low-priority tx descriptors when it starts + * to run low, so that in theory the host should never run out of + * tx descriptors. + */ + desc_pool_size = ol_cfg_target_tx_credit(ctrl_pdev); + } + + /* initialize the counter of the target's tx buffer availability */ + adf_os_atomic_init(&pdev->target_tx_credit); + adf_os_atomic_init(&pdev->orig_target_tx_credit); + /* + * LL - initialize the target credit outselves. + * HL - wait for a HTT target credit initialization during htt_attach. + */ + if (!ol_cfg_is_high_latency(ctrl_pdev)) { + adf_os_atomic_add( + ol_cfg_target_tx_credit(pdev->ctrl_pdev), &pdev->target_tx_credit); + } + + pdev->htt_pdev = htt_attach( + pdev, ctrl_pdev, htc_pdev, osdev, desc_pool_size); + if (!pdev->htt_pdev) { + goto fail2; + } + +#ifdef IPA_UC_OFFLOAD + /* Attach micro controller data path offload resource */ + if (ol_cfg_ipa_uc_offload_enabled(ctrl_pdev)) { + if (htt_ipa_uc_attach(pdev->htt_pdev)) { + goto fail3; + } + } +#endif /* IPA_UC_OFFLOAD */ + + pdev->tx_desc.array = adf_os_mem_alloc( + osdev, desc_pool_size * sizeof(union ol_tx_desc_list_elem_t)); + if (!pdev->tx_desc.array) { + goto fail3; + } + adf_os_mem_set( + pdev->tx_desc.array, 0, + desc_pool_size * sizeof(union ol_tx_desc_list_elem_t)); + + /* + * Each SW tx desc (used only within the tx datapath SW) has a + * matching HTT tx desc (used for downloading tx meta-data to FW/HW). + * Go ahead and allocate the HTT tx desc and link it with the SW tx + * desc now, to avoid doing it during time-critical transmit. + */ + pdev->tx_desc.pool_size = desc_pool_size; + for (i = 0; i < desc_pool_size; i++) { + void *htt_tx_desc; + u_int32_t paddr_lo; + htt_tx_desc = htt_tx_desc_alloc(pdev->htt_pdev, &paddr_lo); + if (! htt_tx_desc) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "%s: failed to alloc HTT tx desc (%d of %d)\n", + __func__, i, desc_pool_size); + while (--i >= 0) { + htt_tx_desc_free( + pdev->htt_pdev, + pdev->tx_desc.array[i].tx_desc.htt_tx_desc); + } + goto fail4; + } + pdev->tx_desc.array[i].tx_desc.htt_tx_desc = htt_tx_desc; + pdev->tx_desc.array[i].tx_desc.htt_tx_desc_paddr = paddr_lo; +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + pdev->tx_desc.array[i].tx_desc.pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + pdev->tx_desc.array[i].tx_desc.entry_timestamp_ticks = 0xffffffff; +#endif +#endif + } + + /* link SW tx descs into a freelist */ + pdev->tx_desc.num_free = desc_pool_size; + pdev->tx_desc.freelist = &pdev->tx_desc.array[0]; + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s first tx_desc:0x%p Last tx desc:0x%p\n", __func__, + (u_int32_t *) pdev->tx_desc.freelist, + (u_int32_t *) (pdev->tx_desc.freelist + desc_pool_size)); + for (i = 0; i < desc_pool_size-1; i++) { + pdev->tx_desc.array[i].next = &pdev->tx_desc.array[i+1]; + } + pdev->tx_desc.array[i].next = NULL; + + /* check what format of frames are expected to be delivered by the OS */ + pdev->frame_format = ol_cfg_frame_type(pdev->ctrl_pdev); + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + pdev->htt_pkt_type = htt_pkt_type_native_wifi; + } else if (pdev->frame_format == wlan_frm_fmt_802_3) { + pdev->htt_pkt_type = htt_pkt_type_ethernet; + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "%s Invalid standard frame type: %d\n", + __func__, pdev->frame_format); + goto fail5; + } + + /* setup the global rx defrag waitlist */ + TAILQ_INIT(&pdev->rx.defrag.waitlist); + + /* configure where defrag timeout and duplicate detection is handled */ + pdev->rx.flags.defrag_timeout_check = + pdev->rx.flags.dup_check = + ol_cfg_rx_host_defrag_timeout_duplicate_check(ctrl_pdev); + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + /* Need to revisit this part. Currently,hardcode to riva's caps */ + pdev->target_tx_tran_caps = wlan_frm_tran_cap_raw; + pdev->target_rx_tran_caps = wlan_frm_tran_cap_raw; + /* + * The Riva HW de-aggregate doesn't have capability to generate 802.11 + * header for non-first subframe of A-MSDU. + */ + pdev->sw_subfrm_hdr_recovery_enable = 1; + /* + * The Riva HW doesn't have the capability to set Protected Frame bit + * in the MAC header for encrypted data frame. + */ + pdev->sw_pf_proc_enable = 1; + + if (pdev->frame_format == wlan_frm_fmt_802_3) { + /* sw llc process is only needed in 802.3 to 802.11 transform case */ + pdev->sw_tx_llc_proc_enable = 1; + pdev->sw_rx_llc_proc_enable = 1; + } else { + pdev->sw_tx_llc_proc_enable = 0; + pdev->sw_rx_llc_proc_enable = 0; + } + + switch(pdev->frame_format) { + case wlan_frm_fmt_raw: + pdev->sw_tx_encap = + pdev->target_tx_tran_caps & wlan_frm_tran_cap_raw ? 0 : 1; + pdev->sw_rx_decap = + pdev->target_rx_tran_caps & wlan_frm_tran_cap_raw ? 0 : 1; + break; + case wlan_frm_fmt_native_wifi: + pdev->sw_tx_encap = + pdev->target_tx_tran_caps & wlan_frm_tran_cap_native_wifi ? 0: 1; + pdev->sw_rx_decap = + pdev->target_rx_tran_caps & wlan_frm_tran_cap_native_wifi ? 0: 1; + break; + case wlan_frm_fmt_802_3: + pdev->sw_tx_encap = + pdev->target_tx_tran_caps & wlan_frm_tran_cap_8023 ? 0: 1; + pdev->sw_rx_decap = + pdev->target_rx_tran_caps & wlan_frm_tran_cap_8023 ? 0: 1; + break; + default: + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid standard frame type for encap/decap: fmt %x tx %x rx %x\n", + pdev->frame_format, + pdev->target_tx_tran_caps, + pdev->target_rx_tran_caps); + goto fail5; + } +#endif + + /* + * Determine what rx processing steps are done within the host. + * Possibilities: + * 1. Nothing - rx->tx forwarding and rx PN entirely within target. + * (This is unlikely; even if the target is doing rx->tx forwarding, + * the host should be doing rx->tx forwarding too, as a back up for + * the target's rx->tx forwarding, in case the target runs short on + * memory, and can't store rx->tx frames that are waiting for missing + * prior rx frames to arrive.) + * 2. Just rx -> tx forwarding. + * This is the typical configuration for HL, and a likely + * configuration for LL STA or small APs (e.g. retail APs). + * 3. Both PN check and rx -> tx forwarding. + * This is the typical configuration for large LL APs. + * Host-side PN check without rx->tx forwarding is not a valid + * configuration, since the PN check needs to be done prior to + * the rx->tx forwarding. + */ + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev)) { + /* PN check, rx-tx forwarding and rx reorder is done by the target */ + if (ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev)) { + pdev->rx_opt_proc = ol_rx_in_order_deliver; + } else { + pdev->rx_opt_proc = ol_rx_fwd_check; + } + } else { + if (ol_cfg_rx_pn_check(pdev->ctrl_pdev)) { + if (ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev)) { + /* + * PN check done on host, rx->tx forwarding not done at all. + */ + pdev->rx_opt_proc = ol_rx_pn_check_only; + } else if (ol_cfg_rx_fwd_check(pdev->ctrl_pdev)) { + /* + * Both PN check and rx->tx forwarding done on host. + */ + pdev->rx_opt_proc = ol_rx_pn_check; + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "%s: invalid config: if rx PN check is on the host," + "rx->tx forwarding check needs to also be on the host.\n", + __func__); + goto fail5; + } + } else { + /* PN check done on target */ + if ((!ol_cfg_rx_fwd_disabled(pdev->ctrl_pdev)) && + ol_cfg_rx_fwd_check(pdev->ctrl_pdev)) + { + /* + * rx->tx forwarding done on host (possibly as + * back-up for target-side primary rx->tx forwarding) + */ + pdev->rx_opt_proc = ol_rx_fwd_check; + } else { + /* rx->tx forwarding either done in target, or not done at all */ + pdev->rx_opt_proc = ol_rx_deliver; + } + } + } + + /* initialize mutexes for tx desc alloc and peer lookup */ + adf_os_spinlock_init(&pdev->tx_mutex); + adf_os_spinlock_init(&pdev->peer_ref_mutex); + adf_os_spinlock_init(&pdev->rx.mutex); + adf_os_spinlock_init(&pdev->last_real_peer_mutex); + OL_TXRX_PEER_STATS_MUTEX_INIT(pdev); + + if (ol_cfg_is_high_latency(ctrl_pdev)) { + adf_os_spinlock_init(&pdev->tx_queue_spinlock); + pdev->tx_sched.scheduler = ol_tx_sched_attach(pdev); + if (pdev->tx_sched.scheduler == NULL) { + goto fail6; + } + } + + if (OL_RX_REORDER_TRACE_ATTACH(pdev) != A_OK) { + goto fail7; + } + + if (OL_RX_PN_TRACE_ATTACH(pdev) != A_OK) { + goto fail8; + } + +#ifdef PERE_IP_HDR_ALIGNMENT_WAR + pdev->host_80211_enable = ol_scn_host_80211_enable_get(pdev->ctrl_pdev); +#endif + + /* + * WDI event attach + */ +#ifdef WDI_EVENT_ENABLE + if ((ret = wdi_event_attach(pdev)) == A_ERROR) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_WARN, + "WDI event attach unsuccessful\n"); + } +#endif + + /* + * Initialize rx PN check characteristics for different security types. + */ + adf_os_mem_set(&pdev->rx_pn[0], 0, sizeof(pdev->rx_pn)); + + /* TKIP: 48-bit TSC, CCMP: 48-bit PN */ + pdev->rx_pn[htt_sec_type_tkip].len = + pdev->rx_pn[htt_sec_type_tkip_nomic].len = + pdev->rx_pn[htt_sec_type_aes_ccmp].len = 48; + pdev->rx_pn[htt_sec_type_tkip].cmp = + pdev->rx_pn[htt_sec_type_tkip_nomic].cmp = + pdev->rx_pn[htt_sec_type_aes_ccmp].cmp = ol_rx_pn_cmp48; + + /* WAPI: 128-bit PN */ + pdev->rx_pn[htt_sec_type_wapi].len = 128; + pdev->rx_pn[htt_sec_type_wapi].cmp = ol_rx_pn_wapi_cmp; + + OL_RX_REORDER_TIMEOUT_INIT(pdev); + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "Created pdev %p\n", pdev); + + #if defined(CONFIG_HL_SUPPORT) && defined(ENABLE_TX_QUEUE_LOG) + pdev->txq_log.size = OL_TXQ_LOG_SIZE; + pdev->txq_log.oldest_record_offset = 0; + pdev->txq_log.offset = 0; + pdev->txq_log.allow_wrap = 1; + pdev->txq_log.wrapped = 0; + #endif /* defined(CONFIG_HL_SUPPORT) && defined(ENABLE_TX_QUEUE_LOG) */ + + pdev->cfg.host_addba = ol_cfg_host_addba(ctrl_pdev); + + #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI + #define OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT 3 + #if 1 + #define OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT \ + /* avg = 100% * new + 0% * old */ \ + (1 << OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT) + #else + #define OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT \ + /* avg = 25% * new + 25% * old */ \ + (1 << (OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT-2)) + #endif + pdev->rssi_update_shift = OL_TXRX_RSSI_UPDATE_SHIFT_DEFAULT; + pdev->rssi_new_weight = OL_TXRX_RSSI_NEW_WEIGHT_DEFAULT; + #endif + + OL_TXRX_LOCAL_PEER_ID_POOL_INIT(pdev); + + pdev->cfg.ll_pause_txq_limit = ol_tx_cfg_max_tx_queue_depth_ll(ctrl_pdev); + +#ifdef QCA_COMPUTE_TX_DELAY + adf_os_mem_zero(&pdev->tx_delay, sizeof(pdev->tx_delay)); + adf_os_spinlock_init(&pdev->tx_delay.mutex); + + /* initialize compute interval with 5 seconds (ESE default) */ + pdev->tx_delay.avg_period_ticks = adf_os_msecs_to_ticks(5000); + { + u_int32_t bin_width_1000ticks; + bin_width_1000ticks = adf_os_msecs_to_ticks( + QCA_TX_DELAY_HIST_INTERNAL_BIN_WIDTH_MS * 1000); + /* + * Compute a factor and shift that together are equal to the + * inverse of the bin_width time, so that rather than dividing + * by the bin width time, approximately the same result can be + * obtained much more efficiently by a multiply + shift. + * multiply_factor >> shift = 1 / bin_width_time, so + * multiply_factor = (1 << shift) / bin_width_time. + * + * Pick the shift semi-arbitrarily. + * If we knew statically what the bin_width would be, we could + * choose a shift that minimizes the error. + * Since the bin_width is determined dynamically, simply use a + * shift that is about half of the u_int32_t size. This should + * result in a relatively large multiplier value, which minimizes + * the error from rounding the multiplier to an integer. + * The rounding error only becomes significant if the tick units + * are on the order of 1 microsecond. In most systems, it is + * expected that the tick units will be relatively low-resolution, + * on the order of 1 millisecond. In such systems the rounding + * error is negligible. + * It would be more accurate to dynamically try out different + * shifts and choose the one that results in the smallest rounding + * error, but that extra level of fidelity is not needed. + */ + pdev->tx_delay.hist_internal_bin_width_shift = 16; + pdev->tx_delay.hist_internal_bin_width_mult = + ((1 << pdev->tx_delay.hist_internal_bin_width_shift) * + 1000 + (bin_width_1000ticks >> 1)) / bin_width_1000ticks; + } +#endif /* QCA_COMPUTE_TX_DELAY */ + +#ifdef QCA_SUPPORT_TX_THROTTLE + /* Thermal Mitigation */ + ol_tx_throttle_init(pdev); +#endif + return pdev; /* success */ + +fail8: + OL_RX_REORDER_TRACE_DETACH(pdev); + +fail7: + adf_os_spinlock_destroy(&pdev->tx_mutex); + adf_os_spinlock_destroy(&pdev->peer_ref_mutex); + adf_os_spinlock_destroy(&pdev->rx.mutex); + adf_os_spinlock_destroy(&pdev->last_real_peer_mutex); + OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev); + + ol_tx_sched_detach(pdev); + +fail6: + if (ol_cfg_is_high_latency(ctrl_pdev)) { + adf_os_spinlock_destroy(&pdev->tx_queue_spinlock); + } + +fail5: + for (i = 0; i < desc_pool_size; i++) { + htt_tx_desc_free( + pdev->htt_pdev, pdev->tx_desc.array[i].tx_desc.htt_tx_desc); + } + +fail4: + adf_os_mem_free(pdev->tx_desc.array); +#ifdef IPA_UC_OFFLOAD + if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev)) { + htt_ipa_uc_detach(pdev->htt_pdev); + } +#endif /* IPA_UC_OFFLOAD */ + +fail3: + htt_detach(pdev->htt_pdev); + +fail2: + ol_txrx_peer_find_detach(pdev); + +fail1: + adf_os_mem_free(pdev); + +fail0: + return NULL; /* fail */ +} + +A_STATUS ol_txrx_pdev_attach_target(ol_txrx_pdev_handle pdev) +{ + return htt_attach_target(pdev->htt_pdev); +} + +void +ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) +{ + int i; + /* preconditions */ + TXRX_ASSERT2(pdev); + + /* check that the pdev has no vdevs allocated */ + TXRX_ASSERT1(TAILQ_EMPTY(&pdev->vdev_list)); + + OL_RX_REORDER_TIMEOUT_CLEANUP(pdev); + + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + ol_tx_sched_detach(pdev); + } +#ifdef QCA_SUPPORT_TX_THROTTLE + /* Thermal Mitigation */ + adf_os_timer_cancel(&pdev->tx_throttle.phase_timer); + adf_os_timer_free(&pdev->tx_throttle.phase_timer); +#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ + adf_os_timer_cancel(&pdev->tx_throttle.tx_timer); + adf_os_timer_free(&pdev->tx_throttle.tx_timer); +#endif +#endif + if (force) { + /* + * The assertion above confirms that all vdevs within this pdev + * were detached. However, they may not have actually been deleted. + * If the vdev had peers which never received a PEER_UNMAP message + * from the target, then there are still zombie peer objects, and + * the vdev parents of the zombie peers are also zombies, hanging + * around until their final peer gets deleted. + * Go through the peer hash table and delete any peers left in it. + * As a side effect, this will complete the deletion of any vdevs + * that are waiting for their peers to finish deletion. + */ + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "Force delete for pdev %p\n", pdev); + ol_txrx_peer_find_hash_erase(pdev); + } + + /* Stop the communication between HTT and target at first */ + htt_detach_target(pdev->htt_pdev); + + for (i = 0; i < pdev->tx_desc.pool_size; i++) { + void *htt_tx_desc; + + /* + * Confirm that each tx descriptor is "empty", i.e. it has + * no tx frame attached. + * In particular, check that there are no frames that have + * been given to the target to transmit, for which the + * target has never provided a response. + */ + if (adf_os_atomic_read(&pdev->tx_desc.array[i].tx_desc.ref_cnt)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, + "Warning: freeing tx frame " + "(no tx completion from the target)\n"); + ol_tx_desc_frame_free_nonstd( + pdev, &pdev->tx_desc.array[i].tx_desc, 1); + } + htt_tx_desc = pdev->tx_desc.array[i].tx_desc.htt_tx_desc; + htt_tx_desc_free(pdev->htt_pdev, htt_tx_desc); + } + + adf_os_mem_free(pdev->tx_desc.array); + +#ifdef IPA_UC_OFFLOAD + /* Detach micro controller data path offload resource */ + if (ol_cfg_ipa_uc_offload_enabled(pdev->ctrl_pdev)) { + htt_ipa_uc_detach(pdev->htt_pdev); + } +#endif /* IPA_UC_OFFLOAD */ + + htt_detach(pdev->htt_pdev); + + ol_txrx_peer_find_detach(pdev); + + adf_os_spinlock_destroy(&pdev->tx_mutex); + adf_os_spinlock_destroy(&pdev->peer_ref_mutex); + adf_os_spinlock_destroy(&pdev->last_real_peer_mutex); + adf_os_spinlock_destroy(&pdev->rx.mutex); +#ifdef QCA_SUPPORT_TX_THROTTLE + /* Thermal Mitigation */ + adf_os_spinlock_destroy(&pdev->tx_throttle.mutex); +#endif + OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev); + + OL_RX_REORDER_TRACE_DETACH(pdev); + OL_RX_PN_TRACE_DETACH(pdev); + /* + * WDI event detach + */ +#ifdef WDI_EVENT_ENABLE + if (wdi_event_detach(pdev) == A_ERROR) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_WARN, + "WDI detach unsuccessful\n"); + } +#endif + OL_TXRX_LOCAL_PEER_ID_CLEANUP(pdev); + +#ifdef QCA_COMPUTE_TX_DELAY + adf_os_spinlock_destroy(&pdev->tx_delay.mutex); +#endif + + adf_os_mem_free(pdev); +} + +ol_txrx_vdev_handle +ol_txrx_vdev_attach( + ol_txrx_pdev_handle pdev, + u_int8_t *vdev_mac_addr, + u_int8_t vdev_id, + enum wlan_op_mode op_mode) +{ + struct ol_txrx_vdev_t *vdev; + + /* preconditions */ + TXRX_ASSERT2(pdev); + TXRX_ASSERT2(vdev_mac_addr); + + vdev = adf_os_mem_alloc(pdev->osdev, sizeof(*vdev)); + if (!vdev) { + return NULL; /* failure */ + } + + /* store provided params */ + vdev->pdev = pdev; + vdev->vdev_id = vdev_id; + vdev->opmode = op_mode; + + vdev->osif_rx = NULL; + + vdev->delete.pending = 0; + vdev->safemode = 0; + vdev->drop_unenc = 1; + vdev->num_filters = 0; +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + adf_os_atomic_init(&vdev->tx_desc_count); +#endif + + adf_os_mem_copy( + &vdev->mac_addr.raw[0], vdev_mac_addr, OL_TXRX_MAC_ADDR_LEN); + + TAILQ_INIT(&vdev->peer_list); + vdev->last_real_peer = NULL; + + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + vdev->hlTdlsFlag = false; + #endif + + #ifdef QCA_IBSS_SUPPORT + vdev->ibss_peer_num = 0; + vdev->ibss_peer_heart_beat_timer = 0; + #endif + + #if defined(CONFIG_HL_SUPPORT) + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + u_int8_t i; + for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { + TAILQ_INIT(&vdev->txqs[i].head); + vdev->txqs[i].paused_count.total = 0; + vdev->txqs[i].frms = 0; + vdev->txqs[i].bytes = 0; + vdev->txqs[i].ext_tid = OL_TX_NUM_TIDS + i; + vdev->txqs[i].flag = ol_tx_queue_empty; + /* aggregation is not applicable for vdev tx queues */ + vdev->txqs[i].aggr_state = ol_tx_aggr_disabled; + } + } + #endif /* defined(CONFIG_HL_SUPPORT) */ + + adf_os_spinlock_init(&vdev->ll_pause.mutex); + vdev->ll_pause.paused_reason = 0; + vdev->ll_pause.txq.head = vdev->ll_pause.txq.tail = NULL; + vdev->ll_pause.txq.depth = 0; + adf_os_timer_init( + pdev->osdev, + &vdev->ll_pause.timer, + ol_tx_vdev_ll_pause_queue_send, + vdev, ADF_DEFERRABLE_TIMER); + adf_os_atomic_init(&vdev->os_q_paused); + adf_os_atomic_set(&vdev->os_q_paused, 0); + vdev->tx_fl_lwm = 0; + vdev->tx_fl_hwm = 0; + vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID; + vdev->osif_flow_control_cb = NULL; + /* Default MAX Q depth for every VDEV */ + vdev->ll_pause.max_q_depth = + ol_tx_cfg_max_tx_queue_depth_ll(vdev->pdev->ctrl_pdev); + /* add this vdev into the pdev's list */ + TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "Created vdev %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], vdev->mac_addr.raw[2], + vdev->mac_addr.raw[3], vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + + /* + * We've verified that htt_op_mode == wlan_op_mode, + * so no translation is needed. + */ + htt_vdev_attach(pdev->htt_pdev, vdev_id, op_mode); + + return vdev; +} + +void ol_txrx_osif_vdev_register(ol_txrx_vdev_handle vdev, + void *osif_vdev, + struct ol_txrx_osif_ops *txrx_ops) +{ + vdev->osif_dev = osif_vdev; + vdev->osif_rx = txrx_ops->rx.std; + + if (ol_cfg_is_high_latency(vdev->pdev->ctrl_pdev)) { + txrx_ops->tx.std = vdev->tx = ol_tx_hl; + txrx_ops->tx.non_std = ol_tx_non_std_hl; + } else { + txrx_ops->tx.std = vdev->tx = OL_TX_LL; + txrx_ops->tx.non_std = ol_tx_non_std_ll; + } + #ifdef QCA_LL_TX_FLOW_CT + vdev->osif_flow_control_cb = txrx_ops->tx.flow_control_cb; + #endif /* QCA_LL_TX_FLOW_CT */ +} + +void +ol_txrx_set_curchan( + ol_txrx_pdev_handle pdev, + u_int32_t chan_mhz) +{ + return; +} + +void +ol_txrx_set_safemode( + ol_txrx_vdev_handle vdev, + u_int32_t val) +{ + vdev->safemode = val; +} + +void +ol_txrx_set_privacy_filters( + ol_txrx_vdev_handle vdev, + void *filters, + u_int32_t num) +{ + adf_os_mem_copy( + vdev->privacy_filters, filters, num*sizeof(privacy_exemption)); + vdev->num_filters = num; +} + +void +ol_txrx_set_drop_unenc( + ol_txrx_vdev_handle vdev, + u_int32_t val) +{ + vdev->drop_unenc = val; +} + +void +ol_txrx_vdev_detach( + ol_txrx_vdev_handle vdev, + ol_txrx_vdev_delete_cb callback, + void *context) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + /* preconditions */ + TXRX_ASSERT2(vdev); + +#if defined(CONFIG_HL_SUPPORT) + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + struct ol_tx_frms_queue_t *txq; + int i; + + for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { + txq = &vdev->txqs[i]; + ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS)); + } + } + #endif /* defined(CONFIG_HL_SUPPORT) */ + + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + adf_os_timer_cancel(&vdev->ll_pause.timer); + adf_os_timer_free(&vdev->ll_pause.timer); + while (vdev->ll_pause.txq.head) { + adf_nbuf_t next = adf_nbuf_next(vdev->ll_pause.txq.head); + adf_nbuf_set_next(vdev->ll_pause.txq.head, NULL); + adf_nbuf_unmap(pdev->osdev, vdev->ll_pause.txq.head, + ADF_OS_DMA_TO_DEVICE); + adf_nbuf_tx_free(vdev->ll_pause.txq.head, 1 /* error */); + vdev->ll_pause.txq.head = next; + } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + adf_os_spinlock_destroy(&vdev->ll_pause.mutex); + + /* remove the vdev from its parent pdev's list */ + TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem); + + /* + * Use peer_ref_mutex while accessing peer_list, in case + * a peer is in the process of being removed from the list. + */ + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + /* check that the vdev has no peers allocated */ + if (!TAILQ_EMPTY(&vdev->peer_list)) { + /* debug print - will be removed later */ + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s: not deleting vdev object %p (%02x:%02x:%02x:%02x:%02x:%02x)" + "until deletion finishes for all its peers\n", + __func__, vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], + vdev->mac_addr.raw[2], vdev->mac_addr.raw[3], + vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + /* indicate that the vdev needs to be deleted */ + vdev->delete.pending = 1; + vdev->delete.callback = callback; + vdev->delete.context = context; + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return; + } + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s: deleting vdev object %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + __func__, vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], vdev->mac_addr.raw[2], + vdev->mac_addr.raw[3], vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + + htt_vdev_detach(pdev->htt_pdev, vdev->vdev_id); + + /* + * Doesn't matter if there are outstanding tx frames - + * they will be freed once the target sends a tx completion + * message for them. + */ + adf_os_mem_free(vdev); + if (callback) { + callback(context); + } +} + +ol_txrx_peer_handle +ol_txrx_peer_attach( + ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, + u_int8_t *peer_mac_addr) +{ + struct ol_txrx_peer_t *peer; + struct ol_txrx_peer_t *temp_peer; + u_int8_t i; + int differs; + bool wait_on_deletion = false; + unsigned long rc; + + /* preconditions */ + TXRX_ASSERT2(pdev); + TXRX_ASSERT2(vdev); + TXRX_ASSERT2(peer_mac_addr); + + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + /* check for duplicate exsisting peer */ + TAILQ_FOREACH(temp_peer, &vdev->peer_list, peer_list_elem) { + if (!ol_txrx_peer_find_mac_addr_cmp(&temp_peer->mac_addr, + (union ol_txrx_align_mac_addr_t *)peer_mac_addr)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) already exsist.\n", + vdev->vdev_id, + peer_mac_addr[0], peer_mac_addr[1], + peer_mac_addr[2], peer_mac_addr[3], + peer_mac_addr[4], peer_mac_addr[5]); + if (adf_os_atomic_read(&temp_peer->delete_in_progress)) { + vdev->wait_on_peer_id = temp_peer->local_id; + adf_os_init_completion(&vdev->wait_delete_comp); + wait_on_deletion = true; + } else { + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return NULL; + } + } + } + + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + + if (wait_on_deletion) { + /* wait for peer deletion */ + rc = adf_os_wait_for_completion_timeout( + &vdev->wait_delete_comp, + adf_os_msecs_to_ticks(PEER_DELETION_TIMEOUT)); + if (!rc) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "timedout waiting for peer(%d) deletion\n", + vdev->wait_on_peer_id); + vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID; + return NULL; + } + } + + peer = adf_os_mem_alloc(pdev->osdev, sizeof(*peer)); + if (!peer) { + return NULL; /* failure */ + } + adf_os_mem_zero(peer, sizeof(*peer)); + + /* store provided params */ + peer->vdev = vdev; + adf_os_mem_copy( + &peer->mac_addr.raw[0], peer_mac_addr, OL_TXRX_MAC_ADDR_LEN); + + #if defined(CONFIG_HL_SUPPORT) + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + for (i = 0; i < OL_TX_NUM_TIDS; i++) { + TAILQ_INIT(&peer->txqs[i].head); + peer->txqs[i].paused_count.total = 0; + peer->txqs[i].frms = 0; + peer->txqs[i].bytes = 0; + peer->txqs[i].ext_tid = i; + peer->txqs[i].flag = ol_tx_queue_empty; + peer->txqs[i].aggr_state = ol_tx_aggr_untried; + } + /* aggregation is not applicable for mgmt and non-QoS tx queues */ + for (i = OL_TX_NUM_QOS_TIDS; i < OL_TX_NUM_TIDS; i++) { + peer->txqs[i].aggr_state = ol_tx_aggr_disabled; + } + } + ol_txrx_peer_pause(peer); + #endif /* defined(CONFIG_HL_SUPPORT) */ + + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + /* add this peer into the vdev's list */ + TAILQ_INSERT_TAIL(&vdev->peer_list, peer, peer_list_elem); + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + /* check whether this is a real peer (peer mac addr != vdev mac addr) */ + if (ol_txrx_peer_find_mac_addr_cmp(&vdev->mac_addr, &peer->mac_addr)) { + vdev->last_real_peer = peer; + } + + peer->rx_opt_proc = pdev->rx_opt_proc; + + ol_rx_peer_init(pdev, peer); + + /* initialize the peer_id */ + for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) { + peer->peer_ids[i] = HTT_INVALID_PEER; + } + + adf_os_atomic_init(&peer->delete_in_progress); + + adf_os_atomic_init(&peer->ref_cnt); + + /* keep one reference for attach */ + adf_os_atomic_inc(&peer->ref_cnt); + + /* keep one reference for ol_rx_peer_map_handler */ + adf_os_atomic_inc(&peer->ref_cnt); + + peer->valid = 1; + + ol_txrx_peer_find_hash_add(pdev, peer); + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, + "vdev %p created peer %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + vdev, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], peer->mac_addr.raw[2], + peer->mac_addr.raw[3], peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + /* + * For every peer MAp message search and set if bss_peer + */ + differs = adf_os_mem_cmp( + peer->mac_addr.raw, vdev->mac_addr.raw, OL_TXRX_MAC_ADDR_LEN); + if (!differs) { + peer->bss_peer = 1; + } + + /* + * The peer starts in the "disc" state while association is in progress. + * Once association completes, the peer will get updated to "auth" state + * by a call to ol_txrx_peer_state_update if the peer is in open mode, or + * else to the "conn" state. For non-open mode, the peer will progress to + * "auth" state once the authentication completes. + */ + peer->state = ol_txrx_peer_state_invalid; + ol_txrx_peer_state_update(pdev, peer->mac_addr.raw, ol_txrx_peer_state_disc); + + #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI + peer->rssi_dbm = HTT_RSSI_INVALID; + #endif + + OL_TXRX_LOCAL_PEER_ID_ALLOC(pdev, peer); + + return peer; +} + +/* + * Discarding tx filter - removes all data frames (disconnected state) + */ +static A_STATUS +ol_tx_filter_discard(struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + return A_ERROR; +} +/* + * Non-autentication tx filter - filters out data frames that are not + * related to authentication, but allows EAPOL (PAE) or WAPI (WAI) + * data frames (connected state) + */ +static A_STATUS +ol_tx_filter_non_auth(struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + return + (tx_msdu_info->htt.info.ethertype == ETHERTYPE_PAE || + tx_msdu_info->htt.info.ethertype == ETHERTYPE_WAI) ? A_OK : A_ERROR; +} + +/* + * Pass-through tx filter - lets all data frames through (authenticated state) + */ +static A_STATUS +ol_tx_filter_pass_thru(struct ol_txrx_msdu_info_t *tx_msdu_info) +{ + return A_OK; +} + +void +ol_txrx_peer_state_update(ol_txrx_pdev_handle pdev, u_int8_t *peer_mac, + enum ol_txrx_peer_state state) +{ + struct ol_txrx_peer_t *peer; + + peer = ol_txrx_peer_find_hash_find(pdev, peer_mac, 0, 1); + + if (NULL == peer) + { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, "%s: peer is null for peer_mac" + " 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, + peer_mac[0], peer_mac[1], peer_mac[2], peer_mac[3], + peer_mac[4], peer_mac[5]); + return; + } + + + /* TODO: Should we send WMI command of the connection state? */ + /* avoid multiple auth state change. */ + if (peer->state == state) { +#ifdef TXRX_PRINT_VERBOSE_ENABLE + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO3, + "%s: no state change, returns directly\n", __FUNCTION__); +#endif + adf_os_atomic_dec(&peer->ref_cnt); + return; + } + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, "%s: change from %d to %d\n", + __FUNCTION__, peer->state, state); + + peer->tx_filter = (state == ol_txrx_peer_state_auth) ? + ol_tx_filter_pass_thru : (state == ol_txrx_peer_state_conn) ? + ol_tx_filter_non_auth : ol_tx_filter_discard; + + if (peer->vdev->pdev->cfg.host_addba) { + if (state == ol_txrx_peer_state_auth) { + int tid; + /* + * Pause all regular (non-extended) TID tx queues until data + * arrives and ADDBA negotiation has completed. + */ + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, + "%s: pause peer and unpause mgmt, non-qos\n", __func__); + ol_txrx_peer_pause(peer); /* pause all tx queues */ + /* unpause mgmt and non-QoS tx queues */ + for (tid = OL_TX_NUM_QOS_TIDS; tid < OL_TX_NUM_TIDS; tid++) { + ol_txrx_peer_tid_unpause(peer, tid); + } + } + } + adf_os_atomic_dec(&peer->ref_cnt); + + /* Set the state after the Pause to avoid the race condiction with ADDBA check in tx path */ + peer->state = state; +} + +void +ol_txrx_peer_keyinstalled_state_update( + struct ol_txrx_peer_t *peer, + u_int8_t val) +{ + peer->keyinstalled = val; +} + +void +ol_txrx_peer_update(ol_txrx_vdev_handle vdev, + u_int8_t *peer_mac, + ol_txrx_peer_update_param_t *param, + ol_txrx_peer_update_select_t select) +{ + struct ol_txrx_peer_t *peer; + + peer = ol_txrx_peer_find_hash_find(vdev->pdev, peer_mac, 0, 1); + if (!peer) + { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, "%s: peer is null", __FUNCTION__); + return; + } + + switch (select) { + case ol_txrx_peer_update_qos_capable: + { + /* save qos_capable here txrx peer, + * when HTT_ISOC_T2H_MSG_TYPE_PEER_INFO comes then save. + */ + peer->qos_capable = param->qos_capable; + /* + * The following function call assumes that the peer has a single + * ID. This is currently true, and is expected to remain true. + */ + htt_peer_qos_update( + peer->vdev->pdev->htt_pdev, + peer->peer_ids[0], + peer->qos_capable); + break; + } + case ol_txrx_peer_update_uapsdMask: + { + peer->uapsd_mask = param->uapsd_mask; + htt_peer_uapsdmask_update( + peer->vdev->pdev->htt_pdev, + peer->peer_ids[0], + peer->uapsd_mask); + break; + } + case ol_txrx_peer_update_peer_security: + { + enum ol_sec_type sec_type = param->sec_type; + enum htt_sec_type peer_sec_type = htt_sec_type_none; + + switch(sec_type) { + case ol_sec_type_none: + peer_sec_type = htt_sec_type_none; + break; + case ol_sec_type_wep128: + peer_sec_type = htt_sec_type_wep128; + break; + case ol_sec_type_wep104: + peer_sec_type = htt_sec_type_wep104; + break; + case ol_sec_type_wep40: + peer_sec_type = htt_sec_type_wep40; + break; + case ol_sec_type_tkip: + peer_sec_type = htt_sec_type_tkip; + break; + case ol_sec_type_tkip_nomic: + peer_sec_type = htt_sec_type_tkip_nomic; + break; + case ol_sec_type_aes_ccmp: + peer_sec_type = htt_sec_type_aes_ccmp; + break; + case ol_sec_type_wapi: + peer_sec_type = htt_sec_type_wapi; + break; + default: + peer_sec_type = htt_sec_type_none; + break; + } + + peer->security[txrx_sec_ucast].sec_type = + peer->security[txrx_sec_mcast].sec_type = peer_sec_type; + + break; + } + default: + { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "ERROR: unknown param %d in %s\n", select, __func__); + break; + } + } + adf_os_atomic_dec(&peer->ref_cnt); +} + +u_int8_t +ol_txrx_peer_uapsdmask_get(struct ol_txrx_pdev_t *txrx_pdev, u_int16_t peer_id) +{ + + struct ol_txrx_peer_t *peer; + peer = ol_txrx_peer_find_by_id(txrx_pdev, peer_id); + if (peer) { + return peer->uapsd_mask; + } + + return 0; +} + +u_int8_t +ol_txrx_peer_qoscapable_get (struct ol_txrx_pdev_t * txrx_pdev, u_int16_t peer_id) +{ + + struct ol_txrx_peer_t *peer_t = ol_txrx_peer_find_by_id(txrx_pdev, peer_id); + if (peer_t != NULL) + { + return peer_t->qos_capable; + } + + return 0; +} + +void +ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer) +{ + struct ol_txrx_vdev_t *vdev; + struct ol_txrx_pdev_t *pdev; + int i; + + /* preconditions */ + TXRX_ASSERT2(peer); + + vdev = peer->vdev; + if (NULL == vdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "The vdev is not present anymore\n"); + return; + } + + pdev = vdev->pdev; + if (NULL == pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "The pdev is not present anymore\n"); + return; + } + + /* + * Check for the reference count before deleting the peer + * as we noticed that sometimes we are re-entering this + * function again which is leading to dead-lock. + * (A double-free should never happen, so throw an assertion if it does.) + */ + + if (0 == adf_os_atomic_read(&(peer->ref_cnt)) ) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "The Peer is not present anymore\n"); + adf_os_assert(0); + return; + } + + /* + * Hold the lock all the way from checking if the peer ref count + * is zero until the peer references are removed from the hash + * table and vdev list (if the peer ref count is zero). + * This protects against a new HL tx operation starting to use the + * peer object just after this function concludes it's done being used. + * Furthermore, the lock needs to be held while checking whether the + * vdev's list of peers is empty, to make sure that list is not modified + * concurrently with the empty check. + */ + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + if (adf_os_atomic_dec_and_test(&peer->ref_cnt)) { + u_int16_t peer_id; + + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "Deleting peer %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + + peer_id = peer->local_id; + /* remove the reference to the peer from the hash table */ + ol_txrx_peer_find_hash_remove(pdev, peer); + + /* remove the peer from its parent vdev's list */ + TAILQ_REMOVE(&peer->vdev->peer_list, peer, peer_list_elem); + + /* cleanup the Rx reorder queues for this peer */ + ol_rx_peer_cleanup(vdev, peer); + + /* peer is removed from peer_list */ + adf_os_atomic_set(&peer->delete_in_progress, 0); + + /* Set wait_delete_comp event if the current peer id matches + * with registered peer id. + */ + if (peer_id == vdev->wait_on_peer_id) { + adf_os_complete(&vdev->wait_delete_comp); + vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID; + } + + /* check whether the parent vdev has no peers left */ + if (TAILQ_EMPTY(&vdev->peer_list)) { + /* + * Now that there are no references to the peer, we can + * release the peer reference lock. + */ + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + /* + * Check if the parent vdev was waiting for its peers to be + * deleted, in order for it to be deleted too. + */ + if (vdev->delete.pending) { + ol_txrx_vdev_delete_cb vdev_delete_cb = vdev->delete.callback; + void *vdev_delete_context = vdev->delete.context; + + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s: deleting vdev object %p " + "(%02x:%02x:%02x:%02x:%02x:%02x)" + " - its last peer is done\n", + __func__, vdev, + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], + vdev->mac_addr.raw[2], vdev->mac_addr.raw[3], + vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + /* all peers are gone, go ahead and delete it */ + adf_os_mem_free(vdev); + if (vdev_delete_cb) { + vdev_delete_cb(vdev_delete_context); + } + } + } else { + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + } + + #if defined(CONFIG_HL_SUPPORT) + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + struct ol_tx_frms_queue_t *txq; + + for (i = 0; i < OL_TX_NUM_TIDS; i++) { + txq = &peer->txqs[i]; + ol_tx_queue_free(pdev, txq, i); + } + } + #endif /* defined(CONFIG_HL_SUPPORT) */ + /* + * 'array' is allocated in addba handler and is supposed to be freed + * in delba handler. There is the case (for example, in SSR) where + * delba handler is not called. Because array points to address of + * 'base' by default and is reallocated in addba handler later, only + * free the memory when the array does not point to base. + */ + for (i = 0; i < OL_TXRX_NUM_EXT_TIDS; i++) { + if (peer->tids_rx_reorder[i].array != + &peer->tids_rx_reorder[i].base) { + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s, delete reorder array, tid:%d\n", + __func__, i); + adf_os_mem_free(peer->tids_rx_reorder[i].array); + ol_rx_reorder_init(&peer->tids_rx_reorder[i], (u_int8_t)i); + } + } + + adf_os_mem_free(peer); + } else { + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + } +} + +void +ol_txrx_peer_detach(ol_txrx_peer_handle peer) +{ + struct ol_txrx_vdev_t *vdev = peer->vdev; + + /* redirect the peer's rx delivery function to point to a discard func */ + peer->rx_opt_proc = ol_rx_discard; + + peer->valid = 0; + + OL_TXRX_LOCAL_PEER_ID_FREE(peer->vdev->pdev, peer); + + /* debug print to dump rx reorder state */ + //htt_rx_reorder_log_print(vdev->pdev->htt_pdev); + + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s:peer %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + __func__, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + + if (peer->vdev->last_real_peer == peer) { + peer->vdev->last_real_peer = NULL; + } + + adf_os_spin_lock_bh(&vdev->pdev->last_real_peer_mutex); + if (vdev->last_real_peer == peer) { + vdev->last_real_peer = NULL; + } + adf_os_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex); + htt_rx_reorder_log_print(peer->vdev->pdev->htt_pdev); + + /* set delete_in_progress to identify that wma + * is waiting for unmap massage for this peer */ + adf_os_atomic_set(&peer->delete_in_progress, 1); + /* + * Remove the reference added during peer_attach. + * The peer will still be left allocated until the + * PEER_UNMAP message arrives to remove the other + * reference, added by the PEER_MAP message. + */ + ol_txrx_peer_unref_delete(peer); +} + +ol_txrx_peer_handle +ol_txrx_peer_find_by_addr(struct ol_txrx_pdev_t *pdev, u_int8_t *peer_mac_addr) +{ + struct ol_txrx_peer_t *peer; + peer = ol_txrx_peer_find_hash_find(pdev, peer_mac_addr, 0, 0); + if (peer) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: Delete extra reference %p\n", __func__, peer); + /* release the extra reference */ + ol_txrx_peer_unref_delete(peer); + } + return peer; +} + +int +ol_txrx_get_tx_pending(ol_txrx_pdev_handle pdev_handle) +{ + struct ol_txrx_pdev_t *pdev = (ol_txrx_pdev_handle)pdev_handle; + int total; + + if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) { + total = adf_os_atomic_read(&pdev->orig_target_tx_credit); + } else { + total = ol_cfg_target_tx_credit(pdev->ctrl_pdev); + } + + return (total - pdev->tx_desc.num_free); +} + +void +ol_txrx_discard_tx_pending(ol_txrx_pdev_handle pdev_handle) +{ + ol_tx_desc_list tx_descs; + /* First let hif do the adf_os_atomic_dec_and_test(&tx_desc->ref_cnt) + * then let htt do the adf_os_atomic_dec_and_test(&tx_desc->ref_cnt) + * which is tha same with normal data send complete path*/ + htt_tx_pending_discard(pdev_handle->htt_pdev); + + TAILQ_INIT(&tx_descs); + ol_tx_queue_discard(pdev_handle, A_TRUE, &tx_descs); + //Discard Frames in Discard List + ol_tx_desc_frame_list_free(pdev_handle, &tx_descs, 1 /* error */); + + ol_tx_discard_target_frms(pdev_handle); +} + +/*--- debug features --------------------------------------------------------*/ + +unsigned g_txrx_print_level = TXRX_PRINT_LEVEL_ERR; /* default */ + +void ol_txrx_print_level_set(unsigned level) +{ +#ifndef TXRX_PRINT_ENABLE + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "The driver is compiled without TXRX prints enabled.\n" + "To enable them, recompile with TXRX_PRINT_ENABLE defined.\n"); +#else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "TXRX printout level changed from %d to %d\n", + g_txrx_print_level, level); + g_txrx_print_level = level; +#endif +} + +struct ol_txrx_stats_req_internal { + struct ol_txrx_stats_req base; + int serviced; /* state of this request */ + int offset; +}; + +static inline +u_int64_t OL_TXRX_STATS_PTR_TO_U64(struct ol_txrx_stats_req_internal *req) +{ + return (u_int64_t) ((size_t) req); +} + +static inline +struct ol_txrx_stats_req_internal * OL_TXRX_U64_TO_STATS_PTR(u_int64_t cookie) +{ + return (struct ol_txrx_stats_req_internal *) ((size_t) cookie); +} + +#ifdef ATH_PERF_PWR_OFFLOAD +void +ol_txrx_fw_stats_cfg( + ol_txrx_vdev_handle vdev, + u_int8_t cfg_stats_type, + u_int32_t cfg_val) +{ + u_int64_t dummy_cookie = 0; + htt_h2t_dbg_stats_get( + vdev->pdev->htt_pdev, + 0 /* upload mask */, + 0 /* reset mask */, + cfg_stats_type, + cfg_val, + dummy_cookie); +} + +A_STATUS +ol_txrx_fw_stats_get( + ol_txrx_vdev_handle vdev, + struct ol_txrx_stats_req *req) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + u_int64_t cookie; + struct ol_txrx_stats_req_internal *non_volatile_req; + + if (!pdev || + req->stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS || + req->stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS ) + { + return A_ERROR; + } + + /* + * Allocate a non-transient stats request object. + * (The one provided as an argument is likely allocated on the stack.) + */ + non_volatile_req = adf_os_mem_alloc(pdev->osdev, sizeof(*non_volatile_req)); + if (! non_volatile_req) { + return A_NO_MEMORY; + } + /* copy the caller's specifications */ + non_volatile_req->base = *req; + non_volatile_req->serviced = 0; + non_volatile_req->offset = 0; + + /* use the non-volatile request object's address as the cookie */ + cookie = OL_TXRX_STATS_PTR_TO_U64(non_volatile_req); + + if (htt_h2t_dbg_stats_get( + pdev->htt_pdev, + req->stats_type_upload_mask, + req->stats_type_reset_mask, + HTT_H2T_STATS_REQ_CFG_STAT_TYPE_INVALID, 0, + cookie)) + { + adf_os_mem_free(non_volatile_req); + return A_ERROR; + } + + if (req->wait.blocking) { + while (adf_os_mutex_acquire(pdev->osdev, req->wait.sem_ptr)) {} + } + + return A_OK; +} +#endif +void +ol_txrx_fw_stats_handler( + ol_txrx_pdev_handle pdev, + u_int64_t cookie, + u_int8_t *stats_info_list) +{ + enum htt_dbg_stats_type type; + enum htt_dbg_stats_status status; + int length; + u_int8_t *stats_data; + struct ol_txrx_stats_req_internal *req; + int more = 0; + + req = OL_TXRX_U64_TO_STATS_PTR(cookie); + + do { + htt_t2h_dbg_stats_hdr_parse( + stats_info_list, &type, &status, &length, &stats_data); + if (status == HTT_DBG_STATS_STATUS_SERIES_DONE) { + break; + } + if (status == HTT_DBG_STATS_STATUS_PRESENT || + status == HTT_DBG_STATS_STATUS_PARTIAL) + { + u_int8_t *buf; + int bytes = 0; + + if (status == HTT_DBG_STATS_STATUS_PARTIAL) { + more = 1; + } + if (req->base.print.verbose || req->base.print.concise) { + /* provide the header along with the data */ + htt_t2h_stats_print(stats_info_list, req->base.print.concise); + } + + switch (type) { + case HTT_DBG_STATS_WAL_PDEV_TXRX: + bytes = sizeof(struct wlan_dbg_stats); + if (req->base.copy.buf) { + int limit; + + limit = sizeof(struct wlan_dbg_stats); + if (req->base.copy.byte_limit < limit) { + limit = req->base.copy.byte_limit; + } + buf = req->base.copy.buf + req->offset; + adf_os_mem_copy(buf, stats_data, limit); + } + break; + case HTT_DBG_STATS_RX_REORDER: + bytes = sizeof(struct rx_reorder_stats); + if (req->base.copy.buf) { + int limit; + + limit = sizeof(struct rx_reorder_stats); + if (req->base.copy.byte_limit < limit) { + limit = req->base.copy.byte_limit; + } + buf = req->base.copy.buf + req->offset; + adf_os_mem_copy(buf, stats_data, limit); + } + break; + case HTT_DBG_STATS_RX_RATE_INFO: + bytes = sizeof(wlan_dbg_rx_rate_info_t); + if (req->base.copy.buf) { + int limit; + + limit = sizeof(wlan_dbg_rx_rate_info_t); + if (req->base.copy.byte_limit < limit) { + limit = req->base.copy.byte_limit; + } + buf = req->base.copy.buf + req->offset; + adf_os_mem_copy(buf, stats_data, limit); + } + break; + + case HTT_DBG_STATS_TX_RATE_INFO: + bytes = sizeof(wlan_dbg_tx_rate_info_t); + if (req->base.copy.buf) { + int limit; + + limit = sizeof(wlan_dbg_tx_rate_info_t); + if (req->base.copy.byte_limit < limit) { + limit = req->base.copy.byte_limit; + } + buf = req->base.copy.buf + req->offset; + adf_os_mem_copy(buf, stats_data, limit); + } + break; + + case HTT_DBG_STATS_TX_PPDU_LOG: + bytes = 0; /* TO DO: specify how many bytes are present */ + /* TO DO: add copying to the requestor's buffer */ + break; + + case HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO: + + bytes = sizeof(struct rx_remote_buffer_mgmt_stats); + if (req->base.copy.buf) { + int limit; + + limit = sizeof(struct rx_remote_buffer_mgmt_stats); + if (req->base.copy.byte_limit < limit) { + limit = req->base.copy.byte_limit; + } + buf = req->base.copy.buf + req->offset; + adf_os_mem_copy(buf, stats_data, limit); + } + break; + + default: + break; + } + buf = req->base.copy.buf ? req->base.copy.buf : stats_data; + if (req->base.callback.fp) { + req->base.callback.fp( + req->base.callback.ctxt, type, buf, bytes); + } + } + stats_info_list += length; + } while (1); + + if (! more) { + if (req->base.wait.blocking) { + adf_os_mutex_release(pdev->osdev, req->base.wait.sem_ptr); + } + adf_os_mem_free(req); + } +} + +#ifndef ATH_PERF_PWR_OFFLOAD /*---------------------------------------------*/ +int ol_txrx_debug(ol_txrx_vdev_handle vdev, int debug_specs) +{ + if (debug_specs & TXRX_DBG_MASK_OBJS) { + #if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5 + ol_txrx_pdev_display(vdev->pdev, 0); + #else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "The pdev,vdev,peer display functions are disabled.\n" + "To enable them, recompile with TXRX_DEBUG_LEVEL > 5.\n"); + #endif + } + if (debug_specs & TXRX_DBG_MASK_STATS) { + #if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF + ol_txrx_stats_display(vdev->pdev); + #else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "txrx stats collection is disabled.\n" + "To enable it, recompile with TXRX_STATS_LEVEL on.\n"); + #endif + } + if (debug_specs & TXRX_DBG_MASK_PROT_ANALYZE) { + #if defined(ENABLE_TXRX_PROT_ANALYZE) + ol_txrx_prot_ans_display(vdev->pdev); + #else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "txrx protocol analysis is disabled.\n" + "To enable it, recompile with " + "ENABLE_TXRX_PROT_ANALYZE defined.\n"); + #endif + } + if (debug_specs & TXRX_DBG_MASK_RX_REORDER_TRACE) { + #if defined(ENABLE_RX_REORDER_TRACE) + ol_rx_reorder_trace_display(vdev->pdev, 0, 0); + #else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, + "rx reorder seq num trace is disabled.\n" + "To enable it, recompile with " + "ENABLE_RX_REORDER_TRACE defined.\n"); + #endif + + } + return 0; +} +#endif + +int ol_txrx_aggr_cfg(ol_txrx_vdev_handle vdev, + int max_subfrms_ampdu, + int max_subfrms_amsdu) +{ + return htt_h2t_aggr_cfg_msg(vdev->pdev->htt_pdev, + max_subfrms_ampdu, + max_subfrms_amsdu); +} + +#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5 +void +ol_txrx_pdev_display(ol_txrx_pdev_handle pdev, int indent) +{ + struct ol_txrx_vdev_t *vdev; + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*s%s:\n", indent, " ", "txrx pdev"); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*spdev object: %p\n", indent+4, " ", pdev); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*svdev list:\n", indent+4, " "); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + ol_txrx_vdev_display(vdev, indent+8); + } + ol_txrx_peer_find_display(pdev, indent+4); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*stx desc pool: %d elems @ %p\n", indent+4, " ", + pdev->tx_desc.pool_size, pdev->tx_desc.array); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, "\n"); + htt_display(pdev->htt_pdev, indent); +} + +void +ol_txrx_vdev_display(ol_txrx_vdev_handle vdev, int indent) +{ + struct ol_txrx_peer_t *peer; + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*stxrx vdev: %p\n", indent, " ", vdev); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*sID: %d\n", indent+4, " ", vdev->vdev_id); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*sMAC addr: %d:%d:%d:%d:%d:%d\n", + indent+4, " ", + vdev->mac_addr.raw[0], vdev->mac_addr.raw[1], vdev->mac_addr.raw[2], + vdev->mac_addr.raw[3], vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*speer list:\n", indent+4, " "); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + ol_txrx_peer_display(peer, indent+8); + } +} + +void +ol_txrx_peer_display(ol_txrx_peer_handle peer, int indent) +{ + int i; + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*stxrx peer: %p\n", indent, " ", peer); + for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) { + if (peer->peer_ids[i] != HTT_INVALID_PEER) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*sID: %d\n", indent+4, " ", peer->peer_ids[i]); + } + } +} +#endif /* TXRX_DEBUG_LEVEL */ + +#if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF +void +ol_txrx_stats_display(ol_txrx_pdev_handle pdev) +{ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, "txrx stats:\n"); + if (TXRX_STATS_LEVEL == TXRX_STATS_LEVEL_BASIC) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " tx: %lld msdus (%lld B)\n", + pdev->stats.pub.tx.delivered.pkts, + pdev->stats.pub.tx.delivered.bytes); + } else { /* full */ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " tx: sent %lld msdus (%lld B), " + "rejected %lld (%lld B), dropped %lld (%lld B)\n", + pdev->stats.pub.tx.delivered.pkts, + pdev->stats.pub.tx.delivered.bytes, + pdev->stats.pub.tx.dropped.host_reject.pkts, + pdev->stats.pub.tx.dropped.host_reject.bytes, + pdev->stats.pub.tx.dropped.download_fail.pkts + + pdev->stats.pub.tx.dropped.target_discard.pkts + + pdev->stats.pub.tx.dropped.no_ack.pkts, + pdev->stats.pub.tx.dropped.download_fail.bytes + + pdev->stats.pub.tx.dropped.target_discard.bytes + + pdev->stats.pub.tx.dropped.no_ack.bytes); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " download fail: %lld (%lld B), " + "target discard: %lld (%lld B), " + "no ack: %lld (%lld B)\n", + pdev->stats.pub.tx.dropped.download_fail.pkts, + pdev->stats.pub.tx.dropped.download_fail.bytes, + pdev->stats.pub.tx.dropped.target_discard.pkts, + pdev->stats.pub.tx.dropped.target_discard.bytes, + pdev->stats.pub.tx.dropped.no_ack.pkts, + pdev->stats.pub.tx.dropped.no_ack.bytes); + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " rx: %lld ppdus, %lld mpdus, %lld msdus, %lld bytes, %lld errs\n", + pdev->stats.priv.rx.normal.ppdus, + pdev->stats.priv.rx.normal.mpdus, + pdev->stats.pub.rx.delivered.pkts, + pdev->stats.pub.rx.delivered.bytes, + pdev->stats.priv.rx.err.mpdu_bad); + if (TXRX_STATS_LEVEL == TXRX_STATS_LEVEL_FULL) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " forwarded %lld msdus, %lld bytes\n", + pdev->stats.pub.rx.forwarded.pkts, + pdev->stats.pub.rx.forwarded.bytes); + } +} + +int +ol_txrx_stats_publish(ol_txrx_pdev_handle pdev, struct ol_txrx_stats *buf) +{ + adf_os_assert(buf); + adf_os_assert(pdev); + adf_os_mem_copy(buf, &pdev->stats.pub, sizeof(pdev->stats.pub)); + return TXRX_STATS_LEVEL; +} +#endif /* TXRX_STATS_LEVEL */ + +#if defined(ENABLE_TXRX_PROT_ANALYZE) + +void +ol_txrx_prot_ans_display(ol_txrx_pdev_handle pdev) +{ + ol_txrx_prot_an_display(pdev->prot_an_tx_sent); + ol_txrx_prot_an_display(pdev->prot_an_rx_sent); +} + +#endif /* ENABLE_TXRX_PROT_ANALYZE */ + +#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI +int16_t +ol_txrx_peer_rssi(ol_txrx_peer_handle peer) +{ + return (peer->rssi_dbm == HTT_RSSI_INVALID) ? + OL_TXRX_RSSI_INVALID : peer->rssi_dbm; +} +#endif /* #ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI */ + +#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS +A_STATUS +ol_txrx_peer_stats_copy( + ol_txrx_pdev_handle pdev, + ol_txrx_peer_handle peer, + ol_txrx_peer_stats_t *stats) +{ + adf_os_assert(pdev && peer && stats); + adf_os_spin_lock_bh(&pdev->peer_stat_mutex); + adf_os_mem_copy(stats, &peer->stats, sizeof(*stats)); + adf_os_spin_unlock_bh(&pdev->peer_stat_mutex); + return A_OK; +} +#endif /* QCA_ENABLE_OL_TXRX_PEER_STATS */ + +void +ol_vdev_rx_set_intrabss_fwd( + ol_txrx_vdev_handle vdev, + a_bool_t val) +{ + if (NULL == vdev) + return; + + vdev->disable_intrabss_fwd = val; +} + +#ifdef QCA_LL_TX_FLOW_CT +a_bool_t +ol_txrx_get_tx_resource( + ol_txrx_vdev_handle vdev, + unsigned int low_watermark, + unsigned int high_watermark_offset +) +{ + adf_os_spin_lock_bh(&vdev->pdev->tx_mutex); + if (vdev->pdev->tx_desc.num_free < (u_int16_t)low_watermark) { + vdev->tx_fl_lwm = (u_int16_t)low_watermark; + vdev->tx_fl_hwm = (u_int16_t)(low_watermark + high_watermark_offset); + /* Not enough free resource, stop TX OS Q */ + adf_os_atomic_set(&vdev->os_q_paused, 1); + adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex); + return A_FALSE; + } + adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex); + return A_TRUE; +} + +void +ol_txrx_ll_set_tx_pause_q_depth( + ol_txrx_vdev_handle vdev, + int pause_q_depth +) +{ + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + vdev->ll_pause.max_q_depth = pause_q_depth; + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef IPA_UC_OFFLOAD +void +ol_txrx_ipa_uc_get_resource( + ol_txrx_pdev_handle pdev, + u_int32_t *ce_sr_base_paddr, + u_int32_t *ce_sr_ring_size, + u_int32_t *ce_reg_paddr, + u_int32_t *tx_comp_ring_base_paddr, + u_int32_t *tx_comp_ring_size, + u_int32_t *tx_num_alloc_buffer, + u_int32_t *rx_rdy_ring_base_paddr, + u_int32_t *rx_rdy_ring_size, + u_int32_t *rx_proc_done_idx_paddr +) +{ + htt_ipa_uc_get_resource(pdev->htt_pdev, + ce_sr_base_paddr, + ce_sr_ring_size, + ce_reg_paddr, + tx_comp_ring_base_paddr, + tx_comp_ring_size, + tx_num_alloc_buffer, + rx_rdy_ring_base_paddr, + rx_rdy_ring_size, + rx_proc_done_idx_paddr); +} + +void +ol_txrx_ipa_uc_set_doorbell_paddr( + ol_txrx_pdev_handle pdev, + u_int32_t ipa_tx_uc_doorbell_paddr, + u_int32_t ipa_rx_uc_doorbell_paddr +) +{ + htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev, + ipa_tx_uc_doorbell_paddr, + ipa_rx_uc_doorbell_paddr); +} + +void +ol_txrx_ipa_uc_set_active( + ol_txrx_pdev_handle pdev, + a_bool_t uc_active, + a_bool_t is_tx +) +{ + htt_h2t_ipa_uc_set_active(pdev->htt_pdev, + uc_active, + is_tx); +} + +void +ol_txrx_ipa_uc_op_response( + ol_txrx_pdev_handle pdev, + u_int8_t *op_msg +) +{ + if (pdev->ipa_uc_op_cb) { + pdev->ipa_uc_op_cb(op_msg, pdev->osif_dev); + } +} + +void ol_txrx_ipa_uc_register_op_cb( + ol_txrx_pdev_handle pdev, + ipa_uc_op_cb_type op_cb, + void *osif_dev) +{ + pdev->ipa_uc_op_cb = op_cb; + pdev->osif_dev = osif_dev; +} + +void ol_txrx_ipa_uc_get_stat(ol_txrx_pdev_handle pdev) +{ + htt_h2t_ipa_uc_get_stats(pdev->htt_pdev); +} + +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.h new file mode 100644 index 0000000000000..8109c75cbee7d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_TXRX__H_ +#define _OL_TXRX__H_ + +#include /* adf_nbuf_t */ +#include /* ol_txrx_vdev_t, etc. */ +#include /* ol_pdev_handle */ + +void +ol_txrx_peer_unref_delete(struct ol_txrx_peer_t *peer); + +u_int16_t +ol_tx_desc_pool_size_hl(ol_pdev_handle ctrl_pdev); + + +#ifndef OL_TX_AVG_FRM_BYTES +#define OL_TX_AVG_FRM_BYTES 1000 +#endif + +#ifndef OL_TX_DESC_POOL_SIZE_MIN_HL +#define OL_TX_DESC_POOL_SIZE_MIN_HL 500 +#endif + +#ifndef OL_TX_DESC_POOL_SIZE_MAX_HL +#define OL_TX_DESC_POOL_SIZE_MAX_HL 5000 +#endif + +#ifdef CONFIG_PER_VDEV_TX_DESC_POOL +#define TXRX_HL_TX_FLOW_CTRL_VDEV_LOW_WATER_MARK 400 +#define TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED 100 +#endif + +#endif /* _OL_TXRX__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.c new file mode 100644 index 0000000000000..f2d5ac2b64989 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_encap.c + * @brief Provide functions to encap/decap on txrx frames. + * @details + * This file contains functions for data frame encap/decap: + * ol_tx_encap: encap outgoing data frames. + * ol_rx_decap: decap incoming data frames. + */ +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + +#include /* adf_nbuf_t, etc. */ +#include /* ieee80211_frame */ +#include /* struct llc,struct struct ether_header, etc. */ +#include /* TXRX_ASSERT1 */ +#include /* struct ol_txrx_vdev_t,struct ol_txrx_pdev_t,etc. */ +#include /* struct ol_rx_decap_info_t*/ + +#define OL_TX_COPY_NATIVE_WIFI_HEADER(wh, msdu, hdsize, localbuf) \ + do { \ + wh = (struct ieee80211_frame*)adf_nbuf_data(msdu); \ + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { \ + hdsize = sizeof(struct ieee80211_frame_addr4); \ + } else { \ + hdsize = sizeof(struct ieee80211_frame); \ + } \ + if ( adf_nbuf_len(msdu) < hdsize) { \ + return A_ERROR; \ + } \ + adf_os_mem_copy(localbuf, wh, hdsize); \ + wh = (struct ieee80211_frame*)localbuf; \ + } while (0); + +static inline A_STATUS +ol_tx_copy_native_wifi_header( + adf_nbuf_t msdu, + u_int8_t *hdsize, + u_int8_t *localbuf) +{ + struct ieee80211_frame *wh = (struct ieee80211_frame*)adf_nbuf_data(msdu); + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { + *hdsize = sizeof(struct ieee80211_frame_addr4); + } else { + *hdsize = sizeof(struct ieee80211_frame); + } + if (adf_nbuf_len(msdu) < *hdsize) { + return A_ERROR; + } + adf_os_mem_copy(localbuf, wh, *hdsize); + return A_OK; +} + +static inline A_STATUS +ol_tx_encap_from_native_wifi ( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + struct ol_txrx_msdu_info_t *tx_msdu_info +) +{ + u_int8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4)]; + struct ieee80211_frame *wh; + u_int8_t hdsize, new_hdsize; + struct ieee80211_qoscntl *qos_cntl; + struct ol_txrx_peer_t *peer; + + if (tx_msdu_info->htt.info.frame_type != htt_frm_type_data) { + return A_OK; + } + peer = tx_msdu_info->peer; + /* + * for unicast,the peer should not be NULL. + * for multicast, the peer is AP. + */ + if (tx_msdu_info->htt.info.is_unicast + && peer->qos_capable) + { + if (A_OK != ol_tx_copy_native_wifi_header(msdu, &hdsize, localbuf)) + return A_ERROR; + wh = (struct ieee80211_frame*)localbuf; + + /*add qos cntl*/ + qos_cntl = (struct ieee80211_qoscntl*)(localbuf + hdsize); + qos_cntl->i_qos[0] = tx_msdu_info->htt.info.ext_tid & IEEE80211_QOS_TID; + +#if 0 + if ( wmmParam[ac].wmep_noackPolicy ) { + qos_cntl->i_qos[0]|= 1 << IEEE80211_QOS_ACKPOLICY_S; + } +#endif + + qos_cntl->i_qos[1] = 0; + wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS; + /* count for qos field */ + new_hdsize = hdsize + sizeof(struct ieee80211_qosframe) - sizeof(struct ieee80211_frame); + + /*add ht control field if needed */ + + /* copy new hd to bd */ + adf_os_mem_copy( + (void*)htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, new_hdsize), + localbuf, + new_hdsize); + adf_nbuf_pull_head(msdu, hdsize); + tx_msdu_info->htt.info.l3_hdr_offset = new_hdsize; + tx_desc->orig_l2_hdr_bytes = hdsize; + } + /* Set Protected Frame bit in MAC header */ + if (vdev->pdev->sw_pf_proc_enable && tx_msdu_info->htt.action.do_encrypt) { + if (tx_desc->orig_l2_hdr_bytes) { + wh = (struct ieee80211_frame*)htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, + tx_msdu_info->htt.info.l3_hdr_offset); + } else { + if (A_OK != ol_tx_copy_native_wifi_header(msdu, &hdsize, localbuf)) + return A_ERROR; + wh = (struct ieee80211_frame*)htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc, hdsize); + adf_os_mem_copy((void*)wh, localbuf, hdsize); + adf_nbuf_pull_head(msdu, hdsize); + tx_msdu_info->htt.info.l3_hdr_offset = hdsize; + tx_desc->orig_l2_hdr_bytes = hdsize; + } + wh->i_fc[1] |= IEEE80211_FC1_WEP; + } + return A_OK; +} + +static inline A_STATUS +ol_tx_encap_from_8023 ( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + struct ol_txrx_msdu_info_t *tx_msdu_info +) +{ + u_int8_t localbuf[ sizeof(struct ieee80211_qosframe_htc_addr4) \ + + sizeof(struct llc_snap_hdr_t)]; + struct llc_snap_hdr_t *llc_hdr; + struct ethernet_hdr_t *eth_hdr; + struct ieee80211_frame *wh; + u_int8_t hdsize, new_l2_hdsize, new_hdsize; + struct ieee80211_qoscntl *qos_cntl; + const u_int8_t ethernet_II_llc_snap_header_prefix[] = \ + { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; + struct ol_txrx_peer_t *peer; + u_int16_t ether_type; + + if (tx_msdu_info->htt.info.frame_type != htt_frm_type_data) + return A_OK; + + /* + * for unicast,the peer should not be NULL. + * for multicast, the peer is AP. + */ + peer = tx_msdu_info->peer; + + eth_hdr = (struct ethernet_hdr_t *)adf_nbuf_data(msdu); + hdsize = sizeof(struct ethernet_hdr_t); + wh = (struct ieee80211_frame *)localbuf; + wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; + *(u_int16_t *)wh->i_dur = 0; + new_hdsize = 0; + + switch (vdev->opmode) { + case wlan_op_mode_ap: + /* DA , BSSID , SA*/ + adf_os_mem_copy(wh->i_addr1, eth_hdr->dest_addr, + IEEE80211_ADDR_LEN); + adf_os_mem_copy(wh->i_addr2, &vdev->mac_addr.raw, + IEEE80211_ADDR_LEN); + adf_os_mem_copy(wh->i_addr3, eth_hdr->src_addr, + IEEE80211_ADDR_LEN); + wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS; + new_hdsize = sizeof(struct ieee80211_frame); + break; + case wlan_op_mode_ibss: + /* DA, SA, BSSID */ + adf_os_mem_copy(wh->i_addr1, eth_hdr->dest_addr, + IEEE80211_ADDR_LEN); + adf_os_mem_copy(wh->i_addr2, eth_hdr->src_addr, + IEEE80211_ADDR_LEN); + /* need to check the bssid behaviour for IBSS vdev */ + adf_os_mem_copy(wh->i_addr3, &vdev->mac_addr.raw, + IEEE80211_ADDR_LEN); + wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; + new_hdsize = sizeof(struct ieee80211_frame); + break; + case wlan_op_mode_sta: + /* BSSID, SA , DA*/ + adf_os_mem_copy(wh->i_addr1, &peer->mac_addr.raw, + IEEE80211_ADDR_LEN); + adf_os_mem_copy(wh->i_addr2, eth_hdr->src_addr, + IEEE80211_ADDR_LEN); + adf_os_mem_copy(wh->i_addr3, eth_hdr->dest_addr, + IEEE80211_ADDR_LEN); + wh->i_fc[1] = IEEE80211_FC1_DIR_TODS; + new_hdsize = sizeof(struct ieee80211_frame); + break; + case wlan_op_mode_monitor: + default: + return A_ERROR; + } + /*add qos cntl*/ + if (tx_msdu_info->htt.info.is_unicast && peer->qos_capable ) { + qos_cntl = (struct ieee80211_qoscntl*)(localbuf + new_hdsize); + qos_cntl->i_qos[0] = tx_msdu_info->htt.info.ext_tid & IEEE80211_QOS_TID; + wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS; +#if 0 + if ( wmmParam[ac].wmep_noackPolicy ) { + qos_cntl->i_qos[0]|= 1 << IEEE80211_QOS_ACKPOLICY_S; + } +#endif + qos_cntl->i_qos[1] = 0; + new_hdsize += sizeof(struct ieee80211_qoscntl); + + /*add ht control field if needed */ + } + /* Set Protected Frame bit in MAC header */ + if (vdev->pdev->sw_pf_proc_enable && tx_msdu_info->htt.action.do_encrypt) { + wh->i_fc[1] |= IEEE80211_FC1_WEP; + } + new_l2_hdsize = new_hdsize; + /* add llc snap if needed */ + if (vdev->pdev->sw_tx_llc_proc_enable) { + llc_hdr = (struct llc_snap_hdr_t *) (localbuf + new_hdsize); + ether_type = (eth_hdr->ethertype[0]<<8) |(eth_hdr->ethertype[1]); + if ( ether_type >= IEEE8023_MAX_LEN ) { + adf_os_mem_copy(llc_hdr, + ethernet_II_llc_snap_header_prefix, + sizeof(ethernet_II_llc_snap_header_prefix)); + if ( ether_type == ETHERTYPE_AARP || ether_type == ETHERTYPE_IPX) { + llc_hdr->org_code[2] = BTEP_SNAP_ORGCODE_2;// 0xf8; bridge tunnel header + } + llc_hdr->ethertype[0] = eth_hdr->ethertype[0]; + llc_hdr->ethertype[1] = eth_hdr->ethertype[1]; + new_hdsize += sizeof(struct llc_snap_hdr_t); + } + else { + /*llc ready, and it's in payload pdu, do we need to move to BD pdu?*/ + } + } + adf_os_mem_copy( + (void*)htt_tx_desc_mpdu_header(tx_desc->htt_tx_desc,new_l2_hdsize), + localbuf, + new_hdsize); + adf_nbuf_pull_head(msdu,hdsize); + tx_msdu_info->htt.info.l3_hdr_offset = new_l2_hdsize; + tx_desc->orig_l2_hdr_bytes = hdsize; + return A_OK; +} + +A_STATUS +ol_tx_encap( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + struct ol_txrx_msdu_info_t *msdu_info) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + return ol_tx_encap_from_native_wifi(vdev, tx_desc, msdu,msdu_info); + } else if (pdev->frame_format == wlan_frm_fmt_802_3) { + return ol_tx_encap_from_8023(vdev, tx_desc, msdu, msdu_info); + } else { + /* todo for other types */ + return A_ERROR; + } +} + +static inline void +ol_rx_decap_to_native_wifi( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info, + struct ethernet_hdr_t *ethr_hdr) +{ + struct ieee80211_frame_addr4 *wh; + u_int16_t hdsize; + + /* + * we need to remove Qos control field and HT control. + * MSFT: http://msdn.microsoft.com/en-us/library/windows/hardware/ff552608(v=vs.85).aspx + */ + wh = (struct ieee80211_frame_addr4 *)info->hdr; + if ( (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { + hdsize = sizeof(struct ieee80211_frame_addr4); + } + else { + hdsize = sizeof(struct ieee80211_frame); + } + wh = (struct ieee80211_frame_addr4 *) adf_nbuf_push_head(msdu, hdsize); + TXRX_ASSERT2(wh != NULL); + TXRX_ASSERT2(hdsize <= info->hdr_len); + adf_os_mem_copy ((u_int8_t *)wh, info->hdr, hdsize); + + /* amsdu subfrm handling if ethr_hdr is not NULL */ + if (ethr_hdr != NULL) { + switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { + case IEEE80211_FC1_DIR_NODS: + adf_os_mem_copy(wh->i_addr1, ethr_hdr->dest_addr, ETHERNET_ADDR_LEN); + adf_os_mem_copy(wh->i_addr2, ethr_hdr->src_addr, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_TODS: + adf_os_mem_copy(wh->i_addr2, ethr_hdr->src_addr, ETHERNET_ADDR_LEN); + adf_os_mem_copy(wh->i_addr3, ethr_hdr->dest_addr, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_FROMDS: + adf_os_mem_copy(wh->i_addr1, ethr_hdr->dest_addr, ETHERNET_ADDR_LEN); + adf_os_mem_copy(wh->i_addr3, ethr_hdr->src_addr, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_DSTODS: + adf_os_mem_copy(wh->i_addr3, ethr_hdr->dest_addr, ETHERNET_ADDR_LEN); + adf_os_mem_copy(wh->i_addr4, ethr_hdr->src_addr, ETHERNET_ADDR_LEN); + break; + } + } + if (IEEE80211_QOS_HAS_SEQ(wh) ) { + if (wh->i_fc[1] & IEEE80211_FC1_ORDER) { + wh->i_fc[1] &= ~IEEE80211_FC1_ORDER; + } + wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS; + } +} + +static inline void +ol_rx_decap_to_8023 ( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info, + struct ethernet_hdr_t *ethr_hdr) +{ + struct llc_snap_hdr_t *llc_hdr; + u_int16_t ether_type; + u_int16_t l2_hdr_space; + struct ieee80211_frame_addr4 *wh; + u_int8_t local_buf[ETHERNET_HDR_LEN]; + u_int8_t *buf; + + /* + * populate Ethernet header, + * if ethr_hdr is null, rx frame is 802.11 format(HW ft disabled) + * if ethr_hdr is not null, rx frame is "subfrm of amsdu". + */ + buf = (u_int8_t *)adf_nbuf_data(msdu); + llc_hdr = (struct llc_snap_hdr_t *)buf; + ether_type = (llc_hdr->ethertype[0] << 8)|llc_hdr->ethertype[1]; + /* do llc remove if needed */ + l2_hdr_space = 0; + if (IS_SNAP(llc_hdr)) { + if (IS_BTEP(llc_hdr)) { + /* remove llc*/ + l2_hdr_space += sizeof(struct llc_snap_hdr_t); + llc_hdr = NULL; + } + else if (IS_RFC1042(llc_hdr)) { + if ( !(ether_type == ETHERTYPE_AARP || + ether_type == ETHERTYPE_IPX) ) { + /* remove llc*/ + l2_hdr_space += sizeof(struct llc_snap_hdr_t); + llc_hdr = NULL; + } + } + } + if (l2_hdr_space > ETHERNET_HDR_LEN) { + buf = adf_nbuf_pull_head(msdu, l2_hdr_space - ETHERNET_HDR_LEN); + } + else if (l2_hdr_space < ETHERNET_HDR_LEN) { + buf = adf_nbuf_push_head(msdu, ETHERNET_HDR_LEN - l2_hdr_space); + } + + /* normal msdu(non-subfrm of A-MSDU) if ethr_hdr is null */ + if (ethr_hdr == NULL) { + /* mpdu hdr should be present in info,re-create ethr_hdr based on mpdu hdr*/ + TXRX_ASSERT2(info->hdr_len != 0); + wh = (struct ieee80211_frame_addr4 *)info->hdr; + ethr_hdr = (struct ethernet_hdr_t *)local_buf; + switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { + case IEEE80211_FC1_DIR_NODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr1, ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr2, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_TODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr3, ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr2, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_FROMDS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr1, ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr3, ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_DSTODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr3, ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr4, ETHERNET_ADDR_LEN); + break; + } + } + if (llc_hdr == NULL) { + ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff; + ethr_hdr->ethertype[1] = (ether_type) & 0xff; + } + else { + u_int32_t pktlen = adf_nbuf_len(msdu) - sizeof(ethr_hdr->ethertype); + TXRX_ASSERT2(pktlen <= ETHERNET_MTU); + ether_type = (u_int16_t)pktlen; + ether_type = adf_nbuf_len(msdu) - sizeof(struct ethernet_hdr_t); + ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff; + ethr_hdr->ethertype[1] = (ether_type) & 0xff; + } + adf_os_mem_copy(buf, ethr_hdr, ETHERNET_HDR_LEN); +} + +static inline A_STATUS +ol_rx_decap_subfrm_amsdu( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + u_int8_t * subfrm_hdr; + u_int8_t localbuf[ETHERNET_HDR_LEN]; + struct ethernet_hdr_t *ether_hdr = (struct ethernet_hdr_t*)localbuf; + + subfrm_hdr = (u_int8_t *)adf_nbuf_data(msdu); + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + /* decap to native wifi */ + adf_os_mem_copy(ether_hdr, + subfrm_hdr, + ETHERNET_HDR_LEN); + adf_nbuf_pull_head(msdu, ETHERNET_HDR_LEN); + ol_rx_decap_to_native_wifi(vdev, + msdu, + info, + ether_hdr); + } + else if (pdev->frame_format == wlan_frm_fmt_802_3) { + if (pdev->sw_rx_llc_proc_enable) { + /* remove llc snap hdr if it's necessary according to + * 802.11 table P-3 + */ + adf_os_mem_copy(ether_hdr, + subfrm_hdr, + ETHERNET_HDR_LEN); + adf_nbuf_pull_head(msdu, ETHERNET_HDR_LEN); + ol_rx_decap_to_8023(vdev, + msdu, + info, + ether_hdr); + } + else { + /* subfrm of A-MSDU is already in 802.3 format. + * if target HW or FW has done LLC rmv process, + * we do nothing here. + */ + } + } + else { + /* todo for othertype*/ + } + return A_OK; + +} + +static inline A_STATUS +ol_rx_decap_msdu( + struct ol_txrx_vdev_t *vdev, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + struct ieee80211_frame *wh; + wh = (struct ieee80211_frame *)adf_nbuf_data(msdu); + + if (pdev->frame_format == wlan_frm_fmt_native_wifi) { + /* Decap to native wifi because according to MSFT( + * MSFT: http://msdn.microsoft.com/en-us/library/windows/hardware/ff552608(v=vs.85).aspx), + * we need to remove Qos and HTC field before indicate to OS. + */ + if (IEEE80211_QOS_HAS_SEQ(wh) ) { + info->hdr_len = ol_txrx_ieee80211_hdrsize(wh); + TXRX_ASSERT2(info->hdr_len <= sizeof(info->hdr)); + adf_os_mem_copy(info->hdr, /* use info->hdr as temp buf.*/ + wh, + info->hdr_len); + adf_nbuf_pull_head(msdu, info->hdr_len); + ol_rx_decap_to_native_wifi(vdev, + msdu, + info, /* 802.11 hdr*/ + NULL); /* ethernet hdr*/ + } + } + else if (pdev->frame_format == wlan_frm_fmt_802_3) { + if (pdev->sw_rx_llc_proc_enable) { + info->hdr_len = ol_txrx_ieee80211_hdrsize(wh); + TXRX_ASSERT2(info->hdr_len <= sizeof(info->hdr)); + adf_os_mem_copy(info->hdr, /* use info->hdr as temp buf.*/ + wh, + info->hdr_len); + adf_nbuf_pull_head(msdu, info->hdr_len); + /* remove llc snap hdr if it's necessary according to + * 802.11 table P-3 + */ + ol_rx_decap_to_8023(vdev, + msdu, + info, /* 802.11 hdr*/ + NULL); /* ethernet hdr*/ + } + else { + /* Subfrm of A-MSDU is already in 802.3 format. + * And if target HW or FW has done LLC rmv process ( + * sw_rx_lc_proc_enable == 0), we do nothing here. + */ + } + } + else { + /* todo for othertype*/ + } + return A_OK; + +} + +A_STATUS +ol_rx_decap( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info) +{ + A_STATUS status; + u_int8_t *mpdu_hdr; + + if (!info->is_subfrm) { + if (info->is_msdu_cmpl_mpdu && !info->is_first_subfrm) { + /* It's normal MSDU. */ + } else { + /* It's a first subfrm of A-MSDU and may also be the last subfrm of A-MSDU */ + info->is_subfrm = 1; + info->hdr_len = 0; + if (vdev->pdev->sw_subfrm_hdr_recovery_enable) { + /* we save the first subfrm mpdu hdr for subsequent + * subfrm 802.11 header recovery in certain chip(such as Riva). + */ + mpdu_hdr = adf_nbuf_data(msdu); + info->hdr_len = ol_txrx_ieee80211_hdrsize(mpdu_hdr); + TXRX_ASSERT2(info->hdr_len <= sizeof(info->hdr)); + adf_os_mem_copy(info->hdr, mpdu_hdr, info->hdr_len); + adf_nbuf_pull_head(msdu, info->hdr_len); + } + } + } + + if (info->is_subfrm && vdev->pdev->sw_subfrm_hdr_recovery_enable) { + /* + * This case is enabled for some HWs(such as Riva).The HW de-aggregate + * doesn't have capability to generate 802.11 header for non-first subframe + * of A-MSDU.That means sw needs to cache the first subfrm mpdu header + * to generate the subsequent subfrm's 802.11 header. + */ + TXRX_ASSERT2(info->hdr_len != 0); + status = ol_rx_decap_subfrm_amsdu(vdev, msdu, info); + } else { + status = ol_rx_decap_msdu(vdev, msdu, info); + } + + if (info->is_msdu_cmpl_mpdu) { + info->is_subfrm = + info->is_first_subfrm = + info->hdr_len = 0; + } + return status; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.h new file mode 100644 index 0000000000000..9d7590e329ef4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_encap.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_encap.h + * @brief definitions for txrx encap/decap function and struct + */ +#ifndef _OL_TXRX_ENCAP__H_ +#define _OL_TXRX_ENCAP__H_ + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + +#include /* adf_nbuf_t */ +#include /* ieee80211_qosframe_htc_addr4 */ +#include /* ol_tx_desc_t, ol_txrx_msdu_info_t */ + +/** + * @brief Encap outgoing frm from OS dependent format to Target + * acceptable frm format + * @details + * For native wifi format, the function will add Qos control field + * based on peer's QOS capbabilities . + * For 802.3 format, the function will transform to 802.11 format + * with or without QOS control field based on peer's QOS capabilites. + * @param vdev - handle to vdev object + * @param tx_desc - tx desc struct,some fields will be updated. + * @param msdu - adf_nbuf_t + * @param msdu_info - informations from tx classification. + * @return + * A_OK: encap operation sucessful + * other: operation failed,the msdu need be dropped. + */ +A_STATUS +ol_tx_encap( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + struct ol_txrx_msdu_info_t *msdu_info); + + +struct ol_rx_decap_info_t { + u_int8_t hdr[sizeof(struct ieee80211_qosframe_htc_addr4)]; + int hdr_len; + u_int8_t is_subfrm : 1, + is_first_subfrm :1, + is_msdu_cmpl_mpdu : 1; +}; + +/** + * @brief decap incoming frm from Target to Host OS + * acceptable frm format + * @details + * For native wifi format, the function will remove Qos control field + * and HT control field if any. + * For 802.3 format, the function will will do llc snap header process + * if Target haven't done that. + * @param vdev - handle to vdev object + * @param peer - the peer object. + * @param msdu - adf_nbuf_t + * @param info - ol_rx_decap_info_t: context info for decap + * @return + * A_OK: decap operation sucessful + * other: operation failed,the msdu need be dropped. + */ +A_STATUS +ol_rx_decap ( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info); + + +static inline A_STATUS +OL_TX_ENCAP( + struct ol_txrx_vdev_t *vdev, + struct ol_tx_desc_t *tx_desc, + adf_nbuf_t msdu, + struct ol_txrx_msdu_info_t *msdu_info) +{ + if (vdev->pdev->sw_tx_encap) { + return ol_tx_encap(vdev, tx_desc, msdu,msdu_info); + } + return A_OK; +} + +static inline A_STATUS +OL_RX_DECAP( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + adf_nbuf_t msdu, + struct ol_rx_decap_info_t *info) +{ + if (vdev->pdev->sw_rx_decap) { + return ol_rx_decap(vdev, peer, msdu, info); + } + return A_OK; +} + +#define OL_TX_RESTORE_HDR(__tx_desc,__msdu) \ + if(__tx_desc->orig_l2_hdr_bytes != 0) { \ + adf_nbuf_push_head(__msdu, __tx_desc->orig_l2_hdr_bytes); \ + } +#else +#define OL_TX_ENCAP(vdev, tx_desc, msdu, msdu_info) A_OK +#define OL_RX_DECAP(vdev, peer, msdu, info) A_OK +#define OL_TX_RESTORE_HDR(__tx_desc,__msdu) +#endif +#endif /* _OL_TXRX_ENCAP__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_event.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_event.c new file mode 100644 index 0000000000000..b369f089c8a2b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_event.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "ol_txrx_types.h" + +#ifdef WDI_EVENT_ENABLE + +static inline wdi_event_subscribe * +wdi_event_next_sub(wdi_event_subscribe *wdi_sub) +{ + if (!wdi_sub) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid subscriber in %s\n", __FUNCTION__); + return NULL; + } + return wdi_sub->priv.next; +} + +static inline void +wdi_event_del_subs(wdi_event_subscribe *wdi_sub, int event_index) +{ + wdi_event_notify deallocate_sub; + while (wdi_sub) { + wdi_event_subscribe *next = wdi_event_next_sub(wdi_sub); + /* + * Context is NULL for static allocation of subs + * In dynamic allocation case notify the user + */ + if (wdi_sub->context) { + deallocate_sub = wdi_sub->context; + deallocate_sub( + WDI_EVENT_SUB_DEALLOCATE, WDI_EVENT_BASE + event_index); + } + wdi_sub = next; + } + //adf_os_mem_free(wdi_sub); +} + +static inline void +wdi_event_iter_sub( + struct ol_txrx_pdev_t *pdev, + uint32_t event_index, + wdi_event_subscribe *wdi_sub, + void *data) +{ + enum WDI_EVENT event = event_index + WDI_EVENT_BASE; + + if (wdi_sub) { + do { + wdi_sub->callback(pdev, event, data); + } while ((wdi_sub = wdi_event_next_sub(wdi_sub))); + } +} + +void +wdi_event_handler( + enum WDI_EVENT event, + struct ol_txrx_pdev_t *txrx_pdev, + void *data) +{ + uint32_t event_index; + wdi_event_subscribe *wdi_sub; + /* + * Input validation + */ + if (!event) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid WDI event in %s\n", __FUNCTION__); + return; + } + if (!txrx_pdev) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid pdev in WDI event handler\n"); + return; + } + /* + * There can be NULL data, so no validation for the data + * Subscribers must do the sanity based on the requirements + */ + event_index = event - WDI_EVENT_BASE; + + wdi_sub = txrx_pdev->wdi_event_list[event_index]; + + /* Find the subscriber */ + wdi_event_iter_sub(txrx_pdev, event_index, wdi_sub, data); +} + +A_STATUS +wdi_event_sub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event) +{ + uint32_t event_index; + wdi_event_subscribe *wdi_sub; + /* Input validation */ + if (!txrx_pdev) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid txrx_pdev in %s", __FUNCTION__); + return A_ERROR; + } + if (!event_cb_sub) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid callback in %s", __FUNCTION__); + return A_ERROR; + } + if ((!event) || (event >= WDI_EVENT_LAST) || (event < WDI_EVENT_BASE)) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid event in %s", __FUNCTION__); + return A_ERROR; + } /* Input validation */ + + event_index = event - WDI_EVENT_BASE; + + wdi_sub = txrx_pdev->wdi_event_list[event_index]; + /* + * Check if it is the first subscriber of the event + */ + if (!wdi_sub) { + wdi_sub = event_cb_sub; + wdi_sub->priv.next = NULL; + wdi_sub->priv.prev = NULL; + txrx_pdev->wdi_event_list[event_index] = wdi_sub; + return A_OK; + } + event_cb_sub->priv.next = wdi_sub; + event_cb_sub->priv.prev = NULL; + wdi_sub->priv.prev = event_cb_sub; + txrx_pdev->wdi_event_list[event_index] = event_cb_sub; + + return A_OK; +} + +A_STATUS +wdi_event_unsub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event) +{ + uint32_t event_index = event - WDI_EVENT_BASE; + + /* Input validation */ + if (!event_cb_sub) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid callback in %s", __FUNCTION__); + return A_ERROR; + } + if (!event_cb_sub->priv.prev) { + txrx_pdev->wdi_event_list[event_index] = event_cb_sub->priv.next; + } else { + event_cb_sub->priv.prev->priv.next = event_cb_sub->priv.next; + } + if (event_cb_sub->priv.next) { + event_cb_sub->priv.next->priv.prev = event_cb_sub->priv.prev; + } + //adf_os_mem_free(event_cb_sub); + + return A_OK; +} + +A_STATUS +wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev) +{ + /* Input validation */ + if (!txrx_pdev) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid device in %s\nWDI event attach failed", __FUNCTION__); + return A_ERROR; + } + /* Separate subscriber list for each event */ + txrx_pdev->wdi_event_list = (wdi_event_subscribe **) + adf_os_mem_alloc( + txrx_pdev->osdev, sizeof(wdi_event_subscribe *) * WDI_NUM_EVENTS); + if (!txrx_pdev->wdi_event_list) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Insufficient memory for the WDI event lists\n"); + return A_NO_MEMORY; + } + return A_OK; +} + +A_STATUS +wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev) +{ + int i; + wdi_event_subscribe *wdi_sub; + if (!txrx_pdev) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR, + "Invalid device in %s\nWDI attach failed", __FUNCTION__); + return A_ERROR; + } + if (!txrx_pdev->wdi_event_list) { + return A_ERROR; + } + for (i = 0; i < WDI_NUM_EVENTS; i++) { + wdi_sub = txrx_pdev->wdi_event_list[i]; + if (wdi_sub) { + /* Delete all the subscribers */ + wdi_event_del_subs(wdi_sub, i); + } + } + /* txrx_pdev->wdi_event_list would be non-null */ + adf_os_mem_free(txrx_pdev->wdi_event_list); + return A_OK; +} + +#endif /* WDI_EVENT_ENABLE */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h new file mode 100644 index 0000000000000..5191dcd22e443 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h @@ -0,0 +1,672 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_TXRX_INTERNAL__H_ +#define _OL_TXRX_INTERNAL__H_ + +#include /* adf_os_assert */ +#include /* adf_nbuf_t */ +#include /* adf_os_mem_set */ +#include /* ieee80211_frame */ +#include /* htt_rx_msdu_desc_completes_mpdu, etc. */ + +#include + +#include +#include /* ETHERNET_HDR_LEN, etc. */ +#include /* IPV4_HDR_LEN, etc. */ +#include /* IPV6_HDR_LEN, etc. */ +#include /* IP_PROTOCOL_TCP, etc. */ + +#ifdef ATH_11AC_TXCOMPACT +#define OL_TX_DESC_NO_REFS(tx_desc) 1 +#define OL_TX_DESC_REF_INIT(tx_desc) /* no-op */ +#define OL_TX_DESC_REF_INC(tx_desc) /* no-op */ +#else +#define OL_TX_DESC_NO_REFS(tx_desc) \ + adf_os_atomic_dec_and_test(&tx_desc->ref_cnt) +#define OL_TX_DESC_REF_INIT(tx_desc) adf_os_atomic_init(&tx_desc->ref_cnt) +#define OL_TX_DESC_REF_INC(tx_desc) adf_os_atomic_inc(&tx_desc->ref_cnt) +#endif + +#ifndef ARRAY_LEN +#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0])) +#endif + + +#ifndef TXRX_ASSERT_LEVEL +#define TXRX_ASSERT_LEVEL 3 +#endif + +#ifdef __KLOCWORK__ +# define TXRX_ASSERT1(x) do { if (!(x)) abort(); } while (0) +# define TXRX_ASSERT2(x) do { if (!(x)) abort(); } while (0) +#else // #ifdef __KLOCWORK__ + +#if TXRX_ASSERT_LEVEL > 0 +#define TXRX_ASSERT1(condition) adf_os_assert((condition)) +#else +#define TXRX_ASSERT1(condition) +#endif + +#if TXRX_ASSERT_LEVEL > 1 +#define TXRX_ASSERT2(condition) adf_os_assert((condition)) +#else +#define TXRX_ASSERT2(condition) +#endif +#endif // #ifdef __KLOCWORK__ +enum { + /* FATAL_ERR - print only irrecoverable error messages */ + TXRX_PRINT_LEVEL_FATAL_ERR, + + /* ERR - include non-fatal err messages */ + TXRX_PRINT_LEVEL_ERR, + + /* WARN - include warnings */ + TXRX_PRINT_LEVEL_WARN, + + /* INFO1 - include fundamental, infrequent events */ + TXRX_PRINT_LEVEL_INFO1, + + /* INFO2 - include non-fundamental but infrequent events */ + TXRX_PRINT_LEVEL_INFO2, + + /* INFO3 - include frequent events */ + /* to avoid performance impact, don't use INFO3 unless explicitly enabled */ + #ifdef TXRX_PRINT_VERBOSE_ENABLE + TXRX_PRINT_LEVEL_INFO3, + #endif /* TXRX_PRINT_VERBOSE_ENABLE */ +}; + +extern unsigned g_txrx_print_level; + +#ifdef TXRX_PRINT_ENABLE + +#include /* va_list */ +#include /* adf_os_vprint */ + +/* Supress 4296 - expression is always true + * It will fire if level is TXRX_PRINT_LEVEL_FATAL_ERR (0) + * because g_txrx_print_level is unsigned */ +#define ol_txrx_print(level, fmt, ...) \ + if (level <= g_txrx_print_level) adf_os_print(fmt, ## __VA_ARGS__) +#define TXRX_PRINT(level, fmt, ...) \ + ol_txrx_print(level, "TXRX: " fmt, ## __VA_ARGS__) + +#ifdef TXRX_PRINT_VERBOSE_ENABLE + +#define ol_txrx_print_verbose(fmt, ...) \ + if (TXRX_PRINT_LEVEL_INFO3 <= g_txrx_print_level) \ + adf_os_print(fmt, ## __VA_ARGS__) +#define TXRX_PRINT_VERBOSE(fmt, ...) \ + ol_txrx_print_verbose("TXRX: " fmt, ## __VA_ARGS__) +#else +#define TXRX_PRINT_VERBOSE(fmt, ...) +#endif /* TXRX_PRINT_VERBOSE_ENABLE */ + +/* define PN check failure message print rate + as 1 second */ +#define TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS 1000 + +#else +#define TXRX_PRINT(level, fmt, ...) +#define TXRX_PRINT_VERBOSE(fmt, ...) +#endif /* TXRX_PRINT_ENABLE */ + +/*--- tx credit debug printouts ---*/ + +#ifndef DEBUG_CREDIT +#define DEBUG_CREDIT 0 +#endif + +#if DEBUG_CREDIT +#define TX_CREDIT_DEBUG_PRINT(fmt, ...) adf_os_print(fmt, ## __VA_ARGS__) +#else +#define TX_CREDIT_DEBUG_PRINT(fmt, ...) +#endif + +/*--- tx scheduler debug printouts ---*/ + +#ifdef HOST_TX_SCHED_DEBUG +#define TX_SCHED_DEBUG_PRINT(fmt, ...) adf_os_print(fmt, ## __VA_ARGS__) +#else +#define TX_SCHED_DEBUG_PRINT(fmt, ...) +#endif +#define TX_SCHED_DEBUG_PRINT_ALWAYS(fmt, ...) adf_os_print(fmt, ## __VA_ARGS__) + +#define OL_TXRX_LIST_APPEND(head, tail, elem) \ +do { \ + if (!(head)) { \ + (head) = (elem); \ + } else { \ + adf_nbuf_set_next((tail), (elem)); \ + } \ + (tail) = (elem); \ +} while (0) + +static inline void +ol_rx_mpdu_list_next( + struct ol_txrx_pdev_t *pdev, + void *mpdu_list, + adf_nbuf_t *mpdu_tail, + adf_nbuf_t *next_mpdu) +{ + htt_pdev_handle htt_pdev = pdev->htt_pdev; + adf_nbuf_t msdu; + + /* + * For now, we use a simply flat list of MSDUs. + * So, traverse the list until we reach the last MSDU within the MPDU. + */ + TXRX_ASSERT2(mpdu_list); + msdu = mpdu_list; + while (!htt_rx_msdu_desc_completes_mpdu( + htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, msdu))) + { + msdu = adf_nbuf_next(msdu); + TXRX_ASSERT2(msdu); + } + /* msdu now points to the last MSDU within the first MPDU */ + *mpdu_tail = msdu; + *next_mpdu = adf_nbuf_next(msdu); +} + + +/*--- txrx stats macros ---*/ + + +/* unconditional defs */ +#define TXRX_STATS_INCR(pdev, field) TXRX_STATS_ADD(pdev, field, 1) + +/* default conditional defs (may be undefed below) */ + +#define TXRX_STATS_INIT(_pdev) \ + adf_os_mem_set(&((_pdev)->stats), 0x0, sizeof((_pdev)->stats)) +#define TXRX_STATS_ADD(_pdev, _field, _delta) \ + _pdev->stats._field += _delta +#define TXRX_STATS_MSDU_INCR(pdev, field, netbuf) \ + do { \ + TXRX_STATS_INCR((pdev), pub.field.pkts); \ + TXRX_STATS_ADD((pdev), pub.field.bytes, adf_nbuf_len(netbuf)); \ + } while (0) + +/* conditional defs based on verbosity level */ + +#if /*---*/ TXRX_STATS_LEVEL == TXRX_STATS_LEVEL_FULL + +#define TXRX_STATS_MSDU_LIST_INCR(pdev, field, netbuf_list) \ + do { \ + adf_nbuf_t tmp_list = netbuf_list; \ + while (tmp_list) { \ + TXRX_STATS_MSDU_INCR(pdev, field, tmp_list); \ + tmp_list = adf_nbuf_next(tmp_list); \ + } \ + } while (0) + +#define TXRX_STATS_MSDU_INCR_TX_STATUS(status, pdev, netbuf) \ + switch (status) { \ + case htt_tx_status_ok: \ + TXRX_STATS_MSDU_INCR(pdev, tx.delivered, netbuf); \ + break; \ + case htt_tx_status_discard: \ + TXRX_STATS_MSDU_INCR(pdev, tx.dropped.target_discard, netbuf); \ + break; \ + case htt_tx_status_no_ack: \ + TXRX_STATS_MSDU_INCR(pdev, tx.dropped.no_ack, netbuf); \ + break; \ + case htt_tx_status_download_fail: \ + TXRX_STATS_MSDU_INCR(pdev, tx.dropped.download_fail, netbuf); \ + break; \ + default: \ + break; \ + } + +#define TXRX_STATS_UPDATE_TX_STATS(_pdev, _status, _p_cntrs, _b_cntrs) \ +do { \ + switch (status) { \ + case htt_tx_status_ok: \ + TXRX_STATS_ADD(_pdev, pub.tx.delivered.pkts, _p_cntrs); \ + TXRX_STATS_ADD(_pdev, pub.tx.delivered.bytes, _b_cntrs); \ + break; \ + case htt_tx_status_discard: \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.target_discard.pkts, _p_cntrs); \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.target_discard.bytes, _b_cntrs); \ + break; \ + case htt_tx_status_no_ack: \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.no_ack.pkts, _p_cntrs); \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.no_ack.bytes, _b_cntrs); \ + break; \ + case htt_tx_status_download_fail: \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.download_fail.pkts, _p_cntrs); \ + TXRX_STATS_ADD(_pdev, pub.tx.dropped.download_fail.bytes, _b_cntrs); \ + break; \ + default: \ + break; \ + } \ +} while (0) + +#elif /*---*/ TXRX_STATS_LEVEL == TXRX_STATS_LEVEL_BASIC + +#define TXRX_STATS_MSDU_LIST_INCR(pdev, field, netbuf_list) + +#define TXRX_STATS_MSDU_INCR_TX_STATUS(status, pdev, netbuf) \ + do { \ + if (status == htt_tx_status_ok) { \ + TXRX_STATS_MSDU_INCR(pdev, tx.delivered, netbuf); \ + } \ + } while (0) + +#define TXRX_STATS_INIT(_pdev) \ + adf_os_mem_set(&((_pdev)->stats), 0x0, sizeof((_pdev)->stats)) + +#define TXRX_STATS_UPDATE_TX_STATS(_pdev, _status, _p_cntrs, _b_cntrs) \ +do { \ + if (adf_os_likely(_status == htt_tx_status_ok)) { \ + TXRX_STATS_ADD(_pdev, pub.tx.delivered.pkts, _p_cntrs); \ + TXRX_STATS_ADD(_pdev, pub.tx.delivered.bytes, _b_cntrs); \ + } \ +} while (0) + +#else /*---*/ /* stats off */ + +#undef TXRX_STATS_INIT +#define TXRX_STATS_INIT(_pdev) + +#undef TXRX_STATS_ADD +#define TXRX_STATS_ADD(_pdev, _field, _delta) + +#undef TXRX_STATS_MSDU_INCR +#define TXRX_STATS_MSDU_INCR(pdev, field, netbuf) + +#define TXRX_STATS_MSDU_LIST_INCR(pdev, field, netbuf_list) + +#define TXRX_STATS_MSDU_INCR_TX_STATUS(status, pdev, netbuf) + +#define TXRX_STATS_UPDATE_TX_STATS(_pdev, _status, _p_cntrs, _b_cntrs) + +#endif /*---*/ /* TXRX_STATS_LEVEL */ + + +/*--- txrx sequence number trace macros ---*/ + + +#define TXRX_SEQ_NUM_ERR(_status) (0xffff - _status) + +#if defined(ENABLE_RX_REORDER_TRACE) + +A_STATUS ol_rx_reorder_trace_attach(ol_txrx_pdev_handle pdev); +void ol_rx_reorder_trace_detach(ol_txrx_pdev_handle pdev); +void ol_rx_reorder_trace_add( + ol_txrx_pdev_handle pdev, + u_int8_t tid, + u_int16_t reorder_idx, + u_int16_t seq_num, + int num_mpdus); + +#define OL_RX_REORDER_TRACE_ATTACH ol_rx_reorder_trace_attach +#define OL_RX_REORDER_TRACE_DETACH ol_rx_reorder_trace_detach +#define OL_RX_REORDER_TRACE_ADD ol_rx_reorder_trace_add + +#else + +#define OL_RX_REORDER_TRACE_ATTACH(_pdev) A_OK +#define OL_RX_REORDER_TRACE_DETACH(_pdev) +#define OL_RX_REORDER_TRACE_ADD(pdev, tid, reorder_idx, seq_num, num_mpdus) + +#endif /* ENABLE_RX_REORDER_TRACE */ + + +/*--- txrx packet number trace macros ---*/ + + +#if defined(ENABLE_RX_PN_TRACE) + +A_STATUS ol_rx_pn_trace_attach(ol_txrx_pdev_handle pdev); +void ol_rx_pn_trace_detach(ol_txrx_pdev_handle pdev); +void ol_rx_pn_trace_add( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer, + u_int16_t tid, + void *rx_desc); + +#define OL_RX_PN_TRACE_ATTACH ol_rx_pn_trace_attach +#define OL_RX_PN_TRACE_DETACH ol_rx_pn_trace_detach +#define OL_RX_PN_TRACE_ADD ol_rx_pn_trace_add + +#else + +#define OL_RX_PN_TRACE_ATTACH(_pdev) A_OK +#define OL_RX_PN_TRACE_DETACH(_pdev) +#define OL_RX_PN_TRACE_ADD(pdev, peer, tid, rx_desc) + +#endif /* ENABLE_RX_PN_TRACE */ + +static inline int +ol_txrx_ieee80211_hdrsize(const void *data) +{ + const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data; + int size = sizeof(struct ieee80211_frame); + + /* NB: we don't handle control frames */ + TXRX_ASSERT1( + (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL); + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { + size += IEEE80211_ADDR_LEN; + } + if (IEEE80211_QOS_HAS_SEQ(wh)) { + size += sizeof(u_int16_t); + /* Qos frame with Order bit set indicates an HTC frame */ + if (wh->i_fc[1] & IEEE80211_FC1_ORDER) { + size += sizeof(struct ieee80211_htc); + } + } + return size; +} + +/*--- frame display utility ---*/ + +enum ol_txrx_frm_dump_options { + ol_txrx_frm_dump_contents = 0x1, + ol_txrx_frm_dump_tcp_seq = 0x2, +}; + +#ifdef TXRX_DEBUG_DATA +static inline void +OL_TXRX_FRMS_DUMP( + const char *name, + struct ol_txrx_pdev_t *pdev, + adf_nbuf_t frm, + enum ol_txrx_frm_dump_options display_options, + int max_len) +{ + #define TXRX_FRM_DUMP_MAX_LEN 128 + u_int8_t local_buf[TXRX_FRM_DUMP_MAX_LEN] = {0}; + u_int8_t *p; + + if (name) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, "%s\n", name); + } + while (frm) { + p = adf_nbuf_data(frm); + if (display_options & ol_txrx_frm_dump_tcp_seq) { + int tcp_offset; + int l2_hdr_size; + u_int16_t ethertype; + u_int8_t ip_prot; + + if (pdev->frame_format == wlan_frm_fmt_802_3) { + struct ethernet_hdr_t *enet_hdr = (struct ethernet_hdr_t *) p; + l2_hdr_size = ETHERNET_HDR_LEN; + + /* + * LLC/SNAP present? + */ + ethertype = + (enet_hdr->ethertype[0] << 8) | enet_hdr->ethertype[1]; + if (!IS_ETHERTYPE(ethertype)) { + /* 802.3 format */ + struct llc_snap_hdr_t *llc_hdr; + + llc_hdr = (struct llc_snap_hdr_t *) (p + l2_hdr_size); + l2_hdr_size += LLC_SNAP_HDR_LEN; + ethertype = + (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1]; + } + } else { + struct llc_snap_hdr_t *llc_hdr; + /* (generic?) 802.11 */ + l2_hdr_size = sizeof(struct ieee80211_frame); + llc_hdr = (struct llc_snap_hdr_t *) (p + l2_hdr_size); + l2_hdr_size += LLC_SNAP_HDR_LEN; + ethertype = + (llc_hdr->ethertype[0] << 8) | llc_hdr->ethertype[1]; + } + if (ethertype == ETHERTYPE_IPV4) { + struct ipv4_hdr_t *ipv4_hdr; + ipv4_hdr = (struct ipv4_hdr_t *) (p + l2_hdr_size); + ip_prot = ipv4_hdr->protocol; + tcp_offset = l2_hdr_size + IPV4_HDR_LEN; + } else if (ethertype == ETHERTYPE_IPV6) { + struct ipv6_hdr_t *ipv6_hdr; + ipv6_hdr = (struct ipv6_hdr_t *) (p + l2_hdr_size); + ip_prot = ipv6_hdr->next_hdr; + tcp_offset = l2_hdr_size + IPV6_HDR_LEN; + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "frame %p non-IP ethertype (%x)\n", frm, ethertype); + goto NOT_IP_TCP; + } + if (ip_prot == IP_PROTOCOL_TCP) { +#if 0 + struct tcp_hdr_t *tcp_hdr; + u_int32_t tcp_seq_num; + tcp_hdr = (struct tcp_hdr_t *) (p + tcp_offset); + tcp_seq_num = + (tcp_hdr->seq_num[0] << 24) | + (tcp_hdr->seq_num[1] << 16) | + (tcp_hdr->seq_num[1] << 8) | + (tcp_hdr->seq_num[1] << 0); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "frame %p: TCP seq num = %d\n", frm, tcp_seq_num); +#else + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "frame %p: TCP seq num = %d\n", frm, + ((*(p + tcp_offset + 4)) << 24) | + ((*(p + tcp_offset + 5)) << 16) | + ((*(p + tcp_offset + 6)) << 8) | + (*(p + tcp_offset + 7))); +#endif + } else { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "frame %p non-TCP IP protocol (%x)\n", frm, ip_prot); + } + } +NOT_IP_TCP: + if (display_options & ol_txrx_frm_dump_contents) { + int i, frag_num, len_lim; + len_lim = max_len; + if (len_lim > adf_nbuf_len(frm)) { + len_lim = adf_nbuf_len(frm); + } + if (len_lim > TXRX_FRM_DUMP_MAX_LEN) { + len_lim = TXRX_FRM_DUMP_MAX_LEN; + } + + /* + * Gather frame contents from netbuf fragments + * into a contiguous buffer. + */ + frag_num = 0; + i = 0; + while (i < len_lim) { + int frag_bytes; + frag_bytes = adf_nbuf_get_frag_len(frm, frag_num); + if (frag_bytes > len_lim - i) { + frag_bytes = len_lim - i; + } + if (frag_bytes > 0) { + p = adf_nbuf_get_frag_vaddr(frm, frag_num); + adf_os_mem_copy(&local_buf[i], p, frag_bytes); + } + frag_num++; + i += frag_bytes; + } + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "frame %p data (%p), hex dump of bytes 0-%d of %d:\n", + frm, p, len_lim-1, (int) adf_nbuf_len(frm)); + p = local_buf; + while (len_lim > 16) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " " /* indent */ + "%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + *(p + 0), *(p + 1), *(p + 2), *(p + 3), + *(p + 4), *(p + 5), *(p + 6), *(p + 7), + *(p + 8), *(p + 9), *(p + 10), *(p + 11), + *(p + 12), *(p + 13), *(p + 14), *(p + 15)); + p += 16; + len_lim -= 16; + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + " " /* indent */); + while (len_lim > 0) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, + "%02x ", *p); + p++; + len_lim--; + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO, "\n"); + } + frm = adf_nbuf_next(frm); + } +} +#else +#define OL_TXRX_FRMS_DUMP(name, pdev, frms, display_options, max_len) +#endif /* TXRX_DEBUG_DATA */ + +#ifdef SUPPORT_HOST_STATISTICS + +#define OL_RX_ERR_STATISTICS(pdev, vdev, err_type, sec_type, is_mcast) \ + ol_rx_err_statistics(pdev->ctrl_pdev, vdev->vdev_id, err_type, \ + sec_type, is_mcast); + +#define OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, err_type) \ +do { \ + int is_mcast; \ + enum htt_sec_type sec_type; \ + is_mcast = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc); \ + sec_type = peer->security[is_mcast ? txrx_sec_mcast : txrx_sec_ucast].sec_type; \ + OL_RX_ERR_STATISTICS(pdev, vdev, err_type, pdev->sec_types[sec_type], is_mcast); \ +} while (false) + +#define OL_RX_ERR_INV_PEER_STATISTICS(pdev, rx_msdu) \ +do { \ + struct ieee80211_frame *wh = NULL; \ + /*FIX THIS :Here htt_rx_mpdu_wifi_hdr_retrieve should be used. But at */ \ + /*present it seems it does not work.*/ \ + /*wh = (struct ieee80211_frame *)htt_rx_mpdu_wifi_hdr_retrieve(pdev->htt_pdev, rx_desc);*/ \ + \ + /* this only apply to LL device.*/ \ + if (!ol_cfg_is_high_latency(pdev->ctrl_pdev) && \ + ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_native_wifi) { \ + /* For windows, it is always native wifi header .*/ \ + wh = (struct ieee80211_frame*)adf_nbuf_data(rx_msdu); \ + } \ + ol_rx_err_inv_peer_statistics(pdev->ctrl_pdev, wh, OL_RX_ERR_UNKNOWN_PEER); \ +} while (false) + +#define OL_RX_ERR_STATISTICS_2(pdev, vdev, peer, rx_desc, rx_msdu, rx_status) \ +do { \ + enum ol_rx_err_type err_type = OL_RX_ERR_NONE; \ + switch (rx_status) { \ + case htt_rx_status_decrypt_err: \ + err_type = OL_RX_ERR_DECRYPT; \ + break; \ + case htt_rx_status_tkip_mic_err: \ + err_type = OL_RX_ERR_TKIP_MIC; \ + break; \ + case htt_rx_status_mpdu_length_err: \ + err_type = OL_RX_ERR_MPDU_LENGTH; \ + break; \ + case htt_rx_status_mpdu_encrypt_required_err: \ + err_type = OL_RX_ERR_ENCRYPT_REQUIRED; \ + break; \ + case htt_rx_status_err_dup: \ + err_type = OL_RX_ERR_DUP; \ + break; \ + case htt_rx_status_err_fcs: \ + err_type = OL_RX_ERR_FCS; \ + break; \ + default: \ + err_type = OL_RX_ERR_UNKNOWN; \ + break; \ + } \ + if (vdev != NULL && peer != NULL) { \ + OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_mpdu_desc, err_type); \ + } else { \ + OL_RX_ERR_INV_PEER_STATISTICS(pdev, rx_msdu); \ + } \ +} while (false) +#else +#define OL_RX_ERR_STATISTICS(pdev, vdev, err_type, sec_type, is_mcast) +#define OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc, err_type) +#define OL_RX_ERR_STATISTICS_2(pdev, vdev, peer, rx_desc, rx_msdu, rx_status) +#endif /* SUPPORT_HOST_STATISTICS */ + +#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS +#define OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx, type, msdu) \ + do { \ + adf_os_spin_lock_bh(&peer->vdev->pdev->peer_stat_mutex); \ + peer->stats. tx_or_rx .frms. type += 1; \ + peer->stats. tx_or_rx .bytes. type += adf_nbuf_len(msdu); \ + adf_os_spin_unlock_bh(&peer->vdev->pdev->peer_stat_mutex); \ + } while (0) +#define OL_TXRX_PEER_STATS_UPDATE(peer, tx_or_rx, msdu) \ + do { \ + struct ol_txrx_vdev_t *vdev = peer->vdev; \ + struct ol_txrx_pdev_t *pdev = vdev->pdev; \ + u_int8_t *dest_addr; \ + if (pdev->frame_format == wlan_frm_fmt_802_3) { \ + dest_addr = adf_nbuf_data(msdu); \ + } else { /* 802.11 format */ \ + struct ieee80211_frame *frm; \ + frm = (struct ieee80211_frame *) adf_nbuf_data(msdu); \ + if (vdev->opmode == wlan_op_mode_ap) { \ + dest_addr = (u_int8_t *) &(frm->i_addr1[0]); \ + } else { \ + dest_addr = (u_int8_t *) &(frm->i_addr3[0]); \ + } \ + } \ + if (adf_os_unlikely(IEEE80211_IS_BROADCAST(dest_addr))) { \ + OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx, bcast, msdu); \ + } else if (adf_os_unlikely(IEEE80211_IS_MULTICAST(dest_addr))) { \ + OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx, mcast, msdu); \ + } else { \ + OL_TXRX_PEER_STATS_UPDATE_BASE(peer, tx_or_rx, ucast, msdu); \ + } \ + } while (0) +#define OL_TX_PEER_STATS_UPDATE(peer, msdu) \ + OL_TXRX_PEER_STATS_UPDATE(peer, tx, msdu) +#define OL_RX_PEER_STATS_UPDATE(peer, msdu) \ + OL_TXRX_PEER_STATS_UPDATE(peer, rx, msdu) +#define OL_TXRX_PEER_STATS_MUTEX_INIT(pdev) \ + adf_os_spinlock_init(&pdev->peer_stat_mutex) +#define OL_TXRX_PEER_STATS_MUTEX_DESTROY(pdev) \ + adf_os_spinlock_destroy(&pdev->peer_stat_mutex) +#else +#define OL_TX_PEER_STATS_UPDATE(peer, msdu) /* no-op */ +#define OL_RX_PEER_STATS_UPDATE(peer, msdu) /* no-op */ +#define OL_TXRX_PEER_STATS_MUTEX_INIT(peer) /* no-op */ +#define OL_TXRX_PEER_STATS_MUTEX_DESTROY(peer) /* no-op */ +#endif + +#ifndef DEBUG_HTT_CREDIT +#define DEBUG_HTT_CREDIT 0 +#endif + +#endif /* _OL_TXRX_INTERNAL__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.c new file mode 100644 index 0000000000000..5513f581d2496 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.c @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=== includes ===*/ +/* header files for OS primitives */ +#include /* u_int32_t, etc. */ +#include /* adf_os_mem_alloc, etc. */ +#include /* adf_os_device_t, adf_os_print */ +/* header files for utilities */ +#include /* TAILQ */ + +/* header files for configuration API */ +#include /* ol_cfg_max_peer_id */ + +/* header files for our internal definitions */ +#include /* ol_txrx_pdev_t, etc. */ +#include /* TXRX_DEBUG_LEVEL */ +#include /* ol_txrx_pdev_t, etc. */ +#include /* ol_txrx_peer_unref_delete */ +#include /* ol_txrx_peer_find_attach, etc. */ +#include + +/*=== misc. / utility function definitions ==================================*/ + +static int +ol_txrx_log2_ceil(unsigned value) +{ + /* need to switch to unsigned math so that negative values + * will right-shift towards 0 instead of -1 + */ + unsigned tmp = value; + int log2 = -1; + + if (value == 0) + { + TXRX_ASSERT2(0); + return 0; + } + + while (tmp) { + log2++; + tmp >>= 1; + } + if (1U << log2 != value) { + log2++; + } + + return log2; +} + +static int +ol_txrx_peer_find_add_id_to_obj( + struct ol_txrx_peer_t *peer, + u_int16_t peer_id) +{ + int i; + + for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) { + if (peer->peer_ids[i] == HTT_INVALID_PEER) { + peer->peer_ids[i] = peer_id; + return 0; /* success */ + } + } + return 1; /* failure */ +} + +/*=== function definitions for peer MAC addr --> peer object hash table =====*/ + +/* + * TXRX_PEER_HASH_LOAD_FACTOR: + * Multiply by 2 and divide by 2^0 (shift by 0), then round up to a + * power of two. + * This provides at least twice as many bins in the peer hash table + * as there will be entries. + * Having substantially more bins than spaces minimizes the probability of + * having to compare MAC addresses. + * Because the MAC address comparison is fairly efficient, it is okay if the + * hash table is sparsely loaded, but it's generally better to use extra mem + * to keep the table sparse, to keep the lookups as fast as possible. + * An optimization would be to apply a more conservative loading factor for + * high latency, where the lookup happens during the tx classification of + * every tx frame, than for low-latency, where the lookup only happens + * during association, when the PEER_MAP message is received. + */ +#define TXRX_PEER_HASH_LOAD_MULT 2 +#define TXRX_PEER_HASH_LOAD_SHIFT 0 + +static int +ol_txrx_peer_find_hash_attach(struct ol_txrx_pdev_t *pdev) +{ + int i, hash_elems, log2; + + /* allocate the peer MAC address -> peer object hash table */ + hash_elems = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1; + hash_elems *= TXRX_PEER_HASH_LOAD_MULT; + hash_elems >>= TXRX_PEER_HASH_LOAD_SHIFT; + log2 = ol_txrx_log2_ceil(hash_elems); + hash_elems = 1 << log2; + + pdev->peer_hash.mask = hash_elems - 1; + pdev->peer_hash.idx_bits = log2; + /* allocate an array of TAILQ peer object lists */ + pdev->peer_hash.bins = adf_os_mem_alloc( + pdev->osdev, + hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, ol_txrx_peer_t))); + if (!pdev->peer_hash.bins) { + return 1; /* failure */ + } + for (i = 0; i < hash_elems; i++) { + TAILQ_INIT(&pdev->peer_hash.bins[i]); + } + return 0; /* success */ +} + +static void +ol_txrx_peer_find_hash_detach(struct ol_txrx_pdev_t *pdev) +{ + adf_os_mem_free(pdev->peer_hash.bins); +} + +static inline unsigned +ol_txrx_peer_find_hash_index( + struct ol_txrx_pdev_t *pdev, + union ol_txrx_align_mac_addr_t *mac_addr) +{ + unsigned index; + + index = + mac_addr->align2.bytes_ab ^ + mac_addr->align2.bytes_cd ^ + mac_addr->align2.bytes_ef; + index ^= index >> pdev->peer_hash.idx_bits; + index &= pdev->peer_hash.mask; + return index; +} + + +void +ol_txrx_peer_find_hash_add( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + unsigned index; + + index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr); + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + /* + * It is important to add the new peer at the tail of the peer list + * with the bin index. Together with having the hash_find function + * search from head to tail, this ensures that if two entries with + * the same MAC address are stored, the one added first will be + * found first. + */ + TAILQ_INSERT_TAIL(&pdev->peer_hash.bins[index], peer, hash_list_elem); + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); +} + +struct ol_txrx_peer_t * +ol_txrx_peer_vdev_find_hash(struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + u_int8_t *peer_mac_addr, + int mac_addr_is_aligned, + u_int8_t check_valid) +{ + union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr; + unsigned index; + struct ol_txrx_peer_t *peer; + + if (mac_addr_is_aligned) { + mac_addr = (union ol_txrx_align_mac_addr_t *) peer_mac_addr; + } else { + adf_os_mem_copy( + &local_mac_addr_aligned.raw[0], + peer_mac_addr, OL_TXRX_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; + } + index = ol_txrx_peer_find_hash_index(pdev, mac_addr); + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) { + if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 + && (check_valid == 0 || peer->valid) && peer->vdev == vdev ) { + /* found it - increment the ref count before releasing the lock */ + adf_os_atomic_inc(&peer->ref_cnt); + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return peer; + } + } + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return NULL; /* failure */ +} + +struct ol_txrx_peer_t * +ol_txrx_peer_find_hash_find( + struct ol_txrx_pdev_t *pdev, + u_int8_t *peer_mac_addr, + int mac_addr_is_aligned, + u_int8_t check_valid) +{ + union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr; + unsigned index; + struct ol_txrx_peer_t *peer; + + if (mac_addr_is_aligned) { + mac_addr = (union ol_txrx_align_mac_addr_t *) peer_mac_addr; + } else { + adf_os_mem_copy( + &local_mac_addr_aligned.raw[0], + peer_mac_addr, OL_TXRX_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; + } + index = ol_txrx_peer_find_hash_index(pdev, mac_addr); + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) { + if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 + && (check_valid == 0 || peer->valid)) { + /* found it - increment the ref count before releasing the lock */ + adf_os_atomic_inc(&peer->ref_cnt); + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return peer; + } + } + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + return NULL; /* failure */ +} + +void +ol_txrx_peer_find_hash_remove( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer) +{ + unsigned index; + + index = ol_txrx_peer_find_hash_index(pdev, &peer->mac_addr); + /* + * DO NOT take the peer_ref_mutex lock here - it needs to be taken + * by the caller. + * The caller needs to hold the lock from the time the peer object's + * reference count is decremented and tested up through the time the + * reference to the peer object is removed from the hash table, by + * this function. + * Holding the lock only while removing the peer object reference + * from the hash table keeps the hash table consistent, but does not + * protect against a new HL tx context starting to use the peer object + * if it looks up the peer object from its MAC address just after the + * peer ref count is decremented to zero, but just before the peer + * object reference is removed from the hash table. + */ + //adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_REMOVE(&pdev->peer_hash.bins[index], peer, hash_list_elem); + //adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); +} + +void +ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev) +{ + unsigned i; + /* + * Not really necessary to take peer_ref_mutex lock - by this point, + * it's known that the pdev is no longer in use. + */ + + for (i = 0; i <= pdev->peer_hash.mask; i++) { + if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) { + struct ol_txrx_peer_t *peer, *peer_next; + + /* + * TAILQ_FOREACH_SAFE must be used here to avoid any memory access + * violation after peer is freed + */ + TAILQ_FOREACH_SAFE( + peer, &pdev->peer_hash.bins[i], hash_list_elem, peer_next) + { + /* + * Don't remove the peer from the hash table - + * that would modify the list we are currently traversing, + * and it's not necessary anyway. + */ + /* + * Artificially adjust the peer's ref count to 1, so it + * will get deleted by ol_txrx_peer_unref_delete. + */ + adf_os_atomic_init(&peer->ref_cnt); /* set to zero */ + adf_os_atomic_inc(&peer->ref_cnt); /* incr to one */ + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Delete Peer %p\n", __func__, peer); + ol_txrx_peer_unref_delete(peer); + } + } + } +} + +/*=== function definitions for peer id --> peer object map ==================*/ + +static int +ol_txrx_peer_find_map_attach(struct ol_txrx_pdev_t *pdev) +{ + int max_peers, peer_map_size; + + /* allocate the peer ID -> peer object map */ + max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1; + peer_map_size = max_peers * sizeof(pdev->peer_id_to_obj_map[0]); + pdev->peer_id_to_obj_map = adf_os_mem_alloc(pdev->osdev, peer_map_size); + if (!pdev->peer_id_to_obj_map) { + return 1; /* failure */ + } + + /* + * The peer_id_to_obj_map doesn't really need to be initialized, + * since elements are only used after they have been individually + * initialized. + * However, it is convenient for debugging to have all elements + * that are not in use set to 0. + */ + adf_os_mem_set(pdev->peer_id_to_obj_map, 0, peer_map_size); + + return 0; /* success */ +} + +static void +ol_txrx_peer_find_map_detach(struct ol_txrx_pdev_t *pdev) +{ + adf_os_mem_free(pdev->peer_id_to_obj_map); +} + +static inline void +ol_txrx_peer_find_add_id( + struct ol_txrx_pdev_t *pdev, + u_int8_t *peer_mac_addr, + u_int16_t peer_id) +{ + struct ol_txrx_peer_t *peer; + + /* check if there's already a peer object with this MAC address */ + peer = ol_txrx_peer_find_hash_find(pdev, peer_mac_addr, 1 /* is aligned */, 0); + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s: peer %p ID %d\n", __func__, peer, peer_id); + if (peer) { + /* peer's ref count was already incremented by peer_find_hash_find */ + pdev->peer_id_to_obj_map[peer_id] = peer; + /* + * remove the reference added in ol_txrx_peer_find_hash_find. + * the reference for the first peer id is already added in ol_txrx_peer_attach. + * Riva/Pronto has one peer id for each peer. + * Peregrine/Rome has two peer id for each peer. + */ + if (peer->peer_ids[0] == HTT_INVALID_PEER) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Delete Peer %p\n", __func__, peer); + ol_txrx_peer_unref_delete(peer); + } + if (ol_txrx_peer_find_add_id_to_obj(peer, peer_id)) { + /* TBDXXX: assert for now */ + adf_os_assert(0); + } + return; + } + /* + * Currently peer IDs are assigned for vdevs as well as peers. + * If the peer ID is for a vdev, then we will fail to find a peer + * with a matching MAC address. + */ + //TXRX_ASSERT2(0); +} + +/*=== allocation / deallocation function definitions ========================*/ + +int +ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev) +{ + if (ol_txrx_peer_find_map_attach(pdev)) { + return 1; + } + if (ol_txrx_peer_find_hash_attach(pdev)) { + ol_txrx_peer_find_map_detach(pdev); + return 1; + } + return 0; /* success */ +} + +void +ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev) +{ + ol_txrx_peer_find_map_detach(pdev); + ol_txrx_peer_find_hash_detach(pdev); +} + +/*=== function definitions for message handling =============================*/ + +void +ol_rx_peer_map_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tx_ready) +{ + ol_txrx_peer_find_add_id(pdev, peer_mac_addr, peer_id); + if (pdev->cfg.is_high_latency && !tx_ready) { + struct ol_txrx_peer_t *peer; + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (!peer) { + /* ol_txrx_peer_detach called before peer map arrived */ + return; + }else { + if (tx_ready) { +#if defined(CONFIG_HL_SUPPORT) + int i; + /* unpause all tx queues now, since the target is ready */ + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + ol_txrx_peer_tid_unpause(peer, i); + } +#endif + } else { + /* walk through paused mgmt queue, update tx descriptors */ + ol_tx_queue_decs_reinit(peer, peer_id); + + /* keep non-mgmt tx queues paused until assoc is finished */ + /* tx queues were paused in ol_txrx_peer_attach*/ + /* unpause tx mgmt queue */ + ol_txrx_peer_tid_unpause(peer, HTT_TX_EXT_TID_MGMT); + } + } + } +} + +void +ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, u_int16_t peer_id) +{ +#if defined(CONFIG_HL_SUPPORT) + struct ol_txrx_peer_t *peer; + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (peer) { + int i; + /* + * Unpause all data tx queues now that the target is ready. + * The mgmt tx queue was not paused, so skip it. + */ + for (i = 0; i < ARRAY_LEN(peer->txqs); i++) { + if (i == HTT_TX_EXT_TID_MGMT) { + continue; /* mgmt tx queue was not paused */ + } + ol_txrx_peer_tid_unpause(peer, i); + } + } +#endif +} + +void +ol_rx_peer_unmap_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id) +{ + struct ol_txrx_peer_t *peer; + peer = (peer_id == HTT_INVALID_PEER) ? NULL : + pdev->peer_id_to_obj_map[peer_id]; + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s: peer %p with ID %d to be unmapped.\n", __func__, peer, peer_id); + pdev->peer_id_to_obj_map[peer_id] = NULL; + /* + * Currently peer IDs are assigned for vdevs as well as peers. + * If the peer ID is for a vdev, then the peer pointer stored + * in peer_id_to_obj_map will be NULL. + */ + if (!peer) return; + /* + * Remove a reference to the peer. + * If there are no more references, delete the peer object. + */ + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: Remove the ID %d reference to peer %p\n", + __func__, peer_id, peer); + ol_txrx_peer_unref_delete(peer); +} + +struct ol_txrx_peer_t * +ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev) +{ + struct ol_txrx_peer_t *peer; + + adf_os_spin_lock_bh(&vdev->pdev->last_real_peer_mutex); + /* + * Check the TXRX Peer is itself valid And also + * if HTT Peer ID has been setup for this peer + */ + if (vdev->last_real_peer && vdev->last_real_peer->peer_ids[0] != HTT_INVALID_PEER_ID) + { + adf_os_atomic_inc(&vdev->last_real_peer->ref_cnt); + peer = vdev->last_real_peer; + } else { + peer = NULL; + } + adf_os_spin_unlock_bh(&vdev->pdev->last_real_peer_mutex); + return peer; +} + +/*=== function definitions for debug ========================================*/ + +#if defined (TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5 +void +ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent) +{ + int i, max_peers; + + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*speer map:\n", indent, " "); + max_peers = ol_cfg_max_peer_id(pdev->ctrl_pdev) + 1; + for (i = 0; i < max_peers; i++) { + if (pdev->peer_id_to_obj_map[i]) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*sid %d -> %p\n", + indent+4, " ", i, pdev->peer_id_to_obj_map[i]); + } + } + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*speer hash table:\n", indent, " "); + for (i = 0; i <= pdev->peer_hash.mask; i++) { + if (!TAILQ_EMPTY(&pdev->peer_hash.bins[i])) { + struct ol_txrx_peer_t *peer; + TAILQ_FOREACH(peer, &pdev->peer_hash.bins[i], hash_list_elem) { + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "%*shash idx %d -> %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", + indent+4, " ", i, peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + } + } + } +} +#endif /* if TXRX_DEBUG_LEVEL */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.h new file mode 100644 index 0000000000000..acb7d6474237e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_peer_find.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_peer_find.h + * @brief Define the API for the rx peer lookup datapath module. + */ +#ifndef _OL_TXRX_PEER_FIND__H_ +#define _OL_TXRX_PEER_FIND__H_ + +#include /* HTT_INVALID_PEER */ +#include /* ol_txrx_pdev_t, etc. */ +#include /* TXRX_ASSERT */ + +int ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev); + +void ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev); + +static inline +int +ol_txrx_peer_find_mac_addr_cmp( + union ol_txrx_align_mac_addr_t *mac_addr1, + union ol_txrx_align_mac_addr_t *mac_addr2) +{ + return + !((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd) + /* + * Intentionally use & rather than &&. + * because the operands are binary rather than generic boolean, + * the functionality is equivalent. + * Using && has the advantage of short-circuited evaluation, + * but using & has the advantage of no conditional branching, + * which is a more significant benefit. + */ + & + (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef)); +} + +static inline +struct ol_txrx_peer_t * +ol_txrx_peer_find_by_id( + struct ol_txrx_pdev_t *pdev, + u_int16_t peer_id) +{ + struct ol_txrx_peer_t *peer; + peer = (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) ? NULL : + pdev->peer_id_to_obj_map[peer_id]; + /* + * Currently, peer IDs are assigned to vdevs as well as peers. + * If the peer ID is for a vdev, the peer_id_to_obj_map entry + * will hold NULL rather than a valid peer pointer. + */ + //TXRX_ASSERT2(peer != NULL); + /* + * Only return the peer object if it is valid, + * i.e. it has not already been detached. + * If it has already been detached, then returning the + * peer object could result in unpausing the peer's tx queues + * in HL systems, which is an invalid operation following peer_detach. + */ + if (peer && peer->valid) { + return peer; + } + return NULL; +} + +void +ol_txrx_peer_find_hash_add( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer); + +struct ol_txrx_peer_t * +ol_txrx_peer_find_hash_find( + struct ol_txrx_pdev_t *pdev, + u_int8_t *peer_mac_addr, + int mac_addr_is_aligned, + u_int8_t check_valid); + +struct +ol_txrx_peer_t * +ol_txrx_peer_vdev_find_hash( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_vdev_t *vdev, + u_int8_t *peer_mac_addr, + int mac_addr_is_aligned, + u_int8_t check_valid); + +void +ol_txrx_peer_find_hash_remove( + struct ol_txrx_pdev_t *pdev, + struct ol_txrx_peer_t *peer); + +void +ol_txrx_peer_find_hash_erase( + struct ol_txrx_pdev_t *pdev); + +struct ol_txrx_peer_t * +ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev); + +#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5 +void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent); +#else +#define ol_txrx_peer_find_display(pdev, indent) +#endif /* TXRX_DEBUG_LEVEL */ + +#endif /* _OL_TXRX_PEER_FIND__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_types.h new file mode 100644 index 0000000000000..8343101e757a2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -0,0 +1,905 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_types.h + * @brief Define the major data types used internally by the host datapath SW. + */ +#ifndef _OL_TXRX_TYPES__H_ +#define _OL_TXRX_TYPES__H_ + +#include /* adf_nbuf_t */ +#include /* TAILQ */ +#include /* A_UINT8 */ +#include /* htt_sec_type, htt_pkt_type, etc. */ +#include /* adf_os_atomic_t */ +#include /* wdi_event_subscribe */ +#include /* adf_os_timer_t */ +#include /* adf_os_spinlock */ +#include /* ol_pktlog_dev_handle */ +#include +#include +#include "ol_txrx_htt_api.h" +#include "ol_htt_tx_api.h" +#include "ol_htt_rx_api.h" +#include "wlan_qct_tl.h" +#include +#include +/* + * The target may allocate multiple IDs for a peer. + * In particular, the target may allocate one ID to represent the + * multicast key the peer uses, and another ID to represent the + * unicast key the peer uses. + */ +#define MAX_NUM_PEER_ID_PER_PEER 8 + +#define OL_TXRX_MAC_ADDR_LEN 6 + +/* OL_TXRX_NUM_EXT_TIDS - + * 16 "real" TIDs + 3 pseudo-TIDs for mgmt, mcast/bcast & non-QoS data + */ +#define OL_TXRX_NUM_EXT_TIDS 19 + +#define OL_TX_NUM_QOS_TIDS 16 /* 16 regular TIDs */ +#define OL_TX_NON_QOS_TID 16 +#define OL_TX_MGMT_TID 17 +#define OL_TX_NUM_TIDS 18 + +#define OL_TX_VDEV_MCAST_BCAST 0 // HTT_TX_EXT_TID_MCAST_BCAST +#define OL_TX_VDEV_DEFAULT_MGMT 1 // HTT_TX_EXT_TID_DEFALT_MGMT +#define OL_TX_VDEV_NUM_QUEUES 2 + +#define OL_TXRX_MGMT_TYPE_BASE htt_pkt_num_types +#define OL_TXRX_MGMT_NUM_TYPES 8 + +#define OL_TX_MUTEX_TYPE adf_os_spinlock_t +#define OL_RX_MUTEX_TYPE adf_os_spinlock_t + +struct ol_txrx_pdev_t; +struct ol_txrx_vdev_t; +struct ol_txrx_peer_t; + +struct ol_pdev_t; +typedef struct ol_pdev_t* ol_pdev_handle; + +struct ol_vdev_t; +typedef struct ol_vdev_t* ol_vdev_handle; + +struct ol_peer_t; +typedef struct ol_peer_t* ol_peer_handle; + +/* rx filter related */ +#define MAX_PRIVACY_FILTERS 4 /* max privacy filters */ + +typedef enum _privacy_filter { + PRIVACY_FILTER_ALWAYS, + PRIVACY_FILTER_KEY_UNAVAILABLE, +} privacy_filter ; + +typedef enum _privacy_filter_packet_type { + PRIVACY_FILTER_PACKET_UNICAST, + PRIVACY_FILTER_PACKET_MULTICAST, + PRIVACY_FILTER_PACKET_BOTH +} privacy_filter_packet_type ; + +typedef struct _privacy_excemption_filter { + /* ethertype - + * type of ethernet frames this filter applies to, in host byte order + */ + u_int16_t ether_type; + privacy_filter filter_type; + privacy_filter_packet_type packet_type; +} privacy_exemption; + +enum ol_tx_frm_type { + ol_tx_frm_std = 0, /* regular frame - no added header fragments */ + ol_tx_frm_tso, /* TSO segment, with a modified IP header added */ + ol_tx_frm_audio, /* audio frames, with a custom LLC/SNAP header added */ + ol_tx_frm_no_free, /* frame requires special tx completion callback */ +}; + +struct ol_tx_desc_t { + adf_nbuf_t netbuf; + void *htt_tx_desc; + u_int32_t htt_tx_desc_paddr; + adf_os_atomic_t ref_cnt; + enum htt_tx_status status; + +#ifdef QCA_COMPUTE_TX_DELAY + u_int32_t entry_timestamp_ticks; +#endif + /* + * Allow tx descriptors to be stored in (doubly-linked) lists. + * This is mainly used for HL tx queuing and scheduling, but is + * also used by LL+HL for batch processing of tx frames. + */ + TAILQ_ENTRY(ol_tx_desc_t) tx_desc_list_elem; + + /* + * Remember whether the tx frame is a regular packet, or whether + * the driver added extra header fragments (e.g. a modified IP header + * for TSO fragments, or an added LLC/SNAP header for audio interworking + * data) that need to be handled in a special manner. + * This field is filled in with the ol_tx_frm_type enum. + */ + u_int8_t pkt_type; +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + /* used by tx encap, to restore the os buf start offset after tx complete*/ + u_int8_t orig_l2_hdr_bytes; +#endif +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + struct ol_txrx_vdev_t* vdev; +#endif +}; + +typedef TAILQ_HEAD(, ol_tx_desc_t) ol_tx_desc_list; + +union ol_tx_desc_list_elem_t { + union ol_tx_desc_list_elem_t *next; + struct ol_tx_desc_t tx_desc; +}; + +union ol_txrx_align_mac_addr_t { + u_int8_t raw[OL_TXRX_MAC_ADDR_LEN]; + struct { + u_int16_t bytes_ab; + u_int16_t bytes_cd; + u_int16_t bytes_ef; + } align2; + struct { + u_int32_t bytes_abcd; + u_int16_t bytes_ef; + } align4; +}; + +struct ol_rx_reorder_timeout_list_elem_t +{ + TAILQ_ENTRY(ol_rx_reorder_timeout_list_elem_t) reorder_timeout_list_elem; + u_int32_t timestamp_ms; + struct ol_txrx_peer_t *peer; + u_int8_t tid; + u_int8_t active; +}; + +#define TXRX_TID_TO_WMM_AC(_tid) (\ + (((_tid) >> 1) == 3) ? TXRX_WMM_AC_VO : \ + (((_tid) >> 1) == 2) ? TXRX_WMM_AC_VI : \ + (((_tid) ^ ((_tid) >> 1)) & 0x1) ? TXRX_WMM_AC_BK : \ + TXRX_WMM_AC_BE) + +struct ol_tx_reorder_cat_timeout_t { + TAILQ_HEAD(, ol_rx_reorder_timeout_list_elem_t) virtual_timer_list; + adf_os_timer_t timer; + u_int32_t duration_ms; + struct ol_txrx_pdev_t *pdev; +}; + +enum ol_tx_scheduler_status { + ol_tx_scheduler_idle = 0, + ol_tx_scheduler_running, +}; + +enum ol_tx_queue_status { + ol_tx_queue_empty = 0, + ol_tx_queue_active, + ol_tx_queue_paused, +}; + +struct ol_txrx_msdu_info_t { + struct htt_msdu_info_t htt; + struct ol_txrx_peer_t *peer; +}; + +enum { + ol_tx_aggr_untried = 0, + ol_tx_aggr_enabled, + ol_tx_aggr_disabled, + ol_tx_aggr_retry, + ol_tx_aggr_in_progress, +}; + +struct ol_tx_frms_queue_t { + /* list_elem - + * Allow individual tx frame queues to be linked together into + * scheduler queues of tx frame queues + */ + TAILQ_ENTRY(ol_tx_frms_queue_t) list_elem; + u_int8_t aggr_state; + struct { + u_int8_t total; + /* pause requested by ctrl SW rather than txrx SW */ + u_int8_t by_ctrl; + } paused_count; + u_int8_t ext_tid; + u_int16_t frms; + u_int32_t bytes; + ol_tx_desc_list head; + enum ol_tx_queue_status flag; +}; + +enum { + ol_tx_log_entry_type_invalid, + ol_tx_log_entry_type_queue_state, + ol_tx_log_entry_type_enqueue, + ol_tx_log_entry_type_dequeue, + ol_tx_log_entry_type_drop, + ol_tx_log_entry_type_queue_free, + + ol_tx_log_entry_type_wrap, +}; + +struct ol_tx_log_queue_state_var_sz_t { + u_int32_t active_bitmap; + u_int16_t credit; + u_int8_t num_cats_active; + u_int8_t data[1]; +}; + +struct ol_tx_log_queue_add_t { + u_int8_t num_frms; + u_int8_t tid; + u_int16_t peer_id; + u_int16_t num_bytes; +}; + +struct ol_mac_addr { + u_int8_t mac_addr[OL_TXRX_MAC_ADDR_LEN]; +}; + +struct ol_tx_sched_t; +typedef struct ol_tx_sched_t *ol_tx_sched_handle; + +#ifndef OL_TXRX_NUM_LOCAL_PEER_IDS +#define OL_TXRX_NUM_LOCAL_PEER_IDS 33 /* default */ +#endif + +#ifndef ol_txrx_local_peer_id_t +#define ol_txrx_local_peer_id_t u_int8_t /* default */ +#endif + +#ifdef QCA_COMPUTE_TX_DELAY +/* + * Delay histogram bins: 16 bins of 10 ms each to count delays + * from 0-160 ms, plus one overflow bin for delays > 160 ms. + */ +#define QCA_TX_DELAY_HIST_INTERNAL_BINS 17 +#define QCA_TX_DELAY_HIST_INTERNAL_BIN_WIDTH_MS 10 + +struct ol_tx_delay_data { + struct { + u_int64_t transmit_sum_ticks; + u_int64_t queue_sum_ticks; + u_int32_t transmit_num; + u_int32_t queue_num; + } avgs; + u_int16_t hist_bins_queue[QCA_TX_DELAY_HIST_INTERNAL_BINS]; +}; + +#endif /* QCA_COMPUTE_TX_DELAY */ + +/* Thermal Mitigation */ + +typedef enum _throttle_level { + THROTTLE_LEVEL_0, + THROTTLE_LEVEL_1, + THROTTLE_LEVEL_2, + THROTTLE_LEVEL_3, + /* Invalid */ + THROTTLE_LEVEL_MAX, +} throttle_level ; + +typedef enum _throttle_phase { + THROTTLE_PHASE_OFF, + THROTTLE_PHASE_ON, + /* Invalid */ + THROTTLE_PHASE_MAX, +} throttle_phase ; + +#define THROTTLE_TX_THRESHOLD (100) + +#ifdef IPA_UC_OFFLOAD +typedef void (*ipa_uc_op_cb_type)(u_int8_t *op_msg, void *osif_ctxt); +#endif /* IPA_UC_OFFLOAD */ + +/* + * As depicted in the diagram below, the pdev contains an array of + * NUM_EXT_TID ol_tx_active_queues_in_tid_t elements. + * Each element identifies all the tx queues that are active for + * the TID, from the different peers. + * + * Each peer contains an array of NUM_EXT_TID ol_tx_frms_queue_t elements. + * Each element identifies the tx frames for the TID that need to be sent + * to the peer. + * + * + * pdev: ol_tx_active_queues_in_tid_t active_in_tids[NUM_EXT_TIDS] + * TID + * 0 1 2 17 + * +============+============+============+== ==+============+ + * | active (y) | active (n) | active (n) | | active (y) | + * |------------+------------+------------+-- --+------------| + * | queues | queues | queues | | queues | + * +============+============+============+== ==+============+ + * | | + * .--+-----------------------------------------------' + * | | + * | | peer X: peer Y: + * | | ol_tx_frms_queue_t ol_tx_frms_queue_t + * | | tx_queues[NUM_EXT_TIDS] tx_queues[NUM_EXT_TIDS] + * | | TID +======+ TID +======+ + * | `---->| next |-------------------------->| next |--X + * | 0 | prev | .------. .------. 0 | prev | .------. + * | | txq |-->|txdesc|-->|txdesc| | txq |-->|txdesc| + * | +======+ `------' `------' +======+ `------' + * | | next | | | 1 | next | | + * | 1 | prev | v v | prev | v + * | | txq | .------. .------. | txq | .------. + * | +======+ |netbuf| |netbuf| +======+ |netbuf| + * | | next | `------' `------' | next | `------' + * | 2 | prev | 2 | prev | + * | | txq | | txq | + * | +======+ +======+ + * | | | | | + * | + * | + * | | | | | + * | +======+ +======+ + * `------->| next |--X | next | + * 17 | prev | .------. 17 | prev | + * | txq |-->|txdesc| | txq | + * +======+ `------' +======+ + * | + * v + * .------. + * |netbuf| + * `------' + */ +struct ol_txrx_pdev_t { + /* ctrl_pdev - handle for querying config info */ + ol_pdev_handle ctrl_pdev; + + /* osdev - handle for mem alloc / free, map / unmap */ + adf_os_device_t osdev; + + htt_pdev_handle htt_pdev; + + struct { + int is_high_latency; + int host_addba; + int ll_pause_txq_limit; + int default_tx_comp_req; + } cfg; + + /* WDI subscriber's event list */ + wdi_event_subscribe **wdi_event_list; + +#ifndef REMOVE_PKT_LOG + /* Pktlog pdev */ + struct ol_pktlog_dev_t* pl_dev; +#endif /* #ifndef REMOVE_PKT_LOG */ + + enum ol_sec_type sec_types[htt_num_sec_types]; + /* standard frame type */ + enum wlan_frm_fmt frame_format; + enum htt_pkt_type htt_pkt_type; + +#ifdef QCA_SUPPORT_SW_TXRX_ENCAP + /* txrx encap/decap */ + u_int8_t sw_tx_encap; + u_int8_t sw_rx_decap; + u_int8_t target_tx_tran_caps; + u_int8_t target_rx_tran_caps; + /* llc process */ + u_int8_t sw_tx_llc_proc_enable; + u_int8_t sw_rx_llc_proc_enable; + /* A-MSDU */ + u_int8_t sw_subfrm_hdr_recovery_enable; + /* Protected Frame bit handling */ + u_int8_t sw_pf_proc_enable; +#endif + /* + * target tx credit - + * not needed for LL, but used for HL download scheduler to keep + * track of roughly how much space is available in the target for + * tx frames + */ + adf_os_atomic_t target_tx_credit; + adf_os_atomic_t orig_target_tx_credit; + + /* Peer mac address to staid mapping */ + struct ol_mac_addr mac_to_staid[WLAN_MAX_STA_COUNT + 3]; + + /* ol_txrx_vdev list */ + TAILQ_HEAD(, ol_txrx_vdev_t) vdev_list; + + /* peer ID to peer object map (array of pointers to peer objects) */ + struct ol_txrx_peer_t **peer_id_to_obj_map; + + struct { + unsigned mask; + unsigned idx_bits; + TAILQ_HEAD(, ol_txrx_peer_t) *bins; + } peer_hash; + + /* rx specific processing */ + struct { + struct { + TAILQ_HEAD(, ol_rx_reorder_t) waitlist; + u_int32_t timeout_ms; + } defrag; + struct { + int defrag_timeout_check; + int dup_check; + } flags; + + struct { + struct ol_tx_reorder_cat_timeout_t access_cats[TXRX_NUM_WMM_AC]; + } reorder_timeout; + adf_os_spinlock_t mutex; + } rx; + + /* rx proc function */ + void (*rx_opt_proc)( + struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + + /* tx data delivery notification callback function */ + struct { + ol_txrx_data_tx_cb func; + void *ctxt; + } tx_data_callback; + + /* tx management delivery notification callback functions */ + struct { + struct { + ol_txrx_mgmt_tx_cb download_cb; + ol_txrx_mgmt_tx_cb ota_ack_cb; + void *ctxt; + } callbacks[OL_TXRX_MGMT_NUM_TYPES]; + } tx_mgmt; + + /* tx descriptor pool */ + struct { + u_int16_t pool_size; + u_int16_t num_free; + union ol_tx_desc_list_elem_t *array; + union ol_tx_desc_list_elem_t *freelist; + } tx_desc; + + struct { + int (*cmp)( + union htt_rx_pn_t *new, + union htt_rx_pn_t *old, + int is_unicast, + int opmode); + int len; + } rx_pn[htt_num_sec_types]; + + /* tx mutex */ + OL_TX_MUTEX_TYPE tx_mutex; + + /* + * peer ref mutex: + * 1. Protect peer object lookups until the returned peer object's + * reference count is incremented. + * 2. Provide mutex when accessing peer object lookup structures. + */ + OL_RX_MUTEX_TYPE peer_ref_mutex; + + /* + * last_real_peer_mutex: + * Protect lookups of any vdev's last_real_peer pointer until the + * reference count for the pointed-to peer object is incremented. + * This mutex could be in the vdev struct, but it's slightly simpler + * to have a single lock in the pdev struct. Since the lock is only + * held for an extremely short time, and since it's very unlikely for + * two vdev's to concurrently access the lock, there's no real + * benefit to having a per-vdev lock. + */ + OL_RX_MUTEX_TYPE last_real_peer_mutex; + + +#if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF + struct { + struct { + struct { + struct { + u_int64_t ppdus; + u_int64_t mpdus; + } normal; + struct { + /* + * mpdu_bad is general - + * replace it with the specific counters below + */ + u_int64_t mpdu_bad; + //u_int64_t mpdu_fcs; + //u_int64_t mpdu_duplicate; + //u_int64_t mpdu_pn_replay; + //u_int64_t mpdu_bad_sender; /* peer not found */ + //u_int64_t mpdu_flushed; + //u_int64_t msdu_defrag_mic_err; + } err; + } rx; + } priv; + struct ol_txrx_stats pub; + } stats; +#endif /* TXRX_STATS_LEVEL */ + +#if defined(ENABLE_RX_REORDER_TRACE) + struct { + u_int32_t mask; + u_int32_t idx; + u_int64_t cnt; +#define TXRX_RX_REORDER_TRACE_SIZE_LOG2 8 /* 256 entries */ + struct { + u_int16_t reorder_idx; + u_int16_t seq_num; + u_int8_t num_mpdus; + u_int8_t tid; + } *data; + } rx_reorder_trace; +#endif /* ENABLE_RX_REORDER_TRACE */ + +#if defined(ENABLE_RX_PN_TRACE) + struct { + u_int32_t mask; + u_int32_t idx; + u_int64_t cnt; +#define TXRX_RX_PN_TRACE_SIZE_LOG2 5 /* 32 entries */ + struct { + struct ol_txrx_peer_t *peer; + u_int32_t pn32; + u_int16_t seq_num; + u_int8_t unicast; + u_int8_t tid; + } *data; + } rx_pn_trace; +#endif /* ENABLE_RX_PN_TRACE */ + +#if defined(PERE_IP_HDR_ALIGNMENT_WAR) + bool host_80211_enable; +#endif + + /* + * tx_sched only applies for HL, but is defined unconditionally rather than + * only if defined(CONFIG_HL_SUPPORT). This is because the struct only + * occupies a few bytes, and to avoid the complexity of wrapping references + * to the struct members in "defined(CONFIG_HL_SUPPORT)" conditional + * compilation. + * If this struct gets expanded to a non-trivial size, then it should be + * conditionally compiled to only apply if defined(CONFIG_HL_SUPPORT). + */ + adf_os_spinlock_t tx_queue_spinlock; + struct { + enum ol_tx_scheduler_status tx_sched_status; + ol_tx_sched_handle scheduler; + } tx_sched; + /* + * tx_queue only applies for HL, but is defined unconditionally to avoid + * wrapping references to tx_queue in "defined(CONFIG_HL_SUPPORT)" + * conditional compilation. + */ + struct { + adf_os_atomic_t rsrc_cnt; + /* threshold_lo - when to start tx desc margin replenishment */ + u_int16_t rsrc_threshold_lo; + /* threshold_hi - where to stop during tx desc margin replenishment */ + u_int16_t rsrc_threshold_hi; + } tx_queue; + +#if defined(ENABLE_TX_QUEUE_LOG) && defined(CONFIG_HL_SUPPORT) +#define OL_TXQ_LOG_SIZE 1024 + struct { + int size; + int oldest_record_offset; + int offset; + int allow_wrap; + u_int32_t wrapped; + u_int8_t data[OL_TXQ_LOG_SIZE]; /* aligned to u_int32_t boundary */ + } txq_log; +#endif + +#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS + adf_os_spinlock_t peer_stat_mutex; +#endif + + int rssi_update_shift; + int rssi_new_weight; +#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID + struct { + ol_txrx_local_peer_id_t pool[OL_TXRX_NUM_LOCAL_PEER_IDS+1]; + ol_txrx_local_peer_id_t freelist; + adf_os_spinlock_t lock; + ol_txrx_peer_handle map[OL_TXRX_NUM_LOCAL_PEER_IDS]; + } local_peer_ids; +#endif + +#ifdef QCA_COMPUTE_TX_DELAY +#ifdef QCA_COMPUTE_TX_DELAY_PER_TID +#define QCA_TX_DELAY_NUM_CATEGORIES \ + (OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES) +#else +#define QCA_TX_DELAY_NUM_CATEGORIES 1 +#endif + struct { + adf_os_spinlock_t mutex; + struct { + struct ol_tx_delay_data copies[2/*ping-pong updating*/]; + int in_progress_idx; + u_int32_t avg_start_time_ticks; + } cats[QCA_TX_DELAY_NUM_CATEGORIES]; + u_int32_t tx_compl_timestamp_ticks; + u_int32_t avg_period_ticks; + u_int32_t hist_internal_bin_width_mult; + u_int32_t hist_internal_bin_width_shift; + } tx_delay; + + u_int16_t packet_count[QCA_TX_DELAY_NUM_CATEGORIES]; + u_int16_t packet_loss_count[QCA_TX_DELAY_NUM_CATEGORIES]; + +#endif /* QCA_COMPUTE_TX_DELAY */ + + struct { + adf_os_spinlock_t mutex; + /* timer used to monitor the throttle "on" phase and "off" phase */ + adf_os_timer_t phase_timer; + /* timer used to send tx frames */ + adf_os_timer_t tx_timer; + /*This is the time in ms of the throttling window, it will include an + "on" phase and an "off" phase */ + u_int32_t throttle_period_ms; + /* Current throttle level set by the client ex. level 0, level 1, etc*/ + throttle_level current_throttle_level; + /* Index that points to the phase within the throttle period */ + throttle_phase current_throttle_phase; + /* Maximum number of frames to send to the target at one time */ + u_int32_t tx_threshold; + /* stores time in ms of on and off phase for each throttle level*/ + int throttle_time_ms[THROTTLE_LEVEL_MAX][THROTTLE_PHASE_MAX]; + /* mark as true if traffic is paused due to thermal throttling */ + a_bool_t is_paused; + } tx_throttle; + +#ifdef IPA_UC_OFFLOAD + ipa_uc_op_cb_type ipa_uc_op_cb; + void *osif_dev; +#endif /* IPA_UC_OFFLOAD */ +}; + +struct ol_txrx_vdev_t { + /* pdev - the physical device that is the parent of this virtual device */ + struct ol_txrx_pdev_t *pdev; + + /* vdev_id - ID used to specify a particular vdev to the target */ + u_int8_t vdev_id; + + void *osif_dev; + + /* MAC address */ + union ol_txrx_align_mac_addr_t mac_addr; + + /* tx paused - NO LONGER NEEDED? */ + + /* node in the pdev's list of vdevs */ + TAILQ_ENTRY(ol_txrx_vdev_t) vdev_list_elem; + + /* ol_txrx_peer list */ + TAILQ_HEAD(peer_list_t, ol_txrx_peer_t) peer_list; + /* last real peer created for this vdev (not "self" pseudo-peer) */ + struct ol_txrx_peer_t *last_real_peer; + + /* transmit function used by this vdev */ + ol_txrx_tx_fp tx; + + /* receive function used by this vdev to hand rx frames to the OS shim */ + ol_txrx_rx_fp osif_rx; + + struct { + /* + * If the vdev object couldn't be deleted immediately because it still + * had some peer objects left, remember that a delete was requested, + * so it can be deleted once all its peers have been deleted. + */ + int pending; + /* + * Store a function pointer and a context argument to provide a + * notification for when the vdev is deleted. + */ + ol_txrx_vdev_delete_cb callback; + void *context; + } delete; + + /* safe mode control to bypass the encrypt and decipher process*/ + u_int32_t safemode; + + /* rx filter related */ + u_int32_t drop_unenc; + privacy_exemption privacy_filters[MAX_PRIVACY_FILTERS]; + u_int32_t num_filters; + + enum wlan_op_mode opmode; + +#ifdef QCA_IBSS_SUPPORT + /* ibss mode related */ + int16_t ibss_peer_num; /* the number of active peers */ + int16_t ibss_peer_heart_beat_timer; /* for detecting peer departure */ +#endif + +#if defined(CONFIG_HL_SUPPORT) + struct ol_tx_frms_queue_t txqs[OL_TX_VDEV_NUM_QUEUES]; +#endif + + struct { + struct { + adf_nbuf_t head; + adf_nbuf_t tail; + int depth; + } txq; + u_int32_t paused_reason; + adf_os_spinlock_t mutex; + adf_os_timer_t timer; + int max_q_depth; + } ll_pause; + a_bool_t disable_intrabss_fwd; + adf_os_atomic_t os_q_paused; + u_int16_t tx_fl_lwm; + u_int16_t tx_fl_hwm; + ol_txrx_tx_flow_control_fp osif_flow_control_cb; + +#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + union ol_txrx_align_mac_addr_t hl_tdls_ap_mac_addr; + bool hlTdlsFlag; +#endif +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + adf_os_atomic_t tx_desc_count; +#endif + u_int16_t wait_on_peer_id; + adf_os_comp_t wait_delete_comp; +}; + +struct ol_rx_reorder_array_elem_t { + adf_nbuf_t head; + adf_nbuf_t tail; +}; + +struct ol_rx_reorder_t { + u_int8_t win_sz; + u_int8_t win_sz_mask; + u_int8_t num_mpdus; + struct ol_rx_reorder_array_elem_t *array; + /* base - single rx reorder element used for non-aggr cases */ + struct ol_rx_reorder_array_elem_t base; +#if defined(QCA_SUPPORT_OL_RX_REORDER_TIMEOUT) + struct ol_rx_reorder_timeout_list_elem_t timeout; +#endif + /* only used for defrag right now */ + TAILQ_ENTRY(ol_rx_reorder_t) defrag_waitlist_elem; + u_int32_t defrag_timeout_ms; + /* get back to parent ol_txrx_peer_t when ol_rx_reorder_t is in a + * waitlist */ + u_int16_t tid; +}; + +enum { + txrx_sec_mcast = 0, + txrx_sec_ucast +}; + +typedef A_STATUS (*ol_tx_filter_func)(struct ol_txrx_msdu_info_t *tx_msdu_info); + +struct ol_txrx_peer_t { + struct ol_txrx_vdev_t *vdev; + + adf_os_atomic_t ref_cnt; + adf_os_atomic_t delete_in_progress; + + /* The peer state tracking is used for HL systems + * that don't support tx and rx filtering within the target. + * In such systems, the peer's state determines what kind of + * tx and rx filtering, if any, is done. + * This variable doesn't apply to LL systems, or to HL systems for + * which the target handles tx and rx filtering. However, it is + * simplest to declare and update this variable unconditionally, + * for all systems. + */ + enum ol_txrx_peer_state state; + ol_tx_filter_func tx_filter; + + /* peer ID(s) for this peer */ + u_int16_t peer_ids[MAX_NUM_PEER_ID_PER_PEER]; +#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID + u_int16_t local_id; +#endif + + union ol_txrx_align_mac_addr_t mac_addr; + + /* node in the vdev's list of peers */ + TAILQ_ENTRY(ol_txrx_peer_t) peer_list_elem; + /* node in the hash table bin's list of peers */ + TAILQ_ENTRY(ol_txrx_peer_t) hash_list_elem; + + /* + * per TID info - + * stored in separate arrays to avoid alignment padding mem overhead + */ + struct ol_rx_reorder_t tids_rx_reorder[OL_TXRX_NUM_EXT_TIDS]; + union htt_rx_pn_t tids_last_pn[OL_TXRX_NUM_EXT_TIDS]; + u_int8_t tids_last_pn_valid[OL_TXRX_NUM_EXT_TIDS]; + u_int16_t tids_next_rel_idx[OL_TXRX_NUM_EXT_TIDS]; + u_int16_t tids_last_seq[OL_TXRX_NUM_EXT_TIDS]; + + struct { + enum htt_sec_type sec_type; + u_int32_t michael_key[2]; /* relevant for TKIP */ + } security[2]; /* 0 -> multicast, 1 -> unicast */ + + /* + * rx proc function: this either is a copy of pdev's rx_opt_proc for + * regular rx processing, or has been redirected to a /dev/null discard + * function when peer deletion is in progress. + */ + void (*rx_opt_proc)(struct ol_txrx_vdev_t *vdev, + struct ol_txrx_peer_t *peer, + unsigned tid, + adf_nbuf_t msdu_list); + +#if defined(CONFIG_HL_SUPPORT) + struct ol_tx_frms_queue_t txqs[OL_TX_NUM_TIDS]; +#endif + +#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS + ol_txrx_peer_stats_t stats; +#endif + int16_t rssi_dbm; + + /* NAWDS Flag and Bss Peer bit */ + u_int16_t nawds_enabled:1, + bss_peer:1, + valid:1; + + /* QoS info*/ + u_int8_t qos_capable; + /* U-APSD tid mask */ + u_int8_t uapsd_mask; + /*flag indicating key installed*/ + u_int8_t keyinstalled; + + /* Bit to indicate if PN check is done in fw */ + adf_os_atomic_t fw_pn_check; + +#ifdef WLAN_FEATURE_11W + /* PN counter for Robust Management Frames */ + u_int64_t last_rmf_pn; + u_int32_t rmf_pn_replays; + u_int8_t last_rmf_pn_valid; +#endif +}; + +#endif /* _OL_TXRX_TYPES__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/txrx.h b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/txrx.h new file mode 100644 index 0000000000000..12e1f619bd4d0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TXRX/txrx.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef TXRX_H +#define TXRX_H + +#include "vos_api.h" +#include "adf_nbuf.h" +#include "csrApi.h" +#include "sapApi.h" +#include "adf_nbuf.h" +#include "ol_txrx_osif_api.h" +#include "wlan_qct_tl.h" + +/* wait on peer deletion timeout value in milliseconds */ +#define PEER_DELETION_TIMEOUT 500 + +enum txrx_wmm_ac { + TXRX_WMM_AC_VO, + TXRX_WMM_AC_VI, + TXRX_WMM_AC_BK, + TXRX_WMM_AC_BE, + + TXRX_NUM_WMM_AC +}; + +struct txrx_rx_metainfo { + u8 up; + u16 dest_staid; +}; + +enum bt_frame_type { + /* BT-AMP packet of type data */ + TXRX_BT_AMP_TYPE_DATA = 0x0001, + + /* BT-AMP packet of type activity report */ + TXRX_BT_AMP_TYPE_AR = 0x0002, + + /* BT-AMP packet of type security frame */ + TXRX_BT_AMP_TYPE_SEC = 0x0003, + + /* BT-AMP packet of type Link Supervision request frame */ + TXRX_BT_AMP_TYPE_LS_REQ = 0x0004, + + /* BT-AMP packet of type Link Supervision reply frame */ + TXRX_BT_AMP_TYPE_LS_REP = 0x0005, + + /* Invalid Frame */ + TXRX_BAP_INVALID_FRAME + +}; + +enum wlan_ts_direction { + /* uplink */ + WLAN_TX_DIR = 0, + + /* downlink */ + WLAN_RX_DIR = 1, + + /*bidirectional*/ + WLAN_BI_DIR = 2, +}; + +enum wlan_sta_state { + /* Transition in this state made upon creation*/ + WLAN_STA_INIT = 0, + + /* Transition happens after Assoc success if second level authentication + is needed*/ + WLAN_STA_CONNECTED, + + /* Transition happens when second level auth is successful and keys are + properly installed */ + WLAN_STA_AUTHENTICATED, + + /* Transition happens when connectivity is lost*/ + WLAN_STA_DISCONNECTED, + + WLAN_STA_MAX_STATE +}; + +struct wlan_txrx_stats { + /* Define various txrx stats here*/ +}; + +struct ol_txrx_vdev_t; + +VOS_STATUS wlan_register_mgmt_client(void *pdev_txrx, + VOS_STATUS (*rx_mgmt)(void *g_vosctx, + void *buf)); + +typedef void (*ol_txrx_vdev_delete_cb)(void *context); + +/** + * @typedef ol_txrx_tx_fp + * @brief top-level transmit function + */ +typedef adf_nbuf_t +(*ol_txrx_tx_fp)(struct ol_txrx_vdev_t *vdev, adf_nbuf_t msdu_list); + +typedef void +(*ol_txrx_mgmt_tx_cb)(void *ctxt, adf_nbuf_t tx_mgmt_frm, int had_error); + +/* If RSSI realm is changed, send notification to Clients, SME, HDD */ +typedef VOS_STATUS (*wlan_txrx_rssi_cross_thresh) (void *adapter, u8 rssi, + void *usr_ctx, v_S7_t avg_rssi); + +struct wlan_txrx_ind_req { + u16 msgType; // message type is same as the request type + u16 msgLen; // length of the entire request + u8 sessionId; //sme Session Id + u8 rssiNotification; + u8 avgRssi; + void *tlCallback; + void *pAdapter; + void *pUserCtxt; +}; + +struct wlan_txrx_config_param { + u8 ucAcWeights[TXRX_NUM_WMM_AC]; + u32 uDelayedTriggerFrmInt; + u8 uMinFramesProcThres; +}; + +/* Rx callback registered with txrx */ +typedef int (*wlan_txrx_cb_type)( void *g_vosctx, adf_nbuf_t buf, u8 sta_id, + struct txrx_rx_metainfo *rx_meta_info); + +static inline int wlan_txrx_get_rssi(void *g_vosctx, u8 sta_id, v_S7_t *rssi) +{ + return 0; +} + +static inline int wlan_txrx_enable_uapsd_ac(void *g_vosctx, u8 sta_id, + enum txrx_wmm_ac ac, u8 tid, u8 up, + u32 srv_int, u32 suspend_int, + enum wlan_ts_direction ts_dir) +{ + return 0; +} + +static inline int wlan_txrx_disable_uapsd_ac(void *g_vosctx, u8 sta_id, + enum txrx_wmm_ac ac) +{ + return 0; +} + +static inline int wlan_change_sta_state(void *g_vosctx, u8 sta_id, + enum wlan_sta_state state) +{ + return 0; +} + +static inline int wlan_deregister_mgmt_client(void *g_vosctx) +{ + return 0; +} + +static inline void wlan_assoc_failed(u8 staid) +{ +} + +static inline int wlan_get_ap_stats(void *g_vosctx, tSap_SoftapStats *buf, + bool reset) +{ + return 0; +} + +static inline int wlan_get_txrx_stats(void *g_vosctx, struct wlan_txrx_stats *stats, + u8 sta_id) +{ + return 0; +} + +static inline int wlan_txrx_update_rssi_bmps(void *g_vosctx, u8 sta_id, + v_S7_t rssi) +{ + return 0; +} + +static inline int wlan_txrx_deregister_rssi_indcb(void *g_vosctx, + v_S7_t rssi_val, + u8 trigger_event, + wlan_txrx_rssi_cross_thresh cb, + int mod_id) +{ + return 0; +} + +static inline int wlan_txrx_register_rssi_indcb(void *g_vosctx, + v_S7_t rssi_val, + u8 trigger_event, + wlan_txrx_rssi_cross_thresh cb, + int mod_id, void *usr_ctx) +{ + return 0; +} + +/* FIXME: The following stubs will be removed eventually */ +static inline int wlan_txrx_mc_process_msg(void *g_vosctx, vos_msg_t *msg) +{ + return 0; +} + +static inline int wlan_txrx_tx_process_msg(void *g_vosctx, vos_msg_t *msg) +{ + return 0; +} + +static inline void wlan_txrx_mc_free_msg(void *g_vosctx, vos_msg_t *msg) +{ +} +static inline void wlan_txrx_tx_free_msg(void *g_vosctx, vos_msg_t *msg) +{ +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_internal.h b/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_internal.h new file mode 100644 index 0000000000000..2e1d8a0b2a99a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_internal.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +#ifndef EPPING_INTERNAL_H +#define EPPING_INTERNAL_H +/**=========================================================================== + + \file epping_internal.h + + \brief Linux epping internal head file + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif +#include +#include "htc_api.h" +#include "htc_packet.h" +#include "epping_test.h" +#include + +#define EPPING_LOG_MASK (1< + +#define WLAN_EPPING_ENABLE_BIT (1 << 8) +#define WLAN_EPPING_IRQ_BIT (1 << 9) +#define WLAN_EPPING_FW_UART_BIT (1 << 10) +#define WLAN_IS_EPPING_ENABLED(x) (x & WLAN_EPPING_ENABLE_BIT) +#define WLAN_IS_EPPING_IRQ(x) (x & WLAN_EPPING_IRQ_BIT) +#define WLAN_IS_EPPING_FW_UART(x) (x & WLAN_EPPING_FW_UART_BIT) + +/* epping_main signatures */ +int epping_driver_init(int con_mode, vos_wake_lock_t *g_wake_lock, + char *pwlan_module_name); +void epping_driver_exit(v_CONTEXT_t pVosContext); +void epping_exit(v_CONTEXT_t pVosContext); +int epping_wlan_startup(struct device *dev, v_VOID_t *hif_sc); +#endif /* end #ifndef EPPING_MAIN_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_test.h b/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_test.h new file mode 100644 index 0000000000000..feacdbbdf69ac --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/inc/epping_test.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + */ +//------------------------------------------------------------------------------ +// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +// + +/* This file contains shared definitions for the host/target endpoint ping test */ + +#ifndef EPPING_TEST_H +#define EPPING_TEST_H + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif + + /* alignment to 4-bytes */ +#define EPPING_ALIGNMENT_PAD (((sizeof(HTC_FRAME_HDR) + 3) & (~0x3)) - sizeof(HTC_FRAME_HDR)) + +#ifndef A_OFFSETOF +#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field)) +#endif + +#define EPPING_RSVD_FILL 0xCC + +#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7 + +typedef PREPACK struct { + A_UINT8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */ + A_UINT8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */ + A_UINT8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target) + When echoed: StreamEchoSent_t == StreamEcho_h */ + A_UINT8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */ + A_UINT8 StreamNo_h; /* stream number to send on (filled by host) */ + A_UINT8 Magic_h[4]; /* magic number to filter for this packet on the host*/ + A_UINT8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value + since this packet maps to a 14-byte ethernet frame we want + to make sure ethertype field is set to something unknown */ + + A_UINT8 _pad[2]; /* padding for alignment */ + A_UINT8 TimeStamp[8]; /* timestamp of packet (host or target) */ + A_UINT32 HostContext_h; /* 4 byte host context, target echos this back */ + A_UINT32 SeqNo; /* sequence number (set by host or target) */ + A_UINT16 Cmd_h; /* ping command (filled by host) */ + A_UINT16 CmdFlags_h; /* optional flags */ + A_UINT8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ + A_UINT8 CmdBuffer_t[8]; /* buffer for command (target -> host) */ + A_UINT16 DataLength; /* length of data */ + A_UINT16 DataCRC; /* 16 bit CRC of data */ + A_UINT16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */ +} POSTPACK EPPING_HEADER; + +#define EPPING_PING_MAGIC_0 0xAA +#define EPPING_PING_MAGIC_1 0x55 +#define EPPING_PING_MAGIC_2 0xCE +#define EPPING_PING_MAGIC_3 0xEC + +#define IS_EPPING_PACKET(pPkt) (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \ + ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \ + ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \ + ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3)) + +#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \ + (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \ + (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \ + (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;} + +#define CMD_FLAGS_DATA_CRC (1 << 0) /* DataCRC field is valid */ +#define CMD_FLAGS_DELAY_ECHO (1 << 1) /* delay the echo of the packet */ +#define CMD_FLAGS_NO_DROP (1 << 2) /* do not drop at HTC layer no matter what the stream is */ + +#define IS_EPING_PACKET_NO_DROP(pPkt) ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP) + +#define EPPING_CMD_ECHO_PACKET 1 /* echo packet test */ +#define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */ +#define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */ +#define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */ +#define EPPING_CMD_CONT_RX_START 5 /* continous RX packets, parameters are in CmdBuffer_h */ +#define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */ + + /* test command parameters may be no more than 8 bytes */ +typedef PREPACK struct { + A_UINT16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */ + A_UINT16 PacketLength; /* length of packet to generate including header */ + A_UINT16 Flags; /* flags */ + +#define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */ +#define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */ +#define EPPING_CONT_RX_RANDOM_LEN (1 << 2) /* randomize the packet lengths */ +#define EPPING_CONT_RX_NO_DATA_FILL (1 << 3) /* target will not fill buffers */ + A_UINT16 Context; /* flags */ + +} POSTPACK EPPING_CONT_RX_PARAMS; + +#define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h) +#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(A_UINT16))) + +#define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we + can use this to distinguish packets */ + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + +#endif /* EPPING_TEST_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_helper.c b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_helper.c new file mode 100644 index 0000000000000..fb720de2ba049 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_helper.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" + +int epping_cookie_init(epping_context_t*pEpping_ctx) +{ + A_UINT32 i, j; + + pEpping_ctx->cookie_list = NULL; + pEpping_ctx->cookie_count = 0; + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + pEpping_ctx->s_cookie_mem[i] = + vos_mem_malloc(sizeof(struct epping_cookie)*MAX_COOKIE_SLOT_SIZE); + if (pEpping_ctx->s_cookie_mem == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: no mem for cookie (idx = %d)", __func__, i); + goto error; + } + vos_mem_zero(pEpping_ctx->s_cookie_mem[i], + sizeof(struct epping_cookie)*MAX_COOKIE_SLOT_SIZE); + } + adf_os_spinlock_init(&pEpping_ctx->cookie_lock); + + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + struct epping_cookie *cookie_mem = pEpping_ctx->s_cookie_mem[i]; + for (j = 0; j < MAX_COOKIE_SLOT_SIZE; j++) { + epping_free_cookie(pEpping_ctx, &cookie_mem[j]); + } + } + return 0; +error: + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + if (pEpping_ctx->s_cookie_mem[i]) { + vos_mem_free(pEpping_ctx->s_cookie_mem[i]); + pEpping_ctx->s_cookie_mem[i] = NULL; + } + } + return -ENOMEM; +} + +/* cleanup cookie queue */ +void epping_cookie_cleanup(epping_context_t*pEpping_ctx) +{ + int i; + adf_os_spin_lock_bh(&pEpping_ctx->cookie_lock); + pEpping_ctx->cookie_list = NULL; + pEpping_ctx->cookie_count = 0; + adf_os_spin_unlock_bh(&pEpping_ctx->cookie_lock); + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + if (pEpping_ctx->s_cookie_mem[i]) { + vos_mem_free(pEpping_ctx->s_cookie_mem[i]); + pEpping_ctx->s_cookie_mem[i] = NULL; + } + } +} + +void epping_free_cookie(epping_context_t*pEpping_ctx, + struct epping_cookie *cookie) +{ + adf_os_spin_lock_bh(&pEpping_ctx->cookie_lock); + cookie->next = pEpping_ctx->cookie_list; + pEpping_ctx->cookie_list = cookie; + pEpping_ctx->cookie_count++; + adf_os_spin_unlock_bh(&pEpping_ctx->cookie_lock); +} + +struct epping_cookie *epping_alloc_cookie(epping_context_t*pEpping_ctx) +{ + struct epping_cookie *cookie; + + adf_os_spin_lock_bh(&pEpping_ctx->cookie_lock); + cookie = pEpping_ctx->cookie_list; + if(cookie != NULL) + { + pEpping_ctx->cookie_list = cookie->next; + pEpping_ctx->cookie_count--; + } + adf_os_spin_unlock_bh(&pEpping_ctx->cookie_lock); + return cookie; +} + +void epping_get_dummy_mac_addr(tSirMacAddr macAddr) +{ + macAddr[0] = 69; /* E */ + macAddr[1] = 80; /* P */ + macAddr[2] = 80; /* P */ + macAddr[3] = 73; /* I */ + macAddr[4] = 78; /* N */ + macAddr[5] = 71; /* G */ +} + +void epping_hex_dump(void *data, int buf_len, const char *str) +{ + char *buf = (char *)data; + int i; + + printk("%s: E, %s\n", __func__, str); + for (i=0; (i+7)< buf_len; i+=8) + { + printk("%02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[i], + buf[i+1], + buf[i+2], + buf[i+3], + buf[i+4], + buf[i+5], + buf[i+6], + buf[i+7]); + } + + // Dump the bytes in the last line + for (; i < buf_len; i++) + { + printk("%02x ", buf[i]); + } + printk("\n%s: X %s\n", __func__, str); +} + + +void *epping_get_adf_ctx(void) +{ + VosContextType *pVosContext = NULL; + adf_os_device_t *pAdfCtx; + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + pAdfCtx = vos_get_context(VOS_MODULE_ID_ADF, pVosContext); + return pAdfCtx; +} + +void epping_log_packet(epping_adapter_t *pAdapter, + EPPING_HEADER *eppingHdr, int ret, const char *str) +{ + if (eppingHdr->Cmd_h & EPPING_LOG_MASK) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: cmd = %d, seqNo = %u, flag = 0x%x, ret = %d, " + "txCount = %lu, txDrop = %lu, txBytes = %lu," + "rxCount = %lu, rxDrop = %lu, rxBytes = %lu\n", + str, eppingHdr->Cmd_h, eppingHdr->SeqNo, + eppingHdr->CmdFlags_h, ret, + pAdapter->stats.tx_packets, + pAdapter->stats.tx_dropped, + pAdapter->stats.tx_bytes, + pAdapter->stats.rx_packets, + pAdapter->stats.rx_dropped, + pAdapter->stats.rx_bytes); + } +} + +void epping_log_stats(epping_adapter_t *pAdapter, const char *str) +{ + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: txCount = %lu, txDrop = %lu, tx_bytes = %lu, " + "rxCount = %lu, rxDrop = %lu, rx_bytes = %lu, tx_acks = %u\n", + str, + pAdapter->stats.tx_packets, + pAdapter->stats.tx_dropped, + pAdapter->stats.tx_bytes, + pAdapter->stats.rx_packets, + pAdapter->stats.rx_dropped, + pAdapter->stats.rx_bytes, + pAdapter->pEpping_ctx->total_tx_acks); +} + +void epping_set_kperf_flag(epping_adapter_t *pAdapter, + HTC_ENDPOINT_ID eid, + A_UINT8 kperf_flag) +{ + pAdapter->pEpping_ctx->kperf[eid] = kperf_flag; + pAdapter->pEpping_ctx->kperf_num_rx_recv[eid] = 0; + pAdapter->pEpping_ctx->kperf_num_tx_acks[eid] = 0; +} + +#ifdef HIF_PCI + +static int epping_tx_thread_fn(void *data) +{ + int i; + epping_poll_t *epping_poll = data; + + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: arg = %p", __func__, data); + while (!epping_poll->done) { + down(&epping_poll->sem); + adf_os_atomic_dec(&epping_poll->atm); + if (epping_poll->skb && !epping_poll->done) { + for (i = 0; i < MAX_TX_PKT_DUP_NUM; i++) { + epping_tx_dup_pkt((epping_adapter_t *)epping_poll->arg, + epping_poll->eid, epping_poll->skb); + udelay(WLAN_EPPING_DELAY_TIMEOUT_US); + } + } + } + return 0; +} + +#define EPPING_TX_THREAD "EPPINGTX" +void epping_register_tx_copier(HTC_ENDPOINT_ID eid, epping_context_t *pEpping_ctx) +{ + epping_poll_t *epping_poll = &pEpping_ctx->epping_poll[eid]; + epping_poll->eid = eid; + epping_poll->arg = pEpping_ctx->epping_adapter; + epping_poll->done = false; + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: eid = %d, arg = %p", + __func__, eid, pEpping_ctx->epping_adapter); + sema_init(&epping_poll->sem, 0); + adf_os_atomic_init(&epping_poll->atm); + epping_poll->inited = true; + epping_poll->pid = kthread_create(epping_tx_thread_fn, + epping_poll, EPPING_TX_THREAD); + wake_up_process(epping_poll->pid); +} +void epping_unregister_tx_copier(HTC_ENDPOINT_ID eid, epping_context_t *pEpping_ctx) +{ + epping_poll_t *epping_poll; + + if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS ) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: invalid eid = %d", + __func__, eid); + return; + } + + epping_poll = &pEpping_ctx->epping_poll[eid]; + + epping_poll->done = true; + if (epping_poll->inited) { + epping_tx_copier_schedule(pEpping_ctx, eid, NULL); + msleep(EPPING_KTID_KILL_WAIT_TIME_MS); + } + if (epping_poll->skb) + adf_nbuf_free(epping_poll->skb); + OS_MEMZERO(epping_poll, sizeof(epping_poll_t)); + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: eid = %d", + __func__, eid); +} +void epping_tx_copier_schedule(epping_context_t *pEpping_ctx, HTC_ENDPOINT_ID eid, adf_nbuf_t skb) +{ + epping_poll_t *epping_poll = &pEpping_ctx->epping_poll[eid]; + + if (!epping_poll->skb && skb) { + epping_poll->skb = adf_nbuf_copy(skb); + } + if (adf_os_atomic_read(&epping_poll->atm) < EPPING_MAX_WATER_MARK) { + adf_os_atomic_inc(&epping_poll->atm); + up(&epping_poll->sem); + } +} +#endif /* HIF_PCI */ diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_main.c b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_main.c new file mode 100644 index 0000000000000..4193c2dcc2895 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_main.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bmi.h" +#include "ol_fw.h" +#include "ol_if_athvar.h" +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +#include "epping_main.h" +#include "epping_internal.h" + +#ifdef TIMER_MANAGER +#define TIMER_MANAGER_STR " +TIMER_MANAGER" +#else +#define TIMER_MANAGER_STR "" +#endif + +#ifdef MEMORY_DEBUG +#define MEMORY_DEBUG_STR " +MEMORY_DEBUG" +#else +#define MEMORY_DEBUG_STR "" +#endif + +#if defined(HIF_PCI) || defined(HIF_USB) +extern int hif_register_driver(void); +extern void hif_unregister_driver(void); +#endif + +/**--------------------------------------------------------------------------- + + \brief epping_driver_init() - End point ping driver Init Function + + This is the driver entry point - called in different timeline depending + on whether the driver is statically or dynamically linked + + \param - con_mode connection mode + + \return - 0 for success, negative for failure + +----------------------------------------------------------------------------*/ +int epping_driver_init(int con_mode, vos_wake_lock_t *g_wake_lock, + char *pwlan_module_name) +{ + int ret = 0; + unsigned long rc; + epping_context_t *pEpping_ctx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__); + +#ifdef TIMER_MANAGER + vos_timer_manager_init(); +#endif +#ifdef MEMORY_DEBUG + vos_mem_init(); +#endif + + pEpping_ctx = vos_mem_malloc(sizeof(epping_context_t)); + if (pEpping_ctx == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: No memory", __func__); + ret = -ENOMEM; + goto error1; + } + vos_mem_zero(pEpping_ctx, sizeof(epping_context_t)); + pEpping_ctx->g_wake_lock = g_wake_lock; + pEpping_ctx->con_mode = con_mode; + pEpping_ctx->pwlan_module_name = pwlan_module_name; + + status = vos_preOpen(&pEpping_ctx->pVosContext); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to preOpen VOSS", __func__); + ret = -1; + goto error1; + } + + /* save epping_context in VOSS */ + ((VosContextType *)(pEpping_ctx->pVosContext))->pHDDContext = + (v_VOID_t*)pEpping_ctx; + +#ifdef HIF_SDIO +#define WLAN_WAIT_TIME_WLANSTART 10000 +#else +#define WLAN_WAIT_TIME_WLANSTART 2000 +#endif + init_completion(&pEpping_ctx->wlan_start_comp); + ret = hif_register_driver(); + if (!ret) { + rc = wait_for_completion_timeout( + &pEpping_ctx->wlan_start_comp, + msecs_to_jiffies(WLAN_WAIT_TIME_WLANSTART)); + if (!rc) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: timed-out waiting for hif_register_driver", __func__); + ret = -1; + } else + ret = 0; + } + if (ret) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: %s driver Initialization failed", + __func__, pEpping_ctx->pwlan_module_name); + hif_unregister_driver(); + vos_preClose(&pEpping_ctx->pVosContext); + ret = -ENODEV; + vos_mem_free(pEpping_ctx); + +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif + return ret; + } else { + pr_info("%s: %s driver loaded\n", + __func__, pEpping_ctx->pwlan_module_name); + return 0; + } +error1: + if (pEpping_ctx) { + vos_mem_free(pEpping_ctx); + pEpping_ctx = NULL; + } +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif + return ret; +} + +void epping_exit(v_CONTEXT_t pVosContext) +{ + epping_context_t *pEpping_ctx; + VosContextType *gpVosContext; + + pEpping_ctx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (pEpping_ctx == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: error: pEpping_ctx = NULL", + __func__); + return; + } + gpVosContext = pEpping_ctx->pVosContext; + if (pVosContext == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: error: pVosContext = NULL", + __func__); + return; + } + if (pEpping_ctx->epping_adapter) { + epping_destroy_adapter(pEpping_ctx->epping_adapter); + pEpping_ctx->epping_adapter = NULL; + } + hif_disable_isr(gpVosContext->pHIFContext); + hif_reset_soc(gpVosContext->pHIFContext); + HTCStop(gpVosContext->htc_ctx); + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; +#ifdef HIF_PCI + { + int i; + for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) { + epping_unregister_tx_copier(i, pEpping_ctx); + } + } +#endif /* HIF_PCI */ + epping_cookie_cleanup(pEpping_ctx); + vos_mem_free(pEpping_ctx); +} + +void epping_driver_exit(v_CONTEXT_t pVosContext) +{ + epping_context_t *pEpping_ctx; + + pr_info("%s: unloading driver\n", __func__); + + pEpping_ctx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + + if(!pEpping_ctx) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: module exit called before probe",__func__); + } + else + { +#ifdef QCA_PKT_PROTO_TRACE + vos_pkt_proto_trace_close(); +#endif /* QCA_PKT_PROTO_TRACE */ + //pHddCtx->isUnloadInProgress = TRUE; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + } + hif_unregister_driver(); + vos_preClose( &pVosContext ); +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif + pr_info("%s: driver unloaded\n", __func__); +} + +static void epping_target_suspend_acknowledge(void *context) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + epping_context_t *pEpping_ctx = vos_get_context(VOS_MODULE_ID_HDD, + vos_context); + int wow_nack = *((int *)context); + + if (NULL == pEpping_ctx) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: epping_ctx is NULL", __func__); + return; + } + /* EPPING_TODO: do we need wow_nack? */ + pEpping_ctx->wow_nack = wow_nack; +} + +int epping_wlan_startup(struct device *parent_dev, v_VOID_t *hif_sc) +{ + int ret = 0; + epping_context_t *pEpping_ctx = NULL; + VosContextType *pVosContext = NULL; + HTC_INIT_INFO htcInfo; + struct ol_softc *scn; + tSirMacAddr adapter_macAddr; + adf_os_device_t adf_ctx; + + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(pVosContext == NULL) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Failed vos_get_global_context", __func__); + ret = -1; + return ret; + } + + pEpping_ctx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if(pEpping_ctx == NULL) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to get pEpping_ctx", __func__); + ret = -1; + return ret; + } + pEpping_ctx->parent_dev = (void *)parent_dev; + epping_get_dummy_mac_addr(adapter_macAddr); + + ((VosContextType*)pVosContext)->pHIFContext = hif_sc; + + /* store target type and target version info in hdd ctx */ + pEpping_ctx->target_type = ((struct ol_softc *)hif_sc)->target_type; + + /* Initialize the timer module */ + vos_timer_module_init(); + + scn = vos_get_context(VOS_MODULE_ID_HIF, pVosContext); + if (!scn) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: scn is null!", __func__); + return -1; + } + scn->enableuartprint = 0; + scn->enablefwlog = 0; + + /* Initialize BMI and Download firmware */ + if (bmi_download_firmware(scn)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: BMI failed to download target", __func__); + BMICleanup(scn); + return -1; + } + + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: bmi_download_firmware done", __func__); + + htcInfo.pContext = pVosContext->pHIFContext; + htcInfo.TargetFailure = ol_target_failure; + htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge; + adf_ctx = vos_get_context(VOS_MODULE_ID_ADF, pVosContext); + + /* Create HTC */ + pVosContext->htc_ctx = HTCCreate(htcInfo.pContext, &htcInfo, adf_ctx); + if (!pVosContext->htc_ctx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to Create HTC", __func__); + BMICleanup(scn); + return -1; + } + pEpping_ctx->HTCHandle = vos_get_context(VOS_MODULE_ID_HTC, pVosContext); + if (pEpping_ctx->HTCHandle == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HTCHandle is NULL", __func__); + return -1; + } + scn->htc_handle = pEpping_ctx->HTCHandle; + + HIFClaimDevice(scn->hif_hdl, scn); + + if (bmi_done(scn)) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto error_end; + } + /* start HIF */ + if (HTCWaitTarget(scn->htc_handle) != A_OK) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HTCWaitTarget error", __func__); + goto error_end; + } + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: HTC ready", __func__); + + ret = epping_connect_service(pEpping_ctx); + if (ret != 0) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HTCWaitTargetdone", __func__); + goto error_end; + } + if (HTCStart(pEpping_ctx->HTCHandle) != A_OK) { + goto error_end; + } + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: HTC started", __func__); + + /* init the tx cookie resource */ + ret = epping_cookie_init(pEpping_ctx); + if (ret == 0) { + pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx, + adapter_macAddr, + WLAN_HDD_INFRA_STATION); + } + if (ret < 0 || pEpping_ctx->epping_adapter == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: epping_add_adaptererror error", __func__); + HTCStop(pEpping_ctx->HTCHandle); + epping_cookie_cleanup(pEpping_ctx); + goto error_end; + } +#ifdef HIF_PCI + { + int i; + for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) { + epping_register_tx_copier(i, pEpping_ctx); + } + } +#endif /* HIF_PCI */ + EPPING_LOG(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__); + complete(&pEpping_ctx->wlan_start_comp); + return ret; + +error_end: + HTCDestroy(pVosContext->htc_ctx); + pVosContext->htc_ctx = NULL; + BMICleanup(scn); + return -1; +} diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_rx.c b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_rx.c new file mode 100644 index 0000000000000..9097299568944 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_rx.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" +#include "epping_test.h" + +#define AR6000_MAX_RX_BUFFERS 16 +#define AR6000_BUFFER_SIZE 1664 +#define AR6000_MIN_HEAD_ROOM 64 + +static bool enb_rx_dump = 0; + +#ifdef HIF_SDIO +void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint) +{ + epping_context_t *pEpping_ctx = (epping_context_t *)ctx; + void *osBuf; + int RxBuffers; + int buffersToRefill; + HTC_PACKET *pPacket; + HTC_PACKET_QUEUE queue; + + buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - + HTCGetNumRecvBuffers(pEpping_ctx->HTCHandle, Endpoint); + + if (buffersToRefill <= 0) { + /* fast return, nothing to fill */ + return; + } + + INIT_HTC_PACKET_QUEUE(&queue); + + EPPING_LOG(VOS_TRACE_LEVEL_INFO, + "%s: providing htc with %d buffers at eid=%d\n", + __func__, buffersToRefill, Endpoint); + + for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) { + osBuf = adf_nbuf_alloc(NULL, AR6000_BUFFER_SIZE, + AR6000_MIN_HEAD_ROOM, 4, FALSE); + if (NULL == osBuf) { + break; + } + /* the HTC packet wrapper is at the head of the reserved area + * in the skb */ + pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf)); + /* set re-fill info */ + SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf, + adf_nbuf_data(osBuf), + AR6000_BUFFER_SIZE,Endpoint); + SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket,osBuf); + /* add to queue */ + HTC_PACKET_ENQUEUE(&queue,pPacket); + } + + if (!HTC_QUEUE_EMPTY(&queue)) { + /* add packets */ + HTCAddReceivePktMultiple(pEpping_ctx->HTCHandle, &queue); + } +} +#endif /* HIF_SDIO */ + +void epping_rx(void *ctx, HTC_PACKET *pPacket) +{ + epping_context_t *pEpping_ctx = (epping_context_t *)ctx; + epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter; + struct net_device* dev = pAdapter->dev; + A_STATUS status = pPacket->Status; + HTC_ENDPOINT_ID eid = pPacket->Endpoint; + struct sk_buff *pktSkb = (struct sk_buff *)pPacket->pPktContext; + + EPPING_LOG(VOS_TRACE_LEVEL_INFO, + "%s: pAdapter = 0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d", + __func__, pAdapter, eid, pktSkb, pPacket->pBuffer, + pPacket->ActualLength, status); + + if (status != A_OK) { + if (status != A_ECANCELED) { + printk("%s: RX ERR (%d) \n", __func__, status); + } + adf_nbuf_free(pktSkb); + return; + } + + /* deliver to up layer */ + if (pktSkb) + { + EPPING_HEADER *eppingHdr = (EPPING_HEADER *)adf_nbuf_data(pktSkb); + if (EPPING_ALIGNMENT_PAD > 0) { + A_NETBUF_PULL(pktSkb, EPPING_ALIGNMENT_PAD); + } + if (enb_rx_dump) + epping_hex_dump((void *)adf_nbuf_data(pktSkb), + pktSkb->len, __func__); + pktSkb->dev = dev; + if ((pktSkb->dev->flags & IFF_UP) == IFF_UP) { + pktSkb->protocol = eth_type_trans(pktSkb, pktSkb->dev); + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += pktSkb->len; + if (pEpping_ctx->kperf[eid] == true) { + switch (eppingHdr->Cmd_h) { + case EPPING_CMD_CONT_RX_STOP: + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: RXPERF: EID = %d, num_pkts_received = %u\n", + __func__, eid, pEpping_ctx->kperf_num_rx_recv[eid]); + OS_MEMCPY(eppingHdr->CmdBuffer_t, + &pEpping_ctx->kperf_num_rx_recv[eid], + sizeof(unsigned int)); + epping_set_kperf_flag(pAdapter, eid, false); + netif_rx_ni(pktSkb); + break; + case 0: /* RXPERF hard code 0 in FW */ + adf_nbuf_free(pktSkb); + pEpping_ctx->kperf_num_rx_recv[eid]++; + if ((pAdapter->stats.rx_packets % EPPING_STATS_LOG_COUNT) == 0) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: total_rx_pkts = %lu", + __func__, pAdapter->stats.rx_packets); + } + break; + case EPPING_CMD_CAPTURE_RECV_CNT: + epping_set_kperf_flag(pAdapter, eid, false); + netif_rx_ni(pktSkb); + break; + default: + netif_rx_ni(pktSkb); + pEpping_ctx->kperf_num_rx_recv[eid]++; + if ((pAdapter->stats.rx_packets % EPPING_STATS_LOG_COUNT) == 0) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: total_rx_pkts = %lu", + __func__, pAdapter->stats.rx_packets); + } + break; + } + } else { + netif_rx_ni(pktSkb); + if ((pAdapter->stats.rx_packets % EPPING_STATS_LOG_COUNT) == 0) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: total_rx_pkts = %lu", + __func__, pAdapter->stats.rx_packets); + } + } + } else { + ++pAdapter->stats.rx_dropped; + adf_nbuf_free(pktSkb); + } + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_tx.c b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_tx.c new file mode 100644 index 0000000000000..75f6a0cc6fadc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_tx.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" +#include "epping_test.h" + +#define TX_RETRY_TIMEOUT_IN_MS 1 + +static bool enb_tx_dump = 0; + +void epping_tx_dup_pkt(epping_adapter_t *pAdapter, + HTC_ENDPOINT_ID eid, adf_nbuf_t skb) +{ + struct epping_cookie * cookie = NULL; + int skb_len, ret; + adf_nbuf_t new_skb; + + cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); + if (cookie == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: epping_alloc_cookie returns no resource\n", __func__); + return; + } + new_skb = adf_nbuf_copy(skb); + if (!new_skb) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: adf_nbuf_copy returns no resource\n", __func__); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + return; + } + SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, + cookie, adf_nbuf_data(skb), adf_nbuf_len(new_skb), eid, 0); + SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb); + skb_len = (int)adf_nbuf_len(new_skb); + /* send the packet */ + ret = HTCSendPkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); + if (ret != A_OK) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HTCSendPkt failed, ret = %d\n", __func__, ret); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + adf_nbuf_free(new_skb); + return; + } + pAdapter->stats.tx_bytes += skb_len; + ++pAdapter->stats.tx_packets; + if (((pAdapter->stats.tx_packets + + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && + (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { + epping_log_stats(pAdapter, __func__); + } +} +static int epping_tx_send_int(adf_nbuf_t skb, + epping_adapter_t *pAdapter) +{ + EPPING_HEADER *eppingHdr = (EPPING_HEADER *)adf_nbuf_data(skb); + HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; + struct epping_cookie * cookie = NULL; + A_UINT8 ac = 0; + A_STATUS ret = A_OK; + int skb_len; + EPPING_HEADER tmpHdr = *eppingHdr; + + /* allocate resource for this packet */ + cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); + /* no resource */ + if (cookie == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: epping_alloc_cookie returns no resource\n", __func__); + return -1; + } + + if (enb_tx_dump) + epping_hex_dump((void *)eppingHdr, skb->len, __func__); + /* + * a quirk of linux, the payload of the frame is 32-bit aligned and thus + * the addition of the HTC header will mis-align the start of the HTC + * frame, so we add some padding which will be stripped off in the target + */ + if (EPPING_ALIGNMENT_PAD > 0) { + A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD); + } + /* prepare ep/HTC information */ + ac = eppingHdr->StreamNo_h; + eid = pAdapter->pEpping_ctx->EppingEndpoint[ac]; + if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: invalid eid = %d, ac = %d\n", __func__, eid, ac); + return -1; + } + if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT || + tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) { + epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]); + } + if (pAdapter->pEpping_ctx->kperf[eid]) { + switch (tmpHdr.Cmd_h) { + case EPPING_CMD_NO_ECHO: +#ifdef HIF_PCI + epping_tx_copier_schedule(pAdapter->pEpping_ctx, eid, skb); +#endif /* HIF_PCI */ + break; + default: + break; + } + } + if (pAdapter->pEpping_ctx->kperf[eid] && + tmpHdr.Cmd_h == EPPING_CMD_NO_ECHO) { + epping_tx_dup_pkt(pAdapter, eid, skb); + } + SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, + cookie, adf_nbuf_data(skb), adf_nbuf_len(skb), eid, 0); + SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb); + skb_len = skb->len; + /* send the packet */ + ret = HTCSendPkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); + epping_log_packet(pAdapter, &tmpHdr, ret, __func__); + if (ret != A_OK) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HTCSendPkt failed, status = %d\n", __func__, ret); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + return -1; + } + pAdapter->stats.tx_bytes += skb_len; + ++pAdapter->stats.tx_packets; + if (((pAdapter->stats.tx_packets + + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && + (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { + epping_log_stats(pAdapter, __func__); + } + + return 0; +} + +void epping_tx_timer_expire(epping_adapter_t *pAdapter) +{ + adf_nbuf_t nodrop_skb; + + EPPING_LOG(VOS_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__, + adf_nbuf_queue_len(&pAdapter->nodrop_queue)); + + if (!adf_nbuf_queue_len(&pAdapter->nodrop_queue)) { + /* nodrop queue is empty so no need to arm timer */ + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + return; + } + + /* try to flush nodrop queue */ + while ((nodrop_skb = adf_nbuf_queue_remove(&pAdapter->nodrop_queue))) { + if (epping_tx_send_int(nodrop_skb, pAdapter)) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: nodrop: %p xmit fail in timer\n", __func__, nodrop_skb); + /* fail to xmit so put the nodrop packet to the nodrop queue */ + adf_nbuf_queue_insert_head(&pAdapter->nodrop_queue, nodrop_skb); + break; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_INFO, + "%s: nodrop: %p xmit ok in timer\n", __func__, nodrop_skb); + } + } + + /* if nodrop queue is not empty, continue to arm timer */ + if (nodrop_skb) { + adf_os_spin_lock_bh(&pAdapter->data_lock); + /* if nodrop queue is not empty, continue to arm timer */ + if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) { + pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING; + adf_os_timer_mod(&pAdapter->epping_timer, TX_RETRY_TIMEOUT_IN_MS); + } + adf_os_spin_unlock_bh(&pAdapter->data_lock); + } else { + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + } +} + +int epping_tx_send(adf_nbuf_t skb, epping_adapter_t *pAdapter) +{ + adf_nbuf_t nodrop_skb; + EPPING_HEADER *eppingHdr; + A_UINT8 ac = 0; + + eppingHdr = (EPPING_HEADER *)adf_nbuf_data(skb); + + if (!IS_EPPING_PACKET(eppingHdr)) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Recived non endpoint ping packets\n", __func__); + /* no packet to send, cleanup */ + adf_nbuf_free(skb); + return -ENOMEM; + } + + /* the stream ID is mapped to an access class */ + ac = eppingHdr->StreamNo_h; + /* hard coded two ep ids */ + if (ac != 0 && ac != 1) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: ac %d is not mapped to mboxping service\n", __func__, ac); + adf_nbuf_free(skb); + return -ENOMEM; + } + + /* + * some EPPING packets cannot be dropped no matter what access class + * it was sent on. A special care has been taken: + * 1. when there is no TX resource, queue the control packets to + * a special queue + * 2. when there is TX resource, send the queued control packets first + * and then other packets + * 3. a timer launches to check if there is queued control packets and + * flush them + */ + + /* check the nodrop queue first */ + while ((nodrop_skb = adf_nbuf_queue_remove(&pAdapter->nodrop_queue))) { + if (epping_tx_send_int(nodrop_skb, pAdapter)) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: nodrop: %p xmit fail\n", __func__, nodrop_skb); + /* fail to xmit so put the nodrop packet to the nodrop queue */ + adf_nbuf_queue_insert_head(&pAdapter->nodrop_queue, nodrop_skb); + /* no cookie so free the current skb */ + goto tx_fail; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_INFO, + "%s: nodrop: %p xmit ok\n", __func__, nodrop_skb); + } + } + + /* send the original packet */ + if (epping_tx_send_int(skb, pAdapter)) + goto tx_fail; + + return 0; + +tx_fail: + if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) { + /* allow to drop the skb so drop it */ + adf_nbuf_free(skb); + ++pAdapter->stats.tx_dropped; + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Tx skb %p dropped, stats.tx_dropped = %ld\n", + __func__, skb, pAdapter->stats.tx_dropped); + return -ENOMEM; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: nodrop: %p queued\n", __func__, skb); + adf_nbuf_queue_add(&pAdapter->nodrop_queue, skb); + adf_os_spin_lock_bh(&pAdapter->data_lock); + if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) { + pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING; + adf_os_timer_mod(&pAdapter->epping_timer, TX_RETRY_TIMEOUT_IN_MS); + } + adf_os_spin_unlock_bh(&pAdapter->data_lock); + } + + return 0; +} + +#ifdef HIF_SDIO +HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, + HTC_PACKET *pPacket) +{ + epping_context_t *pEpping_ctx = (epping_context_t *)Context; + epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter; + HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP; + netif_stop_queue(pAdapter->dev); + return action; +} +#endif /* HIF_SDIO */ +void epping_tx_complete_multiple(void *ctx, + HTC_PACKET_QUEUE *pPacketQueue) +{ + epping_context_t *pEpping_ctx = (epping_context_t *)ctx; + epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter; + struct net_device* dev = pAdapter->dev; + A_STATUS status; + HTC_ENDPOINT_ID eid; + adf_nbuf_t pktSkb; + struct epping_cookie *cookie; + A_BOOL flushing = FALSE; + adf_nbuf_queue_t skb_queue; + HTC_PACKET *htc_pkt; + + adf_nbuf_queue_init(&skb_queue); + + adf_os_spin_lock_bh(&pAdapter->data_lock); + + while (!HTC_QUEUE_EMPTY(pPacketQueue)) { + htc_pkt = HTC_PACKET_DEQUEUE(pPacketQueue); + if (htc_pkt == NULL) + break; + status=htc_pkt->Status; + eid=htc_pkt->Endpoint; + pktSkb=GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); + cookie = htc_pkt->pPktContext; + + ASSERT(pktSkb); + ASSERT(htc_pkt->pBuffer == adf_nbuf_data(pktSkb)); + + /* add this to the list, use faster non-lock API */ + adf_nbuf_queue_add(&skb_queue,pktSkb); + + if (A_SUCCESS(status)) { + ASSERT(htc_pkt->ActualLength == adf_nbuf_len(pktSkb)); + } + EPPING_LOG(VOS_TRACE_LEVEL_INFO, + "%s skb=%p data=%p len=0x%x eid=%d ", + __func__, pktSkb, htc_pkt->pBuffer, + htc_pkt->ActualLength, eid); + + if (A_FAILED(status)) { + if (status == A_ECANCELED) { + /* a packet was flushed */ + flushing = TRUE; + } + if (status != A_NO_RESOURCE) { + printk("%s() -TX ERROR, status: 0x%x\n", __func__, + status); + } + } else { + EPPING_LOG(VOS_TRACE_LEVEL_INFO, "%s: OK\n", __func__); + flushing = FALSE; + } + + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + } + + adf_os_spin_unlock_bh(&pAdapter->data_lock); + + /* free all skbs in our local list */ + while (adf_nbuf_queue_len(&skb_queue)) { + /* use non-lock version */ + pktSkb = adf_nbuf_queue_remove(&skb_queue); + if (pktSkb == NULL) + break; + adf_nbuf_free(pktSkb); + pEpping_ctx->total_tx_acks++; + } + + if (!flushing) { + netif_wake_queue(dev); + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_txrx.c b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_txrx.c new file mode 100644 index 0000000000000..44fe268b080b8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/EPPING/src/epping_txrx.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * + */ + + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(MSM_PLATFORM) && defined(HIF_PCI) +#include +#endif /* MSM_PLATFORM */ +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" + +static int epping_start_adapter(epping_adapter_t *pAdapter); +static void epping_stop_adapter(epping_adapter_t *pAdapter); + +static void epping_timer_expire(void *data) +{ + struct net_device *dev = (struct net_device *) data; + epping_adapter_t *pAdapter; + + if (dev == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: netdev = NULL", __func__); + return; + } + + pAdapter = netdev_priv(dev); + if (pAdapter == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: adapter = NULL", __func__); + return; + } + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + epping_tx_timer_expire(pAdapter); +} + +static int epping_ndev_open(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + epping_start_adapter(pAdapter); + return ret; +} + +static int epping_ndev_stop(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + epping_stop_adapter(pAdapter); +end: + return ret; +} + +static void epping_ndev_uninit (struct net_device *dev) +{ + epping_adapter_t *pAdapter; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + goto end; + } + epping_stop_adapter(pAdapter); +end: + return; +} + +void epping_tx_queue_timeout(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + goto end; + } + + EPPING_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred, pAdapter->started= %d", + __func__, pAdapter->started); + + /* Getting here implies we disabled the TX queues + * for too long. Since this is epping + * (not because of disassociation or low resource scenarios), + * try to restart the queue + */ + if (pAdapter->started) + netif_wake_queue(dev); +end: + return; + +} + +int epping_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + ret = epping_tx_send(skb, pAdapter); +end: + return ret; +} + +struct net_device_stats* epping_get_stats(struct net_device *dev) +{ + epping_adapter_t *pAdapter = netdev_priv(dev); + + if ( NULL == pAdapter ) + { + EPPING_LOG(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter = NULL", __func__); + return NULL; + } + + return &pAdapter->stats; +} + +int epping_ndev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + if (dev != pAdapter->dev) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto end; + } + + if ((!ifr) || (!ifr->ifr_data)) { + ret = -EINVAL; + goto end; + } + + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + EPPING_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: do not support ioctl %d (SIOCDEVPRIVATE + 1)", + __func__, cmd); + break; + default: + EPPING_LOG(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + +end: + return ret; +} + +static int epping_set_mac_address(struct net_device *dev, void *addr) +{ + epping_adapter_t *pAdapter = netdev_priv(dev); + struct sockaddr *psta_mac_addr = addr; + vos_mem_copy(&pAdapter->macAddressCurrent, + psta_mac_addr->sa_data, ETH_ALEN); + vos_mem_copy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + return 0; +} + +static void epping_stop_adapter(epping_adapter_t *pAdapter) +{ + if (pAdapter && pAdapter->started) { + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + pAdapter->started = false; +#if defined(MSM_PLATFORM) && defined(HIF_PCI) + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_LOW); +#endif + } +} + +static int epping_start_adapter(epping_adapter_t *pAdapter) +{ + if (!pAdapter) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: pAdapter= NULL\n", __func__); + return -1; + } + if (!pAdapter->started) { +#if defined(MSM_PLATFORM) && defined(HIF_PCI) + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_HIGH); +#endif + netif_carrier_on(pAdapter->dev); + netif_tx_start_all_queues(pAdapter->dev); + pAdapter->started = true; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_WARN, + "%s: pAdapter %p already started\n", __func__, pAdapter); + } + return 0; +} +static int epping_register_adapter(epping_adapter_t *pAdapter) +{ + int ret = 0; + + if ((ret = register_netdev(pAdapter->dev)) != 0) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: unable to register device\n", pAdapter->dev->name); + } else { + pAdapter->registered = true; + } + return ret; +} + +static void epping_unregister_adapter(epping_adapter_t *pAdapter) +{ + if (pAdapter) { + epping_stop_adapter(pAdapter); + if (pAdapter->registered) { + unregister_netdev(pAdapter->dev); + pAdapter->registered = false; + } + } else { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: pAdapter = NULL, unable to unregister device\n", + __func__); + } +} + +void epping_destroy_adapter(epping_adapter_t *pAdapter) +{ + struct net_device *dev = NULL; + epping_context_t *pEpping_ctx; + + if (!pAdapter || !pAdapter->pEpping_ctx) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: pAdapter = NULL\n", __func__); + return; + } + + dev = pAdapter->dev; + pEpping_ctx= pAdapter->pEpping_ctx; + epping_unregister_adapter(pAdapter); + + adf_os_spinlock_destroy(&pAdapter->data_lock); + adf_os_timer_free(&pAdapter->epping_timer); + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + + while (adf_nbuf_queue_len(&pAdapter->nodrop_queue)) { + adf_nbuf_t tmp_nbuf = NULL; + tmp_nbuf = adf_nbuf_queue_remove(&pAdapter->nodrop_queue); + if (tmp_nbuf) + adf_nbuf_free(tmp_nbuf); + } + + free_netdev(dev); + if (!pEpping_ctx) + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: pEpping_ctx = NULL\n", __func__); + else + pEpping_ctx->epping_adapter = NULL; +} + +static struct net_device_ops epping_drv_ops = { + .ndo_open = epping_ndev_open, + .ndo_stop = epping_ndev_stop, + .ndo_uninit = epping_ndev_uninit, + .ndo_start_xmit = epping_hard_start_xmit, + .ndo_tx_timeout = epping_tx_queue_timeout, + .ndo_get_stats = epping_get_stats, + .ndo_do_ioctl = epping_ndev_ioctl, + .ndo_set_mac_address = epping_set_mac_address, + .ndo_select_queue = NULL, + }; + +#define EPPING_TX_QUEUE_MAX_LEN 128 /* need to be power of 2 */ + +epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx, + tSirMacAddr macAddr, device_mode_t device_mode) +{ + struct net_device *dev; + epping_adapter_t *pAdapter; + + dev = alloc_netdev(sizeof(epping_adapter_t), "wifi%d", ether_setup); + if (dev == NULL) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: Cannot allocate epping_adapter_t\n", __func__); + return NULL; + } + + pAdapter = netdev_priv(dev); + vos_mem_zero(pAdapter, sizeof(*pAdapter)); + pAdapter->dev = dev; + pAdapter->pEpping_ctx = pEpping_ctx; + pAdapter->device_mode = device_mode; /* station, SAP, etc */ + vos_mem_copy(dev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr)); + vos_mem_copy(pAdapter->macAddressCurrent.bytes, + macAddr, sizeof(tSirMacAddr)); + adf_os_spinlock_init(&pAdapter->data_lock); + adf_nbuf_queue_init(&pAdapter->nodrop_queue); + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + adf_os_timer_init(epping_get_adf_ctx(), &pAdapter->epping_timer, + epping_timer_expire, dev, ADF_DEFERRABLE_TIMER); + dev->type = ARPHRD_IEEE80211; + dev->netdev_ops = &epping_drv_ops; + dev->watchdog_timeo = 5 * HZ; /* XXX */ + dev->tx_queue_len = ATH_TXBUF-1; /* 1 for mgmt frame */ + if (epping_register_adapter(pAdapter) == 0) { + netif_tx_disable(dev); + netif_carrier_off(dev); + return pAdapter; + } else { + epping_destroy_adapter(pAdapter); + return NULL; + } +} + +int epping_connect_service(epping_context_t *pEpping_ctx) +{ + int status, i; + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP response; + + vos_mem_zero(&connect, sizeof(connect)); + vos_mem_zero(&response, sizeof(response)); + + /* these fields are the same for all service endpoints */ + connect.EpCallbacks.pContext = pEpping_ctx; + connect.EpCallbacks.EpTxCompleteMultiple = epping_tx_complete_multiple; + connect.EpCallbacks.EpRecv = epping_rx; + /* epping_tx_complete use Multiple version */ + connect.EpCallbacks.EpTxComplete = NULL; + connect.MaxSendQueueDepth = 64; + +#ifdef HIF_SDIO + connect.EpCallbacks.EpRecvRefill = epping_refill; + connect.EpCallbacks.EpSendFull = + epping_tx_queue_full /* ar6000_tx_queue_full */; +#elif defined(HIF_USB) || defined(HIF_PCI) + connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */; + connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */; + /* disable flow control for hw flow control */ + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; +#endif + + /* connect to service */ + connect.ServiceID = WMI_DATA_BE_SVC; + status = HTCConnectService(pEpping_ctx->HTCHandle, &connect, &response); + if (status != EOK) { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "Failed to connect to Endpoint Ping BE service status:%d \n", + status); + return -1;; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "eppingtest BE endpoint:%d\n", response.Endpoint); + } + pEpping_ctx->EppingEndpoint[0] = response.Endpoint; + +#if defined(HIF_PCI) || defined(HIF_USB) + connect.ServiceID = WMI_DATA_BK_SVC; + status = HTCConnectService(pEpping_ctx->HTCHandle, + &connect, &response); + if (status != EOK) + { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "Failed to connect to Endpoint Ping BK service status:%d \n", + status); + return -1;; + } else { + EPPING_LOG(VOS_TRACE_LEVEL_FATAL, + "eppingtest BK endpoint:%d\n", response.Endpoint); + } + pEpping_ctx->EppingEndpoint[1] = response.Endpoint; + /* Since we do not create other two SVC use BK endpoint + * for rest ACs (2, 3) */ + for (i = 2; i < EPPING_MAX_NUM_EPIDS; i++) { + pEpping_ctx->EppingEndpoint[i] = response.Endpoint; + } +#else + /* we only use one endpoint for high latenance bus. + * Map all AC's EPIDs to the same endpoint ID returned by HTC */ + for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) { + pEpping_ctx->EppingEndpoint[i] = response.Endpoint; + } +#endif + return 0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_main.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_main.h new file mode 100644 index 0000000000000..e9f58da105a9e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_main.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( BAP_HDD_MAIN_H ) +#define BAP_HDD_MAIN_H + +/**=========================================================================== + + \file BAP_HDD_MAIN_H.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define BSL_MAX_CLIENTS 1 +#define BSL_MAX_PHY_LINK_PER_CLIENT 1 + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief BSL_Init() - Initialize the BSL Misc char driver + + This is called in by WLANBAP_Open() as part of bringing up the BT-AMP PAL (BAP) + WLANBAP_Open() will pass in the device context created. + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int BSL_Init (void *pCtx); + +/**--------------------------------------------------------------------------- + + \brief BSL_Deinit() - De-initialize the BSL Misc char driver + + This is called in by WLANBAP_Close() as part of bringing down the BT-AMP PAL (BAP) + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int BSL_Deinit(void *pCtx); + + + +#endif // end #if !defined( BAP_HDD_MAIN_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_misc.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_misc.h new file mode 100644 index 0000000000000..889961d4a0b10 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/bap_hdd_misc.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( BAP_HDD_MISC_H ) +#define BAP_HDD_MISC_H + +/**=========================================================================== + + \file BAP_HDD_MISC.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_SetConfig() - To updates some configuration for BAP module in + SME + + This should be called after WLANBAP_Start(). + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to set the config in SME BAP + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_SetConfig +( + WLANBAP_ConfigType *pConfig +); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_RegisterWithHCI() - To register WLAN PAL with HCI + + + \param + pAdapter : HDD adapter + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to register with HCI + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_RegisterWithHCI(hdd_adapter_t *pAdapter); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_DeregisterFromHCI() - To deregister WLAN PAL with HCI + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to deregister with HCI + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_DeregisterFromHCI(void); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_StopAmp() - To stop the current AMP traffic/connection + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to stop AMP connection + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_StopAmp(void); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_AmpSessionOn() - To check if AMP connection is on currently + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + + --------------------------------------------------------------------------*/ +v_BOOL_t WLANBAP_AmpSessionOn(void); +#endif // end #if !defined( BAP_HDD_MISC_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/qc_sap_ioctl.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/qc_sap_ioctl.h new file mode 100644 index 0000000000000..01226326f176a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/qc_sap_ioctl.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _QC_SAP_IOCTL_H_ +#define _QC_SAP_IOCTL_H_ + +/* + * QCSAP ioctls. + */ + +/* + * Max size of optional information elements. We artificially + * constrain this; it's limited only by the max frame size (and + * the max parameter size of the wireless extensions). + */ +#define QCSAP_MAX_OPT_IE 256 +#define QCSAP_MAX_WSC_IE 256 +#define QCSAP_MAX_GET_STA_INFO 512 + +typedef struct sSSID +{ + u_int8_t length; + u_int8_t ssId[32]; +} tSSID; + +typedef struct sSSIDInfo +{ + tSSID ssid; + u_int8_t ssidHidden; +}tSSIDInfo; + +typedef enum { + eQC_DOT11_MODE_ALL = 0, + eQC_DOT11_MODE_ABG = 0x0001, //11a/b/g only, no HT, no proprietary + eQC_DOT11_MODE_11A = 0x0002, + eQC_DOT11_MODE_11B = 0x0004, + eQC_DOT11_MODE_11G = 0x0008, + eQC_DOT11_MODE_11N = 0x0010, + eQC_DOT11_MODE_11G_ONLY = 0x0020, + eQC_DOT11_MODE_11N_ONLY = 0x0040, + eQC_DOT11_MODE_11B_ONLY = 0x0080, + eQC_DOT11_MODE_11A_ONLY = 0x0100, + //This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL except when it starts IBSS in 11B of 2.4GHz + //It is for CSR internal use + eQC_DOT11_MODE_AUTO = 0x0200, + +} tQcPhyMode; + +#define QCSAP_ADDR_LEN 6 + +typedef u_int8_t qcmacaddr[QCSAP_ADDR_LEN]; + +struct qc_mac_acl_entry { + qcmacaddr addr; + int vlan_id; +}; + +typedef enum { + eQC_AUTH_TYPE_OPEN_SYSTEM, + eQC_AUTH_TYPE_SHARED_KEY, + eQC_AUTH_TYPE_AUTO_SWITCH +} eQcAuthType; + +typedef enum { + eQC_WPS_BEACON_IE, + eQC_WPS_PROBE_RSP_IE, + eQC_WPS_ASSOC_RSP_IE +} eQCWPSType; + + +/* + * Retrieve the WPA/RSN information element for an associated station. + */ +struct sQcSapreq_wpaie { + u_int8_t wpa_ie[QCSAP_MAX_OPT_IE]; + u_int8_t wpa_macaddr[QCSAP_ADDR_LEN]; +}; + +/* + * Retrieve the WSC information element for an associated station. + */ +struct sQcSapreq_wscie { + u_int8_t wsc_macaddr[QCSAP_ADDR_LEN]; + u_int8_t wsc_ie[QCSAP_MAX_WSC_IE]; +}; + + +/* + * Retrieve the WPS PBC Probe Request IEs. + */ +typedef struct sQcSapreq_WPSPBCProbeReqIES { + u_int8_t macaddr[QCSAP_ADDR_LEN]; + u_int16_t probeReqIELen; + u_int8_t probeReqIE[512]; +} sQcSapreq_WPSPBCProbeReqIES_t ; + +/* + * Channel List Info + */ + +typedef struct +{ + v_U8_t num_channels; + v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tChannelListInfo, *tpChannelListInfo; + + +#ifdef __linux__ +/* + * Wireless Extensions API, private ioctl interfaces. + * + * NB: Even-numbered ioctl numbers have set semantics and are privileged! + * (regardless of the incorrect comment in wireless.h!) + */ + +#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) +#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1) +/* (SIOCIWFIRSTPRIV+2) is unused */ +/* (SIOCIWFIRSTPRIV+3) is unused */ +#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4) +#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV+5) +#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6) +#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV+7) +#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV+8) +#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9) +#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10) +#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11) +#define QCSAP_IOCTL_AP_STATS (SIOCIWFIRSTPRIV+12) +#define QCSAP_IOCTL_GET_STATS (SIOCIWFIRSTPRIV+13) +#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14) + +#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15) +#define WE_SET_WLAN_DBG 1 +#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV+16) +#define WE_LOG_DUMP_CMD 1 +#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17) + +#define WE_P2P_NOA_CMD 2 +//IOCTL to configure MCC params +#define WE_MCC_CONFIG_CREDENTIAL 3 +#define WE_MCC_CONFIG_PARAMS 4 + +#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV+18) +#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV+19) +#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV+20) +#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV+21) +#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV+22) +#define QCSAP_IOCTL_DATAPATH_SNAP_SHOT (SIOCIWFIRSTPRIV+23) +#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV+25) +#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV+26) +#define QCSAP_IOCTL_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28) +#ifdef DEBUG +#define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1 +#endif + +#define MAX_VAR_ARGS 7 +#define QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED (SIOCIWFIRSTPRIV + 31) + +#define QCSAP_IOCTL_MAX_STR_LEN 1024 + + +#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7) +#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) + +#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf) +#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1) + + +enum { + QCSAP_PARAM_MAX_ASSOC = 1, + QCSAP_PARAM_GET_WLAN_DBG, + QCSAP_PARAM_CLR_ACL = 4, + QCSAP_PARAM_ACL_MODE, + QCSAP_PARAM_HIDE_SSID, + QCSAP_PARAM_AUTO_CHANNEL, + QCSAP_PARAM_SET_MC_RATE, + QCSAP_PARAM_SET_TXRX_FW_STATS, + QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY, + QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA, + QCSAP_DBGLOG_LOG_LEVEL, + QCSAP_DBGLOG_VAP_ENABLE, + QCSAP_DBGLOG_VAP_DISABLE, + QCSAP_DBGLOG_MODULE_ENABLE, + QCSAP_DBGLOG_MODULE_DISABLE, + QCSAP_DBGLOG_MOD_LOG_LEVEL, + QCSAP_DBGLOG_TYPE, + QCSAP_DBGLOG_REPORT_ENABLE, + QCASAP_TXRX_FWSTATS_RESET, + QCSAP_PARAM_RTSCTS, + QCASAP_SET_11N_RATE, + QCASAP_SET_VHT_RATE, + QCASAP_SHORT_GI, + QCSAP_SET_AMPDU, + QCSAP_SET_AMSDU, + QCSAP_GTX_HT_MCS, + QCSAP_GTX_VHT_MCS, + QCSAP_GTX_USRCFG, + QCSAP_GTX_THRE, + QCSAP_GTX_MARGIN, + QCSAP_GTX_STEP, + QCSAP_GTX_MINTPC, + QCSAP_GTX_BWMASK, +#ifdef QCA_PKT_PROTO_TRACE + QCASAP_SET_DEBUG_LOG, +#endif + QCASAP_SET_TM_LEVEL, + QCASAP_SET_DFS_IGNORE_CAC, + QCASAP_GET_DFS_NOL, + QCASAP_SET_DFS_NOL, + QCSAP_PARAM_SET_CHANNEL_CHANGE, + QCASAP_SET_DFS_TARGET_CHNL, + QCASAP_SET_RADAR_CMD, + QCSAP_GET_ACL, + QCASAP_TX_CHAINMASK_CMD, + QCASAP_RX_CHAINMASK_CMD, + QCASAP_NSS_CMD, + QCSAP_IPA_UC_STAT, + QCASAP_SET_PHYMODE, +}; + +int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +#endif /* __linux__ */ + +#endif /*_QC_SAP_IOCTL_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_assoc.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_assoc.h new file mode 100644 index 0000000000000..b78ab3c80ccea --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_assoc.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#if !defined( HDD_CONNECTION_H__ ) +#define HDD_CONNECTION_H__ +#include +#define HDD_MAX_NUM_IBSS_STA ( 32 ) +#ifdef FEATURE_WLAN_TDLS +#define HDD_MAX_NUM_TDLS_STA ( 8 ) +#define HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN ( 1 ) +#define TDLS_STA_INDEX_VALID(staId) \ + (((staId) >= 1) && ((staId) < 0xFF)) +#endif +#define TKIP_COUNTER_MEASURE_STARTED 1 +#define TKIP_COUNTER_MEASURE_STOPED 0 +/* Timeout (in ms) for Link to Up before Registering Station */ +#define ASSOC_LINKUP_TIMEOUT 60 + +/* In pronto case, IBSS owns the first peer for bss peer. + In Rome case, IBSS uses the 2nd peer as bss peer */ +#define IBSS_BROADCAST_STAID 1 + +typedef enum +{ + /** Not associated in Infra or participating in an IBSS / Ad-hoc network.*/ + eConnectionState_NotConnected, + + /** While connection in progress */ + eConnectionState_Connecting, + + /** Associated in an Infrastructure network.*/ + eConnectionState_Associated, + + /** Participating in an IBSS network though disconnected (no partner stations + in the IBSS).*/ + eConnectionState_IbssDisconnected, + + /** Participating in an IBSS network with partner stations also present*/ + eConnectionState_IbssConnected, + + /** Disconnecting in an Infrastructure network.*/ + eConnectionState_Disconnecting + +}eConnectionState; +/**This structure stores the connection information */ +typedef struct connection_info_s +{ + /** connection state of the NIC.*/ + eConnectionState connState; + + /** BSS type of the current connection. Comes from the MIB at the + time the connect request is issued in combination with the BssDescription + from the associated entity.*/ + + eMib_dot11DesiredBssType connDot11DesiredBssType; + /** BSSID */ + tCsrBssid bssId; + + /** SSID Info*/ + tCsrSSIDInfo SSID; + + /** Station ID */ + v_U8_t staId[ HDD_MAX_NUM_IBSS_STA ]; + /** Peer Mac Address of the IBSS Stations */ + v_MACADDR_t peerMacAddress[ HDD_MAX_NUM_IBSS_STA ]; + /** Auth Type */ + eCsrAuthType authType; + + /** Unicast Encryption Type */ + eCsrEncryptionType ucEncryptionType; + + /** Multicast Encryption Type */ + eCsrEncryptionType mcEncryptionType; + + /** Keys */ + tCsrKeys Keys; + + /** Operation Channel */ + v_U8_t operationChannel; + + /** Remembers authenticated state */ + v_U8_t uIsAuthenticated; + + /** Dot11Mode */ + tANI_U32 dot11Mode; + + v_U8_t proxyARPService; + +}connection_info_t; +/*Forward declaration of Adapter*/ +typedef struct hdd_adapter_s hdd_adapter_t; +typedef struct hdd_context_s hdd_context_t; +typedef struct hdd_station_ctx hdd_station_ctx_t; +typedef struct hdd_ap_ctx_s hdd_ap_ctx_t; +typedef struct hdd_mon_ctx_s hdd_mon_ctx_t; + +typedef enum +{ + ePeerConnected = 1, + ePeerDisconnected +}ePeerStatus; + +extern v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx ); +eCsrBand hdd_connGetConnectedBand( hdd_station_ctx_t *pHddStaCtx ); +extern eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, v_U32_t roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ); + +extern v_VOID_t hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType ); + +v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddCtx, + eMib_dot11DesiredBssType *pConnectedBssType ); + +int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType ); + +int hdd_set_csr_auth_type( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType ); +VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter, + tANI_U8 *peerMac, tANI_U16 staId, tANI_U8 ucastSig); +void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter); + +void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac, + tANI_U8 peerStatus, + tANI_U8 peerTimingMeasCap, + tANI_U8 sessionId, + tSirSmeChanInfo *chan_info); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter, + const tANI_U16 measurementToken, + const tANI_BOOLEAN flag, + const tANI_U8 numBss); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg.h new file mode 100644 index 0000000000000..600183404756f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg.h @@ -0,0 +1,3608 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_CONFIG_H__ ) +#define HDD_CONFIG_H__ + +/**=========================================================================== + + \file hdd_Config.h + + \brief Android WLAN Adapter Configuration functions + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +#define FW_MODULE_LOG_LEVEL_STRING_LENGTH (255) + +//Number of items that can be configured +#define MAX_CFG_INI_ITEMS 512 + +// Defines for all of the things we read from the configuration (registry). + +#define CFG_RTS_THRESHOLD_NAME "RTSThreshold" +#define CFG_RTS_THRESHOLD_MIN WNI_CFG_RTS_THRESHOLD_STAMIN // min is 0, meaning always use RTS. +#define CFG_RTS_THRESHOLD_MAX WNI_CFG_RTS_THRESHOLD_STAMAX // max is the max frame size +#define CFG_RTS_THRESHOLD_DEFAULT WNI_CFG_RTS_THRESHOLD_STADEF + +#define CFG_FRAG_THRESHOLD_NAME "gFragmentationThreshold" +#define CFG_FRAG_THRESHOLD_MIN WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN +#define CFG_FRAG_THRESHOLD_MAX WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX +#define CFG_FRAG_THRESHOLD_DEFAULT WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF + +#define CFG_CALIBRATION_NAME "gCalibration" +#define CFG_CALIBRATION_MIN ( 0 ) +#define CFG_CALIBRATION_MAX ( 1 ) +#define CFG_CALIBRATION_MAC_DEFAULT ( 1 ) +#define CFG_CALIBRATION_DEFAULT CFG_CALIBRATION_MAC_DEFAULT + +#define CFG_CALIBRATION_PERIOD_NAME "gCalibrationPeriod" +#define CFG_CALIBRATION_PERIOD_MIN ( 2 ) +#define CFG_CALIBRATION_PERIOD_MAX ( 10 ) +#define CFG_CALIBRATION_PERIOD_MAC_DEFAULT ( 5 ) +#define CFG_CALIBRATION_PERIOD_DEFAULT CFG_CALIBRATION_PERIOD_MAC_DEFAULT + +#define CFG_OPERATING_CHANNEL_NAME "gOperatingChannel" +#define CFG_OPERATING_CHANNEL_MIN ( 0 ) +#define CFG_OPERATING_CHANNEL_MAX ( 14 ) +#define CFG_OPERATING_CHANNEL_DEFAULT ( 1 ) + +#define CFG_SHORT_SLOT_TIME_ENABLED_NAME "gShortSlotTimeEnabled" +#define CFG_SHORT_SLOT_TIME_ENABLED_MIN WNI_CFG_SHORT_SLOT_TIME_STAMIN +#define CFG_SHORT_SLOT_TIME_ENABLED_MAX WNI_CFG_SHORT_SLOT_TIME_STAMAX +#define CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT WNI_CFG_SHORT_SLOT_TIME_STADEF + +#define CFG_11D_SUPPORT_ENABLED_NAME "g11dSupportEnabled" +#define CFG_11D_SUPPORT_ENABLED_MIN WNI_CFG_11D_ENABLED_STAMIN +#define CFG_11D_SUPPORT_ENABLED_MAX WNI_CFG_11D_ENABLED_STAMAX +#define CFG_11D_SUPPORT_ENABLED_DEFAULT WNI_CFG_11D_ENABLED_STADEF // Default is ON + +#define CFG_11H_SUPPORT_ENABLED_NAME "g11hSupportEnabled" +#define CFG_11H_SUPPORT_ENABLED_MIN ( 0 ) +#define CFG_11H_SUPPORT_ENABLED_MAX ( 1 ) +#define CFG_11H_SUPPORT_ENABLED_DEFAULT ( 1 ) // Default is ON + +#define CFG_ENFORCE_11D_CHANNELS_NAME "gEnforce11dChannel" +#define CFG_ENFORCE_11D_CHANNELS_MIN ( 0 ) +#define CFG_ENFORCE_11D_CHANNELS_MAX ( 1 ) +#define CFG_ENFORCE_11D_CHANNELS_DEFAULT ( 0 ) + +//COUNTRY Code Priority +#define CFG_COUNTRY_CODE_PRIORITY_NAME "gCountryCodePriority" +#define CFG_COUNTRY_CODE_PRIORITY_MIN ( 0 ) +#define CFG_COUNTRY_CODE_PRIORITY_MAX ( 1 ) +#define CFG_COUNTRY_CODE_PRIORITY_DEFAULT ( 0 ) + +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_NAME "gEnforceCountryCodeMatch" +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_MIN ( 0 ) +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_MAX ( 1 ) +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_DEFAULT ( 0 ) + +#define CFG_ENFORCE_DEFAULT_DOMAIN_NAME "gEnforceDefaultDomain" +#define CFG_ENFORCE_DEFAULT_DOMAIN_MIN ( 0 ) +#define CFG_ENFORCE_DEFAULT_DOMAIN_MAX ( 1 ) +#define CFG_ENFORCE_DEFAULT_DOMAIN_DEFAULT ( 0 ) + +#define CFG_HEARTBEAT_THRESH_24_NAME "gHeartbeat24" +#define CFG_HEARTBEAT_THRESH_24_MIN WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN +#define CFG_HEARTBEAT_THRESH_24_MAX WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX +#define CFG_HEARTBEAT_THRESH_24_DEFAULT WNI_CFG_HEART_BEAT_THRESHOLD_STADEF + +#define CFG_POWER_USAGE_NAME "gPowerUsage" +#define CFG_POWER_USAGE_MIN "Min" //Minimum Power Save +#define CFG_POWER_USAGE_MAX "Max" //Maximum Power Save +#define CFG_POWER_USAGE_DEFAULT "Mod" //Moderate Power Save + +//Enable suspend on Android +#define CFG_ENABLE_SUSPEND_NAME "gEnableSuspend" +#define CFG_ENABLE_SUSPEND_MIN ( 0 ) //No support for suspend +#define CFG_ENABLE_SUSPEND_MAX ( 3 ) //Map to Deep Sleep +#define CFG_ENABLE_SUSPEND_DEFAULT ( 1 ) //Map to Standby + +//Driver start/stop command mappings +#define CFG_ENABLE_ENABLE_DRIVER_STOP_NAME "gEnableDriverStop" +#define CFG_ENABLE_ENABLE_DRIVER_STOP_MIN ( 0 ) //No support for stop +#define CFG_ENABLE_ENABLE_DRIVER_STOP_MAX ( 2 ) //Map to Deep Sleep +#define CFG_ENABLE_ENABLE_DRIVER_STOP_DEFAULT ( 0 ) + +#define CFG_WOWL_PATTERN_NAME "gWowlPattern" +#define CFG_WOWL_PATTERN_DEFAULT "" + +//IMPS = IdleModePowerSave +#define CFG_ENABLE_IMPS_NAME "gEnableImps" +#define CFG_ENABLE_IMPS_MIN ( 0 ) +#define CFG_ENABLE_IMPS_MAX ( 1 ) +#define CFG_ENABLE_IMPS_DEFAULT ( 1 ) + +#define CFG_IMPS_MINIMUM_SLEEP_TIME_NAME "gImpsMinSleepTime" +#define CFG_IMPS_MINIMUM_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MINIMUM_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MINIMUM_SLEEP_TIME_DEFAULT ( 5 ) + +#define CFG_IMPS_MODERATE_SLEEP_TIME_NAME "gImpsModSleepTime" +#define CFG_IMPS_MODERATE_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MODERATE_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MODERATE_SLEEP_TIME_DEFAULT ( 10) + +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_NAME "gImpsMaxSleepTime" +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_DEFAULT ( 15 ) + +//BMPS = BeaconModePowerSave +#define CFG_ENABLE_BMPS_NAME "gEnableBmps" +#define CFG_ENABLE_BMPS_MIN ( 0 ) +#define CFG_ENABLE_BMPS_MAX ( 1 ) +#define CFG_ENABLE_BMPS_DEFAULT ( 1 ) + +#define CFG_BMPS_MINIMUM_LI_NAME "gBmpsMinListenInterval" +#define CFG_BMPS_MINIMUM_LI_MIN ( 1 ) +#define CFG_BMPS_MINIMUM_LI_MAX ( 65535 ) +#define CFG_BMPS_MINIMUM_LI_DEFAULT ( 1 ) + +#define CFG_BMPS_MODERATE_LI_NAME "gBmpsModListenInterval" +#define CFG_BMPS_MODERATE_LI_MIN ( 1 ) +#define CFG_BMPS_MODERATE_LI_MAX ( 65535 ) +#define CFG_BMPS_MODERATE_LI_DEFAULT ( 1 ) + +#define CFG_BMPS_MAXIMUM_LI_NAME "gBmpsMaxListenInterval" +#define CFG_BMPS_MAXIMUM_LI_MIN ( 1 ) +#define CFG_BMPS_MAXIMUM_LI_MAX ( 65535 ) +#define CFG_BMPS_MAXIMUM_LI_DEFAULT ( 1 ) + +// gEnableAutoBmpsTimer has been previously published as an externally +// configurable parameter. See analysis of CR 178211 for detailed info +// on why we want to *always* set this to 1 i.e. we no longer want +// this parameter to be configurable. the clean solution would be for +// users to not define this item in winreg so that the default value +// (which needs to be changed to 1) gets picked up but we cannot rely on that +// since this item has been published already hence the proposed +// solution to change the name of the item along with the change in the +// default value. also we could decide to not read this item from registry +// but leaving open the option of being able to configure this item for +// ASW's internal use +#define CFG_ENABLE_AUTO_BMPS_TIMER_NAME "gEnableAutoBmpsTimer_INTERNAL" +#define CFG_ENABLE_AUTO_BMPS_TIMER_MIN ( 0 ) +#define CFG_ENABLE_AUTO_BMPS_TIMER_MAX ( 1 ) +#define CFG_ENABLE_AUTO_BMPS_TIMER_DEFAULT ( 1 ) + +#define CFG_AUTO_BMPS_TIMER_VALUE_NAME "gAutoBmpsTimerValue" +#define CFG_AUTO_BMPS_TIMER_VALUE_MIN ( 1000 ) +#define CFG_AUTO_BMPS_TIMER_VALUE_MAX ( 4294967295UL ) +#define CFG_AUTO_BMPS_TIMER_VALUE_DEFAULT ( 1000 ) + +#define CFG_MAX_RX_AMPDU_FACTOR_NAME "gMaxRxAmpduFactor" +#define CFG_MAX_RX_AMPDU_FACTOR_MIN WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN +#define CFG_MAX_RX_AMPDU_FACTOR_MAX WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX +#define CFG_MAX_RX_AMPDU_FACTOR_DEFAULT WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF + +//Configuration added to enable/disable CTS2SELF in +//Adaptive RX drain feature +#define CFG_ENABLE_ADAPT_RX_DRAIN_NAME "gEnableAdaptRxDrain" +#define CFG_ENABLE_ADAPT_RX_DRAIN_MIN WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN +#define CFG_ENABLE_ADAPT_RX_DRAIN_MAX WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX +#define CFG_ENABLE_ADAPT_RX_DRAIN_DEFAULT WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF + + +#define CFG_REG_CHANGE_DEF_COUNTRY_NAME "gRegulatoryChangeCountry" +#define CFG_REG_CHANGE_DEF_COUNTRY_DEFAULT ( 0 ) +#define CFG_REG_CHANGE_DEF_COUNTRY_MIN ( 0 ) +#define CFG_REG_CHANGE_DEF_COUNTRY_MAX ( 1 ) + +#define CFG_ADVERTISE_CONCURRENT_OPERATION_NAME "gAdvertiseConcurrentOperation" +#define CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT ( 1 ) +#define CFG_ADVERTISE_CONCURRENT_OPERATION_MIN ( 0 ) +#define CFG_ADVERTISE_CONCURRENT_OPERATION_MAX ( 1 ) + +typedef enum +{ + eHDD_DOT11_MODE_AUTO = 0, //covers all things we support + eHDD_DOT11_MODE_abg, //11a/b/g only, no HT, no proprietary + eHDD_DOT11_MODE_11b, + eHDD_DOT11_MODE_11g, + eHDD_DOT11_MODE_11n, + eHDD_DOT11_MODE_11g_ONLY, + eHDD_DOT11_MODE_11n_ONLY, + eHDD_DOT11_MODE_11b_ONLY, +#ifdef WLAN_FEATURE_11AC + eHDD_DOT11_MODE_11ac_ONLY, + eHDD_DOT11_MODE_11ac, +#endif +}eHddDot11Mode; + +#define CFG_DOT11_MODE_NAME "gDot11Mode" +#define CFG_DOT11_MODE_MIN eHDD_DOT11_MODE_AUTO +#ifdef WLAN_FEATURE_11AC +#define CFG_DOT11_MODE_MAX eHDD_DOT11_MODE_11ac +#define CFG_DOT11_MODE_DEFAULT eHDD_DOT11_MODE_11ac +#else +#define CFG_DOT11_MODE_MAX eHDD_DOT11_MODE_11b_ONLY +#define CFG_DOT11_MODE_DEFAULT eHDD_DOT11_MODE_11n +#endif + +#define CFG_SAP_FORCE_11AC_FOR_11N "gSapForce11ACFor11n" +#define CFG_SAP_FORCE_11AC_FOR_11N_MIN ( 0 ) +#define CFG_SAP_FORCE_11AC_FOR_11N_MAX ( 1 ) +#define CFG_SAP_FORCE_11AC_FOR_11N_DEFAULT ( 1 ) + +#define CFG_CHANNEL_BONDING_MODE_24GHZ_NAME "gChannelBondingMode24GHz" +#define CFG_CHANNEL_BONDING_MODE_MIN WNI_CFG_CHANNEL_BONDING_MODE_STAMIN +#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX +#define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF + +#define CFG_CHANNEL_BONDING_MODE_5GHZ_NAME "gChannelBondingMode5GHz" +#define CFG_CHANNEL_BONDING_MODE_MIN WNI_CFG_CHANNEL_BONDING_MODE_STAMIN +#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX +#define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF + +#define CFG_FIXED_RATE_NAME "gFixedRate" +#define CFG_FIXED_RATE_MIN WNI_CFG_FIXED_RATE_STAMIN +#define CFG_FIXED_RATE_MAX WNI_CFG_FIXED_RATE_STAMAX +#define CFG_FIXED_RATE_DEFAULT WNI_CFG_FIXED_RATE_STADEF + +#define CFG_SHORT_GI_20MHZ_NAME "gShortGI20Mhz" +#define CFG_SHORT_GI_20MHZ_MIN WNI_CFG_SHORT_GI_20MHZ_STAMIN +#define CFG_SHORT_GI_20MHZ_MAX WNI_CFG_SHORT_GI_20MHZ_STAMAX +#define CFG_SHORT_GI_20MHZ_DEFAULT WNI_CFG_SHORT_GI_20MHZ_STADEF + +#define CFG_BLOCK_ACK_AUTO_SETUP_NAME "gBlockAckAutoSetup" +#define CFG_BLOCK_ACK_AUTO_SETUP_MIN ( 0 ) +#define CFG_BLOCK_ACK_AUTO_SETUP_MAX ( 1 ) +#define CFG_BLOCK_ACK_AUTO_SETUP_DEFAULT ( 1 ) + +#define CFG_SCAN_RESULT_AGE_COUNT_NAME "gScanResultAgeCount" +#define CFG_SCAN_RESULT_AGE_COUNT_MIN ( 1 ) +#define CFG_SCAN_RESULT_AGE_COUNT_MAX ( 100 ) +#define CFG_SCAN_RESULT_AGE_COUNT_DEFAULT ( 3 ) + +//All in seconds +//Not Connect, No Power Save +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_NAME "gScanResultAgeNCNPS" +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_DEFAULT ( 50 ) +//Not Connect, Power Save +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_NAME "gScanResultAgeNCPS" +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_DEFAULT ( 300 ) +//Connect, No Power Save +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_NAME "gScanResultAgeCNPS" +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_DEFAULT ( 150 ) +//Connect, Power Save +#define CFG_SCAN_RESULT_AGE_TIME_CPS_NAME "gScanResultAgeCPS" +#define CFG_SCAN_RESULT_AGE_TIME_CPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_CPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_CPS_DEFAULT ( 600 ) + +#define CFG_RSSI_CATEGORY_GAP_NAME "gRssiCatGap" +#define CFG_RSSI_CATEGORY_GAP_MIN ( 5 ) +#define CFG_RSSI_CATEGORY_GAP_MAX ( 100 ) +#define CFG_RSSI_CATEGORY_GAP_DEFAULT ( 5 ) + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CFG_ROAM_PREFER_5GHZ "gRoamPrefer5GHz" +#define CFG_ROAM_PREFER_5GHZ_MIN ( 0 ) +#define CFG_ROAM_PREFER_5GHZ_MAX ( 1 ) +#define CFG_ROAM_PREFER_5GHZ_DEFAULT ( 1 ) + +/* + To enable, set gRoamIntraBand=1 (Roaming within band) + To disable, set gRoamIntraBand=0 (Roaming across band) +*/ +#define CFG_ROAM_INTRA_BAND "gRoamIntraBand" +#define CFG_ROAM_INTRA_BAND_MIN ( 0 ) +#define CFG_ROAM_INTRA_BAND_MAX ( 1 ) +#define CFG_ROAM_INTRA_BAND_DEFAULT ( 0 ) +#endif + +#define CFG_SHORT_PREAMBLE_NAME "gShortPreamble" +#define CFG_SHORT_PREAMBLE_MIN WNI_CFG_SHORT_PREAMBLE_STAMIN +#define CFG_SHORT_PREAMBLE_MAX WNI_CFG_SHORT_PREAMBLE_STAMAX +#define CFG_SHORT_PREAMBLE_DEFAULT WNI_CFG_SHORT_PREAMBLE_STADEF + +#define CFG_IBSS_BSSID_NAME "gIbssBssid" +#define CFG_IBSS_BSSID_MIN "000000000000" +#define CFG_IBSS_BSSID_MAX "ffffffffffff" +#define CFG_IBSS_BSSID_DEFAULT "000AF5040506" + +#define CFG_INTF0_MAC_ADDR_NAME "Intf0MacAddress" +#define CFG_INTF0_MAC_ADDR_MIN "000000000000" +#define CFG_INTF0_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF0_MAC_ADDR_DEFAULT "000AF5898980" + +#define CFG_INTF1_MAC_ADDR_NAME "Intf1MacAddress" +#define CFG_INTF1_MAC_ADDR_MIN "000000000000" +#define CFG_INTF1_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF1_MAC_ADDR_DEFAULT "000AF5898981" + +#define CFG_INTF2_MAC_ADDR_NAME "Intf2MacAddress" +#define CFG_INTF2_MAC_ADDR_MIN "000000000000" +#define CFG_INTF2_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF2_MAC_ADDR_DEFAULT "000AF5898982" + +#define CFG_INTF3_MAC_ADDR_NAME "Intf3MacAddress" +#define CFG_INTF3_MAC_ADDR_MIN "000000000000" +#define CFG_INTF3_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF3_MAC_ADDR_DEFAULT "000AF5898983" + +#define CFG_AP_QOS_UAPSD_MODE_NAME "gEnableApUapsd" // ACs to setup U-APSD for at assoc +#define CFG_AP_QOS_UAPSD_MODE_MIN ( 0 ) +#define CFG_AP_QOS_UAPSD_MODE_MAX ( 1 ) +#define CFG_AP_QOS_UAPSD_MODE_DEFAULT ( 1 ) + +#define CFG_AP_COUNTRY_CODE "gAPCntryCode" +#define CFG_AP_COUNTRY_CODE_MIN "USI" +#define CFG_AP_COUNTRY_CODE_MAX "USI" +#define CFG_AP_COUNTRY_CODE_DEFAULT "FFF" + +#define CFG_AP_ENABLE_RANDOM_BSSID_NAME "gEnableApRandomBssid" +#define CFG_AP_ENABLE_RANDOM_BSSID_MIN ( 0 ) +#define CFG_AP_ENABLE_RANDOM_BSSID_MAX ( 1 ) +#define CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT ( 0 ) + +#define CFG_AP_ENABLE_PROTECTION_MODE_NAME "gEnableApProt" +#define CFG_AP_ENABLE_PROTECTION_MODE_MIN ( 0 ) +#define CFG_AP_ENABLE_PROTECTION_MODE_MAX ( 1 ) +#define CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT ( 1 ) + +// Bit map for CFG_AP_PROTECTION_MODE_DEFAULT +// LOWER byte for associated stations +// UPPER byte for overlapping stations +// each byte will have the following info +// bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8 +// OBSS RIFS LSIG_TXOP NON_GF HT20 FROM_11G FROM_11B FROM_11A +// bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +// OBSS RIFS LSIG_TXOP NON_GF HT_20 FROM_11G FROM_11B FROM_11A +#define CFG_AP_PROTECTION_MODE_NAME "gApProtection" +#define CFG_AP_PROTECTION_MODE_MIN ( 0x0 ) +#define CFG_AP_PROTECTION_MODE_MAX ( 0xFFFF ) +#define CFG_AP_PROTECTION_MODE_DEFAULT ( 0xBFFF ) + +#define CFG_AP_OBSS_PROTECTION_MODE_NAME "gEnableApOBSSProt" +#define CFG_AP_OBSS_PROTECTION_MODE_MIN ( 0 ) +#define CFG_AP_OBSS_PROTECTION_MODE_MAX ( 1 ) +#define CFG_AP_OBSS_PROTECTION_MODE_DEFAULT ( 0 ) + +#define CFG_AP_STA_SECURITY_SEPERATION_NAME "gDisableIntraBssFwd" +#define CFG_AP_STA_SECURITY_SEPERATION_MIN ( 0 ) +#define CFG_AP_STA_SECURITY_SEPERATION_MAX ( 1 ) +#define CFG_AP_STA_SECURITY_SEPERATION_DEFAULT ( 0 ) + +#define CFG_AP_LISTEN_MODE_NAME "gEnablePhyAgcListenMode" +#define CFG_AP_LISTEN_MODE_MIN (0) +#define CFG_AP_LISTEN_MODE_MAX (128) +#define CFG_AP_LISTEN_MODE_DEFAULT (128) + +#define CFG_AP_AUTO_SHUT_OFF "gAPAutoShutOff" +#define CFG_AP_AUTO_SHUT_OFF_MIN ( 0 ) +#define CFG_AP_AUTO_SHUT_OFF_MAX ( 4294967295UL ) +#define CFG_AP_AUTO_SHUT_OFF_DEFAULT ( 0 ) + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +#define CFG_WLAN_AUTO_SHUTDOWN "gWlanAutoShutdown" +#define CFG_WLAN_AUTO_SHUTDOWN_MIN ( 0 ) +#define CFG_WLAN_AUTO_SHUTDOWN_MAX ( 86400 ) /* Max 1 day timeout */ +#define CFG_WLAN_AUTO_SHUTDOWN_DEFAULT ( 0 ) +#endif + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE "gWlanMccToSccSwitchMode" +#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MIN ( VOS_MCC_TO_SCC_SWITCH_DISABLE) +#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MAX ( VOS_MCC_TO_SCC_SWITCH_FORCE ) +#define CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_DEFAULT (VOS_MCC_TO_SCC_SWITCH_DISABLE) +#endif + + +#define CFG_FRAMES_PROCESSING_TH_MODE_NAME "gMinFramesProcThres" +#define CFG_FRAMES_PROCESSING_TH_MIN ( 0 ) +#define CFG_FRAMES_PROCESSING_TH_MAX ( 39 ) +#define CFG_FRAMES_PROCESSING_TH_DEFAULT ( 0 ) + +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL "gAPChannelSelectStartChannel" +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MAX (0xFF) +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_DEFAULT (0) + +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL "gAPChannelSelectEndChannel" +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MAX (0xFF) +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_DEFAULT (11) + +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND "gAPChannelSelectOperatingBand" +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MAX (0x5) +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_DEFAULT (0) + +#define CFG_DISABLE_PACKET_FILTER "gDisablePacketFilter" +#define CFG_DISABLE_PACKET_FILTER_MIN (0) +#define CFG_DISABLE_PACKET_FILTER_MAX (0x1) +#define CFG_DISABLE_PACKET_FILTER_DEFAULT (0) + +#define CFG_ENABLE_LTE_COEX "gEnableLTECoex" +#define CFG_ENABLE_LTE_COEX_MIN ( 0 ) +#define CFG_ENABLE_LTE_COEX_MAX ( 1 ) +#define CFG_ENABLE_LTE_COEX_DEFAULT ( 0 ) + +#define CFG_AP_KEEP_ALIVE_PERIOD_NAME "gApKeepAlivePeriod" +#define CFG_AP_KEEP_ALIVE_PERIOD_MIN WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN +#define CFG_AP_KEEP_ALIVE_PERIOD_MAX WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX +#define CFG_AP_KEEP_ALIVE_PERIOD_DEFAULT WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF + +#define CFG_GO_KEEP_ALIVE_PERIOD_NAME "gGoKeepAlivePeriod" +#define CFG_GO_KEEP_ALIVE_PERIOD_MIN WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN +#define CFG_GO_KEEP_ALIVE_PERIOD_MAX WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX +#define CFG_GO_KEEP_ALIVE_PERIOD_DEFAULT WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF + +#define CFG_AP_LINK_MONITOR_PERIOD_NAME "gApLinkMonitorPeriod" +#define CFG_AP_LINK_MONITOR_PERIOD_MIN ( 3 ) +#define CFG_AP_LINK_MONITOR_PERIOD_MAX ( 50 ) +#define CFG_AP_LINK_MONITOR_PERIOD_DEFAULT ( 10 ) + +/* gGoLinkMonitorPeriod is period where link is idle and where + * we send NULL frame + */ +#define CFG_GO_LINK_MONITOR_PERIOD_NAME "gGoLinkMonitorPeriod" +#define CFG_GO_LINK_MONITOR_PERIOD_MIN ( 3 ) +#define CFG_GO_LINK_MONITOR_PERIOD_MAX ( 50 ) +#define CFG_GO_LINK_MONITOR_PERIOD_DEFAULT ( 10 ) + + +#define CFG_BEACON_INTERVAL_NAME "gBeaconInterval" +#define CFG_BEACON_INTERVAL_MIN WNI_CFG_BEACON_INTERVAL_STAMIN +#define CFG_BEACON_INTERVAL_MAX WNI_CFG_BEACON_INTERVAL_STAMAX +#define CFG_BEACON_INTERVAL_DEFAULT WNI_CFG_BEACON_INTERVAL_STADEF + +//Additional Handoff related Parameters +#define CFG_ENABLE_IDLE_SCAN_NAME "gEnableIdleScan" +#define CFG_ENABLE_IDLE_SCAN_MIN ( 0 ) +#define CFG_ENABLE_IDLE_SCAN_MAX ( 1 ) +#define CFG_ENABLE_IDLE_SCAN_DEFAULT ( 1 ) + +#define CFG_ROAMING_TIME_NAME "gRoamingTime" +#define CFG_ROAMING_TIME_MIN ( 0 ) +#define CFG_ROAMING_TIME_MAX ( 4294967UL ) +#define CFG_ROAMING_TIME_DEFAULT ( 10 ) + +#define CFG_VCC_RSSI_TRIGGER_NAME "gVccRssiTrigger" +#define CFG_VCC_RSSI_TRIGGER_MIN ( 0 ) +#define CFG_VCC_RSSI_TRIGGER_MAX ( 80 ) +#define CFG_VCC_RSSI_TRIGGER_DEFAULT ( 80 ) + +#define CFG_VCC_UL_MAC_LOSS_THRESH_NAME "gVccUlMacLossThresh" +#define CFG_VCC_UL_MAC_LOSS_THRESH_MIN ( 0 ) +#define CFG_VCC_UL_MAC_LOSS_THRESH_MAX ( 9 ) +#define CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT ( 9 ) + +#define CFG_PASSIVE_MAX_CHANNEL_TIME_NAME "gPassiveMaxChannelTime" +#define CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ( 0 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT ( 110 ) + +#define CFG_PASSIVE_MIN_CHANNEL_TIME_NAME "gPassiveMinChannelTime" +#define CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ( 0 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_DEFAULT ( 60 ) + +#define CFG_ACTIVE_MAX_CHANNEL_TIME_NAME "gActiveMaxChannelTime" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT ( 40 ) + +#define CFG_ACTIVE_MIN_CHANNEL_TIME_NAME "gActiveMinChannelTime" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_DEFAULT ( 20 ) + +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_NAME "gActiveMaxChannelTimeBtc" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_DEFAULT ( 120 ) + +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_NAME "gActiveMinChannelTimeBtc" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_DEFAULT ( 60 ) + +#define CFG_RETRY_LIMIT_ZERO_NAME "gRetryLimitZero" +#define CFG_RETRY_LIMIT_ZERO_MIN ( 0 ) +#define CFG_RETRY_LIMIT_ZERO_MAX ( 15 ) +#define CFG_RETRY_LIMIT_ZERO_DEFAULT ( 5 ) + +#define CFG_RETRY_LIMIT_ONE_NAME "gRetryLimitOne" +#define CFG_RETRY_LIMIT_ONE_MIN ( 0 ) +#define CFG_RETRY_LIMIT_ONE_MAX ( 15 ) +#define CFG_RETRY_LIMIT_ONE_DEFAULT ( 10 ) + +#define CFG_RETRY_LIMIT_TWO_NAME "gRetryLimitTwo" +#define CFG_RETRY_LIMIT_TWO_MIN ( 0 ) +#define CFG_RETRY_LIMIT_TWO_MAX ( 15 ) +#define CFG_RETRY_LIMIT_TWO_DEFAULT ( 15 ) + +#define CFG_DISABLE_AGG_WITH_BTC_NAME "gDisableAggWithBTC" +#define CFG_DISABLE_AGG_WITH_BTC_MIN ( 0 ) +#define CFG_DISABLE_AGG_WITH_BTC_MAX ( 1 ) +#define CFG_DISABLE_AGG_WITH_BTC_DEFAULT ( 1 ) + +#ifdef WLAN_AP_STA_CONCURRENCY + +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME "gPassiveMaxChannelTimeConc" +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT ( 110 ) + +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME "gPassiveMinChannelTimeConc" +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT ( 60 ) + +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME "gActiveMaxChannelTimeConc" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT ( 40 ) + +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME "gActiveMinChannelTimeConc" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT ( 20 ) + +#define CFG_REST_TIME_CONC_NAME "gRestTimeConc" +#define CFG_REST_TIME_CONC_MIN ( 0 ) +#define CFG_REST_TIME_CONC_MAX ( 10000 ) +#define CFG_REST_TIME_CONC_DEFAULT ( 100 ) + +#define CFG_NUM_STA_CHAN_COMBINED_CONC_NAME "gNumStaChanCombinedConc" +#define CFG_NUM_STA_CHAN_COMBINED_CONC_MIN ( 1 ) +#define CFG_NUM_STA_CHAN_COMBINED_CONC_MAX ( 255 ) +#define CFG_NUM_STA_CHAN_COMBINED_CONC_DEFAULT ( 3 ) + +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_NAME "gNumP2PChanCombinedConc" +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_MIN ( 1 ) +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_MAX ( 255 ) +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_DEFAULT ( 1 ) +#endif + +#define CFG_MAX_PS_POLL_NAME "gMaxPsPoll" +#define CFG_MAX_PS_POLL_MIN WNI_CFG_MAX_PS_POLL_STAMIN +#define CFG_MAX_PS_POLL_MAX WNI_CFG_MAX_PS_POLL_STAMAX +#define CFG_MAX_PS_POLL_DEFAULT WNI_CFG_MAX_PS_POLL_STADEF + +#define CFG_MAX_TX_POWER_NAME "gTxPowerCap" +#define CFG_MAX_TX_POWER_MIN WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN +#define CFG_MAX_TX_POWER_MAX WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX +//Not to use CFG default because if no registry setting, this is ignored by SME. +#define CFG_MAX_TX_POWER_DEFAULT WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX + + +#define CFG_LOW_GAIN_OVERRIDE_NAME "gLowGainOverride" +#define CFG_LOW_GAIN_OVERRIDE_MIN WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN +#define CFG_LOW_GAIN_OVERRIDE_MAX WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX +#define CFG_LOW_GAIN_OVERRIDE_DEFAULT WNI_CFG_LOW_GAIN_OVERRIDE_STADEF + +#define CFG_RSSI_FILTER_PERIOD_NAME "gRssiFilterPeriod" +#define CFG_RSSI_FILTER_PERIOD_MIN WNI_CFG_RSSI_FILTER_PERIOD_STAMIN +#define CFG_RSSI_FILTER_PERIOD_MAX WNI_CFG_RSSI_FILTER_PERIOD_STAMAX +// Increased this value for Non-ESE AP. This is cause FW RSSI Monitoring +// the consumer of this value is ON by default. So to impact power numbers +// we are setting this to a high value. +#define CFG_RSSI_FILTER_PERIOD_DEFAULT WNI_CFG_RSSI_FILTER_PERIOD_STADEF + +#define CFG_IGNORE_DTIM_NAME "gIgnoreDtim" +#define CFG_IGNORE_DTIM_MIN WNI_CFG_IGNORE_DTIM_STAMIN +#define CFG_IGNORE_DTIM_MAX WNI_CFG_IGNORE_DTIM_STAMAX +#define CFG_IGNORE_DTIM_DEFAULT WNI_CFG_IGNORE_DTIM_STADEF + +#define CFG_MAX_LI_MODULATED_DTIM_NAME "gMaxLIModulatedDTIM" +#define CFG_MAX_LI_MODULATED_DTIM_MIN ( 1 ) +#define CFG_MAX_LI_MODULATED_DTIM_MAX ( 10 ) +#define CFG_MAX_LI_MODULATED_DTIM_DEFAULT ( 10 ) + +#define CFG_RX_ANT_CONFIGURATION_NAME "gNumRxAnt" +#define CFG_RX_ANT_CONFIGURATION_NAME_MIN ( 1 ) +#define CFG_RX_ANT_CONFIGURATION_NAME_MAX ( 2 ) +#define CFG_RX_ANT_CONFIGURATION_NAME_DEFAULT ( 2 ) + +#define CFG_FW_HEART_BEAT_MONITORING_NAME "gEnableFWHeartBeatMonitoring" +#define CFG_FW_HEART_BEAT_MONITORING_MIN ( 0 ) +#define CFG_FW_HEART_BEAT_MONITORING_MAX ( 1 ) +#define CFG_FW_HEART_BEAT_MONITORING_DEFAULT ( 1 ) + +#define CFG_FW_BEACON_FILTERING_NAME "gEnableFWBeaconFiltering" +#define CFG_FW_BEACON_FILTERING_MIN ( 0 ) +#define CFG_FW_BEACON_FILTERING_MAX ( 1 ) +#define CFG_FW_BEACON_FILTERING_DEFAULT ( 1 ) + +#define CFG_FW_RSSI_MONITORING_NAME "gEnableFWRssiMonitoring" +#define CFG_FW_RSSI_MONITORING_MIN ( 0 ) +#define CFG_FW_RSSI_MONITORING_MAX ( 1 ) +#define CFG_FW_RSSI_MONITORING_DEFAULT ( 1 ) + +#define CFG_DATA_INACTIVITY_TIMEOUT_NAME "gDataInactivityTimeout" +#define CFG_DATA_INACTIVITY_TIMEOUT_MIN ( 1 ) +#define CFG_DATA_INACTIVITY_TIMEOUT_MAX ( 255 ) +#define CFG_DATA_INACTIVITY_TIMEOUT_DEFAULT ( 20 ) + +#define CFG_NTH_BEACON_FILTER_NAME "gNthBeaconFilter" +#define CFG_NTH_BEACON_FILTER_MIN ( WNI_CFG_NTH_BEACON_FILTER_STAMIN ) +#define CFG_NTH_BEACON_FILTER_MAX ( WNI_CFG_NTH_BEACON_FILTER_STAMAX ) +#define CFG_NTH_BEACON_FILTER_DEFAULT ( WNI_CFG_NTH_BEACON_FILTER_STADEF ) + +#define CFG_RF_SETTLING_TIME_CLK_NAME "rfSettlingTimeUs" +#define CFG_RF_SETTLING_TIME_CLK_MIN ( 0 ) +#define CFG_RF_SETTLING_TIME_CLK_MAX ( 60000 ) +#define CFG_RF_SETTLING_TIME_CLK_DEFAULT ( 1500 ) + +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_NAME "gStaKeepAlivePeriod" +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN ( 0 ) +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX ( 65535) +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT ( 0 ) + +//WMM configuration +#define CFG_QOS_WMM_MODE_NAME "WmmIsEnabled" +#define CFG_QOS_WMM_MODE_MIN (0) +#define CFG_QOS_WMM_MODE_MAX (2) //HDD_WMM_NO_QOS +#define CFG_QOS_WMM_MODE_DEFAULT (0) //HDD_WMM_AUTO + +#define CFG_QOS_WMM_80211E_ENABLED_NAME "80211eIsEnabled" +#define CFG_QOS_WMM_80211E_ENABLED_MIN (0) +#define CFG_QOS_WMM_80211E_ENABLED_MAX (1) +#define CFG_QOS_WMM_80211E_ENABLED_DEFAULT (0) + +#define CFG_QOS_WMM_UAPSD_MASK_NAME "UapsdMask" // ACs to setup U-APSD for at assoc +#define CFG_QOS_WMM_UAPSD_MASK_MIN (0x00) +#define CFG_QOS_WMM_UAPSD_MASK_MAX (0xFF) +#define CFG_QOS_WMM_UAPSD_MASK_DEFAULT (0x00) + +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_NAME "InfraUapsdVoSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MAX (4294967295UL ) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_DEFAULT (20) + +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_NAME "InfraUapsdVoSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MAX (4294967295UL ) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_NAME "InfraUapsdViSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_NAME "InfraUapsdViSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_NAME "InfraUapsdBeSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_NAME "InfraUapsdBeSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_NAME "InfraUapsdBkSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_NAME "InfraUapsdBkSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_DEFAULT (2000) + +#ifdef FEATURE_WLAN_ESE +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME "InfraInactivityInterval" +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN (0) +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT (0) //disabled + +#define CFG_ESE_FEATURE_ENABLED_NAME "EseEnabled" +#define CFG_ESE_FEATURE_ENABLED_MIN (0) +#define CFG_ESE_FEATURE_ENABLED_MAX (1) +#define CFG_ESE_FEATURE_ENABLED_DEFAULT (0) //disabled +#endif // FEATURE_WLAN_ESE + +#ifdef FEATURE_WLAN_LFR +#define CFG_LFR_FEATURE_ENABLED_NAME "FastRoamEnabled" +#define CFG_LFR_FEATURE_ENABLED_MIN (0) +#define CFG_LFR_FEATURE_ENABLED_MAX (1) +#define CFG_LFR_FEATURE_ENABLED_DEFAULT (0) //disabled + +#define CFG_LFR_MAWC_FEATURE_ENABLED_NAME "MAWCEnabled" +#define CFG_LFR_MAWC_FEATURE_ENABLED_MIN (0) +#define CFG_LFR_MAWC_FEATURE_ENABLED_MAX (1) +#define CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT (0) /* disabled */ +#endif // FEATURE_WLAN_LFR + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +// This flag will control fasttransition in case of 11r and ese. +// Basically with this the whole neighbor roam, pre-auth, reassoc +// can be turned ON/OFF. +// With this turned OFF 11r will completely not work. +// For 11r this flag has to be ON. +// For ESE fastroam will not work. +#define CFG_FAST_TRANSITION_ENABLED_NAME "FastTransitionEnabled" +#define CFG_FAST_TRANSITION_ENABLED_NAME_MIN (0) +#define CFG_FAST_TRANSITION_ENABLED_NAME_MAX (1) +#define CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT (1) //Enabled + +/* This parameter is used to decide whether to Roam or not. + * AP1 is the currently associated AP and AP2 is chosen for roaming. + * The Roaming will happen only if AP2 has better Signal Quality and it has a RSSI better than AP1 + * in terms of RoamRssiDiff,and RoamRssiDiff is the number of units (typically measured in dB) AP2 + * is better than AP1. + * This check is not done if the value is Zero */ +#define CFG_ROAM_RSSI_DIFF_NAME "RoamRssiDiff" +#define CFG_ROAM_RSSI_DIFF_MIN (0) +#define CFG_ROAM_RSSI_DIFF_MAX (30) +#define CFG_ROAM_RSSI_DIFF_DEFAULT (5) + +/* + * Following a scan and if potential roam candidate(s) are found, + * then determine whether to register for reassoc threshold or roam + * immediately based on this configuration parameter. If the RSSI + * of any available candidate is better than the currently associated + * AP by at least gImmediateRoamRssiDiff, then being to roam + * immediately. + * NOTE: Value of 0 means that immediate roaming is enabled by default + */ +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_NAME "gImmediateRoamRssiDiff" +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_MIN (0) +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_MAX (125) +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_DEFAULT (0) + +/*This parameter is used to set Wireless Extended Security Mode.*/ +#define CFG_ENABLE_WES_MODE_NAME "gWESModeEnabled" +#define CFG_ENABLE_WES_MODE_NAME_MIN (0) +#define CFG_ENABLE_WES_MODE_NAME_MAX (1) +#define CFG_ENABLE_WES_MODE_NAME_DEFAULT (0) + +#define CFG_ROAM_SCAN_N_PROBES "gRoamScanNProbes" +#define CFG_ROAM_SCAN_N_PROBES_MIN (1) +#define CFG_ROAM_SCAN_N_PROBES_MAX (10) +#define CFG_ROAM_SCAN_N_PROBES_DEFAULT (2) + +#define CFG_ROAM_SCAN_HOME_AWAY_TIME "gRoamScanHomeAwayTime" +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN (0) // 0 for disable +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX (300) +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT (CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) + // disabled by default + +#endif /* (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_OKC +#define CFG_OKC_FEATURE_ENABLED_NAME "OkcEnabled" +#define CFG_OKC_FEATURE_ENABLED_MIN (0) +#define CFG_OKC_FEATURE_ENABLED_MAX (1) +#define CFG_OKC_FEATURE_ENABLED_DEFAULT (1) +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED "gRoamScanOffloadEnabled" +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN (0) +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX (1) +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT (1) +#endif + +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME "PktClassificationBasis" // DSCP or 802.1Q +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN (0) +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX (1) +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT (0) //DSCP + +/* default TSPEC parameters for AC_VO */ +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME "InfraDirAcVo" +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_NAME "InfraNomMsduSizeAcVo" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_DEFAULT (0x80D0) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_NAME "InfraMeanDataRateAcVo" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_DEFAULT (0x14500) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_NAME "InfraMinPhyRateAcVo" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_NAME "InfraSbaAcVo" +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_VI */ +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_NAME "InfraDirAcVi" +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_NAME "InfraNomMsduSizeAcVi" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_NAME "InfraMeanDataRateAcVi" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_DEFAULT (0x57E40) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_NAME "InfraMinPhyRateAcVi" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_NAME "InfraSbaAcVi" +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_BE*/ +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_NAME "InfraDirAcBe" +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_NAME "InfraNomMsduSizeAcBe" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_NAME "InfraMeanDataRateAcBe" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_DEFAULT (0x493E0) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_NAME "InfraMinPhyRateAcBe" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_NAME "InfraSbaAcBe" +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_Bk*/ +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_NAME "InfraDirAcBk" +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_NAME "InfraNomMsduSizeAcBk" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_NAME "InfraMeanDataRateAcBk" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_DEFAULT (0x493E0) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_NAME "InfraMinPhyRateAcBk" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_NAME "InfraSbaAcBk" +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_DEFAULT (0x2001) + +// TL configuration +#define CFG_TL_WFQ_BK_WEIGHT_NAME "WfqBkWeight" +#define CFG_TL_WFQ_BK_WEIGHT_MIN 1 +#define CFG_TL_WFQ_BK_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_BK_WEIGHT_DEFAULT 1 + +#define CFG_TL_WFQ_BE_WEIGHT_NAME "WfqBeWeight" +#define CFG_TL_WFQ_BE_WEIGHT_MIN 1 +#define CFG_TL_WFQ_BE_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_BE_WEIGHT_DEFAULT 3 + +#define CFG_TL_WFQ_VI_WEIGHT_NAME "WfqViWeight" +#define CFG_TL_WFQ_VI_WEIGHT_MIN 1 +#define CFG_TL_WFQ_VI_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_VI_WEIGHT_DEFAULT 5 + +#define CFG_TL_WFQ_VO_WEIGHT_NAME "WfqVoWeight" +#define CFG_TL_WFQ_VO_WEIGHT_MIN 1 +#define CFG_TL_WFQ_VO_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_VO_WEIGHT_DEFAULT 7 + +#define CFG_TL_DELAYED_TRGR_FRM_INT_NAME "DelayedTriggerFrmInt" +#define CFG_TL_DELAYED_TRGR_FRM_INT_MIN 1 +#define CFG_TL_DELAYED_TRGR_FRM_INT_MAX (4294967295UL) +#define CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT 3000 + +#define CFG_REORDER_TIME_BK_NAME "BkReorderTime" +#define CFG_REORDER_TIME_BK_MIN 30 +#define CFG_REORDER_TIME_BK_MAX 1000 +#define CFG_REORDER_TIME_BK_DEFAULT 100 + +#define CFG_REORDER_TIME_BE_NAME "BeReorderTime" +#define CFG_REORDER_TIME_BE_MIN 30 +#define CFG_REORDER_TIME_BE_MAX 1000 +#define CFG_REORDER_TIME_BE_DEFAULT 100 + +#define CFG_REORDER_TIME_VI_NAME "ViReorderTime" +#define CFG_REORDER_TIME_VI_MIN 30 +#define CFG_REORDER_TIME_VI_MAX 1000 +#define CFG_REORDER_TIME_VI_DEFAULT 100 + +#define CFG_REORDER_TIME_VO_NAME "VoReorderTime" +#define CFG_REORDER_TIME_VO_MIN 30 +#define CFG_REORDER_TIME_VO_MAX 1000 +#define CFG_REORDER_TIME_VO_DEFAULT 40 + +#if defined WLAN_FEATURE_VOWIFI +#define CFG_RRM_ENABLE_NAME "gRrmEnable" +#define CFG_RRM_ENABLE_MIN (0) +#define CFG_RRM_ENABLE_MAX (1) +#define CFG_RRM_ENABLE_DEFAULT (0) + +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_NAME "gRrmOperChanMax" //section 11.10.3 IEEE std. 802.11k-2008 +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_MIN (0) //Maxduration = 2^(maxDuration - 4) * bcnIntvl. +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_MAX (8) +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_DEFAULT (3) //max duration = 2^-1 * bcnIntvl (50% of bcn intvl) + +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_NAME "gRrmNonOperChanMax" //Same as above. +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MIN (0) +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MAX (8) +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_DEFAULT (3) + +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME "gRrmRandnIntvl" +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN (10) +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX (100) +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT (100) +#endif + +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_NAME "ImplicitQosIsEnabled" +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MIN (0) +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX (1) +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT (1) + +#define CFG_ENABLE_LOGP_NAME "gEnableLogp" +#define CFG_ENABLE_LOGP_MIN ( 0 ) +#define CFG_ENABLE_LOGP_MAX ( 1 ) +#define CFG_ENABLE_LOGP_DEFAULT ( 0 ) + +#define CFG_BTC_EXECUTION_MODE_NAME "BtcExecutionMode" +#define CFG_BTC_EXECUTION_MODE_MIN ( 0 ) +#define CFG_BTC_EXECUTION_MODE_MAX ( 5 ) +#define CFG_BTC_EXECUTION_MODE_DEFAULT ( 0 ) + +#define CFG_BTC_DHCP_PROTECTION_NAME "BtcConsBtSlotToBlockDuringDhcp" +#define CFG_BTC_DHCP_PROTECTION_MIN ( 0 ) +#define CFG_BTC_DHCP_PROTECTION_MAX ( 0xFF ) +#define CFG_BTC_DHCP_PROTECTION_DEFAULT ( 0 ) + +#define CFG_BTC_A2DP_DHCP_PROTECTION_NAME "BtcA2DPDhcpProtectLevel" +#define CFG_BTC_A2DP_DHCP_PROTECTION_MIN ( 0 ) +#define CFG_BTC_A2DP_DHCP_PROTECTION_MAX ( 0xFF ) +#define CFG_BTC_A2DP_DHCP_PROTECTION_DEFAULT ( 7 ) + +#define CFG_BTC_STATIC_LEN_INQ_BT_NAME "btcStaticLenInqBt" +#define CFG_BTC_STATIC_LEN_INQ_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_INQ_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_INQ_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_PAGE_BT_NAME "btcStaticLenPageBt" +#define CFG_BTC_STATIC_LEN_PAGE_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_PAGE_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_PAGE_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_CONN_BT_NAME "btcStaticLenConnBt" +#define CFG_BTC_STATIC_LEN_CONN_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_CONN_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_CONN_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_LE_BT_NAME "btcStaticLenLeBt" +#define CFG_BTC_STATIC_LEN_LE_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_LE_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_LE_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_INQ_WLAN_NAME "btcStaticLenInqWlan" +#define CFG_BTC_STATIC_LEN_INQ_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_INQ_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_INQ_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_NAME "btcStaticLenPageWlan" +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_CONN_WLAN_NAME "btcStaticLenConnWlan" +#define CFG_BTC_STATIC_LEN_CONN_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_CONN_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_CONN_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_LE_WLAN_NAME "btcStaticLenLeWlan" +#define CFG_BTC_STATIC_LEN_LE_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_LE_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_LE_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_DYN_MAX_LEN_BT_NAME "btcDynMaxLenBt" +#define CFG_BTC_DYN_MAX_LEN_BT_MIN ( 25000 ) +#define CFG_BTC_DYN_MAX_LEN_BT_MAX ( 500000 ) +#define CFG_BTC_DYN_MAX_LEN_BT_DEFAULT ( 250000 ) + +#define CFG_BTC_DYN_MAX_LEN_WLAN_NAME "btcDynMaxLenWlan" +#define CFG_BTC_DYN_MAX_LEN_WLAN_MIN ( 15000 ) +#define CFG_BTC_DYN_MAX_LEN_WLAN_MAX ( 500000 ) +#define CFG_BTC_DYN_MAX_LEN_WLAN_DEFAULT ( 45000 ) + +#define CFG_BTC_MAX_SCO_BLOCK_PERC_NAME "btcMaxScoBlockPerc" +#define CFG_BTC_MAX_SCO_BLOCK_PERC_MIN ( 0 ) +#define CFG_BTC_MAX_SCO_BLOCK_PERC_MAX ( 100 ) +#define CFG_BTC_MAX_SCO_BLOCK_PERC_DEFAULT ( 1 ) + +#define CFG_BTC_DHCP_PROT_ON_A2DP_NAME "btcDhcpProtOnA2dp" +#define CFG_BTC_DHCP_PROT_ON_A2DP_MIN ( 0 ) +#define CFG_BTC_DHCP_PROT_ON_A2DP_MAX ( 1 ) +#define CFG_BTC_DHCP_PROT_ON_A2DP_DEFAULT ( 1 ) + +#define CFG_BTC_DHCP_PROT_ON_SCO_NAME "btcDhcpProtOnSco" +#define CFG_BTC_DHCP_PROT_ON_SCO_MIN ( 0 ) +#define CFG_BTC_DHCP_PROT_ON_SCO_MAX ( 1 ) +#define CFG_BTC_DHCP_PROT_ON_SCO_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_WAN_FREQ_NAME "mwsCoexVictim1WANFreq" +#define CFG_MWS_COEX_VX_WAN_FREQ_MIN ( 0 ) +#define CFG_MWS_COEX_VX_WAN_FREQ_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_WLAN_FREQ_NAME "mwsCoexVictim1WLANFreq" +#define CFG_MWS_COEX_VX_WLAN_FREQ_MIN ( 0 ) +#define CFG_MWS_COEX_VX_WLAN_FREQ_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_CONFIG_NAME "mwsCoexVictim1Config" +#define CFG_MWS_COEX_V1_CONFIG2_NAME "mwsCoexVictim1Config2" +#define CFG_MWS_COEX_VX_CONFIG_MIN ( 0 ) +#define CFG_MWS_COEX_VX_CONFIG_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_CONFIG_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V2_WAN_FREQ_NAME "mwsCoexVictim2WANFreq" +#define CFG_MWS_COEX_V2_WLAN_FREQ_NAME "mwsCoexVictim2WLANFreq" +#define CFG_MWS_COEX_V2_CONFIG_NAME "mwsCoexVictim2Config" +#define CFG_MWS_COEX_V2_CONFIG2_NAME "mwsCoexVictim2Config2" +#define CFG_MWS_COEX_V3_WAN_FREQ_NAME "mwsCoexVictim3WANFreq" +#define CFG_MWS_COEX_V3_WLAN_FREQ_NAME "mwsCoexVictim3WLANFreq" +#define CFG_MWS_COEX_V3_CONFIG_NAME "mwsCoexVictim3Config" +#define CFG_MWS_COEX_V3_CONFIG2_NAME "mwsCoexVictim3Config2" +#define CFG_MWS_COEX_V4_WAN_FREQ_NAME "mwsCoexVictim4WANFreq" +#define CFG_MWS_COEX_V4_WLAN_FREQ_NAME "mwsCoexVictim4WLANFreq" +#define CFG_MWS_COEX_V4_CONFIG_NAME "mwsCoexVictim4Config" +#define CFG_MWS_COEX_V4_CONFIG2_NAME "mwsCoexVictim4Config2" +#define CFG_MWS_COEX_V5_WAN_FREQ_NAME "mwsCoexVictim5WANFreq" +#define CFG_MWS_COEX_V5_WLAN_FREQ_NAME "mwsCoexVictim5WLANFreq" +#define CFG_MWS_COEX_V5_CONFIG_NAME "mwsCoexVictim5Config" +#define CFG_MWS_COEX_V5_CONFIG2_NAME "mwsCoexVictim5Config2" +#define CFG_MWS_COEX_V6_WAN_FREQ_NAME "mwsCoexVictim6WANFreq" +#define CFG_MWS_COEX_V6_WLAN_FREQ_NAME "mwsCoexVictim6WLANFreq" +#define CFG_MWS_COEX_V6_CONFIG_NAME "mwsCoexVictim6Config" +#define CFG_MWS_COEX_V6_CONFIG2_NAME "mwsCoexVictim6Config2" +#define CFG_MWS_COEX_V7_WAN_FREQ_NAME "mwsCoexVictim7WANFreq" +#define CFG_MWS_COEX_V7_WLAN_FREQ_NAME "mwsCoexVictim7WLANFreq" +#define CFG_MWS_COEX_V7_CONFIG_NAME "mwsCoexVictim7Config" +#define CFG_MWS_COEX_V7_CONFIG2_NAME "mwsCoexVictim7Config2" +#define CFG_MWS_COEX_V8_WAN_FREQ_NAME "mwsCoexVictim8WANFreq" +#define CFG_MWS_COEX_V8_WLAN_FREQ_NAME "mwsCoexVictim8WLANFreq" +#define CFG_MWS_COEX_V8_CONFIG_NAME "mwsCoexVictim8Config" +#define CFG_MWS_COEX_V8_CONFIG2_NAME "mwsCoexVictim8Config2" +#define CFG_MWS_COEX_V9_WAN_FREQ_NAME "mwsCoexVictim9WANFreq" +#define CFG_MWS_COEX_V9_WLAN_FREQ_NAME "mwsCoexVictim9WLANFreq" +#define CFG_MWS_COEX_V9_CONFIG_NAME "mwsCoexVictim9Config" +#define CFG_MWS_COEX_V9_CONFIG2_NAME "mwsCoexVictim9Config2" +#define CFG_MWS_COEX_V10_WAN_FREQ_NAME "mwsCoexVictim10WANFreq" +#define CFG_MWS_COEX_V10_WLAN_FREQ_NAME "mwsCoexVictim10WLANFreq" +#define CFG_MWS_COEX_V10_CONFIG_NAME "mwsCoexVictim10Config" +#define CFG_MWS_COEX_V10_CONFIG2_NAME "mwsCoexVictim10Config2" + +#define CFG_MWS_COEX_MODEM_BACKOFF_NAME "mwsCoexModemBackoff" +#define CFG_MWS_COEX_MODEM_BACKOFF_MIN ( 0 ) +#define CFG_MWS_COEX_MODEM_BACKOFF_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_MODEM_BACKOFF_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_CONFIG1_NAME "mwsCoexConfig1" +#define CFG_MWS_COEX_CONFIGX_MIN ( 0 ) +#define CFG_MWS_COEX_CONFIGX_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_CONFIGX_DEFAULT ( 0 ) +#define CFG_MWS_COEX_CONFIG2_NAME "mwsCoexConfig2" +#define CFG_MWS_COEX_CONFIG3_NAME "mwsCoexConfig3" +#define CFG_MWS_COEX_CONFIG4_NAME "mwsCoexConfig4" +#define CFG_MWS_COEX_CONFIG5_NAME "mwsCoexConfig5" +#define CFG_MWS_COEX_CONFIG6_NAME "mwsCoexConfig6" + +#define CFG_SAR_POWER_BACKOFF_NAME "SARPowerBackoff" +#define CFG_SAR_POWER_BACKOFF_MIN ( 0 ) +#define CFG_SAR_POWER_BACKOFF_MAX ( 0xFFFFFFFF ) +#define CFG_SAR_POWER_BACKOFF_DEFAULT ( 0 ) + +#if defined WLAN_FEATURE_VOWIFI_11R +#define CFG_FT_RESOURCE_REQ_NAME "gFTResourceReqSupported" +#define CFG_FT_RESOURCE_REQ_MIN (0) +#define CFG_FT_RESOURCE_REQ_MAX (1) +#define CFG_FT_RESOURCE_REQ_DEFAULT (0) +#endif + +#define CFG_TELE_BCN_TRANS_LI_NAME "telescopicBeaconTransListenInterval" +#define CFG_TELE_BCN_TRANS_LI_MIN ( 0 ) +#define CFG_TELE_BCN_TRANS_LI_MAX ( 7 ) +#define CFG_TELE_BCN_TRANS_LI_DEFAULT ( 3 ) + +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_NAME "telescopicBeaconTransListenIntervalNumIdleBcns" +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MIN ( 5 ) +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MAX ( 255 ) +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_DEFAULT ( 10 ) + +#define CFG_TELE_BCN_MAX_LI_NAME "telescopicBeaconMaxListenInterval" +#define CFG_TELE_BCN_MAX_LI_MIN ( 0 ) +#define CFG_TELE_BCN_MAX_LI_MAX ( 7 ) +#define CFG_TELE_BCN_MAX_LI_DEFAULT ( 5 ) + +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_NAME "telescopicBeaconMaxListenIntervalNumIdleBcns" +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MIN ( 5 ) +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MAX ( 255 ) +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_DEFAULT ( 15 ) + +#define CFG_BCN_EARLY_TERM_WAKE_NAME "beaconEarlyTerminationWakeInterval" +#define CFG_BCN_EARLY_TERM_WAKE_MIN ( 2 ) +#define CFG_BCN_EARLY_TERM_WAKE_MAX ( 255 ) +#define CFG_BCN_EARLY_TERM_WAKE_DEFAULT ( 3 ) + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME "gNeighborScanTimerPeriod" +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN (3) +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX (300) +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT (200) + +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_NAME "gNeighborReassocThreshold" +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MIN (10) +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MAX (125) +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_DEFAULT (83) + +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME "gNeighborLookupThreshold" +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN (10) +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX (120) +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT (78) + +#define CFG_DELAY_BEFORE_VDEV_STOP_NAME "gDelayBeforeVdevStop" +#define CFG_DELAY_BEFORE_VDEV_STOP_MIN (2) +#define CFG_DELAY_BEFORE_VDEV_STOP_MAX (200) +#define CFG_DELAY_BEFORE_VDEV_STOP_DEFAULT (20) + +/* + * This parameter is the drop in RSSI value that will trigger a precautionary + * scan by firmware. + * MAX value is choose so that this type of scan can be disabled by user. + */ +#define CFG_ROAM_RESCAN_RSSI_DIFF_NAME "gRoamRescanRssiDiff" +#define CFG_ROAM_RESCAN_RSSI_DIFF_MIN (0) +#define CFG_ROAM_RESCAN_RSSI_DIFF_MAX (100) +#define CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT (5) + +#define CFG_DROPPED_PKT_DISCONNECT_TH_NAME "gDroppedPktDisconnectTh" +#define CFG_DROPPED_PKT_DISCONNECT_TH_MIN (48) +#define CFG_DROPPED_PKT_DISCONNECT_TH_MAX (256) +#define CFG_DROPPED_PKT_DISCONNECT_TH_DEFAULT (96) + +/* + * This parameter is the RSSI diff above neighbor lookup threshold, when + * opportunistic scan should be triggered. + * MAX value is choose so that this type of scan can be always enabled by user. + * MIN value will cause opportunistic scan to be triggered in neighbor lookup + * RSSI range. + */ +#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_NAME "gOpportunisticThresholdDiff" +#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MIN (0) +#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MAX (127) +#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT (0) + +#define CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME "gNeighborScanChannelList" +#define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT "" + +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME "gNeighborScanChannelMinTime" +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN (10) +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX (40) +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT (20) + +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME "gNeighborScanChannelMaxTime" +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN (3) +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX (300) +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT (30) + +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_NAME "gMaxNeighborReqTries" +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MIN (1) +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MAX (4) +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_DEFAULT (3) + + +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME "gNeighborScanRefreshPeriod" +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN (1000) +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX (60000) +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT (20000) + +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME "gEmptyScanRefreshPeriod" +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN (0) +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX (60000) +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT (0) + +#define CFG_ROAM_BMISS_FIRST_BCNT_NAME "gRoamBmissFirstBcnt" +#define CFG_ROAM_BMISS_FIRST_BCNT_MIN (5) +#define CFG_ROAM_BMISS_FIRST_BCNT_MAX (100) +#define CFG_ROAM_BMISS_FIRST_BCNT_DEFAULT (10) + +#define CFG_ROAM_BMISS_FINAL_BCNT_NAME "gRoamBmissFinalBcnt" +#define CFG_ROAM_BMISS_FINAL_BCNT_MIN (5) +#define CFG_ROAM_BMISS_FINAL_BCNT_MAX (100) +#define CFG_ROAM_BMISS_FINAL_BCNT_DEFAULT (10) + +#define CFG_ROAM_BEACON_RSSI_WEIGHT_NAME "gRoamBeaconRssiWeight" +#define CFG_ROAM_BEACON_RSSI_WEIGHT_MIN (0) +#define CFG_ROAM_BEACON_RSSI_WEIGHT_MAX (16) +#define CFG_ROAM_BEACON_RSSI_WEIGHT_DEFAULT (14) +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +#define CFG_QOS_WMM_BURST_SIZE_DEFN_NAME "burstSizeDefinition" +#define CFG_QOS_WMM_BURST_SIZE_DEFN_MIN (0) +#define CFG_QOS_WMM_BURST_SIZE_DEFN_MAX (1) +#define CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT (0) + +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME "tsInfoAckPolicy" +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN (0x00) +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX (0x01) +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT (0x00) + +#define CFG_SINGLE_TID_RC_NAME "SingleTIDRC" +#define CFG_SINGLE_TID_RC_MIN (0) /* Separate replay counter for all TID */ +#define CFG_SINGLE_TID_RC_MAX (1) /* Single replay counter for all TID */ +#define CFG_SINGLE_TID_RC_DEFAULT (1) + +#define CFG_MCAST_BCAST_FILTER_SETTING_NAME "McastBcastFilter" +#define CFG_MCAST_BCAST_FILTER_SETTING_MIN (0) +#define CFG_MCAST_BCAST_FILTER_SETTING_MAX (3) +#define CFG_MCAST_BCAST_FILTER_SETTING_DEFAULT (0) + +#define CFG_DYNAMIC_PSPOLL_VALUE_NAME "gDynamicPSPollvalue" +#define CFG_DYNAMIC_PSPOLL_VALUE_MIN (0) +#define CFG_DYNAMIC_PSPOLL_VALUE_MAX (255) +#define CFG_DYNAMIC_PSPOLL_VALUE_DEFAULT (0) + +#define CFG_TELE_BCN_WAKEUP_EN_NAME "gTelescopicBeaconWakeupEn" +#define CFG_TELE_BCN_WAKEUP_EN_MIN (0) +#define CFG_TELE_BCN_WAKEUP_EN_MAX (1) +#define CFG_TELE_BCN_WAKEUP_EN_DEFAULT (0) + +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME "gAddTSWhenACMIsOff" +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN (0) +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX (1) //Send AddTs even when ACM is not set for the AC +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT (0) + + +#define CFG_VALIDATE_SCAN_LIST_NAME "gValidateScanList" +#define CFG_VALIDATE_SCAN_LIST_MIN (0) +#define CFG_VALIDATE_SCAN_LIST_MAX (1) +#define CFG_VALIDATE_SCAN_LIST_DEFAULT (0) + +#define CFG_NULLDATA_AP_RESP_TIMEOUT_NAME "gNullDataApRespTimeout" +#define CFG_NULLDATA_AP_RESP_TIMEOUT_MIN ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN ) +#define CFG_NULLDATA_AP_RESP_TIMEOUT_MAX ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX ) +#define CFG_NULLDATA_AP_RESP_TIMEOUT_DEFAULT ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF ) + +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME "gApDataAvailPollInterval" +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN ) +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX ) +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF ) + +#define CFG_ENABLE_HOST_ARPOFFLOAD_NAME "hostArpOffload" +#define CFG_ENABLE_HOST_ARPOFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HOST_ARPOFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HOST_ARPOFFLOAD_DEFAULT ( 0 ) + +#define CFG_ENABLE_HOST_SSDP_NAME "ssdp" +#define CFG_ENABLE_HOST_SSDP_MIN ( 0 ) +#define CFG_ENABLE_HOST_SSDP_MAX ( 1 ) +#define CFG_ENABLE_HOST_SSDP_DEFAULT ( 1 ) + +#ifdef FEATURE_SECURE_FIRMWARE +#define CFG_ENABLE_FW_HASH_CHECK_NAME "gEnableFWHashCheck" +#define CFG_ENABLE_FW_HASH_CHECK_MIN ( 0 ) +#define CFG_ENABLE_FW_HASH_CHECK_MAX ( 1 ) +#define CFG_ENABLE_FW_HASH_CHECK_DEFAULT ( 1 ) +#endif + +#define CFG_ENABLE_HOST_NSOFFLOAD_NAME "hostNSOffload" +#define CFG_ENABLE_HOST_NSOFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HOST_NSOFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HOST_NSOFFLOAD_DEFAULT ( 0 ) + + +#define CFG_ENABLE_BTAMP_NAME "gEnableBtAmp" +#define CFG_ENABLE_BTAMP_MIN ( 0 ) +#define CFG_ENABLE_BTAMP_MAX ( 1 ) +#define CFG_ENABLE_BTAMP_DEFAULT ( 0 ) + +#ifdef WLAN_BTAMP_FEATURE +#define CFG_BT_AMP_PREFERRED_CHANNEL_NAME "BtAmpPreferredChannel" +#define CFG_BT_AMP_PREFERRED_CHANNEL_MIN (1) +#define CFG_BT_AMP_PREFERRED_CHANNEL_MAX (11) +#define CFG_BT_AMP_PREFERRED_CHANNEL_DEFAULT (1) +#endif //WLAN_BTAMP_FEATURE + +#define CFG_BAND_CAPABILITY_NAME "BandCapability" +#define CFG_BAND_CAPABILITY_MIN (0) +#define CFG_BAND_CAPABILITY_MAX (2) +#define CFG_BAND_CAPABILITY_DEFAULT (0) + +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_NAME "enableBeaconEarlyTermination" +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_MIN ( 0 ) +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_MAX ( 1 ) +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_DEFAULT ( 0 ) + +#define CFG_ENABLE_CLOSE_LOOP_NAME "gEnableCloseLoop" +#define CFG_ENABLE_CLOSE_LOOP_MIN WNI_CFG_FIXED_RATE_STAMIN +#define CFG_ENABLE_CLOSE_LOOP_MAX WNI_CFG_FIXED_RATE_STAMAX +#define CFG_ENABLE_CLOSE_LOOP_DEFAULT WNI_CFG_FIXED_RATE_STADEF + +#define CFG_ENABLE_BYPASS_11D_NAME "gEnableBypass11d" +#define CFG_ENABLE_BYPASS_11D_MIN ( 0 ) +#define CFG_ENABLE_BYPASS_11D_MAX ( 1 ) +#define CFG_ENABLE_BYPASS_11D_DEFAULT ( 1 ) + +#define CFG_ENABLE_DFS_CHNL_SCAN_NAME "gEnableDFSChnlScan" +#define CFG_ENABLE_DFS_CHNL_SCAN_MIN ( 0 ) +#define CFG_ENABLE_DFS_CHNL_SCAN_MAX ( 1 ) +#define CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT ( 1 ) + +typedef enum +{ + eHDD_LINK_SPEED_REPORT_ACTUAL = 0, + eHDD_LINK_SPEED_REPORT_MAX = 1, + eHDD_LINK_SPEED_REPORT_MAX_SCALED = 2, +}eHddLinkSpeedReportType; +#ifdef WLAN_FEATURE_11AC +#define CFG_VHT_CHANNEL_WIDTH "gVhtChannelWidth" +#define CFG_VHT_CHANNEL_WIDTH_MIN ( 0 ) +#define CFG_VHT_CHANNEL_WIDTH_MAX ( 2 ) +#define CFG_VHT_CHANNEL_WIDTH_DEFAULT ( 2 ) + +#define CFG_VHT_ENABLE_RX_MCS_8_9 "gVhtRxMCS" +#define CFG_VHT_ENABLE_RX_MCS_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_RX_MCS_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_RX_MCS_8_9_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_TX_MCS_8_9 "gVhtTxMCS" +#define CFG_VHT_ENABLE_TX_MCS_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_TX_MCS_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_TX_MCS_8_9_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_RX_MCS2x2_8_9 "gVhtRxMCS2x2" +#define CFG_VHT_ENABLE_RX_MCS2x2_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_RX_MCS2x2_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_RX_MCS2x2_8_9_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_TX_MCS2x2_8_9 "gVhtTxMCS2x2" +#define CFG_VHT_ENABLE_TX_MCS2x2_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_TX_MCS2x2_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_TX_MCS2x2_8_9_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_2x2_CAP_FEATURE "gEnable2x2" +#define CFG_VHT_ENABLE_2x2_CAP_FEATURE_MIN ( 0 ) +#define CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX ( 1 ) +#define CFG_VHT_ENABLE_2x2_CAP_FEATURE_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE "gEnableMuBformee" +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MIN ( 0 ) +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MAX ( 1 ) +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_PAID_FEATURE "gEnablePAID" +#define CFG_VHT_ENABLE_PAID_FEATURE_MIN ( 0 ) +#define CFG_VHT_ENABLE_PAID_FEATURE_MAX ( 1 ) +#define CFG_VHT_ENABLE_PAID_FEATURE_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_GID_FEATURE "gEnableGID" +#define CFG_VHT_ENABLE_GID_FEATURE_MIN ( 0 ) +#define CFG_VHT_ENABLE_GID_FEATURE_MAX ( 1 ) +#define CFG_VHT_ENABLE_GID_FEATURE_DEFAULT ( 0 ) +#endif + +#define CFG_VHT_ENABLE_1x1_TX_CHAINMASK "gSetTxChainmask1x1" +#define CFG_VHT_ENABLE_1x1_TX_CHAINMASK_MIN ( 1 ) +#define CFG_VHT_ENABLE_1x1_TX_CHAINMASK_MAX ( 2 ) +#define CFG_VHT_ENABLE_1x1_TX_CHAINMASK_DEFAULT ( 1 ) + +#define CFG_VHT_ENABLE_1x1_RX_CHAINMASK "gSetRxChainmask1x1" +#define CFG_VHT_ENABLE_1x1_RX_CHAINMASK_MIN ( 1 ) +#define CFG_VHT_ENABLE_1x1_RX_CHAINMASK_MAX ( 2 ) +#define CFG_VHT_ENABLE_1x1_RX_CHAINMASK_DEFAULT ( 1 ) + +#define CFG_ENABLE_AMPDUPS_FEATURE "gEnableAMPDUPS" +#define CFG_ENABLE_AMPDUPS_FEATURE_MIN ( 0 ) +#define CFG_ENABLE_AMPDUPS_FEATURE_MAX ( 1 ) +#define CFG_ENABLE_AMPDUPS_FEATURE_DEFAULT ( 0 ) + +#define CFG_HT_ENABLE_SMPS_CAP_FEATURE "gEnableHtSMPS" +#define CFG_HT_ENABLE_SMPS_CAP_FEATURE_MIN ( 0 ) +#define CFG_HT_ENABLE_SMPS_CAP_FEATURE_MAX ( 1 ) +#define CFG_HT_ENABLE_SMPS_CAP_FEATURE_DEFAULT ( 0 ) + +#define CFG_HT_SMPS_CAP_FEATURE "gHtSMPS" +#define CFG_HT_SMPS_CAP_FEATURE_MIN ( 0 ) +#define CFG_HT_SMPS_CAP_FEATURE_MAX ( 3 ) +#define CFG_HT_SMPS_CAP_FEATURE_DEFAULT ( 3 ) + +#define CFG_DISABLE_DFS_CH_SWITCH "gDisableDFSChSwitch" +#define CFG_DISABLE_DFS_CH_SWITCH_MIN ( 0 ) +#define CFG_DISABLE_DFS_CH_SWITCH_MAX ( 1 ) +#define CFG_DISABLE_DFS_CH_SWITCH_DEFAULT ( 0 ) + +#define CFG_ENABLE_DFS_MASTER_CAPABILITY "gEnableDFSMasterCap" +#define CFG_ENABLE_DFS_MASTER_CAPABILITY_MIN ( 0 ) +#define CFG_ENABLE_DFS_MASTER_CAPABILITY_MAX ( 1 ) +#define CFG_ENABLE_DFS_MASTER_CAPABILITY_DEFAULT ( 0 ) + +/* + * This parameter indicates if SAP preferred + * channel are INDOOR/OUTDOOR Channels. + * 0- Indicates no preferred channel location or + * no preferred channel restrictions. + * 1- Indicates Use only Indoor channels only. + * 2- Indicates Use outdoor channels only. + */ +#define CFG_SAP_PREFERRED_CHANNEL_LOCATION "gSapPreferredChanLocation" +#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_MIN ( 0 ) +#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_MAX ( 2 ) +#define CFG_SAP_PREFERRED_CHANNEL_LOCATION_DEFAULT ( 0 ) + +#define CFG_DISABLE_DFS_JAPAN_W53 "gDisableDfsJapanW53" +#define CFG_DISABLE_DFS_JAPAN_W53_MIN ( 0 ) +#define CFG_DISABLE_DFS_JAPAN_W53_MAX ( 1 ) +#define CFG_DISABLE_DFS_JAPAN_W53_DEFAULT ( 0 ) + +#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME "dfsPhyerrFilterOffload" +#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT ( 0 ) + +#define CFG_REPORT_MAX_LINK_SPEED "gReportMaxLinkSpeed" +#define CFG_REPORT_MAX_LINK_SPEED_MIN ( eHDD_LINK_SPEED_REPORT_ACTUAL ) +#define CFG_REPORT_MAX_LINK_SPEED_MAX ( eHDD_LINK_SPEED_REPORT_MAX_SCALED ) +#define CFG_REPORT_MAX_LINK_SPEED_DEFAULT ( eHDD_LINK_SPEED_REPORT_MAX_SCALED ) + +/* + * RSSI Thresholds + * Used when eHDD_LINK_SPEED_REPORT_SCALED is selected + */ +#define CFG_LINK_SPEED_RSSI_HIGH "gLinkSpeedRssiHigh" +#define CFG_LINK_SPEED_RSSI_HIGH_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_HIGH_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_HIGH_DEFAULT ( -55 ) + +#define CFG_LINK_SPEED_RSSI_MID "gLinkSpeedRssiMed" +#define CFG_LINK_SPEED_RSSI_MID_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_MID_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_MID_DEFAULT ( -65 ) + +#define CFG_LINK_SPEED_RSSI_LOW "gLinkSpeedRssiLow" +#define CFG_LINK_SPEED_RSSI_LOW_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_LOW_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_LOW_DEFAULT ( -80 ) + +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_NAME "isP2pDeviceAddrAdministrated" +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MIN ( 0 ) +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MAX ( 1 ) +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_DEFAULT ( 1 ) + + +#define CFG_ENABLE_SSR "gEnableSSR" +#define CFG_ENABLE_SSR_MIN ( 0 ) +#define CFG_ENABLE_SSR_MAX ( 1 ) +#define CFG_ENABLE_SSR_DEFAULT ( 1 ) + +#define CFG_ENABLE_OVERLAP_CH "gEnableOverLapCh" +#define CFG_ENABLE_OVERLAP_CH_MIN ( 0 ) +#define CFG_ENABLE_OVERLAP_CH_MAX ( 1 ) +#define CFG_ENABLE_OVERLAP_CH_DEFAULT ( 0 ) + +#define CFG_PPS_ENABLE_5G_EBT "gEnable5gEBT" +#define CFG_PPS_ENABLE_5G_EBT_FEATURE_MIN ( 0 ) +#define CFG_PPS_ENABLE_5G_EBT_FEATURE_MAX ( 1 ) +#define CFG_PPS_ENABLE_5G_EBT_FEATURE_DEFAULT ( 0 ) + +#define CFG_ENABLE_MEMORY_DEEP_SLEEP "gEnableMemDeepSleep" +#define CFG_ENABLE_MEMORY_DEEP_SLEEP_MIN ( 0 ) +#define CFG_ENABLE_MEMORY_DEEP_SLEEP_MAX ( 1 ) +#define CFG_ENABLE_MEMORY_DEEP_SLEEP_DEFAULT ( 1 ) + +/* In cfg.dat 1=1MBPS, 2=2MBPS, 3=5_5MBPS, 4=11MBPS, 5=6MBPS, 6=9MBPS, + * 7=12MBPS, 8=18MBPS, 9=24MBPS. But 6=9MBPS and 8=18MBPS are not basic + * 11g rates and should not be set by gDefaultRateIndex24Ghz. +*/ + +#define CFG_DEFAULT_RATE_INDEX_24GH "gDefaultRateIndex24Ghz" +#define CFG_DEFAULT_RATE_INDEX_24GH_MIN ( 1 ) +#define CFG_DEFAULT_RATE_INDEX_24GH_MAX ( 9 ) +#define CFG_DEFAULT_RATE_INDEX_24GH_DEFAULT ( 1 ) + + +#define CFG_ENABLE_PACKET_LOG "gEnablePacketLog" +#define CFG_ENABLE_PACKET_LOG_MIN ( 0 ) +#define CFG_ENABLE_PACKET_LOG_MAX ( 1 ) +#define CFG_ENABLE_PACKET_LOG_DEFAULT ( 0 ) + +/* gFwDebugLogType takes values from enum dbglog_process_t, + * make default value as DBGLOG_PROCESS_NET_RAW to give the + * logs to net link since cnss_diag service is started at boot + * time by default. + */ +#define CFG_ENABLE_FW_LOG_TYPE "gFwDebugLogType" +#define CFG_ENABLE_FW_LOG_TYPE_MIN ( 0 ) +#define CFG_ENABLE_FW_LOG_TYPE_MAX ( 255 ) +#define CFG_ENABLE_FW_LOG_TYPE_DEFAULT ( 3 ) + +/* gFwDebugLogLevel takes values from enum DBGLOG_LOG_LVL, + * make default value as DBGLOG_WARN to enable error and + * warning logs by default. + */ +#define CFG_ENABLE_FW_DEBUG_LOG_LEVEL "gFwDebugLogLevel" +#define CFG_ENABLE_FW_DEBUG_LOG_LEVEL_MIN ( 0 ) +#define CFG_ENABLE_FW_DEBUG_LOG_LEVEL_MAX ( 255 ) +#define CFG_ENABLE_FW_DEBUG_LOG_LEVEL_DEFAULT ( 4 ) + +/* For valid values of log levels check enum DBGLOG_LOG_LVL and + * for valid values of module ids check enum WLAN_MODULE_ID. + */ +#define CFG_ENABLE_FW_MODULE_LOG_LEVEL "gFwDebugModuleLoglevel" +#define CFG_ENABLE_FW_MODULE_LOG_DEFAULT "" + +#ifdef FEATURE_GREEN_AP +#define CFG_ENABLE_GREEN_AP_FEATURE "gEnableGreenAp" +#define CFG_ENABLE_GREEN_AP_FEATURE_MIN ( 0 ) +#define CFG_ENABLE_GREEN_AP_FEATURE_MAX ( 1 ) +#define CFG_ENABLE_GREEN_AP_FEATURE_DEFAULT ( 1 ) +#endif + +#ifdef FEATURE_WLAN_FORCE_SAP_SCC +#define CFG_SAP_SCC_CHAN_AVOIDANCE "gSapSccChanAvoidance" +#define CFG_SAP_SCC_CHAN_AVOIDANCE_MIN ( 0 ) +#define CFG_SAP_SCC_CHAN_AVOIDANCE_MAX ( 1 ) +#define CFG_SAP_SCC_CHAN_AVOIDANCE_DEFAULT ( 0 ) +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + +/* + * VOS Trace Enable Control + * Notes: + * the MIN/MAX/DEFAULT values apply for all modules + * the DEFAULT value is outside the valid range. if the DEFAULT + * value is not overridden, then no change will be made to the + * "built in" default values compiled into the code + * values are a bitmap indicating which log levels are to enabled + * (must match order of vos_trace_level enumerations) + * 00000001 FATAL + * 00000010 ERROR + * 00000100 WARN + * 00001000 INFO + * 00010000 INFO HIGH + * 00100000 INFO MED + * 01000000 INFO LOW + * 10000000 DEBUG + * + * hence a value of 0xFF would set all bits (enable all logs) + */ + +#define CFG_VOS_TRACE_ENABLE_BAP_NAME "vosTraceEnableBAP" +#define CFG_VOS_TRACE_ENABLE_TL_NAME "vosTraceEnableTL" +#define CFG_VOS_TRACE_ENABLE_WDI_NAME "vosTraceEnableWDI" +#define CFG_VOS_TRACE_ENABLE_HDD_NAME "vosTraceEnableHDD" +#define CFG_VOS_TRACE_ENABLE_SME_NAME "vosTraceEnableSME" +#define CFG_VOS_TRACE_ENABLE_PE_NAME "vosTraceEnablePE" +#define CFG_VOS_TRACE_ENABLE_PMC_NAME "vosTraceEnablePMC" +#define CFG_VOS_TRACE_ENABLE_WDA_NAME "vosTraceEnableWDA" +#define CFG_VOS_TRACE_ENABLE_SYS_NAME "vosTraceEnableSYS" +#define CFG_VOS_TRACE_ENABLE_VOSS_NAME "vosTraceEnableVOSS" +#define CFG_VOS_TRACE_ENABLE_SAP_NAME "vosTraceEnableSAP" +#define CFG_VOS_TRACE_ENABLE_HDD_SAP_NAME "vosTraceEnableHDDSAP" + +#define CFG_VOS_TRACE_ENABLE_MIN (0) +#define CFG_VOS_TRACE_ENABLE_MAX (0xff) +#define CFG_VOS_TRACE_ENABLE_DEFAULT (0xffff) + +#define HDD_MCASTBCASTFILTER_FILTER_NONE 0x00 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST 0x01 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST 0x02 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST 0x03 +#define HDD_MULTICAST_FILTER_LIST 0x04 +#define HDD_MULTICAST_FILTER_LIST_CLEAR 0x05 + +/* + * + * SAP Auto Channel Enable + * Notes: + * Auto Channel selection for SAP configuration + * 0 - Disable Auto Channel + * 1 - Enable auto channel selection in auto mode. + * When enable auto channel, channel provided by Supplicant will be ignored. + * + * Default configuration: Auto channel is disabled. + */ + +#define CFG_SAP_AUTO_CHANNEL_SELECTION_NAME "gApAutoChannelSelection" + +#define CFG_SAP_AUTO_CHANNEL_SELECTION_MIN ( 0 ) +#define CFG_SAP_AUTO_CHANNEL_SELECTION_MAX ( 1 ) +#define CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT ( 0 ) + +#define CFG_ONLY_ALLOWED_CHANNELS "gACSAllowedChannels" +#define CFG_ONLY_ALLOWED_CHANNELS_DEFAULT "" + +/* ACS Scan band preference + * 0 -- No preference + * 1 -- Scan 2.4G first + * 2 -- Scan 5G first +*/ +#define CFG_SAP_SCAN_BAND_PREFERENCE "gAcsScanBandPreference" +#define CFG_SAP_SCAN_BAND_PREFERENCE_MIN (0) +#define CFG_SAP_SCAN_BAND_PREFERENCE_MAX (2) +#define CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT (0) +#define CFG_ACS_BAND_SWITCH_THRESHOLD "gACSBandSwitchThreshold" +#define CFG_ACS_BAND_SWITCH_THRESHOLD_MIN (0) +#define CFG_ACS_BAND_SWITCH_THRESHOLD_MAX (4444) +/* 2 BSS, maximum RSSI -90 */ +#define CFG_ACS_BAND_SWITCH_THRESHOLD_DEFAULT (296) + +/*BMPS Logic + * Notes: + * 1 - Then Host driver and above layers control the PS mechanism + * 0 - Diver/Core Stack internally control the Power saving mechanism + */ +#define CFG_ANDRIOD_POWER_SAVE_NAME "isAndroidPsEn" +#define CFG_ANDRIOD_POWER_SAVE_MIN ( 0 ) +#define CFG_ANDRIOD_POWER_SAVE_MAX ( 1 ) +#define CFG_ANDRIOD_POWER_SAVE_DEFAULT ( 0 ) + + +/* + * Enable Dynamic DTIM + * Options + * 0 -Disable DynamicDTIM + * 1 to 5 - SLM will switch to DTIM specified here when host suspends and + * switch DTIM1 when host resumes */ +#define CFG_ENABLE_DYNAMIC_DTIM_NAME "gEnableDynamicDTIM" +#define CFG_ENABLE_DYNAMIC_DTIM_MIN ( 0 ) +#define CFG_ENABLE_DYNAMIC_DTIM_MAX ( 5 ) +#define CFG_ENABLE_DYNAMIC_DTIM_DEFAULT ( 0 ) + +/* + * Enable First Scan 2G Only + * Options + * 0 - Disable First Scan 2G Option + * 1 - Enable First Scan 2G Option + */ +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME "gEnableFirstScan2GOnly" +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN ( 0 ) +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX ( 1 ) +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT ( 0 ) + +/* + * Skip DFS Channel in case of P2P Search + * Options + * 0 - Don't Skip DFS Channel in case of P2P Search + * 1 - Skip DFS Channel in case of P2P Search + */ +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_NAME "gSkipDfsChannelInP2pSearch" +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MIN ( 0 ) +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MAX ( 1 ) +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_DEFAULT ( 1 ) + +/* + * Ignore Dynamic Dtim in case of P2P + * Options + * 0 - Consider Dynamic Dtim incase of P2P + * 1 - Ignore Dynamic Dtim incase of P2P + */ +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_NAME "gIgnoreDynamicDtimInP2pMode" +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MIN ( 0 ) +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MAX ( 1 ) +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_DEFAULT ( 0 ) + + +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_NAME "gEnableAutomaticTxPowerControl" +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MIN ( 0 ) +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MAX ( 1 ) +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_DEFAULT ( 1 ) + +#define CFG_SHORT_GI_40MHZ_NAME "gShortGI40Mhz" +#define CFG_SHORT_GI_40MHZ_MIN 0 +#define CFG_SHORT_GI_40MHZ_MAX 1 +#define CFG_SHORT_GI_40MHZ_DEFAULT 1 + +/* + * Enable / Disable MCC feature + * Default: Enable + */ +#define CFG_ENABLE_MCC_ENABLED_NAME "gEnableMCCMode" +#define CFG_ENABLE_MCC_ENABLED_MIN ( 0 ) +#define CFG_ENABLE_MCC_ENABLED_MAX ( 1 ) +#define CFG_ENABLE_MCC_ENABLED_DEFAULT ( 1 ) + +/* + * Allow GO in MCC mode to accept different beacon interval than STA's. + * Added for Wi-Fi Cert. 5.1.12 + * Default: gAllowMCCGODiffBI = 2 + * If gAllowMCCGODiffBI = 1 // Set to 1 for WFA certification. GO Beacon + * interval is not changed. MCC GO + * doesn't work well in optimized way. + * In worst scenario, it may invite STA + * disconnection. + * gAllowMCCGODiffBI = 2 //If set to 2 workaround 1 disassoc all the clients + * and update beacon Interval + * gAllowMCCGODiffBI = 3 //If set to 3 tear down the P2P link in auto/ + * Non-autonomous -GO case + * gAllowMCCGODiffBI = 4 //If set to 4 don't disconnect the P2P client + * in autonomous/Non-autonomous -GO case update + * the BI dynamically + */ +#define CFG_ALLOW_MCC_GO_DIFF_BI_NAME "gAllowMCCGODiffBI" +#define CFG_ALLOW_MCC_GO_DIFF_BI_MIN ( 0 ) +#define CFG_ALLOW_MCC_GO_DIFF_BI_MAX ( 4 ) +#define CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT ( 4 ) + +/* + * Enable/Disable Thermal Mitigation feature + * Default: Disable + */ +#define CFG_THERMAL_MIGRATION_ENABLE_NAME "gThermalMitigationEnable" +#define CFG_THERMAL_MIGRATION_ENABLE_MIN ( 0 ) +#define CFG_THERMAL_MIGRATION_ENABLE_MAX ( 1 ) +#define CFG_THERMAL_MIGRATION_ENABLE_DEFAULT ( 0 ) + + + +#define CFG_THROTTLE_PERIOD_NAME "gThrottlePeriod" +#define CFG_THROTTLE_PERIOD_MIN ( 10 ) +#define CFG_THROTTLE_PERIOD_MAX ( 10000 ) +#define CFG_THROTTLE_PERIOD_DEFAULT ( 4000 ) + +#define CFG_THERMAL_TEMP_MIN_LEVEL0_NAME "gThermalTempMinLevel0" +#define CFG_THERMAL_TEMP_MIN_LEVEL0_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL0_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL0_DEFAULT ( 0 ) + +#define CFG_THERMAL_TEMP_MAX_LEVEL0_NAME "gThermalTempMaxLevel0" +#define CFG_THERMAL_TEMP_MAX_LEVEL0_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL0_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL0_DEFAULT ( 90 ) + +#define CFG_THERMAL_TEMP_MIN_LEVEL1_NAME "gThermalTempMinLevel1" +#define CFG_THERMAL_TEMP_MIN_LEVEL1_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL1_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL1_DEFAULT ( 70 ) + +#define CFG_THERMAL_TEMP_MAX_LEVEL1_NAME "gThermalTempMaxLevel1" +#define CFG_THERMAL_TEMP_MAX_LEVEL1_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL1_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL1_DEFAULT ( 110 ) + +#define CFG_THERMAL_TEMP_MIN_LEVEL2_NAME "gThermalTempMinLevel2" +#define CFG_THERMAL_TEMP_MIN_LEVEL2_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL2_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL2_DEFAULT ( 90 ) + +#define CFG_THERMAL_TEMP_MAX_LEVEL2_NAME "gThermalTempMaxLevel2" +#define CFG_THERMAL_TEMP_MAX_LEVEL2_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL2_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL2_DEFAULT ( 125 ) + +#define CFG_THERMAL_TEMP_MIN_LEVEL3_NAME "gThermalTempMinLevel3" +#define CFG_THERMAL_TEMP_MIN_LEVEL3_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL3_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MIN_LEVEL3_DEFAULT ( 110 ) + +#define CFG_THERMAL_TEMP_MAX_LEVEL3_NAME "gThermalTempMaxLevel3" +#define CFG_THERMAL_TEMP_MAX_LEVEL3_MIN ( 0 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL3_MAX ( 1000 ) +#define CFG_THERMAL_TEMP_MAX_LEVEL3_DEFAULT ( 0 ) + + +/* + * Enable/Disable Modulated DTIM feature + * Default: Disable + */ +#define CFG_ENABLE_MODULATED_DTIM_NAME "gEnableModulatedDTIM" +#define CFG_ENABLE_MODULATED_DTIM_MIN ( 0 ) +#define CFG_ENABLE_MODULATED_DTIM_MAX ( 5 ) +#define CFG_ENABLE_MODULATED_DTIM_DEFAULT ( 0 ) + +/* + * Enable/Disable Multicast MAC Address List feature + * Default: Disable + */ +#define CFG_MC_ADDR_LIST_ENABLE_NAME "gMCAddrListEnable" +#define CFG_MC_ADDR_LIST_ENABLE_MIN ( 0 ) +#define CFG_MC_ADDR_LIST_ENABLE_MAX ( 1 ) +#define CFG_MC_ADDR_LIST_ENABLE_DEFAULT ( 0 ) + +/* Set number of buffers to be advertised during ADDBA negotiation*/ +#define CFG_NUM_BUFF_ADVERT_NAME "gNumBuffAdvert" +#define CFG_NUM_BUFF_ADVERT_MIN ( 0 ) +#define CFG_NUM_BUFF_ADVERT_MAX ( 128 ) +#define CFG_NUM_BUFF_ADVERT_DEFAULT ( 64 ) + +/* + * Allow MCC to modify config + */ +#define CFG_MCC_CONFIG_PARAM_NAME "gMccAllowCfgModify" +#define CFG_MCC_CONFIG_PARAM_MIN ( 0x0000 ) +#define CFG_MCC_CONFIG_PARAM_MAX ( 0x01ff ) +#define CFG_MCC_CONFIG_PARAM_DEFAULT ( 0x000C ) + +#define CFG_ENABLE_RX_STBC "gEnableRXSTBC" +#define CFG_ENABLE_RX_STBC_MIN ( 0 ) +#define CFG_ENABLE_RX_STBC_MAX ( 1 ) +#define CFG_ENABLE_RX_STBC_DEFAULT ( 1 ) + +#define CFG_ENABLE_TX_STBC "gEnableTXSTBC" +#define CFG_ENABLE_TX_STBC_MIN ( 0 ) +#define CFG_ENABLE_TX_STBC_MAX ( 1 ) +#define CFG_ENABLE_TX_STBC_DEFAULT ( 0 ) + +#define CFG_ENABLE_RX_LDPC "gEnableRXLDPC" +#define CFG_ENABLE_RX_LDPC_MIN ( 0 ) +#define CFG_ENABLE_RX_LDPC_MAX ( 1 ) +#define CFG_ENABLE_RX_LDPC_DEFAULT ( 0 ) + +/* + * Enable/Disable vsta based on MAX Assoc limit + * defined in WCNSS_qcom_cfg.ini. + */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define CFG_VSTA_SUPPORT_ENABLE "gEnableVSTASupport" +#define CFG_VSTA_SUPPORT_ENABLE_MIN ( 0 ) +#define CFG_VSTA_SUPPORT_ENABLE_MAX ( 1 ) +#define CFG_VSTA_SUPPORT_ENABLE_DEFAULT ( 0 ) +#endif + +#ifdef FEATURE_WLAN_TDLS +#define CFG_TDLS_SUPPORT_ENABLE "gEnableTDLSSupport" +#define CFG_TDLS_SUPPORT_ENABLE_MIN ( 0 ) +#define CFG_TDLS_SUPPORT_ENABLE_MAX ( 1 ) +#define CFG_TDLS_SUPPORT_ENABLE_DEFAULT ( 0 ) + +#define CFG_TDLS_IMPLICIT_TRIGGER "gEnableTDLSImplicitTrigger" +#define CFG_TDLS_IMPLICIT_TRIGGER_MIN ( 0 ) +#define CFG_TDLS_IMPLICIT_TRIGGER_MAX ( 1 ) +#define CFG_TDLS_IMPLICIT_TRIGGER_DEFAULT ( 0 ) + +#define CFG_TDLS_TX_STATS_PERIOD "gTDLSTxStatsPeriod" +#define CFG_TDLS_TX_STATS_PERIOD_MIN ( 10 ) +#define CFG_TDLS_TX_STATS_PERIOD_MAX ( 4294967295UL ) +#define CFG_TDLS_TX_STATS_PERIOD_DEFAULT ( 5000 ) + +#define CFG_TDLS_TX_PACKET_THRESHOLD "gTDLSTxPacketThreshold" +#define CFG_TDLS_TX_PACKET_THRESHOLD_MIN ( 0 ) +#define CFG_TDLS_TX_PACKET_THRESHOLD_MAX ( 4294967295UL ) +#define CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT ( 100 ) + +#define CFG_TDLS_DISCOVERY_PERIOD "gTDLSDiscoveryPeriod" +#define CFG_TDLS_DISCOVERY_PERIOD_MIN ( 5000 ) +#define CFG_TDLS_DISCOVERY_PERIOD_MAX ( 4294967295UL ) +#define CFG_TDLS_DISCOVERY_PERIOD_DEFAULT ( 20000 ) + +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT "gTDLSMaxDiscoveryAttempt" +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ( 1 ) +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX ( 100 ) +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_DEFAULT ( 5 ) + +#define CFG_TDLS_IDLE_TIMEOUT "gTDLSIdleTimeout" +#define CFG_TDLS_IDLE_TIMEOUT_MIN ( 2000 ) +#define CFG_TDLS_IDLE_TIMEOUT_MAX ( 40000 ) +#define CFG_TDLS_IDLE_TIMEOUT_DEFAULT ( 5000 ) + +#define CFG_TDLS_IDLE_PACKET_THRESHOLD "gTDLSIdlePacketThreshold" +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ( 0 ) +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX ( 40000 ) +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT ( 5 ) + +#define CFG_TDLS_RSSI_HYSTERESIS "gTDLSRssiHysteresis" +#define CFG_TDLS_RSSI_HYSTERESIS_MIN ( 0 ) +#define CFG_TDLS_RSSI_HYSTERESIS_MAX ( 100 ) +#define CFG_TDLS_RSSI_HYSTERESIS_DEFAULT ( 100 ) + +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD "gTDLSRSSITriggerThreshold" +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ( -120 ) +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX ( 0 ) +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_DEFAULT ( -75 ) + +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD "gTDLSRSSITeardownThreshold" +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ( -120 ) +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX ( 0 ) +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_DEFAULT ( -75 ) + +#define CFG_TDLS_RSSI_DELTA "gTDLSRSSIDelta" +#define CFG_TDLS_RSSI_DELTA_MIN ( -30 ) +#define CFG_TDLS_RSSI_DELTA_MAX ( 0 ) +#define CFG_TDLS_RSSI_DELTA_DEFAULT ( -20 ) + +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_NAME "gTDLSUapsdMask" // ACs to setup U-APSD for TDLS Sta +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_MIN (0) +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_MAX (0x0F) +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_DEFAULT (0x0F) + +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE "gEnableTDLSBufferSta" +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MIN (0) +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MAX (1) +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_DEFAULT (1) + +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME "gTDLSPuapsdInactivityTime" +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN (0) +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX (10) +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEFAULT (0) + +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD "gTDLSPuapsdRxFrameThreshold" +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN (10) +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX (20) +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT (10) + +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW "gTDLSPuapsdPTIWindow" +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MIN (1) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MAX (5) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_DEFAULT (2) + +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT "gTDLSPuapsdPTRTimeout" +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MIN (0) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MAX (10000) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_DEFAULT (5000) + +#define CFG_TDLS_EXTERNAL_CONTROL "gTDLSExternalControl" +#define CFG_TDLS_EXTERNAL_CONTROL_MIN (0) +#define CFG_TDLS_EXTERNAL_CONTROL_MAX (1) +#define CFG_TDLS_EXTERNAL_CONTROL_DEFAULT (0) + +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE "gEnableTDLSOffChannel" +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN (0) +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX (1) +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_DEFAULT (0) + +#define CFG_TDLS_WMM_MODE_ENABLE "gEnableTDLSWmmMode" +#define CFG_TDLS_WMM_MODE_ENABLE_MIN (0) +#define CFG_TDLS_WMM_MODE_ENABLE_MAX (1) +#define CFG_TDLS_WMM_MODE_ENABLE_DEFAULT (0) + +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM "gTDLSPrefOffChanNum" +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN (1) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX (165) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT (36) + +/* Tdls offchannel bandwidth is now represented in bits as follows. + * 0th bit - 20MHz + * 1st bit - 40MHz + * 2nd bit - 80MHz + * 3rd bit - 160MHz + * If more than one bits are set the f/w will start from the highest + * and select one, based on the capability of peer. + */ +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW "gTDLSPrefOffChanBandwidth" +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MIN (0) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MAX (0x0F) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_DEFAULT (0x07) + +/* Enable TDLS Scan: Allow scan and maintain TDLS link. + * 0: If peer is not buffer STA capable and device is not sleep STA + * capable, then teardown TDLS link when scan is initiated. If peer + * is buffer STA and we can be sleep STA then TDLS link is maintained + * during scan. + * 1: Maintain TDLS link and allow scan even if peer is not buffer STA + * capable and device is not sleep STA capable. There will be loss of + * Rx pkts since peer would not know when device moves away from tdls + * channel. Tx on TDLS link would stop when device moves away from tdls + * channel. + */ +#define CFG_TDLS_SCAN_ENABLE "gEnableTDLSScan" +#define CFG_TDLS_SCAN_ENABLE_MIN (0) +#define CFG_TDLS_SCAN_ENABLE_MAX (1) +#define CFG_TDLS_SCAN_ENABLE_DEFAULT (0) +#endif + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE "gEnableActiveModeOffload" +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_MIN ( 0 ) +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_MAX ( 1 ) +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_DEFAULT ( 1 ) +#endif +/* Enable/Disable LPWR Image(cMEM uBSP) Transition */ +#define CFG_ENABLE_LPWR_IMG_TRANSITION_NAME "gEnableLpwrImgTransition" +#define CFG_ENABLE_LPWR_IMG_TRANSITION_MIN ( 0 ) +#define CFG_ENABLE_LPWR_IMG_TRANSITION_MAX ( 1 ) +#define CFG_ENABLE_LPWR_IMG_TRANSITION_DEFAULT ( 0 ) + + + +/* + * Scan Aging timeout value in seconds + */ +#define CFG_SCAN_AGING_PARAM_NAME "gScanAgingTime" +#define CFG_SCAN_AGING_PARAM_MIN ( 0 ) +#define CFG_SCAN_AGING_PARAM_MAX ( 200 ) +#define CFG_SCAN_AGING_PARAM_DEFAULT ( 60 ) + +/* Config Param to enable the txLdpc capability + * 0 - disable + * 1 - HT LDPC enable + * 2 - VHT LDPC enable + * 3 - HT & VHT LDPC enable */ +#define CFG_TX_LDPC_ENABLE_FEATURE "gTxLdpcEnable" +#define CFG_TX_LDPC_ENABLE_FEATURE_MIN ( 0 ) +#define CFG_TX_LDPC_ENABLE_FEATURE_MAX ( 3 ) +#define CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT ( 0 ) + +/* + * Enable / Disable MCC Adaptive Scheduler feature + * Default: Enable + */ +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_NAME "gEnableMCCAdaptiveScheduler" +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN ( 0 ) +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ( 1 ) +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT ( 1 ) + +#ifdef WLAN_FEATURE_11AC +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE "gTxBFEnable" +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN ) +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX ) +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_DEFAULT ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF ) + +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED "gTxBFCsnValue" +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MIN ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN ) +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1 ) +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_DEFAULT ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1 ) + +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ "gEnableTxBFin20MHz" +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_MIN ( 0 ) +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_MAX ( 1 ) +#define CFG_VHT_ENABLE_TXBF_IN_20MHZ_DEFAULT ( 0 ) + +#endif + +//Enable debug for remain on channel issues +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_NAME "gDebugP2pRemainOnChannel" +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_DEFAULT ( 0 ) +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MIN ( 0 ) +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MAX ( 1 ) + +/* + * SAP ALLOW All Channels + */ +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_NAME "gSapAllowAllChannel" +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MIN ( 0 ) +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MAX ( 1 ) +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_DEFAULT ( 0 ) + + +#ifdef WLAN_FEATURE_11AC +#define CFG_DISABLE_LDPC_WITH_TXBF_AP "gDisableLDPCWithTxbfAP" +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN ( 0 ) +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX ( 1 ) +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT ( 0 ) +#endif + +#define CFG_LIST_OF_NON_DFS_COUNTRY_CODE "gListOfNonDfsCountryCode" +#define CFG_LIST_OF_NON_DFS_COUNTRY_CODE_DEFAULT "JO,MA" + + +/* + * IBSS Operating Channels for 2.4G and 5GHz channels + */ +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME "gAdHocChannel5G" +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN ( 36 ) +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX ( 165 ) +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT ( 44 ) + +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME "gAdHocChannel24G" +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN ( 1 ) +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX ( 14 ) +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT ( 6 ) + +#define CFG_LIST_OF_NON_11AC_COUNTRY_CODE "gListOfNon11acCountryCode" +#define CFG_LIST_OF_NON_11AC_COUNTRY_CODE_DEFAULT "RU,UA,ZA" + +/* Parameter to control VHT support in 2.4 GHz band */ +#define CFG_ENABLE_VHT_FOR_24GHZ_NAME "gEnableVhtFor24GHzBand" +#define CFG_ENABLE_VHT_FOR_24GHZ_MIN (0) +#define CFG_ENABLE_VHT_FOR_24GHZ_MAX (1) +#define CFG_ENABLE_VHT_FOR_24GHZ_DEFAULT (0) + + +#define CFG_MAX_MEDIUM_TIME "gMaxMediumTime" +#define CFG_MAX_MEDIUM_TIME_STAMIN WNI_CFG_MAX_MEDIUM_TIME_STAMIN +#define CFG_MAX_MEDIUM_TIME_STAMAX WNI_CFG_MAX_MEDIUM_TIME_STAMAX +#define CFG_MAX_MEDIUM_TIME_STADEFAULT WNI_CFG_MAX_MEDIUM_TIME_STADEF + +/* + * SCAN Offload + */ +#define CFG_SCAN_OFFLOAD_NAME "gEnableDirectedScanOffload" +#define CFG_SCAN_OFFLOAD_DISABLE ( 0 ) +#define CFG_SCAN_OFFLOAD_ENABLE ( 1 ) +#define CFG_SCAN_OFFLOAD_DEFAULT ( CFG_SCAN_OFFLOAD_DISABLE ) + +/* + * Enable legacy fast roaming (LFR) on STA link during concurrent sessions + */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY "gEnableFastRoamInConcurrency" +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN ( 0 ) +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX ( 1 ) +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT ( 1 ) +#endif + +/* + * FlexConnectPowerFactor parameter + * Default: Disable (0) + */ +#define CFG_FLEX_CONNECT_POWER_FACTOR_NAME "gFlexConnectPowerFactor" +#define CFG_FLEX_CONNECT_POWER_FACTOR_MIN ( 0 ) +#define CFG_FLEX_CONNECT_POWER_FACTOR_MAX ( 9 ) +#define CFG_FLEX_CONNECT_POWER_FACTOR_DEFAULT ( 0 ) + +/* + * Enable heart beat monitoring offload to FW + */ +#define CFG_ENABLE_HEART_BEAT_OFFLOAD "gEnableIbssHeartBeatOffload" +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_DEFAULT ( 1 ) + +#define CFG_ANTENNA_DIVERSITY_PARAM_NAME "gAntennaDiversity" +#define CFG_ANTENNA_DIVERSITY_PARAM_MIN ( 0 ) +#define CFG_ANTENNA_DIVERSITY_PARAM_MAX ( 3 ) +#define CFG_ANTENNA_DIVERSITY_PARAM_DEFAULT ( 0 ) + +#define CFG_ENABLE_SNR_MONITORING_NAME "gEnableSNRMonitoring" +#define CFG_ENABLE_SNR_MONITORING_MIN ( 0 ) +#define CFG_ENABLE_SNR_MONITORING_MAX ( 1 ) +#define CFG_ENABLE_SNR_MONITORING_DEFAULT ( 0 ) +//Macro to enable/disable dynamic timer +#define CFG_DYNAMIC_SPLIT_SCAN_NAME "gEnableDynSplitScan" +#define CFG_DYNAMIC_SPLIT_SCAN_MIN ( 0 ) +#define CFG_DYNAMIC_SPLIT_SCAN_MAX ( 1 ) +#define CFG_DYNAMIC_SPLIT_SCAN_DEFAULT ( 1 ) + +//Macro to monitor the packet count +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_NAME "gSplitScanTxRxThreshold" +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MIN ( 10 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MAX ( 100 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_DEFAULT ( 50 ) + +//Macro to handle the monitor timer value in milliseconds +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_NAME "gSplitScanTxRxTimer" +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MIN ( 1000 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MAX ( 10000 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_DEFAULT ( 5000 ) + +#ifdef FEATURE_WLAN_SCAN_PNO +#define CFG_PNO_SCAN_SUPPORT "gPNOScanSupport" +#define CFG_PNO_SCAN_SUPPORT_ENABLE ( 1 ) +#define CFG_PNO_SCAN_SUPPORT_DISABLE ( 0 ) +#define CFG_PNO_SCAN_SUPPORT_DEFAULT ( 1 ) + +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE "gPNOScanTimerRepeatValue" +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT ( 6 ) +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN ( 0 ) +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX ( 0xffffffff ) +#endif + +#define CFG_AMSDU_SUPPORT_IN_AMPDU_NAME "gAmsduSupportInAMPDU" +#define CFG_AMSDU_SUPPORT_IN_AMPDU_MIN (0) +#define CFG_AMSDU_SUPPORT_IN_AMPDU_MAX (1) +#define CFG_AMSDU_SUPPORT_IN_AMPDU_DEFAULT (0) //disabled + +/* Prefer connecting to 5G AP even if its RSSI is lower by + gSelect5GHzMargin dBm than 2.4G AP. +This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN "gSelect5GHzMargin" +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_MIN (0) +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_MAX (60) +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_DEFAULT (0) //set 0 to disable + +#define CFG_ENABLE_TCP_CHKSUM_OFFLOAD "gEnableTCPChkSumOffld" +#define CFG_ENABLE_TCP_CHKSUM_OFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_TCP_CHKSUM_OFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_TCP_CHKSUM_OFFLOAD_DEFAULT ( 0 ) + +#define CFG_ENABLE_IP_CHKSUM_OFFLOAD "gEnableIPChecksumOffload" +#define CFG_ENABLE_IP_CHKSUM_OFFLOAD_DISABLE ( 0 ) +#define CFG_ENABLE_IP_CHKSUM_OFFLOAD_ENABLE ( 1 ) +#define CFG_ENABLE_IP_CHKSUM_OFFLOAD_DEFAULT ( CFG_ENABLE_IP_CHKSUM_OFFLOAD_DISABLE ) + +/* + * Power Save Offload + */ +#define CFG_POWERSAVE_OFFLOAD_NAME "gEnablePowerSaveOffload" +#define CFG_POWERSAVE_OFFLOAD_MIN ( 0 ) +#define CFG_POWERSAVE_OFFLOAD_MAX ( 4 ) +#define CFG_POWERSAVE_OFFLOAD_DEFAULT ( CFG_POWERSAVE_OFFLOAD_MIN ) + +#ifdef IPA_OFFLOAD +/* + * IPA Offload configuration - Each bit enables a feature + * bit0 - IPA Enable + * bit1 - IPA Pre filter enable + * bit2 - IPv6 enable + * bit3 - IPA Resource Manager (RM) enable + * bit4 - IPA Clock scaling enable + */ +#define CFG_IPA_OFFLOAD_CONFIG_NAME "gIPAConfig" +#define CFG_IPA_OFFLOAD_CONFIG_MIN ( 0 ) +#define CFG_IPA_OFFLOAD_CONFIG_MAX ( 0xFFFFFFFF ) +#define CFG_IPA_OFFLOAD_CONFIG_DEFAULT ( CFG_IPA_OFFLOAD_CONFIG_MIN ) + +/* + * IPA DESC SIZE + */ +#define CFG_IPA_DESC_SIZE_NAME "gIPADescSize" +#define CFG_IPA_DESC_SIZE_MIN ( 800 ) +#define CFG_IPA_DESC_SIZE_MAX ( 8000 ) +#define CFG_IPA_DESC_SIZE_DEFAULT ( 800 ) + +#define CFG_IPA_HIGH_BANDWIDTH_MBPS "gIPAHighBandwidthMbps" +#define CFG_IPA_HIGH_BANDWIDTH_MBPS_MIN ( 200 ) +#define CFG_IPA_HIGH_BANDWIDTH_MBPS_MAX ( 1000 ) +#define CFG_IPA_HIGH_BANDWIDTH_MBPS_DEFAULT ( 400 ) + +#define CFG_IPA_MEDIUM_BANDWIDTH_MBPS "gIPAMediumBandwidthMbps" +#define CFG_IPA_MEDIUM_BANDWIDTH_MBPS_MIN ( 100 ) +#define CFG_IPA_MEDIUM_BANDWIDTH_MBPS_MAX ( 400 ) +#define CFG_IPA_MEDIUM_BANDWIDTH_MBPS_DEFAULT ( 200 ) + +#define CFG_IPA_LOW_BANDWIDTH_MBPS "gIPALowBandwidthMbps" +#define CFG_IPA_LOW_BANDWIDTH_MBPS_MIN ( 0 ) +#define CFG_IPA_LOW_BANDWIDTH_MBPS_MAX ( 100 ) +#define CFG_IPA_LOW_BANDWIDTH_MBPS_DEFAULT ( 100 ) +#endif + +/* + * P2P Listen Offload + */ +#define CFG_P2P_LISTEN_OFFLOAD_NAME "gEnableP2pListenOffload" +#define CFG_P2P_LISTEN_OFFLOAD_DISABLE ( 0 ) +#define CFG_P2P_LISTEN_OFFLOAD_ENABLE ( 1 ) +#define CFG_P2P_LISTEN_OFFLOAD_DEFAULT ( CFG_P2P_LISTEN_OFFLOAD_DISABLE ) + +/* + * Firmware uart print + */ +#define CFG_ENABLE_FW_UART_PRINT_NAME "gEnablefwprint" +#define CFG_ENABLE_FW_UART_PRINT_DISABLE ( 0 ) +#define CFG_ENABLE_FW_UART_PRINT_ENABLE ( 1 ) +#define CFG_ENABLE_FW_UART_PRINT_DEFAULT ( CFG_ENABLE_FW_UART_PRINT_DISABLE ) + +/* + * Firmware log + */ +#define CFG_ENABLE_FW_LOG_NAME "gEnablefwlog" +#define CFG_ENABLE_FW_LOG_DISABLE ( 0 ) +#define CFG_ENABLE_FW_LOG_ENABLE ( 1 ) +#define CFG_ENABLE_FW_LOG_DEFAULT ( CFG_ENABLE_FW_LOG_DISABLE ) + +/* + * Enable/Disable SSR for USB + */ +#define CFG_ENABLE_FW_SELF_RECOVERY_NAME "gEnableFwSelfRecovery" +#define CFG_ENABLE_FW_SELF_RECOVERY_DISABLE ( 0 ) +#define CFG_ENABLE_FW_SELF_RECOVERY_ENABLE ( 1 ) +#define CFG_ENABLE_FW_SELF_RECOVERY_DEFAULT ( CFG_ENABLE_FW_SELF_RECOVERY_DISABLE ) + +#ifdef WLAN_FEATURE_11AC +//Macro to handle maximum receive AMPDU size configuration +#define CFG_VHT_AMPDU_LEN_EXPONENT_NAME "gVhtAmpduLenExponent" +#define CFG_VHT_AMPDU_LEN_EXPONENT_MIN ( 0 ) +#define CFG_VHT_AMPDU_LEN_EXPONENT_MAX ( 7 ) +#define CFG_VHT_AMPDU_LEN_EXPONENT_DEFAULT ( 3 ) + +#define CFG_VHT_MPDU_LEN_NAME "gVhtMpduLen" +#define CFG_VHT_MPDU_LEN_MIN ( 0 ) +#define CFG_VHT_MPDU_LEN_MAX ( 2 ) +#define CFG_VHT_MPDU_LEN_DEFAULT ( 0 ) +#endif + +#define CFG_MAX_WOW_FILTERS_NAME "gMaxWoWFilters" +#define CFG_MAX_WOW_FILTERS_MIN ( 0 ) +#define CFG_MAX_WOW_FILTERS_MAX ( 22 ) +#define CFG_MAX_WOW_FILTERS_DEFAULT ( 22 ) + +/* + * WOW Enable/Disable. + * 0 - Disable both magic pattern match and pattern byte match. + * 1 - Enable magic pattern match on all interfaces. + * 2 - Enable pattern byte match on all interfaces. + * 3 - Enable both magic patter and pattern byte match on all interfaces. + */ +#define CFG_WOW_STATUS_NAME "gEnableWoW" +#define CFG_WOW_ENABLE_MIN ( 0 ) +#define CFG_WOW_ENABLE_MAX ( 3 ) +#define CFG_WOW_STATUS_DEFAULT ( 3 ) + +#define CFG_COALESING_IN_IBSS_NAME "gCoalesingInIBSS" +#define CFG_COALESING_IN_IBSS_MIN (0) +#define CFG_COALESING_IN_IBSS_MAX (1) +#define CFG_COALESING_IN_IBSS_DEFAULT (0) //disabled + +#define CFG_IBSS_ATIM_WIN_SIZE_NAME "gIbssATIMWinSize" +#define CFG_IBSS_ATIM_WIN_SIZE_MIN (0) +#define CFG_IBSS_ATIM_WIN_SIZE_MAX (50) +#define CFG_IBSS_ATIM_WIN_SIZE_DEFAULT (0) + +/* + * Indicates if IBSS Power Save is + * supported or not. When not allowed, + * IBSS station has to stay awake all + * the time and should never set PM=1 + * in its transmitted frames. This + * parameter is meaningful/valid only + * when gIbssATIMWinSize is non-zero + */ +#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_NAME "gIbssIsPowerSaveAllowed" +#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_MIN (0) +#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_MAX (1) +#define CFG_IBSS_IS_POWER_SAVE_ALLOWED_DEFAULT (1) + +/* + * Indicates if IBSS Power Collapse + * is allowed or not. + */ +#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_NAME "gIbssIsPowerCollapseAllowed" +#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MIN (0) +#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MAX (1) +#define CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_DEFAULT (1) + +/* + * This parameter indicates whether IBSS station + * can exit power save mode and enter power active + * state whenever there is a TX/RX activity. + */ +#define CFG_IBSS_AWAKE_ON_TX_RX_NAME "gIbssAwakeOnTxRx" +#define CFG_IBSS_AWAKE_ON_TX_RX_MIN (0) +#define CFG_IBSS_AWAKE_ON_TX_RX_MAX (1) +#define CFG_IBSS_AWAKE_ON_TX_RX_DEFAULT (0) + +/* + * In IBSS mode if Awake on TX/RX activity is enabled + * Ibss Inactivity parameter indicates the data + * inactivity time in number of beacon intervals + * after which IBSS station re-inters power save + * by sending Null frame with PM=1 + */ +#define CFG_IBSS_INACTIVITY_TIME_NAME "gIbssInactivityTime" +#define CFG_IBSS_INACTIVITY_TIME_MIN (1) +#define CFG_IBSS_INACTIVITY_TIME_MAX (10) +#define CFG_IBSS_INACTIVITY_TIME_DEFAULT (1) + +/* + * In IBSS mode Tx Service Period Inactivity + * time in msecs indicates the time after + * which TX Service Period is terminated by + * sending a Qos Null frame with EOSP. + * If value is 0, TX SP is terminated with the + * last buffered packet itself instead of waiting + * for the inactivity + */ +#define CFG_IBSS_TXSP_END_INACTIVITY_NAME "gIbssTxSpEndInactivityTime" +#define CFG_IBSS_TXSP_END_INACTIVITY_MIN (0) +#define CFG_IBSS_TXSP_END_INACTIVITY_MAX (100) +#define CFG_IBSS_TXSP_END_INACTIVITY_DEFAULT (0) + +/* + * When IBSS network is initialized, PS-supporting device + * does not enter protocol sleep state during first + * gIbssPsWarmupTime seconds. + */ +#define CFG_IBSS_PS_WARMUP_TIME_NAME "gIbssPsWarmupTime" +#define CFG_IBSS_PS_WARMUP_TIME_MIN (0) +/* Allow unsigned Int Max for now */ +#define CFG_IBSS_PS_WARMUP_TIME_MAX (65535) +#define CFG_IBSS_PS_WARMUP_TIME_DEFAULT (0) + +/* + * IBSS Power Save Enable/Disable 1 RX + * chain usage during the ATIM window + */ +#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_NAME "gIbssPs1RxChainInAtim" +#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MIN (0) +#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MAX (1) +#define CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_DEFAULT (0) + +#define CFG_SAP_MAX_NO_PEERS "gSoftApMaxPeers" +#define CFG_SAP_MAX_NO_PEERS_MIN (1) +#define CFG_SAP_MAX_NO_PEERS_MAX (32) +#define CFG_SAP_MAX_NO_PEERS_DEFAULT (32) + +/* + * Connection related log Enable/Disable. + * 0x1 - Enable mgmt pkt logs (no probe req/rsp). + * 0x2 - Enable EAPOL pkt logs. + * 0x4 - Enable DHCP pkt logs. + * 0x0 - Disable all the above connection related logs. + */ +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE "gEnableDebugLog" +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN (0) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0) + +/* This will be used only for debugging purpose, will be removed after sometime */ +#define CFG_ENABLE_RX_THREAD "gEnableRxThread" +#define CFG_ENABLE_RX_THREAD_MIN (0) +#define CFG_ENABLE_RX_THREAD_MAX (1) +#define CFG_ENABLE_RX_THREAD_DEFAULT (1) + +/* SAR Thermal limit values for 2g and 5g */ + +#define CFG_SET_TXPOWER_LIMIT2G_NAME "TxPower2g" +#define CFG_SET_TXPOWER_LIMIT2G_MIN ( 0 ) +#define CFG_SET_TXPOWER_LIMIT2G_MAX ( 30 ) +#define CFG_SET_TXPOWER_LIMIT2G_DEFAULT ( 15 ) + +#define CFG_SET_TXPOWER_LIMIT5G_NAME "TxPower5g" +#define CFG_SET_TXPOWER_LIMIT5G_MIN ( 0 ) +#define CFG_SET_TXPOWER_LIMIT5G_MAX ( 30 ) +#define CFG_SET_TXPOWER_LIMIT5G_DEFAULT ( 15 ) + +#ifdef QCA_LL_TX_FLOW_CT +/* Default, single interface case flow control parameters */ +#define CFG_LL_TX_FLOW_LWM "TxFlowLowWaterMark" +#define CFG_LL_TX_FLOW_LWM_MIN ( 0 ) +#define CFG_LL_TX_FLOW_LWM_MAX ( 1000 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_FLOW_LWM_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_FLOW_LWM_DEFAULT ( 300 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_FLOW_HWM_OFFSET "TxFlowHighWaterMarkOffset" +#define CFG_LL_TX_FLOW_HWM_OFFSET_MIN ( 0 ) +#define CFG_LL_TX_FLOW_HWM_OFFSET_MAX ( 300 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_FLOW_HWM_OFFSET_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_FLOW_HWM_OFFSET_DEFAULT ( 94 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_FLOW_MAX_Q_DEPTH "TxFlowMaxQueueDepth" +#define CFG_LL_TX_FLOW_MAX_Q_DEPTH_MIN ( 400 ) +#define CFG_LL_TX_FLOW_MAX_Q_DEPTH_MAX ( 3500 ) +#define CFG_LL_TX_FLOW_MAX_Q_DEPTH_DEFAULT ( 1500 ) + +#define CFG_LL_TX_LBW_FLOW_LWM "TxLbwFlowLowWaterMark" +#define CFG_LL_TX_LBW_FLOW_LWM_MIN ( 0 ) +#define CFG_LL_TX_LBW_FLOW_LWM_MAX ( 1000 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_LBW_FLOW_LWM_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_LBW_FLOW_LWM_DEFAULT ( 450 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_LBW_FLOW_HWM_OFFSET "TxLbwFlowHighWaterMarkOffset" +#define CFG_LL_TX_LBW_FLOW_HWM_OFFSET_MIN ( 0 ) +#define CFG_LL_TX_LBW_FLOW_HWM_OFFSET_MAX ( 300 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_LBW_FLOW_HWM_OFFSET_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_LBW_FLOW_HWM_OFFSET_DEFAULT ( 50 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH "TxLbwFlowMaxQueueDepth" +#define CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_MIN ( 400 ) +#define CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_MAX ( 3500 ) +#define CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_DEFAULT ( 750 ) + +#define CFG_LL_TX_HBW_FLOW_LWM "TxHbwFlowLowWaterMark" +#define CFG_LL_TX_HBW_FLOW_LWM_MIN ( 0 ) +#define CFG_LL_TX_HBW_FLOW_LWM_MAX ( 1000 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_HBW_FLOW_LWM_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_HBW_FLOW_LWM_DEFAULT ( 406 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_HBW_FLOW_HWM_OFFSET "TxHbwFlowHighWaterMarkOffset" +#define CFG_LL_TX_HBW_FLOW_HWM_OFFSET_MIN ( 0 ) +#define CFG_LL_TX_HBW_FLOW_HWM_OFFSET_MAX ( 300 ) +#if defined(CONFIG_HL_SUPPORT) +#define CFG_LL_TX_HBW_FLOW_HWM_OFFSET_DEFAULT ( 0 ) +#else +#define CFG_LL_TX_HBW_FLOW_HWM_OFFSET_DEFAULT ( 94 ) +#endif /* defined(CONFIG_HL_SUPPORT) */ + +#define CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH "TxHbwFlowMaxQueueDepth" +#define CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_MIN ( 400 ) +#define CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_MAX ( 3500 ) +#define CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_DEFAULT ( 1500 ) +#endif /* QCA_LL_TX_FLOW_CT */ + +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_NAME "gEnableStrictRegulatoryForFCC" +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MIN ( 0 ) +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MAX ( 1 ) +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_DEFAULT ( 0 ) + +#define CFG_SAP_MAX_OFFLOAD_PEERS "gMaxOffloadPeers" +#define CFG_SAP_MAX_OFFLOAD_PEERS_MIN (2) +#define CFG_SAP_MAX_OFFLOAD_PEERS_MAX (5) +#define CFG_SAP_MAX_OFFLOAD_PEERS_DEFAULT (2) + +#define CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS "gMaxOffloadReorderBuffs" +#define CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_MIN (0) +#define CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_MAX (3) +#define CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_DEFAULT (2) + +#ifdef FEATURE_WLAN_RA_FILTERING +#define CFG_RA_FILTER_ENABLE_NAME "gRAFilterEnable" +#define CFG_RA_FILTER_ENABLE_MIN (0) +#define CFG_RA_FILTER_ENABLE_MAX (1) +#define CFG_RA_FILTER_ENABLE_DEFAULT (0) + +#define CFG_RA_RATE_LIMIT_INTERVAL_NAME "gRArateLimitInterval" +#define CFG_RA_RATE_LIMIT_INTERVAL_MIN (60) +#define CFG_RA_RATE_LIMIT_INTERVAL_MAX (300) +#define CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT (60)/*60 SEC*/ +#endif + +#define CFG_INITIAL_DWELL_TIME_NAME "gInitialDwellTime" +#define CFG_INITIAL_DWELL_TIME_DEFAULT (0) +#define CFG_INITIAL_DWELL_TIME_MIN (0) +#define CFG_INITIAL_DWELL_TIME_MAX (100) + +#define CFG_INITIAL_SCAN_NO_DFS_CHNL_NAME "gInitialScanNoDFSChnl" +#define CFG_INITIAL_SCAN_NO_DFS_CHNL_DEFAULT (0) +#define CFG_INITIAL_SCAN_NO_DFS_CHNL_MIN (0) +#define CFG_INITIAL_SCAN_NO_DFS_CHNL_MAX (1) + +#define CFG_OVERRIDE_COUNTRY_CODE "gStaCountryCode" +#define CFG_OVERRIDE_COUNTRY_CODE_DEFAULT "000" + +#define CFG_ROAMING_DFS_CHANNEL_NAME "gAllowDFSChannelRoam" +#define CFG_ROAMING_DFS_CHANNEL_DISABLED (0) +#define CFG_ROAMING_DFS_CHANNEL_ENABLED_NORMAL (1) +#define CFG_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE (2) +#define CFG_ROAMING_DFS_CHANNEL_MIN (CFG_ROAMING_DFS_CHANNEL_DISABLED) +#define CFG_ROAMING_DFS_CHANNEL_MAX (CFG_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE) +#define CFG_ROAMING_DFS_CHANNEL_DEFAULT (CFG_ROAMING_DFS_CHANNEL_DISABLED) + +#ifdef MSM_PLATFORM +#define CFG_BUS_BANDWIDTH_HIGH_THRESHOLD "gBusBandwidthHighThreshold" +#define CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_DEFAULT ( 2000 ) +#define CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_MIN ( 0 ) +#define CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_MAX ( 4294967295UL ) + +#define CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD "gBusBandwidthMediumThreshold" +#define CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_DEFAULT ( 500 ) +#define CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_MIN ( 0 ) +#define CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_MAX ( 4294967295UL ) + +#define CFG_BUS_BANDWIDTH_LOW_THRESHOLD "gBusBandwidthLowThreshold" +#define CFG_BUS_BANDWIDTH_LOW_THRESHOLD_DEFAULT ( 150 ) +#define CFG_BUS_BANDWIDTH_LOW_THRESHOLD_MIN ( 0 ) +#define CFG_BUS_BANDWIDTH_LOW_THRESHOLD_MAX ( 4294967295UL ) + +#define CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL "gBusBandwidthComputeInterval" +#define CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_DEFAULT ( 100 ) +#define CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_MIN ( 0 ) +#define CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_MAX ( 10000 ) + +#define CFG_TCP_DELACK_THRESHOLD_HIGH "gTcpDelAckThresholdHigh" +#define CFG_TCP_DELACK_THRESHOLD_HIGH_DEFAULT ( 500 ) +#define CFG_TCP_DELACK_THRESHOLD_HIGH_MIN ( 0 ) +#define CFG_TCP_DELACK_THRESHOLD_HIGH_MAX ( 16000 ) + +#define CFG_TCP_DELACK_THRESHOLD_LOW "gTcpDelAckThresholdLow" +#define CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT ( 1000 ) +#define CFG_TCP_DELACK_THRESHOLD_LOW_MIN ( 0 ) +#define CFG_TCP_DELACK_THRESHOLD_LOW_MAX ( 10000 ) +#endif /* MSM_PLATFORM */ + +#ifdef WLAN_FEATURE_11W +#define CFG_PMF_SA_QUERY_MAX_RETRIES_NAME "pmfSaQueryMaxRetries" +#define CFG_PMF_SA_QUERY_MAX_RETRIES_DEFAULT ( 5 ) +#define CFG_PMF_SA_QUERY_MAX_RETRIES_MIN ( 0 ) +#define CFG_PMF_SA_QUERY_MAX_RETRIES_MAX ( 20 ) + +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_NAME "pmfSaQueryRetryInterval" +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_DEFAULT ( 200 ) +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_MIN ( 0 ) +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_MAX ( 2000 ) +#endif + +#define CFG_MAX_CONCURRENT_CONNECTIONS_NAME "gMaxConcurrentActiveSessions" +#define CFG_MAX_CONCURRENT_CONNECTIONS_DEFAULT ( 2 ) +#define CFG_MAX_CONCURRENT_CONNECTIONS_MIN ( 1 ) +#define CFG_MAX_CONCURRENT_CONNECTIONS_MAX ( 4 ) + +#ifdef QCA_HT_2040_COEX +#define CFG_ENABLE_HT_2040_COEX "gHT2040CoexEnabled" +#define CFG_ENABLE_HT_2040_COEX_MIN ( 0 ) +#define CFG_ENABLE_HT_2040_COEX_MAX ( 1 ) +#define CFG_ENABLE_HT_2040_COEX_DEFAULT ( 0 ) +#endif + +#define CFG_IGNORE_CAC_NAME "gIgnoreCAC" +#define CFG_IGNORE_CAC_MIN ( 0 ) +#define CFG_IGNORE_CAC_MAX ( 1 ) +#define CFG_IGNORE_CAC_DEFAULT ( 0 ) + +#define CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_NAME "gEnableSAPDfsChSifsBurst" +#define CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_MIN ( 0 ) +#define CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_MAX ( 1 ) +#define CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_DEFAULT ( 1 ) + +#define CFG_DFS_RADAR_PRI_MULTIPLIER_NAME "gDFSradarMappingPriMultiplier" +#define CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT ( 4 ) +#define CFG_DFS_RADAR_PRI_MULTIPLIER_MIN ( 0 ) +#define CFG_DFS_RADAR_PRI_MULTIPLIER_MAX ( 10 ) +#define CFG_REORDER_OFFLOAD_SUPPORT_NAME "gReorderOffloadSupported" +#define CFG_REORDER_OFFLOAD_SUPPORT_MIN ( 0 ) +#define CFG_REORDER_OFFLOAD_SUPPORT_MAX ( 1 ) +#define CFG_REORDER_OFFLOAD_SUPPORT_DEFAULT ( 0 ) + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define CFG_ROAMING_OFFLOAD_NAME "gRoamOffloadEnabled" +#define CFG_ROAMING_OFFLOAD_MIN (0) +#define CFG_ROAMING_OFFLOAD_MAX (1) +#define CFG_ROAMING_OFFLOAD_DEFAULT (0) +#endif +#ifdef IPA_UC_OFFLOAD +#define CFG_IPA_UC_OFFLOAD_ENABLED_NAME "IpaUcOffloadEnabled" +#define CFG_IPA_UC_OFFLOAD_ENABLED_MIN ( 0 ) +#define CFG_IPA_UC_OFFLOAD_ENABLED_MAX ( 1 ) +#define CFG_IPA_UC_OFFLOAD_ENABLED_DEFAULT ( 0 ) + +#define CFG_IPA_UC_TX_BUF_COUNT_NAME "IpaUcTxBufCount" +#define CFG_IPA_UC_TX_BUF_COUNT_MIN ( 0 ) +#define CFG_IPA_UC_TX_BUF_COUNT_MAX ( 2048 ) +#define CFG_IPA_UC_TX_BUF_COUNT_DEFAULT ( 512 ) + +#define CFG_IPA_UC_TX_BUF_SIZE_NAME "IpaUcTxBufSize" +#define CFG_IPA_UC_TX_BUF_SIZE_MIN ( 0 ) +#define CFG_IPA_UC_TX_BUF_SIZE_MAX ( 4096 ) +#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT ( 2048 ) + +#define CFG_IPA_UC_RX_IND_RING_COUNT_NAME "IpaUcRxIndRingCount" +#define CFG_IPA_UC_RX_IND_RING_COUNT_MIN ( 0 ) +#define CFG_IPA_UC_RX_IND_RING_COUNT_MAX ( 2048 ) +#define CFG_IPA_UC_RX_IND_RING_COUNT_DEFAULT ( 1024 ) + +#define CFG_IPA_UC_TX_PARTITION_BASE_NAME "IpaUcTxPartitionBase" +#define CFG_IPA_UC_TX_PARTITION_BASE_MIN ( 0 ) +#define CFG_IPA_UC_TX_PARTITION_BASE_MAX ( 9000 ) +#define CFG_IPA_UC_TX_PARTITION_BASE_DEFAULT ( 3000 ) +#endif /* IPA_UC_OFFLOAD */ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +/* Enable WLAN Logging to app space */ +#define CFG_WLAN_LOGGING_SUPPORT_NAME "wlanLoggingEnable" +#define CFG_WLAN_LOGGING_SUPPORT_ENABLE ( 1 ) +#define CFG_WLAN_LOGGING_SUPPORT_DISABLE ( 0 ) +#define CFG_WLAN_LOGGING_SUPPORT_DEFAULT ( 1 ) + +/* Enable FATAL and ERROR logs for kmsg console */ +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_NAME "wlanLoggingFEToConsole" +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_ENABLE ( 1 ) +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DISABLE ( 0 ) +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT ( 0 ) + +/* Number of buffers to be used for WLAN logging */ +#define CFG_WLAN_LOGGING_NUM_BUF_NAME "wlanLoggingNumBuf" +#define CFG_WLAN_LOGGING_NUM_BUF_MIN ( 4 ) +#define CFG_WLAN_LOGGING_NUM_BUF_MAX ( 64 ) +#define CFG_WLAN_LOGGING_NUM_BUF_DEFAULT ( 32 ) +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ + +#define CFG_ENABLE_SIFS_BURST "gEnableSifsBurst" +#define CFG_ENABLE_SIFS_BURST_MIN ( 0 ) +#define CFG_ENABLE_SIFS_BURST_MAX ( 1 ) +#define CFG_ENABLE_SIFS_BURST_DEFAULT ( 0 ) + +#ifdef WLAN_FEATURE_LPSS +#define CFG_ENABLE_LPASS_SUPPORT "gEnableLpassSupport" +#define CFG_ENABLE_LPASS_SUPPORT_DEFAULT ( 0 ) +#define CFG_ENABLE_LPASS_SUPPORT_MIN ( 0 ) +#define CFG_ENABLE_LPASS_SUPPORT_MAX ( 1 ) +#endif + +#define CFG_ENABLE_SELF_RECOVERY "gEnableSelfRecovery" +#define CFG_ENABLE_SELF_RECOVERY_MIN ( 0 ) +#define CFG_ENABLE_SELF_RECOVERY_MAX ( 1 ) +#define CFG_ENABLE_SELF_RECOVERY_DEFAULT ( 0 ) + +#define CFG_ENABLE_SAP_SUSPEND "gEnableSapSuspend" +#define CFG_ENABLE_SAP_SUSPEND_MIN ( 0 ) +#define CFG_ENABLE_SAP_SUSPEND_MAX ( 1 ) +#define CFG_ENABLE_SAP_SUSPEND_DEFAULT ( 1 ) + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +#define CFG_EXTWOW_GO_TO_SUSPEND "gExtWoWgotoSuspend" +#define CFG_EXTWOW_GO_TO_SUSPEND_MIN ( 0 ) +#define CFG_EXTWOW_GO_TO_SUSPEND_MAX ( 1 ) +#define CFG_EXTWOW_GO_TO_SUSPEND_DEFAULT ( 1 ) + +#define CFG_EXTWOW_APP1_WAKE_PIN_NUMBER "gExtWowApp1WakeupPinNumber" +#define CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_MIN ( 0 ) +#define CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_MAX ( 255 ) +#define CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_DEFAULT ( 12 ) + +#define CFG_EXTWOW_APP2_WAKE_PIN_NUMBER "gExtWowApp2WakeupPinNumber" +#define CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_MIN ( 0 ) +#define CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_MAX ( 255 ) +#define CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_DEFAULT ( 16 ) + +#define CFG_EXTWOW_KA_INIT_PING_INTERVAL "gExtWoWApp2KAInitPingInterval" +#define CFG_EXTWOW_KA_INIT_PING_INTERVAL_MIN ( 0 ) +#define CFG_EXTWOW_KA_INIT_PING_INTERVAL_MAX ( 0xffffffff ) +#define CFG_EXTWOW_KA_INIT_PING_INTERVAL_DEFAULT ( 240 ) + +#define CFG_EXTWOW_KA_MIN_PING_INTERVAL "gExtWoWApp2KAMinPingInterval" +#define CFG_EXTWOW_KA_MIN_PING_INTERVAL_MIN ( 0 ) +#define CFG_EXTWOW_KA_MIN_PING_INTERVAL_MAX ( 0xffffffff ) +#define CFG_EXTWOW_KA_MIN_PING_INTERVAL_DEFAULT ( 240 ) + +#define CFG_EXTWOW_KA_MAX_PING_INTERVAL "gExtWoWApp2KAMaxPingInterval" +#define CFG_EXTWOW_KA_MAX_PING_INTERVAL_MIN ( 0 ) +#define CFG_EXTWOW_KA_MAX_PING_INTERVAL_MAX ( 0xffffffff ) +#define CFG_EXTWOW_KA_MAX_PING_INTERVAL_DEFAULT ( 1280 ) + +#define CFG_EXTWOW_KA_INC_PING_INTERVAL "gExtWoWApp2KAIncPingInterval" +#define CFG_EXTWOW_KA_INC_PING_INTERVAL_MIN ( 0 ) +#define CFG_EXTWOW_KA_INC_PING_INTERVAL_MAX ( 0xffffffff ) +#define CFG_EXTWOW_KA_INC_PING_INTERVAL_DEFAULT ( 4 ) + +#define CFG_EXTWOW_TCP_SRC_PORT "gExtWoWApp2TcpSrcPort" +#define CFG_EXTWOW_TCP_SRC_PORT_MIN ( 0 ) +#define CFG_EXTWOW_TCP_SRC_PORT_MAX ( 65535 ) +#define CFG_EXTWOW_TCP_SRC_PORT_DEFAULT ( 5000 ) + +#define CFG_EXTWOW_TCP_DST_PORT "gExtWoWApp2TcpDstPort" +#define CFG_EXTWOW_TCP_DST_PORT_MIN ( 0 ) +#define CFG_EXTWOW_TCP_DST_PORT_MAX ( 65535 ) +#define CFG_EXTWOW_TCP_DST_PORT_DEFAULT ( 5001 ) + +#define CFG_EXTWOW_TCP_TX_TIMEOUT "gExtWoWApp2TcpTxTimeout" +#define CFG_EXTWOW_TCP_TX_TIMEOUT_MIN ( 0 ) +#define CFG_EXTWOW_TCP_TX_TIMEOUT_MAX ( 0xffffffff ) +#define CFG_EXTWOW_TCP_TX_TIMEOUT_DEFAULT ( 200 ) + +#define CFG_EXTWOW_TCP_RX_TIMEOUT "gExtWoWApp2TcpRxTimeout" +#define CFG_EXTWOW_TCP_RX_TIMEOUT_MIN ( 0 ) +#define CFG_EXTWOW_TCP_RX_TIMEOUT_MAX ( 0xffffffff ) +#define CFG_EXTWOW_TCP_RX_TIMEOUT_DEFAULT ( 200 ) +#endif + +#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_NAME "gEnableDeauthToDisassocMap" +#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MIN ( 0 ) +#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MAX ( 1 ) +#define CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_DEFAULT ( 0 ) + +#define CFG_ENABLE_MAC_ADDR_SPOOFING "gEnableMacAddrSpoof" +#define CFG_ENABLE_MAC_ADDR_SPOOFING_MIN (0) +#define CFG_ENABLE_MAC_ADDR_SPOOFING_MAX (1) +#define CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT (1) + +#define CFG_SAP_DOT11MC "gSapDot11mc" +#define CFG_SAP_DOT11MC_MIN (0) +#define CFG_SAP_DOT11MC_MAX (1) +#define CFG_SAP_DOT11MC_DEFAULT (0) + +/* Option to report rssi in cfg80211_inform_bss_frame() + * 0 = use rssi value based on noise floor = -96 dBm + * 1 = use rssi value based on actual noise floor in hardware + */ +#define CFG_INFORM_BSS_RSSI_RAW_NAME "gInformBssRssiRaw" +#define CFG_INFORM_BSS_RSSI_RAW_MIN (0) +#define CFG_INFORM_BSS_RSSI_RAW_MAX (1) +#define CFG_INFORM_BSS_RSSI_RAW_DEFAULT (1) + +#define CFG_P2P_LISTEN_DEFER_INTERVAL_NAME "gP2PListenDeferInterval" +#define CFG_P2P_LISTEN_DEFER_INTERVAL_MIN (100) +#define CFG_P2P_LISTEN_DEFER_INTERVAL_MAX (200) +#define CFG_P2P_LISTEN_DEFER_INTERVAL_DEFAULT (100) + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +typedef struct +{ + //Bitmap to track what is explicitly configured + DECLARE_BITMAP(bExplicitCfg, MAX_CFG_INI_ITEMS); + + //Config parameters + v_U32_t RTSThreshold; + v_U32_t FragmentationThreshold; + v_U32_t nCheckForHangTime; + v_U32_t Calibration; + v_U32_t CalibrationPeriod; + v_U8_t OperatingChannel; + v_BOOL_t ShortSlotTimeEnabled; + v_BOOL_t Is11dSupportEnabled; + v_BOOL_t Is11hSupportEnabled; + v_BOOL_t fEnforce11dChannels; + v_BOOL_t fSupplicantCountryCodeHasPriority; + v_BOOL_t fEnforceCountryCodeMatch; + v_BOOL_t fEnforceDefaultDomain; + v_U32_t HeartbeatThresh24; + char PowerUsageControl[4]; + v_U8_t nEnableSuspend; + v_U8_t nEnableDriverStop; + v_BOOL_t fIsImpsEnabled; + v_BOOL_t fIsLogpEnabled; + v_U8_t btcExecutionMode; + v_U8_t btcConsBtSlotsToBlockDuringDhcp; + v_U8_t btcA2DPBtSubIntervalsDuringDhcp; + v_U32_t btcStaticLenInqBt; + v_U32_t btcStaticLenPageBt; + v_U32_t btcStaticLenConnBt; + v_U32_t btcStaticLenLeBt; + v_U32_t btcStaticLenInqWlan; + v_U32_t btcStaticLenPageWlan; + v_U32_t btcStaticLenConnWlan; + v_U32_t btcStaticLenLeWlan; + v_U32_t btcDynMaxLenBt; + v_U32_t btcDynMaxLenWlan; + v_U32_t btcMaxScoBlockPerc; + v_U32_t btcDhcpProtOnA2dp; + v_U32_t btcDhcpProtOnSco; + v_U32_t mwsCoexVictimWANFreq[10]; + v_U32_t mwsCoexVictimWLANFreq[10]; + v_U32_t mwsCoexVictimConfig[10]; + v_U32_t mwsCoexVictimConfig2[10]; + v_U32_t mwsCoexModemBackoff; + v_U32_t mwsCoexConfig[6]; + v_U32_t SARPowerBackoff; + v_U32_t nImpsModSleepTime; + v_U32_t nImpsMaxSleepTime; + v_U32_t nImpsMinSleepTime; + v_BOOL_t fIsBmpsEnabled; + v_U32_t nBmpsModListenInterval; + v_U32_t nBmpsMaxListenInterval; + v_U32_t nBmpsMinListenInterval; + v_BOOL_t fIsAutoBmpsTimerEnabled; + v_U32_t nAutoBmpsTimerValue; + eHddDot11Mode dot11Mode; + v_U32_t nChannelBondingMode24GHz; + v_U32_t nChannelBondingMode5GHz; + v_U32_t MaxRxAmpduFactor; + v_U32_t nBAAgingTimerInterval; + v_U16_t TxRate; + v_U32_t AdaptiveThresholdAlgo; + v_U32_t ShortGI20MhzEnable; + v_U32_t BlockAckAutoSetup; + v_U32_t ScanResultAgeCount; + v_U32_t nScanAgeTimeNCNPS; + v_U32_t nScanAgeTimeNCPS; + v_U32_t nScanAgeTimeCNPS; + v_U32_t nScanAgeTimeCPS; + v_U8_t nRssiCatGap; + v_BOOL_t fIsShortPreamble; + v_MACADDR_t IbssBssid; + v_U32_t AdHocChannel5G; + v_U32_t AdHocChannel24G; + v_U8_t intfAddrMask; + v_MACADDR_t intfMacAddr[VOS_MAX_CONCURRENCY_PERSONA]; + + v_BOOL_t apUapsdEnabled; + v_BOOL_t apRandomBssidEnabled; + v_BOOL_t apProtEnabled; + v_U16_t apProtection; + v_BOOL_t apOBSSProtEnabled; + v_U8_t MinFramesProcThres; + v_U8_t apCntryCode[4]; + v_BOOL_t apDisableIntraBssFwd; + v_U8_t nEnableListenMode; + v_U32_t nAPAutoShutOff; + v_U8_t apStartChannelNum; + v_U8_t apEndChannelNum; + v_U8_t apOperatingBand; + v_BOOL_t apAutoChannelSelection; + v_BOOL_t apForce11ACFor11n; + v_U8_t enableLTECoex; + v_U32_t apKeepAlivePeriod; + v_U32_t goKeepAlivePeriod; + v_U32_t apLinkMonitorPeriod; + v_U32_t goLinkMonitorPeriod; + v_U32_t nBeaconInterval; + v_U8_t nTxPowerCap; //In dBm + v_BOOL_t fIsLowGainOverride; + v_U8_t disablePacketFilter; +#if defined WLAN_FEATURE_VOWIFI + v_BOOL_t fRrmEnable; + v_U8_t nInChanMeasMaxDuration; + v_U8_t nOutChanMeasMaxDuration; + v_U16_t nRrmRandnIntvl; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + //Vowifi 11r params + v_BOOL_t fFTResourceReqSupported; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + v_U16_t nNeighborScanPeriod; + v_U8_t nNeighborReassocRssiThreshold; + v_U8_t nNeighborLookupRssiThreshold; + v_U8_t delay_before_vdev_stop; + v_U8_t nOpportunisticThresholdDiff; + v_U8_t nRoamRescanRssiDiff; + v_U8_t neighborScanChanList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + v_U16_t nNeighborScanMinChanTime; + v_U16_t nNeighborScanMaxChanTime; + v_U16_t nMaxNeighborReqTries; + v_U16_t nNeighborResultsRefreshPeriod; + v_U16_t nEmptyScanRefreshPeriod; + v_U8_t nRoamBmissFirstBcnt; + v_U8_t nRoamBmissFinalBcnt; + v_U8_t nRoamBeaconRssiWeight; +#endif + + //Additional Handoff params + v_BOOL_t nEnableIdleScan; + v_U32_t nRoamingTime; + v_U16_t nVccRssiTrigger; + v_U32_t nVccUlMacLossThreshold; + + v_U32_t nPassiveMinChnTime; //in units of milliseconds + v_U32_t nPassiveMaxChnTime; //in units of milliseconds + v_U32_t nActiveMinChnTime; //in units of milliseconds + v_U32_t nActiveMaxChnTime; //in units of milliseconds + + v_U32_t nInitialDwellTime; //in units of milliseconds + bool initial_scan_no_dfs_chnl; + + v_U32_t nActiveMinChnTimeBtc; //in units of milliseconds + v_U32_t nActiveMaxChnTimeBtc; //in units of milliseconds +#ifdef WLAN_AP_STA_CONCURRENCY + v_U32_t nPassiveMinChnTimeConc; //in units of milliseconds + v_U32_t nPassiveMaxChnTimeConc; //in units of milliseconds + v_U32_t nActiveMinChnTimeConc; //in units of milliseconds + v_U32_t nActiveMaxChnTimeConc; //in units of milliseconds + v_U32_t nRestTimeConc; //in units of milliseconds + v_U8_t nNumStaChanCombinedConc; //number of channels combined for + //STA in each split scan operation + v_U8_t nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + v_U8_t nMaxPsPoll; + + v_U8_t nRssiFilterPeriod; + v_BOOL_t fIgnoreDtim; + v_U8_t fMaxLIModulatedDTIM; + + v_U8_t nRxAnt; + v_U8_t fEnableFwHeartBeatMonitoring; + v_U8_t fEnableFwBeaconFiltering; + v_BOOL_t fEnableFwRssiMonitoring; + v_U8_t nDataInactivityTimeout; + v_U8_t nthBeaconFilter; + + //WMM QoS Configuration + hdd_wmm_user_mode_t WmmMode; + v_BOOL_t b80211eIsEnabled; + v_U8_t UapsdMask; // what ACs to setup U-APSD for at assoc + v_U32_t InfraUapsdVoSrvIntv; + v_U32_t InfraUapsdVoSuspIntv; + v_U32_t InfraUapsdViSrvIntv; + v_U32_t InfraUapsdViSuspIntv; + v_U32_t InfraUapsdBeSrvIntv; + v_U32_t InfraUapsdBeSuspIntv; + v_U32_t InfraUapsdBkSrvIntv; + v_U32_t InfraUapsdBkSuspIntv; +#ifdef FEATURE_WLAN_LFR + v_BOOL_t isFastRoamIniFeatureEnabled; + v_BOOL_t MAWCEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + v_U32_t InfraInactivityInterval; + v_BOOL_t isEseIniFeatureEnabled; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + v_BOOL_t isFastTransitionEnabled; + v_U8_t RoamRssiDiff; + v_U8_t nImmediateRoamRssiDiff; + v_BOOL_t isWESModeEnabled; +#endif +#ifdef FEATURE_WLAN_OKC + v_BOOL_t isOkcIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + v_BOOL_t isRoamOffloadScanEnabled; +#endif + hdd_wmm_classification_t PktClassificationBasis; // DSCP or 802.1Q + v_BOOL_t bImplicitQosEnabled; + + /* default TSPEC parameters for AC_VO */ + sme_QosWmmDirType InfraDirAcVo; + v_U16_t InfraNomMsduSizeAcVo; + v_U32_t InfraMeanDataRateAcVo; + v_U32_t InfraMinPhyRateAcVo; + v_U16_t InfraSbaAcVo; + + /* default TSPEC parameters for AC_VI */ + sme_QosWmmDirType InfraDirAcVi; + v_U16_t InfraNomMsduSizeAcVi; + v_U32_t InfraMeanDataRateAcVi; + v_U32_t InfraMinPhyRateAcVi; + v_U16_t InfraSbaAcVi; + + /* default TSPEC parameters for AC_BE */ + sme_QosWmmDirType InfraDirAcBe; + v_U16_t InfraNomMsduSizeAcBe; + v_U32_t InfraMeanDataRateAcBe; + v_U32_t InfraMinPhyRateAcBe; + v_U16_t InfraSbaAcBe; + + /* default TSPEC parameters for AC_BK */ + sme_QosWmmDirType InfraDirAcBk; + v_U16_t InfraNomMsduSizeAcBk; + v_U32_t InfraMeanDataRateAcBk; + v_U32_t InfraMinPhyRateAcBk; + v_U16_t InfraSbaAcBk; + + /* TL related configuration */ + v_U8_t WfqBkWeight; + v_U8_t WfqBeWeight; + v_U8_t WfqViWeight; + v_U8_t WfqVoWeight; + v_U32_t DelayedTriggerFrmInt; + v_U16_t BkReorderAgingTime; + v_U16_t BeReorderAgingTime; + v_U16_t ViReorderAgingTime; + v_U16_t VoReorderAgingTime; + + /* Wowl pattern */ + char wowlPattern[1024]; + + /* Control for Replay counter. value 1 means + single replay counter for all TID*/ + v_BOOL_t bSingleTidRc; + v_U8_t mcastBcastFilterSetting; + v_BOOL_t fhostArpOffload; + v_BOOL_t ssdp; +#ifdef FEATURE_WLAN_RA_FILTERING + v_BOOL_t IsRArateLimitEnabled; + v_U16_t RArateLimitInterval; +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + v_BOOL_t PnoOffload; +#endif + v_BOOL_t fhostNSOffload; + v_BOOL_t burstSizeDefinition; + v_U8_t tsInfoAckPolicy; + + /* RF Settling Time Clock */ + v_U32_t rfSettlingTimeUs; + v_U8_t enableBtAmp; +#ifdef WLAN_BTAMP_FEATURE + v_U8_t preferredChannel; +#endif //WLAN_BTAMP_FEATURE + + v_U8_t dynamicPsPollValue; + v_BOOL_t AddTSWhenACMIsOff; + v_BOOL_t fValidateScanList; + + v_U32_t infraStaKeepAlivePeriod; + v_U8_t nNullDataApRespTimeout; + v_U8_t nBandCapability; + + v_U32_t apDataAvailPollPeriodInMs; + v_BOOL_t fEnableBeaconEarlyTermination; + v_BOOL_t teleBcnWakeupEn; + +/* VOS Trace Control*/ + v_U16_t vosTraceEnableBAP; + v_U16_t vosTraceEnableTL; + v_U16_t vosTraceEnableWDI; + v_U16_t vosTraceEnableHDD; + v_U16_t vosTraceEnableSME; + v_U16_t vosTraceEnablePE; + v_U16_t vosTraceEnablePMC; + v_U16_t vosTraceEnableWDA; + v_U16_t vosTraceEnableSYS; + v_U16_t vosTraceEnableVOSS; + v_U16_t vosTraceEnableSAP; + v_U16_t vosTraceEnableHDDSAP; + + v_U16_t nTeleBcnTransListenInterval; + v_U16_t nTeleBcnMaxListenInterval; + v_U16_t nTeleBcnTransLiNumIdleBeacons; + v_U16_t nTeleBcnMaxLiNumIdleBeacons; + v_U8_t bcnEarlyTermWakeInterval; + v_U32_t enableCloseLoop; + v_U8_t enableBypass11d; + v_U8_t enableDFSChnlScan; + v_U8_t enableDynamicDTIM; + v_U8_t enableAutomaticTxPowerControl; + v_U8_t ShortGI40MhzEnable; + eHddLinkSpeedReportType reportMaxLinkSpeed; + v_S31_t linkSpeedRssiHigh; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + v_BOOL_t nRoamPrefer5GHz; + v_BOOL_t nRoamIntraBand; + v_U8_t nProbes; + v_U16_t nRoamScanHomeAwayTime; +#endif + v_S31_t linkSpeedRssiMid; + v_S31_t linkSpeedRssiLow; + v_U8_t enableMCC; + v_U8_t allowMCCGODiffBI; + v_BOOL_t isP2pDeviceAddrAdministrated; + v_U8_t thermalMitigationEnable; + v_U32_t throttlePeriod; +#ifdef WLAN_FEATURE_11AC + v_U8_t vhtChannelWidth; + v_U8_t vhtRxMCS; + v_U8_t vhtTxMCS; + v_BOOL_t enableTxBF; + v_U8_t txBFCsnValue; + v_U8_t vhtRxMCS2x2; + v_U8_t vhtTxMCS2x2; + v_BOOL_t enable2x2; + v_BOOL_t txchainmask1x1; + v_BOOL_t rxchainmask1x1; + v_BOOL_t enableMuBformee; + v_BOOL_t enableVhtpAid; + v_BOOL_t enableVhtGid; + v_BOOL_t enableTxBFin20MHz; +#endif + v_U8_t enableAmpduPs; + v_U8_t enableHtSmps; + v_U8_t htSmps; + v_U8_t enableModulatedDTIM; + v_U32_t fEnableMCAddrList; + v_BOOL_t enableFirstScan2GOnly; + v_BOOL_t skipDfsChnlInP2pSearch; + v_BOOL_t ignoreDynamicDtimInP2pMode; + v_U16_t configMccParam; + v_U32_t numBuffAdvert; + v_BOOL_t enableRxSTBC; + v_BOOL_t enableTxSTBC; + v_BOOL_t enableRxLDPC; + v_BOOL_t enable5gEBT; +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t fEnableTDLSSupport; + v_BOOL_t fEnableTDLSImplicitTrigger; + v_U32_t fTDLSTxStatsPeriod; + v_U32_t fTDLSTxPacketThreshold; + v_U32_t fTDLSDiscoveryPeriod; + v_U32_t fTDLSMaxDiscoveryAttempt; + v_U32_t fTDLSIdleTimeout; + v_U32_t fTDLSIdlePacketThreshold; + v_U32_t fTDLSRSSIHysteresis; + v_S31_t fTDLSRSSITriggerThreshold; + v_S31_t fTDLSRSSITeardownThreshold; + v_S31_t fTDLSRSSIDelta; + v_U32_t fTDLSUapsdMask; // what ACs to setup U-APSD for TDLS + v_U32_t fEnableTDLSBufferSta; + v_U32_t fEnableTDLSSleepSta; + v_U32_t fTDLSPuapsdInactivityTimer; + v_U32_t fTDLSRxFrameThreshold; + v_U32_t fTDLSPuapsdPTIWindow; + v_U32_t fTDLSPuapsdPTRTimeout; + v_BOOL_t fTDLSExternalControl; + v_U32_t fEnableTDLSOffChannel; + v_U32_t fEnableTDLSWmmMode; + v_U8_t fTDLSPrefOffChanNum; + v_U8_t fTDLSPrefOffChanBandwidth; + uint8_t enable_tdls_scan; +#endif +#ifdef WLAN_SOFTAP_VSTA_FEATURE + v_BOOL_t fEnableVSTASupport; +#endif +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + v_BOOL_t fEnableActiveModeOffload; +#endif + v_U32_t enableLpwrImgTransition; + v_U8_t scanAgingTimeout; + v_BOOL_t enableTxLdpc; + v_U8_t disableLDPCWithTxbfAP; + v_U8_t enableMCCAdaptiveScheduler; + v_BOOL_t isAndroidPsEn; + v_BOOL_t sapAllowAllChannel; + v_U8_t retryLimitZero; + v_U8_t retryLimitOne; + v_U8_t retryLimitTwo; + v_U8_t disableAggWithBtc; + char listOfNonDfsCountryCode[128]; + v_BOOL_t enableSSR; + char listOfNon11acCountryCode[128]; + v_U32_t cfgMaxMediumTime; + v_BOOL_t enableVhtFor24GHzBand; + v_U8_t fScanOffload; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* Flag indicating whether legacy fast roam during concurrency is enabled in cfg.ini or not */ + v_BOOL_t bFastRoamInConIniFeatureEnabled; +#endif + v_BOOL_t fEnableAdaptRxDrain; + //TX and RX traffic threshold for split scan + v_U8_t txRxThresholdForSplitScan; + v_U8_t dynSplitscan; //Enable/Disable dynamic + //splitscan + //Traffic monitor timer for split scan + v_U32_t trafficMntrTmrForSplitScan; + v_U8_t flexConnectPowerFactor; + v_BOOL_t enableIbssHeartBeatOffload; + v_U32_t antennaDiversity; + v_BOOL_t fEnableSNRMonitoring; + /*PNO related parameters */ +#ifdef FEATURE_WLAN_SCAN_PNO + v_BOOL_t configPNOScanSupport; + v_U32_t configPNOScanTimerRepeatValue; +#endif + v_U8_t isAmsduSupportInAMPDU; + v_U8_t nSelect5GHzMargin; + v_U8_t isCoalesingInIBSSAllowed; + + /* IBSS Power Save related parameters */ + v_U32_t ibssATIMWinSize; + v_U8_t isIbssPowerSaveAllowed; + v_U8_t isIbssPowerCollapseAllowed; + v_U8_t isIbssAwakeOnTxRx; + v_U32_t ibssInactivityCount; + v_U32_t ibssTxSpEndInactivityTime; + v_U32_t ibssPsWarmupTime; + v_U32_t ibssPs1RxChainInAtimEnable; + + v_BOOL_t enableTCPChkSumOffld; + v_BOOL_t enableIPChecksumOffload; + v_BOOL_t enablePowersaveOffload; + v_BOOL_t enablefwprint; + v_BOOL_t enablefwlog; + v_BOOL_t enableFwSelfRecovery; + v_BOOL_t fP2pListenOffload; +#ifdef WLAN_FEATURE_11AC + v_U8_t fVhtAmpduLenExponent; + v_U32_t vhtMpduLen; +#endif +#ifdef IPA_OFFLOAD + v_U32_t IpaConfig; + v_BOOL_t IpaClkScalingEnable; + v_U32_t IpaDescSize; + v_U32_t IpaHighBandwidthMbps; + v_U32_t IpaMediumBandwidthMbps; + v_U32_t IpaLowBandwidthMbps; +#endif +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + v_U32_t WlanMccToSccSwitchMode; +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + v_U32_t WlanAutoShutdown; +#endif + v_U8_t maxWoWFilters; + v_U8_t wowEnable; + v_U8_t maxNumberOfPeers; + v_U8_t disableDFSChSwitch; + v_U8_t enableDFSMasterCap; + v_U16_t thermalTempMinLevel0; + v_U16_t thermalTempMaxLevel0; + v_U16_t thermalTempMinLevel1; + v_U16_t thermalTempMaxLevel1; + v_U16_t thermalTempMinLevel2; + v_U16_t thermalTempMaxLevel2; + v_U16_t thermalTempMinLevel3; + v_U16_t thermalTempMaxLevel3; + v_U32_t TxPower2g; + v_U32_t TxPower5g; + v_U32_t gEnableDebugLog; + v_U8_t enableRxThread; + v_BOOL_t fDfsPhyerrFilterOffload; + v_U8_t gSapPreferredChanLocation; + v_U8_t gDisableDfsJapanW53; + v_BOOL_t gEnableOverLapCh; + char acsAllowedChnls[CFG_MAX_STR_LEN]; + v_BOOL_t fRegChangeDefCountry; + v_U8_t acsScanBandPreference; +#ifdef QCA_LL_TX_FLOW_CT + v_U32_t TxFlowLowWaterMark; + v_U32_t TxFlowHighWaterMarkOffset; + v_U32_t TxFlowMaxQueueDepth; + v_U32_t TxLbwFlowLowWaterMark; + v_U32_t TxLbwFlowHighWaterMarkOffset; + v_U32_t TxLbwFlowMaxQueueDepth; + v_U32_t TxHbwFlowLowWaterMark; + v_U32_t TxHbwFlowHighWaterMarkOffset; + v_U32_t TxHbwFlowMaxQueueDepth; +#endif /* QCA_LL_TX_FLOW_CT */ + v_U16_t acsBandSwitchThreshold; + v_BOOL_t gEnableStrictRegulatoryForFCC; + v_U8_t apMaxOffloadPeers; + v_U8_t apMaxOffloadReorderBuffs; + v_BOOL_t advertiseConcurrentOperation; + v_BOOL_t enableMemDeepSleep; + + v_U32_t defaultRateIndex24Ghz; + char overrideCountryCode[4]; + + v_U8_t allowDFSChannelRoam; + + v_BOOL_t debugP2pRemainOnChannel; + + v_BOOL_t enablePacketLog; +#ifdef MSM_PLATFORM + v_U32_t busBandwidthHighThreshold; + v_U32_t busBandwidthMediumThreshold; + v_U32_t busBandwidthLowThreshold; + v_U32_t busBandwidthComputeInterval; + v_U32_t tcpDelackThresholdHigh; + v_U32_t tcpDelackThresholdLow; +#endif /* MSM_PLATFORM */ + + /* FW debug log parameters */ + v_U32_t enableFwLogType; + v_U32_t enableFwLogLevel; + v_U8_t enableFwModuleLogLevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH]; + +#ifdef WLAN_FEATURE_11W + v_U32_t pmfSaQueryMaxRetries; + v_U32_t pmfSaQueryRetryInterval; +#endif + + v_U8_t gMaxConcurrentActiveSessions; + +#ifdef QCA_HT_2040_COEX + v_BOOL_t ht2040CoexEnabled; +#endif + v_U8_t ignoreCAC; + v_BOOL_t IsSapDfsChSifsBurstEnabled; + +#ifdef FEATURE_GREEN_AP + v_BOOL_t enableGreenAP; +#endif + + v_S31_t dfsRadarPriMultiplier; + v_U8_t reorderOffloadSupport; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + v_BOOL_t isRoamOffloadEnabled; +#endif + +#ifdef IPA_UC_OFFLOAD + v_U8_t IpaUcOffloadEnabled; + v_U32_t IpaUcTxBufCount; + v_U32_t IpaUcTxBufSize; + v_U32_t IpaUcRxIndRingCount; + v_U32_t IpaUcTxPartitionBase; +#endif /* IPA_UC_OFFLOAD */ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + /* WLAN Logging */ + v_U32_t wlanLoggingEnable; + v_U32_t wlanLoggingFEToConsole; + v_U32_t wlanLoggingNumBuf; +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ + + v_BOOL_t enableSifsBurst; + +#ifdef WLAN_FEATURE_LPSS + v_BOOL_t enablelpasssupport; +#endif + + v_BOOL_t enableSelfRecovery; +#ifdef FEATURE_WLAN_FORCE_SAP_SCC + v_U8_t SapSccChanAvoidance; +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + + v_BOOL_t enableSapSuspend; + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + v_U8_t extWowGotoSuspend; + v_U8_t extWowApp1WakeupPinNumber; + v_U8_t extWowApp2WakeupPinNumber; + v_U32_t extWowApp2KAInitPingInterval; + v_U32_t extWowApp2KAMinPingInterval; + v_U32_t extWowApp2KAMaxPingInterval; + v_U32_t extWowApp2KAIncPingInterval; + v_U16_t extWowApp2TcpSrcPort; + v_U16_t extWowApp2TcpDstPort; + v_U32_t extWowApp2TcpTxTimeout; + v_U32_t extWowApp2TcpRxTimeout; +#endif + v_BOOL_t gEnableDeauthToDisassocMap; + bool enable_mac_spoofing; + uint8_t sap_dot11mc; + uint8_t inform_bss_rssi_raw; +#ifdef FEATURE_SECURE_FIRMWARE + bool enable_fw_hash_check; +#endif + uint16_t p2p_listen_defer_interval; + uint16_t pkt_err_disconn_th; +} hdd_config_t; + +#ifdef WLAN_FEATURE_MBSSID +typedef struct mbssid_sap_dyn_ini_config { + /* ACS Parameters */ + v_U8_t apStartChannelNum; + v_U8_t apEndChannelNum; + v_U8_t apOperatingBand; + v_BOOL_t apAutoChannelSelection; + char acsAllowedChnls[CFG_MAX_STR_LEN]; + v_U8_t acsScanBandPreference; + v_U16_t acsBandSwitchThreshold; + v_BOOL_t apForce11ACFor11n; +} mbssid_sap_dyn_ini_config_t; +#endif + +#define VAR_OFFSET( _Struct, _Var ) (offsetof(_Struct, _Var)) +#define VAR_SIZE( _Struct, _Var ) (sizeof(((_Struct *)0)->_Var)) + +#define VAR_FLAGS_NONE ( 0 ) +#define VAR_FLAGS_REQUIRED ( 1 << 0 ) // bit 0 is Required or Optional +#define VAR_FLAGS_OPTIONAL ( 0 << 0 ) + +#define VAR_FLAGS_RANGE_CHECK ( 1 << 1 ) // bit 1 tells if range checking is required. + // If less than MIN, assume MIN. + // If greater than MAX, assume MAX. + +#define VAR_FLAGS_RANGE_CHECK_ASSUME_MINMAX ( VAR_FLAGS_RANGE_CHECK ) + +/* + * bit 2 is range checking that assumes the DEFAULT value + * If less than MIN, assume DEFAULT, + * If greater than MAX, assume DEFAULT. + */ +#define VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ( 1 << 2 ) + +/* + * Bit 3 indicates that the config item can be modified dynamically + * on a running system + */ +#define VAR_FLAGS_DYNAMIC_CFG ( 1 << 3 ) + +typedef enum +{ + WLAN_PARAM_Integer, + WLAN_PARAM_SignedInteger, + WLAN_PARAM_HexInteger, + WLAN_PARAM_String, + WLAN_PARAM_MacAddr, +}WLAN_PARAMETER_TYPE; + +#define REG_VARIABLE( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default, _Min, _Max ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( _Flags ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + ( _Default ), \ + ( _Min ), \ + ( _Max ), \ + NULL, \ + 0 \ +} + +#define REG_DYNAMIC_VARIABLE( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default, _Min, _Max, \ + _CBFunc, _CBParam ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( VAR_FLAGS_DYNAMIC_CFG | ( _Flags ) ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + ( _Default ), \ + ( _Min ), \ + ( _Max ), \ + ( _CBFunc ), \ + ( _CBParam ) \ +} + +#define REG_VARIABLE_STRING( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( _Flags ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + (unsigned long)( _Default ), \ + 0, \ + 0, \ + NULL, \ + 0 \ +} + +typedef struct tREG_TABLE_ENTRY { + + char* RegName; // variable name in the qcom_cfg.ini file + WLAN_PARAMETER_TYPE RegType; // variable type in the hdd_config_t structure + unsigned long Flags; // Specify optional parms and if RangeCheck is performed + unsigned short VarOffset; // offset to field from the base address of the structure + unsigned short VarSize; // size (in bytes) of the field + unsigned long VarDefault; // default value to use + unsigned long VarMin; // minimum value, for range checking + unsigned long VarMax; // maximum value, for range checking + // Dynamic modification notifier + void (*pfnDynamicNotify)(hdd_context_t *pHddCtx, unsigned long NotifyId); + unsigned long NotifyId; // Dynamic modification identifier +} REG_TABLE_ENTRY; + +static __inline unsigned long utilMin( unsigned long a, unsigned long b ) +{ + return( ( a < b ) ? a : b ); +} + +/*--------------------------------------------------------------------------- + Function declarations and documentation + -------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx); +VOS_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx); +VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx); +v_BOOL_t hdd_update_config_dat ( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_cfg_get_global_config(hdd_context_t *pHddCtx, char *pBuf, + int buflen); +#ifdef WLAN_FEATURE_MBSSID +VOS_STATUS hdd_cfg_get_sap_dyn_config(hdd_adapter_t *pAdapter, char *pBuf, + int buflen); +#endif +eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode( eHddDot11Mode dot11Mode ); +VOS_STATUS hdd_execute_global_config_command(hdd_context_t *pHddCtx, + char *command); +#ifdef WLAN_FEATURE_MBSSID +VOS_STATUS hdd_execute_sap_dyn_config_command(hdd_adapter_t *pAdapter, + char *command); +#endif +tANI_BOOLEAN hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx); +VOS_STATUS hdd_set_idle_ps_config(hdd_context_t *pHddCtx, v_U32_t val); + +void hdd_update_tgt_cfg(void *context, void *param); +void hdd_dfs_indicate_radar(void *context, void *param); + +VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8 *len, + tANI_U8 intArrayMaxLen ); +#ifdef WLAN_FEATURE_MBSSID +v_VOID_t hdd_mbssid_apply_def_cfg_ini(hdd_adapter_t *pAdapter); +#endif + +void print_hdd_cfg(hdd_context_t *pHddCtx); +VOS_STATUS hdd_update_nss(hdd_context_t *hdd_ctx, uint8_t nss); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg80211.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg80211.h new file mode 100644 index 0000000000000..0957be369255f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -0,0 +1,988 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_CFG80211_H__ ) +#define HDD_CFG80211_H__ + + +/**=========================================================================== + + \file wlan_hdd_cfg80211.h + + \brief cfg80211 functions declarations + + ==========================================================================*/ + +/* $HEADER$ */ + + +//value for initial part of frames and number of bytes to be compared +#define GAS_INITIAL_REQ "\x04\x0a" +#define GAS_INITIAL_REQ_SIZE 2 + +#define GAS_INITIAL_RSP "\x04\x0b" +#define GAS_INITIAL_RSP_SIZE 2 + +#define GAS_COMEBACK_REQ "\x04\x0c" +#define GAS_COMEBACK_REQ_SIZE 2 + +#define GAS_COMEBACK_RSP "\x04\x0d" +#define GAS_COMEBACK_RSP_SIZE 2 + +#define P2P_PUBLIC_ACTION_FRAME "\x04\x09\x50\x6f\x9a\x09" +#define P2P_PUBLIC_ACTION_FRAME_SIZE 6 + +#define P2P_ACTION_FRAME "\x7f\x50\x6f\x9a\x09" +#define P2P_ACTION_FRAME_SIZE 5 + +#define SA_QUERY_FRAME_REQ "\x08\x00" +#define SA_QUERY_FRAME_REQ_SIZE 2 + +#define SA_QUERY_FRAME_RSP "\x08\x01" +#define SA_QUERY_FRAME_RSP_SIZE 2 + +#define HDD_P2P_WILDCARD_SSID "DIRECT-" //TODO Put it in proper place; +#define HDD_P2P_WILDCARD_SSID_LEN 7 + +#define WNM_BSS_ACTION_FRAME "\x0a\x07" +#define WNM_BSS_ACTION_FRAME_SIZE 2 + +#define WNM_NOTIFICATION_FRAME "\x0a\x1a" +#define WNM_NOTIFICATION_FRAME_SIZE 2 + +#define WPA_OUI_TYPE "\x00\x50\xf2\x01" +#define BLACKLIST_OUI_TYPE "\x00\x50\x00\x00" +#define WHITELIST_OUI_TYPE "\x00\x50\x00\x01" +#define WPA_OUI_TYPE_SIZE 4 + +#define WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 +#define BASIC_RATE_MASK 0x80 +#define RATE_MASK 0x7f + +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS +/* GPS application requirement */ +#define QCOM_VENDOR_IE_ID 221 +#define QCOM_OUI1 0x00 +#define QCOM_OUI2 0xA0 +#define QCOM_OUI3 0xC6 +#define QCOM_VENDOR_IE_AGE_TYPE 0x100 +#define QCOM_VENDOR_IE_AGE_LEN 11 + +#ifdef FEATURE_WLAN_TDLS +#define WLAN_IS_TDLS_SETUP_ACTION(action) \ + ((SIR_MAC_TDLS_SETUP_REQ <= action) && (SIR_MAC_TDLS_SETUP_CNF >= action)) +#if !defined (TDLS_MGMT_VERSION2) +#define TDLS_MGMT_VERSION2 0 +#endif +#endif + +#define MAX_CHANNEL (MAX_2_4GHZ_CHANNEL + NUM_5GHZ_CHANNELS) + +typedef struct { + u8 element_id; + u8 len; + u8 oui_1; + u8 oui_2; + u8 oui_3; + u32 type; + u32 age; +}__attribute__((packed)) qcom_ie_age ; +#endif + +/* Vendor id to be used in vendor specific command and events + * to user space. + * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID, + * vendor subcmd definitions prefixed with QCA_NL80211_VENDOR_SUBCMD, and + * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in + * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that + */ + +#define QCA_NL80211_VENDOR_ID 0x001374 + +enum qca_nl80211_vendor_subcmds { + QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0, + QCA_NL80211_VENDOR_SUBCMD_TEST = 1, + /* subcmds 2..9 not yet allocated */ + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY = 10, + QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY = 11, + QCA_NL80211_VENDOR_SUBCMD_NAN = 12, + QCA_NL80211_VENDOR_SUBCMD_STATS_EXT = 13, + /* subcommands for link layer statistics start here */ + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET = 14, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET = 15, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR = 16, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS = 17, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS = 18, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS = 19, + /* subcommands for extscan start here */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START = 20, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP = 21, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS = 22, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES = 23, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS = 24, + /* Used when report_threshold is reached in scan cache. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE = 25, + /* Used to report scan results when each probe rsp. is received, + * if report_events enabled in wifi_scan_cmd_params. + */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT = 26, + /* Indicates progress of scanning state-machine. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT = 27, + /* Indicates BSSID Hotlist. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND = 28, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST = 29, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST = 30, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE = 31, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE = 32, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE = 33, + /* EXT TDLS */ + QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE = 34, + QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE = 35, + QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS = 36, + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE = 37, + /* Get supported features */ + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38, + + /* Set scanning_mac_oui */ + QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI = 39, + /* Set nodfs_flag */ + QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG = 40, + + /* Get Concurrency Matrix */ + QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42, +}; + +enum qca_nl80211_vendor_subcmds_index { +#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC) + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX = 0, +#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC */ + +#ifdef WLAN_FEATURE_NAN + QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX, +#endif /* WLAN_FEATURE_NAN */ + +#ifdef WLAN_FEATURE_STATS_EXT + QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX, +#endif /* WLAN_FEATURE_STATS_EXT */ + +#ifdef FEATURE_WLAN_EXTSCAN + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX, +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + /* EXT TDLS */ + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX, +}; + +/* EXT TDLS */ +enum qca_wlan_vendor_attr_tdls_enable { + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_disable { + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_get_status { + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_state { + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr { + QCA_WLAN_VENDOR_ATTR_INVALID = 0, + /* used by QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY */ + QCA_WLAN_VENDOR_ATTR_DFS = 1, + /* used by QCA_NL80211_VENDOR_SUBCMD_NAN */ + QCA_WLAN_VENDOR_ATTR_NAN = 2, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, + QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAX = + QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1 +}; + +#ifdef FEATURE_WLAN_EXTSCAN +enum qca_wlan_vendor_attr_extscan_config_params +{ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0, + + /* Unsigned 32-bit value; Middleware provides it to the driver. Middle ware + * either gets it from caller, e.g., framework, or generates one if + * framework doesn't provide it. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + + /* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS, + + /* NL attributes for input params used by + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START sub command. + */ + + /* Unsigned 32-bit value; channel frequency */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL, + /* Unsigned 32-bit value; dwell time in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME, + /* Unsigned 8-bit value; 0: active; 1: passive; N/A for DFS */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE, + /* Unsigned 8-bit value; channel class */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS, + + /* Unsigned 8-bit value; bucket index, 0 based */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX, + /* Unsigned 8-bit value; band. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND, + /* Unsigned 32-bit value; desired period, in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD, + /* Unsigned 8-bit value; report events semantics. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS, + /* Unsigned 32-bit value. + * Followed by a nested array of EXTSCAN_CHANNEL_SPEC_* attributes. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC, + + /* Unsigned 32-bit value; base timer period in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD, + /* Unsigned 32-bit value; number of APs to store in each scan in the + * BSSID/RSSI history buffer (keep the highest RSSI APs). + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN, + /* Unsigned 8-bit value; In %, when scan buffer is this much full, wake up + * APPS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD, + /* Unsigned 8-bit value; number of scan bucket specs; followed by a nested + * array of_EXTSCAN_BUCKET_SPEC_* attributes and values. The size of the + * array is determined by NUM_BUCKETS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC, + + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH, + /* Unsigned 32-bit value; maximum number of results to be returned. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX, + + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL, + + /* Number of hotlist APs as unsigned 32-bit value, followed by a nested + * array of AP_THRESHOLD_PARAM attributes and values. The size of the + * array is determined by NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM, + + /* Unsigned 32bit value; number of samples for averaging RSSI. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE, + /* Unsigned 32bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE, + /* Unsigned 32bit value; number of APs breaching threshold. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING, + /* Unsigned 32bit value; number of APs. Followed by an array of + * AP_THRESHOLD_PARAM attributes. Size of the array is NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_extscan_results +{ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_INVALID = 0, + + /* Unsigned 32-bit value; must match the request Id supplied by Wi-Fi HAL + * in the corresponding subcmd NL msg + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + + /* Unsigned 32-bit value; used to indicate the status response from + * firmware/driver for the vendor sub-command. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, + + /* EXTSCAN Valid Channels attributes */ + /* Unsigned 32bit value; followed by a nested array of CHANNELS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS, + /* An array of NUM_CHANNELS x Unsigned 32bit value integers representing + * channel numbers + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS, + + /* EXTSCAN Capabilities attributes */ + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE, + /* Signed 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES, + + /* EXTSCAN Attributes used with + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE sub-command. + */ + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + + + /* EXTSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT sub-command. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_* + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST, + + /* Unsigned 64-bit value; age of sample at the time of retrieval */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + /* 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + /* Unsigned 32-bit value; size of the IE DATA blob */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + /* An array of IE_LENGTH x Unsigned 8-bit value; blob of all the + * information elements found in the beacon; this data should be a + * packed list of wifi_information_element objects, one after the other. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + /* Unsigned 8-bit value; set by driver to indicate more scan results are + * available. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT sub-command. + */ + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS, + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of results. + */ + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE sub-command. + */ + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL, + /* Unsigned 32-bit value. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI, + /* A nested array of signed 32-bit RSSI values. Size of the array is + * determined by (NUM_RSSI of SIGNIFICANT_CHANGE_RESULT_NUM_RSSI. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST - 1, +}; + +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +enum qca_wlan_vendor_attr_ll_stats_set +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_get +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_INVALID = 0, + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting the stats results, the driver uses the same + * value to indicate which GET request the results correspond to. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID, + /* Unsigned 34bit value - bit mask to identify what + * statistics are requested for retrieval. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_clr +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_results +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_INVALID = 0, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_REQ_ID = 1, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_* are + * nested within the interface stats. + */ + + /* Interface mode, e.g., STA, SOFTAP, IBSS, etc. + * Type = enum wifi_interface_mode */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, + /* Interface MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + /* Type = enum wifi_connection_state, + * e.g., DISCONNECTED, AUTHENTICATING, etc. + * valid for STA, CLI only. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + /* Type = enum wifi_roam_state. Roaming state, + * e.g., IDLE or ACTIVE (is that valid for STA only?) + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + /* Unsigned 32bit value. WIFI_CAPABILITY_XXX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + /* NULL terminated SSID. An array of 33 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + /* BSSID. An array of 6 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + /* Country string advertised by AP. An array of 3 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + /* Country string for this association. An array of 3 Unsigned 8bit values*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_* could + * be nested within the interface stats. + */ + + /* Type = enum wifi_traffic_ac, e.g., V0, VI, BE and BK */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + /* Unsigned 32bit value. Number of peers */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_* are + * nested within the interface stats. + */ + + /* Type = enum wifi_peer_type. Peer type, e.g., STA, AP, P2P GO etc. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + /* MAC addr corresponding to respective peer. + * An array of 6 Unsigned 8bit values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + /* Unsigned int 32bit value representing capabilities + * corresponding to respective peer. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + /* Unsigned 32bit value. Number of rates */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + + /* Attributes nested within the rate stats.*/ + /* Unsigned 8bit value */ + /* Unsigned int 8bit value; 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + /* Unsigned int 8bit value; 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + /* Unsigned int 8bit value; 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + /* Unsigned int 8bit value; OFDM/CCK rate code would be as per IEEE Std + * in the units of 0.5mbps HT/VHT it would be mcs index */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + + /* Unsigned 32bit value. Bit rate in units of 100Kbps */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* could be + * nested within the peer info stats. + */ + + /* Unsigned int 32bit value. Number of successfully transmitted data pkts, + * i.e., with ACK received *corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + /* Unsigned int 32bit value. Number of received data pkts + * corresponding to the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + /* Unsigned int 32bit value. Number of data pkts losses, i.e., + * no ACK received corresponding to *the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + /* Unsigned int 32bit value. Total number of data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + /* Unsigned int 32bit value. Total number of short data pkt retries for + the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + /* Unsigned int 32bit value. Total number of long data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + /* Unsigned 32bit value. Total number of msecs the radio is awake + * accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * transmitting accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * in active receive accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to all scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to NAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to GSCAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to roam scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to PNO scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to HS2.0 scans and GAS exchange accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + /* Unsigned 32bit value. Number of channels. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_ + * could be nested within the channel stats. + */ + + /* Type = enum wifi_channel_width. Channel width, e.g., 20, 40, 80, etc.*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + /* Unsigned 32bit value. Primary 20MHz channel. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + /* Unsigned 32bit value. Center frequency (MHz) first segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + /* Unsigned 32bit value. Center frequency (MHz) second segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ could be + * nested within the radio stats. + */ + + /* Unsigned int 32bit value representing total number of msecs the radio + * s awake on that *channel accruing over time, corresponding to + * the respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + /* Unsigned int 32bit value representing total number of msecs the + * CCA register is busy accruing *over time corresponding to the + * respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO, + + /* Unsigned 8bit value. Used by the driver; if set to 1, it indicates that + * more stats, e.g., peers or radio, are to follow in the next + * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_*_RESULTS event. + * Otherwise, it is set to 0. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST -1 +}; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +enum qca_wlan_vendor_attr_get_supported_features { + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_FEATURE_SET = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX = + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_set_scanning_mac_oui { + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_INVALID = 0, + /* An array of 3 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX = + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_set_no_dfs_flag +{ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX = + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_AFTER_LAST - 1, +}; + +/* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX sub command. + */ +enum qca_wlan_vendor_attr_get_concurrency_matrix { + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX = 1, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE = 2, + /* An array of SET_SIZE x Unsigned 32bit values representing + * concurrency combinations. + */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET = 3, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX = + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_AFTER_LAST - 1, +}; + +/* Feature defines */ +#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */ +#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */ +#define WIFI_FEATURE_HOTSPOT 0x0004 /* Support for GAS/ANQP */ +#define WIFI_FEATURE_P2P 0x0008 /* Wifi-Direct */ +#define WIFI_FEATURE_SOFT_AP 0x0010 /* Soft AP */ +#define WIFI_FEATURE_EXTSCAN 0x0020 /* Extended Scan APIs */ +#define WIFI_FEATURE_NAN 0x0040 /* Neighbor Awareness + Networking */ +#define WIFI_FEATURE_D2D_RTT 0x0080 /* Device-to-device RTT */ +#define WIFI_FEATURE_D2AP_RTT 0x0100 /* Device-to-AP RTT */ +#define WIFI_FEATURE_BATCH_SCAN 0x0200 /* Batched Scan (legacy) */ +#define WIFI_FEATURE_PNO 0x0400 /* Preferred network offload */ +#define WIFI_FEATURE_ADDITIONAL_STA 0x0800 /* Support for two STAs */ +#define WIFI_FEATURE_TDLS 0x1000 /* Tunnel directed link + setup */ +#define WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 /* Support for TDLS off + channel */ +#define WIFI_FEATURE_EPR 0x4000 /* Enhanced power reporting */ +#define WIFI_FEATURE_AP_STA 0x8000 /* Support for AP STA + Concurrency */ +#define WIFI_FEATURE_LINK_LAYER_STATS 0x10000 /* Link layer stats */ +/* Add more features here */ + + +#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC) +#define HDD_MAX_AVOID_FREQ_RANGES 4 +typedef struct sHddAvoidFreqRange +{ + u32 startFreq; + u32 endFreq; +} tHddAvoidFreqRange; + +typedef struct sHddAvoidFreqList +{ + u32 avoidFreqRangeCount; + tHddAvoidFreqRange avoidFreqRange[HDD_MAX_AVOID_FREQ_RANGES]; +} tHddAvoidFreqList; +#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC */ + +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo + ); + +#ifdef FEATURE_WLAN_LFR +int wlan_hdd_cfg80211_pmksa_candidate_notify( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + int index, bool preauth ); +#endif + +#ifdef FEATURE_WLAN_LFR_METRICS +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); + +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status); + +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); +#endif + +#ifdef FEATURE_WLAN_WAPI +void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, + u8 key_index, const u8 *mac_addr, u8 *key , int key_Len); +#endif +struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size); + +int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); + +int wlan_hdd_cfg80211_init(struct device *dev, + struct wiphy *wiphy, + hdd_config_t *pCfg + ); + +void wlan_hdd_update_wiphy(struct wiphy *wiphy, + hdd_config_t *pCfg); + +int wlan_hdd_cfg80211_register( struct wiphy *wiphy); +void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter); + +void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#else +int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#endif + +extern v_VOID_t hdd_connSetConnectionState(hdd_adapter_t *pAdapter, + eConnectionState connState); +VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel); +#ifdef FEATURE_WLAN_TDLS +int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy, + struct net_device *dev, u8 *peer); +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD +extern void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp); +#endif +void* wlan_hdd_change_country_code_cb(void *pAdapter); +void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel); + +v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid); + +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac); + +#if defined(QCA_WIFI_FTM) && defined(CONFIG_NL80211_TESTMODE) +void wlan_hdd_testmode_rx_event(void *buf, size_t buf_len); +#endif + +void hdd_suspend_wlan(void (*callback)(void *callbackContext, boolean suspended), + void *callbackContext); +void hdd_resume_wlan(void); + +#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC) +int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx, + tHddAvoidFreqList *pAvoidFreqList); +#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC*/ + +#ifdef FEATURE_WLAN_EXTSCAN +void wlan_hdd_cfg80211_extscan_callback(void *ctx, + const tANI_U16 evType, + void *pMsg); +#endif /* FEATURE_WLAN_EXTSCAN */ + +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo); + +int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_debugfs.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_debugfs.h new file mode 100644 index 0000000000000..40415fd154e00 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_debugfs.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_DEBUGFS_H +#define _WLAN_HDD_DEBUGFS_H + +#ifdef WLAN_OPEN_SOURCE +VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter); +void hdd_debugfs_exit(hdd_context_t *pHddCtx); +#else +inline VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter) +{ + return VOS_STATUS_SUCCESS; +} +inline void hdd_debugfs_exit(hdd_context_t *pHddCtx) +{ +} +#endif /* #ifdef WLAN_OPEN_SOURCE */ +#endif /* #ifndef _WLAN_HDD_DEBUGFS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dev_pwr.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dev_pwr.h new file mode 100644 index 0000000000000..c17b1b0a6031e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dev_pwr.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_DEV_PWR_H +#define __WLAN_HDD_DEV_PWR_H + +#include +#include +#include +#include + + +/*---------------------------------------------------------------------------- + + @brief Registration function. + Register suspend, resume callback functions with platform driver. + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +static inline VOS_STATUS hddRegisterPmOps(hdd_context_t *pHddCtx) +{ + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief De-registration function. + Deregister the suspend, resume callback functions with platform driver + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS De-Registration Success + VOS_STATUS_E_FAILURE De-Registration Fail + +----------------------------------------------------------------------------*/ +static inline VOS_STATUS hddDeregisterPmOps(hdd_context_t *pHddCtx) +{ + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief TM Level Change handler + Received Tm Level changed notification + + @param dev : Device context + changedTmLevel : Changed new TM level + + @return + +----------------------------------------------------------------------------*/ +static inline void hddDevTmLevelChangedHandler(struct device *dev, + int changedTmLevel) +{ + return; +} + +/*---------------------------------------------------------------------------- + + @brief Register function + Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmRegisterNotifyCallback(hdd_context_t *pHddCtx); + +/*---------------------------------------------------------------------------- + + @brief Un-Register function + Un-Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Un-Registration Success + VOS_STATUS_E_FAILURE Un-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmUnregisterNotifyCallback(hdd_context_t *pHddCtx); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dp_utils.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dp_utils.h new file mode 100644 index 0000000000000..f052823529a9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_dp_utils.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_HDD_DP_UTILS_H ) +#define __WLAN_HDD_DP_UTILS_H + +/**============================================================================= + wlan_hdd_dp_utils.h + + \brief Utility functions for data path module + + Description... + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +typedef struct list_head hdd_list_node_t; + +typedef struct hdd_list_s +{ + hdd_list_node_t anchor; + v_SIZE_t count; + v_SIZE_t max_size; + spinlock_t lock; +} hdd_list_t; + +typedef struct +{ + hdd_list_node_t anchor; + struct sk_buff *skb; + int userPriority; +} skb_list_node_t; + +//FIXME Need a helper function to cleanup skbs in a queue. Required for cleanup/shutdown + +/**----------------------------------------------------------------------------- + Function declarations and documentation + ----------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t hdd_list_init( hdd_list_t *pList, v_SIZE_t max_size) +{ + INIT_LIST_HEAD( &pList->anchor ); + pList->count = 0; + pList->max_size = max_size; + spin_lock_init(&pList->lock); +} + +VOS_INLINE_FN v_VOID_t hdd_list_destroy( hdd_list_t *pList ) +{ + if ( pList->count !=0 ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: list length not equal to zero",__func__); + } +} + +VOS_INLINE_FN v_VOID_t hdd_list_size( hdd_list_t *pList, v_SIZE_t *pSize ) +{ + *pSize = pList->count; +} + +VOS_STATUS hdd_list_insert_front( hdd_list_t *pList, hdd_list_node_t *pNode ); + +VOS_STATUS hdd_list_insert_back( hdd_list_t *pList, hdd_list_node_t *pNode ); + +VOS_STATUS hdd_list_insert_back_size( hdd_list_t *pList, hdd_list_node_t *pNode, v_SIZE_t *pSize ); + +VOS_STATUS hdd_list_remove_front( hdd_list_t *pList, hdd_list_node_t **ppNode ); + +VOS_STATUS hdd_list_remove_back( hdd_list_t *pList, hdd_list_node_t **ppNode ); + +VOS_STATUS hdd_list_remove_node( hdd_list_t *pList, hdd_list_node_t *pNodeToRemove ); +VOS_STATUS hdd_list_peek_front( hdd_list_t *pList, hdd_list_node_t **ppNode ); +VOS_STATUS hdd_list_peek_next( hdd_list_t *pList, hdd_list_node_t *pNode, + hdd_list_node_t **ppNode ); +VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ); +#endif //__WLAN_HDD_DP_UTILS_H diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ether.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ether.h new file mode 100644 index 0000000000000..76c21020878b5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ether.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_ETHER_H +#define _WLAN_HDD_ETHER_H +/*============================================================================ + @file wlan_hdd_ether.h + + This module describes Ethernet packet formats for processing by HDD. +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WLAN_SNAP_OUI_LEN 3 +#define WLAN_SNAP_DSAP 0xAAU +#define WLAN_SNAP_SSAP 0xAAU +#define WLAN_SNAP_CTRL 0x03 +#define WLAN_MIN_PROTO 0x0600 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +struct wlan_snap_hdr { + unsigned char dsap; + unsigned char ssap; + unsigned char ctrl; + unsigned char oui[WLAN_SNAP_OUI_LEN]; +} __packed; + +struct wlan_8023 { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_len; + struct wlan_snap_hdr h_snap; + __be16 h_proto; +} __packed; + +struct wlan_8023_vlan { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + __be16 h_len; + struct wlan_snap_hdr h_snap; + __be16 h_proto; +} __packed; + +union generic_ethhdr { + struct ethhdr eth_II; + struct vlan_ethhdr eth_IIv; + struct wlan_8023 eth_8023; + struct wlan_8023_vlan eth_8023v; +}; + +#endif /* #ifndef _WLAN_HDD_ETHER_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ftm.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ftm.h new file mode 100644 index 0000000000000..d470d24e13e9c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ftm.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_HDD_FTM_H +#define WLAN_HDD_FTM_H +#include "vos_status.h" +#include "vos_mq.h" +#include "vos_api.h" +#include "msg.h" +#include "halTypes.h" +#include "vos_types.h" +#include + +#define WLAN_FTM_SUCCESS 0 +#define WLAN_FTM_FAILURE 1 + +typedef enum { + WLAN_FTM_INITIALIZED, + WLAN_FTM_STOPPED, + WLAN_FTM_STARTED, +} wlan_hdd_ftm_state; +typedef struct wlan_hdd_ftm_status_s +{ + v_U8_t ftm_state; + /**vos event */ + vos_event_t ftm_vos_event; + + /** completion variable for ftm command to complete*/ + struct completion ftm_comp_var; + v_BOOL_t IsCmdPending; +} wlan_hdd_ftm_status_t; + +int wlan_hdd_ftm_open(hdd_context_t *pHddCtx); +int wlan_hdd_ftm_close(hdd_context_t *pHddCtx); + +#if defined(QCA_WIFI_FTM) +VOS_STATUS wlan_hdd_ftm_testmode_cmd(void *data, int len); +int wlan_hdd_qcmbr_unified_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr); +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_host_offload.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_host_offload.h new file mode 100644 index 0000000000000..5082fe3b5a0d6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_host_offload.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_HOST_OFFLOAD_H__ +#define __WLAN_HDD_HOST_OFFLOAD_H__ + +/**=========================================================================== + + \file wlan_hdd_host_offload.h + + \brief Android WLAN HDD Host Offload API + +==========================================================================*/ + +/* Offload types. */ +#define WLAN_IPV4_ARP_REPLY_OFFLOAD 0 +#define WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 + +/* Enable or disable offload. */ +#define WLAN_OFFLOAD_DISABLE 0 +#define WLAN_OFFLOAD_ENABLE 0x1 +#define WLAN_OFFLOAD_BC_FILTER_ENABLE 0x2 +#define WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE (WLAN_OFFLOAD_ENABLE | WLAN_OFFLOAD_BC_FILTER_ENABLE) + +/* Offload request. */ +typedef struct +{ + v_U8_t offloadType; + v_U8_t enableOrDisable; + union + { + v_U8_t hostIpv4Addr [4]; + v_U8_t hostIpv6Addr [16]; + } params; + v_MACADDR_t bssId; +} tHostOffloadRequest, *tpHostOffloadRequest; + +#endif // __WLAN_HDD_HOST_OFFLOAD_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_hostapd.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_hostapd.h new file mode 100644 index 0000000000000..4d24a53924abb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_hostapd.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_HOSTAPD_H ) +#define WLAN_HDD_HOSTAPD_H + +/**=========================================================================== + + \file WLAN_HDD_HOSTAPD_H.h + + \brief Linux HDD HOSTAPD include file + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/* max length of command string in hostapd ioctl */ +#define HOSTAPD_IOCTL_COMMAND_STRLEN_MAX 8192 + +hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *name); + +VOS_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter, tANI_U8 rtnl_held); + +VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter); + +eCsrAuthType +hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4]); + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]); + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]); + +eCsrAuthType +hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4]); + +eCsrEncryptionType +hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4]); + +VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t*,v_U8_t*); +void hdd_softap_sta_disassoc(hdd_adapter_t*,v_U8_t*); +void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t*,v_BOOL_t); +int hdd_softap_unpackIE( tHalHandle halHandle, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, + v_BOOL_t *pMFPCapable, + v_BOOL_t *pMFPRequired, + u_int16_t gen_ie_len, + u_int8_t *gen_ie ); + +VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback); +VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter ); +void hdd_set_ap_ops( struct net_device *pWlanHostapdDev ); +int hdd_hostapd_stop (struct net_device *dev); +void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx); +void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx); +#ifdef FEATURE_WLAN_FORCE_SAP_SCC +void hdd_restart_softap (hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter); +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ +#ifdef QCA_HT_2040_COEX +VOS_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter, + tANI_U8 channel_type); +#endif +#endif // end #if !defined( WLAN_HDD_HOSTAPD_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_includes.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_includes.h new file mode 100644 index 0000000000000..239e7920b9117 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_includes.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_INCLUDES_H__ ) +#define HDD_INCLUDES_H__ + +/**=========================================================================== + + \file wlan_hdd_includes.h + + \brief Internal includes for the Linux HDD + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +// throw all the includes in here f to get the .c files in the HDD to compile. + +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_dp_utils.h" +#include "wlan_hdd_mib.h" +#include "wlan_hdd_wext.h" +#include "wlan_hdd_main.h" +#include "wlan_hdd_tx_rx.h" + +#ifdef FEATURE_OEM_DATA_SUPPORT +/*include for oem data req specific structures*/ +/*and function declarations*/ +#include "wlan_hdd_oemdata.h" +#endif + +#endif // end #if !defined( HDD_INCLUDES_H__ ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ipa.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ipa.h new file mode 100644 index 0000000000000..2bd1f0bf19d6b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_ipa.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HDD_IPA_H__ +#define HDD_IPA_H__ + +/**=========================================================================== + + \file wlan_hdd_ipa.h + + \brief WLAN IPA interface module headers + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#ifdef IPA_OFFLOAD +#include + +VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx); +VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx); +int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, + enum ipa_wlan_event type, uint8_t *mac_addr); +VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rxBuf, + v_U8_t sta_id); +bool hdd_ipa_is_enabled(hdd_context_t *pHddCtx); + +int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets, + uint64_t rx_packets); + +int hdd_ipa_suspend(hdd_context_t *hdd_ctx); +int hdd_ipa_resume(hdd_context_t *hdd_ctx); + +#ifdef IPA_UC_OFFLOAD +void hdd_ipa_uc_stat_query(hdd_context_t *pHddCtx, + uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff); +void hdd_ipa_uc_stat_request( hdd_adapter_t *adapter, uint8_t reason); +#endif + +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_keep_alive.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_keep_alive.h new file mode 100644 index 0000000000000..a33074c7c2729 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_keep_alive.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_KEEP_ALIVE_H__ +#define __WLAN_HDD_KEEP_ALIVE_H__ + +/**=========================================================================== + + \file wlan_hdd_keep_alive.h + + \brief Android WLAN HDD Keep-Alive API + +==========================================================================*/ + +/* Packet Types. */ +#define WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 +#define WLAN_KEEP_ALIVE_NULL_PKT 1 + +/* Enable or disable offload. */ +#define WLAN_KEEP_ALIVE_DISABLE 0 +#define WLAN_KEEP_ALIVE_ENABLE 0x1 + +/* Offload request. */ +typedef struct +{ + v_U8_t packetType; + v_U32_t timePeriod; + v_U8_t hostIpv4Addr[4]; + v_U8_t destIpv4Addr[4]; + v_U8_t destMacAddr [6]; + v_U8_t bssIdx; +} tKeepAliveRequest, *tpKeepAliveRequest; + +#endif // __WLAN_HDD_KEEP_ALIVE_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h new file mode 100644 index 0000000000000..a34f4baeca3f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_main.h @@ -0,0 +1,1745 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_MAIN_H ) +#define WLAN_HDD_MAIN_H +/**=========================================================================== + + \file WLAN_HDD_MAIN_H.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include "sirMacProtDef.h" +#include "csrApi.h" +#include +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif +#include +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#include "wlan_hdd_cfg80211.h" +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +#include +#endif +#ifdef WLAN_FEATURE_MBSSID +#include "sapApi.h" +#endif + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +/** Number of Tx Queues */ +#define NUM_TX_QUEUES 4 +/** HDD's internal Tx Queue Length. Needs to be a power of 2 */ +#define HDD_TX_QUEUE_MAX_LEN 128 +/** HDD internal Tx Queue Low Watermark. Net Device TX queue is disabled + * when HDD queue becomes full. This Low watermark is used to enable + * the Net Device queue again */ +#define HDD_TX_QUEUE_LOW_WATER_MARK (HDD_TX_QUEUE_MAX_LEN*3/4) +/** Bytes to reserve in the headroom */ +#define LIBRA_HW_NEEDED_HEADROOM 128 +/** Hdd Tx Time out value */ +#ifdef LIBRA_LINUX_PC +#define HDD_TX_TIMEOUT (8000) +#else +#define HDD_TX_TIMEOUT msecs_to_jiffies(5000) +#endif +/** Hdd Default MTU */ +#define HDD_DEFAULT_MTU (1500) + +/**event flags registered net device*/ +#define NET_DEVICE_REGISTERED (0) +#define SME_SESSION_OPENED (1) +#define INIT_TX_RX_SUCCESS (2) +#define WMM_INIT_DONE (3) +#define SOFTAP_BSS_STARTED (4) +#define DEVICE_IFACE_OPENED (5) +#define TDLS_INIT_DONE (6) + +/** Maximum time(ms)to wait for disconnect to complete **/ +#define WLAN_WAIT_TIME_DISCONNECT 2000 +#define WLAN_WAIT_TIME_STATS 800 +#define WLAN_WAIT_TIME_POWER 800 +#define WLAN_WAIT_TIME_COUNTRY 1000 +#define WLAN_WAIT_TIME_LINK_STATUS 800 +/* Amount of time to wait for sme close session callback. + This value should be larger than the timeout used by WDI to wait for + a response from WCNSS */ +#define WLAN_WAIT_TIME_SESSIONOPENCLOSE 15000 +#define WLAN_WAIT_TIME_ABORTSCAN 2000 +#define WLAN_WAIT_TIME_EXTSCAN 1000 +#define WLAN_WAIT_TIME_LL_STATS 5000 + + +/** Maximum time(ms) to wait for mc thread suspend **/ +#define WLAN_WAIT_TIME_MCTHREAD_SUSPEND 1200 + +/** Maximum time(ms) to wait for target to be ready for suspend **/ +#define WLAN_WAIT_TIME_READY_TO_SUSPEND 2000 + + +/** Maximum time(ms) to wait for tdls add sta to complete **/ +#define WAIT_TIME_TDLS_ADD_STA 1500 + +/** Maximum time(ms) to wait for tdls del sta to complete **/ +#define WAIT_TIME_TDLS_DEL_STA 1500 + +/** Maximum time(ms) to wait for Link Establish Req to complete **/ +#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 + +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_TDLS_MGMT 11000 + +/** Maximum time(ms) to wait for tdls initiator to start direct communication **/ +#define WAIT_TIME_TDLS_INITIATOR 600 + +/* Scan Req Timeout */ +#define WLAN_WAIT_TIME_SCAN_REQ 100 + +#define MAX_NUMBER_OF_ADAPTERS 4 + +#define MAX_CFG_STRING_LEN 255 + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +/** Mac Address string **/ +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ADDRESS_STR_LEN 18 /* Including null terminator */ +#define MAX_GENIE_LEN 255 + +#define WLAN_CHIP_VERSION "WCNSS" + +#define hddLog(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args) +#define ENTER() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__) +#define EXIT() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Exit:%s", __func__) + +#define WLAN_HDD_GET_PRIV_PTR(__dev__) (hdd_adapter_t*)(netdev_priv((__dev__))) + +#define MAX_EXIT_ATTEMPTS_DURING_LOGP 20 + +#define MAX_NO_OF_2_4_CHANNELS 14 + +#define WLAN_HDD_PUBLIC_ACTION_FRAME 4 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET 24 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET 24 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET 0 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET 1 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET 2 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET 5 +#define WLAN_HDD_VENDOR_SPECIFIC_ACTION 0x09 +#define WLAN_HDD_WFA_OUI 0x506F9A +#define WLAN_HDD_WFA_P2P_OUI_TYPE 0x09 +#define WLAN_HDD_P2P_SOCIAL_CHANNELS 3 +#define WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN 1 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET 6 + +#define WLAN_HDD_IS_SOCIAL_CHANNEL(center_freq) \ +(((center_freq) == 2412) || ((center_freq) == 2437) || ((center_freq) == 2462)) + +#define WLAN_HDD_CHANNEL_IN_UNII_1_BAND(center_freq) \ +(((center_freq) == 5180 ) || ((center_freq) == 5200) \ +|| ((center_freq) == 5220) || ((center_freq) == 5240)) + +#ifdef WLAN_FEATURE_11W +#define WLAN_HDD_SA_QUERY_ACTION_FRAME 8 +#endif + +#define WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP 14 +#define WLAN_HDD_TDLS_ACTION_FRAME 12 +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK +#define HDD_WAKE_LOCK_DURATION 50 //in msecs +#endif + +#define WLAN_HDD_QOS_ACTION_FRAME 1 +#define WLAN_HDD_QOS_MAP_CONFIGURE 4 +#define HDD_SAP_WAKE_LOCK_DURATION 10000 //in msecs + +#define HDD_MOD_EXIT_SSR_MAX_RETRIES 60 + +/* Maximum number of interfaces allowed(STA, P2P Device, P2P Interfaces) */ +#ifndef WLAN_OPEN_P2P_INTERFACE +#define WLAN_MAX_INTERFACES 3 +#else +#define WLAN_MAX_INTERFACES 4 +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define GTK_OFFLOAD_ENABLE 0 +#define GTK_OFFLOAD_DISABLE 1 +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +#define HDD_PNO_SCAN_TIMERS_SET_ONE 1 +/* value should not be greater than PNO_MAX_SCAN_TIMERS */ +#define HDD_PNO_SCAN_TIMERS_SET_MULTIPLE 6 +#endif + +#define MAX_USER_COMMAND_SIZE 4096 + +#define HDD_MAC_ADDR_LEN 6 +#define HDD_SESSION_ID_ANY 50 //This should be same as CSR_SESSION_ID_ANY + +#define HDD_MIN_TX_POWER (-100) // minimum tx power +#define HDD_MAX_TX_POWER (+100) // maximum tx power + +typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN]; + +/* + * Generic asynchronous request/response support + * + * Many of the APIs supported by HDD require a call to SME to + * perform an action or to retrieve some data. In most cases SME + * performs the operation asynchronously, and will execute a provided + * callback function when the request has completed. In order to + * synchronize this the HDD API allocates a context which is then + * passed to SME, and which is then, in turn, passed back to the + * callback function when the operation completes. The callback + * function then sets a completion variable inside the context which + * the HDD API is waiting on. In an ideal world the HDD API would + * wait forever (or at least for a long time) for the response to be + * received and for the completion variable to be set. However in + * most cases these HDD APIs are being invoked in the context of a + * user space thread which has invoked either a cfg80211 API or a + * wireless extensions ioctl and which has taken the kernel rtnl_lock. + * Since this lock is used to synchronize many of the kernel tasks, we + * do not want to hold it for a long time. In addition we do not want + * to block user space threads (such as the wpa supplicant's main + * thread) for an extended time. Therefore we only block for a short + * time waiting for the response before we timeout. This means that + * it is possible for the HDD API to timeout, and for the callback to + * be invoked afterwards. In order for the callback function to + * determine if the HDD API is still waiting, a magic value is also + * stored in the shared context. Only if the context has a valid + * magic will the callback routine do any work. In order to further + * synchronize these activities a spinlock is used so that if any HDD + * API timeout coincides with its callback, the operations of the two + * threads will be serialized. + */ + +struct statsContext +{ + struct completion completion; + hdd_adapter_t *pAdapter; + unsigned int magic; +}; + +struct linkspeedContext +{ + struct completion completion; + hdd_adapter_t *pAdapter; + unsigned int magic; +}; + +extern spinlock_t hdd_context_lock; + +#define STATS_CONTEXT_MAGIC 0x53544154 //STAT +#define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI +#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR +#define SNR_CONTEXT_MAGIC 0x534E5200 //SNR +#define LINK_CONTEXT_MAGIC 0x4C494E4B //LINKSPEED +#define LINK_STATUS_MAGIC 0x4C4B5354 //LINKSTATUS(LNST) + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define HDD_BATCH_SCAN_VERSION (17) +#define HDD_SET_BATCH_SCAN_DEFAULT_FREQ (30)/*batch scan frequency default 30s*/ +#define HDD_SET_BATCH_SCAN_BEST_NETWORK (16)/*best network default value*/ +#define HDD_SET_BATCH_SCAN_DEFAULT_BAND (0)/*auto means both 2.4GHz and 5GHz*/ +#define HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY (1)/*only 2.4GHz band*/ +#define HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY (2)/*only 5GHz band*/ +#define HDD_SET_BATCH_SCAN_REQ_TIME_OUT (15000) /*Batch scan req timeout in ms*/ +#define HDD_GET_BATCH_SCAN_RSP_TIME_OUT (15000) /*Batch scan req timeout in ms*/ +#define HDD_BATCH_SCAN_AP_META_INFO_SIZE (150) /*AP meta info size in string*/ + +#endif + +#ifdef QCA_LL_TX_FLOW_CT +/* MAX OS Q block time value in msec + * Prevent from permanent stall, resume OS Q if timer expired */ +#define WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 1000 +#define WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME 100 +#define WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH 14 +#endif /* QCA_LL_TX_FLOW_CT */ + +#define HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390 +#define HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1 390 +#define HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780 +#define HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2 780 + +typedef struct hdd_tx_rx_stats_s +{ + // start_xmit stats + __u32 txXmitCalled; + __u32 txXmitDropped; + __u32 txXmitBackPressured; + __u32 txXmitQueued; + __u32 txXmitClassifiedAC[NUM_TX_QUEUES]; + __u32 txXmitDroppedAC[NUM_TX_QUEUES]; + __u32 txXmitBackPressuredAC[NUM_TX_QUEUES]; + __u32 txXmitQueuedAC[NUM_TX_QUEUES]; + // fetch_cbk stats + __u32 txFetched; + __u32 txFetchedAC[NUM_TX_QUEUES]; + __u32 txFetchEmpty; + __u32 txFetchLowResources; + __u32 txFetchDequeueError; + __u32 txFetchDequeued; + __u32 txFetchDequeuedAC[NUM_TX_QUEUES]; + __u32 txFetchDePressured; + __u32 txFetchDePressuredAC[NUM_TX_QUEUES]; + // complete_cbk_stats + __u32 txCompleted; + // flush stats + __u32 txFlushed; + __u32 txFlushedAC[NUM_TX_QUEUES]; + // Deque depressure stats + __u32 txDequeDePressured; + __u32 txDequeDePressuredAC[NUM_TX_QUEUES]; + // rx stats + __u32 rxChains; + __u32 rxPackets; + __u32 rxDropped; + __u32 rxDelivered; + __u32 rxRefused; + __u32 pkt_tx_count; //TX pkt Counter used for dynamic splitscan + __u32 pkt_rx_count; //RX pkt Counter used for dynamic splitscan + +} hdd_tx_rx_stats_t; + +#ifdef WLAN_FEATURE_11W +typedef struct hdd_pmf_stats_s +{ + uint8 numUnprotDeauthRx; + uint8 numUnprotDisassocRx; +} hdd_pmf_stats_t; +#endif + +typedef struct hdd_stats_s +{ + tCsrSummaryStatsInfo summary_stat; + tCsrGlobalClassAStatsInfo ClassA_stat; + tCsrGlobalClassBStatsInfo ClassB_stat; + tCsrGlobalClassCStatsInfo ClassC_stat; + tCsrGlobalClassDStatsInfo ClassD_stat; + tCsrPerStaStatsInfo perStaStats; + hdd_tx_rx_stats_t hddTxRxStats; +#ifdef WLAN_FEATURE_11W + hdd_pmf_stats_t hddPmfStats; +#endif +} hdd_stats_t; + +typedef enum +{ + HDD_ROAM_STATE_NONE, + + // Issuing a disconnect due to transition into low power states. + HDD_ROAM_STATE_DISCONNECTING_POWER, + + // move to this state when HDD sets a key with SME/CSR. Note this is + // an important state to get right because we will get calls into our SME + // callback routine for SetKey activity that we did not initiate! + HDD_ROAM_STATE_SETTING_KEY, +} HDD_ROAM_STATE; + +typedef enum +{ + eHDD_SUSPEND_NONE = 0, + eHDD_SUSPEND_DEEP_SLEEP, + eHDD_SUSPEND_STANDBY, +} hdd_ps_state_t; + +typedef struct roaming_info_s +{ + HDD_ROAM_STATE roamingState; + vos_event_t roamingEvent; + + tWlanHddMacAddr bssid; + tWlanHddMacAddr peerMac; + tANI_U32 roamId; + eRoamCmdStatus roamStatus; + v_BOOL_t deferKeyComplete; + +} roaming_info_t; + +#ifdef FEATURE_WLAN_WAPI +/* Define WAPI macros for Length, BKID count etc*/ +#define MAX_WPI_KEY_LENGTH 16 +#define MAX_NUM_PN 16 +#define MAC_ADDR_LEN 6 +#define MAX_ADDR_INDEX 12 +#define MAX_NUM_AKM_SUITES 16 +#define MAX_NUM_UNI_SUITES 16 +#define MAX_NUM_BKIDS 16 + +/** WAPI AUTH mode definition */ +enum _WAPIAuthMode +{ + WAPI_AUTH_MODE_OPEN = 0, + WAPI_AUTH_MODE_PSK = 1, + WAPI_AUTH_MODE_CERT +} __packed; +typedef enum _WAPIAuthMode WAPIAuthMode; + +/** WAPI Work mode structure definition */ +#define WZC_ORIGINAL 0 +#define WAPI_EXTENTION 1 + +struct _WAPI_FUNCTION_MODE +{ + unsigned char wapiMode; +}__packed; + +typedef struct _WAPI_FUNCTION_MODE WAPI_FUNCTION_MODE; + +typedef struct _WAPI_BKID +{ + v_U8_t bkid[16]; +}WAPI_BKID, *pWAPI_BKID; + +/** WAPI Association information structure definition */ +struct _WAPI_AssocInfo +{ + v_U8_t elementID; + v_U8_t length; + v_U16_t version; + v_U16_t akmSuiteCount; + v_U32_t akmSuite[MAX_NUM_AKM_SUITES]; + v_U16_t unicastSuiteCount; + v_U32_t unicastSuite[MAX_NUM_UNI_SUITES]; + v_U32_t multicastSuite; + v_U16_t wapiCability; + v_U16_t bkidCount; + WAPI_BKID bkidList[MAX_NUM_BKIDS]; +} __packed; + +typedef struct _WAPI_AssocInfo WAPI_AssocInfo; +typedef struct _WAPI_AssocInfo *pWAPI_IEAssocInfo; + +/** WAPI KEY Type definition */ +enum _WAPIKeyType +{ + PAIRWISE_KEY, //0 + GROUP_KEY //1 +}__packed; +typedef enum _WAPIKeyType WAPIKeyType; + +/** WAPI KEY Direction definition */ +enum _KEY_DIRECTION +{ + None, + Rx, + Tx, + Rx_Tx +}__packed; + +typedef enum _KEY_DIRECTION WAPI_KEY_DIRECTION; + +/* WAPI KEY structure definition */ +struct WLAN_WAPI_KEY +{ + WAPIKeyType keyType; + WAPI_KEY_DIRECTION keyDirection; /*reserved for future use*/ + v_U8_t keyId; + v_U8_t addrIndex[MAX_ADDR_INDEX]; /*reserved for future use*/ + int wpiekLen; + v_U8_t wpiek[MAX_WPI_KEY_LENGTH]; + int wpickLen; + v_U8_t wpick[MAX_WPI_KEY_LENGTH]; + v_U8_t pn[MAX_NUM_PN]; /*reserved for future use*/ +}__packed; + +typedef struct WLAN_WAPI_KEY WLAN_WAPI_KEY; +typedef struct WLAN_WAPI_KEY *pWLAN_WAPI_KEY; + +#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define WPA_GET_BE24(a) ((u32) ( (a[0] << 16) | (a[1] << 8) | a[2])) +#define WLAN_EID_WAPI 68 +#define WAPI_PSK_AKM_SUITE 0x02721400 +#define WAPI_CERT_AKM_SUITE 0x01721400 + +/* WAPI BKID List structure definition */ +struct _WLAN_BKID_LIST +{ + v_U32_t length; + v_U32_t BKIDCount; + WAPI_BKID BKID[1]; +}__packed; + +typedef struct _WLAN_BKID_LIST WLAN_BKID_LIST; +typedef struct _WLAN_BKID_LIST *pWLAN_BKID_LIST; + + +/* WAPI Information structure definition */ +struct hdd_wapi_info_s +{ + v_U32_t nWapiMode; + v_BOOL_t fIsWapiSta; + v_MACADDR_t cachedMacAddr; + v_UCHAR_t wapiAuthMode; +}__packed; +typedef struct hdd_wapi_info_s hdd_wapi_info_t; +#endif /* FEATURE_WLAN_WAPI */ + +typedef struct beacon_data_s { + u8 *head, *tail; + int head_len, tail_len; + int dtim_period; +} beacon_data_t; + +typedef enum device_mode +{ /* MAINTAIN 1 - 1 CORRESPONDENCE WITH tVOS_CON_MODE*/ + WLAN_HDD_INFRA_STATION, + WLAN_HDD_SOFTAP, + WLAN_HDD_P2P_CLIENT, + WLAN_HDD_P2P_GO, + WLAN_HDD_MONITOR, + WLAN_HDD_FTM, + WLAN_HDD_IBSS, + WLAN_HDD_P2P_DEVICE +}device_mode_t; + +typedef enum rem_on_channel_request_type +{ + REMAIN_ON_CHANNEL_REQUEST, + OFF_CHANNEL_ACTION_TX, +}rem_on_channel_request_type_t; + +/* Thermal mitigation Level Enum Type */ +typedef enum +{ + WLAN_HDD_TM_LEVEL_0, + WLAN_HDD_TM_LEVEL_1, + WLAN_HDD_TM_LEVEL_2, + WLAN_HDD_TM_LEVEL_3, + WLAN_HDD_TM_LEVEL_4, + WLAN_HDD_TM_LEVEL_MAX +} WLAN_TmLevelEnumType; + +/* Driver Action based on thermal mitigation level structure */ +typedef struct +{ + v_BOOL_t ampduEnable; + v_BOOL_t enterImps; + v_U32_t txSleepDuration; + v_U32_t txOperationDuration; + v_U32_t txBlockFrameCountThreshold; +} hdd_tmLevelAction_t; + +/* Thermal Mitigation control context structure */ +typedef struct +{ + WLAN_TmLevelEnumType currentTmLevel; + hdd_tmLevelAction_t tmAction; + vos_timer_t txSleepTimer; + struct mutex tmOperationLock; + vos_event_t setTmDoneEvent; + v_U32_t txFrameCount; + v_TIME_t lastblockTs; + v_TIME_t lastOpenTs; + struct netdev_queue *blockedQueue; + v_BOOL_t qBlocked; +} hdd_thermal_mitigation_info_t; + +typedef struct action_pkt_buffer +{ + tANI_U8* frame_ptr; + tANI_U32 frame_length; + tANI_U16 freq; +}action_pkt_buffer_t; + +typedef struct hdd_remain_on_chan_ctx +{ + struct net_device *dev; + struct ieee80211_channel chan; + enum nl80211_channel_type chan_type; + unsigned int duration; + u64 cookie; + rem_on_channel_request_type_t rem_on_chan_request; + v_U32_t p2pRemOnChanTimeStamp; + vos_timer_t hdd_remain_on_chan_timer; + action_pkt_buffer_t action_pkt_buff; + v_BOOL_t hdd_remain_on_chan_cancel_in_progress; +}hdd_remain_on_chan_ctx_t; + +/* RoC Request entry */ +typedef struct hdd_roc_req +{ + hdd_list_node_t node; /* MUST be first element */ + hdd_adapter_t *pAdapter; + hdd_remain_on_chan_ctx_t *pRemainChanCtx; +}hdd_roc_req_t; + +typedef enum{ + HDD_IDLE, + HDD_PD_REQ_ACK_PENDING, + HDD_GO_NEG_REQ_ACK_PENDING, + HDD_INVALID_STATE, +}eP2PActionFrameState; + +typedef enum { + WLAN_HDD_GO_NEG_REQ, + WLAN_HDD_GO_NEG_RESP, + WLAN_HDD_GO_NEG_CNF, + WLAN_HDD_INVITATION_REQ, + WLAN_HDD_INVITATION_RESP, + WLAN_HDD_DEV_DIS_REQ, + WLAN_HDD_DEV_DIS_RESP, + WLAN_HDD_PROV_DIS_REQ, + WLAN_HDD_PROV_DIS_RESP, +}tActionFrmType; + +typedef struct hdd_cfg80211_state_s +{ + tANI_U16 current_freq; + u64 action_cookie; + tANI_U8 *buf; + size_t len; + struct sk_buff *skb; + hdd_remain_on_chan_ctx_t* remain_on_chan_ctx; + struct mutex remain_on_chan_ctx_lock; + eP2PActionFrameState actionFrmState; +}hdd_cfg80211_state_t; + + +typedef enum{ + HDD_SSR_NOT_REQUIRED, + HDD_SSR_REQUIRED, + HDD_SSR_DISABLED, +}e_hdd_ssr_required; + +struct hdd_station_ctx +{ + /** Handle to the Wireless Extension State */ + hdd_wext_state_t WextState; + +#ifdef FEATURE_WLAN_TDLS + tdlsCtx_t *pHddTdlsCtx; +#endif + + + /**Connection information*/ + connection_info_t conn_info; + + roaming_info_t roam_info; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + int ft_carrier_on; +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + tSirGtkOffloadParams gtkOffloadReqParams; +#endif + /*Increment whenever ibss New peer joins and departs the network */ + int ibss_sta_generation; + + /* Indication of wep/wpa-none keys installation */ + v_BOOL_t ibss_enc_key_installed; + + /*Save the wep/wpa-none keys*/ + tCsrRoamSetKey ibss_enc_key; + v_BOOL_t hdd_ReassocScenario; + + /* STA ctx debug variables */ + int staDebugState; +}; + +#define BSS_STOP 0 +#define BSS_START 1 +typedef struct hdd_hostapd_state_s +{ + int bssState; + vos_event_t vosEvent; + VOS_STATUS vosStatus; + v_BOOL_t bCommit; + +} hdd_hostapd_state_t; + + +/* + * Per station structure kept in HDD for multiple station support for SoftAP +*/ +typedef struct { + /** The station entry is used or not */ + v_BOOL_t isUsed; + + /** Station ID reported back from HAL (through SAP). Broadcast + * uses station ID zero by default in both libra and volans. */ + v_U8_t ucSTAId; + + /** MAC address of the station */ + v_MACADDR_t macAddrSTA; + + /** Current Station state so HDD knows how to deal with packet + * queue. Most recent states used to change TL STA state. */ + WLANTL_STAStateType tlSTAState; + + /** Transmit queues for each AC (VO,VI,BE etc). */ + hdd_list_t wmm_tx_queue[NUM_TX_QUEUES]; + + /** Might need to differentiate queue depth in contention case */ + v_U16_t aTxQueueDepth[NUM_TX_QUEUES]; + + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + + /**Track whether 3/4th of resources are used */ + v_BOOL_t vosLowResource; + + /** Track QoS status of station */ + v_BOOL_t isQosEnabled; + + /** The station entry for which Deauth is in progress */ + v_BOOL_t isDeauthInProgress; +} hdd_station_info_t; + +struct hdd_ap_ctx_s +{ + hdd_hostapd_state_t HostapdState; + + // Memory differentiation mode is enabled + //v_U16_t uMemoryDiffThreshold; + //v_U8_t uNumActiveAC; + //v_U8_t uActiveACMask; + //v_U8_t aTxQueueLimit[NUM_TX_QUEUES]; + + /** Packet Count to update uNumActiveAC and uActiveACMask */ + //v_U16_t uUpdatePktCount; + + /** Station ID assigned after BSS starts */ + v_U8_t uBCStaId; + + v_U8_t uPrivacy; // The privacy bits of configuration + + tSirWPSPBCProbeReq WPSPBCProbeReq; + + tsap_Config_t sapConfig; + + struct semaphore semWpsPBCOverlapInd; + + v_BOOL_t apDisableIntraBssFwd; + + vos_timer_t hdd_ap_inactivity_timer; + + v_U8_t operatingChannel; + + v_BOOL_t uIsAuthenticated; + + eCsrEncryptionType ucEncryptType; + + //This will point to group key data, if it is received before start bss. + tCsrRoamSetKey groupKey; + // This will have WEP key data, if it is received before start bss + tCsrRoamSetKey wepKey[CSR_MAX_NUM_KEY]; + + beacon_data_t *beacon; + + v_BOOL_t bApActive; +#ifdef WLAN_FEATURE_MBSSID + /* SAP Context */ + v_PVOID_t sapContext; +#endif + v_BOOL_t dfs_cac_block_tx; +}; + +struct hdd_mon_ctx_s +{ + hdd_adapter_t *pAdapterForTx; +}; + +typedef struct hdd_scaninfo_s +{ + /* The scan id */ + v_U32_t scanId; + + /* The scan pending */ + v_U32_t mScanPending; + + /* Counter for mScanPending so that the scan pending + error log is not printed for more than 5 times */ + v_U32_t mScanPendingCounter; + + /* Client Wait Scan Result */ + v_U32_t waitScanResult; + + /* Additional IE for scan */ + tSirAddie scanAddIE; + + /* Scan mode*/ + tSirScanType scan_mode; + + /* Scan Completion Event */ + struct completion scan_req_completion_event; + + /* completion variable for abortscan */ + struct completion abortscan_event_var; + + vos_event_t scan_finished_event; + + hdd_scan_pending_option_e scan_pending_option; + +#ifdef FEATURE_WLAN_SCAN_PNO + /* The PNO scan pending */ + v_BOOL_t mPnoScanPending; +#endif + +}hdd_scaninfo_t; + +#define WLAN_HDD_MAX_MC_ADDR_LIST 10 + +#ifdef WLAN_FEATURE_PACKET_FILTERING +typedef struct multicast_addr_list +{ + v_U8_t isFilterApplied; + v_U8_t mc_cnt; + v_U8_t addr[WLAN_HDD_MAX_MC_ADDR_LIST][ETH_ALEN]; +} t_multicast_add_list; +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/* Batch scan response AP info */ +typedef struct +{ + /*Batch ID*/ + tANI_U32 batchId; + /*is it last AP in GET BATCH SCAN RSP*/ + v_BOOL_t isLastAp; + /*BSSID*/ + tANI_U8 bssid[SIR_MAC_ADDR_LEN]; + /*SSID*/ + tANI_U8 ssid[SIR_MAX_SSID_SIZE + 1]; + /*Channel*/ + tANI_U8 ch; + /*RSSI or Level*/ + tANI_S8 rssi; + /*Age*/ + tANI_U32 age; +}tHDDbatchScanRspApInfo; + +/*Batch scan response list*/ +struct tHDDBatchScanRspList +{ + tHDDbatchScanRspApInfo ApInfo; + struct tHDDBatchScanRspList *pNext; +}; + +typedef struct tHDDBatchScanRspList tHddBatchScanRsp; + +/*Batch Scan state*/ +typedef enum +{ + /*Batch scan is started this means WLS_BATCHING SET command is issued + from framework*/ + eHDD_BATCH_SCAN_STATE_STARTED, + + /*Batch scan is stopped this means WLS_BATCHING STOP command is issued + from framework*/ + eHDD_BATCH_SCAN_STATE_STOPPED, + + eHDD_BATCH_SCAN_STATE_MAX, +} eHDD_BATCH_SCAN_STATE; + +#endif + +#define WLAN_HDD_ADAPTER_MAGIC 0x574c414e //ASCII "WLAN" + +struct hdd_adapter_s +{ + void *pHddCtx; + + device_mode_t device_mode; + + /** Handle to the network device */ + struct net_device *dev; + + /** IPv4 notifier callback for handling ARP offload on change in IP */ + struct notifier_block ipv4_notifier; + bool ipv4_notifier_registered; + struct work_struct ipv4NotifierWorkQueue; +#ifdef WLAN_NS_OFFLOAD + /** IPv6 notifier callback for handling NS offload on change in IP */ + struct notifier_block ipv6_notifier; + bool ipv6_notifier_registered; + struct work_struct ipv6NotifierWorkQueue; +#endif + + //TODO Move this to sta Ctx + struct wireless_dev wdev ; + struct cfg80211_scan_request *request ; + + /** ops checks if Opportunistic Power Save is Enable or Not + * ctw stores ctWindow value once we receive Opps command from + * wpa_supplicant then using ctWindow value we need to Enable + * Opportunistic Power Save + */ + tANI_U8 ops; + tANI_U32 ctw; + + /** Current MAC Address for the adapter */ + v_MACADDR_t macAddressCurrent; + + /**Event Flags*/ + unsigned long event_flags; + + /**Device TX/RX statistics*/ + struct net_device_stats stats; + /** HDD statistics*/ + hdd_stats_t hdd_stats; + /** linkspeed statistics */ + tSirLinkSpeedInfo ls_stats; + /**Mib information*/ + sHddMib_t hdd_mib; + + tANI_U8 sessionId; + + /* Completion variable for session close */ + struct completion session_close_comp_var; + + /* Completion variable for session open */ + struct completion session_open_comp_var; + + //TODO: move these to sta ctx. These may not be used in AP + /** completion variable for disconnect callback */ + struct completion disconnect_comp_var; + + /** Completion of change country code */ + struct completion change_country_code; + + /* completion variable for Linkup Event */ + struct completion linkup_event_var; + + /* completion variable for cancel remain on channel Event */ + struct completion cancel_rem_on_chan_var; + + /* completion variable for off channel remain on channel Event */ + struct completion offchannel_tx_event; + /* Completion variable for action frame */ + struct completion tx_action_cnf_event; + /* Completion variable for remain on channel ready */ + struct completion rem_on_chan_ready_event; + + /* Completion variable for Upper Layer Authentication */ + struct completion ula_complete; + +#ifdef FEATURE_WLAN_TDLS + struct completion tdls_add_station_comp; + struct completion tdls_del_station_comp; + struct completion tdls_mgmt_comp; + struct completion tdls_link_establish_req_comp; + eHalStatus tdlsAddStaStatus; +#endif + + /* Track whether the linkup handling is needed */ + v_BOOL_t isLinkUpSvcNeeded; + + /* Mgmt Frames TX completion status code */ + tANI_U32 mgmtTxCompletionStatus; + +/************************************************************* + * Tx Queues + */ + /** Transmit queues for each AC (VO,VI,BE etc) */ + hdd_list_t wmm_tx_queue[NUM_TX_QUEUES]; + /**Track whether VOS is in a low resource state*/ + v_BOOL_t isVosOutOfResource; + + /**Track whether 3/4th of resources are used */ + v_BOOL_t isVosLowResource; + + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t isTxSuspended[NUM_TX_QUEUES]; + + /** WMM Status */ + hdd_wmm_status_t hddWmmStatus; +/************************************************************* + */ +/************************************************************* + * TODO - Remove it later + */ + /** Multiple station supports */ + /** Per-station structure */ + spinlock_t staInfo_lock; //To protect access to station Info + hdd_station_info_t aStaInfo[WLAN_MAX_STA_COUNT]; + //v_U8_t uNumActiveStation; + + v_U16_t aTxQueueLimit[NUM_TX_QUEUES]; +/************************************************************* + */ + +#ifdef FEATURE_WLAN_WAPI + hdd_wapi_info_t wapi_info; +#endif + + v_S7_t rssi; +#ifdef WLAN_FEATURE_LPSS + v_BOOL_t rssi_send; +#endif + + tANI_U8 snr; + + struct work_struct monTxWorkQueue; + struct sk_buff *skb_to_tx; + + union { + hdd_station_ctx_t station; + hdd_ap_ctx_t ap; + hdd_mon_ctx_t monitor; + }sessionCtx; + + hdd_cfg80211_state_t cfg80211State; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + t_multicast_add_list mc_addr_list; +#endif + + //Magic cookie for adapter sanity verification + v_U32_t magic; + v_BOOL_t higherDtimTransition; + v_BOOL_t survey_idx; + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*Completion variable for set batch scan request*/ + struct completion hdd_set_batch_scan_req_var; + /*Completion variable for get batch scan request*/ + struct completion hdd_get_batch_scan_req_var; + /*HDD batch scan lock*/ + struct mutex hdd_batch_scan_lock; + /*HDD set batch scan request*/ + tSirSetBatchScanReq hddSetBatchScanReq; + /*HDD set batch scan response*/ + tSirSetBatchScanRsp hddSetBatchScanRsp; + /*HDD stop batch scan indication*/ + tSirStopBatchScanInd hddStopBatchScanInd; + /*HDD get batch scan request*/ + tSirTriggerBatchScanResultInd hddTriggerBatchScanResultInd; + /* Batched scan response queue: new batch scan results added at the tail + and old batch scan results are deleted from head */ + tHddBatchScanRsp *pBatchScanRsp; + /*No of scans in batch scan rsp(MSCAN)*/ + v_U32_t numScanList; + /*isTruncated = 1 batch scan rsp is truncated + isTruncated = 0 batch scan rsp is complete*/ + v_BOOL_t isTruncated; + /*Wait for get batch scan response from FW or not*/ + volatile v_BOOL_t hdd_wait_for_get_batch_scan_rsp; + /*Wait for set batch scan response from FW or not*/ + volatile v_BOOL_t hdd_wait_for_set_batch_scan_rsp; + /*Previous batch scan ID*/ + v_U32_t prev_batch_id; + /*Batch scan state*/ + eHDD_BATCH_SCAN_STATE batchScanState; +#endif + + hdd_scaninfo_t scan_info; +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + tAniTrafStrmMetrics tsmStats; +#endif + /* Flag to ensure PSB is configured through framework */ + v_U8_t psbChanged; + /* UAPSD psb value configured through framework */ + v_U8_t configuredPsb; +#ifdef IPA_OFFLOAD + void *ipa_context; +#endif +#ifdef WLAN_FEATURE_MBSSID + /* this need to be adapter struct since adapter type can be dyn changed */ + mbssid_sap_dyn_ini_config_t sap_dyn_ini_cfg; +#endif + struct work_struct scan_block_work; +#ifdef MSM_PLATFORM + unsigned long prev_rx_packets; + unsigned long prev_tx_packets; + int connection; +#endif + v_BOOL_t is_roc_inprogress; + +#ifdef QCA_LL_TX_FLOW_CT + vos_timer_t tx_flow_control_timer; + v_BOOL_t tx_flow_timer_initialized; + unsigned int tx_flow_low_watermark; + unsigned int tx_flow_high_watermark_offset; +#endif /* QCA_LL_TX_FLOW_CT */ + v_BOOL_t offloads_configured; + + /* DSCP to UP QoS Mapping */ + sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1]; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + v_BOOL_t isLinkLayerStatsSet; +#endif + v_U8_t linkStatus; + + /* Time stamp for last completed RoC request */ + v_TIME_t lastRocTs; + + /* work queue to defer the back to back p2p_listen */ + struct delayed_work roc_work; +}; + +#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) +#define WLAN_HDD_GET_AP_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.ap) +#define WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter) (&(pAdapter)->sessionCtx.station.WextState) +#define WLAN_HDD_GET_CTX(pAdapter) ((hdd_context_t*)pAdapter->pHddCtx) +#define WLAN_HDD_GET_HAL_CTX(pAdapter) (((hdd_context_t*)(pAdapter->pHddCtx))->hHal) +#define WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter) (&(pAdapter)->sessionCtx.ap.HostapdState) +#define WLAN_HDD_GET_CFG_STATE_PTR(pAdapter) (&(pAdapter)->cfg80211State) +#ifdef WLAN_FEATURE_MBSSID +#define WLAN_HDD_GET_SAP_CTX_PTR(pAdapter) (pAdapter->sessionCtx.ap.sapContext) +#endif +#ifdef FEATURE_WLAN_TDLS +#define WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter) \ + (((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && \ + (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode)) ? 0 : 1) +#define WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter) \ + ((WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter)) ? \ + (tdlsCtx_t*)(pAdapter)->sessionCtx.station.pHddTdlsCtx : NULL) +#endif + +/* Set mac address locally administered bit */ +#define WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macaddr) (macaddr[0] &= 0xFD) + +typedef struct hdd_adapter_list_node +{ + hdd_list_node_t node; // MUST be first element + hdd_adapter_t *pAdapter; +}hdd_adapter_list_node_t; + +typedef struct hdd_priv_data_s +{ + tANI_U8 *buf; + int used_len; + int total_len; +}hdd_priv_data_t; + +#ifdef FEATURE_GREEN_AP + +#define GREEN_AP_PS_ON_TIME (0) +#define GREEN_AP_PS_DELAY_TIME (20) + +/* + * Green-AP power save state + */ +typedef enum +{ + GREEN_AP_PS_IDLE_STATE = 1, + GREEN_AP_PS_OFF_STATE, + GREEN_AP_PS_WAIT_STATE, + GREEN_AP_PS_ON_STATE, +}hdd_green_ap_ps_state_t; + +typedef enum +{ + GREEN_AP_PS_START_EVENT = 1, + GREEN_AP_PS_STOP_EVENT, + GREEN_AP_ADD_STA_EVENT, + GREEN_AP_DEL_STA_EVENT, + GREEN_AP_PS_ON_EVENT, + GREEN_AP_PS_WAIT_EVENT, +}hdd_green_ap_event_t; + +typedef struct +{ + uint64_t ps_on_count; + v_TIME_t ps_on_prev_ticks; + v_TIME_t ps_on_ticks; + + uint64_t ps_off_count; + v_TIME_t ps_off_prev_ticks; + v_TIME_t ps_off_ticks; + +}hdd_green_ap_stats; + +/* + * Green-AP context + */ +typedef struct +{ + v_CONTEXT_t pHddContext; + + v_U8_t ps_enable; + v_U32_t ps_on_time; + v_U32_t ps_delay_time; + v_U32_t num_nodes; + + hdd_green_ap_ps_state_t ps_state; + hdd_green_ap_event_t ps_event; + + vos_timer_t ps_timer; + + hdd_green_ap_stats stats; + +}hdd_green_ap_ctx_t; +#endif /* FEATURE_GREEN_AP */ + +#define MAX_MOD_LOGLEVEL 10 +typedef struct +{ + v_U8_t enable; + v_U8_t dl_type; + v_U8_t dl_report; + v_U8_t dl_loglevel; + v_U8_t index; + v_U32_t dl_mod_loglevel[MAX_MOD_LOGLEVEL]; + +}fw_log_info; + +/** Adapter stucture definition */ + +struct hdd_context_s +{ + /** Global VOS context */ + v_CONTEXT_t pvosContext; + + /** HAL handle...*/ + tHalHandle hHal; + + struct wiphy *wiphy ; + //TODO Remove this from here. + + hdd_list_t hddAdapters; //List of adapters + + /* One per STA: 1 for BCMC_STA_ID, 1 for each SAP_SELF_STA_ID, 1 for WDS_STAID */ + hdd_adapter_t *sta_to_adapter[WLAN_MAX_STA_COUNT + VOS_MAX_NO_OF_SAP_MODE + 2]; //One per sta. For quick reference. + + /** Pointer for firmware image data */ + const struct firmware *fw; + + /** Pointer for configuration data */ + const struct firmware *cfg; + + /** Pointer for nv data */ + const struct firmware *nv; + + /** Pointer to the parent device */ + struct device *parent_dev; + + /** Config values read from qcom_cfg.ini file */ + hdd_config_t *cfg_ini; + wlan_hdd_ftm_status_t ftm; + /** completion variable for full power callback */ + struct completion full_pwr_comp_var; + /** completion variable for Request BMPS callback */ + struct completion req_bmps_comp_var; + + /** completion variable for standby callback */ + struct completion standby_comp_var; + + /* Completion variable to indicate Rx Thread Suspended */ + struct completion rx_sus_event_var; + + /* Completion variable to indicate Tx Thread Suspended */ + struct completion tx_sus_event_var; + + /* Completion variable to indicate Mc Thread Suspended */ + struct completion mc_sus_event_var; + + struct completion reg_init; + + v_BOOL_t isWlanSuspended; + + v_BOOL_t isTxThreadSuspended; + + v_BOOL_t isMcThreadSuspended; + + v_BOOL_t isRxThreadSuspended; + +#ifdef QCA_CONFIG_SMP + v_BOOL_t isTlshimRxThreadSuspended; +#endif + + volatile v_BOOL_t isLogpInProgress; + + v_BOOL_t isLoadInProgress; + + v_BOOL_t isUnloadInProgress; + + /**Track whether driver has been suspended.*/ + hdd_ps_state_t hdd_ps_state; + + /* Track whether Mcast/Bcast Filter is enabled.*/ + v_BOOL_t hdd_mcastbcast_filter_set; + + /* Track whether ignore DTIM is enabled*/ + v_BOOL_t hdd_ignore_dtim_enabled; + v_U32_t hdd_actual_ignore_DTIM_value; + v_U32_t hdd_actual_LI_value; + + + v_BOOL_t hdd_wlan_suspended; + v_BOOL_t suspended; + + spinlock_t filter_lock; + + /* Lock to avoid race condition during start/stop bss */ + struct mutex sap_lock; + + /** ptt Process ID*/ + v_SINT_t ptt_pid; +#ifdef WLAN_KD_READY_NOTIFIER + v_BOOL_t kd_nl_init; +#endif /* WLAN_KD_READY_NOTIFIER */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + /* OEM App registered or not */ + v_BOOL_t oem_app_registered; + + /* OEM App Process ID */ + v_SINT_t oem_pid; +#endif + + v_U8_t change_iface; + + /** Concurrency Parameters*/ + tVOS_CONCURRENCY_MODE concurrency_mode; + + v_U8_t no_of_open_sessions[VOS_MAX_NO_OF_MODE]; + v_U8_t no_of_active_sessions[VOS_MAX_NO_OF_MODE]; + + /* Number of times riva restarted */ + v_U32_t hddRivaResetStats; + + /* Can we allow AMP connection right now*/ + v_BOOL_t isAmpAllowed; + + /** P2P Device MAC Address for the adapter */ + v_MACADDR_t p2pDeviceAddress; + + /* Thermal mitigation information */ + hdd_thermal_mitigation_info_t tmInfo; + +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_t rx_wake_lock; +#endif + + /* + * Framework initiated driver restarting + * hdd_reload_timer : Restart retry timer + * isRestartInProgress: Restart in progress + * hdd_restart_retries: Restart retries + * + */ + vos_timer_t hdd_restart_timer; + atomic_t isRestartInProgress; + u_int8_t hdd_restart_retries; + + /*is_dyanmic_channel_range_set is set to 1 when Softap_set_channel_range + is invoked*/ + v_BOOL_t is_dynamic_channel_range_set; + + vos_wake_lock_t sap_wake_lock; + +#ifdef FEATURE_WLAN_TDLS + eTDLSSupportMode tdls_mode; + eTDLSSupportMode tdls_mode_last; + tdlsConnInfo_t tdlsConnInfo[HDD_MAX_NUM_TDLS_STA]; + /* maximum TDLS station number allowed upon runtime condition */ + tANI_U16 max_num_tdls_sta; + /* TDLS peer connected count */ + tANI_U16 connected_peer_count; + tdls_scan_context_t tdls_scan_ctxt; + /* Lock to avoid race condition during TDLS operations*/ + struct mutex tdls_lock; + tANI_U8 tdls_off_channel; + tANI_U16 tdls_channel_offset; +#endif + +#ifdef IPA_OFFLOAD + void *hdd_ipa; +#ifdef IPA_UC_OFFLOAD + /* CE resources */ + v_U32_t ce_sr_base_paddr; + v_U32_t ce_sr_ring_size; + v_U32_t ce_reg_paddr; + + /* WLAN TX:IPA->WLAN */ + v_U32_t tx_comp_ring_base_paddr; + v_U32_t tx_comp_ring_size; + v_U32_t tx_num_alloc_buffer; + + /* WLAN RX:WLAN->IPA */ + v_U32_t rx_rdy_ring_base_paddr; + v_U32_t rx_rdy_ring_size; + v_U32_t rx_proc_done_idx_paddr; + + /* IPA UC doorbell registers paddr */ + v_U32_t tx_comp_doorbell_paddr; + v_U32_t rx_ready_doorbell_paddr; +#endif /* IPA_UC_OFFLOAD */ +#endif + /* MC/BC Filter state variable + * This always contains the value that is currently + * configured + * */ + v_U8_t configuredMcastBcastFilter; + + v_U8_t sus_res_mcastbcast_filter; + + v_BOOL_t sus_res_mcastbcast_filter_valid; + + /* debugfs entry */ + struct dentry *debugfs_phy; + + /* Use below lock to protect access to isSchedScanUpdatePending + * since it will be accessed in two different contexts. + */ + spinlock_t schedScan_lock; + + // Flag keeps track of wiphy suspend/resume + v_BOOL_t isWiphySuspended; + + // Indicates about pending sched_scan results + v_BOOL_t isSchedScanUpdatePending; + /* + * TX_rx_pkt_count_timer + */ + vos_timer_t tx_rx_trafficTmr; + +#ifdef MSM_PLATFORM + /* DDR bus bandwidth compute timer + */ + vos_timer_t bus_bw_timer; + int cur_vote_level; + spinlock_t bus_bw_lock; + int cur_rx_level; + uint64_t prev_rx; +#endif + + v_U8_t issplitscan_enabled; + + /* VHT80 allowed*/ + v_BOOL_t isVHT80Allowed; + + struct completion ready_to_suspend; + /* defining the solution type */ + v_U32_t target_type; + + /* defining the firmware version */ + v_U32_t target_fw_version; + v_U32_t dfs_radar_found; + + /* defining the chip/rom version */ + v_U32_t target_hw_version; + /* defining the chip/rom revision */ + v_U32_t target_hw_revision; + /* chip/rom name */ + const char *target_hw_name; + struct regulatory reg; +#ifdef FEATURE_WLAN_CH_AVOID + v_U16_t unsafe_channel_count; + v_U16_t unsafe_channel_list[NUM_20MHZ_RF_CHANNELS]; +#endif /* FEATURE_WLAN_CH_AVOID */ + + v_U8_t max_intf_count; + v_U8_t current_intf_count; +#ifdef WLAN_FEATURE_LPSS + v_U8_t lpss_support; +#endif + + tSirScanType ioctl_scan_mode; + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + adf_os_work_t sta_ap_intf_check_work; +#endif + + v_U8_t dev_dfs_cac_status; + + v_BOOL_t btCoexModeSet; +#ifdef FEATURE_GREEN_AP + hdd_green_ap_ctx_t *green_ap_ctx; +#endif + fw_log_info fw_log_settings; +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + vos_timer_t skip_acs_scan_timer; + v_U8_t skip_acs_scan_status; +#endif + + vos_wake_lock_t sap_dfs_wakelock; + atomic_t sap_dfs_ref_cnt; + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + v_BOOL_t is_extwow_app_type1_param_set; + v_BOOL_t is_extwow_app_type2_param_set; + v_BOOL_t ext_wow_should_suspend; + struct completion ready_to_extwow; +#endif + + /* Time since boot up to WiFi turn ON (in micro seconds) */ + v_U64_t wifi_turn_on_time_since_boot; + + /* number of rf chains supported by target */ + uint32_t num_rf_chains; + + /* Is htTxSTBC supported by target */ + uint8_t ht_tx_stbc_supported; + /* RoC request queue and work */ + struct work_struct rocReqWork; + hdd_list_t hdd_roc_req_q; +}; + +/*--------------------------------------------------------------------------- + Function declarations and documentation + -------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void wlan_hdd_check_sta_ap_concurrent_ch_intf(void *sta_pAdapter); +#endif + +VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode); + +VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode, + hdd_adapter_list_node_t** pNextAdapterNode); + +VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode); + +VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, + const char* name, tSirMacAddr macAddr, + tANI_U8 rtnl_held ); +VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held ); +VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ); +void hdd_dump_concurrency_info(hdd_context_t *pHddCtx); +hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ); +hdd_adapter_t * hdd_get_adapter_by_vdev( hdd_context_t *pHddCtx, + tANI_U32 vdev_id ); +hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, tSirMacAddr macAddr ); +hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ); +hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ); +void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession); +void hdd_set_station_ops( struct net_device *pWlanDev ); +tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx); +void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr); +v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode ); + +void hdd_set_conparam ( v_UINT_t newParam ); +tVOS_CON_MODE hdd_get_conparam( void ); + +void wlan_hdd_enable_deepsleep(v_VOID_t * pVosContext); +v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx); +v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx); +void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId, + eCsrAbortReason reason); +void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); +void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); + +void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id); +void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter); +void hdd_prevent_suspend(void); +void hdd_allow_suspend(void); +void hdd_prevent_suspend_timeout(v_U32_t timeout); +bool hdd_is_ssr_required(void); +void hdd_set_ssr_required(e_hdd_ssr_required value); + +VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx); +VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type); + +void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy); +VOS_STATUS hdd_setIbssPowerSaveParams(hdd_adapter_t *pAdapter); +void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy); +VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx); +void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx); +void hdd_set_pwrparams(hdd_context_t *pHddCtx); +void hdd_reset_pwrparams(hdd_context_t *pHddCtx); +int wlan_hdd_validate_context(hdd_context_t *pHddCtx); +v_BOOL_t hdd_is_valid_mac_address(const tANI_U8* pMacAddr); +VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx); +void hdd_ipv4_notifier_work_queue(struct work_struct *work); +bool hdd_isConnectionInProgress(hdd_context_t *pHddCtx); +#ifdef WLAN_FEATURE_PACKET_FILTERING +int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType, tANI_U8 sessionId); +#endif + +#ifdef WLAN_NS_OFFLOAD +void hdd_ipv6_notifier_work_queue(struct work_struct *work); +#endif + + +void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx); + +int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr); +int wlan_hdd_set_mc_rate(hdd_adapter_t *pAdapter, int targetRate); +#ifdef MSM_PLATFORM +void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter); +void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *pAdapter); +#else +static inline void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + return; +} + +static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter) +{ + return; +} +#endif + +int hdd_wlan_startup(struct device *dev, void *hif_sc); +void __hdd_wlan_exit(void); +int hdd_wlan_notify_modem_power_state(int state); +#ifdef QCA_HT_2040_COEX +int hdd_wlan_set_ht2040_mode(hdd_adapter_t *pAdapter, v_U16_t staId, + v_MACADDR_t macAddrSTA, int width); +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +); + +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ + +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter); + +#endif /*End of FEATURE_WLAN_BATCH_SCAN*/ + +VOS_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *pHddCtx); + + +#ifdef WLAN_FEATURE_LPSS +void wlan_hdd_send_status_pkg(hdd_adapter_t *pAdapter, + hdd_station_ctx_t *pHddStaCtx, + v_U8_t is_on, + v_U8_t is_connected); +void wlan_hdd_send_version_pkg(v_U32_t fw_version, + v_U32_t chip_id, + const char *chip_name); +void wlan_hdd_send_all_scan_intf_info(hdd_context_t *pHddCtx); +#endif +void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len); +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, v_U8_t enable); +#endif + +hdd_adapter_t *hdd_get_con_sap_adapter(hdd_adapter_t *this_sap_adapter); + +boolean hdd_is_5g_supported(hdd_context_t * pHddCtx); + +#ifdef FEATURE_GREEN_AP +boolean hdd_wlan_green_ap_is_ps_on(hdd_context_t *pHddCtx); +int hdd_wlan_green_ap_enable(hdd_adapter_t *pHostapdAdapter, + v_U8_t enable); +void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx, + hdd_green_ap_event_t event); +#endif + +#ifdef WLAN_FEATURE_STATS_EXT +void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx); +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx); +#endif + +void hdd_update_macaddr(hdd_config_t *cfg_ini, v_MACADDR_t hw_macaddr); +#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) +void wlan_hdd_disable_roaming(hdd_adapter_t *pAdapter); +void wlan_hdd_enable_roaming(hdd_adapter_t *pAdapter); +#endif +int hdd_set_miracast_mode(hdd_adapter_t *pAdapter, tANI_U8 *command); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +static inline bool hdd_link_layer_stats_supported(void) +{ + return true; +} +#else +static inline bool hdd_link_layer_stats_supported(void) +{ + return false; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + +#endif // end #if !defined( WLAN_HDD_MAIN_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_mib.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_mib.h new file mode 100644 index 0000000000000..baceec8b3a802 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_mib.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_MIB_h__ ) +#define WLAN_HDD_MIB_h__ + + +#include + +typedef enum +{ + eMib_dot11DesiredBssType_infrastructure = 1, + eMib_dot11DesiredBssType_independent = 2, + eMib_dot11DesiredBssType_infra_ap =3, + eMib_dot11DesiredBssType_any = 4 + +} eMib_dot11DesiredBssType; + + +/** This is the maximum number of BSSIDs supported in the + dot11DesiredBssidList. All the code operates off of + this maximum BSSID list count. */ +#define MIB_DOT11_DESIRED_BSSID_LIST_MAX_COUNT ( 1 ) + +typedef struct +{ + v_U32_t cEntries; + + v_MACADDR_t BSSIDs[ MIB_DOT11_DESIRED_BSSID_LIST_MAX_COUNT ]; + +} sMib_dot11DesiredBssidList; + + + +/** This is the maximum number of SSIDs supported in the + dot11DesiredSsidList. All the code operates off of + this maximum SSID list count. */ + +#define MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ( 1 ) + +#define MIB_DOT11_SSID_MAX_LENGTH ( 32 ) + +typedef struct +{ + v_U32_t ssidLength; + v_U8_t ssid[ MIB_DOT11_SSID_MAX_LENGTH ]; + +} sDot11Ssid; + +typedef struct +{ + v_U32_t cEntries; + + sDot11Ssid SSIDs[ MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ]; + +} sMib_dot11DesiredSsidList; + + + +typedef enum +{ + // these are bitmasks.... + eMib_dot11AutoConfigEnabled_None = 0U, + eMib_dot11AutoConfigEnabled_Phy = 0x00000001U, + eMib_dot11AutoConfigEnabled_Mac = 0x00000002U + +} eMib_dot11AutoConfigEnabled; + + + +#define MIB_DOT11_SUPPORTED_PHY_TYPES_MAX_COUNT ( 3 ) + +typedef enum tagMib_dot11PhyType +{ + eMib_dot11PhyType_11b, + eMib_dot11PhyType_11a, + eMib_dot11PhyType_11g, + eMib_dot11PhyType_all +} eMib_dot11PhyType; + +typedef struct tagMib_dot11SupportedPhyTypes +{ + v_U32_t cEntries; + eMib_dot11PhyType phyTypes[ MIB_DOT11_SUPPORTED_PHY_TYPES_MAX_COUNT ]; +} sMib_dot11SupportedPhyTypes; + + +typedef enum +{ + eMib_DevicePowerState_D0, + eMib_DevicePowerState_D1, + eMib_DevicePowerState_D2, + eMib_DevicePowerState_D3 + +} eMib_DevicePowerState; + + +typedef enum +{ + eMib_dot11NICPowerState_OFF = VOS_FALSE, + eMib_dot11NICPowerState_ON = VOS_TRUE + +} eMib_dot11NICPowerState; + + +typedef enum +{ + eMib_dot11HardwarePHYState_OFF = VOS_FALSE, + eMib_dot11HardwarePHYState_ON = VOS_TRUE + +} eMib_dot11HardwarePHYState; + + +typedef enum +{ + eMib_dot11PowerSavingLevel_None, + eMib_dot11PowerSavingLevel_MaxPS, + eMib_dot11PowerSavingLevel_FastPS, + eMib_dot11PowerSavingLevel_MaximumLevel + +} eMib_dot11PowerSavingLevel; + + +#define MIB_DOT11_MAC_EXCLUSION_LIST_MAX_COUNT 4 +typedef struct +{ + v_U32_t cEntries; + + v_MACADDR_t macAddrs[ MIB_DOT11_MAC_EXCLUSION_LIST_MAX_COUNT ]; + +} sMib_dot11MacExcludeList; + +#define MIB_DOT11_PRIVACY_EXEMPT_LIST_MAX_COUNT 32 + +typedef enum +{ + eMib_dot11ExemptionAction_Always, + eMib_dot11ExemptionAction_OnKeyMapUnavailable + +}eMib_dot11ExemptAction; + +typedef enum +{ + eMib_dot11ExemptPacket_Unicast, + eMib_dot11ExemptPacket_Multicast, + eMib_dot11ExemptPacket_Both + +}eMib_dot11ExemptPacket; + +typedef struct +{ + v_U16_t uEtherType; + eMib_dot11ExemptAction exemptAction; + eMib_dot11ExemptPacket exemptPacket; + +}sMib_dot11PrivacyExemption; + +typedef struct +{ + v_U32_t cEntries; + + sMib_dot11PrivacyExemption privacyExemptList[ MIB_DOT11_PRIVACY_EXEMPT_LIST_MAX_COUNT ]; + +} sMib_dot11PrivacyExemptionList; + +typedef struct sHddMib_s +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + + sMib_dot11DesiredBssidList mibDot11DesiredBssidList; + + sMib_dot11DesiredSsidList mibDot11DesiredSsidList; + + eMib_dot11AutoConfigEnabled mibDot11AutoConfigEnabled; + + // the device power state for the device (the D-state... you know D0, D1, D2, etc. + eMib_DevicePowerState mibDevicePowerState; + + // dot11NICPowerState is really the on/off state of the PHY. This can be + /* Manipulated through OIDs like a software control for radio on/off. */ + eMib_dot11NICPowerState mibDot11NICPowerState; + + // Hardware PHY state is the on/off state of the hardware PHY. + eMib_dot11HardwarePHYState mibDot11HardwarePHYState; + + // dot11 Power Saving level is the 802.11 power saving level/state for the 802.11 + // NIC. Typically this is mapped to 802.11 BMPS in some fashion. We are not going + // to disappoint; the Libra NIC maps these to different BMPS settings. + eMib_dot11PowerSavingLevel mibDot11PowerSavingLevel; + + sMib_dot11MacExcludeList mibDot11MacExcludeList; + + sMib_dot11PrivacyExemptionList mibDot11PrivacyExemptionList; + + sMib_dot11SupportedPhyTypes mibDot11SupportedPhyTypes; + eMib_dot11PhyType mibDot11CurrentPhyType; + + v_BOOL_t dot11IbssJoinOnly; + v_BOOL_t HiddenNetworkEnabled; + + +}sHddMib_t; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_nan.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_nan.h new file mode 100644 index 0000000000000..b3015e258f9df --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_nan.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef __WLAN_HDD_NAN_H +#define __WLAN_HDD_NAN_H +/*========================================================================= + + \file wlan_hdd_nan.h + + \brief Linux HDD NAN include file + +==========================================================================*/ + +void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx); + +#endif /* __WLAN_HDD_NAN_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_oemdata.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_oemdata.h new file mode 100644 index 0000000000000..7751f85ae92f5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_oemdata.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/**=========================================================================== + + \file wlan_hdd_oemdata.h + + \brief Internal includes for the oem data + + ==========================================================================*/ + + +#ifndef __WLAN_HDD_OEM_DATA_H__ +#define __WLAN_HDD_OEM_DATA_H__ + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +#define OEM_APP_SIGNATURE_LEN 16 +#define OEM_APP_SIGNATURE_STR "QUALCOMM-OEM-APP" + +#define OEM_TARGET_SIGNATURE_LEN 8 +#define OEM_TARGET_SIGNATURE "QUALCOMM" + +#define OEM_CAP_MAX_NUM_CHANNELS 128 + +typedef enum +{ + /* Error null context */ + OEM_ERR_NULL_CONTEXT = 1, + + /* OEM App is not registered */ + OEM_ERR_APP_NOT_REGISTERED, + + /* Invalid signature */ + OEM_ERR_INVALID_SIGNATURE, + + /* Invalid message type */ + OEM_ERR_NULL_MESSAGE_HEADER, + + /* Invalid message type */ + OEM_ERR_INVALID_MESSAGE_TYPE, + + /* Invalid length in message body */ + OEM_ERR_INVALID_MESSAGE_LENGTH +} eOemErrorCode; + +int oem_activate_service(void *pAdapter); + +int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 major; + tANI_U8 minor; + tANI_U8 patch; + tANI_U8 build; +} tDriverVersion; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Signature of chip set vendor, e.g. QUALCOMM */ + tANI_U8 oem_target_signature[OEM_TARGET_SIGNATURE_LEN]; + tANI_U32 oem_target_type; /* Chip type */ + tANI_U32 oem_fw_version; /* FW version */ + tDriverVersion driver_version; /* CLD version */ + tANI_U16 allowed_dwell_time_min; /* Channel dwell time - allowed min */ + tANI_U16 allowed_dwell_time_max; /* Channel dwell time - allowed max */ + tANI_U16 curr_dwell_time_min; /* Channel dwell time - current min */ + tANI_U16 curr_dwell_time_max; /* Channel dwell time - current max */ + tANI_U16 supported_bands; /* 2.4G or 5G Hz */ + tANI_U16 num_channels; /* Num of channels IDs to follow */ + tANI_U8 channel_list[OEM_CAP_MAX_NUM_CHANNELS]; /* List of channel IDs */ +} t_iw_oem_data_cap; + +typedef PACKED_PRE struct PACKED_POST +{ + /* channel id */ + tANI_U32 chan_id; + + /* reserved0 */ + tANI_U32 reserved0; + + /* Primary 20 MHz channel frequency in MHz */ + tANI_U32 mhz; + + /* Center frequency 1 in MHz */ + tANI_U32 band_center_freq1; + + /* Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode */ + tANI_U32 band_center_freq2; + + /* channel info described below */ + tANI_U32 info; + + /* contains min power, max power, reg power and reg class id */ + tANI_U32 reg_info_1; + + /* contains antennamax */ + tANI_U32 reg_info_2; +} tHddChannelInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + /* peer mac address */ + tANI_U8 peer_mac_addr[6]; + + /* peer status: 1: CONNECTED, 2: DISCONNECTED */ + tANI_U8 peer_status; + + /* vdev_id for the peer mac */ + tANI_U8 vdev_id; + + /* peer capability: + * 0: RTT/RTT2 + * 1: RTT3(timing Meas Capability) + * 2: RTT3(fine timing Meas Capability) + * Default is 0 + */ + tANI_U32 peer_capability; + + /* reserved0 */ + tANI_U32 reserved0; + + /* channel info on which peer is connected */ + tHddChannelInfo peer_chan_info; +} tPeerStatusInfo; + +struct iw_oem_data_req +{ + v_U8_t oemDataReq[OEM_DATA_REQ_SIZE]; +}; + +int iw_set_oem_data_req( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); + +int iw_get_oem_data_rsp( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); + +struct iw_oem_data_rsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +}; + +#endif //__WLAN_HDD_OEM_DATA_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_p2p.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_p2p.h new file mode 100644 index 0000000000000..a7af5c00a50ae --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_p2p.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __P2P_H +#define __P2P_H +/**=========================================================================== + +\file wlan_hdd_p2p.h + +\brief Linux HDD P2P include file + +==========================================================================*/ +#define ACTION_FRAME_TX_TIMEOUT 2000 +#define WAIT_CANCEL_REM_CHAN 1000 +#define WAIT_REM_CHAN_READY 1000 +#define WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX 3000 +#define READY_EVENT_PROPOGATE_TIME 2 +#define ESTIMATED_ROC_DUR_REQD_FOR_ACTION_TX 20 +#define COMPLETE_EVENT_PROPOGATE_TIME 10 + +#define ACTION_FRAME_DEFAULT_WAIT 200 + +#define WLAN_HDD_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) +#define WLAN_HDD_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4) +#define WLAN_HDD_80211_FRM_DA_OFFSET 4 +#define P2P_WILDCARD_SSID_LEN 7 +#define P2P_WILDCARD_SSID "DIRECT-" + +#define P2P_ROC_DURATION_MULTIPLIER_GO_PRESENT 2 +#define P2P_ROC_DURATION_MULTIPLIER_GO_ABSENT 5 + +#ifdef WLAN_FEATURE_11W +#define WLAN_HDD_SET_WEP_FRM_FC(__fc__) ( (__fc__) = ((__fc__) | 0x40)) +#endif //WLAN_FEATURE_11W + +#define HDD_P2P_MAX_ROC_DURATION 1000 + +enum hdd_rx_flags { + HDD_RX_FLAG_DECRYPTED = 1 << 0, + HDD_RX_FLAG_MMIC_STRIPPED = 1 << 1, + HDD_RX_FLAG_IV_STRIPPED = 1 << 2, +}; + + +#define P2P_POWER_SAVE_TYPE_OPPORTUNISTIC (1 << 0) +#define P2P_POWER_SAVE_TYPE_PERIODIC_NOA (1 << 1) +#define P2P_POWER_SAVE_TYPE_SINGLE_NOA (1 << 2) + +#ifdef WLAN_FEATURE_P2P_DEBUG +typedef enum { P2P_NOT_ACTIVE, + P2P_GO_NEG_PROCESS, + P2P_GO_NEG_COMPLETED, + P2P_CLIENT_CONNECTING_STATE_1, + P2P_GO_COMPLETED_STATE, + P2P_CLIENT_CONNECTED_STATE_1, + P2P_CLIENT_DISCONNECTED_STATE, + P2P_CLIENT_CONNECTING_STATE_2, + P2P_CLIENT_COMPLETED_STATE + }tP2PConnectionStatus; + +extern tP2PConnectionStatus globalP2PConnectionStatus; +#endif + +typedef struct p2p_app_setP2pPs{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; +}p2p_app_setP2pPs_t; + +int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ); + +int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ); + +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie); + +int hdd_setP2pPs( struct net_device *dev, void *msgData ); +int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command ); +int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command ); + +void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, tANI_U8* pbFrames, + tANI_U8 frameType, + tANI_U32 rxChan, tANI_S8 rxRssi); + +void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ); +void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess ); +int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter); +void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ); +#else +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, u64 *cookie ); +#endif + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#else +struct net_device* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev ); +#else +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ); +#endif + +void wlan_hdd_cleanup_remain_on_channel_ctx(hdd_adapter_t *pAdapter); + +/* Max entry for RoC request */ +#define MAX_ROC_REQ_QUEUE_ENTRY 10 + +void wlan_hdd_roc_request_dequeue(struct work_struct *work); +void hdd_p2p_roc_work_queue(struct work_struct *work); + +#endif // __P2P_H diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_packet_filtering.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_packet_filtering.h new file mode 100644 index 0000000000000..ad7f76587e812 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_packet_filtering.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/****************************************************************************** +* +* Name: wlan_hdd_packet_filtering.h +* +* Description: Packet Filter Definitions. +* +* +******************************************************************************/ + +#ifndef __WLAN_HDD_PACKET_FILTERING_H__ +#define __WLAN_HDD_PACKET_FILTERING_H__ + + + +#ifdef WLAN_FEATURE_PACKET_FILTERING + +#define HDD_MAX_CMP_PER_PACKET_FILTER 5 +#define HDD_FILTER_IPV6_MC_UC 1 +#define HDD_FILTER_IPV6_MC 0 +#define HDD_FILTER_ID_IPV6_MC 10 +#define HDD_FILTER_ID_IPV6_UC 11 + +#define HDD_IPV6_MC_CMP_DATA 0x33 +#define HDD_IPV6_UC_CMP_DATA 0x01 +#define HDD_IPV6_CMP_DATA_0 0x86 +#define HDD_IPV6_CMP_DATA_1 0xDD + +#define HDD_WLAN_MAC_ADDR_LEN 6 +#define HDD_MAX_NUM_MULTICAST_ADDRESS 10 + +typedef enum +{ + HDD_FILTER_PROTO_TYPE_INVALID = 0, + HDD_FILTER_PROTO_TYPE_MAC = 1, + HDD_FILTER_PROTO_TYPE_ARP = 2, + HDD_FILTER_PROTO_TYPE_IPV4 =3 , + HDD_FILTER_PROTO_TYPE_IPV6 = 4, + HDD_FILTER_PROTO_TYPE_UDP = 5, + HDD_FILTER_PROTO_TYPE_MAX +} eProtoLayer; + +typedef enum +{ + HDD_RCV_FILTER_INVALID = 0, + HDD_RCV_FILTER_SET = 1, + HDD_RCV_FILTER_CLEAR = 2, + HDD_RCV_FILTER_MAX +}eFilterAction; + +typedef enum +{ + HDD_FILTER_CMP_TYPE_INVALID = 0, + HDD_FILTER_CMP_TYPE_EQUAL = 1, + HDD_FILTER_CMP_TYPE_MASK_EQUAL = 2, + HDD_FILTER_CMP_TYPE_NOT_EQUAL = 3, + HDD_FILTER_CMP_TYPE_MASK_NOT_EQUAL = 4, + HDD_FILTER_CMP_TYPE_MAX +}eCompareFlag; + +struct PacketFilterParamsCfg +{ + v_U8_t protocolLayer; + v_U8_t cmpFlag; + v_U8_t dataOffset; + v_U8_t dataLength; + v_U8_t compareData[8]; + v_U8_t dataMask[8]; +}; + +typedef struct +{ + v_U8_t filterAction; + v_U8_t filterId; + v_U8_t numParams; + struct PacketFilterParamsCfg paramsData [HDD_MAX_CMP_PER_PACKET_FILTER]; +}tPacketFilterCfg, *tpPacketFilterCfg; + +typedef v_U8_t tHddMacAddr[HDD_WLAN_MAC_ADDR_LEN]; + +typedef struct +{ + v_U8_t mcastBcastFilterSetting; + v_U8_t mcast_addr_cnt; + tHddMacAddr multicastAddr[HDD_MAX_NUM_MULTICAST_ADDRESS]; +} tRcvFltMcAddrList, *tpRcvFltMcAddrList; + +#endif +#endif // __WLAN_HDD_PACKET_FILTERING_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_power.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_power.h new file mode 100644 index 0000000000000..417e46229a797 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_power.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_POWER_H +#define __WLAN_HDD_POWER_H + +/**=========================================================================== + + \file wlan_hdd_power.h + + \brief Linux HDD Power + + ==========================================================================*/ + + +/*-------------------------------------------------------------------------- + * Include Files + *------------------------------------------------------------------------*/ +#include "wlan_hdd_main.h" + +/*--------------------------------------------------------------------------- + * Preprocessor definitions and constants + *-------------------------------------------------------------------------*/ + //gEnableSuspend = 1 in INI file implies suspend to standby + #define WLAN_MAP_SUSPEND_TO_STANDBY 1 + + //gEnableSuspend = 2 in INI file implies suspend to deep sleep + #define WLAN_MAP_SUSPEND_TO_DEEP_SLEEP 2 + + //gEnableSuspend = 3 in INI file implies suspend to set MCAST/BCAST filter + #define WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER 3 + + //gEnableDriverStop = 1 implies map driver stop to standby + #define WLAN_MAP_DRIVER_STOP_TO_STANDBY 1 + + /* gEnableDriverStop = 2 implies map driver stop to deep sleep */ + #define WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP 2 + + //Maximum time (ms) to wait for standby to complete + #define WLAN_WAIT_TIME_STANDBY 3000 + + //Maximum time (ms) to wait for full pwr to complete + #define WLAN_WAIT_TIME_FULL_PWR 3000 + + +/*--------------------------------------------------------------------------- + * Type declarations + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function declarations and documentation + * ------------------------------------------------------------------------*/ + eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx); + VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, + hdd_adapter_t* pAdapter); + VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx); + VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, + hdd_adapter_t* pAdapter); +#ifdef CONFIG_HAS_EARLYSUSPEND + VOS_STATUS hdd_wlan_reset(void); + VOS_STATUS hdd_wlan_reset_initialization(void) ; +#endif + /* SSR shutdown & re-init functions */ + VOS_STATUS hdd_wlan_shutdown(void); + VOS_STATUS hdd_wlan_re_init(void *hif_sc); + +void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter); +VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t* pAdapter, int fenable); +/* + * Function: hdd_conf_hostoffload + * Central function to configure the supported offloads, + * either enable or disable them. + */ +void hdd_conf_hostoffload(hdd_adapter_t * pAdapter, v_BOOL_t fenable); +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable); +#endif +#ifdef WLAN_NS_OFFLOAD +void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable); +#endif +#endif // if !defined __WLAN_QCT_DRIVER_H diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h new file mode 100644 index 0000000000000..a82ddf910beb0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( WLAN_HDD_SOFTAP_TX_RX_H ) +#define WLAN_HDD_SOFTAP_TX_RX_H + +/**=========================================================================== + + \file wlan_hdd_softap_tx_rx.h + + \brief Linux HDD SOFTAP Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +#define HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN (82*2) +#define HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN (78*2) +#define HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN (74*2) +#define HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN (70*2) + +/* SoftAP specific AC Weights */ +#define HDD_SOFTAP_BK_WEIGHT_DEFAULT 1 +#define HDD_SOFTAP_BE_WEIGHT_DEFAULT 3 +#define HDD_SOFTAP_VI_WEIGHT_DEFAULT 8 +#define HDD_SOFTAP_VO_WEIGHT_DEFAULT 18 + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documentation + -------------------------------------------------------------------------*/ + +/**============================================================================ + @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra softap network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued successfully + ===========================================================================*/ +extern int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +extern void hdd_softap_tx_timeout(struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_stats() - Function registered with the Linux OS for + device TX/RX statistics + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +extern struct net_device_stats* hdd_softap_stats(struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @param pmacAddrSTA : [in] pointer to the MAC address of the station + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA); + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a station + in Tx/RX modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId ); + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + successfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ); + +/**============================================================================ + @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ucAC : [in] pointer to access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ucAC, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ); + +/**============================================================================ + @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +extern VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ); + +/**============================================================================ + @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when a packet was received + for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param rxBufChain : [in] pointer to adf_nbuf rx chain + @param staId : [in] Station Id + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_rx_packet_cbk(v_VOID_t *vosContext, + adf_nbuf_t rxBufChain, + v_U8_t staId); + +/**============================================================================ + @brief hdd_softap_DeregisterSTA - Deregister a station from TL block + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deregister + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ); + +/**============================================================================ + @brief hdd_softap_RegisterSTA - Register a station into TL block + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deregister + @param fAuthRequired: [in] Station requires further security negotiation or not + @param fPrivacyBit : [in] privacy bit needs to be set or not + @param ucastSig : [in] Unicast Signature send to TL + @param bcastSig : [in] Broadcast Signature send to TL + @param pPeerMacAddress : [in] station MAC address + @param fWmmEnabled : [in] Wmm enabled sta or not + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter, + v_BOOL_t fAuthRequired, + v_BOOL_t fPrivacyBit, + v_U8_t staId, + v_U8_t ucastSig, + v_U8_t bcastSig, + v_MACADDR_t *pPeerMacAddress, + v_BOOL_t fWmmEnabled); + +/**============================================================================ + @brief hdd_softap_Register_BC_STA - Register a default broadcast station into TL block + + @param pAdapter : [in] pointer to adapter context + @param fPrivacyBit : [in] privacy bit needs to be set or not + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit); + +/**============================================================================ + @brief hdd_softap_DeregisterSTA - DeRegister the default broadcast station into TL block + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter); + +/**============================================================================ + @brief hdd_softap_stop_bss - Helper function to stop bss and do cleanup in HDD and TL + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pHostapdAdapter); + + +/**============================================================================ + @brief hdd_softap_change_STA_state - Helper function to change station state by MAC address + + @param pAdapter : [in] pointer to adapter context + @param pDestMacAddress : [in] pointer to station MAC address + @param state : [in] new station state + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state); + +/**============================================================================ + @brief hdd_softap_GetStaId - Helper function to get station Id from MAC address + + @param pAdapter : [in] pointer to adapter context + @param pDestMacAddress : [in] pointer to station MAC address + @param staId : [out] station id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_GetStaId( hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId); + +/**============================================================================ + @brief hdd_softap_GetConnectedStaId - Helper function to get station Id of the connected device + + @param pAdapter : [in] pointer to adapter context + @param staId : [out] station id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_GetConnectedStaId( hdd_adapter_t *pAdapter, v_U8_t *staId); + +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_softap_tx_resume_timer_expired_handler() - Resume OS TX Q timer + expired handler for SAP and P2P GO interface. + If Blocked OS Q is not resumed during timeout period, to prevent + permanent stall, resume OS Q forcefully for SAP and P2P GO interface. + + @param adapter_context : [in] pointer to vdev adapter + + @return : NONE + ===========================================================================*/ +void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context); + +/**============================================================================ + @brief hdd_softap_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev adapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_softap_tx_resume_cb(void *adapter_context, + v_BOOL_t tx_resume); +#endif /* QCA_LL_TX_FLOW_CT */ +#endif // end #if !defined( WLAN_HDD_SOFTAP_TX_RX_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tdls.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tdls.h new file mode 100644 index 0000000000000..3c74f70ce0047 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tdls.h @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __HDD_TDSL_H +#define __HDD_TDSL_H +/**=========================================================================== + +\file wlan_hdd_tdls.h + +\brief Linux HDD TDLS include file +==========================================================================*/ + +#ifdef FEATURE_WLAN_TDLS + +#define MAX_NUM_TDLS_PEER 3 + +#define TDLS_SUB_DISCOVERY_PERIOD 100 + +#define TDLS_MAX_DISCOVER_REQS_PER_TIMER 1 + +#define TDLS_DISCOVERY_PERIOD 3600000 + +#define TDLS_TX_STATS_PERIOD 3600000 + +#define TDLS_IMPLICIT_TRIGGER_PKT_THRESHOLD 100 + +#define TDLS_RX_IDLE_TIMEOUT 5000 + +#define TDLS_RSSI_TRIGGER_HYSTERESIS 50 + +/* before UpdateTimer expires, we want to timeout discovery response. +should not be more than 2000 */ +#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 + +#define TDLS_CTX_MAGIC 0x54444c53 // "TDLS" + +#define TDLS_MAX_SCAN_SCHEDULE 10 +#define TDLS_MAX_SCAN_REJECT 5 +#define TDLS_DELAY_SCAN_PER_CONNECTION 100 +#define TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN 1 + +#define TDLS_IS_CONNECTED(peer) \ + ((eTDLS_LINK_CONNECTED == (peer)->link_status) || \ + (eTDLS_LINK_TEARING == (peer)->link_status)) + +/* bit mask flag for tdls_option to FW */ +#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ +#define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ +#define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ +#define TDLS_SEC_OFFCHAN_OFFSET_0 0 +#define TDLS_SEC_OFFCHAN_OFFSET_40PLUS 40 +#define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40) +#define TDLS_SEC_OFFCHAN_OFFSET_80 80 +#define TDLS_SEC_OFFCHAN_OFFSET_160 160 + +#define TDLS_PEER_LIST_SIZE 256 + +typedef struct +{ + tANI_U32 tdls; + tANI_U32 tx_period_t; + tANI_U32 tx_packet_n; + tANI_U32 discovery_period_t; + tANI_U32 discovery_tries_n; + tANI_U32 idle_timeout_t; + tANI_U32 idle_packet_n; + tANI_U32 rssi_hysteresis; + tANI_S32 rssi_trigger_threshold; + tANI_S32 rssi_teardown_threshold; + tANI_S32 rssi_delta; +} tdls_config_params_t; + +typedef struct +{ + struct wiphy *wiphy; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev; +#endif + struct cfg80211_scan_request *scan_request; + int magic; + int attempt; + int reject; + struct delayed_work tdls_scan_work; +} tdls_scan_context_t; + +typedef enum { + eTDLS_SUPPORT_NOT_ENABLED = 0, + eTDLS_SUPPORT_DISABLED, /* suppress implicit trigger and not respond to the peer */ + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY, /* suppress implicit trigger, but respond to the peer */ + eTDLS_SUPPORT_ENABLED, /* implicit trigger */ +} eTDLSSupportMode; + +typedef enum eTDLSCapType{ + eTDLS_CAP_NOT_SUPPORTED = -1, + eTDLS_CAP_UNKNOWN = 0, + eTDLS_CAP_SUPPORTED = 1, +} tTDLSCapType; + +typedef enum eTDLSLinkStatus { + eTDLS_LINK_IDLE = 0, + eTDLS_LINK_DISCOVERING, + eTDLS_LINK_DISCOVERED, + eTDLS_LINK_CONNECTING, + eTDLS_LINK_CONNECTED, + eTDLS_LINK_TEARING, +} tTDLSLinkStatus; + + +typedef enum { + eTDLS_LINK_SUCCESS, /* Success */ + eTDLS_LINK_UNSPECIFIED = -1, /* Unspecified reason */ + eTDLS_LINK_NOT_SUPPORTED = -2, /* Remote side doesn't support TDLS */ + eTDLS_LINK_UNSUPPORTED_BAND = -3, /* Remote side doesn't support this + band */ + eTDLS_LINK_NOT_BENEFICIAL = -4, /* Going to AP is better than direct */ + eTDLS_LINK_DROPPED_BY_REMOTE = -5 /* Remote side doesn't want it anymore */ +} tTDLSLinkReason; + +typedef struct { + int channel; /* channel hint, in channel number + (NOT frequency ) */ + int global_operating_class; /* operating class to use */ + int max_latency_ms; /* max latency that can be tolerated + by apps */ + int min_bandwidth_kbps; /* bandwidth required by apps, in kilo + bits per second */ +} tdls_req_params_t; + +typedef enum { + WIFI_TDLS_DISABLED, /* TDLS is not enabled, or is disabled + now */ + WIFI_TDLS_ENABLED, /* TDLS is enabled, but not yet tried */ + WIFI_TDLS_TRYING, /* Direct link is being attempted + (optional) */ + WIFI_TDLS_ESTABLISHED, /* Direct link is established */ + WIFI_TDLS_ESTABLISHED_OFF_CHANNEL, /* Direct link is established using + MCC */ + WIFI_TDLS_DROPPED, /* Direct link was established, but is + now dropped */ + WIFI_TDLS_FAILED /* Direct link failed */ +} tdls_state_t; + +typedef int (*cfg80211_exttdls_callback)(tANI_U8* mac, + tANI_S32 state, + tANI_S32 reason, + void *ctx); +typedef struct { + tANI_U16 period; + tANI_U16 bytes; +} tdls_tx_tput_config_t; + +typedef struct { + tANI_U16 period; + tANI_U16 tries; +} tdls_discovery_config_t; + +typedef struct { + tANI_U16 timeout; +} tdls_rx_idle_config_t; + +typedef struct { + tANI_U16 rssi_thres; +} tdls_rssi_config_t; + +struct _hddTdlsPeer_t; + +typedef struct { + struct list_head peer_list[TDLS_PEER_LIST_SIZE]; + hdd_adapter_t *pAdapter; +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_t peerDiscoverTimer; +#endif + vos_timer_t peerDiscoveryTimeoutTimer; + tdls_config_params_t threshold_config; + tANI_S32 discovery_peer_cnt; + tANI_U32 discovery_sent_cnt; + tANI_S8 ap_rssi; + struct _hddTdlsPeer_t *curr_candidate; + struct work_struct implicit_setup; + v_U32_t magic; +} tdlsCtx_t; + +typedef struct _hddTdlsPeer_t { + struct list_head node; + tdlsCtx_t *pHddTdlsCtx; + tSirMacAddr peerMac; + tANI_U16 staId ; + tANI_S8 rssi; + tTDLSCapType tdls_support; + tTDLSLinkStatus link_status; + tANI_U8 signature; + tANI_U8 is_responder; + tANI_U8 discovery_processed; + tANI_U16 discovery_attempt; + tANI_U16 tx_pkt; + tANI_U16 rx_pkt; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 supported_channels_len; + tANI_U8 supported_channels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supported_oper_classes_len; + tANI_U8 supported_oper_classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; + tANI_BOOLEAN isForcedPeer; + tANI_U8 op_class_for_pref_off_chan; + tANI_U8 pref_off_chan_num; + tANI_U8 op_class_for_pref_off_chan_is_set; + /* EXT TDLS */ + tTDLSLinkReason reason; + cfg80211_exttdls_callback state_change_notification; +} hddTdlsPeer_t; + +typedef struct { + /* Session ID */ + tANI_U8 sessionId; + /*TDLS peer station id */ + v_U8_t staId; + /* TDLS peer mac Address */ + v_MACADDR_t peerMac; +} tdlsConnInfo_t; + +typedef struct { + tANI_U32 vdev_id; + tANI_U32 tdls_state; + tANI_U32 notification_interval_ms; + tANI_U32 tx_discovery_threshold; + tANI_U32 tx_teardown_threshold; + tANI_S32 rssi_teardown_threshold; + tANI_S32 rssi_delta; + tANI_U32 tdls_options; + tANI_U32 peer_traffic_ind_window; + tANI_U32 peer_traffic_response_timeout; + tANI_U32 puapsd_mask; + tANI_U32 puapsd_inactivity_time; + tANI_U32 puapsd_rx_frame_threshold; +} tdlsInfo_t; + +int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac); + +void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac); + +int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx); + +int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId); + +hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac, tANI_BOOLEAN mutexLock); + +hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac); + +int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac, + tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams); +hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac); + +int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter, u8* mac, tTDLSCapType cap); + +void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, + tTDLSLinkStatus status, + tTDLSLinkReason reason); +void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, + u8* mac, + tTDLSLinkStatus linkStatus, + tTDLSLinkReason reason); + +int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac); + +int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter, + u8 *mac, + tCsrStaParams *StaParams, + tANI_BOOLEAN isBufSta, + tANI_BOOLEAN isOffChannelSupported); + +int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi); + +int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder); + +int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac); + +int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature); + +int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config); + +int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac); + +tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter); + +int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen); + +void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode); + +void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter); + +u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac); + +hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8* mac, u8 skip_self); + +void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode, + v_BOOL_t bUpdateLast); + +tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx); + +void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx); + +int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); + +int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); + +void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter, + vos_timer_t *timer, + v_U32_t expirationTime); +void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, + hddTdlsPeer_t *curr_peer, + tANI_U16 reason); + +#ifdef CONFIG_TDLS_IMPLICIT +void wlan_hdd_tdls_pre_setup_init_work(tdlsCtx_t *pHddTdlsCtx, + hddTdlsPeer_t *curr_candidate); +#endif + +int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter, + uint8_t *mac, + uint32_t chan, + uint32_t max_latency, + uint32_t op_class, + uint32_t min_bandwidth); + +int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac, + tANI_BOOLEAN forcePeer); +int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer); +int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, + u8 *peer, + cfg80211_exttdls_callback callback, + uint32_t chan, + uint32_t max_latency, + uint32_t op_class, + uint32_t min_bandwidth); +void hdd_tdls_notify_mode_change(hdd_adapter_t *pAdapter, + hdd_context_t *pHddCtx); +void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *pHddCtx); + +/* EXT TDLS */ +int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, + tANI_U8* mac, + tANI_S32 *state, + tANI_S32 *reason); +void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, + tANI_S32 *state, + tANI_S32 *reason); +int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, + cfg80211_exttdls_callback callback); +hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *pAdapter); +int hdd_set_tdls_offchannel(hdd_context_t *pHddCtx, int offchannel); +int hdd_set_tdls_secoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset); +int hdd_set_tdls_offchannelmode(hdd_adapter_t *pAdapter, int offchanmode); +void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, + bool tdls_chan_swit_prohibited); +int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val); + +#else +static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *pAdapter, + hdd_context_t *pHddCtx) +{ +} +static inline void +wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *pHddCtx) +{ +} +#endif + +#endif // __HDD_TDSL_H diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tgt_cfg.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tgt_cfg.h new file mode 100644 index 0000000000000..b8c6f6b0f3339 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tgt_cfg.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HDD_TGT_CFG_H +#define HDD_TGT_CFG_H + +/* TODO: Find it from the max number of supported vdev */ +#define INTF_MACADDR_MASK 0x7 + +struct hdd_tgt_services { + u_int32_t sta_power_save; + u_int32_t uapsd; + u_int32_t ap_dfs; + u_int32_t en_11ac; + u_int32_t arp_offload; + u_int32_t early_rx; +#ifdef FEATURE_WLAN_SCAN_PNO + v_BOOL_t pno_offload; +#endif + v_BOOL_t beacon_offload; + u_int32_t lte_coex_ant_share; +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t en_tdls; + v_BOOL_t en_tdls_offchan; + v_BOOL_t en_tdls_uapsd_buf_sta; + v_BOOL_t en_tdls_uapsd_sleep_sta; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + v_BOOL_t en_roam_offload; +#endif +#endif +}; + +struct hdd_tgt_ht_cap { + u_int32_t mpdu_density; + bool ht_rx_stbc; + bool ht_tx_stbc; + bool ht_rx_ldpc; + bool ht_sgi_20; + bool ht_sgi_40; + u_int32_t num_rf_chains; +}; + +#ifdef WLAN_FEATURE_11AC +struct hdd_tgt_vht_cap { + u_int32_t vht_max_mpdu; + u_int32_t supp_chan_width; + u_int32_t vht_rx_ldpc; + u_int32_t vht_short_gi_80; + u_int32_t vht_short_gi_160; + u_int32_t vht_tx_stbc; + u_int32_t vht_rx_stbc; + u_int32_t vht_su_bformer; + u_int32_t vht_su_bformee; + u_int32_t vht_mu_bformer; + u_int32_t vht_mu_bformee; + u_int32_t vht_max_ampdu_len_exp; + u_int32_t vht_txop_ps; +}; +#endif + + +struct hdd_tgt_cfg { + u_int32_t target_fw_version; + u_int8_t band_cap; + u_int32_t reg_domain; + u_int32_t eeprom_rd_ext; + v_MACADDR_t hw_macaddr; + struct hdd_tgt_services services; + struct hdd_tgt_ht_cap ht_cap; +#ifdef WLAN_FEATURE_11AC + struct hdd_tgt_vht_cap vht_cap; +#endif + v_U8_t max_intf_count; +#ifdef WLAN_FEATURE_LPSS + v_U8_t lpss_support; +#endif +}; + +struct hdd_dfs_radar_ind { + u_int8_t ieee_chan_number; + u_int32_t chan_freq; + u_int32_t dfs_radar_status; +}; + +#endif /* HDD_TGT_CFG_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_trace.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_trace.h new file mode 100644 index 0000000000000..4208fdedc9e0f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_trace.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_TRACE_H__ +#define __WLAN_HDD_TRACE_H__ + +#include "macTrace.h" + +#define NO_SESSION 0xFF + +enum { + TRACE_CODE_HDD_OPEN_REQUEST, + TRACE_CODE_HDD_STOP_REQUEST, + TRACE_CODE_HDD_TX_TIMEOUT, + TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL, + TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL, + TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL, + TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL, + TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL, + TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL, + TRACE_CODE_HDD_SETROAMDELTA_IOCTL, + TRACE_CODE_HDD_GETROAMDELTA_IOCTL, + TRACE_CODE_HDD_GETBAND_IOCTL, + TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL, + TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL, + TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL, + TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, + TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST, + TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST, + TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT, + TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR, + TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL, + TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL, + TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL, + TRACE_CODE_HDD_ADD_VIRTUAL_INTF, + TRACE_CODE_HDD_DEL_VIRTUAL_INTF, + TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF, + TRACE_CODE_HDD_CFG80211_START_AP, + TRACE_CODE_HDD_CFG80211_CHANGE_BEACON, + TRACE_CODE_HDD_CFG80211_STOP_AP, + TRACE_CODE_HDD_CFG80211_CHANGE_BSS, + TRACE_CODE_HDD_CFG80211_ADD_KEY, + TRACE_CODE_HDD_CFG80211_GET_KEY, + TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + TRACE_CODE_HDD_CFG80211_CONNECT, + TRACE_CODE_HDD_CFG80211_DISCONNECT, + TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, + TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS, + TRACE_CODE_HDD_CFG80211_SET_TXPOWER, + TRACE_CODE_HDD_CFG80211_GET_TXPOWER, + TRACE_CODE_HDD_CFG80211_SET_CHANNEL, + TRACE_CODE_HDD_CFG80211_ADD_BEACON, + TRACE_CODE_HDD_CFG80211_SET_BEACON, + TRACE_CODE_HDD_CFG80211_CHANGE_IFACE, + TRACE_CODE_HDD_CHANGE_STATION, + TRACE_CODE_HDD_CFG80211_UPDATE_BSS, + TRACE_CODE_HDD_CFG80211_SCAN, + TRACE_CODE_HDD_REMAIN_ON_CHANNEL, + TRACE_CODE_HDD_REMAINCHANREADYHANDLER, + TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL, + TRACE_CODE_HDD_ACTION, + TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, + TRACE_CODE_HDD_CFG80211_GET_STA, + TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT, + TRACE_CODE_HDD_CFG80211_DEL_STA, + TRACE_CODE_HDD_CFG80211_ADD_STA, + TRACE_CODE_HDD_CFG80211_SET_PMKSA, + TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES, + TRACE_CODE_HDD_CFG80211_TDLS_MGMT, + TRACE_CODE_HDD_CFG80211_TDLS_OPER, + TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA, + TRACE_CODE_HDD_UNSUPPORTED_IOCTL, + TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL, + TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL +}; + +extern void hddTraceDump(void *pMac, tpvosTraceRecord pRecord, + tANI_U16 recIndex); +extern void hddTraceInit(void); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tx_rx.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tx_rx.h new file mode 100644 index 0000000000000..309f567d02a9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_TX_RX_H ) +#define WLAN_HDD_TX_RX_H + +/**=========================================================================== + + \file wlan_hdd_tx_rx.h + + \brief Linux HDD Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +#define HDD_ETHERTYPE_802_1_X ( 0x888E ) +#define HDD_ETHERTYPE_802_1_X_FRAME_OFFSET ( 12 ) +#define HDD_ETHERTYPE_802_1_X_SIZE ( 2 ) +#ifdef FEATURE_WLAN_WAPI +#define HDD_ETHERTYPE_WAI ( 0x88b4 ) +#endif + +#define HDD_80211_HEADER_LEN 24 +#define HDD_80211_HEADER_QOS_CTL 2 +#define HDD_LLC_HDR_LEN 6 +#define HDD_FRAME_TYPE_MASK 0x0c +#define HDD_FRAME_SUBTYPE_MASK 0xf0 +#define HDD_FRAME_TYPE_DATA 0x08 +#define HDD_FRAME_TYPE_MGMT 0x00 +#define HDD_FRAME_SUBTYPE_QOSDATA 0x80 +#define HDD_FRAME_SUBTYPE_DEAUTH 0xC0 +#define HDD_FRAME_SUBTYPE_DISASSOC 0xA0 +#define HDD_DEST_ADDR_OFFSET 6 + +#define HDD_MAC_HDR_SIZE 6 + +#define HDD_PSB_CFG_INVALID 0xFF +#define HDD_PSB_CHANGED 0xFF +#define SME_QOS_UAPSD_CFG_BK_CHANGED_MASK 0xF1 +#define SME_QOS_UAPSD_CFG_BE_CHANGED_MASK 0xF2 +#define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK 0xF4 +#define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK 0xF8 + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documentation + -------------------------------------------------------------------------*/ + +/**============================================================================ + @brief hdd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued successfully + ===========================================================================*/ +extern int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); + +extern int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); +/**============================================================================ + @brief hdd_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +extern void hdd_tx_timeout(struct net_device *dev); + +/**============================================================================ + @brief hdd_stats() - Function registered with the Linux OS for + device TX/RX statistics + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +extern struct net_device_stats* hdd_stats(struct net_device *dev); + +/**============================================================================ + @brief hdd_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + succesfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ); + +/**============================================================================ + @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ucAC : [in] pointer to access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ucAC, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ); + +/**============================================================================ + @brief hdd_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +extern VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ); + +/**============================================================================ + @brief hdd_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when a packet was received + for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param rxBufChain : [in] pointer to adf_nbuf rx chain + @param staId : [in] Station Id + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_rx_packet_cbk(v_VOID_t *vosContext, adf_nbuf_t rxBufChain, + v_U8_t staId); + +/**============================================================================ + @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is EAPOL + : VOS_FALSE otherwise + ===========================================================================*/ +extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ); + +/**============================================================================ + @brief hdd_mon_tx_mgmt_pkt() - Transmit MGMT packet received on monitor + interface. + + @param pAdapter: [in] SAP/P2P GO adapter. + ===========================================================================*/ +void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter); + +/**============================================================================ + @brief hdd_mon_tx_work_queue() - work queue handler for transmitting + mgmt packets. + + @param work: [in] work queue structure. + ===========================================================================*/ +void hdd_mon_tx_work_queue(struct work_struct *work); + +/**============================================================================ + @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address + @param pHddStaCtx : [in] pointer to HDD Station Context + pMacAddress [in] pointer to Peer Mac address + staID [out] pointer to Station Index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, + v_MACADDR_t *pMacAddress, v_U8_t *staId); + +/**============================================================================ + @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() - + Timer handler to check enable/disable split scan + @param pHddStaCtx : Hdd adapter + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *pAdapter); + +/**============================================================================ + @brief hdd_flush_ibss_tx_queues() - + Flush tx queues in IBSS mode + @param pAdapter: Hdd adapter + @param STAId: Sta index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId); + +/**========================================================================= + @brief hdd_wmm_acquire_access_required()- + Determine whether wmm ac acquire access is required + @param pAdapter : pointer to Adapter context + @param acType : AC + @return : void + ========================================================================*/ +void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter, + WLANTL_ACEnumType acType); + +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev adapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_cb(void *adapter_context, + v_BOOL_t tx_resume); + +/**============================================================================ + @brief hdd_tx_resume_timer_expired_handler() - Resume OS TX Q timer expired + handler. + If Blocked OS Q is not resumed during timeout period, to prevent + permanent stall, resume OS Q forcefully. + + @param adapter_context : [in] pointer to vdev adapter + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_timer_expired_handler(void *adapter_context); +#endif /* QCA_LL_TX_FLOW_CT */ +#endif // end #if !defined( WLAN_HDD_TX_RX_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h new file mode 100644 index 0000000000000..b522f830fa95c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wext.h @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WEXT_IW_H__ +#define __WEXT_IW_H__ + +#include +#include +#include +#include +#include +#include +#include "vos_event.h" + +/* + * order of parameters in addTs private ioctl + */ +#define HDD_WLAN_WMM_PARAM_HANDLE 0 +#define HDD_WLAN_WMM_PARAM_TID 1 +#define HDD_WLAN_WMM_PARAM_DIRECTION 2 +#define HDD_WLAN_WMM_PARAM_APSD 3 +#define HDD_WLAN_WMM_PARAM_USER_PRIORITY 4 +#define HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE 5 +#define HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE 6 +#define HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE 7 +#define HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE 8 +#define HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE 9 +#define HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE 10 +#define HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE 11 +#define HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE 12 +#define HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL 13 +#define HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL 14 +#define HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN 15 +#define HDD_WLAN_WMM_PARAM_ACK_POLICY 16 +#define HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL 17 +#define HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL 18 +#define HDD_WLAN_WMM_PARAM_COUNT 19 + +#define MHZ 6 + +#define WE_MAX_STR_LEN 1024 +#define WLAN_HDD_UI_BAND_AUTO 0 +#define WLAN_HDD_UI_BAND_5_GHZ 1 +#define WLAN_HDD_UI_BAND_2_4_GHZ 2 +/* SETBAND x */ +/* 012345678 */ +#define WLAN_HDD_UI_SET_BAND_VALUE_OFFSET 8 + +typedef enum +{ + HDD_WLAN_WMM_DIRECTION_UPSTREAM = 0, + HDD_WLAN_WMM_DIRECTION_DOWNSTREAM = 1, + HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL = 2, +} hdd_wlan_wmm_direction_e; + +typedef enum +{ + HDD_WLAN_WMM_POWER_SAVE_LEGACY = 0, + HDD_WLAN_WMM_POWER_SAVE_UAPSD = 1, +} hdd_wlan_wmm_power_save_e; + +typedef enum +{ + // TSPEC/re-assoc done, async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS = 0, + // no need to setup TSPEC since ACM=0 and no UAPSD desired, sync + async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD = 1, + // no need to setup TSPEC since ACM=0 and UAPSD already exists, sync + async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING = 2, + // TSPEC result pending, sync + HDD_WLAN_WMM_STATUS_SETUP_PENDING = 3, + // TSPEC/re-assoc failed, sync + async + HDD_WLAN_WMM_STATUS_SETUP_FAILED = 4, + // Request rejected due to invalid params, sync + async + HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM = 5, + // TSPEC request rejected since AP!=QAP, sync + HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM = 6, + + // TSPEC modification/re-assoc successful, async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS = 7, + // TSPEC modification a no-op since ACM=0 and no change in UAPSD, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD = 8, + // TSPEC modification a no-op since ACM=0 and requested U-APSD already exists, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING = 9, + // TSPEC result pending, sync + HDD_WLAN_WMM_STATUS_MODIFY_PENDING = 10, + // TSPEC modification failed, prev TSPEC in effect, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_FAILED = 11, + // TSPEC modification request rejected due to invalid params, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM = 12, + + // TSPEC release successful, sync and also async + HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS = 13, + // TSPEC release pending, sync + HDD_WLAN_WMM_STATUS_RELEASE_PENDING = 14, + // TSPEC release failed, sync + async + HDD_WLAN_WMM_STATUS_RELEASE_FAILED = 15, + // TSPEC release rejected due to invalid params, sync + HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM = 16, + // TSPEC modified due to the mux'ing of requests on ACs, async + + HDD_WLAN_WMM_STATUS_MODIFIED = 17, + // TSPEC revoked by AP, async + HDD_WLAN_WMM_STATUS_LOST = 18, + // some internal failure like memory allocation failure, etc, sync + HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE = 19, + + /* U-APSD failed during setup but OTA setup (whether TSPEC exchange or + re-assoc) was done so app should release this QoS, async */ + HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED = 20, + /* U-APSD failed during modify, but OTA setup (whether TSPEC exchange or + re-assoc) was done so app should release this QoS, async */ + HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED = 21 + +} hdd_wlan_wmm_status_e; + +/** TS Info Ack Policy */ +typedef enum +{ + HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK = 0, + HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 1, +} hdd_wlan_wmm_ts_info_ack_policy_e; + +/** vendor element ID */ +#define IE_EID_VENDOR ( 221 ) /* 0xDD */ +#define IE_LEN_SIZE 1 +#define IE_EID_SIZE 1 +#define IE_VENDOR_OUI_SIZE 4 + +/** Maximum Length of WPA/RSN IE */ +#define MAX_WPA_RSN_IE_LEN 40 + +/** Maximum Number of WEP KEYS */ +#define MAX_WEP_KEYS 4 + +/** Ether Address Length */ +#define ETHER_ADDR_LEN 6 + +/** Enable 11d */ +#define ENABLE_11D 1 + +/** Disable 11d */ +#define DISABLE_11D 0 + +/* + refer wpa.h in wpa supplicant code for REASON_MICHAEL_MIC_FAILURE + + supplicant sets REASON_MICHAEL_MIC_FAILURE as the reason code when it sends the MLME deauth IOCTL + for TKIP counter measures +*/ +#define HDD_REASON_MICHAEL_MIC_FAILURE 14 + +/* + * These are for TLV fields in WPS IE + */ +#define HDD_WPS_UUID_LEN 16 +#define HDD_WPS_ELEM_VERSION 0x104a +#define HDD_WPS_ELEM_REQUEST_TYPE 0x103a +#define HDD_WPS_ELEM_CONFIG_METHODS 0x1008 +#define HDD_WPS_ELEM_UUID_E 0x1047 +#define HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE 0x1054 +#define HDD_WPS_ELEM_RF_BANDS 0x103c +#define HDD_WPS_ELEM_ASSOCIATION_STATE 0x1002 +#define HDD_WPS_ELEM_CONFIGURATION_ERROR 0x1009 +#define HDD_WPS_ELEM_DEVICE_PASSWORD_ID 0x1012 + +#define HDD_WPA_ELEM_VENDOR_EXTENSION 0x1049 + +#define HDD_WPS_MANUFACTURER_LEN 64 +#define HDD_WPS_MODEL_NAME_LEN 32 +#define HDD_WPS_MODEL_NUM_LEN 32 +#define HDD_WPS_SERIAL_NUM_LEN 32 +#define HDD_WPS_DEVICE_OUI_LEN 4 +#define HDD_WPS_DEVICE_NAME_LEN 32 + +#define HDD_WPS_ELEM_WPS_STATE 0x1044 +#define HDD_WPS_ELEM_APSETUPLOCK 0x1057 +#define HDD_WPS_ELEM_SELECTEDREGISTRA 0x1041 +#define HDD_WPS_ELEM_RSP_TYPE 0x103B +#define HDD_WPS_ELEM_MANUFACTURER 0x1021 +#define HDD_WPS_ELEM_MODEL_NAME 0x1023 +#define HDD_WPS_ELEM_MODEL_NUM 0x1024 +#define HDD_WPS_ELEM_SERIAL_NUM 0x1042 +#define HDD_WPS_ELEM_DEVICE_NAME 0x1011 +#define HDD_WPS_ELEM_REGISTRA_CONF_METHODS 0x1053 + +#define HDD_RTSCTS_EN_MASK 0xF +#define HDD_RTSCTS_ENABLE 1 +#define HDD_CTS_ENABLE 2 + +#define WPS_OUI_TYPE "\x00\x50\xf2\x04" +#define WPS_OUI_TYPE_SIZE 4 + +#define SS_OUI_TYPE "\x00\x16\x32" +#define SS_OUI_TYPE_SIZE 3 + +#define P2P_OUI_TYPE "\x50\x6f\x9a\x09" +#define P2P_OUI_TYPE_SIZE 4 + +#define HS20_OUI_TYPE "\x50\x6f\x9a\x10" +#define HS20_OUI_TYPE_SIZE 4 + +#define OSEN_OUI_TYPE "\x50\x6f\x9a\x12" +#define OSEN_OUI_TYPE_SIZE 4 + +#ifdef WLAN_FEATURE_WFD +#define WFD_OUI_TYPE "\x50\x6f\x9a\x0a" +#define WFD_OUI_TYPE_SIZE 4 +#endif + +typedef enum +{ + eWEXT_WPS_OFF = 0, + eWEXT_WPS_ON = 1, +}hdd_wps_mode_e; + +typedef enum +{ + DRIVER_POWER_MODE_AUTO = 0, + DRIVER_POWER_MODE_ACTIVE = 1, +} hdd_power_mode_e; + +typedef enum +{ + WEXT_SCAN_PENDING_GIVEUP = 0, + WEXT_SCAN_PENDING_PIGGYBACK = 1, + WEXT_SCAN_PENDING_DELAY = 2, + WEXT_SCAN_PENDING_MAX +} hdd_scan_pending_option_e; + +/* + * This structure contains the interface level (granularity) + * configuration information in support of wireless extensions. + */ +typedef struct hdd_wext_state_s +{ + /** The CSR "desired" Profile */ + tCsrRoamProfile roamProfile; + + /** BSSID to which connect request is received */ + tCsrBssid req_bssId; + + /** The association status code */ + v_U32_t statusCode; + + /** wpa version WPA/WPA2/None*/ + v_S31_t wpaVersion; + + /**WPA or RSN IE*/ + u_int8_t WPARSNIE[MAX_WPA_RSN_IE_LEN]; + + /**gen IE */ + tSirAddie genIE; + + /**Additional IE for assoc */ + tSirAddie assocAddIE; + + /**auth key mgmt */ + v_S31_t authKeyMgmt; + + /**vos event */ + vos_event_t vosevent; + + vos_event_t scanevent; + + /**Counter measure state, Started/Stopped*/ + v_BOOL_t mTKIPCounterMeasures; + + /**Completion Variable*/ + struct completion completion_var; + +#ifdef FEATURE_OEM_DATA_SUPPORT + /* oem data req in Progress */ + v_BOOL_t oemDataReqInProgress; + + /* oem data req ID */ + v_U32_t oemDataReqID; +#endif + +#ifdef FEATURE_WLAN_ESE + /* ESE state variables */ + v_BOOL_t isESEConnection; + eCsrAuthType collectedAuthType; /* Collected from ALL SIOCSIWAUTH Ioctls. Will be negotiatedAuthType - in tCsrProfile */ +#endif +}hdd_wext_state_t; + +typedef struct ccp_freq_chan_map_s{ + // List of frequencies + v_U32_t freq; + v_U32_t chan; +}hdd_freq_chan_map_t; + +#define wlan_hdd_get_wps_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE, ie, ie_len) + +#define wlan_hdd_get_p2p_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE, ie, ie_len) + +#ifdef WLAN_FEATURE_WFD +#define wlan_hdd_get_wfd_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE, ie, ie_len) +#endif + +extern int hdd_UnregisterWext(struct net_device *dev); +extern int hdd_register_wext(struct net_device *dev); +extern int hdd_wlan_get_freq(v_U32_t chan,v_U32_t *freq); +extern int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu); +extern int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu); +extern void hdd_wlan_get_version(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_cscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_essid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra); + + +extern int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra); + +extern int iw_get_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra); + +VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + + +VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + +VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + +void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result); + +extern int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int hdd_priv_get_data(struct iw_point *p_priv_data, + union iwreq_data *wrqu); + +extern void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len); + +extern VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, + tSirMacAddr macAddress); +void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter); +void hdd_GetClassA_statisticsCB(void *pStats, void *pContext); +void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext); + +VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter); + +v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, + v_U8_t *ie, int ie_len); + +VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode); + +VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx, + hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx); + +VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value); + +VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr); + +void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter); + +#ifdef FEATURE_WLAN_TDLS +VOS_STATUS iw_set_tdls_params(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra, int nOffset); +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value); +#endif + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set); +#endif +void* wlan_hdd_change_country_code_callback(void *pAdapter); + +VOS_STATUS wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode); + +int hdd_setBand(struct net_device *dev, u8 ui_band); +int hdd_setBand_helper(struct net_device *dev, const char *command); +int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal, + int new_phymode, + hdd_context_t *phddctx); + +int process_wma_set_command_twoargs(int sessid, int paramid, + int sval, int ssecval, int vpdev); +#endif // __WEXT_IW_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wmm.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wmm.h new file mode 100644 index 0000000000000..dea928f0dc273 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wmm.h @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _WLAN_HDD_WMM_H +#define _WLAN_HDD_WMM_H +/*============================================================================ + @file wlan_hdd_wmm.h + + This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation) + houses all the logic for WMM in HDD. + + On the control path, it has the logic to setup QoS, modify QoS and delete + QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an + explicit application invoked and an internal HDD invoked. The implicit QoS + is for applications that do NOT call the custom QCT WLAN OIDs for QoS but + which DO mark their traffic for prioritization. It also has logic to start, + update and stop the U-APSD trigger frame generation. It also has logic to + read WMM related config parameters from the registry. + + On the data path, it has the logic to figure out the WMM AC of an egress + packet and when to signal TL to serve a particular AC queue. It also has the + logic to retrieve a packet based on WMM priority in response to a fetch from + TL. + + The remaining functions are utility functions for information hiding. +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +// #define HDD_WMM_DEBUG 1 + +#define HDD_WMM_CTX_MAGIC 0x574d4d58 // "WMMX" + +#define HDD_WMM_HANDLE_IMPLICIT 0xFFFFFFFF + +#define HDD_WLAN_INVALID_STA_ID 0xFF + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*! @brief AC/Queue Index values for Linux Qdisc to operate on different traffic. +*/ +typedef enum +{ + HDD_LINUX_AC_VO = 0, + HDD_LINUX_AC_VI = 1, + HDD_LINUX_AC_BE = 2, + HDD_LINUX_AC_BK = 3 + +} hdd_wmm_linuxac_t; + +/*! @brief types of classification supported +*/ +typedef enum +{ + HDD_WMM_CLASSIFICATION_DSCP = 0, + HDD_WMM_CLASSIFICATION_802_1Q = 1 + +} hdd_wmm_classification_t; + +/*! @brief UAPSD state +*/ +typedef enum +{ + HDD_WMM_NON_UAPSD = 0, + HDD_WMM_UAPSD = 1 + +} hdd_wmm_uapsd_state_t; + + +typedef enum +{ + //STA can associate with any AP, & HDD looks at the SME notification after + // association to find out if associated with QAP and acts accordingly + HDD_WMM_USER_MODE_AUTO = 0, + //SME will add the extra logic to make sure STA associates with a QAP only + HDD_WMM_USER_MODE_QBSS_ONLY = 1, + //SME will not join a QoS AP, unless the phy mode setting says "Auto". In + // that case, STA is free to join 11n AP. Although from HDD point of view, + // it will not be doing any packet classifications + HDD_WMM_USER_MODE_NO_QOS = 2, + +} hdd_wmm_user_mode_t; + +// UAPSD Mask bits +// (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) +#define HDD_AC_VO 0x1 +#define HDD_AC_VI 0x2 +#define HDD_AC_BK 0x4 +#define HDD_AC_BE 0x8 + +/*! @brief WMM Qos instance control block +*/ +typedef struct +{ + struct list_head node; + v_U32_t handle; + v_U32_t qosFlowId; + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wlan_wmm_status_e lastStatus; + struct work_struct wmmAcSetupImplicitQos; + v_U32_t magic; +} hdd_wmm_qos_context_t; + +/*! @brief WMM related per-AC state & status info +*/ +typedef struct +{ + // does the AP require access to this AC? + v_BOOL_t wmmAcAccessRequired; + + // does the worker thread need to acquire access to this AC? + v_BOOL_t wmmAcAccessNeeded; + + // is implicit QoS negotiation currently taking place? + v_BOOL_t wmmAcAccessPending; + + // has implicit QoS negotiation already failed? + v_BOOL_t wmmAcAccessFailed; + + // has implicit QoS negotiation already succeeded? + v_BOOL_t wmmAcAccessGranted; + + /* + * Is access to this AC allowed, either because we are not doing + * WMM, we are not doing implicit QoS, implicit QoS has completed, + * or explicit QoS has completed? + */ + v_BOOL_t wmmAcAccessAllowed; + + // is the wmmAcTspecInfo valid? + v_BOOL_t wmmAcTspecValid; + + // are the wmmAcUapsd* fields valid? + v_BOOL_t wmmAcUapsdInfoValid; + + // current (possibly aggregate) Tspec for this AC + sme_QosWmmTspecInfo wmmAcTspecInfo; + + // current U-APSD parameters + v_BOOL_t wmmAcIsUapsdEnabled; + v_U32_t wmmAcUapsdServiceInterval; + v_U32_t wmmAcUapsdSuspensionInterval; + sme_QosWmmDirType wmmAcUapsdDirection; + +#ifdef FEATURE_WLAN_ESE + // Inactivity time parameters for TSPEC + v_U32_t wmmInactivityTime; + v_U32_t wmmPrevTrafficCnt; + vos_timer_t wmmInactivityTimer; +#endif + +} hdd_wmm_ac_status_t; + +/*! @brief WMM state & status info +*/ +typedef struct +{ + struct list_head wmmContextList; + struct mutex wmmLock; + hdd_wmm_ac_status_t wmmAcStatus[WLANTL_MAX_AC]; + v_BOOL_t wmmQap; + v_BOOL_t wmmQosConnection; +} hdd_wmm_status_t; + +extern const v_U8_t hdd_QdiscAcToTlAC[]; +extern const v_U8_t hddWmmUpToAcMap[]; +extern const v_U8_t hddLinuxUpToAcMap[]; + +#define WLAN_HDD_MAX_DSCP 0x3f + +/**============================================================================ + @brief hdd_wmm_init() - Function which will initialize the WMM configuration + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_wmm_adapter_init() - Function which will initialize the WMM + configuration and status to an initial state. + The configuration can later be overwritten via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_wmm_adapter_close() - Function which will perform any necessary work to + to clean up the WMM functionality prior to the kernel module unload + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter ); + +/**============================================================================ + @brief hdd_wmm_select_queue() - Function which will classify an OS packet + into Linux Qdisc expectation + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to OS packet (sk_buff) + + @return : queue_index/Linux AC value. + ===========================================================================*/ +v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb); + +/**============================================================================ + @brief hdd_hostapd_select_queue() - Function which will classify the packet + according to Linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ + +v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb); + + + +/**============================================================================ + @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet + into a WMM AC based on either 802.1Q or DSCP + + @param pAdapter : [in] pointer to adapter context + @param skb : [in] pointer to OS packet (sk_buff) + @param pAcType : [out] pointer to WMM AC type of OS packet + + @return : None + ===========================================================================*/ +v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter, + struct sk_buff *skb, + WLANTL_ACEnumType* pAcType, + sme_QosWmmUpType* pUserPri); + + +/**============================================================================ + @brief hdd_wmm_acquire_access() - Function which will attempt to acquire + admittance for a WMM AC + + @param pAdapter : [in] pointer to adapter context + @param acType : [in] WMM AC type of OS packet + @param pGranted : [out] pointer to boolean flag when indicates if access + has been granted or not + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter, + WLANTL_ACEnumType acType, + v_BOOL_t * pGranted ); + +/**============================================================================ + @brief hdd_wmm_assoc() - Function which will handle the housekeeping + required by WMM when association takes place + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ); + +/**============================================================================ + @brief hdd_wmm_connect() - Function which will handle the housekeeping + required by WMM when a connection is established + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ); + +/**============================================================================ + @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the + initial value of the UAPSD mask based upon the device configuration + + @param pAdapter : [in] pointer to adapter context + @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter, + tANI_U8 *pUapsdMask ); + +/**============================================================================ + @brief hdd_wmm_is_active() - Function which will determine if WMM is + active on the current connection + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_TRUE if WMM is enabled + : VOS_FALSE if WMM is not enabled + ===========================================================================*/ +v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter ); + +/**============================================================================ + @brief hdd_wmm_addts() - Function which will add a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + @param pTspec : [in] pointer to the traffic spec + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter, + v_U32_t handle, + sme_QosWmmTspecInfo* pTspec ); + +/**============================================================================ + @brief hdd_wmm_delts() - Function which will delete a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter, + v_U32_t handle ); + +/**============================================================================ + @brief hdd_wmm_checkts() - Function which will return the status of a traffic + spec at the request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter, + v_U32_t handle ); +/**============================================================================ + @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status + of all ACs + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter ); + +#endif /* #ifndef _WLAN_HDD_WMM_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wowl.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wowl.h new file mode 100644 index 0000000000000..398a2425bc5da --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_hdd_wowl.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_WOWL_H +#define _WLAN_HDD_WOWL_H + +/*============================================================================ + @file wlan_hdd_wowl.h + + This module houses all the logic for WOWL in HDD. + + It provides the following APIs + + - Ability to enable/disable following WoWL modes + 1) Magic packet (MP) mode + 2) Pattern Byte Matching (PBM) mode + - Ability to add/remove patterns for PBM + + A Magic Packet is a packet that contains 6 0xFFs followed by 16 contiguous + copies of the receiving NIC's Ethernet address. There is no API to configure + Magic Packet Pattern. + + Wakeup pattern (used for PBM) is defined as following: + typedef struct + { + U8 PatternSize; // Non-Zero pattern size + U8 PatternMaskSize; // Non-zero pattern mask size + U8 PatternMask[PatternMaskSize]; // Pattern mask + U8 Pattern[PatternSize]; // Pattern + } hdd_wowl_ptrn_t; + + PatternSize and PatternMaskSize indicate size of the variable length Pattern + and PatternMask. PatternMask indicates which bytes of an incoming packet + should be compared with corresponding bytes in the pattern. + + Maximum allowed pattern size is 128 bytes. Maximum allowed PatternMaskSize + is 16 bytes. + + Maximum number of patterns that can be configured is 8 + + HDD will add following 2 commonly used patterns for PBM by default: + 1) ARP Broadcast Pattern + 2) Unicast Pattern + + However note that WoWL will not be enabled by default by HDD. WoWL needs to + enabled explicitly by exercising the iwpriv command. + + HDD will expose an API that accepts patterns as Hex string in the following + format: "PatternSize:PatternMaskSize:PatternMask:Pattern". Multiple patterns + can be specified by delimiting each pattern with the ';' token. + "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:...." + + Patterns can be configured dynamically via iwpriv cmd or statically via + qcom_cfg.ini file + + PBM (when enabled) can perform filtering on unicast data or broadcast data or + both. These configurations are part of factory defaults (cfg.dat) and + the default behavior is to perform filtering on both unicast and data frames. + + MP filtering (when enabled) is performed ALWAYS on both unicast and broadcast + data frames. + + Management frames are not subjected to WoWL filtering and are discarded when + WoWL is enabled. + + Whenever a pattern match succeeds, RX path is restored and packets (both + management and data) will be pushed to the host from that point onwards. + Therefore, exit from WoWL is implicit and happens automatically when the + first packet match succeeds. + + WoWL works on top of BMPS. So when WoWL is requested, SME will attempt to put + the device in BMPS mode (if not already in BMPS). If attempt to BMPS fails, + request for WoWL will be rejected. + +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WOWL_PTRN_MAX_SIZE 146 +#define WOWL_PTRN_MASK_MAX_SIZE 19 +#define WOWL_MAX_PTRNS_ALLOWED 22 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/**============================================================================ + @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be + used when PBM filtering is enabled + + @param ptrn : [in] pointer to the pattern string to be added + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn); + +/**============================================================================ + @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern + + @param ptrn : [in] pointer to the pattern string to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn); + +/**============================================================================ + @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be added + pattern_offset : [in] offset of the pattern in the frame payload + pattern_buf : [in] pointer to the pattern hex string to be added + pattern_mask : [in] pointer to the pattern mask hex string + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx, + v_U8_t pattern_offset, char *pattern_buf, + char *pattern_mask); + +/**============================================================================ + @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx); + +/**============================================================================ + @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one + of MP and PBM must be enabled + + @param enable_mp : [in] Whether to enable magic packet WoWL mode + @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_enter_wowl (hdd_adapter_t *pAdapter, v_BOOL_t enable_mp, v_BOOL_t enable_pbm); + +/**============================================================================ + @brief hdd_exit_wowl() - Function which will disable WoWL + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter); + +/**============================================================================ + @brief hdd_init_wowl() - Init function which will initialize the WoWL module + and perform any required initial configuration + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_init_wowl (hdd_adapter_t* pAdapter); + +/**============================================================================ + @brief hdd_parse_hex() - function returns integer equivalent of hexa decimal + + @return : integer equivalent of hexa decimal + ===========================================================================*/ +int hdd_parse_hex(unsigned char c); + +#endif /* #ifndef _WLAN_HDD_WOWL_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_qct_driver.h b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_qct_driver.h new file mode 100644 index 0000000000000..31c30706b9c79 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/inc/wlan_qct_driver.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_DRIVER_H ) +#define __WLAN_QCT_DRIVER_H + +/**======================================================================== + + \file wlan_qct_driver.h + + \brief Header file for Wireless LAN Host Device Driver Kernel Module + + ========================================================================*/ + +/**======================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/05/09 kanand Created module. + + ===========================================================================*/ + +/*-------------------------------------------------------------------------- + * Include Files + *------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Preprocessor definitions and constants + *-------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Type declarations + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function declarations and documentation + * ------------------------------------------------------------------------*/ + +#endif // if !defined __WLAN_QCT_DRIVER_H diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/bap_hdd_main.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/bap_hdd_main.c new file mode 100644 index 0000000000000..85632ac8d1c9e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/bap_hdd_main.c @@ -0,0 +1,4576 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file bap_hdd_main.c + + \brief 802.11 BT-AMP PAL Host Device Driver implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/gb-bluez/vendor/qcom/proprietary/wlan/libra/CORE/HDD/src/bap_hdd_main.c,v 1.63 2011/04/01 15:24:20 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 12/1/09 JZmuda Created module. + + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#ifdef WLAN_BTAMP_FEATURE +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +//#include +#include +#include +/* -------------------------------------------------------------------------*/ +#include +#include +#include +#include +/* -------------------------------------------------------------------------*/ +#include +#include + +#include +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +// the difference between the next two is that the first is the max +// number we support in our current implementation while the second is +// the max allowed by the spec +#define BSL_MAX_PHY_LINKS ( BSL_MAX_CLIENTS * BSL_MAX_PHY_LINK_PER_CLIENT ) +#define BSL_MAX_ALLOWED_PHY_LINKS 255 + +// these likely will need tuning based on experiments +#define BSL_MAX_RX_PKT_DESCRIPTOR 100 +#define BSL_MAX_TX_PKT_DESCRIPTOR 100 + +// these caps are in place to not have run-away queues, again needs empirical tuning +#define BSL_MAX_SIZE_TX_ACL_QUEUE 50 +#define BSL_MAX_SIZE_RX_ACL_QUEUE 50 +#define BSL_MAX_SIZE_RX_EVT_QUEUE 50 + +#if 0 +What are the maximum sizes of a command packet, an event packet and an ACL +data packet? + +[JimZ]: Sizes: +1. Cmd Maximum size is slightly greater than 672 btyes. But I am pretty sure +right now that I will never have more than 240 bytes to send down at a time. And +that is good. Because some rather unpleasant things happen at the HCI interface +if I exceed that. ( Think 8-bit CPUs. And the limitations of an 8-bit length + field. ) + +2. Event - Ditto. + +3. Data 1492 bytes +#endif + +// jimz +// TLV related defines + +#define USE_FINAL_FRAMESC +//#undef USE_FINAL_FRAMESC +// jimz +// TLV related defines + +#ifndef USE_FINAL_FRAMESC //USE_FINAL_FRAMESC +// AMP ASSOC TLV related defines +#define AMP_ASSOC_TLV_TYPE_SIZE 2 +#define AMP_ASSOC_TLV_LEN_SIZE 2 +#define AMP_ASSOC_TLV_TYPE_AND_LEN_SIZE (AMP_ASSOC_TLV_TYPE_SIZE + AMP_ASSOC_TLV_LEN_SIZE) + +// FLOW SPEC TLV related defines +#define FLOWSPEC_TYPE_SIZE 2 +#define FLOWSPEC_LEN_SIZE 2 +#define FLOWSPEC_TYPE_AND_LEN_SIZE (FLOWSPEC_TYPE_SIZE + FLOWSPEC_LEN_SIZE) + +// CMD TLV related defines +#define CMD_TLV_TYPE_SIZE 2 +#define CMD_TLV_LEN_SIZE 2 +#define CMD_TLV_TYPE_AND_LEN_SIZE (CMD_TLV_TYPE_SIZE + CMD_TLV_LEN_SIZE) + +// Event TLV related defines +#define EVENT_TLV_TYPE_SIZE 2 +#define EVENT_TLV_LEN_SIZE 2 +#define EVENT_TLV_TYPE_AND_LEN_SIZE (EVENT_TLV_TYPE_SIZE + EVENT_TLV_LEN_SIZE) + +// Data header size related defines +#define DATA_HEADER_SIZE 4 + +#else //USE_FINAL_FRAMESC + +// AMP ASSOC TLV related defines +#define AMP_ASSOC_TLV_TYPE_SIZE 1 +#define AMP_ASSOC_TLV_LEN_SIZE 2 +#define AMP_ASSOC_TLV_TYPE_AND_LEN_SIZE (AMP_ASSOC_TLV_TYPE_SIZE + AMP_ASSOC_TLV_LEN_SIZE) + +// FLOW SPEC TLV related defines +#define FLOWSPEC_TYPE_SIZE 1 +#define FLOWSPEC_LEN_SIZE 1 +#define FLOWSPEC_TYPE_AND_LEN_SIZE (FLOWSPEC_TYPE_SIZE + FLOWSPEC_LEN_SIZE) + +// CMD TLV related defines +#define CMD_TLV_TYPE_SIZE 2 +#define CMD_TLV_LEN_SIZE 1 +#define CMD_TLV_TYPE_AND_LEN_SIZE (CMD_TLV_TYPE_SIZE + CMD_TLV_LEN_SIZE) + +// Event TLV related defines +#define EVENT_TLV_TYPE_SIZE 1 +#define EVENT_TLV_LEN_SIZE 1 +#define EVENT_TLV_TYPE_AND_LEN_SIZE (EVENT_TLV_TYPE_SIZE + EVENT_TLV_LEN_SIZE) + +// Data header size related defines +#define DATA_HEADER_SIZE 4 + +#endif // USE_FINAL_FRAMESC +// jimz + +#define BSL_MAX_EVENT_SIZE 700 + +#define BSL_DEV_HANDLE 0x1234 + +// Debug related defines +#define DBGLOG printf +//#define DUMPLOG +#if defined DUMPLOG +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + DBGLOG("%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + DBGLOG("%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + DBGLOG("\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +// These are required to replace some Microsoft specific specifiers +//#define UNALIGNED __align +#define UNALIGNED +#define INFINITE 0 + +#define BT_AMP_HCI_CTX_MAGIC 0x48434949 // "HCII" + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +// Temporary Windows types +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef void * HANDLE; +typedef char TCHAR; +typedef void *LPVOID; +typedef const void *LPCVOID; + +typedef struct +{ + BOOL used; // is this a valid context? + vos_event_t ReadableEvt; // the event a ReadFile can block on + ptBtampHandle bapHdl; // our handle in BAP + vos_list_t PhyLinks; // a list of all associations setup by this client +// Newly added for BlueZ + struct hci_dev *hdev; // the BlueZ HCI device structure + + /* I don't know how many of these Tx fields we need */ + spinlock_t lock; /* For serializing operations */ + + struct sk_buff_head txq; /* We need the ACL Data Tx queue */ + + /* We definitely need some of these rx_skb fields */ + unsigned long rx_state; + unsigned long rx_count; + struct sk_buff *rx_skb; + + struct net_device *p_dev; // Our parent wlan network device + +} BslClientCtxType; + +typedef struct +{ + BslClientCtxType* pctx; + /* Tx skb queue and the workstructure for handling Tx as deferred work. */ + struct sk_buff *tx_skb; + + struct work_struct hciInterfaceProcessing; + v_U32_t magic; + +} BslHciWorkStructure; + +typedef struct +{ + TCHAR* ValueName; // name of the value + DWORD Type; // type of value + DWORD DwordValue; // DWORD value + TCHAR* StringValue; // string value + +} BslRegEntry; + +typedef struct +{ + BOOL used; // is this a valid context? + hdd_list_t ACLTxQueue[WLANTL_MAX_AC]; // the TX ACL queues + BslClientCtxType* pClientCtx; // ptr to application context that spawned + // this association + v_U8_t PhyLinkHdl; // BAP handle for this association + void* pPhyLinkDescNode; // ptr to node in list of assoc in client ctx + // real type BslPhyLinksNodeType* + +} BslPhyLinkCtxType; + +typedef struct +{ + vos_list_node_t node; // MUST be first element + BslPhyLinkCtxType* pPhy; // ptr to an association context + +} BslPhyLinksNodeType; + +typedef struct +{ + vos_list_node_t node; // MUST be first element + vos_pkt_t* pVosPkt; // ptr to a RX VoS pkt which can hold an HCI event or ACL data + +} BslRxListNodeType; + +// Borrowed from wlan_hdd_dp_utils.h +typedef struct +{ + hdd_list_node_t node; // MUST be first element + struct sk_buff * skb; // ptr to the ACL data + +} BslTxListNodeType; + +typedef struct +{ + BslPhyLinkCtxType* ptr; // ptr to the association context for this phy_link_handle + +} BslPhyLinkMapEntryType; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +BslClientCtxType* gpBslctx; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +// Temporary (until multi-phy link) pointer to BT-AMP context +static void *gpCtx; + +// an efficient lookup from phy_link_handle to phy link context +static BslPhyLinkMapEntryType BslPhyLinkMap[BSL_MAX_ALLOWED_PHY_LINKS]; + +//static HANDLE hBsl = NULL; //INVALID_HANDLE_VALUE; +static BOOL bBslInited = FALSE; + +static BslClientCtxType BslClientCtx[BSL_MAX_CLIENTS]; +//static vos_lock_t BslClientLock; + +static BslPhyLinkCtxType BslPhyLinkCtx[BSL_MAX_PHY_LINKS]; +//static vos_lock_t BslPhyLock; + +// the pool for association contexts +static vos_list_t BslPhyLinksDescPool; +static BslPhyLinksNodeType BslPhyLinksDesc[BSL_MAX_PHY_LINKS]; + +//static v_U32_t Eventlen = 0; + +/*--------------------------------------------------------------------------- + * Forward declarations + *-------------------------------------------------------------------------*/ +static void bslWriteFinish(struct work_struct *work); + +/*--------------------------------------------------------------------------- + * Driver Entry points and Structure definitions + *-------------------------------------------------------------------------*/ +static int BSL_Open (struct hci_dev *hdev); +static int BSL_Close (struct hci_dev *hdev); +static int BSL_Flush(struct hci_dev *hdev); +static int BSL_IOControl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); +static int BSL_Write(struct sk_buff *skb); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static void BSL_Destruct(struct hci_dev *hdev); +#endif + + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ +static v_BOOL_t WLANBAP_AmpConnectionAllowed(void) +{ + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + v_BOOL_t retVal = VOS_FALSE; + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + return pHddCtx->isAmpAllowed; + } + else + { + return retVal; + } + } + return retVal; +} + +/** + @brief WLANBAP_STAFetchPktCB() - The fetch packet callback registered + with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STAFetchPktCBType routine being called. Which is called by + TL when the scheduling algorithms allows for transmission of another + packet to the module. + + This function is here to "wrap" or abstract WLANTL_STAFetchPktCBType. + Because the BAP-specific HDD "shim" layer (BSL) doesn't know anything + about STAIds, or other parameters required by TL. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STAFetchCBType to retreive + this value. + @param pucAC: [inout] access category requested by TL, if HDD does not + have packets on this AC it can choose to service another AC queue in + the order of priority + @param vosDataBuff: [out] pointer to the VOSS data buffer that was + transmitted + @param tlMetaInfo: [out] meta info related to the data frame + + @return + The result code associated with performing the operation +*/ +static VOS_STATUS WLANBAP_STAFetchPktCB +( + v_PVOID_t pHddHdl, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +) +{ + BslPhyLinkCtxType* pPhyCtx; + VOS_STATUS VosStatus; + v_U8_t AcIdxStart; + v_U8_t AcIdx; + hdd_list_node_t *pLink; + BslTxListNodeType *pNode; + struct sk_buff * skb; + BslClientCtxType* pctx; + WLANTL_ACEnumType Ac; + vos_pkt_t* pVosPkt; + WLANTL_MetaInfoType TlMetaInfo; + pctx = &BslClientCtx[0]; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "WLANBAP_STAFetchPktCB" ); + + // sanity checking + if( pHddHdl == NULL || vosDataBuff == NULL || + tlMetaInfo == NULL || ucAC >= WLANTL_MAX_AC || ucAC < 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + // Initialize the VOSS packet returned to NULL - in case of error + *vosDataBuff = NULL; + + pPhyCtx = (BslPhyLinkCtxType *)pHddHdl; + AcIdx = AcIdxStart = ucAC; + + spin_lock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + VosStatus = hdd_list_remove_front( &pPhyCtx->ACLTxQueue[AcIdx], &pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + + if ( VOS_STATUS_E_EMPTY == VosStatus ) + { + do + { + AcIdx = (AcIdx + 1) % WLANTL_MAX_AC; + + spin_lock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + VosStatus = hdd_list_remove_front( &pPhyCtx->ACLTxQueue[AcIdx], &pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + + } + while ( VosStatus == VOS_STATUS_E_EMPTY && AcIdx != AcIdxStart ); + + if ( VosStatus == VOS_STATUS_E_EMPTY ) + { + // Queue is empty. This can happen. Just return NULL back to TL... + return(VOS_STATUS_E_EMPTY); + } + else if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT( 0 ); + } + } + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT( 0 ); + } + + pNode = (BslTxListNodeType *)pLink; + skb = pNode->skb; + + // I will access the skb in a VOSS packet + // Wrap the OS provided skb in a VOSS packet + // Attach skb to VOS packet. + VosStatus = vos_pkt_wrap_data_packet( &pVosPkt, + VOS_PKT_TYPE_TX_802_3_DATA, + skb, + NULL, + NULL); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB vos_pkt_wrap_data_packet " + "failed status =%d", VosStatus ); + kfree_skb(skb); + return VosStatus; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s: pVosPkt(vos_pkt_t *)=%p", __func__, + pVosPkt ); + + VosStatus = WLANBAP_XlateTxDataPkt( pctx->bapHdl, pPhyCtx->PhyLinkHdl, + &Ac, &TlMetaInfo, pVosPkt); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB WLANBAP_XlateTxDataPkt " + "failed status =%d", VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + kfree_skb(skb); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return VosStatus; + } + // give TL the VoS pkt + *vosDataBuff = pVosPkt; + + // provide the meta-info BAP provided previously + *tlMetaInfo = TlMetaInfo; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: *vosDataBuff(vos_pkt_t *)=%p", __func__, *vosDataBuff ); + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_STAFetchPktCB() + +/** + @brief WLANBAP_STARxCB() - The receive callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STARxCBType routine being called. Which is called by + TL to notify when a packet was received for a registered STA. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STARxCBType to retrieve this value. + @param vosDataBuff: [in] pointer to the VOSS data buffer that was received + (it may be a linked list) + @param pRxMetaInfo: [in] Rx meta info related to the data frame + + @return + The result code associated with performing the operation +*/ +static VOS_STATUS WLANBAP_STARxCB +( + v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + WLANTL_RxMetaInfoType* pRxMetaInfo +) +{ + BslPhyLinkCtxType* pctx; + BslClientCtxType* ppctx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + WLANTL_ACEnumType Ac; // this is not needed really + struct sk_buff *skb = NULL; + vos_pkt_t* pVosPacket; + vos_pkt_t* pNextVosPacket; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "WLANBAP_STARxCB" ); + + // sanity checking + if ( pHddHdl == NULL || vosDataBuff == NULL || pRxMetaInfo == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STARxCB bad input" ); + if(NULL != vosDataBuff) + { + VosStatus = vos_pkt_return_packet( vosDataBuff ); + } + return VOS_STATUS_E_FAILURE; + } + + pctx = (BslPhyLinkCtxType *)pHddHdl; + ppctx = pctx->pClientCtx; + + if( NULL == ppctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STARxCB ClientCtx is NULL" ); + VosStatus = vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAILURE; + } + + // walk the chain until all are processed + pVosPacket = vosDataBuff; + do + { + // get the pointer to the next packet in the chain + // (but don't unlink the packet since we free the entire chain later) + VosStatus = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE); + + // both "success" and "empty" are acceptable results + if (!((VosStatus == VOS_STATUS_SUCCESS) || (VosStatus == VOS_STATUS_E_EMPTY))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,"%s: Failure walking packet chain", __func__); + return VOS_STATUS_E_FAILURE; + } + + // process the packet + VosStatus = WLANBAP_XlateRxDataPkt( ppctx->bapHdl, pctx->PhyLinkHdl, + &Ac, pVosPacket ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "WLANBAP_STARxCB WLANBAP_XlateRxDataPkt " + "failed status = %d", VosStatus ); + + VosStatus = VOS_STATUS_E_FAILURE; + + break; + } + + // Extract the OS packet (skb). + // Tell VOS to detach the OS packet from the VOS packet + VosStatus = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: Failure extracting skb from vos pkt. " + "VosStatus = %d", __func__, VosStatus ); + + VosStatus = VOS_STATUS_E_FAILURE; + + break; + } + + //JEZ100809: While an skb is being handled by the kernel, is "skb->dev" de-ref'd? + skb->dev = (struct net_device *) gpBslctx->hdev; + bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; + //skb->protocol = eth_type_trans(skb, skb->dev); + //skb->ip_summed = CHECKSUM_UNNECESSARY; + + // This is my receive skb pointer + gpBslctx->rx_skb = skb; + + // This is how data and events are passed up to BlueZ + hci_recv_frame(gpBslctx->rx_skb); + + // now process the next packet in the chain + pVosPacket = pNextVosPacket; + + } while (pVosPacket); + + + //JEZ100922: We are free to return the enclosing VOSS packet. + VosStatus = vos_pkt_return_packet( vosDataBuff ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_STARxCB() + +/** + @brief WLANBAP_TxCompCB() - The Tx complete callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_TxCompCBType routine being called. Which is called by + TL to notify when a transmission for a packet has ended. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association + @param vosDataBuff: [in] pointer to the VOSS data buffer that was transmitted + @param wTxSTAtus: [in] status of the transmission + + @return + The result code associated with performing the operation +*/ +extern v_VOID_t WLANBAP_TxPacketMonitorHandler ( v_PVOID_t ); // our handle in BAP + +static VOS_STATUS WLANBAP_TxCompCB +( + v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + //BslTxListNodeType* pTxNode; + void* pOsPkt = NULL; + BslPhyLinkCtxType* pctx; + BslClientCtxType* ppctx; + static int num_packets; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "WLANBAP_TxCompCB. vosDataBuff(vos_pkt_t *)=%p", vosDataBuff ); + + // be aware that pHddHdl can be NULL or can point to the per association + // BSL context from the register data plane. In either case it does not + // matter since we will simply free the VoS pkt and reclaim the TX + // descriptor + + // sanity checking + if ( vosDataBuff == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_TxCompCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + VosStatus = vos_pkt_get_os_packet( vosDataBuff, &pOsPkt, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAILURE; + } + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + VosStatus = vos_pkt_return_packet( vosDataBuff ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // JEZ110330: Now signal the layer above me...that I have released some packets. + pctx = (BslPhyLinkCtxType *)pHddHdl; + ppctx = pctx->pClientCtx; + num_packets = (num_packets + 1) % 4; + if (num_packets == 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s: Sending up number of completed packets. num_packets = %d.", __func__, num_packets ); + WLANBAP_TxPacketMonitorHandler ( (v_PVOID_t) ppctx->bapHdl ); // our handle in BAP + } + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_TxCompCB() + +/** + @brief BslFlushTxQueues() - flush the Tx queues + + @param pPhyCtx : [in] ptr to the phy context whose queues need to be flushed + + @return + VOS_STATUS + +*/ +static VOS_STATUS BslFlushTxQueues +( + BslPhyLinkCtxType* pPhyCtx +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + hdd_list_node_t* pLink; + BslTxListNodeType *pNode; + + + if(TRUE == pPhyCtx->used) + { + while (++i != WLANTL_MAX_AC) + { + //Free up any packets in the Tx queue + spin_lock_bh(&pPhyCtx->ACLTxQueue[i].lock); + while (true) + { + VosStatus = hdd_list_remove_front(&pPhyCtx->ACLTxQueue[i], &pLink ); + if(VOS_STATUS_E_EMPTY != VosStatus) + { + pNode = (BslTxListNodeType *)pLink; + kfree_skb(pNode->skb); + continue; + } + break; + } + spin_unlock_bh(&pPhyCtx->ACLTxQueue[i].lock); + } + } + return(VOS_STATUS_SUCCESS); +} // BslFlushTxQueues + + +/** + @brief BslReleasePhyCtx() - this function will free up an association context + + @param pPhyCtx : [in] ptr to the phy context to release + + @return + None + +*/ +static void BslReleasePhyCtx +( + BslPhyLinkCtxType* pPhyCtx +) +{ + uintptr_t OldMapVal; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslReleasePhyCtx" ); + + pPhyCtx->used = FALSE; + + + if (BslPhyLinkMap[pPhyCtx->PhyLinkHdl].ptr == NULL) return; + + + // update the phy link handle based map so TX data is stopped from flowing through + OldMapVal = vos_atomic_set( (uintptr_t *) (BslPhyLinkMap[pPhyCtx->PhyLinkHdl].ptr), + (uintptr_t) 0 ); + + // clear out the Tx Queues + VosStatus = BslFlushTxQueues(pPhyCtx); + + // clear out the parent ptr + // pPhyCtx->pClientCtx = NULL;//commented to debug exception + + // we also need to remove this assocation from the list of active + // associations maintained in the application context + if( pPhyCtx->pPhyLinkDescNode ) + { + VosStatus = vos_list_remove_node( &pPhyCtx->pClientCtx->PhyLinks, + &((BslPhyLinksNodeType*)pPhyCtx->pPhyLinkDescNode)->node); + if (VOS_STATUS_SUCCESS != VosStatus) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: vos_list_remove_node() is not succses", __func__); + } else { + //Return the PhyLink handle to the free pool + VosStatus = vos_list_insert_front(&BslPhyLinksDescPool,&((BslPhyLinksNodeType*)pPhyCtx->pPhyLinkDescNode)->node); + if (VOS_STATUS_SUCCESS != VosStatus) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: vos_list_insert_front() is not succses", __func__); + } + } + pPhyCtx->pPhyLinkDescNode = NULL; + } + pPhyCtx->pClientCtx = NULL;//Moved here to bebug the exception + + pPhyCtx->used = FALSE; + +} // BslReleasePhyCtx() + +/** + @brief WLAN_BAPEventCB() - Implements the callback for ALL asynchronous events. + + Including Events resulting from: + * HCI Create Physical Link, + * Disconnect Physical Link, + * Create Logical Link, + * Flow Spec Modify, + * HCI Reset, + * HCI Flush,... + + Also used to return sync events locally by BSL + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + BSL gets this from the downgoing packets Physical handle value. + @param pBapHCIEvent: [in] pointer to the union of "HCI Event" structures. + Contains all info needed for HCI event. + @param AssocSpecificEvent: [in] flag indicates assoc-specific (1) or + global (0) event + + @return + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success +*/ +static VOS_STATUS WLANBAP_EventCB +( + v_PVOID_t pHddHdl, /* this could refer to either the BSL per + association context which got passed in during + register data plane OR the BSL per application + context passed in during register BAP callbacks + based on setting of the Boolean flag below */ + tpBtampHCI_Event pBapHCIEvent, /* This now encodes ALL event types including + Command Complete and Command Status*/ + v_BOOL_t AssocSpecificEvent /* Flag to indicate global or assoc-specific event */ +) +{ + BslClientCtxType* pctx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + vos_pkt_t* pVosPkt; + v_U32_t PackStatus; + static v_U8_t Buff[BSL_MAX_EVENT_SIZE]; // stack overflow? + v_U32_t Written = 0; // FramesC REQUIRES this + v_U32_t OldMapVal; + struct sk_buff *skb = NULL; + + // sanity checking + if ( pBapHCIEvent == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB event=%d " + "assoc_specific=%d", pBapHCIEvent->bapHCIEventCode, AssocSpecificEvent ); + + if ( pHddHdl == NULL ) + { + /* Consider the following error scenarios to bypass the NULL check: + - create LL without a call for create PL before + - delete LL or PL when no AMP connection has been established yet + Client context is unimportant from HCI point of view, only needed by the TLV API in BAP + TODO: Change the TLV APIs to not to carry the client context; it doesn't use it anyway + */ + if (( AssocSpecificEvent ) && + (BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT != pBapHCIEvent->bapHCIEventCode) && + (BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT != pBapHCIEvent->bapHCIEventCode)) + { + pctx = gpBslctx; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "WLANBAP_EventCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + } + + + if(NULL != pHddHdl) + { + if ( AssocSpecificEvent ) + { + // get the app context from the assoc context + pctx = ((BslPhyLinkCtxType *)pHddHdl)->pClientCtx; + } + else + { + pctx = (BslClientCtxType *)pHddHdl; + } + } + + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pctx is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + + } + + VosStatus = vos_pkt_get_packet( &pVosPkt, VOS_PKT_TYPE_RX_RAW, + BSL_MAX_EVENT_SIZE, 1, 0, NULL, NULL); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB vos_pkt_get_packet " + "failed status=%d", VosStatus ); + return(VosStatus); + } + + switch ( pBapHCIEvent->bapHCIEventCode ) + { + /** BT events */ + case BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT: + { + /* + BTAMP_TLV_HCI_RESET_CMD: + BTAMP_TLV_HCI_FLUSH_CMD: + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD: + BTAMP_TLV_HCI_SET_EVENT_MASK_CMD: + BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD: + BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD: + BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD: + BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD: + BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD: + BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD: + BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TO_CMD: + BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TO_CMD: + BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD: + BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFORMATION_CMD: + BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_COMMANDS_CMD: + BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD: + BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD: + BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD: + BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD: + BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD: + BTAMP_TLV_HCI_READ_RSSI_CMD: + BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD: + BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD: + BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD: + BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD: + BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD: + BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0: + + */ + + // pack + PackStatus = btampPackTlvHCI_Command_Complete_Event( pctx, + &pBapHCIEvent->u.btampCommandCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Command_Complete_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_COMMAND_STATUS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Command_Status_Event( pctx, + &pBapHCIEvent->u.btampCommandStatusEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Command_Status_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Num_Completed_Pkts_Event( pctx, + &pBapHCIEvent->u.btampNumOfCompletedPktsEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Num_Completed_Pkts_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Num_Completed_Data_Blocks_Event( pctx, + &pBapHCIEvent->u.btampNumOfCompletedDataBlocksEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Num_Completed_Data_Blocks_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Hardware_Error_Event( pctx, + &pBapHCIEvent->u.btampHardwareErrorEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Flush_Occurred_Event( pctx, + &pBapHCIEvent->u.btampFlushOccurredEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Flush_Occurred_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Enhanced_Flush_Complete_Event( pctx, + &pBapHCIEvent->u.btampEnhancedFlushCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Enhanced_Flush_Complete_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Loopback_Command_Event( pctx, + &pBapHCIEvent->u.btampLoopbackCommandEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Data_Buffer_Overflow_Event( pctx, + &pBapHCIEvent->u.btampDataBufferOverflowEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_QOS_VIOLATION_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Qos_Violation_Event( pctx, + &pBapHCIEvent->u.btampQosViolationEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + /** BT v3.0 events */ + case BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event( pctx, + &pBapHCIEvent->u.btampGenericAMPLinkKeyNotificationEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // look at this event to determine whether to cleanup the PHY context + if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_STATUS_SUCCESS ) + { + // register the data plane now + VosStatus = WLANBAP_RegisterDataPlane( pctx->bapHdl, + WLANBAP_STAFetchPktCB, + WLANBAP_STARxCB, + WLANBAP_TxCompCB, + (BslPhyLinkCtxType *)pHddHdl ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB WLANBAP_RegisterDataPlane " + "failed status = %d", VosStatus ); + // we still want to send the event upto app so do not bail + } + else + { + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); + +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + } + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_REJ_RESOURCES ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_TIMEOUT ) + { + //We need to update the phy link handle here to be able to reissue physical link accept + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); + +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_MAX_NUM_CNCTS ) + { + //We need to update the phy link handle here to be able to reissue physical link /create/accept + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_TIMEOUT ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + 0x16 /* WLANBAP_ERROR_FAILED_CONNECTION? */ ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + 0x8 /* WLANBAP_ERROR_AUTH_FAILED? */ ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_NO_CNCT ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected HCI Phy Link Comp Evt " + "status =%d", pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status ); + } + + break; + } + case BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Channel_Selected_Event( pctx, + &pBapHCIEvent->u.btampChannelSelectedEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // we need to cleanup the PHY context always but have these checks to make + // sure we catch unexpected behavior, strangely enough even when peer triggers + // the disconnect the reason code is still 0x16, weird + if ( pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.status == WLANBAP_STATUS_SUCCESS && + pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.reason == WLANBAP_ERROR_TERM_BY_LOCAL_HOST ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected HCI Dis Phy Link Comp Evt " + "status =%d reason =%d", pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.status, + pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.reason ); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Loss_Warning_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkLossWarningEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Recovery_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkRecoveryEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Logical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampLogicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Flow_Spec_Modify_Complete_Event( pctx, + &pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event( pctx, + &pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + default: + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected event" ); + + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + break; + } + } + + if (BSL_MAX_EVENT_SIZE < Written) + { + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(0); + return(VOS_STATUS_E_FAILURE); + } + + // stick the event into a VoS pkt + VosStatus = vos_pkt_push_head( pVosPkt, Buff, Written ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB vos_pkt_push_head " + "status =%d", VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // Extract the OS packet (skb). + // Tell VOS to detach the OS packet from the VOS packet + VosStatus = vos_pkt_get_os_packet( pVosPkt, (v_VOID_t **)&skb, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: Failure extracting skb from vos pkt. " + "VosStatus = %d", __func__, VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + //JEZ100922: We are free to return the enclosing VOSS packet. + VosStatus = vos_pkt_return_packet( pVosPkt ); + if(VOS_STATUS_SUCCESS != VosStatus) + { + // just print no action required + VOS_ASSERT(0); + } + + //JEZ100809: While an skb is being handled by the kernel, is "skb->dev" de-ref'd? + skb->dev = (struct net_device *) gpBslctx->hdev; + bt_cb(skb)->pkt_type = HCI_EVENT_PKT; + //skb->protocol = eth_type_trans(skb, skb->dev); + //skb->ip_summed = CHECKSUM_UNNECESSARY; + + // This is my receive skb pointer + gpBslctx->rx_skb = skb; + + // This is how data and events are passed up to BlueZ + hci_recv_frame(gpBslctx->rx_skb); + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_EventCB() + +static VOS_STATUS +WLANBAP_PhyLinkFailure +( + BslClientCtxType* pctx, + v_U8_t phy_link_handle +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; + + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = WLANBAP_ERROR_UNSPECIFIED_ERROR; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = 0; + //TBD: Could be a cleaner way to get the PhyLinkCtx handle; For now works + BslPhyLinkCtx[0].pClientCtx = pctx; + vosStatus = WLANBAP_EventCB( &BslPhyLinkCtx[0], &bapHCIEvent, TRUE ); + + return vosStatus; +} + +/** + @brief BslFindAndInitClientCtx() - This function will find and initialize a client + a.k.a app context + + @param pctx : [inout] ptr to the client context + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslFindAndInitClientCtx +( + BslClientCtxType** pctx_ +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx; + v_U8_t i; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslFindAndInitClientCtx" ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,"%s:BslClientLock already inited",__func__); + // return(0); + } + + for ( i=0; i < BSL_MAX_CLIENTS; i++ ) + { + if ( !BslClientCtx[i].used ) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,"%s:BslClientCtx[%d] selected",__func__, i); + BslClientCtx[i].used = TRUE; + break; + } + } + + if ( i == BSL_MAX_CLIENTS ) + { + // no more clients can be supported + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslFindAndInitClientCtx no more " + "clients can be supported MAX=%d", BSL_MAX_CLIENTS ); + return FALSE; + } + + //pctx = BslClientCtx + i; + pctx = gpBslctx; + + // get a handle from BAP + VosStatus = WLANBAP_GetNewHndl(&pctx->bapHdl); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + pctx->used = FALSE; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:WLAN_GetNewHndl Failed",__func__); + + return(FALSE); + } + + // register the event cb with BAP, this cb is used for BOTH association + // specific and non-association specific event notifications by BAP. + // However association specific events will be called with a different + // cookie that is passed in during the physical link create/accept + VosStatus = WLAN_BAPRegisterBAPCallbacks( pctx->bapHdl, WLANBAP_EventCB, pctx ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + pctx->used = FALSE; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:WLAN_BAPRegsiterBAPCallaback Failed",__func__); + + return(FALSE); + } + + // init the PhyLinks queue to keep track of the assoc's of this client + VosStatus = vos_list_init( &pctx->PhyLinks ); + if (VOS_STATUS_SUCCESS != VosStatus) + { + pctx->used = FALSE; + VOS_ASSERT(0); + return(FALSE); + } + + *pctx_ = pctx; + + return(TRUE); +} //BslFindAndInitClientCtx() + +/** + @brief BslReleaseClientCtx() - This function will release a client a.k.a. app + context + + @param pctx : [in] ptr to the client context + + @return + None + +*/ +//#if 0 +static void BslReleaseClientCtx +( + BslClientCtxType* pctx +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + vos_list_node_t* pLink; + BslPhyLinksNodeType *pPhyNode; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslReleaseClientCtx" ); + + // an app can do this without cleaning up after itself i.e. it can have active associations and + // data pending, we need to cleanup its mess + + // first tell BAP we dont want the handle anymore, BAP will cleanup all the associations and + // consume resulting HCI events, so after this we will not get any HCI events. we will also + // not see any FetchPktCB and RxPktCB. We can still expect TxCompletePktCB + VosStatus = WLANBAP_ReleaseHndl( pctx->bapHdl ); + if (VOS_STATUS_SUCCESS != VosStatus) + { + // just print no action required + VOS_ASSERT(0); + } + + // find and free all of the association contexts belonging to this app + while ( VOS_IS_STATUS_SUCCESS( VosStatus = vos_list_remove_front( &pctx->PhyLinks, &pLink ) ) ) + { + pPhyNode = (BslPhyLinksNodeType *)pLink; + + // since the phy link has already been removed from the list of active + // associations, make sure we dont attempt to do this again + pPhyNode->pPhy->pPhyLinkDescNode = NULL; + + BslReleasePhyCtx( pPhyNode->pPhy ); + } + + VOS_ASSERT( VosStatus == VOS_STATUS_E_EMPTY ); + + // destroy the PhyLinks queue + VosStatus = vos_list_destroy( &pctx->PhyLinks ); + if (VOS_STATUS_SUCCESS != VosStatus) + { + // just print no action required + VOS_ASSERT(0); + } + + pctx->used = FALSE; + +} // BslReleaseClientCtx() +//#endif + +/** + @brief BslInitPhyCtx() - Initialize the Phy Context array. + + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslInitPhyCtx (void) +{ + v_U16_t i; + // free PHY context + + for ( i=0; iused = TRUE; + + // store the PHY link handle + BslPhyLinkCtx[i].PhyLinkHdl = PhyLinkHdl; + + // init the TX queues + for ( j=0; jnode = *pLink; + pNode->pPhy = *ppPhyCtx; + + + // now queue the pkt into the correct queue + VosStatus = vos_list_insert_back( &pctx->PhyLinks, pLink ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // need to record the desc for this assocation in the list of + // active assocations in client context to allow cleanup later + (*ppPhyCtx)->pPhyLinkDescNode = pNode; + + return(TRUE); + } +} // BslFindAndInitPhyCtx() + +/** + @brief BslProcessHCICommand() - This function will process an HCI command i.e + take an HCI command buffer, unpack it and then call the appropriate BAP API + + @param pctx : [in] ptr to the client context + @param pBuffer_ : [in] the input buffer containing the HCI command + @param Count_ : [in] size of the HCI command buffer + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslProcessHCICommand +( + BslClientCtxType* pctx, + LPCVOID pBuffer_, + DWORD Count_ +) +{ + LPVOID pBuffer = (LPVOID) pBuffer_; // castaway the const-ness of the ptr + v_U16_t Count = (v_U16_t) Count_; // this should be OK max size < 1500 + v_U32_t UnpackStatus; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BOOL Status; + BslPhyLinkCtxType* pPhyCtx; + tBtampHCI_Event HCIEvt; + v_U16_t x = 1; + int i = 0; + + // the opcode is in LE, if we are LE too then this is fine else we need some + // byte swapping + v_U16_t cmdOpcode = *(UNALIGNED v_U16_t *)pBuffer; + v_U8_t *pBuf = (v_U8_t *)pBuffer; + v_U8_t *pTmp = (v_U8_t *)pBuf; + + // TODO: do we really need to do this per call even though the op is quite cheap + if(*(v_U8_t *)&x == 0) + { + // BE + cmdOpcode = ( cmdOpcode & 0xFF ) << 8 | ( cmdOpcode & 0xFF00 ) >> 8; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslProcessHCICommand: cmdOpcode = %hx", cmdOpcode ); + + for(i=0; i<4; i++) + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: *pBuf before advancepTmp[%x] = %x", i,pTmp[i] ); + + pBuf+=CMD_TLV_TYPE_AND_LEN_SIZE; + + + switch ( cmdOpcode ) + { + /** BT v3.0 Link Control commands */ + case BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Create_Physical_Link_Cmd CreatePhysicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Create_Physical_Link_Cmd( NULL, + pBuf, Count, &CreatePhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + if(VOS_FALSE == WLANBAP_AmpConnectionAllowed()) + { + VosStatus = WLANBAP_PhyLinkFailure(pctx, CreatePhysicalLinkCmd.phy_link_handle); + if ( VOS_STATUS_SUCCESS != VosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_PhyLinkFailure failed"); + // handle the error + return(FALSE); + } + break; + } + + // setup the per PHY link BAP context + Status = BslFindAndInitPhyCtx( pctx, CreatePhysicalLinkCmd.phy_link_handle, + &pPhyCtx ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "CreatePhysicalLinkCmd.phy_link_handle=%d",CreatePhysicalLinkCmd.phy_link_handle); + + if ( !Status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: BslFindAndInitPhyCtx failed"); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkCreate( pctx->bapHdl, + &CreatePhysicalLinkCmd, pPhyCtx, &HCIEvt ); + + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkCreate failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pPhyCtx, &HCIEvt, TRUE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Accept_Physical_Link_Cmd AcceptPhysicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Accept_Physical_Link_Cmd( NULL, + pBuf, Count, &AcceptPhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Accept_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + if(VOS_FALSE == WLANBAP_AmpConnectionAllowed()) + { + VosStatus = WLANBAP_PhyLinkFailure(pctx, AcceptPhysicalLinkCmd.phy_link_handle); + if ( VOS_STATUS_SUCCESS != VosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_PhyLinkFailure failed"); + // handle the error + return(FALSE); + } + break; + } + + // setup the per PHY link BAP context + Status = BslFindAndInitPhyCtx( pctx, AcceptPhysicalLinkCmd.phy_link_handle, + &pPhyCtx ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "AcceptPhysicalLinkCmd.phy_link_handle=%d",AcceptPhysicalLinkCmd.phy_link_handle); + + if ( !Status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: BslFindAndInitPhyCtx failed"); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkAccept( pctx->bapHdl, + &AcceptPhysicalLinkCmd, pPhyCtx, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkAccept failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pPhyCtx, &HCIEvt, TRUE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Disconnect_Physical_Link_Cmd DisconnectPhysicalLinkCmd; + Count = Count - 3;//Type and length field lengths are not needed + pTmp = pBuf; + for(i=0; i<4; i++) + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: *pBuf in Disconnect phy link pTmp[%x] = %x", i,pTmp[i] ); + // unpack + UnpackStatus = btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd( NULL, + pBuf, Count, &DisconnectPhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkDisconnect( pctx->bapHdl, + &DisconnectPhysicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkDisconnect failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Create_Logical_Link_Cmd CreateLogicalLinkCmd; + Count -= 3; //To send the correct length to unpack event + // unpack + UnpackStatus = btampUnpackTlvHCI_Create_Logical_Link_Cmd( NULL, + pBuf, Count, &CreateLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Create_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkCreate( pctx->bapHdl, + &CreateLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkCreate failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Accept_Logical_Link_Cmd AcceptLogicalLinkCmd; + Count = Count - 3;//Subtract Type and Length fields + // unpack + UnpackStatus = btampUnpackTlvHCI_Accept_Logical_Link_Cmd( NULL, + pBuf, Count, &AcceptLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Accept_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkAccept( pctx->bapHdl, + &AcceptLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkAccept failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Disconnect_Logical_Link_Cmd DisconnectLogicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd( NULL, + pBuf, Count, &DisconnectLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkDisconnect( pctx->bapHdl, + &DisconnectLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkDisconnect failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD: + { + tBtampTLVHCI_Logical_Link_Cancel_Cmd LogicalLinkCancelCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Logical_Link_Cancel_Cmd( NULL, + pBuf, Count, &LogicalLinkCancelCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Logical_Link_Cancel_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkCancel( pctx->bapHdl, + &LogicalLinkCancelCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkCancel failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD: + { + tBtampTLVHCI_Flow_Spec_Modify_Cmd FlowSpecModifyCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Flow_Spec_Modify_Cmd( NULL, + pBuf, Count, &FlowSpecModifyCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Flow_Spec_Modify_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPFlowSpecModify( pctx->bapHdl, + &FlowSpecModifyCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPFlowSpecModify failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Host Controller and Baseband Commands + */ + case BTAMP_TLV_HCI_RESET_CMD: + { + VosStatus = WLAN_BAPReset( pctx->bapHdl ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReset failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_SET_EVENT_MASK_CMD: + { + tBtampTLVHCI_Set_Event_Mask_Cmd SetEventMaskCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Event_Mask_Cmd( NULL, + pBuf, Count, &SetEventMaskCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Event_Mask_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetEventMask( pctx->bapHdl, + &SetEventMaskCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetEventMask failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_FLUSH_CMD: + { + tBtampTLVHCI_Flush_Cmd FlushCmd; + + // unpack + UnpackStatus = btampUnpackTlvHCI_Flush_Cmd( NULL, + pBuf, Count, &FlushCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Flush_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + /* Flush the TX queue */ +//#ifdef BAP_DEBUG + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s:HCI Flush command - will flush Tx Queue", __func__); +//#endif //BAP_DEBUG + // JEZ100604: Temporary short cut + pPhyCtx = &BslPhyLinkCtx[0]; + VosStatus = BslFlushTxQueues ( pPhyCtx); + + /* Acknowledge the command */ + VosStatus = WLAN_BAPFlush( pctx->bapHdl, &FlushCmd ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLAN_BAPFlush failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD: + { + tBtampTLVHCI_Enhanced_Flush_Cmd FlushCmd; + + // unpack + UnpackStatus = btampUnpackTlvHCI_Enhanced_Flush_Cmd( NULL, + pBuf, Count, &FlushCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: btampUnpackTlvHCI_Enhanced_Flush_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + /* Flush the TX queue */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:HCI Flush command - will flush Tx Queue for pkt type %d", __func__, FlushCmd.packet_type); + // We support BE traffic only + if(WLANTL_AC_BE == FlushCmd.packet_type) + { + pPhyCtx = &BslPhyLinkCtx[0]; + VosStatus = BslFlushTxQueues ( pPhyCtx); + } + + /* Acknowledge the command */ + VosStatus = WLAN_EnhancedBAPFlush( pctx->bapHdl, &FlushCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLAN_EnahncedBAPFlush failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD: + { + VosStatus = WLAN_BAPReadConnectionAcceptTimeout( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadConnectionAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd WriteConnectionAcceptTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd( NULL, + pBuf, Count, &WriteConnectionAcceptTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteConnectionAcceptTimeout( pctx->bapHdl, + &WriteConnectionAcceptTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteConnectionAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD: + { + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd ReadLinkSupervisionTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd( NULL, + pBuf, Count, &ReadLinkSupervisionTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLinkSupervisionTimeout( pctx->bapHdl, + &ReadLinkSupervisionTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLinkSupervisionTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd WriteLinkSupervisionTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd( NULL, + pBuf, Count, &WriteLinkSupervisionTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLinkSupervisionTimeout( pctx->bapHdl, + &WriteLinkSupervisionTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLinkSupervisionTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* v3.0 Host Controller and Baseband Commands */ + case BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + { + VosStatus = WLAN_BAPReadLogicalLinkAcceptTimeout( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLogicalLinkAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd WriteLogicalLinkAcceptTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd( NULL, + pBuf, Count, &WriteLogicalLinkAcceptTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLogicalLinkAcceptTimeout( pctx->bapHdl, + &WriteLogicalLinkAcceptTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLogicalLinkAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD: + { + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd SetEventMaskPage2Cmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd( NULL, + pBuf, Count, &SetEventMaskPage2Cmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetEventMaskPage2( pctx->bapHdl, + &SetEventMaskPage2Cmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetEventMaskPage2 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD: + { + VosStatus = WLAN_BAPReadLocationData( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocationData failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD: + { + tBtampTLVHCI_Write_Location_Data_Cmd WriteLocationDataCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Location_Data_Cmd( NULL, + pBuf, Count, &WriteLocationDataCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Location_Data_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLocationData( pctx->bapHdl, + &WriteLocationDataCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLocationData failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD: + { + VosStatus = WLAN_BAPReadFlowControlMode( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadFlowControlMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD: + { + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd WriteFlowControlModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd( NULL, + pBuf, Count, &WriteFlowControlModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteFlowControlMode( pctx->bapHdl, + &WriteFlowControlModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteFlowControlMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD: + { + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd ReadBestEffortFlushTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd( NULL, + pBuf, Count, &ReadBestEffortFlushTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadBestEffortFlushTimeout( pctx->bapHdl, + &ReadBestEffortFlushTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadBestEffortFlushTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd WriteBestEffortFlushTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd( NULL, + pBuf, Count, &WriteBestEffortFlushTimeoutCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteBestEffortFlushTimeout( pctx->bapHdl, + &WriteBestEffortFlushTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteBestEffortFlushTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /** opcode definition for this command from AMP HCI CR D9r4 markup */ + case BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD: + { + tBtampTLVHCI_Set_Short_Range_Mode_Cmd SetShortRangeModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd( NULL, + pBuf, Count, &SetShortRangeModeCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetShortRangeMode( pctx->bapHdl, + &SetShortRangeModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetShortRangeMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* End of v3.0 Host Controller and Baseband Commands */ + /* + Informational Parameters + */ + case BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD: + { + VosStatus = WLAN_BAPReadLocalVersionInfo( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalVersionInfo failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD: + { + VosStatus = WLAN_BAPReadLocalSupportedCmds( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalSupportedCmds failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD: + { + VosStatus = WLAN_BAPReadBufferSize( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadBufferSize failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* v3.0 Informational commands */ + case BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD: + { + VosStatus = WLAN_BAPReadDataBlockSize( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadDataBlockSize failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Status Parameters + */ + case BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD: + { + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd ReadFailedContactCounterCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd( NULL, + pBuf, Count, &ReadFailedContactCounterCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadFailedContactCounter( pctx->bapHdl, + &ReadFailedContactCounterCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadFailedContactCounter failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD: + { + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd ResetFailedContactCounterCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd( NULL, + pBuf, Count, &ResetFailedContactCounterCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPResetFailedContactCounter( pctx->bapHdl, + &ResetFailedContactCounterCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPResetFailedContactCounter failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD: + { + tBtampTLVHCI_Read_Link_Quality_Cmd ReadLinkQualityCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Link_Quality_Cmd( NULL, + pBuf, Count, &ReadLinkQualityCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Link_Quality_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLinkQuality( pctx->bapHdl, + &ReadLinkQualityCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLinkQuality failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_RSSI_CMD: + { + tBtampTLVHCI_Read_RSSI_Cmd ReadRssiCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_RSSI_Cmd( NULL, + pBuf, Count, &ReadRssiCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_RSSI_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadRSSI( pctx->bapHdl, + &ReadRssiCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadRSSI failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD: + { + tBtampTLVHCI_Read_Local_AMP_Information_Cmd ReadLocalAmpInformationCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd( NULL, + pBuf, Count, &ReadLocalAmpInformationCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLocalAMPInfo( pctx->bapHdl, + &ReadLocalAmpInformationCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalAMPInfo failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD: + { + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd ReadLocalAmpAssocCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd( NULL, + pBuf, Count, &ReadLocalAmpAssocCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLocalAMPAssoc( pctx->bapHdl, + &ReadLocalAmpAssocCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalAMPAssoc failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD: + { + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd WriteRemoteAmpAssocCmd; + // unpack + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: HCI_Write_Remote_AMP_ASSOC_Cmd Count = %d", Count); + DUMPLOG(1, __func__, "HCI_Write_Remote_AMP_ASSOC cmd", + pBuf, + Count); + + UnpackStatus = btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd( NULL, + pBuf, Count, &WriteRemoteAmpAssocCmd ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WriteRemoteAmpAssocCmd.amp_assoc_remaining_length = %d", + WriteRemoteAmpAssocCmd.amp_assoc_remaining_length + ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + +//#define BAP_UNIT_TEST +#ifdef BAP_UNIT_TEST + { + unsigned char test_amp_assoc_fragment[] = + { + 0x01, 0x00, 0x06, 0x00, 0x00, 0xde, 0xad, 0xbe, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x0c, 0x00, 0x55, 0x53, 0x20, 0xc9, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x55, 0x53, + 0x20, 0xc9, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }; + WriteRemoteAmpAssocCmd.present = 1; + WriteRemoteAmpAssocCmd.phy_link_handle = 1; + WriteRemoteAmpAssocCmd.length_so_far = 0; + WriteRemoteAmpAssocCmd.amp_assoc_remaining_length = 74; + /* Set the amp_assoc_fragment to the right values of MAC addr and + * channels + */ + vos_mem_copy( + WriteRemoteAmpAssocCmd.amp_assoc_fragment, + test_amp_assoc_fragment, + sizeof( test_amp_assoc_fragment)); + + } +#endif + + VosStatus = WLAN_BAPWriteRemoteAMPAssoc( pctx->bapHdl, + &WriteRemoteAmpAssocCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteRemoteAMPAssoc failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Debug Commands + */ + case BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD: + { + tBtampTLVHCI_Read_Loopback_Mode_Cmd ReadLoopbackModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Loopback_Mode_Cmd( NULL, + pBuf, Count, &ReadLoopbackModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Loopback_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLoopbackMode( pctx->bapHdl, + &ReadLoopbackModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLoopbackMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD: + { + tBtampTLVHCI_Write_Loopback_Mode_Cmd WriteLoopbackModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Loopback_Mode_Cmd( NULL, + pBuf, Count, &WriteLoopbackModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Loopback_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLoopbackMode( pctx->bapHdl, + &WriteLoopbackModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLoopbackMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0: + { + VosStatus = WLAN_BAPVendorSpecificCmd0( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPVendorSpecificCmd0 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1: + { + VosStatus = WLAN_BAPVendorSpecificCmd1( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPVendorSpecificCmd1 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + default: + { + /* Unknow opcode. Return a command status event...with "Unknown Opcode" status */ + + /* Format the command status event to return... */ + HCIEvt.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + HCIEvt.u.btampCommandStatusEvent.present = 1; + HCIEvt.u.btampCommandStatusEvent.status = WLANBAP_ERROR_UNKNOWN_HCI_CMND; + HCIEvt.u.btampCommandStatusEvent.num_hci_command_packets = 1; + HCIEvt.u.btampCommandStatusEvent.command_opcode + = cmdOpcode; + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + + break; + } + } + + return(TRUE); +} // BslProcessHCICommand() + + +/** + @brief BslProcessACLDataTx() - This function will process an egress ACL data packet + + @param pctx : [in] ptr to the client context + @param pBuffer_ : [in] ptr to the buffer containing the ACL data packet + @param pCount : [in] size of the ACL data packet buffer + + @return + TRUE if all OK, FALSE otherwise + +*/ +#define BTAMP_USE_VOS_WRAPPER +//#undef BTAMP_USE_VOS_WRAPPER +#ifdef BTAMP_USE_VOS_WRAPPER +static BOOL BslProcessACLDataTx +( + BslClientCtxType* pctx, + struct sk_buff *skb, + v_SIZE_t* pCount +) +#else +static BOOL BslProcessACLDataTx +( + BslClientCtxType* pctx, + LPCVOID pBuffer_, + v_SIZE_t* pCount +) +#endif +{ +#ifndef BTAMP_USE_VOS_WRAPPER + LPVOID pBuffer = (LPVOID) pBuffer_; // castaway const-ness of ptr +#endif + BOOL findPhyStatus; + BslPhyLinkCtxType* pPhyCtx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + WLANTL_ACEnumType Ac; + hdd_list_node_t* pLink; + BslTxListNodeType *pNode; + v_SIZE_t ListSize; + // I will access the skb in a VOSS packet +#ifndef BTAMP_USE_VOS_WRAPPER + struct sk_buff *skb; +#endif +#if 0 + static int num_packets; +#endif + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslProcessACLDataTx" ); + + // need to find the PHY link for this ACL data pkt based on phy_link_handle + // TODO need some endian-ness check? + ////findPhyStatus = BslFindPhyCtx( pctx, *(v_U8_t *)skb->data, &pPhyCtx ); + //findPhyStatus = BslFindPhyCtx( pctx, *(v_U8_t *)pBuffer, &pPhyCtx ); + // JEZ100604: Temporary short cut + pPhyCtx = &BslPhyLinkCtx[0]; + findPhyStatus = VOS_TRUE; + + if ( findPhyStatus ) + { + //Use the skb->cb field to hold the list node information + pNode = (BslTxListNodeType *) &skb->cb; + + // This list node info includes the VOS pkt + pNode->skb = skb; + + // stick the SKB into the node + pLink = (hdd_list_node_t *) pNode; + VosStatus = WLANBAP_GetAcFromTxDataPkt(pctx->bapHdl, skb->data, &Ac); + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx WLANBAP_GetAcFromTxDataPkt " + "failed status =%d", VosStatus ); + + Ac = WLANTL_AC_BE; + } + + // now queue the pkt into the correct queue + // We will want to insert a node of type BslTxListNodeType (was going to be vos_pkt_list_node_t) + spin_lock_bh(&pPhyCtx->ACLTxQueue[Ac].lock); + VosStatus = hdd_list_insert_back( &pPhyCtx->ACLTxQueue[Ac], pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[Ac].lock); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // determine if there is a need to signal TL through BAP + hdd_list_size( &pPhyCtx->ACLTxQueue[Ac], &ListSize ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + if ( ListSize == 1 ) + { + // Let TL know we have a packet to send for this AC + VosStatus = WLANBAP_STAPktPending( pctx->bapHdl, pPhyCtx->PhyLinkHdl, Ac ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx WLANBAP_STAPktPending " + "failed status =%d", VosStatus ); + VOS_ASSERT(0); + } + } + + return(TRUE); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx attempting to send " + "data for a non-existant assocation" ); + + return(FALSE); + } + + +} // BslProcessACLDataTx() + + +static inline void *hci_get_drvdata(struct hci_dev *hdev) +{ + return hdev->driver_data; +} + +static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) +{ + hdev->driver_data = data; +} + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief BSL_Init() - Initialize the BSL Misc char driver + + This is called in vos_open(), right after WLANBAP_Open(), as part of + bringing up the BT-AMP PAL (BAP) + vos_open() will pass in the VOS context. In which a BSL context can be created. + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +//int BSL_Init (void *pCtx) +int BSL_Init ( v_PVOID_t pvosGCtx ) +{ + BslClientCtxType* pctx = NULL; + ptBtampHandle bapHdl = NULL; // our handle in BAP + //ptBtampContext pBtampCtx = NULL; + int err = 0; + struct hci_dev *hdev = NULL; + //struct net_device *dev = NULL; // Our parent wlan network device + hdd_adapter_t *pAdapter = NULL; // Used to retrieve the parent WLAN device + hdd_context_t *pHddCtx = NULL; + hdd_config_t *pConfig = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL; + VOS_STATUS status; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Init"); + + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) BSL control block + ------------------------------------------------------------------------*/ + //vos_alloc_context(pvosGCtx, VOS_MODULE_ID_BSL, (v_VOID_t**)&pctx, sizeof(BslClientCtxType)); + pctx = &BslClientCtx[0]; + + bapHdl = vos_get_context( VOS_MODULE_ID_BAP, pvosGCtx); + if ( NULL == bapHdl ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + // Save away the btamp (actually the vos) context + gpCtx = pvosGCtx; + + /* Save away the pointer to the BT-AMP PAL context in the BSL driver context */ + pctx->bapHdl = bapHdl; + + /* Save away the pointer to the BSL driver context in a global (fix this) */ + gpBslctx = pctx; + + /* Initialize all the Phy Contexts to un-used */ + BslInitPhyCtx(); + + /* Initialize the Rx fields in the HCI driver context */ + //pctx->rx_state = RECV_WAIT_PACKET_TYPE; + pctx->rx_count = 0; + pctx->rx_skb = NULL; + + /* JEZ100713: Temporarily the Tx skb queue will have depth one.*/ + // Don't disturb tx_skb + //pctx->tx_skb = NULL; + //pctx->tx_skb = alloc_skb(WLANBAP_MAX_80211_PAL_PDU_SIZE+12, GFP_ATOMIC); + + pctx->hdev = NULL; + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, pvosGCtx ); + if(NULL != pHddCtx) + { + pConfig = pHddCtx->cfg_ini; + } + if(NULL == pConfig) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Didn't register as HCI device"); + return 0; + } + else if(0 == pConfig->enableBtAmp) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Didn't register as HCI device, user option(gEnableBtAmp) is set to 0"); + return 0; + } + + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + { + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + if ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + if ( WLAN_HDD_SOFTAP == pAdapterNode->pAdapter->device_mode) + { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + } + else if (WLAN_HDD_P2P_GO == pAdapterNode->pAdapter->device_mode) + { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO); + } + } + } + else + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HDD Adapter pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the pointer to the parent WLAN device in BSL driver context */ + pctx->p_dev = pAdapter->dev; + + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Can't allocate HCI device in BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the HCI device pointer in the BSL driver context */ + pctx->hdev = hdev; + +#if defined HCI_80211 || defined HCI_AMP +#define BUILD_FOR_BLUETOOTH_NEXT_2_6 +#else +#undef BUILD_FOR_BLUETOOTH_NEXT_2_6 +#endif + +#ifdef BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->bus = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ +#ifdef HCI_80211 + hdev->dev_type = HCI_80211; +#else + hdev->dev_type = HCI_AMP; +#endif +#ifdef FEATURE_WLAN_BTAMP_UT + /* For the "real" BlueZ build, DON'T Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif +#else //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->type = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ + //hdev->dev_type = HCI_80211; + ////hdev->dev_type = HCI_AMP; + /* For the "temporary" BlueZ build, Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* Save away the BSL driver pointer in the HCI device context */ + + hci_set_drvdata(hdev, pctx); + /* Set the parent device for this HCI device. This is our WLAN net_device */ + SET_HCIDEV_DEV(hdev, &pctx->p_dev->dev); + + hdev->open = BSL_Open; + hdev->close = BSL_Close; + hdev->flush = BSL_Flush; + hdev->send = BSL_Write; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + hdev->destruct = BSL_Destruct; + hdev->owner = THIS_MODULE; +#endif + hdev->ioctl = BSL_IOControl; + + + /* Timeout before it is safe to send the first HCI packet */ + msleep(1000); + + /* Register HCI device */ + err = hci_register_dev(hdev); + if (err < 0) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to register HCI device, err=%d", err); + pctx->hdev = NULL; + hci_free_dev(hdev); + return -ENODEV; + } + + pHddCtx->isAmpAllowed = VOS_TRUE; + return 0; +} // BSL_Init() + +/**--------------------------------------------------------------------------- + + \brief BSL_Deinit() - De-initialize the BSL Misc char driver + + This is called in by WLANBAP_Close() as part of bringing down the BT-AMP PAL (BAP) + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int BSL_Deinit( v_PVOID_t pvosGCtx ) +{ + //int err = 0; + struct hci_dev *hdev; + BslClientCtxType* pctx = NULL; + + //pctx = vos_get_context( VOS_MODULE_ID_BSL, pvosGCtx); + pctx = gpBslctx; + + if ( NULL == pctx ) + { + //VOS_TRACE( VOS_MODULE_ID_BSL, VOS_TRACE_LEVEL_ERROR, + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Retrieve the HCI device pointer from the BSL driver context */ + hdev = pctx->hdev; + + if (!hdev) + return 0; + + /* hci_unregister_dev is called again here, in case user didn't call it */ + /* Unregister device from BlueZ; fcn sends us HCI commands before it returns */ + /* And then the registered hdev->close fcn should be called by BlueZ (BSL_Close) */ + hci_unregister_dev(hdev); + /* BSL_Close is called again here, in case BlueZ didn't call it */ + BSL_Close(hdev); + hci_free_dev(hdev); + pctx->hdev = NULL; + + return 0; +} // BSL_Deinit() + + +/** + @brief BSL_Open() - This function opens a device for reading, and writing. + An application indirectly invokes this function when it calls the fopen() + system call to open a special device file names. + + @param *hdev : [in] pointer to the open HCI device structure. + BSL_Init (Device Manager) function creates and stores this HCI + device context in the BSL context. + + @return + This function returns a status code. Negative codes are failures. + + NB: I don't seem to be following this convention. +*/ +//static int BSL_Open(struct inode *pInode, struct file *pFile) +static int BSL_Open( struct hci_dev *hdev ) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx = (BslClientCtxType *)(hci_get_drvdata(hdev)); + v_U16_t i; + BOOL rval; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Open"); + + /* you can only open a btamp device one time */ + if (bBslInited) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BSL_Open: Already Opened."); + return -EPERM; /* Operation not permitted */ + } + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSLClientLock already inited"); + // return -EIO; /* I/O error */ + return 0; + } + + VosStatus = vos_list_init( &BslPhyLinksDescPool ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + //return -EIO; /* I/O error */ + return 0; + } + + // now we need to populate this pool with the free pkt desc from the array + for ( i=0; iprivate_data != NULL) + bBslInited = TRUE; + + rval = BslFindAndInitClientCtx( &pctx ); + + if(rval != TRUE) + { + // Where is the clean-up in case the above BslFindAndInitClientCtx() call + // fails? + //return -EIO; /* I/O error */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSLFindAndInitClientContext failed"); + return 0; + } + + + /* Let Linux fopen() know everything is all right */ + return 0; +} // BSL_Open() + +/** + @brief BSL_Close() - This function closes a device context created by + BSL_Open(). May be called more than once during AMP PAL shut down. + + @param *hdev : [in] pointer to the open HCI device structure. + BSL_Init (Device Manager) function creates and stores this HCI + device context in the BSL context. + + @return + TRUE indicates success. FALSE indicates failure. +*/ +//static int BSL_Close (struct inode *pInode, struct file *pFile) +static int BSL_Close ( struct hci_dev *hdev ) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx; + vos_list_node_t* pLink; + v_U16_t i; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Close"); + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + pHddCtx->isAmpAllowed = VOS_FALSE; + } + } + + // it may seem there is some risk here because we are using a value + // passed into us as a pointer. what if this pointer is 0 or points to + // someplace bad? as it turns out the caller is device manager and not + // the application. kernel should trap such invalid access but we will check + // for NULL pointer + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Close: NULL hdev specified"); + return FALSE; + } + + pctx = (BslClientCtxType *)(hci_get_drvdata(hdev)); + + if ( pctx == NULL || !bBslInited) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BSL_Close: %s is not open", hdev->name); + return TRUE; + } + + // need to cleanup any per PHY state and the common RX state + BslReleaseClientCtx( pctx ); + for ( i=0; ilen)=%d", __func__, skb->len); + + // Sanity check inputs + if ( 0 == skb->len ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: skb is empty", __func__); + //return -EFAULT; /* Bad address */ + return 0; + } + + hdev = (struct hci_dev *)(skb->dev); + + // Sanity check the HCI device in the skb + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Frame for Unknown HCI device (hdev=NULL)", __func__); + //return -ENODEV; /* no device */ + return 0; + } + + pctx = (BslClientCtxType *)hci_get_drvdata(hdev); + + // Sanity check inputs + if ( pctx == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx is bad i/p", __func__); + //return -EFAULT; /* Bad address */ + return 0; + /* Maybe I should return "no device" */ + //return -ENODEV; /* no device */ + } + + // Switch for each case of packet type + switch (bt_cb(skb)->pkt_type) + { + case HCI_ACLDATA_PKT: + // Directly execute the data write + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: HCI ACL data tx, skb=%p", + __func__, skb); + // ACL data + hdev->stat.acl_tx++; + // Correct way of doing this... + written = skb->len; +#ifdef BTAMP_USE_VOS_WRAPPER + status = BslProcessACLDataTx( pctx, skb, &written ); +#else + status = BslProcessACLDataTx( pctx, skb->data, &written ); + // Free up the skb + kfree_skb(skb); +#endif //BTAMP_USE_VOS_WRAPPER + break; + case HCI_COMMAND_PKT: + // Defer the HCI command writes + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HCI command", __func__); + hdev->stat.cmd_tx++; + + // Allocate an HCI context. To use as a "container" for the "work" to be deferred. + pHciContext = kmalloc(sizeof(*pHciContext), GFP_ATOMIC); + if (NULL == pHciContext) + { + // no memory for HCI context. Nothing we can do but drop + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate context", __func__); + kfree_skb(skb); + return 0; + } + + // save away the tx skb in the HCI context...so it can be + // retrieved by the work procedure. + pHciContext->tx_skb = skb; + // save away the pctx context...so it can be retrieved by the work procedure. + pHciContext->pctx = pctx; + pHciContext->magic = BT_AMP_HCI_CTX_MAGIC; +#ifdef CONFIG_CNSS + cnss_init_work(&pHciContext->hciInterfaceProcessing, + bslWriteFinish); +#else + INIT_WORK(&pHciContext->hciInterfaceProcessing, + bslWriteFinish); +#endif + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Scheduling work for skb %p, BT-AMP Client context %p, work %p", + __func__, skb, pctx, pHciContext); + + status = schedule_work(&pHciContext->hciInterfaceProcessing); + + // Check result + if ( 0 == status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: hciInterfaceProcessing work already queued. This should never happen.", __func__); + } + + + // Temporary way of doing this + //written = skb->len-CMD_TLV_TYPE_AND_LEN_SIZE; + written = skb->len; + break; + case HCI_SCODATA_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: unknown type", __func__); + hdev->stat.sco_tx++; + // anything else including HCI events and SCO data + status = FALSE; + // Free up the skb + kfree_skb(skb); + break; + default: + // anything else including HCI events and SCO data + status = FALSE; + // Free up the skb + kfree_skb(skb); + break; + }; + + + // JEZ100809: For the HCI command, will the caller need to wait until the work takes place and + // return the ACTUAL amount of data written. + +// The next line is temporary + //written = skb->len; + return(written); +} // BSL_Write() + +/** + @brief bslWriteFinish() - This function finished the writes operation + started by BSL_Write(). + + @param work : [in] pointer to work structure + + @return : void + +*/ +static void bslWriteFinish(struct work_struct *work) +{ + //BslClientCtxType* pctx = + // container_of(work, BslClientCtxType, hciInterfaceProcessing); + BslHciWorkStructure *pHciContext = + container_of(work, BslHciWorkStructure, hciInterfaceProcessing); + BslClientCtxType* pctx = pHciContext->pctx; + VOS_STATUS status; + struct sk_buff *skb; + struct hci_dev *hdev; + //char *bslBuff = NULL; + v_SIZE_t written = 0; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pctx); + + // Sanity check inputs + if ( pctx == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx is bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + } + + //skb = pctx->tx_skb; + skb = pHciContext->tx_skb; + kfree( pHciContext); + + // Sanity check inputs + if ( skb == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: skb is bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Count (skb->len)=%d", __func__, skb->len); + + hdev = (struct hci_dev *)(skb->dev); + + // Sanity check the HCI device in the skb + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Frame for Unknown HCI device (hdev=NULL)", __func__); + return; // -ENODEV; /* no device */ + } + + + // Sanity check inputs + if ( pctx != (BslClientCtxType *)hci_get_drvdata(hdev)); + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx and hdev not consistent - bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + /* Maybe I should return "no device" */ + //return -ENODEV; /* no device */ + } + + // Switch for each case of packet type + switch (bt_cb(skb)->pkt_type) + { + case HCI_COMMAND_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HCI command", __func__); + hdev->stat.cmd_tx++; + // HCI command + status = BslProcessHCICommand( pctx, skb->data, skb->len-CMD_TLV_TYPE_AND_LEN_SIZE); + // Temporary way of doing this + //written = skb->len-CMD_TLV_TYPE_AND_LEN_SIZE; + written = skb->len; + break; + case HCI_SCODATA_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: unknown type", __func__); + hdev->stat.sco_tx++; + // anything else including HCI events and SCO data + status = FALSE; + break; + default: + // anything else including HCI events and SCO data + status = FALSE; + break; + }; + + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Freeing skb %p", + __func__, skb); + + consume_skb(skb); + +// How do I return the actual number of bytes written to the caller? +// return(written); + return; +} //bslWriteFinish() + +VOS_STATUS WLANBAP_SetConfig +( + WLANBAP_ConfigType *pConfig +) +{ + BslClientCtxType* pctx; + VOS_STATUS status; + // sanity checking + if ( pConfig == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig bad input" ); + return VOS_STATUS_E_FAILURE; + } + pctx = gpBslctx; + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pctx on WLANBAP_SetConfig"); + return VOS_STATUS_E_FAULT; + } + + // get a handle from BAP + status = WLANBAP_GetNewHndl(&pctx->bapHdl); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig can't get BAP handle" ); + return VOS_STATUS_E_FAILURE; + } + + + status = WLAN_BAPSetConfig(pctx->bapHdl, pConfig); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig can't set BAP config" ); + return VOS_STATUS_E_FAILURE; + } + + return(VOS_STATUS_SUCCESS); +} + +VOS_STATUS WLANBAP_RegisterWithHCI(hdd_adapter_t *pAdapter) +{ + struct hci_dev *hdev = NULL; + BslClientCtxType* pctx = NULL; + int err = 0; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + pctx = gpBslctx; + + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pctx on WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HDD Adapter pointer from pvosGCtx on WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + + if(NULL != pctx->hdev) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_WARN, + "Already registered as HCI device"); + return VOS_STATUS_SUCCESS; + } + + + + /* Save away the pointer to the parent WLAN device in BSL driver context */ + pctx->p_dev = pAdapter->dev; + + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Can't allocate HCI device in WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the HCI device pointer in the BSL driver context */ + pctx->hdev = hdev; + +#if defined HCI_80211 || defined HCI_AMP +#define BUILD_FOR_BLUETOOTH_NEXT_2_6 +#else +#undef BUILD_FOR_BLUETOOTH_NEXT_2_6 +#endif + +#ifdef BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->bus = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ +#ifdef HCI_80211 + hdev->dev_type = HCI_80211; +#else + hdev->dev_type = HCI_AMP; +#endif +#ifdef FEATURE_WLAN_BTAMP_UT + /* For the "real" BlueZ build, DON'T Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif +#else //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->type = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ + //hdev->dev_type = HCI_80211; + ////hdev->dev_type = HCI_AMP; + /* For the "temporary" BlueZ build, Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* Save away the BSL driver pointer in the HCI device context */ + hci_set_drvdata(hdev, pctx); + /* Set the parent device for this HCI device. This is our WLAN net_device */ + SET_HCIDEV_DEV(hdev, &pctx->p_dev->dev); + + hdev->open = BSL_Open; + hdev->close = BSL_Close; + hdev->flush = BSL_Flush; + hdev->send = BSL_Write; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + hdev->owner = THIS_MODULE; + hdev->destruct = BSL_Destruct; +#endif + hdev->ioctl = BSL_IOControl; + + + /* Timeout before it is safe to send the first HCI packet */ + msleep(1000); + + /* Register HCI device */ + err = hci_register_dev(hdev); + if (err < 0) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to register HCI device, err=%d", err); + pctx->hdev = NULL; + hci_free_dev(hdev); + return VOS_STATUS_E_FAULT; + } + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + } + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANBAP_DeregisterFromHCI(void) +{ + struct hci_dev *hdev; + BslClientCtxType* pctx = NULL; + + pctx = gpBslctx; + + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_DeregisterFromHCI"); + return VOS_STATUS_E_FAULT; + } + + /* Retrieve the HCI device pointer from the BSL driver context */ + hdev = pctx->hdev; + + if (!hdev) + return VOS_STATUS_E_FAULT; + + /* Unregister device from BlueZ; fcn sends us HCI commands before it returns */ + /* And then the registered hdev->close fcn should be called by BlueZ (BSL_Close) */ + hci_unregister_dev(hdev); + + /* BSL_Close is called again here, in case BlueZ didn't call it */ + BSL_Close(hdev); + hci_free_dev(hdev); + pctx->hdev = NULL; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANBAP_StopAmp(void) +{ + BslClientCtxType* pctx; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pctx = gpBslctx; + + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_StopAmp"); + status = VOS_STATUS_E_FAULT; + } + else + { + //is AMP session on, if so disconnect + if(VOS_TRUE == WLAN_BAPSessionOn(pctx->bapHdl)) + { + status = WLAN_BAPDisconnect(pctx->bapHdl); + } + } + return status; +} + +v_BOOL_t WLANBAP_AmpSessionOn(void) +{ + BslClientCtxType* pctx; + + pctx = gpBslctx; + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_AmpSessionOn"); + return VOS_FALSE; + } + else + { + return( WLAN_BAPSessionOn(pctx->bapHdl)); + } +} + + +#endif // WLAN_BTAMP_FEATURE diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c new file mode 100644 index 0000000000000..6eedd4cb42831 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c @@ -0,0 +1,4891 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_assoc.c + \brief WLAN Host Device Driver implementation + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 05/06/09 Shailender Created module. + ==========================================================================*/ + +#include "wlan_hdd_includes.h" +#include +#include "dot11f.h" +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" +#include "wlan_hdd_power.h" +#include +#include +#include +#include "wlan_hdd_cfg80211.h" +#include "csrInsideApi.h" +#include "wlan_hdd_p2p.h" +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#include "sme_Api.h" +#ifdef FEATURE_WLAN_FORCE_SAP_SCC +#include "wlan_hdd_hostapd.h" +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ +#ifdef IPA_OFFLOAD +#include +#endif +v_BOOL_t mibIsDot11DesiredBssTypeInfrastructure( hdd_adapter_t *pAdapter ); + +struct ether_addr +{ + u_char ether_addr_octet[6]; +}; +// These are needed to recognize WPA and RSN suite types +#define HDD_WPA_OUI_SIZE 4 +v_U8_t ccpWpaOui00[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x00 }; +v_U8_t ccpWpaOui01[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x01 }; +v_U8_t ccpWpaOui02[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; +v_U8_t ccpWpaOui03[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x03 }; +v_U8_t ccpWpaOui04[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x04 }; +v_U8_t ccpWpaOui05[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x05 }; +#ifdef FEATURE_WLAN_ESE +v_U8_t ccpWpaOui06[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM +#endif /* FEATURE_WLAN_ESE */ +#define HDD_RSN_OUI_SIZE 4 +v_U8_t ccpRSNOui00[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher +v_U8_t ccpRSNOui01[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN +v_U8_t ccpRSNOui02[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK +v_U8_t ccpRSNOui03[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved +v_U8_t ccpRSNOui04[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP +v_U8_t ccpRSNOui05[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104 +#ifdef FEATURE_WLAN_ESE +v_U8_t ccpRSNOui06[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W +v_U8_t ccpRSNOui07[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x06 }; // RSN-PSK-SHA256 +/* RSN-8021X-SHA256 */ +v_U8_t ccpRSNOui08[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; +#endif + +#if defined(WLAN_FEATURE_VOWIFI_11R) +// Offset where the EID-Len-IE, start. +#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2)*/ +#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */ +#endif + +#define BEACON_FRAME_IES_OFFSET 12 + +#ifdef WLAN_FEATURE_11W +void hdd_indicateUnprotMgmtFrame(hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +static void hdd_indicateTsmIe(hdd_adapter_t *pAdapter, tANI_U8 tid, + tANI_U8 state, + tANI_U16 measInterval ); +static void hdd_indicateCckmPreAuth(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); +static void hdd_indicateEseAdjApRepInd(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); +static void hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter, + const tCsrRoamInfo *pRoamInfo); + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ); + +v_VOID_t hdd_connSetAuthenticated( hdd_adapter_t *pAdapter, v_U8_t authState ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + /* save the new connection state */ + hddLog(LOG1, FL("Authenticated state Changed from oldState:%d to State:%d"), + pHddStaCtx->conn_info.uIsAuthenticated, authState); + pHddStaCtx->conn_info.uIsAuthenticated = authState; + + /* Check is pending ROC request or not when auth state changed */ + schedule_work(&pHddCtx->rocReqWork); +} + +v_VOID_t hdd_connSetConnectionState( hdd_adapter_t *pAdapter, + eConnectionState connState ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + /* save the new connection state */ + hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"), + pHddStaCtx->conn_info.connState,connState); + pHddStaCtx->conn_info.connState = connState; + + /* Check is pending ROC request or not when connection state changed */ + schedule_work(&pHddCtx->rocReqWork); +} + +// returns FALSE if not connected. +// returns TRUE for the two 'connected' states (Infra Associated or IBSS Connected ). +// returns the connection state. Can specify NULL if you dont' want to get the actual state. + +static inline v_BOOL_t hdd_connGetConnectionState( hdd_station_ctx_t *pHddStaCtx, + eConnectionState *pConnState ) +{ + v_BOOL_t fConnected; + eConnectionState connState; + + // get the connection state. + connState = pHddStaCtx->conn_info.connState; + // Set the fConnected return variable based on the Connected State. + if ( eConnectionState_Associated == connState || + eConnectionState_IbssConnected == connState || + eConnectionState_IbssDisconnected == connState) + { + fConnected = VOS_TRUE; + } + else + { + fConnected = VOS_FALSE; + } + + if ( pConnState ) + { + *pConnState = connState; + } + + return( fConnected ); +} + +v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx ) +{ + return( hdd_connGetConnectionState( pHddStaCtx, NULL ) ); +} + +eCsrBand hdd_connGetConnectedBand( hdd_station_ctx_t *pHddStaCtx ) +{ + v_U8_t staChannel = 0; + + if ( eConnectionState_Associated == pHddStaCtx->conn_info.connState ) + { + staChannel = pHddStaCtx->conn_info.operationChannel; + } + + if ( staChannel > 0 && staChannel < 14 ) + return eCSR_BAND_24; + else if (staChannel >= 36 && staChannel <= 165 ) + return eCSR_BAND_5G; + else /* If station is not connected return as eCSR_BAND_ALL */ + return eCSR_BAND_ALL; +} + +static inline v_BOOL_t hdd_connGetConnectedCipherAlgo( hdd_station_ctx_t *pHddStaCtx, eCsrEncryptionType *pConnectedCipherAlgo ) +{ + v_BOOL_t fConnected = VOS_FALSE; + + fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL ); + + if ( pConnectedCipherAlgo ) + { + *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType; + } + + return( fConnected ); +} + +inline v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eMib_dot11DesiredBssType *pConnectedBssType ) +{ + v_BOOL_t fConnected = VOS_FALSE; + + fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL ); + + if ( pConnectedBssType ) + { + *pConnectedBssType = pHddStaCtx->conn_info.connDot11DesiredBssType; + } + + return( fConnected ); +} + +static inline void hdd_connSaveConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eCsrRoamBssType csrRoamBssType ) +{ + switch( csrRoamBssType ) + { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_infrastructure; + break; + + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_independent; + break; + + /** We will never set the BssType to 'any' when attempting a connection + so CSR should never send this back to us.*/ + case eCSR_BSS_TYPE_ANY: + default: + VOS_ASSERT( 0 ); + break; + } + +} + +void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE; + + VOS_ASSERT( pRoamInfo ); + + if ( pRoamInfo ) + { + // Save the BSSID for the connection... + if ( eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType ) + { + VOS_ASSERT( pRoamInfo->pBssDesc ); + vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,6 ); + + // Save the Station ID for this station from the 'Roam Info'. + //For IBSS mode, staId is assigned in NEW_PEER_IND + //For reassoc, the staID doesn't change and it may be invalid in this structure + //so no change here. + if( !pRoamInfo->fReassocReq ) + { + pHddStaCtx->conn_info.staId [0]= pRoamInfo->staId; + } + } + else if ( eCSR_BSS_TYPE_IBSS == eBssType ) + { + vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,sizeof(pRoamInfo->bssid) ); + } + else + { + // can't happen. We need a valid IBSS or Infra setting in the BSSDescription + // or we can't function. + VOS_ASSERT( 0 ); + } + + // notify WMM + hdd_wmm_connect(pAdapter, pRoamInfo, eBssType); + + if( !pRoamInfo->u.pConnectedProfile ) + { + VOS_ASSERT( pRoamInfo->u.pConnectedProfile ); + } + else + { + // Get Multicast Encryption Type + encryptType = pRoamInfo->u.pConnectedProfile->mcEncryptionType; + pHddStaCtx->conn_info.mcEncryptionType = encryptType; + /* Get Unicast Encryption Type */ + encryptType = pRoamInfo->u.pConnectedProfile->EncryptionType; + pHddStaCtx->conn_info.ucEncryptionType = encryptType; + + pHddStaCtx->conn_info.authType = pRoamInfo->u.pConnectedProfile->AuthType; + + pHddStaCtx->conn_info.operationChannel = pRoamInfo->u.pConnectedProfile->operationChannel; + + // Save the ssid for the connection + vos_mem_copy( &pHddStaCtx->conn_info.SSID.SSID, &pRoamInfo->u.pConnectedProfile->SSID, sizeof( tSirMacSSid ) ); + + // Save dot11mode in which STA associated to AP + pHddStaCtx->conn_info.dot11Mode = pRoamInfo->u.pConnectedProfile->dot11Mode; + + pHddStaCtx->conn_info.proxyARPService = pRoamInfo->u.pConnectedProfile->proxyARPService; + } + } + + // save the connected BssType + hdd_connSaveConnectedBssType( pHddStaCtx, eBssType ); + +} + +#if defined(WLAN_FEATURE_VOWIFI_11R) +/* + * Send the 11R key information to the supplicant. + * Only then can the supplicant generate the PMK-R1. + * (BTW, the ESE supplicant also needs the Assoc Resp IEs + * for the same purpose.) + * + * Mainly the Assoc Rsp IEs are passed here. For the IMDA + * this contains the R1KHID, R0KHID and the MDID. + * For FT, this consists of the Reassoc Rsp FTIEs. + * This is the Assoc Response. + */ +static void hdd_SendFTAssocResponse(struct net_device *dev, hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + char *buff; + unsigned int len = 0; + u8 *pFTAssocRsp = NULL; + + if (pCsrRoamInfo->nAssocRspLength == 0) + { + hddLog(LOGE, + "%s: pCsrRoamInfo->nAssocRspLength=%d", + __func__, (int)pCsrRoamInfo->nAssocRspLength); + return; + } + + pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength + + pCsrRoamInfo->nAssocReqLength); + if (pFTAssocRsp == NULL) + { + hddLog(LOGE, "%s: AssocReq or AssocRsp is NULL", __func__); + return; + } + + // pFTAssocRsp needs to point to the IEs + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__, + (unsigned int)pFTAssocRsp[0], + (unsigned int)pFTAssocRsp[1]); + + // We need to send the IEs to the supplicant. + buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + + // Send the Assoc Resp, the supplicant needs this for initial Auth. + len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + wrqu.data.length = len; + memset(buff, 0, IW_GENERIC_IE_MAX); + memcpy(buff, pFTAssocRsp, len); + wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff); + + kfree(buff); +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*--------------------------------------------------- + * + * Send the FTIEs, RIC IEs during FT. This is eventually + * used to send the FT events to the supplicant + * + * At the reception of Auth2 we send the RIC followed + * by the auth response IEs to the supplicant. + * Once both are received in the supplicant, an FT + * event is generated to the supplicant. + * + *--------------------------------------------------- + */ +void hdd_SendFTEvent(hdd_adapter_t *pAdapter) +{ + tANI_U16 auth_resp_len = 0; + tANI_U32 ric_ies_length = 0; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + +#if defined(KERNEL_SUPPORT_11R_CFG80211) + struct cfg80211_ft_event_params ftEvent; + v_U8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN]; + v_U8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN]; + struct net_device *dev = pAdapter->dev; +#else + char *buff; + union iwreq_data wrqu; + tANI_U16 str_len; +#endif + +#if defined(KERNEL_SUPPORT_11R_CFG80211) + vos_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN); + vos_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN); + + sme_GetRICIEs( pHddCtx->hHal, pAdapter->sessionId, (u8 *)ricIe, + DOT11F_IE_FTINFO_MAX_LEN, &ric_ies_length ); + if (ric_ies_length == 0) + { + hddLog(LOGW, + "%s: RIC IEs is of length 0 not sending RIC Information for now", + __func__); + } + + ftEvent.ric_ies = ricIe; + ftEvent.ric_ies_len = ric_ies_length; + hddLog(LOG1, "%s: RIC IEs is of length %d", __func__, (int)ric_ies_length); + + sme_GetFTPreAuthResponse(pHddCtx->hHal, pAdapter->sessionId, (u8 *)ftIe, + DOT11F_IE_FTINFO_MAX_LEN, &auth_resp_len); + + if (auth_resp_len == 0) + { + hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__); + return; + } + + sme_SetFTPreAuthState(pHddCtx->hHal, pAdapter->sessionId, VOS_TRUE); + + ftEvent.target_ap = ftIe; + + ftEvent.ies = (u8 *)(ftIe + SIR_MAC_ADDR_LENGTH); + ftEvent.ies_len = auth_resp_len - SIR_MAC_ADDR_LENGTH; + + hddLog(LOG1, "%s ftEvent.ies_len %zu", __FUNCTION__, ftEvent.ies_len); + hddLog(LOG1, "%s ftEvent.ric_ies_len %zu", + __FUNCTION__, ftEvent.ric_ies_len ); + hddLog(LOG1, "%s ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x ", + __FUNCTION__, ftEvent.target_ap[0], ftEvent.target_ap[1], + ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4], + ftEvent.target_ap[5]); + + (void)cfg80211_ft_event(dev, &ftEvent); + +#else + // We need to send the IEs to the supplicant + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + vos_mem_zero(buff, IW_CUSTOM_MAX); + + // Sme needs to send the RIC IEs first + str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX); + sme_GetRICIEs( pHddCtx->hHal, pAdapter->sessionId, (u8 *)&(buff[str_len]), + (IW_CUSTOM_MAX - str_len), &ric_ies_length ); + if (ric_ies_length == 0) + { + hddLog(LOGW, + "%s: RIC IEs is of length 0 not sending RIC Information for now", + __func__); + } + else + { + wrqu.data.length = str_len + ric_ies_length; + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + } + + // Sme needs to provide the Auth Resp + vos_mem_zero(buff, IW_CUSTOM_MAX); + str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX); + sme_GetFTPreAuthResponse(pHddCtx->hHal, pAdapter->sessionId, + (u8 *)&buff[str_len], + (IW_CUSTOM_MAX - str_len), + &auth_resp_len); + + if (auth_resp_len == 0) + { + hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__); + kfree(buff); + return; + } + + wrqu.data.length = str_len + auth_resp_len; + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + + kfree(buff); +#endif +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef FEATURE_WLAN_ESE + +/* + * Send the ESE required "new AP Channel info" to the supplicant. + * (This keeps the supplicant "up to date" on the current channel.) + * + * The current (new AP) channel information is passed in. + */ +static void hdd_SendNewAPChannelInfo(struct net_device *dev, hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc; + + + if (descriptor == NULL) + { + hddLog(LOGE, + "%s: pCsrRoamInfo->pBssDesc=%p", + __func__, descriptor); + return; + } + + // Send the Channel event, the supplicant needs this to generate the Adjacent AP report. + hddLog(LOGW, "%s: Sending up an SIOCGIWFREQ, channelId=%d", __func__, descriptor->channelId); + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.freq.m = descriptor->channelId; + wrqu.freq.e = 0; + wrqu.freq.i = 0; + wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL); +} + +#endif /* FEATURE_WLAN_ESE */ + +void hdd_SendUpdateBeaconIEsEvent(hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + u8 *pBeaconIes; + u8 currentLen = 0; + char *buff; + int totalIeLen = 0, currentOffset = 0, strLen; + + memset(&wrqu, '\0', sizeof(wrqu)); + + if (0 == pCsrRoamInfo->nBeaconLength) + { + hddLog(LOGW, "%s: pCsrRoamInfo->nBeaconFrameLength = 0", __func__); + return; + } + pBeaconIes = (u8 *)(pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET); + if (pBeaconIes == NULL) + { + hddLog(LOGW, "%s: Beacon IEs is NULL", __func__); + return; + } + + // pBeaconIes needs to point to the IEs + hddLog(LOG1, "%s: Beacon IEs is now at %02x%02x", __func__, + (unsigned int)pBeaconIes[0], + (unsigned int)pBeaconIes[1]); + hddLog(LOG1, "%s: Beacon IEs length = %d", __func__, pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET); + + // We need to send the IEs to the supplicant. + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + vos_mem_zero(buff, IW_CUSTOM_MAX); + + strLen = strlcpy(buff,"BEACONIEs=", IW_CUSTOM_MAX); + currentLen = strLen + 1; + + totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET; + do + { + /* If the beacon size exceeds max CUSTOM event size, break it into chunks of CUSTOM event + * max size and send it to supplicant. Changes are done in supplicant to handle this */ + vos_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1)); + currentLen = VOS_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1); + vos_mem_copy(&buff[strLen + 1], pBeaconIes+currentOffset, currentLen); + currentOffset += currentLen; + totalIeLen -= currentLen; + wrqu.data.length = strLen + 1 + currentLen; + if (totalIeLen) + buff[strLen] = 1; // This tells supplicant more chunks are pending + else + buff[strLen] = 0; // For last chunk of beacon IE to supplicant + + hddLog(LOG1, "%s: Beacon IEs length to supplicant = %d", __func__, currentLen); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + } while (totalIeLen > 0); + + kfree(buff); +} + +static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRoamInfo) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + union iwreq_data wrqu; + int we_event; + char *msg; + int type = -1; + v_MACADDR_t peerMacAddr; + +#if defined (WLAN_FEATURE_VOWIFI_11R) + // Added to find the auth type on the fly at run time + // rather than with cfg to see if FT is enabled + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile); +#endif + + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + we_event = SIOCGIWAP; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (NULL != pCsrRoamInfo) + if (pCsrRoamInfo->roamSynchInProgress) + /* change logging before release */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "LFR3:hdd_SendAssociationEvent"); +#endif + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */ + { + if (!pCsrRoamInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA in associated state but pCsrRoamInfo is null", + __func__); + return; + } + + wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode); + memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId, sizeof(pCsrRoamInfo->pBssDesc->bssId)); + type = WLAN_STA_ASSOC_DONE_IND; + +#ifdef WLAN_FEATURE_P2P_DEBUG + if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_1) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTED_STATE_1; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Connecting state to Connected State for 8-way " + "Handshake"); + } + else if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_2) + { + globalP2PConnectionStatus = P2P_CLIENT_COMPLETED_STATE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Connecting state to P2P Client Connection Completed"); + } + } +#endif + pr_info("wlan: " MAC_ADDRESS_STR " connected to " MAC_ADDRESS_STR "\n", + MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes), + MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data)); + hdd_SendUpdateBeaconIEsEvent(pAdapter, pCsrRoamInfo); + + + /* Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS is Enabled Or + * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_VOWIFI_11R is Enabled + * and fFTEnable is TRUE */ +#ifdef WLAN_FEATURE_VOWIFI_11R + // Send FT Keys to the supplicant when FT is enabled + if ((pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN_PSK) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN) +#ifdef FEATURE_WLAN_ESE + || (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) +#endif + ) + { + hdd_SendFTAssocResponse(dev, pAdapter, pCsrRoamInfo); + } +#endif + if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + tSirSmeChanInfo chan_info; + vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId, + sizeof(pHddStaCtx->conn_info.bssId)); + chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id; + chan_info.mhz = pCsrRoamInfo->chan_info.mhz; + chan_info.info = pCsrRoamInfo->chan_info.info; + chan_info.band_center_freq1 = pCsrRoamInfo->chan_info.band_center_freq1; + chan_info.band_center_freq2 = pCsrRoamInfo->chan_info.band_center_freq2; + chan_info.reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1; + chan_info.reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2; + + /* send peer status indication to oem app */ + hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerConnected, + pCsrRoamInfo->timingMeasCap, + pAdapter->sessionId, + &chan_info); + } + +#ifdef FEATURE_WLAN_TDLS + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) { + hddLog(LOG1, + FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"), + pCsrRoamInfo->tdls_prohibited, + pCsrRoamInfo->tdls_chan_swit_prohibited); + + wlan_hdd_update_tdls_info(pAdapter, pCsrRoamInfo->tdls_prohibited, + pCsrRoamInfo->tdls_chan_swit_prohibited); + } +#endif + +#ifdef MSM_PLATFORM +#ifdef CONFIG_CNSS + /* start timer in sta/p2p_cli */ + spin_lock_bh(&pHddCtx->bus_bw_lock); + pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + spin_unlock_bh(&pHddCtx->bus_bw_lock); + hdd_start_bus_bw_compute_timer(pAdapter); +#endif +#endif + } + else if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) // IBss Associated + { + wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode); + memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId, ETH_ALEN); + type = WLAN_STA_ASSOC_DONE_IND; + pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR"\n", + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId)); + } + else /* Not Associated */ + { + pr_info("wlan: disconnected\n"); + type = WLAN_STA_DISASSOC_DONE_IND; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); +#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + wlan_hdd_enable_roaming(pAdapter); +#endif + +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0], + WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE); +#endif + + if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId, + sizeof(pHddStaCtx->conn_info.bssId)); + + /* send peer status indication to oem app */ + hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerDisconnected, + 0, pAdapter->sessionId, + NULL); + } + +#ifdef WLAN_FEATURE_LPSS + pAdapter->rssi_send = VOS_FALSE; + wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0); +#endif + +#ifdef MSM_PLATFORM + /* stop timer in sta/p2p_cli */ + spin_lock_bh(&pHddCtx->bus_bw_lock); + pAdapter->prev_tx_packets = 0; + pAdapter->prev_rx_packets = 0; + spin_unlock_bh(&pHddCtx->bus_bw_lock); + hdd_stop_bus_bw_compute_timer(pAdapter); +#endif + } + hdd_dump_concurrency_info(pHddCtx); + + msg = NULL; + /*During the WLAN uninitialization,supplicant is stopped before the + driver so not sending the status of the connection to supplicant*/ + if ((pHddCtx->isLoadInProgress != TRUE) && + (pHddCtx->isUnloadInProgress != TRUE)) + { + wireless_send_event(dev, we_event, &wrqu, msg); +#ifdef FEATURE_WLAN_ESE + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */ + { + if ( (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) ) + hdd_SendNewAPChannelInfo(dev, pAdapter, pCsrRoamInfo); + } +#endif + } + send_btc_nlink_msg(type, 0); +} + +void hdd_connRemoveConnectInfo( hdd_station_ctx_t *pHddStaCtx ) +{ + // Remove staId, bssId and peerMacAddress + pHddStaCtx->conn_info.staId [ 0 ] = 0; + vos_mem_zero( &pHddStaCtx->conn_info.bssId, sizeof( v_MACADDR_t ) ); + vos_mem_zero( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], sizeof( v_MACADDR_t ) ); + + // Clear all security settings + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + + vos_mem_zero( &pHddStaCtx->conn_info.Keys, sizeof( tCsrKeys ) ); + vos_mem_zero( &pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey) ); + + // Set not-connected state + pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY; + pHddStaCtx->conn_info.proxyARPService = 0; + + vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) ); +} +/* TODO Revisit this function. and data path */ +static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (WLAN_HDD_IBSS != pAdapter->device_mode) + { + hdd_disconnect_tx_rx(pAdapter); + } + else + { + // Need to cleanup all queues only if the last peer leaves + if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState) + { + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + hdd_disconnect_tx_rx(pAdapter); + } + else + { + // There is atleast one more peer, do not cleanup all queues + hdd_flush_ibss_tx_queues(pAdapter, staId); + } + } + + vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + __func__, staId, vosStatus, vosStatus ); + } + return( vosStatus ); +} + + +static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vstatus; + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_U8_t sta_id; + v_BOOL_t sendDisconInd = TRUE; + + // Sanity check + if(dev == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: net_dev is released return", __func__); + return eHAL_STATUS_FAILURE; + } + + // notify apps that we can't pass traffic anymore + netif_tx_disable(dev); + netif_carrier_off(dev); + +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0], + WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE); +#endif + +#ifdef QCA_PKT_PROTO_TRACE + /* STA disconnected, update into trace buffer */ + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + vos_pkt_trace_buf_update("ST:DISASC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + + /* HDD has initiated disconnect, do not send disconnect indication + * to kernel as it will be handled by __cfg80211_disconnect. + */ + if ( eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL(" HDD has initiated a disconnect, no need to send" + " disconnect indication to kernel")); + sendDisconInd = FALSE; + } + + if(pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) + { + INIT_COMPLETION(pAdapter->disconnect_comp_var); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_Disconnecting", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_Disconnecting); + } + + /* If only STA mode is on */ + if((pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1)) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + hdd_clearRoamProfileIe( pAdapter ); + hdd_wmm_init( pAdapter ); + + // indicate 'disconnect' status to wpa_supplicant... + hdd_SendAssociationEvent(dev,pRoamInfo); + /* indicate disconnected event to nl80211 */ + if(roamStatus != eCSR_ROAM_IBSS_LEAVE) + { + /*During the WLAN uninitialization,supplicant is stopped before the + driver so not sending the status of the connection to supplicant*/ + if ((pHddCtx->isLoadInProgress != TRUE) && + (pHddCtx->isUnloadInProgress != TRUE)) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: sent disconnected event to nl80211", + __func__); +#ifdef WLAN_FEATURE_P2P_DEBUG + if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTED_STATE_1) + { + globalP2PConnectionStatus = P2P_CLIENT_DISCONNECTED_STATE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] 8 way Handshake completed " + "and moved to disconnected state"); + } + else if(globalP2PConnectionStatus == P2P_CLIENT_COMPLETED_STATE) + { + globalP2PConnectionStatus = P2P_NOT_ACTIVE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] P2P Client is removed " + "and moved to inactive state"); + } + } +#endif + + /*Only send indication to kernel if not initiated by kernel*/ + if ( sendDisconInd ) + { + /* To avoid wpa_supplicant sending "HANGED" CMD to ICS UI */ + if( eCSR_ROAM_LOSTLINK == roamStatus ) + { + cfg80211_disconnected(dev, pRoamInfo->reasonCode, NULL, 0, GFP_KERNEL); + } + else + { + cfg80211_disconnected(dev, WLAN_REASON_UNSPECIFIED, NULL, 0, GFP_KERNEL); + } + } + //If the Device Mode is Station + // and the P2P Client is Connected + //Enable BMPS + + /* + * In case of JB, as Change-Iface may or may not be called for p2p0 + * Enable BMPS/IMPS in case P2P_CLIENT disconnected + * If power save offload is enabled, Fw will take care + * of power save in case of concurrency. + */ + if((VOS_STATUS_SUCCESS == hdd_issta_p2p_clientconnected(pHddCtx)) + && !pHddCtx->cfg_ini->enablePowersaveOffload) + { + //Enable BMPS only of other Session is P2P Client + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + + if(NULL != pHddCtx) + { + //Only P2P Client is there Enable Bmps back + if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) && + (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE])) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + } + } + } + } + } + + if (eCSR_ROAM_IBSS_LEAVE == roamStatus) + { + sta_id = IBSS_BROADCAST_STAID; + } + else + { + sta_id = pHddStaCtx->conn_info.staId[0]; + } + hdd_wmm_adapter_clear(pAdapter); +#if defined(WLAN_FEATURE_VOWIFI_11R) + sme_FTReset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId); +#endif + //We should clear all sta register with TL, for now, only one. + vstatus = hdd_roamDeregisterSTA( pAdapter, sta_id ); + if ( !VOS_IS_STATUS_SUCCESS(vstatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "hdd_roamDeregisterSTA() failed to for staID %d. " + "Status= %d [0x%x]", + sta_id, status, status ); + + status = eHAL_STATUS_FAILURE; + } + + pHddCtx->sta_to_adapter[sta_id] = NULL; + // Clear saved connection information in HDD + hdd_connRemoveConnectInfo( pHddStaCtx ); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_NotConnected); +#ifdef WLAN_FEATURE_GTK_OFFLOAD + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + memset(&pHddStaCtx->gtkOffloadReqParams, 0, + sizeof (tSirGtkOffloadParams)); + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + } +#endif + +#ifdef FEATURE_WLAN_TDLS + if (eCSR_ROAM_IBSS_LEAVE != roamStatus) + { + wlan_hdd_tdls_disconnection_callback(pAdapter); + } +#endif + + if (pHddCtx->cfg_ini->enablePowersaveOffload && + ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))) + { + sme_PsOffloadDisableDeferredPowerSave( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + } + + //Unblock anyone waiting for disconnect to complete + complete(&pAdapter->disconnect_comp_var); + return( status ); +} +static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + v_U8_t staId, + v_MACADDR_t *pPeerMacAddress, + tSirBssDescription *pBssDesc ) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + eCsrEncryptionType connectedCipherAlgo; + v_BOOL_t fConnected; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + + if ( NULL == pBssDesc) + { + return VOS_STATUS_E_FAILURE; + } + /* Get the Station ID from the one saved during the association */ + staDesc.ucSTAId = staId; + + if ( pHddStaCtx->conn_info.connDot11DesiredBssType == eMib_dot11DesiredBssType_infrastructure) + { + staDesc.wSTAType = WLAN_STA_INFRA; + + // grab the bssid from the connection info in the adapter structure and hand that + // over to TL when registering. + vos_mem_copy( staDesc.vSTAMACAddress.bytes, pHddStaCtx->conn_info.bssId,sizeof(pHddStaCtx->conn_info.bssId) ); + } + else + { + // for an IBSS 'connect', setup the Station Descriptor for TL. + staDesc.wSTAType = WLAN_STA_IBSS; + + /* + * Note that for IBSS, the STA MAC address and BSSID are going to be + * different where in infrastructure, they are the same (BSSID is the + * MAC address of the AP). So, for IBSS we have a second field to pass + * to TL in the STA descriptor that we don't pass when making an + * Infrastructure connection. + */ + vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) ); + vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 ); + } + + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + // set the QoS field appropriately + if (hdd_wmm_is_active(pAdapter)) + { + staDesc.ucQosEnabled = 1; + } + else + { + staDesc.ucQosEnabled = 0; + } + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if ( connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE ) + { + staDesc.ucProtectedFrame = 1; + } + else + { + staDesc.ucProtectedFrame = 0; + + } + +#ifdef FEATURE_WLAN_ESE + staDesc.ucIsEseSta = pRoamInfo->isESEAssoc; +#endif //FEATURE_WLAN_ESE + +#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK + /* check whether replay check is valid for the station or not */ + if( (eCSR_ENCRYPT_TYPE_TKIP == connectedCipherAlgo) || (eCSR_ENCRYPT_TYPE_AES == connectedCipherAlgo)) + { + /* Encryption mode is either TKIP or AES + and replay check is valid for only these + two encryption modes */ + staDesc.ucIsReplayCheckValid = VOS_TRUE; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "HDD register TL ucIsReplayCheckValid %d: Replay check is needed for station", staDesc.ucIsReplayCheckValid); + } + + else + { + /* For other encryption modes replay check is + not needed */ + staDesc.ucIsReplayCheckValid = VOS_FALSE; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "HDD register TL ucIsReplayCheckValid %d", staDesc.ucIsReplayCheckValid); + } +#endif + +#ifdef FEATURE_WLAN_WAPI + hddLog(LOG1, "%s: WAPI STA Registered: %d", __func__, pAdapter->wapi_info.fIsWapiSta); + if (pAdapter->wapi_info.fIsWapiSta) + { + staDesc.ucIsWapiSta = 1; + } + else + { + staDesc.ucIsWapiSta = 0; + } +#endif /* FEATURE_WLAN_WAPI */ + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame ); + + // UMA is Not ready yet, Xlation will be done by TL + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register TL QoS_enabled=%d", + staDesc.ucQosEnabled ); + // Initialize signatures and state + staDesc.ucUcastSig = pRoamInfo->ucastSig; + staDesc.ucBcastSig = pRoamInfo->bcastSig; + staDesc.ucInitState = pRoamInfo->fAuthRequired ? + WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED; + // Register the Station with TL... + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HDD register TL ucInitState=%d", __func__, staDesc.ucInitState ); + + /* Incase Micro controller data path offload enabled, + * All the traffic routed to WLAN host driver, do not need to + * route IPA. It should be routed kernel network stack */ +#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + if (hdd_ipa_is_enabled(pHddCtx)) + vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext, + hdd_ipa_process_rxt, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, + pBssDesc->rssi ); + else +#endif + vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext, + hdd_rx_packet_cbk, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, + pBssDesc->rssi ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + vosStatus, vosStatus ); + return vosStatus; + } + + if ( cfg_param->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + cfg_param->trafficMntrTmrForSplitScan); + } + + // if (WPA), tell TL to go to 'connected' and after keys come to the driver, + // then go to 'authenticated'. For all other authentication types + // (those that donot require upper layer authentication) we can put + // TL directly into 'authenticated' state. + if (staDesc.wSTAType != WLAN_STA_IBSS) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "STA type %d fConnected %d", staDesc.wSTAType, fConnected); + } + + + if ( !pRoamInfo->fAuthRequired ) + { + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + + hdd_connSetAuthenticated(pAdapter, VOS_TRUE); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "ULA auth StaId= %d. Changing TL state to CONNECTED" + "at Join time", pHddStaCtx->conn_info.staId[0] ); + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, staDesc.ucSTAId, + WLANTL_STA_CONNECTED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + hdd_connSetAuthenticated(pAdapter, VOS_FALSE); + } + return( vosStatus ); +} + +static void hdd_SendReAssocEvent(struct net_device *dev, + hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo, v_U8_t *reqRsnIe, + tANI_U32 reqRsnLength) +{ + unsigned int len = 0; + u8 *pFTAssocRsp = NULL; + v_U8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL); + tANI_U32 rspRsnLength = 0; + struct ieee80211_channel *chan; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (!rspRsnIe) { + hddLog(LOGE, FL("Unable to allocate RSN IE")); + return; + } + + if (pCsrRoamInfo == NULL) { + hddLog(LOGE, FL("Invalid CSR roam info")); + goto done; + } + + if (pCsrRoamInfo->nAssocRspLength == 0) { + hddLog(LOGE, FL("Invalid assoc response length")); + goto done; + } + + pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength + + pCsrRoamInfo->nAssocReqLength); + if (pFTAssocRsp == NULL) + goto done; + + /* pFTAssocRsp needs to point to the IEs */ + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, FL("AssocRsp is now at %02x%02x"), + (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]); + + /* Active session count is decremented upon disconnection, but during + * roaming, there is no disconnect indication and hence active session + * count is not decremented. + * After roaming is completed, active session count is incremented + * as a part of connect indication but effectively after roaming the + * active session count should still be the same and hence upon + * successful reassoc decrement the active session count here */ + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + + /* Send the Assoc Resp, the supplicant needs this for initial Auth */ + len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + rspRsnLength = len; + memcpy(rspRsnIe, pFTAssocRsp, len); + memset(rspRsnIe + len, 0, IW_GENERIC_IE_MAX - len); + + chan = ieee80211_get_channel(pAdapter->wdev.wiphy, + (int)pCsrRoamInfo->pBssDesc->channelId); + cfg80211_roamed(dev, chan, pCsrRoamInfo->bssid, + reqRsnIe, reqRsnLength, + rspRsnIe, rspRsnLength,GFP_KERNEL); +done: + kfree(rspRsnIe); +} + +void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamInfo roamInfo; + roamInfo.fAuthRequired = FALSE; + vos_mem_copy(roamInfo.bssid, + pHddStaCtx->roam_info.bssid, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(roamInfo.peerMac, + pHddStaCtx->roam_info.peerMac, + VOS_MAC_ADDR_SIZE); + + halStatus = hdd_RoamSetKeyCompleteHandler(pAdapter, + &roamInfo, + pHddStaCtx->roam_info.roamId, + pHddStaCtx->roam_info.roamStatus, + eCSR_ROAM_RESULT_AUTHENTICATED); + if (halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, "%s: Set Key complete failure", __func__); + } + pHddStaCtx->roam_info.deferKeyComplete = FALSE; +} + +static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); +#ifdef FEATURE_WLAN_FORCE_SAP_SCC + hdd_adapter_t *pHostapdAdapter; +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + v_U8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN]; + tANI_U32 reqRsnLength = DOT11F_IE_RSN_MAX_LEN; +#if defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || defined (WLAN_FEATURE_VOWIFI_11R) + int ft_carrier_on = FALSE; +#endif + v_BOOL_t hddDisconInProgress = FALSE; + unsigned long rc; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pRoamInfo && pRoamInfo->roamSynchInProgress) { + /* change logging before release */ + hddLog(VOS_TRACE_LEVEL_DEBUG, "LFR3:hdd_AssociationCompletionHandler"); + } +#endif + + /* HDD has initiated disconnect, do not send connect result indication + * to kernel as it will be handled by __cfg80211_disconnect. + */ + if(( eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) && + (( eCSR_ROAM_RESULT_ASSOCIATED == roamResult) || + ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus)) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL(" Disconnect from HDD in progress ")); + hddDisconInProgress = TRUE; + } + + if ( eCSR_ROAM_RESULT_ASSOCIATED == roamResult ) + { + if (NULL == pRoamInfo) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pRoamInfo is NULL")); + return eHAL_STATUS_FAILURE; + } + if ( !hddDisconInProgress ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_Associated", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_Associated); + } + + // Save the connection info from CSR... + hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE ); +#ifdef FEATURE_WLAN_WAPI + if ( pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE || + pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_PSK ) + { + pAdapter->wapi_info.fIsWapiSta = 1; + } + else + { + pAdapter->wapi_info.fIsWapiSta = 0; + } +#endif /* FEATURE_WLAN_WAPI */ + + /* Indicate 'connect' status to user space */ + hdd_SendAssociationEvent(dev,pRoamInfo); + + // Initialize the Linkup event completion variable + INIT_COMPLETION(pAdapter->linkup_event_var); + + /* + Sometimes Switching ON the Carrier is taking time to activate the device properly. Before allowing any + packet to go up to the application, device activation has to be ensured for proper queue mapping by the + kernel. we have registered net device notifier for device change notification. With this we will come to + know that the device is getting activated properly. + */ +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pHddStaCtx->ft_carrier_on == FALSE) + { +#endif + // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable + pAdapter->isLinkUpSvcNeeded = TRUE; + + // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable + pAdapter->isLinkUpSvcNeeded = TRUE; + + // Switch on the Carrier to activate the device + netif_carrier_on(dev); + + // Wait for the Link to up to ensure all the queues are set properly by the kernel + rc = wait_for_completion_timeout(&pAdapter->linkup_event_var, + msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning:ASSOC_LINKUP_TIMEOUT", __func__); + } + + // Disable Linkup Event Servicing - no more service required from the net device notifier call + pAdapter->isLinkUpSvcNeeded = FALSE; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + } + else { + pHddStaCtx->ft_carrier_on = FALSE; + ft_carrier_on = TRUE; + } +#endif + /* Check for STAID */ + if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId) + pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter; + else + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Wrong Staid: %d", __func__, + pRoamInfo->staId); + +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT, + pRoamInfo->bssid); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_FALSE); +#endif + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (pHddCtx->cfg_ini->WlanMccToSccSwitchMode + != VOS_MCC_TO_SCC_SWITCH_DISABLE +#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + && !VOS_IS_DFS_CH(pHddStaCtx->conn_info.operationChannel) +#endif + ) { + adf_os_create_work(0, &pHddCtx->sta_ap_intf_check_work, + wlan_hdd_check_sta_ap_concurrent_ch_intf, (void *)pAdapter); + adf_os_sched_work(0, &pHddCtx->sta_ap_intf_check_work); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Checking for Concurrent Change interference"); + } +#endif + +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_connection_callback(pAdapter); +#endif + +#ifdef QCA_PKT_PROTO_TRACE + /* STA Associated, update into trace buffer */ + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + vos_pkt_trace_buf_update("ST:ASSOC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + //For reassoc, the station is already registered, all we need is to change the state + //of the STA in TL. + //If authentication is required (WPA/WPA2/DWEP), change TL to CONNECTED instead of AUTHENTICATED + if( !pRoamInfo->fReassocReq ) + { + struct cfg80211_bss *bss; +#ifdef WLAN_FEATURE_VOWIFI_11R + u8 *pFTAssocRsp = NULL; + unsigned int assocRsplen = 0; + u8 *pFTAssocReq = NULL; + unsigned int assocReqlen = 0; + struct ieee80211_channel *chan; +#endif + v_U8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN]; + tANI_U32 rspRsnLength = DOT11F_IE_RSN_MAX_LEN; + + /* add bss_id to cfg80211 data base */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + pr_err("wlan: Not able to create BSS entry\n"); + return eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN || + pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN_PSK ) + { + + //Association Response + pFTAssocRsp = (u8 *)(pRoamInfo->pbFrames + pRoamInfo->nBeaconLength + + pRoamInfo->nAssocReqLength); + if (pFTAssocRsp != NULL) + { + // pFTAssocRsp needs to point to the IEs + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__, + (unsigned int)pFTAssocRsp[0], + (unsigned int)pFTAssocRsp[1]); + assocRsplen = pRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + } + else + { + hddLog(LOGE, "%s:AssocRsp is NULL", __func__); + assocRsplen = 0; + } + + //Association Request + pFTAssocReq = (u8 *)(pRoamInfo->pbFrames + + pRoamInfo->nBeaconLength); + if (pFTAssocReq != NULL) + { + if(!ft_carrier_on) + { + // pFTAssocReq needs to point to the IEs + pFTAssocReq += FT_ASSOC_REQ_IES_OFFSET; + hddLog(LOG1, "%s: pFTAssocReq is now at %02x%02x", __func__, + (unsigned int)pFTAssocReq[0], + (unsigned int)pFTAssocReq[1]); + assocReqlen = pRoamInfo->nAssocReqLength - FT_ASSOC_REQ_IES_OFFSET; + } + else + { + /* This should contain only the FTIEs */ + assocReqlen = pRoamInfo->nAssocReqLength; + } + } + else + { + hddLog(LOGE, "%s:AssocReq is NULL", __func__); + assocReqlen = 0; + } + + if(ft_carrier_on) + { + if ( !hddDisconInProgress ) + { + /* After roaming is completed, active session count is + * incremented as a part of connect indication but + * effectively the active session count should still + * be the same and hence upon successful reassoc + * decrement the active session count here */ + wlan_hdd_decr_active_session(pHddCtx, + pAdapter->device_mode); + + hddLog(LOG1, "%s ft_carrier_on is %d, sending roamed " + "indication", __FUNCTION__, ft_carrier_on); + chan = ieee80211_get_channel(pAdapter->wdev.wiphy, + (int)pRoamInfo->pBssDesc->channelId); + hddLog(LOG1, "assocReqlen %d assocRsplen %d", assocReqlen, + assocRsplen); + cfg80211_roamed(dev,chan, pRoamInfo->bssid, + pFTAssocReq, assocReqlen, pFTAssocRsp, assocRsplen, + GFP_KERNEL); + } + if (sme_GetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId)) + { + sme_SetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, FALSE); + pRoamInfo->fAuthRequired = FALSE; + + vos_mem_copy(pHddStaCtx->roam_info.bssid, + pRoamInfo->bssid, + HDD_MAC_ADDR_LEN); + vos_mem_copy(pHddStaCtx->roam_info.peerMac, + pRoamInfo->peerMac, + HDD_MAC_ADDR_LEN); + pHddStaCtx->roam_info.roamId = roamId; + pHddStaCtx->roam_info.roamStatus = roamStatus; + pHddStaCtx->roam_info.deferKeyComplete = TRUE; + } + } + else if ( !hddDisconInProgress ) + { + hddLog(LOG1, "%s ft_carrier_on is %d, sending connect " + "indication", __FUNCTION__, ft_carrier_on); + cfg80211_connect_result(dev, pRoamInfo->bssid, + pFTAssocReq, assocReqlen, + pFTAssocRsp, assocRsplen, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + } + else +#endif + { + /* wpa supplicant expecting WPA/RSN IE in connect result */ + csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &reqRsnLength, + reqRsnIe); + + csrRoamGetWpaRsnRspIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &rspRsnLength, + rspRsnIe); + if ( !hddDisconInProgress ) + { +#if defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if(ft_carrier_on) + hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength); + else +#endif /* FEATURE_WLAN_ESE */ + + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: sending connect indication to nl80211:for bssid " MAC_ADDRESS_STR " reason:%d and Status:%d", + __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid), + roamResult, roamStatus); + + /* inform connect result to nl80211 */ + cfg80211_connect_result(dev, pRoamInfo->bssid, + reqRsnIe, reqRsnLength, + rspRsnIe, rspRsnLength, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + } + } + if ( !hddDisconInProgress ) + { + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + pHddCtx->wiphy, +#endif + bss); + + // perform any WMM-related association processing + hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE); + + /* Start the Queue - Start tx queues before hdd_roamRegisterSTA, + since hdd_roamRegisterSTA will flush any cached data frames + immediately */ + netif_tx_wake_all_queues(dev); + + // Register the Station with TL after associated... + vosStatus = hdd_roamRegisterSTA( pAdapter, + pRoamInfo, + pHddStaCtx->conn_info.staId[ 0 ], + NULL, + pRoamInfo->pBssDesc ); + } + } + else + { + /* wpa supplicant expecting WPA/RSN IE in connect result */ + /* in case of reassociation also need to indicate it to supplicant */ + csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &reqRsnLength, + reqRsnIe); + + hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength); + //Reassoc successfully + if( pRoamInfo->fAuthRequired ) + { + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0], + WLANTL_STA_CONNECTED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + hdd_connSetAuthenticated(pAdapter, VOS_FALSE); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: staId: %d Changing TL state to AUTHENTICATED", + __func__, pHddStaCtx->conn_info.staId[ 0 ] ); + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0], + WLANTL_STA_AUTHENTICATED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + hdd_connSetAuthenticated(pAdapter, VOS_TRUE); + } + + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // perform any WMM-related association processing + hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE); + } + + /* Start the tx queues */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pRoamInfo->roamSynchInProgress) { + hddLog(VOS_TRACE_LEVEL_DEBUG, "LFR3:netif_tx_wake_all_queues"); + } +#endif + netif_tx_wake_all_queues(dev); + } + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Cannot register STA with TL. Failed with vosStatus = %d [%08X]", + vosStatus, vosStatus ); + } +#ifdef WLAN_FEATURE_11W + vos_mem_zero( &pAdapter->hdd_stats.hddPmfStats, + sizeof(pAdapter->hdd_stats.hddPmfStats) ); +#endif + } + else + { + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (pRoamInfo) + pr_info("wlan: connection failed with " MAC_ADDRESS_STR + " reason:%d and Status:%d\n", + MAC_ADDR_ARRAY(pRoamInfo->bssid), + roamResult, roamStatus); + else + pr_info("wlan: connection failed with " MAC_ADDRESS_STR + " reason:%d and Status:%d\n", + MAC_ADDR_ARRAY(pWextState->req_bssId), + roamResult, roamStatus); + + /* Set connection state to eConnectionState_NotConnected only when CSR + * has completed operation - with a ASSOCIATION_FAILURE status + */ + if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus && !hddDisconInProgress ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_NotConnected); + } + if((pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1)) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + + //If the Device Mode is Station + // and the P2P Client is Connected + //Enable BMPS + + /* + * In case of JB, as Change-Iface may or may not be called for p2p0 + * Enable BMPS/IMPS in case P2P_CLIENT disconnected + * If ps offload is enabled, fw will take care in case of concurrency. + */ + if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) && + (vos_concurrent_open_sessions_running()) && + !pHddCtx->cfg_ini->enablePowersaveOffload) + { + //Enable BMPS only of other Session is P2P Client + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + + if(NULL != pHddCtx) + { + //Only P2P Client is there Enable Bmps back + if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) && + (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE])) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + } + } + } + + /* CR465478: Only send up a connection failure result when CSR has + * completed operation - with a ASSOCIATION_FAILURE status.*/ + if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus && !hddDisconInProgress ) + { + if (pRoamInfo) + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: send connect failure to nl80211: for bssid " MAC_ADDRESS_STR" reason:%d and Status:%d " , + __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid), + roamResult, roamStatus); + else + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: connect failed: for bssid " MAC_ADDRESS_STR " reason:%d and Status:%d " , + __func__, MAC_ADDR_ARRAY(pWextState->req_bssId), + roamResult, roamStatus); + + /* inform association failure event to nl80211 */ + if ( eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult ) + { + if (pRoamInfo) + cfg80211_connect_result ( dev, pRoamInfo->bssid, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL ); + else + cfg80211_connect_result ( dev, pWextState->req_bssId, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL ); + } + else + { + if (pRoamInfo) { + eCsrAuthType authType = + pWextState->roamProfile.AuthType.authType[0]; + v_BOOL_t isWep = (authType == eCSR_AUTH_TYPE_OPEN_SYSTEM) || + (authType == eCSR_AUTH_TYPE_SHARED_KEY); + + /* In case of OPEN-WEP or SHARED-WEP authentication, + * send exact protocol reason code. This enables user + * applications to reconnect the station with correct + * configuration. + */ + cfg80211_connect_result ( dev, pRoamInfo->bssid, + NULL, 0, NULL, 0, + isWep ? pRoamInfo->reasonCode : + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL ); + } else + cfg80211_connect_result ( dev, pWextState->req_bssId, + NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL ); + } + } + + if (pRoamInfo) { + if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) || + (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) || + (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode)) { + wlan_hdd_cfg80211_update_bss_list(pAdapter, pRoamInfo); + } + } + + /*Clear the roam profile*/ + hdd_clearRoamProfileIe( pAdapter ); + hdd_wmm_init( pAdapter ); + + netif_tx_disable(dev); + netif_carrier_off(dev); + + } + +#ifdef FEATURE_WLAN_FORCE_SAP_SCC + if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult && + pHddCtx->cfg_ini->SapSccChanAvoidance) { + pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (pHostapdAdapter != NULL) { + /* Restart SAP if its operating channel is different + * from AP channel. + */ + if (pHostapdAdapter->sessionCtx.ap.operatingChannel != + pRoamInfo->pBssDesc->channelId) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Restart Sap as SAP channel is %d and STA channel is %d", + pHostapdAdapter->sessionCtx.ap.operatingChannel, + pRoamInfo->pBssDesc->channelId); + hdd_restart_softap(pHddCtx, pHostapdAdapter); + } + } + } +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + return eHAL_STATUS_SUCCESS; +} + +/**============================================================================ + * + @brief hdd_RoamIbssIndicationHandler() - Here we update the status of the + Ibss when we receive information that we have started/joined an ibss session + + ===========================================================================*/ +static void hdd_RoamIbssIndicationHandler( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: id %d, status %d, result %d", + __func__, pAdapter->dev->name, roamId, roamStatus, roamResult); + + switch( roamResult ) + { + // both IBSS Started and IBSS Join should come in here. + case eCSR_ROAM_RESULT_IBSS_STARTED: + case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS: + case eCSR_ROAM_RESULT_IBSS_COALESCED: + { + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + if (NULL == pRoamInfo) + { + VOS_ASSERT(0); + return; + } + + /* When IBSS Started comes from CSR, we need to move + * connection state to IBSS Disconnected (meaning no peers + * are in the IBSS). + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_IbssDisconnected", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_IbssDisconnected); + /* Notify wmm */ + hdd_wmm_connect(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS); + pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter; + hdd_roamRegisterSTA (pAdapter, pRoamInfo, + IBSS_BROADCAST_STAID, + &broadcastMacAddr, pRoamInfo->pBssDesc); + + if (pRoamInfo->pBssDesc) + { + struct cfg80211_bss *bss; + + /* we created the IBSS, notify supplicant */ + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: created ibss " + MAC_ADDRESS_STR, + __func__, pAdapter->dev->name, + MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId)); + + /* we must first give cfg80211 the BSS information */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %s: unable to create IBSS entry", + __func__, pAdapter->dev->name); + return; + } + + cfg80211_ibss_joined(pAdapter->dev, bss->bssid, GFP_KERNEL); + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + pHddCtx->wiphy, +#endif + bss); + } + + break; + } + + case eCSR_ROAM_RESULT_IBSS_START_FAILED: + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unable to create IBSS", + __func__, pAdapter->dev->name); + break; + } + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unexpected result %d", + __func__, pAdapter->dev->name, (int)roamResult); + break; + } + + return; +} + +/**============================================================================ + * + @brief roamSaveIbssStation() - Save the IBSS peer MAC address in the adapter. + This information is passed to iwconfig later. The peer that joined + last is passed as information to iwconfig. + If we add HDD_MAX_NUM_IBSS_STA or less STA we return success else we + return FALSE. + + ===========================================================================*/ +static int roamSaveIbssStation( hdd_station_ctx_t *pHddStaCtx, v_U8_t staId, v_MACADDR_t *peerMacAddress ) +{ + int fSuccess = FALSE; + int idx = 0; + + for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) + { + if ( 0 == pHddStaCtx->conn_info.staId[ idx ] ) + { + pHddStaCtx->conn_info.staId[ idx ] = staId; + + vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ], peerMacAddress ); + + fSuccess = TRUE; + break; + } + } + + return( fSuccess ); +} +/**============================================================================ + * + @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter. + If we remove HDD_MAX_NUM_IBSS_STA or less STA we return success else we + return FALSE. + + ===========================================================================*/ +static int roamRemoveIbssStation( hdd_adapter_t *pAdapter, v_U8_t staId ) +{ + int fSuccess = FALSE; + int idx = 0; + v_U8_t valid_idx = 0; + v_U8_t del_idx = 0; + v_U8_t empty_slots = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) + { + if ( staId == pHddStaCtx->conn_info.staId[ idx ] ) + { + pHddStaCtx->conn_info.staId[ idx ] = 0; + + vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ] ); + + fSuccess = TRUE; + + // Note the deleted Index, if its 0 we need special handling + del_idx = idx; + + empty_slots++; + } + else + { + if (pHddStaCtx->conn_info.staId[idx] != 0) + { + valid_idx = idx; + } + else + { + // Found an empty slot + empty_slots++; + } + } + } + + if (HDD_MAX_NUM_IBSS_STA == empty_slots) + { + // Last peer departed, set the IBSS state appropriately + pHddStaCtx->conn_info.connState = eConnectionState_IbssDisconnected; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Last IBSS Peer Departed!!!" ); + } + + // Find next active staId, to have a valid sta trigger for TL. + if (fSuccess == TRUE) + { + if (del_idx == 0) + { + if (pHddStaCtx->conn_info.staId[valid_idx] != 0) + { + pHddStaCtx->conn_info.staId[0] = pHddStaCtx->conn_info.staId[valid_idx]; + vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], + &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ]); + + pHddStaCtx->conn_info.staId[valid_idx] = 0; + vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ] ); + } + } + } + return( fSuccess ); +} + +/**============================================================================ + * + @brief roamIbssConnectHandler() : We update the status of the IBSS to + connected in this function. + + ===========================================================================*/ +static eHalStatus roamIbssConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo ) +{ + struct cfg80211_bss *bss; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: IBSS Connect Indication from SME!!! " + "Set HDD connState to eConnectionState_IbssConnected", + __func__); + // Set the internal connection state to show 'IBSS Connected' (IBSS with a partner stations)... + hdd_connSetConnectionState(pAdapter, + eConnectionState_IbssConnected); + + // Save the connection info from CSR... + hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS ); + + // Send the bssid address to the wext. + hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo); + /* add bss_id to cfg80211 data base */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %s: unable to create IBSS entry", + __func__, pAdapter->dev->name); + return eHAL_STATUS_FAILURE; + } + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + WLAN_HDD_GET_CTX(pAdapter)->wiphy, +#endif + bss); + + return( eHAL_STATUS_SUCCESS ); +} +/**============================================================================ + * + @brief hdd_RoamSetKeyCompleteHandler() - Update the security parameters. + + ===========================================================================*/ +static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + eCsrEncryptionType connectedCipherAlgo; + v_BOOL_t fConnected = FALSE; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + ENTER(); + + if (NULL == pRoamInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "pRoamInfo is NULL"); + return eHAL_STATUS_FAILURE; + } + // if ( WPA ), tell TL to go to 'authenticated' after the keys are set. + // then go to 'authenticated'. For all other authentication types (those that do + // not require upper layer authentication) we can put TL directly into 'authenticated' + // state. + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Set Key completion roamStatus =%d roamResult=%d " MAC_ADDRESS_STR, + roamStatus, roamResult, MAC_ADDR_ARRAY(pRoamInfo->peerMac)); + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if( fConnected ) + { + if ( WLAN_HDD_IBSS == pAdapter->device_mode ) + { + v_U8_t staId; + + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + if ( 0 == memcmp( pRoamInfo->peerMac, + &broadcastMacAddr, VOS_MAC_ADDR_SIZE ) ) + { + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + IBSS_BROADCAST_STAID); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + else + { + vosStatus = hdd_Ibss_GetStaId(pHddStaCtx, + (v_MACADDR_t*)pRoamInfo->peerMac, + &staId); + if ( VOS_STATUS_SUCCESS == vosStatus ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL STA Ptk Installed for STAID=%d", staId); + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + staId); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + } + } + else + { + /* + * TODO: Considering getting a state machine in HDD later. + * This routine is invoked twice. 1)set PTK 2)set GTK. + * The following if statement will be TRUE when setting GTK. + * At this time we don't handle the state in detail. + * Related CR: 174048 - TL not in authenticated state + */ + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0], + WLANTL_STA_AUTHENTICATED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + hdd_connSetAuthenticated(pAdapter, VOS_TRUE); + if ( ( eCSR_ROAM_RESULT_AUTHENTICATED == roamResult ) && + (pRoamInfo != NULL) && !pRoamInfo->fAuthRequired ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, "Key set " + "for StaId= %d. Changing TL state to AUTHENTICATED", + pHddStaCtx->conn_info.staId[ 0 ] ); + + // Connections that do not need Upper layer authentication, + // transition TL to 'Authenticated' state after the keys are set. + vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0], + WLANTL_STA_AUTHENTICATED, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRoamInfo->roamSynchInProgress +#else + VOS_FALSE +#endif + ); + + hdd_connSetAuthenticated(pAdapter, VOS_TRUE); + + if (pHddCtx->cfg_ini->enablePowersaveOffload && + ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))) + { + sme_PsOffloadEnableDeferredPowerSave( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + pHddStaCtx->hdd_ReassocScenario); + } + } + else + { + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ]); + } + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + } + else + { + // possible disassoc after issuing set key and waiting set key complete + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + + EXIT(); + return( eHAL_STATUS_SUCCESS ); +} +/**============================================================================ + * + @brief hdd_RoamMicErrorIndicationHandler() - This function indicates the Mic failure to the supplicant. + ===========================================================================*/ +static eHalStatus hdd_RoamMicErrorIndicationHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if( eConnectionState_Associated == pHddStaCtx->conn_info.connState && + TKIP_COUNTER_MEASURE_STOPED == pHddStaCtx->WextState.mTKIPCounterMeasures ) + { + struct iw_michaelmicfailure msg; + union iwreq_data wreq; + memset(&msg, '\0', sizeof(msg)); + msg.src_addr.sa_family = ARPHRD_ETHER; + memcpy(msg.src_addr.sa_data, pRoamInfo->u.pMICFailureInfo->taMacAddr, sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr)); + hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(msg.src_addr.sa_data)); + + if(pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) + msg.flags = IW_MICFAILURE_GROUP; + else + msg.flags = IW_MICFAILURE_PAIRWISE; + memset(&wreq, 0, sizeof(wreq)); + wreq.data.length = sizeof(msg); + wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq, (char *)&msg); + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(pAdapter->dev, + pRoamInfo->u.pMICFailureInfo->taMacAddr, + ((pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE), + pRoamInfo->u.pMICFailureInfo->keyId, + pRoamInfo->u.pMICFailureInfo->TSC, + GFP_KERNEL); + + } + + return( eHAL_STATUS_SUCCESS ); +} + +/**============================================================================ + * + @brief roamRoamConnectStatusUpdateHandler() - The Ibss connection status is + updated regularly here in this function. + + ===========================================================================*/ +static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + VOS_STATUS vosStatus; + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + switch( roamResult ) + { + case eCSR_ROAM_RESULT_IBSS_NEW_PEER: + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + struct station_info staInfo; + + pr_info ( "IBSS New Peer indication from SME " + "with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId), + pRoamInfo->staId ); + + if ( !roamSaveIbssStation( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pRoamInfo->staId, (v_MACADDR_t *)pRoamInfo->peerMac ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "New IBSS peer but we already have the max we can handle. Can't register this one" ); + break; + } + + pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter; + + pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter; + WLANTL_UpdateSTABssIdforIBSS(pHddCtx->pvosContext, + IBSS_BROADCAST_STAID,pHddStaCtx->conn_info.bssId); + + // Register the Station with TL for the new peer. + vosStatus = hdd_roamRegisterSTA( pAdapter, + pRoamInfo, + pRoamInfo->staId, + (v_MACADDR_t *)pRoamInfo->peerMac, + pRoamInfo->pBssDesc ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Cannot register STA with TL for IBSS. Failed with vosStatus = %d [%08X]", + vosStatus, vosStatus ); + } + pHddStaCtx->ibss_sta_generation++; + memset(&staInfo, 0, sizeof(staInfo)); + staInfo.filled = 0; + staInfo.generation = pHddStaCtx->ibss_sta_generation; + + cfg80211_new_sta(pAdapter->dev, + (const u8 *)pRoamInfo->peerMac, + &staInfo, GFP_KERNEL); + + if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_TKIP == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_AES == pHddStaCtx->ibss_enc_key.encType ) + { + pHddStaCtx->ibss_enc_key.keyDirection = eSIR_TX_RX; + memcpy(&pHddStaCtx->ibss_enc_key.peerMac, + pRoamInfo->peerMac, VOS_MAC_ADDR_SIZE); + + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_INFO_HIGH, "New peer joined set PTK encType=%d", + pHddStaCtx->ibss_enc_key.encType); + + vosStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &pHddStaCtx->ibss_enc_key, &roamId ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", + __func__, vosStatus); + return VOS_STATUS_E_FAILURE; + } + } + netif_carrier_on(pAdapter->dev); + netif_tx_start_all_queues(pAdapter->dev); + break; + } + + case eCSR_ROAM_RESULT_IBSS_CONNECT: + { + + roamIbssConnectHandler( pAdapter, pRoamInfo ); + + break; + } + case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED: + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (!roamRemoveIbssStation(pAdapter, pRoamInfo->staId)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "IBSS peer departed by cannot find peer in our registration table with TL" ); + } + + pr_info ( "IBSS Peer Departed from SME " + "with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId), + pRoamInfo->staId ); + + hdd_roamDeregisterSTA( pAdapter, pRoamInfo->staId ); + + pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL; + pHddStaCtx->ibss_sta_generation++; + + cfg80211_del_sta(pAdapter->dev, + (const u8 *)&pRoamInfo->peerMac, + GFP_KERNEL); + break; + } + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME"); + // Stop only when we are inactive + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_NotConnected); + + // Send the bssid address to the wext. + hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo); + // clean up data path + hdd_disconnect_tx_rx(pAdapter); + break; + } + default: + break; + + } + + return( eHAL_STATUS_SUCCESS ); +} + +#ifdef FEATURE_WLAN_TDLS +/**============================================================================ + * + @brief hdd_roamRegisterTDLSSTA() - Construct the staDesc and register with + TL the new STA. This is called as part of ADD_STA in the TDLS setup + Return: VOS_STATUS + + ===========================================================================*/ +VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter, + tANI_U8 *peerMac, tANI_U16 staId, tANI_U8 ucastSig) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + eCsrEncryptionType connectedCipherAlgo = eCSR_ENCRYPT_TYPE_UNKNOWN; + v_BOOL_t fConnected = FALSE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if (!fConnected) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s not connected. ignored", __func__); + return VOS_FALSE; + } + + /* + * TDLS sta in BSS should be set as STA type TDLS and STA MAC should + * be peer MAC, here we are working on direct Link + */ + staDesc.ucSTAId = staId ; + + staDesc.wSTAType = WLAN_STA_TDLS ; + + vos_mem_copy( staDesc.vSTAMACAddress.bytes, peerMac, + sizeof(tSirMacAddr) ); + + vos_mem_copy(staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 ); + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + /* set the QoS field appropriately ..*/ + (hdd_wmm_is_active(pAdapter)) ? (staDesc.ucQosEnabled = 1) + : (staDesc.ucQosEnabled = 0) ; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register \ + TL QoS_enabled=%d", staDesc.ucQosEnabled ); + + staDesc.ucProtectedFrame = (connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE) ; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame ); + + /* + * UMA is ready we inform TL to do frame translation. + */ + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + + /* Initialize signatures and state */ + staDesc.ucUcastSig = ucastSig ; + + /* tdls Direct Link do not need bcastSig */ + staDesc.ucBcastSig = 0 ; + +#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK + if(staDesc.ucProtectedFrame) + staDesc.ucIsReplayCheckValid = VOS_TRUE; + else + staDesc.ucIsReplayCheckValid = VOS_FALSE; +#endif + + staDesc.ucInitState = WLANTL_STA_CONNECTED ; + + /* Register the Station with TL... */ + /* Incase Micro controller data path offload enabled, + * All the traffic routed to WLAN host driver, do not need to + * route IPA. It should be routed kernel network stack */ +#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + if (hdd_ipa_is_enabled(pHddCtx)) + vosStatus = WLANTL_RegisterSTAClient( pVosContext, + hdd_ipa_process_rxt, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, 0 ); + else +#endif + vosStatus = WLANTL_RegisterSTAClient( pVosContext, + hdd_rx_packet_cbk, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, 0 ); + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_RegisterSTAClient() failed to register. " + "Status= %d [0x%08X]", __func__, vosStatus, vosStatus ); + return vosStatus; + } + + if ( cfg_param->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)) ) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + cfg_param->trafficMntrTmrForSplitScan); + } + return( vosStatus ); +} + +static VOS_STATUS hdd_roamDeregisterTDLSSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus; + vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + __func__, staId, vosStatus, vosStatus ); + } + return( vosStatus ); +} + + +/* + * HDD interface between SME and TL to ensure TDLS client registration with + * TL in case of new TDLS client is added and deregistration at the time + * TDLS client is deleted. + */ + +eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); +#ifdef CONFIG_TDLS_IMPLICIT + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); +#endif + tSmeTdlsPeerStateParams smeTdlsPeerStateParams; + eHalStatus status = eHAL_STATUS_FAILURE ; + tANI_U8 staIdx; + hddTdlsPeer_t *curr_peer; + tANI_U32 reason; + +#ifdef WLAN_FEATURE_TDLS_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR), + roamResult == eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND" : + roamResult == eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND? "DEL_ALL_TDLS_PEER_IND" : + roamResult == eCSR_ROAM_RESULT_UPDATE_TDLS_PEER? "UPDATE_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP? "LINK_ESTABLISH_REQ_RSP" : + roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER? "TDLS_SHOULD_DISCOVER" : + roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN? "TDLS_SHOULD_TEARDOWN" : + roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED? "TDLS_SHOULD_PEER_DISCONNECTED" : + "UNKNOWN", + pRoamInfo->staId, + MAC_ADDR_ARRAY(pRoamInfo->peerMac)) ; +#endif + +#ifdef CONFIG_TDLS_IMPLICIT + if (!pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS ctx is null, ignore roamResult (%d)", + __func__, roamResult); + return status; + } +#endif + + switch( roamResult ) + { + case eCSR_ROAM_RESULT_ADD_TDLS_PEER: + { + if(eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("%s: Add Sta is failed. %d"),__func__, pRoamInfo->statusCode); + } + else + { + + /* check if there is available index for this new TDLS STA */ + for ( staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++ ) + { + if (0 == pHddCtx->tdlsConnInfo[staIdx].staId ) + { + pHddCtx->tdlsConnInfo[staIdx].sessionId = pRoamInfo->sessionId; + pHddCtx->tdlsConnInfo[staIdx].staId = pRoamInfo->staId; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("TDLS: STA IDX at %d is %d " + "of mac " MAC_ADDRESS_STR), + staIdx, pHddCtx->tdlsConnInfo[staIdx].staId, + MAC_ADDR_ARRAY(pRoamInfo->peerMac)); + + vos_copy_macaddr(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + (v_MACADDR_t *)pRoamInfo->peerMac) ; + status = eHAL_STATUS_SUCCESS ; + break ; + } + } + if (staIdx < pHddCtx->max_num_tdls_sta) + { + if (-1 == wlan_hdd_tdls_set_sta_id(pAdapter, pRoamInfo->peerMac, pRoamInfo->staId)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan_hdd_tdls_set_sta_id() failed"); + return VOS_FALSE; + } + + (WLAN_HDD_GET_CTX(pAdapter))->sta_to_adapter[pRoamInfo->staId] = pAdapter; + /* store the ucast signature , if required for further reference. */ + + wlan_hdd_tdls_set_signature( pAdapter, pRoamInfo->peerMac, pRoamInfo->ucastSig ); + } + else + { + status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: no available slot in conn_info. staId %d cannot be stored", __func__, pRoamInfo->staId); + } + pAdapter->tdlsAddStaStatus = status; + } + complete(&pAdapter->tdls_add_station_comp); + break ; + } + case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER: + { + if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Add Sta is failed. %d", __func__, pRoamInfo->statusCode); + } + /* store the ucast signature which will be used later when + * registering to TL + */ + pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode; + complete(&pAdapter->tdls_add_station_comp); + break; + } + case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP: + { + if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Link Establish Request failed. %d", __func__, pRoamInfo->statusCode); + } + complete(&pAdapter->tdls_link_establish_req_comp); + break; + } + case eCSR_ROAM_RESULT_DELETE_TDLS_PEER: + { + for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) + { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) && + pRoamInfo->staId == pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("HDD: del STA IDX = %x"), pRoamInfo->staId) ; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); + if (NULL != curr_peer && TDLS_IS_CONNECTED(curr_peer)) + { + hdd_roamDeregisterTDLSSTA ( pAdapter, pRoamInfo->staId ); + wlan_hdd_tdls_decrement_peer_count(pAdapter); + } + wlan_hdd_tdls_reset_peer(pAdapter, pRoamInfo->peerMac); + + pHddCtx->tdlsConnInfo[staIdx].staId = 0 ; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + wlan_hdd_tdls_check_bmps(pAdapter); + status = eHAL_STATUS_SUCCESS ; + break ; + } + } + complete(&pAdapter->tdls_del_station_comp); + } + break ; + case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND: + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Sending teardown to supplicant with reason code %u", + __func__, pRoamInfo->reasonCode); + +#ifdef CONFIG_TDLS_IMPLICIT + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); + wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, pRoamInfo->reasonCode); +#endif + status = eHAL_STATUS_SUCCESS ; + break ; + } + case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND: + { + /* 0 staIdx is assigned to AP we dont want to touch that */ + for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) + { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) && + pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("hdd_tdlsStatusUpdate: staIdx %d " MAC_ADDRESS_STR), + pHddCtx->tdlsConnInfo[staIdx].staId, + MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes)); + wlan_hdd_tdls_reset_peer(pAdapter, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + hdd_roamDeregisterTDLSSTA ( pAdapter, pHddCtx->tdlsConnInfo[staIdx].staId ); + vos_mem_zero(&smeTdlsPeerStateParams, + sizeof(smeTdlsPeerStateParams)); + smeTdlsPeerStateParams.vdevId = + pHddCtx->tdlsConnInfo[staIdx].sessionId; + vos_mem_copy(&smeTdlsPeerStateParams.peerMacAddr, + &pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes, + VOS_MAC_ADDR_SIZE); + smeTdlsPeerStateParams.peerState = + eSME_TDLS_PEER_STATE_TEARDOWN; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("hdd_tdlsStatusUpdate: calling sme_UpdateTdlsPeerState for staIdx %d " MAC_ADDRESS_STR), + pHddCtx->tdlsConnInfo[staIdx].staId, + MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes)); + status = sme_UpdateTdlsPeerState(pHddCtx->hHal, + &smeTdlsPeerStateParams); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_UpdateTdlsPeerState failed for " + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes)); + } + wlan_hdd_tdls_decrement_peer_count(pAdapter); + + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + pHddCtx->tdlsConnInfo[staIdx].staId = 0 ; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + + status = eHAL_STATUS_SUCCESS ; + } + } + wlan_hdd_tdls_check_bmps(pAdapter); + break ; + } + case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER: + { +#ifdef CONFIG_TDLS_IMPLICIT + /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */ + if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) || + (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"), + pHddCtx->concurrency_mode, + pHddCtx->no_of_active_sessions[VOS_STA_MODE]); + status = eHAL_STATUS_FAILURE; + break; + } + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, pRoamInfo->peerMac); + if (!curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer null", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + if (eTDLS_LINK_CONNECTED == curr_peer->link_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS link status is connected, ignore SHOULD_DISCOVER", __func__); + } + else + { + /* if external control is enabled then initiate TDLS + * only if forced peer is set otherwise ignore + * Should Discover trigger from fw + */ + if (pHddCtx->cfg_ini->fTDLSExternalControl && + (FALSE == curr_peer->isForcedPeer)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER")); + status = eHAL_STATUS_SUCCESS; + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"), + pHddCtx->cfg_ini->fTDLSExternalControl, + curr_peer->isForcedPeer, + pRoamInfo->reasonCode); + } + wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer); + } + status = eHAL_STATUS_SUCCESS; + } +#else + status = eHAL_STATUS_SUCCESS; +#endif + break ; + } + + case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN: + { +#ifdef CONFIG_TDLS_IMPLICIT + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); + if (!curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer null", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + if (eTDLS_LINK_CONNECTED == curr_peer->link_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Received SHOULD_TEARDOWN for peer " + MAC_ADDRESS_STR " staId: %d, reason: %d"), + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + pRoamInfo->staId, + pRoamInfo->reasonCode); + + if (pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_RSSI || + pRoamInfo->reasonCode == + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) + { + reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE; + } + else + reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON; + + wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter, + curr_peer, + reason); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"), + pRoamInfo->reasonCode); + } + status = eHAL_STATUS_SUCCESS; + } +#else + status = eHAL_STATUS_SUCCESS; +#endif + break ; + } + + case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED: + { +#ifdef CONFIG_TDLS_IMPLICIT + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE); + if (!curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer null", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + if (eTDLS_LINK_CONNECTED == curr_peer->link_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Received SHOULD_PEER_DISCONNECTED for peer " + MAC_ADDRESS_STR " staId: %d, reason: %d"), + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + pRoamInfo->staId, + pRoamInfo->reasonCode); + + if (pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_RSSI || + pRoamInfo->reasonCode == + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT || + pRoamInfo->reasonCode == + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) + { + reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE; + } + else + reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON; + + wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter, + curr_peer, + reason); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"), + pRoamInfo->reasonCode); + } + status = eHAL_STATUS_SUCCESS; + } +#else + status = eHAL_STATUS_SUCCESS; +#endif + break ; + } + default: + { + break ; + } + } + + return status ; +} +#endif + +static void iw_full_power_cbfn (void *pContext, eHalStatus status) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_context_t *pHddCtx = NULL; + int ret; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pAdapter [%p]", + __func__, pAdapter); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid (%d)", __func__, ret); + return; + } + + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), NULL, NULL); + } +} + +eHalStatus +hdd_smeRoamCallback(void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_wext_state_t *pWextState = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = NULL; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "CSR Callback: status= %d result= %d roamID=%d", + roamStatus, roamResult, roamId ); + + /* Sanity check */ + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter or adapter has invalid magic"); + return eHAL_STATUS_FAILURE; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + switch( roamStatus ) + { + case eCSR_ROAM_SESSION_OPENED: + if(pAdapter != NULL) + { + set_bit(SME_SESSION_OPENED, &pAdapter->event_flags); + complete(&pAdapter->session_open_comp_var); + } + break; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* We did pre-auth,then we attempted a 11r or ese reassoc. + * reassoc failed due to failure, timeout, reject from ap + * in any case tell the OS, our carrier is off and mark + * interface down */ + case eCSR_ROAM_FT_REASSOC_FAILED: + hddLog(LOGE, FL("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"), + roamStatus, roamResult, pAdapter->sessionId); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */ + if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set == TRUE) { + (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE; + } + pHddStaCtx->ft_carrier_on = FALSE; + pHddStaCtx->hdd_ReassocScenario = FALSE; + hddLog(LOG1, + FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"), + pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId); + break; + + case eCSR_ROAM_FT_START: + // When we roam for ESE and 11r, we dont want the + // OS to be informed that the link is down. So mark + // the link ready for ft_start. After this the + // eCSR_ROAM_SHOULD_ROAM will be received. + // Where in we will not mark the link down + // Also we want to stop tx at this point when we will be + // doing disassoc at this time. This saves 30-60 msec + // after reassoc. + { + struct net_device *dev = pAdapter->dev; + netif_tx_disable(dev); + /* + * Deregister for this STA with TL with the objective to flush + * all the packets for this STA from wmm_tx_queue. If not done here, + * we would run into a race condition (CR390567) wherein TX + * thread would schedule packets from wmm_tx_queue AFTER peer STA has + * been deleted. And, these packets get assigned with a STA idx of + * self-sta (since the peer STA has been deleted) and get transmitted + * on the new channel before the reassoc request. Since there will be + * no ACK on the new channel, each packet gets retransmitted which + * takes several seconds before the transmission of reassoc request. + * This leads to reassoc-timeout and roam failure. + */ + status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] ); + if ( !VOS_IS_STATUS_SUCCESS(status ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"), + pHddStaCtx->conn_info.staId[0], status, status ); + halStatus = eHAL_STATUS_FAILURE; + } + } + pHddStaCtx->ft_carrier_on = TRUE; + pHddStaCtx->hdd_ReassocScenario = VOS_TRUE; + hddLog(LOG1, + FL("hdd_ReassocScenario set to: %d due to eCSR_ROAM_FT_START, session: %d"), + pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId); + break; +#endif + + case eCSR_ROAM_SHOULD_ROAM: + // Dont need to do anything + { + struct net_device *dev = pAdapter->dev; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + // notify apps that we can't pass traffic anymore + netif_tx_disable(dev); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pHddStaCtx->ft_carrier_on == FALSE) + { +#endif + netif_carrier_off(dev); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + } +#endif + +#if !(defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)) + //We should clear all sta register with TL, for now, only one. + status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] ); + if ( !VOS_IS_STATUS_SUCCESS(status ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"), + pHddStaCtx->conn_info.staId[0], status, status ); + halStatus = eHAL_STATUS_FAILURE; + } +#endif + } + break; + case eCSR_ROAM_LOSTLINK: + if(roamResult == eCSR_ROAM_RESULT_LOSTLINK) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Roaming started due to connection lost"); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + break; + } + case eCSR_ROAM_DISASSOCIATED: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_DISASSOCIATED****"); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */ + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->hdd_mcastbcast_filter_set == TRUE) + { + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) { + pHddCtx->configuredMcastBcastFilter = + pHddCtx->sus_res_mcastbcast_filter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: disassociation happening, restoring configuredMcastBcastFilter"); + hddLog(VOS_TRACE_LEVEL_INFO,"McastBcastFilter = %d", + pHddCtx->configuredMcastBcastFilter); + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: already called mcastbcast filter"); + (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE; + } +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* Call to clear any MC Addr List filter applied after + * successful connection. + */ + wlan_hdd_set_mc_addr_list(pAdapter, FALSE); +#endif + } + break; + case eCSR_ROAM_IBSS_LEAVE: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_IBSS_LEAVE****"); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + case eCSR_ROAM_ASSOCIATION_COMPLETION: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_ASSOCIATION_COMPLETION****"); + // To Do - address probable memory leak with WEP encryption upon successful association + if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) + { + //Clear saved connection information in HDD + hdd_connRemoveConnectInfo( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) ); + } + halStatus = hdd_AssociationCompletionHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pRoamInfo) + pRoamInfo->roamSynchInProgress = VOS_FALSE; +#endif + break; + case eCSR_ROAM_ASSOCIATION_FAILURE: + halStatus = hdd_AssociationCompletionHandler( pAdapter, + pRoamInfo, roamId, roamStatus, roamResult ); + break; + case eCSR_ROAM_IBSS_IND: + hdd_RoamIbssIndicationHandler( pAdapter, pRoamInfo, roamId, + roamStatus, roamResult ); + break; + + case eCSR_ROAM_CONNECT_STATUS_UPDATE: + halStatus = roamRoamConnectStatusUpdateHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + + case eCSR_ROAM_MIC_ERROR_IND: + halStatus = hdd_RoamMicErrorIndicationHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + + case eCSR_ROAM_SET_KEY_COMPLETE: + { + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + if((pHddCtx) && + (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) && + (TRUE == pHddCtx->hdd_wlan_suspended) && + (eCSR_ROAM_RESULT_NONE == roamResult)) + { + /* Send DTIM period to the FW; only if the wlan is already + in suspend. This is the case with roaming (reassoc), + DELETE_BSS_REQ zeroes out Modulated/Dynamic DTIM sent in + previous suspend_wlan. Sending SET_POWER_PARAMS_REQ + before the ENTER_BMPS_REQ ensures Listen Interval is + regained back to LI * Modulated DTIM */ + hdd_set_pwrparams(pHddCtx); + + /* At this point, device should not be in BMPS; + if due to unexpected scenario, if we are in BMPS, + then trigger Exit and Enter BMPS to take DTIM period + effective */ + if (BMPS == pmcGetPmcState(pHddCtx->hHal)) + { + hddLog( LOGE, FL("Not expected: device is already in BMPS mode, Exit & Enter BMPS again!")); + + sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_full_power_cbfn, pAdapter, + eSME_FULL_PWR_NEEDED_BY_HDD); + } + } + halStatus = hdd_RoamSetKeyCompleteHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) { + pHddStaCtx->hdd_ReassocScenario = VOS_FALSE; + hddLog(LOG1, + FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"), + pHddStaCtx->hdd_ReassocScenario, + pAdapter->sessionId); + } + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pRoamInfo != NULL) + pRoamInfo->roamSynchInProgress = VOS_FALSE; +#endif + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_ROAM_FT_RESPONSE: + hdd_SendFTEvent(pAdapter); + break; +#endif +#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + case eCSR_ROAM_PMK_NOTIFY: + if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType) + { + /* Notify the supplicant of a new candidate */ + halStatus = wlan_hdd_cfg80211_pmksa_candidate_notify(pAdapter, pRoamInfo, 1, false); + } + break; +#endif + +#ifdef FEATURE_WLAN_LFR_METRICS + case eCSR_ROAM_PREAUTH_INIT_NOTIFY: + /* This event is to notify pre-auth initiation */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter, pRoamInfo)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_PREAUTH_STATUS_SUCCESS: + /* This event will notify pre-auth completion in case of success */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter, + pRoamInfo, 1)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_PREAUTH_STATUS_FAILURE: + /* This event will notify pre-auth completion in case of failure. */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter, + pRoamInfo, 0)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_HANDOVER_SUCCESS: + /* This event is to notify handover success. + It will be only invoked on success */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_handover(pAdapter, pRoamInfo)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; +#endif + + case eCSR_ROAM_INDICATE_MGMT_FRAME: + hdd_indicateMgmtFrame( pAdapter, + pRoamInfo->nFrameLength, + pRoamInfo->pbFrames, + pRoamInfo->frameType, + pRoamInfo->rxChan, + pRoamInfo->rxRssi ); + break; + case eCSR_ROAM_REMAIN_CHAN_READY: + hdd_remainChanReadyHandler( pAdapter ); + break; + case eCSR_ROAM_SEND_ACTION_CNF: + hdd_sendActionCnf( pAdapter, + (roamResult == eCSR_ROAM_RESULT_NONE) ? TRUE : FALSE ); + break; +#ifdef FEATURE_WLAN_TDLS + case eCSR_ROAM_TDLS_STATUS_UPDATE: + halStatus = hdd_RoamTdlsStatusUpdateHandler( pAdapter, pRoamInfo, + roamId, roamStatus, roamResult ); + break ; + case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND: + wlan_hdd_tdls_mgmt_completion_callback(pAdapter, pRoamInfo->reasonCode); + break; +#endif +#ifdef WLAN_FEATURE_11W + case eCSR_ROAM_UNPROT_MGMT_FRAME_IND: + hdd_indicateUnprotMgmtFrame(pAdapter, pRoamInfo->nFrameLength, + pRoamInfo->pbFrames, + pRoamInfo->frameType); + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eCSR_ROAM_TSM_IE_IND: + hdd_indicateTsmIe(pAdapter, pRoamInfo->tsmIe.tsid, + pRoamInfo->tsmIe.state, pRoamInfo->tsmIe.msmt_interval); + break; + + case eCSR_ROAM_CCKM_PREAUTH_NOTIFY: + { + if (eCSR_AUTH_TYPE_CCKM_WPA == pHddStaCtx->conn_info.authType || + eCSR_AUTH_TYPE_CCKM_RSN == pHddStaCtx->conn_info.authType) + { + hdd_indicateCckmPreAuth(pAdapter, pRoamInfo); + } + break; + } + + case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND: + { + hdd_indicateEseAdjApRepInd(pAdapter, pRoamInfo); + break; + } + + case eCSR_ROAM_ESE_BCN_REPORT_IND: + { + hdd_indicateEseBcnReportInd(pAdapter, pRoamInfo); + break; + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef NL80211_KEY_REPLAY_CTR_LEN /* kernel supports key mgmt offload */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case eCSR_ROAM_AUTHORIZED_EVENT: + { +#ifdef NL80211_KEY_LEN_PTK_KCK + struct cfg80211_auth_params auth_params; + if (pRoamInfo != NULL) { + auth_params.ptk_kck = pRoamInfo->kck; + auth_params.ptk_kek = pRoamInfo->kek; + auth_params.key_replay_ctr = pRoamInfo->replay_ctr; + auth_params.status = NL80211_AUTHORIZED; + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + pRoamInfo->replay_ctr,NL80211_KEY_REPLAY_CTR_LEN); + hddLog(VOS_TRACE_LEVEL_DEBUG, + "LFR3:cfg80211_key_mgmt_auth NL80211_AUTHORIZED"); + cfg80211_key_mgmt_auth(pAdapter->dev, &auth_params, GFP_KERNEL); + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LFR3:pRoamInfo is NULL. Not sending Authorized Event"); + halStatus = eHAL_STATUS_FAILURE; + } + break; +#else + v_U8_t keyReplayCtr [NL80211_KEY_REPLAY_CTR_LEN]; + vos_mem_zero(keyReplayCtr, sizeof(keyReplayCtr)); + hddLog(VOS_TRACE_LEVEL_DEBUG, + "cfg80211_authorization_event NL80211_AUTHORIZED"); + cfg80211_authorization_event(pAdapter->dev, NL80211_AUTHORIZED, + keyReplayCtr, GFP_KERNEL); + break; +#endif + } +#endif +#endif + default: + break; + } + return( halStatus ); +} +eCsrAuthType hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4]) +{ + eCsrAuthType auth_type; + // is the auth type supported? + if ( memcmp(auth_suite , ccpRSNOui01, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN; + } else + if (memcmp(auth_suite , ccpRSNOui02, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_PSK; + } else +#ifdef WLAN_FEATURE_VOWIFI_11R + if (memcmp(auth_suite , ccpRSNOui04, 4) == 0) + { + // Check for 11r FT Authentication with PSK + auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK; + } else + if (memcmp(auth_suite , ccpRSNOui03, 4) == 0) + { + // Check for 11R FT Authentication with 802.1X + auth_type = eCSR_AUTH_TYPE_FT_RSN; + } else +#endif +#ifdef FEATURE_WLAN_ESE + if (memcmp(auth_suite , ccpRSNOui06, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_CCKM_RSN; + } else +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + if (memcmp(auth_suite , ccpRSNOui07, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } else + if (memcmp(auth_suite , ccpRSNOui08, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } else +#endif + { + auth_type = eCSR_AUTH_TYPE_UNKNOWN; + } + return auth_type; +} + +eCsrAuthType +hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4]) +{ + eCsrAuthType auth_type; + // is the auth type supported? + if ( memcmp(auth_suite , ccpWpaOui01, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_WPA; + } else + if (memcmp(auth_suite , ccpWpaOui02, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_WPA_PSK; + } else +#ifdef FEATURE_WLAN_ESE + if (memcmp(auth_suite , ccpWpaOui06, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_CCKM_WPA; + } else +#endif /* FEATURE_WLAN_ESE */ + { + auth_type = eCSR_AUTH_TYPE_UNKNOWN; + } + hddLog(LOG1, FL("auth_type: %d"), auth_type); + return auth_type; +} + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]) +{ + eCsrEncryptionType cipher_type; + // is the cipher type supported? + if ( memcmp(cipher_suite , ccpRSNOui04, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_AES; + } + else if (memcmp(cipher_suite , ccpRSNOui02, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_TKIP; + } + else if (memcmp(cipher_suite , ccpRSNOui00, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_NONE; + } + else if (memcmp(cipher_suite , ccpRSNOui01, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + else if (memcmp(cipher_suite , ccpRSNOui05, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + else + { + cipher_type = eCSR_ENCRYPT_TYPE_FAILED; + } + hddLog(LOG1, FL("cipher_type: %d"), cipher_type); + return cipher_type; +} +/* To find if the MAC address is NULL */ +static tANI_U8 hdd_IsMACAddrNULL (tANI_U8 *macAddr, tANI_U8 length) +{ + int i; + for (i = 0; i < length; i++) + { + if (0x00 != (macAddr[i])) + { + return FALSE; + } + } + return TRUE; +} /****** end hdd_IsMACAddrNULL() ******/ + +eCsrEncryptionType +hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4]) +{ + eCsrEncryptionType cipher_type; + // is the cipher type supported? + if ( memcmp(cipher_suite , ccpWpaOui04, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_AES; + } else + if (memcmp(cipher_suite , ccpWpaOui02, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_TKIP; + } else + if (memcmp(cipher_suite , ccpWpaOui00, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_NONE; + } else + if (memcmp(cipher_suite , ccpWpaOui01, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } else + if (memcmp(cipher_suite , ccpWpaOui05, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } else + { + cipher_type = eCSR_ENCRYPT_TYPE_FAILED; + } + hddLog(LOG1, FL("cipher_type: %d"), cipher_type); + return cipher_type; +} + +static tANI_S32 hdd_ProcessGENIE(hdd_adapter_t *pAdapter, + struct ether_addr *pBssid, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, +#ifdef WLAN_FEATURE_11W + u_int8_t *pMfpRequired, + u_int8_t *pMfpCapable, +#endif + u_int16_t gen_ie_len, + u_int8_t *gen_ie) +{ + tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus result; + tDot11fIERSN dot11RSNIE; + tDot11fIEWPA dot11WPAIE; + tANI_U32 i; + tANI_U8 *pRsnIe; + tANI_U16 RSNIeLen; + tPmkidCacheInfo PMKIDCache[4]; // Local transfer memory + v_BOOL_t updatePMKCache = FALSE; + + /* Clear struct of tDot11fIERSN and tDot11fIEWPA specifically setting present + flag to 0 */ + memset( &dot11WPAIE, 0 , sizeof(tDot11fIEWPA) ); + memset( &dot11RSNIE, 0 , sizeof(tDot11fIERSN) ); + + // Validity checks + if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) || + (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) ) + { + hddLog(LOGE, "%s: Invalid DOT11F IE Length passed :%d", + __func__, gen_ie_len); + return -EINVAL; + } + // Type check + if ( gen_ie[0] == DOT11F_EID_RSN) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) ) + { + hddLog(LOGE, "%s: Invalid DOT11F RSN IE length :%d", + __func__, gen_ie_len); + return -EINVAL; + } + // Skip past the EID byte and length byte + pRsnIe = gen_ie + 2; + RSNIeLen = gen_ie_len - 2; + // Unpack the RSN IE + dot11fUnpackIeRSN((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11RSNIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"), + __func__, dot11RSNIE.pwise_cipher_suite_count ); + hddLog(LOG1, FL("%s: authentication suite count: %d"), + __func__, dot11RSNIE.akm_suite_count); + /*Here we have followed the apple base code, + but probably I suspect we can do something different*/ + //dot11RSNIE.akm_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]); + //dot11RSNIE.pwise_cipher_suite_count + *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]); + //dot11RSNIE.gp_cipher_suite_count + *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite); +#ifdef WLAN_FEATURE_11W + *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1 ; + *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1 ; +#endif + // Set the PMKSA ID Cache for this interface + for (i=0; iether_addr_octet , 6)) + { + hddLog(LOGE, "%s: Invalid MAC adrr", __func__); + break; + } + updatePMKCache = TRUE; + // For right now, I assume setASSOCIATE() has passed in the bssid. + vos_mem_copy(PMKIDCache[i].BSSID, + pBssid, ETHER_ADDR_LEN); + vos_mem_copy(PMKIDCache[i].PMKID, + dot11RSNIE.pmkid[i], + CSR_RSN_PMKID_SIZE); + } + + if (updatePMKCache) + { + // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache + hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with cache entry %d."), + __func__, i ); + // Finally set the PMKSA ID Cache in CSR + result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId, + PMKIDCache, + dot11RSNIE.pmkid_count, + FALSE); + } + } + else if (gen_ie[0] == DOT11F_EID_WPA) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) + { + hddLog(LOGE, "%s: Invalid DOT11F WPA IE length :%d", + __func__, gen_ie_len); + return -EINVAL; + } + // Skip past the EID byte and length byte - and four byte WiFi OUI + pRsnIe = gen_ie + 2 + 4; + RSNIeLen = gen_ie_len - (2 + 4); + // Unpack the WPA IE + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11WPAIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"), + __func__, dot11WPAIE.unicast_cipher_count ); + hddLog(LOG1, FL("%s: WPA authentication suite count: %d"), + __func__, dot11WPAIE.auth_suite_count); + //dot11WPAIE.auth_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]); + //dot11WPAIE.unicast_cipher_count + *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]); + //dot11WPAIE.unicast_cipher_count + *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + } + else + { + hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]); + return -EINVAL; + } + return 0; +} +int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + v_U32_t status = 0; + eCsrEncryptionType RSNEncryptType; + eCsrEncryptionType mcRSNEncryptType; +#ifdef WLAN_FEATURE_11W + u_int8_t RSNMfpRequired; + u_int8_t RSNMfpCapable; +#endif + struct ether_addr bSsid; // MAC address of assoc peer + // MAC address of assoc peer + // But, this routine is only called when we are NOT associated. + vos_mem_copy(bSsid.ether_addr_octet, + pWextState->roamProfile.BSSIDs.bssid, + sizeof(bSsid.ether_addr_octet)); + if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) + { + //continue + } + else + { + return 0; + } + // The actual processing may eventually be more extensive than this. + // Right now, just consume any PMKIDs that are sent in by the app. + status = hdd_ProcessGENIE(pAdapter, + &bSsid, // MAC address of assoc peer + &RSNEncryptType, + &mcRSNEncryptType, + RSNAuthType, +#ifdef WLAN_FEATURE_11W + &RSNMfpRequired, + &RSNMfpCapable, +#endif + pWextState->WPARSNIE[1]+2, + pWextState->WPARSNIE); + if (status == 0) + { + // Now copy over all the security attributes you have parsed out + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + + pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; // Use the cipher type in the RSN IE + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = mcRSNEncryptType; + + if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && + ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) || + (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) + { + /*For wpa none supplicant sends the WPA IE with unicast cipher as + eCSR_ENCRYPT_TYPE_NONE ,where as the multicast cipher as + either AES/TKIP based on group cipher configuration + mentioned in the wpa_supplicant.conf.*/ + + /*Set the unicast cipher same as multicast cipher*/ + pWextState->roamProfile.EncryptionType.encryptionType[0] + = mcRSNEncryptType; + } + +#ifdef WLAN_FEATURE_11W + pWextState->roamProfile.MFPRequired = RSNMfpRequired; + pWextState->roamProfile.MFPCapable = RSNMfpCapable; +#endif + hddLog( LOG1, "%s: CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d", __func__, *RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + return 0; +} +int hdd_set_csr_auth_type ( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + ENTER(); + + pRoamProfile->AuthType.numEntries = 1; + hddLog( LOG1, "%s: pHddStaCtx->conn_info.authType = %d", __func__, pHddStaCtx->conn_info.authType); + + switch( pHddStaCtx->conn_info.authType) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: + case eCSR_AUTH_TYPE_CCKM_RSN: +#endif + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) { + + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM ; + } else + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) { + +#ifdef FEATURE_WLAN_ESE + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + hddLog( LOG1, "%s: set authType to CCKM WPA. AKM also 802.1X.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA; + } else + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA)) { + hddLog( LOG1, "%s: Last chance to set authType to CCKM WPA.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA; + } else +#endif + if((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA; + } else + if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_PSK; + } else { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_NONE; + } + } + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) { +#ifdef FEATURE_WLAN_ESE + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + hddLog( LOG1, "%s: set authType to CCKM RSN. AKM also 802.1X.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN; + } else + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN)) { + hddLog( LOG1, "%s: Last chance to set authType to CCKM RSN.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN; + } else +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN; + }else + if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK)) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN_PSK; + } else +#endif + +#ifdef WLAN_FEATURE_11W + if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } else + if (RSNAuthType == eCSR_AUTH_TYPE_RSN_8021X_SHA256) { + pRoamProfile->AuthType.authType[0] = + eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } else +#endif + + if( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN; + } else + if ( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK; + } else { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN; + } + } + break; + + case eCSR_AUTH_TYPE_SHARED_KEY: + + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; + break; + default: + +#ifdef FEATURE_WLAN_ESE + hddLog( LOG1, "%s: In default, unknown auth type.", __func__); +#endif /* FEATURE_WLAN_ESE */ + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN; + break; + } + + hddLog( LOG1, "%s Set roam Authtype to %d", + __func__, pWextState->roamProfile.AuthType.authType[0]); + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief iw_set_essid() - + This function sets the ssid received from wpa_supplicant + to the CSR roam profile. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +int iw_set_essid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + unsigned long rc; + v_U32_t status = 0; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U32_t roamId; + tCsrRoamProfile *pRoamProfile; + eMib_dot11DesiredBssType connectedBssType; + eCsrAuthType RSNAuthType; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION && + pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) { + hddLog(LOGW, "%s device mode %d is not allowed.", + __func__, pAdapter->device_mode); + return -EINVAL; + } + + if(pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s :Counter measure is in progress", __func__); + return -EBUSY; + } + if( SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length ) + return -EINVAL; + + pRoamProfile = &pWextState->roamProfile; + if (hdd_connGetConnectedBssType(pHddStaCtx, &connectedBssType) || + (eMib_dot11DesiredBssType_independent == + pHddStaCtx->conn_info.connDot11DesiredBssType)) { + VOS_STATUS vosStatus; + + /* Need to issue a disconnect to CSR. */ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(hHal, pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + if (VOS_STATUS_SUCCESS == vosStatus) { + rc = wait_for_completion_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog( LOGE, FL("Disconnect event timed out")); + } + } + } + + /** when cfg80211 defined, wpa_supplicant wext driver uses + zero-length, null-string ssid for force disconnection. + after disconnection (if previously connected) and cleaning ssid, + driver MUST return success */ + if ( 0 == wrqu->essid.length ) { + return 0; + } + + status = hdd_wmm_get_uapsd_mask(pAdapter, + &pWextState->roamProfile.uapsd_mask); + if (VOS_STATUS_SUCCESS != status) + { + pWextState->roamProfile.uapsd_mask = 0; + } + pWextState->roamProfile.SSIDs.numOfSSIDs = 1; + + pWextState->roamProfile.SSIDs.SSIDList->SSID.length = wrqu->essid.length; + + vos_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId, sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId)); + vos_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId), extra, wrqu->essid.length); + if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion || + IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion ) { + + //set gen ie + hdd_SetGENIEToCsr(pAdapter, &RSNAuthType); + + //set auth + hdd_set_csr_auth_type(pAdapter, RSNAuthType); + } +#ifdef FEATURE_WLAN_WAPI + hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__); + if (pAdapter->wapi_info.nWapiMode) + { + switch (pAdapter->wapi_info.wapiAuthMode) + { + case WAPI_AUTH_MODE_PSK: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__, pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + break; + } + case WAPI_AUTH_MODE_CERT: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__, pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + break; + } + } // End of switch + if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK || + pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) + { + hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__); + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + } + } +#endif /* FEATURE_WLAN_WAPI */ + /* if previous genIE is not NULL, update AssocIE */ + if (0 != pWextState->genIE.length) + { + memset( &pWextState->assocAddIE, 0, sizeof(pWextState->assocAddIE) ); + memcpy( pWextState->assocAddIE.addIEdata, pWextState->genIE.addIEdata, + pWextState->genIE.length); + pWextState->assocAddIE.length = pWextState->genIE.length; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + + /* clear previous genIE after use it */ + memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) ); + } + + /* assumes it is not WPS Association by default, except when pAddIEAssoc has WPS IE */ + pWextState->roamProfile.bWPSAssociation = FALSE; + + if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc, + pWextState->roamProfile.nAddIEAssocLength)) + pWextState->roamProfile.bWPSAssociation = TRUE; + + + // Disable auto BMPS entry by PMC until DHCP is done + sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), TRUE); + + pWextState->roamProfile.csrPersona = pAdapter->device_mode; + (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE; + + if ( eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType ) + { + hdd_select_cbmode(pAdapter, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->AdHocChannel5G); + } + status = sme_RoamConnect( hHal,pAdapter->sessionId, + &(pWextState->roamProfile), &roamId); + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + + EXIT(); + return status; +} + +/**--------------------------------------------------------------------------- + + \brief iw_get_essid() - + This function returns the essid to the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + ENTER(); + + if((pHddStaCtx->conn_info.connState == eConnectionState_Associated && + wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) || + ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected || + pHddStaCtx->conn_info.connState == eConnectionState_IbssDisconnected) && + wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) + { + dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length; + memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId, dwrq->length); + dwrq->flags = 1; + } else { + memset(extra, 0, dwrq->length); + dwrq->length = 0; + dwrq->flags = 0; + } + EXIT(); + return 0; +} +/**--------------------------------------------------------------------------- + + \brief iw_set_auth() - + This function sets the auth type received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_set_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile; + eCsrEncryptionType mcEncryptionType; + eCsrEncryptionType ucEncryptionType; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(wrqu->param.flags & IW_AUTH_INDEX) + { + case IW_AUTH_WPA_VERSION: + + pWextState->wpaVersion = wrqu->param.value; + + break; + + case IW_AUTH_CIPHER_PAIRWISE: + { + if(wrqu->param.value & IW_AUTH_CIPHER_NONE) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_AES; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + + if( (IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) ) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) ) + /*Dynamic WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + else + /*Static WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) { + + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) ) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + /*Dynamic WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + else + /*Static WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + + } + else { + + hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER", + __func__, wrqu->param.value); + return -EINVAL; + } + + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = ucEncryptionType; + } + break; + case IW_AUTH_CIPHER_GROUP: + { + if(wrqu->param.value & IW_AUTH_CIPHER_NONE) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_AES; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X )) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + + else + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) + { + /*Dynamic WEP keys won't work with shared keys*/ + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + else + { + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + else { + + hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER", + __func__, wrqu->param.value); + return -EINVAL; + } + + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = mcEncryptionType; + } + break; + + case IW_AUTH_80211_AUTH_ALG: + { + /*Save the auth algo here and set auth type to SME Roam profile + in the iw_set_ap_address*/ + if( wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + else if(wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY; + + else if(wrqu->param.value & IW_AUTH_ALG_LEAP) + /*Not supported*/ + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pWextState->roamProfile.AuthType.authType[0] = pHddStaCtx->conn_info.authType; + } + break; + + case IW_AUTH_KEY_MGMT: + { +#ifdef FEATURE_WLAN_ESE +#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */ + /*Check for CCKM AKM type */ + if ( wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: CCKM AKM Set %d", + __func__, wrqu->param.value); + /* Set the CCKM bit in authKeyMgmt */ + /* Right now, this breaks all ref to authKeyMgmt because our + * code doesn't realize it is a "bitfield" + */ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM; + /*Set the key management to 802.1X*/ + //pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; + pWextState->isESEConnection = eANI_BOOLEAN_TRUE; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_CCKM_RSN; + } else if ( wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) { + /*Save the key management*/ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK; + //pWextState->authKeyMgmt = wrqu->param.value; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN; + } else if (!( wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) { + pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE; //eCSR_AUTH_TYPE_WPA_NONE + /*Save the key management anyway*/ + pWextState->authKeyMgmt = wrqu->param.value; + } else { // It must be IW_AUTH_KEY_MGMT_802_1X + /*Save the key management*/ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + //pWextState->authKeyMgmt = wrqu->param.value; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN; + } +#else + /*Save the key management*/ + pWextState->authKeyMgmt = wrqu->param.value; +#endif /* FEATURE_WLAN_ESE */ + } + break; + + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if(wrqu->param.value) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure started %d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED; + } + else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure stopped=%d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED; + } + } + break; + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_WPA_ENABLED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_ROAMING_CONTROL: + case IW_AUTH_PRIVACY_INVOKED: + + default: + + hddLog(LOGW, "%s called with unsupported auth type %d", __func__, + wrqu->param.flags & IW_AUTH_INDEX); + break; + } + + EXIT(); + return 0; +} +/**--------------------------------------------------------------------------- + + \brief iw_get_auth() - + This function returns the auth type to the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_get_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t* pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile; + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(pRoamProfile->negotiatedAuthType) + { + case eCSR_AUTH_TYPE_WPA_NONE: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED; + break; + case eCSR_AUTH_TYPE_WPA: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_WPA; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: +#endif + case eCSR_AUTH_TYPE_RSN: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2; + break; + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + wrqu->param.value = IW_AUTH_ALG_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_UNKNOWN: + hddLog(LOG1,"%s called with unknown auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + hddLog(LOG1,"%s called with WPA PSK auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + hddLog(LOG1,"%s called with RSN PSK auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; + default: + hddLog(LOGE,"%s called with unknown auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; + } + if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) + { + switch(pRoamProfile->negotiatedUCEncryptionType) + { + case eCSR_ENCRYPT_TYPE_NONE: + wrqu->param.value = IW_AUTH_CIPHER_NONE; + break; + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP40; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + wrqu->param.value = IW_AUTH_CIPHER_TKIP; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP104; + break; + case eCSR_ENCRYPT_TYPE_AES: + wrqu->param.value = IW_AUTH_CIPHER_CCMP; + break; + default: + hddLog(LOG1, "%s called with unknown auth type %d ", + __func__, pRoamProfile->negotiatedUCEncryptionType); + return -EIO; + } + } + + if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) + { + switch(pRoamProfile->negotiatedMCEncryptionType) + { + case eCSR_ENCRYPT_TYPE_NONE: + wrqu->param.value = IW_AUTH_CIPHER_NONE; + break; + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP40; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + wrqu->param.value = IW_AUTH_CIPHER_TKIP; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP104; + break; + case eCSR_ENCRYPT_TYPE_AES: + wrqu->param.value = IW_AUTH_CIPHER_CCMP; + break; + default: + hddLog(LOG1, "%s called with unknown auth type %d ", + __func__, pRoamProfile->negotiatedMCEncryptionType); + return -EIO; + } + } + + hddLog(LOG1, "%s called with auth type %d", + __func__, pRoamProfile->AuthType.authType[0]); + EXIT(); + return 0; +} +/**--------------------------------------------------------------------------- + + \brief iw_set_ap_address() - + This function calls the sme_RoamConnect function to associate + to the AP with the specified BSSID received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev)); + v_U8_t *pMacAddress=NULL; + ENTER(); + pMacAddress = (v_U8_t*) wrqu->ap_addr.sa_data; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s "MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pMacAddress)); + vos_mem_copy( pHddStaCtx->conn_info.bssId, pMacAddress, sizeof( tCsrBssid )); + EXIT(); + + return 0; +} +/**--------------------------------------------------------------------------- + + \brief iw_get_ap_address() - + This function returns the BSSID to the wpa_supplicant + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev)); + + ENTER(); + + if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) || + (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)) + { + memcpy(wrqu->ap_addr.sa_data,pHddStaCtx->conn_info.bssId,ETH_ALEN); + } + else + { + memset(wrqu->ap_addr.sa_data,0,sizeof(wrqu->ap_addr.sa_data)); + } + EXIT(); + return 0; +} + +#ifdef WLAN_FEATURE_11W +/**--------------------------------------------------------------------------- + + \brief hdd_indicateUnprotMgmtFrame - + This function forwards the unprotected management frame to the supplicant + \param - pAdapter - Pointer to HDD adapter + - nFrameLength - Length of the unprotected frame being passed + - pbFrames - Pointer to the frame buffer + - frameType - 802.11 frame type + \return - nothing + + --------------------------------------------------------------------------*/ +void hdd_indicateUnprotMgmtFrame( hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ) +{ + tANI_U8 type = 0; + tANI_U8 subType = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d", + __func__, frameType, nFrameLength); + + /* Sanity Checks */ + if (NULL == pAdapter) + { + hddLog( LOGE, FL("pAdapter is NULL")); + return; + } + + if (NULL == pAdapter->dev) + { + hddLog( LOGE, FL("pAdapter->dev is NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog( LOGE, FL("pAdapter has invalid magic")); + return; + } + + if( !nFrameLength ) + { + hddLog( LOGE, FL("Frame Length is Invalid ZERO")); + return; + } + + if (NULL == pbFrames) { + hddLog( LOGE, FL("pbFrames is NULL")); + return; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); + + /* Get pAdapter from Destination mac address of the frame */ + if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) + { + cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames, nFrameLength); + pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++; + } + else if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DEAUTH) + { + cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames, nFrameLength); + pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++; + } + else + { + hddLog( LOGE, FL("Frame type %d and subtype %d are not valid"), type, subType); + return; + } +} +#endif + +#if defined (FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void hdd_indicateTsmIe(hdd_adapter_t *pAdapter, tANI_U8 tid, + tANI_U8 state, + tANI_U16 measInterval ) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + int nBytes = 0; + + if (NULL == pAdapter) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, "TSM Ind tid(%d) state(%d) MeasInt(%d)", + tid, state, measInterval); + + nBytes = snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d",tid,state,measInterval); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateCckmPreAuth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */ + hddLog(VOS_TRACE_LEVEL_INFO, + "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR" %d:%d", + MAC_ADDR_ARRAY(pRoamInfo->bssid), + pRoamInfo->timestamp[0], + pRoamInfo->timestamp[1]); + + nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY="); + pos += nBytes; + freeBytes -= nBytes; + + vos_mem_copy(pos, pRoamInfo->bssid, VOS_MAC_ADDR_SIZE); + pos += VOS_MAC_ADDR_SIZE; + freeBytes -= VOS_MAC_ADDR_SIZE; + + nBytes = snprintf(pos, freeBytes, " %u:%u", + pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]); + freeBytes -= nBytes; + + wrqu.data.pointer = buf; + wrqu.data.length = (IW_CUSTOM_MAX - freeBytes); + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateEseAdjApRepInd(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + int nBytes = 0; + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay); + + nBytes = snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter, + const tANI_U16 measurementToken, + const tANI_BOOLEAN flag, + const tANI_U8 numBss) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("CCXBCNREP=%d %d %d"), measurementToken, flag, + numBss); + + nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken, + flag, numBss); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + + +static void hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter, + const tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + tANI_U8 i = 0, len = 0; + tANI_U8 tot_bcn_ieLen = 0; /* total size of the beacon report data */ + tANI_U8 lastSent = 0, sendBss = 0; + int bcnRepFieldSize = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].bcnReportFields); + tANI_U8 ieLenByte = 1; + /* CCXBCNREP=meas_tokflagno_of_bsstot_bcn_ie_len = 18 bytes */ +#define ESEBCNREPHEADER_LEN (18) + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + /* Custom event can pass maximum of 256 bytes of data, + based on the IE len we need to identify how many BSS info can + be filled in to custom event data */ + /* + meas_tokflagno_of_bsstot_bcn_ie_len bcn_rep_data + bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces + CCXBCNREP=meas_tokflagno_of_bsstot_bcn_ie_len = 18 bytes + */ + + if ((pRoamInfo->pEseBcnReportRsp->flag >> 1) && (!pRoamInfo->pEseBcnReportRsp->numBss)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "Measurement Done but no scan results"); + /* If the measurement is none and no scan results found, + indicate the supplicant about measurement done */ + hdd_indicateEseBcnReportNoResults(pAdapter, + pRoamInfo->pEseBcnReportRsp->measurementToken, + pRoamInfo->pEseBcnReportRsp->flag, + pRoamInfo->pEseBcnReportRsp->numBss); + } + else + { + while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) + { + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + tot_bcn_ieLen = 0; + sendBss = 0; + pos = buf; + freeBytes = IW_CUSTOM_MAX; + + for (i = lastSent; i < pRoamInfo->pEseBcnReportRsp->numBss; i++) + { + len = bcnRepFieldSize + ieLenByte + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen; + if ((len + tot_bcn_ieLen) > (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) + { + break; + } + tot_bcn_ieLen += len; + sendBss++; + hddLog(VOS_TRACE_LEVEL_INFO, "i(%d) sizeof bcnReportFields(%d)" + "IeLength(%d) Length of Ie(%d) totLen(%d)", + i, bcnRepFieldSize, 1, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen, + tot_bcn_ieLen); + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Sending %d BSS Info", sendBss); + hddLog(VOS_TRACE_LEVEL_INFO, "CCXBCNREP=%d %d %d %d", + pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag, + sendBss, tot_bcn_ieLen); + + nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ", + pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag, + sendBss); + pos += nBytes; + freeBytes -= nBytes; + + /* Copy total Beacon report data length */ + vos_mem_copy(pos, (char*)&tot_bcn_ieLen, sizeof(tot_bcn_ieLen)); + pos += sizeof(tot_bcn_ieLen); + freeBytes -= sizeof(tot_bcn_ieLen); + + for (i = 0; i < sendBss; i++) + { + hddLog(VOS_TRACE_LEVEL_INFO, "ChanNum(%d) Spare(%d) MeasDuration(%d)" + " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)" + " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)" + " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)", + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ChanNum, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Spare, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.MeasDuration, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.PhyType, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.RecvSigPower, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ParentTsf, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[0], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[1], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.BcnInterval, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.CapabilityInfo, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[0], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[1], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[2], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[3], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[4], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[5]); + + /* bcn report fields are copied */ + len = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields); + vos_mem_copy(pos, (char*)&pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields, len); + pos += len; + freeBytes -= len; + + /* Add 1 byte of ie len */ + len = pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].ieLen; + vos_mem_copy(pos, (char*)&len, sizeof(len)); + pos += sizeof(len); + freeBytes -= sizeof(len); + + /* copy IE from scan results */ + vos_mem_copy(pos, (char*)pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].pBuf, len); + pos += len; + freeBytes -= len; + } + + wrqu.data.pointer = buf; + wrqu.data.length = IW_CUSTOM_MAX - freeBytes; + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + lastSent += sendBss; + } + } +} + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg.c new file mode 100644 index 0000000000000..0c796e9cfb437 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg.c @@ -0,0 +1,6781 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 07/27/09 kanand Created module. + + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +static void +cbNotifySetRoamPrefer5GHz(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamPrefer5GHz(pHddCtx->hHal, pHddCtx->cfg_ini->nRoamPrefer5GHz); +} + +static void +cbNotifySetImmediateRoamRssiDiff(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateImmediateRoamRssiDiff(pHddCtx->hHal, + pHddCtx->cfg_ini->nImmediateRoamRssiDiff, + 0); +} + +static void +cbNotifySetRoamRssiDiff(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamRssiDiff(pHddCtx->hHal, + 0, + pHddCtx->cfg_ini->RoamRssiDiff); +} + +static void +cbNotifySetFastTransitionEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateFastTransitionEnabled(pHddCtx->hHal, + pHddCtx->cfg_ini->isFastTransitionEnabled); +} + +static void +cbNotifySetRoamIntraBand(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_setRoamIntraBand(pHddCtx->hHal, pHddCtx->cfg_ini->nRoamIntraBand); +} + +static void +cbNotifySetWESMode(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateWESMode(pHddCtx->hHal, + pHddCtx->cfg_ini->isWESModeEnabled, + 0); +} + +static void +cbNotifySetRoamScanNProbes(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamScanNProbes(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nProbes); +} + +static void +cbNotifySetRoamScanHomeAwayTime(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamScanHomeAwayTime(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nRoamScanHomeAwayTime, + eANI_BOOLEAN_TRUE); +} +#endif + +#ifdef FEATURE_WLAN_OKC +static void +cbNotifySetOkcFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ +} +#endif + +#ifdef FEATURE_WLAN_LFR +static void +NotifyIsFastRoamIniFeatureEnabled(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateIsFastRoamIniFeatureEnabled(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled ); +} + +static void +NotifyIsMAWCIniFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateIsMAWCIniFeatureEnabled(pHddCtx->hHal, + pHddCtx->cfg_ini->MAWCEnabled ); +} +#endif + +#ifdef FEATURE_WLAN_ESE +static void +cbNotifySetEseFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateIsEseFeatureEnabled(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->isEseIniFeatureEnabled ); +} +#endif + +static void +cbNotifySetFwRssiMonitoring(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateConfigFwRssiMonitoring(pHddCtx->hHal, + pHddCtx->cfg_ini->fEnableFwRssiMonitoring); +} + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +static void cbNotifySetOpportunisticScanThresholdDiff(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_SetRoamOpportunisticScanThresholdDiff(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nOpportunisticThresholdDiff ); +} + +static void cbNotifySetRoamRescanRssiDiff(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_SetRoamRescanRssiDiff(pHddCtx->hHal, + 0, + pHddCtx->cfg_ini->nRoamRescanRssiDiff); +} + +static void +cbNotifySetNeighborLookupRssiThreshold(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_setNeighborLookupRssiThreshold(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nNeighborLookupRssiThreshold); +} + +static void +cb_notify_set_delay_before_vdev_stop(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_set_delay_before_vdev_stop(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->delay_before_vdev_stop); +} + +static void +cbNotifySetNeighborScanPeriod(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_setNeighborScanPeriod(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nNeighborScanPeriod ); +} + +static void +cbNotifySetNeighborResultsRefreshPeriod(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_setNeighborScanRefreshPeriod(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod); +} + +static void +cbNotifySetEmptyScanRefreshPeriod(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateEmptyScanRefreshPeriod(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nEmptyScanRefreshPeriod); +} + +static void +cbNotifySetNeighborScanMinChanTime(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_setNeighborScanMinChanTime(pHddCtx->hHal, + pHddCtx->cfg_ini->nNeighborScanMinChanTime, + 0); +} + +static void +cbNotifySetNeighborScanMaxChanTime(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + sme_setNeighborScanMaxChanTime(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nNeighborScanMaxChanTime); +} +static void cbNotifySetRoamBmissFirstBcnt(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_SetRoamBmissFirstBcnt(pHddCtx->hHal, + 0, + pHddCtx->cfg_ini->nRoamBmissFirstBcnt); +} + +static void cbNotifySetRoamBmissFinalBcnt(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + sme_SetRoamBmissFinalBcnt(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nRoamBmissFinalBcnt); +} + +static void cbNotifySetRoamBeaconRssiWeight(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + sme_SetRoamBeaconRssiWeight(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->nRoamBeaconRssiWeight); +} + +static void +cbNotifySetDFSScanMode(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* At the point this routine is called, the value in the cfg_ini + table has already been updated */ + sme_UpdateDFSScanMode(pHddCtx->hHal, 0, + pHddCtx->cfg_ini->allowDFSChannelRoam); +} + +#endif + +static void cbNotifySetEnableSSR(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateEnableSSR(pHddCtx->hHal, pHddCtx->cfg_ini->enableSSR); +} + + +static void cbNotify_set_gSapPreferredChanLocation(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + WLANSAP_set_Dfs_Preferred_Channel_location(pHddCtx->hHal, + pHddCtx->cfg_ini->gSapPreferredChanLocation); +} + + +static void chNotify_set_gDisableDfsJapanW53(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + WLANSAP_set_Dfs_Restrict_JapanW53(pHddCtx->hHal, + pHddCtx->cfg_ini->gDisableDfsJapanW53); +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static void +cbNotifyUpdateRoamScanOffloadEnabled(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + sme_UpdateRoamScanOffloadEnabled(pHddCtx->hHal, + pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + if (0 == pHddCtx->cfg_ini->isRoamOffloadScanEnabled) { + pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled = 0; + sme_UpdateEnableFastRoamInConcurrency(pHddCtx->hHal, + pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled); + } +} + +static void +cbNotifySetEnableFastRoamInConcurrency(hdd_context_t *pHddCtx, + unsigned long NotifyId) +{ + sme_UpdateEnableFastRoamInConcurrency(pHddCtx->hHal, + pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled); +} + +#endif + +REG_TABLE_ENTRY g_registry_table[] = +{ + REG_VARIABLE( CFG_RTS_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, RTSThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RTS_THRESHOLD_DEFAULT, + CFG_RTS_THRESHOLD_MIN, + CFG_RTS_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_FRAG_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, FragmentationThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FRAG_THRESHOLD_DEFAULT, + CFG_FRAG_THRESHOLD_MIN, + CFG_FRAG_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_CALIBRATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, Calibration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_CALIBRATION_DEFAULT, + CFG_CALIBRATION_MIN, + CFG_CALIBRATION_MAX ), + + REG_VARIABLE( CFG_CALIBRATION_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, CalibrationPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_CALIBRATION_PERIOD_DEFAULT, + CFG_CALIBRATION_PERIOD_MIN, + CFG_CALIBRATION_PERIOD_MAX ), + + REG_VARIABLE( CFG_OPERATING_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, OperatingChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OPERATING_CHANNEL_DEFAULT, + CFG_OPERATING_CHANNEL_MIN, + CFG_OPERATING_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SHORT_SLOT_TIME_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortSlotTimeEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT, + CFG_SHORT_SLOT_TIME_ENABLED_MIN, + CFG_SHORT_SLOT_TIME_ENABLED_MAX ), + + REG_VARIABLE( CFG_11D_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, Is11dSupportEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_11D_SUPPORT_ENABLED_DEFAULT, + CFG_11D_SUPPORT_ENABLED_MIN, + CFG_11D_SUPPORT_ENABLED_MAX ), + + REG_VARIABLE( CFG_11H_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, Is11hSupportEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_11H_SUPPORT_ENABLED_DEFAULT, + CFG_11H_SUPPORT_ENABLED_MIN, + CFG_11H_SUPPORT_ENABLED_MAX ), + + REG_VARIABLE( CFG_ENFORCE_11D_CHANNELS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforce11dChannels, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_11D_CHANNELS_DEFAULT, + CFG_ENFORCE_11D_CHANNELS_MIN, + CFG_ENFORCE_11D_CHANNELS_MAX ), + + REG_VARIABLE( CFG_COUNTRY_CODE_PRIORITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, fSupplicantCountryCodeHasPriority, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_COUNTRY_CODE_PRIORITY_DEFAULT, + CFG_COUNTRY_CODE_PRIORITY_MIN, + CFG_COUNTRY_CODE_PRIORITY_MAX), + + REG_VARIABLE( CFG_ENFORCE_COUNTRY_CODE_MATCH_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforceCountryCodeMatch, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_COUNTRY_CODE_MATCH_DEFAULT, + CFG_ENFORCE_COUNTRY_CODE_MATCH_MIN, + CFG_ENFORCE_COUNTRY_CODE_MATCH_MAX ), + + REG_VARIABLE( CFG_ENFORCE_DEFAULT_DOMAIN_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforceDefaultDomain, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_DEFAULT_DOMAIN_DEFAULT, + CFG_ENFORCE_DEFAULT_DOMAIN_MIN, + CFG_ENFORCE_DEFAULT_DOMAIN_MAX ), + + REG_VARIABLE( CFG_HEARTBEAT_THRESH_24_NAME, WLAN_PARAM_Integer, + hdd_config_t, HeartbeatThresh24, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_HEARTBEAT_THRESH_24_DEFAULT, + CFG_HEARTBEAT_THRESH_24_MIN, + CFG_HEARTBEAT_THRESH_24_MAX ), + + REG_VARIABLE_STRING( CFG_POWER_USAGE_NAME, WLAN_PARAM_String, + hdd_config_t, PowerUsageControl, + VAR_FLAGS_OPTIONAL, + (void *)CFG_POWER_USAGE_DEFAULT ), + + REG_VARIABLE( CFG_ENABLE_SUSPEND_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEnableSuspend, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SUSPEND_DEFAULT, + CFG_ENABLE_SUSPEND_MIN, + CFG_ENABLE_SUSPEND_MAX ), + + REG_VARIABLE( CFG_ENABLE_ENABLE_DRIVER_STOP_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEnableDriverStop, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_ENABLE_DRIVER_STOP_DEFAULT, + CFG_ENABLE_ENABLE_DRIVER_STOP_MIN, + CFG_ENABLE_ENABLE_DRIVER_STOP_MAX ), + + REG_VARIABLE( CFG_ENABLE_IMPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsImpsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_IMPS_DEFAULT, + CFG_ENABLE_IMPS_MIN, + CFG_ENABLE_IMPS_MAX ), + + REG_VARIABLE( CFG_ENABLE_LOGP_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsLogpEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LOGP_DEFAULT, + CFG_ENABLE_LOGP_MIN, + CFG_ENABLE_LOGP_MAX ), + + REG_VARIABLE( CFG_IMPS_MINIMUM_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsMinSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MINIMUM_SLEEP_TIME_DEFAULT, + CFG_IMPS_MINIMUM_SLEEP_TIME_MIN, + CFG_IMPS_MINIMUM_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_IMPS_MAXIMUM_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsMaxSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MAXIMUM_SLEEP_TIME_DEFAULT, + CFG_IMPS_MAXIMUM_SLEEP_TIME_MIN, + CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_IMPS_MODERATE_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsModSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MODERATE_SLEEP_TIME_DEFAULT, + CFG_IMPS_MODERATE_SLEEP_TIME_MIN, + CFG_IMPS_MODERATE_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_ENABLE_BMPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsBmpsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BMPS_DEFAULT, + CFG_ENABLE_BMPS_MIN, + CFG_ENABLE_BMPS_MAX ), + + REG_VARIABLE( CFG_BMPS_MINIMUM_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsMinListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MINIMUM_LI_DEFAULT, + CFG_BMPS_MINIMUM_LI_MIN, + CFG_BMPS_MINIMUM_LI_MAX ), + + REG_VARIABLE( CFG_BMPS_MAXIMUM_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsMaxListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MAXIMUM_LI_DEFAULT, + CFG_BMPS_MAXIMUM_LI_MIN, + CFG_BMPS_MAXIMUM_LI_MAX ), + + REG_VARIABLE( CFG_BMPS_MODERATE_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsModListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MODERATE_LI_DEFAULT, + CFG_BMPS_MODERATE_LI_MIN, + CFG_BMPS_MODERATE_LI_MAX ), + + REG_VARIABLE( CFG_ENABLE_AUTO_BMPS_TIMER_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsAutoBmpsTimerEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_AUTO_BMPS_TIMER_DEFAULT, + CFG_ENABLE_AUTO_BMPS_TIMER_MIN, + CFG_ENABLE_AUTO_BMPS_TIMER_MAX ), + + REG_VARIABLE( CFG_AUTO_BMPS_TIMER_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, nAutoBmpsTimerValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AUTO_BMPS_TIMER_VALUE_DEFAULT, + CFG_AUTO_BMPS_TIMER_VALUE_MIN, + CFG_AUTO_BMPS_TIMER_VALUE_MAX ), + + REG_VARIABLE( CFG_DOT11_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, dot11Mode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_DOT11_MODE_DEFAULT, + CFG_DOT11_MODE_MIN, + CFG_DOT11_MODE_MAX ), + + REG_VARIABLE( CFG_SAP_FORCE_11AC_FOR_11N, WLAN_PARAM_Integer, + hdd_config_t, apForce11ACFor11n, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_FORCE_11AC_FOR_11N_DEFAULT, + CFG_SAP_FORCE_11AC_FOR_11N_MIN, + CFG_SAP_FORCE_11AC_FOR_11N_MAX ), + + REG_VARIABLE( CFG_CHANNEL_BONDING_MODE_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, nChannelBondingMode24GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_CHANNEL_BONDING_MODE_DEFAULT, + CFG_CHANNEL_BONDING_MODE_MIN, + CFG_CHANNEL_BONDING_MODE_MAX), + + REG_VARIABLE( CFG_CHANNEL_BONDING_MODE_5GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, nChannelBondingMode5GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_CHANNEL_BONDING_MODE_DEFAULT, + CFG_CHANNEL_BONDING_MODE_MIN, + CFG_CHANNEL_BONDING_MODE_MAX), + + REG_VARIABLE( CFG_MAX_RX_AMPDU_FACTOR_NAME, WLAN_PARAM_Integer, + hdd_config_t, MaxRxAmpduFactor, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_MAX_RX_AMPDU_FACTOR_DEFAULT, + CFG_MAX_RX_AMPDU_FACTOR_MIN, + CFG_MAX_RX_AMPDU_FACTOR_MAX), + + REG_VARIABLE( CFG_FIXED_RATE_NAME, WLAN_PARAM_Integer, + hdd_config_t, TxRate, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_FIXED_RATE_DEFAULT, + CFG_FIXED_RATE_MIN, + CFG_FIXED_RATE_MAX ), + + REG_VARIABLE( CFG_SHORT_GI_20MHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortGI20MhzEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_GI_20MHZ_DEFAULT, + CFG_SHORT_GI_20MHZ_MIN, + CFG_SHORT_GI_20MHZ_MAX ), + + REG_VARIABLE( CFG_BLOCK_ACK_AUTO_SETUP_NAME, WLAN_PARAM_Integer, + hdd_config_t, BlockAckAutoSetup, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_BLOCK_ACK_AUTO_SETUP_DEFAULT, + CFG_BLOCK_ACK_AUTO_SETUP_MIN, + CFG_BLOCK_ACK_AUTO_SETUP_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_COUNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, ScanResultAgeCount, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_COUNT_DEFAULT, + CFG_SCAN_RESULT_AGE_COUNT_MIN, + CFG_SCAN_RESULT_AGE_COUNT_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_NCNPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeNCNPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_NCPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeNCPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_NCPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_NCPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_NCPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_CNPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeCNPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_CNPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_CNPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_CNPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_CPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeCPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_CPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_CPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_CPS_MAX ), + + REG_VARIABLE( CFG_RSSI_CATEGORY_GAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRssiCatGap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RSSI_CATEGORY_GAP_DEFAULT, + CFG_RSSI_CATEGORY_GAP_MIN, + CFG_RSSI_CATEGORY_GAP_MAX ), + + REG_VARIABLE( CFG_SHORT_PREAMBLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsShortPreamble, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_PREAMBLE_DEFAULT, + CFG_SHORT_PREAMBLE_MIN, + CFG_SHORT_PREAMBLE_MAX ), + + REG_VARIABLE_STRING( CFG_IBSS_BSSID_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, IbssBssid, + VAR_FLAGS_OPTIONAL, + (void *)CFG_IBSS_BSSID_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF0_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[0], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF0_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF1_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[1], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF1_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF2_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[2], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF2_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF3_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[3], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF3_MAC_ADDR_DEFAULT ), + + REG_VARIABLE( CFG_AP_QOS_UAPSD_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, apUapsdEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_QOS_UAPSD_MODE_DEFAULT, + CFG_AP_QOS_UAPSD_MODE_MIN, + CFG_AP_QOS_UAPSD_MODE_MAX ), + + REG_VARIABLE_STRING( CFG_AP_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, apCntryCode, + VAR_FLAGS_OPTIONAL, + (void *)CFG_AP_COUNTRY_CODE_DEFAULT ), + + REG_VARIABLE( CFG_AP_ENABLE_RANDOM_BSSID_NAME, WLAN_PARAM_Integer, + hdd_config_t, apRandomBssidEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT, + CFG_AP_ENABLE_RANDOM_BSSID_MIN, + CFG_AP_ENABLE_RANDOM_BSSID_MAX ), + + REG_VARIABLE( CFG_AP_ENABLE_PROTECTION_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, apProtEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT, + CFG_AP_ENABLE_PROTECTION_MODE_MIN, + CFG_AP_ENABLE_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_PROTECTION_MODE_NAME, WLAN_PARAM_HexInteger, + hdd_config_t, apProtection, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_PROTECTION_MODE_DEFAULT, + CFG_AP_PROTECTION_MODE_MIN, + CFG_AP_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_OBSS_PROTECTION_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, apOBSSProtEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_OBSS_PROTECTION_MODE_DEFAULT, + CFG_AP_OBSS_PROTECTION_MODE_MIN, + CFG_AP_OBSS_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_STA_SECURITY_SEPERATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, apDisableIntraBssFwd, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_STA_SECURITY_SEPERATION_DEFAULT, + CFG_AP_STA_SECURITY_SEPERATION_MIN, + CFG_AP_STA_SECURITY_SEPERATION_MAX ), + + REG_VARIABLE( CFG_FRAMES_PROCESSING_TH_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, MinFramesProcThres, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FRAMES_PROCESSING_TH_DEFAULT, + CFG_FRAMES_PROCESSING_TH_MIN, + CFG_FRAMES_PROCESSING_TH_MAX ), + + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_START_CHANNEL , WLAN_PARAM_Integer, + hdd_config_t, apStartChannelNum, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_END_CHANNEL , WLAN_PARAM_Integer, + hdd_config_t, apEndChannelNum, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_OPERATING_BAND , WLAN_PARAM_Integer, + hdd_config_t, apOperatingBand, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_DEFAULT, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MIN, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MAX ), + + REG_VARIABLE( CFG_SAP_AUTO_CHANNEL_SELECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, apAutoChannelSelection, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT, + CFG_SAP_AUTO_CHANNEL_SELECTION_MIN, + CFG_SAP_AUTO_CHANNEL_SELECTION_MAX ), + + REG_VARIABLE( CFG_ENABLE_LTE_COEX , WLAN_PARAM_Integer, + hdd_config_t, enableLTECoex, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LTE_COEX_DEFAULT, + CFG_ENABLE_LTE_COEX_MIN, + CFG_ENABLE_LTE_COEX_MAX ), + + REG_VARIABLE( CFG_AP_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_AP_KEEP_ALIVE_PERIOD_MIN, + CFG_AP_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_GO_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, goKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GO_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_GO_KEEP_ALIVE_PERIOD_MIN, + CFG_GO_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_AP_LINK_MONITOR_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apLinkMonitorPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_LINK_MONITOR_PERIOD_DEFAULT, + CFG_AP_LINK_MONITOR_PERIOD_MIN, + CFG_AP_LINK_MONITOR_PERIOD_MAX), + + REG_VARIABLE( CFG_GO_LINK_MONITOR_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, goLinkMonitorPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GO_LINK_MONITOR_PERIOD_DEFAULT, + CFG_GO_LINK_MONITOR_PERIOD_MIN, + CFG_GO_LINK_MONITOR_PERIOD_MAX), + + REG_VARIABLE( CFG_DISABLE_PACKET_FILTER , WLAN_PARAM_Integer, + hdd_config_t, disablePacketFilter, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_PACKET_FILTER_DEFAULT, + CFG_DISABLE_PACKET_FILTER_MIN, + CFG_DISABLE_PACKET_FILTER_MAX ), + + REG_VARIABLE( CFG_BEACON_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBeaconInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_BEACON_INTERVAL_DEFAULT, + CFG_BEACON_INTERVAL_MIN, + CFG_BEACON_INTERVAL_MAX ), + + REG_VARIABLE( CFG_ENABLE_IDLE_SCAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, nEnableIdleScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_IDLE_SCAN_DEFAULT, + CFG_ENABLE_IDLE_SCAN_MIN, + CFG_ENABLE_IDLE_SCAN_MAX ), + + REG_VARIABLE( CFG_ROAMING_TIME_NAME , WLAN_PARAM_Integer, + hdd_config_t, nRoamingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAMING_TIME_DEFAULT, + CFG_ROAMING_TIME_MIN, + CFG_ROAMING_TIME_MAX ), + + REG_VARIABLE( CFG_VCC_RSSI_TRIGGER_NAME , WLAN_PARAM_Integer, + hdd_config_t, nVccRssiTrigger, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VCC_RSSI_TRIGGER_DEFAULT, + CFG_VCC_RSSI_TRIGGER_MIN, + CFG_VCC_RSSI_TRIGGER_MAX ), + + REG_VARIABLE( CFG_VCC_UL_MAC_LOSS_THRESH_NAME , WLAN_PARAM_Integer, + hdd_config_t, nVccUlMacLossThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT, + CFG_VCC_UL_MAC_LOSS_THRESH_MIN, + CFG_VCC_UL_MAC_LOSS_THRESH_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMaxChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_MIN, + CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MIN_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMinChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_MIN, + CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMaxChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMinChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMaxChnTimeBtc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMinChnTimeBtc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_ZERO_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitZero, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_ZERO_DEFAULT, + CFG_RETRY_LIMIT_ZERO_MIN, + CFG_RETRY_LIMIT_ZERO_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_ONE_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitOne, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_ONE_DEFAULT, + CFG_RETRY_LIMIT_ONE_MIN, + CFG_RETRY_LIMIT_ONE_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_TWO_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitTwo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_TWO_DEFAULT, + CFG_RETRY_LIMIT_TWO_MIN, + CFG_RETRY_LIMIT_TWO_MAX ), + + REG_VARIABLE( CFG_DISABLE_AGG_WITH_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, disableAggWithBtc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_AGG_WITH_BTC_DEFAULT, + CFG_DISABLE_AGG_WITH_BTC_MIN, + CFG_DISABLE_AGG_WITH_BTC_MAX ), + +#ifdef WLAN_AP_STA_CONCURRENCY + REG_VARIABLE( CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMaxChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMinChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMaxChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMinChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_REST_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRestTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REST_TIME_CONC_DEFAULT, + CFG_REST_TIME_CONC_MIN, + CFG_REST_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_NUM_STA_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNumStaChanCombinedConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NUM_STA_CHAN_COMBINED_CONC_DEFAULT, + CFG_NUM_STA_CHAN_COMBINED_CONC_MIN, + CFG_NUM_STA_CHAN_COMBINED_CONC_MAX ), + + REG_VARIABLE( CFG_NUM_P2P_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNumP2PChanCombinedConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NUM_P2P_CHAN_COMBINED_CONC_DEFAULT, + CFG_NUM_P2P_CHAN_COMBINED_CONC_MIN, + CFG_NUM_P2P_CHAN_COMBINED_CONC_MAX ), +#endif + + REG_VARIABLE( CFG_MAX_PS_POLL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nMaxPsPoll, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_PS_POLL_DEFAULT, + CFG_MAX_PS_POLL_MIN, + CFG_MAX_PS_POLL_MAX ), + + REG_VARIABLE( CFG_MAX_TX_POWER_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTxPowerCap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_TX_POWER_DEFAULT, + CFG_MAX_TX_POWER_MIN, + CFG_MAX_TX_POWER_MAX ), + + REG_VARIABLE( CFG_LOW_GAIN_OVERRIDE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsLowGainOverride, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LOW_GAIN_OVERRIDE_DEFAULT, + CFG_LOW_GAIN_OVERRIDE_MIN, + CFG_LOW_GAIN_OVERRIDE_MAX ), + + REG_VARIABLE( CFG_RSSI_FILTER_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRssiFilterPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RSSI_FILTER_PERIOD_DEFAULT, + CFG_RSSI_FILTER_PERIOD_MIN, + CFG_RSSI_FILTER_PERIOD_MAX ), + + REG_VARIABLE( CFG_IGNORE_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIgnoreDtim, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_DTIM_DEFAULT, + CFG_IGNORE_DTIM_MIN, + CFG_IGNORE_DTIM_MAX ), + + REG_VARIABLE( CFG_MAX_LI_MODULATED_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, fMaxLIModulatedDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_LI_MODULATED_DTIM_DEFAULT, + CFG_MAX_LI_MODULATED_DTIM_MIN, + CFG_MAX_LI_MODULATED_DTIM_MAX ), + + REG_VARIABLE( CFG_RX_ANT_CONFIGURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRxAnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RX_ANT_CONFIGURATION_NAME_DEFAULT, + CFG_RX_ANT_CONFIGURATION_NAME_MIN, + CFG_RX_ANT_CONFIGURATION_NAME_MAX ), + + REG_VARIABLE( CFG_FW_HEART_BEAT_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwHeartBeatMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_HEART_BEAT_MONITORING_DEFAULT, + CFG_FW_HEART_BEAT_MONITORING_MIN, + CFG_FW_HEART_BEAT_MONITORING_MAX ), + + REG_VARIABLE( CFG_FW_BEACON_FILTERING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwBeaconFiltering, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_BEACON_FILTERING_DEFAULT, + CFG_FW_BEACON_FILTERING_MIN, + CFG_FW_BEACON_FILTERING_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_FW_RSSI_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwRssiMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_RSSI_MONITORING_DEFAULT, + CFG_FW_RSSI_MONITORING_MIN, + CFG_FW_RSSI_MONITORING_MAX, + cbNotifySetFwRssiMonitoring, 0 ), + + REG_VARIABLE( CFG_DATA_INACTIVITY_TIMEOUT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nDataInactivityTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DATA_INACTIVITY_TIMEOUT_DEFAULT, + CFG_DATA_INACTIVITY_TIMEOUT_MIN, + CFG_DATA_INACTIVITY_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_NTH_BEACON_FILTER_NAME, WLAN_PARAM_Integer, + hdd_config_t, nthBeaconFilter, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NTH_BEACON_FILTER_DEFAULT, + CFG_NTH_BEACON_FILTER_MIN, + CFG_NTH_BEACON_FILTER_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, WmmMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_MODE_DEFAULT, + CFG_QOS_WMM_MODE_MIN, + CFG_QOS_WMM_MODE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_80211E_ENABLED_NAME , WLAN_PARAM_Integer, + hdd_config_t, b80211eIsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_80211E_ENABLED_DEFAULT, + CFG_QOS_WMM_80211E_ENABLED_MIN, + CFG_QOS_WMM_80211E_ENABLED_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_UAPSD_MASK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, UapsdMask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_UAPSD_MASK_DEFAULT, + CFG_QOS_WMM_UAPSD_MASK_MIN, + CFG_QOS_WMM_UAPSD_MASK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdVoSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdVoSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdViSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdViSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBeSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBeSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBkSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBkSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MAX ), + +#ifdef FEATURE_WLAN_ESE + REG_VARIABLE( CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, InfraInactivityInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX), + + REG_DYNAMIC_VARIABLE( CFG_ESE_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isEseIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ESE_FEATURE_ENABLED_DEFAULT, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX, + cbNotifySetEseFeatureEnabled, 0 ), +#endif // FEATURE_WLAN_ESE + +#ifdef FEATURE_WLAN_LFR + // flag to turn ON/OFF Legacy Fast Roaming + REG_DYNAMIC_VARIABLE( CFG_LFR_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isFastRoamIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LFR_FEATURE_ENABLED_DEFAULT, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX, + NotifyIsFastRoamIniFeatureEnabled, 0 ), + + /* flag to turn ON/OFF Motion assistance for Legacy Fast Roaming */ + REG_DYNAMIC_VARIABLE( CFG_LFR_MAWC_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, MAWCEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT, + CFG_LFR_MAWC_FEATURE_ENABLED_MIN, + CFG_LFR_MAWC_FEATURE_ENABLED_MAX, + NotifyIsMAWCIniFeatureEnabled, 0 ), + +#endif // FEATURE_WLAN_LFR + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + // flag to turn ON/OFF 11r and ESE FastTransition + REG_DYNAMIC_VARIABLE( CFG_FAST_TRANSITION_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isFastTransitionEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX, + cbNotifySetFastTransitionEnabled, 0 ), + + /* Variable to specify the delta/difference between the RSSI of current AP + * and roamable AP while roaming */ + REG_DYNAMIC_VARIABLE( CFG_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, RoamRssiDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_RSSI_DIFF_DEFAULT, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX, + cbNotifySetRoamRssiDiff, 0), + + REG_DYNAMIC_VARIABLE( CFG_IMMEDIATE_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImmediateRoamRssiDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_DEFAULT, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_MIN, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_MAX, + cbNotifySetImmediateRoamRssiDiff, 0), + + REG_DYNAMIC_VARIABLE( CFG_ENABLE_WES_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, isWESModeEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_WES_MODE_NAME_DEFAULT, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX, + cbNotifySetWESMode, 0), +#endif +#ifdef FEATURE_WLAN_OKC + REG_DYNAMIC_VARIABLE( CFG_OKC_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isOkcIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OKC_FEATURE_ENABLED_DEFAULT, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX, + cbNotifySetOkcFeatureEnabled, 0 ), +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_OFFLOAD_ENABLED, WLAN_PARAM_Integer, + hdd_config_t, isRoamOffloadScanEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX, + cbNotifyUpdateRoamScanOffloadEnabled, 0), +#endif + REG_VARIABLE( CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME , WLAN_PARAM_Integer, + hdd_config_t, PktClassificationBasis, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VO_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VO_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_VI_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VI_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VI_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_BE_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BE_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BE_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_BK_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BK_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BK_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_BK_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_BK_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqBkWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_BK_WEIGHT_DEFAULT, + CFG_TL_WFQ_BK_WEIGHT_MIN, + CFG_TL_WFQ_BK_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_BE_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqBeWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_BE_WEIGHT_DEFAULT, + CFG_TL_WFQ_BE_WEIGHT_MIN, + CFG_TL_WFQ_BE_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_VI_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqViWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_VI_WEIGHT_DEFAULT, + CFG_TL_WFQ_VI_WEIGHT_MIN, + CFG_TL_WFQ_VI_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_VO_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqVoWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_VO_WEIGHT_DEFAULT, + CFG_TL_WFQ_VO_WEIGHT_MIN, + CFG_TL_WFQ_VO_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_DELAYED_TRGR_FRM_INT_NAME , WLAN_PARAM_Integer, + hdd_config_t, DelayedTriggerFrmInt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT, + CFG_TL_DELAYED_TRGR_FRM_INT_MIN, + CFG_TL_DELAYED_TRGR_FRM_INT_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_BK_NAME , WLAN_PARAM_Integer, + hdd_config_t, BkReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_BK_DEFAULT, + CFG_REORDER_TIME_BK_MIN, + CFG_REORDER_TIME_BK_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_BE_NAME , WLAN_PARAM_Integer, + hdd_config_t, BeReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_BE_DEFAULT, + CFG_REORDER_TIME_BE_MIN, + CFG_REORDER_TIME_BE_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_VI_NAME , WLAN_PARAM_Integer, + hdd_config_t, ViReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_VI_DEFAULT, + CFG_REORDER_TIME_VI_MIN, + CFG_REORDER_TIME_VI_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_VO_NAME , WLAN_PARAM_Integer, + hdd_config_t, VoReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_VO_DEFAULT, + CFG_REORDER_TIME_VO_MIN, + CFG_REORDER_TIME_VO_MAX ), + + REG_VARIABLE_STRING( CFG_WOWL_PATTERN_NAME, WLAN_PARAM_String, + hdd_config_t, wowlPattern, + VAR_FLAGS_OPTIONAL, + (void *)CFG_WOWL_PATTERN_DEFAULT ), + + REG_VARIABLE( CFG_QOS_IMPLICIT_SETUP_ENABLED_NAME , WLAN_PARAM_Integer, + hdd_config_t, bImplicitQosEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT, + CFG_QOS_IMPLICIT_SETUP_ENABLED_MIN, + CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX ), + + REG_VARIABLE( CFG_BTC_EXECUTION_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcExecutionMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_EXECUTION_MODE_DEFAULT, + CFG_BTC_EXECUTION_MODE_MIN, + CFG_BTC_EXECUTION_MODE_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROTECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcConsBtSlotsToBlockDuringDhcp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROTECTION_DEFAULT, + CFG_BTC_DHCP_PROTECTION_MIN, + CFG_BTC_DHCP_PROTECTION_MAX ), + + REG_VARIABLE( CFG_BTC_A2DP_DHCP_PROTECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcA2DPBtSubIntervalsDuringDhcp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_A2DP_DHCP_PROTECTION_DEFAULT, + CFG_BTC_A2DP_DHCP_PROTECTION_MIN, + CFG_BTC_A2DP_DHCP_PROTECTION_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_INQ_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenInqBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_BT_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_BT_MIN, + CFG_BTC_STATIC_LEN_INQ_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_PAGE_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenPageBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_BT_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_BT_MIN, + CFG_BTC_STATIC_LEN_PAGE_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_CONN_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenConnBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_BT_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_BT_MIN, + CFG_BTC_STATIC_LEN_CONN_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_LE_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenLeBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_LE_BT_DEFAULT, + CFG_BTC_STATIC_LEN_LE_BT_MIN, + CFG_BTC_STATIC_LEN_LE_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_INQ_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenInqWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_WLAN_MIN, + CFG_BTC_STATIC_LEN_INQ_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_PAGE_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenPageWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN, + CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_CONN_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenConnWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_WLAN_MIN, + CFG_BTC_STATIC_LEN_CONN_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_LE_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenLeWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_LE_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_LE_WLAN_MIN, + CFG_BTC_STATIC_LEN_LE_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_DYN_MAX_LEN_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDynMaxLenBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_MAX_LEN_BT_DEFAULT, + CFG_BTC_DYN_MAX_LEN_BT_MIN, + CFG_BTC_DYN_MAX_LEN_BT_MAX ), + + REG_VARIABLE( CFG_BTC_DYN_MAX_LEN_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDynMaxLenWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_MAX_LEN_WLAN_DEFAULT, + CFG_BTC_DYN_MAX_LEN_WLAN_MIN, + CFG_BTC_DYN_MAX_LEN_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_MAX_SCO_BLOCK_PERC_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcMaxScoBlockPerc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_MAX_SCO_BLOCK_PERC_DEFAULT, + CFG_BTC_MAX_SCO_BLOCK_PERC_MIN, + CFG_BTC_MAX_SCO_BLOCK_PERC_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROT_ON_A2DP_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDhcpProtOnA2dp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROT_ON_A2DP_DEFAULT, + CFG_BTC_DHCP_PROT_ON_A2DP_MIN, + CFG_BTC_DHCP_PROT_ON_A2DP_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROT_ON_SCO_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDhcpProtOnSco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROT_ON_SCO_DEFAULT, + CFG_BTC_DHCP_PROT_ON_SCO_MIN, + CFG_BTC_DHCP_PROT_ON_SCO_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_MODEM_BACKOFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexModemBackoff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_MODEM_BACKOFF_DEFAULT, + CFG_MWS_COEX_MODEM_BACKOFF_MIN, + CFG_MWS_COEX_MODEM_BACKOFF_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG1_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG3_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG4_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG5_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG6_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_SAR_POWER_BACKOFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, SARPowerBackoff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAR_POWER_BACKOFF_DEFAULT, + CFG_SAR_POWER_BACKOFF_MIN, + CFG_SAR_POWER_BACKOFF_MAX ), + + REG_VARIABLE( CFG_AP_LISTEN_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, nEnableListenMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_LISTEN_MODE_DEFAULT, + CFG_AP_LISTEN_MODE_MIN, + CFG_AP_LISTEN_MODE_MAX ), + + REG_VARIABLE( CFG_AP_AUTO_SHUT_OFF , WLAN_PARAM_Integer, + hdd_config_t, nAPAutoShutOff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_AUTO_SHUT_OFF_DEFAULT, + CFG_AP_AUTO_SHUT_OFF_MIN, + CFG_AP_AUTO_SHUT_OFF_MAX ), + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + REG_VARIABLE( CFG_WLAN_MCC_TO_SCC_SWITCH_MODE , WLAN_PARAM_Integer, + hdd_config_t, WlanMccToSccSwitchMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_DEFAULT, + CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MIN, + CFG_WLAN_MCC_TO_SCC_SWITCH_MODE_MAX ), +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + REG_VARIABLE( CFG_WLAN_AUTO_SHUTDOWN , WLAN_PARAM_Integer, + hdd_config_t, WlanAutoShutdown, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_AUTO_SHUTDOWN_DEFAULT, + CFG_WLAN_AUTO_SHUTDOWN_MIN, + CFG_WLAN_AUTO_SHUTDOWN_MAX ), +#endif +#if defined WLAN_FEATURE_VOWIFI + REG_VARIABLE( CFG_RRM_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fRrmEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_ENABLE_DEFAULT, + CFG_RRM_ENABLE_MIN, + CFG_RRM_ENABLE_MAX ), + + REG_VARIABLE( CFG_RRM_OPERATING_CHAN_MAX_DURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nInChanMeasMaxDuration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_DEFAULT, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_MIN, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_MAX ), + + REG_VARIABLE( CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nOutChanMeasMaxDuration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_DEFAULT, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MIN, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MAX ), + + REG_VARIABLE( CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRrmRandnIntvl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX ), +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + REG_VARIABLE( CFG_FT_RESOURCE_REQ_NAME, WLAN_PARAM_Integer, + hdd_config_t, fFTResourceReqSupported, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FT_RESOURCE_REQ_DEFAULT, + CFG_FT_RESOURCE_REQ_MIN, + CFG_FT_RESOURCE_REQ_MAX ), +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX, + cbNotifySetNeighborScanPeriod, 0 ), + + REG_VARIABLE( CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborReassocRssiThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_DEFAULT, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborLookupRssiThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX, + cbNotifySetNeighborLookupRssiThreshold, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, nOpportunisticThresholdDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT, + CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MIN, + CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MAX, + cbNotifySetOpportunisticScanThresholdDiff, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_RESCAN_RSSI_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRoamRescanRssiDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT, + CFG_ROAM_RESCAN_RSSI_DIFF_MIN, + CFG_ROAM_RESCAN_RSSI_DIFF_MAX, + cbNotifySetRoamRescanRssiDiff, 0 ), + + REG_VARIABLE_STRING( CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME, WLAN_PARAM_String, + hdd_config_t, neighborScanChanList, + VAR_FLAGS_OPTIONAL, + (void *)CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanMinChanTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX, + cbNotifySetNeighborScanMinChanTime, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanMaxChanTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX, + cbNotifySetNeighborScanMaxChanTime, 0 ), + + REG_VARIABLE( CFG_11R_NEIGHBOR_REQ_MAX_TRIES_NAME, WLAN_PARAM_Integer, + hdd_config_t, nMaxNeighborReqTries, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_DEFAULT, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MIN, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MAX), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborResultsRefreshPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX, + cbNotifySetNeighborResultsRefreshPeriod, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEmptyScanRefreshPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT, + CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN, + CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX, + cbNotifySetEmptyScanRefreshPeriod, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_BMISS_FIRST_BCNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRoamBmissFirstBcnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_BMISS_FIRST_BCNT_DEFAULT, + CFG_ROAM_BMISS_FIRST_BCNT_MIN, + CFG_ROAM_BMISS_FIRST_BCNT_MAX, + cbNotifySetRoamBmissFirstBcnt, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_BMISS_FINAL_BCNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRoamBmissFinalBcnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_BMISS_FINAL_BCNT_DEFAULT, + CFG_ROAM_BMISS_FINAL_BCNT_MIN, + CFG_ROAM_BMISS_FINAL_BCNT_MAX, + cbNotifySetRoamBmissFinalBcnt, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_BEACON_RSSI_WEIGHT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRoamBeaconRssiWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_BEACON_RSSI_WEIGHT_DEFAULT, + CFG_ROAM_BEACON_RSSI_WEIGHT_MIN, + CFG_ROAM_BEACON_RSSI_WEIGHT_MAX, + cbNotifySetRoamBeaconRssiWeight, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAMING_DFS_CHANNEL_NAME , WLAN_PARAM_Integer, + hdd_config_t, allowDFSChannelRoam, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX, + cbNotifySetDFSScanMode, 0), + + REG_DYNAMIC_VARIABLE( CFG_DELAY_BEFORE_VDEV_STOP_NAME, WLAN_PARAM_Integer, + hdd_config_t, delay_before_vdev_stop, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DELAY_BEFORE_VDEV_STOP_DEFAULT, + CFG_DELAY_BEFORE_VDEV_STOP_MIN, + CFG_DELAY_BEFORE_VDEV_STOP_MAX, + cb_notify_set_delay_before_vdev_stop, 0 ), + +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + + REG_VARIABLE( CFG_QOS_WMM_BURST_SIZE_DEFN_NAME , WLAN_PARAM_Integer, + hdd_config_t, burstSizeDefinition, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT, + CFG_QOS_WMM_BURST_SIZE_DEFN_MIN, + CFG_QOS_WMM_BURST_SIZE_DEFN_MAX ), + + REG_VARIABLE( CFG_MCAST_BCAST_FILTER_SETTING_NAME, WLAN_PARAM_Integer, + hdd_config_t, mcastBcastFilterSetting, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MCAST_BCAST_FILTER_SETTING_DEFAULT, + CFG_MCAST_BCAST_FILTER_SETTING_MIN, + CFG_MCAST_BCAST_FILTER_SETTING_MAX ), + + REG_VARIABLE( CFG_ENABLE_HOST_ARPOFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fhostArpOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HOST_ARPOFFLOAD_DEFAULT, + CFG_ENABLE_HOST_ARPOFFLOAD_MIN, + CFG_ENABLE_HOST_ARPOFFLOAD_MAX ), + +#ifdef FEATURE_WLAN_RA_FILTERING + REG_VARIABLE( CFG_RA_FILTER_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, IsRArateLimitEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RA_FILTER_ENABLE_DEFAULT, + CFG_RA_FILTER_ENABLE_MIN, + CFG_RA_FILTER_ENABLE_MAX ), + + REG_VARIABLE( CFG_RA_RATE_LIMIT_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, RArateLimitInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT, + CFG_RA_RATE_LIMIT_INTERVAL_MIN, + CFG_RA_RATE_LIMIT_INTERVAL_MAX ), +#endif + + REG_VARIABLE( CFG_ENABLE_HOST_SSDP_NAME, WLAN_PARAM_Integer, + hdd_config_t, ssdp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HOST_SSDP_DEFAULT, + CFG_ENABLE_HOST_SSDP_MIN, + CFG_ENABLE_HOST_SSDP_MAX ), + +#ifdef FEATURE_SECURE_FIRMWARE + REG_VARIABLE(CFG_ENABLE_FW_HASH_CHECK_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_fw_hash_check, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_HASH_CHECK_DEFAULT, + CFG_ENABLE_FW_HASH_CHECK_MIN, + CFG_ENABLE_FW_HASH_CHECK_MAX), +#endif + + REG_VARIABLE( CFG_ENABLE_HOST_NSOFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fhostNSOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HOST_NSOFFLOAD_DEFAULT, + CFG_ENABLE_HOST_NSOFFLOAD_MIN, + CFG_ENABLE_HOST_NSOFFLOAD_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, tsInfoAckPolicy, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX ), + + REG_VARIABLE( CFG_SINGLE_TID_RC_NAME, WLAN_PARAM_Integer, + hdd_config_t, bSingleTidRc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SINGLE_TID_RC_DEFAULT, + CFG_SINGLE_TID_RC_MIN, + CFG_SINGLE_TID_RC_MAX), + + REG_VARIABLE( CFG_DYNAMIC_PSPOLL_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, dynamicPsPollValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DYNAMIC_PSPOLL_VALUE_DEFAULT, + CFG_DYNAMIC_PSPOLL_VALUE_MIN, + CFG_DYNAMIC_PSPOLL_VALUE_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_WAKEUP_EN_NAME, WLAN_PARAM_Integer, + hdd_config_t, teleBcnWakeupEn, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_WAKEUP_EN_DEFAULT, + CFG_TELE_BCN_WAKEUP_EN_MIN, + CFG_TELE_BCN_WAKEUP_EN_MAX ), + + REG_VARIABLE( CFG_INFRA_STA_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, infraStaKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, AddTSWhenACMIsOff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX ), + + + REG_VARIABLE( CFG_VALIDATE_SCAN_LIST_NAME , WLAN_PARAM_Integer, + hdd_config_t, fValidateScanList, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VALIDATE_SCAN_LIST_DEFAULT, + CFG_VALIDATE_SCAN_LIST_MIN, + CFG_VALIDATE_SCAN_LIST_MAX ), + + REG_VARIABLE( CFG_NULLDATA_AP_RESP_TIMEOUT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNullDataApRespTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NULLDATA_AP_RESP_TIMEOUT_DEFAULT, + CFG_NULLDATA_AP_RESP_TIMEOUT_MIN, + CFG_NULLDATA_AP_RESP_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apDataAvailPollPeriodInMs, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ), + + REG_VARIABLE( CFG_ENABLE_BTAMP_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableBtAmp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BTAMP_DEFAULT, + CFG_ENABLE_BTAMP_MIN, + CFG_ENABLE_BTAMP_MAX ), + +#ifdef WLAN_BTAMP_FEATURE + REG_VARIABLE( CFG_BT_AMP_PREFERRED_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, preferredChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BT_AMP_PREFERRED_CHANNEL_DEFAULT, + CFG_BT_AMP_PREFERRED_CHANNEL_MIN, + CFG_BT_AMP_PREFERRED_CHANNEL_MAX ), +#endif //WLAN_BTAMP_FEATURE + + REG_VARIABLE( CFG_BAND_CAPABILITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBandCapability, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BAND_CAPABILITY_DEFAULT, + CFG_BAND_CAPABILITY_MIN, + CFG_BAND_CAPABILITY_MAX ), + + REG_VARIABLE( CFG_ENABLE_BEACON_EARLY_TERMINATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableBeaconEarlyTermination, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BEACON_EARLY_TERMINATION_DEFAULT, + CFG_ENABLE_BEACON_EARLY_TERMINATION_MIN, + CFG_ENABLE_BEACON_EARLY_TERMINATION_MAX ), + +/* CFG_VOS_TRACE_ENABLE Parameters */ + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_BAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableBAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_TL_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableTL, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_WDI_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableWDI, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_HDD_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableHDD, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SME_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSME, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_PE_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnablePE, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_PMC_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnablePMC, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_WDA_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableWDA, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SYS_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSYS, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_VOSS_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableVOSS, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_HDD_SAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableHDDSAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_TRANS_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnTransListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_TRANS_LI_DEFAULT, + CFG_TELE_BCN_TRANS_LI_MIN, + CFG_TELE_BCN_TRANS_LI_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnTransLiNumIdleBeacons, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_DEFAULT, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MIN, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_MAX_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnMaxListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_MAX_LI_DEFAULT, + CFG_TELE_BCN_MAX_LI_MIN, + CFG_TELE_BCN_MAX_LI_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnMaxLiNumIdleBeacons, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_DEFAULT, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MIN, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MAX ), + + REG_VARIABLE( CFG_BCN_EARLY_TERM_WAKE_NAME, WLAN_PARAM_Integer, + hdd_config_t, bcnEarlyTermWakeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BCN_EARLY_TERM_WAKE_DEFAULT, + CFG_BCN_EARLY_TERM_WAKE_MIN, + CFG_BCN_EARLY_TERM_WAKE_MAX ), + + REG_VARIABLE( CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apDataAvailPollPeriodInMs, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ), + + REG_VARIABLE( CFG_ENABLE_CLOSE_LOOP_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableCloseLoop, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_CLOSE_LOOP_DEFAULT, + CFG_ENABLE_CLOSE_LOOP_MIN, + CFG_ENABLE_CLOSE_LOOP_MAX ), + + REG_VARIABLE( CFG_ENABLE_BYPASS_11D_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableBypass11d, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BYPASS_11D_DEFAULT, + CFG_ENABLE_BYPASS_11D_MIN, + CFG_ENABLE_BYPASS_11D_MAX ), + + REG_VARIABLE( CFG_ENABLE_DFS_CHNL_SCAN_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDFSChnlScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT, + CFG_ENABLE_DFS_CHNL_SCAN_MIN, + CFG_ENABLE_DFS_CHNL_SCAN_MAX ), + + REG_VARIABLE( CFG_ENABLE_DYNAMIC_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDynamicDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DYNAMIC_DTIM_DEFAULT, + CFG_ENABLE_DYNAMIC_DTIM_MIN, + CFG_ENABLE_DYNAMIC_DTIM_MAX ), + + REG_VARIABLE( CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableAutomaticTxPowerControl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_DEFAULT, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MIN, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MAX ), + + REG_VARIABLE( CFG_SHORT_GI_40MHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortGI40MhzEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_GI_40MHZ_DEFAULT, + CFG_SHORT_GI_40MHZ_MIN, + CFG_SHORT_GI_40MHZ_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_REPORT_MAX_LINK_SPEED, WLAN_PARAM_Integer, + hdd_config_t, reportMaxLinkSpeed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REPORT_MAX_LINK_SPEED_DEFAULT, + CFG_REPORT_MAX_LINK_SPEED_MIN, + CFG_REPORT_MAX_LINK_SPEED_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_HIGH, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiHigh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_HIGH_DEFAULT, + CFG_LINK_SPEED_RSSI_HIGH_MIN, + CFG_LINK_SPEED_RSSI_HIGH_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_MID, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiMid, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_MID_DEFAULT, + CFG_LINK_SPEED_RSSI_MID_MIN, + CFG_LINK_SPEED_RSSI_MID_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_LOW, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiLow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_LOW_DEFAULT, + CFG_LINK_SPEED_RSSI_LOW_MIN, + CFG_LINK_SPEED_RSSI_LOW_MAX, + NULL, 0 ), + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + REG_DYNAMIC_VARIABLE( CFG_ROAM_PREFER_5GHZ, WLAN_PARAM_Integer, + hdd_config_t, nRoamPrefer5GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_PREFER_5GHZ_DEFAULT, + CFG_ROAM_PREFER_5GHZ_MIN, + CFG_ROAM_PREFER_5GHZ_MAX, + cbNotifySetRoamPrefer5GHz, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_INTRA_BAND, WLAN_PARAM_Integer, + hdd_config_t, nRoamIntraBand, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_INTRA_BAND_DEFAULT, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX, + cbNotifySetRoamIntraBand, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_N_PROBES, WLAN_PARAM_Integer, + hdd_config_t, nProbes, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_N_PROBES_DEFAULT, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX, + cbNotifySetRoamScanNProbes, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_HOME_AWAY_TIME, WLAN_PARAM_Integer, + hdd_config_t, nRoamScanHomeAwayTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX, + cbNotifySetRoamScanHomeAwayTime, 0 ), + +#endif + + REG_VARIABLE( CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isP2pDeviceAddrAdministrated, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_DEFAULT, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MIN, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MAX ), + + REG_VARIABLE( CFG_ENABLE_MCC_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableMCC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MCC_ENABLED_DEFAULT, + CFG_ENABLE_MCC_ENABLED_MIN, + CFG_ENABLE_MCC_ENABLED_MAX ), + + REG_VARIABLE( CFG_ALLOW_MCC_GO_DIFF_BI_NAME, WLAN_PARAM_Integer, + hdd_config_t, allowMCCGODiffBI, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT, + CFG_ALLOW_MCC_GO_DIFF_BI_MIN, + CFG_ALLOW_MCC_GO_DIFF_BI_MAX ), + + REG_VARIABLE( CFG_THERMAL_MIGRATION_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalMitigationEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_MIGRATION_ENABLE_DEFAULT, + CFG_THERMAL_MIGRATION_ENABLE_MIN, + CFG_THERMAL_MIGRATION_ENABLE_MAX ), + + REG_VARIABLE( CFG_THROTTLE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, throttlePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THROTTLE_PERIOD_DEFAULT, + CFG_THROTTLE_PERIOD_MIN, + CFG_THROTTLE_PERIOD_MAX ), + + REG_VARIABLE( CFG_ENABLE_MODULATED_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableModulatedDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MODULATED_DTIM_DEFAULT, + CFG_ENABLE_MODULATED_DTIM_MIN, + CFG_ENABLE_MODULATED_DTIM_MAX ), + + REG_VARIABLE( CFG_MC_ADDR_LIST_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableMCAddrList, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MC_ADDR_LIST_ENABLE_DEFAULT, + CFG_MC_ADDR_LIST_ENABLE_MIN, + CFG_MC_ADDR_LIST_ENABLE_MAX ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_VHT_CHANNEL_WIDTH, WLAN_PARAM_Integer, + hdd_config_t, vhtChannelWidth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_CHANNEL_WIDTH_DEFAULT, + CFG_VHT_CHANNEL_WIDTH_MIN, + CFG_VHT_CHANNEL_WIDTH_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_RX_MCS_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtRxMCS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_RX_MCS_8_9_DEFAULT, + CFG_VHT_ENABLE_RX_MCS_8_9_MIN, + CFG_VHT_ENABLE_RX_MCS_8_9_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_TX_MCS_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtTxMCS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_TX_MCS_8_9_DEFAULT, + CFG_VHT_ENABLE_TX_MCS_8_9_MIN, + CFG_VHT_ENABLE_TX_MCS_8_9_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_RX_MCS2x2_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtRxMCS2x2, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_RX_MCS2x2_8_9_DEFAULT, + CFG_VHT_ENABLE_RX_MCS2x2_8_9_MIN, + CFG_VHT_ENABLE_RX_MCS2x2_8_9_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_TX_MCS2x2_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtTxMCS2x2, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_TX_MCS2x2_8_9_DEFAULT, + CFG_VHT_ENABLE_TX_MCS2x2_8_9_MIN, + CFG_VHT_ENABLE_TX_MCS2x2_8_9_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_2x2_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enable2x2, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_2x2_CAP_FEATURE_DEFAULT, + CFG_VHT_ENABLE_2x2_CAP_FEATURE_MIN, + CFG_VHT_ENABLE_2x2_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableMuBformee, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_DEFAULT, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MIN, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_VHT_ENABLE_PAID_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableVhtpAid, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_PAID_FEATURE_DEFAULT, + CFG_VHT_ENABLE_PAID_FEATURE_MIN, + CFG_VHT_ENABLE_PAID_FEATURE_MAX ), + + REG_VARIABLE( CFG_VHT_ENABLE_GID_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableVhtGid, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_GID_FEATURE_DEFAULT, + CFG_VHT_ENABLE_GID_FEATURE_MIN, + CFG_VHT_ENABLE_GID_FEATURE_MAX ), +#endif + + REG_VARIABLE( CFG_VHT_ENABLE_1x1_TX_CHAINMASK, WLAN_PARAM_Integer, + hdd_config_t, txchainmask1x1, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_1x1_TX_CHAINMASK_DEFAULT, + CFG_VHT_ENABLE_1x1_TX_CHAINMASK_MIN, + CFG_VHT_ENABLE_1x1_TX_CHAINMASK_MAX ), + + REG_VARIABLE( CFG_VHT_ENABLE_1x1_RX_CHAINMASK, WLAN_PARAM_Integer, + hdd_config_t, rxchainmask1x1, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_1x1_RX_CHAINMASK_DEFAULT, + CFG_VHT_ENABLE_1x1_RX_CHAINMASK_MIN, + CFG_VHT_ENABLE_1x1_RX_CHAINMASK_MAX ), + + REG_VARIABLE( CFG_ENABLE_AMPDUPS_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableAmpduPs, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_AMPDUPS_FEATURE_DEFAULT, + CFG_ENABLE_AMPDUPS_FEATURE_MIN, + CFG_ENABLE_AMPDUPS_FEATURE_MAX ), + + REG_VARIABLE( CFG_HT_ENABLE_SMPS_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableHtSmps, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_HT_ENABLE_SMPS_CAP_FEATURE_DEFAULT, + CFG_HT_ENABLE_SMPS_CAP_FEATURE_MIN, + CFG_HT_ENABLE_SMPS_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_HT_SMPS_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, htSmps, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_HT_SMPS_CAP_FEATURE_DEFAULT, + CFG_HT_SMPS_CAP_FEATURE_MIN, + CFG_HT_SMPS_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_DISABLE_DFS_CH_SWITCH, WLAN_PARAM_Integer, + hdd_config_t, disableDFSChSwitch, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_DFS_CH_SWITCH_DEFAULT, + CFG_DISABLE_DFS_CH_SWITCH_MIN, + CFG_DISABLE_DFS_CH_SWITCH_MAX ), + + REG_VARIABLE( CFG_ENABLE_DFS_MASTER_CAPABILITY, WLAN_PARAM_Integer, + hdd_config_t, enableDFSMasterCap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DFS_MASTER_CAPABILITY_DEFAULT, + CFG_ENABLE_DFS_MASTER_CAPABILITY_MIN, + CFG_ENABLE_DFS_MASTER_CAPABILITY_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_SAP_PREFERRED_CHANNEL_LOCATION, WLAN_PARAM_Integer, + hdd_config_t, gSapPreferredChanLocation, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_PREFERRED_CHANNEL_LOCATION_DEFAULT, + CFG_SAP_PREFERRED_CHANNEL_LOCATION_MIN, + CFG_SAP_PREFERRED_CHANNEL_LOCATION_MAX, + cbNotify_set_gSapPreferredChanLocation, 0), + + REG_DYNAMIC_VARIABLE( CFG_DISABLE_DFS_JAPAN_W53, WLAN_PARAM_Integer, + hdd_config_t, gDisableDfsJapanW53, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_DFS_JAPAN_W53_DEFAULT, + CFG_DISABLE_DFS_JAPAN_W53_MIN, + CFG_DISABLE_DFS_JAPAN_W53_MAX, + chNotify_set_gDisableDfsJapanW53, 0), + + REG_VARIABLE( CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableFirstScan2GOnly, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX ), + + REG_VARIABLE( CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_NAME, WLAN_PARAM_Integer, + hdd_config_t, skipDfsChnlInP2pSearch, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_DEFAULT, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MIN, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MAX ), + + REG_VARIABLE( CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, ignoreDynamicDtimInP2pMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_DEFAULT, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MIN, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MAX ), + + REG_VARIABLE( CFG_NUM_BUFF_ADVERT_NAME, WLAN_PARAM_Integer, + hdd_config_t,numBuffAdvert , + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_NUM_BUFF_ADVERT_DEFAULT, + CFG_NUM_BUFF_ADVERT_MIN, + CFG_NUM_BUFF_ADVERT_MAX ), + + REG_VARIABLE( CFG_MCC_CONFIG_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, configMccParam, + VAR_FLAGS_OPTIONAL, + CFG_MCC_CONFIG_PARAM_DEFAULT, + CFG_MCC_CONFIG_PARAM_MIN, + CFG_MCC_CONFIG_PARAM_MAX ), + + REG_VARIABLE( CFG_ENABLE_RX_STBC, WLAN_PARAM_Integer, + hdd_config_t, enableRxSTBC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_RX_STBC_DEFAULT, + CFG_ENABLE_RX_STBC_MIN, + CFG_ENABLE_RX_STBC_MAX ), + + REG_VARIABLE( CFG_ENABLE_TX_STBC, WLAN_PARAM_Integer, + hdd_config_t, enableTxSTBC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_TX_STBC_DEFAULT, + CFG_ENABLE_TX_STBC_MIN, + CFG_ENABLE_TX_STBC_MAX ), + + REG_VARIABLE( CFG_ENABLE_RX_LDPC, WLAN_PARAM_Integer, + hdd_config_t, enableRxLDPC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_RX_LDPC_DEFAULT, + CFG_ENABLE_RX_LDPC_MIN, + CFG_ENABLE_RX_LDPC_MAX ), + + REG_VARIABLE( CFG_PPS_ENABLE_5G_EBT, WLAN_PARAM_Integer, + hdd_config_t, enable5gEBT, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PPS_ENABLE_5G_EBT_FEATURE_DEFAULT, + CFG_PPS_ENABLE_5G_EBT_FEATURE_MIN, + CFG_PPS_ENABLE_5G_EBT_FEATURE_MAX ), + +#ifdef FEATURE_WLAN_TDLS + REG_VARIABLE( CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_SUPPORT_ENABLE_MIN, + CFG_TDLS_SUPPORT_ENABLE_MAX ), + + REG_VARIABLE( CFG_TDLS_IMPLICIT_TRIGGER, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSImplicitTrigger, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IMPLICIT_TRIGGER_DEFAULT, + CFG_TDLS_IMPLICIT_TRIGGER_MIN, + CFG_TDLS_IMPLICIT_TRIGGER_MAX ), + + REG_VARIABLE( CFG_TDLS_TX_STATS_PERIOD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSTxStatsPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_TX_STATS_PERIOD_DEFAULT, + CFG_TDLS_TX_STATS_PERIOD_MIN, + CFG_TDLS_TX_STATS_PERIOD_MAX ), + + REG_VARIABLE( CFG_TDLS_TX_PACKET_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSTxPacketThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT, + CFG_TDLS_TX_PACKET_THRESHOLD_MIN, + CFG_TDLS_TX_PACKET_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_DISCOVERY_PERIOD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSDiscoveryPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_DISCOVERY_PERIOD_DEFAULT, + CFG_TDLS_DISCOVERY_PERIOD_MIN, + CFG_TDLS_DISCOVERY_PERIOD_MAX ), + + REG_VARIABLE( CFG_TDLS_MAX_DISCOVERY_ATTEMPT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSMaxDiscoveryAttempt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_DEFAULT, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX ), + + REG_VARIABLE( CFG_TDLS_IDLE_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSIdleTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IDLE_TIMEOUT_DEFAULT, + CFG_TDLS_IDLE_TIMEOUT_MIN, + CFG_TDLS_IDLE_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_TDLS_IDLE_PACKET_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSIdlePacketThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_HYSTERESIS, WLAN_PARAM_Integer, + hdd_config_t, fTDLSRSSIHysteresis, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_HYSTERESIS_DEFAULT, + CFG_TDLS_RSSI_HYSTERESIS_MIN, + CFG_TDLS_RSSI_HYSTERESIS_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_TRIGGER_THRESHOLD, WLAN_PARAM_SignedInteger, + hdd_config_t, fTDLSRSSITriggerThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_DEFAULT, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_TEARDOWN_THRESHOLD, WLAN_PARAM_SignedInteger, + hdd_config_t, fTDLSRSSITeardownThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_DEFAULT, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_DELTA, WLAN_PARAM_SignedInteger, + hdd_config_t, fTDLSRSSIDelta, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_DELTA_DEFAULT, + CFG_TDLS_RSSI_DELTA_MIN, + CFG_TDLS_RSSI_DELTA_MAX ), + + REG_VARIABLE( CFG_TDLS_QOS_WMM_UAPSD_MASK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, fTDLSUapsdMask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_QOS_WMM_UAPSD_MASK_DEFAULT, + CFG_TDLS_QOS_WMM_UAPSD_MASK_MIN, + CFG_TDLS_QOS_WMM_UAPSD_MASK_MAX ), + + REG_VARIABLE( CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSBufferSta, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MIN, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MAX ), + + REG_VARIABLE( CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSOffChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX ), + + REG_VARIABLE( CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPrefOffChanNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX ), + + REG_VARIABLE( CFG_TDLS_PREFERRED_OFF_CHANNEL_BW, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPrefOffChanBandwidth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MIN, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MAX ), + + REG_VARIABLE( CFG_TDLS_PUAPSD_INACTIVITY_TIME, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdInactivityTimer, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEFAULT, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX ), + + REG_VARIABLE( CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSRxFrameThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdPTIWindow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MIN, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MAX ), + + REG_VARIABLE( CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdPTRTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MIN, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_TDLS_EXTERNAL_CONTROL, WLAN_PARAM_Integer, + hdd_config_t, fTDLSExternalControl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_EXTERNAL_CONTROL_DEFAULT, + CFG_TDLS_EXTERNAL_CONTROL_MIN, + CFG_TDLS_EXTERNAL_CONTROL_MAX ), + + REG_VARIABLE( CFG_TDLS_WMM_MODE_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSWmmMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_WMM_MODE_ENABLE_DEFAULT, + CFG_TDLS_WMM_MODE_ENABLE_MIN, + CFG_TDLS_WMM_MODE_ENABLE_MAX ), + + REG_VARIABLE( CFG_TDLS_SCAN_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, enable_tdls_scan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_SCAN_ENABLE_DEFAULT, + CFG_TDLS_SCAN_ENABLE_MIN, + CFG_TDLS_SCAN_ENABLE_MAX ), +#endif + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + REG_VARIABLE( CFG_VSTA_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableVSTASupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VSTA_SUPPORT_ENABLE_DEFAULT, + CFG_VSTA_SUPPORT_ENABLE_MIN, + CFG_VSTA_SUPPORT_ENABLE_MAX ), +#endif + REG_VARIABLE( CFG_ENABLE_LPWR_IMG_TRANSITION_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableLpwrImgTransition, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_MIN, + CFG_ENABLE_LPWR_IMG_TRANSITION_MAX ), + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + REG_VARIABLE( CFG_ACTIVEMODE_OFFLOAD_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableActiveModeOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_DEFAULT, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_MIN, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_MAX ), +#endif + REG_VARIABLE( CFG_ENABLE_LPWR_IMG_TRANSITION_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableLpwrImgTransition, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_MIN, + CFG_ENABLE_LPWR_IMG_TRANSITION_MAX ), + + + REG_VARIABLE( CFG_SCAN_AGING_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, scanAgingTimeout, + VAR_FLAGS_OPTIONAL, + CFG_SCAN_AGING_PARAM_DEFAULT, + CFG_SCAN_AGING_PARAM_MIN, + CFG_SCAN_AGING_PARAM_MAX ), + + REG_VARIABLE( CFG_TX_LDPC_ENABLE_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableTxLdpc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT, + CFG_TX_LDPC_ENABLE_FEATURE_MIN, + CFG_TX_LDPC_ENABLE_FEATURE_MAX ), + + REG_VARIABLE( CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableMCCAdaptiveScheduler, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ), + + REG_VARIABLE( CFG_ANDRIOD_POWER_SAVE_NAME, WLAN_PARAM_Integer, + hdd_config_t, isAndroidPsEn, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ANDRIOD_POWER_SAVE_DEFAULT, + CFG_ANDRIOD_POWER_SAVE_MIN, + CFG_ANDRIOD_POWER_SAVE_MAX), + + REG_VARIABLE( CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, AdHocChannel5G, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX), + + REG_VARIABLE( CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, AdHocChannel24G, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableTxBF, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_DEFAULT, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_VHT_ENABLE_TXBF_IN_20MHZ, WLAN_PARAM_Integer, + hdd_config_t, enableTxBFin20MHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_DEFAULT, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_MIN, + CFG_VHT_ENABLE_TXBF_IN_20MHZ_MAX ), + + REG_VARIABLE( CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, WLAN_PARAM_Integer, + hdd_config_t, txBFCsnValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_DEFAULT, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MIN, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX ), +#endif + + REG_VARIABLE( CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, sapAllowAllChannel, + VAR_FLAGS_OPTIONAL, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_DEFAULT, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MIN, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MAX ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_DISABLE_LDPC_WITH_TXBF_AP, WLAN_PARAM_Integer, + hdd_config_t, disableLDPCWithTxbfAP, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT, + CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN, + CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX ), +#endif + + REG_VARIABLE_STRING( CFG_LIST_OF_NON_DFS_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, listOfNonDfsCountryCode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + (void *)CFG_LIST_OF_NON_DFS_COUNTRY_CODE_DEFAULT), + + REG_DYNAMIC_VARIABLE( CFG_ENABLE_SSR, WLAN_PARAM_Integer, + hdd_config_t, enableSSR, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SSR_DEFAULT, + CFG_ENABLE_SSR_MIN, + CFG_ENABLE_SSR_MAX, + cbNotifySetEnableSSR, 0 ), + + REG_VARIABLE_STRING( CFG_LIST_OF_NON_11AC_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, listOfNon11acCountryCode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + (void *)CFG_LIST_OF_NON_11AC_COUNTRY_CODE_DEFAULT), + + REG_VARIABLE( CFG_MAX_MEDIUM_TIME, WLAN_PARAM_Integer, + hdd_config_t, cfgMaxMediumTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_MEDIUM_TIME_STADEFAULT, + CFG_MAX_MEDIUM_TIME_STAMIN, + CFG_MAX_MEDIUM_TIME_STAMAX ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_ENABLE_VHT_FOR_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableVhtFor24GHzBand, + VAR_FLAGS_OPTIONAL, + CFG_ENABLE_VHT_FOR_24GHZ_DEFAULT, + CFG_ENABLE_VHT_FOR_24GHZ_MIN, + CFG_ENABLE_VHT_FOR_24GHZ_MAX), +#endif + + REG_VARIABLE( CFG_SCAN_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fScanOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SCAN_OFFLOAD_DEFAULT, + CFG_SCAN_OFFLOAD_DISABLE, + CFG_SCAN_OFFLOAD_ENABLE ), + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + REG_DYNAMIC_VARIABLE( CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY, WLAN_PARAM_Integer, + hdd_config_t, bFastRoamInConIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX, + cbNotifySetEnableFastRoamInConcurrency, 0 ), +#endif + + REG_VARIABLE( CFG_ENABLE_ADAPT_RX_DRAIN_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableAdaptRxDrain, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_ENABLE_ADAPT_RX_DRAIN_DEFAULT, + CFG_ENABLE_ADAPT_RX_DRAIN_MIN, + CFG_ENABLE_ADAPT_RX_DRAIN_MAX), + + REG_VARIABLE( CFG_DYNAMIC_SPLIT_SCAN_NAME, WLAN_PARAM_Integer, + hdd_config_t, dynSplitscan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DYNAMIC_SPLIT_SCAN_DEFAULT, + CFG_DYNAMIC_SPLIT_SCAN_MIN, + CFG_DYNAMIC_SPLIT_SCAN_MAX ), + + REG_VARIABLE( CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, txRxThresholdForSplitScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MIN, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MAX ), + + REG_VARIABLE( CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_NAME, WLAN_PARAM_Integer, + hdd_config_t, trafficMntrTmrForSplitScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MIN, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MAX ), + + REG_VARIABLE( CFG_FLEX_CONNECT_POWER_FACTOR_NAME, WLAN_PARAM_Integer, + hdd_config_t, flexConnectPowerFactor, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_MINMAX, + CFG_FLEX_CONNECT_POWER_FACTOR_DEFAULT, + CFG_FLEX_CONNECT_POWER_FACTOR_MIN, + CFG_FLEX_CONNECT_POWER_FACTOR_MAX ), + + REG_VARIABLE( CFG_ENABLE_HEART_BEAT_OFFLOAD, WLAN_PARAM_Integer, + hdd_config_t, enableIbssHeartBeatOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HEART_BEAT_OFFLOAD_DEFAULT, + CFG_ENABLE_HEART_BEAT_OFFLOAD_MIN, + CFG_ENABLE_HEART_BEAT_OFFLOAD_MAX), + + REG_VARIABLE( CFG_ANTENNA_DIVERSITY_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, antennaDiversity, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ANTENNA_DIVERSITY_PARAM_DEFAULT, + CFG_ANTENNA_DIVERSITY_PARAM_MIN, + CFG_ANTENNA_DIVERSITY_PARAM_MAX), + + REG_VARIABLE( CFG_ENABLE_SNR_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableSNRMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_ENABLE_SNR_MONITORING_DEFAULT, + CFG_ENABLE_SNR_MONITORING_MIN, + CFG_ENABLE_SNR_MONITORING_MAX), + +#ifdef FEATURE_WLAN_SCAN_PNO + REG_VARIABLE( CFG_PNO_SCAN_SUPPORT, WLAN_PARAM_Integer, + hdd_config_t, configPNOScanSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PNO_SCAN_SUPPORT_DEFAULT, + CFG_PNO_SCAN_SUPPORT_DISABLE, + CFG_PNO_SCAN_SUPPORT_ENABLE), + + REG_VARIABLE( CFG_PNO_SCAN_TIMER_REPEAT_VALUE, WLAN_PARAM_Integer, + hdd_config_t, configPNOScanTimerRepeatValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX), +#endif + REG_VARIABLE( CFG_AMSDU_SUPPORT_IN_AMPDU_NAME , WLAN_PARAM_Integer, + hdd_config_t, isAmsduSupportInAMPDU, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AMSDU_SUPPORT_IN_AMPDU_DEFAULT, + CFG_AMSDU_SUPPORT_IN_AMPDU_MIN, + CFG_AMSDU_SUPPORT_IN_AMPDU_MAX ), + + REG_VARIABLE( CFG_STRICT_5GHZ_PREF_BY_MARGIN , WLAN_PARAM_Integer, + hdd_config_t, nSelect5GHzMargin, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_DEFAULT, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_MIN, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_MAX ), + + REG_VARIABLE( CFG_ENABLE_TCP_CHKSUM_OFFLOAD, WLAN_PARAM_Integer, + hdd_config_t, enableTCPChkSumOffld, + VAR_FLAGS_OPTIONAL, + CFG_ENABLE_TCP_CHKSUM_OFFLOAD_DEFAULT, + CFG_ENABLE_TCP_CHKSUM_OFFLOAD_MIN, + CFG_ENABLE_TCP_CHKSUM_OFFLOAD_MAX), + + REG_VARIABLE( CFG_ENABLE_IP_CHKSUM_OFFLOAD, WLAN_PARAM_Integer, + hdd_config_t, enableIPChecksumOffload, + VAR_FLAGS_OPTIONAL, + CFG_ENABLE_IP_CHKSUM_OFFLOAD_DEFAULT, + CFG_ENABLE_IP_CHKSUM_OFFLOAD_DISABLE, + CFG_ENABLE_IP_CHKSUM_OFFLOAD_ENABLE ), + + REG_VARIABLE( CFG_POWERSAVE_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, enablePowersaveOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_POWERSAVE_OFFLOAD_DEFAULT, + CFG_POWERSAVE_OFFLOAD_MIN, + CFG_POWERSAVE_OFFLOAD_MAX ), + + REG_VARIABLE( CFG_ENABLE_FW_UART_PRINT_NAME, WLAN_PARAM_Integer, + hdd_config_t, enablefwprint, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_UART_PRINT_DEFAULT, + CFG_ENABLE_FW_UART_PRINT_DISABLE, + CFG_ENABLE_FW_UART_PRINT_ENABLE), + + REG_VARIABLE( CFG_ENABLE_FW_LOG_NAME, WLAN_PARAM_Integer, + hdd_config_t, enablefwlog, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_LOG_DEFAULT, + CFG_ENABLE_FW_LOG_DISABLE, + CFG_ENABLE_FW_LOG_ENABLE), + + REG_VARIABLE( CFG_ENABLE_FW_SELF_RECOVERY_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableFwSelfRecovery, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_SELF_RECOVERY_DEFAULT, + CFG_ENABLE_FW_SELF_RECOVERY_DISABLE, + CFG_ENABLE_FW_SELF_RECOVERY_ENABLE), + +#ifdef IPA_OFFLOAD + REG_VARIABLE( CFG_IPA_OFFLOAD_CONFIG_NAME, WLAN_PARAM_HexInteger, + hdd_config_t, IpaConfig, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IPA_OFFLOAD_CONFIG_DEFAULT, + CFG_IPA_OFFLOAD_CONFIG_MIN, + CFG_IPA_OFFLOAD_CONFIG_MAX), + + REG_VARIABLE( CFG_IPA_DESC_SIZE_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaDescSize, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IPA_DESC_SIZE_DEFAULT, + CFG_IPA_DESC_SIZE_MIN, + CFG_IPA_DESC_SIZE_MAX ), + + REG_VARIABLE( CFG_IPA_HIGH_BANDWIDTH_MBPS, WLAN_PARAM_Integer, + hdd_config_t, IpaHighBandwidthMbps, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IPA_HIGH_BANDWIDTH_MBPS_DEFAULT, + CFG_IPA_HIGH_BANDWIDTH_MBPS_MIN, + CFG_IPA_HIGH_BANDWIDTH_MBPS_MAX), + + REG_VARIABLE( CFG_IPA_MEDIUM_BANDWIDTH_MBPS, WLAN_PARAM_Integer, + hdd_config_t, IpaMediumBandwidthMbps, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IPA_MEDIUM_BANDWIDTH_MBPS_DEFAULT, + CFG_IPA_MEDIUM_BANDWIDTH_MBPS_MIN, + CFG_IPA_MEDIUM_BANDWIDTH_MBPS_MAX), + + REG_VARIABLE( CFG_IPA_LOW_BANDWIDTH_MBPS, WLAN_PARAM_Integer, + hdd_config_t, IpaLowBandwidthMbps, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IPA_LOW_BANDWIDTH_MBPS_DEFAULT, + CFG_IPA_LOW_BANDWIDTH_MBPS_MIN, + CFG_IPA_LOW_BANDWIDTH_MBPS_MAX), +#endif + REG_VARIABLE( CFG_P2P_LISTEN_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fP2pListenOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_P2P_LISTEN_OFFLOAD_DEFAULT, + CFG_P2P_LISTEN_OFFLOAD_DISABLE, + CFG_P2P_LISTEN_OFFLOAD_ENABLE ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_VHT_AMPDU_LEN_EXPONENT_NAME, WLAN_PARAM_Integer, + hdd_config_t, fVhtAmpduLenExponent, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_VHT_AMPDU_LEN_EXPONENT_DEFAULT, + CFG_VHT_AMPDU_LEN_EXPONENT_MIN, + CFG_VHT_AMPDU_LEN_EXPONENT_MAX), + + REG_VARIABLE( CFG_VHT_MPDU_LEN_NAME, WLAN_PARAM_Integer, + hdd_config_t, vhtMpduLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_VHT_MPDU_LEN_DEFAULT, + CFG_VHT_MPDU_LEN_MIN, + CFG_VHT_MPDU_LEN_MAX), +#endif + + REG_VARIABLE( CFG_MAX_WOW_FILTERS_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxWoWFilters, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_MAX_WOW_FILTERS_DEFAULT, + CFG_MAX_WOW_FILTERS_MIN, + CFG_MAX_WOW_FILTERS_MAX), + + REG_VARIABLE( CFG_WOW_STATUS_NAME, WLAN_PARAM_Integer, + hdd_config_t, wowEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WOW_STATUS_DEFAULT, + CFG_WOW_ENABLE_MIN, + CFG_WOW_ENABLE_MAX), + + REG_VARIABLE( CFG_COALESING_IN_IBSS_NAME , WLAN_PARAM_Integer, + hdd_config_t, isCoalesingInIBSSAllowed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_COALESING_IN_IBSS_DEFAULT, + CFG_COALESING_IN_IBSS_MIN, + CFG_COALESING_IN_IBSS_MAX ), + + REG_VARIABLE( CFG_IBSS_ATIM_WIN_SIZE_NAME , WLAN_PARAM_Integer, + hdd_config_t, ibssATIMWinSize, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_ATIM_WIN_SIZE_DEFAULT, + CFG_IBSS_ATIM_WIN_SIZE_MIN, + CFG_IBSS_ATIM_WIN_SIZE_MAX ), + + REG_VARIABLE( CFG_SAP_MAX_NO_PEERS, WLAN_PARAM_Integer, + hdd_config_t, maxNumberOfPeers, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_MAX_NO_PEERS_DEFAULT, + CFG_SAP_MAX_NO_PEERS_MIN, + CFG_SAP_MAX_NO_PEERS_MAX), + + REG_VARIABLE( CFG_IBSS_IS_POWER_SAVE_ALLOWED_NAME , WLAN_PARAM_Integer, + hdd_config_t, isIbssPowerSaveAllowed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_IS_POWER_SAVE_ALLOWED_DEFAULT, + CFG_IBSS_IS_POWER_SAVE_ALLOWED_MIN, + CFG_IBSS_IS_POWER_SAVE_ALLOWED_MAX ), + + REG_VARIABLE( CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_NAME , WLAN_PARAM_Integer, + hdd_config_t, isIbssPowerCollapseAllowed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_DEFAULT, + CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MIN, + CFG_IBSS_IS_POWER_COLLAPSE_ALLOWED_MAX ), + + REG_VARIABLE( CFG_IBSS_AWAKE_ON_TX_RX_NAME , WLAN_PARAM_Integer, + hdd_config_t, isIbssAwakeOnTxRx, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_AWAKE_ON_TX_RX_DEFAULT, + CFG_IBSS_AWAKE_ON_TX_RX_MIN, + CFG_IBSS_AWAKE_ON_TX_RX_MAX ), + + REG_VARIABLE( CFG_IBSS_INACTIVITY_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, ibssInactivityCount, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_INACTIVITY_TIME_DEFAULT, + CFG_IBSS_INACTIVITY_TIME_MIN, + CFG_IBSS_INACTIVITY_TIME_MAX ), + + REG_VARIABLE( CFG_IBSS_TXSP_END_INACTIVITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, ibssTxSpEndInactivityTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_TXSP_END_INACTIVITY_DEFAULT, + CFG_IBSS_TXSP_END_INACTIVITY_MIN, + CFG_IBSS_TXSP_END_INACTIVITY_MAX ), + + REG_VARIABLE( CFG_IBSS_PS_WARMUP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, ibssPsWarmupTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_PS_WARMUP_TIME_DEFAULT, + CFG_IBSS_PS_WARMUP_TIME_MIN, + CFG_IBSS_PS_WARMUP_TIME_MAX ), + + REG_VARIABLE( CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_NAME, WLAN_PARAM_Integer, + hdd_config_t, ibssPs1RxChainInAtimEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_DEFAULT, + CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MIN, + CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MIN_LEVEL0_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMinLevel0, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL0_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL0_MIN, + CFG_THERMAL_TEMP_MIN_LEVEL0_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MAX_LEVEL0_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMaxLevel0, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL0_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL0_MIN, + CFG_THERMAL_TEMP_MAX_LEVEL0_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MIN_LEVEL1_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMinLevel1, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL1_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL1_MIN, + CFG_THERMAL_TEMP_MIN_LEVEL1_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MAX_LEVEL1_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMaxLevel1, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL1_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL1_MIN, + CFG_THERMAL_TEMP_MAX_LEVEL1_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MIN_LEVEL2_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMinLevel2, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL2_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL2_MIN, + CFG_THERMAL_TEMP_MIN_LEVEL2_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MAX_LEVEL2_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMaxLevel2, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL2_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL2_MIN, + CFG_THERMAL_TEMP_MAX_LEVEL2_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MIN_LEVEL3_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMinLevel3, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL3_DEFAULT, + CFG_THERMAL_TEMP_MIN_LEVEL3_MIN, + CFG_THERMAL_TEMP_MIN_LEVEL3_MAX ), + + REG_VARIABLE( CFG_THERMAL_TEMP_MAX_LEVEL3_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalTempMaxLevel3, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL3_DEFAULT, + CFG_THERMAL_TEMP_MAX_LEVEL3_MIN, + CFG_THERMAL_TEMP_MAX_LEVEL3_MAX ), + + REG_VARIABLE( CFG_SET_TXPOWER_LIMIT2G_NAME , WLAN_PARAM_Integer, + hdd_config_t, TxPower2g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SET_TXPOWER_LIMIT2G_DEFAULT, + CFG_SET_TXPOWER_LIMIT2G_MIN, + CFG_SET_TXPOWER_LIMIT2G_MAX ), + + REG_VARIABLE( CFG_SET_TXPOWER_LIMIT5G_NAME , WLAN_PARAM_Integer, + hdd_config_t, TxPower5g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SET_TXPOWER_LIMIT5G_DEFAULT, + CFG_SET_TXPOWER_LIMIT5G_MIN, + CFG_SET_TXPOWER_LIMIT5G_MAX ), + + REG_VARIABLE( CFG_ENABLE_DEBUG_CONNECT_ISSUE, WLAN_PARAM_Integer, + hdd_config_t, gEnableDebugLog, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN , + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX), + + REG_VARIABLE( CFG_ENABLE_RX_THREAD, WLAN_PARAM_Integer, + hdd_config_t, enableRxThread, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_RX_THREAD_DEFAULT, + CFG_ENABLE_RX_THREAD_MIN, + CFG_ENABLE_RX_THREAD_MAX), + + REG_VARIABLE( CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fDfsPhyerrFilterOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT, + CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN, + CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX ), + + REG_VARIABLE( CFG_ENABLE_OVERLAP_CH, WLAN_PARAM_Integer, + hdd_config_t, gEnableOverLapCh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENABLE_OVERLAP_CH_DEFAULT, + CFG_ENABLE_OVERLAP_CH_MIN, + CFG_ENABLE_OVERLAP_CH_MAX ), + + REG_VARIABLE_STRING( CFG_ONLY_ALLOWED_CHANNELS, WLAN_PARAM_String, + hdd_config_t, acsAllowedChnls, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL, + (void *)CFG_ONLY_ALLOWED_CHANNELS_DEFAULT), + + REG_VARIABLE( CFG_REG_CHANGE_DEF_COUNTRY_NAME, WLAN_PARAM_Integer, + hdd_config_t, fRegChangeDefCountry, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REG_CHANGE_DEF_COUNTRY_DEFAULT, + CFG_REG_CHANGE_DEF_COUNTRY_MIN, + CFG_REG_CHANGE_DEF_COUNTRY_MAX), + + REG_VARIABLE( CFG_SAP_SCAN_BAND_PREFERENCE, WLAN_PARAM_Integer, + hdd_config_t, acsScanBandPreference, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT, + CFG_SAP_SCAN_BAND_PREFERENCE_MIN, + CFG_SAP_SCAN_BAND_PREFERENCE_MAX ), + +#ifdef QCA_LL_TX_FLOW_CT + REG_VARIABLE( CFG_LL_TX_FLOW_LWM, WLAN_PARAM_Integer, + hdd_config_t, TxFlowLowWaterMark, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_FLOW_LWM_DEFAULT, + CFG_LL_TX_FLOW_LWM_MIN, + CFG_LL_TX_FLOW_LWM_MAX ), + + REG_VARIABLE( CFG_LL_TX_FLOW_HWM_OFFSET, WLAN_PARAM_Integer, + hdd_config_t, TxFlowHighWaterMarkOffset, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_FLOW_HWM_OFFSET_DEFAULT, + CFG_LL_TX_FLOW_HWM_OFFSET_MIN, + CFG_LL_TX_FLOW_HWM_OFFSET_MAX ), + + REG_VARIABLE( CFG_LL_TX_FLOW_MAX_Q_DEPTH, WLAN_PARAM_Integer, + hdd_config_t, TxFlowMaxQueueDepth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_FLOW_MAX_Q_DEPTH_DEFAULT, + CFG_LL_TX_FLOW_MAX_Q_DEPTH_MIN, + CFG_LL_TX_FLOW_MAX_Q_DEPTH_MAX ), + + REG_VARIABLE( CFG_LL_TX_LBW_FLOW_LWM, WLAN_PARAM_Integer, + hdd_config_t, TxLbwFlowLowWaterMark, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_LBW_FLOW_LWM_DEFAULT, + CFG_LL_TX_LBW_FLOW_LWM_MIN, + CFG_LL_TX_LBW_FLOW_LWM_MAX ), + + REG_VARIABLE( CFG_LL_TX_LBW_FLOW_HWM_OFFSET, WLAN_PARAM_Integer, + hdd_config_t, TxLbwFlowHighWaterMarkOffset, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_LBW_FLOW_HWM_OFFSET_DEFAULT, + CFG_LL_TX_LBW_FLOW_HWM_OFFSET_MIN, + CFG_LL_TX_LBW_FLOW_HWM_OFFSET_MAX ), + + REG_VARIABLE( CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH, WLAN_PARAM_Integer, + hdd_config_t, TxLbwFlowMaxQueueDepth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_DEFAULT, + CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_MIN, + CFG_LL_TX_LBW_FLOW_MAX_Q_DEPTH_MAX ), + + REG_VARIABLE( CFG_LL_TX_HBW_FLOW_LWM, WLAN_PARAM_Integer, + hdd_config_t, TxHbwFlowLowWaterMark, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_HBW_FLOW_LWM_DEFAULT, + CFG_LL_TX_HBW_FLOW_LWM_MIN, + CFG_LL_TX_HBW_FLOW_LWM_MAX ), + + REG_VARIABLE( CFG_LL_TX_HBW_FLOW_HWM_OFFSET, WLAN_PARAM_Integer, + hdd_config_t, TxHbwFlowHighWaterMarkOffset, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_HBW_FLOW_HWM_OFFSET_DEFAULT, + CFG_LL_TX_HBW_FLOW_HWM_OFFSET_MIN, + CFG_LL_TX_HBW_FLOW_HWM_OFFSET_MAX ), + + REG_VARIABLE( CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH, WLAN_PARAM_Integer, + hdd_config_t, TxHbwFlowMaxQueueDepth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_DEFAULT, + CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_MIN, + CFG_LL_TX_HBW_FLOW_MAX_Q_DEPTH_MAX ), +#endif /* QCA_LL_TX_FLOW_CT */ + + REG_VARIABLE( CFG_INITIAL_DWELL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nInitialDwellTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INITIAL_DWELL_TIME_DEFAULT, + CFG_INITIAL_DWELL_TIME_MIN, + CFG_INITIAL_DWELL_TIME_MAX ), + + REG_VARIABLE( CFG_INITIAL_SCAN_NO_DFS_CHNL_NAME, WLAN_PARAM_Integer, + hdd_config_t, initial_scan_no_dfs_chnl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INITIAL_SCAN_NO_DFS_CHNL_DEFAULT, + CFG_INITIAL_SCAN_NO_DFS_CHNL_MIN, + CFG_INITIAL_SCAN_NO_DFS_CHNL_MAX ), + + REG_VARIABLE( CFG_ACS_BAND_SWITCH_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, acsBandSwitchThreshold, +#ifndef WLAN_FEATURE_MBSSID + VAR_FLAGS_DYNAMIC_CFG | +#endif + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ACS_BAND_SWITCH_THRESHOLD_DEFAULT, + CFG_ACS_BAND_SWITCH_THRESHOLD_MIN, + CFG_ACS_BAND_SWITCH_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_NAME, WLAN_PARAM_Integer, + hdd_config_t, gEnableStrictRegulatoryForFCC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_DEFAULT, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MIN, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MAX ), + + REG_VARIABLE( CFG_SAP_MAX_OFFLOAD_PEERS, WLAN_PARAM_Integer, + hdd_config_t, apMaxOffloadPeers, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_MAX_OFFLOAD_PEERS_DEFAULT, + CFG_SAP_MAX_OFFLOAD_PEERS_MIN, + CFG_SAP_MAX_OFFLOAD_PEERS_MAX ), + + REG_VARIABLE( CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS, WLAN_PARAM_Integer, + hdd_config_t, apMaxOffloadReorderBuffs, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_DEFAULT, + CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_MIN, + CFG_SAP_MAX_OFFLOAD_REORDER_BUFFS_MAX ), + + REG_VARIABLE( CFG_ADVERTISE_CONCURRENT_OPERATION_NAME , WLAN_PARAM_Integer, + hdd_config_t, advertiseConcurrentOperation, + VAR_FLAGS_OPTIONAL, + CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT, + CFG_ADVERTISE_CONCURRENT_OPERATION_MIN, + CFG_ADVERTISE_CONCURRENT_OPERATION_MAX ), + + REG_VARIABLE( CFG_ENABLE_MEMORY_DEEP_SLEEP, WLAN_PARAM_Integer, + hdd_config_t, enableMemDeepSleep, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MEMORY_DEEP_SLEEP_DEFAULT, + CFG_ENABLE_MEMORY_DEEP_SLEEP_MIN, + CFG_ENABLE_MEMORY_DEEP_SLEEP_MAX ), + + REG_VARIABLE( CFG_DEFAULT_RATE_INDEX_24GH, WLAN_PARAM_Integer, + hdd_config_t, defaultRateIndex24Ghz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DEFAULT_RATE_INDEX_24GH_DEFAULT, + CFG_DEFAULT_RATE_INDEX_24GH_MIN, + CFG_DEFAULT_RATE_INDEX_24GH_MAX ), + + REG_VARIABLE_STRING( CFG_OVERRIDE_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, overrideCountryCode, + VAR_FLAGS_OPTIONAL, + (void *)CFG_OVERRIDE_COUNTRY_CODE_DEFAULT), + + REG_VARIABLE( CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, debugP2pRemainOnChannel, + VAR_FLAGS_OPTIONAL, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_DEFAULT, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MIN, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MAX ), + + REG_VARIABLE( CFG_ENABLE_PACKET_LOG, WLAN_PARAM_Integer, + hdd_config_t, enablePacketLog, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_PACKET_LOG_DEFAULT, + CFG_ENABLE_PACKET_LOG_MIN, + CFG_ENABLE_PACKET_LOG_MAX ), + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + REG_VARIABLE( CFG_ROAMING_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, isRoamOffloadEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ROAMING_OFFLOAD_DEFAULT, + CFG_ROAMING_OFFLOAD_MIN, + CFG_ROAMING_OFFLOAD_MAX), +#endif +#ifdef MSM_PLATFORM + REG_VARIABLE( CFG_BUS_BANDWIDTH_HIGH_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, busBandwidthHighThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_DEFAULT, + CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_MIN, + CFG_BUS_BANDWIDTH_HIGH_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, busBandwidthMediumThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_DEFAULT, + CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_MIN, + CFG_BUS_BANDWIDTH_MEDIUM_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_BUS_BANDWIDTH_LOW_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, busBandwidthLowThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BUS_BANDWIDTH_LOW_THRESHOLD_DEFAULT, + CFG_BUS_BANDWIDTH_LOW_THRESHOLD_MIN, + CFG_BUS_BANDWIDTH_LOW_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, busBandwidthComputeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_DEFAULT, + CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_MIN, + CFG_BUS_BANDWIDTH_COMPUTE_INTERVAL_MAX), + + REG_VARIABLE( CFG_TCP_DELACK_THRESHOLD_HIGH, WLAN_PARAM_Integer, + hdd_config_t, tcpDelackThresholdHigh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_HIGH_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_HIGH_MIN, + CFG_TCP_DELACK_THRESHOLD_HIGH_MAX ), + + REG_VARIABLE( CFG_TCP_DELACK_THRESHOLD_LOW, WLAN_PARAM_Integer, + hdd_config_t, tcpDelackThresholdLow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_LOW_MIN, + CFG_TCP_DELACK_THRESHOLD_LOW_MAX ), +#endif + + + REG_VARIABLE( CFG_ENABLE_FW_LOG_TYPE , WLAN_PARAM_Integer, + hdd_config_t, enableFwLogType, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_LOG_TYPE_DEFAULT, + CFG_ENABLE_FW_LOG_TYPE_MIN, + CFG_ENABLE_FW_LOG_TYPE_MAX ), + + REG_VARIABLE( CFG_ENABLE_FW_DEBUG_LOG_LEVEL, WLAN_PARAM_Integer, + hdd_config_t, enableFwLogLevel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_DEBUG_LOG_LEVEL_DEFAULT, + CFG_ENABLE_FW_DEBUG_LOG_LEVEL_MIN, + CFG_ENABLE_FW_DEBUG_LOG_LEVEL_MAX ), + + REG_VARIABLE_STRING( CFG_ENABLE_FW_MODULE_LOG_LEVEL, WLAN_PARAM_String, + hdd_config_t, enableFwModuleLogLevel, + VAR_FLAGS_OPTIONAL, + (void *) CFG_ENABLE_FW_MODULE_LOG_DEFAULT), + + + +#ifdef WLAN_FEATURE_11W + REG_VARIABLE(CFG_PMF_SA_QUERY_MAX_RETRIES_NAME, WLAN_PARAM_Integer, + hdd_config_t, pmfSaQueryMaxRetries, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PMF_SA_QUERY_MAX_RETRIES_DEFAULT, + CFG_PMF_SA_QUERY_MAX_RETRIES_MIN, + CFG_PMF_SA_QUERY_MAX_RETRIES_MAX ), + + REG_VARIABLE(CFG_PMF_SA_QUERY_RETRY_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, pmfSaQueryRetryInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_DEFAULT, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_MIN, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_MAX ), +#endif + REG_VARIABLE(CFG_MAX_CONCURRENT_CONNECTIONS_NAME, WLAN_PARAM_Integer, + hdd_config_t, gMaxConcurrentActiveSessions, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_CONCURRENT_CONNECTIONS_DEFAULT, + CFG_MAX_CONCURRENT_CONNECTIONS_MIN, + CFG_MAX_CONCURRENT_CONNECTIONS_MAX ), + +#ifdef QCA_HT_2040_COEX + REG_VARIABLE(CFG_ENABLE_HT_2040_COEX, WLAN_PARAM_Integer, + hdd_config_t, ht2040CoexEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HT_2040_COEX_DEFAULT, + CFG_ENABLE_HT_2040_COEX_MIN, + CFG_ENABLE_HT_2040_COEX_MAX ), +#endif + +#ifdef FEATURE_GREEN_AP + REG_VARIABLE( CFG_ENABLE_GREEN_AP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableGreenAP, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_GREEN_AP_FEATURE_DEFAULT, + CFG_ENABLE_GREEN_AP_FEATURE_MIN, + CFG_ENABLE_GREEN_AP_FEATURE_MAX ), +#endif + + REG_VARIABLE(CFG_IGNORE_CAC_NAME, WLAN_PARAM_Integer, + hdd_config_t, ignoreCAC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_CAC_DEFAULT, + CFG_IGNORE_CAC_MIN, + CFG_IGNORE_CAC_MAX), + + REG_VARIABLE(CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_NAME, WLAN_PARAM_Integer, + hdd_config_t, IsSapDfsChSifsBurstEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_DEFAULT, + CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_MIN, + CFG_ENABLE_SAP_DFS_CH_SIFS_BURST_MAX ), + + REG_VARIABLE(CFG_DFS_RADAR_PRI_MULTIPLIER_NAME, WLAN_PARAM_Integer, + hdd_config_t, dfsRadarPriMultiplier, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT, + CFG_DFS_RADAR_PRI_MULTIPLIER_MIN, + CFG_DFS_RADAR_PRI_MULTIPLIER_MAX), + + REG_VARIABLE( CFG_REORDER_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, reorderOffloadSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_OFFLOAD_SUPPORT_DEFAULT, + CFG_REORDER_OFFLOAD_SUPPORT_MIN, + CFG_REORDER_OFFLOAD_SUPPORT_MAX ), +#ifdef IPA_UC_OFFLOAD + REG_VARIABLE( CFG_IPA_UC_OFFLOAD_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaUcOffloadEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_IPA_UC_OFFLOAD_ENABLED_DEFAULT, + CFG_IPA_UC_OFFLOAD_ENABLED_MIN, + CFG_IPA_UC_OFFLOAD_ENABLED_MAX ), + + REG_VARIABLE( CFG_IPA_UC_TX_BUF_COUNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaUcTxBufCount, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_IPA_UC_TX_BUF_COUNT_DEFAULT, + CFG_IPA_UC_TX_BUF_COUNT_MIN, + CFG_IPA_UC_TX_BUF_COUNT_MAX ), + + REG_VARIABLE( CFG_IPA_UC_TX_BUF_SIZE_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaUcTxBufSize, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_IPA_UC_TX_BUF_SIZE_DEFAULT, + CFG_IPA_UC_TX_BUF_SIZE_MIN, + CFG_IPA_UC_TX_BUF_SIZE_MAX ), + + REG_VARIABLE( CFG_IPA_UC_RX_IND_RING_COUNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaUcRxIndRingCount, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_IPA_UC_RX_IND_RING_COUNT_DEFAULT, + CFG_IPA_UC_RX_IND_RING_COUNT_MIN, + CFG_IPA_UC_RX_IND_RING_COUNT_MAX ), + + REG_VARIABLE( CFG_IPA_UC_TX_PARTITION_BASE_NAME, WLAN_PARAM_Integer, + hdd_config_t, IpaUcTxPartitionBase, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_IPA_UC_TX_PARTITION_BASE_DEFAULT, + CFG_IPA_UC_TX_PARTITION_BASE_MIN, + CFG_IPA_UC_TX_PARTITION_BASE_MAX ), +#endif /* IPA_UC_OFFLOAD */ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + REG_VARIABLE(CFG_WLAN_LOGGING_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_SUPPORT_DEFAULT, + CFG_WLAN_LOGGING_SUPPORT_DISABLE, + CFG_WLAN_LOGGING_SUPPORT_ENABLE ), + + REG_VARIABLE(CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingFEToConsole, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DISABLE, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_ENABLE ), + + REG_VARIABLE(CFG_WLAN_LOGGING_NUM_BUF_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingNumBuf, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_NUM_BUF_DEFAULT, + CFG_WLAN_LOGGING_NUM_BUF_MIN, + CFG_WLAN_LOGGING_NUM_BUF_MAX ), +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ + + REG_VARIABLE( CFG_ENABLE_SIFS_BURST, WLAN_PARAM_Integer, + hdd_config_t, enableSifsBurst, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SIFS_BURST_DEFAULT, + CFG_ENABLE_SIFS_BURST_MIN, + CFG_ENABLE_SIFS_BURST_MAX ), + +#ifdef WLAN_FEATURE_LPSS + REG_VARIABLE(CFG_ENABLE_LPASS_SUPPORT, WLAN_PARAM_Integer, + hdd_config_t, enablelpasssupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LPASS_SUPPORT_DEFAULT, + CFG_ENABLE_LPASS_SUPPORT_MIN, + CFG_ENABLE_LPASS_SUPPORT_MAX), +#endif + + REG_VARIABLE( CFG_ENABLE_SELF_RECOVERY, WLAN_PARAM_Integer, + hdd_config_t, enableSelfRecovery, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SELF_RECOVERY_DEFAULT, + CFG_ENABLE_SELF_RECOVERY_MIN, + CFG_ENABLE_SELF_RECOVERY_MAX ), + +#ifdef FEATURE_WLAN_FORCE_SAP_SCC + REG_VARIABLE(CFG_SAP_SCC_CHAN_AVOIDANCE, WLAN_PARAM_Integer, + hdd_config_t, SapSccChanAvoidance, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_SCC_CHAN_AVOIDANCE_DEFAULT, + CFG_SAP_SCC_CHAN_AVOIDANCE_MIN, + CFG_SAP_SCC_CHAN_AVOIDANCE_MAX), +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + + REG_VARIABLE( CFG_ENABLE_SAP_SUSPEND, WLAN_PARAM_Integer, + hdd_config_t, enableSapSuspend, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SAP_SUSPEND_DEFAULT, + CFG_ENABLE_SAP_SUSPEND_MIN, + CFG_ENABLE_SAP_SUSPEND_MAX ), + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + REG_VARIABLE( CFG_EXTWOW_GO_TO_SUSPEND, WLAN_PARAM_Integer, + hdd_config_t, extWowGotoSuspend, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_GO_TO_SUSPEND_DEFAULT, + CFG_EXTWOW_GO_TO_SUSPEND_MIN, + CFG_EXTWOW_GO_TO_SUSPEND_MAX ), + + REG_VARIABLE( CFG_EXTWOW_APP1_WAKE_PIN_NUMBER, WLAN_PARAM_Integer, + hdd_config_t, extWowApp1WakeupPinNumber, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_DEFAULT, + CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_MIN, + CFG_EXTWOW_APP1_WAKE_PIN_NUMBER_MAX ), + + REG_VARIABLE( CFG_EXTWOW_APP2_WAKE_PIN_NUMBER, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2WakeupPinNumber, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_DEFAULT, + CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_MIN, + CFG_EXTWOW_APP2_WAKE_PIN_NUMBER_MAX ), + + REG_VARIABLE( CFG_EXTWOW_KA_INIT_PING_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2KAInitPingInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_KA_INIT_PING_INTERVAL_DEFAULT, + CFG_EXTWOW_KA_INIT_PING_INTERVAL_MIN, + CFG_EXTWOW_KA_INIT_PING_INTERVAL_MAX ), + + REG_VARIABLE( CFG_EXTWOW_KA_MIN_PING_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2KAMinPingInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_KA_MIN_PING_INTERVAL_DEFAULT, + CFG_EXTWOW_KA_MIN_PING_INTERVAL_MIN, + CFG_EXTWOW_KA_MIN_PING_INTERVAL_MAX ), + + REG_VARIABLE( CFG_EXTWOW_KA_MAX_PING_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2KAMaxPingInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_KA_MAX_PING_INTERVAL_DEFAULT, + CFG_EXTWOW_KA_MAX_PING_INTERVAL_MIN, + CFG_EXTWOW_KA_MAX_PING_INTERVAL_MAX ), + + REG_VARIABLE( CFG_EXTWOW_KA_INC_PING_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2KAIncPingInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_KA_INC_PING_INTERVAL_DEFAULT, + CFG_EXTWOW_KA_INC_PING_INTERVAL_MIN, + CFG_EXTWOW_KA_INC_PING_INTERVAL_MAX ), + + REG_VARIABLE( CFG_EXTWOW_TCP_SRC_PORT, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2TcpSrcPort, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_TCP_SRC_PORT_DEFAULT, + CFG_EXTWOW_TCP_SRC_PORT_MIN, + CFG_EXTWOW_TCP_SRC_PORT_MAX ), + + REG_VARIABLE( CFG_EXTWOW_TCP_DST_PORT, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2TcpDstPort, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_TCP_DST_PORT_DEFAULT, + CFG_EXTWOW_TCP_DST_PORT_MIN, + CFG_EXTWOW_TCP_DST_PORT_MAX ), + + REG_VARIABLE( CFG_EXTWOW_TCP_TX_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2TcpTxTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_TCP_TX_TIMEOUT_DEFAULT, + CFG_EXTWOW_TCP_TX_TIMEOUT_MIN, + CFG_EXTWOW_TCP_TX_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_EXTWOW_TCP_RX_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, extWowApp2TcpRxTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTWOW_TCP_RX_TIMEOUT_DEFAULT, + CFG_EXTWOW_TCP_RX_TIMEOUT_MIN, + CFG_EXTWOW_TCP_RX_TIMEOUT_MAX ), +#endif + REG_VARIABLE( CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, gEnableDeauthToDisassocMap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_DEFAULT, + CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MIN, + CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP_MAX ), + + REG_VARIABLE( CFG_ENABLE_MAC_ADDR_SPOOFING, WLAN_PARAM_Integer, + hdd_config_t, enable_mac_spoofing, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT, + CFG_ENABLE_MAC_ADDR_SPOOFING_MIN, + CFG_ENABLE_MAC_ADDR_SPOOFING_MAX ), + REG_VARIABLE(CFG_SAP_DOT11MC, WLAN_PARAM_Integer, + hdd_config_t, sap_dot11mc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_DOT11MC_DEFAULT, + CFG_SAP_DOT11MC_MIN, + CFG_SAP_DOT11MC_MAX ), + REG_VARIABLE(CFG_INFORM_BSS_RSSI_RAW_NAME, WLAN_PARAM_Integer, + hdd_config_t, inform_bss_rssi_raw, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INFORM_BSS_RSSI_RAW_DEFAULT, + CFG_INFORM_BSS_RSSI_RAW_MIN, + CFG_INFORM_BSS_RSSI_RAW_MAX), + + REG_VARIABLE(CFG_DROPPED_PKT_DISCONNECT_TH_NAME, WLAN_PARAM_Integer, + hdd_config_t, pkt_err_disconn_th, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DROPPED_PKT_DISCONNECT_TH_DEFAULT, + CFG_DROPPED_PKT_DISCONNECT_TH_MIN, + CFG_DROPPED_PKT_DISCONNECT_TH_MAX), +}; + +#ifdef WLAN_FEATURE_MBSSID +REG_TABLE_ENTRY mbssid_sap_dyn_ini_reg_table[] = +{ + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_START_CHANNEL , WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, apStartChannelNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT + | VAR_FLAGS_DYNAMIC_CFG, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_END_CHANNEL , WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, apEndChannelNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT + | VAR_FLAGS_DYNAMIC_CFG, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SAP_CHANNEL_SELECT_OPERATING_BAND , WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, apOperatingBand, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT + | VAR_FLAGS_DYNAMIC_CFG, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_DEFAULT, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MIN, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MAX ), + + REG_VARIABLE( CFG_SAP_AUTO_CHANNEL_SELECTION_NAME , WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, apAutoChannelSelection, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT + | VAR_FLAGS_DYNAMIC_CFG, + CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT, + CFG_SAP_AUTO_CHANNEL_SELECTION_MIN, + CFG_SAP_AUTO_CHANNEL_SELECTION_MAX ), + + + REG_VARIABLE_STRING( CFG_ONLY_ALLOWED_CHANNELS, WLAN_PARAM_String, + mbssid_sap_dyn_ini_config_t, acsAllowedChnls, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_DYNAMIC_CFG, + (void *)CFG_ONLY_ALLOWED_CHANNELS_DEFAULT), + + REG_VARIABLE( CFG_SAP_SCAN_BAND_PREFERENCE, WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, acsScanBandPreference, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK + | VAR_FLAGS_DYNAMIC_CFG, + CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT, + CFG_SAP_SCAN_BAND_PREFERENCE_MIN, + CFG_SAP_SCAN_BAND_PREFERENCE_MAX ), + + REG_VARIABLE( CFG_ACS_BAND_SWITCH_THRESHOLD, WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, acsBandSwitchThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK + | VAR_FLAGS_DYNAMIC_CFG, + CFG_ACS_BAND_SWITCH_THRESHOLD_DEFAULT, + CFG_ACS_BAND_SWITCH_THRESHOLD_MIN, + CFG_ACS_BAND_SWITCH_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_SAP_FORCE_11AC_FOR_11N, WLAN_PARAM_Integer, + mbssid_sap_dyn_ini_config_t, apForce11ACFor11n, + VAR_FLAGS_DYNAMIC_CFG | + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_FORCE_11AC_FOR_11N_DEFAULT, + CFG_SAP_FORCE_11AC_FOR_11N_MIN, + CFG_SAP_FORCE_11AC_FOR_11N_MAX ), + + REG_VARIABLE(CFG_P2P_LISTEN_DEFER_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, p2p_listen_defer_interval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_P2P_LISTEN_DEFER_INTERVAL_DEFAULT, + CFG_P2P_LISTEN_DEFER_INTERVAL_MIN, + CFG_P2P_LISTEN_DEFER_INTERVAL_MAX), +}; +#endif + +/* + * This function returns a pointer to the character after the occurrence + * of a new line character. It also modifies the original string by replacing + * the '\n' character with the null character. + * Function returns NULL if no new line character was found before end of + * string was reached + */ +static char* get_next_line(char* str) +{ + char c; + + if( str == NULL || *str == '\0') { + return NULL; + } + + c = *str; + while(c != '\n' && c != '\0' && c != 0xd) { + str = str + 1; + c = *str; + } + + if (c == '\0' ) { + return NULL; + } + else + { + *str = '\0'; + return (str+1); + } + + return NULL; +} + +// look for space. Ascii values to look are - +// 0x09 == horizontal tab +// 0x0a == Newline ("\n") +// 0x0b == vertical tab +// 0x0c == Newpage or feed form. +// 0x0d == carriage return (CR or "\r") +// Null ('\0') should not considered as space. +#define i_isspace(ch) (((ch) >= 0x09 && (ch) <= 0x0d) || (ch) == ' ') + +/* + * This function trims any leading and trailing white spaces + */ +static char *i_trim(char *str) + +{ + char *ptr; + + if(*str == '\0') return str; + + /* Find the first non white-space*/ + for (ptr = str; i_isspace(*ptr); ptr++); + if (*ptr == '\0') + return str; + + /* This is the new start of the string*/ + str = ptr; + + /* Find the last non white-space */ + ptr += strlen(ptr) - 1; + for (; ptr != str && i_isspace(*ptr); ptr--); + /* Null terminate the following character */ + ptr[1] = '\0'; + + return str; +} + + +//Structure to store each entry in qcom_cfg.ini file +typedef struct +{ + char *name; + char *value; +}tCfgIniEntry; + +static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t * pHddCtx, + tCfgIniEntry* iniTable, unsigned long entries); + +#ifdef WLAN_CFG_DEBUG +void dump_cfg_ini (tCfgIniEntry* iniTable, unsigned long entries) +{ + unsigned long i; + + for (i = 0; i < entries; i++) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s entry Name=[%s] value=[%s]", + WLAN_INI_FILE, iniTable[i].name, iniTable[i].value); + } +} +#endif + +/* + * This function reads the qcom_cfg.ini file and + * parses each 'Name=Value' pair in the ini file + */ +VOS_STATUS hdd_parse_config_ini(hdd_context_t* pHddCtx) +{ + int status, i=0; + /** Pointer for firmware image data */ + const struct firmware *fw = NULL; + char *buffer, *line, *pTemp = NULL; + size_t size; + char *name, *value; + /* cfgIniTable is static to avoid excess stack usage */ + static tCfgIniEntry cfgIniTable[MAX_CFG_INI_ITEMS]; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + memset(cfgIniTable, 0, sizeof(cfgIniTable)); + + status = request_firmware(&fw, WLAN_INI_FILE, pHddCtx->parent_dev); + + if(status) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: request_firmware failed %d",__func__, status); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + if(!fw || !fw->data || !fw->size) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: %s download failed", + __func__, WLAN_INI_FILE); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + + hddLog(LOG1, "%s: qcom_cfg.ini Size %zu", __func__, fw->size); + + buffer = (char*)vos_mem_malloc(fw->size); + + if(NULL == buffer) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: kmalloc failure",__func__); + release_firmware(fw); + return VOS_STATUS_E_FAILURE; + } + pTemp = buffer; + + vos_mem_copy((void*)buffer,(void *)fw->data, fw->size); + size = fw->size; + + while (buffer != NULL) + { + line = get_next_line(buffer); + buffer = i_trim(buffer); + + hddLog(LOG1, "%s: item", buffer); + + if(strlen((char*)buffer) == 0 || *buffer == '#') { + buffer = line; + continue; + } + else if(strncmp(buffer, "END", 3) == 0 ) { + break; + } + else + { + name = buffer; + while(*buffer != '=' && *buffer != '\0') + buffer++; + if(*buffer != '\0') { + *buffer++ = '\0'; + i_trim(name); + if(strlen (name) != 0) { + buffer = i_trim(buffer); + if(strlen(buffer)>0) { + value = buffer; + while(!i_isspace(*buffer) && *buffer != '\0') + buffer++; + *buffer = '\0'; + cfgIniTable[i].name= name; + cfgIniTable[i++].value= value; + if(i >= MAX_CFG_INI_ITEMS) { + hddLog(LOGE,"%s: Number of items in %s > %d", + __func__, WLAN_INI_FILE, MAX_CFG_INI_ITEMS); + break; + } + } + } + } + } + buffer = line; + } + + //Loop through the registry table and apply all these configs + vos_status = hdd_apply_cfg_ini(pHddCtx, cfgIniTable, i); + +config_exit: + release_firmware(fw); + vos_mem_free(pTemp); + return vos_status; +} + + +void print_hdd_cfg(hdd_context_t *pHddCtx) +{ + int i; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "*********Config values in HDD Adapter*******"); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RTSThreshold] Value = %u",pHddCtx->cfg_ini->RTSThreshold) ; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [OperatingChannel] Value = [%u]",pHddCtx->cfg_ini->OperatingChannel); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [PowerUsageControl] Value = [%s]",pHddCtx->cfg_ini->PowerUsageControl); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fIsImpsEnabled] Value = [%u]",pHddCtx->cfg_ini->fIsImpsEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [AutoBmpsTimerEnabled] Value = [%u]",pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nAutoBmpsTimerValue] Value = [%u]",pHddCtx->cfg_ini->nAutoBmpsTimerValue); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nVccRssiTrigger] Value = [%u]",pHddCtx->cfg_ini->nVccRssiTrigger); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gIbssBssid] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->IbssBssid.bytes)); + + for (i=0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [Intf%dMacAddress] Value =["MAC_ADDRESS_STR"]", + i, MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes)); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApEnableUapsd] value = [%u]",pHddCtx->cfg_ini->apUapsdEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAPCntryCode] Value =[%c%c%c]", + pHddCtx->cfg_ini->apCntryCode[0],pHddCtx->cfg_ini->apCntryCode[1], + pHddCtx->cfg_ini->apCntryCode[2]); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableApProt] value = [%u]", pHddCtx->cfg_ini->apProtEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAPAutoShutOff] Value = [%u]", pHddCtx->cfg_ini->nAPAutoShutOff); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gWlanMccToSccSwitchMode] Value = [%u]", pHddCtx->cfg_ini->WlanMccToSccSwitchMode); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gWlanAutoShutdown] Value = [%u]", pHddCtx->cfg_ini->WlanAutoShutdown); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableListenMode] Value = [%u]", pHddCtx->cfg_ini->nEnableListenMode); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApProtection] value = [%u]",pHddCtx->cfg_ini->apProtection); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableApOBSSProt] value = [%u]",pHddCtx->cfg_ini->apOBSSProtEnabled); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApAutoChannelSelection] value = [%u]",pHddCtx->cfg_ini->apAutoChannelSelection); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gACSAllowedChannels] value = [%s]", pHddCtx->cfg_ini->acsAllowedChnls); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gACSBandSwitchThreshold] value = [%u]", pHddCtx->cfg_ini->acsBandSwitchThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode24GHz); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode5GHz); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [dot11Mode] Value = [%u]",pHddCtx->cfg_ini->dot11Mode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WmmMode] Value = [%u] ",pHddCtx->cfg_ini->WmmMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [UapsdMask] Value = [0x%x] ",pHddCtx->cfg_ini->UapsdMask); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [PktClassificationBasis] Value = [%u] ",pHddCtx->cfg_ini->PktClassificationBasis); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ImplicitQosIsEnabled] Value = [%u]",(int)pHddCtx->cfg_ini->bImplicitQosEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdVoSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdVoSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdVoSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdVoSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdViSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdViSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdViSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdViSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBeSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBeSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBeSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBeSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBkSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBkSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBkSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBkSuspIntv); +#ifdef FEATURE_WLAN_ESE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraInactivityInterval] Value = [%u] ",pHddCtx->cfg_ini->InfraInactivityInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [EseEnabled] Value = [%u] ",pHddCtx->cfg_ini->isEseIniFeatureEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [FastTransitionEnabled] Value = [%u] ",pHddCtx->cfg_ini->isFastTransitionEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gTxPowerCap] Value = [%u] dBm ",pHddCtx->cfg_ini->nTxPowerCap); +#endif +#ifdef FEATURE_WLAN_LFR + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [FastRoamEnabled] Value = [%u] ",pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [MAWCEnabled] Value = [%u] ",pHddCtx->cfg_ini->MAWCEnabled); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RoamRssiDiff] Value = [%u] ",pHddCtx->cfg_ini->RoamRssiDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ImmediateRoamRssiDiff] Value = [%u] ",pHddCtx->cfg_ini->nImmediateRoamRssiDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [isWESModeEnabled] Value = [%u] ",pHddCtx->cfg_ini->isWESModeEnabled); +#endif +#ifdef FEATURE_WLAN_OKC + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [OkcEnabled] Value = [%u] ",pHddCtx->cfg_ini->isOkcIniFeatureEnabled); +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [configPNOScanSupport] Value = [%u] ",pHddCtx->cfg_ini->configPNOScanSupport); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [configPNOScanTimerRepeatValue] Value = [%u] ",pHddCtx->cfg_ini->configPNOScanTimerRepeatValue); +#endif +#ifdef FEATURE_WLAN_TDLS + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableTDLSSupport] Value = [%u] ",pHddCtx->cfg_ini->fEnableTDLSSupport); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableTDLSImplicitTrigger] Value = [%u] ",pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fTDLSExternalControl] Value = [%u] ",pHddCtx->cfg_ini->fTDLSExternalControl); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fTDLSUapsdMask] Value = [%u] ",pHddCtx->cfg_ini->fTDLSUapsdMask); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableTDLSBufferSta] Value = [%u] ",pHddCtx->cfg_ini->fEnableTDLSBufferSta); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableTDLSWmmMode] Value = [%u] ",pHddCtx->cfg_ini->fEnableTDLSWmmMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [enable_tdls_scan] Value = [%u]", + pHddCtx->cfg_ini->enable_tdls_scan); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcVo] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcVo); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcVi] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcVi); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcBe] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcBe); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcBk] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcBk); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqBkWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqBkWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqBeWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqBeWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqViWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqViWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqVoWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqVoWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [DelayedTriggerFrmInt] Value = [%u] ",pHddCtx->cfg_ini->DelayedTriggerFrmInt); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BkReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->BkReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BeReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->BeReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ViReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->ViReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [VoReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->VoReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [mcastBcastFilterSetting] Value = [%u] ",pHddCtx->cfg_ini->mcastBcastFilterSetting); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fhostArpOffload] Value = [%u] ",pHddCtx->cfg_ini->fhostArpOffload); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ssdp] Value = [%u] ", pHddCtx->cfg_ini->ssdp); +#ifdef FEATURE_SECURE_FIRMWARE + hddLog(LOG2, "Name = [enable_fw_hash_check] Value = [%u]", + pHddCtx->cfg_ini->enable_fw_hash_check); +#endif +#ifdef FEATURE_WLAN_RA_FILTERING + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RArateLimitInterval] Value = [%u] ", pHddCtx->cfg_ini->RArateLimitInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [IsRArateLimitEnabled] Value = [%u] ", pHddCtx->cfg_ini->IsRArateLimitEnabled); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fFTResourceReqSupported] Value = [%u] ",pHddCtx->cfg_ini->fFTResourceReqSupported); +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborReassocRssiThreshold] Value = [%u] ",pHddCtx->cfg_ini->nNeighborReassocRssiThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborLookupRssiThreshold] Value = [%u] ",pHddCtx->cfg_ini->nNeighborLookupRssiThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [nOpportunisticThresholdDiff] Value = [%u] ", + pHddCtx->cfg_ini->nOpportunisticThresholdDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [nRoamRescanRssiDiff] Value = [%u] ", + pHddCtx->cfg_ini->nRoamRescanRssiDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanMinChanTime] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanMinChanTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanMaxChanTime] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanMaxChanTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nMaxNeighborRetries] Value = [%u] ",pHddCtx->cfg_ini->nMaxNeighborReqTries); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanPeriod] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanResultsRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nEmptyScanRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nEmptyScanRefreshPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [nRoamBmissFirstBcnt] Value = [%u] ", + pHddCtx->cfg_ini->nRoamBmissFirstBcnt); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [nRoamBmissFinalBcnt] Value = [%u] ", + pHddCtx->cfg_ini->nRoamBmissFinalBcnt); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [nRoamBeaconRssiWeight] Value = [%u] ", + pHddCtx->cfg_ini->nRoamBeaconRssiWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [allowDFSChannelRoam] Value = [%u] ", + pHddCtx->cfg_ini->allowDFSChannelRoam); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [burstSizeDefinition] Value = [0x%x] ",pHddCtx->cfg_ini->burstSizeDefinition); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [tsInfoAckPolicy] Value = [0x%x] ",pHddCtx->cfg_ini->tsInfoAckPolicy); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [rfSettlingTimeUs] Value = [%u] ",pHddCtx->cfg_ini->rfSettlingTimeUs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [bSingleTidRc] Value = [%u] ",pHddCtx->cfg_ini->bSingleTidRc); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDynamicPSPollvalue] Value = [%u] ",pHddCtx->cfg_ini->dynamicPsPollValue); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAddTSWhenACMIsOff] Value = [%u] ",pHddCtx->cfg_ini->AddTSWhenACMIsOff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gValidateScanList] Value = [%u] ",pHddCtx->cfg_ini->fValidateScanList); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gStaKeepAlivePeriod] Value = [%u] ",pHddCtx->cfg_ini->infraStaKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApDataAvailPollInterVal] Value = [%u] ",pHddCtx->cfg_ini->apDataAvailPollPeriodInMs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableBtAmp] Value = [%u] ",pHddCtx->cfg_ini->enableBtAmp); +#ifdef WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BtAmpPreferredChannel] Value = [%u] ",pHddCtx->cfg_ini->preferredChannel); +#endif //WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BandCapability] Value = [%u] ",pHddCtx->cfg_ini->nBandCapability); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableBeaconEarlyTermination] Value = [%u] ",pHddCtx->cfg_ini->fEnableBeaconEarlyTermination); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [teleBcnWakeupEnable] Value = [%u] ",pHddCtx->cfg_ini->teleBcnWakeupEn); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [transListenInterval] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnTransListenInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [transLiNumIdleBeacons] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnTransLiNumIdleBeacons); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxListenInterval] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxListenInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxLiNumIdleBeacons] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxLiNumIdleBeacons); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [bcnEarlyTermWakeInterval] Value = [%u] ",pHddCtx->cfg_ini->bcnEarlyTermWakeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApDataAvailPollInterVal] Value = [%u] ",pHddCtx->cfg_ini->apDataAvailPollPeriodInMs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableBypass11d] Value = [%u] ",pHddCtx->cfg_ini->enableBypass11d); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableDFSChnlScan] Value = [%u] ",pHddCtx->cfg_ini->enableDFSChnlScan); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gReportMaxLinkSpeed] Value = [%u] ",pHddCtx->cfg_ini->reportMaxLinkSpeed); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [thermalMitigationEnable] Value = [%u] ",pHddCtx->cfg_ini->thermalMitigationEnable); +#ifdef WLAN_FEATURE_11AC + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gVhtChannelWidth] value = [%u]",pHddCtx->cfg_ini->vhtChannelWidth); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enableFirstScan2GOnly] Value = [%u] ",pHddCtx->cfg_ini->enableFirstScan2GOnly); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [skipDfsChnlInP2pSearch] Value = [%u] ",pHddCtx->cfg_ini->skipDfsChnlInP2pSearch); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ignoreDynamicDtimInP2pMode] Value = [%u] ",pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enableRxSTBC] Value = [%u] ",pHddCtx->cfg_ini->enableRxSTBC); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableLpwrImgTransition] Value = [%u] ",pHddCtx->cfg_ini->enableLpwrImgTransition); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableSSR] Value = [%u] ",pHddCtx->cfg_ini->enableSSR); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableVhtFor24GHzBand] Value = [%u] ",pHddCtx->cfg_ini->enableVhtFor24GHzBand); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gFlexConnectPowerFactor] Value = [%u] ", pHddCtx->cfg_ini->flexConnectPowerFactor); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableIbssHeartBeatOffload] Value = [%u] ", pHddCtx->cfg_ini->enableIbssHeartBeatOffload); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAntennaDiversity] Value = [%u] ", pHddCtx->cfg_ini->antennaDiversity); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gGoLinkMonitorPeriod] Value = [%u]",pHddCtx->cfg_ini->goLinkMonitorPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApLinkMonitorPeriod] Value = [%u]",pHddCtx->cfg_ini->apLinkMonitorPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gGoKeepAlivePeriod] Value = [%u]",pHddCtx->cfg_ini->goKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApKeepAlivePeriod]Value = [%u]",pHddCtx->cfg_ini->apKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAmsduSupportInAMPDU] Value = [%u] ",pHddCtx->cfg_ini->isAmsduSupportInAMPDU); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nSelect5GHzMargin] Value = [%u] ",pHddCtx->cfg_ini->nSelect5GHzMargin); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gCoalesingInIBSS] Value = [%u] ",pHddCtx->cfg_ini->isCoalesingInIBSSAllowed); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssATIMWinSize] Value = [%u] ",pHddCtx->cfg_ini->ibssATIMWinSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssIsPowerSaveAllowed] Value = [%u] ",pHddCtx->cfg_ini->isIbssPowerSaveAllowed); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssIsPowerCollapseAllowed] Value = [%u] ",pHddCtx->cfg_ini->isIbssPowerCollapseAllowed); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssAwakeOnTxRx] Value = [%u] ",pHddCtx->cfg_ini->isIbssAwakeOnTxRx); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssInactivityTime] Value = [%u] ",pHddCtx->cfg_ini->ibssInactivityCount); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssTxSpEndInactivityTime] Value = [%u] ",pHddCtx->cfg_ini->ibssTxSpEndInactivityTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIbssPsWarmupTime] Value = [%u] ",pHddCtx->cfg_ini->ibssPsWarmupTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gIbssPs1RxChainInAtim] Value = [%u] ", + pHddCtx->cfg_ini->ibssPs1RxChainInAtimEnable); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fDfsPhyerrFilterOffload] Value = [%u] ",pHddCtx->cfg_ini->fDfsPhyerrFilterOffload); + +#ifdef IPA_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIPAConfig] Value = [0x%x] ",pHddCtx->cfg_ini->IpaConfig); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIPADescSize] Value = [%u] ",pHddCtx->cfg_ini->IpaDescSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [IpaHighBandwidthMbpsg] Value = [%u] ",pHddCtx->cfg_ini->IpaHighBandwidthMbps); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [IpaMediumBandwidthMbps] Value = [%u] ",pHddCtx->cfg_ini->IpaMediumBandwidthMbps); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [IpaLowBandwidthMbps] Value = [%u] ",pHddCtx->cfg_ini->IpaLowBandwidthMbps); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableOverLapCh] Value = [%u] ",pHddCtx->cfg_ini->gEnableOverLapCh); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAcsScanBandPreference] Value = [%u] ",pHddCtx->cfg_ini->acsScanBandPreference); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxOffloadPeers] Value = [%u] ",pHddCtx->cfg_ini->apMaxOffloadPeers); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxOffloadReorderBuffs] value = [%u] ",pHddCtx->cfg_ini->apMaxOffloadReorderBuffs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [overrideCountryCode] Value = [%s] ",pHddCtx->cfg_ini->overrideCountryCode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAllowDFSChannelRoam] Value = [%u] ",pHddCtx->cfg_ini->allowDFSChannelRoam); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxConcurrentActiveSessions] Value = [%u] ", pHddCtx->cfg_ini->gMaxConcurrentActiveSessions); + +#ifdef MSM_PLATFORM + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gBusBandwidthHighThreshold] Value = [%u] ", + pHddCtx->cfg_ini->busBandwidthHighThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gBusBandwidthMediumThreshold] Value = [%u] ", + pHddCtx->cfg_ini->busBandwidthMediumThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gBusBandwidthLowThreshold] Value = [%u] ", + pHddCtx->cfg_ini->busBandwidthLowThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gbusBandwidthComputeInterval] Value = [%u] ", + pHddCtx->cfg_ini->busBandwidthComputeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTcpDelAckThresholdHigh] Value = [%u] ", + pHddCtx->cfg_ini->tcpDelackThresholdHigh); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTcpDelAckThresholdLow] Value = [%u] ", + pHddCtx->cfg_ini->tcpDelackThresholdLow); +#endif + +#ifdef QCA_HT_2040_COEX + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gHT2040CoexEnabled] Value = [%u]", + pHddCtx->cfg_ini->ht2040CoexEnabled); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gIgnoreCAC] Value = [%u] ", + pHddCtx->cfg_ini->ignoreCAC); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gSapPreferredChanLocation] Value = [%u] ", + pHddCtx->cfg_ini->gSapPreferredChanLocation); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDisableDfsJapanW53] Value = [%u] ", + pHddCtx->cfg_ini->gDisableDfsJapanW53); +#ifdef FEATURE_GREEN_AP + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableGreenAp] Value = [%u] ", + pHddCtx->cfg_ini->enableGreenAP); +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [isRoamOffloadEnabled] Value = [%u]", + pHddCtx->cfg_ini->isRoamOffloadEnabled); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableSifsBurst] Value = [%u]", + pHddCtx->cfg_ini->enableSifsBurst); + +#ifdef WLAN_FEATURE_LPSS + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableLpassSupport] Value = [%u] ", + pHddCtx->cfg_ini->enablelpasssupport); +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableSelfRecovery] Value = [%u]", + pHddCtx->cfg_ini->enableSelfRecovery); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableSapSuspend] Value = [%u]", + pHddCtx->cfg_ini->enableSapSuspend); + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWgotoSuspend] Value = [%u]", + pHddCtx->cfg_ini->extWowGotoSuspend); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWowApp1WakeupPinNumber] Value = [%u]", + pHddCtx->cfg_ini->extWowApp1WakeupPinNumber); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWowApp2WakeupPinNumber] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2WakeupPinNumber); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2KAInitPingInterval] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2KAInitPingInterval); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2KAMinPingInterval] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2KAMinPingInterval); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2KAMaxPingInterval] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2KAMaxPingInterval); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2KAIncPingInterval] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2KAIncPingInterval); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2TcpSrcPort] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2TcpSrcPort); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2TcpDstPort] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2TcpDstPort); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2TcpTxTimeout] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2TcpTxTimeout); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gExtWoWApp2TcpRxTimeout] Value = [%u]", + pHddCtx->cfg_ini->extWowApp2TcpRxTimeout); +#endif + hddLog(LOG2, "Name = [gP2PListenDeferInterval] Value = [%u]", + pHddCtx->cfg_ini->p2p_listen_defer_interval); +} + +#define CFG_VALUE_MAX_LEN 256 +#define CFG_ENTRY_MAX_LEN (32+CFG_VALUE_MAX_LEN) +static VOS_STATUS hdd_cfg_get_config(REG_TABLE_ENTRY *reg_table, + unsigned long cRegTableEntries, + v_U8_t *ini_struct, + hdd_context_t *pHddCtx, char *pBuf, int buflen) +{ + unsigned int idx; + REG_TABLE_ENTRY *pRegEntry = reg_table; + v_U32_t value; + char valueStr[CFG_VALUE_MAX_LEN]; + char configStr[CFG_ENTRY_MAX_LEN]; + char *fmt; + void *pField; + v_MACADDR_t *pMacAddr; + char *pCur = pBuf; + int curlen; + + // start with an empty string + *pCur = '\0'; + + for ( idx = 0; idx < cRegTableEntries; idx++, pRegEntry++ ) + { + pField = ini_struct + pRegEntry->VarOffset; + + if ( ( WLAN_PARAM_Integer == pRegEntry->RegType ) || + ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) || + ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) ) + { + value = 0; + memcpy( &value, pField, pRegEntry->VarSize ); + if ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) + { + fmt = "%x"; + } + else if ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) + { + fmt = "%d"; + } + else + { + fmt = "%u"; + } + snprintf(valueStr, CFG_VALUE_MAX_LEN, fmt, value); + } + else if ( WLAN_PARAM_String == pRegEntry->RegType ) + { + snprintf(valueStr, CFG_VALUE_MAX_LEN, "%s", (char *)pField); + } + else if ( WLAN_PARAM_MacAddr == pRegEntry->RegType ) + { + pMacAddr = (v_MACADDR_t *) pField; + snprintf(valueStr, CFG_VALUE_MAX_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + pMacAddr->bytes[0], + pMacAddr->bytes[1], + pMacAddr->bytes[2], + pMacAddr->bytes[3], + pMacAddr->bytes[4], + pMacAddr->bytes[5]); + } + else + { + snprintf(valueStr, CFG_VALUE_MAX_LEN, "(unhandled)"); + } + curlen = scnprintf(configStr, CFG_ENTRY_MAX_LEN, + "%s=[%s]%s\n", + pRegEntry->RegName, + valueStr, + test_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg) ? + "*" : ""); + + // ideally we want to return the config to the application + // however the config is too big so we just printk() for now +#ifdef RETURN_IN_BUFFER + if (curlen <= buflen) + { + // copy string + '\0' + memcpy(pCur, configStr, curlen+1); + + // account for addition; + pCur += curlen; + buflen -= curlen; + } + else + { + // buffer space exhausted, return what we have + return VOS_STATUS_E_RESOURCES; + } +#else + printk(KERN_INFO "%s", configStr); +#endif // RETURN_IN_BUFFER + +} + +#ifndef RETURN_IN_BUFFER + // notify application that output is in system log + snprintf(pCur, buflen, "WLAN configuration written to system log"); +#endif // RETURN_IN_BUFFER + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_cfg_get_global_config(hdd_context_t *pHddCtx, char *pBuf, + int buflen) +{ + return hdd_cfg_get_config(g_registry_table, ARRAY_SIZE(g_registry_table), + (v_U8_t *) pHddCtx->cfg_ini, + pHddCtx, pBuf, buflen); +} + +#ifdef WLAN_FEATURE_MBSSID +VOS_STATUS hdd_cfg_get_sap_dyn_config(hdd_adapter_t *pAdapter, char *pBuf, + int buflen) +{ + return hdd_cfg_get_config(mbssid_sap_dyn_ini_reg_table, + ARRAY_SIZE(mbssid_sap_dyn_ini_reg_table), + (v_U8_t *) &pAdapter->sap_dyn_ini_cfg, + WLAN_HDD_GET_CTX(pAdapter), + pBuf, buflen); +} +#endif + +static VOS_STATUS find_cfg_item (tCfgIniEntry* iniTable, unsigned long entries, + char *name, char** value) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + unsigned long i; + + for (i = 0; i < entries; i++) { + if (strcmp(iniTable[i].name, name) == 0) { + *value = iniTable[i].value; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Found %s entry for Name=[%s] Value=[%s] ", + WLAN_INI_FILE, name, *value); + return VOS_STATUS_SUCCESS; + } + } + + return status; +} + +static int parseHexDigit(char c) +{ + if (c >= '0' && c <= '9') + return c-'0'; + if (c >= 'a' && c <= 'f') + return c-'a'+10; + if (c >= 'A' && c <= 'F') + return c-'A'+10; + + return 0; +} + +/* convert string to 6 bytes mac address + * 00AA00BB00CC -> 0x00 0xAA 0x00 0xBB 0x00 0xCC + */ +static void update_mac_from_string(hdd_context_t *pHddCtx, tCfgIniEntry *macTable, int num) +{ + int i = 0, j = 0, res = 0; + char *candidate = NULL; + v_MACADDR_t macaddr[VOS_MAX_CONCURRENCY_PERSONA]; + + memset(macaddr, 0, sizeof(macaddr)); + + for (i = 0; i < num; i++) + { + candidate = macTable[i].value; + for (j = 0; j < VOS_MAC_ADDR_SIZE; j++) { + res = hex2bin(&macaddr[i].bytes[j], &candidate[(j<<1)], 1); + if (res < 0) + break; + } + if (res == 0 && !vos_is_macaddr_zero(&macaddr[i])) { + vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], + (v_U8_t *)&macaddr[i].bytes[0], VOS_MAC_ADDR_SIZE); + } + } +} + +/* + * This function tries to update mac address from cfg file. + * It overwrites the MAC address if config file exist. + */ +VOS_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx) +{ + int status, i = 0; + const struct firmware *fw = NULL; + char *line, *buffer = NULL; + char *name, *value; + tCfgIniEntry macTable[VOS_MAX_CONCURRENCY_PERSONA]; + tSirMacAddr customMacAddr; + + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + memset(macTable, 0, sizeof(macTable)); + status = request_firmware(&fw, WLAN_MAC_FILE, pHddCtx->parent_dev); + + if (status) + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: request_firmware failed %d", + __func__, status); + vos_status = VOS_STATUS_E_FAILURE; + return vos_status; + } + if (!fw || !fw->data || !fw->size) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: invalid firmware", __func__); + vos_status = VOS_STATUS_E_INVAL; + goto config_exit; + } + + buffer = (char *)fw->data; + + /* data format: + * Intf0MacAddress=00AA00BB00CC + * Intf1MacAddress=00AA00BB00CD + * END + */ + while (buffer != NULL) + { + line = get_next_line(buffer); + buffer = i_trim(buffer); + + if (strlen((char *)buffer) == 0 || *buffer == '#') { + buffer = line; + continue; + } + if (strncmp(buffer, "END", 3) == 0) + break; + + name = buffer; + buffer = strchr(buffer, '='); + if (buffer) { + *buffer++ = '\0'; + i_trim(name); + if (strlen(name) != 0) { + buffer = i_trim(buffer); + if (strlen(buffer) == 12) { + value = buffer; + macTable[i].name = name; + macTable[i++].value = value; + if (i >= VOS_MAX_CONCURRENCY_PERSONA) + break; + } + } + } + buffer = line; + } + if (i <= VOS_MAX_CONCURRENCY_PERSONA) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %d Mac addresses provided", __func__, i); + } + else { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid number of Mac address provided, nMac = %d", + __func__, i); + vos_status = VOS_STATUS_E_INVAL; + goto config_exit; + } + + update_mac_from_string(pHddCtx, &macTable[0], i); + + vos_mem_copy(&customMacAddr, + &pHddCtx->cfg_ini->intfMacAddr[0].bytes[0], + sizeof(tSirMacAddr)); + sme_SetCustomMacAddr(customMacAddr); + +config_exit: + release_firmware(fw); + return vos_status; +} + +static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t *pHddCtx, tCfgIniEntry* iniTable, unsigned long entries) +{ + VOS_STATUS match_status = VOS_STATUS_E_FAILURE; + VOS_STATUS ret_status = VOS_STATUS_SUCCESS; + unsigned int idx; + void *pField; + char *value_str = NULL; + unsigned long len_value_str; + char *candidate; + v_U32_t value; + v_S31_t svalue; + void *pStructBase = pHddCtx->cfg_ini; + REG_TABLE_ENTRY *pRegEntry = g_registry_table; + unsigned long cRegTableEntries = sizeof(g_registry_table) / sizeof( g_registry_table[ 0 ]); + v_U32_t cbOutString; + int i; + int rv; + + // sanity test + if (MAX_CFG_INI_ITEMS < cRegTableEntries) + { + hddLog(LOGE, "%s: MAX_CFG_INI_ITEMS too small, must be at least %ld", + __func__, cRegTableEntries); + } + + for ( idx = 0; idx < cRegTableEntries; idx++, pRegEntry++ ) + { + //Calculate the address of the destination field in the structure. + pField = ( (v_U8_t *)pStructBase )+ pRegEntry->VarOffset; + + match_status = find_cfg_item(iniTable, entries, pRegEntry->RegName, &value_str); + + if( (match_status != VOS_STATUS_SUCCESS) && ( pRegEntry->Flags & VAR_FLAGS_REQUIRED ) ) + { + // If we could not read the cfg item and it is required, this is an error. + hddLog(LOGE, "%s: Failed to read required config parameter %s", + __func__, pRegEntry->RegName); + ret_status = VOS_STATUS_E_FAILURE; + break; + } + + if ( ( WLAN_PARAM_Integer == pRegEntry->RegType ) || + ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) ) + { + // If successfully read from the registry, use the value read. + // If not, use the default value. + if ( match_status == VOS_STATUS_SUCCESS && (WLAN_PARAM_Integer == pRegEntry->RegType)) { + rv = kstrtou32(value_str, 10, &value); + if (rv < 0) { + hddLog(LOGE, "%s: Reg Parameter %s invalid. Enforcing default", + __func__, pRegEntry->RegName); + value = pRegEntry->VarDefault; + } + } + else if ( match_status == VOS_STATUS_SUCCESS && (WLAN_PARAM_HexInteger == pRegEntry->RegType)) { + rv = kstrtou32(value_str, 16, &value); + if (rv < 0) { + hddLog(LOGE, "%s: Reg paramter %s invalid. Enforcing default", + __func__, pRegEntry->RegName); + value = pRegEntry->VarDefault; + } + } + else { + value = pRegEntry->VarDefault; + } + + // If this parameter needs range checking, do it here. + if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK ) + { + if ( value > pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Maximum", + __func__, pRegEntry->RegName, value, pRegEntry->VarMax ); + value = pRegEntry->VarMax; + } + + if ( value < pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Minimum", + __func__, pRegEntry->RegName, value, pRegEntry->VarMin); + value = pRegEntry->VarMin; + } + } + // If this parameter needs range checking, do it here. + else if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ) + { + if ( value > pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Default= %lu", + __func__, pRegEntry->RegName, value, pRegEntry->VarMax, pRegEntry->VarDefault ); + value = pRegEntry->VarDefault; + } + + if ( value < pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Default= %lu", + __func__, pRegEntry->RegName, value, pRegEntry->VarMin, pRegEntry->VarDefault ); + value = pRegEntry->VarDefault; + } + } + + // Move the variable into the output field. + memcpy( pField, &value, pRegEntry->VarSize ); + } + else if ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) + { + // If successfully read from the registry, use the value read. + // If not, use the default value. + if (VOS_STATUS_SUCCESS == match_status) + { + rv = kstrtos32(value_str, 10, &svalue); + if (rv < 0) { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Reg Parameter %s invalid. Enforcing Default", + __func__, pRegEntry->RegName); + svalue = (v_S31_t)pRegEntry->VarDefault; + } + } + else + { + svalue = (v_S31_t)pRegEntry->VarDefault; + } + + // If this parameter needs range checking, do it here. + if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK ) + { + if ( svalue > (v_S31_t)pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum " + "[%d > %d]. Enforcing Maximum", __func__, + pRegEntry->RegName, svalue, (int)pRegEntry->VarMax ); + svalue = (v_S31_t)pRegEntry->VarMax; + } + + if ( svalue < (v_S31_t)pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum " + "[%d < %d]. Enforcing Minimum", __func__, + pRegEntry->RegName, svalue, (int)pRegEntry->VarMin); + svalue = (v_S31_t)pRegEntry->VarMin; + } + } + // If this parameter needs range checking, do it here. + else if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ) + { + if ( svalue > (v_S31_t)pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum " + "[%d > %d]. Enforcing Default= %d", + __func__, pRegEntry->RegName, svalue, + (int)pRegEntry->VarMax, + (int)pRegEntry->VarDefault ); + svalue = (v_S31_t)pRegEntry->VarDefault; + } + + if ( svalue < (v_S31_t)pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum " + "[%d < %d]. Enforcing Default= %d", + __func__, pRegEntry->RegName, svalue, + (int)pRegEntry->VarMin, + (int)pRegEntry->VarDefault); + svalue = pRegEntry->VarDefault; + } + } + + // Move the variable into the output field. + memcpy( pField, &svalue, pRegEntry->VarSize ); + } + // Handle string parameters + else if ( WLAN_PARAM_String == pRegEntry->RegType ) + { +#ifdef WLAN_CFG_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "RegName = %s, VarOffset %u VarSize %u VarDefault %s", + pRegEntry->RegName, pRegEntry->VarOffset, pRegEntry->VarSize, (char*)pRegEntry->VarDefault); +#endif + + if ( match_status == VOS_STATUS_SUCCESS) + { + len_value_str = strlen(value_str); + + if(len_value_str > (pRegEntry->VarSize - 1)) { + hddLog(LOGE, "%s: Invalid Value=[%s] specified for Name=[%s] in %s", + __func__, value_str, pRegEntry->RegName, WLAN_INI_FILE); + cbOutString = utilMin( strlen( (char *)pRegEntry->VarDefault ), pRegEntry->VarSize - 1 ); + memcpy( pField, (void *)(pRegEntry->VarDefault), cbOutString ); + ( (v_U8_t *)pField )[ cbOutString ] = '\0'; + } + else + { + memcpy( pField, (void *)(value_str), len_value_str); + ( (v_U8_t *)pField )[ len_value_str ] = '\0'; + } + } + else + { + // Failed to read the string parameter from the registry. Use the default. + cbOutString = utilMin( strlen( (char *)pRegEntry->VarDefault ), pRegEntry->VarSize - 1 ); + memcpy( pField, (void *)(pRegEntry->VarDefault), cbOutString ); + ( (v_U8_t *)pField )[ cbOutString ] = '\0'; + } + } + else if ( WLAN_PARAM_MacAddr == pRegEntry->RegType ) + { + if(pRegEntry->VarSize != VOS_MAC_ADDR_SIZE) { + hddLog(LOGE, "%s: Invalid VarSize %u for Name=[%s]", + __func__, pRegEntry->VarSize, pRegEntry->RegName); + continue; + } + candidate = (char*)pRegEntry->VarDefault; + if ( match_status == VOS_STATUS_SUCCESS) { + len_value_str = strlen(value_str); + if(len_value_str != (VOS_MAC_ADDR_SIZE*2)) { + hddLog(LOGE, "%s: Invalid MAC addr [%s] specified for Name=[%s] in %s", + __func__, value_str, pRegEntry->RegName, WLAN_INI_FILE); + } + else + candidate = value_str; + } + //parse the string and store it in the byte array + for(i=0; iRegName); + } + + // did we successfully parse a cfg item for this parameter? + if( (match_status == VOS_STATUS_SUCCESS) && + (idx < MAX_CFG_INI_ITEMS) ) + { + set_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg); + } + } + + print_hdd_cfg(pHddCtx); + + return( ret_status ); +} + +#ifdef WLAN_FEATURE_MBSSID +v_VOID_t hdd_mbssid_apply_def_cfg_ini(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *iniConfig = pHddCtx->cfg_ini; + mbssid_sap_dyn_ini_config_t *sap_ini_cfg = &pAdapter->sap_dyn_ini_cfg; + + sap_ini_cfg->apStartChannelNum = iniConfig->apStartChannelNum; + sap_ini_cfg->apEndChannelNum = iniConfig->apEndChannelNum; + sap_ini_cfg->apOperatingBand = iniConfig->apOperatingBand; + sap_ini_cfg->apAutoChannelSelection = iniConfig->apAutoChannelSelection; + sap_ini_cfg->acsScanBandPreference = iniConfig->acsScanBandPreference; + sap_ini_cfg->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold; + vos_mem_copy(sap_ini_cfg->acsAllowedChnls, iniConfig->acsAllowedChnls, + CFG_MAX_STR_LEN); + sap_ini_cfg->apForce11ACFor11n = iniConfig->apForce11ACFor11n; +} +#endif + +eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode( eHddDot11Mode dot11Mode ) +{ + switch (dot11Mode) + { + case (eHDD_DOT11_MODE_abg): + return eCSR_DOT11_MODE_abg; + case (eHDD_DOT11_MODE_11b): + return eCSR_DOT11_MODE_11b; + case (eHDD_DOT11_MODE_11g): + return eCSR_DOT11_MODE_11g; + default: + case (eHDD_DOT11_MODE_11n): + return eCSR_DOT11_MODE_11n; + case (eHDD_DOT11_MODE_11g_ONLY): + return eCSR_DOT11_MODE_11g_ONLY; + case (eHDD_DOT11_MODE_11n_ONLY): + return eCSR_DOT11_MODE_11n_ONLY; + case (eHDD_DOT11_MODE_11b_ONLY): + return eCSR_DOT11_MODE_11b_ONLY; +#ifdef WLAN_FEATURE_11AC + case (eHDD_DOT11_MODE_11ac_ONLY): + return eCSR_DOT11_MODE_11ac_ONLY; + case (eHDD_DOT11_MODE_11ac): + return eCSR_DOT11_MODE_11ac; +#endif + case (eHDD_DOT11_MODE_AUTO): + return eCSR_DOT11_MODE_AUTO; + } + +} + +static void hdd_set_btc_config(hdd_context_t *pHddCtx) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + tSmeBtcConfig btcParams; + int i; + + sme_BtcGetConfig(pHddCtx->hHal, &btcParams); + + btcParams.btcExecutionMode = pConfig->btcExecutionMode; + btcParams.btcConsBtSlotsToBlockDuringDhcp = pConfig->btcConsBtSlotsToBlockDuringDhcp; + btcParams.btcA2DPBtSubIntervalsDuringDhcp = pConfig->btcA2DPBtSubIntervalsDuringDhcp; + + btcParams.btcStaticLenInqBt = pConfig->btcStaticLenInqBt; + btcParams.btcStaticLenPageBt = pConfig->btcStaticLenPageBt; + btcParams.btcStaticLenConnBt = pConfig->btcStaticLenConnBt; + btcParams.btcStaticLenLeBt = pConfig->btcStaticLenLeBt; + btcParams.btcStaticLenInqWlan = pConfig->btcStaticLenInqWlan; + btcParams.btcStaticLenPageWlan = pConfig->btcStaticLenPageWlan; + btcParams.btcStaticLenConnWlan = pConfig->btcStaticLenConnWlan; + btcParams.btcStaticLenLeWlan = pConfig->btcStaticLenLeWlan; + btcParams.btcDynMaxLenBt = pConfig->btcDynMaxLenBt; + btcParams.btcDynMaxLenWlan = pConfig->btcDynMaxLenWlan; + btcParams.btcMaxScoBlockPerc = pConfig->btcMaxScoBlockPerc; + btcParams.btcDhcpProtOnA2dp = pConfig->btcDhcpProtOnA2dp; + btcParams.btcDhcpProtOnSco = pConfig->btcDhcpProtOnSco; + + for (i = 0; i < 10; i++) + { + btcParams.mwsCoexVictimWANFreq[i] = pConfig->mwsCoexVictimWANFreq[i]; + btcParams.mwsCoexVictimWLANFreq[i] = pConfig->mwsCoexVictimWLANFreq[i]; + btcParams.mwsCoexVictimConfig[i] = pConfig->mwsCoexVictimConfig[i]; + btcParams.mwsCoexVictimConfig2[i] = pConfig->mwsCoexVictimConfig2[i]; + } + for (i = 0; i < 6; i++) + { + btcParams.mwsCoexConfig[i] = pConfig->mwsCoexConfig[i]; + } + btcParams.mwsCoexModemBackoff = pConfig->mwsCoexModemBackoff; + btcParams.SARPowerBackoff = pConfig->SARPowerBackoff; + + sme_BtcSetConfig(pHddCtx->hHal, &btcParams); +} + +static void hdd_set_power_save_config(hdd_context_t *pHddCtx, tSmeConfigParams *smeConfig) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + tPmcBmpsConfigParams bmpsParams; + + sme_GetConfigPowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE, &bmpsParams); + + if (strcmp(pConfig->PowerUsageControl, "Min") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsMinSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsMinListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + if (strcmp(pConfig->PowerUsageControl, "Max") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsMaxSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsMaxListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + if (strcmp(pConfig->PowerUsageControl, "Mod") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsModSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsModListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + + if (pConfig->fIsImpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + else + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + + /*If isAndroidPsEn is 1 then Host driver and above layers control the PS mechanism + If Value set to 0 Driver/Core Stack internally control the Power saving mechanism */ + sme_SetHostPowerSave (pHddCtx->hHal, pConfig->isAndroidPsEn); + + if (pConfig->fIsBmpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + else + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + + bmpsParams.trafficMeasurePeriod = pConfig->nAutoBmpsTimerValue; + + if (sme_SetConfigPowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE, &bmpsParams)== eHAL_STATUS_FAILURE) + { + hddLog(LOGE, "SetConfigPowerSave failed to set BMPS params"); + } + + if(pConfig->fIsAutoBmpsTimerEnabled) + { + sme_StartAutoBmpsTimer(pHddCtx->hHal); + } + +} + +static void hdd_set_power_save_offload_config(hdd_context_t *pHddCtx) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + tANI_U32 listenInterval = 0; + + if (strcmp(pConfig->PowerUsageControl, "Min") == 0) + { + listenInterval = pConfig->nBmpsMinListenInterval; + } + else if (strcmp(pConfig->PowerUsageControl, "Max") == 0) + { + listenInterval = pConfig->nBmpsMaxListenInterval; + } + else if (strcmp(pConfig->PowerUsageControl, "Mod") == 0) + { + listenInterval = pConfig->nBmpsModListenInterval; + } + + /* + * Based on Mode Set the LI + * Otherwise default LI value of 1 will + * be taken + */ + if (listenInterval) + { + /* + * setcfg for listenInterval. + * Make sure CFG is updated because PE reads this + * from CFG at the time of assoc or reassoc + */ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, listenInterval, + NULL, eANI_BOOLEAN_FALSE); + } + + if(pConfig->fIsBmpsEnabled) + { + sme_ConfigEnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + else + { + sme_ConfigDisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } +} + +VOS_STATUS hdd_set_idle_ps_config(hdd_context_t *pHddCtx, v_U32_t val) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + hddLog(LOG1, "hdd_set_idle_ps_config: Enter Val %d", val); + + if(pConfig->fIsImpsEnabled) + { + status = sme_SetIdlePowersaveConfig(pHddCtx->pvosContext, val); + if(VOS_STATUS_SUCCESS != status) + { + hddLog(LOGE, "Fail to Set Idle PS Config val %d", val); + } + } + else + { + hddLog(LOG1, "hdd_set_idle_ps_config: IMPS not enabled in ini"); + } + return status; +} + +VOS_STATUS hdd_string_to_u8_array( char *str, tANI_U8 *intArray, tANI_U8 *len, + tANI_U8 intArrayMaxLen ) +{ + char *s = str; + + if( str == NULL || intArray == NULL || len == NULL ) + { + return VOS_STATUS_E_INVAL; + } + *len = 0; + + while ( (s != NULL) && (*len < intArrayMaxLen) ) + { + int val; + /* Increment length only if sscanf successfully extracted one element. + Any other return value means error. Ignore it. */ + if( sscanf(s, "%d", &val ) == 1 ) + { + intArray[*len] = (tANI_U8) val; + *len += 1; + } + s = strpbrk( s, "," ); + if( s ) + s++; + } + + return VOS_STATUS_SUCCESS; + +} + + +v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx ) +{ + v_BOOL_t fStatus = TRUE; + tANI_U32 val; + tANI_U16 val16; + + hdd_config_t *pConfig = pHddCtx->cfg_ini; + tSirMacHTCapabilityInfo *phtCapInfo; + + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_GI_20MHZ, + pConfig->ShortGI20MhzEnable, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SHORT_GI_20MHZ to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CAL_CONTROL, pConfig->Calibration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_CAL_CONTROL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CAL_PERIOD, pConfig->CalibrationPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_CAL_PERIOD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BA_AUTO_SETUP, pConfig->BlockAckAutoSetup, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BA_AUTO_SETUP to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FIXED_RATE, pConfig->TxRate, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_FIXED_RATE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_RX_AMPDU_FACTOR, + pConfig->MaxRxAmpduFactor, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_PREAMBLE, pConfig->fIsShortPreamble, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_SHORT_PREAMBLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + pConfig->nPassiveMinChnTime, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME" + " to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pConfig->nPassiveMaxChnTime, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME" + " to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BEACON_INTERVAL, pConfig->nBeaconInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BEACON_INTERVAL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_PS_POLL, pConfig->nMaxPsPoll, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_PS_POLL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CURRENT_RX_ANTENNA, pConfig-> nRxAnt, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_CURRENT_RX_ANTENNA configuration info to HAL"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LOW_GAIN_OVERRIDE, pConfig->fIsLowGainOverride, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_LOW_GAIN_OVERRIDE to HAL"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RSSI_FILTER_PERIOD, pConfig->nRssiFilterPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_RSSI_FILTER_PERIOD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, pConfig->fIgnoreDtim, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_IGNORE_DTIM configuration to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_HEART_BEAT, pConfig->fEnableFwHeartBeatMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_HEART_BEAT configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_BCN_FILTER, pConfig->fEnableFwBeaconFiltering, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_BCN_FILTER configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, pConfig->fEnableFwRssiMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_RSSI_MONITOR configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, pConfig->nDataInactivityTimeout, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_NTH_BEACON_FILTER, pConfig->nthBeaconFilter, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_NTH_BEACON_FILTER configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_LTE_COEX, pConfig->enableLTECoex, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_LTE_COEX to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE, pConfig->nEnableListenMode, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_KEEP_ALIVE_TIMEOUT, pConfig->apKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_AP_KEEP_ALIVE_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_GO_KEEP_ALIVE_TIMEOUT, pConfig->goKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_GO_KEEP_ALIVE_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_LINK_MONITOR_TIMEOUT, pConfig->apLinkMonitorPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_AP_LINK_MONITOR_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_GO_LINK_MONITOR_TIMEOUT, pConfig->goLinkMonitorPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_GO_LINK_MONITOR_TIMEOUT to CCM"); + } + + +#if defined WLAN_FEATURE_VOWIFI + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_ENABLED, pConfig->fRrmEnable, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_ENABLE configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_OPERATING_CHAN_MAX, pConfig->nInChanMeasMaxDuration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_OPERATING_CHAN_MAX configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, pConfig->nOutChanMeasMaxDuration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_OUT_CHAN_MAX configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MCAST_BCAST_FILTER_SETTING, pConfig->mcastBcastFilterSetting, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SINGLE_TID_RC, pConfig->bSingleTidRc, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_SINGLE_TID_RC configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_WAKEUP_EN, pConfig->teleBcnWakeupEn, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_WAKEUP_EN configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_TRANS_LI, pConfig->nTeleBcnTransListenInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_TRANS_LI configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_MAX_LI, pConfig->nTeleBcnMaxListenInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_MAX_LI configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS, pConfig->nTeleBcnTransLiNumIdleBeacons, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS, pConfig->nTeleBcnMaxLiNumIdleBeacons, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RF_SETTLING_TIME_CLK, pConfig->rfSettlingTimeUs, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RF_SETTLING_TIME_CLK configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, pConfig->infraStaKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD configuration info to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_PS_POLL_VALUE, pConfig->dynamicPsPollValue, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_DYNAMIC_PS_POLL_VALUE configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT, pConfig->nNullDataApRespTimeout, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_PS_NULLDATA_DELAY_TIMEOUT configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, pConfig->apDataAvailPollPeriodInMs, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD configuration info to CCM"); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, pConfig->FragmentationThreshold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_FRAGMENTATION_THRESHOLD configuration info to CCM"); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RTS_THRESHOLD, pConfig->RTSThreshold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RTS_THRESHOLD configuration info to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_11D_ENABLED, pConfig->Is11dSupportEnabled, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_11D_ENABLED configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DFS_MASTER_ENABLED, + pConfig->enableDFSMasterCap, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + fStatus = FALSE; + hddLog(LOGE, + "Failure: Could not set value for WNI_CFG_DFS_MASTER_ENABLED"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + pConfig->enableTxBFin20MHz, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + fStatus = FALSE; + hddLog(LOGE, + "Failure: Could not set value for WNI_CFG_VHT_ENABLE_TXBF_20MHZ"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HEART_BEAT_THRESHOLD, pConfig->HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_HEART_BEAT_THRESHOLD configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, pConfig->apDataAvailPollPeriodInMs, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD configuration info to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_CLOSE_LOOP, + pConfig->enableCloseLoop, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_CLOSE_LOOP to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TX_PWR_CTRL_ENABLE, + pConfig->enableAutomaticTxPowerControl, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TX_PWR_CTRL_ENABLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_GI_40MHZ, + pConfig->ShortGI40MhzEnable, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SHORT_GI_40MHZ to CCM"); + } + + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST, pConfig->fEnableMCAddrList, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"); + } + +#ifdef WLAN_FEATURE_11AC + /* Based on cfg.ini, update the Basic MCS set, RX/TX MCS map in the cfg.dat */ + /* valid values are 0(MCS0-7), 1(MCS0-8), 2(MCS0-9) */ + /* we update only the least significant 2 bits in the corresponding fields */ + if( (pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac) ) + { + { + tANI_U32 temp = 0; + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; + if (pConfig->enable2x2) + temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2); + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; + if (pConfig->enable2x2) + temp = (temp & 0xFFF3) | (pConfig->vhtRxMCS2x2 << 2); + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtTxMCS; + if (pConfig->enable2x2) + temp = (temp & 0xFFF3) | (pConfig->vhtTxMCS2x2 << 2); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "vhtRxMCS2x2 - %x temp - %u enable2x2 %d", + pConfig->vhtRxMCS2x2, temp, pConfig->enable2x2); + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CCM"); + } + /* Currently shortGI40Mhz is used for shortGI80Mhz */ + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ, + pConfig->ShortGI40MhzEnable, NULL, eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass WNI_VHT_SHORT_GI_80MHZ to CCM"); + } + // Hardware is capable of doing 128K AMPDU in 11AC mode + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + pConfig->fVhtAmpduLenExponent, NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_AMPDU_LEN_EXPONENT to CCM"); + } + + /* Change MU Bformee only when TxBF is enabled */ + if (pConfig->enableTxBF) + { + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + &temp); + + if(temp != pConfig->enableMuBformee) + { + if(ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + pConfig->enableMuBformee, NULL, + eANI_BOOLEAN_FALSE) ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on\ + WNI_CFG_VHT_MU_BEAMFORMEE_CAP to CCM"); + } + } + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH, + pConfig->vhtMpduLen, NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_MAX_MPDU_LENGTH to CCM"); + } + } + } +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_NUM_BUFF_ADVERT,pConfig->numBuffAdvert, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_NUM_BUFF_ADVERT to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HT_RX_STBC, + pConfig->enableRxSTBC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_HT_RX_STBC to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_HT_CAP_INFO, &val); + val16 = (tANI_U16)val; + phtCapInfo = (tSirMacHTCapabilityInfo *)&val16; + phtCapInfo->rxSTBC = pConfig->enableRxSTBC; + phtCapInfo->advCodingCap = pConfig->enableRxLDPC; + val = val16; + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HT_CAP_INFO, + val, NULL, eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_HT_CAP_INFO to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_RXSTBC, + pConfig->enableRxSTBC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RXSTBC to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TXSTBC, + pConfig->enableTxSTBC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TXSTBC to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP, + pConfig->enableRxLDPC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_LDPC_CODING_CAP to CCM"); + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + if(pConfig->fEnableVSTASupport) + { + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_ASSOC_STA_LIMIT, &val); + if( val <= WNI_CFG_ASSOC_STA_LIMIT_STADEF) + val = WNI_CFG_ASSOC_STA_LIMIT_STAMAX; + } + else + { + val = pConfig->maxNumberOfPeers; + + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASSOC_STA_LIMIT, val, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_ASSOC_STA_LIMIT configuration info to CCM"); + } +#endif + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_LPWR_IMG_TRANSITION, + pConfig->enableLpwrImgTransition, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_LPWR_IMG_TRANSITION to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, pConfig->enableMCCAdaptiveScheduler, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP, pConfig->disableLDPCWithTxbfAP, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_ZERO, pConfig->retryLimitZero, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_ZERO to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_ONE, pConfig->retryLimitOne, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_ONE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_TWO, pConfig->retryLimitTwo, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_TWO to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_MEDIUM_TIME, pConfig->cfgMaxMediumTime, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_MEDIUM_TIME to CCM"); + } + +#ifdef FEATURE_WLAN_TDLS + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + pConfig->fTDLSUapsdMask, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_BUF_STA_ENABLED, + pConfig->fEnableTDLSBufferSta, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_BUF_STA_ENABLED to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_PUAPSD_INACT_TIME, + pConfig->fTDLSPuapsdInactivityTimer, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_PUAPSD_INACT_TIME to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_RX_FRAME_THRESHOLD, + pConfig->fTDLSRxFrameThreshold, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_RX_FRAME_THRESHOLD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + pConfig->fEnableTDLSOffChannel, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_BUF_STA_ENABLED to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_WMM_MODE_ENABLED, + pConfig->fEnableTDLSWmmMode, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_WMM_MODE_ENABLED to CCM"); + } + +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_ADAPT_RX_DRAIN, + pConfig->fEnableAdaptRxDrain, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_ADAPT_RX_DRAIN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FLEX_CONNECT_POWER_FACTOR, + pConfig->flexConnectPowerFactor, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on " + "WNI_CFG_FLEX_CONNECT_POWER_FACTOR to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ANTENNA_DIVESITY, + pConfig->antennaDiversity, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ANTENNA_DIVESITY to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ, + pConfig->defaultRateIndex24Ghz, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DEFAULT_RATE_INDEX_24GHZ to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL, + pConfig->debugP2pRemainOnChannel, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, + "Could not pass on WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL to CCM"); + } + +#ifdef WLAN_FEATURE_11W + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + pConfig->pmfSaQueryMaxRetries, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SA_QUERY_MAX_RETRIES to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + pConfig->pmfSaQueryRetryInterval, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SA_QUERY_RETRY_INTERVAL to CCM"); + } +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_ATIM_WIN_SIZE, + pConfig->ibssATIMWinSize, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_IBSS_ATIM_WIN_SIZE to CCM"); + } + return fStatus; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_set_sme_config() - + + This function initializes the sme configuration parameters + + \param - pHddCtx - Pointer to the HDD Adapter. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + eHalStatus halStatus; + tSmeConfigParams *smeConfig; + + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + smeConfig = vos_mem_malloc(sizeof(*smeConfig)); + if (NULL == smeConfig) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: unable to allocate smeConfig", __func__); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(smeConfig, sizeof(*smeConfig)); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s bWmmIsEnabled=%d 802_11e_enabled=%d dot11Mode=%d", __func__, + pConfig->WmmMode, pConfig->b80211eIsEnabled, pConfig->dot11Mode); + + // Config params obtained from the registry + /* To Do */ + // set regulatory information here + + smeConfig->csrConfig.RTSThreshold = pConfig->RTSThreshold; + smeConfig->csrConfig.FragmentationThreshold = pConfig->FragmentationThreshold; + smeConfig->csrConfig.shortSlotTime = pConfig->ShortSlotTimeEnabled; + smeConfig->csrConfig.Is11dSupportEnabled = pConfig->Is11dSupportEnabled; + smeConfig->csrConfig.HeartbeatThresh24 = pConfig->HeartbeatThresh24; + + smeConfig->csrConfig.phyMode = hdd_cfg_xlate_to_csr_phy_mode ( pConfig->dot11Mode ); + + smeConfig->csrConfig.channelBondingMode24GHz = pConfig->nChannelBondingMode24GHz; + smeConfig->csrConfig.channelBondingMode5GHz = pConfig->nChannelBondingMode5GHz; + smeConfig->csrConfig.TxRate = pConfig->TxRate; + smeConfig->csrConfig.nScanResultAgeCount = pConfig->ScanResultAgeCount; + smeConfig->csrConfig.scanAgeTimeNCNPS = pConfig->nScanAgeTimeNCNPS; + smeConfig->csrConfig.scanAgeTimeNCPS = pConfig->nScanAgeTimeNCPS; + smeConfig->csrConfig.scanAgeTimeCNPS = pConfig->nScanAgeTimeCNPS; + smeConfig->csrConfig.scanAgeTimeCPS = pConfig->nScanAgeTimeCPS; + smeConfig->csrConfig.AdHocChannel24 = pConfig->OperatingChannel; + smeConfig->csrConfig.fEnforce11dChannels = pConfig->fEnforce11dChannels; + smeConfig->csrConfig.fSupplicantCountryCodeHasPriority = pConfig->fSupplicantCountryCodeHasPriority; + smeConfig->csrConfig.fEnforceCountryCodeMatch = pConfig->fEnforceCountryCodeMatch; + smeConfig->csrConfig.fEnforceDefaultDomain = pConfig->fEnforceDefaultDomain; + smeConfig->csrConfig.bCatRssiOffset = pConfig->nRssiCatGap; + smeConfig->csrConfig.vccRssiThreshold = pConfig->nVccRssiTrigger; + smeConfig->csrConfig.vccUlMacLossThreshold = pConfig->nVccUlMacLossThreshold; + smeConfig->csrConfig.nRoamingTime = pConfig->nRoamingTime; + smeConfig->csrConfig.IsIdleScanEnabled = pConfig->nEnableIdleScan; + smeConfig->csrConfig.nInitialDwellTime = pConfig->nInitialDwellTime; + smeConfig->csrConfig.initial_scan_no_dfs_chnl = + pConfig->initial_scan_no_dfs_chnl; + smeConfig->csrConfig.nActiveMaxChnTime = pConfig->nActiveMaxChnTime; + smeConfig->csrConfig.nActiveMinChnTime = pConfig->nActiveMinChnTime; + smeConfig->csrConfig.nPassiveMaxChnTime = pConfig->nPassiveMaxChnTime; + smeConfig->csrConfig.nPassiveMinChnTime = pConfig->nPassiveMinChnTime; + smeConfig->csrConfig.nActiveMaxChnTimeBtc = pConfig->nActiveMaxChnTimeBtc; + smeConfig->csrConfig.nActiveMinChnTimeBtc = pConfig->nActiveMinChnTimeBtc; + smeConfig->csrConfig.disableAggWithBtc = pConfig->disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + smeConfig->csrConfig.nActiveMaxChnTimeConc = pConfig->nActiveMaxChnTimeConc; + smeConfig->csrConfig.nActiveMinChnTimeConc = pConfig->nActiveMinChnTimeConc; + smeConfig->csrConfig.nPassiveMaxChnTimeConc = pConfig->nPassiveMaxChnTimeConc; + smeConfig->csrConfig.nPassiveMinChnTimeConc = pConfig->nPassiveMinChnTimeConc; + smeConfig->csrConfig.nRestTimeConc = pConfig->nRestTimeConc; + smeConfig->csrConfig.nNumStaChanCombinedConc = pConfig->nNumStaChanCombinedConc; + smeConfig->csrConfig.nNumP2PChanCombinedConc = pConfig->nNumP2PChanCombinedConc; + +#endif + smeConfig->csrConfig.Is11eSupportEnabled = pConfig->b80211eIsEnabled; + smeConfig->csrConfig.WMMSupportMode = pConfig->WmmMode; + +#if defined WLAN_FEATURE_VOWIFI + smeConfig->rrmConfig.rrmEnabled = pConfig->fRrmEnable; + smeConfig->rrmConfig.maxRandnInterval = pConfig->nRrmRandnIntvl; +#endif + //Remaining config params not obtained from registry + // On RF EVB beacon using channel 1. +#ifdef WLAN_FEATURE_11AC + smeConfig->csrConfig.nVhtChannelWidth = pConfig->vhtChannelWidth; + smeConfig->csrConfig.enableTxBF = pConfig->enableTxBF; + smeConfig->csrConfig.txBFCsnValue = pConfig->txBFCsnValue; + smeConfig->csrConfig.enable2x2 = pConfig->enable2x2; + smeConfig->csrConfig.enableVhtFor24GHz = pConfig->enableVhtFor24GHzBand; + smeConfig->csrConfig.enableMuBformee = pConfig->enableMuBformee; + smeConfig->csrConfig.enableVhtpAid = pConfig->enableVhtpAid; + smeConfig->csrConfig.enableVhtGid = pConfig->enableVhtGid; +#endif + smeConfig->csrConfig.enableAmpduPs = pConfig->enableAmpduPs; + smeConfig->csrConfig.enableHtSmps = pConfig->enableHtSmps; + smeConfig->csrConfig.htSmps = pConfig->htSmps; + smeConfig->csrConfig.AdHocChannel5G = pConfig->AdHocChannel5G; + smeConfig->csrConfig.AdHocChannel24 = pConfig->AdHocChannel24G; + smeConfig->csrConfig.ProprietaryRatesEnabled = 0; + smeConfig->csrConfig.HeartbeatThresh50 = 40; + smeConfig->csrConfig.bandCapability = pConfig->nBandCapability; + if (pConfig->nBandCapability == eCSR_BAND_24) + { + smeConfig->csrConfig.Is11hSupportEnabled = 0; + } else { + smeConfig->csrConfig.Is11hSupportEnabled = pConfig->Is11hSupportEnabled; + } + smeConfig->csrConfig.cbChoice = 0; + smeConfig->csrConfig.bgScanInterval = 0; + smeConfig->csrConfig.eBand = pConfig->nBandCapability; + smeConfig->csrConfig.nTxPowerCap = pConfig->nTxPowerCap; + smeConfig->csrConfig.fEnableBypass11d = pConfig->enableBypass11d; + smeConfig->csrConfig.fEnableDFSChnlScan = pConfig->enableDFSChnlScan; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + smeConfig->csrConfig.nRoamPrefer5GHz = pConfig->nRoamPrefer5GHz; + smeConfig->csrConfig.nRoamIntraBand = pConfig->nRoamIntraBand; + smeConfig->csrConfig.nProbes = pConfig->nProbes; + + smeConfig->csrConfig.nRoamScanHomeAwayTime = pConfig->nRoamScanHomeAwayTime; +#endif + smeConfig->csrConfig.fFirstScanOnly2GChnl = pConfig->enableFirstScan2GOnly; + + //FIXME 11d config is hardcoded + if ( VOS_STA_SAP_MODE != hdd_get_conparam()) + { + smeConfig->csrConfig.Csr11dinfo.Channels.numChannels = 0; + + /* if there is a requirement that HDD will control the default + * channel list & country code (say from .ini file) we need to + * add some logic here. Otherwise the default 11d info should + * come from NV as per our current implementation */ + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "AP country Code %s", pConfig->apCntryCode); + + if (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0) + sme_setRegInfo(pHddCtx->hHal, pConfig->apCntryCode); + sme_set11dinfo(pHddCtx->hHal, smeConfig); + } + + if (!pConfig->enablePowersaveOffload) + { + hdd_set_power_save_config(pHddCtx, smeConfig); + } + else + { + hdd_set_power_save_offload_config(pHddCtx); + } + + hdd_set_btc_config(pHddCtx); + +#ifdef WLAN_FEATURE_VOWIFI_11R + smeConfig->csrConfig.csr11rConfig.IsFTResourceReqSupported = pConfig->fFTResourceReqSupported; +#endif +#ifdef FEATURE_WLAN_LFR + smeConfig->csrConfig.isFastRoamIniFeatureEnabled = pConfig->isFastRoamIniFeatureEnabled; + smeConfig->csrConfig.MAWCEnabled = pConfig->MAWCEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + smeConfig->csrConfig.isEseIniFeatureEnabled = pConfig->isEseIniFeatureEnabled; + if( pConfig->isEseIniFeatureEnabled ) + { + pConfig->isFastTransitionEnabled = TRUE; + } +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + smeConfig->csrConfig.isFastTransitionEnabled = pConfig->isFastTransitionEnabled; + smeConfig->csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff; + smeConfig->csrConfig.nImmediateRoamRssiDiff = pConfig->nImmediateRoamRssiDiff; + smeConfig->csrConfig.isWESModeEnabled = pConfig->isWESModeEnabled; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + smeConfig->csrConfig.isRoamOffloadScanEnabled = pConfig->isRoamOffloadScanEnabled; + smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = pConfig->bFastRoamInConIniFeatureEnabled; + + if (0 == smeConfig->csrConfig.isRoamOffloadScanEnabled) + { + /* Disable roaming in concurrency if roam scan offload is disabled */ + smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0; + } +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + smeConfig->csrConfig.neighborRoamConfig.nNeighborReassocRssiThreshold = pConfig->nNeighborReassocRssiThreshold; + smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold = pConfig->nNeighborLookupRssiThreshold; + smeConfig->csrConfig.neighborRoamConfig.delay_before_vdev_stop = + pConfig->delay_before_vdev_stop; + + smeConfig->csrConfig.neighborRoamConfig.nOpportunisticThresholdDiff = + pConfig->nOpportunisticThresholdDiff; + smeConfig->csrConfig.neighborRoamConfig.nRoamRescanRssiDiff = + pConfig->nRoamRescanRssiDiff; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMaxChanTime = pConfig->nNeighborScanMaxChanTime; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMinChanTime = pConfig->nNeighborScanMinChanTime; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanTimerPeriod = pConfig->nNeighborScanPeriod; + smeConfig->csrConfig.neighborRoamConfig.nMaxNeighborRetries = pConfig->nMaxNeighborReqTries; + smeConfig->csrConfig.neighborRoamConfig.nNeighborResultsRefreshPeriod = pConfig->nNeighborResultsRefreshPeriod; + smeConfig->csrConfig.neighborRoamConfig.nEmptyScanRefreshPeriod = pConfig->nEmptyScanRefreshPeriod; + hdd_string_to_u8_array( pConfig->neighborScanChanList, + smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.channelList, + &smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.numChannels, + WNI_CFG_VALID_CHANNEL_LIST_LEN ); + smeConfig->csrConfig.neighborRoamConfig.nRoamBmissFirstBcnt = pConfig->nRoamBmissFirstBcnt; + smeConfig->csrConfig.neighborRoamConfig.nRoamBmissFinalBcnt = pConfig->nRoamBmissFinalBcnt; + smeConfig->csrConfig.neighborRoamConfig.nRoamBeaconRssiWeight = pConfig->nRoamBeaconRssiWeight; +#endif + + smeConfig->csrConfig.addTSWhenACMIsOff = pConfig->AddTSWhenACMIsOff; + smeConfig->csrConfig.fValidateList = pConfig->fValidateScanList; + smeConfig->csrConfig.allowDFSChannelRoam = pConfig->allowDFSChannelRoam; + + //Enable/Disable MCC + smeConfig->csrConfig.fEnableMCCMode = pConfig->enableMCC; + smeConfig->csrConfig.fAllowMCCGODiffBI = pConfig->allowMCCGODiffBI; + + //Scan Results Aging Time out value + smeConfig->csrConfig.scanCfgAgingTime = pConfig->scanAgingTimeout; + + smeConfig->csrConfig.enableTxLdpc = pConfig->enableTxLdpc; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + smeConfig->csrConfig.cc_switch_mode = pConfig->WlanMccToSccSwitchMode; +#endif + + smeConfig->csrConfig.isAmsduSupportInAMPDU = pConfig->isAmsduSupportInAMPDU; + smeConfig->csrConfig.nSelect5GHzMargin = pConfig->nSelect5GHzMargin; + + smeConfig->csrConfig.isCoalesingInIBSSAllowed = + pHddCtx->cfg_ini->isCoalesingInIBSSAllowed; +#ifdef QCA_HT_2040_COEX + smeConfig->csrConfig.obssEnabled = pHddCtx->cfg_ini->ht2040CoexEnabled; +#endif + + /* update SSR config */ + sme_UpdateEnableSSR((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->enableSSR); + /* Update the Directed scan offload setting */ + smeConfig->fScanOffload = pHddCtx->cfg_ini->fScanOffload; + + /* Update the p2p listen offload setting */ + smeConfig->fP2pListenOffload = pHddCtx->cfg_ini->fP2pListenOffload; + smeConfig->csrConfig.scanBandPreference = + pHddCtx->cfg_ini->acsScanBandPreference; + +#ifdef FEATURE_WLAN_SCAN_PNO + /* Update PNO offload status */ + smeConfig->pnoOffload = pHddCtx->cfg_ini->PnoOffload; +#endif + + /* Update maximum interfaces information */ + smeConfig->max_intf_count = pHddCtx->max_intf_count; + + smeConfig->fEnableDebugLog = pHddCtx->cfg_ini->gEnableDebugLog; + + smeConfig->enable5gEBT = pHddCtx->cfg_ini->enable5gEBT; + + smeConfig->enableSelfRecovery = pHddCtx->cfg_ini->enableSelfRecovery; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + smeConfig->csrConfig.isRoamOffloadEnabled = + pHddCtx->cfg_ini->isRoamOffloadEnabled; +#endif + + smeConfig->csrConfig.pkt_err_disconn_th = + pHddCtx->cfg_ini->pkt_err_disconn_th; + + halStatus = sme_UpdateConfig( pHddCtx->hHal, smeConfig); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + status = VOS_STATUS_E_FAILURE; + hddLog(LOGE, "sme_UpdateConfig() return failure %d", halStatus); + } + + vos_mem_free(smeConfig); + return status; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_execute_config_command() - + + This function executes an arbitrary configuration set command + + \param - pHddCtx - Pointer to the HDD Adapter. + \parmm - command - a configuration command of the form: + = + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS hdd_execute_config_command(REG_TABLE_ENTRY *reg_table, + unsigned long tableSize, v_U8_t *ini_struct, + hdd_context_t *pHddCtx, char *command) +{ + REG_TABLE_ENTRY *pRegEntry; + char *clone; + char *pCmd; + void *pField; + char *name; + char *value_str; + v_U32_t value; + v_S31_t svalue; + size_t len_value_str; + unsigned int idx; + unsigned int i; + VOS_STATUS vstatus; + int rv; + + // assume failure until proven otherwise + vstatus = VOS_STATUS_E_FAILURE; + + // clone the command so that we can manipulate it + clone = kstrdup(command, GFP_ATOMIC); + if (NULL == clone) + { + hddLog(LOGE, "%s: memory allocation failure, unable to process [%s]", + __func__, command); + return vstatus; + } + + // 'clone' will point to the beginning of the string so it can be freed + // 'pCmd' will be used to walk/parse the command + pCmd = clone; + + // get rid of leading/trailing whitespace + pCmd = i_trim(pCmd); + if ('\0' == *pCmd) + { + // only whitespace + hddLog(LOGE, "%s: invalid command, only whitespace:[%s]", + __func__, command); + goto done; + } + + // parse the = + name = pCmd; + while (('=' != *pCmd) && ('\0' != *pCmd)) + { + pCmd++; + } + if ('\0' == *pCmd) + { + // did not find '=' + hddLog(LOGE, "%s: invalid command, no '=':[%s]", + __func__, command); + goto done; + } + + // replace '=' with NUL to terminate the + *pCmd++ = '\0'; + name = i_trim(name); + if ('\0' == *name) + { + // did not find a name + hddLog(LOGE, "%s: invalid command, no :[%s]", + __func__, command); + goto done; + } + + value_str = i_trim(pCmd); + if ('\0' == *value_str) + { + // did not find a value + hddLog(LOGE, "%s: invalid command, no :[%s]", + __func__, command); + goto done; + } + + // lookup the configuration item + for (idx = 0; idx < tableSize; idx++) + { + if (0 == strcmp(name, reg_table[idx].RegName)) + { + // found a match + break; + } + } + if (tableSize == idx) + { + // did not match the name + hddLog(LOGE, "%s: invalid command, unknown configuration item:[%s]", + __func__, command); + goto done; + } + + pRegEntry = ®_table[idx]; + if (!(pRegEntry->Flags & VAR_FLAGS_DYNAMIC_CFG)) + { + // does not support dynamic configuration + hddLog(LOGE, "%s: Global_Registry_Table.%s does not support " + "dynamic configuration", __func__, name); + vstatus = VOS_STATUS_E_PERM; + goto done; + } + + pField = ini_struct + pRegEntry->VarOffset; + + switch (pRegEntry->RegType) + { + case WLAN_PARAM_Integer: + rv = kstrtou32(value_str, 10, &value); + if (rv < 0) + goto done; + if (value < pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %u < min value %lu", + __func__, value, pRegEntry->VarMin); + goto done; + } + if (value > pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %u > max value %lu", + __func__, value, pRegEntry->VarMax); + goto done; + } + memcpy(pField, &value, pRegEntry->VarSize); + break; + + case WLAN_PARAM_HexInteger: + rv = kstrtou32(value_str, 16, &value); + if (rv < 0) + goto done; + if (value < pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %x < min value %lx", + __func__, value, pRegEntry->VarMin); + goto done; + } + if (value > pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %x > max value %lx", + __func__, value, pRegEntry->VarMax); + goto done; + } + memcpy(pField, &value, pRegEntry->VarSize); + break; + + case WLAN_PARAM_SignedInteger: + rv = kstrtos32(value_str, 10, &svalue); + if (rv < 0) + goto done; + if (svalue < (v_S31_t)pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %d < min value %d", + __func__, svalue, (int)pRegEntry->VarMin); + goto done; + } + if (svalue > (v_S31_t)pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %d > max value %d", + __func__, svalue, (int)pRegEntry->VarMax); + goto done; + } + memcpy(pField, &svalue, pRegEntry->VarSize); + break; + + case WLAN_PARAM_String: + len_value_str = strlen(value_str); + if (len_value_str > (pRegEntry->VarSize - 1)) + { + // too big + hddLog(LOGE, + "%s: invalid command, string [%s] length " + "%zu exceeds maximum length %u", + __func__, value_str, + len_value_str, (pRegEntry->VarSize - 1)); + goto done; + } + // copy string plus NUL + memcpy(pField, value_str, (len_value_str + 1)); + break; + + case WLAN_PARAM_MacAddr: + len_value_str = strlen(value_str); + if (len_value_str != (VOS_MAC_ADDR_SIZE * 2)) + { + // out of range + hddLog(LOGE, + "%s: invalid command, MAC address [%s] length " + "%zu is not expected length %u", + __func__, value_str, + len_value_str, (VOS_MAC_ADDR_SIZE * 2)); + goto done; + } + //parse the string and store it in the byte array + for (i = 0; i < VOS_MAC_ADDR_SIZE; i++) + { + ((char*)pField)[i] = (char) + ((parseHexDigit(value_str[(i * 2)]) * 16) + + parseHexDigit(value_str[(i * 2) + 1])); + } + break; + + default: + goto done; + } + + // if we get here, we had a successful modification + vstatus = VOS_STATUS_SUCCESS; + + // config table has been modified, is there a notifier? + if (NULL != pRegEntry->pfnDynamicNotify) + { + (pRegEntry->pfnDynamicNotify)(pHddCtx, pRegEntry->NotifyId); + } + + // note that this item was explicitly configured + if (idx < MAX_CFG_INI_ITEMS) + { + set_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg); + } + done: + kfree(clone); + return vstatus; +} + +VOS_STATUS hdd_execute_global_config_command(hdd_context_t *pHddCtx, + char *command) +{ + return hdd_execute_config_command(g_registry_table, + ARRAY_SIZE(g_registry_table), + (v_U8_t *) pHddCtx->cfg_ini, + pHddCtx, command); +} + +#ifdef WLAN_FEATURE_MBSSID +VOS_STATUS hdd_execute_sap_dyn_config_command(hdd_adapter_t *pAdapter, + char *command) +{ + return hdd_execute_config_command(mbssid_sap_dyn_ini_reg_table, + ARRAY_SIZE(mbssid_sap_dyn_ini_reg_table), + (v_U8_t *) &pAdapter->sap_dyn_ini_cfg, + WLAN_HDD_GET_CTX(pAdapter), command); +} +#endif +/**--------------------------------------------------------------------------- + + \brief hdd_is_okc_mode_enabled() - + + This function returns whether OKC mode is enabled or not + + \param - pHddCtx - Pointer to the HDD Adapter. + + \return - 1 for enabled, zero for disabled + + --------------------------------------------------------------------------*/ + +tANI_BOOLEAN hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx) +{ + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pHddCtx is NULL", __func__); + return -EINVAL; + } + +#ifdef FEATURE_WLAN_OKC + return pHddCtx->cfg_ini->isOkcIniFeatureEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +/** + * hdd_update_nss() - configures the provided nss value to the driver + * + * @hdd_ctx: the pointer to hdd context + * @nss : the number of spatial streams to be updated + * + * Return: VOS_STATUS_SUCCESS if nss is correctly updated, + * otherwise VOS_STATUS_E_FAILURE would be returned + */ +VOS_STATUS hdd_update_nss(hdd_context_t *hdd_ctx, uint8_t nss) +{ + hdd_config_t *hdd_config = hdd_ctx->cfg_ini; + uint32_t temp = 0; + uint32_t rx_supp_data_rate, tx_supp_data_rate; + uint8_t status = TRUE; + tSirMacHTCapabilityInfo *ht_cap_info; + uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET] = {0}; + uint8_t mcs_set_temp[SIZE_OF_SUPPORTED_MCS_SET]; + uint32_t val; + uint16_t val16; + uint8_t enable2x2; + + if ((nss == 2) && (hdd_ctx->num_rf_chains != 2)) { + hddLog(LOGE, "No support for 2 spatial streams"); + return VOS_STATUS_E_FAILURE; + } + + enable2x2 = (nss == 1) ? 0 : 1; + + if (hdd_config->enable2x2 == enable2x2) { + hddLog(LOGE, "NSS same as requested"); + return VOS_STATUS_SUCCESS; + } + + if (TRUE == sme_is_any_session_in_connected_state(hdd_ctx->hHal)) { + hddLog(LOGE, "Connected sessions present, Do not change NSS"); + return VOS_STATUS_E_FAILURE; + } + + hdd_config->enable2x2 = enable2x2; + + if (!hdd_config->enable2x2) { + /* 1x1 */ + rx_supp_data_rate = HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; + tx_supp_data_rate = HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; + } else { + /* 2x2 */ + rx_supp_data_rate = HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; + tx_supp_data_rate = HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; + } + + /* Update Rx Highest Long GI data Rate */ + if (ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + rx_supp_data_rate, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, + "Could not pass on WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM"); + } + + /* Update Tx Highest Long GI data Rate */ + if (ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + tx_supp_data_rate, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, + "Could not pass on HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 to CCM"); + } + + ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &temp); + val16 = (uint16_t)temp; + ht_cap_info = (tSirMacHTCapabilityInfo *)&val16; + if (!(hdd_ctx->ht_tx_stbc_supported && hdd_config->enable2x2)) + ht_cap_info->txSTBC = 0; + else + ht_cap_info->txSTBC = hdd_config->enableTxSTBC; + temp = val16; + if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, + temp, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_HT_CAP_INFO to CCM"); + } + + ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp); + temp = (temp & 0xFFFC) | hdd_config->vhtRxMCS; + if (hdd_config->enable2x2) + temp = (temp & 0xFFF3) | (hdd_config->vhtRxMCS2x2 << 2); + else + temp |= 0x000C; + + if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, + temp, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, + "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CCM"); + } + + ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | hdd_config->vhtRxMCS; + if (hdd_config->enable2x2) + temp = (temp & 0xFFF3) | (hdd_config->vhtRxMCS2x2 << 2); + else + temp |= 0x000C; + + if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_RX_MCS_MAP, + temp, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CCM"); + } + + ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | hdd_config->vhtTxMCS; + if (hdd_config->enable2x2) + temp = (temp & 0xFFF3) | (hdd_config->vhtTxMCS2x2 << 2); + else + temp |= 0x000C; + + if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_MCS_MAP, + temp, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CCM"); + } + +#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff + val = SIZE_OF_SUPPORTED_MCS_SET; + ccmCfgGetStr(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, + mcs_set_temp, &val); + + mcs_set[0] = mcs_set_temp[0]; + if (hdd_config->enable2x2) + for (val = 0; val < nss; val++) + mcs_set[val] = WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; + + if (ccmCfgSetStr(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, + mcs_set, SIZE_OF_SUPPORTED_MCS_SET, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + status = FALSE; + hddLog(LOGE, "Could not pass on MCS SET to CCM"); + } +#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES + + if (eHAL_STATUS_SUCCESS != sme_update_nss(hdd_ctx->hHal, nss)) + status = FALSE; + + return (status == FALSE) ? VOS_STATUS_E_FAILURE : VOS_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c new file mode 100644 index 0000000000000..d50fce5c738f0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -0,0 +1,16135 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_cfg80211.c + + \brief WLAN Host Device Driver implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 21/12/09 Ashwani Created module. + + 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID + Ganesh K + ==========================================================================*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CNSS +#include +#endif +#include +#include +#include +#include "ccmApi.h" +#include "sirParams.h" +#include "dot11f.h" +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_wext.h" +#include "sme_Api.h" +#include "wlan_hdd_p2p.h" +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_hostapd.h" +#include "wlan_hdd_softap_tx_rx.h" +#include "wlan_hdd_main.h" +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_power.h" +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_utils.h" +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif +#include "vos_sched.h" +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_wmm.h" +#include "wlan_qct_wda.h" +#include "wlan_nv.h" +#include "wlan_hdd_dev_pwr.h" +#ifdef CONFIG_CNSS +#include +#endif +#include "wlan_hdd_misc.h" +#ifdef WLAN_FEATURE_NAN +#include "nan_Api.h" +#include "wlan_hdd_nan.h" +#endif +#ifdef IPA_OFFLOAD +#include +#endif + +#define g_mode_rates_size (12) +#define a_mode_rates_size (8) +#define FREQ_BASE_80211G (2407) +#define FREQ_BAND_DIFF_80211G (5) +#define MAX_SCAN_SSID 10 +#define MAX_PENDING_LOG 5 +#define MAX_HT_MCS_IDX 8 +#define MAX_VHT_MCS_IDX 10 +#define INVALID_MCS_IDX 255 +#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \ + ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields))) + +/* For IBSS, enable obss, fromllb, overlapOBSS & overlapFromllb protection + check. The bit map is defined in: + + typedef struct sCfgProtection + { + tANI_U32 overlapFromlla:1; + tANI_U32 overlapFromllb:1; + tANI_U32 overlapFromllg:1; + tANI_U32 overlapHt20:1; + tANI_U32 overlapNonGf:1; + tANI_U32 overlapLsigTxop:1; + tANI_U32 overlapRifs:1; + tANI_U32 overlapOBSS:1; + tANI_U32 fromlla:1; + tANI_U32 fromllb:1; + tANI_U32 fromllg:1; + tANI_U32 ht20:1; + tANI_U32 nonGf:1; + tANI_U32 lsigTxop:1; + tANI_U32 rifs:1; + tANI_U32 obss:1; + }tCfgProtection, *tpCfgProtection; + +*/ +#define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282 + +#define HDD2GHZCHAN(freq, chan, flag) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (freq), \ + .hw_value = (chan),\ + .flags = (flag), \ + .max_antenna_gain = 0 ,\ + .max_power = 30, \ +} + +#define HDD5GHZCHAN(freq, chan, flag) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = (freq), \ + .hw_value = (chan),\ + .flags = (flag), \ + .max_antenna_gain = 0 ,\ + .max_power = 30, \ +} + +#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\ +{\ + .bitrate = rate, \ + .hw_value = rate_id, \ + .flags = flag, \ +} + +#ifndef WLAN_FEATURE_TDLS_DEBUG +#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO +#else +#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03 +#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 +#endif + +#define HDD_CHANNEL_14 14 +#define WLAN_HDD_MAX_FEATURE_SET 8 + +#ifdef FEATURE_WLAN_EXTSCAN +/* + * Used to allocate the size of 4096 for the EXTScan NL data. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements. + */ + +#define EXTSCAN_EVENT_BUF_SIZE 4096 +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* + * Used to allocate the size of 4096 for the link layer stats. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define LL_STATS_EVENT_BUF_SIZE 4096 +#endif + +/* EXT TDLS */ +/* + * Used to allocate the size of 4096 for the TDLS. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define EXTTDLS_EVENT_BUF_SIZE 4096 + +static const u32 hdd_cipher_suites[] = +{ + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, +#ifdef FEATURE_WLAN_ESE +#define WLAN_CIPHER_SUITE_BTK 0x004096fe /* use for BTK */ +#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */ + WLAN_CIPHER_SUITE_BTK, + WLAN_CIPHER_SUITE_KRK, + WLAN_CIPHER_SUITE_CCMP, +#else + WLAN_CIPHER_SUITE_CCMP, +#endif +#ifdef FEATURE_WLAN_WAPI + WLAN_CIPHER_SUITE_SMS4, +#endif +#ifdef WLAN_FEATURE_11W + WLAN_CIPHER_SUITE_AES_CMAC, +#endif +}; + +static struct ieee80211_channel hdd_channels_2_4_GHZ[] = +{ + HDD2GHZCHAN(2412, 1, 0) , + HDD2GHZCHAN(2417, 2, 0) , + HDD2GHZCHAN(2422, 3, 0) , + HDD2GHZCHAN(2427, 4, 0) , + HDD2GHZCHAN(2432, 5, 0) , + HDD2GHZCHAN(2437, 6, 0) , + HDD2GHZCHAN(2442, 7, 0) , + HDD2GHZCHAN(2447, 8, 0) , + HDD2GHZCHAN(2452, 9, 0) , + HDD2GHZCHAN(2457, 10, 0) , + HDD2GHZCHAN(2462, 11, 0) , + HDD2GHZCHAN(2467, 12, 0) , + HDD2GHZCHAN(2472, 13, 0) , + HDD2GHZCHAN(2484, 14, 0) , +}; + +static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] = +{ + HDD2GHZCHAN(2412, 1, 0) , + HDD2GHZCHAN(2437, 6, 0) , + HDD2GHZCHAN(2462, 11, 0) , +}; + +static struct ieee80211_channel hdd_channels_5_GHZ[] = +{ + HDD5GHZCHAN(4920, 240, 0) , + HDD5GHZCHAN(4940, 244, 0) , + HDD5GHZCHAN(4960, 248, 0) , + HDD5GHZCHAN(4980, 252, 0) , + HDD5GHZCHAN(5040, 208, 0) , + HDD5GHZCHAN(5060, 212, 0) , + HDD5GHZCHAN(5080, 216, 0) , + HDD5GHZCHAN(5180, 36, 0) , + HDD5GHZCHAN(5200, 40, 0) , + HDD5GHZCHAN(5220, 44, 0) , + HDD5GHZCHAN(5240, 48, 0) , + HDD5GHZCHAN(5260, 52, 0) , + HDD5GHZCHAN(5280, 56, 0) , + HDD5GHZCHAN(5300, 60, 0) , + HDD5GHZCHAN(5320, 64, 0) , + HDD5GHZCHAN(5500,100, 0) , + HDD5GHZCHAN(5520,104, 0) , + HDD5GHZCHAN(5540,108, 0) , + HDD5GHZCHAN(5560,112, 0) , + HDD5GHZCHAN(5580,116, 0) , + HDD5GHZCHAN(5600,120, 0) , + HDD5GHZCHAN(5620,124, 0) , + HDD5GHZCHAN(5640,128, 0) , + HDD5GHZCHAN(5660,132, 0) , + HDD5GHZCHAN(5680,136, 0) , + HDD5GHZCHAN(5700,140, 0) , +#ifdef FEATURE_WLAN_CH144 + HDD5GHZCHAN(5720,144, 0) , +#endif /* FEATURE_WLAN_CH144 */ + HDD5GHZCHAN(5745,149, 0) , + HDD5GHZCHAN(5765,153, 0) , + HDD5GHZCHAN(5785,157, 0) , + HDD5GHZCHAN(5805,161, 0) , + HDD5GHZCHAN(5825,165, 0) , +}; + +static struct ieee80211_rate g_mode_rates[] = +{ + HDD_G_MODE_RATETAB(10, 0x1, 0), + HDD_G_MODE_RATETAB(20, 0x2, 0), + HDD_G_MODE_RATETAB(55, 0x4, 0), + HDD_G_MODE_RATETAB(110, 0x8, 0), + HDD_G_MODE_RATETAB(60, 0x10, 0), + HDD_G_MODE_RATETAB(90, 0x20, 0), + HDD_G_MODE_RATETAB(120, 0x40, 0), + HDD_G_MODE_RATETAB(180, 0x80, 0), + HDD_G_MODE_RATETAB(240, 0x100, 0), + HDD_G_MODE_RATETAB(360, 0x200, 0), + HDD_G_MODE_RATETAB(480, 0x400, 0), + HDD_G_MODE_RATETAB(540, 0x800, 0), +}; + +static struct ieee80211_rate a_mode_rates[] = +{ + HDD_G_MODE_RATETAB(60, 0x10, 0), + HDD_G_MODE_RATETAB(90, 0x20, 0), + HDD_G_MODE_RATETAB(120, 0x40, 0), + HDD_G_MODE_RATETAB(180, 0x80, 0), + HDD_G_MODE_RATETAB(240, 0x100, 0), + HDD_G_MODE_RATETAB(360, 0x200, 0), + HDD_G_MODE_RATETAB(480, 0x400, 0), + HDD_G_MODE_RATETAB(540, 0x800, 0), +}; + +static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ = +{ + .channels = hdd_channels_2_4_GHZ, + .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ), + .band = IEEE80211_BAND_2GHZ, + .bitrates = g_mode_rates, + .n_bitrates = g_mode_rates_size, + .ht_cap.ht_supported = 1, + .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 + | IEEE80211_HT_CAP_GRN_FLD + | IEEE80211_HT_CAP_DSSSCCK40 + | IEEE80211_HT_CAP_LSIG_TXOP_PROT + | IEEE80211_HT_CAP_SGI_40 + | IEEE80211_HT_CAP_SUP_WIDTH_20_40, + .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, + .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ), + .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, + .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 + | IEEE80211_VHT_CAP_SHORT_GI_80 + | IEEE80211_VHT_CAP_TXSTBC +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) + | (IEEE80211_VHT_CAP_RXSTBC_MASK & + ( IEEE80211_VHT_CAP_RXSTBC_1 + | IEEE80211_VHT_CAP_RXSTBC_2)) +#endif + | IEEE80211_VHT_CAP_RXLDPC, +}; + +static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ = +{ + .channels = hdd_social_channels_2_4_GHZ, + .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ), + .band = IEEE80211_BAND_2GHZ, + .bitrates = g_mode_rates, + .n_bitrates = g_mode_rates_size, + .ht_cap.ht_supported = 1, + .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 + | IEEE80211_HT_CAP_GRN_FLD + | IEEE80211_HT_CAP_DSSSCCK40 + | IEEE80211_HT_CAP_LSIG_TXOP_PROT, + .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, + .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ), + .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, +}; + +static struct ieee80211_supported_band wlan_hdd_band_5_GHZ = +{ + .channels = hdd_channels_5_GHZ, + .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ), + .band = IEEE80211_BAND_5GHZ, + .bitrates = a_mode_rates, + .n_bitrates = a_mode_rates_size, + .ht_cap.ht_supported = 1, + .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 + | IEEE80211_HT_CAP_GRN_FLD + | IEEE80211_HT_CAP_DSSSCCK40 + | IEEE80211_HT_CAP_LSIG_TXOP_PROT + | IEEE80211_HT_CAP_SGI_40 + | IEEE80211_HT_CAP_SUP_WIDTH_20_40, + .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, + .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ), + .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, + .vht_cap.vht_supported = 1, + .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 + | IEEE80211_VHT_CAP_SHORT_GI_80 + | IEEE80211_VHT_CAP_TXSTBC +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) + | (IEEE80211_VHT_CAP_RXSTBC_MASK & + ( IEEE80211_VHT_CAP_RXSTBC_1 + | IEEE80211_VHT_CAP_RXSTBC_2)) +#endif + | IEEE80211_VHT_CAP_RXLDPC +}; + +/* This structure contain information what kind of frame are expected in + TX/RX direction for each kind of interface */ +static const struct ieee80211_txrx_stypes +wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ACTION) | + BIT(SIR_MAC_MGMT_PROBE_REQ), + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ACTION) | + BIT(SIR_MAC_MGMT_PROBE_REQ), + }, + [NL80211_IFTYPE_P2P_GO] = { + /* This is also same as for SoftAP */ + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, +}; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +/* Interface limits and combinations registered by the driver */ + +/* STA ( + STA ) combination */ +static const struct ieee80211_iface_limit +wlan_hdd_sta_iface_limit[] = { + { + .max = 3, /* p2p0 is a STA as well */ + .types = BIT(NL80211_IFTYPE_STATION), + }, +}; + +/* ADHOC (IBSS) limit */ +static const struct ieee80211_iface_limit +wlan_hdd_adhoc_iface_limit[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_ADHOC), + }, +}; + +/* AP ( + AP ) combination */ +static const struct ieee80211_iface_limit +wlan_hdd_ap_iface_limit[] = { + { + .max = (VOS_MAX_NO_OF_SAP_MODE + + SAP_MAX_OBSS_STA_CNT), + .types = BIT(NL80211_IFTYPE_AP), + }, +}; + +/* P2P limit */ +static const struct ieee80211_iface_limit +wlan_hdd_p2p_iface_limit[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_GO), + }, +}; + +static const struct ieee80211_iface_limit +wlan_hdd_sta_ap_iface_limit[] = { + { + /* We need 1 extra STA interface for OBSS scan when SAP starts + * with HT40 in STA+SAP concurrency mode + */ + .max = (1 + SAP_MAX_OBSS_STA_CNT), + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = VOS_MAX_NO_OF_SAP_MODE, + .types = BIT(NL80211_IFTYPE_AP), + }, +}; + +/* STA + P2P combination */ +static const struct ieee80211_iface_limit +wlan_hdd_sta_p2p_iface_limit[] = { + { + /* One reserved for dedicated P2PDEV usage */ + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION) + }, + { + /* Support for two identical (GO + GO or CLI + CLI) + * or dissimilar (GO + CLI) P2P interfaces + */ + .max = 2, + .types = BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT), + }, +}; + +static struct ieee80211_iface_combination +wlan_hdd_iface_combination[] = { + /* STA */ + { + .limits = wlan_hdd_sta_iface_limit, + .num_different_channels = 2, + .max_interfaces = 3, + .n_limits = ARRAY_SIZE(wlan_hdd_sta_iface_limit), + }, + /* ADHOC */ + { + .limits = wlan_hdd_adhoc_iface_limit, + .num_different_channels = 1, + .max_interfaces = 2, + .n_limits = ARRAY_SIZE(wlan_hdd_adhoc_iface_limit), + }, + /* AP */ + { + .limits = wlan_hdd_ap_iface_limit, + .num_different_channels = 2, + .max_interfaces = (SAP_MAX_OBSS_STA_CNT + + VOS_MAX_NO_OF_SAP_MODE), + .n_limits = ARRAY_SIZE(wlan_hdd_ap_iface_limit), + }, + /* P2P */ + { + .limits = wlan_hdd_p2p_iface_limit, + .num_different_channels = 2, + .max_interfaces = 2, + .n_limits = ARRAY_SIZE(wlan_hdd_p2p_iface_limit), + }, + /* STA + AP */ + { + .limits = wlan_hdd_sta_ap_iface_limit, + .num_different_channels = 2, + .max_interfaces = (1 + SAP_MAX_OBSS_STA_CNT + + VOS_MAX_NO_OF_SAP_MODE), + .n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_iface_limit), + .beacon_int_infra_match = true, + }, + /* STA + P2P */ + { + .limits = wlan_hdd_sta_p2p_iface_limit, + .num_different_channels = 2, + /* one interface reserved for P2PDEV dedicated usage */ + .max_interfaces = 4, + .n_limits = ARRAY_SIZE(wlan_hdd_sta_p2p_iface_limit), + .beacon_int_infra_match = true, + }, +}; +#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + + +static struct cfg80211_ops wlan_hdd_cfg80211_ops; + +/* Data rate 100KBPS based on IE Index */ +struct index_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_rate[4]; +}; + +/* 11B, 11G Rate table include Basic rate and Extended rate + The IDX field is the rate index + The HI field is the rate when RSSI is strong or being ignored + (in this case we report actual rate) + The MID field is the rate when RSSI is moderate + (in this case we cap 11b rates at 5.5 and 11g rates at 24) + The LO field is the rate when RSSI is low + (in this case we don't report rates, actual current rate used) + */ +static const struct +{ + v_U8_t beacon_rate_index; + v_U16_t supported_rate[4]; +} supported_data_rate[] = +{ +/* IDX HI HM LM LO (RSSI-based index */ + {2, { 10, 10, 10, 0}}, + {4, { 20, 20, 10, 0}}, + {11, { 55, 20, 10, 0}}, + {12, { 60, 55, 20, 0}}, + {18, { 90, 55, 20, 0}}, + {22, {110, 55, 20, 0}}, + {24, {120, 90, 60, 0}}, + {36, {180, 120, 60, 0}}, + {44, {220, 180, 60, 0}}, + {48, {240, 180, 90, 0}}, + {66, {330, 180, 90, 0}}, + {72, {360, 240, 90, 0}}, + {96, {480, 240, 120, 0}}, + {108, {540, 240, 120, 0}} +}; + +/* MCS Based rate table */ +/* HT MCS parameters with Nss = 1 */ +static struct index_data_rate_type supported_mcs_rate_nss1[] = +{ +/* MCS L20 L40 S20 S40 */ + {0, {65, 135, 72, 150}}, + {1, {130, 270, 144, 300}}, + {2, {195, 405, 217, 450}}, + {3, {260, 540, 289, 600}}, + {4, {390, 810, 433, 900}}, + {5, {520, 1080, 578, 1200}}, + {6, {585, 1215, 650, 1350}}, + {7, {650, 1350, 722, 1500}} +}; +/* HT MCS parameters with Nss = 2 */ +static struct index_data_rate_type supported_mcs_rate_nss2[] = +{ +/* MCS L20 L40 S20 S40 */ + {0, {130, 270, 144, 300}}, + {1, {260, 540, 289, 600}}, + {2, {390, 810, 433, 900}}, + {3, {520, 1080, 578, 1200}}, + {4, {780, 1620, 867, 1800}}, + {5, {1040, 2160, 1156, 2400}}, + {6, {1170, 2430, 1300, 2700}}, + {7, {1300, 2700, 1444, 3000}} +}; + +#ifdef WLAN_FEATURE_11AC + +#define DATA_RATE_11AC_MCS_MASK 0x03 + +struct index_vht_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_VHT80_rate[2]; + v_U16_t supported_VHT40_rate[2]; + v_U16_t supported_VHT20_rate[2]; +}; + +typedef enum +{ + DATA_RATE_11AC_MAX_MCS_7, + DATA_RATE_11AC_MAX_MCS_8, + DATA_RATE_11AC_MAX_MCS_9, + DATA_RATE_11AC_MAX_MCS_NA +} eDataRate11ACMaxMcs; + +/* SSID broadcast type */ +typedef enum eSSIDBcastType +{ + eBCAST_UNKNOWN = 0, + eBCAST_NORMAL = 1, + eBCAST_HIDDEN = 2, +} tSSIDBcastType; + +/* MCS Based VHT rate table */ +/* MCS parameters with Nss = 1*/ +static struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = +{ +/* MCS L80 S80 L40 S40 L20 S40*/ + {0, {293, 325}, {135, 150}, {65, 72}}, + {1, {585, 650}, {270, 300}, {130, 144}}, + {2, {878, 975}, {405, 450}, {195, 217}}, + {3, {1170, 1300}, {540, 600}, {260, 289}}, + {4, {1755, 1950}, {810, 900}, {390, 433}}, + {5, {2340, 2600}, {1080, 1200}, {520, 578}}, + {6, {2633, 2925}, {1215, 1350}, {585, 650}}, + {7, {2925, 3250}, {1350, 1500}, {650, 722}}, + {8, {3510, 3900}, {1620, 1800}, {780, 867}}, + {9, {3900, 4333}, {1800, 2000}, {780, 867}} +}; + +/*MCS parameters with Nss = 2*/ +static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = +{ +/* MCS L80 S80 L40 S40 L20 S40*/ + {0, {585, 650}, {270, 300}, {130, 144}}, + {1, {1170, 1300}, {540, 600}, {260, 289}}, + {2, {1755, 1950}, {810, 900}, {390, 433}}, + {3, {2340, 2600}, {1080, 1200}, {520, 578}}, + {4, {3510, 3900}, {1620, 1800}, {780, 867}}, + {5, {4680, 5200}, {2160, 2400}, {1040, 1156}}, + {6, {5265, 5850}, {2430, 2700}, {1170, 1300}}, + {7, {5850, 6500}, {2700, 3000}, {1300, 1444}}, + {8, {7020, 7800}, {3240, 3600}, {1560, 1733}}, + {9, {7800, 8667}, {3600, 4000}, {1560, 1733}} +}; +#endif /* WLAN_FEATURE_11AC */ + +/* Array index points to MCS and array value points respective rssi */ +static int rssiMcsTbl[][10] = +{ +/*MCS 0 1 2 3 4 5 6 7 8 9*/ + {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20 + {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40 + {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80 +}; + +extern struct net_device_ops net_ops_struct; + +#ifdef WLAN_NL80211_TESTMODE +enum wlan_hdd_tm_attr +{ + WLAN_HDD_TM_ATTR_INVALID = 0, + WLAN_HDD_TM_ATTR_CMD = 1, + WLAN_HDD_TM_ATTR_DATA = 2, + WLAN_HDD_TM_ATTR_STREAM_ID = 3, + WLAN_HDD_TM_ATTR_TYPE = 4, + /* keep last */ + WLAN_HDD_TM_ATTR_AFTER_LAST, + WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1, +}; + +enum wlan_hdd_tm_cmd +{ + WLAN_HDD_TM_CMD_WLAN_FTM = 0, + WLAN_HDD_TM_CMD_WLAN_HB = 1, +}; + +#define WLAN_HDD_TM_DATA_MAX_LEN 5000 + +static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] = +{ + [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 }, + [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY, + .len = WLAN_HDD_TM_DATA_MAX_LEN }, +}; +#endif /* WLAN_NL80211_TESTMODE */ + +#ifdef FEATURE_WLAN_EXTSCAN + +static const struct nla_policy +wlan_hdd_extscan_config_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] = +{ + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 }, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = { .type = NLA_U8 }, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = { .type = NLA_UNSPEC }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type = NLA_U32 }, +}; + +static const struct nla_policy +wlan_hdd_extscan_results_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX + 1] = +{ + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD] = { .type = NLA_U16 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY] = { .type = NLA_U16 }, +}; + + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC) +/* + * FUNCTION: wlan_hdd_send_avoid_freq_event + * This is called when wlan driver needs to send vendor specific + * avoid frequency range event to user space + */ +int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx, + tHddAvoidFreqList *pAvoidFreqList) +{ + struct sk_buff *vendor_event; + + ENTER(); + + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return -1; + } + + if (!pAvoidFreqList) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAvoidFreqList is null", __func__); + return -1; + } + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + sizeof(tHddAvoidFreqList), + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX, + GFP_KERNEL); + if (!vendor_event) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_event_alloc failed", __func__); + return -1; + } + + memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)), + (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList)); + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + + EXIT(); + return 0; +} +#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC */ + +#ifdef WLAN_FEATURE_NAN +/* + * FUNCTION: wlan_hdd_cfg80211_nan_request + * This is called when wlan driver needs to send vendor specific + * nan request event. + */ +static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tNanRequestReq nan_req; + VOS_STATUS status; + int ret_val = -1; + + nan_req.request_data_len = data_len; + nan_req.request_data = (void *)data; + + status = sme_NanRequest(&nan_req); + if (VOS_STATUS_SUCCESS == status) { + ret_val = 0; + } + return ret_val; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_nan_callback + * This is a callback function and it gets called + * when we need to report nan response event to + * upper layers. + */ +static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *vendor_event; + int status; + tSirNanEvent *data; + + if (NULL == msg) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL(" msg received here is null")); + return; + } + data = msg; + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + data->event_data_len + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX, + GFP_KERNEL); + + if (!vendor_event) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, + data->event_data_len, data->event_data)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR_NAN put fail")); + kfree_skb(vendor_event); + return; + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); +} + +/* + * FUNCTION: wlan_hdd_cfg80211_nan_init + * This function is called to register the callback to sme layer + */ +void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx) +{ + sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback); +} + +#endif + +/* vendor specific events */ +static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = +{ +#ifdef FEATURE_WLAN_CH_AVOID + [QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY + }, +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_NAN + [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN + }, +#endif + +#ifdef WLAN_FEATURE_STATS_EXT + [QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT + }, +#endif /* WLAN_FEATURE_STATS_EXT */ +#ifdef FEATURE_WLAN_EXTSCAN + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE + }, +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS + }, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +/* EXT TDLS */ + [QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE + }, +}; + +static int is_driver_dfs_capable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + u32 dfs_capability = 0; + struct sk_buff *temp_skbuff; + int ret_val; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) + dfs_capability = !!(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD); +#endif + + temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + NLMSG_HDRLEN); + + if (temp_skbuff != NULL) + { + + ret_val = nla_put_u32(temp_skbuff, QCA_WLAN_VENDOR_ATTR_DFS, + dfs_capability); + if (ret_val) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR_DFS put fail", __func__); + kfree_skb(temp_skbuff); + + return ret_val; + } + + return cfg80211_vendor_cmd_reply(temp_skbuff); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: dfs capability: buffer alloc fail", __func__); + return -1; + +} + +static int +__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct sk_buff *skb = NULL; + tANI_U32 fset = 0; + int ret; + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("Hdd context not valid")); + return -EINVAL; + } + + if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { + hddLog(LOG1, FL("Infra Station mode is supported by driver")); + fset |= WIFI_FEATURE_INFRA; + } + + if (TRUE == hdd_is_5g_supported(pHddCtx)) { + hddLog(LOG1, FL("INFRA_5G is supported by firmware")); + fset |= WIFI_FEATURE_INFRA_5G; + } + +#ifdef WLAN_FEATURE_P2P + if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) && + (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) { + hddLog(LOG1, FL("WiFi-Direct is supported by driver")); + fset |= WIFI_FEATURE_P2P; + } +#endif + + /* Soft-AP is supported currently by default */ + fset |= WIFI_FEATURE_SOFT_AP; + +#ifdef FEATURE_WLAN_EXTSCAN + if (sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) { + hddLog(LOG1, FL("EXTScan is supported by firmware")); + fset |= WIFI_FEATURE_EXTSCAN; + } +#endif + +#ifdef WLAN_FEATURE_NAN + if (sme_IsFeatureSupportedByFW(NAN)) { + hddLog(LOG1, FL("NAN is supported by firmware")); + fset |= WIFI_FEATURE_NAN; + } +#endif + + if (sme_IsFeatureSupportedByFW(RTT)) { + hddLog(LOG1, FL("RTT is supported by firmware")); + fset |= WIFI_FEATURE_D2D_RTT; + fset |= WIFI_FEATURE_D2AP_RTT; + } + +#ifdef FEATURE_WLAN_BATCH_SCAN + if (fset & WIFI_FEATURE_EXTSCAN) { + hddLog(LOG1, FL("Batch scan is supported as extscan is supported")); + fset &= ~WIFI_FEATURE_BATCH_SCAN; + } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) { + hddLog(LOG1, FL("Batch scan (legacy) is supported by firmware")); + fset |= WIFI_FEATURE_BATCH_SCAN; + } +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO + if (pHddCtx->cfg_ini->configPNOScanSupport && + sme_IsFeatureSupportedByFW(PNO)) { + hddLog(LOG1, FL("PNO is supported by firmware")); + fset |= WIFI_FEATURE_PNO; + } +#endif + + /* STA+STA is supported currently by default */ + fset |= WIFI_FEATURE_ADDITIONAL_STA; + +#ifdef FEATURE_WLAN_TDLS + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) && + sme_IsFeatureSupportedByFW(TDLS)) { + hddLog(LOG1, FL("TDLS is supported by firmware")); + fset |= WIFI_FEATURE_TDLS; + } + + if (sme_IsFeatureSupportedByFW(TDLS) && + (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) { + hddLog(LOG1, FL("TDLS off-channel is supported by firmware")); + fset |= WIFI_FEATURE_TDLS_OFFCHANNEL; + } +#endif + +#ifdef WLAN_AP_STA_CONCURRENCY + /* AP+STA concurrency is supported currently by default */ + fset |= WIFI_FEATURE_AP_STA; +#endif + + if (hdd_link_layer_stats_supported()) + fset |= WIFI_FEATURE_LINK_LAYER_STATS; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) + + NLMSG_HDRLEN); + + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -EINVAL; + } + hddLog(LOG1, FL("Supported Features : 0x%x"), fset); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) { + hddLog(LOGE, FL("nla put fail")); + goto nla_put_failure; + } + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_get_supported_features() - get supported features + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +static int +wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, + data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int +wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirScanMacOui pReqMsg = NULL; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1]; + eHalStatus status; + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + if (FALSE == pHddCtx->cfg_ini->enable_mac_spoofing) { + hddLog(LOGW, FL("MAC address spoofing is not enabled")); + return -ENOTSUPP; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX, + data, data_len, + NULL)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(LOGE, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch oui */ + if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) { + hddLog(LOGE, FL("attr mac oui failed")); + goto fail; + } + + nla_memcpy(&pReqMsg->oui[0], + tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI], + sizeof(pReqMsg->oui)); + + hddLog(LOG1, FL("Oui (%02x:%02x:%02x)"), pReqMsg->oui[0], pReqMsg->oui[1], + pReqMsg->oui[2]); + + status = sme_SetScanningMacOui(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_SetScanningMacOui failed(err=%d)"), status); + goto fail; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int +__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0}; + uint8_t i, feature_sets, max_feature_sets; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1]; + struct sk_buff *reply_skb; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX, + data, data_len, NULL)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch max feature set */ + if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) { + hddLog(LOGE, FL("Attr max feature set size failed")); + return -EINVAL; + } + max_feature_sets = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]); + hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets); + + /* Fill feature combination matrix */ + feature_sets = 0; + if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err; + feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA | + WIFI_FEATURE_P2P; + + /* Add more feature combinations here */ + + feature_sets = VOS_MIN(feature_sets, max_feature_sets); + hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets); + hddLog(LOG1, "Feature set matrix"); + for (i = 0; i < feature_sets; i++) + hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]); + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(u32) * feature_sets + + NLMSG_HDRLEN); + + if (reply_skb) { + if (nla_put_u32(reply_skb, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE, + feature_sets) || + nla_put(reply_skb, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET, + sizeof(u32) * feature_sets, feature_set_matrix)) { + hddLog(LOGE, FL("nla put fail")); + kfree_skb(reply_skb); + return -EINVAL; + } + + return cfg80211_vendor_cmd_reply(reply_skb); + } + hddLog(LOGE, FL("Feature set matrix: buffer alloc fail")); + return -ENOMEM; + +max_buffer_err: + hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"), + feature_sets, WLAN_HDD_MAX_FEATURE_SET); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +static int +wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data, + data_len); + vos_ssr_unprotect(__func__); + return ret; +} + +#ifdef WLAN_FEATURE_STATS_EXT +static int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tStatsExtRequestReq stats_ext_req; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int ret_val = -1; + eHalStatus status; + + stats_ext_req.request_data_len = data_len; + stats_ext_req.request_data = (void *)data; + + status = sme_StatsExtRequest(pAdapter->sessionId, &stats_ext_req); + + if (eHAL_STATUS_SUCCESS == status) + ret_val = 0; + + return ret_val; +} + +static void wlan_hdd_cfg80211_stats_ext_callback(void* ctx, tStatsExtEvent* msg) +{ + + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *vendor_event; + int status; + int ret_val; + tStatsExtEvent *data = msg; + hdd_adapter_t *pAdapter = NULL; + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return; + } + + pAdapter = hdd_get_adapter_by_vdev( pHddCtx, data->vdev_id); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vdev_id %d does not exist with host", + __func__, data->vdev_id); + return; + } + + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + data->event_data_len + + sizeof(tANI_U32) + + NLMSG_HDRLEN + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_event_alloc failed", __func__); + return; + } + + ret_val = nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_IFINDEX, + pAdapter->dev->ifindex); + if (ret_val) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR_IFINDEX put fail", __func__); + kfree_skb(vendor_event); + + return; + } + + + ret_val = nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_STATS_EXT, + data->event_data_len, data->event_data); + + if (ret_val) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR_STATS_EXT put fail", __func__); + kfree_skb(vendor_event); + + return; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + +} + + +void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx) +{ + sme_StatsExtRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_stats_ext_callback); +} + +#endif + +#ifdef FEATURE_WLAN_EXTSCAN +static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirGetExtScanCapabilitiesReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + status = sme_ExtScanGetCapabilities(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ExtScanGetCapabilities failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_extscan_get_capabilities() - get ext scan capabilities + * @wiphy: Pointer to wiphy + * @wdev: Pointer to wdev + * @data: Pointer to data + * @data_len: Data length + * + * Return: 0 for success, non-zero for failure + */ +static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, + data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanGetCachedResultsReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + /* Parse and fetch flush parameter */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed")); + goto fail; + } + pReqMsg->flush = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush); + + status = sme_getCachedResults(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_getCachedResults failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanSetBssidHotListReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *apTh; + eHalStatus status; + tANI_U8 i; + int rem; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + /* Parse and fetch number of APs */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed")); + goto fail; + } + pReqMsg->numAp = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + i = 0; + nla_for_each_nested(apTh, + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) { + if (nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(apTh), nla_len(apTh), + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed")); + goto fail; + } + + /* Parse and fetch MAC address */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed")); + goto fail; + } + nla_memcpy(pReqMsg->ap[i].bssid, + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID], + sizeof(tSirMacAddr)); + hddLog(VOS_TRACE_LEVEL_INFO, MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid)); + + /* Parse and fetch low RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed")); + goto fail; + } + pReqMsg->ap[i].low = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low); + + /* Parse and fetch high RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed")); + goto fail; + } + pReqMsg->ap[i].high = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"), + pReqMsg->ap[i].high); + + /* Parse and fetch channel */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed")); + goto fail; + } + pReqMsg->ap[i].channel = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel (%u)"), + pReqMsg->ap[i].channel); + i++; + } + + status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_SetBssHotlist failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_set_significant_change( + struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanSetSigChangeReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *apTh; + eHalStatus status; + tANI_U8 i; + int rem; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + /* Parse and fetch RSSI sample size */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed")); + goto fail; + } + pReqMsg->rssiSampleSize = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize); + + /* Parse and fetch lost AP sample size */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed")); + goto fail; + } + pReqMsg->lostApSampleSize = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize); + + /* Parse and fetch AP min breaching */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr AP min breaching")); + goto fail; + } + pReqMsg->minBreaching = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("AP min breaching (%u)"), pReqMsg->minBreaching); + + /* Parse and fetch number of APs */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed")); + goto fail; + } + pReqMsg->numAp = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + i = 0; + nla_for_each_nested(apTh, + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) { + if (nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(apTh), nla_len(apTh), + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed")); + goto fail; + } + + /* Parse and fetch MAC address */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed")); + goto fail; + } + nla_memcpy(pReqMsg->ap[i].bssid, + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID], + sizeof(tSirMacAddr)); + hddLog(VOS_TRACE_LEVEL_INFO, MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid)); + + /* Parse and fetch low RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed")); + goto fail; + } + pReqMsg->ap[i].low = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low); + + /* Parse and fetch high RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed")); + goto fail; + } + pReqMsg->ap[i].high = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("RSSI High (%d)"), pReqMsg->ap[i].high); + + /* Parse and fetch channel */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed")); + goto fail; + } + pReqMsg->ap[i].channel = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Channel (%u)"), pReqMsg->ap[i].channel); + i++; + } + + status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_SetSignificantChange failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + tANI_U32 requestId, maxChannels; + tWifiBand wifiBand; + eHalStatus status; + struct sk_buff *reply_skb; + tANI_U8 i; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId); + + /* Parse and fetch wifi band */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed")); + return -EINVAL; + } + wifiBand = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand); + + /* Parse and fetch max channels */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]) { + hddLog(LOGE, FL("attr max channels failed")); + return -EINVAL; + } + maxChannels = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]); + hddLog(LOG1, FL("Max channels (%d)"), maxChannels); + + status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal), + wifiBand, ChannelList, + &numChannels); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_GetValidChannelsByBand failed (err=%d)"), status); + return -EINVAL; + } + + numChannels = VOS_MIN(numChannels, maxChannels); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels); + for (i = 0; i < numChannels; i++) + hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]); + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(u32) * numChannels + + NLMSG_HDRLEN); + + if (reply_skb) { + if (nla_put_u32(reply_skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS, + numChannels) || + nla_put(reply_skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS, + sizeof(u32) * numChannels, ChannelList)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + kfree_skb(reply_skb); + return -EINVAL; + } + + return cfg80211_vendor_cmd_reply(reply_skb); + } + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("valid channels: buffer alloc fail")); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirWifiScanCmdReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *buckets; + struct nlattr *channels; + int rem1, rem2; + eHalStatus status; + tANI_U8 bktIndex, j, numChannels; + tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + /* Parse and fetch base period */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed")); + goto fail; + } + pReqMsg->basePeriod = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"), + pReqMsg->basePeriod); + + /* Parse and fetch max AP per scan */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed")); + goto fail; + } + pReqMsg->maxAPperScan = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"), + pReqMsg->maxAPperScan); + + /* Parse and fetch report threshold */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed")); + goto fail; + } + pReqMsg->reportThreshold = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"), + pReqMsg->reportThreshold); + + /* Parse and fetch number of buckets */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed")); + goto fail; + } + pReqMsg->numBuckets = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]); + if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) { + hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets " + "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS); + pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"), + pReqMsg->numBuckets); + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed")); + goto fail; + } + + bktIndex = 0; + nla_for_each_nested(buckets, + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) { + if (nla_parse(bucket, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(buckets), nla_len(buckets), NULL)) { //policy + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed")); + goto fail; + } + + /* Parse and fetch bucket spec */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].bucket = nla_get_u8( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), + pReqMsg->buckets[bktIndex].bucket); + + /* Parse and fetch wifi band */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].band = nla_get_u8( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), + pReqMsg->buckets[bktIndex].band); + + /* Parse and fetch period */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].period = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"), + pReqMsg->buckets[bktIndex].period); + + /* Parse and fetch report events */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"), + pReqMsg->buckets[bktIndex].reportEvents); + + /* Framework shall pass the channel list if the input WiFi band is + * WIFI_BAND_UNSPECIFIED. + * If the input WiFi band is specified (any value other than + * WIFI_BAND_UNSPECIFIED) then driver populates the channel list */ + if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) { + numChannels = 0; + hddLog(LOG1, "WiFi band is specified, driver to fill channel list"); + status = sme_GetValidChannelsByBand(pHddCtx->hHal, + pReqMsg->buckets[bktIndex].band, + chanList, &numChannels); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_GetValidChannelsByBand failed (err=%d)"), status); + goto fail; + } + + pReqMsg->buckets[bktIndex].numChannels = + VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS); + hddLog(LOG1, FL("Num channels (%d)"), + pReqMsg->buckets[bktIndex].numChannels); + + for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels; j++) { + pReqMsg->buckets[bktIndex].channels[j].channel = chanList[j]; + pReqMsg->buckets[bktIndex].channels[j].chnlClass = 0; + if (CSR_IS_CHANNEL_DFS(vos_freq_to_chan(chanList[j]))) { + pReqMsg->buckets[bktIndex].channels[j].passive = 1; + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = + CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT; + } else { + pReqMsg->buckets[bktIndex].channels[j].passive = 0; + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = + CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT; + } + + hddLog(LOG1, + "Channel(%u) Passive(%u) Dwell time(%u ms) Class(%u)", + pReqMsg->buckets[bktIndex].channels[j].channel, + pReqMsg->buckets[bktIndex].channels[j].passive, + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs, + pReqMsg->buckets[bktIndex].channels[j].chnlClass); + } + continue; + } + + /* Parse and fetch number of channels */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].numChannels = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"), + pReqMsg->buckets[bktIndex].numChannels); + + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed")); + goto fail; + } + + j = 0; + nla_for_each_nested(channels, + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) { + if (nla_parse(channel, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(channels), nla_len(channels), + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed")); + goto fail; + } + + /* Parse and fetch channel */ + if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32( + channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"), + pReqMsg->buckets[bktIndex].channels[j].channel); + + /* Parse and fetch dwell time */ + if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32( + channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"), + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs); + + /* Parse and fetch channel spec passive */ + if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("attr channel spec passive failed")); + goto fail; + } + pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8( + channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"), + pReqMsg->buckets[bktIndex].channels[j].passive); + j++; + } + bktIndex++; + } + + status = sme_ExtScanStart(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ExtScanStart failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanStopReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + status = sme_ExtScanStop(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ExtScanStop failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanResetBssidHotlistReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ResetBssHotlist failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_reset_significant_change( + struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + tpSirExtScanResetSignificantChangeReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + + ENTER(); + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + pReqMsg = vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + goto fail; + } + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ResetSignificantChange failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + return 0; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +static bool put_wifi_rate_stat( tpSirWifiRateStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + stats->rate.preamble) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + stats->rate.nss) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + stats->rate.bw) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + stats->rate.rateMcsIdx) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + stats->rate.bitrate ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + stats->mpduLost ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + stats->retries) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + stats->retriesLong)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_peer_info( tpSirWifiPeerInfo stats, + struct sk_buff *vendor_event) +{ + u32 i = 0; + tpSirWifiRateStat pRateStats; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + stats->type) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + stats->capabilities) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + stats->numRate)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + goto error; + } + + if (stats->numRate) + { + struct nlattr *rateInfo; + struct nlattr *rates; + + rateInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO); + if (rateInfo == NULL) + goto error; + + for (i = 0; i < stats->numRate; i++) + { + pRateStats = (tpSirWifiRateStat )((uint8 *) + stats->rateStats + + (i * sizeof(tSirWifiRateStat))); + rates = nla_nest_start(vendor_event, i); + if (rates == NULL) + goto error; + + if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + nla_nest_end(vendor_event, rates); + } + nla_nest_end(vendor_event, rateInfo); + } + + return TRUE; +error: + return FALSE; +} + +static bool put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + stats->ac ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + stats->txMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + stats->rxMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + stats->rxAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + stats->txAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + stats->mpduLost )|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + stats->retries ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + stats->retriesLong ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + stats->contentionTimeMin ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + stats->contentionTimeMax ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + stats->contentionTimeAvg ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + stats->contentionNumSamples )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_interface_info(tpSirWifiInterfaceInfo stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, + stats->mode ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + VOS_MAC_ADDR_SIZE, stats->macAddr) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + stats->state ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + stats->roaming ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + stats->capabilities ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + strlen(stats->ssid), stats->ssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + VOS_MAC_ADDR_SIZE, stats->bssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat, + u32 num_peers, + struct sk_buff *vendor_event) +{ + int i = 0; + struct nlattr *wmmInfo; + struct nlattr *wmmStats; + + if (FALSE == put_wifi_interface_info( + &pWifiIfaceStat->info, + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + num_peers) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + pWifiIfaceStat->beaconRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + pWifiIfaceStat->mgmtRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + pWifiIfaceStat->mgmtActionRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + pWifiIfaceStat->mgmtActionTx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + pWifiIfaceStat->rssiMgmt) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + pWifiIfaceStat->rssiData) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + pWifiIfaceStat->rssiAck)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + + wmmInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO); + if (wmmInfo == NULL) + return FALSE; + + for (i = 0; i < WIFI_AC_MAX; i++) + { + wmmStats = nla_nest_start(vendor_event, i); + if (wmmStats == NULL) + return FALSE; + + if (FALSE == put_wifi_wmm_ac_stat( + &pWifiIfaceStat->AccessclassStats[i], + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("put_wifi_wmm_ac_stat Fail")); + return FALSE; + } + + nla_nest_end(vendor_event, wmmStats); + } + nla_nest_end(vendor_event, wmmInfo); + return TRUE; +} + +static tSirWifiInterfaceMode +hdd_map_device_to_ll_iface_mode ( int deviceMode ) +{ + switch (deviceMode) + { + case WLAN_HDD_INFRA_STATION: + return WIFI_INTERFACE_STA; + case WLAN_HDD_SOFTAP: + return WIFI_INTERFACE_SOFTAP; + case WLAN_HDD_P2P_CLIENT: + return WIFI_INTERFACE_P2P_CLIENT; + case WLAN_HDD_P2P_GO: + return WIFI_INTERFACE_P2P_GO; + case WLAN_HDD_IBSS: + return WIFI_INTERFACE_IBSS; + default: + /* Return Interface Mode as STA for all the unsupported modes */ + return WIFI_INTERFACE_STA; + } +} + +static bool hdd_get_interface_info(hdd_adapter_t *pAdapter, + tpSirWifiInterfaceInfo pInfo) +{ + v_U8_t *staMac = NULL; + hdd_station_ctx_t *pHddStaCtx; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode); + + vos_mem_copy(pInfo->macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_DISCONNECTED; + } + if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Session ID %d, Connection is in progress", __func__, + pAdapter->sessionId); + pInfo->state = WIFI_ASSOCIATING; + } + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]); + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: client " MAC_ADDRESS_STR + " is in the middle of WPS/EAPOL exchange.", __func__, + MAC_ADDR_ARRAY(staMac)); + pInfo->state = WIFI_AUTHENTICATING; + } + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_ASSOCIATED; + vos_mem_copy(pInfo->bssid, + &pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE); + vos_mem_copy(pInfo->ssid, + pHddStaCtx->conn_info.SSID.SSID.ssId, + pHddStaCtx->conn_info.SSID.SSID.length); + /* + * NULL Terminate the string + */ + pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0; + } + } + + vos_mem_copy(pInfo->countryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + vos_mem_copy(pInfo->apCountryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + return TRUE; +} + +/* + * hdd_link_layer_process_peer_stats () - This function is called after + * receiving Link Layer Peer statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter, + u32 more_data, + tpSirWifiPeerStat pData) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWifiRateStat pWifiRateStat; + tpSirWifiPeerStat pWifiPeerStat; + tpSirWifiPeerInfo pWifiPeerInfo; + struct sk_buff *vendor_event; + int status, i, j; + struct nlattr *peers; + int numRate; + + pWifiPeerStat = pData; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_PEER_ALL : numPeers %u, more data = %u", + pWifiPeerStat->numPeers, + more_data); + + for (i = 0; i < pWifiPeerStat->numPeers; i++) + { + pWifiPeerInfo = (tpSirWifiPeerInfo) + ((uint8 *)pWifiPeerStat->peerInfo + + ( i * sizeof(tSirWifiPeerInfo))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " %d) LL_STATS Channel Stats " + " Peer Type %u " + " peerMacAddress %pM " + " capabilities 0x%x " + " numRate %u ", + i, + pWifiPeerInfo->type, + pWifiPeerInfo->peerMacAddress, + pWifiPeerInfo->capabilities, + pWifiPeerInfo->numRate); + { + for (j = 0; j < pWifiPeerInfo->numRate; j++) + { + pWifiRateStat = (tpSirWifiRateStat) + ((tANI_U8 *) pWifiPeerInfo->rateStats + + ( j * sizeof(tSirWifiRateStat))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " peer Rate Stats " + " preamble %u " + " nss %u " + " bw %u " + " rateMcsIdx %u " + " reserved %u " + " bitrate %u " + " txMpdu %u " + " rxMpdu %u " + " mpduLost %u " + " retries %u " + " retriesShort %u " + " retriesLong %u", + pWifiRateStat->rate.preamble, + pWifiRateStat->rate.nss, + pWifiRateStat->rate.bw, + pWifiRateStat->rate.rateMcsIdx, + pWifiRateStat->rate.reserved, + pWifiRateStat->rate.bitrate, + pWifiRateStat->txMpdu, + pWifiRateStat->rxMpdu, + pWifiRateStat->mpduLost, + pWifiRateStat->retries, + pWifiRateStat->retriesShort, + pWifiRateStat->retriesLong); + } + } + } + + /* + * Allocate a size of 4096 for the peer stats comprising + * each of size = sizeof (tSirWifiPeerInfo) + numRate * + * sizeof (tSirWifiRateStat).Each field is put with an + * NL attribute.The size of 4096 is considered assuming + * that number of rates shall not exceed beyond 50 with + * the sizeof (tSirWifiRateStat) being 32. + */ + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_event_alloc failed", + __func__); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA, + more_data) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + pWifiPeerStat->numPeers)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__); + + kfree_skb(vendor_event); + return; + } + + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo); + + if (pWifiPeerStat->numPeers) + { + struct nlattr *peerInfo; + peerInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO); + if (peerInfo == NULL) { + hddLog(LOGE, FL("nla_nest_start failed")); + kfree_skb(vendor_event); + return; + } + + for (i = 1; i <= pWifiPeerStat->numPeers; i++) + { + peers = nla_nest_start(vendor_event, i); + if (peers == NULL) { + hddLog(LOGE, FL("nla_nest_start failed")); + kfree_skb(vendor_event); + return; + } + + numRate = pWifiPeerInfo->numRate; + + if (FALSE == put_wifi_peer_info( + pWifiPeerInfo, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put_wifi_peer_info fail")); + kfree_skb(vendor_event); + return; + } + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo + + (i * sizeof(tSirWifiPeerInfo)) + + (numRate * sizeof (tSirWifiRateStat))); + nla_nest_end(vendor_event, peers); + } + nla_nest_end(vendor_event, peerInfo); + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * hdd_link_layer_process_iface_stats () - This function is called after + * receiving Link Layer Interface statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter, + tpSirWifiIfaceStat pData, + u32 num_peers) +{ + tpSirWifiIfaceStat pWifiIfaceStat; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status; + int i; + + pWifiIfaceStat = pData; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid") ); + return; + } + + /* + * Allocate a size of 4096 for the interface stats comprising + * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered + * assuming that all these fit with in the limit.Please take + * a call on the limit based on the data requirements on + * interface statistics. + */ + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed") ); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "WMI_LINK_STATS_IFACE Data"); + + if (FALSE == hdd_get_interface_info(pAdapter, + &pWifiIfaceStat->info)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("hdd_get_interface_info get fail")); + kfree_skb(vendor_event); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + " Num peers %u " + "LL_STATS_IFACE: " + " Mode %u " + " MAC %pM " + " State %u " + " Roaming %u " + " capabilities 0x%x " + " SSID %s " + " BSSID %pM", + num_peers, + pWifiIfaceStat->info.mode, + pWifiIfaceStat->info.macAddr, + pWifiIfaceStat->info.state, + pWifiIfaceStat->info.roaming, + pWifiIfaceStat->info.capabilities, + pWifiIfaceStat->info.ssid, + pWifiIfaceStat->info.bssid); + + hddLog(VOS_TRACE_LEVEL_INFO, + " AP country str: %c%c%c", + pWifiIfaceStat->info.apCountryStr[0], + pWifiIfaceStat->info.apCountryStr[1], + pWifiIfaceStat->info.apCountryStr[2]); + + hddLog(VOS_TRACE_LEVEL_INFO, + " Country Str Association: %c%c%c", + pWifiIfaceStat->info.countryStr[0], + pWifiIfaceStat->info.countryStr[1], + pWifiIfaceStat->info.countryStr[2]); + + hddLog(VOS_TRACE_LEVEL_INFO, + " beaconRx %u " + " mgmtRx %u " + " mgmtActionRx %u " + " mgmtActionTx %u " + " rssiMgmt %u " + " rssiData %u " + " rssiAck %u", + pWifiIfaceStat->beaconRx, + pWifiIfaceStat->mgmtRx, + pWifiIfaceStat->mgmtActionRx, + pWifiIfaceStat->mgmtActionTx, + pWifiIfaceStat->rssiMgmt, + pWifiIfaceStat->rssiData, + pWifiIfaceStat->rssiAck ); + + for (i = 0; i < WIFI_AC_MAX; i++) + { + hddLog(VOS_TRACE_LEVEL_INFO, + + " %d) LL_STATS IFACE: " + " ac: %u txMpdu: %u " + " rxMpdu: %u txMcast: %u " + " rxMcast: %u rxAmpdu: %u " + " txAmpdu: %u mpduLost: %u " + " retries: %u retriesShort: %u " + " retriesLong: %u contentionTimeMin: %u " + " contentionTimeMax: %u contentionTimeAvg: %u " + " contentionNumSamples: %u", + i, + pWifiIfaceStat->AccessclassStats[i].ac, + pWifiIfaceStat->AccessclassStats[i].txMpdu, + pWifiIfaceStat->AccessclassStats[i].rxMpdu, + pWifiIfaceStat->AccessclassStats[i].txMcast, + pWifiIfaceStat->AccessclassStats[i].rxMcast, + pWifiIfaceStat->AccessclassStats[i].rxAmpdu, + pWifiIfaceStat->AccessclassStats[i].txAmpdu, + pWifiIfaceStat->AccessclassStats[i].mpduLost, + pWifiIfaceStat->AccessclassStats[i].retries, + pWifiIfaceStat->AccessclassStats[i].retriesShort, + pWifiIfaceStat->AccessclassStats[i].retriesLong, + pWifiIfaceStat->AccessclassStats[i].contentionTimeMin, + pWifiIfaceStat->AccessclassStats[i].contentionTimeMax, + pWifiIfaceStat->AccessclassStats[i].contentionTimeAvg, + pWifiIfaceStat->AccessclassStats[i].contentionNumSamples); + } + + if (FALSE == put_wifi_iface_stats(pWifiIfaceStat, num_peers, vendor_event)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("put_wifi_iface_stats fail")); + kfree_skb(vendor_event); + return; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * hdd_link_layer_process_radio_stats () - This function is called after + * receiving Link Layer Radio statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter, + u32 more_data, + tpSirWifiRadioStat pData, + u32 num_radio) +{ + int status, i; + tpSirWifiRadioStat pWifiRadioStat; + tpSirWifiChannelStats pWifiChannelStats; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + pWifiRadioStat = pData; + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_RADIO" + " number of radios = %u" + " radio is %d onTime is %u" + " txTime is %u rxTime is %u" + " onTimeScan is %u onTimeNbd is %u" + " onTimeGscan is %u onTimeRoamScan is %u" + " onTimePnoScan is %u onTimeHs20 is %u" + " numChannels is %u", + num_radio, + pWifiRadioStat->radio, + pWifiRadioStat->onTime, + pWifiRadioStat->txTime, + pWifiRadioStat->rxTime, + pWifiRadioStat->onTimeScan, + pWifiRadioStat->onTimeNbd, + pWifiRadioStat->onTimeGscan, + pWifiRadioStat->onTimeRoamScan, + pWifiRadioStat->onTimePnoScan, + pWifiRadioStat->onTimeHs20, + pWifiRadioStat->numChannels); + + /* + * Allocate a size of 4096 for the Radio stats comprising + * sizeof (tSirWifiRadioStat) + numChannels * sizeof + * (tSirWifiChannelStats).Each channel data is put with an + * NL attribute.The size of 4096 is considered assuming that + * number of channels shall not exceed beyond 60 with the + * sizeof (tSirWifiChannelStats) being 24 bytes. + */ + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA, + more_data) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, + num_radio) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + pWifiRadioStat->radio) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + pWifiRadioStat->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + pWifiRadioStat->txTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + pWifiRadioStat->rxTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + pWifiRadioStat->onTimeScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + pWifiRadioStat->onTimeNbd) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN, + pWifiRadioStat->onTimeGscan)|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + pWifiRadioStat->onTimeRoamScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + pWifiRadioStat->onTimePnoScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + pWifiRadioStat->onTimeHs20) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + pWifiRadioStat->numChannels)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + + kfree_skb(vendor_event); + return ; + } + + if (pWifiRadioStat->numChannels) + { + struct nlattr *chList; + struct nlattr *chInfo; + + chList = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO); + if (chList == NULL) { + hddLog(LOGE, FL("nla_nest_start failed")); + kfree_skb(vendor_event); + return; + } + + for (i = 0; i < pWifiRadioStat->numChannels; i++) + { + pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*) + pWifiRadioStat->channels + + (i * sizeof(tSirWifiChannelStats))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " %d) Channel Info" + " width is %u " + " CenterFreq %u " + " CenterFreq0 %u " + " CenterFreq1 %u " + " onTime %u " + " ccaBusyTime %u", + i, + pWifiChannelStats->channel.width, + pWifiChannelStats->channel.centerFreq, + pWifiChannelStats->channel.centerFreq0, + pWifiChannelStats->channel.centerFreq1, + pWifiChannelStats->onTime, + pWifiChannelStats->ccaBusyTime); + + chInfo = nla_nest_start(vendor_event, i); + if (chInfo == NULL) { + hddLog(LOGE, FL("nla_nest_start failed")); + kfree_skb(vendor_event); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + pWifiChannelStats->channel.width) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + pWifiChannelStats->channel.centerFreq) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + pWifiChannelStats->channel.centerFreq0) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + pWifiChannelStats->channel.centerFreq1) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + pWifiChannelStats->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + pWifiChannelStats->ccaBusyTime)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed")); + kfree_skb(vendor_event); + return ; + } + nla_nest_end(vendor_event, chInfo); + } + nla_nest_end(vendor_event, chList); + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * wlan_hdd_cfg80211_link_layer_stats_callback () - This function is called + * after receiving Link Layer indications from FW.This callback converts the + * firmware data to the NL data and send the same to the kernel/upper layers. + */ +static void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, + int indType, + void *pRsp) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + hdd_adapter_t *pAdapter = NULL; + tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp; + int status; + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + pAdapter = hdd_get_adapter_by_vdev(pHddCtx, + linkLayerStatsResults->ifaceId); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vdev_id %d does not exist with host", + __func__, linkLayerStatsResults->ifaceId); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Link Layer Indication indType: %d", __func__, indType); + + switch (indType) + { + case SIR_HAL_LL_STATS_RESULTS_RSP: + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP")); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE paramID = 0x%x", + linkLayerStatsResults->paramId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE ifaceId = %u", + linkLayerStatsResults->ifaceId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE respId = %u", + linkLayerStatsResults->rspId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE more data = %u", + linkLayerStatsResults->moreResultToFollow); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE num radio = %u", + linkLayerStatsResults->num_radio); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE result = %p", + linkLayerStatsResults->results); + + if (linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO ) + { + hdd_link_layer_process_radio_stats(pAdapter, + linkLayerStatsResults->moreResultToFollow, + (tpSirWifiRadioStat) + linkLayerStatsResults->results, + linkLayerStatsResults->num_radio); + } + else if (linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE ) + { + hdd_link_layer_process_iface_stats(pAdapter, + (tpSirWifiIfaceStat) + linkLayerStatsResults->results, + linkLayerStatsResults->num_peers); + } + else if (linkLayerStatsResults->paramId & WMI_LINK_STATS_ALL_PEER ) + { + hdd_link_layer_process_peer_stats(pAdapter, + linkLayerStatsResults->moreResultToFollow, + (tpSirWifiPeerStat) + linkLayerStatsResults->results); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("INVALID LL_STATS_NOTIFY RESPONSE ***********")); + } + + break; + } + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType); + break; + } + + return; +} + + +void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx) +{ + sme_SetLinkLayerStatsIndCB(pHddCtx->hHal, + wlan_hdd_cfg80211_link_layer_stats_callback); +} + + +const struct +nla_policy +qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] = + { .type = NLA_U32 }, +}; + +static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int status; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1]; + tSirLLStatsSetReq LinkLayerStatsSetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_set_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("maximum attribute not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present")); + return -EINVAL; + } + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Stats Gathering Not Present")); + return -EINVAL; + } + + /* Shall take the request Id if the Upper layers pass. 1 For now.*/ + LinkLayerStatsSetReq.reqId = 1; + + LinkLayerStatsSetReq.mpduSizeThreshold = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]); + + LinkLayerStatsSetReq.aggressiveStatisticsGathering = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]); + + LinkLayerStatsSetReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET reqId = %d", + LinkLayerStatsSetReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET staId = %d", LinkLayerStatsSetReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET mpduSizeThreshold = %d", + LinkLayerStatsSetReq.mpduSizeThreshold); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET aggressive Statistics Gathering = %d", + LinkLayerStatsSetReq.aggressiveStatisticsGathering); + + + if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq(pHddCtx->hHal, + &LinkLayerStatsSetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsSetReq Failed", __func__); + return -EINVAL; + } + + pAdapter->isLinkLayerStatsSet = 1; + + return 0; +} + +const struct +nla_policy +qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] = +{ + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting + * the stats results, the driver uses the same value to indicate + * which GET request the results + * correspond to. + */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 }, + + /* Unsigned 32bit value . bit mask to identify what statistics are + requested for retrieval */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 } +}; + +static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1]; + tSirLLStatsGetReq LinkLayerStatsGetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int status; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL ; + } + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_get_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("max attribute not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present")); + return -EINVAL; + } + + LinkLayerStatsGetReq.reqId = + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]); + LinkLayerStatsGetReq.paramIdMask = + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]); + + LinkLayerStatsGetReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET reqId = %d", LinkLayerStatsGetReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET staId = %d", LinkLayerStatsGetReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET paramIdMask = %d", + LinkLayerStatsGetReq.paramIdMask); + + if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq(pHddCtx->hHal, + &LinkLayerStatsGetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsGetReq Failed", __func__); + return -EINVAL; + } + + return 0; +} + +const struct +nla_policy +qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 }, +}; + +static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1]; + tSirLLStatsClearReq LinkLayerStatsClearReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + u32 statsClearReqMask; + u8 stopReq; + int status; + struct sk_buff *temp_skbuff; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_clr_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("STATS_CLR_MAX is not present")); + return -EINVAL; + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] || + !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA")); + return -EINVAL; + } + + statsClearReqMask = LinkLayerStatsClearReq.statsClearReqMask = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]); + + stopReq = LinkLayerStatsClearReq.stopReq = + nla_get_u8( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]); + + /* + * Shall take the request Id if the Upper layers pass. 1 For now. + */ + LinkLayerStatsClearReq.reqId = 1; + + LinkLayerStatsClearReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR reqId = %d", LinkLayerStatsClearReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR staId = %d", LinkLayerStatsClearReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR statsClearReqMask = 0x%X", + LinkLayerStatsClearReq.statsClearReqMask); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR stopReq = %d", + LinkLayerStatsClearReq.stopReq); + + if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal, + &LinkLayerStatsClearReq)) + { + temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 2 * sizeof(u32) + + 2 * NLMSG_HDRLEN); + if (temp_skbuff != NULL) + { + if (nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + statsClearReqMask) || + nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + stopReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail")); + kfree_skb(temp_skbuff); + return -EINVAL; + } + + /* If the ask is to stop the stats collection as part of clear + * (stopReq = 1) , ensure that no further requests of get + * go to the firmware by having isLinkLayerStatsSet set to 0. + * However it the stopReq as part of the clear request is 0 , + * the request to get the statistics are honoured as in this + * case the firmware is just asked to clear the statistics. + */ + if (stopReq == 1) + pAdapter->isLinkLayerStatsSet = 0; + + return cfg80211_vendor_cmd_reply(temp_skbuff); + } + return -ENOMEM; + } + + return -EINVAL; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/* EXT TDLS */ +static const struct nla_policy +wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] = + {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 }, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC }, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_state_change_policy[ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC }, + [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 }, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_get_status_policy[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC }, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 }, + +}; + +static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + uint8_t peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1]; + eHalStatus ret; + tANI_S32 state; + tANI_S32 reason; + struct sk_buff *skb = NULL; + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX, + data, data_len, + wlan_hdd_tdls_config_get_status_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute")); + return -EINVAL; + } + + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason); + + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("get status Failed")); + return -EINVAL; + } + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 2 * sizeof(int32_t) + + NLMSG_HDRLEN); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) tdls peer " MAC_ADDRESS_STR), + reason, + state, + MAC_ADDR_ARRAY(peer)); + + if (nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, state) || + nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, reason)) { + + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + return cfg80211_vendor_cmd_reply(skb); + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +/** + * wlan_hdd_cfg80211_exttdls_get_status() - get ext tdls status + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, + data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac, + tANI_S32 state, + tANI_S32 reason, + void *ctx) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + struct sk_buff *skb = NULL; + + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid ")); + return -EINVAL; + } + + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + return -ENOTSUPP; + } + skb = cfg80211_vendor_event_alloc( + pHddCtx->wiphy, + EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering ")); + hddLog(VOS_TRACE_LEVEL_INFO, "Reason (%d) Status (%d)", reason, state); + hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(mac)); + + if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR, + VOS_MAC_ADDR_SIZE, mac) || + nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, state) || + nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, reason) + ) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return (0); + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + uint8_t peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1]; + eHalStatus status; + tdls_req_params_t pReqMsg = {0}; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("TDLS External Control is not enabled")); + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX, + data, data_len, + wlan_hdd_tdls_config_enable_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + /* Parse and fetch channel */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed")); + return -EINVAL; + } + pReqMsg.channel = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel); + + /* Parse and fetch global operating class */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed")); + return -EINVAL; + } + pReqMsg.global_operating_class = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"), + pReqMsg.global_operating_class); + + /* Parse and fetch latency ms */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed")); + return -EINVAL; + } + pReqMsg.max_latency_ms = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"), + pReqMsg.max_latency_ms); + + /* Parse and fetch required bandwidth kbps */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed")); + return -EINVAL; + } + + pReqMsg.min_bandwidth_kbps = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"), + pReqMsg.min_bandwidth_kbps); + + return (wlan_hdd_tdls_extctrl_config_peer(pAdapter, + peer, + wlan_hdd_cfg80211_exttdls_callback, + pReqMsg.channel, + pReqMsg.max_latency_ms, + pReqMsg.global_operating_class, + pReqMsg.min_bandwidth_kbps)); +} + +/** + * wlan_hdd_cfg80211_exttdls_enable() - enable ext tdls + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + u8 peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1]; + eHalStatus status; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX, + data, data_len, + wlan_hdd_tdls_config_disable_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer)); +} + +/** + * wlan_hdd_cfg80211_exttdls_disable() - disable ext tdls + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static const struct nla_policy +wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + +1] = +{ + [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 }, +}; + + +static int wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1]; + eHalStatus status; + int ret_val = -EPERM; + u32 no_dfs_flag = 0; + hdd_adapter_list_node_t *p_adapter_node = NULL, *p_next = NULL; + hdd_adapter_t *p_adapter; + VOS_STATUS vos_status; + hdd_ap_ctx_t *p_ap_ctx; + hdd_station_ctx_t *p_sta_ctx; + + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX, + data, data_len, + wlan_hdd_set_no_dfs_flag_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid attr")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed")); + return -EINVAL; + } + + no_dfs_flag = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]); + + hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag = %d"), + no_dfs_flag); + + if (no_dfs_flag > 1) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid value of dfs flag")); + return -EINVAL; + } + + if (no_dfs_flag == pHddCtx->cfg_ini->enableDFSChnlScan) { + if (no_dfs_flag) { + + vos_status = hdd_get_front_adapter( pHddCtx, &p_adapter_node); + while ((NULL != p_adapter_node) && + (VOS_STATUS_SUCCESS == vos_status)) + { + p_adapter = p_adapter_node->pAdapter; + + if (WLAN_HDD_SOFTAP == p_adapter->device_mode) { + p_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(p_adapter); + + /* if there is SAP already running on DFS channel, + do not disable scan on dfs channels. Note that with + SAP on DFS, there cannot be conurrency on single + radio. But then we can have multiple radios !!!!! */ + if (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState( + p_ap_ctx->operatingChannel)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SAP running on DFS channel")); + return -EOPNOTSUPP; + } + } + + if (WLAN_HDD_INFRA_STATION == p_adapter->device_mode) { + p_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(p_adapter); + + /* if STA is already connected on DFS channel, + do not disable scan on dfs channels */ + if (hdd_connIsConnected(p_sta_ctx) && + (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState( + p_sta_ctx->conn_info.operationChannel))) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("client connected on DFS channel")); + return -EOPNOTSUPP; + } + } + + vos_status = hdd_get_next_adapter(pHddCtx, p_adapter_node, + &p_next); + p_adapter_node = p_next; + } + } + + pHddCtx->cfg_ini->enableDFSChnlScan = !no_dfs_flag; + + hdd_abort_mac_scan_all_adapters(pHddCtx); + + /* call the SME API to tunnel down the new channel list + to the firmware */ + status = sme_handle_dfs_chan_scan(hHal, + pHddCtx->cfg_ini->enableDFSChnlScan); + + if (eHAL_STATUS_SUCCESS == status) { + ret_val = 0; + + /* Clear the SME scan cache also. Note that the clearing of scan + * results is independent of session; so no need to iterate over + * all sessions + */ + status = sme_ScanFlushResult(hHal, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != status) + ret_val = -EPERM; + } + } else { + hddLog(VOS_TRACE_LEVEL_INFO, FL(" the DFS flag has not changed")); + ret_val = 0; + } + + return ret_val; +} + + +const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = +{ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)is_driver_dfs_capable + }, + +#ifdef WLAN_FEATURE_NAN + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_nan_request + }, +#endif + +#ifdef WLAN_FEATURE_STATS_EXT + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_stats_ext_request + }, +#endif +#ifdef FEATURE_WLAN_EXTSCAN + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_start + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_stop + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_extscan_get_valid_channels + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_get_capabilities + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_get_cached_results + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_set_bssid_hotlist + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_reset_bssid_hotlist + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_set_significant_change + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_extscan_reset_significant_change + }, +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_ll_stats_clear + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_ll_stats_set + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_ll_stats_get + }, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +/* EXT TDLS */ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_exttdls_enable + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = (void *)wlan_hdd_cfg80211_exttdls_disable + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_exttdls_get_status + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_get_supported_features + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_set_scanning_mac_oui + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_disable_dfs_chan_scan + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = (void *)wlan_hdd_cfg80211_get_concurrency_matrix + }, +}; + + +/* + * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc + * This function is called by hdd_wlan_startup() + * during initialization. + * This function is used to allocate wiphy structure. + */ +struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size) +{ + struct wiphy *wiphy; + ENTER(); + + /* + * Create wiphy device + */ + wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size); + + if (!wiphy) + { + /* Print error and jump into err label and free the memory */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__); + return NULL; + } + + return wiphy; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_band + * This function is called from the supplicant through a + * private ioctl to change the band value + */ +int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand) +{ + int i, j; + eNVChannelEnabledType channelEnabledState; + + ENTER(); + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (NULL == wiphy->bands[i]) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d", + __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + channelEnabledState = vos_nv_getChannelEnabledState( + band->channels[j].hw_value); + + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only + { +#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY + // Enable Social channels for P2P + if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) && + NV_CHANNEL_ENABLE == channelEnabledState) + band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + else +#endif + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + + if (NV_CHANNEL_DISABLE == channelEnabledState || + NV_CHANNEL_INVALID == channelEnabledState) + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + } + else if (NV_CHANNEL_DFS == channelEnabledState) + { + band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + band->channels[j].flags |= IEEE80211_CHAN_RADAR; + } + else + { + band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED + |IEEE80211_CHAN_RADAR); + } + } + } + return 0; +} +/* + * FUNCTION: wlan_hdd_cfg80211_init + * This function is called by hdd_wlan_startup() + * during initialization. + * This function is used to initialize and register wiphy structure. + */ +int wlan_hdd_cfg80211_init(struct device *dev, + struct wiphy *wiphy, + hdd_config_t *pCfg + ) +{ + int i, j; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + ENTER(); + + /* Now bind the underlying wlan device with wiphy */ + set_wiphy_dev(wiphy, dev); + + wiphy->mgmt_stypes = wlan_hdd_txrx_stypes; + + + /* This will disable updating of NL channels from passive to + * active if a beacon is received on passive channel. */ + wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS; + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME + | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD + | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL +#ifdef FEATURE_WLAN_STA_4ADDR_SCHEME + | WIPHY_FLAG_4ADDR_STATION +#endif + | WIPHY_FLAG_OFFCHAN_TX; + wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE; +#endif + + wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT; + wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED; + wiphy->wowlan.pattern_min_len = 1; + wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pCfg->isFastTransitionEnabled +#ifdef FEATURE_WLAN_LFR + || pCfg->isFastRoamIniFeatureEnabled +#endif +#ifdef FEATURE_WLAN_ESE + || pCfg->isEseIniFeatureEnabled +#endif + ) + { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + } +#endif +#ifdef FEATURE_WLAN_TDLS + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS + | WIPHY_FLAG_TDLS_EXTERNAL_SETUP; +#endif + + wiphy->features |= NL80211_FEATURE_HT_IBSS; + +#ifdef FEATURE_WLAN_SCAN_PNO + if (pCfg->configPNOScanSupport) + { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH; + } +#endif/*FEATURE_WLAN_SCAN_PNO*/ + +#if defined QCA_WIFI_FTM + if (vos_get_conparam() != VOS_FTM_MODE) { +#endif + + /* even with WIPHY_FLAG_CUSTOM_REGULATORY, + driver can still register regulatory callback and + it will get regulatory settings in wiphy->band[], but + driver need to determine what to do with both + regulatory settings */ + + wiphy->reg_notifier = wlan_hdd_linux_reg_notifier; + +#if defined QCA_WIFI_FTM + } +#endif + + wiphy->max_scan_ssids = MAX_SCAN_SSID; + + wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH; + + wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS; + + /* Supports STATION & AD-HOC modes right now */ + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_AP); + + if( pCfg->advertiseConcurrentOperation ) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + if( pCfg->enableMCC ) { + int i; + for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination); i++) { + if( !pCfg->allowMCCGODiffBI ) + wlan_hdd_iface_combination[i].beacon_int_infra_match = true; + } + } + wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination); + wiphy->iface_combinations = wlan_hdd_iface_combination; +#endif + } + + /* Before registering we need to update the HT capability based + * on ini values */ + if( !pCfg->ShortGI20MhzEnable ) + { + wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; + wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; + } + + if( !pCfg->ShortGI40MhzEnable ) + { + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; + } + + if( !pCfg->nChannelBondingMode5GHz ) + { + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + + wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ; + if (true == hdd_is_5g_supported(pHddCtx)) + { + wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ; + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (NULL == wiphy->bands[i]) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d", + __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only + { +#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY + // Enable social channels for P2P + if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq)) + band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + else +#endif + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + } + } + /*Initialise the supported cipher suite details*/ + wiphy->cipher_suites = hdd_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites); + + /*signal strength in mBm (100*dBm) */ + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wiphy->max_remain_on_channel_duration = 1000; + wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands); + wiphy->vendor_commands = hdd_wiphy_vendor_commands; + + wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events; + wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) + if (pCfg->enableDFSMasterCap) { + wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD; + } +#endif + + wiphy->max_ap_assoc_sta = pCfg->maxNumberOfPeers; + +#ifdef QCA_HT_2040_COEX + if (pCfg->ht2040CoexEnabled) + wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; +#endif + +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pCfg->isRoamOffloadEnabled) { + wiphy->flags |= WIPHY_FLAG_HAS_KEY_MGMT_OFFLOAD; + wiphy->key_mgmt_offload_support |= + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PSK; + wiphy->key_mgmt_offload_support |= + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_PSK; + wiphy->key_mgmt_offload_support |= + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_PMKSA; + wiphy->key_mgmt_offload_support |= + NL80211_KEY_MGMT_OFFLOAD_SUPPORT_FT_802_1X; + wiphy->key_derive_offload_support |= + NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_IGTK; + wiphy->key_derive_offload_support |= + NL80211_KEY_DERIVE_OFFLOAD_SUPPORT_SHA256; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: LFR3:Driver key mgmt offload capability flags %x", + __func__,wiphy->key_mgmt_offload_support); + } +#endif +#endif + + EXIT(); + return 0; +} + +/* + * In this function, wiphy structure is updated after VOSS + * initialization. In wlan_hdd_cfg80211_init, only the + * default values will be initialized. The final initialization + * of all required members can be done here. + */ +void wlan_hdd_update_wiphy(struct wiphy *wiphy, + hdd_config_t *pCfg) +{ + wiphy->max_ap_assoc_sta = pCfg->maxNumberOfPeers; +} + +/* In this function we are registering wiphy. */ +int wlan_hdd_cfg80211_register(struct wiphy *wiphy) +{ + ENTER(); + /* Register our wiphy dev with cfg80211 */ + if (0 > wiphy_register(wiphy)) + { + /* print error */ + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__); + return -EIO; + } + + EXIT(); + return 0; +} + +/* + HDD function to update wiphy capability based on target offload status. + + wlan_hdd_cfg80211_init() does initialization of all wiphy related + capability even before downloading firmware to the target. In discrete + case, host will get know certain offload capability (say sched_scan + caps) only after downloading firmware to the target and target boots up. + This function is used to override setting done in wlan_hdd_cfg80211_init() + based on target capability. +*/ +void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy) +{ +#ifdef FEATURE_WLAN_SCAN_PNO + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_config_t *pCfg = pHddCtx->cfg_ini; + + /* wlan_hdd_cfg80211_init() sets sched_scan caps already in wiphy before + * control comes here. Here just we need to clear it if firmware doesn't + * have PNO support. */ + if (!pCfg->PnoOffload) { + wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + wiphy->max_sched_scan_ssids = 0; + wiphy->max_match_sets = 0; + wiphy->max_sched_scan_ie_len = 0; + } +#endif +} + +/* + * In this function we are updating channel list when, + * regulatory domain is FCC and country code is US. + * Here In FCC standard 5GHz UNII-1 Bands are indoor only. + * As per FCC smart phone is not a indoor device. + * GO should not operate on indoor channels. + */ +void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy) +{ + int j; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE; + /* Default country code from NV at the time of wiphy initialization. */ + if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal, + &defaultCountryCode[0])) + { + hddLog(LOGE, FL("Failed to get default country code from NV")); + } + if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S')) + { + if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ]) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ ); + return; + } + for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ]; + // Mark UNII -1 band channel as passive + if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq)) + band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + } +} + +/* This function registers for all frame which supplicant is interested in */ +void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + /* Register for all P2P action, public action etc frames */ + v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4); + + ENTER(); + + /* Right now we are registering these frame when driver is getting + initialized. Once we will move to 2.6.37 kernel, in which we have + frame register ops, we will move this code as a part of that */ + /* GAS Initial Request */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE ); + + /* GAS Initial Response */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE ); + + /* GAS Comeback Request */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE ); + + /* GAS Comeback Response */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE ); + + /* P2P Public Action */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)P2P_PUBLIC_ACTION_FRAME, + P2P_PUBLIC_ACTION_FRAME_SIZE ); + + /* P2P Action */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)P2P_ACTION_FRAME, + P2P_ACTION_FRAME_SIZE ); + + /* WNM BSS Transition Request frame */ + sme_RegisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)WNM_BSS_ACTION_FRAME, + WNM_BSS_ACTION_FRAME_SIZE ); + + /* WNM-Notification */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)WNM_NOTIFICATION_FRAME, + WNM_NOTIFICATION_FRAME_SIZE ); +} + +void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + /* Register for all P2P action, public action etc frames */ + v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4); + + ENTER(); + + /* Right now we are registering these frame when driver is getting + initialized. Once we will move to 2.6.37 kernel, in which we have + frame register ops, we will move this code as a part of that */ + /* GAS Initial Request */ + + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE ); + + /* GAS Initial Response */ + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE ); + + /* GAS Comeback Request */ + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE ); + + /* GAS Comeback Response */ + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE ); + + /* P2P Public Action */ + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)P2P_PUBLIC_ACTION_FRAME, + P2P_PUBLIC_ACTION_FRAME_SIZE ); + + /* P2P Action */ + sme_DeregisterMgmtFrame(hHal, HDD_SESSION_ID_ANY, type, + (v_U8_t*)P2P_ACTION_FRAME, + P2P_ACTION_FRAME_SIZE ); + + /* WNM-Notification */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)WNM_NOTIFICATION_FRAME, + WNM_NOTIFICATION_FRAME_SIZE ); +} + +#ifdef FEATURE_WLAN_WAPI +void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index, + const u8 *mac_addr, u8 *key , int key_Len) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamSetKey setKey; + v_BOOL_t isConnected = TRUE; + int status = 0; + v_U32_t roamId= 0xFF; + tANI_U8 *pKeyPtr = NULL; + int n = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__,pAdapter->device_mode); + + vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; // Store Key ID + setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption + setKey.keyDirection = eSIR_TX_RX; /* Key Direction both TX and RX */ + setKey.paeRole = 0 ; // the PAE role + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) + { + vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac ); + } + else + { + vos_mem_copy(setKey.peerMac, mac_addr, VOS_MAC_ADDR_SIZE); + } + setKey.keyLength = key_Len; + pKeyPtr = setKey.Key; + memcpy( pKeyPtr, key, key_Len); + + hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x", + __func__, key_Len); + for (n = 0 ; n < key_Len; n++) + hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ", + __func__,n,setKey.Key[n]); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + if ( isConnected ) + { + status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + } + if ( status != 0 ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", + __LINE__, status ); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } +} +#endif /* FEATURE_WLAN_WAPI*/ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter, + beacon_data_t **ppBeacon, + struct beacon_parameters *params) +#else +int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter, + beacon_data_t **ppBeacon, + struct cfg80211_beacon_data *params, + int dtim_period) +#endif +{ + int size; + beacon_data_t *beacon = NULL; + beacon_data_t *old = NULL; + int head_len,tail_len; + + ENTER(); + if (params->head && !params->head_len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("head_len is NULL")); + return -EINVAL; + } + + old = pAdapter->sessionCtx.ap.beacon; + + if (!params->head && !old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) old and new heads points to NULL"), + pAdapter->sessionId); + return -EINVAL; + } + + if(params->head) + head_len = params->head_len; + else + head_len = old->head_len; + + if(params->tail || !old) + tail_len = params->tail_len; + else + tail_len = old->tail_len; + + size = sizeof(beacon_data_t) + head_len + tail_len; + + beacon = kzalloc(size, GFP_KERNEL); + + if( beacon == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Mem allocation for beacon failed")); + return -ENOMEM; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + if(params->dtim_period || !old ) + beacon->dtim_period = params->dtim_period; + else + beacon->dtim_period = old->dtim_period; +#else + if(dtim_period || !old ) + beacon->dtim_period = dtim_period; + else + beacon->dtim_period = old->dtim_period; +#endif + + beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t); + beacon->tail = beacon->head + head_len; + beacon->head_len = head_len; + beacon->tail_len = tail_len; + + if(params->head) { + memcpy (beacon->head,params->head,beacon->head_len); + } + else { + if(old) + memcpy (beacon->head,old->head,beacon->head_len); + } + + if(params->tail) { + memcpy (beacon->tail,params->tail,beacon->tail_len); + } + else { + if(old) + memcpy (beacon->tail,old->tail,beacon->tail_len); + } + + *ppBeacon = beacon; + + kfree(old); + + return 0; + +} + +v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid) +{ + int left = length; + v_U8_t *ptr = pIes; + v_U8_t elem_id,elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +/* Check if rate is 11g rate or not */ +static int wlan_hdd_rate_is_11g(u8 rate) +{ + static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */ + u8 i; + for (i = 0; i < 8; i++) + { + if(rate == gRateArray[i]) + return TRUE; + } + return FALSE; +} + +/* Check for 11g rate and set proper 11g only mode */ +static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht, + u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode) +{ + u8 i, num_rates = pIe[0]; + + pIe += 1; + for ( i = 0; i < num_rates; i++) + { + if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) + { + /* If rate set have 11g rate than change the mode to 11G */ + *pSapHw_mode = eSAP_DOT11_MODE_11g; + if (pIe[i] & BASIC_RATE_MASK) + { + /* If we have 11g rate as basic rate, it means mode + is 11g only mode. + */ + *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY; + *pCheckRatesfor11g = FALSE; + } + } + else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i]) + { + *require_ht = TRUE; + } + } + return; +} + +static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter) +{ + tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head; + u8 checkRatesfor11g = TRUE; + u8 require_ht = FALSE; + u8 *pIe=NULL; + + pConfig->SapHw_mode= eSAP_DOT11_MODE_11b; + + pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0], + pBeacon->head_len, WLAN_EID_SUPP_RATES); + if (pIe != NULL) + { + pIe += 1; + wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g, + &pConfig->SapHw_mode); + } + + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_EXT_SUPP_RATES); + if (pIe != NULL) + { + + pIe += 1; + wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g, + &pConfig->SapHw_mode); + } + + if( pConfig->channel > 14 ) + { + pConfig->SapHw_mode= eSAP_DOT11_MODE_11a; + } + + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_HT_CAPABILITY); + + if(pIe) + { + pConfig->SapHw_mode= eSAP_DOT11_MODE_11n; + if(require_ht) + pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY; + } +} + +static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie, + v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size) +{ + v_U16_t ielen = 0; + v_U8_t *pIe = NULL; + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size, + pBeacon->tail, pBeacon->tail_len); + + if (pIe) + { + ielen = pIe[1] + 2; + if ((*total_ielen + ielen) <= MAX_GENIE_LEN) + { + vos_mem_copy(&genie[*total_ielen], pIe, ielen); + } + else + { + hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***"); + return -EINVAL; + } + *total_ielen += ielen; + } + return 0; +} + +static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter, + v_U8_t *genie, v_U8_t *total_ielen) +{ + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + int left = pBeacon->tail_len; + v_U8_t *ptr = pBeacon->tail; + v_U8_t elem_id, elem_len; + v_U16_t ielen = 0; + + if ( NULL == ptr || 0 == left ) + return; + + while (left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if (elem_len > left) + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "****Invalid IEs eid = %d elem_len=%d left=%d*****", + elem_id, elem_len, left); + return; + } + if (IE_EID_VENDOR == elem_id) + { + /* skipping the VSIE's which we don't want to include or + * it will be included by existing code + */ + if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) && +#ifdef WLAN_FEATURE_WFD + (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) && +#endif + (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0)) + { + ielen = ptr[1] + 2; + if ((*total_ielen + ielen) <= MAX_GENIE_LEN) + { + vos_mem_copy(&genie[*total_ielen], ptr, ielen); + *total_ielen += ielen; + } + else + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "IE Length is too big " + "IEs eid=%d elem_len=%d total_ie_lent=%d", + elem_id, elem_len, *total_ielen); + } + } + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return; +} + +static void wlan_hdd_add_extra_ie(hdd_adapter_t* pHostapdAdapter, + v_U8_t *genie, v_U8_t *total_ielen, + v_U8_t temp_ie_id) +{ + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + int left = pBeacon->tail_len; + v_U8_t *ptr = pBeacon->tail; + v_U8_t elem_id, elem_len; + v_U16_t ielen = 0; + + if ( NULL == ptr || 0 == left ) + return; + + while (left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if (elem_len > left) + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "****Invalid IEs eid = %d elem_len=%d left=%d*****", + elem_id, elem_len, left); + return; + } + + if (temp_ie_id == elem_id) + { + ielen = ptr[1] + 2; + if ((*total_ielen + ielen) <= MAX_GENIE_LEN) + { + vos_mem_copy(&genie[*total_ielen], ptr, ielen); + *total_ielen += ielen; + } + else + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "IE Length is too big " + "IEs eid=%d elem_len=%d total_ie_lent=%d", + elem_id, elem_len, *total_ielen); + } + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter, + struct beacon_parameters *params) +#else +static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter, + struct cfg80211_beacon_data *params) +#endif +{ + v_U8_t *genie; + v_U8_t total_ielen = 0; + int ret = 0; + tsap_Config_t *pConfig; + tSirUpdateIE updateIE; + + pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; + + genie = vos_mem_malloc(MAX_GENIE_LEN); + + if(genie == NULL) { + + return -ENOMEM; + } + + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) + { + hddLog(LOGE, FL("Adding WPS IE failed")); + ret = -EINVAL; + goto done; + } + +#ifdef WLAN_FEATURE_WFD + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) + { + hddLog(LOGE, FL("Adding WFD IE failed")); + ret = -EINVAL; + goto done; + } +#endif + + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)) + { + hddLog(LOGE, FL("Adding P2P IE failed")); + ret = -EINVAL; + goto done; + } + +#ifdef FEATURE_WLAN_WAPI + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) + { + wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen, + WLAN_EID_WAPI); + } +#endif + + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) + { + wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen); + } + +#ifdef QCA_HT_2040_COEX + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) { + tSmeConfigParams smeConfig; + + vos_mem_zero(&smeConfig, sizeof(smeConfig)); + sme_GetConfigParam(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), &smeConfig); + if (smeConfig.csrConfig.obssEnabled) + wlan_hdd_add_extra_ie(pHostapdAdapter, genie, &total_ielen, + WLAN_EID_OVERLAP_BSS_SCAN_PARAM); + } +#endif + + vos_mem_copy(updateIE.bssid, pHostapdAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pHostapdAdapter->sessionId; + + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = total_ielen; + updateIE.pAdditionIEBuffer = genie; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_TRUE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on Add Ie probe beacon data")); + ret = -EINVAL; + goto done; + } + WLANSAP_ResetSapConfigAddIE(pConfig , eUPDATE_IE_PROBE_BCN); + } else { + WLANSAP_UpdateSapConfigAddIE(pConfig, + genie, + total_ielen, + eUPDATE_IE_PROBE_BCN); + } + + /* Added for Probe Response IE */ + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = params->proberesp_ies_len; + updateIE.pAdditionIEBuffer = (tANI_U8*)params->proberesp_ies; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_PROBE_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RESP add Ie data")); + ret = -EINVAL; + goto done; + } + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_PROBE_RESP); + } else { + WLANSAP_UpdateSapConfigAddIE(pConfig, + params->proberesp_ies, + params->proberesp_ies_len, + eUPDATE_IE_PROBE_RESP); + } + + /* Assoc resp Add ie Data */ + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = params->assocresp_ies_len; + updateIE.pAdditionIEBuffer = (tANI_U8*)params->assocresp_ies; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on Add Ie Assoc Response data")); + ret = -EINVAL; + goto done; + } + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ASSOC_RESP); + } else { + WLANSAP_UpdateSapConfigAddIE(pConfig, + params->assocresp_ies, + params->assocresp_ies_len, + eUPDATE_IE_ASSOC_RESP); + } + +done: + vos_mem_free(genie); + return ret; +} + +/* + * FUNCTION: wlan_hdd_validate_operation_channel + * called by wlan_hdd_cfg80211_start_bss() and + * wlan_hdd_cfg80211_set_channel() + * This function validates whether given channel is part of valid + * channel list. + */ +VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel) +{ + + v_U32_t num_ch = 0; + u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + u32 indx = 0; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U8_t fValidChannel = FALSE, count = 0; + hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + + num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if ( hdd_pConfig_ini->sapAllowAllChannel) + { + /* Validate the channel */ + for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++) + { + if ( channel == rfChannels[count].channelNum ) + { + fValidChannel = TRUE; + break; + } + } + if (fValidChannel != TRUE) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + valid_ch, &num_ch)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to get valid channel list", __func__); + return VOS_STATUS_E_FAILURE; + } + for (indx = 0; indx < num_ch; indx++) + { + if (channel == valid_ch[indx]) + { + break; + } + } + + if (indx >= num_ch) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; + +} + +/** + * FUNCTION: wlan_hdd_cfg80211_set_channel + * This function is used to set the channel number + */ +static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type + ) +{ + hdd_adapter_t *pAdapter = NULL; + v_U32_t num_ch = 0; + int channel = 0; + int freq = chan->center_freq; /* freq is in MHZ */ + hdd_context_t *pHddCtx; + int status; +#ifdef QCA_HT_2040_COEX + tSmeConfigParams smeConfig; +#endif + + ENTER(); + + + if( NULL == dev ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Called with dev = NULL.", __func__); + return -ENODEV; + } + pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId, + channel_type )); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %d freq = %d",__func__, + pAdapter->device_mode, chan->center_freq); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + /* + * Do freq to chan conversion + * TODO: for 11a + */ + + channel = ieee80211_frequency_to_channel(freq); + + /* Check freq range */ + if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) || + (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Channel [%d] is outside valid range from %d to %d", + __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN, + WNI_CFG_CURRENT_CHANNEL_STAMAX); + return -EINVAL; + } + + num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) && + (WLAN_HDD_P2P_GO != pAdapter->device_mode)) + { + if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: set channel to [%d] for device mode =%d", + __func__, channel,pAdapter->device_mode); + } + if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + ) + { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) + { + /* Link is up then return cant set channel*/ + hddLog( VOS_TRACE_LEVEL_ERROR, + "%s: IBSS Associated, can't set the channel", __func__); + return -EINVAL; + } + + num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = channel; + pRoamProfile->ChannelInfo.ChannelList = + &pHddStaCtx->conn_info.operationChannel; + } + else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + if(VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel; + } + else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) + { + + /* If auto channel selection is configured as enable/ 1 then ignore + channel set by supplicant + */ +#ifdef WLAN_FEATURE_MBSSID + if (pAdapter->sap_dyn_ini_cfg.apAutoChannelSelection) +#else + hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + if ( cfg_param->apAutoChannelSelection ) +#endif + { + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = + AUTO_CHANNEL_SELECT; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: set channel to auto channel (0) for device mode =%d", + __func__, pAdapter->device_mode); + } + else + { + if(VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel; + } + +#ifdef QCA_HT_2040_COEX + /* set channel bonding mode for 2.4G */ + if ( channel <= 14 ) + { + switch (channel_type) + { + case NL80211_CHAN_HT20: + case NL80211_CHAN_NO_HT: + sme_SetPhyCBMode24G(pHddCtx->hHal, + PHY_SINGLE_CHANNEL_CENTERED); + break; + + case NL80211_CHAN_HT40MINUS: + sme_SetPhyCBMode24G(pHddCtx->hHal, + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY); + break; + case NL80211_CHAN_HT40PLUS: + sme_SetPhyCBMode24G(pHddCtx->hHal, + PHY_DOUBLE_CHANNEL_LOW_PRIMARY); + break; + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s:Error!!! Invalid HT20/40 mode !", + __func__); + return -EINVAL; + } + } + + vos_mem_zero(&smeConfig, sizeof(smeConfig)); + sme_GetConfigParam(pHddCtx->hHal, &smeConfig); + if (NL80211_CHAN_NO_HT == channel_type) + smeConfig.csrConfig.obssEnabled = VOS_FALSE; + else + smeConfig.csrConfig.obssEnabled = VOS_TRUE; + sme_UpdateConfig (pHddCtx->hHal, &smeConfig); + +#endif + } + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid device mode failed to set valid channel", __func__); + return -EINVAL; + } + EXIT(); + return status; +} + +/* + * FUNCTION: wlan_hdd_set_acs_allowed_channels + * set only allowed channel for ACS + * input channel list is a string with comma separated + * channel number, the first number is the total number + * of channels specified. e.g. 4,1,6,9,36 + */ +static void wlan_hdd_set_acs_allowed_channels( + char *acsAllowedChnls, + char *acsSapChnlList, + int length) +{ + char *p; + + /* a white space is required at the beginning of the + string to be properly parsed by function + sapSetPreferredChannel later */ + strlcpy(acsSapChnlList, " ", length); + strlcat(acsSapChnlList, acsAllowedChnls, length); + p = acsSapChnlList; + while (*p) + { + /* looking for comma, replace it with white space */ + if (*p == ',') + *p = ' '; + + p++; + } + + return; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, + struct beacon_parameters *params) +#else +static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, + struct cfg80211_beacon_data *params, + const u8 *ssid, size_t ssid_len, + enum nl80211_hidden_ssid hidden_ssid) +#endif +{ + tsap_Config_t *pConfig; + beacon_data_t *pBeacon = NULL; + struct ieee80211_mgmt *pMgmt_frame; + v_U8_t *pIe=NULL; + v_U16_t capab_info; + eCsrAuthType RSNAuthType; + eCsrEncryptionType RSNEncryptType; + eCsrEncryptionType mcRSNEncryptType; + int status = VOS_STATUS_SUCCESS; + tpWLAN_SAPEventCB pSapEventCallback; + hdd_hostapd_state_t *pHostapdState; + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + struct qc_mac_acl_entry *acl_entry = NULL; + v_SINT_t i; + hdd_config_t *iniConfig; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); +#ifdef WLAN_FEATURE_11AC + v_BOOL_t sapForce11ACFor11n = +#ifdef WLAN_FEATURE_MBSSID + pHostapdAdapter->sap_dyn_ini_cfg.apForce11ACFor11n; +#else + pHddCtx->cfg_ini->apForce11ACFor11n; +#endif +#endif + tSmeConfigParams *psmeConfig; + v_BOOL_t MFPCapable = VOS_FALSE; + v_BOOL_t MFPRequired = VOS_FALSE; + u_int16_t prev_rsn_length = 0; + ENTER(); + + iniConfig = pHddCtx->cfg_ini; + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + + pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; + + pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + + pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head; + + pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int; + + pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch; + + //channel is already set in the set_channel Call back + //pConfig->channel = pCommitConfig->channel; + + /*Protection parameter to enable or disable*/ + pConfig->protEnabled = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled; + + pConfig->dtim_period = pBeacon->dtim_period; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***", + pConfig->dtim_period); + + pConfig->enOverLapCh = !!pHddCtx->cfg_ini->gEnableOverLapCh; +#ifdef WLAN_FEATURE_MBSSID + if (strlen(pHostapdAdapter->sap_dyn_ini_cfg.acsAllowedChnls) > 0 ) +#else + if (strlen(iniConfig->acsAllowedChnls) > 0) +#endif + { + wlan_hdd_set_acs_allowed_channels( +#ifdef WLAN_FEATURE_MBSSID + pHostapdAdapter->sap_dyn_ini_cfg.acsAllowedChnls, +#else + iniConfig->acsAllowedChnls, +#endif + pConfig->acsAllowedChnls, + sizeof(pConfig->acsAllowedChnls)); + } + + if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) + { + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_COUNTRY); + if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0) + { + tANI_BOOLEAN restartNeeded; + pConfig->ieee80211d = 1; + vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3); + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + else if(pIe) + { + tANI_BOOLEAN restartNeeded; + pConfig->ieee80211d = 1; + vos_mem_copy(pConfig->countryCode, &pIe[2], 3); + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + else + { + pConfig->countryCode[0] = pHddCtx->reg.alpha2[0]; + pConfig->countryCode[1] = pHddCtx->reg.alpha2[1]; + pConfig->ieee80211d = 0; + } + +#ifdef WLAN_FEATURE_MBSSID + if (!vos_concurrent_sap_sessions_running()) { + /* Single AP Mode */ + if (VOS_IS_DFS_CH(pConfig->channel)) + pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; + } else { + /* MBSSID Mode */ + hdd_adapter_t *con_sap_adapter; + v_U16_t con_ch; + + con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter); + if (con_sap_adapter) { + /* we have active SAP running */ + /* Check if user configured channel is ACS or DFS */ + con_ch = con_sap_adapter->sessionCtx.ap.sapConfig.channel; + /* For fixed channel or ACS, once primary AP chooses a DFS + * channel secondary AP should alway follow primary APs channel + * This is applicable for cases even when primary AP moves to + * non DFS channel after RADAR detection. + */ + if (con_ch == AUTO_CHANNEL_SELECT) { + con_ch = con_sap_adapter->sessionCtx.ap.operatingChannel; + } + + if (VOS_IS_DFS_CH(con_ch)) { + /* AP-AP DFS: secondary AP has to follow primary AP's + * channel */ + /* NOTE:Even if orig user configured channel is DFS, use the + * current operating channel since when RADAR detected orig + * configured channel will be in NOL and already running AP + * might have choosen another channel + */ + con_ch = con_sap_adapter->sessionCtx.ap.operatingChannel; + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Only SCC AP-AP DFS Permitted (ch=%d, con_ch=%d)", + __func__, + pConfig->channel, + con_ch); + hddLog(VOS_TRACE_LEVEL_ERROR, + "Overriding guest AP's channel !!"); + pConfig->channel = con_ch; + } + } else { + /* We have idle AP interface (no active SAP running on it + * When one SAP is stopped then also this condition applies */ + if (VOS_IS_DFS_CH(pConfig->channel)) + pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; + } + } +#endif + /* + * If auto channel is configured i.e. channel is 0, + * so skip channel validation. + */ + if( AUTO_CHANNEL_SELECT != pConfig->channel ) + { + if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, pConfig->channel); + return -EINVAL; + } + + /* reject SAP if DFS channel scan is not allowed */ + if ((VOS_FALSE == pHddCtx->cfg_ini->enableDFSChnlScan) && + (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(pConfig->channel))) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("not allowed to start SAP on DFS channel")); + return -EOPNOTSUPP; + } + } + else + { + if(1 != pHddCtx->is_dynamic_channel_range_set) + { +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_SetChannelRange(hHal, + pHostapdAdapter->sap_dyn_ini_cfg.apStartChannelNum, + pHostapdAdapter->sap_dyn_ini_cfg.apEndChannelNum, + pHostapdAdapter->sap_dyn_ini_cfg.apOperatingBand); +#else + hdd_config_t *hdd_pConfig= + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini; + WLANSAP_SetChannelRange(hHal, + hdd_pConfig->apStartChannelNum, + hdd_pConfig->apEndChannelNum, + hdd_pConfig->apOperatingBand); +#endif + } + pHddCtx->is_dynamic_channel_range_set = 0; + } + WLANSAP_Set_Dfs_Ignore_CAC(hHal, iniConfig->ignoreCAC); + + /* + * Set the JAPAN W53 disabled INI param + * in to SAP DFS for restricting these + * channel from being picked during DFS + * random channel selection. + */ + WLANSAP_set_Dfs_Restrict_JapanW53(hHal, + iniConfig->gDisableDfsJapanW53); + + /* + * Set the SAP Indoor/Outdoor preferred + * operating channel location. This + * prameter will restrict SAP picking + * channel from only Indoor/outdoor + * channels list only based up on the + * this parameter. + */ + WLANSAP_set_Dfs_Preferred_Channel_location(hHal, + iniConfig->gSapPreferredChanLocation); + } + else + { + pConfig->ieee80211d = 0; + } + + capab_info = pMgmt_frame->u.beacon.capab_info; + + pConfig->privacy = (pMgmt_frame->u.beacon.capab_info & + WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE; + + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy; + + /*Set wps station to configured*/ + pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len); + + if(pIe) + { + if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) + { + hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***"); + return -EINVAL; + } + else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0) + { + hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2)); + /* Check 15 bit of WPS IE as it contain information for wps state + * WPS state + */ + if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) + { + pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED; + } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15]) + { + pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED; + } + } + } + else + { + pConfig->wps_state = SAP_WPS_DISABLED; + } + pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up + + pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; + pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType = + eCSR_ENCRYPT_TYPE_NONE; + + pConfig->RSNWPAReqIELength = 0; + memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE)); + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_RSN); + if(pIe && pIe[1]) + { + pConfig->RSNWPAReqIELength = pIe[1] + 2; + if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE)) + memcpy(&pConfig->RSNWPAReqIE[0], pIe, + pConfig->RSNWPAReqIELength); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + /* The actual processing may eventually be more extensive than + * this. Right now, just consume any PMKIDs that are sent in + * by the app. + * */ + status = hdd_softap_unpackIE( + vos_get_context( VOS_MODULE_ID_SME, pVosContext), + &RSNEncryptType, + &mcRSNEncryptType, + &RSNAuthType, + &MFPCapable, + &MFPRequired, + pConfig->RSNWPAReqIE[1]+2, + pConfig->RSNWPAReqIE ); + + if( VOS_STATUS_SUCCESS == status ) + { + /* Now copy over all the security attributes you have + * parsed out + * */ + pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE + pConfig->mcRSNEncryptType = mcRSNEncryptType; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType + = RSNEncryptType; + hddLog( LOG1, FL("CSR AuthType = %d, " + "EncryptionType = %d mcEncryptionType = %d"), + RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + } + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) + { + if (pConfig->RSNWPAReqIE[0]) + { + /*Mixed mode WPA/WPA2*/ + prev_rsn_length = pConfig->RSNWPAReqIELength; + pConfig->RSNWPAReqIELength += pIe[1] + 2; + if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE)) + memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe, + pIe[1] + 2); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + } + else + { + pConfig->RSNWPAReqIELength = pIe[1] + 2; + if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE)) + memcpy(&pConfig->RSNWPAReqIE[0], pIe, + pConfig->RSNWPAReqIELength); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + status = hdd_softap_unpackIE( + vos_get_context( VOS_MODULE_ID_SME, pVosContext), + &RSNEncryptType, + &mcRSNEncryptType, + &RSNAuthType, + &MFPCapable, + &MFPRequired, + pConfig->RSNWPAReqIE[1]+2, + pConfig->RSNWPAReqIE ); + + if( VOS_STATUS_SUCCESS == status ) + { + /* Now copy over all the security attributes you have + * parsed out + * */ + pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE + pConfig->mcRSNEncryptType = mcRSNEncryptType; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType + = RSNEncryptType; + hddLog( LOG1, FL("CSR AuthType = %d, " + "EncryptionType = %d mcEncryptionType = %d"), + RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + } + } + + if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) { + hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***"); + return -EINVAL; + } + + pConfig->SSIDinfo.ssidHidden = VOS_FALSE; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + if (params->ssid != NULL) + { + vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len); + pConfig->SSIDinfo.ssid.length = params->ssid_len; + + switch (params->hidden_ssid) { + case NL80211_HIDDEN_SSID_NOT_IN_USE: + hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE; + break; + case NL80211_HIDDEN_SSID_ZERO_LEN: + hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN; + break; + case NL80211_HIDDEN_SSID_ZERO_CONTENTS: + hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_CONTENTS; + break; + default: + hddLog(LOGE, "Wrong hidden_ssid param %d", params->hidden_ssid); + break; + } + } +#else + if (ssid != NULL) + { + vos_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len); + pConfig->SSIDinfo.ssid.length = ssid_len; + + switch (hidden_ssid) { + case NL80211_HIDDEN_SSID_NOT_IN_USE: + hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE; + break; + case NL80211_HIDDEN_SSID_ZERO_LEN: + hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN; + break; + case NL80211_HIDDEN_SSID_ZERO_CONTENTS: + hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS"); + pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_CONTENTS; + break; + default: + hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid); + break; + } + } +#endif + + vos_mem_copy(pConfig->self_macaddr.bytes, + pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + /* default value */ + pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED; + pConfig->num_accept_mac = 0; + pConfig->num_deny_mac = 0; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + pConfig->cc_switch_mode = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->WlanMccToSccSwitchMode; +#endif + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + /* pIe for black list is following form: + type : 1 byte + length : 1 byte + OUI : 4 bytes + acl type : 1 byte + no of mac addr in black list: 1 byte + list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id + */ + if ((pIe != NULL) && (pIe[1] != 0)) + { + pConfig->SapMacaddr_acl = pIe[6]; + pConfig->num_deny_mac = pIe[7]; + hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d", + pIe[6], pIe[7]); + if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS) + pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS; + acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); + for (i = 0; i < pConfig->num_deny_mac; i++) + { + vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr)); + acl_entry++; + } + } + pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + /* pIe for white list is following form: + type : 1 byte + length : 1 byte + OUI : 4 bytes + acl type : 1 byte + no of mac addr in white list: 1 byte + list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id + */ + if ((pIe != NULL) && (pIe[1] != 0)) + { + pConfig->SapMacaddr_acl = pIe[6]; + pConfig->num_accept_mac = pIe[7]; + hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d", + pIe[6], pIe[7]); + if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS) + pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS; + acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); + for (i = 0; i < pConfig->num_accept_mac; i++) + { + vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr)); + acl_entry++; + } + } + + wlan_hdd_set_sapHwmode(pHostapdAdapter); + +#ifdef WLAN_FEATURE_11AC + /* Overwrite the hostapd setting for HW mode only for 11ac. + * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini . + * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */ + if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) || + (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) && + sapForce11ACFor11n && + (( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO ) || + ( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac ) || + ( (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY )) ) + { + if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) + pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac_ONLY; + else + pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac; + + /* If ACS disable and selected channel <= 14 + OR + ACS enabled and ACS operating band is chosen as 2.4 + AND + VHT in 2.4G Disabled + THEN + Fallback to 11N mode + */ + if ((((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= 14) + || (AUTO_CHANNEL_SELECT == pConfig->channel && +#ifdef WLAN_FEATURE_MBSSID + pHostapdAdapter->sap_dyn_ini_cfg.apOperatingBand +#else + iniConfig->apOperatingBand +#endif + == eSAP_RF_SUBBAND_2_4_GHZ)) && + (WLAN_HDD_GET_CTX(pHostapdAdapter)->cfg_ini->enableVhtFor24GHzBand + == FALSE)) || + (WLAN_HDD_GET_CTX(pHostapdAdapter)->isVHT80Allowed == FALSE)) + { + pConfig->SapHw_mode = eSAP_DOT11_MODE_11n; + } + } +#endif + + if ( AUTO_CHANNEL_SELECT != pConfig->channel ) + { + sme_SelectCBMode(hHal, + sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode), + pConfig->channel); + } + // ht_capab is not what the name conveys,this is used for protection bitmap + pConfig->ht_capab = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection; + + if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) ) + { + hddLog(LOGE, FL("SAP Not able to set AP IEs")); + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); + return -EINVAL; + } + + //Uapsd Enabled Bit + pConfig->UapsdEnable = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled; + //Enable OBSS protection + pConfig->obssProtEnabled = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled; + + if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) { + pConfig->sap_dot11mc = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sap_dot11mc; + } else { /* for P2P-Go case */ + pConfig->sap_dot11mc = 1; + } + hddLog(LOG1, FL("11MC Support Enabled : %d\n"), + pConfig->sap_dot11mc); + +#ifdef WLAN_FEATURE_11W + pConfig->mfpCapable = MFPCapable; + pConfig->mfpRequired = MFPRequired; + hddLog(LOG1, FL("Soft AP MFP capable %d, MFP required %d\n"), + pConfig->mfpCapable, pConfig->mfpRequired); +#endif + + hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes)); + hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"), + pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int, + (int)pConfig->channel); + hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"), + pConfig->SapHw_mode, pConfig->privacy, + pConfig->authType); + hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"), + (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable); + hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"), + pConfig->protEnabled, pConfig->obssProtEnabled); + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); + //Bss already started. just return. + //TODO Probably it should update some beacon params. + hddLog( LOGE, "Bss Already started...Ignore the request"); + EXIT(); + return 0; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections")); + return -EINVAL; + } + + pConfig->persona = pHostapdAdapter->device_mode; + + psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams)); + if ( NULL != psmeConfig) + { +#ifdef WLAN_FEATURE_MBSSID + eHalStatus halStatus = eHAL_STATUS_FAILURE; + sme_GetConfigParam(hHal, psmeConfig); + psmeConfig->csrConfig.scanBandPreference = + pHostapdAdapter->sap_dyn_ini_cfg.acsScanBandPreference; + halStatus = sme_UpdateConfig(pHddCtx->hHal, psmeConfig); + if ( !HAL_STATUS_SUCCESS( halStatus ) + && pConfig->channel == AUTO_CHANNEL_SELECT ) + { + hddLog(LOGE, "sme_UpdateConfig() for ACS Scan band pref Fail: %d", + halStatus); + return -EAGAIN; + } + pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference; +#else + sme_GetConfigParam(hHal, psmeConfig); + pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference; +#endif + vos_mem_free(psmeConfig); + } +#ifdef WLAN_FEATURE_MBSSID + pConfig->acsBandSwitchThreshold = + pHostapdAdapter->sap_dyn_ini_cfg.acsBandSwitchThreshold; + pConfig->apAutoChannelSelection = + pHostapdAdapter->sap_dyn_ini_cfg.apAutoChannelSelection; + pConfig->apStartChannelNum = + pHostapdAdapter->sap_dyn_ini_cfg.apStartChannelNum; + pConfig->apEndChannelNum = + pHostapdAdapter->sap_dyn_ini_cfg.apEndChannelNum; + pConfig->apOperatingBand = pHostapdAdapter->sap_dyn_ini_cfg.apOperatingBand; +#else + pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold; + pConfig->apAutoChannelSelection = iniConfig->apAutoChannelSelection; + pConfig->apStartChannelNum = iniConfig->apStartChannelNum; + pConfig->apEndChannelNum = iniConfig->apEndChannelNum; + pConfig->apOperatingBand = iniConfig->apOperatingBand; +#endif + +#if defined(FEATURE_WLAN_AP_AP_ACS_OPTIMIZE) && defined(WLAN_FEATURE_MBSSID) + if (vos_concurrent_sap_sessions_running() && + pConfig->channel == AUTO_CHANNEL_SELECT) { + hdd_adapter_t *con_sap_adapter; + tsap_Config_t *con_sap_config = NULL; + + con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter); + + if (con_sap_adapter) + con_sap_config = &con_sap_adapter->sessionCtx.ap.sapConfig; + + pConfig->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; + + hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"), + pHddCtx->skip_acs_scan_status); + + if (con_sap_config && con_sap_config->channel == AUTO_CHANNEL_SELECT && + pHddCtx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) { + + hddLog(LOG1, FL("Operating Band: PriAP: %d SecAP: %d"), + con_sap_config->apOperatingBand, pConfig->apOperatingBand); + + if (con_sap_config->apOperatingBand == 5 && + pConfig->apOperatingBand > 0) { + pConfig->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; + + } else if (con_sap_config->apOperatingBand + == pConfig->apOperatingBand) { + v_U8_t con_sap_st_ch, con_sap_end_ch; + v_U8_t cur_sap_st_ch, cur_sap_end_ch; + v_U8_t bandStartChannel, bandEndChannel; + + con_sap_st_ch = con_sap_config->apStartChannelNum; + con_sap_end_ch = con_sap_config->apEndChannelNum; + cur_sap_st_ch = pConfig->apStartChannelNum; + cur_sap_end_ch = pConfig->apEndChannelNum; + + WLANSAP_extend_to_acs_range(pConfig->apOperatingBand, + &cur_sap_st_ch, &cur_sap_end_ch, + &bandStartChannel, &bandEndChannel); + + WLANSAP_extend_to_acs_range(con_sap_config->apOperatingBand, + &con_sap_st_ch, &con_sap_end_ch, + &bandStartChannel, &bandEndChannel); + + if (con_sap_st_ch <= cur_sap_st_ch && + con_sap_end_ch >= cur_sap_end_ch) { + + pConfig->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; + + } else if (con_sap_st_ch >= cur_sap_st_ch && + con_sap_end_ch >= cur_sap_end_ch) { + + pConfig->skip_acs_scan_status = eSAP_DO_PAR_ACS_SCAN; + + pConfig->skip_acs_scan_range1_stch = cur_sap_st_ch; + pConfig->skip_acs_scan_range1_endch = con_sap_st_ch - 1; + pConfig->skip_acs_scan_range2_stch = 0; + pConfig->skip_acs_scan_range2_endch = 0; + + } else if (con_sap_st_ch <= cur_sap_st_ch && + con_sap_end_ch <= cur_sap_end_ch) { + + pConfig->skip_acs_scan_status = eSAP_DO_PAR_ACS_SCAN; + + pConfig->skip_acs_scan_range1_stch = con_sap_end_ch + 1; + pConfig->skip_acs_scan_range1_endch = cur_sap_end_ch; + pConfig->skip_acs_scan_range2_stch = 0; + pConfig->skip_acs_scan_range2_endch = 0; + + } else if (con_sap_st_ch >= cur_sap_st_ch && + con_sap_end_ch <= cur_sap_end_ch) { + + pConfig->skip_acs_scan_status = eSAP_DO_PAR_ACS_SCAN; + + pConfig->skip_acs_scan_range1_stch = cur_sap_st_ch; + pConfig->skip_acs_scan_range1_endch = con_sap_st_ch - 1; + pConfig->skip_acs_scan_range2_stch = con_sap_end_ch; + pConfig->skip_acs_scan_range2_endch = cur_sap_end_ch + 1; + + } else + pConfig->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; + + hddLog(LOG1, + FL("SecAP ACS Skip = %d, ACS CH RANGE = %d-%d, %d-%d"), + pConfig->skip_acs_scan_status, + pConfig->skip_acs_scan_range1_stch, + pConfig->skip_acs_scan_range1_endch, + pConfig->skip_acs_scan_range2_stch, + pConfig->skip_acs_scan_range2_endch); + } + } + } +#endif + + pSapEventCallback = hdd_hostapd_SAPEventCB; + + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = VOS_TRUE; + + status = WLANSAP_StartBss( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + pVosContext, +#endif + pSapEventCallback, pConfig, (v_PVOID_t)pHostapdAdapter->dev); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); + hddLog(LOGE,FL("SAP Start Bss fail")); + return -EINVAL; + } + + hddLog(LOG1, + FL("Waiting for Scan to complete(auto mode) and BSS to start")); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("%s: ERROR: HDD vos wait for single_event failed!!"), + __func__); + smeGetCommandQStatus(hHal); + VOS_ASSERT(0); + return -EINVAL; + } + + /* Successfully started Bss update the state bit. */ + set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode); + +#ifdef WLAN_FEATURE_P2P_DEBUG + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) + { + globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE; + hddLog(LOGE,"[P2P State] From Go nego completed to " + "Non-autonomous Group started"); + } + else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE) + { + globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE; + hddLog(LOGE,"[P2P State] From Inactive to " + "Autonomous Group started"); + } + } +#endif + + pHostapdState->bCommit = TRUE; + EXIT(); + + return 0; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_BEACON, + pAdapter->sessionId, params->interval)); + hddLog(LOG2, FL("Device mode=%d"), pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections")); + return -EINVAL; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + beacon_data_t *old, *new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (old) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("already beacon info added to session(%d)"), + pAdapter->sessionId); + return -EALREADY; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("Error!!! Allocating the new beacon")); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + + status = wlan_hdd_cfg80211_start_bss(pAdapter, params); + if (0 != status) { + pAdapter->sessionCtx.ap.beacon = NULL; + kfree(new); + } + } + + EXIT(); + return status; +} + +/** + * wlan_hdd_cfg80211_add_beacon() - add beacon in sap mode + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * @param: Pointer to beacon parameters + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_BEACON, + pAdapter->sessionId, pHddStaCtx->conn_info.authType)); + hddLog(LOG1, FL("Device_mode = %d"), pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + beacon_data_t *old, *new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (!old) { + hddLog(LOGE, + FL("session(%d) old and new heads points to NULL"), + pAdapter->sessionId); + return -ENOENT; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params); + + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("Error!!! Allocating the new beacon")); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + status = wlan_hdd_cfg80211_start_bss(pAdapter, params); + } + + EXIT(); + return status; +} + +/** + * wlan_hdd_cfg80211_set_beacon() - set beacon in sap mode + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * @param: Pointer to beacon parameters + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy, + struct net_device *dev) +#else +static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy, + struct net_device *dev) +#endif +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = NULL; + hdd_scaninfo_t *pScanInfo = NULL; + hdd_adapter_t *staAdapter = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tSirUpdateIE updateIE; + beacon_data_t *old; + int ret; + unsigned long rc; + hdd_adapter_list_node_t *pAdapterNode = NULL; + hdd_adapter_list_node_t *pNext = NULL; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_STOP_AP, + pAdapter->sessionId, pAdapter->device_mode)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return ret; + } + + if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + return -EOPNOTSUPP; + } + + hddLog(LOG1, FL("Device_mode = %d"), pAdapter->device_mode); + + status = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + staAdapter = pAdapterNode->pAdapter; + + if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode || + (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) || + (WLAN_HDD_P2P_GO == staAdapter->device_mode)) { + pScanInfo = &staAdapter->scan_info; + + if (pScanInfo && pScanInfo->mScanPending) { + hddLog(LOG1, FL("Aborting pending scan for device mode:%d"), + staAdapter->device_mode); + INIT_COMPLETION(pScanInfo->abortscan_event_var); + hdd_abort_mac_scan(staAdapter->pHddCtx, staAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + rc = wait_for_completion_timeout( + &pScanInfo->abortscan_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN)); + if (!rc) { + hddLog(LOGE, + FL("Timeout occurred while waiting for abortscan")); + VOS_ASSERT(pScanInfo->mScanPending); + } + } + } + + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + hdd_hostapd_stop(dev); + + old = pAdapter->sessionCtx.ap.beacon; + if (!old) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Session(%d) beacon data points to NULL"), + pAdapter->sessionId); + return -EINVAL; + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); + + mutex_lock(&pHddCtx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) { + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + vos_event_reset(&pHostapdState->vosEvent); +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); +#else + status = WLANSAP_StopBss(pHddCtx->pvosContext); +#endif + if (VOS_IS_STATUS_SUCCESS(status)) { + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD vos wait for single_event failed!!")); + VOS_ASSERT(0); + } + } + clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); + /* BSS stopped, clear the active sessions for this device mode */ + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + + pAdapter->sessionCtx.ap.beacon = NULL; + kfree(old); + } + mutex_unlock(&pHddCtx->sap_lock); + + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("Stopping the BSS")); + return -EINVAL; + } + + vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_TRUE; + updateIE.notify = VOS_TRUE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); + } + + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE")); + } + + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pAdapter); + +#ifdef WLAN_FEATURE_P2P_DEBUG + if((pAdapter->device_mode == WLAN_HDD_P2P_GO) && + (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE)) { + hddLog(LOGE,"[P2P State] From GO completed to Inactive state " + "GO got removed"); + globalP2PConnectionStatus = P2P_NOT_ACTIVE; + } +#endif + EXIT(); + return ret; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) +/** + * wlan_hdd_cfg80211_del_beacon() - delete beacon in sap mode + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#else +/** + * wlan_hdd_cfg80211_stop_ap() - stop sap + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)) +static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId, + params-> beacon_interval)); + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter magic is invalid", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: pAdapter = %p, device mode = %d", + __func__, pAdapter, pAdapter->device_mode); + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections")); + return -EINVAL; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old, *new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (old) + return -EALREADY; + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, ¶ms->beacon, params->dtim_period); + + if (status != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Error!!! Allocating the new beacon", __func__); + return -EINVAL; + } + pAdapter->sessionCtx.ap.beacon = new; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wlan_hdd_cfg80211_set_channel(wiphy, dev, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + params->channel, params->channel_type); +#else + params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef))); +#endif +#endif + /* set authentication type */ + switch ( params->auth_type ) + { + case NL80211_AUTHTYPE_OPEN_SYSTEM: + pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_OPEN_SYSTEM; + break; + case NL80211_AUTHTYPE_SHARED_KEY: + pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_SHARED_KEY; + break; + default: + pAdapter->sessionCtx.ap.sapConfig.authType = eSAP_AUTO_SWITCH; + } + + status = wlan_hdd_cfg80211_start_bss(pAdapter, ¶ms->beacon, params->ssid, + params->ssid_len, params->hidden_ssid); + } + + EXIT(); + return status; +} + +/** + * wlan_hdd_cfg80211_start_ap() - start sap + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * @params: Pointer to start ap configuration parameters + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + beacon_data_t *old,*new; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_BEACON, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, FL("device_mode = %d"), pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + return -EOPNOTSUPP; + } + + old = pAdapter->sessionCtx.ap.beacon; + + if (!old) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) beacon data points to NULL"), + pAdapter->sessionId); + return -EINVAL; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0); + + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("new beacon alloc failed")); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0); + + EXIT(); + return status; +} + +/** + * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode + * @wiphy: Pointer to wiphy + * @dev: Pointer to netdev + * @params: Pointer to change beacon parameters + * + * Return: zero for success non-zero for failure + */ +static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int ret = 0; + eHalStatus halStatus; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_BSS, + pAdapter->sessionId, params->ap_isolate)); + hddLog(VOS_TRACE_LEVEL_INFO, FL("device_mode = %d, ap_isolate = %d"), + pAdapter->device_mode, params->ap_isolate); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return ret; + } + + if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + return -EOPNOTSUPP; + } + + /* ap_isolate == -1 means that in change bss, upper layer doesn't + * want to update this parameter */ + if (-1 != params->ap_isolate) { + pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate; + + halStatus = sme_ApDisableIntraBssFwd(pHddCtx->hHal, + pAdapter->sessionId, + pAdapter->sessionCtx.ap.apDisableIntraBssFwd); + if (!HAL_STATUS_SUCCESS(halStatus)) { + ret = -EINVAL; + } + } + + EXIT(); + return ret; +} + +static int +wlan_hdd_change_iface_to_adhoc(struct net_device *ndev, + tCsrRoamProfile *pRoamProfile, + enum nl80211_iftype type) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *pConfig = pHddCtx->cfg_ini; + struct wireless_dev *wdev = ndev->ieee80211_ptr; + + pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS; + pRoamProfile->phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); + pAdapter->device_mode = WLAN_HDD_IBSS; + wdev->iftype = type; + + return 0; +} + +static int wlan_hdd_change_iface_to_sta_mode(struct net_device *ndev, + enum nl80211_iftype type) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_wext_state_t *wext; + struct wireless_dev *wdev; + VOS_STATUS status; + + ENTER(); + + wdev = ndev->ieee80211_ptr; + hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE); + hdd_deinit_adapter(pHddCtx, pAdapter); + wdev->iftype = type; + /*Check for sub-string p2p to confirm its a p2p interface*/ + if (NULL != strnstr(ndev->name, "p2p", 3)) { + pAdapter->device_mode = + (type == NL80211_IFTYPE_STATION)? + WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT; + } else { + pAdapter->device_mode = + (type == NL80211_IFTYPE_STATION) ? + WLAN_HDD_INFRA_STATION : WLAN_HDD_P2P_CLIENT; + } + + // set con_mode to STA only when no SAP concurrency mode + if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO))) + hdd_set_conparam(0); + pHddCtx->change_iface = type; + memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx)); + hdd_set_station_ops(pAdapter->dev); + status = hdd_init_station_mode(pAdapter); + wext = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + wext->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata; + wext->roamProfile.nAddIEScanLength = pAdapter->scan_info.scanAddIE.length; + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} +/* FUNCTION: wlan_hdd_change_country_code_cd +* to wait for country code completion +*/ +void* wlan_hdd_change_country_code_cb(void *pAdapter) +{ + hdd_adapter_t *call_back_pAdapter = pAdapter; + complete(&call_back_pAdapter->change_country_code); + return NULL; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_change_iface + * This function is used to set the interface type (INFRASTRUCTURE/ADHOC) + */ +static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) +{ + struct wireless_dev *wdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); + hdd_context_t *pHddCtx; + tCsrRoamProfile *pRoamProfile = NULL; + eCsrRoamBssType LastBSSType; + hdd_config_t *pConfig = NULL; + eMib_dot11DesiredBssType connectedBssType; + unsigned long rc; + VOS_STATUS vstatus; + eHalStatus hstatus; + int status; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_IFACE, + pAdapter->sessionId, type)); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Device_mode = %d, IFTYPE = 0x%x"), + pAdapter->device_mode, type); + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections")); + return -EINVAL; + } + + pConfig = pHddCtx->cfg_ini; + wdev = ndev->ieee80211_ptr; + +#ifdef WLAN_BTAMP_FEATURE + if((NL80211_IFTYPE_P2P_CLIENT == type)|| + (NL80211_IFTYPE_ADHOC == type)|| + (NL80211_IFTYPE_AP == type)|| + (NL80211_IFTYPE_P2P_GO == type)) { + pHddCtx->isAmpAllowed = VOS_FALSE; + /* Stop AMP traffic */ + vstatus = WLANBAP_StopAmp(); + if (VOS_STATUS_SUCCESS != vstatus) { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(LOGP, FL("Failed to stop AMP")); + return -EINVAL; + } + } +#endif /* WLAN_BTAMP_FEATURE */ + /* Reset the current device mode bit mask */ + wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode); + + hdd_tdls_notify_mode_change(pAdapter, pHddCtx); + + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)) { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + pRoamProfile = &pWextState->roamProfile; + LastBSSType = pRoamProfile->BSSType; + + switch (type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + vstatus = wlan_hdd_change_iface_to_sta_mode(ndev, type); + if (vstatus != VOS_STATUS_SUCCESS) + return -EINVAL; + +#ifdef QCA_LL_TX_FLOW_CT + if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) { + vos_timer_init(&pAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_tx_resume_timer_expired_handler, + pAdapter); + pAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); +#endif /* QCA_LL_TX_FLOW_CT */ + + goto done; + + case NL80211_IFTYPE_ADHOC: + hddLog(LOG1, FL("Setting interface Type to ADHOC")); + wlan_hdd_change_iface_to_adhoc(ndev, pRoamProfile, type); + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + FL("Setting interface Type to %s"), + (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo"); + + /* Cancel any remain on channel for GO mode */ + if (NL80211_IFTYPE_P2P_GO == type) { + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + } + + if (NL80211_IFTYPE_AP == type) { + /* As Loading WLAN Driver one interface being created for + * p2p device address. This will take one HW STA and the + * max number of clients that can connect to softAP will be + * reduced by one. so while changing the interface type to + * NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface as it is + * not required in SoftAP mode. + */ + + /* Get P2P Adapter */ + hdd_adapter_t *pP2pAdapter = NULL; + pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE); + + if (pP2pAdapter) { + hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); + hdd_deinit_adapter(pHddCtx, pP2pAdapter); + hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); + } + } + hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE); + + /* De-init the adapter */ + hdd_deinit_adapter(pHddCtx, pAdapter); + memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx)); + pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ? + WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO; + + /* + * If Powersave Offload is enabled + * Fw will take care incase of concurrency + */ + if (!pHddCtx->cfg_ini->enablePowersaveOffload) { + /* Disable BMPS and IMPS if enabled before starting Go */ + if (WLAN_HDD_P2P_GO == pAdapter->device_mode) { + if(VOS_STATUS_E_FAILURE == + hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO)) { + /* Fail to Exit BMPS */ + VOS_ASSERT(0); + } + } + } + + if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) && + (pConfig->apRandomBssidEnabled)) { + /* To meet Android requirements create a randomized + MAC address of the form 02:1A:11:Fx:xx:xx */ + get_random_bytes(&ndev->dev_addr[3], 3); + ndev->dev_addr[0] = 0x02; + ndev->dev_addr[1] = 0x1A; + ndev->dev_addr[2] = 0x11; + ndev->dev_addr[3] |= 0xF0; + memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr, + VOS_MAC_ADDR_SIZE); + pr_info("wlan: Generated HotSpot BSSID "MAC_ADDRESS_STR"\n", + MAC_ADDR_ARRAY(ndev->dev_addr)); + } + + hdd_set_ap_ops(pAdapter->dev); + + /* This is for only SAP mode where users can + * control country through ini. + * P2P GO follows station country code + * acquired during the STA scanning. */ + if ((NL80211_IFTYPE_AP == type) && + (memcmp(pConfig->apCntryCode, + CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)) { + hddLog(LOG1, FL("Setting country code from INI")); + init_completion(&pAdapter->change_country_code); + hstatus = sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_cb, + pConfig->apCntryCode, pAdapter, + pHddCtx->pvosContext, + eSIR_FALSE, eSIR_TRUE); + if (eHAL_STATUS_SUCCESS == hstatus) { + /* Wait for completion */ + rc = wait_for_completion_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if (!rc) { + hddLog(LOGE, + FL("SME Timed out while setting country code")); + } + } else { + hddLog(LOGE, FL("SME Change Country code failed")); + return -EINVAL; + } + } + + vstatus = hdd_init_ap_mode(pAdapter); + if (vstatus != VOS_STATUS_SUCCESS) { + hddLog(LOGP, FL("Error initializing the ap mode")); + return -EINVAL; + } + hdd_set_conparam(1); + +#ifdef QCA_LL_TX_FLOW_CT + if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) { + vos_timer_init(&pAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_softap_tx_resume_timer_expired_handler, + pAdapter); + pAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_softap_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); +#endif /* QCA_LL_TX_FLOW_CT */ + + /* Interface type changed update in wiphy structure */ + if (wdev) { + wdev->iftype = type; + pHddCtx->change_iface = type; + } else { + hddLog(LOGE, FL("Wireless dev is NULL")); + return -EINVAL; + } + goto done; + } + + default: + hddLog(LOGE, FL("Unsupported interface type (%d)"), type); + return -EOPNOTSUPP; + } + } else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + switch (type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_ADHOC: + status = wlan_hdd_change_iface_to_sta_mode(ndev, type); + if (status != VOS_STATUS_SUCCESS) + return status; + +#ifdef QCA_LL_TX_FLOW_CT + if ((NL80211_IFTYPE_P2P_CLIENT == type) || + (NL80211_IFTYPE_STATION == type)) { + if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) { + vos_timer_init(&pAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_tx_resume_timer_expired_handler, + pAdapter); + pAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); + } +#endif /* QCA_LL_TX_FLOW_CT */ + + /* FW will take care if PS offload is enabled. */ + if (pHddCtx->cfg_ini->enablePowersaveOffload) + goto done; + + if (pHddCtx->hdd_wlan_suspended) { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + goto done; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + wdev->iftype = type; + pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ? + WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO; +#ifdef QCA_LL_TX_FLOW_CT + if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) { + vos_timer_init(&pAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_softap_tx_resume_timer_expired_handler, + pAdapter); + pAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_softap_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); +#endif /* QCA_LL_TX_FLOW_CT */ + goto done; + + default: + hddLog(LOGE, FL("Unsupported interface type(%d)"), type); + return -EOPNOTSUPP; + } + } else { + hddLog(LOGE, FL("Unsupported device mode(%d)"), pAdapter->device_mode); + return -EOPNOTSUPP; + } + + if (LastBSSType != pRoamProfile->BSSType) { + /* Interface type changed update in wiphy structure */ + wdev->iftype = type; + + /* The BSS mode changed, We need to issue disconnect + if connected or in IBSS disconnect state */ + if (hdd_connGetConnectedBssType( + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType) || + (eCSR_BSS_TYPE_START_IBSS == LastBSSType)) { + /* Need to issue a disconnect to CSR.*/ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + if (eHAL_STATUS_SUCCESS == + sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED)) { + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog(LOGE, + FL("Wait on disconnect_comp_var failed")); + } + } + } + } + +done: + /* Set bitmask based on updated value */ + wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode); + + /* Only STA mode support TM now + * all other mode, TM feature should be disabled */ + if ((pHddCtx->cfg_ini->thermalMitigationEnable) && + (~VOS_STA & pHddCtx->concurrency_mode)) { + hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0); + } + +#ifdef WLAN_BTAMP_FEATURE + if ((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <= 1)) { + /* We are ok to do AMP */ + pHddCtx->isAmpAllowed = VOS_TRUE; + } +#endif /* WLAN_BTAMP_FEATURE */ + +#ifdef WLAN_FEATURE_LPSS + wlan_hdd_send_all_scan_intf_info(pHddCtx); +#endif + + EXIT(); + return 0; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_change_iface + * wrapper function to protect the actual implementation from SSR. + */ +static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef FEATURE_WLAN_TDLS +static int wlan_hdd_tdls_add_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + VOS_STATUS status; + hddTdlsPeer_t *pTdlsPeer; + tANI_U16 numCurrTdlsPeers; + unsigned long rc; + long ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return ret; + } + + if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) || + (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: TDLS mode is disabled OR not enabled in FW." + MAC_ADDRESS_STR " Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + return -ENOTSUPP; + } + + pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac); + + if ( NULL == pTdlsPeer ) { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid", + __func__, MAC_ADDR_ARRAY(mac), update); + return -EINVAL; + } + + /* in add station, we accept existing valid staId if there is */ + if ((0 == update) && + ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) || + (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR + " link_status %d. staId %d. add station ignored.", + __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId); + return 0; + } + /* in change station, we accept only when staId is valid */ + if ((1 == update) && + ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) || + (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId)))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR + " link status %d. staId %d. change station %s.", + __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId, + (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined"); + return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM; + } + + /* when others are on-going, we want to change link_status to idle */ + if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS setup is ongoing. Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + goto error; + } + + /* first to check if we reached to maximum supported TDLS peer. + TODO: for now, return -EPERM looks working fine, + but need to check if any other errno fit into this category.*/ + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (pHddCtx->max_num_tdls_sta <= numCurrTdlsPeers) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected. Request declined." + " Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers, + pHddCtx->max_num_tdls_sta); + goto error; + } + else + { + hddTdlsPeer_t *pTdlsPeer; + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " already connected. Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + return -EPERM; + } + } + if (0 == update) + wlan_hdd_tdls_set_link_status(pAdapter, + mac, + eTDLS_LINK_CONNECTING, + eTDLS_LINK_SUCCESS); + + /* debug code */ + if (NULL != StaParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: TDLS Peer Parameters.", __func__); + if(StaParams->htcap_present) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "ht_capa->extended_capabilities: %0x", + StaParams->HTCap.extendedHtCapInfo); + } + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "params->capability: %0x",StaParams->capability); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "params->ext_capab_len: %0x",StaParams->extn_capability[0]); + if(StaParams->vhtcap_present) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x", + StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest, + StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest); + } + { + int i = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:"); + for (i = 0; i < sizeof(StaParams->supported_rates); i++) + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "[%d]: %x ", i, StaParams->supported_rates[i]); + } + } /* end debug code */ + else if ((1 == update) && (NULL == StaParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : update is true, but staParams is NULL. Error!", __func__); + return -EPERM; + } + + INIT_COMPLETION(pAdapter->tdls_add_station_comp); + + if (!update) + { + status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, mac); + } + else + { + status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, mac, StaParams); + } + + rc = wait_for_completion_timeout(&pAdapter->tdls_add_station_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); + + if (!rc) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: timeout waiting for tdls add station indication", + __func__); + return -EPERM; + } + + if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Add Station is unsuccessful", __func__); + return -EPERM; + } + + return 0; + +error: + wlan_hdd_tdls_set_link_status(pAdapter, + mac, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + return -EPERM; + +} +#endif + +static bool wlan_hdd_is_duplicate_channel(tANI_U8 *arr, + int index, + tANI_U8 match) +{ + int i; + for (i = 0; i < index; i++) { + if (arr[i] == match) + return TRUE; + } + return FALSE; +} + +static int wlan_hdd_change_station(struct wiphy *wiphy, + struct net_device *dev, + u8 *mac, + struct station_parameters *params) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + v_MACADDR_t STAMacAddress; +#ifdef FEATURE_WLAN_TDLS + tCsrStaParams StaParams = {0}; + tANI_U8 isBufSta = 0; + tANI_U8 isOffChannelSupported = 0; +#endif + int ret; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CHANGE_STATION, + pAdapter->sessionId, params->listen_interval)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t)); + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) { + status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress, + WLANTL_STA_AUTHENTICATED); + + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Not able to change TL state to AUTHENTICATED")); + return -EINVAL; + } + } + } else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) { +#ifdef FEATURE_WLAN_TDLS + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + StaParams.capability = params->capability; + StaParams.uapsd_queues = params->uapsd_queues; + StaParams.max_sp = params->max_sp; + + /* Convert (first channel , number of channels) tuple to + * the total list of channels. This goes with the assumption + * that if the first channel is < 14, then the next channels + * are an incremental of 1 else an incremental of 4 till the number + * of channels. + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: params->supported_channels_len: %d", + __func__, params->supported_channels_len); + if (0 != params->supported_channels_len) { + int i = 0, j = 0, k = 0, no_of_channels = 0; + int num_unique_channels; + int next; + for (i = 0 ; i < params->supported_channels_len && + j < SIR_MAC_MAX_SUPP_CHANNELS; i += 2) { + int wifi_chan_index; + if (!wlan_hdd_is_duplicate_channel( + StaParams.supported_channels, + j, + params->supported_channels[i])){ + StaParams.supported_channels[j] = + params->supported_channels[i]; + } else { + continue; + } + wifi_chan_index = + ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 ); + no_of_channels = params->supported_channels[i + 1]; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: i: %d, j: %d, k: %d, StaParams.supported_channels[%d]: %d, wifi_chan_index: %d, no_of_channels: %d", + __func__, i, j, k, j, + StaParams.supported_channels[j], + wifi_chan_index, + no_of_channels); + + for (k = 1; k <= no_of_channels && + j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++) { + next = StaParams.supported_channels[j] + wifi_chan_index; + if (!wlan_hdd_is_duplicate_channel( + StaParams.supported_channels, + j+1, + next)){ + StaParams.supported_channels[j + 1] = next; + } else { + continue; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: i: %d, j: %d, k: %d, StaParams.supported_channels[%d]: %d", + __func__, i, j, k, j+1, + StaParams.supported_channels[j+1]); + j += 1; + } + } + num_unique_channels = j+1; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Unique Channel List", __func__); + for (i = 0; i < num_unique_channels; i++) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: StaParams.supported_channels[%d]: %d,", + __func__, i, StaParams.supported_channels[i]); + } + /* num of channels should not be more than max + * number of channels in 2.4GHz and 5GHz + */ + if (MAX_CHANNEL < num_unique_channels) + num_unique_channels = MAX_CHANNEL; + + StaParams.supported_channels_len = num_unique_channels; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: After removing duplcates StaParams.supported_channels_len: %d", + __func__, StaParams.supported_channels_len); + } + vos_mem_copy(StaParams.supported_oper_classes, + params->supported_oper_classes, + params->supported_oper_classes_len); + StaParams.supported_oper_classes_len = + params->supported_oper_classes_len; + + if (0 != params->ext_capab_len) + vos_mem_copy(StaParams.extn_capability, params->ext_capab, + sizeof(StaParams.extn_capability)); + + if (NULL != params->ht_capa) { + StaParams.htcap_present = 1; + vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap)); + } + + StaParams.supported_rates_len = params->supported_rates_len; + + /* + * Note : The Maximum sizeof supported_rates sent by the Supplicant + * is 32. The supported_rates array, for all the structures + * propagating till Add Sta to the firmware has to be modified, + * if the supplicant (ieee80211) is modified to send more rates. + */ + + /* To avoid Data Corruption, set to max length + to SIR_MAC_MAX_SUPP_RATES */ + if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES) + StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES; + + if (0 != StaParams.supported_rates_len) { + int i = 0; + vos_mem_copy(StaParams.supported_rates, params->supported_rates, + StaParams.supported_rates_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Supported Rates with Length %d", StaParams.supported_rates_len); + for (i=0; i < StaParams.supported_rates_len; i++) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "[%d]: %0x", i, StaParams.supported_rates[i]); + } + + if (NULL != params->vht_capa) { + StaParams.vhtcap_present = 1; + vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap)); + } + + if (0 != params->ext_capab_len ) { + /*Define A Macro : TODO Sunil*/ + if ((1<<4) & StaParams.extn_capability[3]) { + isBufSta = 1; + } + /* TDLS Channel Switching Support */ + if ((1<<6) & StaParams.extn_capability[3]) { + isOffChannelSupported = 1; + } + } + + status = wlan_hdd_tdls_set_peer_caps(pAdapter, mac, + &StaParams, isBufSta, + isOffChannelSupported); + if (VOS_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wlan_hdd_tdls_set_peer_caps failed!")); + return -EINVAL; + } + + status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams); + if (VOS_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wlan_hdd_tdls_add_station failed!")); + return -EINVAL; + } + } +#endif + } + EXIT(); + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_add_key + * This function is used to initialize the key information + */ +static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + tCsrRoamSetKey setKey; + u8 groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int status; + v_U32_t roamId= 0xFF; +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; +#endif + hdd_hostapd_state_t *pHostapdState; + eHalStatus halStatus; + hdd_context_t *pHddCtx; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_KEY, + pAdapter->sessionId, params->key_len)); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__, pAdapter->device_mode); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__, + key_index); + + return -EINVAL; + } + + if (CSR_MAX_KEY_LEN < params->key_len) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__, + params->key_len); + + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: called with key index = %d & key length %d", + __func__, key_index, params->key_len); + + /*extract key idx, key len and key*/ + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + setKey.keyLength = params->key_len; + vos_mem_copy(&setKey.Key[0],params->key, params->key_len); + + switch (params->cipher) + { + case WLAN_CIPHER_SUITE_WEP40: + setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + break; + + case WLAN_CIPHER_SUITE_WEP104: + setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + break; + + case WLAN_CIPHER_SUITE_TKIP: + { + u8 *pKey = &setKey.Key[0]; + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey, params->key, 16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16], ¶ms->key[24], 8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24], ¶ms->key[16], 8); + + + break; + } + + case WLAN_CIPHER_SUITE_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + +#ifdef FEATURE_WLAN_WAPI + case WLAN_CIPHER_SUITE_SMS4: + { + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr, + params->key, params->key_len); + return 0; + } +#endif + +#ifdef FEATURE_WLAN_ESE + case WLAN_CIPHER_SUITE_KRK: + setKey.encType = eCSR_ENCRYPT_TYPE_KRK; + break; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WLAN_CIPHER_SUITE_BTK: + setKey.encType = eCSR_ENCRYPT_TYPE_BTK; + break; +#endif +#endif + +#ifdef WLAN_FEATURE_11W + case WLAN_CIPHER_SUITE_AES_CMAC: + setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC; + break; +#endif + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u", + __func__, params->cipher); + return -EOPNOTSUPP; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d", + __func__, setKey.encType); + + if (!pairwise) + { + /* set group key*/ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: setting Broadcast key", + __func__, __LINE__); + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE); + } + else + { + /* set pairwise key*/ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: setting pairwise key", + __func__, __LINE__); + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac, mac_addr, VOS_MAC_ADDR_SIZE); + } + if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise) + { + /* if a key is already installed, block all subsequent ones */ + if (pAdapter->sessionCtx.station.ibss_enc_key_installed) { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: IBSS key installed already", __func__); + return 0; + } + + setKey.keyDirection = eSIR_TX_RX; + /*Set the group key*/ + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", __func__, status); + return -EINVAL; + } + /*Save the keys here and call sme_RoamSetKey for setting + the PTK after peer joins the IBSS network*/ + vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key, + &setKey, sizeof(tCsrRoamSetKey)); + + pAdapter->sessionCtx.station.ibss_enc_key_installed = 1; + return status; + } + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) + { + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if( pHostapdState->bssState == BSS_START ) + { +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), + &setKey); +#else + status = WLANSAP_SetKeySta( pVosContext, &setKey); +#endif + if ( status != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", + __LINE__, status ); + } + } + + /* Saving WEP keys */ + else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType || + eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType ) + { + //Save the wep key in ap context. Issue setkey after the BSS is started. + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey)); + } + else + { + //Save the key in ap context. Issue setkey after the BSS is started. + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey)); + } + } + else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) ) + { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (!pairwise) + { + /* set group key*/ + if (pHddStaCtx->roam_info.deferKeyComplete) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: Perform Set key Complete", + __func__, __LINE__); + hdd_PerformRoamSetKeyComplete(pAdapter); + } + } + + pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len; + + pWextState->roamProfile.Keys.defaultIndex = key_index; + + + vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0], + params->key, params->key_len); + + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5], + setKey.keyDirection); + + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* The supplicant may attempt to set the PTK once pre-authentication + is done. Save the key in the UMAC and include it in the ADD BSS + request */ + halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey); + if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: Update PreAuth Key success", __func__); + return 0; + } + else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Update PreAuth Key failed", __func__); + return -EINVAL; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + /* issue set key request to SME*/ + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + return -EINVAL; + } + + + /* in case of IBSS as there was no information available about WEP keys during + * IBSS join, group key initialized with NULL key, so re-initialize group key + * with correct value*/ + if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) && + !( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) + ) + && + ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher) + || (WLAN_CIPHER_SUITE_WEP104 == params->cipher) + ) + ) + { + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE); + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5], + setKey.keyDirection); + + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed for group key (IBSS), returned %d", + __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + return -EINVAL; + } + } + } + + return 0; +} + +static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params + ) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise, + mac_addr, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_get_key + * This function is used to get the key information + */ +static int __wlan_hdd_cfg80211_get_key( + struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params*) + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile); + struct key_params params; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_GET_KEY, + pAdapter->sessionId, params.cipher)); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Device_mode = %d"), pAdapter->device_mode); + + memset(¶ms, 0, sizeof(params)); + + if (CSR_MAX_NUM_KEY <= key_index) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index); + return -EINVAL; + } + + switch (pRoamProfile->EncryptionType.encryptionType[0]) { + case eCSR_ENCRYPT_TYPE_NONE: + params.cipher = IW_AUTH_CIPHER_NONE; + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + params.cipher = WLAN_CIPHER_SUITE_WEP40; + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + params.cipher = WLAN_CIPHER_SUITE_WEP104; + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + params.cipher = WLAN_CIPHER_SUITE_TKIP; + break; + + case eCSR_ENCRYPT_TYPE_AES: + params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + break; + + default: + params.cipher = IW_AUTH_CIPHER_NONE; + break; + } + + params.key_len = pRoamProfile->Keys.KeyLength[key_index]; + params.seq_len = 0; + params.seq = NULL; + params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0]; + callback(cookie, ¶ms); + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_get_key( + struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params*) + ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise, + mac_addr, cookie, callback); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_del_key + * This function is used to delete the key information + */ +static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr + ) +{ + int status = 0; + + //This code needs to be revisited. There is sme_removeKey API, we should + //plan to use that. After the change to use correct index in setkey, + //it is observed that this is invalidating peer + //key index whenever re-key is done. This is affecting data link. + //It should be ok to ignore del_key. +#if 0 + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + u8 groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + + ENTER(); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d", + __func__,pAdapter->device_mode); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__, + key_index); + + return -EINVAL; + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + + if (mac_addr) + vos_mem_copy(setKey.peerMac, mac_addr, VOS_MAC_ADDR_SIZE); + else + vos_mem_copy(setKey.peerMac, groupmacaddr, VOS_MAC_ADDR_SIZE); + + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if( pHostapdState->bssState == BSS_START) + { +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), + &setKey); +#else + status = WLANSAP_SetKeySta( pVosContext, &setKey); +#endif + + if ( status != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", + __LINE__, status ); + } + } + } + else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + ) + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5]); + if(pAdapter->sessionCtx.station.conn_info.connState == + eConnectionState_Associated) + { + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failure, returned %d", + __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + return -EINVAL; + } + } + } +#endif + EXIT(); + return status; +} + +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static int wlan_hdd_cfg80211_key_mgmt_set_pmk(struct wiphy *wiphy, + struct net_device *ndev, + const u8 *pmk, size_t pmk_len) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); + hdd_wext_state_t *pWextState; + hdd_station_ctx_t *pHddStaCtx; + + ENTER(); + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (pmk) { + tANI_U8 localPmk [SIR_ROAM_SCAN_PSK_SIZE]; + if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) +#ifdef FEATURE_WLAN_ESE + && (!pWextState->isESEConnection) +#endif + ) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: calling sme_RoamSetPSK_PMK \n", __func__); + vos_mem_copy(localPmk, pmk, SIR_ROAM_SCAN_PSK_SIZE); + sme_RoamSetPSK_PMK(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, localPmk, pmk_len); + return VOS_STATUS_SUCCESS; + } + } + return VOS_STATUS_SUCCESS; +} +#endif +#endif + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_default_key + * This function is used to set the default tx key index + */ +static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool unicast, bool multicast) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + pAdapter->sessionId, key_index)); + + hddLog(LOG1, FL("Device_mode = %d key_index = %d"), + pAdapter->device_mode, key_index); + + if (CSR_MAX_NUM_KEY <= key_index) { + hddLog(LOGE, FL("Invalid key index %d"), key_index); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) { + if ((eCSR_ENCRYPT_TYPE_TKIP != + pHddStaCtx->conn_info.ucEncryptionType) && + (eCSR_ENCRYPT_TYPE_AES != + pHddStaCtx->conn_info.ucEncryptionType)) { + /* If default key index is not same as previous one, + * then update the default key index */ + + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + tCsrKeys *Keys = &pWextState->roamProfile.Keys; + + hddLog(LOG2, FL("Default tx key index %d"), key_index); + + Keys->defaultIndex = (u8)key_index; + vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + setKey.keyLength = Keys->KeyLength[key_index]; + + vos_mem_copy(&setKey.Key[0], + &Keys->KeyMaterial[key_index][0], + Keys->KeyLength[key_index]); + + setKey.keyDirection = eSIR_TX_RX; + + vos_mem_copy(setKey.peerMac, + &pHddStaCtx->conn_info.bssId[0], VOS_MAC_ADDR_SIZE); + + if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN && + pWextState->roamProfile.EncryptionType.encryptionType[0] == + eCSR_ENCRYPT_TYPE_WEP104) { + /* + * In the case of dynamic wep supplicant hardcodes DWEP type + * to eCSR_ENCRYPT_TYPE_WEP104 even though ap is configured for + * WEP-40 encryption. In this case the key length is 5 but the + * encryption type is 104 hence checking the key length(5) and + * encryption type(104) and switching encryption type to 40. + */ + pWextState->roamProfile.EncryptionType.encryptionType[0] = + eCSR_ENCRYPT_TYPE_WEP40; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = + eCSR_ENCRYPT_TYPE_WEP40; + } + + setKey.encType = + pWextState->roamProfile.EncryptionType.encryptionType[0]; + + /* Issue set key request */ + status = sme_RoamSetKey(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId); + + if (0 != status) { + hddLog(LOGE, FL("sme_RoamSetKey failed, returned %d"), status); + return -EINVAL; + } + } + } else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) { + /* In SoftAp mode setting key direction for default mode */ + if ((eCSR_ENCRYPT_TYPE_TKIP != + pWextState->roamProfile.EncryptionType.encryptionType[0]) && + (eCSR_ENCRYPT_TYPE_AES != + pWextState->roamProfile.EncryptionType.encryptionType[0])) { + /* Saving key direction for default key index to TX default */ + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT; + } + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool unicast, bool multicast) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast, + multicast); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_inform_bss + * This function is used to inform the BSS details to nl80211 interface. + */ +static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss( + hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile) +{ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + tSirBssDescription *pBssDesc = roamProfile->pBssDesc; + int chan_no; + int ie_length; + const char *ie; + unsigned int freq; + struct ieee80211_channel *chan; + int rssi = 0; + struct cfg80211_bss *bss = NULL; + + ENTER(); + + if (NULL == pBssDesc) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("pBssDesc is NULL")); + return bss; + } + + chan_no = pBssDesc->channelId; + ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length ); + ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL); + + if (NULL == ie) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("IE of BSS descriptor is NULL")); + return bss; + } + + if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ)) { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ); + } else { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ); + } + + chan = __ieee80211_get_channel(wiphy, freq); + + if (!chan) { + hddLog(LOGE, FL("chan pointer is NULL")); + return NULL; + } + + bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId, + &roamProfile->SSID.ssId[0], roamProfile->SSID.length, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + if (bss == NULL) { + rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100; + + return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId, + le64_to_cpu(*(__le64 *)pBssDesc->timeStamp), + pBssDesc->capabilityInfo, + pBssDesc->beaconInterval, ie, ie_length, + rssi, GFP_KERNEL )); + } else { + return bss; + } +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_bss_list + * This function is used to inform nl80211 interface that BSS might have + * been lost. + */ +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo) +{ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + tSirBssDescription *pBssDesc = pRoamInfo->pBssDesc; + int chan_no; + unsigned int freq; + struct ieee80211_channel *chan; + struct cfg80211_bss *bss = NULL; + + ENTER(); + + if (NULL == pBssDesc) { + hddLog(LOGE, FL("pBssDesc is NULL")); + return bss; + } + + if (NULL == pRoamInfo->pProfile) { + hddLog(LOGE, FL("Roam profile is NULL")); + return bss; + } + + chan_no = pBssDesc->channelId; + + if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ)) { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ); + } else { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ); + } + + chan = __ieee80211_get_channel(wiphy, freq); + + if (!chan) { + hddLog(LOGE, FL("chan pointer is NULL")); + return NULL; + } + + bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId, + &pRoamInfo->pProfile->SSIDs.SSIDList->SSID.ssId[0], + pRoamInfo->pProfile->SSIDs.SSIDList->SSID.length, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + if (bss == NULL) { + hddLog(LOGE, FL("BSS not present")); + } else { + hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pBssDesc->bssId)); + cfg80211_unlink_bss(wiphy, bss); + } + return bss; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame + * This function is used to inform the BSS details to nl80211 interface. + */ +struct cfg80211_bss* +wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter, + tSirBssDescription *bss_desc + ) +{ + /* + cfg80211_inform_bss() is not updating ie field of bss entry, if entry + already exists in bss data base of cfg80211 for that particular BSS ID. + Using cfg80211_inform_bss_frame to update the bss entry instead of + cfg80211_inform_bss, But this call expects mgmt packet as input. As of + now there is no possibility to get the mgmt(probe response) frame from PE, + converting bss_desc to ieee80211_mgmt(probe response) and passing to + cfg80211_inform_bss_frame. + */ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + int chan_no = bss_desc->channelId; +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS + qcom_ie_age *qie_age = NULL; + int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age); +#else + int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ); +#endif + const char *ie = + ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL); + unsigned int freq; + struct ieee80211_channel *chan; + struct ieee80211_mgmt *mgmt = NULL; + struct cfg80211_bss *bss_status = NULL; + size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length; + int rssi = 0; + hdd_context_t *pHddCtx; + int status; +#ifdef CONFIG_CNSS + struct timespec ts; +#endif + hdd_config_t *cfg_param = NULL; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return NULL; + } + + cfg_param = pHddCtx->cfg_ini; + mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL); + if (!mgmt) { + hddLog(LOGE, FL("memory allocation failed")); + return NULL; + } + + memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN); + +#ifdef CONFIG_CNSS + /* Android does not want the time stamp from the frame. + Instead it wants a monotonic increasing value */ + cnss_get_monotonic_boottime(&ts); + mgmt->u.probe_resp.timestamp = + ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); +#else + /* keep old behavior for non-open source (for now) */ + memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp, + sizeof (bss_desc->timeStamp)); + +#endif + + mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval; + mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo; + +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS + /* GPS Requirement: need age ie per entry. Using vendor specific. */ + /* Assuming this is the last IE, copy at the end */ + ie_length -=sizeof(qcom_ie_age); + qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length); + qie_age->element_id = QCOM_VENDOR_IE_ID; + qie_age->len = QCOM_VENDOR_IE_AGE_LEN; + qie_age->oui_1 = QCOM_OUI1; + qie_age->oui_2 = QCOM_OUI2; + qie_age->oui_3 = QCOM_OUI3; + qie_age->type = QCOM_VENDOR_IE_AGE_TYPE; + qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime; +#endif + + memcpy(mgmt->u.probe_resp.variable, ie, ie_length); + if (bss_desc->fProbeRsp) { + mgmt->frame_control |= + (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); + } else { + mgmt->frame_control |= + (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); + } + + if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) && + (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL)) { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ); + } else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) && + (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL)) { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ); + } else { + hddLog(LOGE, FL("Invalid chan_no %d"), chan_no); + kfree(mgmt); + return NULL; + } + + chan = __ieee80211_get_channel(wiphy, freq); + /* + * When the band is changed on the fly using the GUI, three things are done + * 1. scan abort + * 2. flush scan results from cache + * 3. update the band with the new band user specified (refer to the + * hdd_setBand_helper function) as part of the scan abort, message will be + * queued to PE and we proceed with flushing and changing the band. + * PE will stop the scanning further and report back the results what ever + * it had till now by calling the call back function. + * if the time between update band and scandone call back is sufficient + * enough the band change reflects in SME, SME validates the channels + * and discards the channels corresponding to previous band and calls back + * with zero bss results. but if the time between band update and scan done + * callback is very small then band change will not reflect in SME and SME + * reports to HDD all the channels corresponding to previous band.this is + * due to race condition.but those channels are invalid to the new band and + * so this function __ieee80211_get_channel will return NULL.Each time we + * report scan result with this pointer null warning kernel trace is printed + * if the scan results contain large number of APs continuously kernel + * warning trace is printed and it will lead to apps watch dog bark. + * So drop the bss and continue to next bss. + */ + if (chan == NULL) { + hddLog(LOGE, FL("chan pointer is NULL")); + kfree(mgmt); + return NULL; + } + + /* Based on .ini configuration, raw rssi can be reported for bss. + * Raw rssi is typically used for estimating power. + */ + + rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw : + bss_desc->rssi; + + /* Supplicant takes the signal strength in terms of mBm(100*dBm) */ + rssi = (VOS_MIN(rssi, 0)) * 100; + + hddLog(LOG1, FL("BSSID: "MAC_ADDRESS_STR" Channel:%d RSSI:%d"), + MAC_ADDR_ARRAY(mgmt->bssid), chan->center_freq, (int)(rssi/100)); + + bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt, frame_len, rssi, + GFP_KERNEL); + kfree(mgmt); + return bss_status; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_bss_db + * This function is used to update the BSS data base of CFG8011 + */ +struct cfg80211_bss* +wlan_hdd_cfg80211_update_bss_db(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + tCsrRoamConnectedProfile roamProfile; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + struct cfg80211_bss *bss = NULL; + + ENTER(); + + memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile)); + sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile); + + if (NULL != roamProfile.pBssDesc) { + bss = wlan_hdd_cfg80211_inform_bss(pAdapter, + &roamProfile); + + if (NULL == bss) { + hddLog(LOG1, FL("cfg80211_inform_bss return NULL")); + } + + sme_RoamFreeConnectProfile(hHal, &roamProfile); + } else { + hddLog(LOGE, FL("roamProfile.pBssDesc is NULL")); + } + EXIT(); + return bss; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_bss + */ +static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy, + hdd_adapter_t *pAdapter + ) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tCsrScanResultInfo *pScanResult; + eHalStatus status = 0; + tScanResultHandle pResult; + struct cfg80211_bss *bss_status = NULL; + hdd_context_t *pHddCtx; + int ret; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_UPDATE_BSS, + NO_SESSION, pAdapter->sessionId)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + /* + * start getting scan results and populate cgf80211 BSS database + */ + status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult); + + /* no scan results */ + if (NULL == pResult) { + hddLog(LOG1, FL("No scan result Status %d"), status); + return status; + } + + pScanResult = sme_ScanResultGetFirst(hHal, pResult); + + while (pScanResult) { + /* + * cfg80211_inform_bss() is not updating ie field of bss entry, if + * entry already exists in bss data base of cfg80211 for that + * particular BSS ID. Using cfg80211_inform_bss_frame to update the + * bss entry instead of cfg80211_inform_bss, But this call expects + * mgmt packet as input. As of now there is no possibility to get + * the mgmt(probe response) frame from PE, converting bss_desc to + * ieee80211_mgmt(probe response) and passing to c + * fg80211_inform_bss_frame. + * */ + + bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter, + &pScanResult->BssDescriptor); + + + if (NULL == bss_status) { + hddLog(LOG1, FL("NULL returned by cfg80211_inform_bss_frame")); + } else { + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + wiphy, +#endif + bss_status); + } + + pScanResult = sme_ScanResultGetNext(hHal, pResult); + } + + sme_ScanResultPurge(hHal, pResult); + + EXIT(); + return 0; +} + +void +hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel) +{ + VOS_TRACE(VOS_MODULE_ID_HDD, logLevel, + "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4], + pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10], + pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]); +} /****** end hddPrintPmkId() ******/ + +#define dump_pmkid(pMac, pmkid) \ + { \ + hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \ + hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\ + } + +#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +/* + * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify + * This function is used to notify the supplicant of a new PMKSA candidate. + */ +int wlan_hdd_cfg80211_pmksa_candidate_notify( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + int index, bool preauth ) +{ +#ifdef FEATURE_WLAN_OKC + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + ENTER(); + hddLog(LOG1, FL("is going to notify supplicant of:")); + + if (NULL == pRoamInfo) { + hddLog(LOGP, FL("pRoamInfo is NULL")); + return -EINVAL; + } + + if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_INFO, MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pRoamInfo->bssid)); + cfg80211_pmksa_candidate_notify(dev, index, pRoamInfo->bssid, + preauth, GFP_KERNEL); + } +#endif /* FEATURE_WLAN_OKC */ + return 0; +} +#endif //FEATURE_WLAN_LFR + +#ifdef FEATURE_WLAN_LFR_METRICS +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth + * 802.11r/LFR metrics reporting function to report preauth initiation + * + */ +#define MAX_LFR_METRICS_EVENT_LENGTH 100 +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = scnprintf(metrics_notification, + sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status + * 802.11r/LFR metrics reporting function to report preauth completion + * or failure + */ +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + scnprintf(metrics_notification, sizeof(metrics_notification), + "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + if (1 == preauth_status) + strncat(metrics_notification, " TRUE", 5); + else + strncat(metrics_notification, " FALSE", 6); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = strlen(metrics_notification); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover + * 802.11r/LFR metrics reporting function to report handover initiation + * + */ +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = scnprintf(metrics_notification, + sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} +#endif + +/* + * FUNCTION: hdd_cfg80211_scan_done_callback + * scanning callback function, called after finishing scan + * + */ +static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle, + void *pContext, + tANI_U8 sessionId, + tANI_U32 scanId, + eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + //struct wireless_dev *wdev = dev->ieee80211_ptr; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_scaninfo_t *pScanInfo = &pAdapter->scan_info; + struct cfg80211_scan_request *req = NULL; + bool aborted = false; + unsigned long rc; + int ret = 0; + + ENTER(); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s called with halHandle = %p, pContext = %p," + "scanID = %d, returned status = %d", + __func__, halHandle, pContext, (int) scanId, (int) status); + + pScanInfo->mScanPendingCounter = 0; + + //Block on scan req completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pScanInfo->scan_req_completion_event, + msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s wait on scan_req_completion_event timed out", __func__); + VOS_ASSERT(pScanInfo->mScanPending); + goto allow_suspend; + } + + if (pScanInfo->mScanPending != VOS_TRUE) + { + VOS_ASSERT(pScanInfo->mScanPending); + goto allow_suspend; + } + + /* Check the scanId */ + if (pScanInfo->scanId != scanId) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s called with mismatched scanId pScanInfo->scanId = %d " + "scanId = %d", __func__, (int) pScanInfo->scanId, + (int) scanId); + } + + ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy, + pAdapter); + + if (0 > ret) + hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__); + + + /* If any client wait scan result through WEXT + * send scan done event to client */ + if (pAdapter->scan_info.waitScanResult) + { + /* The other scan request waiting for current scan finish + * Send event to notify current scan finished */ + if(WEXT_SCAN_PENDING_DELAY == pAdapter->scan_info.scan_pending_option) + { + vos_event_set(&pAdapter->scan_info.scan_finished_event); + } + /* Send notify to WEXT client */ + else if(WEXT_SCAN_PENDING_PIGGYBACK == pAdapter->scan_info.scan_pending_option) + { + struct net_device *dev = pAdapter->dev; + union iwreq_data wrqu; + int we_event; + char *msg; + + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + } + } + pAdapter->scan_info.waitScanResult = FALSE; + + /* Get the Scan Req */ + req = pAdapter->request; + + if (!req) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL"); + pScanInfo->mScanPending = VOS_FALSE; + goto allow_suspend; + } + + pAdapter->request = NULL; + /* Scan is no longer pending */ + pScanInfo->mScanPending = VOS_FALSE; + + /* + * cfg80211_scan_done informing NL80211 about completion + * of scanning + */ + if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE) + { + aborted = true; + } + cfg80211_scan_done(req, aborted); + + complete(&pScanInfo->abortscan_event_var); + +allow_suspend: + /* release the wake lock at the end of the scan*/ + hdd_allow_suspend(); + + /* Acquire wakelock to handle the case where APP's tries to suspend + * immediately after the driver gets connect request(i.e after scan) + * from supplicant, this result in app's is suspending and not able + * to process the connect request to AP */ + hdd_prevent_suspend_timeout(1000); + +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_scan_done_callback(pAdapter); +#endif + + EXIT(); + return 0; +} + +/* + * FUNCTION: hdd_isConnectionInProgress + * Go through each adapter and check if Connection is in progress + * + */ +bool hdd_isConnectionInProgress(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status = 0; + v_U8_t staId = 0; + v_U8_t *staMac = NULL; + + if (TRUE == pHddCtx->btCoexModeSet) { + hddLog(LOG1, FL("BTCoex Mode operation in progress")); + return true; + } + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + + if (pAdapter) { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Adapter with device mode %d exists", + __func__, pAdapter->device_mode); + if (((WLAN_HDD_INFRA_STATION == + pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == + pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == + pAdapter->device_mode)) && + (eConnectionState_Connecting == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))-> + conn_info.connState)) { + hddLog(LOGE, + FL("%p(%d) Connection is in progress"), + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + pAdapter->sessionId); + return true; + } + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + smeNeighborRoamIsHandoffInProgress( + WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %p(%d) Reassociation is in progress", __func__, + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId); + return VOS_TRUE; + } + if ((WLAN_HDD_INFRA_STATION == + pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == + pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == + pAdapter->device_mode)) { + pHddStaCtx = + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if ((eConnectionState_Associated == + pHddStaCtx->conn_info.connState) && + (VOS_FALSE == + pHddStaCtx->conn_info. + uIsAuthenticated)) { + staMac = (v_U8_t *) &(pAdapter-> + macAddressCurrent.bytes[0]); + hddLog(LOGE, + FL("client " MAC_ADDRESS_STR " is in the middle of WPS/EAPOL exchange."), + MAC_ADDR_ARRAY(staMac)); + return true; + } + } else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode)) { + for (staId = 0; staId < WLAN_MAX_STA_COUNT; + staId++) { + if ((pAdapter->aStaInfo[staId]. + isUsed) && + (WLANTL_STA_CONNECTED == + pAdapter->aStaInfo[staId]. + tlSTAState)) { + staMac = (v_U8_t *) &(pAdapter-> + aStaInfo[staId]. + macAddrSTA.bytes[0]); + + hddLog(LOGE, + FL("client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the " + "middle of WPS/EAPOL exchange."), + MAC_ADDR_ARRAY(staMac)); + return true; + } + } + } + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + return false; +} + +static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) +{ + hdd_adapter_t *adapter = container_of(work, + hdd_adapter_t, scan_block_work); + struct cfg80211_scan_request *request = adapter->request; + + request->n_ssids = 0; + request->n_channels = 0; + + hddLog(LOGE, + "%s:##In DFS Master mode. Scan aborted. Null result sent", + __func__); + cfg80211_scan_done(request, true); + adapter->request = NULL; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_scan + * this scan respond to scan trigger and update cfg80211 scan database + * later, scan dump command can be used to receive scan results + */ +int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = request->wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_config_t *cfg_param = NULL; + tCsrScanRequest scanRequest; + tANI_U8 *channelList = NULL, i; + v_U32_t scanId = 0; + int status; + hdd_scaninfo_t *pScanInfo = NULL; + v_U8_t* pP2pIe = NULL; + hdd_adapter_t *con_sap_adapter; + uint16_t con_dfs_ch; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SCAN, + pAdapter->sessionId, request->n_channels)); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__, pAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + cfg_param = pHddCtx->cfg_ini; + pScanInfo = &pAdapter->scan_info; + +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if (VOS_TRUE == WLANBAP_AmpSessionOn()) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: No scanning when AMP is on", __func__); + return -EOPNOTSUPP; + } +#endif + //Scan on any other interface is not supported. + if (pAdapter->device_mode == WLAN_HDD_SOFTAP) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Not scanning on device_mode = %d", + __func__, pAdapter->device_mode); + return -EOPNOTSUPP; + } + /* Block All Scan during DFS operation and send null scan result */ + con_sap_adapter = hdd_get_con_sap_adapter(pAdapter); + if (con_sap_adapter) { + con_dfs_ch = con_sap_adapter->sessionCtx.ap.sapConfig.channel; + if (con_dfs_ch == AUTO_CHANNEL_SELECT) + con_dfs_ch = con_sap_adapter->sessionCtx.ap.operatingChannel; + + if (VOS_IS_DFS_CH(con_dfs_ch)) { + /* Provide empty scan result during DFS operation since scanning + * not supported during DFS. Reason is following case: + * DFS is supported only in SCC for MBSSID Mode. + * We shall not return EBUSY or ENOTSUPP as when Primary AP is + * operating in DFS channel and secondary AP is started. Though we + * force SCC in driver, the hostapd issues obss scan before + * starting secAP. This results in MCC in DFS mode. + * Thus we return null scan result. If we return scan failure + * hostapd fails secondary AP startup. + */ + pAdapter->request = request; + +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->scan_block_work, + wlan_hdd_cfg80211_scan_block_cb); +#else + INIT_WORK(&pAdapter->scan_block_work, + wlan_hdd_cfg80211_scan_block_cb); +#endif + + schedule_work(&pAdapter->scan_block_work); + return 0; + } + } + + if (TRUE == pScanInfo->mScanPending) + { + if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__); + } + return -EBUSY; + } + +#ifdef FEATURE_WLAN_SCAN_PNO + /* This check will not allow any normal scan when we already issued + * an PNO scan. + */ + if (TRUE == pScanInfo->mPnoScanPending) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mPnoScanPending is TRUE", __func__); + return -EBUSY; + } +#endif + + //Don't Allow Scan and return busy if Remain On + //Channel and action frame is pending + //Otherwise Cancel Remain On Channel and allow Scan + //If no action frame pending + if (0 != wlan_hdd_check_remain_on_channel(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__); + return -EBUSY; + } +#ifdef FEATURE_WLAN_TDLS + /* if tdls disagree scan right now, return immediately. + tdls will schedule the scan when scan is allowed. (return SUCCESS) + or will reject the scan if any TDLS is in progress. (return -EBUSY) + */ + status = wlan_hdd_tdls_scan_callback (pAdapter, + wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request); + if (status <= 0) + { + if (!status) + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress.scan rejected %d", + __func__, status); + else + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d", + __func__, status); + + return status; + } +#endif + + if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Acquire lock fail", __func__); + return -EAGAIN; + } + if (TRUE == pHddCtx->tmInfo.tmAction.enterImps) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: MAX TM Level Scan not allowed", __func__); + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + return -EBUSY; + } + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + + /* Check if scan is allowed at this point of time. + */ + if (hdd_isConnectionInProgress(pHddCtx)) { + hddLog(LOGE, FL("Scan not allowed")); + return -EBUSY; + } + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d", + request->n_ssids); + + /* Even though supplicant doesn't provide any SSIDs, n_ssids is + * set to 1. Because of this, driver is assuming that this is not + * wildcard scan and so is not aging out the scan results. + */ + if ((request->ssids) && (request->n_ssids == 1) && + ('\0' == request->ssids->ssid[0])) + { + request->n_ssids = 0; + } + + if ((request->ssids) && (0 < request->n_ssids)) + { + tCsrSSIDInfo *SsidInfo; + int j; + scanRequest.SSIDs.numOfSSIDs = request->n_ssids; + /* Allocate num_ssid tCsrSSIDInfo structure */ + SsidInfo = scanRequest.SSIDs.SSIDList = + vos_mem_malloc(request->n_ssids * sizeof(tCsrSSIDInfo)); + + if (NULL == scanRequest.SSIDs.SSIDList) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: memory alloc failed SSIDInfo buffer", __func__); + return -ENOMEM; + } + + /* copy all the ssid's and their length */ + for (j = 0; j < request->n_ssids; j++, SsidInfo++) + { + /* get the ssid length */ + SsidInfo->SSID.length = request->ssids[j].ssid_len; + vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0], + SsidInfo->SSID.length); + SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0'; + hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s", + j, SsidInfo->SSID.ssId); + } + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else + { + /* Set the scan type to default type, in this case it is ACTIVE */ + scanRequest.scanType = pHddCtx->ioctl_scan_mode; + } + scanRequest.minChnTime = cfg_param->nActiveMinChnTime; + scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime; + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + if (MAX_CHANNEL < request->n_channels) + { + hddLog(VOS_TRACE_LEVEL_WARN, "No of Scan Channels exceeded limit: %d", + request->n_channels); + request->n_channels = MAX_CHANNEL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "No of Scan Channels: %d", request->n_channels); + + if (request->n_channels) + { + char chList [(request->n_channels*5)+1]; + int len; + channelList = vos_mem_malloc(request->n_channels); + if (NULL == channelList) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "channelList memory alloc failed channelList"); + status = -ENOMEM; + goto free_mem; + } + for (i = 0, len = 0; i < request->n_channels ; i++ ) + { + channelList[i] = request->channels[i]->hw_value; + len += snprintf(chList+len, 5, "%d ", channelList[i]); + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Channel-List: %s", chList); + + } + scanRequest.ChannelInfo.numOfChannels = request->n_channels; + scanRequest.ChannelInfo.ChannelList = channelList; + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + /* Flush the scan results(only p2p beacons) for STA scan and P2P + * search (Flush on both full scan and social scan but not on single + * channel scan).P2P search happens on 3 social channels (1, 6, 11) + */ + + /* Supplicant does single channel scan after 8-way handshake + * and in that case driver shouldn't flush scan results. If + * driver flushes the scan results here and unfortunately if + * the AP doesn't respond to our probe req then association + * fails which is not desired + */ + + if (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) + { + hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results"); + sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId ); + } + + if (request->ie_len) + { + /* save this for future association (join requires this) */ + memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) ); + memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len); + pScanInfo->scanAddIE.length = request->ie_len; + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode) + ) + { + pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata; + pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length; + } + + scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length; + scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata; + + pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie, + request->ie_len); + if (pP2pIe != NULL) + { +#ifdef WLAN_FEATURE_P2P_DEBUG + if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) || + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) && + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1; + hddLog(VOS_TRACE_LEVEL_ERROR, + "[P2P State] Changing state from Go nego completed to Connection is started"); + hddLog(VOS_TRACE_LEVEL_ERROR, + "[P2P]P2P Scanning is started for 8way Handshake"); + } + else if ((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) && + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2; + hddLog(VOS_TRACE_LEVEL_ERROR, + "[P2P State] Changing state from Disconnected state to Connection is started"); + hddLog(VOS_TRACE_LEVEL_ERROR, + "[P2P]P2P Scanning is started for 4way Handshake"); + } +#endif + + /* no_cck will be set during p2p find to disable 11b rates */ + if (request->no_cck) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: This is a P2P Search", __func__); + scanRequest.p2pSearch = 1; + + if (request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS) + { + /* set requestType to P2P Discovery */ + scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY; + } + + /* + * Skip Dfs Channel in case of P2P Search if it is set in + * ini file + */ + if (cfg_param->skipDfsChnlInP2pSearch) + { + scanRequest.skipDfsChnlInP2pSearch = 1; + } + else + { + scanRequest.skipDfsChnlInP2pSearch = 0; + } + + } + } + } + + INIT_COMPLETION(pScanInfo->scan_req_completion_event); + + /* acquire the wakelock to avoid the apps suspend during the scan. To + * address the following issues. + * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in + * BMPS/IMPS this result in android trying to suspend aggressively and backing off + * for long time, this result in apps running at full power for long time. + * 2) Connected scenario: If we allow the suspend during the scan, RIVA will + * be stuck in full power because of resume BMPS + */ + hdd_prevent_suspend(); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,p2pSearch %d, skipDfsChnlIn P2pSearch %d", + scanRequest.requestType, scanRequest.scanType, + scanRequest.minChnTime, scanRequest.maxChnTime, + scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch); + + status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &scanRequest, &scanId, + &hdd_cfg80211_scan_done_callback, dev ); + + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_ScanRequest returned error %d", __func__, status); + complete(&pScanInfo->scan_req_completion_event); + if(eHAL_STATUS_RESOURCES == status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress.So defer the scan by informing busy", + __func__); + status = -EBUSY; + } + else + { + status = -EIO; + } + + hdd_allow_suspend(); + goto free_mem; + } + + pScanInfo->mScanPending = TRUE; + pAdapter->request = request; + pScanInfo->scanId = scanId; + + complete(&pScanInfo->scan_req_completion_event); + +free_mem: + if( scanRequest.SSIDs.SSIDList ) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); + } + + if( channelList ) + vos_mem_free( channelList ); + + EXIT(); + + return status; +} + +int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_scan(wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request); + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel) +{ + v_U8_t iniDot11Mode = + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode; + eHddDot11Mode hddDot11Mode = iniDot11Mode; + + hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"), + iniDot11Mode); + switch ( iniDot11Mode ) + { + case eHDD_DOT11_MODE_AUTO: + case eHDD_DOT11_MODE_11ac: + case eHDD_DOT11_MODE_11ac_ONLY: +#ifdef WLAN_FEATURE_11AC + hddDot11Mode = eHDD_DOT11_MODE_11ac; +#else + hddDot11Mode = eHDD_DOT11_MODE_11n; +#endif + break; + case eHDD_DOT11_MODE_11n: + case eHDD_DOT11_MODE_11n_ONLY: + hddDot11Mode = eHDD_DOT11_MODE_11n; + break; + default: + hddDot11Mode = iniDot11Mode; + break; + } + /* This call decides required channel bonding mode */ + sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal), + hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode), + operationChannel); +} + +/* + * FUNCTION: wlan_hdd_cfg80211_connect_start + * This function is used to start the association process + */ +int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter, + const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel) +{ + int status = 0; + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + v_U32_t roamId; + tCsrRoamProfile *pRoamProfile; + eCsrAuthType RSNAuthType; + + ENTER(); + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + status = wlan_hdd_validate_context(pHddCtx); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid!", __func__); + return status; + } + + if (SIR_MAC_MAX_SSID_LENGTH < ssid_len) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__); + return -EINVAL; + } + + pRoamProfile = &pWextState->roamProfile; + + if (pRoamProfile) + { + hdd_station_ctx_t *pHddStaCtx; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (HDD_WMM_USER_MODE_NO_QOS == + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode) + { + /*QoS not enabled in cfg file*/ + pRoamProfile->uapsd_mask = 0; + } + else + { + /*QoS enabled, update uapsd mask from cfg file*/ + pRoamProfile->uapsd_mask = + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask; + } + + pRoamProfile->SSIDs.numOfSSIDs = 1; + pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len; + vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId, + sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId)); + vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId), + ssid, ssid_len); + + if (bssid) + { + pRoamProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid, + VOS_MAC_ADDR_SIZE); + /* Save BSSID in separate variable as well, as RoamProfile + BSSID is getting zeroed out in the association process. And in + case of join failure we should send valid BSSID to supplicant + */ + vos_mem_copy((void *)(pWextState->req_bssId), bssid, + VOS_MAC_ADDR_SIZE); + } + else + { + vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid), VOS_MAC_ADDR_SIZE); + } + + hddLog(LOG1, FL("Connect to SSID: %.*s operating Channel: %u"), + pRoamProfile->SSIDs.SSIDList->SSID.length, + pRoamProfile->SSIDs.SSIDList->SSID.ssId, + operatingChannel); + + if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) || + (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion)) + { + /*set gen ie*/ + hdd_SetGENIEToCsr(pAdapter, &RSNAuthType); + /*set auth*/ + hdd_set_csr_auth_type(pAdapter, RSNAuthType); + } +#ifdef FEATURE_WLAN_WAPI + if (pAdapter->wapi_info.nWapiMode) + { + hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__); + switch (pAdapter->wapi_info.wapiAuthMode) + { + case WAPI_AUTH_MODE_PSK: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__, + pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + break; + } + case WAPI_AUTH_MODE_CERT: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__, + pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + break; + } + } // End of switch + if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK || + pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) + { + hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + } + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef WLAN_FEATURE_GTK_OFFLOAD + /* Initializing gtkOffloadReqParams */ + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + memset(&pHddStaCtx->gtkOffloadReqParams, 0, + sizeof (tSirGtkOffloadParams)); + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + } +#endif + pRoamProfile->csrPersona = pAdapter->device_mode; + + if( operatingChannel ) + { + pRoamProfile->ChannelInfo.ChannelList = &operatingChannel; + pRoamProfile->ChannelInfo.numOfChannels = 1; + } + else + { + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + } + if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel) + { + /* + * Need to post the IBSS power save parameters + * to WMA. WMA will configure this parameters + * to firmware if power save is enabled by the + * firmware. + */ + status = hdd_setIbssPowerSaveParams(pAdapter); + + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Set IBSS Power Save Params Failed", __func__); + return -EINVAL; + } + hdd_select_cbmode(pAdapter,operatingChannel); + } + + /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect() + * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state + * If direct path, conn_state will be accordingly changed to NotConnected or Associated + * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback() + * if sme_RomConnect is to be queued, Connecting state will remain until it is completed. + */ + if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_Connecting", + __func__); + hdd_connSetConnectionState(pAdapter, + eConnectionState_Connecting); + } + + /* After 8-way handshake supplicant should give the scan command + * in that it update the additional IEs, But because of scan + * enhancements, the supplicant is not issuing the scan command now. + * So the unicast frames which are sent from the host are not having + * the additional IEs. If it is P2P CLIENT and there is no additional + * IE present in roamProfile, then use the additional IE form scan_info + */ + + if ((pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) && + (!pRoamProfile->pAddIEScan)) + { + pRoamProfile->pAddIEScan = &pAdapter->scan_info.scanAddIE.addIEdata[0]; + pRoamProfile->nAddIEScanLength = pAdapter->scan_info.scanAddIE.length; + } + + status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, pRoamProfile, &roamId); + + if ((eHAL_STATUS_SUCCESS != status) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with " + "status %d. -> NotConnected", __func__, pAdapter->sessionId, status); + /* change back to NotAssociated */ + hdd_connSetConnectionState(pAdapter, + eConnectionState_NotConnected); + } + + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__); + return -EINVAL; + } + EXIT(); + return status; +} + +/* + * FUNCTION: wlan_hdd_set_cfg80211_auth_type + * This function is used to set the authentication type (OPEN/SHARED). + * + */ +static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter, + enum nl80211_auth_type auth_type) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + /*set authentication type*/ + switch (auth_type) + { + case NL80211_AUTHTYPE_AUTOMATIC: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to AUTOSWITCH", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH; + break; + + case NL80211_AUTHTYPE_OPEN_SYSTEM: +#ifdef WLAN_FEATURE_VOWIFI_11R + case NL80211_AUTHTYPE_FT: +#endif /* WLAN_FEATURE_VOWIFI_11R */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to OPEN", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + + case NL80211_AUTHTYPE_SHARED_KEY: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to SHARED", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY; + break; +#ifdef FEATURE_WLAN_ESE + case NL80211_AUTHTYPE_NETWORK_EAP: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to CCKM WPA", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required. + break; +#endif + + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unsupported authentication type %d", __func__, + auth_type); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN; + return -EINVAL; + } + + pWextState->roamProfile.AuthType.authType[0] = + pHddStaCtx->conn_info.authType; + return 0; +} + +/* + * FUNCTION: wlan_hdd_set_akm_suite + * This function is used to set the key mgmt type(PSK/8021x). + * + */ +static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter, + u32 key_mgmt + ) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + ENTER(); + /* Should be in ieee802_11_defs.h */ +#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05 +#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06 + /*set key mgmt type*/ + switch(key_mgmt) + { + case WLAN_AKM_SUITE_PSK: + case WLAN_AKM_SUITE_PSK_SHA256: +#ifdef WLAN_FEATURE_VOWIFI_11R + case WLAN_AKM_SUITE_FT_PSK: +#endif + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK; + break; + + case WLAN_AKM_SUITE_8021X_SHA256: + case WLAN_AKM_SUITE_8021X: +#ifdef WLAN_FEATURE_VOWIFI_11R + case WLAN_AKM_SUITE_FT_8021X: +#endif + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + break; +#ifdef FEATURE_WLAN_ESE +#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */ +#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */ + case WLAN_AKM_SUITE_CCKM: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM; + break; +#endif +#ifndef WLAN_AKM_SUITE_OSEN +#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */ +#endif + case WLAN_AKM_SUITE_OSEN: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + break; + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d", + __func__, key_mgmt); + return -EINVAL; + + } + return 0; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_cipher + * This function is used to set the encryption type + * (NONE/WEP40/WEP104/TKIP/CCMP). + */ +static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter, + u32 cipher, + bool ucast + ) +{ + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + if (!cipher) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none", + __func__, cipher); + encryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + + /*set encryption method*/ + switch (cipher) + { + case IW_AUTH_CIPHER_NONE: + encryptionType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case WLAN_CIPHER_SUITE_WEP40: + encryptionType = eCSR_ENCRYPT_TYPE_WEP40; + break; + + case WLAN_CIPHER_SUITE_WEP104: + encryptionType = eCSR_ENCRYPT_TYPE_WEP104; + break; + + case WLAN_CIPHER_SUITE_TKIP: + encryptionType = eCSR_ENCRYPT_TYPE_TKIP; + break; + + case WLAN_CIPHER_SUITE_CCMP: + encryptionType = eCSR_ENCRYPT_TYPE_AES; + break; +#ifdef FEATURE_WLAN_WAPI + case WLAN_CIPHER_SUITE_SMS4: + encryptionType = eCSR_ENCRYPT_TYPE_WPI; + break; +#endif + +#ifdef FEATURE_WLAN_ESE + case WLAN_CIPHER_SUITE_KRK: + encryptionType = eCSR_ENCRYPT_TYPE_KRK; + break; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WLAN_CIPHER_SUITE_BTK: + encryptionType = eCSR_ENCRYPT_TYPE_BTK; + break; +#endif +#endif + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d", + __func__, cipher); + return -EOPNOTSUPP; + } + } + + if (ucast) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d", + __func__, encryptionType); + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = + encryptionType; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d", + __func__, encryptionType); + pHddStaCtx->conn_info.mcEncryptionType = encryptionType; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType; + } + + return 0; +} + + +/* + * FUNCTION: wlan_hdd_cfg80211_set_ie + * This function is used to parse WPA/RSN IE's. + */ +int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter, + u8 *ie, + size_t ie_len + ) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + u8 *genie = ie; + v_U16_t remLen = ie_len; +#ifdef FEATURE_WLAN_WAPI + v_U32_t akmsuite[MAX_NUM_AKM_SUITES]; + u16 *tmp; + v_U16_t akmsuiteCount; + int *akmlist; +#endif + ENTER(); + + /* clear previous assocAddIE */ + pWextState->assocAddIE.length = 0; + pWextState->roamProfile.bWPSAssociation = VOS_FALSE; + pWextState->roamProfile.bOSENAssociation = VOS_FALSE; + + while (remLen >= 2) + { + v_U16_t eLen = 0; + v_U8_t elementId; + elementId = *genie++; + eLen = *genie++; + remLen -= 2; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]", + __func__, elementId, eLen); + + switch ( elementId ) + { + case DOT11F_EID_WPA: + if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */ + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WPA IE", __func__); + return -EINVAL; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)", + __func__, eLen + 2); + + if (SIR_MAC_MAX_ADD_IE_LENGTH < + (pWextState->assocAddIE.length + eLen)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.bWPSAssociation = VOS_TRUE; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) + { + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/); + pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len; + } + else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE, + P2P_OUI_TYPE_SIZE))) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)", + __func__, eLen + 2); + + if (SIR_MAC_MAX_ADD_IE_LENGTH < + (pWextState->assocAddIE.length + eLen)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } +#ifdef WLAN_FEATURE_WFD + else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE, + WFD_OUI_TYPE_SIZE)) + /*Consider WFD IE, only for P2P Client */ + && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)", + __func__, eLen + 2); + + if (SIR_MAC_MAX_ADD_IE_LENGTH < + (pWextState->assocAddIE.length + eLen)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // WFD IE is saved to Additional IE ; it should be accumulated to handle + // WPS IE + P2P IE + WFD IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } +#endif + /* Appending HS 2.0 Indication Element in Association Request */ + else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE, + HS20_OUI_TYPE_SIZE)) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)", + __func__, eLen + 2); + + if (SIR_MAC_MAX_ADD_IE_LENGTH < + (pWextState->assocAddIE.length + eLen)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + /* Appending OSEN Information Element in Association Request */ + else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE, + OSEN_OUI_TYPE_SIZE)) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)", + __func__, eLen + 2); + + if ( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.bOSENAssociation = VOS_TRUE; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + break; + case DOT11F_EID_RSN: + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/); + pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len; + break; + /* Appending Extended Capabilities with Interworking bit set in Assoc Req */ + case DOT11F_EID_EXTCAP: + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)", + __func__, eLen + 2); + + if (SIR_MAC_MAX_ADD_IE_LENGTH < + (pWextState->assocAddIE.length + eLen)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + break; + } +#ifdef FEATURE_WLAN_WAPI + case WLAN_EID_WAPI: + pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1 + hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u", + pAdapter->wapi_info.nWapiMode); + tmp = (u16 *)ie; + tmp = tmp + 2; // Skip element Id and Len, Version + akmsuiteCount = WPA_GET_LE16(tmp); + tmp = tmp + 1; + akmlist = (int *)(tmp); + if(akmsuiteCount <= MAX_NUM_AKM_SUITES) + { + memcpy(akmsuite, akmlist, (4*akmsuiteCount)); + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count"); + VOS_ASSERT(0); + return -EINVAL; + } + + if (WAPI_PSK_AKM_SUITE == akmsuite[0]) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK", + __func__); + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK; + } + if (WAPI_CERT_AKM_SUITE == akmsuite[0]) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE", + __func__); + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT; + } + break; +#endif + default: + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s Set UNKNOWN IE %X", __func__, elementId); + /* when Unknown IE is received we should break and continue + * to the next IE in the buffer instead we were returning + * so changing this to break */ + break; + } + genie += eLen; + remLen -= eLen; + } + EXIT(); + return 0; +} + +/* + * FUNCTION: hdd_isWPAIEPresent + * Parse the received IE to find the WPA IE + * + */ +static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len) +{ + v_U8_t eLen = 0; + v_U16_t remLen = ie_len; + v_U8_t elementId = 0; + + while (remLen >= 2) + { + elementId = *ie++; + eLen = *ie++; + remLen -= 2; + if (eLen > remLen) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: IE length is wrong %d", __func__, eLen); + return FALSE; + } + if ((elementId == DOT11F_EID_WPA) && (remLen > 5)) + { + /* OUI - 0x00 0X50 0XF2 + WPA Information Element - 0x01 + WPA version - 0x01*/ + if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5)) + return TRUE; + } + ie += eLen; + remLen -= eLen; + } + return FALSE; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_privacy + * This function is used to initialize the security + * parameters during connect operation. + */ +int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter, + struct cfg80211_connect_params *req + ) +{ + int status = 0; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + ENTER(); + + /*set wpa version*/ + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + + if (req->crypto.wpa_versions) + { + if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + } + else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2; + } + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__, + pWextState->wpaVersion); + + /*set authentication type*/ + status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set authentication type ", __func__); + return status; + } + + /*set key mgmt type*/ + if (req->crypto.n_akm_suites) + { + status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite", + __func__); + return status; + } + } + + /*set pairwise cipher type*/ + if (req->crypto.n_ciphers_pairwise) + { + status = wlan_hdd_cfg80211_set_cipher(pAdapter, + req->crypto.ciphers_pairwise[0], true); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set unicast cipher type", __func__); + return status; + } + } + else + { + /*Reset previous cipher suite to none*/ + status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set unicast cipher type", __func__); + return status; + } + } + + /*set group cipher type*/ + status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group, + false); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type", + __func__); + return status; + } + +#ifdef WLAN_FEATURE_11W + pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED); +#endif + + /* Parse WPA/RSN IE, and set the corresponding fields in Roam profile */ + if (req->ie_len) + { + status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len); + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE", + __func__); + return status; + } + } + + /*incase of WEP set default key information*/ + if (req->key && req->key_len) + { + if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0]) + || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0]) + ) + { + if ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported", + __func__); + return -EOPNOTSUPP; + } + else + { + u8 key_len = req->key_len; + u8 key_idx = req->key_idx; + + if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len) + && (CSR_MAX_NUM_KEY > key_idx) + ) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: setting default wep key, key_idx = %hu key_len %hu", + __func__, key_idx, key_len); + vos_mem_copy( + &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0], + req->key, key_len); + pWextState->roamProfile.Keys.KeyLength[key_idx] = + (u8)key_len; + pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx; + } + } + } + } + + return status; +} + +/* + * FUNCTION: wlan_hdd_try_disconnect + * This function is used to disconnect from previous + * connection + */ +static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter ) +{ + unsigned long rc; + hdd_station_ctx_t *pHddStaCtx; + eMib_dot11DesiredBssType connectedBssType; + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType ); + + if((eMib_dot11DesiredBssType_independent == connectedBssType) || + (eConnectionState_Associated == pHddStaCtx->conn_info.connState) || + (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)) + { + /* Issue disconnect to CSR */ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + if( eHAL_STATUS_SUCCESS == + sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED ) ) + { + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog(LOGE, FL("Sme disconnect event timed out session Id %d" + " staDebugState %d"), pAdapter->sessionId, + pHddStaCtx->staDebugState); + return -EALREADY; + } + } + } + else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) + { + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog(LOGE, FL("Disconnect event timed out session Id %d" + " staDebugState %d"), pAdapter->sessionId, + pHddStaCtx->staDebugState); + return -EALREADY; + } + } + + return 0; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_connect + * This function is used to start the association process + */ +static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req + ) +{ + int status; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL; + hdd_context_t *pHddCtx; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CONNECT, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %d",__func__,pAdapter->device_mode); + + if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION && + pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: device_mode is not supported", __func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + /* Supplicant indicate its decision to offload key management + * by setting the third bit in flags in case of Secure connection + * so if the supplicant does not support this then LFR3.0 shall + * be disabled.if supplicant indicates support for offload + * of key management then we shall enable LFR3.0.Note that + * supplicant set the bit in flags means driver already indicated + * its capability to handle the key management and LFR3.0 is + * enabled in INI and FW also has the capability to handle + * key management offload as part of LFR3.0 + */ + +#ifdef NL80211_KEY_LEN_PMK /* if kernel supports key mgmt offload */ + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_ERROR, + "%s: LFR3:Supplicant association request flags %x", + __func__, req->flags); + if (!(req->flags & ASSOC_REQ_OFFLOAD_KEY_MGMT)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Supplicant does not support key mgmt offload for this AP")); + sme_UpdateRoamKeyMgmtOffloadEnabled(pHddCtx->hHal, + pAdapter->sessionId, + FALSE); + } else { + sme_UpdateRoamKeyMgmtOffloadEnabled(pHddCtx->hHal, + pAdapter->sessionId, + TRUE); + } +#else + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Kernel does not support key mgmt offload")); + sme_UpdateRoamKeyMgmtOffloadEnabled(pHddCtx->hHal, pAdapter->sessionId, FALSE); +#endif /* #ifdef NL80211_KEY_LEN_PMK */ + +#endif + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Reached max concurrent connections")); + return -ECONNREFUSED; + } + +#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + wlan_hdd_disable_roaming(pAdapter); +#endif + +#ifdef WLAN_BTAMP_FEATURE + //Infra connect not supported when AMP traffic is on. + if (VOS_TRUE == WLANBAP_AmpSessionOn()) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: No connection when AMP is on", __func__); + return -ECONNREFUSED; + } +#endif + + //If Device Mode is Station Concurrent Sessions Exit BMps + //P2P Mode will be taken care in Open/close adapter + if (!pHddCtx->cfg_ini->enablePowersaveOffload && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + (vos_concurrent_open_sessions_running())) { + exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, + WLAN_HDD_INFRA_STATION); + } + + /*Try disconnecting if already in connected state*/ + status = wlan_hdd_try_disconnect(pAdapter); + if ( 0 > status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing" + " connection")); + return -EALREADY; + } + + /*initialise security parameters*/ + status = wlan_hdd_cfg80211_set_privacy(pAdapter, req); + + if (0 > status) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params", + __func__); + return status; + } + + if (req->channel) { + status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid, + req->ssid_len, req->bssid, + req->channel->hw_value); + } else { + status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid, + req->ssid_len, req->bssid, 0); + } + + if (0 > status) { + //ReEnable BMPS if disabled + // If PS offload is enabled, fw will take care of +// ps in cae of concurrency. + if((VOS_STATUS_SUCCESS == exitbmpsStatus) && + (NULL != pHddCtx) && !pHddCtx->cfg_ini->enablePowersaveOffload) { + if (pHddCtx->hdd_wlan_suspended) { + hdd_set_pwrparams(pHddCtx); + } + //ReEnable Bmps and Imps back + hdd_enable_bmps_imps(pHddCtx); + } + + hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed")); + return status; + } +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if ((eHAL_STATUS_SUCCESS == status) && (req->psk)) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: psk = %p", __func__, req->psk); + /* since PMK is available only in cfg80211_connect(), we save it + * even before we know connection succeeded or not */ + if (pHddCtx->cfg_ini->isRoamOffloadEnabled) { + hdd_wext_state_t *pWextState = + WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tANI_U8 localPsk [SIR_ROAM_SCAN_PSK_SIZE]; + if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) +#ifdef FEATURE_WLAN_ESE + && (!pWextState->isESEConnection) +#endif + ) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("calling sme_RoamSetPSK")); + vos_mem_copy(localPsk, req->psk, SIR_ROAM_SCAN_PSK_SIZE); + sme_RoamSetPSK_PMK(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, localPsk, SIR_ROAM_SCAN_PSK_SIZE); + } + } + } +#endif +#endif + pHddCtx->isAmpAllowed = VOS_FALSE; + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_disconnect + * This function is used to issue a disconnect request to SME + */ +int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason ) +{ + int status, result = 0; + unsigned long rc; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + /*stop tx queues*/ + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + pHddCtx->isAmpAllowed = VOS_TRUE; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_Disconnecting", + __func__); + pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting; + INIT_COMPLETION(pAdapter->disconnect_comp_var); + + /*issue disconnect*/ + + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, reason); + if (eHAL_STATUS_CMD_NOT_QUEUED == status) { + hddLog(LOG1, FL("status = %d, already disconnected"), (int)status); + goto disconnected; + } else if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s csrRoamDisconnect failure, returned %d", + __func__, (int)status ); + pHddStaCtx->staDebugState = status; + result = -EINVAL; + goto disconnected; + } + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failed to disconnect, timed out", __func__); + result = -ETIMEDOUT; + } + +disconnected: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Set HDD connState to eConnectionState_NotConnected")); + hdd_connSetConnectionState(pAdapter, + eConnectionState_NotConnected); + + return result; +} + + +/* + * FUNCTION: __wlan_hdd_cfg80211_disconnect + * This function is used to issue a disconnect request to SME + */ +static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy, + struct net_device *dev, + u16 reason + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + int status; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + eConnectionState connState; +#ifdef FEATURE_WLAN_TDLS + tANI_U8 staIdx; +#endif + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DISCONNECT, + pAdapter->sessionId, reason)); + hddLog(VOS_TRACE_LEVEL_INFO, FL("device_mode (%d) reason code(%d)"), + pAdapter->device_mode, reason); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + /* Issue disconnect request to SME, if station is in connected state */ + if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) || + (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)) { + eCsrRoamDisconnectReason reasonCode = + eCSR_DISCONNECT_REASON_UNSPECIFIED; + hdd_scaninfo_t *pScanInfo; + + connState = pHddStaCtx->conn_info.connState; + switch (reason) { + case WLAN_REASON_MIC_FAILURE: + reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR; + break; + + case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY: + case WLAN_REASON_DISASSOC_AP_BUSY: + case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: + reasonCode = eCSR_DISCONNECT_REASON_DISASSOC; + break; + + case WLAN_REASON_PREV_AUTH_NOT_VALID: + case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + reasonCode = eCSR_DISCONNECT_REASON_DEAUTH; + break; + + case WLAN_REASON_DEAUTH_LEAVING: + reasonCode = pHddCtx->cfg_ini->gEnableDeauthToDisassocMap ? + eCSR_DISCONNECT_REASON_STA_HAS_LEFT : + eCSR_DISCONNECT_REASON_DEAUTH; + break; + case WLAN_REASON_DISASSOC_STA_HAS_LEFT: + reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT; + break; + default: + reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED; + break; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("convert to internal reason %d to reasonCode %d"), + reason, reasonCode); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + pScanInfo = &pAdapter->scan_info; + if (pScanInfo->mScanPending) { + hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, " + "Aborting Scan"); + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + +#ifdef FEATURE_WLAN_TDLS + /* First clean up the tdls peers if any */ + for (staIdx = 0 ; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) && + (pHddCtx->tdlsConnInfo[staIdx].staId)) { + uint8 *mac; + mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes; + hddLog(TDLS_LOG_LEVEL, + "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR, + __func__, pHddCtx->tdlsConnInfo[staIdx].staId, + pAdapter->sessionId, + MAC_ADDR_ARRAY(mac)); + sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + mac); + } + } +#endif + hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode); + status = wlan_hdd_disconnect(pAdapter, reasonCode); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("failure, returned %d"), status); + pHddStaCtx->conn_info.connState = connState; + return -EINVAL; + } + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("unexpected cfg disconnect called while in state (%d)"), + pHddStaCtx->conn_info.connState); + } + + return status; +} + +static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy, + struct net_device *dev, + u16 reason + ) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss + * This function is used to initialize the security + * settings in IBSS mode. + */ +static int wlan_hdd_cfg80211_set_privacy_ibss( + hdd_adapter_t *pAdapter, + struct cfg80211_ibss_params *params + ) +{ + int status = 0; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey)); + pHddStaCtx->ibss_enc_key_installed = 0; + + if (params->ie_len && ( NULL != params->ie) ) + { + if (wlan_hdd_cfg80211_get_ie_ptr (params->ie, + params->ie_len, WLAN_EID_RSN )) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2; + encryptionType = eCSR_ENCRYPT_TYPE_AES; + } + else if ( hdd_isWPAIEPresent (params->ie, params->ie_len )) + { + tDot11fIEWPA dot11WPAIE; + tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + u8 *ie; + + memset(&dot11WPAIE, 0, sizeof(dot11WPAIE)); + ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie, + params->ie_len, DOT11F_EID_WPA); + if ( NULL != ie ) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + // Unpack the WPA IE + //Skip past the EID byte and length byte - and four byte WiFi OUI + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + &ie[2+4], + ie[1] - 4, + &dot11WPAIE); + /*Extract the multicast cipher, the encType for unicast + cipher for wpa-none is none*/ + encryptionType = + hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + } + } + + status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE", + __func__); + return status; + } + } + + pWextState->roamProfile.AuthType.authType[0] = + pHddStaCtx->conn_info.authType = + eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if (params->privacy) + { + /* Security enabled IBSS, At this time there is no information available + * about the security parameters, so initialise the encryption type to + * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY. + * The correct security parameters will be updated later in + * wlan_hdd_cfg80211_add_key */ + /* Hal expects encryption type to be set inorder + *enable privacy bit in beacons */ + + encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "encryptionType=%d", encryptionType); + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType; + return status; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_join_ibss + * This function is used to create/join an IBSS + */ +static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile; + int status; + bool alloc_bssid = VOS_FALSE; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %d",__func__,pAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Reached max concurrent connections")); + return -ECONNREFUSED; + } + + /*Try disconnecting if already in connected state*/ + status = wlan_hdd_try_disconnect(pAdapter); + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing" + " IBSS connection")); + return -EALREADY; + } + + pRoamProfile = &pWextState->roamProfile; + + if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType ) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s Interface type is not set to IBSS", __func__); + return -EINVAL; + } + + /* enable selected protection checks in IBSS mode */ + pRoamProfile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK; + + if (eHAL_STATUS_FAILURE == ccmCfgSetInt( pHddCtx->hHal, + WNI_CFG_IBSS_ATIM_WIN_SIZE, + pHddCtx->cfg_ini->ibssATIMWinSize, + NULL, + eANI_BOOLEAN_FALSE)) + { + hddLog(LOGE, + "%s: Could not pass on WNI_CFG_IBSS_ATIM_WIN_SIZE to CCM", + __func__); + } + + /* BSSID is provided by upper layers hence no need to AUTO generate */ + if (NULL != params->bssid) { + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__); + return -EIO; + } + } + else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0) + { + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__); + return -EIO; + } + params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE); + if (!params->bssid) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Memory allocation failed")); + return -ENOMEM; + } + vos_mem_copy((v_U8_t *)params->bssid, + (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0], + VOS_MAC_ADDR_SIZE); + alloc_bssid = VOS_TRUE; + } + if ((params->beacon_interval > CFG_BEACON_INTERVAL_MIN) + && (params->beacon_interval <= CFG_BEACON_INTERVAL_MAX)) + pRoamProfile->beaconInterval = params->beacon_interval; + else { + pRoamProfile->beaconInterval = CFG_BEACON_INTERVAL_DEFAULT; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: input beacon interval %d TU is invalid, use default %d TU", + __func__, params->beacon_interval, + pRoamProfile->beaconInterval); + } + + /* Set Channel */ + if (NULL != +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + params->chandef.chan) +#else + params->channel) +#endif + { + u8 channelNum; + v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + int indx; + + /* Get channel number */ + channelNum = + ieee80211_frequency_to_channel( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + params->chandef.chan->center_freq); +#else + params->channel->center_freq); +#endif + + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list", + __func__); + return -EOPNOTSUPP; + } + + for (indx = 0; indx < numChans; indx++) + { + if (channelNum == validChan[indx]) + { + break; + } + } + if (indx >= numChans) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d", + __func__, channelNum); + return -EINVAL; + } + /* Set the Operational Channel */ + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__, + channelNum); + pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = channelNum; + pRoamProfile->ChannelInfo.ChannelList = + &pHddStaCtx->conn_info.operationChannel; + } + + /* Initialize security parameters */ + status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params); + if (status < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters", + __func__); + return status; + } + + /* Issue connect start */ + status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid, + params->ssid_len, params->bssid, + pHddStaCtx->conn_info.operationChannel); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__); + return status; + } + + if (NULL != params->bssid && + pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 && + alloc_bssid == VOS_TRUE) + { + vos_mem_free(params->bssid); + } + return 0; +} + +static int wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_leave_ibss + * This function is used to leave an IBSS + */ +static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status; + eHalStatus hal_status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, + pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE)); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("device_mode = %d"), pAdapter->device_mode); + if (NULL == pWextState) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Data Storage Corruption")); + return -EIO; + } + + pRoamProfile = &pWextState->roamProfile; + + /* Issue disconnect only if interface type is set to IBSS */ + if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType) { + hddLog (VOS_TRACE_LEVEL_ERROR, FL("BSS Type is not set to IBSS")); + return -EINVAL; + } + + /* Issue Disconnect request */ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE); + if (!HAL_STATUS_SUCCESS(hal_status)) { + hddLog(LOGE, + FL("sme_RoamDisconnect failed hal_status(%d)"), hal_status); + return -EAGAIN; + } + + return 0; +} + +static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params + * This function is used to set the phy parameters + * (RTS Threshold/FRAG Threshold/Retry Count etc ...) + */ +static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + tHalHandle hHal = pHddCtx->hHal; + int status; + + ENTER(); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS, + NO_SESSION, wiphy->rts_threshold)); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) + { + u32 rts_threshold = (wiphy->rts_threshold == -1) ? + WNI_CFG_RTS_THRESHOLD_STAMAX : + wiphy->rts_threshold; + + if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) || + (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid RTS Threshold value %u", + __func__, rts_threshold); + return -EINVAL; + } + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, + rts_threshold, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for rts_threshold value %u", + __func__, rts_threshold); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %u", __func__, + rts_threshold); + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) + { + u16 frag_threshold = (wiphy->frag_threshold == -1) ? + WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX : + wiphy->frag_threshold; + + if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)|| + (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid frag_threshold value %hu", __func__, + frag_threshold); + return -EINVAL; + } + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, + frag_threshold, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for frag_threshold value %hu", + __func__, frag_threshold); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__, + frag_threshold); + } + + if ((changed & WIPHY_PARAM_RETRY_SHORT) + || (changed & WIPHY_PARAM_RETRY_LONG)) + { + u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ? + wiphy->retry_short : + wiphy->retry_long; + + if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) || + (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu", + __func__, retry_value); + return -EINVAL; + } + + if (changed & WIPHY_PARAM_RETRY_SHORT) + { + if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, + retry_value, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for long retry count %hu", + __func__, retry_value); + return -EIO; + } + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu", + __func__, retry_value); + } + else if (changed & WIPHY_PARAM_RETRY_SHORT) + { + if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, + retry_value, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for short retry count %hu", + __func__, retry_value); + return -EIO; + } + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu", + __func__, retry_value); + } + } + + + return 0; +} + +static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_txpower + * This function is used to set the txpower + */ +static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif + enum nl80211_tx_power_setting type, + int dbm) +{ + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + tHalHandle hHal = NULL; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int status; + + ENTER(); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_TXPOWER, + NO_SESSION, type )); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + hHal = pHddCtx->hHal; + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, + dbm, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) { + hddLog(LOGE, FL("ccmCfgSetInt failed for tx power %hu"), dbm); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, FL("Set tx power level %d dbm"), dbm); + + switch (type) { + /* Automatically determine transmit power */ + case NL80211_TX_POWER_AUTOMATIC: + /* Fall through */ + case NL80211_TX_POWER_LIMITED: /* Limit TX power by the mBm parameter */ + if (sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS) { + hddLog(LOGE, FL("Setting maximum tx power failed")); + return -EIO; + } + break; + + case NL80211_TX_POWER_FIXED: /* Fix TX power to the mBm parameter */ + hddLog(LOGE, FL("NL80211_TX_POWER_FIXED not supported")); + return -EOPNOTSUPP; + break; + + default: + hddLog(LOGE, FL("Invalid power setting type %d"), type); + return -EIO; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif + enum nl80211_tx_power_setting type, + int dbm) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_txpower(wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + wdev, +#endif + type, + dbm); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_get_txpower + * This function is used to read the txpower + */ +static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif + int *dbm) +{ + + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + *dbm = 0; + return status; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (NULL == pAdapter) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("pAdapter is NULL")); + return -ENOENT; + } + + wlan_hdd_get_classAstats(pAdapter); + *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr; + + EXIT(); + return 0; +} + + +static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *dev, + u8* mac, struct station_info *sinfo) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length; + tANI_U8 rate_flags; + + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_config_t *pCfg = pHddCtx->cfg_ini; + + tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX]; + tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX; + tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; + tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX; + tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET]; + tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET; + tANI_U16 maxRate = 0; + tANI_U16 myRate; + tANI_U16 currentRate = 0; + tANI_U8 maxSpeedMCS = 0; + tANI_U8 maxMCSIdx = 0; + tANI_U8 rateFlag = 1; + tANI_U8 i, j, rssidx; + tANI_U8 nss = 1; + int status, mode = 0, maxHtIdx; + struct index_vht_data_rate_type *supported_vht_mcs_rate; + struct index_data_rate_type *supported_mcs_rate; + +#ifdef WLAN_FEATURE_11AC + tANI_U32 vht_mcs_map; + eDataRate11ACMaxMcs vhtMaxMcs; +#endif /* WLAN_FEATURE_11AC */ + + ENTER(); + + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || + (0 == ssidlen)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or" + " Invalid ssidlen, %d", __func__, ssidlen); + /*To keep GUI happy*/ + return 0; + } + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + wlan_hdd_get_rssi(pAdapter, &sinfo->signal); + sinfo->filled |= STATION_INFO_SIGNAL; + +#ifdef WLAN_FEATURE_LPSS + if (!pAdapter->rssi_send) { + pAdapter->rssi_send = VOS_TRUE; + wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 1); + } +#endif + + wlan_hdd_get_station_stats(pAdapter); + rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags; + + //convert to the UI units of 100kbps + myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5; + if (!(rate_flags & eHAL_TX_RATE_LEGACY)) { + nss = pAdapter->hdd_stats.ClassA_stat.rx_frag_cnt; + + if (eHDD_LINK_SPEED_REPORT_ACTUAL == pCfg->reportMaxLinkSpeed) { + /* Get current rate flags if report actual */ + rate_flags = pAdapter->hdd_stats.ClassA_stat.promiscuous_rx_frag_cnt; + } + + if (pAdapter->hdd_stats.ClassA_stat.mcs_index == INVALID_MCS_IDX) { + rate_flags = eHAL_TX_RATE_LEGACY; + pAdapter->hdd_stats.ClassA_stat.mcs_index = 0; + } + } +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n", + sinfo->signal, + pCfg->reportMaxLinkSpeed, + myRate, + (int) pCfg->linkSpeedRssiHigh, + (int) pCfg->linkSpeedRssiMid, + (int) pCfg->linkSpeedRssiLow, + (int) rate_flags, + (int) pAdapter->hdd_stats.ClassA_stat.mcs_index); +#endif //LINKSPEED_DEBUG_ENABLED + + if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed) + { + // we do not want to necessarily report the current speed + if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) + { + // report the max possible speed + rssidx = 0; + } + else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed) + { + // report the max possible speed with RSSI scaling + if (sinfo->signal >= pCfg->linkSpeedRssiHigh) + { + // report the max possible speed + rssidx = 0; + } + else if (sinfo->signal >= pCfg->linkSpeedRssiMid) + { + // report middle speed + rssidx = 1; + } + else if (sinfo->signal >= pCfg->linkSpeedRssiLow) + { + // report middle speed + rssidx = 2; + } + else + { + // report actual speed + rssidx = 3; + } + } + else + { + // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid value for reportMaxLinkSpeed: %u", + __func__, pCfg->reportMaxLinkSpeed); + rssidx = 0; + } + + maxRate = 0; + + /* Get Basic Rate Set */ + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET, + OperationalRates, &ORLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + + for (i = 0; i < ORLeng; i++) + { + for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++) + { + /* Validate Rate Set */ + if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F)) + { + currentRate = supported_data_rate[j].supported_rate[rssidx]; + break; + } + } + /* Update MAX rate */ + maxRate = (currentRate > maxRate)?currentRate:maxRate; + } + + /* Get Extended Rate Set */ + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + ExtendedRates, &ERLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + + for (i = 0; i < ERLeng; i++) + { + for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++) + { + if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F)) + { + currentRate = supported_data_rate[j].supported_rate[rssidx]; + break; + } + } + /* Update MAX rate */ + maxRate = (currentRate > maxRate)?currentRate:maxRate; + } + /* Get MCS Rate Set -- + Only if we are connected in non legacy mode and not reporting + actual speed */ + if ((3 != rssidx) && + !(rate_flags & eHAL_TX_RATE_LEGACY)) + { + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET, + MCSRates, &MCSLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + rateFlag = 0; +#ifdef WLAN_FEATURE_11AC + supported_vht_mcs_rate = (struct index_vht_data_rate_type *) + ((nss == 1)? + &supported_vht_mcs_rate_nss1 : + &supported_vht_mcs_rate_nss2); + + if (rate_flags & eHAL_TX_RATE_VHT80) + mode = 2; + else if ((rate_flags & eHAL_TX_RATE_VHT40) || + (rate_flags & eHAL_TX_RATE_HT40)) + mode = 1; + else + mode = 0; + + /* VHT80 rate has separate rate table */ + if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80)) + { + ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map); + vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK ); + if (rate_flags & eHAL_TX_RATE_SGI) + { + rateFlag |= 1; + } + if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs) + { + maxMCSIdx = 7; + } + else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs) + { + maxMCSIdx = 8; + } + else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs) + { + //VHT20 is supporting 0~8 + if (rate_flags & eHAL_TX_RATE_VHT20) + maxMCSIdx = 8; + else + maxMCSIdx = 9; + } + + if (rssidx != 0) + { + for (i=0; i <= maxMCSIdx ; i++) + { + if (sinfo->signal <= rssiMcsTbl[mode][i]) + { + maxMCSIdx = i; + break; + } + } + } + + if (rate_flags & eHAL_TX_RATE_VHT80) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag]; + } + else if (rate_flags & eHAL_TX_RATE_VHT40) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag]; + } + else if (rate_flags & eHAL_TX_RATE_VHT20) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag]; + } + + maxSpeedMCS = 1; + if (currentRate > maxRate) + { + maxRate = currentRate; + } + + } + else +#endif /* WLAN_FEATURE_11AC */ + { + if (rate_flags & eHAL_TX_RATE_HT40) + { + rateFlag |= 1; + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + rateFlag |= 2; + } + + supported_mcs_rate = (struct index_data_rate_type *) + ((nss == 1)? &supported_mcs_rate_nss1 : + &supported_mcs_rate_nss2); + + maxHtIdx = MAX_HT_MCS_IDX; + if (rssidx != 0) + { + for (i=0; i < MAX_HT_MCS_IDX; i++) + { + if (sinfo->signal <= rssiMcsTbl[mode][i]) + { + maxHtIdx = i + 1; + break; + } + } + } + + for (i = 0; i < MCSLeng; i++) + { + for (j = 0; j < maxHtIdx; j++) + { + if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i]) + { + currentRate = supported_mcs_rate[j].supported_rate[rateFlag]; + break; + } + } + + if ((j < MAX_HT_MCS_IDX) && (currentRate > maxRate)) + { + maxRate = currentRate; + maxSpeedMCS = 1; + maxMCSIdx = supported_mcs_rate[j].beacon_rate_index; + } + } + } + } + + else if (!(rate_flags & eHAL_TX_RATE_LEGACY)) + { + maxRate = myRate; + maxSpeedMCS = 1; + maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index; + } + + // make sure we report a value at least as big as our current rate + if ((maxRate < myRate) || (0 == maxRate)) + { + maxRate = myRate; + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + maxSpeedMCS = 0; + } + else + { + maxSpeedMCS = 1; + maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index; + } + } + + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + sinfo->txrate.legacy = maxRate; +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy); +#endif //LINKSPEED_DEBUG_ENABLED + } + else + { + sinfo->txrate.mcs = maxMCSIdx; +#ifdef WLAN_FEATURE_11AC + sinfo->txrate.nss = nss; + if (rate_flags & eHAL_TX_RATE_VHT80) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; + } + else if (rate_flags & eHAL_TX_RATE_VHT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + else if (rate_flags & eHAL_TX_RATE_VHT20) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + } + else + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; +#endif /* WLAN_FEATURE_11AC */ + if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (rate_flags & eHAL_TX_RATE_HT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + if (!(sinfo->txrate.flags & RATE_INFO_FLAGS_VHT_MCS)) + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + } + +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting MCS rate %d flags %x\n", + sinfo->txrate.mcs, + sinfo->txrate.flags ); +#endif //LINKSPEED_DEBUG_ENABLED + } + } + else + { + // report current rate instead of max rate + + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + //provide to the UI in units of 100kbps + sinfo->txrate.legacy = myRate; +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy); +#endif //LINKSPEED_DEBUG_ENABLED + } + else + { + //must be MCS + sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index; +#ifdef WLAN_FEATURE_11AC + sinfo->txrate.nss = nss; + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + if (rate_flags & eHAL_TX_RATE_VHT80) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; + } + else if (rate_flags & eHAL_TX_RATE_VHT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } +#endif /* WLAN_FEATURE_11AC */ + if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (rate_flags & eHAL_TX_RATE_HT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + } +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting actual MCS rate %d flags %x\n", + sinfo->txrate.mcs, + sinfo->txrate.flags ); +#endif //LINKSPEED_DEBUG_ENABLED + } + } + sinfo->filled |= STATION_INFO_TX_BITRATE; + + sinfo->tx_bytes = pAdapter->stats.tx_bytes; + sinfo->filled |= STATION_INFO_TX_BYTES; + + sinfo->tx_packets = + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3]; + + sinfo->tx_retries = + pAdapter->hdd_stats.summary_stat.retry_cnt[0] + + pAdapter->hdd_stats.summary_stat.retry_cnt[1] + + pAdapter->hdd_stats.summary_stat.retry_cnt[2] + + pAdapter->hdd_stats.summary_stat.retry_cnt[3]; + + sinfo->tx_failed = + pAdapter->hdd_stats.summary_stat.fail_cnt[0] + + pAdapter->hdd_stats.summary_stat.fail_cnt[1] + + pAdapter->hdd_stats.summary_stat.fail_cnt[2] + + pAdapter->hdd_stats.summary_stat.fail_cnt[3]; + + sinfo->filled |= + STATION_INFO_TX_PACKETS | + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED; + + sinfo->rx_bytes = pAdapter->stats.rx_bytes; + sinfo->filled |= STATION_INFO_RX_BYTES; + + sinfo->rx_packets = pAdapter->stats.rx_packets; + sinfo->filled |= STATION_INFO_RX_PACKETS; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_GET_STA, + pAdapter->sessionId, maxRate)); + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *dev, + u8* mac, struct station_info *sinfo) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, bool mode, int timeout) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT, + pAdapter->sessionId, timeout)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + if ((DRIVER_POWER_MODE_AUTO == !mode) && + (TRUE == pHddCtx->hdd_wlan_suspended) && + (pHddCtx->cfg_ini->fhostArpOffload) && + (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: in cfg80211_set_power_mgmt, calling arp offload"); + vos_status = hdd_conf_arp_offload(pAdapter, TRUE); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s:Failed to enable ARPOFFLOAD Feature %d", + __func__, vos_status); + } + } + + /**The get power cmd from the supplicant gets updated by the nl only + *on successful execution of the function call + *we are oppositely mapped w.r.t mode in the driver + **/ + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + vos_status = wlan_hdd_enter_bmps(pAdapter, !mode); + else + vos_status = wlan_hdd_set_powersave(pAdapter, !mode); + + if (!mode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: DHCP start indicated through power save", __func__); + sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode, + pAdapter->macAddressCurrent.bytes, pAdapter->sessionId); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: DHCP stop indicated through power save", __func__); + sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode, + pAdapter->macAddressCurrent.bytes, pAdapter->sessionId); + } + + EXIT(); + if (VOS_STATUS_E_FAILURE == vos_status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to enter bmps mode", __func__); + return -EINVAL; + } + return 0; +} + + +static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, bool mode, int timeout) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index) +{ + ENTER(); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +static int wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_txq_params *params) +{ + ENTER(); + return 0; +} +#else +static int wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct ieee80211_txq_params *params) +{ + ENTER(); + return 0; +} +#endif //LINUX_VERSION_CODE + +static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + v_U8_t staId; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DEL_STA, + pAdapter->sessionId, pAdapter->device_mode)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode)) { + if ((NULL == mac) || (vos_is_macaddr_broadcast((v_MACADDR_t *)mac))) { + v_U16_t i; + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + if ((pAdapter->aStaInfo[i].isUsed) && + (!pAdapter->aStaInfo[i].isDeauthInProgress)) { + u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes; +#ifdef IPA_UC_OFFLOAD + if (pHddCtx->cfg_ini->IpaUcOffloadEnabled) { + hdd_ipa_wlan_evt(pAdapter, pAdapter->aStaInfo[i].ucSTAId, + WLAN_CLIENT_DISCONNECT, macAddr); + } +#endif /* IPA_UC_OFFLOAD */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Delete STA with MAC::"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(macAddr)); + + /* Send disassoc and deauth both to avoid some IOT issues */ + hdd_softap_sta_disassoc(pAdapter, macAddr); + vos_status = hdd_softap_sta_deauth(pAdapter, macAddr); + if (VOS_IS_STATUS_SUCCESS(vos_status)) + pAdapter->aStaInfo[i].isDeauthInProgress = TRUE; + } + } + } else { + vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Skip DEL STA as this is not used::"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac)); + return -ENOENT; + } + +#ifdef IPA_UC_OFFLOAD + if (pHddCtx->cfg_ini->IpaUcOffloadEnabled) { + hdd_ipa_wlan_evt(pAdapter, staId, + WLAN_CLIENT_DISCONNECT, mac); + } +#endif /* IPA_UC_OFFLOAD */ + + if (pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Skip DEL STA as deauth is in progress::" + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(mac)); + return -ENOENT; + } + + pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE; + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Delete STA with MAC::"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac)); + + /* Send disassoc and deauth both to avoid some IOT issues */ + hdd_softap_sta_disassoc(pAdapter, mac); + vos_status = hdd_softap_sta_deauth(pAdapter, mac); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE; + hddLog(VOS_TRACE_LEVEL_INFO, + FL("STA removal failed for ::"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac)); + return -ENOENT; + } + } + } + + EXIT(); + return 0; +} + +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac, struct station_parameters *params) +{ + int status = -EPERM; +#ifdef FEATURE_WLAN_TDLS + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + u32 mask, set; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_STA, + pAdapter->sessionId, params->listen_interval)); + + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return -EINVAL; + } + + mask = params->sta_flags_mask; + + set = params->sta_flags_set; + +#ifdef WLAN_FEATURE_TDLS_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR, + __func__, mask, set, MAC_ADDR_ARRAY(mac)); +#endif + + if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL); + } + } +#endif + return status; +} + +static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac, struct station_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef FEATURE_WLAN_LFR +static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle halHandle; + eHalStatus result = eHAL_STATUS_SUCCESS; + int status; + tPmkidCacheInfo pmk_id; + + if (!pmksa) { + hddLog(LOGE, FL("pmksa is NULL")); + return -EINVAL; + } + + if (!pmksa->bssid || !pmksa->pmkid) { + hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"), + pmksa->bssid, pmksa->pmkid); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("set PMKSA for "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pmksa->bssid)); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN); + vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE); + + /* Add to the PMKSA ID Cache in CSR */ + result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId, + &pmk_id, 1, FALSE); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_PMKSA, + pAdapter->sessionId, result)); + + return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL; +} + +static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle halHandle; + int status = 0; + + if (!pmksa) { + hddLog(LOGE, FL("pmksa is NULL")); + return -EINVAL; + } + + if (!pmksa->bssid) { + hddLog(LOGE, FL("pmksa->bssid is NULL")); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Deleting PMKSA for "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pmksa->bssid)); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + /* Delete the PMKID CSR cache */ + if (eHAL_STATUS_SUCCESS != + sme_RoamDelPMKIDfromCache(halHandle, + pAdapter->sessionId, pmksa->bssid, FALSE)) { + hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pmksa->bssid)); + status = -EINVAL; + } + + return status; +} + + +static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa); + vos_ssr_unprotect(__func__); + + return ret; + +} + +static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle halHandle; + int status = 0; + + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Flushing PMKSA")); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + /* Retrieve halHandle */ + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + /* Flush the PMKID cache in CSR */ + if (eHAL_STATUS_SUCCESS != + sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache")); + status = -EINVAL; + } + + return status; +} + +static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211) +static int +__wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES, + pAdapter->sessionId, pHddStaCtx->conn_info.connState)); + // Added for debug on reception of Re-assoc Req. + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"), + ftie->ie_len); + hddLog(LOGE, FL("Should be Re-assoc Req IEs")); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__, + ftie->ie_len); +#endif + + // Pass the received FT IEs to SME + sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, + (const u8 *)ftie->ie, + ftie->ie_len); + return 0; +} + +static int +wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +static int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_scaninfo_t *pScanInfo = NULL; + unsigned long rc; + + pScanInfo = &pAdapter->scan_info; + + if (pScanInfo->mScanPending && pAdapter->request) + { + INIT_COMPLETION(pScanInfo->abortscan_event_var); + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + + rc = wait_for_completion_timeout( + &pScanInfo->abortscan_event_var, + msecs_to_jiffies(5000)); + if (!rc) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for abort scan" , + __func__); + return -ETIME; + } + } + return 0; +} +void hdd_cfg80211_sched_scan_done_callback(void *callbackContext, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + int ret; + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + hdd_context_t *pHddCtx; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return ; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is Null!!!", __func__); + return ; + } + + spin_lock(&pHddCtx->schedScan_lock); + if (TRUE == pHddCtx->isWiphySuspended) + { + pHddCtx->isSchedScanUpdatePending = TRUE; + spin_unlock(&pHddCtx->schedScan_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Update cfg80211 scan database after it resume", __func__); + return ; + } + spin_unlock(&pHddCtx->schedScan_lock); + + ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter); + + if (0 > ret) + hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__); + + cfg80211_sched_scan_results(pHddCtx->wiphy); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: cfg80211 scan result database updated", __func__); +} + +/* + * FUNCTION: wlan_hdd_is_pno_allowed + * Disallow pno if any session is active + */ +static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pTempAdapter = NULL; + hdd_station_ctx_t *pStaCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status = 0; + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + /* The current firmware design does not allow PNO during any + * active sessions. Hence, determine the active sessions + * and return a failure. + */ + + while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status)) + { + pTempAdapter = pAdapterNode->pAdapter; + pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter); + + if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode) + && (eConnectionState_NotConnected != pStaCtx->conn_info.connState)) + || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode) + || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode) + || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode) + ) + { + return eHAL_STATUS_FAILURE; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return eHAL_STATUS_SUCCESS; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start + * Function to enable PNO + */ +static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_sched_scan_request *request) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpSirPNOScanReq pPnoRequest = NULL; + hdd_context_t *pHddCtx; + tHalHandle hHal; + v_U32_t i, indx, num_ch, tempInterval, j; + u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN; + eHalStatus status = eHAL_STATUS_FAILURE; + int ret = 0; + hdd_scaninfo_t *pScanInfo = &pAdapter->scan_info; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + + if (0 != ret) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HAL context is Null!!!", __func__); + return -EINVAL; + } + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + (eConnectionState_Connecting == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %p(%d) Connection in progress: sched_scan_start denied (EBUSY)", __func__, \ + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId); + return -EBUSY; + } + + /* + * The current umac is unable to handle the SCAN_PREEMPT and SCAN_DEQUEUED + * so its necessary to terminate the existing scan which is already issued + * otherwise the host won't enter into the suspend state due to the reason + * that the wlan wakelock which was held in the wlan_hdd_cfg80211_scan + * function. + */ + if (TRUE == pScanInfo->mScanPending) + { + ret = wlan_hdd_scan_abort(pAdapter); + if(ret < 0){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: aborting the existing scan is unsuccessful", __func__); + return -EBUSY; + } + } + + if (eHAL_STATUS_FAILURE == wlan_hdd_is_pno_allowed(pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: pno is not allowed", __func__); + return -ENOTSUPP; + } + + pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq)); + if (NULL == pPnoRequest) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_malloc failed", __func__); + return -ENOMEM; + } + + memset(pPnoRequest, 0, sizeof (tSirPNOScanReq)); + pPnoRequest->enable = 1; /*Enable PNO */ + pPnoRequest->ucNetworksCount = request->n_match_sets; + + if (( !pPnoRequest->ucNetworksCount ) || + ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS )) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Network input is not correct %d", + __func__, pPnoRequest->ucNetworksCount); + ret = -EINVAL; + goto error; + } + + if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Incorrect number of channels %d", + __func__, request->n_channels); + ret = -EINVAL; + goto error; + } + + /* Framework provides one set of channels(all) + * common for all saved profile */ + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + channels_allowed, &num_channels_allowed)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to get valid channel list", __func__); + ret = -EINVAL; + goto error; + } + /* Checking each channel against allowed channel list */ + num_ch = 0; + if (request->n_channels) + { + char chList [(request->n_channels*5)+1]; + int len; + for (i = 0, len = 0; i < request->n_channels; i++) + { + for (indx = 0; indx < num_channels_allowed; indx++) + { + if (request->channels[i]->hw_value == channels_allowed[indx]) + { + valid_ch[num_ch++] = request->channels[i]->hw_value; + len += snprintf(chList+len, 5, "%d ", + request->channels[i]->hw_value); + break ; + } + } + } + hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList); + } + /* Filling per profile params */ + for (i = 0; i < pPnoRequest->ucNetworksCount; i++) + { + pPnoRequest->aNetworks[i].ssId.length = + request->match_sets[i].ssid.ssid_len; + + if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) || + ( pPnoRequest->aNetworks[i].ssId.length > 32 ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SSID Len %d is not correct for network %d", + __func__, pPnoRequest->aNetworks[i].ssId.length, i); + ret = -EINVAL; + goto error; + } + + memcpy(pPnoRequest->aNetworks[i].ssId.ssId, + request->match_sets[i].ssid.ssid, + request->match_sets[i].ssid.ssid_len); + pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/ + pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/ + pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/ + + /*Copying list of valid channel into request */ + memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch); + pPnoRequest->aNetworks[i].ucChannelCount = num_ch; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + pPnoRequest->aNetworks[i].rssiThreshold = + request->match_sets[i].rssi_thold; +#else + pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value +#endif + } + + for (i = 0; i < request->n_ssids; i++) { + j = 0; + while (j < pPnoRequest->ucNetworksCount) { + if ((pPnoRequest->aNetworks[j].ssId.length == + request->ssids[i].ssid_len) && + (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId, + request->ssids[i].ssid, + pPnoRequest->aNetworks[j].ssId.length))) { + pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN; + break; + } + j++; + } + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Number of hidden networks being Configured = %d", + request->n_ssids); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "request->ie_len = %zu", request->ie_len); + if ((0 < request->ie_len) && (NULL != request->ie)) + { + pPnoRequest->us24GProbeTemplateLen = request->ie_len; + memcpy(&pPnoRequest->p24GProbeTemplate, request->ie, + pPnoRequest->us24GProbeTemplateLen); + + pPnoRequest->us5GProbeTemplateLen = request->ie_len; + memcpy(&pPnoRequest->p5GProbeTemplate, request->ie, + pPnoRequest->us5GProbeTemplateLen); + } + + /* Driver gets only one time interval which is hard coded in + * supplicant for 10000ms. Taking power consumption into account 6 timers + * will be used, Timer value is increased exponentially i.e 10,20,40, + * 80,160,320 secs. And number of scan cycle for each timer + * is configurable through INI param gPNOScanTimerRepeatValue. + * If it is set to 0 only one timer will be used and PNO scan cycle + * will be repeated after each interval specified by supplicant + * till PNO is disabled. + */ + if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue) + pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE; + else + pPnoRequest->scanTimers.ucScanTimersCount = + HDD_PNO_SCAN_TIMERS_SET_MULTIPLE; + + tempInterval = (request->interval)/1000; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Base scan interval = %d PNOScanTimerRepeatValue = %d", + tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue); + for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++) + { + pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat = + pHddCtx->cfg_ini->configPNOScanTimerRepeatValue; + pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval; + tempInterval *= 2; + } + //Repeat last timer until pno disabled. + pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0; + + pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d", + pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO, + pPnoRequest->scanTimers.ucScanTimersCount); + + status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), + pPnoRequest, pAdapter->sessionId, + hdd_cfg80211_sched_scan_done_callback, pAdapter); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to enable PNO", __func__); + ret = -EINVAL; + goto error; + } + + pScanInfo->mPnoScanPending = TRUE; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO scanRequest offloaded"); + +error: + vos_mem_free(pPnoRequest); + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_sched_scan_start + * NL interface to enable PNO + */ +static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_sched_scan_request *request) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop + * Function to disable PNO + */ +static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, + struct net_device *dev) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + tHalHandle hHal; + tpSirPNOScanReq pPnoRequest = NULL; + int ret = 0; + hdd_scaninfo_t *pScanInfo = &pAdapter->scan_info; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is Null", __func__); + return -ENODEV; + } + + /* The return 0 is intentional when isLogpInProgress and + * isLoadUnloadInProgress. We did observe a crash due to a return of + * failure in sched_scan_stop , especially for a case where the unload + * of the happens at the same time. The function __cfg80211_stop_sched_scan + * was clearing rdev->sched_scan_req only when the sched_scan_stop returns + * success. If it returns a failure , then its next invocation due to the + * clean up of the second interface will have the dev pointer corresponding + * to the first one leading to a crash. + */ + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + return ret; + } + + if ((pHddCtx->isLoadInProgress) || + (pHddCtx->isUnloadInProgress)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HAL context is Null!!!", __func__); + return -EINVAL; + } + + pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq)); + if (NULL == pPnoRequest) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_malloc failed", __func__); + return -ENOMEM; + } + + memset(pPnoRequest, 0, sizeof (tSirPNOScanReq)); + pPnoRequest->enable = 0; /* Disable PNO */ + pPnoRequest->ucNetworksCount = 0; + + + status = sme_SetPreferredNetworkList(hHal, pPnoRequest, + pAdapter->sessionId, + NULL, pAdapter); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to disabled PNO"); + ret = -EINVAL; + } + + /* Allow normal scan to continue */ + pScanInfo->mPnoScanPending = FALSE; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: PNO scan disabled", __func__); + + vos_mem_free(pPnoRequest); + + EXIT(); + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop + * NL interface to disable PNO + */ +static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /*FEATURE_WLAN_SCAN_PNO*/ + + +#ifdef FEATURE_WLAN_TDLS +#if TDLS_MGMT_VERSION2 +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, const u8 *buf, size_t len) +#else +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, const u8 *buf, size_t len) +#endif +{ + + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + u8 peerMac[VOS_MAC_ADDR_SIZE]; + VOS_STATUS status; + int max_sta_failed = 0; + int responder; + unsigned long rc; + tANI_U16 numCurrTdlsPeers; +#if !(TDLS_MGMT_VERSION2) + u32 peer_capability; + peer_capability = 0; +#endif + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_TDLS_MGMT, + pAdapter->sessionId, action_code)); + + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return -EINVAL; + } + + if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: TDLS mode is disabled OR not enabled in FW." + MAC_ADDRESS_STR " action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -ENOTSUPP; + } + /* If any concurrency is detected */ + if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) || + (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Multiple STA OR Concurrency detected. Ignore TDLS MGMT frame. action_code=%d, concurrency_mode: 0x%x, active_sessions: %d"), + action_code, + pHddCtx->concurrency_mode, + pHddCtx->no_of_active_sessions[VOS_STA_MODE]); + return -EPERM; + } + /* other than teardown frame, mgmt frames are not sent if disabled */ + if (SIR_MAC_TDLS_TEARDOWN != action_code) + { + /* if tdls_mode is disabled to respond to peer's request */ + if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR + " TDLS mode is disabled. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + + return -ENOTSUPP; + } + } + if (WLAN_IS_TDLS_SETUP_ACTION(action_code)) + { + if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS setup is ongoing. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -EPERM; + } + } + + if (SIR_MAC_TDLS_SETUP_REQ == action_code || + SIR_MAC_TDLS_SETUP_RSP == action_code ) + { + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (pHddCtx->max_num_tdls_sta <= numCurrTdlsPeers) + { + /* supplicant still sends tdls_mgmt(SETUP_REQ) even after + we return error code at 'add_station()'. Hence we have this + check again in addition to add_station(). + Anyway, there is no hard to double-check. */ + if (SIR_MAC_TDLS_SETUP_REQ == action_code) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(peer), action_code, + numCurrTdlsPeers, pHddCtx->max_num_tdls_sta); + return -EINVAL; + } + else + { + /* maximum reached. tweak to send error code to peer and return + error code to supplicant */ + status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(peer), status_code, + numCurrTdlsPeers, pHddCtx->max_num_tdls_sta); + max_sta_failed = -EPERM; + /* fall through to send setup resp with failure status + code */ + } + } + else + { + hddTdlsPeer_t *pTdlsPeer; + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE); + if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:" MAC_ADDRESS_STR " already connected. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -EPERM; + } + } + } + vos_mem_copy(peerMac, peer, 6); + +#ifdef WLAN_FEATURE_TDLS_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + "tdls_mgmt", MAC_ADDR_ARRAY(peer), + action_code, dialog_token, status_code, len); +#endif + + /*Except teardown responder will not be used so just make 0*/ + responder = 0; + if (SIR_MAC_TDLS_TEARDOWN == action_code) + { + + hddTdlsPeer_t *pTdlsPeer; + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE); + + if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + responder = pTdlsPeer->is_responder; + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu", + __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status, + dialog_token, status_code, len); + return -EPERM; + } + } + + /* For explicit trigger of DIS_REQ come out of BMPS for + successfully receiving DIS_RSP from peer. */ + if ((SIR_MAC_TDLS_SETUP_RSP == action_code) || + (SIR_MAC_TDLS_DIS_RSP == action_code) || + (SIR_MAC_TDLS_DIS_REQ == action_code)) + { + /* Fw will take care if PS offload is enabled. */ + if (!pHddCtx->cfg_ini->enablePowersaveOffload) + { + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Sending frame action_code %u.Disable BMPS", + __func__, action_code); + hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + } + } + if (SIR_MAC_TDLS_DIS_REQ != action_code) + wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED); + } + + /* make sure doesn't call send_mgmt() while it is pending */ + if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -EBUSY; + } + + pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC; + INIT_COMPLETION(pAdapter->tdls_mgmt_comp); + + status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peerMac, action_code, + dialog_token, status_code, peer_capability, + (tANI_U8 *)buf, len, !responder); + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SendTdlsMgmtFrame failed!", __func__); + pAdapter->mgmtTxCompletionStatus = FALSE; + + wlan_hdd_tdls_check_bmps(pAdapter); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&pAdapter->tdls_mgmt_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_MGMT)); + + if ((0 == rc) || (TRUE != pAdapter->mgmtTxCompletionStatus)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Mgmt Tx Completion timed out TxCompletion %u", + __func__, pAdapter->mgmtTxCompletionStatus); + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + + if (pHddCtx->isUnloadInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + + pAdapter->mgmtTxCompletionStatus = FALSE; + wlan_hdd_tdls_check_bmps(pAdapter); + return -EINVAL; + } + + if (max_sta_failed) + { + wlan_hdd_tdls_check_bmps(pAdapter); + return max_sta_failed; + } + + if (SIR_MAC_TDLS_SETUP_RSP == action_code) + { + return wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE); + } + else if (SIR_MAC_TDLS_SETUP_CNF == action_code) + { + return wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE); + } + + return 0; +} + + +int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, + u8 *peer, + cfg80211_exttdls_callback callback, + u32 chan, + u32 max_latency, + u32 op_class, + u32 min_bandwidth) +{ + hddTdlsPeer_t *pTdlsPeer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) || + (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s TDLS External control or Implicit Trigger not enabled ", + __func__); + return -ENOTSUPP; + } + + /* To cater the requirement of establishing the TDLS link + * irrespective of the data traffic , get an entry of TDLS peer. + */ + pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer); + if (pTdlsPeer == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: peer " MAC_ADDRESS_STR " does not exist", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + + if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s TDLS Add Force Peer Failed", + __func__); + return -EINVAL; + } + + if ( 0 != wlan_hdd_tdls_set_extctrl_param(pAdapter, peer, + chan, max_latency, + op_class, min_bandwidth) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s TDLS Set Peer's External Ctrl Parameter Failed", + __func__); + return -EINVAL; + } + + if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s TDLS set callback Failed", + __func__); + return -EINVAL; + } + + return(0); +} + +int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer) +{ + hddTdlsPeer_t *pTdlsPeer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) || + (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s TDLS External control or Implicit Trigger not enabled ", + __func__); + return -ENOTSUPP; + } + + + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE); + + if ( NULL == pTdlsPeer ) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR + "peer matching MAC_ADDRESS_STR not found", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + else { + wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + } + + if (0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Failed", + __func__); + return -EINVAL; + } + /* EXT TDLS */ + if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s TDLS set callback Failed", + __func__); + return -EINVAL; + } + return(0); +} +static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, + enum nl80211_tdls_operation oper) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + int status; + tSmeTdlsPeerStateParams smeTdlsPeerStateParams; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + hddTdlsPeer_t *pTdlsPeer; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_TDLS_OPER, + pAdapter->sessionId, oper)); + if ( NULL == peer ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid arguments", __func__); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + + /* QCA 2.0 Discrete ANDs feature capability in cfg_ini with that + * received from target, so cfg_ini gives combined intersected result + */ + if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "TDLS Disabled in INI OR not enabled in FW. " + "Cannot process TDLS commands"); + return -ENOTSUPP; + } + + switch (oper) { + case NL80211_TDLS_ENABLE_LINK: + { + VOS_STATUS status; + unsigned long rc; + tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams; + + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE); + + if (NULL == pTdlsPeer) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: peer matching "MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_ENABLE_LINK", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NL80211_TDLS_ENABLE_LINK for peer " + MAC_ADDRESS_STR" link_status: %d", + __func__, MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status); + + if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid sta index %u for " + MAC_ADDRESS_STR" TDLS_ENABLE_LINK failed", + __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + + if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status) + { + if (IS_ADVANCE_TDLS_ENABLE) { + + if (0 != wlan_hdd_tdls_get_link_establish_params( + pAdapter, peer,&tdlsLinkEstablishParams)) { + return -EINVAL; + } + INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp); + + sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peer, &tdlsLinkEstablishParams); + /* Send TDLS peer UAPSD capabilities to the firmware and + * register with the TL on after the response for this operation + * is received . + */ + rc = wait_for_completion_timeout( + &pAdapter->tdls_link_establish_req_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ)); + if (!rc) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Link Establish Request timed out", __func__); + return -EINVAL; + } + } + wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, + eTDLS_LINK_CONNECTED, + eTDLS_LINK_SUCCESS); + /* start TDLS client registration with TL */ + status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature); + if (VOS_STATUS_SUCCESS == status) + { + tANI_U8 i; + + vos_mem_zero(&smeTdlsPeerStateParams, + sizeof(tSmeTdlsPeerStateParams)); + + smeTdlsPeerStateParams.vdevId = pAdapter->sessionId; + vos_mem_copy(&smeTdlsPeerStateParams.peerMacAddr, + &pTdlsPeer->peerMac, + sizeof(tSirMacAddr)); + smeTdlsPeerStateParams.peerState = + eSME_TDLS_PEER_STATE_CONNECTED; + smeTdlsPeerStateParams.peerCap.isPeerResponder = + pTdlsPeer->is_responder; + smeTdlsPeerStateParams.peerCap.peerUapsdQueue = + pTdlsPeer->uapsdQueues; + smeTdlsPeerStateParams.peerCap.peerMaxSp = + pTdlsPeer->maxSp; + smeTdlsPeerStateParams.peerCap.peerBuffStaSupport = + pTdlsPeer->isBufSta; + smeTdlsPeerStateParams.peerCap.peerOffChanSupport = + pTdlsPeer->isOffChannelSupported; + smeTdlsPeerStateParams.peerCap.peerCurrOperClass = 0; + smeTdlsPeerStateParams.peerCap.selfCurrOperClass = 0; + smeTdlsPeerStateParams.peerCap.peerChanLen = + pTdlsPeer->supported_channels_len; + smeTdlsPeerStateParams.peerCap.prefOffChanNum = + pTdlsPeer->pref_off_chan_num; + smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth = + pHddCtx->cfg_ini->fTDLSPrefOffChanBandwidth; + if (pTdlsPeer->op_class_for_pref_off_chan_is_set) { + smeTdlsPeerStateParams.peerCap.opClassForPrefOffChanIsSet = + pTdlsPeer->op_class_for_pref_off_chan_is_set; + smeTdlsPeerStateParams.peerCap.opClassForPrefOffChan = + pTdlsPeer->op_class_for_pref_off_chan; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Peer " MAC_ADDRESS_STR "vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d, prefOffChanNum: %d, prefOffChanBandwidth: %d, op_class_for_pref_off_chan_is_set: %d, op_class_for_pref_off_chan: %d", + __func__, MAC_ADDR_ARRAY(peer), + smeTdlsPeerStateParams.vdevId, + smeTdlsPeerStateParams.peerState, + smeTdlsPeerStateParams.peerCap.isPeerResponder, + smeTdlsPeerStateParams.peerCap.peerUapsdQueue, + smeTdlsPeerStateParams.peerCap.peerMaxSp, + smeTdlsPeerStateParams.peerCap.peerBuffStaSupport, + smeTdlsPeerStateParams.peerCap.peerOffChanSupport, + smeTdlsPeerStateParams.peerCap.peerCurrOperClass, + smeTdlsPeerStateParams.peerCap.selfCurrOperClass, + smeTdlsPeerStateParams.peerCap.peerChanLen, + smeTdlsPeerStateParams.peerCap.peerOperClassLen, + smeTdlsPeerStateParams.peerCap.prefOffChanNum, + smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth, + pTdlsPeer->op_class_for_pref_off_chan_is_set, + pTdlsPeer->op_class_for_pref_off_chan); + + for (i = 0; i < pTdlsPeer->supported_channels_len; i++) + { + smeTdlsPeerStateParams.peerCap.peerChan[i] = + pTdlsPeer->supported_channels[i]; + } + smeTdlsPeerStateParams.peerCap.peerOperClassLen = + pTdlsPeer->supported_oper_classes_len; + for (i = 0; i < pTdlsPeer->supported_oper_classes_len; i++) + { + smeTdlsPeerStateParams.peerCap.peerOperClass[i] = + pTdlsPeer->supported_oper_classes[i]; + } + + halStatus = sme_UpdateTdlsPeerState(pHddCtx->hHal, + &smeTdlsPeerStateParams); + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_UpdateTdlsPeerState failed for " + MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + return -EPERM; + } + wlan_hdd_tdls_increment_peer_count(pAdapter); + } + wlan_hdd_tdls_check_bmps(pAdapter); + + /* Update TL about the UAPSD masks , to route the packets to firmware */ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta) + || pHddCtx->cfg_ini->fTDLSUapsdMask ) + { + int ac; + uint8 ucAc[4] = { WLANTL_AC_VO, + WLANTL_AC_VI, + WLANTL_AC_BK, + WLANTL_AC_BE }; + uint8 tlTid[4] = { 7, 5, 2, 3 } ; + for(ac=0; ac < 4; ac++) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pTdlsPeer->staId, ucAc[ac], + tlTid[ac], tlTid[ac], 0, 0, + WLANTL_BI_DIR, + 1, + pAdapter->sessionId ); + } + } + } + + } + break; + case NL80211_TDLS_DISABLE_LINK: + { + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE); + + if ( NULL == pTdlsPeer ) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: peer matching "MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_DISABLE_LINK", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NL80211_TDLS_DISABLE_LINK for peer " + MAC_ADDRESS_STR " link_status: %d", + __func__, MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status); + + if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) + { + unsigned long rc; + + INIT_COMPLETION(pAdapter->tdls_del_station_comp); + + sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peer ); + + rc = wait_for_completion_timeout(&pAdapter->tdls_del_station_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA)); + if (!rc) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Del station timed out", __func__); + return -EPERM; + } + wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS Peer Station doesn't exist.", __func__); + } + } + break; + case NL80211_TDLS_TEARDOWN: + { + status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Error in TDLS Teardown", __func__); + return status; + } + } + break; + case NL80211_TDLS_SETUP: + { + status = wlan_hdd_tdls_extctrl_config_peer(pAdapter, peer, + NULL, pHddCtx->cfg_ini->fTDLSPrefOffChanNum, + 0, 0, 0); + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Error in TDLS Setup", __func__); + return status; + } + } + break; + case NL80211_TDLS_DISCOVERY_REQ: + /* We don't support in-driver setup/teardown/discovery */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: We don't support in-driver setup/teardown/discovery", + __func__); + return -ENOTSUPP; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: unsupported event", __func__); + return -ENOTSUPP; + } + return 0; +} + +static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, + enum nl80211_tdls_operation oper) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper); + vos_ssr_unprotect(__func__); + + return ret; +} + +int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy, + struct net_device *dev, u8 *peer) +{ + hddLog(VOS_TRACE_LEVEL_INFO, + "tdls send discover req: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(peer)); +#if TDLS_MGMT_VERSION2 + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0); +#else + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0); +#endif +} +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* + * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback + * Callback routine called upon receiving response for + * get offload info + */ +void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) +{ + + hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext; + tANI_U8 tempReplayCounter[8]; + hdd_station_ctx_t *pHddStaCtx; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return ; + } + + if (NULL == pGtkOffloadGetInfoRsp) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pGtkOffloadGetInfoRsp is Null", __func__); + return ; + } + + if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wlan Failed to get replay counter value", + __func__); + return ; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + /* Update replay counter */ + pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter = + pGtkOffloadGetInfoRsp->ullKeyReplayCounter; + + { + /* changing from little to big endian since supplicant + * works on big endian format + */ + int i; + tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter; + + for (i = 0; i < 8; i++) + { + tempReplayCounter[7-i] = (tANI_U8)p[i]; + } + } + + /* Update replay counter to NL */ + cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId, + tempReplayCounter, GFP_KERNEL); +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data + * This function is used to offload GTK rekeying job to the firmware. + */ +int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_station_ctx_t *pHddStaCtx; + tHalHandle hHal; + int result; + tSirGtkOffloadParams hddGtkOffloadReqParams; + eHalStatus status = eHAL_STATUS_FAILURE; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA, + pAdapter->sessionId, pAdapter->device_mode)); + + result = wlan_hdd_validate_context(pHddCtx); + + if (0 != result) { + hddLog(LOGE, FL("HDD context is not valid")); + return result; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal){ + hddLog(LOGE, FL("HAL context is Null!!!")); + return -EAGAIN; + } + + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE; + memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN); + memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN); + memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId, + VOS_MAC_ADDR_SIZE); + { + /* changing from big to little endian since driver + * works on little endian format + */ + tANI_U8 *p = + (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter; + int i; + + for (i = 0; i < 8; i++) { + p[7-i] = data->replay_ctr[i]; + } + } + + if (TRUE == pHddCtx->hdd_wlan_suspended) { + /* if wlan is suspended, enable GTK offload directly from here */ + memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams, + pAdapter->sessionId); + + if (eHAL_STATUS_SUCCESS != status) { + hddLog(LOGE, FL("sme_SetGTKOffload failed, status(%d)"), status); + return -EINVAL; + } + hddLog(LOG1, FL("sme_SetGTKOffload successful")); + } else { + hddLog(LOG1, FL("wlan not suspended GTKOffload request is stored")); + } + + return result; +} + +int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /*WLAN_FEATURE_GTK_OFFLOAD*/ +/* + * FUNCTION: wlan_hdd_cfg80211_set_mac_acl + * This function is used to set access control policy + */ +static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, + struct net_device *dev, const struct cfg80211_acl_data *params) +{ + int i; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_hostapd_state_t *pHostapdState; + tsap_Config_t *pConfig; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx; + int status; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + ENTER(); + + if (NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: params is Null", __func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + pVosContext = pHddCtx->pvosContext; + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + if (NULL == pHostapdState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: pHostapdState is Null", __func__); + return -EINVAL; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d" + "no acl entries = %d", params->acl_policy, params->n_acl_entries); + + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) + { + pConfig = &pAdapter->sessionCtx.ap.sapConfig; + + /* default value */ + pConfig->num_accept_mac = 0; + pConfig->num_deny_mac = 0; + + /** + * access control policy + * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are + * listed in hostapd.deny file. + * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are + * listed in hostapd.accept file. + */ + if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy) + { + pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED; + } + else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy) + { + pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Acl Policy : %d is not supported", + __func__, params->acl_policy); + return -ENOTSUPP; + } + + if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl) + { + pConfig->num_accept_mac = params->n_acl_entries; + for (i = 0; i < params->n_acl_entries; i++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "** Add ACL MAC entry %i in WhiletList :" + MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(params->mac_addrs[i].addr)); + + vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr, + sizeof(qcmacaddr)); + } + } + else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl) + { + pConfig->num_deny_mac = params->n_acl_entries; + for (i = 0; i < params->n_acl_entries; i++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "** Add ACL MAC entry %i in BlackList :" + MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(params->mac_addrs[i].addr)); + + vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr, + sizeof(qcmacaddr)); + } + } + +#ifdef WLAN_FEATURE_MBSSID + vos_status = WLANSAP_SetMacACL(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), pConfig); +#else + vos_status = WLANSAP_SetMacACL(pVosContext, pConfig); +#endif + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SAP Set Mac Acl fail", __func__); + return -EINVAL; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid device_mode = %d", + __func__, pAdapter->device_mode); + return -EINVAL; + } + + return 0; +} + +#ifdef WLAN_NL80211_TESTMODE +#ifdef FEATURE_WLAN_LPHB +void wlan_hdd_cfg80211_lphb_ind_handler +( + void *pHddCtx, + tSirLPHBInd *lphbInd +) +{ + struct sk_buff *skb; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB indication arrived"); + + if (0 != wlan_hdd_validate_context((hdd_context_t *)pHddCtx)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid argument pHddCtx", __func__); + return; + } + + if (NULL == lphbInd) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid argument lphbInd", __func__); + return; + } + + skb = cfg80211_testmode_alloc_event_skb( + ((hdd_context_t *)pHddCtx)->wiphy, + sizeof(tSirLPHBInd), + GFP_ATOMIC); + if (!skb) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB timeout, NL buffer alloc fail"); + return; + } + + if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_CMD put fail"); + goto nla_put_failure; + } + if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_TYPE put fail"); + goto nla_put_failure; + } + if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA, + sizeof(tSirLPHBInd), lphbInd)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_DATA put fail"); + goto nla_put_failure; + } + cfg80211_testmode_event(skb, GFP_ATOMIC); + return; + +nla_put_failure: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLA Put fail"); + kfree_skb(skb); + + return; +} +#endif /* FEATURE_WLAN_LPHB */ + +static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, + void *data, int len) +{ + struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1]; + int err = 0; +#ifdef FEATURE_WLAN_LPHB + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + eHalStatus smeStatus; +#endif /* FEATURE_WLAN_LPHB */ + + err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy); + if (err) { + hddLog(LOGE, FL("Testmode INV ATTR")); + return err; + } + + if (!tb[WLAN_HDD_TM_ATTR_CMD]) { + hddLog(LOGE, FL("Testmode INV CMD")); + return -EINVAL; + } + + switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])) + { +#ifdef FEATURE_WLAN_LPHB + /* Low Power Heartbeat configuration request */ + case WLAN_HDD_TM_CMD_WLAN_HB: + { + int buf_len; + void *buf; + tSirLPHBReq *hb_params = NULL; + tSirLPHBReq *hb_params_temp = NULL; + + if (!tb[WLAN_HDD_TM_ATTR_DATA]) { + hddLog(LOGE, FL("Testmode INV DATA")); + return -EINVAL; + } + + buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]); + buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]); + + hb_params_temp =(tSirLPHBReq *)buf; + if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) && + (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0)) + return -EINVAL; + + hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq)); + if (NULL == hb_params) { + hddLog(LOGE, FL("Request Buffer Alloc Fail")); + return -ENOMEM; + } + + vos_mem_copy(hb_params, buf, buf_len); + smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal), + hb_params, + wlan_hdd_cfg80211_lphb_ind_handler); + if (eHAL_STATUS_SUCCESS != smeStatus) { + hddLog(LOGE, "LPHB Config Fail, disable"); + vos_mem_free(hb_params); + } + return 0; + } +#endif /* FEATURE_WLAN_LPHB */ + +#if defined(QCA_WIFI_FTM) + case WLAN_HDD_TM_CMD_WLAN_FTM: + { + int buf_len; + void *buf; + VOS_STATUS status; + if (!tb[WLAN_HDD_TM_ATTR_DATA]) { + hddLog(LOGE, + FL("WLAN_HDD_TM_ATTR_DATA attribute is invalid")); + return -EINVAL; + } + + buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]); + buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]); + + status = wlan_hdd_ftm_testmode_cmd(buf, buf_len); + + if (status != VOS_STATUS_SUCCESS) + err = -EBUSY; + break; + } +#endif + + default: + hddLog(LOGE, FL("command %d not supported"), + nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])); + return -EOPNOTSUPP; + } + + return err; +} + +static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len); + vos_ssr_unprotect(__func__); + + return ret; +} + +#if defined(QCA_WIFI_FTM) +void wlan_hdd_testmode_rx_event(void *buf, size_t buf_len) +{ + struct sk_buff *skb; + hdd_context_t *hdd_ctx; + void *vos_global_ctx; + + if (!buf || !buf_len) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: buf or buf_len invalid, buf = %p buf_len = %zu", + __func__, buf, buf_len); + return; + } + + vos_global_ctx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + + if (!vos_global_ctx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: voss global context invalid", + __func__); + return; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_global_ctx); + + if (!hdd_ctx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd context invalid", + __func__); + return; + } + + skb = cfg80211_testmode_alloc_event_skb(hdd_ctx->wiphy, + buf_len, GFP_KERNEL); + if (!skb) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to allocate testmode rx skb!", + __func__); + return; + } + + if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_FTM) || + nla_put(skb, WLAN_HDD_TM_ATTR_DATA, buf_len, buf)) + goto nla_put_failure; + + cfg80211_testmode_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: nla_put failed on testmode rx skb!", + __func__); +} +#endif +#endif /* CONFIG_NL80211_TESTMODE */ + +static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, + struct net_device *dev, + int idx, struct survey_info *survey) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + tHalHandle halHandle; + v_U32_t channel = 0, freq = 0; /* Initialization Required */ + v_S7_t snr,rssi; + int status, i, j, filled = 0; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring || + 0 != pAdapter->survey_idx || + eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + /* The survey dump ops when implemented completely is expected to + * return a survey of all channels and the ops is called by the + * kernel with incremental values of the argument 'idx' till it + * returns -ENONET. But we can only support the survey for the + * operating channel for now. survey_idx is used to track + * that the ops is called only once and then return -ENONET for + * the next iteration + */ + pAdapter->survey_idx = 0; + return -ENONET; + } + + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + wlan_hdd_get_snr(pAdapter, &snr); + wlan_hdd_get_rssi(pAdapter, &rssi); + + sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId); + hdd_wlan_get_freq(channel, &freq); + + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + if (NULL == wiphy->bands[i]) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: wiphy->bands[i] is NULL, i = %d", __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + if (band->channels[j].center_freq == (v_U16_t)freq) + { + survey->channel = &band->channels[j]; + /* The Rx BDs contain SNR values in dB for the received frames + * while the supplicant expects noise. So we calculate and + * return the value of noise (dBm) + * SNR (dB) = RSSI (dBm) - NOISE (dBm) + */ + survey->noise = rssi - snr; + survey->filled = SURVEY_INFO_NOISE_DBM; + filled = 1; + } + } + } + + if (filled) + pAdapter->survey_idx = 1; + else + { + pAdapter->survey_idx = 0; + return -ENONET; + } + + return 0; +} + +static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, + struct net_device *dev, + int idx, struct survey_info *survey) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_resume_wlan + * this is called when cfg80211 driver resume + * driver updates latest sched_scan scan result(if any) to cfg80211 database + */ +int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_adapter_t *pAdapter; + hdd_adapter_list_node_t *pAdapterNode, *pNext; + VOS_STATUS status = VOS_STATUS_SUCCESS; + int result; + pVosSchedContext vosSchedContext = get_vos_sched_ctxt(); + + ENTER(); + + result = wlan_hdd_validate_context(pHddCtx); + if (0 != result) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return result; + } + +#ifdef CONFIG_CNSS + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_MEDIUM); +#endif + + /* Resume MC thread */ + if (pHddCtx->isMcThreadSuspended) { + complete(&vosSchedContext->ResumeMcEvent); + pHddCtx->isMcThreadSuspended = FALSE; + } + +#ifdef QCA_CONFIG_SMP + /* Resume tlshim Rx thread */ + if (pHddCtx->isTlshimRxThreadSuspended) { + complete(&vosSchedContext->ResumeTlshimRxEvent); + pHddCtx->isTlshimRxThreadSuspended = FALSE; + } + +#endif + hdd_resume_wlan(); + + spin_lock(&pHddCtx->schedScan_lock); + pHddCtx->isWiphySuspended = FALSE; + if (TRUE != pHddCtx->isSchedScanUpdatePending) { + spin_unlock(&pHddCtx->schedScan_lock); + hddLog(LOG1, FL("Return resume is not due to PNO indication")); + return 0; + } + /* Reset flag to avoid updating cfg80211 data old results again */ + pHddCtx->isSchedScanUpdatePending = FALSE; + spin_unlock(&pHddCtx->schedScan_lock); + + status = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + if ((NULL != pAdapter) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) { + if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter)) { + hddLog(LOGW, FL("NO SCAN result")); + } else { + /* Acquire wakelock to handle the case where APP's tries to + * suspend immediately after updating the scan results. This + * results in app's is in suspended state and not able to + * process the connect request to AP + */ + hdd_prevent_suspend_timeout(2000); + cfg80211_sched_scan_results(pHddCtx->wiphy); + } + + hddLog(LOG1, FL("cfg80211 scan result database updated")); + + return result; + } + status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + hddLog(LOG1, FL("Failed to find Adapter")); + return result; +} + +void wlan_hdd_cfg80211_ready_to_suspend(void *callbackContext, boolean suspended) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)callbackContext; + pHddCtx->suspended = suspended; + complete(&pHddCtx->ready_to_suspend); +} + +int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_resume_wlan(wiphy); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan + * this is called when cfg80211 driver suspends + */ +int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ +#ifdef QCA_CONFIG_SMP +#define RX_TLSHIM_SUSPEND_TIMEOUT 200 /* msecs */ +#endif + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + pVosSchedContext vosSchedContext = get_vos_sched_ctxt(); + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + hdd_scaninfo_t *pScanInfo; + VOS_STATUS status; + int rc; + + ENTER(); + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) { + hddLog(LOGE, FL("HDD context is not valid")); + return rc; + } + + /* If RADAR detection is in progress (HDD), prevent suspend. The flag + * "dfs_cac_block_tx" is set to TRUE when RADAR is found and stay TRUE until + * CAC is done for a SoftAP which is in started state. + */ + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) { + if (BSS_START == + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter)->bssState && + VOS_TRUE == + WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->dfs_cac_block_tx) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("RADAR detection in progress, do not allow suspend")); + return -EAGAIN; + } else if (!pHddCtx->cfg_ini->enableSapSuspend) { + /* return -EOPNOTSUPP if SAP does not support suspend + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:SAP does not support suspend!!", __func__); + return -EOPNOTSUPP; + } + } else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) { + if (!pHddCtx->cfg_ini->enableSapSuspend) { + /* return -EOPNOTSUPP if GO does not support suspend + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:GO does not support suspend!!", __func__); + return -EOPNOTSUPP; + } + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + /* Stop ongoing scan on each interface */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + pScanInfo = &pAdapter->scan_info; + + if (sme_staInMiddleOfRoaming(pHddCtx->hHal, pAdapter->sessionId)) { + hddLog(LOG1, FL("Roaming in progress, do not allow suspend")); + return -EAGAIN; + } + + if (pHddCtx->cfg_ini->enablePowersaveOffload && + pHddCtx->cfg_ini->fIsBmpsEnabled && + ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))) { + if (!sme_PsOffloadIsStaInPowerSave(pHddCtx->hHal, + pAdapter->sessionId)) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("STA is not in power save, Do not allow suspend")); + return -EAGAIN; + } + } + + if (pScanInfo->mScanPending && pAdapter->request) + { + INIT_COMPLETION(pScanInfo->abortscan_event_var); + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + + status = wait_for_completion_timeout( + &pScanInfo->abortscan_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN)); + if (!status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for abort scan" , + __func__); + return -ETIME; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + +#ifdef IPA_OFFLOAD + /* + * Suspend IPA early before proceeding to suspend other entities like + * firmware to avoid any race conditions. + */ + if (hdd_ipa_suspend(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_DEBUG, FL("IPA not ready to suspend!")); + return -EAGAIN; + } +#endif + + /* Wait for the target to be ready for suspend */ + INIT_COMPLETION(pHddCtx->ready_to_suspend); + + hdd_suspend_wlan(&wlan_hdd_cfg80211_ready_to_suspend, pHddCtx); + + rc = wait_for_completion_timeout(&pHddCtx->ready_to_suspend, + msecs_to_jiffies(WLAN_WAIT_TIME_READY_TO_SUSPEND)); + if (!rc) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to get ready to suspend", __func__); + goto resume_tx; + } + + if (!pHddCtx->suspended) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Faied as suspend_status is wrong:%d", + __func__, pHddCtx->suspended); + goto resume_tx; + } + + /* Suspend MC thread */ + set_bit(MC_SUSPEND_EVENT_MASK, &vosSchedContext->mcEventFlag); + wake_up_interruptible(&vosSchedContext->mcWaitQueue); + + /* Wait for suspend confirmation from MC thread */ + rc = wait_for_completion_timeout(&pHddCtx->mc_sus_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_MCTHREAD_SUSPEND)); + if (!rc) + { + clear_bit(MC_SUSPEND_EVENT_MASK, &vosSchedContext->mcEventFlag); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop mc thread", __func__); + goto resume_tx; + } + + pHddCtx->isMcThreadSuspended = TRUE; + +#ifdef QCA_CONFIG_SMP + /* Suspend tlshim rx thread */ + set_bit(RX_SUSPEND_EVENT_MASK, &vosSchedContext->tlshimRxEvtFlg); + wake_up_interruptible(&vosSchedContext->tlshimRxWaitQueue); + rc = wait_for_completion_timeout( + &vosSchedContext->SuspndTlshimRxEvent, + msecs_to_jiffies(RX_TLSHIM_SUSPEND_TIMEOUT)); + if (!rc) { + clear_bit(RX_SUSPEND_EVENT_MASK, &vosSchedContext->tlshimRxEvtFlg); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop tl_shim rx thread", __func__); + goto resume_all; + } + pHddCtx->isTlshimRxThreadSuspended = TRUE; +#endif + + pHddCtx->isWiphySuspended = TRUE; + +#ifdef CONFIG_CNSS + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); +#endif + + EXIT(); + return 0; + +#ifdef QCA_CONFIG_SMP +resume_all: + + complete(&vosSchedContext->ResumeMcEvent); + pHddCtx->isMcThreadSuspended = FALSE; +#endif + +resume_tx: + + hdd_resume_wlan(); + return -ETIME; + +} + +int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef QCA_HT_2040_COEX +int wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + VOS_STATUS status; + tSmeConfigParams smeConfig; + bool cbModeChange; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return status; + } + + if (!pHddCtx->cfg_ini->ht2040CoexEnabled) + return -EOPNOTSUPP; + + vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(pHddCtx->hHal, &smeConfig); + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20: + if (smeConfig.csrConfig.channelBondingMode24GHz != + eCSR_INI_SINGLE_CHANNEL_CENTERED) { + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + sme_UpdateConfig(pHddCtx->hHal, &smeConfig); + cbModeChange = TRUE; + } + break; + + case NL80211_CHAN_WIDTH_40: + if (smeConfig.csrConfig.channelBondingMode24GHz == + eCSR_INI_SINGLE_CHANNEL_CENTERED) { + if ( NL80211_CHAN_HT40MINUS == cfg80211_get_chandef_type(chandef)) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + sme_UpdateConfig(pHddCtx->hHal, &smeConfig); + cbModeChange = TRUE; + } + break; + + default: + hddLog(LOGE, FL("Error!!! Invalid HT20/40 mode !")); + return -EINVAL; + } + + if (!cbModeChange) + return 0; + + if (WLAN_HDD_SOFTAP != pAdapter->device_mode) + return 0; + + hddLog(LOG1, FL("Channel bonding changed to %d"), + smeConfig.csrConfig.channelBondingMode24GHz); + + /* Change SAP ht2040 mode */ + status = hdd_set_sap_ht2040_mode(pAdapter, + cfg80211_get_chandef_type(chandef)); + if (status != VOS_STATUS_SUCCESS) { + hddLog(LOGE, + FL("Error!!! Cannot set SAP HT20/40 mode!")); + return -EINVAL; + } + + return 0; +} +#endif + +#ifdef FEATURE_WLAN_EXTSCAN + +static void +wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, + tpSirExtScanCapabilitiesEvent pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets); + hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan); + hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)", + pData->maxRssiSampleSize); + hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)", + pData->maxScanReportingThreshold); + hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs); + hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)", + pData->maxSignificantWifiChangeAPs); + hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)", + pData->maxBsidHistoryEntries); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE, + pData->scanCacheSize) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS, + pData->scanBuckets) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN, + pData->maxApPerScan) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE, + pData->maxRssiSampleSize) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD, + pData->maxScanReportingThreshold) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS, + pData->maxHotlistAPs) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS, + pData->maxSignificantWifiChangeAPs) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES, + pData->maxBsidHistoryEntries)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +static void +wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, tpSirExtScanStartRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +static void +wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, tpSirExtScanStopRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(LOG1, "Req Id (%u) Status (%u)", pData->requestId, pData->status); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +static void +wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx, + tpSirExtScanSetBssidHotListRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void +wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx, + tpSirExtScanResetBssidHotlistRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +static void +wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx, + tpSirExtScanSetSignificantChangeRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +static void +wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx, + tpSirExtScanResetSignificantChangeRspParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void +wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx, + tpSirWifiScanResultEvent pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tANI_U32 i; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(LOG1, "Req Id (%u) Num results (%u) More Data (%u)", + pData->requestId, pData->numOfAps, pData->moreData); + + for (i = 0; i < pData->numOfAps; i++) { + /* + * Firmware returns timestamp from WiFi turn ON till BSSID was cached + * (in seconds). Add this with time gap between system boot up to + * WiFi turn ON to derive the time since boot when the BSSID was cached. + */ + pData->ap[i].ts += pHddCtx->wifi_turn_on_time_since_boot; + hddLog(VOS_TRACE_LEVEL_INFO, "[index=%d] Timestamp(0x%llX) " + "Ssid (%s) " + "Bssid (" MAC_ADDRESS_STR ") " + "Channel (%u) " + "Rssi (%d) " + "RTT (%u) " + "RTT_SD (%u) " + "Beacon Period (%u) " + "Capability (0x%x) " + "Ie length (%d)", + i, + pData->ap[i].ts, + pData->ap[i].ssid, + MAC_ADDR_ARRAY(pData->ap[i].bssid), + pData->ap[i].channel, + pData->ap[i].rssi, + pData->ap[i].rtt, + pData->ap[i].rtt_sd, + pData->ap[i].beaconPeriod, + pData->ap[i].capability, + pData->ap[i].ieLength); + } + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numOfAps)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (pData->numOfAps) { + struct nlattr *aps; + + aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST); + if (!aps) + goto fail; + + for (i = 0; i < pData->numOfAps; i++) { + struct nlattr *ap; + + ap = nla_nest_start(skb, i); + if (!ap) + goto fail; + + if (nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pData->ap[i].ts) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pData->ap[i].ssid), + pData->ap[i].ssid) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + sizeof(pData->ap[i].bssid), + pData->ap[i].bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pData->ap[i].channel) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pData->ap[i].rssi) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pData->ap[i].rtt) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pData->ap[i].rtt_sd) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + pData->ap[i].beaconPeriod) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + pData->ap[i].capability) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + pData->ap[i].ieLength)) + goto fail; + + if (pData->ap[i].ieLength) + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + pData->ap[i].ieLength, pData->ap[i].ieData)) + goto fail; + + nla_nest_end(skb, ap); + } + nla_nest_end(skb, aps); + + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) + goto fail; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +fail: + kfree_skb(skb); + return; + +} +static void +wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx, + tpSirWifiScanResultEvent pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tANI_U32 i; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps); + hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData); + + for (i = 0; i < pData->numOfAps; i++) { + hddLog(VOS_TRACE_LEVEL_INFO, "[index=%d] Timestamp(0x%llX) " + "Ssid (%s) " + "Bssid (" MAC_ADDRESS_STR ") " + "Channel (%u) " + "Rssi (%d) " + "RTT (%u) " + "RTT_SD (%u)", + i, + pData->ap[i].ts, + pData->ap[i].ssid, + MAC_ADDR_ARRAY(pData->ap[i].bssid), + pData->ap[i].channel, + pData->ap[i].rssi, + pData->ap[i].rtt, + pData->ap[i].rtt_sd); + } + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numOfAps)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (pData->numOfAps) { + struct nlattr *aps; + + aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST); + if (!aps) + goto fail; + + for (i = 0; i < pData->numOfAps; i++) { + struct nlattr *ap; + + ap = nla_nest_start(skb, i); + if (!ap) + goto fail; + + if (nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pData->ap[i].ts) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pData->ap[i].ssid), + pData->ap[i].ssid) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + sizeof(pData->ap[i].bssid), + pData->ap[i].bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pData->ap[i].channel) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pData->ap[i].rssi) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pData->ap[i].rtt) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pData->ap[i].rtt_sd)) + goto fail; + + nla_nest_end(skb, ap); + } + nla_nest_end(skb, aps); + + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) + goto fail; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +fail: + kfree_skb(skb); + return; + +} + +static void +wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind( + void *ctx, + tpSirWifiSignificantChangeEvent pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tSirWifiSignificantChange *ap_info; + tANI_S32 *rssi; + tANI_U32 i, j; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numResults); + hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData); + + ap_info = &pData->ap[0]; + for (i = 0; i < pData->numResults; i++) { + hddLog(VOS_TRACE_LEVEL_INFO, "[index=%d] " + "Bssid (" MAC_ADDRESS_STR ") " + "Channel (%u) " + "numOfRssi (%d)", + i, + MAC_ADDR_ARRAY(ap_info->bssid), + ap_info->channel, + ap_info->numOfRssi); + rssi = &(ap_info)->rssi[0]; + for (j = 0; j < ap_info->numOfRssi; j++) + hddLog(VOS_TRACE_LEVEL_INFO, "Rssi (%d)", *rssi++); + + ap_info += ap_info->numOfRssi * sizeof(*rssi); + } + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numResults)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (pData->numResults) { + struct nlattr *aps; + + aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST); + if (!aps) + goto fail; + + ap_info = &pData->ap[0]; + for (i = 0; i < pData->numResults; i++) { + struct nlattr *ap; + + ap = nla_nest_start(skb, i); + if (!ap) + goto fail; + + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID, + sizeof(tSirMacAddr), ap_info->bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL, + ap_info->channel) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI, + ap_info->numOfRssi) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST, + sizeof(s32) * ap_info->numOfRssi, &(ap_info)->rssi[0])) + goto fail; + + nla_nest_end(skb, ap); + + ap_info += ap_info->numOfRssi * sizeof(*rssi); + } + nla_nest_end(skb, aps); + + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) + goto fail; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +fail: + kfree_skb(skb); + return; + +} + +static void +wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx, + tpSirWifiFullScanResultEvent pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + /* + * If the full scan result including IE data exceeds NL 4K size limitation, + * drop that beacon/probe rsp frame. + */ + if ((sizeof(*pData) + pData->ap.ieLength) >= EXTSCAN_EVENT_BUF_SIZE) { + hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!!")); + return; + } + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + pData->ap.channel = vos_chan_to_freq(pData->ap.channel); + hddLog(LOG1, "Req Id (%u) More Data (%u)", pData->requestId, + pData->moreData); + hddLog(LOG1, "AP Info: Timestamp(0x%llX) Ssid (%s) " + "Bssid (" MAC_ADDRESS_STR ") " + "Channel (%u) " + "Rssi (%d) " + "RTT (%u) " + "RTT_SD (%u) " + "Bcn Period (%d) " + "Capability (0x%X) " + "IE Length (%d)", + pData->ap.ts, + pData->ap.ssid, + MAC_ADDR_ARRAY(pData->ap.bssid), + pData->ap.channel, + pData->ap.rssi, + pData->ap.rtt, + pData->ap.rtt_sd, + pData->ap.beaconPeriod, + pData->ap.capability, + pData->ap.ieLength); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + pData->ap.ieData, pData->ap.ieLength); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pData->ap.ts) || + nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pData->ap.ssid), + pData->ap.ssid) || + nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + sizeof(pData->ap.bssid), + pData->ap.bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pData->ap.channel) || + nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pData->ap.rssi) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pData->ap.rtt) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pData->ap.rtt_sd) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + pData->ap.beaconPeriod) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + pData->ap.capability) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + pData->ap.ieLength) || + nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + if (pData->ap.ieLength) { + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + pData->ap.ieLength, pData->ap.ieData)) + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void +wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx, + tpSirExtScanResultsAvailableIndParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", + pData->numResultsAvailable); + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numResultsAvailable)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void +wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, + tpSirExtScanOnScanEventIndParams pData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx) || !pData) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid " + "or pData(%p) is null"), pData); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, "Request Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)", pData->scanEventType); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)", pData->status); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE, + pData->scanEventType) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS, + pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + + +void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is invalid" + "Received event (%d)"), evType); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType); + + switch (evType) { + case eSIR_EXTSCAN_START_RSP: + wlan_hdd_cfg80211_extscan_start_rsp(ctx, + (tpSirExtScanStartRspParams)pMsg); + break; + + case eSIR_EXTSCAN_STOP_RSP: + wlan_hdd_cfg80211_extscan_stop_rsp(ctx, + (tpSirExtScanStopRspParams)pMsg); + break; + + case eSIR_EXTSCAN_CACHED_RESULTS_RSP: + /* There is no need to send this response to upper layer + Just log the message */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Rcvd eSIR_EXTSCAN_CACHED_RESULTS_RSP")); + break; + + case eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP: + wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, + (tpSirExtScanSetBssidHotListRspParams)pMsg); + break; + + case eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP: + wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, + (tpSirExtScanResetBssidHotlistRspParams)pMsg); + break; + + case eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP: + wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, + (tpSirExtScanSetSignificantChangeRspParams)pMsg); + break; + + case eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP: + wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, + (tpSirExtScanResetSignificantChangeRspParams)pMsg); + break; + + case eSIR_EXTSCAN_GET_CAPABILITIES_IND: + wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, + (tpSirExtScanCapabilitiesEvent)pMsg); + break; + + case eSIR_EXTSCAN_HOTLIST_MATCH_IND: + wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, + (tpSirWifiScanResultEvent)pMsg); + break; + + case eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND: + wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind( + ctx, + (tpSirWifiSignificantChangeEvent)pMsg); + break; + + case eSIR_EXTSCAN_CACHED_RESULTS_IND: + wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, + (tpSirWifiScanResultEvent)pMsg); + break; + + case eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND: + wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, + (tpSirExtScanResultsAvailableIndParams)pMsg); + break; + + case eSIR_EXTSCAN_FULL_SCAN_RESULT_IND: + wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, + (tpSirWifiFullScanResultEvent)pMsg); + break; + + case eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND: + wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, + (tpSirExtScanOnScanEventIndParams)pMsg); + break; + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Unknown event type (%u)"), evType); + break; + } +} + +#endif /* FEATURE_WLAN_EXTSCAN */ + +/* cfg80211_ops */ +static struct cfg80211_ops wlan_hdd_cfg80211_ops = +{ + .add_virtual_intf = wlan_hdd_add_virtual_intf, + .del_virtual_intf = wlan_hdd_del_virtual_intf, + .change_virtual_intf = wlan_hdd_cfg80211_change_iface, + .change_station = wlan_hdd_change_station, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + .add_beacon = wlan_hdd_cfg80211_add_beacon, + .del_beacon = wlan_hdd_cfg80211_del_beacon, + .set_beacon = wlan_hdd_cfg80211_set_beacon, +#else + .start_ap = wlan_hdd_cfg80211_start_ap, + .change_beacon = wlan_hdd_cfg80211_change_beacon, + .stop_ap = wlan_hdd_cfg80211_stop_ap, +#endif + .change_bss = wlan_hdd_cfg80211_change_bss, + .add_key = wlan_hdd_cfg80211_add_key, + .get_key = wlan_hdd_cfg80211_get_key, + .del_key = wlan_hdd_cfg80211_del_key, + .set_default_key = wlan_hdd_cfg80211_set_default_key, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + .set_channel = wlan_hdd_cfg80211_set_channel, +#endif + .scan = wlan_hdd_cfg80211_scan, + .connect = wlan_hdd_cfg80211_connect, + .disconnect = wlan_hdd_cfg80211_disconnect, + .join_ibss = wlan_hdd_cfg80211_join_ibss, + .leave_ibss = wlan_hdd_cfg80211_leave_ibss, + .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params, + .set_tx_power = wlan_hdd_cfg80211_set_txpower, + .get_tx_power = wlan_hdd_cfg80211_get_txpower, + .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel, + .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel, + .mgmt_tx = wlan_hdd_mgmt_tx, + .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait, + .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key, + .set_txq_params = wlan_hdd_set_txq_params, + .get_station = wlan_hdd_cfg80211_get_station, + .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt, + .del_station = wlan_hdd_cfg80211_del_station, + .add_station = wlan_hdd_cfg80211_add_station, +#ifdef FEATURE_WLAN_LFR + .set_pmksa = wlan_hdd_cfg80211_set_pmksa, + .del_pmksa = wlan_hdd_cfg80211_del_pmksa, + .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa, +#endif +#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211) + .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies, +#endif +#ifdef FEATURE_WLAN_TDLS + .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt, + .tdls_oper = wlan_hdd_cfg80211_tdls_oper, +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD + .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data, +#endif /* WLAN_FEATURE_GTK_OFFLOAD */ +#ifdef FEATURE_WLAN_SCAN_PNO + .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start, + .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop, +#endif /*FEATURE_WLAN_SCAN_PNO */ + .resume = wlan_hdd_cfg80211_resume_wlan, + .suspend = wlan_hdd_cfg80211_suspend_wlan, + .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl, +#ifdef WLAN_NL80211_TESTMODE + .testmode_cmd = wlan_hdd_cfg80211_testmode, +#endif +#ifdef QCA_HT_2040_COEX + .set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width, +#endif + .dump_survey = wlan_hdd_cfg80211_dump_survey, +#ifdef NL80211_KEY_LEN_PMK /* kernel supports key mgmt offload */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + .key_mgmt_set_pmk = wlan_hdd_cfg80211_key_mgmt_set_pmk, +#endif +#endif +}; diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c new file mode 100644 index 0000000000000..bc9d0e81be3f0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_debugfs.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_OPEN_SOURCE +#include +#include + +#define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8 +#define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512 +#define MAX_USER_COMMAND_SIZE_FRAME 4096 + +static ssize_t wcnss_wowenable_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; + + char cmd[MAX_USER_COMMAND_SIZE_WOWL_ENABLE + 1]; + char *sptr, *token; + v_U8_t wow_enable = 0; + v_U8_t wow_mp = 0; + v_U8_t wow_pbm = 0; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + + return -EINVAL; + } + + if (!sme_IsFeatureSupportedByFW(WOW)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Wake-on-Wireless feature is not supported " + "in firmware!", __func__); + + return -EINVAL; + } + + if (count > MAX_USER_COMMAND_SIZE_WOWL_ENABLE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_WOWL_ENABLE); + + return -EINVAL; + } + + /* Get command from user */ + if (copy_from_user(cmd, buf, count)) + return -EFAULT; + cmd[count] = '\0'; + sptr = cmd; + + /* Get enable or disable wow */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_enable)) + return -EINVAL; + + /* Disable wow */ + if (!wow_enable) { + if (!hdd_exit_wowl(pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_exit_wowl failed!", __func__); + + return -EFAULT; + } + + return count; + } + + /* Get enable or disable magic packet mode */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_mp)) + return -EINVAL; + if (wow_mp > 1) + wow_mp = 1; + + /* Get enable or disable pattern byte matching mode */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_pbm)) + return -EINVAL; + if (wow_pbm > 1) + wow_pbm = 1; + + if (!hdd_enter_wowl(pAdapter, wow_mp, wow_pbm)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_enter_wowl failed!", __func__); + + return -EFAULT; + } + + return count; +} + +static ssize_t wcnss_wowpattern_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; + + char cmd[MAX_USER_COMMAND_SIZE_WOWL_PATTERN + 1]; + char *sptr, *token; + v_U8_t pattern_idx = 0; + v_U8_t pattern_offset = 0; + char *pattern_buf; + char *pattern_mask; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + + return -EINVAL; + } + + if (!sme_IsFeatureSupportedByFW(WOW)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Wake-on-Wireless feature is not supported " + "in firmware!", __func__); + + return -EINVAL; + } + + if (count > MAX_USER_COMMAND_SIZE_WOWL_PATTERN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_WOWL_PATTERN); + + return -EINVAL; + } + + /* Get command from user */ + if (copy_from_user(cmd, buf, count)) + return -EFAULT; + cmd[count] = '\0'; + sptr = cmd; + + /* Get pattern idx */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + if (kstrtou8(token, 0, &pattern_idx)) + return -EINVAL; + + /* Get pattern offset */ + token = strsep(&sptr, " "); + + /* Delete pattern if no further argument */ + if (!token) { + hdd_del_wowl_ptrn_debugfs(pAdapter, pattern_idx); + + return count; + } + + if (kstrtou8(token, 0, &pattern_offset)) + return -EINVAL; + + /* Get pattern */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + pattern_buf = token; + + /* Get pattern mask */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + pattern_mask = token; + pattern_mask[strlen(pattern_mask) - 1] = '\0'; + + hdd_add_wowl_ptrn_debugfs(pAdapter, pattern_idx, pattern_offset, + pattern_buf, pattern_mask); + + return count; +} + +static ssize_t wcnss_patterngen_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; + hdd_context_t *pHddCtx; + tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams; + tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams; + + char *cmd, *sptr, *token; + v_U8_t pattern_idx = 0; + v_U8_t pattern_duration = 0; + char *pattern_buf; + v_U16_t pattern_len = 0; + v_U16_t i = 0; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Periodic Tx Pattern Offload feature is not supported " + "in firmware!", __func__); + return -EINVAL; + } + + /* Get command from user */ + if (count <= MAX_USER_COMMAND_SIZE_FRAME) + cmd = vos_mem_malloc(count + 1); + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_FRAME); + + return -EINVAL; + } + + if (!cmd) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for cmd failed!", __func__); + + return -EFAULT; + } + + if (copy_from_user(cmd, buf, count)) + { + vos_mem_free(cmd); + return -EFAULT; + } + cmd[count] = '\0'; + sptr = cmd; + + /* Get pattern idx */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + if (kstrtou8(token, 0, &pattern_idx)) + goto failure; + + if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Pattern index %d is not in the range (0 ~ %d).", + __func__, pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1); + + goto failure; + } + + /* Get pattern duration */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + if (kstrtou8(token, 0, &pattern_duration)) + goto failure; + + /* Delete pattern using index if duration is 0 */ + if (!pattern_duration) + { + delPeriodicTxPtrnParams = + vos_mem_malloc(sizeof(tSirDelPeriodicTxPtrn)); + if (!delPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for delPeriodicTxPtrnParams " + "failed!", __func__); + + vos_mem_free(cmd); + return -EFAULT; + } + delPeriodicTxPtrnParams->ucPtrnId = pattern_idx; + delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx; + vos_mem_copy(delPeriodicTxPtrnParams->macAddress, + pAdapter->macAddressCurrent.bytes, 6); + + /* Delete pattern */ + if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal, + delPeriodicTxPtrnParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_DelPeriodicTxPtrn() failed!", __func__); + + vos_mem_free(delPeriodicTxPtrnParams); + goto failure; + } + vos_mem_free(cmd); + return count; + } + + /* Check if it's in connected state only when adding patterns */ + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Not in Connected state!", __func__); + + goto failure; + } + + /* Get pattern */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + + pattern_buf = token; + pattern_buf[strlen(pattern_buf) - 1] = '\0'; + pattern_len = strlen(pattern_buf); + + /* Since the pattern is a hex string, 2 characters represent 1 byte. */ + if (pattern_len % 2) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern!", __func__); + + goto failure; + } + else + pattern_len >>= 1; + + if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Not an 802.3 frame!", __func__); + + goto failure; + } + + addPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirAddPeriodicTxPtrn)); + if (!addPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for addPeriodicTxPtrnParams " + "failed!", __func__); + + vos_mem_free(cmd); + return -EFAULT; + } + + addPeriodicTxPtrnParams->ucPtrnId = pattern_idx; + addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500; + addPeriodicTxPtrnParams->ucPtrnSize = pattern_len; + vos_mem_copy(addPeriodicTxPtrnParams->macAddress, + pAdapter->macAddressCurrent.bytes, 6); + + /* Extract the pattern */ + for(i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++) + { + addPeriodicTxPtrnParams->ucPattern[i] = + (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); + + /* Skip to next byte */ + pattern_buf += 2; + } + + /* Add pattern */ + if (eHAL_STATUS_SUCCESS != sme_AddPeriodicTxPtrn(pHddCtx->hHal, + addPeriodicTxPtrnParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AddPeriodicTxPtrn() failed!", __func__); + + vos_mem_free(addPeriodicTxPtrnParams); + goto failure; + } + vos_mem_free(cmd); + return count; + +failure: + vos_mem_free(cmd); + return -EINVAL; +} + +static int wcnss_debugfs_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + { + file->private_data = inode->i_private; + } + + return 0; +} + +static const struct file_operations fops_wowenable = { + .write = wcnss_wowenable_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static const struct file_operations fops_wowpattern = { + .write = wcnss_wowpattern_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static const struct file_operations fops_patterngen = { + .write = wcnss_patterngen_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->debugfs_phy = debugfs_create_dir("wlan_wcnss", 0); + + if (NULL == pHddCtx->debugfs_phy) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("wow_enable", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_wowenable)) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("wow_pattern", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_wowpattern)) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("pattern_gen", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_patterngen)) + return VOS_STATUS_E_FAILURE; + + return VOS_STATUS_SUCCESS; +} + +void hdd_debugfs_exit(hdd_context_t *pHddCtx) +{ + debugfs_remove_recursive(pHddCtx->debugfs_phy); +} +#endif /* #ifdef WLAN_OPEN_SOURCE */ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dev_pwr.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dev_pwr.c new file mode 100644 index 0000000000000..8d9c7ef376b89 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dev_pwr.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/29/11 tbh Created module. + + ==========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + * Global variables. + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Local variables. + *-------------------------------------------------------------------------*/ +/* Reference VoIP, 100msec delay make disconnect. + * So TX sleep must be less than 100msec + * Every 20msec TX frame will goes out. + * 10 frame means 2seconds TX operation */ +static const hdd_tmLevelAction_t thermalMigrationAction[WLAN_HDD_TM_LEVEL_MAX] = +{ + /* TM Level 0, Do nothing, just normal operation */ + {1, 0, 0, 0, 0xFFFFF}, + /* Tm Level 1, disable TX AMPDU */ + {0, 0, 0, 0, 0xFFFFF}, + /* TM Level 2, disable AMDPU, + * TX sleep 100msec if TX frame count is larger than 16 during 300msec */ + {0, 0, 100, 300, 16}, + /* TM Level 3, disable AMDPU, + * TX sleep 500msec if TX frame count is larger than 11 during 500msec */ + {0, 0, 500, 500, 11}, + /* TM Level 4, MAX TM level, enter IMPS */ + {0, 1, 1000, 500, 10} +}; +#ifdef HAVE_WCNSS_SUSPEND_RESUME_NOTIFY +static bool suspend_notify_sent; +#endif + + +/*---------------------------------------------------------------------------- + + @brief TX frame block timeout handler + Resume TX, and reset TX frame count + + @param hdd_context_t pHddCtx + Global hdd context + + @return NONE + +----------------------------------------------------------------------------*/ +void hddDevTmTxBlockTimeoutHandler(void *usrData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)usrData; + hdd_adapter_t *staAdapater; + /* Sanity, This should not happen */ + if(NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: NULL Context", __func__); + VOS_ASSERT(0); + return; + } + + staAdapater = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + + if(NULL == staAdapater) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: NULL Adapter", __func__); + VOS_ASSERT(0); + return; + } + + if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Acquire lock fail", __func__); + return; + } + pHddCtx->tmInfo.txFrameCount = 0; + + /* Resume TX flow */ + + netif_tx_wake_all_queues(staAdapater->dev); + pHddCtx->tmInfo.qBlocked = VOS_FALSE; + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + + return; +} + +/*---------------------------------------------------------------------------- + + @brief Register function + Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmRegisterNotifyCallback(hdd_context_t *pHddCtx) +{ + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO, + "%s: Register TM Handler", __func__); + + wcnss_register_thermal_mitigation(pHddCtx->parent_dev ,hddDevTmLevelChangedHandler); + + /* Set Default TM Level as Lowest, do nothing */ + pHddCtx->tmInfo.currentTmLevel = WLAN_HDD_TM_LEVEL_0; + vos_mem_zero(&pHddCtx->tmInfo.tmAction, sizeof(hdd_tmLevelAction_t)); + vos_timer_init(&pHddCtx->tmInfo.txSleepTimer, + VOS_TIMER_TYPE_SW, + hddDevTmTxBlockTimeoutHandler, + (void *)pHddCtx); + mutex_init(&pHddCtx->tmInfo.tmOperationLock); + pHddCtx->tmInfo.txFrameCount = 0; + pHddCtx->tmInfo.blockedQueue = NULL; + pHddCtx->tmInfo.qBlocked = VOS_FALSE; + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief Un-Register function + Un-Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Un-Registration Success + VOS_STATUS_E_FAILURE Un-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmUnregisterNotifyCallback(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + wcnss_unregister_thermal_mitigation(hddDevTmLevelChangedHandler); + + if(VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer)) + { + vosStatus = vos_timer_stop(&pHddCtx->tmInfo.txSleepTimer); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timer stop fail", __func__); + } + } + + // Destroy the vos timer... + vosStatus = vos_timer_destroy(&pHddCtx->tmInfo.txSleepTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Fail to destroy timer", __func__); + } + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dp_utils.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dp_utils.c new file mode 100644 index 0000000000000..a570e3c566c81 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_dp_utils.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + wlan_hdd_dp_utils.c + + \brief Utility functions for data path module + + Description... + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Function declarations and documentation + ----------------------------------------------------------------------------*/ + + +VOS_STATUS hdd_list_insert_front( hdd_list_t *pList, hdd_list_node_t *pNode ) +{ + list_add( pNode, &pList->anchor ); + pList->count++; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_insert_back( hdd_list_t *pList, hdd_list_node_t *pNode ) +{ + list_add_tail( pNode, &pList->anchor ); + pList->count++; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_insert_back_size( hdd_list_t *pList, hdd_list_node_t *pNode, v_SIZE_t *pSize ) +{ + list_add_tail( pNode, &pList->anchor ); + pList->count++; + *pSize = pList->count; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_front( hdd_list_t *pList, hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + *ppNode = listptr; + list_del(pList->anchor.next); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_back( hdd_list_t *pList, hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.prev; + *ppNode = listptr; + list_del(pList->anchor.prev); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_node( hdd_list_t *pList, + hdd_list_node_t *pNodeToRemove ) +{ + hdd_list_node_t *tmp; + int found = 0; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + // verify that pNodeToRemove is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNodeToRemove) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_del(pNodeToRemove); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_peek_front( hdd_list_t *pList, + hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + *ppNode = listptr; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_peek_next( hdd_list_t *pList, hdd_list_node_t *pNode, + hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + int found = 0; + hdd_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL)) + { + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + + if (found == 0) + { + return VOS_STATUS_E_INVAL; + } + + listptr = pNode->next; + if (listptr == &pList->anchor) + { + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ) +{ + int i; + int k; + char temp[3] = {0}; + int rv; + + //18 is MAC Address length plus the colons + if ( !pSrcMac && (length > 18 || length < 18) ) + { + return VOS_STATUS_E_FAILURE; + } + i = k = 0; + while ( i < length ) + { + memcpy(temp, pSrcMac+i, 2); + rv = kstrtou8(temp, 16, &pDescMac[k++]); + if (rv < 0) + return VOS_STATUS_E_FAILURE; + i += 3; + } + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_early_suspend.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_early_suspend.c new file mode 100644 index 0000000000000..4625741e09ca7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -0,0 +1,2258 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= +* wlan_hdd_early_suspend.c +* +* \brief power management functions +* +* Description + +* +==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- +* Include files +* ----------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif +#include "halTypes.h" +#include "sme_Api.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "cfgApi.h" + +#ifdef WLAN_BTAMP_FEATURE +#include "bapApi.h" +#include "bap_hdd_main.h" +#include "bap_hdd_misc.h" +#endif + +#include +#include +#include +#include +#include +#ifdef IPA_OFFLOAD +#include +#endif + +/**----------------------------------------------------------------------------- +* Preprocessor definitions and constants +* ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- +* Type declarations +* ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- +* Function and variables declarations +* ----------------------------------------------------------------------------*/ +#include "wlan_hdd_power.h" +#include "wlan_hdd_packet_filtering.h" + +#include +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +/* Time in msec */ +#ifdef CONFIG_SLUB_DEBUG_ON +#define HDD_SSR_BRING_UP_TIME 20000 +#else +#define HDD_SSR_BRING_UP_TIME 10000 +#endif + +static eHalStatus g_full_pwr_status; +static eHalStatus g_standby_status; + +extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx); +extern void hdd_wlan_initial_scan(hdd_context_t *pHddCtx); + +extern struct notifier_block hdd_netdev_notifier; +extern tVOS_CON_MODE hdd_get_conparam ( void ); + +static struct timer_list ssr_timer; +static bool ssr_timer_started; + +//Callback invoked by PMC to report status of standby request +void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status); + g_standby_status = status; + + if(eHAL_STATUS_SUCCESS == status) + { + pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__); + } + + complete(&pHddCtx->standby_comp_var); +} + +//Callback invoked by PMC to report status of full power request +void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status); + g_full_pwr_status = status; + + if(eHAL_STATUS_SUCCESS == status) + { + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + } + + complete(&pHddCtx->full_pwr_comp_var); +} + +eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx) +{ + eHalStatus status = VOS_STATUS_SUCCESS; + unsigned long rc; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__); + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + + g_full_pwr_status = eHAL_STATUS_FAILURE; + status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx, + eSME_FULL_PWR_NEEDED_BY_HDD); + + if(status == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + rc = wait_for_completion_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on full_pwr_comp_var failed")); + } + status = g_full_pwr_status; + if(g_full_pwr_status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + VOS_ASSERT(0); + goto failure; + } + } + else if(status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d", + __func__, status); + VOS_ASSERT(0); + goto failure; + } + else + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + +failure: + //No blocking to reduce latency. No other device should be depending on WLAN + //to finish resume and WLAN won't be instantly on after resume + return status; +} + + +//Helper routine to put the chip into standby +VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + unsigned long rc; + + //Disable IMPS/BMPS as we do not want the device to enter any power + //save mode on its own during suspend sequence + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + //Note we do not disable queues unnecessarily. Queues should already be disabled + //if STA is disconnected or the queue will be disabled as and when disconnect + //happens because of standby procedure. + + //Ensure that device is in full power first. There is scope for optimization + //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS. + //Core s/w needs to be optimized to handle this. Until then we request full + //power before issuing request for standby. + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + g_full_pwr_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + rc = wait_for_completion_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on full_pwr_comp_var failed")); + } + + if(g_full_pwr_status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + } + else if(halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d", + __func__, halStatus); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + + if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) { + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + } + + //Request standby. Standby will cause the STA to disassociate first. TX queues + //will be disabled (by HDD) when STA disconnects. You do not want to disable TX + //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC + //will send this failure code in case of concurrent sessions. Power Save cannot be supported + //when there are concurrent sessions. + INIT_COMPLETION(pHddCtx->standby_comp_var); + g_standby_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx); + + if (halStatus == eHAL_STATUS_PMC_PENDING) + { + //Wait till WLAN device enters standby mode + rc = wait_for_completion_timeout(&pHddCtx->standby_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on standby_comp_var failed")); + } + + if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + } + else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d", + __func__, halStatus); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + else + pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY; + +failure: + //Restore IMPS config + if(pHddCtx->cfg_ini->fIsImpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + + //Restore BMPS config + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + return vosStatus; +} + + +//Helper routine for Deep sleep entry +VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + unsigned long rc; + + //Stop the Interface TX queue. + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + //Disable IMPS,BMPS as we do not want the device to enter any power + //save mode on it own during suspend sequence + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + //Ensure that device is in full power as we will touch H/W during vos_Stop + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + g_full_pwr_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + rc = wait_for_completion_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on full_pwr_comp_var failed")); + } + + if(g_full_pwr_status != eHAL_STATUS_SUCCESS){ + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + VOS_ASSERT(0); + } + } + else if(halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__); + VOS_ASSERT(0); + } + + //Issue a disconnect. This is required to inform the supplicant that + //STA is getting disassociated and for GUI to be updated properly + INIT_COMPLETION(pAdapter->disconnect_comp_var); + halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + //Success implies disconnect command got queued up successfully + if(halStatus == eHAL_STATUS_SUCCESS) + { + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on disconnect_comp_var failed")); + } + } + //None of the steps should fail after this. Continue even in case of failure + vosStatus = vos_stop( pHddCtx->pvosContext ); + if (!VOS_IS_STATUS_SUCCESS( vosStatus )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d", + __func__, vosStatus); + VOS_ASSERT(0); + } + + pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP; + + //Restore IMPS config + if(pHddCtx->cfg_ini->fIsImpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + + //Restore BMPS config + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + return vosStatus; +} + +VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter) +{ + VOS_STATUS vosStatus; + eHalStatus halStatus; + tANI_U32 type, subType; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling hdd_set_sme_config",__func__); + vosStatus = hdd_set_sme_config( pHddCtx ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in hdd_set_sme_config",__func__); + goto err_deep_sleep; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling vos_start",__func__); + vosStatus = vos_start( pHddCtx->pvosContext ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in vos_start",__func__); + goto err_deep_sleep; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling hdd_post_voss_start_config",__func__); + vosStatus = hdd_post_voss_start_config( pHddCtx ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in hdd_post_voss_start_config",__func__); + goto err_voss_stop; + } + + vosStatus = vos_get_vdev_types(pAdapter->device_mode, &type, &subType); + if (VOS_STATUS_SUCCESS != vosStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "failed to get vdev type"); + goto err_voss_stop; + } + + //Open a SME session for future operation + halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter, + (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId, + type, subType); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]", + halStatus, halStatus ); + goto err_voss_stop; + + } + + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + + //Trigger the initial scan + hdd_wlan_initial_scan(pHddCtx); + + return VOS_STATUS_SUCCESS; + +err_voss_stop: + vos_stop(pHddCtx->pvosContext); +err_deep_sleep: + return VOS_STATUS_E_FAILURE; + +} + +/* + * Function: hdd_conf_hostoffload + * Central function to configure the supported offloads, + * either enable or disable them. + */ +void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t *pVosContext = NULL; + VOS_STATUS vstatus = VOS_STATUS_E_FAILURE; + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"), + fenable); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null")); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__); + return; + } + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + if (fenable) + { + if (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) + { + if ((pHddCtx->cfg_ini->fhostArpOffload)) + { + /* + * Configure the ARP Offload. + * Even if it fails we have to reconfigure the MC/BC + * filter flag as we want RIVA not to drop BroadCast + * Packets + */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Calling ARP Offload with flag: %d"), fenable); + vstatus = hdd_conf_arp_offload(pAdapter, fenable); + pHddCtx->configuredMcastBcastFilter &= + ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST); + + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Failed to enable ARPOFfloadFeature %d", + vstatus); + } + } + //Configure GTK_OFFLOAD +#ifdef WLAN_FEATURE_GTK_OFFLOAD + hdd_conf_gtk_offload(pAdapter, fenable); +#endif + +#ifdef WLAN_NS_OFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + /* + * Configure the NS Offload. + * Even if it fails we have to reconfigure the MC/BC filter flag + * as we want RIVA not to drop Multicast Packets + */ + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Calling NS Offload with flag: %d"), fenable); + hdd_conf_ns_offload(pAdapter, fenable); + pHddCtx->configuredMcastBcastFilter &= + ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } + +#endif + /* + * This variable saves the state if offload were configured + * or not. helps in recovering when pcie fails to suspend + * because of ongoing scan and state is no longer associated. + */ + pAdapter->offloads_configured = TRUE; + } + } + else + { + //Disable ARPOFFLOAD + if ( (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) || + (pAdapter->offloads_configured == TRUE) + ) + { + pAdapter->offloads_configured = FALSE; + + if (pHddCtx->cfg_ini->fhostArpOffload) + { + vstatus = hdd_conf_arp_offload(pAdapter, fenable); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Failed to disable ARPOffload Feature %d", vstatus); + } + } + //Disable GTK_OFFLOAD +#ifdef WLAN_FEATURE_GTK_OFFLOAD + hdd_conf_gtk_offload(pAdapter, fenable); +#endif + +#ifdef WLAN_NS_OFFLOAD + //Disable NSOFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + hdd_conf_ns_offload(pAdapter, fenable); + } +#endif + } + } + } + return; +} + +#ifdef WLAN_NS_OFFLOAD +void hdd_ipv6_notifier_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = + container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue); + hdd_context_t *pHddCtx; + int status; + + hddLog(LOG1, FL("Reconfiguring NS Offload")); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(LOGE, FL("HDD context is invalid")); + return; + } + + if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->configuredMcastBcastFilter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE; + } + + if ((eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) + && (pHddCtx->hdd_wlan_suspended)) + { + // This invocation being part of the IPv6 registration callback, + // we are passing second parameter as 2 to avoid registration + // of IPv6 notifier again. + hdd_conf_ns_offload(pAdapter, 2); + } +} + +static int wlan_hdd_ipv6_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg; + struct net_device *ndev = ifa->idev->dev; + hdd_adapter_t *pAdapter = + container_of(nb, struct hdd_adapter_s, ipv6_notifier); + hdd_context_t *pHddCtx; + int status; + + if (pAdapter && pAdapter->dev == ndev) + { + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(LOGE, FL("HDD context is invalid")); + return NOTIFY_DONE; + } + + schedule_work(&pAdapter->ipv6NotifierWorkQueue); + } + + return NOTIFY_DONE; +} + +/**---------------------------------------------------------------------------- + + \brief hdd_conf_ns_offload() - Configure NS offload + + Called during SUSPEND to configure the NS offload (MC BC filter) which + reduces power consumption. + + \param - pAdapter - Adapter context for which NS offload is to be configured + \param - fenable - 0 - disable. + 1 - enable. (with IPv6 notifier registration) + 2 - enable. (without IPv6 notifier registration) + + \return - void + + ---------------------------------------------------------------------------*/ +void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) +{ + struct inet6_dev *in6_dev; + struct inet6_ifaddr *ifp; + struct list_head *p; + tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}}; + tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0}; + tSirHostOffloadReq offLoadRequest; + hdd_context_t *pHddCtx; + + int i =0; + int ret =0; + eHalStatus returnStatus; + + ENTER(); + hddLog(LOG1, FL(" fenable = %d"), fenable); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (fenable) + { + in6_dev = __in6_dev_get(pAdapter->dev); + if (NULL != in6_dev) + { + //read_lock_bh(&in6_dev->lock); + list_for_each(p, &in6_dev->addr_list) + { + ifp = list_entry(p, struct inet6_ifaddr, if_list); + switch(ipv6_addr_src_scope(&ifp->addr)) + { + case IPV6_ADDR_SCOPE_LINKLOCAL: + vos_mem_copy(&selfIPv6Addr[0], &ifp->addr.s6_addr, + sizeof(ifp->addr.s6_addr)); + selfIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID; + hddLog (VOS_TRACE_LEVEL_INFO, + "Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6", + selfIPv6Addr[0]); + break; + case IPV6_ADDR_SCOPE_GLOBAL: + vos_mem_copy(&selfIPv6Addr[1], &ifp->addr.s6_addr, + sizeof(ifp->addr.s6_addr)); + selfIPv6AddrValid[1] = SIR_IPV6_ADDR_VALID; + hddLog (VOS_TRACE_LEVEL_INFO, + "Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6", + selfIPv6Addr[1]); + break; + default: + hddLog(LOGE, "The Scope %d is not supported", + ipv6_addr_src_scope(&ifp->addr)); + } + + } + //read_unlock_bh(&in6_dev->lock); + vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest)); + for (i =0; imacAddressCurrent.bytes, + sizeof(tANI_U8)*SIR_MAC_ADDR_LEN); + + offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = SIR_IPV6_ADDR_VALID; + offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; + offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; + + hddLog (VOS_TRACE_LEVEL_INFO, + "configuredMcastBcastFilter: %d",pHddCtx->configuredMcastBcastFilter); + + if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) + && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST == + pHddCtx->sus_res_mcastbcast_filter) || + (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter))) + { + hddLog (VOS_TRACE_LEVEL_INFO, + "Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE"); + offLoadRequest.enableOrDisable = + SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE; + } + + vos_mem_copy(&offLoadRequest.params.hostIpv6Addr, + &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0], + sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN); + + hddLog (VOS_TRACE_LEVEL_INFO, + "Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6", + offLoadRequest.nsOffloadInfo.selfIPv6Addr, + offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]); + + //Configure the Firmware with this + returnStatus = sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest); + if(eHAL_STATUS_SUCCESS != returnStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to enable HostOffload feature with status: %d"), + returnStatus); + } + vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest)); + } + } + if (fenable == 1 && !pAdapter->ipv6_notifier_registered) + { + // Register IPv6 notifier to notify if any change in IP + // So that we can reconfigure the offload parameters + pAdapter->ipv6_notifier.notifier_call = + wlan_hdd_ipv6_changed; + ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier); + if (ret) + { + hddLog(LOGE, FL("Failed to register IPv6 notifier")); + } + else + { + hddLog(LOG1, FL("Registered IPv6 notifier")); + pAdapter->ipv6_notifier_registered = true; + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("IPv6 dev does not exist. Failed to request NSOffload")); + return; + } + } + else + { + //Disable NSOffload + if (pAdapter->ipv6_notifier_registered) + { + hddLog(LOG1, FL("Unregistered IPv6 notifier")); + unregister_inet6addr_notifier(&pAdapter->ipv6_notifier); + pAdapter->ipv6_notifier_registered = false; + } + vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); + offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; + offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; + + //Disable NSOffload on all slots + for (i = 0; i < SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA; i++) + { + offLoadRequest.nsOffloadInfo.slotIdx = i; + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disable NSOflload" + " on slot %d"), i); + } + } + } + return; +} +#endif + +void hdd_ipv4_notifier_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = + container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue); + hdd_context_t *pHddCtx; + int status; + + hddLog(LOG1, FL("Reconfiguring ARP Offload")); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(LOGE, FL("HDD context is invalid")); + return; + } + + if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->configuredMcastBcastFilter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE; + } + + if ((eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) + && (pHddCtx->hdd_wlan_suspended)) + { + // This invocation being part of the IPv4 registration callback, + // we are passing second parameter as 2 to avoid registration + // of IPv4 notifier again. + hdd_conf_arp_offload(pAdapter, 2); + } +} + +static int wlan_hdd_ipv4_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)arg; + struct in_ifaddr **ifap = NULL; + struct in_device *in_dev; + + struct net_device *ndev = ifa->ifa_dev->dev; + hdd_adapter_t *pAdapter = + container_of(nb, struct hdd_adapter_s, ipv4_notifier); + hdd_context_t *pHddCtx; + int status; + if (pAdapter && pAdapter->dev == ndev) + { + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(LOGE, FL("HDD context is invalid")); + return NOTIFY_DONE; + } + if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL) + { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) + { + if (!strcmp(pAdapter->dev->name, ifa->ifa_label)) + { + break; /* found */ + } + } + } + if(ifa && ifa->ifa_local) + { + schedule_work(&pAdapter->ipv4NotifierWorkQueue); + } + } + + return NOTIFY_DONE; +} + +/**---------------------------------------------------------------------------- + + \brief hdd_conf_arp_offload() - Configure ARP offload + + Called during SUSPEND to configure the ARP offload (MC BC filter) which + reduces power consumption. + + \param - pAdapter -Adapter context for which ARP offload is to be configured + \param - fenable - 0 - disable. + 1 - enable. (with IPv4 notifier registration) + 2 - enable. (without IPv4 notifier registration) + + \return - + VOS_STATUS_SUCCESS - on successful operation + VOS_STATUS_E_FAILURE - on failure of operation +-----------------------------------------------------------------------------*/ +VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable) +{ + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + struct in_device *in_dev; + int i = 0; + int ret = 0; + tSirHostOffloadReq offLoadRequest; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" fenable = %d \n"), fenable); + if(fenable) + { + if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL) + { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) + { + if (!strcmp(pAdapter->dev->name, ifa->ifa_label)) + { + break; /* found */ + } + } + } + if(ifa && ifa->ifa_local) + { + offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD; + offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__); + + if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter) || + (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter)) && + (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)) + { + offLoadRequest.enableOrDisable = + SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE; + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: inside arp offload conditional check"); + } + + hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d", + offLoadRequest.enableOrDisable); + + //converting u32 to IPV4 address + for(i = 0 ; i < 4; i++) + { + offLoadRequest.params.hostIpv4Addr[i] = + (ifa->ifa_local >> (i*8) ) & 0xFF ; + } + hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d", + offLoadRequest.params.hostIpv4Addr[0], + offLoadRequest.params.hostIpv4Addr[1], + offLoadRequest.params.hostIpv4Addr[2], + offLoadRequest.params.hostIpv4Addr[3]); + + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload " + "feature", __func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("IP Address is not assigned\n")); + } + + if (fenable == 1 && !pAdapter->ipv4_notifier_registered) + { + // Register IPv4 notifier to notify if any change in IP + // So that we can reconfigure the offload parameters + pAdapter->ipv4_notifier.notifier_call = + wlan_hdd_ipv4_changed; + ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier); + if (ret) + { + hddLog(LOGE, FL("Failed to register IPv4 notifier")); + } + else + { + hddLog(LOG1, FL("Registered IPv4 notifier")); + pAdapter->ipv4_notifier_registered = true; + } + } + return VOS_STATUS_SUCCESS; + } + else + { + if (pAdapter->ipv4_notifier_registered) + { + hddLog(LOG1, FL("Unregistered IPv4 notifier")); + unregister_inetaddr_notifier(&pAdapter->ipv4_notifier); + pAdapter->ipv4_notifier_registered = false; + } + vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); + offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; + offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD; + + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host " + "offload feature", __func__); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; + } +} + +/* + * This function is called before setting mcbc filters + * to modify filter value considering Different Offloads + */ + +void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx, + tANI_U8 *pMcBcFilter) +{ + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed")); + return; + } + + *pMcBcFilter = pHddCtx->configuredMcastBcastFilter; + if (pHddCtx->cfg_ini->fhostArpOffload) + { + /* ARP offload is enabled, do not block bcast packets at RXP + * Will be using Bitmasking to reset the filter. As we have + * disable Broadcast filtering, Anding with the negation + * of Broadcast BIT + */ + *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST); + } + +#ifdef WLAN_NS_OFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + /* NS offload is enabled, do not block mcast packets at RXP + * Will be using Bitmasking to reset the filter. As we have + * disable Multicast filtering, Anding with the negation + * of Multicast BIT + */ + *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } +#endif + + pHddCtx->configuredMcastBcastFilter = *pMcBcFilter; +} + +void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tpSirWlanSetRxpFilters wlanRxpFilterParam = + vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if(NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter); + if (TRUE == setfilter) + { + hdd_mcbc_filter_modification(pHddCtx, + &wlanRxpFilterParam->configuredMcstBcstFilterSetting); + } + else + { + /*Use the current configured value to clear*/ + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + } + + wlanRxpFilterParam->setMcstBcstFilter = setfilter; + halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam); + if (eHAL_STATUS_SUCCESS != halStatus) + vos_mem_free(wlanRxpFilterParam); + if(setfilter && (eHAL_STATUS_SUCCESS == halStatus)) + pHddCtx->hdd_mcastbcast_filter_set = TRUE; +} + +static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx, + hdd_adapter_t *pAdapter, + void (*callback)(void *callbackContext, + boolean suspended), + void *callbackContext) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tpSirWlanSuspendParam wlanSuspendParam = + vos_mem_malloc(sizeof(tSirWlanSuspendParam)); + + if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->configuredMcastBcastFilter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind"); + hddLog(VOS_TRACE_LEVEL_INFO, "configuredMCastBcastFilter saved = %d", + pHddCtx->configuredMcastBcastFilter); + + } + + + if(NULL == wlanSuspendParam) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: send wlan suspend indication", __func__); + + if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)) + { + //Configure supported OffLoads + hdd_conf_hostoffload(pAdapter, TRUE); + wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* During suspend, configure MC Addr list filter to the firmware + * function takes care of checking necessary conditions before + * configuring. + */ + wlan_hdd_set_mc_addr_list(pAdapter, TRUE); +#endif + } + + if ((eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) || + (eConnectionState_IbssConnected == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + wlanSuspendParam->connectedState = TRUE; + else + wlanSuspendParam->connectedState = FALSE; + + wlanSuspendParam->sessionId = pAdapter->sessionId; + halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam, + callback, callbackContext); + if(eHAL_STATUS_SUCCESS == halStatus) + { + pHddCtx->hdd_mcastbcast_filter_set = TRUE; + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ConfigureSuspendInd returned failure %d"), halStatus); + + vos_mem_free(wlanSuspendParam); + } +} + +static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter) +{ + hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + + halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, + NULL + ); + + if (eHAL_STATUS_SUCCESS != halStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_ConfigureResumeReq return failure %d", + __func__, halStatus); + + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: send wlan resume indication", __func__); + /* Disable supported OffLoads */ + hdd_conf_hostoffload(pAdapter, FALSE); + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) { + pHddCtx->configuredMcastBcastFilter = + pHddCtx->sus_res_mcastbcast_filter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter"); + hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d", + pHddCtx->configuredMcastBcastFilter); + + +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* Filter was applied during suspend indication + * clear it when we resume. + */ + wlan_hdd_set_mc_addr_list(pAdapter, FALSE); +#endif +} + +//Suspend routine registered with Android OS +void hdd_suspend_wlan(void (*callback)(void *callbackContext, boolean suspended), + void *callbackContext) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + bool hdd_enter_bmps = FALSE; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return; + } + + if (pHddCtx->isLogpInProgress) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Ignore suspend wlan, LOGP in progress!", __func__); + return; + } + + hdd_set_pwrparams(pHddCtx); + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_SOFTAP != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + + { + goto send_suspend_ind; + } + /* Avoid multiple enter/exit BMPS in this while loop using + * hdd_enter_bmps flag + */ + if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal))) + { + hdd_enter_bmps = TRUE; + + /* If device was already in BMPS, and dynamic DTIM is set, + * exit(set the device to full power) and enter BMPS again + * to reflect new DTIM value */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + + pHddCtx->hdd_ignore_dtim_enabled = TRUE; + } +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY) + { + //stop the interface before putting the chip to standby + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + } + else if (pHddCtx->cfg_ini->nEnableSuspend == + WLAN_MAP_SUSPEND_TO_DEEP_SLEEP) + { + //Execute deep sleep procedure + hdd_enter_deep_sleep(pHddCtx, pAdapter); + } +#endif + +send_suspend_ind: + //stop all TX queues before suspend + netif_tx_disable(pAdapter->dev); + WLANTL_PauseUnPauseQs(pVosContext, true); + + /* Keep this suspend indication at the end (before processing next adaptor) + * for discrete. This indication is considered as trigger point to start + * WOW (if wow is enabled). */ + /*Suspend notification sent down to driver*/ + hdd_conf_suspend_ind(pHddCtx, pAdapter, callback, callbackContext); + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + pHddCtx->hdd_wlan_suspended = TRUE; + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY) + { + hdd_enter_standby(pHddCtx); + } +#endif + + return; +} + +static void hdd_PowerStateChangedCB +( + v_PVOID_t callbackContext, + tPmcState newState +) +{ + hdd_context_t *pHddCtx = callbackContext; + /* if the driver was not in BMPS during early suspend, + * the dynamic DTIM is now updated at Riva */ + if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended + && pHddCtx->cfg_ini->enableDynamicDTIM + && (pHddCtx->hdd_ignore_dtim_enabled == FALSE)) + { + pHddCtx->hdd_ignore_dtim_enabled = TRUE; + } + spin_lock(&pHddCtx->filter_lock); + if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended) + { + spin_unlock(&pHddCtx->filter_lock); + if (VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->configuredMcastBcastFilter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE; + + hddLog(VOS_TRACE_LEVEL_INFO, "offload: callback to associated"); + hddLog(VOS_TRACE_LEVEL_INFO, "saving configuredMcastBcastFilter = %d", + pHddCtx->configuredMcastBcastFilter); + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: calling hdd_conf_mcastbcast_filter"); + + } + + hdd_conf_mcastbcast_filter(pHddCtx, TRUE); + if(pHddCtx->hdd_mcastbcast_filter_set != TRUE) + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__); + } + else + { + /* Android framework can send resume request when the WCN chip is + * in IMPS mode. When the chip exits IMPS mode the firmware will + * restore all the registers to the state they were before the chip + * entered IMPS and so our hardware filter settings configured by the + * resume request will be lost. So reconfigure the filters on detecting + * a change in the power state of the WCN chip. + */ + spin_unlock(&pHddCtx->filter_lock); + if (IMPS != newState) + { + spin_lock(&pHddCtx->filter_lock); + if (FALSE == pHddCtx->hdd_wlan_suspended) + { + spin_unlock(&pHddCtx->filter_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "Not in IMPS/BMPS and suspended state"); + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + } + else + { + spin_unlock(&pHddCtx->filter_lock); + } + } + } +} + + + +void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx) +{ + v_CONTEXT_t pVosContext; + tHalHandle smeContext; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL == pVosContext) + { + hddLog(LOGE, "%s: Invalid pContext", __func__); + return; + } + smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext); + if (NULL == smeContext) + { + hddLog(LOGE, "%s: Invalid smeContext", __func__); + return; + } + + spin_lock_init(&pHddCtx->filter_lock); + if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER == + pHddCtx->cfg_ini->nEnableSuspend) + { + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + { + pmcRegisterDeviceStateUpdateInd(smeContext, + hdd_PowerStateChangedCB, pHddCtx); + } + /* TODO: For Power Save Offload case */ + } +} + +void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx) +{ + v_CONTEXT_t pVosContext; + tHalHandle smeContext; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL == pVosContext) + { + hddLog(LOGE, "%s: Invalid pContext", __func__); + return; + } + smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext); + if (NULL == smeContext) + { + hddLog(LOGE, "%s: Invalid smeContext", __func__); + return; + } + + if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER == + pHddCtx->cfg_ini->nEnableSuspend) + { + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + { + pmcDeregisterDeviceStateUpdateInd(smeContext, + hdd_PowerStateChangedCB); + } + /* TODO: For Power Save Offload case */ + } +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable) +{ + eHalStatus ret; + tSirGtkOffloadParams hddGtkOffloadReqParams; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if(fenable) + { + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags )) + { + vos_mem_copy(&hddGtkOffloadReqParams, + &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + + ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + &hddGtkOffloadReqParams, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SetGTKOffload failed, returned %d", + __func__, ret); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_SetGTKOffload successful", __func__); + } + + } + else + { + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId, + &pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE)) && + (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags)) + { + + /* Host driver has previously offloaded GTK rekey */ + ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlan_hdd_cfg80211_update_replayCounterCallback, + pAdapter, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_GetGTKOffload failed, returned %d", + __func__, ret); + return; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_GetGTKOffload successful", + __func__); + + /* Sending GTK offload disable */ + memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + &hddGtkOffloadReqParams, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to disable GTK offload, returned %d", + __func__, ret); + return; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: successfully disabled GTK offload request to HAL", + __func__); + } + } + } + return; +} +#endif /*WLAN_FEATURE_GTK_OFFLOAD*/ + +void hdd_resume_wlan(void) +{ + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_CONTEXT_t pVosContext = NULL; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return; + } + + if (pHddCtx->isLogpInProgress) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Ignore resume wlan, LOGP in progress!", __func__); + return; + } + + pHddCtx->hdd_wlan_suspended = FALSE; + + /*loop through all adapters. Concurrency */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_SOFTAP != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + { + goto send_resume_ind; + } + + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__); + hdd_exit_deep_sleep(pAdapter); + } +#endif + + if(pHddCtx->hdd_ignore_dtim_enabled == TRUE) + { + /*Switch back to DTIM 1*/ + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + /*Disabled ModulatedDTIM if enabled on suspend*/ + if(pHddCtx->cfg_ini->enableModulatedDTIM) + powerRequest.uDTIMPeriod = 0; + + /* Update ignoreDTIM and ListedInterval in CFG with default values */ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM%d",powerRequest.uListenInterval); + sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE); + + if (BMPS == pmcGetPmcState(pHddCtx->hHal)) + { + /* put the device into full power */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + + /* put the device back into BMPS */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + + pHddCtx->hdd_ignore_dtim_enabled = FALSE; + } + } + +send_resume_ind: + //wake the tx queues + hddLog(LOG1, FL("Enabling queues")); + WLANTL_PauseUnPauseQs(pVosContext, false); + + netif_tx_wake_all_queues(pAdapter->dev); + + hdd_conf_resume_ind(pAdapter); + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + +#ifdef IPA_OFFLOAD + hdd_ipa_resume(pHddCtx); +#endif + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY) + { + hdd_exit_standby(pHddCtx); + } +#endif + + return; +} + +VOS_STATUS hdd_wlan_reset_initialization(void) +{ + v_CONTEXT_t pVosContext = NULL; + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__); + + // Prevent the phone from going to sleep + hdd_prevent_suspend(); + + return VOS_STATUS_SUCCESS; +} + + +/* + * Based on the ioctl command received by HDD, put WLAN driver + * into the quiet mode. This is the same as the early suspend + * notification that driver used to listen + */ +void hdd_set_wlan_suspend_mode(bool suspend) +{ + vos_ssr_protect(__func__); + if (suspend) + hdd_suspend_wlan(NULL, NULL); + else + hdd_resume_wlan(); + vos_ssr_unprotect(__func__); +} + +static void hdd_ssr_timer_init(void) +{ + init_timer(&ssr_timer); +} + +static void hdd_ssr_timer_del(void) +{ + del_timer(&ssr_timer); + ssr_timer_started = false; +} + +static void hdd_ssr_timer_cb(unsigned long data) +{ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired!", __func__); + VOS_BUG(0); +} + +static void hdd_ssr_timer_start(int msec) +{ + if(ssr_timer_started) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Trying to start SSR timer when " + "it's running!", __func__); + } + ssr_timer.expires = jiffies + msecs_to_jiffies(msec); + ssr_timer.function = hdd_ssr_timer_cb; + add_timer(&ssr_timer); + ssr_timer_started = true; +} + +/* the HDD interface to WLAN driver shutdown, + * the primary shutdown function in SSR + */ +VOS_STATUS hdd_wlan_shutdown(void) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + pVosSchedContext vosSchedContext = NULL; + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__); + +#ifdef WLAN_FEATURE_LPSS + wlan_hdd_send_status_pkg(NULL, NULL, 0, 0); +#endif + + /* If SSR never completes, then do kernel panic. */ + hdd_ssr_timer_init(); + hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME); + + /* Get the global VOSS context. */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + /* Get the HDD context. */ + pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx->isLogpInProgress = TRUE; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + vos_clear_concurrent_session_count(); + //Stop the traffic monitor timer + if ( VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)) + { + vos_timer_stop(&pHddCtx->tx_rx_trafficTmr); + } + + hdd_reset_all_adapters(pHddCtx); + + vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__); + } + + /* Disable IMPS/BMPS as we do not want the device to enter any power + * save mode on its own during reset sequence + */ + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE); + + vosSchedContext = get_vos_sched_ctxt(); + + /* Wakeup all driver threads */ + if(TRUE == pHddCtx->isMcThreadSuspended){ + complete(&vosSchedContext->ResumeMcEvent); + pHddCtx->isMcThreadSuspended= FALSE; + } + if(TRUE == pHddCtx->isTxThreadSuspended){ + complete(&vosSchedContext->ResumeTxEvent); + pHddCtx->isTxThreadSuspended= FALSE; + } + if(TRUE == pHddCtx->isRxThreadSuspended){ + complete(&vosSchedContext->ResumeRxEvent); + pHddCtx->isRxThreadSuspended= FALSE; + } +#ifdef QCA_CONFIG_SMP + if (TRUE == pHddCtx->isTlshimRxThreadSuspended) { + complete(&vosSchedContext->ResumeTlshimRxEvent); + pHddCtx->isTlshimRxThreadSuspended = FALSE; + } +#endif + + /* Reset the Suspend Variable */ + pHddCtx->isWlanSuspended = FALSE; + + /* Stop all the threads; we do not want any messages to be a processed, + * any more and the best way to ensure that is to terminate the threads + * gracefully. + */ + /* Wait for MC to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__); + set_bit(MC_SHUTDOWN_EVENT_MASK, &vosSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT_MASK, &vosSchedContext->mcEventFlag); + wake_up_interruptible(&vosSchedContext->mcWaitQueue); + wait_for_completion(&vosSchedContext->McShutdown); + + /* Wait for TX to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__); + set_bit(TX_SHUTDOWN_EVENT_MASK, &vosSchedContext->txEventFlag); + set_bit(TX_POST_EVENT_MASK, &vosSchedContext->txEventFlag); + wake_up_interruptible(&vosSchedContext->txWaitQueue); + wait_for_completion(&vosSchedContext->TxShutdown); + + /* Wait for RX to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__); + set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->rxEventFlag); + set_bit(RX_POST_EVENT_MASK, &vosSchedContext->rxEventFlag); + wake_up_interruptible(&vosSchedContext->rxWaitQueue); + wait_for_completion(&vosSchedContext->RxShutdown); + +#ifdef QCA_CONFIG_SMP + /* Wait for TLshim RX to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TLshim RX thread", + __func__); + unregister_hotcpu_notifier(vosSchedContext->cpuHotPlugNotifier); + set_bit(RX_SHUTDOWN_EVENT_MASK, &vosSchedContext->tlshimRxEvtFlg); + set_bit(RX_POST_EVENT_MASK, &vosSchedContext->tlshimRxEvtFlg); + wake_up_interruptible(&vosSchedContext->tlshimRxWaitQueue); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for TLshim RX thread to exit", + __func__); + wait_for_completion(&vosSchedContext->TlshimRxShutdown); + vosSchedContext->TlshimRxThread = NULL; + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for dropping RX packets", + __func__); + vos_drop_rxpkt_by_staid(vosSchedContext, WLAN_MAX_STA_COUNT); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Waiting for freeing freeQ", __func__); + vos_free_tlshim_pkt_freeq(vosSchedContext); +#endif + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop BAP",__func__); + } +#endif //WLAN_BTAMP_FEATURE + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing WDA STOP", __func__); + vosStatus = WDA_stop(pVosContext, HAL_STOP_TYPE_RF_KILL); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + WDA_setNeedShutdown(pVosContext); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__); + /* Stop SME - Cannot invoke vos_stop as vos_stop relies + * on threads being running to process the SYS Stop + */ + vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop sme %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__); + /* Stop MAC (PE and HAL) */ + vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop mac %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__); + /* Stop TL */ + vosStatus = WLANTL_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop TL %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hif_disable_isr(((VosContextType*)pVosContext)->pHIFContext); + + hdd_unregister_mcast_bcast_filter(pHddCtx); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__); + /* Clean up message queues of TX, RX and MC thread */ + vos_sched_flush_mc_mqs(vosSchedContext); + vos_sched_flush_tx_mqs(vosSchedContext); + vos_sched_flush_rx_mqs(vosSchedContext); + + /* Deinit all the TX, RX and MC queues */ + vos_sched_deinit_mqs(vosSchedContext); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__); + /* shutdown VOSS */ + vos_shutdown(pVosContext); + + /*mac context has already been released in mac_close call + so setting it to NULL in hdd context*/ + pHddCtx->hHal = (tHalHandle)NULL; + + if (free_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock", + __func__); + } + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete" + ,__func__); + return VOS_STATUS_SUCCESS; +} + + + +/* the HDD interface to WLAN driver re-init. + * This is called to initialize/start WLAN driver after a shutdown. + */ +VOS_STATUS hdd_wlan_re_init(void *hif_sc) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + eHalStatus halStatus; +#ifdef WLAN_BTAMP_FEATURE + hdd_config_t *pConfig = NULL; + WLANBAP_ConfigType btAmpConfig; +#endif + + hdd_adapter_t *pAdapter; + int i; + hdd_prevent_suspend(); + + + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + /* Get the VOS context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(pVosContext == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed vos_get_global_context", + __func__); + goto err_re_init; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if(!pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); + goto err_re_init; + } + + if (!hif_sc) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hif_sc is NULL", __func__); + goto err_re_init; + } + + ((VosContextType*)pVosContext)->pHIFContext = hif_sc; + + /* The driver should always be initialized in STA mode after SSR */ + hdd_set_conparam(0); + + /* Re-open VOSS, it is a re-open b'se control transport was never closed. */ + vosStatus = vos_open(&pVosContext, 0); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__); + goto err_re_init; + } + +#if !defined(REMOVE_PKT_LOG) + hif_init_pdev_txrx_handle(hif_sc, + vos_get_context(VOS_MODULE_ID_TXRX, pVosContext)); +#endif + + /* Save the hal context in Adapter */ + pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext ); + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__); + goto err_vosclose; + } + + /* Set the SME configuration parameters. */ + vosStatus = hdd_set_sme_config(pHddCtx); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__); + goto err_vosclose; + } + + vosStatus = vos_preStart( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__); + goto err_vosclose; + } + + vosStatus = hdd_set_sme_chan_list(pHddCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to init channel list", __func__); + goto err_vosclose; + } + + /* In the integrated architecture we update the configuration from + the INI file and from NV before vOSS has been started so that + the final contents are available to send down to the cCPU */ + /* Apply the cfg.ini to cfg.dat */ + if (FALSE == hdd_update_config_dat(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ ); + goto err_vosclose; + } + + /* Set the MAC Address, currently this is used by HAL to add self sta. + * Remove this once self sta is added as part of session open. */ + halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID, + (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0], + sizeof(pHddCtx->cfg_ini->intfMacAddr[0])); + if (!HAL_STATUS_SUCCESS(halStatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. " + "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus); + goto err_vosclose; + } + + /* Start VOSS which starts up the SME/MAC/HAL modules and everything else + Note: Firmware image will be read and downloaded inside vos_start API */ + vosStatus = vos_start( pVosContext ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); + goto err_vosclose; + } + + vosStatus = hdd_post_voss_start_config( pHddCtx ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed", + __func__); + goto err_vosstop; + } + + /* Try to get an adapter from mode ID */ + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (!pAdapter) { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (!pAdapter) { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS); + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to get Adapter!", + __func__); + } + } + } + + /* Get WLAN Host/FW/HW version */ + if (pAdapter) + hdd_wlan_get_version(pAdapter, NULL, NULL); + + /* Pass FW version to HIF layer */ + hif_set_fw_info(hif_sc, pHddCtx->target_fw_version); + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Open(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open BAP",__func__); + goto err_vosstop; + } + vosStatus = BSL_Init(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Init BSL",__func__); + goto err_bap_close; + } + vosStatus = WLANBAP_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start TL",__func__); + goto err_bap_close; + } + pConfig = pHddCtx->cfg_ini; + btAmpConfig.ucPreferredChannel = pConfig->preferredChannel; + vosStatus = WLANBAP_SetConfig(&btAmpConfig); +#endif //WLAN_BTAMP_FEATURE + + /* Restart all adapters */ + hdd_start_all_adapters(pHddCtx); + + /* Reconfigure FW logs after SSR */ + if (pAdapter) { + if (pHddCtx->fw_log_settings.enable != 0) { + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_MODULE_ENABLE, + pHddCtx->fw_log_settings.enable , DBG_CMD); + } else { + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_MODULE_DISABLE, + pHddCtx->fw_log_settings.enable, DBG_CMD); + } + + if (pHddCtx->fw_log_settings.dl_report != 0) { + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_REPORT_ENABLE, + pHddCtx->fw_log_settings.dl_report, DBG_CMD); + + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_TYPE, + pHddCtx->fw_log_settings.dl_type, DBG_CMD); + + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_LOG_LEVEL, + pHddCtx->fw_log_settings.dl_loglevel, DBG_CMD); + + for (i = 0; i < MAX_MOD_LOGLEVEL; i++) { + if (pHddCtx->fw_log_settings.dl_mod_loglevel[i] != 0) { + process_wma_set_command(pAdapter->sessionId, + WMI_DBGLOG_MOD_LOG_LEVEL, + pHddCtx->fw_log_settings.dl_mod_loglevel[i], + DBG_CMD); + } + } + } + } + + pHddCtx->isLogpInProgress = FALSE; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + hdd_register_mcast_bcast_filter(pHddCtx); + hdd_ssr_timer_del(); + + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_FW_CRASHED_IND, NULL, 0); + + /* Allow the phone to go to sleep */ + hdd_allow_suspend(); + /* register for riva power on lock */ + if (req_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed", + __func__); + goto err_unregister_pmops; + } + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + +#ifdef WLAN_FEATURE_LPSS + wlan_hdd_send_all_scan_intf_info(pHddCtx); + wlan_hdd_send_version_pkg(pHddCtx->target_fw_version, + pHddCtx->target_hw_version, + pHddCtx->target_hw_name); +#endif + goto success; + +err_unregister_pmops: +#ifdef CONFIG_HAS_EARLYSUSPEND + hdd_unregister_mcast_bcast_filter(pHddCtx); +#endif + hdd_close_all_adapters(pHddCtx); +#ifdef WLAN_BTAMP_FEATURE + WLANBAP_Stop(pVosContext); +#endif + +#ifdef WLAN_BTAMP_FEATURE +err_bap_close: + WLANBAP_Close(pVosContext); +#endif + +err_vosstop: + vos_stop(pVosContext); + +err_vosclose: + vos_close(pVosContext); + vos_sched_close(pVosContext); + if (pHddCtx) + { + /* Unregister the Net Device Notifier */ + unregister_netdevice_notifier(&hdd_netdev_notifier); + /* Clean up HDD Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); +#ifdef WLAN_KD_READY_NOTIFIER + cnss_diag_notify_wlan_close(); + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ + /* Free up dynamically allocated members inside HDD Adapter */ + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + + wiphy_unregister(pHddCtx->wiphy); + wiphy_free(pHddCtx->wiphy); + } + vos_preClose(&pVosContext); + +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + +err_re_init: + /* Allow the phone to go to sleep */ + hdd_allow_suspend(); + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + VOS_BUG(0); + return -EPERM; + +success: + /* Trigger replay of BTC events */ + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ftm.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ftm.c new file mode 100644 index 0000000000000..b97966163c943 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ftm.c @@ -0,0 +1,1160 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_ftm.c + + \brief This file contains the WLAN factory test mode implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 07/18/14 kanand Cleanup. Remove legacy Prima code and retain support for Rome only + 04/20/11 Leo/Henri Convergence for Prima and Volans. Single image for FTM and mission mode + 04/05/09 Shailender Created module. + + ==========================================================================*/ +#include +#include "vos_sched.h" +#include +#include "sirTypes.h" +#include "halTypes.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sme_Api.h" +#include "macInitApi.h" +#include "wlan_qct_sys.h" +#include "wlan_qct_tl.h" +#include "wlan_hdd_misc.h" +#include "i_vos_packet.h" +#include "vos_nvitem.h" +#include "wlan_hdd_main.h" +#include "qwlan_version.h" +#include "wlan_nv.h" +#include "wlan_qct_wda.h" +#include "cfgApi.h" +#include "wlan_qct_pal_device.h" + +#if defined(QCA_WIFI_FTM) +#include "bmi.h" +#include "ol_fw.h" +#include "testmode.h" +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_main.h" +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#include +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +#endif + +static int wlan_ftm_stop(hdd_context_t *pHddCtx); +static int hdd_ftm_service_registration(hdd_context_t *pHddCtx); + +#if defined(QCA_WIFI_FTM) +#if defined(LINUX_QCMBR) +#define ATH_XIOCTL_UNIFIED_UTF_CMD 0x1000 +#define ATH_XIOCTL_UNIFIED_UTF_RSP 0x1001 +#define MAX_UTF_LENGTH 1024 +typedef struct qcmbr_data_s { + unsigned int cmd; + unsigned int length; + unsigned char buf[MAX_UTF_LENGTH + 4]; + unsigned int copy_to_user; +} qcmbr_data_t; +typedef struct qcmbr_queue_s { + unsigned char utf_buf[MAX_UTF_LENGTH + 4]; + struct list_head list; +} qcmbr_queue_t; +LIST_HEAD(qcmbr_queue_head); +DEFINE_SPINLOCK(qcmbr_queue_lock); +#endif +#endif + + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_postmsg() - + + The function used for sending the command to the halphy. + + \param - cmd_ptr - Pointer command buffer. + + \param - cmd_len - Command length. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static v_U32_t wlan_ftm_postmsg(v_U8_t *cmd_ptr, v_U16_t cmd_len) +{ + vos_msg_t *ftmReqMsg; + vos_msg_t ftmMsg; + ENTER(); + + ftmReqMsg = (vos_msg_t *) cmd_ptr; + + ftmMsg.type = WDA_FTM_CMD_REQ; + ftmMsg.reserved = 0; + ftmMsg.bodyptr = (v_U8_t*)cmd_ptr; + ftmMsg.bodyval = 0; + + /* Use Vos messaging mechanism to send the command to halPhy */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message( + VOS_MODULE_ID_WDA, + (vos_msg_t *)&ftmMsg)) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL", __func__); + + return VOS_STATUS_E_FAILURE; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +void wlan_hdd_ftm_update_tgt_cfg(void *context, void *param) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)context; + struct hdd_tgt_cfg *cfg = (struct hdd_tgt_cfg *)param; + + if (!vos_is_macaddr_zero(&cfg->hw_macaddr)) { + hdd_update_macaddr(hdd_ctx->cfg_ini, cfg->hw_macaddr); + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid MAC passed from target, using MAC from ini file" + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(hdd_ctx->cfg_ini->intfMacAddr[0].bytes)); + } +} + +/*--------------------------------------------------------------------------- + + \brief wlan_ftm_vos_open() - Open the vOSS Module + + The \a wlan_ftm_vos_open() function opens the vOSS Scheduler + Upon successful initialization: + + - All VOS submodules should have been initialized + + - The VOS scheduler should have opened + + - All the WLAN SW components should have been opened. This include + MAC. + + + \param hddContextSize: Size of the HDD context to allocate. + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa wlan_ftm_vos_open() + +---------------------------------------------------------------------------*/ +static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_SIZE_t hddContextSize ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int iter = 0; + tSirRetStatus sirStatus = eSIR_SUCCESS; + tMacOpenParameters macOpenParms; + pVosContextType gpVosContext = (pVosContextType)pVosContext; +#if defined(QCA_WIFI_FTM) + adf_os_device_t adf_ctx; + HTC_INIT_INFO htcInfo; + v_PVOID_t pHifContext = NULL; + v_PVOID_t pHtcContext = NULL; +#endif + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + if (NULL == gpVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to open VOSS without a PreOpen",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Initialize the probe event */ + if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init probeEvent",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + if(vos_event_init(&(gpVosContext->wdaCompleteEvent)) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init wdaCompleteEvent",__func__); + VOS_ASSERT(0); + + goto err_probe_event; + } + + /* Initialize the free message queue */ + vStatus = vos_mq_init(&gpVosContext->freeVosMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize VOS free message queue %d", + __func__, vStatus); + VOS_ASSERT(0); + goto err_wda_complete_event; + } + + for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++) + { + (gpVosContext->aMsgWrappers[iter]).pVosMsg = + &(gpVosContext->aMsgBuffers[iter]); + INIT_LIST_HEAD(&gpVosContext->aMsgWrappers[iter].msgNode); + vos_mq_put(&gpVosContext->freeVosMq, &(gpVosContext->aMsgWrappers[iter])); + } + + /* Now Open the VOS Scheduler */ + vStatus= vos_sched_open(gpVosContext, &gpVosContext->vosSched, + sizeof(VosSchedContext)); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open VOS Scheduler %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_msg_queue; + } + +#if defined(QCA_WIFI_FTM) + /* Initialize BMI and Download firmware */ + pHifContext = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext); + if (!pHifContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: failed to get HIF context", __func__); + goto err_sched_close; + } + + if (bmi_download_firmware(pHifContext)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: BMI failed to download target", __func__); + goto err_bmi_close; + } + htcInfo.pContext = gpVosContext->pHIFContext; + htcInfo.TargetFailure = ol_target_failure; + htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge; + adf_ctx = vos_get_context(VOS_MODULE_ID_ADF, gpVosContext); + + /* Create HTC */ + gpVosContext->htc_ctx = HTCCreate(htcInfo.pContext, &htcInfo, adf_ctx); + if (!gpVosContext->htc_ctx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to Create HTC", __func__); + goto err_bmi_close; + goto err_sched_close; + } + + if (bmi_done(pHifContext)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto err_htc_close; + } +#endif /* QCA_WIFI_FTM */ + + /* Open the SYS module */ + vStatus = sysOpen(gpVosContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open SYS module %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_sched_close; + } + + /*Open the WDA module */ + vos_mem_set(&macOpenParms, sizeof(macOpenParms), 0); + macOpenParms.driverType = eDRIVER_TYPE_MFG; + + pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext); + if((NULL == pHddCtx) || + (NULL == pHddCtx->cfg_ini)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Hdd Context is Null", __func__); + VOS_ASSERT(0); + goto err_sys_close; + } + + macOpenParms.powersaveOffloadEnabled = + pHddCtx->cfg_ini->enablePowersaveOffload; + vStatus = WDA_open(gpVosContext, gpVosContext->pHDDContext, + wlan_hdd_ftm_update_tgt_cfg, NULL, + &macOpenParms); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open WDA module %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_sys_close; + } + +#if defined(QCA_WIFI_FTM) + pHtcContext = vos_get_context(VOS_MODULE_ID_HTC, gpVosContext); + if (!pHtcContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: failed to get HTC context", __func__); + goto err_wda_close; + } + if (HTCWaitTarget(pHtcContext)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto err_wda_close; + } +#endif + + /* initialize the NV module */ + vStatus = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + // NV module cannot be initialized, however the driver is allowed + // to proceed + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize the NV module %d", __func__, vStatus); + goto err_wda_close; + } + + /* If we arrive here, both threads dispatching messages correctly */ + + /* Now proceed to open the MAC */ + + /* UMA is supported in hardware for performing the + frame translation 802.11 <-> 802.3 */ + macOpenParms.frameTransRequired = 1; + + sirStatus = macOpen(&(gpVosContext->pMACContext), gpVosContext->pHDDContext, + &macOpenParms); + + if (eSIR_SUCCESS != sirStatus) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open MAC %d", __func__, sirStatus); + VOS_ASSERT(0); + goto err_nv_close; + } + +#ifndef QCA_WIFI_FTM + /* Now proceed to open the SME */ + vStatus = sme_Open(gpVosContext->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open SME %d", __func__, vStatus); + goto err_mac_close; + } + + vStatus = sme_init_chan_list(gpVosContext->pMACContext, + pHddCtx->reg.alpha2, pHddCtx->reg.cc_src); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init sme channel list", __func__); + } else { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS successfully Opened", __func__); + return VOS_STATUS_SUCCESS; + } +#else + return VOS_STATUS_SUCCESS; +#endif + +#ifndef QCA_WIFI_FTM +err_mac_close: +#endif + macClose(gpVosContext->pMACContext); + +err_nv_close: + vos_nv_close(); + +err_wda_close: + WDA_close(gpVosContext); + +err_sys_close: + sysClose(gpVosContext); + +#if defined(QCA_WIFI_FTM) +err_htc_close: + if (gpVosContext->htc_ctx) { + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; + } + +err_bmi_close: + BMICleanup(pHifContext); +#endif /* QCA_WIFI_FTM */ + +err_sched_close: + vos_sched_close(gpVosContext); +err_msg_queue: + vos_mq_deinit(&gpVosContext->freeVosMq); + +err_wda_complete_event: + vos_event_destroy(&gpVosContext->wdaCompleteEvent); + +err_probe_event: + vos_event_destroy(&gpVosContext->ProbeEvent); + + return VOS_STATUS_E_FAILURE; + +} /* wlan_ftm_vos_open() */ + +/*--------------------------------------------------------------------------- + + \brief wlan_ftm_vos_close() - Close the vOSS Module + + The \a wlan_ftm_vos_close() function closes the vOSS Module + + \param vosContext context of vos + + \return VOS_STATUS_SUCCESS - successfully closed + + \sa wlan_ftm_vos_close() + +---------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_vos_close( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + pVosContextType gpVosContext = (pVosContextType)vosContext; + +#ifndef QCA_WIFI_FTM + vosStatus = sme_Close(((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = WDA_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close WDA %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + +#if defined(QCA_WIFI_FTM) + if (gpVosContext->htc_ctx) + { + HTCStop(gpVosContext->htc_ctx); + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; + } + vosStatus = wma_wmi_service_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close wma_wmi_service", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + hif_disable_isr(gpVosContext->pHIFContext); +#endif + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy ProbeEvent %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy wdaCompleteEvent %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief vos_ftm_preStart() - + + The \a vos_ftm_preStart() function to download CFG. + including: + - ccmStart + + - WDA: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_start + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_ftm_preStart( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; +#if defined(QCA_WIFI_FTM) + pVosContextType gpVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, + NULL); +#endif + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "vos prestart"); + if (NULL == pVosContext->pWDAContext) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* call macPreStart */ + vStatus = macPreStart(pVosContext->pMACContext); + if ( !VOS_IS_STATUS_SUCCESS(vStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed at macPreStart "); + return VOS_STATUS_E_FAILURE; + } + + /* call ccmStart */ + ccmStart(pVosContext->pMACContext); + + /* Reset wda wait event */ + vos_event_reset(&pVosContext->wdaCompleteEvent); + + + /*call WDA pre start*/ + vStatus = WDA_preStart(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to WDA prestart "); + ccmStop(pVosContext->pMACContext); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Need to update time out of complete */ + vStatus = vos_wait_single_event( &pVosContext->wdaCompleteEvent, 1000); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_preStart reporting other error", __func__); + } + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + +#if defined(QCA_WIFI_FTM) + vStatus = HTCStart(gpVosContext->htc_ctx); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed to Start HTC"); + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + wma_wait_for_ready_event(gpVosContext->pWDAContext); +#endif /* QCA_WIFI_FTM */ + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_open() - + + The function hdd_wlan_startup calls this function to initialize the FTM specific modules. + + \param - pAdapter - Pointer HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +int wlan_hdd_ftm_open(hdd_context_t *pHddCtx) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext= NULL; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to open VOSS without a PreOpen", __func__); + VOS_ASSERT(0); + goto err_vos_status_failure; + } + + vStatus = wlan_ftm_vos_open( pVosContext, 0); + + if ( !VOS_IS_STATUS_SUCCESS( vStatus )) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed", __func__); + goto err_vos_status_failure; + } + + /* + * For Integrated SOC, only needed to start WDA, + * which happens in wlan_hdd_ftm_start() + */ + /* Save the hal context in Adapter */ + pHddCtx->hHal = (tHalHandle)vos_get_context(VOS_MODULE_ID_SME, pVosContext ); + + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: HAL context is null", __func__); + goto err_ftm_close; + } + + return VOS_STATUS_SUCCESS; + +err_ftm_close: + wlan_ftm_vos_close(pVosContext); + +err_vos_status_failure: + return VOS_STATUS_E_FAILURE; +} + +static int hdd_ftm_service_registration(hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pAdapter; + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_FTM, "wlan%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed", __func__); + goto err_adapter_open_failure; + } + + /* Initialize the ftm vos event */ + if (vos_event_init(&pHddCtx->ftm.ftm_vos_event) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init probeEvent", __func__); + VOS_ASSERT(0); + goto err_adapter_close; + } + + pHddCtx->ftm.ftm_state = WLAN_FTM_INITIALIZED; + + return VOS_STATUS_SUCCESS; + +err_adapter_close: +hdd_close_all_adapters( pHddCtx ); + +err_adapter_open_failure: + + return VOS_STATUS_E_FAILURE; +} + + + +int wlan_hdd_ftm_close(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t vosContext = pHddCtx->pvosContext; + + hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_FTM); + ENTER(); + if(pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__); + return VOS_STATUS_E_NOMEM; + } + + if (pHddCtx->ftm.IsCmdPending == TRUE) + { + if (vos_event_set(&pHddCtx->ftm.ftm_vos_event)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + } + } + + if(WLAN_FTM_STARTED == pHddCtx->ftm.ftm_state) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Ftm has been started. stopping ftm", __func__); + wlan_ftm_stop(pHddCtx); + } + + hdd_close_all_adapters( pHddCtx ); + + vosStatus = vos_sched_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close VOSS Scheduler",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + //Close VOSS + wlan_ftm_vos_close(vosContext); + + + vosStatus = vos_event_destroy(&pHddCtx->ftm.ftm_vos_event); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy ftm_vos Event",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + +#if defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR) + spin_lock_bh(&qcmbr_queue_lock); + if (!list_empty(&qcmbr_queue_head)) { + qcmbr_queue_t *msg_buf, *tmp_buf; + list_for_each_entry_safe(msg_buf, tmp_buf, &qcmbr_queue_head, list) { + list_del(&msg_buf->list); + kfree(msg_buf); + } + } + spin_unlock_bh(&qcmbr_queue_lock); +#endif + + return 0; + +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_start() - + + This function starts the following modules. + 1) WDA Start. + 2) HTC Start. + 3) MAC Start to download the firmware. + + + \param - pAdapter - Pointer HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int wlan_hdd_ftm_start(hdd_context_t *pHddCtx) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)(pHddCtx->pvosContext); + + if (WLAN_FTM_STARTED == pHddCtx->ftm.ftm_state) + { + return VOS_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Starting CLD SW", __func__); + + /* We support only one instance for now ...*/ + if (pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: mismatch in context",__func__); + goto err_status_failure; + } + + + if (pVosContext->pMACContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context",__func__); + goto err_status_failure; + } + + /* Vos preStart is calling */ + if ( !VOS_IS_STATUS_SUCCESS(vos_ftm_preStart(pHddCtx->pvosContext) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__); + goto err_status_failure; + } + + + + vStatus = WDA_start(pVosContext); + if (vStatus != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start WDA",__func__); + goto err_status_failure; + } + + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: MAC correctly started",__func__); + + if (hdd_ftm_service_registration(pHddCtx)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed", __func__); + goto err_ftm_service_reg; + } + + pHddCtx->ftm.ftm_state = WLAN_FTM_STARTED; + + return VOS_STATUS_SUCCESS; + +err_ftm_service_reg: + wlan_hdd_ftm_close(pHddCtx); + + +err_status_failure: + + return VOS_STATUS_E_FAILURE; + +} + +#if defined(QCA_WIFI_FTM) +int hdd_ftm_start(hdd_context_t *pHddCtx) +{ + return wlan_hdd_ftm_start(pHddCtx); +} +#endif + +static int wlan_ftm_stop(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus; + + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + { + /* STOP MAC only */ + v_VOID_t *hHal; + hHal = vos_get_context( VOS_MODULE_ID_SME, pHddCtx->pvosContext ); + if (NULL == hHal) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL hHal", __func__); + } else { + vosStatus = macStop(hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + WDA_stop(pHddCtx->pvosContext, HAL_STOP_TYPE_RF_KILL); + } + return WLAN_FTM_SUCCESS; +} + +#if defined(QCA_WIFI_FTM) +int hdd_ftm_stop(hdd_context_t *pHddCtx) +{ + return wlan_ftm_stop(pHddCtx); +} +#endif + +#if defined(QCA_WIFI_FTM) +#if defined(LINUX_QCMBR) +static int wlan_hdd_qcmbr_command(hdd_adapter_t *pAdapter, qcmbr_data_t *pqcmbr_data) +{ + int ret = 0; + qcmbr_queue_t *qcmbr_buf = NULL; + + switch (pqcmbr_data->cmd) { + case ATH_XIOCTL_UNIFIED_UTF_CMD: { + pqcmbr_data->copy_to_user = 0; + if (pqcmbr_data->length) { + if (wlan_hdd_ftm_testmode_cmd(pqcmbr_data->buf, + pqcmbr_data->length) + != VOS_STATUS_SUCCESS) { + ret = -EBUSY; + } else { + ret = 0; + } + } + } + break; + + case ATH_XIOCTL_UNIFIED_UTF_RSP: { + pqcmbr_data->copy_to_user = 1; + if (!list_empty(&qcmbr_queue_head)) { + spin_lock_bh(&qcmbr_queue_lock); + qcmbr_buf = list_first_entry(&qcmbr_queue_head, + qcmbr_queue_t, list); + list_del(&qcmbr_buf->list); + spin_unlock_bh(&qcmbr_queue_lock); + ret = 0; + } else { + ret = -1; + } + + if (!ret) { + memcpy(pqcmbr_data->buf, qcmbr_buf->utf_buf, + (MAX_UTF_LENGTH + 4)); + kfree(qcmbr_buf); + } else { + ret = -EAGAIN; + } + } + break; + } + + return ret; +} + +#ifdef CONFIG_COMPAT +static int wlan_hdd_qcmbr_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + qcmbr_data_t *qcmbr_data; + int ret = 0; + + qcmbr_data = kzalloc(sizeof(qcmbr_data_t), GFP_KERNEL); + if (qcmbr_data == NULL) + return -ENOMEM; + + if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) { + ret = -EFAULT; + goto exit; + } + + ret = wlan_hdd_qcmbr_command(pAdapter, qcmbr_data); + if (qcmbr_data->copy_to_user) { + ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf, + (MAX_UTF_LENGTH + 4)); + } + +exit: + kfree(qcmbr_data); + return ret; +} +#else /* CONFIG_COMPAT */ +static int wlan_hdd_qcmbr_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + return 0; +} +#endif /* CONFIG_COMPAT */ + +static int wlan_hdd_qcmbr_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + qcmbr_data_t *qcmbr_data; + int ret = 0; + + qcmbr_data = kzalloc(sizeof(qcmbr_data_t), GFP_KERNEL); + if (qcmbr_data == NULL) + return -ENOMEM; + + if (copy_from_user(qcmbr_data, ifr->ifr_data, sizeof(*qcmbr_data))) { + ret = -EFAULT; + goto exit; + } + + ret = wlan_hdd_qcmbr_command(pAdapter, qcmbr_data); + if (qcmbr_data->copy_to_user) { + ret = copy_to_user(ifr->ifr_data, qcmbr_data->buf, + (MAX_UTF_LENGTH + 4)); + } + +exit: + kfree(qcmbr_data); + return ret; +} + +int wlan_hdd_qcmbr_unified_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + int ret = 0; + + if (is_compat_task()) { + ret = wlan_hdd_qcmbr_compat_ioctl(pAdapter, ifr); + } else { + ret = wlan_hdd_qcmbr_ioctl(pAdapter, ifr); + } + + return ret; +} + +static void WLANQCMBR_McProcessMsg(v_VOID_t *message) +{ + qcmbr_queue_t *qcmbr_buf = NULL; + u_int32_t data_len; + + data_len = *((u_int32_t *)message) + sizeof(u_int32_t); + qcmbr_buf = kzalloc(sizeof(qcmbr_queue_t), GFP_KERNEL); + if (qcmbr_buf != NULL) { + memcpy(qcmbr_buf->utf_buf, message, data_len); + spin_lock_bh(&qcmbr_queue_lock); + list_add_tail(&(qcmbr_buf->list), &qcmbr_queue_head); + spin_unlock_bh(&qcmbr_queue_lock); + } +} +#endif /*LINUX_QCMBR*/ + +VOS_STATUS WLANFTM_McProcessMsg (v_VOID_t *message) +{ + void *data; + u_int32_t data_len; + + if (!message) + return VOS_STATUS_E_INVAL; + + data_len = *((u_int32_t *)message); + data = (u_int32_t *)message + 1; + +#if defined(LINUX_QCMBR) + WLANQCMBR_McProcessMsg(message); +#else +#ifdef CONFIG_NL80211_TESTMODE + wlan_hdd_testmode_rx_event(data, (size_t)data_len); +#endif +#endif + + vos_mem_free(message); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_ftm_testmode_cmd(void *data, int len) +{ + struct ar6k_testmode_cmd_data *cmd_data; + + cmd_data = (struct ar6k_testmode_cmd_data *) + vos_mem_malloc(sizeof(*cmd_data)); + + if (!cmd_data) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Failed to allocate FTM command data")); + return VOS_STATUS_E_NOMEM; + } + + cmd_data->data = vos_mem_malloc(len); + + if (!cmd_data->data) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Failed to allocate FTM command data buffer")); + vos_mem_free(cmd_data); + return VOS_STATUS_E_NOMEM; + } + + cmd_data->len = len; + vos_mem_copy(cmd_data->data, data, len); + + if (wlan_ftm_postmsg((v_U8_t *)cmd_data, sizeof(*cmd_data))) { + vos_mem_free(cmd_data->data); + vos_mem_free(cmd_data); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} +#endif /*QCA_WIFI_FTM*/ diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c new file mode 100644 index 0000000000000..238df71027a03 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c @@ -0,0 +1,5206 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_hostapd.c + \brief WLAN Host Device Driver implementation + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure + ==========================================================================*/ +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" +#include +#include "wlan_hdd_p2p.h" +#ifdef IPA_OFFLOAD +#include +#endif +#include "cfgApi.h" +#include "wniCfgAp.h" +#include "wlan_hdd_misc.h" +#ifdef FEATURE_WLAN_FORCE_SAP_SCC +#include +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ +#if defined CONFIG_CNSS +#include +#endif + +#include "wma.h" +#ifdef DEBUG +#include "wma_api.h" +#endif +extern int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev); +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "wlan_hdd_cfg.h" + +#define IS_UP(_dev) \ + (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) +#define IS_UP_AUTO(_ic) \ + (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO) +#define WE_WLAN_VERSION 1 +#define WE_GET_STA_INFO_SIZE 30 +/* WEXT limitation: MAX allowed buf len for any * + * IW_PRIV_TYPE_CHAR is 2Kbytes * + */ +#define WE_SAP_MAX_STA_INFO 0x7FF + +#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7) +#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) +#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf) +#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1) + +#define SAP_24GHZ_CH_COUNT (14) +#define ACS_SCAN_EXPIRY_TIMEOUT_S 4 + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_channel_wakelock_init + + \param - Pointer to HDD context + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx) +{ + /* Initialize the wakelock */ + vos_wake_lock_init(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock"); + atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_channel_allow_suspend - Allow suspend in a channel. + + Called when, + 1. BSS stopped + 2. Channel switch + + \param - pAdapter, channel + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter, + u_int8_t channel) +{ + + hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"), + pHostapdState->bssState, channel, + atomic_read(&pHddCtx->sap_dfs_ref_cnt)); + + /* Return if BSS is already stopped */ + if (pHostapdState->bssState == BSS_STOP) + return; + + /* Release wakelock when no more DFS channels are used */ + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channel)) { + if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) { + hddLog(LOGE, FL("DFS: allowing suspend (chan %d)"), channel); + vos_wake_lock_release(&pHddCtx->sap_dfs_wakelock); + } + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_channel_prevent_suspend - Prevent suspend in a channel. + + Called when, + 1. BSS started + 2. Channel switch + + \param - pAdapter, channel + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter, + u_int8_t channel) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"), + pHostapdState->bssState, channel, + atomic_read(&pHddCtx->sap_dfs_ref_cnt)); + + /* Return if BSS is already started && wakelock is acquired */ + if ((pHostapdState->bssState == BSS_START) && + (atomic_read(&pHddCtx->sap_dfs_ref_cnt) > 1)) + return; + + /* Acquire wakelock if we have at least one DFS channel in use */ + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channel)) { + if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) { + hddLog(LOGE, FL("DFS: preventing suspend (chan %d)"), channel); + vos_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock); + } + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_channel_wakelock_deinit + + \param - Pointer to HDD context + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx) +{ + if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) { + /* Release wakelock */ + vos_wake_lock_release(&pHddCtx->sap_dfs_wakelock); + /* Reset the reference count */ + atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); + hddLog(LOGE, FL("DFS: allowing suspend")); + } + + /* Destroy lock */ + vos_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock); +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_open() - HDD Open function for hostapd interface + + This is called in response to ifconfig up + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int hdd_hostapd_open (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = netdev_priv(dev); + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0)); + + if (WLAN_HDD_GET_CTX(pAdapter)->isLoadInProgress || + WLAN_HDD_GET_CTX(pAdapter)->isUnloadInProgress) + { + hddLog(LOGE, FL("Driver load/unload in progress, ignore adapter open")); + goto done; + } + + //Turn ON carrier state + netif_carrier_on(dev); + //Enable all Tx queues + netif_tx_start_all_queues(dev); +done: + EXIT(); + return 0; +} +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_stop() - HDD stop function for hostapd interface + + This is called in response to ifconfig down + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int hdd_hostapd_stop (struct net_device *dev) +{ + ENTER(); + + //Stop all tx queues + netif_tx_disable(dev); + + //Turn OFF carrier state + netif_carrier_off(dev); + + EXIT(); + return 0; +} +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_uninit() - HDD uninit function + + This is called during the netdev unregister to uninitialize all data +associated with the device + + \param - dev Pointer to net_device structure + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_hostapd_uninit (struct net_device *dev) +{ + hdd_adapter_t *pHostapdAdapter = netdev_priv(dev); + + ENTER(); + + if (pHostapdAdapter && pHostapdAdapter->pHddCtx) + { + hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter); + + /* after uninit our adapter structure will no longer be valid */ + pHostapdAdapter->dev = NULL; + } + + EXIT(); +} + + +/**============================================================================ + @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets. There are 2 versions of this function. One that uses + locked queue and other that uses lockless queues. Both have been retained to + do some performance testing + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued successfully + ===========================================================================*/ +int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + return 0; +} +int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu) +{ + return 0; +} + +static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter, + hdd_priv_data_t *priv_data) +{ + tANI_U8 *command = NULL; + int ret = 0; + + /* + * Note that valid pointers are provided by caller + */ + + if (priv_data->total_len <= 0 || + priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX) + { + /* below we allocate one more byte for command buffer. + * To avoid addition overflow total_len should be + * smaller than INT_MAX. */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d", + __func__, priv_data->total_len); + ret = -EFAULT; + goto exit; + } + + /* Allocate +1 for '\0' */ + command = kmalloc((priv_data->total_len + 1), GFP_KERNEL); + if (!command) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__); + ret = -ENOMEM; + goto exit; + } + + if (copy_from_user(command, priv_data->buf, priv_data->total_len)) + { + ret = -EFAULT; + goto exit; + } + + /* Make sure the command is NUL-terminated */ + command[priv_data->total_len] = '\0'; + + hddLog(VOS_TRACE_LEVEL_INFO, + "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command); + + if (strncmp(command, "P2P_SET_NOA", 11) == 0) + { + hdd_setP2pNoa(pAdapter->dev, command); + } + else if (strncmp(command, "P2P_SET_PS", 10) == 0) + { + hdd_setP2pOpps(pAdapter->dev, command); + } +#ifdef FEATURE_WLAN_BATCH_SCAN + else if (strncmp(command, "WLS_BATCHING", 12) == 0) + { + ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command); + } +#endif + else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0) + { + /* + * command should be a string having format + * SET_SAP_CHANNEL_LIST + */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Preferred Channels for SAP", + __func__); + +#ifdef WLAN_FEATURE_MBSSID + ret = sapSetPreferredChannel(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), + command); +#else + ret = sapSetPreferredChannel(command); +#endif + } + else if (strncmp(command, "MIRACAST", 8) == 0) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Received MIRACAST command", __func__); + ret = hdd_set_miracast_mode(pAdapter, command); + } +exit: + if (command) + { + kfree(command); + } + return ret; +} + +#ifdef CONFIG_COMPAT +static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + struct { + compat_uptr_t buf; + int used_len; + int total_len; + } compat_priv_data; + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&compat_priv_data, ifr->ifr_data, + sizeof(compat_priv_data))) { + ret = -EFAULT; + goto exit; + } + priv_data.buf = compat_ptr(compat_priv_data.buf); + priv_data.used_len = compat_priv_data.used_len; + priv_data.total_len = compat_priv_data.total_len; + ret = hdd_hostapd_driver_command(pAdapter, &priv_data); + exit: + return ret; +} +#else /* CONFIG_COMPAT */ +static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + /* will never be invoked */ + return 0; +} +#endif /* CONFIG_COMPAT */ + +static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) { + ret = -EFAULT; + } else { + ret = hdd_hostapd_driver_command(pAdapter, &priv_data); + } + return ret; +} + +static int hdd_hostapd_ioctl(struct net_device *dev, + struct ifreq *ifr, int cmd) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int ret; + + if (dev != pAdapter->dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto exit; + } + + if ((!ifr) || (!ifr->ifr_data)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("ifr or ifr->ifr_data is NULL")); + ret = -EINVAL; + goto exit; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid context", __func__); + ret = -EBUSY; + goto exit; + } + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + if (is_compat_task()) + ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr); + else + ret = hdd_hostapd_driver_ioctl(pAdapter, ifr); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + exit: + return ret; +} + +#ifdef QCA_HT_2040_COEX +VOS_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter, + tANI_U8 channel_type) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: change HT20/40 mode", __func__); + + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) { + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if ( NULL == hHal ) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Hal ctx is null", __func__); + return VOS_STATUS_E_FAULT; + } + halStatus = sme_SetHT2040Mode(hHal, pHostapdAdapter->sessionId, + channel_type, eANI_BOOLEAN_TRUE); + if (halStatus == eHAL_STATUS_FAILURE ) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to change HT20/40 mode", __func__); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} +#endif + +#ifdef FEATURE_WLAN_FORCE_SAP_SCC +/**--------------------------------------------------------------------------- + \brief hdd_restart_softap() - + Restart SAP on STA channel to support + STA + SAP concurrency. + + --------------------------------------------------------------------------*/ +void hdd_restart_softap(hdd_context_t *pHddCtx, + hdd_adapter_t *pHostapdAdapter) +{ + tHddAvoidFreqList hdd_avoid_freq_list; + + /* generate vendor specific event */ + vos_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList)); + hdd_avoid_freq_list.avoidFreqRange[0].startFreq = + vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel); + hdd_avoid_freq_list.avoidFreqRange[0].endFreq = + vos_chan_to_freq(pHostapdAdapter->sessionCtx.ap.operatingChannel); + hdd_avoid_freq_list.avoidFreqRangeCount = 1; + wlan_hdd_send_avoid_freq_event(pHddCtx, &hdd_avoid_freq_list); +} +#endif /* FEATURE_WLAN_FORCE_SAP_SCC */ + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_set_mac_address() - + This function sets the user specified mac address using + the command ifconfig wlanX hw ether . + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *psta_mac_addr = addr; + ENTER(); + memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + EXIT(); + return 0; +} +void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback) +{ + struct net_device *dev = (struct net_device *)usrDataForCallback; + v_BYTE_t we_custom_event[64]; + union iwreq_data wrqu; +#ifdef DISABLE_CONCURRENCY_AUTOSAVE + VOS_STATUS vos_status; + hdd_adapter_t *pHostapdAdapter; + hdd_ap_ctx_t *pHddApCtx; +#endif /*DISABLE_CONCURRENCY_AUTOSAVE */ + + /* event_name space-delimiter driver_module_name */ + /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */ + char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME; + int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */ + + ENTER(); + +#ifdef DISABLE_CONCURRENCY_AUTOSAVE + if (vos_concurrent_open_sessions_running()) + { + /* + This timer routine is going to be called only when AP + persona is up. + If there are concurrent sessions running we do not want + to shut down the Bss.Instead we run the timer again so + that if Autosave is enabled next time and other session + was down only then we bring down AP + */ + pHostapdAdapter = netdev_priv(dev); + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + vos_status = vos_timer_start( + &pHddApCtx->hdd_ap_inactivity_timer, + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff + * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + } + EXIT(); + return; + } +#endif /*DISABLE_CONCURRENCY_AUTOSAVE */ + memset(&we_custom_event, '\0', sizeof(we_custom_event)); + memcpy(&we_custom_event, autoShutEvent, event_len); + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = event_len; + + hddLog(LOG1, FL("Shutting down AP interface due to inactivity")); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event); + + EXIT(); +} + +VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: UPDATE Beacon Params", __func__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Hal ctx is null", __func__); + return VOS_STATUS_E_FAULT; + } + halStatus = sme_ChangeMCCBeaconInterval(hHal, pHostapdAdapter->sessionId); + if(halStatus == eHAL_STATUS_FAILURE ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update Beacon Params", __func__); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} + +void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback) +{ + v_U8_t staId = 0; + struct net_device *dev; + dev = (struct net_device *)usrDataForCallback; + + hddLog(LOGE, FL("Clearing all the STA entry....")); + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if ( pHostapdAdapter->aStaInfo[staId].isUsed && + ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) + { + //Disconnect all the stations + hdd_softap_sta_disassoc(pHostapdAdapter, &pHostapdAdapter->aStaInfo[staId].macAddrSTA.bytes[0]); + } + } +} + +static int hdd_stop_p2p_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback) +{ + struct net_device *dev; + hdd_context_t *pHddCtx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + dev = (struct net_device *)usrDataForCallback; + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); +#else + status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext); +#endif + if (VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting P2P link!!!!!!")); + } + clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode); + } + EXIT(); + return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY; +} + +VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t *pHostapdState; + struct net_device *dev; + eSapHddEvent sapEvent; + union iwreq_data wrqu; + v_BYTE_t *we_custom_event_generic = NULL; + int we_event = 0; + int i = 0; + v_U8_t staId; + VOS_STATUS vos_status; + v_BOOL_t bWPSState; + v_BOOL_t bAuthRequired = TRUE; + tpSap_AssocMacAddr pAssocStasArray = NULL; + char unknownSTAEvent[IW_CUSTOM_MAX+1]; + char maxAssocExceededEvent[IW_CUSTOM_MAX+1]; + v_BYTE_t we_custom_start_event[64]; + char *startBssEvent; + hdd_context_t *pHddCtx; + hdd_scaninfo_t *pScanInfo = NULL; + struct iw_michaelmicfailure msg; + v_U8_t ignoreCAC = 0; + hdd_config_t *cfg = NULL; + struct wlan_dfs_info dfs_info; + v_U8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN; + hdd_adapter_t *con_sap_adapter; + VOS_STATUS status = VOS_STATUS_SUCCESS; +#if defined CONFIG_CNSS + int ret = 0; +#endif + + dev = (struct net_device *)usrDataForCallback; + if (!dev) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: usrDataForCallback is null", __func__); + return eHAL_STATUS_FAILURE; + } + + pHostapdAdapter = netdev_priv(dev); + + if ((NULL == pHostapdAdapter) || + (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter or adapter has invalid magic"); + return eHAL_STATUS_FAILURE; + } + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + + if (!pSapEvent) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pSapEvent is null", __func__); + return eHAL_STATUS_FAILURE; + } + + sapEvent = pSapEvent->sapHddEventCode; + memset(&wrqu, '\0', sizeof(wrqu)); + pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx); + + if (!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null")); + return eHAL_STATUS_FAILURE; + } + + cfg = pHddCtx->cfg_ini; + + if (!cfg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD config is null")); + return eHAL_STATUS_FAILURE; + } + + dfs_info.channel = pHddApCtx->operatingChannel; + sme_GetCountryCode(pHddCtx->hHal, dfs_info.country_code, &cc_len); + + switch(sapEvent) + { + case eSAP_START_BSS_EVENT : + hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"), + pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS", + pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel, + pSapEvent->sapevt.sapStartBssCompleteEvent.staId); + + pHostapdAdapter->sessionId = + pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId; + + pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status; + vos_status = vos_event_set(&pHostapdState->vosEvent); + + if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!")); + goto stopbss; + } + else + { +#ifdef FEATURE_WLAN_CH_AVOID + sme_ChAvoidUpdateReq(pHddCtx->hHal); +#endif /* FEATURE_WLAN_CH_AVOID */ + + pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId; + +#ifdef QCA_LL_TX_FLOW_CT + if (pHostapdAdapter->tx_flow_timer_initialized == VOS_FALSE) + { + vos_timer_init(&pHostapdAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_tx_resume_timer_expired_handler, + pHostapdAdapter); + pHostapdAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_tx_resume_cb, + pHostapdAdapter->sessionId, + (void *)pHostapdAdapter); +#endif + + //@@@ need wep logic here to set privacy bit + vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status); + } +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + { + status = hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId, + WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr); + + if (status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: WLAN_AP_CONNECT event failed!!")); + goto stopbss; + } + } +#endif + + if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) + { + // AP Inactivity timer init and start + vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW, + hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev ); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + + vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + + } +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE); +#endif + pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel; + + hdd_hostapd_channel_prevent_suspend(pHostapdAdapter, + pHddApCtx->operatingChannel); + + pHostapdState->bssState = BSS_START; + +#ifdef FEATURE_GREEN_AP + if (!(VOS_STA & pHddCtx->concurrency_mode) && + cfg->enable2x2 && + cfg->enableGreenAP) { + hdd_wlan_green_ap_mc(pHddCtx, GREEN_AP_PS_START_EVENT); + } else { + hdd_wlan_green_ap_mc(pHddCtx, GREEN_AP_PS_STOP_EVENT); + hddLog(VOS_TRACE_LEVEL_INFO, + "Green-AP: is disabled, due to sta_concurrency: %d, enable2x2: %d, enableGreenAP: %d", + VOS_STA & pHddCtx->concurrency_mode, + cfg->enable2x2, + cfg->enableGreenAP); + } +#endif + // Send current operating channel of SoftAP to BTC-ES + send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0); + + //Set group key / WEP key every time when BSS is restarted + if( pHddApCtx->groupKey.keyLength ) + { + status = WLANSAP_SetKeySta( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, +#endif + &pHddApCtx->groupKey); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SetKeySta failed", __func__); + } + } + else + { + for ( i = 0; i < CSR_MAX_NUM_KEY; i++ ) + { + if ( !pHddApCtx->wepKey[i].keyLength ) + continue; + + status = WLANSAP_SetKeySta( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, +#endif + &pHddApCtx->wepKey[i]); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SetKeySta failed idx %d", __func__, i); + } + } + } + + pHddCtx->dfs_radar_found = VOS_FALSE; + WLANSAP_Get_Dfs_Ignore_CAC(pHddCtx->hHal, &ignoreCAC); + if ((NV_CHANNEL_DFS != + vos_nv_getChannelEnabledState(pHddApCtx->operatingChannel)) + || ignoreCAC) + { + pHddApCtx->dfs_cac_block_tx = VOS_FALSE; + } else { + /* + * DFS requirement: Do not transmit during CAC. + * This flag will be reset when BSS starts + * (if not in a DFS channel) or CAC ends. + */ + pHddApCtx->dfs_cac_block_tx = VOS_TRUE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "The value of dfs_cac_block_tx[%d] for ApCtx[%p]", + pHddApCtx->dfs_cac_block_tx, pHddApCtx); + + if ((NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(pHddApCtx->operatingChannel)) && + (pHddCtx->cfg_ini->IsSapDfsChSifsBurstEnabled == 0)) + { + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Setting SIFS Burst disable for DFS channel %d", + __func__, pHddApCtx->operatingChannel); + + if (process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_ENABLE, + 0, PDEV_CMD)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Set SIFS Burst for DFS channel %d", + __func__, pHddApCtx->operatingChannel); + } + } + + //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled + startBssEvent = "SOFTAP.enabled"; + memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event)); + memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent)); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(startBssEvent); + we_event = IWEVCUSTOM; + we_custom_event_generic = we_custom_start_event; + hdd_dump_concurrency_info(pHddCtx); + break; //Event will be sent after Switch-Case stmt + + case eSAP_STOP_BSS_EVENT: + hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + + hdd_hostapd_channel_allow_suspend(pHostapdAdapter, + pHddApCtx->operatingChannel); + +#ifdef FEATURE_GREEN_AP + hdd_wlan_green_ap_mc(pHddCtx, GREEN_AP_PS_STOP_EVENT); +#endif + //Free up Channel List incase if it is set +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); +#else + sapCleanupChannelList(); +#endif + + pHddApCtx->operatingChannel = 0; //Invalidate the channel info. +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + { + status = hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId, + WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr); + + if (status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: WLAN_AP_DISCONNECT event failed!!")); + goto stopbss; + } + } +#endif + /* reset the dfs_cac_status and dfs_cac_block_tx flag only when + * the last BSS is stopped + */ + con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter); + if (!con_sap_adapter) { + pHddApCtx->dfs_cac_block_tx = TRUE; + pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; + } + goto stopbss; + + case eSAP_DFS_CAC_START: + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_START_IND, + &dfs_info, sizeof(struct wlan_dfs_info)); + pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS; + break; + + case eSAP_DFS_CAC_END: + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_END_IND, + &dfs_info, sizeof(struct wlan_dfs_info)); + pHddApCtx->dfs_cac_block_tx = VOS_FALSE; + pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE; + break; + + case eSAP_DFS_RADAR_DETECT: + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_RADAR_DETECT_IND, + &dfs_info, sizeof(struct wlan_dfs_info)); + pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE; + break; + + case eSAP_DFS_NO_AVAILABLE_CHANNEL: + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, + &dfs_info, sizeof(struct wlan_dfs_info)); + break; + + case eSAP_STA_SET_KEY_EVENT: + /* TODO: forward the message to hostapd once implementation + is done for now just print */ + hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + return VOS_STATUS_SUCCESS; + case eSAP_STA_DEL_KEY_EVENT: + /* TODO: forward the message to hostapd once implementation + is done for now just print */ + hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT"); + return VOS_STATUS_SUCCESS; + case eSAP_STA_MIC_FAILURE_EVENT: + { + memset(&msg, '\0', sizeof(msg)); + msg.src_addr.sa_family = ARPHRD_ETHER; + memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t)); + hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data)); + if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) + msg.flags = IW_MICFAILURE_GROUP; + else + msg.flags = IW_MICFAILURE_PAIRWISE; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(msg); + we_event = IWEVMICHAELMICFAILURE; + we_custom_event_generic = (v_BYTE_t *)&msg; + } + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(dev, + pSapEvent->sapevt. + sapStationMICFailureEvent.staMac.bytes, + ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE), + pSapEvent->sapevt.sapStationMICFailureEvent.keyId, + pSapEvent->sapevt.sapStationMICFailureEvent.TSC, + GFP_KERNEL); + break; + + case eSAP_STA_ASSOC_EVENT: + case eSAP_STA_REASSOC_EVENT: + wrqu.addr.sa_family = ARPHRD_ETHER; + memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac, + sizeof(v_MACADDR_t)); + hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + we_event = IWEVREGISTERED; + +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_Get_WPS_State(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &bWPSState); +#else + WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState); +#endif + + if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) ) + { + bAuthRequired = FALSE; + } + + if (bAuthRequired || bWPSState == eANI_BOOLEAN_TRUE ) + { + vos_status = hdd_softap_RegisterSTA(pHostapdAdapter, + TRUE, + pHddApCtx->uPrivacy, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId, + 0, + 0, + (v_MACADDR_t *)wrqu.addr.sa_data, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""), + vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + } + else + { + vos_status = hdd_softap_RegisterSTA(pHostapdAdapter, + FALSE, + pHddApCtx->uPrivacy, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId, + 0, + 0, + (v_MACADDR_t *)wrqu.addr.sa_data, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""), + vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + } +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + { + status = hdd_ipa_wlan_evt(pHostapdAdapter, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId, + WLAN_CLIENT_CONNECT_EX, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: WLAN_CLIENT_CONNECT_EX event failed!!")); + goto stopbss; + } + } +#endif +#ifdef QCA_PKT_PROTO_TRACE + /* Peer associated, update into trace buffer */ + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + vos_pkt_trace_buf_update("HA:ASSOC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + +#ifdef MSM_PLATFORM + /* start timer in sap/p2p_go */ + if (pHddApCtx->bApActive == VOS_FALSE) + { + spin_lock_bh(&pHddCtx->bus_bw_lock); + pHostapdAdapter->prev_tx_packets = pHostapdAdapter->stats.tx_packets; + pHostapdAdapter->prev_rx_packets = pHostapdAdapter->stats.rx_packets; + spin_unlock_bh(&pHddCtx->bus_bw_lock); + hdd_start_bus_bw_compute_timer(pHostapdAdapter); + } +#endif + pHddApCtx->bApActive = VOS_TRUE; + // Stop AP inactivity timer + if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING) + { + vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to start AP inactivity timer")); + } +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_FALSE); +#endif + vos_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock, + HDD_SAP_WAKE_LOCK_DURATION); + { + struct station_info staInfo; + v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen; + + memset(&staInfo, 0, sizeof(staInfo)); + if (iesLen <= MAX_ASSOC_IND_IE_LEN ) + { + staInfo.assoc_req_ies = + (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0]; + staInfo.assoc_req_ies_len = iesLen; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) + staInfo.filled |= STATION_INFO_ASSOC_REQ_IES; +#endif + cfg80211_new_sta(dev, + (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0], + &staInfo, GFP_KERNEL); + } + else + { + hddLog(LOGE, FL(" Assoc Ie length is too long")); + } + } + + pScanInfo = &pHostapdAdapter->scan_info; + // Lets do abort scan to ensure smooth authentication for client + if ((pScanInfo != NULL) && pScanInfo->mScanPending) + { + hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + /* send peer status indication to oem app */ + hdd_SendPeerStatusIndToOemApp( + &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac, + ePeerConnected, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.timingMeasCap, + pHostapdAdapter->sessionId, + &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.chan_info); + } + +#ifdef FEATURE_GREEN_AP + hdd_wlan_green_ap_mc(pHddCtx, GREEN_AP_ADD_STA_EVENT); +#endif + break; + case eSAP_STA_DISASSOC_EVENT: + memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, + sizeof(v_MACADDR_t)); + hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC) + hddLog(LOG1," User initiated disassociation"); + else + hddLog(LOG1," MAC initiated disassociation"); + we_event = IWEVEXPIRED; + vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!")); + return VOS_STATUS_E_FAILURE; + } +#ifdef IPA_OFFLOAD + if (hdd_ipa_is_enabled(pHddCtx)) + { + status = hdd_ipa_wlan_evt(pHostapdAdapter, staId, WLAN_CLIENT_DISCONNECT, + pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes); + + if (status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!")); + goto stopbss; + } + } +#endif +#ifdef QCA_PKT_PROTO_TRACE + /* Peer dis-associated, update into trace buffer */ + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + vos_pkt_trace_buf_update("HA:DISASC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + hdd_softap_DeregisterSTA(pHostapdAdapter, staId); + + pHddApCtx->bApActive = VOS_FALSE; + spin_lock_bh( &pHostapdAdapter->staInfo_lock ); + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (pHostapdAdapter->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId) + { + pHddApCtx->bApActive = VOS_TRUE; + break; + } + } + spin_unlock_bh( &pHostapdAdapter->staInfo_lock ); + + // Start AP inactivity timer if no stations associated with it + if ((0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)) + { + if (pHddApCtx->bApActive == FALSE) + { + if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED) + { + vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + } + else + VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED); + } + } +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE); +#endif + + cfg80211_del_sta(dev, + (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0], + GFP_KERNEL); + + //Update the beacon Interval if it is P2P GO + vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter); + if (VOS_STATUS_SUCCESS != vos_status) + { + hddLog(LOGE, "%s: failed to update Beacon interval %d", + __func__, vos_status); + } + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + /* send peer status indication to oem app */ + hdd_SendPeerStatusIndToOemApp( + &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, + ePeerDisconnected, 0, + pHostapdAdapter->sessionId, NULL); + } + +#ifdef MSM_PLATFORM + /*stop timer in sap/p2p_go */ + if (pHddApCtx->bApActive == FALSE) + { + spin_lock_bh(&pHddCtx->bus_bw_lock); + pHostapdAdapter->prev_tx_packets = 0; + pHostapdAdapter->prev_rx_packets = 0; + spin_unlock_bh(&pHddCtx->bus_bw_lock); + hdd_stop_bus_bw_compute_timer(pHostapdAdapter); + } +#endif +#ifdef FEATURE_GREEN_AP + hdd_wlan_green_ap_mc(pHddCtx, GREEN_AP_DEL_STA_EVENT); +#endif + break; + case eSAP_WPS_PBC_PROBE_REQ_EVENT: + { + static const char * message ="MLMEWPSPBCPROBEREQ.indication"; + union iwreq_data wreq; + + down(&pHddApCtx->semWpsPBCOverlapInd); + pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen; + + vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE, + pHddApCtx->WPSPBCProbeReq.probeReqIELen); + + vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t)); + hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr)); + memset(&wreq, 0, sizeof(wreq)); + wreq.data.length = strlen(message); // This is length of message + wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message); + + return VOS_STATUS_SUCCESS; + } + case eSAP_ASSOC_STA_CALLBACK_EVENT: + pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas; + if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) + { // List of associated stations + for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++) + { + hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR, + i+1, + pAssocStasArray->assocId, + pAssocStasArray->staId, + MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes)); + pAssocStasArray++; + } + } + vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here + pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL; + return VOS_STATUS_SUCCESS; + case eSAP_INDICATE_MGMT_FRAME: + hdd_indicateMgmtFrame( pHostapdAdapter, + pSapEvent->sapevt.sapManagementFrameInfo.nFrameLength, + pSapEvent->sapevt.sapManagementFrameInfo.pbFrames, + pSapEvent->sapevt.sapManagementFrameInfo.frameType, + pSapEvent->sapevt.sapManagementFrameInfo.rxChan, 0); + return VOS_STATUS_SUCCESS; + case eSAP_REMAIN_CHAN_READY: + hdd_remainChanReadyHandler( pHostapdAdapter ); + return VOS_STATUS_SUCCESS; + case eSAP_SEND_ACTION_CNF: + hdd_sendActionCnf( pHostapdAdapter, + ( eSAP_STATUS_SUCCESS == + pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ? + TRUE : FALSE ); + return VOS_STATUS_SUCCESS; + case eSAP_UNKNOWN_STA_JOIN: + snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x", + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]); + we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ + wrqu.data.pointer = unknownSTAEvent; + wrqu.data.length = strlen(unknownSTAEvent); + we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent; + hddLog(LOGE,"%s", unknownSTAEvent); + break; + + case eSAP_MAX_ASSOC_EXCEEDED: + snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied" + " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect" + " one or more devices to enable the new device connection", + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]); + we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ + wrqu.data.pointer = maxAssocExceededEvent; + wrqu.data.length = strlen(maxAssocExceededEvent); + we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent; + hddLog(LOG1,"%s", maxAssocExceededEvent); + break; + case eSAP_STA_ASSOC_IND: + return VOS_STATUS_SUCCESS; + + case eSAP_DISCONNECT_ALL_P2P_CLIENT: + hddLog(LOG1, FL(" Disconnecting all the P2P Clients....")); + hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback); + return VOS_STATUS_SUCCESS; + + case eSAP_MAC_TRIG_STOP_BSS_EVENT : + vos_status = hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(LOGW, FL("hdd_stop_p2p_link failed %d"), vos_status); + } + return VOS_STATUS_SUCCESS; + + case eSAP_CHANNEL_CHANGE_EVENT: + hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event")); + /* Prevent suspend for new channel */ + hdd_hostapd_channel_prevent_suspend(pHostapdAdapter, + pSapEvent->sapevt.sapChannelChange.operatingChannel); + /* Allow suspend for old channel */ + hdd_hostapd_channel_allow_suspend(pHostapdAdapter, + pHddApCtx->operatingChannel); + /* TODO Need to indicate operating channel change to hostapd */ + return VOS_STATUS_SUCCESS; + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + case eSAP_ACS_SCAN_SUCCESS_EVENT: + pHddCtx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; + hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"), + ACS_SCAN_EXPIRY_TIMEOUT_S); + vos_timer_stop( &pHddCtx->skip_acs_scan_timer); + vos_status = vos_timer_start( &pHddCtx->skip_acs_scan_timer, + ACS_SCAN_EXPIRY_TIMEOUT_S * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to start ACS scan expiry timer")); + return VOS_STATUS_SUCCESS; +#endif + + case eSAP_DFS_NOL_GET: + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Received eSAP_DFS_NOL_GET event")); +#if defined CONFIG_CNSS + /* get the dfs nol from cnss */ + ret = cnss_wlan_get_dfs_nol( + pSapEvent->sapevt.sapDfsNolInfo.pDfsList, + pSapEvent->sapevt.sapDfsNolInfo.sDfsList); + + if (ret > 0) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Get %d bytes of dfs nol from cnss", + __func__, ret); + return VOS_STATUS_SUCCESS; + } else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: No dfs nol entry in CNSS, ret: %d", + __func__, ret); + return VOS_STATUS_E_FAULT; + } +#endif + case eSAP_DFS_NOL_SET: + hddLog(VOS_TRACE_LEVEL_INFO, FL("Received eSAP_DFS_NOL_SET event")); +#if defined CONFIG_CNSS + /* set the dfs nol to cnss */ + ret = cnss_wlan_set_dfs_nol( + pSapEvent->sapevt.sapDfsNolInfo.pDfsList, + pSapEvent->sapevt.sapDfsNolInfo.sDfsList); + + if (ret) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Failed to set dfs nol - ret: %d", + __func__, ret); + } else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Set %d bytes dfs nol to cnss", + __func__, + pSapEvent->sapevt.sapDfsNolInfo.sDfsList); + } +#endif + return VOS_STATUS_SUCCESS; + + default: + hddLog(LOG1,"SAP message is not handled"); + goto stopbss; + return VOS_STATUS_SUCCESS; + } + wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic); + return VOS_STATUS_SUCCESS; + +stopbss : + { + v_BYTE_t we_custom_event[64]; + char *stopBssEvent = "STOP-BSS.response";//17 + int event_len = strlen(stopBssEvent); + + hddLog(LOG1, FL("BSS stop status = %s"), + pSapEvent->sapevt.sapStopBssCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + + /* Change the BSS state now since, as we are shutting things down, + * we don't want interfaces to become re-enabled */ + pHostapdState->bssState = BSS_STOP; + + if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) + { + if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state) + { + vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to stop AP inactivity timer")); + } + + vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to Destroy AP inactivity timer")); + } +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE); +#endif + + /* Stop the pkts from n/w stack as we are going to free all of + * the TX WMM queues for all STAID's */ + hdd_hostapd_stop(dev); + + /* reclaim all resources allocated to the BSS */ + vos_status = hdd_softap_stop_bss(pHostapdAdapter); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status); + + /* once the event is set, structure dev/pHostapdAdapter should + * not be touched since they are now subject to being deleted + * by another thread */ + if (eSAP_STOP_BSS_EVENT == sapEvent) + vos_event_set(&pHostapdState->vosEvent); + + /* Notify user space that the BSS has stopped */ + memset(&we_custom_event, '\0', sizeof(we_custom_event)); + memcpy(&we_custom_event, stopBssEvent, event_len); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = event_len; + we_event = IWEVCUSTOM; + we_custom_event_generic = we_custom_event; + wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic); + hdd_dump_concurrency_info(pHddCtx); + } + return VOS_STATUS_SUCCESS; +} + +int hdd_softap_unpackIE( + tHalHandle halHandle, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, + v_BOOL_t *pMFPCapable, + v_BOOL_t *pMFPRequired, + u_int16_t gen_ie_len, + u_int8_t *gen_ie ) +{ + tDot11fIERSN dot11RSNIE; + tDot11fIEWPA dot11WPAIE; + + tANI_U8 *pRsnIe; + tANI_U16 RSNIeLen; + + if (NULL == halHandle) + { + hddLog(LOGE, FL("Error haHandle returned NULL")); + return -EINVAL; + } + + // Validity checks + if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) || + (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) ) + return -EINVAL; + // Type check + if ( gen_ie[0] == DOT11F_EID_RSN) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) ) + { + return VOS_STATUS_E_FAILURE; + } + // Skip past the EID byte and length byte + pRsnIe = gen_ie + 2; + RSNIeLen = gen_ie_len - 2; + // Unpack the RSN IE + memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN)); + dot11fUnpackIeRSN((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11RSNIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"), + __func__, dot11RSNIE.pwise_cipher_suite_count ); + hddLog(LOG1, FL("%s: authentication suite count: %d"), + __func__, dot11RSNIE.akm_suite_count); + /*Here we have followed the apple base code, + but probably I suspect we can do something different*/ + //dot11RSNIE.akm_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]); + //dot11RSNIE.pwise_cipher_suite_count + *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]); + //dot11RSNIE.gp_cipher_suite_count + *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite); + // Set the PMKSA ID Cache for this interface + *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80); + *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40); + // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache + } else + if (gen_ie[0] == DOT11F_EID_WPA) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) + { + return VOS_STATUS_E_FAILURE; + } + // Skip past the EID byte and length byte - and four byte WiFi OUI + pRsnIe = gen_ie + 2 + 4; + RSNIeLen = gen_ie_len - (2 + 4); + // Unpack the WPA IE + memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA)); + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11WPAIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"), + __func__, dot11WPAIE.unicast_cipher_count ); + hddLog(LOG1, FL("%s: WPA authentication suite count: %d"), + __func__, dot11WPAIE.auth_suite_count); + //dot11WPAIE.auth_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]); + //dot11WPAIE.unicast_cipher_count + *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]); + //dot11WPAIE.unicast_cipher_count + *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + *pMFPCapable = VOS_FALSE; + *pMFPRequired = VOS_FALSE; + } + else + { + hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + + /**--------------------------------------------------------------------------- + + \brief hdd_softap_set_channel_change() - + This function to support SAP channel change with CSA IE + set in the beacons. + + \param - dev - Pointer to the net device. + - target_channel - target channel number. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static +int hdd_softap_set_channel_change(struct net_device *dev, int target_channel) +{ + VOS_STATUS status; + int ret = 0; + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + hdd_context_t *pHddCtx = NULL; + +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid HDD context", __func__); + ret = -EBUSY; + return ret; + } + + /* + * Set the dfs_radar_found flag to mimic channel change + * when a radar is found. This will enable synchronizing + * SAP and HDD states similar to that of radar indication. + * Suspend the netif queues to stop queuing Tx frames + * from upper layers. netif queues will be resumed + * once the channel change is completed and SAP will + * post eSAP_START_BSS_EVENT success event to HDD. + */ + pHddCtx->dfs_radar_found = VOS_TRUE; + + /* + * Post the Channel Change request to SAP. + */ + status = WLANSAP_SetChannelChangeWithCsa( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + pVosContext, +#endif + (v_U32_t) target_channel); + + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SAP set channel failed for channel = %d", + __func__, target_channel); + /* + * If channel change command fails then clear the + * radar found flag and also restart the netif + * queues. + */ + + pHddCtx->dfs_radar_found = VOS_FALSE; + + ret = -EINVAL; + } + + return ret; +} + +int +static iw_softap_set_ini_cfg(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOS_STATUS vstatus; + int ret = 0; /* success */ + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + hdd_context_t *pHddCtx; + + if (pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL!", __func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret != 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return ret; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received data %s", __func__, extra); + + vstatus = hdd_execute_global_config_command(pHddCtx, extra); +#ifdef WLAN_FEATURE_MBSSID + if (vstatus == VOS_STATUS_E_PERM) { + vstatus = hdd_execute_sap_dyn_config_command(pAdapter, extra); + if (vstatus == VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Stored in Dynamic SAP ini config", __func__); + } +#endif + if (VOS_STATUS_SUCCESS != vstatus) + { + ret = -EINVAL; + } + + return ret; +} + +int +static iw_softap_get_ini_cfg(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int ret = 0; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret != 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return ret; + } + +#ifdef WLAN_FEATURE_MBSSID + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Printing Adapter MBSSID SAP Dyn INI Config", __func__); + hdd_cfg_get_sap_dyn_config(pAdapter, extra, QCSAP_IOCTL_MAX_STR_LEN); + /* Overwrite extra buffer with global ini config if need to return in buf */ +#endif + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Printing CLD global INI Config", __func__); + hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN); + wrqu->data.length = strlen(extra)+1; + + return 0; +} + +static int iw_softap_set_two_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int sub_cmd = value[0]; + int ret = 0; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret != 0) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid!", __func__); + goto out; + } + + switch(sub_cmd) { +#ifdef DEBUG + case QCSAP_IOCTL_SET_FW_CRASH_INJECT: + hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d", value[1], value[2]); + ret = process_wma_set_command_twoargs((int) pAdapter->sessionId, + (int) GEN_PARAM_CRASH_INJECT, + value[1], value[2], GEN_CMD); + break; +#endif + default: + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd); + break; + } + +out: + return ret; +} + +static void print_mac_list(v_MACADDR_t *macList, v_U8_t size) +{ + int i; + v_BYTE_t *macArray; + + for (i = 0; i < size; i++) { + macArray = (macList + i)->bytes; + pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n", + i, MAC_ADDR_ARRAY(macArray)); + } + return; +} + +static VOS_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter) +{ + eSapMacAddrACL acl_mode; + v_MACADDR_t MacList[MAX_ACL_MAC_ADDRESS]; + v_U8_t listnum; + v_PVOID_t pvosGCtx = NULL; + +#ifdef WLAN_FEATURE_MBSSID + pvosGCtx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter); +#else + pvosGCtx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + vos_mem_zero(&MacList[0], sizeof(MacList)); + if (VOS_STATUS_SUCCESS == WLANSAP_GetACLMode(pvosGCtx, &acl_mode)) { + pr_info("******** ACL MODE *********\n"); + switch (acl_mode) { + case eSAP_ACCEPT_UNLESS_DENIED: + pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n"); + break; + case eSAP_DENY_UNLESS_ACCEPTED: + pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n"); + break; + case eSAP_SUPPORT_ACCEPT_AND_DENY: + pr_info("ACL Mode = ACCEPT_AND_DENY\n"); + break; + case eSAP_ALLOW_ALL: + pr_info("ACL Mode = ALLOW_ALL\n"); + break; + default: + pr_info("Invalid SAP ACL Mode = %d\n", acl_mode); + return VOS_STATUS_E_FAILURE; + } + } else { + return VOS_STATUS_E_FAILURE; + } + + if (VOS_STATUS_SUCCESS == WLANSAP_GetACLAcceptList(pvosGCtx, + &MacList[0], &listnum)) { + pr_info("******* WHITE LIST ***********\n"); + if (listnum <= MAX_ACL_MAC_ADDRESS) + print_mac_list(&MacList[0], listnum); + } else { + return VOS_STATUS_E_FAILURE; + } + + if (VOS_STATUS_SUCCESS == WLANSAP_GetACLDenyList(pvosGCtx, + &MacList[0], &listnum)) { + pr_info("******* BLACK LIST ***********\n"); + if (listnum <= MAX_ACL_MAC_ADDRESS) + print_mac_list(&MacList[0], listnum); + } else { + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +int +static iw_softap_setparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal; + int *value = (int *)extra; + int sub_cmd = value[0]; + int set_value = value[1]; + eHalStatus status; + int ret = 0; /* success */ + v_CONTEXT_t pVosContext; + + if (!pHostapdAdapter || !pHostapdAdapter->pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: either hostapd Adapter is null or HDD ctx is null", + __func__); + return -1; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (!hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal ctx is null", __func__); + return -1; + } + + pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + if (!pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Vos ctx is null", __func__); + return -1; + } + + switch(sub_cmd) + { + + case QCSAP_PARAM_CLR_ACL: + if (VOS_STATUS_SUCCESS != WLANSAP_ClearACL( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter) +#else + pVosContext +#endif + )) + { + ret = -EIO; + } + break; + + case QCSAP_PARAM_ACL_MODE: + if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) || + (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value)) + { + hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value); + ret = -EINVAL; + } + else + { +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_SetMode(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), set_value); +#else + WLANSAP_SetMode(pVosContext, set_value); +#endif + + } + break; + + case QCSAP_PARAM_AUTO_CHANNEL: + if ((0 != set_value) && (1 != set_value)) + { + hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value); + ret = -EINVAL; + } + else + { +#ifdef WLAN_FEATURE_MBSSID + pHostapdAdapter->sap_dyn_ini_cfg.apAutoChannelSelection = + set_value; +#else + (WLAN_HDD_GET_CTX + (pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value; +#endif + } + break; + + case QCSAP_PARAM_SET_CHANNEL_CHANGE: + if ( WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode ) + { + hddLog(LOG1, "SET SAP Channel Change to new channel= %d", + set_value); + ret = hdd_softap_set_channel_change(dev, set_value); + } + else + { + hddLog(LOGE, FL("%s:Channel Change Failed, Device in test mode"), + __func__); + ret = -EINVAL; + } + break; + + case QCSAP_PARAM_MAX_ASSOC: + if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) + { + hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value); + ret = -EINVAL; + } + else + { + if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) + { + hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d." + "Setting it to max allowed and continuing"), + set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX); + set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX; + } + status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, + set_value, NULL, eANI_BOOLEAN_FALSE); + if ( status != eHAL_STATUS_SUCCESS ) + { + hddLog(LOGE, FL("setMaxAssoc failure, status %d"), + status); + ret = -EIO; + } + } + break; + + case QCSAP_PARAM_HIDE_SSID: + { + eHalStatus status = eHAL_STATUS_SUCCESS; + status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value); + if(eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCSAP_PARAM_HIDE_SSID failed", + __func__); + return status; + } + break; + } + case QCSAP_PARAM_SET_MC_RATE: + { + tSirRateUpdateInd *rateUpdate; + hdd_context_t*pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx); + hdd_config_t *pConfig = NULL; + + if (pHddCtx) + pConfig = pHddCtx->cfg_ini; + else { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: pHddCtx = NULL", __func__); + ret = -1; + break; + } + + rateUpdate = (tSirRateUpdateInd *) + vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdate) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_MC_RATE indication alloc fail", __func__); + ret = -1; + break; + } + vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd )); + + hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value); + memcpy(rateUpdate->bssid, + pHostapdAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + rateUpdate->nss = (pConfig->enable2x2 == 0) ? 0 : 1; + rateUpdate->dev_mode = pHostapdAdapter->device_mode; + rateUpdate->mcastDataRate24GHz = set_value; + rateUpdate->mcastDataRate24GHzTxFlag = 1; + rateUpdate->mcastDataRate5GHz = set_value; + rateUpdate->bcastDataRate = -1; + status = sme_SendRateUpdateInd(hHal, rateUpdate); + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_MC_RATE failed", __func__); + vos_mem_free(rateUpdate); + ret = -1; + } + break; + } + + case QCSAP_PARAM_SET_TXRX_FW_STATS: + { + hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID, + set_value, VDEV_CMD); + break; + } + /* Firmware debug log */ + case QCSAP_DBGLOG_LOG_LEVEL: + { + hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_LOG_LEVEL, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_VAP_ENABLE: + { + hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_VAP_ENABLE, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_VAP_DISABLE: + { + hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_VAP_DISABLE, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_MODULE_ENABLE: + { + hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_MODULE_ENABLE, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_MODULE_DISABLE: + { + hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_MODULE_DISABLE, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_MOD_LOG_LEVEL: + { + hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_MOD_LOG_LEVEL, + set_value, DBG_CMD); + break; + } + + case QCSAP_DBGLOG_TYPE: + { + hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_TYPE, + set_value, DBG_CMD); + break; + } + case QCSAP_DBGLOG_REPORT_ENABLE: + { + hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_DBGLOG_REPORT_ENABLE, + set_value, DBG_CMD); + break; + } + case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY: + { + tVOS_CONCURRENCY_MODE concurrent_state = 0; + v_U8_t first_adapter_operating_channel = 0; + int ret = 0; /* success */ + hddLog(LOG1, "%s: iwpriv cmd to set MCC latency with val: " + "%dms", __func__, set_value); + concurrent_state = hdd_get_concurrency_mode(); + /** + * Check if concurrency mode is active. + * Need to modify this code to support MCC modes other than + * STA/P2P GO + */ + if (concurrent_state == (VOS_STA | VOS_P2P_GO)) + { + hddLog(LOG1, "%s: STA & P2P are both enabled", __func__); + /** + * The channel number and latency are formatted in + * a bit vector then passed on to WMA layer. + +**********************************************+ + | bits 31-16 | bits 15-8 | bits 7-0 | + | Unused | latency - Chan. 1 | channel no.| + +**********************************************+ + */ + + /* Get the operating channel of the designated vdev */ + first_adapter_operating_channel = + hdd_get_operating_channel + ( + pHostapdAdapter->pHddCtx, + pHostapdAdapter->device_mode + ); + /* Move the time latency for the adapter to bits 15-8 */ + set_value = set_value << 8; + /* Store the channel number at bits 7-0 of the bit vector + * as per the bit format above. + */ + set_value = set_value | first_adapter_operating_channel; + /* Send command to WMA */ + ret = process_wma_set_command + ( + (int)pHostapdAdapter->sessionId, + (int)WMA_VDEV_MCC_SET_TIME_LATENCY, + set_value, VDEV_CMD + ); + } + else + { + hddLog(LOG1, "%s: MCC is not active. Exit w/o setting" + " latency", __func__); + } + break; + } + + case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA: + { + v_U8_t first_adapter_operating_channel = 0; + v_U8_t second_adapter_opertaing_channel = 0; + tVOS_CONCURRENCY_MODE concurrent_state = 0; + hdd_adapter_t *staAdapter = NULL; + int ret = 0; /* success */ + + hddLog(LOG1, "%s: iwpriv cmd to set MCC quota value %dms", + __func__, set_value); + /** + * Check if concurrency mode is active. + * Need to modify this code to support MCC modes other than + * STA/P2P GO + */ + concurrent_state = hdd_get_concurrency_mode(); + if (concurrent_state == (VOS_STA | VOS_P2P_GO)) + { + hddLog(LOG1, "%s: STA & P2P are both enabled", __func__); + /** + * The channel numbers for both adapters and the time + * quota for the 1st adapter, i.e., one specified in cmd + * are formatted as a bit vector then passed on to WMA + +************************************************+ + |bit 31-24 |bit 23-16 | bits 15-8 |bits 7-0 | + | Unused | Quota for| chan. # for |chan. # for| + | | 1st chan.| 1st chan. |2nd chan. | + +************************************************+ + */ + + /* Get the operating channel of the specified vdev */ + first_adapter_operating_channel = + hdd_get_operating_channel + ( + pHostapdAdapter->pHddCtx, + pHostapdAdapter->device_mode + ); + hddLog(LOG1, "%s: 1st channel No.:%d and quota:%dms", + __func__, first_adapter_operating_channel, + set_value); + /* Move the time quota for first adapter to bits 15-8 */ + set_value = set_value << 8; + /** Store the operating channel number of 1st adapter at + * the lower 8-bits of bit vector. + */ + set_value = set_value | first_adapter_operating_channel; + if (pHostapdAdapter->device_mode == + WLAN_HDD_INFRA_STATION) + { + /* iwpriv cmd issued on wlan0; get p2p0 vdev chan. */ + if ((concurrent_state & VOS_P2P_CLIENT) != 0) + { + /* The 2nd MCC vdev is P2P client */ + staAdapter = hdd_get_adapter + ( + pHostapdAdapter->pHddCtx, + WLAN_HDD_P2P_CLIENT + ); + } else + { + /* The 2nd MCC vdev is P2P GO */ + staAdapter = hdd_get_adapter + ( + pHostapdAdapter->pHddCtx, + WLAN_HDD_P2P_GO + ); + } + } + else + { + /* iwpriv cmd issued on p2p0; get channel for wlan0 */ + staAdapter = hdd_get_adapter + ( + pHostapdAdapter->pHddCtx, + WLAN_HDD_INFRA_STATION + ); + } + if (staAdapter != NULL) + { + second_adapter_opertaing_channel = + hdd_get_operating_channel + ( + staAdapter->pHddCtx, + staAdapter->device_mode + ); + hddLog(LOG1, "%s: 2nd vdev channel No. is:%d", + __func__, second_adapter_opertaing_channel); + /* Move the time quota and operating channel number + * for the first adapter to bits 23-16 & bits 15-8 + * of set_value vector, respectively. + */ + set_value = set_value << 8; + /* Store the channel number for 2nd MCC vdev at bits + * 7-0 of set_value vector as per the bit format above. + */ + set_value = set_value | + second_adapter_opertaing_channel; + ret = process_wma_set_command + ( + (int)pHostapdAdapter->sessionId, + (int)WMA_VDEV_MCC_SET_TIME_QUOTA, + set_value, + VDEV_CMD + ); + } + else + { + hddLog(LOGE, "%s: NULL adapter handle. Exit", + __func__); + } + } + else + { + hddLog(LOG1, "%s: MCC is not active. " + "Exit w/o setting latency", __func__); + } + break; + } + + case QCASAP_TXRX_FWSTATS_RESET: + { + hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMA_VDEV_TXRX_FWSTATS_RESET_CMDID, + set_value, VDEV_CMD); + break; + } + + case QCSAP_PARAM_RTSCTS: + { + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_ENABLE_RTSCTS, + set_value, VDEV_CMD); + if (ret) { + hddLog(LOGE, "FAILED TO SET RTSCTS at SAP"); + ret = -EIO; + } + break; + } + case QCASAP_SET_11N_RATE: + { + u_int8_t preamble = 0, nss = 0, rix = 0; + tsap_Config_t *pConfig = + &pHostapdAdapter->sessionCtx.ap.sapConfig; + + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d", set_value); + + if (set_value != 0xff) { + rix = RC_2_RATE_IDX(set_value); + if (set_value & 0x80) { + if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11b || + pConfig->SapHw_mode == eSAP_DOT11_MODE_11b_ONLY || + pConfig->SapHw_mode == eSAP_DOT11_MODE_11g || + pConfig->SapHw_mode == eSAP_DOT11_MODE_11g_ONLY || + pConfig->SapHw_mode == eSAP_DOT11_MODE_abg || + pConfig->SapHw_mode == eSAP_DOT11_MODE_11a) { + hddLog(LOGE, "Not valid mode for HT"); + ret = -EIO; + break; + } + preamble = WMI_RATE_PREAMBLE_HT; + nss = HT_RC_2_STREAMS(set_value) - 1; + } else if (set_value & 0x10) { + if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11a) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for cck"); + ret = -EIO; + break; + } + preamble = WMI_RATE_PREAMBLE_CCK; + /* Enable Short preamble always for CCK except 1mbps */ + if (rix != 0x3) + rix |= 0x4; + } else { + if (pConfig->SapHw_mode == eSAP_DOT11_MODE_11b || + pConfig->SapHw_mode == eSAP_DOT11_MODE_11b_ONLY) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Not valid for OFDM"); + ret = -EIO; + break; + } + preamble = WMI_RATE_PREAMBLE_OFDM; + } + + set_value = (preamble << 6) | (nss << 4) | rix; + } + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d " + "preamble %x nss %d", set_value, rix, preamble, nss); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_FIXED_RATE, + set_value, VDEV_CMD); + break; + } + + case QCASAP_SET_VHT_RATE: + { + u_int8_t preamble = 0, nss = 0, rix = 0; + tsap_Config_t *pConfig = + &pHostapdAdapter->sessionCtx.ap.sapConfig; + + if (pConfig->SapHw_mode != eSAP_DOT11_MODE_11ac && + pConfig->SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d", + __func__, pConfig->SapHw_mode, pConfig->channel); + ret = -EIO; + break; + } + + if (set_value != 0xff) { + rix = RC_2_RATE_IDX_11AC(set_value); + preamble = WMI_RATE_PREAMBLE_VHT; + nss = HT_RC_2_STREAMS_11AC(set_value) - 1; + + set_value = (preamble << 6) | (nss << 4) | rix; + } + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d " + "preamble %x nss %d", set_value, rix, preamble, nss); + + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_FIXED_RATE, + set_value, VDEV_CMD); + break; + } + + case QCASAP_SHORT_GI: + { + hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value); + + ret = sme_UpdateHTConfig(hHal, pHostapdAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ, /* same as 40MHZ */ + set_value); + if (ret) + hddLog(LOGE, "Failed to set ShortGI value ret(%d)", ret); + break; + } + + case QCSAP_SET_AMPDU: + { + hddLog(LOG1, "QCSAP_SET_AMPDU val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMPDU, + set_value, GEN_CMD); + break; + } + + case QCSAP_SET_AMSDU: + { + hddLog(LOG1, "QCSAP_SET_AMSDU val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMSDU, + set_value, GEN_CMD); + break; + } + case QCSAP_GTX_HT_MCS: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_HT_MCS, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_VHT_MCS: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_VHT_MCS, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_USRCFG: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_USR_CFG, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_THRE: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_THRE, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_MARGIN: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MARGIN, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_STEP: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_STEP, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_MINTPC: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MINTPC, + set_value, GTX_CMD); + break; + } + + case QCSAP_GTX_BWMASK: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_BW_MASK, + set_value, GTX_CMD); + break; + } + + + +#ifdef QCA_PKT_PROTO_TRACE + case QCASAP_SET_DEBUG_LOG: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value); + /* Trace buffer dump only */ + if (VOS_PKT_TRAC_DUMP_CMD == set_value) + { + vos_pkt_trace_buf_dump(); + break; + } + pHddCtx->cfg_ini->gEnableDebugLog = set_value; + break; + } +#endif /* QCA_PKT_PROTO_TRACE */ + + case QCASAP_SET_TM_LEVEL: + { + hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d", + set_value); + (void)sme_SetThermalLevel(hHal, set_value); + break; + } + + + case QCASAP_SET_DFS_IGNORE_CAC: + { + hddLog(VOS_TRACE_LEVEL_INFO, "Set Dfs ignore CAC %d", + set_value); + + if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP) + return -EINVAL; + + ret = WLANSAP_Set_Dfs_Ignore_CAC(hHal, set_value); + break; + } + + case QCASAP_SET_DFS_TARGET_CHNL: + { + hddLog(VOS_TRACE_LEVEL_INFO, "Set Dfs target channel %d", + set_value); + + if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP) + return -EINVAL; + + ret = WLANSAP_Set_Dfs_Target_Chnl(hHal, set_value); + break; + } + + + case QCASAP_SET_DFS_NOL: + WLANSAP_Set_DfsNol( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + pVosContext, +#endif + (eSapDfsNolType)set_value + ); + break; + + case QCASAP_SET_RADAR_CMD: + { + hdd_context_t *pHddCtx = + WLAN_HDD_GET_CTX(pHostapdAdapter); + v_U8_t ch = + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->operatingChannel; + v_BOOL_t isDfsch; + + isDfsch = (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(ch)); + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value); + + if (!pHddCtx->dfs_radar_found && isDfsch) { + ret = process_wma_set_command( + (int)pHostapdAdapter->sessionId, + (int)WMA_VDEV_DFS_CONTROL_CMDID, + set_value, VDEV_CMD); + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Ignore command due to " + "dfs_radar_found: %d, is_dfs_channel: %d"), + pHddCtx->dfs_radar_found, isDfsch); + } + break; + } + case QCASAP_TX_CHAINMASK_CMD: + { + hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_PARAM_TX_CHAIN_MASK, + set_value, PDEV_CMD); + break; + } + + case QCASAP_RX_CHAINMASK_CMD: + { + hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_PARAM_RX_CHAIN_MASK, + set_value, PDEV_CMD); + break; + } + + case QCASAP_NSS_CMD: + { + hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value); + ret = process_wma_set_command((int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_NSS, + set_value, VDEV_CMD); + break; + } +#ifdef IPA_UC_OFFLOAD + case QCSAP_IPA_UC_STAT: + { + /* If input value is non-zero get stats */ + if (set_value) { + hdd_ipa_uc_stat_request(pHostapdAdapter, set_value); + } + else { + /* place holder for stats clean up + * Stats clean not implemented yet on firmware and ipa */ + } + return ret; + } +#endif /* IPA_UC_OFFLOAD */ + case QCASAP_SET_PHYMODE: + { + hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + ret = wlan_hdd_update_phymode(dev, hHal, set_value, phddctx); + break; + } + default: + hddLog(LOGE, FL("Invalid setparam command %d value %d"), + sub_cmd, set_value); + ret = -EINVAL; + break; + } + + return ret; +} + + +int +static iw_softap_getparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + int *value = (int *)extra; + int sub_cmd = value[0]; + eHalStatus status; + int ret = 0; /* success */ + hdd_context_t *pHddCtx = NULL; + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + switch (sub_cmd) + { + case QCSAP_PARAM_MAX_ASSOC: + status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status); + ret = -EIO; + } + break; + + case QCSAP_PARAM_GET_WLAN_DBG: + { + vos_trace_display(); + *value = 0; + break; + } + + case QCSAP_PARAM_AUTO_CHANNEL: + { +#ifdef WLAN_FEATURE_MBSSID + *value = pHostapdAdapter->sap_dyn_ini_cfg.apAutoChannelSelection; +#else + *value = (WLAN_HDD_GET_CTX + (pHostapdAdapter))->cfg_ini->apAutoChannelSelection; +#endif + break; + } + + case QCSAP_PARAM_RTSCTS: + { + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_ENABLE_RTSCTS, + VDEV_CMD); + break; + } + + case QCASAP_SHORT_GI: + { + *value = (int)sme_GetHTConfig(hHal, + pHostapdAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ); + break; + } + + case QCSAP_GTX_HT_MCS: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_HT_MCS, + GTX_CMD); + break; + } + + case QCSAP_GTX_VHT_MCS: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_VHT_MCS, + GTX_CMD); + break; + } + + case QCSAP_GTX_USRCFG: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_USR_CFG, + GTX_CMD); + break; + } + + case QCSAP_GTX_THRE: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_THRE, + GTX_CMD); + break; + } + + case QCSAP_GTX_MARGIN: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MARGIN, + GTX_CMD); + break; + } + + case QCSAP_GTX_STEP: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_STEP, + GTX_CMD); + break; + } + + case QCSAP_GTX_MINTPC: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MINTPC, + GTX_CMD); + break; + } + + case QCSAP_GTX_BWMASK: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_BW_MASK, + GTX_CMD); + break; + } + + case QCASAP_GET_DFS_NOL: + { + WLANSAP_Get_DfsNol( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter) +#else + pHddCtx->pvosContext +#endif + ); + } + break; + + case QCSAP_GET_ACL: + { + hddLog(LOG1, FL("QCSAP_GET_ACL")); + if (hdd_print_acl(pHostapdAdapter) != VOS_STATUS_SUCCESS) { + hddLog(LOGE, FL("QCSAP_GET_ACL returned Error: not completed")); + } + *value = 0; + break; + } + + case QCASAP_TX_CHAINMASK_CMD: + { + hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_PARAM_TX_CHAIN_MASK, + PDEV_CMD); + break; + } + + case QCASAP_RX_CHAINMASK_CMD: + { + hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_PARAM_RX_CHAIN_MASK, + PDEV_CMD); + break; + } + + case QCASAP_NSS_CMD: + { + hddLog(LOG1, "QCASAP_NSS_CMD"); + *value = wma_cli_get_command(pHddCtx->pvosContext, + (int)pHostapdAdapter->sessionId, + (int)WMI_VDEV_PARAM_NSS, + VDEV_CMD); + break; + } + + default: + hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd); + ret = -EINVAL; + break; + + } + + return ret; +} + +/* Usage: + BLACK_LIST = 0 + WHITE_LIST = 1 + ADD MAC = 0 + REMOVE MAC = 1 + + mac addr will be accepted as a 6 octet mac address with each octet inputted in hex + for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33 + while using this ioctl + + Syntax: + iwpriv softap.0 modify_acl + <6 octet mac addr> + + Examples: + eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list + iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0 + eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list + iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1 +*/ +int iw_softap_modify_acl(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + v_BYTE_t *value = (v_BYTE_t*)extra; + v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE]; + int listType, cmd, i; + int ret = 0; /* success */ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + ENTER(); + for (i=0; ioperatingChannel; + return 0; +} + +int +static iw_softap_set_max_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + int *value = (int *)extra; + int set_value; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + if (NULL == value) + return -ENOMEM; + + /* Assign correct slef MAC address */ + vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + + set_value = value[0]; + if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed", + __func__); + return -EIO; + } + + return 0; +} + +int +static iw_display_data_path_snapshot(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + /* Function initiating dumping states of + * HDD(WMM Tx Queues) + * TL State (with Per Client infor) + * DXE Snapshot (Called at the end of TL Snapshot) + */ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + hddLog(LOGE, "%s: called for SAP",__func__); + hdd_wmm_tx_snapshot(pHostapdAdapter); + WLANTL_TLDebugMessage(VOS_TRUE); + return 0; +} + +int +static iw_softap_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + int *value = (int *)extra; + int set_value; + tSirMacAddr bssid; + + if (NULL == value) + return -ENOMEM; + + vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + + set_value = value[0]; + if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pHostapdAdapter->sessionId, bssid, + pHostapdAdapter->device_mode, + set_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed", + __func__); + return -EIO; + } + + return 0; +} + +#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0) + +int +static iw_softap_getassoc_stamacaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo; + char *buf; + int cnt = 0; + int left; + int ret = 0; + /* maclist_index must be u32 to match user space */ + u32 maclist_index; + + /* + * NOTE WELL: this is a "get" ioctl but it uses an even ioctl + * number, and even numbered iocts are supposed to have "set" + * semantics. Hence the wireless extensions support in the kernel + * won't correctly copy the result to user space, so the ioctl + * handler itself must copy the data. Output format is 32-bit + * record length, followed by 0 or more 6-byte STA MAC addresses. + * + * Further note that due to the incorrect semantics, the "iwpriv" + * user space application is unable to correctly invoke this API, + * hence it is not registered in the hostapd_private_args. This + * API can only be invoked by directly invoking the ioctl() system + * call. + */ + + /* Make sure user space allocated a reasonable buffer size */ + if (wrqu->data.length < sizeof(maclist_index)) { + hddLog(LOG1, "%s: invalid userspace buffer", __func__); + return -EINVAL; + } + + /* allocate local buffer to build the response */ + buf = kmalloc(wrqu->data.length, GFP_KERNEL); + if (!buf) { + hddLog(LOG1, "%s: failed to allocate response buffer", __func__); + return -ENOMEM; + } + + /* start indexing beyond where the record count will be written */ + maclist_index = sizeof(maclist_index); + left = wrqu->data.length - maclist_index; + + spin_lock_bh(&pHostapdAdapter->staInfo_lock); + while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) { + if ((pStaInfo[cnt].isUsed) && + (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) { + memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA), + VOS_MAC_ADDR_SIZE); + maclist_index += VOS_MAC_ADDR_SIZE; + left -= VOS_MAC_ADDR_SIZE; + } + cnt++; + } + spin_unlock_bh(&pHostapdAdapter->staInfo_lock); + + *((u32 *)buf) = maclist_index; + wrqu->data.length = maclist_index; + if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) { + hddLog(LOG1, "%s: failed to copy response to user buffer", __func__); + ret = -EFAULT; + } + kfree(buf); + return ret; +} + +/* Usage: + mac addr will be accepted as a 6 octet mac address with each octet inputted in hex + for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33 + while using this ioctl + + Syntax: + iwpriv softap.0 disassoc_sta <6 octet mac address> + + e.g. + disassociate sta with mac addr 00:0a:f5:11:22:33 from softap + iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33 +*/ + +int +static iw_softap_disassoc_sta(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + v_U8_t *peerMacAddr; + + ENTER(); + /* iwpriv tool or framework calls this ioctl with + * data passed in extra (less than 16 octets); + */ + peerMacAddr = (v_U8_t *)(extra); + + hddLog(LOG1, "%s data " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peerMacAddr)); + hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr); + EXIT(); + return 0; +} + +int +static iw_softap_ap_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + WLANTL_TRANSFER_STA_TYPE statBuffer; + char *pstatbuf; + int len; + + memset(&statBuffer, 0, sizeof(statBuffer)); + WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, + &statBuffer, (v_BOOL_t)wrqu->data.flags); + + pstatbuf = kmalloc(wrqu->data.length, GFP_KERNEL); + if(NULL == pstatbuf) { + hddLog(LOG1, "unable to allocate memory"); + return -ENOMEM; + } + len = scnprintf(pstatbuf, wrqu->data.length, + "RUF=%d RMF=%d RBF=%d " + "RUB=%d RMB=%d RBB=%d " + "TUF=%d TMF=%d TBF=%d " + "TUB=%d TMB=%d TBB=%d", + (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, + (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt, + (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt, + (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, + (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt, + (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt); + + if (len > wrqu->data.length || + copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len)) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + kfree(pstatbuf); + return -EFAULT; + } + wrqu->data.length -= len; + kfree(pstatbuf); + return 0; +} + +static int iw_softap_set_channel_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + int *value = (int *)extra; + int startChannel = value[0]; + int endChannel = value[1]; + int band = value[2]; + VOS_STATUS status; + int ret = 0; /* success */ + + status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band); + if(status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"), + startChannel,endChannel, band); + ret = -EINVAL; + } + + pHddCtx->is_dynamic_channel_range_set = 1; + + return ret; +} + +int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + v_U32_t num_channels = 0; + v_U8_t i = 0; + v_U8_t bandStartChannel = RF_CHAN_1; + v_U8_t bandEndChannel = RF_CHAN_165; + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + tpChannelListInfo channel_list = (tpChannelListInfo) extra; + eCsrBand curBand = eCSR_BAND_ALL; + + if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand)) + { + hddLog(LOGE,FL("not able get the current frequency band")); + return -EIO; + } + wrqu->data.length = sizeof(tChannelListInfo); + ENTER(); + + if (eCSR_BAND_24 == curBand) + { + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + } + else if (eCSR_BAND_5G == curBand) + { + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + } + + hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, " + "bandEndChannel = %hu "), curBand, + bandStartChannel, bandEndChannel ); + + for( i = bandStartChannel; i <= bandEndChannel; i++ ) + { + if( NV_CHANNEL_ENABLE == regChannels[i].enabled ) + { + channel_list->channels[num_channels] = rfChannels[i].channelNum; + num_channels++; + } + } + + + hddLog(LOG1,FL(" number of channels %d"), num_channels); + + if (num_channels > IW_MAX_FREQUENCIES) + { + num_channels = IW_MAX_FREQUENCIES; + } + + channel_list->num_channels = num_channels; + EXIT(); + + return 0; +} + +static +int iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + eHalStatus status; + v_U32_t length = DOT11F_IE_RSN_MAX_LEN; + v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN]; + ENTER(); + hddLog(LOG1,FL("getGEN_IE ioctl")); + // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.) + status = WLANSap_getstationIE_information( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), +#else + pVosContext, +#endif + &length, + genIeBytes + ); + + length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN); + if (wrqu->data.length < length || + copy_to_user(wrqu->data.pointer, + (v_VOID_t*)genIeBytes, length)) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + wrqu->data.length = length; + + hddLog(LOG1,FL(" RSN IE of %d bytes returned"), wrqu->data.length ); + + + EXIT(); + return 0; +} +static +int iw_get_WPSPBCProbeReqIEs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs; + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + ENTER(); + + hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl")); + memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs)); + + WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen; + vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE, + pHddApCtx->WPSPBCProbeReq.probeReqIE, + WPSPBCProbeReqIEs.probeReqIELen); + vos_mem_copy(&WPSPBCProbeReqIEs.macaddr, + pHddApCtx->WPSPBCProbeReq.peerMacAddr, + sizeof(v_MACADDR_t)); + if (copy_to_user(wrqu->data.pointer, + (void *)&WPSPBCProbeReqIEs, + sizeof(WPSPBCProbeReqIEs))) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen; + hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr)); + up(&pHddApCtx->semWpsPBCOverlapInd); + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief iw_set_auth_hostap() - + This function sets the auth type received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int iw_set_auth_hostap(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + ENTER(); + switch(wrqu->param.flags & IW_AUTH_INDEX) + { + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if(wrqu->param.value) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure started %d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED; + } + else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure stopped=%d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED; + } + + hdd_softap_tkip_mic_fail_counter_measure(pAdapter, + wrqu->param.value); + } + break; + + default: + + hddLog(LOGW, "%s called with unsupported auth type %d", __func__, + wrqu->param.flags & IW_AUTH_INDEX); + break; + } + + EXIT(); + return 0; +} + +static int iw_set_ap_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + int retval = 0; + VOS_STATUS vstatus; + struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; + v_U8_t groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int key_index; + struct iw_point *encoding = &wrqu->encoding; + tCsrRoamSetKey setKey; +// tCsrRoamRemoveKey RemoveKey; + int i; + + ENTER(); + + key_index = encoding->flags & IW_ENCODE_INDEX; + + if(key_index > 0) { + + /*Convert from 1-based to 0-based keying*/ + key_index--; + } + if(!ext->key_len) { +#if 0 + /*Set the encryption type to NONE*/ +#if 0 + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; +#endif + + RemoveKey.keyId = key_index; + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + vos_mem_copy(RemoveKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE); + } + else { + vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE); + } + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + case IW_ENCODE_ALG_WEP: + RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + break; + case IW_ENCODE_ALG_TKIP: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + break; + case IW_ENCODE_ALG_CCMP: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + default: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d", + __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac)); + ); +#ifdef WLAN_FEATURE_MBSSID + vstatus = WLANSAP_DelKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &RemoveKey ); +#else + vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey ); +#endif + + if ( vstatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d", + __LINE__, vstatus ); + retval = -EINVAL; + } +#endif + return retval; + + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + + setKey.keyId = key_index; + setKey.keyLength = ext->key_len; + + if(ext->key_len <= CSR_MAX_KEY_LEN) { + vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len); + } + + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE); + } + else { + + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE); + } + if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + { + setKey.keyDirection = eSIR_TX_DEFAULT; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE); + } + + /*For supplicant pae role is zero*/ + setKey.paeRole = 0; + + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case IW_ENCODE_ALG_WEP: + setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + pHddApCtx->uPrivacy = 1; + hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy); + break; + + case IW_ENCODE_ALG_TKIP: + { + v_U8_t *pKey = &setKey.Key[0]; + + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey,ext->key,16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16],&ext->key[24],8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24],&ext->key[16],8); + + } + break; + + case IW_ENCODE_ALG_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + + default: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength, + setKey.keyId); + for(i=0; i< ext->key_len; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%02x"), setKey.Key[i]); + +#ifdef WLAN_FEATURE_MBSSID + vstatus = WLANSAP_SetKeySta( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &setKey ); +#else + vstatus = WLANSAP_SetKeySta( pVosContext, &setKey ); +#endif + + if ( vstatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus ); + retval = -EINVAL; + } + + return retval; +} + + +static int iw_set_ap_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ +#if 0 + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + struct iw_mlme *mlme = (struct iw_mlme *)extra; + + ENTER(); + + //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED + switch (mlme->cmd) { + case IW_MLME_DISASSOC: + case IW_MLME_DEAUTH: + hddLog(LOG1, "Station disassociate"); + if( pAdapter->conn_info.connState == eConnectionState_Associated ) + { + eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED; + + if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE ) + reason = eCSR_DISCONNECT_REASON_MIC_ERROR; + + status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason); + + //clear all the reason codes + if (status != 0) + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status ); + } + + netif_stop_queue(dev); + netif_carrier_off(dev); + } + else + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd ); + } + default: + hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd ); + return -EINVAL; + }//end of switch + EXIT(); +#endif + return 0; +// return status; +} + +static int iw_get_ap_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + v_U32_t status = 0; + + status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu); + + return status; +} + +static int iw_get_ap_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + v_U32_t status = 0; + + status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu); + + return status; +} + +static int iw_get_ap_freq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + v_U32_t status = FALSE, channel = 0, freq = 0; + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal; + hdd_hostapd_state_t *pHostapdState; + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pHostapdAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + + if(pHostapdState->bssState == BSS_STOP ) + { + if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel) + != eHAL_STATUS_SUCCESS) + { + return -EIO; + } + else + { + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + } + else + { + channel = pHddApCtx->operatingChannel; + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + return 0; +} + +static int iw_get_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int status = 0; + + wrqu->mode = IW_MODE_MASTER; + + return status; +} + +static int iw_softap_setwpsie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + hdd_hostapd_state_t *pHostapdState; + eHalStatus halStatus= eHAL_STATUS_SUCCESS; + u_int8_t *wps_genie; + u_int8_t *fwps_genie; + u_int8_t *pos; + tpSap_WPSIE pSap_WPSIe; + u_int8_t WPSIeType; + u_int16_t length; + struct iw_point s_priv_data; + + ENTER(); + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + return -EINVAL; + } + + if ((NULL == s_priv_data.pointer) || + (s_priv_data.length < QCSAP_MAX_WSC_IE)) { + return -EINVAL; + } + + wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + + if (NULL == wps_genie) { + hddLog(LOG1, + "%s: failed to alloc memory and copy data from user buffer", + __func__); + return -EFAULT; + } + + fwps_genie = wps_genie; + + pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE)); + if (NULL == pSap_WPSIe) + { + hddLog(LOGE, "VOS unable to allocate memory"); + kfree(fwps_genie); + return -ENOMEM; + } + vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE)); + + hddLog(LOG1,"%s WPS IE type[0x%X] IE[0x%X], LEN[%d]", __func__, wps_genie[0], wps_genie[1], wps_genie[2]); + WPSIeType = wps_genie[0]; + if ( wps_genie[0] == eQC_WPS_BEACON_IE) + { + pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE; + wps_genie = wps_genie + 1; + switch ( wps_genie[0] ) + { + case DOT11F_EID_WPA: + if (wps_genie[1] < 2 + 4) + { + vos_mem_free(pSap_WPSIe); + kfree(fwps_genie); + return -EINVAL; + } + else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0) + { + hddLog (LOG1, "%s Set WPS BEACON IE(len %d)",__func__, wps_genie[1]+2); + pos = &wps_genie[6]; + while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) ) + { + switch((u_int16_t)(*pos<<8) | *(pos+1)) + { + case HDD_WPS_ELEM_VERSION: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version = *pos; + hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.Version); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_VER_PRESENT; + pos += 1; + break; + + case HDD_WPS_ELEM_WPS_STATE: + pos +=4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState = *pos; + hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.wpsState); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_STATE_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_APSETUPLOCK: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked = *pos; + hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.APSetupLocked); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_APSETUPLOCK_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_SELECTEDREGISTRA: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra = *pos; + hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistra); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRA_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_DEVICE_PASSWORD_ID: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID = (*pos<<8) | *(pos+1); + hddLog(LOG1, "Password ID: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.DevicePasswordID); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_DEVICEPASSWORDID_PRESENT; + pos += 2; + break; + case HDD_WPS_ELEM_REGISTRA_CONF_METHODS: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1); + hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.SelectedRegistraCfgMethod); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT; + pos += 2; + break; + + case HDD_WPS_ELEM_UUID_E: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSBeaconIE.UUID_E, pos, length); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_UUIDE_PRESENT; + pos += length; + break; + case HDD_WPS_ELEM_RF_BANDS: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand = *pos; + hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSBeaconIE.RFBand); + pSap_WPSIe->sapwpsie.sapWPSBeaconIE.FieldPresent |= WPS_BEACON_RF_BANDS_PRESENT; + pos += 1; + break; + + default: + hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)", (*pos<<8 | *(pos+1))); + vos_mem_free(pSap_WPSIe); + kfree(fwps_genie); + return -EINVAL; + } + } + } + else { + hddLog (LOGE, "%s WPS IE Mismatch %X", + __func__, wps_genie[0]); + } + break; + + default: + hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]); + vos_mem_free(pSap_WPSIe); + kfree(fwps_genie); + return 0; + } + } + else if( wps_genie[0] == eQC_WPS_PROBE_RSP_IE) + { + pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE; + wps_genie = wps_genie + 1; + switch ( wps_genie[0] ) + { + case DOT11F_EID_WPA: + if (wps_genie[1] < 2 + 4) + { + vos_mem_free(pSap_WPSIe); + kfree(fwps_genie); + return -EINVAL; + } + else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0) + { + hddLog (LOG1, "%s Set WPS PROBE RSP IE(len %d)",__func__, wps_genie[1]+2); + pos = &wps_genie[6]; + while (((size_t)pos - (size_t)&wps_genie[6]) < (wps_genie[1] - 4) ) + { + switch((u_int16_t)(*pos<<8) | *(pos+1)) + { + case HDD_WPS_ELEM_VERSION: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version = *pos; + hddLog(LOG1, "WPS version %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Version); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_VER_PRESENT; + pos += 1; + break; + + case HDD_WPS_ELEM_WPS_STATE: + pos +=4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState = *pos; + hddLog(LOG1, "WPS State %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.wpsState); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_STATE_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_APSETUPLOCK: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked = *pos; + hddLog(LOG1, "AP setup lock %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.APSetupLocked); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_APSETUPLOCK_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_SELECTEDREGISTRA: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra = *pos; + hddLog(LOG1, "Selected Registra %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistra); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRA_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_DEVICE_PASSWORD_ID: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID = (*pos<<8) | *(pos+1); + hddLog(LOG1, "Password ID: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DevicePasswordID); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICEPASSWORDID_PRESENT; + pos += 2; + break; + case HDD_WPS_ELEM_REGISTRA_CONF_METHODS: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod = (*pos<<8) | *(pos+1); + hddLog(LOG1, "Select Registra Config Methods: %x", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT; + pos += 2; + break; + case HDD_WPS_ELEM_RSP_TYPE: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType = *pos; + hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ResponseType); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RESPONSETYPE_PRESENT; + pos += 1; + break; + case HDD_WPS_ELEM_UUID_E: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.UUID_E, pos, length); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_UUIDE_PRESENT; + pos += length; + break; + + case HDD_WPS_ELEM_MANUFACTURER: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.num_name = length; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.Manufacture.name, pos, length); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MANUFACTURE_PRESENT; + pos += length; + break; + + case HDD_WPS_ELEM_MODEL_NAME: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.num_text = length; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelName.text, pos, length); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNAME_PRESENT; + pos += length; + break; + case HDD_WPS_ELEM_MODEL_NUM: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.num_text = length; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ModelNumber.text, pos, length); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_MODELNUMBER_PRESENT; + pos += length; + break; + case HDD_WPS_ELEM_SERIAL_NUM: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.num_text = length; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SerialNumber.text, pos, length); + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_SERIALNUMBER_PRESENT; + pos += length; + break; + case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory = (*pos<<8 | *(pos+1)); + hddLog(LOG1, "primary dev category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceCategory); + pos += 2; + + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.PrimaryDeviceOUI, pos, HDD_WPS_DEVICE_OUI_LEN); + hddLog(LOG1, "primary dev oui: %02x, %02x, %02x, %02x", pos[0], pos[1], pos[2], pos[3]); + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory = (*pos<<8 | *(pos+1)); + hddLog(LOG1, "primary dev sub category: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceSubCategory); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT; + break; + case HDD_WPS_ELEM_DEVICE_NAME: + pos += 2; + length = *pos<<8 | *(pos+1); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.num_text = length; + vos_mem_copy(pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.DeviceName.text, pos, length); + pos += length; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_DEVICENAME_PRESENT; + break; + case HDD_WPS_ELEM_CONFIG_METHODS: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.ConfigMethod = (*pos<<8) | *(pos+1); + hddLog(LOG1, "Config Methods: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.SelectedRegistraCfgMethod); + pos += 2; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_CONFIGMETHODS_PRESENT; + break; + + case HDD_WPS_ELEM_RF_BANDS: + pos += 4; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand = *pos; + hddLog(LOG1, "RF band: %d", pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.RFBand); + pos += 1; + pSap_WPSIe->sapwpsie.sapWPSProbeRspIE.FieldPresent |= WPS_PROBRSP_RF_BANDS_PRESENT; + break; + } // switch + } + } + else + { + hddLog (LOGE, "%s WPS IE Mismatch %X",__func__, wps_genie[0]); + } + + } // switch + } + +#ifdef WLAN_FEATURE_MBSSID + halStatus = WLANSAP_Set_WpsIe(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), pSap_WPSIe); +#else + halStatus = WLANSAP_Set_WpsIe(pVosContext, pSap_WPSIe); +#endif + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + if( pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE) + { + //hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + //v_CONTEXT_t pVosContext = pHostapdAdapter->pvosContext; +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_Update_WpsIe ( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter) ); +#else + WLANSAP_Update_WpsIe ( pVosContext ); +#endif + } + + vos_mem_free(pSap_WPSIe); + kfree(fwps_genie); + EXIT(); + return halStatus; +} + +static int iw_softap_stopbss(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = NULL; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return status; + } + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); +#else + status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext); +#endif + if (VOS_IS_STATUS_SUCCESS(status)) + { + hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("%s: ERROR: HDD vos wait for single_event failed!!"), + __func__); + VOS_ASSERT(0); + } + } + clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode); + } + EXIT(); + return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY; +} + +static int iw_softap_version(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + + ENTER(); + hdd_wlan_get_version(pHostapdAdapter, wrqu, extra); + EXIT(); + return 0; +} + +VOS_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len) +{ + v_U8_t i; + v_U8_t maxSta = 0; + int len = 0; + const char sta_info_header[] = "staId staAddress"; + hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); + + len = scnprintf(pBuf, buf_len, sta_info_header); + pBuf += len; + buf_len -= len; + + if(pHddCtx) + maxSta = pHddCtx->cfg_ini->maxNumberOfPeers; + + for (i = 0; i <= maxSta; i++) + { + if(pAdapter->aStaInfo[i].isUsed) + { + len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x", + pAdapter->aStaInfo[i].ucSTAId, + pAdapter->aStaInfo[i].macAddrSTA.bytes[0], + pAdapter->aStaInfo[i].macAddrSTA.bytes[1], + pAdapter->aStaInfo[i].macAddrSTA.bytes[2], + pAdapter->aStaInfo[i].macAddrSTA.bytes[3], + pAdapter->aStaInfo[i].macAddrSTA.bytes[4], + pAdapter->aStaInfo[i].macAddrSTA.bytes[5]); + pBuf += len; + buf_len -= len; + } + if(WE_GET_STA_INFO_SIZE > buf_len) + { + break; + } + } + return VOS_STATUS_SUCCESS; +} + +static int iw_softap_get_sta_info(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + VOS_STATUS status; + ENTER(); + status = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__); + return -EINVAL; + } + wrqu->data.length = strlen(extra); + EXIT(); + return 0; +} + +static int iw_set_ap_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; +#endif + eHalStatus halStatus= eHAL_STATUS_SUCCESS; + u_int8_t *genie = (u_int8_t *)extra; + + ENTER(); + + if(!wrqu->data.length) + { + EXIT(); + return 0; + } + + switch (genie[0]) + { + case DOT11F_EID_WPA: + case DOT11F_EID_RSN: + if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) + { + hdd_softap_Deregister_BC_STA(pHostapdAdapter); + hdd_softap_Register_BC_STA(pHostapdAdapter, 1); + } + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1; +#ifdef WLAN_FEATURE_MBSSID + halStatus = WLANSAP_Set_WPARSNIes(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), genie, wrqu->data.length); +#else + halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length); +#endif + break; + + default: + hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]); + halStatus = 0; + } + + EXIT(); + return halStatus; +} + +VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, + tSirMacAddr macAddress) +{ + eHalStatus hstatus; + unsigned long rc; + struct linkspeedContext context; + tSirLinkSpeedInfo *linkspeed_req; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + linkspeed_req = (tSirLinkSpeedInfo *)vos_mem_malloc(sizeof(*linkspeed_req)); + if (NULL == linkspeed_req) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Request Buffer Alloc Fail", __func__); + return VOS_STATUS_E_INVAL; + } + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = LINK_CONTEXT_MAGIC; + + vos_mem_copy(linkspeed_req->peer_macaddr, macAddress, sizeof(tSirMacAddr) ); + hstatus = sme_GetLinkSpeed( WLAN_HDD_GET_HAL_CTX(pAdapter), + linkspeed_req, + &context, + hdd_GetLink_SpeedCB); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics for link speed", + __func__); + vos_mem_free(linkspeed_req); + } + else + { + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timed out while retrieving link speed", + __func__); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + return VOS_STATUS_SUCCESS; +} + + +int iw_get_softap_linkspeed(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) + +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + hdd_context_t *pHddCtx; + char *pLinkSpeed = (char*)extra; + char *pmacAddress; + v_U32_t link_speed = 0; + int len = sizeof(v_U32_t)+1; + tSirMacAddr macAddress; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + int rc, valid, i; + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + valid = wlan_hdd_validate_context(pHddCtx); + + if (0 != valid) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context not valid")); + return valid; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d\n", __func__, wrqu->data.length); + + if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) + { + pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL); + if (NULL == pmacAddress) { + hddLog(LOG1, "unable to allocate memory"); + return -ENOMEM; + } + if (copy_from_user((void *)pmacAddress, + wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + kfree(pmacAddress); + return -EFAULT; + } + pmacAddress[MAC_ADDRESS_STR_LEN] = '\0'; + + status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress ); + kfree(pmacAddress); + + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed")); + } + } + /* If no mac address is passed and/or its length is less than 17, + * link speed for first connected client will be returned. + */ + if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status )) { + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + if (pHostapdAdapter->aStaInfo[i].isUsed && + (!vos_is_macaddr_broadcast(&pHostapdAdapter->aStaInfo[i].macAddrSTA))) { + vos_copy_macaddr((v_MACADDR_t *)macAddress, + &pHostapdAdapter->aStaInfo[i].macAddrSTA); + status = VOS_STATUS_SUCCESS; + break; + } + } + } + if (!VOS_IS_STATUS_SUCCESS(status )) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid peer macaddress")); + return -EINVAL; + } + status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter, + macAddress); + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME linkspeed")); + return -EINVAL; + } + + link_speed = pHostapdAdapter->ls_stats.estLinkSpeed; + + /* linkspeed in units of 500 kbps */ + link_speed = link_speed / 500; + wrqu->data.length = len; + rc = snprintf(pLinkSpeed, len, "%u", link_speed); + if ((rc < 0) || (rc >= len)) + { + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed")); + return -EIO; + } + + return 0; +} + +static const iw_handler hostapd_handler[] = +{ + (iw_handler) NULL, /* SIOCSIWCOMMIT */ + (iw_handler) NULL, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) NULL, /* SIOCSIWFREQ */ + (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */ + (iw_handler) NULL, /* SIOCSIWMODE */ + (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) NULL, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + (iw_handler) NULL, /* SIOCSIWSPY */ + (iw_handler) NULL, /* SIOCGIWSPY */ + (iw_handler) NULL, /* SIOCSIWTHRSPY */ + (iw_handler) NULL, /* SIOCGIWTHRSPY */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) NULL, /* SIOCGIWAP */ + (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) NULL, /* SIOCSIWSCAN */ + (iw_handler) NULL, /* SIOCGIWSCAN */ + (iw_handler) NULL, /* SIOCSIWESSID */ + (iw_handler) NULL, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) NULL, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWRATE */ + (iw_handler) NULL, /* SIOCGIWRATE */ + (iw_handler) NULL, /* SIOCSIWRTS */ + (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */ + (iw_handler) NULL, /* SIOCSIWFRAG */ + (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */ + (iw_handler) NULL, /* SIOCSIWTXPOW */ + (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) NULL, /* SIOCSIWRETRY */ + (iw_handler) NULL, /* SIOCGIWRETRY */ + (iw_handler) NULL, /* SIOCSIWENCODE */ + (iw_handler) NULL, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */ + (iw_handler) NULL, /* SIOCGIWGENIE */ + (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */ + (iw_handler) NULL, /* SIOCGIWAUTH */ + (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) NULL, /* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ +}; + +/* + * Note that the following ioctls were defined with semantics which + * cannot be handled by the "iwpriv" userspace application and hence + * they are not included in the hostapd_private_args array + * QCSAP_IOCTL_ASSOC_STA_MACADDR + */ + +static const struct iw_priv_args hostapd_private_args[] = { + { QCSAP_IOCTL_SETPARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" }, + { QCSAP_IOCTL_SETPARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" }, + { QCSAP_PARAM_MAX_ASSOC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" }, + { QCSAP_PARAM_HIDE_SSID, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" }, + { QCSAP_PARAM_SET_MC_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" }, + { QCSAP_PARAM_SET_TXRX_FW_STATS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txrx_fw_stats" }, + { QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMccLatency" }, + { QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMccQuota" }, + { QCSAP_PARAM_AUTO_CHANNEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" }, + { QCSAP_PARAM_SET_CHANNEL_CHANGE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setChanChange" }, + + /* Sub-cmds DBGLOG specific commands */ + { QCSAP_DBGLOG_LOG_LEVEL , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_loglevel" }, + + { QCSAP_DBGLOG_VAP_ENABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_vapon" }, + + { QCSAP_DBGLOG_VAP_DISABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_vapoff" }, + + { QCSAP_DBGLOG_MODULE_ENABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_modon" }, + + { QCSAP_DBGLOG_MODULE_DISABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_modoff" }, + + { QCSAP_DBGLOG_MOD_LOG_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_mod_loglevel" }, + + { QCSAP_DBGLOG_TYPE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_type" }, + { QCSAP_DBGLOG_REPORT_ENABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_report" }, + { QCASAP_TXRX_FWSTATS_RESET, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txrx_fw_st_rst" }, + { QCSAP_PARAM_RTSCTS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "enablertscts" }, + + { QCASAP_SET_11N_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11NRates" }, + + { QCASAP_SET_VHT_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11ACRates" }, + + { QCASAP_SHORT_GI, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "enable_short_gi" }, + + { QCSAP_SET_AMPDU, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ampdu" }, + + { QCSAP_SET_AMSDU, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "amsdu" }, + + { QCSAP_GTX_HT_MCS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxHTMcs" }, + + { QCSAP_GTX_VHT_MCS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxVHTMcs" }, + + { QCSAP_GTX_USRCFG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxUsrCfg" }, + + { QCSAP_GTX_THRE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxThre" }, + + { QCSAP_GTX_MARGIN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxMargin" }, + + { QCSAP_GTX_STEP, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxStep" }, + + { QCSAP_GTX_MINTPC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxMinTpc" }, + + { QCSAP_GTX_BWMASK, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxBWMask" }, + + { QCSAP_PARAM_CLR_ACL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setClearAcl" }, + + { QCSAP_PARAM_ACL_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setAclMode" }, + +#ifdef QCA_PKT_PROTO_TRACE + { QCASAP_SET_DEBUG_LOG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setDbgLvl" }, +#endif /* QCA_PKT_PROTO_TRACE */ + + { QCASAP_SET_TM_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTmLevel" }, + + { QCASAP_SET_DFS_IGNORE_CAC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setDfsIgnoreCAC" }, + + { QCASAP_SET_DFS_NOL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setdfsnol" }, + + { QCASAP_SET_DFS_TARGET_CHNL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setNextChnl" }, + + { QCASAP_SET_RADAR_CMD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setRadar" }, +#ifdef IPA_UC_OFFLOAD + { QCSAP_IPA_UC_STAT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ipaucstat" }, +#endif /* IPA_UC_OFFLOAD */ + + { QCASAP_TX_CHAINMASK_CMD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txchainmask" }, + + { QCASAP_RX_CHAINMASK_CMD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_rxchainmask" }, + + { QCASAP_NSS_CMD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_nss" }, + + { QCASAP_SET_PHYMODE, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setphymode" }, + + { QCSAP_IOCTL_GETPARAM, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" }, + { QCSAP_IOCTL_GETPARAM, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" }, + { QCSAP_PARAM_MAX_ASSOC, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" }, + { QCSAP_PARAM_GET_WLAN_DBG, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" }, + { QCSAP_PARAM_AUTO_CHANNEL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" }, + { QCSAP_GTX_BWMASK, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxBWMask" }, + { QCSAP_GTX_MINTPC, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxMinTpc" }, + { QCSAP_GTX_STEP, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxStep" }, + { QCSAP_GTX_MARGIN, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxMargin" }, + { QCSAP_GTX_THRE, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxThre" }, + { QCSAP_GTX_USRCFG, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxUsrCfg" }, + { QCSAP_GTX_VHT_MCS, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxVHTMcs" }, + { QCSAP_GTX_HT_MCS, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_gtxHTMcs" }, + { QCASAP_SHORT_GI, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_short_gi" }, + { QCSAP_PARAM_RTSCTS, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts" }, + { QCASAP_GET_DFS_NOL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol" }, + { QCSAP_GET_ACL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_acl_list" }, + { QCASAP_TX_CHAINMASK_CMD, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_txchainmask" }, + { QCASAP_RX_CHAINMASK_CMD, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rxchainmask" }, + { QCASAP_NSS_CMD, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_nss" }, + + { QCSAP_IOCTL_GET_STAWPAIE, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "get_staWPAIE" }, + { QCSAP_IOCTL_SETWPAIE, + IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE | IW_PRIV_SIZE_FIXED, 0, "setwpaie" }, + { QCSAP_IOCTL_STOPBSS, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" }, + { QCSAP_IOCTL_VERSION, 0, + IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" }, + { QCSAP_IOCTL_GET_STA_INFO, 0, + IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" }, + { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES, + IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" }, + { QCSAP_IOCTL_GET_CHANNEL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" }, + { QCSAP_IOCTL_DISASSOC_STA, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" }, + { QCSAP_IOCTL_AP_STATS, 0, + IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" }, + { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED, + IW_PRIV_TYPE_CHAR | 18, + IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" }, + + { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" }, + /* handlers for sub-ioctl */ + { WE_SET_WLAN_DBG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setwlandbg" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_LOG_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dump" }, + { WE_P2P_NOA_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "SetP2pPs" }, + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_CREDENTIAL, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccCrdnl" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccConfig" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_MODIFY_ACL, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, + 0, + "modify_acl" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_GET_CHANNEL_LIST, + 0, + IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo), + "getChannelList" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_TX_POWER, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxPower" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower" }, + + { QCSAP_IOCTL_DATAPATH_SNAP_SHOT, + IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE, + 0, + "dataSnapshot" }, + + /* Set HDD CFG Ini param */ + { QCSAP_IOCTL_SET_INI_CFG, + IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, + 0, + "setConfig" }, + + /* Get HDD CFG Ini param */ + { QCSAP_IOCTL_GET_INI_CFG, + 0, + IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, + "getConfig" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_TWO_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, + "" }, + /* handlers for sub-ioctl */ +#ifdef DEBUG + { QCSAP_IOCTL_SET_FW_CRASH_INJECT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, + "crash_inject" }, +#endif +}; + +static const iw_handler hostapd_private[] = { + [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl + [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl + [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE + [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie, + [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss + [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version + [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs, + [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel, + [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr, + [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta, + [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats, + [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone, + [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone, + [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range, + [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl, + [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list, + [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info, + [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed, + [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power, + [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power, + [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot, + [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] = iw_softap_set_ini_cfg, + [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] = iw_softap_get_ini_cfg, + [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = + iw_softap_set_two_ints_getnone, +}; +const struct iw_handler_def hostapd_handler_def = { + .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]), + .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]), + .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]), + .standard = (iw_handler *)hostapd_handler, + .private = (iw_handler *)hostapd_private, + .private_args = hostapd_private_args, + .get_wireless_stats = NULL, +}; + +struct net_device_ops net_ops_struct = { + .ndo_open = hdd_hostapd_open, + .ndo_stop = hdd_hostapd_stop, + .ndo_uninit = hdd_hostapd_uninit, + .ndo_start_xmit = hdd_softap_hard_start_xmit, + .ndo_tx_timeout = hdd_softap_tx_timeout, + .ndo_get_stats = hdd_softap_stats, + .ndo_set_mac_address = hdd_hostapd_set_mac_address, + .ndo_do_ioctl = hdd_hostapd_ioctl, + .ndo_change_mtu = hdd_hostapd_change_mtu, + .ndo_select_queue = hdd_hostapd_select_queue, + }; + +int hdd_set_hostapd(hdd_adapter_t *pAdapter) +{ + return VOS_STATUS_SUCCESS; +} + +void hdd_set_ap_ops( struct net_device *pWlanHostapdDev ) +{ + pWlanHostapdDev->netdev_ops = &net_ops_struct; +} + +VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter ) +{ + hdd_hostapd_state_t * phostapdBuf; + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_STATUS status; +#ifdef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + v_CONTEXT_t sapContext=NULL; +#endif + int ret; + + ENTER(); + + if (pHddCtx->isLogpInProgress) { + hddLog(LOG1, FL("LOGP in Progress. Ignore!!!")); + return VOS_STATUS_E_FAILURE; + } + +#ifdef WLAN_FEATURE_MBSSID + sapContext = WLANSAP_Open(pVosContext); + if (sapContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: WLANSAP_Open failed!!")); + return VOS_STATUS_E_FAULT; + } + + pAdapter->sessionCtx.ap.sapContext = sapContext; + + status = WLANSAP_Start(sapContext); + if ( ! VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: WLANSAP_Start failed!!")); + WLANSAP_Close(sapContext); + return status; + } +#endif + + // Allocate the Wireless Extensions state structure + phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter ); + + sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode); + + // Zero the memory. This zeros the profile structure. + memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t)); + + // Set up the pointer to the Wireless Extensions state structure + // NOP + status = hdd_set_hostapd(pAdapter); + if(!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,("ERROR: hdd_set_hostapd failed!!")); +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_Close(sapContext); +#endif + return status; + } + + status = vos_event_init(&phostapdBuf->vosEvent); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!")); +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_Close(sapContext); +#endif + return status; + } + + init_completion(&pAdapter->session_close_comp_var); + init_completion(&pAdapter->session_open_comp_var); + + sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1); + + // Register as a wireless device + dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def; + + //Initialize the data path module + status = hdd_softap_init_tx_rx(pAdapter); + if ( !VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__); + } + + status = hdd_wmm_adapter_init( pAdapter ); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "hdd_wmm_adapter_init() failed with status code %08d [x%08x]", + status, status ); + goto error_wmm_init; + } + + set_bit(WMM_INIT_DONE, &pAdapter->event_flags); + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_ENABLE, + (int)pHddCtx->cfg_ini->enableSifsBurst, + PDEV_CMD); + + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: WMI_PDEV_PARAM_BURST_ENABLE set failed %d", + __func__, ret); + } + + wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), pAdapter ); + + return status; + +error_wmm_init: + hdd_softap_deinit_tx_rx( pAdapter ); +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_Close(sapContext); +#endif + EXIT(); + return status; +} + +hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name ) +{ + struct net_device *pWlanHostapdDev = NULL; + hdd_adapter_t *pHostapdAdapter = NULL; + v_CONTEXT_t pVosContext= NULL; + + hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: iface_name = %s", __func__, iface_name); + + pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, ether_setup, NUM_TX_QUEUES); + + if (pWlanHostapdDev != NULL) + { + pHostapdAdapter = netdev_priv(pWlanHostapdDev); + + //Init the net_device structure + ether_setup(pWlanHostapdDev); + + //Initialize the adapter context to zeros. + vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t )); + pHostapdAdapter->dev = pWlanHostapdDev; + pHostapdAdapter->pHddCtx = pHddCtx; + pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC; + + hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: pWlanHostapdDev = %p, " + "pHostapdAdapter = %p, " + "concurrency_mode=0x%x", __func__, + pWlanHostapdDev, + pHostapdAdapter, + (int)vos_get_concurrency_mode()); + + //Get the Global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + //Save the adapter context in global context for future. + ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter; + + //Init the net_device structure + strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ); + + hdd_set_ap_ops( pHostapdAdapter->dev ); + + pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT; + pWlanHostapdDev->mtu = HDD_DEFAULT_MTU; + + vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr)); + vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr)); + + pHostapdAdapter->offloads_configured = FALSE; + pWlanHostapdDev->destructor = free_netdev; + pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ; + pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy; + pHostapdAdapter->wdev.netdev = pWlanHostapdDev; + init_completion(&pHostapdAdapter->tx_action_cnf_event); + init_completion(&pHostapdAdapter->cancel_rem_on_chan_var); + init_completion(&pHostapdAdapter->rem_on_chan_ready_event); + init_completion(&pHostapdAdapter->ula_complete); + init_completion(&pHostapdAdapter->offchannel_tx_event); + init_completion(&pHostapdAdapter->scan_info.scan_req_completion_event); + init_completion(&pHostapdAdapter->scan_info.abortscan_event_var); + vos_event_init(&pHostapdAdapter->scan_info.scan_finished_event); + pHostapdAdapter->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP; + + SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev); + } + return pHostapdAdapter; +} + +VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held ) +{ + struct net_device *dev = pAdapter->dev; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if( rtnl_lock_held ) + { + if (strnchr(dev->name, strlen(dev->name), '%')) { + if( dev_alloc_name(dev, dev->name) < 0 ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__); + return VOS_STATUS_E_FAILURE; + } + } + if (register_netdevice(dev)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Failed:register_netdevice", __func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if (register_netdev(dev)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__); + return VOS_STATUS_E_FAILURE; + } + } + set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags); + + EXIT(); + return status; +} + +VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter) +{ +#ifdef WLAN_FEATURE_MBSSID + VOS_STATUS status; + v_PVOID_t sapContext=WLAN_HDD_GET_SAP_CTX_PTR(pAdapter); +#endif + + ENTER(); + + hdd_softap_deinit_tx_rx(pAdapter); + + /* if we are being called during driver unload, then the dev has already + been invalidated. if we are being called at other times, then we can + detach the wireless device handlers */ + if (pAdapter->dev) + { + pAdapter->dev->wireless_handlers = NULL; + } + +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_Stop(sapContext); + if ( ! VOS_IS_STATUS_SUCCESS( status ) ) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:WLANSAP_Stop", __func__); + } + + status = WLANSAP_Close(sapContext); + if ( ! VOS_IS_STATUS_SUCCESS( status ) ) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:WLANSAP_close", __func__); + } + pAdapter->sessionCtx.ap.sapContext = NULL; +#endif + + EXIT(); + return 0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ipa.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ipa.c new file mode 100644 index 0000000000000..f511e34321855 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ipa.c @@ -0,0 +1,3473 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +/*======================================================================== + +\file wlan_hdd_ipa.c + +\brief WLAN HDD and ipa interface implementation + +========================================================================*/ + +/*-------------------------------------------------------------------------- +Include Files +------------------------------------------------------------------------*/ +#ifdef IPA_OFFLOAD +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vos_sched.h" +#include "tl_shim.h" +#include "wlan_qct_tl.h" + +#ifdef IPA_UC_OFFLOAD +#include "wma.h" +#include "wma_api.h" +#endif /* IPA_UC_OFFLOAD */ + +#define HDD_IPA_DESC_BUFFER_RATIO 4 +#define HDD_IPA_IPV4_NAME_EXT "_ipv4" +#define HDD_IPA_IPV6_NAME_EXT "_ipv6" + +#define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 1000 +#ifdef IPA_UC_OFFLOAD +#define HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 12 +#define HDD_IPA_UC_WLAN_8023_HDR_SIZE 14 +/* WDI TX and RX PIPE */ +#define HDD_IPA_UC_NUM_WDI_PIPE 2 +#define HDD_IPA_UC_MAX_PENDING_EVENT 33 +#endif /* IPA_UC_OFFLOAD */ + +#ifdef IPA_UC_OFFLOAD +typedef enum { + HDD_IPA_UC_OPCODE_TX_SUSPEND = 0, + HDD_IPA_UC_OPCODE_TX_RESUME = 1, + HDD_IPA_UC_OPCODE_RX_SUSPEND = 2, + HDD_IPA_UC_OPCODE_RX_RESUME = 3, + HDD_IPA_UC_OPCODE_STATS = 4, + /* keep this last */ + HDD_IPA_UC_OPCODE_MAX +} hdd_ipa_uc_op_code; + +typedef enum { + HDD_IPA_UC_STAT_REASON_NONE, + HDD_IPA_UC_STAT_REASON_DEBUG, + HDD_IPA_UC_STAT_REASON_BW_CAL +} hdd_ipa_uc_stat_reason; +#endif /* IPA_UC_OFFLOAD */ + +struct llc_snap_hdr { + uint8_t dsap; + uint8_t ssap; + uint8_t resv[4]; + __be16 eth_type; +} __packed; + +struct hdd_ipa_tx_hdr { + struct ethhdr eth; + struct llc_snap_hdr llc_snap; +} __packed; + +/* For Tx pipes, use 802.3 Header format */ +static struct hdd_ipa_tx_hdr ipa_tx_hdr = { + { + {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF}, + {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF}, + 0x00 /* length can be zero */ + }, + { + /* LLC SNAP header 8 bytes */ + 0xaa, 0xaa, + {0x03, 0x00, 0x00, 0x00}, + 0x0008 /* type value(2 bytes) ,filled by wlan */ + /* 0x0800 - IPV4, 0x86dd - IPV6 */ + } +}; + +#ifdef IPA_UC_OFFLOAD +struct frag_header { + uint32 + reserved16:16, + length:16; + uint32 reserved32; +} __packed; + +struct ipa_header { + uint32 + reserved:24, + vdev_id:8; +} __packed; + +struct hdd_ipa_uc_tx_hdr { + struct frag_header frag_hd; + struct ipa_header ipa_hd; + struct ethhdr eth; +} __packed; + +/* For Tx pipes, use 802.3 Header format */ +struct hdd_ipa_uc_tx_hdr ipa_uc_tx_hdr = { + { + 0x00000000, + 0x00000000 + }, + { + 0x00000000 + }, + { + {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, + {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, + 0x0008 + } +}; +#endif /* IPA_UC_OFFLOAD */ + +/* + +----------+----------+--------------+--------+ + | Reserved | QCMAP ID | interface id | STA ID | + +----------+----------+--------------+--------+ + */ +struct hdd_ipa_cld_hdr { + uint8_t reserved[2]; + uint8_t iface_id; + uint8_t sta_id; +} __packed; + +struct hdd_ipa_rx_hdr { + struct hdd_ipa_cld_hdr cld_hdr; + struct ethhdr eth; +} __packed; + +struct hdd_ipa_pm_tx_cb { + struct hdd_ipa_iface_context *iface_context; + struct ipa_rx_data *ipa_tx_desc; +}; + +#ifdef IPA_UC_OFFLOAD +struct hdd_ipa_uc_rx_hdr { + struct ethhdr eth; +} __packed; +#endif /* IPA_UC_OFFLOAD */ + +#define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr) +#ifdef IPA_UC_OFFLOAD +#define HDD_IPA_UC_WLAN_CLD_HDR_LEN 0 +#endif /* IPA_UC_OFFLOAD */ + +#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_tx_hdr) +#ifdef IPA_UC_OFFLOAD +#define HDD_IPA_UC_WLAN_TX_HDR_LEN sizeof(ipa_uc_tx_hdr) +#endif /* IPA_UC_OFFLOAD */ + +#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr) +#ifdef IPA_UC_OFFLOAD +#define HDD_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_uc_rx_hdr) +#endif /* IPA_UC_OFFLOAD */ + +#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0 + +#define HDD_IPA_GET_IFACE_ID(_data) \ + (((struct hdd_ipa_cld_hdr *) (_data))->iface_id) + + +#define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \ + "%s:%d: "fmt, __func__, __LINE__, ## args) + +#define HDD_IPA_DBG_DUMP(_lvl, _prefix, _buf, _len) \ + do {\ + VOS_TRACE(VOS_MODULE_ID_HDD, _lvl, "%s:", _prefix); \ + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, _lvl, _buf, _len); \ + } while(0) + +enum hdd_ipa_rm_state { + HDD_IPA_RM_RELEASED, + HDD_IPA_RM_GRANT_PENDING, + HDD_IPA_RM_GRANTED, +}; + +#define HDD_IPA_MAX_IFACE 3 +#define HDD_IPA_MAX_SYSBAM_PIPE 4 +#define HDD_IPA_RX_PIPE HDD_IPA_MAX_IFACE + +static struct hdd_ipa_adapter_2_client { + enum ipa_client_type cons_client; + enum ipa_client_type prod_client; +} hdd_ipa_adapter_2_client[HDD_IPA_MAX_IFACE] = { + {IPA_CLIENT_WLAN1_CONS, IPA_CLIENT_WLAN1_PROD}, + {IPA_CLIENT_WLAN2_CONS, IPA_CLIENT_WLAN1_PROD}, + {IPA_CLIENT_WLAN3_CONS, IPA_CLIENT_WLAN1_PROD}, +}; + +struct hdd_ipa_sys_pipe { + uint32_t conn_hdl; + uint8_t conn_hdl_valid; + struct ipa_sys_connect_params ipa_sys_params; +}; + +struct hdd_ipa_iface_stats { + uint64_t num_tx; + uint64_t num_tx_drop; + uint64_t num_tx_err; + uint64_t num_tx_cac_drop; + uint64_t num_rx_prefilter; + uint64_t num_rx_ipa_excep; + uint64_t num_rx_recv; + uint64_t num_rx_recv_mul; + uint64_t num_rx_send_desc_err; + uint64_t max_rx_mul; +}; + +struct hdd_ipa_priv; + +struct hdd_ipa_iface_context { + struct hdd_ipa_priv *hdd_ipa; + hdd_adapter_t *adapter; + void *tl_context; + + enum ipa_client_type cons_client; + enum ipa_client_type prod_client; + + uint8_t iface_id; /* This iface ID */ + uint8_t sta_id; /* This iface station ID */ + adf_os_spinlock_t interface_lock; + uint32_t ifa_address; + struct hdd_ipa_iface_stats stats; +}; + + +struct hdd_ipa_stats { + uint32_t event[IPA_WLAN_EVENT_MAX]; + uint64_t num_send_msg; + uint64_t num_free_msg; + + uint64_t num_rm_grant; + uint64_t num_rm_release; + uint64_t num_rm_grant_imm; + uint64_t num_cons_perf_req; + uint64_t num_prod_perf_req; + + uint64_t num_rx_drop; + uint64_t num_rx_ipa_tx_dp; + uint64_t num_rx_ipa_splice; + uint64_t num_rx_ipa_loop; + uint64_t num_rx_ipa_tx_dp_err; + uint64_t num_rx_ipa_write_done; + uint64_t num_max_ipa_tx_mul; + uint64_t num_rx_ipa_hw_maxed_out; + uint64_t max_pend_q_cnt; + + uint64_t num_tx_comp_cnt; + uint64_t num_tx_queued; + uint64_t num_tx_dequeued; + uint64_t num_max_pm_queue; + + uint64_t num_freeq_empty; + uint64_t num_pri_freeq_empty; + uint64_t num_rx_excep; +}; + +#ifdef IPA_UC_OFFLOAD +struct ipa_uc_stas_map { + v_BOOL_t is_reserved; + uint8_t sta_id; +}; + +struct op_msg_type { + uint8_t msg_t; + uint8_t rsvd; + uint16_t op_code; + uint16_t len; + uint16_t rsvd_snd; +}; + +struct ipa_uc_fw_stats { + uint32_t tx_comp_ring_base; + uint32_t tx_comp_ring_size; + uint32_t tx_comp_ring_dbell_addr; + uint32_t tx_comp_ring_dbell_ind_val; + uint32_t tx_comp_ring_dbell_cached_val; + uint32_t tx_pkts_enqueued; + uint32_t tx_pkts_completed; + uint32_t tx_is_suspend; + uint32_t tx_reserved; + uint32_t rx_ind_ring_base; + uint32_t rx_ind_ring_size; + uint32_t rx_ind_ring_dbell_addr; + uint32_t rx_ind_ring_dbell_ind_val; + uint32_t rx_ind_ring_dbell_ind_cached_val; + uint32_t rx_ind_ring_rdidx_addr; + uint32_t rx_ind_ring_rd_idx_cached_val; + uint32_t rx_refill_idx; + uint32_t rx_num_pkts_indicated; + uint32_t rx_buf_refilled; + uint32_t rx_num_ind_drop_no_space; + uint32_t rx_num_ind_drop_no_buf; + uint32_t rx_is_suspend; + uint32_t rx_reserved; +}; + +struct ipa_uc_pending_event { + vos_list_node_t node; + hdd_adapter_t *adapter; + enum ipa_wlan_event type; + uint8_t sta_id; + uint8_t mac_addr[VOS_MAC_ADDR_SIZE]; +}; + +static const char *op_string[] = { + "TX_SUSPEND", + "TX_RESUME", + "RX_SUSPEND", + "RX_RESUME", + "STATS", +}; +#endif /* IPA_UC_OFFLOAD */ + +struct hdd_ipa_priv { + struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_SYSBAM_PIPE]; + struct hdd_ipa_iface_context iface_context[HDD_IPA_MAX_IFACE]; + enum hdd_ipa_rm_state rm_state; + /* + * IPA driver can send RM notifications with IRQ disabled so using adf + * APIs as it is taken care gracefully. Without this, kernel would throw + * an warning if spin_lock_bh is used while IRQ is disabled + */ + adf_os_spinlock_t rm_lock; + struct work_struct rm_work; + vos_wake_lock_t wake_lock; + struct delayed_work wake_lock_work; + bool wake_lock_released; + + enum ipa_client_type prod_client; + + atomic_t tx_ref_cnt; + adf_nbuf_queue_t pm_queue_head; + struct work_struct pm_work; + adf_os_spinlock_t pm_lock; + bool suspended; + + uint32_t pending_hw_desc_cnt; + uint32_t hw_desc_cnt; + spinlock_t q_lock; + uint32_t freeq_cnt; + struct list_head free_desc_head; + + uint32_t pend_q_cnt; + struct list_head pend_desc_head; + + hdd_context_t *hdd_ctx; + + struct dentry *debugfs_dir; + struct hdd_ipa_stats stats; + + struct notifier_block ipv4_notifier; + uint32_t curr_prod_bw; + uint32_t curr_cons_bw; + +#ifdef IPA_UC_OFFLOAD + uint8_t activated_fw_pipe; + uint8_t sap_num_connected_sta; + uint32_t tx_pipe_handle; + uint32_t rx_pipe_handle; + v_BOOL_t resource_loading; + v_BOOL_t resource_unloading; + v_BOOL_t pending_cons_req; + struct ipa_uc_stas_map assoc_stas_map[WLAN_MAX_STA_COUNT]; + vos_list_t pending_event; + vos_lock_t event_lock; + uint32_t ipa_tx_packets_diff; + uint32_t ipa_rx_packets_diff; + uint32_t ipa_p_tx_packets; + uint32_t ipa_p_rx_packets; + hdd_ipa_uc_stat_reason stat_req_reason; +#endif /* IPA_UC_OFFLOAD */ +}; + +static struct hdd_ipa_priv *ghdd_ipa; + +#define HDD_IPA_ENABLE_MASK BIT(0) +#define HDD_IPA_PRE_FILTER_ENABLE_MASK BIT(1) +#define HDD_IPA_IPV6_ENABLE_MASK BIT(2) +#define HDD_IPA_RM_ENABLE_MASK BIT(3) +#define HDD_IPA_CLK_SCALING_ENABLE_MASK BIT(4) + +#define HDD_IPA_IS_CONFIG_ENABLED(_hdd_ctx, _mask)\ + (((_hdd_ctx)->cfg_ini->IpaConfig & (_mask)) == (_mask)) + +/* Local Function Prototypes */ +static void hdd_ipa_send_pkt_to_ipa(struct hdd_ipa_priv *hdd_ipa); +static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data); +static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data); +static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type); + +#ifdef IPA_UC_OFFLOAD +static void hdd_ipa_uc_rm_notify_handler(void *context, + void *rxpkt, + u_int16_t staid); +#endif /* IPA_UC_OFFLOAD */ + +#ifdef IPA_UC_OFFLOAD +extern int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev); +#endif /* IPA_UC_OFFLOAD */ + +bool hdd_ipa_is_enabled(hdd_context_t *hdd_ctx) +{ + return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_ENABLE_MASK); +} + +v_U8_t hdd_ipa_uc_is_enabled(struct hdd_ipa_priv *hdd_ipa) +{ +#ifdef IPA_UC_OFFLOAD + return hdd_ipa->hdd_ctx->cfg_ini->IpaUcOffloadEnabled; +#else + return 0; +#endif /* IPA_UC_OFFLOAD */ +} + +static inline bool hdd_ipa_is_pre_filter_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_PRE_FILTER_ENABLE_MASK); +} + +static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_IPV6_ENABLE_MASK); +} + +static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_RM_ENABLE_MASK); +} + +static inline bool hdd_ipa_is_clk_scaling_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, + HDD_IPA_CLK_SCALING_ENABLE_MASK | + HDD_IPA_RM_ENABLE_MASK); +} + +static struct ipa_tx_data_desc *hdd_ipa_alloc_data_desc( + struct hdd_ipa_priv *hdd_ipa, int priority) +{ + struct ipa_tx_data_desc *desc = NULL; + + spin_lock_bh(&hdd_ipa->q_lock); + + /* Keep the descriptors for priority alloc which can be used for + * anchor nodes + */ + if (hdd_ipa->freeq_cnt < (HDD_IPA_DESC_BUFFER_RATIO * 2) && !priority) { + hdd_ipa->stats.num_freeq_empty++; + goto end; + } + + if (!list_empty(&hdd_ipa->free_desc_head)) { + desc = list_first_entry(&hdd_ipa->free_desc_head, + struct ipa_tx_data_desc, link); + list_del(&desc->link); + hdd_ipa->freeq_cnt--; + } else { + hdd_ipa->stats.num_pri_freeq_empty++; + } + +end: + spin_unlock_bh(&hdd_ipa->q_lock); + + return desc; +} + +static void hdd_ipa_free_data_desc(struct hdd_ipa_priv *hdd_ipa, + struct ipa_tx_data_desc *desc) +{ + desc->priv = NULL; + desc->pyld_buffer = NULL; + desc->pyld_len = 0; + spin_lock_bh(&hdd_ipa->q_lock); + list_add_tail(&desc->link, &hdd_ipa->free_desc_head); + hdd_ipa->freeq_cnt++; + spin_unlock_bh(&hdd_ipa->q_lock); +} + +static struct iphdr * hdd_ipa_get_ip_pkt(void *data, uint16_t *eth_type) +{ + struct ethhdr *eth = (struct ethhdr *)data; + struct llc_snap_hdr *ls_hdr; + struct iphdr *ip_hdr; + + ip_hdr = NULL; + *eth_type = be16_to_cpu(eth->h_proto); + if (*eth_type < 0x600) { + /* Non Ethernet II framing format */ + ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data + + sizeof(struct ethhdr)); + + if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) || + ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB))) + *eth_type = be16_to_cpu(ls_hdr->eth_type); + ip_hdr = (struct iphdr *)((uint8_t *)data + + sizeof(struct ethhdr) + sizeof(struct llc_snap_hdr)); + } else if (*eth_type == ETH_P_IP) { + ip_hdr = (struct iphdr *)((uint8_t *)data + + sizeof(struct ethhdr)); + } + + return ip_hdr; +} + +static bool hdd_ipa_can_send_to_ipa(hdd_adapter_t *adapter, struct hdd_ipa_priv *hdd_ipa, void *data) +{ + uint16_t eth_type; + struct iphdr *ip_hdr = NULL; + + if (!hdd_ipa_is_pre_filter_enabled(hdd_ipa)) + return true; + ip_hdr = hdd_ipa_get_ip_pkt(data, ð_type); + + if (eth_type == ETH_P_IP) { + //Check if the dest IP address is itself, and in that case, bypass IPA + if (ip_hdr->daddr != ((struct hdd_ipa_iface_context *)(adapter->ipa_context))->ifa_address) + return true; + else + return false; + } + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa) && eth_type == ETH_P_IPV6) + return true; + + return false; +} + +#ifdef IPA_UC_OFFLOAD +void hdd_ipa_uc_stat_query(hdd_context_t *pHddCtx, + uint32_t *ipa_tx_diff, uint32_t *ipa_rx_diff) +{ + struct hdd_ipa_priv *hdd_ipa; + + hdd_ipa = (struct hdd_ipa_priv *)pHddCtx->hdd_ipa; + *ipa_tx_diff = 0; + *ipa_rx_diff = 0; + + if (!hdd_ipa_is_enabled(pHddCtx) || + !(hdd_ipa_uc_is_enabled(hdd_ipa))) { + return; + } + + vos_lock_acquire(&hdd_ipa->event_lock); + if ((HDD_IPA_UC_NUM_WDI_PIPE == hdd_ipa->activated_fw_pipe) && + (VOS_FALSE == hdd_ipa->resource_loading)) { + *ipa_tx_diff = hdd_ipa->ipa_tx_packets_diff; + *ipa_rx_diff = hdd_ipa->ipa_rx_packets_diff; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: STAT Query TX DIFF %d, RX DIFF %d", + __func__, *ipa_tx_diff, *ipa_rx_diff); + } + vos_lock_release(&hdd_ipa->event_lock); + return; +} + +void hdd_ipa_uc_stat_request( hdd_adapter_t *adapter, uint8_t reason) +{ + hdd_context_t *pHddCtx; + struct hdd_ipa_priv *hdd_ipa; + + if (!adapter) { + return; + } + + pHddCtx = (hdd_context_t *)adapter->pHddCtx; + hdd_ipa = (struct hdd_ipa_priv *)pHddCtx->hdd_ipa; + if (!hdd_ipa_is_enabled(pHddCtx) || + !(hdd_ipa_uc_is_enabled(hdd_ipa))) { + return; + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: STAT REQ Reason %d", + __func__, reason); + vos_lock_acquire(&hdd_ipa->event_lock); + if ((HDD_IPA_UC_NUM_WDI_PIPE == hdd_ipa->activated_fw_pipe) && + (VOS_FALSE == hdd_ipa->resource_loading)) { + hdd_ipa->stat_req_reason = (hdd_ipa_uc_stat_reason)reason; + process_wma_set_command( + (int)adapter->sessionId, + (int)WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID, + 0, VDEV_CMD); + } + vos_lock_release(&hdd_ipa->event_lock); +} + +static v_BOOL_t hdd_ipa_uc_find_add_assoc_sta( + struct hdd_ipa_priv *hdd_ipa, + v_BOOL_t sta_add, + uint8_t sta_id) +{ + /* Found associated sta */ + v_BOOL_t sta_found = VOS_FALSE; + uint8_t idx; + + for (idx = 0; idx < WLAN_MAX_STA_COUNT; idx++) { + if ((hdd_ipa->assoc_stas_map[idx].is_reserved) && + (hdd_ipa->assoc_stas_map[idx].sta_id == sta_id)) { + sta_found = VOS_TRUE; + break; + } + } + + /* Try to add sta which is already in + * If the sta is already in, just return sta_found */ + if (sta_add && sta_found) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: STA ID %d already exist, cannot add", + __func__, sta_id); + return sta_found; + } + + if (sta_add) { + /* Find first empty slot */ + for (idx = 0; idx < WLAN_MAX_STA_COUNT; idx++) { + if (!hdd_ipa->assoc_stas_map[idx].is_reserved) { + hdd_ipa->assoc_stas_map[idx].is_reserved = + VOS_TRUE; + hdd_ipa->assoc_stas_map[idx].sta_id = sta_id; + return sta_found; + } + } + } + + /* Delete STA from map, but could not find STA within the map + * Error case, add error log */ + if (!sta_add && !sta_found) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: STA ID %d does not exist, cannot delete", + __func__, sta_id); + return sta_found; + } + + if (!sta_add) { + for (idx = 0; idx < WLAN_MAX_STA_COUNT; idx++) { + if ((hdd_ipa->assoc_stas_map[idx].is_reserved) && + (hdd_ipa->assoc_stas_map[idx].sta_id == sta_id)) { + hdd_ipa->assoc_stas_map[idx].is_reserved = + VOS_FALSE; + hdd_ipa->assoc_stas_map[idx].sta_id = 0xFF; + return sta_found; + } + } + } + + return sta_found; +} + +static int hdd_ipa_uc_enable_pipes(struct hdd_ipa_priv *hdd_ipa) +{ + int result; + + /* ACTIVATE TX PIPE */ + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Enable TX PIPE", __func__); + result = ipa_enable_wdi_pipe(hdd_ipa->tx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Enable TX PIPE fail, code %d", + __func__, result); + return result; + } + result = ipa_resume_wdi_pipe(hdd_ipa->tx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Resume TX PIPE fail, code %d", + __func__, result); + return result; + } + WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext, + VOS_TRUE, VOS_TRUE); + + /* ACTIVATE RX PIPE */ + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Enable RX PIPE", __func__); + result = ipa_enable_wdi_pipe(hdd_ipa->rx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Enable RX PIPE fail, code %d", + __func__, result); + return result; + } + result = ipa_resume_wdi_pipe(hdd_ipa->rx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Resume RX PIPE fail, code %d", + __func__, result); + return result; + } + WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext, + VOS_TRUE, VOS_FALSE); + + return 0; +} + +static int hdd_ipa_uc_disable_pipes(struct hdd_ipa_priv *hdd_ipa) +{ + int result; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disable RX PIPE", __func__); + result = ipa_suspend_wdi_pipe(hdd_ipa->rx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Suspend RX PIPE fail, code %d", + __func__, result); + return result; + } + result = ipa_disable_wdi_pipe(hdd_ipa->rx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Disable RX PIPE fail, code %d", + __func__, result); + return result; + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disable TX PIPE", __func__); + result = ipa_suspend_wdi_pipe(hdd_ipa->tx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Suspend TX PIPE fail, code %d", + __func__, result); + return result; + } + result = ipa_disable_wdi_pipe(hdd_ipa->tx_pipe_handle); + if (result) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: Disable TX PIPE fail, code %d", + __func__, result); + return result; + } + + return 0; +} + +static int hdd_ipa_uc_handle_first_con(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_ipa->activated_fw_pipe = 0; + hdd_ipa->resource_loading = VOS_TRUE; + /* If RM feature enabled + * Request PROD Resource first + * PROD resource may return sync or async manners */ + if ((hdd_ipa_is_rm_enabled(hdd_ipa)) && + (!ipa_rm_request_resource(IPA_RM_RESOURCE_WLAN_PROD))) { + /* RM PROD request sync return + * enable pipe immediately */ + if (hdd_ipa_uc_enable_pipes(hdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPA WDI Pipes activate fail", __func__); + hdd_ipa->resource_loading = VOS_FALSE; + return -EBUSY; + } + } else { + /* RM Disabled + * Just enabled all the PIPEs */ + if (hdd_ipa_uc_enable_pipes(hdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPA WDI Pipes activate fail", __func__); + hdd_ipa->resource_loading = VOS_FALSE; + return -EBUSY; + } + } + return 0; +} + +static int hdd_ipa_uc_handle_last_discon(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_ipa->resource_unloading = VOS_TRUE; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disable FW RX PIPE", __func__); + WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext, + VOS_FALSE, VOS_FALSE); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disable FW TX PIPE", __func__); + WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext, + VOS_FALSE, VOS_TRUE); + return 0; +} + +void hdd_ipa_uc_rm_notify_handler(void *context, + void *rxpkt, + u_int16_t staid) +{ + enum ipa_rm_event event_code; + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return; + + vos_mem_copy(&event_code, rxpkt, sizeof(event_code)); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s, event code %d", + __func__, event_code); + + switch(event_code) { + case IPA_RM_RESOURCE_GRANTED: + /* Differed RM Granted */ + hdd_ipa_uc_enable_pipes(hdd_ipa); + if (hdd_ipa->pending_cons_req) { + ipa_rm_notify_completion(IPA_RM_RESOURCE_GRANTED, + IPA_RM_RESOURCE_WLAN_CONS); + } + hdd_ipa->pending_cons_req = VOS_FALSE; + break; + + case IPA_RM_RESOURCE_RELEASED: + /* Differed RM Released */ + hdd_ipa->resource_unloading = VOS_FALSE; + if (hdd_ipa->pending_cons_req) { + ipa_rm_notify_completion(IPA_RM_RESOURCE_RELEASED, + IPA_RM_RESOURCE_WLAN_CONS); + } + hdd_ipa->pending_cons_req = VOS_FALSE; + break; + + default: + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s, invalid event code %d", + __func__, event_code); + break; + } +} + +void hdd_ipa_uc_rm_notify_defer(void *hdd_ipa, enum ipa_rm_event event) +{ + pVosSchedContext sched_ctx = get_vos_sched_ctxt(); + struct VosTlshimPkt *pkt; + v_U8_t *event_code_pkt; + + if (unlikely(!sched_ctx)) + return; + + pkt = vos_alloc_tlshim_pkt(sched_ctx); + if (!pkt) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s, alloc fail", __func__); + return; + } + + event_code_pkt = vos_mem_malloc(sizeof(unsigned int)); + vos_mem_copy(event_code_pkt, &event, 1); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "%s, posted event %d", __func__, event); + pkt->callback = (vos_tlshim_cb)hdd_ipa_uc_rm_notify_handler; + pkt->context = hdd_ipa; + pkt->Rxpkt = (void *) event_code_pkt; + pkt->staId = 0; + vos_indicate_rxpkt(sched_ctx, pkt); +} + +static int hdd_ipa_uc_proc_pending_event(struct hdd_ipa_priv *hdd_ipa) +{ + v_SIZE_t pending_event_count; + struct ipa_uc_pending_event *pending_event = NULL; + + vos_list_size(&hdd_ipa->pending_event, &pending_event_count); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s, Pending Event Count %d", __func__, pending_event_count); + if (!pending_event_count) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s, No Pending Event", __func__); + return 0; + } + + vos_list_remove_front(&hdd_ipa->pending_event, + (vos_list_node_t **)&pending_event); + while (pending_event != NULL) { + hdd_ipa_wlan_evt(pending_event->adapter, + pending_event->type, + pending_event->sta_id, + pending_event->mac_addr); + vos_mem_free(pending_event); + pending_event = NULL; + vos_list_remove_front(&hdd_ipa->pending_event, + (vos_list_node_t **)&pending_event); + } + return 0; +} + +static void hdd_ipa_uc_op_cb(v_U8_t *op_msg, void *usr_ctxt) +{ + struct op_msg_type *msg; + struct ipa_uc_fw_stats *uc_fw_stat; + struct IpaHwStatsWDIInfoData_t ipa_stat; + struct hdd_ipa_priv *hdd_ipa; + hdd_context_t *hdd_ctx; + + if (!op_msg || !usr_ctxt) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s, INVALID ARG", __func__); + return; + } + + msg = (struct op_msg_type *)op_msg; + if (HDD_IPA_UC_OPCODE_MAX <= msg->op_code) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s, INVALID OPCODE %d", __func__, msg->op_code); + return; + } + + hdd_ctx = (hdd_context_t *)usr_ctxt; + hdd_ipa = (struct hdd_ipa_priv *)hdd_ctx->hdd_ipa; + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, + "%s, OPCODE %s", __func__, op_string[msg->op_code]); + + if ((HDD_IPA_UC_OPCODE_TX_RESUME == msg->op_code) || + (HDD_IPA_UC_OPCODE_RX_RESUME == msg->op_code)) { + vos_lock_acquire(&hdd_ipa->event_lock); + hdd_ipa->activated_fw_pipe++; + if (HDD_IPA_UC_NUM_WDI_PIPE == hdd_ipa->activated_fw_pipe) { + hdd_ipa->resource_loading = VOS_FALSE; + hdd_ipa_uc_proc_pending_event(hdd_ipa); + } + vos_lock_release(&hdd_ipa->event_lock); + } + + if ((HDD_IPA_UC_OPCODE_TX_SUSPEND == msg->op_code) || + (HDD_IPA_UC_OPCODE_RX_SUSPEND == msg->op_code)) { + vos_lock_acquire(&hdd_ipa->event_lock); + hdd_ipa->activated_fw_pipe--; + if (!hdd_ipa->activated_fw_pipe) { + hdd_ipa_uc_disable_pipes(hdd_ipa); + if ((hdd_ipa_is_rm_enabled(hdd_ipa)) && + (!ipa_rm_release_resource(IPA_RM_RESOURCE_WLAN_PROD))) { + /* Sync return success from IPA + * Enable/resume all the PIPEs */ + hdd_ipa->resource_unloading = VOS_FALSE; + hdd_ipa_uc_proc_pending_event(hdd_ipa); + } else { + hdd_ipa->resource_unloading = VOS_FALSE; + hdd_ipa_uc_proc_pending_event(hdd_ipa); + } + } + vos_lock_release(&hdd_ipa->event_lock); + } + + if ((HDD_IPA_UC_OPCODE_STATS == msg->op_code) && + (HDD_IPA_UC_STAT_REASON_DEBUG == hdd_ipa->stat_req_reason)) { + /* STATs from host */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_HOST CE ====\n" + "CE RING BASE: 0x%x\n" + "CE RING SIZE: %d\n" + "CE REG ADDR : 0x%x", + hdd_ctx->ce_sr_base_paddr, + hdd_ctx->ce_sr_ring_size, + hdd_ctx->ce_reg_paddr); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_HOST TX ====\n" + "COMP RING BASE: 0x%x\n" + "COMP RING SIZE: %d\n" + "NUM ALLOC BUF: %d\n" + "COMP RING DBELL : 0x%x", + hdd_ctx->tx_comp_ring_base_paddr, + hdd_ctx->tx_comp_ring_size, + hdd_ctx->tx_num_alloc_buffer, + hdd_ctx->tx_comp_doorbell_paddr); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_HOST RX ====\n" + "IND RING BASE: 0x%x\n" + "IND RING SIZE: %d\n" + "IND RING DBELL : 0x%x\n" + "PROC DONE IND ADDR : 0x%x\n" + "NUM EXCP PKT : %llu", + hdd_ctx->rx_rdy_ring_base_paddr, + hdd_ctx->rx_rdy_ring_size, + hdd_ctx->rx_ready_doorbell_paddr, + hdd_ctx->rx_proc_done_idx_paddr, + hdd_ipa->stats.num_rx_excep); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_HOST CONTROL ====\n" + "NUM STAs: %d\n" + "TX PIPE HDL: %d\n" + "RX PIPE HDL : %d\n" + "RSC LOADING : %d\n" + "RSC UNLOADING : %d\n" + "PNDNG CNS RQT : %d", + hdd_ipa->sap_num_connected_sta, + hdd_ipa->tx_pipe_handle, + hdd_ipa->rx_pipe_handle, + (unsigned int)hdd_ipa->resource_loading, + (unsigned int)hdd_ipa->resource_unloading, + (unsigned int)hdd_ipa->pending_cons_req); + + /* STATs from FW */ + uc_fw_stat = (struct ipa_uc_fw_stats *) + (op_msg + sizeof(struct op_msg_type)); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_FW TX ====\n" + "COMP RING BASE: 0x%x\n" + "COMP RING SIZE: %d\n" + "COMP RING DBELL : 0x%x\n" + "COMP RING DBELL IND VAL : %d\n" + "COMP RING DBELL CACHED VAL : %d\n" + "COMP RING DBELL CACHED VAL : %d\n" + "PKTS ENQ : %d\n" + "PKTS COMP : %d\n" + "IS SUSPEND : %d\n" + "RSVD : 0x%x", + uc_fw_stat->tx_comp_ring_base, + uc_fw_stat->tx_comp_ring_size, + uc_fw_stat->tx_comp_ring_dbell_addr, + uc_fw_stat->tx_comp_ring_dbell_ind_val, + uc_fw_stat->tx_comp_ring_dbell_cached_val, + uc_fw_stat->tx_comp_ring_dbell_cached_val, + uc_fw_stat->tx_pkts_enqueued, + uc_fw_stat->tx_pkts_completed, + uc_fw_stat->tx_is_suspend, + uc_fw_stat->tx_reserved); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC WLAN_FW RX ====\n" + "IND RING BASE: 0x%x\n" + "IND RING SIZE: %d\n" + "IND RING DBELL : 0x%x\n" + "IND RING DBELL IND VAL : %d\n" + "IND RING DBELL CACHED VAL : %d\n" + "RDY IND ADDR : 0x%x\n" + "RDY IND CACHE VAL : %d\n" + "RFIL IND : %d\n" + "NUM PKT INDICAT : %d\n" + "BUF REFIL : %d\n" + "NUM DROP NO SPC : %d\n" + "NUM DROP NO BUF : %d\n" + "IS SUSPND : %d\n" + "RSVD : 0x%x\n", + uc_fw_stat->rx_ind_ring_base, + uc_fw_stat->rx_ind_ring_size, + uc_fw_stat->rx_ind_ring_dbell_addr, + uc_fw_stat->rx_ind_ring_dbell_ind_val, + uc_fw_stat->rx_ind_ring_dbell_ind_cached_val, + uc_fw_stat->rx_ind_ring_rdidx_addr, + uc_fw_stat->rx_ind_ring_rd_idx_cached_val, + uc_fw_stat->rx_refill_idx, + uc_fw_stat->rx_num_pkts_indicated, + uc_fw_stat->rx_buf_refilled, + uc_fw_stat->rx_num_ind_drop_no_space, + uc_fw_stat->rx_num_ind_drop_no_buf, + uc_fw_stat->rx_is_suspend, + uc_fw_stat->rx_reserved); + /* STATs from IPA */ + ipa_get_wdi_stats(&ipa_stat); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC IPA TX ====\n" + "NUM PROCD : %d\n" + "CE DBELL : 0x%x\n" + "NUM DBELL FIRED : %d\n" + "COMP RNG FULL : %d\n" + "COMP RNG EMPT : %d\n" + "COMP RNG USE HGH : %d\n" + "COMP RNG USE LOW : %d\n" + "BAM FIFO FULL : %d\n" + "BAM FIFO EMPT : %d\n" + "BAM FIFO USE HGH : %d\n" + "BAM FIFO USE LOW : %d\n" + "NUM DBELL : %d\n" + "NUM UNEXP DBELL : %d\n" + "NUM BAM INT HDL : 0x%x\n" + "NUM BAM INT NON-RUN : 0x%x\n" + "NUM QMB INT HDL : 0x%x", + ipa_stat.tx_ch_stats.num_pkts_processed, + ipa_stat.tx_ch_stats.copy_engine_doorbell_value, + ipa_stat.tx_ch_stats.num_db_fired, + ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringFull, + ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringEmpty, + ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringUsageHigh, + ipa_stat.tx_ch_stats.tx_comp_ring_stats.ringUsageLow, + ipa_stat.tx_ch_stats.bam_stats.bamFifoFull, + ipa_stat.tx_ch_stats.bam_stats.bamFifoEmpty, + ipa_stat.tx_ch_stats.bam_stats.bamFifoUsageHigh, + ipa_stat.tx_ch_stats.bam_stats.bamFifoUsageLow, + ipa_stat.tx_ch_stats.num_db, + ipa_stat.tx_ch_stats.num_unexpected_db, + ipa_stat.tx_ch_stats.num_bam_int_handled, + ipa_stat.tx_ch_stats.num_bam_int_in_non_runnning_state, + ipa_stat.tx_ch_stats.num_qmb_int_handled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "==== IPA_UC IPA RX ====\n" + "MAX OST PKT : %d\n" + "NUM PKT PRCSD : %d\n" + "RNG RP : 0x%x\n" + "COMP RNG FULL : %d\n" + "COMP RNG EMPT : %d\n" + "COMP RNG USE HGH : %d\n" + "COMP RNG USE LOW : %d\n" + "BAM FIFO FULL : %d\n" + "BAM FIFO EMPT : %d\n" + "BAM FIFO USE HGH : %d\n" + "BAM FIFO USE LOW : %d\n" + "NUM DB : %d\n" + "NUM UNEXP DB : %d\n" + "NUM BAM INT HNDL : 0x%x\n", + ipa_stat.rx_ch_stats.max_outstanding_pkts, + ipa_stat.rx_ch_stats.num_pkts_processed, + ipa_stat.rx_ch_stats.rx_ring_rp_value, + ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringFull, + ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringEmpty, + ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringUsageHigh, + ipa_stat.rx_ch_stats.rx_ind_ring_stats.ringUsageLow, + ipa_stat.rx_ch_stats.bam_stats.bamFifoFull, + ipa_stat.rx_ch_stats.bam_stats.bamFifoEmpty, + ipa_stat.rx_ch_stats.bam_stats.bamFifoUsageHigh, + ipa_stat.rx_ch_stats.bam_stats.bamFifoUsageLow, + ipa_stat.rx_ch_stats.num_db, + ipa_stat.rx_ch_stats.num_unexpected_db, + ipa_stat.rx_ch_stats.num_bam_int_handled); + } else if ((HDD_IPA_UC_OPCODE_STATS == msg->op_code) && + (HDD_IPA_UC_STAT_REASON_BW_CAL == hdd_ipa->stat_req_reason)) { + /* STATs from FW */ + uc_fw_stat = (struct ipa_uc_fw_stats *) + (op_msg + sizeof(struct op_msg_type)); + vos_lock_acquire(&hdd_ipa->event_lock); + hdd_ipa->ipa_tx_packets_diff = uc_fw_stat->tx_pkts_completed - + hdd_ipa->ipa_p_tx_packets; + hdd_ipa->ipa_rx_packets_diff = + (uc_fw_stat->rx_num_ind_drop_no_space + + uc_fw_stat->rx_num_ind_drop_no_buf + + uc_fw_stat->rx_num_pkts_indicated) - + hdd_ipa->ipa_p_rx_packets; + + hdd_ipa->ipa_p_tx_packets = uc_fw_stat->tx_pkts_completed; + hdd_ipa->ipa_p_rx_packets = + (uc_fw_stat->rx_num_ind_drop_no_space + + uc_fw_stat->rx_num_ind_drop_no_buf + + uc_fw_stat->rx_num_pkts_indicated); + vos_lock_release(&hdd_ipa->event_lock); + } + adf_os_mem_free(op_msg); +} + +static hdd_adapter_t *hdd_ipa_uc_get_adapter(struct hdd_ipa_priv *hdd_ipa, + uint8_t iface_id) +{ + uint8_t i; + + /* This revisit needed for performance */ + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + if ((hdd_ipa->iface_context[i].adapter != NULL) && + (hdd_ipa->iface_context[i].adapter->sessionId == iface_id)) { + return hdd_ipa->iface_context[i].adapter; + } + } + return NULL; +} + +static VOS_STATUS hdd_ipa_uc_ol_init(hdd_context_t *hdd_ctx) +{ + struct ipa_wdi_in_params pipe_in; + struct ipa_wdi_out_params pipe_out; + struct hdd_ipa_priv *ipa_ctxt = (struct hdd_ipa_priv *)hdd_ctx->hdd_ipa; + + vos_mem_zero(&pipe_in, sizeof(struct ipa_wdi_in_params)); + vos_mem_zero(&pipe_out, sizeof(struct ipa_wdi_out_params)); + + vos_list_init(&ipa_ctxt->pending_event); + vos_lock_init(&ipa_ctxt->event_lock); + + /* TX PIPE */ + pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = HDD_IPA_UC_WLAN_TX_HDR_LEN; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_additional_const_len = + HDD_IPA_UC_WLAN_8023_HDR_SIZE; + pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC; + pipe_in.sys.client = IPA_CLIENT_WLAN1_CONS; + pipe_in.sys.desc_fifo_sz = hdd_ctx->cfg_ini->IpaDescSize; + pipe_in.sys.priv = hdd_ctx->hdd_ipa; + pipe_in.sys.ipa_ep_cfg.hdr_ext.hdr_little_endian = true; + pipe_in.sys.notify = hdd_ipa_i2w_cb; + if (!hdd_ipa_is_rm_enabled(ghdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: IPA RM DISABLED, IPA AWAKE", __func__); + pipe_in.sys.keep_ipa_awake = TRUE; + } + + pipe_in.u.dl.comp_ring_base_pa = hdd_ctx->tx_comp_ring_base_paddr; + pipe_in.u.dl.comp_ring_size = hdd_ctx->tx_comp_ring_size * 4; + pipe_in.u.dl.ce_ring_base_pa = hdd_ctx->ce_sr_base_paddr; + pipe_in.u.dl.ce_door_bell_pa = hdd_ctx->ce_reg_paddr; + pipe_in.u.dl.ce_ring_size = hdd_ctx->ce_sr_ring_size * 8; + pipe_in.u.dl.num_tx_buffers = hdd_ctx->tx_num_alloc_buffer; + + /* Connect WDI IPA PIPE */ + ipa_connect_wdi_pipe(&pipe_in, &pipe_out); + /* Micro Controller Doorbell register */ + hdd_ctx->tx_comp_doorbell_paddr = (v_U32_t)pipe_out.uc_door_bell_pa; + /* WLAN TX PIPE Handle */ + ipa_ctxt->tx_pipe_handle = pipe_out.clnt_hdl; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "TX : CRBPA 0x%x, CRS %d, CERBPA 0x%x, CEDPA 0x%x," + " CERZ %d, NB %d, CDBPAD 0x%x", + (unsigned int)pipe_in.u.dl.comp_ring_base_pa, + pipe_in.u.dl.comp_ring_size, + (unsigned int)pipe_in.u.dl.ce_ring_base_pa, + (unsigned int)pipe_in.u.dl.ce_door_bell_pa, + pipe_in.u.dl.ce_ring_size, + pipe_in.u.dl.num_tx_buffers, + (unsigned int)hdd_ctx->tx_comp_doorbell_paddr); + + /* RX PIPE */ + pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = HDD_IPA_UC_WLAN_RX_HDR_LEN; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 0; + pipe_in.sys.ipa_ep_cfg.hdr.hdr_metadata_reg_valid = 1; + pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC; + pipe_in.sys.client = IPA_CLIENT_WLAN1_PROD; + pipe_in.sys.desc_fifo_sz = hdd_ctx->cfg_ini->IpaDescSize + + sizeof(struct sps_iovec); + pipe_in.sys.notify = hdd_ipa_w2i_cb; + if (!hdd_ipa_is_rm_enabled(ghdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPA RM DISABLED, IPA AWAKE", __func__); + pipe_in.sys.keep_ipa_awake = TRUE; + } + + pipe_in.u.ul.rdy_ring_base_pa = hdd_ctx->rx_rdy_ring_base_paddr; + pipe_in.u.ul.rdy_ring_size = hdd_ctx->rx_rdy_ring_size; + pipe_in.u.ul.rdy_ring_rp_pa = hdd_ctx->rx_proc_done_idx_paddr; + + + ipa_connect_wdi_pipe(&pipe_in, &pipe_out); + hdd_ctx->rx_ready_doorbell_paddr = pipe_out.uc_door_bell_pa; + ipa_ctxt->rx_pipe_handle = pipe_out.clnt_hdl; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH, + "RX : RRBPA 0x%x, RRS %d, PDIPA 0x%x, RDY_DB_PAD 0x%x", + (unsigned int)pipe_in.u.ul.rdy_ring_base_pa, + pipe_in.u.ul.rdy_ring_size, + (unsigned int)pipe_in.u.ul.rdy_ring_rp_pa, + (unsigned int)hdd_ctx->rx_ready_doorbell_paddr); + + WLANTL_SetUcDoorbellPaddr((pVosContextType)(hdd_ctx->pvosContext), + (v_U32_t)hdd_ctx->tx_comp_doorbell_paddr, + (v_U32_t)hdd_ctx->rx_ready_doorbell_paddr); + + WLANTL_RegisterOPCbFnc((pVosContextType)(hdd_ctx->pvosContext), + hdd_ipa_uc_op_cb, (void *)hdd_ctx); + + return VOS_STATUS_SUCCESS; +} +#endif /* IPA_UC_OFFLOAD */ + +static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa) +{ + int ret = 0; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return 0; + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + + switch(hdd_ipa->rm_state) { + case HDD_IPA_RM_GRANTED: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return 0; + case HDD_IPA_RM_GRANT_PENDING: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return -EINPROGRESS; + case HDD_IPA_RM_RELEASED: + hdd_ipa->rm_state = HDD_IPA_RM_GRANT_PENDING; + break; + } + + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + ret = ipa_rm_inactivity_timer_request_resource( + IPA_RM_RESOURCE_WLAN_PROD); + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + if (ret == 0) { + hdd_ipa->rm_state = HDD_IPA_RM_GRANTED; + hdd_ipa->stats.num_rm_grant_imm++; + } + + cancel_delayed_work(&hdd_ipa->wake_lock_work); + if (hdd_ipa->wake_lock_released) { + vos_wake_lock_acquire(&hdd_ipa->wake_lock); + hdd_ipa->wake_lock_released = false; + } + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + return ret; +} + +static void hdd_ipa_wake_lock_timer_func(struct work_struct *work) +{ + struct hdd_ipa_priv *hdd_ipa = container_of(to_delayed_work(work), + struct hdd_ipa_priv, wake_lock_work); + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + + if (hdd_ipa->rm_state != HDD_IPA_RM_RELEASED) + goto end; + + hdd_ipa->wake_lock_released = true; + vos_wake_lock_release(&hdd_ipa->wake_lock); + +end: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); +} + +static int hdd_ipa_rm_try_release(struct hdd_ipa_priv *hdd_ipa) +{ + int ret = 0; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return 0; + + if (atomic_read(&hdd_ipa->tx_ref_cnt)) + return -EAGAIN; + + spin_lock_bh(&hdd_ipa->q_lock); + if (hdd_ipa->pending_hw_desc_cnt || hdd_ipa->pend_q_cnt) { + spin_unlock_bh(&hdd_ipa->q_lock); + return -EAGAIN; + } + spin_unlock_bh(&hdd_ipa->q_lock); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + if (!adf_nbuf_is_queue_empty(&hdd_ipa->pm_queue_head)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + return -EAGAIN; + } + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + switch(hdd_ipa->rm_state) { + case HDD_IPA_RM_GRANTED: + break; + case HDD_IPA_RM_GRANT_PENDING: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return -EINPROGRESS; + case HDD_IPA_RM_RELEASED: + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return 0; + } + + /* IPA driver returns immediately so set the state here to avoid any + * race condition. + */ + hdd_ipa->rm_state = HDD_IPA_RM_RELEASED; + hdd_ipa->stats.num_rm_release++; + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + ret = ipa_rm_inactivity_timer_release_resource( + IPA_RM_RESOURCE_WLAN_PROD); + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + if (unlikely(ret != 0)) { + hdd_ipa->rm_state = HDD_IPA_RM_GRANTED; + WARN_ON(1); + } + + /* + * If wake_lock is released immediately, kernel would try to suspend + * immediately as well, Just avoid ping-pong between suspend-resume + * while there is healthy amount of data transfer going on by + * releasing the wake_lock after some delay. + */ + schedule_delayed_work(&hdd_ipa->wake_lock_work, + msecs_to_jiffies(HDD_IPA_RX_INACTIVITY_MSEC_DELAY)); + + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + return ret; +} + +static void hdd_ipa_rm_send_pkt_to_ipa(struct work_struct *work) +{ + struct hdd_ipa_priv *hdd_ipa = container_of(work, + struct hdd_ipa_priv, rm_work); + + return hdd_ipa_send_pkt_to_ipa(hdd_ipa); +} + +static void hdd_ipa_rm_notify(void *user_data, enum ipa_rm_event event, + unsigned long data) +{ + struct hdd_ipa_priv *hdd_ipa = user_data; + + if (unlikely(!hdd_ipa)) + return; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Evt: %d", event); + + switch(event) { + case IPA_RM_RESOURCE_GRANTED: +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + /* RM Notification comes with ISR context + * it should be serialized into differed thread to avoid + * ISR sleep problem */ + if (hdd_ipa->resource_loading) { + hdd_ipa_uc_rm_notify_defer(hdd_ipa, event); + } else { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "UCResource Grntd with invalid status"); + } + break; + } +#endif /* IPA_UC_OFFLOAD */ + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + hdd_ipa->rm_state = HDD_IPA_RM_GRANTED; + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + hdd_ipa->stats.num_rm_grant++; + + schedule_work(&hdd_ipa->rm_work); + break; + case IPA_RM_RESOURCE_RELEASED: + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "RM Release"); +#ifdef IPA_UC_OFFLOAD + hdd_ipa->resource_unloading = VOS_FALSE; +#endif /* IPA_UC_OFFLOAD */ + break; + default: + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Unknown RM Evt: %d", event); + break; + } +} + +static int hdd_ipa_rm_cons_release(void) +{ +#ifdef IPA_UC_OFFLOAD + /* Do Nothing */ +#endif /* IPA_UC_OFFLOAD */ + return 0; +} + +static int hdd_ipa_rm_cons_request(void) +{ +#ifdef IPA_UC_OFFLOAD + if ((ghdd_ipa->resource_loading) || (ghdd_ipa->resource_unloading)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, + "%s: ipa resource loading/unloading in progress", + __func__); + ghdd_ipa->pending_cons_req = VOS_TRUE; + return -EINPROGRESS; + } +#endif /* IPA_UC_OFFLOAD */ + return 0; +} + +int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets, + uint64_t rx_packets) +{ + uint32_t next_cons_bw, next_prod_bw; + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + struct ipa_rm_perf_profile profile; + int ret; + + if ((!hdd_ipa_is_enabled(hdd_ctx)) || + (!hdd_ipa_is_clk_scaling_enabled(hdd_ipa))) + return 0; + + memset(&profile, 0, sizeof(profile)); + + if (tx_packets > (hdd_ctx->cfg_ini->busBandwidthHighThreshold / 2)) + next_cons_bw = hdd_ctx->cfg_ini->IpaHighBandwidthMbps; + else if (tx_packets > + (hdd_ctx->cfg_ini->busBandwidthMediumThreshold / 2)) + next_cons_bw = hdd_ctx->cfg_ini->IpaMediumBandwidthMbps; + else + next_cons_bw = hdd_ctx->cfg_ini->IpaLowBandwidthMbps; + + if (rx_packets > (hdd_ctx->cfg_ini->busBandwidthHighThreshold / 2)) + next_prod_bw = hdd_ctx->cfg_ini->IpaHighBandwidthMbps; + else if (rx_packets > + (hdd_ctx->cfg_ini->busBandwidthMediumThreshold / 2)) + next_prod_bw = hdd_ctx->cfg_ini->IpaMediumBandwidthMbps; + else + next_prod_bw = hdd_ctx->cfg_ini->IpaLowBandwidthMbps; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "CONS perf curr: %d, next: %d", + hdd_ipa->curr_cons_bw, next_cons_bw); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "PROD perf curr: %d, next: %d", + hdd_ipa->curr_prod_bw, next_prod_bw); + + if (hdd_ipa->curr_cons_bw != next_cons_bw) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "Requesting CONS perf curr: %d, next: %d", + hdd_ipa->curr_cons_bw, next_cons_bw); + profile.max_supported_bandwidth_mbps = next_cons_bw; + ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_WLAN_CONS, + &profile); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "RM CONS set perf profile failed: %d", + ret); + + return ret; + } + hdd_ipa->curr_cons_bw = next_cons_bw; + hdd_ipa->stats.num_cons_perf_req++; + } + + if (hdd_ipa->curr_prod_bw != next_prod_bw) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "Requesting PROD perf curr: %d, next: %d", + hdd_ipa->curr_prod_bw, next_prod_bw); + profile.max_supported_bandwidth_mbps = next_prod_bw; + ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_WLAN_PROD, + &profile); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "RM PROD set perf profile failed: %d", + ret); + return ret; + } + hdd_ipa->curr_prod_bw = next_prod_bw; + hdd_ipa->stats.num_prod_perf_req++; + } + + return 0; +} + +static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) +{ + struct ipa_rm_create_params create_params = {0}; + int ret; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return 0; + +#ifdef CONFIG_CNSS + cnss_init_work(&hdd_ipa->rm_work, hdd_ipa_rm_send_pkt_to_ipa); +#else + INIT_WORK(&hdd_ipa->rm_work, hdd_ipa_rm_send_pkt_to_ipa); +#endif + memset(&create_params, 0, sizeof(create_params)); + create_params.name = IPA_RM_RESOURCE_WLAN_PROD; + create_params.reg_params.user_data = hdd_ipa; + create_params.reg_params.notify_cb = hdd_ipa_rm_notify; + create_params.floor_voltage = IPA_VOLTAGE_SVS; + + ret = ipa_rm_create_resource(&create_params); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Create RM resource failed: %d", + ret); + goto setup_rm_fail; + } + + memset(&create_params, 0, sizeof(create_params)); + create_params.name = IPA_RM_RESOURCE_WLAN_CONS; + create_params.request_resource= hdd_ipa_rm_cons_request; + create_params.release_resource= hdd_ipa_rm_cons_release; + create_params.floor_voltage = IPA_VOLTAGE_SVS; + + ret = ipa_rm_create_resource(&create_params); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Create RM CONS resource failed: %d", ret); + goto delete_prod; + } + + ipa_rm_add_dependency(IPA_RM_RESOURCE_WLAN_PROD, + IPA_RM_RESOURCE_APPS_CONS); + + ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WLAN_PROD, + HDD_IPA_RX_INACTIVITY_MSEC_DELAY); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Timer init failed: %d", + ret); + goto timer_init_failed; + } + + /* Set the lowest bandwidth to start with */ + ret = hdd_ipa_set_perf_level(hdd_ipa->hdd_ctx, 0, 0); + + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Set perf level failed: %d", ret); + goto set_perf_failed; + } + + vos_wake_lock_init(&hdd_ipa->wake_lock, "wlan_ipa"); +#ifdef CONFIG_CNSS + cnss_init_delayed_work(&hdd_ipa->wake_lock_work, + hdd_ipa_wake_lock_timer_func); +#else + INIT_DELAYED_WORK(&hdd_ipa->wake_lock_work, + hdd_ipa_wake_lock_timer_func); +#endif + adf_os_spinlock_init(&hdd_ipa->rm_lock); + hdd_ipa->rm_state = HDD_IPA_RM_RELEASED; + hdd_ipa->wake_lock_released = true; + atomic_set(&hdd_ipa->tx_ref_cnt, 0); + + return ret; + +set_perf_failed: + ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WLAN_PROD); + +timer_init_failed: + ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_CONS); + +delete_prod: + ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD); + +setup_rm_fail: + return ret; +} + +static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa) +{ + int ret; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + return; + + cancel_delayed_work_sync(&hdd_ipa->wake_lock_work); + vos_wake_lock_destroy(&hdd_ipa->wake_lock); + +#ifdef WLAN_OPEN_SOURCE + cancel_work_sync(&hdd_ipa->rm_work); +#endif + adf_os_spinlock_destroy(&hdd_ipa->rm_lock); + + ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WLAN_PROD); + + ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD); + if (ret) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "RM PROD resource delete failed %d", ret); + + ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_CONS); + if (ret) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "RM CONS resource delete failed %d", ret); +} + +static void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adapter) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + + if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%p", + adapter); + + adf_nbuf_free(skb); + return; + } + + if (hdd_ipa->hdd_ctx->isUnloadInProgress) { + adf_nbuf_free(skb); + return; + } + + skb->dev = adapter->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_NONE; + ++adapter->hdd_stats.hddTxRxStats.rxPackets; + if (netif_rx_ni(skb) == NET_RX_SUCCESS) + ++adapter->hdd_stats.hddTxRxStats.rxDelivered; + else + ++adapter->hdd_stats.hddTxRxStats.rxRefused; + adapter->dev->last_rx = jiffies; +} + +static void hdd_ipa_send_pkt_to_ipa(struct hdd_ipa_priv *hdd_ipa) +{ + struct ipa_tx_data_desc *send_desc, *desc, *tmp; + uint32_t cur_send_cnt = 0, pend_q_cnt; + adf_nbuf_t buf; + struct ipa_tx_data_desc *send_desc_head = NULL; + + /* Unloading is in progress so do not proceed to send the packets to + * IPA + */ + if (hdd_ipa->hdd_ctx->isUnloadInProgress) + return; + + /* Make it priority queue request as send descriptor */ + send_desc_head = hdd_ipa_alloc_data_desc(hdd_ipa, 1); + + /* Try again later when descriptors are available */ + if (!send_desc_head) + return; + + INIT_LIST_HEAD(&send_desc_head->link); + + spin_lock_bh(&hdd_ipa->q_lock); + + if (hdd_ipa->pending_hw_desc_cnt >= hdd_ipa->hw_desc_cnt) { + hdd_ipa->stats.num_rx_ipa_hw_maxed_out++; + spin_unlock_bh(&hdd_ipa->q_lock); + hdd_ipa_free_data_desc(hdd_ipa, send_desc_head); + return; + } + + pend_q_cnt = hdd_ipa->pend_q_cnt; + + if (pend_q_cnt == 0) { + spin_unlock_bh(&hdd_ipa->q_lock); + hdd_ipa_free_data_desc(hdd_ipa, send_desc_head); + return; + } + + /* If hardware has more room than what is pending in the queue update + * the send_desc_head right away without going through the loop + */ + if ((hdd_ipa->pending_hw_desc_cnt + pend_q_cnt) < + hdd_ipa->hw_desc_cnt) { + list_splice_tail_init(&hdd_ipa->pend_desc_head, + &send_desc_head->link); + cur_send_cnt = pend_q_cnt; + hdd_ipa->pend_q_cnt = 0; + hdd_ipa->stats.num_rx_ipa_splice++; + } else { + while (((hdd_ipa->pending_hw_desc_cnt + cur_send_cnt) < + hdd_ipa->hw_desc_cnt) && pend_q_cnt > 0) + { + send_desc = list_first_entry(&hdd_ipa->pend_desc_head, + struct ipa_tx_data_desc, link); + list_del(&send_desc->link); + list_add_tail(&send_desc->link, &send_desc_head->link); + cur_send_cnt++; + pend_q_cnt--; + } + hdd_ipa->stats.num_rx_ipa_loop++; + + hdd_ipa->pend_q_cnt -= cur_send_cnt; + + VOS_ASSERT(hdd_ipa->pend_q_cnt == pend_q_cnt); + } + + hdd_ipa->pending_hw_desc_cnt += cur_send_cnt; + spin_unlock_bh(&hdd_ipa->q_lock); + + if (ipa_tx_dp_mul(hdd_ipa->prod_client, send_desc_head) != 0) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "ipa_tx_dp_mul failed: %u, q_cnt: %u!", + hdd_ipa->pending_hw_desc_cnt, + hdd_ipa->pend_q_cnt); + goto ipa_tx_failed; + } + + hdd_ipa->stats.num_rx_ipa_tx_dp += cur_send_cnt; + if (cur_send_cnt > hdd_ipa->stats.num_max_ipa_tx_mul) + hdd_ipa->stats.num_max_ipa_tx_mul = cur_send_cnt; + + return; + +ipa_tx_failed: + + spin_lock_bh(&hdd_ipa->q_lock); + hdd_ipa->pending_hw_desc_cnt -= cur_send_cnt; + spin_unlock_bh(&hdd_ipa->q_lock); + + list_for_each_entry_safe(desc, tmp, &send_desc_head->link, link) { + list_del(&desc->link); + buf = desc->priv; + adf_nbuf_free(buf); + hdd_ipa_free_data_desc(hdd_ipa, desc); + hdd_ipa->stats.num_rx_ipa_tx_dp_err++; + } + + /* Return anchor node */ + hdd_ipa_free_data_desc(hdd_ipa, send_desc_head); +} + +VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list, + v_U8_t sta_id) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + hdd_adapter_t *adapter = NULL; + struct hdd_ipa_iface_context *iface_context = NULL; + adf_nbuf_t buf, next_buf; + uint8_t cur_cnt = 0; + struct hdd_ipa_cld_hdr *cld_hdr; + struct ipa_tx_data_desc *send_desc = NULL; + + if (!hdd_ipa_is_enabled(hdd_ipa->hdd_ctx)) + return VOS_STATUS_E_INVAL; + + adapter = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; + if (!adapter || !adapter->ipa_context || + adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id: %d", + sta_id); + goto drop_pkts; + } + + iface_context = (struct hdd_ipa_iface_context *) adapter->ipa_context; + + buf = rx_buf_list; + while (buf) { + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "RX data", + buf->data, 24); + + next_buf = adf_nbuf_queue_next(buf); + adf_nbuf_set_next(buf, NULL); + + adapter->stats.rx_packets++; + adapter->stats.rx_bytes += buf->len; + /* + * we want to send Rx packets to IPA only when it is + * IPV4 or IPV6 (if IPV6 is enabled). All other packets + * will be sent to network stack directly. + */ + if (!hdd_ipa_can_send_to_ipa(adapter, hdd_ipa, buf->data)) { + iface_context->stats.num_rx_prefilter++; + hdd_ipa_send_skb_to_network(buf, adapter); + buf = next_buf; + continue; + } + + cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(buf, + HDD_IPA_WLAN_CLD_HDR_LEN); + cld_hdr->sta_id = sta_id; + cld_hdr->iface_id = iface_context->iface_id; + + send_desc = hdd_ipa_alloc_data_desc(hdd_ipa, 0); + if (!send_desc) { + adf_nbuf_free(buf); /*No desc available; drop*/ + buf = next_buf; + iface_context->stats.num_rx_send_desc_err++; + continue; + } + + send_desc->priv = buf; + send_desc->pyld_buffer = buf->data; + send_desc->pyld_len = buf->len; + spin_lock_bh(&hdd_ipa->q_lock); + list_add_tail(&send_desc->link, &hdd_ipa->pend_desc_head); + hdd_ipa->pend_q_cnt++; + spin_unlock_bh(&hdd_ipa->q_lock); + cur_cnt++; + buf = next_buf; + } + + iface_context->stats.num_rx_recv += cur_cnt; + if (cur_cnt > 1) + iface_context->stats.num_rx_recv_mul++; + + if (cur_cnt > iface_context->stats.max_rx_mul) + iface_context->stats.max_rx_mul = cur_cnt; + + if (hdd_ipa->pend_q_cnt > hdd_ipa->stats.max_pend_q_cnt) + hdd_ipa->stats.max_pend_q_cnt = hdd_ipa->pend_q_cnt; + + if (cur_cnt && hdd_ipa_rm_request(hdd_ipa) == 0) { + hdd_ipa_send_pkt_to_ipa(hdd_ipa); + } + + return VOS_STATUS_SUCCESS; + +drop_pkts: + buf = rx_buf_list; + while (buf) { + next_buf = adf_nbuf_queue_next(buf); + adf_nbuf_free(buf); + buf = next_buf; + hdd_ipa->stats.num_rx_drop++; + if (adapter) + adapter->stats.rx_dropped++; + } + + return VOS_STATUS_E_FAILURE; +} + +static void hdd_ipa_set_adapter_ip_filter(hdd_adapter_t *adapter) +{ + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + struct in_device *in_dev; + struct net_device *dev; + struct hdd_ipa_iface_context *iface_context; + + iface_context = (struct hdd_ipa_iface_context *)adapter->ipa_context; + dev = adapter->dev; + if (!dev || !iface_context) { + return; + } + /* This optimization not needed for Station mode one of + * the reason being sta-usb tethered mode + */ + if (adapter->device_mode == WLAN_HDD_INFRA_STATION) { + iface_context->ifa_address = 0; + return; + } + + + /* Get IP address */ + if (dev->priv_flags & IFF_BRIDGE_PORT) { +#ifdef WLAN_OPEN_SOURCE + rcu_read_lock(); +#endif + dev = netdev_master_upper_dev_get_rcu(adapter->dev); +#ifdef WLAN_OPEN_SOURCE + rcu_read_unlock(); +#endif + if (!dev) + return; + } + if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) { + if (dev->name && !strcmp(dev->name, ifa->ifa_label)) + break; /* found */ + } + } + if(ifa && ifa->ifa_address) { + iface_context->ifa_address = ifa->ifa_address; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,"%s: %d.%d.%d.%d", dev->name, + iface_context->ifa_address & 0x000000ff, + iface_context->ifa_address >> 8 & 0x000000ff, + iface_context->ifa_address >> 16 & 0x000000ff, + iface_context->ifa_address >> 24 & 0x000000ff); + } +} + +static int hdd_ipa_ipv4_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + hdd_adapter_list_node_t *padapter_node = NULL, *pnext = NULL; + hdd_adapter_t *padapter; + VOS_STATUS status; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "IPv4 Change detected. Updating wlan IPv4 local filters"); + + status = hdd_get_front_adapter(hdd_ipa->hdd_ctx, &padapter_node); + while (padapter_node && VOS_STATUS_SUCCESS == status) { + padapter = padapter_node->pAdapter; + if (padapter) + hdd_ipa_set_adapter_ip_filter(padapter); + + status = hdd_get_next_adapter(hdd_ipa->hdd_ctx, padapter_node, &pnext); + padapter_node = pnext; + } + return 0; +} + +static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data) +{ + struct hdd_ipa_priv *hdd_ipa = NULL; + hdd_adapter_t *adapter = NULL; + struct ipa_tx_data_desc *done_desc_head, *done_desc, *tmp; + adf_nbuf_t skb; + uint8_t iface_id; + adf_nbuf_t buf; + + hdd_ipa = (struct hdd_ipa_priv *)priv; + + switch (evt) { + case IPA_RECEIVE: + skb = (adf_nbuf_t) data; + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + iface_id = (uint8_t)skb->cb[0]; + } else +#endif /* IPA_UC_OFFLOAD */ + { + iface_id = HDD_IPA_GET_IFACE_ID(skb->data); + } + + if (iface_id >= HDD_IPA_MAX_IFACE) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "IPA_RECEIVE: Invalid iface_id: %u", + iface_id); + adf_nbuf_free(skb); + return; + } + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + adapter = hdd_ipa_uc_get_adapter(hdd_ipa, iface_id); + } else +#endif /* IPA_UC_OFFLOAD */ + { + adapter = hdd_ipa->iface_context[iface_id].adapter; + } + + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb", skb->data, + 8); +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + hdd_ipa->stats.num_rx_excep++; + skb_pull(skb, HDD_IPA_UC_WLAN_CLD_HDR_LEN); + } else +#endif /* IPA_UC_OFFLOAD */ + { + skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN); + } + + hdd_ipa->iface_context[iface_id].stats.num_rx_ipa_excep++; + hdd_ipa_send_skb_to_network(skb, adapter); + break; + case IPA_WRITE_DONE: + done_desc_head = (struct ipa_tx_data_desc *)data; + list_for_each_entry_safe(done_desc, tmp, + &done_desc_head->link, link) { + list_del(&done_desc->link); + buf = done_desc->priv; + adf_nbuf_free(buf); + hdd_ipa_free_data_desc(hdd_ipa, done_desc); + spin_lock_bh(&hdd_ipa->q_lock); + hdd_ipa->pending_hw_desc_cnt--; + spin_unlock_bh(&hdd_ipa->q_lock); + hdd_ipa->stats.num_rx_ipa_write_done++; + } + /* add anchor node also back to free list */ + hdd_ipa_free_data_desc(hdd_ipa, done_desc_head); + + hdd_ipa_send_pkt_to_ipa(hdd_ipa); + + hdd_ipa_rm_try_release(hdd_ipa); + break; + default: + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "w2i cb wrong event: 0x%x", evt); + return; + } +} + +static void hdd_ipa_nbuf_cb(adf_nbuf_t skb) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "%lx", NBUF_OWNER_PRIV_DATA(skb)); + ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb)); + + hdd_ipa->stats.num_tx_comp_cnt++; + + atomic_dec(&hdd_ipa->tx_ref_cnt); + + hdd_ipa_rm_try_release(hdd_ipa); +} + +static void hdd_ipa_send_pkt_to_tl(struct hdd_ipa_iface_context *iface_context, + struct ipa_rx_data *ipa_tx_desc) +{ + struct hdd_ipa_priv *hdd_ipa = iface_context->hdd_ipa; + v_U8_t interface_id; + hdd_adapter_t *adapter = NULL; + adf_nbuf_t skb; + + adf_os_spin_lock_bh(&iface_context->interface_lock); + adapter = iface_context->adapter; + if (!adapter) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, "Interface Down"); + ipa_free_skb(ipa_tx_desc); + iface_context->stats.num_tx_drop++; + adf_os_spin_unlock_bh(&iface_context->interface_lock); + hdd_ipa_rm_try_release(hdd_ipa); + return; + } + + /* + * During CAC period, data packets shouldn't be sent over the air so + * drop all the packets here + */ + if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx) { + ipa_free_skb(ipa_tx_desc); + adf_os_spin_unlock_bh(&iface_context->interface_lock); + iface_context->stats.num_tx_cac_drop++; + hdd_ipa_rm_try_release(hdd_ipa); + return; + } + + interface_id = adapter->sessionId; + ++adapter->stats.tx_packets; + adapter->stats.tx_bytes += ipa_tx_desc->skb->len; + + adf_os_spin_unlock_bh(&iface_context->interface_lock); + + skb = ipa_tx_desc->skb; + + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; + NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; + NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr; + + NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc; + + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, + iface_context->tl_context, ipa_tx_desc->skb, + interface_id); + if (skb) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "TLSHIM tx fail"); + ipa_free_skb(ipa_tx_desc); + iface_context->stats.num_tx_err++; + hdd_ipa_rm_try_release(hdd_ipa); + return; + } + + atomic_inc(&hdd_ipa->tx_ref_cnt); + + iface_context->stats.num_tx++; + +} + +static void hdd_ipa_pm_send_pkt_to_tl(struct work_struct *work) +{ + struct hdd_ipa_priv *hdd_ipa = container_of(work, + struct hdd_ipa_priv, pm_work); + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; + adf_nbuf_t skb; + uint32_t dequeued = 0; + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + while (((skb = adf_nbuf_queue_remove(&hdd_ipa->pm_queue_head)) != + NULL)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + + dequeued++; + + hdd_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + } + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + hdd_ipa->stats.num_tx_dequeued += dequeued; + if (dequeued > hdd_ipa->stats.num_max_pm_queue) + hdd_ipa->stats.num_max_pm_queue = dequeued; +} + +static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data) +{ + struct hdd_ipa_priv *hdd_ipa = NULL; + struct ipa_rx_data *ipa_tx_desc; + struct hdd_ipa_iface_context *iface_context; + adf_nbuf_t skb; + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; + + iface_context = (struct hdd_ipa_iface_context *) priv; + if (evt != IPA_RECEIVE) { + skb = (adf_nbuf_t) data; + dev_kfree_skb_any(skb); + iface_context->stats.num_tx_drop++; + return; + } + ipa_tx_desc = (struct ipa_rx_data *)data; + hdd_ipa = iface_context->hdd_ipa; + + /* + * When SSR is going on or driver is unloading, just drop the packets. + * During SSR, there is no use in queueing the packets as STA has to + * connect back any way + */ + if (hdd_ipa->hdd_ctx->isLogpInProgress || + hdd_ipa->hdd_ctx->isUnloadInProgress) { + ipa_free_skb(ipa_tx_desc); + iface_context->stats.num_tx_drop++; + return; + } + + skb = ipa_tx_desc->skb; + + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8); + + /* + * If PROD resource is not requested here then there may be cases where + * IPA hardware may be clocked down because of not having proper + * dependency graph between WLAN CONS and modem PROD pipes. Adding the + * workaround to request PROD resource while data is going over CONS + * pipe to prevent the IPA hardware clockdown. + */ + hdd_ipa_rm_request(hdd_ipa); + + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + /* + * If host is still suspended then queue the packets and these will be + * drained later when resume completes. When packet is arrived here and + * host is suspended, this means that there is already resume is in + * progress. + */ + if (hdd_ipa->suspended) { + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + pm_tx_cb->iface_context = iface_context; + pm_tx_cb->ipa_tx_desc = ipa_tx_desc; + adf_nbuf_queue_add(&hdd_ipa->pm_queue_head, skb); + hdd_ipa->stats.num_tx_queued++; + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + return; + } + + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + /* + * If we are here means, host is not suspended, wait for the work queue + * to finish. + */ +#ifdef WLAN_OPEN_SOURCE + flush_work(&hdd_ipa->pm_work); +#endif + + return hdd_ipa_send_pkt_to_tl(iface_context, ipa_tx_desc); +} + +int hdd_ipa_suspend(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return 0; + + /* + * Check if IPA is ready for suspend, If we are here means, there is + * high chance that suspend would go through but just to avoid any race + * condition after suspend started, these checks are conducted before + * allowing to suspend. + */ + if (atomic_read(&hdd_ipa->tx_ref_cnt)) + return -EAGAIN; + + adf_os_spin_lock_bh(&hdd_ipa->rm_lock); + + if (hdd_ipa->rm_state != HDD_IPA_RM_RELEASED) { + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + return -EAGAIN; + } + adf_os_spin_unlock_bh(&hdd_ipa->rm_lock); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + hdd_ipa->suspended = true; + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + return 0; +} + +int hdd_ipa_resume(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return 0; + + schedule_work(&hdd_ipa->pm_work); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + hdd_ipa->suspended = false; + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + return 0; +} + +static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) +{ + int i, ret = 0; + struct ipa_sys_connect_params *ipa; + uint32_t desc_fifo_sz; + + /* The maximum number of descriptors that can be provided to a BAM at + * once is one less than the total number of descriptors that the buffer + * can contain. + * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof + * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can + * be provided at once. + * Because of above requirement, one extra descriptor will be added to + * make sure hardware always has one descriptor. + */ + desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + + sizeof(struct sps_iovec); + + /*setup TX pipes */ + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params; + + ipa->client = hdd_ipa_adapter_2_client[i].cons_client; + ipa->desc_fifo_sz = desc_fifo_sz; + ipa->priv = &hdd_ipa->iface_context[i]; + ipa->notify = hdd_ipa_i2w_cb; + + ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; + ipa->ipa_ep_cfg.mode.mode = IPA_BASIC; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + ipa->keep_ipa_awake = 1; + + ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl)); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for pipe %d" + " ret: %d", i, ret); + goto setup_sys_pipe_fail; + } + hdd_ipa->sys_pipe[i].conn_hdl_valid = 1; + } + + /* + * Hard code it here, this can be extended if in case PROD pipe is also + * per interface. Right now there is no advantage of doing this. + */ + hdd_ipa->prod_client = IPA_CLIENT_WLAN1_PROD; + + ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params; + + ipa->client = hdd_ipa->prod_client; + + ipa->desc_fifo_sz = desc_fifo_sz; + ipa->priv = hdd_ipa; + ipa->notify = hdd_ipa_w2i_cb; + + ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; + ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_RX_HDR_LEN; + ipa->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1; + ipa->ipa_ep_cfg.mode.mode = IPA_BASIC; + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + ipa->keep_ipa_awake = 1; + + ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl)); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for RX pipe: %d", + ret); + goto setup_sys_pipe_fail; + } + hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].conn_hdl_valid = 1; + + return ret; + +setup_sys_pipe_fail: + + while (--i >= 0) { + ipa_teardown_sys_pipe(hdd_ipa->sys_pipe[i].conn_hdl); + adf_os_mem_zero(&hdd_ipa->sys_pipe[i], + sizeof(struct hdd_ipa_sys_pipe )); + } + + return ret; +} + +/* Disconnect all the Sys pipes */ +static void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa) +{ + int ret = 0, i; + for (i = 0; i < HDD_IPA_MAX_SYSBAM_PIPE; i++) { + if (hdd_ipa->sys_pipe[i].conn_hdl_valid) { + ret = ipa_teardown_sys_pipe( + hdd_ipa->sys_pipe[i].conn_hdl); + if (ret) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed: %d", + ret); + + hdd_ipa->sys_pipe[i].conn_hdl_valid = 0; + } + } +} + +static int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, + struct hdd_ipa_iface_context *iface_context) +{ + struct ipa_tx_intf tx_intf; + struct ipa_rx_intf rx_intf; + struct ipa_ioc_tx_intf_prop *tx_prop = NULL; + struct ipa_ioc_rx_intf_prop *rx_prop = NULL; + char *ifname = iface_context->adapter->dev->name; + + char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX]; + char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX]; + + int num_prop = 1; + int ret = 0; + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) + num_prop++; + + /* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */ + tx_prop = adf_os_mem_alloc(NULL, + sizeof(struct ipa_ioc_tx_intf_prop) * num_prop); + if (!tx_prop) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "tx_prop allocation failed"); + goto register_interface_fail; + } + + /* Allocate RX properties, 1 each for IPv4 & IPv6 */ + rx_prop = adf_os_mem_alloc(NULL, + sizeof(struct ipa_ioc_rx_intf_prop) * num_prop); + if (!rx_prop) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "rx_prop allocation failed"); + goto register_interface_fail; + } + + adf_os_mem_zero(&tx_intf, sizeof(tx_intf)); + adf_os_mem_zero(&rx_intf, sizeof(rx_intf)); + + snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV6_NAME_EXT); + + rx_prop[IPA_IP_v4].ip = IPA_IP_v4; + rx_prop[IPA_IP_v4].src_pipe = iface_context->prod_client; + + rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA; + + /* + * Interface ID is 3rd byte in the CLD header. Add the meta data and + * mask to identify the interface in IPA hardware + */ + rx_prop[IPA_IP_v4].attrib.meta_data = + htonl(iface_context->iface_id << 16); + rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000); + + rx_intf.num_props++; + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { + rx_prop[IPA_IP_v6].ip = IPA_IP_v6; + rx_prop[IPA_IP_v6].src_pipe = iface_context->prod_client; + + rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA; + rx_prop[IPA_IP_v4].attrib.meta_data = + htonl(iface_context->iface_id << 16); + rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000); + + rx_intf.num_props++; + } + + tx_prop[IPA_IP_v4].ip = IPA_IP_v4; + tx_prop[IPA_IP_v4].dst_pipe = iface_context->cons_client; + strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, + IPA_RESOURCE_NAME_MAX); + tx_intf.num_props++; + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { + tx_prop[IPA_IP_v6].ip = IPA_IP_v6; + tx_prop[IPA_IP_v6].dst_pipe = iface_context->cons_client; + strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name, + IPA_RESOURCE_NAME_MAX); + tx_intf.num_props++; + } + + tx_intf.prop = tx_prop; + rx_intf.prop = rx_prop; + + /* Call the ipa api to register interface */ + ret = ipa_register_intf(ifname, &tx_intf, &rx_intf); + +register_interface_fail: + adf_os_mem_free(tx_prop); + adf_os_mem_free(rx_prop); + return ret; +} + +static void hdd_remove_ipa_header(char *name) +{ + struct ipa_ioc_get_hdr hdrlookup; + int ret = 0, len; + struct ipa_ioc_del_hdr *ipa_hdr; + + adf_os_mem_zero(&hdrlookup, sizeof(hdrlookup)); + strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name)); + ret = ipa_get_hdr(&hdrlookup); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d", + name, ret); + return; + } + + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: 0x%x", hdrlookup.hdl); + len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1; + ipa_hdr = (struct ipa_ioc_del_hdr *) adf_os_mem_alloc(NULL, len); + if (ipa_hdr == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_hdr allocation failed"); + return; + } + ipa_hdr->num_hdls = 1; + ipa_hdr->commit = 0; + ipa_hdr->hdl[0].hdl = hdrlookup.hdl; + ipa_hdr->hdl[0].status = -1; + ret = ipa_del_hdr(ipa_hdr); + if (ret != 0) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Delete header failed: %d", + ret); + + adf_os_mem_free(ipa_hdr); +} + + +static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa, + struct hdd_ipa_iface_context *iface_context, uint8_t *mac_addr) +{ + hdd_adapter_t *adapter = iface_context->adapter; + char *ifname; + struct ipa_ioc_add_hdr *ipa_hdr = NULL; + int ret = -EINVAL; + struct hdd_ipa_tx_hdr *tx_hdr = NULL; +#ifdef IPA_UC_OFFLOAD + struct hdd_ipa_uc_tx_hdr *uc_tx_hdr = NULL; +#endif /* IPA_UC_OFFLOAD */ + + ifname = adapter->dev->name; + + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Add Partial hdr: %s, %pM", + ifname, mac_addr); + + /* dynamically allocate the memory to add the hdrs */ + ipa_hdr = adf_os_mem_alloc(NULL, sizeof(struct ipa_ioc_add_hdr) + + sizeof(struct ipa_hdr_add)); + if (!ipa_hdr) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: ipa_hdr allocation failed", ifname); + ret = -ENOMEM; + goto end; + } + + ipa_hdr->commit = 0; + ipa_hdr->num_hdrs = 1; + + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { +#ifdef IPA_UC_OFFLOAD + uc_tx_hdr = (struct hdd_ipa_uc_tx_hdr *)ipa_hdr->hdr[0].hdr; + memcpy(uc_tx_hdr, &ipa_uc_tx_hdr, HDD_IPA_UC_WLAN_TX_HDR_LEN); + memcpy(uc_tx_hdr->eth.h_source, mac_addr, ETH_ALEN); + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + ipa_hdr->hdr[0].hdr_len = HDD_IPA_UC_WLAN_TX_HDR_LEN; + ipa_hdr->hdr[0].is_partial = 1; + ipa_hdr->hdr[0].hdr_hdl = 0; + ret = ipa_add_hdr(ipa_hdr); +#endif /* IPA_UC_OFFLOAD */ + } else { + tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr; + + /* Set the Source MAC */ + memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN); + memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN); + + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; + ipa_hdr->hdr[0].is_partial = 1; + ipa_hdr->hdr[0].hdr_hdl = 0; + + /* Set the type to IPV4 in the header*/ + tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP); + + ret = ipa_add_hdr(ipa_hdr); + } + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 add hdr failed: %d", + ifname, ret); + goto end; + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: 0x%x", + ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl); + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV6_NAME_EXT); + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + /* Set the type to IPV6 in the header*/ + uc_tx_hdr = (struct hdd_ipa_uc_tx_hdr *)ipa_hdr->hdr[0].hdr; + uc_tx_hdr->eth.h_proto = cpu_to_be16(ETH_P_IPV6); + } else +#endif /* IPA_UC_OFFLOAD */ + { + /* Set the type to IPV6 in the header*/ + tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr; + tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6); + } + + ret = ipa_add_hdr(ipa_hdr); + + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPv6 add hdr failed: %d", + ifname, ret); + goto clean_ipv4_hdr; + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: 0x%x", + ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl); + } + + adf_os_mem_free(ipa_hdr); + + return ret; + +clean_ipv4_hdr: + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + hdd_remove_ipa_header(ipa_hdr->hdr[0].name); +end: + if(ipa_hdr) + adf_os_mem_free(ipa_hdr); + + return ret; +} + +static void hdd_ipa_clean_hdr(hdd_adapter_t *adapter) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + int ret; + char name_ipa[IPA_RESOURCE_NAME_MAX]; + + /* Remove the headers */ + snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s", + adapter->dev->name, HDD_IPA_IPV4_NAME_EXT); + hdd_remove_ipa_header(name_ipa); + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { + snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s", + adapter->dev->name, HDD_IPA_IPV6_NAME_EXT); + hdd_remove_ipa_header(name_ipa); + } + /* unregister the interface with IPA */ + ret = ipa_deregister_intf(adapter->dev->name); + if (ret) + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: ipa_deregister_intf fail: %d", + adapter->dev->name, ret); +} + +static void hdd_ipa_cleanup_iface(struct hdd_ipa_iface_context *iface_context) +{ + if (iface_context == NULL) + return; + + hdd_ipa_clean_hdr(iface_context->adapter); + + adf_os_spin_lock_bh(&iface_context->interface_lock); + iface_context->adapter->ipa_context = NULL; + iface_context->adapter = NULL; + iface_context->tl_context = NULL; + adf_os_spin_unlock_bh(&iface_context->interface_lock); + iface_context->ifa_address = 0; +} + + +static int hdd_ipa_setup_iface(struct hdd_ipa_priv *hdd_ipa, + hdd_adapter_t *adapter, uint8_t sta_id) +{ + struct hdd_ipa_iface_context *iface_context = NULL; + void *tl_context = NULL; + int i, ret = 0; + + /* Lower layer may send multiple START_BSS_EVENT in DFS mode or during + * channel change indication. Since these indications are sent by lower + * layer as SAP updates and IPA doesn't have to do anything for these + * updates so ignoring! + */ + if (WLAN_HDD_SOFTAP == adapter->device_mode && adapter->ipa_context) + return 0; + + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + if (hdd_ipa->iface_context[i].adapter == NULL) { + iface_context = &(hdd_ipa->iface_context[i]); + break; + } + } + + if (iface_context == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "All the IPA interfaces are in use"); + ret = -ENOMEM; + goto end; + } + + + adapter->ipa_context = iface_context; + iface_context->adapter = adapter; + iface_context->sta_id = sta_id; + tl_context = tl_shim_get_vdev_by_sta_id(hdd_ipa->hdd_ctx->pvosContext, + sta_id); + + if (tl_context == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Not able to get TL context sta_id: %d", + sta_id); + ret = -EINVAL; + goto end; + } + + iface_context->tl_context = tl_context; + + ret = hdd_ipa_add_header_info(hdd_ipa, iface_context, + adapter->dev->dev_addr); + + if (ret) + goto end; + + /* Configure the TX and RX pipes filter rules */ + ret = hdd_ipa_register_interface(hdd_ipa, iface_context); + if (ret) + goto cleanup_header; + + return ret; + +cleanup_header: + + hdd_ipa_clean_hdr(adapter); +end: + if (iface_context) + hdd_ipa_cleanup_iface(iface_context); + return ret; +} + + +static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) +{ + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len); + ghdd_ipa->stats.num_free_msg++; + adf_os_mem_free(buff); +} + +static inline char *hdd_ipa_wlan_event_to_str(enum ipa_wlan_event event) +{ + switch(event) { + case WLAN_CLIENT_CONNECT: return "WLAN_CLIENT_CONNECT"; + case WLAN_CLIENT_DISCONNECT: return "WLAN_CLIENT_DISCONNECT"; + case WLAN_CLIENT_POWER_SAVE_MODE: return "WLAN_CLIENT_POWER_SAVE_MODE"; + case WLAN_CLIENT_NORMAL_MODE: return "WLAN_CLIENT_NORMAL_MODE"; + case SW_ROUTING_ENABLE: return "SW_ROUTING_ENABLE"; + case SW_ROUTING_DISABLE: return "SW_ROUTING_DISABLE"; + case WLAN_AP_CONNECT: return "WLAN_AP_CONNECT"; + case WLAN_AP_DISCONNECT: return "WLAN_AP_DISCONNECT"; + case WLAN_STA_CONNECT: return "WLAN_STA_CONNECT"; + case WLAN_STA_DISCONNECT: return "WLAN_STA_DISCONNECT"; + case WLAN_CLIENT_CONNECT_EX: return "WLAN_CLIENT_CONNECT_EX"; + + case IPA_WLAN_EVENT_MAX: + default: + return "UNKNOWN"; + } +} + +int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, + enum ipa_wlan_event type, uint8_t *mac_addr) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + struct ipa_msg_meta meta; + struct ipa_wlan_msg *msg; + struct ipa_wlan_msg_ex *msg_ex = NULL; + int ret; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d", + adapter->dev->name, hdd_ipa_wlan_event_to_str(type), + mac_addr, + sta_id); + + if (type >= IPA_WLAN_EVENT_MAX) + return -EINVAL; + + if (WARN_ON(is_zero_ether_addr(mac_addr))) + return -EINVAL; + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa) && + (WLAN_HDD_SOFTAP != adapter->device_mode)) { + return 0; + } + /* During IPA UC resource loading/unloading + * new event issued. + * Store event seperatly and handle later */ + if (hdd_ipa_uc_is_enabled(hdd_ipa) && + ((hdd_ipa->resource_loading) || + (hdd_ipa->resource_unloading))) { + struct ipa_uc_pending_event *pending_evet = NULL; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s, RL/RUL inprogress", __func__); + pending_evet = (struct ipa_uc_pending_event *)vos_mem_malloc( + sizeof(struct ipa_uc_pending_event)); + if (!pending_evet) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Pending event memory alloc fail"); + return -ENOMEM; + } + pending_evet->adapter = adapter; + pending_evet->sta_id = sta_id; + pending_evet->type = type; + vos_mem_copy(pending_evet->mac_addr, + mac_addr, + VOS_MAC_ADDR_SIZE); + vos_list_insert_back(&hdd_ipa->pending_event, + &pending_evet->node); + } +#endif /* IPA_UC_OFFLOAD */ + + hdd_ipa->stats.event[type]++; + + switch (type) { + case WLAN_STA_CONNECT: + case WLAN_AP_CONNECT: + ret = hdd_ipa_setup_iface(hdd_ipa, adapter, sta_id); + if (ret) + goto end; + break; + + case WLAN_STA_DISCONNECT: + case WLAN_AP_DISCONNECT: + hdd_ipa_cleanup_iface(adapter->ipa_context); + break; + + case WLAN_CLIENT_CONNECT_EX: + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", + adapter->dev->ifindex, sta_id); + + meta.msg_type = type; + meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) + + sizeof(struct ipa_wlan_hdr_attrib_val)); + msg_ex = adf_os_mem_alloc (NULL, meta.msg_len); + + if (msg_ex == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "msg_ex allocation failed"); + return -ENOMEM; + } + strlcpy(msg_ex->name, adapter->dev->name, + IPA_RESOURCE_NAME_MAX); + msg_ex->num_of_attribs = 1; + msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR; +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + msg_ex->attribs[0].offset = + HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET; + } else +#endif /* IPA_UC_OFFLOAD */ + { + msg_ex->attribs[0].offset = + HDD_IPA_WLAN_HDR_DES_MAC_OFFSET; + } + memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, + IPA_MAC_ADDR_SIZE); + + ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn); + + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d : %d", + msg_ex->name, meta.msg_type, ret); + adf_os_mem_free(msg_ex); + return ret; + } + hdd_ipa->stats.num_send_msg++; +#ifdef IPA_UC_OFFLOAD + if (!hdd_ipa_uc_is_enabled(hdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED", + msg_ex->name, meta.msg_type); + } else { + vos_lock_acquire(&hdd_ipa->event_lock); + if (hdd_ipa_uc_find_add_assoc_sta(hdd_ipa, + VOS_TRUE, + sta_id)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: STA ID %d found, not valid", + msg_ex->name, sta_id); + vos_lock_release(&hdd_ipa->event_lock); + return 0; + } + hdd_ipa->sap_num_connected_sta++; + hdd_ipa->pending_cons_req = VOS_FALSE; + /* Enable IPA UC Data PIPEs when first STA connected */ + if (1 == hdd_ipa->sap_num_connected_sta) { + ret = hdd_ipa_uc_handle_first_con(hdd_ipa); + if (!ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: handle 1st con ret %d", + msg_ex->name, ret); + } + } + vos_lock_release(&hdd_ipa->event_lock); + } +#endif /* IPA_UC_OFFLOAD */ + return ret; + + case WLAN_CLIENT_DISCONNECT: +#ifdef IPA_UC_OFFLOAD + if (!hdd_ipa_uc_is_enabled(hdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPA UC OFFLOAD NOT ENABLED", + msg_ex->name); + return 0; + } + + vos_lock_acquire(&hdd_ipa->event_lock); + if (!hdd_ipa_uc_find_add_assoc_sta(hdd_ipa, + VOS_FALSE, + sta_id)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: STA ID %d NOT found, not valid", + msg_ex->name, sta_id); + vos_lock_release(&hdd_ipa->event_lock); + return 0; + } + hdd_ipa->sap_num_connected_sta--; + /* Disable IPA UC TX PIPE when last STA disconnected */ + if (!hdd_ipa->sap_num_connected_sta) { + hdd_ipa_uc_handle_last_discon(hdd_ipa); + } + vos_lock_release(&hdd_ipa->event_lock); +#endif /* IPA_UC_OFFLOAD */ + break; + + default: + return 0; + } + + meta.msg_len = sizeof(struct ipa_wlan_msg); + msg = adf_os_mem_alloc(NULL, meta.msg_len); + if (msg == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "msg allocation failed"); + return -ENOMEM; + } + + meta.msg_type = type; + strlcpy(msg->name, adapter->dev->name, IPA_RESOURCE_NAME_MAX); + memcpy(msg->mac_addr, mac_addr, ETH_ALEN); + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d", + msg->name, meta.msg_type); + + ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn); + + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d fail:%d", + msg->name, meta.msg_type, ret); + adf_os_mem_free(msg); + return ret; + } + + hdd_ipa->stats.num_send_msg++; + +end: + return ret; +} + + +static void hdd_ipa_rx_pipe_desc_free(void) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + uint32_t i = 0, max_desc_cnt; + struct ipa_tx_data_desc *desc, *tmp; + + max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; + + spin_lock_bh(&hdd_ipa->q_lock); + + list_for_each_entry_safe(desc, tmp, &hdd_ipa->pend_desc_head, link) { + list_del(&desc->link); + adf_nbuf_free(desc->priv); + spin_unlock_bh(&hdd_ipa->q_lock); + hdd_ipa_free_data_desc(hdd_ipa, desc); + spin_lock_bh(&hdd_ipa->q_lock); + } + + list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) { + list_del(&desc->link); + spin_unlock_bh(&hdd_ipa->q_lock); + adf_os_mem_free(desc); + spin_lock_bh(&hdd_ipa->q_lock); + i++; + } + spin_unlock_bh(&hdd_ipa->q_lock); + + if (i != max_desc_cnt) + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free desc leak: %u, %u", i, + max_desc_cnt); + +} + + +static int hdd_ipa_rx_pipe_desc_alloc(void) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + uint32_t i, max_desc_cnt; + int ret = 0; + struct ipa_tx_data_desc *tmp_desc; + + hdd_ipa->hw_desc_cnt = IPA_NUM_OF_FIFO_DESC( + hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize); + max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; + + spin_lock_init(&hdd_ipa->q_lock); + + INIT_LIST_HEAD(&hdd_ipa->free_desc_head); + INIT_LIST_HEAD(&hdd_ipa->pend_desc_head); + hdd_ipa->freeq_cnt = max_desc_cnt; + for (i = 0; i < max_desc_cnt; i++) { + tmp_desc = adf_os_mem_alloc(NULL, + sizeof(struct ipa_tx_data_desc)); + if (!tmp_desc) { + ret = -ENOMEM; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Descriptor allocation failed"); + goto fail; + } + spin_lock_bh(&hdd_ipa->q_lock); + list_add_tail(&tmp_desc->link, &hdd_ipa->free_desc_head); + spin_unlock_bh(&hdd_ipa->q_lock); + } + + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "Desc sz:%d h_desc_cnt:%d freeq_cnt:%u", + hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize, hdd_ipa->hw_desc_cnt, + hdd_ipa->freeq_cnt); + return ret; +fail: + hdd_ipa_rx_pipe_desc_free(); + return ret; +} + +static inline char *hdd_ipa_rm_state_to_str(enum hdd_ipa_rm_state state) +{ + switch (state) { + case HDD_IPA_RM_RELEASED: return "RELEASED"; + case HDD_IPA_RM_GRANT_PENDING: return "GRANT_PENDING"; + case HDD_IPA_RM_GRANTED: return "GRANTED"; + } + + return "UNKNOWN"; +} + +static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + struct hdd_ipa_priv *hdd_ipa = file->private_data; + char *buf; + unsigned int len = 0, buf_len = 4096; + ssize_t ret_cnt; + int i; + struct hdd_ipa_iface_context *iface_context = NULL; +#define HDD_IPA_STATS(_buf, _len, _hdd_ipa, _name) \ + scnprintf(_buf, _len, "%30s: %llu\n", #_name, _hdd_ipa->stats._name) + +#define HDD_IPA_IFACE_STATS(_buf, _len, _iface, _name) \ + scnprintf(_buf, _len, "%30s: %llu\n", #_name, _iface->stats._name) + + buf = kzalloc(buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + len += scnprintf(buf + len, buf_len - len, + "\nhw_desc_cnt/pending_cnt: %u/%u, " + "freeq_cnt/pend_q_cnt: %u/%u\n", hdd_ipa->hw_desc_cnt, + hdd_ipa->pending_hw_desc_cnt, hdd_ipa->freeq_cnt, + hdd_ipa->pend_q_cnt); + + len += scnprintf(buf + len, buf_len - len, + "\n<------------------ WLAN EVENTS STATS" + " ------------------>\n"); + for (i = 0; i < IPA_WLAN_EVENT_MAX; i++) { + len += scnprintf(buf + len, buf_len - len, "%30s: %u\n", + hdd_ipa_wlan_event_to_str(i), + hdd_ipa->stats.event[i]); + } + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_send_msg); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_free_msg); + + if (!hdd_ipa_is_rm_enabled(hdd_ipa)) + goto skip; + + len += scnprintf(buf + len, buf_len - len, + "\n<------------------ IPA RM STATS" + " ------------------>\n"); + + len += scnprintf(buf + len, buf_len - len, "%30s: %s\n", "rm_state", + hdd_ipa_rm_state_to_str(hdd_ipa->rm_state)); + + len += scnprintf(buf + len, buf_len - len, "%30s: %s\n", "wake_lock", + hdd_ipa->wake_lock_released ? "RELEASED" : "ACQUIRED"); + + len += scnprintf(buf + len, buf_len - len, "%30s: %d\n", "tx_ref_cnt", + atomic_read(&hdd_ipa->tx_ref_cnt)); + + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_rm_grant); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_rm_release); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rm_grant_imm); + + if (!hdd_ipa_is_clk_scaling_enabled(hdd_ipa)) + goto skip; + + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_cons_perf_req); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_prod_perf_req); + len += scnprintf(buf + len, buf_len - len, "%30s: %u\n", "curr_prod_bw", + hdd_ipa->curr_prod_bw); + len += scnprintf(buf + len, buf_len - len, "%30s: %u\n", "curr_cons_bw", + hdd_ipa->curr_cons_bw); + +skip: + len += scnprintf(buf + len, buf_len - len, + "\n<------------------ IPA STATS" + " ------------------>\n"); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, num_rx_drop); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_tx_dp); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_splice); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_loop); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_tx_dp_err); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_write_done); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_max_ipa_tx_mul); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_rx_ipa_hw_maxed_out); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + max_pend_q_cnt); + + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_tx_comp_cnt); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_tx_queued); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_tx_dequeued); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_max_pm_queue); + + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_freeq_empty); + len += HDD_IPA_STATS(buf + len, buf_len - len, hdd_ipa, + num_pri_freeq_empty); + + len += scnprintf(buf + len, buf_len - len, + "\n<------------------ IPA IFACE STATS" + " ------------------>\n"); + + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + + iface_context = &hdd_ipa->iface_context[i]; + + if (iface_context->adapter == NULL) + continue; + + len += scnprintf(buf + len, buf_len - len, + "\n%s: iface_id: %u, sta_id: %u," + " device_mode: %u\n", + iface_context->adapter->dev->name, + iface_context->iface_id, + iface_context->sta_id, + iface_context->adapter->device_mode); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_tx); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_tx_drop); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_tx_err); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_tx_cac_drop); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_rx_prefilter); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_rx_ipa_excep); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_rx_recv); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_rx_recv_mul); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, num_rx_send_desc_err); + len += HDD_IPA_IFACE_STATS(buf + len, buf_len - len, + iface_context, max_rx_mul); + } + + ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); + + kfree(buf); + return ret_cnt; +#undef HDD_IPA_STATS +#undef HDD_IPA_IFACE_STATS +} + +static ssize_t hdd_ipa_debugfs_write_ipa_stats(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + struct hdd_ipa_priv *hdd_ipa = file->private_data; + struct hdd_ipa_iface_context *iface_context = NULL; + int ret; + uint32_t val; + int i; + + ret = kstrtou32_from_user(user_buf, count, 0, &val); + + if (ret) + return ret; + + if (val == 0) { + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + iface_context = &hdd_ipa->iface_context[i]; + memset(&iface_context->stats, 0, + sizeof(iface_context->stats)); + } + + memset(&hdd_ipa->stats, 0, sizeof(hdd_ipa->stats)); + } + + return count; +} + +static const struct file_operations fops_ipa_stats = { + .read = hdd_ipa_debugfs_read_ipa_stats, + .write = hdd_ipa_debugfs_write_ipa_stats, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + + +static int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) +{ +#ifdef WLAN_OPEN_SOURCE + hdd_ipa->debugfs_dir = debugfs_create_dir("cld", + hdd_ipa->hdd_ctx->wiphy->debugfsdir); + if (!hdd_ipa->debugfs_dir) + return -ENOMEM; + + debugfs_create_file("ipa-stats", S_IRUSR, hdd_ipa->debugfs_dir, + hdd_ipa, &fops_ipa_stats); +#endif + return 0; +} + +static void hdd_ipa_debugfs_remove(struct hdd_ipa_priv *hdd_ipa) +{ +#ifdef WLAN_OPEN_SOURCE + debugfs_remove_recursive(hdd_ipa->debugfs_dir); +#endif +} + +/** +* hdd_ipa_init() - Allocate hdd_ipa resources, ipa pipe resource and register +* wlan interface with IPA module. +* @param +* hdd_ctx : [in] pointer to HDD context +* @return : VOS_STATUS_E_FAILURE - Errors +* : VOS_STATUS_SUCCESS - Ok +*/ +VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = NULL; + int ret, i; + struct hdd_ipa_iface_context *iface_context = NULL; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return VOS_STATUS_SUCCESS; + + hdd_ipa = adf_os_mem_alloc(NULL, sizeof(struct hdd_ipa_priv)); + if (!hdd_ipa) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "hdd_ipa allocation failed"); + goto fail_setup_rm; + } + + hdd_ctx->hdd_ipa = hdd_ipa; + ghdd_ipa = hdd_ipa; + hdd_ipa->hdd_ctx = hdd_ctx; + + /* Create the interface context */ + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + iface_context = &hdd_ipa->iface_context[i]; + iface_context->hdd_ipa = hdd_ipa; + iface_context->cons_client = + hdd_ipa_adapter_2_client[i].cons_client; + iface_context->prod_client = + hdd_ipa_adapter_2_client[i].prod_client; + iface_context->iface_id = i; + adf_os_spinlock_init(&iface_context->interface_lock); + } + +#ifdef CONFIG_CNSS + cnss_init_work(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl); +#else + INIT_WORK(&hdd_ipa->pm_work, hdd_ipa_pm_send_pkt_to_tl); +#endif + adf_os_spinlock_init(&hdd_ipa->pm_lock); + adf_nbuf_queue_init(&hdd_ipa->pm_queue_head); + + ret = hdd_ipa_setup_rm(hdd_ipa); + if (ret) + goto fail_setup_rm; + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + hdd_ipa->sap_num_connected_sta = 0; + hdd_ipa->ipa_tx_packets_diff = 0; + hdd_ipa->ipa_rx_packets_diff = 0; + hdd_ipa->ipa_p_tx_packets = 0; + hdd_ipa->ipa_p_rx_packets = 0; + hdd_ipa_uc_ol_init(hdd_ctx); + } else +#endif /* IPA_UC_OFFLOAD */ + { + ret = hdd_ipa_setup_sys_pipe(hdd_ipa); + if (ret) + goto fail_create_sys_pipe; + + ret = hdd_ipa_rx_pipe_desc_alloc(); + if (ret) + goto fail_alloc_rx_pipe_desc; + } + + ret = hdd_ipa_debugfs_init(hdd_ipa); + if (ret) + goto fail_alloc_rx_pipe_desc; + + if (!hdd_ipa_uc_is_enabled(hdd_ipa)) { + hdd_ipa->ipv4_notifier.notifier_call = hdd_ipa_ipv4_changed; + ret = register_inetaddr_notifier(&hdd_ipa->ipv4_notifier); + if (ret) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "WLAN IPv4 local filter register failed"); + } + + return VOS_STATUS_SUCCESS; +fail_alloc_rx_pipe_desc: + hdd_ipa_rx_pipe_desc_free(); +fail_create_sys_pipe: + hdd_ipa_destory_rm_resource(hdd_ipa); +fail_setup_rm: + if (hdd_ipa) + adf_os_mem_free(hdd_ipa); + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) +{ + struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; + int i; + struct hdd_ipa_iface_context *iface_context = NULL; + adf_nbuf_t skb; + struct hdd_ipa_pm_tx_cb *pm_tx_cb = NULL; + + if (!hdd_ipa_is_enabled(hdd_ctx)) + return VOS_STATUS_SUCCESS; + + if (!hdd_ipa_uc_is_enabled(hdd_ipa)) { + unregister_inetaddr_notifier(&hdd_ipa->ipv4_notifier); + hdd_ipa_teardown_sys_pipe(hdd_ipa); + } + + hdd_ipa_destory_rm_resource(hdd_ipa); + +#ifdef WLAN_OPEN_SOURCE + cancel_work_sync(&hdd_ipa->pm_work); +#endif + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + + while (((skb = adf_nbuf_queue_remove(&hdd_ipa->pm_queue_head)) != + NULL)) { + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb; + ipa_free_skb(pm_tx_cb->ipa_tx_desc); + + adf_os_spin_lock_bh(&hdd_ipa->pm_lock); + } + adf_os_spin_unlock_bh(&hdd_ipa->pm_lock); + + adf_os_spinlock_destroy(&hdd_ipa->pm_lock); + + /* Destroy the interface lock */ + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + iface_context = &hdd_ipa->iface_context[i]; + adf_os_spinlock_destroy(&iface_context->interface_lock); + } + + hdd_ipa_debugfs_remove(hdd_ipa); + + /* This should never hit but still make sure that there are no pending + * descriptor in IPA hardware + */ + if (hdd_ipa->pending_hw_desc_cnt != 0) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "IPA Pending write done: %d Waiting!", + hdd_ipa->pending_hw_desc_cnt); + + for (i = 0; hdd_ipa->pending_hw_desc_cnt != 0 && i < 10; i++) { + usleep(100); + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "IPA Pending write done: desc: %d %s(%d)!", + hdd_ipa->pending_hw_desc_cnt, + hdd_ipa->pending_hw_desc_cnt == 0 ? "completed" + : "leak", i); + } + +#ifdef IPA_UC_OFFLOAD + if (hdd_ipa_uc_is_enabled(hdd_ipa)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disconnect TX PIPE", __func__); + ipa_disconnect_wdi_pipe(hdd_ipa->tx_pipe_handle); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, + "%s: Disconnect RX PIPE", __func__); + ipa_disconnect_wdi_pipe(hdd_ipa->rx_pipe_handle); + vos_lock_destroy(&hdd_ipa->event_lock); + vos_list_destroy(&hdd_ipa->pending_event); + } else +#endif /* IPA_UC_OFFLOAD */ + { + hdd_ipa_rx_pipe_desc_free(); + } + + adf_os_mem_free(hdd_ipa); + hdd_ctx->hdd_ipa = NULL; + + return VOS_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c new file mode 100755 index 0000000000000..42e4dab2112bb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c @@ -0,0 +1,14401 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/*======================================================================== + + \file wlan_hdd_main.c + + \brief WLAN Host Device Driver implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module + 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +//#include +#include +#include +#include +#ifdef WLAN_FEATURE_LPSS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include +#include +#endif // WLAN_BTAMP_FEATURE +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" + +#include +#include +#include +#include +#include +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_p2p.h" +#include +int wlan_hdd_ftm_start(hdd_context_t *pAdapter); +#include "sapApi.h" +#include +#include +#include +#ifdef MSM_PLATFORM +#ifdef CONFIG_CNSS +#include +#endif +#endif +#include +#include +#include "cfgApi.h" +#include "wlan_hdd_dev_pwr.h" +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif +#include "qwlan_version.h" +#include "wlan_qct_wda.h" +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#ifdef FEATURE_WLAN_CH_AVOID +#ifdef CONFIG_CNSS +#include +#endif +extern int hdd_hostapd_stop (struct net_device *dev); +void hdd_ch_avoid_cb(void *hdd_context,void *indi_param); +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_NAN +#include "wlan_hdd_nan.h" +#endif /* WLAN_FEATURE_NAN */ + +#include "wlan_hdd_debugfs.h" +#include "epping_main.h" + +#ifdef IPA_OFFLOAD +#include +#endif +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +#include "wma.h" + +#if defined(LINUX_QCMBR) +#define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13) +#endif + +#ifdef MODULE +#define WLAN_MODULE_NAME module_name(THIS_MODULE) +#else +#define WLAN_MODULE_NAME "wlan" +#endif + +#ifdef TIMER_MANAGER +#define TIMER_MANAGER_STR " +TIMER_MANAGER" +#else +#define TIMER_MANAGER_STR "" +#endif + +#ifdef MEMORY_DEBUG +#define MEMORY_DEBUG_STR " +MEMORY_DEBUG" +#else +#define MEMORY_DEBUG_STR "" +#endif + +#define DISABLE_KRAIT_IDLE_PS_VAL 200 +#ifdef IPA_UC_OFFLOAD +/* If IPA UC data path is enabled, target should reserve extra tx descriptors + * for IPA WDI data path. + * Then host data path should allow less TX packet pumping in case + * IPA WDI data path enabled */ +#define WLAN_TFC_IPAUC_TX_DESC_RESERVE 100 +#endif /* IPA_UC_OFFLOAD */ + +/* the Android framework expects this param even though we don't use it */ +#define BUF_LEN 20 +static char fwpath_buffer[BUF_LEN]; +static struct kparam_string fwpath = { + .string = fwpath_buffer, + .maxlen = BUF_LEN, +}; + +static char *country_code; +static int enable_11d = -1; +static int enable_dfs_chan_scan = -1; + +#ifndef MODULE +static int wlan_hdd_inited; +#endif + +/* + * spinlock for synchronizing asynchronous request/response + * (full description of use in wlan_hdd_main.h) + */ +DEFINE_SPINLOCK(hdd_context_lock); + +/* + * The rate at which the driver sends RESTART event to supplicant + * once the function 'vos_wlanRestart()' is called + * + */ +#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */ +#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */ + +/* + * Size of Driver command strings from upper layer + */ +#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */ +#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */ + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define TID_MIN_VALUE 0 +#define TID_MAX_VALUE 15 +static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, + const tANI_U8 tid, + tAniTrafStrmMetrics* pTsmMetrics); +static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue, + tCsrEseBeaconReq *pEseBcnReq); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +/* + * Maximum buffer size used for returning the data back to user space + */ +#define WLAN_MAX_BUF_SIZE 1024 +#define WLAN_PRIV_DATA_MAX_LEN 8192 +/* + * Driver miracast parameters 0-Disabled + * 1-Source, 2-Sink + */ +#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0 +#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2 + +/* + * When ever we need to print IBSSPEERINFOALL for more than 16 STA + * we will split the printing. + */ +#define NUM_OF_STA_DATA_TO_PRINT 16 + +/* + * Android DRIVER command structures + */ +struct android_wifi_reassoc_params { + unsigned char bssid[18]; + int channel; +}; + +#define ANDROID_WIFI_ACTION_FRAME_SIZE 1040 +struct android_wifi_af_params { + unsigned char bssid[18]; + int channel; + int dwell_time; + int len; + unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE]; +} ; + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +#define WLAN_HDD_MAX_TCP_PORT 65535 +#define WLAN_WAIT_TIME_READY_TO_EXTWOW 2000 +#endif + +static vos_wake_lock_t wlan_wake_lock; +/* set when SSR is needed after unload */ +static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED; + +//internal function declaration +static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx); +static void wlan_hdd_restart_init(hdd_context_t *pHddCtx); +static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx); + +void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback); +void hdd_set_wlan_suspend_mode(bool suspend); + +v_U16_t hdd_select_queue(struct net_device *dev, + struct sk_buff *skb); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +static void hdd_set_multicast_list(struct net_device *dev); +#endif + +void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand); +static int hdd_parse_channellist(const tANI_U8 *pValue, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels); +static int hdd_parse_send_action_frame_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, + tANI_U8 *pChannel, + tANI_U8 *pDwellTime, + tANI_U8 **pBuf, + tANI_U8 *pBufLen); +static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, + tANI_U8 *pChannel); +#endif + +struct completion wlan_start_comp; +#ifdef QCA_WIFI_FTM +extern int hdd_ftm_start(hdd_context_t *pHddCtx); +extern int hdd_ftm_stop(hdd_context_t *pHddCtx); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +v_VOID_t wlan_hdd_auto_shutdown_cb(v_VOID_t); +#endif + +/* Store WLAN driver version info in a global variable such that crash debugger + can extract it from driver debug symbol and crashdump for post processing */ +tANI_U8 g_wlan_driver_version[ ] = QWLAN_VERSIONSTR; + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, + tANI_U8 **pCckmIe, + tANI_U8 *pCckmIeLen); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#ifdef FEATURE_GREEN_AP + +static void hdd_wlan_green_ap_timer_fn(void *phddctx) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)phddctx; + hdd_green_ap_ctx_t *green_ap; + + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return; + } + green_ap = pHddCtx->green_ap_ctx; + + if (green_ap) + hdd_wlan_green_ap_mc(pHddCtx, green_ap->ps_event); +} + +static VOS_STATUS hdd_wlan_green_ap_attach(hdd_context_t *pHddCtx) +{ + hdd_green_ap_ctx_t *green_ap; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + green_ap = vos_mem_malloc(sizeof(hdd_green_ap_ctx_t)); + + if (!green_ap) { + hddLog(LOGP, FL("Memory allocation for Green-AP failed!")); + status = VOS_STATUS_E_NOMEM; + goto error; + } + + vos_mem_zero((void *)green_ap, sizeof(*green_ap)); + green_ap->pHddContext = pHddCtx; + pHddCtx->green_ap_ctx = green_ap; + + green_ap->ps_state = GREEN_AP_PS_OFF_STATE; + green_ap->ps_event = 0; + green_ap->num_nodes = 0; + green_ap->ps_on_time = GREEN_AP_PS_ON_TIME; + green_ap->ps_delay_time = GREEN_AP_PS_DELAY_TIME; + + vos_timer_init(&green_ap->ps_timer, + VOS_TIMER_TYPE_SW, + hdd_wlan_green_ap_timer_fn, + (void *)pHddCtx); + +error: + + EXIT(); + return status; +} + +static VOS_STATUS hdd_wlan_green_ap_deattach(hdd_context_t *pHddCtx) +{ + hdd_green_ap_ctx_t *green_ap = pHddCtx->green_ap_ctx; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if (green_ap == NULL) { + hddLog(LOG1, FL("Green-AP is not enabled")); + status = VOS_STATUS_E_NOSUPPORT; + goto done; + } + + /* check if the timer status is destroyed */ + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&green_ap->ps_timer)) + { + vos_timer_stop(&green_ap->ps_timer); + } + + /* Destroy the Green AP timer */ + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &green_ap->ps_timer))) + { + hddLog(LOG1, FL("Cannot deallocate Green-AP's timer")); + } + + /* release memory */ + vos_mem_zero((void *)green_ap, sizeof(*green_ap)); + vos_mem_free(green_ap); + pHddCtx->green_ap_ctx = NULL; + +done: + + EXIT(); + return status; +} + +static void hdd_wlan_green_ap_update(hdd_context_t *pHddCtx, + hdd_green_ap_ps_state_t state, + hdd_green_ap_event_t event) +{ + hdd_green_ap_ctx_t *green_ap = pHddCtx->green_ap_ctx; + + green_ap->ps_state = state; + green_ap->ps_event = event; +} + +int hdd_wlan_green_ap_enable(hdd_adapter_t *pHostapdAdapter, + v_U8_t enable) +{ + int ret = 0; + + hddLog(LOG1, "%s: Set Green-AP val: %d", __func__, enable); + + ret = process_wma_set_command( + (int)pHostapdAdapter->sessionId, + (int)WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, + enable, + DBG_CMD); + + return ret; +} + + +boolean hdd_wlan_green_ap_is_ps_on(hdd_context_t *pHddCtx) +{ + hdd_green_ap_ctx_t *green_ap = pHddCtx->green_ap_ctx; + + if (green_ap == NULL) + return FALSE; + + return ((green_ap->ps_state == GREEN_AP_PS_ON_STATE) + && (green_ap->ps_enable)); +} + + +void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx, + hdd_green_ap_event_t event) +{ + hdd_green_ap_ctx_t *green_ap = pHddCtx->green_ap_ctx; + hdd_adapter_t *pAdapter = NULL; + + if (green_ap == NULL) + return ; + + hddLog(LOG1, "%s: Green-AP event: %d, state: %d, num_nodes: %d", + __func__, event, green_ap->ps_state, green_ap->num_nodes); + + /* handle the green ap ps event */ + switch(event) { + case GREEN_AP_PS_START_EVENT: + green_ap->ps_enable = 1; + break; + + case GREEN_AP_PS_STOP_EVENT: + green_ap->ps_enable = 0; + break; + + case GREEN_AP_ADD_STA_EVENT: + green_ap->num_nodes++; + break; + + case GREEN_AP_DEL_STA_EVENT: + if (green_ap->num_nodes) + green_ap->num_nodes--; + break; + + case GREEN_AP_PS_ON_EVENT: + case GREEN_AP_PS_WAIT_EVENT: + break; + + default: + hddLog(LOGE, "%s: invalid event %d", __func__, event); + break; + } + + /* Confirm that power save is enabled before doing state transitions */ + if (!green_ap->ps_enable) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Green-AP is disabled")); + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_IDLE_STATE, GREEN_AP_PS_WAIT_EVENT); + goto done; + } + + pAdapter = hdd_get_adapter (pHddCtx, WLAN_HDD_SOFTAP ); + + if (pAdapter == NULL) { + hddLog(LOGE, FL("Green-AP no SAP adapter")); + goto done; + } + + /* handle the green ap ps state */ + switch(green_ap->ps_state) { + case GREEN_AP_PS_IDLE_STATE: + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_OFF_STATE, GREEN_AP_PS_WAIT_EVENT); + break; + + case GREEN_AP_PS_OFF_STATE: + if (!green_ap->num_nodes) { + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_WAIT_STATE, GREEN_AP_PS_WAIT_EVENT); + vos_timer_start(&green_ap->ps_timer, + green_ap->ps_delay_time); + } + break; + + case GREEN_AP_PS_WAIT_STATE: + if (!green_ap->num_nodes) { + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_ON_STATE, GREEN_AP_PS_WAIT_EVENT); + + hdd_wlan_green_ap_enable(pAdapter, 1); + + if (green_ap->ps_on_time) { + hdd_wlan_green_ap_update(pHddCtx, + 0, GREEN_AP_PS_WAIT_EVENT); + vos_timer_start(&green_ap->ps_timer, + green_ap->ps_on_time); + } + } else { + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_OFF_STATE, GREEN_AP_PS_WAIT_EVENT); + } + break; + + case GREEN_AP_PS_ON_STATE: + if (green_ap->num_nodes) { + if (hdd_wlan_green_ap_enable(pAdapter, 0)) { + hddLog(LOGE, FL("FAILED TO SET GREEN-AP mode")); + goto done; + } + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_OFF_STATE, GREEN_AP_PS_WAIT_EVENT); + } else if ((green_ap->ps_event = GREEN_AP_PS_WAIT_EVENT) && + (green_ap->ps_on_time)) { + + /* ps_on_time timeout, switch to ps off */ + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_WAIT_STATE, GREEN_AP_PS_ON_EVENT); + + if (hdd_wlan_green_ap_enable(pAdapter, 0)) { + hddLog(LOGE, FL("FAILED TO SET GREEN-AP mode")); + goto done; + } + + vos_timer_start(&green_ap->ps_timer, + green_ap->ps_delay_time); + } + break; + + default: + hddLog(LOGE, "%s: invalid state %d", __func__, green_ap->ps_state); + hdd_wlan_green_ap_update(pHddCtx, + GREEN_AP_PS_OFF_STATE, GREEN_AP_PS_WAIT_EVENT); + break; + } + +done: + return; +} + +#endif /* FEATURE_GREEN_AP */ + +#if defined (FEATURE_WLAN_MCC_TO_SCC_SWITCH) || defined (FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_restart_sap() - This function is used to restart SAP in + driver internally + + \param - ap_adapter - Pointer to SAP hdd_adapter_t structure + + \return - void + + --------------------------------------------------------------------------*/ + +static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter) +{ + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t *pHostapdState; + VOS_STATUS vos_status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter); + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + + mutex_lock(&pHddCtx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) { + wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev, + NULL); + hdd_cleanup_actionframe(pHddCtx, ap_adapter); + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); + if ( VOS_STATUS_SUCCESS == WLANSAP_StopBss( +#ifdef WLAN_FEATURE_MBSSID + pHddApCtx->sapContext +#else + (WLAN_HDD_GET_CTX(ap_adapter))->pvosContext +#endif + )) { + vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + goto end; + } + } + clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode); + hddLog(LOGE, FL("SAP Stop Success")); + + if (WLANSAP_StartBss( +#ifdef WLAN_FEATURE_MBSSID + pHddApCtx->sapContext, +#else + pHddCtx->pvosContext, +#endif + hdd_hostapd_SAPEventCB, &pHddApCtx->sapConfig, + (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) { + hddLog(LOGE, FL("SAP Start Bss fail")); + goto end; + } + + hddLog(LOG1, FL("Waiting for SAP to start")); + vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("SAP Start failed")); + goto end; + } + hddLog(LOGE, FL("SAP Start Success")); + set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); + wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode); + pHostapdState->bCommit = TRUE; + } +end: + mutex_unlock(&pHddCtx->sap_lock); + return; +} +#endif + +static int hdd_netdev_notifier_call(struct notifier_block * nb, + unsigned long state, + void *data) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) + struct netdev_notifier_info *dev_notif_info = data; + struct net_device *dev = dev_notif_info->dev; +#else + struct net_device *dev = data; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; +#ifdef WLAN_BTAMP_FEATURE + VOS_STATUS status; +#endif + //Make sure that this callback corresponds to our device. + if ((strncmp(dev->name, "wlan", 4)) && + (strncmp(dev->name, "p2p", 3))) + return NOTIFY_DONE; + + if ((pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC) && + (pAdapter->dev != dev)) { + hddLog(LOGE, FL("device adapter is not matching!!!")); + return NOTIFY_DONE; + } + + if (!dev->ieee80211_ptr) { + hddLog(LOGE, FL("ieee80211_ptr is NULL!!!")); + return NOTIFY_DONE; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__); + VOS_ASSERT(0); + return NOTIFY_DONE; + } + if (pHddCtx->isLogpInProgress) + return NOTIFY_DONE; + + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu", + __func__, dev->name, state); + + switch (state) { + case NETDEV_REGISTER: + break; + + case NETDEV_UNREGISTER: + break; + + case NETDEV_UP: + sme_ChAvoidUpdateReq(pHddCtx->hHal); + break; + + case NETDEV_DOWN: + break; + + case NETDEV_CHANGE: + if(TRUE == pAdapter->isLinkUpSvcNeeded) + complete(&pAdapter->linkup_event_var); + break; + + case NETDEV_GOING_DOWN: + if( pAdapter->scan_info.mScanPending != FALSE ) + { + unsigned long rc; + INIT_COMPLETION(pAdapter->scan_info.abortscan_event_var); + hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + rc = wait_for_completion_timeout( + &pAdapter->scan_info.abortscan_event_var, + msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN)); + if (!rc) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for abortscan", + __func__); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Scan is not Pending from user" , __func__); + } +#ifdef WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__); + status = WLANBAP_StopAmp(); + if(VOS_STATUS_SUCCESS != status ) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop AMP", __func__); + } + else + { + //a state m/c implementation in PAL is TBD to avoid this delay + msleep(500); + if ( pHddCtx->isAmpAllowed ) + { + WLANBAP_DeregisterFromHCI(); + pHddCtx->isAmpAllowed = VOS_FALSE; + } + } +#endif //WLAN_BTAMP_FEATURE + break; + + default: + break; + } + + return NOTIFY_DONE; +} + +struct notifier_block hdd_netdev_notifier = { + .notifier_call = hdd_netdev_notifier_call, +}; + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ +void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx); +void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx); +//variable to hold the insmod parameters +static int con_mode; +#ifndef MODULE +/* current con_mode - used only for statically linked driver + * con_mode is changed by user space to indicate a mode change which will + * result in calling the module exit and init functions. The module + * exit function will clean up based on the value of con_mode prior to it + * being changed by user space. So curr_con_mode records the current con_mode + * for exit when con_mode becomes the next mode for init + */ +static int curr_con_mode; +#endif + +/**--------------------------------------------------------------------------- + + \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable + + Called immediately after the cfg.ini is read in order to configure + the desired trace levels. + + \param - moduleId - module whose trace level is being configured + \param - bitmask - bitmask of log levels to be enabled + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask) +{ + VOS_TRACE_LEVEL level; + + /* if the bitmask is the default value, then a bitmask was not + specified in cfg.ini, so leave the logging level alone (it + will remain at the "compiled in" default value) */ + if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask) + { + return; + } + + /* a mask was specified. start by disabling all logging */ + vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0); + + /* now cycle through the bitmask until all "set" bits are serviced */ + level = VOS_TRACE_LEVEL_FATAL; + while (0 != bitmask) + { + if (bitmask & 1) + { + vos_trace_setValue(moduleId, level, 1); + } + level++; + bitmask >>= 1; + } +} + + +/* + * FUNCTION: wlan_hdd_validate_context + * This function is used to check the HDD context + */ +int wlan_hdd_validate_context(hdd_context_t *pHddCtx) +{ + ENTER(); + + if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini) { + hddLog(LOGE, FL("HDD context is Null")); + return -ENODEV; + } + + if (pHddCtx->isLogpInProgress) { + hddLog(LOGE, FL("LOGP in Progress. Ignore!!!")); + return -EAGAIN; + } + + if ((pHddCtx->isLoadInProgress) || + (pHddCtx->isUnloadInProgress)) { + hddLog(LOGE, FL("Unloading/Loading in Progress. Ignore!!!")); + return -EAGAIN; + } + return 0; +} + + +void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + eCsrPhyMode phyMode; + hdd_config_t *cfg_param = NULL; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD Context is null !!"); + return ; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "pAdapter is null !!"); + return ; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + cfg_param = pHddCtx->cfg_ini; + if (NULL == cfg_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "cfg_params not available !!"); + return ; + } + + phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter)); + + if (!pHddCtx->isVHT80Allowed) + { + if ((eCSR_DOT11_MODE_AUTO == phyMode) || + (eCSR_DOT11_MODE_11ac == phyMode) || + (eCSR_DOT11_MODE_11ac_ONLY == phyMode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Setting phymode to 11n!!"); + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n); + } + } + else + { + /*New country Supports 11ac as well resetting value back from .ini*/ + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), + hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode)); + return ; + } + + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) || + (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode))) + { + VOS_STATUS vosStatus; + + // need to issue a disconnect to CSR. + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED ); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + unsigned long rc; + + rc = wait_for_completion_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) + hddLog(LOGE, FL("failure waiting for disconnect_comp_var")); + } + } +} + + +void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD Context is null !!"); + return ; + } + + cfg_param = pHddCtx->cfg_ini; + + if (NULL == cfg_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "cfg_params not available !!"); + return ; + } + + if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code)) + { + /*New country doesn't support DFS */ + sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0); + } + else + { + /*New country Supports DFS as well resetting value back from .ini*/ + sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan); + } + +} + +/**--------------------------------------------------------------------------- + + \brief hdd_setIbssPowerSaveParams - update IBSS Power Save params to WMA. + + This function sets the IBSS power save config parameters to WMA + which will send it to firmware if FW supports IBSS power save + before vdev start. + + \param - hdd_adapter_t Hdd adapter. + + \return - VOS_STATUS VOS_STATUS_SUCCESS on Success and VOS_STATUS_E_FAILURE + on failure. + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_setIbssPowerSaveParams(hdd_adapter_t *pAdapter) +{ + int ret; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + + if (pHddCtx == NULL) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE, + pHddCtx->cfg_ini->ibssATIMWinSize, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED, + pHddCtx->cfg_ini->isIbssPowerSaveAllowed, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED, + pHddCtx->cfg_ini->isIbssPowerCollapseAllowed, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX, + pHddCtx->cfg_ini->isIbssAwakeOnTxRx, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_INACTIVITY_TIME, + pHddCtx->cfg_ini->ibssInactivityCount, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_INACTIVITY_TIME failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME, + pHddCtx->cfg_ini->ibssTxSpEndInactivityTime, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS, + pHddCtx->cfg_ini->ibssPsWarmupTime, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = process_wma_set_command(pAdapter->sessionId, + WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW, + pHddCtx->cfg_ini->ibssPs1RxChainInAtimEnable, + VDEV_CMD); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW failed %d"), + ret); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/**--------------------------------------------------------------------------- + + \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from + input string + + This function extracts assigned integer from string in below format: + "STRING=10" : extracts integer 10 from this string + + \param - pInPtr Pointer to input string + \param - base Base for string to int conversion(10 for decimal 16 for hex) + \param - pOutPtr Pointer to variable in which extracted integer needs to be + assigned + \param - pLastArg to tell whether it is last argument in input string or + not + + \return - NULL for failure cases + pointer to next argument in input string for success cases + --------------------------------------------------------------------------*/ +static tANI_U8 * +hdd_extract_assigned_int_from_str +( + tANI_U8 *pInPtr, + tANI_U8 base, + tANI_U32 *pOutPtr, + tANI_U8 *pLastArg +) +{ + int tempInt; + int v = 0; + char buf[32]; + int val = 0; + *pLastArg = FALSE; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE); + if (NULL == pInPtr) + { + return NULL; + } + + pInPtr++; + + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + val = sscanf(pInPtr, "%32s ", buf); + if (val < 0 && val > strlen(pInPtr)) + { + return NULL; + } + pInPtr += val; + v = kstrtos32(buf, base, &tempInt); + if (v < 0) + { + return NULL; + } + if (tempInt < 0) + { + tempInt = 0; + } + *pOutPtr = tempInt; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE); + if (NULL == pInPtr) + { + *pLastArg = TRUE; + return NULL; + } + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + return pInPtr; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from + input string + + This function extracts assigned character from string in below format: + "STRING=A" : extracts char 'A' from this string + + \param - pInPtr Pointer to input string + \param - pOutPtr Pointer to variable in which extracted char needs to be + assigned + \param - pLastArg to tell whether it is last argument in input string or + not + + \return - NULL for failure cases + pointer to next argument in input string for success cases + --------------------------------------------------------------------------*/ +static tANI_U8 * +hdd_extract_assigned_char_from_str +( + tANI_U8 *pInPtr, + tANI_U8 *pOutPtr, + tANI_U8 *pLastArg +) +{ + *pLastArg = FALSE; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE); + if (NULL == pInPtr) + { + return NULL; + } + + pInPtr++; + + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + *pOutPtr = *pInPtr; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE); + if (NULL == pInPtr) + { + *pLastArg = TRUE; + return NULL; + } + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + return pInPtr; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command + + This function parses set batch scan command in below format: + WLS_BATCHING_SET followed by below arguments + "SCANFREQ=XX" : Optional defaults to 30 sec + "MSCAN=XX" : Required number of scans to attempt to batch + "BESTN=XX" : Best Network (RSSI) defaults to 16 + "CHANNEL=" : optional defaults to all channels, can list 'A'or` B. + A. implies only 5 GHz , B. implies only 2.4GHz + "RTT=X" : optional defaults to 0 + returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on + error + + For example input commands: + 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is + translated into set batch scan with following parameters: + a) Frequency 60 seconds + b) Batch 10 scans together + c) Best RSSI to be 20 + d) 5GHz band only + e) RTT is equal to 0 + + \param - pValue Pointer to input channel list + \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_set_batchscan_command +( + tANI_U8 *pValue, + tSirSetBatchScanReq *pHddSetBatchScanReq +) +{ + tANI_U8 *inPtr = pValue; + tANI_U8 val = 0; + tANI_U8 lastArg = 0; + tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ; + tANI_U32 nMscan; + tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK; + tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND; + tANI_U32 nRtt = 0; + tANI_U32 temp; + + /*go to space after WLS_BATCHING_SET command*/ + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*check and parse SCANFREQ*/ + if ((strncmp(inPtr, "SCANFREQ", 8) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &temp, &lastArg); + + if (0 != temp) + { + nScanFreq = temp; + } + + if ( (NULL == inPtr) || (TRUE == lastArg)) + { + return -EINVAL; + } + } + + /*check and parse MSCAN*/ + if ((strncmp(inPtr, "MSCAN", 5) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &nMscan, &lastArg); + + if (0 == nMscan) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "invalid MSCAN=%d", nMscan); + return -EINVAL; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + else + { + return -EINVAL; + } + + /*check and parse BESTN*/ + if ((strncmp(inPtr, "BESTN", 5) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &temp, &lastArg); + + if (0 != temp) + { + nBestN = temp; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + + /*check and parse CHANNEL*/ + if ((strncmp(inPtr, "CHANNEL", 7) == 0)) + { + inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg); + + if (('A' == val) || ('a' == val)) + { + ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY; + } + else if (('B' == val) || ('b' == val)) + { + ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY; + } + else + { + ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + + /*check and parse RTT*/ + if ((strncmp(inPtr, "RTT", 3) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &nRtt, &lastArg); + if (TRUE == lastArg) + { + goto done; + } + if (NULL == inPtr) + { + return -EINVAL; + } + } + + +done: + + pHddSetBatchScanReq->scanFrequency = nScanFreq; + pHddSetBatchScanReq->numberOfScansToBatch = nMscan; + pHddSetBatchScanReq->bestNetwork = nBestN; + pHddSetBatchScanReq->rfBand = ucRfBand; + pHddSetBatchScanReq->rtt = nRtt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received WLS_BATCHING_SET with SCANFREQ=%d " + "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d", + pHddSetBatchScanReq->scanFrequency, + pHddSetBatchScanReq->numberOfScansToBatch, + pHddSetBatchScanReq->bestNetwork, + pHddSetBatchScanReq->rfBand, + pHddSetBatchScanReq->rtt); + + return 0; +}/*End of hdd_parse_set_batchscan_command*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_set_batch_scan_req_callback () - This function is called after + receiving set batch scan response from FW and it saves set batch scan + response data FW to HDD context and sets the completion event on + which hdd_ioctl is waiting + + \param - callbackContext Pointer to HDD adapter + \param - pRsp Pointer to set batch scan response data received from FW + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_set_batch_scan_req_callback +( + void *callbackContext, + tSirSetBatchScanRsp *pRsp +) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + tSirSetBatchScanRsp *pHddSetBatchScanRsp; + + /*sanity check*/ + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + VOS_ASSERT(0); + return; + } + pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp; + + /*save set batch scan response*/ + pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Received set batch scan rsp from FW with nScansToBatch=%d", + pHddSetBatchScanRsp->nScansToBatch); + + pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE; + complete(&pAdapter->hdd_set_batch_scan_req_var); + + return; +}/*End of hdd_set_batch_scan_req_callback*/ + + +/**--------------------------------------------------------------------------- + + \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta + info in hdd batch scan response queue + + \param - pAdapter Pointer to hdd adapter + \param - pAPMetaInfo Pointer to access point meta info + \param - scanId scan ID of batch scan response + \param - isLastAp tells whether AP is last AP in batch scan response or not + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter, + tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp) +{ + tHddBatchScanRsp *pHead; + tHddBatchScanRsp *pNode; + tHddBatchScanRsp *pPrev; + tHddBatchScanRsp *pTemp; + tANI_U8 ssidLen; + + /*head of hdd batch scan response queue*/ + pHead = pAdapter->pBatchScanRsp; + + pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp)); + if (NULL == pNode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Could not allocate memory", __func__); + VOS_ASSERT(0); + return; + } + + vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid, + sizeof(pNode->ApInfo.bssid)); + ssidLen = strlen(pApMetaInfo->ssid); + if (SIR_MAX_SSID_SIZE < ssidLen) + { + /*invalid scan result*/ + vos_mem_free(pNode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen); + return; + } + vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen); + /*null terminate ssid*/ + pNode->ApInfo.ssid[ssidLen] = '\0'; + pNode->ApInfo.ch = pApMetaInfo->ch; + pNode->ApInfo.rssi = pApMetaInfo->rssi; + pNode->ApInfo.age = pApMetaInfo->timestamp; + pNode->ApInfo.batchId = scanId; + pNode->ApInfo.isLastAp = isLastAp; + + pNode->pNext = NULL; + if (NULL == pHead) + { + pAdapter->pBatchScanRsp = pNode; + } + else + { + pTemp = pHead; + while (NULL != pTemp) + { + pPrev = pTemp; + pTemp = pTemp->pNext; + } + pPrev->pNext = pNode; + } + + return; +}/*End of hdd_populate_batch_scan_rsp_queue*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_batch_scan_result_ind_callback () - This function is called after + receiving batch scan response indication from FW. It saves get batch scan + response data in HDD batch scan response queue. This callback sets the + completion event on which hdd_ioctl is waiting only after getting complete + batch scan response data from FW + + \param - callbackContext Pointer to HDD adapter + \param - pRsp Pointer to get batch scan response data received from FW + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_batch_scan_result_ind_callback +( + void *callbackContext, + void *pRsp +) +{ + v_BOOL_t isLastAp; + tANI_U32 numApMetaInfo; + tANI_U32 numNetworkInScanList; + tANI_U32 numberScanList; + tANI_U32 nextScanListOffset; + tANI_U32 nextApMetaInfoOffset; + hdd_adapter_t* pAdapter; + tpSirBatchScanList pScanList; + tpSirBatchScanNetworkInfo pApMetaInfo; + tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/ + tSirSetBatchScanReq *pReq; + + pAdapter = (hdd_adapter_t *)callbackContext; + /*sanity check*/ + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + VOS_ASSERT(0); + return; + } + + /*initialize locals*/ + pReq = &pAdapter->hddSetBatchScanReq; + pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp; + isLastAp = FALSE; + numApMetaInfo = 0; + numNetworkInScanList = 0; + numberScanList = 0; + nextScanListOffset = 0; + nextApMetaInfoOffset = 0; + pScanList = NULL; + pApMetaInfo = NULL; + + if ((NULL == pBatchScanRsp) || (NULL == pReq)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq); + isLastAp = TRUE; + pAdapter->numScanList = 0; + goto done; + } + + pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan rsp: numberScalList %d", numberScanList); + + if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: numberScanList %d", __func__, numberScanList); + isLastAp = TRUE; + goto done; + } + + while (numberScanList) + { + pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults + + nextScanListOffset); + if (NULL == pScanList) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pScanList is %p", __func__, pScanList); + isLastAp = TRUE; + goto done; + } + numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan rsp: numApMetaInfo %d scanId %d", + numApMetaInfo, pScanList->scanId); + + if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: numApMetaInfo %d", __func__, numApMetaInfo); + isLastAp = TRUE; + goto done; + } + + /*Initialize next AP meta info offset for next scan list*/ + nextApMetaInfoOffset = 0; + + while (numApMetaInfo) + { + pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList + + nextApMetaInfoOffset); + if (NULL == pApMetaInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pApMetaInfo is %p", __func__, pApMetaInfo); + isLastAp = TRUE; + goto done; + } + /*calculate AP age*/ + pApMetaInfo->timestamp = + pBatchScanRsp->timestamp - pApMetaInfo->timestamp; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: bssId "MAC_ADDRESS_STR + " ch %d rssi %d timestamp %d", __func__, + MAC_ADDR_ARRAY(pApMetaInfo->bssid), + pApMetaInfo->ch, pApMetaInfo->rssi, + pApMetaInfo->timestamp); + + /*mark last AP in batch scan response*/ + if ((TRUE == pBatchScanRsp->isLastResult) && + (1 == numberScanList) && (1 == numApMetaInfo)) + { + isLastAp = TRUE; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + /*store batch scan response in hdd queue*/ + hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo, + pScanList->scanId, isLastAp); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo); + numApMetaInfo--; + } + + nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8)) + + (sizeof(tSirBatchScanNetworkInfo) + * numNetworkInScanList)); + numberScanList--; + } + +done: + + /*notify hdd_ioctl only if complete batch scan rsp is received and it was + requested from hdd_ioctl*/ + if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) && + (TRUE == isLastAp)) + { + pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE; + complete(&pAdapter->hdd_get_batch_scan_req_var); + } + + return; +}/*End of hdd_batch_scan_result_ind_callback*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_format_batch_scan_rsp () - This function formats batch scan + response as per batch scan FR request format by putting proper markers + + \param - pDest pointer to destination buffer + \param - cur_len current length + \param - tot_len total remaining size which can be written to user space + \param - pApMetaInfo Pointer to get batch scan response AP meta info + \param - pAdapter Pointer to HDD adapter + + \return - ret no of characters written + + --------------------------------------------------------------------------*/ +static tANI_U32 +hdd_format_batch_scan_rsp +( + tANI_U8 *pDest, + tANI_U32 cur_len, + tANI_U32 tot_len, + tHddBatchScanRsp *pApMetaInfo, + hdd_adapter_t* pAdapter +) +{ + tANI_U32 ret = 0; + tANI_U32 rem_len = 0; + tANI_U8 temp_len = 0; + tANI_U8 temp_total_len = 0; + tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE]; + tANI_U8 *pTemp = temp; + + /* + * Batch scan response needs to be returned to user space in + * following format: + * "scancount=X\n" where X is the number of scans in current batch + * batch + * "trunc\n" optional present if current scan truncated + * "bssid=XX:XX:XX:XX:XX:XX\n" + * "ssid=XXXX\n" + * "freq=X\n" frequency in Mhz + * "level=XX\n" + * "age=X\n" ms + * "dist=X\n" cm (-1 if not available) + * "errror=X\n" (-1if not available) + * "====\n" (end of ap marker) + * "####\n" (end of scan marker) + * "----\n" (end of results) + * + * Send scan result in above format to user space based on + * available length. + */ + + /* + * The GET response may have more data than the driver can return in its + * buffer. In that case the buffer should be filled to the nearest complete + * scan, ending with "%%%%".Subsequent calls should return the remaining + * data starting with the next scan (optional .trunc\n., .apcount=X\n., etc) + * The final buffer should end with "----\n" + */ + + /*sanity*/ + if (cur_len > tot_len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len); + return 0; + } + else + { + rem_len = (tot_len - cur_len); + } + + /*end scan marker*/ + if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id) + { + temp_len = snprintf(pTemp, sizeof(temp), "####\n"); + pTemp += temp_len; + temp_total_len += temp_len; + } + + /*bssid*/ + temp_len = snprintf(pTemp, sizeof(temp), + "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", + pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1], + pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3], + pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]); + pTemp += temp_len; + temp_total_len += temp_len; + + /*ssid*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n", + pApMetaInfo->ApInfo.ssid); + pTemp += temp_len; + temp_total_len += temp_len; + + /*freq*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n", + sme_ChnToFreq(pApMetaInfo->ApInfo.ch)); + pTemp += temp_len; + temp_total_len += temp_len; + + /*level*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n", + pApMetaInfo->ApInfo.rssi); + pTemp += temp_len; + temp_total_len += temp_len; + + /*age*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n", + pApMetaInfo->ApInfo.age); + pTemp += temp_len; + temp_total_len += temp_len; + + /*dist*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*error*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*end AP marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*last AP in batch scan response*/ + if(TRUE == pApMetaInfo->ApInfo.isLastAp) + { + /*end scan marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*end batch scan result marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + } + + if (temp_total_len < rem_len) + { + ret = temp_total_len + 1; + strlcpy(pDest, temp, ret); + pAdapter->isTruncated = FALSE; + } + else + { + pAdapter->isTruncated = TRUE; + if (rem_len >= strlen("%%%%")) + { + ret = snprintf(pDest, sizeof(temp), "%%%%"); + } + else + { + ret = 0; + } + } + + return ret; + +}/*End of hdd_format_batch_scan_rsp*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_populate_user_batch_scan_rsp() - This function populates user data + buffer starting with head of hdd batch scan response queue + + \param - pAdapter Pointer to HDD adapter + \param - pDest Pointer to user data buffer + \param - cur_len current offset in user buffer + \param - rem_len remaining no of bytes in user buffer + + \return - number of bytes written in user buffer + + --------------------------------------------------------------------------*/ + +tANI_U32 hdd_populate_user_batch_scan_rsp +( + hdd_adapter_t* pAdapter, + tANI_U8 *pDest, + tANI_U32 cur_len, + tANI_U32 rem_len +) +{ + tHddBatchScanRsp *pHead; + tHddBatchScanRsp *pPrev; + tANI_U32 len; + + pAdapter->isTruncated = FALSE; + + /*head of hdd batch scan response queue*/ + pHead = pAdapter->pBatchScanRsp; + while (pHead) + { + len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead, + pAdapter); + pDest += len; + pDest--; + cur_len += len; + if(TRUE == pAdapter->isTruncated) + { + /*result is truncated return rest of scan rsp in next req*/ + cur_len = rem_len; + break; + } + pPrev = pHead; + pHead = pHead->pNext; + pAdapter->pBatchScanRsp = pHead; + if (TRUE == pPrev->ApInfo.isLastAp) + { + pAdapter->prev_batch_id = 0; + } + else + { + pAdapter->prev_batch_id = pPrev->ApInfo.batchId; + } + vos_mem_free(pPrev); + pPrev = NULL; + } + + return cur_len; +}/*End of hdd_populate_user_batch_scan_rsp*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch + scan response data from HDD queue to user space + It does following in detail: + a) if HDD has enough data in its queue then it 1st copies data to user + space and then send get batch scan indication message to FW. In this + case it does not wait on any event and batch scan response data will + be populated in HDD response queue in MC thread context after receiving + indication from FW + b) else send get batch scan indication message to FW and wait on an event + which will be set once HDD receives complete batch scan response from + FW and then this function returns batch scan response to user space + + \param - pAdapter Pointer to HDD adapter + \param - pPrivData Pointer to priv_data + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_return_batch_scan_rsp_to_user +( + hdd_adapter_t* pAdapter, + hdd_priv_data_t *pPrivData, + tANI_U8 *command +) +{ + tANI_U8 *pDest; + tANI_U32 count = 0; + tANI_U32 len = 0; + tANI_U32 cur_len = 0; + tANI_U32 rem_len = 0; + eHalStatus halStatus; + unsigned long rc; + tSirTriggerBatchScanResultInd *pReq; + + pReq = &pAdapter->hddTriggerBatchScanResultInd; + pReq->param = 0;/*batch scan client*/ + pDest = (tANI_U8 *)(command + pPrivData->used_len); + pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE; + + cur_len = pPrivData->used_len; + if (pPrivData->total_len > pPrivData->used_len) + { + rem_len = pPrivData->total_len - pPrivData->used_len; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid user data buffer total_len %d used_len %d", + __func__, pPrivData->total_len, pPrivData->used_len); + return -EFAULT; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest, + cur_len, rem_len); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + /*enough scan result available in cache to return to user space or + scan result needs to be fetched 1st from fw and then return*/ + if (len == cur_len) + { + pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE; + halStatus = sme_TriggerBatchScanResultInd( + WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, + pAdapter->sessionId, hdd_batch_scan_result_ind_callback, + pAdapter); + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) + { + INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var); + rc = wait_for_completion_timeout( + &pAdapter->hdd_get_batch_scan_req_var, + msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT)); + if (!rc) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wait on hdd_get_batch_scan_req_var failed", + __func__); + return -EFAULT; + } + } + + len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE, + "scancount=%u\n", pAdapter->numScanList); + pDest += len; + cur_len += len; + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest, + cur_len, rem_len); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + count = 0; + len = (len - pPrivData->used_len); + pDest = (command + pPrivData->used_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NEW BATCH SCAN RESULT:"); + while(count < len) + { + printk("%c", *(pDest + count)); + count++; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: copy %d data to user buffer", __func__, len); + if (copy_to_user(pPrivData->buf, pDest, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_GetBatchScanScan returned failure halStatus %d", + halStatus); + return -EINVAL; + } + } + else + { + count = 0; + len = (len - pPrivData->used_len); + pDest = (command + pPrivData->used_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "REMAINING TRUNCATED BATCH SCAN RESULT:"); + while(count < len) + { + printk("%c", *(pDest + count)); + count++; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: copy %d data to user buffer", __func__, len); + if (copy_to_user(pPrivData->buf, pDest, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + } + + return 0; +} /*End of hdd_return_batch_scan_rsp_to_user*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +) +{ + int ret = 0; + hdd_context_t *pHddCtx; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid!", __func__); + goto exit; + } + + if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0) + { + char extra[32]; + tANI_U8 len = 0; + tANI_U8 version = HDD_BATCH_SCAN_VERSION; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d", + version); + if (copy_to_user(pPrivdata->buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = HDD_BATCH_SCAN_VERSION; + } + else if (strncmp(command, "WLS_BATCHING SET", 16) == 0) + { + int status; + tANI_U8 *value = (command + 16); + eHalStatus halStatus; + unsigned long rc; + tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq; + tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && + (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) && + (WLAN_HDD_P2P_GO != pAdapter->device_mode) && + (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received WLS_BATCHING SET command in invalid mode %d " + "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_set_batchscan_command(value, pReq); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid WLS_BATCHING SET command"); + ret = -EINVAL; + goto exit; + } + + + pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE; + halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, + pAdapter->sessionId, hdd_set_batch_scan_req_callback, + pAdapter); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + char extra[32]; + tANI_U8 len = 0; + tANI_U8 mScan = 0; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_SetBatchScanReq returned success halStatus %d", + halStatus); + if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp) + { + INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var); + rc = wait_for_completion_timeout( + &pAdapter->hdd_set_batch_scan_req_var, + msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT)); + if (0 == rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout waiting for set batch scan to complete", + __func__); + ret = -EINVAL; + goto exit; + } + } + if ( !pRsp->nScansToBatch ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Received set batch scan failure response from FW", + __func__); + ret = -EINVAL; + goto exit; + } + /*As per the Batch Scan Framework API we should return the MIN of + either MSCAN or the max # of scans firmware can cache*/ + mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: request MSCAN %d response MSCAN %d ret %d", + __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan); + + len = scnprintf(extra, sizeof(extra), "%d", mScan); + if (copy_to_user(pPrivdata->buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy MSCAN value to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_SetBatchScanReq returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0) + { + eHalStatus halStatus; + tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd; + pInd->param = 0; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Batch scan is not yet enabled batch scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + hdd_deinit_batch_scan(pAdapter); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + + halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd, + pAdapter->sessionId); + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + ret = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_StopBatchScanInd returned success halStatus %d", + halStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_StopBatchScanInd returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING GET", 16) == 0) + { + tANI_U32 remain_len; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Batch scan is not yet enabled could not return results " + "Batch Scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + pPrivdata->used_len = 16; + remain_len = pPrivdata->total_len - pPrivdata->used_len; + if (remain_len < pPrivdata->total_len) + { + /*Clear previous batch scan response data if any*/ + vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid total length from user space can't fetch batch" + " scan response total_len %d used_len %d remain len %d", + pPrivdata->total_len, pPrivdata->used_len, remain_len); + ret = -EINVAL; + goto exit; + } + ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command); + } + +exit: + + return ret; +} + +#endif/*End of FEATURE_WLAN_BATCH_SCAN*/ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* + \brief hdd_reassoc() - perform a user space-directed reassoc + + \param - pAdapter - Adapter upon which the command was received + \param - bssid - BSSID with which to reassociate + \param - channel - channel upon which to reassociate + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, const tANI_U8 channel) +{ + hdd_station_ctx_t *pHddStaCtx; + int ret = 0; + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* if not associated, no need to proceed with reassoc */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__); + ret = -EINVAL; + goto exit; + } + + /* if the target bssid is same as currently associated AP, + then no need to proceed with reassoc */ + if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Reassoc BSSID is same as currently associated AP bssid", + __func__); + ret = -EINVAL; + goto exit; + } + + /* Check channel number is a valid channel number */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter, channel)) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Channel %d", + __func__, channel); + ret = -EINVAL; + goto exit; + } + + /* Proceed with reassoc */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + { + tCsrHandoffRequest handoffInfo; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + handoffInfo.channel = channel; + handoffInfo.src = REASSOC; + memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr)); + sme_HandoffRequest(pHddCtx->hHal, pAdapter->sessionId, &handoffInfo); + } +#endif + exit: + return ret; +} + +/* + \brief hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command + + This function parses the v1 REASSOC command with the format + + REASSOC xx:xx:xx:xx:xx:xx CH + + Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the + BSSID and CH is the ASCII representation of the channel. For + example + + REASSOC 00:0a:0b:11:22:33 48 + + \param - pAdapter - Adapter upon which the command was received + \param - command - ASCII text command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command) +{ + tANI_U8 channel = 0; + tSirMacAddr bssid; + int ret; + + ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel); + if (ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse reassoc command data", __func__); + } else { + ret = hdd_reassoc(pAdapter, bssid, channel); + } + return ret; +} + +/* + \brief hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command + + This function parses the v2 REASSOC command with the format + + REASSOC + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received, ASCII command followed + by binary data + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, + const char *command) +{ + struct android_wifi_reassoc_params params; + tSirMacAddr bssid; + int ret; + + /* The params are located after "REASSOC " */ + memcpy(¶ms, command + 8, sizeof(params)); + + if (!mac_pton(params.bssid, (u8 *)&bssid)) { + hddLog(LOGE, "%s: MAC address parsing failed", __func__); + ret = -EINVAL; + } else { + ret = hdd_reassoc(pAdapter, bssid, params.channel); + } + return ret; +} + +/* + \brief hdd_parse_reassoc() - parse the REASSOC command + + There are two different versions of the REASSOC command. Version 1 + of the command contains a parameter list that is ASCII characters + whereas version 2 contains a combination of ASCII and binary + payload. Determine if a version 1 or a version 2 command is being + parsed by examining the parameters, and then dispatch the parser + that is appropriate for the command. + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command) +{ + int ret; + + /* both versions start with "REASSOC " + * v1 has a bssid and channel # as an ASCII string + * REASSOC xx:xx:xx:xx:xx:xx CH + * v2 has a C struct + * REASSOC + * + * The first field in the v2 struct is also the bssid in ASCII. + * But in the case of a v2 message the BSSID is NUL-terminated. + * Hence we can peek at that offset to see if this is V1 or V2 + * REASSOC xx:xx:xx:xx:xx:xx* + * 1111111111222222 + * 01234567890123456789012345 + */ + if (command[25]) { + ret = hdd_parse_reassoc_v1(pAdapter, command); + } else { + ret = hdd_parse_reassoc_v2(pAdapter, command); + } + + return ret; +} +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* + \brief hdd_sendactionframe() - send a user space supplied action frame + + \param - pAdapter - Adapter upon which the command was received + \param - bssid - BSSID target of the action frame + \param - channel - channel upon which to send the frame + \param - dwell_time - amount of time to dwell when the frame is sent + \param - payload_len - length of the payload + \param - payload - payload of the frame + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_sendactionframe(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, + const tANI_U8 channel, const tANI_U8 dwell_time, + const tANI_U8 payload_len, const tANI_U8 *payload) +{ + struct ieee80211_channel chan; + tANI_U8 frame_len; + tANI_U8 *frame; + struct ieee80211_hdr_3addr *hdr; + u64 cookie; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + int ret = 0; + tpSirMacVendorSpecificFrameHdr pVendorSpecific = + (tpSirMacVendorSpecificFrameHdr) payload; + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + /* if not associated, no need to send action frame */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__); + ret = -EINVAL; + goto exit; + } + + /* if the target bssid is different from currently associated AP, + then no need to send action frame */ + if (memcmp(bssid, pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE)) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: STA is not associated to this AP", + __func__); + ret = -EINVAL; + goto exit; + } + + chan.center_freq = sme_ChnToFreq(channel); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* Check if it is specific action frame */ + if (pVendorSpecific->category == SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY) { + static const tANI_U8 Oui[] = { 0x00, 0x00, 0xf0 }; + if (vos_mem_compare(pVendorSpecific->Oui, (void *) Oui, 3)) { + /* if the channel number is different from operating channel then + no need to send action frame */ + if (channel != 0) { + if (channel != pHddStaCtx->conn_info.operationChannel) { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: channel(%d) is different from operating channel(%d)", + __func__, channel, + pHddStaCtx->conn_info.operationChannel); + ret = -EINVAL; + goto exit; + } + /* If channel number is specified and same as home channel, + * ensure that action frame is sent immediately by cancelling + * roaming scans. Otherwise large dwell times may cause long + * delays in sending action frames. + */ + sme_abortRoamScan(pHddCtx->hHal, pAdapter->sessionId); + } else { + /* 0 is accepted as current home channel, delayed + * transmission of action frame is ok. + */ + chan.center_freq = + sme_ChnToFreq(pHddStaCtx->conn_info.operationChannel); + } + } + } +#endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (chan.center_freq == 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:invalid channel number %d", + __func__, channel); + ret = -EINVAL; + goto exit; + } + + frame_len = payload_len + 24; + frame = vos_mem_malloc(frame_len); + if (!frame) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed", __func__); + ret = -ENOMEM; + goto exit; + } + vos_mem_zero(frame, frame_len); + + hdr = (struct ieee80211_hdr_3addr *)frame; + hdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); + vos_mem_copy(hdr->addr1, bssid, VOS_MAC_ADDR_SIZE); + vos_mem_copy(hdr->addr2, pAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(hdr->addr3, bssid, VOS_MAC_ADDR_SIZE); + vos_mem_copy(hdr + 1, payload, payload_len); + + ret = wlan_hdd_mgmt_tx(NULL, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + &(pAdapter->wdev), +#else + pAdapter->dev, +#endif + &chan, 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + NL80211_CHAN_HT20, 1, +#endif + dwell_time, frame, frame_len, 1, 1, &cookie ); + vos_mem_free(frame); + exit: + return ret; +} + +/* + \brief hdd_parse_sendactionframe_v1() - parse version 1 of the + SENDACTIONFRAME command + + This function parses the v1 SENDACTIONFRAME command with the format + + SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DW xxxxxx + + Where "xx:xx:xx:xx:xx:xx" is the Hex-ASCII representation of the + BSSID, CH is the ASCII representation of the channel, DW is the + ASCII representation of the dwell time, and xxxxxx is the Hex-ASCII + payload. For example + + SENDACTIONFRAME 00:0a:0b:11:22:33 48 40 aabbccddee + + \param - pAdapter - Adapter upon which the command was received + \param - command - ASCII text command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_sendactionframe_v1(hdd_adapter_t *pAdapter, const char *command) +{ + tANI_U8 channel = 0; + tANI_U8 dwell_time = 0; + tANI_U8 payload_len = 0; + tANI_U8 *payload = NULL; + tSirMacAddr bssid; + int ret; + + ret = hdd_parse_send_action_frame_v1_data(command, bssid, &channel, + &dwell_time, &payload, + &payload_len); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse send action frame data", __func__); + } else { + ret = hdd_sendactionframe(pAdapter, bssid, channel, dwell_time, + payload_len, payload); + vos_mem_free(payload); + } + + return ret; +} + +/* + \brief hdd_parse_sendactionframe_v2() - parse version 2 of the + SENDACTIONFRAME command + + This function parses the v2 SENDACTIONFRAME command with the format + + SENDACTIONFRAME + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received, ASCII command followed + by binary data + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_sendactionframe_v2(hdd_adapter_t *pAdapter, + const char *command) +{ + struct android_wifi_af_params *params; + tSirMacAddr bssid; + int ret; + + /* params are large so keep off the stack */ + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) return -ENOMEM; + + /* The params are located after "SENDACTIONFRAME " */ + memcpy(params, command + 16, sizeof(*params)); + + if (!mac_pton(params->bssid, (u8 *)&bssid)) { + hddLog(LOGE, "%s: MAC address parsing failed", __func__); + ret = -EINVAL; + } else { + ret = hdd_sendactionframe(pAdapter, bssid, params->channel, + params->dwell_time, params->len, params->data); + } + kfree(params); + return ret; +} + +/* + \brief hdd_parse_sendactionframe() - parse the SENDACTIONFRAME command + + There are two different versions of the SENDACTIONFRAME command. + Version 1 of the command contains a parameter list that is ASCII + characters whereas version 2 contains a combination of ASCII and + binary payload. Determine if a version 1 or a version 2 command is + being parsed by examining the parameters, and then dispatch the + parser that is appropriate for the version of the command. + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_sendactionframe(hdd_adapter_t *pAdapter, const char *command) +{ + int ret; + + /* both versions start with "SENDACTIONFRAME " + * v1 has a bssid and other parameters as an ASCII string + * SENDACTIONFRAME xx:xx:xx:xx:xx:xx CH DWELL LEN FRAME + * v2 has a C struct + * SENDACTIONFRAME + * + * The first field in the v2 struct is also the bssid in ASCII. + * But in the case of a v2 message the BSSID is NUL-terminated. + * Hence we can peek at that offset to see if this is V1 or V2 + * SENDACTIONFRAME xx:xx:xx:xx:xx:xx* + * 111111111122222222223333 + * 0123456789012345678901234567890123 + */ + if (command[33]) { + ret = hdd_parse_sendactionframe_v1(pAdapter, command); + } else { + ret = hdd_parse_sendactionframe_v2(pAdapter, command); + } + + return ret; +} +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* + \brief hdd_parse_set_roam_scan_channels_v1() - parse version 1 of the + SETROAMSCANCHANNELS command + + This function parses the v1 SETROAMSCANCHANNELS command with the format + + SETROAMSCANCHANNELS N C1 C2 ... Cn + + Where "N" is the ASCII representation of the number of channels and + C1 thru Cn is the ASCII representation of the channels. For example + + SETROAMSCANCHANNELS 4 36 40 44 48 + + \param - pAdapter - Adapter upon which the command was received + \param - command - ASCII text command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_set_roam_scan_channels_v1(hdd_adapter_t *pAdapter, + const char *command) +{ + tANI_U8 channel_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 num_chan = 0; + eHalStatus status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int ret; + + ret = hdd_parse_channellist(command, channel_list, &num_chan); + if (ret) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse channel list information", __func__); + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL, + pAdapter->sessionId, num_chan)); + + if (num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: number of channels (%d) supported exceeded max (%d)", + __func__, num_chan, WNI_CFG_VALID_CHANNEL_LIST_LEN); + ret = -EINVAL; + goto exit; + } + + status = sme_ChangeRoamScanChannelList(pHddCtx->hHal, pAdapter->sessionId, + channel_list, num_chan); + if (eHAL_STATUS_SUCCESS != status) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update channel list information", __func__); + ret = -EINVAL; + goto exit; + } + exit: + return ret; +} + +/* + \brief hdd_parse_set_roam_scan_channels_v2() - parse version 2 of the + SETROAMSCANCHANNELS command + + This function parses the v2 SETROAMSCANCHANNELS command with the format + + SETROAMSCANCHANNELS [N][C1][C2][Cn] + + The command begins with SETROAMSCANCHANNELS followed by a space, but + what follows the space is an array of u08 parameters. For example + + SETROAMSCANCHANNELS [0x04 0x24 0x28 0x2c 0x30] + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received, ASCII command followed + by binary data + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_set_roam_scan_channels_v2(hdd_adapter_t *pAdapter, + const char *command) +{ + const tANI_U8 *value; + tANI_U8 channel_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 channel; + tANI_U8 num_chan; + int i; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + eHalStatus status; + int ret = 0; + + /* array of values begins after "SETROAMSCANCHANNELS " */ + value = command + 20; + + num_chan = *value++; + if (num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: number of channels (%d) supported exceeded max (%d)", + __func__, num_chan, WNI_CFG_VALID_CHANNEL_LIST_LEN); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL, + pAdapter->sessionId, num_chan)); + + for (i = 0; i < num_chan; i++) { + channel = *value++; + if (channel > WNI_CFG_CURRENT_CHANNEL_STAMAX) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: index %d invalid channel %d", __func__, i, channel); + ret = -EINVAL; + goto exit; + } + channel_list[i] = channel; + } + status = sme_ChangeRoamScanChannelList(pHddCtx->hHal, pAdapter->sessionId, + channel_list, num_chan); + if (eHAL_STATUS_SUCCESS != status) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update channel list information", __func__); + ret = -EINVAL; + goto exit; + } + exit: + return ret; +} + +/* + \brief hdd_parse_set_roam_scan_channels() - parse the + SETROAMSCANCHANNELS command + + There are two different versions of the SETROAMSCANCHANNELS command. + Version 1 of the command contains a parameter list that is ASCII + characters whereas version 2 contains a binary payload. Determine + if a version 1 or a version 2 command is being parsed by examining + the parameters, and then dispatch the parser that is appropriate for + the command. + + \param - pAdapter - Adapter upon which the command was received + \param - command - command that was received + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_set_roam_scan_channels(hdd_adapter_t *pAdapter, + const char *command) +{ + const char *cursor; + char ch; + bool v1; + int ret; + + /* start after "SETROAMSCANCHANNELS " */ + cursor = command + 20; + + /* assume we have a version 1 command until proven otherwise */ + v1 = true; + + /* v1 params will only contain ASCII digits and space */ + while ((ch = *cursor++) && v1) { + if (!(isdigit(ch) || isspace(ch))) { + v1 = false; + } + } + if (v1) { + ret = hdd_parse_set_roam_scan_channels_v1(pAdapter, command); + } else { + ret = hdd_parse_set_roam_scan_channels_v2(pAdapter, command); + } + + return ret; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */ + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_setrmcrate_command() - HDD Parse reliable multicast + set rate command + + This function parses the SETRMCTXRATE command passed in the format + SETRMCTXRATEX(multicast rate in Mbps) + For example input commands: + 1) SETRMCTXRATE 6 -> This is translated into set RMC multicast rate + to 6 Mbps + 1) SETRMCTXRATE 0 -> This is translated into disabling fixed multicast rate + and enabling multicast RA in firmware + + \param - pValue Pointer to SETRMCTXRATE command + \param - pRate Pointer to local RMC multicast rate variable + \param - pTxFlags Pointer to local RMC multicast rate variable + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_parse_setrmcrate_command(tANI_U8 *pValue, + tANI_U32 *pRate, tTxrateinfoflags *pTxFlags) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + char buf[32]; + *pRate = 0; + *pTxFlags = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return 0; + } + + /* + * getting the first argument which sets multicast rate. + */ + sscanf(inPtr, "%32s ", buf); + v = kstrtos32(buf, 10, &tempInt); + if ( v < 0) + { + return -EINVAL; + } + + /* + * Validate the multicast rate. + */ + switch (tempInt) + { + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Unsupported rate: %d", tempInt); + return -EINVAL; + case 0: + case 6: + case 9: + case 12: + case 18: + case 24: + case 36: + case 48: + case 54: + *pTxFlags = eHAL_TX_RATE_LEGACY; + *pRate = tempInt * 10; + break; + case 65: + *pTxFlags = eHAL_TX_RATE_HT20; + *pRate = tempInt * 10; + break; + case 72: + *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; + *pRate = 722; /* fractional rate 72.2 Mbps */ + break; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Rate: %d", *pRate); + + return 0; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief hdd_parse_plm_cmd() - HDD Parse Plm command + + This function parses the plm command passed in the format + CCXPLMREQ + + + + + + \param - pValue Pointer to input data + \param - pPlmRequest Pointer to output struct tpSirPlmReq + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +eHalStatus hdd_parse_plm_cmd(tANI_U8 *pValue, tSirPlmReq *pPlmRequest) +{ + tANI_U8 *cmdPtr = NULL; + int count, content = 0, ret = 0; + char buf[32]; + + /* moving to argument list */ + cmdPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*no space after the command*/ + if (SPACE_ASCII_VALUE != *cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* START/STOP PLM req */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + pPlmRequest->enable = content; + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* Dialog token of radio meas req containing meas reqIE */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + pPlmRequest->diag_token = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "diag token %d", pPlmRequest->diag_token); + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* measurement token of meas req IE */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + pPlmRequest->meas_token = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "meas token %d", pPlmRequest->meas_token); + + hddLog(VOS_TRACE_LEVEL_ERROR, + "PLM req %s", pPlmRequest->enable ? "START" : "STOP"); + if (pPlmRequest->enable) { + + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* total number of bursts after which STA stops sending */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content < 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->numBursts= content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "num burst %d", pPlmRequest->numBursts); + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /* removing empty spaces */ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* burst interval in seconds */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content <= 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->burstInt = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "burst Int %d", pPlmRequest->burstInt); + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* Meas dur in TU's,STA goes off-ch and transmit PLM bursts */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content <= 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->measDuration = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "measDur %d", pPlmRequest->measDuration); + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* burst length of PLM bursts */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content <= 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->burstLen = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "burstLen %d", pPlmRequest->burstLen); + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* desired tx power for transmission of PLM bursts */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content <= 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->desiredTxPwr = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, + "desiredTxPwr %d", pPlmRequest->desiredTxPwr); + + for (count = 0; count < VOS_MAC_ADDR_SIZE; count++) + { + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 16, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + pPlmRequest->macAddr[count] = content; + } + + hddLog(VOS_TRACE_LEVEL_DEBUG, "MC addr "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPlmRequest->macAddr)); + + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + /* number of channels */ + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content < 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->plmNumCh = content; + hddLog(VOS_TRACE_LEVEL_DEBUG, "numch %d", pPlmRequest->plmNumCh); + + /* Channel numbers */ + for (count = 0; count < pPlmRequest->plmNumCh; count++) + { + cmdPtr = strpbrk(cmdPtr, " "); + + if (NULL == cmdPtr) + return eHAL_STATUS_FAILURE; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *cmdPtr) && ('\0' != *cmdPtr)) + cmdPtr++; + + ret = sscanf(cmdPtr, "%31s ", buf); + if (1 != ret) return eHAL_STATUS_FAILURE; + + ret = kstrtos32(buf, 10, &content); + if ( ret < 0) return eHAL_STATUS_FAILURE; + + if (content <= 0) + return eHAL_STATUS_FAILURE; + + pPlmRequest->plmChList[count]= content; + hddLog(VOS_TRACE_LEVEL_DEBUG, " ch- %d", + pPlmRequest->plmChList[count]); + } + } /* If PLM START */ + + return eHAL_STATUS_SUCCESS; +} +#endif +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +static void wlan_hdd_ready_to_extwow(void *callbackContext, + boolean is_success) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)callbackContext; + int rc; + + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return; + } + pHddCtx->ext_wow_should_suspend = is_success; + complete(&pHddCtx->ready_to_extwow); +} + +static int hdd_enable_ext_wow(hdd_adapter_t *pAdapter, + tpSirExtWoWParams arg_params) +{ + tSirExtWoWParams params; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + int rc; + + vos_mem_copy(¶ms, arg_params, sizeof(params)); + + INIT_COMPLETION(pHddCtx->ready_to_extwow); + + halStatus = sme_ConfigureExtWoW(hHal, ¶ms, + &wlan_hdd_ready_to_extwow, pHddCtx); + if (eHAL_STATUS_SUCCESS != halStatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ConfigureExtWoW returned failure %d"), halStatus); + return -EPERM; + } + + rc = wait_for_completion_timeout(&pHddCtx->ready_to_extwow, + msecs_to_jiffies(WLAN_WAIT_TIME_READY_TO_EXTWOW)); + if (!rc) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to get ready to extwow", __func__); + return -EPERM; + } + + if (pHddCtx->ext_wow_should_suspend) { + if (pHddCtx->cfg_ini->extWowGotoSuspend) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received ready to ExtWoW. Going to suspend", __func__); + + wlan_hdd_cfg80211_suspend_wlan(pHddCtx->wiphy, NULL); + wlan_hif_pci_suspend(); + } + } else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Received ready to ExtWoW failure", __func__); + return -EPERM; + } + + return 0; +} + +static int hdd_enable_ext_wow_parser(hdd_adapter_t *pAdapter, int vdev_id, + int value) +{ + tSirExtWoWParams params; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int rc; + + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return -EINVAL; + } + + if (value < EXT_WOW_TYPE_APP_TYPE1 || value > EXT_WOW_TYPE_APP_TYPE1_2 ) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid type")); + return -EINVAL; + } + + if (value == EXT_WOW_TYPE_APP_TYPE1 && + pHddCtx->is_extwow_app_type1_param_set) + params.type = value; + else if (value == EXT_WOW_TYPE_APP_TYPE2 && + pHddCtx->is_extwow_app_type2_param_set) + params.type = value; + else if (value == EXT_WOW_TYPE_APP_TYPE1_2 && + pHddCtx->is_extwow_app_type1_param_set && + pHddCtx->is_extwow_app_type2_param_set) + params.type = value; + else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Set app params before enable it value %d"),value); + return -EINVAL; + } + + params.vdev_id = vdev_id; + params.wakeup_pin_num = pHddCtx->cfg_ini->extWowApp1WakeupPinNumber | + (pHddCtx->cfg_ini->extWowApp2WakeupPinNumber << 8); + + return hdd_enable_ext_wow(pAdapter, ¶ms); +} + +static int hdd_set_app_type1_params(tHalHandle hHal, + tpSirAppType1Params arg_params) +{ + tSirAppType1Params params; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + vos_mem_copy(¶ms, arg_params, sizeof(params)); + + halStatus = sme_ConfigureAppType1Params(hHal, ¶ms); + if (eHAL_STATUS_SUCCESS != halStatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ConfigureAppType1Params returned failure %d"), halStatus); + return -EPERM; + } + + return 0; +} + +static int hdd_set_app_type1_parser(hdd_adapter_t *pAdapter, + char *arg, int len) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + char id[20], password[20]; + tSirAppType1Params params; + int rc, i; + + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return -EINVAL; + } + + if (2 != sscanf(arg, "%8s %16s", id, password)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid Number of arguments")); + return -EINVAL; + } + + memset(¶ms, 0, sizeof(tSirAppType1Params)); + params.vdev_id = pAdapter->sessionId; + for (i = 0; i < ETHER_ADDR_LEN; i++) + params.wakee_mac_addr[i] = pAdapter->macAddressCurrent.bytes[i]; + + params.id_length = strlen(id); + vos_mem_copy(params.identification_id, id, params.id_length); + params.pass_length = strlen(password); + vos_mem_copy(params.password, password, params.pass_length); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: %d %pM %.8s %u %.16s %u", + __func__, params.vdev_id, params.wakee_mac_addr, + params.identification_id, params.id_length, + params.password, params.pass_length ); + + return hdd_set_app_type1_params(hHal, ¶ms); +} + +static int hdd_set_app_type2_params(tHalHandle hHal, + tpSirAppType2Params arg_params) +{ + tSirAppType2Params params; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + vos_mem_copy(¶ms, arg_params, sizeof(params)); + + halStatus = sme_ConfigureAppType2Params(hHal, ¶ms); + if (eHAL_STATUS_SUCCESS != halStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ConfigureAppType2Params returned failure %d"), halStatus); + return -EPERM; + } + + return 0; +} + +static int hdd_set_app_type2_parser(hdd_adapter_t *pAdapter, + char *arg, int len) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + char mac_addr[20], rc4_key[20]; + unsigned int gateway_mac[6], i; + tSirAppType2Params params; + int ret; + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return -EINVAL; + } + + memset(¶ms, 0, sizeof(tSirAppType2Params)); + + ret = sscanf(arg, "%17s %16s %x %x %x %u %u %hu %hu %u %u %u %u %u %u", + mac_addr, rc4_key, (unsigned int *)¶ms.ip_id, + (unsigned int*)¶ms.ip_device_ip, + (unsigned int*)¶ms.ip_server_ip, + (unsigned int*)¶ms.tcp_seq, (unsigned int*)¶ms.tcp_ack_seq, + (uint16_t *)¶ms.tcp_src_port, + (uint16_t *)¶ms.tcp_dst_port, + (unsigned int*)¶ms.keepalive_init, + (unsigned int*)¶ms.keepalive_min, + (unsigned int*)¶ms.keepalive_max, + (unsigned int*)¶ms.keepalive_inc, + (unsigned int*)¶ms.tcp_tx_timeout_val, + (unsigned int*)¶ms.tcp_rx_timeout_val); + + + if (ret != 15 && ret != 7) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Number of arguments"); + return -EINVAL; + } + + if (6 != sscanf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", &gateway_mac[0], + &gateway_mac[1], &gateway_mac[2], &gateway_mac[3], + &gateway_mac[4], &gateway_mac[5])) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MacAddress Input %s", mac_addr); + return -EINVAL; + } + + if (params.tcp_src_port > WLAN_HDD_MAX_TCP_PORT || + params.tcp_dst_port > WLAN_HDD_MAX_TCP_PORT) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid TCP Port Number"); + return -EINVAL; + } + + for (i = 0; i < ETHER_ADDR_LEN; i++) + params.gateway_mac[i] = (uint8_t) gateway_mac[i]; + + params.rc4_key_len = strlen(rc4_key); + vos_mem_copy(params.rc4_key, rc4_key, params.rc4_key_len); + + params.vdev_id = pAdapter->sessionId; + params.tcp_src_port = (params.tcp_src_port != 0)? + params.tcp_src_port : pHddCtx->cfg_ini->extWowApp2TcpSrcPort; + params.tcp_dst_port = (params.tcp_dst_port != 0)? + params.tcp_dst_port : pHddCtx->cfg_ini->extWowApp2TcpDstPort; + params.keepalive_init = (params.keepalive_init != 0)? + params.keepalive_init : pHddCtx->cfg_ini->extWowApp2KAInitPingInterval; + params.keepalive_min = (params.keepalive_min != 0)? + params.keepalive_min : pHddCtx->cfg_ini->extWowApp2KAMinPingInterval; + params.keepalive_max = (params.keepalive_max != 0)? + params.keepalive_max : pHddCtx->cfg_ini->extWowApp2KAMaxPingInterval; + params.keepalive_inc = (params.keepalive_inc != 0)? + params.keepalive_inc : pHddCtx->cfg_ini->extWowApp2KAIncPingInterval; + params.tcp_tx_timeout_val = (params.tcp_tx_timeout_val != 0)? + params.tcp_tx_timeout_val : pHddCtx->cfg_ini->extWowApp2TcpTxTimeout; + params.tcp_rx_timeout_val = (params.tcp_rx_timeout_val != 0)? + params.tcp_rx_timeout_val : pHddCtx->cfg_ini->extWowApp2TcpRxTimeout; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: %pM %.16s %u %u %u %u %u %u %u %u %u %u %u %u %u", + __func__, gateway_mac, rc4_key, params.ip_id, params.ip_device_ip, + params.ip_server_ip, params.tcp_seq, params.tcp_ack_seq, + params.tcp_src_port, params.tcp_dst_port, params.keepalive_init, + params.keepalive_min, params.keepalive_max, + params.keepalive_inc, params.tcp_tx_timeout_val, + params.tcp_rx_timeout_val); + + return hdd_set_app_type2_params(hHal, ¶ms); +} + +#endif + +int wlan_hdd_set_mc_rate(hdd_adapter_t *pAdapter, int targetRate) +{ + tSirRateUpdateInd *rateUpdate; + eHalStatus status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *pConfig = NULL; + + if (pHddCtx == NULL) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return -EINVAL; + } + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (WLAN_HDD_SOFTAP != pAdapter->device_mode) && + (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Received SETMCRATE command in invalid mode %d" + "SETMCRATE command is only allowed in STA, IBSS or SOFTAP mode", + __func__, pAdapter->device_mode); + return -EINVAL; + } + pConfig = pHddCtx->cfg_ini; + rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdate) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SETMCRATE indication alloc fail", __func__); + return -EFAULT; + } + vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd )); + rateUpdate->nss = (pConfig->enable2x2 == 0) ? 0 : 1; + rateUpdate->dev_mode = pAdapter->device_mode; + rateUpdate->mcastDataRate24GHz = targetRate; + rateUpdate->mcastDataRate24GHzTxFlag = 1; + rateUpdate->mcastDataRate5GHz = targetRate; + rateUpdate->bcastDataRate = -1; + memcpy(rateUpdate->bssid, pAdapter->macAddressCurrent.bytes, + sizeof(rateUpdate->bssid)); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: MC Target rate %d, mac = %pM, dev_mode = %d", + __func__, rateUpdate->mcastDataRate24GHz, rateUpdate->bssid, + pAdapter->device_mode); + status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SETMCRATE failed", __func__); + vos_mem_free(rateUpdate); + return -EFAULT; + } + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command + + This function parses the MAXTXPOWER command passed in the format + MAXTXPOWERX(Tx power in dbm) + For example input commands: + 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm + 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm + + \param - pValue Pointer to MAXTXPOWER command + \param - pDbm Pointer to tx power + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_parse_setmaxtxpower_command(tANI_U8 *pValue, int *pTxPower) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + *pTxPower = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return 0; + } + + v = kstrtos32(inPtr, 10, &tempInt); + + /* Range checking for passed parameter */ + if ( (tempInt < HDD_MIN_TX_POWER) || + (tempInt > HDD_MAX_TX_POWER) ) + { + return -EINVAL; + } + + *pTxPower = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SETMAXTXPOWER: %d", *pTxPower); + + return 0; +} /*End of hdd_parse_setmaxtxpower_command*/ + + +static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len) +{ + int ret = 0; + + if (!pCfg || !command || !extra || !len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for GETDWELLTIME is incorrect", __func__); + ret = -EINVAL; + return ret; + } + + if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n", + (int)pCfg->nActiveMaxChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n", + (int)pCfg->nActiveMinChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n", + (int)pCfg->nPassiveMaxChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n", + (int)pCfg->nPassiveMinChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME", 12) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME %u \n", + (int)pCfg->nActiveMaxChnTime); + return ret; + } + else + { + ret = -EINVAL; + } + + return ret; +} + +static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command) +{ + tHalHandle hHal; + hdd_config_t *pCfg; + tANI_U8 *value = command; + tSmeConfigParams smeConfig; + int val = 0, ret = 0, temp = 0; + + if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini) + || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter)))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME is incorrect", __func__); + ret = -EINVAL; + return ret; + } + + vos_mem_zero(&smeConfig, sizeof(smeConfig)); + sme_GetConfigParam(hHal, &smeConfig); + + if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 ) + { + value = value + 24; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMaxChnTime = val; + smeConfig.csrConfig.nActiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0) + { + value = value + 24; + temp = kstrtou32(value, 10, &val); + if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME ACTIVE MIN is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMinChnTime = val; + smeConfig.csrConfig.nActiveMinChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0) + { + value = value + 25; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nPassiveMaxChnTime = val; + smeConfig.csrConfig.nPassiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0) + { + value = value + 25; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN || + val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nPassiveMinChnTime = val; + smeConfig.csrConfig.nPassiveMinChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME", 12) == 0) + { + value = value + 13; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMaxChnTime = val; + smeConfig.csrConfig.nActiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else + { + ret = -EINVAL; + } + + return ret; +} + +static void hdd_GetLink_statusCB(v_U8_t status, void *pContext) +{ + struct statsContext *pLinkContext; + hdd_adapter_t *pAdapter; + + if (NULL == pContext) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Bad pContext [%p]", + __func__, pContext); + return; + } + + pLinkContext = pContext; + pAdapter = pLinkContext->pAdapter; + + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (LINK_STATUS_MAGIC != pLinkContext->magic)) { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pLinkContext->magic); + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pLinkContext->magic = 0; + + /* copy over the status */ + pAdapter->linkStatus = status; + + /* notify the caller */ + complete(&pLinkContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +/** + * wlan_hdd_get_link_status() - get link status + * @pAdapter: pointer to the adapter + * + * This function sends a request to query the link status and waits + * on a timer to invoke the callback. if the callback is invoked then + * latest link status shall be returned or otherwise cached value + * will be returned. + * + * Return: On success, link status shall be returned. + * On error or not associated, link status 0 will be returned. + */ +static int wlan_hdd_get_link_status(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + struct statsContext context; + eHalStatus hstatus; + unsigned long rc; + + if (pHddCtx->isLogpInProgress) { + hddLog(LOGW, FL("LOGP in Progress. Ignore!!!")); + return 0; + } + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + /* If not associated, then expected link status return value is 0 */ + hddLog(LOG1, FL("Not associated!")); + return 0; + } + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = LINK_STATUS_MAGIC; + hstatus = sme_getLinkStatus(WLAN_HDD_GET_HAL_CTX(pAdapter), + hdd_GetLink_statusCB, + &context, + pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != hstatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve link status", __func__); + /* return a cached value */ + } else { + /* request is sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_LINK_STATUS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving link status")); + } + } + + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + /* either callback updated pAdapter stats or it has cached data */ + return pAdapter->linkStatus; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void hdd_wma_send_fastreassoc_cmd(int sessionId, tSirMacAddr bssid, + int channel) +{ + t_wma_roam_invoke_cmd *fastreassoc; + vos_msg_t msg = {0}; + + fastreassoc = vos_mem_malloc(sizeof(*fastreassoc)); + if (NULL == fastreassoc) { + hddLog(LOGE, FL("vos_mem_alloc failed for fastreassoc")); + return; + } + fastreassoc->vdev_id = sessionId; + fastreassoc->channel = channel; + fastreassoc->bssid[0] = bssid[0]; + fastreassoc->bssid[1] = bssid[1]; + fastreassoc->bssid[2] = bssid[2]; + fastreassoc->bssid[3] = bssid[3]; + fastreassoc->bssid[4] = bssid[4]; + fastreassoc->bssid[5] = bssid[5]; + + msg.type = SIR_HAL_ROAM_INVOKE; + msg.reserved = 0; + msg.bodyptr = fastreassoc; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, + &msg)) { + vos_mem_free(fastreassoc); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post ROAM_INVOKE_CMD message to WMA")); + } +} +#endif + +/** + * hdd_set_miracast_mode() - function used to set the miracast mode value + * @pAdapter: pointer to the adapter of the interface. + * @command: pointer to the command buffer "MIRACAST ". + * Return: 0 on success -EINVAL on failure. + */ +int hdd_set_miracast_mode(hdd_adapter_t *pAdapter, tANI_U8 *command) +{ + tHalHandle hHal = WLAN_HDD_GET_CTX(pAdapter)->hHal; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 filterType = 0; + tANI_U8 *value; + int ret; + + value = command + 9; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &filterType); + if (ret < 0) { + /* If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: kstrtou8 failed range", __func__); + return -EINVAL; + } + + /* Filtertype value should be either 0-Disabled, 1-Source, 2-sink */ + if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) || + (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Accepted Values are 0 to 2." + "0-Disabled, 1-Source, 2-Sink", __func__); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO, "%s: miracast mode %hu", __func__, filterType); + pMac->fMiracastSessionPresent = filterType; + return 0; +} + +/** + * drv_cmd_set_fcc_channel() - handle fcc constraint request + * @hdd_ctx: HDD context + * @cmd: command ptr + * @cmd_len: command len + * + * Return: status + */ +static int drv_cmd_set_fcc_channel(hdd_context_t *hdd_ctx, uint8_t *cmd, + uint8_t cmd_len) +{ + uint8_t *value; + uint8_t fcc_constraint; + eHalStatus status; + int ret = 0; + + value = cmd + cmd_len + 1; + + ret = kstrtou8(value, 10, &fcc_constraint); + if ((ret < 0) || (fcc_constraint > 1)) { + /* + * If the input value is greater than max value of datatype, + * then also it is a failure + */ + hddLog(LOGE, FL("value out of range")); + return -EINVAL; + } + + status = sme_disable_non_fcc_channel(hdd_ctx->hHal, !fcc_constraint); + if (status != eHAL_STATUS_SUCCESS) + ret = -EPERM; + + return ret; +} + +static int hdd_driver_command(hdd_adapter_t *pAdapter, + hdd_priv_data_t *ppriv_data) +{ + hdd_priv_data_t priv_data; + tANI_U8 *command = NULL; + int ret = 0; + + /* + * Note that valid pointers are provided by caller + */ + + /* copy to local struct to avoid numerous changes to legacy code */ + priv_data = *ppriv_data; + + if (priv_data.total_len <= 0 || + priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s:invalid priv_data.total_len(%d)!!!", __func__, + priv_data.total_len); + ret = -EINVAL; + goto exit; + } + + /* Allocate +1 for '\0' */ + command = kmalloc(priv_data.total_len + 1, GFP_KERNEL); + if (!command) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to allocate memory", __func__); + ret = -ENOMEM; + goto exit; + } + + if (copy_from_user(command, priv_data.buf, priv_data.total_len)) + { + ret = -EFAULT; + goto exit; + } + + /* Make sure the command is NUL-terminated */ + command[priv_data.total_len] = '\0'; + + /* at one time the following block of code was conditional. braces + * have been retained to avoid re-indenting the legacy code + */ + { + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Received %s cmd from Wi-Fi GUI***", __func__, command); + + if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 ) + { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL, + pAdapter->sessionId, (unsigned) + (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 | + *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 | + *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 | + *(pHddCtx->p2pDeviceAddress.bytes+5)))); + if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes, + sizeof(tSirMacAddr))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + } + } + else if (strncmp(command, "SETBAND", 7) == 0) + { + tANI_U8 *ptr = command ; + int ret = 0 ; + + /* Change band request received */ + + /* First 8 bytes will have "SETBAND " and + * 9 byte will have band setting value */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: SetBandCommand Info comm %s UL %d, TL %d", + __func__, command, priv_data.used_len, priv_data.total_len); + /* Change band request received */ + ret = hdd_setBand_helper(pAdapter->dev, ptr); + } + else if (strncmp(command, "SETWMMPS", 8) == 0) + { + tANI_U8 *ptr = command; + ret = hdd_wmmps_helper(pAdapter, ptr); + } + else if (strncasecmp(command, "COUNTRY", 7) == 0) + { + eHalStatus status; + unsigned long rc; + char *country_code; + + country_code = command + 8; + + INIT_COMPLETION(pAdapter->change_country_code); + hdd_checkandupdate_dfssetting(pAdapter, country_code); + + status = + sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_callback, + country_code, pAdapter, + pHddCtx->pvosContext, + eSIR_TRUE, eSIR_TRUE); + if (status == eHAL_STATUS_SUCCESS) + { + rc = wait_for_completion_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME while setting country code timed out", + __func__); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME Change Country code fail, status=%d", + __func__, status); + ret = -EINVAL; + } + + } + /* + * Command should be a string having format + * SET_SAP_CHANNEL_LIST + */ + else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0) + { + tANI_U8 *ptr = command; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " Received Command to Set Preferred Channels for SAP in %s", __func__); + +#ifdef WLAN_FEATURE_MBSSID + ret = sapSetPreferredChannel(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), ptr); +#else + ret = sapSetPreferredChannel(ptr); +#endif + } + else if (strncmp(command, "SETSUSPENDMODE", 14) == 0) + { + } +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + else if (strncmp(command, "SETROAMTRIGGER", 14) == 0) + { + tANI_U8 *value = command; + tANI_S8 rssi = 0; + tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT; + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* Move pointer to ahead of SETROAMTRIGGER */ + value = value + 15; + + /* Convert the value from ascii to integer */ + ret = kstrtos8(value, 10, &rssi); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX); + ret = -EINVAL; + goto exit; + } + + lookUpThreshold = abs(rssi); + + if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) || + (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Neighbor lookup threshold value %d is out of range" + " (Min: %d Max: %d)", lookUpThreshold, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL, + pAdapter->sessionId, lookUpThreshold)); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Roam trigger" + " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold); + + pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold; + status = sme_setNeighborLookupRssiThreshold(pHddCtx->hHal, + pAdapter->sessionId, + lookUpThreshold); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to set roam trigger, try again", __func__); + ret = -EPERM; + goto exit; + } + + /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */ + sme_setNeighborReassocRssiThreshold(pHddCtx->hHal, + pAdapter->sessionId, + lookUpThreshold + 5); + } + else if (strncmp(command, "GETROAMTRIGGER", 14) == 0) + { + tANI_U8 lookUpThreshold = + sme_getNeighborLookupRssiThreshold(pHddCtx->hHal); + int rssi = (-1) * lookUpThreshold; + char extra[32]; + tANI_U8 len = 0; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL, + pAdapter->sessionId, lookUpThreshold)); + len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamScanPeriod = 0; + tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT; + + /* input refresh period is in terms of seconds */ + /* Move pointer to ahead of SETROAMSCANPERIOD */ + value = value + 18; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanPeriod); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000), + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + + if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) || + (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam scan period value %d is out of range" + " (Min: %d Max: %d)", roamScanPeriod, + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000), + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL, + pAdapter->sessionId, roamScanPeriod)); + neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan period" + " (Empty Scan refresh period) = %d", __func__, roamScanPeriod); + + pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod; + sme_UpdateEmptyScanRefreshPeriod(pHddCtx->hHal, + pAdapter->sessionId, + neighborEmptyScanRefreshPeriod); + } + else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0) + { + tANI_U16 nEmptyScanRefreshPeriod = + sme_getEmptyScanRefreshPeriod(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL, + pAdapter->sessionId, nEmptyScanRefreshPeriod)); + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000)); + /* Returned value is in units of seconds */ + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamScanRefreshPeriod = 0; + tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT; + + /* input refresh period is in terms of seconds */ + /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD */ + value = value + 25; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanRefreshPeriod); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000), + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + + if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) || + (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Neighbor scan results refresh period value %d is out of range" + " (Min: %d Max: %d)", roamScanRefreshPeriod, + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000), + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan refresh period" + " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod); + + pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod; + sme_setNeighborScanRefreshPeriod(pHddCtx->hHal, + pAdapter->sessionId, + neighborScanRefreshPeriod); + } + else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0) + { + tANI_U16 value = sme_getNeighborScanRefreshPeriod(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANREFRESHPERIOD", (value/1000)); + /* Returned value is in units of seconds */ + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#ifdef FEATURE_WLAN_LFR + /* SETROAMMODE */ + else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT; + + /* Move pointer to ahead of SETROAMMODE */ + value = value + SIZE_OF_SETROAMMODE + 1; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) || + (roamMode > CFG_LFR_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam Mode value %d is out of range" + " (Min: %d Max: %d)", roamMode, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: Received Command to Set Roam Mode = %d", __func__, roamMode); + /* + * Note that + * SETROAMMODE 0 is to enable LFR while + * SETROAMMODE 1 is to disable LFR, but + * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable. + * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled. + */ + if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode) + roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */ + else + roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */ + + pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode; + /* LFR2 is dependent on Fast Roam. So, enable/disable LFR2 + * variable. if Fast Roam has been changed from disabled to enabled, + * then enable LFR2 and send the LFR START command to the firmware. + * Otherwise, send the LFR STOP command to the firmware and then + * disable LFR2.The sequence is different. + */ + if (roamMode) { + pHddCtx->cfg_ini->isRoamOffloadScanEnabled = roamMode; + sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + sme_UpdateIsFastRoamIniFeatureEnabled(pHddCtx->hHal, + pAdapter->sessionId, + roamMode); + } else { + sme_UpdateIsFastRoamIniFeatureEnabled(pHddCtx->hHal, + pAdapter->sessionId, + roamMode); + pHddCtx->cfg_ini->isRoamOffloadScanEnabled = roamMode; + sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + } + } + /* GETROAMMODE */ + else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0) + { + tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + /* + * roamMode value shall be inverted because the semantics is + * different. + */ + if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode) + roamMode = CFG_LFR_FEATURE_ENABLED_MAX; + else + roamMode = CFG_LFR_FEATURE_ENABLED_MIN; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + else if (strncmp(command, "SETROAMDELTA", 12) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT; + + /* Move pointer to ahead of SETROAMDELTA */ + value = value + 13; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamRssiDiff); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX); + ret = -EINVAL; + goto exit; + } + + if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) || + (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam rssi diff value %d is out of range" + " (Min: %d Max: %d)", roamRssiDiff, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff); + + pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff; + sme_UpdateRoamRssiDiff(pHddCtx->hHal, + pAdapter->sessionId, roamRssiDiff); + } + else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0) + { + tANI_U8 roamRssiDiff = sme_getRoamRssiDiff(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMDELTA_IOCTL, + pAdapter->sessionId, roamRssiDiff)); + len = scnprintf(extra, sizeof(extra), "%s %d", + command, roamRssiDiff); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + else if (strncmp(command, "GETBAND", 7) == 0) + { + int band = -1; + char extra[32]; + tANI_U8 len = 0; + hdd_getBand_helper(pHddCtx, &band); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETBAND_IOCTL, + pAdapter->sessionId, band)); + len = scnprintf(extra, sizeof(extra), "%s %d", command, band); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANCHANNELS ", 20) == 0) + { + ret = hdd_parse_set_roam_scan_channels(pAdapter, command); + } + else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0) + { + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + tANI_U8 j = 0; + char extra[128] = {0}; + int len; + + if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( + pHddCtx->hHal, + ChannelList, + &numChannels, + pAdapter->sessionId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: failed to get roam scan channel list", __func__); + ret = -EFAULT; + goto exit; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL, + pAdapter->sessionId, numChannels)); + /* output channel list is of the format + [Number of roam scan channels][Channel1][Channel2]... */ + /* copy the number of channels in the 0th index */ + len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels); + for (j = 0; (j < numChannels); j++) + { + len += scnprintf(extra + len, sizeof(extra) - len, " %d", + ChannelList[j]); + } + + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETCCXMODE", 10) == 0) + { + tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (eseMode && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled(pHddCtx->hHal)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETCCXMODE", eseMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETOKCMODE", 10) == 0) + { + tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx); + char extra[32]; + tANI_U8 len = 0; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (okcMode && + sme_getIsEseFeatureEnabled(pHddCtx->hHal) && + sme_getIsFtFeatureEnabled(pHddCtx->hHal)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETOKCMODE", okcMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETFASTROAM", 11) == 0) + { + tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETFASTROAM", lfrMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETFASTTRANSITION", 17) == 0) + { + tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETFASTTRANSITION", ft); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0) + { + tANI_U8 *value = command; + tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT; + + /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME */ + value = value + 26; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &minTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) || + (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "scan min channel time value %d is out of range" + " (Min: %d Max: %d)", minTime, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL, + pAdapter->sessionId, minTime)); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change channel min time = %d", __func__, minTime); + + pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime; + sme_setNeighborScanMinChanTime(pHddCtx->hHal, + minTime, pAdapter->sessionId); + } + else if (strncmp(command, "SENDACTIONFRAME", 15) == 0) + { + ret = hdd_parse_sendactionframe(pAdapter, command); + } + else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0) + { + tANI_U16 val = sme_getNeighborScanMinChanTime( + pHddCtx->hHal, + pAdapter->sessionId); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANCHANNELMINTIME", val); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL, + pAdapter->sessionId, val)); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0) + { + tANI_U8 *value = command; + tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT; + + /* Move pointer to ahead of SETSCANCHANNELTIME */ + value = value + 19; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &maxTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou16 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou16 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) || + (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "lfr mode value %d is out of range" + " (Min: %d Max: %d)", maxTime, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change channel max time = %d", __func__, maxTime); + + pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime; + sme_setNeighborScanMaxChanTime(pHddCtx->hHal, + pAdapter->sessionId, maxTime); + } + else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0) + { + tANI_U16 val = sme_getNeighborScanMaxChanTime(pHddCtx->hHal, + pAdapter->sessionId); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETSCANCHANNELTIME", val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANHOMETIME", 15) == 0) + { + tANI_U8 *value = command; + tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT; + + /* Move pointer to ahead of SETSCANHOMETIME */ + value = value + 16; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &val); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou16 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou16 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX); + ret = -EINVAL; + goto exit; + } + + if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) || + (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "scan home time value %d is out of range" + " (Min: %d Max: %d)", val, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change scan home time = %d", __func__, val); + + pHddCtx->cfg_ini->nNeighborScanPeriod = val; + sme_setNeighborScanPeriod(pHddCtx->hHal, + pAdapter->sessionId, val); + } + else if (strncmp(command, "GETSCANHOMETIME", 15) == 0) + { + tANI_U16 val = sme_getNeighborScanPeriod(pHddCtx->hHal, + pAdapter->sessionId); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETSCANHOMETIME", val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMINTRABAND", 16) == 0) + { + tANI_U8 *value = command; + tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT; + + /* Move pointer to ahead of SETROAMINTRABAND */ + value = value + 17; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &val); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX); + ret = -EINVAL; + goto exit; + } + + if ((val < CFG_ROAM_INTRA_BAND_MIN) || + (val > CFG_ROAM_INTRA_BAND_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "intra band mode value %d is out of range" + " (Min: %d Max: %d)", val, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change intra band = %d", __func__, val); + + pHddCtx->cfg_ini->nRoamIntraBand = val; + sme_setRoamIntraBand(pHddCtx->hHal, val); + } + else if (strncmp(command, "GETROAMINTRABAND", 16) == 0) + { + tANI_U16 val = sme_getRoamIntraBand(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMINTRABAND", val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANNPROBES", 14) == 0) + { + tANI_U8 *value = command; + tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT; + + /* Move pointer to ahead of SETSCANNPROBES */ + value = value + 15; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &nProbes); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX); + ret = -EINVAL; + goto exit; + } + + if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) || + (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NProbes value %d is out of range" + " (Min: %d Max: %d)", nProbes, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set nProbes = %d", __func__, nProbes); + + pHddCtx->cfg_ini->nProbes = nProbes; + sme_UpdateRoamScanNProbes(pHddCtx->hHal, pAdapter->sessionId, + nProbes); + } + else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0) + { + tANI_U8 val = sme_getRoamScanNProbes(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0) + { + tANI_U8 *value = command; + tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT; + + /* Move pointer to ahead of SETSCANHOMEAWAYTIME */ + /* input value is in units of msec */ + value = value + 20; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &homeAwayTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) || + (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "homeAwayTime value %d is out of range" + " (Min: %d Max: %d)", homeAwayTime, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime); + if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime) + { + pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime; + sme_UpdateRoamScanHomeAwayTime(pHddCtx->hHal, + pAdapter->sessionId, + homeAwayTime, eANI_BOOLEAN_TRUE); + } + } + else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0) + { + tANI_U16 val = sme_getRoamScanHomeAwayTime(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "REASSOC", 7) == 0) + { + ret = hdd_parse_reassoc(pAdapter, command); + } + else if (strncmp(command, "SETWESMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT; + + /* Move pointer to ahead of SETWESMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &wesMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) || + (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WES Mode value %d is out of range" + " (Min: %d Max: %d)", wesMode, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode); + + pHddCtx->cfg_ini->isWESModeEnabled = wesMode; + sme_UpdateWESMode(pHddCtx->hHal, wesMode, pAdapter->sessionId); + } + else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0) + { + tANI_BOOLEAN wesMode = sme_GetWESMode(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETOPPORTUNISTICRSSIDIFF", 24) == 0) + { + tANI_U8 *value = command; + tANI_U8 nOpportunisticThresholdDiff = CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT; + + /* Move pointer to ahead of SETOPPORTUNISTICRSSIDIFF */ + value = value + 25; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &nOpportunisticThresholdDiff); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed.", __func__); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Opportunistic Threshold diff = %d", + __func__, + nOpportunisticThresholdDiff); + + sme_SetRoamOpportunisticScanThresholdDiff(pHddCtx->hHal, + pAdapter->sessionId, + nOpportunisticThresholdDiff); + } + else if (strncmp(priv_data.buf, "GETOPPORTUNISTICRSSIDIFF", 24) == 0) + { + tANI_S8 val = sme_GetRoamOpportunisticScanThresholdDiff( + pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMRESCANRSSIDIFF", 21) == 0) + { + tANI_U8 *value = command; + tANI_U8 nRoamRescanRssiDiff = CFG_ROAM_RESCAN_RSSI_DIFF_DEFAULT; + + /* Move pointer to ahead of SETROAMRESCANRSSIDIFF */ + value = value + 22; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &nRoamRescanRssiDiff); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed.", __func__); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Roam Rescan RSSI Diff = %d", + __func__, + nRoamRescanRssiDiff); + sme_SetRoamRescanRssiDiff(pHddCtx->hHal, + pAdapter->sessionId, + nRoamRescanRssiDiff); + } + else if (strncmp(priv_data.buf, "GETROAMRESCANRSSIDIFF", 21) == 0) + { + tANI_U8 val = sme_GetRoamRescanRssiDiff(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */ +#ifdef FEATURE_WLAN_LFR + else if (strncmp(command, "SETFASTROAM", 11) == 0) + { + tANI_U8 *value = command; + tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT; + + /* Move pointer to ahead of SETFASTROAM */ + value = value + 12; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &lfrMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) || + (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "lfr mode value %d is out of range" + " (Min: %d Max: %d)", lfrMode, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change lfr mode = %d", __func__, lfrMode); + + pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode; + sme_UpdateIsFastRoamIniFeatureEnabled(pHddCtx->hHal, + pAdapter->sessionId, + lfrMode); + } +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + else if (strncmp(command, "SETFASTTRANSITION", 17) == 0) + { + tANI_U8 *value = command; + tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT; + + /* Move pointer to ahead of SETFASTROAM */ + value = value + 18; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &ft); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) || + (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "ft mode value %d is out of range" + " (Min: %d Max: %d)", ft, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change ft mode = %d", __func__, ft); + + pHddCtx->cfg_ini->isFastTransitionEnabled = ft; + sme_UpdateFastTransitionEnabled(pHddCtx->hHal, ft); + } + + else if (strncmp(command, "FASTREASSOC", 11) == 0) + { + tANI_U8 *value = command; + tANI_U8 channel = 0; + tSirMacAddr targetApBssid; + tHalHandle hHal; + v_U32_t roamId = 0; + tCsrRoamModifyProfileFields modProfileFields; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tCsrHandoffRequest handoffInfo; +#endif + hdd_station_ctx_t *pHddStaCtx = NULL; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + /* if not associated, no need to proceed with reassoc */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__); + ret = -EINVAL; + goto exit; + } + + ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, + &channel); + if (ret) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse reassoc command data", __func__); + goto exit; + } + + /* if the target bssid is same as currently associated AP, + issue reassoc to same AP */ + if (VOS_TRUE == vos_mem_compare(targetApBssid, + pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__); + sme_GetModifyProfileFields(hHal, pAdapter->sessionId, + &modProfileFields); + sme_RoamReassoc(hHal, pAdapter->sessionId, + NULL, modProfileFields, &roamId, 1); + ret = 0; + goto exit; + } + + /* Check channel number is a valid channel number */ + if(VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter, channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d] \n", __func__, channel); + + ret = -EINVAL; + goto exit; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pHddCtx->cfg_ini->isRoamOffloadEnabled) { + hdd_wma_send_fastreassoc_cmd((int)pAdapter->sessionId, targetApBssid, + (int) channel); + goto exit; + } +#endif + /* Proceed with reassoc */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + handoffInfo.channel = channel; + handoffInfo.src = FASTREASSOC; + vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr)); + sme_HandoffRequest(pHddCtx->hHal, pAdapter->sessionId, &handoffInfo); +#endif + } +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + else if (strncmp(command, "CCXPLMREQ", 9) == 0) + { + tANI_U8 *value = command; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirPlmReq pPlmRequest = NULL; + + pPlmRequest = vos_mem_malloc(sizeof(tSirPlmReq)); + if (NULL == pPlmRequest){ + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_plm_cmd(value, pPlmRequest); + if (eHAL_STATUS_SUCCESS != status){ + vos_mem_free(pPlmRequest); + pPlmRequest = NULL; + ret = -EINVAL; + goto exit; + } + pPlmRequest->sessionId = pAdapter->sessionId; + + status = sme_SetPlmRequest(pHddCtx->hHal, pPlmRequest); + if (eHAL_STATUS_SUCCESS != status) + { + vos_mem_free(pPlmRequest); + pPlmRequest = NULL; + ret = -EINVAL; + goto exit; + } + } +#endif +#ifdef FEATURE_WLAN_ESE + else if (strncmp(command, "SETCCXMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (sme_getIsEseFeatureEnabled(pHddCtx->hHal) && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled(pHddCtx->hHal)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + /* Move pointer to ahead of SETCCXMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &eseMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) || + (eseMode > CFG_ESE_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Ese mode value %d is out of range" + " (Min: %d Max: %d)", eseMode, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change ese mode = %d", __func__, eseMode); + + pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode; + sme_UpdateIsEseFeatureEnabled(pHddCtx->hHal, pAdapter->sessionId, + eseMode); + } +#endif + else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN roamScanControl = 0; + + /* Move pointer to ahead of SETROAMSCANCONTROL */ + value = value + 19; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanControl); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed ", __func__); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl); + + if (0 != roamScanControl) + { + ret = 0; /* return success but ignore param value "TRUE" */ + goto exit; + } + + sme_SetRoamScanControl(pHddCtx->hHal, + pAdapter->sessionId, roamScanControl); + } +#ifdef FEATURE_WLAN_OKC + else if (strncmp(command, "SETOKCMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (sme_getIsEseFeatureEnabled(pHddCtx->hHal) && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled(pHddCtx->hHal)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + /* Move pointer to ahead of SETOKCMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &okcMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) || + (okcMode > CFG_OKC_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Okc mode value %d is out of range" + " (Min: %d Max: %d)", okcMode, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change okc mode = %d", __func__, okcMode); + + pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode; + } +#endif /* FEATURE_WLAN_OKC */ + else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0) + { + tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + command, roamScanControl); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#ifdef WLAN_FEATURE_PACKET_FILTERING + else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0) + { + tANI_U8 filterType = 0; + tANI_U8 *value = command; + + /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6 */ + value = value + 22; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &filterType); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range ", __func__); + ret = -EINVAL; + goto exit; + } + + if (filterType != 0 && filterType != 1) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Accepted Values are 0 and 1 ", __func__); + ret = -EINVAL; + goto exit; + } + wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType, + pAdapter->sessionId); + } +#endif + else if (strncmp(command, "BTCOEXMODE", 10) == 0 ) + { + char *bcMode; + bcMode = command + 11; + if ('1' == *bcMode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + FL("BTCOEXMODE %d"), *bcMode); + pHddCtx->btCoexModeSet = TRUE; + } + else if ('2' == *bcMode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + FL("BTCOEXMODE %d"), *bcMode); + pHddCtx->btCoexModeSet = FALSE; + } + } + else if (strncmp(command, "SCAN-ACTIVE", 11) == 0) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; + } + else if (strncmp(command, "SCAN-PASSIVE", 12) == 0) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->ioctl_scan_mode = eSIR_PASSIVE_SCAN; + } + else if (strncmp(command, "GETDWELLTIME", 12) == 0) + { + hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + char extra[32]; + tANI_U8 len = 0; + + memset(extra, 0, sizeof(extra)); + ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len); + if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = len; + } + else if (strncmp(command, "SETDWELLTIME", 12) == 0) + { + ret = hdd_set_dwell_time(pAdapter, command); + } + else if ( strncasecmp(command, "MIRACAST", 8) == 0 ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received MIRACAST command", __func__); + + ret = hdd_set_miracast_mode(pAdapter, command); + } + else if (strncmp(command, "SETRMCTXRATE", 12) == 0) + { + tANI_U8 *value = command; + tANI_U32 uRate = 0; + tTxrateinfoflags txFlags = 0; + tSirRateUpdateInd *rateUpdateParams; + int status; + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (WLAN_HDD_SOFTAP != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received SETRMCTXRATE command in invalid mode %d" + "SETRMC command is only allowed in IBSS or SOFTAP mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid SETRMCTXRATE command "); + ret = -EINVAL; + goto exit; + } + + rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdateParams) + { + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: uRate %d ", __func__, uRate); + + vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd )); + + /* -1 implies ignore this param */ + rateUpdateParams->ucastDataRate = -1; + + /* + * Fill the user specified RMC rate param + * and the derived tx flags. + */ + rateUpdateParams->nss = (pConfig->enable2x2 == 0) ? 0 : 1; + rateUpdateParams->reliableMcastDataRate = uRate; + rateUpdateParams->reliableMcastDataRateTxFlag = txFlags; + rateUpdateParams->dev_mode = pAdapter->device_mode; + rateUpdateParams->bcastDataRate = -1; + memcpy(rateUpdateParams->bssid, pAdapter->macAddressCurrent.bytes, + sizeof(rateUpdateParams->bssid)); + status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), + rateUpdateParams); + } + + +#ifdef FEATURE_WLAN_BATCH_SCAN + else if (strncmp(command, "WLS_BATCHING", 12) == 0) + { + ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command); + } +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0) + { + tANI_U8 *value = command; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + eHalStatus status; + ret = hdd_parse_channellist(value, ChannelList, &numChannels); + if (ret) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse channel list information", __func__); + goto exit; + } + if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_ERROR, + "%s: number of channels (%d) supported exceeded max (%d)", + __func__, + numChannels, + WNI_CFG_VALID_CHANNEL_LIST_LEN); + ret = -EINVAL; + goto exit; + } + status = sme_SetEseRoamScanChannelList(pHddCtx->hHal, + pAdapter->sessionId, + ChannelList, + numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update channel list information", __func__); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "GETTSMSTATS", 11) == 0) + { + tANI_U8 *value = command; + char extra[128] = {0}; + int len = 0; + tANI_U8 tid = 0; + hdd_station_ctx_t *pHddStaCtx = NULL; + tAniTrafStrmMetrics tsmMetrics; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + /* if not associated, return error */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_ERROR, + "%s:Not associated!", + __func__); + ret = -EINVAL; + goto exit; + } + /* Move pointer to ahead of GETTSMSTATS */ + value = value + 12; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &tid); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, + * then also + * kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + TID_MIN_VALUE, + TID_MAX_VALUE); + ret = -EINVAL; + goto exit; + } + if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "tid value %d is out of range" + " (Min: %d Max: %d)", tid, + TID_MIN_VALUE, + TID_MAX_VALUE); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_INFO, + "%s: Received Command to get tsm stats tid = %d", + __func__, + tid); + if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to get tsm stats", __func__); + ret = -EFAULT; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_INFO, + "UplinkPktQueueDly(%d)" + "UplinkPktQueueDlyHist[0](%d)" + "UplinkPktQueueDlyHist[1](%d)" + "UplinkPktQueueDlyHist[2](%d)" + "UplinkPktQueueDlyHist[3](%d)" + "UplinkPktTxDly(%u)" + "UplinkPktLoss(%d)" + "UplinkPktCount(%d)" + "RoamingCount(%d)" + "RoamingDly(%d)", + tsmMetrics.UplinkPktQueueDly, + tsmMetrics.UplinkPktQueueDlyHist[0], + tsmMetrics.UplinkPktQueueDlyHist[1], + tsmMetrics.UplinkPktQueueDlyHist[2], + tsmMetrics.UplinkPktQueueDlyHist[3], + tsmMetrics.UplinkPktTxDly, + tsmMetrics.UplinkPktLoss, + tsmMetrics.UplinkPktCount, + tsmMetrics.RoamingCount, + tsmMetrics.RoamingDly); + /* Output TSM stats is of the format + * GETTSMSTATS [PktQueueDly] + * [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly] + * eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */ + len = scnprintf(extra, + sizeof(extra), + "%s %d %d:%d:%d:%d %u %d %d %d %d", + command, + tsmMetrics.UplinkPktQueueDly, + tsmMetrics.UplinkPktQueueDlyHist[0], + tsmMetrics.UplinkPktQueueDlyHist[1], + tsmMetrics.UplinkPktQueueDlyHist[2], + tsmMetrics.UplinkPktQueueDlyHist[3], + tsmMetrics.UplinkPktTxDly, + tsmMetrics.UplinkPktLoss, + tsmMetrics.UplinkPktCount, + tsmMetrics.RoamingCount, + tsmMetrics.RoamingDly); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETCCKMIE", 9) == 0) + { + tANI_U8 *value = command; + tANI_U8 *cckmIe = NULL; + tANI_U8 cckmIeLen = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse cckm ie data", __func__); + ret = -EINVAL; + goto exit; + } + if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: CCKM Ie input length is more than max[%d]", __func__, + DOT11F_IE_RSN_MAX_LEN); + if (NULL != cckmIe) + { + vos_mem_free(cckmIe); + cckmIe = NULL; + } + ret = -EINVAL; + goto exit; + } + sme_SetCCKMIe(pHddCtx->hHal, pAdapter->sessionId, cckmIe, cckmIeLen); + if (NULL != cckmIe) + { + vos_mem_free(cckmIe); + cckmIe = NULL; + } + } + else if (strncmp(command, "CCXBEACONREQ", 12) == 0) + { + tANI_U8 *value = command; + tCsrEseBeaconReq eseBcnReq; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = hdd_parse_ese_beacon_req(value, &eseBcnReq); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse ese beacon req", __func__); + ret = -EINVAL; + goto exit; + } + + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated")); + hdd_indicateEseBcnReportNoResults (pAdapter, + eseBcnReq.bcnReq[0].measurementToken, + 0x02, //BIT(1) set for measurement done + 0); // no BSS + goto exit; + } + + status = sme_SetEseBeaconRequest(pHddCtx->hHal, + pAdapter->sessionId, + &eseBcnReq); + + if (eHAL_STATUS_RESOURCES == status) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("sme_SetEseBeaconRequest failed (%d)," + " a request already in progress"), status); + ret = -EBUSY; + goto exit; + } else if (eHAL_STATUS_SUCCESS != status) { + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_ERROR, + "%s: sme_SetEseBeaconRequest failed (%d)", + __func__, + status); + ret = -EINVAL; + goto exit; + } + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + else if (strncmp(command, "SETMCRATE", 9) == 0) + { + tANI_U8 *value = command; + int targetRate; + /* Move pointer to ahead of SETMCRATE */ + /* input value is in units of hundred kbps */ + value = value + 10; + /* Convert the value from ascii to integer, decimal base */ + ret = kstrtouint(value, 10, &targetRate); + ret = wlan_hdd_set_mc_rate(pAdapter, targetRate); + } + else if (strncmp(command, "MAXTXPOWER", 10) == 0) + { + int status; + int txPower; + VOS_STATUS vosStatus; + eHalStatus smeStatus; + tANI_U8 *value = command; + hdd_adapter_t *pAdapter; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + status = hdd_parse_setmaxtxpower_command(value, &txPower); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAXTXPOWER command "); + ret = -EINVAL; + goto exit; + } + + vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vosStatus ) + { + pAdapter = pAdapterNode->pAdapter; + /* Assign correct self MAC address */ + vos_mem_copy(bssid, pAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(selfMac, pAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + + hddLog(VOS_TRACE_LEVEL_INFO, "Device mode %d max tx power %d" + " selfMac: " MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ", + pAdapter->device_mode, txPower, MAC_ADDR_ARRAY(selfMac), + MAC_ADDR_ARRAY(bssid)); + smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal), bssid, + selfMac, txPower); + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed", + __func__); + ret = -EINVAL; + goto exit; + } + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success", + __func__); + vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + } + else if (strncmp(command, "SETDFSSCANMODE", 14) == 0) + { + tANI_U8 *value = command; + tANI_U8 dfsScanMode = CFG_ROAMING_DFS_CHANNEL_DEFAULT; + + /* Move pointer to ahead of SETDFSSCANMODE */ + value = value + 15; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &dfsScanMode); + if (ret < 0) + { + /* If the input value is greater than max value of + * datatype, then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX); + ret = -EINVAL; + goto exit; + } + + if ((dfsScanMode < CFG_ROAMING_DFS_CHANNEL_MIN) || + (dfsScanMode > CFG_ROAMING_DFS_CHANNEL_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "dfsScanMode value %d is out of range" + " (Min: %d Max: %d)", dfsScanMode, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set DFS Scan Mode = %d", + __func__, dfsScanMode); + + pHddCtx->cfg_ini->allowDFSChannelRoam = dfsScanMode; + sme_UpdateDFSScanMode(pHddCtx->hHal, pAdapter->sessionId, + dfsScanMode); + } + else if (strncmp(command, "GETDFSSCANMODE", 14) == 0) + { + tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETLINKSTATUS", 13) == 0) { + int value = wlan_hdd_get_link_status(pAdapter); + char extra[32]; + tANI_U8 len = 0; + len = scnprintf(extra, sizeof(extra), "%s %d", command, value); + if (copy_to_user(priv_data.buf, &extra, len + 1)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + else if (strncmp(command, "ENABLEEXTWOW", 12) == 0) { + + tANI_U8 *value = command; + int set_value; + + /* Move pointer to ahead of ENABLEEXTWOW*/ + value += 12; + sscanf(value, "%d", &set_value); + ret = hdd_enable_ext_wow_parser(pAdapter, + pAdapter->sessionId, set_value); + + } else if (strncmp(command, "SETAPP1PARAMS", 13) == 0) { + tANI_U8 *value = command; + + /* Move pointer to ahead of SETAPP1PARAMS*/ + value += 13; + ret = hdd_set_app_type1_parser(pAdapter, + value, strlen(value)); + if (ret >= 0) + pHddCtx->is_extwow_app_type1_param_set = TRUE; + + } else if (strncmp(command, "SETAPP2PARAMS", 13) == 0) { + tANI_U8 *value = command; + + /* Move pointer to ahead of SETAPP2PARAMS*/ + value += 13; + ret = hdd_set_app_type2_parser(pAdapter, + value, strlen(value)); + if (ret >= 0) + pHddCtx->is_extwow_app_type2_param_set = TRUE; + } +#endif +#ifdef FEATURE_WLAN_TDLS + else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 26; + sscanf(value, "%d", &set_value); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel offset:%d"), + set_value); + ret = hdd_set_tdls_secoffchanneloffset(pHddCtx, set_value); + } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 18; + sscanf(value, "%d", &set_value); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel mode:%d"), + set_value); + ret = hdd_set_tdls_offchannelmode(pAdapter, set_value); + } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 14; + ret = sscanf(value, "%d", &set_value); + if (ret != 1) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Wrong value is given for hdd_set_tdls_offchannel"); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel num: %d"), set_value); + ret = hdd_set_tdls_offchannel(pHddCtx, set_value); + } else if (strncmp(command, "TDLSSCAN", 8) == 0) { + uint8_t *value = command; + int set_value; + /* Move pointer to point the string */ + value += 8; + ret = sscanf(value, "%d", &set_value); + if (ret != 1) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Wrong value is given for tdls_scan_type"); + ret = -EINVAL; + goto exit; + } + hddLog(LOG1, FL("Tdls scan type val: %d"), + set_value); + ret = hdd_set_tdls_scan_type(pHddCtx, set_value); + } +#endif + else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0) { + /* + * this command wld be called by user-space when it detects WLAN + * ON after airplane mode is set. When APM is set, WLAN turns off. + * But it can be turned back on. Otherwise; when APM is turned back + * off, WLAN wld turn back on. So at that point the command is + * expected to come down. 0 means disable, 1 means enable. The + * constraint is removed when parameter 1 is set or different + * country code is set + */ + + ret = drv_cmd_set_fcc_channel(pHddCtx, command, 15); + + } else { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_UNSUPPORTED_IOCTL, + pAdapter->sessionId, 0)); + hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s", + __func__, command); + } + + } +exit: + if (command) + { + kfree(command); + } + return ret; +} + +#ifdef CONFIG_COMPAT +static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + struct { + compat_uptr_t buf; + int used_len; + int total_len; + } compat_priv_data; + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&compat_priv_data, ifr->ifr_data, + sizeof(compat_priv_data))) { + ret = -EFAULT; + goto exit; + } + priv_data.buf = compat_ptr(compat_priv_data.buf); + priv_data.used_len = compat_priv_data.used_len; + priv_data.total_len = compat_priv_data.total_len; + ret = hdd_driver_command(pAdapter, &priv_data); + exit: + return ret; +} +#else /* CONFIG_COMPAT */ +static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + /* will never be invoked */ + return 0; +} +#endif /* CONFIG_COMPAT */ + +static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) { + ret = -EFAULT; + } else { + ret = hdd_driver_command(pAdapter, &priv_data); + } + return ret; +} + +int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + long ret = 0; + + if (dev != pAdapter->dev) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto exit; + } + + if ((!ifr) || (!ifr->ifr_data)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid data", __func__); + ret = -EINVAL; + goto exit; + } + +#if defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR) + if (VOS_FTM_MODE == hdd_get_conparam()) { + if (SIOCIOCTLTX99 == cmd) { + ret = wlan_hdd_qcmbr_unified_ioctl(pAdapter, ifr); + goto exit; + } + } +#endif + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + ret = -EBUSY; + goto exit; + } + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + if (is_compat_task()) + ret = hdd_driver_compat_ioctl(pAdapter, ifr); + else + ret = hdd_driver_ioctl(pAdapter, ifr); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + exit: + return ret; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief hdd_parse_ese_beacon_req() - Parse ese beacon request + + This function parses the ese beacon request passed in the format + CCXBEACONREQ + Channel 1Scan Mode Meas DurationChannel N + Scan Mode NMeas Duration N + if the Number of bcn req fields (N) does not match with the actual number of fields passed + then take N. + and are treated as one pair + For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40. + This function does not take care of removing duplicate channels from the list + + \param - pValue Pointer to data + \param - pEseBcnReq output pointer to store parsed ie information + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue, + tCsrEseBeaconReq *pEseBcnReq) +{ + tANI_U8 *inPtr = pValue; + int tempInt = 0; + int j = 0, i = 0, v = 0; + char buf[32]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) return -EINVAL; + + /*getting the first argument ie measurement token*/ + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if ( v < 0) return -EINVAL; + + pEseBcnReq->numBcnReqIe = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe); + + for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++) + { + for (i = 0; i < 4; i++) + { + /*inPtr pointing to the beginning of first space after number of ie fields*/ + inPtr = strpbrk( inPtr, " " ); + /*no ie data after the number of ie fields argument*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty space*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no ie data after the number of ie fields argument and spaces*/ + if ( '\0' == *inPtr ) return -EINVAL; + + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if (v < 0) return -EINVAL; + + switch (i) + { + case 0: /* Measurement token */ + if (tempInt <= 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Measurement Token(%d)", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].measurementToken = tempInt; + break; + + case 1: /* Channel number */ + if ((tempInt <= 0) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Channel Number(%d)", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].channel = tempInt; + break; + + case 2: /* Scan mode */ + if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].scanMode= tempInt; + break; + + case 3: /* Measurement duration */ + if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) || + ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Measurement Duration(%d)", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].measurementDuration = tempInt; + break; + } + } + } + + for (j = 0; j < pEseBcnReq->numBcnReqIe; j++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Index(%d) Measurement Token(%u) Channel(%u) Scan Mode(%u) Measurement Duration(%u)", + j, + pEseBcnReq->bcnReq[j].measurementToken, + pEseBcnReq->bcnReq[j].channel, + pEseBcnReq->bcnReq[j].scanMode, + pEseBcnReq->bcnReq[j].measurementDuration); + } + + return VOS_STATUS_SUCCESS; +} + +static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, + const tANI_U32 staId, + void *pContext ) +{ + struct statsContext *pStatsContext = NULL; + hdd_adapter_t *pAdapter = NULL; + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the tsm stats */ + pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly; + vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist, + tsmMetrics.UplinkPktQueueDlyHist, + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); + pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly; + pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss; + pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount; + pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount; + pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, + const tANI_U8 tid, + tAniTrafStrmMetrics* pTsmMetrics) +{ + hdd_station_ctx_t *pHddStaCtx = NULL; + eHalStatus hstatus; + VOS_STATUS vstatus = VOS_STATUS_SUCCESS; + unsigned long rc; + struct statsContext context; + hdd_context_t *pHddCtx = NULL; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* we are connected prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + + /* query tsm stats */ + hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context, pHddCtx->pvosContext, tid); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics", + __func__); + vstatus = VOS_STATUS_E_FAULT; + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timed out while retrieving statistics", + __func__); + vstatus = VOS_STATUS_E_TIMEOUT; + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + if (VOS_STATUS_SUCCESS == vstatus) + { + pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly; + vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist, + pAdapter->tsmStats.UplinkPktQueueDlyHist, + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); + pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly; + pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss; + pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount; + pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount; + pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly; + } + return vstatus; +} +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand) +{ + eCsrBand band = -1; + sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band); + switch (band) + { + case eCSR_BAND_ALL: + *pBand = WLAN_HDD_UI_BAND_AUTO; + break; + + case eCSR_BAND_24: + *pBand = WLAN_HDD_UI_BAND_2_4_GHZ; + break; + + case eCSR_BAND_5G: + *pBand = WLAN_HDD_UI_BAND_5_GHZ; + break; + + default: + hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band); + *pBand = -1; + break; + } +} + +/* + * Mac address for multiple virtual interface is found as following + * i) The mac address of the first interface is just the actual hw mac address. + * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to + * define the mac address for the remaining interfaces and locally + * administered bit is set. INTF_MACADDR_MASK is based on the number of + * supported virtual interfaces, right now this is 0x07 (meaning 8 interface). + * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1, + * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc. + */ + +void hdd_update_macaddr(hdd_config_t *cfg_ini, v_MACADDR_t hw_macaddr) +{ + int8_t i; + u_int8_t macaddr_b3, tmp_br3; + + vos_mem_copy(cfg_ini->intfMacAddr[0].bytes, hw_macaddr.bytes, + VOS_MAC_ADDR_SIZE); + for (i = 1; i < VOS_MAX_CONCURRENCY_PERSONA; i++) { + vos_mem_copy(cfg_ini->intfMacAddr[i].bytes, hw_macaddr.bytes, + VOS_MAC_ADDR_SIZE); + macaddr_b3 = cfg_ini->intfMacAddr[i].bytes[3]; + tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & + INTF_MACADDR_MASK; + macaddr_b3 += tmp_br3; + + /* XOR-ing bit-24 of the mac address. This will give enough + * mac address range before collision + */ + macaddr_b3 ^= (1 << 7); + + /* Set locally administered bit */ + cfg_ini->intfMacAddr[i].bytes[0] |= 0x02; + cfg_ini->intfMacAddr[i].bytes[3] = macaddr_b3; + hddLog(VOS_TRACE_LEVEL_INFO, "cfg_ini->intfMacAddr[%d]: " + MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(cfg_ini->intfMacAddr[i].bytes)); + } +} + +static void hdd_update_tgt_services(hdd_context_t *hdd_ctx, + struct hdd_tgt_services *cfg) +{ + hdd_config_t *cfg_ini = hdd_ctx->cfg_ini; + tpAniSirGlobal pMac = PMAC_STRUCT(hdd_ctx->hHal); + + /* Set up UAPSD */ + cfg_ini->apUapsdEnabled &= cfg->uapsd; + +#ifdef WLAN_FEATURE_11AC + /* 11AC mode support */ + if ((cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac || + cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && + !cfg->en_11ac) + cfg_ini->dot11Mode = eHDD_DOT11_MODE_AUTO; +#endif /* #ifdef WLAN_FEATURE_11AC */ + + /* ARP offload: override user setting if invalid */ + cfg_ini->fhostArpOffload &= cfg->arp_offload; + +#ifdef FEATURE_WLAN_SCAN_PNO + /* PNO offload */ + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: PNO Capability in f/w = %d", + __func__,cfg->pno_offload); + if (cfg->pno_offload) + cfg_ini->PnoOffload = TRUE; +#endif + pMac->lteCoexAntShare = cfg->lte_coex_ant_share; +#ifdef FEATURE_WLAN_TDLS + cfg_ini->fEnableTDLSSupport &= cfg->en_tdls; + cfg_ini->fEnableTDLSOffChannel &= cfg->en_tdls_offchan; + cfg_ini->fEnableTDLSBufferSta &= cfg->en_tdls_uapsd_buf_sta; + if (cfg_ini->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta) + { + cfg_ini->fEnableTDLSSleepSta = TRUE; + } + else + { + cfg_ini->fEnableTDLSSleepSta = FALSE; + } +#endif + pMac->beacon_offload = cfg->beacon_offload; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + cfg_ini->isRoamOffloadEnabled &= cfg->en_roam_offload; +#endif + +} + +static void hdd_update_tgt_ht_cap(hdd_context_t *hdd_ctx, + struct hdd_tgt_ht_cap *cfg) +{ + eHalStatus status; + tANI_U32 value, val32; + tANI_U16 val16; + hdd_config_t *pconfig = hdd_ctx->cfg_ini; + tSirMacHTCapabilityInfo *phtCapInfo; + tANI_U8 mcs_set[SIZE_OF_SUPPORTED_MCS_SET]; + uint8_t enable_tx_stbc; + + /* check and update RX STBC */ + if (pconfig->enableRxSTBC && !cfg->ht_rx_stbc) + pconfig->enableRxSTBC = cfg->ht_rx_stbc; + + /* get the MPDU density */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get MPDU DENSITY", + __func__); + value = 0; + } + + /* + * MPDU density: + * override user's setting if value is larger + * than the one supported by target + */ + if (value > cfg->mpdu_density) { + status = ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_MPDU_DENSITY, + cfg->mpdu_density, + NULL, eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set MPDU DENSITY to CCM", + __func__); + } + + /* get the HT capability info*/ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, &val32); + if (eHAL_STATUS_SUCCESS != status) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get HT capability info", + __func__); + return; + } + val16 = (tANI_U16)val32; + phtCapInfo = (tSirMacHTCapabilityInfo *)&val16; + + /* Set the LDPC capability */ + phtCapInfo->advCodingCap = cfg->ht_rx_ldpc; + + + if (pconfig->ShortGI20MhzEnable && !cfg->ht_sgi_20) + pconfig->ShortGI20MhzEnable = cfg->ht_sgi_20; + + if (pconfig->ShortGI40MhzEnable && !cfg->ht_sgi_40) + pconfig->ShortGI40MhzEnable = cfg->ht_sgi_40; + + hdd_ctx->num_rf_chains = cfg->num_rf_chains; + hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc; + + enable_tx_stbc = pconfig->enableTxSTBC; + + if (pconfig->enable2x2 && (cfg->num_rf_chains == 2)) + { + pconfig->enable2x2 = 1; + } + else + { + pconfig->enable2x2 = 0; + enable_tx_stbc = 0; + + /* 1x1 */ + /* Update Rx Highest Long GI data Rate */ + if (ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, "Could not pass on " + "WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE to CCM"); + } + + /* Update Tx Highest Long GI data Rate */ + if (ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + HDD_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, "Could not pass on " + "HDD_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1 to CCM"); + } + } + if (!(cfg->ht_tx_stbc && pconfig->enable2x2)) + { + enable_tx_stbc = 0; + } + phtCapInfo->txSTBC = enable_tx_stbc; + val32 = val16; + status = ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_HT_CAP_INFO, + val32, NULL, eANI_BOOLEAN_FALSE); + if (status != eHAL_STATUS_SUCCESS) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set HT capability to CCM", + __func__); +#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff + value = SIZE_OF_SUPPORTED_MCS_SET; + if (ccmCfgGetStr(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, mcs_set, + &value) == eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Read MCS rate set", __func__); + + if (pconfig->enable2x2) + { + for (value = 0; value < cfg->num_rf_chains; value++) + mcs_set[value] = WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; + + status = ccmCfgSetStr(hdd_ctx->hHal, WNI_CFG_SUPPORTED_MCS_SET, + mcs_set, SIZE_OF_SUPPORTED_MCS_SET, NULL, + eANI_BOOLEAN_FALSE); + if (status == eHAL_STATUS_FAILURE) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set MCS SET to CCM", __func__); + } + } +#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES +} + +#ifdef WLAN_FEATURE_11AC +static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx, + struct hdd_tgt_vht_cap *cfg) +{ + eHalStatus status; + tANI_U32 value = 0; + hdd_config_t *pconfig = hdd_ctx->cfg_ini; + + /* Get the current MPDU length */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_MAX_MPDU_LENGTH, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get MPDU LENGTH", + __func__); + value = 0; + } + + /* + * VHT max MPDU length: + * override if user configured value is too high + * that the target cannot support + */ + if (value > cfg->vht_max_mpdu) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_MAX_MPDU_LENGTH, + cfg->vht_max_mpdu, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT MAX MPDU LENGTH", + __func__); + } + } + + /* Get the current supported chan width */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get MPDU LENGTH", + __func__); + value = 0; + } + + /* + * Update VHT supported chan width: + * if user setting is invalid, override it with + * target capability + */ + if ((value == eHT_CHANNEL_WIDTH_80MHZ && + !(cfg->supp_chan_width & eHT_CHANNEL_WIDTH_80MHZ)) || + (value == eHT_CHANNEL_WIDTH_160MHZ && + !(cfg->supp_chan_width & eHT_CHANNEL_WIDTH_160MHZ))) { + u_int32_t width = eHT_CHANNEL_WIDTH_20MHZ; + + if (cfg->supp_chan_width & eHT_CHANNEL_WIDTH_160MHZ) + width = eHT_CHANNEL_WIDTH_160MHZ; + else if (cfg->supp_chan_width & eHT_CHANNEL_WIDTH_80MHZ) + width = eHT_CHANNEL_WIDTH_80MHZ; + + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + width, NULL, eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT SUPPORTED CHAN WIDTH", + __func__); + } + } + + /* Get the current RX LDPC setting */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_LDPC_CODING_CAP, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT LDPC CODING CAP", + __func__); + value = 0; + } + + /* Set the LDPC capability */ + if (value && !cfg->vht_rx_ldpc) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_LDPC_CODING_CAP, + cfg->vht_rx_ldpc, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT LDPC CODING CAP to CCM", + __func__); + } + } + + /* Get current GI 80 value */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get SHORT GI 80MHZ", + __func__); + value = 0; + } + + /* set the Guard interval 80MHz */ + if (value && !cfg->vht_short_gi_80) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SHORT_GI_80MHZ, + cfg->vht_short_gi_80, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set SHORT GI 80MHZ to CCM", + __func__); + } + } + + /* Get current GI 160 value */ + status = ccmCfgGetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get SHORT GI 80 & 160", + __func__); + value = 0; + } + + /* set the Guard interval 160MHz */ + if (value && !cfg->vht_short_gi_160) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + cfg->vht_short_gi_160, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set SHORT GI 80 & 160 to CCM", + __func__); + } + } + + /* Get VHT TX STBC cap */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT TX STBC", + __func__); + value = 0; + } + + /* VHT TX STBC cap */ + if (value && !cfg->vht_tx_stbc) { + status = ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TXSTBC, + cfg->vht_tx_stbc, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set the VHT TX STBC to CCM", + __func__); + } + } + + /* Get VHT RX STBC cap */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT RX STBC", + __func__); + value = 0; + } + + /* VHT RX STBC cap */ + if (value && !cfg->vht_rx_stbc) { + status = ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_RXSTBC, + cfg->vht_rx_stbc, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set the VHT RX STBC to CCM", + __func__); + } + } + + /* Get VHT SU Beamformer cap */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_SU_BEAMFORMER_CAP, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT SU BEAMFORMER CAP", + __func__); + value = 0; + } + + /* set VHT SU Beamformer cap */ + if (value && !cfg->vht_su_bformer) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SU_BEAMFORMER_CAP, + cfg->vht_su_bformer, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT SU BEAMFORMER CAP", + __func__); + } + } + + /* check and update SU BEAMFORMEE capability*/ + if (pconfig->enableTxBF && !cfg->vht_su_bformee) + pconfig->enableTxBF = cfg->vht_su_bformee; + + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + pconfig->enableTxBF, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT SU BEAMFORMEE CAP", + __func__); + } + + /* Get VHT MU Beamformer cap */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMER_CAP, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT MU BEAMFORMER CAP", + __func__); + value = 0; + } + + /* set VHT MU Beamformer cap */ + if (value && !cfg->vht_mu_bformer) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_MU_BEAMFORMER_CAP, + cfg->vht_mu_bformer, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set the VHT MU BEAMFORMER CAP to CCM", + __func__); + } + } + + /* Get VHT MU Beamformee cap */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT MU BEAMFORMEE CAP", + __func__); + value = 0; + } + + /* set VHT MU Beamformee cap */ + if (value && !cfg->vht_mu_bformee) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + cfg->vht_mu_bformee, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set VHT MU BEAMFORMER CAP", + __func__); + } + } + + /* Get VHT MAX AMPDU Len exp */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT AMPDU LEN", + __func__); + value = 0; + } + + /* + * VHT max AMPDU len exp: + * override if user configured value is too high + * that the target cannot support. + * Even though Rome publish ampdu_len=7, it can + * only support 4 because of some h/w bug. + */ + + if (value > cfg->vht_max_ampdu_len_exp) { + status = ccmCfgSetInt(hdd_ctx->hHal, + WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + cfg->vht_max_ampdu_len_exp, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set the VHT AMPDU LEN EXP", + __func__); + } + } + + /* Get VHT TXOP PS CAP */ + status = ccmCfgGetInt(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, &value); + + if (status != eHAL_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get VHT TXOP PS", + __func__); + value = 0; + } + + /* set VHT TXOP PS cap */ + if (value && !cfg->vht_txop_ps) { + status = ccmCfgSetInt(hdd_ctx->hHal, WNI_CFG_VHT_TXOP_PS, + cfg->vht_txop_ps, NULL, + eANI_BOOLEAN_FALSE); + + if (status == eHAL_STATUS_FAILURE) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: could not set the VHT TXOP PS", + __func__); + } + } +} +#endif /* #ifdef WLAN_FEATURE_11AC */ + +void hdd_update_tgt_cfg(void *context, void *param) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)context; + struct hdd_tgt_cfg *cfg = (struct hdd_tgt_cfg *)param; + tANI_U8 temp_band_cap; + + /* first store the INI band capability */ + temp_band_cap = hdd_ctx->cfg_ini->nBandCapability; + + hdd_ctx->cfg_ini->nBandCapability = cfg->band_cap; + + /* now overwrite the target band capability with INI + setting if INI setting is a subset */ + + if ((hdd_ctx->cfg_ini->nBandCapability == eCSR_BAND_ALL) && + (temp_band_cap != eCSR_BAND_ALL)) + hdd_ctx->cfg_ini->nBandCapability = temp_band_cap; + else if ((hdd_ctx->cfg_ini->nBandCapability != eCSR_BAND_ALL) && + (temp_band_cap != eCSR_BAND_ALL) && + (hdd_ctx->cfg_ini->nBandCapability != temp_band_cap)) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("ini BandCapability not supported by the target")); + } + + if (!hdd_ctx->isLogpInProgress) { + hdd_ctx->reg.reg_domain = cfg->reg_domain; + hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext; + } + + /* This can be extended to other configurations like ht, vht cap... */ + + if (!vos_is_macaddr_zero(&cfg->hw_macaddr)) + { + hdd_update_macaddr(hdd_ctx->cfg_ini, cfg->hw_macaddr); + } + else { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid MAC passed from target, using MAC from ini file" + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(hdd_ctx->cfg_ini->intfMacAddr[0].bytes)); + } + + hdd_ctx->target_fw_version = cfg->target_fw_version; + + hdd_ctx->max_intf_count = cfg->max_intf_count; + +#ifdef WLAN_FEATURE_LPSS + hdd_ctx->lpss_support = cfg->lpss_support; +#endif + + hdd_update_tgt_services(hdd_ctx, &cfg->services); + + hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); + +#ifdef WLAN_FEATURE_11AC + hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); +#endif /* #ifdef WLAN_FEATURE_11AC */ +} + +/* This function is invoked when a radar in found on the + * SAP current operating channel and Data Tx from netif + * has to be stopped to honor the DFS regulations. + * Actions: Stop the netif Tx queues,Indicate Radar present + * in HDD context for future usage. + */ +void hdd_dfs_indicate_radar(void *context, void *param) +{ + hdd_context_t *pHddCtx= (hdd_context_t *)context; + struct hdd_dfs_radar_ind *hdd_radar_event = + (struct hdd_dfs_radar_ind*)param; + hdd_adapter_list_node_t *pAdapterNode = NULL, + *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + if (pHddCtx == NULL) + { + return; + } + if (hdd_radar_event == NULL) + { + return; + } + + if (pHddCtx->cfg_ini->disableDFSChSwitch) + { + return; + } + + if (VOS_TRUE == hdd_radar_event->dfs_radar_status) + { + pHddCtx->dfs_radar_found = VOS_TRUE; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) + { + WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->dfs_cac_block_tx = VOS_TRUE; + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data + + This function parses the send action frame data passed in the format + SENDACTIONFRAME + + \param - pValue Pointer to input data + \param - pTargetApBssid Pointer to target Ap bssid + \param - pChannel Pointer to the Target AP channel + \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame + \param - pBuf Pointer to data + \param - pBufLen Pointer to data length + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_send_action_frame_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, + tANI_U8 *pChannel, tANI_U8 *pDwellTime, + tANI_U8 **pBuf, tANI_U8 *pBufLen) +{ + const tANI_U8 *inPtr = pValue; + const tANI_U8 *dataEnd; + int tempInt; + int j = 0; + int i = 0; + int v = 0; + tANI_U8 tempBuf[32]; + tANI_U8 tempByte = 0; + /* 12 hexa decimal digits, 5 ':' and '\0' */ + tANI_U8 macAddress[18]; + + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + v = sscanf(inPtr, "%17s", macAddress); + if (!((1 == v) && hdd_is_valid_mac_address(macAddress))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAC address or All hex inputs are not read (%d)", v); + return -EINVAL; + } + + pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]); + pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]); + pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]); + pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]); + pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]); + pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]); + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the channel number */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ( v < 0 || tempInt < 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX ) + return -EINVAL; + + *pChannel = tempInt; + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the dwell time */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ( v < 0 || tempInt < 0) return -EINVAL; + + *pDwellTime = tempInt; + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /* find the length of data */ + dataEnd = inPtr; + while(('\0' != *dataEnd) ) + { + dataEnd++; + } + *pBufLen = dataEnd - inPtr ; + if ( *pBufLen <= 0) return -EINVAL; + + /* Allocate the number of bytes based on the number of input characters + whether it is even or odd. + if the number of input characters are even, then we need N/2 byte. + if the number of input characters are odd, then we need do (N+1)/2 to + compensate rounding off. + For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough. + If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */ + *pBuf = vos_mem_malloc((*pBufLen + 1)/2); + if (NULL == *pBuf) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return -EINVAL; + } + + /* the buffer received from the upper layer is character buffer, + we need to prepare the buffer taking 2 characters in to a U8 hex decimal number + for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st + and f0 in 3rd location */ + for (i = 0, j = 0; j < *pBufLen; j += 2) + { + if( j+1 == *pBufLen) + { + tempByte = hdd_parse_hex(inPtr[j]); + } + else + { + tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1])); + } + (*pBuf)[i++] = tempByte; + } + *pBufLen = i; + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_channellist() - HDD Parse channel list + + This function parses the channel list passed in the format + SETROAMSCANCHANNELSChannel 1Channel 2Channel N + if the Number of channels (N) does not match with the actual number of channels passed + then take the minimum of N and count of (Ch1, Ch2, ...Ch M) + For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken. + If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48. + This function does not take care of removing duplicate channels from the list + + \param - pValue Pointer to input channel list + \param - ChannelList Pointer to local output array to record channel list + \param - pNumChannels Pointer to number of roam scan channels + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_channellist(const tANI_U8 *pValue, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels) +{ + const tANI_U8 *inPtr = pValue; + int tempInt; + int j = 0; + int v = 0; + char buf[32]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the first argument ie the number of channels*/ + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if ((v < 0) || + (tempInt <= 0) || + (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN)) + { + return -EINVAL; + } + + *pNumChannels = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Number of channels are: %d", *pNumChannels); + + for (j = 0; j < (*pNumChannels); j++) + { + /*inPtr pointing to the beginning of first space after number of channels*/ + inPtr = strpbrk( inPtr, " " ); + /*no channel list after the number of channels argument*/ + if (NULL == inPtr) + { + if (0 != j) + { + *pNumChannels = j; + return 0; + } + else + { + return -EINVAL; + } + } + + /*removing empty space*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no channel list after the number of channels argument and spaces*/ + if ( '\0' == *inPtr ) + { + if (0 != j) + { + *pNumChannels = j; + return 0; + } + else + { + return -EINVAL; + } + } + + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if ((v < 0) || + (tempInt <= 0) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + return -EINVAL; + } + pChannelList[j] = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Channel %d added to preferred channel list", + pChannelList[j] ); + } + + return 0; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data + + This function parses the reasoc command data passed in the format + REASSOC + + \param - pValue Pointer to input data (its a NUL terminated string) + \param - pTargetApBssid Pointer to target Ap bssid + \param - pChannel Pointer to the Target AP channel + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, + tANI_U8 *pChannel) +{ + const tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + tANI_U8 tempBuf[32]; + /* 12 hexa decimal digits, 5 ':' and '\0' */ + tANI_U8 macAddress[18]; + + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + v = sscanf(inPtr, "%17s", macAddress); + if (!((1 == v) && hdd_is_valid_mac_address(macAddress))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAC address or All hex inputs are not read (%d)", v); + return -EINVAL; + } + + pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]); + pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]); + pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]); + pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]); + pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]); + pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]); + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the channel number */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ((v < 0) || + (tempInt < 0) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + return -EINVAL; + } + + *pChannel = tempInt; + return VOS_STATUS_SUCCESS; +} + +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE + This function parses the SETCCKM IE command + SETCCKMIE + \param - pValue Pointer to input data + \param - pCckmIe Pointer to output cckm Ie + \param - pCckmIeLen Pointer to output cckm ie length + \return - 0 for success non-zero for failure + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, + tANI_U8 *pCckmIeLen) +{ + tANI_U8 *inPtr = pValue; + tANI_U8 *dataEnd; + int j = 0; + int i = 0; + tANI_U8 tempByte = 0; + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + /* find the length of data */ + dataEnd = inPtr; + while(('\0' != *dataEnd) ) + { + dataEnd++; + ++(*pCckmIeLen); + } + if ( *pCckmIeLen <= 0) return -EINVAL; + /* + * Allocate the number of bytes based on the number of input characters + * whether it is even or odd. + * if the number of input characters are even, then we need N/2 byte. + * if the number of input characters are odd, then we need do (N+1)/2 to + * compensate rounding off. + * For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough. + * If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes + */ + *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2); + if (NULL == *pCckmIe) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return -EINVAL; + } + vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2); + /* + * the buffer received from the upper layer is character buffer, + * we need to prepare the buffer taking 2 characters in to a U8 hex + * decimal number for example 7f0000f0...form a buffer to contain + * 7f in 0th location, 00 in 1st and f0 in 3rd location + */ + for (i = 0, j = 0; j < *pCckmIeLen; j += 2) + { + tempByte = (hdd_parse_hex(inPtr[j]) << 4) + | (hdd_parse_hex(inPtr[j + 1])); + (*pCckmIe)[i++] = tempByte; + } + *pCckmIeLen = i; + return VOS_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/**--------------------------------------------------------------------------- + + \brief hdd_is_valid_mac_address() - Validate MAC address + + This function validates whether the given MAC address is valid or not + Expected MAC address is of the format XX:XX:XX:XX:XX:XX + where X is the hexa decimal digit character and separated by ':' + This algorithm works even if MAC address is not separated by ':' + + This code checks given input string mac contains exactly 12 hexadecimal digits. + and a separator colon : appears in the input string only after + an even number of hex digits. + + \param - pMacAddr pointer to the input MAC address + \return - 1 for valid and 0 for invalid + + --------------------------------------------------------------------------*/ + +v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr) +{ + int xdigit = 0; + int separator = 0; + while (*pMacAddr) + { + if (isxdigit(*pMacAddr)) + { + xdigit++; + } + else if (':' == *pMacAddr) + { + if (0 == xdigit || ((xdigit / 2) - 1) != separator) + break; + + ++separator; + } + else + { + /* Invalid MAC found */ + return 0; + } + ++pMacAddr; + } + return (xdigit == 12 && (separator == 5 || separator == 0)); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_open() - HDD Open function + + This is called in response to ifconfig up + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int hdd_open (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + int ret; + v_BOOL_t in_standby = TRUE; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST, + pAdapter->sessionId, pAdapter->device_mode)); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + status = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status)) { + if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags)) { + hddLog(LOG1, FL("chip already out of standby")); + in_standby = FALSE; + break; + } else { + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if (TRUE == in_standby) { + if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter)) { + hddLog(LOGE, FL("Failed to bring wlan out of power save")); + return -EINVAL; + } + } + + set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); + if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + hddLog(LOG1, FL("Enabling Tx Queues")); + /* Enable TX queues only when we are connected */ + netif_tx_start_all_queues(dev); + } + + return ret; +} + +int hdd_mon_open (struct net_device *dev) +{ + netif_start_queue(dev); + + return 0; +} +/**--------------------------------------------------------------------------- + + \brief hdd_stop() - HDD stop function + + This is called in response to ifconfig down + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int hdd_stop (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_BOOL_t enter_standby = TRUE; + int ret; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST, + pAdapter->sessionId, pAdapter->device_mode)); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + /* Nothing to be done if the interface is not opened */ + if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NETDEV Interface is not OPENED", __func__); + return -ENODEV; + } + + /* Make sure the interface is marked as closed */ + clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__); + + /* Disable TX on the interface, after this hard_start_xmit() will not + * be called on that interface + */ + netif_tx_disable(pAdapter->dev); + + /* Mark the interface status as "down" for outside world */ + netif_carrier_off(pAdapter->dev); + + /* The interface is marked as down for outside world (aka kernel) + * But the driver is pretty much alive inside. The driver needs to + * tear down the existing connection on the netdev (session) + * cleanup the data pipes and wait until the control plane is stabilized + * for this interface. The call also needs to wait until the above + * mentioned actions are completed before returning to the caller. + * Notice that the hdd_stop_adapter is requested not to close the session + * That is intentional to be able to scan if it is a STA/P2P interface + */ + hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE); + + /* DeInit the adapter. This ensures datapath cleanup as well */ + hdd_deinit_adapter(pHddCtx, pAdapter); + + /* SoftAP ifaces should never go in power save mode + making sure same here. */ + if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode ) || + (WLAN_HDD_MONITOR == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + /* SoftAP mode, so return from here */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: In SAP MODE", __func__); + EXIT(); + return 0; + } + + /* Find if any iface is up. If any iface is up then can't put device to + * sleep/power save mode + */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) ) + { + if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot " + "put device to sleep", __func__); + enter_standby = FALSE; + break; + } + else + { + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if (TRUE == enter_standby) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down " + "entering standby", __func__); + if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx)) + { + /*log and return success*/ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put " + "wlan in power save", __func__); + } + } + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_uninit() - HDD uninit function + + This is called during the netdev unregister to uninitialize all data +associated with the device + + \param - dev Pointer to net_device structure + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_uninit (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + ENTER(); + + do + { + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid magic", __func__); + break; + } + + if (NULL == pAdapter->pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: NULL pHddCtx", __func__); + break; + } + + if (dev != pAdapter->dev) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid device reference", __func__); + /* we haven't validated all cases so let this go for now */ + } + + hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter); + + /* after uninit our adapter structure will no longer be valid */ + pAdapter->dev = NULL; + pAdapter->magic = 0; + } while (0); + + EXIT(); +} + +/**--------------------------------------------------------------------------- + \brief hdd_full_pwr_cbk() - HDD full power callback function + + This is the function invoked by SME to inform the result of a full power + request issued by HDD + + \param - callback context - Pointer to cookie + status - result of request + + \return - None + +--------------------------------------------------------------------------*/ +void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status); + if(&pHddCtx->full_pwr_comp_var) + { + complete(&pHddCtx->full_pwr_comp_var); + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function + + This is the function invoked by SME to inform the result of BMPS + request issued by HDD + + \param - callback context - Pointer to cookie + status - result of request + + \return - None + +--------------------------------------------------------------------------*/ +void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status) +{ + + struct completion *completion_var = (struct completion*) callbackContext; + + hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status); + if(completion_var != NULL) + { + complete(completion_var); + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_get_cfg_file_size() - + + This function reads the configuration file using the request firmware + API and returns the configuration file size. + + \param - pCtx - Pointer to the adapter . + - pFileName - Pointer to the file name. + - pBufSize - Pointer to the buffer size. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize) +{ + int status; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + + ENTER(); + + status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->fw || !pHddCtx->fw->data) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__); + status = VOS_STATUS_E_FAILURE; + } + else { + *pBufSize = pHddCtx->fw->size; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize); + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_read_cfg_file() - + + This function reads the configuration file using the request firmware + API and returns the cfg data and the buffer size of the configuration file. + + \param - pCtx - Pointer to the adapter . + - pFileName - Pointer to the file name. + - pBuffer - Pointer to the data buffer. + - pBufSize - Pointer to the buffer size. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, + v_VOID_t *pBuffer, v_SIZE_t *pBufSize) +{ + int status; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + + ENTER(); + + status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->fw || !pHddCtx->fw->data) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__); + return VOS_STATUS_E_FAILURE; + } + else { + if(*pBufSize != pHddCtx->fw->size) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG " + "file size", __func__); + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + return VOS_STATUS_E_FAILURE; + } + else { + if(pBuffer) { + vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize); + } + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + } + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_set_mac_address() - + + This function sets the user specified mac address using + the command ifconfig wlanX hw ether . + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int hdd_set_mac_address(struct net_device *dev, void *addr) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct sockaddr *psta_mac_addr = addr; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + ENTER(); + + memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + + EXIT(); + return halStatus; +} + +tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx) +{ + int i; + for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i))) + break; + } + + if( VOS_MAX_CONCURRENCY_PERSONA == i) + return NULL; + + pHddCtx->cfg_ini->intfAddrMask |= (1 << i); + return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0]; +} + +void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr) +{ + int i; + for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) ) + { + pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i); + break; + } + } + return; +} + +static struct net_device_ops wlan_drv_ops = { + .ndo_open = hdd_open, + .ndo_stop = hdd_stop, + .ndo_uninit = hdd_uninit, + .ndo_start_xmit = hdd_hard_start_xmit, + .ndo_tx_timeout = hdd_tx_timeout, + .ndo_get_stats = hdd_stats, + .ndo_do_ioctl = hdd_ioctl, + .ndo_set_mac_address = hdd_set_mac_address, + .ndo_select_queue = hdd_select_queue, +#ifdef WLAN_FEATURE_PACKET_FILTERING +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0)) + .ndo_set_rx_mode = hdd_set_multicast_list, +#else + .ndo_set_multicast_list = hdd_set_multicast_list, +#endif //LINUX_VERSION_CODE +#endif + }; + static struct net_device_ops wlan_mon_drv_ops = { + .ndo_open = hdd_mon_open, + .ndo_stop = hdd_stop, + .ndo_uninit = hdd_uninit, + .ndo_start_xmit = hdd_mon_hard_start_xmit, + .ndo_tx_timeout = hdd_tx_timeout, + .ndo_get_stats = hdd_stats, + .ndo_do_ioctl = hdd_ioctl, + .ndo_set_mac_address = hdd_set_mac_address, +}; + + +void hdd_set_station_ops( struct net_device *pWlanDev ) +{ + pWlanDev->netdev_ops = &wlan_drv_ops; +} + +static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name ) +{ + struct net_device *pWlanDev = NULL; + hdd_adapter_t *pAdapter = NULL; + /* + * cfg80211 initialization and registration.... + */ + pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES); + + if(pWlanDev != NULL) + { + + //Save the pointer to the net_device in the HDD adapter + pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev ); + + vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) ); + + pAdapter->dev = pWlanDev; + pAdapter->pHddCtx = pHddCtx; + pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC; + + init_completion(&pAdapter->session_open_comp_var); + init_completion(&pAdapter->session_close_comp_var); + init_completion(&pAdapter->disconnect_comp_var); + init_completion(&pAdapter->linkup_event_var); + init_completion(&pAdapter->cancel_rem_on_chan_var); + init_completion(&pAdapter->rem_on_chan_ready_event); + init_completion(&pAdapter->offchannel_tx_event); + init_completion(&pAdapter->tx_action_cnf_event); +#ifdef FEATURE_WLAN_TDLS + init_completion(&pAdapter->tdls_add_station_comp); + init_completion(&pAdapter->tdls_del_station_comp); + init_completion(&pAdapter->tdls_mgmt_comp); + init_completion(&pAdapter->tdls_link_establish_req_comp); +#endif + + init_completion(&pHddCtx->mc_sus_event_var); + init_completion(&pHddCtx->tx_sus_event_var); + init_completion(&pHddCtx->rx_sus_event_var); + init_completion(&pHddCtx->ready_to_suspend); + init_completion(&pAdapter->ula_complete); + init_completion(&pAdapter->change_country_code); + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + init_completion(&pHddCtx->ready_to_extwow); +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + init_completion(&pAdapter->hdd_set_batch_scan_req_var); + init_completion(&pAdapter->hdd_get_batch_scan_req_var); + pAdapter->pBatchScanRsp = NULL; + pAdapter->numScanList = 0; + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + pAdapter->prev_batch_id = 0; + mutex_init(&pAdapter->hdd_batch_scan_lock); +#endif + init_completion(&pAdapter->scan_info.scan_req_completion_event); + init_completion(&pAdapter->scan_info.abortscan_event_var); + + vos_event_init(&pAdapter->scan_info.scan_finished_event); + pAdapter->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP; + + pAdapter->offloads_configured = FALSE; + pAdapter->isLinkUpSvcNeeded = FALSE; + pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE; + //Init the net_device structure + strlcpy(pWlanDev->name, name, IFNAMSIZ); + + vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr)); + vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr)); + pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT; + pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM; + + if (pHddCtx->cfg_ini->enableIPChecksumOffload) + pWlanDev->features |= NETIF_F_HW_CSUM; + else if (pHddCtx->cfg_ini->enableTCPChkSumOffld) + pWlanDev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + pWlanDev->features |= NETIF_F_RXCSUM; + hdd_set_station_ops( pAdapter->dev ); + + pWlanDev->destructor = free_netdev; + pWlanDev->ieee80211_ptr = &pAdapter->wdev ; + pAdapter->wdev.wiphy = pHddCtx->wiphy; + pAdapter->wdev.netdev = pWlanDev; + /* set pWlanDev's parent to underlying device */ + SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev); + hdd_wmm_init( pAdapter ); + } + + return pAdapter; +} + +VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held ) +{ + struct net_device *pWlanDev = pAdapter->dev; + //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + //eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + if( rtnl_lock_held ) + { + if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) { + if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__); + return VOS_STATUS_E_FAILURE; + } + } + if (register_netdevice(pWlanDev)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if(register_netdev(pWlanDev)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__); + return VOS_STATUS_E_FAILURE; + } + } + set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags); + + return VOS_STATUS_SUCCESS; +} + +static eHalStatus hdd_smeCloseSessionCallback(void *pContext) +{ + hdd_adapter_t *pAdapter = pContext; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__); + return eHAL_STATUS_INVALID_PARAMETER; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__); + return eHAL_STATUS_NOT_INITIALIZED; + } + + clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags); + +#if !defined (CONFIG_CNSS) && \ + !defined (WLAN_OPEN_SOURCE) + /* need to make sure all of our scheduled work has completed. + * This callback is called from MC thread context, so it is safe to + * to call below flush work queue API from here. + * + * Even though this is called from MC thread context, if there is a faulty + * work item in the system, that can hang this call forever. So flushing + * this global work queue is not safe; and now we make sure that + * individual work queues are stopped correctly. But the cancel work queue + * is a GPL only API, so the proprietary version of the driver would still + * rely on the global work queue flush. + */ + flush_scheduled_work(); +#endif + + /* We can be blocked while waiting for scheduled work to be + * flushed, and the adapter structure can potentially be freed, in + * which case the magic will have been reset. So make sure the + * magic is still good, and hence the adapter structure is still + * valid, before signalling completion */ + if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic) + { + complete(&pAdapter->session_close_comp_var); + } + + return eHAL_STATUS_SUCCESS; +} + +VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ) +{ + struct net_device *pWlanDev = pAdapter->dev; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tANI_U32 type, subType; + unsigned long rc; + int ret_val; + + INIT_COMPLETION(pAdapter->session_open_comp_var); + sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode); + status = vos_get_vdev_types(pAdapter->device_mode, &type, &subType); + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "failed to get vdev type"); + goto error_sme_open; + } + //Open a SME session for future operation + halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter, + (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId, + type, subType); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "sme_OpenSession() failed with status code %08d [x%08x]", + halStatus, halStatus ); + status = VOS_STATUS_E_FAILURE; + goto error_sme_open; + } + + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->session_open_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("Session is not opened within timeout period code %ld"), + rc ); + status = VOS_STATUS_E_FAILURE; + goto error_sme_open; + } + + // Register wireless extensions + if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_register_wext() failed with status code %08d [x%08x]", + halStatus, halStatus ); + status = VOS_STATUS_E_FAILURE; + goto error_register_wext; + } + + //Set the Connection State to Not Connected + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + + //Set the default operation channel + pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel; + + /* Make the default Auth Type as OPEN*/ + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_init_tx_rx() failed with status code %08d [x%08x]", + status, status ); + goto error_init_txrx; + } + + set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + + if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_wmm_adapter_init() failed with status code %08d [x%08x]", + status, status ); + goto error_wmm_init; + } + + set_bit(WMM_INIT_DONE, &pAdapter->event_flags); + + ret_val = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_ENABLE, + (int)pHddCtx->cfg_ini->enableSifsBurst, + PDEV_CMD); + + if (0 != ret_val) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: WMI_PDEV_PARAM_BURST_ENABLE set failed %d", + __func__, ret_val); + } + +#ifdef FEATURE_WLAN_TDLS + if(0 != wlan_hdd_tdls_init(pAdapter)) + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__); + goto error_tdls_init; + } + set_bit(TDLS_INIT_DONE, &pAdapter->event_flags); +#endif + + return VOS_STATUS_SUCCESS; + +#ifdef FEATURE_WLAN_TDLS +error_tdls_init: + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + hdd_wmm_adapter_close(pAdapter); +#endif +error_wmm_init: + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + hdd_deinit_tx_rx(pAdapter); +error_init_txrx: + hdd_UnregisterWext(pWlanDev); +error_register_wext: + if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) + { + INIT_COMPLETION(pAdapter->session_close_comp_var); + if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal, + pAdapter->sessionId, + hdd_smeCloseSessionCallback, pAdapter)) + { + unsigned long rc; + + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->session_close_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if (rc <= 0) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Session is not opened within timeout period code %ld"), + rc); + } +} +error_sme_open: + return status; +} + +void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) +{ + hdd_cfg80211_state_t *cfgState; + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if( NULL != cfgState->buf ) + { + unsigned long rc; + INIT_COMPLETION(pAdapter->tx_action_cnf_event); + rc = wait_for_completion_timeout( + &pAdapter->tx_action_cnf_event, + msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT)); + if (!rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s HDD Wait for Action Confirmation Failed!!", + __func__); + } + } + return; +} + +void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) +{ + ENTER(); + switch ( pAdapter->device_mode ) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + { + if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags)) + { + hdd_deinit_tx_rx( pAdapter ); + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + } + + if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); +#ifdef FEATURE_WLAN_TDLS + if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags)) + { + wlan_hdd_tdls_exit(pAdapter); + clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags); + } +#endif + + break; + } + + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + { + + if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); + + hdd_unregister_hostapd(pAdapter); + + // set con_mode to STA only when no SAP concurrency mode + if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO))) + hdd_set_conparam( 0 ); + wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL ); + break; + } + + case WLAN_HDD_MONITOR: + { + hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx; + if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags)) + { + hdd_deinit_tx_rx( pAdapter ); + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + } + if(NULL != pAdapterforTx) + { + hdd_cleanup_actionframe(pHddCtx, pAdapterforTx); + } + break; + } + + + default: + break; + } + + EXIT(); +} + +void hdd_cleanup_adapter(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + tANI_U8 rtnl_held) +{ + struct net_device *pWlanDev = NULL; + + if (pAdapter) + pWlanDev = pAdapter->dev; + else { + hddLog(LOGE, FL("pAdapter is Null")); + return; + } + +#ifdef FEATURE_WLAN_BATCH_SCAN + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)) { + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) { + hdd_deinit_batch_scan(pAdapter); + } + } +#endif + + /* The adapter is marked as closed. When hdd_wlan_exit() call returns, + * the driver is almost closed and cannot handle either control + * messages or data. However, unregister_netdevice() call above will + * eventually invoke hdd_stop (ndo_close) driver callback, which attempts + * to close the active connections (basically excites control path) which + * is not right. Setting this flag helps hdd_stop() to recognize that + * the interface is closed and restricts any operations on that + */ + clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); + + if (test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) { + if (rtnl_held) { + unregister_netdevice(pWlanDev); + } else { + unregister_netdev(pWlanDev); + } + /* Note that the pAdapter is no longer valid at this point + since the memory has been reclaimed */ + } +} + +void hdd_set_pwrparams(hdd_context_t *pHddCtx) +{ + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + /*loop through all adapters.*/ + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + + { // we skip this registration for modes other than STA and P2P client modes. + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + continue; + } + + //Apply Dynamic DTIM For P2P + //Only if ignoreDynamicDtimInP2pMode is not set in ini + if ((pHddCtx->cfg_ini->enableDynamicDTIM || + pHddCtx->cfg_ini->enableModulatedDTIM) && + ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) && + !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) && + (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) && + (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) && + (pHddCtx->cfg_ini->fIsBmpsEnabled)) + { + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = 1; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + if (pHddCtx->cfg_ini->enableModulatedDTIM) + { + powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + } + else + { + powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM; + } + + /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM + * specified during Enter/Exit BMPS when LCD off*/ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + /* switch to the DTIM specified in cfg.ini */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM %d", powerRequest.uListenInterval); + sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE); + break; + + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } +} + +void hdd_reset_pwrparams(hdd_context_t *pHddCtx) +{ + /*Switch back to DTIM 1*/ + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + /* Update ignoreDTIM and ListedInterval in CFG with default values */ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM%d",powerRequest.uListenInterval); + sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE); + +} + +VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + { + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + + if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled) + { + sme_StartAutoBmpsTimer(pHddCtx->hHal); + } + + if (pHddCtx->cfg_ini->fIsImpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + + return status; +} + +VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type) +{ + hdd_adapter_t *pAdapter = NULL; + eHalStatus halStatus; + VOS_STATUS status = VOS_STATUS_E_INVAL; + v_BOOL_t disableBmps = FALSE; + v_BOOL_t disableImps = FALSE; + + switch(session_type) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_GO: + //Exit BMPS -> Is Sta/P2P Client is already connected + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if((NULL != pAdapter)&& + hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + disableBmps = TRUE; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if((NULL != pAdapter)&& + hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + disableBmps = TRUE; + } + + //Exit both Bmps and Imps incase of Go/SAP Mode + if((WLAN_HDD_SOFTAP == session_type) || + (WLAN_HDD_P2P_GO == session_type)) + { + disableBmps = TRUE; + disableImps = TRUE; + } + + if(TRUE == disableImps) + { + if (pHddCtx->cfg_ini->fIsImpsEnabled) + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + } + + if(TRUE == disableBmps) + { + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + { + halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + if(eHAL_STATUS_SUCCESS != halStatus) + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__); + VOS_ASSERT(0); + return status; + } + } + + if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled) + { + halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal); + + if(eHAL_STATUS_SUCCESS != halStatus) + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__); + VOS_ASSERT(0); + return status; + } + } + } + + if((TRUE == disableBmps) || + (TRUE == disableImps)) + { + /* Now, get the chip into Full Power now */ + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus != eHAL_STATUS_SUCCESS) + { + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + unsigned long rc; + //Block on a completion variable. Can't wait forever though + rc = wait_for_completion_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(1000)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: wait on full_pwr_comp_var failed", + __func__); +} + } + else + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__); + VOS_ASSERT(0); + return status; + } + } + + status = VOS_STATUS_SUCCESS; + } + + break; + } + return status; +} + +VOS_STATUS hdd_check_for_existing_macaddr( hdd_context_t *pHddCtx, + tSirMacAddr macAddr ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + + if (pAdapter && vos_mem_compare(pAdapter->macAddressCurrent.bytes, + macAddr, sizeof(tSirMacAddr))) { + return VOS_STATUS_E_FAILURE; + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + return VOS_STATUS_SUCCESS; +} + +hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, + const char *iface_name, tSirMacAddr macAddr, + tANI_U8 rtnl_held ) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pHddAdapterNode = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + VOS_STATUS exitbmpsStatus = VOS_STATUS_E_FAILURE; + hdd_cfg80211_state_t *cfgState; + int ret; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: iface =%s type = %d\n", __func__, + iface_name, session_type); + + if (pHddCtx->current_intf_count >= pHddCtx->max_intf_count){ + /* Max limit reached on the number of vdevs configured by the host. + * Return error + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d", + __func__,pHddCtx->current_intf_count, pHddCtx->max_intf_count); + return NULL; + } + + if(macAddr == NULL) + { + /* Not received valid macAddr */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Unable to add virtual intf: Not able to get" + "valid mac address",__func__); + return NULL; + } + + status = hdd_check_for_existing_macaddr(pHddCtx, macAddr); + if (VOS_STATUS_E_FAILURE == status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Duplicate MAC addr: "MAC_ADDRESS_STR" already exists", + __func__, MAC_ADDR_ARRAY(macAddr)); + return NULL; + } + + /* + * If Powersave Offload is enabled + * Fw will take care incase of concurrency + */ + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + { + //Disable BMPS incase of Concurrency + exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type); + + if(VOS_STATUS_E_FAILURE == exitbmpsStatus) + { + //Fail to Exit BMPS + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Fail to Exit BMPS")); + VOS_ASSERT(0); + return NULL; + } + } + + switch(session_type) + { + case WLAN_HDD_INFRA_STATION: + /* Reset locally administered bit if the device mode is STA */ + WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr); + /* fall through */ + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + if (session_type == WLAN_HDD_INFRA_STATION) + pAdapter->wdev.iftype = NL80211_IFTYPE_STATION; + else if (session_type == WLAN_HDD_P2P_DEVICE) + pAdapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; + else + pAdapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; + + pAdapter->device_mode = session_type; + + status = hdd_init_station_mode( pAdapter ); + if( VOS_STATUS_SUCCESS != status ) + goto err_free_netdev; + + status = hdd_register_interface( pAdapter, rtnl_held ); + if( VOS_STATUS_SUCCESS != status ) + { + hdd_deinit_adapter(pHddCtx, pAdapter); + goto err_free_netdev; + } + // Workqueue which gets scheduled in IPv4 notification callback +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->ipv4NotifierWorkQueue, + hdd_ipv4_notifier_work_queue); +#else + INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, + hdd_ipv4_notifier_work_queue); +#endif + +#ifdef WLAN_NS_OFFLOAD + // Workqueue which gets scheduled in IPv6 notification callback. +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->ipv6NotifierWorkQueue, + hdd_ipv6_notifier_work_queue); +#else + INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, + hdd_ipv6_notifier_work_queue); +#endif +#endif + //Stop the Interface TX queue. + netif_tx_disable(pAdapter->dev); + //netif_tx_disable(pWlanDev); + netif_carrier_off(pAdapter->dev); + + if (WLAN_HDD_P2P_CLIENT == session_type || + WLAN_HDD_P2P_DEVICE == session_type) { + /* Initialize the work queue to defer the + * back to back RoC request */ + INIT_DELAYED_WORK(&pAdapter->roc_work, hdd_p2p_roc_work_queue); + } + +#ifdef QCA_LL_TX_FLOW_CT + /* SAT mode default TX Flow control instance + * This instance will be used for + * STA mode, IBSS mode and TDLS mode */ + if (pAdapter->tx_flow_timer_initialized == VOS_FALSE) { + vos_timer_init(&pAdapter->tx_flow_control_timer, + VOS_TIMER_TYPE_SW, + hdd_tx_resume_timer_expired_handler, + pAdapter); + pAdapter->tx_flow_timer_initialized = VOS_TRUE; + } + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + hdd_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); +#endif /* QCA_LL_TX_FLOW_CT */ + + break; + } + + case WLAN_HDD_P2P_GO: + case WLAN_HDD_SOFTAP: + { + pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name ); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ? + NL80211_IFTYPE_AP: + NL80211_IFTYPE_P2P_GO; + pAdapter->device_mode = session_type; + + status = hdd_init_ap_mode(pAdapter); + if( VOS_STATUS_SUCCESS != status ) + goto err_free_netdev; + + status = hdd_register_hostapd( pAdapter, rtnl_held ); + if( VOS_STATUS_SUCCESS != status ) + { + hdd_deinit_adapter(pHddCtx, pAdapter); + goto err_free_netdev; + } + + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + hdd_set_conparam( 1 ); + if (WLAN_HDD_P2P_GO == session_type) { + /* Initialize the work queue to + * defer the back to back RoC request */ + INIT_DELAYED_WORK(&pAdapter->roc_work, hdd_p2p_roc_work_queue); + } + + break; + } + case WLAN_HDD_MONITOR: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR; + pAdapter->device_mode = session_type; + status = hdd_register_interface( pAdapter, rtnl_held ); + pAdapter->dev->netdev_ops = &wlan_mon_drv_ops; + hdd_init_tx_rx( pAdapter ); + set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + //Set adapter to be used for data tx. It will use either GO or softap. + pAdapter->sessionCtx.monitor.pAdapterForTx = + hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP); + if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) + { + pAdapter->sessionCtx.monitor.pAdapterForTx = + hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO); + } + /* This work queue will be used to transmit management packet over + * monitor interface. */ + if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__); + return NULL; + } + +#ifdef CONFIG_CNSS + cnss_init_work(&pAdapter->sessionCtx.monitor.pAdapterForTx-> + monTxWorkQueue, hdd_mon_tx_work_queue); +#else + INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue, + hdd_mon_tx_work_queue); +#endif + } + break; + case WLAN_HDD_FTM: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning + * message while loading driver in FTM mode. */ + pAdapter->wdev.iftype = NL80211_IFTYPE_STATION; + pAdapter->device_mode = session_type; + status = hdd_register_interface( pAdapter, rtnl_held ); + + hdd_init_tx_rx( pAdapter ); + + //Stop the Interface TX queue. + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + } + break; + default: + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d", + __func__, session_type); + VOS_ASSERT(0); + return NULL; + } + } + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + mutex_init(&cfgState->remain_on_chan_ctx_lock); + + if( VOS_STATUS_SUCCESS == status ) + { +#ifdef WLAN_FEATURE_MBSSID + hdd_mbssid_apply_def_cfg_ini(pAdapter); +#endif + //Add it to the hdd's session list. + pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) ); + if( NULL == pHddAdapterNode ) + { + status = VOS_STATUS_E_NOMEM; + } + else + { + pHddAdapterNode->pAdapter = pAdapter; + status = hdd_add_adapter_back ( pHddCtx, + pHddAdapterNode ); + } + } + + if( VOS_STATUS_SUCCESS != status ) + { + if( NULL != pAdapter ) + { + hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held ); + pAdapter = NULL; + } + if( NULL != pHddAdapterNode ) + { + vos_mem_free( pHddAdapterNode ); + } + + goto resume_bmps; + } + + if(VOS_STATUS_SUCCESS == status) + { + wlan_hdd_set_concurrency_mode(pHddCtx, session_type); + + //Initialize the WoWL service + if(!hdd_init_wowl(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__); + goto err_free_netdev; + } + + /* Adapter successfully added. Increment the vdev count */ + pHddCtx->current_intf_count++; + + hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: current_intf_count=%d", __func__, + pHddCtx->current_intf_count); +#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + if (vos_get_concurrency_mode() == VOS_STA_SAP) { + hdd_adapter_t *ap_adapter; + + ap_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (ap_adapter != NULL && + test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) && + VOS_IS_DFS_CH(ap_adapter->sessionCtx.ap.operatingChannel)) { + + hddLog(VOS_TRACE_LEVEL_WARN, + "STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS" + ); + ap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT; + wlan_hdd_restart_sap(ap_adapter); + } + } +#endif + } + + if ((vos_get_conparam() != VOS_FTM_MODE) && (!pHddCtx->cfg_ini->enable2x2)) + { +#define HDD_DTIM_1CHAIN_RX_ID 0x5 +#define HDD_SMPS_PARAM_VALUE_S 29 + + /* Disable DTIM 1 chain Rx when in 1x1, we are passing two values as + param_id << 29 | param_value. Below param_value = 0(disable) */ + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_SMPS_PARAM_CMDID, + HDD_DTIM_1CHAIN_RX_ID << HDD_SMPS_PARAM_VALUE_S, + VDEV_CMD); + + if (ret != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: DTIM 1 chain set failed %d", __func__, ret); + goto err_free_netdev; + } + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TX_CHAIN_MASK, + (int)pHddCtx->cfg_ini->txchainmask1x1, + PDEV_CMD); + if (ret != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: WMI_PDEV_PARAM_TX_CHAIN_MASK set" + " failed %d", __func__, ret); + goto err_free_netdev; + } + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_RX_CHAIN_MASK, + (int)pHddCtx->cfg_ini->rxchainmask1x1, + PDEV_CMD); + if (ret != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: WMI_PDEV_PARAM_RX_CHAIN_MASK set" + " failed %d", __func__, ret); + goto err_free_netdev; + } +#undef HDD_DTIM_1CHAIN_RX_ID +#undef HDD_SMPS_PARAM_VALUE_S + } + + if (VOS_FTM_MODE != vos_get_conparam()) + { + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_HYST_EN, + (int)pHddCtx->cfg_ini->enableMemDeepSleep, + PDEV_CMD); + + if (ret != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: WMI_PDEV_PARAM_HYST_EN set" + " failed %d", __func__, ret); + goto err_free_netdev; + } + } + + +#ifdef CONFIG_FW_LOGS_BASED_ON_INI + + /* Enable FW logs based on INI configuration */ + if ((VOS_FTM_MODE != vos_get_conparam()) && + (pHddCtx->cfg_ini->enablefwlog)) + { + tANI_U8 count = 0; + tANI_U32 value = 0; + tANI_U8 numEntries = 0; + tANI_U8 moduleLoglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH]; + + pHddCtx->fw_log_settings.dl_type = pHddCtx->cfg_ini->enableFwLogType; + ret = process_wma_set_command( (int)pAdapter->sessionId, + (int)WMI_DBGLOG_TYPE, + pHddCtx->cfg_ini->enableFwLogType, DBG_CMD ); + if (ret != 0) + { + hddLog(LOGE, FL("Failed to enable FW log type ret %d"), ret); + } + + pHddCtx->fw_log_settings.dl_loglevel = pHddCtx->cfg_ini->enableFwLogLevel; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_LOG_LEVEL, + pHddCtx->cfg_ini->enableFwLogLevel, DBG_CMD); + if (ret != 0) + { + hddLog(LOGE, FL("Failed to enable FW log level ret %d"), ret); + } + + hdd_string_to_u8_array( pHddCtx->cfg_ini->enableFwModuleLogLevel, + moduleLoglevel, + &numEntries, + FW_MODULE_LOG_LEVEL_STRING_LENGTH ); + while (count < numEntries) + { + /* FW module log level input string looks like below: + gFwDebugModuleLoglevel=, , so on.... + For example: + gFwDebugModuleLoglevel=1,0,2,1,3,2,4,3,5,4,6,5,7,6,8,7 + Above input string means : + For FW module ID 1 enable log level 0 + For FW module ID 2 enable log level 1 + For FW module ID 3 enable log level 2 + For FW module ID 4 enable log level 3 + For FW module ID 5 enable log level 4 + For FW module ID 6 enable log level 5 + For FW module ID 7 enable log level 6 + For FW module ID 8 enable log level 7 + */ + /* FW expects WMI command value = Module ID * 10 + Module Log level */ + value = ( (moduleLoglevel[count] * 10) + moduleLoglevel[count + 1] ); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_MOD_LOG_LEVEL, + value, DBG_CMD); + if (ret != 0) + { + hddLog(LOGE, FL("Failed to enable FW module log level %d ret %d"), + value, ret); + } + + count += 2; + } + } + +#endif + + + return pAdapter; + +err_free_netdev: + free_netdev(pAdapter->dev); + wlan_hdd_release_intf_addr( pHddCtx, + pAdapter->macAddressCurrent.bytes ); + +resume_bmps: + //If bmps disabled enable it + if (!pHddCtx->cfg_ini->enablePowersaveOffload) + { + if(VOS_STATUS_SUCCESS == exitbmpsStatus) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + } + + return NULL; +} + +VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + tANI_U8 rtnl_held ) +{ + hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pCurrent ); + if( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d", + __func__, status); + return status; + } + + while ( pCurrent->pAdapter != pAdapter ) + { + status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext ); + if( VOS_STATUS_SUCCESS != status ) + break; + + pCurrent = pNext; + } + pAdapterNode = pCurrent; + if( VOS_STATUS_SUCCESS == status ) + { + wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode); + hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held ); + + hdd_remove_adapter( pHddCtx, pAdapterNode ); + vos_mem_free( pAdapterNode ); + pAdapterNode = NULL; + + /* Adapter removed. Decrement vdev count */ + if (pHddCtx->current_intf_count != 0) + pHddCtx->current_intf_count--; + + /* + * If Powersave Offload is enabled, + * Fw will take care incase of concurrency + */ + if(pHddCtx->cfg_ini->enablePowersaveOffload) + return VOS_STATUS_SUCCESS; + + /* If there is a single session of STA/P2P client, re-enable BMPS */ + if ((!vos_concurrent_open_sessions_running()) && + ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) || + (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1))) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pHddAdapterNode; + VOS_STATUS status; + + ENTER(); + + do + { + status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode ); + if( pHddAdapterNode && VOS_STATUS_SUCCESS == status ) + { + hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE ); + vos_mem_free( pHddAdapterNode ); + } + }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status ); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter) +{ + tANI_U8 *bssid = NULL; + tSirUpdateIE updateIE; + switch (pHostapdAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + { + hdd_station_ctx_t * pHddStaCtx = + WLAN_HDD_GET_STATION_CTX_PTR(pHostapdAdapter); + bssid = (tANI_U8*)&pHddStaCtx->conn_info.bssId; + break; + } + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + case WLAN_HDD_IBSS: + { + bssid = pHostapdAdapter->macAddressCurrent.bytes; + break; + } + case WLAN_HDD_MONITOR: + case WLAN_HDD_FTM: + case WLAN_HDD_P2P_DEVICE: + default: + /* + * wlan_hdd_reset_prob_rspies should not have been called + * for these kind of devices + */ + hddLog(LOGE, FL("Unexpected request for the current device type %d"), + pHostapdAdapter->device_mode); + return; + } + + vos_mem_copy(updateIE.bssid, bssid, sizeof(tSirMacAddr)); + updateIE.smeSessionId = pHostapdAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_TRUE; + updateIE.notify = VOS_FALSE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_PROBE_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); + } +} + +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + union iwreq_data wrqu; + tSirUpdateIE updateIE ; + unsigned long rc; + + ENTER(); + + if (pHddCtx->isLogpInProgress) { + hddLog(LOG1, FL("LOGP in Progress. Ignore!!!")); + return VOS_STATUS_E_FAILURE; + } + + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + switch(pAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) ) + { + if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS) + halStatus = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE); + else + halStatus = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + //success implies disconnect command got queued up successfully + if(halStatus == eHAL_STATUS_SUCCESS) + { + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: wait on disconnect_comp_var failed", + __func__); + } + } + else + { + hddLog(LOGE, "%s: failed to post disconnect event to SME", + __func__); + } + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL); + } + else + { + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION) { + wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter); +#ifdef WLAN_OPEN_SOURCE + cancel_delayed_work_sync(&pAdapter->roc_work); +#endif + } + + if (pAdapter->ipv4_notifier_registered) + { + hddLog(LOG1, FL("Unregistered IPv4 notifier")); + unregister_inetaddr_notifier(&pAdapter->ipv4_notifier); + pAdapter->ipv4_notifier_registered = false; + } +#ifdef WLAN_OPEN_SOURCE + cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue); +#endif + +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_DeRegisterTXFlowControl(pHddCtx->pvosContext, pAdapter->sessionId); + if (pAdapter->tx_flow_timer_initialized == VOS_TRUE) { + if(VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) { + vos_timer_stop(&pAdapter->tx_flow_control_timer); + } + vos_timer_destroy(&pAdapter->tx_flow_control_timer); + pAdapter->tx_flow_timer_initialized = VOS_FALSE; + } +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef WLAN_NS_OFFLOAD +#ifdef WLAN_OPEN_SOURCE + cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue); +#endif + if (pAdapter->ipv6_notifier_registered) + { + hddLog(LOG1, FL("Unregistered IPv6 notifier")); + unregister_inet6addr_notifier(&pAdapter->ipv6_notifier); + pAdapter->ipv6_notifier_registered = false; + } +#endif + /* It is possible that the caller of this function does not + * wish to close the session + */ + if (VOS_TRUE == bCloseSession && + test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) + { + INIT_COMPLETION(pAdapter->session_close_comp_var); + if (eHAL_STATUS_SUCCESS == + sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, + hdd_smeCloseSessionCallback, pAdapter)) + { + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->session_close_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if (!rc) { + hddLog(LOGE, "%s: failure waiting for session_close_comp_var", + __func__); + } + } + } + break; + + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + //Any softap specific cleanup here... + if (pAdapter->device_mode == WLAN_HDD_P2P_GO) { + wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter); +#ifdef WLAN_OPEN_SOURCE + cancel_delayed_work_sync(&pAdapter->roc_work); +#endif + } + +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_DeRegisterTXFlowControl(pHddCtx->pvosContext, pAdapter->sessionId); + if (pAdapter->tx_flow_timer_initialized == VOS_TRUE) { + if(VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) { + vos_timer_stop(&pAdapter->tx_flow_control_timer); + } + vos_timer_destroy(&pAdapter->tx_flow_control_timer); + pAdapter->tx_flow_timer_initialized = VOS_FALSE; + } +#endif /* QCA_LL_TX_FLOW_CT */ + + mutex_lock(&pHddCtx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + VOS_STATUS status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + //Stop Bss. +#ifdef WLAN_FEATURE_MBSSID + status = WLANSAP_StopBss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); +#else + status = WLANSAP_StopBss(pHddCtx->pvosContext); +#endif + + if (VOS_IS_STATUS_SUCCESS(status)) + { + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d", + __func__, status); + } + } + else + { + hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__); + } + clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + + vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + /* Probe bcn reset */ + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_PROBE_BCN) + == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); + } + /* Assoc resp reset */ + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE")); + } + + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pAdapter); + kfree(pAdapter->sessionCtx.ap.beacon); + pAdapter->sessionCtx.ap.beacon = NULL; + } + mutex_unlock(&pHddCtx->sap_lock); + break; + + case WLAN_HDD_MONITOR: +#ifdef WLAN_OPEN_SOURCE + cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue); +#endif + break; + + default: + break; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter) +{ + tHddBatchScanRsp *pNode; + tHddBatchScanRsp *pPrev; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Adapter context is Null", __func__); + return; + } + + pNode = pAdapter->pBatchScanRsp; + while (pNode) + { + pPrev = pNode; + pNode = pNode->pNext; + vos_mem_free((v_VOID_t * )pPrev); + pPrev = NULL; + } + + pAdapter->pBatchScanRsp = NULL; + pAdapter->numScanList = 0; + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + pAdapter->prev_batch_id = 0; + + return; +} +#endif + +VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE; + + hdd_deinit_tx_rx(pAdapter); + if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + +#ifdef FEATURE_WLAN_BATCH_SCAN + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) + { + hdd_deinit_batch_scan(pAdapter); + } +#endif + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; +#ifndef MSM_PLATFORM + v_MACADDR_t bcastMac = VOS_MAC_ADDR_BROADCAST_INITIALIZER; +#endif + eConnectionState connState; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + hdd_wmm_init( pAdapter ); + + switch(pAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + + connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState; + + hdd_init_station_mode(pAdapter); + /* Open the gates for HDD to receive Wext commands */ + pAdapter->isLinkUpSvcNeeded = FALSE; + pAdapter->scan_info.mScanPending = FALSE; + pAdapter->scan_info.waitScanResult = FALSE; + + //Indicate disconnect event to supplicant if associated previously + if (eConnectionState_Associated == connState || + eConnectionState_IbssConnected == connState ) + { + union iwreq_data wrqu; + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL); + pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE; + + /* indicate disconnected event to nl80211 */ + cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED, + NULL, 0, GFP_KERNEL); + } + else if (eConnectionState_Connecting == connState) + { + /* + * Indicate connect failure to supplicant if we were in the + * process of connecting + */ + cfg80211_connect_result(pAdapter->dev, NULL, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL); + } + +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, hdd_tx_resume_cb, + pAdapter->sessionId, (void *)pAdapter); +#endif + + break; + + case WLAN_HDD_SOFTAP: + /* softAP can handle SSR */ + break; + + case WLAN_HDD_P2P_GO: +#ifdef MSM_PLATFORM + hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant", + __func__); + cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL); +#else + hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send restart supplicant", + __func__); + /* event supplicant to restart */ + cfg80211_del_sta(pAdapter->dev, + (const u8 *)&bcastMac.bytes[0], GFP_KERNEL); +#endif + break; + + case WLAN_HDD_MONITOR: + /* monitor interface start */ + break; + default: + break; + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + v_U32_t roamId; + unsigned long rc; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + init_completion(&pAdapter->disconnect_comp_var); + sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) + hddLog(LOGE, "%s: failure waiting for disconnect_comp_var", + __func__); + pWextState->roamProfile.csrPersona = pAdapter->device_mode; + pHddCtx->isAmpAllowed = VOS_FALSE; + sme_RoamConnect(pHddCtx->hHal, + pAdapter->sessionId, &(pWextState->roamProfile), + &roamId); + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +void hdd_dump_concurrency_info(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t * pHostapdState; + tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 }; + v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0; + const char *p2pMode = "DEV"; + const char *ccMode = "Standalone"; + +#ifdef QCA_LL_TX_FLOW_CT + v_U8_t targetChannel = 0; + v_U8_t preAdapterChannel = 0; + v_U8_t channel24; + v_U8_t channel5; + hdd_adapter_t *preAdapterContext = NULL; + hdd_adapter_t *pAdapter2_4 = NULL; + hdd_adapter_t *pAdapter5 = NULL; +#endif /* QCA_LL_TX_FLOW_CT */ + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + switch (pAdapter->device_mode) { + case WLAN_HDD_INFRA_STATION: + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) { + staChannel = pHddStaCtx->conn_info.operationChannel; + memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid)); +#ifdef QCA_LL_TX_FLOW_CT + targetChannel = staChannel; +#endif /* QCA_LL_TX_FLOW_CT */ + } + break; + case WLAN_HDD_P2P_CLIENT: + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) { + p2pChannel = pHddStaCtx->conn_info.operationChannel; + memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid)); + p2pMode = "CLI"; +#ifdef QCA_LL_TX_FLOW_CT + targetChannel = p2pChannel; +#endif /* QCA_LL_TX_FLOW_CT */ + } + break; + case WLAN_HDD_P2P_GO: + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) { + p2pChannel = pHddApCtx->operatingChannel; + memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid)); +#ifdef QCA_LL_TX_FLOW_CT + targetChannel = p2pChannel; +#endif /* QCA_LL_TX_FLOW_CT */ + } + p2pMode = "GO"; + break; + case WLAN_HDD_SOFTAP: + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) { + apChannel = pHddApCtx->operatingChannel; + memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid)); +#ifdef QCA_LL_TX_FLOW_CT + targetChannel = apChannel; +#endif /* QCA_LL_TX_FLOW_CT */ + } + break; + case WLAN_HDD_IBSS: + return; /* skip printing station message below */ + default: + break; + } +#ifdef QCA_LL_TX_FLOW_CT + if (targetChannel) + { + /* This is first adapter detected as active + * set as default for none concurrency case */ + if (!preAdapterChannel) + { +#ifdef IPA_UC_OFFLOAD + /* If IPA UC data path is enabled, + * target should reserve extra tx descriptors + * for IPA WDI data path. + * Then host data path should allow less TX packet pumping in case + * IPA WDI data path enabled */ + if ((pHddCtx->cfg_ini->IpaUcOffloadEnabled) && + (WLAN_HDD_SOFTAP == pAdapter->device_mode)) { + pAdapter->tx_flow_low_watermark = + pHddCtx->cfg_ini->TxFlowLowWaterMark + + WLAN_TFC_IPAUC_TX_DESC_RESERVE; + } else +#endif /* IPA_UC_OFFLOAD */ + { + pAdapter->tx_flow_low_watermark = + pHddCtx->cfg_ini->TxFlowLowWaterMark; + } + pAdapter->tx_flow_high_watermark_offset = + pHddCtx->cfg_ini->TxFlowHighWaterMarkOffset; + WLANTL_SetAdapterMaxQDepth(pHddCtx->pvosContext, + pAdapter->sessionId, + pHddCtx->cfg_ini->TxFlowMaxQueueDepth); + /* Temporary set log level as error + * TX Flow control feature settled down, will lower log level */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "MODE %d, CH %d, LWM %d, HWM %d, TXQDEP %d", + pAdapter->device_mode, + targetChannel, + pAdapter->tx_flow_low_watermark, + pAdapter->tx_flow_low_watermark + + pAdapter->tx_flow_high_watermark_offset, + pHddCtx->cfg_ini->TxFlowMaxQueueDepth); + preAdapterChannel = targetChannel; + preAdapterContext = pAdapter; + } + else + { + /* SCC, disable TX flow control for both + * SCC each adapter cannot reserve dedicated channel resource + * as a result, if any adapter blocked OS Q by flow control, + * blocked adapter will lost chance to recover */ + if (preAdapterChannel == targetChannel) + { + /* Current adapter */ + pAdapter->tx_flow_low_watermark = 0; + pAdapter->tx_flow_high_watermark_offset = 0; + WLANTL_SetAdapterMaxQDepth(pHddCtx->pvosContext, + pAdapter->sessionId, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + hddLog(VOS_TRACE_LEVEL_ERROR, + "SCC: MODE %d, CH %d, LWM %d, HWM %d, TXQDEP %d", + pAdapter->device_mode, + targetChannel, + pAdapter->tx_flow_low_watermark, + pAdapter->tx_flow_low_watermark + + pAdapter->tx_flow_high_watermark_offset, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + + if (!preAdapterContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "SCC: Previous adapter context NULL"); + continue; + } + + /* Previous adapter */ + preAdapterContext->tx_flow_low_watermark = 0; + preAdapterContext->tx_flow_high_watermark_offset = 0; + WLANTL_SetAdapterMaxQDepth(pHddCtx->pvosContext, + preAdapterContext->sessionId, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + /* Temporary set log level as error + * TX Flow control feature settled down, will lower log level */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "SCC: MODE %d, CH %d, LWM %d, HWM %d, TXQDEP %d", + preAdapterContext->device_mode, + targetChannel, + preAdapterContext->tx_flow_low_watermark, + preAdapterContext->tx_flow_low_watermark + + preAdapterContext->tx_flow_high_watermark_offset, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + } + /* MCC, each adapter will have dedicated resource */ + else + { + /* current channel is 2.4 */ + if (targetChannel <= WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH) + { + channel24 = targetChannel; + channel5 = preAdapterChannel; + pAdapter2_4 = pAdapter; + pAdapter5 = preAdapterContext; + } + /* Current channel is 5 */ + else + { + channel24 = preAdapterChannel; + channel5 = targetChannel; + pAdapter2_4 = preAdapterContext; + pAdapter5 = pAdapter; + } + + if (!pAdapter5) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "MCC: 5GHz adapter context NULL"); + continue; + } + pAdapter5->tx_flow_low_watermark = + pHddCtx->cfg_ini->TxHbwFlowLowWaterMark; + pAdapter5->tx_flow_high_watermark_offset = + pHddCtx->cfg_ini->TxHbwFlowHighWaterMarkOffset; + WLANTL_SetAdapterMaxQDepth(pHddCtx->pvosContext, + pAdapter5->sessionId, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + /* Temporary set log level as error + * TX Flow control feature settled down, will lower log level */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "MCC: MODE %d, CH %d, LWM %d, HWM %d, TXQDEP %d", + pAdapter5->device_mode, + channel5, + pAdapter5->tx_flow_low_watermark, + pAdapter5->tx_flow_low_watermark + + pAdapter5->tx_flow_high_watermark_offset, + pHddCtx->cfg_ini->TxHbwFlowMaxQueueDepth); + + if (!pAdapter2_4) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "MCC: 2.4GHz adapter context NULL"); + continue; + } + pAdapter2_4->tx_flow_low_watermark = + pHddCtx->cfg_ini->TxLbwFlowLowWaterMark; + pAdapter2_4->tx_flow_high_watermark_offset = + pHddCtx->cfg_ini->TxLbwFlowHighWaterMarkOffset; + WLANTL_SetAdapterMaxQDepth(pHddCtx->pvosContext, + pAdapter2_4->sessionId, + pHddCtx->cfg_ini->TxLbwFlowMaxQueueDepth); + /* Temporary set log level as error + * TX Flow control feature settled down, will lower log level */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "MCC: MODE %d, CH %d, LWM %d, HWM %d, TXQDEP %d", + pAdapter2_4->device_mode, + channel24, + pAdapter2_4->tx_flow_low_watermark, + pAdapter2_4->tx_flow_low_watermark + + pAdapter2_4->tx_flow_high_watermark_offset, + pHddCtx->cfg_ini->TxLbwFlowMaxQueueDepth); + } + } + } + targetChannel = 0; +#endif /* QCA_LL_TX_FLOW_CT */ + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) { + ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC"; + } + hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s", + staChannel, MAC_ADDR_ARRAY(staBssid), ccMode); + if (p2pChannel > 0) { + hddLog(VOS_TRACE_LEVEL_INFO, "p2p-%s(%d) " MAC_ADDRESS_STR, + p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid)); + } + if (apChannel > 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR, + apChannel, MAC_ADDR_ARRAY(apBssid)); + } + + if (p2pChannel > 0 && apChannel > 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel); + } +} + +bool hdd_is_ssr_required( void) +{ + return (isSsrRequired == HDD_SSR_REQUIRED); +} + +/* Once SSR is disabled then it cannot be set. */ +void hdd_set_ssr_required( e_hdd_ssr_required value) +{ + if (HDD_SSR_DISABLED == isSsrRequired) + return; + + isSsrRequired = value; +} + +VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_peek_front ( &pHddCtx->hddAdapters, + (hdd_list_node_t**) ppAdapterNode ); + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode, + hdd_adapter_list_node_t** pNextAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_peek_next ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode, + (hdd_list_node_t**)pNextAdapterNode ); + + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_remove_node ( &pHddCtx->hddAdapters, + &pAdapterNode->node ); + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_remove_front( &pHddCtx->hddAdapters, + (hdd_list_node_t**) ppAdapterNode ); + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_insert_back ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode ); + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock(&pHddCtx->hddAdapters.lock); + status = hdd_list_insert_front ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode ); + spin_unlock(&pHddCtx->hddAdapters.lock); + return status; +} + +hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, + tSirMacAddr macAddr ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes, + macAddr, sizeof(tSirMacAddr) ) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name, + IFNAMSIZ ) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +hdd_adapter_t *hdd_get_adapter_by_vdev( hdd_context_t *pHddCtx, + tANI_U32 vdev_id ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS vos_status; + + + vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode); + + while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status)) + { + pAdapter = pAdapterNode->pAdapter; + + if (pAdapter->sessionId == vdev_id) + return pAdapter; + + vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vdev_id %d does not exist with host", + __func__, vdev_id); + + return NULL; +} + +hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && (mode == pAdapter->device_mode) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +//Remove this function later +hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode ) + { + return pAdapter; + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +/**--------------------------------------------------------------------------- + + \brief hdd_set_monitor_tx_adapter() - + + This API initializes the adapter to be used while transmitting on monitor + adapter. + + \param - pHddCtx - Pointer to the HDD context. + pAdapter - Adapter that will used for TX. This can be NULL. + \return - None. + --------------------------------------------------------------------------*/ +void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) +{ + hdd_adapter_t *pMonAdapter; + + pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR ); + + if( NULL != pMonAdapter ) + { + pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter; + } +} +/**--------------------------------------------------------------------------- + + \brief hdd_select_queue() - + + This API returns the operating channel of the requested device mode + + \param - pHddCtx - Pointer to the HDD context. + - mode - Device mode for which operating channel is required + supported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT + WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO. + \return - channel number. "0" id the requested device is not found OR it is not connected. + --------------------------------------------------------------------------*/ +v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + v_U8_t operatingChannel = 0; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( mode == pAdapter->device_mode ) + { + switch(pAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) ) + operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel; + break; + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + /*softap connection info */ + if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel; + break; + default: + break; + } + + break; //Found the device of interest. break the loop + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return operatingChannel; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/**--------------------------------------------------------------------------- + + \brief hdd_set_multicast_list() - + + This used to set the multicast address list. + + \param - dev - Pointer to the WLAN device. + - skb - Pointer to OS packet (sk_buff). + \return - success/fail + + --------------------------------------------------------------------------*/ +static void hdd_set_multicast_list(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int mc_count; + int i = 0; + struct netdev_hw_addr *ha; + + if (dev->flags & IFF_ALLMULTI) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: allow all multicast frames", __func__); + pAdapter->mc_addr_list.mc_cnt = 0; + } + else + { + mc_count = netdev_mc_count(dev); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: mc_count = %u", __func__, mc_count); + if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: No free filter available; allow all multicast frames", __func__); + pAdapter->mc_addr_list.mc_cnt = 0; + return; + } + + pAdapter->mc_addr_list.mc_cnt = mc_count; + + netdev_for_each_mc_addr(ha, dev) { + if (i == mc_count) + break; + memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN); + memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR, + __func__, i, + MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i])); + i++; + } + } + return; +} +#endif + +/**--------------------------------------------------------------------------- + + \brief hdd_select_queue() - + + This function is registered with the Linux OS for network + core to decide which queue to use first. + + \param - dev - Pointer to the WLAN device. + - skb - Pointer to OS packet (sk_buff). + \return - ac, Queue Index/access category corresponding to UP in IP header + + --------------------------------------------------------------------------*/ +v_U16_t hdd_select_queue(struct net_device *dev, + struct sk_buff *skb) +{ + return hdd_wmm_select_queue(dev, skb); +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_initial_scan() - + + This function triggers the initial scan + + \param - pAdapter - Pointer to the HDD adapter. + + --------------------------------------------------------------------------*/ +void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter) +{ + tCsrScanRequest scanReq; + tCsrChannelInfo channelInfo; + eHalStatus halStatus; + tANI_U32 scanId; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + vos_mem_zero(&scanReq, sizeof(tCsrScanRequest)); + vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff); + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + if(sme_Is11dSupported(pHddCtx->hHal)) + { + halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo ); + if ( HAL_STATUS_SUCCESS( halStatus ) ) + { + scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels); + if( !scanReq.ChannelInfo.ChannelList ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__); + vos_mem_free(channelInfo.ChannelList); + channelInfo.ChannelList = NULL; + return; + } + vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList, + channelInfo.numOfChannels); + scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels; + vos_mem_free(channelInfo.ChannelList); + channelInfo.ChannelList = NULL; + } + + scanReq.scanType = eSIR_PASSIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN; + scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime; + scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime; + } + else + { + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime; + scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime; + } + + halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d", + __func__, halStatus ); + } + + if(sme_Is11dSupported(pHddCtx->hHal)) + vos_mem_free(scanReq.ChannelInfo.ChannelList); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_full_power_callback() - HDD full power callback function + + This is the function invoked by SME to inform the result of a full power + request issued by HDD + + \param - callback context - Pointer to cookie + \param - status - result of request + + \return - None + + --------------------------------------------------------------------------*/ +static void hdd_full_power_callback(void *callbackContext, eHalStatus status) +{ + struct statsContext *pContext = callbackContext; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: context = %p, status = %d", __func__, pContext, status); + + if (NULL == callbackContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, context [%p]", + __func__, callbackContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if (POWER_CONTEXT_MAGIC != pContext->magic) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, magic [%08x]", + __func__, pContext->magic); + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pContext->magic = 0; + + /* notify the caller */ + complete(&pContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +static inline VOS_STATUS hdd_UnregisterWext_all_adapters(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_IBSS) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) || + (pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + wlan_hdd_cfg80211_deregister_frames(pAdapter); + hdd_UnregisterWext(pAdapter->dev); + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) + { + pAdapter = pAdapterNode->pAdapter; + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_IBSS) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) || + (pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) { + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_exit() - HDD WLAN exit function + + This is the driver exit point (invoked during rmmod) + + \param - pHddCtx - Pointer to the HDD Context + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_wlan_exit(hdd_context_t *pHddCtx) +{ + eHalStatus halStatus; + v_CONTEXT_t pVosContext = pHddCtx->pvosContext; + VOS_STATUS vosStatus; + struct wiphy *wiphy = pHddCtx->wiphy; + struct statsContext powerContext; + unsigned long rc; + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + ENTER(); + + if (VOS_FTM_MODE != hdd_get_conparam()) + { + // Unloading, restart logic is no more required. + wlan_hdd_restart_deinit(pHddCtx); + } + + hdd_UnregisterWext_all_adapters(pHddCtx); + + if (VOS_FTM_MODE == hdd_get_conparam()) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: FTM MODE", __func__); +#if defined(QCA_WIFI_FTM) + if (hdd_ftm_stop(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_ftm_stop Failed",__func__); + VOS_ASSERT(0); + } + pHddCtx->ftm.ftm_state = WLAN_FTM_STOPPED; +#endif + wlan_hdd_ftm_close(pHddCtx); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: FTM driver unloaded", __func__); + goto free_hdd_ctx; + } + + /* DeRegister with platform driver as client for Suspend/Resume */ + vosStatus = hddDeregisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__); + VOS_ASSERT(0); + } + + vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__); + } + + /* + * Cancel any outstanding scan requests. We are about to close all + * of our adapters, but an adapter structure is what SME passes back + * to our callback function. Hence if there are any outstanding scan + * requests then there is a race condition between when the adapter + * is closed and when the callback is invoked. We try to resolve that + * race condition here by cancelling any outstanding scans before we + * close the adapters. + * Note that the scans may be cancelled in an asynchronous manner, so + * ideally there needs to be some kind of synchronization. Rather than + * introduce a new synchronization here, we will utilize the fact that + * we are about to Request Full Power, and since that is synchronized, + * the expectation is that by the time Request Full Power has completed, + * all scans will be cancelled. + */ + hdd_abort_mac_scan_all_adapters(pHddCtx); + + /* Stop the traffic monitor timer */ + if ((NULL != pConfig) && (pConfig->dynSplitscan)) { + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)) { + vos_timer_stop(&pHddCtx->tx_rx_trafficTmr); + } + + /* Destroy the traffic monitor timer */ + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->tx_rx_trafficTmr))) { + hddLog(LOGE, FL("Cannot de-allocate Traffic monitor timer")); + } + } + +#ifdef MSM_PLATFORM + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) + { + vos_timer_stop(&pHddCtx->bus_bw_timer); + } + + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->bus_bw_timer))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate Bus bandwidth timer", __func__); + } +#endif + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->skip_acs_scan_timer)) { + vos_timer_stop(&pHddCtx->skip_acs_scan_timer); + } + + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->skip_acs_scan_timer))) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate ACS Skip timer", __func__); + } +#endif + + if (pConfig && !pConfig->enablePowersaveOffload) + { + //Disable IMPS/BMPS as we do not want the device to enter any power + //save mode during shutdown + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE); + + //Ensure that device is in full power as we will touch H/W during vos_Stop + init_completion(&powerContext.completion); + powerContext.magic = POWER_CONTEXT_MAGIC; + + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback, + &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD); + + if (eHAL_STATUS_SUCCESS != halStatus) + { + if (eHAL_STATUS_PMC_PENDING == halStatus) + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout( + &powerContext.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: timed out while requesting full power", + __func__); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request for Full Power failed, status %d", + __func__, halStatus); + /* continue -- need to clean up as much as possible */ + } + } + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + powerContext.magic = 0; + spin_unlock(&hdd_context_lock); + } + else + { + /* + * Powersave Offload Case + * Disable Idle Power Save Mode + */ + hdd_set_idle_ps_config(pHddCtx, FALSE); + } + + hdd_debugfs_exit(pHddCtx); + + // Unregister the Net Device Notifier + unregister_netdevice_notifier(&hdd_netdev_notifier); + + /* Stop all adapters, this will ensure the termination of active + * connections on the interface. Make sure the vos_scheduler is + * still available to handle those control messages + */ + hdd_stop_all_adapters( pHddCtx ); + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop BAP",__func__); + } +#endif //WLAN_BTAMP_FEATURE + + //Stop all the modules + vosStatus = vos_stop( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop VOSS",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + //This requires pMac access, Call this before vos_close(). + hdd_unregister_mcast_bcast_filter(pHddCtx); + + //Close the scheduler before calling vos_close to make sure no thread is + // scheduled after the each module close is called i.e after all the data + // structures are freed. + vosStatus = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + /* Destroy the wake lock */ + vos_wake_lock_destroy(&pHddCtx->rx_wake_lock); +#endif + /* Destroy the wake lock */ + vos_wake_lock_destroy(&pHddCtx->sap_wake_lock); + + hdd_hostapd_channel_wakelock_deinit(pHddCtx); + + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + //Close VOSS + //This frees pMac(HAL) context. There should not be any call that requires pMac access after this. + vos_close(pVosContext); + +#ifdef FEATURE_GREEN_AP + if (!VOS_IS_STATUS_SUCCESS( + hdd_wlan_green_ap_deattach(pHddCtx))) + { + hddLog(LOGE, FL("Cannot deallocate Green-AP resource")); + } +#endif + + //Close Watchdog + if (pConfig && pConfig->fIsLogpEnabled) + vos_watchdog_close(pVosContext); + + //Clean up HDD Nlink Service + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if (pConfig && pConfig->wlanLoggingEnable) + { + wlan_logging_sock_deactivate_svc(); + } +#endif + +#ifdef WLAN_KD_READY_NOTIFIER + cnss_diag_notify_wlan_close(); + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ + + + hdd_close_all_adapters( pHddCtx ); + +#ifdef IPA_OFFLOAD + hdd_ipa_cleanup(pHddCtx); +#endif + + /* free the power on lock from platform driver */ + if (free_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock", + __func__); + } + + /* Free up RoC request queue and flush workqueue */ + vos_flush_work(&pHddCtx->rocReqWork); + hdd_list_destroy(&pHddCtx->hdd_roc_req_q); + +free_hdd_ctx: + /* Free up dynamically allocated members inside HDD Adapter */ + if (pHddCtx->cfg_ini) { + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + } + + /* FTM mode, WIPHY did not registered + If un-register here, system crash will happen */ + if (VOS_FTM_MODE != hdd_get_conparam()) + { + wiphy_unregister(wiphy) ; + } + wiphy_free(wiphy) ; + if (hdd_is_ssr_required()) + { +#ifdef MSM_PLATFORM +#ifdef CONFIG_CNSS + /* WDI timeout had happened during unload, so SSR is needed here */ + subsystem_restart("wcnss"); +#endif +#endif + msleep(5000); + } + hdd_set_ssr_required (VOS_FALSE); +} + +void __hdd_wlan_exit(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + ENTER(); + + //Get the global vos context + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!pVosContext) + return; + if (WLAN_IS_EPPING_ENABLED(con_mode)) { + epping_exit(pVosContext); + return; + } + + if(NULL == pVosContext) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid global VOSS context", __func__); + EXIT(); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, + pVosContext); + + if(NULL == pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid HDD Context", __func__); + EXIT(); + return; + } + + /* module exit should never proceed if SSR is not completed */ + while(pHddCtx->isLogpInProgress){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:SSR in Progress; block rmmod for 1 second!!!", + __func__); + msleep(1000); + } + + pHddCtx->isUnloadInProgress = TRUE; + + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + +#ifdef WLAN_FEATURE_LPSS + wlan_hdd_send_status_pkg(NULL, NULL, 0, 0); +#endif + + //Do all the cleanup before deregistering the driver + hdd_wlan_exit(pHddCtx); + EXIT(); +} + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE +void hdd_skip_acs_scan_timer_handler(void * data) +{ + hdd_context_t *pHddCtx = (hdd_context_t *) data; + hddLog(LOG1, FL("ACS Scan result expired. Reset ACS scan skip")); + pHddCtx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; +} +#endif + +#ifdef QCA_HT_2040_COEX +/**-------------------------------------------------------------------------- + + \brief notify FW with HT20/HT40 mode + + -------------------------------------------------------------------------*/ +int hdd_wlan_set_ht2040_mode(hdd_adapter_t *pAdapter, v_U16_t staId, + v_MACADDR_t macAddrSTA, int channel_type) +{ + int status; + VOS_STATUS vosStatus; + hdd_context_t *pHddCtx = NULL; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return -1; + } + if (!pHddCtx->hHal) + return -1; + + vosStatus = sme_notify_ht2040_mode(pHddCtx->hHal, staId, macAddrSTA, + pAdapter->sessionId, channel_type); + if (VOS_STATUS_SUCCESS != vosStatus) { + hddLog(LOGE, "Fail to send notification with ht2040 mode\n"); + return -1; + } + + return 0; +} +#endif + +/**-------------------------------------------------------------------------- + + \brief notify FW with modem power status + + -------------------------------------------------------------------------*/ +int hdd_wlan_notify_modem_power_state(int state) +{ + int status; + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!pVosContext) + return -1; + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return -1; + } + if (!pHddCtx->hHal) + return -1; + + vosStatus = sme_notify_modem_power_state(pHddCtx->hHal, state); + if (VOS_STATUS_SUCCESS != vosStatus) { + hddLog(LOGE, "Fail to send notification with modem power state %d", + state); + return -1; + } + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_post_voss_start_config() - HDD post voss start config helper + + \param - pAdapter - Pointer to the HDD + + \return - None + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx) +{ + eHalStatus halStatus; + v_U32_t listenInterval; + tANI_U32 ignoreDtim; + + + // Send ready indication to the HDD. This will kick off the MAC + // into a 'running' state and should kick off an initial scan. + halStatus = sme_HDDReadyInd( pHddCtx->hHal ); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status " + "code %08d [x%08x]",__func__, halStatus, halStatus ); + return VOS_STATUS_E_FAILURE; + } + + // Set default LI and ignoreDtim into HDD context, + // otherwise under some race condition, HDD will set 0 LI value into RIVA, + // And RIVA will crash + wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval); + pHddCtx->hdd_actual_LI_value = listenInterval; + wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim); + pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim; + + + return VOS_STATUS_SUCCESS; +} + +/* wake lock APIs for HDD */ +void hdd_prevent_suspend(void) +{ + vos_wake_lock_acquire(&wlan_wake_lock); +} + +void hdd_allow_suspend(void) +{ + vos_wake_lock_release(&wlan_wake_lock); +} + +void hdd_prevent_suspend_timeout(v_U32_t timeout) +{ + vos_wake_lock_timeout_acquire(&wlan_wake_lock, timeout); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability + information between Host and Riva + + This function gets reported version of FW + It also finds the version of Riva headers used to compile the host + It compares the above two and prints a warning if they are different + It gets the SW and HW version string + Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg + indicating the features they support through a bitmap + + \param - pHddCtx - Pointer to HDD context + + \return - void + + --------------------------------------------------------------------------*/ + +void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx) +{ + + tSirVersionType versionCompiled; + tSirVersionType versionReported; + tSirVersionString versionString; + tANI_U8 fwFeatCapsMsgSupported = 0; + VOS_STATUS vstatus; + + memset(&versionCompiled, 0, sizeof(versionCompiled)); + memset(&versionReported, 0, sizeof(versionReported)); + + /* retrieve and display WCNSS version information */ + do { + + vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal, + &versionCompiled); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS WLAN compiled version", + __func__); + break; + } + + vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal, + &versionReported); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS WLAN reported version", + __func__); + break; + } + + if ((versionCompiled.major != versionReported.major) || + (versionCompiled.minor != versionReported.minor) || + (versionCompiled.version != versionReported.version) || + (versionCompiled.revision != versionReported.revision)) + { + pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, " + "Host expected %u.%u.%u.%u\n", + WLAN_MODULE_NAME, + (int)versionReported.major, + (int)versionReported.minor, + (int)versionReported.version, + (int)versionReported.revision, + (int)versionCompiled.major, + (int)versionCompiled.minor, + (int)versionCompiled.version, + (int)versionCompiled.revision); + } + else + { + pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n", + WLAN_MODULE_NAME, + (int)versionReported.major, + (int)versionReported.minor, + (int)versionReported.version, + (int)versionReported.revision); + } + + vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal, + versionString, + sizeof(versionString)); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS software version string", + __func__); + break; + } + + pr_info("%s: WCNSS software version %s\n", + WLAN_MODULE_NAME, versionString); + + vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal, + versionString, + sizeof(versionString)); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS hardware version string", + __func__); + break; + } + + pr_info("%s: WCNSS hardware version %s\n", + WLAN_MODULE_NAME, versionString); + + /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message + 2.Host-FW capability exchange message is only present on riva 1.1 so + send the message only if it the riva is 1.1 + minor numbers for different riva branches: + 0 -> (1.0)Mainline Build + 1 -> (1.1)Mainline Build + 2->(1.04) Stability Build + */ + if (((versionReported.major>0) || (versionReported.minor>1) || + ((versionReported.minor>=1) && (versionReported.version>=1))) + && ((versionReported.major == 1) && (versionReported.minor >= 1))) + fwFeatCapsMsgSupported = 1; + + if (fwFeatCapsMsgSupported) + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(!pHddCtx->cfg_ini->fEnableActiveModeOffload) + sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD); +#endif + /* Indicate if IBSS heartbeat monitoring needs to be offloaded */ + if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload) + { + sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD); + } + + sme_featureCapsExchange(pHddCtx->hHal); + } + + } while (0); + +} + +/* Initialize channel list in sme based on the country code */ +VOS_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx) +{ + return sme_init_chan_list(hdd_ctx->hHal, hdd_ctx->reg.alpha2, + hdd_ctx->reg.cc_src); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz + + \param - pHddCtx - Pointer to the hdd context + + \return - true if hardware supports 5GHz + + --------------------------------------------------------------------------*/ +boolean hdd_is_5g_supported(hdd_context_t * pHddCtx) +{ + /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1); + * then hardware support 5Ghz. + */ + return true; +} + +#define WOW_MAX_FILTER_LISTS 1 +#define WOW_MAX_FILTERS_PER_LIST 4 +#define WOW_MIN_PATTERN_SIZE 6 +#define WOW_MAX_PATTERN_SIZE 64 + +static VOS_STATUS wlan_hdd_reg_init(hdd_context_t *hdd_ctx) +{ + struct wiphy *wiphy; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + wiphy = hdd_ctx->wiphy; + + /* initialize the NV module. This is required so that + we can initialize the channel information in wiphy + from the NV.bin data. The channel information in + wiphy needs to be initialized before wiphy registration */ + + status = vos_init_wiphy_from_eeprom(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_init_wiphy failed", __func__); + return status; + } + + wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | + WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_EAP_IDENTITY_REQ | + WIPHY_WOWLAN_4WAY_HANDSHAKE | + WIPHY_WOWLAN_RFKILL_RELEASE; + + wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS * + WOW_MAX_FILTERS_PER_LIST); + wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE; + wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE; + + /* registration of wiphy dev with cfg80211 */ + if (0 > wlan_hdd_cfg80211_register(wiphy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__); + status = VOS_STATUS_E_FAILURE; + } + + return status; +} + + +#ifdef MSM_PLATFORM +void hdd_cnss_request_bus_bandwidth(hdd_context_t *pHddCtx, + uint64_t tx_packets, uint64_t rx_packets) +{ +#ifdef CONFIG_CNSS + uint64_t total = tx_packets + rx_packets; + enum cnss_bus_width_type next_vote_level = CNSS_BUS_WIDTH_NONE; + + uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2; + enum cnss_bus_width_type next_rx_level = CNSS_BUS_WIDTH_NONE; + + + if (total > pHddCtx->cfg_ini->busBandwidthHighThreshold) + next_vote_level = CNSS_BUS_WIDTH_HIGH; + else if (total > pHddCtx->cfg_ini->busBandwidthMediumThreshold) + next_vote_level = CNSS_BUS_WIDTH_MEDIUM; + else + next_vote_level = CNSS_BUS_WIDTH_LOW; + + if (pHddCtx->cur_vote_level != next_vote_level) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + "%s: trigger level %d, tx_packets: %lld, rx_packets: %lld", + __func__, next_vote_level, tx_packets, rx_packets); + pHddCtx->cur_vote_level = next_vote_level; + cnss_request_bus_bandwidth(next_vote_level); + + if (next_vote_level == CNSS_BUS_WIDTH_LOW) { + if (vos_sched_handle_throughput_req(false)) + hddLog(LOGE, FL("low bandwidth set rx affinity fail")); + } else { + if (vos_sched_handle_throughput_req(true)) + hddLog(LOGE, FL("high bandwidth set rx affinity fail")); + } + } + + pHddCtx->prev_rx = rx_packets; + if (temp_rx > pHddCtx->cfg_ini->tcpDelackThresholdHigh) + next_rx_level = CNSS_BUS_WIDTH_HIGH; + else + next_rx_level = CNSS_BUS_WIDTH_LOW; + + if (pHddCtx->cur_rx_level != next_rx_level) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: TCP DELACK trigger level %d, average_rx: %llu", + __func__, next_rx_level, temp_rx); + pHddCtx->cur_rx_level = next_rx_level; + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, + &next_rx_level, + sizeof(next_rx_level)); + } +#endif +} + +#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x))) +static void hdd_bus_bw_compute_cbk(void *priv) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)priv; + hdd_adapter_t *pAdapter = NULL; + uint64_t tx_packets= 0, rx_packets= 0; + hdd_adapter_list_node_t *pAdapterNode = NULL; + VOS_STATUS status = 0; + v_BOOL_t connected = FALSE; +#ifdef IPA_UC_OFFLOAD + uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0; + hdd_adapter_t *pValidAdapter = NULL; +#endif /* IPA_UC_OFFLOAD */ + + for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + NULL != pAdapterNode && VOS_STATUS_SUCCESS == status; + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) + { + + if ((pAdapter = pAdapterNode->pAdapter) == NULL) + continue; + +#ifdef IPA_UC_OFFLOAD + pValidAdapter = pAdapter; +#endif /* IPA_UC_OFFLOAD */ + + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION || + pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) && + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)->conn_info.connState + != eConnectionState_Associated) { + + continue; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO) && + WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->bApActive == VOS_FALSE) { + + continue; + } + + tx_packets += HDD_BW_GET_DIFF(pAdapter->stats.tx_packets, + pAdapter->prev_tx_packets); + rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets, + pAdapter->prev_rx_packets); + + spin_lock_bh(&pHddCtx->bus_bw_lock); + pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + spin_unlock_bh(&pHddCtx->bus_bw_lock); + connected = TRUE; + } +#ifdef IPA_UC_OFFLOAD + hdd_ipa_uc_stat_query(pHddCtx, &ipa_tx_packets, &ipa_rx_packets); + tx_packets += (uint64_t)ipa_tx_packets; + rx_packets += (uint64_t)ipa_rx_packets; +#endif /* IPA_UC_OFFLOAD */ + if (!connected) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "bus bandwidth timer running in disconnected state"); + return; + } + + hdd_cnss_request_bus_bandwidth(pHddCtx, tx_packets, rx_packets); + +#ifdef IPA_OFFLOAD + hdd_ipa_set_perf_level(pHddCtx, tx_packets, rx_packets); +#ifdef IPA_UC_OFFLOAD + hdd_ipa_uc_stat_request(pValidAdapter, 2); +#endif /* IPA_UC_OFFLOAD */ +#endif + + vos_timer_start(&pHddCtx->bus_bw_timer, + pHddCtx->cfg_ini->busBandwidthComputeInterval); +} +#endif + + +/**--------------------------------------------------------------------------- + \brief hdd_11d_scan_done - callback to be executed when 11d scan is + completed to flush out the scan results + + 11d scan is done during driver load and is a passive scan on all + channels supported by the device, 11d scans may find some APs on + frequencies which are forbidden to be used in the regulatory domain + the device is operating in. If these APs are notified to the supplicant + it may try to connect to these APs, thus flush out all the scan results + which are present in SME after 11d scan is done. + + \return - eHalStatus + + --------------------------------------------------------------------------*/ +static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext, + tANI_U8 sessionId, tANI_U32 scanId, + eCsrScanStatus status) +{ + ENTER(); + + sme_ScanFlushResult(halHandle, 0); + + EXIT(); + + return eHAL_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_startup() - HDD init function + + This is the driver startup code executed once a WLAN device has been detected + + \param - dev - Pointer to the underlying device + + \return - 0 for success, < 0 for failure + + --------------------------------------------------------------------------*/ + +int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) +{ + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; +#ifdef WLAN_OPEN_P2P_INTERFACE + hdd_adapter_t *pP2pAdapter = NULL; +#endif + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext= NULL; +#ifdef WLAN_BTAMP_FEATURE + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + WLANBAP_ConfigType btAmpConfig; + hdd_config_t *pConfig; +#endif + int ret; + int i; + struct wiphy *wiphy; + unsigned long rc; + tSmeThermalParams thermalParam; + tSirTxPowerLimit *hddtxlimit; +#ifdef FEATURE_WLAN_CH_AVOID + int unsafeChannelIndex; +#endif + + ENTER(); + + if (WLAN_IS_EPPING_ENABLED(con_mode)) { + /* if epping enabled redirect start to epping module */ + ret = epping_wlan_startup(dev, hif_sc); + EXIT(); + return ret; + } + /* + * cfg80211: wiphy allocation + */ + wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ; + + if(wiphy == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__); + return -EIO; + } + + pHddCtx = wiphy_priv(wiphy); + + //Initialize the adapter context to zeros. + vos_mem_zero(pHddCtx, sizeof( hdd_context_t )); + + pHddCtx->wiphy = wiphy; + pHddCtx->isLoadInProgress = TRUE; + pHddCtx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; + + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + /*Get vos context here bcoz vos_open requires it*/ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(pVosContext == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__); + goto err_free_hdd_context; + } + + //Save the Global VOSS context in adapter context for future. + pHddCtx->pvosContext = pVosContext; + + //Save the adapter context in global context for future. + ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx; + + pHddCtx->parent_dev = dev; + + init_completion(&pHddCtx->full_pwr_comp_var); + init_completion(&pHddCtx->standby_comp_var); + init_completion(&pHddCtx->req_bmps_comp_var); + + spin_lock_init(&pHddCtx->schedScan_lock); + + hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS ); + +#ifdef FEATURE_WLAN_TDLS + /* tdls_lock is initialized before an hdd_open_adapter ( which is + * invoked by other instances also) to protect the concurrent + * access for the Adapters by TDLS module. + */ + mutex_init(&pHddCtx->tdls_lock); +#endif + + // Load all config first as TL config is needed during vos_open + pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL); + if(pHddCtx->cfg_ini == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__); + goto err_free_hdd_context; + } + + vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t )); + + // Read and parse the qcom_cfg.ini file + status = hdd_parse_config_ini( pHddCtx ); + if ( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s", + __func__, WLAN_INI_FILE); + goto err_config; + } + + ((VosContextType*)pVosContext)->pHIFContext = hif_sc; + + /* store target type and target version info in hdd ctx */ + pHddCtx->target_type = ((struct ol_softc *)hif_sc)->target_type; + + pHddCtx->current_intf_count=0; + pHddCtx->max_intf_count = CSR_ROAM_SESSION_MAX; + + /* INI has been read, initialise the configuredMcastBcastFilter with + * INI value as this will serve as the default value + */ + pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting; + hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d", + pHddCtx->cfg_ini->mcastBcastFilterSetting); + + if (false == hdd_is_5g_supported(pHddCtx)) + { + //5Ghz is not supported. + if (1 != pHddCtx->cfg_ini->nBandCapability) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__); + pHddCtx->cfg_ini->nBandCapability = 1; + } + } + + /* + * If SNR Monitoring is enabled, FW has to parse all beacons + * for calculating and storing the average SNR, so set Nth beacon + * filter to 1 to enable FW to parse all the beacons + */ + if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring) + { + /* The log level is deliberately set to WARN as overriding + * nthBeaconFilter to 1 will increase power consumption and this + * might just prove helpful to detect the power issue. + */ + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__); + pHddCtx->cfg_ini->nthBeaconFilter = 1; + } + /* + * cfg80211: Initialization ... + */ +#if !defined(LINUX_QCMBR) + if (VOS_FTM_MODE != hdd_get_conparam()) +#endif + { + if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: wlan_hdd_cfg80211_init return failure", __func__); + goto err_config; + } + } + + /* Initialize struct for saving f/w log setting will be used + after ssr */ + pHddCtx->fw_log_settings.enable = pHddCtx->cfg_ini->enablefwlog; + pHddCtx->fw_log_settings.dl_type = 0; + pHddCtx->fw_log_settings.dl_report = 0; + pHddCtx->fw_log_settings.dl_loglevel = 0; + pHddCtx->fw_log_settings.index = 0; + for (i = 0; i < MAX_MOD_LOGLEVEL; i++) { + pHddCtx->fw_log_settings.dl_mod_loglevel[i] = 0; + } + // Update VOS trace levels based upon the cfg.ini + hdd_vos_trace_enable(VOS_MODULE_ID_BAP, + pHddCtx->cfg_ini->vosTraceEnableBAP); + hdd_vos_trace_enable(VOS_MODULE_ID_TL, + pHddCtx->cfg_ini->vosTraceEnableTL); + hdd_vos_trace_enable(VOS_MODULE_ID_WDI, + pHddCtx->cfg_ini->vosTraceEnableWDI); + hdd_vos_trace_enable(VOS_MODULE_ID_HDD, + pHddCtx->cfg_ini->vosTraceEnableHDD); + hdd_vos_trace_enable(VOS_MODULE_ID_SME, + pHddCtx->cfg_ini->vosTraceEnableSME); + hdd_vos_trace_enable(VOS_MODULE_ID_PE, + pHddCtx->cfg_ini->vosTraceEnablePE); + hdd_vos_trace_enable(VOS_MODULE_ID_PMC, + pHddCtx->cfg_ini->vosTraceEnablePMC); + hdd_vos_trace_enable(VOS_MODULE_ID_WDA, + pHddCtx->cfg_ini->vosTraceEnableWDA); + hdd_vos_trace_enable(VOS_MODULE_ID_SYS, + pHddCtx->cfg_ini->vosTraceEnableSYS); + hdd_vos_trace_enable(VOS_MODULE_ID_VOSS, + pHddCtx->cfg_ini->vosTraceEnableVOSS); + hdd_vos_trace_enable(VOS_MODULE_ID_SAP, + pHddCtx->cfg_ini->vosTraceEnableSAP); + hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP, + pHddCtx->cfg_ini->vosTraceEnableHDDSAP); + + print_hdd_cfg(pHddCtx); + + if (VOS_FTM_MODE == hdd_get_conparam()) + goto ftm_processing; + + //Open watchdog module + if(pHddCtx->cfg_ini->fIsLogpEnabled) + { + status = vos_watchdog_open(pVosContext, + &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext)); + + if(!VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__); + goto err_wdclose; + } + } + + pHddCtx->isLogpInProgress = FALSE; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); + + status = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_nv_open failed", __func__); + goto err_wdclose; + } + + status = vos_open( &pVosContext, 0); + if ( !VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__); + goto err_vos_nv_close; + } + + wlan_hdd_update_wiphy(wiphy, pHddCtx->cfg_ini); + +#if !defined(REMOVE_PKT_LOG) + hif_init_pdev_txrx_handle(hif_sc, + vos_get_context(VOS_MODULE_ID_TXRX, pVosContext)); +#endif + + pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext ); + + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__); + goto err_vosclose; + } + + status = vos_preStart( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__); + goto err_vosclose; + } + + status = wlan_hdd_reg_init(pHddCtx); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to init channel list", __func__); + goto err_vosclose; + } + + if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) + { + pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d", + __func__, enable_dfs_chan_scan); + } + if (0 == enable_11d || 1 == enable_11d) + { + pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d", + __func__, enable_11d); + } + + /* Note that the vos_preStart() sequence triggers the cfg download. + The cfg download must occur before we update the SME config + since the SME config operation must access the cfg database */ + status = hdd_set_sme_config( pHddCtx ); + + if ( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__); + goto err_wiphy_unregister; + } + + status = hdd_set_sme_chan_list(pHddCtx); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to init channel list", __func__); + goto err_wiphy_unregister; + } + + /* In the integrated architecture we update the configuration from + the INI file and from NV before vOSS has been started so that + the final contents are available to send down to the cCPU */ + + // Apply the cfg.ini to cfg.dat + if (FALSE == hdd_update_config_dat(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ ); + goto err_wiphy_unregister; + } + + if ( VOS_STATUS_SUCCESS != hdd_update_mac_config( pHddCtx ) ) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: can't update mac config, using MAC from ini file", + __func__); + } + + { + eHalStatus halStatus; + /* Set the MAC Address Currently this is used by HAL to + * add self sta. Remove this once self sta is added as + * part of session open. + */ + halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID, + (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0], + sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) ); + + if (!HAL_STATUS_SUCCESS( halStatus )) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. " + "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus ); + goto err_wiphy_unregister; + } + } + +#ifdef IPA_OFFLOAD + if (hdd_ipa_init(pHddCtx) == VOS_STATUS_E_FAILURE) + goto err_wiphy_unregister; +#endif + + /*Start VOSS which starts up the SME/MAC/HAL modules and everything else */ + status = vos_start( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); + goto err_wiphy_unregister; + } + +#ifdef FEATURE_WLAN_CH_AVOID + cnss_get_wlan_unsafe_channel(pHddCtx->unsafe_channel_list, + &(pHddCtx->unsafe_channel_count), + sizeof(v_U16_t) * NUM_20MHZ_RF_CHANNELS); + + hddLog(VOS_TRACE_LEVEL_INFO,"%s: num of unsafe channels is %d. ", + __func__, + pHddCtx->unsafe_channel_count); + for (unsafeChannelIndex = 0; + unsafeChannelIndex < pHddCtx->unsafe_channel_count; + unsafeChannelIndex++) + { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: channel %d is not safe. ", + __func__, pHddCtx->unsafe_channel_list[unsafeChannelIndex]); + + } + + /* Plug in avoid channel notification callback */ + sme_AddChAvoidCallback(pHddCtx->hHal, + hdd_ch_avoid_cb); +#endif /* FEATURE_WLAN_CH_AVOID */ + + status = hdd_post_voss_start_config( pHddCtx ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed", + __func__); + goto err_vosstop; + } + +#ifdef QCA_PKT_PROTO_TRACE + vos_pkt_proto_trace_init(); +#endif /* QCA_PKT_PROTO_TRACE */ + + ftm_processing: + if (VOS_FTM_MODE == hdd_get_conparam()) + { + if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__); + goto err_config; + } +#if defined(QCA_WIFI_FTM) + if (hdd_ftm_start(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_ftm_start Failed",__func__); + goto err_free_ftm_open; + } +#endif + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE); + pHddCtx->isLoadInProgress = FALSE; + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded", __func__); + complete(&wlan_start_comp); + return VOS_STATUS_SUCCESS; + } + + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE ); + +#ifdef WLAN_OPEN_P2P_INTERFACE + /* Open P2P device interface */ + if (pAdapter != NULL) + { + if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated) + { + vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes, + pHddCtx->cfg_ini->intfMacAddr[0].bytes, + sizeof(tSirMacAddr)); + + /* Generate the P2P Device Address. This consists of the device's + * primary MAC address with the locally administered bit set. + */ + pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02; + } + else + { + tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx); + if (p2p_dev_addr != NULL) + { + vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0], + p2p_dev_addr, VOS_MAC_ADDR_SIZE); + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to allocate mac_address for p2p_device", + __func__); + goto err_close_adapter; + } + } + + pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d", + &pHddCtx->p2pDeviceAddress.bytes[0], FALSE ); + if ( NULL == pP2pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to do hdd_open_adapter for P2P Device Interface", + __func__); + goto err_close_adapter; + } + } +#endif + + if( pAdapter == NULL ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__); + goto err_close_adapter; + } + + + /* Target hw version/revision would only be retrieved after + firmware download */ + hif_get_hw_info(hif_sc, &pHddCtx->target_hw_version, + &pHddCtx->target_hw_revision); + + /* Get the wlan hw/fw version */ + hdd_wlan_get_version(pAdapter, NULL, NULL); + + /* pass target_fw_version to HIF layer */ + hif_set_fw_info(hif_sc, pHddCtx->target_fw_version); + + if (country_code) + { + eHalStatus ret; + + INIT_COMPLETION(pAdapter->change_country_code); + hdd_checkandupdate_dfssetting(pAdapter, country_code); + + ret = sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_callback, + country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE); + if (eHAL_STATUS_SUCCESS == ret) + { + rc = wait_for_completion_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME while setting country code timed out", __func__); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME Change Country code from module param fail ret=%d", __func__, ret); + ret = -EINVAL; + } + } + +#ifdef WLAN_BTAMP_FEATURE + vStatus = WLANBAP_Open(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open BAP",__func__); + goto err_close_adapter; + } + + vStatus = BSL_Init(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Init BSL",__func__); + goto err_bap_close; + } + vStatus = WLANBAP_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start TL",__func__); + goto err_bap_close; + } + + pConfig = pHddCtx->cfg_ini; + btAmpConfig.ucPreferredChannel = pConfig->preferredChannel; + status = WLANBAP_SetConfig(&btAmpConfig); + +#endif //WLAN_BTAMP_FEATURE + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE)) + { + hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__); + pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0; + sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + } +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + /*SME must send channel update configuration to RIVA*/ + sme_UpdateChannelConfig(pHddCtx->hHal); +#endif + sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done); + + /* Register with platform driver as client for Suspend/Resume */ + status = hddRegisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__); +#ifdef WLAN_BTAMP_FEATURE + goto err_bap_stop; +#else + goto err_close_adapter; +#endif //WLAN_BTAMP_FEATURE + } + + /* Open debugfs interface */ + if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_debugfs_init failed!", __func__); + } + + /* Register TM level change handler function to the platform */ + status = hddDevTmRegisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__); + goto err_unregister_pmops; + } + + /* register for riva power on lock to platform driver */ + if (req_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed", + __func__); + goto err_unregister_pmops; + } + + // register net device notifier for device change notification + ret = register_netdevice_notifier(&hdd_netdev_notifier); + + if(ret < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__); + goto err_free_power_on_lock; + } + + //Initialize the nlink service + if(nl_srv_init() != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__); + goto err_reg_netdev; + } + +#ifdef WLAN_KD_READY_NOTIFIER + pHddCtx->kd_nl_init = 1; +#endif /* WLAN_KD_READY_NOTIFIER */ + + //Initialize the BTC service + if(btc_activate_service(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__); + goto err_nl_srv; + } + +#ifdef FEATURE_OEM_DATA_SUPPORT + //Initialize the OEM service + if (oem_activate_service(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: oem_activate_service failed", __func__); + goto err_nl_srv; + } +#endif + +#ifdef PTT_SOCK_SVC_ENABLE + //Initialize the PTT service + if(ptt_sock_activate_svc(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__); + goto err_nl_srv; + } +#endif + + //Initialize the CNSS-DIAG service + if (cnss_diag_activate_service() < 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: cnss_diag_activate_service failed", __func__); + goto err_nl_srv; + } + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if (pHddCtx->cfg_ini->wlanLoggingEnable) { + if (wlan_logging_sock_activate_svc( + pHddCtx->cfg_ini->wlanLoggingFEToConsole, + pHddCtx->cfg_ini->wlanLoggingNumBuf)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: wlan_logging_sock_activate_svc failed", __func__); + goto err_nl_srv; + } + } +#endif + + hdd_register_mcast_bcast_filter(pHddCtx); + if (VOS_STA_SAP_MODE != hdd_get_conparam()) + { + /* Action frame registered in one adapter which will + * applicable to all interfaces + */ + wlan_hdd_cfg80211_register_frames(pAdapter); + } + + mutex_init(&pHddCtx->sap_lock); + + pHddCtx->isLoadInProgress = FALSE; + pHddCtx->wifi_turn_on_time_since_boot = adf_get_boottime(); + +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + /* Initialize the wake lcok */ + vos_wake_lock_init(&pHddCtx->rx_wake_lock, + "qcom_rx_wakelock"); +#endif + /* Initialize the wake lcok */ + vos_wake_lock_init(&pHddCtx->sap_wake_lock, + "qcom_sap_wakelock"); + + hdd_hostapd_channel_wakelock_init(pHddCtx); + + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE); + + // Initialize the restart logic + wlan_hdd_restart_init(pHddCtx); + + //Register the traffic monitor timer now + if ( pHddCtx->cfg_ini->dynSplitscan) + { + vos_timer_init(&pHddCtx->tx_rx_trafficTmr, + VOS_TIMER_TYPE_SW, + hdd_tx_rx_pkt_cnt_stat_timer_handler, + (void *)pHddCtx); + } + + if(pHddCtx->cfg_ini->enablePowersaveOffload) + { + hdd_set_idle_ps_config(pHddCtx, TRUE); + } + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + if (pHddCtx->cfg_ini->WlanAutoShutdown != 0) + if (sme_set_auto_shutdown_cb(pHddCtx->hHal, wlan_hdd_auto_shutdown_cb) + != eHAL_STATUS_SUCCESS) + hddLog(LOGE, FL("Auto shutdown feature could not be enabled")); +#endif + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + status = vos_timer_init(&pHddCtx->skip_acs_scan_timer, VOS_TIMER_TYPE_SW, + hdd_skip_acs_scan_timer_handler, (void *)pHddCtx); + if (!VOS_IS_STATUS_SUCCESS(status)) + hddLog(LOGE, FL("Failed to init ACS Skip timer\n")); +#endif + +#ifdef FEATURE_GREEN_AP + if (!VOS_IS_STATUS_SUCCESS( + hdd_wlan_green_ap_attach(pHddCtx))) { + hddLog(LOGE, FL("Failed to allocate Green-AP resource")); + } +#endif + +#ifdef WLAN_FEATURE_NAN + wlan_hdd_cfg80211_nan_init(pHddCtx); +#endif + + /* Thermal Mitigation */ + thermalParam.smeThermalMgmtEnabled = + pHddCtx->cfg_ini->thermalMitigationEnable; + thermalParam.smeThrottlePeriod = pHddCtx->cfg_ini->throttlePeriod; + + thermalParam.smeThermalLevels[0].smeMinTempThreshold = + pHddCtx->cfg_ini->thermalTempMinLevel0; + thermalParam.smeThermalLevels[0].smeMaxTempThreshold = + pHddCtx->cfg_ini->thermalTempMaxLevel0; + thermalParam.smeThermalLevels[1].smeMinTempThreshold = + pHddCtx->cfg_ini->thermalTempMinLevel1; + thermalParam.smeThermalLevels[1].smeMaxTempThreshold = + pHddCtx->cfg_ini->thermalTempMaxLevel1; + thermalParam.smeThermalLevels[2].smeMinTempThreshold = + pHddCtx->cfg_ini->thermalTempMinLevel2; + thermalParam.smeThermalLevels[2].smeMaxTempThreshold = + pHddCtx->cfg_ini->thermalTempMaxLevel2; + thermalParam.smeThermalLevels[3].smeMinTempThreshold = + pHddCtx->cfg_ini->thermalTempMinLevel3; + thermalParam.smeThermalLevels[3].smeMaxTempThreshold = + pHddCtx->cfg_ini->thermalTempMaxLevel3; + + if (eHAL_STATUS_SUCCESS != sme_InitThermalInfo(pHddCtx->hHal,thermalParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Error while initializing thermal information", __func__); + } + + /* SAR power limit */ + hddtxlimit = vos_mem_malloc(sizeof(tSirTxPowerLimit)); + if (!hddtxlimit) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for TxPowerLimit " + "failed!", __func__); + goto err_nl_srv; + } + hddtxlimit->txPower2g = pHddCtx->cfg_ini->TxPower2g; + hddtxlimit->txPower5g = pHddCtx->cfg_ini->TxPower5g; + + if (eHAL_STATUS_SUCCESS != sme_TxpowerLimit(pHddCtx->hHal,hddtxlimit)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Error setting txlimit in sme", __func__); + } + +#ifdef MSM_PLATFORM + spin_lock_init(&pHddCtx->bus_bw_lock); + vos_timer_init(&pHddCtx->bus_bw_timer, + VOS_TIMER_TYPE_SW, + hdd_bus_bw_compute_cbk, + (void *)pHddCtx); +#endif + +#ifdef WLAN_FEATURE_STATS_EXT + wlan_hdd_cfg80211_stats_ext_init(pHddCtx); +#endif +#ifdef FEATURE_WLAN_EXTSCAN + sme_ExtScanRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_extscan_callback); +#endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + wlan_hdd_cfg80211_link_layer_stats_init(pHddCtx); +#endif + +#ifdef WLAN_FEATURE_LPSS + wlan_hdd_send_all_scan_intf_info(pHddCtx); + wlan_hdd_send_version_pkg(pHddCtx->target_fw_version, + pHddCtx->target_hw_version, + pHddCtx->target_hw_name); +#endif + + /* Initialize the RoC Request queue and work. */ + hdd_list_init((&pHddCtx->hdd_roc_req_q), MAX_ROC_REQ_QUEUE_ENTRY); +#ifdef CONFIG_CNSS + cnss_init_work(&pHddCtx->rocReqWork, wlan_hdd_roc_request_dequeue); +#else + INIT_WORK(&pHddCtx->rocReqWork, wlan_hdd_roc_request_dequeue); +#endif + + complete(&wlan_start_comp); + goto success; + +err_nl_srv: +#ifdef WLAN_KD_READY_NOTIFIER + cnss_diag_notify_wlan_close(); + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ +err_reg_netdev: + unregister_netdevice_notifier(&hdd_netdev_notifier); + +err_free_power_on_lock: + free_riva_power_on_lock("wlan"); + +err_unregister_pmops: + hddDevTmUnregisterNotifyCallback(pHddCtx); + hddDeregisterPmOps(pHddCtx); + + hdd_debugfs_exit(pHddCtx); + +#ifdef WLAN_BTAMP_FEATURE +err_bap_stop: + WLANBAP_Stop(pVosContext); +#endif + +#ifdef WLAN_BTAMP_FEATURE +err_bap_close: + WLANBAP_Close(pVosContext); +#endif + +err_close_adapter: + hdd_close_all_adapters( pHddCtx ); + +err_vosstop: + vos_stop(pVosContext); + +err_wiphy_unregister: + wiphy_unregister(wiphy); + +err_vosclose: + status = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) ); + } + vos_close(pVosContext ); + +err_vos_nv_close: + + vos_nv_close(); + +err_wdclose: + if(pHddCtx->cfg_ini->fIsLogpEnabled) + vos_watchdog_close(pVosContext); + +if (VOS_FTM_MODE == hdd_get_conparam()) +{ +#if defined(QCA_WIFI_FTM) +err_free_ftm_open: + wlan_hdd_ftm_close(pHddCtx); +#endif +} + +err_config: + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + +err_free_hdd_context: + /* wiphy_free() will free the HDD context so remove global reference */ + if (pVosContext) + ((VosContextType*)(pVosContext))->pHDDContext = NULL; + + wiphy_free(wiphy) ; + //kfree(wdev) ; + VOS_BUG(1); + + if (hdd_is_ssr_required()) + { +#ifdef MSM_PLATFORM +#ifdef CONFIG_CNSS + /* WDI timeout had happened during load, so SSR is needed here */ + subsystem_restart("wcnss"); +#endif +#endif + msleep(5000); + } + hdd_set_ssr_required (VOS_FALSE); + + return -EIO; + +success: + EXIT(); + return 0; +} + +/* + * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at + * a time, and wait for the completion interrupt to start the next transfer. + * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS). + * The delay incurred for resuming from IDLE/SA PS is huge during driver load. + * So prevent APPS IDLE/SA PS during driver load for reducing interrupt latency. + */ + +#ifdef CONFIG_CNSS +static inline void hdd_request_pm_qos(int val) +{ + cnss_request_pm_qos(val); +} + +static inline void hdd_remove_pm_qos(void) +{ + cnss_remove_pm_qos(); +} +#else +static inline void hdd_request_pm_qos(int val) +{ +} + +static inline void hdd_remove_pm_qos(void) +{ +} +#endif + +/**--------------------------------------------------------------------------- + + \brief hdd_driver_init() - Core Driver Init Function + + This is the driver entry point - called in different time line depending + on whether the driver is statically or dynamically linked + + \param - None + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_driver_init( void) +{ + VOS_STATUS status; + v_CONTEXT_t pVosContext = NULL; + int ret_status = 0; + unsigned long rc; + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_init_svc(); +#endif + + ENTER(); + + vos_wake_lock_init(&wlan_wake_lock, "wlan"); + hdd_prevent_suspend(); + /* + * The Krait is going to Idle/Stand Alone Power Save + * more aggressively which is resulting in the longer driver load time. + * The Fix is to not allow Krait to enter Idle Power Save during driver load. + */ + + hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL); + + vos_ssr_protect_init(); + + pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME, + QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR); + + do { + +#ifndef MODULE + if (WLAN_IS_EPPING_ENABLED(con_mode)) { + ret_status = epping_driver_init(con_mode, &wlan_wake_lock, + WLAN_MODULE_NAME); + if (ret_status < 0) { + hdd_remove_pm_qos(); + hdd_allow_suspend(); + vos_wake_lock_destroy(&wlan_wake_lock); + } + return ret_status; + } +#else + if (WLAN_IS_EPPING_ENABLED(hdd_get_conparam())) { + ret_status = epping_driver_init(hdd_get_conparam(), + &wlan_wake_lock, WLAN_MODULE_NAME); + if (ret_status < 0) { + hdd_remove_pm_qos(); + hdd_allow_suspend(); + vos_wake_lock_destroy(&wlan_wake_lock); + } + return ret_status; + } +#endif + +#ifdef TIMER_MANAGER + vos_timer_manager_init(); +#endif + +#ifdef MEMORY_DEBUG + vos_mem_init(); +#endif + + /* Preopen VOSS so that it is ready to start at least SAL */ + status = vos_preOpen(&pVosContext); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__); + ret_status = -1; + break; + } + +#ifdef HDD_TRACE_RECORD + MTRACE(hddTraceInit()); +#endif + +#ifndef MODULE + /* For statically linked driver, call hdd_set_conparam to update curr_con_mode + */ + hdd_set_conparam((v_UINT_t)con_mode); +#endif + +#define HDD_WLAN_START_WAIT_TIME VOS_WDA_TIMEOUT + 5000 + + init_completion(&wlan_start_comp); + + ret_status = hif_register_driver(); + if (!ret_status) { + rc = wait_for_completion_timeout( + &wlan_start_comp, + msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: timed-out waiting for hif_register_driver", __func__); + ret_status = -1; + } else + ret_status = 0; + } + + hdd_remove_pm_qos(); + hdd_allow_suspend(); + + if (ret_status) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN Driver Initialization failed", + __func__); + hif_unregister_driver(); + vos_preClose( &pVosContext ); + ret_status = -ENODEV; + break; + } else { + pr_info("%s: driver loaded\n", WLAN_MODULE_NAME); + return 0; + } + + + } while (0); + + if (0 != ret_status) + { +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + + vos_wake_lock_destroy(&wlan_wake_lock); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_deinit_svc(); +#endif + + pr_err("%s: driver load failure\n", WLAN_MODULE_NAME); + } + else + { + //Send WLAN UP indication to Nlink Service + send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0); + + pr_info("%s: driver loaded\n", WLAN_MODULE_NAME); + } + + EXIT(); + + return ret_status; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_module_init() - Init Function + + This is the driver entry point (invoked when module is loaded using insmod) + + \param - None + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +#ifdef MODULE +static int __init hdd_module_init ( void) +{ + return hdd_driver_init(); +} +#else /* #ifdef MODULE */ +static int __init hdd_module_init ( void) +{ + /* Driver initialization is delayed to fwpath_changed_handler */ + return 0; +} +#endif /* #ifdef MODULE */ + +/**--------------------------------------------------------------------------- + + \brief hdd_driver_exit() - Exit function + + This is the driver exit point (invoked when module is unloaded using rmmod + or con_mode was changed by user space) + + \param - None + + \return - None + + --------------------------------------------------------------------------*/ +static void hdd_driver_exit(void) +{ + hdd_context_t *pHddCtx = NULL; + int retry = 0; + v_CONTEXT_t pVosContext = NULL; + + pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR); + + //Get the global vos context + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + goto done; + } + + if (WLAN_IS_EPPING_ENABLED(con_mode)) { + epping_driver_exit(pVosContext); + goto done; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__); + } + else + { +#ifdef QCA_PKT_PROTO_TRACE + vos_pkt_proto_trace_close(); +#endif /* QCA_PKT_PROTO_TRACE */ + while(pHddCtx->isLogpInProgress || + vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:SSR in Progress; block rmmod for 1 second!!!", __func__); + msleep(1000); + + if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:SSR never completed, fatal error", __func__); + VOS_BUG(0); + } + } + + pHddCtx->isUnloadInProgress = TRUE; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + } + + vos_wait_for_work_thread_completion(__func__); + + hif_unregister_driver(); + + vos_preClose( &pVosContext ); + +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_deinit_svc(); +#endif + +done: + vos_wake_lock_destroy(&wlan_wake_lock); + pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_module_exit() - Exit function + + This is the driver exit point (invoked when module is unloaded using rmmod) + + \param - None + + \return - None + + --------------------------------------------------------------------------*/ +static void __exit hdd_module_exit(void) +{ + hdd_driver_exit(); +} + +#ifdef MODULE +static int fwpath_changed_handler(const char *kmessage, + struct kernel_param *kp) +{ + return param_set_copystring(kmessage, kp); +} + +#if ! defined(QCA_WIFI_FTM) +static int con_mode_handler(const char *kmessage, + struct kernel_param *kp) +{ + return param_set_int(kmessage, kp); +} +#endif +#else /* #ifdef MODULE */ +/**--------------------------------------------------------------------------- + + \brief kickstart_driver + + This is the driver entry point + - delayed driver initialization when driver is statically linked + - invoked when module parameter fwpath is modified from user space to signal + initializing the WLAN driver or when con_mode is modified from user space + to signal a switch in operating mode + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int kickstart_driver(void) +{ + int ret_status; + + if (!wlan_hdd_inited) { + ret_status = hdd_driver_init(); + wlan_hdd_inited = ret_status ? 0 : 1; + return ret_status; + } + + hdd_driver_exit(); + + msleep(200); + + ret_status = hdd_driver_init(); + wlan_hdd_inited = ret_status ? 0 : 1; + return ret_status; +} + +/**--------------------------------------------------------------------------- + + \brief fwpath_changed_handler() - Handler Function + + Handle changes to the fwpath parameter + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int fwpath_changed_handler(const char *kmessage, + struct kernel_param *kp) +{ + int ret; + + ret = param_set_copystring(kmessage, kp); + if (0 == ret) + ret = kickstart_driver(); + return ret; +} + +#if ! defined(QCA_WIFI_FTM) +/**--------------------------------------------------------------------------- + + \brief con_mode_handler() - + + Handler function for module param con_mode when it is changed by user space + Dynamically linked - do nothing + Statically linked - exit and init driver, as in rmmod and insmod + + \param - + + \return - + + --------------------------------------------------------------------------*/ +static int con_mode_handler(const char *kmessage, struct kernel_param *kp) +{ + int ret; + + ret = param_set_int(kmessage, kp); + if (0 == ret) + ret = kickstart_driver(); + return ret; +} +#endif +#endif /* #ifdef MODULE */ + +/**--------------------------------------------------------------------------- + + \brief hdd_get_conparam() - + + This is the driver exit point (invoked when module is unloaded using rmmod) + + \param - None + + \return - tVOS_CON_MODE + + --------------------------------------------------------------------------*/ +tVOS_CON_MODE hdd_get_conparam ( void ) +{ +#ifdef MODULE + return (tVOS_CON_MODE)con_mode; +#else + return (tVOS_CON_MODE)curr_con_mode; +#endif +} +void hdd_set_conparam ( v_UINT_t newParam ) +{ + con_mode = newParam; +#ifndef MODULE + curr_con_mode = con_mode; +#endif +} +/**--------------------------------------------------------------------------- + + \brief hdd_softap_sta_deauth() - function + + This to take counter measure to handle deauth req from HDD + + \param - pAdapter - Pointer to the HDD + + \param - enable - boolean value + + \return - None + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress) +{ +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; +#endif + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + ENTER(); + + hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)", + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + + //Ignore request to deauth bcmc station + if( pDestMacAddress[0] & 0x1 ) + return vosStatus; + +#ifdef WLAN_FEATURE_MBSSID + vosStatus = WLANSAP_DeauthSta(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), pDestMacAddress); +#else + vosStatus = WLANSAP_DeauthSta(pVosContext, pDestMacAddress); +#endif + + EXIT(); + return vosStatus; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_softap_sta_disassoc() - function + + This to take counter measure to handle deauth req from HDD + + \param - pAdapter - Pointer to the HDD + + \param - enable - boolean value + + \return - None + + --------------------------------------------------------------------------*/ + +void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress) +{ +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; +#endif + + ENTER(); + + hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + + //Ignore request to disassoc bcmc station + if( pDestMacAddress[0] & 0x1 ) + return; + +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_DisassocSta(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), pDestMacAddress); +#else + WLANSAP_DisassocSta(pVosContext,pDestMacAddress); +#endif +} + +void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable) +{ +#ifndef WLAN_FEATURE_MBSSID + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; +#endif + + ENTER(); + + hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_SetCounterMeasure(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), (v_BOOL_t)enable); +#else + WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable); +#endif +} + +/**--------------------------------------------------------------------------- + * + * \brief hdd_get__concurrency_mode() - + * + * + * \param - None + * + * \return - CONCURRENCY MODE + * + * --------------------------------------------------------------------------*/ +tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ) +{ + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x", __func__, + pHddCtx->concurrency_mode); + return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode; + } + } + + /* we are in an invalid state :( */ + hddLog(LOGE, "%s: Invalid context", __func__); + return VOS_STA; +} + +/* Decide whether to allow/not the apps power collapse. + * Allow apps power collapse if we are in connected state. + * if not, allow only if we are in IMPS */ +v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx) +{ + tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal); + tANI_BOOLEAN scanRspPending; + tANI_BOOLEAN inMiddleOfRoaming; + hdd_config_t *pConfig = pHddCtx->cfg_ini; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status; + tVOS_CONCURRENCY_MODE concurrent_state = 0; + + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + return TRUE; + + concurrent_state = hdd_get_concurrency_mode(); + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) || + (concurrent_state == (VOS_STA | VOS_P2P_GO))) && + (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + return TRUE; +#endif + + /*loop through all adapters. TBD fix for Concurrency */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) + || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal, + pAdapter->sessionId); + inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal, + pAdapter->sessionId); + if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled) + && (pmcState != IMPS && pmcState != BMPS + && pmcState != STOPPED && pmcState != STANDBY)) || + (eANI_BOOLEAN_TRUE == scanRspPending) || + (eANI_BOOLEAN_TRUE == inMiddleOfRoaming)) + { + hddLog( LOGE, "%s: do not allow APPS power collapse-" + "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d", + __func__, pmcState, scanRspPending, inMiddleOfRoaming ); + return FALSE; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return TRUE; +} + +/* Decides whether to send suspend notification to Riva + * if any adapter is in BMPS; then it is required */ +v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx) +{ + tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal); + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + if (pConfig->fIsBmpsEnabled && (pmcState == BMPS)) + { + return TRUE; + } + return FALSE; +} + +void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->concurrency_mode |= (1 << mode); + pHddCtx->no_of_open_sessions[mode]++; + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x " + "Number of open sessions for mode %d = %d"), + pHddCtx->concurrency_mode, mode, + pHddCtx->no_of_open_sessions[mode]); +} + + +void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) + { + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->no_of_open_sessions[mode]--; + if (!(pHddCtx->no_of_open_sessions[mode])) + pHddCtx->concurrency_mode &= (~(1 << mode)); + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x " + "Number of open sessions for mode %d = %d"), + pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]); + } + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_incr_active_session() + * + * This function increments the number of active sessions + * maintained per device mode + * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented + * Incase of SAP/P2P GO upon bss start it is incremented + * + * \param pHddCtx - HDD Context + * \param mode - device mode + * + * \return - None + * + * --------------------------------------------------------------------------*/ +void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->no_of_active_sessions[mode]++; + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"), + mode, + pHddCtx->no_of_active_sessions[mode]); +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_decr_active_session() + * + * This function decrements the number of active sessions + * maintained per device mode + * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented + * Incase of SAP/P2P GO upon bss stop it is decremented + * + * \param pHddCtx - HDD Context + * \param mode - device mode + * + * \return - None + * + * --------------------------------------------------------------------------*/ +void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + if (pHddCtx->no_of_active_sessions[mode]) + pHddCtx->no_of_active_sessions[mode]--; + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"), + mode, + pHddCtx->no_of_active_sessions[mode]); +} + + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_init + * + * This function initializes restart timer/flag. An internal function. + * + * \param - pHddCtx + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +static void wlan_hdd_restart_init(hdd_context_t *pHddCtx) +{ + /* Initialize */ + pHddCtx->hdd_restart_retries = 0; + atomic_set(&pHddCtx->isRestartInProgress, 0); + vos_timer_init(&pHddCtx->hdd_restart_timer, + VOS_TIMER_TYPE_SW, + wlan_hdd_restart_timer_cb, + pHddCtx); +} +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_deinit + * + * This function cleans up the resources used. An internal function. + * + * \param - pHddCtx + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx) +{ + + VOS_STATUS vos_status; + /* Block any further calls */ + atomic_set(&pHddCtx->isRestartInProgress, 1); + /* Cleanup */ + vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer ); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to stop HDD restart timer")); + vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to destroy HDD restart timer")); + +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_framework_restart + * + * This function uses a cfg80211 API to start a framework initiated WLAN + * driver module unload/load. + * + * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT). + * + * + * \param - pHddCtx + * + * \return - VOS_STATUS_SUCCESS: Success + * VOS_STATUS_E_EMPTY: Adapter is Empty + * VOS_STATUS_E_NOMEM: No memory + + * --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + int len = (sizeof (struct ieee80211_mgmt)); + struct ieee80211_mgmt *mgmt = NULL; + + /* Prepare the DEAUTH management frame with reason code */ + mgmt = kzalloc(len, GFP_KERNEL); + if(mgmt == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: memory allocation failed (%d bytes)", __func__, len); + return VOS_STATUS_E_NOMEM; + } + mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK; + + /* Iterate over all adapters/devices */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + do + { + if( (status == VOS_STATUS_SUCCESS) && + pAdapterNode && + pAdapterNode->pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "restarting the driver(intf:\'%s\' mode:%d :try %d)", + pAdapterNode->pAdapter->dev->name, + pAdapterNode->pAdapter->device_mode, + pHddCtx->hdd_restart_retries + 1); + /* + * CFG80211 event to restart the driver + * + * 'cfg80211_send_unprot_deauth' sends a + * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state + * of SME(Linux Kernel) state machine. + * + * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart + * the driver. + * + */ + + cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len ); + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status)); + + + /* Free the allocated management frame */ + kfree(mgmt); + + /* Retry until we unload or reach max count */ + if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT) + vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS); + + return status; + +} +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_timer_cb + * + * Restart timer callback. An internal function. + * + * \param - User data: + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback) +{ + hdd_context_t *pHddCtx = usrDataForCallback; + wlan_hdd_framework_restart(pHddCtx); + return; + +} + + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_driver + * + * This function sends an event to supplicant to restart the WLAN driver. + * + * This function is called from vos_wlanRestart. + * + * \param - pHddCtx + * + * \return - VOS_STATUS_SUCCESS: Success + * VOS_STATUS_E_EMPTY: Adapter is Empty + * VOS_STATUS_E_ALREADY: Request already in progress + + * --------------------------------------------------------------------------*/ +VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + /* A tight check to make sure reentrancy */ + if(atomic_xchg(&pHddCtx->isRestartInProgress, 1)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: WLAN restart is already in progress", __func__); + + return VOS_STATUS_E_ALREADY; + } + /* Send reset FIQ to WCNSS to invoke SSR. */ +#ifdef HAVE_WCNSS_RESET_INTR + wcnss_reset_intr(); +#endif + + return status; +} + +/* + * API to find if there is any STA or P2P-Client is connected + */ +VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx) +{ + return sme_isSta_p2p_clientConnected(pHddCtx->hHal); +} + +#ifdef FEATURE_WLAN_CH_AVOID +/**--------------------------------------------------------------------------- + + \brief hdd_freq_to_chn() - + + Input frequency translated into channel number + + \param - freq input frequency with order of MHz + + \return - corresponding channel number. + if cannot find correct channel number, return 0 + + --------------------------------------------------------------------------*/ +v_U16_t hdd_freq_to_chn +( + v_U16_t freq +) +{ + int loop; + + for (loop = 0; loop < NUM_20MHZ_RF_CHANNELS; loop++) + { + if (rfChannels[loop].targetFreq == freq) + { + return rfChannels[loop].channelNum; + } + } + + return (0); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_find_prefd_safe_chnl() - + + Try to find safe channel within preferred channel + In case auto channel selection enabled + - Preferred and safe channel should be used + - If no overlapping, preferred channel should be used + + \param - hdd_ctxt hdd context pointer + + \return - 1: found preferred safe channel + 0: could not found preferred safe channel + + --------------------------------------------------------------------------*/ +static v_U8_t hdd_find_prefd_safe_chnl(hdd_context_t *hdd_ctxt) +{ + v_U16_t safe_channels[NUM_20MHZ_RF_CHANNELS]; + v_U16_t safe_channel_count; + v_U8_t is_unsafe = 1; + v_U16_t i; + v_U16_t channel_loop; + + safe_channel_count = 0; + for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) { + is_unsafe = 0; + for (channel_loop = 0; + channel_loop < hdd_ctxt->unsafe_channel_count; + channel_loop++) { + if (rfChannels[i].channelNum == + hdd_ctxt->unsafe_channel_list[channel_loop]) { + is_unsafe = 1; + break; + } + } + if (!is_unsafe) { + safe_channels[safe_channel_count] = rfChannels[i].channelNum; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "safe channel %d", safe_channels[safe_channel_count]); + safe_channel_count++; + } + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "perferred range %d - %d", + hdd_ctxt->cfg_ini->apStartChannelNum, + hdd_ctxt->cfg_ini->apEndChannelNum); + for (i = 0; i < safe_channel_count; i++) { + if ((safe_channels[i] >= hdd_ctxt->cfg_ini->apStartChannelNum) && + (safe_channels[i] <= hdd_ctxt->cfg_ini->apEndChannelNum)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "safe channel %d is in perferred range", safe_channels[i]); + return 1; + } + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_ch_avoid_cb() - + + Avoid channel notification from FW handler. + FW will send un-safe channel list to avoid over wrapping. + hostapd should not use notified channel + + \param - pAdapter HDD adapter pointer + indParam channel avoid notification parameter + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_ch_avoid_cb +( + void *hdd_context, + void *indi_param +) +{ + hdd_adapter_t *hostapd_adapter = NULL; + hdd_context_t *hdd_ctxt; + tSirChAvoidIndType *ch_avoid_indi; + v_U8_t range_loop; + v_U16_t channel_loop; + v_U16_t dup_check; + v_U16_t start_channel; + v_U16_t end_channel; + v_CONTEXT_t vos_context; + static int restart_sap_in_progress = 0; + tHddAvoidFreqList hdd_avoid_freq_list; + tANI_U32 i; + + /* Basic sanity */ + if (!hdd_context || !indi_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : Invalid arguments", __func__); + return; + } + + hdd_ctxt = (hdd_context_t *)hdd_context; + ch_avoid_indi = (tSirChAvoidIndType *)indi_param; + vos_context = hdd_ctxt->pvosContext; + + /* Make unsafe channel list */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : band count %d", + __func__, ch_avoid_indi->avoid_range_count); + + /* generate vendor specific event */ + vos_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList)); + for (i = 0; i < ch_avoid_indi->avoid_range_count; i++) + { + hdd_avoid_freq_list.avoidFreqRange[i].startFreq = + ch_avoid_indi->avoid_freq_range[i].start_freq; + hdd_avoid_freq_list.avoidFreqRange[i].endFreq = + ch_avoid_indi->avoid_freq_range[i].end_freq; + } + hdd_avoid_freq_list.avoidFreqRangeCount = ch_avoid_indi->avoid_range_count; + + wlan_hdd_send_avoid_freq_event(hdd_ctxt, &hdd_avoid_freq_list); + + /* clear existing unsafe channel cache */ + hdd_ctxt->unsafe_channel_count = 0; + vos_mem_zero(hdd_ctxt->unsafe_channel_list, sizeof(v_U16_t) * NUM_20MHZ_RF_CHANNELS); + + if (0 == ch_avoid_indi->avoid_range_count) { + hdd_ctxt->unsafe_channel_count = 0; + } else { + for (range_loop = 0; range_loop < ch_avoid_indi->avoid_range_count; range_loop++) + { + if (hdd_ctxt->unsafe_channel_count >= NUM_20MHZ_RF_CHANNELS) + break; + + start_channel = hdd_freq_to_chn( + ch_avoid_indi->avoid_freq_range[range_loop].start_freq); + end_channel = hdd_freq_to_chn( + ch_avoid_indi->avoid_freq_range[range_loop].end_freq); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : start %d : %d, end %d : %d", + __func__, + ch_avoid_indi->avoid_freq_range[range_loop].start_freq, + start_channel, + ch_avoid_indi->avoid_freq_range[range_loop].end_freq, + end_channel); + + /* do not process frequency bands that are not mapped to predefined channels */ + if (start_channel == 0 || end_channel == 0) + continue; + + for (channel_loop = start_channel; + channel_loop < (end_channel + 1); + channel_loop++) + { + /* Channel duplicate check routine */ + for (dup_check = 0; dup_check < hdd_ctxt->unsafe_channel_count; dup_check++) + { + if (hdd_ctxt->unsafe_channel_list[dup_check] == channel_loop) + { + /* This channel is duplicated */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : found duplicated channel %d", + __func__, channel_loop); + break; + } + } + if (dup_check == hdd_ctxt->unsafe_channel_count) + { + hdd_ctxt->unsafe_channel_list[hdd_ctxt->unsafe_channel_count++] = channel_loop; + } + else + { + /* DUP, do nothing */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : duplicated channel %d", + __func__, channel_loop); + } + } + } + } + +#ifdef CONFIG_CNSS + cnss_set_wlan_unsafe_channel(hdd_ctxt->unsafe_channel_list, + hdd_ctxt->unsafe_channel_count); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : number of unsafe channels is %d ", + __func__, hdd_ctxt->unsafe_channel_count); + for (channel_loop = 0; + channel_loop < hdd_ctxt->unsafe_channel_count; + channel_loop++) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: channel %d is not safe ", __func__, + hdd_ctxt->unsafe_channel_list[channel_loop]); + } +#endif + + /* If auto channel select is enabled + * preferred channel is in safe channel, + * re-start softap interface with safe channel. + * no overlap with preferred channel and safe channel + * do not re-start softap interface + * stay current operating channel. */ + if ((hdd_ctxt->cfg_ini->apAutoChannelSelection) && + (!hdd_find_prefd_safe_chnl(hdd_ctxt))) { + return; + } + + if (hdd_ctxt->unsafe_channel_count) { + hostapd_adapter = hdd_get_adapter(hdd_ctxt, WLAN_HDD_SOFTAP); + if (hostapd_adapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : Current operation channel %d, sessionCtx.ap.sapConfig.channel %d", + __func__, + hostapd_adapter->sessionCtx.ap.operatingChannel, + hostapd_adapter->sessionCtx.ap.sapConfig.channel); + for (channel_loop = 0; channel_loop < hdd_ctxt->unsafe_channel_count; channel_loop++) + { + if (((hdd_ctxt->unsafe_channel_list[channel_loop] == + hostapd_adapter->sessionCtx.ap.operatingChannel)) && + (AUTO_CHANNEL_SELECT == hostapd_adapter->sessionCtx.ap.sapConfig.channel) && + !restart_sap_in_progress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Restarting SAP", __func__); + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_LTE_COEX_IND, NULL, 0); + restart_sap_in_progress = 1; + /* current operating channel is un-safe channel, restart driver */ + hdd_hostapd_stop(hostapd_adapter->dev); + break; + } + } + } + } + return; +} +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_LPSS +int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data, + hdd_adapter_t *pAdapter, + hdd_station_ctx_t *pHddStaCtx, + v_U8_t is_on, + v_U8_t is_connected) +{ + hdd_context_t *pHddCtx = NULL; + tANI_U8 buflen = WLAN_SVC_COUNTRY_CODE_LEN; + + if (!data) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid data pointer", __func__); + return (-1); + } + if (!pAdapter) { + if (is_on) { + /* no active interface */ + data->lpss_support = 0; + data->is_on = is_on; + return 0; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid adapter pointer", __func__); + return (-1); + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->lpss_support && pHddCtx->cfg_ini->enablelpasssupport) + data->lpss_support = 1; + else + data->lpss_support = 0; + data->numChannels = WLAN_SVC_MAX_NUM_CHAN; + sme_GetCfgValidChannels(pHddCtx->hHal, data->channel_list, + &data->numChannels); + sme_GetCountryCode(pHddCtx->hHal, data->country_code, &buflen); + data->is_on = is_on; + data->vdev_id = pAdapter->sessionId; + data->vdev_mode = pAdapter->device_mode; + if (pHddStaCtx) { + data->is_connected = is_connected; + data->rssi = pAdapter->rssi; + data->freq = vos_chan_to_freq(pHddStaCtx->conn_info.operationChannel); + if (WLAN_SVC_MAX_SSID_LEN >= pHddStaCtx->conn_info.SSID.SSID.length) { + data->ssid_len = pHddStaCtx->conn_info.SSID.SSID.length; + memcpy(data->ssid, + pHddStaCtx->conn_info.SSID.SSID.ssId, + pHddStaCtx->conn_info.SSID.SSID.length); + } + if (WLAN_SVC_MAX_BSSID_LEN >= sizeof(pHddStaCtx->conn_info.bssId)) + memcpy(data->bssid, + pHddStaCtx->conn_info.bssId, + sizeof(pHddStaCtx->conn_info.bssId)); + } + return 0; +} + +int wlan_hdd_gen_wlan_version_pack(struct wlan_version_data *data, + v_U32_t fw_version, + v_U32_t chip_id, + const char *chip_name) +{ + if (!data) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid data pointer", __func__); + return (-1); + } + + data->chip_id = chip_id; + strlcpy(data->chip_name, chip_name, WLAN_SVC_MAX_STR_LEN); + if (strncmp(chip_name, "Unknown", 7)) + strlcpy(data->chip_from, "Qualcomm", WLAN_SVC_MAX_STR_LEN); + else + strlcpy(data->chip_from, "Unknown", WLAN_SVC_MAX_STR_LEN); + strlcpy(data->host_version, QWLAN_VERSIONSTR, WLAN_SVC_MAX_STR_LEN); + scnprintf(data->fw_version, WLAN_SVC_MAX_STR_LEN, "%d.%d.%d.%d", + (fw_version & 0xf0000000) >> 28, + (fw_version & 0xf000000) >> 24, + (fw_version & 0xf00000) >> 20, + (fw_version & 0x7fff)); + return 0; +} +#endif + +#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_disable_roaming() + + This function loop through each adapter and disable roaming on each STA + device mode except the input adapter. + Note: On the input adapter roaming is not enabled yet hence no need to + disable. + + \param - pAdapter HDD adapter pointer + + \return - None + + --------------------------------------------------------------------------*/ +void wlan_hdd_disable_roaming(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_adapter_t *pAdapterIdx = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL; + hdd_adapter_list_node_t *pNext = NULL; + VOS_STATUS status; + + if (pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled && + pHddCtx->cfg_ini->isRoamOffloadScanEnabled && + WLAN_HDD_INFRA_STATION == pAdapter->device_mode && + vos_is_sta_active_connection_exists()) { + hddLog(LOG1, FL("Connect received on STA sessionId(%d)"), + pAdapter->sessionId); + /* Loop through adapter and disable roaming for each STA device mode + except the input adapter. */ + + status = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapterIdx = pAdapterNode->pAdapter; + + if (WLAN_HDD_INFRA_STATION == pAdapterIdx->device_mode && + pAdapter->sessionId != pAdapterIdx->sessionId) { + hddLog(LOG1, FL("Disable Roaming on sessionId(%d)"), + pAdapterIdx->sessionId); + sme_stopRoaming(WLAN_HDD_GET_HAL_CTX(pAdapterIdx), + pAdapterIdx->sessionId, 0); + } + + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + } +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_enable_roaming() + + This function loop through each adapter and enable roaming on each STA + device mode except the input adapter. + Note: On the input adapter no need to enable roaming because link got + disconnected on this. + + \param - pAdapter HDD adapter pointer + + \return - None + + --------------------------------------------------------------------------*/ +void wlan_hdd_enable_roaming(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_adapter_t *pAdapterIdx = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL; + hdd_adapter_list_node_t *pNext = NULL; + VOS_STATUS status; + + if (pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled && + pHddCtx->cfg_ini->isRoamOffloadScanEnabled && + WLAN_HDD_INFRA_STATION == pAdapter->device_mode && + vos_is_sta_active_connection_exists()) { + hddLog(LOG1, FL("Disconnect received on STA sessionId(%d)"), + pAdapter->sessionId); + /* Loop through adapter and enable roaming for each STA device mode + except the input adapter. */ + + status = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapterIdx = pAdapterNode->pAdapter; + + if (WLAN_HDD_INFRA_STATION == pAdapterIdx->device_mode && + pAdapter->sessionId != pAdapterIdx->sessionId) { + hddLog(LOG1, FL("Enabling Roaming on sessionId(%d)"), + pAdapterIdx->sessionId); + sme_startRoaming(WLAN_HDD_GET_HAL_CTX(pAdapterIdx), + pAdapterIdx->sessionId, + REASON_CONNECT); + } + + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + } +} +#endif + + +void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *ani_hdr; + void *nl_data = NULL; + int flags = GFP_KERNEL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); + + if(skb == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_SVC; + + ani_hdr = NLMSG_DATA(nlh); + ani_hdr->type = type; + + switch(type) { + case WLAN_SVC_FW_CRASHED_IND: + case WLAN_SVC_LTE_COEX_IND: +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND: +#endif + ani_hdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + break; + case WLAN_SVC_WLAN_STATUS_IND: + case WLAN_SVC_WLAN_VERSION_IND: + case WLAN_SVC_DFS_CAC_START_IND: + case WLAN_SVC_DFS_CAC_END_IND: + case WLAN_SVC_DFS_RADAR_DETECT_IND: + case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: + case WLAN_SVC_WLAN_TP_IND: + ani_hdr->length = len; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); + nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); + memcpy(nl_data, data, len); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len)); + break; + + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN SVC: Attempt to send unknown nlink message %d", type); + kfree_skb(skb); + return; + } + + nl_srv_bcast(skb); + + return; +} + +#ifdef WLAN_FEATURE_LPSS +void wlan_hdd_send_status_pkg(hdd_adapter_t *pAdapter, + hdd_station_ctx_t *pHddStaCtx, + v_U8_t is_on, + v_U8_t is_connected) +{ + int ret = 0; + struct wlan_status_data data; +#ifdef CONFIG_CNSS + struct cnss_platform_cap cap; + + ret = cnss_get_platform_cap(&cap); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: platform capability info from CNSS not available", + __func__); + return; + } + + if (!(cap.cap_flag & CNSS_HAS_UART_ACCESS)) + return; +#endif + + if (VOS_FTM_MODE == hdd_get_conparam()) + return; + + memset(&data, 0, sizeof(struct wlan_status_data)); + if (is_on) + ret = wlan_hdd_gen_wlan_status_pack(&data, pAdapter, pHddStaCtx, + is_on, is_connected); + if (!ret) + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_STATUS_IND, + &data, sizeof(struct wlan_status_data)); +} + +void wlan_hdd_send_version_pkg(v_U32_t fw_version, + v_U32_t chip_id, + const char *chip_name) +{ + int ret = 0; + struct wlan_version_data data; +#ifdef CONFIG_CNSS + struct cnss_platform_cap cap; + + ret = cnss_get_platform_cap(&cap); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: platform capability info from CNSS not available", + __func__); + return; + } + + if (!(cap.cap_flag & CNSS_HAS_UART_ACCESS)) + return; +#endif + + if (VOS_FTM_MODE == hdd_get_conparam()) + return; + + memset(&data, 0, sizeof(struct wlan_version_data)); + ret = wlan_hdd_gen_wlan_version_pack(&data, fw_version, chip_id, chip_name); + if (!ret) + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_VERSION_IND, + &data, sizeof(struct wlan_version_data)); +} + +void wlan_hdd_send_all_scan_intf_info(hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pDataAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + v_BOOL_t scan_intf_found = VOS_FALSE; + VOS_STATUS status; + + if (!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer for pHddCtx", + __func__); + return; + } + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pDataAdapter = pAdapterNode->pAdapter; + if (pDataAdapter) { + if (pDataAdapter->device_mode == WLAN_HDD_INFRA_STATION || + pDataAdapter->device_mode == WLAN_HDD_P2P_CLIENT || + pDataAdapter->device_mode == WLAN_HDD_P2P_DEVICE) { + scan_intf_found = VOS_TRUE; + wlan_hdd_send_status_pkg(pDataAdapter, NULL, 1, 0); + } + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + if (!scan_intf_found) + wlan_hdd_send_status_pkg(pDataAdapter, NULL, 1, 0); +} +#endif + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +v_VOID_t wlan_hdd_auto_shutdown_cb(v_VOID_t) +{ + hddLog(LOGE, FL("%s: Wlan Idle. Sending Shutdown event.."),__func__); + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0); +} + +void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, v_BOOL_t enable) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + v_BOOL_t ap_connected = VOS_FALSE, sta_connected = VOS_FALSE; + tHalHandle hHal; + + hHal = hdd_ctx->hHal; + if (hHal == NULL) + return; + + if (hdd_ctx->cfg_ini->WlanAutoShutdown == 0) + return; + + if (enable == VOS_FALSE) { + if (sme_set_auto_shutdown_timer(hHal, 0) != eHAL_STATUS_SUCCESS) { + hddLog(LOGE, FL("Failed to stop wlan auto shutdown timer")); + } + return; + } + + /* To enable shutdown timer check concurrency */ + if (vos_concurrent_open_sessions_running()) { + status = hdd_get_front_adapter ( hdd_ctx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter && pAdapter->device_mode == WLAN_HDD_INFRA_STATION) { + if (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)->conn_info.connState + == eConnectionState_Associated) { + sta_connected = VOS_TRUE; + break; + } + } + if (pAdapter && pAdapter->device_mode == WLAN_HDD_SOFTAP) { + if(WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->bApActive == VOS_TRUE) { + ap_connected = VOS_TRUE; + break; + } + } + status = hdd_get_next_adapter ( hdd_ctx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if (ap_connected == VOS_TRUE || sta_connected == VOS_TRUE) { + hddLog(LOG1, FL("CC Session active. Shutdown timer not enabled")); + return; + } else { + if (sme_set_auto_shutdown_timer(hHal, + hdd_ctx->cfg_ini->WlanAutoShutdown) + != eHAL_STATUS_SUCCESS) + hddLog(LOGE, FL("Failed to start wlan auto shutdown timer")); + else + hddLog(LOG1, FL("Auto Shutdown timer for %d seconds enabled"), + hdd_ctx->cfg_ini->WlanAutoShutdown); + + } +} +#endif + +hdd_adapter_t * hdd_get_con_sap_adapter(hdd_adapter_t *this_sap_adapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(this_sap_adapter); + hdd_adapter_t *pAdapter, *con_sap_adapter; + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + con_sap_adapter = NULL; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter && pAdapter->device_mode == WLAN_HDD_SOFTAP) { + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) { + if (pAdapter != this_sap_adapter) { + con_sap_adapter = pAdapter; + break; + } + } + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return con_sap_adapter; +} + +#ifdef MSM_PLATFORM +void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) + return; + + vos_timer_start(&pHddCtx->bus_bw_timer, + pHddCtx->cfg_ini->busBandwidthComputeInterval); +} + +void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_BOOL_t can_stop = VOS_TRUE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) { + /* trying to stop timer, when not running is not good */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "bus band width compute timer is not running"); + return; + } + + if (vos_concurrent_open_sessions_running()) { + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter && (pAdapter->device_mode == WLAN_HDD_INFRA_STATION || + pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) && + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)->conn_info.connState + == eConnectionState_Associated) { + can_stop = VOS_FALSE; + break; + } + if (pAdapter && (pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO) && + WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->bApActive == VOS_TRUE) { + can_stop = VOS_FALSE; + break; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if(can_stop == VOS_TRUE) + vos_timer_stop(&pHddCtx->bus_bw_timer); +} +#endif + + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void wlan_hdd_check_sta_ap_concurrent_ch_intf(void *data) +{ + hdd_adapter_t *ap_adapter = NULL, *sta_adapter = (hdd_adapter_t *)data; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(sta_adapter); + tHalHandle hHal; + hdd_ap_ctx_t *pHddApCtx; + v_U16_t intf_ch = 0; + + if ((pHddCtx->cfg_ini->WlanMccToSccSwitchMode == VOS_MCC_TO_SCC_SWITCH_DISABLE) + || !(vos_concurrent_open_sessions_running() + || !(vos_get_concurrency_mode() == VOS_STA_SAP))) + return; + + ap_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (ap_adapter == NULL) + return; + + if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) + return; + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + hHal = WLAN_HDD_GET_HAL_CTX(ap_adapter); + + if (hHal == NULL) + return; + +#ifdef WLAN_FEATURE_MBSSID + intf_ch = WLANSAP_CheckCCIntf(pHddApCtx->sapContext); +#else + intf_ch = WLANSAP_CheckCCIntf(pHddCtx->pvosContext); +#endif + if (intf_ch == 0) + return; + + pHddApCtx->sapConfig.channel = intf_ch; + sme_SelectCBMode(hHal, + sapConvertSapPhyModeToCsrPhyMode(pHddApCtx->sapConfig.SapHw_mode), + pHddApCtx->sapConfig.channel); + wlan_hdd_restart_sap(ap_adapter); +} + +#endif + + + +//Register the module init/exit functions +module_init(hdd_module_init); +module_exit(hdd_module_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Qualcomm Atheros, Inc."); +MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); + +#if defined(QCA_WIFI_FTM) +module_param(con_mode, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +#else +module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +#endif + +module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +module_param(enable_dfs_chan_scan, int, + S_IRUSR | S_IRGRP | S_IROTH); + +module_param(enable_11d, int, + S_IRUSR | S_IRGRP | S_IROTH); + +module_param(country_code, charp, + S_IRUSR | S_IRGRP | S_IROTH); diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_mib.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_mib.c new file mode 100644 index 0000000000000..9a2ccc4df01ae --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_mib.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "wlan_hdd_includes.h" + + +static inline v_VOID_t mibGetDot11DesiredBssType( hdd_adapter_t *pAdapter, eMib_dot11DesiredBssType *pDot11DesiredBssType ) +{ + *pDot11DesiredBssType = pAdapter->hdd_mib.mibDot11DesiredBssType; + return; +} + +static inline VOS_STATUS mibSetDot11DesiredBssType( hdd_adapter_t *pAdapter, eMib_dot11DesiredBssType mibDot11DesiredBssType ) +{ + pAdapter->hdd_mib.mibDot11DesiredBssType = mibDot11DesiredBssType; + return( VOS_STATUS_SUCCESS ); +} + +v_BOOL_t mibIsDot11DesiredBssTypeInfrastructure( hdd_adapter_t *pAdapter ) +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + mibGetDot11DesiredBssType( pAdapter, &mibDot11DesiredBssType ); + + return( eMib_dot11DesiredBssType_infrastructure == mibDot11DesiredBssType ); +} + + +static inline v_BOOL_t mibIsDot11DesiredBssTypeIndependent( hdd_adapter_t *pAdapter ) +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + mibGetDot11DesiredBssType( pAdapter, &mibDot11DesiredBssType ); + + return( eMib_dot11DesiredBssType_independent == mibDot11DesiredBssType ); +} + +static inline v_VOID_t mibGetDot11IbssJoinOnly( hdd_adapter_t *pAdapter, v_BOOL_t *pdot11IbssJoinOnly ) +{ + *pdot11IbssJoinOnly = pAdapter->hdd_mib.dot11IbssJoinOnly; + return; +} + +static inline VOS_STATUS mibSetDot11IbssJoinOnly( hdd_adapter_t *pAdapter, v_BOOL_t dot11IbssJoinOnly ) +{ + pAdapter->hdd_mib.dot11IbssJoinOnly = dot11IbssJoinOnly; + return( VOS_STATUS_SUCCESS ); +} + +static inline VOS_STATUS mibSetDot11NICPowerState( hdd_adapter_t *pAdapter, eMib_dot11NICPowerState *pMibDot11NICPowerState ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11NICPowerState = *pMibDot11NICPowerState; + + return( status ); +} + +static inline VOS_STATUS mibSetDot11NICPowerStateOff( hdd_adapter_t *pAdapter ) +{ + eMib_dot11NICPowerState dot11NICPowerState = eMib_dot11NICPowerState_OFF; + return( mibSetDot11NICPowerState( pAdapter, &dot11NICPowerState ) ); +} + +static inline void mibGetDot11NICPowerState( hdd_adapter_t *pAdapter, eMib_dot11NICPowerState *pMibDot11NICPowerState ) +{ + *pMibDot11NICPowerState = pAdapter->hdd_mib.mibDot11NICPowerState; + + return; +} + +static inline v_BOOL_t mibIsDot11NICPowerStateOn( hdd_adapter_t *pAdapter ) +{ + eMib_dot11NICPowerState dot11NICPowerState; + + mibGetDot11NICPowerState( pAdapter, &dot11NICPowerState ); + + return( eMib_dot11NICPowerState_ON == dot11NICPowerState ); +} + +static inline v_BOOL_t mibIsDot11NICPowerStateOff( hdd_adapter_t *pAdapter ) +{ + return( !mibIsDot11NICPowerStateOn( pAdapter ) ); +} + +static inline VOS_STATUS mibSetDot11DesiredSsidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredSsidList *pDot11DesiredSsidList ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if ( pDot11DesiredSsidList->cEntries > MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ) + + pAdapter->hdd_mib.mibDot11DesiredSsidList = *pDot11DesiredSsidList ; + + return( status ); +} + +static inline VOS_STATUS mibSetDot11DesiredBssidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredBssidList *pDot11DesiredBssidList ) +{ + pAdapter->hdd_mib.mibDot11DesiredBssidList = *pDot11DesiredBssidList; + + return( VOS_STATUS_SUCCESS ); +} + + +static inline v_VOID_t mibGetDot11DesiredBssidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredBssidList *pMibDot11DesiredBssidList ) +{ + *pMibDot11DesiredBssidList = pAdapter->hdd_mib.mibDot11DesiredBssidList; + + return; +} + + +static inline v_VOID_t mibGetDot11DesiredSsidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredSsidList *pMibDot11DesiredSsidList ) +{ + *pMibDot11DesiredSsidList = pAdapter->hdd_mib.mibDot11DesiredSsidList; + + return; +} + + +static inline VOS_STATUS mibSetDot11AutoConfigEnabled( hdd_adapter_t *pAdapter, eMib_dot11AutoConfigEnabled *pMibDot11AutoConfigEnabled ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11AutoConfigEnabled = *pMibDot11AutoConfigEnabled; + + return( status ); +} + + +static inline v_VOID_t mibGetDot11AutoConfigEnabled( hdd_adapter_t *pAdapter, eMib_dot11AutoConfigEnabled *pMibDot11AutoConfigEnabled ) +{ + *pMibDot11AutoConfigEnabled = pAdapter->hdd_mib.mibDot11AutoConfigEnabled; + + return; +} + +static inline VOS_STATUS mibSetDot11MacExcludeList( hdd_adapter_t *pAdapter, sMib_dot11MacExcludeList *pDot11MacExcludeList ) +{ + pAdapter->hdd_mib.mibDot11MacExcludeList = *pDot11MacExcludeList; + + return( VOS_STATUS_SUCCESS ); +} + +static inline VOS_STATUS mibGetDot11MacExcludeList( hdd_adapter_t *pAdapter, sMib_dot11MacExcludeList *pDot11MacExcludeList ) +{ + *pDot11MacExcludeList = pAdapter->hdd_mib.mibDot11MacExcludeList; + + return( VOS_STATUS_SUCCESS ); +} + +static inline void mibSetDefaultDot11MacExcludeList( hdd_adapter_t *pAdapter ) +{ + pAdapter->hdd_mib.mibDot11MacExcludeList.cEntries = 0; +} + +static inline VOS_STATUS mibSetDot11HardwarePHYState( hdd_adapter_t *pAdapter, eMib_dot11HardwarePHYState *pMibDot11HardwarePHYState ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11HardwarePHYState = *pMibDot11HardwarePHYState; + + return( status ); +} + + +static inline void mibGetDot11HardwarePHYState( hdd_adapter_t *pAdapter, eMib_dot11HardwarePHYState *pMibDot11HardwarePHYState ) +{ + *pMibDot11HardwarePHYState = pAdapter->hdd_mib.mibDot11HardwarePHYState; + + return; +} + +static inline void mibSetDefaultDot11PrivacyExemptionList( hdd_adapter_t *pAdapter ) +{ + pAdapter->hdd_mib.mibDot11PrivacyExemptionList.cEntries = 0; +} + + +static inline void mibGetDot11PowerSavingLevel( hdd_adapter_t *pAdapter, eMib_dot11PowerSavingLevel *pMibDot11PowerSavingLevel ) +{ + *pMibDot11PowerSavingLevel = pAdapter->hdd_mib.mibDot11PowerSavingLevel; + + return; +} + + +static inline void mibGetDevicePowerState( hdd_adapter_t *pAdapter, eMib_DevicePowerState *pMibDevicePowerState ) +{ + *pMibDevicePowerState = pAdapter->hdd_mib.mibDevicePowerState; + + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c new file mode 100644 index 0000000000000..dfa256cce08e0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c @@ -0,0 +1,1051 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/*================================================================================ + \file wlan_hdd_oemdata.c + + \brief Linux Wireless Extensions for oem data req/rsp + + $Id: wlan_hdd_oemdata.c,v 1.34 2010/04/15 01:49:23 -- VINAY + +================================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include "qwlan_version.h" +#include "vos_utils.h" +#include "wma.h" +static struct hdd_context_s *pHddCtx; + + +/*--------------------------------------------------------------------------------------------- + + \brief hdd_OemDataReqCallback() - + + This function also reports the results to the user space + + \return - eHalStatus enumeration + +-----------------------------------------------------------------------------------------------*/ +static eHalStatus hdd_OemDataReqCallback(tHalHandle hHal, + void *pContext, + tANI_U32 oemDataReqID, + eOemDataReqStatus oemDataReqStatus) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + struct net_device *dev = (struct net_device *) pContext; + union iwreq_data wrqu; + char buffer[IW_CUSTOM_MAX+1]; + + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buffer, '\0', sizeof(buffer)); + + //now if the status is success, then send an event up + //so that the application can request for the data + //else no need to send the event up + if (oemDataReqStatus == eOEM_DATA_REQ_FAILURE) { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-FAILED"); + hddLog(LOGW, "%s: oem data req %d failed", __func__, oemDataReqID); + } else if(oemDataReqStatus == eOEM_DATA_REQ_INVALID_MODE) { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-INVALID-MODE"); + hddLog(LOGW, "%s: oem data req %d failed because the driver is in invalid mode (IBSS|BTAMP|AP)", __func__, oemDataReqID); + } else { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-SUCCESS"); + } + + wrqu.data.pointer = buffer; + wrqu.data.length = strlen(buffer); + + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buffer); + + return status; +} + +/**-------------------------------------------------------------------------------------------- + + \brief iw_get_oem_data_rsp() - + + This function gets the oem data response. This invokes + the respective sme functionality. Function for handling the oem data rsp + IOCTL + + \param - dev - Pointer to the net device + - info - Pointer to the iw_oem_data_req + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +-----------------------------------------------------------------------------------------------*/ +int iw_get_oem_data_rsp( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int rc = 0; + eHalStatus status; + struct iw_oem_data_rsp* pHddOemDataRsp; + tOemDataRsp* pSmeOemDataRsp; + + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return -EBUSY; + } + + do + { + //get the oem data response from sme + status = sme_getOemDataRsp(WLAN_HDD_GET_HAL_CTX(pAdapter), &pSmeOemDataRsp); + if (status != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, "%s: failed in sme_getOemDataRsp", __func__); + rc = -EIO; + break; + } + else + { + if (pSmeOemDataRsp != NULL) + { + pHddOemDataRsp = (struct iw_oem_data_rsp*)(extra); + vos_mem_copy(pHddOemDataRsp->oemDataRsp, pSmeOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); + } + else + { + hddLog(LOGE, "%s: pSmeOemDataRsp = NULL", __func__); + rc = -EIO; + break; + } + } + } while(0); + + return rc; +} + +/**--------------------------------------------------------------------------- + + \brief iw_set_oem_data_req() + + This function sets the oem data req configuration. This invokes + the respective sme oem data req functionality. Function for + handling the set IOCTL for the oem data req configuration + + \param - dev - Pointer to the net device + - info - Pointer to the iw_oem_data_req + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +-----------------------------------------------------------------------------------------------*/ +int iw_set_oem_data_req( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int rc = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + struct iw_oem_data_req *pOemDataReq = NULL; + tOemDataReqConfig oemDataReqConfig; + + tANI_U32 oemDataReqID = 0; + + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return -EBUSY; + } + + do + { + if (NULL != wrqu->data.pointer) + { + pOemDataReq = (struct iw_oem_data_req *)wrqu->data.pointer; + } + + if (pOemDataReq == NULL) + { + hddLog(LOGE, "in %s oemDataReq == NULL", __func__); + rc = -EIO; + break; + } + + vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); + + if (copy_from_user((&oemDataReqConfig)->oemDataReq, + pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: copy_from_user() failed!", __func__); + rc = -EFAULT; + break; + } + + status = sme_OemDataReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &oemDataReqConfig, + &oemDataReqID, + &hdd_OemDataReqCallback, + dev); + if (status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_OemDataReq status %d", __func__, status); + rc = -EFAULT; + break; + } + pwextBuf->oemDataReqID = oemDataReqID; + pwextBuf->oemDataReqInProgress = TRUE; + + } while (0); + + return rc; +} + + +/**--------------------------------------------------------------------------- + + \brief iw_get_oem_data_cap() + + This function gets the capability information for OEM Data Request + and Response. + + \param - dev - Pointer to the net device + - info - Pointer to the t_iw_oem_data_cap + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +----------------------------------------------------------------------------*/ +int iw_get_oem_data_cap( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + eHalStatus status; + t_iw_oem_data_cap oemDataCap; + t_iw_oem_data_cap *pHddOemDataCap; + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + hdd_context_t *pHddContext; + hdd_config_t *pConfig; + tANI_U32 numChannels; + tANI_U8 chanList[OEM_CAP_MAX_NUM_CHANNELS]; + tANI_U32 i; + + ENTER(); + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid context, pAdapter is null", __func__); + return -EINVAL; + } + + pHddContext = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid context, HDD context is null", __func__); + return -EINVAL; + } + + if (pHddContext->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + pConfig = pHddContext->cfg_ini; + if (!pConfig) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:HDD configuration is null", __func__); + return -ENOENT; + } + + do + { + vos_mem_zero(&oemDataCap, sizeof(oemDataCap)); + strlcpy(oemDataCap.oem_target_signature, OEM_TARGET_SIGNATURE, + OEM_TARGET_SIGNATURE_LEN); + oemDataCap.oem_target_type = pHddContext->target_type; + oemDataCap.oem_fw_version = pHddContext->target_fw_version; + oemDataCap.driver_version.major = QWLAN_VERSION_MAJOR; + oemDataCap.driver_version.minor = QWLAN_VERSION_MINOR; + oemDataCap.driver_version.patch = QWLAN_VERSION_PATCH; + oemDataCap.driver_version.build = QWLAN_VERSION_BUILD; + oemDataCap.allowed_dwell_time_min = pConfig->nNeighborScanMinChanTime; + oemDataCap.allowed_dwell_time_max = pConfig->nNeighborScanMaxChanTime; + oemDataCap.curr_dwell_time_min = + sme_getNeighborScanMinChanTime(pHddContext->hHal, + pAdapter->sessionId); + oemDataCap.curr_dwell_time_max = + sme_getNeighborScanMaxChanTime(pHddContext->hHal, + pAdapter->sessionId); + oemDataCap.supported_bands = pConfig->nBandCapability; + + /* request for max num of channels */ + numChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + status = sme_GetCfgValidChannels(pHddContext->hHal, + &chanList[0], + &numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:failed to get valid channel list", __func__); + return -ENOENT; + } + else + { + /* make sure num channels is not more than chan list array */ + if (numChannels > OEM_CAP_MAX_NUM_CHANNELS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Num of channels(%d) more than length(%d) of chanlist", + __func__, numChannels, OEM_CAP_MAX_NUM_CHANNELS); + return -ENOMEM; + } + + oemDataCap.num_channels = numChannels; + for (i = 0; i < numChannels; i++) + { + oemDataCap.channel_list[i] = chanList[i]; + } + } + + pHddOemDataCap = (t_iw_oem_data_cap *)(extra); + vos_mem_copy(pHddOemDataCap, &oemDataCap, sizeof(*pHddOemDataCap)); + } while (0); + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_reg_rsp_nlink_msg() - send oem registration response + + This function sends oem message to registered application process + + \param - + - none + + \return - none + + --------------------------------------------------------------------------*/ +void send_oem_reg_rsp_nlink_msg(void) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *buf; + tANI_U8 *numInterfaces; + tANI_U8 *deviceMode; + tANI_U8 *vdevId; + hdd_adapter_list_node_t *pAdapterNode = NULL; + hdd_adapter_list_node_t *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status = 0; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return; + } + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_APP_REG_RSP; + + /* Fill message body: + * First byte will be number of interfaces, followed by + * two bytes for each interfaces + * - one byte for device mode + * - one byte for vdev id + */ + buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + numInterfaces = buf++; + *numInterfaces = 0; + + /* Iterate through each of the adapters and fill device mode and vdev id */ + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while ((VOS_STATUS_SUCCESS == status) && pAdapterNode) + { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter) + { + deviceMode = buf++; + vdevId = buf++; + *deviceMode = pAdapter->device_mode; + *vdevId = pAdapter->sessionId; + (*numInterfaces)++; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: numInterfaces: %d, deviceMode: %d, vdevId: %d", + __func__, *numInterfaces, *deviceMode, *vdevId); + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + aniHdr->length = sizeof(tANI_U8) + (*numInterfaces) * 2 * sizeof(tANI_U8); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending App Reg Response length (%d) to process pid (%d)", + __func__, aniHdr->length, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_err_rsp_nlink_msg() - send oem error response + + This function sends error response to oem app + + \param - + - app_pid - PID of oem application process + + \return - none + + --------------------------------------------------------------------------*/ +void send_oem_err_rsp_nlink_msg(v_SINT_t app_pid, tANI_U8 error_code) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *buf; + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_OEM_ERROR; + aniHdr->length = sizeof(tANI_U8); + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + aniHdr->length); + + /* message body will contain one byte of error code */ + buf = (char *) ((char *) aniHdr + sizeof(tAniMsgHdr)); + *buf = error_code; + + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending oem error response to process pid (%d)", + __func__, app_pid); + + (void)nl_srv_ucast(skb, app_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_data_rsp_msg() - send oem data response + + This function sends oem data rsp message to registered application process + over the netlink socket. + + \param - + - oemDataRsp - Pointer to OEM Data Response struct + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +void send_oem_data_rsp_msg(int length, tANI_U8 *oemDataRsp) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *oemData; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return; + } + + if (length > OEM_DATA_RSP_SIZE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid length of Oem Data response", __func__); + return; + } + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + OEM_DATA_RSP_SIZE), + GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_OEM_DATA_RSP; + + aniHdr->length = length; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + oemData = (tANI_U8 *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + vos_mem_copy(oemData, oemDataRsp, length); + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending Oem Data Response of len (%d) to process pid (%d)", + __func__, length, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief oem_process_data_req_msg() - process oem data request + + This function sends oem message to SME + + \param - + - oemDataLen - Length to OEM Data buffer + - oemData - Pointer to OEM Data buffer + + \return - eHalStatus enumeration + + --------------------------------------------------------------------------*/ +eHalStatus oem_process_data_req_msg(int oemDataLen, char *oemData) +{ + hdd_adapter_t *pAdapter = NULL; + tOemDataReqConfig oemDataReqConfig; + tANI_U32 oemDataReqID = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* for now, STA interface only */ + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: No adapter for STA mode", __func__); + return eHAL_STATUS_FAILURE; + } + + if (!oemData) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: oemData is null", __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); + + vos_mem_copy((&oemDataReqConfig)->oemDataReq, oemData, oemDataLen); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling sme_OemDataReq", __func__); + + status = sme_OemDataReq(pHddCtx->hHal, + pAdapter->sessionId, + &oemDataReqConfig, + &oemDataReqID, + &hdd_OemDataReqCallback, + pAdapter->dev); + return status; +} + +/**--------------------------------------------------------------------------- + + \brief oem_process_channel_info_req_msg() - process oem channel_info request + + This function responds with channel info to oem process + + \param - + - numOfChannels - number of channels + - chanList - channel list + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tHddChannelInfo *pHddChanInfo; + tHddChannelInfo hddChanInfo; + tANI_U8 chanId; + tANI_U32 reg_info_1; + tANI_U32 reg_info_2; + eHalStatus status = eHAL_STATUS_FAILURE; + int i; + tANI_U8 *buf; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return -1; + } + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(tANI_U8) + + numOfChannels * sizeof(tHddChannelInfo)), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return -1; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_CHANNEL_INFO_RSP; + + aniHdr->length = sizeof(tANI_U8) + numOfChannels * sizeof(tHddChannelInfo); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + + /* First byte of message body will have num of channels */ + buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + *buf++ = numOfChannels; + + /* Next follows channel info struct for each channel id. + * If chan id is wrong or SME returns failure for a channel + * then fill in 0 in channel info for that particular channel + */ + for (i = 0 ; i < numOfChannels; i++) + { + pHddChanInfo = (tHddChannelInfo *) ((char *) buf + + i * sizeof(tHddChannelInfo)); + + chanId = chanList[i]; + status = sme_getRegInfo(pHddCtx->hHal, chanId, + ®_info_1, ®_info_2); + if (eHAL_STATUS_SUCCESS == status) + { + /* band center freq1, and freq2 depends on peer's capability + * and at this time we might not be associated on the given channel, + * so fill freq1=mhz, and freq2=0 + */ + hddChanInfo.chan_id = chanId; + hddChanInfo.reserved0 = 0; + hddChanInfo.mhz = vos_chan_to_freq(chanId); + hddChanInfo.band_center_freq1 = hddChanInfo.mhz; + hddChanInfo.band_center_freq2 = 0; + + /* set only DFS flag in info, rest of the fields will be filled in + * by the OEM App + */ + hddChanInfo.info = 0; + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(chanId)) + WMI_SET_CHANNEL_FLAG(&hddChanInfo, WMI_CHAN_FLAG_DFS); + + hddChanInfo.reg_info_1 = reg_info_1; + hddChanInfo.reg_info_2 = reg_info_2; + } + else + { + /* chanId passed to sme_getRegInfo is not valid, fill in zeros + * in channel info struct + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_getRegInfo failed for chan (%d), return info 0", + __func__, chanId); + hddChanInfo.chan_id = chanId; + hddChanInfo.reserved0 = 0; + hddChanInfo.mhz = 0; + hddChanInfo.band_center_freq1 = 0; + hddChanInfo.band_center_freq2 = 0; + hddChanInfo.info = 0; + hddChanInfo.reg_info_1 = 0; + hddChanInfo.reg_info_2 = 0; + } + vos_mem_copy(pHddChanInfo, &hddChanInfo, sizeof(tHddChannelInfo)); + } + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending channel info resp for num channels (%d) to pid (%d)", + __func__, numOfChannels, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_SendPeerStatusIndToOemApp() + + This function sends peer status indication to registered oem application + + \param - + - peerMac : MAC address of peer + - peerStatus : ePeerConnected or ePeerDisconnected + - peerTimingMeasCap : 0: RTT/RTT2, 1: RTT3. Default is 0 + - sessionId : SME session id, i.e. vdev_id + - chanId: operating channel id + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac, + tANI_U8 peerStatus, + tANI_U8 peerTimingMeasCap, + tANI_U8 sessionId, + tSirSmeChanInfo *chan_info) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tPeerStatusInfo *pPeerInfo; + + + if (!pHddCtx || !pHddCtx->hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Either HDD Ctx is null or Hal Ctx is null", __func__); + return; + } + + /* check if oem app has registered and pid is valid */ + if ((!pHddCtx->oem_app_registered) || (pHddCtx->oem_pid == 0)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: OEM app is not registered(%d) or pid is invalid(%d)", + __func__, pHddCtx->oem_app_registered, pHddCtx->oem_pid); + return; + } + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(tPeerStatusInfo)), + GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_PEER_STATUS_IND; + + aniHdr->length = sizeof(tPeerStatusInfo); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + + pPeerInfo = (tPeerStatusInfo *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + + vos_mem_copy(pPeerInfo->peer_mac_addr, peerMac->bytes, + sizeof(peerMac->bytes)); + pPeerInfo->peer_status = peerStatus; + pPeerInfo->vdev_id = sessionId; + /* peerTimingMeasCap - bit mask for timing and fine timing Meas Cap */ + pPeerInfo->peer_capability = peerTimingMeasCap; + pPeerInfo->reserved0 = 0; + + if (chan_info) { + pPeerInfo->peer_chan_info.chan_id = chan_info->chan_id; + pPeerInfo->peer_chan_info.reserved0 = 0; + pPeerInfo->peer_chan_info.mhz = chan_info->mhz; + pPeerInfo->peer_chan_info.band_center_freq1 = + chan_info->band_center_freq1; + pPeerInfo->peer_chan_info.band_center_freq2 = + chan_info->band_center_freq2; + pPeerInfo->peer_chan_info.info = chan_info->info; + pPeerInfo->peer_chan_info.reg_info_1 = chan_info->reg_info_1; + pPeerInfo->peer_chan_info.reg_info_2 = chan_info->reg_info_2; + } else { + pPeerInfo->peer_chan_info.chan_id = 0; + pPeerInfo->peer_chan_info.reserved0 = 0; + pPeerInfo->peer_chan_info.mhz = 0; + pPeerInfo->peer_chan_info.band_center_freq1 = 0; + pPeerInfo->peer_chan_info.band_center_freq2 = 0; + pPeerInfo->peer_chan_info.info = 0; + pPeerInfo->peer_chan_info.reg_info_1 = 0; + pPeerInfo->peer_chan_info.reg_info_2 = 0; + } + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: sending peer "MAC_ADDRESS_STR + " status(%d), peerTimingMeasCap(%d), vdevId(%d), chanId(%d)" + " to oem app pid(%d), center freq 1 (%d), center freq 2 (%d)," + " info (0x%x), frequency (%d),reg info 1 (0x%x)," + " reg info 2 (0x%x)",__func__, MAC_ADDR_ARRAY(peerMac->bytes), + peerStatus, peerTimingMeasCap, sessionId, + pPeerInfo->peer_chan_info.chan_id, pHddCtx->oem_pid, + pPeerInfo->peer_chan_info.band_center_freq1, + pPeerInfo->peer_chan_info.band_center_freq2, + pPeerInfo->peer_chan_info.info, + pPeerInfo->peer_chan_info.mhz, + pPeerInfo->peer_chan_info.reg_info_1, + pPeerInfo->peer_chan_info.reg_info_2); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return; +} + +/* + * Callback function invoked by Netlink service for all netlink + * messages (from user space) addressed to WLAN_NL_MSG_OEM + */ + +/** + * oem_msg_callback() - callback invoked by netlink service + * @skb: skb with netlink message + * + * This function gets invoked by netlink service when a message + * is received from user space addressed to WLAN_NL_MSG_OEM + * + * Return: zero on success + * On error, error number will be returned. + */ +static int oem_msg_callback(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + tAniMsgHdr *msg_hdr; + int ret; + char *sign_str = NULL; + nlh = (struct nlmsghdr *)skb->data; + + if (!nlh) { + hddLog(LOGE, FL("Netlink header null")); + return -EPERM; + } + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + msg_hdr = NLMSG_DATA(nlh); + + if (!msg_hdr) { + hddLog(LOGE, FL("Message header null")); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, OEM_ERR_NULL_MESSAGE_HEADER); + return -EPERM; + } + + if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr) + msg_hdr->length)) { + hddLog(LOGE, FL("Invalid nl msg len, nlh->nlmsg_len (%d), msg_hdr->len (%d)"), + nlh->nlmsg_len, msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + + switch (msg_hdr->type) { + case ANI_MSG_APP_REG_REQ: + /* Registration request is only allowed for Qualcomm Application */ + hddLog(LOG1, FL("Received App Req Req from App process pid(%d), len(%d)"), + nlh->nlmsg_pid, msg_hdr->length); + + sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr)); + if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) && + (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR, + OEM_APP_SIGNATURE_LEN))) { + hddLog(LOG1, FL("Valid App Req Req from oem app process pid(%d)"), + nlh->nlmsg_pid); + + pHddCtx->oem_app_registered = TRUE; + pHddCtx->oem_pid = nlh->nlmsg_pid; + send_oem_reg_rsp_nlink_msg(); + } else { + hddLog(LOGE, FL("Invalid signature in App Reg Request from pid(%d)"), + nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_SIGNATURE); + return -EPERM; + } + break; + + case ANI_MSG_OEM_DATA_REQ: + hddLog(LOG1, FL("Received Oem Data Request length(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!pHddCtx->oem_app_registered) || + (nlh->nlmsg_pid != pHddCtx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, FL("OEM DataReq: app not registered(%d) or incorrect pid(%d)"), + pHddCtx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) { + hddLog(LOGE, FL("Invalid length (%d) in Oem Data Request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + oem_process_data_req_msg(msg_hdr->length, + (char *) ((char *)msg_hdr + + sizeof(tAniMsgHdr))); + break; + + case ANI_MSG_CHANNEL_INFO_REQ: + hddLog(LOG1, + FL("Received channel info request, num channel(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!pHddCtx->oem_app_registered) || + (nlh->nlmsg_pid != pHddCtx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, + FL("Chan InfoReq: app not registered(%d) or incorrect pid(%d)"), + pHddCtx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + /* message length contains list of channel ids */ + if ((!msg_hdr->length) || + (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) { + hddLog(LOGE, + FL("Invalid length (%d) in channel info request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + oem_process_channel_info_req_msg(msg_hdr->length, + (char *)((char*)msg_hdr + sizeof(tAniMsgHdr))); + break; + + default: + hddLog(LOGE, + FL("Received Invalid message type (%d), length (%d)"), + msg_hdr->type, msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_TYPE); + return -EPERM; + } + return 0; +} + +static int __oem_msg_callback(struct sk_buff *skb) +{ + int ret; + + vos_ssr_protect(__func__); + ret = oem_msg_callback(skb); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief oem_activate_service() - Activate oem message handler + + This function registers a handler to receive netlink message from + an OEM application process. + + \param - + - pAdapter - pointer to HDD adapter + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int oem_activate_service(void *pAdapter) +{ + pHddCtx = (struct hdd_context_s*) pAdapter; + + /* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */ + nl_srv_register(WLAN_NL_MSG_OEM, __oem_msg_callback); + return 0; +} + + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c new file mode 100644 index 0000000000000..874f8479170a1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_p2p.c @@ -0,0 +1,2665 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_p2p.c + + \brief WLAN Host Device Driver implementation for P2P commands interface + + ========================================================================*/ + +#include +#include +#include +#include "sme_Api.h" +#include "sme_QosApi.h" +#include "wlan_hdd_p2p.h" +#include "sapApi.h" +#include "wlan_hdd_main.h" +#include "vos_trace.h" +#include +#include +#include +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_sched.h" + +//Ms to Micro Sec +#define MS_TO_MUS(x) ((x)*1000); + +tANI_U8* hdd_getActionString( tANI_U16 MsgType ) +{ + switch (MsgType) + { + CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT); + CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT); + CASE_RETURN_STRING(SIR_MAC_ACTION_DLP); + CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK); + CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE); + CASE_RETURN_STRING(SIR_MAC_ACTION_RRM); + CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST); + CASE_RETURN_STRING(SIR_MAC_ACTION_HT); + CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY); + CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB); + CASE_RETURN_STRING(SIR_MAC_ACTION_WNM); + CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM); + CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS); + CASE_RETURN_STRING(SIR_MAC_ACITON_MESH); + CASE_RETURN_STRING(SIR_MAC_ACTION_MHF); + CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED); + CASE_RETURN_STRING(SIR_MAC_ACTION_WME); + CASE_RETURN_STRING(SIR_MAC_ACTION_VHT); + default: + return ("UNKNOWN"); + } +} + +#ifdef WLAN_FEATURE_P2P_DEBUG +#define MAX_P2P_ACTION_FRAME_TYPE 9 +const char *p2p_action_frame_type[]={"GO Negotiation Request", + "GO Negotiation Response", + "GO Negotiation Confirmation", + "P2P Invitation Request", + "P2P Invitation Response", + "Device Discoverability Request", + "Device Discoverability Response", + "Provision Discovery Request", + "Provision Discovery Response"}; + +/* We no need to protect this variable since + * there is no chance of race to condition + * and also not make any complicating the code + * just for debugging log + */ +tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE; + +#endif +#ifdef WLAN_FEATURE_TDLS_DEBUG +#define MAX_TDLS_ACTION_FRAME_TYPE 11 +const char *tdls_action_frame_type[] = {"TDLS Setup Request", + "TDLS Setup Response", + "TDLS Setup Confirm", + "TDLS Teardown", + "TDLS Peer Traffic Indication", + "TDLS Channel Switch Request", + "TDLS Channel Switch Response", + "TDLS Peer PSM Request", + "TDLS Peer PSM Response", + "TDLS Peer Traffic Response", + "TDLS Discovery Request" }; +#endif + +extern struct net_device_ops net_ops_struct; + +static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb, + int rtap_len, int flag ); + +static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter, + hdd_cfg80211_state_t* cfgState, + tANI_BOOLEAN actionSendSuccess ); + +static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ); + +static bool wlan_hdd_is_type_p2p_action( const u8 *buf ) +{ + const u8 *ouiPtr; + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] != + WLAN_HDD_PUBLIC_ACTION_FRAME ) { + return FALSE; + } + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] != + WLAN_HDD_VENDOR_SPECIFIC_ACTION ) { + return FALSE; + } + + ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET]; + + if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) { + return FALSE; + } + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] != + WLAN_HDD_WFA_P2P_OUI_TYPE ) { + return FALSE; + } + + return TRUE; +} + +static bool hdd_p2p_is_action_type_rsp( const u8 *buf ) +{ + tActionFrmType actionFrmType; + + if ( wlan_hdd_is_type_p2p_action(buf) ) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET]; + if ( actionFrmType != WLAN_HDD_INVITATION_REQ && + actionFrmType != WLAN_HDD_GO_NEG_REQ && + actionFrmType != WLAN_HDD_DEV_DIS_REQ && + actionFrmType != WLAN_HDD_PROV_DIS_REQ ) + return TRUE; + } + + return FALSE; +} + +eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx, + eHalStatus status ) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + + if( pRemainChanCtx == NULL ) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog( LOGW, + "%s: No Rem on channel pending for which Rsp is received", __func__); + return eHAL_STATUS_SUCCESS; + } + + hddLog( LOG1, "Received remain on channel rsp"); + vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer); + vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer); + + cfgState->remain_on_chan_ctx = NULL; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + + if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) + { + if( cfgState->buf ) + { + hddLog( LOGP, + "%s: We need to receive yet an ack from one of tx packet", + __func__); + } + cfg80211_remain_on_channel_expired( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pRemainChanCtx->dev->ieee80211_ptr, +#else + pRemainChanCtx->dev, +#endif + pRemainChanCtx->cookie, + &pRemainChanCtx->chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type, +#endif + GFP_KERNEL); + pAdapter->lastRocTs = vos_timer_get_system_time(); + } + + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) + { + sme_DeregisterMgmtFrame( + hHal, sessionId, + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0 ); + } + } + else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + WLANSAP_DeRegisterMgmtFrame( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, +#endif + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0 ); + + } + + if(pRemainChanCtx->action_pkt_buff.frame_ptr != NULL + && pRemainChanCtx->action_pkt_buff.frame_length != 0 ) + { + vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr); + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + pRemainChanCtx->action_pkt_buff.frame_length = 0; + } + vos_mem_free( pRemainChanCtx ); + complete(&pAdapter->cancel_rem_on_chan_var); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pAdapter->is_roc_inprogress = FALSE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hdd_allow_suspend(); + return eHAL_STATUS_SUCCESS; +} + +void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter) +{ + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + unsigned long rc; + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + if(cfgState->remain_on_chan_ctx != NULL) + { + hddLog(LOGE, "Cancel Existing Remain on Channel"); + + if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( + &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer)) + vos_timer_stop(&cfgState->remain_on_chan_ctx-> + hdd_remain_on_chan_timer); + + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress == TRUE) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog(LOGE, + "ROC timer cancellation in progress," + " wait for completion"); + rc = wait_for_completion_timeout(&pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (!rc) { + hddLog(LOGE, + "%s:wait on cancel_rem_on_chan_var timed out", + __func__); + } + return; + } + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + /* Wait till remain on channel ready indication before issuing cancel + * remain on channel request, otherwise if remain on channel not + * received and if the driver issues cancel remain on channel then lim + * will be in unknown state. + */ + rc = wait_for_completion_timeout(&pAdapter->rem_on_chan_ready_event, + msecs_to_jiffies(WAIT_REM_CHAN_READY)); + if (!rc) { + hddLog( LOGE, + "%s: timeout waiting for remain on channel ready indication", + __func__); + } + + INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); + + /* Issue abort remain on chan request to sme. + * The remain on channel callback will make sure the remain_on_chan + * expired event is sent. + */ + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), + pAdapter->sessionId ); + } + else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode) + ) + { + WLANSAP_CancelRemainOnChannel( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); +#endif + } + + rc = wait_for_completion_timeout(&pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + + if (!rc) { + hddLog( LOGE, + "%s: timeout waiting for cancel remain on channel ready" + " indication", + __func__); + } + hdd_allow_suspend(); + } else + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); +} + +int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter) +{ + int status = 0; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if(WLAN_HDD_P2P_GO != pAdapter->device_mode) + { + //Cancel Existing Remain On Channel + //If no action frame is pending + if( cfgState->remain_on_chan_ctx != NULL) + { + //Check whether Action Frame is pending or not + if( cfgState->buf == NULL) + { + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + } + else + { + hddLog( LOG1, "Cannot Cancel Existing Remain on Channel"); + status = -EBUSY; + } + } + } + return status; +} +/* Clean up RoC context at hdd_stop_adapter*/ +void wlan_hdd_cleanup_remain_on_channel_ctx(hdd_adapter_t *pAdapter) +{ + unsigned long rc; + v_U8_t retry = 0; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter); + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + while (pAdapter->is_roc_inprogress) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC in progress for session %d!!!", + __func__, pAdapter->sessionId); + msleep(500); + if (retry++ > 3) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC completion is not received.!!!", __func__); + if (pAdapter->device_mode == WLAN_HDD_P2P_GO) + { + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + } else if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT || + pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) + { + sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + } + + rc = wait_for_completion_timeout(&pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (!rc) { + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for RoC Cancellation" , + __func__); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx != NULL) + { + cfgState->remain_on_chan_ctx = NULL; + vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer); + vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer); + if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL + && pRemainChanCtx->action_pkt_buff.frame_length != 0) + { + vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr); + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + pRemainChanCtx->action_pkt_buff.frame_length = 0; + } + vos_mem_free( pRemainChanCtx ); + pAdapter->is_roc_inprogress = FALSE; + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + } + /* hold the lock before break from the loop */ + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + break; + } + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + } /* end of while */ + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + +} + +void wlan_hdd_remain_on_chan_timeout(void *data) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)data; + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + hdd_cfg80211_state_t *cfgState; + + if(NULL == pAdapter) + { + hddLog( LOGE,"%s: pAdapter is NULL !!!", __func__); + return; + } + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + + if(NULL == pRemainChanCtx) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog( LOGE,"%s: No Remain on channel is pending", __func__); + return; + } + + if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress ) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog( LOGE, FL("Cancellation already in progress")); + return; + } + + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__); + + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), + pAdapter->sessionId ); + } + else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode) + ) + { + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + } + + hdd_allow_suspend(); + +} + +static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter, + hdd_remain_on_chan_ctx_t *pRemainChanCtx) +{ + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter_temp; + VOS_STATUS status; + v_BOOL_t isGoPresent = VOS_FALSE; + unsigned int duration; + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + if (pAdapter->is_roc_inprogress == TRUE) { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("remain on channel request is in execution")); + return -EBUSY; + } + cfgState->remain_on_chan_ctx = pRemainChanCtx; + cfgState->current_freq = pRemainChanCtx->chan.center_freq; + pAdapter->is_roc_inprogress = TRUE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + + /* Initialize Remain on chan timer */ + vos_status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer, + VOS_TIMER_TYPE_SW, + wlan_hdd_remain_on_chan_timeout, + pAdapter); + if (vos_status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not able to initialize remain_on_chan timer")); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + cfgState->remain_on_chan_ctx = NULL; + pAdapter->is_roc_inprogress = FALSE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + vos_mem_free(pRemainChanCtx); + return -EINVAL; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter_temp = pAdapterNode->pAdapter; + if(pAdapter_temp->device_mode == WLAN_HDD_P2P_GO) + { + isGoPresent = VOS_TRUE; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + //Extending duration for proactive extension logic for RoC + duration = pRemainChanCtx->duration; + if (isGoPresent == VOS_TRUE) + duration = P2P_ROC_DURATION_MULTIPLIER_GO_PRESENT * duration; + else + duration = P2P_ROC_DURATION_MULTIPLIER_GO_ABSENT * duration; + + + hdd_prevent_suspend(); + INIT_COMPLETION(pAdapter->rem_on_chan_ready_event); + + //call sme API to start remain on channel. + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + //call sme API to start remain on channel. + + if (eHAL_STATUS_SUCCESS != sme_RemainOnChannel( + WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, + pRemainChanCtx->chan.hw_value, duration, + wlan_hdd_remain_on_channel_callback, pAdapter, + (tANI_U8)(pRemainChanCtx->rem_on_chan_request + == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE)) { + hddLog(LOGE, FL("sme_RemainOnChannel returned failure")); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + cfgState->remain_on_chan_ctx = NULL; + pAdapter->is_roc_inprogress = FALSE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + vos_mem_free(pRemainChanCtx); + hdd_allow_suspend(); + return -EINVAL; + } + + if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) { + if (eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame( + WLAN_HDD_GET_HAL_CTX(pAdapter), + sessionId, (SIR_MAC_MGMT_FRAME << 2) | + (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0)) + hddLog(LOGE, FL("sme_RegisterMgmtFrame returned failure")); + } + } + else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + //call sme API to start remain on channel. + if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, +#endif + pRemainChanCtx->chan.hw_value, duration, + wlan_hdd_remain_on_channel_callback, pAdapter)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_RemainOnChannel returned fail", __func__); + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + cfgState->remain_on_chan_ctx = NULL; + pAdapter->is_roc_inprogress = FALSE; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + vos_mem_free (pRemainChanCtx); + hdd_allow_suspend(); + return -EINVAL; + } + + + if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, +#endif + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__); + WLANSAP_CancelRemainOnChannel( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); +#endif + hdd_allow_suspend(); + return -EINVAL; + } + + } + return 0; +} + +/** + * wlan_hdd_roc_request_enqueue() - enqueue remain on channel request + * @adapter: Pointer to the adapter + * @remain_chan_ctx: Pointer to the remain on channel context + * + * Return: 0 on success, error number otherwise + */ +static int wlan_hdd_roc_request_enqueue(hdd_adapter_t *adapter, + hdd_remain_on_chan_ctx_t *remain_chan_ctx) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + hdd_roc_req_t *hdd_roc_req; + VOS_STATUS status; + + /* + * "Driver is busy" OR "there is already RoC request inside the queue" + * so enqueue this RoC Request and execute sequentially later. + */ + + hdd_roc_req = vos_mem_malloc(sizeof(*hdd_roc_req)); + + if (NULL == hdd_roc_req) { + hddLog(LOGP, FL("malloc failed for roc req context")); + return -ENOMEM; + } + + hdd_roc_req->pAdapter = adapter; + hdd_roc_req->pRemainChanCtx = remain_chan_ctx; + + /* Enqueue this RoC request */ + spin_lock(&hdd_ctx->hdd_roc_req_q.lock); + status = hdd_list_insert_back(&hdd_ctx->hdd_roc_req_q, + &hdd_roc_req->node); + spin_unlock(&hdd_ctx->hdd_roc_req_q.lock); + + if (VOS_STATUS_SUCCESS != status) { + hddLog(LOGP, FL("Not able to enqueue RoC Req context")); + vos_mem_free(hdd_roc_req); + return -EINVAL; + } + + return 0; +} + +/** + * wlan_hdd_roc_request_dequeue() - dequeue remain on channel request + * @work: Pointer to work queue struct + * + * Return: none + */ +void wlan_hdd_roc_request_dequeue(struct work_struct *work) +{ + VOS_STATUS status; + int ret = 0; + hdd_roc_req_t *hdd_roc_req; + hdd_context_t *hdd_ctx = + container_of(work, hdd_context_t, rocReqWork); + + hddLog(LOG1, FL("RoC request timeout")); + + if (list_empty(&hdd_ctx->hdd_roc_req_q.anchor)) + return; + + /* If driver is busy then we can't run RoC */ + if (hdd_ctx->isLoadInProgress || hdd_ctx->isUnloadInProgress || + hdd_isConnectionInProgress(hdd_ctx)) { + hddLog(LOGE, + FL("Wlan Load/Unload or Connection is in progress")); + return; + } + + if (hdd_ctx->isLogpInProgress) { + hddLog(LOGE, FL("LOGP in Progress. Ignore!!!")); + return; + } + + while (!list_empty(&hdd_ctx->hdd_roc_req_q.anchor)) { + /* go to process this RoC request */ + spin_lock(&hdd_ctx->hdd_roc_req_q.lock); + status = hdd_list_remove_front(&hdd_ctx->hdd_roc_req_q, + (hdd_list_node_t**) &hdd_roc_req); + spin_unlock(&hdd_ctx->hdd_roc_req_q.lock); + + if (status == VOS_STATUS_SUCCESS) { + ret = wlan_hdd_execute_remain_on_channel( + hdd_roc_req->pAdapter, + hdd_roc_req->pRemainChanCtx); + if (ret == -EBUSY){ + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("dropping RoC request")); + vos_mem_free(hdd_roc_req->pRemainChanCtx); + } + vos_mem_free(hdd_roc_req); + } + } +} + +static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie, + rem_on_channel_request_type_t request_type ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = NULL; + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + v_BOOL_t isBusy = VOS_FALSE; + v_SIZE_t size = 0; + hdd_adapter_t *sta_adapter; + int ret = 0; + int status = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__, pAdapter->device_mode); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + hddLog( LOG1, + "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, duration %d", + chan->hw_value, chan->center_freq, channel_type, duration ); +#else + hddLog( LOG1, + "chan(hw_val)0x%x chan(centerfreq) %d, duration %d", + chan->hw_value, chan->center_freq, duration ); +#endif + + /* + * When P2P-GO and if we are trying to unload the driver then + * wlan driver is keep on receiving the remain on channel command + * and which is resulting in crash. So not allowing any remain on + * channel requets when Load/Unload is in progress + */ + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + if (hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx)) { + hddLog(LOGE, FL("Connection is in progress")); + isBusy = VOS_TRUE; + } + + pRemainChanCtx = vos_mem_malloc(sizeof(hdd_remain_on_chan_ctx_t)); + if (NULL == pRemainChanCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Not able to allocate memory for Channel context", + __func__); + return -ENOMEM; + } + + vos_mem_copy(&pRemainChanCtx->chan, chan, + sizeof(struct ieee80211_channel)); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type = channel_type; +#endif + pRemainChanCtx->duration = duration; + pRemainChanCtx->p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + pRemainChanCtx->dev = dev; + *cookie = (uintptr_t) pRemainChanCtx; + pRemainChanCtx->cookie = *cookie; + pRemainChanCtx->rem_on_chan_request = request_type; + + pRemainChanCtx->action_pkt_buff.freq = 0; + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + pRemainChanCtx->action_pkt_buff.frame_length = 0; + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE; + + if (REMAIN_ON_CHANNEL_REQUEST == request_type) { + sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if ((NULL != sta_adapter)&& + hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter))) { + if (pAdapter->lastRocTs !=0 && + ((vos_timer_get_system_time() - pAdapter->lastRocTs ) + < pHddCtx->cfg_ini->p2p_listen_defer_interval)) { + if (pRemainChanCtx->duration > HDD_P2P_MAX_ROC_DURATION) + pRemainChanCtx->duration = HDD_P2P_MAX_ROC_DURATION; + + wlan_hdd_roc_request_enqueue(pAdapter, pRemainChanCtx); + schedule_delayed_work(&pAdapter->roc_work, + msecs_to_jiffies(pHddCtx->cfg_ini->p2p_listen_defer_interval)); + hddLog(LOG1, "Defer interval is %hu, pAdapter %p", + pHddCtx->cfg_ini->p2p_listen_defer_interval, pAdapter); + return 0; + } + } + } + + /* Check roc_req_Q has pending RoC Request or not */ + hdd_list_size(&(pHddCtx->hdd_roc_req_q), &size); + + if ((isBusy == VOS_FALSE) && (!size)) { + /* Media is free and no RoC request is in queue, execute directly */ + status = wlan_hdd_execute_remain_on_channel(pAdapter, + pRemainChanCtx); + if (status == -EBUSY) { + if (wlan_hdd_roc_request_enqueue(pAdapter, pRemainChanCtx)) { + vos_mem_free(pRemainChanCtx); + return -EAGAIN; + } + } + return 0; + } else { + if (wlan_hdd_roc_request_enqueue(pAdapter, pRemainChanCtx)) { + vos_mem_free(pRemainChanCtx); + return -EAGAIN; + } + } + + /* + * if driver is free and there is RoC request in the queue then + * schedule the RoC work directly. + */ + if (isBusy == VOS_FALSE) { + schedule_work(&pHddCtx->rocReqWork); + } + + return 0; +} + +int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_REMAIN_ON_CHANNEL, + pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST)); + return wlan_hdd_request_remain_on_channel(wiphy, dev, + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + duration, cookie, + REMAIN_ON_CHANNEL_REQUEST); +} + +int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wdev, +#else + dev, +#endif + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + duration, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} + + +void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ) +{ + hdd_cfg80211_state_t *cfgState = NULL; + hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL; + VOS_STATUS status; + + if (NULL == pAdapter) + { + hddLog(LOGE, FL("pAdapter is NULL")); + return; + } + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hddLog( LOG1, "Ready on chan ind"); + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if( pRemainChanCtx != NULL ) + { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_REMAINCHANREADYHANDLER, + pAdapter->sessionId, pRemainChanCtx->duration)); + + // Removing READY_EVENT_PROPOGATE_TIME from current time which gives + // more accurate Remain on Channel start time. + pRemainChanCtx->p2pRemOnChanTimeStamp = + vos_timer_get_system_time() - READY_EVENT_PROPOGATE_TIME; + + //start timer for actual duration + if(VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer)) + { + hddLog( LOGE, "Timer Started before ready event!!!"); + vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer); + } + status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer, + (pRemainChanCtx->duration + COMPLETE_EVENT_PROPOGATE_TIME)); + if (status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, "%s: Remain on Channel timer start failed", + __func__); + } + + if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) + { + cfg80211_ready_on_channel( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + (uintptr_t)pRemainChanCtx, + &pRemainChanCtx->chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type, +#endif + pRemainChanCtx->duration, GFP_KERNEL ); + } + else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request) + { + complete(&pAdapter->offchannel_tx_event); + } + + // Check for cached action frame + if(pRemainChanCtx->action_pkt_buff.frame_length != 0) + { + hddLog(LOGE, "%s: Sent cached action frame to supplicant", __func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr,pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + cfg80211_rx_mgmt( pAdapter->dev, pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#else + cfg80211_rx_mgmt( pAdapter->dev, pRemainChanCtx->action_pkt_buff.freq, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#endif /* LINUX_VERSION_CODE */ + + vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr); + pRemainChanCtx->action_pkt_buff.frame_length = 0; + pRemainChanCtx->action_pkt_buff.freq = 0; + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + } + complete(&pAdapter->rem_on_chan_ready_event); + } + else + { + hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__); + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + return; +} + +int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + int status; + unsigned long rc; + hdd_list_node_t *tmp, *q; + hdd_roc_req_t *curr_roc_req; + + hddLog( LOG1, "Cancel remain on channel"); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + /* Remove RoC request inside queue */ + spin_lock(&pHddCtx->hdd_roc_req_q.lock); + list_for_each_safe(tmp, q, &pHddCtx->hdd_roc_req_q.anchor) { + curr_roc_req = list_entry(tmp, hdd_roc_req_t, node); + if ((uintptr_t)curr_roc_req->pRemainChanCtx == cookie) { + status = hdd_list_remove_node(&pHddCtx->hdd_roc_req_q, + (hdd_list_node_t*)curr_roc_req); + spin_unlock(&pHddCtx->hdd_roc_req_q.lock); + if (status == VOS_STATUS_SUCCESS) { + vos_mem_free(curr_roc_req->pRemainChanCtx); + vos_mem_free(curr_roc_req); + } + return 0; + } + } + spin_unlock(&pHddCtx->hdd_roc_req_q.lock); + + /* FIXME cancel currently running remain on chan. + * Need to check cookie and cancel accordingly + */ + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if( (cfgState->remain_on_chan_ctx == NULL) || + (cfgState->remain_on_chan_ctx->cookie != cookie) ) + { + hddLog( LOGE, + "%s: No Remain on channel pending with specified cookie value", + __func__); + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + return -EINVAL; + } + + if (NULL != cfgState->remain_on_chan_ctx) + { + vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer); + if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog( LOG1, + FL("ROC timer cancellation in progress," + " wait for completion")); + rc = wait_for_completion_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (!rc) { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var timed out", + __func__); + } + return 0; + } + else + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + + /* wait until remain on channel ready event received + * for already issued remain on channel request */ + rc = wait_for_completion_timeout(&pAdapter->rem_on_chan_ready_event, + msecs_to_jiffies(WAIT_REM_CHAN_READY)); + if (!rc) { + hddLog( LOGE, + "%s: timeout waiting for remain on channel ready indication", + __func__); + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + } + INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); + /* Issue abort remain on chan request to sme. + * The remain on channel callback will make sure the remain_on_chan + * expired event is sent. + */ + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + + tANI_U8 sessionId = pAdapter->sessionId; + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), + sessionId ); + } + else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode) + ) + { + WLANSAP_CancelRemainOnChannel( +#ifdef WLAN_FEATURE_MBSSID + WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); +#else + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); +#endif + + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d", + __func__, pAdapter->device_mode); + return -EIO; + } + rc = wait_for_completion_timeout(&pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (!rc) { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var timed out ", __func__); + } + hdd_allow_suspend(); + return 0; +} + +int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wdev, +#else + dev, +#endif + cookie); + vos_ssr_unprotect(__func__); + + return ret; +} + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#else +int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, u64 *cookie ) +#endif /* LINUX_VERSION_CODE */ +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tANI_U16 extendedWait = 0; + tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); + tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); + tActionFrmType actionFrmType; + bool noack = 0; + int status; + unsigned long rc; + hdd_adapter_t *goAdapter; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_ACTION, pAdapter->sessionId, + pAdapter->device_mode )); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d", + __func__, pAdapter->device_mode, type); + +#ifdef WLAN_FEATURE_P2P_DEBUG + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION) && + wlan_hdd_is_type_p2p_action(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET])) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA to " + MAC_ADDRESS_STR, actionFrmType, + MAC_ADDR_ARRAY(&buf[WLAN_HDD_80211_FRM_DA_OFFSET])); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA to " + MAC_ADDRESS_STR, p2p_action_frame_type[actionFrmType], + MAC_ADDR_ARRAY(&buf[WLAN_HDD_80211_FRM_DA_OFFSET])); + if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; + hddLog(LOGE,"[P2P State]Inactive state to " + "GO negotiation progress state"); + } + else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]GO nego progress to GO nego" + " completed state"); + } + } + } +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + noack = dont_wait_for_ack; +#endif + + //If the wait is coming as 0 with off channel set + //then set the wait to 200 ms + if (offchan && !wait) + wait = ACTION_FRAME_DEFAULT_WAIT; + + //Call sme API to send out a action frame. + // OR can we send it directly through data path?? + // After tx completion send tx status back. + if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + if (type == SIR_MAC_MGMT_FRAME) + { + if (subType == SIR_MAC_MGMT_PROBE_RSP) + { + /* Drop Probe response recieved from supplicant, as for GO and + SAP PE itself sends probe response + */ + goto err_rem_channel; + } + else if ((subType == SIR_MAC_MGMT_DISASSOC) || + (subType == SIR_MAC_MGMT_DEAUTH)) + { + /* During EAP failure or P2P Group Remove supplicant + * is sending del_station command to driver. From + * del_station function, Driver will send deauth frame to + * p2p client. No need to send disassoc frame from here. + * so Drop the frame here and send tx indication back to + * supplicant. + */ + tANI_U8 dstMac[ETH_ALEN] = {0}; + memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Deauth/Disassoc received for STA:" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(dstMac)); + goto err_rem_channel; + } + } + } + + if( NULL != cfgState->buf ) + { + if ( !noack ) + { + hddLog( LOGE, "(%s):Previous P2P Action frame packet pending", + __func__); + hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter); + } + else + { + hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY", + __func__); + return -EBUSY; + } + } + + if( subType == SIR_MAC_MGMT_ACTION) + { + hddLog( LOG1, "Action frame tx request : %s", + hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET])); + } + + goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO ); + + //If GO adapter exists and operating on same frequency + //then we will not request remain on channel + if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq) + == goAdapter->sessionCtx.ap.operatingChannel ) ) + { + goto send_frame; + } + + if( offchan && wait) + { + int status; + rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX; + // In case of P2P Client mode if we are already + // on the same channel then send the frame directly + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION) && + hdd_p2p_is_action_type_rsp(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET]) && + cfgState->remain_on_chan_ctx && + cfgState->current_freq == chan->center_freq ) + { + if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( + &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer)) + { + vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer); + status = vos_timer_start(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer, + wait); + if(status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, "%s: Remain on Channel timer start failed", + __func__); + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + goto send_frame; + } else { + + if(pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress == TRUE) + { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "action frame tx: waiting for completion of ROC "); + + rc = wait_for_completion_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (!rc) { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var timed out", + __func__); + } + + } else + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + } + } else + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + + if((cfgState->remain_on_chan_ctx != NULL) && + (cfgState->current_freq == chan->center_freq) + ) + { + hddLog(LOG1,"action frame: extending the wait time"); + extendedWait = (tANI_U16)wait; + goto send_frame; + } + + INIT_COMPLETION(pAdapter->offchannel_tx_event); + + status = wlan_hdd_request_remain_on_channel(wiphy, dev, + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + wait, cookie, + req_type); + if(0 != status) + { + if( (-EBUSY == status) && + (cfgState->current_freq == chan->center_freq) ) + { + goto send_frame; + } + goto err_rem_channel; + } + /* This will extend timer in LIM when sending Any action frame + * It will cover remain on channel timer till next action frame + * in rx direction. + */ + extendedWait = (tANI_U16)wait; + /* Wait for driver to be ready on the requested channel */ + rc = wait_for_completion_timeout( + &pAdapter->offchannel_tx_event, + msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX)); + if(!rc) { + hddLog( LOGE, "wait on offchannel_tx_event timed out"); + goto err_rem_channel; + } + } + else if ( offchan ) + { + /* Check before sending action frame + whether we already remain on channel */ + if(NULL == cfgState->remain_on_chan_ctx) + { + goto err_rem_channel; + } + } + send_frame: + + if(!noack) + { + cfgState->buf = vos_mem_malloc( len ); //buf; + if( cfgState->buf == NULL ) + return -ENOMEM; + + cfgState->len = len; + + vos_mem_copy( cfgState->buf, buf, len); + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + + if( cfgState->remain_on_chan_ctx ) + { + cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie; + *cookie = cfgState->action_cookie; + } + else + { + *cookie = (uintptr_t) cfgState->buf; + cfgState->action_cookie = *cookie; + } + + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + } + + if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION) && + (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + hddLog(LOG1, "Tx Action Frame %u", actionFrmType); + if (actionFrmType == WLAN_HDD_PROV_DIS_REQ) + { + cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING; + hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING", __func__); + } + else if (actionFrmType == WLAN_HDD_GO_NEG_REQ) + { + cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING; + hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING", __func__); + } + } + + if (eHAL_STATUS_SUCCESS != + sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter), + sessionId, buf, len, extendedWait, noack)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_sendAction returned fail", __func__); + goto err; + } + } + else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + if( VOS_STATUS_SUCCESS != +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_SendAction( WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), +#else + WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, +#endif + buf, len, 0 ) ) + + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SendAction returned fail", __func__); + goto err; + } + } + + return 0; +err: + if(!noack) + { + hdd_sendActionCnf( pAdapter, FALSE ); + } + return 0; +err_rem_channel: + *cookie = (uintptr_t)cfgState; + cfg80211_mgmt_tx_status( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + *cookie, buf, len, FALSE, GFP_KERNEL ); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#else +int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, size_t len, u64 *cookie ) +#endif /* LINUX_VERSION_CODE */ +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + ret = __wlan_hdd_mgmt_tx(wiphy, wdev, chan, offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, channel_type_valid, +#endif + wait, buf, len, no_cck, + dont_wait_for_ack, cookie); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan, + channel_type, channel_type_valid, wait, + buf, len, no_cck, dont_wait_for_ack, cookie); +#else + ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan, + channel_type, channel_type_valid, wait, + buf, len, cookie); +#endif /* LINUX_VERSION_CODE */ + vos_ssr_unprotect(__func__); + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + return wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, wdev, cookie); +} +#else +int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) +{ + return wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, dev, cookie); +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} +#else +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +/** + * __hdd_p2p_roc_work_queue() - roc delayed work queue handler + * @work: Pointer to work queue struct + * + * Return: none + */ +static void __hdd_p2p_roc_work_queue(struct work_struct *work) +{ + wlan_hdd_roc_request_dequeue(work); +} + +/** + * hdd_p2p_roc_work_queue() - roc delayed work queue handler + * @work: Pointer to work queue struct + * + * Return: none + */ +void hdd_p2p_roc_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_p2p_roc_work_queue(work); + vos_ssr_unprotect(__func__); + + return; +} + +void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess ) +{ + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + cfgState->actionFrmState = HDD_IDLE; + + hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess); + if( NULL == cfgState->buf ) + { + return; + } + + /* If skb is NULL it means this packet was received on CFG80211 interface + * else it was received on Monitor interface */ + if( cfgState->skb == NULL ) + { + /* + * buf is the same pointer it passed us to send. Since we are sending + * it through control path, we use different buffers. + * In case of mac80211, they just push it to the skb and pass the same + * data while sending tx ack status. + * */ + cfg80211_mgmt_tx_status( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + cfgState->action_cookie, + cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL ); + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + } + else + { + hdd_adapter_t* pMonAdapter = + hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR ); + if( pMonAdapter == NULL ) + { + hddLog( LOGE, "Not able to get Monitor Adapter"); + cfgState->skb = NULL; + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + complete(&pAdapter->tx_action_cnf_event); + return; + } + /* Send TX completion feedback over monitor interface. */ + hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess ); + cfgState->skb = NULL; + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + /* Look for the next Mgmt packet to TX */ + hdd_mon_tx_mgmt_pkt(pAdapter); + } + complete(&pAdapter->tx_action_cnf_event); +} + +/** + * hdd_setP2pNoa + * + *FUNCTION: + * This function is called from hdd_hostapd_ioctl function when Driver + * get P2P_SET_NOA command from wpa_supplicant using private ioctl + * + *LOGIC: + * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param dev Pointer to net device structure + * @param command Pointer to command + * + * @return Status + */ + +int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + int count, duration, start_time; + char *param; + int ret; + + param = strnchr(command, strlen(command), ' '); + if (param == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: strnchr failed to find delimeter", __func__); + return -EINVAL; + } + param++; + ret = sscanf(param, "%d %d %d", &count, &start_time, &duration); + if (ret != 3) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: P2P_SET GO NoA: fail to read params, ret=%d", + __func__, ret); + return -EINVAL; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_SET GO NoA: count=%d start_time=%d duration=%d", + __func__, count, start_time, duration); + duration = MS_TO_MUS(duration); + /* PS Selection + * Periodic NoA (2) + * Single NOA (4) + */ + NoA.opp_ps = 0; + NoA.ctWindow = 0; + if (count == 1) + { + NoA.duration = 0; + NoA.single_noa_duration = duration; + NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA; + } + else + { + NoA.duration = duration; + NoA.single_noa_duration = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA; + } + NoA.interval = MS_TO_MUS(100); + NoA.count = count; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + return status; +} + +/** + * hdd_setP2pOpps + * + *FUNCTION: + * This function is called from hdd_hostapd_ioctl function when Driver + * get P2P_SET_PS command from wpa_supplicant using private ioctl + * + *LOGIC: + * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param dev Pointer to net device structure + * @param command Pointer to command + * + * @return Status + */ + +int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + char *param; + int legacy_ps, opp_ps, ctwindow; + int ret; + + param = strnchr(command, strlen(command), ' '); + if (param == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: strnchr failed to find delimiter", __func__); + return -EINVAL; + } + param++; + ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow); + if (ret != 3) { + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: P2P_SET GO PS: fail to read params, ret=%d", + __func__, ret); + return -EINVAL; + } + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d", + __func__, legacy_ps, opp_ps, ctwindow); + + /* PS Selection + * Opportunistic Power Save (1) + */ + + /* From wpa_cli user need to use separate command to set ctWindow and Opps + * When user want to set ctWindow during that time other parameters + * values are coming from wpa_supplicant as -1. + * Example : User want to set ctWindow with 30 then wpa_cli command : + * P2P_SET ctwindow 30 + * Command Received at hdd_hostapd_ioctl is as below: + * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30) + */ + if (ctwindow != -1) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Opportunistic Power Save is %s", + (TRUE == pAdapter->ops) ? "Enable" : "Disable" ); + + if (ctwindow != pAdapter->ctw) + { + pAdapter->ctw = ctwindow; + + if(pAdapter->ops) + { + NoA.opp_ps = pAdapter->ops; + NoA.ctWindow = pAdapter->ctw; + NoA.duration = 0; + NoA.single_noa_duration = 0; + NoA.interval = 0; + NoA.count = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + } + return 0; + } + } + + if (opp_ps != -1) + { + pAdapter->ops = opp_ps; + + + if ((opp_ps != -1) && (pAdapter->ctw)) + { + NoA.opp_ps = opp_ps; + NoA.ctWindow = pAdapter->ctw; + NoA.duration = 0; + NoA.single_noa_duration = 0; + NoA.interval = 0; + NoA.count = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + } + } + return status; +} + +int hdd_setP2pPs( struct net_device *dev, void *msgData ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData; + + NoA.opp_ps = pappNoA->opp_ps; + NoA.ctWindow = pappNoA->ctWindow; + NoA.duration = pappNoA->duration; + NoA.interval = pappNoA->interval; + NoA.count = pappNoA->count; + NoA.single_noa_duration = pappNoA->single_noa_duration; + NoA.psSelection = pappNoA->psSelection; + NoA.sessionid = pAdapter->sessionId; + + sme_p2pSetPs(hHal, &NoA); + return status; +} + +static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type ) +{ + tANI_U8 sessionType; + + switch( type ) + { + case NL80211_IFTYPE_AP: + sessionType = WLAN_HDD_SOFTAP; + break; + case NL80211_IFTYPE_P2P_GO: + sessionType = WLAN_HDD_P2P_GO; + break; + case NL80211_IFTYPE_P2P_CLIENT: + sessionType = WLAN_HDD_P2P_CLIENT; + break; + case NL80211_IFTYPE_STATION: + sessionType = WLAN_HDD_INFRA_STATION; + break; + case NL80211_IFTYPE_MONITOR: + sessionType = WLAN_HDD_MONITOR; + break; + default: + sessionType = WLAN_HDD_INFRA_STATION; + break; + } + + return sessionType; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#else +struct net_device* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#endif +{ + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_adapter_t* pAdapter = NULL; + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return ERR_PTR(ret); + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type)); + /*Allow addition multiple interface for WLAN_HDD_P2P_CLIENT and + WLAN_HDD_SOFTAP session type*/ + if ((hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL) +#ifdef WLAN_FEATURE_MBSSID + && WLAN_HDD_SOFTAP != wlan_hdd_get_session_type(type) +#endif + && WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) + && WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) + ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. " + "Two interfaces of same type are not supported currently.", + __func__, type); + return ERR_PTR(-EINVAL); + } + + wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx); + + if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && + ((NL80211_IFTYPE_P2P_GO == type) || + (NL80211_IFTYPE_P2P_CLIENT == type))) + { + /* Generate the P2P Interface Address. this address must be + * different from the P2P Device Address. + */ + v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress; + p2pDeviceAddress.bytes[4] ^= 0x80; + pAdapter = hdd_open_adapter( pHddCtx, + wlan_hdd_get_session_type(type), + name, p2pDeviceAddress.bytes, + VOS_TRUE ); + } + else + { + pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type), + name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE ); + } + + if( NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__); + return ERR_PTR(-ENOSPC); + } + EXIT(); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + return pAdapter->dev->ieee80211_ptr; +#else + return pAdapter->dev; +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +{ + struct wireless_dev* wdev; + + vos_ssr_protect(__func__); + wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return wdev; +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +{ + struct wireless_dev* wdev; + + vos_ssr_protect(__func__); + wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return wdev; +} +#else +struct net_device* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +{ + struct net_device* ndev; + + vos_ssr_protect(__func__); + ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return ndev; +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) +#else +int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) +#endif +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int status; + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_DEL_VIRTUAL_INTF, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__,pVirtAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is not valid", __func__); + return status; + } + + wlan_hdd_release_intf_addr( pHddCtx, + pVirtAdapter->macAddressCurrent.bytes ); + + hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE ); + hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE ); + EXIT(); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) +#else +int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) +#endif +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + ret = __wlan_hdd_del_virtual_intf(wiphy, wdev); +#else + ret = __wlan_hdd_del_virtual_intf(wiphy, dev); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ) +{ + //Indicate a Frame over Monitor Intf. + int rxstat; + struct sk_buff *skb = NULL; + int needed_headroom = 0; + int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED | + HDD_RX_FLAG_MMIC_STRIPPED; +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx); +#endif + hddLog( LOG1, FL("Indicate Frame over Monitor Intf")); + + if (NULL == pbFrames) + { + hddLog(LOGE, FL("NULL frame pointer")); + return; + } + + /* room for the radiotap header based on driver features + * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for + * RX flags. + * */ + needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4; + + //alloc skb here + skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC); + if (unlikely(NULL == skb)) + { + hddLog( LOGW, FL("Unable to allocate skb")); + return; + } + skb_reserve(skb, VPKT_SIZE_BUFFER); + if (unlikely(skb_headroom(skb) < nFrameLength)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD [%d]: Insufficient headroom, " + "head[%p], data[%p], req[%d]", + __LINE__, skb->head, skb->data, nFrameLength); + kfree_skb(skb); + return ; + } + // actually push the data + memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength); + /* prepend radiotap information */ + if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) ) + { + hddLog( LOGE, FL("Not Able Add Radio Tap")); + //free skb + kfree_skb(skb); + return ; + } + + skb_reset_mac_header( skb ); + skb->dev = pMonAdapter->dev; + skb->protocol = eth_type_trans( skb, skb->dev ); + skb->ip_summed = CHECKSUM_NONE; +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION); +#endif + rxstat = netif_rx_ni(skb); + if( NET_RX_SUCCESS == rxstat ) + { + hddLog( LOG1, FL("Success")); + } + else + hddLog( LOGE, FL("Failed %d"), rxstat); + + return ; +} + +void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType, + tANI_U32 rxChan, + tANI_S8 rxRssi ) +{ + tANI_U16 freq; + tANI_U16 extend_time; + tANI_U8 type = 0; + tANI_U8 subType = 0; + tActionFrmType actionFrmType; + hdd_cfg80211_state_t *cfgState = NULL; + VOS_STATUS status; + hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL; + hdd_context_t *pHddCtx; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d", + __func__, frameType, nFrameLength); + + if (NULL == pAdapter) + { + hddLog(LOGE, FL("pAdapter is NULL")); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 == nFrameLength) + { + hddLog(LOGE, FL("Frame Length is Invalid ZERO")); + return; + } + + if (NULL == pbFrames) + { + hddLog(LOGE, FL("pbFrames is NULL")); + return; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); + + /* Get pAdapter from Destination mac address of the frame */ + if ((type == SIR_MAC_MGMT_FRAME) && + (subType != SIR_MAC_MGMT_PROBE_REQ)) + { + pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter), + &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]); + if (NULL == pAdapter) + { + /* Under assumption that we don't receive any action frame + * with BCST as destination we dropping action frame + */ + hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = " + MAC_ADDRESS_STR , + MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET])); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d" + " subType = %d", __func__, frameType, + nFrameLength, subType); + return; + } + } + + + if (NULL == pAdapter->dev) + { + hddLog( LOGE, FL("pAdapter->dev is NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog( LOGE, FL("pAdapter has invalid magic")); + return; + } + + if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode )) + { + hdd_adapter_t *pMonAdapter = + hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) ); + + if (NULL != pMonAdapter) + { + hddLog( LOG1, FL("Indicate Frame over Monitor Interface")); + hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength, + pbFrames, frameType); + return; + } + } + + //Channel indicated may be wrong. TODO + //Indicate an action frame. + if( rxChan <= MAX_NO_OF_2_4_CHANNELS ) + { + freq = ieee80211_channel_to_frequency( rxChan, + IEEE80211_BAND_2GHZ); + } + else + { + freq = ieee80211_channel_to_frequency( rxChan, + IEEE80211_BAND_5GHZ); + } + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION)) + { + if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME) + { + // public action frame + if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) && + vos_mem_compare(&pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)) + // P2P action frames + { + u8 *macFrom = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6]; + actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + hddLog(LOG1, "Rx Action Frame %u", actionFrmType); +#ifdef WLAN_FEATURE_P2P_DEBUG + if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA" + " from " MAC_ADDRESS_STR, actionFrmType, + MAC_ADDR_ARRAY(macFrom)); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA" + " from " MAC_ADDRESS_STR, + p2p_action_frame_type[actionFrmType], + MAC_ADDR_ARRAY(macFrom)); + if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; + hddLog(LOGE,"[P2P State]Inactive state to " + "GO negotiation progress state"); + } + else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]GO negotiation progress to " + "GO negotiation completed state"); + } + else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]Inactive state to GO negotiation" + " completed state Autonomous GO formation"); + } + } +#endif + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx != NULL) + { + if(actionFrmType == WLAN_HDD_GO_NEG_REQ || + actionFrmType == WLAN_HDD_GO_NEG_RESP || + actionFrmType == WLAN_HDD_INVITATION_REQ || + actionFrmType == WLAN_HDD_DEV_DIS_REQ || + actionFrmType == WLAN_HDD_PROV_DIS_REQ ) + { + hddLog( LOG1, "Extend RoC timer on reception of Action Frame"); + + if ((actionFrmType == WLAN_HDD_GO_NEG_REQ) + || (actionFrmType == WLAN_HDD_GO_NEG_RESP)) + extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT; + else + extend_time = ACTION_FRAME_DEFAULT_WAIT; + + if(completion_done(&pAdapter->rem_on_chan_ready_event)) + { + if(VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer)) + { + vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer); + status = vos_timer_start( + &pRemainChanCtx->hdd_remain_on_chan_timer, + extend_time); + if (status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, "%s: Remain on Channel timer start failed", + __func__); + } + } else { + hddLog( LOG1, "%s: Rcvd action frame after timer expired", + __func__); + } + } else { + // Buffer Packet + if(pRemainChanCtx->action_pkt_buff.frame_length == 0) + { + pRemainChanCtx->action_pkt_buff.frame_length = nFrameLength; + pRemainChanCtx->action_pkt_buff.freq = freq; + pRemainChanCtx->action_pkt_buff.frame_ptr + = vos_mem_malloc(nFrameLength); + vos_mem_copy(pRemainChanCtx->action_pkt_buff.frame_ptr, + pbFrames, nFrameLength); + hddLog( LOGE,"%s:" + "Action Pkt Cached successfully !!!", __func__); + } else { + hddLog( LOGE,"%s:" + "Frames are pending. dropping frame !!!", __func__); + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + return; + } + } + } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + + if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) && + (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) || + ((actionFrmType == WLAN_HDD_GO_NEG_RESP) && + (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING))) + { + hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ", + __func__); + hdd_sendActionCnf(pAdapter, TRUE); + } + } +#ifdef FEATURE_WLAN_TDLS + else if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP) + { + u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6]; +#ifdef WLAN_FEATURE_TDLS_DEBUG + hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + MAC_ADDR_ARRAY(mac),rxRssi); +#endif + wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi); + wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac); + } +#endif + } +#ifdef WLAN_FEATURE_TDLS_DEBUG + if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME) + { + actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1]; + if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] unknown[%d] <--- OTA", + actionFrmType); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] %s <--- OTA", + tdls_action_frame_type[actionFrmType]); + } + } +#endif + if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&& + (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) ) + { + sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); + } + } + + //Indicate Frame Over Normal Interface + hddLog( LOG1, FL("Indicate Frame over NL80211 Interface")); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, 0, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + cfg80211_rx_mgmt( pAdapter->dev, freq, 0, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#else + cfg80211_rx_mgmt( pAdapter->dev, freq, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#endif /* LINUX_VERSION_CODE */ +} + +/* + * ieee80211_add_rx_radiotap_header - add radiotap header + */ +static int hdd_wlan_add_rx_radiotap_hdr ( + struct sk_buff *skb, int rtap_len, int flag ) +{ + u8 rtap_temp[20] = {0}; + struct ieee80211_radiotap_header *rthdr; + unsigned char *pos; + u16 rx_flags = 0; + + rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]); + + /* radiotap header, set always present flags */ + rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | + (1 << IEEE80211_RADIOTAP_RX_FLAGS)); + rthdr->it_len = cpu_to_le16(rtap_len); + + pos = (unsigned char *) (rthdr + 1); + + /* the order of the following fields is important */ + + /* IEEE80211_RADIOTAP_FLAGS */ + *pos = 0; + pos++; + + /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */ + /* ensure 2 byte alignment for the 2 byte field as required */ + if ((pos - (u8 *)rthdr) & 1) + pos++; + put_unaligned_le16(rx_flags, pos); + pos += 2; + + // actually push the data + memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len); + + return 0; +} + +static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter, + hdd_cfg80211_state_t* cfgState, + tANI_BOOLEAN actionSendSuccess ) +{ + struct ieee80211_radiotap_header *rthdr; + unsigned char *pos; + struct sk_buff *skb = cfgState->skb; +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); +#endif + + /* 2 Byte for TX flags and 1 Byte for Retry count */ + u32 rtHdrLen = sizeof(*rthdr) + 3; + + u8 *data; + + /* We have to return skb with Data starting with MAC header. We have + * copied SKB data starting with MAC header to cfgState->buf. We will pull + * entire skb->len from skb and then we will push cfgState->buf to skb + * */ + if( NULL == skb_pull(skb, skb->len) ) + { + hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len); + kfree_skb(cfgState->skb); + return; + } + + data = skb_push( skb, cfgState->len ); + + if (data == NULL) + { + hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len); + kfree_skb( cfgState->skb ); + return; + } + + memcpy( data, cfgState->buf, cfgState->len ); + + /* send frame to monitor interfaces now */ + if( skb_headroom(skb) < rtHdrLen ) + { + hddLog( LOGE, FL("No headroom for rtap header")); + kfree_skb(cfgState->skb); + return; + } + + rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen ); + + memset( rthdr, 0, rtHdrLen ); + rthdr->it_len = cpu_to_le16( rtHdrLen ); + rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | + (1 << IEEE80211_RADIOTAP_DATA_RETRIES) + ); + + pos = (unsigned char *)( rthdr+1 ); + + // Fill TX flags + *pos = actionSendSuccess; + pos += 2; + + // Fill retry count + *pos = 0; + pos++; + + skb_set_mac_header( skb, 0 ); + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset( skb->cb, 0, sizeof( skb->cb ) ); +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION); +#endif + if (in_interrupt()) + netif_rx( skb ); + else + netif_rx_ni( skb ); + + /* Enable Queues which we have disabled earlier */ + netif_tx_start_all_queues( pAdapter->dev ); + +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_scan.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_scan.c new file mode 100644 index 0000000000000..5a14e14ecaa3a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_scan.c @@ -0,0 +1,1176 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_scan.c + + \brief WLAN Host Device Driver implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + + ==========================================================================*/ + /* To extract the Scan results */ + +/* Add a stream event */ + +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif + +#include +#include + + +#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" +#define WEXT_CSCAN_HEADER_SIZE 12 +#define WEXT_CSCAN_SSID_SECTION 'S' +#define WEXT_CSCAN_CHANNEL_SECTION 'C' +#define WEXT_CSCAN_NPROBE_SECTION 'N' +#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' +#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' +#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' +#define WEXT_CSCAN_TYPE_SECTION 'T' +#define WEXT_CSCAN_PENDING_SECTION 'O' +#define WEXT_CSCAN_TYPE_DEFAULT 0 +#define WEXT_CSCAN_TYPE_PASSIVE 1 +#define WEXT_CSCAN_PASV_DWELL_TIME 130 +#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250 +#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000 +#define WEXT_CSCAN_HOME_DWELL_TIME 130 +#define MAX_RATES 12 + +#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000 + +typedef struct hdd_scan_info{ + struct net_device *dev; + struct iw_request_info *info; + char *start; + char *end; +} hdd_scan_info_t, *hdd_scan_info_tp; + +static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate) +{ + + /** Slightly more sophisticated processing has to take place here. + Basic rates are rounded DOWN. HT rates are rounded UP.*/ + return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2); +} + + +static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event ) +{ + struct iw_event event; + + *last_event = *current_event; + vos_mem_zero(&event, sizeof (struct iw_event)); + event.cmd = cmd; + event.u.data.flags = 1; + event.u.data.length = length; + *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data); + + if(*last_event == *current_event) + { + /* no space to add event */ + hddLog( LOGE, "%s: no space left to add event", __func__); + return -E2BIG; /* Error code, may be E2BIG */ + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_GetWPARSNIEs() - + + This function extract the WPA/RSN IE from the Bss descriptor IEs fields + + \param - ieFields - Pointer to the Bss Descriptor IEs. + - ie_length - IE Length. + - last_event -Points to the last event. + - current_event - Points to the + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +/* Extract the WPA and/or RSN IEs */ +static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo ) +{ + v_U8_t eid, elen, *element; + v_U16_t tie_length=0; + + ENTER(); + + element = ieFields; + tie_length = ie_length; + + while( tie_length > 2 && element != NULL ) + { + eid = element[0]; + elen = element[1]; + + /*If element length is greater than total remaining ie length, + *break the loop*/ + if ((elen+2) > tie_length) + break; + + switch(eid) + { + case DOT11F_EID_WPA: + case DOT11F_EID_RSN: +#ifdef FEATURE_WLAN_WAPI + case DOT11F_EID_WAPI: +#endif + if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 ) + return -E2BIG; + break; + + default: + break; + } + + /* Next element */ + tie_length -= (2 + elen); + element += 2 + elen; + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_IndicateScanResult() - + + This function returns the scan results to the wpa_supplicant + + \param - scanInfo - Pointer to the scan info structure. + - descriptor - Pointer to the Bss Descriptor. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +#define MAX_CUSTOM_LEN 64 +static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tSirBssDescription *descriptor = &scan_result->BssDescriptor; + struct iw_event event; + char *current_event = scanInfo->start; + char *end = scanInfo->end; + char *last_event; + char *current_pad; + v_U16_t ie_length = 0; + v_U16_t capabilityInfo; + char *modestr; + int error; + char custom[MAX_CUSTOM_LEN]; + char *p; + + hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(descriptor->bssId)); + + error = 0; + last_event = current_event; + vos_mem_zero(&event, sizeof (event)); + + /* BSSID */ + event.cmd = SIOCGIWAP; + event.u.ap_addr.sa_family = ARPHRD_ETHER; + vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId, + sizeof (descriptor->bssId)); + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_ADDR_LEN); + + if (last_event == current_event) + { + /* no space to add event */ + /* Error code may be E2BIG */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWAP "); + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero(&event, sizeof (struct iw_event)); + + /* Protocol Name */ + event.cmd = SIOCGIWNAME; + + switch (descriptor->nwType) + { + case eSIR_11A_NW_TYPE: + modestr = "a"; + break; + case eSIR_11B_NW_TYPE: + modestr = "b"; + break; + case eSIR_11G_NW_TYPE: + modestr = "g"; + break; + case eSIR_11N_NW_TYPE: + modestr = "n"; + break; + default: + hddLog( LOGW, "%s: Unknown network type [%d]", + __func__, descriptor->nwType); + modestr = "?"; + break; + } + snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr); + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_CHAR_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); + /* Error code, may be E2BIG */ + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*Freq*/ + event.cmd = SIOCGIWFREQ; + + event.u.freq.m = descriptor->channelId; + event.u.freq.e = 0; + event.u.freq.i = 0; + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_FREQ_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWFREQ"); + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /* BSS Mode */ + event.cmd = SIOCGIWMODE; + + capabilityInfo = descriptor->capabilityInfo; + + if (SIR_MAC_GET_ESS(capabilityInfo)) + { + event.u.mode = IW_MODE_MASTER; + } + else if (SIR_MAC_GET_IBSS(capabilityInfo)) + { + event.u.mode = IW_MODE_ADHOC; + } + else + { + /* neither ESS or IBSS */ + event.u.mode = IW_MODE_AUTO; + } + + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_UINT_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); + return -E2BIG; + } + /* To extract SSID */ + ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); + + if (ie_length > 0) + { + /* dot11BeaconIEs is a large struct, so we make it static to + avoid stack overflow. This API is only invoked via ioctl, + so it is serialized by the kernel rtnl_lock and hence does + not need to be reentrant */ + static tDot11fBeaconIEs dot11BeaconIEs; + tDot11fIESSID *pDot11SSID; + tDot11fIESuppRates *pDot11SuppRates; + tDot11fIEExtSuppRates *pDot11ExtSuppRates; + tDot11fIEHTCaps *pDot11IEHTCaps; + int numBasicRates = 0; + int maxNumRates = 0; + + pDot11IEHTCaps = NULL; + + dot11fUnpackBeaconIEs ((tpAniSirGlobal) + hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs); + + pDot11SSID = &dot11BeaconIEs.SSID; + + + if (pDot11SSID->present ) { + last_event = current_event; + vos_mem_zero (&event, sizeof (struct iw_event)); + + event.cmd = SIOCGIWESSID; + event.u.data.flags = 1; + event.u.data.length = scan_result->ssId.length; + current_event = iwe_stream_add_point (scanInfo->info,current_event, end, + &event, (char *)scan_result->ssId.ssId); + + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); + return -E2BIG; + } + } + + if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) + { + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); + return -E2BIG; + } + + last_event = current_event; + current_pad = current_event + IW_EV_LCP_LEN; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*Rates*/ + event.cmd = SIOCGIWRATE; + + + pDot11SuppRates = &dot11BeaconIEs.SuppRates; + + if (pDot11SuppRates->present ) + { + int i; + + numBasicRates = pDot11SuppRates->num_rates; + for (i=0; inum_rates; i++) + { + if (0 != (pDot11SuppRates->rates[i] & 0x7F)) + { + event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( + &pDot11SuppRates->rates[i]); + + current_pad = iwe_stream_add_value (scanInfo->info,current_event, + current_pad, end, &event, IW_EV_PARAM_LEN); + } + } + + } + + pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates; + + if (pDot11ExtSuppRates->present ) + { + int i,no_of_rates; + maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates; + + /* Check to make sure the total number of rates + doesn't exceed IW_MAX_BITRATES */ + + maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES); + + if((maxNumRates - numBasicRates) > MAX_RATES) + { + no_of_rates = MAX_RATES; + hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates "); + } + else + { + no_of_rates = maxNumRates - numBasicRates; + } + for ( i=0; i< no_of_rates ; i++ ) + { + if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F)) + { + event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( + &pDot11ExtSuppRates->rates[i]); + + current_pad = iwe_stream_add_value (scanInfo->info,current_event, + current_pad, end, &event, IW_EV_PARAM_LEN); + } + } + } + + + if ((current_pad - current_event) >= IW_EV_LCP_LEN) + { + current_event = current_pad; + } + else + { + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWRATE"); + return -E2BIG; + } + } + + last_event = current_event; + vos_mem_zero (&event, sizeof (struct iw_event)); + + + event.cmd = SIOCGIWENCODE; + + if (SIR_MAC_GET_PRIVACY(capabilityInfo)) + { + event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + } + else + { + event.u.data.flags = IW_ENCODE_DISABLED; + } + event.u.data.length = 0; + + current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid); + + + if(last_event == current_event) + { /* no space to add event + Error code, may be E2BIG */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWENCODE"); + return -E2BIG; + } + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*RSSI*/ + event.cmd = IWEVQUAL; + event.u.qual.qual = descriptor->rssi; + event.u.qual.noise = descriptor->sinr; + + /*To keep the rssi icon of the connected AP in the scan window + *and the rssi icon of the wireless networks in sync */ + if (( eConnectionState_Associated == + pAdapter->sessionCtx.station.conn_info.connState ) && + ( VOS_TRUE == vos_mem_compare(descriptor->bssId, + pAdapter->sessionCtx.station.conn_info.bssId, + VOS_MAC_ADDR_SIZE))) + { + event.u.qual.level = pAdapter->rssi; + } + else + { + event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0); + } + + event.u.qual.updated = IW_QUAL_ALL_UPDATED; + + current_event = iwe_stream_add_event(scanInfo->info,current_event, + end, &event, IW_EV_QUAL_LEN); + + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVQUAL"); + return -E2BIG; + } + + + /* AGE */ + event.cmd = IWEVCUSTOM; + p = custom; + p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu", + vos_timer_get_system_ticks() - descriptor->nReceivedTime); + event.u.data.length = p - custom; + current_event = iwe_stream_add_point (scanInfo->info,current_event, end, + &event, custom); + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); + return -E2BIG; + } + + scanInfo->start = current_event; + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_ScanRequestCallback() - + + The sme module calls this callback function once it finish the scan request + and this function notifies the scan complete event to the wpa_supplicant. + + \param - halHandle - Pointer to the Hal Handle. + - pContext - Pointer to the data context. + - sessionId - Session identifier + - scanId - Scan ID. + - status - CSR Status. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U8 sessionId, tANI_U32 scanId, + eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + union iwreq_data wrqu; + int we_event; + char *msg; + + ENTER(); + + hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d," + " returned status = %d", __func__, halHandle, pContext, + (int) scanId, (int) status); + + /* if there is a scan request pending when the wlan driver is unloaded + we may be invoked as SME flushes its pending queue. If that is the + case, the underlying net_device may have already been destroyed, so + do some quick sanity before proceeding */ + if (pAdapter->dev != dev) + { + hddLog(LOGW, "%s: device mismatch %p vs %p", + __func__, pAdapter->dev, dev); + return eHAL_STATUS_SUCCESS; + } + + /* Check the scanId */ + if (pAdapter->scan_info.scanId != scanId) + { + hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d " + "scanId = %d ", __func__, (int) pAdapter->scan_info.scanId, + (int) scanId); + } + + /* Scan is no longer pending */ + pAdapter->scan_info.mScanPending = VOS_FALSE; + + // notify any applications that may be interested + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + + EXIT(); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + + return eHAL_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief iw_set_scan() - + + This function process the scan request from the wpa_supplicant + and set the scan request to the SME + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + struct iw_scan_req *scanReq = (struct iw_scan_req *)extra; + hdd_adapter_t *con_sap_adapter; + uint16_t con_dfs_ch; + + ENTER(); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); + +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if( VOS_TRUE == WLANBAP_AmpSessionOn() ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); + return eHAL_STATUS_SUCCESS; + } +#endif + /* Block All Scan during DFS operation and send null scan result */ + con_sap_adapter = hdd_get_con_sap_adapter(pAdapter); + if (con_sap_adapter) { + con_dfs_ch = con_sap_adapter->sessionCtx.ap.sapConfig.channel; + if (con_dfs_ch == AUTO_CHANNEL_SELECT) + con_dfs_ch = con_sap_adapter->sessionCtx.ap.operatingChannel; + + if (VOS_IS_DFS_CH(con_dfs_ch)) { + hddLog(LOGW, "%s:##In DFS Master mode. Scan aborted", __func__); + return -EOPNOTSUPP; + } + } + + + if(pAdapter->scan_info.mScanPending == TRUE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); + return eHAL_STATUS_SUCCESS; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return eHAL_STATUS_SUCCESS; + } + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + if (NULL != wrqu->data.pointer) + { + /* set scanType, active or passive */ + if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || + (eSIR_ACTIVE_SCAN == pHddCtx->ioctl_scan_mode)) + { + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else + { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + } + + /* set bssid using sockaddr from iw_scan_req */ + vos_mem_copy(scanRequest.bssid, + &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) ); + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + + if(scanReq->essid_len) { + scanRequest.SSIDs.numOfSSIDs = 1; + scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if(scanRequest.SSIDs.SSIDList) { + scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len; + vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len); + } + else + { + scanRequest.SSIDs.numOfSSIDs = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__); + VOS_ASSERT(0); + } + } + } + + /* set min and max channel time */ + scanRequest.minChnTime = scanReq->min_channel_time; + scanRequest.maxChnTime = scanReq->max_channel_time; + + } + else + { + if (pHddCtx->ioctl_scan_mode == eSIR_ACTIVE_SCAN) { + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } else { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + } + + vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff ); + + /* set min and max channel time to zero */ + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + } + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 0; + + scanRequest.ChannelInfo.ChannelList = NULL; + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + /* if previous genIE is not NULL, update ScanIE */ + if (0 != pwextBuf->genIE.length) + { + memset( &pAdapter->scan_info.scanAddIE, 0, sizeof(pAdapter->scan_info.scanAddIE) ); + memcpy( pAdapter->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, + pwextBuf->genIE.length ); + pAdapter->scan_info.scanAddIE.length = pwextBuf->genIE.length; + + pwextBuf->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata; + pwextBuf->roamProfile.nAddIEScanLength = pAdapter->scan_info.scanAddIE.length; + + /* clear previous genIE after use it */ + memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); + } + + /* push addIEScan in scanRequset if exist */ + if (pAdapter->scan_info.scanAddIE.addIEdata && + pAdapter->scan_info.scanAddIE.length) + { + scanRequest.uIEFieldLen = pAdapter->scan_info.scanAddIE.length; + scanRequest.pIEField = pAdapter->scan_info.scanAddIE.addIEdata; + } + + status = sme_ScanRequest((WLAN_HDD_GET_CTX(pAdapter))->hHal, + pAdapter->sessionId, &scanRequest, &scanId, + &hdd_ScanRequestCallback, dev); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status); + goto error; + } + + pAdapter->scan_info.mScanPending = TRUE; + + pAdapter->scan_info.scanId = scanId; + +error: + if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len)) + vos_mem_free(scanRequest.SSIDs.SSIDList); + + EXIT(); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + return status; +} + +/**--------------------------------------------------------------------------- + + \brief iw_get_scan() - + + This function returns the scan results to the wpa_supplicant + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +int iw_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tCsrScanResultInfo *pScanResult; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_scan_info_t scanInfo; + tScanResultHandle pResult; + int i = 0; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!", + __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA); + ENTER(); + + if (TRUE == pAdapter->scan_info.mScanPending) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); + return -EAGAIN; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return -EAGAIN; + } + + scanInfo.dev = dev; + scanInfo.start = extra; + scanInfo.info = info; + + if (0 == wrqu->data.length) + { + scanInfo.end = extra + IW_SCAN_MAX_DATA; + } + else + { + scanInfo.end = extra + wrqu->data.length; + } + + status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult); + + if (NULL == pResult) + { + // no scan results + hddLog(LOG1,"iw_get_scan: NULL Scan Result "); + return 0; + } + + pScanResult = sme_ScanResultGetFirst(hHal, pResult); + + while (pScanResult) + { + status = hdd_IndicateScanResult(&scanInfo, pScanResult); + if (0 != status) + { + break; + } + i++; + pScanResult = sme_ScanResultGetNext(hHal, pResult); + } + + sme_ScanResultPurge(hHal, pResult); + + EXIT(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i); + return status; +} + +#if 0 +static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + union iwreq_data wrqu; + int we_event; + char *msg; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + ENTER(); + + hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d," + " returned status = %d", __func__, halHandle, pContext, + (int) scanId, (int) status); + + /* Check the scanId */ + if (pwextBuf->scanId != scanId) + { + hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d " + "scanId = %d ", __func__, (int) pwextBuf->scanId, + (int) scanId); + } + + /* Scan is no longer pending */ + pwextBuf->mScanPending = VOS_FALSE; + + // notify any applications that may be interested + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + + vos_status = vos_event_set(&pwextBuf->vosevent); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!")); + return VOS_STATUS_E_FAILURE; + } + + EXIT(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + + return eHAL_STATUS_SUCCESS; +} +#endif + +int iw_set_cscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U8_t channelIdx; + + ENTER(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); + +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if( VOS_TRUE == WLANBAP_AmpSessionOn() ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); + return eHAL_STATUS_SUCCESS; + } +#endif + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return eHAL_STATUS_SUCCESS; + } + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + if (NULL != wrqu->data.pointer) + { + char *str_ptr = NULL; + tCsrSSIDInfo *SsidInfo = NULL; + int num_ssid = 0; + int i, j, ssid_start; + hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP; + + str_ptr = extra; + + i = WEXT_CSCAN_HEADER_SIZE; + + if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] ) + { + scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i]; + ++i; + } + pAdapter->scan_info.scan_pending_option = scanPendingOption; + + if(pAdapter->scan_info.mScanPending == TRUE) + { + hddLog(LOG1,"%s: mScanPending is TRUE",__func__); + /* If any scan is pending, just giveup this scan request */ + if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption) + { + pAdapter->scan_info.waitScanResult = FALSE; + return eHAL_STATUS_SUCCESS; + } + /* If any scan pending, wait till finish current scan, + and try this scan request when previous scan finish */ + else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption) + { + pAdapter->scan_info.waitScanResult = TRUE; + vos_event_reset(&pAdapter->scan_info.scan_finished_event); + if(vos_wait_single_event(&pAdapter->scan_info.scan_finished_event, + WEXT_CSCAN_SCAN_DONE_WAIT_TIME)) + { + hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__); + return eHAL_STATUS_SUCCESS; + } + } + /* Piggyback previous scan result */ + else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption) + { + pAdapter->scan_info.waitScanResult = TRUE; + return eHAL_STATUS_SUCCESS; + } + } + pAdapter->scan_info.waitScanResult = FALSE; + + /* Check for scan IE */ + while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] ) + { + /* ssid_len */ + if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION) + { + /* total number of ssid's */ + num_ssid++; + /* increment length filed */ + i += str_ptr[i] + 1; + } + /* i should be saved and it will be pointing to 'C' */ + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid); + if( num_ssid ) + { + /* To be fixed in SME and PE: override the number of ssid with 1, + * as SME and PE does not handle multiple SSID in scan request + * */ + scanRequest.SSIDs.numOfSSIDs = num_ssid; + /* Allocate num_ssid tCsrSSIDInfo structure */ + SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo)); + if(NULL == scanRequest.SSIDs.SSIDList) { + hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer"); + return -ENOMEM; + } + + /* copy all the ssid's and their length */ + ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */ + for(j = 0; j < num_ssid; j++) { + if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){ + scanRequest.SSIDs.numOfSSIDs -= 1; + } else{ + /* get the ssid length */ + SsidInfo->SSID.length = str_ptr[ssid_start++]; + vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId); + } + /* skipping length */ + ssid_start += str_ptr[ssid_start - 1] + 1; + /* Store next ssid info */ + SsidInfo++; + } + } + + /* Check for Channel IE */ + if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i]) + { + if( str_ptr[++i] == 0 ) + { + scanRequest.ChannelInfo.numOfChannels = 0; + scanRequest.ChannelInfo.ChannelList = NULL; + i++; + } + else { + + /* increment the counter */ + scanRequest.ChannelInfo.numOfChannels = str_ptr[i++]; + /* store temp channel list */ + /* SME expects 1 byte channel content */ + scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t)); + if(NULL == scanRequest.ChannelInfo.ChannelList) + { + hddLog(LOGE, "memory alloc failed for channel list creation"); + status = -ENOMEM; + goto exit_point; + } + + for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++) + { + /* SCAN request from upper layer has 2 bytes channel */ + scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i]; + i += sizeof(v_U16_t); + } + } + } + + /* Set default */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + + /* Now i is pointing to passive dwell dwell time */ + /* 'P',min dwell time, max dwell time */ + /* next two offsets contain min and max channel time */ + if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) ) + { + /* No SSID specified, num_ssid == 0, then start passive scan */ + if (!num_ssid || (eSIR_PASSIVE_SCAN == pAdapter->scan_info.scan_mode)) + { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time; + scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time; + i++; + } + else + { + i += 3; + } + } + + /* H indicates active channel time */ + if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) ) + { + if (num_ssid || (eSIR_ACTIVE_SCAN == pAdapter->scan_info.scan_mode)) + { + scanRequest.scanType = eSIR_ACTIVE_SCAN; + scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time; + scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time; + i++; + } + else + { + i +=3; + } + } + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + pAdapter->scan_info.mScanPending = TRUE; + + /* if previous genIE is not NULL, update ScanIE */ + if(0 != pwextBuf->genIE.length) + { + memset( &pAdapter->scan_info.scanAddIE, 0, sizeof(pAdapter->scan_info.scanAddIE) ); + memcpy( pAdapter->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, + pwextBuf->genIE.length ); + pAdapter->scan_info.scanAddIE.length = pwextBuf->genIE.length; + + pwextBuf->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata; + pwextBuf->roamProfile.nAddIEScanLength = pAdapter->scan_info.scanAddIE.length; + + /* clear previous genIE after use it */ + memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); + } + + /* push addIEScan in scanRequset if exist */ + if (pAdapter->scan_info.scanAddIE.addIEdata && + pAdapter->scan_info.scanAddIE.length) + { + scanRequest.uIEFieldLen = pAdapter->scan_info.scanAddIE.length; + scanRequest.pIEField = pAdapter->scan_info.scanAddIE.addIEdata; + } + + status = sme_ScanRequest((WLAN_HDD_GET_CTX(pAdapter))->hHal, + pAdapter->sessionId, &scanRequest, &scanId, + &hdd_ScanRequestCallback, dev); + if( !HAL_STATUS_SUCCESS(status) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: SME scan fail status %d !!!",__func__, status); + pAdapter->scan_info.mScanPending = FALSE; + status = -EINVAL; + goto exit_point; + } + + pAdapter->scan_info.scanId = scanId; + + } //end of data->pointer + else { + status = -1; + } + +exit_point: + + /* free ssidlist */ + if (scanRequest.SSIDs.SSIDList) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); + } + /* free the channel list */ + if(scanRequest.ChannelInfo.ChannelList) + { + vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList); + } + + EXIT(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + return status; +} + +/* Abort any MAC scan if in progress */ +void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId, + eCsrAbortReason reason) +{ + sme_AbortMacScan(pHddCtx->hHal, sessionId, reason); +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_softap_tx_rx.c new file mode 100644 index 0000000000000..22586f080783c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_softap_tx_rx.c @@ -0,0 +1,1680 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**=========================================================================== + + \file wlan_hdd_softap_tx_rx.c + + \brief Linux HDD Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#ifdef IPA_OFFLOAD +#include +#endif +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function definitions and documentation + -------------------------------------------------------------------------*/ +#if 0 +static void hdd_softap_dump_sk_buff(struct sk_buff * skb) +{ + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p ", __func__, skb->head); + //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p ", __func__, skb->data); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p ", __func__, skb->tail); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p ", __func__, skb->end); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d ", __func__, skb->len); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d ", __func__, skb->data_len); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], + skb->data[5], skb->data[6], skb->data[7]); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12], + skb->data[13], skb->data[14], skb->data[15]); +} +#endif + +extern void hdd_set_wlan_suspend_mode(bool suspend); + +/**============================================================================ + @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + v_U8_t STAId = 0; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + spin_lock_bh( &pAdapter->staInfo_lock ); + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + if (FALSE == pAdapter->aStaInfo[STAId].isUsed) + { + continue; + } + + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor); + + if (VOS_STATUS_E_EMPTY != status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + + //current list is empty + break; + } + pAdapter->aStaInfo[STAId].txSuspended[i] = VOS_FALSE; + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock); + } + pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE; + } + + spin_unlock_bh( &pAdapter->staInfo_lock ); + + return status; +} + +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_softap_tx_resume_timer_expired_handler() - Resume OS TX Q timer + expired handler for SAP and P2P GO interface. + If Blocked OS Q is not resumed during timeout period, to prevent + permanent stall, resume OS Q forcefully for SAP and P2P GO interface. + + @param adapter_context : [in] pointer to vdev adapter + + @return : NONE + ===========================================================================*/ +void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context; + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: INV ARG", __func__); + /* INVALID ARG */ + return; + } + + netif_tx_wake_all_queues(pAdapter->dev); + return; +} + +/**============================================================================ + @brief hdd_softap_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev adapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_softap_tx_resume_cb(void *adapter_context, + v_BOOL_t tx_resume) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context; + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: INV ARG", __func__); + /* INVALID ARG */ + return; + } + + /* Resume TX */ + if (VOS_TRUE == tx_resume) + { + if(VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) + { + vos_timer_stop(&pAdapter->tx_flow_control_timer); + } + + netif_tx_wake_all_queues(pAdapter->dev); + } +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + else if (VOS_FALSE == tx_resume) /* Pause TX */ + { + netif_tx_stop_all_queues(pAdapter->dev); + if (VOS_TIMER_STATE_STOPPED == + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) + { + VOS_STATUS status; + status = vos_timer_start(&pAdapter->tx_flow_control_timer, + WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + if ( !VOS_IS_STATUS_SUCCESS(status) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start tx_flow_control_timer", __func__); + } + } + } +#endif + + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + +/**============================================================================ + @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS + for transmitting packets. + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NETDEV_TX_OK + ===========================================================================*/ +int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + WLANTL_ACEnumType ac = WLANTL_AC_BE; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_MACADDR_t *pDestMacAddress; + v_U8_t STAId; +#ifdef QCA_PKT_PROTO_TRACE + hdd_context_t *hddCtxt = (hdd_context_t *)pAdapter->pHddCtx; + v_U8_t proto_type = 0; +#endif /* QCA_PKT_PROTO_TRACE */ + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + /* Prevent this function to be called during SSR since TL context may + not be reinitialized at this time which will lead crash. */ + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: LOGP in Progress. Ignore!!!", __func__); + goto drop_pkt; + } + + /* + * If the device is operating on a DFS Channel + * then check if SAP is in CAC WAIT state and + * drop the packets. In CAC WAIT state device + * is expected not to transmit any frames. + * SAP starts Tx only after the BSS START is + * done. + */ + if (pHddApCtx->dfs_cac_block_tx) + { + goto drop_pkt; + } + + pDestMacAddress = (v_MACADDR_t*)skb->data; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + if (vos_is_macaddr_broadcast( pDestMacAddress ) || + vos_is_macaddr_group(pDestMacAddress)) + { + // The BC/MC station ID is assigned during BSS starting phase. + // SAP will return the station ID used for BC/MC traffic. + STAId = pHddApCtx->uBCStaId; + } + else + { + STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1); + if (STAId == HDD_WLAN_INVALID_STA_ID) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to find right station", __func__); + goto drop_pkt; + } + else if (FALSE == pAdapter->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: STA %d is unregistered", __func__, STAId); + goto drop_pkt; + } + + if ( (WLANTL_STA_CONNECTED != pAdapter->aStaInfo[STAId].tlSTAState) && + (WLANTL_STA_AUTHENTICATED != pAdapter->aStaInfo[STAId].tlSTAState) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Station not connected yet", __func__); + goto drop_pkt; + } + else if(WLANTL_STA_CONNECTED == pAdapter->aStaInfo[STAId].tlSTAState) + { + if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: NON-EAPOL packet in non-Authenticated state", __func__); + goto drop_pkt; + } + } + } + +#ifdef QCA_LL_TX_FLOW_CT + if (VOS_FALSE == + WLANTL_GetTxResource((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pAdapter->sessionId, + pAdapter->tx_flow_low_watermark, + pAdapter->tx_flow_high_watermark_offset)) { + if ((pAdapter->tx_flow_timer_initialized == TRUE) && + (VOS_TIMER_STATE_STOPPED == + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer))) { + netif_tx_stop_all_queues(dev); + vos_timer_start(&pAdapter->tx_flow_control_timer, + WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + } + } +#endif /* QCA_LL_TX_FLOW_CT */ + + //Get TL AC corresponding to Qdisc queue index/AC. + ac = hdd_QdiscAcToTlAC[skb->queue_mapping]; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; + +#if defined (IPA_OFFLOAD) + if(!(NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID)) { +#endif + // Check if the buffer has enough header room + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) + goto drop_pkt; + + if (skb_headroom(skb) < dev->hard_header_len) { + struct sk_buff *tmp; + tmp = skb; + skb = skb_realloc_headroom(tmp, dev->hard_header_len); + dev_kfree_skb(tmp); + if (!skb) + goto drop_pkt; + } +#if defined (IPA_OFFLOAD) + } +#endif + + +#ifdef QCA_PKT_PROTO_TRACE + if ((hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || + (hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) + { + /* Proto Trace enabled */ + proto_type = vos_pkt_get_proto_type(skb, + hddCtxt->cfg_ini->gEnableDebugLog, 0); + if (VOS_PKT_TRAC_TYPE_EAPOL & proto_type) + { + vos_pkt_trace_buf_update("HA:T:EPL"); + } + else if (VOS_PKT_TRAC_TYPE_DHCP & proto_type) + { + vos_pkt_trace_buf_update("HA:T:DHC"); + } + } +#endif /* QCA_PKT_PROTO_TRACE */ + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count; + + if (WLANTL_SendSTA_DataFrame((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, skb +#ifdef QCA_PKT_PROTO_TRACE + , proto_type +#endif /* QCA_PKT_PROTO_TRACE */ + ) != NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to send packet to txrx for staid:%d", + __func__, STAId); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + goto drop_pkt; + } + + dev->trans_start = jiffies; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__); + + return NETDEV_TX_OK; + +drop_pkt: + + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + + return NETDEV_TX_OK; +} +/**============================================================================ + @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations. + + @param skb : [in] pointer to packet (sk_buff) + @param dev : [in] pointer to Libra network device + @param STAId : [in] Station Id of Destination Station + @param up : [in] User Priority + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued successfully + ===========================================================================*/ +VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb, + struct net_device *dev, + v_U8_t STAId, + v_U8_t up) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + skb_list_node_t *pktNode = NULL; + v_SIZE_t pktListSize = 0; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + v_U8_t ac; + vos_list_node_t *anchor = NULL; + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + spin_lock_bh( &pAdapter->staInfo_lock ); + if ( FALSE == pAdapter->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: STA %d is unregistered", __func__, STAId ); + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + + /* If the QoS is not enabled on the receiving station, then send it with BE priority */ + if ( !pAdapter->aStaInfo[STAId].isQosEnabled ) + up = SME_QOS_WMM_UP_BE; + + ac = hddWmmUpToAcMap[up]; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Classified as ac %d up %d", __func__, ac, up); + + skb->queue_mapping = hddLinuxUpToAcMap[up]; + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + //Stick the User Priority inside this node + pktNode->userPriority = up; + + INIT_LIST_HEAD(&pktNode->anchor); + + spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize); + if(pAdapter->aStaInfo[STAId].txSuspended[ac] || + pktListSize >= pAdapter->aTxQueueLimit[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize); + /* TODO:Rx Flowchart should be triggered here to SUPEND SSC on RX side. + * SUSPEND should be done based on Threshold. RESUME would be + * triggered in fetch cbk after recovery. + */ + kfree_skb(skb); + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize ); + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s:Insert Tx queue failed. Pkt dropped", __func__); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + ++pAdapter->stats.tx_dropped; + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac]; + + if (1 == pktListSize) + { + //Let TL know we have a packet to send for this AC + //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__); + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to signal TL for AC=%d STAId =%d", + __func__, ac, STAId ); + + //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle + //as we are in a soft irq context. Also it must be the same packet that we just allocated. + spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor); + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + } + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__); + +xmit_end: + spin_unlock_bh( &pAdapter->staInfo_lock ); + return status; +} + +/** + * __hdd_softap_tx_timeout() - softap tx timeout + * @dev: pointer to net_device + * + * Function called by OS if there is any timeout during transmission. + * Since HDD simply enqueues packet and returns control to OS right away, + * this would never be invoked. + * + * Return: none + */ +static void __hdd_softap_tx_timeout(struct net_device *dev) +{ + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred", __func__); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (hdd_ctx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: LOGP in Progress. Ignore!!!", __func__); + return; + } + + /* + * Getting here implies we disabled the TX queues for too long. Queues are + * disabled either because of disassociation or low resource scenarios. In + * case of disassociation it is ok to ignore this. But if associated, we have + * do possible recovery here. + */ +} + +/** + * hdd_softap_tx_timeout() - SSR wrapper for __hdd_softap_tx_timeout + * @dev: pointer to net_device + * + * Return: none + */ +void hdd_softap_tx_timeout(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_softap_tx_timeout(dev); + vos_ssr_unprotect(__func__); +} + +/**============================================================================ + @brief hdd_softap_stats() - Function registered with the Linux OS for + device TX/RX statistic + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +struct net_device_stats* hdd_softap_stats(struct net_device *dev) +{ + hdd_adapter_t* priv = netdev_priv(dev); + return &priv->stats; +} + + +/**============================================================================ + @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + v_SIZE_t size = 0; + + v_U8_t STAId = 0; + + v_U8_t pACWeights[] = { + HDD_SOFTAP_BK_WEIGHT_DEFAULT, + HDD_SOFTAP_BE_WEIGHT_DEFAULT, + HDD_SOFTAP_VI_WEIGHT_DEFAULT, + HDD_SOFTAP_VO_WEIGHT_DEFAULT + }; + + pAdapter->isVosOutOfResource = VOS_FALSE; + pAdapter->isVosLowResource = VOS_FALSE; + + vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats)); + + while (++i != NUM_TX_QUEUES) + hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + + /* Initial HDD buffer control / flow control fields*/ + vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size); + + pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN; + + spin_lock_init( &pAdapter->staInfo_lock ); + + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + } + + /* Update the AC weights suitable for SoftAP mode of operation */ + WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights); + + return status; +} + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = hdd_softap_flush_tx_queues(pAdapter); + + return status; +} + +/**============================================================================ + @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : void + ===========================================================================*/ +static void hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId ) +{ + v_U8_t i = -1; + + hdd_list_node_t *anchor = NULL; + + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + if (FALSE == pAdapter->aStaInfo[STAId].isUsed) + return; + + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + if (VOS_STATUS_E_EMPTY != + hdd_list_remove_front(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], + &anchor)) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + + //current list is empty + break; + } + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock); + } + + return; +} + +/**============================================================================ + @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @param pmacAddrSTA : [in] pointer to the MAC address of the station + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA) +{ + v_U8_t i = 0; + spin_lock_bh( &pAdapter->staInfo_lock ); + if (pAdapter->aStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Reinit station %d", __func__, STAId ); + spin_unlock_bh( &pAdapter->staInfo_lock ); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + + pAdapter->aStaInfo[STAId].isUsed = TRUE; + pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE; + vos_copy_macaddr( &pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA); + + spin_unlock_bh( &pAdapter->staInfo_lock ); + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a station in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t ac; + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + v_U8_t tlAC; + hdd_hostapd_state_t *pHostapdState; + v_U8_t i; + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + spin_lock_bh( &pAdapter->staInfo_lock ); + if (FALSE == pAdapter->aStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Deinit station not inited %d", __func__, STAId ); + spin_unlock_bh( &pAdapter->staInfo_lock ); + return VOS_STATUS_E_FAILURE; + } + + hdd_softap_flush_tx_queues_sta(pAdapter, STAId); + + pAdapter->aStaInfo[STAId].isUsed = FALSE; + pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE; + + /* if this STA had any of its WMM TX queues suspended, then the + associated queue on the network interface was disabled. check + to see if that is the case, in which case we need to re-enable + the interface queue. but we only do this if the BSS is running + since, if the BSS is stopped, all of the interfaces have been + stopped and should not be re-enabled */ + + if (BSS_START == pHostapdState->bssState) + { + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + tlAC = hdd_QdiscAcToTlAC[ac]; + txSuspended[ac] = pAdapter->aStaInfo[STAId].txSuspended[tlAC]; + } + } + vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t)); + + /* re-init spin lock, since netdev can still open adapter until + * driver gets unloaded + */ + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], + HDD_TX_QUEUE_MAX_LEN); + } + + if (BSS_START == pHostapdState->bssState) + { + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + if (txSuspended[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + netif_wake_subqueue(pAdapter->dev, ac); + } + } + } + + spin_unlock_bh( &pAdapter->staInfo_lock ); + return status; +} + +/**============================================================================ + @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter ) +{ + return hdd_softap_flush_tx_queues(pAdapter); +} + +/**============================================================================ + @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the bus + successfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = NULL; + void* pOsPkt = NULL; + + if( ( NULL == vosContext ) || ( NULL == pVosPacket ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE ); + if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt)) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + //Get the Adapter context. + pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev); + if(pAdapter == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txCompleted; + } + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + status = vos_pkt_return_packet( pVosPacket ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Could not return VOS packet to the pool", __func__); + } + + return status; +} + + +/**============================================================================ + @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ac : [in] access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ac, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + vos_pkt_t *pVosPacket = NULL; + v_MACADDR_t* pDestMacAddress = NULL; + v_TIME_t timestamp; + v_SIZE_t size = 0; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + hdd_context_t *pHddCtx = NULL; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pStaId ) || + ( NULL == ppVosPacket ) || + ( NULL == pPktMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null Params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + STAId = *pStaId; + if (STAId >= WLAN_MAX_STA_COUNT) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid STAId %d passed by TL", __func__, STAId); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[STAId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + if (FALSE == pAdapter->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Unregistered STAId %d passed by TL", __func__, STAId); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetched; + + *ppVosPacket = NULL; + + //Make sure the AC being asked for is sane + if( ac > WLANTL_MAX_AC || ac < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d passed by TL", __func__, ac); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac]; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: AC %d passed by TL", __func__, ac); + + //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources + //This simplifies the locking and unlocking of Tx queue + status = vos_pkt_wrap_data_packet( &pVosPacket, + VOS_PKT_TYPE_TX_802_3_DATA, + NULL, //OS Pkt is not being passed + hdd_softap_tx_low_resource_cbk, + pAdapter ); + + if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES) + { + //Remember VOS is in a low resource situation + pAdapter->isVosOutOfResource = VOS_TRUE; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: VOSS in Low Resource scenario", __func__); + //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty. + return VOS_STATUS_E_FAILURE; + } + + /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC + as the other branch does. + */ + spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &size); + + if (0 == size) + { + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_EMPTY; + } + + status = hdd_list_remove_front( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: AC %d has packets pending", __func__, ac); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error in de-queuing skb from Tx queue status = %d", + __func__, status ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + + //Attach skb to VOS packet. + status = vos_pkt_set_os_packet( pVosPacket, skb ); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error attaching skb", __func__); + vos_pkt_return_packet(pVosPacket); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Just being paranoid. To be removed later + if(pVosPacket == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS packet returned by VOSS is NULL", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Return VOS packet to TL; + *ppVosPacket = pVosPacket; + + //Fill out the meta information needed by TL + //FIXME This timestamp is really the time stamp of wrap_data_packet + vos_pkt_get_timestamp( pVosPacket, ×tamp ); + pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp; + if ( 1 < size ) + { + pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send + } + else + { + pPktMetaInfo->bMorePackets = 0; + } + + pPktMetaInfo->ucIsEapol = 0; + + if(pAdapter->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED) + { + if (TRUE == hdd_IsEAPOLPacket( pVosPacket )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOS packet is EAPOL packet", __func__); + pPktMetaInfo->ucIsEapol = 1; + } + } + /* xg: @@@@: temporarily disable these. will revisit later */ + { + pPktMetaInfo->ucUP = pktNode->userPriority; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + } + + pPktMetaInfo->ucType = 0; //FIXME Don't know what this is + //Extract the destination address from ethernet frame + pDestMacAddress = (v_MACADDR_t*)skb->data; + + // we need 802.3 to 802.11 frame translation + // (note that Bcast/Mcast will be translated in SW, unicast in HW) + pPktMetaInfo->ucDisableFrmXtl = 0; + pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0; + pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0; + + if ( (pAdapter->aStaInfo[STAId].txSuspended[ac]) && + (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE; + netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb)); + } + + // We're giving the packet to TL so consider it transmitted from + // a statistics perspective. We account for it here instead of + // when the packet is returned for two reasons. First, TL will + // manipulate the skb to the point where the len field is not + // accurate, leading to inaccurate byte counts if we account for + // it later. Second, TL does not provide any feedback as to + // whether or not the packet was successfully sent over the air, + // so the packet counts will be the same regardless of where we + // account for them + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac]; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Valid VOS PKT returned to TL", __func__); + + return status; +} + + +/**============================================================================ + @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ) +{ + VOS_STATUS status; + v_SINT_t i = 0; + v_SIZE_t size = 0; + hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + + if ((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + hddLog(LOGE, FL("Invalid adapter %p"), pAdapter); + return VOS_STATUS_E_FAILURE; + } + + //Return the packet to VOS. We just needed to know that VOS is out of low resource + //situation. Here we will only signal TL that there is a pending data for a STA. + //VOS packet will be requested (if needed) when TL comes back to fetch data. + vos_pkt_return_packet( pVosPacket ); + + pAdapter->isVosOutOfResource = VOS_FALSE; + + // Indicate to TL that there is pending data if a queue is non empty. + // This Code wasnt included in earlier version which resulted in + // Traffic stalling + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + if ((pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) || + (pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED)) + { + for( i=NUM_TX_QUEUES-1; i>=0; --i ) + { + size = 0; + hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &size); + if ( size > 0 ) + { + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, + (WLANTL_ACEnumType)i ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure in indicating pkt to TL for ac=%d", __func__,i); + } + } + } + } + } + return VOS_STATUS_SUCCESS; +} + + + +/**============================================================================ + @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when one or more packets were + received for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param rxBuf : [in] pointer to rx adf_nbuf + @param staId : [in] Station Id (Address 1 Index) + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_rx_packet_cbk(v_VOID_t *vosContext, + adf_nbuf_t rxBuf, v_U8_t staId) +{ + hdd_adapter_t *pAdapter = NULL; + int rxstat; + struct sk_buff *skb = NULL; + hdd_context_t *pHddCtx = NULL; +#ifdef QCA_PKT_PROTO_TRACE + v_U8_t proto_type; +#endif /* QCA_PKT_PROTO_TRACE */ + struct sk_buff *skb_next; + + //Sanity check on inputs + if ((NULL == vosContext) || (NULL == rxBuf)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[staId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + hddLog(LOGE, FL("invalid adapter or adapter has invalid magic")); + return VOS_STATUS_E_FAILURE; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "Magic cookie(%x) for adapter sanity verification is invalid", + pAdapter->magic); + return VOS_STATUS_E_FAILURE; + } + + if (!pAdapter->dev) { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "Invalid DEV(NULL) Drop packets"); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxChains; + + // walk the chain until all are processed + skb = (struct sk_buff *) rxBuf; + + while (NULL != skb) { + skb_next = skb->next; + skb->dev = pAdapter->dev; + + ++pAdapter->hdd_stats.hddTxRxStats.rxPackets; + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += skb->len; + +#ifdef QCA_PKT_PROTO_TRACE + if ((pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog, 0); + if (VOS_PKT_TRAC_TYPE_EAPOL & proto_type) + vos_pkt_trace_buf_update("HA:R:EPL"); + else if (VOS_PKT_TRAC_TYPE_DHCP & proto_type) + vos_pkt_trace_buf_update("HA:R:DHC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: send one packet to kernel", __func__); + + skb->protocol = eth_type_trans(skb, skb->dev); + + /* + * If this is not a last packet on the chain + * Just put packet into backlog queue, not scheduling RX sirq + */ + if (skb->next) { + rxstat = netif_rx(skb); + } else { +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION); +#endif + /* + * This is the last packet on the chain + * Scheduling rx sirq + */ + rxstat = netif_rx_ni(skb); + } + + if (NET_RX_SUCCESS == rxstat) + ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered; + else + ++pAdapter->hdd_stats.hddTxRxStats.rxRefused; + + skb = skb_next; + } + pAdapter->dev->last_rx = jiffies; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx; + v_U8_t i; + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_INVAL; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + return VOS_STATUS_E_INVAL; + } + + pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); + //Clear station in TL and then update HDD data structures. This helps + //to block RX frames from other station to this station. + vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + staId, vosStatus, vosStatus ); + } + + if (pAdapter->aStaInfo[staId].isUsed) { + spin_lock_bh( &pAdapter->staInfo_lock ); + vos_mem_zero(&pAdapter->aStaInfo[staId], sizeof(hdd_station_info_t)); + + /* re-init spin lock, since netdev can still open adapter until + * driver gets unloaded + */ + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pAdapter->aStaInfo[staId].wmm_tx_queue[i], + HDD_TX_QUEUE_MAX_LEN); + } + spin_unlock_bh( &pAdapter->staInfo_lock ); + } + pHddCtx->sta_to_adapter[staId] = NULL; + + return( vosStatus ); +} + +VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter, + v_BOOL_t fAuthRequired, + v_BOOL_t fPrivacyBit, + v_U8_t staId, + v_U8_t ucastSig, + v_U8_t bcastSig, + v_MACADDR_t *pPeerMacAddress, + v_BOOL_t fWmmEnabled ) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + hdd_context_t *pHddCtx = pAdapter->pHddCtx; + hdd_adapter_t *pmonAdapter = NULL; + + //eCsrEncryptionType connectedCipherAlgo; + //v_BOOL_t fConnected; + + /* + * Clean up old entry if it is not cleaned up properly + */ + if ( pAdapter->aStaInfo[staId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "clean up old entry for STA %d", staId); + hdd_softap_DeregisterSTA( pAdapter, staId ); + } + + /* Get the Station ID from the one saved during the association */ + + staDesc.ucSTAId = staId; + + + /*Save the pAdapter Pointer for this staId*/ + pHddCtx->sta_to_adapter[staId] = pAdapter; + + staDesc.wSTAType = WLAN_STA_SOFTAP; + + vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) ); + vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 ); + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "register station"); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "station mac " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes)); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "BSSIDforIBSS " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes)); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "SOFTAP SELFMAC " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes)); + + vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress); + + staDesc.ucQosEnabled = fWmmEnabled; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "HDD SOFTAP register TL QoS_enabled=%d", + staDesc.ucQosEnabled ); + + staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ; + + + // For PRIMA UMA frame translation is not enable yet. + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + + // Initialize signatures and state + staDesc.ucUcastSig = ucastSig; + staDesc.ucBcastSig = bcastSig; + staDesc.ucInitState = fAuthRequired ? + WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED; + + staDesc.ucIsReplayCheckValid = VOS_FALSE; + + // Register the Station with TL... + /* Incase Micro controller data path offload enabled, + * All the traffic routed to WLAN host driver, do not need to + * route IPA. It should be routed kernel network stack */ +#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + if (hdd_ipa_is_enabled(pHddCtx)) + vosStatus = WLANTL_RegisterSTAClient( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + hdd_ipa_process_rxt, + hdd_softap_tx_complete_cbk, + hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 ); + else +#endif + vosStatus = WLANTL_RegisterSTAClient( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + hdd_softap_rx_packet_cbk, + hdd_softap_tx_complete_cbk, + hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + vosStatus, vosStatus ); + return vosStatus; + } + + //Timer value should be in milliseconds + if ( pHddCtx->cfg_ini->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + pHddCtx->cfg_ini->trafficMntrTmrForSplitScan); + } + + // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver, + // then go to 'authenticated'. For all other authentication types (those that do + // not require upper layer authentication) we can put TL directly into 'authenticated' + // state. + + //VOS_ASSERT( fConnected ); + pAdapter->aStaInfo[staId].ucSTAId = staId; + pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled; + + if ( !fAuthRequired ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", + pAdapter->aStaInfo[staId].ucSTAId ); + + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED, VOS_FALSE); + + pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED; + pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE; + } + else + { + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pAdapter->aStaInfo[staId].ucSTAId ); + + vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId, + WLANTL_STA_CONNECTED, VOS_FALSE); + pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED; + + pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE; + + } + pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx); + if(pmonAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH, + "Turn on Monitor the carrier"); + netif_carrier_on(pmonAdapter->dev); + //Enable Tx queue + netif_tx_start_all_queues(pmonAdapter->dev); + } + netif_carrier_on(pAdapter->dev); + //Enable Tx queue + netif_tx_start_all_queues(pAdapter->dev); + + return( vosStatus ); +} + +VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + hdd_ap_ctx_t *pHddApCtx; + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + + pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter; +#ifdef WLAN_FEATURE_MBSSID + pHddCtx->sta_to_adapter[pHddApCtx->uBCStaId] = pAdapter; +#else + pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter; +#endif + vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0); + + return vosStatus; +} + +VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter) +{ + return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId); +} + +VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + v_U8_t staId = 0; + hdd_context_t *pHddCtx; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + /*bss deregister is not allowed during wlan driver loading or unloading*/ + if ((pHddCtx->isLoadInProgress) || + (pHddCtx->isUnloadInProgress)) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s:Loading_unloading in Progress. Ignore!!!",__func__); + return VOS_STATUS_E_PERM; + } + + vosStatus = hdd_softap_Deregister_BC_STA( pAdapter); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId); + } + + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if (pAdapter->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered + vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to deregister sta Id %d", __func__, staId); + } + } + return vosStatus; +} + +VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state) +{ + v_U8_t ucSTAId = WLAN_MAX_STA_COUNT; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to find right station", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Station MAC address does not matching", __func__); + return VOS_STATUS_E_FAILURE; + } + + vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state, VOS_FALSE); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: change station to state %d succeed", __func__, state); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + pAdapter->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED; + } + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s exit", __func__); + + return vosStatus; +} + + +VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId) +{ + v_U8_t i; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (vos_mem_compare(&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) && + pAdapter->aStaInfo[i].isUsed) + { + *staId = i; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId) +{ + v_U8_t i; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (pAdapter->aStaInfo[i].isUsed && + (!vos_is_macaddr_broadcast(&pAdapter->aStaInfo[i].macAddrSTA))) + { + *staId = i; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tdls.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tdls.c new file mode 100644 index 0000000000000..c4a7e00f69443 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tdls.c @@ -0,0 +1,3161 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_tdls.c + + \brief WLAN Host Device Driver implementation for TDLS + + ========================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_cfg80211.h" +#include "vos_sched.h" + +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER +static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx); +#endif /* TDLS_USE_SEPARATE_DISCOVERY_TIMER */ + +static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx); +static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx); +int wpa_tdls_is_allowed_force_peer(tdlsCtx_t *pHddTdlsCtx, u8 *mac); +#ifdef CONFIG_TDLS_IMPLICIT +static void wlan_hdd_tdls_pre_setup(struct work_struct *work); +#endif + +#ifndef WLAN_FEATURE_TDLS_DEBUG +#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO +#else +#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN +#endif + +static u8 wlan_hdd_tdls_hash_key (u8 *mac) +{ + int i; + u8 key = 0; + + for (i = 0; i < 6; i++) + key ^= mac[i]; + + return key; +} + +/** + * wlan_hdd_tdls_disable_offchan_and_teardown_links - Disable offchannel + * and teardown TDLS links + * @hddCtx : pointer to hdd context + * + * Return: None + */ +void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) +{ + u16 connected_tdls_peers = 0; + u8 staidx; + hddTdlsPeer_t *curr_peer = NULL; + hdd_adapter_t *adapter = NULL; + + if (eTDLS_SUPPORT_NOT_ENABLED == hddctx->tdls_mode) { + hddLog(LOG1, FL("TDLS mode is disabled OR not enabled in FW")); + return ; + } + + adapter = hdd_get_adapter(hddctx, WLAN_HDD_INFRA_STATION); + + if (adapter == NULL) { + hddLog(LOGE, FL("Station Adapter Not Found")); + return; + } + + connected_tdls_peers = wlan_hdd_tdlsConnectedPeers(adapter); + + if (!connected_tdls_peers) + return ; + + /* TDLS is not supported in case of concurrency. + * Disable TDLS Offchannel in FW to avoid more + * than two concurrent channels and generate TDLS + * teardown indication to supplicant. + * Below function Finds the first connected peer and + * disables TDLS offchannel for that peer. + * FW enables TDLS offchannel only when there is + * one TDLS peer. When there are more than one TDLS peer, + * there will not be TDLS offchannel in FW. + * So to avoid sending multiple request to FW, for now, + * just invoke offchannel mode functions only once + */ + hdd_set_tdls_offchannel(hddctx, hddctx->cfg_ini->fTDLSPrefOffChanNum); + hdd_set_tdls_secoffchanneloffset(hddctx, + TDLS_SEC_OFFCHAN_OFFSET_40PLUS); + hdd_set_tdls_offchannelmode(adapter, DISABLE_CHANSWITCH); + + for (staidx = 0; staidx < hddctx->max_num_tdls_sta; + staidx++) { + if (!hddctx->tdlsConnInfo[staidx].staId) + continue; + + curr_peer = wlan_hdd_tdls_find_all_peer(hddctx, + hddctx->tdlsConnInfo[staidx].peerMac.bytes); + + if (!curr_peer) + continue; + + hddLog(LOG1, FL("indicate TDLS teardown (staId %d)"), + curr_peer->staId); + + wlan_hdd_tdls_indicate_teardown( + curr_peer->pHddTdlsCtx->pAdapter, + curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + } +} + +/** + * hdd_tdls_notify_mode_change - Notify mode change + * @adapter: pointer to hdd adapter + * @hddCtx : pointer to hdd context + * + * Return: None + */ +void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, hdd_context_t *hddctx) +{ + if (adapter->device_mode != WLAN_HDD_INFRA_STATION) + wlan_hdd_tdls_disable_offchan_and_teardown_links(hddctx); +} + +#ifdef CONFIG_TDLS_IMPLICIT +void wlan_hdd_tdls_pre_setup_init_work(tdlsCtx_t * pHddTdlsCtx, + hddTdlsPeer_t *curr_candidate) +{ + if (!pHddTdlsCtx || !curr_candidate) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: either pHddTdlsCtx or curr_candidate is null", + __func__); + return; + } + + if (TDLS_CTX_MAGIC != pHddTdlsCtx->magic) + { + /* When TDLS discovery attempt for a peer reaches to max configured + * threshold then tdls support for that peer would be disabled and + * in that case, ignore discovery trigger from FW for that peer. + */ + if (eTDLS_CAP_NOT_SUPPORTED == curr_candidate->tdls_support) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls_support is marked disabled for peer: " + MAC_ADDRESS_STR ", ignore pre_setup_init_work", + __func__, MAC_ADDR_ARRAY(curr_candidate->peerMac)); + return; + } + + pHddTdlsCtx->curr_candidate = curr_candidate; + pHddTdlsCtx->magic = TDLS_CTX_MAGIC; + + schedule_work(&pHddTdlsCtx->implicit_setup); + } +} +#endif + +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER +static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx, + tANI_BOOLEAN mutexLock, + v_U32_t discoveryExpiry) +{ + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + + if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx or pAdapter points to NULL")); + + return; + } + + pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter ); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + if (mutexLock) + { + mutex_lock(&pHddCtx->tdls_lock); + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d", + pHddTdlsCtx->ap_rssi); + + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + + return; +} + +static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData ) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData; + int discover_req_sent = 0; + v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD; + tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE; + + if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx or pAdapter points to NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pHddTdlsCtx->pAdapter->magic) { + hddLog(LOGE, FL("pAdapter has invalid magic")); + return; + } + + + pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter ); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__); + + if (0 == pHddTdlsCtx->discovery_peer_cnt) + pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx); + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each (pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i, + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->discovery_processed, + discover_req_sent, + curr_peer->tdls_support, + curr_peer->link_status, + curr_peer->discovery_attempt, + pHddTdlsCtx->threshold_config.discovery_tries_n); + + if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) { + if (!curr_peer->discovery_processed) { + + curr_peer->discovery_processed = 1; + discover_req_sent++; + pHddTdlsCtx->discovery_peer_cnt--; + + if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) && + (eTDLS_LINK_IDLE == curr_peer->link_status) && + (curr_peer->tx_pkt >= + pHddTdlsCtx->threshold_config.tx_packet_n)) { + + if (curr_peer->discovery_attempt < + pHddTdlsCtx->threshold_config.discovery_tries_n) { + sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), + pHddTdlsCtx->pAdapter->sessionId, + curr_peer->peerMac, + WLAN_TDLS_DISCOVERY_REQUEST, + 1, 0, 0, NULL, 0, 0); + curr_peer->discovery_attempt++; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Maximum Discovery retries reached", __func__); + curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED; + } + + } + } + } + else + goto exit_loop; + } + } +exit_loop: + + if (0 != pHddTdlsCtx->discovery_peer_cnt) { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER", + pHddTdlsCtx->discovery_peer_cnt); + discover_expiry = TDLS_SUB_DISCOVERY_PERIOD; + doMutexLock = eANI_BOOLEAN_FALSE; + goto done; + } + discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t; + + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + + mutex_unlock(&pHddCtx->tdls_lock); + + /* Commenting out the following function as it was introducing + * a race condition when pHddTdlsCtx is deleted. Also , this + * function is consuming more time in the timer callback. + * RSSI based trigger needs to revisit this part of the code. + */ + + /* + * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi); + */ + +done: + wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry); + + if ( !doMutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return; +} +#endif /* TDLS_USE_SEPARATE_DISCOVERY_TIMER */ + + + +static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + + pHddTdlsCtx = (tdlsCtx_t *)userData; + if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx or pAdapter points to NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pHddTdlsCtx->pAdapter->magic) { + hddLog(LOGE, FL("pAdapter has invalid magic")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter ); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + if (NULL == pHddCtx) + return; + + mutex_lock(&pHddCtx->tdls_lock); + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + if (eTDLS_LINK_DISCOVERING == tmp->link_status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR " to idle state", __func__, + MAC_ADDR_ARRAY(tmp->peerMac)); + mutex_unlock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_set_peer_link_status(tmp, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + mutex_lock(&pHddCtx->tdls_lock); + } + } + } + + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter); + + return; +} + +static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + return; + } + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) + { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + list_del(pos); + vos_mem_free(tmp); + tmp = NULL; + } + } +} + +static void wlan_hdd_tdls_schedule_scan(struct work_struct *work) +{ + tdls_scan_context_t *scan_ctx = + container_of(work, tdls_scan_context_t, tdls_scan_work.work); + + if (NULL == scan_ctx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("scan_ctx is NULL")); + return; + } + + if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic)) + return; + + scan_ctx->attempt++; + + wlan_hdd_cfg80211_scan(scan_ctx->wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + scan_ctx->dev, +#endif + scan_ctx->scan_request); +} + +/* stop all monitoring timers per Adapter */ +static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx) +{ +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +} + +/* stop all the tdls timers running */ +static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx); +} + +int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tdlsCtx_t *pHddTdlsCtx = NULL; + int i; + v_U8_t staIdx; + tdlsInfo_t *tInfo; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if (NULL == pHddCtx) + return -1; + + mutex_lock(&pHddCtx->tdls_lock); + + /* QCA 2.0 Discrete ANDs feature capability in cfg_ini with that + * received from target, so cfg_ini gives combined intersected result + */ + if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) + ) + { + pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s TDLS not enabled (%d) or FW doesn't support", + __func__, pHddCtx->cfg_ini->fEnableTDLSSupport); + mutex_unlock(&pHddCtx->tdls_lock); + return 0; + } + /* TDLS is supported only in STA / P2P Client modes, + * hence the check for TDLS support in a specific Device mode. + * Do not return a failure rather do not continue further + * with the initialization as tdls_init would be called + * during the open adapter for a p2p interface at which point + * the device mode would be a P2P_DEVICE. The point here is to + * continue initialization for STA / P2P Client modes. + * TDLS exit also check for the device mode for clean up hence + * there is no issue even if success is returned. + */ + if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter)) + { + mutex_unlock(&pHddCtx->tdls_lock); + return 0; + } + /* Check for the valid pHddTdlsCtx. If valid do not further + * allocate the memory, rather continue with the initialization. + * If tdls_initialization would get reinvoked without tdls_exit + * getting invoked (SSR) there is no point to further proceed + * with the memory allocations. + */ + if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx) + { + pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t)); + + if (NULL == pHddTdlsCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__); + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + /* initialize TDLS pAdater context */ + vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t)); +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_discover_peer_cb, + pHddTdlsCtx); +#endif + + vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_discovery_timeout_peer_cb, + pHddTdlsCtx); + + pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx; + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) + INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]); + } else { + struct list_head *head, *pos, *q; + hddTdlsPeer_t *tmp = NULL; + + pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx; + + /* stop all timers */ + wlan_hdd_tdls_timers_stop(pHddTdlsCtx); + + /* remove entries from peer list only if peer is not forced */ + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe(pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + if (FALSE == tmp->isForcedPeer) { + list_del(pos); + vos_mem_free(tmp); + tmp = NULL; + } else { + tmp->link_status = eTDLS_LINK_IDLE; + tmp->reason = eTDLS_LINK_UNSPECIFIED; + tmp->staId = 0; + tmp->discovery_attempt = 0; + } + } + } + /* reset tdls peer count to 0 */ + pHddCtx->connected_peer_count = 0; + } + + /* initialize TDLS global context */ + pHddCtx->connected_peer_count = 0; + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, 0); + + pHddCtx->tdls_scan_ctxt.magic = 0; + pHddCtx->tdls_scan_ctxt.attempt = 0; + pHddCtx->tdls_scan_ctxt.reject = 0; + pHddCtx->tdls_scan_ctxt.scan_request = NULL; + + if (pHddCtx->cfg_ini->fEnableTDLSSleepSta || + pHddCtx->cfg_ini->fEnableTDLSBufferSta || + pHddCtx->cfg_ini->fEnableTDLSOffChannel) + pHddCtx->max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN; + else + pHddCtx->max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, FL("max_num_tdls_sta: %d"), + pHddCtx->max_num_tdls_sta); + + for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) + { + pHddCtx->tdlsConnInfo[staIdx].staId = 0; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + } + + pHddTdlsCtx->pAdapter = pAdapter; + + pHddTdlsCtx->curr_candidate = NULL; + pHddTdlsCtx->magic = 0; + + /* remember configuration even if it is not used right now. it could be used later */ + pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod; + pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold; + pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod; + pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt; + pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout; + pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold; + pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis; + pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold; + pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold; + pHddTdlsCtx->threshold_config.rssi_delta = pHddCtx->cfg_ini->fTDLSRSSIDelta; + + if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) + { + pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; + hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__); + } + else + { + pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; + } + +#ifdef CONFIG_TDLS_IMPLICIT +#ifdef CONFIG_CNSS + cnss_init_work(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); +#else + INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); +#endif +#endif + +#ifdef CONFIG_CNSS + cnss_init_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, + wlan_hdd_tdls_schedule_scan); +#else + INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, + wlan_hdd_tdls_schedule_scan); +#endif + + /* + * Release tdls lock before calling in SME api + * which would try to acquire sme lock. + */ + mutex_unlock(&pHddCtx->tdls_lock); + tInfo = vos_mem_malloc(sizeof(tdlsInfo_t)); + if (NULL == tInfo) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed for tInfo", __func__); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_mem_free(pHddTdlsCtx); + return -1; + } + + tInfo->vdev_id = pAdapter->sessionId; + tInfo->tdls_state = pHddCtx->tdls_mode; + tInfo->notification_interval_ms = pHddTdlsCtx->threshold_config.tx_period_t; + tInfo->tx_discovery_threshold = pHddTdlsCtx->threshold_config.tx_packet_n; + tInfo->tx_teardown_threshold = pHddTdlsCtx->threshold_config.idle_packet_n; + tInfo->rssi_teardown_threshold = + pHddTdlsCtx->threshold_config.rssi_teardown_threshold; + tInfo->rssi_delta = pHddTdlsCtx->threshold_config.rssi_delta; + tInfo->tdls_options = 0; + if (pHddCtx->cfg_ini->fEnableTDLSOffChannel) + tInfo->tdls_options |= ENA_TDLS_OFFCHAN; + if (pHddCtx->cfg_ini->fEnableTDLSBufferSta) + tInfo->tdls_options |= ENA_TDLS_BUFFER_STA; + if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) + tInfo->tdls_options |= ENA_TDLS_SLEEP_STA; + tInfo->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tInfo->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tInfo->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tInfo->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tInfo->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Setting tdls state and param in fw: " + "vdev_id: %d, " + "tdls_state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", + __func__, + tInfo->vdev_id, + tInfo->tdls_state, + tInfo->notification_interval_ms, + tInfo->tx_discovery_threshold, + tInfo->tx_teardown_threshold, + tInfo->rssi_teardown_threshold, + tInfo->rssi_delta, + tInfo->tdls_options, + tInfo->peer_traffic_ind_window, + tInfo->peer_traffic_response_timeout, + tInfo->puapsd_mask, + tInfo->puapsd_inactivity_time, + tInfo->puapsd_rx_frame_threshold); + + halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tInfo, TRUE); + if (eHAL_STATUS_SUCCESS != halStatus) + { + vos_mem_free(tInfo); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_mem_free(pHddTdlsCtx); + return -1; + } + + return 0; +} + +void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + tdlsInfo_t *tInfo; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is NULL")); + return; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + /* TDLS context can be null and might have been freed up during + * cleanup for STA adapter + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("pHddTdlsCtx is NULL, adapter device mode: %d"), + pAdapter->device_mode); + return; + } + + vos_flush_work(&pHddTdlsCtx->implicit_setup); + vos_flush_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work); + + mutex_lock(&pHddCtx->tdls_lock); + + /* must stop timer here before freeing peer list, because peerIdleTimer is + part of peer list structure. */ + wlan_hdd_tdls_timers_destroy(pHddTdlsCtx); + wlan_hdd_tdls_free_list(pHddTdlsCtx); + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt); + + /* No need to post message during driver unload because MC thread is + already shutdown */ + if ( !pHddCtx->isUnloadInProgress) + { + tInfo = vos_mem_malloc(sizeof(tdlsInfo_t)); + if (NULL != tInfo) + { + tInfo->vdev_id = pAdapter->sessionId; + tInfo->tdls_state = eTDLS_SUPPORT_DISABLED; + tInfo->notification_interval_ms = + pHddTdlsCtx->threshold_config.tx_period_t; + tInfo->tx_discovery_threshold = + pHddTdlsCtx->threshold_config.tx_packet_n; + tInfo->tx_teardown_threshold = + pHddTdlsCtx->threshold_config.idle_packet_n; + tInfo->rssi_teardown_threshold = + pHddTdlsCtx->threshold_config.rssi_teardown_threshold; + tInfo->rssi_delta = pHddTdlsCtx->threshold_config.rssi_delta; + tInfo->tdls_options = 0; + if (pHddCtx->cfg_ini->fEnableTDLSOffChannel) + tInfo->tdls_options |= ENA_TDLS_OFFCHAN; + if (pHddCtx->cfg_ini->fEnableTDLSBufferSta) + tInfo->tdls_options |= ENA_TDLS_BUFFER_STA; + if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) + tInfo->tdls_options |= ENA_TDLS_SLEEP_STA; + tInfo->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tInfo->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tInfo->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tInfo->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tInfo->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Setting tdls state and param in fw: " + "vdev_id: %d, " + "tdls_state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", + __func__, + tInfo->vdev_id, + tInfo->tdls_state, + tInfo->notification_interval_ms, + tInfo->tx_discovery_threshold, + tInfo->tx_teardown_threshold, + tInfo->rssi_teardown_threshold, + tInfo->rssi_delta, + tInfo->tdls_options, + tInfo->peer_traffic_ind_window, + tInfo->peer_traffic_response_timeout, + tInfo->puapsd_mask, + tInfo->puapsd_inactivity_time, + tInfo->puapsd_rx_frame_threshold); + + halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tInfo, FALSE); + if (eHAL_STATUS_SUCCESS != halStatus) + { + vos_mem_free(tInfo); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed for tInfo", __func__); + } + } + + pHddTdlsCtx->magic = 0; + pHddTdlsCtx->pAdapter = NULL; + + vos_mem_free(pHddTdlsCtx); + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + pHddTdlsCtx = NULL; +} + +static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx) +{ +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +} + +/* destroy all the tdls timers running */ +static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx); +} + +/* if mac address exist, return pointer + if mac address doesn't exist, create a list and add, return pointer + return NULL if fails to get new mac address +*/ +hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac) +{ + struct list_head *head; + hddTdlsPeer_t *peer; + u8 key; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return NULL; + } + + /* if already there, just update */ + peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (peer != NULL) + { + return peer; + } + + /* not found, allocate and add the list */ + peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); + if (NULL == peer) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); + return NULL; + } + + mutex_lock(&pHddCtx->tdls_lock); + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + vos_mem_free(peer); + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; + } + + key = wlan_hdd_tdls_hash_key(mac); + head = &pHddTdlsCtx->peer_list[key]; + + vos_mem_zero(peer, sizeof(hddTdlsPeer_t)); + vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac)); + peer->pHddTdlsCtx = pHddTdlsCtx; + peer->pref_off_chan_num = pHddCtx->cfg_ini->fTDLSPrefOffChanNum; + + list_add_tail(&peer->node, head); + mutex_unlock(&pHddCtx->tdls_lock); + + return peer; +} + +int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter, + u8* mac, + tTDLSCapType cap) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->tdls_support = cap; + + return 0; +} + +void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, + tTDLSLinkStatus status, + tTDLSLinkReason reason) +{ + tANI_S32 state = 0; + tANI_S32 res = 0; + hdd_context_t *pHddCtx; + + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return; + } + + if (curr_peer->pHddTdlsCtx == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer->pHddTdlsCtx is NULL")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(curr_peer->pHddTdlsCtx->pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u", + MAC_ADDR_ARRAY(curr_peer->peerMac), status); + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer->link_status = status; + + /* If TDLS link status is already passed the discovery state + * then clear discovery attempt count + */ + if (status >= eTDLS_LINK_DISCOVERED) + { + curr_peer->discovery_attempt = 0; + } + + mutex_unlock(&pHddCtx->tdls_lock); + + if (curr_peer->isForcedPeer && curr_peer->state_change_notification) + { + /*save the reason for any further query*/ + curr_peer->reason = reason; + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); + + (*curr_peer->state_change_notification)( + curr_peer->peerMac, + state, + res, + curr_peer->pHddTdlsCtx->pAdapter); + + } + return; +} + +void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, + u8* mac, + tTDLSLinkStatus linkStatus, + tTDLSLinkReason reason) +{ + tANI_S32 state = 0; + tANI_S32 res = 0; + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer->link_status= linkStatus; + + /* If TDLS link status is already passed the discovery state + * then clear discovery attempt count + */ + if (linkStatus >= eTDLS_LINK_DISCOVERED) + { + curr_peer->discovery_attempt = 0; + } + + mutex_unlock(&pHddCtx->tdls_lock); + + if (curr_peer->isForcedPeer && curr_peer->state_change_notification) + { + /*save the reason for any further query*/ + curr_peer->reason = reason; + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); + + (curr_peer->state_change_notification)( + mac, + state, + res, + curr_peer->pHddTdlsCtx->pAdapter); + + } + + return; +} + +int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac) +{ + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx; + + if ( NULL == pHddTdlsCtx ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + return -1; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return -1; + } + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + + if (NULL == curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + if (pHddTdlsCtx->discovery_sent_cnt) + pHddTdlsCtx->discovery_sent_cnt--; + + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + mutex_unlock(&pHddCtx->tdls_lock); + if (0 == pHddTdlsCtx->discovery_sent_cnt) + { + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); + } + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "Discovery(%u) Response from " MAC_ADDRESS_STR " link_status %d", + pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->link_status); + + if (eTDLS_LINK_DISCOVERING == curr_peer->link_status) + { + /* + * Since we are here, it means Throughput threshold is already met. + * Make sure RSSI threshold is also met before setting up TDLS link + */ + if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold) + { + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_DISCOVERED, + eTDLS_LINK_SUCCESS); + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" , + MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi, + pHddTdlsCtx->threshold_config.rssi_trigger_threshold); + cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ", + MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi, + pHddTdlsCtx->threshold_config.rssi_trigger_threshold); + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + + /* if RSSI threshold is not met then allow further discovery + * attempts by decrementing count for the last attempt + */ + if (curr_peer->discovery_attempt) + curr_peer->discovery_attempt--; + } + } + else + { + wlan_hdd_tdls_check_bmps(pAdapter); + } + + curr_peer->tdls_support = eTDLS_CAP_SUPPORTED; + return 0; +} + +int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter, + u8 *mac, + tCsrStaParams *StaParams, + tANI_BOOLEAN isBufSta, + tANI_BOOLEAN isOffChannelSupported) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->uapsdQueues = StaParams->uapsd_queues; + curr_peer->maxSp = StaParams->max_sp; + curr_peer->isBufSta = isBufSta; + curr_peer->isOffChannelSupported = isOffChannelSupported; + + vos_mem_copy(curr_peer->supported_channels, + StaParams->supported_channels, + StaParams->supported_channels_len); + + curr_peer->supported_channels_len = + StaParams->supported_channels_len; + + vos_mem_copy(curr_peer->supported_oper_classes, + StaParams->supported_oper_classes, + StaParams->supported_oper_classes_len); + + curr_peer->supported_oper_classes_len = + StaParams->supported_oper_classes_len; + return 0; +} + +int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac, + tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + tdlsLinkEstablishParams->isResponder = curr_peer->is_responder; + tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues; + tdlsLinkEstablishParams->maxSp = curr_peer->maxSp; + tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta; + tdlsLinkEstablishParams->isOffChannelSupported = + curr_peer->isOffChannelSupported; + + vos_mem_copy(tdlsLinkEstablishParams->supportedChannels, + curr_peer->supported_channels, + curr_peer->supported_channels_len); + + tdlsLinkEstablishParams->supportedChannelsLen = + curr_peer->supported_channels_len; + + vos_mem_copy(tdlsLinkEstablishParams->supportedOperClasses, + curr_peer->supported_oper_classes, + curr_peer->supported_oper_classes_len); + + tdlsLinkEstablishParams->supportedOperClassesLen = + curr_peer->supported_oper_classes_len; + return 0; +} + +int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->rssi = rxRssi; + + return 0; +} + +int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->is_responder = responder; + + return 0; +} + +int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + return (curr_peer->is_responder); +} + +int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->signature = uSignature; + + return 0; +} + + +void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac) +{ + memcpy(mac, skb->data, 6); +} + +void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac) +{ + memcpy(mac, skb->data+6, 6); +} + +int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode) + return -1; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + if (tx) + curr_peer->tx_pkt++; + else + curr_peer->rx_pkt++; + + return 0; +} + +static int wlan_hdd_tdls_check_config(tdls_config_params_t *config) +{ + if (config->tdls > 2) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls); + return -1; + } + if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN || + config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%ld>", __func__, config->tx_period_t, + CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX); + return -1; + } + if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN || + config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%ld>", __func__, + config->tx_packet_n, + CFG_TDLS_TX_PACKET_THRESHOLD_MIN, + CFG_TDLS_TX_PACKET_THRESHOLD_MAX); + return -1; + } + if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN || + config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%ld>", __func__, + config->discovery_period_t, + CFG_TDLS_DISCOVERY_PERIOD_MIN, + CFG_TDLS_DISCOVERY_PERIOD_MAX); + return -1; + } + if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN || + config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", + __func__, + config->discovery_tries_n, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX); + return -1; + } + if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN || + config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, + config->idle_timeout_t, + CFG_TDLS_IDLE_TIMEOUT_MIN, + CFG_TDLS_IDLE_TIMEOUT_MAX); + return -1; + } + if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN || + config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX); + return -1; + } + if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN || + config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis, + CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX); + return -1; + } + if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN || + config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX); + return -1; + } + if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN || + config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX); + return -1; + } + return 0; +} + +int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + eTDLSSupportMode req_tdls_mode; + tdlsInfo_t *tdlsParams; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if (NULL == pHddTdlsCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS not enabled!")); + return -1; + } + + if (wlan_hdd_tdls_check_config(config) != 0) + { + return -1; + } + + /* config->tdls is mapped to 0->1, 1->2, 2->3 */ + req_tdls_mode = config->tdls + 1; + if (pHddCtx->tdls_mode == req_tdls_mode) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls); + return -1; + } + + /* copy the configuration only when given tdls mode is implicit trigger enable */ + if (eTDLS_SUPPORT_ENABLED == req_tdls_mode) + { + memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t)); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "iw set tdls params: %d %d %d %d %d %d %d %d %d %d", + config->tdls, + config->tx_period_t, + config->tx_packet_n, + config->discovery_period_t, + config->discovery_tries_n, + config->idle_timeout_t, + config->idle_packet_n, + config->rssi_hysteresis, + config->rssi_trigger_threshold, + config->rssi_teardown_threshold); + + wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE); + + tdlsParams = vos_mem_malloc(sizeof(tdlsInfo_t)); + if (NULL == tdlsParams) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed for tdlsParams", __func__); + return -1; + } + + tdlsParams->vdev_id = pAdapter->sessionId; + tdlsParams->tdls_state = config->tdls; + tdlsParams->notification_interval_ms = config->tx_period_t; + tdlsParams->tx_discovery_threshold = config->tx_packet_n; + tdlsParams->tx_teardown_threshold = config->idle_packet_n; + tdlsParams->rssi_teardown_threshold = config->rssi_teardown_threshold; + tdlsParams->rssi_delta = config->rssi_delta; + tdlsParams->tdls_options = 0; + if (pHddCtx->cfg_ini->fEnableTDLSOffChannel) + tdlsParams->tdls_options |= ENA_TDLS_OFFCHAN; + if (pHddCtx->cfg_ini->fEnableTDLSBufferSta) + tdlsParams->tdls_options |= ENA_TDLS_BUFFER_STA; + if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) + tdlsParams->tdls_options |= ENA_TDLS_SLEEP_STA; + tdlsParams->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tdlsParams->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tdlsParams->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tdlsParams->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tdlsParams->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; + + + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Setting tdls state and param in fw: " + "vdev_id: %d, " + "tdls_state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", + __func__, + tdlsParams->vdev_id, + tdlsParams->tdls_state, + tdlsParams->notification_interval_ms, + tdlsParams->tx_discovery_threshold, + tdlsParams->tx_teardown_threshold, + tdlsParams->rssi_teardown_threshold, + tdlsParams->rssi_delta, + tdlsParams->tdls_options, + tdlsParams->peer_traffic_ind_window, + tdlsParams->peer_traffic_response_timeout, + tdlsParams->puapsd_mask, + tdlsParams->puapsd_inactivity_time, + tdlsParams->puapsd_rx_frame_threshold); + + halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tdlsParams, TRUE); + if (eHAL_STATUS_SUCCESS != halStatus) + { + vos_mem_free(tdlsParams); + return -1; + } + + return 0; +} + +/** + * wlan_hdd_update_tdls_info - update tdls status info + * @adapter: ptr to device adapter. + * @tdls_prohibited: indicates whether tdls is prohibited. + * @tdls_chan_swit_prohibited: indicates whether tdls channel switch + * is prohibited. + * + * Normally an AP does not influence TDLS connection between STAs + * associated to it. But AP may set bits for TDLS Prohibited or + * TDLS Channel Switch Prohibited in Extended Capability IE in + * Assoc/Re-assoc response to STA. So after STA is connected to + * an AP, call this function to update TDLS status as per those + * bits set in Ext Cap IE in received Assoc/Re-assoc response + * from AP. + * + * Return: None. + */ +void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, + bool tdls_chan_swit_prohibited) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + tdlsCtx_t *hdd_tdls_ctx = WLAN_HDD_GET_TDLS_CTX_PTR(adapter); + tdlsInfo_t *tdls_param; + eHalStatus hal_status; + + if (!hdd_tdls_ctx) { + /* may be TDLS is not applicable for this adapter */ + hddLog(LOG1, FL("HDD TDLS context is null")); + return; + } + + /* If TDLS support is disabled then no need to update target */ + if (FALSE == hdd_ctx->cfg_ini->fEnableTDLSSupport) { + hddLog(LOG1, FL("TDLS not enabled")); + return; + } + + /* If AP indicated TDLS Prohibited then disable tdls mode */ + mutex_lock(&hdd_ctx->tdls_lock); + if (tdls_prohibited) { + hdd_ctx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + } else { + if (FALSE == hdd_ctx->cfg_ini->fEnableTDLSImplicitTrigger) { + hdd_ctx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; + } else { + hdd_ctx->tdls_mode = eTDLS_SUPPORT_ENABLED; + } + } + mutex_unlock(&hdd_ctx->tdls_lock); + + tdls_param = vos_mem_malloc(sizeof(*tdls_param)); + if (!tdls_param) { + hddLog(LOGE, + FL("memory allocation failed for tdlsParams")); + return; + } + + tdls_param->vdev_id = adapter->sessionId; + tdls_param->tdls_state = hdd_ctx->tdls_mode; + tdls_param->notification_interval_ms = + hdd_tdls_ctx->threshold_config.tx_period_t; + tdls_param->tx_discovery_threshold = + hdd_tdls_ctx->threshold_config.tx_packet_n; + tdls_param->tx_teardown_threshold = + hdd_tdls_ctx->threshold_config.idle_packet_n; + tdls_param->rssi_teardown_threshold = + hdd_tdls_ctx->threshold_config.rssi_teardown_threshold; + tdls_param->rssi_delta = hdd_tdls_ctx->threshold_config.rssi_delta; + + tdls_param->tdls_options = 0; + + /* Do not enable TDLS offchannel, if AP prohibited TDLS channel switch */ + if ((hdd_ctx->cfg_ini->fEnableTDLSOffChannel) && + (!tdls_chan_swit_prohibited)) { + tdls_param->tdls_options |= ENA_TDLS_OFFCHAN; + } + + if (hdd_ctx->cfg_ini->fEnableTDLSBufferSta) + tdls_param->tdls_options |= ENA_TDLS_BUFFER_STA; + + if (hdd_ctx->cfg_ini->fEnableTDLSSleepSta) + tdls_param->tdls_options |= ENA_TDLS_SLEEP_STA; + + tdls_param->peer_traffic_ind_window = + hdd_ctx->cfg_ini->fTDLSPuapsdPTIWindow; + tdls_param->peer_traffic_response_timeout = + hdd_ctx->cfg_ini->fTDLSPuapsdPTRTimeout; + tdls_param->puapsd_mask = + hdd_ctx->cfg_ini->fTDLSUapsdMask; + tdls_param->puapsd_inactivity_time = + hdd_ctx->cfg_ini->fTDLSPuapsdInactivityTimer; + tdls_param->puapsd_rx_frame_threshold = + hdd_ctx->cfg_ini->fTDLSRxFrameThreshold; + + hddLog(LOG1, + FL("Setting tdls state and param in fw: " + "vdev_id: %d, " + "tdls_state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d "), + tdls_param->vdev_id, + tdls_param->tdls_state, + tdls_param->notification_interval_ms, + tdls_param->tx_discovery_threshold, + tdls_param->tx_teardown_threshold, + tdls_param->rssi_teardown_threshold, + tdls_param->rssi_delta, + tdls_param->tdls_options, + tdls_param->peer_traffic_ind_window, + tdls_param->peer_traffic_response_timeout, + tdls_param->puapsd_mask, + tdls_param->puapsd_inactivity_time, + tdls_param->puapsd_rx_frame_threshold); + + hal_status = sme_UpdateFwTdlsState(hdd_ctx->hHal, tdls_param, TRUE); + if (eHAL_STATUS_SUCCESS != hal_status) { + vos_mem_free(tdls_param); + return; + } + + return; +} + +int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->staId = staId; + + return 0; +} + +int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter, uint8_t *mac, + uint32_t chan, uint32_t max_latency, + uint32_t op_class, uint32_t min_bandwidth) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (!pHddCtx) + return -1; + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + { + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->op_class_for_pref_off_chan = (uint8_t)op_class; + curr_peer->pref_off_chan_num = (uint8_t)chan; + + if (curr_peer->op_class_for_pref_off_chan) + curr_peer->op_class_for_pref_off_chan_is_set = 1; + else + curr_peer->op_class_for_pref_off_chan_is_set = 0; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac, + tANI_BOOLEAN forcePeer) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (!pHddCtx) + return -1; + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + { + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->isForcedPeer = forcePeer; + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +/* if peerMac is found, then it returns pointer to hddTdlsPeer_t + * otherwise, it returns NULL + */ +hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac, + tANI_BOOLEAN mutexLock) +{ + u8 key; + struct list_head *pos; + struct list_head *head; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return NULL; + } + + if ( mutexLock ) + { + mutex_lock(&pHddCtx->tdls_lock); + } + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; + } + + key = wlan_hdd_tdls_hash_key(mac); + + head = &pHddTdlsCtx->peer_list[key]; + + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (!memcmp(mac, curr_peer->peerMac, 6)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "findTdlsPeer: found staId %d", curr_peer->staId); + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; + } + } + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; +} + +hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + hddTdlsPeer_t *curr_peer= NULL; + VOS_STATUS status = 0; + + mutex_lock(&pHddCtx->tdls_lock); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer) + { + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; +} + + +int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac) +{ + hdd_context_t *pHddCtx; + hddTdlsPeer_t *curr_peer; + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + curr_peer->staId = 0; + + return 0; +} + +/* Caller has to take the lock before calling this function */ +static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + tmp->tx_pkt = 0; + tmp->rx_pkt = 0; + } + } + + return ; +} + +/* Caller has to take the lock before calling this function */ +static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + pHddTdlsCtx->discovery_peer_cnt = 0; + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + tmp->discovery_processed = 0; + } + } + + return 0; +} + +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER +static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + struct list_head *pos, *q; + int discovery_peer_cnt=0; + hddTdlsPeer_t *tmp; + + /* + * This function expects the callers to acquire the Mutex. + */ + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s, %d, " MAC_ADDRESS_STR, __func__, i, + MAC_ADDR_ARRAY(tmp->peerMac)); + discovery_peer_cnt++; + } + } + return discovery_peer_cnt; +} +#endif /* TDLS_USE_SEPARATE_DISCOVERY_TIMER */ + +tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return 0; + } + + return pHddCtx->connected_peer_count; +} + +int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen) +{ + int i; + int len, init_len; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return 0; + } + + init_len = buflen; + len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buflen -= len; + /* 1234567890123456789012345678901234567 */ + len = scnprintf(buf, buflen, "---------------------------------\n"); + buf += len; + buflen -= len; + + mutex_lock(&pHddCtx->tdls_lock); + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) { + mutex_unlock(&pHddCtx->tdls_lock); + len = scnprintf(buf, buflen, "TDLS not enabled\n"); + return len; + } + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each(pos, head) { + curr_peer= list_entry (pos, hddTdlsPeer_t, node); + + if (buflen < 32+1) + break; + len = scnprintf(buf, buflen, + MAC_ADDRESS_STR"%3d%4s%3s%5d\n", + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->staId, + (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N", + TDLS_IS_CONNECTED(curr_peer) ? "Y":"N", + curr_peer->rssi); + buf += len; + buflen -= len; + } + } + mutex_unlock(&pHddCtx->tdls_lock); + return init_len-buflen; +} + +void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s, update %d discover %d", __func__, + pHddTdlsCtx->threshold_config.tx_period_t, + pHddTdlsCtx->threshold_config.discovery_period_t); + + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) + { + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + } + mutex_unlock(&pHddCtx->tdls_lock); + +} + +void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__); + + mutex_lock(&pHddCtx->tdls_lock); + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx); + wlan_hdd_tdls_free_list(pHddTdlsCtx); + + pHddTdlsCtx->curr_candidate = NULL; + + mutex_unlock(&pHddCtx->tdls_lock); +} + +void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode) +{ + pAdapter->mgmtTxCompletionStatus = statusCode; + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d", + __func__, statusCode); + complete(&pAdapter->tdls_mgmt_comp); +} + +void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + pHddCtx->connected_peer_count++; + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d", + __func__, pHddCtx->connected_peer_count); + + mutex_unlock(&pHddCtx->tdls_lock); +} + +void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + if (pHddCtx->connected_peer_count) + pHddCtx->connected_peer_count--; + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d", + __func__, pHddCtx->connected_peer_count); + + mutex_unlock(&pHddCtx->tdls_lock); + +} + +void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + hddTdlsPeer_t *curr_peer; + + if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) + { + //getting over logged, so moving log-level to INFO. + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0); + if (NULL != curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY (curr_peer->peerMac)); + return; + } + /* + * If Powersave Offload is enabled + * Fw will take care incase of concurrency + */ + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + { + if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) && + (0 == pHddCtx->connected_peer_count) && + (0 == pHddTdlsCtx->discovery_sent_cnt)) + { + if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: No TDLS peer connected/discovery sent. Enable BMPS", + __func__); + hdd_enable_bmps_imps(pHddCtx); + } + } + else + { + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: TDLS peer connected. Disable BMPS", __func__); + hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + } + } + } + else + { + if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) && + (0 == pHddCtx->connected_peer_count) && + (0 == pHddTdlsCtx->discovery_sent_cnt)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: No TDLS peer connected/discovery sent. Enable BMPS", + __func__); + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, FALSE); + sme_PsOffloadEnablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: TDLS peer connected. Disable BMPS", __func__); + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, TRUE); + sme_PsOffloadDisablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + + } + } + return; +} + +u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return 0; + } + + return (eTDLS_LINK_CONNECTING == curr_peer->link_status); +} + +/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL. + * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE + * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if + mac is NULL, this argument is ignored, and check for all the peer list. + */ +static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *curr_peer; + struct list_head *pos; + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + return NULL; + } + + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) { + continue; + } + else + { + if (eTDLS_LINK_CONNECTING == curr_peer->link_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + return curr_peer; + } + } + } + } + return NULL; +} + +hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8 *mac, u8 skip_self) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + hddTdlsPeer_t *curr_peer= NULL; + VOS_STATUS status = 0; + + mutex_lock(&pHddCtx->tdls_lock); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self); + if (curr_peer) + { + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; +} + +static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_timers_stop(pHddTdlsCtx); +} + +static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx); + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + +} + +void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode, + v_BOOL_t bUpdateLast) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + tdlsCtx_t *pHddTdlsCtx; + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + if (pHddCtx->tdls_mode == tdls_mode) + { + hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode); + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + if(eTDLS_SUPPORT_ENABLED == tdls_mode) + wlan_hdd_tdls_implicit_enable(pHddTdlsCtx); + else if((eTDLS_SUPPORT_DISABLED == tdls_mode) || + (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode)) + wlan_hdd_tdls_implicit_disable(pHddTdlsCtx); + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + if(bUpdateLast) + { + pHddCtx->tdls_mode_last = tdls_mode; + } + else + { + pHddCtx->tdls_mode_last = pHddCtx->tdls_mode; + } + pHddCtx->tdls_mode = tdls_mode; + + mutex_unlock(&pHddCtx->tdls_lock); +} + +static void __wlan_hdd_tdls_pre_setup(struct work_struct *work) +{ + tdlsCtx_t *pHddTdlsCtx = + container_of(work, tdlsCtx_t, implicit_setup); + hdd_context_t *pHddCtx; + hddTdlsPeer_t *curr_peer; + hddTdlsPeer_t *temp_peer; + int status; + tSirMacAddr peer_mac; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL")); + return; + } + + if (unlikely(TDLS_CTX_MAGIC != pHddTdlsCtx->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: tdls magic number mis-match %u", + __func__, pHddTdlsCtx->magic); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer = pHddTdlsCtx->curr_candidate; + + if (NULL == curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + goto done; + } + + vos_mem_copy(&peer_mac, curr_peer->peerMac, sizeof(peer_mac)); + + mutex_unlock(&pHddCtx->tdls_lock); + + /* + * If Powersave Offload is enabled + * Fw will take care incase of concurrency + */ + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + { + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: Disable BMPS", __func__); + hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + } + } + + temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0); + + if (NULL != temp_peer) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored", + __func__, MAC_ADDR_ARRAY(temp_peer->peerMac)); + goto done; + } + + if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support) + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_DISCOVERING, + eTDLS_LINK_SUCCESS); + + mutex_lock(&pHddCtx->tdls_lock); + + /* Ignore discovery attempt if External Control is enabled, that + * is, peer is forced. In that case, continue discovery attempt + * regardless attempt count + */ + if (FALSE == curr_peer->isForcedPeer) + { + if (curr_peer->discovery_attempt >= + pHddTdlsCtx->threshold_config.discovery_tries_n) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: discovery attempt (%d) reached max (%d) for peer " + MAC_ADDRESS_STR ", ignore discovery trigger from fw", + __func__, curr_peer->discovery_attempt, + pHddTdlsCtx->threshold_config.discovery_tries_n, + MAC_ADDR_ARRAY(curr_peer->peerMac)); + curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED; + goto done; + } + } + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_DISCOVERING, + eTDLS_LINK_SUCCESS); + + status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy, + pHddTdlsCtx->pAdapter->dev, + peer_mac); + + mutex_lock(&pHddCtx->tdls_lock); + + if (NULL == pHddTdlsCtx->curr_candidate) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: current candidate Not valid any more", __func__); + goto done; + } + + curr_peer = pHddTdlsCtx->curr_candidate; + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " discovery could not sent", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support) + { + mutex_unlock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + mutex_lock(&pHddCtx->tdls_lock); + } + goto done; + } + + pHddTdlsCtx->discovery_sent_cnt++; + + curr_peer->discovery_attempt++; + + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %u timeout %u msec", + __func__, pHddTdlsCtx->discovery_sent_cnt, + pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); + + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &pHddTdlsCtx->peerDiscoveryTimeoutTimer, + pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); + +done: + pHddTdlsCtx->curr_candidate = NULL; + pHddTdlsCtx->magic = 0; + mutex_unlock(&pHddCtx->tdls_lock); + return; +} + +static void wlan_hdd_tdls_pre_setup(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __wlan_hdd_tdls_pre_setup(work); + vos_ssr_unprotect(__func__); +} + +tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + VOS_STATUS status = 0; + tANI_U32 count = 0; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + count = count + pHddTdlsCtx->discovery_sent_cnt; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return count; +} + +void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + if ((0 == pHddCtx->connected_peer_count) && + (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx))) + { + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), + pAdapter->sessionId, 0); + return; + } + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), + pAdapter->sessionId, 1); + return; +} + +void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx) +{ + if (NULL == tdls_scan_ctx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("tdls_scan_ctx is NULL")); + return; + } + + tdls_scan_ctx->attempt = 0; + tdls_scan_ctx->reject = 0; + tdls_scan_ctx->magic = 0; + tdls_scan_ctx->scan_request = NULL; + return; +} + +int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + tdls_scan_context_t *scan_ctx; + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return -1; + } + + scan_ctx = &pHddCtx->tdls_scan_ctxt; + + scan_ctx->wiphy = wiphy; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + scan_ctx->dev = dev; +#endif + + scan_ctx->scan_request = request; + return 0; +} + +static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request, + unsigned long delay) +{ + if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request); +#else + wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request); +#endif + pHddCtx->tdls_scan_ctxt.attempt = 0; + pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC; + } + schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay); +} + +/* return negative = caller should stop and return error code immediately + return 0 = caller should stop and return success immediately + return 1 = caller can continue to scan + */ +int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + u16 connectedTdlsPeers; + hddTdlsPeer_t *curr_peer; + unsigned long delay; + int ret; + + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) + return ret; + + /* if tdls is not enabled, then continue scan */ + if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) + return 1; + + curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0); + if (NULL != curr_peer) + { + if (pHddCtx->tdls_scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT) + { + pHddCtx->tdls_scan_ctxt.reject = 0; + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle", + __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->tdls_scan_ctxt.reject); + + wlan_hdd_tdls_set_peer_link_status (curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + return 1; + } + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls in progress. scan rejected %d", + __func__, pHddCtx->tdls_scan_ctxt.reject); + return -EBUSY; + } + + /* tdls teardown is ongoing */ + if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode) + { + connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE)) + { + delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec", + __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay); + + wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request, + msecs_to_jiffies(delay)); + /* scan should not continue */ + return 0; + } + /* no connected peer or max retry reached, scan continue */ + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls disabled. connected_peers %d attempt %d. scan allowed", + __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt); + return 1; + } + /* while tdls is up, first time scan */ + else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode) + { + /* Disable implicit trigger logic & tdls operation */ + wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE); + /* indicate the teardown all connected to peer */ + connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (connectedTdlsPeers) + { + tANI_U8 staIdx; + tANI_U8 num = 0; + tANI_U8 i; + tANI_BOOLEAN allPeersBufStas = 1; + hddTdlsPeer_t *curr_peer; + hddTdlsPeer_t *connectedPeerList[HDD_MAX_NUM_TDLS_STA]; + + /* If TDLSScan is enabled then allow scan and maintain tdls link + * regardless if peer is buffer sta capable or not and if device + * is sleep sta capable or not. If peer is not buffer sta capable, + * then Tx would stop when device initiates scan and there will be + * loss of Rx packets since peer would not know when device moves + * away from the tdls channel. + */ + if (1 == pHddCtx->cfg_ini->enable_tdls_scan) { + hddLog(LOG1, + FL("TDLSScan enabled, keep tdls link and allow scan, connectedTdlsPeers: %d"), + connectedTdlsPeers); + return 1; + } + + for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) + { + if (pHddCtx->tdlsConnInfo[staIdx].staId) + { + curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, + pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + if (curr_peer) + { + connectedPeerList[num++] = curr_peer; + if (!(curr_peer->isBufSta)) + allPeersBufStas = 0; + } + } + } + + if ((TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN == + connectedTdlsPeers) && + (pHddCtx->cfg_ini->fEnableTDLSSleepSta) && + (allPeersBufStas)) + { + /* All connected peers bufStas and we can be sleepSta + * so allow scan + */ + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d", + __func__, connectedTdlsPeers, pHddCtx->tdls_mode); + return 1; + } + else + { + for (i = 0; i < num; i++) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: indicate TDLS teadown (staId %d)", + __func__, connectedPeerList[i]->staId); +#ifdef CONFIG_TDLS_IMPLICIT + wlan_hdd_tdls_indicate_teardown( + connectedPeerList[i]->pHddTdlsCtx->pAdapter, + connectedPeerList[i], + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); +#endif + } + } + /* schedule scan */ + delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers); + + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec", + __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter), + delay); + + wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request, + msecs_to_jiffies(delay)); + /* scan should not continue */ + return 0; + } + /* no connected peer, scan continue */ + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: tdls_mode %d, and no tdls connection. scan allowed", + __func__, pHddCtx->tdls_mode); + } + return 1; +} + +void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return; +} + + /* free allocated memory at scan time */ + wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt); + + /* if tdls was enabled before scan, re-enable tdls mode */ + if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last); + + wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE); + } + wlan_hdd_tdls_check_bmps(pAdapter); +} + +void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter, + vos_timer_t *timer, + v_U32_t expirationTime) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* Check whether driver load unload is in progress */ + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + hddLog(LOGE, FL("Driver load/unload is in progress.")); + return; + } + + if (hdd_connIsConnected(pHddStaCtx)) { + vos_timer_stop(timer); + vos_timer_start(timer, expirationTime); + } +} + +void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, + hddTdlsPeer_t *curr_peer, + tANI_U16 reason) +{ + if (NULL == pAdapter || NULL == curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("parameters passed are invalid")); + return; + } + + if (eTDLS_LINK_CONNECTED != curr_peer->link_status) + return; + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_TEARING, + eTDLS_LINK_DROPPED_BY_REMOTE); + cfg80211_tdls_oper_request(pAdapter->dev, + curr_peer->peerMac, + NL80211_TDLS_TEARDOWN, + reason, + GFP_KERNEL); +} + +/*EXT TDLS*/ +int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, + cfg80211_exttdls_callback callback) +{ + hdd_context_t *pHddCtx; + hdd_adapter_t *pAdapter; + + if (!curr_peer) return -1; + + pAdapter = curr_peer->pHddTdlsCtx->pAdapter; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if ((NULL == pHddCtx)) return -1; + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer->state_change_notification = callback; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, + tANI_S32 *state, + tANI_S32 *reason) +{ + *reason = curr_peer->reason; + + switch(curr_peer->link_status) + { + case eTDLS_LINK_IDLE: + case eTDLS_LINK_DISCOVERING: + case eTDLS_LINK_DISCOVERED: + *state = WIFI_TDLS_ENABLED; + break; + case eTDLS_LINK_CONNECTING: + *state = WIFI_TDLS_TRYING; + break; + case eTDLS_LINK_CONNECTED: + *state = WIFI_TDLS_ESTABLISHED; + break; + case eTDLS_LINK_TEARING: + *state = WIFI_TDLS_DROPPED; + break; + } +} + +int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, + tANI_U8* mac, + tANI_S32 *state, + tANI_S32 *reason) +{ + hddTdlsPeer_t *curr_peer; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -EINVAL; + } + + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, state, reason); + return (0); +} + +hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *pAdapter) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer = NULL; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return NULL; + } + mutex_lock(&pHddCtx->tdls_lock); + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) { + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; + } + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (curr_peer && (curr_peer->link_status == eTDLS_LINK_CONNECTED)) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + FL(MAC_ADDRESS_STR "eTDLS_LINK_CONNECTED"), + MAC_ADDR_ARRAY(curr_peer->peerMac)); + return curr_peer; + } + } + } + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; +} + +int hdd_set_tdls_offchannel(hdd_context_t *pHddCtx, int offchannel) +{ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + if (offchannel < CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN || + offchannel > CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls off channel %u"), + offchannel); + return -EINVAL; + } + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Either TDLS or TDLS Off-channel is not enabled")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls off channel from %d to %d"), + pHddCtx->tdls_off_channel, offchannel); + pHddCtx->tdls_off_channel = offchannel; + return 0; +} + +int hdd_set_tdls_secoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset) +{ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + pHddCtx->tdls_channel_offset = 0; + switch (offchanoffset) { + case TDLS_SEC_OFFCHAN_OFFSET_0: + pHddCtx->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: + case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: + pHddCtx->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_80: + pHddCtx->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_160: + pHddCtx->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls secondary off channel offset %d"), + offchanoffset); + return -EINVAL; + }/* end switch */ + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Either TDLS or TDLS Off-channel is not enabled")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls secondary off channel offset to 0x%x"), + pHddCtx->tdls_channel_offset); + return 0; +} + +int hdd_set_tdls_offchannelmode(hdd_adapter_t *pAdapter, int offchanmode) +{ + hddTdlsPeer_t *connPeer = NULL; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tSmeTdlsChanSwitchParams chanSwitchParams; + + if (offchanmode < ENABLE_CHANSWITCH || offchanmode > DISABLE_CHANSWITCH) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls off channel mode %d"), + offchanmode); + return -EINVAL; + } + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("tdls off channel mode req in not associated state %d"), + offchanmode); + return -EPERM; + } + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + connPeer = wlan_hdd_tdls_find_first_connected_peer(pAdapter); + if (NULL == connPeer) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + FL("No TDLS Connected Peer")); + return -EPERM; + } + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + FL("TDLS Connection not supported")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("TDLS Channel Switch in swmode=%d"), + offchanmode); + + switch (offchanmode) { + case ENABLE_CHANSWITCH: + case DISABLE_CHANSWITCH: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls off channel mode %d tdls_off_channel %d offchanoffset %d"), + offchanmode, pHddCtx->tdls_off_channel, + pHddCtx->tdls_channel_offset); + if (pHddCtx->tdls_off_channel && pHddCtx->tdls_channel_offset) { + chanSwitchParams.vdev_id = pAdapter->sessionId; + chanSwitchParams.tdls_off_channel = pHddCtx->tdls_off_channel; + chanSwitchParams.tdls_off_ch_bw_offset = + pHddCtx->tdls_channel_offset; + chanSwitchParams.tdls_off_ch_mode = offchanmode; + chanSwitchParams.is_responder = connPeer->is_responder; + vos_mem_copy(&chanSwitchParams.peer_mac_addr, + &connPeer->peerMac, + sizeof(tSirMacAddr)); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Peer " MAC_ADDRESS_STR "vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d"), + MAC_ADDR_ARRAY(chanSwitchParams.peer_mac_addr), + chanSwitchParams.vdev_id, + chanSwitchParams.tdls_off_channel, + chanSwitchParams.tdls_off_ch_bw_offset, + chanSwitchParams.tdls_off_ch_mode, + chanSwitchParams.is_responder); + + sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + &chanSwitchParams); + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS off-channel parameters are not set yet!!!")); + return -EINVAL; + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d"), + offchanmode, pHddCtx->tdls_off_channel, + pHddCtx->tdls_channel_offset); + break; + }/* end switch */ + return 0; +} + +/** + * hdd_set_tdls_scan_type - set scan during active tdls session + * @hdd_ctx: ptr to hdd context. + * @val: scan type value: 0 or 1. + * + * Set scan type during tdls session. If set to 1, that means driver + * shall maintain tdls link and allow scan regardless if tdls peer is + * buffer sta capable or not and/or if device is sleep sta capable or + * not. If tdls peer is not buffer sta capable then during scan there + * will be loss of Rx packets and Tx would stop when device moves away + * from tdls channel. If set to 0, then driver shall teardown tdls link + * before initiating scan if peer is not buffer sta capable and device + * is not sleep sta capable. By default, scan type is set to 0. + * + * Return: success (0) or failure (errno value) + */ +int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val) +{ + if ((val != 0) && (val != 1)) { + hddLog(LOGE, FL("Incorrect value of tdls scan type: %d"), + val); + return -EINVAL; + } else { + hdd_ctx->cfg_ini->enable_tdls_scan = val; + return 0; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_trace.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_trace.c new file mode 100644 index 0000000000000..f7d683e6522a9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_trace.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + \file wlan_hdd_trace.c + + \brief WLAN Host Device Driver trace implementation + + ========================================================================*/ + +#include "vos_trace.h" +#include "vos_types.h" +#include "wlan_hdd_trace.h" +#include "wlan_hdd_main.h" + +static tANI_U8 *hddTraceGetEventString(tANI_U32 code) +{ + switch (code) { + CASE_RETURN_STRING(TRACE_CODE_HDD_OPEN_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_STOP_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_TX_TIMEOUT); + CASE_RETURN_STRING(TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMDELTA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMDELTA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETBAND_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL); + CASE_RETURN_STRING + (TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_ADD_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_DEL_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_START_AP); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CHANGE_BEACON); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_STOP_AP); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CHANGE_BSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_ADD_KEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_KEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CONNECT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DISCONNECT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_JOIN_IBSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_LEAVE_IBSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_TXPOWER); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_TXPOWER); + CASE_RETURN_STRING(TRACE_CODE_HDD_REMAIN_ON_CHANNEL); + CASE_RETURN_STRING(TRACE_CODE_HDD_REMAINCHANREADYHANDLER); + CASE_RETURN_STRING + (TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL); + CASE_RETURN_STRING(TRACE_CODE_HDD_ACTION); + CASE_RETURN_STRING(TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DEL_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_ADD_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_PMKSA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_TDLS_MGMT); + CASE_RETURN_STRING(TRACE_CODE_HDD_UNSUPPORTED_IOCTL); + CASE_RETURN_STRING + (TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL); + CASE_RETURN_STRING + (TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL); + default: + return ("UNKNOWN"); + break; + } +} + +void hddTraceDump(void *pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) +{ + hddLog(LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", + recIndex, pRecord->time, pRecord->session, + "HDD Event:", hddTraceGetEventString(pRecord->code), + pRecord->data); +} + +void hddTraceInit() +{ + vosTraceRegister(VOS_MODULE_ID_HDD, (tpvosTraceCb) & hddTraceDump); +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tx_rx.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tx_rx.c new file mode 100644 index 0000000000000..ec4940f9cf956 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -0,0 +1,1838 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**=========================================================================== + + \file wlan_hdd_tx_rx.c + + \brief Linux HDD Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +/* Needs to be removed when completely root-caused */ +#define IPV6_MCAST_WAR 1 + +#include +#include +#include +#include +#include +#include +#include +#ifdef IPV6_MCAST_WAR +#include +#endif + +#include +#include +#include +#include +#include "sapApi.h" +#include + +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif + +#ifdef IPA_OFFLOAD +#include +#endif + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +const v_U8_t hddWmmAcToHighestUp[] = { + SME_QOS_WMM_UP_RESV, + SME_QOS_WMM_UP_EE, + SME_QOS_WMM_UP_VI, + SME_QOS_WMM_UP_NC +}; + +//Mapping Linux AC interpretation to TL AC. +const v_U8_t hdd_QdiscAcToTlAC[] = { + WLANTL_AC_VO, + WLANTL_AC_VI, + WLANTL_AC_BE, + WLANTL_AC_BK, +}; + +static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter); + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function definitions and documentation + -------------------------------------------------------------------------*/ + +#ifdef DATA_PATH_UNIT_TEST +//Utility function to dump an sk_buff +static void dump_sk_buff(struct sk_buff * skb) +{ + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len); + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], + skb->data[5], skb->data[6], skb->data[7]); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12], + skb->data[13], skb->data[14], skb->data[15]); +} + +//Function for Unit Test only +static void transport_thread(hdd_adapter_t *pAdapter) +{ + v_U8_t staId; + WLANTL_ACEnumType ac = WLANTL_AC_BE; + vos_pkt_t *pVosPacket = NULL ; + vos_pkt_t dummyPacket; + WLANTL_MetaInfoType pktMetaInfo; + WLANTL_RxMetaInfoType pktRxMetaInfo; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + status = hdd_tx_fetch_packet_cbk( pAdapter->pvosContext, + &staId, + &ac, + &pVosPacket, + &pktMetaInfo ); + if (status != VOS_STATUS_SUCCESS && status != VOS_STATUS_E_EMPTY) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_fetch_packet_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_fetch_packet_cbk", __func__); + + status = hdd_tx_complete_cbk(pAdapter->pvosContext, &dummyPacket, VOS_STATUS_SUCCESS); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_complete_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_complete_cbk", __func__); + + status = hdd_tx_low_resource_cbk(pVosPacket, pAdapter); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_low_resource_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_low_resource_cbk", __func__); + + status = hdd_rx_packet_cbk( pAdapter->pvosContext, + &dummyPacket, + staId, + &pktRxMetaInfo); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_rx_packet_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_rx_packet_cbk", __func__); + +} +#endif + + +/**============================================================================ + @brief hdd_flush_tx_queues() - Utility function to flush the TX queues + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + pAdapter->isVosLowResource = VOS_FALSE; + + while (++i != NUM_TX_QUEUES) + { + //Free up any packets in the Tx queue + spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock); + while (true) + { + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[i], &anchor ); + if(VOS_STATUS_E_EMPTY != status) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + //TODO + //++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + break; + } + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + /* Back pressure is no longer in effect */ + pAdapter->isTxSuspended[i] = VOS_FALSE; + } + + return status; +} + +/**============================================================================ + @brief hdd_flush_ibss_tx_queues() - Utility function to flush the TX queues + in IBSS mode + + @param pAdapter : [in] pointer to adapter context + : [in] Station Id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId) +{ + v_U8_t i; + v_SIZE_t size = 0; + v_U8_t skbStaIdx; + skb_list_node_t *pktNode = NULL; + hdd_list_node_t *tmp = NULL, *next = NULL; + struct netdev_queue *txq; + struct sk_buff *skb = NULL; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL %u"), STAId); + VOS_ASSERT(0); + return; + } + + for (i = 0; i < NUM_TX_QUEUES; i++) + { + spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock); + + if ( list_empty( &pAdapter->wmm_tx_queue[i].anchor ) ) + { + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + continue; + } + + /* Iterate through the queue and identify the data for STAId */ + list_for_each_safe(tmp, next, &pAdapter->wmm_tx_queue[i].anchor) + { + pktNode = list_entry(tmp, skb_list_node_t, anchor); + if (pktNode != NULL) + { + skb = pktNode->skb; + + /* Get the STAId from data */ + skbStaIdx = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1); + if (skbStaIdx == STAId) + { + /* Data for STAId is freed along with the queue node */ + + list_del(tmp); + kfree_skb(skb); + + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + pAdapter->wmm_tx_queue[i].count--; + } + } + } + + /* Restart the queue only-if suspend and the queue was flushed */ + hdd_list_size( &pAdapter->wmm_tx_queue[i], &size ); + txq = netdev_get_tx_queue(pAdapter->dev, i); + + if (VOS_TRUE == pAdapter->isTxSuspended[i] && + size <= HDD_TX_QUEUE_LOW_WATER_MARK && + netif_tx_queue_stopped(txq) ) + { + netif_tx_start_queue(txq); + pAdapter->isTxSuspended[i] = VOS_FALSE; + ++pAdapter->hdd_stats.hddTxRxStats.txDequeDePressured; + ++pAdapter->hdd_stats.hddTxRxStats.txDequeDePressuredAC[i]; + } + + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + } +} + +static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter) +{ + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + v_SIZE_t size = 0; + WLANTL_ACEnumType ac = 0; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_list_node_t *anchor = NULL; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return NULL; + } + + // do we have any packets pending in this AC? + hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); + if( size == 0 ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: NO Packet Pending", __func__); + return NULL; + } + + //Remove the packet from the queue + spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock); + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to remove Packet from the list", + __func__); + + return NULL; + } + + /* If we are in a back pressure situation see if we can turn the + hose back on */ + if ( (pAdapter->isTxSuspended[ac]) && + (size <= HDD_TX_QUEUE_LOW_WATER_MARK) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: TX queue[%d] re-enabled", __func__, ac); + pAdapter->isTxSuspended[ac] = VOS_FALSE; + /* Enable Queues which we have disabled earlier */ + netif_tx_start_all_queues( pAdapter->dev ); + } + + return skb; +} + +static void __hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter) +{ + hdd_cfg80211_state_t *cfgState; + struct sk_buff* skb; + hdd_adapter_t* pMonAdapter = NULL; + struct ieee80211_hdr *hdr; + hdd_context_t *hdd_ctx; + int ret = 0; + + if (pAdapter == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + + hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return; + } + + pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR ); + if (pMonAdapter == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: pMonAdapter is NULL", __func__); + return; + } + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if( NULL != cfgState->buf ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Already one MGMT packet Tx going on", __func__); + return; + } + + skb = hdd_mon_tx_fetch_pkt(pMonAdapter); + + if (NULL == skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: No Packet Pending", __func__); + return; + } + + cfgState->buf = vos_mem_malloc( skb->len ); //buf; + if( cfgState->buf == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Allocate memory", __func__); + goto fail; + } + + cfgState->len = skb->len; + + vos_mem_copy( cfgState->buf, skb->data, skb->len); + + cfgState->skb = skb; //buf; + cfgState->action_cookie = (uintptr_t)cfgState->buf; + + hdr = (struct ieee80211_hdr *)skb->data; + if( (hdr->frame_control & HDD_FRAME_TYPE_MASK) + == HDD_FRAME_TYPE_MGMT ) + { + if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK) + == HDD_FRAME_SUBTYPE_DEAUTH ) + { + hdd_softap_sta_deauth( pAdapter, hdr->addr1 ); + goto mgmt_handled; + } + else if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK) + == HDD_FRAME_SUBTYPE_DISASSOC ) + { + hdd_softap_sta_disassoc( pAdapter, hdr->addr1 ); + goto mgmt_handled; + } + } + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Sending action frame to SAP to TX, Len %d", __func__, skb->len); + + if (VOS_STATUS_SUCCESS != +#ifdef WLAN_FEATURE_MBSSID + WLANSAP_SendAction( pAdapter->sessionCtx.ap.sapContext, +#else + WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, +#endif + skb->data, skb->len, 0) ) + + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SendAction returned fail", __func__); + hdd_sendActionCnf( pAdapter, FALSE ); + } + return; + +mgmt_handled: + hdd_sendActionCnf( pAdapter, TRUE ); + return; +fail: + kfree_skb(pAdapter->skb_to_tx); + pAdapter->skb_to_tx = NULL; + return; +} + +/** + * hdd_mon_tx_mgmt_pkt() - monitor mode tx packet api + * @adapter: Pointer to adapter + * + * Return: none + */ +void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* adapter) +{ + vos_ssr_protect(__func__); + __hdd_mon_tx_mgmt_pkt(adapter); + vos_ssr_unprotect(__func__); +} + +static void __hdd_mon_tx_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = container_of(work, hdd_adapter_t, monTxWorkQueue); + __hdd_mon_tx_mgmt_pkt(pAdapter); +} + +/** + * hdd_mon_tx_work_queue() - monitor mode tx work handler + * @work: Pointer to work + * + * Return: none + */ +void hdd_mon_tx_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_mon_tx_work_queue(work); + vos_ssr_unprotect(__func__); +} + +int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + v_U16_t rt_hdr_len; + struct ieee80211_hdr *hdr; + hdd_adapter_t *pPgBkAdapter, *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct ieee80211_radiotap_header *rtap_hdr = + (struct ieee80211_radiotap_header *)skb->data; + + /*Supplicant sends the EAPOL packet on monitor interface*/ + pPgBkAdapter = pAdapter->sessionCtx.monitor.pAdapterForTx; + if(pPgBkAdapter == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: No Adapter to piggy back. Dropping the pkt on monitor inf", + __func__); + goto fail; /* too short to be possibly valid */ + } + + /* Check if total skb length is greater then radio tap + header length of not */ + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) + goto fail; /* too short to be possibly valid */ + + /* check if radio tap header version is correct or not */ + if (unlikely(rtap_hdr->it_version)) + goto fail; /* only version 0 is supported */ + + /*Strip off the radio tap header*/ + rt_hdr_len = ieee80211_get_radiotap_len(skb->data); + + /* Check if skb length if greater then total radio tap header length ot not*/ + if (unlikely(skb->len < rt_hdr_len)) + goto fail; + + /* Update the trans_start for this netdev */ + dev->trans_start = jiffies; + /* + * fix up the pointers accounting for the radiotap + * header still being in there. + */ + skb_set_mac_header(skb, rt_hdr_len); + skb_set_network_header(skb, rt_hdr_len); + skb_set_transport_header(skb, rt_hdr_len); + + /* Pull rtap header out of the skb */ + skb_pull(skb, rt_hdr_len); + + /*Supplicant adds: radiotap Hdr + radiotap data + 80211 Header. So after + * radio tap header and 802.11 header starts + */ + hdr = (struct ieee80211_hdr *)skb->data; + + /* Send data frames through the normal Data path. In this path we will + * convert rcvd 802.11 packet to 802.3 packet */ + if ( (hdr->frame_control & HDD_FRAME_TYPE_MASK) == HDD_FRAME_TYPE_DATA) + { + v_U8_t da[6]; + v_U8_t sa[6]; + + memcpy (da, hdr->addr1, VOS_MAC_ADDR_SIZE); + memcpy (sa, hdr->addr2, VOS_MAC_ADDR_SIZE); + + /* Pull 802.11 MAC header */ + skb_pull(skb, HDD_80211_HEADER_LEN); + + if ( HDD_FRAME_SUBTYPE_QOSDATA == + (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)) + { + skb_pull(skb, HDD_80211_HEADER_QOS_CTL); + } + + /* Pull LLC header */ + skb_pull(skb, HDD_LLC_HDR_LEN); + + /* Create space for Ethernet header */ + skb_push(skb, HDD_MAC_HDR_SIZE*2); + memcpy(&skb->data[0], da, HDD_MAC_HDR_SIZE); + memcpy(&skb->data[HDD_DEST_ADDR_OFFSET], sa, HDD_MAC_HDR_SIZE); + + /* Only EAPOL Data packets are allowed through monitor interface */ + if (vos_be16_to_cpu( + (*(unsigned short*)&skb->data[HDD_ETHERTYPE_802_1_X_FRAME_OFFSET]) ) + != HDD_ETHERTYPE_802_1_X) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: Not a Eapol packet. Drop this frame", __func__); + //If not EAPOL frames, drop them. + kfree_skb(skb); + return NETDEV_TX_OK; + } + + skb->protocol = htons(HDD_ETHERTYPE_802_1_X); + + hdd_hostapd_select_queue(pPgBkAdapter->dev, skb); + return hdd_softap_hard_start_xmit( skb, pPgBkAdapter->dev ); + } + else + { + VOS_STATUS status; + WLANTL_ACEnumType ac = 0; + skb_list_node_t *pktNode = NULL; + v_SIZE_t pktListSize = 0; + + spin_lock(&pAdapter->wmm_tx_queue[ac].lock); + //If we have already reached the max queue size, disable the TX queue + if ( pAdapter->wmm_tx_queue[ac].count == pAdapter->wmm_tx_queue[ac].max_size) + { + /* We want to process one packet at a time, so lets disable all TX queues + * and re-enable the queues once we get TX feedback for this packet */ + netif_tx_stop_all_queues(pAdapter->dev); + pAdapter->isTxSuspended[ac] = VOS_TRUE; + spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); + return NETDEV_TX_BUSY; + } + spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + INIT_LIST_HEAD(&pktNode->anchor); + + //Insert the OS packet into the appropriate AC queue + spin_lock(&pAdapter->wmm_tx_queue[ac].lock); + status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[ac], + &pktNode->anchor, &pktListSize ); + spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s:Insert Tx queue failed. Pkt dropped", __func__); + kfree_skb(skb); + return NETDEV_TX_OK; + } + + if (pktListSize == 1) { + /* + * In this context we cannot acquire any mutex etc. And to transmit + * this packet we need to call SME API. So to take care of this we will + * schedule a work queue + */ + schedule_work(&pPgBkAdapter->monTxWorkQueue); + } + return NETDEV_TX_OK; + } + +fail: + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Packet Rcvd at Monitor interface is not proper," + " Dropping the packet", + __func__); + kfree_skb(skb); + return NETDEV_TX_OK; +} + +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_tx_resume_timer_expired_handler() - Resume OS TX Q timer expired + handler. + If Blocked OS Q is not resumed during timeout period, to prevent + permanent stall, resume OS Q forcefully. + + @param adapter_context : [in] pointer to vdev adapter + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_timer_expired_handler(void *adapter_context) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context; + + if (!pAdapter) + { + /* INVALID ARG */ + return; + } + + netif_tx_wake_all_queues(pAdapter->dev); + return; +} + +/**============================================================================ + @brief hdd_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev adapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_cb(void *adapter_context, + v_BOOL_t tx_resume) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context; + hdd_station_ctx_t *hdd_sta_ctx = NULL; + + if (!pAdapter) + { + /* INVALID ARG */ + return; + } + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* Resume TX */ + if (VOS_TRUE == tx_resume) + { + if (VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) + { + vos_timer_stop(&pAdapter->tx_flow_control_timer); + } + if (adf_os_unlikely(hdd_sta_ctx->hdd_ReassocScenario)) { + hddLog(LOGW, + FL("flow control, tx queues un-pause avoided as we are in REASSOCIATING state")); + return; + } + netif_tx_wake_all_queues(pAdapter->dev); + } +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + else if (VOS_FALSE == tx_resume) /* Pause TX */ + { + netif_tx_stop_all_queues(pAdapter->dev); + if (VOS_TIMER_STATE_STOPPED == + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer)) + { + VOS_STATUS status; + status = vos_timer_start(&pAdapter->tx_flow_control_timer, + WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + if ( !VOS_IS_STATUS_SUCCESS(status) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start tx_flow_control_timer", __func__); + } + } + } +#endif + + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + +/**============================================================================ + @brief hdd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets. This version of the function directly passes the packet + to Transport Layer. + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued successfully + ===========================================================================*/ +int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + VOS_STATUS status; + WLANTL_ACEnumType ac; + sme_QosWmmUpType up; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_BOOL_t granted; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; +#ifdef QCA_PKT_PROTO_TRACE + hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter); + v_U8_t proto_type = 0; +#endif /* QCA_PKT_PROTO_TRACE */ + +#ifdef QCA_WIFI_FTM + if (hdd_get_conparam() == VOS_FTM_MODE) { + kfree_skb(skb); + return NETDEV_TX_OK; + } +#endif + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + if (WLAN_HDD_IBSS == pAdapter->device_mode) + { + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + + STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1); + + if ((STAId == HDD_WLAN_INVALID_STA_ID) && + (vos_is_macaddr_broadcast( pDestMacAddress ) || + vos_is_macaddr_group(pDestMacAddress))) + { + STAId = IBSS_BROADCAST_STAID; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: BC/MC packet", __func__); + } + else if (STAId == HDD_WLAN_INVALID_STA_ID) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Received Unicast frame with invalid staID", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + return NETDEV_TX_OK; + } + } + else + { + STAId = pHddStaCtx->conn_info.staId[0]; + } + +#ifdef QCA_LL_TX_FLOW_CT + if (VOS_FALSE == + WLANTL_GetTxResource((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pAdapter->sessionId, + pAdapter->tx_flow_low_watermark, + pAdapter->tx_flow_high_watermark_offset)) { + netif_tx_stop_all_queues(dev); + if ((pAdapter->tx_flow_timer_initialized == TRUE) && + (VOS_TIMER_STATE_STOPPED == + vos_timer_getCurrentState(&pAdapter->tx_flow_control_timer))) { + vos_timer_start(&pAdapter->tx_flow_control_timer, + WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); + } + } +#endif /* QCA_LL_TX_FLOW_CT */ + + //Get TL AC corresponding to Qdisc queue index/AC. + ac = hdd_QdiscAcToTlAC[skb->queue_mapping]; + +#ifdef IPA_OFFLOAD + if(!(NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID)) { +#endif + + /* Check if the buffer has enough header room */ + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) + goto drop_pkt; + + if (skb_headroom(skb) < dev->hard_header_len) { + struct sk_buff *tmp; + tmp = skb; + skb = skb_realloc_headroom(tmp, dev->hard_header_len); + dev_kfree_skb(tmp); + if (!skb) + goto drop_pkt; + } +#ifdef IPA_OFFLOAD + } +#endif + //user priority from IP header, which is already extracted and set from + //select_queue call back function + up = skb->priority; + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: Classified as ac %d up %d", __func__, ac, up); +#endif // HDD_WMM_DEBUG + + if (HDD_PSB_CHANGED == pAdapter->psbChanged) + { + /* Function which will determine acquire admittance for a + * WMM AC is required or not based on psb configuration done + * in the framework + */ + hdd_wmm_acquire_access_required(pAdapter, ac); + } + + //Make sure we have access to this access category + if (((pAdapter->psbChanged & (1 << ac)) && likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) || + (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE)) + { + granted = VOS_TRUE; + } + else + { + status = hdd_wmm_acquire_access( pAdapter, ac, &granted ); + pAdapter->psbChanged |= (1 << ac); + } + + if (!granted) { + bool isDefaultAc = VOS_FALSE; + /* ADDTS request for this AC is sent, for now + * send this packet through next available lower + * Access category until ADDTS negotiation completes. + */ + while (!likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) { + switch(ac) { + case WLANTL_AC_VO: + ac = WLANTL_AC_VI; + up = SME_QOS_WMM_UP_VI; + break; + case WLANTL_AC_VI: + ac = WLANTL_AC_BE; + up = SME_QOS_WMM_UP_BE; + break; + case WLANTL_AC_BE: + ac = WLANTL_AC_BK; + up = SME_QOS_WMM_UP_BK; + break; + default: + ac = WLANTL_AC_BK; + up = SME_QOS_WMM_UP_BK; + isDefaultAc = VOS_TRUE; + break; + } + if (isDefaultAc) + break; + } + skb->priority = up; + skb->queue_mapping = hddLinuxUpToAcMap[up]; + } + +#ifdef QCA_PKT_PROTO_TRACE + if ((hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || + (hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) + { + proto_type = vos_pkt_get_proto_type(skb, + hddCtxt->cfg_ini->gEnableDebugLog, 0); + if (VOS_PKT_TRAC_TYPE_EAPOL & proto_type) + { + vos_pkt_trace_buf_update("ST:T:EPL"); + } + else if (VOS_PKT_TRAC_TYPE_DHCP & proto_type) + { + vos_pkt_trace_buf_update("ST:T:DHC"); + } + } +#endif /* QCA_PKT_PROTO_TRACE */ + + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count; + + /* + * TODO: Should we stop net queues when txrx returns non-NULL?. + */ + if (WLANTL_SendSTA_DataFrame((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, (adf_nbuf_t) skb +#ifdef QCA_PKT_PROTO_TRACE + , proto_type +#endif /* QCA_PKT_PROTO_TRACE */ + ) != NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to send packet to txrx for staid:%d", + __func__, STAId); + goto drop_pkt; + } + + dev->trans_start = jiffies; + + return NETDEV_TX_OK; + +drop_pkt: + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + kfree_skb(skb); + return NETDEV_TX_OK; +} + +/**============================================================================ + @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address + + @param pHddStaCtx : [in] pointer to HDD Station Context + pMacAddress [in] pointer to Peer Mac address + staID [out] pointer to Station Index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ + +VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAddress, v_U8_t *staId) +{ + v_U8_t idx; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) + { + if (vos_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[ idx ], + pMacAddress, sizeof(v_MACADDR_t))) + { + *staId = pHddStaCtx->conn_info.staId[idx]; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} + +/**============================================================================ + @brief hdd_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +void hdd_tx_timeout(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct netdev_queue *txq; + int i = 0; + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred", __func__); + //Getting here implies we disabled the TX queues for too long. Queues are + //disabled either because of disassociation or low resource scenarios. In + //case of disassociation it is ok to ignore this. But if associated, we have + //do possible recovery here + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d", + pAdapter->wmm_tx_queue[0].count, + pAdapter->wmm_tx_queue[1].count, + pAdapter->wmm_tx_queue[2].count, + pAdapter->wmm_tx_queue[3].count); + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "tx_suspend AC0: %d AC1: %d AC2: %d AC3: %d", + pAdapter->isTxSuspended[0], + pAdapter->isTxSuspended[1], + pAdapter->isTxSuspended[2], + pAdapter->isTxSuspended[3]); + + for (i = 0; i < 8; i++) + { + txq = netdev_get_tx_queue(dev, i); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "Queue%d status: %d", i, netif_tx_queue_stopped(txq)); + } + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "carrier state: %d", netif_carrier_ok(dev)); +} + + +/**============================================================================ + @brief hdd_stats() - Function registered with the Linux OS for + device TX/RX statistic + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +struct net_device_stats* hdd_stats(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + return &pAdapter->stats; +} + + +/**============================================================================ + @brief hdd_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + pAdapter->isVosOutOfResource = VOS_FALSE; + pAdapter->isVosLowResource = VOS_FALSE; + + //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats)); + //Will be zeroed out during alloc + + while (++i != NUM_TX_QUEUES) + { + pAdapter->isTxSuspended[i] = VOS_FALSE; + hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + + return status; +} + + +/**============================================================================ + @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + status = hdd_flush_tx_queues(pAdapter); + if (VOS_STATUS_SUCCESS != status) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + FL("failed to flush tx queues")); + + while (++i != NUM_TX_QUEUES) + { + //Free up actual list elements in the Tx queue + hdd_list_destroy( &pAdapter->wmm_tx_queue[i] ); + } + + return status; +} + + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter ) +{ + return hdd_flush_tx_queues(pAdapter); +} + + +/**============================================================================ + @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is EAPOL + : VOS_FALSE otherwise + ===========================================================================*/ + +v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_BOOL_t fEAPOL = VOS_FALSE; + void *pBuffer = NULL; + + + vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, + &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); + if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + if (pBuffer && vos_be16_to_cpu( *(unsigned short*)pBuffer) == HDD_ETHERTYPE_802_1_X ) + { + fEAPOL = VOS_TRUE; + } + } + + return fEAPOL; +} + + +#ifdef FEATURE_WLAN_WAPI // Need to update this function +/**============================================================================ + @brief hdd_IsWAIPacket() - Checks the packet is WAI or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is WAI + : VOS_FALSE otherwise + ===========================================================================*/ + +v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_BOOL_t fIsWAI = VOS_FALSE; + void *pBuffer = NULL; + + // Need to update this function + vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, + &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); + + if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + if (pBuffer && vos_be16_to_cpu( *((unsigned short*)pBuffer)) == HDD_ETHERTYPE_WAI) + { + fIsWAI = VOS_TRUE; + } + } + + return fIsWAI; +} +#endif /* FEATURE_WLAN_WAPI */ + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + successfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + void* pOsPkt = NULL; + + if( ( NULL == vosContext ) || ( NULL == pVosPacket ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE ); + if (!VOS_IS_STATUS_SUCCESS( status )) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + //Get the Adapter context. + pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_INFRA_STATION); + if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + hddLog(LOG1, FL("Invalid adapter %p"), pAdapter); + else + ++pAdapter->hdd_stats.hddTxRxStats.txCompleted; + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + status = vos_pkt_return_packet( pVosPacket ); + if (!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Could not return VOS packet to the pool", __func__); + } + + return status; +} + + +/**============================================================================ + @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ac : [in] access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ac, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + vos_pkt_t *pVosPacket = NULL; + v_MACADDR_t* pDestMacAddress = NULL; + v_TIME_t timestamp; + WLANTL_ACEnumType newAc; + v_SIZE_t size = 0; + tANI_U8 acAdmitted, i; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pStaId ) || + ( NULL == ppVosPacket ) || + ( NULL == pPktMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Null Params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if(pHddCtx == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[*pStaId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + hddLog(LOGE, FL("Invalid adapter %p staId %u"), pAdapter, *pStaId); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetched; + + *ppVosPacket = NULL; + + //Make sure the AC being asked for is sane + if( ac >= WLANTL_MAX_AC || ac < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d passed by TL", __func__, ac); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: AC %d passed by TL", __func__, ac); +#endif // HDD_WMM_DEBUG + + // We find an AC with packets + // or we determine we have no more packets to send + // HDD is not allowed to change AC. + + // has this AC been admitted? or + // To allow EAPOL packets when not authenticated + if (unlikely((0==pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed) && + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.uIsAuthenticated)) + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty; +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: no packets pending", __func__); +#endif // HDD_WMM_DEBUG + return VOS_STATUS_E_FAILURE; + } + + // do we have any packets pending in this AC? + hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); + if( size > 0 ) + { + // yes, so process it +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: AC %d has packets pending", __func__, ac); +#endif // HDD_WMM_DEBUG + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty; +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: no packets pending", __func__); +#endif // HDD_WMM_DEBUG + return VOS_STATUS_E_FAILURE; + } + + //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources + //This simplifies the locking and unlocking of Tx queue + status = vos_pkt_wrap_data_packet( &pVosPacket, + VOS_PKT_TYPE_TX_802_3_DATA, + NULL, //OS Pkt is not being passed + hdd_tx_low_resource_cbk, + pAdapter ); + + if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES) + { + //Remember VOS is in a low resource situation + pAdapter->isVosOutOfResource = VOS_TRUE; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOSS in Low Resource scenario", __func__); + //TL will now think we have no more packets in this AC + return VOS_STATUS_E_FAILURE; + } + + //Remove the packet from the queue + spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock); + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, "%s: Error in de-queuing " + "skb from Tx queue status = %d", __func__, status ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + + //Attach skb to VOS packet. + status = vos_pkt_set_os_packet( pVosPacket, skb ); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__); + vos_pkt_return_packet(pVosPacket); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Just being paranoid. To be removed later + if(pVosPacket == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOS packet returned by VOSS is NULL", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + +#ifdef FEATURE_WLAN_TDLS + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) + { + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + u8 mac[6]; + + wlan_hdd_tdls_extract_da(skb, mac); + + if (vos_is_macaddr_group((v_MACADDR_t *)mac)) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED, + "broadcast packet, not adding to peer list"); + } else if (memcmp(pHddStaCtx->conn_info.bssId, + mac, 6) != 0) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED, + "extract mac: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(mac) ); + + wlan_hdd_tdls_increment_pkt_count(pAdapter, mac, 1); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED, + "packet da is bssid, not adding to peer list"); + } + } +#endif + + //Return VOS packet to TL; + *ppVosPacket = pVosPacket; + + //Fill out the meta information needed by TL + //FIXME This timestamp is really the time stamp of wrap_data_packet + vos_pkt_get_timestamp( pVosPacket, ×tamp ); + pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp; + + if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE) + pPktMetaInfo->ucIsEapol = 0; + else + pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0; + +#ifdef FEATURE_WLAN_WAPI + // Override usIsEapol value when its zero for WAPI case + pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0; +#endif /* FEATURE_WLAN_WAPI */ + + if ((HDD_WMM_USER_MODE_NO_QOS == pHddCtx->cfg_ini->WmmMode) || + (!pAdapter->hddWmmStatus.wmmQap)) + { + // either we don't want QoS or the AP doesn't support QoS + pPktMetaInfo->ucUP = 0; + pPktMetaInfo->ucTID = 0; + } + else + { + /* 1. Check if ACM is set for this AC + * 2. If set, check if this AC had already admitted + * 3. If not already admitted, downgrade the UP to next best UP */ + if(!pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired || + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid) + { + pPktMetaInfo->ucUP = pktNode->userPriority; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + } + else + { + //Downgrade the UP + acAdmitted = pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid; + newAc = WLANTL_AC_BK; + for (i=ac-1; i>0; i--) + { + if (pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessRequired == 0) + { + newAc = i; + break; + } + } + pPktMetaInfo->ucUP = hddWmmAcToHighestUp[newAc]; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,"Downgrading UP %d to UP %d ", pktNode->userPriority, pPktMetaInfo->ucUP); + } + } + + pPktMetaInfo->ucType = 0; //FIXME Don't know what this is + pPktMetaInfo->ucDisableFrmXtl = 0; //802.3 frame so we need to xlate + if ( 1 < size ) + { + pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send + } + else + { + pPktMetaInfo->bMorePackets = 0; + } + + //Extract the destination address from ethernet frame + pDestMacAddress = (v_MACADDR_t*)skb->data; + pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0; + pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0; + + + + /* If we are in a back pressure situation see if we can turn the + hose back on */ + if ( (pAdapter->isTxSuspended[ac]) && + (size <= HDD_TX_QUEUE_LOW_WATER_MARK) ) + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressured; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressuredAC[ac]; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue[%d] re-enabled", __func__, ac); + pAdapter->isTxSuspended[ac] = VOS_FALSE; + netif_tx_wake_queue(netdev_get_tx_queue(pAdapter->dev, + skb_get_queue_mapping(skb) )); + } + + + // We're giving the packet to TL so consider it transmitted from + // a statistics perspective. We account for it here instead of + // when the packet is returned for two reasons. First, TL will + // manipulate the skb to the point where the len field is not + // accurate, leading to inaccurate byte counts if we account for + // it later. Second, TL does not provide any feedback as to + // whether or not the packet was successfully sent over the air, + // so the packet counts will be the same regardless of where we + // account for them + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac]; + + if((pHddCtx->cfg_ini->thermalMitigationEnable) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) + { + if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Tm Lock fail", __func__); + return VOS_STATUS_E_FAILURE; + } + if(WLAN_HDD_TM_LEVEL_1 < pHddCtx->tmInfo.currentTmLevel) + { + if(0 == pHddCtx->tmInfo.txFrameCount) + { + /* Just recovered from sleep timeout */ + pHddCtx->tmInfo.lastOpenTs = timestamp; + } + + if((VOS_FALSE == pHddCtx->tmInfo.qBlocked) && + ((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) && + (pHddCtx->tmInfo.txFrameCount >= pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold)) + { + /* During TX open duration, TX frame count is larger than threshold + * Block TX during Sleep time */ + netif_tx_stop_all_queues(pAdapter->dev); + pHddCtx->tmInfo.qBlocked = VOS_TRUE; + pHddCtx->tmInfo.lastblockTs = timestamp; + if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer)) + { + vos_timer_start(&pHddCtx->tmInfo.txSleepTimer, pHddCtx->tmInfo.tmAction.txSleepDuration); + } + } + else if(((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) && + (pHddCtx->tmInfo.txFrameCount < pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold)) + { + /* During TX open duration, TX frame count is less than threshold + * Reset count and timestamp to prepare next cycle */ + pHddCtx->tmInfo.lastOpenTs = timestamp; + pHddCtx->tmInfo.txFrameCount = 0; + } + else + { + /* Do Nothing */ + } + pHddCtx->tmInfo.txFrameCount++; + } + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + } + + +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,"%s: Valid VOS PKT returned to TL", __func__); +#endif // HDD_WMM_DEBUG + + return status; +} + + +/**============================================================================ + @brief hdd_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ) +{ + VOS_STATUS status; + v_SINT_t i = 0; + v_SIZE_t size = 0; + hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + hddLog(LOGE, FL("Invalid adpater %p"), pAdapter); + return VOS_STATUS_E_FAILURE; + } + + //Return the packet to VOS. We just needed to know that VOS is out of low resource + //situation. Here we will only signal TL that there is a pending data for a STA. + //VOS packet will be requested (if needed) when TL comes back to fetch data. + vos_pkt_return_packet( pVosPacket ); + + pAdapter->isVosOutOfResource = VOS_FALSE; + + //Indicate to TL that there is pending data if a queue is non empty + for( i=NUM_TX_QUEUES-1; i>=0; --i ) + { + size = 0; + hdd_list_size( &pAdapter->wmm_tx_queue[i], &size ); + if ( size > 0 ) + { + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId [0], + (WLANTL_ACEnumType)i ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failure in indicating pkt to TL for ac=%d", __func__,i); + } + } + } + + return VOS_STATUS_SUCCESS; +} + +#ifdef IPV6_MCAST_WAR +/* + * Return TRUE if the packet is to be dropped + */ +static inline +bool drop_ip6_mcast(struct sk_buff *skb) +{ + struct ethhdr *eth; + + eth = eth_hdr(skb); + if (unlikely(skb->pkt_type == PACKET_MULTICAST)) { + if (unlikely(ether_addr_equal(eth->h_source, skb->dev->dev_addr))) + return true; + } + return false; +} +#else +#define drop_ip6_mcast(_a) 0 +#endif + + + +/**============================================================================ + @brief hdd_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when one or more packets were + received for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station Id + @param rxBuf : [in] pointer to rx adf_nbuf + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_rx_packet_cbk(v_VOID_t *vosContext, + adf_nbuf_t rxBuf, v_U8_t staId) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + int rxstat; + struct sk_buff *skb = NULL; + struct sk_buff *skb_next; +#ifdef QCA_PKT_PROTO_TRACE + v_U8_t proto_type; +#endif /* QCA_PKT_PROTO_TRACE */ + hdd_station_ctx_t *pHddStaCtx = NULL; + + //Sanity check on inputs + if ((NULL == vosContext) || (NULL == rxBuf)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[staId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { + hddLog(LOGE, FL("invalid adapter %p for sta Id %d"), pAdapter, staId); + return VOS_STATUS_E_FAILURE; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "Magic cookie(%x) for adapter sanity verification is invalid", + pAdapter->magic); + return VOS_STATUS_E_FAILURE; + } + ++pAdapter->hdd_stats.hddTxRxStats.rxChains; + + // walk the chain until all are processed + skb = (struct sk_buff *) rxBuf; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + while (NULL != skb) { + skb_next = skb->next; + + if ((pHddStaCtx->conn_info.proxyARPService) && + cfg80211_is_gratuitous_arp_unsolicited_na(skb)) { + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Dropping HS 2.0 Gratuitous ARP or Unsolicited NA", __func__); + kfree_skb(skb); + + skb = skb_next; + continue; + } + +#ifdef QCA_PKT_PROTO_TRACE + if ((pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog, 0); + if (VOS_PKT_TRAC_TYPE_EAPOL & proto_type) + vos_pkt_trace_buf_update("ST:R:EPL"); + else if (VOS_PKT_TRAC_TYPE_DHCP & proto_type) + vos_pkt_trace_buf_update("ST:R:DHC"); + } +#endif /* QCA_PKT_PROTO_TRACE */ + + skb->dev = pAdapter->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + + /* Check & drop mcast packets (for IPV6) as required */ + if (drop_ip6_mcast(skb)) { + print_hex_dump_bytes("MAC Header", + DUMP_PREFIX_NONE, skb_mac_header(skb), 16); + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Dropping multicast to self NA", __func__); + kfree_skb(skb); + + skb = skb_next; + continue; + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxPackets; + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += skb->len; + + /* + * If this is not a last packet on the chain + * Just put packet into backlog queue, not scheduling RX sirq + */ + if (skb->next) { + rxstat = netif_rx(skb); + } else { +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION); +#endif + /* + * This is the last packet on the chain + * Scheduling rx sirq + */ + rxstat = netif_rx_ni(skb); + } + + if (NET_RX_SUCCESS == rxstat) + ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered; + else + ++pAdapter->hdd_stats.hddTxRxStats.rxRefused; + + skb = skb_next; + } + + pAdapter->dev->last_rx = jiffies; + + return VOS_STATUS_SUCCESS; +} + + +/**============================================================================ + @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() - + Enable/Disable split scan based on TX and RX traffic. + @param HddContext : [in] pointer to Hdd context + @return : None + ===========================================================================*/ +void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx) +{ + +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c new file mode 100644 index 0000000000000..e52008e7242bb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c @@ -0,0 +1,11001 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** ------------------------------------------------------------------------ * + ------------------------------------------------------------------------ * + + + \file wlan_hdd_wext.c + + \brief Airgo Linux Wireless Extensions Common Control Plane Types and + interfaces. + + $Id: wlan_hdd_wext.c,v 1.34 2007/04/14 01:49:23 jimz Exp jimz $This file defines all of the types that are utilized by the CCP module + of the "Portable" HDD. This file also includes the underlying Linux + Wireless Extensions Data types referred to by CCP. + + ======================================================================== */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include +#endif +#include +#include +#include "ccmApi.h" +#include "sirParams.h" +#include "csrApi.h" +#include "csrInsideApi.h" +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#endif +#include +#include "dot11f.h" +#include +#include +#include +#include "utilsApi.h" +#include "wlan_hdd_p2p.h" +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif + +#include "ieee80211_common.h" +#include "ol_if_athvar.h" +#include "dbglog_host.h" +#include "wma.h" + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include "wlan_hdd_power.h" +#include "qwlan_version.h" +#include "wlan_hdd_host_offload.h" +#include "wlan_hdd_keep_alive.h" +#ifdef WLAN_FEATURE_PACKET_FILTERING +#include "wlan_hdd_packet_filtering.h" +#endif + +#include +#include +#include "wlan_qct_tl.h" + +#include "wlan_hdd_misc.h" +#include "bap_hdd_misc.h" + +#include "wlan_hdd_dev_pwr.h" +#include "qc_sap_ioctl.h" +#include "sme_Api.h" +#include "wlan_qct_wda.h" +#include "vos_trace.h" +#include "wlan_hdd_assoc.h" + +#ifdef QCA_PKT_PROTO_TRACE +#include "vos_packet.h" +#endif /* QCA_PKT_PROTO_TRACE */ + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include "wlan_hdd_cfg80211.h" +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT +#define MAX_OEM_DATA_RSP_LEN 2047 +#endif + +#define HDD_FINISH_ULA_TIME_OUT 800 +#define HDD_SET_MCBC_FILTERS_TO_FW 1 +#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0 + +extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); +static int ioctl_debug; +module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +/* To Validate Channel against the Frequency and Vice-Versa */ +static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, + {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8}, + {2452, 9}, {2457, 10}, {2462, 11}, {2467 ,12}, {2472, 13}, + {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248}, {4980, 252}, + {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36}, {5200, 40}, {5220, 44}, + {5240, 48}, {5260, 52}, {5280, 56}, {5300, 60}, {5320, 64}, {5500, 100}, + {5520, 104}, {5540, 108}, {5560, 112}, {5580, 116}, {5600, 120}, + {5620, 124}, {5640, 128}, {5660, 132}, {5680, 136}, {5700, 140}, + {5720, 144}, {5745, 149}, {5765, 153}, {5785, 157}, {5805, 161}, + {5825, 165} }; + +#define FREQ_CHAN_MAP_TABLE_SIZE (sizeof(freq_chan_map)/sizeof(freq_chan_map[0])) + +#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7) +#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) + +#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf) +#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0) +#define WE_SET_11D_STATE 1 +#define WE_WOWL 2 +#define WE_SET_POWER 3 +#define WE_SET_MAX_ASSOC 4 +#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 5 +#define WE_SET_DATA_INACTIVITY_TO 6 +#define WE_SET_MAX_TX_POWER 7 +#define WE_SET_HIGHER_DTIM_TRANSITION 8 +#define WE_SET_TM_LEVEL 9 +#define WE_SET_PHYMODE 10 +#define WE_SET_NSS 11 +#define WE_SET_LDPC 12 +#define WE_SET_TX_STBC 13 +#define WE_SET_RX_STBC 14 +#define WE_SET_SHORT_GI 15 +#define WE_SET_RTSCTS 16 +#define WE_SET_CHWIDTH 17 +#define WE_SET_ANI_EN_DIS 18 +#define WE_SET_ANI_POLL_PERIOD 19 +#define WE_SET_ANI_LISTEN_PERIOD 20 +#define WE_SET_ANI_OFDM_LEVEL 21 +#define WE_SET_ANI_CCK_LEVEL 22 +#define WE_SET_DYNAMIC_BW 23 +#define WE_SET_TX_CHAINMASK 24 +#define WE_SET_RX_CHAINMASK 25 +#define WE_SET_11N_RATE 26 +#define WE_SET_AMPDU 27 +#define WE_SET_AMSDU 28 +#define WE_SET_TXPOW_2G 29 +#define WE_SET_TXPOW_5G 30 +/* Private ioctl for firmware debug log */ +#define WE_DBGLOG_LOG_LEVEL 31 +#define WE_DBGLOG_VAP_ENABLE 32 +#define WE_DBGLOG_VAP_DISABLE 33 +#define WE_DBGLOG_MODULE_ENABLE 34 +#define WE_DBGLOG_MODULE_DISABLE 35 +#define WE_DBGLOG_MOD_LOG_LEVEL 36 +#define WE_DBGLOG_TYPE 37 +#define WE_SET_TXRX_FWSTATS 38 +#define WE_SET_VHT_RATE 39 +#define WE_DBGLOG_REPORT_ENABLE 40 +#define WE_TXRX_FWSTATS_RESET 41 +#define WE_SET_MAX_TX_POWER_2_4 42 +#define WE_SET_MAX_TX_POWER_5_0 43 +#define WE_SET_POWER_GATING 44 +/* Private ioctl for packet power save */ +#define WE_PPS_PAID_MATCH 45 +#define WE_PPS_GID_MATCH 46 +#define WE_PPS_EARLY_TIM_CLEAR 47 +#define WE_PPS_EARLY_DTIM_CLEAR 48 +#define WE_PPS_EOF_PAD_DELIM 49 +#define WE_PPS_MACADDR_MISMATCH 50 +#define WE_PPS_DELIM_CRC_FAIL 51 +#define WE_PPS_GID_NSTS_ZERO 52 +#define WE_PPS_RSSI_CHECK 53 +/* 54 is unused */ +#define WE_SET_HTSMPS 55 +/* Private ioctl for QPower */ +#define WE_SET_QPOWER_MAX_PSPOLL_COUNT 56 +#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE 57 +#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 58 +#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59 + +#define WE_SET_BURST_ENABLE 60 +#define WE_SET_BURST_DUR 61 +/* GTX Commands */ +#define WE_SET_GTX_HT_MCS 62 +#define WE_SET_GTX_VHT_MCS 63 +#define WE_SET_GTX_USRCFG 64 +#define WE_SET_GTX_THRE 65 +#define WE_SET_GTX_MARGIN 66 +#define WE_SET_GTX_STEP 67 +#define WE_SET_GTX_MINTPC 68 +#define WE_SET_GTX_BWMASK 69 +/* Private ioctl to configure MCC home channels time quota and latency */ +#define WE_MCC_CONFIG_LATENCY 70 +#define WE_MCC_CONFIG_QUOTA 71 +/* Private IOCTL for debug connection issues */ +#define WE_SET_DEBUG_LOG 72 +#define WE_SET_SCAN_BAND_PREFERENCE 73 +#ifdef WE_SET_TX_POWER +#undef WE_SET_TX_POWER +#endif +#define WE_SET_TX_POWER 74 +/* Private ioctl for earlyrx power save feature */ +#define WE_SET_EARLY_RX_ADJUST_ENABLE 75 +#define WE_SET_EARLY_RX_TGT_BMISS_NUM 76 +#define WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE 77 +#define WE_SET_EARLY_RX_SLOP_STEP 78 +#define WE_SET_EARLY_RX_INIT_SLOP 79 +#define WE_SET_EARLY_RX_ADJUST_PAUSE 80 +#define WE_SET_MC_RATE 81 +#define WE_SET_EARLY_RX_DRIFT_SAMPLE 82 +/* Private ioctl for packet power save */ +#define WE_PPS_5G_EBT 83 +#define WE_SET_CTS_CBW 84 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) +#define WE_GET_11D_STATE 1 +#define WE_IBSS_STATUS 2 + +#define WE_GET_WLAN_DBG 4 +#define WE_GET_MAX_ASSOC 6 +/* 7 is unused */ +#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8 +#define WE_GET_CONCURRENCY_MODE 9 +#define WE_GET_NSS 11 +#define WE_GET_LDPC 12 +#define WE_GET_TX_STBC 13 +#define WE_GET_RX_STBC 14 +#define WE_GET_SHORT_GI 15 +#define WE_GET_RTSCTS 16 +#define WE_GET_CHWIDTH 17 +#define WE_GET_ANI_EN_DIS 18 +#define WE_GET_ANI_POLL_PERIOD 19 +#define WE_GET_ANI_LISTEN_PERIOD 20 +#define WE_GET_ANI_OFDM_LEVEL 21 +#define WE_GET_ANI_CCK_LEVEL 22 +#define WE_GET_DYNAMIC_BW 23 +#define WE_GET_TX_CHAINMASK 24 +#define WE_GET_RX_CHAINMASK 25 +#define WE_GET_11N_RATE 26 +#define WE_GET_AMPDU 27 +#define WE_GET_AMSDU 28 +#define WE_GET_TXPOW_2G 29 +#define WE_GET_TXPOW_5G 30 +#define WE_GET_POWER_GATING 31 +#define WE_GET_PPS_PAID_MATCH 32 +#define WE_GET_PPS_GID_MATCH 33 +#define WE_GET_PPS_EARLY_TIM_CLEAR 34 +#define WE_GET_PPS_EARLY_DTIM_CLEAR 35 +#define WE_GET_PPS_EOF_PAD_DELIM 36 +#define WE_GET_PPS_MACADDR_MISMATCH 37 +#define WE_GET_PPS_DELIM_CRC_FAIL 38 +#define WE_GET_PPS_GID_NSTS_ZERO 39 +#define WE_GET_PPS_RSSI_CHECK 40 +/* Private ioctl for QPower */ +#define WE_GET_QPOWER_MAX_PSPOLL_COUNT 41 +#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE 42 +#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 43 +#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44 +#define WE_GET_BURST_ENABLE 45 +#define WE_GET_BURST_DUR 46 +/* GTX Commands */ +#define WE_GET_GTX_HT_MCS 47 +#define WE_GET_GTX_VHT_MCS 48 +#define WE_GET_GTX_USRCFG 49 +#define WE_GET_GTX_THRE 50 +#define WE_GET_GTX_MARGIN 51 +#define WE_GET_GTX_STEP 52 +#define WE_GET_GTX_MINTPC 53 +#define WE_GET_GTX_BWMASK 54 +#define WE_GET_SCAN_BAND_PREFERENCE 55 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3) +#define WE_WOWL_ADD_PTRN 1 +#define WE_WOWL_DEL_PTRN 2 +#if defined WLAN_FEATURE_VOWIFI +#define WE_NEIGHBOR_REPORT_REQUEST 3 +#endif +#define WE_SET_AP_WPS_IE 4 //This is called in station mode to set probe rsp ie. +#define WE_SET_CONFIG 5 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4) +#define WE_SET_WLAN_DBG 1 +/* 2 is unused */ +#define WE_SET_SAP_CHANNELS 3 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5) +#define WE_WLAN_VERSION 1 +#define WE_GET_STATS 2 +#define WE_GET_CFG 3 +#define WE_GET_WMM_STATUS 4 +#define WE_GET_CHANNEL_LIST 5 +#ifdef WLAN_FEATURE_11AC +#define WE_GET_RSSI 6 +#endif +#define WE_GET_ROAM_RSSI 7 +#ifdef FEATURE_WLAN_TDLS +#define WE_GET_TDLS_PEERS 8 +#endif +#ifdef WLAN_FEATURE_11W +#define WE_GET_11W_INFO 9 +#endif +#define WE_GET_STATES 10 +#define WE_GET_PHYMODE 12 +#ifdef FEATURE_OEM_DATA_SUPPORT +#define WE_GET_OEM_DATA_CAP 13 +#endif + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6) +#define WE_CLEAR_STATS 1 +#ifdef WLAN_BTAMP_FEATURE +#define WE_ENABLE_AMP 4 +#define WE_DISABLE_AMP 5 +#endif /* WLAN_BTAMP_FEATURE */ +#define WE_ENABLE_DXE_STALL_DETECT 6 +#define WE_DISPLAY_DXE_SNAP_SHOT 7 +#define WE_SET_REASSOC_TRIGGER 8 +#define WE_DISPLAY_DATAPATH_SNAP_SHOT 9 +#define WE_DUMP_AGC_START 11 +#define WE_DUMP_AGC 12 +#define WE_DUMP_CHANINFO_START 13 +#define WE_DUMP_CHANINFO 14 +#define WE_DUMP_WATCHDOG 15 +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +#define WE_DUMP_PCIE_LOG 16 +#endif +#define WE_GET_RECOVERY_STAT 17 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7) +#define WE_LOG_DUMP_CMD 1 + +#define WE_P2P_NOA_CMD 2 +//IOCTL to configure MCC params +#define WE_MCC_CONFIG_CREDENTIAL 3 +#define WE_MCC_CONFIG_PARAMS 4 + +#ifdef FEATURE_WLAN_TDLS +#define WE_TDLS_CONFIG_PARAMS 5 +#endif + +#define WE_UNIT_TEST_CMD 7 + +#define WE_MTRACE_DUMP_CMD 8 +#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9 + +#ifdef FEATURE_WLAN_TDLS +#undef MAX_VAR_ARGS +#define MAX_VAR_ARGS 11 +#else +#define MAX_VAR_ARGS 7 +#endif + + +/* Private ioctls (with no sub-ioctls) */ +/* note that they must be odd so that they have "get" semantics */ +#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9) +#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11) +#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13) + +/* (SIOCIWFIRSTPRIV + 8) is currently unused */ +/* (SIOCIWFIRSTPRIV + 16) is currently unused */ +/* (SIOCIWFIRSTPRIV + 10) is currently unused */ +/* (SIOCIWFIRSTPRIV + 12) is currently unused */ +/* (SIOCIWFIRSTPRIV + 14) is currently unused */ +/* (SIOCIWFIRSTPRIV + 15) is currently unused */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/* Private ioctls for setting the measurement configuration */ +#define WLAN_PRIV_SET_OEM_DATA_REQ (SIOCIWFIRSTPRIV + 17) +#define WLAN_PRIV_GET_OEM_DATA_RSP (SIOCIWFIRSTPRIV + 19) +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20) +#endif + +/* Private ioctl for setting the host offload feature */ +#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18) + +/* Private ioctl to get the statistics */ +#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21) + +/* Private ioctl to set the Keep Alive Params */ +#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22) +#ifdef WLAN_FEATURE_PACKET_FILTERING +/* Private ioctl to set the Packet Filtering Params */ +#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23) +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +/* Private ioctl to get the statistics */ +#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24) +#endif + +#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25) /*Don't change this number*/ + +#define WLAN_PRIV_SET_MCBC_FILTER (SIOCIWFIRSTPRIV + 26) +#define WLAN_PRIV_CLEAR_MCBC_FILTER (SIOCIWFIRSTPRIV + 27) +/* Private ioctl to trigger reassociation */ + +#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29) + +#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28) +#define WE_SET_SMPS_PARAM 1 +#ifdef DEBUG +#define WE_SET_FW_CRASH_INJECT 2 +#endif + +#define WLAN_STATS_INVALID 0 +#define WLAN_STATS_RETRY_CNT 1 +#define WLAN_STATS_MUL_RETRY_CNT 2 +#define WLAN_STATS_TX_FRM_CNT 3 +#define WLAN_STATS_RX_FRM_CNT 4 +#define WLAN_STATS_FRM_DUP_CNT 5 +#define WLAN_STATS_FAIL_CNT 6 +#define WLAN_STATS_RTS_FAIL_CNT 7 +#define WLAN_STATS_ACK_FAIL_CNT 8 +#define WLAN_STATS_RTS_SUC_CNT 9 +#define WLAN_STATS_RX_DISCARD_CNT 10 +#define WLAN_STATS_RX_ERROR_CNT 11 +#define WLAN_STATS_TX_BYTE_CNT 12 + +#define WLAN_STATS_RX_BYTE_CNT 13 +#define WLAN_STATS_RX_RATE 14 +#define WLAN_STATS_TX_RATE 15 + +#define WLAN_STATS_RX_UC_BYTE_CNT 16 +#define WLAN_STATS_RX_MC_BYTE_CNT 17 +#define WLAN_STATS_RX_BC_BYTE_CNT 18 +#define WLAN_STATS_TX_UC_BYTE_CNT 19 +#define WLAN_STATS_TX_MC_BYTE_CNT 20 +#define WLAN_STATS_TX_BC_BYTE_CNT 21 + +#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \ + if ((__tlen + __size + 2) < WE_MAX_STR_LEN) \ + { \ + *__p++ = __type; \ + *__p++ = __size; \ + memcpy(__p, __val, __size); \ + __p += __size; \ + __tlen += __size + 2; \ + } \ + else \ + { \ + hddLog(VOS_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!"); \ + } \ + } while(0); + +#define VERSION_VALUE_MAX_LEN 32 + +#define TX_PER_TRACKING_DEFAULT_RATIO 5 +#define TX_PER_TRACKING_MAX_RATIO 10 +#define TX_PER_TRACKING_DEFAULT_WATERMARK 5 + +#define WLAN_ADAPTER 0 +#define P2P_ADAPTER 1 + +/*MCC Configuration parameters */ +enum { + MCC_SCHEDULE_TIME_SLICE_CFG_PARAM = 1, + MCC_MAX_NULL_SEND_TIME_CFG_PARAM, + MCC_TX_EARLY_STOP_TIME_CFG_PARAM, + MCC_RX_DRAIN_TIME_CFG_PARAM, + MCC_CHANNEL_SWITCH_TIME_CFG_PARAM, + MCC_MIN_CHANNEL_TIME_CFG_PARAM, + MCC_PARK_BEFORE_TBTT_CFG_PARAM, + MCC_MIN_AFTER_DTIM_CFG_PARAM, + MCC_TOO_CLOSE_MARGIN_CFG_PARAM, +}; + +static const struct qwlan_hw qwlan_hw_list[] = { + { + .id = AR6320_REV1_VERSION, + .subid = 0, + .name = "QCA6174_REV1", + }, + { + .id = AR6320_REV1_1_VERSION, + .subid = 0x1, + .name = "QCA6174_REV1_1", + }, + { + .id = AR6320_REV1_3_VERSION, + .subid = 0x2, + .name = "QCA6174_REV1_3", + }, + { + .id = AR6320_REV2_1_VERSION, + .subid = 0x4, + .name = "QCA6174_REV2_1", + }, + { + .id = AR6320_REV2_1_VERSION, + .subid = 0x5, + .name = "QCA6174_REV2_2", + }, + { + .id = AR6320_REV3_VERSION, + .subid = 0x6, + .name = "QCA6174_REV2.3", + }, + { + .id = AR6320_REV3_VERSION, + .subid = 0x8, + .name = "QCA6174_REV3", + }, + { + .id = AR6320_REV3_VERSION, + .subid = 0x9, + .name = "QCA6174_REV3_1", + }, + { + .id = AR6320_REV3_2_VERSION, + .subid = 0xA, + .name = "QCA6174_REV3_2", + } +}; + +int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, + v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest, + v_U8_t sessionId); +#endif + +/**--------------------------------------------------------------------------- + + \brief mem_alloc_copy_from_user_helper - + + Helper function to allocate buffer and copy user data. + + \param - wrqu - Pointer to IOCTL Data. + len - size + + \return - On Success pointer to buffer, On failure NULL + + --------------------------------------------------------------------------*/ +void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len) +{ + u8 *ptr = NULL; + + /* in order to protect the code, an extra byte is post appended to the buffer + * and the null termination is added. However, when allocating (len+1) byte + * of memory, we need to make sure that there is no uint overflow when doing + * addition. In theory check len < UINT_MAX protects the uint overflow. For + * wlan private ioctl, the buffer size is much less than UINT_MAX, as a good + * guess, now, it is assumed that the private command buffer size is no + * greater than 4K (4096 bytes). So we use 4096 as the upper boundary for now. + */ + if (len > MAX_USER_COMMAND_SIZE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid length"); + return NULL; + } + + + ptr = kmalloc(len + 1, GFP_KERNEL); + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "unable to allocate memory"); + return NULL; + } + + if (copy_from_user(ptr, wrqu_data, len)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + kfree(ptr); + return NULL; + } + ptr[len] = '\0'; + return ptr; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_priv_get_data - + + Helper function to get compatible struct iw_point passed to ioctl + + \param - p_priv_data - pointer to iw_point struct to be filled + wrqu - Pointer to IOCTL Data received from user space + + \return - 0 if p_priv_data successfully filled + error otherwise + + --------------------------------------------------------------------------*/ +int hdd_priv_get_data(struct iw_point *p_priv_data, + union iwreq_data *wrqu) +{ + if ((NULL == p_priv_data) || (NULL == wrqu)) { + return -EINVAL; + } + +#ifdef CONFIG_COMPAT + if (is_compat_task()) { + struct compat_iw_point *p_compat_priv_data; + + /* Compat task: typecast to compat structure and copy the members. */ + p_compat_priv_data = (struct compat_iw_point *) &wrqu->data; + + p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer); + p_priv_data->length = p_compat_priv_data->length; + p_priv_data->flags = p_compat_priv_data->flags; + } else { +#endif /* #ifdef CONFIG_COMPAT */ + + /* Non compat task: directly copy the structure. */ + memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point)); + +#ifdef CONFIG_COMPAT + } +#endif /* #ifdef CONFIG_COMPAT */ + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_get_version() - + + This function use to get Wlan Driver, Firmware, & Hardware Version. + + \param - pAdapter Pointer to the adapter. + wrqu - Pointer to IOCTL REQUEST Data. + extra - Pointer to char + + \return - none + + --------------------------------------------------------------------------*/ +void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu, + char *extra) +{ + tSirVersionString wcnss_SW_version; + const char *pSWversion; + const char *pHWversion; + v_U32_t MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0; + + hdd_context_t *pHddContext; + int i = 0; + + pHddContext = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddContext) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid context, HDD context is null", __func__); + goto error; + } + + snprintf(wcnss_SW_version, sizeof(tSirVersionString), "%08x", + pHddContext->target_fw_version); + + pSWversion = wcnss_SW_version; + MSPId = (pHddContext->target_fw_version & 0xf0000000) >> 28; + mSPId = (pHddContext->target_fw_version & 0xf000000) >> 24; + SIId = (pHddContext->target_fw_version & 0xf00000) >> 20; + CRMId = pHddContext->target_fw_version & 0x7fff; + + for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) { + if (pHddContext->target_hw_version == qwlan_hw_list[i].id && + pHddContext->target_hw_revision == qwlan_hw_list[i].subid) { + pHWversion = qwlan_hw_list[i].name; + break; + } + } + + if (i == ARRAY_SIZE(qwlan_hw_list)) + pHWversion = "Unknown"; + pHddContext->target_hw_name = pHWversion; + + if (wrqu) { + wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN, + "Host SW:%s, FW:%d.%d.%d.%d, HW:%s", + QWLAN_VERSIONSTR, + MSPId, + mSPId, + SIId, + CRMId, + pHWversion); + } else { + pr_info("Host SW:%s, FW:%d.%d.%d.%d, HW:%s\n", + QWLAN_VERSIONSTR, + MSPId, + mSPId, + SIId, + CRMId, + pHWversion); + } +error: + return; +} + +int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U32_t threshold = 0,status = 0; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + if ( eHAL_STATUS_SUCCESS != + ccmCfgGetInt(hHal, WNI_CFG_RTS_THRESHOLD, &threshold) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD")); + return -EIO; + } + wrqu->rts.value = threshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Rts-Threshold=%d!!"), wrqu->rts.value); + + EXIT(); + + return 0; +} +int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U32_t threshold = 0,status = 0; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + if ( ccmCfgGetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD")); + return -EIO; + } + wrqu->frag.value = threshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Frag-Threshold=%d!!"), wrqu->frag.value); + + EXIT(); + + return 0; +} + +int hdd_wlan_get_freq(v_U32_t channel, v_U32_t *pfreq) +{ + int i; + if (channel > 0) + { + for (i=0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) + { + if (channel == freq_chan_map[i].chan) + { + *pfreq = freq_chan_map[i].freq; + return 1; + } + } + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Invalid channel no=%d!!"), channel); + return -EINVAL; +} + +static v_BOOL_t +hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType) +{ + v_BOOL_t rsnType = VOS_FALSE; + // is the authType supported? + switch (authType) + { + case eCSR_AUTH_TYPE_NONE: //never used + rsnType = eANI_BOOLEAN_FALSE; + break; + // MAC layer authentication types + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + rsnType = eANI_BOOLEAN_FALSE; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + rsnType = eANI_BOOLEAN_FALSE; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + rsnType = eANI_BOOLEAN_FALSE; + break; + + // Upper layer authentication types + case eCSR_AUTH_TYPE_WPA: + rsnType = eANI_BOOLEAN_TRUE; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + rsnType = eANI_BOOLEAN_TRUE; + break; + case eCSR_AUTH_TYPE_WPA_NONE: + rsnType = eANI_BOOLEAN_TRUE; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: +#endif + case eCSR_AUTH_TYPE_RSN: + rsnType = eANI_BOOLEAN_TRUE; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + rsnType = eANI_BOOLEAN_TRUE; + break; + //case eCSR_AUTH_TYPE_FAILED: + case eCSR_AUTH_TYPE_UNKNOWN: + rsnType = eANI_BOOLEAN_FALSE; + break; + default: + hddLog(LOGE, FL("%s called with unknown authType - default to Open, None"), + __func__); + rsnType = eANI_BOOLEAN_FALSE; + break; + } + hddLog(LOGE, FL("%s called with authType: %d, returned: %d"), + __func__, authType, rsnType); + return rsnType; +} + +static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n", + __func__, (int)rssi, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi */ + pAdapter->rssi = rssi; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: snr [%d] STA [%d] pContext [%p]\n", + __func__, (int)snr, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the snr */ + pAdapter->snr = snr; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) +{ + struct statsContext context; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus hstatus; + unsigned long rc; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + /* return a cached value */ + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = RSSI_CONTEXT_MAGIC; + + hstatus = sme_GetRssi(pHddCtx->hHal, hdd_GetRssiCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, pAdapter->rssi, + &context, pHddCtx->pvosContext); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving RSSI")); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *rssi_value = pAdapter->rssi; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr) +{ + struct statsContext context; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus hstatus; + unsigned long rc; + int valid; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + valid = wlan_hdd_validate_context(pHddCtx); + if (0 != valid) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return VOS_STATUS_E_FAULT; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = SNR_CONTEXT_MAGIC; + + hstatus = sme_GetSnr(pHddCtx->hHal, hdd_GetSnrCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving SNR")); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *snr = pAdapter->snr; + + return VOS_STATUS_SUCCESS; +} +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + +static void hdd_GetRoamRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + if (ioctl_debug) + { + pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n", + __func__, (int)rssi, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi */ + pAdapter->rssi = rssi; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + + + +VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) +{ + struct statsContext context; + hdd_context_t *pHddCtx = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + eHalStatus hstatus; + unsigned long rc; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + /* return a cached value */ + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__); + /* return a cached value */ + *rssi_value = 0; + return VOS_STATUS_SUCCESS; + } + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = RSSI_CONTEXT_MAGIC; + + hstatus = sme_GetRoamRssi(pHddCtx->hHal, hdd_GetRoamRssiCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context, pHddCtx->pvosContext); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving RSSI")); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *rssi_value = pAdapter->rssi; + + return VOS_STATUS_SUCCESS; +} +#endif + + +void hdd_StatisticsCB( void *pStats, void *pContext ) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_stats_t *pStatsCache = NULL; + hdd_wext_state_t *pWextState; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + tCsrSummaryStatsInfo *pSummaryStats = NULL; + tCsrGlobalClassAStatsInfo *pClassAStats = NULL; + tCsrGlobalClassBStatsInfo *pClassBStats = NULL; + tCsrGlobalClassCStatsInfo *pClassCStats = NULL; + tCsrGlobalClassDStatsInfo *pClassDStats = NULL; + tCsrPerStaStatsInfo *pPerStaStats = NULL; + + if (pAdapter!= NULL) + pStatsCache = &pAdapter->hdd_stats; + + + pSummaryStats = (tCsrSummaryStatsInfo *)pStats; + pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 ); + pClassBStats = (tCsrGlobalClassBStatsInfo *)( pClassAStats + 1 ); + pClassCStats = (tCsrGlobalClassCStatsInfo *)( pClassBStats + 1 ); + pClassDStats = (tCsrGlobalClassDStatsInfo *)( pClassCStats + 1 ); + pPerStaStats = (tCsrPerStaStatsInfo *)( pClassDStats + 1 ); + + if (pStatsCache!=NULL) + { + // and copy the stats into the cache we keep in the adapter instance structure + vos_mem_copy( &pStatsCache->summary_stat, pSummaryStats, sizeof( pStatsCache->summary_stat ) ); + vos_mem_copy( &pStatsCache->ClassA_stat, pClassAStats, sizeof( pStatsCache->ClassA_stat ) ); + vos_mem_copy( &pStatsCache->ClassB_stat, pClassBStats, sizeof( pStatsCache->ClassB_stat ) ); + vos_mem_copy( &pStatsCache->ClassC_stat, pClassCStats, sizeof( pStatsCache->ClassC_stat ) ); + vos_mem_copy( &pStatsCache->ClassD_stat, pClassDStats, sizeof( pStatsCache->ClassD_stat ) ); + vos_mem_copy( &pStatsCache->perStaStats, pPerStaStats, sizeof( pStatsCache->perStaStats ) ); + } + + if (pAdapter) { + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + vos_status = vos_event_set(&pWextState->vosevent); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("vos_event_set failed")); + return; + } + } +} + +void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result) +{ + v_CONTEXT_t pVosContext; + hdd_context_t *pHddCtx; + VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ); +#if 0 + hdd_wext_state_t *pWextState; + v_U32_t roamId; +#endif + + ENTER(); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL); + + pHddCtx = (hdd_context_t*) vos_get_context(VOS_MODULE_ID_HDD,pVosContext); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid pHddCtx", __func__); + return; + } +#if 0 + pWextState = pAdapter->pWextState; +#endif + + if (WNI_CFG_NEED_RESTART == result || WNI_CFG_NEED_RELOAD == result) + { + //TODO Verify is this is really used. If yes need to fix it. + hdd_reconnect_all_adapters( pHddCtx ); +#if 0 + pAdapter->conn_info.connState = eConnectionState_NotConnected; + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(halHandle, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + if(VOS_STATUS_SUCCESS == vosStatus) + wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + + sme_RoamConnect(halHandle, + pAdapter->sessionId, &(pWextState->roamProfile), + &roamId); +#endif + } + + EXIT(); + +} + +void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter) +{ + int i = 0; + hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + /* clear WPA/RSN/WSC IE information in the profile */ + pWextState->roamProfile.nWPAReqIELength = 0; + pWextState->roamProfile.pWPAReqIE = (tANI_U8 *)NULL; + pWextState->roamProfile.nRSNReqIELength = 0; + pWextState->roamProfile.pRSNReqIE = (tANI_U8 *)NULL; + +#ifdef FEATURE_WLAN_WAPI + pWextState->roamProfile.nWAPIReqIELength = 0; + pWextState->roamProfile.pWAPIReqIE = (tANI_U8 *)NULL; +#endif + + pWextState->roamProfile.bWPSAssociation = VOS_FALSE; + pWextState->roamProfile.bOSENAssociation = VOS_FALSE; + pWextState->roamProfile.pAddIEScan = (tANI_U8 *)NULL; + pWextState->roamProfile.nAddIEScanLength = 0; + pWextState->roamProfile.pAddIEAssoc = (tANI_U8 *)NULL; + pWextState->roamProfile.nAddIEAssocLength = 0; + + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] + = eCSR_ENCRYPT_TYPE_NONE; + + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] + = eCSR_ENCRYPT_TYPE_NONE; + + pWextState->roamProfile.AuthType.numEntries = 1; + pWextState->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + +#ifdef WLAN_FEATURE_11W + pWextState->roamProfile.MFPEnabled = eANI_BOOLEAN_FALSE; + pWextState->roamProfile.MFPRequired = 0; + pWextState->roamProfile.MFPCapable = 0; +#endif + + pWextState->authKeyMgmt = 0; + + for (i=0; i < CSR_MAX_NUM_KEY; i++) + { + if (pWextState->roamProfile.Keys.KeyMaterial[i]) + { + pWextState->roamProfile.Keys.KeyLength[i] = 0; + } + } +#ifdef FEATURE_WLAN_WAPI + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN; + pAdapter->wapi_info.nWapiMode = 0; +#endif + + vos_mem_zero((void *)(pWextState->req_bssId), VOS_MAC_ADDR_SIZE); + +} + +void wlan_hdd_ula_done_cb(v_VOID_t *callbackContext) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t*)callbackContext; + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + } + else + { + complete(&pAdapter->ula_complete); + } +} + +VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + VOS_STATUS vos_status; + unsigned long rc; + + if (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated) + { + INIT_COMPLETION(pAdapter->ula_complete); + + /*To avoid race condition between the set key and the last EAPOL + packet, notify TL to finish upper layer authentication incase if the + last EAPOL packet pending in the TL queue.*/ + vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter); + + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANTL_Finish_ULA returned ERROR status= %d", + __LINE__, vos_status ); + return vos_status; + + } + + rc = wait_for_completion_timeout(&pAdapter->ula_complete, + msecs_to_jiffies(HDD_FINISH_ULA_TIME_OUT)); + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failure wait on ULA to complete %ld"), rc); + /* we'll still fall through and return success since the + * connection may still get established but is just taking + * too long for us to wait */ + } + } + return VOS_STATUS_SUCCESS; +} + +v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie, int ie_len) +{ + + int left = ie_len; + v_U8_t *ptr = ie; + v_U8_t elem_id,elem_len; + v_U8_t eid = 0xDD; + + if ( NULL == ie || 0 == ie_len ) + return NULL; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + if(memcmp( &ptr[2], oui, oui_size)==0) + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +static int iw_set_commit(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hddLog( LOG1, "In %s", __func__); + /* Do nothing for now */ + return 0; +} + +static int iw_get_name(struct net_device *dev, + struct iw_request_info *info, + char *wrqu, char *extra) +{ + + ENTER(); + strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ); + EXIT(); + return 0; +} + +static int iw_set_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tCsrRoamProfile *pRoamProfile; + eCsrRoamBssType LastBSSType; + eMib_dot11DesiredBssType connectedBssType; + hdd_config_t *pConfig; + struct wireless_dev *wdev; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return 0; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + wdev = dev->ieee80211_ptr; + pRoamProfile = &pWextState->roamProfile; + LastBSSType = pRoamProfile->BSSType; + + hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType); + + switch (wrqu->mode) + { + case IW_MODE_ADHOC: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS; + // Set the phymode correctly for IBSS. + pConfig = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + pWextState->roamProfile.phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); + pAdapter->device_mode = WLAN_HDD_IBSS; + wdev->iftype = NL80211_IFTYPE_ADHOC; + break; + case IW_MODE_INFRA: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + wdev->iftype = NL80211_IFTYPE_STATION; + break; + case IW_MODE_AUTO: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY; + break; + default: + hddLog(LOGE, "%s Unknown AP Mode value %d ", __func__, wrqu->mode); + return -EOPNOTSUPP; + } + + if ( LastBSSType != pRoamProfile->BSSType ) + { + //the BSS mode changed + // We need to issue disconnect if connected or in IBSS disconnect state + if ( hdd_connGetConnectedBssType( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) || + ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) ) + { + VOS_STATUS vosStatus; + // need to issue a disconnect to CSR. + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE ); + if(VOS_STATUS_SUCCESS == vosStatus) + { + unsigned long rc; + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var")); + } +} + } + + EXIT(); + return 0; +} + + +static int +iw_get_mode(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return 0; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + switch (pWextState->roamProfile.BSSType) { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + hddLog(LOG1, FL("returns IW_MODE_INFRA")); + wrqu->mode = IW_MODE_INFRA; + break; + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + hddLog(LOG1, FL("returns IW_MODE_ADHOC")); + wrqu->mode = IW_MODE_ADHOC; + break; + case eCSR_BSS_TYPE_ANY: + default: + hddLog(LOG1, FL("returns IW_MODE_AUTO")); + wrqu->mode = IW_MODE_AUTO; + break; + } + + EXIT(); + return 0; +} + +static int iw_set_freq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + v_U32_t numChans = 0; + v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + v_U32_t indx = 0; + v_U32_t status = 0; + + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamProfile * pRoamProfile; + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + pRoamProfile = &pWextState->roamProfile; + + hddLog(LOG1,"setCHANNEL ioctl"); + + /* Link is up then return cant set channel*/ + if(eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState || + eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + hddLog( LOGE, "IBSS Associated"); + return -EOPNOTSUPP; + } + + /* Settings by Frequency as input */ + if((wrqu->freq.e == 1) && (wrqu->freq.m >= (tANI_U32)2.412e8) && + (wrqu->freq.m <= (tANI_U32)5.825e8)) + { + tANI_U32 freq = wrqu->freq.m / 100000; + + while ((indx < FREQ_CHAN_MAP_TABLE_SIZE) && (freq != freq_chan_map[indx].freq)) + indx++; + if (indx >= FREQ_CHAN_MAP_TABLE_SIZE) + { + return -EINVAL; + } + wrqu->freq.e = 0; + wrqu->freq.m = freq_chan_map[indx].chan; + + } + + if (wrqu->freq.e == 0) + { + if((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) || + (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + hddLog(LOG1,"%s: Channel [%d] is outside valid range from %d to %d", + __func__, wrqu->freq.m, WNI_CFG_CURRENT_CHANNEL_STAMIN, + WNI_CFG_CURRENT_CHANNEL_STAMAX); + return -EINVAL; + } + + numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if (ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans) != eHAL_STATUS_SUCCESS){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST")); + return -EIO; + } + + for (indx = 0; indx < numChans; indx++) { + if (wrqu->freq.m == validChan[indx]){ + break; + } + } + } + else{ + + return -EINVAL; + } + + if(indx >= numChans) + { + return -EINVAL; + } + + /* Set the Operational Channel */ + numChans = pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = wrqu->freq.m; + pRoamProfile->ChannelInfo.ChannelList = &pHddStaCtx->conn_info.operationChannel; + + hddLog(LOG1,"pRoamProfile->operationChannel = %d", wrqu->freq.m); + + EXIT(); + + return status; +} + +static int iw_get_freq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + v_U32_t status = FALSE, channel = 0, freq = 0; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal; + hdd_wext_state_t *pWextState; + tCsrRoamProfile * pRoamProfile; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + pRoamProfile = &pWextState->roamProfile; + + if( pHddStaCtx->conn_info.connState== eConnectionState_Associated ) + { + if (sme_GetOperationChannel(hHal, &channel, pAdapter->sessionId) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to get operating channel %u"), pAdapter->sessionId); + return -EIO; + } + else + { + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status ) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + } + else + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = 0; + fwrq->e = MHZ; + } + return 0; +} + +static int iw_get_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return -EBUSY; + } + + if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + wrqu->txpower.value = 0; + return 0; + } + wlan_hdd_get_classAstats(pAdapter); + wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr; + + return 0; +} + +static int iw_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + ENTER(); + + if ( ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, wrqu->txpower.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_get_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return status; + } + + if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + wrqu->bitrate.value = 0; + } + else { + status = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + hdd_StatisticsCB, 0, FALSE, + pHddStaCtx->conn_info.staId[0], pAdapter, + pAdapter->sessionId ); + + if(eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics", + __func__); + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timeout while retrieving statistics", + __func__); + return VOS_STATUS_E_FAILURE; + } + + wrqu->bitrate.value = pAdapter->hdd_stats.ClassA_stat.tx_rate*500*1000; + } + + EXIT(); + + return vos_status; +} +/* ccm call back function */ + +static int iw_set_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN]; + v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + v_U32_t i, rate; + v_U32_t valid_rate = FALSE, active_phy_mode = 0; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + return -ENXIO ; + } + + rate = wrqu->bitrate.value; + + if (rate == -1) + { + rate = WNI_CFG_FIXED_RATE_AUTO; + valid_rate = TRUE; + } + else if (ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS) + { + if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G + || active_phy_mode == WNI_CFG_DOT11_MODE_11B) + { + if ((ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_SUPPORTED_RATES_11A, + supp_rates, &a_len) == eHAL_STATUS_SUCCESS) && + (ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_SUPPORTED_RATES_11B, + supp_rates, &b_len) == eHAL_STATUS_SUCCESS)) + { + for (i = 0; i < (b_len + a_len); ++i) + { + /* supported rates returned is double the actual rate so we divide it by 2 */ + if ((supp_rates[i]&0x7F)/2 == rate) + { + valid_rate = TRUE; + rate = i + WNI_CFG_FIXED_RATE_1MBPS; + break; + } + } + } + } + } + if (valid_rate != TRUE) + { + return -EINVAL; + } + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_FIXED_RATE, rate, + ccmCfgSetCallback,eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_FIXED_RATE")); + return -EIO; + } + return 0; +} + + +static int iw_set_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + u_int8_t *genie = NULL; + u_int8_t *base_genie = NULL; + v_U16_t remLen; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return 0; + } + + if (!wrqu->data.length) { + hdd_clearRoamProfileIe(pAdapter); + EXIT(); + return 0; + } + + base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == base_genie) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + genie = base_genie; + + remLen = wrqu->data.length; + + hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0], genie[1]); + + /* clear any previous genIE before this call */ + memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) ); + + while (remLen >= 2) + { + v_U16_t eLen = 0; + v_U8_t elementId; + elementId = *genie++; + eLen = *genie++; + remLen -= 2; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]", + __func__, elementId, eLen); + + switch ( elementId ) + { + case IE_EID_VENDOR: + if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */ + { + kfree(base_genie); + return -EINVAL; + } + + if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) + { + v_U16_t curGenIELen = pWextState->genIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)", + __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2); + + if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + kfree(base_genie); + return -ENOMEM; + } + // save to Additional IE ; it should be accumulated to handle WPS IE + other IE + memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); + pWextState->genIE.length += eLen + 2; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) + { + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); + pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nWPAReqIELength = eLen + 2; + } + else /* any vendorId except WPA IE should be accumulated to genIE */ + { + v_U16_t curGenIELen = pWextState->genIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OUI(%02x %02x %02x %02x) IE(len %d)", + __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2); + + if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + kfree(base_genie); + return -ENOMEM; + } + // save to Additional IE ; it should be accumulated to handle WPS IE + other IE + memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); + pWextState->genIE.length += eLen + 2; + } + break; + case DOT11F_EID_RSN: + hddLog (LOG1, "%s Set RSN IE (len %d)",__func__, eLen+2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); + pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nRSNReqIELength = eLen + 2; + break; + + default: + hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, elementId); + kfree(base_genie); + return 0; + } + genie += eLen; + remLen -= eLen; + } + EXIT(); + kfree(base_genie); + return 0; +} + +static int iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eHalStatus status; + v_U32_t length = DOT11F_IE_RSN_MAX_LEN; + v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN]; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + + hddLog(LOG1,"getGEN_IE ioctl"); + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + if( pHddStaCtx->conn_info.connState == eConnectionState_NotConnected) + { + return -ENXIO; + } + + // Return something ONLY if we are associated with an RSN or WPA network + if ( VOS_TRUE != hdd_IsAuthTypeRSN(WLAN_HDD_GET_HAL_CTX(pAdapter), + pWextState->roamProfile.negotiatedAuthType)) + { + return -ENXIO; + } + + // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.) + status = csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &length, + genIeBytes); + length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN); + if (wrqu->data.length < length) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + vos_mem_copy( extra, (v_VOID_t*)genIeBytes, length); + wrqu->data.length = length; + + hddLog(LOG1,"%s: RSN IE of %d bytes returned", __func__, wrqu->data.length ); + + EXIT(); + + return 0; +} + +static int iw_get_encode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile); + int keyId; + eCsrAuthType authType = eCSR_AUTH_TYPE_NONE; + int i; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + keyId = pRoamProfile->Keys.defaultIndex; + + if(keyId < 0 || keyId >= MAX_WEP_KEYS) + { + hddLog(LOG1,"%s: Invalid keyId : %d", __func__, keyId); + return -EINVAL; + } + + if(pRoamProfile->Keys.KeyLength[keyId] > 0) + { + dwrq->flags |= IW_ENCODE_ENABLED; + dwrq->length = pRoamProfile->Keys.KeyLength[keyId]; + vos_mem_copy(extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]); + + dwrq->flags |= (keyId + 1); + + } + else + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + for(i=0; i < MAX_WEP_KEYS; i++) + { + if(pRoamProfile->Keys.KeyMaterial[i] == NULL) + { + continue; + } + else + { + break; + } + } + + if(MAX_WEP_KEYS == i) + { + dwrq->flags |= IW_ENCODE_NOKEY; + } + + authType = ((hdd_station_ctx_t*)WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType; + + if(eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) + { + dwrq->flags |= IW_ENCODE_OPEN; + } + else + { + dwrq->flags |= IW_ENCODE_RESTRICTED; + } + EXIT(); + return 0; +} + +#define PAE_ROLE_AUTHENTICATOR 1 // =1 for authenticator, +#define PAE_ROLE_SUPPLICANT 0 // =0 for supplicant + + +/* + * This function sends a single 'key' to LIM at all time. + */ + +static int iw_get_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U32_t status = 0; + + status = hdd_wlan_get_rts_threshold(pAdapter,wrqu); + + return status; +} + +static int iw_set_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + if ( wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX ) + { + return -EINVAL; + } + + if ( ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_get_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U32_t status = 0; + + status = hdd_wlan_get_frag_threshold(pAdapter,wrqu); + + return status; +} + +static int iw_set_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + if ( wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX ) + { + return -EINVAL; + } + + if ( ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_get_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + ENTER(); + return -EOPNOTSUPP; +} + +static int iw_set_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + ENTER(); + return -EOPNOTSUPP; +} + +static int iw_get_range(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + struct iw_range *range = (struct iw_range *) extra; + + v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + v_U32_t num_channels = sizeof(channels); + v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN]; + v_U32_t a_len; + v_U32_t b_len; + v_U32_t active_phy_mode = 0; + v_U8_t index = 0, i; + + ENTER(); + + wrqu->data.length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + /*Get the phy mode*/ + if (ccmCfgGetInt(hHal, + WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "active_phy_mode = %d", active_phy_mode); + + if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G) + { + /*Get the supported rates for 11G band*/ + a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + if (ccmCfgGetStr(hHal, + WNI_CFG_SUPPORTED_RATES_11A, + supp_rates, &a_len) == eHAL_STATUS_SUCCESS) + { + if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) + { + a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + } + for (i = 0; i < a_len; i++) + { + range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000; + } + range->num_bitrates = a_len; + } + else + { + return -EIO; + } + } + else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) + { + /*Get the supported rates for 11B band*/ + b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + if (ccmCfgGetStr(hHal, + WNI_CFG_SUPPORTED_RATES_11B, + supp_rates, &b_len) == eHAL_STATUS_SUCCESS) + { + if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) + { + b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + } + for (i = 0; i < b_len; i++) + { + range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000; + } + range->num_bitrates = b_len; + } + else + { + return -EIO; + } + } + } + + range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX; + range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN; + range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX; + + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + range->num_encoding_sizes = 2; + range->max_encoding_tokens = MAX_WEP_KEYS; + + // we support through Wireless Extensions 22 + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 22; + + /*Supported Channels and Frequencies*/ + if (ccmCfgGetStr((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels, &num_channels) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST")); + return -EIO; + } + if (num_channels > IW_MAX_FREQUENCIES) + { + num_channels = IW_MAX_FREQUENCIES; + } + + range->num_channels = num_channels; + range->num_frequency = num_channels; + + for (index=0; index < num_channels; index++) + { + v_U32_t frq_indx = 0; + + range->freq[index].i = channels[index]; + while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) + { + if(channels[index] == freq_chan_map[frq_indx].chan) + { + range->freq[index].m = freq_chan_map[frq_indx].freq * 100000; + range->freq[index].e = 1; + break; + } + frq_indx++; + } + } + + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + + /*Encryption capability*/ + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + + /* Txpower capability */ + range->txpower_capa = IW_TXPOW_MWATT; + + /*Scanning capability*/ + #if WIRELESS_EXT >= 22 + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL; + #endif + + EXIT(); + return 0; +} + +/* Callback function registered with PMC to know status of PMC request */ +static void iw_power_callback_fn (void *pContext, eHalStatus status) +{ + struct statsContext *pStatsContext; + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = (struct statsContext *)pContext; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if (POWER_CONTEXT_MAGIC != pStatsContext->magic) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, magic [%08x]", + __func__, pStatsContext->magic); + + if (ioctl_debug) + { + pr_info("%s: Invalid context, magic [%08x]\n", + __func__, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +/* Callback function for tx per hit */ +void hdd_tx_per_hit_cb (void *pCallbackContext) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCallbackContext; + unsigned char tx_fail[16]; + union iwreq_data wrqu; + + if (NULL == pAdapter || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(LOGE, "hdd_tx_per_hit_cb: pAdapter is NULL"); + return; + } + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(tx_fail, "TX_FAIL", sizeof(tx_fail)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail); +} + +void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) +{ + struct statsContext *pStatsContext; + tCsrGlobalClassAStatsInfo *pClassAStats; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: pStats [%p] pContext [%p]\n", + __func__, pStats, pContext); + } + + if ((NULL == pStats) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pStats [%p] pContext [%p]", + __func__, pStats, pContext); + return; + } + + pClassAStats = pStats; + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->hdd_stats.ClassA_stat = *pClassAStats; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext) +{ + struct linkspeedContext *pLinkSpeedContext; + hdd_adapter_t *pAdapter; + + if ((NULL == pLinkSpeed) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pLinkSpeed [%p] pContext [%p]", + __func__, pLinkSpeed, pContext); + return; + } + spin_lock(&hdd_context_lock); + pLinkSpeedContext = pContext; + pAdapter = pLinkSpeedContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + + if ((NULL == pAdapter) || (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pLinkSpeedContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pLinkSpeedContext->magic); + } + return; + } + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pLinkSpeedContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->ls_stats = *pLinkSpeed; + + /* notify the caller */ + complete(&pLinkSpeedContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eHalStatus hstatus; + unsigned long rc; + struct statsContext context; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + return VOS_STATUS_SUCCESS; + } + + /* we are connected + prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + /* query only for Class A statistics (which include link speed) */ + hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, + SME_GLOBAL_CLASSA_STATS, + hdd_GetClassA_statisticsCB, + 0, // not periodic + FALSE, //non-cached results + pHddStaCtx->conn_info.staId[0], + &context, + pAdapter->sessionId ); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve Class A statistics", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving Class A statistics")); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + /* either callback updated pAdapter stats or it has cached data */ + return VOS_STATUS_SUCCESS; +} + +static void hdd_get_station_statisticsCB(void *pStats, void *pContext) +{ + struct statsContext *pStatsContext; + tCsrSummaryStatsInfo *pSummaryStats; + tCsrGlobalClassAStatsInfo *pClassAStats; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: pStats [%p] pContext [%p]\n", + __func__, pStats, pContext); + } + + if ((NULL == pStats) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pStats [%p] pContext [%p]", + __func__, pStats, pContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + pSummaryStats = (tCsrSummaryStatsInfo *)pStats; + pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 ); + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->hdd_stats.summary_stat = *pSummaryStats; + pAdapter->hdd_stats.ClassA_stat = *pClassAStats; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eHalStatus hstatus; + unsigned long rc; + struct statsContext context; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_SUCCESS; + } + + /* we are connected + prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + + /* query only for Summary & Class A statistics */ + hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS, + hdd_get_station_statisticsCB, + 0, // not periodic + FALSE, //non-cached results + pHddStaCtx->conn_info.staId[0], + &context, + pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics", + __func__); + /* we'll return with cached values */ + } + else + { + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while retrieving statistics")); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + /* either callback updated pAdapter stats or it has cached data */ + return VOS_STATUS_SUCCESS; +} + + +/* + * Support for the LINKSPEED private command + * Per the WiFi framework the response must be of the form + * "LinkSpeed xx" + */ +static int iw_get_linkspeed(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + char *pLinkSpeed = (char*)extra; + int len = sizeof(v_U32_t) + 1; + v_U32_t link_speed = 0; + VOS_STATUS status; + int rc, valid; + tSirMacAddr bssid; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + valid = wlan_hdd_validate_context(pHddCtx); + + if (0 != valid) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return valid; + } + vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE); + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + /* we are not connected so we don't have a classAstats */ + link_speed = 0; + } + else + { + status = wlan_hdd_get_linkspeed_for_peermac(pAdapter, bssid); + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME linkspeed")); + return -EINVAL; + } + link_speed = pAdapter->ls_stats.estLinkSpeed; + /* linkspeed in units of 500 kbps */ + link_speed = link_speed / 500; + } + wrqu->data.length = len; + /* return the linkspeed in the format required by the WiFi Framework */ + rc = snprintf(pLinkSpeed, len, "%u", link_speed); + if ((rc < 0) || (rc >= len)) + { + /* encoding or length error? */ + hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed")); + return -EIO; + } + + /* a value is being successfully returned */ + return rc; +} + +/* + * Helper function to return correct value for WLAN_GET_LINK_SPEED + * + */ +static int iw_get_linkspeed_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int rc; + + rc = iw_get_linkspeed(dev, info, wrqu, extra); + + if (rc < 0) + return rc; + + /* a value is being successfully returned */ + return 0; +} + +/* + * Support for the RSSI & RSSI-APPROX private commands + * Per the WiFi framework the response must be of the form + * " rssi " + * unless we are not associated, in which case the response is + * "OK" + */ +static int iw_get_rssi(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + char *cmd = extra; + int len = wrqu->data.length; + v_S7_t s7Rssi = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length; + VOS_STATUS vosStatus; + int rc; + + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || + (0 == ssidlen) || (ssidlen >= len)) + { + /* we are not connected or our SSID is too long + so we cannot report an rssi */ + rc = scnprintf(cmd, len, "OK"); + } + else + { + /* we are connected with a valid SSID + so we can write the SSID into the return buffer + (note that it is not NUL-terminated) */ + memcpy(cmd, pHddStaCtx->conn_info.SSID.SSID.ssId, ssidlen ); + + vosStatus = wlan_hdd_get_rssi(pAdapter, &s7Rssi); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* append the rssi to the ssid in the format required by + the WiFI Framework */ + rc = scnprintf(&cmd[ssidlen], len - ssidlen, " rssi %d", s7Rssi); + rc += ssidlen; + } + else + { + rc = -1; + } + } + + /* verify that we wrote a valid response */ + if ((rc < 0) || (rc >= len)) + { + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to encode RSSI, got [%s]", + __func__, cmd); + return -EIO; + } + + /* a value is being successfully returned */ + return rc; +} + +/* + * Support for SoftAP channel range private command + */ +static int iw_softap_set_channel_range( struct net_device *dev, + int startChannel, + int endChannel, + int band) +{ + VOS_STATUS status; + int ret = 0; + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + status = WLANSAP_SetChannelRange(hHal, startChannel, endChannel, band); + + if (VOS_STATUS_SUCCESS != status) + { + ret = -EINVAL; + } + pHddCtx->is_dynamic_channel_range_set = 1; + return ret; +} + +VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) +{ + struct statsContext context; + eHalStatus status; + hdd_context_t *pHddCtx; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL"); + return VOS_STATUS_E_FAULT; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + return VOS_STATUS_E_FAILURE; + } + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + if (DRIVER_POWER_MODE_ACTIVE == mode) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering " + "Full Power", __func__); + status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context, + eSME_FULL_PWR_NEEDED_BY_HDD); + // Enter Full power command received from GUI this means we are disconnected + // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC + sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE); + if (eHAL_STATUS_PMC_PENDING == status) + { + unsigned long rc; + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting full power")); + } + } + } + else if (DRIVER_POWER_MODE_AUTO == mode) + { + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ", + __func__); + // Enter BMPS command received from GUI this means DHCP is completed + // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry + sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), + FALSE); + status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context); + if (eHAL_STATUS_PMC_PENDING == status) + { + unsigned long rc; + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting BMPS")); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not " + "enabled in the cfg"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode) +{ + hdd_context_t *pHddCtx; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL"); + return VOS_STATUS_E_FAULT; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (DRIVER_POWER_MODE_ACTIVE == mode) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering " + "Full Power", __func__); + + /* + * Enter Full power command received from GUI + * this means we are disconnected + */ + sme_PsOffloadDisablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + } + else if (DRIVER_POWER_MODE_AUTO == mode) + { + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ", + __func__); + + /* + * Enter BMPS command received from GUI + * this means DHCP is completed + */ + sme_PsOffloadEnablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not " + "enabled in the cfg"); + } + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx, + hdd_adapter_t *pAdapter) +{ + VOS_STATUS vos_Status; + + if ((NULL == pAdapter) || (NULL == pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid pointer"); + return VOS_STATUS_E_FAULT; + } + + /**Exit from Deep sleep or standby if we get the driver + START cmd from android GUI + */ + if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit " + "from Stand by",__func__); + vos_Status = hdd_exit_standby(pHddCtx); + } + else if (eHDD_SUSPEND_DEEP_SLEEP == pHddCtx->hdd_ps_state) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit " + "from deep sleep",__func__); + vos_Status = hdd_exit_deep_sleep(pHddCtx, pAdapter); + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Not in standby or deep sleep. " + "Ignore start cmd %d", __func__, pHddCtx->hdd_ps_state); + vos_Status = VOS_STATUS_SUCCESS; + } + + return vos_Status; +} + +VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx) +{ + VOS_STATUS vos_Status = VOS_STATUS_E_FAILURE; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "HDD context NULL"); + return VOS_STATUS_E_FAULT; + } + + if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop) + { + //Execute standby procedure. + //Executing standby procedure will cause the STA to + //disassociate first and then the chip will be put into standby. + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering Stand by mode"); + vos_Status = hdd_enter_standby(pHddCtx); + } + else if (WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP == + pHddCtx->cfg_ini->nEnableDriverStop) + { + //Execute deep sleep procedure + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering " + "deep sleep mode"); + //Deep sleep not supported + vos_Status = hdd_enter_standby(pHddCtx); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO_LOW, "%s: Driver stop is not enabled %d", + __func__, pHddCtx->cfg_ini->nEnableDriverStop); + vos_Status = VOS_STATUS_SUCCESS; + } + + return vos_Status; +} + + +void* wlan_hdd_change_country_code_callback(void *pAdapter) +{ + + hdd_adapter_t *call_back_pAdapter = pAdapter; + complete(&call_back_pAdapter->change_country_code); + + return NULL; +} + +static int iw_set_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + char *cmd = NULL; + int cmd_len = wrqu->data.length; + int ret = 0; + int rc = 0; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + cmd = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == cmd) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + if (ioctl_debug) + { + pr_info("%s: req [%s] len [%d]\n", __func__, cmd, cmd_len); + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: ***Received %s cmd from Wi-Fi GUI***", __func__, cmd); + + if (pHddCtx->isLogpInProgress) { + if (ioctl_debug) + { + pr_info("%s: RESTART in progress\n", __func__); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + kfree(cmd); + return -EBUSY; + } + + if (strncmp(cmd, "CSCAN", 5) == 0 ) + { + if (eHAL_STATUS_SUCCESS != iw_set_cscan(dev, info, wrqu, cmd)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Error in iw_set_scan!", __func__); + rc = -EINVAL; + } + } + else if( strcasecmp(cmd, "start") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Start command"); + /*Exit from Deep sleep or standby if we get the driver START cmd from android GUI*/ + + vos_status = wlan_hdd_exit_lowpower(pHddCtx, pAdapter); + if (vos_status == VOS_STATUS_SUCCESS) + { + union iwreq_data wrqu; + char buf[10]; + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(buf, "START", sizeof(buf)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: START CMD Status %d", __func__, vos_status); + rc = -EIO; + } + goto done; + } + else if( strcasecmp(cmd, "stop") == 0 ) + { + union iwreq_data wrqu; + char buf[10]; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Stop command"); + + wlan_hdd_enter_lowpower(pHddCtx); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(buf, "STOP", sizeof(buf)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + goto done; + } + else if (strcasecmp(cmd, "macaddr") == 0) + { + ret = snprintf(cmd, cmd_len, "Macaddr = " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes)); + } + else if (strcasecmp(cmd, "scan-active") == 0) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; + ret = snprintf(cmd, cmd_len, "OK"); + } + else if (strcasecmp(cmd, "scan-passive") == 0) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->ioctl_scan_mode = eSIR_PASSIVE_SCAN; + ret = snprintf(cmd, cmd_len, "OK"); + } + else if( strcasecmp(cmd, "scan-mode") == 0 ) + { + ret = snprintf(cmd, cmd_len, "ScanMode = %u", pAdapter->scan_info.scan_mode); + } + else if( strcasecmp(cmd, "linkspeed") == 0 ) + { + ret = iw_get_linkspeed(dev, info, wrqu, cmd); + } + else if( strncasecmp(cmd, "COUNTRY", 7) == 0 ) { + char *country_code; + unsigned long rc; + eHalStatus eHal_status; + + country_code = cmd + 8; + + init_completion(&pAdapter->change_country_code); + + eHal_status = sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback)wlan_hdd_change_country_code_callback, + country_code, + pAdapter, + pHddCtx->pvosContext, + eSIR_TRUE, + eSIR_TRUE); + + /* Wait for completion */ + rc = wait_for_completion_timeout(&pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timedout while setting country code")); + } + + if (eHAL_STATUS_SUCCESS != eHal_status) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: SME Change Country code fail", __func__); + kfree(cmd); + return -EIO; + } + } + else if( strncasecmp(cmd, "rssi", 4) == 0 ) + { + ret = iw_get_rssi(dev, info, wrqu, cmd); + } + else if( strncasecmp(cmd, "powermode", 9) == 0 ) { + int mode; + char *ptr; + + if (9 < cmd_len) + { + ptr = (char*)(cmd + 9); + + }else{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CMD LENGTH %d is not correct",cmd_len); + kfree(cmd); + return -EINVAL; + } + + if (1 != sscanf(ptr,"%d",&mode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "powermode input %s is not correct",ptr); + kfree(cmd); + return -EIO; + } + + if(!pHddCtx->cfg_ini->enablePowersaveOffload) + wlan_hdd_enter_bmps(pAdapter, mode); + else + wlan_hdd_set_powersave(pAdapter, mode); + } + else if (strncasecmp(cmd, "getpower", 8) == 0 ) { + v_U32_t pmc_state; + v_U16_t value; + + pmc_state = pmcGetPmcState(WLAN_HDD_GET_HAL_CTX(pAdapter)); + if(pmc_state == BMPS) { + value = DRIVER_POWER_MODE_AUTO; + } + else { + value = DRIVER_POWER_MODE_ACTIVE; + } + ret = snprintf(cmd, cmd_len, "powermode = %u", value); + } + else if( strncasecmp(cmd, "btcoexmode", 10) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "btcoexmode"); + /*TODO: set the btcoexmode*/ + } + else if( strcasecmp(cmd, "btcoexstat") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "BtCoex Status"); + /*TODO: Return the btcoex status*/ + } + else if( strcasecmp(cmd, "rxfilter-start") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Start command"); + + /*TODO: Enable Rx data Filter*/ + } + else if( strcasecmp(cmd, "rxfilter-stop") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Stop command"); + + /*TODO: Disable Rx data Filter*/ + } + else if( strcasecmp(cmd, "rxfilter-statistics") == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "Rx Data Filter Statistics command"); + /*TODO: rxfilter-statistics*/ + } + else if( strncasecmp(cmd, "rxfilter-add", 12) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-add"); + /*TODO: rxfilter-add*/ + } + else if( strncasecmp(cmd, "rxfilter-remove",15) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-remove"); + /*TODO: rxfilter-remove*/ + } +#ifdef FEATURE_WLAN_SCAN_PNO + else if( strncasecmp(cmd, "pnosetup", 8) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "pnosetup"); + /*TODO: support pnosetup*/ + } + else if( strncasecmp(cmd, "pnoforce", 8) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "pnoforce"); + /*TODO: support pnoforce*/ + } + else if( strncasecmp(cmd, "pno",3) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "pno"); + vos_status = iw_set_pno(dev, info, wrqu, cmd, 3); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } + else if( strncasecmp(cmd, "rssifilter",10) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "rssifilter"); + vos_status = iw_set_rssi_filter(dev, info, wrqu, cmd, 10); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } +#endif /*FEATURE_WLAN_SCAN_PNO*/ + else if( strncasecmp(cmd, "powerparams",11) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "powerparams"); + vos_status = iw_set_power_params(dev, info, wrqu, cmd, 11); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } + else if( 0 == strncasecmp(cmd, "CONFIG-TX-TRACKING", 18) ) { + tSirTxPerTrackingParam tTxPerTrackingParam; + char *ptr; + + if (18 < cmd_len) + { + ptr = (char*)(cmd + 18); + }else{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CMD LENGTH %d is not correct",cmd_len); + kfree(cmd); + return -EINVAL; + } + + if (4 != sscanf(ptr,"%hhu %hhu %hhu %u", + &(tTxPerTrackingParam.ucTxPerTrackingEnable), + &(tTxPerTrackingParam.ucTxPerTrackingPeriod), + &(tTxPerTrackingParam.ucTxPerTrackingRatio), + &(tTxPerTrackingParam.uTxPerTrackingWatermark))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CONFIG-TX-TRACKING %s input is not correct",ptr); + kfree(cmd); + return -EIO; + } + + // parameters checking + // period has to be larger than 0 + if (0 == tTxPerTrackingParam.ucTxPerTrackingPeriod) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Period input is not correct"); + kfree(cmd); + return -EIO; + } + + // use default value 5 is the input is not reasonable. in unit of 10% + if ((tTxPerTrackingParam.ucTxPerTrackingRatio > TX_PER_TRACKING_MAX_RATIO) || (0 == tTxPerTrackingParam.ucTxPerTrackingRatio)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Ratio input is not good. use default 5"); + tTxPerTrackingParam.ucTxPerTrackingRatio = TX_PER_TRACKING_DEFAULT_RATIO; + } + + // default is 5 + if (0 == tTxPerTrackingParam.uTxPerTrackingWatermark) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Tx Packet number input is not good. use default 5"); + tTxPerTrackingParam.uTxPerTrackingWatermark = TX_PER_TRACKING_DEFAULT_WATERMARK; + } + + if (eHAL_STATUS_SUCCESS != + sme_SetTxPerTracking(pHddCtx->hHal, + hdd_tx_per_hit_cb, + (void*)pAdapter, &tTxPerTrackingParam)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Set Tx PER Tracking Failed!"); + rc = -EIO; + } + } + else { + hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s", + __func__, cmd); + } +done: + /* many of the commands write information back into the command + string using snprintf(). check the return value here in one + place */ + if ((ret < 0) || (ret >= cmd_len)) + { + /* there was an encoding error or overflow */ + rc = -EINVAL; + } + else if (ret > 0) + { + if (copy_to_user(wrqu->data.pointer, cmd, ret)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + kfree(cmd); + return -EFAULT; + } + wrqu->data.length = ret; + } + + if (ioctl_debug) + { + pr_info("%s: rsp [%s] len [%d] status %d\n", + __func__, cmd, wrqu->data.length, rc); + } + kfree(cmd); + return rc; +} + +static int iw_set_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + ENTER(); + return 0; +} + +static int iw_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + ENTER(); + return 0; +} + +static struct iw_statistics *get_wireless_stats(struct net_device *dev) +{ + ENTER(); + return NULL; +} + +static int iw_set_encode(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) + +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + struct iw_point *encoderq = &(wrqu->encoding); + v_U32_t keyId; + v_U8_t key_length; + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + v_BOOL_t fKeyPresent = 0; + int i; + eHalStatus status = eHAL_STATUS_SUCCESS; + + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + + keyId = encoderq->flags & IW_ENCODE_INDEX; + + if(keyId) + { + if(keyId > MAX_WEP_KEYS) + { + return -EINVAL; + } + + fKeyPresent = 1; + keyId--; + } + else + { + fKeyPresent = 0; + } + + + if(wrqu->data.flags & IW_ENCODE_DISABLED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****iwconfig wlan0 key off*****"); + if(!fKeyPresent) { + + for(i=0;i < CSR_MAX_NUM_KEY; i++) { + + if(pWextState->roamProfile.Keys.KeyMaterial[i]) + pWextState->roamProfile.Keys.KeyLength[i] = 0; + } + } + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + pWextState->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + INIT_COMPLETION(pAdapter->disconnect_comp_var); + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED ); + if(eHAL_STATUS_SUCCESS == status) + { + unsigned long rc; + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var")); + } + } + + return status; + + } + + if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "iwconfig wlan0 key on"); + + pHddStaCtx->conn_info.authType = (encoderq->flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY : eCSR_AUTH_TYPE_OPEN_SYSTEM; + + } + + + if(wrqu->data.length > 0) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",__func__,wrqu->data.length); + + key_length = wrqu->data.length; + + /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued.*/ + + if(5 == key_length) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Call with WEP40,key_len=%d",__func__,key_length); + + if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP40; + } + else + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + } + else if(13 == key_length) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s:Call with WEP104,key_len:%d",__func__,key_length); + + if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + else + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Invalid WEP key length :%d", + __func__, key_length); + return -EINVAL; + } + + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pHddStaCtx->conn_info.mcEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType; + + if((eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) && + ((eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) || + (eCSR_AUTH_TYPE_SHARED_KEY == pHddStaCtx->conn_info.authType))) + { + + vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[keyId][0],extra,key_length); + + pWextState->roamProfile.Keys.KeyLength[keyId] = (v_U8_t)key_length; + pWextState->roamProfile.Keys.defaultIndex = (v_U8_t)keyId; + + return status; + } + } + + return 0; +} + +static int iw_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile); + int keyId; + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + eCsrAuthType authType = eCSR_AUTH_TYPE_NONE; + int i; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + keyId = pRoamProfile->Keys.defaultIndex; + + if(keyId < 0 || keyId >= MAX_WEP_KEYS) + { + hddLog(LOG1,"%s: Invalid keyId : %d", __func__, keyId); + return -EINVAL; + } + + if(pRoamProfile->Keys.KeyLength[keyId] > 0) + { + dwrq->flags |= IW_ENCODE_ENABLED; + dwrq->length = pRoamProfile->Keys.KeyLength[keyId]; + vos_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]), + pRoamProfile->Keys.KeyLength[keyId]); + } + else + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + for(i=0; i < MAX_WEP_KEYS; i++) + { + if(pRoamProfile->Keys.KeyMaterial[i] == NULL) + { + continue; + } + else + { + break; + } + } + + if(MAX_WEP_KEYS == i) + { + dwrq->flags |= IW_ENCODE_NOKEY; + } + else + { + dwrq->flags |= IW_ENCODE_ENABLED; + } + + encryptionType = pRoamProfile->EncryptionType.encryptionType[0]; + + if(eCSR_ENCRYPT_TYPE_NONE == encryptionType) + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType; + + if(IW_AUTH_ALG_OPEN_SYSTEM == authType) + { + dwrq->flags |= IW_ENCODE_OPEN; + } + else + { + dwrq->flags |= IW_ENCODE_RESTRICTED; + } + EXIT(); + return 0; + +} + +static int iw_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + eHalStatus halStatus= eHAL_STATUS_SUCCESS; + + tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile; + v_U32_t status = 0; + + struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; + + v_U8_t groupmacaddr[VOS_MAC_ADDR_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + int key_index; + struct iw_point *encoding = &wrqu->encoding; + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + VOS_STATUS vos_status; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + key_index = encoding->flags & IW_ENCODE_INDEX; + + if(key_index > 0) { + + /*Convert from 1-based to 0-based keying*/ + key_index--; + } + if(!ext->key_len) { + + /* Set the encryption type to NONE */ + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + return status; + } + + if(eConnectionState_NotConnected == pHddStaCtx->conn_info.connState && + (IW_ENCODE_ALG_WEP == ext->alg)) + { + if(IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) { + + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Invalid Configuration:%s"),__func__); + return -EINVAL; + } + else { + /*Static wep, update the roam profile with the keys */ + if(ext->key && (ext->key_len <= eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES) && + key_index < CSR_MAX_NUM_KEY) { + vos_mem_copy(&pRoamProfile->Keys.KeyMaterial[key_index][0],ext->key,ext->key_len); + pRoamProfile->Keys.KeyLength[key_index] = (v_U8_t)ext->key_len; + + if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + pRoamProfile->Keys.defaultIndex = (v_U8_t)key_index; + + } + } + return status; + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + + setKey.keyId = key_index; + setKey.keyLength = ext->key_len; + + if(ext->key_len <= CSR_MAX_KEY_LEN) { + vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len); + } + + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr, VOS_MAC_ADDR_SIZE); + } + else { + + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data, VOS_MAC_ADDR_SIZE); + } + + /*For supplicant pae role is zero*/ + setKey.paeRole = 0; + + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case IW_ENCODE_ALG_WEP: + setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + break; + + case IW_ENCODE_ALG_TKIP: + { + v_U8_t *pKey = &setKey.Key[0]; + + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey,ext->key,16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16],&ext->key[24],8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24],&ext->key[16],8); + + } + break; + + case IW_ENCODE_ALG_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + +#ifdef FEATURE_WLAN_ESE +#define IW_ENCODE_ALG_KRK 6 + case IW_ENCODE_ALG_KRK: + setKey.encType = eCSR_ENCRYPT_TYPE_KRK; + break; +#endif /* FEATURE_WLAN_ESE */ + + default: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d"),__func__,(int)ext->alg,(int)ext->key_len,setKey.encType); + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* The supplicant may attempt to set the PTK once pre-authentication + is done. Save the key in the UMAC and include it in the ADD + BSS request */ + halStatus = sme_FTUpdateKey(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey); + if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: Update PreAuth Key success", __func__); + return 0; + } + else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Update PreAuth Key failed", __func__); + return -EINVAL; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + vos_status = wlan_hdd_check_ula_done(pAdapter); + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d", + __LINE__, vos_status ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + + halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),pAdapter->sessionId, &setKey, &roamId ); + + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", + __LINE__, halStatus ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + + return halStatus; +} + +static int iw_set_retry(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if(wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN || + wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Invalid Retry-Limit=%d!!"),wrqu->retry.value); + + return -EINVAL; + } + + if(wrqu->retry.flags & IW_RETRY_LIMIT) { + + if((wrqu->retry.flags & IW_RETRY_LONG)) + { + if ( ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + } + else if((wrqu->retry.flags & IW_RETRY_SHORT)) + { + if ( ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + } + } + else + { + return -EOPNOTSUPP; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Set Retry-Limit=%d!!"),wrqu->retry.value); + + EXIT(); + + return 0; + +} + +static int iw_get_retry(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U32_t retry = 0; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if((wrqu->retry.flags & IW_RETRY_LONG)) + { + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; + + if ( ccmCfgGetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + + wrqu->retry.value = retry; + } + else if ((wrqu->retry.flags & IW_RETRY_SHORT)) + { + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; + + if ( ccmCfgGetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + + wrqu->retry.value = retry; + } + else { + return -EOPNOTSUPP; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Retry-Limit=%d!!"),retry); + + EXIT(); + + return 0; +} + +static int iw_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + struct iw_mlme *mlme = (struct iw_mlme *)extra; + eHalStatus status = eHAL_STATUS_SUCCESS; + + ENTER(); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!",__func__); + return 0; + } + + //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED + switch (mlme->cmd) { + case IW_MLME_DISASSOC: + case IW_MLME_DEAUTH: + + if( pHddStaCtx->conn_info.connState == eConnectionState_Associated ) + { + eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED; + + if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE ) + reason = eCSR_DISCONNECT_REASON_MIC_ERROR; + + INIT_COMPLETION(pAdapter->disconnect_comp_var); + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,reason); + + if(eHAL_STATUS_SUCCESS == status) + { + unsigned long rc; + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var")); + } + else + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", + __func__, (int)mlme->cmd, (int)status ); + + /* Resetting authKeyMgmt */ + (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt = 0; + + netif_tx_disable(dev); + netif_carrier_off(dev); + + } + else + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd ); + } + break; + default: + hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd ); + return -EINVAL; + }//end of switch + + EXIT(); + + return status; + +} + +int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev) +{ + int ret = 0; + vos_msg_t msg = {0}; + + wda_cli_set_cmd_t *iwcmd = (wda_cli_set_cmd_t *)vos_mem_malloc( + sizeof(wda_cli_set_cmd_t)); + if (NULL == iwcmd) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed", __func__); + return -EINVAL; + } + vos_mem_zero((void *)iwcmd, sizeof(wda_cli_set_cmd_t)); + iwcmd->param_value = sval; + iwcmd->param_vdev_id = sessid; + iwcmd->param_id = paramid; + iwcmd->param_vp_dev = vpdev; + msg.type = WDA_CLI_SET_CMD; + msg.reserved = 0; + msg.bodyptr = (void *)iwcmd; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, + &msg)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post wda_cli_set_cmd message to WDA", + __func__); + vos_mem_free(iwcmd); + ret = -EIO; + } + return ret; +} + +int process_wma_set_command_twoargs(int sessid, int paramid, + int sval, int ssecval, int vpdev) +{ + int ret = 0; + vos_msg_t msg = {0}; + wda_cli_set_cmd_t *iwcmd = vos_mem_malloc(sizeof(*iwcmd)); + + if (NULL == iwcmd) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed!", __func__); + ret = -EINVAL; + goto out; + } + + vos_mem_zero(iwcmd, sizeof(*iwcmd)); + iwcmd->param_value = sval; + iwcmd->param_sec_value = ssecval; + iwcmd->param_vdev_id = sessid; + iwcmd->param_id = paramid; + iwcmd->param_vp_dev = vpdev; + msg.type = WDA_CLI_SET_CMD; + msg.reserved = 0; + msg.bodyptr = iwcmd; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post wda_cli_set_cmd message to WDA", __func__); + vos_mem_free(iwcmd); + ret = -EIO; + } + +out: + return ret; +} + +int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal, + int new_phymode, + hdd_context_t *phddctx) +{ +#ifdef QCA_HT_2040_COEX + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net); + eHalStatus halStatus = eHAL_STATUS_FAILURE; +#endif + v_BOOL_t band_24 = VOS_FALSE, band_5g = VOS_FALSE; + v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE; + tSmeConfigParams smeconfig; + tANI_U32 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; +#ifdef WLAN_FEATURE_11AC + tANI_U32 vhtchanwidth; +#endif + eCsrPhyMode phymode = -EIO, old_phymode; + eCsrBand curr_band = eCSR_BAND_ALL; + + old_phymode = sme_GetPhyMode(hal); + + if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != + sme_GetCBPhyStateFromCBIniValue( + phddctx->cfg_ini->nChannelBondingMode24GHz)) + ch_bond24 = VOS_TRUE; + + if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != + sme_GetCBPhyStateFromCBIniValue( + phddctx->cfg_ini->nChannelBondingMode5GHz)) + ch_bond5g = VOS_TRUE; + + if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_ALL) { + band_24 = band_5g = VOS_TRUE; + } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_24) { + band_24 = VOS_TRUE; + } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_5G) { + band_5g = VOS_TRUE; + } + + vhtchanwidth = phddctx->cfg_ini->vhtChannelWidth; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, ("ch_bond24=%d " + "ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u"), ch_bond24, + ch_bond5g, band_24, band_5g, vhtchanwidth); + switch (new_phymode) { + case IEEE80211_MODE_11A: + if (band_5g) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11a); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) + phymode = eCSR_DOT11_MODE_11a; + else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + case IEEE80211_MODE_11B: + if (band_24) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11b); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) + phymode = eCSR_DOT11_MODE_11b; + else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + case IEEE80211_MODE_11G: + if (band_24) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11g); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) + phymode = eCSR_DOT11_MODE_11g; + else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + /* + * UMAC doesn't have option to set MODE_11NA/MODE_11NG as phymode + * so setting phymode as eCSR_DOT11_MODE_11n and updating the band + * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG + */ + case IEEE80211_MODE_11NA_HT20: + if (band_5g) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_11n; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + curr_band = eCSR_BAND_5G; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + case IEEE80211_MODE_11NA_HT40: + if (band_5g && ch_bond5g) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_11n; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + curr_band = eCSR_BAND_5G; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + case IEEE80211_MODE_11NG_HT20: + if (band_24) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_11n; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + curr_band = eCSR_BAND_24; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; + case IEEE80211_MODE_11NG_HT40: + if (band_24 && ch_bond24) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_11n; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + curr_band = eCSR_BAND_24; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; +#ifdef WLAN_FEATURE_11AC + case IEEE80211_MODE_11AC_VHT20: + case IEEE80211_MODE_11AC_VHT40: + case IEEE80211_MODE_11AC_VHT80: + if (band_5g) { + sme_SetPhyMode(hal, eCSR_DOT11_MODE_11ac); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_11ac; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + } + break; +#endif + case IEEE80211_MODE_2G_AUTO: + sme_SetPhyMode(hal, eCSR_DOT11_MODE_AUTO); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_AUTO; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + curr_band = eCSR_BAND_24; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + break; + case IEEE80211_MODE_5G_AUTO: + sme_SetPhyMode(hal, eCSR_DOT11_MODE_AUTO); + if ((hdd_setBand(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) { + phymode = eCSR_DOT11_MODE_AUTO; + chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + curr_band = eCSR_BAND_5G; + } else { + sme_SetPhyMode(hal, old_phymode); + return -EIO; + } + break; + default: + return -EIO; + } + +#ifdef WLAN_FEATURE_11AC + switch (new_phymode) { + case IEEE80211_MODE_11AC_VHT20: + vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ; + case IEEE80211_MODE_11AC_VHT40: + vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ; + case IEEE80211_MODE_11AC_VHT80: + vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ; + default: + vhtchanwidth = phddctx->cfg_ini->vhtChannelWidth; + } +#endif + + if (phymode != -EIO) { + sme_GetConfigParam(hal, &smeconfig); + smeconfig.csrConfig.phyMode = phymode; + if (phymode == eCSR_DOT11_MODE_11n && + chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) { + if (curr_band == eCSR_BAND_24) + smeconfig.csrConfig.channelBondingMode24GHz = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + else + smeconfig.csrConfig.channelBondingMode5GHz = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + +#ifdef QCA_HT_2040_COEX + smeconfig.csrConfig.obssEnabled = eANI_BOOLEAN_FALSE; + halStatus = sme_SetHT2040Mode(hal, pAdapter->sessionId, + eHT_CHAN_HT20, eANI_BOOLEAN_FALSE); + if (halStatus == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Failed to disable OBSS")); + return -EIO; + } +#endif + } else if (phymode == eCSR_DOT11_MODE_11n && + chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) { + if (curr_band == eCSR_BAND_24) + smeconfig.csrConfig.channelBondingMode24GHz = + phddctx->cfg_ini->nChannelBondingMode24GHz; + else + smeconfig.csrConfig.channelBondingMode5GHz = + phddctx->cfg_ini->nChannelBondingMode5GHz; + +#ifdef QCA_HT_2040_COEX + if (phddctx->cfg_ini->ht2040CoexEnabled) { + smeconfig.csrConfig.obssEnabled = eANI_BOOLEAN_TRUE; + halStatus = sme_SetHT2040Mode(hal, pAdapter->sessionId, + eHT_CHAN_HT20, eANI_BOOLEAN_TRUE); + if (halStatus == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Failed to enable OBSS")); + return -EIO; + } + } +#endif + } +#ifdef WLAN_FEATURE_11AC + smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth; +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SET PHY MODE=%d", + smeconfig.csrConfig.phyMode); + sme_UpdateConfig(hal, &smeconfig); + } + + return 0; +} + +/* set param sub-ioctls */ +static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tSmeConfigParams smeConfig; + int *value = (int *)extra; + int sub_cmd = value[0]; + int set_value = value[1]; + int ret = 0; /* success */ + int enable_pbm, enable_mp; + +#ifdef CONFIG_HAS_EARLYSUSPEND + v_U8_t nEnableSuspendOld; +#endif + INIT_COMPLETION(pWextState->completion_var); + memset(&smeConfig, 0x00, sizeof(smeConfig)); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(sub_cmd) + { + case WE_SET_11D_STATE: + { + if((ENABLE_11D == set_value) || (DISABLE_11D == set_value)) { + + sme_GetConfigParam(hHal, &smeConfig); + smeConfig.csrConfig.Is11dSupportEnabled = (v_BOOL_t)set_value; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("11D state=%d!!"), + smeConfig.csrConfig.Is11dSupportEnabled); + + sme_UpdateConfig(hHal, &smeConfig); + } + else { + return -EINVAL; + } + break; + } + + case WE_WOWL: + { + switch (set_value) + { + case 0x00: + hdd_exit_wowl(pAdapter); + break; + case 0x01: + case 0x02: + case 0x03: + enable_mp = (set_value & 0x01) ? 1 : 0; + enable_pbm = (set_value & 0x02) ? 1 : 0; + hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s", + (enable_mp ? "YES":"NO"), (enable_pbm ? "YES":"NO")); + hdd_enter_wowl(pAdapter, enable_mp, enable_pbm); + break; + default: + hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL", set_value); + ret = -EINVAL; + break; + } + + break; + } + case WE_SET_POWER: + { + switch (set_value) + { + case 0: //Full Power + { + struct statsContext context; + eHalStatus status; + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context, + eSME_FULL_PWR_NEEDED_BY_HDD); + if (eHAL_STATUS_PMC_PENDING == status) + { + unsigned long rc; + rc = wait_for_completion_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting full power")); + } + } + /* either we have a response or we timed out. if we timed + out there is a race condition such that the callback + function could be executing at the same time we are. of + primary concern is if the callback function had already + verified the "magic" but had not yet set the completion + variable when a timeout occurred. we serialize these + activities by invalidating the magic while holding a + shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + hddLog(LOGE, "iwpriv Full Power completed"); + break; + } + case 1: //Enable BMPS + sme_EnablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE); + break; + case 2: //Disable BMPS + sme_DisablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE); + break; + case 3: //Request Bmps + { + struct statsContext context; + eHalStatus status; + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context); + if (eHAL_STATUS_PMC_PENDING == status) + { + unsigned long rc; + rc = wait_for_completion_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while requesting BMPS")); + } + } + /* either we have a response or we timed out. if we + timed out there is a race condition such that the + callback function could be executing at the same + time we are. of primary concern is if the callback + function had already verified the "magic" but had + not yet set the completion variable when a timeout + occurred. we serialize these activities by + invalidating the magic while holding a shared + spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + hddLog(LOGE, "iwpriv Request BMPS completed"); + break; + } + case 4: //Enable IMPS + sme_EnablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE); + break; + case 5: //Disable IMPS + sme_DisablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE); + break; + case 6: //Enable Standby + sme_EnablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE); + break; + case 7: //Disable Standby + sme_DisablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE); + break; + case 8: //Request Standby +#ifdef CONFIG_HAS_EARLYSUSPEND +#endif + break; + case 9: //Start Auto Bmps Timer + sme_StartAutoBmpsTimer(hHal); + break; + case 10://Stop Auto BMPS Timer + sme_StopAutoBmpsTimer(hHal); + break; +#ifdef CONFIG_HAS_EARLYSUSPEND + case 11://suspend to standby +#ifdef CONFIG_HAS_EARLYSUSPEND + nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 1; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld; +#endif + break; + case 12://suspend to deep sleep +#ifdef CONFIG_HAS_EARLYSUSPEND + nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 2; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld; +#endif + break; + case 13://resume from suspend +#ifdef CONFIG_HAS_EARLYSUSPEND +#endif + break; +#endif + case 14://reset wlan (power down/power up) + break; + default: + hddLog(LOGE, "Invalid arg %d in WE_SET_POWER IOCTL", set_value); + ret = -EINVAL; + break; + } + break; + } + + case WE_SET_MAX_ASSOC: + { + if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) || + (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)) + { + ret = -EINVAL; + } + else if ( ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, + set_value, NULL, eANI_BOOLEAN_FALSE) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT")); + ret = -EIO; + } + break; + } + + case WE_SET_SAP_AUTO_CHANNEL_SELECTION: + { + if (set_value == 0 || set_value == 1) + { +#ifdef WLAN_FEATURE_MBSSID + pAdapter->sap_dyn_ini_cfg.apAutoChannelSelection = set_value; +#else + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection + = set_value; +#endif + } + else + { + hddLog(LOGE, + "Invalid arg %d in WE_SET_SAP_AUTO_CHANNEL_SELECTION IOCTL", + set_value); + ret = -EINVAL; + } + break; + } + + case WE_SET_DATA_INACTIVITY_TO: + { + if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) || + (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) || + (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + set_value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)) + { + hddLog(LOGE,"Failure: Could not pass on " + "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info " + "to CCM"); + ret = -EINVAL; + } + break; + } + case WE_SET_MC_RATE: + { + ret = wlan_hdd_set_mc_rate(pAdapter, set_value); + break; + } + case WE_SET_TX_POWER: + { + tSirMacAddr bssid; + + vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE); + if ( sme_SetTxPower(hHal, pAdapter->sessionId, bssid, + pAdapter->device_mode, set_value) != + eHAL_STATUS_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed", + __func__); + return -EIO; + } + break; + } + case WE_SET_MAX_TX_POWER: + { + tSirMacAddr bssid; + tSirMacAddr selfMac; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Setting maximum tx power %d dBm", + __func__, set_value); + vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(selfMac, pHddStaCtx->conn_info.bssId, + VOS_MAC_ADDR_SIZE); + + if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) != + eHAL_STATUS_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed", + __func__); + return -EIO; + } + + break; + } + case WE_SET_MAX_TX_POWER_2_4: + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting maximum tx power %d dBm for 2.4 GHz band", + __func__, set_value); + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value) != + eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Setting maximum tx power failed for 2.4 GHz band", + __func__); + return -EIO; + } + + break; + } + case WE_SET_MAX_TX_POWER_5_0: + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting maximum tx power %d dBm for 5.0 GHz band", + __func__, set_value); + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value) != + eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Setting maximum tx power failed for 5.0 GHz band", + __func__); + return -EIO; + } + + break; + } + case WE_SET_HIGHER_DTIM_TRANSITION: + { + if(!((set_value == eANI_BOOLEAN_FALSE) || + (set_value == eANI_BOOLEAN_TRUE))) + { + hddLog(LOGE, "Dynamic DTIM Incorrect data:%d", set_value); + ret = -EINVAL; + } + else + { + if(pAdapter->higherDtimTransition != set_value) + { + pAdapter->higherDtimTransition = set_value; + hddLog(LOG1, "%s: higherDtimTransition set to :%d", __func__, pAdapter->higherDtimTransition); + } + } + + break; + } + + case WE_SET_TM_LEVEL: + { + hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d", + set_value); + (void)sme_SetThermalLevel(hHal, set_value); + break; + } + + case WE_SET_PHYMODE: + { + hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter); + + ret = wlan_hdd_update_phymode(dev, hHal, set_value, phddctx); + break; + } + + case WE_SET_NSS: + { + hddLog(LOG1, "Set NSS = %d", set_value); + if ((set_value > 2) || (set_value <= 0)) { + hddLog(LOGE, "NSS greater than 2 not supported"); + ret = -EINVAL; + } else { + if (VOS_STATUS_SUCCESS != + hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter), set_value)) + ret = -EINVAL; + } + break; + } + + case WE_SET_GTX_HT_MCS: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_HT_MCS, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_VHT_MCS: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_VHT_MCS, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_USRCFG: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_USR_CFG, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_THRE: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_THRE, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_MARGIN: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MARGIN, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_STEP: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_STEP, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_MINTPC: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MINTPC, + set_value, GTX_CMD); + break; + } + + case WE_SET_GTX_BWMASK: + { + hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_BW_MASK, + set_value, GTX_CMD); + break; + } + + case WE_SET_LDPC: + { + tANI_U32 value; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + }uHTCapabilityInfo; + + hddLog(LOG1, "LDPC val %d", set_value); + /* get the HT capability info*/ + ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value); + if (eHAL_STATUS_SUCCESS != ret) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: could not get HT capability info", + __func__); + return -EIO; + } + + uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value; + if ((set_value && (uHTCapabilityInfo.htCapInfo.advCodingCap)) || + (!set_value)) { + ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_ADVANCE_CODING, + set_value); + } + + if (ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to set LDPC value"); + + break; + } + + case WE_SET_TX_STBC: + { + tANI_U32 value; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + }uHTCapabilityInfo; + + hddLog(LOG1, "TX_STBC val %d", set_value); + /* get the HT capability info*/ + ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value); + if (eHAL_STATUS_SUCCESS != ret) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: could not get HT capability info", + __func__); + return -EIO; + } + + uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value; + if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC)) || + (!set_value)) { + ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_TX_STBC, + set_value); + } + + if (ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to set TX STBC value"); + + break; + } + + case WE_SET_RX_STBC: + { + tANI_U32 value; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + }uHTCapabilityInfo; + + hddLog(LOG1, "WMI_VDEV_PARAM_RX_STBC val %d", set_value); + /* get the HT capability info*/ + ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value); + if (eHAL_STATUS_SUCCESS != ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get HT capability info", + __func__); + return -EIO; + } + + uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value; + if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC)) || + (!set_value)) { + ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_RX_STBC, + (!set_value)? set_value : + uHTCapabilityInfo.htCapInfo.rxSTBC); + } + + if (ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to set RX STBC value"); + break; + } + + case WE_SET_SHORT_GI: + { + hddLog(LOG1, "WMI_VDEV_PARAM_SGI val %d", set_value); + ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ, + set_value); + if (ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to set ShortGI value"); + break; + } + + case WE_SET_RTSCTS: + { + u_int32_t value; + + hddLog(LOG1, "WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x", set_value); + + if ((set_value & HDD_RTSCTS_EN_MASK) == HDD_RTSCTS_ENABLE) + value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->RTSThreshold; + else if (((set_value & HDD_RTSCTS_EN_MASK) == 0) || + ((set_value & HDD_RTSCTS_EN_MASK) == HDD_CTS_ENABLE)) + value = WNI_CFG_RTS_THRESHOLD_STAMAX; + else + return -EIO; + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_ENABLE_RTSCTS, + set_value, VDEV_CMD); + if (!ret) { + if (ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, value, + ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != + eHAL_STATUS_SUCCESS) { + hddLog(LOGE, "FAILED TO SET RTSCTS"); + return -EIO; + } + } + + break; + } + + case WE_SET_CHWIDTH: + { + bool chwidth = false; + hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter); + /*updating channel bonding only on 5Ghz*/ + hddLog(LOG1, "WMI_VDEV_PARAM_CHWIDTH val %d", set_value); + if (set_value > eHT_CHANNEL_WIDTH_80MHZ) { + hddLog(LOGE, "Invalid channel width 0->20 1->40 2->80"); + return -EINVAL; + } + + if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != + csrConvertCBIniValueToPhyCBState( + phddctx->cfg_ini->nChannelBondingMode5GHz))) + chwidth = true; + + sme_GetConfigParam(hHal, &smeConfig); + switch (set_value) { + case eHT_CHANNEL_WIDTH_20MHZ: + smeConfig.csrConfig.channelBondingMode5GHz = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + break; + case eHT_CHANNEL_WIDTH_40MHZ: + if (chwidth) + smeConfig.csrConfig.channelBondingMode5GHz = + phddctx->cfg_ini->nChannelBondingMode5GHz; + else + return -EINVAL; + + break; +#ifdef WLAN_FEATURE_11AC + case eHT_CHANNEL_WIDTH_80MHZ: + if (chwidth) + smeConfig.csrConfig.channelBondingMode5GHz = + phddctx->cfg_ini->nChannelBondingMode5GHz; + else + return -EINVAL; + + break; +#endif + + default: + return -EINVAL; + } + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_CHWIDTH, + set_value, VDEV_CMD); + if (!ret) + sme_UpdateConfig(hHal, &smeConfig); + + break; + } + + case WE_SET_ANI_EN_DIS: + { + hddLog(LOG1, "WMI_PDEV_PARAM_ANI_ENABLE val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_ENABLE, + set_value, PDEV_CMD); + break; + } + + case WE_SET_ANI_POLL_PERIOD: + { + hddLog(LOG1, "WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_POLL_PERIOD, + set_value, PDEV_CMD); + break; + } + + case WE_SET_ANI_LISTEN_PERIOD: + { + hddLog(LOG1, "WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, + set_value, PDEV_CMD); + break; + } + + case WE_SET_ANI_OFDM_LEVEL: + { + hddLog(LOG1, "WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_OFDM_LEVEL, + set_value, PDEV_CMD); + break; + } + + case WE_SET_ANI_CCK_LEVEL: + { + hddLog(LOG1, "WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_CCK_LEVEL, + set_value, PDEV_CMD); + break; + } + + case WE_SET_DYNAMIC_BW: + { + hddLog(LOG1, "WMI_PDEV_PARAM_DYNAMIC_BW val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_DYNAMIC_BW, + set_value, PDEV_CMD); + break; + } + + case WE_SET_CTS_CBW: + { + hddLog(LOG1, "WE_SET_CTS_CBW val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_CTS_CBW, + set_value, PDEV_CMD); + break; + } + + case WE_SET_11N_RATE: + { + u_int8_t preamble = 0, nss = 0, rix = 0; + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d", set_value); + + if (set_value != 0xff) { + rix = RC_2_RATE_IDX(set_value); + if (set_value & 0x80) { + preamble = WMI_RATE_PREAMBLE_HT; + nss = HT_RC_2_STREAMS(set_value) -1; + } else { + nss = 0; + rix = RC_2_RATE_IDX(set_value); + if (set_value & 0x10) { + preamble = WMI_RATE_PREAMBLE_CCK; + /* Enable Short preamble always for CCK except 1mbps */ + if(rix != 0x3) + rix |= 0x4; + } else + preamble = WMI_RATE_PREAMBLE_OFDM; + } + set_value = (preamble << 6) | (nss << 4) | rix; + } + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x\ + nss %d", set_value, rix, preamble, nss); + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_FIXED_RATE, + set_value, VDEV_CMD); + break; + } + + case WE_SET_VHT_RATE: + { + u_int8_t preamble = 0, nss = 0, rix = 0; + + if (set_value != 0xff) { + rix = RC_2_RATE_IDX_11AC(set_value); + preamble = WMI_RATE_PREAMBLE_VHT; + nss = HT_RC_2_STREAMS_11AC(set_value) -1; + + set_value = (preamble << 6) | (nss << 4) | rix; + } + hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x\ + nss %d", set_value, rix, preamble, nss); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_FIXED_RATE, + set_value, VDEV_CMD); + break; + } + + case WE_SET_AMPDU: + { + hddLog(LOG1, "SET AMPDU val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMPDU, + set_value, GEN_CMD); + break; + } + + case WE_SET_AMSDU: + { + hddLog(LOG1, "SET AMSDU val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMSDU, + set_value, GEN_CMD); + break; + } + + case WE_SET_BURST_ENABLE: + { + hddLog(LOG1, "SET Burst enable val %d", set_value); + if ((set_value == 0) || (set_value == 1)) { + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_ENABLE, + set_value, PDEV_CMD); + } + else + ret = -EINVAL; + break; + } + case WE_SET_BURST_DUR: + { + hddLog(LOG1, "SET Burst duration val %d", set_value); + if ((set_value > 0) && (set_value <= 8192)) { + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_DUR, + set_value, PDEV_CMD); + } + else + ret = -EINVAL; + break; + } + + case WE_SET_TX_CHAINMASK: + { + hddLog(LOG1, "WMI_PDEV_PARAM_TX_CHAIN_MASK val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TX_CHAIN_MASK, + set_value, PDEV_CMD); + break; + } + + case WE_SET_RX_CHAINMASK: + { + hddLog(LOG1, "WMI_PDEV_PARAM_RX_CHAIN_MASK val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_RX_CHAIN_MASK, + set_value, PDEV_CMD); + break; + } + + case WE_SET_TXPOW_2G: + { + hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TXPOWER_LIMIT2G, + set_value, PDEV_CMD); + break; + } + + case WE_SET_TXPOW_5G: + { + hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TXPOWER_LIMIT5G, + set_value, PDEV_CMD); + break; + } + + case WE_SET_POWER_GATING: + { + hddLog(LOG1, "WMI_PDEV_PARAM_POWER_GATING_SLEEP val %d", + set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_POWER_GATING_SLEEP, + (set_value)? true:false, PDEV_CMD); + break; + } + + /* Firmware debug log */ + case WE_DBGLOG_LOG_LEVEL: + { + hddLog(LOG1, "WE_DBGLOG_LOG_LEVEL val %d", set_value); + pHddCtx->fw_log_settings.dl_loglevel = set_value; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_LOG_LEVEL, + set_value, DBG_CMD); + break; + } + + case WE_DBGLOG_VAP_ENABLE: + { + hddLog(LOG1, "WE_DBGLOG_VAP_ENABLE val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_VAP_ENABLE, + set_value, DBG_CMD); + break; + } + + case WE_DBGLOG_VAP_DISABLE: + { + hddLog(LOG1, "WE_DBGLOG_VAP_DISABLE val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_VAP_DISABLE, + set_value, DBG_CMD); + break; + } + + case WE_DBGLOG_MODULE_ENABLE: + { + hddLog(LOG1, "WE_DBGLOG_MODULE_ENABLE val %d", set_value); + pHddCtx->fw_log_settings.enable = set_value; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_MODULE_ENABLE, + set_value, DBG_CMD); + break; + } + + case WE_DBGLOG_MODULE_DISABLE: + { + hddLog(LOG1, "WE_DBGLOG_MODULE_DISABLE val %d", set_value); + pHddCtx->fw_log_settings.enable = set_value; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_MODULE_DISABLE, + set_value, DBG_CMD); + break; + } + case WE_DBGLOG_MOD_LOG_LEVEL: + { + hddLog(LOG1, "WE_DBGLOG_MOD_LOG_LEVEL val %d", set_value); + + if (pHddCtx->fw_log_settings.index >= MAX_MOD_LOGLEVEL) { + pHddCtx->fw_log_settings.index = 0; + } + + pHddCtx->fw_log_settings.dl_mod_loglevel[pHddCtx-> + fw_log_settings.index] = set_value; + pHddCtx->fw_log_settings.index++; + + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_MOD_LOG_LEVEL, + set_value, DBG_CMD); + break; + } + + case WE_DBGLOG_TYPE: + { + hddLog(LOG1, "WE_DBGLOG_TYPE val %d", set_value); + pHddCtx->fw_log_settings.dl_type = set_value; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_TYPE, + set_value, DBG_CMD); + break; + } + case WE_DBGLOG_REPORT_ENABLE: + { + hddLog(LOG1, "WE_DBGLOG_REPORT_ENABLE val %d", set_value); + pHddCtx->fw_log_settings.dl_report = set_value; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_DBGLOG_REPORT_ENABLE, + set_value, DBG_CMD); + break; + } + + case WE_SET_TXRX_FWSTATS: + { + hddLog(LOG1, "WE_SET_TXRX_FWSTATS val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID, + set_value, VDEV_CMD); + break; + } + + case WE_TXRX_FWSTATS_RESET: + { + hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMA_VDEV_TXRX_FWSTATS_RESET_CMDID, + set_value, VDEV_CMD); + break; + } + + case WE_PPS_PAID_MATCH: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + + hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_PAID_MATCH, + set_value, PPS_CMD); + break; + } + + case WE_PPS_GID_MATCH: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_GID_MATCH, + set_value, PPS_CMD); + break; + } + + case WE_PPS_EARLY_TIM_CLEAR: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR, + set_value, PPS_CMD); + break; + } + + case WE_PPS_EARLY_DTIM_CLEAR: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR, + set_value, PPS_CMD); + break; + } + + case WE_PPS_EOF_PAD_DELIM: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EOF_PAD_DELIM, + set_value, PPS_CMD); + break; + } + + case WE_PPS_MACADDR_MISMATCH: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_MACADDR_MISMATCH, + set_value, PPS_CMD); + break; + } + + case WE_PPS_DELIM_CRC_FAIL: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_DELIM_CRC_FAIL, + set_value, PPS_CMD); + break; + } + + + case WE_PPS_GID_NSTS_ZERO: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_GID_NSTS_ZERO, + set_value, PPS_CMD); + break; + } + + + case WE_PPS_RSSI_CHECK: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return EINVAL; + hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_RSSI_CHECK, + set_value, PPS_CMD); + break; + } + + case WE_PPS_5G_EBT: + { + if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION) + return -EINVAL; + + hddLog(LOG1, "WMI_VDEV_PPS_5G_EBT val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_5G_EBT, + set_value, PPS_CMD); + break; + } + + case WE_SET_HTSMPS: + { + hddLog(LOG1, "WE_SET_HTSMPS val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_SMPS_FORCE_MODE_CMDID, + set_value, VDEV_CMD); + break; + } + + + case WE_SET_QPOWER_MAX_PSPOLL_COUNT: + { + hddLog(LOG1, "WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d", + set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT, + set_value, QPOWER_CMD); + break; + } + + case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE: + { + hddLog(LOG1, "WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d", + set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE, + set_value, QPOWER_CMD); + break; + } + + case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL: + { + hddLog(LOG1, "WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d", + set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL, + set_value, QPOWER_CMD); + break; + } + + case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL: + { + hddLog(LOG1, "WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d", + set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL, + set_value, QPOWER_CMD); + break; + } + case WE_SET_SCAN_BAND_PREFERENCE: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) { + ret = -EINVAL; + break; + } + hddLog(LOG1, "WE_SET_BAND_PREFERRENCE val %d ", set_value); + + if (eCSR_BAND_ALL == set_value || + eCSR_BAND_24 == set_value || eCSR_BAND_5G == set_value) { + sme_GetConfigParam(hHal, &smeConfig); + smeConfig.csrConfig.scanBandPreference = set_value; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "set band scan preference = %d", + smeConfig.csrConfig.scanBandPreference); + + sme_UpdateConfig(hHal, &smeConfig); + } + else { + ret = -EINVAL; + } + break; + + } + + case WE_MCC_CONFIG_LATENCY: + { + tVOS_CONCURRENCY_MODE concurrent_state = 0; + v_U8_t first_adapter_operating_channel = 0; + int ret = 0; /* success */ + + hddLog(LOG1, "iwpriv cmd to set MCC latency with val %dms", + set_value); + /** + * Check if concurrency mode is active. + * Need to modify this code to support MCC modes other than STA/P2P + */ + concurrent_state = hdd_get_concurrency_mode(); + if ((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) || + (concurrent_state == (VOS_STA | VOS_P2P_GO))) + { + hddLog(LOG1, "STA & P2P are both enabled"); + /** + * The channel number and latency are formatted in + * a bit vector then passed on to WMA layer. + +**********************************************+ + |bits 31-16 | bits 15-8 | bits 7-0 | + | Unused | latency - Chan. 1 | channel no. | + +**********************************************+ + */ + /* Get the operating channel of the designated vdev */ + first_adapter_operating_channel = + hdd_get_operating_channel + ( + pAdapter->pHddCtx, + pAdapter->device_mode + ); + /* Move the time latency for the adapter to bits 15-8 */ + set_value = set_value << 8; + /* Store the channel number at bits 7-0 of the bit vector */ + set_value = set_value | first_adapter_operating_channel; + /* Send command to WMA */ + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMA_VDEV_MCC_SET_TIME_LATENCY, + set_value, VDEV_CMD); + } + else + { + hddLog(LOG1, "%s: MCC is not active. Exit w/o setting latency", + __func__); + } + break; + } + + case WE_MCC_CONFIG_QUOTA: + { + v_U8_t first_adapter_operating_channel = 0; + v_U8_t second_adapter_opertaing_channel = 0; + hdd_adapter_t *staAdapter = NULL; + int ret = 0; /* success */ + + tVOS_CONCURRENCY_MODE concurrent_state = hdd_get_concurrency_mode(); + hddLog(LOG1, "iwpriv cmd to set MCC quota with val %dms", + set_value); + /** + * Check if concurrency mode is active. + * Need to modify this code to support MCC modes other than STA/P2P + */ + if ((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) || + (concurrent_state == (VOS_STA | VOS_P2P_GO))) + { + hddLog(LOG1, "STA & P2P are both enabled"); + /** + * The channel numbers for both adapters and the time + * quota for the 1st adapter, i.e., one specified in cmd + * are formatted as a bit vector then passed on to WMA + +************************************************************+ + |bit 31-24 | bit 23-16 | bits 15-8 | bits 7-0 | + | Unused | Quota for | chan. # for | chan. # for | + | | 1st chan. | 1st chan. | 2nd chan. | + +************************************************************+ + */ + /* Get the operating channel of the specified vdev */ + first_adapter_operating_channel = + hdd_get_operating_channel + ( + pAdapter->pHddCtx, + pAdapter->device_mode + ); + hddLog(LOG1, "1st channel No.:%d and quota:%dms", + first_adapter_operating_channel, set_value); + /* Move the time quota for first channel to bits 15-8 */ + set_value = set_value << 8; + /** Store the channel number of 1st channel at bits 7-0 + * of the bit vector + */ + set_value = set_value | first_adapter_operating_channel; + /* Find out the 2nd MCC adapter and its operating channel */ + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + { + /* iwpriv cmd was issued on wlan0; get p2p0 vdev channel */ + if ((concurrent_state & VOS_P2P_CLIENT) != 0) + { + /* The 2nd MCC vdev is P2P client */ + staAdapter = hdd_get_adapter(pAdapter->pHddCtx, + WLAN_HDD_P2P_CLIENT); + } else + { + /* The 2nd MCC vdev is P2P GO */ + staAdapter = hdd_get_adapter(pAdapter->pHddCtx, + WLAN_HDD_P2P_GO); + } + } + else + { + /* iwpriv cmd was issued on p2p0; get wlan0 vdev channel */ + staAdapter = hdd_get_adapter(pAdapter->pHddCtx, + WLAN_HDD_INFRA_STATION); + } + if (staAdapter != NULL) + { + second_adapter_opertaing_channel = + hdd_get_operating_channel + ( + staAdapter->pHddCtx, + staAdapter->device_mode + ); + hddLog(LOG1, "2nd vdev channel No. is:%d", + second_adapter_opertaing_channel); + /** Now move the time quota and channel number of the + * 1st adapter to bits 23-16 and bits 15-8 of the bit + * vector, respectively. + */ + set_value = set_value << 8; + /* Store the channel number for 2nd MCC vdev at bits + * 7-0 of set_value + */ + set_value = set_value | second_adapter_opertaing_channel; + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMA_VDEV_MCC_SET_TIME_QUOTA, + set_value, VDEV_CMD); + } + else + { + hddLog(LOGE, "NULL adapter handle. Exit"); + } + } + else + { + hddLog(LOG1, "%s: MCC is not active. Exit w/o setting latency", + __func__); + } + break; + } + case WE_SET_DEBUG_LOG: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); +#ifdef QCA_PKT_PROTO_TRACE + /* Trace buffer dump only */ + if (VOS_PKT_TRAC_DUMP_CMD == set_value) + { + vos_pkt_trace_buf_dump(); + break; + } +#endif /* QCA_PKT_PROTO_TRACE */ + pHddCtx->cfg_ini->gEnableDebugLog = set_value; + sme_UpdateConnectDebug(pHddCtx->hHal, set_value); + break; + } + case WE_SET_EARLY_RX_ADJUST_ENABLE: + { + hddLog(LOG1, "SET early_rx enable val %d", set_value); + if ((set_value == 0) || (set_value == 1)) { + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, + set_value, VDEV_CMD); + } + else + ret = -EINVAL; + break; + } + case WE_SET_EARLY_RX_TGT_BMISS_NUM: + { + hddLog(LOG1, "SET early_rx bmiss val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, + set_value, VDEV_CMD); + break; + } + case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE: + { + hddLog(LOG1, "SET early_rx bmiss sample cycle %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, + set_value, VDEV_CMD); + break; + } + case WE_SET_EARLY_RX_SLOP_STEP: + { + hddLog(LOG1, "SET early_rx bmiss slop step val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, + set_value, VDEV_CMD); + break; + } + case WE_SET_EARLY_RX_INIT_SLOP: + { + hddLog(LOG1, "SET early_rx init slop step val %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, + set_value, VDEV_CMD); + break; + } + case WE_SET_EARLY_RX_ADJUST_PAUSE: + { + hddLog(LOG1, "SET early_rx adjust pause %d", set_value); + if ((set_value == 0) || (set_value == 1)) { + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, + set_value, VDEV_CMD); + } + else + ret = -EINVAL; + break; + } + case WE_SET_EARLY_RX_DRIFT_SAMPLE: + { + hddLog(LOG1, "SET early_rx drift sample %d", set_value); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, + set_value, VDEV_CMD); + break; + } + default: + { + hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd); + ret = -EINVAL; + break; + } + } + return ret; +} + +/* set param sub-ioctls */ +static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOS_STATUS vstatus; + int sub_cmd; + int ret = 0; /* success */ + char *pBuffer = NULL; + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); +#ifdef WLAN_FEATURE_VOWIFI + hdd_config_t *pConfig = pHddCtx->cfg_ini; +#endif /* WLAN_FEATURE_VOWIFI */ + struct iw_point s_priv_data; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + return -EINVAL; + } + + /* make sure all params are correctly passed to function */ + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + + /* ODD number is used for set, copy data using copy_from_user */ + pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + if (NULL == pBuffer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received length %d", __func__, s_priv_data.length); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received data %s", __func__, pBuffer); + + switch(sub_cmd) + { + case WE_WOWL_ADD_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN"); + hdd_add_wowl_ptrn(pAdapter, pBuffer); + break; + case WE_WOWL_DEL_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN"); + hdd_del_wowl_ptrn(pAdapter, pBuffer); + break; +#if defined WLAN_FEATURE_VOWIFI + case WE_NEIGHBOR_REPORT_REQUEST: + { + tRrmNeighborReq neighborReq; + tRrmNeighborRspCallbackInfo callbackInfo; + + if (pConfig->fRrmEnable) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request"); + neighborReq.no_ssid = (s_priv_data.length - 1) ? false : true ; + if( !neighborReq.no_ssid ) + { + neighborReq.ssid.length = (s_priv_data.length - 1) > 32 ? + 32 : (s_priv_data.length - 1); + vos_mem_copy(neighborReq.ssid.ssId, pBuffer, + neighborReq.ssid.length); + } + + callbackInfo.neighborRspCallback = NULL; + callbackInfo.neighborRspCallbackContext = NULL; + callbackInfo.timeout = 5000; //5 seconds + sme_NeighborReportRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &neighborReq, &callbackInfo ); + } + else + { + hddLog(LOGE, "%s: Ignoring neighbor request as RRM is not enabled", __func__); + ret = -EINVAL; + } + } + break; +#endif + case WE_SET_AP_WPS_IE: + hddLog( LOGE, "Received WE_SET_AP_WPS_IE" ); + sme_updateP2pIe(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer, + s_priv_data.length); + break; + case WE_SET_CONFIG: + vstatus = hdd_execute_global_config_command(pHddCtx, pBuffer); +#ifdef WLAN_FEATURE_MBSSID + if (vstatus == VOS_STATUS_E_PERM) { + vstatus = hdd_execute_sap_dyn_config_command(pAdapter, pBuffer); + if (vstatus == VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Stored in Dynamic SAP ini config", __func__); + + } +#endif + if (VOS_STATUS_SUCCESS != vstatus) + { + ret = -EINVAL; + } + break; + default: + { + hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd); + ret = -EINVAL; + break; + } + } + kfree(pBuffer); + return ret; +} + +/* get param sub-ioctls */ +static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + int *value = (int *)extra; + int ret = 0; /* success */ + hdd_context_t *wmahddCtxt = WLAN_HDD_GET_CTX(pAdapter); + void *wmapvosContext = wmahddCtxt->pvosContext; + tSmeConfigParams smeConfig; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch (value[0]) + { + case WE_GET_11D_STATE: + { + sme_GetConfigParam(hHal,&smeConfig); + + *value = smeConfig.csrConfig.Is11dSupportEnabled; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%d!!"),*value); + + break; + } + + case WE_IBSS_STATUS: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****Return IBSS Status*****"); + break; + + case WE_GET_WLAN_DBG: + { + vos_trace_display(); + *value = 0; + break; + } + case WE_GET_MAX_ASSOC: + { + if (ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT")); + ret = -EIO; + } + break; + } + + case WE_GET_SAP_AUTO_CHANNEL_SELECTION: + { +#ifdef WLAN_FEATURE_MBSSID + *value = pAdapter->sap_dyn_ini_cfg.apAutoChannelSelection; +#else + *value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection; +#endif + break; + } + case WE_GET_CONCURRENCY_MODE: + { + *value = hdd_get_concurrency_mode ( ); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("concurrency mode=%d"),*value); + break; + } + + case WE_GET_NSS: + { + sme_GetConfigParam(hHal, &smeConfig); + *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2; + hddLog(LOG1, "GET_NSS: Current NSS:%d", *value); + break; + } + + case WE_GET_GTX_HT_MCS: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_HT_MCS, + GTX_CMD); + break; + } + + case WE_GET_GTX_VHT_MCS: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_VHT_MCS, + GTX_CMD); + break; + } + + case WE_GET_GTX_USRCFG: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_USR_CFG, + GTX_CMD); + break; + } + + case WE_GET_GTX_THRE: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_THRE, + GTX_CMD); + break; + } + + case WE_GET_GTX_MARGIN: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MARGIN, + GTX_CMD); + break; + } + + case WE_GET_GTX_STEP: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_STEP, + GTX_CMD); + break; + } + + case WE_GET_GTX_MINTPC: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_MINTPC, + GTX_CMD); + break; + } + + case WE_GET_GTX_BWMASK: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_GTX_BW_MASK, + GTX_CMD); + break; + } + + case WE_GET_LDPC: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_LDPC"); + *value = sme_GetHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_ADVANCE_CODING); + break; + } + + case WE_GET_TX_STBC: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_TX_STBC"); + *value = sme_GetHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_TX_STBC); + break; + } + + case WE_GET_RX_STBC: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_RX_STBC"); + *value = sme_GetHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_RX_STBC); + break; + } + + case WE_GET_SHORT_GI: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_SGI"); + *value = sme_GetHTConfig(hHal, pAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ); + break; + } + + case WE_GET_RTSCTS: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_ENABLE_RTSCTS"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_ENABLE_RTSCTS, + VDEV_CMD); + break; + } + + case WE_GET_CHWIDTH: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_CHWIDTH"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_CHWIDTH, + VDEV_CMD); + break; + } + + case WE_GET_ANI_EN_DIS: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_ENABLE"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_ENABLE, + PDEV_CMD); + break; + } + + case WE_GET_ANI_POLL_PERIOD: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_POLL_PERIOD"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_POLL_PERIOD, + PDEV_CMD); + break; + } + + case WE_GET_ANI_LISTEN_PERIOD: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, + PDEV_CMD); + break; + } + + case WE_GET_ANI_OFDM_LEVEL: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_OFDM_LEVEL, + PDEV_CMD); + break; + } + + case WE_GET_ANI_CCK_LEVEL: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_ANI_CCK_LEVEL, + PDEV_CMD); + break; + } + + case WE_GET_DYNAMIC_BW: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_DYNAMIC_BW, + PDEV_CMD); + break; + } + + case WE_GET_11N_RATE: + { + hddLog(LOG1, "GET WMI_VDEV_PARAM_FIXED_RATE"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PARAM_FIXED_RATE, + VDEV_CMD); + break; + } + + case WE_GET_AMPDU: + { + hddLog(LOG1, "GET AMPDU"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMPDU, + GEN_CMD); + break; + } + + case WE_GET_AMSDU: + { + hddLog(LOG1, "GET AMSDU"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)GEN_VDEV_PARAM_AMSDU, + GEN_CMD); + break; + } + + case WE_GET_BURST_ENABLE: + { + hddLog(LOG1, "GET Burst enable value"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_ENABLE, + PDEV_CMD); + break; + } + case WE_GET_BURST_DUR: + { + hddLog(LOG1, "GET Burst Duration value"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_BURST_DUR, + PDEV_CMD); + break; + } + + case WE_GET_TX_CHAINMASK: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TX_CHAIN_MASK, + PDEV_CMD); + break; + } + + case WE_GET_RX_CHAINMASK: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_RX_CHAIN_MASK"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_RX_CHAIN_MASK, + PDEV_CMD); + break; + } + + case WE_GET_TXPOW_2G: + { + tANI_U32 txpow2g = 0; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TXPOWER_LIMIT2G, + PDEV_CMD); + if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal, + WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow2g) ) + { + return -EIO; + } + hddLog(LOG1, "2G tx_power %d", txpow2g); + break; + } + + case WE_GET_TXPOW_5G: + { + tANI_U32 txpow5g = 0; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_TXPOWER_LIMIT5G, + PDEV_CMD); + if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal, + WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow5g) ) + { + return -EIO; + } + hddLog(LOG1, "5G tx_power %d", txpow5g); + break; + } + + case WE_GET_POWER_GATING: + { + hddLog(LOG1, "GET WMI_PDEV_PARAM_POWER_GATING_SLEEP"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_PDEV_PARAM_POWER_GATING_SLEEP, + PDEV_CMD); + break; + } + + case WE_GET_PPS_PAID_MATCH: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_PAID_MATCH, + PPS_CMD); + break; + } + + case WE_GET_PPS_GID_MATCH: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_GID_MATCH, + PPS_CMD); + break; + } + + case WE_GET_PPS_EARLY_TIM_CLEAR: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR, + PPS_CMD); + break; + } + + case WE_GET_PPS_EARLY_DTIM_CLEAR: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR, + PPS_CMD); + break; + } + + case WE_GET_PPS_EOF_PAD_DELIM: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_EOF_PAD_DELIM, + PPS_CMD); + break; + } + + case WE_GET_PPS_MACADDR_MISMATCH: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_MACADDR_MISMATCH, + PPS_CMD); + break; + } + + case WE_GET_PPS_DELIM_CRC_FAIL: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_DELIM_CRC_FAIL, + PPS_CMD); + break; + } + + case WE_GET_PPS_GID_NSTS_ZERO: + { + hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_GID_NSTS_ZERO, + PPS_CMD); + break; + } + + case WE_GET_PPS_RSSI_CHECK: + { + + hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_VDEV_PPS_RSSI_CHECK, + PPS_CMD); + break; + } + + case WE_GET_QPOWER_MAX_PSPOLL_COUNT: + { + hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT, + QPOWER_CMD); + break; + } + + case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE: + { + hddLog(LOG1, "WE_GET_QPOWER_MAX_TX_BEFORE_WAKE"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE, + QPOWER_CMD); + break; + } + + case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL: + { + hddLog(LOG1, "WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL, + QPOWER_CMD); + break; + } + + case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL: + { + hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT"); + *value = wma_cli_get_command(wmapvosContext, + (int)pAdapter->sessionId, + (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL, + QPOWER_CMD); + break; + } + + case WE_GET_SCAN_BAND_PREFERENCE: + { + sme_GetConfigParam(hHal, &smeConfig); + *value = smeConfig.csrConfig.scanBandPreference; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "scanBandPreference = %d", *value); + break; + } + + default: + { + hddLog(LOGE, "Invalid IOCTL get_value command %d", value[0]); + break; + } + } + + return ret; +} + +/* set param sub-ioctls */ +int iw_set_three_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int *value = (int *)extra; + int sub_cmd = value[0]; + int ret = 0; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(sub_cmd) { + + case WE_SET_WLAN_DBG: + vos_trace_setValue( value[1], value[2], value[3]); + break; + + case WE_SET_SAP_CHANNELS: + ret = iw_softap_set_channel_range( dev, value[1], value[2], value[3]); + break; + + default: + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd ); + break; + + } + return ret; +} + +static int iw_get_char_setnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int sub_cmd = wrqu->data.flags; +#ifdef WLAN_FEATURE_11W + hdd_wext_state_t *pWextState; +#endif + +#ifdef WLAN_FEATURE_11W + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); +#endif + + if (NULL == WLAN_HDD_GET_CTX(pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD Context is NULL!", __func__); + + return -EINVAL; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(sub_cmd) + { + case WE_WLAN_VERSION: + { + hdd_wlan_get_version(pAdapter, wrqu, extra); + break; + } + + case WE_GET_STATS: + { + hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats; + + snprintf(extra, WE_MAX_STR_LEN, + "\nTransmit" + "\ncalled %u, dropped %u, backpressured %u, queued %u" + "\n dropped BK %u, BE %u, VI %u, VO %u" + "\n classified BK %u, BE %u, VI %u, VO %u" + "\nbackpressured BK %u, BE %u, VI %u, VO %u" + "\n queued BK %u, BE %u, VI %u, VO %u" + "\nfetched %u, empty %u, lowres %u, deqerr %u" + "\ndequeued %u, depressured %u, deque-depressured %u, completed %u, flushed %u" + "\n fetched BK %u, BE %u, VI %u, VO %u" + "\n dequeued BK %u, BE %u, VI %u, VO %u" + "\n depressured BK %u, BE %u, VI %u, VO %u" + "\nDeque depressured BK %u, BE %u, VI %u, VO %u" + "\n flushed BK %u, BE %u, VI %u, VO %u" + "\n\nReceive" + "\nchains %u, packets %u, dropped %u, delivered %u, refused %u" + "\n", + pStats->txXmitCalled, + pStats->txXmitDropped, + pStats->txXmitBackPressured, + pStats->txXmitQueued, + + pStats->txXmitDroppedAC[WLANTL_AC_BK], + pStats->txXmitDroppedAC[WLANTL_AC_BE], + pStats->txXmitDroppedAC[WLANTL_AC_VI], + pStats->txXmitDroppedAC[WLANTL_AC_VO], + + pStats->txXmitClassifiedAC[WLANTL_AC_BK], + pStats->txXmitClassifiedAC[WLANTL_AC_BE], + pStats->txXmitClassifiedAC[WLANTL_AC_VI], + pStats->txXmitClassifiedAC[WLANTL_AC_VO], + + pStats->txXmitBackPressuredAC[WLANTL_AC_BK], + pStats->txXmitBackPressuredAC[WLANTL_AC_BE], + pStats->txXmitBackPressuredAC[WLANTL_AC_VI], + pStats->txXmitBackPressuredAC[WLANTL_AC_VO], + + pStats->txXmitQueuedAC[WLANTL_AC_BK], + pStats->txXmitQueuedAC[WLANTL_AC_BE], + pStats->txXmitQueuedAC[WLANTL_AC_VI], + pStats->txXmitQueuedAC[WLANTL_AC_VO], + + pStats->txFetched, + pStats->txFetchEmpty, + pStats->txFetchLowResources, + pStats->txFetchDequeueError, + + pStats->txFetchDequeued, + pStats->txFetchDePressured, + pStats->txDequeDePressured, + pStats->txCompleted, + pStats->txFlushed, + + pStats->txFetchedAC[WLANTL_AC_BK], + pStats->txFetchedAC[WLANTL_AC_BE], + pStats->txFetchedAC[WLANTL_AC_VI], + pStats->txFetchedAC[WLANTL_AC_VO], + + pStats->txFetchDequeuedAC[WLANTL_AC_BK], + pStats->txFetchDequeuedAC[WLANTL_AC_BE], + pStats->txFetchDequeuedAC[WLANTL_AC_VI], + pStats->txFetchDequeuedAC[WLANTL_AC_VO], + + pStats->txFetchDePressuredAC[WLANTL_AC_BK], + pStats->txFetchDePressuredAC[WLANTL_AC_BE], + pStats->txFetchDePressuredAC[WLANTL_AC_VI], + pStats->txFetchDePressuredAC[WLANTL_AC_VO], + + pStats->txDequeDePressuredAC[WLANTL_AC_BK], + pStats->txDequeDePressuredAC[WLANTL_AC_BE], + pStats->txDequeDePressuredAC[WLANTL_AC_VI], + pStats->txDequeDePressuredAC[WLANTL_AC_VO], + + pStats->txFlushedAC[WLANTL_AC_BK], + pStats->txFlushedAC[WLANTL_AC_BE], + pStats->txFlushedAC[WLANTL_AC_VI], + pStats->txFlushedAC[WLANTL_AC_VO], + + pStats->rxChains, + pStats->rxPackets, + pStats->rxDropped, + pStats->rxDelivered, + pStats->rxRefused + ); + wrqu->data.length = strlen(extra)+1; + break; + } + +/* The case prints the current state of the HDD, SME, CSR, PE, TL + *it can be extended for WDI Global State as well. + *And currently it only checks P2P_CLIENT adapter. + *P2P_DEVICE and P2P_GO have not been added as of now. +*/ + case WE_GET_STATES: + { + int buf = 0, len = 0; + int adapter_num = 0; + int count = 0, check = 1; + + tANI_U16 tlState; + tHalHandle hHal = NULL; + tpAniSirGlobal pMac = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + hdd_adapter_t *useAdapter = NULL; + + /* Print wlan0 or p2p0 states based on the adapter_num + *by using the correct adapter + */ + while ( adapter_num < 2 ) + { + if ( WLAN_ADAPTER == adapter_num ) + { + useAdapter = pAdapter; + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n\n wlan0 States:-"); + len += buf; + } + else if ( P2P_ADAPTER == adapter_num ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n\n p2p0 States:-"); + len += buf; + + if( !pHddCtx ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pHddCtx is NULL"); + len += buf; + break; + } + + /*Printing p2p0 states only in the case when the device is + configured as a p2p_client*/ + useAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if ( !useAdapter ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n Device not configured as P2P_CLIENT."); + len += buf; + break; + } + } + + hHal = WLAN_HDD_GET_HAL_CTX( useAdapter ); + if (!hHal) { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pMac is NULL"); + len += buf; + break; + } + pMac = PMAC_STRUCT( hHal ); + if (!pMac) { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pMac is NULL"); + len += buf; + break; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(useAdapter); + + tlState = smeGetTLSTAState(hHal, pHddStaCtx->conn_info.staId[0]); + + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n HDD Conn State - %s " + "\n \n SME State:" + "\n Neighbour Roam State - %s" + "\n CSR State - %s" + "\n CSR Substate - %s" + "\n \n TL STA %d State: %s", + macTraceGetHDDWlanConnState( + pHddStaCtx->conn_info.connState), + macTraceGetNeighbourRoamState( + sme_getNeighborRoamState(hHal, + useAdapter->sessionId)), + macTraceGetcsrRoamState( + sme_getCurrentRoamState(hHal, + useAdapter->sessionId)), + macTraceGetcsrRoamSubState( + sme_getCurrentRoamSubState(hHal, + useAdapter->sessionId)), + pHddStaCtx->conn_info.staId[0], + macTraceGetTLState(tlState) + ); + len += buf; + adapter_num++; + } + + if (hHal) { + /* Printing Lim State starting with global lim states */ + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n \n LIM STATES:-" + "\n Global Sme State - %s "\ + "\n Global mlm State - %s "\ + "\n", + macTraceGetLimSmeState(sme_getLimSmeState(hHal)), + macTraceGetLimMlmState(sme_getLimSmeState(hHal)) + ); + len += buf; + + /* Printing the PE Sme and Mlm states for valid lim sessions */ + while (check < 3 && count < 255) { + if (sme_IsLimSessionValid(hHal, count)) { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n Lim Valid Session %d:-" + "\n PE Sme State - %s " + "\n PE Mlm State - %s " + "\n", + check, + macTraceGetLimSmeState(sme_getLimSmeSessionState( + hHal, count)), + macTraceGetLimMlmState(sme_getLimMlmSessionState( + hHal, count)) + ); + + len += buf; + check++; + } + count++; + } + } + + wrqu->data.length = strlen(extra)+1; + break; + } + + case WE_GET_CFG: + { +#ifdef WLAN_FEATURE_MBSSID + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Printing Adapter MBSSID SAP Dyn INI Config", __func__); + hdd_cfg_get_sap_dyn_config(pAdapter, + extra, QCSAP_IOCTL_MAX_STR_LEN); + /* Overwrite extra buffer with global ini config if need to return + * in buf + */ +#endif + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Printing CLD global INI Config", __func__); + hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter), extra, + QCSAP_IOCTL_MAX_STR_LEN); + wrqu->data.length = strlen(extra)+1; + break; + } +#ifdef WLAN_FEATURE_11AC + case WE_GET_RSSI: + { + v_S7_t s7Rssi = 0; + wlan_hdd_get_rssi(pAdapter, &s7Rssi); + snprintf(extra, WE_MAX_STR_LEN, "rssi=%d",s7Rssi); + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WE_GET_ROAM_RSSI: + { + v_S7_t s7Rssi = 0; + wlan_hdd_get_roam_rssi(pAdapter, &s7Rssi); + snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi); + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + case WE_GET_WMM_STATUS: + { + snprintf(extra, WE_MAX_STR_LEN, + "\nDir: 0=up, 1=down, 3=both\n" + "|------------------------|\n" + "|AC | ACM |Admitted| Dir |\n" + "|------------------------|\n" + "|VO | %d | %3s | %d |\n" + "|VI | %d | %3s | %d |\n" + "|BE | %d | %3s | %d |\n" + "|BK | %d | %3s | %d |\n" + "|------------------------|\n", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcTspecInfo.ts_info.direction); + + + wrqu->data.length = strlen(extra)+1; + break; + } + case WE_GET_CHANNEL_LIST: + { + VOS_STATUS status; + v_U8_t i, len; + char* buf ; + + tChannelListInfo channel_list; + + memset(&channel_list, 0, sizeof(channel_list)); + status = iw_softap_get_channel_list(dev, info, wrqu, (char *)&channel_list); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s GetChannelList Failed!!!", __func__); + return -EINVAL; + } + buf = extra; + /** + * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. Maximum buffer + * needed = 5 * number of channels. Check if sufficient + * buffer is available and then proceed to fill the buffer. + */ + if(WE_MAX_STR_LEN < (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s Insufficient Buffer to populate channel list", + __func__); + return -EINVAL; + } + len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", + channel_list.num_channels); + for(i = 0 ; i < channel_list.num_channels; i++) + { + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, + "%u ", channel_list.channels[i]); + } + wrqu->data.length = strlen(extra)+1; + + break; + } +#ifdef FEATURE_WLAN_TDLS + case WE_GET_TDLS_PEERS: + { + wrqu->data.length = wlan_hdd_tdls_get_all_peers(pAdapter, extra, WE_MAX_STR_LEN)+1; + break; + } +#endif +#ifdef WLAN_FEATURE_11W + case WE_GET_11W_INFO: + { + hddLog(LOGE, "WE_GET_11W_ENABLED = %d", pWextState->roamProfile.MFPEnabled ); + + snprintf(extra, WE_MAX_STR_LEN, + "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d" + "\n Number of Unprotected Disassocs %d" + "\n Number of Unprotected Deauths %d", + (*pWextState->roamProfile.BSSIDs.bssid)[0], (*pWextState->roamProfile.BSSIDs.bssid)[1], + (*pWextState->roamProfile.BSSIDs.bssid)[2], (*pWextState->roamProfile.BSSIDs.bssid)[3], + (*pWextState->roamProfile.BSSIDs.bssid)[4], (*pWextState->roamProfile.BSSIDs.bssid)[5], + pWextState->roamProfile.MFPEnabled, pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx, + pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx); + + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + case WE_GET_PHYMODE: + { + v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE; + hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter); + tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eCsrPhyMode phymode; + eCsrBand currBand; + tSmeConfigParams smeconfig; + + sme_GetConfigParam(hal, &smeconfig); + if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != + smeconfig.csrConfig.channelBondingMode24GHz) + ch_bond24 = VOS_TRUE; + + if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != + smeconfig.csrConfig.channelBondingMode5GHz) + ch_bond5g = VOS_TRUE; + + phymode = sme_GetPhyMode(hal); + if ((eHAL_STATUS_SUCCESS != sme_GetFreqBand(hal, &currBand))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to get current band config", + __func__); + return -EIO; + } + + + switch (phymode) { + case eCSR_DOT11_MODE_AUTO: + snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE"); + break; + case eCSR_DOT11_MODE_TAURUS: + case eCSR_DOT11_MODE_POLARIS: + case eCSR_DOT11_MODE_TAURUS_ONLY: + case eCSR_DOT11_MODE_TITAN: + case eCSR_DOT11_MODE_11n: + case eCSR_DOT11_MODE_11n_ONLY: + if (currBand == eCSR_BAND_24) { + if (ch_bond24) + snprintf(extra, WE_MAX_STR_LEN, "11NGHT40"); + else + snprintf(extra, WE_MAX_STR_LEN, "11NGHT20"); + } + else if(currBand == eCSR_BAND_5G) { + if (ch_bond5g) + snprintf(extra, WE_MAX_STR_LEN, "11NAHT40"); + else + snprintf(extra, WE_MAX_STR_LEN, "11NAHT20"); + } else { + snprintf(extra, WE_MAX_STR_LEN, "11N"); + } + break; + case eCSR_DOT11_MODE_abg: + snprintf(extra, WE_MAX_STR_LEN, "11ABG"); + break; + case eCSR_DOT11_MODE_11a: + case eCSR_DOT11_MODE_11a_ONLY: + snprintf(extra, WE_MAX_STR_LEN, "11A"); + break; + case eCSR_DOT11_MODE_11b: + case eCSR_DOT11_MODE_11b_ONLY: + snprintf(extra, WE_MAX_STR_LEN, "11B"); + break; + case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: + snprintf(extra, WE_MAX_STR_LEN, "11G"); + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + case eCSR_DOT11_MODE_11ac_ONLY: + if (hddctx->cfg_ini->vhtChannelWidth == + eHT_CHANNEL_WIDTH_20MHZ) + snprintf(extra, WE_MAX_STR_LEN, "11ACVHT20"); + else if (hddctx->cfg_ini->vhtChannelWidth == + eHT_CHANNEL_WIDTH_40MHZ) + snprintf(extra, WE_MAX_STR_LEN, "11ACVHT40"); + else if (hddctx->cfg_ini->vhtChannelWidth == + eHT_CHANNEL_WIDTH_80MHZ) + snprintf(extra, WE_MAX_STR_LEN, "11ACVHT80"); + else if (hddctx->cfg_ini->vhtChannelWidth == + eHT_CHANNEL_WIDTH_160MHZ) + snprintf(extra, WE_MAX_STR_LEN, "11ACVHT160"); + break; +#endif + } + + wrqu->data.length = strlen(extra)+1; + break; + } + +#ifdef FEATURE_OEM_DATA_SUPPORT + case WE_GET_OEM_DATA_CAP: + { + return iw_get_oem_data_cap(dev, info, wrqu, extra); + } +#endif /* FEATURE_OEM_DATA_SUPPORT */ + default: + { + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd ); + break; + } + } + + return 0; +} + +/* action sub-ioctls */ +static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int ret = 0; /* success */ + int sub_cmd; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + msleep(1000); + return -EBUSY; + } + +#ifdef CONFIG_COMPAT + /* this ioctl is a special case where a sub-ioctl is used and both + * the number of get and set args is 0. in this specific case the + * logic in iwpriv places the sub_cmd in the data.flags portion of + * the iwreq. unfortunately the location of this field will be + * different between 32-bit and 64-bit user space, and the standard + * compat support in the kernel does not handle this case. so we + * need to explicitly handle it here. */ + if (is_compat_task()) { + struct compat_iw_point *compat_iw_point = + (struct compat_iw_point *) &wrqu->data; + sub_cmd = compat_iw_point->flags; + } else { + sub_cmd = wrqu->data.flags; + } +#else + sub_cmd = wrqu->data.flags; +#endif + + switch (sub_cmd) + { + case WE_CLEAR_STATS: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: clearing", __func__); + memset(&pAdapter->stats, 0, sizeof(pAdapter->stats)); + memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats)); + break; + } + + case WE_GET_RECOVERY_STAT: + { + tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter); + sme_getRecoveryStats(hal); + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case WE_ENABLE_AMP: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: enabling AMP", __func__); + WLANBAP_RegisterWithHCI(pAdapter); + break; + } + case WE_DISABLE_AMP: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__); + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + status = WLANBAP_StopAmp(); + if(VOS_STATUS_SUCCESS != status ) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop AMP", __func__); + } + else + { + //a state m/c implementation in PAL is TBD to avoid this delay + msleep(500); + pHddCtx->isAmpAllowed = VOS_FALSE; + WLANBAP_DeregisterFromHCI(); + } + + break; + } +#endif + case WE_ENABLE_DXE_STALL_DETECT: + { + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + sme_transportDebug(hHal, VOS_FALSE, VOS_TRUE); + break; + } + case WE_DISPLAY_DXE_SNAP_SHOT: + { + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + sme_transportDebug(hHal, VOS_TRUE, VOS_FALSE); + break; + } + case WE_DISPLAY_DATAPATH_SNAP_SHOT: + { + hddLog(LOGE, "%s: called %d",__func__, sub_cmd); + hdd_wmm_tx_snapshot(pAdapter); + WLANTL_TLDebugMessage(VOS_TRUE); + break; + } + case WE_SET_REASSOC_TRIGGER: + { + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U32_t roamId = 0; + tCsrRoamModifyProfileFields modProfileFields; + sme_GetModifyProfileFields(hHal, pAdapter->sessionId, + &modProfileFields); + sme_RoamReassoc(hHal, pAdapter->sessionId, + NULL, modProfileFields, &roamId, 1); + return 0; + } + + case WE_DUMP_AGC_START: + { + hddLog(LOG1, "WE_DUMP_AGC_START"); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_PARAM_DUMP_AGC_START, + 0, GEN_CMD); + break; + } + case WE_DUMP_AGC: + { + hddLog(LOG1, "WE_DUMP_AGC"); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_PARAM_DUMP_AGC, + 0, GEN_CMD); + break; + } + + case WE_DUMP_CHANINFO_START: + { + hddLog(LOG1, "WE_DUMP_CHANINFO_START"); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_PARAM_DUMP_CHANINFO_START, + 0, GEN_CMD); + break; + } + case WE_DUMP_CHANINFO: + { + hddLog(LOG1, "WE_DUMP_CHANINFO_START"); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_PARAM_DUMP_CHANINFO, + 0, GEN_CMD); + break; + } + case WE_DUMP_WATCHDOG: + { + hddLog(LOG1, "WE_DUMP_WATCHDOG"); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)GEN_PARAM_DUMP_WATCHDOG, + 0, GEN_CMD); + break; + } +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + case WE_DUMP_PCIE_LOG: + { + hddLog(LOGE, "WE_DUMP_PCIE_LOG"); + ret = process_wma_set_command((int) pAdapter->sessionId, + (int) GEN_PARAM_DUMP_PCIE_ACCESS_LOG, + 0, GEN_CMD); + break; + } +#endif + default: + { + hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd); + break; + } + } + + return ret; +} + +void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter) +{ + /* + * Function to display HDD WMM information + * for Tx Queues. + * Prints global as well as per client depending + * whether the clients are registered or not. + */ + int i = 0, j = 0; + for ( i=0; i< NUM_TX_QUEUES; i++) + { + spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock); + hddLog(LOGE, "HDD WMM TxQueue Info For AC: %d Count: %d PrevAdress:%p, NextAddress:%p", + i, pAdapter->wmm_tx_queue[i].count, + pAdapter->wmm_tx_queue[i].anchor.prev, pAdapter->wmm_tx_queue[i].anchor.next); + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + } + + for(i =0; iaStaInfo[i].isUsed) + { + hddLog(LOGE, "******STAIndex: %d*********", i); + for ( j=0; j< NUM_TX_QUEUES; j++) + { + spin_lock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock); + hddLog(LOGE, "HDD TxQueue Info For AC: %d Count: %d PrevAdress:%p, NextAddress:%p", + j, pAdapter->aStaInfo[i].wmm_tx_queue[j].count, + pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.prev, + pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.next); + spin_unlock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock); + } + } + } + +} + +static int __iw_set_var_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + int sub_cmd; + int apps_args[MAX_VAR_ARGS] = {0}; + int num_args; + hdd_station_ctx_t *pStaCtx = NULL ; + hdd_ap_ctx_t *pAPCtx = NULL; + int cmd = 0; + int staId = 0; + struct iw_point s_priv_data; + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + return -EINVAL; + } + + if (NULL == s_priv_data.pointer) { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + num_args = s_priv_data.length; + + hddLog(LOG1, "%s: Received length %d", __func__, s_priv_data.length); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if (num_args > MAX_VAR_ARGS) + { + num_args = MAX_VAR_ARGS; + } + + /* ODD number is used for set, copy data using copy_from_user */ + if (copy_from_user(apps_args, s_priv_data.pointer, + (sizeof(int)) * num_args)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + + if(( sub_cmd == WE_MCC_CONFIG_CREDENTIAL ) || + (sub_cmd == WE_MCC_CONFIG_PARAMS )) + { + if(( pAdapter->device_mode == WLAN_HDD_INFRA_STATION )|| + ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT )) + { + pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + staId = pStaCtx->conn_info.staId[0]; + } + else if (( pAdapter->device_mode == WLAN_HDD_P2P_GO ) || + ( pAdapter->device_mode == WLAN_HDD_SOFTAP )) + { + pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + staId = pAPCtx->uBCStaId; + } + else + { + hddLog(LOGE, "%s: Device mode %d not recognised", __FUNCTION__, pAdapter->device_mode); + return 0; + } + } + + switch (sub_cmd) + { + case WE_LOG_DUMP_CMD: + { + hddLog(LOG1, "%s: LOG_DUMP %d arg1 %d arg2 %d arg3 %d arg4 %d", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4]); + + logPrintf(hHal, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4]); + + } + break; + + case WE_P2P_NOA_CMD: + { + p2p_app_setP2pPs_t p2pNoA; + + p2pNoA.opp_ps = apps_args[0]; + p2pNoA.ctWindow = apps_args[1]; + p2pNoA.duration = apps_args[2]; + p2pNoA.interval = apps_args[3]; + p2pNoA.count = apps_args[4]; + p2pNoA.single_noa_duration = apps_args[5]; + p2pNoA.psSelection = apps_args[6]; + + hddLog(LOG1, "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d PsSelection %x", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4], apps_args[5], apps_args[6]); + + hdd_setP2pPs(dev, &p2pNoA); + + } + break; + + case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD: + { + hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1 %d arg2", + __func__, apps_args[0], apps_args[1]); + vosTraceEnable(apps_args[0], apps_args[1]); + } + break; + + case WE_MTRACE_DUMP_CMD: + { + hddLog(LOG1, "%s: MTRACE_DUMP code %d session %d count %d " + "bitmask_of_module %d ", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3]); + vosTraceDumpAll((void*)hHal , apps_args[0], apps_args[1], + apps_args[2], apps_args[3]); + + } + break; + + case WE_MCC_CONFIG_CREDENTIAL : + { + cmd = 287; //Command should be updated if there is any change + // in the Riva dump command + if((apps_args[0] >= 40 ) && (apps_args[0] <= 160 )) + { + logPrintf(hHal, cmd, staId, apps_args[0], apps_args[1], apps_args[2]); + } + else + { + hddLog(LOGE, "%s : Enter valid MccCredential value between MIN :40 and MAX:160", __func__); + return 0; + } + } + break; + + case WE_MCC_CONFIG_PARAMS : + { + cmd = 288; //command Should be updated if there is any change + // in the Riva dump command + hdd_validate_mcc_config(pAdapter, staId, apps_args[0], apps_args[1],apps_args[2]); + } + break; + +#ifdef FEATURE_WLAN_TDLS + case WE_TDLS_CONFIG_PARAMS : + { + tdls_config_params_t tdlsParams; + + tdlsParams.tdls = apps_args[0]; + tdlsParams.tx_period_t = apps_args[1]; + tdlsParams.tx_packet_n = apps_args[2]; + tdlsParams.discovery_period_t = apps_args[3]; + tdlsParams.discovery_tries_n = apps_args[4]; + tdlsParams.idle_timeout_t = apps_args[5]; + tdlsParams.idle_packet_n = apps_args[6]; + tdlsParams.rssi_hysteresis = apps_args[7]; + tdlsParams.rssi_trigger_threshold = apps_args[8]; + tdlsParams.rssi_teardown_threshold = apps_args[9]; + tdlsParams.rssi_delta = apps_args[10]; + + wlan_hdd_tdls_set_params(dev, &tdlsParams); + } + break; +#endif + case WE_UNIT_TEST_CMD : + { + t_wma_unit_test_cmd *unitTestArgs; + vos_msg_t msg = {0}; + int i, j; + if ((apps_args[0] < WLAN_MODULE_ID_MIN) || + (apps_args[0] >= WLAN_MODULE_ID_MAX)) { + hddLog(LOGE, FL("Invalid MODULE ID %d"), apps_args[0]); + return -EINVAL; + } + if (apps_args[1] > (WMA_MAX_NUM_ARGS)) { + hddLog(LOGE, FL("Too Many args %d"), apps_args[1]); + return -EINVAL; + } + unitTestArgs = vos_mem_malloc(sizeof(*unitTestArgs)); + if (NULL == unitTestArgs) { + hddLog(LOGE, + FL("vos_mem_alloc failed for unitTestArgs")); + return -ENOMEM; + } + unitTestArgs->vdev_id = (int)pAdapter->sessionId; + unitTestArgs->module_id = apps_args[0]; + unitTestArgs->num_args = apps_args[1]; + for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) { + unitTestArgs->args[i] = apps_args[j]; + } + msg.type = SIR_HAL_UNIT_TEST_CMD; + msg.reserved = 0; + msg.bodyptr = unitTestArgs; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, + &msg)) { + vos_mem_free(unitTestArgs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post UNIT_TEST_CMD message to WDA")); + return -EINVAL; + } + } + break; + default: + { + hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd ); + } + break; + } + + return 0; +} + + +int iw_set_var_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + return ret; +} + + +static int iw_add_tspec(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + int params[HDD_WLAN_WMM_PARAM_COUNT]; + sme_QosWmmTspecInfo tSpec; + v_U32_t handle; + struct iw_point s_priv_data; + + /* + * Make sure the application is sufficiently privileged + * note that the kernel will do this for "set" ioctls, but since + * this ioctl wants to return status to user space it must be + * defined as a "get" ioctl. + */ + if (!capable(CAP_NET_ADMIN)) + { + return -EPERM; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + // we must be associated in order to add a tspec + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // since we are defined to be a "get" ioctl, and since the number + // of params exceeds the number of params that wireless extensions + // will pass down in the iwreq_data, we must copy the "set" params. + // We must handle the compat for iwreq_data in 32U/64K environment. + + // helper function to get iwreq_data with compat handling. + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // make sure all params are correctly passed to function + if ((NULL == s_priv_data.pointer) || + (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // from user space ourselves + if (copy_from_user(¶ms, s_priv_data.pointer, sizeof(params))) { + // hmmm, can't get them + return -EIO; + } + + // clear the tspec + memset(&tSpec, 0, sizeof(tSpec)); + + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // validate the TID + if (params[HDD_WLAN_WMM_PARAM_TID] > 7) + { + // out of range + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID]; + + // validate the direction + switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) + { + case HDD_WLAN_WMM_DIRECTION_UPSTREAM: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK; + break; + + case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + break; + + case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH; + break; + + default: + // unknown + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD]; + + // validate the user priority + if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) + { + // out of range + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY]; + if(0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"***ts_info.up out of bounds***"); + return 0; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s:TS_INFO PSB %d UP %d !!!", __func__, + tSpec.ts_info.psb, tSpec.ts_info.up); + + tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE]; + tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE]; + tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE]; + tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE]; + tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE]; + tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE]; + tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE]; + tSpec.surplus_bw_allowance = params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE]; + tSpec.min_service_interval = params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL]; + tSpec.max_service_interval = params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL]; + tSpec.suspension_interval = params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL]; + tSpec.inactivity_interval = params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL]; + + tSpec.ts_info.burst_size_defn = params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN]; + + // validate the ts info ack policy + switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) + { + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK: + tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + break; + + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK: + tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + break; + + default: + // unknown + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec); + return 0; +} + + +static int iw_del_tspec(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int *params = (int *)extra; + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + v_U32_t handle; + + /* + * Make sure the application is sufficiently privileged + * note that the kernel will do this for "set" ioctls, but since + * this ioctl wants to return status to user space it must be + * defined as a "get" ioctl. + */ + if (!capable(CAP_NET_ADMIN)) + { + return -EPERM; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + // although we are defined to be a "get" ioctl, the params we require + // will fit in the iwreq_data, therefore unlike iw_add_tspec() there + // is no need to copy the params from user space + + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + *pStatus = hdd_wmm_delts(pAdapter, handle); + return 0; +} + + +static int iw_get_tspec(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int *params = (int *)extra; + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + v_U32_t handle; + + // although we are defined to be a "get" ioctl, the params we require + // will fit in the iwreq_data, therefore unlike iw_add_tspec() there + // is no need to copy the params from user space + + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + *pStatus = hdd_wmm_checkts(pAdapter, handle); + return 0; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +// +// +// Each time the supplicant has the auth_request or reassoc request +// IEs ready. This is pushed to the driver. The driver will inturn use +// it to send out the auth req and reassoc req for 11r FT Assoc. +// +static int iw_set_fties(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + //v_CONTEXT_t pVosContext; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + if (!wrqu->data.length) + { + hddLog(LOGE, FL("called with 0 length IEs")); + return -EINVAL; + } + if (wrqu->data.pointer == NULL) + { + hddLog(LOGE, FL("called with NULL IE")); + return -EINVAL; + } + + // Added for debug on reception of Re-assoc Req. + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(LOGE, FL("Called with Ie of length = %d when not associated"), + wrqu->data.length); + hddLog(LOGE, FL("Should be Re-assoc Req IEs")); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + hddLog(LOG1, FL("%s called with Ie of length = %d"), __func__, wrqu->data.length); +#endif + + // Pass the received FT IEs to SME + sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, extra, + wrqu->data.length); + + return 0; +} +#endif + +static int iw_set_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)extra; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWlanSetRxpFilters wlanRxpFilterParam; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tpSirRcvFltMcAddrList mc_addr_list_ptr; + int idx; + eHalStatus ret_val; + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + if ((HDD_MULTICAST_FILTER_LIST == pRequest->mcastBcastFilterSetting) || + (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting)) + { +#ifdef WLAN_FEATURE_PACKET_FILTERING + + mc_addr_list_ptr = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == mc_addr_list_ptr) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -ENOMEM; + } + + mc_addr_list_ptr->ulMulticastAddrCnt = pRequest->mcast_addr_cnt; + + if (mc_addr_list_ptr->ulMulticastAddrCnt > HDD_MAX_NUM_MULTICAST_ADDRESS) + mc_addr_list_ptr->ulMulticastAddrCnt = HDD_MAX_NUM_MULTICAST_ADDRESS; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr List Cnt %d", __func__, + mc_addr_list_ptr->ulMulticastAddrCnt); + + for (idx = 0; idx < mc_addr_list_ptr->ulMulticastAddrCnt; idx++) + { + memcpy(&mc_addr_list_ptr->multicastAddr[idx], + pRequest->multicastAddr[idx], HDD_WLAN_MAC_ADDR_LEN); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr for Idx %d ="MAC_ADDRESS_STR, __func__, + idx, MAC_ADDR_ARRAY(mc_addr_list_ptr->multicastAddr[idx])); + } + + if (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting) + mc_addr_list_ptr->action = HDD_DELETE_MCBC_FILTERS_FROM_FW; //clear + else + mc_addr_list_ptr->action = HDD_SET_MCBC_FILTERS_TO_FW; //set + + ret_val = sme_8023MulticastList(hHal, pAdapter->sessionId, mc_addr_list_ptr); + vos_mem_free(mc_addr_list_ptr); + if (eHAL_STATUS_SUCCESS != ret_val) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to Set MC Address List", + __func__); + return -EINVAL; + } +#endif //WLAN_FEATURE_PACKET_FILTERING + } + else + { + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Set MC BC Filter Config request: %d suspend %d", + __func__, pRequest->mcastBcastFilterSetting, + pHddCtx->hdd_wlan_suspended); + + pHddCtx->configuredMcastBcastFilter = pRequest->mcastBcastFilterSetting; + + if (pHddCtx->hdd_wlan_suspended) + { + wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if (NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -EINVAL; + } + + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pRequest->mcastBcastFilterSetting; + wlanRxpFilterParam->setMcstBcstFilter = TRUE; + + hdd_conf_hostoffload(pAdapter, TRUE); + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s:MC/BC changed Req %d Set %d En %d", + __func__, + pHddCtx->configuredMcastBcastFilter, + wlanRxpFilterParam->configuredMcstBcstFilterSetting, + wlanRxpFilterParam->setMcstBcstFilter); + + if (eHAL_STATUS_SUCCESS != + sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlanRxpFilterParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute set HW MC/BC Filter request", + __func__); + vos_mem_free(wlanRxpFilterParam); + return -EINVAL; + } + + } + } + + return 0; +} + +static int iw_clear_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWlanSetRxpFilters wlanRxpFilterParam; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: ", __func__); + + //Reset the filter to INI value as we have to clear the dynamic filter + pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting; + + //Configure FW with new setting + if (pHddCtx->hdd_wlan_suspended) + { + wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if (NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -EINVAL; + } + + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + wlanRxpFilterParam->setMcstBcstFilter = TRUE; + + hdd_conf_hostoffload(pAdapter, TRUE); + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + + if (eHAL_STATUS_SUCCESS != + sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlanRxpFilterParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute set HW MC/BC Filter request", + __func__); + vos_mem_free(wlanRxpFilterParam); + return -EINVAL; + } + } + return 0; +} + +static int iw_set_host_offload(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra; + tSirHostOffloadReq offloadRequest; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP dev is not in CONNECTED state, ignore!!!", __func__); + return -EINVAL; + } + + /* Debug display of request components. */ + switch (pRequest->offloadType) + { + case WLAN_IPV4_ARP_REPLY_OFFLOAD: + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Host offload request: ARP reply", __func__); + switch (pRequest->enableOrDisable) + { + case WLAN_OFFLOAD_DISABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " disable"); + break; + case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " BC Filtering enable"); + case WLAN_OFFLOAD_ENABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " ARP offload enable"); + hddLog(VOS_TRACE_LEVEL_WARN, " IP address: %d.%d.%d.%d", + pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1], + pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]); + } + break; + + case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Host offload request: neighbor discovery", + __func__); + switch (pRequest->enableOrDisable) + { + case WLAN_OFFLOAD_DISABLE: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " disable"); + break; + case WLAN_OFFLOAD_ENABLE: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " enable"); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " IP address: %x:%x:%x:%x:%x:%x:%x:%x", + *(v_U16_t *)(pRequest->params.hostIpv6Addr), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 2), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 4), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 6), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 8), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 10), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 12), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 14)); + } + } + + /* Execute offload request. The reason that we can copy the request information + from the ioctl structure to the SME structure is that they are laid out + exactly the same. Otherwise, each piece of information would have to be + copied individually. */ + memcpy(&offloadRequest, pRequest, wrqu->data.length); + if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offloadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute host offload request", + __func__); + return -EINVAL; + } + + return 0; +} + +static int iw_set_keepalive_params(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpKeepAliveRequest pRequest = (tpKeepAliveRequest) extra; + tSirKeepAliveReq keepaliveRequest; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return 0; + } + + if (pRequest->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) { + hddLog(LOGE, FL("Value of timePeriod exceed Max limit %d"), + pRequest->timePeriod); + return -EINVAL; + } + + + /* Debug display of request components. */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set Keep Alive Request : TimePeriod %d size %zu", + __func__, pRequest->timePeriod, sizeof(tKeepAliveRequest)); + + switch (pRequest->packetType) + { + case WLAN_KEEP_ALIVE_NULL_PKT: + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", __func__); + break; + + case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Keep Alive Request: Tx UnSolicited ARP RSP", + __func__); + + hddLog(VOS_TRACE_LEVEL_WARN, " Host IP address: %d.%d.%d.%d", + pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1], + pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]); + + hddLog(VOS_TRACE_LEVEL_WARN, " Dest IP address: %d.%d.%d.%d", + pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1], + pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]); + + hddLog(VOS_TRACE_LEVEL_WARN, " Dest MAC address: %d:%d:%d:%d:%d:%d", + pRequest->destMacAddr[0], pRequest->destMacAddr[1], + pRequest->destMacAddr[2], pRequest->destMacAddr[3], + pRequest->destMacAddr[4], pRequest->destMacAddr[5]); + break; + } + + /* Execute keep alive request. The reason that we can copy the request information + from the ioctl structure to the SME structure is that they are laid out + exactly the same. Otherwise, each piece of information would have to be + copied individually. */ + memcpy(&keepaliveRequest, pRequest, wrqu->data.length); + + hddLog(VOS_TRACE_LEVEL_ERROR, "set Keep: TP before SME %d", keepaliveRequest.timePeriod); + + if (eHAL_STATUS_SUCCESS != sme_SetKeepAlive(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &keepaliveRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Keep Alive", + __func__); + return -EINVAL; + } + + return 0; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest, + tANI_U8 sessionId) +{ + tSirRcvPktFilterCfgType packetFilterSetReq = {0}; + tSirRcvFltPktClearParam packetFilterClrReq = {0}; + int i=0; + + if (pHddCtx->cfg_ini->disablePacketFilter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Packet Filtering Disabled. Returning ", + __func__ ); + return 0; + } + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + /* Debug display of request components. */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Packet Filter Request : FA %d params %d", + __func__, pRequest->filterAction, pRequest->numParams); + + switch (pRequest->filterAction) + { + case HDD_RCV_FILTER_SET: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Packet Filter Request for Id: %d", + __func__, pRequest->filterId); + + packetFilterSetReq.filterId = pRequest->filterId; + if ( pRequest->numParams >= HDD_MAX_CMP_PER_PACKET_FILTER) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Number of Params exceed Max limit %d", + __func__, pRequest->numParams); + return -EINVAL; + } + packetFilterSetReq.numFieldParams = pRequest->numParams; + packetFilterSetReq.coalesceTime = 0; + packetFilterSetReq.filterType = 1; + for (i=0; i < pRequest->numParams; i++) + { + packetFilterSetReq.paramsData[i].protocolLayer = pRequest->paramsData[i].protocolLayer; + packetFilterSetReq.paramsData[i].cmpFlag = pRequest->paramsData[i].cmpFlag; + packetFilterSetReq.paramsData[i].dataOffset = pRequest->paramsData[i].dataOffset; + packetFilterSetReq.paramsData[i].dataLength = pRequest->paramsData[i].dataLength; + packetFilterSetReq.paramsData[i].reserved = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "Proto %d Comp Flag %d Filter Type %d", + pRequest->paramsData[i].protocolLayer, pRequest->paramsData[i].cmpFlag, + packetFilterSetReq.filterType); + + hddLog(VOS_TRACE_LEVEL_INFO, "Data Offset %d Data Len %d", + pRequest->paramsData[i].dataOffset, pRequest->paramsData[i].dataLength); + + memcpy(&packetFilterSetReq.paramsData[i].compareData, + pRequest->paramsData[i].compareData, pRequest->paramsData[i].dataLength); + memcpy(&packetFilterSetReq.paramsData[i].dataMask, + pRequest->paramsData[i].dataMask, pRequest->paramsData[i].dataLength); + + hddLog(VOS_TRACE_LEVEL_INFO, "CData %d CData %d CData %d CData %d CData %d CData %d", + pRequest->paramsData[i].compareData[0], pRequest->paramsData[i].compareData[1], + pRequest->paramsData[i].compareData[2], pRequest->paramsData[i].compareData[3], + pRequest->paramsData[i].compareData[4], pRequest->paramsData[i].compareData[5]); + + hddLog(VOS_TRACE_LEVEL_INFO, "MData %d MData %d MData %d MData %d MData %d MData %d", + pRequest->paramsData[i].dataMask[0], pRequest->paramsData[i].dataMask[1], + pRequest->paramsData[i].dataMask[2], pRequest->paramsData[i].dataMask[3], + pRequest->paramsData[i].dataMask[4], pRequest->paramsData[i].dataMask[5]); + } + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Set Filter", + __func__); + return -EINVAL; + } + + break; + + case HDD_RCV_FILTER_CLEAR: + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Clear Packet Filter Request for Id: %d", + __func__, pRequest->filterId); + packetFilterClrReq.filterId = pRequest->filterId; + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, &packetFilterClrReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter", + __func__); + return -EINVAL; + } + break; + + default : + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Packet Filter Request: Invalid %d", + __func__, pRequest->filterAction); + return -EINVAL; + } + return 0; +} + +int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType, + tANI_U8 sessionId) +{ + tSirRcvPktFilterCfgType packetFilterSetReq = {0}; + tSirRcvFltPktClearParam packetFilterClrReq = {0}; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" NULL HDD Context Passed")); + return -EINVAL; + } + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if (pHddCtx->cfg_ini->disablePacketFilter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Packet Filtering Disabled. Returning ", + __func__ ); + return -EINVAL; + } + + switch (filterType) + { + /* For setting IPV6 MC and UC Filter we need to configure + * 2 filters, one for MC and one for UC. + * The Filter ID shouldn't be swapped, which results in making + * UC Filter ineffective. + * We have hard coded all the values + * + * Reason for a separate UC filter is because, driver need to + * specify the FW that the specific filter is for unicast + * otherwise FW will not pass the unicast frames by default + * through the filter. This is required to avoid any performance + * hits when no unicast filter is set and only MC/BC are set. + * The way driver informs host is by using the MAC protocol + * layer, CMP flag set to MAX, CMP Data set to 1. + */ + + case HDD_FILTER_IPV6_MC_UC: + /* Setting IPV6 MC Filter below + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[0].dataOffset = + WLAN_HDD_80211_FRM_DA_OFFSET; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_MC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Multicast Filter", + __func__); + return -EINVAL; + } + + memset( &packetFilterSetReq, 0, sizeof(tSirRcvPktFilterCfgType)); + + /* + * Setting IPV6 UC Filter below + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_UC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_MAX; + packetFilterSetReq.paramsData[0].dataOffset = 0; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_UC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Unicast Filter", + __func__); + return -EINVAL; + } + + break; + + case HDD_FILTER_IPV6_MC: + /* + * IPV6 UC Filter might be already set, + * clear the UC Filter. As the Filter + * IDs are static, we can directly clear it. + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterClrReq.filterId = HDD_FILTER_ID_IPV6_UC; + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, + &packetFilterClrReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Clear IPv6 Unicast Filter", + __func__); + return -EINVAL; + } + + /* + * Setting IPV6 MC Filter below + */ + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[0].dataOffset = + WLAN_HDD_80211_FRM_DA_OFFSET; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_MC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Multicast Filter", + __func__); + return -EINVAL; + } + break; + + default : + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Packet Filter Request: Invalid", + __func__); + return -EINVAL; + } + return 0; +} + +void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set) +{ + v_U8_t i; + tpSirRcvFltMcAddrList pMulticastAddrs = NULL; + tHalHandle hHal = NULL; + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD CTX is NULL")); + return; + } + + hHal = pHddCtx->hHal; + + if (NULL == hHal) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HAL Handle is NULL")); + return; + } + + /* Check if INI is enabled or not, other wise just return + */ + if (pHddCtx->cfg_ini->fEnableMCAddrList) + { + pMulticastAddrs = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == pMulticastAddrs) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Could not allocate Memory")); + return; + } + vos_mem_zero(pMulticastAddrs, sizeof(tSirRcvFltMcAddrList)); + pMulticastAddrs->action = set; + + if (set) + { + /* Following pre-conditions should be satisfied before we + * configure the MC address list. + */ + if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) + && pAdapter->mc_addr_list.mc_cnt + && (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + pMulticastAddrs->ulMulticastAddrCnt = + pAdapter->mc_addr_list.mc_cnt; + for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) + { + memcpy(pMulticastAddrs->multicastAddr[i], + pAdapter->mc_addr_list.addr[i], + sizeof(pAdapter->mc_addr_list.addr[i])); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: %s multicast filter: addr =" + MAC_ADDRESS_STR, + __func__, set ? "setting" : "clearing", + MAC_ADDR_ARRAY(pMulticastAddrs->multicastAddr[i])); + } + /* Set multicast filter */ + sme_8023MulticastList(hHal, pAdapter->sessionId, + pMulticastAddrs); + } + } + else + { + /* Need to clear only if it was previously configured + */ + if (pAdapter->mc_addr_list.isFilterApplied) + { + pMulticastAddrs->ulMulticastAddrCnt = + pAdapter->mc_addr_list.mc_cnt; + for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) { + memcpy(pMulticastAddrs->multicastAddr[i], + pAdapter->mc_addr_list.addr[i], + sizeof(pAdapter->mc_addr_list.addr[i])); + } + sme_8023MulticastList(hHal, pAdapter->sessionId, + pMulticastAddrs); + } + + } + /* MAddrCnt is MulticastAddrCnt */ + hddLog(VOS_TRACE_LEVEL_INFO, "smeSessionId:%d; set:%d; MCAdddrCnt :%d", + pAdapter->sessionId, set, pMulticastAddrs->ulMulticastAddrCnt); + + pAdapter->mc_addr_list.isFilterApplied = set ? TRUE : FALSE; + vos_mem_free(pMulticastAddrs); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("gMCAddrListEnable is not enabled in INI")); + } + return; +} + +static int iw_set_packet_filter_params(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpPacketFilterCfg pRequest = NULL; + int ret; + struct iw_point s_priv_data; + + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + return -EINVAL; + } + + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) { + return -EINVAL; + } + + /* ODD number is used for set, copy data using copy_from_user */ + pRequest = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + if (NULL == pRequest) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + ret = wlan_hdd_set_filter(WLAN_HDD_GET_CTX(pAdapter), pRequest, + pAdapter->sessionId); + kfree(pRequest); + + return ret; +} +#endif +static int iw_get_statistics(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + char *p = extra; + int tlen = 0; + tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat); + + tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat); + tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat); + + ENTER(); + + if (pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return -EINVAL; + } + + if (eConnectionState_Associated != (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) { + + wrqu->txpower.value = 0; + } + else { + status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + hdd_StatisticsCB, 0, FALSE, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + pAdapter, + pAdapter->sessionId ); + + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve SME statistics", + __func__); + return -EINVAL; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timeout while retrieving statistics", + __func__); + /*Remove the SME statistics list by passing NULL in callback argument*/ + status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + NULL, 0, FALSE, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + pAdapter, + pAdapter->sessionId ); + + return -EINVAL; + } + FILL_TLV(p, (tANI_U8)WLAN_STATS_RETRY_CNT, + (tANI_U8) sizeof (pStats->retry_cnt), + (char*) &(pStats->retry_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_MUL_RETRY_CNT, + (tANI_U8) sizeof (pStats->multiple_retry_cnt), + (char*) &(pStats->multiple_retry_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_FRM_CNT, + (tANI_U8) sizeof (pStats->tx_frm_cnt), + (char*) &(pStats->tx_frm_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_FRM_CNT, + (tANI_U8) sizeof (pStats->rx_frm_cnt), + (char*) &(pStats->rx_frm_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_FRM_DUP_CNT, + (tANI_U8) sizeof (pStats->frm_dup_cnt), + (char*) &(pStats->frm_dup_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_FAIL_CNT, + (tANI_U8) sizeof (pStats->fail_cnt), + (char*) &(pStats->fail_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_FAIL_CNT, + (tANI_U8) sizeof (pStats->rts_fail_cnt), + (char*) &(pStats->rts_fail_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_ACK_FAIL_CNT, + (tANI_U8) sizeof (pStats->ack_fail_cnt), + (char*) &(pStats->ack_fail_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_SUC_CNT, + (tANI_U8) sizeof (pStats->rts_succ_cnt), + (char*) &(pStats->rts_succ_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_DISCARD_CNT, + (tANI_U8) sizeof (pStats->rx_discard_cnt), + (char*) &(pStats->rx_discard_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_ERROR_CNT, + (tANI_U8) sizeof (pStats->rx_error_cnt), + (char*) &(pStats->rx_error_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]), + (char*) &(dStats->tx_uc_byte_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_byte_cnt), + (char*) &(dStats->rx_byte_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_RATE, + (tANI_U8) sizeof (dStats->rx_rate), + (char*) &(dStats->rx_rate), + tlen); + + /* Transmit rate, in units of 500 kbit/sec */ + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_RATE, + (tANI_U8) sizeof (aStats->tx_rate), + (char*) &(aStats->tx_rate), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_UC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_uc_byte_cnt[0]), + (char*) &(dStats->rx_uc_byte_cnt[0]), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_MC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_mc_byte_cnt), + (char*) &(dStats->rx_mc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_bc_byte_cnt), + (char*) &(dStats->rx_bc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_UC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]), + (char*) &(dStats->tx_uc_byte_cnt[0]), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_MC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_mc_byte_cnt), + (char*) &(dStats->tx_mc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_bc_byte_cnt), + (char*) &(dStats->tx_bc_byte_cnt), + tlen); + + wrqu->data.length = tlen; + + } + + EXIT(); + + return 0; +} + + +#ifdef FEATURE_WLAN_SCAN_PNO + +/*Max Len for PNO notification*/ +#define MAX_PNO_NOTIFY_LEN 100 +void found_pref_network_cb (void *callbackContext, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + union iwreq_data wrqu; + char buf[MAX_PNO_NOTIFY_LEN+1]; + + hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d", + pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi); + + // create the event + memset(&wrqu, 0, sizeof(wrqu)); + memset(buf, 0, sizeof(buf)); + + snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u", + pPrefNetworkFoundInd->ssId.ssId, + (unsigned int)pPrefNetworkFoundInd->rssi); + + wrqu.data.pointer = buf; + wrqu.data.length = strlen(buf); + + // send the event + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + +} + + +/*string based input*/ +VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + /* pnoRequest is a large struct, so we make it static to avoid stack + overflow. This API is only invoked via ioctl, so it is + serialized by the kernel rtnl_lock and hence does not need to be + reentrant */ + static tSirPNOScanReq pnoRequest; + char *ptr; + v_U8_t i,j, ucParams, ucMode; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO data len %d data %s", + wrqu->data.length, + extra); + + if (wrqu->data.length <= nOffset ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct"); + return VOS_STATUS_E_FAILURE; + } + + pnoRequest.enable = 0; + pnoRequest.ucNetworksCount = 0; + /*----------------------------------------------------------------------- + Input is string based and expected to be like this: + + + for each network: + + + + + e.g: + 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0 + + this translates into: + ----------------------------- + enable PNO + look for 2 networks: + test - with authentication type 0 and encryption type 0, + that can be found on 3 channels: 1 6 and 11 , + SSID bcast type is unknown (directed probe will be sent if AP not found) + and must meet -40dBm RSSI + + test2 - with auth and encryption type 4/4 + that can be found on 6 channels 1, 2, 3, 4, 5 and 6 + bcast type is non-bcast (directed probe will be sent) + and must not meet any RSSI threshold + + scan every 5 seconds 2 times, scan every 300 seconds until stopped + -----------------------------------------------------------------------*/ + ptr = extra + nOffset; + + if (1 != sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO enable input is not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pnoRequest.enable ) + { + /*Disable PNO*/ + memset(&pnoRequest, 0, sizeof(pnoRequest)); + sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest, + pAdapter->sessionId, + found_pref_network_cb, pAdapter); + return VOS_STATUS_SUCCESS; + } + + ptr += nOffset; + + if (1 != sscanf(ptr,"%hhu %n", &(pnoRequest.ucNetworksCount), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO count input not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO enable %d networks count %d offset %d", + pnoRequest.enable, + pnoRequest.ucNetworksCount, + nOffset); + + /* Parameters checking: + ucNetworksCount has to be larger than 0*/ + if (( 0 == pnoRequest.ucNetworksCount ) || + ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS )) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct"); + return VOS_STATUS_E_FAILURE; + } + + ptr += nOffset; + + for ( i = 0; i < pnoRequest.ucNetworksCount; i++ ) + { + + pnoRequest.aNetworks[i].ssId.length = 0; + + ucParams = sscanf(ptr,"%hhu %n", + &(pnoRequest.aNetworks[i].ssId.length),&nOffset); + + if (1 != ucParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO ssid length input is not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + if (( 0 == pnoRequest.aNetworks[i].ssId.length ) || + ( pnoRequest.aNetworks[i].ssId.length > 32 ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "SSID Len %d is not correct for network %d", + pnoRequest.aNetworks[i].ssId.length, i); + return VOS_STATUS_E_FAILURE; + } + + /*Advance to SSID*/ + ptr += nOffset; + + memcpy(pnoRequest.aNetworks[i].ssId.ssId, ptr, + pnoRequest.aNetworks[i].ssId.length); + ptr += pnoRequest.aNetworks[i].ssId.length; + + ucParams = sscanf(ptr,"%u %u %hhu %n", + &(pnoRequest.aNetworks[i].authentication), + &(pnoRequest.aNetworks[i].encryption), + &(pnoRequest.aNetworks[i].ucChannelCount), + &nOffset); + + if ( 3 != ucParams ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect cmd %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO len %d ssid 0x%08x%08x%08x%08x%08x%08x%08x%08x" + "auth %d encry %d channel count %d offset %d", + pnoRequest.aNetworks[i].ssId.length, + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[0]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[4]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[8]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[12]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[16]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[20]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[24]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[28]), + pnoRequest.aNetworks[i].authentication, + pnoRequest.aNetworks[i].encryption, + pnoRequest.aNetworks[i].ucChannelCount, + nOffset ); + + /*Advance to channel list*/ + ptr += nOffset; + + if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect number of channels"); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 != pnoRequest.aNetworks[i].ucChannelCount) + { + for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++) + { + if (1 != sscanf(ptr,"%hhu %n", + &(pnoRequest.aNetworks[i].aChannels[j]), + &nOffset)) + { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO network channel input is not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + } + /*Advance to next channel number*/ + ptr += nOffset; + } + } + + if (1 != sscanf(ptr,"%u %n", + &(pnoRequest.aNetworks[i].bcastNetwType), + &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO broadcast network type input is not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO bcastNetwType %d offset %d", + pnoRequest.aNetworks[i].bcastNetwType, + nOffset ); + + /*Advance to rssi Threshold*/ + ptr += nOffset; + if (1 != sscanf(ptr,"%d %n", + &(pnoRequest.aNetworks[i].rssiThreshold), + &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO rssi threshold input is not valid %s",ptr); + return VOS_STATUS_E_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO rssi %d offset %d", + pnoRequest.aNetworks[i].rssiThreshold, + nOffset ); + /*Advance to next network*/ + ptr += nOffset; + }/*For ucNetworkCount*/ + + ucParams = sscanf(ptr,"%hhu %n", + &(pnoRequest.scanTimers.ucScanTimersCount), + &nOffset); + + /*Read the scan timers*/ + if (( 1 == ucParams ) && ( pnoRequest.scanTimers.ucScanTimersCount > 0 )) + { + ptr += nOffset; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Scan timer count %d offset %d", + pnoRequest.scanTimers.ucScanTimersCount, + nOffset ); + + if ( SIR_PNO_MAX_SCAN_TIMERS < pnoRequest.scanTimers.ucScanTimersCount ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Incorrect cmd - too many scan timers"); + return VOS_STATUS_E_FAILURE; + } + + for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++ ) + { + ucParams = sscanf(ptr,"%u %u %n", + &(pnoRequest.scanTimers.aTimerValues[i].uTimerValue), + &( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat), + &nOffset); + + if (2 != ucParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Incorrect cmd - diff params then expected %d", ucParams); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO Timer value %d Timer repeat %d offset %d", + pnoRequest.scanTimers.aTimerValues[i].uTimerValue, + pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat, + nOffset ); + + ptr += nOffset; + } + + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "No scan timers provided param count %d scan timers %d", + ucParams, pnoRequest.scanTimers.ucScanTimersCount ); + + /*Scan timers defaults to 5 minutes*/ + pnoRequest.scanTimers.ucScanTimersCount = 1; + pnoRequest.scanTimers.aTimerValues[0].uTimerValue = 60; + pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0; + } + + ucParams = sscanf(ptr,"%hhu %n",&(ucMode), &nOffset); + + pnoRequest.modePNO = ucMode; + /*for LA we just expose suspend option*/ + if (( 1 != ucParams )||( ucMode >= SIR_PNO_MODE_MAX )) + { + pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND; + } + + sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest, + pAdapter->sessionId, + found_pref_network_cb, pAdapter); + + return VOS_STATUS_SUCCESS; +}/*iw_set_pno*/ + +VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U8_t rssiThreshold = 0; + v_U8_t nRead; + + nRead = sscanf(extra + nOffset,"%hhu", + &rssiThreshold); + + if ( 1 != nRead ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect format"); + return VOS_STATUS_E_FAILURE; + } + + sme_SetRSSIFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), rssiThreshold); + return VOS_STATUS_SUCCESS; +} + + +static int iw_set_pno_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Set PNO Private"); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + return iw_set_pno(dev,info,wrqu,extra,0); +} +#endif /*FEATURE_WLAN_SCAN_PNO*/ + +//Common function to SetBand +int hdd_setBand(struct net_device *dev, u8 ui_band) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eCsrBand band; + + VOS_STATUS status; + hdd_context_t *pHddCtx; + hdd_adapter_list_node_t *pAdapterNode, *pNext; + eCsrBand currBand = eCSR_BAND_MAX; + eCsrBand connectedBand; + + pAdapterNode = NULL; + pNext = NULL; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + switch(ui_band) + { + case WLAN_HDD_UI_BAND_AUTO: + band = eCSR_BAND_ALL; + break; + case WLAN_HDD_UI_BAND_5_GHZ: + band = eCSR_BAND_5G; + break; + case WLAN_HDD_UI_BAND_2_4_GHZ: + band = eCSR_BAND_24; + break; + default: + band = eCSR_BAND_MAX; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change band to %u", + __func__, band); + + if (band == eCSR_BAND_MAX) + { + /* Received change band request with invalid band value */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid band value %u", __func__, ui_band); + return -EINVAL; + } + + if ( (band == eCSR_BAND_24 && pHddCtx->cfg_ini->nBandCapability==2) || + (band == eCSR_BAND_5G && pHddCtx->cfg_ini->nBandCapability==1) || + (band == eCSR_BAND_ALL && pHddCtx->cfg_ini->nBandCapability!=0)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: band value %u violate INI settings %u", __func__, + band, pHddCtx->cfg_ini->nBandCapability); + return -EIO; + } + + if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &currBand)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to get current band config", + __func__); + return -EIO; + } + + if (currBand != band) + { + /* Change band request received. + * Abort pending scan requests, flush the existing scan results, + * and change the band capability + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Current band value = %u, new setting %u ", + __func__, currBand, band); + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE); + connectedBand = + hdd_connGetConnectedBand(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)); + + /* Handling is done only for STA and P2P */ + if ( band != eCSR_BAND_ALL && + ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) && + (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) && + (connectedBand != band)) + { + hdd_station_ctx_t *pHddStaCtx = &(pAdapter)->sessionCtx.station; + eHalStatus status = eHAL_STATUS_SUCCESS; + long lrc; + + /* STA already connected on current band, So issue disconnect + * first, then change the band*/ + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s STA (Device mode=%d) connected in band %u, Changing band to %u, Issuing Disconnect" + "Set HDD connState to eConnectionState_NotConnected", + __func__, pAdapter->device_mode, + currBand, band); + + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + INIT_COMPLETION(pAdapter->disconnect_comp_var); + + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + if ( eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s csrRoamDisconnect failure, returned %d", + __func__, (int)status ); + return -EINVAL; + } + + lrc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + + if (lrc == 0) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Timeout while waiting for csrRoamDisconnect", + __func__); + return -ETIMEDOUT ; + } + } + + sme_ScanFlushResult(hHal, pAdapter->sessionId); + + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + if (eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, pAdapter->sessionId, + band)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + FL("Failed to set the band value to %u"), band); + return -EINVAL; + } + wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand)band); + } + return 0; +} + +int hdd_setBand_helper(struct net_device *dev, const char *command) +{ + u8 band; + int ret; + + /* Convert the band value from ascii to integer */ + command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET; + ret = kstrtou8(command, 10, &band); + if (ret < 0) { + hddLog(LOGE, FL("kstrtou8 failed")); + return -EINVAL; + } + + return hdd_setBand(dev, band); +} + +static int iw_set_band_config(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int *value = (int *)extra; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + return hdd_setBand(dev, value[0]); +} + +static int iw_set_power_params_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + char *ptr; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Set power params Private"); + /* ODD number is used for set, copy data using copy_from_user */ + ptr = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + ret = iw_set_power_params(dev, info, wrqu, ptr, 0); + kfree(ptr); + return ret; +} + + + +/*string based input*/ +VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tSirSetPowerParamsReq powerRequest; + char *ptr; + v_U8_t ucType; + v_U32_t uTotalSize, uValue; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power Params data len %d data %s", + wrqu->data.length, + extra); + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if (wrqu->data.length <= nOffset ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "set power param input is not correct"); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize = wrqu->data.length - nOffset; + + /*----------------------------------------------------------------------- + Input is string based and expected to be like this: + + ... + + e.g: + 1 2 2 3 3 0 4 1 5 1 + + e.g. setting just a few: + 1 2 4 1 + + parameter types: + ----------------------------- + 1 - Ignore DTIM + 2 - Listen Interval + 3 - Broadcast Multicast Filter + 4 - Beacon Early Termination + 5 - Beacon Early Termination Interval + -----------------------------------------------------------------------*/ + powerRequest.uIgnoreDTIM = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uListenInterval = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uBcastMcastFilter = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uEnableBET = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uBETInterval = SIR_NOCHANGE_POWER_VALUE; + + ptr = extra + nOffset; + + while ( uTotalSize ) + { + if (1 != sscanf(ptr,"%hhu %n", &(ucType), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize -= nOffset; + + if (!uTotalSize) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type : %d with no value at offset %d", + ucType, nOffset); + return VOS_STATUS_E_FAILURE; + } + + ptr += nOffset; + + if (1 != sscanf(ptr,"%u %n", &(uValue), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter value %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power request parameter %d value %d offset %d", + ucType, uValue, nOffset); + + switch (ucType) + { + case eSIR_IGNORE_DTIM: + powerRequest.uIgnoreDTIM = uValue; + break; + case eSIR_LISTEN_INTERVAL: + powerRequest.uListenInterval = uValue; + break; + case eSIR_MCAST_BCAST_FILTER: + powerRequest.uBcastMcastFilter = uValue; + break; + case eSIR_ENABLE_BET: + powerRequest.uEnableBET = uValue; + break; + case eSIR_BET_INTERVAL: + powerRequest.uBETInterval = uValue; + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type : %d with value: %d at offset %d", + ucType, uValue, nOffset); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize -= nOffset; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power request parameter %d Total size", + uTotalSize); + ptr += nOffset; + /* This is added for dynamic Tele LI enable (0xF1) /disable (0xF0)*/ + if(!(uTotalSize - nOffset) && + (powerRequest.uListenInterval != SIR_NOCHANGE_POWER_VALUE)) + { + uTotalSize = 0; + } + + }/*Go for as long as we have a valid string*/ + + /* put the device into full power*/ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + + /* Apply the power save params*/ + sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE); + + /* put the device back to power save*/ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + + return VOS_STATUS_SUCCESS; +}/*iw_set_power_params*/ + +int iw_set_two_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int *value = (int *)extra; + int sub_cmd = value[0]; + int ret = 0; + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + switch(sub_cmd) { + case WE_SET_SMPS_PARAM: + hddLog(LOG1, "WE_SET_SMPS_PARAM val %d %d", value[1], value[2]); + ret = process_wma_set_command((int)pAdapter->sessionId, + (int)WMI_STA_SMPS_PARAM_CMDID, + value[1] << WMA_SMPS_PARAM_VALUE_S | value[2], VDEV_CMD); + break; +#ifdef DEBUG + case WE_SET_FW_CRASH_INJECT: + hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d", value[1], value[2]); + pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n", + value[1], value[2]); + ret = process_wma_set_command_twoargs((int) pAdapter->sessionId, + (int) GEN_PARAM_CRASH_INJECT, + value[1], value[2], GEN_CMD); + break; +#endif + default: + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd); + break; + } + + return ret; +} + + +// Define the Wireless Extensions to the Linux Network Device structure +// A number of these routines are NULL (meaning they are not implemented.) + +static const iw_handler we_handler[] = +{ + (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */ + (iw_handler) iw_get_name, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) iw_set_freq, /* SIOCSIWFREQ */ + (iw_handler) iw_get_freq, /* SIOCGIWFREQ */ + (iw_handler) iw_set_mode, /* SIOCSIWMODE */ + (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) iw_get_range, /* SIOCGIWRANGE */ + (iw_handler) iw_set_priv, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + (iw_handler) iw_set_ap_address, /* SIOCSIWAP */ + (iw_handler) iw_get_ap_address, /* SIOCGIWAP */ + (iw_handler) iw_set_mlme, /* SIOCSIWMLME */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) iw_set_scan, /* SIOCSIWSCAN */ + (iw_handler) iw_get_scan, /* SIOCGIWSCAN */ + (iw_handler) iw_set_essid, /* SIOCSIWESSID */ + (iw_handler) iw_get_essid, /* SIOCGIWESSID */ + (iw_handler) iw_set_nick, /* SIOCSIWNICKN */ + (iw_handler) iw_get_nick, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */ + (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */ + (iw_handler) iw_set_rts_threshold,/* SIOCSIWRTS */ + (iw_handler) iw_get_rts_threshold,/* SIOCGIWRTS */ + (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */ + (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */ + (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */ + (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */ + (iw_handler) iw_set_retry, /* SIOCSIWRETRY */ + (iw_handler) iw_get_retry, /* SIOCGIWRETRY */ + (iw_handler) iw_set_encode, /* SIOCSIWENCODE */ + (iw_handler) iw_get_encode, /* SIOCGIWENCODE */ + (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */ + (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_genie, /* SIOCSIWGENIE */ + (iw_handler) iw_get_genie, /* SIOCGIWGENIE */ + (iw_handler) iw_set_auth, /* SIOCSIWAUTH */ + (iw_handler) iw_get_auth, /* SIOCGIWAUTH */ + (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ +}; + +static const iw_handler we_private[] = { + + [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, //set priv ioctl + [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, //get priv ioctl + [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, //get priv ioctl + [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone, + [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone, + [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, //action priv ioctl + [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone, + [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec, + [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec, + [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec, +#ifdef FEATURE_OEM_DATA_SUPPORT + [WLAN_PRIV_SET_OEM_DATA_REQ - SIOCIWFIRSTPRIV] = iw_set_oem_data_req, //oem data req Specifc + [WLAN_PRIV_GET_OEM_DATA_RSP - SIOCIWFIRSTPRIV] = iw_get_oem_data_rsp, //oem data req Specifc +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties, +#endif + [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload, + [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics, + [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] = iw_set_keepalive_params +#ifdef WLAN_FEATURE_PACKET_FILTERING + , + [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_packet_filter_params +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + , + [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno_priv +#endif + , + [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config, + [WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_set_dynamic_mcbc_filter, + [WLAN_PRIV_CLEAR_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_clear_dynamic_mcbc_filter, + [WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv, + [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed_priv, + [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_two_ints_getnone, +}; + +/*Maximum command length can be only 15 */ +static const struct iw_priv_args we_private_args[] = { + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_SET_11D_STATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11Dstate" }, + + { WE_WOWL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "wowl" }, + + { WE_SET_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setPower" }, + + { WE_SET_MAX_ASSOC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setMaxAssoc" }, + + { WE_SET_SAP_AUTO_CHANNEL_SELECTION, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setAutoChannel" }, + + { WE_SET_DATA_INACTIVITY_TO, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "inactivityTO" }, + + { WE_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setMaxTxPower" }, + + { WE_SET_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxPower" }, + + { WE_SET_MC_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setMcRate" }, + + { WE_SET_MAX_TX_POWER_2_4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower2G" }, + + { WE_SET_MAX_TX_POWER_5_0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower5G" }, + + /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA + * as well to keep same syntax as in SAP. Now onwards, STA + * will support both */ + { WE_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower" }, + + /* set Higher DTIM Transition (DTIM1 to DTIM3) + * 1 = enable and 0 = disable */ + { + WE_SET_HIGHER_DTIM_TRANSITION, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setHDtimTransn" }, + + { WE_SET_TM_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTmLevel" }, + + { WE_SET_PHYMODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setphymode" }, + + { WE_SET_NSS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "nss" }, + + { WE_SET_LDPC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ldpc" }, + + { WE_SET_TX_STBC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tx_stbc" }, + + { WE_SET_RX_STBC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "rx_stbc" }, + + { WE_SET_SHORT_GI, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "shortgi" }, + + { WE_SET_RTSCTS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "enablertscts" }, + + { WE_SET_CHWIDTH, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "chwidth" }, + + { WE_SET_ANI_EN_DIS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "anienable" }, + + { WE_SET_ANI_POLL_PERIOD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "aniplen" }, + + { WE_SET_ANI_LISTEN_PERIOD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "anilislen" }, + + { WE_SET_ANI_OFDM_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "aniofdmlvl" }, + + { WE_SET_ANI_CCK_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "aniccklvl" }, + + { WE_SET_DYNAMIC_BW, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "cwmenable" }, + + { WE_SET_CTS_CBW, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "cts_cbw" }, + + { WE_SET_GTX_HT_MCS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxHTMcs" }, + + { WE_SET_GTX_VHT_MCS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxVHTMcs" }, + + { WE_SET_GTX_USRCFG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxUsrCfg" }, + + { WE_SET_GTX_THRE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxThre" }, + + { WE_SET_GTX_MARGIN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxMargin" }, + + { WE_SET_GTX_STEP, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxStep" }, + + { WE_SET_GTX_MINTPC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxMinTpc" }, + + { WE_SET_GTX_BWMASK, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "gtxBWMask" }, + + { WE_SET_TX_CHAINMASK, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txchainmask" }, + + { WE_SET_RX_CHAINMASK, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "rxchainmask" }, + + { WE_SET_11N_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11NRates" }, + + { WE_SET_VHT_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11ACRates" }, + + { WE_SET_AMPDU, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ampdu" }, + + { WE_SET_AMSDU, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "amsdu" }, + + { WE_SET_BURST_ENABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "burst_enable" }, + + { WE_SET_BURST_DUR, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "burst_dur" }, + + { WE_SET_TXPOW_2G, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txpow2g" }, + + { WE_SET_TXPOW_5G, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txpow5g" }, + + { WE_SET_POWER_GATING, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "pwrgating" }, + + /* Sub-cmds DBGLOG specific commands */ + { WE_DBGLOG_LOG_LEVEL , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_loglevel" }, + + { WE_DBGLOG_VAP_ENABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_vapon" }, + + { WE_DBGLOG_VAP_DISABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_vapoff" }, + + { WE_DBGLOG_MODULE_ENABLE , + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_modon" }, + + { WE_DBGLOG_MODULE_DISABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_modoff" }, + + { WE_DBGLOG_MOD_LOG_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_mod_loglevel" }, + + { WE_DBGLOG_TYPE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_type" }, + { WE_DBGLOG_REPORT_ENABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "dl_report" }, + + { WE_SET_TXRX_FWSTATS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txrx_fw_stats" }, + + { WE_TXRX_FWSTATS_RESET, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "txrx_fw_st_rst" }, + + { WE_PPS_PAID_MATCH, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "paid_match" }, + + + { WE_PPS_GID_MATCH, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "gid_match" }, + + + { WE_PPS_EARLY_TIM_CLEAR, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "tim_clear" }, + + + { WE_PPS_EARLY_DTIM_CLEAR, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "dtim_clear" }, + + + { WE_PPS_EOF_PAD_DELIM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "eof_delim" }, + + + { WE_PPS_MACADDR_MISMATCH, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "mac_match" }, + + + { WE_PPS_DELIM_CRC_FAIL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "delim_fail" }, + + + { WE_PPS_GID_NSTS_ZERO, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "nsts_zero" }, + + + { WE_PPS_RSSI_CHECK, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "rssi_chk" }, + + { WE_PPS_5G_EBT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "5g_ebt" }, + + { WE_SET_HTSMPS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "htsmps" }, + + + { WE_SET_QPOWER_MAX_PSPOLL_COUNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_qpspollcnt" }, + + { WE_SET_QPOWER_MAX_TX_BEFORE_WAKE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_qtxwake" }, + + { WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_qwakeintv" }, + + { WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_qnodatapoll" }, + + /* handlers for MCC time quota and latency sub ioctls */ + { WE_MCC_CONFIG_LATENCY, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setMccLatency" }, + + { WE_MCC_CONFIG_QUOTA, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setMccQuota" }, + + { WE_SET_DEBUG_LOG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setDbgLvl" }, + + { WE_SET_SCAN_BAND_PREFERENCE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_scan_pref" }, + /* handlers for early_rx power save */ + { WE_SET_EARLY_RX_ADJUST_ENABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_enable" }, + + { WE_SET_EARLY_RX_TGT_BMISS_NUM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_bmiss_val" }, + + { WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_bmiss_smpl" }, + + { WE_SET_EARLY_RX_SLOP_STEP, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_slop_step" }, + + { WE_SET_EARLY_RX_INIT_SLOP, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_init_slop" }, + + { WE_SET_EARLY_RX_ADJUST_PAUSE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_adj_pause" }, + + { WE_SET_EARLY_RX_DRIFT_SAMPLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "erx_dri_sample" }, + + { WLAN_PRIV_SET_NONE_GET_INT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "" }, + + /* handlers for sub-ioctl */ + { WE_GET_11D_STATE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get11Dstate" }, + + { WE_IBSS_STATUS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getAdhocStatus" }, + + { WE_GET_WLAN_DBG, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getwlandbg" }, + + { WE_GET_MAX_ASSOC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getMaxAssoc" }, + + { WE_GET_SAP_AUTO_CHANNEL_SELECTION, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getAutoChannel" }, + + { WE_GET_CONCURRENCY_MODE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getconcurrency" }, + + { WE_GET_NSS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_nss" }, + + { WE_GET_LDPC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_ldpc" }, + + { WE_GET_TX_STBC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_tx_stbc" }, + + { WE_GET_RX_STBC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_rx_stbc" }, + + { WE_GET_SHORT_GI, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_shortgi" }, + + { WE_GET_RTSCTS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_rtscts" }, + + { WE_GET_CHWIDTH, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_chwidth" }, + + { WE_GET_ANI_EN_DIS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_anienable" }, + + { WE_GET_ANI_POLL_PERIOD, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_aniplen" }, + + { WE_GET_ANI_LISTEN_PERIOD, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_anilislen" }, + + { WE_GET_ANI_OFDM_LEVEL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_aniofdmlvl" }, + + { WE_GET_ANI_CCK_LEVEL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_aniccklvl" }, + + { WE_GET_DYNAMIC_BW, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_cwmenable" }, + + { WE_GET_GTX_HT_MCS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxHTMcs" }, + + { WE_GET_GTX_VHT_MCS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxVHTMcs" }, + + { WE_GET_GTX_USRCFG, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxUsrCfg" }, + + { WE_GET_GTX_THRE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxThre" }, + + { WE_GET_GTX_MARGIN, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxMargin" }, + + { WE_GET_GTX_STEP, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxStep" }, + + { WE_GET_GTX_MINTPC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxMinTpc" }, + + { WE_GET_GTX_BWMASK, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gtxBWMask" }, + + { WE_GET_TX_CHAINMASK, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txchainmask" }, + + { WE_GET_RX_CHAINMASK, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_rxchainmask" }, + + { WE_GET_11N_RATE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_11nrate" }, + + { WE_GET_AMPDU, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_ampdu" }, + + { WE_GET_AMSDU, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_amsdu" }, + + { WE_GET_BURST_ENABLE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_burst_en" }, + + { WE_GET_BURST_DUR, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_burst_dur" }, + + { WE_GET_TXPOW_2G, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txpow2g" }, + + { WE_GET_TXPOW_5G, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txpow5g" }, + + { WE_GET_POWER_GATING, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_pwrgating" }, + + { WE_GET_PPS_PAID_MATCH, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_paid_match"}, + + + { WE_GET_PPS_GID_MATCH, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_gid_match"}, + + + { WE_GET_PPS_EARLY_TIM_CLEAR, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_tim_clear"}, + + + { WE_GET_PPS_EARLY_DTIM_CLEAR, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_dtim_clear"}, + + + { WE_GET_PPS_EOF_PAD_DELIM, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_eof_delim"}, + + + { WE_GET_PPS_MACADDR_MISMATCH, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_mac_match"}, + + + { WE_GET_PPS_DELIM_CRC_FAIL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_delim_fail"}, + + + { WE_GET_PPS_GID_NSTS_ZERO, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_nsts_zero"}, + + + { WE_GET_PPS_RSSI_CHECK, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_rssi_chk"}, + + { WE_GET_QPOWER_MAX_PSPOLL_COUNT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_qpspollcnt"}, + + { WE_GET_QPOWER_MAX_TX_BEFORE_WAKE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_qtxwake"}, + + { WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_qwakeintv"}, + + { WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_qnodatapoll"}, + + { WE_GET_SCAN_BAND_PREFERENCE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_scan_pref"}, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_CHAR_GET_NONE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_WOWL_ADD_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlAddPtrn" }, + + { WE_WOWL_DEL_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlDelPtrn" }, + +#if defined WLAN_FEATURE_VOWIFI + /* handlers for sub-ioctl */ + { WE_NEIGHBOR_REPORT_REQUEST, + IW_PRIV_TYPE_CHAR | 512, + 0, + "neighbor" }, +#endif + { WE_SET_AP_WPS_IE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "set_ap_wps_ie" }, + + { WE_SET_CONFIG, + IW_PRIV_TYPE_CHAR| 512, + 0, + "setConfig" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_THREE_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_SET_WLAN_DBG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setwlandbg" }, + + { WE_SET_SAP_CHANNELS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setsapchannels" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_GET_CHAR_SET_NONE, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "" }, + + /* handlers for sub-ioctl */ + { WE_WLAN_VERSION, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "version" }, + { WE_GET_STATS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getStats" }, + { WE_GET_STATES, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getHostStates" }, + { WE_GET_CFG, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getConfig" }, +#ifdef WLAN_FEATURE_11AC + { WE_GET_RSSI, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getRSSI" }, +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + { WE_GET_ROAM_RSSI, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getRoamRSSI" }, +#endif + { WE_GET_WMM_STATUS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getWmmStatus" }, + { + WE_GET_CHANNEL_LIST, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getChannelList" }, +#ifdef FEATURE_WLAN_TDLS + { + WE_GET_TDLS_PEERS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getTdlsPeers" }, +#endif +#ifdef WLAN_FEATURE_11W + { + WE_GET_11W_INFO, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getPMFInfo" }, +#endif + { WE_GET_PHYMODE, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getphymode" }, +#ifdef FEATURE_OEM_DATA_SUPPORT + { WE_GET_OEM_DATA_CAP, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getOemDataCap" }, +#endif /* FEATURE_OEM_DATA_SUPPORT */ + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_NONE_GET_NONE, + 0, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_CLEAR_STATS, + 0, + 0, + "clearStats" }, + { WE_GET_RECOVERY_STAT, + 0, + 0, + "getRecoverStat" }, +#ifdef WLAN_BTAMP_FEATURE + { WE_ENABLE_AMP, + 0, + 0, + "enableAMP" }, + { WE_DISABLE_AMP, + 0, + 0, + "disableAMP" }, +#endif /* WLAN_BTAMP_FEATURE */ + { WE_ENABLE_DXE_STALL_DETECT, + 0, + 0, + "dxeStallDetect" }, + { WE_DISPLAY_DXE_SNAP_SHOT, + 0, + 0, + "dxeSnapshot" }, + { WE_DISPLAY_DATAPATH_SNAP_SHOT, + 0, + 0, + "dataSnapshot"}, + { + WE_SET_REASSOC_TRIGGER, + 0, + 0, + "reassoc" }, + { WE_DUMP_AGC_START, + 0, + 0, + "dump_agc_start" }, + + { WE_DUMP_AGC, + 0, + 0, + "dump_agc" }, + + { WE_DUMP_CHANINFO_START, + 0, + 0, + "dump_chninfo_en" }, + + { WE_DUMP_CHANINFO, + 0, + 0, + "dump_chninfo" }, + + { WE_DUMP_WATCHDOG, + 0, + 0, + "dump_watchdog" }, +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + { WE_DUMP_PCIE_LOG, + 0, + 0, + "dump_pcie_log" }, +#endif + /* handlers for main ioctl */ + { WLAN_PRIV_SET_VAR_INT_GET_NONE, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_LOG_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dump" }, + + /* handlers for sub-ioctl */ + { WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setdumplog" }, + + { WE_MTRACE_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dumplog" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_CREDENTIAL, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccCrdnl" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccConfig" }, + +#ifdef FEATURE_WLAN_TDLS + /* handlers for sub ioctl */ + { + WE_TDLS_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setTdlsConfig" }, +#endif + { + WE_UNIT_TEST_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setUnitTestCmd" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_ADD_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "addTspec" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_DEL_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "delTspec" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_GET_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getTspec" }, + +#ifdef FEATURE_OEM_DATA_SUPPORT + /* handlers for main ioctl - OEM DATA */ + { + WLAN_PRIV_SET_OEM_DATA_REQ, + IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_req) | IW_PRIV_SIZE_FIXED, + 0, + "set_oem_data_req" }, + + /* handlers for main ioctl - OEM DATA */ + { + WLAN_PRIV_GET_OEM_DATA_RSP, + 0, + IW_PRIV_TYPE_BYTE | MAX_OEM_DATA_RSP_LEN, + "get_oem_data_rsp" }, +#endif + + /* handlers for main ioctl - host offload */ + { + WLAN_PRIV_SET_HOST_OFFLOAD, + IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest), + 0, + "setHostOffload" }, + + { + WLAN_GET_WLAN_STATISTICS, + 0, + IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN, + "getWlanStats" }, + + { + WLAN_SET_KEEPALIVE_PARAMS, + IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN, + 0, + "setKeepAlive" }, +#ifdef WLAN_FEATURE_PACKET_FILTERING + { + WLAN_SET_PACKET_FILTER_PARAMS, + IW_PRIV_TYPE_BYTE | sizeof(tPacketFilterCfg), + 0, + "setPktFilter" }, +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + { + WLAN_SET_PNO, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + 0, + "setpno" }, +#endif + { + WLAN_SET_BAND_CONFIG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "SETBAND" }, + /* handlers for dynamic MC BC ioctl */ + { + WLAN_PRIV_SET_MCBC_FILTER, + IW_PRIV_TYPE_BYTE | sizeof(tRcvFltMcAddrList), + 0, + "setMCBCFilter" }, + { + WLAN_PRIV_CLEAR_MCBC_FILTER, + 0, + 0, + "clearMCBCFilter" }, + { + WLAN_SET_POWER_PARAMS, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + 0, + "setpowerparams" }, + { + WLAN_GET_LINK_SPEED, + IW_PRIV_TYPE_CHAR | 18, + IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_TWO_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, + "" }, + { WE_SET_SMPS_PARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, "set_smps_param" }, +#ifdef DEBUG + { WE_SET_FW_CRASH_INJECT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, "crash_inject" }, +#endif +}; + + + +const struct iw_handler_def we_handler_def = { + .num_standard = sizeof(we_handler) / sizeof(we_handler[0]), + .num_private = sizeof(we_private) / sizeof(we_private[0]), + .num_private_args = sizeof(we_private_args) / sizeof(we_private_args[0]), + + .standard = (iw_handler *)we_handler, + .private = (iw_handler *)we_private, + .private_args = we_private_args, + .get_wireless_stats = get_wireless_stats, +}; + +int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3) +{ + v_U32_t cmd = 288; //Command to RIVA + hdd_context_t *pHddCtx = NULL; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + /* + *configMccParam : specify the bit which needs to be modified + *allowed to update based on wlan_qcom_cfg.ini + * configuration + * Bit 0 : SCHEDULE_TIME_SLICE MIN : 5 MAX : 20 + * Bit 1 : MAX_NULL_SEND_TIME MIN : 1 MAX : 10 + * Bit 2 : TX_EARLY_STOP_TIME MIN : 1 MAX : 10 + * Bit 3 : RX_DRAIN_TIME MIN : 1 MAX : 10 + * Bit 4 : CHANNEL_SWITCH_TIME MIN : 1 MAX : 20 + * Bit 5 : MIN_CHANNEL_TIME MIN : 5 MAX : 20 + * Bit 6 : PARK_BEFORE_TBTT MIN : 1 MAX : 5 + * Bit 7 : MIN_AFTER_DTIM MIN : 5 MAX : 15 + * Bit 8 : TOO_CLOSE_MARGIN MIN : 1 MAX : 3 + * Bit 9 : Reserved + */ + switch (arg1) + { + //Update MCC SCHEDULE_TIME_SLICE parameter + case MCC_SCHEDULE_TIME_SLICE_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0001) + { + if((arg2 >= 5) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC MAX_NULL_SEND_TIME parameter + case MCC_MAX_NULL_SEND_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0002) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC TX_EARLY_STOP_TIME parameter + case MCC_TX_EARLY_STOP_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0004) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC RX_DRAIN_TIME parameter + case MCC_RX_DRAIN_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0008) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC CHANNEL_SWITCH_TIME parameter + case MCC_CHANNEL_SWITCH_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0010) + { + if((arg2 >= 1) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC MIN_CHANNEL_TIME parameter + case MCC_MIN_CHANNEL_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0020) + { + if((arg2 >= 5) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC PARK_BEFORE_TBTT parameter + case MCC_PARK_BEFORE_TBTT_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0040) + { + if((arg2 >= 1) && (arg2 <= 5)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC MIN_AFTER_DTIM parameter + case MCC_MIN_AFTER_DTIM_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0080) + { + if((arg2 >= 5) && (arg2 <= 15)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + //Update MCC TOO_CLOSE_MARGIN parameter + case MCC_TOO_CLOSE_MARGIN_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0100) + { + if((arg2 >= 1) && (arg2 <= 3)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value", __FUNCTION__); + return 0; + } + } + break; + + default : + hddLog(LOGE, FL("Unknown / Not allowed to configure parameter : %d"), arg1); + break; + } + return 0; +} + +int hdd_set_wext(hdd_adapter_t *pAdapter) +{ + hdd_wext_state_t *pwextBuf; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + // Now configure the roaming profile links. To SSID and bssid. + pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0; + pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID; + + pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0; + pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId; + + /*Set the numOfChannels to zero to scan all the channels*/ + pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0; + pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL; + + /* Default is no encryption */ + pwextBuf->roamProfile.EncryptionType.numEntries = 1; + pwextBuf->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pwextBuf->roamProfile.mcEncryptionType.numEntries = 1; + pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + + /* Default is no authentication */ + pwextBuf->roamProfile.AuthType.numEntries = 1; + pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_TAURUS; + pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + + /*Set the default scan mode*/ + pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN; + + hdd_clearRoamProfileIe(pAdapter); + + return VOS_STATUS_SUCCESS; + + } + +int hdd_register_wext(struct net_device *dev) + { + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + VOS_STATUS status; + + ENTER(); + + // Zero the memory. This zeros the profile structure. + memset(pwextBuf, 0,sizeof(hdd_wext_state_t)); + + init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->completion_var); + + + status = hdd_set_wext(pAdapter); + + if(!VOS_IS_STATUS_SUCCESS(status)) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_wext failed!!")); + return eHAL_STATUS_FAILURE; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->vosevent))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos event init failed!!")); + return eHAL_STATUS_FAILURE; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->scanevent))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD scan event init failed!!")); + return eHAL_STATUS_FAILURE; + } + + // Register as a wireless device + dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def; + + EXIT(); + return 0; +} + +int hdd_UnregisterWext(struct net_device *dev) +{ + hddLog(LOG1, FL("dev(%p)"), dev); + + if (dev != NULL) { + rtnl_lock(); + dev->wireless_handlers = NULL; + rtnl_unlock(); + } + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wmm.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wmm.c new file mode 100644 index 0000000000000..1c6ea7105b891 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wmm.c @@ -0,0 +1,2690 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + @file wlan_hdd_wmm.c + + This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation) + houses all the logic for WMM in HDD. + + On the control path, it has the logic to setup QoS, modify QoS and delete + QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an + explicit application invoked and an internal HDD invoked. The implicit QoS + is for applications that do NOT call the custom QCT WLAN OIDs for QoS but + which DO mark their traffic for prioritization. It also has logic to start, + update and stop the U-APSD trigger frame generation. It also has logic to + read WMM related config parameters from the registry. + + On the data path, it has the logic to figure out the WMM AC of an egress + packet and when to signal TL to serve a particular AC queue. It also has the + logic to retrieve a packet based on WMM priority in response to a fetch from + TL. + + The remaining functions are utility functions for information hiding. +============================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// change logging behavior based upon debug flag +#ifdef HDD_WMM_DEBUG +#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL +#else +#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR +#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN +#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO +#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH +#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW +#endif + + +#define WLAN_HDD_MAX_DSCP 0x3f + +// DHCP Port number +#define DHCP_SOURCE_PORT 0x4400 +#define DHCP_DESTINATION_PORT 0x4300 + +#define HDD_WMM_UP_TO_AC_MAP_SIZE 8 + +const v_U8_t hddWmmUpToAcMap[] = { + WLANTL_AC_BE, + WLANTL_AC_BK, + WLANTL_AC_BK, + WLANTL_AC_BE, + WLANTL_AC_VI, + WLANTL_AC_VI, + WLANTL_AC_VO, + WLANTL_AC_VO +}; + +//Linux based UP -> AC Mapping +const v_U8_t hddLinuxUpToAcMap[8] = { + HDD_LINUX_AC_BE, + HDD_LINUX_AC_BK, + HDD_LINUX_AC_BK, + HDD_LINUX_AC_BE, + HDD_LINUX_AC_VI, + HDD_LINUX_AC_VI, + HDD_LINUX_AC_VO, + HDD_LINUX_AC_VO +}; + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/** + @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and + how to update UAPSD parameters in TL + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + VOS_STATUS status; + v_U32_t service_interval; + v_U32_t suspension_interval; + sme_QosWmmDirType direction; + v_BOOL_t psb; + + + // The TSPEC must be valid + if (pAc->wmmAcTspecValid == VOS_FALSE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid TSPEC", + __func__); + return; + } + + // determine the service interval + if (pAc->wmmAcTspecInfo.min_service_interval) + { + service_interval = pAc->wmmAcTspecInfo.min_service_interval; + } + else if (pAc->wmmAcTspecInfo.max_service_interval) + { + service_interval = pAc->wmmAcTspecInfo.max_service_interval; + } + else + { + // no service interval is present in the TSPEC + // this is OK, there just won't be U-APSD + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: No service interval supplied", + __func__); + service_interval = 0; + } + + // determine the suspension interval & direction + suspension_interval = pAc->wmmAcTspecInfo.suspension_interval; + direction = pAc->wmmAcTspecInfo.ts_info.direction; + psb = pAc->wmmAcTspecInfo.ts_info.psb; + + // if we have previously enabled U-APSD, have any params changed? + if ((pAc->wmmAcUapsdInfoValid) && + (pAc->wmmAcUapsdServiceInterval == service_interval) && + (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) && + (pAc->wmmAcUapsdDirection == direction) && + (pAc->wmmAcIsUapsdEnabled == psb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: No change in U-APSD parameters", + __func__); + return; + } + + // are we in the appropriate power save modes? + if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + ePMC_BEACON_MODE_POWER_SAVE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: BMPS is not enabled", + __func__); + return; + } + + if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + ePMC_UAPSD_MODE_POWER_SAVE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: U-APSD is not enabled", + __func__); + return; + } + + // everything is in place to notify TL + status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType, + pAc->wmmAcTspecInfo.ts_info.tid, + pAc->wmmAcTspecInfo.ts_info.up, + service_interval, + suspension_interval, + direction, + psb, + pAdapter->sessionId); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to enable U-APSD for AC=%d", + __func__, acType ); + return; + } + + // stash away the parameters that were used + pAc->wmmAcUapsdInfoValid = VOS_TRUE; + pAc->wmmAcUapsdServiceInterval = service_interval; + pAc->wmmAcUapsdSuspensionInterval = suspension_interval; + pAc->wmmAcUapsdDirection = direction; + pAc->wmmAcIsUapsdEnabled = psb; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Enabled UAPSD in TL srv_int=%d " + "susp_int=%d dir=%d AC=%d", + __func__, + service_interval, + suspension_interval, + direction, + acType); + +} + +/** + @brief hdd_wmm_disable_tl_uapsd() - function which decides whether + to disable UAPSD parameters in TL + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + VOS_STATUS status; + + + // have we previously enabled UAPSD? + if (pAc->wmmAcUapsdInfoValid == VOS_TRUE) + { + status = WLANTL_DisableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType, + pAdapter->sessionId); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to disable U-APSD for AC=%d", + __func__, acType ); + } + else + { + // TL no longer has valid UAPSD info + pAc->wmmAcUapsdInfoValid = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Disabled UAPSD in TL for AC=%d", + __func__, + acType); + } + } +} + +#endif + +/** + @brief hdd_wmm_free_context() - function which frees a QoS context + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + // must have been freed in another thread + return; + } + + // get pointer to the adapter context + pAdapter = pQosContext->pAdapter; + + // take the wmmLock since we're manipulating the context list + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + + // make sure nobody thinks this is a valid context + pQosContext->magic = 0; + + // unlink the context + list_del(&pQosContext->node); + + // done manipulating the list + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + + // reclaim memory + kfree(pQosContext); + +} + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/** + @brief hdd_wmm_notify_app() - function which notifies an application + changes in state of it flow + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +#define MAX_NOTIFY_LEN 50 +static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter; + union iwreq_data wrqu; + char buf[MAX_NOTIFY_LEN+1]; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return; + } + + + // create the event + memset(&wrqu, 0, sizeof(wrqu)); + memset(buf, 0, sizeof(buf)); + + snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]", + (unsigned int)pQosContext->handle, + (unsigned int)pQosContext->lastStatus); + + wrqu.data.pointer = buf; + wrqu.data.length = strlen(buf); + + // get pointer to the adapter + pAdapter = pQosContext->pAdapter; + + // send the event + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Sending [%s]", __func__, buf); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + + + +#ifdef FEATURE_WLAN_ESE +/** + @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is + called for every inactivity interval per AC. This function gets the + current transmitted packets on the given AC, and checks if there where + any TX activity from the previous interval. If there was no traffic + then it would delete the TS that was negotiated on that AC. + + @param pUserData : [in] pointer to pQosContext + + @return : NONE +*/ +void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData ) +{ + hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData; + hdd_adapter_t* pAdapter; + hdd_wmm_ac_status_t *pAc; + hdd_wlan_wmm_status_e status; + VOS_STATUS vos_status; + v_U32_t currentTrafficCnt = 0; + WLANTL_ACEnumType acType = pQosContext->acType; + + pAdapter = pQosContext->pAdapter; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + // Get the Tx stats for this AC. + currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"), + acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt); + if (pAc->wmmPrevTrafficCnt == currentTrafficCnt) + { + // If there is no traffic activity, delete the TSPEC for this AC + status = hdd_wmm_delts(pAdapter, pQosContext->handle); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"), + acType, status); + } + else + { + pAc->wmmPrevTrafficCnt = currentTrafficCnt; + if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED) + { + // Restart the timer + vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Restarting inactivity timer failed on AC %d"), acType); + } + } + else + { + VOS_ASSERT(vos_timer_getCurrentState( + &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED); + } + } + + return; +} + + +/** + @brief hdd_wmm_enable_inactivity_timer() - function to enable the + traffic inactivity timer for the given AC, if the inactivity_interval + specified in the ADDTS parameters is non-zero + + @param pQosContext : [in] pointer to pQosContext + @param inactivityTime: [in] value of the inactivity interval in millisecs + + @return : VOS_STATUS_E_FAILURE + VOS_STATUS_SUCCESS +*/ +VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime) +{ + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc; + + pAdapter = pQosContext->pAdapter; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + + // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero, + // a traffic inactivity timer needs to be started for the given AC + vos_status = vos_timer_init( + &pAc->wmmInactivityTimer, + VOS_TIMER_TYPE_SW, + hdd_wmm_inactivity_timer_cb, + (v_PVOID_t)pQosContext ); + if ( !VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Initializing inactivity timer failed on AC %d"), acType); + return vos_status; + } + + // Start the inactivity timer + vos_status = vos_timer_start( + &pAc->wmmInactivityTimer, + inactivityTime); + if ( !VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Starting inactivity timer failed on AC %d"), acType); + return vos_status; + } + pAc->wmmInactivityTime = inactivityTime; + // Initialize the current tx traffic count on this AC + pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType]; + + return vos_status; +} + +/** + @brief hdd_wmm_enable_inactivity_timer() - function to disable the + traffic inactivity timer for the given AC. This would be called when + deleting the TS. + + @param pQosContext : [in] pointer to pQosContext + + @return : VOS_STATUS_E_FAILURE + VOS_STATUS_SUCCESS +*/ +VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + + // Clear the timer and the counter + pAc->wmmInactivityTime = 0; + pAc->wmmPrevTrafficCnt = 0; + vos_timer_stop(&pAc->wmmInactivityTimer); + vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer); + + return vos_status; +} +#endif // FEATURE_WLAN_ESE + +/** + @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving + QoS notifications. Even though this function has a static scope it gets called + externally through some function pointer magic (so there is a need for + rigorous parameter checking) + + @param hHal : [in] the HAL handle + @param HddCtx : [in] the HDD specified handle + @param pCurrentQosInfo : [in] the TSPEC params + @param SmeStatus : [in] the QoS related SME status + + @return + eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise +*/ +static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal, + void * hddCtx, + sme_QosWmmTspecInfo* pCurrentQosInfo, + sme_QosStatusType smeStatus, + v_U32_t qosFlowId) +{ + hdd_wmm_qos_context_t* pQosContext = hddCtx; + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wmm_ac_status_t *pAc; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return eHAL_STATUS_FAILURE; + } + + pAdapter = pQosContext->pAdapter; + acType = pQosContext->acType; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: status %d flowid %d info %p", + __func__, smeStatus, qosFlowId, pCurrentQosInfo); + + switch (smeStatus) + { + + case SME_QOS_STATUS_SETUP_SUCCESS_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is complete", + __func__); + + // there will always be a TSPEC returned with this status, even if + // a TSPEC is not exchanged OTA + if (pCurrentQosInfo) + { + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + } + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_FALSE; + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL for TL AC %d", + __func__, acType); + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + +#ifdef FEATURE_WLAN_ESE + // Check if the inactivity interval is specified + if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Inactivity timer value = %d for AC=%d", + __func__, pCurrentQosInfo->inactivity_interval, acType); + hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval); + } +#endif // FEATURE_WLAN_ESE + + // notify TL to enable trigger frames if necessary + hdd_wmm_enable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup is complete (U-APSD set previously)", + __func__); + + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING; + hdd_wmm_notify_app(pQosContext); + } + + break; + + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup failed", + __func__); + // QoS setup failed + + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_FALSE; + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED; + + hdd_wmm_notify_app(pQosContext); + } + + /* + * Setting up QoS Failed, QoS context can be released. + * SME is releasing this flow information and if HDD doesn't release this + * context, next time if application uses the same handle to set-up QoS, + * HDD (as it has QoS context for this handle) will issue Modify QoS + * request to SME but SME will reject as no it has no information + * for this flow. + */ + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup Invalid Params, notify TL", + __func__); + // QoS setup failed + pAc->wmmAcAccessAllowed = VOS_FALSE; + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // we note the failure, but we also mark access as allowed so that + // the packets will flow. Note that the MAC will "do the right thing" + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup failed, not a QoS AP", + __func__); + if (!HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_SETUP_MODIFIED_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup modified", + __func__); + if (pCurrentQosInfo) + { + // update the TSPEC + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED; + hdd_wmm_notify_app(pQosContext); + } + + // need to tell TL to update its UAPSD handling + hdd_wmm_enable_tl_uapsd(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // this was triggered by implicit QoS so we know packets are pending + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + // nothing to do for now + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup successful but U-APSD failed", + __func__); + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // QoS setup was successful but setting U=APSD failed + // Since the OTA part of the request was successful, we don't mark + // this as a failure. + // the packets will flow. Note that the MAC will "do the right thing" + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessFailed = VOS_FALSE; + pAc->wmmAcAccessPending = VOS_FALSE; + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + // Since U-APSD portion failed disabled trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_RELEASE_SUCCESS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Release is complete", + __func__); + + if (pCurrentQosInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: flows still active", + __func__); + + // there is still at least one flow active for this AC + // so update the AC state + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + + // need to tell TL to update its UAPSD handling + hdd_wmm_enable_tl_uapsd(pQosContext); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: last flow", + __func__); + + // this is the last flow active for this AC so update the AC state + pAc->wmmAcTspecValid = VOS_FALSE; + + // DELTS is successful, do not allow + pAc->wmmAcAccessAllowed = VOS_FALSE; + + // need to tell TL to update its UAPSD handling + hdd_wmm_disable_tl_uapsd(pQosContext); + } + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + + // we are done with this flow + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_RELEASE_FAILURE_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Release failure", + __func__); + + // we don't need to update our state or TL since nothing has changed + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + break; + + case SME_QOS_STATUS_RELEASE_QOS_LOST_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: QOS Lost indication received", + __func__); + + // current TSPEC is no longer valid + pAc->wmmAcTspecValid = VOS_FALSE; + // AP has sent DELTS, do not allow + pAc->wmmAcAccessAllowed = VOS_FALSE; + + // need to tell TL to update its UAPSD handling + hdd_wmm_disable_tl_uapsd(pQosContext); + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + // we no longer have implicit access granted + pAc->wmmAcAccessGranted = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_FALSE; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Explicit Qos, notifying user space", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST; + hdd_wmm_notify_app(pQosContext); + } + + // we are done with this flow + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Release pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Release Invalid Params", + __func__); + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Modification is complete, notify TL", + __func__); + + // there will always be a TSPEC returned with this status, even if + // a TSPEC is not exchanged OTA + if (pCurrentQosInfo) + { + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + } + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + + // notify TL to enable trigger frames if necessary + hdd_wmm_enable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY: + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP: + // the flow modification failed so we'll leave in place + // whatever existed beforehand + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: modification pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + // the flow modification was successful but no QoS changes required + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP: + // invalid params -- notify the application + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING: + // nothing to do for now. when APSD is established we'll have work to do + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Modify successful but U-APSD failed", + __func__); + + // QoS modification was successful but setting U=APSD failed. + // This will always be an explicit QoS instance, so all we can + // do is notify the application and let it clean up. + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + // Since U-APSD portion failed disabled trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_HANDING_OFF: + // no roaming so we won't see this + break; + + case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND: + // need to tell TL to stop trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + break; + + case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND: + // need to tell TL to start sending trigger frames again + hdd_wmm_enable_tl_uapsd(pQosContext); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", + __func__, smeStatus ); + VOS_ASSERT(0); + } + + // if Tspec only allows downstream traffic then access is not allowed + if (pAc->wmmAcTspecValid && + (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)) { + pAc->wmmAcAccessAllowed = VOS_FALSE; + } + + // if we have valid Tpsec or if ACM bit is not set, allow access + if ((pAc->wmmAcTspecValid && + (pAc->wmmAcTspecInfo.ts_info.direction != SME_QOS_WMM_TS_DIR_DOWNLINK)) || + !pAc->wmmAcAccessRequired) { + pAc->wmmAcAccessAllowed = VOS_TRUE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: complete, access for TL AC %d is%sallowed", + __func__, + acType, + pAc->wmmAcAccessAllowed ? " " : " not "); + + return eHAL_STATUS_SUCCESS; +} +#endif + +/**======================================================================== + @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically + + @param pAdapter : [in] pointer to adapter structure + + @param ptr : [in] pointer to command buffer + + @return : Zero on success, appropriate error on failure. + =======================================================================*/ +int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr) +{ + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return -EINVAL; + } + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: ptr is NULL", __func__); + return -EINVAL; + } + /* convert ASCII to integer */ + pAdapter->configuredPsb = ptr[9] - '0'; + pAdapter->psbChanged = HDD_PSB_CHANGED; + + return 0; +} + +/**============================================================================ + @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup + QoS for any AC requiring it + + @param work : [in] pointer to work structure + + @return : void + ===========================================================================*/ +static void hdd_wmm_do_implicit_qos(struct work_struct *work) +{ + hdd_wmm_qos_context_t* pQosContext = + container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos); + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wmm_ac_status_t *pAc; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + VOS_STATUS status; + sme_QosStatusType smeStatus; +#endif + sme_QosWmmTspecInfo qosInfo; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return; + } + + pAdapter = pQosContext->pAdapter; + acType = pQosContext->acType; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: pAdapter %p acType %d", + __func__, pAdapter, acType); + + if (!pAc->wmmAcAccessNeeded) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: AC %d doesn't need service", + __func__, acType); + pQosContext->magic = 0; + kfree(pQosContext); + return; + } + + pAc->wmmAcAccessPending = VOS_TRUE; + pAc->wmmAcAccessNeeded = VOS_FALSE; + + memset(&qosInfo, 0, sizeof(qosInfo)); + + qosInfo.ts_info.psb = pAdapter->configuredPsb; + + switch (acType) + { + case WLANTL_AC_VO: + qosInfo.ts_info.up = SME_QOS_WMM_UP_VO; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_VO) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv; + break; + case WLANTL_AC_VI: + qosInfo.ts_info.up = SME_QOS_WMM_UP_VI; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_VI) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv; + break; + default: + case WLANTL_AC_BE: + qosInfo.ts_info.up = SME_QOS_WMM_UP_BE; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_BE) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv; + break; + case WLANTL_AC_BK: + qosInfo.ts_info.up = SME_QOS_WMM_UP_BK; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_BK) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv; + break; + } +#ifdef FEATURE_WLAN_ESE + qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval; +#endif + qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition; + + switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy) + { + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK: + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + break; + + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK: + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + break; + + default: + // unknown + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + } + + if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) + { + if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId)) + { + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + } + } + + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList); + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &qosInfo, + hdd_wmm_sme_callback, + pQosContext, + qosInfo.ts_info.up, + &pQosContext->qosFlowId); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: sme_QosSetupReq returned %d flowid %d", + __func__, smeStatus, pQosContext->qosFlowId); + + // need to check the return values and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + // setup is pending, so no more work to do now. + // all further work will be done in hdd_wmm_sme_callback() + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is pending, no further work", + __func__); + + break; + + + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + // we can't tell the difference between when a request fails because + // AP rejected it versus when SME encountered an internal error + + // in either case SME won't ever reference this context so + // free the record + hdd_wmm_free_context(pQosContext); + + // fall through and start packets flowing + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + // no ACM in effect, no need to setup U-APSD + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + // no ACM in effect, U-APSD is desired but was already setup + + // for these cases everything is already setup so we can + // signal TL that it has work to do + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is complete, notify TL", + __func__); + + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + + break; + + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", + __func__, smeStatus ); + VOS_ASSERT(0); + } +#endif + +} + +/**============================================================================ + @brief hdd_wmm_init() - Function which will initialize the WMM configuration + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ) +{ + sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap; + v_U8_t dscp; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + /* + * DSCP to User Priority Lookup Table + * By default use the 3 Precedence bits of DSCP as the User Priority + */ + for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++) { + hddWmmDscpToUpMap[dscp] = dscp >> 3; + } + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_adapter_init() - Function which will initialize the WMM + configuration and status to an initial state. + The configuration can later be overwritten via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter ) +{ + hdd_wmm_ac_status_t *pAcStatus; + WLANTL_ACEnumType acType; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + pAdapter->hddWmmStatus.wmmQap = VOS_FALSE; + INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList); + mutex_init(&pAdapter->hddWmmStatus.wmmLock); + + for (acType = 0; acType < WLANTL_MAX_AC; acType++) + { + pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + pAcStatus->wmmAcAccessRequired = VOS_FALSE; + pAcStatus->wmmAcAccessNeeded = VOS_FALSE; + pAcStatus->wmmAcAccessPending = VOS_FALSE; + pAcStatus->wmmAcAccessFailed = VOS_FALSE; + pAcStatus->wmmAcAccessGranted = VOS_FALSE; + pAcStatus->wmmAcAccessAllowed = VOS_FALSE; + pAcStatus->wmmAcTspecValid = VOS_FALSE; + pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE; + } + // Invalid value(0xff) to indicate psb not configured through framework initially. + pAdapter->configuredPsb = HDD_PSB_CFG_INVALID; + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status + for all the ACs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter ) +{ + hdd_wmm_ac_status_t *pAcStatus; + WLANTL_ACEnumType acType; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + for (acType = 0; acType < WLANTL_MAX_AC; acType++) + { + pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + pAcStatus->wmmAcAccessRequired = VOS_FALSE; + pAcStatus->wmmAcAccessNeeded = VOS_FALSE; + pAcStatus->wmmAcAccessPending = VOS_FALSE; + pAcStatus->wmmAcAccessFailed = VOS_FALSE; + pAcStatus->wmmAcAccessGranted = VOS_FALSE; + pAcStatus->wmmAcAccessAllowed = VOS_FALSE; + pAcStatus->wmmAcTspecValid = VOS_FALSE; + pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE; + } + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_close() - Function which will perform any necessary work to + to clean up the WMM functionality prior to the kernel module unload + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter ) +{ + hdd_wmm_qos_context_t* pQosContext; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + // free any context records that we still have linked + while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList)) + { + pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList, + hdd_wmm_qos_context_t, node); +#ifdef FEATURE_WLAN_ESE + hdd_wmm_disable_inactivity_timer(pQosContext); +#endif + if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT + && pQosContext->magic == HDD_WMM_CTX_MAGIC) + vos_flush_work(&pQosContext->wmmAcSetupImplicitQos); + + hdd_wmm_free_context(pQosContext); + } + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief is_dhcp_packet() - Function which will check OS packet for + DHCP packet + + @param skb : [in] pointer to OS packet (sk_buff) + @return : VOS_TRUE if the OS packet is DHCP packet + : otherwise VOS_FALSE + ===========================================================================*/ +v_BOOL_t is_dhcp_packet(struct sk_buff *skb) +{ + if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT || + *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT) + return VOS_TRUE; + + return VOS_FALSE; +} + +/**============================================================================ + @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet + into a WMM AC based on either 802.1Q or DSCP + + @param pAdapter : [in] pointer to adapter context + @param skb : [in] pointer to OS packet (sk_buff) + @param pAcType : [out] pointer to WMM AC type of OS packet + + @return : None + ===========================================================================*/ +v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter, + struct sk_buff *skb, + WLANTL_ACEnumType* pAcType, + sme_QosWmmUpType *pUserPri) +{ + unsigned char * pPkt; + union generic_ethhdr *pHdr; + struct iphdr *pIpHdr; + unsigned char tos; + unsigned char dscp; + sme_QosWmmUpType userPri; + WLANTL_ACEnumType acType; + + // this code is executed for every packet therefore + // all debug code is kept conditional + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); +#endif // HDD_WMM_DEBUG + + pPkt = skb->data; + pHdr = (union generic_ethhdr *)pPkt; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: proto/length is 0x%04x", + __func__, pHdr->eth_II.h_proto); +#endif // HDD_WMM_DEBUG + + if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis) + { + if (pHdr->eth_II.h_proto == htons(ETH_P_IP)) + { + // case 1: Ethernet II IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Ethernet II IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + + } + else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) && + (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) && + (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) && + (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) && + (pHdr->eth_8023.h_proto == htons(ETH_P_IP))) + { + // case 2: 802.3 LLC/SNAP IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: 802.3 LLC/SNAP IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q)) + { + // VLAN tagged + + if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP)) + { + // case 3: Ethernet II vlan-tagged IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Ethernet II VLAN tagged IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) && + (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) && + (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) && + (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) && + (pHdr->eth_8023v.h_proto == htons(ETH_P_IP))) + { + // case 4: 802.3 LLC/SNAP vlan-tagged IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else + { + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: VLAN tagged Unhandled Protocol, using default tos", + __func__); +#endif // HDD_WMM_DEBUG + tos = 0; + } + } + else + { + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: Unhandled Protocol, using default tos", + __func__); +#endif // HDD_WMM_DEBUG + //Give the highest priority to 802.1x packet + if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X)) + tos = 0xC0; + else + tos = 0; + } + + dscp = (tos>>2) & 0x3f; + userPri = pAdapter->hddWmmDscpToUpMap[dscp]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: tos is %d, dscp is %d, up is %d", + __func__, tos, dscp, userPri); +#endif // HDD_WMM_DEBUG + + } + else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis) + { + if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q)) + { + // VLAN tagged + userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Tagged frame, UP is %d", + __func__, userPri); +#endif // HDD_WMM_DEBUG + } + else + { + // not VLAN tagged, use default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: Untagged frame, using default UP", + __func__); +#endif // HDD_WMM_DEBUG + //Give the highest priority to 802.1x packet + if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X)) + userPri = SME_QOS_WMM_UP_VO; + else + userPri = SME_QOS_WMM_UP_BE; + } + } + else + { + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unknown classification scheme, using default UP", + __func__); +#endif // HDD_WMM_DEBUG + userPri = SME_QOS_WMM_UP_BE; + } + + acType = hddWmmUpToAcMap[userPri]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: UP is %d, AC is %d", + __func__, userPri, acType); +#endif // HDD_WMM_DEBUG + + *pUserPri = userPri; + *pAcType = acType; + + return; +} + +/**============================================================================ + @brief hdd_hostapd_select_quueue() - Function which will classify the packet + according to Linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ +v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb) +{ + WLANTL_ACEnumType ac; + sme_QosWmmUpType up = SME_QOS_WMM_UP_BE; + v_USHORT_t queueIndex; + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_U8_t STAId; + v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1); + + /*Get the Station ID*/ + if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO, + "%s: Failed to find right station", __func__); + *pSTAId = HDD_WLAN_INVALID_STA_ID; + goto done; + } + + spin_lock_bh( &pAdapter->staInfo_lock ); + if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO, + "%s: Station MAC address does not matching", __func__); + + *pSTAId = HDD_WLAN_INVALID_STA_ID; + goto release_lock; + } + if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode)) + { + /* Get the user priority from IP header & corresponding AC */ + hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up); + //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue + if (pAdapter->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Making priority of DHCP packet as VOICE", __func__); + up = SME_QOS_WMM_UP_VO; + ac = hddWmmUpToAcMap[up]; + } + } + *pSTAId = STAId; + +release_lock: + spin_unlock_bh( &pAdapter->staInfo_lock ); +done: + skb->priority = up; + queueIndex = hddLinuxUpToAcMap[skb->priority]; + + return queueIndex; +} + +/**============================================================================ + @brief hdd_wmm_select_quueue() - Function which will classify the packet + according to Linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ +v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb) +{ + WLANTL_ACEnumType ac; + sme_QosWmmUpType up = SME_QOS_WMM_UP_BE; + v_USHORT_t queueIndex; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + if (isWDresetInProgress()) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("called during WDReset")); + skb->priority = SME_QOS_WMM_UP_BE; + return HDD_LINUX_AC_BE; + } + + /*Get the Station ID*/ + if (WLAN_HDD_IBSS == pAdapter->device_mode) + { + v_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1); + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + + if ( VOS_STATUS_SUCCESS != + hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station, + pDestMacAddress, pSTAId)) + { + *pSTAId = HDD_WLAN_INVALID_STA_ID; + if (!vos_is_macaddr_broadcast(pDestMacAddress) && + !vos_is_macaddr_group(pDestMacAddress)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to find right station pDestMacAddress: " + MAC_ADDRESS_STR , __func__, + MAC_ADDR_ARRAY(pDestMacAddress->bytes)); + goto done; + } + } + } + /* + * If we don't want QoS or the AP doesn't support Qos + * All traffic will get equal opportunity to transmit data frames. + */ + if( hdd_wmm_is_active(pAdapter) ) { + /* Get the user priority from IP header & corresponding AC */ + hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up); + //If 3/4th of BE AC Tx queue is full, then place the DHCP packet in VOICE AC queue + if (pAdapter->isVosLowResource && is_dhcp_packet(skb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: BestEffort Tx Queue is 3/4th full" + " Make DHCP packet's pri as VO", __func__); + up = SME_QOS_WMM_UP_VO; + ac = hddWmmUpToAcMap[up]; + } + } +done: + skb->priority = up; + queueIndex = hddLinuxUpToAcMap[skb->priority]; + + return queueIndex; +} + +/**========================================================================== + @brief hdd_wmm_acquire_access_required() - Function which will determine + acquire admittance for a WMM AC is required or not based on psb configuration + done in framework + + @param pAdapter : [in] pointer to adapter structure + + @param acType : [in] WMM AC type of OS packet + + @return : void + ===========================================================================*/ +void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter, + WLANTL_ACEnumType acType) +{ +/* Each bit in the LSB nibble indicates 1 AC. + * Clearing the particular bit in LSB nibble to indicate + * access required + */ + switch(acType) + { + case WLANTL_AC_BK: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */ + break; + case WLANTL_AC_BE: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */ + break; + case WLANTL_AC_VI: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */ + break; + case WLANTL_AC_VO: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */ + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC Type", __func__); + break; + } +} + +/**============================================================================ + @brief hdd_wmm_acquire_access() - Function which will attempt to acquire + admittance for a WMM AC + + @param pAdapter : [in] pointer to adapter context + @param acType : [in] WMM AC type of OS packet + @param pGranted : [out] pointer to boolean flag when indicates if access + has been granted or not + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter, + WLANTL_ACEnumType acType, + v_BOOL_t * pGranted ) +{ + hdd_wmm_qos_context_t *pQosContext; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered for AC %d", __func__, acType); + + if (!hdd_wmm_is_active(pAdapter) || + !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled || + !pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessRequired) + { + // either we don't want QoS or the AP doesn't support QoS + // or we don't want to do implicit QoS + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: QoS not configured on both ends ", __func__); + + *pGranted = pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed; + + return VOS_STATUS_SUCCESS; + } + + // do we already have an implicit QoS request pending for this AC? + if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) || + (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending)) + { + // request already pending so we need to wait for that response + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Implicit QoS for TL AC %d already scheduled", + __func__, acType); + + *pGranted = VOS_FALSE; + return VOS_STATUS_SUCCESS; + } + + // did we already fail to establish implicit QoS for this AC? + // (if so, access should have been granted when the failure was handled) + if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed) + { + // request previously failed + // allow access, but we'll be downgraded + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Implicit QoS for TL AC %d previously failed", + __func__, acType); + + if (!pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessRequired) + { + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE; + *pGranted = VOS_TRUE; + } + else + { + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_FALSE; + *pGranted = VOS_FALSE; + } + + return VOS_STATUS_SUCCESS; + } + + // we need to establish implicit QoS + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p", + __func__, acType, pAdapter); + + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE; + + pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC); + if (NULL == pQosContext) + { + // no memory for QoS context. Nothing we can do but let data flow + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unable to allocate context", __func__); + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE; + *pGranted = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + + pQosContext->acType = acType; + pQosContext->pAdapter = pAdapter; + pQosContext->qosFlowId = 0; + pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT; + pQosContext->magic = HDD_WMM_CTX_MAGIC; + +#ifdef CONFIG_CNSS + cnss_init_work(&pQosContext->wmmAcSetupImplicitQos, + hdd_wmm_do_implicit_qos); +#else + INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, + hdd_wmm_do_implicit_qos); +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Scheduling work for AC %d, context %p", + __func__, acType, pQosContext); + + schedule_work(&pQosContext->wmmAcSetupImplicitQos); + + // caller will need to wait until the work takes place and + // TSPEC negotiation completes + *pGranted = VOS_FALSE; + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_assoc() - Function which will handle the housekeeping + required by WMM when association takes place + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ) +{ + tANI_U8 uapsdMask; + VOS_STATUS status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + // when we associate we need to notify TL if it needs to enable + // UAPSD for any access categories + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + if (pRoamInfo->fReassocReq) + { + // when we reassociate we should continue to use whatever + // parameters were previously established. if we are + // reassociating due to a U-APSD change for a particular + // Access Category, then the change will be communicated + // to HDD via the QoS callback associated with the given + // flow, and U-APSD parameters will be updated there + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Reassoc so no work, Exiting", __func__); + + return VOS_STATUS_SUCCESS; + } + + // get the negotiated UAPSD Mask + uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask); + + if (uapsdMask & HDD_AC_VO) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_VO, + 7, + 7, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv, + WLANTL_BI_DIR, + 1, + pAdapter->sessionId); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_VI) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_VI, + 5, + 5, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv, + WLANTL_BI_DIR, + 1, + pAdapter->sessionId); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_BK) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_BK, + 2, + 2, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv, + WLANTL_BI_DIR, + 1, + pAdapter->sessionId); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_BE) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_BE, + 3, + 3, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv, + WLANTL_BI_DIR, + 1, + pAdapter->sessionId); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); + + if (!VOS_IS_STATUS_SUCCESS( status )) + { + hdd_wmm_init( pAdapter ); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Exiting", __func__); + + return VOS_STATUS_SUCCESS; +} + + + +static const v_U8_t acmMaskBit[WLANTL_MAX_AC] = + { + 0x4, /* WLANTL_AC_BK */ + 0x8, /* WLANTL_AC_BE */ + 0x2, /* WLANTL_AC_VI */ + 0x1 /* WLANTL_AC_VO */ + }; + +/**============================================================================ + @brief hdd_wmm_connect() - Function which will handle the housekeeping + required by WMM when a connection is established + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ) +{ + int ac; + v_BOOL_t qap; + v_BOOL_t qosConnection; + v_U8_t acmMask; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) && + pRoamInfo && + pRoamInfo->u.pConnectedProfile) { + qap = pRoamInfo->u.pConnectedProfile->qap; + qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection; + acmMask = pRoamInfo->u.pConnectedProfile->acm_mask; + } else { + /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection + false. */ + qap = VOS_TRUE; + qosConnection = VOS_TRUE; + acmMask = 0x0; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: qap is %d, qosConnection is %d, acmMask is 0x%x", + __func__, qap, qosConnection, acmMask); + + pAdapter->hddWmmStatus.wmmQap = qap; + pAdapter->hddWmmStatus.wmmQosConnection = qosConnection; + + for (ac = 0; ac < WLANTL_MAX_AC; ac++) + { + if (qap && + qosConnection && + (acmMask & acmMaskBit[ac])) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: ac %d on", + __func__, ac); + + // admission is required + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE; + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE; + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE; + //after reassoc if we have valid tspec, allow access + if (pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid && + (pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecInfo.ts_info.direction != + SME_QOS_WMM_TS_DIR_DOWNLINK)) { + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: ac %d off", + __func__, ac); + // admission is not required so access is allowed + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE; + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE; + } + + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Exiting", __func__); + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the + initial value of the UAPSD mask based upon the device configuration + + @param pAdapter : [in] pointer to adapter context + @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter, + tANI_U8 *pUapsdMask ) +{ + tANI_U8 uapsdMask; + + if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode) + { + // no QOS then no UAPSD + uapsdMask = 0; + } + else + { + // start with the default mask + uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask; + + // disable UAPSD for any ACs with a 0 Service Interval + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_VO; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_VI; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_BK; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_BE; + } + } + + // return calculated mask + *pUapsdMask = uapsdMask; + return VOS_STATUS_SUCCESS; +} + + +/**============================================================================ + @brief hdd_wmm_is_active() - Function which will determine if WMM is + active on the current connection + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_TRUE if WMM is enabled + : VOS_FALSE if WMM is not enabled + ===========================================================================*/ +v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter ) +{ + if ((!pAdapter->hddWmmStatus.wmmQosConnection) || + (!pAdapter->hddWmmStatus.wmmQap)) + { + return VOS_FALSE; + } + else + { + return VOS_TRUE; + } +} + +/**============================================================================ + @brief hdd_wmm_addts() - Function which will add a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + @param pTspec : [in] pointer to the traffic spec + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter, + v_U32_t handle, + sme_QosWmmTspecInfo* pTspec ) +{ + hdd_wmm_qos_context_t *pQosContext; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosStatusType smeStatus; +#endif + v_BOOL_t found = VOS_FALSE; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // see if a context already exists with the given handle + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + found = VOS_TRUE; + break; + } + } + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + if (found) + { + // record with that handle already exists + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Record already exists with handle 0x%x", + __func__, handle); + + /* Application is trying to modify some of the Tspec params. Allow it */ + smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pTspec, + pQosContext->qosFlowId); + + // need to check the return value and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING; + break; + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD; + break; + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY: + status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING; + break; + case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM; + break; + case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + break; + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + break; + default: + // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + return HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + } + + // we were successful, save the status + pQosContext->lastStatus = status; + return status; + } + + pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL); + if (NULL == pQosContext) + { + // no memory for QoS context. Nothing we can do + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unable to allocate QoS context", __func__); + return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE; + } + + // we assume the tspec has already been validated by the caller + + pQosContext->handle = handle; + if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE) + pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up]; + else { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: ts_info.up (%d) larger than max value (%d), use default acType (%d)", + __func__, pTspec->ts_info.up, + HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]); + pQosContext->acType = hddWmmUpToAcMap[0]; + } + pQosContext->pAdapter = pAdapter; + pQosContext->qosFlowId = 0; + pQosContext->magic = HDD_WMM_CTX_MAGIC; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setting up QoS, context %p", + __func__, pQosContext); + + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList); + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + pTspec, + hdd_wmm_sme_callback, + pQosContext, + pTspec->ts_info.up, + &pQosContext->qosFlowId); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: sme_QosSetupReq returned %d flowid %d", + __func__, smeStatus, pQosContext->qosFlowId); + + // need to check the return value and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_PENDING; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + status = HDD_WLAN_WMM_STATUS_SETUP_PENDING; + break; + case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP: + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + /* + * We can't tell the difference between when a request fails because + * AP rejected it versus when SME encountered an internal error + */ + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + default: + // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes + hdd_wmm_free_context(pQosContext); + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + } +#endif + + // we were successful, save the status + pQosContext->lastStatus = status; + + return status; +} + +/**============================================================================ + @brief hdd_wmm_delts() - Function which will delete a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter, + v_U32_t handle ) +{ + hdd_wmm_qos_context_t *pQosContext; + v_BOOL_t found = VOS_FALSE; + WLANTL_ACEnumType acType = 0; + v_U32_t qosFlowId = 0; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosStatusType smeStatus; +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // locate the context with the given handle + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + found = VOS_TRUE; + acType = pQosContext->acType; + qosFlowId = pQosContext->qosFlowId; + break; + } + } + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + + if (VOS_FALSE == found) + { + // we didn't find the handle + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: handle 0x%x not found", __func__, handle); + return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + } + + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: found handle 0x%x, flow %d, AC %d, context %p", + __func__, handle, qosFlowId, acType, pQosContext); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId ); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: SME flow %d released, SME status %d", + __func__, qosFlowId, smeStatus); + + switch(smeStatus) + { + case SME_QOS_STATUS_RELEASE_SUCCESS_RSP: + // this flow is the only one on that AC, so go ahead and update + // our TSPEC state for the AC + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE; + + // need to tell TL to stop trigger timer, etc + hdd_wmm_disable_tl_uapsd(pQosContext); + +#ifdef FEATURE_WLAN_ESE + // disable the inactivity timer + hdd_wmm_disable_inactivity_timer(pQosContext); +#endif + // we are done with this context + hdd_wmm_free_context(pQosContext); + + // SME must not fire any more callbacks for this flow since the context + // is no longer valid + + return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS; + + case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP: + // do nothing as we will get a response from SME + status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING; + break; + + case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP: + // nothing we can do with the existing flow except leave it + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + break; + + case SME_QOS_STATUS_RELEASE_FAILURE_RSP: + // nothing we can do with the existing flow except leave it + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + + default: + // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + } + +#endif + pQosContext->lastStatus = status; + return status; +} + +/**============================================================================ + @brief hdd_wmm_checkts() - Function which will return the status of a traffic + spec at the request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter, + v_U32_t handle ) +{ + hdd_wmm_qos_context_t *pQosContext; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // locate the context with the given handle + mutex_lock(&pAdapter->hddWmmStatus.wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: found handle 0x%x, context %p", + __func__, handle, pQosContext); + + status = pQosContext->lastStatus; + break; + } + } + mutex_unlock(&pAdapter->hddWmmStatus.wmmLock); + return status; +} diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wowl.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wowl.c new file mode 100644 index 0000000000000..0b33988b00b04 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wowl.c @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + * @file wlan_hdd_wowl.c + * + * + * ==========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WOWL_INTER_PTRN_TOKENIZER ';' +#define WOWL_INTRA_PTRN_TOKENIZER ':' + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED]; //Patterns 0-15 +static v_BOOL_t g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = {0}; +static v_U8_t g_hdd_wowl_ptrns_count = 0; + +int hdd_parse_hex(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c-'0'; + if (c >= 'a' && c <= 'f') + return c-'a'+10; + if (c >= 'A' && c <= 'F') + return c-'A'+10; + + return 0; +} + +static inline int find_ptrn_len(const char* ptrn) +{ + int len = 0; + while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER) + { + len++; ptrn++; + } + return len; +} + +static void hdd_wowl_callback( void *pContext, eHalStatus halStatus ) +{ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Return code = (%d)", __func__, halStatus ); +} + +#ifdef WLAN_WAKEUP_EVENTS +static void hdd_wowl_wakeIndication_callback( void *pContext, + tpSirWakeReasonInd pWakeReasonInd ) +{ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Wake Reason %d", + __func__, pWakeReasonInd->ulReason ); + hdd_exit_wowl((hdd_adapter_t *)pContext); +} +#endif + +static void dump_hdd_wowl_ptrn(tSirWowlAddBcastPtrn *ptrn) +{ + int i; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatetrnId = 0x%x", __func__, + ptrn->ucPatternId); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternByteOffset = 0x%x", __func__, + ptrn->ucPatternByteOffset); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternSize = 0x%x", __func__, + ptrn->ucPatternSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternMaskSize = 0x%x", __func__, + ptrn->ucPatternMaskSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Pattern: ", __func__); + for(i = 0; i < ptrn->ucPatternSize; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", ptrn->ucPattern[i]); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: PatternMask: ", __func__); + for(i = 0; iucPatternMaskSize; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%02X", ptrn->ucPatternMask[i]); +} + + +/**============================================================================ + @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be + used when PBM filtering is enabled + + @param ptrn : [in] pointer to the pattern string to be added + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn) +{ + tSirWowlAddBcastPtrn localPattern; + int i, first_empty_slot, len, offset; + eHalStatus halStatus; + const char *temp; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U8_t sessionId = pAdapter->sessionId; + hdd_context_t *pHddCtx = pAdapter->pHddCtx; + + len = find_ptrn_len(ptrn); + + /* There has to have atleast 1 byte for each field (pattern size, mask size, + * pattern, mask) e.g. PP:QQ:RR:SS ==> 11 chars */ + while ( len >= 11 ) + { + // Detect duplicate pattern + for (i=0; icfg_ini->maxWoWFilters; i++) + { + if(g_hdd_wowl_ptrns[i] == NULL) continue; + + if(!memcmp(ptrn, g_hdd_wowl_ptrns[i], len)) + { + // Pattern Already configured, skip to next pattern + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Trying to add duplicate WoWL pattern. Skip it!"); + ptrn += len; + goto next_ptrn; + } + } + + first_empty_slot = -1; + + // Find an empty slot to store the pattern + for (i=0; icfg_ini->maxWoWFilters; i++) + { + if(g_hdd_wowl_ptrns[i] == NULL) { + first_empty_slot = i; + break; + } + } + + // Maximum number of patterns have been configured already + if(first_empty_slot == -1) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot add anymore patterns. No free slot!", __func__); + return VOS_FALSE; + } + + //Validate the pattern + if(ptrn[2] != WOWL_INTRA_PTRN_TOKENIZER || + ptrn[5] != WOWL_INTRA_PTRN_TOKENIZER) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern string. Skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + // Extract the pattern size + localPattern.ucPatternSize = + ( hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] ); + + // Extract the pattern mask size + localPattern.ucPatternMaskSize = + ( hdd_parse_hex( ptrn[3] ) * 0x10 ) + hdd_parse_hex( ptrn[4] ); + + if(localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE || + localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid length specified. Skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + //compute the offset of tokenizer after the pattern + offset = 5 + 2*localPattern.ucPatternSize + 1; + if(offset >= len || ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern string..skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + /* Compute the end of pattern string */ + offset = offset + 2*localPattern.ucPatternMaskSize; + if(offset+1 != len) //offset begins with 0 + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern string...skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + temp = ptrn; + + // Now advance to where pattern begins + ptrn += 6; + + // Extract the pattern + for(i=0; i < localPattern.ucPatternSize; i++) + { + localPattern.ucPattern[i] = + (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] ); + ptrn += 2; //skip to next byte + } + + ptrn++; /* Skip over the ':' separator after the pattern */ + + // Extract the pattern Mask + for(i=0; i < localPattern.ucPatternMaskSize; i++) + { + localPattern.ucPatternMask[i] = + (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] ); + ptrn += 2; //skip to next byte + } + + //All is good. Store the pattern locally + g_hdd_wowl_ptrns[first_empty_slot] = (char*) kmalloc(len+1, GFP_KERNEL); + if(g_hdd_wowl_ptrns[first_empty_slot] == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kmalloc failure", __func__); + return VOS_FALSE; + } + + memcpy(g_hdd_wowl_ptrns[first_empty_slot], temp, len); + g_hdd_wowl_ptrns[first_empty_slot][len] = '\0'; + localPattern.ucPatternId = first_empty_slot; + localPattern.ucPatternByteOffset = 0; + localPattern.sessionId = sessionId; + + // Register the pattern downstream + halStatus = sme_WowlAddBcastPattern( hHal, &localPattern, sessionId ); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + // Add failed, so invalidate the local storage + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_WowlAddBcastPattern failed with error code (%d)", halStatus ); + kfree(g_hdd_wowl_ptrns[first_empty_slot]); + g_hdd_wowl_ptrns[first_empty_slot] = NULL; + } + + dump_hdd_wowl_ptrn(&localPattern); + + next_ptrn: + if (*ptrn == WOWL_INTER_PTRN_TOKENIZER) + { + ptrn += 1; // move past the tokenizer + len = find_ptrn_len(ptrn); + continue; + } + else + break; + } + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern + + @param ptrn : [in] pointer to the pattern string to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn) +{ + tSirWowlDelBcastPtrn delPattern; + unsigned char id; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_BOOL_t patternFound = VOS_FALSE; + eHalStatus halStatus; + v_U8_t sessionId = pAdapter->sessionId; + hdd_context_t *pHddCtx = pAdapter->pHddCtx; + + // Detect pattern + for (id=0; idcfg_ini->maxWoWFilters && g_hdd_wowl_ptrns[id] != NULL; id++) + { + if(!strcmp(ptrn, g_hdd_wowl_ptrns[id])) + { + patternFound = VOS_TRUE; + break; + } + } + + // If pattern present, remove it from downstream + if(patternFound) + { + delPattern.ucPatternId = id; + halStatus = sme_WowlDelBcastPattern( hHal, &delPattern, sessionId ); + if ( HAL_STATUS_SUCCESS( halStatus ) ) + { + // Remove from local storage as well + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Deleted pattern with id %d [%s]", id, g_hdd_wowl_ptrns[id]); + + kfree(g_hdd_wowl_ptrns[id]); + g_hdd_wowl_ptrns[id] = NULL; + return VOS_TRUE; + } + } + return VOS_FALSE; +} + +/**============================================================================ + @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be added + pattern_offset : [in] offset of the pattern in the frame payload + pattern_buf : [in] pointer to the pattern hex string to be added + pattern_mask : [in] pointer to the pattern mask hex string + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx, + v_U8_t pattern_offset, char *pattern_buf, + char *pattern_mask) +{ + tSirWowlAddBcastPtrn localPattern; + eHalStatus halStatus; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U8_t sessionId = pAdapter->sessionId; + v_U16_t pattern_len, mask_len, i; + + if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern index %d is out of range (0 ~ %d).", + __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1); + + return VOS_FALSE; + } + + pattern_len = strlen(pattern_buf); + + /* Since the pattern is a hex string, 2 characters represent 1 byte. */ + if (pattern_len % 2) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed WoW pattern!", __func__); + + return VOS_FALSE; + } + else + pattern_len >>= 1; + + if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern length %d is out of range (1 ~ %d).", + __func__, pattern_len, WOWL_PTRN_MAX_SIZE); + + return VOS_FALSE; + } + + localPattern.ucPatternId = pattern_idx; + localPattern.ucPatternByteOffset = pattern_offset; + localPattern.ucPatternSize = pattern_len; + localPattern.sessionId = sessionId; + + if (localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern size (%d) greater than max (%d)", + __func__, localPattern.ucPatternSize, + SIR_WOWL_BCAST_PATTERN_MAX_SIZE); + return VOS_FALSE; + } + /* Extract the pattern */ + for (i = 0; i < localPattern.ucPatternSize; i++) + { + localPattern.ucPattern[i] = + (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); + + /* Skip to next byte */ + pattern_buf += 2; + } + + /* Get pattern mask size by pattern length */ + localPattern.ucPatternMaskSize = pattern_len >> 3; + if (pattern_len % 8) + localPattern.ucPatternMaskSize += 1; + + mask_len = strlen(pattern_mask); + if ((mask_len % 2) || (localPattern.ucPatternMaskSize != (mask_len >> 1))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed WoW pattern mask!", __func__); + + return VOS_FALSE; + } + if (localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern mask size (%d) greater than max (%d)", + __func__, localPattern.ucPatternMaskSize, WOWL_PTRN_MASK_MAX_SIZE); + return VOS_FALSE; + } + /* Extract the pattern mask */ + for (i = 0; i < localPattern.ucPatternMaskSize; i++) + { + localPattern.ucPatternMask[i] = + (hdd_parse_hex(pattern_mask[0]) << 4) + hdd_parse_hex(pattern_mask[1]); + + /* Skip to next byte */ + pattern_mask += 2; + } + + /* Register the pattern downstream */ + halStatus = sme_WowlAddBcastPattern(hHal, &localPattern, sessionId); + + if (!HAL_STATUS_SUCCESS(halStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_WowlAddBcastPattern failed with error code (%d).", + __func__, halStatus); + + return VOS_FALSE; + } + + /* All is good. */ + if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) + { + g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1; + g_hdd_wowl_ptrns_count++; + } + + dump_hdd_wowl_ptrn(&localPattern); + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx) +{ + tSirWowlDelBcastPtrn delPattern; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus halStatus; + v_U8_t sessionId = pAdapter->sessionId; + + if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern index %d is not in the range (0 ~ %d).", + __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1); + + return VOS_FALSE; + } + + if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern %d is not in the table.", + __func__, pattern_idx); + + return VOS_FALSE; + } + + delPattern.ucPatternId = pattern_idx; + halStatus = sme_WowlDelBcastPattern(hHal, &delPattern, sessionId); + + if (!HAL_STATUS_SUCCESS(halStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_WowlDelBcastPattern failed with error code (%d).", + __func__, halStatus); + + return VOS_FALSE; + } + + g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0; + g_hdd_wowl_ptrns_count--; + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one + of MP and PBM must be enabled + + @param enable_mp : [in] Whether to enable magic packet WoWL mode + @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_enter_wowl (hdd_adapter_t *pAdapter, v_BOOL_t enable_mp, v_BOOL_t enable_pbm) +{ + tSirSmeWowlEnterParams wowParams; + eHalStatus halStatus; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + vos_mem_zero( &wowParams, sizeof( tSirSmeWowlEnterParams)); + + wowParams.ucPatternFilteringEnable = enable_pbm; + wowParams.ucMagicPktEnable = enable_mp; + wowParams.sessionId = pAdapter->sessionId; + if(enable_mp) + { + vos_copy_macaddr( (v_MACADDR_t *)&(wowParams.magicPtrn), + &(pAdapter->macAddressCurrent) ); + } + +#ifdef WLAN_WAKEUP_EVENTS + wowParams.ucWoWEAPIDRequestEnable = VOS_TRUE; + wowParams.ucWoWEAPOL4WayEnable = VOS_TRUE; + wowParams.ucWowNetScanOffloadMatch = VOS_TRUE; + wowParams.ucWowGTKRekeyError = VOS_TRUE; + wowParams.ucWoWBSSConnLoss = VOS_TRUE; +#endif // WLAN_WAKEUP_EVENTS + + + // Request to put Libra into WoWL + halStatus = sme_EnterWowl( hHal, hdd_wowl_callback, + pAdapter, +#ifdef WLAN_WAKEUP_EVENTS + hdd_wowl_wakeIndication_callback, + pAdapter, +#endif // WLAN_WAKEUP_EVENTS + &wowParams, pAdapter->sessionId); + + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + if ( eHAL_STATUS_PMC_PENDING != halStatus ) + { + // We failed to enter WoWL + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_EnterWowl failed with error code (%d)", halStatus ); + return VOS_FALSE; + } + } + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_exit_wowl() - Function which will disable WoWL + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter) +{ + tSirSmeWowlExitParams wowParams; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus halStatus; + + wowParams.sessionId = pAdapter->sessionId; + + halStatus = sme_ExitWowl( hHal, &wowParams); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_ExitWowl failed with error code (%d)", halStatus ); + return VOS_FALSE; + } + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_init_wowl() - Init function which will initialize the WoWL module + and perform any required initial configuration + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_init_wowl (hdd_adapter_t*pAdapter) +{ + hdd_context_t *pHddCtx = NULL; + pHddCtx = pAdapter->pHddCtx; + + memset(g_hdd_wowl_ptrns, 0, sizeof(g_hdd_wowl_ptrns)); + + //Add any statically configured patterns + hdd_add_wowl_ptrn(pAdapter, pHddCtx->cfg_ini->wowlPattern); + + return VOS_TRUE; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniCompiler.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniCompiler.h new file mode 100644 index 0000000000000..81934142fac46 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniCompiler.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Compiler abstraction layer + * + * + * + * This file tries to abstract the differences among compilers. + * Supported compilers are : + * + * - GNU C/C++ compiler + * - Microsoft C/C++ compiler + * - Intel C/C++ compiler + * + * Written by Ho Lee + */ + +#ifndef __ANI_COMPILER_ABSTRACT_H +#define __ANI_COMPILER_ABSTRACT_H + +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + * 3. Intel C/C++ Compiler + * + * How to detect icc : __INTEL_COMPILER, __ICC (legacy), __ECC (legacy) + * How to detect icc version : + * __INTEL_COMPILER, __ICC, __ECC (700 = 7.0, 900 = 9.0, ...) + * + * 4. Other compilers (not supported) + * + * Borland : __BORLANDC__ + * Greenhills : __ghs + * Metrowerks : __MWERKS__ + * SGI MIPSpro : __sgi + */ + +/* + * Packing directives : These are used to force compiler to pack bits and + * bytes in the data structure. C standard does not regulate this strictly, + * and many things are to compiler implementation. Many compilers support + * compiler specific directives or options that allow different packing + * and alignment. + * + * Alignment directives : Compiler may think packed data structures have + * no specific alignment requirement. Then compiler may generate multiple + * byte accesses to access two byte or four bytes data structures. This + * affects on performance especially for RISC systems. If some data + * structure is located on specific alignment always, alignment directives + * help compiler generate more efficient codes. + */ + +#undef __ANI_COMPILER_PRAGMA_PACK_STACK +#undef __ANI_COMPILER_PRAGMA_PACK + +#if defined(_MSC_VER) +#define __ANI_COMPILER_PRAGMA_PACK_STACK 1 +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#elif defined(__GNUC__) +#define __ani_attr_pre_packed +#define __ani_attr_packed __packed +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#elif defined(ANI_COMPILER_TYPE_RVCT) +/* Nothing defined so far */ +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __align(2) +#define __ani_attr_aligned_4 __align(4) +#define __ani_attr_aligned_8 __align(8) +#define __ani_attr_aligned_16 __align(16) +#define __ani_attr_aligned_32 __align(32) +#else +#error "Unknown compiler" +#endif + +#if defined(ANI_DATAPATH_SECTION) +#define __DP_SRC_RX __attribute__((section(".dpsrcrx"))) +#define __DP_SRC_TX __attribute__((section(".dpsrctx"))) +#define __DP_SRC __attribute__((section(".dpsrc"))) +#define __ANIHDD_MODULE __attribute__((section(".anihdd"))) +#else +#define __DP_SRC_RX +#define __DP_SRC_TX +#define __DP_SRC +#define __ANIHDD_MODULE +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniGlobal.h new file mode 100644 index 0000000000000..8a17cfac85649 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniGlobal.h @@ -0,0 +1,1108 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * aniGlobal.h: MAC Modules Adapter Definitions. + * Author: V. K. Kandarpa + * Date: 10/25/2002 + * + * History:- + * Date: 04/08/2008 Modified by: Santosh Mandiganal + * Modification Information: Added the logDump.h header file and defined the + * dumpTablecurrentId, dumpTableEntry. + * -------------------------------------------------------------------------- + * + */ + +#ifndef _ANIGLOBAL_H +#define _ANIGLOBAL_H + +// Take care to avoid redefinition of this type, if it is +// already defined in "halWmmApi.h" +#if !defined(_HALMAC_WMM_API_H) +typedef struct sAniSirGlobal *tpAniSirGlobal; +#endif + +#include "halTypes.h" +#include "sirCommon.h" +#include "aniSystemDefs.h" +#include "sysDef.h" +#include "dphGlobal.h" +#include "limGlobal.h" +#include "pmmGlobal.h" +#include "schGlobal.h" +#include "sysGlobal.h" +#include "cfgGlobal.h" +#include "utilsGlobal.h" +#include "sirApi.h" + + +#include "wlan_qct_hal.h" + +#include "pmc.h" + +#include "csrApi.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "sme_FTApi.h" +#endif +#include "csrSupport.h" +#include "smeInternal.h" +#include "sapApi.h" +#include "ccmApi.h" +#include "btcApi.h" +#include "csrInternal.h" + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataInternal.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#include "rrmGlobal.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#include "eseGlobal.h" +#endif +#include "p2p_Api.h" + +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif + +#ifdef ANI_DVT_DEBUG +#include "dvtModule.h" +#endif + +// New HAL API interface defs. +#include "logDump.h" + +//Check if this definition can actually move here from halInternal.h even for Volans. In that case +//this featurization can be removed. +#define PMAC_STRUCT( _hHal ) ( (tpAniSirGlobal)_hHal ) + +#define ANI_DRIVER_TYPE(pMac) (((tpAniSirGlobal)(pMac))->gDriverType) + +#define IS_MIRACAST_SESSION_PRESENT(pMac) (((tpAniSirGlobal)(pMac))->fMiracastSessionPresent ? 1 : 0) +// ------------------------------------------------------------------- +// Bss Qos Caps bit map definition +#define LIM_BSS_CAPS_OFFSET_HCF 0 +#define LIM_BSS_CAPS_OFFSET_WME 1 +#define LIM_BSS_CAPS_OFFSET_WSM 2 + +#define LIM_BSS_CAPS_HCF (1 << LIM_BSS_CAPS_OFFSET_HCF) +#define LIM_BSS_CAPS_WME (1 << LIM_BSS_CAPS_OFFSET_WME) +#define LIM_BSS_CAPS_WSM (1 << LIM_BSS_CAPS_OFFSET_WSM) + +// cap should be one of HCF/WME/WSM +#define LIM_BSS_CAPS_GET(cap, val) (((val) & (LIM_BSS_CAPS_ ## cap)) >> LIM_BSS_CAPS_OFFSET_ ## cap) +#define LIM_BSS_CAPS_SET(cap, val) ((val) |= (LIM_BSS_CAPS_ ## cap )) +#define LIM_BSS_CAPS_CLR(cap, val) ((val) &= (~ (LIM_BSS_CAPS_ ## cap))) + +// 40 beacons per heart beat interval is the default + 1 to count the rest +#define MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL 41 + +/* max number of legacy bssid we can store during scan on one channel */ +#define MAX_NUM_LEGACY_BSSID_PER_CHANNEL 10 + +#define P2P_WILDCARD_SSID "DIRECT-" //TODO Put it in proper place; +#define P2P_WILDCARD_SSID_LEN 7 + +#ifdef WLAN_FEATURE_CONCURRENT_P2P +#define MAX_NO_OF_P2P_SESSIONS 5 +#endif //WLAN_FEATURE_CONCURRENT_P2P + +#define SPACE_ASCII_VALUE 32 + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define EQUALS_TO_ASCII_VALUE (61) +#endif + +#define WLAN_HOST_SEQ_NUM_MIN 2048 +#define WLAN_HOST_SEQ_NUM_MAX 4095 +#define LOW_SEQ_NUM_MASK 0x000F +#define HIGH_SEQ_NUM_MASK 0x0FF0 +#define HIGH_SEQ_NUM_OFFSET 4 + +// ------------------------------------------------------------------- +// Change channel generic scheme +typedef void (*CHANGE_CHANNEL_CALLBACK)(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); + +/// LIM global definitions +typedef struct sAniSirLimIbss +{ + void *pHdr; + void *pBeacon; +} tAniSirLimIbss; + +typedef struct sDialogueToken +{ + //bytes 0-3 + tANI_U16 assocId; + tANI_U8 token; + tANI_U8 rsvd1; + //Bytes 4-7 + tANI_U16 tid; + tANI_U8 rsvd2[2]; + + struct sDialogueToken* next; +}tDialogueToken, *tpDialogueToken; + +typedef struct sLimTimers +{ + //TIMERS IN LIM ARE NOT SUPPOSED TO BE ZEROED OUT DURING RESET. + //DURING limInitialize DONOT ZERO THEM OUT. + +//STA SPECIFIC TIMERS + // Periodic background scan timer + TX_TIMER gLimBackgroundScanTimer; + + TX_TIMER gLimPreAuthClnupTimer; + + // Association related timers + TX_TIMER gLimAssocFailureTimer; + TX_TIMER gLimReassocFailureTimer; + + + /// Heartbeat timer on STA + TX_TIMER gLimHeartBeatTimer; + + /// Wait for Probe after Heartbeat failure timer on STA + TX_TIMER gLimProbeAfterHBTimer; + + + // Authentication related timers + TX_TIMER gLimAuthFailureTimer; + + // Join Failure timeout on STA + TX_TIMER gLimJoinFailureTimer; + + // Keepalive timer + TX_TIMER gLimKeepaliveTimer; + + // Scan related timers + TX_TIMER gLimMinChannelTimer; + TX_TIMER gLimMaxChannelTimer; + TX_TIMER gLimPeriodicProbeReqTimer; + + // CNF_WAIT timer + TX_TIMER *gpLimCnfWaitTimer; + + // Send Disassociate frame threshold parameters + TX_TIMER gLimSendDisassocFrameThresholdTimer; + + TX_TIMER gLimAddtsRspTimer; // max wait for a response + + // Update OLBC Cache Timer + TX_TIMER gLimUpdateOlbcCacheTimer; + + TX_TIMER gLimChannelSwitchTimer; + // This TIMER is started on the STA, as indicated by the + // AP in its Quiet BSS IE, for the specified interval + TX_TIMER gLimQuietTimer; + // This TIMER is started on the AP, prior to the AP going + // into LEARN mode + // This TIMER is started on the STA, for the specified + // quiet duration + TX_TIMER gLimQuietBssTimer; + +#ifdef WLAN_FEATURE_VOWIFI_11R + TX_TIMER gLimFTPreAuthRspTimer; +#endif + +#ifdef FEATURE_WLAN_ESE + TX_TIMER gLimEseTsmTimer; +#endif + TX_TIMER gLimRemainOnChannelTimer; + + TX_TIMER gLimPeriodicJoinProbeReqTimer; + TX_TIMER gLimDisassocAckTimer; + TX_TIMER gLimDeauthAckTimer; + // This timer is started when single shot NOA insert msg is sent to FW for scan in P2P GO mode + TX_TIMER gLimP2pSingleShotNoaInsertTimer; + /* This timer is used to convert active channel to + * passive channel when there is no beacon + * for a period of time on a particular DFS channel + */ + TX_TIMER gLimActiveToPassiveChannelTimer; + +//********************TIMER SECTION ENDS************************************************** +// ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize +//**************************************************************************************** + +}tLimTimers; + +typedef struct { + void *pMlmDisassocReq; + void *pMlmDeauthReq; +}tLimDisassocDeauthCnfReq; + +typedef struct sAniSirLim +{ + ////////////////////////////////////// TIMER RELATED START /////////////////////////////////////////// + + tLimTimers limTimers; + /// Flag to track if LIM timers are created or not + tANI_U32 gLimTimersCreated; + + + ////////////////////////////////////// TIMER RELATED END /////////////////////////////////////////// + + ////////////////////////////////////// SCAN/LEARN RELATED START /////////////////////////////////////////// + /** + * This flag when set, will use scan mode instead of + * Learn mode on BP/AP. By default this flag is set + * to true until HIF getting stuck in 0x800 state is + * debugged. + */ + tANI_U32 gLimUseScanModeForLearnMode; + + /** + * This is useful for modules other than LIM + * to see if system is in scan/learn mode or not + */ + tANI_U32 gLimSystemInScanLearnMode; + + // Scan related globals on STA + tANI_U8 gLimReturnAfterFirstMatch; + tANI_U8 gLim24Band11dScanDone; + tANI_U8 gLim50Band11dScanDone; + tANI_U8 gLimReturnUniqueResults; + + // Background Scan related globals on STA + tANI_U32 gLimNumOfBackgroundScanSuccess; + tANI_U32 gLimNumOfConsecutiveBkgndScanFailure; + tANI_U32 gLimNumOfForcedBkgndScan; + tANI_U8 gLimBackgroundScanDisable; //based on BG timer + tANI_U8 gLimForceBackgroundScanDisable; //debug control flag + tANI_U8 gLimBackgroundScanTerminate; //controlled by SME + tANI_U8 gLimReportBackgroundScanResults;//controlled by SME + + /// Place holder for current channel ID + /// being scanned + tANI_U32 gLimCurrentScanChannelId; + + // Hold onto SCAN criteria + /* The below is used in P2P GO case when we need to defer processing SME Req + * to LIM and insert NOA first and process SME req once SNOA is started + */ + tANI_U16 gDeferMsgTypeForNOA; + tANI_U32 *gpDefdSmeMsgForNOA; + + tLimMlmScanReq *gpLimMlmScanReq; + + /// This indicates total length of 'matched' scan results + tANI_U16 gLimMlmScanResultLength; + + /// This indicates total length of 'cached' scan results + tANI_U16 gLimSmeScanResultLength; + + /** + * Hash table definition for storing SCAN results + * This is the placed holder for 'cached' scan results + */ + tLimScanResultNode + *gLimCachedScanHashTable[LIM_MAX_NUM_OF_SCAN_RESULTS]; + + /// This indicates total length of 'matched' scan results + tANI_U16 gLimMlmLfrScanResultLength; + + /// This indicates total length of 'cached' scan results + tANI_U16 gLimSmeLfrScanResultLength; + + /** + * Hash table definition for storing LFR SCAN results + * This is the placed holder for roaming candidates as forwarded + * by FW + */ + tLimScanResultNode + *gLimCachedLfrScanHashTable[LIM_MAX_NUM_OF_SCAN_RESULTS]; + + /// Place holder for current channel ID + /// being scanned during background scanning + tANI_U32 gLimBackgroundScanChannelId; + /// flag to indicate that bacground scan timer has been started + tANI_U8 gLimBackgroundScanStarted; + + /* Used to store the list of legacy bss sta detected during scan on one channel */ + tANI_U16 gLimRestoreCBNumScanInterval; + tANI_U16 gLimRestoreCBCount; + tSirMacAddr gLimLegacyBssidList[MAX_NUM_LEGACY_BSSID_PER_CHANNEL]; + + // + // If this flag is 1, + // then, LIM will "try and trigger" a background + // scan whenever it receives a Quiet BSS IE + // + // If this flag is 0, + // then, LIM will simply shut-off Tx/Rx whenever it + // receives a Quiet BSS IE. + // This is the default behavior when a Quiet BSS IE + // is received and 11H is enabled + // + tANI_U32 gLimTriggerBackgroundScanDuringQuietBss; + + + // This variable store the total duration to do scan + tANI_U32 gTotalScanDuration; + tANI_U32 p2pRemOnChanTimeStamp; + + // abort scan is used to abort an on-going scan + tANI_U8 abortScan; + tLimScanChnInfo scanChnInfo; + + ////////////////////////////////////// SCAN/LEARN RELATED START /////////////////////////////////////////// + tSirMacAddr gSelfMacAddr; //added for BT-AMP Support + + ////////////////////////////////////////// BSS RELATED END /////////////////////////////////////////// + // Place holder for StartBssReq message + // received by SME state machine + + tANI_U8 gLimCurrentBssUapsd; + + /* This is used for testing sta legacy bss detect feature */ + tANI_U8 gLimForceNoPropIE; + + // + // Store the BSS Index returned by HAL during + // WDA_ADD_BSS_RSP here. + // + // For now: + // This will be used during WDA_SET_BSSKEY_REQ in + // order to set the GTK + // Later: + // There could be other interfaces needing this info + // + + // + // Due to the asynchronous nature of the interface + // between PE <-> HAL, some transient information + // like this needs to be cached. + // This is cached upon receipt of eWNI_SME_SETCONTEXT_REQ. + // This is released while posting LIM_MLM_SETKEYS_CNF + // + void* gpLimMlmSetKeysReq; + void* gpLimMlmRemoveKeyReq; + + ////////////////////////////////////////// BSS RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// IBSS RELATED START /////////////////////////////////////////// + //This indicates whether this STA coalesced and adapter to peer's capabilities or not. + tANI_U8 gLimIbssCoalescingHappened; + + /// Definition for storing IBSS peers BSS description + tLimIbssPeerNode *gLimIbssPeerList; + tANI_U32 gLimNumIbssPeers; + + // ibss info - params for which ibss to join while coalescing + tAniSirLimIbss ibssInfo; + + ////////////////////////////////////////// IBSS RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// STATS/COUNTER RELATED START /////////////////////////////////////////// + + tANI_U16 maxStation; + tANI_U16 maxBssId; + + tANI_U32 gLimNumBeaconsRcvd; + tANI_U32 gLimNumBeaconsIgnored; + + tANI_U32 gLimNumDeferredMsgs; + + /// Variable to keep track of number of currently associated STAs + tANI_U16 gLimNumOfAniSTAs; // count of ANI peers + tANI_U16 gLimAssocStaLimit; + + // Heart-Beat interval value + tANI_U32 gLimHeartBeatCount; + + // Statistics to keep track of no. beacons rcvd in heart beat interval + tANI_U16 gLimHeartBeatBeaconStats[MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL]; + +#ifdef WLAN_DEBUG + // Debug counters + tANI_U32 numTot, numBbt, numProtErr, numLearn, numLearnIgnore; + tANI_U32 numSme, numMAC[4][16]; + + // Debug counter to track number of Assoc Req frame drops + // when received in pStaDs->mlmState other than LINK_ESTABLISED + tANI_U32 gLimNumAssocReqDropInvldState; + // counters to track rejection of Assoc Req due to Admission Control + tANI_U32 gLimNumAssocReqDropACRejectTS; + tANI_U32 gLimNumAssocReqDropACRejectSta; + // Debug counter to track number of Reassoc Req frame drops + // when received in pStaDs->mlmState other than LINK_ESTABLISED + tANI_U32 gLimNumReassocReqDropInvldState; + // Debug counter to track number of Hash Miss event that + // will not cause a sending of de-auth/de-associate frame + tANI_U32 gLimNumHashMissIgnored; + + // Debug counter to track number of Beacon frames + // received in unexpected state + tANI_U32 gLimUnexpBcnCnt; + + // Debug counter to track number of Beacon frames + // received in wt-join-state that do have SSID mismatch + tANI_U32 gLimBcnSSIDMismatchCnt; + + // Debug counter to track number of Link establishments on STA/BP + tANI_U32 gLimNumLinkEsts; + + // Debug counter to track number of Rx cleanup + tANI_U32 gLimNumRxCleanup; + + // Debug counter to track different parse problem + tANI_U32 gLim11bStaAssocRejectCount; + +#endif + + //Time stamp of the last beacon received from the BSS to which STA is connected. + tANI_U64 gLastBeaconTimeStamp; + //RX Beacon count for the current BSS to which STA is connected. + tANI_U32 gCurrentBssBeaconCnt; + tANI_U8 gLastBeaconDtimCount; + tANI_U8 gLastBeaconDtimPeriod; + + + ////////////////////////////////////////// STATS/COUNTER RELATED END /////////////////////////////////////////// + + + ////////////////////////////////////////// STATES RELATED START /////////////////////////////////////////// + // Counts Heartbeat failures + tANI_U8 gLimHBfailureCntInLinkEstState; + tANI_U8 gLimProbeFailureAfterHBfailedCnt; + tANI_U8 gLimHBfailureCntInOtherStates; + + /** + * This variable indicates whether LIM module need to + * send response to host. Used to identify whether a request + * is generated internally within LIM module or by host + */ + tANI_U8 gLimRspReqd; + + /// Previous SME State + tLimSmeStates gLimPrevSmeState; + + /// MLM State visible across all Sirius modules + tLimMlmStates gLimMlmState; + + /// Previous MLM State + tLimMlmStates gLimPrevMlmState; + +#ifdef GEN4_SCAN + // LIM to HAL SCAN Management Message Interface states + tLimLimHalScanState gLimHalScanState; +//WLAN_SUSPEND_LINK Related + SUSPEND_RESUME_LINK_CALLBACK gpLimSuspendCallback; + tANI_U32 *gpLimSuspendData; + SUSPEND_RESUME_LINK_CALLBACK gpLimResumeCallback; + tANI_U32 *gpLimResumeData; +//end WLAN_SUSPEND_LINK Related + tANI_U8 fScanDisabled; + //Can be set to invalid channel. If it is invalid, HAL + //should move to previous valid channel or stay in the + //current channel. CB state goes along with channel to resume to + tANI_U16 gResumeChannel; + ePhyChanBondState gResumePhyCbState; +#endif // GEN4_SCAN + + // Change channel generic scheme + CHANGE_CHANNEL_CALLBACK gpchangeChannelCallback; + tANI_U32 *gpchangeChannelData; + + /// SME State visible across all Sirius modules + tLimSmeStates gLimSmeState; + /// This indicates whether we're an AP, STA in BSS/IBSS + tLimSystemRole gLimSystemRole; + + // Number of STAs that do not support short preamble + tLimNoShortParams gLimNoShortParams; + + // Number of STAs that do not support short slot time + tLimNoShortSlotParams gLimNoShortSlotParams; + + + // OLBC parameters + tLimProtStaParams gLimOverlap11gParams; + + tLimProtStaParams gLimOverlap11aParams; + tLimProtStaParams gLimOverlapHt20Params; + tLimProtStaParams gLimOverlapNonGfParams; + + // + // ---------------- DPH ----------------------- + // these used to live in DPH but are now moved here (where they belong) + tANI_U32 gLimPhyMode; + tANI_U32 propRateAdjustPeriod; + tANI_U32 scanStartTime; // used to measure scan time + + tANI_U8 gLimMyMacAddr[6]; + tANI_U8 ackPolicy; + + tANI_U8 gLimQosEnabled:1; //11E + tANI_U8 gLimWmeEnabled:1; //WME + tANI_U8 gLimWsmEnabled:1; //WSM + tANI_U8 gLimHcfEnabled:1; + tANI_U8 gLim11dEnabled:1; + tANI_U8 gLimProbeRespDisableFlag:1; // control over probe response + // ---------------- DPH ----------------------- + + ////////////////////////////////////////// STATES RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// MISC RELATED START /////////////////////////////////////////// + + // WDS info + tANI_U32 gLimNumWdsInfoInd; + tANI_U32 gLimNumWdsInfoSet; + tSirWdsInfo gLimWdsInfo; + + // Deferred Queue Paramters + tLimDeferredMsgQParams gLimDeferredMsgQ; + + // addts request if any - only one can be outstanding at any time + tSirAddtsReq gLimAddtsReq; + tANI_U8 gLimAddtsSent; + tANI_U8 gLimAddtsRspTimerCount; + + //protection related config cache + tCfgProtection cfgProtection; + + tANI_U8 gLimProtectionControl; + //RF band to determibe 2.4/5 GHZ + + // alternate radio info used by STA + tSirAlternateRadioInfo gLimAlternateRadio; + + //This flag will remain to be set except while LIM is waiting for specific response messages + //from HAL. e.g when LIM issues ADD_STA req it will clear this flag and when it will receive + //the response the flag will be set. + tANI_U8 gLimProcessDefdMsgs; + + // UAPSD flag used on AP + tANI_U8 gUapsdEnable; + + /* Used on STA, this is a static UAPSD mask setting + * derived from SME_JOIN_REQ and SME_REASSOC_REQ. If a + * particular AC bit is set, it means the AC is both + * trigger enabled and delivery enabled. + */ + tANI_U8 gUapsdPerAcBitmask; + + /* Used on STA, this is a dynamic UPASD mask setting + * derived from AddTS Rsp and DelTS frame. If a + * particular AC bit is set, it means AC is trigger + * enabled. + */ + tANI_U8 gUapsdPerAcTriggerEnableMask; + + /* Used on STA, dynamic UPASD mask setting + * derived from AddTS Rsp and DelTs frame. If + * a particular AC bit is set, it means AC is + * delivery enabled. + */ + tANI_U8 gUapsdPerAcDeliveryEnableMask; + + /* Used on STA for AC downgrade. This is a dynamic mask + * setting which keep tracks of ACs being admitted. + * If bit is set to 0: That partiular AC is not admitted + * If bit is set to 1: That particular AC is admitted + */ + tANI_U8 gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT]; + + //dialogue token List head/tail for Action frames request sent. + tpDialogueToken pDialogueTokenHead; + tpDialogueToken pDialogueTokenTail; + + tLimTspecInfo tspecInfo[LIM_NUM_TSPEC_MAX]; + + // admission control policy information + tLimAdmitPolicyInfo admitPolicyInfo; + vos_lock_t lkPeGlobalLock; + tANI_U8 disableLDPCWithTxbfAP; +#ifdef FEATURE_WLAN_TDLS + tANI_U8 gLimTDLSBufStaEnabled; + tANI_U8 gLimTDLSUapsdMask; + tANI_U8 gLimTDLSOffChannelEnabled; + // TDLS WMM Mode + tANI_U8 gLimTDLSWmmMode; +#endif + ////////////////////////////////////////// MISC RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// ASSOC RELATED START /////////////////////////////////////////// + // Place holder for JoinReq message + // received by SME state machine + // tpSirSmeJoinReq gpLimJoinReq; + + // Place holder for ReassocReq message + // received by SME state machine + //tpSirSmeReassocReq gpLimReassocReq; sep23 review + + // Current Authentication type used at STA + //tAniAuthType gLimCurrentAuthType; + + // Place holder for current authentication request + // being handled + tLimMlmAuthReq *gpLimMlmAuthReq; + + // Reason code to determine the channel change context while sending + // WDA_CHNL_SWITCH_REQ message to HAL + tANI_U32 channelChangeReasonCode; + + /// MAC level Pre-authentication related globals + tSirMacChanNum gLimPreAuthChannelNumber; + tAniAuthType gLimPreAuthType; + tSirMacAddr gLimPreAuthPeerAddr; + tANI_U32 gLimNumPreAuthContexts; + tLimPreAuthTable gLimPreAuthTimerTable; + + // Placed holder to deauth reason + tANI_U16 gLimDeauthReasonCode; + + // Place holder for Pre-authentication node list + struct tLimPreAuthNode * pLimPreAuthList; + + // Send Disassociate frame threshold parameters + tANI_U16 gLimDisassocFrameThreshold; + tANI_U16 gLimDisassocFrameCredit; + + // Assoc or ReAssoc Response Data/Frame + void *gLimAssocResponseData; + + //One cache for each overlap and associated case. + tCacheParams protStaOverlapCache[LIM_PROT_STA_OVERLAP_CACHE_SIZE]; + tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE]; + + ////////////////////////////////////////// ASSOC RELATED END /////////////////////////////////////////// + + + + // + // For DEBUG purposes + // Primarily for - TITAN BEACON workaround + // Symptom - TFP/PHY gets stuck + // + tANI_U32 gLimScanOverride; + // Holds the desired tSirScanType, as requested by SME + tSirScanType gLimScanOverrideSaved; + + // + // CB State protection, operated upon as follows: + // 1 - CB is enabled in the hardware ONLY WHEN a Titan + // STA associates with the AP + // 0 - CB is enabled/disabled based on the configuration + // received as per eWNI_SME_START_BSS_REQ + // + tANI_U32 gLimCBStateProtection; + + // Count of TITAN STA's currently associated + tANI_U16 gLimTitanStaCount; + + // + // For DEBUG purposes + // Primarily for - TITAN workaround + // Symptom - Avoid NULL data frames + // Applies to AP only + // + tANI_U32 gLimBlockNonTitanSta; + /////////////////////////// TITAN related globals ////////////////////////////////////////// + + + //////////////////////////////// HT RELATED ////////////////////////////////////////// + // + // The following global LIM variables maintain/manage + // the runtime configurations related to 802.11n + + // 802.11n Station detected HT capability in Beacon Frame + tANI_U8 htCapabilityPresentInBeacon; + + // 802.11 HT capability: Enabled or Disabled + tANI_U8 htCapability; + + + tANI_U8 gHTGreenfield; + + tANI_U8 gHTShortGI40Mhz; + tANI_U8 gHTShortGI20Mhz; + + //Set to 0 for 3839 octets + //Set to 1 for 7935 octets + tANI_U8 gHTMaxAmsduLength; + + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + tANI_U8 gHTDsssCckRate40MHzSupport; + + // PSMP Support: Enabled 1 or Disabled 0 + tANI_U8 gHTPSMPSupport; + + // L-SIG TXOP Protection used only if peer support available + tANI_U8 gHTLsigTXOPProtection; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState gHTMIMOPSState; + + // Scan In Power Save + tANI_U8 gScanInPowersave; + + // + // A-MPDU Density + // 000 - No restriction + // 001 - 1/8 usec + // 010 - 1/4 usec + // 011 - 1/2 usec + // 100 - 1 usec + // 101 - 2 usec + // 110 - 4 usec + // 111 - 8 usec + // + tANI_U8 gHTAMpduDensity; + + tANI_BOOLEAN gMaxAmsduSizeEnabled; + // Maximum Tx/Rx A-MPDU factor + tANI_U8 gHTMaxRxAMpduFactor; + + // + // Scheduled PSMP related - Service Interval Granularity + // 000 - 5 ms + // 001 - 10 ms + // 010 - 15 ms + // 011 - 20 ms + // 100 - 25 ms + // 101 - 30 ms + // 110 - 35 ms + // 111 - 40 ms + // + tANI_U8 gHTServiceIntervalGranularity; + + // Indicates whether an AP wants to associate PSMP enabled Stations + tANI_U8 gHTControlledAccessOnly; + + // RIFS Mode. Set if no APSD legacy devices associated + tANI_U8 gHTRifsMode; + // OBss Mode . set when we have Non HT STA is associated or with in overlap bss + tANI_U8 gHTObssMode; + + // Identifies the current Operating Mode + tSirMacHTOperatingMode gHTOperMode; + + // Indicates if PCO is activated in the BSS + tANI_U8 gHTPCOActive; + + // + // If PCO is active, indicates which PCO phase to use + // 0 - switch to 20 MHz phase + // 1 - switch to 40 MHz phase + // + tANI_U8 gHTPCOPhase; + + // + // Used only in beacons. For PR, this is set to 0 + // 0 - Primary beacon + // 1 - Secondary beacon + // + tANI_U8 gHTSecondaryBeacon; + + // + // Dual CTS Protection + // 0 - Use RTS/CTS + // 1 - Dual CTS Protection is used + // + tANI_U8 gHTDualCTSProtection; + + // + // Identifies a single STBC MCS that shall ne used for + // STBC control frames and STBC beacons + // + tANI_U8 gHTSTBCBasicMCS; + + tANI_U8 gHTNonGFDevicesPresent; + + tANI_U8 gAddBA_Declined; // Flag to Decline the BAR if the particular bit (0-7) is being set + + //////////////////////////////// HT RELATED ////////////////////////////////////////// + +#ifdef FEATURE_WLAN_TDLS + tANI_U8 gLimAddStaTdls ; + tANI_U8 gLimTdlsLinkMode ; + //////////////////////////////// TDLS RELATED ////////////////////////////////////////// +#endif + + // wsc info required to form the wsc IE + tLimWscIeInfo wscIeInfo; + tpPESession gpSession ; //Pointer to session table + /* + * sessionID and transactionID from SME is stored here for those messages, for which + * there is no session context in PE, e.g. Scan related messages. + **/ + tANI_U8 gSmeSessionId; + tANI_U16 gTransactionId; + +#ifdef FEATURE_OEM_DATA_SUPPORT +tLimMlmOemDataReq *gpLimMlmOemDataReq; +tLimMlmOemDataRsp *gpLimMlmOemDataRsp; +#endif + + tSirRemainOnChnReq *gpLimRemainOnChanReq; //hold remain on chan request in this buf + vos_list_t gLimMgmtFrameRegistratinQueue; + tANI_U32 mgmtFrameSessionId; + tSirBackgroundScanMode gLimBackgroundScanMode; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tpPESession pSessionEntry; + tANI_U8 reAssocRetryAttempt; +#endif + tLimDisassocDeauthCnfReq limDisassocDeauthCnfReq; + tANI_U8 deferredMsgCnt; + tSirDFSChannelList dfschannelList; + tANI_U8 deauthMsgCnt; + tANI_U8 gLimIbssStaLimit; + + /* Number of channel switch IEs sent so far */ + tANI_U8 gLimDfsChanSwTxCount; + tANI_U8 gLimDfsTargetChanNum; + tANI_U8 fOffloadScanPending; /*Flag to track offload scan */ + tANI_U8 fOffloadScanP2PSearch; /*Flag to track the p2p search */ + tANI_U8 fOffloadScanP2PListen; /*Flag to track the p2p listen */ + tANI_U8 probeCounter; + tANI_U8 maxProbe; +} tAniSirLim, *tpAniSirLim; + +typedef struct sLimMgmtFrameRegistration +{ + vos_list_node_t node; // MUST be first element + tANI_U16 frameType; + tANI_U16 matchLen; + tANI_U16 sessionId; + tANI_U8 matchData[1]; +} tLimMgmtFrameRegistration, *tpLimMgmtFrameRegistration; + +#if defined WLAN_FEATURE_VOWIFI +typedef struct sRrmContext +{ + tRrmSMEContext rrmSmeContext; + tRrmPEContext rrmPEContext; +}tRrmContext, *tpRrmContext; +#endif + +//Check if this definition can actually move here even for Volans. In that case +//this featurization can be removed. +/** ------------------------------------------------------------------------- * + + \typedef tDriverType + + \brief Indicate the driver type to the mac, and based on this do + appropriate initialization. + + -------------------------------------------------------------------------- */ + +typedef enum +{ + eDRIVER_TYPE_PRODUCTION = 0, + eDRIVER_TYPE_MFG = 1, + eDRIVER_TYPE_DVT = 2 +} tDriverType; + +/** ------------------------------------------------------------------------- * + + \typedef tMacOpenParameters + + \brief Parameters needed for Enumeration of all status codes returned by the higher level + interface functions. + + -------------------------------------------------------------------------- */ + +typedef struct sMacOpenParameters +{ + tANI_U16 maxStation; + tANI_U16 maxBssId; + tANI_U32 frameTransRequired; + tANI_U8 powersaveOffloadEnabled; + /* Powersave Parameters */ + tANI_U8 staMaxLIModDtim; + tANI_U8 staModDtim; + tANI_U8 staDynamicDtim; + tDriverType driverType; + tANI_U8 maxWoWFilters; + tANI_U8 wowEnable; +/* Here olIniInfo is used to store ini + * status of arp offload, ns offload + * and others. Currently 1st bit is used + * for arp off load and 2nd bit for ns + * offload currently, rest bits are unused + */ + tANI_U8 olIniInfo; + v_BOOL_t ssdp; + /* + * DFS Phyerror Filtering offload status from ini + * 0 indicates offload disabled + * 1 indicates offload enabled + */ + tANI_U8 dfsPhyerrFilterOffload; +/* pass intra-bss-fwd info to txrx module */ + tANI_U8 apDisableIntraBssFwd; + + /* max offload peer */ + tANI_U8 apMaxOffloadPeers; + + /* max offload reorder buffs */ + tANI_U8 apMaxOffloadReorderBuffs; + +#ifdef FEATURE_WLAN_RA_FILTERING + tANI_U16 RArateLimitInterval; + v_BOOL_t IsRArateLimitEnabled; +#endif + /* is RX re-ordering offloaded to the fw */ + tANI_U8 reorderOffload; + + /* dfs radar pri multiplier */ + tANI_S32 dfsRadarPriMultiplier; + +#ifdef IPA_UC_OFFLOAD + /* IPA Micro controller data path offload enable flag */ + tANI_U8 ucOffloadEnabled; + /* IPA Micro controller data path offload TX buffer count */ + tANI_U32 ucTxBufCount; + /* IPA Micro controller data path offload TX buffer size */ + tANI_U32 ucTxBufSize; + /* IPA Micro controller data path offload RX indication ring count */ + tANI_U32 ucRxIndRingCount; + /* IPA Micro controller data path offload TX partition base */ + tANI_U32 ucTxPartitionBase; +#endif /* IPA_UC_OFFLOAD */ + +} tMacOpenParameters; + +typedef struct sHalMacStartParameters +{ + // parametes for the Firmware + tDriverType driverType; + +} tHalMacStartParameters; + +// ------------------------------------------------------------------- +/// MAC Sirius parameter structure +typedef struct sAniSirGlobal + +{ + tDriverType gDriverType; + + tSirMbMsg* pResetMsg; + tAniSirCfg cfg; + tAniSirLim lim; + tAniSirPmm pmm; + tAniSirSch sch; + tAniSirSys sys; + tAniSirUtils utils; + + /* PAL/HDD handle */ + tHddHandle hHdd; + +#ifdef ANI_DVT_DEBUG + tAniSirDvt dvt; +#endif + + tSmeStruct sme; + tSapStruct sap; + tCsrScanStruct scan; + tCsrRoamStruct roam; + +#ifdef FEATURE_OEM_DATA_SUPPORT + tOemDataStruct oemData; +#endif + tPmcInfo pmc; + tSmeBtcInfo btc; + + tCcm ccm; + +#if defined WLAN_FEATURE_VOWIFI + tRrmContext rrm; +#endif +#ifdef WLAN_FEATURE_CONCURRENT_P2P + tp2pContext p2pContext[MAX_NO_OF_P2P_SESSIONS]; +#else + tp2pContext p2pContext; +#endif + + tANI_U32 gCurrentLogSize; + tANI_U32 menuCurrent; + /* logDump specific */ + tANI_U32 dumpTablecurrentId; + /* Instead of static allocation I will dyanamically allocate memory for dumpTableEntry + Thinking of using linkedlist */ + tDumpModuleEntry *dumpTableEntry[MAX_DUMP_TABLE_ENTRY]; +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t isTdlsPowerSaveProhibited; +#endif + tANI_U8 fScanOffload; + tANI_U8 isCoalesingInIBSSAllowed; + tANI_U8 psOffloadEnabled; + + /* Power Save offload Info */ + tPmcOffloadInfo pmcOffloadInfo; + + /* P2P Listen Offload */ + tANI_U8 fP2pListenOffload; + + /* PNO offload */ + v_BOOL_t pnoOffload; + + csrReadyToSuspendCallback readyToSuspendCallback; + void *readyToSuspendContext; + tANI_U8 lteCoexAntShare; + tANI_U8 beacon_offload; + tANI_U32 fEnableDebugLog; + tANI_U16 mgmtSeqNum; + v_BOOL_t enable5gEBT; + /* Miracast session 0-Disabled, 1-Source, 2-sink*/ + tANI_U8 fMiracastSessionPresent; +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + csrReadyToExtWoWCallback readyToExtWoWCallback; + void *readyToExtWoWContext; +#endif +} tAniSirGlobal; + +typedef enum +{ + eHIDDEN_SSID_NOT_IN_USE, + eHIDDEN_SSID_ZERO_LEN, + eHIDDEN_SSID_ZERO_CONTENTS +} tHiddenssId; + +#ifdef FEATURE_WLAN_TDLS + +#define RFC1042_HDR_LENGTH (6) +#define GET_BE16(x) ((tANI_U16) (((x)[0] << 8) | (x)[1])) +#define ETH_TYPE_89_0d (0x890d) +#define ETH_TYPE_LEN (2) +#define PAYLOAD_TYPE_TDLS_SIZE (1) +#define PAYLOAD_TYPE_TDLS (2) + +#endif + +#endif /* _ANIGLOBAL_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniSystemDefs.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniSystemDefs.h new file mode 100644 index 0000000000000..2720d10e57f78 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/aniSystemDefs.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file aniSystemDefs.h contains definitions used by + * various ANI entities + * Author: Chandra Modumudi + * Date: 09/18/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __ANI_SYSTEM_DEFS_H +#define __ANI_SYSTEM_DEFS_H + +#include "sirTypes.h" +#include "sirMacProtDef.h" + +#define ANI_OUI 0x000AF5 + +/// Max WDS info length. +#define ANI_WDS_INFO_MAX_LENGTH 64 + +//This is to force compiler to use the maximum of an int for enum +#define SIR_MAX_ENUM_SIZE 0x7FFFFFFF + +/* Max key size including the WAPI and TKIP */ +#define WLAN_MAX_KEY_RSC_LEN 16 +#define WLAN_WAPI_KEY_RSC_LEN 16 + + + +#ifndef FALSE +#undef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#undef TRUE +#define TRUE 1 +#endif + +typedef enum eAniBool +{ + eSIR_FALSE, + eSIR_TRUE, + eSIR_DONOT_USE_BOOL = SIR_MAX_ENUM_SIZE +} tAniBool; + +/// Authentication type enum used with peer +typedef enum eAniAuthType +{ + eSIR_OPEN_SYSTEM, + eSIR_SHARED_KEY, +#if defined WLAN_FEATURE_VOWIFI_11R + eSIR_FT_AUTH, +#endif +#if defined FEATURE_WLAN_ESE + eSIR_LEAP_AUTH = 0x80, +#endif + eSIR_AUTO_SWITCH, + eSIR_DONOT_USE_AUTH_TYPE = SIR_MAX_ENUM_SIZE +} tAniAuthType; + +/// Encryption type enum used with peer +typedef enum eAniEdType +{ + eSIR_ED_NONE, + eSIR_ED_WEP40, + eSIR_ED_WEP104, + eSIR_ED_TKIP, + eSIR_ED_CCMP, +#if defined(FEATURE_WLAN_WAPI) + eSIR_ED_WPI, +#endif + /*DPU HW treats encryption mode 4 plus RMF bit set in TX BD as BIP. + Thus while setting BIP encryption mode in corresponding DPU Desc + eSIR_ED_AES_128_CMAC should be set to eSIR_ED_CCMP*/ + eSIR_ED_AES_128_CMAC, + eSIR_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE +} tAniEdType; + + +typedef enum eAniWepType +{ + eSIR_WEP_STATIC, + eSIR_WEP_DYNAMIC, +} tAniWepType; + +/// Enum to specify whether key is used +/// for TX only, RX only or both +typedef enum eAniKeyDirection +{ + eSIR_TX_ONLY, + eSIR_RX_ONLY, + eSIR_TX_RX, + eSIR_TX_DEFAULT, + eSIR_DONOT_USE_KEY_DIRECTION = SIR_MAX_ENUM_SIZE +} tAniKeyDirection; + +typedef struct sAniSSID +{ + tANI_U8 length; + tANI_U8 ssId[SIR_MAC_MAX_SSID_LENGTH]; +} tAniSSID, *tpAniSSID; + +typedef struct sAniApName +{ + tANI_U8 length; + tANI_U8 name[SIR_MAC_MAX_SSID_LENGTH]; +} tAniApName, *tpAniApName; + +/// RSN IE information +typedef struct sSirRSNie +{ + tANI_U16 length; + tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; +} tSirRSNie, *tpSirRSNie; + +/// Additional IE information : +/// This can include WSC IE, P2P IE, and/or FTIE from upper layer. +/// MAC layer transparently convey these IE info between peer STA and upper layer, +/// but never requires to parse it. +typedef struct sSirAddie +{ + tANI_U16 length; + tANI_U8 addIEdata[SIR_MAC_MAX_ADD_IE_LENGTH + 2]; +} tSirAddie, *tpSirAddie; + +#ifdef FEATURE_WLAN_ESE + +// The CCKM IE needs to be in the +// Join and Reassoc Req. +typedef struct sSirCCKMie +{ + tANI_U16 length; + tANI_U8 cckmIEdata[SIR_MAC_MAX_IE_LENGTH+2]; +} tSirCCKMie, *tpSirCCKMie; + +#endif + +/// Definition for Encryption Keys +typedef struct sSirKeys +{ + tANI_U8 keyId; + tANI_U8 unicast; // 0 for multicast + tAniKeyDirection keyDirection; + tANI_U8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + tANI_U8 paeRole; // =1 for authenticator, + // =0 for supplicant + tANI_U16 keyLength; + tANI_U8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tSirKeys, *tpSirKeys; + +/// Definition for Keying material +typedef struct sSirKeyMaterial +{ + tANI_U16 length; // This is the length of all + // data that follows + tAniEdType edType; // Encryption/Decryption type + tANI_U8 numKeys; + tSirKeys key[1]; +} tSirKeyMaterial, *tpSirKeyMaterial; + +#define SIR_CIPHER_SEQ_CTR_SIZE 6 +/// Definition for MIC failure indication +typedef struct sSirMicFailureInfo +{ + tSirMacAddr srcMacAddr; //address used to compute MIC + tSirMacAddr taMacAddr; //transmitter address + tSirMacAddr dstMacAddr; + tAniBool multicast; + tANI_U8 IV1; // first byte of IV + tANI_U8 keyId; // second byte of IV + tANI_U8 TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + tSirMacAddr rxMacAddr; // receive address + +} tSirMicFailureInfo, *tpSirMicFailureInfo; + +typedef __ani_attr_pre_packed struct sTrafStrmMetrics +{ + tANI_U16 UplinkPktQueueDly; + tANI_U16 UplinkPktQueueDlyHist[4]; + tANI_U32 UplinkPktTxDly; + tANI_U16 UplinkPktLoss; + tANI_U16 UplinkPktCount; + tANI_U8 RoamingCount; + tANI_U16 RoamingDly; +} __ani_attr_packed tTrafStrmMetrics, *tpTrafStrmMetrics; + + +typedef __ani_attr_pre_packed struct sBcnReportFields +{ + tANI_U8 ChanNum; + tANI_U8 Spare; + tANI_U16 MeasDuration; + tANI_U8 PhyType; + tANI_U8 RecvSigPower; + tSirMacAddr Bssid; + tANI_U32 ParentTsf; + tANI_U32 TargetTsf[2]; + tANI_U16 BcnInterval; + tANI_U16 CapabilityInfo; +} __ani_attr_packed tBcnReportFields, *tpBcnReportFields; + + +#endif /* __ANI_SYSTEM_DEFS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/logDump.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/logDump.h new file mode 100644 index 0000000000000..734df7aa8bf0c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/logDump.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/*============================================================================ +logDump.h + +Provides api's for dump commands. + +Author: Santosh Mandiganal +Date: 04/06/2008 +============================================================================*/ + + +#ifndef __LOGDUMP_H__ +#define __LOGDUMP_H__ + +#define MAX_DUMP_CMD 999 +#define MAX_DUMP_TABLE_ENTRY 10 + +typedef char * (*tpFunc)(tpAniSirGlobal, tANI_U32, tANI_U32, tANI_U32, tANI_U32, char *); + +typedef struct sDumpFuncEntry { + tANI_U32 id; + char *description; + tpFunc func; +} tDumpFuncEntry; + +typedef struct sDumpModuleEntry { + tANI_U32 mindumpid; + tANI_U32 maxdumpid; + tANI_U32 nItems; + tDumpFuncEntry *dumpTable; +} tDumpModuleEntry; + +typedef struct sRegList { + tANI_U32 addr; + char *name; +} tLogdRegList; + +int log_sprintf(tpAniSirGlobal pMac, char *pBuf, char *fmt, ... ); + +char * +dump_log_level_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_set( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_group_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p); + +void logDumpRegisterTable( tpAniSirGlobal pMac, tDumpFuncEntry *pEntry, + tANI_U32 nItems ); + + +void logDumpInit(tpAniSirGlobal pMac); + +#endif /* __LOGDUMP_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/macInitApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/macInitApi.h new file mode 100644 index 0000000000000..401027c8a2d3f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/macInitApi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * macInitApi.c - Header file for mac level init functions + * Author: Dinesh Upadhyay + * Date: 04/23/2007 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ +#ifndef __MAC_INIT_API_H +#define __MAC_INIT_API_H + +#include "aniGlobal.h" + +tSirRetStatus macStart(tHalHandle hHal, void* pHalMacStartParams); +tSirRetStatus macStop(tHalHandle hHal, tHalStopType stopType); +tSirRetStatus macOpen(tHalHandle * pHalHandle, tHddHandle hHdd, tMacOpenParameters * pMacOpenParms); +tSirRetStatus macClose(tHalHandle hHal); + +tSirRetStatus macPreStart(tHalHandle hHal); + +#endif //__MAC_INIT_API_H diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/macTrace.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/macTrace.h new file mode 100644 index 0000000000000..0377885b94b25 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/macTrace.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + + +* \file macTrace.h + +* \brief definition for trace related APIs + + \author Sunit Bhatia + + ========================================================================*/ + + + +#ifndef __MAC_TRACE_H +#define __MAC_TRACE_H + +#include "aniGlobal.h" + + +#ifdef TRACE_RECORD + +#define MAC_TRACE_GET_MODULE_ID(data) ((data >> 8) & 0xff) +#define MAC_TRACE_GET_MSG_ID(data) (data & 0xffff) + + +#define eLOG_NODROP_MISSED_BEACON_SCENARIO 0 +#define eLOG_PROC_DEAUTH_FRAME_SCENARIO 1 + + +void macTraceReset(tpAniSirGlobal pMac); +void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U16 session, + tANI_U32 data); +void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, + tANI_U16 session, tANI_U32 data); +tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ); +tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ); +tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ); +tANI_U8* macTraceGetSmeMsgString( tANI_U16 smeMsg ); +tANI_U8* macTraceGetModuleString( tANI_U8 moduleId); +tANI_U8* macTraceGetInfoLogString( tANI_U16 infoLog ); +eHalStatus pe_AcquireGlobalLock( tAniSirLim *psPe); +eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe); + +tANI_U8* macTraceGetHDDWlanConnState(tANI_U16 connState); + +#ifdef WLAN_FEATURE_P2P_DEBUG +tANI_U8* macTraceGetP2PConnState(tANI_U16 connState); +#endif + +tANI_U8* macTraceGetNeighbourRoamState(tANI_U16 neighbourRoamState); +tANI_U8* macTraceGetcsrRoamState(tANI_U16 csrRoamState); +tANI_U8* macTraceGetcsrRoamSubState(tANI_U16 csrRoamSubState); +tANI_U8* macTraceGetLimSmeState(tANI_U16 limState); +tANI_U8* macTraceGetLimMlmState(tANI_U16 mlmState); +tANI_U8* macTraceGetTLState(tANI_U16 tlState); + +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h new file mode 100644 index 0000000000000..b84b50ff93c76 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef QWLAN_VERSION_H +#define QWLAN_VERSION_H +/*=========================================================================== + +FILE: + qwlan_version.h + +BRIEF DESCRIPTION: + WLAN Host Version file. + Build number automaticly updated by build scripts. + +===========================================================================*/ + +#define QWLAN_VERSION_MAJOR 4 +#define QWLAN_VERSION_MINOR 4 +#define QWLAN_VERSION_PATCH 21 +#define QWLAN_VERSION_EXTRA "" +#define QWLAN_VERSION_BUILD 65 + +#define QWLAN_VERSIONSTR "4.4.21.65" + + +#define AR6320_REV1_VERSION 0x5000000 +#define AR6320_REV1_1_VERSION 0x5000001 +#define AR6320_REV1_3_VERSION 0x5000003 +#define AR6320_REV2_1_VERSION 0x5010000 +#define AR6320_REV3_VERSION 0x5020000 +#define AR6320_REV3_2_VERSION 0x5030000 + +struct qwlan_hw { + u32 id; + u32 subid; + const char *name; +}; + + +#endif /* QWLAN_VERSION_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h new file mode 100644 index 0000000000000..260e1205901a0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirApi.h @@ -0,0 +1,5620 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file sirApi.h contains definitions exported by + * Sirius software. + * Author: Chandra Modumudi + * Date: 04/16/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIR_API_H +#define __SIR_API_H + +#include "sirTypes.h" +#include "sirMacProtDef.h" +#include "aniSystemDefs.h" +#include "sirParams.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseGlobal.h" +#endif + +/// Start of Sirius software/Host driver message types +#define SIR_HAL_HOST_MSG_START 0x1000 + +/// Max supported channel list +#define SIR_MAX_SUPPORTED_CHANNEL_LIST 96 + +#define SIR_MDIE_SIZE 3 + +// Increase dwell time for P2P search in ms +#define P2P_SEARCH_DWELL_TIME_INCREASE 20 +#define P2P_SOCIAL_CHANNELS 3 + +/* Max number of channels are 165, but to access 165th element of array, + *array of 166 is required. + */ +#define SIR_MAX_24G_5G_CHANNEL_RANGE 166 +#define SIR_BCN_REPORT_MAX_BSS_DESC 4 + + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define SIR_MAX_SSID_SIZE (32) +#endif + + +#define SIR_NUM_11B_RATES 4 //1,2,5.5,11 +#define SIR_NUM_11A_RATES 8 //6,9,12,18,24,36,48,54 +#define SIR_NUM_POLARIS_RATES 3 //72,96,108 +#define SIR_NUM_TITAN_RATES 26 +#define SIR_NUM_TAURUS_RATES 4 //136.5, 151.7,283.5,315 +#define SIR_NUM_PROP_RATES (SIR_NUM_TITAN_RATES + SIR_NUM_TAURUS_RATES) + +#define SIR_CONVERT_2_U32_BITMAP(nRates) ((nRates + 31)/32) + +/* #tANI_U32's needed for a bitmap representation for all prop rates */ +#define SIR_NUM_U32_MAP_RATES SIR_CONVERT_2_U32_BITMAP(SIR_NUM_PROP_RATES) + + +#define SIR_PM_SLEEP_MODE 0 +#define SIR_PM_ACTIVE_MODE 1 + +//hidden SSID options +#define SIR_SCAN_NO_HIDDEN_SSID 0 +#define SIR_SCAN_HIDDEN_SSID_PE_DECISION 1 + +#define SIR_MAC_ADDR_LEN 6 +#define SIR_IPV4_ADDR_LEN 4 + +typedef tANI_U8 tSirIpv4Addr[SIR_IPV4_ADDR_LEN]; + +#define SIR_VERSION_STRING_LEN 64 +typedef tANI_U8 tSirVersionString[SIR_VERSION_STRING_LEN]; + +/* Periodic Tx pattern offload feature */ +#define PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define MAXNUM_PERIODIC_TX_PTRNS 6 + +#define WIFI_SCANNING_MAC_OUI_LENGTH 3 + + +#ifdef FEATURE_WLAN_EXTSCAN + +#define WLAN_EXTSCAN_MAX_CHANNELS 40 +#define WLAN_EXTSCAN_MAX_BUCKETS 16 +#define WLAN_EXTSCAN_MAX_HOTLIST_APS 128 +#define WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS 64 + +typedef enum +{ + eSIR_EXTSCAN_INVALID, + eSIR_EXTSCAN_START_RSP, + eSIR_EXTSCAN_STOP_RSP, + eSIR_EXTSCAN_CACHED_RESULTS_RSP, + eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP, + eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP, + eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP, + eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP, + + eSIR_EXTSCAN_GET_CAPABILITIES_IND, + eSIR_EXTSCAN_HOTLIST_MATCH_IND, + eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND, + eSIR_EXTSCAN_CACHED_RESULTS_IND, + eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND, + eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND, + eSIR_EXTSCAN_FULL_SCAN_RESULT_IND, + + /* Keep this last */ + eSIR_EXTSCAN_CALLBACK_TYPE_MAX, +} tSirExtScanCallbackType; + + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#define SIR_KRK_KEY_LEN 16 +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define SIR_BTK_KEY_LEN 32 +#define SIR_KCK_KEY_LEN 16 +#define SIR_KEK_KEY_LEN 16 +#define SIR_REPLAY_CTR_LEN 8 + +#define SIR_UAPSD_BITOFFSET_ACVO 0 +#define SIR_UAPSD_BITOFFSET_ACVI 1 +#define SIR_UAPSD_BITOFFSET_ACBK 2 +#define SIR_UAPSD_BITOFFSET_ACBE 3 + +#define SIR_UAPSD_FLAG_ACVO (1 << SIR_UAPSD_BITOFFSET_ACVO) +#define SIR_UAPSD_FLAG_ACVI (1 << SIR_UAPSD_BITOFFSET_ACVI) +#define SIR_UAPSD_FLAG_ACBK (1 << SIR_UAPSD_BITOFFSET_ACBK) +#define SIR_UAPSD_FLAG_ACBE (1 << SIR_UAPSD_BITOFFSET_ACBE) +#define SIR_UAPSD_GET(ac, mask) (((mask) & (SIR_UAPSD_FLAG_ ## ac)) >> SIR_UAPSD_BITOFFSET_ ## ac) +#endif +enum eSirHostMsgTypes +{ + SIR_HAL_APP_SETUP_NTF = SIR_HAL_HOST_MSG_START, + SIR_HAL_INITIAL_CAL_FAILED_NTF, + SIR_HAL_NIC_OPER_NTF, + SIR_HAL_INIT_START_REQ, + SIR_HAL_SHUTDOWN_REQ, + SIR_HAL_SHUTDOWN_CNF, + SIR_HAL_RESET_REQ, + SIR_HAL_RADIO_ON_OFF_IND, + SIR_HAL_RESET_CNF, + SIR_WRITE_TO_TD, + SIR_HAL_HDD_ADDBA_REQ, // MAC -> HDD + SIR_HAL_HDD_ADDBA_RSP, // HDD -> HAL + SIR_HAL_DELETEBA_IND, // MAC -> HDD + SIR_HAL_BA_FAIL_IND, // HDD -> MAC + SIR_TL_HAL_FLUSH_AC_REQ, + SIR_HAL_TL_FLUSH_AC_RSP +}; + + + +/** + * Module ID definitions. + */ +enum { + SIR_BOOT_MODULE_ID = 1, + SIR_HAL_MODULE_ID = 0x10, + SIR_CFG_MODULE_ID = 0x12, + SIR_LIM_MODULE_ID, + SIR_ARQ_MODULE_ID, + SIR_SCH_MODULE_ID, + SIR_PMM_MODULE_ID, + SIR_MNT_MODULE_ID, + SIR_DBG_MODULE_ID, + SIR_DPH_MODULE_ID, + SIR_SYS_MODULE_ID, + SIR_SMS_MODULE_ID, + + SIR_PHY_MODULE_ID = 0x20, + + + // Add any modules above this line + SIR_DVT_MODULE_ID +}; + +#define SIR_WDA_MODULE_ID SIR_HAL_MODULE_ID + +/** + * First and last module definition for logging utility + * + * NOTE: The following definitions need to be updated if + * the above list is changed. + */ +#define SIR_FIRST_MODULE_ID SIR_HAL_MODULE_ID +#define SIR_LAST_MODULE_ID SIR_DVT_MODULE_ID + + +// Type declarations used by Firmware and Host software + +// Scan type enum used in scan request +typedef enum eSirScanType +{ + eSIR_PASSIVE_SCAN, + eSIR_ACTIVE_SCAN, + eSIR_BEACON_TABLE, +} tSirScanType; + +/// Result codes Firmware return to Host SW +typedef enum eSirResultCodes +{ + eSIR_SME_SUCCESS, + + eSIR_EOF_SOF_EXCEPTION, + eSIR_BMU_EXCEPTION, + eSIR_LOW_PDU_EXCEPTION, + eSIR_USER_TRIG_RESET, + eSIR_LOGP_EXCEPTION, + eSIR_CP_EXCEPTION, + eSIR_STOP_BSS, + eSIR_AHB_HANG_EXCEPTION, + eSIR_DPU_EXCEPTION, + eSIR_RPE_EXCEPTION, + eSIR_TPE_EXCEPTION, + eSIR_DXE_EXCEPTION, + eSIR_RXP_EXCEPTION, + eSIR_MCPU_EXCEPTION, + eSIR_MCU_EXCEPTION, + eSIR_MTU_EXCEPTION, + eSIR_MIF_EXCEPTION, + eSIR_FW_EXCEPTION, + eSIR_PS_MUTEX_READ_EXCEPTION, + eSIR_PHY_HANG_EXCEPTION, + eSIR_MAILBOX_SANITY_CHK_FAILED, + eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF, // Only where this switch is present + eSIR_CFB_FLAG_STUCK_EXCEPTION, + + eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS=30, + + eSIR_SME_INVALID_PARAMETERS=500, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, + eSIR_SME_RESOURCES_UNAVAILABLE, + eSIR_SME_SCAN_FAILED, // Unable to find a BssDescription + // matching requested scan criteria + eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED, + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE, + eSIR_SME_REFUSED, + eSIR_SME_JOIN_TIMEOUT_RESULT_CODE, + eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, + eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE, + eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, + eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED, + eSIR_SME_AUTH_REFUSED, + eSIR_SME_INVALID_WEP_DEFAULT_KEY, + eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER, + eSIR_SME_ASSOC_REFUSED, + eSIR_SME_REASSOC_REFUSED, + eSIR_SME_DEAUTH_WHILE_JOIN, //Received Deauth while joining or pre-auhtentication. + eSIR_SME_DISASSOC_WHILE_JOIN, //Received Disassociation while joining. + eSIR_SME_DEAUTH_WHILE_REASSOC, //Received Deauth while ReAssociate. + eSIR_SME_DISASSOC_WHILE_REASSOC, //Received Disassociation while ReAssociate + eSIR_SME_STA_NOT_AUTHENTICATED, + eSIR_SME_STA_NOT_ASSOCIATED, + eSIR_SME_STA_DISASSOCIATED, + eSIR_SME_ALREADY_JOINED_A_BSS, + eSIR_ULA_COMPLETED, + eSIR_ULA_FAILURE, + eSIR_SME_LINK_ESTABLISHED, + eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS, + eSIR_SME_UNABLE_TO_PERFORM_DFS, + eSIR_SME_DFS_FAILED, + eSIR_SME_TRANSFER_STA, // To be used when STA need to be LB'ed + eSIR_SME_INVALID_LINK_TEST_PARAMETERS,// Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_MAX_EXCEEDED, // Given in LINK_TEST_START_RSP + eSIR_SME_UNSUPPORTED_RATE, // Given in LINK_TEST_RSP if peer does + // support requested rate in + // LINK_TEST_REQ + eSIR_SME_LINK_TEST_TIMEOUT, // Given in LINK_TEST_IND if peer does + // not respond before next test packet + // is sent + eSIR_SME_LINK_TEST_COMPLETE, // Given in LINK_TEST_IND at the end + // of link test + eSIR_SME_LINK_TEST_INVALID_STATE, // Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_TERMINATE, // Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_INVALID_ADDRESS, // Given in LINK_TEST_STOP_RSP + eSIR_SME_POLARIS_RESET, // Given in SME_STOP_BSS_REQ + eSIR_SME_SETCONTEXT_FAILED, // Given in SME_SETCONTEXT_REQ when + // unable to plumb down keys + eSIR_SME_BSS_RESTART, // Given in SME_STOP_BSS_REQ + + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW, // Given in SME_SCAN_RSP message + // that more SME_SCAN_RSP + // messages are following. + // SME_SCAN_RSP message with + // eSIR_SME_SUCCESS status + // code is the last one. + eSIR_SME_INVALID_ASSOC_RSP_RXED, // Sent in SME_JOIN/REASSOC_RSP + // messages upon receiving + // invalid Re/Assoc Rsp frame. + eSIR_SME_MIC_COUNTER_MEASURES, // STOP BSS triggered by MIC failures: MAC software to disassoc all stations + // with MIC_FAILURE reason code and perform the stop bss operation + eSIR_SME_ADDTS_RSP_TIMEOUT, // didn't get response from peer within + // timeout interval + eSIR_SME_ADDTS_RSP_FAILED, // didn't get success response from HAL + eSIR_SME_RECEIVED, + // TBA - TSPEC related Result Codes + + eSIR_SME_CHANNEL_SWITCH_FAIL, // failed to send out Channel Switch Action Frame + eSIR_SME_INVALID_STA_ROLE, + eSIR_SME_INVALID_STATE, +#ifdef GEN4_SCAN + eSIR_SME_CHANNEL_SWITCH_DISABLED, // either 11h is disabled or channelSwitch is currently active + eSIR_SME_HAL_SCAN_INIT_FAILED, // SIR_HAL_SIR_HAL_INIT_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_START_FAILED, // SIR_HAL_START_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_END_FAILED, // SIR_HAL_END_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_FINISH_FAILED, // SIR_HAL_FINISH_SCAN_RSP returned failed status + eSIR_SME_HAL_SEND_MESSAGE_FAIL, // Failed to send a message to HAL +#else // GEN4_SCAN + eSIR_SME_CHANNEL_SWITCH_DISABLED, // either 11h is disabled or channelSwitch is currently active + eSIR_SME_HAL_SEND_MESSAGE_FAIL, // Failed to send a message to HAL +#endif // GEN4_SCAN +#ifdef FEATURE_OEM_DATA_SUPPORT + eSIR_SME_HAL_OEM_DATA_REQ_START_FAILED, +#endif + eSIR_SME_STOP_BSS_FAILURE, // Failed to stop the bss + eSIR_SME_STA_ASSOCIATED, + eSIR_SME_INVALID_PMM_STATE, + eSIR_SME_CANNOT_ENTER_IMPS, + eSIR_SME_IMPS_REQ_FAILED, + eSIR_SME_BMPS_REQ_FAILED, + eSIR_SME_BMPS_REQ_REJECT, + eSIR_SME_UAPSD_REQ_FAILED, + eSIR_SME_WOWL_ENTER_REQ_FAILED, + eSIR_SME_WOWL_EXIT_REQ_FAILED, +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \ + defined(FEATURE_WLAN_LFR) + eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, + eSIR_SME_FT_REASSOC_FAILURE, +#endif + eSIR_SME_SEND_ACTION_FAIL, +#ifdef WLAN_FEATURE_PACKET_FILTERING + eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED, +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED, +#endif // WLAN_FEATURE_GTK_OFFLOAD + eSIR_SME_DEAUTH_STATUS, + eSIR_DONOT_USE_RESULT_CODE = SIR_MAX_ENUM_SIZE +} tSirResultCodes; + +/* each station added has a rate mode which specifies the sta attributes */ +typedef enum eStaRateMode { + eSTA_TAURUS = 0, + eSTA_TITAN, + eSTA_POLARIS, + eSTA_11b, + eSTA_11bg, + eSTA_11a, + eSTA_11n, +#ifdef WLAN_FEATURE_11AC + eSTA_11ac, +#endif + eSTA_INVALID_RATE_MODE +} tStaRateMode, *tpStaRateMode; + +//although in tSirSupportedRates each IE is 16bit but PE only passes IEs in 8 bits with MSB=1 for basic rates. +//change the mask for bit0-7 only so HAL gets correct basic rates for setting response rates. +#define IERATE_BASICRATE_MASK 0x80 +#define IERATE_RATE_MASK 0x7f +#define IERATE_IS_BASICRATE(x) ((x) & IERATE_BASICRATE_MASK) +#define ANIENHANCED_TAURUS_RATEMAP_BITOFFSET_START 28 + +typedef struct sSirSupportedRates { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + +#ifdef WLAN_FEATURE_11AC + /*Indicates the Maximum MCS that can be received for each number + of spacial streams */ + tANI_U16 vhtRxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to receive*/ + tANI_U16 vhtRxHighestDataRate; + /*Indicates the Maximum MCS that can be transmitted for each number + of spacial streams */ + tANI_U16 vhtTxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + tANI_U16 vhtTxHighestDataRate; +#endif +} tSirSupportedRates, *tpSirSupportedRates; + + +typedef enum eSirRFBand +{ + SIR_BAND_UNKNOWN, + SIR_BAND_2_4_GHZ, + SIR_BAND_5_GHZ, +} tSirRFBand; + + +/* +* Specifies which beacons are to be indicated upto the host driver when +* Station is in power save mode. +*/ +typedef enum eBeaconForwarding +{ + ePM_BEACON_FWD_NTH, + ePM_BEACON_FWD_TIM, + ePM_BEACON_FWD_DTIM, + ePM_BEACON_FWD_NONE +} tBeaconForwarding; + + +typedef struct sSirRemainOnChnReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr selfMacAddr; + tANI_U8 chnNum; + tANI_U8 phyMode; + tANI_U32 duration; + tANI_U8 isProbeRequestAllowed; + tANI_U8 probeRspIe[1]; +}tSirRemainOnChnReq, *tpSirRemainOnChnReq; + +typedef struct sSirRegisterMgmtFrame +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tANI_BOOLEAN registerFrame; + tANI_U16 frameType; + tANI_U16 matchLen; + tANI_U8 matchData[1]; +}tSirRegisterMgmtFrame, *tpSirRegisterMgmtFrame; + +// +// Identifies the neighbor BSS' that was(were) detected +// by an STA and reported to the AP +// +typedef struct sAniTitanCBNeighborInfo +{ + // A BSS was found on the Primary + tANI_U8 cbBssFoundPri; + + // A BSS was found on the adjacent Upper Secondary + tANI_U8 cbBssFoundSecUp; + + // A BSS was found on the adjacent Lower Secondary + tANI_U8 cbBssFoundSecDown; + +} tAniTitanCBNeighborInfo, *tpAniTitanCBNeighborInfo; + +/// Generic type for sending a response message +/// with result code to host software +typedef struct sSirSmeRsp +{ + tANI_U16 messageType; // eWNI_SME_*_RSP + tANI_U16 length; + tANI_U8 sessionId; // To support BT-AMP + tANI_U16 transactionId; // To support BT-AMP + tSirResultCodes statusCode; +} tSirSmeRsp, *tpSirSmeRsp; + +/// Definition for kick starting Firmware on STA +typedef struct sSirSmeStartReq +{ + tANI_U16 messageType; // eWNI_SME_START_REQ + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP Support + tANI_U16 transcationId; //Added for BT-AMP Support + tSirMacAddr bssId; //Added For BT-AMP Support + tANI_U32 roamingAtPolaris; + tANI_U32 sendNewBssInd; +} tSirSmeStartReq, *tpSirSmeStartReq; + +/// Definition for indicating all modules ready on STA +typedef struct sSirSmeReadyReq +{ + tANI_U16 messageType; // eWNI_SME_SYS_READY_IND + tANI_U16 length; + tANI_U16 transactionId; +} tSirSmeReadyReq, *tpSirSmeReadyReq; + +/// Definition for response message to previously issued start request +typedef struct sSirSmeStartRsp +{ + tANI_U16 messageType; // eWNI_SME_START_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; +} tSirSmeStartRsp, *tpSirSmeStartRsp; + + +/// Definition for Load structure +typedef struct sSirLoad +{ + tANI_U16 numStas; + tANI_U16 channelUtilization; +} tSirLoad, *tpSirLoad; + +/// BSS type enum used in while scanning/joining etc +typedef enum eSirBssType +{ + eSIR_INFRASTRUCTURE_MODE, + eSIR_INFRA_AP_MODE, //Added for softAP support + eSIR_IBSS_MODE, + eSIR_BTAMP_STA_MODE, //Added for BT-AMP support + eSIR_BTAMP_AP_MODE, //Added for BT-AMP support + eSIR_AUTO_MODE, + eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE +} tSirBssType; + +/// Definition for WDS Information +typedef struct sSirWdsInfo +{ + tANI_U16 wdsLength; + tANI_U8 wdsBytes[ANI_WDS_INFO_MAX_LENGTH]; +} tSirWdsInfo, *tpSirWdsInfo; + +/// Power Capability info used in 11H +typedef struct sSirMacPowerCapInfo +{ + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tSirMacPowerCapInfo, *tpSirMacPowerCapInfo; + +/// Supported Channel info used in 11H +typedef struct sSirSupChnl +{ + tANI_U8 numChnl; + tANI_U8 channelList[SIR_MAX_SUPPORTED_CHANNEL_LIST]; +} tSirSupChnl, *tpSirSupChnl; + +typedef enum eSirNwType +{ + eSIR_11A_NW_TYPE, + eSIR_11B_NW_TYPE, + eSIR_11G_NW_TYPE, + eSIR_11N_NW_TYPE, +#ifdef WLAN_FEATURE_11AC + eSIR_11AC_NW_TYPE, +#endif + eSIR_DONOT_USE_NW_TYPE = SIR_MAX_ENUM_SIZE +} tSirNwType; + +/// Definition for new iBss peer info +typedef struct sSirNewIbssPeerInfo +{ + tSirMacAddr peerAddr; + tANI_U16 aid; +} tSirNewIbssPeerInfo, *tpSirNewIbssPeerInfo; + +/// Definition for Alternate BSS info +typedef struct sSirAlternateRadioInfo +{ + tSirMacAddr bssId; + tANI_U8 channelId; +} tSirAlternateRadioInfo, *tpSirAlternateRadioInfo; + +/// Definition for Alternate BSS list +typedef struct sSirAlternateRadioList +{ + tANI_U8 numBss; + tSirAlternateRadioInfo alternateRadio[1]; +} tSirAlternateRadioList, *tpSirAlternateRadioList; + +//HT configuration values +typedef __ani_attr_pre_packed struct sSirHtConfig +{ + //Enable/Disable receiving LDPC coded packets + tANI_U32 ht_rx_ldpc:1; + //Enable/Disable TX STBC + tANI_U32 ht_tx_stbc:1; + //Enable/Disable RX STBC + tANI_U32 ht_rx_stbc:2; + //Enable/Disable SGI + tANI_U32 ht_sgi:1; + tANI_U32 unused:27; +} __ani_attr_packed tSirHTConfig, *tpSirHTConfig; + +typedef __ani_attr_pre_packed struct sSirAddIeParams{ + tANI_U16 probeRespDataLen; + tANI_U8 *probeRespData_buff; + tANI_U16 assocRespDataLen; + tANI_U8 *assocRespData_buff; + tANI_U16 probeRespBCNDataLen; + tANI_U8 *probeRespBCNData_buff; +} tSirAddIeParams, *tpSirAddIeParams; + +/// Definition for kick starting BSS +/// ---> MAC +/** + * Usage of ssId, numSSID & ssIdList: + * --------------------------------- + * 1. ssId.length of zero indicates that Broadcast/Suppress SSID + * feature is enabled. + * 2. If ssId.length is zero, MAC SW will advertise NULL SSID + * and interpret the SSID list from numSSID & ssIdList. + * 3. If ssId.length is non-zero, MAC SW will advertise the SSID + * specified in the ssId field and it is expected that + * application will set numSSID to one (only one SSID present + * in the list) and SSID in the list is same as ssId field. + * 4. Application will always set numSSID >= 1. + */ +//*****NOTE: Please make sure all codes are updated if inserting field into this structure..********** +typedef struct sSirSmeStartBssReq +{ + tANI_U16 messageType; // eWNI_SME_START_BSS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP Support + tANI_U16 transactionId; //Added for BT-AMP Support + tSirMacAddr bssId; //Added for BT-AMP Support + tSirMacAddr selfMacAddr; //Added for BT-AMP Support + tANI_U16 beaconInterval; //Added for BT-AMP Support + tANI_U8 dot11mode; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 cc_switch_mode; +#endif + tSirBssType bssType; + tSirMacSSid ssId; + tANI_U8 channelId; + ePhyChanBondState cbMode; + + tANI_U8 privacy; + tANI_U8 apUapsdEnable; + tANI_U8 ssidHidden; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tANI_U16 ht_capab; + tAniAuthType authType; + tANI_U32 dtimPeriod; + tANI_U8 wps_state; + tANI_U8 isCoalesingInIBSSAllowed; //Coalesing on/off knob + tVOS_CON_MODE bssPersona; + + tANI_U8 txLdpcIniFeatureEnabled; + + tSirRSNie rsnIE; // RSN IE to be sent in + // Beacon and Probe + // Response frames + tSirNwType nwType; // Indicates 11a/b/g + tSirMacRateSet operationalRateSet;// Has 11a or 11b rates + tSirMacRateSet extendedRateSet; // Has 11g rates + tSirHTConfig htConfig; + +#ifdef WLAN_FEATURE_11W + tANI_BOOLEAN pmfCapable; + tANI_BOOLEAN pmfRequired; +#endif + + tSirAddIeParams addIeParams; + + tANI_BOOLEAN obssEnabled; + uint8_t sap_dot11mc; + +} tSirSmeStartBssReq, *tpSirSmeStartBssReq; + +#define GET_IE_LEN_IN_BSS(lenInBss) ( lenInBss + sizeof(lenInBss) - \ + ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields))) + +#define WSCIE_PROBE_RSP_LEN (317 + 2) + +typedef struct sSirBssDescription +{ + //offset of the ieFields from bssId. + tANI_U16 length; + tSirMacAddr bssId; + v_TIME_t scanSysTimeMsec; + tANI_U32 timeStamp[2]; + tANI_U16 beaconInterval; + tANI_U16 capabilityInfo; + tSirNwType nwType; // Indicates 11a/b/g + tANI_S8 rssi; + tANI_S8 rssi_raw; + tANI_S8 sinr; + //channelId what peer sent in beacon/probersp. + tANI_U8 channelId; + //channelId on which we are parked at. + //used only in scan case. + tANI_U8 channelIdSelf; + tANI_U8 sSirBssDescriptionRsvd[3]; + tANI_TIMESTAMP nReceivedTime; //base on a tick count. It is a time stamp, not a relative time. +#if defined WLAN_FEATURE_VOWIFI + tANI_U32 parentTSF; + tANI_U32 startTSF[2]; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdiePresent; + tANI_U8 mdie[SIR_MDIE_SIZE]; // MDIE for 11r, picked from the beacons +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U16 QBSSLoad_present; + tANI_U16 QBSSLoad_avail; + tANI_U32 reservedPadding5; // To achieve 8-byte alignment with ESE enabled +#endif + // Please keep the structure 4 bytes aligned above the ieFields + + tANI_U8 fProbeRsp; //whether it is from a probe rsp + tANI_U8 reservedPadding1; + tANI_U8 reservedPadding2; + tANI_U8 reservedPadding3; + tANI_U32 WscIeLen; + tANI_U8 WscIeProbeRsp[WSCIE_PROBE_RSP_LEN]; + tANI_U8 reservedPadding4; + + tANI_U32 ieFields[1]; +} tSirBssDescription, *tpSirBssDescription; + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +typedef struct sSirSmeHTProfile +{ + tANI_U8 dot11mode; + tANI_U8 htCapability; + tANI_U8 htSupportedChannelWidthSet; + tANI_U8 htRecommendedTxWidthSet; + ePhyChanBondState htSecondaryChannelOffset; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability; + tANI_U8 vhtTxChannelWidthSet; + tANI_U8 apCenterChan; + tANI_U8 apChanWidth; +#endif +} tSirSmeHTProfile; +#endif +/// Definition for response message to previously +/// issued start BSS request +/// MAC ---> +typedef struct sSirSmeStartBssRsp +{ + tANI_U16 messageType; // eWNI_SME_START_BSS_RSP + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 transactionId;//transaction ID for cmd + tSirResultCodes statusCode; + tSirBssType bssType;//Add new type for WDS mode + tANI_U16 beaconInterval;//Beacon Interval for both type + tANI_U32 staId; /* Station ID for Self */ +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tSirSmeHTProfile HTProfile; +#endif + tSirBssDescription bssDescription;//Peer BSS description +} tSirSmeStartBssRsp, *tpSirSmeStartBssRsp; + + +typedef struct sSirChannelList +{ + tANI_U8 numChannels; + tANI_U8 channelNumber[SIR_ESE_MAX_MEAS_IE_REQS]; +} tSirChannelList, *tpSirChannelList; + +typedef struct sSirDFSChannelList +{ + tANI_U32 timeStamp[SIR_MAX_24G_5G_CHANNEL_RANGE]; + +} tSirDFSChannelList, *tpSirDFSChannelList; + +#ifdef FEATURE_WLAN_ESE +typedef struct sTspecInfo { + tANI_U8 valid; + tSirMacTspecIE tspec; +} tTspecInfo; + +#define SIR_ESE_MAX_TSPEC_IES 4 +typedef struct sESETspecTspecInfo { + tANI_U8 numTspecs; + tTspecInfo tspec[SIR_ESE_MAX_TSPEC_IES]; +} tESETspecInfo; +#endif + + +/// Definition for Radar Info +typedef struct sSirRadarInfo +{ + tANI_U8 channelNumber; + tANI_U16 radarPulseWidth; // in usecond + tANI_U16 numRadarPulse; +} tSirRadarInfo, *tpSirRadarInfo; + +#define SIR_RADAR_INFO_SIZE (sizeof(tANI_U8) + 2 *sizeof(tANI_U16)) + +/// Two Background Scan mode +typedef enum eSirBackgroundScanMode +{ + eSIR_AGGRESSIVE_BACKGROUND_SCAN = 0, + eSIR_NORMAL_BACKGROUND_SCAN = 1, + eSIR_ROAMING_SCAN = 2, +} tSirBackgroundScanMode; + +/// Two types of traffic check +typedef enum eSirLinkTrafficCheck +{ + eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 0, + eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 1, + eSIR_CHECK_ROAMING_SCAN = 2, +} tSirLinkTrafficCheck; + +#define SIR_BG_SCAN_RETURN_CACHED_RESULTS 0x0 +#define SIR_BG_SCAN_PURGE_RESUTLS 0x80 +#define SIR_BG_SCAN_RETURN_FRESH_RESULTS 0x01 +#define SIR_SCAN_MAX_NUM_SSID 0x0A +#define SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS 0x02 +#define SIR_BG_SCAN_PURGE_LFR_RESULTS 0x40 + +/// Definition for scan request +typedef struct sSirSmeScanReq +{ + tANI_U16 messageType; // eWNI_SME_SCAN_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tSirMacAddr selfMacAddr; //Added For BT-AMP Support + tSirBssType bssType; + tANI_U8 dot11mode; + tSirScanType scanType; + /** + * minChannelTime. Not used if scanType is passive. + * 0x0 - Dont Use min channel timer. Only max channel timeout will used. + * 11k measurements set this to zero to user only single duration for scan. + * - Timeout value used for min channel timeout. + */ + tANI_U32 minChannelTime; + /** + * maxChannelTime. + * 0x0 - Invalid. In case of active scan. + * In case of passive scan, MAX( maxChannelTime, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME) is used. + * + */ + tANI_U32 maxChannelTime; + /** + * returnAfterFirstMatch can take following values: + * 0x00 - Return SCAN_RSP message after complete channel scan + * 0x01 - Return SCAN_RSP message after collecting BSS description + * that matches scan criteria. + * 0xC0 - Return after collecting first 11d IE from 2.4 GHz & + * 5 GHz band channels + * 0x80 - Return after collecting first 11d IE from 5 GHz band + * channels + * 0x40 - Return after collecting first 11d IE from 2.4 GHz + * band channels + * + * Values of 0xC0, 0x80 & 0x40 are to be used by + * Roaming/application when 11d is enabled. + */ + tANI_U32 minChannelTimeBtc; //in units of milliseconds + tANI_U32 maxChannelTimeBtc; //in units of milliseconds + tANI_U32 restTime; //in units of milliseconds, ignored when not connected + tANI_U8 returnAfterFirstMatch; + + /** + * returnUniqueResults can take following values: + * 0 - Collect & report all received BSS descriptions from same BSS. + * 1 - Collect & report unique BSS description from same BSS. + */ + tANI_U8 returnUniqueResults; + + /** + * returnFreshResults can take following values: + * 0x00 - Return background scan results. + * 0x80 - Return & purge background scan results + * 0x01 - Trigger fresh scan instead of returning background scan + * results. + * 0x81 - Trigger fresh scan instead of returning background scan + * results and purge background scan results. + */ + tANI_U8 returnFreshResults; + + /* backgroundScanMode can take following values: + * 0x0 - agressive scan + * 0x1 - normal scan where HAL will check for link traffic + * prior to proceeding with the scan + */ + tSirBackgroundScanMode backgroundScanMode; + + tANI_U8 hiddenSsid; + + /* Number of SSIDs to scan */ + tANI_U8 numSsid; + + //channelList has to be the last member of this structure. Check tSirChannelList for the reason. + /* This MUST be the last field of the structure */ + + + tANI_BOOLEAN p2pSearch; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + + //channelList MUST be the last field of this structure + tSirChannelList channelList; + /*----------------------------- + tSirSmeScanReq.... + ----------------------------- + uIEFiledLen + ----------------------------- + uIEFiledOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEFiled + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tSirSmeScanReq, *tpSirSmeScanReq; + +typedef struct sSirSmeScanAbortReq +{ + tANI_U16 type; + tANI_U16 msgLen; + tANI_U8 sessionId; +} tSirSmeScanAbortReq, *tpSirSmeScanAbortReq; + +typedef struct sSirSmeScanChanReq +{ + tANI_U16 type; + tANI_U16 msgLen; + tANI_U8 sessionId; + tANI_U16 transcationId; +} tSirSmeGetScanChanReq, *tpSirSmeGetScanChanReq; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +typedef struct sSirOemDataReq +{ + tANI_U16 messageType; //eWNI_SME_OEM_DATA_REQ + tANI_U16 messageLen; + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tSirOemDataReq, *tpSirOemDataReq; + +typedef struct sSirOemDataRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tSirOemDataRsp, *tpSirOemDataRsp; + +#endif //FEATURE_OEM_DATA_SUPPORT + +/// Definition for response message to previously issued scan request +typedef struct sSirSmeScanRsp +{ + tANI_U16 messageType; // eWNI_SME_SCAN_RSP + tANI_U16 length; + tANI_U8 sessionId; + tSirResultCodes statusCode; + tANI_U16 transcationId; + tSirBssDescription bssDescription[1]; +} tSirSmeScanRsp, *tpSirSmeScanRsp; + +/// Sme Req message to set the Background Scan mode +typedef struct sSirSmeBackgroundScanModeReq +{ + tANI_U16 messageType; // eWNI_SME_BACKGROUND_SCAN_MODE_REQ + tANI_U16 length; + tSirBackgroundScanMode mode; +} tSirSmeBackgroundScanModeReq, *tpSirSmeBackgroundScanModeReq; + +/// Background Scan Statisics +typedef struct sSirBackgroundScanInfo { + tANI_U32 numOfScanSuccess; + tANI_U32 numOfScanFailure; + tANI_U32 reserved; +} tSirBackgroundScanInfo, *tpSirBackgroundScanInfo; + +#define SIR_BACKGROUND_SCAN_INFO_SIZE (3 * sizeof(tANI_U32)) + +/// Definition for Join/Reassoc info - Reshmi: need to check if this is a def which moved from elsehwere. +typedef struct sJoinReassocInfo +{ + tAniTitanCBNeighborInfo cbNeighbors; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; +} tJoinReassocInfo, *tpJoinReassocInfo; + +/// Definition for join request +/// ---> MAC +/// WARNING! If you add a field in JOIN REQ. +/// Make sure to add it in REASSOC REQ +/// The Serdes function is the same and its +/// shared with REASSOC. So if we add a field +// here and dont add it in REASSOC REQ. It will BREAK!!! REASSOC. +typedef struct sSirSmeJoinReq +{ + tANI_U16 messageType; // eWNI_SME_JOIN_REQ + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 transactionId; + tSirMacSSid ssId; + tSirMacAddr selfMacAddr; // self Mac address + tSirBssType bsstype; // add new type for BT -AMP STA and AP Modules + tANI_U8 dot11mode; // to support BT-AMP +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 cc_switch_mode; +#endif + tVOS_CON_MODE staPersona; //Persona + ePhyChanBondState cbMode; // Pass CB mode value in Join. + + /*This contains the UAPSD Flag for all 4 AC + * B0: AC_VO UAPSD FLAG + * B1: AC_VI UAPSD FLAG + * B2: AC_BK UAPSD FLAG + * B3: AC_BE UASPD FLAG + */ + tANI_U8 uapsdPerAcBitmask; + + tSirMacRateSet operationalRateSet;// Has 11a or 11b rates + tSirMacRateSet extendedRateSet; // Has 11g rates + tSirRSNie rsnIE; // RSN IE to be sent in + // (Re) Association Request +#ifdef FEATURE_WLAN_ESE + tSirCCKMie cckmIE; // CCMK IE to be included as handler for join and reassoc is + // the same. The join will never carry cckm, but will be set to + // 0. +#endif + + tSirAddie addIEScan; // Additional IE to be sent in + // (unicast) Probe Request at the time of join + + tSirAddie addIEAssoc; // Additional IE to be sent in + // (Re) Association Request + + tAniEdType UCEncryptionType; + + tAniEdType MCEncryptionType; + +#ifdef WLAN_FEATURE_11W + tAniEdType MgmtEncryptionType; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + tAniBool is11Rconnection; +#endif +#ifdef FEATURE_WLAN_ESE + tAniBool isESEFeatureIniEnabled; + tAniBool isESEconnection; + tESETspecInfo eseTspecInfo; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tAniBool isFastTransitionEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tAniBool isFastRoamIniFeatureEnabled; +#endif + + tANI_U8 txLdpcIniFeatureEnabled; + tSirHTConfig htConfig; +#ifdef WLAN_FEATURE_11AC + tANI_U8 txBFIniFeatureEnabled; + tANI_U8 txBFCsnValue; + tANI_U8 txMuBformee; + tANI_U8 enableVhtpAid; + tANI_U8 enableVhtGid; +#endif + tANI_U8 enableAmpduPs; + tANI_U8 enableHtSmps; + tANI_U8 htSmps; + + tANI_U8 isAmsduSupportInAMPDU; + tAniBool isWMEenabled; + tAniBool isQosEnabled; + tAniBool isOSENConnection; + tAniTitanCBNeighborInfo cbNeighbors; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + tSirBssDescription bssDescription; + +} tSirSmeJoinReq, *tpSirSmeJoinReq; + +/// Definition for reponse message to previously issued join request +/// MAC ---> +typedef struct sSirSmeJoinRsp +{ + tANI_U16 messageType; // eWNI_SME_JOIN_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tAniAuthType authType; + tANI_U16 protStatusCode; //It holds reasonCode when join fails due to deauth/disassoc frame. + //Otherwise it holds status code. + tANI_U16 aid; + tANI_U32 beaconLength; + tANI_U32 assocReqLength; + tANI_U32 assocRspLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 parsedRicRspLen; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 tspecIeLen; +#endif + tANI_U32 staId;//Station ID for peer + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + /* Timing and fine Timing measurement capability clubbed together */ + tANI_U8 timingMeasCap; + +#ifdef FEATURE_WLAN_TDLS + /* TDLS prohibited and TDLS channel switch prohibited are set as + * per ExtCap IE in received assoc/re-assoc response from AP + */ + bool tdls_prohibited; + bool tdls_chan_swit_prohibited; +#endif + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tSirSmeHTProfile HTProfile; +#endif + + tANI_U8 frames[ 1 ]; +} tSirSmeJoinRsp, *tpSirSmeJoinRsp; + +/// Definition for Authentication indication from peer +typedef struct sSirSmeAuthInd +{ + tANI_U16 messageType; // eWNI_SME_AUTH_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tAniAuthType authType; +} tSirSmeAuthInd, *tpSirSmeAuthInd; + +/// probereq from peer, when wsc is enabled +typedef struct sSirSmeProbereq +{ + tANI_U16 messageType; // eWNI_SME_PROBE_REQ + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr peerMacAddr; + tANI_U16 devicePasswdId; +} tSirSmeProbeReq, *tpSirSmeProbeReq; + +typedef struct sSirSmeChanInfo +{ + /* channel id */ + tANI_U8 chan_id; + /* primary 20 MHz channel frequency in mhz */ + tANI_U32 mhz; + /* Center frequency 1 in MHz */ + tANI_U32 band_center_freq1; + /* Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode */ + tANI_U32 band_center_freq2; + /* channel info described below */ + tANI_U32 info; + /* contains min power, max power, reg power and reg class id */ + tANI_U32 reg_info_1; + /* contains antennamax */ + tANI_U32 reg_info_2; +} tSirSmeChanInfo, *tpSirSmeChanInfo; +/// Definition for Association indication from peer +/// MAC ---> +typedef struct sSirSmeAssocInd +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr bssId; // Self BSSID + tANI_U16 staId; // Station ID for peer + tANI_U8 uniSig; // DPU signature for unicast packets + tANI_U8 bcastSig; // DPU signature for broadcast packets + tAniAuthType authType; + tAniSSID ssId; // SSID used by STA to associate + tSirRSNie rsnIE;// RSN IE received from peer + tSirAddie addIE;// Additional IE received from peer, which possibly include WSC IE and/or P2P IE + + // powerCap & supportedChannels are present only when + // spectrumMgtIndicator flag is set + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + tAniBool wmmEnabledSta; /* if present - STA is WMM enabled */ + tAniBool reassocReq; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + + /* Timing and fine Timing measurement capability clubbed together */ + tANI_U8 timingMeasCap; + tSirSmeChanInfo chan_info; +} tSirSmeAssocInd, *tpSirSmeAssocInd; + + +/// Definition for Association confirm +/// ---> MAC +typedef struct sSirSmeAssocCnf +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; +} tSirSmeAssocCnf, *tpSirSmeAssocCnf; + +/// Definition for Reassociation indication from peer +typedef struct sSirSmeReassocInd +{ + tANI_U16 messageType; // eWNI_SME_REASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirMacAddr peerMacAddr; + tSirMacAddr oldMacAddr; + tANI_U16 aid; + tSirMacAddr bssId; // Self BSSID + tANI_U16 staId; // Station ID for peer + tAniAuthType authType; + tAniSSID ssId; // SSID used by STA to reassociate + tSirRSNie rsnIE; // RSN IE received from peer + + tSirAddie addIE; // Additional IE received from peer + + // powerCap & supportedChannels are present only when + // spectrumMgtIndicator flag is set + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + // Required for indicating the frames to upper layer + // TODO: use the appropriate names to distinguish between the other similar names used above for station mode of operation + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; +} tSirSmeReassocInd, *tpSirSmeReassocInd; + +/// Definition for Reassociation confirm +/// ---> MAC +typedef struct sSirSmeReassocCnf +{ + tANI_U16 messageType; // eWNI_SME_REASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; +} tSirSmeReassocCnf, *tpSirSmeReassocCnf; + + +/// Enum definition for Wireless medium status change codes +typedef enum eSirSmeStatusChangeCode +{ + eSIR_SME_DEAUTH_FROM_PEER, + eSIR_SME_DISASSOC_FROM_PEER, + eSIR_SME_LOST_LINK_WITH_PEER, + eSIR_SME_CHANNEL_SWITCH, + eSIR_SME_JOINED_NEW_BSS, + eSIR_SME_LEAVING_BSS, + eSIR_SME_IBSS_ACTIVE, + eSIR_SME_IBSS_INACTIVE, + eSIR_SME_IBSS_PEER_DEPARTED, + eSIR_SME_RADAR_DETECTED, + eSIR_SME_IBSS_NEW_PEER, + eSIR_SME_AP_CAPS_CHANGED, + eSIR_SME_BACKGROUND_SCAN_FAIL, + eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP, + eSIR_SME_CB_LEGACY_BSS_FOUND_BY_STA +} tSirSmeStatusChangeCode; + +typedef struct sSirSmeNewBssInfo +{ + tSirMacAddr bssId; + tANI_U8 channelNumber; + tANI_U8 reserved; + tSirMacSSid ssId; +} tSirSmeNewBssInfo, *tpSirSmeNewBssInfo; + +typedef struct sSirSmeApNewCaps +{ + tANI_U16 capabilityInfo; + tSirMacAddr bssId; + tANI_U8 channelId; + tANI_U8 reserved[3]; + tSirMacSSid ssId; +} tSirSmeApNewCaps, *tpSirSmeApNewCaps; + +/** + * Table below indicates what information is passed for each of + * the Wireless Media status change notifications: + * + * Status Change code Status change info + * ---------------------------------------------------------------------- + * eSIR_SME_DEAUTH_FROM_PEER Reason code received in DEAUTH frame + * eSIR_SME_DISASSOC_FROM_PEER Reason code received in DISASSOC frame + * eSIR_SME_LOST_LINK_WITH_PEER None + * eSIR_SME_CHANNEL_SWITCH New channel number + * eSIR_SME_JOINED_NEW_BSS BSSID, SSID and channel number + * eSIR_SME_LEAVING_BSS None + * eSIR_SME_IBSS_ACTIVE Indicates that another STA joined + * IBSS apart from this STA that + * started IBSS + * eSIR_SME_IBSS_INACTIVE Indicates that only this STA is left + * in IBSS + * eSIR_SME_RADAR_DETECTED Indicates that radar is detected + * eSIR_SME_IBSS_NEW_PEER Indicates that a new peer is detected + * eSIR_SME_AP_CAPS_CHANGED Indicates that capabilities of the AP + * that STA is currently associated with + * have changed. + * eSIR_SME_BACKGROUND_SCAN_FAIL Indicates background scan failure + */ + +/// Definition for Wireless medium status change notification +typedef struct sSirSmeWmStatusChangeNtf +{ + tANI_U16 messageType; // eWNI_SME_WM_STATUS_CHANGE_NTF + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirSmeStatusChangeCode statusChangeCode; + tSirMacAddr bssId; // Self BSSID + union + { + tANI_U16 deAuthReasonCode; // eSIR_SME_DEAUTH_FROM_PEER + tANI_U16 disassocReasonCode; // eSIR_SME_DISASSOC_FROM_PEER + // none for eSIR_SME_LOST_LINK_WITH_PEER + tANI_U8 newChannelId; // eSIR_SME_CHANNEL_SWITCH + tSirSmeNewBssInfo newBssInfo; // eSIR_SME_JOINED_NEW_BSS + // none for eSIR_SME_LEAVING_BSS + // none for eSIR_SME_IBSS_ACTIVE + // none for eSIR_SME_IBSS_INACTIVE + tSirNewIbssPeerInfo newIbssPeerInfo; // eSIR_SME_IBSS_NEW_PEER + tSirSmeApNewCaps apNewCaps; // eSIR_SME_AP_CAPS_CHANGED + tSirBackgroundScanInfo bkgndScanInfo; // eSIR_SME_BACKGROUND_SCAN_FAIL + tAniTitanCBNeighborInfo cbNeighbors; // eSIR_SME_CB_LEGACY_BSS_FOUND_BY_STA + } statusChangeInfo; +} tSirSmeWmStatusChangeNtf, *tpSirSmeWmStatusChangeNtf; + +/// Definition for Disassociation request +typedef +__ani_attr_pre_packed +struct sSirSmeDisassocReq +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // Peer BSSID + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U8 doNotSendOverTheAir; //This flag tells LIM whether to send the disassoc OTA or not + //This will be set in while handing off from one AP to other +} +__ani_attr_packed +tSirSmeDisassocReq, *tpSirSmeDisassocReq; + +/// Definition for Tkip countermeasures request +typedef __ani_attr_pre_packed struct sSirSmeTkipCntrMeasReq +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // Peer BSSID + tANI_BOOLEAN bEnable; // Start/stop countermeasures +} __ani_attr_packed tSirSmeTkipCntrMeasReq, *tpSirSmeTkipCntrMeasReq; + +typedef struct sAni64BitCounters +{ + tANI_U32 Hi; + tANI_U32 Lo; +}tAni64BitCounters, *tpAni64BitCounters; + +typedef struct sAniSecurityStat +{ + tAni64BitCounters txBlks; + tAni64BitCounters rxBlks; + tAni64BitCounters formatErrorCnt; + tAni64BitCounters decryptErr; + tAni64BitCounters protExclCnt; + tAni64BitCounters unDecryptableCnt; + tAni64BitCounters decryptOkCnt; + +}tAniSecurityStat, *tpAniSecurityStat; + +typedef struct sAniTxRxCounters +{ + tANI_U32 txFrames; // Incremented for every packet tx + tANI_U32 rxFrames; + tANI_U32 nRcvBytes; + tANI_U32 nXmitBytes; +}tAniTxRxCounters, *tpAniTxRxCounters; + +typedef struct sAniTxRxStats +{ + tAni64BitCounters txFrames; + tAni64BitCounters rxFrames; + tAni64BitCounters nRcvBytes; + tAni64BitCounters nXmitBytes; + +}tAniTxRxStats,*tpAniTxRxStats; + +typedef struct sAniSecStats +{ + tAniSecurityStat aes; + tAni64BitCounters aesReplays; + tAniSecurityStat tkip; + tAni64BitCounters tkipReplays; + tAni64BitCounters tkipMicError; + + tAniSecurityStat wep; +#if defined(FEATURE_WLAN_WAPI) && !defined(LIBRA_WAPI_SUPPORT) + tAniSecurityStat wpi; + tAni64BitCounters wpiReplays; + tAni64BitCounters wpiMicError; +#endif +}tAniSecStats, *tpAniSecStats; + +#define SIR_MAX_RX_CHAINS 3 + +typedef struct sAniStaStatStruct +{ + /* following statistic elements till expandPktRxCntLo are not filled with valid data. + * These are kept as it is, since WSM is using this structure. + * These elements can be removed whenever WSM is updated. + * Phystats is used to hold phystats from BD. + */ + tANI_U32 sentAesBlksUcastHi; + tANI_U32 sentAesBlksUcastLo; + tANI_U32 recvAesBlksUcastHi; + tANI_U32 recvAesBlksUcastLo; + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + tANI_U32 singleRetryPkts; + tANI_U32 failedTxPkts; + tANI_U32 ackTimeouts; + tANI_U32 multiRetryPkts; + tANI_U32 fragTxCntsHi; + tANI_U32 fragTxCntsLo; + tANI_U32 transmittedPktsHi; + tANI_U32 transmittedPktsLo; + tANI_U32 phyStatHi; //These are used to fill in the phystats. + tANI_U32 phyStatLo; //This is only for private use. + + tANI_U32 uplinkRssi; + tANI_U32 uplinkSinr; + tANI_U32 uplinkRate; + tANI_U32 downlinkRssi; + tANI_U32 downlinkSinr; + tANI_U32 downlinkRate; + tANI_U32 nRcvBytes; + tANI_U32 nXmitBytes; + + // titan 3c stats + tANI_U32 chunksTxCntHi; // Number of Chunks Transmitted + tANI_U32 chunksTxCntLo; + tANI_U32 compPktRxCntHi; // Number of Packets Received that were actually compressed + tANI_U32 compPktRxCntLo; + tANI_U32 expanPktRxCntHi; // Number of Packets Received that got expanded + tANI_U32 expanPktRxCntLo; + + + /* Following elements are valid and filled in correctly. They have valid values. + */ + + //Unicast frames and bytes. + tAniTxRxStats ucStats; + + //Broadcast frames and bytes. + tAniTxRxStats bcStats; + + //Multicast frames and bytes. + tAniTxRxStats mcStats; + + tANI_U32 currentTxRate; + tANI_U32 currentRxRate; //Rate in 100Kbps + + tANI_U32 maxTxRate; + tANI_U32 maxRxRate; + + tANI_S8 rssi[SIR_MAX_RX_CHAINS]; + + + tAniSecStats securityStats; + + tANI_U8 currentRxRateIdx; //This the softmac rate Index. + tANI_U8 currentTxRateIdx; + +} tAniStaStatStruct, *tpAniStaStatStruct; + +//Statistics that are not maintained per stations. +typedef struct sAniGlobalStatStruct +{ + tAni64BitCounters txError; + tAni64BitCounters rxError; + tAni64BitCounters rxDropNoBuffer; + tAni64BitCounters rxDropDup; + tAni64BitCounters rxCRCError; + + tAni64BitCounters singleRetryPkts; + tAni64BitCounters failedTxPkts; + tAni64BitCounters ackTimeouts; + tAni64BitCounters multiRetryPkts; + tAni64BitCounters fragTxCnts; + tAni64BitCounters fragRxCnts; + + tAni64BitCounters txRTSSuccess; + tAni64BitCounters txCTSSuccess; + tAni64BitCounters rxRTSSuccess; + tAni64BitCounters rxCTSSuccess; + + tAniSecStats securityStats; + + tAniTxRxStats mcStats; + tAniTxRxStats bcStats; + +}tAniGlobalStatStruct,*tpAniGlobalStatStruct; + +typedef enum sPacketType +{ + ePACKET_TYPE_UNKNOWN, + ePACKET_TYPE_11A, + ePACKET_TYPE_11G, + ePACKET_TYPE_11B, + ePACKET_TYPE_11N + +}tPacketType, *tpPacketType; + +typedef struct sAniStatSummaryStruct +{ + tAniTxRxStats uc; //Unicast counters. + tAniTxRxStats bc; //Broadcast counters. + tAniTxRxStats mc; //Multicast counters. + tAni64BitCounters txError; + tAni64BitCounters rxError; + tANI_S8 rssi[SIR_MAX_RX_CHAINS]; //For each chain. + tANI_U32 rxRate; // Rx rate of the last received packet. + tANI_U32 txRate; + tANI_U16 rxMCSId; //MCS index is valid only when packet type is ePACKET_TYPE_11N + tANI_U16 txMCSId; + tPacketType rxPacketType; + tPacketType txPacketType; + tSirMacAddr macAddr; //Mac Address of the station from which above RSSI and rate is from. +}tAniStatSummaryStruct,*tpAniStatSummaryStruct; + +//structure for stats that may be reset, like the ones in sta descriptor +//The stats are saved into here before reset. It should be tANI_U32 aligned. +typedef struct _sPermStaStats +{ + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + tANI_U32 singleRetryPkts; + tANI_U32 failedTxPkts; + tANI_U32 ackTimeouts; + tANI_U32 multiRetryPkts; + tANI_U32 fragTxCntsHi; + tANI_U32 fragTxCntsLo; + tANI_U32 transmittedPktsHi; + tANI_U32 transmittedPktsLo; + + // titan 3c stats + tANI_U32 chunksTxCntHi; // Number of Chunks Transmitted + tANI_U32 chunksTxCntLo; + tANI_U32 compPktRxCntHi; // Number of Packets Received that were actually compressed + tANI_U32 compPktRxCntLo; + tANI_U32 expanPktRxCntHi; // Number of Packets Received that got expanded + tANI_U32 expanPktRxCntLo; +}tPermanentStaStats; + + + + +/// Definition for Disassociation response +typedef struct sSirSmeDisassocRsp +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; + tAniStaStatStruct perStaStats; // STA stats + tANI_U16 staId; +} +__ani_attr_packed + tSirSmeDisassocRsp, *tpSirSmeDisassocRsp; + +/// Definition for Disassociation indication from peer +typedef struct sSirSmeDisassocInd +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; // Session Identifier + tANI_U16 transactionId; // Transaction Identifier with PE + tSirResultCodes statusCode; + tSirMacAddr bssId; + tSirMacAddr peerMacAddr; + tAniStaStatStruct perStaStats; // STA stats + tANI_U16 staId; + tANI_U32 reasonCode; +} tSirSmeDisassocInd, *tpSirSmeDisassocInd; + +/// Definition for Disassociation confirm +/// MAC ---> +typedef struct sSirSmeDisassocCnf +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; + tSirMacAddr peerMacAddr; +} tSirSmeDisassocCnf, *tpSirSmeDisassocCnf; + +/// Definition for Deauthetication request +typedef struct sSirSmeDeauthReq +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // AP BSSID + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; +} tSirSmeDeauthReq, *tpSirSmeDeauthReq; + +/// Definition for Deauthetication response +typedef struct sSirSmeDeauthRsp +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeDeauthRsp, *tpSirSmeDeauthRsp; + +/// Definition for Deauthetication indication from peer +typedef struct sSirSmeDeauthInd +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_IND + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP + tANI_U16 transactionId; //Added for BT-AMP + tSirResultCodes statusCode; + tSirMacAddr bssId;// AP BSSID + tSirMacAddr peerMacAddr; + + tANI_U16 staId; + tANI_U32 reasonCode; +} tSirSmeDeauthInd, *tpSirSmeDeauthInd; + +/// Definition for Deauthentication confirm +/// MAC ---> +typedef struct sSirSmeDeauthCnf +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // AP BSSID + tSirMacAddr peerMacAddr; +} tSirSmeDeauthCnf, *tpSirSmeDeauthCnf; + +/// Definition for stop BSS request message +typedef struct sSirSmeStopBssReq +{ + tANI_U16 messageType; // eWNI_SME_STOP_BSS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; //tranSaction ID for cmd + tSirResultCodes reasonCode; + tSirMacAddr bssId; //Self BSSID +} tSirSmeStopBssReq, *tpSirSmeStopBssReq; + +/// Definition for stop BSS response message +typedef struct sSirSmeStopBssRsp +{ + tANI_U16 messageType; // eWNI_SME_STOP_BSS_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeStopBssRsp, *tpSirSmeStopBssRsp; + + + +/// Definition for Channel Switch indication for station +/// MAC ---> +typedef struct sSirSmeSwitchChannelInd +{ + tANI_U16 messageType; // eWNI_SME_SWITCH_CHL_REQ + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 newChannelId; + tSirMacAddr bssId; // BSSID +} tSirSmeSwitchChannelInd, *tpSirSmeSwitchChannelInd; + +/// Definition for ULA complete indication message +typedef struct sirUlaCompleteInd +{ + tANI_U16 messageType; // eWNI_ULA_COMPLETE_IND + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirUlaCompleteInd, *tpSirUlaCompleteInd; + +/// Definition for ULA complete confirmation message +typedef struct sirUlaCompleteCnf +{ + tANI_U16 messageType; // eWNI_ULA_COMPLETE_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirUlaCompleteCnf, *tpSirUlaCompleteCnf; + +/// Definition for Neighbor BSS indication +/// MAC ---> +/// MAC reports this each time a new I/BSS is detected +typedef struct sSirSmeNeighborBssInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_BSS_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirBssDescription bssDescription[1]; +} tSirSmeNeighborBssInd, *tpSirSmeNeighborBssInd; + +/// Definition for MIC failure indication +/// MAC ---> +/// MAC reports this each time a MIC failure occures on Rx TKIP packet +typedef struct sSirSmeMicFailureInd +{ + tANI_U16 messageType; // eWNI_SME_MIC_FAILURE_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; // BSSID + tSirMicFailureInfo info; +} tSirSmeMicFailureInd, *tpSirSmeMicFailureInd; + +typedef struct sSirSmeMissedBeaconInd +{ + tANI_U16 messageType; // eWNI_SME_MISSED_BEACON_IND + tANI_U16 length; + tANI_U8 bssIdx; +} tSirSmeMissedBeaconInd, *tpSirSmeMissedBeaconInd; + +/// Definition for Set Context request +/// ---> MAC +typedef struct sSirSmeSetContextReq +{ + tANI_U16 messageType; // eWNI_SME_SET_CONTEXT_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr peerMacAddr; + tSirMacAddr bssId; // BSSID + tSirKeyMaterial keyMaterial; +} tSirSmeSetContextReq, *tpSirSmeSetContextReq; + +/// Definition for Set Context response +/// MAC ---> +typedef struct sSirSmeSetContextRsp +{ + tANI_U16 messageType; // eWNI_SME_SET_CONTEXT_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeSetContextRsp, *tpSirSmeSetContextRsp; + +/// Definition for Remove Key Context request +/// ---> MAC +typedef struct sSirSmeRemoveKeyReq +{ + tANI_U16 messageType; // eWNI_SME_REMOVE_KEY_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tSirMacAddr peerMacAddr; + tANI_U8 edType; + tANI_U8 wepType; + tANI_U8 keyId; + tANI_BOOLEAN unicast; +} tSirSmeRemoveKeyReq, *tpSirSmeRemoveKeyReq; + +/// Definition for Remove Key Context response +/// MAC ---> +typedef struct sSirSmeRemoveKeyRsp +{ + tANI_U16 messageType; // eWNI_SME_REMOVE_KEY_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeRemoveKeyRsp, *tpSirSmeRemoveKeyRsp; + +/// Definition for Set Power request +/// ---> MAC +typedef struct sSirSmeSetPowerReq +{ + tANI_U16 messageType; // eWNI_SME_SET_POWER_REQ + tANI_U16 length; + tANI_U16 transactionId; // Transaction ID for cmd + tANI_S8 powerLevel; +} tSirSmeSetPowerReq, *tpSirSmeSetPowerReq; + +/// Definition for Set Power response +/// MAC ---> +typedef struct sSirSmeSetPowerRsp +{ + tANI_U16 messageType; // eWNI_SME_SET_POWER_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeSetPowerRsp, *tpSirSmeSetPowerRsp; + + +/// Definition for Link Test Start response +/// MAC ---> +typedef struct sSirSmeLinkTestStartRsp +{ + tANI_U16 messageType; // eWNI_SME_LINK_TEST_START_RSP + tANI_U16 length; + tSirMacAddr peerMacAddr; + tSirResultCodes statusCode; +} tSirSmeLinkTestStartRsp, *tpSirSmeLinkTestStartRsp; + +/// Definition for Link Test Stop response +/// WSM ---> MAC +typedef struct sSirSmeLinkTestStopRsp +{ + tANI_U16 messageType; // eWNI_SME_LINK_TEST_STOP_RSP + tANI_U16 length; + tSirMacAddr peerMacAddr; + tSirResultCodes statusCode; +} tSirSmeLinkTestStopRsp, *tpSirSmeLinkTestStopRsp; + +/// Definition for kick starting DFS measurements +typedef struct sSirSmeDFSreq +{ + tANI_U16 messageType; // eWNI_SME_DFS_REQ + tANI_U16 length; + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeDFSrequest, *tpSirSmeDFSrequest; + +/// Definition for response message to previously +/// issued DFS request +typedef struct sSirSmeDFSrsp +{ + tANI_U16 messageType; // eWNI_SME_DFS_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U32 dfsReport[1]; +} tSirSmeDFSrsp, *tpSirSmeDFSrsp; + +/// Statistic definitions +//============================================================= +// Per STA statistic structure; This same struct will be used for Aggregate +// STA stats as well. + +// Clear radio stats and clear per sta stats +typedef enum +{ + eANI_CLEAR_ALL_STATS, // Clears all stats + eANI_CLEAR_RX_STATS, // Clears RX statistics of the radio interface + eANI_CLEAR_TX_STATS, // Clears TX statistics of the radio interface + eANI_CLEAR_RADIO_STATS, // Clears all the radio stats + eANI_CLEAR_PER_STA_STATS, // Clears Per STA stats + eANI_CLEAR_AGGR_PER_STA_STATS, // Clears aggregate stats + + // Used to distinguish between per sta to security stats. + // Used only by AP, FW just returns the same parameter as it received. + eANI_LINK_STATS, // Get Per STA stats + eANI_SECURITY_STATS, // Get Per STA security stats + + eANI_CLEAR_STAT_TYPES_END +} tAniStatSubTypes; + +typedef struct sAniTxCtrs +{ + // add the rate counters here + tANI_U32 tx1Mbps; + tANI_U32 tx2Mbps; + tANI_U32 tx5_5Mbps; + tANI_U32 tx6Mbps; + tANI_U32 tx9Mbps; + tANI_U32 tx11Mbps; + tANI_U32 tx12Mbps; + tANI_U32 tx18Mbps; + tANI_U32 tx24Mbps; + tANI_U32 tx36Mbps; + tANI_U32 tx48Mbps; + tANI_U32 tx54Mbps; + tANI_U32 tx72Mbps; + tANI_U32 tx96Mbps; + tANI_U32 tx108Mbps; + + // tx path radio counts + tANI_U32 txFragHi; + tANI_U32 txFragLo; + tANI_U32 txFrameHi; + tANI_U32 txFrameLo; + tANI_U32 txMulticastFrameHi; + tANI_U32 txMulticastFrameLo; + tANI_U32 txFailedHi; + tANI_U32 txFailedLo; + tANI_U32 multipleRetryHi; + tANI_U32 multipleRetryLo; + tANI_U32 singleRetryHi; + tANI_U32 singleRetryLo; + tANI_U32 ackFailureHi; + tANI_U32 ackFailureLo; + tANI_U32 xmitBeacons; + + // titan 3c stats + tANI_U32 txCbEscPktCntHi; // Total Number of Channel Bonded/Escort Packet Transmitted + tANI_U32 txCbEscPktCntLo; + tANI_U32 txChunksCntHi; // Total Number of Chunks Transmitted + tANI_U32 txChunksCntLo; + tANI_U32 txCompPktCntHi; // Total Number of Compresssed Packet Transmitted + tANI_U32 txCompPktCntLo; + tANI_U32 tx50PerCompPktCntHi; // Total Number of Packets with 50% or more compression + tANI_U32 tx50PerCompPktCntLo; + tANI_U32 txExpanPktCntHi; // Total Number of Packets Transmitted that got expanded + tANI_U32 txExpanPktCntLo; +} tAniTxCtrs, *tpAniTxCtrs; + +typedef struct sAniRxCtrs +{ + // receive frame rate counters + tANI_U32 rx1Mbps; + tANI_U32 rx2Mbps; + tANI_U32 rx5_5Mbps; + tANI_U32 rx6Mbps; + tANI_U32 rx9Mbps; + tANI_U32 rx11Mbps; + tANI_U32 rx12Mbps; + tANI_U32 rx18Mbps; + tANI_U32 rx24Mbps; + tANI_U32 rx36Mbps; + tANI_U32 rx48Mbps; + tANI_U32 rx54Mbps; + tANI_U32 rx72Mbps; + tANI_U32 rx96Mbps; + tANI_U32 rx108Mbps; + + // receive size counters; 'Lte' = Less than or equal to + tANI_U32 rxLte64; + tANI_U32 rxLte128Gt64; + tANI_U32 rxLte256Gt128; + tANI_U32 rxLte512Gt256; + tANI_U32 rxLte1kGt512; + tANI_U32 rxLte1518Gt1k; + tANI_U32 rxLte2kGt1518; + tANI_U32 rxLte4kGt2k; + + // rx radio stats + tANI_U32 rxFrag; + tANI_U32 rxFrame; + tANI_U32 fcsError; + tANI_U32 rxMulticast; + tANI_U32 duplicate; + tANI_U32 rtsSuccess; + tANI_U32 rtsFailed; + tANI_U32 wepUndecryptables; + tANI_U32 drops; + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + + // titan 3c stats + tANI_U32 rxDecompPktCntHi; // Total Number of Packets that got decompressed + tANI_U32 rxDecompPktCntLo; + tANI_U32 rxCompPktCntHi; // Total Number of Packets received that were actually compressed + tANI_U32 rxCompPktCntLo; + tANI_U32 rxExpanPktCntHi; // Total Number of Packets received that got expanded + tANI_U32 rxExpanPktCntLo; +} tAniRxCtrs, *tpAniRxCtrs; + +// Radio stats +typedef struct sAniRadioStats +{ + tAniTxCtrs tx; + tAniRxCtrs rx; +} tAniRadioStats, *tpAniRadioStats; + +// Get Radio Stats request structure +// This structure shall be used for both Radio stats and Aggregate stats +// A valid request must contain entire structure with/without valid fields. +// Based on the request type, the valid fields will be checked. +typedef struct sAniGetStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + // only used for clear stats and per sta stats clear + tAniStatSubTypes stat; // Clears the stats of the described types. + tANI_U32 staId; // Per STA stats request must contain valid + // values + tANI_U8 macAddr[6]; +} tAniGetStatsReq, *tpAniGetStatsReq; + +// Get Radio Stats response struct +typedef struct sAniGetRadioStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniRadioStats radio; +} tAniGetRadioStatsRsp, *tpAniGetRadioStatsRsp; + +// Per Sta stats response struct +typedef struct sAniGetPerStaStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniStatSubTypes stat; // Sub type needed by AP. Returns the same value + tAniStaStatStruct sta; + tANI_U32 staId; + tANI_U8 macAddr[6]; +} tAniGetPerStaStatsRsp, *tpAniGetPerStaStatsRsp; + +// Get Aggregate stats +typedef struct sAniGetAggrStaStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniStaStatStruct sta; +} tAniGetAggrStaStatsRsp, *tpAniGetAggrStaStatsRsp; + +// Clear stats request and response structure. 'rc' field is unused in +// request and this field is used in response field. +typedef struct sAniClearStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; // return code - will be filled by FW on + // response. + // Same transaction ID will be returned by the FW + tANI_U16 transactionId; + tAniStatSubTypes stat; // Clears the stats of the described types. + tANI_U32 staId; // Applicable only to PER STA stats clearing + tANI_U8 macAddr[6]; // Applicable only to PER STA stats clearing +} tAniClearStatsRsp, *tpAniClearStatsRsp; + +typedef struct sAniGetGlobalStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniGlobalStatStruct global; +} tAniGetGlobalStatsRsp, *tpAniGetGlobalStatsRsp; + +typedef struct sAniGetStatSummaryRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request --Why? + tANI_U32 rc; + tANI_U16 transactionId; + tAniStatSummaryStruct stat; +} tAniGetStatSummaryRsp, *tpAniGetStatSummaryRsp; + +//*************************************************************** + + +/*******************PE Statistics*************************/ +typedef enum +{ + PE_SUMMARY_STATS_INFO = 0x00000001, + PE_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + PE_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + PE_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + PE_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + PE_PER_STA_STATS_INFO = 0x00000020 +}ePEStatsMask; + +/* + * tpAniGetPEStatsReq is tied to + * for SME ==> PE eWNI_SME_GET_STATISTICS_REQ msgId and + * for PE ==> HAL SIR_HAL_GET_STATISTICS_REQ msgId + */ +typedef struct sAniGetPEStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 staId; // Per STA stats request must contain valid + tANI_U32 statsMask; // categories of stats requested. look at ePEStatsMask + tANI_U8 sessionId; +} tAniGetPEStatsReq, *tpAniGetPEStatsReq; + +/* + * tpAniGetPEStatsRsp is tied to + * for PE ==> SME eWNI_SME_GET_STATISTICS_RSP msgId and + * for HAL ==> PE SIR_HAL_GET_STATISTICS_RSP msgId + */ +typedef struct sAniGetPEStatsRsp +{ + // Common for all types are responses + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request, includes the pStatsBuf length too + tANI_U8 sessionId; + tANI_U32 rc; //success/failure + tANI_U32 staId; // Per STA stats request must contain valid + tANI_U32 statsMask; // categories of stats requested. look at ePEStatsMask +/********************************************************************************************** + //void *pStatsBuf; + The Stats buffer starts here and can be an aggregate of more than one statistics + structure depending on statsMask.The void pointer "pStatsBuf" is commented out + intentionally and the src code that uses this structure should take that into account. +**********************************************************************************************/ +} tAniGetPEStatsRsp, *tpAniGetPEStatsRsp; + +typedef struct sAniGetRssiReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 staId; + tANI_S8 lastRSSI; // in case of error, return last RSSI + void *rssiCallback; + void *pDevContext; //device context + void *pVosContext; //voss context + +} tAniGetRssiReq, *tpAniGetRssiReq; + +typedef struct sAniGetSnrReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 staId; + void *snrCallback; + void *pDevContext; //device context +} tAniGetSnrReq, *tpAniGetSnrReq; + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +typedef struct sAniGetRoamRssiRsp +{ + // Common for all types are responses + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request, includes the pStatsBuf length too + tANI_U8 sessionId; + tANI_U32 rc; //success/failure + tANI_U32 staId; // Per STA stats request must contain valid + tANI_S8 rssi; + void *rssiReq; //rssi request backup + +} tAniGetRoamRssiRsp, *tpAniGetRoamRssiRsp; + +#endif + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) +typedef struct sSirTsmIE +{ + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tSirTsmIE, *tpSirTsmIE; +typedef struct sSirSmeTsmIEInd +{ + tSirTsmIE tsmIe; + tANI_U8 sessionId; +} tSirSmeTsmIEInd, *tpSirSmeTsmIEInd; +typedef struct sAniTrafStrmMetrics +{ + tANI_U16 UplinkPktQueueDly; + tANI_U16 UplinkPktQueueDlyHist[4]; + tANI_U32 UplinkPktTxDly; + tANI_U16 UplinkPktLoss; + tANI_U16 UplinkPktCount; + tANI_U8 RoamingCount; + tANI_U16 RoamingDly; +} tAniTrafStrmMetrics, *tpAniTrafStrmMetrics; +typedef struct sAniGetTsmStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 staId; + tANI_U8 tid; // traffic id + tSirMacAddr bssId; + void *tsmStatsCallback; + void *pDevContext; //device context + void *pVosContext; //voss context +} tAniGetTsmStatsReq, *tpAniGetTsmStatsReq; +typedef struct sAniGetTsmStatsRsp +{ + // Common for all types are responses + tANI_U16 msgType; /* + * message type is same as + * the request type + */ + tANI_U16 msgLen; /* + * length of the entire request, + * includes the pStatsBuf length too + */ + tANI_U8 sessionId; + tANI_U32 rc; /* success/failure */ + tANI_U32 staId; /* + * Per STA stats request must + * contain valid + */ + tAniTrafStrmMetrics tsmMetrics; + void *tsmStatsReq; /* tsm stats request backup */ +} tAniGetTsmStatsRsp, *tpAniGetTsmStatsRsp; + +typedef struct sSirEseBcnReportBssInfo +{ + tBcnReportFields bcnReportFields; + tANI_U8 ieLen; + tANI_U8 *pBuf; +} tSirEseBcnReportBssInfo, *tpSirEseBcnReportBssInfo; + +typedef struct sSirEseBcnReportRsp +{ + tANI_U16 measurementToken; + tANI_U8 flag; /* Flag to report measurement done and more data */ + tANI_U8 numBss; + tSirEseBcnReportBssInfo bcnRepBssInfo[SIR_BCN_REPORT_MAX_BSS_DESC]; +} tSirEseBcnReportRsp, *tpSirEseBcnReportRsp; + +#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_ESE_UPLOAD */ + +/* Change country code request MSG structure */ +typedef struct sAniChangeCountryCodeReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //3 char country code + tAniBool countryFromUserSpace; + tAniBool sendRegHint; //TRUE if we want to send hint to NL80211 + void *changeCCCallback; + void *pDevContext; //device context + void *pVosContext; //voss context + +} tAniChangeCountryCodeReq, *tpAniChangeCountryCodeReq; + +/* generic country code change request MSG structure */ +typedef struct sAniGenericChangeCountryCodeReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //3 char country code + tANI_U16 domain_index; +} tAniGenericChangeCountryCodeReq, *tpAniGenericChangeCountryCodeReq; + +typedef struct sAniDHCPStopInd +{ + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 device_mode; // Mode of the device(ex:STA, AP) + tSirMacAddr adapterMacAddr; // MAC address of the adapter + tSirMacAddr peerMacAddr; // MAC address of the connected peer + +} tAniDHCPInd, *tpAniDHCPInd; + +typedef struct sAniSummaryStatsInfo +{ + tANI_U32 retry_cnt[4]; //Total number of packets(per AC) that were successfully transmitted with retries + tANI_U32 multiple_retry_cnt[4];//The number of MSDU packets and MMPDU frames per AC that the 802.11 + // station successfully transmitted after more than one retransmission attempt + + tANI_U32 tx_frm_cnt[4]; //Total number of packets(per AC) that were successfully transmitted + //(with and without retries, including multi-cast, broadcast) + //tANI_U32 tx_fail_cnt; + //tANI_U32 num_rx_frm_crc_err; //Total number of received frames with CRC Error + //tANI_U32 num_rx_frm_crc_ok; //Total number of successfully received frames with out CRC Error + tANI_U32 rx_frm_cnt; //Total number of packets that were successfully received + //(after appropriate filter rules including multi-cast, broadcast) + tANI_U32 frm_dup_cnt; //Total number of duplicate frames received successfully + tANI_U32 fail_cnt[4]; //Total number packets(per AC) failed to transmit + tANI_U32 rts_fail_cnt; //Total number of RTS/CTS sequence failures for transmission of a packet + tANI_U32 ack_fail_cnt; //Total number packets failed transmit because of no ACK from the remote entity + tANI_U32 rts_succ_cnt; //Total number of RTS/CTS sequence success for transmission of a packet + tANI_U32 rx_discard_cnt; //The sum of the receive error count and dropped-receive-buffer error count. + //HAL will provide this as a sum of (FCS error) + (Fail get BD/PDU in HW) + tANI_U32 rx_error_cnt; //The receive error count. HAL will provide the RxP FCS error global counter. + tANI_U32 tx_byte_cnt; //The sum of the transmit-directed byte count, transmit-multicast byte count + //and transmit-broadcast byte count. HAL will sum TPE UC/MC/BCAST global counters + //to provide this. +}tAniSummaryStatsInfo, *tpAniSummaryStatsInfo; + +typedef enum eTxRateInfo +{ + eHAL_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + eHAL_TX_RATE_HT20 = 0x2, /* HT20 rates */ + eHAL_TX_RATE_HT40 = 0x4, /* HT40 rates */ + eHAL_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + eHAL_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + eHAL_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + eHAL_TX_RATE_VHT40 = 0x40, /* VHT 40 rates */ + eHAL_TX_RATE_VHT80 = 0x80 /* VHT 80 rates */ +} tTxrateinfoflags; + +typedef struct sAniGlobalClassAStatsInfo +{ + tANI_U32 rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames + tANI_U32 promiscuous_rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames when a promiscuous packet filter was enabled + //tANI_U32 rx_fcs_err; //The number of MPDU frames that the 802.11 station received with FCS errors + tANI_U32 rx_input_sensitivity; //The receiver input sensitivity referenced to a FER of 8% at an MPDU length + //of 1024 bytes at the antenna connector. Each element of the array shall correspond + //to a supported rate and the order shall be the same as the supporteRates parameter. + tANI_U32 max_pwr; //The maximum transmit power in dBm upto one decimal. + //for eg: if it is 10.5dBm, the value would be 105 + //tANI_U32 default_pwr; //The nominal transmit level used after normal power on sequence + tANI_U32 sync_fail_cnt; //Number of times the receiver failed to synchronize with the incoming signal + //after detecting the sync in the preamble of the transmitted PLCP protocol data unit. + tANI_U32 tx_rate; //Legacy transmit rate, in units of + //500 kbit/sec, for the most + //recently transmitted frame + tANI_U32 mcs_index; //mcs index for HT20 and HT40 rates + tANI_U32 tx_rate_flags; //to differentiate between HT20 and + //HT40 rates; short and long guard interval + +}tAniGlobalClassAStatsInfo, *tpAniGlobalClassAStatsInfo; + + +typedef struct sAniGlobalSecurityStats +{ + tANI_U32 rx_wep_unencrypted_frm_cnt; //The number of unencrypted received MPDU frames that the MAC layer discarded when + //the IEEE 802.11 dot11ExcludeUnencrypted management information base (MIB) object + //is enabled + tANI_U32 rx_mic_fail_cnt; //The number of received MSDU packets that that the 802.11 station discarded + //because of MIC failures + tANI_U32 tkip_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a TKIP ICV error + tANI_U32 aes_ccmp_format_err; //The number of received MPDU frames that the 802.11 discarded because of an + //invalid AES-CCMP format + tANI_U32 aes_ccmp_replay_cnt; //The number of received MPDU frames that the 802.11 station discarded because of + //the AES-CCMP replay protection procedure + tANI_U32 aes_ccmp_decrpt_err; //The number of received MPDU frames that the 802.11 station discarded because of + //errors detected by the AES-CCMP decryption algorithm + tANI_U32 wep_undecryptable_cnt; //The number of encrypted MPDU frames received for which a WEP decryption key was + //not available on the 802.11 station + tANI_U32 wep_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a WEP ICV error + tANI_U32 rx_decrypt_succ_cnt; //The number of received encrypted packets that the 802.11 station successfully + //decrypted + tANI_U32 rx_decrypt_fail_cnt; //The number of encrypted packets that the 802.11 station failed to decrypt + +}tAniGlobalSecurityStats, *tpAniGlobalSecurityStats; + +typedef struct sAniGlobalClassBStatsInfo +{ + tAniGlobalSecurityStats ucStats; + tAniGlobalSecurityStats mcbcStats; +}tAniGlobalClassBStatsInfo, *tpAniGlobalClassBStatsInfo; + +typedef struct sAniGlobalClassCStatsInfo +{ + tANI_U32 rx_amsdu_cnt; //This counter shall be incremented for a received A-MSDU frame with the stations + //MAC address in the address 1 field or an A-MSDU frame with a group address in the + //address 1 field + tANI_U32 rx_ampdu_cnt; //This counter shall be incremented when the MAC receives an AMPDU from the PHY + tANI_U32 tx_20_frm_cnt; //This counter shall be incremented when a Frame is transmitted only on the + //primary channel + tANI_U32 rx_20_frm_cnt; //This counter shall be incremented when a Frame is received only on the primary channel + tANI_U32 rx_mpdu_in_ampdu_cnt; //This counter shall be incremented by the number of MPDUs received in the A-MPDU + //when an A-MPDU is received + tANI_U32 ampdu_delimiter_crc_err;//This counter shall be incremented when an MPDU delimiter has a CRC error when this + //is the first CRC error in the received AMPDU or when the previous delimiter has been + //decoded correctly + +}tAniGlobalClassCStatsInfo, *tpAniGlobalClassCStatsInfo; + +typedef struct sAniPerStaStatsInfo +{ + tANI_U32 tx_frag_cnt[4]; //The number of MPDU frames that the 802.11 station transmitted and acknowledged + //through a received 802.11 ACK frame + tANI_U32 tx_ampdu_cnt; //This counter shall be incremented when an A-MPDU is transmitted + tANI_U32 tx_mpdu_in_ampdu_cnt; //This counter shall increment by the number of MPDUs in the AMPDU when an A-MPDU + //is transmitted + +}tAniPerStaStatsInfo, *tpAniPerStaStatsInfo; + +/**********************PE Statistics end*************************/ + + + +typedef struct sSirRSSIThresholds +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_S8 ucRssiThreshold1 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold3 : 8; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bReserved10 : 2; +#else + tANI_U8 bReserved10 : 2; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_S8 ucRssiThreshold3 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold1 : 8; +#endif + +}tSirRSSIThresholds, *tpSirRSSIThresholds; + +typedef struct sSirRSSINotification +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 bRssiThres1PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres3NegCross : 1; + v_S7_t avgRssi : 8; + tANI_U32 bReserved : 18; +#else + tANI_U32 bReserved : 18; + v_S7_t avgRssi : 8; + tANI_U32 bRssiThres3NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres1PosCross : 1; +#endif + +}tSirRSSINotification, *tpSirRSSINotification; + + +typedef struct sSirP2PNoaStart +{ + tANI_U32 status; + tANI_U32 bssIdx; +} tSirP2PNoaStart, *tpSirP2PNoaStart; + +typedef struct sSirTdlsInd +{ + tANI_U16 status; + tANI_U16 assocId; + tANI_U16 staIdx; + tANI_U16 reasonCode; +} tSirTdlsInd, *tpSirTdlsInd; + +typedef struct sSirP2PNoaAttr +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 index :8; + tANI_U32 oppPsFlag :1; + tANI_U32 ctWin :7; + tANI_U32 rsvd1: 16; +#else + tANI_U32 rsvd1: 16; + tANI_U32 ctWin :7; + tANI_U32 oppPsFlag :1; + tANI_U32 index :8; +#endif + +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 uNoa1IntervalCnt:8; + tANI_U32 rsvd2:24; +#else + tANI_U32 rsvd2:24; + tANI_U32 uNoa1IntervalCnt:8; +#endif + tANI_U32 uNoa1Duration; + tANI_U32 uNoa1Interval; + tANI_U32 uNoa1StartTime; + +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 uNoa2IntervalCnt:8; + tANI_U32 rsvd3:24; +#else + tANI_U32 rsvd3:24; + tANI_U32 uNoa2IntervalCnt:8; +#endif + tANI_U32 uNoa2Duration; + tANI_U32 uNoa2Interval; + tANI_U32 uNoa2StartTime; +} tSirP2PNoaAttr, *tpSirP2PNoaAttr; + +typedef __ani_attr_pre_packed struct sSirTclasInfo +{ + tSirMacTclasIE tclas; + tANI_U8 version; // applies only for classifier type ip + __ani_attr_pre_packed union { + tSirMacTclasParamEthernet eth; + tSirMacTclasParamIPv4 ipv4; + tSirMacTclasParamIPv6 ipv6; + tSirMacTclasParam8021dq t8021dq; + }__ani_attr_packed tclasParams; +} __ani_attr_packed tSirTclasInfo; + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) +#define TSRS_11AG_RATE_6MBPS 0xC +#define TSRS_11B_RATE_5_5MBPS 0xB +typedef struct sSirMacESETSRSIE +{ + tANI_U8 tsid; + tANI_U8 rates[8]; +} tSirMacESETSRSIE; +typedef struct sSirMacESETSMIE +{ + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tSirMacESETSMIE; +typedef struct sTSMStats +{ + tANI_U8 tid; + tSirMacAddr bssId; + tTrafStrmMetrics tsmMetrics; +} tTSMStats, *tpTSMStats; +typedef struct sEseTSMContext +{ + tANI_U8 tid; + tSirMacESETSMIE tsmInfo; + tTrafStrmMetrics tsmMetrics; +} tEseTSMContext, *tpEseTSMContext; +typedef struct sEsePEContext +{ +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tEseMeasReq curMeasReq; +#endif + tEseTSMContext tsm; +} tEsePEContext, *tpEsePEContext; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +typedef struct sSirAddtsReqInfo +{ + tANI_U8 dialogToken; + tSirMacTspecIE tspec; + + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; +#if defined(FEATURE_WLAN_ESE) + tSirMacESETSRSIE tsrsIE; + tANI_U8 tsrsPresent:1; +#endif + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; + tANI_U8 tclasProcPresent:1; +} tSirAddtsReqInfo, *tpSirAddtsReqInfo; + +typedef struct sSirAddtsRspInfo +{ + tANI_U8 dialogToken; + tSirMacStatusCodes status; + tSirMacTsDelayIE delay; + + tSirMacTspecIE tspec; + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; + tSirMacScheduleIE schedule; +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + tSirMacESETSMIE tsmIE; + tANI_U8 tsmPresent:1; +#endif + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; + tANI_U8 tclasProcPresent:1; + tANI_U8 schedulePresent:1; +} tSirAddtsRspInfo, *tpSirAddtsRspInfo; + +typedef struct sSirDeltsReqInfo +{ + tSirMacTSInfo tsinfo; + tSirMacTspecIE tspec; + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; +} tSirDeltsReqInfo, *tpSirDeltsReqInfo; + +/// Add a tspec as defined +typedef struct sSirAddtsReq +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U32 timeout; // in ms + tANI_U8 rspReqd; + tSirAddtsReqInfo req; +} tSirAddtsReq, *tpSirAddtsReq; + +typedef struct sSirAddtsRsp +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_RSP + tANI_U16 length; + tANI_U8 sessionId; // sme sessionId Added for BT-AMP support + tANI_U16 transactionId; //sme transaction Id Added for BT-AMP Support + tANI_U32 rc; // return code + tSirAddtsRspInfo rsp; +} tSirAddtsRsp, *tpSirAddtsRsp; + +typedef struct sSirDeltsReq +{ + tANI_U16 messageType; // eWNI_SME_DELTS_REQ + tANI_U16 length; + tANI_U8 sessionId;//Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U16 aid; // use 0 if macAddr is being specified + tANI_U8 macAddr[6]; // only on AP to specify the STA + tANI_U8 rspReqd; + tSirDeltsReqInfo req; +} tSirDeltsReq, *tpSirDeltsReq; + +typedef struct sSirDeltsRsp +{ + tANI_U16 messageType; // eWNI_SME_DELTS_RSP + tANI_U16 length; + tANI_U8 sessionId; // sme sessionId Added for BT-AMP support + tANI_U16 transactionId; //sme transaction Id Added for BT-AMP Support + tANI_U32 rc; + tANI_U16 aid; // use 0 if macAddr is being specified + tANI_U8 macAddr[6]; // only on AP to specify the STA + tSirDeltsReqInfo rsp; +} tSirDeltsRsp, *tpSirDeltsRsp; + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +typedef struct sSirPlmReq +{ + tANI_U16 diag_token; // Dialog token + tANI_U16 meas_token; // measurement token + tANI_U16 numBursts; // total number of bursts + tANI_U16 burstInt; // burst interval in seconds + tANI_U16 measDuration; // in TU's,STA goes off-ch + /* no of times the STA should cycle through PLM ch list */ + tANI_U8 burstLen; + tPowerdBm desiredTxPwr; // desired tx power + tSirMacAddr macAddr; // MC dest addr + /* no of channels */ + tANI_U8 plmNumCh; + /* channel numbers */ + tANI_U8 plmChList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 sessionId; + eAniBoolean enable; +} tSirPlmReq, *tpSirPlmReq; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + +#define SIR_QOS_NUM_AC_MAX 4 + +typedef struct sSirAggrQosReqInfo +{ + tANI_U16 tspecIdx; + tSirAddtsReqInfo aggrAddTsInfo[SIR_QOS_NUM_AC_MAX]; +}tSirAggrQosReqInfo, *tpSirAggrQosReqInfo; + +typedef struct sSirAggrQosReq +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U32 timeout; // in ms + tANI_U8 rspReqd; + tSirAggrQosReqInfo aggrInfo; +}tSirAggrQosReq, *tpSirAggrQosReq; + +typedef struct sSirAggrQosRspInfo +{ + tANI_U16 tspecIdx; + tSirAddtsRspInfo aggrRsp[SIR_QOS_NUM_AC_MAX]; +} tSirAggrQosRspInfo, *tpSirAggrQosRspInfo; + +typedef struct sSirAggrQosRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirAggrQosRspInfo aggrInfo; +} tSirAggrQosRsp, *tpSirAggrQosRsp; + +#endif/*WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE*/ + +typedef struct sSirSetTxPowerReq +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr bssId; + tANI_U8 mwPower; + tANI_U8 bssIdx; +} tSirSetTxPowerReq, *tpSirSetTxPowerReq; + +typedef struct sSirSetTxPowerRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U32 status; +} tSirSetTxPowerRsp, *tpSirSetTxPowerRsp; + +typedef struct sSirGetTxPowerReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U16 staid; +} tSirGetTxPowerReq, *tpSirGetTxPowerReq; + +typedef struct sSirGetTxPowerRsp +{ + tANI_U16 messageType; + tANI_U16 length; // length of the entire request + tANI_U32 power; // units of milliwatts + tANI_U32 status; +} tSirGetTxPowerRsp, *tpSirGetTxPowerRsp; + + +typedef tANI_U32 tSirMacNoise[3]; + +typedef struct sSirGetNoiseRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacNoise noise; +} tSirGetNoiseRsp, *tpSirGetNoiseRsp; + +typedef struct sSirQosMapSet +{ + tANI_U8 present; + tANI_U8 num_dscp_exceptions; + tANI_U8 dscp_exceptions[21][2]; + tANI_U8 dscp_range[8][2]; +} tSirQosMapSet, *tpSirQosMapSet; + +// +// PMC --> PE --> HAL +// Power save configuration parameters +// +typedef struct sSirPowerSaveCfg +{ + tANI_U16 listenInterval; + + /* Number of consecutive missed beacons before + * hardware generates an interrupt to wake up + * the host. In units of listen interval. + */ + tANI_U32 HeartBeatCount; + + /* specifies which beacons are to be forwarded + * to host when beacon filtering is enabled. + * In units of listen interval. + */ + tANI_U32 nthBeaconFilter; + + /* Maximum number of PS-Poll send before + * firmware sends data null with PM set to 0. + */ + tANI_U32 maxPsPoll; + + /* If the average RSSI value falls below the + * minRssiThreshold, then FW will send an + * interrupt to wake up the host. + */ + tANI_U32 minRssiThreshold; + + /* Number of beacons for which firmware will + * collect the RSSI values and compute the average. + */ + tANI_U8 numBeaconPerRssiAverage; + + /* FW collects the RSSI stats for this period + * in BMPS mode. + */ + tANI_U8 rssiFilterPeriod; + + // Enabling/disabling broadcast frame filter feature + tANI_U8 broadcastFrameFilter; + + // Enabling/disabling the ignore DTIM feature + tANI_U8 ignoreDtim; + + /* The following configuration parameters are kept + * in order to be backward compatible for Gen5. + * These will NOT be used for Gen6 Libra chip + */ + tBeaconForwarding beaconFwd; + tANI_U16 nthBeaconFwd; + tANI_U8 fEnablePwrSaveImmediately; + tANI_U8 fPSPoll; + + // Enabling/disabling Beacon Early Termination feature + tANI_U8 fEnableBeaconEarlyTermination; + tANI_U8 bcnEarlyTermWakeInterval; + +}tSirPowerSaveCfg, *tpSirPowerSaveCfg; + +/* Reason code for requesting Full Power. This reason code is used by + any module requesting full power from PMC and also by PE when it + sends the eWNI_PMC_EXIT_BMPS_IND to PMC*/ +typedef enum eRequestFullPowerReason +{ + eSME_MISSED_BEACON_IND_RCVD, /* PE received a MAX_MISSED_BEACON_IND */ + eSME_BMPS_STATUS_IND_RCVD, /* PE received a SIR_HAL_BMPS_STATUS_IND */ + eSME_BMPS_MODE_DISABLED, /* BMPS mode was disabled by HDD in SME */ + eSME_LINK_DISCONNECTED_BY_HDD, /* Link has been disconnected requested by HDD */ + eSME_LINK_DISCONNECTED_BY_OTHER,/* Disconnect due to linklost or requested by peer */ + eSME_FULL_PWR_NEEDED_BY_HDD, /* HDD request full power for some reason */ + eSME_FULL_PWR_NEEDED_BY_BAP, /* BAP request full power for BT_AMP */ + eSME_FULL_PWR_NEEDED_BY_CSR, /* CSR requests full power */ + eSME_FULL_PWR_NEEDED_BY_QOS, /* QOS requests full power */ + eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH, /* channel switch request full power*/ +#ifdef FEATURE_WLAN_TDLS + eSME_FULL_PWR_NEEDED_BY_TDLS_PEER_SETUP, /* TDLS peer setup*/ +#endif + eSME_REASON_OTHER /* No specific reason. General reason code */ +} tRequestFullPowerReason, tExitBmpsReason; + + + +//This is sent alongwith eWNI_PMC_EXIT_BMPS_REQ message +typedef struct sExitBmpsInfo +{ + tExitBmpsReason exitBmpsReason; /*Reason for exiting BMPS */ +}tExitBmpsInfo, *tpExitBmpsInfo; + + +// MAC SW --> SME +// Message indicating to SME to exit BMPS sleep mode +typedef struct sSirSmeExitBmpsInd +{ + tANI_U16 mesgType; /* eWNI_PMC_EXIT_BMPS_IND */ + tANI_U16 mesgLen; + tSirResultCodes statusCode; + tExitBmpsReason exitBmpsReason; /*Reason for exiting BMPS */ + tANI_U32 smeSessionId; +} tSirSmeExitBmpsInd, *tpSirSmeExitBmpsInd; + +// MAC SW --> SME +// Message indicating to SME for channel switch +typedef struct sSirSmePreSwitchChannelInd +{ + tANI_U16 mesgType; /* eWNI_SME_PRE_SWITCH_CHL_IND */ + tANI_U16 mesgLen; + tANI_U8 sessionId; +} tSirSmePreSwitchChannelInd, *tpSirSmePreSwitchChannelInd; + + +// +// HDD -> LIM +// tSirMsgQ.type = eWNI_SME_DEL_BA_PEER_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = instance of tDelBAParams +// +typedef struct sSmeDelBAPeerInd +{ + // Message Type + tANI_U16 mesgType; + + tSirMacAddr bssId;//BSSID + + // Message Length + tANI_U16 mesgLen; + + // Station Index + tANI_U16 staIdx; + + // TID for which the BA session is being deleted + tANI_U8 baTID; + + // DELBA direction + // eBA_INITIATOR - Originator + // eBA_RECEIPIENT - Recipient + tANI_U8 baDirection; +} tSmeDelBAPeerInd, *tpSmeDelBAPeerInd; + +typedef struct sSmeIbssPeerInd +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U8 sessionId; + + tSirMacAddr peerAddr; + tANI_U16 staId; + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + //Beacon will be appended for new Peer indication. +}tSmeIbssPeerInd, *tpSmeIbssPeerInd; + +typedef struct sSirIbssPeerInactivityInd +{ + tANI_U8 bssIdx; + tANI_U8 staIdx; + tSirMacAddr peerAddr; +}tSirIbssPeerInactivityInd, *tpSirIbssPeerInactivityInd; + + +typedef struct sLimScanChn +{ + tANI_U16 numTimeScan; //how many time this channel is scan + tANI_U8 channelId; +}tLimScanChn; + +typedef struct sSmeGetScanChnRsp +{ + // Message Type + tANI_U16 mesgType; + // Message Length + tANI_U16 mesgLen; + tANI_U8 sessionId; + tANI_U8 numChn; + tLimScanChn scanChn[1]; +} tSmeGetScanChnRsp, *tpSmeGetScanChnRsp; + +typedef struct sLimScanChnInfo +{ + tANI_U8 numChnInfo; //number of channels in scanChn + tLimScanChn scanChn[SIR_MAX_SUPPORTED_CHANNEL_LIST]; +}tLimScanChnInfo; + +typedef struct sSirSmeGetAssocSTAsReq +{ + tANI_U16 messageType; // eWNI_SME_GET_ASSOC_STAS_REQ + tANI_U16 length; + tSirMacAddr bssId; // BSSID + tANI_U16 modId; + void *pUsrContext; + void *pSapEventCallback; + void *pAssocStasArray;// Pointer to allocated memory passed in WLANSAP_GetAssocStations API +} tSirSmeGetAssocSTAsReq, *tpSirSmeGetAssocSTAsReq; + +typedef struct sSmeMaxAssocInd +{ + tANI_U16 mesgType; // eWNI_SME_MAX_ASSOC_EXCEEDED + tANI_U16 mesgLen; + tANI_U8 sessionId; + tSirMacAddr peerMac; // the new peer that got rejected due to softap max assoc limit reached +} tSmeMaxAssocInd, *tpSmeMaxAssocInd; + +typedef struct sSmeCsaOffloadInd +{ + tANI_U16 mesgType; // eWNI_SME_CSA_OFFLOAD_EVENT + tANI_U16 mesgLen; + tSirMacAddr bssId; // BSSID +} tSmeCsaOffloadInd, *tpSmeCsaOffloadInd; + +/// WOW related structures +// SME -> PE <-> HAL +#define SIR_WOWL_BCAST_PATTERN_MAX_SIZE 146 +#define SIR_WOWL_BCAST_MAX_NUM_PATTERNS 19 +// SME -> PE -> HAL - This is to add WOWL BCAST wake-up pattern. +// SME/HDD maintains the list of the BCAST wake-up patterns. +// This is a pass through message for PE +typedef struct sSirWowlAddBcastPtrn +{ + tANI_U8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + tANI_U8 ucPatternByteOffset; + tANI_U8 ucPatternSize; // Non-Zero Pattern size + tANI_U8 ucPattern[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + tANI_U8 ucPatternMaskSize; // Non-zero pattern mask size + tANI_U8 ucPatternMask[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + // Extra pattern data beyond 128 bytes + tANI_U8 ucPatternExt[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra Pattern + tANI_U8 ucPatternMaskExt[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra Pattern mask + tSirMacAddr bssId; // BSSID + tANI_U8 sessionId; +} tSirWowlAddBcastPtrn, *tpSirWowlAddBcastPtrn; + + +// SME -> PE -> HAL - This is to delete WOWL BCAST wake-up pattern. +// SME/HDD maintains the list of the BCAST wake-up patterns. +// This is a pass through message for PE +typedef struct sSirWowlDelBcastPtrn +{ + /* Pattern ID of the wakeup pattern to be deleted */ + tANI_U8 ucPatternId; + tSirMacAddr bssId; // BSSID +}tSirWowlDelBcastPtrn, *tpSirWowlDelBcastPtrn; + + +// SME->PE: Enter WOWLAN parameters +typedef struct sSirSmeWowlEnterParams +{ + tANI_U8 sessionId; + + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering */ + tANI_U8 ucPatternFilteringEnable; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + tSirMacAddr bssId; +} tSirSmeWowlEnterParams, *tpSirSmeWowlEnterParams; + + +// PE<->HAL: Enter WOWLAN parameters +typedef struct sSirHalWowlEnterParams +{ + tANI_U8 sessionId; + + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + tANI_U8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + tANI_U8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + tANI_U8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + tANI_U8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + tANI_U8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + tANI_U8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + tANI_U8 ucWowMaxSleepUsec; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + /* Status code to be filled by HAL when it sends + * SIR_HAL_WOWL_ENTER_RSP to PE. + */ + eHalStatus status; + + /*BSSID to find the current session + */ + tANI_U8 bssIdx; +} tSirHalWowlEnterParams, *tpSirHalWowlEnterParams; + +// SME->PE: Exit WOWLAN parameters +typedef struct sSirSmeWowlExitParams +{ + tANI_U8 sessionId; + +} tSirSmeWowlExitParams, *tpSirSmeWowlExitParams; + +// PE<->HAL: Exit WOWLAN parameters +typedef struct sSirHalWowlExitParams +{ + tANI_U8 sessionId; + + /* Status code to be filled by HAL when it sends + * SIR_HAL_WOWL_EXIT_RSP to PE. + */ + eHalStatus status; + + /*BSSIDX to find the current session + */ + tANI_U8 bssIdx; +} tSirHalWowlExitParams, *tpSirHalWowlExitParams; + + +#define SIR_MAX_NAME_SIZE 64 +#define SIR_MAX_TEXT_SIZE 32 + +typedef struct sSirName { + v_U8_t num_name; + v_U8_t name[SIR_MAX_NAME_SIZE]; +} tSirName; + +typedef struct sSirText { + v_U8_t num_text; + v_U8_t text[SIR_MAX_TEXT_SIZE]; +} tSirText; + + +#define SIR_WPS_PROBRSP_VER_PRESENT 0x00000001 +#define SIR_WPS_PROBRSP_STATE_PRESENT 0x00000002 +#define SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT 0x00000004 +#define SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT 0x00000008 +#define SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT 0x00000010 +#define SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT 0x00000040 +#define SIR_WPS_PROBRSP_UUIDE_PRESENT 0x00000080 +#define SIR_WPS_PROBRSP_MANUFACTURE_PRESENT 0x00000100 +#define SIR_WPS_PROBRSP_MODELNAME_PRESENT 0x00000200 +#define SIR_WPS_PROBRSP_MODELNUMBER_PRESENT 0x00000400 +#define SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT 0x00000800 +#define SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT 0x00001000 +#define SIR_WPS_PROBRSP_DEVICENAME_PRESENT 0x00002000 +#define SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT 0x00004000 +#define SIR_WPS_PROBRSP_RF_BANDS_PRESENT 0x00008000 + + +typedef struct sSirWPSProbeRspIE { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t ResponseType; // Response type + v_U8_t UUID_E[16]; // Unique identifier of the AP. + tSirName Manufacture; + tSirText ModelName; + tSirText ModelNumber; + tSirText SerialNumber; + v_U32_t PrimaryDeviceCategory ; // Device Category ID: 1Computer, 2Input Device, ... + v_U8_t PrimaryDeviceOUI[4] ; // Vendor specific OUI for Device Sub Category + v_U32_t DeviceSubCategory ; // Device Sub Category ID: 1-PC, 2-Server if Device Category ID is computer + tSirText DeviceName; + v_U16_t ConfigMethod; // Configuaration method + v_U8_t RFBand; // RF bands available on the AP +} tSirWPSProbeRspIE; + +#define SIR_WPS_BEACON_VER_PRESENT 0x00000001 +#define SIR_WPS_BEACON_STATE_PRESENT 0x00000002 +#define SIR_WPS_BEACON_APSETUPLOCK_PRESENT 0x00000004 +#define SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT 0x00000008 +#define SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT 0x00000010 +#define SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define SIR_WPS_BEACON_UUIDE_PRESENT 0x00000080 +#define SIR_WPS_BEACON_RF_BANDS_PRESENT 0x00000100 + +typedef struct sSirWPSBeaconIE { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_U8_t RFBand; // RF bands available on the AP +} tSirWPSBeaconIE; + +#define SIR_WPS_ASSOCRSP_VER_PRESENT 0x00000001 +#define SIR_WPS_ASSOCRSP_RESPONSETYPE_PRESENT 0x00000002 + +typedef struct sSirWPSAssocRspIE { + v_U32_t FieldPresent; + v_U32_t Version; + v_U8_t ResposeType; +} tSirWPSAssocRspIE; + +typedef struct sSirAPWPSIEs { + tSirWPSProbeRspIE SirWPSProbeRspIE; /*WPS Set Probe Respose IE*/ + tSirWPSBeaconIE SirWPSBeaconIE; /*WPS Set Beacon IE*/ + tSirWPSAssocRspIE SirWPSAssocRspIE; /*WPS Set Assoc Response IE*/ +} tSirAPWPSIEs, *tpSiriAPWPSIEs; + +typedef struct sSirUpdateAPWPSIEsReq +{ + tANI_U16 messageType; // eWNI_SME_UPDATE_APWPSIE_REQ + tANI_U16 length; + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tANI_U8 sessionId; //Session ID + tSirAPWPSIEs APWPSIEs; +} tSirUpdateAPWPSIEsReq, *tpSirUpdateAPWPSIEsReq; + +typedef struct sSirUpdateParams +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U8 ssidHidden; // Hide SSID +} tSirUpdateParams, *tpSirUpdateParams; + +//Beacon Interval +typedef struct sSirChangeBIParams +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U16 beaconInterval; // Beacon Interval + tSirMacAddr bssId; + tANI_U8 sessionId; // Session ID +} tSirChangeBIParams, *tpSirChangeBIParams; + +#ifdef QCA_HT_2040_COEX +typedef struct sSirSetHT2040Mode +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 cbMode; + tANI_BOOLEAN obssEnabled; + tSirMacAddr bssId; + tANI_U8 sessionId; // Session ID +} tSirSetHT2040Mode, *tpSirSetHT2040Mode; +#endif + +#define SIR_WPS_UUID_LEN 16 +#define SIR_WPS_PBC_WALK_TIME 120 // 120 Second + +typedef struct sSirWPSPBCSession { + struct sSirWPSPBCSession *next; + tSirMacAddr addr; + tANI_U8 uuid_e[SIR_WPS_UUID_LEN]; + tANI_TIMESTAMP timestamp; +} tSirWPSPBCSession; + +typedef struct sSirSmeGetWPSPBCSessionsReq +{ + tANI_U16 messageType; // eWNI_SME_GET_WPSPBC_SESSION_REQ + tANI_U16 length; + void *pUsrContext; + void *pSapEventCallback; + tSirMacAddr bssId; // BSSID + tSirMacAddr pRemoveMac; // MAC Address of STA in WPS Session to be removed +} tSirSmeGetWPSPBCSessionsReq, *tpSirSmeGetWPSPBCSessionsReq; + +typedef struct sSirWPSPBCProbeReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 probeReqIELen; + tANI_U8 probeReqIE[512]; +} tSirWPSPBCProbeReq, *tpSirWPSPBCProbeReq; + +// probereq from peer, when wsc is enabled +typedef struct sSirSmeProbeReqInd +{ + tANI_U16 messageType; // eWNI_SME_WPS_PBC_PROBE_REQ_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; + tSirWPSPBCProbeReq WPSPBCProbeReq; +} tSirSmeProbeReqInd, *tpSirSmeProbeReqInd; + +typedef struct sSirUpdateAPWPARSNIEsReq +{ + tANI_U16 messageType; // eWNI_SME_SET_APWPARSNIEs_REQ + tANI_U16 length; + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tANI_U8 sessionId; //Session ID + tSirRSNie APWPARSNIEs; +} tSirUpdateAPWPARSNIEsReq, *tpSirUpdateAPWPARSNIEsReq; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_ROAM_MAX_CHANNELS 80 +#define SIR_ROAM_SCAN_MAX_PB_REQ_SIZE 450 +#define CHANNEL_LIST_STATIC 1 /* Occupied channel list remains static */ +#define CHANNEL_LIST_DYNAMIC_INIT 2 /* Occupied channel list can be learnt after init */ +#define CHANNEL_LIST_DYNAMIC_FLUSH 3 /* Occupied channel list can be learnt after flush */ +#define CHANNEL_LIST_DYNAMIC_UPDATE 4 /* Occupied channel list can be learnt after update */ +#define SIR_ROAM_SCAN_24G_DEFAULT_CH 1 +#define SIR_ROAM_SCAN_5G_DEFAULT_CH 36 +#define SIR_ROAM_SCAN_RESERVED_BYTES 61 +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define SIR_ROAM_SCAN_PSK_SIZE 32 +#define SIR_ROAM_R0KH_ID_MAX_LEN 48 +#endif +// SME -> HAL - This is the host offload request. +#define SIR_IPV4_ARP_REPLY_OFFLOAD 0 +#define SIR_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 +#define SIR_IPV6_NS_OFFLOAD 2 +#define SIR_OFFLOAD_DISABLE 0 +#define SIR_OFFLOAD_ENABLE 1 +#define SIR_OFFLOAD_BCAST_FILTER_ENABLE 0x2 +#define SIR_OFFLOAD_MCAST_FILTER_ENABLE 0x4 +#define SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE (SIR_OFFLOAD_ENABLE|SIR_OFFLOAD_BCAST_FILTER_ENABLE) +#define SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE (SIR_OFFLOAD_ENABLE|SIR_OFFLOAD_MCAST_FILTER_ENABLE) + +#ifdef WLAN_NS_OFFLOAD +typedef struct sSirNsOffloadReq +{ + tANI_U8 srcIPv6Addr[16]; + tANI_U8 selfIPv6Addr[16]; + //Only support 2 possible Network Advertisement IPv6 address + tANI_U8 targetIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][16]; + tANI_U8 selfMacAddr[6]; + tANI_U8 srcIPv6AddrValid; + tANI_U8 targetIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]; + tANI_U8 slotIdx; +} tSirNsOffloadReq, *tpSirNsOffloadReq; +#endif //WLAN_NS_OFFLOAD + +typedef struct sSirHostOffloadReq +{ + tANI_U8 offloadType; + tANI_U8 enableOrDisable; + union + { + tANI_U8 hostIpv4Addr [4]; + tANI_U8 hostIpv6Addr [16]; + } params; +#ifdef WLAN_NS_OFFLOAD + tSirNsOffloadReq nsOffloadInfo; +#endif //WLAN_NS_OFFLOAD + tSirMacAddr bssId; +} tSirHostOffloadReq, *tpSirHostOffloadReq; + +/* Packet Types. */ +#define SIR_KEEP_ALIVE_NULL_PKT 1 +#define SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 + +/* Keep Alive request. */ +typedef struct sSirKeepAliveReq +{ + v_U8_t packetType; + v_U32_t timePeriod; + tSirIpv4Addr hostIpv4Addr; + tSirIpv4Addr destIpv4Addr; + tSirMacAddr destMacAddr; + tSirMacAddr bssId; + tANI_U8 sessionId; +} tSirKeepAliveReq, *tpSirKeepAliveReq; + +typedef struct sSirSmeAddStaSelfReq +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; + tANI_U32 type; + tANI_U32 subType; + tANI_U8 sessionId; + tANI_U16 pkt_err_disconn_th; +}tSirSmeAddStaSelfReq, *tpSirSmeAddStaSelfReq; + +typedef struct sSirSmeDelStaSelfReq +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirMacAddr selfMacAddr; + tANI_U8 sessionId; +}tSirSmeDelStaSelfReq, *tpSirSmeDelStaSelfReq; + +typedef struct sSirSmeAddStaSelfRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U16 status; + tSirMacAddr selfMacAddr; +}tSirSmeAddStaSelfRsp, *tpSirSmeAddStaSelfRsp; + +typedef struct sSirSmeDelStaSelfRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U16 status; + tSirMacAddr selfMacAddr; +}tSirSmeDelStaSelfRsp, *tpSirSmeDelStaSelfRsp; + +/* Coex Indication defines - + should match WLAN_COEX_IND_DATA_SIZE + should match WLAN_COEX_IND_TYPE_DISABLE_HB_MONITOR + should match WLAN_COEX_IND_TYPE_ENABLE_HB_MONITOR */ +#define SIR_COEX_IND_DATA_SIZE (4) +#define SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR (0) +#define SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR (1) +#define SIR_COEX_IND_TYPE_SCAN_COMPROMISED (2) +#define SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED (3) +#define SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 (4) +#define SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4 (5) + +typedef struct sSirSmeCoexInd +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U32 coexIndType; + tANI_U32 coexIndData[SIR_COEX_IND_DATA_SIZE]; +}tSirSmeCoexInd, *tpSirSmeCoexInd; + +typedef struct sSirSmeMgmtFrameInd +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U32 rxChan; + tANI_U8 sessionId; + tANI_U8 frameType; + tANI_S8 rxRssi; + tANI_U8 frameBuf[1]; //variable +}tSirSmeMgmtFrameInd, *tpSirSmeMgmtFrameInd; + +#ifdef WLAN_FEATURE_11W +typedef struct sSirSmeUnprotMgmtFrameInd +{ + tANI_U8 sessionId; + tANI_U8 frameType; + tANI_U8 frameLen; + tANI_U8 frameBuf[1]; //variable +}tSirSmeUnprotMgmtFrameInd, *tpSirSmeUnprotMgmtFrameInd; +#endif + +#define SIR_IS_FULL_POWER_REASON_DISCONNECTED(eReason) \ + ( ( eSME_LINK_DISCONNECTED_BY_HDD == (eReason) ) || \ + ( eSME_LINK_DISCONNECTED_BY_OTHER == (eReason) ) || \ + (eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH == (eReason))) +#define SIR_IS_FULL_POWER_NEEDED_BY_HDD(eReason) \ + ( ( eSME_LINK_DISCONNECTED_BY_HDD == (eReason) ) || ( eSME_FULL_PWR_NEEDED_BY_HDD == (eReason) ) ) + +/* P2P Power Save Related */ +typedef struct sSirNoAParam +{ + tANI_U8 ctWindow:7; + tANI_U8 OppPS:1; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 singleNoADuration; + tANI_U8 psSelection; +}tSirNoAParam, *tpSirNoAParam; + +typedef struct sSirWlanSuspendParam +{ + tANI_U8 configuredMcstBcstFilterSetting; + tANI_U8 sessionId; + tANI_U8 connectedState; +}tSirWlanSuspendParam,*tpSirWlanSuspendParam; + +typedef struct sSirWlanResumeParam +{ + tANI_U8 configuredMcstBcstFilterSetting; +}tSirWlanResumeParam,*tpSirWlanResumeParam; + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + +typedef enum ext_wow_type +{ + EXT_WOW_TYPE_APP_TYPE1, /* wow type: only enable wakeup for app type1 */ + EXT_WOW_TYPE_APP_TYPE2, /* wow type: only enable wakeup for app type2 */ + EXT_WOW_TYPE_APP_TYPE1_2, /* wow type: enable wakeup for app type1&2 */ + +}EXT_WOW_TYPE; + +typedef struct +{ + tANI_U8 vdev_id; + EXT_WOW_TYPE type; + tANI_U32 wakeup_pin_num; +} tSirExtWoWParams, *tpSirExtWoWParams; + +typedef struct +{ + tANI_U8 vdev_id; + tSirMacAddr wakee_mac_addr; + tANI_U8 identification_id[8]; + tANI_U8 password[16]; + tANI_U32 id_length; + tANI_U32 pass_length; +} tSirAppType1Params, *tpSirAppType1Params; + +typedef struct +{ + tANI_U8 vdev_id; + + tANI_U8 rc4_key[16]; + tANI_U32 rc4_key_len; + + /** ip header parameter */ + tANI_U32 ip_id; /* NC id */ + tANI_U32 ip_device_ip; /* NC IP address */ + tANI_U32 ip_server_ip; /* Push server IP address */ + + /** tcp header parameter */ + tANI_U16 tcp_src_port; /* NC TCP port */ + tANI_U16 tcp_dst_port; /* Push server TCP port */ + tANI_U32 tcp_seq; + tANI_U32 tcp_ack_seq; + + tANI_U32 keepalive_init; /* Initial ping interval */ + tANI_U32 keepalive_min; /* Minimum ping interval */ + tANI_U32 keepalive_max; /* Maximum ping interval */ + tANI_U32 keepalive_inc; /* Increment of ping interval */ + + tSirMacAddr gateway_mac; + tANI_U32 tcp_tx_timeout_val; + tANI_U32 tcp_rx_timeout_val; +} tSirAppType2Params, *tpSirAppType2Params; +#endif + +typedef struct sSirWlanSetRxpFilters +{ + tANI_U8 configuredMcstBcstFilterSetting; + tANI_U8 setMcstBcstFilter; +}tSirWlanSetRxpFilters,*tpSirWlanSetRxpFilters; + +#ifdef FEATURE_WLAN_SCAN_PNO +// +// PNO Messages +// + +// Set PNO +#define SIR_PNO_MAX_NETW_CHANNELS 26 +#define SIR_PNO_MAX_NETW_CHANNELS_EX 60 +#define SIR_PNO_MAX_SUPP_NETWORKS 16 +#define SIR_PNO_MAX_SCAN_TIMERS 10 + +/*size based of dot11 declaration without extra IEs as we will not carry those for PNO*/ +#define SIR_PNO_MAX_PB_REQ_SIZE 450 + +#define SIR_PNO_24G_DEFAULT_CH 1 +#define SIR_PNO_5G_DEFAULT_CH 36 + +typedef enum +{ + SIR_PNO_MODE_IMMEDIATE, + SIR_PNO_MODE_ON_SUSPEND, + SIR_PNO_MODE_ON_RESUME, + SIR_PNO_MODE_MAX +} eSirPNOMode; + +typedef struct +{ + tSirMacSSid ssId; + tANI_U32 authentication; + tANI_U32 encryption; + tANI_U32 bcastNetwType; + tANI_U8 ucChannelCount; + tANI_U8 aChannels[SIR_PNO_MAX_NETW_CHANNELS_EX]; + tANI_S32 rssiThreshold; +} tSirNetworkType; + +typedef struct +{ + tANI_U32 uTimerValue; + tANI_U32 uTimerRepeat; +}tSirScanTimer; + +typedef struct +{ + tANI_U8 ucScanTimersCount; + tSirScanTimer aTimerValues[SIR_PNO_MAX_SCAN_TIMERS]; +} tSirScanTimersType; + +typedef struct sSirPNOScanReq +{ + tANI_U8 enable; + eSirPNOMode modePNO; + tANI_U8 ucNetworksCount; + tSirNetworkType aNetworks[SIR_PNO_MAX_SUPP_NETWORKS]; + tSirScanTimersType scanTimers; + tANI_U8 sessionId; + + tANI_U16 us24GProbeTemplateLen; + tANI_U8 p24GProbeTemplate[SIR_PNO_MAX_PB_REQ_SIZE]; + tANI_U16 us5GProbeTemplateLen; + tANI_U8 p5GProbeTemplate[SIR_PNO_MAX_PB_REQ_SIZE]; +} tSirPNOScanReq, *tpSirPNOScanReq; + +typedef struct sSirSetRSSIFilterReq +{ + tANI_U8 rssiThreshold; +} tSirSetRSSIFilterReq, *tpSirSetRSSIFilterReq; + + +// Update Scan Params +typedef struct { + tANI_U8 b11dEnabled; + tANI_U8 b11dResolved; + tANI_U8 ucChannelCount; + tANI_U8 aChannels[SIR_PNO_MAX_NETW_CHANNELS_EX]; + tANI_U16 usPassiveMinChTime; + tANI_U16 usPassiveMaxChTime; + tANI_U16 usActiveMinChTime; + tANI_U16 usActiveMaxChTime; + tANI_U8 ucCBState; +} tSirUpdateScanParams, * tpSirUpdateScanParams; + +// Preferred Network Found Indication +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + /* Network that was found with the highest RSSI*/ + tSirMacSSid ssId; + /* Indicates the RSSI */ + tANI_U8 rssi; + /* Length of the beacon or probe response + * corresponding to the candidate found by PNO */ + tANI_U32 frameLength; + tANI_U8 sessionId; + /* Index to memory location where the contents of + * beacon or probe response frame will be copied */ + tANI_U8 data[1]; +} tSirPrefNetworkFoundInd, *tpSirPrefNetworkFoundInd; +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +typedef struct { + tANI_U8 acvo_uapsd: 1; + tANI_U8 acvi_uapsd: 1; + tANI_U8 acbk_uapsd: 1; + tANI_U8 acbe_uapsd: 1; + tANI_U8 reserved: 4; +} tSirAcUapsd, *tpSirAcUapsd; +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +typedef struct +{ + tSirMacSSid ssId; + tANI_U8 currAPbssid[VOS_MAC_ADDR_SIZE]; + tANI_U32 authentication; + tANI_U8 encryption; + tANI_U8 mcencryption; + tANI_U8 ChannelCount; + tANI_U8 ChannelCache[SIR_ROAM_MAX_CHANNELS]; + +} tSirRoamNetworkType; + +typedef struct SirMobilityDomainInfo +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +} tSirMobilityDomainInfo; + +typedef enum { + SIR_ROAMING_DFS_CHANNEL_DISABLED = 0, + SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL = 1, + SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE = 2 +} eSirDFSRoamScanMode; + +typedef struct sSirRoamOffloadScanReq +{ + eAniBoolean RoamScanOffloadEnabled; + eAniBoolean MAWCEnabled; + tANI_S8 LookupThreshold; + tANI_U8 delay_before_vdev_stop; + tANI_U8 OpportunisticScanThresholdDiff; + tANI_U8 RoamRescanRssiDiff; + tANI_U8 RoamRssiDiff; + tANI_U8 ChannelCacheType; + tANI_U8 Command; + tANI_U8 StartScanReason; + tANI_U16 NeighborScanTimerPeriod; + tANI_U16 NeighborRoamScanRefreshPeriod; + tANI_U16 NeighborScanChannelMinTime; + tANI_U16 NeighborScanChannelMaxTime; + tANI_U16 EmptyRefreshScanPeriod; + tANI_U8 ValidChannelCount; + tANI_U8 ValidChannelList[SIR_ROAM_MAX_CHANNELS]; + eAniBoolean IsESEAssoc; + tANI_U16 us24GProbeTemplateLen; + tANI_U8 p24GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; + tANI_U16 us5GProbeTemplateLen; + tANI_U8 p5GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; + tANI_U8 ReservedBytes[SIR_ROAM_SCAN_RESERVED_BYTES]; + /*ReservedBytes is to add any further params in future + without changing the interface params on Host + and firmware.The firmware right now checks + if the size of this structure matches and then + proceeds with the processing of the command. + So, in future, if there is any need to add + more params, pick the memory from reserved + bytes and keep deducting the reserved bytes + by the amount of bytes picked.*/ + tANI_U8 nProbes; + tANI_U16 HomeAwayTime; + tSirRoamNetworkType ConnectedNetwork; + tSirMobilityDomainInfo MDID; + tANI_U8 sessionId; + tANI_U8 RoamBmissFirstBcnt; + tANI_U8 RoamBmissFinalBcnt; + tANI_U8 RoamBeaconRssiWeight; + eSirDFSRoamScanMode allowDFSChannelRoam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 RoamOffloadEnabled; + tANI_U8 PSK_PMK[SIR_ROAM_SCAN_PSK_SIZE]; + tANI_U32 pmk_len; + tANI_U8 Prefer5GHz; + tANI_U8 RoamRssiCatGap; + tANI_U8 Select5GHzMargin; + tANI_U8 KRK[SIR_KRK_KEY_LEN]; + tANI_U8 BTK[SIR_BTK_KEY_LEN]; + tANI_U32 ReassocFailureTimeout; + tSirAcUapsd AcUapsd; + tANI_U8 R0KH_ID[SIR_ROAM_R0KH_ID_MAX_LEN]; + tANI_U32 R0KH_ID_Length; + tANI_U8 RoamKeyMgmtOffloadEnabled; +#endif +} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq; + +typedef struct sSirRoamOffloadScanRsp +{ + tANI_U8 sessionId; + tANI_U32 reason; +} tSirRoamOffloadScanRsp, *tpSirRoamOffloadScanRsp; +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#define SIR_NOCHANGE_POWER_VALUE 0xFFFFFFFF + +//Power Parameters Type +typedef enum +{ + eSIR_IGNORE_DTIM = 1, + eSIR_LISTEN_INTERVAL = 2, + eSIR_MCAST_BCAST_FILTER = 3, + eSIR_ENABLE_BET = 4, + eSIR_BET_INTERVAL = 5 +}tPowerParamType; + +//Power Parameters Value s +typedef struct +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /* DTIM Period */ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicas Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; + + /* MAX LI for modulated DTIM */ + tANI_U32 uMaxLIModulatedDTIM; + +}tSirSetPowerParamsReq, *tpSirSetPowerParamsReq; + +typedef struct sSirTxPerTrackingParam +{ + tANI_U8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + tANI_U8 ucTxPerTrackingPeriod; /* Check period, unit is sec. Once tx_stat_chk enable, firmware will check PER in this period periodically */ + tANI_U8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. for example, 5 means 50% TX failed rate, default is 5. If current TX packet failed rate bigger than this ratio then firmware send WLC_E_TX_STAT_ERROR event to driver */ + tANI_U32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +}tSirTxPerTrackingParam, *tpSirTxPerTrackingParam; + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + Packet Filtering Parameters +---------------------------------------------------------------------------*/ +#define SIR_IPV4_ADDR_LEN 4 +#define SIR_MAC_ADDR_LEN 6 +#define SIR_MAX_FILTER_TEST_DATA_LEN 8 +#define SIR_MAX_NUM_MULTICAST_ADDRESS 240 +#define SIR_MAX_NUM_FILTERS 20 +#define SIR_MAX_NUM_TESTS_PER_FILTER 10 + +// +// Receive Filter Parameters +// +typedef enum +{ + SIR_RCV_FILTER_TYPE_INVALID, + SIR_RCV_FILTER_TYPE_FILTER_PKT, + SIR_RCV_FILTER_TYPE_BUFFER_PKT, + SIR_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}eSirReceivePacketFilterType; + +typedef enum +{ + SIR_FILTER_HDR_TYPE_INVALID, + SIR_FILTER_HDR_TYPE_MAC, + SIR_FILTER_HDR_TYPE_ARP, + SIR_FILTER_HDR_TYPE_IPV4, + SIR_FILTER_HDR_TYPE_IPV6, + SIR_FILTER_HDR_TYPE_UDP, + SIR_FILTER_HDR_TYPE_MAX +}eSirRcvPktFltProtocolType; + +typedef enum +{ + SIR_FILTER_CMP_TYPE_INVALID, + SIR_FILTER_CMP_TYPE_EQUAL, + SIR_FILTER_CMP_TYPE_MASK_EQUAL, + SIR_FILTER_CMP_TYPE_NOT_EQUAL, + SIR_FILTER_CMP_TYPE_MASK_NOT_EQUAL, + SIR_FILTER_CMP_TYPE_MAX +}eSirRcvPktFltCmpFlagType; + +typedef struct sSirRcvPktFilterFieldParams +{ + eSirRcvPktFltProtocolType protocolLayer; + eSirRcvPktFltCmpFlagType cmpFlag; + /* Length of the data to compare */ + tANI_U16 dataLength; + /* from start of the respective frame header */ + tANI_U8 dataOffset; + /* Reserved field */ + tANI_U8 reserved; + /* Data to compare */ + tANI_U8 compareData[SIR_MAX_FILTER_TEST_DATA_LEN]; + /* Mask to be applied on the received packet data before compare */ + tANI_U8 dataMask[SIR_MAX_FILTER_TEST_DATA_LEN]; +}tSirRcvPktFilterFieldParams, *tpSirRcvPktFilterFieldParams; + +typedef struct sSirRcvPktFilterCfg +{ + tANI_U8 filterId; + eSirReceivePacketFilterType filterType; + tANI_U32 numFieldParams; + tANI_U32 coalesceTime; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; //Bssid of the connected AP + tSirRcvPktFilterFieldParams paramsData[SIR_MAX_NUM_TESTS_PER_FILTER]; +}tSirRcvPktFilterCfgType, *tpSirRcvPktFilterCfgType; + +// +// Filter Packet Match Count Parameters +// +typedef struct sSirRcvFltPktMatchCnt +{ + tANI_U8 filterId; + tANI_U32 matchCnt; +} tSirRcvFltPktMatchCnt, tpSirRcvFltPktMatchCnt; + +typedef struct sSirRcvFltPktMatchRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + + /* Success or Failure */ + tANI_U32 status; + tSirRcvFltPktMatchCnt filterMatchCnt[SIR_MAX_NUM_FILTERS]; + tSirMacAddr bssId; +} tSirRcvFltPktMatchRsp, *tpSirRcvFltPktMatchRsp; + +// +// Receive Filter Clear Parameters +// +typedef struct sSirRcvFltPktClearParam +{ + tANI_U32 status; /* only valid for response message */ + tANI_U8 filterId; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; +}tSirRcvFltPktClearParam, *tpSirRcvFltPktClearParam; + +// +// Multicast Address List Parameters +// +typedef struct sSirRcvFltMcAddrList +{ + tANI_U32 ulMulticastAddrCnt; + tSirMacAddr multicastAddr[SIR_MAX_NUM_MULTICAST_ADDRESS]; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; + tANI_U8 action; +} tSirRcvFltMcAddrList, *tpSirRcvFltMcAddrList; +#endif // WLAN_FEATURE_PACKET_FILTERING + +// +// Generic version information +// +typedef struct +{ + tANI_U8 revision; + tANI_U8 version; + tANI_U8 minor; + tANI_U8 major; +} tSirVersionType; + +typedef struct sAniBtAmpLogLinkReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; //sme Session Id + void *btampHandle; //AMP context + +} tAniBtAmpLogLinkReq, *tpAniBtAmpLogLinkReq; + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- +* WDA_GTK_OFFLOAD_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 ulFlags; /* optional flags */ + tANI_U8 aKCK[16]; /* Key confirmation key */ + tANI_U8 aKEK[16]; /* key encryption key */ + tANI_U64 ullKeyReplayCounter; /* replay counter */ + tSirMacAddr bssId; +} tSirGtkOffloadParams, *tpSirGtkOffloadParams; + +/*--------------------------------------------------------------------------- +* WDA_GTK_OFFLOAD_GETINFO_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + + tANI_U32 ulStatus; /* success or failure */ + tANI_U64 ullKeyReplayCounter; /* current replay counter value */ + tANI_U32 ulTotalRekeyCount; /* total rekey attempts */ + tANI_U32 ulGTKRekeyCount; /* successful GTK rekeys */ + tANI_U32 ulIGTKRekeyCount; /* successful iGTK rekeys */ + tSirMacAddr bssId; +} tSirGtkOffloadGetInfoRspParams, *tpSirGtkOffloadGetInfoRspParams; +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +/*--------------------------------------------------------------------------- + tSirWakeReasonInd +---------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U32 ulReason; /* see tWakeReasonType */ + tANI_U32 ulReasonArg; /* argument specific to the reason type */ + tANI_U32 ulStoredDataLen; /* length of optional data stored in this message, in case + HAL truncates the data (i.e. data packets) this length + will be less than the actual length */ + tANI_U32 ulActualDataLen; /* actual length of data */ + tANI_U8 aDataStart[1]; /* variable length start of data (length == storedDataLen) + see specific wake type */ +} tSirWakeReasonInd, *tpSirWakeReasonInd; +#endif // WLAN_WAKEUP_EVENTS + +/*--------------------------------------------------------------------------- + sAniSetTmLevelReq +---------------------------------------------------------------------------*/ +typedef struct sAniSetTmLevelReq +{ + tANI_U16 tmMode; + tANI_U16 newTmLevel; +} tAniSetTmLevelReq, *tpAniSetTmLevelReq; + +#ifdef FEATURE_WLAN_TDLS +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsSendMgmtReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U8 reqType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; + tANI_U8 addIe[1]; //Variable lenght. Dont add any field after this. +} tSirTdlsSendMgmtReq, *tpSirSmeTdlsSendMgmtReq ; + +typedef enum TdlsAddOper +{ + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +} eTdlsAddOper; + +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsAddStaReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + eTdlsAddOper tdlsAddOper; + tSirMacAddr peerMac; + tANI_U16 capability; + tANI_U8 extn_capability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supported_rates_length; + tANI_U8 supported_rates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap htCap; + tANI_U8 vhtcap_present; + tSirVHTCap vhtCap; + tANI_U8 uapsd_queues; + tANI_U8 max_sp; +} tSirTdlsAddStaReq, *tpSirSmeTdlsAddStaReq ; + +/* TDLS Response struct PE-->SME */ +typedef struct sSirTdlsAddStaRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U8 sessionId; // Session ID + tANI_U16 staId ; + tANI_U16 staType ; + tANI_U8 ucastSig; + tANI_U8 bcastSig; + eTdlsAddOper tdlsAddOper; +} tSirTdlsAddStaRsp ; + +/* TDLS Request struct SME-->PE */ +typedef struct +{ + tANI_U16 messageType; // eWNI_SME_TDLS_LINK_ESTABLISH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U8 uapsdQueues; // Peer's uapsd Queues Information + tANI_U8 maxSp; // Peer's Supported Maximum Service Period + tANI_U8 isBufSta; // Does Peer Support as Buffer Station. + tANI_U8 isOffChannelSupported; // Does Peer Support as TDLS Off Channel. + tANI_U8 isResponder; // Is Peer a responder. + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tSirTdlsLinkEstablishReq, *tpSirTdlsLinkEstablishReq; + +/* TDLS Request struct SME-->PE */ +typedef struct +{ + tANI_U16 messageType; // eWNI_SME_TDLS_LINK_ESTABLISH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMac; +}tSirTdlsLinkEstablishReqRsp, *tpSirTdlsLinkEstablishReqRsp; + +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsDelStaReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; +} tSirTdlsDelStaReq, *tpSirSmeTdlsDelStaReq ; +/* TDLS Response struct PE-->SME */ +typedef struct sSirTdlsDelStaRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U16 staId; +} tSirTdlsDelStaRsp, *tpSirTdlsDelStaRsp; +/* TDLS Delete Indication struct PE-->SME */ +typedef struct sSirTdlsDelStaInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirMacAddr peerMac; + tANI_U16 staId; + tANI_U16 reasonCode; +} tSirTdlsDelStaInd, *tpSirTdlsDelStaInd; +typedef struct sSirTdlsDelAllPeerInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID +} tSirTdlsDelAllPeerInd, *tpSirTdlsDelAllPeerInd; +#ifdef FEATURE_WLAN_TDLS_DISAPPEAR_AP +typedef struct sSirTdlsDisappearAPInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 staId; + tSirMacAddr staAddr; +} tSirTdlsDisappearAPInd, *tpSirTdlsDisappearAPInd; +#endif +typedef struct sSirMgmtTxCompletionInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U32 txCompleteStatus; +} tSirMgmtTxCompletionInd, *tpSirMgmtTxCompletionInd; + +typedef struct sSirTdlsEventNotify +{ + tANI_U8 sessionId; + tSirMacAddr peerMac; + tANI_U16 messageType; + tANI_U32 peer_reason; +} tSirTdlsEventNotify; +#endif /* FEATURE_WLAN_TDLS */ + + +typedef struct sSirActiveModeSetBcnFilterReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 seesionId; +} tSirSetActiveModeSetBncFilterReq, *tpSirSetActiveModeSetBncFilterReq; + +//Reset AP Caps Changed +typedef struct sSirResetAPCapsChange +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr bssId; +} tSirResetAPCapsChange, *tpSirResetAPCapsChange; + +/// Definition for Candidate found indication from FW +typedef struct sSirSmeCandidateFoundInd +{ + tANI_U16 messageType; // eWNI_SME_CANDIDATE_FOUND_IND + tANI_U16 length; + tANI_U8 sessionId; // Session Identifier +} tSirSmeCandidateFoundInd, *tpSirSmeCandidateFoundInd; + +#ifdef WLAN_FEATURE_11W +typedef struct sSirWlanExcludeUnencryptParam +{ + tANI_BOOLEAN excludeUnencrypt; + tSirMacAddr bssId; +}tSirWlanExcludeUnencryptParam,*tpSirWlanExcludeUnencryptParam; +#endif + +typedef enum { + P2P_SCAN_TYPE_SEARCH = 1, /* P2P Search */ + P2P_SCAN_TYPE_LISTEN /* P2P Listen */ +}tSirP2pScanType; + +typedef struct sAniHandoffReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 bssid[VOS_MAC_ADDR_SIZE]; + tANI_U8 channel; + tANI_U8 handoff_src; +} tAniHandoffReq, *tpAniHandoffReq; + +typedef struct sSirScanOffloadReq { + tANI_U8 sessionId; + tSirMacAddr bssId; + tANI_U8 numSsid; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tANI_U8 hiddenSsid; + tSirMacAddr selfMacAddr; + tSirBssType bssType; + tANI_U8 dot11mode; + tSirScanType scanType; + tANI_U32 minChannelTime; + tANI_U32 maxChannelTime; + tANI_U32 restTime; //in units of milliseconds, ignored when not connected + tSirP2pScanType p2pScanType; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + tSirChannelList channelList; + /*----------------------------- + sSirScanOffloadReq.... + ----------------------------- + uIEFieldLen + ----------------------------- + uIEFieldOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEField + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tSirScanOffloadReq, *tpSirScanOffloadReq; + +typedef enum sSirScanEventType { + SCAN_EVENT_STARTED=0x1, /* Scan command accepted by FW */ + SCAN_EVENT_COMPLETED=0x2, /* Scan has been completed by FW */ + SCAN_EVENT_BSS_CHANNEL=0x4, /* FW is going to move to HOME channel */ + SCAN_EVENT_FOREIGN_CHANNEL = 0x8,/* FW is going to move to FORIEGN channel */ + SCAN_EVENT_DEQUEUED=0x10, /* scan request got dequeued */ + SCAN_EVENT_PREEMPTED=0x20, /* preempted by other high priority scan */ + SCAN_EVENT_START_FAILED=0x40, /* scan start failed */ + SCAN_EVENT_RESTARTED=0x80, /*scan restarted*/ + SCAN_EVENT_MAX=0x8000 +} tSirScanEventType; + +typedef struct sSirScanOffloadEvent{ + tSirScanEventType event; + tSirResultCodes reasonCode; + tANI_U32 chanFreq; + tANI_U32 requestor; + tANI_U32 scanId; + tSirP2pScanType p2pScanType; + tANI_U8 sessionId; +} tSirScanOffloadEvent, *tpSirScanOffloadEvent; + +typedef struct sSirUpdateChanParam +{ + tANI_U8 chanId; + tANI_U8 pwr; + tANI_BOOLEAN dfsSet; +} tSirUpdateChanParam, *tpSirUpdateChanParam; + +typedef struct sSirUpdateChan +{ + tANI_U8 numChan; + tSirUpdateChanParam chanParam[1]; +} tSirUpdateChanList, *tpSirUpdateChanList; + +typedef enum eSirAddonPsReq +{ + eSIR_ADDON_NOTHING, + eSIR_ADDON_ENABLE_UAPSD, + eSIR_ADDON_DISABLE_UAPSD +}tSirAddonPsReq; + +/* Powersave Offload data */ +typedef struct sSirPsReqData +{ + /* BSSID */ + tSirMacAddr bssId; + + /* Additional Info */ + tSirAddonPsReq addOnReq; +} tSirPsReqData,*tpSirPsReqData; + +#ifdef FEATURE_WLAN_LPHB +#define SIR_LPHB_FILTER_LEN 64 + +typedef enum +{ + LPHB_SET_EN_PARAMS_INDID, + LPHB_SET_TCP_PARAMS_INDID, + LPHB_SET_TCP_PKT_FILTER_INDID, + LPHB_SET_UDP_PARAMS_INDID, + LPHB_SET_UDP_PKT_FILTER_INDID, + LPHB_SET_NETWORK_INFO_INDID, +} LPHBIndType; + +typedef struct sSirLPHBEnableStruct +{ + v_U8_t enable; + v_U8_t item; + v_U8_t session; +} tSirLPHBEnableStruct; + +typedef struct sSirLPHBTcpParamStruct +{ + v_U32_t srv_ip; + v_U32_t dev_ip; + v_U16_t src_port; + v_U16_t dst_port; + v_U16_t timeout; + v_U8_t session; + tSirMacAddr gateway_mac; + uint16 timePeriodSec; // in seconds + uint32 tcpSn; +} tSirLPHBTcpParamStruct; + +typedef struct sSirLPHBTcpFilterStruct +{ + v_U16_t length; + v_U8_t offset; + v_U8_t session; + v_U8_t filter[SIR_LPHB_FILTER_LEN]; +} tSirLPHBTcpFilterStruct; + +typedef struct sSirLPHBUdpParamStruct +{ + v_U32_t srv_ip; + v_U32_t dev_ip; + v_U16_t src_port; + v_U16_t dst_port; + v_U16_t interval; + v_U16_t timeout; + v_U8_t session; + tSirMacAddr gateway_mac; +} tSirLPHBUdpParamStruct; + +typedef struct sSirLPHBUdpFilterStruct +{ + v_U16_t length; + v_U8_t offset; + v_U8_t session; + v_U8_t filter[SIR_LPHB_FILTER_LEN]; +} tSirLPHBUdpFilterStruct; + +typedef struct sSirLPHBReq +{ + v_U16_t cmd; + v_U16_t dummy; + union + { + tSirLPHBEnableStruct lphbEnableReq; + tSirLPHBTcpParamStruct lphbTcpParamReq; + tSirLPHBTcpFilterStruct lphbTcpFilterReq; + tSirLPHBUdpParamStruct lphbUdpParamReq; + tSirLPHBUdpFilterStruct lphbUdpFilterReq; + } params; +} tSirLPHBReq; + +typedef struct sSirLPHBInd +{ + v_U8_t sessionIdx; + v_U8_t protocolType; /*TCP or UDP*/ + v_U8_t eventReason; +} tSirLPHBInd; +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_CH_AVOID +typedef struct sSirChAvoidUpdateReq +{ + tANI_U32 reserved_param; +} tSirChAvoidUpdateReq; +#endif /* FEATURE_WLAN_CH_AVOID */ + +typedef struct sSirLinkSpeedInfo +{ + /* MAC Address for the peer */ + tSirMacAddr peer_macaddr; + tANI_U32 estLinkSpeed; //Linkspeed from firmware +} tSirLinkSpeedInfo, *tpSirLinkSpeedInfo; + +typedef struct sSirAddPeriodicTxPtrn +{ + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + tANI_U8 ucPtrnId; // Pattern ID + tANI_U16 ucPtrnSize; // Pattern size + tANI_U32 usPtrnIntervalMs; // In msec + tANI_U8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} tSirAddPeriodicTxPtrn, *tpSirAddPeriodicTxPtrn; + +typedef struct sSirDelPeriodicTxPtrn +{ + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + /* Bitmap of pattern IDs that need to be deleted */ + tANI_U32 ucPatternIdBitmap; + tANI_U8 ucPtrnId; // Pattern ID +} tSirDelPeriodicTxPtrn, *tpSirDelPeriodicTxPtrn; + +#ifdef FEATURE_WLAN_BATCH_SCAN +// Set batch scan resposne from FW +typedef struct +{ + /*maximum number of scans which FW can cache*/ + tANI_U32 nScansToBatch; +} tSirSetBatchScanRsp, *tpSirSetBatchScanRsp; + +// Set batch scan request to FW +typedef struct +{ + tANI_U32 sessionId; + tANI_U32 scanFrequency; /* how frequent to do scan - default 30Sec*/ + tANI_U32 numberOfScansToBatch; /* number of scans to batch */ + tANI_U32 bestNetwork; /* best networks in terms of rssi */ + tANI_U8 rfBand; /* band to scan : + 0 ->both Band, 1->2.4Ghz Only + and 2-> 5GHz Only */ + tANI_U32 rtt; /* set if required to do RTT it is not + supported in current version */ +} tSirSetBatchScanReq, *tpSirSetBatchScanReq; + + +// Stop batch scan request to FW +typedef struct +{ + tANI_U32 param; +} tSirStopBatchScanInd, *tpSirStopBatchScanInd; + +// Trigger batch scan result indication to FW +typedef struct +{ + tANI_U32 param; +} tSirTriggerBatchScanResultInd, *tpSirTriggerBatchScanResultInd; + +// Batch scan result indication from FW +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssid[6]; /* BSSID */ + tANI_U8 ssid[33]; /* SSID */ + tANI_U8 ch; /* Channel */ + tANI_S8 rssi; /* RSSI or Level */ + /*Timestamp when Network was found. Used to calculate age based on timestamp + in GET_RSP msg header */ + tANI_U32 timestamp; +} tSirBatchScanNetworkInfo, *tpSirBatchScanNetworkInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 scanId; /* Scan List ID. */ + /*No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg*/ + tANI_U32 numNetworksInScanList; + /*Variable data ptr: Number of AP in Scan List*/ + /*Following numNetworkInScanList is data of type tSirBatchScanNetworkInfo + *of sizeof(tSirBatchScanNetworkInfo) * numNetworkInScanList */ + tANI_U8 scanList[1]; +} tSirBatchScanList, *tpSirBatchScanList; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 timestamp; + tANI_U32 numScanLists; + boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + /* following isLastResult is data of type tSirBatchScanList + * of sizeof(tSirBatchScanList) * numScanLists*/ + tANI_U8 scanResults[1]; +} tSirBatchScanResultIndParam, *tpSirBatchScanResultIndParam; + +#endif // FEATURE_WLAN_BATCH_SCAN + +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_BOOLEAN suspended; +} tSirReadyToSuspendInd, *tpSirReadyToSuspendInd; +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_BOOLEAN status; +} tSirReadyToExtWoWInd, *tpSirReadyToExtWoWInd; +#endif +typedef struct sSirRateUpdateInd +{ + tANI_U8 nss; /* 0: 1x1, 1: 2x2 */ + tSirMacAddr bssid; + tVOS_CON_MODE dev_mode; + tANI_S32 bcastDataRate; /* bcast rate unit Mbpsx10, -1 : not used */ + /* 0 implies RA, positive value implies fixed rate, -1 implies ignore this + * param. + */ + tANI_S32 ucastDataRate; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags ucastDataRateTxFlag; + + /* + * 0 implies MCAST RA, positive value implies fixed rate, + * -1 implies ignore this param + */ + tANI_S32 reliableMcastDataRate;//unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags reliableMcastDataRateTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10, + * 0 implies ignore + */ + tANI_U32 mcastDataRate24GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags mcastDataRate24GHzTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 5 GHz, + * unit Mbpsx10, 0 implies ignore + */ + tANI_U32 mcastDataRate5GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags mcastDataRate5GHzTxFlag; + +} tSirRateUpdateInd, *tpSirRateUpdateInd; + +#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC) +#define SIR_CH_AVOID_MAX_RANGE 4 + +typedef struct sSirChAvoidFreqType +{ + tANI_U32 start_freq; + tANI_U32 end_freq; +} tSirChAvoidFreqType; + +typedef struct sSirChAvoidIndType +{ + tANI_U32 avoid_range_count; + tSirChAvoidFreqType avoid_freq_range[SIR_CH_AVOID_MAX_RANGE]; +} tSirChAvoidIndType; +#endif /* FEATURE_WLAN_CH_AVOID || FEATURE_WLAN_FORCE_SAP_SCC */ + +#define SIR_DFS_MAX_20M_SUB_CH 8 + +typedef struct sSirSmeDfsChannelList +{ + tANI_U32 nchannels; + /*Channel number including bonded channels on which the RADAR is present */ + tANI_U8 channels[SIR_DFS_MAX_20M_SUB_CH]; +}tSirSmeDfsChannelList, *tpSirSmeDfsChannelList; + +typedef struct sSirSmeDfsEventInd +{ + tANI_U32 sessionId; + tSirSmeDfsChannelList chan_list; + tANI_U32 dfs_radar_status; + int use_nol; +}tSirSmeDfsEventInd, *tpSirSmeDfsEventInd; + +typedef struct sSirChanChangeRequest +{ + tANI_U16 messageType; + tANI_U16 messageLen; + tANI_U8 targetChannel; + tANI_U8 cbMode; + tANI_U8 bssid[VOS_MAC_ADDR_SIZE]; +}tSirChanChangeRequest, *tpSirChanChangeRequest; + +typedef struct sSirChanChangeResponse +{ + tANI_U8 sessionId; + tANI_U8 newChannelNumber; + tANI_U8 channelChangeStatus; + ePhyChanBondState secondaryChannelOffset; +}tSirChanChangeResponse, *tpSirChanChangeResponse; + +typedef struct sSirStartBeaconIndication +{ + tANI_U16 messageType; + tANI_U16 messageLen; + tANI_U8 beaconStartStatus; + tANI_U8 bssid[VOS_MAC_ADDR_SIZE]; +}tSirStartBeaconIndication, *tpSirStartBeaconIndication; + +/* additional IE type */ +typedef enum tUpdateIEsType +{ + eUPDATE_IE_NONE, + eUPDATE_IE_PROBE_BCN, + eUPDATE_IE_PROBE_RESP, + eUPDATE_IE_ASSOC_RESP, + + /* Add type above this line*/ + /* this is used to reset all buffer */ + eUPDATE_IE_ALL, + eUPDATE_IE_MAX +} eUpdateIEsType; + + +/* Modify particular IE in addition IE for prob resp Bcn */ +typedef struct sSirModifyIE +{ + tSirMacAddr bssid; + tANI_U16 smeSessionId; + boolean notify; + tANI_U8 ieID; + tANI_U8 ieIDLen; /*ie length as per spec*/ + tANI_U16 ieBufferlength; + tANI_U8 *pIEBuffer; + +}tSirModifyIE, *tpSirModifyIE; + + +/* Message format for Update IE message sent to PE */ +typedef struct sSirModifyIEsInd +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tSirModifyIE modifyIE; + eUpdateIEsType updateType; +}tSirModifyIEsInd, *tpSirModifyIEsInd; + + +/* Message format for Update IE message sent to PE */ +typedef struct sSirUpdateIE +{ + tSirMacAddr bssid; + tANI_U16 smeSessionId; + boolean append; + boolean notify; + tANI_U16 ieBufferlength; + tANI_U8 *pAdditionIEBuffer; +}tSirUpdateIE, *tpSirUpdateIE; + + +/* Message format for Update IE message sent to PE */ +typedef struct sSirUpdateIEsInd +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tSirUpdateIE updateIE; + eUpdateIEsType updateType; +}tSirUpdateIEsInd, *tpSirUpdateIEsInd; + +/* Message format for requesting channel switch announcement to lower layers */ +typedef struct sSirDfsCsaIeRequest +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tANI_U8 targetChannel; + tANI_U8 csaIeRequired; + tANI_U8 bssid[VOS_MAC_ADDR_SIZE]; +}tSirDfsCsaIeRequest, *tpSirDfsCsaIeRequest; + +/* Indication from lower layer indicating the completion of first beacon send + * after the beacon template update + */ +typedef struct sSirFirstBeaconTxCompleteInd +{ + tANI_U16 messageType; // eWNI_SME_MISSED_BEACON_IND + tANI_U16 length; + tANI_U8 bssIdx; +}tSirFirstBeaconTxCompleteInd, *tpSirFirstBeaconTxCompleteInd; + +typedef struct sSirSmeCSAIeTxCompleteRsp +{ + tANI_U8 sessionId; + tANI_U8 chanSwIeTxStatus; +}tSirSmeCSAIeTxCompleteRsp, *tpSirSmeCSAIeTxCompleteRsp; + +/* Thermal Mitigation*/ + +typedef struct{ + u_int16_t minTempThreshold; + u_int16_t maxTempThreshold; +} t_thermal_level_info, *tp_thermal_level_info; + +typedef enum +{ + WLAN_WMA_THERMAL_LEVEL_0, + WLAN_WMA_THERMAL_LEVEL_1, + WLAN_WMA_THERMAL_LEVEL_2, + WLAN_WMA_THERMAL_LEVEL_3, + WLAN_WMA_MAX_THERMAL_LEVELS +} t_thermal_level; + +typedef struct{ + /* Array of thermal levels */ + t_thermal_level_info thermalLevels[WLAN_WMA_MAX_THERMAL_LEVELS]; + u_int8_t thermalCurrLevel; + u_int8_t thermalMgmtEnabled; + u_int32_t throttlePeriod; +} t_thermal_mgmt, *tp_thermal_mgmt; + +typedef struct sSirTxPowerLimit +{ + /* Thermal limits for 2g and 5g */ + u_int32_t txPower2g; + u_int32_t txPower5g; +} tSirTxPowerLimit; + +// Notify MODEM power state to FW +typedef struct +{ + tANI_U32 param; +} tSirModemPowerStateInd, *tpSirModemPowerStateInd; + +#ifdef WLAN_FEATURE_STATS_EXT +typedef struct +{ + tANI_U32 vdev_id; + tANI_U32 event_data_len; + u_int8_t event_data[]; +} tSirStatsExtEvent, *tpSirStatsExtEvent; +#endif + +#ifdef WLAN_FEATURE_NAN +typedef struct +{ + tANI_U32 event_data_len; + tANI_U8 event_data[]; +} tSirNanEvent, *tpSirNanEvent; +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +typedef struct sSirSmeRoamOffloadSynchInd +{ + tANI_U16 messageType; /*eWNI_SME_ROAM_OFFLOAD_SYNCH_IND*/ + tANI_U16 length; + tANI_U16 beaconProbeRespOffset; + tANI_U16 beaconProbeRespLength; + tANI_U16 reassocRespOffset; + tANI_U16 reassocRespLength; + tANI_U8 isBeacon; + tANI_U8 roamedVdevId; + tSirMacAddr bssId; + tANI_S8 txMgmtPower; + tANI_U32 authStatus; + tANI_U8 rssi; + tANI_U8 roamReason; + tANI_U32 chan_freq; + tANI_U8 kck[SIR_KCK_KEY_LEN]; + tANI_U8 kek[SIR_KEK_KEY_LEN]; + tANI_U8 replay_ctr[SIR_REPLAY_CTR_LEN]; + tpSirBssDescription pbssDescription; +} tSirRoamOffloadSynchInd, *tpSirRoamOffloadSynchInd; + +typedef struct sSirSmeRoamOffloadSynchCnf +{ + tANI_U8 sessionId; +} tSirSmeRoamOffloadSynchCnf, *tpSirSmeRoamOffloadSynchCnf; + +typedef struct sSirSmeHOFailureInd +{ + tANI_U8 sessionId; +} tSirSmeHOFailureInd, *tpSirSmeHOFailureInd; + +typedef struct sSirRoamOffloadSynchFail +{ + tANI_U8 sessionId; +} tSirRoamOffloadSynchFail, *tpSirRoamOffloadSynchFail; +#endif + +#ifdef FEATURE_WLAN_EXTSCAN + +typedef enum +{ + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_BG = 1, /* 2.4 GHz */ + WIFI_BAND_A = 2, /* 5 GHz without DFS */ + WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ + WIFI_BAND_A_DFS_ONLY = 4, /* 5 GHz DFS only */ + /* 5 is reserved */ + WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ + WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ + + /* Keep it last */ + WIFI_BAND_MAX +} tWifiBand; + +/* wifi scan related events */ +typedef enum +{ + WIFI_SCAN_BUFFER_FULL, + WIFI_SCAN_COMPLETE, +} tWifiScanEventType; + +typedef struct +{ + tSirMacAddr bssid; + + /* Low threshold */ + tANI_S32 low; + + /* High threshold */ + tANI_S32 high; + + /* Frequency in MHz*/ + tANI_U32 channel; +} tSirAPThresholdParam, *tpSirAPThresholdParam; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirGetExtScanCapabilitiesReqParams, *tpSirGetExtScanCapabilitiesReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; + + tANI_U32 scanCacheSize; + tANI_U32 scanBuckets; + tANI_U32 maxApPerScan; + tANI_U32 maxRssiSampleSize; + tANI_U32 maxScanReportingThreshold; + + tANI_U32 maxHotlistAPs; + tANI_U32 maxSignificantWifiChangeAPs; + + tANI_U32 maxBsidHistoryEntries; +} tSirExtScanCapabilitiesEvent, *tpSirExtScanCapabilitiesEvent; + + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; + + /* + * 1 - return cached results and flush it + * 0 - return cached results and do not flush + */ + tANI_BOOLEAN flush; +} tSirExtScanGetCachedResultsReqParams, *tpSirExtScanGetCachedResultsReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanGetCachedResultsRspParams, *tpSirExtScanGetCachedResultsRspParams; + +typedef struct +{ + /* Time of discovery (in micro second) */ + tANI_U64 ts; + + /* Null terminated SSID */ + tANI_U8 ssid[SIR_MAC_MAX_SSID_LENGTH+1]; + + tSirMacAddr bssid; + + /* Frequency in MHz */ + tANI_U32 channel; + + /* RSSI in dBm */ + tANI_S32 rssi; + + /* RTT in nanoseconds */ + tANI_U32 rtt; + + /* Standard deviation in rtt */ + tANI_U32 rtt_sd; + + /* Period advertised in the beacon */ + tANI_U16 beaconPeriod; + + /* Capabilities advertised in the beacon */ + tANI_U16 capability; + + tANI_U16 ieLength; + + tANI_U8 ieData[]; +} tSirWifiScanResult, *tpSirWifiScanResult; + +typedef struct +{ + tANI_U32 requestId; + + tANI_U32 numOfAps; + + /* + * 0 - for last fragment + * 1 - still more fragment(s) coming + */ + tANI_BOOLEAN moreData; + tSirWifiScanResult ap[]; +} tSirWifiScanResultEvent, *tpSirWifiScanResultEvent; + +/* + * Reported when each probe response is received, if reportEvents + * enabled in tSirWifiScanCmdReqParams + */ +typedef struct +{ + tANI_U32 requestId; + + /* + * 0 - for last fragment + * 1 - still more fragment(s) coming + */ + tANI_BOOLEAN moreData; + tSirWifiScanResult ap; +} tSirWifiFullScanResultEvent, *tpSirWifiFullScanResultEvent; + + +typedef struct +{ + /* Frequency in MHz*/ + tANI_U32 channel; + + tANI_U32 dwellTimeMs; + + /* 0 => active + 1 => passive scan; ignored for DFS */ + tANI_BOOLEAN passive; + + tANI_U8 chnlClass; +} tSirWifiScanChannelSpec, *tpSirWifiScanChannelSpec; + +typedef struct +{ + /* Bucket index, 0 based */ + tANI_U8 bucket; + + /* when UNSPECIFIED, use channel list */ + tWifiBand band; + + /* + * Desired period, in millisecond; if this is too + * low, the firmware should choose to generate results as fast as + * it can instead of failing the command byte + */ + tANI_U32 period; + + /* + * 0 => normal reporting (reporting rssi history + * only, when rssi history buffer is % full) + * 1 => same as 0 + report a scan completion event after scanning + * this bucket + * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) + * in real time to HAL + */ + tANI_U32 reportEvents; + + tANI_U32 numChannels; + + /* + * Channels to scan; these may include DFS channels + */ + tSirWifiScanChannelSpec channels[WLAN_EXTSCAN_MAX_CHANNELS]; +} tSirWifiScanBucketSpec, *tpSirWifiScanBucketSpec; + +typedef struct +{ + /* Base timer period */ + tANI_U32 basePeriod; + tANI_U32 maxAPperScan; + + /* in %, when buffer is this much full, wake up host */ + tANI_U32 reportThreshold; + tANI_U32 requestId; + tANI_U8 sessionId; + + tANI_U32 numBuckets; + tSirWifiScanBucketSpec buckets[WLAN_EXTSCAN_MAX_BUCKETS]; +} tSirWifiScanCmdReqParams, *tpSirWifiScanCmdReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanStartRspParams, *tpSirExtScanStartRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirExtScanStopReqParams, *tpSirExtScanStopReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanStopRspParams, *tpSirExtScanStopRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; + + /* Number of hotlist APs */ + tANI_U32 numAp; + tSirAPThresholdParam ap[WLAN_EXTSCAN_MAX_HOTLIST_APS]; +} tSirExtScanSetBssidHotListReqParams, *tpSirExtScanSetBssidHotListReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanSetBssidHotListRspParams, *tpSirExtScanSetBssidHotListRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirExtScanResetBssidHotlistReqParams, + *tpSirExtScanResetBssidHotlistReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanResetBssidHotlistRspParams, + *tpSirExtScanResetBssidHotlistRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; + + /* Number of samples for averaging RSSI */ + tANI_U32 rssiSampleSize; + + /* Number of missed samples to confirm AP loss */ + tANI_U32 lostApSampleSize; + + /* Number of APs breaching threshold required for firmware + * to generate event + */ + tANI_U32 minBreaching; + + tANI_U32 numAp; + tSirAPThresholdParam ap[WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS]; +} tSirExtScanSetSigChangeReqParams, + *tpSirExtScanSetSigChangeReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanSetSignificantChangeRspParams, + *tpSirExtScanSetSignificantChangeRspParams; + +typedef struct +{ + tSirMacAddr bssid; + tANI_U32 channel; + tANI_U32 numOfRssi; + + /* Rssi history in db */ + tANI_S32 rssi[]; +} tSirWifiSignificantChange, *tpSirWifiSignificantChange; + +typedef struct +{ + tANI_U32 requestId; + + tANI_BOOLEAN moreData; + tANI_U32 numResults; + tSirWifiSignificantChange ap[]; +} tSirWifiSignificantChangeEvent, *tpSirWifiSignificantChangeEvent; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirExtScanResetSignificantChangeReqParams, + *tpSirExtScanResetSignificantChangeReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirExtScanResetSignificantChangeRspParams, + *tpSirExtScanResetSignificantChangeRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 numResultsAvailable; +} tSirExtScanResultsAvailableIndParams, + *tpSirExtScanResultsAvailableIndParams; + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +typedef struct +{ + tANI_U32 timer_val; +} tSirAutoShutdownCmdParams; + +typedef struct +{ + tANI_U32 shutdown_reason; +} tSirAutoShutdownEvtParams; +#endif + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; + tANI_U8 scanEventType; +} tSirExtScanOnScanEventIndParams, + *tpSirExtScanOnScanEventIndParams; + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 mpduSizeThreshold; + tANI_U32 aggressiveStatisticsGathering; +} tSirLLStatsSetReq, *tpSirLLStatsSetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 paramIdMask; +} tSirLLStatsGetReq, *tpSirLLStatsGetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 statsClearReqMask; + tANI_U8 stopReq; +} tSirLLStatsClearReq, *tpSirLLStatsClearReq; + +typedef struct +{ + tANI_U8 oui[WIFI_SCANNING_MAC_OUI_LENGTH]; +} tSirScanMacOui, *tpSirScanMacOui; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_NOTIFY_STATS +---------------------------------------------------------------------------*/ + + +/******************************LINK LAYER Statistics**********************/ + +typedef int tSirWifiRadio; +typedef int tSirWifiChannel; +typedef int tSirwifiTxRate; + +/* channel operating width */ +typedef enum +{ + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, +} tSirWifiChannelWidth; + +typedef enum +{ + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ + WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ +} tSirWifiConnectionState; + +typedef enum +{ + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} tSirWifiRoamState; + +typedef enum +{ + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } tSirWifiInterfaceMode; + +/* set for QOS association */ +#define WIFI_CAPABILITY_QOS 0x00000001 +/* set for protected association (802.11 beacon frame control protected bit set) */ +#define WIFI_CAPABILITY_PROTECTED 0x00000002 +/* set if 802.11 Extended Capabilities element interworking bit is set */ +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 +/* set for HS20 association */ +#define WIFI_CAPABILITY_HS20 0x00000008 +/* set is 802.11 Extended Capabilities element UTF-8 SSID bit is set */ +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 +/* set is 802.11 Country Element is present */ +#define WIFI_CAPABILITY_COUNTRY 0x00000020 + +typedef struct +{ + /* tSirWifiInterfaceMode */ + /* interface mode */ + tANI_U8 mode; + /* interface mac address (self) */ + tSirMacAddr macAddr; + /* tSirWifiConnectionState */ + /* connection state (valid for STA, CLI only) */ + tANI_U8 state; + /* tSirWifiRoamState */ + /* roaming state */ + tANI_U32 roaming; + /* WIFI_CAPABILITY_XXX (self) */ + tANI_U32 capabilities; + /* null terminated SSID */ + tANI_U8 ssid[33]; + /* bssid */ + tSirMacAddr bssid; + /* country string advertised by AP */ + tANI_U8 apCountryStr[WNI_CFG_COUNTRY_CODE_LEN]; + /* country string for this association */ + tANI_U8 countryStr[WNI_CFG_COUNTRY_CODE_LEN]; +} tSirWifiInterfaceInfo, *tpSirWifiInterfaceInfo; + +/* channel information */ +typedef struct +{ + /* channel width (20, 40, 80, 80+80, 160) */ + tSirWifiChannelWidth width; + /* primary 20 MHz channel */ + tSirWifiChannel centerFreq; + /* center frequency (MHz) first segment */ + tSirWifiChannel centerFreq0; + /* center frequency (MHz) second segment */ + tSirWifiChannel centerFreq1; +} tSirWifiChannelInfo, *tpSirWifiChannelInfo; + +/* wifi rate info */ +typedef struct +{ + /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + tANI_U32 preamble :3; + /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + tANI_U32 nss :2; + /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + tANI_U32 bw :3; + /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ + /* HT/VHT it would be mcs index */ + tANI_U32 rateMcsIdx :8; + /* reserved */ + tANI_U32 reserved :16; + /* units of 100 Kbps */ + tANI_U32 bitrate; +} tSirWifiRate, *tpSirWifiRate; + +/* channel statistics */ +typedef struct +{ + /* channel */ + tSirWifiChannelInfo channel; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the CCA register is busy (32 bits number accruing over time) */ + tANI_U32 ccaBusyTime; +} tSirWifiChannelStats, *tpSirWifiChannelStats; + +/* radio statistics */ +typedef struct +{ + /* wifi radio (if multiple radio supported) */ + tSirWifiRadio radio; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the radio is transmitting + * (32 bits number accruing over time) + */ + tANI_U32 txTime; + /* msecs the radio is in active receive + *(32 bits number accruing over time) + */ + tANI_U32 rxTime; + /* msecs the radio is awake due to all scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeScan; + /* msecs the radio is awake due to NAN + * (32 bits number accruing over time) + */ + tANI_U32 onTimeNbd; + /* msecs the radio is awake due to Gscan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeGscan; + /* msecs the radio is awake due to roam?scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeRoamScan; + /* msecs the radio is awake due to PNO scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimePnoScan; + /* msecs the radio is awake due to HS2.0 scans and GAS exchange + * (32 bits number accruing over time) + */ + tANI_U32 onTimeHs20; + /* number of channels */ + tANI_U32 numChannels; + /* channel statistics tSirWifiChannelStats */ + tSirWifiChannelStats channels[0]; +} tSirWifiRadioStat, *tpSirWifiRadioStat; + +/* per rate statistics */ +typedef struct +{ + /* rate information */ + tSirWifiRate rate; + /* number of successfully transmitted data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received data pkts */ + tANI_U32 rxMpdu; + /* number of data packet losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries * */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; +} tSirWifiRateStat, *tpSirWifiRateStat; + +/* access categories */ +typedef enum +{ + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} tSirWifiTrafficAc; + +/* wifi peer type */ +typedef enum +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} tSirWifiPeerType; + +/* per peer statistics */ +typedef struct +{ + /* peer type (AP, TDLS, GO etc.) */ + tSirWifiPeerType type; + /* mac address */ + tSirMacAddr peerMacAddress; + /* peer WIFI_CAPABILITY_XXX */ + tANI_U32 capabilities; + /* number of rates */ + tANI_U32 numRate; + /* per rate statistics, number of entries = num_rate */ + tSirWifiRateStat rateStats[0]; +} tSirWifiPeerInfo, *tpSirWifiPeerInfo; + +/* per access category statistics */ +typedef struct +{ + /* tSirWifiTrafficAc */ + /* access category (VI, VO, BE, BK) */ + tANI_U32 ac; + /* number of successfully transmitted unicast data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received unicast mpdus */ + tANI_U32 rxMpdu; + /* number of succesfully transmitted multicast data packets */ + /* STA case: implies ACK received from AP for the unicast */ + /* packet in which mcast pkt was sent */ + tANI_U32 txMcast; + /* number of received multicast data packets */ + tANI_U32 rxMcast; + /* number of received unicast a-mpdus */ + tANI_U32 rxAmpdu; + /* number of transmitted unicast a-mpdus */ + tANI_U32 txAmpdu; + /* number of data pkt losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; + /* data pkt min contention time (usecs) */ + tANI_U32 contentionTimeMin; + /* data pkt max contention time (usecs) */ + tANI_U32 contentionTimeMax; + /* data pkt avg contention time (usecs) */ + tANI_U32 contentionTimeAvg; + /* num of data pkts used for contention statistics */ + tANI_U32 contentionNumSamples; +} tSirWifiWmmAcStat, *tpSirWifiWmmAcStat; + +/* Interface statistics - corresponding to 2nd most + * LSB in wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* current state of the interface */ + tSirWifiInterfaceInfo info; + /* access point beacon received count from connected AP */ + tANI_U32 beaconRx; + /* access point mgmt frames received count from */ + /* connected AP (including Beacon) */ + tANI_U32 mgmtRx; + /* action frames received count */ + tANI_U32 mgmtActionRx; + /* action frames transmit count */ + tANI_U32 mgmtActionTx; + /* access Point Beacon and Management frames RSSI (averaged) */ + tANI_U32 rssiMgmt; + /* access Point Data Frames RSSI (averaged) from connected AP */ + tANI_U32 rssiData; + /* access Point ACK RSSI (averaged) from connected AP */ + tANI_U32 rssiAck; + /* per ac data packet statistics */ + tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX]; +} tSirWifiIfaceStat, *tpSirWifiIfaceStat; + +/* Peer statistics - corresponding to 3rd most LSB in + * wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* number of peers */ + tANI_U32 numPeers; + /* per peer statistics */ + tSirWifiPeerInfo peerInfo[0]; +} tSirWifiPeerStat, *tpSirWifiPeerStat; + +/* wifi statistics bitmap for getting statistics */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + +/* wifi statistics bitmap for clearing statistics */ +/* all radio statistics */ +#define WIFI_STATS_RADIO 0x00000001 +/* cca_busy_time (within radio statistics) */ +#define WIFI_STATS_RADIO_CCA 0x00000002 +/* all channel statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 +/* all scan statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_SCAN 0x00000008 +/* all interface statistics */ +#define WIFI_STATS_IFACE 0x00000010 +/* all tx rate statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_TXRATE 0x00000020 +/* all ac statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_AC 0x00000040 +/* all contention (min, max, avg) statistics (within ac statistics) */ +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 + +typedef struct +{ + tANI_U32 paramId; + tANI_U8 ifaceId; + tANI_U32 rspId; + tANI_U32 moreResultToFollow; + union + { + tANI_U32 num_peers; + tANI_U32 num_radio; + }; + + tANI_U32 peer_event_number ; + /* Variable length field - Do not add anything after this */ + tANI_U8 results[0]; +} tSirLLStatsResults, *tpSirLLStatsResults; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +typedef struct sAniGetLinkStatus +{ + tANI_U16 msgType; /* message type is same as the request type */ + tANI_U16 msgLen; /* length of the entire request */ + tANI_U8 linkStatus; + tANI_U8 sessionId; +} tAniGetLinkStatus, *tpAniGetLinkStatus; + +/* find the size of given member within a structure */ +#ifndef member_size +#define member_size(type, member) (sizeof(((type *)0)->member)) +#endif + +#define RTT_INVALID 0x00 +#define RTT_TIMING_MEAS_CAPABILITY 0x01 +#define RTT_FINE_TIMING_MEAS_CAPABILITY 0x02 + +/* number of neighbor reports that we can handle in Neighbor Report Response */ +#define MAX_SUPPORTED_NEIGHBOR_RPT 15 + +/* Max number of rates allowed in Supported Rates IE */ +#define MAX_NUM_SUPPORTED_RATES (8) + +#endif /* __SIR_API_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacPropExts.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacPropExts.h new file mode 100644 index 0000000000000..40fa9a213a0bd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacPropExts.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sirMacPropExts.h contains the MAC protocol + * extensions to support ANI feature set. + * Author: Chandra Modumudi + * Date: 11/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __MAC_PROP_EXTS_H +#define __MAC_PROP_EXTS_H + +#include "sirTypes.h" +#include "sirApi.h" +#include "aniSystemDefs.h" + +/// EID (Element ID) definitions + +// Proprietary IEs + +// the bit map is also used as a config enable, setting a bit in the +// propIE config variable, enables the corresponding capability in the propIE +// the enables simply result in including the corresponding element in the +// propIE +// Ex: setting the capability bit HCF would result in using the capability bit map for +// hcf instead of including the full HCF element in the IE +// capabilities bit map - bit offsets +// setting 11eQos has effect only if QoS is also enabled. then it overrides +// 11e support and implements it silently (as part of the prop ie) +#define SIR_MAC_PROP_CAPABILITY_HCF WNI_CFG_PROP_CAPABILITY_HCF +#define SIR_MAC_PROP_CAPABILITY_11EQOS WNI_CFG_PROP_CAPABILITY_11EQOS +#define SIR_MAC_PROP_CAPABILITY_WME WNI_CFG_PROP_CAPABILITY_WME +#define SIR_MAC_PROP_CAPABILITY_WSM WNI_CFG_PROP_CAPABILITY_WSM +#define SIR_MAC_PROP_CAPABILITY_EXTRATES WNI_CFG_PROP_CAPABILITY_EXTRATES +// ap->sta only, request STA to stop using prop rates for some time +#define SIR_MAC_PROP_CAPABILITY_EXTRATE_STOP WNI_CFG_PROP_CAPABILITY_EXTRATE_STOP +#define SIR_MAC_PROP_CAPABILITY_TITAN WNI_CFG_PROP_CAPABILITY_TITAN +#define SIR_MAC_PROP_CAPABILITY_TAURUS WNI_CFG_PROP_CAPABILITY_TAURUS +#define SIR_MAC_PROP_CAPABILITY_ESCORT_PKT WNI_CFG_PROP_CAPABILITY_ESCORT_PKT +// unused 9-12 +#define SIR_MAC_PROP_CAPABILITY_EDCAPARAMS WNI_CFG_PROP_CAPABILITY_EDCAPARAMS +#define SIR_MAC_PROP_CAPABILITY_LOADINFO WNI_CFG_PROP_CAPABILITY_LOADINFO +#define SIR_MAC_PROP_CAPABILITY_VERSION WNI_CFG_PROP_CAPABILITY_VERSION +#define SIR_MAC_PROP_CAPABILITY_MAXBITOFFSET WNI_CFG_PROP_CAPABILITY_MAXBITOFFSET + +#define PROP_CAPABILITY_GET(bitname, value) \ + (((value) >> SIR_MAC_PROP_CAPABILITY_ ## bitname) & 1) + + +#define IS_DOT11_MODE_PROPRIETARY(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_POLARIS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TITAN) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + +#define IS_DOT11_MODE_HT(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_11N) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11N_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + +#ifdef WLAN_FEATURE_11AC +#define IS_DOT11_MODE_VHT(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_11AC) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) +#endif + +#define IS_DOT11_MODE_11B(dot11Mode) \ + ((dot11Mode == WNI_CFG_DOT11_MODE_11B) ? TRUE : FALSE) + +#define IS_BSS_VHT_CAPABLE(vhtCaps) \ + ((vhtCaps).present && \ + ((vhtCaps).rxMCSMap != 0xFFFF) && \ + ((vhtCaps).txMCSMap != 0xFFFF)) + +/// Proprietary IE definition +typedef struct sSirMacPropIE +{ + tANI_U8 elementID; // SIR_MAC_ANI_PROP_IE_EID + tANI_U8 length; + tANI_U8 oui[3]; // ANI_OUI for Airgo products + tANI_U8 info[1]; +} tSirMacPropIE, *tpSirMacPropIE; + + +typedef struct sSirMacPropRateSet +{ + tANI_U8 numPropRates; + tANI_U8 propRate[8]; +} tSirMacPropRateSet, *tpSirMacPropRateSet; + + +#define SIR_PROP_VERSION_STR_MAX 20 +typedef struct sSirMacPropVersion +{ + tANI_U32 chip_rev; // board, chipset info + tANI_U8 card_type; // Type of Card + tANI_U8 build_version[SIR_PROP_VERSION_STR_MAX]; //build version string +} tSirMacPropVersion, *tpSirMacPropVersion; + + +/* Default value for gLimRestoreCBNumScanInterval */ +#define LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT 2 + +// +// Proprietary Quite BSS IE structure +// +// Based on the setting of the "Titan" proprietary bit +// in the tSirPropIEStruct.capability field (bit #6), +// this IE will be sent appropriately to all the ANI +// peers in the following management frames - +// 1) Beacons +// 2) Probe Rsp +// +typedef struct sQuietBssIEStruct +{ + + // Indicates the number of TBTT's until the next beacon + // interval during which the next quiet interval will + // start + // 1 - Quiet Interval will start during the beacon + // interval starting at the next TBTT + // 0 - Reserved + tANI_U8 quietCount; + + // Shall be set to the number of beacon intervals between + // the start of regularly scheduled quiet intervals + // defined by this Quiet Element + // 0 - No periodic quiet interval is defined + tANI_U8 quietPeriod; + + // Duration of the quiet interval, expressed in TUs + // 1 TU = 1024 microseconds?? + tANI_U16 quietDuration; + + // Set to the offset of the start of the quiet interval + // from the TBTT specified by the quietCount field, + // expressed in TUs. The value of this offset field will + // be less than one beacon interval + // 1 TU = 1024 microseconds?? + tANI_U16 quietOffset; + +} tQuietBssIEStruct, *tpQuietBssIEStruct; + +typedef struct sChannelSwitchPropIEStruct +{ + tANI_U8 mode; + tANI_U8 primaryChannel; + tANI_U8 subBand; + tANI_U8 channelSwitchCount; + +} tChannelSwitchPropIEStruct, *tpChannelSwitchPropIEStruct; + +// generic proprietary IE structure definition +typedef struct sSirPropIEStruct +{ + tANI_U8 propRatesPresent:1; + tANI_U8 apNamePresent:1; + tANI_U8 loadBalanceInfoPresent:1; + tANI_U8 versionPresent:1; + tANI_U8 edcaParamPresent:1; + tANI_U8 capabilityPresent:1; + tANI_U8 titanPresent:1; + tANI_U8 taurusPresent:1; + tANI_U8 propChannelSwitchPresent:1; + tANI_U8 quietBssPresent:1; + tANI_U8 triggerStaScanPresent:1; + tANI_U8 rsvd:5; + + + tSirMacPropRateSet propRates; + tAniApName apName; // used in beacon/probe only + tSirAlternateRadioInfo alternateRadio; // used in assoc response only + tANI_U16 capability; // capability bit map + tSirMacPropVersion version; + tSirMacEdcaParamSetIE edca; + tChannelSwitchPropIEStruct channelSwitch; + tQuietBssIEStruct quietBss; + tANI_U8 triggerStaScanEnable; + + +} tSirPropIEStruct, *tpSirPropIEStruct; + + + +#endif /* __MAC_PROP_EXTS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h new file mode 100644 index 0000000000000..d826c494a3dc8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h @@ -0,0 +1,2298 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file sirMacProtDef.h contains the MAC/PHY protocol + * definitions used across various projects. + * Author: Chandra Modumudi + * Date: 02/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __MAC_PROT_DEFS_H +#define __MAC_PROT_DEFS_H + +#include "palTypes.h" +#include "sirTypes.h" +#include "wniCfgSta.h" +#include "aniCompiler.h" + + +///Capability information related +#define CAPABILITY_INFO_DELAYED_BA_BIT 14 +#define CAPABILITY_INFO_IMMEDIATE_BA_BIT 15 + +/// 11h MAC defaults +#define SIR_11A_CHANNEL_BEGIN 34 +#define SIR_11A_CHANNEL_END 165 +#define SIR_11B_CHANNEL_BEGIN 1 +#define SIR_11B_CHANNEL_END 14 +#define SIR_11A_FREQUENCY_OFFSET 4 +#define SIR_11B_FREQUENCY_OFFSET 1 + +/// Current version of 802.11 +#define SIR_MAC_PROTOCOL_VERSION 0 + +// Frame Type definitions + +#define SIR_MAC_MGMT_FRAME 0x0 +#define SIR_MAC_CTRL_FRAME 0x1 +#define SIR_MAC_DATA_FRAME 0x2 + +#define SIR_MAC_FRAME_TYPE_START 0x0 +#define SIR_MAC_FRAME_TYPE_END 0x3 + +// Control frame subtype definitions + +#define SIR_MAC_CTRL_RR 4 +#define SIR_MAC_CTRL_BAR 8 +#define SIR_MAC_CTRL_BA 9 +#define SIR_MAC_CTRL_PS_POLL 10 +#define SIR_MAC_CTRL_RTS 11 +#define SIR_MAC_CTRL_CTS 12 +#define SIR_MAC_CTRL_ACK 13 +#define SIR_MAC_CTRL_CF_END 14 +#define SIR_MAC_CTRL_CF_END_ACK 15 + +#define GEN4_SCAN 1 +#ifdef GEN4_SCAN +#define SIR_MAC_MAX_DURATION_MICRO_SECONDS 32767 +#endif // GEN4_SCAN + +// Data frame subtype definitions +#define SIR_MAC_DATA_DATA 0 +#define SIR_MAC_DATA_DATA_ACK 1 +#define SIR_MAC_DATA_DATA_POLL 2 +#define SIR_MAC_DATA_DATA_ACK_POLL 3 +#define SIR_MAC_DATA_NULL 4 +#define SIR_MAC_DATA_NULL_ACK 5 +#define SIR_MAC_DATA_NULL_POLL 6 +#define SIR_MAC_DATA_NULL_ACK_POLL 7 +#define SIR_MAC_DATA_QOS_DATA 8 +#define SIR_MAC_DATA_QOS_DATA_ACK 9 +#define SIR_MAC_DATA_QOS_DATA_POLL 10 +#define SIR_MAC_DATA_QOS_DATA_ACK_POLL 11 +#define SIR_MAC_DATA_QOS_NULL 12 +#define SIR_MAC_DATA_QOS_NULL_ACK 13 +#define SIR_MAC_DATA_QOS_NULL_POLL 14 +#define SIR_MAC_DATA_QOS_NULL_ACK_POLL 15 + +#define SIR_MAC_FRAME_SUBTYPE_START 0 +#define SIR_MAC_FRAME_SUBTYPE_END 16 + +#define SIR_MAC_DATA_QOS_MASK 8 +#define SIR_MAC_DATA_NULL_MASK 4 +#define SIR_MAC_DATA_POLL_MASK 2 +#define SIR_MAC_DATA_ACK_MASK 1 + +// Management frame subtype definitions + +#define SIR_MAC_MGMT_ASSOC_REQ 0x0 +#define SIR_MAC_MGMT_ASSOC_RSP 0x1 +#define SIR_MAC_MGMT_REASSOC_REQ 0x2 +#define SIR_MAC_MGMT_REASSOC_RSP 0x3 +#define SIR_MAC_MGMT_PROBE_REQ 0x4 +#define SIR_MAC_MGMT_PROBE_RSP 0x5 +#define SIR_MAC_MGMT_BEACON 0x8 +#define SIR_MAC_MGMT_ATIM 0x9 +#define SIR_MAC_MGMT_DISASSOC 0xA +#define SIR_MAC_MGMT_AUTH 0xB +#define SIR_MAC_MGMT_DEAUTH 0xC +#define SIR_MAC_MGMT_ACTION 0xD +#define SIR_MAC_MGMT_RESERVED15 0xF + +// Action frame categories + +#define SIR_MAC_ACTION_SPECTRUM_MGMT 0 +#define SIR_MAC_ACTION_QOS_MGMT 1 +#define SIR_MAC_ACTION_DLP 2 +#define SIR_MAC_ACTION_BLKACK 3 +#define SIR_MAC_ACTION_PUBLIC_USAGE 4 +#define SIR_MAC_ACTION_RRM 5 +#define SIR_MAC_ACTION_FAST_BSS_TRNST 6 +#define SIR_MAC_ACTION_HT 7 +#define SIR_MAC_ACTION_SA_QUERY 8 +#define SIR_MAC_ACTION_PROT_DUAL_PUB 9 +#define SIR_MAC_ACTION_WNM 10 +#define SIR_MAC_ACTION_UNPROT_WNM 11 +#define SIR_MAC_ACTION_TDLS 12 +#define SIR_MAC_ACITON_MESH 13 +#define SIR_MAC_ACTION_MHF 14 +#define SIR_MAC_SELF_PROTECTED 15 +#define SIR_MAC_ACTION_WME 17 +#define SIR_MAC_ACTION_VHT 21 + +// QoS management action codes + +#define SIR_MAC_QOS_ADD_TS_REQ 0 +#define SIR_MAC_QOS_ADD_TS_RSP 1 +#define SIR_MAC_QOS_DEL_TS_REQ 2 +#define SIR_MAC_QOS_SCHEDULE 3 +#define SIR_MAC_QOS_MAP_CONFIGURE 4 +// and these are proprietary +#define SIR_MAC_QOS_DEF_BA_REQ 4 +#define SIR_MAC_QOS_DEF_BA_RSP 5 +#define SIR_MAC_QOS_DEL_BA_REQ 6 +#define SIR_MAC_QOS_DEL_BA_RSP 7 + +#ifdef ANI_SUPPORT_11H +// Spectrum management action codes +#define SIR_MAC_ACTION_MEASURE_REQUEST_ID 0 +#define SIR_MAC_ACTION_MEASURE_REPORT_ID 1 +#define SIR_MAC_ACTION_TPC_REQUEST_ID 2 +#define SIR_MAC_ACTION_TPC_REPORT_ID 3 +#endif //ANI_SUPPORT_11H +#define SIR_MAC_ACTION_CHANNEL_SWITCH_ID 4 + + +#ifdef ANI_SUPPORT_11H +// Measurement Request/Report Type +#define SIR_MAC_BASIC_MEASUREMENT_TYPE 0 +#define SIR_MAC_CCA_MEASUREMENT_TYPE 1 +#define SIR_MAC_RPI_MEASUREMENT_TYPE 2 +#endif //ANI_SUPPORT_11H + +//RRM related. +//Refer IEEE Std 802.11k-2008, Section 7.3.2.21, table 7.29 +#if defined WLAN_FEATURE_VOWIFI + +#define SIR_MAC_RRM_CHANNEL_LOAD_TYPE 3 +#define SIR_MAC_RRM_NOISE_HISTOGRAM_BEACON 4 +#define SIR_MAC_RRM_BEACON_TYPE 5 +#define SIR_MAC_RRM_FRAME_TYPE 6 +#define SIR_MAC_RRM_STA_STATISTICS_TYPE 7 +#define SIR_MAC_RRM_LCI_TYPE 8 +#define SIR_MAC_RRM_TSM_TYPE 9 + +//RRM action codes +#define SIR_MAC_RRM_RADIO_MEASURE_REQ 0 +#define SIR_MAC_RRM_RADIO_MEASURE_RPT 1 +#define SIR_MAC_RRM_LINK_MEASUREMENT_REQ 2 +#define SIR_MAC_RRM_LINK_MEASUREMENT_RPT 3 +#define SIR_MAC_RRM_NEIGHBOR_REQ 4 +#define SIR_MAC_RRM_NEIGHBOR_RPT 5 + +#endif + +//VHT Action Field +#ifdef WLAN_FEATURE_11AC +#define SIR_MAC_VHT_GID_NOTIFICATION 1 +#define SIR_MAC_VHT_OPMODE_NOTIFICATION 2 +#endif + +// HT Action Field Codes +#define SIR_MAC_SM_POWER_SAVE 1 + +// DLP action frame types +#define SIR_MAC_DLP_REQ 0 +#define SIR_MAC_DLP_RSP 1 +#define SIR_MAC_DLP_TEARDOWN 2 + +// block acknowledgement action frame types +#define SIR_MAC_BLKACK_ADD_REQ 0 +#define SIR_MAC_BLKACK_ADD_RSP 1 +#define SIR_MAC_BLKACK_DEL 2 +#define SIR_MAC_ACTION_VENDOR_SPECIFIC 9 +#define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F +#define SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP 2 + +// Public Action for 20/40 BSS Coexistence +#define SIR_MAC_ACTION_2040_BSS_COEXISTENCE 0 + +#ifdef WLAN_FEATURE_11W +//11w SA query request/response action frame category code +#define SIR_MAC_SA_QUERY_REQ 0 +#define SIR_MAC_SA_QUERY_RSP 1 +#endif + +#ifdef FEATURE_WLAN_TDLS +#define SIR_MAC_TDLS_SETUP_REQ 0 +#define SIR_MAC_TDLS_SETUP_RSP 1 +#define SIR_MAC_TDLS_SETUP_CNF 2 +#define SIR_MAC_TDLS_TEARDOWN 3 +#define SIR_MAC_TDLS_PEER_TRAFFIC_IND 4 +#define SIR_MAC_TDLS_CH_SWITCH_REQ 5 +#define SIR_MAC_TDLS_CH_SWITCH_RSP 6 +#define SIR_MAC_TDLS_PEER_TRAFFIC_RSP 9 +#define SIR_MAC_TDLS_DIS_REQ 10 +#define SIR_MAC_TDLS_DIS_RSP 14 +#endif + +/* WNM Action field values; IEEE Std 802.11-2012, 8.5.14.1, Table 8-250 */ +#define SIR_MAC_WNM_BSS_TM_QUERY 6 +#define SIR_MAC_WNM_BSS_TM_REQUEST 7 +#define SIR_MAC_WNM_BSS_TM_RESPONSE 8 +#define SIR_MAC_WNM_NOTIF_REQUEST 26 +#define SIR_MAC_WNM_NOTIF_RESPONSE 27 + +#define SIR_MAC_MAX_RANDOM_LENGTH 2306 + +//----------------------------------------------------------------------------- +// EID (Element ID) definitions +// and their min/max lengths +//----------------------------------------------------------------------------- + +#define SIR_MAC_SSID_EID 0 +#define SIR_MAC_SSID_EID_MIN 0 +#define SIR_MAC_SSID_EID_MAX 32 +#define SIR_MAC_RATESET_EID 1 +#define SIR_MAC_RATESET_EID_MIN 1 +#define SIR_MAC_RATESET_EID_MAX 12 +#define SIR_MAC_FH_PARAM_SET_EID 2 +#define SIR_MAC_FH_PARAM_SET_EID_MIN 5 +#define SIR_MAC_FH_PARAM_SET_EID_MAX 5 +#define SIR_MAC_DS_PARAM_SET_EID 3 +#define SIR_MAC_DS_PARAM_SET_EID_MIN 1 +#define SIR_MAC_DS_PARAM_SET_EID_MAX 1 +#define SIR_MAC_CF_PARAM_SET_EID 4 +#define SIR_MAC_CF_PARAM_SET_EID_MIN 6 +#define SIR_MAC_CF_PARAM_SET_EID_MAX 6 +#define SIR_MAC_TIM_EID 5 +#define SIR_MAC_TIM_EID_MIN 3 +#define SIR_MAC_TIM_EID_MAX 254 +#define SIR_MAC_IBSS_PARAM_SET_EID 6 +#define SIR_MAC_IBSS_PARAM_SET_EID_MIN 2 +#define SIR_MAC_IBSS_PARAM_SET_EID_MAX 2 +#define SIR_MAC_COUNTRY_EID 7 +#define SIR_MAC_COUNTRY_EID_MIN 6 +#define SIR_MAC_COUNTRY_EID_MAX 254 +#define SIR_MAC_FH_PARAMS_EID 8 +#define SIR_MAC_FH_PARAMS_EID_MIN 4 +#define SIR_MAC_FH_PARAMS_EID_MAX 4 +#define SIR_MAC_FH_PATTERN_EID 9 +#define SIR_MAC_FH_PATTERN_EID_MIN 4 +#define SIR_MAC_FH_PATTERN_EID_MAX 254 +#define SIR_MAC_REQUEST_EID 10 +#define SIR_MAC_REQUEST_EID_MIN 1 +#define SIR_MAC_REQUEST_EID_MAX 255 +#define SIR_MAC_QBSS_LOAD_EID 11 +#define SIR_MAC_QBSS_LOAD_EID_MIN 5 +#define SIR_MAC_QBSS_LOAD_EID_MAX 5 +#define SIR_MAC_EDCA_PARAM_SET_EID 12 // EDCA parameter set +#define SIR_MAC_EDCA_PARAM_SET_EID_MIN 18 +#define SIR_MAC_EDCA_PARAM_SET_EID_MAX 20 // TBD temp - change backto 18 +#define SIR_MAC_TSPEC_EID 13 +#define SIR_MAC_TSPEC_EID_MIN 55 +#define SIR_MAC_TSPEC_EID_MAX 55 +#define SIR_MAC_TCLAS_EID 14 +#define SIR_MAC_TCLAS_EID_MIN 4 +#define SIR_MAC_TCLAS_EID_MAX 255 +#define SIR_MAC_QOS_SCHEDULE_EID 15 +#define SIR_MAC_QOS_SCHEDULE_EID_MIN 14 +#define SIR_MAC_QOS_SCHEDULE_EID_MAX 14 +#define SIR_MAC_CHALLENGE_TEXT_EID 16 +#define SIR_MAC_CHALLENGE_TEXT_EID_MIN 1 +#define SIR_MAC_CHALLENGE_TEXT_EID_MAX 253 +// reserved 17-31 +#define SIR_MAC_PWR_CONSTRAINT_EID 32 +#define SIR_MAC_PWR_CONSTRAINT_EID_MIN 1 +#define SIR_MAC_PWR_CONSTRAINT_EID_MAX 1 +#define SIR_MAC_PWR_CAPABILITY_EID 33 +#define SIR_MAC_PWR_CAPABILITY_EID_MIN 2 +#define SIR_MAC_PWR_CAPABILITY_EID_MAX 2 +#define SIR_MAC_TPC_REQ_EID 34 +#define SIR_MAC_TPC_REQ_EID_MIN 0 +#define SIR_MAC_TPC_REQ_EID_MAX 255 +// SIR_MAC_EXTENDED_CAP_EID 35 +#define SIR_MAC_TPC_RPT_EID 35 +#define SIR_MAC_TPC_RPT_EID_MIN 2 +#define SIR_MAC_TPC_RPT_EID_MAX 2 +#define SIR_MAC_SPRTD_CHNLS_EID 36 +#define SIR_MAC_SPRTD_CHNLS_EID_MIN 2 +#define SIR_MAC_SPRTD_CHNLS_EID_MAX 254 +#define SIR_MAC_CHNL_SWITCH_ANN_EID 37 +#define SIR_MAC_CHNL_SWITCH_ANN_EID_MIN 3 +#define SIR_MAC_CHNL_SWITCH_ANN_EID_MAX 3 +#define SIR_MAC_MEAS_REQ_EID 38 +#define SIR_MAC_MEAS_REQ_EID_MIN 3 +#define SIR_MAC_MEAS_REQ_EID_MAX 255 +#define SIR_MAC_MEAS_RPT_EID 39 +#define SIR_MAC_MEAS_RPT_EID_MIN 3 +#define SIR_MAC_MEAS_RPT_EID_MAX 255 +#define SIR_MAC_QUIET_EID 40 +#define SIR_MAC_QUIET_EID_MIN 6 +#define SIR_MAC_QUIET_EID_MAX 6 +#define SIR_MAC_IBSS_DFS_EID 41 +#define SIR_MAC_IBSS_DFS_EID_MIN 7 +#define SIR_MAC_IBSS_DFS_EID_MAX 255 +#define SIR_MAC_ERP_INFO_EID 42 +#define SIR_MAC_ERP_INFO_EID_MIN 0 +#define SIR_MAC_ERP_INFO_EID_MAX 255 +#define SIR_MAC_TS_DELAY_EID 43 +#define SIR_MAC_TS_DELAY_EID_MIN 4 +#define SIR_MAC_TS_DELAY_EID_MAX 4 +#define SIR_MAC_TCLAS_PROC_EID 44 +#define SIR_MAC_TCLAS_PROC_EID_MIN 1 +#define SIR_MAC_TCLAS_PROC_EID_MAX 1 +#define SIR_MAC_QOS_CAPABILITY_EID 46 +#define SIR_MAC_QOS_CAPABILITY_EID_MIN 1 +#define SIR_MAC_QOS_CAPABILITY_EID_MAX 1 +#define SIR_MAC_RSN_EID 48 +#define SIR_MAC_RSN_EID_MIN 4 +#define SIR_MAC_RSN_EID_MAX 254 + +//using reserved EID for Qos Action IE for now, +//need to check 11e spec for the actual EID +#define SIR_MAC_QOS_ACTION_EID 49 +#define SIR_MAC_QOS_ACTION_EID_MIN 4 +#define SIR_MAC_QOS_ACTION_EID_MAX 255 +#define SIR_MAC_EXTENDED_RATE_EID 50 +#define SIR_MAC_EXTENDED_RATE_EID_MIN 0 +#define SIR_MAC_EXTENDED_RATE_EID_MAX 255 +// reserved 51-69 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID 70 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MIN 5 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX 5 +// reserved 71-220 +#define SIR_MAC_WPA_EID 221 +#define SIR_MAC_WPA_EID_MIN 0 +#define SIR_MAC_WPA_EID_MAX 255 + +#define SIR_MAC_EID_VENDOR 221 + +// reserved 222-254 +#define SIR_MAC_HT_CAPABILITIES_EID 45 +#define SIR_MAC_HT_CAPABILITIES_EID_MIN 0 +#define SIR_MAC_HT_CAPABILITIES_EID_MAX 255 +#define SIR_MAC_HT_INFO_EID 61 +#define SIR_MAC_HT_INFO_EID_MIN 0 +#define SIR_MAC_HT_INFO_EID_MAX 255 + +#ifdef WLAN_FEATURE_11AC +#define SIR_MAC_VHT_CAPABILITIES_EID 191 +#define SIR_MAC_VHT_OPERATION_EID 192 +#define SIR_MAC_VHT_EXT_BSS_LOAD_EID 193 +#define SIR_MAC_VHT_OPMODE_EID 199 +#endif +#define SIR_MAC_MAX_SUPPORTED_MCS_SET 16 + +/// Workaround IE to change beacon length when it is 4*n+1 +#define SIR_MAC_ANI_WORKAROUND_EID 255 +#define SIR_MAC_ANI_WORKAROUND_EID_MIN 0 +#define SIR_MAC_ANI_WORKAROUND_EID_MAX 255 + +#define SIR_MAC_MAX_ADD_IE_LENGTH 500 +/// Maximum length of each IE +#define SIR_MAC_MAX_IE_LENGTH 255 + +/// Maximum length of each IE +#define SIR_MAC_RSN_IE_MAX_LENGTH 255 +#define SIR_MAC_WPA_IE_MAX_LENGTH 255 +/// Minimum length of each IE +#define SIR_MAC_RSN_IE_MIN_LENGTH 2 +#define SIR_MAC_WPA_IE_MIN_LENGTH 6 + +#ifdef FEATURE_WLAN_ESE +#define ESE_VERSION_4 4 +#define ESE_VERSION_SUPPORTED ESE_VERSION_4 + +// When station sends Radio Management Cap. +// State should be normal=1 +// Mbssid Mask should be 0 +#define RM_STATE_NORMAL 1 +#endif + +#define SIR_MAC_OUI_VERSION_1 1 + +// OUI and type definition for WPA IE in network byte order +#define SIR_MAC_WPA_OUI 0x01F25000 +#define SIR_MAC_WME_OUI 0x02F25000 +#define SIR_MAC_WSM_OUI SIR_MAC_WME_OUI +#define SIR_MAC_WSC_OUI "\x00\x50\xf2\x04" +#define SIR_MAC_WSC_OUI_SIZE 4 +#define SIR_MAC_P2P_OUI "\x50\x6f\x9a\x09" +#define SIR_MAC_P2P_OUI_SIZE 4 +#define SIR_P2P_NOA_ATTR 12 +#define SIR_MAX_NOA_ATTR_LEN 31 +#define SIR_MAX_NOA_DESCR 2 +#define SIR_P2P_IE_HEADER_LEN 6 + +#define SIR_MAC_CISCO_OUI "\x00\x40\x96" +#define SIR_MAC_CISCO_OUI_SIZE 3 + +// min size of wme oui header: oui(3) + type + subtype + version +#define SIR_MAC_OUI_WME_HDR_MIN 6 + +// OUI subtype and their lengths +#define SIR_MAC_OUI_SUBTYPE_WME_INFO 0 +#define SIR_MAC_OUI_WME_INFO_MIN 7 +#define SIR_MAC_OUI_WME_INFO_MAX 7 + +#define SIR_MAC_OUI_SUBTYPE_WME_PARAM 1 +#define SIR_MAC_OUI_WME_PARAM_MIN 24 +#define SIR_MAC_OUI_WME_PARAM_MAX 24 + +#define SIR_MAC_OUI_SUBTYPE_WME_TSPEC 2 +#define SIR_MAC_OUI_WME_TSPEC_MIN 61 +#define SIR_MAC_OUI_WME_TSPEC_MAX 61 + +#define SIR_MAC_OUI_SUBTYPE_WSM_TSPEC 2 // same as WME TSPEC +#define SIR_MAC_OUI_WSM_TSPEC_MIN 61 +#define SIR_MAC_OUI_WSM_TSPEC_MAX 61 + +// reserved subtypes 3-4 +// WSM capability +#define SIR_MAC_OUI_SUBTYPE_WSM_CAPABLE 5 +#define SIR_MAC_OUI_WSM_CAPABLE_MIN 7 +#define SIR_MAC_OUI_WSM_CAPABLE_MAX 7 +// WSM classifier +#define SIR_MAC_OUI_SUBTYPE_WSM_TCLAS 6 +#define SIR_MAC_OUI_WSM_TCLAS_MIN 10 +#define SIR_MAC_OUI_WSM_TCLAS_MAX 255 +// classifier processing element +#define SIR_MAC_OUI_SUBTYPE_WSM_TCLASPROC 7 +#define SIR_MAC_OUI_WSM_TCLASPROC_MIN 7 +#define SIR_MAC_OUI_WSM_TCLASPROC_MAX 7 +// tspec delay element +#define SIR_MAC_OUI_SUBTYPE_WSM_TSDELAY 8 +#define SIR_MAC_OUI_WSM_TSDELAY_MIN 10 +#define SIR_MAC_OUI_WSM_TSDELAY_MAX 10 +// schedule element +#define SIR_MAC_OUI_SUBTYPE_WSM_SCHEDULE 9 +#define SIR_MAC_OUI_WSM_SCHEDULE_MIN 20 +#define SIR_MAC_OUI_WSM_SCHEDULE_MAX 20 + +#ifdef WLAN_NS_OFFLOAD +#define SIR_MAC_NS_OFFLOAD_SIZE 1 //support only one IPv6 offload +#define SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA 2 //Number of target IP in NA frames. It must be at least 2 +#define SIR_MAC_IPV6_ADDR_LEN 16 +#define SIR_IPV6_ADDR_VALID 1 +#endif //WLAN_NS_OFFLOAD +#define SIR_MAC_ARP_OFFLOAD_SIZE 1 + +// total length of an Info element including T/L fields +#define EID_LEN(eid) (2 + (eid)) + +// support for radar Detect, Channel Switch +#define CHANNEL_SWITCH_MAX_FRAME_SIZE 256 + + +// Length of Channel Switch related message +#define SIR_SME_CHANNEL_SWITCH_SIZE (sizeof(tANI_U8) + 2 *sizeof(tANI_U16) + sizeof(tANI_U32) + sizeof(ePhyChanBondState)) +#define SIR_CHANNEL_SWITCH_IE_SIZE EID_LEN(SIR_MAC_CHNL_SWITCH_ANN_EID_MIN) + +//Measurement Request/Report messages +#define SIR_MEAS_REQ_FIELD_SIZE 11 +#define SIR_MEAS_REQ_IE_SIZE (5 + SIR_MEAS_REQ_FIELD_SIZE) +#define SIR_MEAS_REQ_ACTION_FRAME_SIZE (3 + SIR_MEAS_REQ_IE_SIZE) +#define SIR_MEAS_MAX_FRAME_SIZE 256 +#define SIR_MEAS_REPORT_MIN_FRAME_SIZE (3 + EID_LEN(SIR_MAC_MEAS_RPT_EID_MIN)) + +#define SIR_MAC_SET_MEAS_REQ_ENABLE(x) (((tANI_U8) x) | 2) +#define SIR_MAC_SET_MEAS_REQ_REQUEST(x) (((tANI_U8) x) | 4) +#define SIR_MAC_SET_MEAS_REQ_REPORT(x) (((tANI_U8) x) | 8) + +#define SIR_MAC_SET_MEAS_REPORT_LATE(x) (((tANI_U8) x) | 1) +#define SIR_MAC_SET_MEAS_REPORT_INCAPABLE(x) (((tANI_U8) x) | 2) +#define SIR_MAC_SET_MEAS_REPORT_REFUSE(x) (((tANI_U8) x) | 4) + +// Length of TPC Request Action Frame +#define SIR_TPC_REQ_ACTION_FRAME_SIZE (3 + EID_LEN(SIR_MAC_TPC_REQ_EID_MIN)) +#define SIR_TPC_REPORT_ACTION_FRAME_SIZE (3 + EID_LEN(SIR_MAC_TPC_RPT_EID_MIN)) +#define SIR_TPC_MAX_FRAME_SIZE 256 +//----------------------------------------------------------------------------- + +// OFFSET definitions for fixed fields in Management frames + +// Beacon/Probe Response offsets +#define SIR_MAC_TS_OFFSET 0 +#define SIR_MAC_BEACON_INT_OFFSET 8 // Beacon Interval offset +#define SIR_MAC_B_PR_CAPAB_OFFSET 10 +#define SIR_MAC_B_PR_SSID_OFFSET 12 + +// Association/Reassociation offsets +#define SIR_MAC_ASSOC_CAPAB_OFFSET 0 +#define SIR_MAC_LISTEN_INT_OFFSET 2 // Listen Interval offset +#define SIR_MAC_ASSOC_SSID_OFFSET 4 +#define SIR_MAC_CURRENT_AP_OFFSET 4 +#define SIR_MAC_REASSOC_SSID_OFFSET 10 +#define SIR_MAC_ASSOC_STATUS_CODE_OFFSET 2 +#define SIR_MAC_ASSOC_AID_OFFSET 4 +#define SIR_MAC_ASSOC_RSP_RATE_OFFSET 6 + +// Disassociation/Deauthentication offsets +#define SIR_MAC_REASON_CODE_OFFSET 0 + +// Probe Request offset +#define SIR_MAC_PROBE_REQ_SSID_OFFSET 0 + +// Authentication offsets +#define SIR_MAC_AUTH_ALGO_OFFSET 0 +#define SIR_MAC_AUTH_XACT_SEQNUM_OFFSET 2 +#define SIR_MAC_AUTH_STATUS_CODE_OFFSET 4 +#define SIR_MAC_AUTH_CHALLENGE_OFFSET 6 + +/// Transaction sequence number definitions (used in Authentication frames) +#define SIR_MAC_AUTH_FRAME_1 1 +#define SIR_MAC_AUTH_FRAME_2 2 +#define SIR_MAC_AUTH_FRAME_3 3 +#define SIR_MAC_AUTH_FRAME_4 4 + +/// Protocol defined MAX definitions +#define SIR_MAC_ADDR_LENGTH 6 +#define SIR_MAC_MAX_SSID_LENGTH 32 +#define SIR_MAC_MAX_NUMBER_OF_RATES 12 +#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4 +#define SIR_MAC_KEY_LENGTH 13 // WEP Maximum key length size +#define SIR_MAC_AUTH_CHALLENGE_LENGTH 128 +#define SIR_MAC_WEP_IV_LENGTH 4 +#define SIR_MAC_WEP_ICV_LENGTH 4 + +/// MAX key length when ULA is used +#define SIR_MAC_MAX_KEY_LENGTH 32 + +/// Macro definitions for get/set on FC fields +#define SIR_MAC_GET_PROT_VERSION(x) ((((tANI_U16) x) & 0x0300) >> 8) +#define SIR_MAC_GET_FRAME_TYPE(x) ((((tANI_U16) x) & 0x0C00) >> 8) +#define SIR_MAC_GET_FRAME_SUB_TYPE(x) ((((tANI_U16) x) & 0xF000) >> 12) +#define SIR_MAC_GET_WEP_BIT_IN_FC(x) (((tANI_U16) x) & 0x0040) +#define SIR_MAC_SET_PROT_VERSION(x) ((tANI_U16) x) +#define SIR_MAC_SET_FRAME_TYPE(x) (((tANI_U16) x) << 2) +#define SIR_MAC_SET_FRAME_SUB_TYPE(x) (((tANI_U16) x) << 4) +#define SIR_MAC_SET_WEP_BIT_IN_FC(x) (((tANI_U16) x) << 14) + +/// Macro definitions for get/set on capabilityInfo bits +#define SIR_MAC_GET_ESS(x) (((tANI_U16) x) & 0x0001) +#define SIR_MAC_GET_IBSS(x) ((((tANI_U16) x) & 0x0002) >> 1) +#define SIR_MAC_GET_CF_POLLABLE(x) ((((tANI_U16) x) & 0x0004) >> 2) +#define SIR_MAC_GET_CF_POLL_REQ(x) ((((tANI_U16) x) & 0x0008) >> 3) +#define SIR_MAC_GET_PRIVACY(x) ((((tANI_U16) x) & 0x0010) >> 4) +#define SIR_MAC_GET_SHORT_PREAMBLE(x) ((((tANI_U16) x) & 0x0020) >> 5) +#define SIR_MAC_GET_SPECTRUM_MGMT(x) ((((tANI_U16) x) & 0x0100) >> 8) +#define SIR_MAC_GET_QOS(x) ((((tANI_U16) x) & 0x0200) >> 9) +#define SIR_MAC_GET_SHORT_SLOT_TIME(x) ((((tANI_U16) x) & 0x0400) >> 10) +#define SIR_MAC_GET_APSD(x) ((((tANI_U16) x) & 0x0800) >> 11) +#if defined WLAN_FEATURE_VOWIFI +#define SIR_MAC_GET_RRM(x) ((((tANI_U16) x) & 0x1000) >> 12) +#endif +#define SIR_MAC_GET_BLOCK_ACK(x) ((((tANI_U16) x) & 0xc000) >> CAPABILITY_INFO_DELAYED_BA_BIT) +#define SIR_MAC_SET_ESS(x) (((tANI_U16) x) | 0x0001) +#define SIR_MAC_SET_IBSS(x) (((tANI_U16) x) | 0x0002) +#define SIR_MAC_SET_CF_POLLABLE(x) (((tANI_U16) x) | 0x0004) +#define SIR_MAC_SET_CF_POLL_REQ(x) (((tANI_U16) x) | 0x0008) +#define SIR_MAC_SET_PRIVACY(x) (((tANI_U16) x) | 0x0010) +#define SIR_MAC_SET_SHORT_PREAMBLE(x) (((tANI_U16) x) | 0x0020) +#define SIR_MAC_SET_SPECTRUM_MGMT(x) (((tANI_U16) x) | 0x0100) +#define SIR_MAC_SET_QOS(x) (((tANI_U16) x) | 0x0200) +#define SIR_MAC_SET_SHORT_SLOT_TIME(x) (((tANI_U16) x) | 0x0400) +#define SIR_MAC_SET_APSD(x) (((tANI_U16) x) | 0x0800) +#if defined WLAN_FEATURE_VOWIFI +#define SIR_MAC_SET_RRM(x) (((tANI_U16) x) | 0x1000) +#endif +#define SIR_MAC_SET_GROUP_ACK(x) (((tANI_U16) x) | 0x4000) + +#ifdef WLAN_FEATURE_11AC +#define SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(x) ((((tANI_U32) x) & 0x03800000) >> 23) +#endif + +// bitname must be one of the above, eg ESS, CF_POLLABLE, etc. +#define SIR_MAC_CLEAR_CAPABILITY(u16value, bitname) \ + ((u16value) &= (~(SIR_MAC_SET_##bitname(0)))) + +#define IS_WES_MODE_ENABLED(x) \ + ((x)->roam.configParam.isWESModeEnabled) + +#define BA_RECIPIENT 1 +#define BA_INITIATOR 2 +#define BA_BOTH_DIRECTIONS 3 + +/// Status Code (present in Management response frames) enum + +typedef enum eSirMacStatusCodes +{ + eSIR_MAC_SUCCESS_STATUS = 0, //Reserved + eSIR_MAC_UNSPEC_FAILURE_STATUS = 1, //Unspecified reason + // 802.11 reserved 2-9 + /* + WMM status codes(standard 1.1 table 9) + Table 9 ADDTS Response Status Codes + Value Operation + 0 Admission accepted + 1 Invalid parameters + 2 Reserved + 3 Refused + 4-255 Reserved + */ + eSIR_MAC_WME_INVALID_PARAMS_STATUS = 1, // ?? + eSIR_MAC_WME_REFUSED_STATUS = 3, // ?? + eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS = 10, //Cannot support all requested capabilities in the Capability Information field + eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS = 11, //Reassociation denied due to inability to confirm that association exists + eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS = 12, //Association denied due to reason outside the scope of this standard + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS = 13, //Responding station does not support the specified authentication algorithm + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS = 14, //Received an Authentication frame with authentication transaction sequence number + //out of expected sequence + eSIR_MAC_CHALLENGE_FAILURE_STATUS = 15, //Authentication rejected because of challenge failure + eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS = 16, //Authentication rejected due to timeout waiting for next frame in sequence + eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS = 17, //Association denied because AP is unable to handle additional associated stations + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS = 18, //Association denied due to requesting station not supporting all of the data rates in the + //BSSBasicRateSet parameter + eSIR_MAC_SHORT_PREAMBLE_NOT_SUPPORTED_STATUS = 19, //Association denied due to requesting station not supporting the short preamble + //option + eSIR_MAC_PBCC_NOT_SUPPORTED_STATUS = 20, //Association denied due to requesting station not supporting the PBCC modulation + //option + eSIR_MAC_CHANNEL_AGILITY_NOT_SUPPORTED_STATUS = 21, //Association denied due to requesting station not supporting the Channel Agility + //option + eSIR_MAC_SPECTRUM_MGMT_REQD_STATUS = 22, //Association request rejected because Spectrum Management capability is required + eSIR_MAC_PWR_CAPABILITY_BAD_STATUS = 23, //Association request rejected because the information in the Power Capability + //element is unacceptable + eSIR_MAC_SPRTD_CHANNELS_BAD_STATUS = 24, //Association request rejected because the information in the Supported Channels + //element is unacceptable + eSIR_MAC_SHORT_SLOT_NOT_SUPORTED_STATUS = 25, //Association denied due to requesting station not supporting the Short Slot Time + //option + eSIR_MAC_DSSS_OFDM_NOT_SUPPORTED_STATUS = 26, //Association denied due to requesting station not supporting the DSSS-OFDM option + // reserved 27-29 + eSIR_MAC_TRY_AGAIN_LATER = 30, //Association request rejected temporarily, try again later + // reserved 31 + eSIR_MAC_QOS_UNSPECIFIED_FAILURE_STATUS = 32, //Unspecified, QoS-related failure + eSIR_MAC_QAP_NO_BANDWIDTH_STATUS = 33, //Association denied because QoS AP has insufficient bandwidth to handle another + //QoS STA + eSIR_MAC_XS_FRAME_LOSS_STATUS = 34, //Association denied due to excessive frame loss rates and/or poor conditions on cur- + //rent operating channel + eSIR_MAC_STA_QOS_NOT_SUPPORTED_STATUS = 35, //Association (with QoS BSS) denied because the requesting STA does not support the + //QoS facility + eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS = 36, //Reserved + eSIR_MAC_REQ_DECLINED_STATUS = 37, //The request has been declined + eSIR_MAC_INVALID_PARAM_STATUS = 38, //The request has not been successful as one or more parameters have invalid values + eSIR_MAC_TS_NOT_HONOURED_STATUS = 39, //The TS has not been created because the request cannot be honored; however, a suggested + //TSPEC is provided so that the initiating STA may attempt to set another TS + //with the suggested changes to the TSPEC + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS = 40, //Invalid information element, i.e., an information element defined in this standard for + //which the content does not meet the specifications in Clause 7 + eSIR_MAC_INVALID_GROUP_CIPHER_STATUS = 41, //Invalid group cipher + eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS = 42, //Invalid pairwise cipher + eSIR_MAC_INVALID_AKMP_STATUS = 43, //Invalid AKMP + eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS = 44, //Unsupported RSN information element version + eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS = 45, //Invalid RSN information element capabilities + eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS = 46, //Cipher suite rejected because of security policy + eSIR_MAC_TS_NOT_CREATED_STATUS = 47, //The TS has not been created; however, the HC may be capable of creating a TS, in + //response to a request, after the time indicated in the TS Delay element + eSIR_MAC_DL_NOT_ALLOWED_STATUS = 48, //Direct link is not allowed in the BSS by policy + eSIR_MAC_DEST_STA_NOT_KNOWN_STATUS = 49, //The Destination STA is not present within this BSS + eSIR_MAC_DEST_STA_NOT_QSTA_STATUS = 50, //The Destination STA is not a QoS STA + eSIR_MAC_INVALID_LISTEN_INTERVAL_STATUS = 51, //Association denied because the ListenInterval is too large + + eSIR_MAC_DSSS_CCK_RATE_MUST_SUPPORT_STATUS = 52, //FIXME: + eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS = 53, + eSIR_MAC_PSMP_CONTROLLED_ACCESS_ONLY_STATUS = 54, +#ifdef FEATURE_WLAN_ESE + eSIR_MAC_ESE_UNSPECIFIED_QOS_FAILURE_STATUS = 200, //ESE-Unspecified, QoS related failure in (Re)Assoc response frames + eSIR_MAC_ESE_TSPEC_REQ_REFUSED_STATUS = 201, //ESE-TSPEC request refused due to AP's policy configuration in AddTs Rsp, (Re)Assoc Rsp. + eSIR_MAC_ESE_ASSOC_DENIED_INSUFF_BW_STATUS = 202, //ESE-Assoc denied due to insufficient bandwidth to handle new TS in (Re)Assoc Rsp. + eSIR_MAC_ESE_INVALID_PARAMETERS_STATUS = 203, //ESE-Invalid parameters. (Re)Assoc request had one or more TSPEC parameters with + //invalid values. +#endif + +} tSirMacStatusCodes; + +/** + * Reason Code (present in Deauthentication/Disassociation + * Management frames) enum + */ +typedef enum eSirMacReasonCodes +{ + eSIR_MAC_UNSPEC_FAILURE_REASON = 1, //Unspecified reason + eSIR_MAC_PREV_AUTH_NOT_VALID_REASON = 2, //Previous authentication no longer valid + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON = 3, //Deauthenticated because sending station is leaving (or has left) IBSS or ESS + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON = 4, //Disassociated due to inactivity + eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON = 5, //Disassociated because AP is unable to handle all currently associated stations + eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON = 6, //Class 2 frame received from nonauthenticated station + eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON = 7, //Class 3 frame received from nonassociated station + eSIR_MAC_DISASSOC_LEAVING_BSS_REASON = 8, //Disassociated because sending station is leaving (or has left) BSS + eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON = 9, //Station requesting (re)association is not authenticated with responding station + eSIR_MAC_PWR_CAPABILITY_BAD_REASON = 10, //Disassociated because the information in the Power Capability element is unacceptable + eSIR_MAC_SPRTD_CHANNELS_BAD_REASON = 11, //Disassociated because the information in the Supported Channels element is unacceptable + // reserved 12 + eSIR_MAC_INVALID_IE_REASON = 13, //Invalid information element, i.e., an information element defined in this standard for + //which the content does not meet the specifications in Clause 7 + eSIR_MAC_MIC_FAILURE_REASON = 14, //Message integrity code (MIC) failure + eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON = 15, //4-Way Handshake timeout + eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON = 16, //Group Key Handshake timeout + eSIR_MAC_RSN_IE_MISMATCH_REASON = 17, //Information element in 4-Way Handshake different from (Re)Association Request/Probe + //Response/Beacon frame + eSIR_MAC_INVALID_MC_CIPHER_REASON = 18, //Invalid group cipher + eSIR_MAC_INVALID_UC_CIPHER_REASON = 19, //Invalid pairwise cipher + eSIR_MAC_INVALID_AKMP_REASON = 20, //Invalid AKMP + eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON = 21, //Unsupported RSN information element version + eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON = 22, //Invalid RSN information element capabilities + eSIR_MAC_1X_AUTH_FAILURE_REASON = 23, //IEEE 802.1X authentication failed + eSIR_MAC_CIPHER_SUITE_REJECTED_REASON = 24, //Cipher suite rejected because of the security policy +#ifdef FEATURE_WLAN_TDLS + eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE = 25, //TDLS direct link teardown due to TDLS peer STA unreachable via the TDLS direct link + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON = 26, //TDLS direct link teardown for unspecified reason +#endif + // reserved 27 - 30 +#ifdef WLAN_FEATURE_11W + eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION = 31, //Robust management frames policy violation +#endif + eSIR_MAC_QOS_UNSPECIFIED_REASON = 32, //Disassociated for unspecified, QoS-related reason + eSIR_MAC_QAP_NO_BANDWIDTH_REASON = 33, //Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA + eSIR_MAC_XS_UNACKED_FRAMES_REASON = 34, //Disassociated because excessive number of frames need to be acknowledged, but are not + //acknowledged due to AP transmissions and/or poor channel conditions + eSIR_MAC_BAD_TXOP_USE_REASON = 35, //Disassociated because STA is transmitting outside the limits of its TXOPs + eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON = 36, //Requested from peer STA as the STA is leaving the BSS (or resetting) + eSIR_MAC_PEER_REJECT_MECHANISIM_REASON = 37, //Requested from peer STA as it does not want to use the mechanism + eSIR_MAC_MECHANISM_NOT_SETUP_REASON = 38, //Requested from peer STA as the STA received frames using the mechanism for which a + //setup is required + eSIR_MAC_PEER_TIMEDOUT_REASON = 39, //Requested from peer STA due to timeout + eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON = 45, //Peer STA does not support the requested cipher suite + eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON = 46, //FT reason + //reserved 47 - 65535. + eSIR_BEACON_MISSED = 65534, //We invented this to tell beacon missed case +} tSirMacReasonCodes; + + +// BA Initiator v/s Recipient +typedef enum eBADirection +{ + eBA_RECIPIENT, + eBA_INITIATOR +} tBADirection; + +// A-MPDU/BA Enable/Disable in Tx/Rx direction +typedef enum eBAEnable +{ + eBA_DISABLE, + eBA_ENABLE +} tBAEnable; + +// A-MPDU/BA Policy +typedef enum eBAPolicy +{ + eBA_UNCOMPRESSED, + eBA_COMPRESSED +} tBAPolicy; + +// A-MPDU/BA Policy +typedef enum eBAPolicyType +{ + eBA_POLICY_DELAYED, + eBA_POLICY_IMMEDIATE +} tBAPolicyType; + +/// Frame control field format (2 bytes) +typedef __ani_attr_pre_packed struct sSirMacFrameCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 subType :4; + tANI_U8 type :2; + tANI_U8 protVer :2; + + tANI_U8 order :1; + tANI_U8 wep :1; + tANI_U8 moreData :1; + tANI_U8 powerMgmt :1; + tANI_U8 retry :1; + tANI_U8 moreFrag :1; + tANI_U8 fromDS :1; + tANI_U8 toDS :1; + +#else + + tANI_U8 protVer :2; + tANI_U8 type :2; + tANI_U8 subType :4; + + tANI_U8 toDS :1; + tANI_U8 fromDS :1; + tANI_U8 moreFrag :1; + tANI_U8 retry :1; + tANI_U8 powerMgmt :1; + tANI_U8 moreData :1; + tANI_U8 wep :1; + tANI_U8 order :1; + +#endif + +} __ani_attr_packed tSirMacFrameCtl, *tpSirMacFrameCtl; + +/// Sequence control field +typedef __ani_attr_pre_packed struct sSirMacSeqCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 seqNumLo : 4; + tANI_U8 fragNum : 4; + + tANI_U8 seqNumHi : 8; + +#else + + tANI_U8 fragNum : 4; + tANI_U8 seqNumLo : 4; + tANI_U8 seqNumHi : 8; + +#endif +} __ani_attr_packed tSirMacSeqCtl, *tpSirMacSeqCtl; + +/// QoS control field +typedef __ani_attr_pre_packed struct sSirMacQosCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 rsvd : 1; + tANI_U8 ackPolicy : 2; + tANI_U8 esop_txopUnit : 1; + tANI_U8 tid : 4; + + tANI_U8 txop : 8; + +#else + + tANI_U8 tid : 4; + tANI_U8 esop_txopUnit : 1; + tANI_U8 ackPolicy : 2; + tANI_U8 rsvd : 1; + + tANI_U8 txop : 8; + +#endif +} __ani_attr_packed tSirMacQosCtl, *tpSirMacQosCtl; + +/// Length (in bytes) of MAC header in 3 address format +#define SIR_MAC_HDR_LEN_3A 24 + +/// 3 address MAC data header format (24/26 bytes) +typedef __ani_attr_pre_packed struct sSirMacDot3Hdr +{ + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U16 length; +} __ani_attr_packed tSirMacDot3Hdr, *tpSirMacDot3Hdr; + + +/// 3 address MAC data header format (24/26 bytes) +typedef __ani_attr_pre_packed struct sSirMacDataHdr3a +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 addr1[6]; + tANI_U8 addr2[6]; + tANI_U8 addr3[6]; + tSirMacSeqCtl seqControl; + tSirMacQosCtl qosControl; +} __ani_attr_packed tSirMacDataHdr3a, *tpSirMacDataHdr3a; + +/// Management header format +typedef __ani_attr_pre_packed struct sSirMacMgmtHdr +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U8 bssId[6]; + tSirMacSeqCtl seqControl; +} __ani_attr_packed tSirMacMgmtHdr, *tpSirMacMgmtHdr; + +/// ERP information field +typedef __ani_attr_pre_packed struct sSirMacErpInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved:5; + tANI_U8 barkerPreambleMode:1; + tANI_U8 useProtection:1; + tANI_U8 nonErpPresent:1; +#else + tANI_U8 nonErpPresent:1; + tANI_U8 useProtection:1; + tANI_U8 barkerPreambleMode:1; + tANI_U8 reserved:5; +#endif +} __ani_attr_packed tSirMacErpInfo, *tpSirMacErpInfo; + +/// Capability information field +typedef __ani_attr_pre_packed struct sSirMacCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 immediateBA:1; + tANI_U16 delayedBA:1; + tANI_U16 dsssOfdm:1; + tANI_U16 rrm:1; + tANI_U16 apsd:1; + tANI_U16 shortSlotTime:1; + tANI_U16 qos:1; + tANI_U16 spectrumMgt:1; + tANI_U16 channelAgility:1; + tANI_U16 pbcc:1; + tANI_U16 shortPreamble:1; + tANI_U16 privacy:1; + tANI_U16 cfPollReq:1; + tANI_U16 cfPollable:1; + tANI_U16 ibss:1; + tANI_U16 ess:1; +#else + tANI_U16 ess:1; + tANI_U16 ibss:1; + tANI_U16 cfPollable:1; + tANI_U16 cfPollReq:1; + tANI_U16 privacy:1; + tANI_U16 shortPreamble:1; + tANI_U16 pbcc:1; + tANI_U16 channelAgility:1; + tANI_U16 spectrumMgt:1; + tANI_U16 qos:1; + tANI_U16 shortSlotTime:1; + tANI_U16 apsd:1; + tANI_U16 rrm:1; + tANI_U16 dsssOfdm:1; + tANI_U16 delayedBA:1; + tANI_U16 immediateBA:1; +#endif +} __ani_attr_packed tSirMacCapabilityInfo, *tpSirMacCapabilityInfo; + +typedef __ani_attr_pre_packed struct sSirMacCfParamSet +{ + tANI_U8 cfpCount; + tANI_U8 cfpPeriod; + tANI_U16 cfpMaxDuration; + tANI_U16 cfpDurRemaining; +} __ani_attr_packed tSirMacCfParamSet; + +typedef __ani_attr_pre_packed struct sSirMacTim +{ + tANI_U8 dtimCount; + tANI_U8 dtimPeriod; + tANI_U8 bitmapControl; + tANI_U8 bitmapLength; + tANI_U8 bitmap[251]; +} __ani_attr_packed tSirMacTim; + +//12 Bytes long because this structure can be used to represent rate +//and extended rate set IEs +//The parser assume this to be at least 12 +typedef __ani_attr_pre_packed struct sSirMacRateSet +{ + tANI_U8 numRates; + tANI_U8 rate[SIR_MAC_RATESET_EID_MAX]; +} __ani_attr_packed tSirMacRateSet; + + +typedef __ani_attr_pre_packed struct sSirMacSSid +{ + tANI_U8 length; + tANI_U8 ssId[32]; +} __ani_attr_packed tSirMacSSid; + +typedef __ani_attr_pre_packed struct sSirMacWpaInfo +{ + tANI_U8 length; + tANI_U8 info[SIR_MAC_MAX_IE_LENGTH]; +} __ani_attr_packed tSirMacWpaInfo, *tpSirMacWpaInfo, tSirMacRsnInfo, *tpSirMacRsnInfo; + +typedef __ani_attr_pre_packed struct sSirMacFHParamSet +{ + tANI_U16 dwellTime; + tANI_U8 hopSet; + tANI_U8 hopPattern; + tANI_U8 hopIndex; +} tSirMacFHParamSet, *tpSirMacFHParamSet; + +typedef __ani_attr_pre_packed struct sSirMacIBSSParams +{ + tANI_U16 atim; +} tSirMacIBSSParams, *tpSirMacIBSSParams; + +typedef __ani_attr_pre_packed struct sSirMacRRMEnabledCap +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved: 6; + tANI_U8 AntennaInformation: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 MeasurementPilot: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 operatingChanMax: 3; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 APChanReport: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 statistics: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 repeated: 1; + tANI_U8 parallel: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 LinkMeasurement: 1; + tANI_U8 present; +#else + tANI_U8 present; + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 operatingChanMax: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 MeasurementPilot: 3; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + tANI_U8 reserved: 6; +#endif +} tSirMacRRMEnabledCap, *tpSirMacRRMEnabledCap; + + +/* ---------------- + * EDCA Profiles + * --------------- + */ + +#define EDCA_AC_BE 0 +#define EDCA_AC_BK 1 +#define EDCA_AC_VI 2 +#define EDCA_AC_VO 3 +#define AC_MGMT_LO 4 +#define AC_MGMT_HI 5 +#define MAX_NUM_AC 4 + +// access categories +#define SIR_MAC_EDCAACI_BESTEFFORT (EDCA_AC_BE) +#define SIR_MAC_EDCAACI_BACKGROUND (EDCA_AC_BK) +#define SIR_MAC_EDCAACI_VIDEO (EDCA_AC_VI) +#define SIR_MAC_EDCAACI_VOICE (EDCA_AC_VO) + +// access category record +typedef __ani_attr_pre_packed struct sSirMacAciAifsn +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 1; + tANI_U8 aci : 2; + tANI_U8 acm : 1; + tANI_U8 aifsn : 4; +#else + tANI_U8 aifsn : 4; + tANI_U8 acm : 1; + tANI_U8 aci : 2; + tANI_U8 rsvd : 1; +#endif +} __ani_attr_packed tSirMacAciAifsn; + +// contention window size +typedef __ani_attr_pre_packed struct sSirMacCW +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 max : 4; + tANI_U8 min : 4; +#else + tANI_U8 min : 4; + tANI_U8 max : 4; +#endif +} __ani_attr_packed tSirMacCW; + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamRecord +{ + tSirMacAciAifsn aci; + tSirMacCW cw; + tANI_U16 txoplimit; +} __ani_attr_packed tSirMacEdcaParamRecord; + +typedef __ani_attr_pre_packed struct sSirMacQosInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 uapsd : 1; + tANI_U8 txopreq : 1; + tANI_U8 qreq : 1; + tANI_U8 qack : 1; + tANI_U8 count : 4; +#else + tANI_U8 count : 4; + tANI_U8 qack : 1; + tANI_U8 qreq : 1; + tANI_U8 txopreq : 1; + tANI_U8 uapsd : 1; +#endif +} __ani_attr_packed tSirMacQosInfo; + + +typedef __ani_attr_pre_packed struct sSirMacQosInfoStation +{ +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 acvo_uapsd:1; + tANI_U8 acvi_uapsd:1; + tANI_U8 acbk_uapsd:1; + tANI_U8 acbe_uapsd:1; + tANI_U8 qack:1; + tANI_U8 maxSpLen:2; + tANI_U8 moreDataAck:1; +#else + tANI_U8 moreDataAck:1; + tANI_U8 maxSpLen:2; + tANI_U8 qack:1; + tANI_U8 acbe_uapsd:1; + tANI_U8 acbk_uapsd:1; + tANI_U8 acvi_uapsd:1; + tANI_U8 acvo_uapsd:1; +#endif +} __ani_attr_packed tSirMacQosInfoStation, *tpSirMacQosInfoStation; + + + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfo qosInfo; + tANI_U8 rsvd; + tSirMacEdcaParamRecord acbe; // best effort + tSirMacEdcaParamRecord acbk; // background + tSirMacEdcaParamRecord acvi; // video + tSirMacEdcaParamRecord acvo; // voice +} __ani_attr_packed tSirMacEdcaParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacQoSParams +{ + tANI_U8 count; + tANI_U16 limit; + tANI_U8 CWmin[8]; + tANI_U8 AIFS[8]; +} __ani_attr_packed tSirMacQoSParams; + +// ts info direction field can take any of these values +#define SIR_MAC_DIRECTION_UPLINK 0 +#define SIR_MAC_DIRECTION_DNLINK 1 +#define SIR_MAC_DIRECTION_DIRECT 2 +#define SIR_MAC_DIRECTION_BIDIR 3 + +// access policy +// reserved 0 +#define SIR_MAC_ACCESSPOLICY_EDCA 1 +#define SIR_MAC_ACCESSPOLICY_HCCA 2 +#define SIR_MAC_ACCESSPOLICY_BOTH 3 + +typedef __ani_attr_pre_packed struct sSirMacTSInfoTfc +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 burstSizeDefn : 1; + tANI_U8 reserved :7; +#else + tANI_U8 reserved :7; + tANI_U8 burstSizeDefn : 1; +#endif + +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 ackPolicy : 2; + tANI_U16 userPrio : 3; + tANI_U16 psb : 1; + tANI_U16 aggregation : 1; + tANI_U16 accessPolicy : 2; + tANI_U16 direction : 2; + tANI_U16 tsid : 4; + tANI_U16 trafficType : 1; +#else + tANI_U16 trafficType : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 accessPolicy : 2; + tANI_U16 aggregation : 1; + tANI_U16 psb : 1; + tANI_U16 userPrio : 3; + tANI_U16 ackPolicy : 2; +#endif +} __ani_attr_packed tSirMacTSInfoTfc; + +typedef __ani_attr_pre_packed struct sSirMacTSInfoSch +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 7; + tANI_U8 schedule : 1; +#else + tANI_U8 schedule : 1; + tANI_U8 rsvd : 7; +#endif +} __ani_attr_packed tSirMacTSInfoSch; + +typedef __ani_attr_pre_packed struct sSirMacTSInfo +{ + tSirMacTSInfoTfc traffic; + tSirMacTSInfoSch schedule; +} __ani_attr_packed tSirMacTSInfo; + +typedef __ani_attr_pre_packed struct sSirMacTspecIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacTSInfo tsinfo; + tANI_U16 nomMsduSz; + tANI_U16 maxMsduSz; + tANI_U32 minSvcInterval; + tANI_U32 maxSvcInterval; + tANI_U32 inactInterval; + tANI_U32 suspendInterval; + tANI_U32 svcStartTime; + tANI_U32 minDataRate; + tANI_U32 meanDataRate; + tANI_U32 peakDataRate; + tANI_U32 maxBurstSz; + tANI_U32 delayBound; + tANI_U32 minPhyRate; + tANI_U16 surplusBw; + tANI_U16 mediumTime; +} +__ani_attr_packed tSirMacTspecIE; + +// frame classifier types +#define SIR_MAC_TCLASTYPE_ETHERNET 0 +#define SIR_MAC_TCLASTYPE_TCPUDPIP 1 +#define SIR_MAC_TCLASTYPE_8021DQ 2 +// reserved 3-255 + +typedef __ani_attr_pre_packed struct sSirMacTclasParamEthernet +{ + tANI_U8 srcAddr[6]; + tANI_U8 dstAddr[6]; + tANI_U16 type; +}__ani_attr_packed tSirMacTclasParamEthernet; + +typedef __ani_attr_pre_packed struct sSirMacTclasParamIPv4 +{ + tANI_U8 version; + tANI_U8 srcIpAddr[4]; + tANI_U8 dstIpAddr[4]; + tANI_U16 srcPort; + tANI_U16 dstPort; + tANI_U8 dscp; + tANI_U8 protocol; + tANI_U8 rsvd; +} __ani_attr_packed tSirMacTclasParamIPv4; + +#define SIR_MAC_TCLAS_IPV4 4 +#define SIR_MAC_TCLAS_IPV6 6 + +typedef __ani_attr_pre_packed struct sSirMacTclasParamIPv6 +{ + tANI_U8 version; + tANI_U8 srcIpAddr[16]; + tANI_U8 dstIpAddr[16]; + tANI_U16 srcPort; + tANI_U16 dstPort; + tANI_U8 flowLabel[3]; +} __ani_attr_packed tSirMacTclasParamIPv6; + +typedef __ani_attr_pre_packed struct sSirMacTclasParam8021dq +{ + tANI_U16 tag; +} __ani_attr_packed tSirMacTclasParam8021dq; + +typedef __ani_attr_pre_packed struct sSirMacTclasIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 userPrio; + tANI_U8 classifierType; + tANI_U8 classifierMask; +} __ani_attr_packed tSirMacTclasIE; + +typedef __ani_attr_pre_packed struct sSirMacTsDelayIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U32 delay; +} __ani_attr_packed tSirMacTsDelayIE; + +typedef __ani_attr_pre_packed struct sSirMacScheduleInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 rsvd : 9; + tANI_U16 direction : 2; + tANI_U16 tsid : 4; + tANI_U16 aggregation : 1; +#else + tANI_U16 aggregation : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 rsvd : 9; +#endif +} __ani_attr_packed tSirMacScheduleInfo; + +typedef __ani_attr_pre_packed struct sSirMacScheduleIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacScheduleInfo info; + tANI_U32 svcStartTime; + tANI_U32 svcInterval; + tANI_U16 maxSvcDuration; + tANI_U16 specInterval; +} __ani_attr_packed tSirMacScheduleIE; + +typedef __ani_attr_pre_packed struct sSirMacQosCapabilityIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfo qosInfo; +} __ani_attr_packed tSirMacQosCapabilityIE; + +typedef __ani_attr_pre_packed struct sSirMacQosCapabilityStaIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfoStation qosInfo; +} __ani_attr_packed tSirMacQosCapabilityStaIE; + + +typedef tANI_U32 tSirMacTimeStamp[2]; + +typedef tANI_U16 tSirMacBeaconInterval; + +typedef tANI_U16 tSirMacListenInterval; + +typedef tANI_U8 tSirMacChanNum; + +typedef tANI_U8 tSirMacAddr[6]; + + +// IE definitions +typedef __ani_attr_pre_packed struct sSirMacSSidIE +{ + tANI_U8 type; + tSirMacSSid ssId; +} __ani_attr_packed tSirMacSSidIE; + +typedef __ani_attr_pre_packed struct sSirMacRateSetIE +{ + tANI_U8 type; + tSirMacRateSet supportedRateSet; +} __ani_attr_packed tSirMacRateSetIE; + +typedef __ani_attr_pre_packed struct sSirMacDsParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacChanNum channelNumber; +} __ani_attr_packed tSirMacDsParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacCfParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacCfParamSet cfParams; +} __ani_attr_packed tSirMacCfParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacChanInfo +{ + tSirMacChanNum firstChanNum; + tANI_U8 numChannels; + tANI_S8 maxTxPower; +} __ani_attr_packed tSirMacChanInfo; + +typedef __ani_attr_pre_packed struct sSirMacNonErpPresentIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 erp; +} __ani_attr_packed tSirMacNonErpPresentIE; + +typedef struct sSirMacPowerCapabilityIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tSirMacPowerCapabilityIE; + +typedef struct sSirMacSupportedChannelIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 supportedChannels[96]; +} tSirMacSupportedChannelIE; + +typedef struct sSirMacMeasReqField +{ + tANI_U8 channelNumber; + tANI_U8 measStartTime[8]; + tANI_U16 measDuration; +} tSirMacMeasReqField, *tpSirMacMeasReqField; + +typedef struct sSirMacMeasReqIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 measToken; + tANI_U8 measReqMode; + tANI_U8 measType; + tSirMacMeasReqField measReqField; +} tSirMacMeasReqIE, *tpSirMacMeasReqIE; + +#define SIR_MAC_MAX_SUPP_RATES 32 + +#define SIR_MAC_MAX_SUPP_CHANNELS 100 +#define SIR_MAC_MAX_SUPP_OPER_CLASSES 32 +#define SIR_MAC_MAX_EXTN_CAP 8 + +// VHT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacVHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U32 reserved1: 2; + tANI_U32 txAntPattern: 1; + tANI_U32 rxAntPattern: 1; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 htcVHTCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 muBeamformerCap: 1; + tANI_U32 numSoundingDim: 3; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 txSTBC: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 maxMPDULen: 2; +#else + tANI_U32 maxMPDULen: 2; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 txSTBC: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 numSoundingDim: 3; + tANI_U32 muBeamformerCap: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 htcVHTCap: 1; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 rxAntPattern: 1; + tANI_U32 txAntPattern: 1; + tANI_U32 reserved1: 2; +#endif +} __ani_attr_packed tSirMacVHTCapabilityInfo; + +typedef __ani_attr_pre_packed struct sSirMacVHTTxSupDataRateInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved: 3; + tANI_U16 txSupDataRate: 13; +#else + tANI_U16 txSupDataRate: 13; + tANI_U16 reserved: 3; +#endif +}__ani_attr_packed tSirMacVHTTxSupDataRateInfo; + +typedef __ani_attr_pre_packed struct sSirMacVHTRxSupDataRateInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved: 3; + tANI_U16 rxSupDataRate: 13; +#else + tANI_U16 rxSupDataRate: 13; + tANI_U16 reserved: 3; +#endif +}__ani_attr_packed tSirMacVHTRxSupDataRateInfo; + +/** + * struct sSirVhtMcsInfo - VHT MCS information + * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams + * @rx_highest: Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams + * @tx_highest: Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ +typedef struct sSirVhtMcsInfo { + tANI_U16 rxMcsMap; + tANI_U16 rxHighest; + tANI_U16 txMcsMap; + tANI_U16 txHighest; +}tSirVhtMcsInfo; + +/** + * struct sSirVHtCap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +typedef struct sSirVHtCap { + tANI_U32 vhtCapInfo; + tSirVhtMcsInfo suppMcs; +}tSirVHTCap; + +/** + * struct sSirHtCap - HT capabilities + * + * This structure refers to "HT capabilities element" as + * described in 802.11n draft section 7.3.2.52 + */ + + +typedef struct sSirHtCap { + tANI_U16 capInfo; + tANI_U8 ampduParamsInfo; + tANI_U8 suppMcsSet[16]; + tANI_U16 extendedHtCapInfo; + tANI_U32 txBFCapInfo; + tANI_U8 antennaSelectionInfo; +}tSirHTCap; + +// HT Cap and HT IE Size defines +#define HT_CAPABILITY_IE_SIZE 28 +#define HT_INFO_IE_SIZE 24 + +// +// Determines the current operating mode of the 802.11n STA +// +typedef enum eSirMacHTOperatingMode +{ + eSIR_HT_OP_MODE_PURE, // No Protection + eSIR_HT_OP_MODE_OVERLAP_LEGACY, // Overlap Legacy device present, protection is optional + eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT, // No legacy device, but 20 MHz HT present + eSIR_HT_OP_MODE_MIXED // Protetion is required +} tSirMacHTOperatingMode; + + +// Spatial Multiplexing(SM) Power Save mode +typedef enum eSirMacHTMIMOPowerSaveState +{ + eSIR_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + eSIR_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + eSIR_HT_MIMO_PS_NA = 2, // reserved + eSIR_HT_MIMO_PS_NO_LIMIT = 3 // SM Power Save disabled +} tSirMacHTMIMOPowerSaveState; + + +typedef enum eSirMacHTChannelWidth +{ + eHT_CHANNEL_WIDTH_20MHZ = 0, + eHT_CHANNEL_WIDTH_40MHZ = 1, +#ifdef WLAN_FEATURE_11AC + eHT_CHANNEL_WIDTH_80MHZ = 2, + eHT_CHANNEL_WIDTH_160MHZ = 3, +#endif + eHT_MAX_CHANNEL_WIDTH +} tSirMacHTChannelWidth; + +typedef enum eSirMacHTChannelType +{ + eHT_CHAN_NO_HT = 0, + eHT_CHAN_HT20 = 1, + eHT_CHAN_HT40MINUS = 2, + eHT_CHAN_HT40PLUS = 3 +} tSirMacHTChannelType; + +//Packet struct for HT capability +typedef __ani_attr_pre_packed struct sHtCaps { + tANI_U16 advCodingCap: 1; + tANI_U16 supportedChannelWidthSet: 1; + tANI_U16 mimoPowerSave: 2; + tANI_U16 greenField: 1; + tANI_U16 shortGI20MHz: 1; + tANI_U16 shortGI40MHz: 1; + tANI_U16 txSTBC: 1; + tANI_U16 rxSTBC: 2; + tANI_U16 delayedBA: 1; + tANI_U16 maximalAMSDUsize: 1; + tANI_U16 dsssCckMode40MHz: 1; + tANI_U16 psmp: 1; + tANI_U16 stbcControlFrame: 1; + tANI_U16 lsigTXOPProtection: 1; + tANI_U8 maxRxAMPDUFactor: 2; + tANI_U8 mpduDensity: 3; + tANI_U8 reserved1: 3; + tANI_U8 supportedMCSSet[16]; + tANI_U16 pco: 1; + tANI_U16 transitionTime: 2; + tANI_U16 reserved2: 5; + tANI_U16 mcsFeedback: 2; + tANI_U16 reserved3: 6; + tANI_U32 txBF: 1; + tANI_U32 rxStaggeredSounding: 1; + tANI_U32 txStaggeredSounding: 1; + tANI_U32 rxZLF: 1; + tANI_U32 txZLF: 1; + tANI_U32 implicitTxBF: 1; + tANI_U32 calibration: 2; + tANI_U32 explicitCSITxBF: 1; + tANI_U32 explicitUncompressedSteeringMatrix: 1; + tANI_U32 explicitBFCSIFeedback: 3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback: 3; + tANI_U32 explicitCompressedSteeringMatrixFeedback: 3; + tANI_U32 csiNumBFAntennae: 2; + tANI_U32 uncompressedSteeringMatrixBFAntennae: 2; + tANI_U32 compressedSteeringMatrixBFAntennae: 2; + tANI_U32 reserved4: 7; + tANI_U8 antennaSelection: 1; + tANI_U8 explicitCSIFeedbackTx: 1; + tANI_U8 antennaIndicesFeedbackTx: 1; + tANI_U8 explicitCSIFeedback: 1; + tANI_U8 antennaIndicesFeedback: 1; + tANI_U8 rxAS: 1; + tANI_U8 txSoundingPPDUs: 1; + tANI_U8 reserved5: 1; + +} __ani_attr_packed tHtCaps; + +/* During 11h channel switch, the AP can indicate if the + * STA needs to stop the transmission or continue until the + * channel-switch. + * eSIR_CHANSW_MODE_NORMAL - STA can continue transmission + * eSIR_CHANSW_MODE_SILENT - STA should stop transmission + */ +typedef enum eSirMacChanSwMode +{ + eSIR_CHANSW_MODE_NORMAL = 0, + eSIR_CHANSW_MODE_SILENT = 1 +} tSirMacChanSwitchMode; + + +typedef __ani_attr_pre_packed struct _BarControl { + +#ifndef ANI_BIG_BYTE_ENDIAN + + tANI_U16 barAckPolicy:1; + tANI_U16 multiTID:1; + tANI_U16 bitMap:1; + tANI_U16 rsvd:9; + tANI_U16 numTID:4; + +#else + tANI_U16 numTID:4; + tANI_U16 rsvd:9; + tANI_U16 bitMap:1; + tANI_U16 multiTID:1; + tANI_U16 barAckPolicy:1; + +#endif + +}__ani_attr_packed barCtrlType; + +typedef __ani_attr_pre_packed struct _BARFrmStruct { + tSirMacFrameCtl fc; + tANI_U16 duration; + tSirMacAddr rxAddr; + tSirMacAddr txAddr; + barCtrlType barControl; + tSirMacSeqCtl ssnCtrl; +}__ani_attr_packed BARFrmType; + + +// Supported MCS set +#define SIZE_OF_SUPPORTED_MCS_SET 16 +#define SIZE_OF_BASIC_MCS_SET 16 +#define VALID_MCS_SIZE 77 //0-76 +#define MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET 10 +// This is not clear, Count 8 based from NV supported MCS count +#define VALID_MAX_MCS_INDEX 8 + +// +// The following enums will be used to get the "current" HT Capabilities of +// the local STA in a generic fashion. In other words, the following enums +// identify the HT capabilities that can be queried or set. +// +typedef enum eHTCapability +{ + eHT_LSIG_TXOP_PROTECTION, + eHT_STBC_CONTROL_FRAME, + eHT_PSMP, + eHT_DSSS_CCK_MODE_40MHZ, + eHT_MAX_AMSDU_LENGTH, + eHT_DELAYED_BA, + eHT_RX_STBC, + eHT_TX_STBC, + eHT_SHORT_GI_40MHZ, + eHT_SHORT_GI_20MHZ, + eHT_GREENFIELD, + eHT_MIMO_POWER_SAVE, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + eHT_ADVANCED_CODING, + eHT_MAX_RX_AMPDU_FACTOR, + eHT_MPDU_DENSITY, + eHT_PCO, + eHT_TRANSITION_TIME, + eHT_MCS_FEEDBACK, + eHT_TX_BEAMFORMING, + eHT_ANTENNA_SELECTION, + // The following come under Additional HT Capabilities + eHT_SI_GRANULARITY, + eHT_CONTROLLED_ACCESS, + eHT_RIFS_MODE, + eHT_RECOMMENDED_TX_WIDTH_SET, + eHT_EXTENSION_CHANNEL_OFFSET, + eHT_OP_MODE, + eHT_BASIC_STBC_MCS, + eHT_DUAL_CTS_PROTECTION, + eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT, + eHT_PCO_ACTIVE, + eHT_PCO_PHASE +} tHTCapability; + +// HT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 lsigTXOPProtection:1; // Dynamic state + tANI_U16 stbcControlFrame:1; // Static via CFG + tANI_U16 psmp:1; // Static via CFG + tANI_U16 dsssCckMode40MHz:1; // Static via CFG + tANI_U16 maximalAMSDUsize:1; // Static via CFG + tANI_U16 delayedBA:1; // Static via CFG + tANI_U16 rxSTBC:2; // Static via CFG + tANI_U16 txSTBC:1; // Static via CFG + tANI_U16 shortGI40MHz:1; // Static via CFG + tANI_U16 shortGI20MHz:1; // Static via CFG + tANI_U16 greenField:1; // Static via CFG + tANI_U16 mimoPowerSave:2; // Dynamic state + tANI_U16 supportedChannelWidthSet:1; // Static via CFG + tANI_U16 advCodingCap:1; // Static via CFG +#else + tANI_U16 advCodingCap:1; + tANI_U16 supportedChannelWidthSet:1; + tANI_U16 mimoPowerSave:2; + tANI_U16 greenField:1; + tANI_U16 shortGI20MHz:1; + tANI_U16 shortGI40MHz:1; + tANI_U16 txSTBC:1; + tANI_U16 rxSTBC:2; + tANI_U16 delayedBA:1; + tANI_U16 maximalAMSDUsize:1; + tANI_U16 dsssCckMode40MHz:1; + tANI_U16 psmp:1; + tANI_U16 stbcControlFrame:1; + tANI_U16 lsigTXOPProtection:1; +#endif +} __ani_attr_packed tSirMacHTCapabilityInfo; + +// HT Parameters Info +typedef __ani_attr_pre_packed struct sSirMacHTParametersInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved:3; + tANI_U8 mpduDensity:3; // Dynamic state + tANI_U8 maxRxAMPDUFactor:2; // Dynamic state +#else + tANI_U8 maxRxAMPDUFactor:2; + tANI_U8 mpduDensity:3; + tANI_U8 reserved:3; +#endif +} __ani_attr_packed tSirMacHTParametersInfo; + +// Extended HT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacExtendedHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved2:6; + tANI_U16 mcsFeedback:2; // Static via CFG + tANI_U16 reserved1:5; + tANI_U16 transitionTime:2; // Static via CFG + tANI_U16 pco:1; // Static via CFG +#else + tANI_U16 pco:1; + tANI_U16 transitionTime:2; + tANI_U16 reserved1:5; + tANI_U16 mcsFeedback:2; + tANI_U16 reserved2:6; +#endif +} __ani_attr_packed tSirMacExtendedHTCapabilityInfo; + +//IEEE 802.11n/D7.0 - 7.3.2.57.4 +//Part of the "supported MCS set field" +typedef __ani_attr_pre_packed struct sSirMacRxHighestSupportRate +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved : 6; + tANI_U16 rate : 10; +#else + tANI_U16 rate : 10; + tANI_U16 reserved : 6; +#endif +} __ani_attr_packed tSirMacRxHighestSupportRate, *tpSirMacRxHighestSupportRate; + + +// Transmit Beam Forming Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacTxBFCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U32 reserved:7; + tANI_U32 compressedSteeringMatrixBFAntennae:2; // Static via CFG + tANI_U32 uncompressedSteeringMatrixBFAntennae:2; // Static via CFG + tANI_U32 csiNumBFAntennae:2; // Static via CFG + tANI_U32 explicitCompressedSteeringMatrixFeedback:3; // Static via CFG + tANI_U32 explicitUncompressedSteeringMatrixFeedback:3; // Static via CFG + tANI_U32 explicitBFCSIFeedback:3; // Static via CFG + tANI_U32 explicitUncompressedSteeringMatrix:1; // Static via CFG + tANI_U32 explicitCSITxBF:1; // Static via CFG + tANI_U32 calibration:2; // Static via CFG + tANI_U32 implicitTxBF:1; // Static via CFG + tANI_U32 txZLF:1; // Static via CFG + tANI_U32 rxZLF:1; // Static via CFG + tANI_U32 txStaggeredSounding:1; // Static via CFG + tANI_U32 rxStaggeredSounding:1; // Static via CFG + tANI_U32 txBF:1; // Static via CFG +#else + tANI_U32 txBF:1; + tANI_U32 rxStaggeredSounding:1; + tANI_U32 txStaggeredSounding:1; + tANI_U32 rxZLF:1; + tANI_U32 txZLF:1; + tANI_U32 implicitTxBF:1; + tANI_U32 calibration:2; + tANI_U32 explicitCSITxBF:1; + tANI_U32 explicitUncompressedSteeringMatrix:1; + tANI_U32 explicitBFCSIFeedback:3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback:3; + tANI_U32 explicitCompressedSteeringMatrixFeedback:3; + tANI_U32 csiNumBFAntennae:2; + tANI_U32 uncompressedSteeringMatrixBFAntennae:2; + tANI_U32 compressedSteeringMatrixBFAntennae:2; + tANI_U32 reserved:7; +#endif +} __ani_attr_packed tSirMacTxBFCapabilityInfo; + +// Antenna Selection Capability Info +typedef __ani_attr_pre_packed struct sSirMacASCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved2:1; + tANI_U8 txSoundingPPDUs:1; // Static via CFG + tANI_U8 rxAS:1; // Static via CFG + tANI_U8 antennaIndicesFeedback:1; // Static via CFG + tANI_U8 explicitCSIFeedback:1; // Static via CFG + tANI_U8 antennaIndicesFeedbackTx:1; // Static via CFG + tANI_U8 explicitCSIFeedbackTx:1; // Static via CFG + tANI_U8 antennaSelection:1; // Static via CFG +#else + tANI_U8 antennaSelection:1; + tANI_U8 explicitCSIFeedbackTx:1; + tANI_U8 antennaIndicesFeedbackTx:1; + tANI_U8 explicitCSIFeedback:1; + tANI_U8 antennaIndicesFeedback:1; + tANI_U8 rxAS:1; + tANI_U8 txSoundingPPDUs:1; + tANI_U8 reserved2:1; +#endif +} __ani_attr_packed tSirMacASCapabilityInfo; + +// Additional HT IE Field1 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField1 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 serviceIntervalGranularity:3; // Dynamic state + tANI_U8 controlledAccessOnly:1; // Static via CFG + tANI_U8 rifsMode:1; // Dynamic state + tANI_U8 recommendedTxWidthSet:1; // Dynamic state + tANI_U8 secondaryChannelOffset:2; // Dynamic state +#else + tANI_U8 secondaryChannelOffset:2; + tANI_U8 recommendedTxWidthSet:1; + tANI_U8 rifsMode:1; + tANI_U8 controlledAccessOnly:1; + tANI_U8 serviceIntervalGranularity:3; +#endif +} __ani_attr_packed tSirMacHTInfoField1; + +// Additional HT IE Field2 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField2 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved:11; + tANI_U16 obssNonHTStaPresent:1; /*added for Obss */ + tANI_U16 transmitBurstLimit: 1; + tANI_U16 nonGFDevicesPresent:1; + tANI_U16 opMode:2; // Dynamic state +#else + tANI_U16 opMode:2; + tANI_U16 nonGFDevicesPresent:1; + tANI_U16 transmitBurstLimit: 1; + tANI_U16 obssNonHTStaPresent:1; /*added for Obss */ + tANI_U16 reserved:11; +#endif +} __ani_attr_packed tSirMacHTInfoField2; + +// Additional HT IE Field3 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField3 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved:4; + tANI_U16 pcoPhase:1; // Dynamic state + tANI_U16 pcoActive:1; // Dynamic state + tANI_U16 lsigTXOPProtectionFullSupport:1; // Dynamic state + tANI_U16 secondaryBeacon:1; // Dynamic state + tANI_U16 dualCTSProtection:1; // Dynamic state + tANI_U16 basicSTBCMCS:7; // Dynamic state +#else + tANI_U16 basicSTBCMCS:7; + tANI_U16 dualCTSProtection:1; + tANI_U16 secondaryBeacon:1; + tANI_U16 lsigTXOPProtectionFullSupport:1; + tANI_U16 pcoActive:1; + tANI_U16 pcoPhase:1; + tANI_U16 reserved:4; +#endif +} __ani_attr_packed tSirMacHTInfoField3; + +typedef __ani_attr_pre_packed struct sSirMacProbeReqFrame +{ + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacProbeReqFrame, *tpSirMacProbeReqFrame; + +typedef __ani_attr_pre_packed struct sSirMacProbeRspFrame +{ + tSirMacTimeStamp ts; + tSirMacBeaconInterval beaconInterval; + tSirMacCapabilityInfo capabilityInfo; + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; + tSirMacNonErpPresentIE nonErpPresent; + tSirMacDsParamSetIE dsParamsIE; + tSirMacCfParamSetIE cfParamsIE; +} __ani_attr_packed tSirMacProbeRspFrame, *tpSirMacProbeRspFrame; + +typedef __ani_attr_pre_packed struct sSirMacAuthFrameBody +{ + tANI_U16 authAlgoNumber; + tANI_U16 authTransactionSeqNumber; + tANI_U16 authStatusCode; + tANI_U8 type; // = SIR_MAC_CHALLENGE_TEXT_EID + tANI_U8 length; // = SIR_MAC_AUTH_CHALLENGE_LENGTH + tANI_U8 challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH]; +} __ani_attr_packed tSirMacAuthFrameBody, *tpSirMacAuthFrameBody; + +typedef __ani_attr_pre_packed struct sSirMacAuthenticationFrame +{ + tSirMacAuthFrameBody authFrameBody; +} __ani_attr_packed tSirMacAuthFrame, *tpSirMacAuthFrame; + +typedef __ani_attr_pre_packed struct sSirMacAssocReqFrame +{ + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 listenInterval; + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacAssocReqFrame, *tpSirMacAssocReqFrame; + +typedef __ani_attr_pre_packed struct sSirMacAssocRspFrame +{ + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 statusCode; + tANI_U16 aid; + tSirMacRateSetIE supportedRates; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacAssocRspFrame, *tpSirMacAssocRspFrame; + +typedef __ani_attr_pre_packed struct sSirMacDisassocFrame +{ + tANI_U16 reasonCode; +} __ani_attr_packed tSirMacDisassocFrame, *tpSirMacDisassocFrame; + +typedef __ani_attr_pre_packed struct sDSirMacDeauthFrame +{ + tANI_U16 reasonCode; +} __ani_attr_packed tSirMacDeauthFrame, *tpSirMacDeauthFrame; + +/// Common header for all action frames +typedef __ani_attr_pre_packed struct sSirMacActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; +} __ani_attr_packed tSirMacActionFrameHdr, *tpSirMacActionFrameHdr; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +typedef __ani_attr_pre_packed struct sSirMacVendorSpecificFrameHdr +{ + tANI_U8 category; + tANI_U8 Oui[4]; +} __ani_attr_packed tSirMacVendorSpecificFrameHdr, *tpSirMacVendorSpecificFrameHdr; +#endif + +typedef __ani_attr_pre_packed struct sSirMacVendorSpecificPublicActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; + tANI_U8 Oui[4]; + tANI_U8 OuiSubType; + tANI_U8 dialogToken; +} __ani_attr_packed tSirMacVendorSpecificPublicActionFrameHdr, *tpSirMacVendorSpecificPublicActionFrameHdr; + +typedef __ani_attr_pre_packed struct sSirMacP2PActionFrameHdr +{ + tANI_U8 category; + tANI_U8 Oui[4]; + tANI_U8 OuiSubType; + tANI_U8 dialogToken; +} __ani_attr_packed tSirMacP2PActionFrameHdr, *tpSirMacP2PActionFrameHdr; + + + +typedef struct sSirMacMeasActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; + tANI_U8 dialogToken; +} tSirMacMeasActionFrameHdr, *tpSirMacMeasActionFrameHdr; + + +#ifdef ANI_SUPPORT_11H +typedef struct sSirMacTpcReqActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tANI_U8 type; + tANI_U8 length; +} tSirMacTpcReqActionFrame, *tpSirMacTpcReqActionFrame; + +typedef struct sSirMacMeasReqActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tSirMacMeasReqIE measReqIE; +} tSirMacMeasReqActionFrame, *tpSirMacMeasReqActionFrame; +#endif + +#if defined WLAN_FEATURE_VOWIFI + +typedef struct sSirMacNeighborReportReq +{ + tANI_U8 dialogToken; + tANI_U8 ssid_present; + tSirMacSSid ssid; +} tSirMacNeighborReportReq, *tpSirMacNeighborReportReq; + +typedef struct sSirMacLinkReport +{ + tANI_U8 dialogToken; + tANI_U8 txPower; + tANI_U8 rxAntenna; + tANI_U8 txAntenna; + tANI_U8 rcpi; + tANI_U8 rsni; +} tSirMacLinkReport, *tpSirMacLinkReport; + +#define BEACON_REPORT_MAX_IES 224 //Refer IEEE 802.11k-2008, Table 7-31d +typedef struct sSirMacBeaconReport +{ + tANI_U8 regClass; + tANI_U8 channel; + tANI_U8 measStartTime[8]; + tANI_U8 measDuration; + tANI_U8 phyType; + tANI_U8 bcnProbeRsp; + tANI_U8 rsni; + tANI_U8 rcpi; + tSirMacAddr bssid; + tANI_U8 antennaId; + tANI_U32 parentTSF; + tANI_U8 numIes; + tANI_U8 Ies[BEACON_REPORT_MAX_IES]; + +} tSirMacBeaconReport, *tpSirMacBeaconReport; + +#define RADIO_REPORTS_MAX_IN_A_FRAME 4 +typedef struct sSirMacRadioMeasureReport +{ + tANI_U8 token; + tANI_U8 refused; + tANI_U8 incapable; + tANI_U8 type; + union + { + tSirMacBeaconReport beaconReport; + }report; + +}tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport; + +#endif + +// QOS action frame definitions + +// max number of possible tclas elements in any frame +#define SIR_MAC_TCLASIE_MAXNUM 2 + +// 11b rate encoding in MAC format + +#define SIR_MAC_RATE_1 0x02 +#define SIR_MAC_RATE_2 0x04 +#define SIR_MAC_RATE_5_5 0x0B +#define SIR_MAC_RATE_11 0x16 + +// 11a/g rate encoding in MAC format + +#define SIR_MAC_RATE_6 0x0C +#define SIR_MAC_RATE_9 0x12 +#define SIR_MAC_RATE_12 0x18 +#define SIR_MAC_RATE_18 0x24 +#define SIR_MAC_RATE_24 0x30 +#define SIR_MAC_RATE_36 0x48 +#define SIR_MAC_RATE_48 0x60 +#define SIR_MAC_RATE_54 0x6C + +// ANI legacy supported rates +#define SIR_MAC_RATE_72 0x01 +#define SIR_MAC_RATE_96 0x03 +#define SIR_MAC_RATE_108 0x05 + +// ANI enhanced rates +#define SIR_MAC_RATE_42 1000 +#define SIR_MAC_RATE_84 1001 +#define SIR_MAC_RATE_126 1002 +#define SIR_MAC_RATE_144 1003 +#define SIR_MAC_RATE_168 1004 +#define SIR_MAC_RATE_192 1005 +#define SIR_MAC_RATE_216 1006 +#define SIR_MAC_RATE_240 1007 + +#define SIR_MAC_RATE_1_BITMAP (1<<0) +#define SIR_MAC_RATE_2_BITMAP (1<<1) +#define SIR_MAC_RATE_5_5_BITMAP (1<<2) +#define SIR_MAC_RATE_11_BITMAP (1<<3) +#define SIR_MAC_RATE_6_BITMAP (1<<4) +#define SIR_MAC_RATE_9_BITMAP (1<<5) +#define SIR_MAC_RATE_12_BITMAP (1<<6) +#define SIR_MAC_RATE_18_BITMAP (1<<7) +#define SIR_MAC_RATE_24_BITMAP (1<<8) +#define SIR_MAC_RATE_36_BITMAP (1<<9) +#define SIR_MAC_RATE_48_BITMAP (1<<10) +#define SIR_MAC_RATE_54_BITMAP (1<<11) + + +#define sirIsArate(x) ((((tANI_U8)x)==SIR_MAC_RATE_6) || \ + (((tANI_U8)x)==SIR_MAC_RATE_9) || \ + (((tANI_U8)x)==SIR_MAC_RATE_12)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_18)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_24)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_36)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_48)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_54)) + +#define sirIsBrate(x) ((((tANI_U8)x)==SIR_MAC_RATE_1) || \ + (((tANI_U8)x)==SIR_MAC_RATE_2) || \ + (((tANI_U8)x)==SIR_MAC_RATE_5_5)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_11)) + +#define sirIsGrate(x) ((((tANI_U8)x)==SIR_MAC_RATE_1) || \ + (((tANI_U8)x)==SIR_MAC_RATE_2) || \ + (((tANI_U8)x)==SIR_MAC_RATE_5_5)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_11) || \ + (((tANI_U8)x)==SIR_MAC_RATE_6) || \ + (((tANI_U8)x)==SIR_MAC_RATE_9) || \ + (((tANI_U8)x)==SIR_MAC_RATE_12) || \ + (((tANI_U8)x)==SIR_MAC_RATE_18) || \ + (((tANI_U8)x)==SIR_MAC_RATE_24) || \ + (((tANI_U8)x)==SIR_MAC_RATE_36) || \ + (((tANI_U8)x)==SIR_MAC_RATE_48) || \ + (((tANI_U8)x)==SIR_MAC_RATE_54)) + +#define SIR_MAC_MIN_IE_LEN 2 // Minimum IE length for IE validation + + +#define SIR_MAC_TI_TYPE_REASSOC_DEADLINE 1 +#define SIR_MAC_TI_TYPE_KEY_LIFETIME 2 +#define SIR_MAC_TI_TYPE_ASSOC_COMEBACK 3 + +#define SIR_MAC_VHT_CAP_MAX_MPDU_LEN 0 +#define SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET 2 +#define SIR_MAC_VHT_CAP_LDPC_CODING_CAP 4 +#define SIR_MAC_VHT_CAP_SHORTGI_80MHZ 5 +#define SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ 6 +#define SIR_MAC_VHT_CAP_TXSTBC 7 +#define SIR_MAC_VHT_CAP_RXSTBC 8 +#define SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP 11 +#define SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP 12 +#define SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP 13 +#define SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM 16 +#define SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP 19 +#define SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP 20 +#define SIR_MAC_VHT_CAP_TXOPPS 21 +#define SIR_MAC_VHT_CAP_HTC_CAP 22 +#define SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO 23 +#define SIR_MAC_VHT_CAP_LINK_ADAPT_CAP 26 +#define SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN 28 +#define SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN 29 +#define SIR_MAC_VHT_CAP_RESERVED2 30 + +#define SIR_MAC_HT_CAP_ADVCODING_S 0 +#define SIR_MAC_HT_CAP_CHWIDTH40_S 1 +#define SIR_MAC_HT_CAP_SMPOWERSAVE_DYNAMIC_S 2 +#define SIR_MAC_HT_CAP_SM_RESERVED_S 3 +#define SIR_MAC_HT_CAP_GREENFIELD_S 4 +#define SIR_MAC_HT_CAP_SHORTGI20MHZ_S 5 +#define SIR_MAC_HT_CAP_SHORTGI40MHZ_S 6 +#define SIR_MAC_HT_CAP_TXSTBC_S 7 +#define SIR_MAC_HT_CAP_RXSTBC_S 8 +#define SIR_MAC_HT_CAP_DELAYEDBLKACK_S 10 +#define SIR_MAC_HT_CAP_MAXAMSDUSIZE_S 11 +#define SIR_MAC_HT_CAP_DSSSCCK40_S 12 +#define SIR_MAC_HT_CAP_PSMP_S 13 +#define SIR_MAC_HT_CAP_INTOLERANT40_S 14 +#define SIR_MAC_HT_CAP_LSIGTXOPPROT_S 15 + +#define SIR_MAC_TXSTBC 1 +#define SIR_MAC_RXSTBC 1 + +#endif /* __MAC_PROT_DEFS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirTypes.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirTypes.h new file mode 100644 index 0000000000000..4c4f177600a7c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirTypes.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sirTypes.h contains the common types + * + * Author: V. K. Kandarpa + * Date: 04/12/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIR_TYPES_H +#define __SIR_TYPES_H + +#include "halTypes.h" + +#define FIRST_SCAN_ID 1 +/* ********************************************** * + * * + * SIRIUS ERROR Codes / Return Codes * + * * + * ********************************************** */ + +/// Return status type +typedef enum eSirRetStatus +{ + eSIR_SUCCESS, + eSIR_FAILURE, + + /// System Errors + eSIR_SYS_ERROR_BASE=0x100, + eSIR_SYS_TX_THREAD_CREATE_FAILED, + eSIR_SYS_TX_THREAD_RESUME_FAILED, + eSIR_SYS_TX_MSG_Q_CREATE_FAILED, + eSIR_SYS_TX_Q_SEND_FAILED, + eSIR_SYS_TX_Q_RECV_FAILED, + eSIR_SYS_TX_TIMER_ACTIVATE_FAILED, + eSIR_SYS_TX_TIMER_CHANGE_FAILED, + eSIR_SYS_TX_TIMER_CREATE_FAILED, + eSIR_MEM_ALLOC_FAILED, + eSIR_PCI_ERROR, + + // Driver Return Codes + eSIR_HAL_ERROR_BASE=0x1000, + eSIR_HAL_STAID_INVALID, // 1 + eSIR_HAL_TCDESC_INVALID, // 2 + eSIR_HAL_TX_WQ_NOT_VALID, // 3 + eSIR_HAL_PREV_BMU_CMD_INCOMPLETE, // 4 + eSIR_HAL_EEPROM_CRC_FAILED, // 5 + eSIR_HAL_PCI_REVID_INVALID, // 6 + eSIR_HAL_STA_TC_ID_INVALID, // 7 + eSIR_HAL_TXWQ_EMPTY, // 8 + eSIR_HAL_ROUT_TBL_TYPE_STYPE_INVALID, // 9 + eSIR_HAL_TFP_ENABLE_FAILED, // a + eSIR_HAL_TFP_ABORT_CMD_FAILED, // b + eSIR_HAL_TFP_TEMPL_BCNLEN_INVALID, // c + eSIR_HAL_TFP_TEMPL_SCHLEN_INVALID, // d + eSIR_HAL_TFP_TEMPL_CFENDLEN_INVALID, // e + eSIR_HAL_TFP_TEMPL_RRLEN_INVALID, // f + eSIR_HAL_TFP_TEMPL_PSPOLLLEN_INVALID, // 10 + eSIR_HAL_TFP_TEMPL_CTSLEN_INVALID, // 11 + eSIR_HAL_TFP_TEMPL_CFPOLLLEN_INVALID, // 12 + eSIR_HAL_TFP_TEMPL_BACKLEN_INVALID, // 13 + eSIR_HAL_INPUT_INVALID, // 14 + eSIR_HAL_GET_PDU_FAILED, // 15 + eSIR_HAL_ADD_STA_ACK_POLICY_INVALID, // 16 + eSIR_HAL_STA_EXISTS, // 17 + eSIR_HAL_STA_DOES_NOT_EXIST, // 18 + eSIR_HAL_MASTER_WQ_ID_INVALID, // 19 + eSIR_HAL_WQ_NOT_EMPTY, // 1a + eSIR_HAL_WQ_EMPTY, // 1b + eSIR_HAL_PDUCNT_AND_NEXTPTR_MISMATCH, // 1c + eSIR_HAL_ERR_NUM_BYTES_TO_BE_SET_TOO_BIG, // 1d + eSIR_HAL_GET_PKT_LENGTH_INVALID, // 1e + eSIR_HAL_AS_CNT_INVALID, // 1f + eSIR_HAL_RFP_AGE_CMD_SEQFAIL, // 20 + eSIR_HAL_RFP_AGE_CMD_AGE_CMD_TCFAIL, // 21 + eSIR_HAL_RFP_AGE_CMD_PASS, // 22 + eSIR_HAL_RFP_AGE_CMD_TIMEDOUT, // 23 + eSIR_HAL_RHP_HASH_CMD_TIMEOUT, // 24 + eSIR_HAL_RHP_ROUTING_TBL_SET_FAILED, // 25 + eSIR_HAL_RHP_ROUTING_TBL_GET_FAILED, // 26 + + eSIR_HAL_CAL_STATUS_CHK_FAILED, + + eSIR_HAL_SYS_ARM_DBG_MODE_SET_FAILED, + eSIR_HAL_TFP_BCN_SENT, + eSIR_HAL_TFP_BCN_NOT_SENT, + eSIR_HAL_TFP_BKOF_ID_INVALID, + eSIR_HAL_TFP_CFB_ENABLE_INPUT_INVALID, + eSIR_HAL_TFP_EDCF_TXOP_INVALID, + eSIR_HAL_TFP_TEMPL_LEN_INVALID, + eSIR_HAL_KEY_ID_INVALID, + eSIR_HAL_KEY_LEN_INVALID, + eSIR_HAL_CHID_INVALID, + eSIR_HAL_HIF_BURST_READ_FAILED, + eSIR_HAL_HIF_BURST_WRITE_FAILED, + eSIR_HAL_HIF_BURST_LEN_REQ_INVALID, + eSIR_HAL_HIF_TX_NO_FRAG_DESC, + + eSIR_HAL_INVALID_PRODUCT_ID, // 44 + + eSIR_HAL_INVALID_CAPABILITY, // 48 + eSIR_HAL_CB_NOT_ENABLED, // 49 + eSIR_HAL_MAC_RATE_INVALID, // 4a + eSIR_HAL_RHP_HANG, // 4b + eSIR_HAL_UNSUPPORTED, // 4c + eSIR_HAL_TSPEC_INVALID, // 4d + + // NIM Return Codes + eSIR_NIM_ERROR_BASE=0x2000, + eSIR_NIM_ERR_INVALID_EVENT, + + + // MMH Return Codes + eSIR_NIM_MMH_ERROR_BASE=0x2100, + eSIR_NIM_MMH_ERR_INV_EVENT, + eSIR_NIM_MMH_ERR_MSG_LEN, + eSIR_NIM_MMH_ERR_IN_Q_TYPE, + + // MNT Return Codes + eSIR_NIM_MNT_ERROR_BASE=0x2140, + + // WDT Errors + eSIR_NIM_WDT_ERROR_BASE=0x2180, + + // LIM Return Codes + eSIR_LIM_ERROR_BASE=0x2200, + eSIR_LIM_IGNORE_BEACON, + eSIR_LIM_INVALID_STA, + eSIR_LIM_MAX_STA_REACHED_ERROR, + + // SCH Return Codes + eSIR_SCH_ERROR_BASE=0x2300, + + // PMM Return Codes + eSIR_PMM_ERROR_BASE=0x2400, + eSIR_PMM_INVALID_MODE, + eSIR_PMM_INVALID_STATE, + eSIR_PMM_INVALID_ROLE, + eSIR_PMM_STA_NOT_ASSOCIATED, + eSIR_PMM_HEART_BEAT_TMOUT, + eSIR_PMM_NTH_BEACON_DELIVERY, + + // ARQ Return Codes + eSIR_ARQ_ERROR_BASE=0x2500, + + // CFG Return Codes + eSIR_CFG_ERROR_BASE=2600, + eSIR_CFG_INVALID_ID, + eSIR_CFG_INVALID_LEN, + + // parser Return Codes + eSIR_PRS_ERROR_BASE=0x2700, + eSIR_IGNORE_IE, + + // Put all your return codes above this line + eSIR_ERROR_LAST + +} tSirRetStatus; + +# endif // __SIR_TYPES_H diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniApi.h new file mode 100644 index 0000000000000..5504f296d9e1a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniApi.h @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file wniApi.h contains message definitions exported by + * Sirius software modules. + * NOTE: See projects/sirius/include/sirApi.h for structure + * definitions of the host/FW messages. + * + * Author: Chandra Modumudi + * Date: 04/11/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __WNI_API_H +#define __WNI_API_H + +// DPH return error codes +#define ANI_DPH_SUCCESS 0 + +#define ANI_DPH_RX_STA_INVALID 1 + +#define ANI_DPH_DO_TKIP 2 + +#define ANI_DPH_PORT_BLOCKED 3 +#define ANI_DPH_TX_PUSH_ERROR 10 +#define ANI_DPH_TX_MAC_HDR_ERROR 11 +#define ANI_DPH_TX_INVALID_PAYLOAD 12 +#define ANI_DPH_TX_STA_INVALID 13 +#define ANI_DPH_TX_HASH_MISS 14 +#define ANI_DPH_TX_UNINITIALIZED 15 +#define ANI_DPH_TX_RADIO_IN_DIAG_MODE 16 +#define ANI_DPH_WMM_DROP 17 +#define ANI_DPH_APSD_DROP 18 +#define ANI_DPH_UNKNOWN_STA 19 + +/// HDD type for special handling of BDs in the TX pkts +/// Used in the structure ani_mod_info_t->bd_spl_proc_type +#define ANI_HDD_NO_SPL_PROC 0 +#define ANI_HDD_DUMMY_PKT_SPL_PROC 1 +#define ANI_HDD_PRE_DUMMY_PKT_SPL_PROC 2 +#define ANI_HDD_WNS_L2_UPDATE_SPL_PROC 3 +#define ANI_HDD_DUMMY_DATA 4 +#ifdef WMM_APSD +#define ANI_HDD_EOSP_PKT 5 +#endif + +/// Message offset for the cmd to enqueue a dummy pkt to HDD TD ring +#define ANI_DUMMY_PKT_MSG_TYPE_OFFSET 0 +#define ANI_DUMMY_PKT_MSG_LEN_OFFSET 2 +#define ANI_DUMMY_PKT_MAC_ADDR_OFFSET 4 +#define ANI_DUMMY_PKT_STA_ID_OFFSET 10 +#define ANI_DUMMY_PKT_RT_FL_OFFSET 12 +#define ANI_DUMMY_PKT_MSG_LEN 16 +#define ANI_DUMMY_DATA_PAYLOAD_OFFSET 10 + +/** + * Product IDs stored in the EEPROM for the different types of AP radio cards + * supported by Polaris + */ +#define AGN1323AR_00 4 +#define AGN1323AR_01 5 +#define AGN1223AR_00 6 +#define AGN1223AR_01 7 +#define AGN1223AR_02 8 +#define AGN_EEP_PRODUCT_ID_MAX 8 + + + + +/// Start of Sirius/Host message types +#define WNI_HOST_MSG_START 0x1500 + +enum eWniMsgTypes +{ + /// CFG message types + eWNI_CFG_MSG_TYPES_BEGIN=WNI_HOST_MSG_START, + eWNI_CFG_MSG_TYPES_END=eWNI_CFG_MSG_TYPES_BEGIN+0xFF, + + /// SME message types + eWNI_SME_MSG_TYPES_BEGIN=eWNI_CFG_MSG_TYPES_END, + eWNI_SME_START_REQ, + eWNI_SME_START_RSP, + eWNI_SME_SYS_READY_IND, + eWNI_SME_SCAN_REQ, + eWNI_SME_SCAN_ABORT_IND, + eWNI_SME_SCAN_RSP, +#ifdef FEATURE_OEM_DATA_SUPPORT + eWNI_SME_OEM_DATA_REQ, + eWNI_SME_OEM_DATA_RSP, +#endif + eWNI_SME_JOIN_REQ, + eWNI_SME_JOIN_RSP, + eWNI_SME_SETCONTEXT_REQ, + eWNI_SME_SETCONTEXT_RSP, + eWNI_SME_REASSOC_REQ, + eWNI_SME_REASSOC_RSP, + eWNI_SME_DISASSOC_REQ, + eWNI_SME_DISASSOC_RSP, + eWNI_SME_DISASSOC_IND, + eWNI_SME_DISASSOC_CNF, + eWNI_SME_DEAUTH_REQ, + eWNI_SME_DEAUTH_RSP, + eWNI_SME_DEAUTH_IND, + eWNI_SME_WM_STATUS_CHANGE_NTF, + eWNI_SME_IBSS_NEW_PEER_IND, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + eWNI_SME_START_BSS_REQ, + eWNI_SME_START_BSS_RSP, + eWNI_SME_AUTH_IND, + eWNI_SME_ASSOC_IND, + eWNI_SME_ASSOC_CNF, + eWNI_SME_REASSOC_IND, + eWNI_SME_REASSOC_CNF, + eWNI_SME_SWITCH_CHL_REQ, + eWNI_SME_SWITCH_CHL_RSP, + eWNI_SME_STOP_BSS_REQ, + eWNI_SME_STOP_BSS_RSP, + eWNI_SME_DEL_BA_PEER_IND, + eWNI_SME_DEFINE_QOS_REQ, + eWNI_SME_DEFINE_QOS_RSP, + eWNI_SME_DELETE_QOS_REQ, + eWNI_SME_DELETE_QOS_RSP, + eWNI_SME_LINK_TEST_START_REQ, + eWNI_SME_LINK_TEST_START_RSP, + eWNI_SME_LINK_TEST_STOP_REQ, + eWNI_SME_LINK_TEST_STOP_RSP, + eWNI_SME_LINK_TEST_REPORT_IND, + eWNI_SME_NEIGHBOR_BSS_IND, + eWNI_SME_MEASUREMENT_REQ, + eWNI_SME_MEASUREMENT_RSP, + eWNI_SME_MEASUREMENT_IND, + eWNI_SME_SET_WDS_INFO_REQ, + eWNI_SME_SET_WDS_INFO_RSP, + eWNI_SME_WDS_INFO_IND, + eWNI_SME_SET_POWER_REQ, + eWNI_SME_SET_POWER_RSP, + eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_REQ, + eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_RSP, + eWNI_SME_SELECT_CHANNEL_REQ, + eWNI_SME_SELECT_CHANNEL_RSP, + eWNI_SME_SET_PROPRIETARY_IE_REQ, + eWNI_SME_SET_PROPRIETARY_IE_RSP, // #endif + eWNI_SME_DISCARD_SKB_NTF, // Used to cleanup SKBs by HDD + eWNI_SME_DEAUTH_CNF, + eWNI_SME_MIC_FAILURE_IND, + eWNI_SME_ADDTS_REQ, + eWNI_SME_ADDTS_RSP, + eWNI_SME_ADDTS_CNF, + eWNI_SME_ADDTS_IND, + eWNI_SME_DELTS_REQ, + eWNI_SME_DELTS_RSP, + eWNI_SME_DELTS_IND, + eWNI_SME_SET_BACKGROUND_SCAN_MODE_REQ, + eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ, + eWNI_SME_SWITCH_CHL_CB_PRIMARY_RSP, + eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ, + eWNI_SME_SWITCH_CHL_CB_SECONDARY_RSP, + eWNI_SME_PROBE_REQ, + eWNI_SME_STA_STAT_REQ, + eWNI_SME_STA_STAT_RSP, + eWNI_SME_AGGR_STAT_REQ, + eWNI_SME_AGGR_STAT_RSP, + eWNI_SME_GLOBAL_STAT_REQ, + eWNI_SME_GLOBAL_STAT_RSP, + eWNI_SME_STAT_SUMM_REQ, + eWNI_SME_STAT_SUMM_RSP, + eWNI_SME_REMOVEKEY_REQ, + eWNI_SME_REMOVEKEY_RSP, + eWNI_SME_GET_SCANNED_CHANNEL_REQ, + eWNI_SME_GET_SCANNED_CHANNEL_RSP, + eWNI_SME_SET_TX_POWER_REQ, + eWNI_SME_SET_TX_POWER_RSP, + eWNI_SME_GET_TX_POWER_REQ, + eWNI_SME_GET_TX_POWER_RSP, + eWNI_SME_GET_NOISE_REQ, + eWNI_SME_GET_NOISE_RSP, + eWNI_SME_LOW_RSSI_IND, + eWNI_SME_GET_STATISTICS_REQ, + eWNI_SME_GET_STATISTICS_RSP, + eWNI_SME_GET_RSSI_REQ, + eWNI_SME_GET_ROAM_RSSI_REQ, + eWNI_SME_GET_ROAM_RSSI_RSP, + eWNI_SME_GET_ASSOC_STAS_REQ, + eWNI_SME_TKIP_CNTR_MEAS_REQ, + eWNI_SME_UPDATE_APWPSIE_REQ, + eWNI_SME_GET_WPSPBC_SESSION_REQ, + eWNI_SME_WPS_PBC_PROBE_REQ_IND, + eWNI_SME_SET_APWPARSNIEs_REQ, + eWNI_SME_UPPER_LAYER_ASSOC_CNF, + eWNI_SME_HIDE_SSID_REQ, + eWNI_SME_CHNG_MCC_BEACON_INTERVAL, + eWNI_SME_REMAIN_ON_CHANNEL_REQ, + eWNI_SME_REMAIN_ON_CHN_IND, + eWNI_SME_REMAIN_ON_CHN_RSP, + eWNI_SME_MGMT_FRM_IND, + eWNI_SME_REMAIN_ON_CHN_RDY_IND, + eWNI_SME_SEND_ACTION_FRAME_IND, + eWNI_SME_ACTION_FRAME_SEND_CNF, + eWNI_SME_ABORT_REMAIN_ON_CHAN_IND, + eWNI_SME_UPDATE_NOA, + eWNI_SME_CLEAR_DFS_CHANNEL_LIST, + eWNI_SME_CLEAR_LIM_SCAN_CACHE, + eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER, + eWNI_SME_GET_SNR_REQ, + //General Power Save Messages + eWNI_PMC_MSG_TYPES_BEGIN, + eWNI_PMC_PWR_SAVE_CFG, + + //BMPS Messages + eWNI_PMC_ENTER_BMPS_REQ, + eWNI_PMC_ENTER_BMPS_RSP, + eWNI_PMC_EXIT_BMPS_REQ, + eWNI_PMC_EXIT_BMPS_RSP, + eWNI_PMC_EXIT_BMPS_IND, + + //IMPS Messages. + eWNI_PMC_ENTER_IMPS_REQ, + eWNI_PMC_ENTER_IMPS_RSP, + eWNI_PMC_EXIT_IMPS_REQ, + eWNI_PMC_EXIT_IMPS_RSP, + + //UAPSD Messages + eWNI_PMC_ENTER_UAPSD_REQ, + eWNI_PMC_ENTER_UAPSD_RSP, + eWNI_PMC_EXIT_UAPSD_REQ, + eWNI_PMC_EXIT_UAPSD_RSP, + + //WOWL Messages + eWNI_PMC_SMPS_STATE_IND, + + //WoWLAN Messages + eWNI_PMC_WOWL_ADD_BCAST_PTRN, + eWNI_PMC_WOWL_DEL_BCAST_PTRN, + eWNI_PMC_ENTER_WOWL_REQ, + eWNI_PMC_ENTER_WOWL_RSP, + eWNI_PMC_EXIT_WOWL_REQ, + eWNI_PMC_EXIT_WOWL_RSP, + +#ifdef WLAN_FEATURE_PACKET_FILTERING + eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP, +#endif // WLAN_FEATURE_PACKET_FILTERING + +#if defined WLAN_FEATURE_VOWIFI + eWNI_SME_RRM_MSG_TYPE_BEGIN, + + eWNI_SME_NEIGHBOR_REPORT_REQ_IND, + eWNI_SME_NEIGHBOR_REPORT_IND, + eWNI_SME_BEACON_REPORT_REQ_IND, + eWNI_SME_BEACON_REPORT_RESP_XMIT_IND, + +#endif + eWNI_SME_ADD_STA_SELF_REQ, + eWNI_SME_ADD_STA_SELF_RSP, + eWNI_SME_DEL_STA_SELF_REQ, + eWNI_SME_DEL_STA_SELF_RSP, + +#if defined WLAN_FEATURE_VOWIFI_11R + eWNI_SME_FT_PRE_AUTH_REQ, + eWNI_SME_FT_PRE_AUTH_RSP, + eWNI_SME_FT_UPDATE_KEY, + eWNI_SME_FT_AGGR_QOS_REQ, + eWNI_SME_FT_AGGR_QOS_RSP, +#endif + +#if defined FEATURE_WLAN_ESE + eWNI_SME_ESE_ADJACENT_AP_REPORT, +#endif + + eWNI_SME_REGISTER_MGMT_FRAME_REQ, + + eWNI_SME_COEX_IND, + +#ifdef FEATURE_WLAN_SCAN_PNO + eWNI_SME_PREF_NETWORK_FOUND_IND, +#endif // FEATURE_WLAN_SCAN_PNO + + eWNI_SME_TX_PER_HIT_IND, + + eWNI_SME_CHANGE_COUNTRY_CODE, + eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE, + eWNI_SME_PRE_SWITCH_CHL_IND, + eWNI_SME_POST_SWITCH_CHL_IND, + + eWNI_SME_MAX_ASSOC_EXCEEDED, + + eWNI_SME_BTAMP_LOG_LINK_IND,//to serialize the create/accpet LL req from HCI + + +#ifdef WLAN_WAKEUP_EVENTS + eWNI_SME_WAKE_REASON_IND, +#endif // WLAN_WAKEUP_EVENTS + eWNI_SME_EXCLUDE_UNENCRYPTED, + eWNI_SME_RSSI_IND, //RSSI indication from TL to be serialized on MC thread +#ifdef FEATURE_WLAN_TDLS + eWNI_SME_TDLS_SEND_MGMT_REQ, + eWNI_SME_TDLS_SEND_MGMT_RSP, + eWNI_SME_TDLS_ADD_STA_REQ, + eWNI_SME_TDLS_ADD_STA_RSP, + eWNI_SME_TDLS_DEL_STA_REQ, + eWNI_SME_TDLS_DEL_STA_RSP, + eWNI_SME_TDLS_DEL_STA_IND, + eWNI_SME_TDLS_DEL_ALL_PEER_IND, + eWNI_SME_MGMT_FRM_TX_COMPLETION_IND, + eWNI_SME_TDLS_LINK_ESTABLISH_REQ, + eWNI_SME_TDLS_LINK_ESTABLISH_RSP, + eWNI_SME_TDLS_SHOULD_DISCOVER, + eWNI_SME_TDLS_SHOULD_TEARDOWN, + eWNI_SME_TDLS_PEER_DISCONNECTED, +#endif + //NOTE: If you are planning to add more mesages, please make sure that + //SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as + //SIR_LIM_MSG_TYPES_BEGIN+0xB0 = 12B0 (which means max of 176 messages and + //eWNI_SME_TDLS_DEL_STA_RSP = 175. + //Should fix above issue to enable TDLS_INTERNAL + eWNI_SME_SET_BCN_FILTER_REQ, + eWNI_SME_RESET_AP_CAPS_CHANGED, +#ifdef WLAN_FEATURE_11W + eWNI_SME_UNPROT_MGMT_FRM_IND, +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD + eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP, +#endif // WLAN_FEATURE_GTK_OFFLOAD + eWNI_SME_CANDIDATE_FOUND_IND, /*ROAM candidate indication from FW*/ + eWNI_SME_HANDOFF_REQ,/*upper layer requested handoff to driver in STA mode*/ + eWNI_SME_ROAM_SCAN_OFFLOAD_RSP,/*Fwd the LFR scan offload rsp from FW to SME*/ +#ifdef FEATURE_WLAN_LPHB + eWNI_SME_LPHB_IND, +#endif /* FEATURE_WLAN_LPHB */ + + eWNI_SME_GET_TSM_STATS_REQ, + eWNI_SME_GET_TSM_STATS_RSP, + eWNI_SME_TSM_IE_IND, + + eWNI_SME_READY_TO_SUSPEND_IND, +#ifdef FEATURE_WLAN_CH_AVOID + eWNI_SME_CH_AVOID_IND, +#endif /* FEATURE_WLAN_CH_AVOID */ + /* DFS EVENTS */ + eWNI_SME_DFS_RADAR_FOUND, //RADAR found indication from DFS + eWNI_SME_CHANNEL_CHANGE_REQ,//Channel Change Request from SAP + eWNI_SME_CHANNEL_CHANGE_RSP,// Channel Change Response from WMA + eWNI_SME_START_BEACON_REQ,//Start Beacon Transmission. + eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ, //Transmit CSA IE in beacons + eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND, //To indicate completion of CSA IE + //update in beacons/probe rsp + eWNI_SME_STATS_EXT_EVENT, + eWNI_SME_LINK_SPEED_IND,//Indicate linkspeed response from WMA + eWNI_SME_CSA_OFFLOAD_EVENT, + eWNI_SME_UPDATE_ADDITIONAL_IES, // indicates Additional IE from hdd to PE + eWNI_SME_MODIFY_ADDITIONAL_IES, /* To indicate IE modify from hdd to PE */ +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + eWNI_SME_AUTO_SHUTDOWN_IND, +#endif +#ifdef QCA_HT_2040_COEX + eWNI_SME_SET_HT_2040_MODE, +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + eWNI_SME_ROAM_OFFLOAD_SYNCH_IND, /* Roam Synch Indication from WMA to SME*/ + eWNI_SME_HO_FAIL_IND, /* Hand Off Failure Ind from WMA to SME */ +#endif +#ifdef WLAN_FEATURE_NAN + eWNI_SME_NAN_EVENT, +#endif + eWNI_SME_LINK_STATUS_IND, +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + eWNI_SME_READY_TO_EXTWOW_IND, +#endif +#ifdef FEATURE_WLAN_EXTSCAN + eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND, +#endif + eWNI_SME_MSG_TYPES_END +}; + +typedef enum { + eWNI_TDLS_TEARDOWN_REASON_TX, + eWNI_TDLS_TEARDOWN_REASON_RSSI, + eWNI_TDLS_TEARDOWN_REASON_SCAN, + eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE, + eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT, + eWNI_TDLS_TEARDOWN_REASON_BAD_PTR, + eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE, +} eWniTdlsTeardownReason; + +#define WNI_CFG_MSG_TYPES_BEGIN 0x1200 + +/*---------------------------------------------------------------------*/ +/* CFG Module Definitions */ +/*---------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------*/ +/* CFG message definitions */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_MSG_HDR_MASK 0xffff0000 +#define WNI_CFG_MSG_LEN_MASK 0x0000ffff +#define WNI_CFG_MB_HDR_LEN 4 +#define WNI_CFG_MAX_PARAM_NUM 32 + + +/*---------------------------------------------------------------------*/ +/* CFG to HDD message types */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_PARAM_UPDATE_IND (WNI_CFG_MSG_TYPES_BEGIN | 0x00) +#define WNI_CFG_DNLD_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x01) +#define WNI_CFG_DNLD_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x02) +#define WNI_CFG_GET_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x03) +#define WNI_CFG_SET_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x04) +#define WNI_CFG_GET_ATTRIB_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x05) +#define WNI_CFG_ADD_GRP_ADDR_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x06) +#define WNI_CFG_DEL_GRP_ADDR_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x07) + +#define ANI_CFG_GET_RADIO_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x08) +#define ANI_CFG_GET_PER_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x09) +#define ANI_CFG_GET_AGG_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0a) +#define ANI_CFG_CLEAR_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0b) + + +/*---------------------------------------------------------------------*/ +/* CFG to HDD message paramter indices */ + +/* The followings are word indices starting from the message body */ + +/* WNI_CFG_xxxx_xxxx_xxxx: index of parameter */ +/* */ +/* WNI_CFG_xxxx_xxxx_NUM: number of parameters in message */ +/* */ +/* WNI_CFG_xxxx_xxxx_LEN: byte length of message including */ +/* MB header */ +/* */ +/* WNI_CFG_xxxx_xxxx_PARTIAL_LEN: byte length of message including */ +/* parameters and MB header but */ +/* excluding variable data length */ +/*---------------------------------------------------------------------*/ + +// Parameter update indication +#define WNI_CFG_PARAM_UPDATE_IND_PID 0 + +#define WNI_CFG_PARAM_UPDATE_IND_NUM 1 +#define WNI_CFG_PARAM_UPDATE_IND_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_PARAM_UPDATE_IND_NUM << 2)) + +// Configuration download request +#define WNI_CFG_DNLD_REQ_NUM 0 +#define WNI_CFG_DNLD_REQ_LEN WNI_CFG_MB_HDR_LEN + +// Configuration download confirm +#define WNI_CFG_DNLD_CNF_RES 0 + +#define WNI_CFG_DNLD_CNF_NUM 1 +#define WNI_CFG_DNLD_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DNLD_CNF_NUM << 2)) +// Get response +#define WNI_CFG_GET_RSP_RES 0 +#define WNI_CFG_GET_RSP_PID 1 +#define WNI_CFG_GET_RSP_PLEN 2 + +#define WNI_CFG_GET_RSP_NUM 3 +#define WNI_CFG_GET_RSP_PARTIAL_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_RSP_NUM << 2)) +// Set confirm +#define WNI_CFG_SET_CNF_RES 0 +#define WNI_CFG_SET_CNF_PID 1 + +#define WNI_CFG_SET_CNF_NUM 2 +#define WNI_CFG_SET_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_SET_CNF_NUM << 2)) +// Get attribute response +#define WNI_CFG_GET_ATTRIB_RSP_RES 0 +#define WNI_CFG_GET_ATTRIB_RSP_PID 1 +#define WNI_CFG_GET_ATTRIB_RSP_TYPE 2 +#define WNI_CFG_GET_ATTRIB_RSP_PLEN 3 +#define WNI_CFG_GET_ATTRIB_RSP_RW 4 + +#define WNI_CFG_GET_ATTRIB_RSP_NUM 5 +#define WNI_CFG_GET_ATTRIB_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_ATTRIB_RSP_NUM << 2)) + +// Add group address confirm +#define WNI_CFG_ADD_GRP_ADDR_CNF_RES 0 + +#define WNI_CFG_ADD_GRP_ADDR_CNF_NUM 1 +#define WNI_CFG_ADD_GRP_ADDR_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_ADD_GRP_ADDR_CNF_NUM << 2)) + +// Delete group address confirm +#define WNI_CFG_DEL_GRP_ADDR_CNF_RES 0 + +#define WNI_CFG_DEL_GRP_ADDR_CNF_NUM 1 +#define WNI_CFG_DEL_GRP_ADDR_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DEL_GRP_ADDR_CNF_NUM <<2)) + + +#define IS_CFG_MSG(msg) ((msg & 0xff00) == WNI_CFG_MSG_TYPES_BEGIN) + +// Clear stats types. +#define ANI_CLEAR_ALL_STATS 0 +#define ANI_CLEAR_RX_STATS 1 +#define ANI_CLEAR_TX_STATS 2 +#define ANI_CLEAR_PER_STA_STATS 3 +#define ANI_CLEAR_AGGR_PER_STA_STATS 4 +#define ANI_CLEAR_STAT_TYPES_END 5 + +/*---------------------------------------------------------------------*/ +/* HDD to CFG message types */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_DNLD_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x80) +#define WNI_CFG_GET_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x81) +#define WNI_CFG_SET_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x82) +#define WNI_CFG_SET_REQ_NO_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x83) //No RSP for this set + +// Shall be removed after stats integration + + +/*---------------------------------------------------------------------*/ +/* HDD to CFG message paramter indices */ +/* */ +/* The followings are word indices starting from the message body */ +/* */ +/* WNI_CFG_xxxx_xxxx_xxxx: index of parameter */ +/* */ +/* WNI_CFG_xxxx_xxxx_NUM: number of parameters in message */ +/* */ +/* WNI_CFG_xxxx_xxxx_LEN: byte length of message including */ +/* MB header */ +/* */ +/* WNI_CFG_xxxx_xxxx_PARTIAL_LEN: byte length of message including */ +/* parameters and MB header but */ +/* excluding variable data length */ +/*---------------------------------------------------------------------*/ + +// Download response +#define WNI_CFG_DNLD_RSP_BIN_LEN 0 + +#define WNI_CFG_DNLD_RSP_NUM 1 +#define WNI_CFG_DNLD_RSP_PARTIAL_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DNLD_RSP_NUM << 2)) + +// Set parameter request +#define WNI_CFG_SET_REQ_PID 0 +#define WNI_CFG_SET_REQ_PLEN 1 + +/* +// Get attribute request +//#define WNI_CFG_GET_ATTRIB_REQ_PID 0 + +//#define WNI_CFG_GET_ATTRIB_REQ_NUM 1 +//#define WNI_CFG_GET_ATTRIB_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_ATTRIB_REQ_NUM << 2)) +// Add group address request +#define WNI_CFG_ADD_GRP_ADDR_REQ_MAC_ADDR 0 + +#define WNI_CFG_ADD_GRP_ADDR_REQ_NUM 1 +#define WNI_CFG_ADD_GRP_ADDR_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_ADD_GRP_ADDR_REQ_NUM << 2)) +// Delete group address request +#define WNI_CFG_DEL_GRP_ADDR_REQ_MAC_ADDR 0 + +#define WNI_CFG_DEL_GRP_ADDR_REQ_NUM 1 +#define WNI_CFG_DEL_GRP_ADDR_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DEL_GRP_ADDR_REQ_NUM << 2)) +*/ + + +/*---------------------------------------------------------------------*/ +/* CFG return values */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_SUCCESS 1 +#define WNI_CFG_NOT_READY 2 +#define WNI_CFG_INVALID_PID 3 +#define WNI_CFG_INVALID_LEN 4 +#define WNI_CFG_RO_PARAM 5 +#define WNI_CFG_WO_PARAM 6 +#define WNI_CFG_INVALID_STAID 7 +#define WNI_CFG_OTHER_ERROR 8 +#define WNI_CFG_NEED_RESTART 9 +#define WNI_CFG_NEED_RELOAD 10 + + +/*---------------------------------------------------------------------*/ +/* CFG definitions */ +/*---------------------------------------------------------------------*/ + +// Shall be removed after integration of stats. +// Get statistic response +#define WNI_CFG_GET_STAT_RSP_RES 0 +#define WNI_CFG_GET_STAT_RSP_PARAMID 1 +#define WNI_CFG_GET_STAT_RSP_VALUE 2 + +#define WNI_CFG_GET_STAT_RSP_NUM 3 +#define WNI_CFG_GET_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_STAT_RSP_NUM <<2)) +// Get per station statistic response +#define WNI_CFG_GET_PER_STA_STAT_RSP_RES 0 +#define WNI_CFG_GET_PER_STA_STAT_RSP_STAID 1 +#define WNI_CFG_GET_PER_STA_STAT_RSP_FIRST_PARAM 2 + +// Per STA statistic structure +typedef struct sAniCfgPerStaStatStruct +{ + unsigned long sentAesBlksUcastHi; + unsigned long sentAesBlksUcastLo; + + unsigned long recvAesBlksUcastHi; + unsigned long recvAesBlksUcastLo; + + unsigned long aesFormatErrorUcastCnts; + + unsigned long aesReplaysUcast; + + unsigned long aesDecryptErrUcast; + + unsigned long singleRetryPkts; + + unsigned long failedTxPkts; + + unsigned long ackTimeouts; + + unsigned long multiRetryPkts; + + unsigned long fragTxCntsHi; + unsigned long fragTxCntsLo; + + unsigned long transmittedPktsHi; + unsigned long transmittedPktsLo; + + unsigned long phyStatHi; + unsigned long phyStatLo; +} tCfgPerStaStatStruct, *tpAniCfgPerStaStatStruct; + +#define WNI_CFG_GET_PER_STA_STAT_RSP_NUM 23 +#define WNI_CFG_GET_PER_STA_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_PER_STA_STAT_RSP_NUM << 2)) + + +// Shall be removed after integrating stats. +#define WNI_CFG_GET_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x08) +#define WNI_CFG_GET_PER_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x09) +#define WNI_CFG_GET_AGG_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0a) +#define WNI_CFG_GET_TX_RATE_CTR_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0b) + +#define WNI_CFG_GET_AGG_STA_STAT_RSP_NUM 21 +#define WNI_CFG_GET_AGG_STA_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_AGG_STA_STAT_RSP_NUM << 2)) +#define WNI_CFG_GET_AGG_STA_STAT_RSP_RES 0 + + // Get TX rate based stats +#define WNI_CFG_GET_TX_RATE_CTR_RSP_RES 0 + +typedef struct sAniCfgTxRateCtrs +{ +// add the rate counters here + unsigned long TxFrames_1Mbps; + unsigned long TxFrames_2Mbps; + unsigned long TxFrames_5_5Mbps; + unsigned long TxFrames_6Mbps; + unsigned long TxFrames_9Mbps; + unsigned long TxFrames_11Mbps; + unsigned long TxFrames_12Mbps; + unsigned long TxFrames_18Mbps; + unsigned long TxFrames_24Mbps; + unsigned long TxFrames_36Mbps; + unsigned long TxFrames_48Mbps; + unsigned long TxFrames_54Mbps; + unsigned long TxFrames_72Mbps; + unsigned long TxFrames_96Mbps; + unsigned long TxFrames_108Mbps; + +} tAniCfgTxRateCtrs, *tpAniCfgTxRateCtrs; + + +#define WNI_CFG_GET_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x86) +#define WNI_CFG_GET_PER_STA_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x87) +#define WNI_CFG_GET_AGG_STA_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x88) +#define WNI_CFG_GET_TX_RATE_CTR_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x89) + +// Get statistic request +#define WNI_CFG_GET_STAT_REQ_PARAMID 0 + +#define WNI_CFG_GET_STAT_REQ_NUM 1 +#define WNI_CFG_GET_STAT_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_STAT_REQ_NUM << 2)) + + // Get per station statistic request +#define WNI_CFG_GET_PER_STA_STAT_REQ_STAID 0 + +#define WNI_CFG_GET_PER_STA_STAT_REQ_NUM 1 +#define WNI_CFG_GET_PER_STA_STAT_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_PER_STA_STAT_REQ_NUM << 2)) + + + + +#define DYNAMIC_CFG_TYPE_SELECTED_REGISTRAR (0) +#define DYNAMIC_CFG_TYPE_WPS_STATE (1) + +#endif /* __WNI_API_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgAp.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgAp.h new file mode 100644 index 0000000000000..cfe5914e48928 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgAp.h @@ -0,0 +1,2661 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * DO NOT EDIT - This file is generated automatically + */ + +/* + * IMPORTANT: This file is for system that supports both STA and AP mode. + */ + + +#ifndef __WNICFGAP_H +#define __WNICFGAP_H + +/* + * Configuration Parameter ID for STA and AP + */ + +#define WNI_CFG_STA_ID 0 +#define WNI_CFG_CF_POLLABLE 1 +#define WNI_CFG_CFP_PERIOD 2 +#define WNI_CFG_CFP_MAX_DURATION 3 +#define WNI_CFG_SSID 4 +#define WNI_CFG_BEACON_INTERVAL 5 +#define WNI_CFG_DTIM_PERIOD 6 +#define WNI_CFG_WEP_KEY_LENGTH 7 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE 8 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE_ROW 4 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE_COL 1 +#define WNI_CFG_WEP_DEFAULT_KEY_1 8 +#define WNI_CFG_WEP_DEFAULT_KEY_2 9 +#define WNI_CFG_WEP_DEFAULT_KEY_3 10 +#define WNI_CFG_WEP_DEFAULT_KEY_4 11 +#define WNI_CFG_WEP_DEFAULT_KEYID 12 +#define WNI_CFG_EXCLUDE_UNENCRYPTED 13 +#define WNI_CFG_RTS_THRESHOLD 14 +#define WNI_CFG_SHORT_RETRY_LIMIT 15 +#define WNI_CFG_LONG_RETRY_LIMIT 16 +#define WNI_CFG_FRAGMENTATION_THRESHOLD 17 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME 18 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME 19 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME 20 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME 21 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT 22 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT 23 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT 24 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT 25 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT 26 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS 27 +#define WNI_CFG_PS_ENABLE_BCN_FILTER 28 +#define WNI_CFG_PS_ENABLE_HEART_BEAT 29 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT 31 +#define WNI_CFG_RF_SETTLING_TIME_CLK 32 +#define WNI_CFG_SUPPORTED_RATES_11B 33 +#define WNI_CFG_SUPPORTED_RATES_11A 34 +#define WNI_CFG_PHY_MODE 35 +#define WNI_CFG_DOT11_MODE 36 +#define WNI_CFG_OPERATIONAL_RATE_SET 37 +#define WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET 38 +#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET 39 +#define WNI_CFG_LISTEN_INTERVAL 40 +#define WNI_CFG_VALID_CHANNEL_LIST 41 +#define WNI_CFG_CURRENT_CHANNEL 42 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ 43 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ 44 +#define WNI_CFG_RATE_ADAPTATION_TYPE 45 +#define WNI_CFG_FIXED_RATE 46 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ 47 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ 48 +#define WNI_CFG_RETRYRATE_POLICY 49 +#define WNI_CFG_RETRYRATE_SECONDARY 50 +#define WNI_CFG_RETRYRATE_TERTIARY 51 +#define WNI_CFG_APSD_ENABLED 52 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE 53 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE 54 +#define WNI_CFG_AUTHENTICATION_TYPE 55 +#define WNI_CFG_CF_POLL_REQUEST 56 +#define WNI_CFG_PRIVACY_ENABLED 57 +#define WNI_CFG_SHORT_PREAMBLE 58 +#define WNI_CFG_SHORT_SLOT_TIME 59 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY 60 +#define WNI_CFG_QOS_ENABLED 61 +#define WNI_CFG_HCF_ENABLED 62 +#define WNI_CFG_RSN_ENABLED 63 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD 64 +#define WNI_CFG_MAX_NUM_PRE_AUTH 65 +#define WNI_CFG_PREAUTH_CLNUP_TIMEOUT 66 +#define WNI_CFG_RELEASE_AID_TIMEOUT 67 +#define WNI_CFG_HEART_BEAT_THRESHOLD 68 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT 69 +#define WNI_CFG_MANUFACTURER_OUI 70 +#define WNI_CFG_MANUFACTURER_NAME 71 +#define WNI_CFG_MODEL_NUMBER 72 +#define WNI_CFG_MODEL_NAME 73 +#define WNI_CFG_MANUFACTURER_PRODUCT_NAME 74 +#define WNI_CFG_MANUFACTURER_PRODUCT_VERSION 75 +#define WNI_CFG_11D_ENABLED 76 +#define WNI_CFG_MAX_TX_POWER_2_4 77 +#define WNI_CFG_MAX_TX_POWER_5 78 +#define WNI_CFG_NETWORK_DENSITY 79 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM 80 +#define WNI_CFG_CURRENT_TX_ANTENNA 81 +#define WNI_CFG_CURRENT_RX_ANTENNA 82 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL 83 +#define WNI_CFG_POWER_STATE_PER_CHAIN 84 +#define WNI_CFG_NEW_BSS_FOUND_IND 85 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED 86 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED 87 +#define WNI_CFG_AP_NODE_NAME 88 +#define WNI_CFG_COUNTRY_CODE 89 +#define WNI_CFG_11H_ENABLED 90 +#define WNI_CFG_WT_CNF_TIMEOUT 91 +#define WNI_CFG_KEEPALIVE_TIMEOUT 92 +#define WNI_CFG_PROXIMITY 93 +#define WNI_CFG_LOG_LEVEL 94 +#define WNI_CFG_OLBC_DETECT_TIMEOUT 95 +#define WNI_CFG_PROTECTION_ENABLED 96 +#define WNI_CFG_11G_PROTECTION_ALWAYS 97 +#define WNI_CFG_FORCE_POLICY_PROTECTION 98 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED 99 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED 100 +#define WNI_CFG_CAL_PERIOD 101 +#define WNI_CFG_STATS_PERIOD 102 +#define WNI_CFG_CAL_CONTROL 103 +#define WNI_CFG_11G_ONLY_POLICY 104 +#define WNI_CFG_PACKET_CLASSIFICATION 105 +#define WNI_CFG_WME_ENABLED 106 +#define WNI_CFG_ADDTS_RSP_TIMEOUT 107 +#define WNI_CFG_MAX_SP_LENGTH 108 +#define WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD 109 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS 110 +#define WNI_CFG_WSM_ENABLED 111 +#define WNI_CFG_PROP_CAPABILITY 112 +#define WNI_CFG_EDCA_PROFILE 113 +#define WNI_CFG_EDCA_ANI_ACBK_LOCAL 114 +#define WNI_CFG_EDCA_ANI_ACBE_LOCAL 115 +#define WNI_CFG_EDCA_ANI_ACVI_LOCAL 116 +#define WNI_CFG_EDCA_ANI_ACVO_LOCAL 117 +#define WNI_CFG_EDCA_ANI_ACBK 118 +#define WNI_CFG_EDCA_ANI_ACBE 119 +#define WNI_CFG_EDCA_ANI_ACVI 120 +#define WNI_CFG_EDCA_ANI_ACVO 121 +#define WNI_CFG_EDCA_WME_ACBK_LOCAL 122 +#define WNI_CFG_EDCA_WME_ACBE_LOCAL 123 +#define WNI_CFG_EDCA_WME_ACVI_LOCAL 124 +#define WNI_CFG_EDCA_WME_ACVO_LOCAL 125 +#define WNI_CFG_EDCA_WME_ACBK 126 +#define WNI_CFG_EDCA_WME_ACBE 127 +#define WNI_CFG_EDCA_WME_ACVI 128 +#define WNI_CFG_EDCA_WME_ACVO 129 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL 130 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL 131 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL 132 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL 133 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK 134 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE 135 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI 136 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO 137 +#define WNI_CFG_RDET_FLAG 138 +#define WNI_CFG_RADAR_CHANNEL_LIST 139 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT 140 +#define WNI_CFG_ADMIT_POLICY 141 +#define WNI_CFG_ADMIT_BWFACTOR 142 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE 143 +#define WNI_CFG_CHANNEL_BONDING_MODE 144 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE 145 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO 146 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE 147 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO 148 +#define WNI_CFG_TRIG_STA_BK_SCAN 149 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING 150 +#define WNI_CFG_SCAN_CONTROL_LIST 151 +#define WNI_CFG_MIMO_ENABLED 152 +#define WNI_CFG_BLOCK_ACK_ENABLED 153 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT 154 +#define WNI_CFG_HT_RX_STBC 155 +#define WNI_CFG_HT_CAP_INFO 156 +#define WNI_CFG_HT_AMPDU_PARAMS 157 +#define WNI_CFG_SUPPORTED_MCS_SET 158 +#define WNI_CFG_EXT_HT_CAP_INFO 159 +#define WNI_CFG_TX_BF_CAP 160 +#define WNI_CFG_AS_CAP 161 +#define WNI_CFG_HT_INFO_FIELD1 162 +#define WNI_CFG_HT_INFO_FIELD2 163 +#define WNI_CFG_HT_INFO_FIELD3 164 +#define WNI_CFG_BASIC_MCS_SET 165 +#define WNI_CFG_CURRENT_MCS_SET 166 +#define WNI_CFG_GREENFIELD_CAPABILITY 167 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH 168 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET 169 +#define WNI_CFG_VHT_LDPC_CODING_CAP 170 +#define WNI_CFG_VHT_SHORT_GI_80MHZ 171 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ 172 +#define WNI_CFG_VHT_TXSTBC 173 +#define WNI_CFG_VHT_RXSTBC 174 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP 175 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP 176 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED 177 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS 178 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP 179 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP 180 +#define WNI_CFG_VHT_TXOP_PS 181 +#define WNI_CFG_VHT_HTC_VHTC_CAP 182 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT 183 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP 184 +#define WNI_CFG_VHT_RX_ANT_PATTERN 185 +#define WNI_CFG_VHT_TX_ANT_PATTERN 186 +#define WNI_CFG_VHT_RX_MCS_MAP 187 +#define WNI_CFG_VHT_TX_MCS_MAP 188 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE 189 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE 190 +#define WNI_CFG_VHT_CHANNEL_WIDTH 191 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1 192 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2 193 +#define WNI_CFG_VHT_BASIC_MCS_SET 194 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT 195 +#define WNI_CFG_VHT_SS_UNDER_UTIL 196 +#define WNI_CFG_VHT_40MHZ_UTILIZATION 197 +#define WNI_CFG_VHT_80MHZ_UTILIZATION 198 +#define WNI_CFG_VHT_160MHZ_UTILIZATION 199 +#define WNI_CFG_MAX_AMSDU_LENGTH 200 +#define WNI_CFG_MPDU_DENSITY 201 +#define WNI_CFG_NUM_BUFF_ADVERT 202 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR 203 +#define WNI_CFG_SHORT_GI_20MHZ 204 +#define WNI_CFG_SHORT_GI_40MHZ 205 +#define WNI_CFG_RIFS_ENABLED 206 +#define WNI_CFG_MAX_PS_POLL 207 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE 208 +#define WNI_CFG_RSSI_FILTER_PERIOD 209 +#define WNI_CFG_MIN_RSSI_THRESHOLD 210 +#define WNI_CFG_NTH_BEACON_FILTER 211 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE 212 +#define WNI_CFG_SCAN_IN_POWERSAVE 213 +#define WNI_CFG_IGNORE_DTIM 214 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE 215 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE 216 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE 217 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE 218 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON 219 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD 220 +#define WNI_CFG_BA_TIMEOUT 221 +#define WNI_CFG_BA_THRESHOLD_HIGH 222 +#define WNI_CFG_MAX_BA_BUFFERS 223 +#define WNI_CFG_MAX_BA_SESSIONS 224 +#define WNI_CFG_BA_AUTO_SETUP 225 +#define WNI_CFG_ADDBA_REQ_DECLINE 226 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC 227 +#define WNI_CFG_BG_SCAN_CHANNEL_LIST 228 +#define WNI_CFG_MAX_MEDIUM_TIME 229 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU 230 +#define WNI_CFG_IBSS_AUTO_BSSID 231 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG 232 +#define WNI_CFG_PROBE_REQ_ADDNIE_DATA 233 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG 234 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1 235 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA2 236 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA3 237 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG 238 +#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA 239 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG 240 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA 241 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG 242 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA 243 +#define WNI_CFG_WPS_ENABLE 244 +#define WNI_CFG_WPS_STATE 245 +#define WNI_CFG_WPS_PROBE_REQ_FLAG 246 +#define WNI_CFG_WPS_VERSION 247 +#define WNI_CFG_WPS_REQUEST_TYPE 248 +#define WNI_CFG_WPS_CFG_METHOD 249 +#define WNI_CFG_WPS_UUID 250 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY 251 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI 252 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY 253 +#define WNI_CFG_WPS_ASSOCIATION_STATE 254 +#define WNI_CFG_WPS_CONFIGURATION_ERROR 255 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID 256 +#define WNI_CFG_WPS_ASSOC_METHOD 257 +#define WNI_CFG_LOW_GAIN_OVERRIDE 258 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE 259 +#define WNI_CFG_RPE_POLLING_THRESHOLD 260 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG 261 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG 262 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG 263 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG 264 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS 265 +#define WNI_CFG_SINGLE_TID_RC 266 +#define WNI_CFG_RRM_ENABLED 267 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX 268 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX 269 +#define WNI_CFG_TX_PWR_CTRL_ENABLE 270 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING 271 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK 272 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE 273 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT 274 +#define WNI_CFG_TELE_BCN_WAKEUP_EN 275 +#define WNI_CFG_TELE_BCN_TRANS_LI 276 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS 277 +#define WNI_CFG_TELE_BCN_MAX_LI 278 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS 279 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS 280 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD 281 +#define WNI_CFG_ASSOC_STA_LIMIT 282 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL 283 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL 284 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND 285 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD 286 +#define WNI_CFG_ENABLE_CLOSE_LOOP 287 +#define WNI_CFG_ENABLE_LTE_COEX 288 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT 289 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT 290 +#define WNI_CFG_ENABLE_MC_ADDR_LIST 291 +#define WNI_CFG_ENABLE_UC_FILTER 292 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION 293 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED 294 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP 295 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT 296 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK 297 +#define WNI_CFG_TDLS_BUF_STA_ENABLED 298 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME 299 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD 300 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES 301 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL 302 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN 303 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR 304 +#define WNI_CFG_ANTENNA_DIVESITY 305 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT 306 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY 307 +#define WNI_CFG_CURRENT_RSSI 308 +#define WNI_CFG_RTT3_ENABLE 309 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL 310 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE 312 +#define WNI_CFG_DFS_MASTER_ENABLED 313 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ 314 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED 315 + +/* + * String parameter lengths + */ + +#define WNI_CFG_STA_ID_LEN 6 +#define WNI_CFG_SSID_LEN 32 +#define WNI_CFG_WEP_DEFAULT_KEY_1_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_2_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_3_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_4_LEN 13 +#define WNI_CFG_SUPPORTED_RATES_11B_LEN 4 +#define WNI_CFG_SUPPORTED_RATES_11A_LEN 8 +#define WNI_CFG_OPERATIONAL_RATE_SET_LEN 12 +#define WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN 8 +#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN 4 +#define WNI_CFG_VALID_CHANNEL_LIST_LEN 100 +#define WNI_CFG_MANUFACTURER_OUI_LEN 3 +#define WNI_CFG_MANUFACTURER_NAME_LEN 65 +#define WNI_CFG_MODEL_NUMBER_LEN 33 +#define WNI_CFG_MODEL_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN 33 +#define WNI_CFG_MAX_TX_POWER_2_4_LEN 128 +#define WNI_CFG_MAX_TX_POWER_5_LEN 128 +#define WNI_CFG_AP_NODE_NAME_LEN 32 +#define WNI_CFG_COUNTRY_CODE_LEN 3 +#define WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBK_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LEN 20 +#define WNI_CFG_RADAR_CHANNEL_LIST_LEN 20 +#define WNI_CFG_SCAN_CONTROL_LIST_LEN 128 +#define WNI_CFG_SUPPORTED_MCS_SET_LEN 16 +#define WNI_CFG_BASIC_MCS_SET_LEN 16 +#define WNI_CFG_CURRENT_MCS_SET_LEN 16 +#define WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN 100 +#define WNI_CFG_PROBE_REQ_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN 255 +#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN 255 +#define WNI_CFG_WPS_UUID_LEN 16 + +/* + * Integer parameter min/max/default values + */ + +#define WNI_CFG_CF_POLLABLE_APMIN 0 +#define WNI_CFG_CF_POLLABLE_APMAX 1 +#define WNI_CFG_CF_POLLABLE_APDEF 0 + +#define WNI_CFG_CFP_PERIOD_STAMIN 0 +#define WNI_CFG_CFP_PERIOD_STAMAX 255 +#define WNI_CFG_CFP_PERIOD_STADEF 1 + +#define WNI_CFG_CFP_PERIOD_APMIN 0 +#define WNI_CFG_CFP_PERIOD_APMAX 255 +#define WNI_CFG_CFP_PERIOD_APDEF 1 + +#define WNI_CFG_CFP_MAX_DURATION_STAMIN 0 +#define WNI_CFG_CFP_MAX_DURATION_STAMAX 65535 +#define WNI_CFG_CFP_MAX_DURATION_STADEF 30000 + +#define WNI_CFG_CFP_MAX_DURATION_APMIN 0 +#define WNI_CFG_CFP_MAX_DURATION_APMAX 65535 +#define WNI_CFG_CFP_MAX_DURATION_APDEF 30000 + +#define WNI_CFG_BEACON_INTERVAL_STAMIN 0 +#define WNI_CFG_BEACON_INTERVAL_STAMAX 65535 +#define WNI_CFG_BEACON_INTERVAL_STADEF 100 + +#define WNI_CFG_BEACON_INTERVAL_APMIN 0 +#define WNI_CFG_BEACON_INTERVAL_APMAX 65535 +#define WNI_CFG_BEACON_INTERVAL_APDEF 100 + +#define WNI_CFG_DTIM_PERIOD_STAMIN 0 +#define WNI_CFG_DTIM_PERIOD_STAMAX 65535 +#define WNI_CFG_DTIM_PERIOD_STADEF 1 + +#define WNI_CFG_DTIM_PERIOD_APMIN 0 +#define WNI_CFG_DTIM_PERIOD_APMAX 65535 +#define WNI_CFG_DTIM_PERIOD_APDEF 1 + +#define WNI_CFG_WEP_KEY_LENGTH_STAMIN 5 +#define WNI_CFG_WEP_KEY_LENGTH_STAMAX 13 +#define WNI_CFG_WEP_KEY_LENGTH_STADEF 5 + +#define WNI_CFG_WEP_KEY_LENGTH_APMIN 5 +#define WNI_CFG_WEP_KEY_LENGTH_APMAX 13 +#define WNI_CFG_WEP_KEY_LENGTH_APDEF 5 + +#define WNI_CFG_WEP_KEY_LENGTH_5 5 +#define WNI_CFG_WEP_KEY_LENGTH_13 13 + +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMIN 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMAX 3 +#define WNI_CFG_WEP_DEFAULT_KEYID_STADEF 0 + +#define WNI_CFG_WEP_DEFAULT_KEYID_APMIN 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_APMAX 3 +#define WNI_CFG_WEP_DEFAULT_KEYID_APDEF 0 + +#define WNI_CFG_WEP_DEFAULT_KEYID_0 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_1 1 +#define WNI_CFG_WEP_DEFAULT_KEYID_2 2 +#define WNI_CFG_WEP_DEFAULT_KEYID_3 3 + +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN 0 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX 1 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF 0 + +#define WNI_CFG_EXCLUDE_UNENCRYPTED_APMIN 0 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_APMAX 1 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_APDEF 0 + +#define WNI_CFG_RTS_THRESHOLD_STAMIN 0 +#define WNI_CFG_RTS_THRESHOLD_STAMAX 1048576 +#define WNI_CFG_RTS_THRESHOLD_STADEF 2347 + +#define WNI_CFG_RTS_THRESHOLD_APMIN 0 +#define WNI_CFG_RTS_THRESHOLD_APMAX 1048576 +#define WNI_CFG_RTS_THRESHOLD_APDEF 2347 + +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_SHORT_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_SHORT_RETRY_LIMIT_APMIN 0 +#define WNI_CFG_SHORT_RETRY_LIMIT_APMAX 255 +#define WNI_CFG_SHORT_RETRY_LIMIT_APDEF 6 + +#define WNI_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_LONG_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_LONG_RETRY_LIMIT_APMIN 0 +#define WNI_CFG_LONG_RETRY_LIMIT_APMAX 255 +#define WNI_CFG_LONG_RETRY_LIMIT_APDEF 6 + +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +#define WNI_CFG_FRAGMENTATION_THRESHOLD_APMIN 256 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_APMAX 8000 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_APDEF 8000 + +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STADEF 20 + +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_APMIN 0 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_APMAX 65535 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_APDEF 20 + +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF 40 + +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_APMIN 0 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_APMAX 65535 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_APDEF 40 + +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF 60 + +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_APMIN 0 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_APMAX 65535 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_APDEF 60 + +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF 110 + +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_APMIN 0 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_APMAX 65535 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_APDEF 110 + +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF 3000 + +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_APMIN 0 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_APMAX 65535 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_APDEF 3000 + +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_APMIN 0 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_APMAX 65535 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_APDEF 1000 + +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_APMIN 0 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_APMAX 65535 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_APDEF 1000 + +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF 2000 + +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_APMIN 0 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_APMAX 65535 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_APDEF 3000 + +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_APMIN 0 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_APMAX 65535 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_APDEF 3000 + +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN 0 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX 65535 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STADEF 1000 + +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN 0 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX 1 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF 1 + +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 0 + +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN 0 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX 60000 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STADEF 1500 + +#define WNI_CFG_PHY_MODE_STAMIN 0 +#define WNI_CFG_PHY_MODE_STAMAX 3 +#define WNI_CFG_PHY_MODE_STADEF 0 + +#define WNI_CFG_PHY_MODE_APMIN 0 +#define WNI_CFG_PHY_MODE_APMAX 3 +#define WNI_CFG_PHY_MODE_APDEF 0 + +#define WNI_CFG_PHY_MODE_11A 0 +#define WNI_CFG_PHY_MODE_11B 1 +#define WNI_CFG_PHY_MODE_11G 2 +#define WNI_CFG_PHY_MODE_NONE 3 + +#define WNI_CFG_DOT11_MODE_STAMIN 0 +#define WNI_CFG_DOT11_MODE_STAMAX 11 +#define WNI_CFG_DOT11_MODE_STADEF 0 + +#define WNI_CFG_DOT11_MODE_APMIN 0 +#define WNI_CFG_DOT11_MODE_APMAX 11 +#define WNI_CFG_DOT11_MODE_APDEF 0 + +#define WNI_CFG_DOT11_MODE_ALL 0 +#define WNI_CFG_DOT11_MODE_11A 1 +#define WNI_CFG_DOT11_MODE_11B 2 +#define WNI_CFG_DOT11_MODE_11G 3 +#define WNI_CFG_DOT11_MODE_11N 4 +#define WNI_CFG_DOT11_MODE_POLARIS 5 +#define WNI_CFG_DOT11_MODE_TITAN 6 +#define WNI_CFG_DOT11_MODE_TAURUS 7 +#define WNI_CFG_DOT11_MODE_11G_ONLY 8 +#define WNI_CFG_DOT11_MODE_11N_ONLY 9 +#define WNI_CFG_DOT11_MODE_11AC 10 +#define WNI_CFG_DOT11_MODE_11AC_ONLY 11 + +#define WNI_CFG_LISTEN_INTERVAL_STAMIN 0 +#define WNI_CFG_LISTEN_INTERVAL_STAMAX 65535 +#define WNI_CFG_LISTEN_INTERVAL_STADEF 1 + +#define WNI_CFG_LISTEN_INTERVAL_APMIN 0 +#define WNI_CFG_LISTEN_INTERVAL_APMAX 65535 +#define WNI_CFG_LISTEN_INTERVAL_APDEF 1 + +#define WNI_CFG_CURRENT_CHANNEL_STAMIN 0 +#define WNI_CFG_CURRENT_CHANNEL_STAMAX 165 +#define WNI_CFG_CURRENT_CHANNEL_STADEF 1 + +#define WNI_CFG_CURRENT_CHANNEL_APMIN 0 +#define WNI_CFG_CURRENT_CHANNEL_APMAX 165 +#define WNI_CFG_CURRENT_CHANNEL_APDEF 1 + +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX 11 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF 5 + +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_APMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_APMAX 11 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_APDEF 5 + +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX 31 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF 1 + +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_APMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_APMAX 31 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_APDEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMIN 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMAX 2 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STADEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_APMIN 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_APMAX 2 +#define WNI_CFG_RATE_ADAPTATION_TYPE_APDEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_FIXED 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_AUTO 1 +#define WNI_CFG_RATE_ADAPTATION_TYPE_SNR_BASED 2 + +#define WNI_CFG_FIXED_RATE_STAMIN 0 +#define WNI_CFG_FIXED_RATE_STAMAX 44 +#define WNI_CFG_FIXED_RATE_STADEF 0 + +#define WNI_CFG_FIXED_RATE_APMIN 0 +#define WNI_CFG_FIXED_RATE_APMAX 44 +#define WNI_CFG_FIXED_RATE_APDEF 0 + +#define WNI_CFG_FIXED_RATE_AUTO 0 +#define WNI_CFG_FIXED_RATE_1MBPS 1 +#define WNI_CFG_FIXED_RATE_2MBPS 2 +#define WNI_CFG_FIXED_RATE_5_5MBPS 3 +#define WNI_CFG_FIXED_RATE_11MBPS 4 +#define WNI_CFG_FIXED_RATE_6MBPS 5 +#define WNI_CFG_FIXED_RATE_9MBPS 6 +#define WNI_CFG_FIXED_RATE_12MBPS 7 +#define WNI_CFG_FIXED_RATE_18MBPS 8 +#define WNI_CFG_FIXED_RATE_24MBPS 9 +#define WNI_CFG_FIXED_RATE_36MBPS 10 +#define WNI_CFG_FIXED_RATE_48MBPS 11 +#define WNI_CFG_FIXED_RATE_54MBPS 12 +#define WNI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define WNI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define WNI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define WNI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define WNI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define WNI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define WNI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define WNI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define WNI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define WNI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define WNI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define WNI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define WNI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define WNI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define WNI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO 29 +#define WNI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO 30 +#define WNI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO 31 +#define WNI_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO 32 +#define WNI_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO 33 +#define WNI_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO 34 +#define WNI_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO 35 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO 36 +#define WNI_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#define WNI_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#define WNI_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#define WNI_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#define WNI_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#define WNI_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#define WNI_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF 1 + +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_APMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_APMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_APDEF 1 + +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF 5 + +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_APMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_APMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_APDEF 5 + +#define WNI_CFG_RETRYRATE_POLICY_STAMIN 0 +#define WNI_CFG_RETRYRATE_POLICY_STAMAX 255 +#define WNI_CFG_RETRYRATE_POLICY_STADEF 4 + +#define WNI_CFG_RETRYRATE_POLICY_APMIN 0 +#define WNI_CFG_RETRYRATE_POLICY_APMAX 255 +#define WNI_CFG_RETRYRATE_POLICY_APDEF 4 + +#define WNI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define WNI_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define WNI_CFG_RETRYRATE_POLICY_RESERVED 2 +#define WNI_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define WNI_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define WNI_CFG_RETRYRATE_POLICY_MAX 5 + +#define WNI_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_SECONDARY_STADEF 0 + +#define WNI_CFG_RETRYRATE_SECONDARY_APMIN 0 +#define WNI_CFG_RETRYRATE_SECONDARY_APMAX 255 +#define WNI_CFG_RETRYRATE_SECONDARY_APDEF 0 + +#define WNI_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_TERTIARY_STADEF 0 + +#define WNI_CFG_RETRYRATE_TERTIARY_APMIN 0 +#define WNI_CFG_RETRYRATE_TERTIARY_APMAX 255 +#define WNI_CFG_RETRYRATE_TERTIARY_APDEF 0 + +#define WNI_CFG_APSD_ENABLED_STAMIN 0 +#define WNI_CFG_APSD_ENABLED_STAMAX 1 +#define WNI_CFG_APSD_ENABLED_STADEF 0 + +#define WNI_CFG_APSD_ENABLED_APMIN 0 +#define WNI_CFG_APSD_ENABLED_APMAX 1 +#define WNI_CFG_APSD_ENABLED_APDEF 0 + +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_APMIN 0 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_APMAX 1 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_APDEF 1 + +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_APMIN 0 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_APMAX 1 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_APDEF 1 + +#define WNI_CFG_AUTHENTICATION_TYPE_STAMIN 0 +#define WNI_CFG_AUTHENTICATION_TYPE_STAMAX 65535 +#define WNI_CFG_AUTHENTICATION_TYPE_STADEF 0 + +#define WNI_CFG_AUTHENTICATION_TYPE_APMIN 0 +#define WNI_CFG_AUTHENTICATION_TYPE_APMAX 65535 +#define WNI_CFG_AUTHENTICATION_TYPE_APDEF 0 + +#define WNI_CFG_CF_POLL_REQUEST_APMIN 0 +#define WNI_CFG_CF_POLL_REQUEST_APMAX 1 +#define WNI_CFG_CF_POLL_REQUEST_APDEF 0 + +#define WNI_CFG_PRIVACY_ENABLED_STAMIN 0 +#define WNI_CFG_PRIVACY_ENABLED_STAMAX 1 +#define WNI_CFG_PRIVACY_ENABLED_STADEF 0 + +#define WNI_CFG_PRIVACY_ENABLED_APMIN 0 +#define WNI_CFG_PRIVACY_ENABLED_APMAX 1 +#define WNI_CFG_PRIVACY_ENABLED_APDEF 0 + +#define WNI_CFG_SHORT_PREAMBLE_STAMIN 0 +#define WNI_CFG_SHORT_PREAMBLE_STAMAX 1 +#define WNI_CFG_SHORT_PREAMBLE_STADEF 1 + +#define WNI_CFG_SHORT_PREAMBLE_APMIN 0 +#define WNI_CFG_SHORT_PREAMBLE_APMAX 1 +#define WNI_CFG_SHORT_PREAMBLE_APDEF 1 + +#define WNI_CFG_SHORT_SLOT_TIME_STAMIN 0 +#define WNI_CFG_SHORT_SLOT_TIME_STAMAX 1 +#define WNI_CFG_SHORT_SLOT_TIME_STADEF 1 + +#define WNI_CFG_SHORT_SLOT_TIME_APMIN 0 +#define WNI_CFG_SHORT_SLOT_TIME_APMAX 1 +#define WNI_CFG_SHORT_SLOT_TIME_APDEF 0 + +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN 0 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX 1 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF 0 + +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_APMIN 0 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_APMAX 1 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_APDEF 0 + +#define WNI_CFG_QOS_ENABLED_STAMIN 0 +#define WNI_CFG_QOS_ENABLED_STAMAX 1 +#define WNI_CFG_QOS_ENABLED_STADEF 0 + +#define WNI_CFG_QOS_ENABLED_APMIN 0 +#define WNI_CFG_QOS_ENABLED_APMAX 1 +#define WNI_CFG_QOS_ENABLED_APDEF 0 + +#define WNI_CFG_HCF_ENABLED_STAMIN 0 +#define WNI_CFG_HCF_ENABLED_STAMAX 1 +#define WNI_CFG_HCF_ENABLED_STADEF 0 + +#define WNI_CFG_HCF_ENABLED_APMIN 0 +#define WNI_CFG_HCF_ENABLED_APMAX 1 +#define WNI_CFG_HCF_ENABLED_APDEF 0 + +#define WNI_CFG_RSN_ENABLED_STAMIN 0 +#define WNI_CFG_RSN_ENABLED_STAMAX 1 +#define WNI_CFG_RSN_ENABLED_STADEF 0 + +#define WNI_CFG_RSN_ENABLED_APMIN 0 +#define WNI_CFG_RSN_ENABLED_APMAX 1 +#define WNI_CFG_RSN_ENABLED_APDEF 0 + +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMIN 0 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMAX 180000 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STADEF 5000 + +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_APMIN 0 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_APMAX 18000 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_APDEF 5000 + +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMIN 0 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMAX 256 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STADEF 64 + +#define WNI_CFG_MAX_NUM_PRE_AUTH_APMIN 0 +#define WNI_CFG_MAX_NUM_PRE_AUTH_APMAX 256 +#define WNI_CFG_MAX_NUM_PRE_AUTH_APDEF 64 + +#define WNI_CFG_PREAUTH_CLNUP_TIMEOUT_APMIN 0 +#define WNI_CFG_PREAUTH_CLNUP_TIMEOUT_APMAX 120000 +#define WNI_CFG_PREAUTH_CLNUP_TIMEOUT_APDEF 30000 + +#define WNI_CFG_RELEASE_AID_TIMEOUT_APMIN 0 +#define WNI_CFG_RELEASE_AID_TIMEOUT_APMAX 100000 +#define WNI_CFG_RELEASE_AID_TIMEOUT_APDEF 1000 + +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN 0 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX 65535 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STADEF 40 + +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN 10 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMAX 10000 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STADEF 40 + +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_APMIN 10 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_APMAX 10000 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_APDEF 40 + +#define WNI_CFG_11D_ENABLED_STAMIN 0 +#define WNI_CFG_11D_ENABLED_STAMAX 1 +#define WNI_CFG_11D_ENABLED_STADEF 1 + +#define WNI_CFG_11D_ENABLED_APMIN 0 +#define WNI_CFG_11D_ENABLED_APMAX 1 +#define WNI_CFG_11D_ENABLED_APDEF 0 + +#define WNI_CFG_NETWORK_DENSITY_STAMIN 0 +#define WNI_CFG_NETWORK_DENSITY_STAMAX 3 +#define WNI_CFG_NETWORK_DENSITY_STADEF 3 + +#define WNI_CFG_NETWORK_DENSITY_APMIN 0 +#define WNI_CFG_NETWORK_DENSITY_APMAX 3 +#define WNI_CFG_NETWORK_DENSITY_APDEF 0 + +#define WNI_CFG_NETWORK_DENSITY_LOW 0 +#define WNI_CFG_NETWORK_DENSITY_MEDIUM 1 +#define WNI_CFG_NETWORK_DENSITY_HIGH 2 +#define WNI_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMIN 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMAX 2 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STADEF 2 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_APMIN 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_APMAX 2 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_APDEF 2 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CARRIER 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CORRELATION 2 + +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +#define WNI_CFG_CURRENT_TX_ANTENNA_APMIN 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_APMAX 2 +#define WNI_CFG_CURRENT_TX_ANTENNA_APDEF 2 + +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define WNI_CFG_CURRENT_RX_ANTENNA_STADEF 2 + +#define WNI_CFG_CURRENT_RX_ANTENNA_APMIN 1 +#define WNI_CFG_CURRENT_RX_ANTENNA_APMAX 3 +#define WNI_CFG_CURRENT_RX_ANTENNA_APDEF 3 + +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN 0 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX 128 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF 27 + +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_APMIN 0 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_APMAX 128 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_APDEF 27 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STADEF 785 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_APMIN 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_APMAX 65535 +#define WNI_CFG_POWER_STATE_PER_CHAIN_APDEF 785 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define WNI_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define WNI_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define WNI_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMIN 0 +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMAX 1 +#define WNI_CFG_NEW_BSS_FOUND_IND_STADEF 0 + +#define WNI_CFG_NEW_BSS_FOUND_IND_APMIN 0 +#define WNI_CFG_NEW_BSS_FOUND_IND_APMAX 1 +#define WNI_CFG_NEW_BSS_FOUND_IND_APDEF 0 + +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STADEF 0 + +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_APMIN 0 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_APMAX 1 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_APDEF 0 + +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STADEF 0 + +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_APMIN 0 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_APMAX 1 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_APDEF 0 + +#define WNI_CFG_11H_ENABLED_STAMIN 0 +#define WNI_CFG_11H_ENABLED_STAMAX 1 +#define WNI_CFG_11H_ENABLED_STADEF 1 + +#define WNI_CFG_11H_ENABLED_APMIN 0 +#define WNI_CFG_11H_ENABLED_APMAX 1 +#define WNI_CFG_11H_ENABLED_APDEF 1 + +#define WNI_CFG_WT_CNF_TIMEOUT_STAMIN 10 +#define WNI_CFG_WT_CNF_TIMEOUT_STAMAX 3000 +#define WNI_CFG_WT_CNF_TIMEOUT_STADEF 1000 + +#define WNI_CFG_WT_CNF_TIMEOUT_APMIN 10 +#define WNI_CFG_WT_CNF_TIMEOUT_APMAX 3000 +#define WNI_CFG_WT_CNF_TIMEOUT_APDEF 1000 + +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMIN 0 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMAX 3600000 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STADEF 0 + +#define WNI_CFG_KEEPALIVE_TIMEOUT_APMIN 0 +#define WNI_CFG_KEEPALIVE_TIMEOUT_APMAX 3600000 +#define WNI_CFG_KEEPALIVE_TIMEOUT_APDEF 3000 + +#define WNI_CFG_PROXIMITY_STAMIN 0 +#define WNI_CFG_PROXIMITY_STAMAX 1 +#define WNI_CFG_PROXIMITY_STADEF 0 + +#define WNI_CFG_PROXIMITY_APMIN 0 +#define WNI_CFG_PROXIMITY_APMAX 1 +#define WNI_CFG_PROXIMITY_APDEF 0 + +#define WNI_CFG_PROXIMITY_OFF 0 +#define WNI_CFG_PROXIMITY_ON 1 + +#define WNI_CFG_LOG_LEVEL_STAMIN 0 +#define WNI_CFG_LOG_LEVEL_STAMAX 7 +#define WNI_CFG_LOG_LEVEL_STADEF 4 + +#define WNI_CFG_LOG_LEVEL_APMIN 0 +#define WNI_CFG_LOG_LEVEL_APMAX 7 +#define WNI_CFG_LOG_LEVEL_APDEF 4 + +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMIN 1000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMAX 30000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STADEF 10000 + +#define WNI_CFG_OLBC_DETECT_TIMEOUT_APMIN 1000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_APMAX 30000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_APDEF 10000 + +#define WNI_CFG_PROTECTION_ENABLED_STAMIN 0 +#define WNI_CFG_PROTECTION_ENABLED_STAMAX 65535 +#define WNI_CFG_PROTECTION_ENABLED_STADEF 65535 + +#define WNI_CFG_PROTECTION_ENABLED_APMIN 0 +#define WNI_CFG_PROTECTION_ENABLED_APMAX 65535 +#define WNI_CFG_PROTECTION_ENABLED_APDEF 65535 + +#define WNI_CFG_PROTECTION_ENABLED_FROM_llA 0 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llB 1 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llG 2 +#define WNI_CFG_PROTECTION_ENABLED_HT_20 3 +#define WNI_CFG_PROTECTION_ENABLED_NON_GF 4 +#define WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP 5 +#define WNI_CFG_PROTECTION_ENABLED_RIFS 6 +#define WNI_CFG_PROTECTION_ENABLED_OBSS 7 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llA 8 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llB 9 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llG 10 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_HT20 11 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_NON_GF 12 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_LSIG_TXOP 13 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_RIFS 14 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_OBSS 15 + +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMIN 0 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMAX 1 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STADEF 0 + +#define WNI_CFG_11G_PROTECTION_ALWAYS_APMIN 0 +#define WNI_CFG_11G_PROTECTION_ALWAYS_APMAX 1 +#define WNI_CFG_11G_PROTECTION_ALWAYS_APDEF 0 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STADEF 5 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_APMIN 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_APMAX 5 +#define WNI_CFG_FORCE_POLICY_PROTECTION_APDEF 5 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define WNI_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define WNI_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STADEF 0 + +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_APMIN 0 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_APMAX 1 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_APDEF 0 + +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STADEF 1 + +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_APMIN 0 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_APMAX 1 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_APDEF 1 + +#define WNI_CFG_CAL_PERIOD_STAMIN 2 +#define WNI_CFG_CAL_PERIOD_STAMAX 10 +#define WNI_CFG_CAL_PERIOD_STADEF 5 + +#define WNI_CFG_CAL_PERIOD_APMIN 2 +#define WNI_CFG_CAL_PERIOD_APMAX 10 +#define WNI_CFG_CAL_PERIOD_APDEF 5 + +#define WNI_CFG_STATS_PERIOD_STAMIN 1 +#define WNI_CFG_STATS_PERIOD_STAMAX 10 +#define WNI_CFG_STATS_PERIOD_STADEF 10 + +#define WNI_CFG_STATS_PERIOD_APMIN 1 +#define WNI_CFG_STATS_PERIOD_APMAX 10 +#define WNI_CFG_STATS_PERIOD_APDEF 10 + +#define WNI_CFG_CAL_CONTROL_STAMIN 0 +#define WNI_CFG_CAL_CONTROL_STAMAX 1 +#define WNI_CFG_CAL_CONTROL_STADEF 0 + +#define WNI_CFG_CAL_CONTROL_APMIN 0 +#define WNI_CFG_CAL_CONTROL_APMAX 1 +#define WNI_CFG_CAL_CONTROL_APDEF 0 + +#define WNI_CFG_CAL_CONTROL_CAL_ON 0 +#define WNI_CFG_CAL_CONTROL_CAL_OFF 1 + +#define WNI_CFG_11G_ONLY_POLICY_STAMIN 0 +#define WNI_CFG_11G_ONLY_POLICY_STAMAX 1 +#define WNI_CFG_11G_ONLY_POLICY_STADEF 0 + +#define WNI_CFG_11G_ONLY_POLICY_APMIN 0 +#define WNI_CFG_11G_ONLY_POLICY_APMAX 1 +#define WNI_CFG_11G_ONLY_POLICY_APDEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_STAMIN 0 +#define WNI_CFG_PACKET_CLASSIFICATION_STAMAX 3 +#define WNI_CFG_PACKET_CLASSIFICATION_STADEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_APMIN 0 +#define WNI_CFG_PACKET_CLASSIFICATION_APMAX 3 +#define WNI_CFG_PACKET_CLASSIFICATION_APDEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_DISABLED 0 +#define WNI_CFG_PACKET_CLASSIFICATION_DSCP 1 +#define WNI_CFG_PACKET_CLASSIFICATION_8021P 2 +#define WNI_CFG_PACKET_CLASSIFICATION_ALL 3 + +#define WNI_CFG_WME_ENABLED_STAMIN 0 +#define WNI_CFG_WME_ENABLED_STAMAX 1 +#define WNI_CFG_WME_ENABLED_STADEF 1 + +#define WNI_CFG_WME_ENABLED_APMIN 0 +#define WNI_CFG_WME_ENABLED_APMAX 1 +#define WNI_CFG_WME_ENABLED_APDEF 1 + +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_ADDTS_RSP_TIMEOUT_APMIN 0 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_APMAX 65535 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_APDEF 1000 + +#define WNI_CFG_MAX_SP_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_SP_LENGTH_STAMAX 3 +#define WNI_CFG_MAX_SP_LENGTH_STADEF 0 + +#define WNI_CFG_MAX_SP_LENGTH_APMIN 0 +#define WNI_CFG_MAX_SP_LENGTH_APMAX 3 +#define WNI_CFG_MAX_SP_LENGTH_APDEF 0 + +#define WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD_APMIN 0 +#define WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD_APMAX 32 +#define WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD_APDEF 0 + +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMIN 0 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMAX 1 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STADEF 0 + +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_APMIN 0 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_APMAX 1 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_APDEF 0 + +#define WNI_CFG_WSM_ENABLED_STAMIN 0 +#define WNI_CFG_WSM_ENABLED_STAMAX 1 +#define WNI_CFG_WSM_ENABLED_STADEF 0 + +#define WNI_CFG_WSM_ENABLED_APMIN 0 +#define WNI_CFG_WSM_ENABLED_APMAX 1 +#define WNI_CFG_WSM_ENABLED_APDEF 0 + +#define WNI_CFG_PROP_CAPABILITY_STAMIN 0 +#define WNI_CFG_PROP_CAPABILITY_STAMAX 65535 +#define WNI_CFG_PROP_CAPABILITY_STADEF 57535 + +#define WNI_CFG_PROP_CAPABILITY_APMIN 0 +#define WNI_CFG_PROP_CAPABILITY_APMAX 65535 +#define WNI_CFG_PROP_CAPABILITY_APDEF 49321 + +#define WNI_CFG_PROP_CAPABILITY_HCF 0 +#define WNI_CFG_PROP_CAPABILITY_11EQOS 1 +#define WNI_CFG_PROP_CAPABILITY_WME 2 +#define WNI_CFG_PROP_CAPABILITY_WSM 3 +#define WNI_CFG_PROP_CAPABILITY_EXTRATES 4 +#define WNI_CFG_PROP_CAPABILITY_EXTRATE_STOP 5 +#define WNI_CFG_PROP_CAPABILITY_TITAN 6 +#define WNI_CFG_PROP_CAPABILITY_TAURUS 7 +#define WNI_CFG_PROP_CAPABILITY_EDCAPARAMS 13 +#define WNI_CFG_PROP_CAPABILITY_LOADINFO 14 +#define WNI_CFG_PROP_CAPABILITY_VERSION 15 +#define WNI_CFG_PROP_CAPABILITY_MAXBITOFFSET 15 + +#define WNI_CFG_EDCA_PROFILE_STAMIN 0 +#define WNI_CFG_EDCA_PROFILE_STAMAX 255 +#define WNI_CFG_EDCA_PROFILE_STADEF 1 + +#define WNI_CFG_EDCA_PROFILE_APMIN 0 +#define WNI_CFG_EDCA_PROFILE_APMAX 255 +#define WNI_CFG_EDCA_PROFILE_APDEF 1 + +#define WNI_CFG_EDCA_PROFILE_ANI 0 +#define WNI_CFG_EDCA_PROFILE_WMM 1 +#define WNI_CFG_EDCA_PROFILE_TIT_DEMO 2 +#define WNI_CFG_EDCA_PROFILE_MAX 3 +#define WNI_CFG_EDCA_PROFILE_ACM_IDX 0 +#define WNI_CFG_EDCA_PROFILE_AIFSN_IDX 1 +#define WNI_CFG_EDCA_PROFILE_CWMINA_IDX 2 +#define WNI_CFG_EDCA_PROFILE_CWMAXA_IDX 4 +#define WNI_CFG_EDCA_PROFILE_TXOPA_IDX 6 +#define WNI_CFG_EDCA_PROFILE_CWMINB_IDX 7 +#define WNI_CFG_EDCA_PROFILE_CWMAXB_IDX 9 +#define WNI_CFG_EDCA_PROFILE_TXOPB_IDX 11 +#define WNI_CFG_EDCA_PROFILE_CWMING_IDX 12 +#define WNI_CFG_EDCA_PROFILE_CWMAXG_IDX 14 +#define WNI_CFG_EDCA_PROFILE_TXOPG_IDX 16 + +#define WNI_CFG_RDET_FLAG_STAMIN 0 +#define WNI_CFG_RDET_FLAG_STAMAX 1 +#define WNI_CFG_RDET_FLAG_STADEF 0 + +#define WNI_CFG_RDET_FLAG_APMIN 0 +#define WNI_CFG_RDET_FLAG_APMAX 1 +#define WNI_CFG_RDET_FLAG_APDEF 0 + +#define WNI_CFG_RDET_FLAG_ENABLE 1 +#define WNI_CFG_RDET_FLAG_DISABLE 0 + +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN 0 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX 255 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF 0 + +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_APMIN 0 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_APMAX 255 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_APDEF 0 + +#define WNI_CFG_ADMIT_POLICY_STAMIN 0 +#define WNI_CFG_ADMIT_POLICY_STAMAX 2 +#define WNI_CFG_ADMIT_POLICY_STADEF 0 + +#define WNI_CFG_ADMIT_POLICY_APMIN 0 +#define WNI_CFG_ADMIT_POLICY_APMAX 2 +#define WNI_CFG_ADMIT_POLICY_APDEF 0 + +#define WNI_CFG_ADMIT_POLICY_ADMIT_ALL 0 +#define WNI_CFG_ADMIT_POLICY_REJECT_ALL 1 +#define WNI_CFG_ADMIT_POLICY_BW_FACTOR 2 + +#define WNI_CFG_ADMIT_BWFACTOR_STAMIN 0 +#define WNI_CFG_ADMIT_BWFACTOR_STAMAX 100 +#define WNI_CFG_ADMIT_BWFACTOR_STADEF 20 + +#define WNI_CFG_ADMIT_BWFACTOR_APMIN 0 +#define WNI_CFG_ADMIT_BWFACTOR_APMAX 100 +#define WNI_CFG_ADMIT_BWFACTOR_APDEF 20 + +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMIN 0 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMAX 256 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STADEF 60 + +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_APMIN 0 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_APMAX 256 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_APDEF 60 + +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMIN 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMAX 10 +#define WNI_CFG_CHANNEL_BONDING_MODE_STADEF 0 + +#define WNI_CFG_CHANNEL_BONDING_MODE_APMIN 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_APMAX 10 +#define WNI_CFG_CHANNEL_BONDING_MODE_APDEF 0 + +#define WNI_CFG_CHANNEL_BONDING_MODE_DISABLE 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_ENABLE 1 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_BSS 2 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_ALL 3 +#define WNI_CFG_CHANNEL_BONDING_MODE_INTELLIGENT 4 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMIN 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMAX 10 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STADEF 0 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_APMIN 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_APMAX 10 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_APDEF 0 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_NONE 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_LOWER 1 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_HIGHER 2 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_CENTERED 3 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_CENTERED_40MHZ_CENTERED 4 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_CENTERED 5 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_LOW 6 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_LOW 7 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_HIGH 8 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_HIGH 9 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 2 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_APMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_APMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_APDEF 2 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 4 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_APMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_APMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_APDEF 4 + +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 6 + +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_APMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_APMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_APDEF 6 + +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMIN 0 +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMAX 1 +#define WNI_CFG_TRIG_STA_BK_SCAN_STADEF 0 + +#define WNI_CFG_TRIG_STA_BK_SCAN_APMIN 0 +#define WNI_CFG_TRIG_STA_BK_SCAN_APMAX 1 +#define WNI_CFG_TRIG_STA_BK_SCAN_APDEF 1 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMIN 0 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMAX 255 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STADEF 255 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_APMIN 0 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_APMAX 255 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_APDEF 1 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_UNUSED 255 + +#define WNI_CFG_MIMO_ENABLED_STAMIN 0 +#define WNI_CFG_MIMO_ENABLED_STAMAX 1 +#define WNI_CFG_MIMO_ENABLED_STADEF 1 + +#define WNI_CFG_MIMO_ENABLED_APMIN 0 +#define WNI_CFG_MIMO_ENABLED_APMAX 1 +#define WNI_CFG_MIMO_ENABLED_APDEF 1 + +#define WNI_CFG_MIMO_ENABLED_ENABLE 1 +#define WNI_CFG_MIMO_ENABLED_DISABLE 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMIN 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMAX 3 +#define WNI_CFG_BLOCK_ACK_ENABLED_STADEF 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_APMIN 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_APMAX 3 +#define WNI_CFG_BLOCK_ACK_ENABLED_APDEF 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_DELAYED 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE 1 + +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STADEF 1000 + +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_APMIN 0 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_APMAX 65535 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_APDEF 1000 + +#define WNI_CFG_HT_RX_STBC_STAMIN 0 +#define WNI_CFG_HT_RX_STBC_STAMAX 3 +#define WNI_CFG_HT_RX_STBC_STADEF 1 + +#define WNI_CFG_HT_RX_STBC_APMIN 0 +#define WNI_CFG_HT_RX_STBC_APMAX 3 +#define WNI_CFG_HT_RX_STBC_APDEF 1 + +#define WNI_CFG_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_HT_CAP_INFO_STADEF 364 + +#define WNI_CFG_HT_CAP_INFO_APMIN 0 +#define WNI_CFG_HT_CAP_INFO_APMAX 65535 +#define WNI_CFG_HT_CAP_INFO_APDEF 4206 + +#define WNI_CFG_HT_CAP_INFO_ADVANCE_CODING 0 +#define WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET 1 +#define WNI_CFG_HT_CAP_INFO_SM_POWER_SAVE 2 +#define WNI_CFG_HT_CAP_INFO_GREEN_FIELD 4 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ 5 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ 6 +#define WNI_CFG_HT_CAP_INFO_TX_STBC 7 +#define WNI_CFG_HT_CAP_INFO_RX_STBC 8 +#define WNI_CFG_HT_CAP_INFO_DELAYED_BA 10 +#define WNI_CFG_HT_CAP_INFO_MAX_AMSDU_SIZE 11 +#define WNI_CFG_HT_CAP_INFO_DSSS_CCK_MODE_40MHZ 12 +#define WNI_CFG_HT_CAP_INFO_PSMP 13 +#define WNI_CFG_HT_CAP_INFO_STBC_CONTROL_FRAME 14 +#define WNI_CFG_HT_CAP_INFO_LSIG_TXOP_PROTECTION 15 + +#define WNI_CFG_HT_AMPDU_PARAMS_STAMIN 0 +#define WNI_CFG_HT_AMPDU_PARAMS_STAMAX 255 +#define WNI_CFG_HT_AMPDU_PARAMS_STADEF 0 + +#define WNI_CFG_HT_AMPDU_PARAMS_APMIN 0 +#define WNI_CFG_HT_AMPDU_PARAMS_APMAX 255 +#define WNI_CFG_HT_AMPDU_PARAMS_APDEF 2 + +#define WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR 0 +#define WNI_CFG_HT_AMPDU_PARAMS_MPDU_DENSITY 2 +#define WNI_CFG_HT_AMPDU_PARAMS_RESERVED 5 + +#define WNI_CFG_EXT_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_EXT_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_EXT_HT_CAP_INFO_STADEF 1024 + +#define WNI_CFG_EXT_HT_CAP_INFO_APMIN 0 +#define WNI_CFG_EXT_HT_CAP_INFO_APMAX 65535 +#define WNI_CFG_EXT_HT_CAP_INFO_APDEF 1024 + +#define WNI_CFG_EXT_HT_CAP_INFO_PCO 0 +#define WNI_CFG_EXT_HT_CAP_INFO_TRANSITION_TIME 1 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED1 3 +#define WNI_CFG_EXT_HT_CAP_INFO_MCS_FEEDBACK 8 +#define WNI_CFG_EXT_HT_CAP_INFO_HTC_SUPPORT 10 +#define WNI_CFG_EXT_HT_CAP_INFO_RD_RESPONDER 11 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED2 12 + +#define WNI_CFG_TX_BF_CAP_STAMIN 0 +#define WNI_CFG_TX_BF_CAP_STAMAX 4294967295 +#define WNI_CFG_TX_BF_CAP_STADEF 0 + +#define WNI_CFG_TX_BF_CAP_APMIN 0 +#define WNI_CFG_TX_BF_CAP_APMAX 4294967295 +#define WNI_CFG_TX_BF_CAP_APDEF 0 + +#define WNI_CFG_AS_CAP_STAMIN 0 +#define WNI_CFG_AS_CAP_STAMAX 255 +#define WNI_CFG_AS_CAP_STADEF 0 + +#define WNI_CFG_AS_CAP_APMIN 0 +#define WNI_CFG_AS_CAP_APMAX 255 +#define WNI_CFG_AS_CAP_APDEF 0 + +#define WNI_CFG_AS_CAP_ANTENNA_SELECTION 0 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK_TX 1 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK_TX 2 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK 3 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK 4 +#define WNI_CFG_AS_CAP_RX_AS 5 +#define WNI_CFG_AS_CAP_TX_SOUNDING_PPDUS 6 +#define WNI_CFG_AS_CAP_RESERVED 7 + +#define WNI_CFG_HT_INFO_FIELD1_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD1_STAMAX 255 +#define WNI_CFG_HT_INFO_FIELD1_STADEF 15 + +#define WNI_CFG_HT_INFO_FIELD1_APMIN 0 +#define WNI_CFG_HT_INFO_FIELD1_APMAX 255 +#define WNI_CFG_HT_INFO_FIELD1_APDEF 15 + +#define WNI_CFG_HT_INFO_FIELD1_SECONDARY_CHANNEL_OFFSET 0 +#define WNI_CFG_HT_INFO_FIELD1_RECOMMENDED_CHANNEL_WIDTH 2 +#define WNI_CFG_HT_INFO_FIELD1_RIFS_MODE 3 +#define WNI_CFG_HT_INFO_FIELD1_PSMP_ACCESS_ONLY 4 +#define WNI_CFG_HT_INFO_FIELD1_SERVICE_INTERVAL_GRANULARITY 5 + +#define WNI_CFG_HT_INFO_FIELD2_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD2_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD2_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD2_APMIN 0 +#define WNI_CFG_HT_INFO_FIELD2_APMAX 65535 +#define WNI_CFG_HT_INFO_FIELD2_APDEF 0 + +#define WNI_CFG_HT_INFO_FIELD2_OP_MODE 0 +#define WNI_CFG_HT_INFO_FIELD2_NON_GF_DEVICES_PRESENT 2 +#define WNI_CFG_HT_INFO_FIELD2_RESERVED 3 + +#define WNI_CFG_HT_INFO_FIELD3_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD3_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD3_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD3_APMIN 0 +#define WNI_CFG_HT_INFO_FIELD3_APMAX 65535 +#define WNI_CFG_HT_INFO_FIELD3_APDEF 0 + +#define WNI_CFG_HT_INFO_FIELD3_BASIC_STBC_MCS 0 +#define WNI_CFG_HT_INFO_FIELD3_DUAL_STBC_PROTECTION 7 +#define WNI_CFG_HT_INFO_FIELD3_SECONDARY_BEACON 8 +#define WNI_CFG_HT_INFO_FIELD3_LSIG_TXOP_PROTECTION_FULL_SUPPORT 9 +#define WNI_CFG_HT_INFO_FIELD3_PCO_ACTIVE 10 +#define WNI_CFG_HT_INFO_FIELD3_PCO_PHASE 11 +#define WNI_CFG_HT_INFO_FIELD3_RESERVED 12 + +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMIN 0 +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMAX 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_STADEF 0 + +#define WNI_CFG_GREENFIELD_CAPABILITY_APMIN 0 +#define WNI_CFG_GREENFIELD_CAPABILITY_APMAX 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_APDEF 0 + +#define WNI_CFG_GREENFIELD_CAPABILITY_ENABLE 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_DISABLE 0 + +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMIN 0 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMAX 2 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STADEF 0 + +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_APMIN 0 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_APMAX 2 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_APDEF 0 + +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMIN 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMAX 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STADEF 0 + +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_APMIN 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_APMAX 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_APDEF 0 + +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMIN 0 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMAX 1 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STADEF 0 + +#define WNI_CFG_VHT_LDPC_CODING_CAP_APMIN 0 +#define WNI_CFG_VHT_LDPC_CODING_CAP_APMAX 1 +#define WNI_CFG_VHT_LDPC_CODING_CAP_APDEF 0 + +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STADEF 1 + +#define WNI_CFG_VHT_SHORT_GI_80MHZ_APMIN 0 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_APMAX 1 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_APDEF 1 + +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STADEF 0 + +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_APMIN 0 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_APMAX 1 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_APDEF 0 + +#define WNI_CFG_VHT_TXSTBC_STAMIN 0 +#define WNI_CFG_VHT_TXSTBC_STAMAX 1 +#define WNI_CFG_VHT_TXSTBC_STADEF 0 + +#define WNI_CFG_VHT_TXSTBC_APMIN 0 +#define WNI_CFG_VHT_TXSTBC_APMAX 1 +#define WNI_CFG_VHT_TXSTBC_APDEF 0 + +#define WNI_CFG_VHT_RXSTBC_STAMIN 0 +#define WNI_CFG_VHT_RXSTBC_STAMAX 1 +#define WNI_CFG_VHT_RXSTBC_STADEF 1 + +#define WNI_CFG_VHT_RXSTBC_APMIN 0 +#define WNI_CFG_VHT_RXSTBC_APMAX 1 +#define WNI_CFG_VHT_RXSTBC_APDEF 1 + +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_APMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_APMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_APDEF 0 + +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF 0 + +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_APMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_APMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_APDEF 0 + +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN 0 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX 4 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STADEF 0 + +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_APMIN 0 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_APMAX 4 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_APDEF 0 + +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMIN 0 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMAX 3 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STADEF 0 + +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_APMIN 0 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_APMAX 3 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_APDEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_APMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_APMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_APDEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_APMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_APMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_APDEF 0 + +#define WNI_CFG_VHT_TXOP_PS_STAMIN 0 +#define WNI_CFG_VHT_TXOP_PS_STAMAX 1 +#define WNI_CFG_VHT_TXOP_PS_STADEF 0 + +#define WNI_CFG_VHT_TXOP_PS_APMIN 0 +#define WNI_CFG_VHT_TXOP_PS_APMAX 1 +#define WNI_CFG_VHT_TXOP_PS_APDEF 0 + +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMIN 0 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMAX 1 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STADEF 0 + +#define WNI_CFG_VHT_HTC_VHTC_CAP_APMIN 0 +#define WNI_CFG_VHT_HTC_VHTC_CAP_APMAX 1 +#define WNI_CFG_VHT_HTC_VHTC_CAP_APDEF 0 + +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMIN 0 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMAX 7 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STADEF 3 + +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_APMIN 0 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_APMAX 7 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_APDEF 3 + +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMIN 0 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMAX 3 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STADEF 0 + +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_APMIN 0 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_APMAX 3 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_APDEF 0 + +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_RX_ANT_PATTERN_APMIN 0 +#define WNI_CFG_VHT_RX_ANT_PATTERN_APMAX 1 +#define WNI_CFG_VHT_RX_ANT_PATTERN_APDEF 1 + +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_TX_ANT_PATTERN_APMIN 0 +#define WNI_CFG_VHT_TX_ANT_PATTERN_APMAX 1 +#define WNI_CFG_VHT_TX_ANT_PATTERN_APDEF 1 + +#define WNI_CFG_VHT_RX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_RX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_RX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_RX_MCS_MAP_APMIN 0 +#define WNI_CFG_VHT_RX_MCS_MAP_APMAX 65535 +#define WNI_CFG_VHT_RX_MCS_MAP_APDEF 65534 + +#define WNI_CFG_VHT_TX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_TX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_TX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_TX_MCS_MAP_APMIN 0 +#define WNI_CFG_VHT_TX_MCS_MAP_APMAX 65535 +#define WNI_CFG_VHT_TX_MCS_MAP_APDEF 65534 + +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 780 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 780 + +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_APMIN 0 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_APMAX 780 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_APDEF 780 + +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 780 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 780 + +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_APMIN 0 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_APMAX 780 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_APDEF 780 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMAX 3 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_APMIN 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_APMAX 3 +#define WNI_CFG_VHT_CHANNEL_WIDTH_APDEF 0 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ 1 +#define WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ 2 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ 3 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMAX 256 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_APMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_APMAX 256 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_APDEF 0 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMAX 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_APMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_APMAX 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_APDEF 0 + +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMIN 0 +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMAX 65535 +#define WNI_CFG_VHT_BASIC_MCS_SET_STADEF 65534 + +#define WNI_CFG_VHT_BASIC_MCS_SET_APMIN 0 +#define WNI_CFG_VHT_BASIC_MCS_SET_APMAX 65535 +#define WNI_CFG_VHT_BASIC_MCS_SET_APDEF 65534 + +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMIN 0 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMAX 4 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STADEF 0 + +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_APMIN 0 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_APMAX 4 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_APDEF 0 + +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMIN 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMAX 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STADEF 0 + +#define WNI_CFG_VHT_SS_UNDER_UTIL_APMIN 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_APMAX 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_APDEF 0 + +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_40MHZ_UTILIZATION_APMIN 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_APMAX 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_APDEF 0 + +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_80MHZ_UTILIZATION_APMIN 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_APMAX 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_APDEF 0 + +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_160MHZ_UTILIZATION_APMIN 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_APMAX 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_APDEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMAX 1 +#define WNI_CFG_MAX_AMSDU_LENGTH_STADEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_APMIN 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_APMAX 1 +#define WNI_CFG_MAX_AMSDU_LENGTH_APDEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_SHORT_3839_BYTES 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_LONG_7935__BYTES 1 + +#define WNI_CFG_MPDU_DENSITY_STAMIN 0 +#define WNI_CFG_MPDU_DENSITY_STAMAX 7 +#define WNI_CFG_MPDU_DENSITY_STADEF 0 + +#define WNI_CFG_MPDU_DENSITY_APMIN 0 +#define WNI_CFG_MPDU_DENSITY_APMAX 7 +#define WNI_CFG_MPDU_DENSITY_APDEF 0 + +#define WNI_CFG_NUM_BUFF_ADVERT_STAMIN 0 +#define WNI_CFG_NUM_BUFF_ADVERT_STAMAX 128 +#define WNI_CFG_NUM_BUFF_ADVERT_STADEF 64 + +#define WNI_CFG_NUM_BUFF_ADVERT_APMIN 0 +#define WNI_CFG_NUM_BUFF_ADVERT_APMAX 128 +#define WNI_CFG_NUM_BUFF_ADVERT_APDEF 64 + +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN 0 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX 3 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF 3 + +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_APMIN 0 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_APMAX 3 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_APDEF 3 + +#define WNI_CFG_SHORT_GI_20MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_20MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_20MHZ_STADEF 1 + +#define WNI_CFG_SHORT_GI_20MHZ_APMIN 0 +#define WNI_CFG_SHORT_GI_20MHZ_APMAX 1 +#define WNI_CFG_SHORT_GI_20MHZ_APDEF 1 + +#define WNI_CFG_SHORT_GI_20MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_20MHZ_DISABLE 0 + +#define WNI_CFG_SHORT_GI_40MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_40MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_40MHZ_STADEF 0 + +#define WNI_CFG_SHORT_GI_40MHZ_APMIN 0 +#define WNI_CFG_SHORT_GI_40MHZ_APMAX 1 +#define WNI_CFG_SHORT_GI_40MHZ_APDEF 1 + +#define WNI_CFG_SHORT_GI_40MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_40MHZ_DISABLE 0 + +#define WNI_CFG_RIFS_ENABLED_STAMIN 0 +#define WNI_CFG_RIFS_ENABLED_STAMAX 1 +#define WNI_CFG_RIFS_ENABLED_STADEF 1 + +#define WNI_CFG_RIFS_ENABLED_APMIN 0 +#define WNI_CFG_RIFS_ENABLED_APMAX 1 +#define WNI_CFG_RIFS_ENABLED_APDEF 1 + +#define WNI_CFG_RIFS_ENABLED_ENABLE 1 +#define WNI_CFG_RIFS_ENABLED_DISABLE 0 + +#define WNI_CFG_MAX_PS_POLL_STAMIN 0 +#define WNI_CFG_MAX_PS_POLL_STAMAX 255 +#define WNI_CFG_MAX_PS_POLL_STADEF 0 + +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMIN 0 +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMAX 255 +#define WNI_CFG_RSSI_FILTER_PERIOD_STADEF 5 + +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMIN 0 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMAX 10 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STADEF 10 + +#define WNI_CFG_NTH_BEACON_FILTER_STAMIN 0 +#define WNI_CFG_NTH_BEACON_FILTER_STAMAX 255 +#define WNI_CFG_NTH_BEACON_FILTER_STADEF 10 + +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STADEF 0 + +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMIN 0 +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMAX 1 +#define WNI_CFG_SCAN_IN_POWERSAVE_STADEF 1 + +#define WNI_CFG_SCAN_IN_POWERSAVE_APMIN 0 +#define WNI_CFG_SCAN_IN_POWERSAVE_APMAX 1 +#define WNI_CFG_SCAN_IN_POWERSAVE_APDEF 1 + +#define WNI_CFG_IGNORE_DTIM_STAMIN 0 +#define WNI_CFG_IGNORE_DTIM_STAMAX 1 +#define WNI_CFG_IGNORE_DTIM_STADEF 0 + +#define WNI_CFG_IGNORE_DTIM_APMIN 0 +#define WNI_CFG_IGNORE_DTIM_APMAX 1 +#define WNI_CFG_IGNORE_DTIM_APDEF 0 + +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STADEF 40 + +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STADEF 65535 + +#define WNI_CFG_BA_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_TIMEOUT_STADEF 0 + +#define WNI_CFG_BA_TIMEOUT_APMIN 0 +#define WNI_CFG_BA_TIMEOUT_APMAX 65535 +#define WNI_CFG_BA_TIMEOUT_APDEF 0 + +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMIN 0 +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMAX 65535 +#define WNI_CFG_BA_THRESHOLD_HIGH_STADEF 128 + +#define WNI_CFG_BA_THRESHOLD_HIGH_APMIN 0 +#define WNI_CFG_BA_THRESHOLD_HIGH_APMAX 65535 +#define WNI_CFG_BA_THRESHOLD_HIGH_APDEF 128 + +#define WNI_CFG_MAX_BA_BUFFERS_STAMIN 0 +#define WNI_CFG_MAX_BA_BUFFERS_STAMAX 2560 +#define WNI_CFG_MAX_BA_BUFFERS_STADEF 2560 + +#define WNI_CFG_MAX_BA_BUFFERS_APMIN 0 +#define WNI_CFG_MAX_BA_BUFFERS_APMAX 2560 +#define WNI_CFG_MAX_BA_BUFFERS_APDEF 2560 + +#define WNI_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define WNI_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define WNI_CFG_MAX_BA_SESSIONS_STADEF 40 + +#define WNI_CFG_MAX_BA_SESSIONS_APMIN 0 +#define WNI_CFG_MAX_BA_SESSIONS_APMAX 64 +#define WNI_CFG_MAX_BA_SESSIONS_APDEF 40 + +#define WNI_CFG_BA_AUTO_SETUP_STAMIN 0 +#define WNI_CFG_BA_AUTO_SETUP_STAMAX 1 +#define WNI_CFG_BA_AUTO_SETUP_STADEF 1 + +#define WNI_CFG_BA_AUTO_SETUP_APMIN 0 +#define WNI_CFG_BA_AUTO_SETUP_APMAX 1 +#define WNI_CFG_BA_AUTO_SETUP_APDEF 1 + +#define WNI_CFG_BA_AUTO_SETUP_ENABLE 1 +#define WNI_CFG_BA_AUTO_SETUP_DISABLE 0 + +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMIN 0 +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMAX 255 +#define WNI_CFG_ADDBA_REQ_DECLINE_STADEF 0 + +#define WNI_CFG_ADDBA_REQ_DECLINE_APMIN 0 +#define WNI_CFG_ADDBA_REQ_DECLINE_APMAX 255 +#define WNI_CFG_ADDBA_REQ_DECLINE_APDEF 0 + +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STAMIN 0 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STAMAX 1 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STADEF 0 + +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_APMIN 0 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_APMAX 1 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_APDEF 0 + +#define WNI_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define WNI_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define WNI_CFG_MAX_MEDIUM_TIME_STADEF 2048 + +#define WNI_CFG_MAX_MEDIUM_TIME_APMIN 0 +#define WNI_CFG_MAX_MEDIUM_TIME_APMAX 65535 +#define WNI_CFG_MAX_MEDIUM_TIME_APDEF 2048 + +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_APMIN 0 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_APMAX 65535 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_APDEF 64 + +#define WNI_CFG_IBSS_AUTO_BSSID_STAMIN 0 +#define WNI_CFG_IBSS_AUTO_BSSID_STAMAX 1 +#define WNI_CFG_IBSS_AUTO_BSSID_STADEF 1 + +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_APMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_APMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_APDEF 0 + +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_APMIN 0 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_APMAX 1 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_APDEF 0 + +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_APMIN 0 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_APMAX 1 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_APDEF 0 + +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_APMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_APMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_APDEF 0 + +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_APMIN 0 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_APMAX 1 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_APDEF 0 + +#define WNI_CFG_WPS_ENABLE_STAMIN 0 +#define WNI_CFG_WPS_ENABLE_STAMAX 255 +#define WNI_CFG_WPS_ENABLE_STADEF 0 + +#define WNI_CFG_WPS_ENABLE_APMIN 0 +#define WNI_CFG_WPS_ENABLE_APMAX 255 +#define WNI_CFG_WPS_ENABLE_APDEF 0 + +#define WNI_CFG_WPS_ENABLE_AP 1 +#define WNI_CFG_WPS_ENABLE_STA 2 + +#define WNI_CFG_WPS_STATE_STAMIN 0 +#define WNI_CFG_WPS_STATE_STAMAX 255 +#define WNI_CFG_WPS_STATE_STADEF 1 + +#define WNI_CFG_WPS_STATE_APMIN 0 +#define WNI_CFG_WPS_STATE_APMAX 255 +#define WNI_CFG_WPS_STATE_APDEF 1 + +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMIN 0 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMAX 1 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STADEF 0 + +#define WNI_CFG_WPS_PROBE_REQ_FLAG_APMIN 0 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_APMAX 1 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_APDEF 0 + +#define WNI_CFG_WPS_VERSION_STAMIN 0 +#define WNI_CFG_WPS_VERSION_STAMAX 255 +#define WNI_CFG_WPS_VERSION_STADEF 16 + +#define WNI_CFG_WPS_VERSION_APMIN 0 +#define WNI_CFG_WPS_VERSION_APMAX 255 +#define WNI_CFG_WPS_VERSION_APDEF 16 + +#define WNI_CFG_WPS_REQUEST_TYPE_STAMIN 0 +#define WNI_CFG_WPS_REQUEST_TYPE_STAMAX 255 +#define WNI_CFG_WPS_REQUEST_TYPE_STADEF 0 + +#define WNI_CFG_WPS_REQUEST_TYPE_APMIN 0 +#define WNI_CFG_WPS_REQUEST_TYPE_APMAX 255 +#define WNI_CFG_WPS_REQUEST_TYPE_APDEF 3 + +#define WNI_CFG_WPS_CFG_METHOD_STAMIN 0 +#define WNI_CFG_WPS_CFG_METHOD_STAMAX 4294967295 +#define WNI_CFG_WPS_CFG_METHOD_STADEF 8 + +#define WNI_CFG_WPS_CFG_METHOD_APMIN 0 +#define WNI_CFG_WPS_CFG_METHOD_APMAX 4294967295 +#define WNI_CFG_WPS_CFG_METHOD_APDEF 25952654 + +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_APMIN 0 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_APMAX 65535 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_APDEF 6 + +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMIN 0 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMAX 4294967295 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STADEF 5304836 + +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_APMIN 0 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_APMAX 4294967295 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_APDEF 5304836 + +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_APMIN 0 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_APMAX 65535 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_APDEF 1 + +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMIN 0 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMAX 65535 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STADEF 0 + +#define WNI_CFG_WPS_ASSOCIATION_STATE_APMIN 0 +#define WNI_CFG_WPS_ASSOCIATION_STATE_APMAX 65535 +#define WNI_CFG_WPS_ASSOCIATION_STATE_APDEF 0 + +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMIN 0 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMAX 65535 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STADEF 0 + +#define WNI_CFG_WPS_CONFIGURATION_ERROR_APMIN 0 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_APMAX 65535 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_APDEF 0 + +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMAX 4294967295 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STADEF 0 + +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_APMIN 0 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_APMAX 4294967295 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_APDEF 0 + +#define WNI_CFG_WPS_ASSOC_METHOD_STAMIN 0 +#define WNI_CFG_WPS_ASSOC_METHOD_STAMAX 65535 +#define WNI_CFG_WPS_ASSOC_METHOD_STADEF 0 + +#define WNI_CFG_WPS_ASSOC_METHOD_APMIN 0 +#define WNI_CFG_WPS_ASSOC_METHOD_APMAX 65535 +#define WNI_CFG_WPS_ASSOC_METHOD_APDEF 0 + +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +#define WNI_CFG_LOW_GAIN_OVERRIDE_APMIN 0 +#define WNI_CFG_LOW_GAIN_OVERRIDE_APMAX 1 +#define WNI_CFG_LOW_GAIN_OVERRIDE_APDEF 0 + +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMIN 0 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMAX 128 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STADEF 128 + +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_APMIN 0 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_APMAX 128 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_APDEF 128 + +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMIN 0 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMAX 65535 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STADEF 10 + +#define WNI_CFG_RPE_POLLING_THRESHOLD_APMIN 0 +#define WNI_CFG_RPE_POLLING_THRESHOLD_APMAX 65535 +#define WNI_CFG_RPE_POLLING_THRESHOLD_APDEF 10 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_APMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_APMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_APDEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_APMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_APMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_APDEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_APMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_APMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_APDEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_APMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_APMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_APDEF 30 + +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN 0 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX 2 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF 1 + +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_APMIN 0 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_APMAX 2 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_APDEF 1 + +#define WNI_CFG_SINGLE_TID_RC_STAMIN 0 +#define WNI_CFG_SINGLE_TID_RC_STAMAX 1 +#define WNI_CFG_SINGLE_TID_RC_STADEF 1 + +#define WNI_CFG_SINGLE_TID_RC_APMIN 0 +#define WNI_CFG_SINGLE_TID_RC_APMAX 1 +#define WNI_CFG_SINGLE_TID_RC_APDEF 1 + +#define WNI_CFG_RRM_ENABLED_STAMIN 0 +#define WNI_CFG_RRM_ENABLED_STAMAX 1 +#define WNI_CFG_RRM_ENABLED_STADEF 0 + +#define WNI_CFG_RRM_ENABLED_APMIN 0 +#define WNI_CFG_RRM_ENABLED_APMAX 1 +#define WNI_CFG_RRM_ENABLED_APDEF 0 + +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_APMIN 0 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_APMAX 8 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_APDEF 0 + +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_APMIN 0 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_APMAX 8 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_APDEF 0 + +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMIN 0 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMAX 1 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STADEF 1 + +#define WNI_CFG_TX_PWR_CTRL_ENABLE_APMIN 0 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_APMAX 1 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_APDEF 1 + +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN 0 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX 3 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STADEF 0 + +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_APMIN 0 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_APMAX 3 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_APDEF 0 + +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMIN 0 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMAX 255 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STADEF 0 + +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_APMIN 0 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_APMAX 255 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_APDEF 0 + +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN 0 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX 255 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STADEF 0 + +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_APMIN 0 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_APMAX 255 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_APDEF 0 + +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN 0 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX 80 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF 0 + +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN 0 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX 1 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF 0 + +#define WNI_CFG_TELE_BCN_WAKEUP_EN_APMIN 0 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_APMAX 1 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_APDEF 0 + +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_TRANS_LI_STADEF 3 + +#define WNI_CFG_TELE_BCN_TRANS_LI_APMIN 0 +#define WNI_CFG_TELE_BCN_TRANS_LI_APMAX 7 +#define WNI_CFG_TELE_BCN_TRANS_LI_APDEF 3 + +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF 10 + +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_APMIN 5 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_APMAX 255 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_APDEF 10 + +#define WNI_CFG_TELE_BCN_MAX_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_MAX_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_MAX_LI_STADEF 5 + +#define WNI_CFG_TELE_BCN_MAX_LI_APMIN 0 +#define WNI_CFG_TELE_BCN_MAX_LI_APMAX 7 +#define WNI_CFG_TELE_BCN_MAX_LI_APDEF 5 + +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF 15 + +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_APMIN 5 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_APMAX 255 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_APDEF 15 + +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMIN 0 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMAX 255 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STADEF 7 + +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_APMIN 0 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_APMAX 255 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_APDEF 7 + +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN 0 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX 1000 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF 0 + +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_APMIN 0 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_APMAX 1000 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_APDEF 0 + +#define WNI_CFG_ASSOC_STA_LIMIT_STAMIN 1 +#define WNI_CFG_ASSOC_STA_LIMIT_STAMAX 32 +#define WNI_CFG_ASSOC_STA_LIMIT_STADEF 10 + +#define WNI_CFG_ASSOC_STA_LIMIT_APMIN 1 +#define WNI_CFG_ASSOC_STA_LIMIT_APMAX 32 +#define WNI_CFG_ASSOC_STA_LIMIT_APDEF 10 + +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STADEF 1 + +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_APMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_APMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_APDEF 1 + +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STADEF 11 + +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_APMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_APMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_APDEF 11 + +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN 0 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX 5 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STADEF 0 + +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_APMIN 0 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_APMAX 5 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_APDEF 0 + +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN 0 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX 65535 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF 5 + +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_APMIN 0 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_APMAX 65535 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_APDEF 5 + +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMIN 0 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMAX 1 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STADEF 0 + +#define WNI_CFG_ENABLE_CLOSE_LOOP_APMIN 0 +#define WNI_CFG_ENABLE_CLOSE_LOOP_APMAX 1 +#define WNI_CFG_ENABLE_CLOSE_LOOP_APDEF 0 + +#define WNI_CFG_ENABLE_LTE_COEX_STAMIN 0 +#define WNI_CFG_ENABLE_LTE_COEX_STAMAX 1 +#define WNI_CFG_ENABLE_LTE_COEX_STADEF 0 + +#define WNI_CFG_ENABLE_LTE_COEX_APMIN 0 +#define WNI_CFG_ENABLE_LTE_COEX_APMAX 1 +#define WNI_CFG_ENABLE_LTE_COEX_APDEF 0 + +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_APMIN 1 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_APMAX 65535 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_APDEF 20 + +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_APMIN 1 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_APMAX 65535 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_APDEF 20 + +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMIN 0 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMAX 1 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STADEF 0 + +#define WNI_CFG_ENABLE_MC_ADDR_LIST_APMIN 0 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_APMAX 1 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_APDEF 0 + +#define WNI_CFG_ENABLE_UC_FILTER_STAMIN 0 +#define WNI_CFG_ENABLE_UC_FILTER_STAMAX 1 +#define WNI_CFG_ENABLE_UC_FILTER_STADEF 0 + +#define WNI_CFG_ENABLE_UC_FILTER_APMIN 0 +#define WNI_CFG_ENABLE_UC_FILTER_APMAX 1 +#define WNI_CFG_ENABLE_UC_FILTER_APDEF 0 + +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMIN 0 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMAX 1 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STADEF 0 + +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_APMIN 0 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_APMAX 1 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_APDEF 0 + +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN 0 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX 1 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF 0 + +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_APMIN 0 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_APMAX 1 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_APDEF 0 + +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN 0 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX 1 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF 0 + +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_APMIN 0 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_APMAX 1 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_APDEF 0 + +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMAX 255 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STADEF 3 + +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_APMIN 1 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_APMAX 255 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_APDEF 3 + +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMIN 0 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMAX 15 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STADEF 0 + +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_APMIN 0 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_APMAX 15 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_APDEF 0 + +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STADEF 0 + +#define WNI_CFG_TDLS_BUF_STA_ENABLED_APMIN 0 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_APMAX 1 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_APDEF 0 + +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMIN 0 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMAX 10 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STADEF 0 + +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_APMIN 0 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_APMAX 10 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_APDEF 0 + +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMIN 10 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMAX 20 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STADEF 10 + +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_APMIN 10 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_APMAX 20 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_APDEF 10 + +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMIN 0 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMAX 20 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STADEF 5 + +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_APMIN 0 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_APMAX 20 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_APDEF 5 + +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN 10 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMAX 2000 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF 200 + +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_APMIN 10 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_APMAX 2000 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_APDEF 200 + +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN 0 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX 1 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF 1 + +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMIN 0 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMAX 9 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STADEF 0 + +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_APMIN 0 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_APMAX 9 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_APDEF 0 + +#define WNI_CFG_ANTENNA_DIVESITY_STAMIN 0 +#define WNI_CFG_ANTENNA_DIVESITY_STAMAX 3 +#define WNI_CFG_ANTENNA_DIVESITY_STADEF 0 + +#define WNI_CFG_ANTENNA_DIVESITY_APMIN 0 +#define WNI_CFG_ANTENNA_DIVESITY_APMAX 3 +#define WNI_CFG_ANTENNA_DIVESITY_APDEF 0 + +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN 3 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX 50 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF 10 + +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_APMIN 3 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_APMAX 50 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_APDEF 10 + +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN 100 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX 1000 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF 300 + +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_APMIN 100 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_APMAX 1000 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_APDEF 300 + +#define WNI_CFG_CURRENT_RSSI_STAMIN 0 +#define WNI_CFG_CURRENT_RSSI_STAMAX 127 +#define WNI_CFG_CURRENT_RSSI_STADEF 0 + +#define WNI_CFG_CURRENT_RSSI_APMIN 0 +#define WNI_CFG_CURRENT_RSSI_APMAX 127 +#define WNI_CFG_CURRENT_RSSI_APDEF 0 + +#define WNI_CFG_RTT3_ENABLE_STAMIN 0 +#define WNI_CFG_RTT3_ENABLE_STAMAX 1 +#define WNI_CFG_RTT3_ENABLE_STADEF 1 + +#define WNI_CFG_RTT3_ENABLE_APMIN 0 +#define WNI_CFG_RTT3_ENABLE_APMAX 1 +#define WNI_CFG_RTT3_ENABLE_APDEF 1 + +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMIN 0 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMAX 1 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STADEF 0 + +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_APMIN 0 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_APMAX 1 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_APDEF 0 + +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STADEF 0 + +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_APMIN 0 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_APMAX 1 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_APDEF 0 + +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMIN 0 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX 100 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF 0 + +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_APMIN 0 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_APMAX 100 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_APDEF 0 + +#define WNI_CFG_DFS_MASTER_ENABLED_STAMIN 0 +#define WNI_CFG_DFS_MASTER_ENABLED_STAMAX 1 +#define WNI_CFG_DFS_MASTER_ENABLED_STADEF 0 + +#define WNI_CFG_DFS_MASTER_ENABLED_APMIN 0 +#define WNI_CFG_DFS_MASTER_ENABLED_APMAX 1 +#define WNI_CFG_DFS_MASTER_ENABLED_APDEF 0 + +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STADEF 0 + +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_APDEF 0 + +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF 0 + +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_APMIN 0 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_APMAX 1 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_APDEF 0 + +#define CFG_PARAM_MAX_NUM 316 +#define CFG_AP_IBUF_MAX_SIZE 256 +#define CFG_AP_SBUF_MAX_SIZE 3414 +#define CFG_STA_IBUF_MAX_SIZE 251 +#define CFG_STA_SBUF_MAX_SIZE 3380 +#define CFG_SEM_MAX_NUM 19 + +#define CFG_STA_MAGIC_DWORD 0xbeefbeef + +#define CFG_AP_MAGIC_DWORD 0xdeaddead + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgSta.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgSta.h new file mode 100644 index 0000000000000..c76fa93d54906 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/wniCfgSta.h @@ -0,0 +1,1714 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * DO NOT EDIT - This file is generated automatically + */ + +/* + * IMPORTANT: This file is for system that supports STA mode ONLY. + */ + + +#ifndef __WNICFGSTA_H +#define __WNICFGSTA_H + +/* + * Configuration Parameter ID for STA + */ + +#define WNI_CFG_STA_ID 0 +#define WNI_CFG_CFP_PERIOD 2 +#define WNI_CFG_CFP_MAX_DURATION 3 +#define WNI_CFG_SSID 4 +#define WNI_CFG_BEACON_INTERVAL 5 +#define WNI_CFG_DTIM_PERIOD 6 +#define WNI_CFG_WEP_KEY_LENGTH 7 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE 8 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE_ROW 4 +#define WNI_CFG_WEP_DEFAULT_KEY_TABLE_COL 1 +#define WNI_CFG_WEP_DEFAULT_KEY_1 8 +#define WNI_CFG_WEP_DEFAULT_KEY_2 9 +#define WNI_CFG_WEP_DEFAULT_KEY_3 10 +#define WNI_CFG_WEP_DEFAULT_KEY_4 11 +#define WNI_CFG_WEP_DEFAULT_KEYID 12 +#define WNI_CFG_EXCLUDE_UNENCRYPTED 13 +#define WNI_CFG_RTS_THRESHOLD 14 +#define WNI_CFG_SHORT_RETRY_LIMIT 15 +#define WNI_CFG_LONG_RETRY_LIMIT 16 +#define WNI_CFG_FRAGMENTATION_THRESHOLD 17 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME 18 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME 19 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME 20 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME 21 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT 22 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT 23 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT 24 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT 25 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT 26 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS 27 +#define WNI_CFG_PS_ENABLE_BCN_FILTER 28 +#define WNI_CFG_PS_ENABLE_HEART_BEAT 29 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT 31 +#define WNI_CFG_RF_SETTLING_TIME_CLK 32 +#define WNI_CFG_SUPPORTED_RATES_11B 33 +#define WNI_CFG_SUPPORTED_RATES_11A 34 +#define WNI_CFG_PHY_MODE 35 +#define WNI_CFG_DOT11_MODE 36 +#define WNI_CFG_OPERATIONAL_RATE_SET 37 +#define WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET 38 +#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET 39 +#define WNI_CFG_LISTEN_INTERVAL 40 +#define WNI_CFG_VALID_CHANNEL_LIST 41 +#define WNI_CFG_CURRENT_CHANNEL 42 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ 43 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ 44 +#define WNI_CFG_RATE_ADAPTATION_TYPE 45 +#define WNI_CFG_FIXED_RATE 46 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ 47 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ 48 +#define WNI_CFG_RETRYRATE_POLICY 49 +#define WNI_CFG_RETRYRATE_SECONDARY 50 +#define WNI_CFG_RETRYRATE_TERTIARY 51 +#define WNI_CFG_APSD_ENABLED 52 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE 53 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE 54 +#define WNI_CFG_AUTHENTICATION_TYPE 55 +#define WNI_CFG_PRIVACY_ENABLED 57 +#define WNI_CFG_SHORT_PREAMBLE 58 +#define WNI_CFG_SHORT_SLOT_TIME 59 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY 60 +#define WNI_CFG_QOS_ENABLED 61 +#define WNI_CFG_HCF_ENABLED 62 +#define WNI_CFG_RSN_ENABLED 63 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD 64 +#define WNI_CFG_MAX_NUM_PRE_AUTH 65 +#define WNI_CFG_HEART_BEAT_THRESHOLD 68 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT 69 +#define WNI_CFG_MANUFACTURER_OUI 70 +#define WNI_CFG_MANUFACTURER_NAME 71 +#define WNI_CFG_MODEL_NUMBER 72 +#define WNI_CFG_MODEL_NAME 73 +#define WNI_CFG_MANUFACTURER_PRODUCT_NAME 74 +#define WNI_CFG_MANUFACTURER_PRODUCT_VERSION 75 +#define WNI_CFG_11D_ENABLED 76 +#define WNI_CFG_MAX_TX_POWER_2_4 77 +#define WNI_CFG_MAX_TX_POWER_5 78 +#define WNI_CFG_NETWORK_DENSITY 79 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM 80 +#define WNI_CFG_CURRENT_TX_ANTENNA 81 +#define WNI_CFG_CURRENT_RX_ANTENNA 82 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL 83 +#define WNI_CFG_POWER_STATE_PER_CHAIN 84 +#define WNI_CFG_NEW_BSS_FOUND_IND 85 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED 86 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED 87 +#define WNI_CFG_COUNTRY_CODE 89 +#define WNI_CFG_11H_ENABLED 90 +#define WNI_CFG_WT_CNF_TIMEOUT 91 +#define WNI_CFG_KEEPALIVE_TIMEOUT 92 +#define WNI_CFG_PROXIMITY 93 +#define WNI_CFG_LOG_LEVEL 94 +#define WNI_CFG_OLBC_DETECT_TIMEOUT 95 +#define WNI_CFG_PROTECTION_ENABLED 96 +#define WNI_CFG_11G_PROTECTION_ALWAYS 97 +#define WNI_CFG_FORCE_POLICY_PROTECTION 98 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED 99 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED 100 +#define WNI_CFG_CAL_PERIOD 101 +#define WNI_CFG_STATS_PERIOD 102 +#define WNI_CFG_CAL_CONTROL 103 +#define WNI_CFG_11G_ONLY_POLICY 104 +#define WNI_CFG_PACKET_CLASSIFICATION 105 +#define WNI_CFG_WME_ENABLED 106 +#define WNI_CFG_ADDTS_RSP_TIMEOUT 107 +#define WNI_CFG_MAX_SP_LENGTH 108 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS 110 +#define WNI_CFG_WSM_ENABLED 111 +#define WNI_CFG_PROP_CAPABILITY 112 +#define WNI_CFG_EDCA_PROFILE 113 +#define WNI_CFG_EDCA_ANI_ACBK_LOCAL 114 +#define WNI_CFG_EDCA_ANI_ACBE_LOCAL 115 +#define WNI_CFG_EDCA_ANI_ACVI_LOCAL 116 +#define WNI_CFG_EDCA_ANI_ACVO_LOCAL 117 +#define WNI_CFG_EDCA_ANI_ACBK 118 +#define WNI_CFG_EDCA_ANI_ACBE 119 +#define WNI_CFG_EDCA_ANI_ACVI 120 +#define WNI_CFG_EDCA_ANI_ACVO 121 +#define WNI_CFG_EDCA_WME_ACBK_LOCAL 122 +#define WNI_CFG_EDCA_WME_ACBE_LOCAL 123 +#define WNI_CFG_EDCA_WME_ACVI_LOCAL 124 +#define WNI_CFG_EDCA_WME_ACVO_LOCAL 125 +#define WNI_CFG_EDCA_WME_ACBK 126 +#define WNI_CFG_EDCA_WME_ACBE 127 +#define WNI_CFG_EDCA_WME_ACVI 128 +#define WNI_CFG_EDCA_WME_ACVO 129 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL 130 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL 131 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL 132 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL 133 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK 134 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE 135 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI 136 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO 137 +#define WNI_CFG_RDET_FLAG 138 +#define WNI_CFG_RADAR_CHANNEL_LIST 139 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT 140 +#define WNI_CFG_ADMIT_POLICY 141 +#define WNI_CFG_ADMIT_BWFACTOR 142 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE 143 +#define WNI_CFG_CHANNEL_BONDING_MODE 144 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE 145 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO 146 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE 147 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO 148 +#define WNI_CFG_TRIG_STA_BK_SCAN 149 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING 150 +#define WNI_CFG_SCAN_CONTROL_LIST 151 +#define WNI_CFG_MIMO_ENABLED 152 +#define WNI_CFG_BLOCK_ACK_ENABLED 153 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT 154 +#define WNI_CFG_HT_RX_STBC 155 +#define WNI_CFG_HT_CAP_INFO 156 +#define WNI_CFG_HT_AMPDU_PARAMS 157 +#define WNI_CFG_SUPPORTED_MCS_SET 158 +#define WNI_CFG_EXT_HT_CAP_INFO 159 +#define WNI_CFG_TX_BF_CAP 160 +#define WNI_CFG_AS_CAP 161 +#define WNI_CFG_HT_INFO_FIELD1 162 +#define WNI_CFG_HT_INFO_FIELD2 163 +#define WNI_CFG_HT_INFO_FIELD3 164 +#define WNI_CFG_BASIC_MCS_SET 165 +#define WNI_CFG_CURRENT_MCS_SET 166 +#define WNI_CFG_GREENFIELD_CAPABILITY 167 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH 168 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET 169 +#define WNI_CFG_VHT_LDPC_CODING_CAP 170 +#define WNI_CFG_VHT_SHORT_GI_80MHZ 171 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ 172 +#define WNI_CFG_VHT_TXSTBC 173 +#define WNI_CFG_VHT_RXSTBC 174 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP 175 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP 176 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED 177 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS 178 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP 179 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP 180 +#define WNI_CFG_VHT_TXOP_PS 181 +#define WNI_CFG_VHT_HTC_VHTC_CAP 182 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT 183 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP 184 +#define WNI_CFG_VHT_RX_ANT_PATTERN 185 +#define WNI_CFG_VHT_TX_ANT_PATTERN 186 +#define WNI_CFG_VHT_RX_MCS_MAP 187 +#define WNI_CFG_VHT_TX_MCS_MAP 188 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE 189 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE 190 +#define WNI_CFG_VHT_CHANNEL_WIDTH 191 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1 192 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2 193 +#define WNI_CFG_VHT_BASIC_MCS_SET 194 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT 195 +#define WNI_CFG_VHT_SS_UNDER_UTIL 196 +#define WNI_CFG_VHT_40MHZ_UTILIZATION 197 +#define WNI_CFG_VHT_80MHZ_UTILIZATION 198 +#define WNI_CFG_VHT_160MHZ_UTILIZATION 199 +#define WNI_CFG_MAX_AMSDU_LENGTH 200 +#define WNI_CFG_MPDU_DENSITY 201 +#define WNI_CFG_NUM_BUFF_ADVERT 202 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR 203 +#define WNI_CFG_SHORT_GI_20MHZ 204 +#define WNI_CFG_SHORT_GI_40MHZ 205 +#define WNI_CFG_RIFS_ENABLED 206 +#define WNI_CFG_MAX_PS_POLL 207 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE 208 +#define WNI_CFG_RSSI_FILTER_PERIOD 209 +#define WNI_CFG_MIN_RSSI_THRESHOLD 210 +#define WNI_CFG_NTH_BEACON_FILTER 211 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE 212 +#define WNI_CFG_SCAN_IN_POWERSAVE 213 +#define WNI_CFG_IGNORE_DTIM 214 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE 215 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE 216 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE 217 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE 218 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON 219 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD 220 +#define WNI_CFG_BA_TIMEOUT 221 +#define WNI_CFG_BA_THRESHOLD_HIGH 222 +#define WNI_CFG_MAX_BA_BUFFERS 223 +#define WNI_CFG_MAX_BA_SESSIONS 224 +#define WNI_CFG_BA_AUTO_SETUP 225 +#define WNI_CFG_ADDBA_REQ_DECLINE 226 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC 227 +#define WNI_CFG_BG_SCAN_CHANNEL_LIST 228 +#define WNI_CFG_MAX_MEDIUM_TIME 229 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU 230 +#define WNI_CFG_IBSS_AUTO_BSSID 231 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG 232 +#define WNI_CFG_PROBE_REQ_ADDNIE_DATA 233 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG 234 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1 235 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA2 236 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA3 237 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG 238 +#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA 239 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG 240 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA 241 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG 242 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA 243 +#define WNI_CFG_WPS_ENABLE 244 +#define WNI_CFG_WPS_STATE 245 +#define WNI_CFG_WPS_PROBE_REQ_FLAG 246 +#define WNI_CFG_WPS_VERSION 247 +#define WNI_CFG_WPS_REQUEST_TYPE 248 +#define WNI_CFG_WPS_CFG_METHOD 249 +#define WNI_CFG_WPS_UUID 250 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY 251 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI 252 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY 253 +#define WNI_CFG_WPS_ASSOCIATION_STATE 254 +#define WNI_CFG_WPS_CONFIGURATION_ERROR 255 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID 256 +#define WNI_CFG_WPS_ASSOC_METHOD 257 +#define WNI_CFG_LOW_GAIN_OVERRIDE 258 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE 259 +#define WNI_CFG_RPE_POLLING_THRESHOLD 260 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG 261 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG 262 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG 263 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG 264 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS 265 +#define WNI_CFG_SINGLE_TID_RC 266 +#define WNI_CFG_RRM_ENABLED 267 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX 268 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX 269 +#define WNI_CFG_TX_PWR_CTRL_ENABLE 270 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING 271 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK 272 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE 273 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT 274 +#define WNI_CFG_TELE_BCN_WAKEUP_EN 275 +#define WNI_CFG_TELE_BCN_TRANS_LI 276 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS 277 +#define WNI_CFG_TELE_BCN_MAX_LI 278 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS 279 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS 280 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD 281 +#define WNI_CFG_ASSOC_STA_LIMIT 282 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL 283 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL 284 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND 285 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD 286 +#define WNI_CFG_ENABLE_CLOSE_LOOP 287 +#define WNI_CFG_ENABLE_LTE_COEX 288 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT 289 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT 290 +#define WNI_CFG_ENABLE_MC_ADDR_LIST 291 +#define WNI_CFG_ENABLE_UC_FILTER 292 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION 293 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED 294 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP 295 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT 296 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK 297 +#define WNI_CFG_TDLS_BUF_STA_ENABLED 298 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME 299 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD 300 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES 301 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL 302 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN 303 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR 304 +#define WNI_CFG_ANTENNA_DIVESITY 305 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT 306 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY 307 +#define WNI_CFG_CURRENT_RSSI 308 +#define WNI_CFG_RTT3_ENABLE 309 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL 310 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE 312 +#define WNI_CFG_DFS_MASTER_ENABLED 313 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ 314 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED 315 + +/* + * String parameter lengths + */ + +#define WNI_CFG_STA_ID_LEN 6 +#define WNI_CFG_SSID_LEN 32 +#define WNI_CFG_WEP_DEFAULT_KEY_1_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_2_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_3_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_4_LEN 13 +#define WNI_CFG_SUPPORTED_RATES_11B_LEN 4 +#define WNI_CFG_SUPPORTED_RATES_11A_LEN 8 +#define WNI_CFG_OPERATIONAL_RATE_SET_LEN 12 +#define WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN 8 +#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN 4 +#define WNI_CFG_VALID_CHANNEL_LIST_LEN 100 +#define WNI_CFG_MANUFACTURER_OUI_LEN 3 +#define WNI_CFG_MANUFACTURER_NAME_LEN 65 +#define WNI_CFG_MODEL_NUMBER_LEN 33 +#define WNI_CFG_MODEL_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN 33 +#define WNI_CFG_MAX_TX_POWER_2_4_LEN 128 +#define WNI_CFG_MAX_TX_POWER_5_LEN 128 +#define WNI_CFG_COUNTRY_CODE_LEN 3 +#define WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBK_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LEN 20 +#define WNI_CFG_RADAR_CHANNEL_LIST_LEN 20 +#define WNI_CFG_SCAN_CONTROL_LIST_LEN 128 +#define WNI_CFG_SUPPORTED_MCS_SET_LEN 16 +#define WNI_CFG_BASIC_MCS_SET_LEN 16 +#define WNI_CFG_CURRENT_MCS_SET_LEN 16 +#define WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN 100 +#define WNI_CFG_PROBE_REQ_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN 255 +#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN 255 +#define WNI_CFG_WPS_UUID_LEN 16 + +/* + * Integer parameter min/max/default values + */ + +#define WNI_CFG_CFP_PERIOD_STAMIN 0 +#define WNI_CFG_CFP_PERIOD_STAMAX 255 +#define WNI_CFG_CFP_PERIOD_STADEF 1 + +#define WNI_CFG_CFP_MAX_DURATION_STAMIN 0 +#define WNI_CFG_CFP_MAX_DURATION_STAMAX 65535 +#define WNI_CFG_CFP_MAX_DURATION_STADEF 30000 + +#define WNI_CFG_BEACON_INTERVAL_STAMIN 0 +#define WNI_CFG_BEACON_INTERVAL_STAMAX 65535 +#define WNI_CFG_BEACON_INTERVAL_STADEF 100 + +#define WNI_CFG_DTIM_PERIOD_STAMIN 0 +#define WNI_CFG_DTIM_PERIOD_STAMAX 65535 +#define WNI_CFG_DTIM_PERIOD_STADEF 1 + +#define WNI_CFG_WEP_KEY_LENGTH_STAMIN 5 +#define WNI_CFG_WEP_KEY_LENGTH_STAMAX 13 +#define WNI_CFG_WEP_KEY_LENGTH_STADEF 5 + +#define WNI_CFG_WEP_KEY_LENGTH_5 5 +#define WNI_CFG_WEP_KEY_LENGTH_13 13 + +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMIN 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMAX 3 +#define WNI_CFG_WEP_DEFAULT_KEYID_STADEF 0 + +#define WNI_CFG_WEP_DEFAULT_KEYID_0 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_1 1 +#define WNI_CFG_WEP_DEFAULT_KEYID_2 2 +#define WNI_CFG_WEP_DEFAULT_KEYID_3 3 + +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN 0 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX 1 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF 0 + +#define WNI_CFG_RTS_THRESHOLD_STAMIN 0 +#define WNI_CFG_RTS_THRESHOLD_STAMAX 1048576 +#define WNI_CFG_RTS_THRESHOLD_STADEF 2347 + +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_SHORT_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_LONG_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STADEF 20 + +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF 40 + +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF 60 + +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF 110 + +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF 3000 + +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF 2000 + +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN 0 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX 65535 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STADEF 1000 + +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN 0 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX 1 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF 1 + +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 0 + +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN 0 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX 60000 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STADEF 1500 + +#define WNI_CFG_PHY_MODE_STAMIN 0 +#define WNI_CFG_PHY_MODE_STAMAX 3 +#define WNI_CFG_PHY_MODE_STADEF 0 + +#define WNI_CFG_PHY_MODE_11A 0 +#define WNI_CFG_PHY_MODE_11B 1 +#define WNI_CFG_PHY_MODE_11G 2 +#define WNI_CFG_PHY_MODE_NONE 3 + +#define WNI_CFG_DOT11_MODE_STAMIN 0 +#define WNI_CFG_DOT11_MODE_STAMAX 11 +#define WNI_CFG_DOT11_MODE_STADEF 0 + +#define WNI_CFG_DOT11_MODE_ALL 0 +#define WNI_CFG_DOT11_MODE_11A 1 +#define WNI_CFG_DOT11_MODE_11B 2 +#define WNI_CFG_DOT11_MODE_11G 3 +#define WNI_CFG_DOT11_MODE_11N 4 +#define WNI_CFG_DOT11_MODE_POLARIS 5 +#define WNI_CFG_DOT11_MODE_TITAN 6 +#define WNI_CFG_DOT11_MODE_TAURUS 7 +#define WNI_CFG_DOT11_MODE_11G_ONLY 8 +#define WNI_CFG_DOT11_MODE_11N_ONLY 9 +#define WNI_CFG_DOT11_MODE_11AC 10 +#define WNI_CFG_DOT11_MODE_11AC_ONLY 11 + +#define WNI_CFG_LISTEN_INTERVAL_STAMIN 0 +#define WNI_CFG_LISTEN_INTERVAL_STAMAX 65535 +#define WNI_CFG_LISTEN_INTERVAL_STADEF 1 + +#define WNI_CFG_CURRENT_CHANNEL_STAMIN 0 +#define WNI_CFG_CURRENT_CHANNEL_STAMAX 165 +#define WNI_CFG_CURRENT_CHANNEL_STADEF 1 + +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX 11 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF 5 + +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX 31 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMIN 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMAX 2 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STADEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_FIXED 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_AUTO 1 +#define WNI_CFG_RATE_ADAPTATION_TYPE_SNR_BASED 2 + +#define WNI_CFG_FIXED_RATE_STAMIN 0 +#define WNI_CFG_FIXED_RATE_STAMAX 44 +#define WNI_CFG_FIXED_RATE_STADEF 0 + +#define WNI_CFG_FIXED_RATE_AUTO 0 +#define WNI_CFG_FIXED_RATE_1MBPS 1 +#define WNI_CFG_FIXED_RATE_2MBPS 2 +#define WNI_CFG_FIXED_RATE_5_5MBPS 3 +#define WNI_CFG_FIXED_RATE_11MBPS 4 +#define WNI_CFG_FIXED_RATE_6MBPS 5 +#define WNI_CFG_FIXED_RATE_9MBPS 6 +#define WNI_CFG_FIXED_RATE_12MBPS 7 +#define WNI_CFG_FIXED_RATE_18MBPS 8 +#define WNI_CFG_FIXED_RATE_24MBPS 9 +#define WNI_CFG_FIXED_RATE_36MBPS 10 +#define WNI_CFG_FIXED_RATE_48MBPS 11 +#define WNI_CFG_FIXED_RATE_54MBPS 12 +#define WNI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define WNI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define WNI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define WNI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define WNI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define WNI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define WNI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define WNI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define WNI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define WNI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define WNI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define WNI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define WNI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define WNI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define WNI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO 29 +#define WNI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO 30 +#define WNI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO 31 +#define WNI_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO 32 +#define WNI_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO 33 +#define WNI_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO 34 +#define WNI_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO 35 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO 36 +#define WNI_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#define WNI_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#define WNI_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#define WNI_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#define WNI_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#define WNI_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#define WNI_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF 1 + +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF 5 + +#define WNI_CFG_RETRYRATE_POLICY_STAMIN 0 +#define WNI_CFG_RETRYRATE_POLICY_STAMAX 255 +#define WNI_CFG_RETRYRATE_POLICY_STADEF 4 + +#define WNI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define WNI_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define WNI_CFG_RETRYRATE_POLICY_RESERVED 2 +#define WNI_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define WNI_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define WNI_CFG_RETRYRATE_POLICY_MAX 5 + +#define WNI_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_SECONDARY_STADEF 0 + +#define WNI_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_TERTIARY_STADEF 0 + +#define WNI_CFG_APSD_ENABLED_STAMIN 0 +#define WNI_CFG_APSD_ENABLED_STAMAX 1 +#define WNI_CFG_APSD_ENABLED_STADEF 0 + +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_AUTHENTICATION_TYPE_STAMIN 0 +#define WNI_CFG_AUTHENTICATION_TYPE_STAMAX 65535 +#define WNI_CFG_AUTHENTICATION_TYPE_STADEF 0 + +#define WNI_CFG_PRIVACY_ENABLED_STAMIN 0 +#define WNI_CFG_PRIVACY_ENABLED_STAMAX 1 +#define WNI_CFG_PRIVACY_ENABLED_STADEF 0 + +#define WNI_CFG_SHORT_PREAMBLE_STAMIN 0 +#define WNI_CFG_SHORT_PREAMBLE_STAMAX 1 +#define WNI_CFG_SHORT_PREAMBLE_STADEF 1 + +#define WNI_CFG_SHORT_SLOT_TIME_STAMIN 0 +#define WNI_CFG_SHORT_SLOT_TIME_STAMAX 1 +#define WNI_CFG_SHORT_SLOT_TIME_STADEF 1 + +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN 0 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX 1 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF 0 + +#define WNI_CFG_QOS_ENABLED_STAMIN 0 +#define WNI_CFG_QOS_ENABLED_STAMAX 1 +#define WNI_CFG_QOS_ENABLED_STADEF 0 + +#define WNI_CFG_HCF_ENABLED_STAMIN 0 +#define WNI_CFG_HCF_ENABLED_STAMAX 1 +#define WNI_CFG_HCF_ENABLED_STADEF 0 + +#define WNI_CFG_RSN_ENABLED_STAMIN 0 +#define WNI_CFG_RSN_ENABLED_STAMAX 1 +#define WNI_CFG_RSN_ENABLED_STADEF 0 + +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMIN 0 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMAX 180000 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STADEF 5000 + +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMIN 0 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMAX 256 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STADEF 64 + +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN 0 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX 65535 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STADEF 40 + +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN 10 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMAX 10000 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STADEF 40 + +#define WNI_CFG_11D_ENABLED_STAMIN 0 +#define WNI_CFG_11D_ENABLED_STAMAX 1 +#define WNI_CFG_11D_ENABLED_STADEF 1 + +#define WNI_CFG_NETWORK_DENSITY_STAMIN 0 +#define WNI_CFG_NETWORK_DENSITY_STAMAX 3 +#define WNI_CFG_NETWORK_DENSITY_STADEF 3 + +#define WNI_CFG_NETWORK_DENSITY_LOW 0 +#define WNI_CFG_NETWORK_DENSITY_MEDIUM 1 +#define WNI_CFG_NETWORK_DENSITY_HIGH 2 +#define WNI_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMIN 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMAX 2 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STADEF 2 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CARRIER 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CORRELATION 2 + +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define WNI_CFG_CURRENT_RX_ANTENNA_STADEF 2 + +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN 0 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX 128 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF 27 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STADEF 785 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define WNI_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define WNI_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define WNI_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMIN 0 +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMAX 1 +#define WNI_CFG_NEW_BSS_FOUND_IND_STADEF 0 + +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STADEF 0 + +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STADEF 0 + +#define WNI_CFG_11H_ENABLED_STAMIN 0 +#define WNI_CFG_11H_ENABLED_STAMAX 1 +#define WNI_CFG_11H_ENABLED_STADEF 1 + +#define WNI_CFG_WT_CNF_TIMEOUT_STAMIN 10 +#define WNI_CFG_WT_CNF_TIMEOUT_STAMAX 3000 +#define WNI_CFG_WT_CNF_TIMEOUT_STADEF 1000 + +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMIN 0 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMAX 3600000 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STADEF 0 + +#define WNI_CFG_PROXIMITY_STAMIN 0 +#define WNI_CFG_PROXIMITY_STAMAX 1 +#define WNI_CFG_PROXIMITY_STADEF 0 + +#define WNI_CFG_PROXIMITY_OFF 0 +#define WNI_CFG_PROXIMITY_ON 1 + +#define WNI_CFG_LOG_LEVEL_STAMIN 0 +#define WNI_CFG_LOG_LEVEL_STAMAX 7 +#define WNI_CFG_LOG_LEVEL_STADEF 4 + +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMIN 1000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMAX 30000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STADEF 10000 + +#define WNI_CFG_PROTECTION_ENABLED_STAMIN 0 +#define WNI_CFG_PROTECTION_ENABLED_STAMAX 65535 +#define WNI_CFG_PROTECTION_ENABLED_STADEF 65535 + +#define WNI_CFG_PROTECTION_ENABLED_FROM_llA 0 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llB 1 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llG 2 +#define WNI_CFG_PROTECTION_ENABLED_HT_20 3 +#define WNI_CFG_PROTECTION_ENABLED_NON_GF 4 +#define WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP 5 +#define WNI_CFG_PROTECTION_ENABLED_RIFS 6 +#define WNI_CFG_PROTECTION_ENABLED_OBSS 7 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llA 8 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llB 9 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llG 10 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_HT20 11 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_NON_GF 12 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_LSIG_TXOP 13 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_RIFS 14 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_OBSS 15 + +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMIN 0 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMAX 1 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STADEF 0 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STADEF 5 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define WNI_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define WNI_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STADEF 0 + +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STADEF 1 + +#define WNI_CFG_CAL_PERIOD_STAMIN 2 +#define WNI_CFG_CAL_PERIOD_STAMAX 10 +#define WNI_CFG_CAL_PERIOD_STADEF 5 + +#define WNI_CFG_STATS_PERIOD_STAMIN 1 +#define WNI_CFG_STATS_PERIOD_STAMAX 10 +#define WNI_CFG_STATS_PERIOD_STADEF 10 + +#define WNI_CFG_CAL_CONTROL_STAMIN 0 +#define WNI_CFG_CAL_CONTROL_STAMAX 1 +#define WNI_CFG_CAL_CONTROL_STADEF 0 + +#define WNI_CFG_CAL_CONTROL_CAL_ON 0 +#define WNI_CFG_CAL_CONTROL_CAL_OFF 1 + +#define WNI_CFG_11G_ONLY_POLICY_STAMIN 0 +#define WNI_CFG_11G_ONLY_POLICY_STAMAX 1 +#define WNI_CFG_11G_ONLY_POLICY_STADEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_STAMIN 0 +#define WNI_CFG_PACKET_CLASSIFICATION_STAMAX 3 +#define WNI_CFG_PACKET_CLASSIFICATION_STADEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_DISABLED 0 +#define WNI_CFG_PACKET_CLASSIFICATION_DSCP 1 +#define WNI_CFG_PACKET_CLASSIFICATION_8021P 2 +#define WNI_CFG_PACKET_CLASSIFICATION_ALL 3 + +#define WNI_CFG_WME_ENABLED_STAMIN 0 +#define WNI_CFG_WME_ENABLED_STAMAX 1 +#define WNI_CFG_WME_ENABLED_STADEF 1 + +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_MAX_SP_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_SP_LENGTH_STAMAX 3 +#define WNI_CFG_MAX_SP_LENGTH_STADEF 0 + +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMIN 0 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMAX 1 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STADEF 0 + +#define WNI_CFG_WSM_ENABLED_STAMIN 0 +#define WNI_CFG_WSM_ENABLED_STAMAX 1 +#define WNI_CFG_WSM_ENABLED_STADEF 0 + +#define WNI_CFG_PROP_CAPABILITY_STAMIN 0 +#define WNI_CFG_PROP_CAPABILITY_STAMAX 65535 +#define WNI_CFG_PROP_CAPABILITY_STADEF 57535 + +#define WNI_CFG_PROP_CAPABILITY_HCF 0 +#define WNI_CFG_PROP_CAPABILITY_11EQOS 1 +#define WNI_CFG_PROP_CAPABILITY_WME 2 +#define WNI_CFG_PROP_CAPABILITY_WSM 3 +#define WNI_CFG_PROP_CAPABILITY_EXTRATES 4 +#define WNI_CFG_PROP_CAPABILITY_EXTRATE_STOP 5 +#define WNI_CFG_PROP_CAPABILITY_TITAN 6 +#define WNI_CFG_PROP_CAPABILITY_TAURUS 7 +#define WNI_CFG_PROP_CAPABILITY_EDCAPARAMS 13 +#define WNI_CFG_PROP_CAPABILITY_LOADINFO 14 +#define WNI_CFG_PROP_CAPABILITY_VERSION 15 +#define WNI_CFG_PROP_CAPABILITY_MAXBITOFFSET 15 + +#define WNI_CFG_EDCA_PROFILE_STAMIN 0 +#define WNI_CFG_EDCA_PROFILE_STAMAX 255 +#define WNI_CFG_EDCA_PROFILE_STADEF 1 + +#define WNI_CFG_EDCA_PROFILE_ANI 0 +#define WNI_CFG_EDCA_PROFILE_WMM 1 +#define WNI_CFG_EDCA_PROFILE_TIT_DEMO 2 +#define WNI_CFG_EDCA_PROFILE_MAX 3 +#define WNI_CFG_EDCA_PROFILE_ACM_IDX 0 +#define WNI_CFG_EDCA_PROFILE_AIFSN_IDX 1 +#define WNI_CFG_EDCA_PROFILE_CWMINA_IDX 2 +#define WNI_CFG_EDCA_PROFILE_CWMAXA_IDX 4 +#define WNI_CFG_EDCA_PROFILE_TXOPA_IDX 6 +#define WNI_CFG_EDCA_PROFILE_CWMINB_IDX 7 +#define WNI_CFG_EDCA_PROFILE_CWMAXB_IDX 9 +#define WNI_CFG_EDCA_PROFILE_TXOPB_IDX 11 +#define WNI_CFG_EDCA_PROFILE_CWMING_IDX 12 +#define WNI_CFG_EDCA_PROFILE_CWMAXG_IDX 14 +#define WNI_CFG_EDCA_PROFILE_TXOPG_IDX 16 + +#define WNI_CFG_RDET_FLAG_STAMIN 0 +#define WNI_CFG_RDET_FLAG_STAMAX 1 +#define WNI_CFG_RDET_FLAG_STADEF 0 + +#define WNI_CFG_RDET_FLAG_ENABLE 1 +#define WNI_CFG_RDET_FLAG_DISABLE 0 + +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN 0 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX 255 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF 0 + +#define WNI_CFG_ADMIT_POLICY_STAMIN 0 +#define WNI_CFG_ADMIT_POLICY_STAMAX 2 +#define WNI_CFG_ADMIT_POLICY_STADEF 0 + +#define WNI_CFG_ADMIT_POLICY_ADMIT_ALL 0 +#define WNI_CFG_ADMIT_POLICY_REJECT_ALL 1 +#define WNI_CFG_ADMIT_POLICY_BW_FACTOR 2 + +#define WNI_CFG_ADMIT_BWFACTOR_STAMIN 0 +#define WNI_CFG_ADMIT_BWFACTOR_STAMAX 100 +#define WNI_CFG_ADMIT_BWFACTOR_STADEF 20 + +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMIN 0 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMAX 256 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STADEF 60 + +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMIN 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMAX 10 +#define WNI_CFG_CHANNEL_BONDING_MODE_STADEF 0 + +#define WNI_CFG_CHANNEL_BONDING_MODE_DISABLE 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_ENABLE 1 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_BSS 2 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_ALL 3 +#define WNI_CFG_CHANNEL_BONDING_MODE_INTELLIGENT 4 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMIN 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMAX 10 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STADEF 0 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_NONE 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_LOWER 1 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_HIGHER 2 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_CENTERED 3 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_CENTERED_40MHZ_CENTERED 4 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_CENTERED 5 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_LOW 6 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_LOW 7 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_HIGH 8 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_HIGH 9 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 2 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 4 + +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 6 + +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMIN 0 +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMAX 1 +#define WNI_CFG_TRIG_STA_BK_SCAN_STADEF 0 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMIN 0 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMAX 255 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STADEF 255 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_UNUSED 255 + +#define WNI_CFG_MIMO_ENABLED_STAMIN 0 +#define WNI_CFG_MIMO_ENABLED_STAMAX 1 +#define WNI_CFG_MIMO_ENABLED_STADEF 1 + +#define WNI_CFG_MIMO_ENABLED_ENABLE 1 +#define WNI_CFG_MIMO_ENABLED_DISABLE 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMIN 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMAX 3 +#define WNI_CFG_BLOCK_ACK_ENABLED_STADEF 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_DELAYED 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE 1 + +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STADEF 1000 + +#define WNI_CFG_HT_RX_STBC_STAMIN 0 +#define WNI_CFG_HT_RX_STBC_STAMAX 3 +#define WNI_CFG_HT_RX_STBC_STADEF 1 + +#define WNI_CFG_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_HT_CAP_INFO_STADEF 364 + +#define WNI_CFG_HT_CAP_INFO_ADVANCE_CODING 0 +#define WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET 1 +#define WNI_CFG_HT_CAP_INFO_SM_POWER_SAVE 2 +#define WNI_CFG_HT_CAP_INFO_GREEN_FIELD 4 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ 5 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ 6 +#define WNI_CFG_HT_CAP_INFO_TX_STBC 7 +#define WNI_CFG_HT_CAP_INFO_RX_STBC 8 +#define WNI_CFG_HT_CAP_INFO_DELAYED_BA 10 +#define WNI_CFG_HT_CAP_INFO_MAX_AMSDU_SIZE 11 +#define WNI_CFG_HT_CAP_INFO_DSSS_CCK_MODE_40MHZ 12 +#define WNI_CFG_HT_CAP_INFO_PSMP 13 +#define WNI_CFG_HT_CAP_INFO_STBC_CONTROL_FRAME 14 +#define WNI_CFG_HT_CAP_INFO_LSIG_TXOP_PROTECTION 15 + +#define WNI_CFG_HT_AMPDU_PARAMS_STAMIN 0 +#define WNI_CFG_HT_AMPDU_PARAMS_STAMAX 255 +#define WNI_CFG_HT_AMPDU_PARAMS_STADEF 0 + +#define WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR 0 +#define WNI_CFG_HT_AMPDU_PARAMS_MPDU_DENSITY 2 +#define WNI_CFG_HT_AMPDU_PARAMS_RESERVED 5 + +#define WNI_CFG_EXT_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_EXT_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_EXT_HT_CAP_INFO_STADEF 1024 + +#define WNI_CFG_EXT_HT_CAP_INFO_PCO 0 +#define WNI_CFG_EXT_HT_CAP_INFO_TRANSITION_TIME 1 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED1 3 +#define WNI_CFG_EXT_HT_CAP_INFO_MCS_FEEDBACK 8 +#define WNI_CFG_EXT_HT_CAP_INFO_HTC_SUPPORT 10 +#define WNI_CFG_EXT_HT_CAP_INFO_RD_RESPONDER 11 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED2 12 + +#define WNI_CFG_TX_BF_CAP_STAMIN 0 +#define WNI_CFG_TX_BF_CAP_STAMAX 4294967295 +#define WNI_CFG_TX_BF_CAP_STADEF 0 + +#define WNI_CFG_AS_CAP_STAMIN 0 +#define WNI_CFG_AS_CAP_STAMAX 255 +#define WNI_CFG_AS_CAP_STADEF 0 + +#define WNI_CFG_AS_CAP_ANTENNA_SELECTION 0 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK_TX 1 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK_TX 2 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK 3 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK 4 +#define WNI_CFG_AS_CAP_RX_AS 5 +#define WNI_CFG_AS_CAP_TX_SOUNDING_PPDUS 6 +#define WNI_CFG_AS_CAP_RESERVED 7 + +#define WNI_CFG_HT_INFO_FIELD1_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD1_STAMAX 255 +#define WNI_CFG_HT_INFO_FIELD1_STADEF 15 + +#define WNI_CFG_HT_INFO_FIELD1_SECONDARY_CHANNEL_OFFSET 0 +#define WNI_CFG_HT_INFO_FIELD1_RECOMMENDED_CHANNEL_WIDTH 2 +#define WNI_CFG_HT_INFO_FIELD1_RIFS_MODE 3 +#define WNI_CFG_HT_INFO_FIELD1_PSMP_ACCESS_ONLY 4 +#define WNI_CFG_HT_INFO_FIELD1_SERVICE_INTERVAL_GRANULARITY 5 + +#define WNI_CFG_HT_INFO_FIELD2_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD2_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD2_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD2_OP_MODE 0 +#define WNI_CFG_HT_INFO_FIELD2_NON_GF_DEVICES_PRESENT 2 +#define WNI_CFG_HT_INFO_FIELD2_RESERVED 3 + +#define WNI_CFG_HT_INFO_FIELD3_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD3_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD3_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD3_BASIC_STBC_MCS 0 +#define WNI_CFG_HT_INFO_FIELD3_DUAL_STBC_PROTECTION 7 +#define WNI_CFG_HT_INFO_FIELD3_SECONDARY_BEACON 8 +#define WNI_CFG_HT_INFO_FIELD3_LSIG_TXOP_PROTECTION_FULL_SUPPORT 9 +#define WNI_CFG_HT_INFO_FIELD3_PCO_ACTIVE 10 +#define WNI_CFG_HT_INFO_FIELD3_PCO_PHASE 11 +#define WNI_CFG_HT_INFO_FIELD3_RESERVED 12 + +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMIN 0 +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMAX 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_STADEF 0 + +#define WNI_CFG_GREENFIELD_CAPABILITY_ENABLE 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_DISABLE 0 + +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMIN 0 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMAX 2 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STADEF 0 + +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMIN 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMAX 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STADEF 0 + +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMIN 0 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMAX 1 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STADEF 0 + +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STADEF 1 + +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STADEF 0 + +#define WNI_CFG_VHT_TXSTBC_STAMIN 0 +#define WNI_CFG_VHT_TXSTBC_STAMAX 1 +#define WNI_CFG_VHT_TXSTBC_STADEF 0 + +#define WNI_CFG_VHT_RXSTBC_STAMIN 0 +#define WNI_CFG_VHT_RXSTBC_STAMAX 1 +#define WNI_CFG_VHT_RXSTBC_STADEF 1 + +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF 0 + +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN 0 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX 4 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STADEF 0 + +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMIN 0 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMAX 3 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STADEF 0 + +#define WNI_CFG_VHT_TXOP_PS_STAMIN 0 +#define WNI_CFG_VHT_TXOP_PS_STAMAX 1 +#define WNI_CFG_VHT_TXOP_PS_STADEF 0 + +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMIN 0 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMAX 1 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STADEF 0 + +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMIN 0 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMAX 7 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STADEF 3 + +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMIN 0 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMAX 3 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STADEF 0 + +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_RX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_RX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_RX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_TX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_TX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_TX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 780 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 780 + +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 780 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 780 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMAX 3 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ 1 +#define WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ 2 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ 3 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMAX 256 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMAX 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STADEF 0 + +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMIN 0 +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMAX 65535 +#define WNI_CFG_VHT_BASIC_MCS_SET_STADEF 65534 + +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMIN 0 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMAX 4 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STADEF 0 + +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMIN 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMAX 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STADEF 0 + +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMAX 1 +#define WNI_CFG_MAX_AMSDU_LENGTH_STADEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_SHORT_3839_BYTES 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_LONG_7935__BYTES 1 + +#define WNI_CFG_MPDU_DENSITY_STAMIN 0 +#define WNI_CFG_MPDU_DENSITY_STAMAX 7 +#define WNI_CFG_MPDU_DENSITY_STADEF 0 + +#define WNI_CFG_NUM_BUFF_ADVERT_STAMIN 0 +#define WNI_CFG_NUM_BUFF_ADVERT_STAMAX 128 +#define WNI_CFG_NUM_BUFF_ADVERT_STADEF 64 + +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN 0 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX 3 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF 3 + +#define WNI_CFG_SHORT_GI_20MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_20MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_20MHZ_STADEF 1 + +#define WNI_CFG_SHORT_GI_20MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_20MHZ_DISABLE 0 + +#define WNI_CFG_SHORT_GI_40MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_40MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_40MHZ_STADEF 0 + +#define WNI_CFG_SHORT_GI_40MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_40MHZ_DISABLE 0 + +#define WNI_CFG_RIFS_ENABLED_STAMIN 0 +#define WNI_CFG_RIFS_ENABLED_STAMAX 1 +#define WNI_CFG_RIFS_ENABLED_STADEF 1 + +#define WNI_CFG_RIFS_ENABLED_ENABLE 1 +#define WNI_CFG_RIFS_ENABLED_DISABLE 0 + +#define WNI_CFG_MAX_PS_POLL_STAMIN 0 +#define WNI_CFG_MAX_PS_POLL_STAMAX 255 +#define WNI_CFG_MAX_PS_POLL_STADEF 0 + +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMIN 0 +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMAX 255 +#define WNI_CFG_RSSI_FILTER_PERIOD_STADEF 5 + +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMIN 0 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMAX 10 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STADEF 10 + +#define WNI_CFG_NTH_BEACON_FILTER_STAMIN 0 +#define WNI_CFG_NTH_BEACON_FILTER_STAMAX 255 +#define WNI_CFG_NTH_BEACON_FILTER_STADEF 10 + +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STADEF 0 + +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMIN 0 +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMAX 1 +#define WNI_CFG_SCAN_IN_POWERSAVE_STADEF 1 + +#define WNI_CFG_IGNORE_DTIM_STAMIN 0 +#define WNI_CFG_IGNORE_DTIM_STAMAX 1 +#define WNI_CFG_IGNORE_DTIM_STADEF 0 + +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STADEF 40 + +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STADEF 65535 + +#define WNI_CFG_BA_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_TIMEOUT_STADEF 0 + +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMIN 0 +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMAX 65535 +#define WNI_CFG_BA_THRESHOLD_HIGH_STADEF 128 + +#define WNI_CFG_MAX_BA_BUFFERS_STAMIN 0 +#define WNI_CFG_MAX_BA_BUFFERS_STAMAX 2560 +#define WNI_CFG_MAX_BA_BUFFERS_STADEF 2560 + +#define WNI_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define WNI_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define WNI_CFG_MAX_BA_SESSIONS_STADEF 40 + +#define WNI_CFG_BA_AUTO_SETUP_STAMIN 0 +#define WNI_CFG_BA_AUTO_SETUP_STAMAX 1 +#define WNI_CFG_BA_AUTO_SETUP_STADEF 1 + +#define WNI_CFG_BA_AUTO_SETUP_ENABLE 1 +#define WNI_CFG_BA_AUTO_SETUP_DISABLE 0 + +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMIN 0 +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMAX 255 +#define WNI_CFG_ADDBA_REQ_DECLINE_STADEF 0 + +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STAMIN 0 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STAMAX 1 +#define WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC_STADEF 0 + +#define WNI_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define WNI_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define WNI_CFG_MAX_MEDIUM_TIME_STADEF 2048 + +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +#define WNI_CFG_IBSS_AUTO_BSSID_STAMIN 0 +#define WNI_CFG_IBSS_AUTO_BSSID_STAMAX 1 +#define WNI_CFG_IBSS_AUTO_BSSID_STADEF 1 + +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_WPS_ENABLE_STAMIN 0 +#define WNI_CFG_WPS_ENABLE_STAMAX 255 +#define WNI_CFG_WPS_ENABLE_STADEF 0 + +#define WNI_CFG_WPS_ENABLE_AP 1 +#define WNI_CFG_WPS_ENABLE_STA 2 + +#define WNI_CFG_WPS_STATE_STAMIN 0 +#define WNI_CFG_WPS_STATE_STAMAX 255 +#define WNI_CFG_WPS_STATE_STADEF 1 + +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMIN 0 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMAX 1 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STADEF 0 + +#define WNI_CFG_WPS_VERSION_STAMIN 0 +#define WNI_CFG_WPS_VERSION_STAMAX 255 +#define WNI_CFG_WPS_VERSION_STADEF 16 + +#define WNI_CFG_WPS_REQUEST_TYPE_STAMIN 0 +#define WNI_CFG_WPS_REQUEST_TYPE_STAMAX 255 +#define WNI_CFG_WPS_REQUEST_TYPE_STADEF 0 + +#define WNI_CFG_WPS_CFG_METHOD_STAMIN 0 +#define WNI_CFG_WPS_CFG_METHOD_STAMAX 4294967295 +#define WNI_CFG_WPS_CFG_METHOD_STADEF 8 + +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMIN 0 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMAX 4294967295 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STADEF 5304836 + +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMIN 0 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMAX 65535 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STADEF 0 + +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMIN 0 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMAX 65535 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STADEF 0 + +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMAX 4294967295 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STADEF 0 + +#define WNI_CFG_WPS_ASSOC_METHOD_STAMIN 0 +#define WNI_CFG_WPS_ASSOC_METHOD_STAMAX 65535 +#define WNI_CFG_WPS_ASSOC_METHOD_STADEF 0 + +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMIN 0 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMAX 128 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STADEF 128 + +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMIN 0 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMAX 65535 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STADEF 10 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF 30 + +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN 0 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX 2 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF 1 + +#define WNI_CFG_SINGLE_TID_RC_STAMIN 0 +#define WNI_CFG_SINGLE_TID_RC_STAMAX 1 +#define WNI_CFG_SINGLE_TID_RC_STADEF 1 + +#define WNI_CFG_RRM_ENABLED_STAMIN 0 +#define WNI_CFG_RRM_ENABLED_STAMAX 1 +#define WNI_CFG_RRM_ENABLED_STADEF 0 + +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMIN 0 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMAX 1 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STADEF 1 + +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN 0 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX 3 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STADEF 0 + +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMIN 0 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMAX 255 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STADEF 0 + +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN 0 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX 255 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STADEF 0 + +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN 0 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX 80 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF 0 + +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN 0 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX 1 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF 0 + +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_TRANS_LI_STADEF 3 + +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF 10 + +#define WNI_CFG_TELE_BCN_MAX_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_MAX_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_MAX_LI_STADEF 5 + +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF 15 + +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMIN 0 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMAX 255 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STADEF 7 + +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN 0 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX 1000 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF 0 + +#define WNI_CFG_ASSOC_STA_LIMIT_STAMIN 1 +#define WNI_CFG_ASSOC_STA_LIMIT_STAMAX 32 +#define WNI_CFG_ASSOC_STA_LIMIT_STADEF 10 + +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STADEF 1 + +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STADEF 11 + +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN 0 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX 5 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STADEF 0 + +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN 0 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX 65535 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF 5 + +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMIN 0 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMAX 1 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STADEF 0 + +#define WNI_CFG_ENABLE_LTE_COEX_STAMIN 0 +#define WNI_CFG_ENABLE_LTE_COEX_STAMAX 1 +#define WNI_CFG_ENABLE_LTE_COEX_STADEF 0 + +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMIN 0 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMAX 1 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STADEF 0 + +#define WNI_CFG_ENABLE_UC_FILTER_STAMIN 0 +#define WNI_CFG_ENABLE_UC_FILTER_STAMAX 1 +#define WNI_CFG_ENABLE_UC_FILTER_STADEF 0 + +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMIN 0 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMAX 1 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STADEF 0 + +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN 0 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX 1 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF 0 + +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN 0 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX 1 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF 0 + +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMAX 255 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STADEF 3 + +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMIN 0 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMAX 15 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STADEF 0 + +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STADEF 0 + +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMIN 0 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMAX 10 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STADEF 0 + +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMIN 10 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMAX 20 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STADEF 10 + +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMIN 0 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMAX 20 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STADEF 5 + +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN 10 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMAX 2000 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF 200 + +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN 0 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX 1 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF 1 + +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMIN 0 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMAX 9 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STADEF 0 + +#define WNI_CFG_ANTENNA_DIVESITY_STAMIN 0 +#define WNI_CFG_ANTENNA_DIVESITY_STAMAX 3 +#define WNI_CFG_ANTENNA_DIVESITY_STADEF 0 + +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN 3 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX 50 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF 10 + +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN 100 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX 1000 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF 300 + +#define WNI_CFG_CURRENT_RSSI_STAMIN 0 +#define WNI_CFG_CURRENT_RSSI_STAMAX 127 +#define WNI_CFG_CURRENT_RSSI_STADEF 0 + +#define WNI_CFG_RTT3_ENABLE_STAMIN 0 +#define WNI_CFG_RTT3_ENABLE_STAMAX 1 +#define WNI_CFG_RTT3_ENABLE_STADEF 1 + +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMIN 0 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMAX 1 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STADEF 0 + +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STADEF 0 + +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMIN 0 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX 100 +#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF 0 + +#define WNI_CFG_DFS_MASTER_ENABLED_STAMIN 0 +#define WNI_CFG_DFS_MASTER_ENABLED_STAMAX 1 +#define WNI_CFG_DFS_MASTER_ENABLED_STADEF 0 + +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMIN 0 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMAX 1 +#define WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STADEF 0 + +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF 0 + +#define CFG_PARAM_MAX_NUM 316 +#define CFG_STA_IBUF_MAX_SIZE 251 +#define CFG_STA_SBUF_MAX_SIZE 3380 +#define CFG_SEM_MAX_NUM 19 + +#define CFG_STA_MAGIC_DWORD 0xbeefbeef + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgApi.c new file mode 100644 index 0000000000000..a5ae387d3041c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgApi.c @@ -0,0 +1,1080 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file contains the source code for CFG API functions. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ + +#include "palTypes.h" +#include "cfgPriv.h" +#include "cfgDebug.h" +#include "wlan_qct_wda.h" + +//--------------------------------------------------------------------- +// Static Variables +//---------------------------------------------------------------------- +static tCfgCtl __gCfgEntry[CFG_PARAM_MAX_NUM] ; +static tANI_U32 __gCfgIBufMin[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U32 __gCfgIBufMax[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U32 __gCfgIBuf[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U8 __gCfgSBuf[CFG_STA_SBUF_MAX_SIZE] ; +static tANI_U8 __gSBuffer[CFG_MAX_STR_LEN] ; +static tANI_U32 __gParamList[WNI_CFG_MAX_PARAM_NUM + + WNI_CFG_GET_PER_STA_STAT_RSP_NUM]; + +static void Notify(tpAniSirGlobal, tANI_U16, tANI_U32); + + +// --------------------------------------------------------------------- +tANI_U32 cfgNeedRestart(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return 0; + } + return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RESTART) ; +} + +// --------------------------------------------------------------------- +tANI_U32 cfgNeedReload(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return 0; + } + return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RELOAD) ; +} + +// --------------------------------------------------------------------- +/** + * wlan_cfgInit() + * + * FUNCTION: + * CFG initialization function. + * + * LOGIC: + * Please see Configuration & Statistic Collection Micro-Architecture + * specification for the pseudocode. + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * This function must be called during system initialization. + * + * @param None + * @return None. + */ + +void +wlan_cfgInit(tpAniSirGlobal pMac) +{ + // Set status to not-ready + pMac->cfg.gCfgStatus = CFG_INCOMPLETE; + + // Send CFG_DNLD_REQ to host + PELOGW(cfgLog(pMac, LOGW, FL("Sending CFG_DNLD_REQ"));) + cfgSendHostMsg(pMac, WNI_CFG_DNLD_REQ, WNI_CFG_DNLD_REQ_LEN, + WNI_CFG_DNLD_REQ_NUM, 0, 0, 0); + +} /*** end wlan_cfgInit() ***/ + + +//--------------------------------------------------------------------- +tSirRetStatus cfgInit(tpAniSirGlobal pMac) +{ + pMac->cfg.gCfgIBufMin = __gCfgIBufMin; + pMac->cfg.gCfgIBufMax = __gCfgIBufMax; + pMac->cfg.gCfgIBuf = __gCfgIBuf; + pMac->cfg.gCfgSBuf = __gCfgSBuf; + pMac->cfg.gSBuffer = __gSBuffer; + pMac->cfg.gCfgEntry = __gCfgEntry; + pMac->cfg.gParamList = __gParamList; + + return (eSIR_SUCCESS); +} + +//---------------------------------------------------------------------- +void cfgDeInit(tpAniSirGlobal pMac) +{ + pMac->cfg.gCfgIBufMin = NULL; + pMac->cfg.gCfgIBufMax = NULL; + pMac->cfg.gCfgIBuf = NULL; + pMac->cfg.gCfgSBuf = NULL; + pMac->cfg.gSBuffer = NULL; + pMac->cfg.gCfgEntry = NULL; + pMac->cfg.gParamList = NULL; +} + +// --------------------------------------------------------------------- +/** + * cfgSetInt() + * + * FUNCTION: + * This function is called to update an integer parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Range checking is performed by the calling function. In case this + * function call is being triggered by a request from host, then host + * is responsible for performing range checking before sending the + * request. + * + * - Host RW permission checking should already be done prior to calling + * this function by the message processing function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param value: 32-bit unsigned value + * + * @return eSIR_SUCCESS : request completed successfully \n + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID \n + */ + +tSirRetStatus +cfgSetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 value) +{ + tANI_U32 index; + tANI_U32 control, mask; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + return eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_IBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else if ((pMac->cfg.gCfgIBufMin[index] > value) || + (pMac->cfg.gCfgIBufMax[index] < value)) + { + PELOGE(cfgLog(pMac, LOGE, FL("Value %d out of range [%d,%d] cfg id %d"), + value, pMac->cfg.gCfgIBufMin[index], + pMac->cfg.gCfgIBufMax[index], cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + // Write integer value + pMac->cfg.gCfgIBuf[index] = value; + + // Update hardware if necessary + mask = control & CFG_CTL_NTF_MASK; + if ((mask & CFG_CTL_NTF_HW) != 0) + PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!"));) + + // Notify other modules if necessary + if ((mask & CFG_CTL_NTF_MASK) != 0) + Notify(pMac, cfgId, mask); + + } + + return (retVal); + +} /*** end cfgSetInt ***/ + +// --------------------------------------------------------------------- +/** + * cfgCheckValid() + * + * FUNCTION: + * This function is called to check if a parameter is valid + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + */ + +tSirRetStatus +cfgCheckValid(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + tANI_U32 control; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOG3(cfgLog(pMac, LOG3, FL("Invalid cfg id %d"), cfgId);) + return(eSIR_CFG_INVALID_ID); + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOG3(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + return(eSIR_CFG_INVALID_ID); + } + else + return(eSIR_SUCCESS); + +} /*** end cfgCheckValid() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetInt() + * + * FUNCTION: + * This function is called to read an integer parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pVal: address where parameter value will be written + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + */ + +tSirRetStatus +wlan_cfgGetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pValue) +{ + tANI_U32 index; + tANI_U32 control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_IBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else { + // Get integer value + if (index < CFG_STA_IBUF_MAX_SIZE) + *pValue = pMac->cfg.gCfgIBuf[index]; + } + + return (retVal); + +} /*** end wlan_cfgGetInt() ***/ + +// --------------------------------------------------------------------- +/** + * cfgSetStr() + * + * FUNCTION: + * This function is called to set a string parameter. + * + * LOGIC: + * This function invokes the cfgSetStrNotify function passing the notify + * boolean value set to TRUE. This basically means that HAL needs to be + * notified. This is true in the case of non-integrated SOC's or Libra/Volans. + * In the case of Prima the cfgSetStrNotify is invoked with the boolean value + * set to FALSE. + * + * ASSUMPTIONS: + * - always Notify has to be called + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pStr: address of string data + * @param len: string length + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus cfgSetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr, + tANI_U32 length) +{ + return cfgSetStrNotify( pMac, cfgId, pStr, length, TRUE ); +} + +// --------------------------------------------------------------------- +/** + * cfgSetStrNotify() + * + * FUNCTION: + * This function is called to set a string parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - No length checking will be performed. Should be done by calling + * module. + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pStr: address of string data + * @param len: string length + * @param notifyMod. Notify respective Module + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus +cfgSetStrNotify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr, + tANI_U32 length, int notifyMod) +{ + tANI_U8 *pDst, *pDstEnd; + tANI_U32 index, paramLen, control, mask; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + return eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid Sbuf index %d (max size %d)"), + index, CFG_STA_SBUF_MAX_SIZE);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + pDst = &pMac->cfg.gCfgSBuf[index]; + paramLen = *pDst++; + if (length > paramLen) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (>%d) cfg id %d"), + length, paramLen, cfgId);) + retVal = eSIR_CFG_INVALID_LEN; + } + else + { + *pDst++ = (tANI_U8)length; + pDstEnd = pDst + length; + while (pDst < pDstEnd) + { + *pDst++ = *pStr++; + } + + if(notifyMod) + { + // Update hardware if necessary + mask = control & CFG_CTL_NTF_MASK; + if ((mask & CFG_CTL_NTF_HW) != 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!"));) + } + + // Notify other modules if necessary + if ( (mask & CFG_CTL_NTF_MASK) != 0) + { + Notify(pMac, cfgId, mask); + } + } + } + + } + + return (retVal); + +} /*** end cfgSetStrNotify() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStr() + * + * FUNCTION: + * This function is called to get a string parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pBuf: address of string buffer + * @param pLen: address of max buffer length + * actual length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus +wlan_cfgGetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) +{ + tANI_U8 *pSrc, *pSrcEnd; + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + // Get string + pSrc = &pMac->cfg.gCfgSBuf[index]; + pSrc++; // skip over max length + if (*pLength < *pSrc) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (<%d) cfg id %d"), + *pLength, *pSrc, cfgId);) + retVal = eSIR_CFG_INVALID_LEN; + } + else + { + *pLength = *pSrc++; // save parameter length + pSrcEnd = pSrc + *pLength; + while (pSrc < pSrcEnd) + *pBuf++ = *pSrc++; + } + } + + return (retVal); + +} /*** end wlan_cfgGetStr() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStrMaxLen() + * + * FUNCTION: + * This function is called to get a string maximum length. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pLen: maximum length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * + */ + +tSirRetStatus +wlan_cfgGetStrMaxLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength) +{ + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + *pLength = pMac->cfg.gCfgSBuf[index]; + } + + return (retVal); + +} /*** end wlan_cfgGetStrMaxLen() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStrLen() + * + * FUNCTION: + * This function is called to get a string length. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pLen: current length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * + */ + +tSirRetStatus +wlan_cfgGetStrLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength) +{ + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE-1) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + *pLength = pMac->cfg.gCfgSBuf[index+1]; + } + + return (retVal); + +} /*** end wlan_cfgGetStrLen() ***/ + + + +/*------------------------------------------------------------- +\fn cfgGetDot11dTransmitPower +\brief This function returns the regulatory max transmit power +\param pMac +\return tPowerdBm - Power +\-------------------------------------------------------------*/ +static tPowerdBm +cfgGetDot11dTransmitPower(tpAniSirGlobal pMac, tANI_U16 cfgId, + tANI_U32 cfgLength, tANI_U8 channel) +{ + tANI_U8 *pCountryInfo = NULL; + tANI_U8 count = 0; + tPowerdBm maxTxPwr = WDA_MAX_TXPOWER_INVALID; + + /* At least one element is present */ + if(cfgLength < sizeof(tSirMacChanInfo)) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid CFGLENGTH %d while getting 11d txpower"), cfgLength);) + goto error; + } + + pCountryInfo = vos_mem_malloc(cfgLength); + if ( NULL == pCountryInfo ) + { + cfgLog(pMac, LOGP, FL(" failed to allocate memory")); + goto error; + } + /* The CSR will always update this CFG. The contents will be from country IE if regulatory domain + * is enabled on AP else will contain EEPROM contents + */ + if (wlan_cfgGetStr(pMac, cfgId, pCountryInfo, &cfgLength) != eSIR_SUCCESS) + { + vos_mem_free(pCountryInfo); + pCountryInfo = NULL; + + cfgLog(pMac, LOGP, FL("Failed to retrieve 11d configuration parameters while retrieving 11d tuples")); + goto error; + } + /* Identify the channel and maxtxpower */ + while(count <= (cfgLength - (sizeof(tSirMacChanInfo)))) + { + tANI_U8 firstChannel, maxChannels; + + firstChannel = pCountryInfo[count++]; + maxChannels = pCountryInfo[count++]; + maxTxPwr = pCountryInfo[count++]; + + if((channel >= firstChannel) && + (channel < (firstChannel + maxChannels))) + { + break; + } + } + +error: + if (NULL != pCountryInfo) + vos_mem_free(pCountryInfo); + + return maxTxPwr; +} + + +/**---------------------------------------------------------------------- +\fn cfgGetRegulatoryMaxTransmitPower + +\brief Gets regulatory tx power on the current channel. + +\param pMac +\param channel +\param rfBand + -----------------------------------------------------------------------*/ +tPowerdBm cfgGetRegulatoryMaxTransmitPower(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U32 cfgLength = 0; + tANI_U16 cfgId = 0; + tPowerdBm maxTxPwr; + eRfBandMode rfBand = eRF_BAND_UNKNOWN; + + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + rfBand = eRF_BAND_5_GHZ; + else + rfBand = eRF_BAND_2_4_GHZ; + + + /* Get the max transmit power for current channel for the current regulatory domain */ + switch (rfBand) + { + case eRF_BAND_2_4_GHZ: + cfgId = WNI_CFG_MAX_TX_POWER_2_4; + cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN; + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 2.4 GHz channels to get regulatory max tx power"));) + break; + + case eRF_BAND_5_GHZ: + cfgId = WNI_CFG_MAX_TX_POWER_5; + cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN; + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 5.0 GHz channels to get regulatory max tx power"));) + break; + + case eRF_BAND_UNKNOWN: + default: + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Invalid current working band for the device"));) + return WDA_MAX_TXPOWER_INVALID; //Its return, not break. + } + + maxTxPwr = cfgGetDot11dTransmitPower(pMac, cfgId, cfgLength, channel); + + return (maxTxPwr); +} + +// --------------------------------------------------------------------- +/** + * cfgGetCapabilityInfo + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tSirRetStatus +cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession sessionEntry) +{ + tANI_U32 val = 0; + tpSirMacCapabilityInfo pCapInfo; + tLimSystemRole systemRole = limGetSystemRole(sessionEntry); + + *pCap = 0; + pCapInfo = (tpSirMacCapabilityInfo) pCap; + + if (systemRole == eLIM_STA_IN_IBSS_ROLE) + pCapInfo->ibss = 1; // IBSS bit + else if ( (systemRole == eLIM_AP_ROLE) ||(systemRole == eLIM_BT_AMP_AP_ROLE)||(systemRole == eLIM_BT_AMP_STA_ROLE) || + (systemRole == eLIM_STA_ROLE) ) + pCapInfo->ess = 1; // ESS bit + else if (limGetSystemRole(sessionEntry) == eLIM_P2P_DEVICE_ROLE ) + { + pCapInfo->ess = 0; + pCapInfo->ibss = 0; + } + else + cfgLog(pMac, LOGP, FL("can't get capability, role is UNKNOWN!!")); + + + if(systemRole == eLIM_AP_ROLE) + { + val = sessionEntry->privacy; + } + else + { + // PRIVACY bit + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_PRIVACY_ENABLED failed")); + return eSIR_FAILURE; + } + } + if (val) + pCapInfo->privacy = 1; + + // Short preamble bit + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_PREAMBLE failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->shortPreamble = 1; + + + // PBCC bit + pCapInfo->pbcc = 0; + + // Channel agility bit + pCapInfo->channelAgility = 0; + //If STA/AP operating in 11B mode, don't set rest of the capability info bits. + if(sessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B) + return eSIR_SUCCESS; + + // Short slot time bit + if (systemRole == eLIM_AP_ROLE) + { + pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported; + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val) + != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, + FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed")); + return eSIR_FAILURE; + } + /* When in STA mode, we need to check if short slot is enabled as well as check if the current operating + * mode is short slot time and then decide whether to enable short slot or not. It is safe to check both + * cfg values to determine short slot value in this funcn since this funcn is always used after assoc when + * these cfg values are already set based on peer's capability. Even in case of IBSS, its value is set to + * correct value either in delBSS as part of deleting the previous IBSS or in start BSS as part of coalescing + */ + if (val) + { + pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported; + } + } + + // Spectrum Management bit + if((eLIM_STA_IN_IBSS_ROLE != systemRole) && + sessionEntry->lim11hEnable ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_11H_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->spectrumMgt = 1; + } + + // QoS bit + if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_QOS_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->qos = 1; + + // APSD bit + if (wlan_cfgGetInt(pMac, WNI_CFG_APSD_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_APSD_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->apsd = 1; + +#if defined WLAN_FEATURE_VOWIFI + if ((limGetSystemRole(sessionEntry) == eLIM_STA_ROLE) ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_RRM_ENABLED failed")); + return eSIR_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + PELOGE(cfgLog( pMac, LOGE, "RRM = %d",val );) +#endif + if (val) + pCapInfo->rrm = 1; + } +#endif + //DSSS-OFDM + //FIXME : no config defined yet. + + // Block ack bit + if (wlan_cfgGetInt(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_BLOCK_ACK_ENABLED failed")); + return eSIR_FAILURE; + } + pCapInfo->delayedBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); + pCapInfo->immediateBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * cfgSetCapabilityInfo + * + * FUNCTION: + * This function is called on BP based on the capabilities + * received in SME_JOIN/REASSOC_REQ message. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: 1. ESS/IBSS capabilities are based on system role. + * 2. Since PBCC, Channel agility and Extended capabilities + * are not supported, they're not set at CFG + * + * @param pMac Pointer to global MAC structure + * @param caps 16-bit Capability Info field + * @return None + */ + +void +cfgSetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 caps) +{ +} + + +// --------------------------------------------------------------------- +/** + * cfgCleanup() + * + * FUNCTION: + * CFG cleanup function. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * This function must be called during system shutdown. + * + * @param None + * + * @return None. + * + */ + +void +cfgCleanup(tpAniSirGlobal pMac) +{ + // Set status to not-ready + pMac->cfg.gCfgStatus = CFG_INCOMPLETE; + +} /*** end CfgCleanup() ***/ + +// --------------------------------------------------------------------- +/** + * Notify() + * + * FUNCTION: + * This function is called to notify other modules of parameter update. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: configuration parameter ID + * @param mask: notification mask + * + * @return None. + * + */ + +static void +Notify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 ntfMask) +{ + + tSirMsgQ mmhMsg; + + mmhMsg.type = SIR_CFG_PARAM_UPDATE_IND; + mmhMsg.bodyval = (tANI_U32)cfgId; + mmhMsg.bodyptr = NULL; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + + if ((ntfMask & CFG_CTL_NTF_SCH) != 0) + schPostMessage(pMac, &mmhMsg); + + if ((ntfMask & CFG_CTL_NTF_LIM) != 0) + limPostMsgApi(pMac, &mmhMsg); + + if ((ntfMask & CFG_CTL_NTF_HAL) != 0) + wdaPostCtrlMsg(pMac, &mmhMsg); + + // Notify ARQ + +} /*** end Notify() ***/ + +// --------------------------------------------------------------------- diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.c new file mode 100644 index 0000000000000..7778a54d460a4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file cfgDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + ========================================================================*/ + +#include "cfgDebug.h" + +void cfgLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if (loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_CFG_MODULE_ID )]) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_CFG_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.h new file mode 100644 index 0000000000000..26c44e9a6a6dd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDebug.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ + +#ifndef __CFG_DEBUG_H__ +#define __CFG_DEBUG_H__ + +#include "sirDebug.h" +#include "utilsApi.h" +#include "limTrace.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) cfgLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDef.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDef.h new file mode 100644 index 0000000000000..0be77c6e9f63a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgDef.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This is the private header file for CFG module. + * + * Author: Kevin Nguyen + * Date: 03/20/02 + * History:- + * 03/20/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGDEF_H +#define __CFGDEF_H + +/* + * CFG Control Flag definitions + */ +#define CFG_CTL_VALID 0x00010000 +#define CFG_CTL_RE 0x00020000 +#define CFG_CTL_WE 0x00040000 +#define CFG_CTL_INT 0x00080000 +#define CFG_CTL_SAVE 0x00100000 +#define CFG_CTL_RESTART 0x00200000 +#define CFG_CTL_RELOAD 0x00400000 +#define CFG_CTL_NTF_PHY 0x00800000 +#define CFG_CTL_NTF_MAC 0x01000000 +#define CFG_CTL_NTF_LOG 0x02000000 +#define CFG_CTL_NTF_HAL 0x04000000 +#define CFG_CTL_NTF_DPH 0x08000000 +#define CFG_CTL_NTF_ARQ 0x10000000 +#define CFG_CTL_NTF_SCH 0x20000000 +#define CFG_CTL_NTF_LIM 0x40000000 +#define CFG_CTL_NTF_HDD 0x80000000 +#define CFG_CTL_NTF_MASK 0xFFE00000 + +#define CFG_CTL_NTF_TFP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_RHP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_RFP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_SP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_HW (CFG_CTL_NTF_MAC | CFG_CTL_NTF_PHY) + +#define CFG_BUF_INDX_MASK 0x00000fff +#define CFG_SEM_INDX_MASK 0x0000f000 +#define CFG_SEM_INDX_SHIFT 12 + + +#endif /* __CFGDEF_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgParamName.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgParamName.c new file mode 100644 index 0000000000000..abaf1cab75939 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgParamName.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * DO NOT EDIT - This file is generated automatically + */ + +/* + * IMPORTANT: This file is for system that supports STA mode ONLY. + */ +#include "cfgPriv.h" + +unsigned char *gCfgParamName[] = { + (unsigned char *)"STA_ID", + (unsigned char *)"CF_POLLABLE", + (unsigned char *)"CFP_PERIOD", + (unsigned char *)"CFP_MAX_DURATION", + (unsigned char *)"SSID", + (unsigned char *)"BEACON_INTERVAL", + (unsigned char *)"DTIM_PERIOD", + (unsigned char *)"WEP_KEY_LENGTH", + (unsigned char *)"WEP_DEFAULT_KEY_1", + (unsigned char *)"WEP_DEFAULT_KEY_2", + (unsigned char *)"WEP_DEFAULT_KEY_3", + (unsigned char *)"WEP_DEFAULT_KEY_4", + (unsigned char *)"WEP_DEFAULT_KEYID", + (unsigned char *)"EXCLUDE_UNENCRYPTED", + (unsigned char *)"RTS_THRESHOLD", + (unsigned char *)"SHORT_RETRY_LIMIT", + (unsigned char *)"LONG_RETRY_LIMIT", + (unsigned char *)"FRAGMENTATION_THRESHOLD", + (unsigned char *)"ACTIVE_MINIMUM_CHANNEL_TIME", + (unsigned char *)"ACTIVE_MAXIMUM_CHANNEL_TIME", + (unsigned char *)"PASSIVE_MINIMUM_CHANNEL_TIME", + (unsigned char *)"PASSIVE_MAXIMUM_CHANNEL_TIME", + (unsigned char *)"JOIN_FAILURE_TIMEOUT", + (unsigned char *)"AUTHENTICATE_FAILURE_TIMEOUT", + (unsigned char *)"AUTHENTICATE_RSP_TIMEOUT", + (unsigned char *)"ASSOCIATION_FAILURE_TIMEOUT", + (unsigned char *)"REASSOCIATION_FAILURE_TIMEOUT", + (unsigned char *)"RA_PERIODICITY_TIMEOUT_IN_PS", + (unsigned char *)"PS_ENABLE_BCN_FILTER", + (unsigned char *)"PS_ENABLE_HEART_BEAT", + (unsigned char *)"PS_ENABLE_RSSI_MONITOR", + (unsigned char *)"PS_DATA_INACTIVITY_TIMEOUT", + (unsigned char *)"RF_SETTLING_TIME_CLK", + (unsigned char *)"SUPPORTED_RATES_11B", + (unsigned char *)"SUPPORTED_RATES_11A", + (unsigned char *)"PHY_MODE", + (unsigned char *)"DOT11_MODE", + (unsigned char *)"OPERATIONAL_RATE_SET", + (unsigned char *)"EXTENDED_OPERATIONAL_RATE_SET", + (unsigned char *)"PROPRIETARY_OPERATIONAL_RATE_SET", + (unsigned char *)"LISTEN_INTERVAL", + (unsigned char *)"VALID_CHANNEL_LIST", + (unsigned char *)"CURRENT_CHANNEL", + (unsigned char *)"DEFAULT_RATE_INDEX_5GHZ", + (unsigned char *)"DEFAULT_RATE_INDEX_24GHZ", + (unsigned char *)"RATE_ADAPTATION_TYPE", + (unsigned char *)"FIXED_RATE", + (unsigned char *)"FIXED_RATE_MULTICAST_24GHZ", + (unsigned char *)"FIXED_RATE_MULTICAST_5GHZ", + (unsigned char *)"RETRYRATE_POLICY", + (unsigned char *)"RETRYRATE_SECONDARY", + (unsigned char *)"RETRYRATE_TERTIARY", + (unsigned char *)"APSD_ENABLED", + (unsigned char *)"SHARED_KEY_AUTH_ENABLE", + (unsigned char *)"OPEN_SYSTEM_AUTH_ENABLE", + (unsigned char *)"AUTHENTICATION_TYPE", + (unsigned char *)"CF_POLL_REQUEST", + (unsigned char *)"PRIVACY_ENABLED", + (unsigned char *)"SHORT_PREAMBLE", + (unsigned char *)"SHORT_SLOT_TIME", + (unsigned char *)"ACCEPT_SHORT_SLOT_ASSOC_ONLY", + (unsigned char *)"QOS_ENABLED", + (unsigned char *)"HCF_ENABLED", + (unsigned char *)"RSN_ENABLED", + (unsigned char *)"BACKGROUND_SCAN_PERIOD", + (unsigned char *)"MAX_NUM_PRE_AUTH", + (unsigned char *)"PREAUTH_CLNUP_TIMEOUT", + (unsigned char *)"RELEASE_AID_TIMEOUT", + (unsigned char *)"HEART_BEAT_THRESHOLD", + (unsigned char *)"PROBE_AFTER_HB_FAIL_TIMEOUT", + (unsigned char *)"MANUFACTURER_OUI", + (unsigned char *)"MANUFACTURER_NAME", + (unsigned char *)"MODEL_NUMBER", + (unsigned char *)"MODEL_NAME", + (unsigned char *)"MANUFACTURER_PRODUCT_NAME", + (unsigned char *)"MANUFACTURER_PRODUCT_VERSION", + (unsigned char *)"11D_ENABLED", + (unsigned char *)"MAX_TX_POWER_2_4", + (unsigned char *)"MAX_TX_POWER_5", + (unsigned char *)"NETWORK_DENSITY", + (unsigned char *)"ADAPTIVE_THRESHOLD_ALGORITHM", + (unsigned char *)"CURRENT_TX_ANTENNA", + (unsigned char *)"CURRENT_RX_ANTENNA", + (unsigned char *)"CURRENT_TX_POWER_LEVEL", + (unsigned char *)"POWER_STATE_PER_CHAIN", + (unsigned char *)"NEW_BSS_FOUND_IND", + (unsigned char *)"PROPRIETARY_ANI_FEATURES_ENABLED", + (unsigned char *)"PROPRIETARY_RATES_ENABLED", + (unsigned char *)"AP_NODE_NAME", + (unsigned char *)"COUNTRY_CODE", + (unsigned char *)"11H_ENABLED", + (unsigned char *)"WT_CNF_TIMEOUT", + (unsigned char *)"KEEPALIVE_TIMEOUT", + (unsigned char *)"PROXIMITY", + (unsigned char *)"LOG_LEVEL", + (unsigned char *)"OLBC_DETECT_TIMEOUT", + (unsigned char *)"PROTECTION_ENABLED", + (unsigned char *)"11G_PROTECTION_ALWAYS", + (unsigned char *)"FORCE_POLICY_PROTECTION", + (unsigned char *)"11G_SHORT_PREAMBLE_ENABLED", + (unsigned char *)"11G_SHORT_SLOT_TIME_ENABLED", + (unsigned char *)"CAL_PERIOD", + (unsigned char *)"STATS_PERIOD", + (unsigned char *)"CAL_CONTROL", + (unsigned char *)"11G_ONLY_POLICY", + (unsigned char *)"PACKET_CLASSIFICATION", + (unsigned char *)"WME_ENABLED", + (unsigned char *)"ADDTS_RSP_TIMEOUT", + (unsigned char *)"MAX_SP_LENGTH", + (unsigned char *)"KEEP_ALIVE_STA_LIMIT_THRESHOLD", + (unsigned char *)"SEND_SINGLE_SSID_ALWAYS", + (unsigned char *)"WSM_ENABLED", + (unsigned char *)"PROP_CAPABILITY", + (unsigned char *)"EDCA_PROFILE", + (unsigned char *)"EDCA_ANI_ACBK_LOCAL", + (unsigned char *)"EDCA_ANI_ACBE_LOCAL", + (unsigned char *)"EDCA_ANI_ACVI_LOCAL", + (unsigned char *)"EDCA_ANI_ACVO_LOCAL", + (unsigned char *)"EDCA_ANI_ACBK", + (unsigned char *)"EDCA_ANI_ACBE", + (unsigned char *)"EDCA_ANI_ACVI", + (unsigned char *)"EDCA_ANI_ACVO", + (unsigned char *)"EDCA_WME_ACBK_LOCAL", + (unsigned char *)"EDCA_WME_ACBE_LOCAL", + (unsigned char *)"EDCA_WME_ACVI_LOCAL", + (unsigned char *)"EDCA_WME_ACVO_LOCAL", + (unsigned char *)"EDCA_WME_ACBK", + (unsigned char *)"EDCA_WME_ACBE", + (unsigned char *)"EDCA_WME_ACVI", + (unsigned char *)"EDCA_WME_ACVO", + (unsigned char *)"EDCA_TIT_DEMO_ACBK_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACBE_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACVI_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACVO_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACBK", + (unsigned char *)"EDCA_TIT_DEMO_ACBE", + (unsigned char *)"EDCA_TIT_DEMO_ACVI", + (unsigned char *)"EDCA_TIT_DEMO_ACVO", + (unsigned char *)"RDET_FLAG", + (unsigned char *)"RADAR_CHANNEL_LIST", + (unsigned char *)"LOCAL_POWER_CONSTRAINT", + (unsigned char *)"ADMIT_POLICY", + (unsigned char *)"ADMIT_BWFACTOR", + (unsigned char *)"MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE", + (unsigned char *)"CHANNEL_BONDING_MODE", + (unsigned char *)"CB_SECONDARY_CHANNEL_STATE", + (unsigned char *)"DYNAMIC_THRESHOLD_ZERO", + (unsigned char *)"DYNAMIC_THRESHOLD_ONE", + (unsigned char *)"DYNAMIC_THRESHOLD_TWO", + (unsigned char *)"TRIG_STA_BK_SCAN", + (unsigned char *)"DYNAMIC_PROFILE_SWITCHING", + (unsigned char *)"SCAN_CONTROL_LIST", + (unsigned char *)"MIMO_ENABLED", + (unsigned char *)"BLOCK_ACK_ENABLED", + (unsigned char *)"BA_ACTIVITY_CHECK_TIMEOUT", + (unsigned char *)"HT_RX_STBC", + (unsigned char *)"HT_CAP_INFO", + (unsigned char *)"HT_AMPDU_PARAMS", + (unsigned char *)"SUPPORTED_MCS_SET", + (unsigned char *)"EXT_HT_CAP_INFO", + (unsigned char *)"TX_BF_CAP", + (unsigned char *)"AS_CAP", + (unsigned char *)"HT_INFO_FIELD1", + (unsigned char *)"HT_INFO_FIELD2", + (unsigned char *)"HT_INFO_FIELD3", + (unsigned char *)"BASIC_MCS_SET", + (unsigned char *)"CURRENT_MCS_SET", + (unsigned char *)"GREENFIELD_CAPABILITY", + (unsigned char *)"VHT_MAX_MPDU_LENGTH", + (unsigned char *)"VHT_SUPPORTED_CHAN_WIDTH_SET", + (unsigned char *)"VHT_LDPC_CODING_CAP", + (unsigned char *)"VHT_SHORT_GI_80MHZ", + (unsigned char *)"VHT_SHORT_GI_160_AND_80_PLUS_80MHZ", + (unsigned char *)"VHT_TXSTBC", + (unsigned char *)"VHT_RXSTBC", + (unsigned char *)"VHT_SU_BEAMFORMER_CAP", + (unsigned char *)"VHT_SU_BEAMFORMEE_CAP", + (unsigned char *)"VHT_CSN_BEAMFORMEE_ANT_SUPPORTED", + (unsigned char *)"VHT_NUM_SOUNDING_DIMENSIONS", + (unsigned char *)"VHT_MU_BEAMFORMER_CAP", + (unsigned char *)"VHT_MU_BEAMFORMEE_CAP", + (unsigned char *)"VHT_TXOP_PS", + (unsigned char *)"VHT_HTC_VHTC_CAP", + (unsigned char *)"VHT_AMPDU_LEN_EXPONENT", + (unsigned char *)"VHT_LINK_ADAPTATION_CAP", + (unsigned char *)"VHT_RX_ANT_PATTERN", + (unsigned char *)"VHT_TX_ANT_PATTERN", + (unsigned char *)"VHT_RX_MCS_MAP", + (unsigned char *)"VHT_TX_MCS_MAP", + (unsigned char *)"VHT_RX_HIGHEST_SUPPORTED_DATA_RATE", + (unsigned char *)"VHT_TX_HIGHEST_SUPPORTED_DATA_RATE", + (unsigned char *)"VHT_CHANNEL_WIDTH", + (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT1", + (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT2", + (unsigned char *)"VHT_BASIC_MCS_SET", + (unsigned char *)"VHT_MU_MIMO_CAP_STA_COUNT", + (unsigned char *)"VHT_SS_UNDER_UTIL", + (unsigned char *)"VHT_40MHZ_UTILIZATION", + (unsigned char *)"VHT_80MHZ_UTILIZATION", + (unsigned char *)"VHT_160MHZ_UTILIZATION", + (unsigned char *)"MAX_AMSDU_LENGTH", + (unsigned char *)"MPDU_DENSITY", + (unsigned char *)"NUM_BUFF_ADVERT", + (unsigned char *)"MAX_RX_AMPDU_FACTOR", + (unsigned char *)"SHORT_GI_20MHZ", + (unsigned char *)"SHORT_GI_40MHZ", + (unsigned char *)"RIFS_ENABLED", + (unsigned char *)"MAX_PS_POLL", + (unsigned char *)"NUM_BEACON_PER_RSSI_AVERAGE", + (unsigned char *)"RSSI_FILTER_PERIOD", + (unsigned char *)"MIN_RSSI_THRESHOLD", + (unsigned char *)"NTH_BEACON_FILTER", + (unsigned char *)"BROADCAST_FRAME_FILTER_ENABLE", + (unsigned char *)"SCAN_IN_POWERSAVE", + (unsigned char *)"IGNORE_DTIM", + (unsigned char *)"WOWLAN_UCAST_PATTERN_FILTER_ENABLE", + (unsigned char *)"WOWLAN_CHANNEL_SWITCH_ENABLE", + (unsigned char *)"WOWLAN_DEAUTH_ENABLE", + (unsigned char *)"WOWLAN_DISASSOC_ENABLE", + (unsigned char *)"WOWLAN_MAX_MISSED_BEACON", + (unsigned char *)"WOWLAN_MAX_SLEEP_PERIOD", + (unsigned char *)"BA_TIMEOUT", + (unsigned char *)"BA_THRESHOLD_HIGH", + (unsigned char *)"MAX_BA_BUFFERS", + (unsigned char *)"MAX_BA_SESSIONS", + (unsigned char *)"BA_AUTO_SETUP", + (unsigned char *)"ADDBA_REQ_DECLINE", + (unsigned char *)"DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC", + (unsigned char *)"BG_SCAN_CHANNEL_LIST", + (unsigned char *)"MAX_MEDIUM_TIME", + (unsigned char *)"MAX_MPDUS_IN_AMPDU", + (unsigned char *)"IBSS_AUTO_BSSID", + (unsigned char *)"PROBE_REQ_ADDNIE_FLAG", + (unsigned char *)"PROBE_REQ_ADDNIE_DATA", + (unsigned char *)"PROBE_RSP_ADDNIE_FLAG", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA1", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA2", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA3", + (unsigned char *)"ASSOC_RSP_ADDNIE_FLAG", + (unsigned char *)"ASSOC_RSP_ADDNIE_DATA", + (unsigned char *)"PROBE_REQ_ADDNP2PIE_FLAG", + (unsigned char *)"PROBE_REQ_ADDNP2PIE_DATA", + (unsigned char *)"PROBE_RSP_BCN_ADDNIE_FLAG", + (unsigned char *)"PROBE_RSP_BCN_ADDNIE_DATA", + (unsigned char *)"WPS_ENABLE", + (unsigned char *)"WPS_STATE", + (unsigned char *)"WPS_PROBE_REQ_FLAG", + (unsigned char *)"WPS_VERSION", + (unsigned char *)"WPS_REQUEST_TYPE", + (unsigned char *)"WPS_CFG_METHOD", + (unsigned char *)"WPS_UUID", + (unsigned char *)"WPS_PRIMARY_DEVICE_CATEGORY", + (unsigned char *)"WPS_PIMARY_DEVICE_OUI", + (unsigned char *)"WPS_DEVICE_SUB_CATEGORY", + (unsigned char *)"WPS_ASSOCIATION_STATE", + (unsigned char *)"WPS_CONFIGURATION_ERROR", + (unsigned char *)"WPS_DEVICE_PASSWORD_ID", + (unsigned char *)"WPS_ASSOC_METHOD", + (unsigned char *)"LOW_GAIN_OVERRIDE", + (unsigned char *)"ENABLE_PHY_AGC_LISTEN_MODE", + (unsigned char *)"RPE_POLLING_THRESHOLD", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC0_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC1_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC2_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC3_REG", + (unsigned char *)"NO_OF_ONCHIP_REORDER_SESSIONS", + (unsigned char *)"SINGLE_TID_RC", + (unsigned char *)"RRM_ENABLED", + (unsigned char *)"RRM_OPERATING_CHAN_MAX", + (unsigned char *)"RRM_NON_OPERATING_CHAN_MAX", + (unsigned char *)"TX_PWR_CTRL_ENABLE", + (unsigned char *)"MCAST_BCAST_FILTER_SETTING", + (unsigned char *)"BTC_DHCP_BT_SLOTS_TO_BLOCK", + (unsigned char *)"DYNAMIC_PS_POLL_VALUE", + (unsigned char *)"PS_NULLDATA_AP_RESP_TIMEOUT", + (unsigned char *)"TELE_BCN_WAKEUP_EN", + (unsigned char *)"TELE_BCN_TRANS_LI", + (unsigned char *)"TELE_BCN_TRANS_LI_IDLE_BCNS", + (unsigned char *)"TELE_BCN_MAX_LI", + (unsigned char *)"TELE_BCN_MAX_LI_IDLE_BCNS", + (unsigned char *)"BTC_A2DP_DHCP_BT_SUB_INTERVALS", + (unsigned char *)"INFRA_STA_KEEP_ALIVE_PERIOD", + (unsigned char *)"ASSOC_STA_LIMIT", + (unsigned char *)"SAP_CHANNEL_SELECT_START_CHANNEL", + (unsigned char *)"SAP_CHANNEL_SELECT_END_CHANNEL", + (unsigned char *)"SAP_CHANNEL_SELECT_OPERATING_BAND", + (unsigned char *)"AP_DATA_AVAIL_POLL_PERIOD", + (unsigned char *)"ENABLE_CLOSE_LOOP", + (unsigned char *)"ENABLE_LTE_COEX", + (unsigned char *)"AP_KEEP_ALIVE_TIMEOUT", + (unsigned char *)"GO_KEEP_ALIVE_TIMEOUT", + (unsigned char *)"ENABLE_MC_ADDR_LIST", + (unsigned char *)"ENABLE_UC_FILTER", + (unsigned char *)"ENABLE_LPWR_IMG_TRANSITION", + (unsigned char *)"ENABLE_MCC_ADAPTIVE_SCHED", + (unsigned char *)"DISABLE_LDPC_WITH_TXBF_AP", + (unsigned char *)"AP_LINK_MONITOR_TIMEOUT", + (unsigned char *)"TDLS_QOS_WMM_UAPSD_MASK", + (unsigned char *)"TDLS_BUF_STA_ENABLED", + (unsigned char *)"TDLS_PUAPSD_INACT_TIME", + (unsigned char *)"TDLS_RX_FRAME_THRESHOLD", + (unsigned char *)"PMF_SA_QUERY_MAX_RETRIES", + (unsigned char *)"PMF_SA_QUERY_RETRY_INTERVAL", + (unsigned char *)"ENABLE_ADAPT_RX_DRAIN", + (unsigned char *)"FLEX_CONNECT_POWER_FACTOR", + (unsigned char *)"ANTENNA_DIVESITY", + (unsigned char *)"GO_LINK_MONITOR_TIMEOUT", + (unsigned char *)"RMC_ACTION_PERIOD_FREQUENCY", + (unsigned char *)"CURRENT_RSSI", + (unsigned char *)"RTT3_ENABLE", + (unsigned char *)"DEBUG_P2P_REMAIN_ON_CHANNEL", + (unsigned char *)"TDLS_OFF_CHANNEL_ENABLED", + (unsigned char *)"IBSS_ATIM_WIN_SIZE", + (unsigned char *)"DFS_MASTER_ENABLED", + (unsigned char *)"VHT_ENABLE_TXBF_20MHZ", + (unsigned char *)"TDLS_WMM_MODE_ENABLED", +}; diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgPriv.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgPriv.h new file mode 100644 index 0000000000000..bec65f83ed850 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgPriv.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This is the private header file for CFG module. + * + * Author: Kevin Nguyen + * Date: 03/20/02 + * History:- + * 03/20/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGPRIV_H +#define __CFGPRIV_H + +#include +#include +#include +#include +#include +#include +#include +#include "cfgDef.h" + + #include + +/*--------------------------------------------------------------------*/ +/* CFG miscellaneous definition */ +/*--------------------------------------------------------------------*/ + +// Function index bit mask +#define CFG_FUNC_INDX_MASK 0x7f +#define CFG_GET_FUNC_INDX(val) (val & CFG_FUNC_INDX_MASK) + +// Macro to convert return code to debug string index +#define CFG_GET_DBG_INDX(val) (val - eCFG_SUCCESS - 1) + + +/*--------------------------------------------------------------------*/ +/* Binary header structure */ +/*--------------------------------------------------------------------*/ +typedef struct sCfgBinHdr +{ + tANI_U32 hdrInfo; + tANI_U32 controlSize; + tANI_U32 iBufSize; + tANI_U32 sBufSize; +} tCfgBinHdr, *tpCfgBinHdr; + + +/*--------------------------------------------------------------------*/ +/* Polaris HW counter access structure */ +/*--------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 addr; + tANI_U32 mask; + tANI_U32 shift; +} tCfgHwCnt; + + +#define CFG_STAT_CNT_LO_MASK 0x0000ffff +#define CFG_STAT_CNT_HI_MASK 0xffff0000 +#define CFG_STAT_CNT_HI_INCR 0x00010000 + +/*--------------------------------------------------------------------*/ +/* CFG function prototypes */ +/*--------------------------------------------------------------------*/ + +extern void cfgSendHostMsg(tpAniSirGlobal, tANI_U16, tANI_U32, tANI_U32, tANI_U32*, tANI_U32, tANI_U32*); + + + + + + +#endif /* __CFGPRIV_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c new file mode 100644 index 0000000000000..09d0080af7227 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgProcMsg.c @@ -0,0 +1,919 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file contains CFG functions for processing host messages. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "cfgPriv.h" +#include "cfgDebug.h" +#include "wlan_qct_wda.h" + + +/*--------------------------------------------------------------------*/ +/* Static function prototypes */ +/*--------------------------------------------------------------------*/ +static void ProcDnldRsp (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcGetReq (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcSetReq (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcSetReqNoRsp (tpAniSirGlobal, tANI_U16, tANI_U32*); + +static tANI_U8 CheckParam(tpAniSirGlobal, tANI_U16, tANI_U32, tANI_U32, tANI_U32*); +static void GetStrValue(tANI_U8*, tANI_U8*, tANI_U32); + + +/*--------------------------------------------------------------------*/ +/* Module global variables */ +/*--------------------------------------------------------------------*/ + +// CFG function table +void (*gCfgFunc[])(tpAniSirGlobal, tANI_U16, tANI_U32*) = +{ ProcDnldRsp, + ProcGetReq, + ProcSetReq, + ProcSetReqNoRsp +}; + +/**--------------------------------------------------------------------- + * cfgProcessMbMsg() + * + *FUNCTION: + * CFG mailbox message processing function. + * + *LOGIC: + * + *ASSUMPTIONS: + * None. + * + *NOTE: + * + * @param pMsg Message pointer + * + * @return None. + * + */ +void +cfgProcessMbMsg(tpAniSirGlobal pMac, tSirMbMsg *pMsg) +{ + tANI_U16 index; + tANI_U16 len; + tANI_U32 *pParam; + + // Use type[7:0] as index to function table + index = CFG_GET_FUNC_INDX(pMsg->type); + + if (index >= (sizeof(gCfgFunc) / sizeof(gCfgFunc[0]))) + { + vos_mem_free(pMsg); + return; + } + len = pMsg->msgLen - WNI_CFG_MB_HDR_LEN; + pParam = ((tANI_U32*)pMsg) + 1; + + // Call processing function + gCfgFunc[index](pMac, len, pParam); + + // Free up buffer + vos_mem_free(pMsg); + +} /*** end cfgProcessMbMsg() ***/ + +/**--------------------------------------------------------------------- + * ProcDnldRsp() + * + * FUNCTION: + * This function processes CFG_DNLD_RSP message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param length: message length + * @param pParam: parameter list pointer + * + * @return None + * + */ +static void +ProcDnldRsp(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + tANI_S32 i; + + tANI_U32 expLen, retVal, bufStart, bufEnd; + tANI_U32 *pSrc, *pDst, *pDstEnd; + tANI_U32 strSize, j; + tANI_U8 pStr[CFG_MAX_STR_LEN]; + tpCfgBinHdr pHdr; + tANI_U32 logLevel; + tSirMsgQ mmhMsg; + + // First Dword must contain the AP or STA magic dword + PELOGW(cfgLog(pMac, LOGW, FL("CFG size %d bytes MAGIC dword is 0x%x"), + length, sirReadU32N((tANI_U8*)pParam) );) + + // if the string is not correct, return failure + if (*pParam == CFG_STA_MAGIC_DWORD) {} + + + + + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid magic dword 0x%x"),sirReadU32N((tANI_U8*)pParam) );) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + pParam++; + length -= 4; + + // Verify message length + { + pMac->cfg.gCfgMaxIBufSize = CFG_STA_IBUF_MAX_SIZE; + pMac->cfg.gCfgMaxSBufSize = CFG_STA_SBUF_MAX_SIZE; + } + + // Parse the Cfg header + pHdr = (tpCfgBinHdr) pParam; + pParam += (sizeof(tCfgBinHdr) >> 2); + PELOGW(cfgLog(pMac, LOGW, FL("CFG hdr totParams %d intParams %d strBufSize %d/%d"), + pHdr->controlSize, pHdr->iBufSize, pHdr->sBufSize, pMac->cfg.gCfgMaxSBufSize);) + + expLen = ((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) + + pHdr->sBufSize + sizeof(tCfgBinHdr); + + if (length != expLen) + { + PELOGE(cfgLog(pMac, LOGE, FL(" DNLD_RSP invalid length %d (exp %d)"), + length, expLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + + if (pHdr->controlSize != CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Total parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + if (pHdr->iBufSize != pMac->cfg.gCfgMaxIBufSize) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Integer parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + // Copy control array + pDst = (tANI_U32*)pMac->cfg.gCfgEntry; + pDstEnd = pDst + CFG_PARAM_MAX_NUM; + pSrc = pParam; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + // Copy default values + pDst = pMac->cfg.gCfgIBuf; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy min values + pDst = pMac->cfg.gCfgIBufMin; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy max values + pDst = pMac->cfg.gCfgIBufMax; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + for (i=0; icfg.gCfgMaxIBufSize; i++) + if (pMac->cfg.gCfgIBuf[i] < pMac->cfg.gCfgIBufMin[i] || + pMac->cfg.gCfgIBuf[i] > pMac->cfg.gCfgIBufMax[i]) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg id %d Invalid def value %d " + "min %d max %d"), + i, pMac->cfg.gCfgIBuf[i], pMac->cfg.gCfgIBufMin[i], + pMac->cfg.gCfgIBufMax[i]);) + } + + // Calculate max string buffer lengths for all string parameters + bufEnd = pMac->cfg.gCfgMaxSBufSize; + for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) + { + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) + continue; + + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) + continue; + + bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK; + pMac->cfg.gCfgSBuf[bufStart] = (tANI_U8)(bufEnd - bufStart - 2); + + PELOG1(cfgLog(pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"), + i, pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);) + + bufEnd = bufStart; + } + + // Initialize string defaults + strSize = pHdr->sBufSize; + while (strSize) + { + tANI_U32 paramId, paramLen, paramLenCeil4; + + if (strSize < 4) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d bytes"), strSize);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + paramId = *pSrc >> 16; + paramLen = *pSrc & 0xff; + pSrc++; + strSize -= 4; + + paramLenCeil4 = ((paramLen + 3) >> 2); + if (strSize < paramLenCeil4 << 2) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d bytes"), strSize);) + PELOGE(cfgLog(pMac, LOGE, FL("param id %d len %d bytes"), paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + for (j=0; j < paramLenCeil4; j++) + { + pStr[4*j] = (tANI_U8) (*pSrc >> 24) & 0xff; + pStr[4*j+1] = (tANI_U8) (*pSrc >> 16) & 0xff; + pStr[4*j+2] = (tANI_U8) (*pSrc >> 8) & 0xff; + pStr[4*j+3] = (tANI_U8) (*pSrc) & 0xff; + + pSrc++; + strSize -= 4; + } + + PELOG1(cfgLog(pMac, LOG1, FL("set str id %d len %d"), paramId, paramLen);) + + if (cfgSetStr(pMac, (tANI_U16) paramId, pStr, paramLen) != eSIR_SUCCESS) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error setting str default param %d len %d"), paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + } + + // Set the default log level based on config + wlan_cfgGetInt(pMac, WNI_CFG_LOG_LEVEL, &logLevel); + for (i = 0; i < LOG_ENTRY_NUM; i++) + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = logLevel; + + // Set status to READY + pMac->cfg.gCfgStatus = CFG_SUCCESS; + retVal = WNI_CFG_SUCCESS; + PELOG1(cfgLog(pMac, LOG1, " Completed successfully");) + + end: + + if ( retVal != WNI_CFG_SUCCESS ) + pMac->cfg.gCfgStatus = CFG_FAILURE; + + // Send response message to host + pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal; + cfgSendHostMsg(pMac, WNI_CFG_DNLD_CNF, WNI_CFG_DNLD_CNF_LEN, + WNI_CFG_DNLD_CNF_NUM, pMac->cfg.gParamList, 0, 0); + + // Notify WDA that the config has downloaded + mmhMsg.type = SIR_CFG_DOWNLOAD_COMPLETE_IND; + mmhMsg.bodyptr = NULL; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + if (wdaPostCtrlMsg(pMac, &mmhMsg) != eSIR_SUCCESS) + { + PELOGE(cfgLog(pMac, LOGE, FL("WDAPostMsgApi failed!"));) + } + +} /*** end procDnldRsp() ***/ + + +/**--------------------------------------------------------------------- + * ProcGetReq() + * + * FUNCTION: + * This function processes CFG_GET_REQ message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * For every parameter ID specified on the list, CFG will send a separate + * CFG_GET_RSP back to host. + * + * @param length: message length + * @param pParam: parameter list pointer + * + * @return None + * + */ +static void +ProcGetReq(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + tANI_U16 cfgId, i; + tANI_U32 value, valueLen, result; + tANI_U32 *pValue; + + PELOG1(cfgLog(pMac, LOG1, FL("Rcvd cfg get request %d bytes"), length);) + for (i=0; icfg.gCfgStatus) + { + cfgId = (tANI_U16)sirReadU32N((tANI_U8*)pParam); + PELOGE(cfgLog(pMac, LOGE, FL("CFG not ready, param %d"), cfgId);) + pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] = WNI_CFG_NOT_READY; + pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId; + pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = 0; + cfgSendHostMsg(pMac, WNI_CFG_GET_RSP, WNI_CFG_GET_RSP_PARTIAL_LEN, + WNI_CFG_GET_RSP_NUM, pMac->cfg.gParamList, 0, 0); + } + else + { + // Process all parameter ID's on the list + while (length >= sizeof(tANI_U32)) + { + cfgId = (tANI_U16)*pParam++; + pValue = 0; + valueLen = 0; + + PELOG1(cfgLog(pMac, LOG1, FL("Cfg get param %d"), cfgId);) + + // Check for valid parameter ID, etc... + if (CheckParam(pMac, cfgId, CFG_CTL_RE, WNI_CFG_WO_PARAM, &result)) + { + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + // Get integer parameter + result = (wlan_cfgGetInt(pMac, cfgId, &value) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + pValue = &value; + valueLen = sizeof(tANI_U32); + } + else + { + // Get string parameter + valueLen = sizeof(pMac->cfg.gSBuffer); + result = (wlan_cfgGetStr(pMac, cfgId, pMac->cfg.gSBuffer, &valueLen) + == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + pValue = (tANI_U32*)pMac->cfg.gSBuffer; + } + } + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Check param failed, param %d"), cfgId);) + result = WNI_CFG_INVALID_LEN; + } + + // Send response message to host + pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] = result; + pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId; + pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = valueLen; + + // We need to round up buffer length to word-increment + valueLen = (((valueLen + 3) >> 2) << 2); + cfgSendHostMsg(pMac, WNI_CFG_GET_RSP, + WNI_CFG_GET_RSP_PARTIAL_LEN + valueLen, + WNI_CFG_GET_RSP_NUM, pMac->cfg.gParamList, valueLen, pValue); + + // Decrement length + length -= sizeof(tANI_U32); + } + } + +} /*** end procGetReq() ***/ + + + +/**--------------------------------------------------------------------- + * ProcSetReqInternal() + * + * FUNCTION: + * This function processes CFG_SET_REQ message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * - The message content is coded in TLV format. + * - For string parameter, the length field is byte accurate. However, + * the next TLV set will begin on the next word boundary. + * + * NOTE: + * - For every parameter ID specified on the list, CFG will send a separate + * CFG_SET_RSP back to host. + * + * @param length: message length + * @param pParam: parameter list pointer + * @param fRsp: whether to send response to host. TRUE means sending. + * @return None + * + */ +static void +ProcSetReqInternal(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam, tANI_BOOLEAN fRsp) +{ + tANI_U16 cfgId, valueLen, valueLenRoundedUp4; + tANI_U32 value, result; + + PELOG1(cfgLog(pMac, LOGl, FL("Rcvd cfg set request %d bytes"), length);) + + if (!pMac->cfg.gCfgStatus) + { + cfgId = (tANI_U16)sirReadU32N((tANI_U8*)pParam); + PELOG1(cfgLog(pMac, LOGW, FL("CFG not ready, param %d"), cfgId);) + pMac->cfg.gParamList[WNI_CFG_SET_CNF_RES] = WNI_CFG_NOT_READY; + pMac->cfg.gParamList[WNI_CFG_SET_CNF_PID] = cfgId; + if( fRsp ) + { + cfgSendHostMsg(pMac, WNI_CFG_SET_CNF, WNI_CFG_SET_CNF_LEN, + WNI_CFG_SET_CNF_NUM, pMac->cfg.gParamList, 0, 0); + } + } + else + { + // Process all TLVs in buffer + while (length >= (sizeof(tANI_U32) * 2)) + { + cfgId = (tANI_U16) *pParam++; + valueLen = (tANI_U16) *pParam++; + length -= (sizeof(tANI_U32) * 2); + // value length rounded up to a 4 byte multiple + valueLenRoundedUp4 = (((valueLen + 3) >> 2) << 2); + + // Check for valid request before proceeding + if (CheckParam(pMac, cfgId, CFG_CTL_WE, WNI_CFG_RO_PARAM, &result)) + { + PELOG1(cfgLog(pMac, LOGW, (char *) gCfgParamName[cfgId]);) + // Process integer parameter + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + // Set VALUE + if (valueLen != sizeof(tANI_U32)) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid value length %d in set param %d (tot %d)"), + valueLen, cfgId, length);) + result = WNI_CFG_INVALID_LEN; + } + else + { + value = *pParam; + PELOG1(cfgLog(pMac, LOGW, FL("Cfg set int %d len %d(%d) val %d"), + cfgId, valueLen, valueLenRoundedUp4, value);) + result = (cfgSetInt(pMac, cfgId, value) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + if (result == WNI_CFG_SUCCESS) + { + if (cfgNeedRestart(pMac, cfgId)) + { + result = WNI_CFG_NEED_RESTART ; + } + else + if (cfgNeedReload(pMac, cfgId)) + { + result = WNI_CFG_NEED_RELOAD ; + } + } + } + } + // Process string parameter + else + { + if (valueLenRoundedUp4 > length) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid string length %d" + "in set param %d (tot %d)"), valueLen, + cfgId, length);) + result = WNI_CFG_INVALID_LEN; + } + else + { + GetStrValue((tANI_U8*)pParam, pMac->cfg.gSBuffer, valueLen); + PELOG1(cfgLog(pMac, LOGW, FL("Cfg set str %d len %d(%d) bytes"), + cfgId, valueLen, valueLenRoundedUp4);) + result = (cfgSetStr(pMac, cfgId, pMac->cfg.gSBuffer, valueLen) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + if (result == WNI_CFG_SUCCESS) + { + if (cfgNeedRestart(pMac, cfgId)) + { + result = WNI_CFG_NEED_RESTART ; + } + else + if (cfgNeedReload(pMac, cfgId)) + { + result = WNI_CFG_NEED_RELOAD ; + } + } + } + } + } + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Check param failed, param %d"), cfgId);) + result = WNI_CFG_INVALID_LEN; + } + + // Send confirm message to host + pMac->cfg.gParamList[WNI_CFG_SET_CNF_RES] = result; + pMac->cfg.gParamList[WNI_CFG_SET_CNF_PID] = cfgId; + if( fRsp ) + { + cfgSendHostMsg(pMac, WNI_CFG_SET_CNF, WNI_CFG_SET_CNF_LEN, + WNI_CFG_SET_CNF_NUM, pMac->cfg.gParamList, 0, 0); + } + else + { + PELOGW(cfgLog( pMac, LOG2, " CFGID %d no rsp", cfgId);) + } + + if (valueLenRoundedUp4 > length) + length = 0; + else + { + length -= valueLenRoundedUp4; + pParam += (valueLenRoundedUp4 >> 2); + } + } + } +} + + + +static void +ProcSetReq(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + ProcSetReqInternal( pMac, length, pParam, eANI_BOOLEAN_TRUE ); +} + +static void +ProcSetReqNoRsp(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + ProcSetReqInternal( pMac, length, pParam, eANI_BOOLEAN_FALSE ); +} + + + +/**--------------------------------------------------------------------- + * CheckParam() + * + * FUNCTION: + * This function is called to perform various check on a parameter. + * + * LOGIC: + * - If cfgId is out of bound or parameter is not valid, result + * WNI_CFG_INVALID_PID is returned at address specified in pResult. + * + * - If specified 'flag' is not set in the parameter control entry, + * 'failedResult' is returned at address specified in pResult. + * + * ASSUMPTIONS: + * Since this function is used internally, 'pResult' is always valid. + * + * NOTE: + * + * @param None + * + * @return true: Parameter is valid and matches checked condition \n + * @return false: Parameter either is not valid or does not match + * checked condition. + * + */ +static tANI_U8 +CheckParam(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 flag, tANI_U32 failedResult, tANI_U32 *pResult) +{ + // Check if parameter ID is out of bound + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid param id %d"), cfgId);) + *pResult = WNI_CFG_INVALID_PID; + } + else + { + // Check if parameter is valid + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Param id %d not valid"), cfgId);) + *pResult = WNI_CFG_INVALID_PID; + } + else + { + // Check control field against flag + if ((pMac->cfg.gCfgEntry[cfgId].control & flag) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Param id %d wrong permissions %x"), + cfgId, pMac->cfg.gCfgEntry[cfgId].control);) + *pResult = failedResult; + } + else + return(true); + } + } + return(false); + +} /*** cfgParamCheck() ***/ + + +/**--------------------------------------------------------------------- + * GetStrValue() + * + * FUNCTION: + * This function copies a string value from the specified buffer. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBuf: input data buffer + * @param pValue: address where data is returned + * @param length: number of bytes to copy + * + * @return None + * + */ +static void +GetStrValue(tANI_U8 *pBuf, tANI_U8 *pValue, tANI_U32 length) +{ + tANI_U8 *pEnd; + + pEnd = pValue + length; + while (pValue < pEnd) + *pValue++ = *pBuf++; +} /*** end GetStrValue() ***/ + + +/**--------------------------------------------------------------------- + * processCfgDownloadReq() + * + * FUNCTION: This function does the Cfg Download and is invoked + * only in the case of Prima or the Integrated SOC + * solutions. Not applicable to Volans or Libra + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param length: message length + * @param pConfig: parameter list pointer + * + * @return None + * + */ + +void +processCfgDownloadReq(tpAniSirGlobal pMac, tANI_U16 length, + tANI_U32 *pConfig) +{ + tANI_S32 i; + + tANI_U32 expLen, retVal, bufStart, bufEnd; + tANI_U32 *pSrc, *pDst, *pDstEnd; + tANI_U32 strSize, j; + tANI_U8 pStr[CFG_MAX_STR_LEN]; + tpCfgBinHdr pHdr; + tANI_U32 logLevel; + + // First Dword must contain the AP or STA magic dword + PELOGW(cfgLog(pMac, LOGW, FL("CFG size %d bytes MAGIC dword is 0x%x"), + length, sirReadU32N((tANI_U8*)pConfig) );) + + // if the string is not correct, return failure + if (CFG_STA_MAGIC_DWORD != *pConfig) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid magic dword 0x%x"), + sirReadU32N((tANI_U8*)pConfig) );) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + pConfig++; + length -= 4; + + // Verify message length + pMac->cfg.gCfgMaxIBufSize = CFG_STA_IBUF_MAX_SIZE; + pMac->cfg.gCfgMaxSBufSize = CFG_STA_SBUF_MAX_SIZE; + + // Parse the Cfg header + pHdr = (tpCfgBinHdr) pConfig; + pConfig += (sizeof(tCfgBinHdr) >> 2); + + PELOGW(cfgLog(pMac, LOGW, FL("CFG hdr totParams %d intParams %d strBufSize %d/%d"), + pHdr->controlSize,pHdr->iBufSize, + pHdr->sBufSize, pMac->cfg.gCfgMaxSBufSize);) + + expLen = ((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) + + pHdr->sBufSize + sizeof(tCfgBinHdr); + + if (length != expLen) + { + PELOGE(cfgLog(pMac, LOGE, FL(" DNLD_RSP invalid length %d (exp %d)"), + length, expLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + + if (CFG_PARAM_MAX_NUM != pHdr->controlSize ) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Total parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + if (pHdr->iBufSize != pMac->cfg.gCfgMaxIBufSize) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Integer parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + // Copy control array + pDst = (tANI_U32*)pMac->cfg.gCfgEntry; + pDstEnd = pDst + CFG_PARAM_MAX_NUM; + pSrc = pConfig; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy default values + pDst = pMac->cfg.gCfgIBuf; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy min values + pDst = pMac->cfg.gCfgIBufMin; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy max values + pDst = pMac->cfg.gCfgIBufMax; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + for (i=0; icfg.gCfgMaxIBufSize; i++) + { + if (pMac->cfg.gCfgIBuf[i] < pMac->cfg.gCfgIBufMin[i] || + pMac->cfg.gCfgIBuf[i] > pMac->cfg.gCfgIBufMax[i]) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg id %d Invalid def value %d " + "min %d max %d"), + i, pMac->cfg.gCfgIBuf[i], pMac->cfg.gCfgIBufMin[i], + pMac->cfg.gCfgIBufMax[i]);) + } + } + + // Calculate max string buffer lengths for all string parameters + bufEnd = pMac->cfg.gCfgMaxSBufSize; + for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) + { + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) + continue; + + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) + continue; + + bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK; + pMac->cfg.gCfgSBuf[bufStart] = (tANI_U8)(bufEnd - bufStart - 2); + + PELOG1(cfgLog(pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"), + i, pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);) + + bufEnd = bufStart; + } + + // Initialize string defaults + strSize = pHdr->sBufSize; + while (strSize) + { + tANI_U32 paramId, paramLen, paramLenCeil4; + + if (strSize < 4) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d bytes"), + strSize);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + paramId = *pSrc >> 16; + paramLen = *pSrc & 0xff; + + pSrc++; + strSize -= 4; + + paramLenCeil4 = ((paramLen + 3) >> 2); + if (strSize < paramLenCeil4 << 2) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d" + "bytes"), strSize);) + PELOGE(cfgLog(pMac, LOGE, FL("param id %d len %d bytes"), + paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + for (j=0; j < paramLenCeil4; j++) + { + pStr[4*j] = (tANI_U8) (*pSrc >> 24) & 0xff; + pStr[4*j+1] = (tANI_U8) (*pSrc >> 16) & 0xff; + pStr[4*j+2] = (tANI_U8) (*pSrc >> 8) & 0xff; + pStr[4*j+3] = (tANI_U8) (*pSrc) & 0xff; + + pSrc++; + strSize -= 4; + } + + PELOG1(cfgLog(pMac, LOG1, FL("set str id %d len %d"), paramId, paramLen);) + + if (cfgSetStrNotify(pMac, (tANI_U16)paramId, pStr, paramLen, FALSE) != eSIR_SUCCESS) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error setting str default param %d " + "len %d"), paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + } + + // Set the default log level based on config + wlan_cfgGetInt(pMac, WNI_CFG_LOG_LEVEL, &logLevel); + for (i = 0; i < LOG_ENTRY_NUM; i++) + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = logLevel; + + // Set status to READY + pMac->cfg.gCfgStatus = CFG_SUCCESS; + retVal = WNI_CFG_SUCCESS; + PELOG1(cfgLog(pMac, LOG1, " Completed successfully");) + +end: + + if ( WNI_CFG_SUCCESS != retVal ) + pMac->cfg.gCfgStatus = CFG_FAILURE; + + pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal; + +} /*** end ProcessDownloadReq() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgSendMsg.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgSendMsg.c new file mode 100644 index 0000000000000..9540d20a71f28 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgSendMsg.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file contains the source code for composing and sending messages + * to host. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "cfgPriv.h" +#include "limTrace.h" +#include "cfgDebug.h" + +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); + +/*--------------------------------------------------------------------*/ +/* ATTENTION: The functions contained in this module are to be used */ +/* by CFG module ONLY. */ +/*--------------------------------------------------------------------*/ + + +/**--------------------------------------------------------------------- + * cfgSendHostMsg() + * + * FUNCTION: + * Send CNF/RSP to host. + * + * LOGIC: + * Please see Configuration & Statistic Collection Micro-Architecture + * specification for details. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param msgType: message type + * @param msgLen: message length + * @param paramNum: number of parameters + * @param pParamList: pointer to parameter list + * @param dataLen: data length + * @param pData: pointer to additional data + * + * @return None. + * + */ +void +cfgSendHostMsg(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 msgLen, tANI_U32 paramNum, tANI_U32 *pParamList, + tANI_U32 dataLen, tANI_U32 *pData) +{ + tANI_U32 *pMsg, *pEnd; + tSirMsgQ mmhMsg; + + // sanity + if ((paramNum > 0) && (NULL == pParamList)) + { + PELOGE(cfgLog(pMac, LOGE, + FL("pParamList NULL when paramNum greater than 0!"));) + return; + } + if ((dataLen > 0) && (NULL == pData)) + { + PELOGE(cfgLog(pMac, LOGE, + FL("pData NULL when dataLen greater than 0!"));) + return; + } + + // Allocate message buffer + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + PELOGE(cfgLog(pMac, LOGE, + FL("Memory allocation failure!"));) + return; + } + + // Fill in message details + mmhMsg.type = msgType; + mmhMsg.bodyptr = pMsg; + mmhMsg.bodyval = 0; + ((tSirMbMsg*)pMsg)->type = msgType; + ((tSirMbMsg*)pMsg)->msgLen = (tANI_U16)msgLen; + + switch (msgType) + { + case WNI_CFG_GET_RSP: + case WNI_CFG_PARAM_UPDATE_IND: + case WNI_CFG_DNLD_REQ: + case WNI_CFG_DNLD_CNF: + case WNI_CFG_SET_CNF: + // Fill in parameters + pMsg++; + if (NULL != pParamList) + { + pEnd = pMsg + paramNum; + while (pMsg < pEnd) + { + *pMsg++ = *pParamList++; + } + } + // Copy data if there is any + if (NULL != pData) + { + pEnd = pMsg + (dataLen >> 2); + while (pMsg < pEnd) + { + *pMsg++ = *pData++; + } + } + break; + + default: + PELOGE(cfgLog(pMac, LOGE, + FL("Unknown msg %d!"), (int) msgType);) + vos_mem_free( pMsg); + return; + } + + // Ship it + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + SysProcessMmhMsg(pMac, &mmhMsg); + +} /*** end cfgSendHostMsg() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/cfg.txt new file mode 100644 index 0000000000000..3c14ccb77133b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/cfg.txt @@ -0,0 +1,4705 @@ +* Copyright (c) 2014 The Linux Foundation. All rights reserved. +* +* Previously licensed under the ISC license by Qualcomm Atheros, Inc. +* +* +* Permission to use, copy, modify, and/or distribute this software for +* any purpose with or without fee is hereby granted, provided that the +* above copyright notice and this permission notice appear in all +* copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. + +* This file was originally distributed by Qualcomm Atheros, Inc. +* under proprietary terms before Copyright ownership was assigned +* to the Linux Foundation. + +* +* This is the data definition file for the CFG module. +* Author: Kevin Nguyen +* Date: 03/18/02 +* History:- +* 03/18/02 Created. +* 08/10/05 ww: add maoe channels to have a complete channel listing: (see WNI_CFG_VALID_CHANNEL_LIST) +* 08/10/05 ww: WNI_CFG_SCAN_CONTROL_LIST has a new contents +* -------------------------------------------------------------------- + +********************************************************************** +* +* This file contains the descriptions of all configuration parameters +* for both STA and AP. +* +* OUTPUT: +* ------- +* The output files are: +* wniCfgSta.h - C header file for STA mode only +* wniCfgAp.h - C header file for both STA and AP +* wniCfgSta.bin - Control and default values for STA system +* wniCfgAp.bin - Control and default values for AP system +* +* PARAMETER DESCRIPTION: +* ---------------------- +* For each parameter, the description must be on separate lines and +* exactly as specified below. [] are comments and should not be included. +* +* [Common info] parameter_name type maxLen semIndx +* [STA flags] valid RW P/NP RESTART/RELOAD +* [STA_NTF] notification_mask +* [STA values] min max value [for integer] +* length byte1 byte2 ... [for string] +* [AP flags] valid RW/RO/WO P/NP RESTART/RELOAD +* [AP_NTF] notification_mask +* [AP values] min max value [for integer] +* length byte1 byte2 ... [for string] +* +* parameter_name: +* This will be used as the base name for C macro definition. +* Therefore, C syntax rule must be observed. +* +* type: +* Specifies parameter type +* S - variable-length string +* I - integer +* +* maxLen: +* Specifies maximum parameter length in bytes. +* +* semIndx: +* Specifies semaphore index to use for locking this parameter. +* More than one parameters (those belonging to the same group) +* can share the same semaphore index. +* +* valid: +* Specifies if this parameter will be valid in current mode. +* V - Valid +* NV - Not valid +* +* RW: +* Specifies Read/Write mode. +* RO - Read only +* RW - Read/Write +* WO - Write only +* XX - Not accessible from host +* +* P: +* Specifies persistent memory option +* P - Save to persistent memory +* NP - No save +* +* RELOAD: +* Specifies whether setting this requires reloading the MAC module +* This attribute can be changed only when SME is in OFFLINE or SUSPEND(OFFLINE) state +* +* RESTART: +* Specifies whether setting this requires (re)assoc at STA and restart at AP +* This attribute can be changed only when SME is in OFFLINE, SUSPEND(OFFLINE), +* IDLE or SUSPEND(IDLE) states +* +* STA_notification: +* Lists modules to be notified in STA mode. Valid modules are: +* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one +* modules can be listed on the same line using space or tab as the +* separator. If no notification is required, 'NONE' must be specified. +* +* AP_notification: +* Lists module to be notified in AP mode. Valid modules are: +* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one +* modules can be listed on the same line using space or tab as the +* separator. If no notification is required, 'NONE' must be specified. +* +* STA/AP integer values: +* min: +* Specifies minimum value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* max: +* Specifies maximum value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* default: +* Specifies default value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* STA/AP string values: +* len: +* The actual length of the string +* +* bytei: +* byte i of the string where i varies from 1 to len +* +* TABLE GENERATION: +* ----------------- +* Table can be generated using keywords '#TABLE' and '#END' as below: +* +* #TABLE table_name number_of_row +* WNI_CFG_xxxx +* ....... +* ....... +* #END +* +* The CFG utility will generate the following output: +* WNI_CFG_table_xxx_ID xxx +* WNI_CFG_table_xxx_ROW number_of_rows +* WNI_CFG_table_xxx_COL number_of_columns +* +* These will be followed by the parameter definition for each entry in +* the table. Table is organized in column-major order. +* +* #ENTRY_VALUES 1 +* 0 4 1 +* 0 0 0 +* #ENTRY_VALUES 2 +* 0 4 2 +* 0 0 0 +* #ENTRY_VALUES 3 +* 0 4 3 +* 0 0 0 +* #ENTRY_VALUES 4 +* 0 4 4 +* 0 0 0 +* +* +* ENUMERATION +* ----------- +* Enumerations can be define using keyword '#ENUM' +* +* #ENUM xxx val +* +* The cfg utility will generate the following output in the header file +* #define paramname_xxx val +* + + +* +* Station ID (changing requires restart) +* + +WNI_CFG_STA_ID S 6 1 +V RW NP RELOAD +HAL +6 0x22 0x22 0x44 0x44 0x33 0x33 +V RW NP RELOAD +HAL +6 0x22 0x22 0x11 0x11 0x33 0x33 + +* +* CF Pollable +* + +WNI_CFG_CF_POLLABLE I 4 1 +NV RO NP RESTART +NONE +0 0 0 +V RO NP RESTART +NONE +0 1 0 + +* +* CFP Period +* + +WNI_CFG_CFP_PERIOD I 4 1 +V RO NP +NONE +0 255 1 +V RW NP +SCH +0 255 1 + +* +* CFP Max Duration +* + +WNI_CFG_CFP_MAX_DURATION I 4 1 +V RO NP +NONE +0 65535 30000 +V RW NP +HAL +0 65535 30000 + +* +* SSID (changing requires restart) +* + +WNI_CFG_SSID S 32 1 +V RW NP RESTART +NONE +10 1 2 3 4 5 6 7 8 9 0 +V RW NP RESTART +NONE +10 1 2 3 4 5 6 7 8 9 0 + +* +* Beacon Period +* Can't be changed on STA in infrastructure, ignore notification at SCH +* + +WNI_CFG_BEACON_INTERVAL I 4 2 +V RW NP +SCH +0 65535 100 +V RW NP +SCH +0 65535 100 + +* +* DTIM Period +* + +WNI_CFG_DTIM_PERIOD I 4 2 +V RO NP +NONE +0 65535 1 +V RW NP +SCH +0 65535 1 + + +* +* WEP Key Length (5 or 13 bytes) +* + +WNI_CFG_WEP_KEY_LENGTH I 4 5 +V RW NP RESTART +NONE +5 13 5 +V RW NP RESTART +NONE +5 13 5 + +#ENUM 5 5 +#ENUM 13 13 + +* +* Default Key Table +* + +#TABLE WNI_CFG_WEP_DEFAULT_KEY_TABLE 4 + +WNI_CFG_WEP_DEFAULT_KEY S 13 4 +V WO NP RESTART +NONE +0 +V WO NP RESTART +NONE +0 + +#END + +* +* WEP Default Key id +* + +WNI_CFG_WEP_DEFAULT_KEYID I 4 5 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +#ENUM 0 0 +#ENUM 1 1 +#ENUM 2 2 +#ENUM 3 3 + +* +* Exclude unencrypted frames (WEP) +* + +WNI_CFG_EXCLUDE_UNENCRYPTED I 4 5 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* RTS Threshold +* + +WNI_CFG_RTS_THRESHOLD I 4 6 +V RW NP +HAL +0 1048576 2347 +V RW NP +HAL +0 1048576 2347 + +* +* Short Retry Limit +* + +WNI_CFG_SHORT_RETRY_LIMIT I 4 6 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + +* +* Long Retry Limit +* + +WNI_CFG_LONG_RETRY_LIMIT I 4 6 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + + +* +* Fragmentation Threshold +* + +WNI_CFG_FRAGMENTATION_THRESHOLD I 4 6 +V RW NP +HAL +256 8000 8000 +V RW NP +HAL +256 8000 8000 + + +* +* Minimum Channel Time (TU) +* + +WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 20 +V RW NP +NONE +0 65535 20 + +* +* Maximum Channel Time (TU) +* + +WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 40 +V RW NP +NONE +0 65535 40 +* +* Minimum Channel Time (TU) +* + +WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 60 +V RW NP +NONE +0 65535 60 + +* +* Maximum Channel Time (TU) +* + +WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 110 +V RW NP +NONE +0 65535 110 + +* +* Join Failure Timeout (TU) +* + +WNI_CFG_JOIN_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 3000 +V RW NP +NONE +0 65535 3000 + +* +* Authenticate Failure Timeout (TU) +* + +WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + +* +* Authenticate Response Timeout (TU) +* + +WNI_CFG_AUTHENTICATE_RSP_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + +* +* Assocation Failure Timeout (TU) +* + +WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT I 4 8 +V RW NP +LIM +0 65535 2000 +V RW NP +LIM +0 65535 3000 + +* +* Reassociation Failure Timeout (TU) +* + +WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 3000 + + +* +* RA periodicity Timeout (TU) +* + +WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS I 4 7 +V RW NP +HAL +0 65535 1000 +NV RW NP +NONE +0 0 0 + +* +* Beacon Filter Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_BCN_FILTER I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* Heart Beat Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_HEART_BEAT I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* RSSI Monitor Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_RSSI_MONITOR I 4 7 +V RW NP +HAL +0 1 0 +NV RW NP +NONE +0 1 0 + + +* +* PS Data InActivity Timeout (TU) +* + +WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT I 4 7 +V RW NP +HAL +1 255 20 +NV RW NP +NONE +1 255 20 + + +* +* RF Settling Time Clk (In US) +* + +WNI_CFG_RF_SETTLING_TIME_CLK I 4 7 +V RW NP +HAL +0 60000 1500 +NV RW NP +NONE +0 60000 1500 + +* +* Supported Rate Set for 11b +* + +WNI_CFG_SUPPORTED_RATES_11B S 4 2 +V RO NP +NONE +4 2 4 11 22 +V RO NP +NONE +4 2 4 11 22 + +* +* Supported Rate Set for 11a +* + +WNI_CFG_SUPPORTED_RATES_11A S 8 7 +V RO NP +NONE +8 12 18 24 36 48 72 96 108 +V RO NP +NONE +8 12 18 24 36 48 72 96 108 + + +* +* PHY Mode +* + +WNI_CFG_PHY_MODE I 4 9 +V RW NP RESTART +NONE +0 3 0 +V RW NP RESTART +NONE +0 3 0 + +#ENUM 11A 0 +#ENUM 11B 1 +#ENUM 11G 2 +#ENUM NONE 3 + + +* +*The Dot11 mode can change dynamically on STA +* +WNI_CFG_DOT11_MODE I 4 9 +V RW NP RESTART +LIM +0 11 0 +V RW NP RESTART +LIM +0 11 0 + +#ENUM ALL 0 +#ENUM 11A 1 +#ENUM 11B 2 +#ENUM 11G 3 +#ENUM 11N 4 +#ENUM POLARIS 5 +#ENUM TITAN 6 +#ENUM TAURUS 7 +#ENUM 11G_ONLY 8 +#ENUM 11N_ONLY 9 +#ENUM 11AC 10 +#ENUM 11AC_ONLY 11 + + + + + + +* +* Operational Rate Set (goes in beacon, probe rsp and assoc req) +* + +WNI_CFG_OPERATIONAL_RATE_SET S 12 2 +V RW NP RESTART +NONE +0 +V RW NP RESTART +NONE +4 0x82 0x84 11 22 +* 8 0x8c 18 24 36 48 72 96 108 + +* +* Extended Operational Rate Set (goes in beacon, assoc req) +* required for 11g +* + +WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET S 8 7 +V RW NP RESTART +NONE +0 +V RW NP RESTART +NONE +0 + +* +* Proprietary Operational Rate Set +* + +WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET S 4 7 +V RW NP RESTART +NONE +4 1 3 5 7 +V RW NP RESTART +NONE +4 1 3 5 7 + +* +* BSSID +* In IBSS, this can be changed for coalescing, should SME go into IDLE state? +* + +* +* Listen Interval +* + +WNI_CFG_LISTEN_INTERVAL I 4 7 +V RW NP RESTART +NONE +0 65535 1 +V RO NP +NONE +0 65535 1 + +* +* Valid Channel List +* + +WNI_CFG_VALID_CHANNEL_LIST S 100 8 +V RW NP RESTART +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 +V RW NP RESTART +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 + +* +* Current Channel +* + +WNI_CFG_CURRENT_CHANNEL I 4 9 +V RO NP +NONE +0 165 1 +V RO NP +NONE +0 165 1 + + +* +* For 11a or pure 11g, use 6Mbps(rateindex 11) +* as the default beaconRateIndex and +* nonBeaconRateIndex. +* +WNI_CFG_DEFAULT_RATE_INDEX_5GHZ I 4 9 +V RW NP +NONE +0 11 5 +V RW NP +NONE +0 11 5 + +* +* For 11b/g, use 1Mbps +* as the default beaconRateIndex and +* nonBeaconRateIndex. +* +WNI_CFG_DEFAULT_RATE_INDEX_24GHZ I 4 9 +V RW NP +NONE +0 31 1 +V RW NP +NONE +0 31 1 + + +* ********************************************************* +* +* Rate adaptation type +* + +WNI_CFG_RATE_ADAPTATION_TYPE I 4 0 +V RW NP +SCH +0 2 1 +V RW NP +SCH +0 2 1 + +#ENUM FIXED 0 +#ENUM AUTO 1 +#ENUM SNR_BASED 2 + +* +* Rate adaptation fixed rate +* Used to determine the rate for all peer stations +* +* + +WNI_CFG_FIXED_RATE I 4 0 +V RW NP +HAL +0 44 0 +V RW NP +HAL +0 44 0 + +#ENUM AUTO 0 + +#ENUM 1MBPS 1 +#ENUM 2MBPS 2 +#ENUM 5_5MBPS 3 +#ENUM 11MBPS 4 + +#ENUM 6MBPS 5 +#ENUM 9MBPS 6 +#ENUM 12MBPS 7 +#ENUM 18MBPS 8 +#ENUM 24MBPS 9 +#ENUM 36MBPS 10 +#ENUM 48MBPS 11 +#ENUM 54MBPS 12 + +#ENUM 6_5MBPS_MCS0_20MHZ_SIMO 13 +#ENUM 13MBPS_MCS1_20MHZ_SIMO 14 +#ENUM 19_5MBPS_MCS2_20MHZ_SIMO 15 +#ENUM 26MBPS_MCS3_20MHZ_SIMO 16 +#ENUM 39MBPS_MCS4_20MHZ_SIMO 17 +#ENUM 52MBPS_MCS5_20MHZ_SIMO 18 +#ENUM 58_5MBPS_MCS6_20MHZ_SIMO 19 +#ENUM 65MBPS_MCS7_20MHZ_SIMO 20 + +#ENUM 7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#ENUM 14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#ENUM 21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#ENUM 28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#ENUM 43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#ENUM 57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#ENUM 65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#ENUM 72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 + +#ENUM 0_25MBPS_SLR_20MHZ_SIMO 29 +#ENUM 0_5MBPS_SLR_20MHZ_SIMO 30 + +#ENUM 68_25MBPS_QC_PROP_20MHZ_SIMO 31 +#ENUM 54MBPS_MCS3_40MHZ_SIMO 32 +#ENUM 81MBPS_MCS4_40MHZ_SIMO 33 +#ENUM 108MBPS_MCS5_40MHZ_SIMO 34 +#ENUM 121_5MBPS_MCS6_40MHZ_SIMO 35 +#ENUM 135MBPS_MCS7_40MHZ_SIMO 36 +#ENUM 15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#ENUM 30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#ENUM 45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#ENUM 60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#ENUM 90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#ENUM 120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#ENUM 135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#ENUM 150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +* ********************************************************* +* +* Broadcast/mutlicast rates for 2.4GHZ +* uses the same rate indices definition as WNI_CFG_FIXED_RATE +* default value corresponds to 1M + +WNI_CFG_FIXED_RATE_MULTICAST_24GHZ I 4 8 +V RW NP +HAL +0 31 1 +V RW NP +HAL +0 31 1 + +* ********************************************************* +* +* Broadcast/mutlicast rates for 5 GHZ +* uses the same rate indices definition as WNI_CFG_FIXED_RATE +* default value corresponds to 6M + +WNI_CFG_FIXED_RATE_MULTICAST_5GHZ I 4 8 +V RW NP +HAL +0 31 5 +V RW NP +HAL +0 31 5 + +* +* retry rate selection policy +* 0 => use the minimum supported rate +* 1 => use the same rate as the chosen primary rate +* 2 => use the rate specified in RETRYRATE_SECONDARY +* 3 => use the rate closest to the primary +* 4 => autoselect the retry rate based on RA algorithm +* + +WNI_CFG_RETRYRATE_POLICY I 4 0 +V RW NP +HAL +0 255 4 +V RW NP +HAL +0 255 4 + +#ENUM MIN_SUPPORTED 0 +#ENUM PRIMARY 1 +#ENUM RESERVED 2 +#ENUM CLOSEST 3 +#ENUM AUTOSELECT 4 +#ENUM MAX 5 + +* +* the following two CFG's are +* used only if the retryrate policy == 2 +* These should be set to one of the values used +* for configuring fixed rates (see enumerated rates) +* + +WNI_CFG_RETRYRATE_SECONDARY I 4 0 +V RW NP +HAL +0 255 0 +V RW NP +HAL +0 255 0 + +WNI_CFG_RETRYRATE_TERTIARY I 4 0 +V RW NP +HAL +0 255 0 +V RW NP +HAL +0 255 0 + +* ********************************************************* +* +* Automatic Power Save Delivery capability +* + +WNI_CFG_APSD_ENABLED I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Shared key authentication supported +* + +WNI_CFG_SHARED_KEY_AUTH_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* Open system authentication supported +* + +WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* Authentication Type (change requires restart) +* + +WNI_CFG_AUTHENTICATION_TYPE I 4 8 +V RW NP RESTART +NONE +0 65535 0 +V RW NP RESTART +NONE +0 65535 0 + +* +* CF Poll Request (change requires restart) +* + +WNI_CFG_CF_POLL_REQUEST I 4 8 +NV RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Privacy Enabled (change requires restart) +* + +WNI_CFG_PRIVACY_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Short Preamble (change requires restart) +* + +WNI_CFG_SHORT_PREAMBLE I 4 8 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* Short Slot time +* This is the operational state of the BSS + +WNI_CFG_SHORT_SLOT_TIME I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 0 + + +* +* ACCEPT Short Slot Association only +* +* 1: If AP supports shortSlot, then AP will accept +* association only from stations that supports +* supports short slot +* 0: AP supports shortSlot, but AP will accept association +* from stations regardless of whether station supports +* short slot or long slot +* +WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* QOS Enabled (change requires restart) +* + +WNI_CFG_QOS_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* HCF Enabled (change requires restart) +* + +WNI_CFG_HCF_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* RSN (11i/WPA) Enabled +* + +WNI_CFG_RSN_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Background scanning periodicity (kilo usec) +* + +WNI_CFG_BACKGROUND_SCAN_PERIOD I 4 8 +V RW NP +LIM +0 180000 5000 +V RW NP +LIM +0 18000 5000 + +* +* Max number of Preauthentication +* + +WNI_CFG_MAX_NUM_PRE_AUTH I 4 8 +V RW NP RESTART +NONE +0 256 64 +V RW NP RESTART +NONE +0 256 64 + +* +* Preauthentication Cleanup Timeout (kilo usec) +* + +WNI_CFG_PREAUTH_CLNUP_TIMEOUT I 4 8 +NV XX NP +NONE +0 0 0 +V RW NP +LIM +0 120000 30000 + +* +* Release AID Timeout +* + +WNI_CFG_RELEASE_AID_TIMEOUT I 4 8 +NV XX NP +NONE +0 0 0 +V RW NP +LIM +0 100000 1000 +* +* Heartbeat Threshold +* + +WNI_CFG_HEART_BEAT_THRESHOLD I 4 8 +V RW NP +LIM +0 65535 40 +NV RW NP +NONE +0 65535 40 + +* +* Probe response wait time out after heartbeat failure +* + +WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT I 4 8 +V RW NP +NONE +10 10000 40 +V RW NP +NONE +10 10000 40 + +* +* Manufacturer OUI (from eeprom) +* + +WNI_CFG_MANUFACTURER_OUI S 3 8 +V RO NP +NONE +3 0x0 0xa 0xf5 +V RO NP +NONE +3 0x0 0xa 0xf5 + +* +* Manufacture Name (from eeprom) +* + +WNI_CFG_MANUFACTURER_NAME S 65 8 +V RO NP +NONE +8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D +V RO NP +NONE +8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D + +* +* Model Number (from eeprom) +* + +WNI_CFG_MODEL_NUMBER S 33 8 +V RO NP +NONE +6 0x4d 0x4e 0x31 0x32 0x33 0x34 +V RO NP +NONE +6 0x4d 0x4e 0x31 0x32 0x33 0x34 + + + +* +* Model Name (from eeprom) +* WFR4031 +* + +WNI_CFG_MODEL_NAME S 33 8 +V RO NP +NONE +7 0x57 0x46 0x52 0x34 0x30 0x33 0x31 +V RO NP +NONE +7 0x57 0x46 0x52 0x34 0x30 0x33 0x31 + + + + +* +* Manufacture Product Name (from eeprom) +* + +WNI_CFG_MANUFACTURER_PRODUCT_NAME S 33 8 +V RO NP +NONE +6 0x31 0x31 0x6e 0x2D 0x41 0x50 +V RO NP +NONE +6 0x31 0x31 0x6e 0x2D 0x41 0x50 + + +* +* Manufacture Product Version (from eeprom) +* + +WNI_CFG_MANUFACTURER_PRODUCT_VERSION S 33 8 +V RO NP +NONE +6 0x53 0x4e 0x31 0x32 0x33 0x34 +V RO NP +NONE +6 0x53 0x4e 0x31 0x32 0x33 0x34 + +* +* Multi Domain Capability (11d) Enable +* + +WNI_CFG_11D_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 0 + +* +* per channel Max power transmit (in dBm) +* this parameter correspond to the MAX_COUNTRY_EID +* table of (Channel Number/num channel/max tx power) +* +* There is one table for 5GHz channels and one table for 2.4GHz channels +* + +WNI_CFG_MAX_TX_POWER_2_4 S 128 8 +V RW NP +NONE +3 1 14 20 +V RW NP +NONE +3 1 14 20 + +WNI_CFG_MAX_TX_POWER_5 S 128 8 +V RW NP +NONE +3 36 126 20 +V RW NP +NONE +3 36 126 20 + +* +* Cell size configurations. These are canned configurations for a specified +* cell size. +* +WNI_CFG_NETWORK_DENSITY I 4 9 +V RW NP +HAL +0 3 3 +V RW NP +HAL +0 3 0 + +#ENUM LOW 0 +#ENUM MEDIUM 1 +#ENUM HIGH 2 +#ENUM ADAPTIVE 3 + + +* +* Adaptive Threshold Algorithm +* +WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM I 4 9 +V RW NP +HAL +1 2 2 +V RW NP +HAL +1 2 2 + +#ENUM CARRIER 1 +#ENUM CORRELATION 2 + + + +* +* Current TX Antenna +* + +WNI_CFG_CURRENT_TX_ANTENNA I 4 9 +V RW NP +HAL +1 1 1 +V RW NP +HAL +1 2 2 + +* +* Current RX Antenna +* + +WNI_CFG_CURRENT_RX_ANTENNA I 4 9 +V RW NP +HAL +1 2 2 +V RW NP +HAL +1 3 3 + +* +* Current TX Power Level +* + +WNI_CFG_CURRENT_TX_POWER_LEVEL I 4 9 +V RW NP +NONE +0 128 27 +V RW NP +NONE +0 128 27 + + +* +* Radio Power State for each Chain +* +* This CFG is invoked when user issues the Apple setPower() +* command, which configures the power state for each chain. Currently, +* Taurus supports up to three chains, and each chain can be configured +* to one of the 4 following possible power states: +* POWER_OFF = 0x0 +* POWER_ON = 0x1 +* POWER_TX = 0x2 +* POWER_RX = 0x3 +* +* The power state of each chain is expressed in nibble: +* bit[0:3] - chain 0 +* bit[4:7] - chain 1 +* bit[8:11] - chain 2 +* bit[12:15] - not used at the moment +* +* Examples: +* 0x001 - 1x1 (chain 1 is for both tx and rcv. chain 1,2 are turned off) +* 0x031 - 1x2 (chain 0 is for both tx and rcv. chain 1 is rcv only. chain 2 is turned off) +* 0x011 - 2x2 (chain 0,1 are used for both tx and rcv) +* 0x311 - 2x3 (chain 0,1 are used for both tx and rcv. chain 2 is for rcv only) +* 0x333 - all 3 chains are set to RX +* + +WNI_CFG_POWER_STATE_PER_CHAIN I 4 9 +V RW NP +HAL +0 0xffff 0x311 +V RW NP +HAL +0 0xffff 0x311 + +#ENUM OFF 0 +#ENUM ON 1 +#ENUM TX 2 +#ENUM RX 3 +#ENUM MASK 0xf +#ENUM CHAIN_0_OFFSET 0 +#ENUM CHAIN_1_OFFSET 4 +#ENUM CHAIN_2_OFFSET 8 + + +* +* Parameter to indicate or not new BSS found +* + +WNI_CFG_NEW_BSS_FOUND_IND I 4 9 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Proprietary ANI features enable/disable +* + +WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* Qualcomm Prop Rates are disabled by default +* +WNI_CFG_PROPRIETARY_RATES_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* AP node Name +* + +WNI_CFG_AP_NODE_NAME S 32 8 +NV RO NP +NONE +0 +V RW NP RESTART +NONE +0 + +* +* Country code (from EEPROM) +* + +WNI_CFG_COUNTRY_CODE S 3 8 +V RW NP +NONE +0 +V RW NP +NONE +3 0x11 0x22 0x33 + +* +* Spectrum Management (11h) enable/disable +* + +WNI_CFG_11H_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* Wait for CNF Timeout. CNF include (RE)ASSOC, DISASSOC, AUTH, DEAUTH, +* DUMMY packet +* + +WNI_CFG_WT_CNF_TIMEOUT I 4 12 +V RW NP +NONE +10 3000 1000 +V RW NP +NONE +10 3000 1000 + +* +* Keepalive Timeout. A Null data frame is sent out every timeout. +* Applicable to both AP and STA +* + +WNI_CFG_KEEPALIVE_TIMEOUT I 4 12 +V RW NP +NONE +0 3600000 0 +V RW NP +NONE +0 3600000 3000 + +* +* Proximity, set it for very short distances +* Proxmity setting is applied via halPhySetNwDensity() +* +* close proximity off = densityOn is true. network density config applies. +* close proximity on = densityOn is false. Don't care about network density config. +* + +WNI_CFG_PROXIMITY I 4 12 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +#ENUM OFF 0 +#ENUM ON 1 + +* +* Default LOG level +* + +WNI_CFG_LOG_LEVEL I 4 12 +V RW NP +NONE +0 7 4 +V RW NP +NONE +0 7 4 + +* +* OLBC detection timeout +* + +WNI_CFG_OLBC_DETECT_TIMEOUT I 4 12 +V RW NP +NONE +1000 30000 10000 +V RW NP +NONE +1000 30000 10000 + +********************************** +* Protection Enable +* +*LOWER byte for associated stations +*UPPER byte for overlapping stations. +*11g ==> protection from 11g +*11b ==> protection from 11b +*each byte will have the following info +*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +*reserved reserved RIFS Lsig n-GF ht20 11g 11b +********************************** +WNI_CFG_PROTECTION_ENABLED I 4 9 +V RW NP RESTART +LIM +0 0xffff 0xffff +V RW NP RESTART +LIM +0 0xffff 0xffff + +#ENUM FROM_llA 0 +#ENUM FROM_llB 1 +#ENUM FROM_llG 2 +#ENUM HT_20 3 +#ENUM NON_GF 4 +#ENUM LSIG_TXOP 5 +#ENUM RIFS 6 +#ENUM OBSS 7 +#ENUM OLBC_FROM_llA 8 +#ENUM OLBC_FROM_llB 9 +#ENUM OLBC_FROM_llG 10 +#ENUM OLBC_HT20 11 +#ENUM OLBC_NON_GF 12 +#ENUM OLBC_LSIG_TXOP 13 +#ENUM OLBC_RIFS 14 +#ENUM OLBC_OBSS 15 + + +* **************************************** +* +* 11G Protection Enable Always +* Valid only if protection is enabled +* forces uses of protection regardless of legacy stations +* + +WNI_CFG_11G_PROTECTION_ALWAYS I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +********************************************* +* Force protection +* 0 : disable protection +* 1 : CTS +* 2 : RTS by threshold (threshold nonzero) +* 3 : dual CTS (not supported right now) +* 4 : RTS (threshold 0) +* 5 : auto + +WNI_CFG_FORCE_POLICY_PROTECTION I 4 9 +V RW NP RESTART +HAL +0 5 5 +V RW NP RESTART +HAL +0 5 5 + +#ENUM DISABLE 0 +#ENUM CTS 1 +#ENUM RTS 2 +#ENUM DUAL_CTS 3 +#ENUM RTS_ALWAYS 4 +#ENUM AUTO 5 + + + + + + +******************************************** +* 11G Short Preamble Enable +* + +WNI_CFG_11G_SHORT_PREAMBLE_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* 11G Short Slot Time Enable (change requires restart) +* This is the admin state of short slot support. + +WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* Calibration periodicity (minutes) +* + +WNI_CFG_CAL_PERIOD I 4 12 +V RW NP +HAL +2 10 5 +V RW NP +HAL +2 10 5 + +* +* Statistics collection periodicity (seconds) +* + +WNI_CFG_STATS_PERIOD I 4 12 +V RW NP +HAL +1 10 10 +V RW NP +HAL +1 10 10 + +* +* Calibration on/off control +* + +WNI_CFG_CAL_CONTROL I 4 12 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +#ENUM CAL_ON 0 +#ENUM CAL_OFF 1 + + +* +* Parameter to allow 11g only STAs while operating in 11g mode +* + +WNI_CFG_11G_ONLY_POLICY I 4 12 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Packet Classification +* This flag is a bitmask used to indicate which +* frame classifier to be enabled: +* b0: DSCP +* b1: 802.1P +* + +WNI_CFG_PACKET_CLASSIFICATION I 4 12 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +#ENUM DISABLED 0 +#ENUM DSCP 1 +#ENUM 8021P 2 +#ENUM ALL 3 + +* +* WME Enabled (change requires restart) +* + +WNI_CFG_WME_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* ADDTS response timeout (in ms) +* + +WNI_CFG_ADDTS_RSP_TIMEOUT I 4 8 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + + + * Max SP Length indicates the max number of + * total buffered MSDUs and MMPDUs the WMM AP + * may deliver to WMM STA during any service period + * triggered by WMM STA. + * 1) If AP sends WMM IE with the UAPSD bit 0, max_sp_length=0 + * 2) If WMM STA's all 4 UAPSD flag are set to 0, max_sp_length=0 + * 3) If AP sends WMM IE with UAPSD=1, and at least one of stations + * UAPSD flag is set to 1, then max_sp_length can be set to: + * [b5:b6]=0x00: WMM AP may deliver all buffered frames + * [b5:b6]=0x10: WMM AP may deliver max 2 buffered frames + * [b5:b6]=0x01: WMM AP may deliver max 4 buffered frames + * [b5:b6]=0x11: WMM AP may deliver max 6 buffered frames + +WNI_CFG_MAX_SP_LENGTH I 4 8 +V RW NP +NONE +0 3 0 +V RW NP +NONE +0 3 0 + + +* +* KEEP ALIVE STA Limit Threshold , used in AP to delete the STA +* from Station Table which didn't respond to Probe Response Messages +* + +WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD I 4 8 +NV RW NP +NONE +0 32 0 +V RW NP +NONE +0 32 0 + +* +* Parameter that specifies whether to send SSID +* in Probe Response when SSID is suppressed +* + +WNI_CFG_SEND_SINGLE_SSID_ALWAYS I 4 12 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* WSM Enabled (change requires restart) +* Takes effect only if WME is also enabled +* + +WNI_CFG_WSM_ENABLED I 4 8 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* **************************************** +* +* Proprietary IE capability enable +* bit mapped: +* 0:HCF 1:11eQos 2:WME 3:WSM 4:EXT_RATES +* 5:EXTRATE_STOP +* 6:Titan device 7:Taurus Device +* 13:EDCA 14:LOADINFO 15:VERSION +* + +WNI_CFG_PROP_CAPABILITY I 4 8 +V RW NP +NONE +0 0xffff 0xe0bf +V RW NP +NONE +0 0xffff 0xc0a9 + +#ENUM HCF 0 +#ENUM 11EQOS 1 +#ENUM WME 2 +#ENUM WSM 3 +#ENUM EXTRATES 4 +#ENUM EXTRATE_STOP 5 +#ENUM TITAN 6 +#ENUM TAURUS 7 +#ENUM EDCAPARAMS 13 +#ENUM LOADINFO 14 +#ENUM VERSION 15 +#ENUM MAXBITOFFSET 15 + +* **************************************** +* +* Background Channel List +* Contains pairs of {channelNumber, scanType} +* where scanType = 0 indicates active scan and +* = 1 indicates passive scan +* +* +*WNI_CFG_BACKGROUND_SCAN_LIST S 128 8 +*V RW NP RESTART +*LIM +*60 36 0 40 0 44 0 48 0 52 0 56 0 60 0 64 0 1 0 6 0 11 0 34 0 38 0 42 0 46 0 2 0 3 0 4 0 5 0 7 0 8 0 9 0 10 0 12 0 13 0 14 0 149 0 153 0 157 0 161 0 +*V RW NP RESTART +*LIM +*60 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 34 0 36 0 38 0 40 0 42 0 44 0 46 0 48 0 52 0 56 0 60 0 64 0 149 0 153 0 157 0 161 0 +* + +* **************************************** +* EDCA paramters are contained in profiles - each profile contains +* the parameters [ACM, AIFSN, CWmin, CWmax, TxOp] for four +* access categories (i.e., four sets). Two such sets of four parameters +* make a single profile: One set is used locally by the AP, the other set +* is broadcast for use by stations. +* +* Cwmin and Cwmax are two bytes each, MSB first. So Cwmin of [3 255] is +* equivalent to 0x3ff, i.e. 3*256+255=1023 +* +* The profile to use is selected based on the valus of the profile select param +* See ENUMs below for definitions of profile values +* + +WNI_CFG_EDCA_PROFILE I 4 8 +V RW NP +SCH +0 255 1 +V RW NP +SCH +0 255 1 + +#ENUM ANI 0 +#ENUM WMM 1 +#ENUM TIT_DEMO 2 +#ENUM MAX 3 + +#ENUM ACM_IDX 0 +#ENUM AIFSN_IDX 1 +#ENUM CWMINA_IDX 2 +#ENUM CWMAXA_IDX 4 +#ENUM TXOPA_IDX 6 +#ENUM CWMINB_IDX 7 +#ENUM CWMAXB_IDX 9 +#ENUM TXOPB_IDX 11 +#ENUM CWMING_IDX 12 +#ENUM CWMAXG_IDX 14 +#ENUM TXOPG_IDX 16 + + +* **************************************** +* Profile 0 (Airgo) parameters - AC_BK Local +* ACM, AIFSN, [CWminH, CWminL, CWmaxH, CWmaxL, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 + +* +* Profile 0 (Airgo) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 + +* +* Profile 0 (Airgo) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 + +* +* Profile 0 (Airgo) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 + +* +* Profile 0 (Airgo) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 + +* +* Profile 0 (Airgo) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 + +* +* Profile 0 (Airgo) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 + +* +* Profile 0 (Airgo) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 + + +* **************************************** +* Profile 1 (WME) parameters - AC_BK Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + + +* +* Profile 1 (WME) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 3 0 15 0 63 0 0 31 3 255 0 0 15 0 63 0 +V RW NP RESTART +NONE +17 0 3 0 15 0 63 0 0 15 0 63 0 0 15 0 63 0 + +* +* Profile 1 (WME) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 +V RW NP RESTART +NONE +17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 + +* +* Profile 1 (WME) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 +V RW NP RESTART +NONE +17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 + +* +* Profile 1 (WME) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + +* +* Profile 1 (WME) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + +* +* Profile 1 (WME) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 + +* +* Profile 1 (WME) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 + +* **************************************** +* Profile 2(Titan Demo) parameters - AC_BK Local +* ACM, AIFSN, [CWminH, CWminL, CWmaxH, CWmaxL, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Radar detector flag enable/disable +* + +WNI_CFG_RDET_FLAG I 4 9 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +WNI_CFG_RADAR_CHANNEL_LIST S 20 8 +V RW NP RESTART +NONE +15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 +V RW NP RESTART +NONE +15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 + +* +* Local Power Constraint (dBm) +* + +WNI_CFG_LOCAL_POWER_CONSTRAINT I 4 12 +V RW NP RESTART +NONE +0 255 0 +V RW NP RESTART +NONE +0 255 0 + +* ********************************************************* +* +* Admission Control Policy +* used for admitting tspec's when either edca or hcca are in use +* + +WNI_CFG_ADMIT_POLICY I 4 8 +V RW NP RESTART +NONE +0 2 0 +V RW NP +SCH +0 2 0 + +#ENUM ADMIT_ALL 0 +#ENUM REJECT_ALL 1 +#ENUM BW_FACTOR 2 + +* +* Oversubscription factor for admission control +* valid only when admit policy is set to BW_FACTOR +* units are in terms of 1/10th of available bandwidth +* + +WNI_CFG_ADMIT_BWFACTOR I 4 8 +V RW NP RESTART +NONE +0 100 20 +V RW NP +SCH +0 100 20 + +* ********************************************************* +* +* Number of "consecutive" Background Scan Failure needed +* before LIM is forced to perform 1 aggressive background scan +* +WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE I 4 8 +V RW NP RESTART +NONE +0 256 60 +V RW NP RESTART +NONE +0 256 60 + + +************************************* +* Feature: Channel Bonding +************************************* +* +* Global flag to enable/disable Channel Bonding +* 0 - Disable: Force disable channel bonding for all TC-ids +* 1 - Enable: Force enable channel bonding for all TC-ids +* 2 - no legacy bss: Enable channel bonding if no legacy BSS are present +* 3 - no legacy all: Enable channel bonding if no legacy BSS or devices are present +* 4 - intelligent: Enable channel bonding depending on load level on secondary channel +* +WNI_CFG_CHANNEL_BONDING_MODE I 4 12 +V RW NP RESTART +LIM +0 10 0 +V RW NP RESTART +LIM +0 10 0 + +#ENUM DISABLE 0 +#ENUM ENABLE 1 +#ENUM IF_NO_LEGACY_BSS 2 +#ENUM IF_NO_LEGACY_ALL 3 +#ENUM INTELLIGENT 4 + + +* +* When the channel is 40MHz wide, this CFG indicates +* if the secondary channel is located above (at +* a higher frequency), or located below (at a +* lower frequency). +* +* 0 - There is no secondary channel. The channel is 20Mhz +* 1 - LOWER: Secondary channel 40MHZ is located below the primary channel +* 2 - CENTERED:Secondary channel and primary located at centered +* 3 - HIGHER: Secondary channel 40 MHZ is located above the primary channel +* 4 - 80MHZ_LOW_CENTERED : 20/40MHZ offset LOW 40/80MHZ offset CENTERED +* 5 - 80MHZ_CENTERED_CENTERED : 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED +* 6 - 80MHZ_HIGH_CENTERED : 20/40MHZ offset HIGH 40/80MHZ offset CENTERED +* 7 - 80MHZ_LOW_LOW: 20/40MHZ offset LOW 40/80MHZ offset LOW +* 8 - 80MHZ_HIGH_LOW: 20/40MHZ offset HIGH 40/80MHZ offset LOW +* 9 - 80MHZ_LOW_HIGH: 20/40MHZ offset LOW 40/80MHZ offset HIGH +* 10 - 80MHZ_HIGH_HIGH: 20/40MHZ offset HIGH 40/80MHZ offset HIGH +* +WNI_CFG_CB_SECONDARY_CHANNEL_STATE I 4 12 +V RW NP +NONE +0 10 0 +V RW NP +NONE +0 10 0 + +#ENUM NONE 0 +#ENUM LOWER 1 +#ENUM HIGHER 2 +#ENUM 11AC_20MHZ_LOW_40MHZ_CENTERED 3 +#ENUM 11AC_20MHZ_CENTERED_40MHZ_CENTERED 4 +#ENUM 11AC_20MHZ_HIGH_40MHZ_CENTERED 5 +#ENUM 11AC_20MHZ_LOW_40MHZ_LOW 6 +#ENUM 11AC_20MHZ_HIGH_40MHZ_LOW 7 +#ENUM 11AC_20MHZ_LOW_40MHZ_HIGH 8 +#ENUM 11AC_20MHZ_HIGH_40MHZ_HIGH 9 + +************************************* +* Feature: Dynamic Retry Rates +************************************* +* +* When the short/long retry count reach the +* adaptive_retry_threshold(0), then the retry0 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_ZERO I 4 12 +V RW NP +HAL +0 255 2 +V RW NP +HAL +0 255 2 + +* +* When the short/long retry count reach the +* adaptive_retry_threshold(1), then the retry1 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_ONE I 4 12 +V RW NP +HAL +0 255 4 +V RW NP +HAL +0 255 4 + +* +* When the short/long retry count reach the +* adaptive_retry_threshold(2), then the retry2 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_TWO I 4 12 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + + +* +* Trigger Station Background Scan Flag +* +WNI_CFG_TRIG_STA_BK_SCAN I 4 12 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 1 + +* ********************************************************* +* control of dynamic EDCA parameter profile switching +* +* OOB, we would like to support WMM standard edca profile +* However, when Airgo STA's join the BSS, we would like +* to switch the profile to Airgo high-performance edca parameters +* +* This cfg supports that behaviour. It is used only if 11e qos +* has been enabled and is ignored otherwise. +* +* When set to any value (other than unused), it determines the +* edca profile to switch to when an Airgo STA joins the BSS. +* +* By default, we choose to switch to Airgo profile. +* +* NOTE: This parameter applies only to an AP +* + +WNI_CFG_DYNAMIC_PROFILE_SWITCHING I 4 8 +V RW NP RESTART +NONE +0 255 255 +V RW NP RESTART +NONE +0 255 1 + +#ENUM UNUSED 255 + +* ********************************************************* +* +* Scan control list +* Contains pairs of {channelNumber, activeScanAllowedFlag} +* where scanType = 1 indicates active scan is allowed, and +* = 0 indicates passive scan is used +* If a channel is not on this list, active scan is NOT allowed. So it is +* sufficient to inlude only those channels where active scan is allowed +* on this list. +* +* The list determines only whether active scan is allowed or not; it does not +* determine which type of scan is actually performed. +* + +WNI_CFG_SCAN_CONTROL_LIST S 128 8 +V RW NP RESTART +LIM +112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1 +V RW NP RESTART +LIM +112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1 + + +* **************************************** +* +* MIMO rates enabled (for rate adaptation, to start) +* + +WNI_CFG_MIMO_ENABLED I 4 9 +V RW NP RELOAD +NONE +0 1 1 +V RW NP RELOAD +NIM +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + + +* +* BLOCK ACK Enabled (change requires restart) +* change default to ON +* bit 0 ==> delayed BA +* bit 1 ==> immediate BA +WNI_CFG_BLOCK_ACK_ENABLED I 4 8 +V RW NP RESTART +LIM +0 3 0 +V RW NP RESTART +LIM +0 3 0 + +#ENUM DELAYED 0 +#ENUM IMMEDIATE 1 + + +* +*BA Activity check global timer +* +WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT I 4 7 +V RW NP +HAL +0 65535 1000 +V RW NP +HAL +0 65535 1000 + + +* +* Rx STBC support +* +WNI_CFG_HT_RX_STBC I 4 7 +V RW NP RESTART +LIM +0 3 1 +V RW NP RESTART +LIM +0 3 1 + + +* +* 1. HT capabilities Info: 2 bytes size +* +* Supported channel Width is set to 1 (40 Mhz) +* SM Power Save is disabled. +* GreenField support is enabled. +* Short GI for 20 and 40Mhz is enabled. +* Max AMSDU Size is set to 0(3839 Octets) +* DSSS-CCK Mode is enabled. +* LSIG TXOP Protection is disabled +* Rest of the features are not supported at this moment. +* +* fedc ba98 7654 3210 +* 0000 0001 0010 0000 +* +WNI_CFG_HT_CAP_INFO I 4 10 +V RW NP RESTART +LIM +0 0xffff 0x016c +V RW NP RESTART +LIM +0 0xffff 0x106e + +#ENUM ADVANCE_CODING 0 +#ENUM SUPPORTED_CHAN_WIDTH_SET 1 +#ENUM SM_POWER_SAVE 2 +#ENUM GREEN_FIELD 4 +#ENUM SHORT_GI_20MHZ 5 +#ENUM SHORT_GI_40MHZ 6 +#ENUM TX_STBC 7 +#ENUM RX_STBC 8 +#ENUM DELAYED_BA 10 +#ENUM MAX_AMSDU_SIZE 11 +#ENUM DSSS_CCK_MODE_40MHZ 12 +#ENUM PSMP 13 +#ENUM STBC_CONTROL_FRAME 14 +#ENUM LSIG_TXOP_PROTECTION 15 + +* +* 2. HT Parameters Info: 1 byte size +* +* Max AMPDU Rx Factor is defined using bit #0 and #1 +* MPDU Density is defined using bit #2 thru #4. +* The default values are, +* 7654 3210 +* 0000 0010 --> 2 for RX AMPDU Factor, 0 for MPDU density +* +WNI_CFG_HT_AMPDU_PARAMS I 4 7 +V RW NP RESTART +LIM +0 0xff 0x00 +V RW NP RESTART +LIM +0 0xff 0x02 + +#ENUM MAX_RX_AMPDU_FACTOR 0 +#ENUM MPDU_DENSITY 2 +#ENUM RESERVED 5 + +* +* 3. Supported MCS Set: 16 bytes size +* +* MCS #0-15 and #32 is supported. +* +WNI_CFG_SUPPORTED_MCS_SET S 16 7 +V RW P RESTART +LIM +16 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 255 255 0 0 1 0 0 0 0 0 0 0 0 0 0 0 + +* +* 4. Extended HT Capabilities Info: 2 bytes size +* +* Only HTC Support is enabled, rest all features are not +* supported at this moment. +* +* fedc ba98 7654 3210 +* 0000 0100 0000 0000 +* +WNI_CFG_EXT_HT_CAP_INFO I 4 10 +V RW P RESTART +LIM +0 0xffff 0x0400 +V RW P RESTART +LIM +0 0xffff 0x0400 + +#ENUM PCO 0 +#ENUM TRANSITION_TIME 1 +#ENUM RESERVED1 3 +#ENUM MCS_FEEDBACK 8 +#ENUM HTC_SUPPORT 10 +#ENUM RD_RESPONDER 11 +#ENUM RESERVED2 12 + + +* +* 5. Transmit Beam Forming Capabiliries Info: 4 bytes size +* +WNI_CFG_TX_BF_CAP I 4 7 +V RO NP RESTART +LIM +0 0xffffffff 0x00000000 +V RO NP RESTART +LIM +0 0xffffffff 0x00000000 + +* +* 6. Antenna Selection Capabilities: 1 byte size +* +WNI_CFG_AS_CAP I 4 7 +V RW P RESTART +LIM +0 0xff 0x00 +V RW P RESTART +LIM +0 0xff 0x00 + +#ENUM ANTENNA_SELECTION 0 +#ENUM EXPLICIT_CSI_FEEDBACK_TX 1 +#ENUM ANTENNA_INDICES_FEEDBACK_TX 2 +#ENUM EXPLICIT_CSI_FEEDBACK 3 +#ENUM ANTENNA_INDICES_FEEDBACK 4 +#ENUM RX_AS 5 +#ENUM TX_SOUNDING_PPDUS 6 +#ENUM RESERVED 7 + +************************************************** +* Beacon HT (High Through) Info IE +*************************************************** +* +* 3. HT Info Field1: 1 byte size. +* +* Secondary Channel Offset is set to 3 (Down) by default and will +* be updated dynamically by DFS algorithm. +* Channel Width is set to 1 (40 Mhz) +* RIFS Mode is enabled +* Rest of the features are not supported at this moment. +* +* 7654 3210 +* 0000 1111 +* +WNI_CFG_HT_INFO_FIELD1 I 4 10 +V RW NP RESTART +LIM +0 0xff 0x0f +V RW NP RESTART +LIM +0 0xff 0x0f + +#ENUM SECONDARY_CHANNEL_OFFSET 0 +#ENUM RECOMMENDED_CHANNEL_WIDTH 2 +#ENUM RIFS_MODE 3 +#ENUM PSMP_ACCESS_ONLY 4 +#ENUM SERVICE_INTERVAL_GRANULARITY 5 + +* +* 4. HT Info Field2: 2 bytes +* +* Operation mode is set to 0(Pure, GF) to begin with and +* will be updated dynamically. +* 'NonGF Devices present is also set to zero and +* will be updated dynamically. +* +* fedc ba98 7654 3210 +* 0000 0000 0000 0000 +* +WNI_CFG_HT_INFO_FIELD2 I 4 10 +V RW P +LIM +0 0xffff 0x00 +V RW P +LIM +0 0xffff 0x00 + +#ENUM OP_MODE 0 +#ENUM NON_GF_DEVICES_PRESENT 2 +#ENUM RESERVED 3 + +* +* 5. HT Info Field3: 2 bytes +* +* fedc ba98 7654 3210 +* 0000 0000 0000 0000 +* +* LSIG TXOP Full Protection will be zero to begin with and +* updated dynamically. +* Everything else is not supported at this moment. +* +WNI_CFG_HT_INFO_FIELD3 I 4 10 +V RW P +LIM +0 0xffff 0x0000 +V RW P +LIM +0 0xffff 0x0000 + +#ENUM BASIC_STBC_MCS 0 +#ENUM DUAL_STBC_PROTECTION 7 +#ENUM SECONDARY_BEACON 8 +#ENUM LSIG_TXOP_PROTECTION_FULL_SUPPORT 9 +#ENUM PCO_ACTIVE 10 +#ENUM PCO_PHASE 11 +#ENUM RESERVED 12 + +* +* 6. Basic MCS Set: 16 bytes size +* +* For now set this to zero and don't put any restrictions. +* +WNI_CFG_BASIC_MCS_SET S 16 7 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +* +* 7. Current supported MCS Set: 16 bytes size +* +* For now set this to zero and don't put any restrictions. +* +WNI_CFG_CURRENT_MCS_SET S 16 7 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + +* +* Greenfield Capability +* By default Greenfield is enabled +* +WNI_CFG_GREENFIELD_CAPABILITY I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 0 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +* +* Maximum AMPDU Length +* By default set to zero for 3895 octets +* +WNI_CFG_VHT_MAX_MPDU_LENGTH I 4 19 +V RW NP +LIM +0 2 0 +V RW NP +LIM +0 2 0 + +* +* Supported Channel Width Set +* By default set to zero for +* STAs does not support either 160 or 80+80MHz +* +WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* LDPC Coding Capability +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_LDPC_CODING_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Short GI for 80MHz +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_SHORT_GI_80MHZ I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* Short GI for 160MHz and 80+80MHz +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Transmission of 2x1 STBC +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_TXSTBC I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Reception of PPDUs using STBC +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_RXSTBC I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* Support for Operating as SU Beamformer +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_SU_BEAMFORMER_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Operating as SU Beamformee +* Riva does not support, But Pronto supports, default set to 0 +* +WNI_CFG_VHT_SU_BEAMFORMEE_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Compressed Steering Number of Beamformer Antennas Supported +* Riva does not support,Pronto supports, default set to 0 +* +WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED I 4 19 +V RW NP +LIM +0 4 0 +V RW NP +LIM +0 4 0 + +* +* Number of Sounding Dimensions indicates Number +* of antennas used by the beamformer when sending beamformed transmissions +* Riva/Pronto does not support beamformer, default set to 0 +* +WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +* +* MU Beamformer Capable +* Riva/Pronto does not support, default set to 0 +* +WNI_CFG_VHT_MU_BEAMFORMER_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* MU Beamformee Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_MU_BEAMFORMEE_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* VHT TXOP PS +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_TXOP_PS I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* +HTC-VHT Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_HTC_VHTC_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Maximum AMPDU Length exponent range 0-7 +* 2^(13+Max AMPDU Length)-1, default set to 0 +* +WNI_CFG_VHT_AMPDU_LEN_EXPONENT I 4 19 +V RW NP +LIM +0 7 3 +V RW NP +LIM +0 7 3 + +* +* VHT Link Adaptation Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_LINK_ADAPTATION_CAP I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +* +* VHT Rx Antenna Pattern Consistency +* +WNI_CFG_VHT_RX_ANT_PATTERN I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* VHT Tx Antenna Pattern Consistency +* +WNI_CFG_VHT_TX_ANT_PATTERN I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* RxMCS Map is 16 bits, The 2bit Max MCS for n SS field. +* Indicates the maximum MCS that can be received for each +* number of spacial streams. Riva supports MCS 0-9 +* +WNI_CFG_VHT_RX_MCS_MAP I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* TxMCS Map is 16 bits, The 2bit Max MCS for n SS field. +* Indicates the maximum MCS that can be transmitted for each +* number of spacial streams. +* +WNI_CFG_VHT_TX_MCS_MAP I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* +* Rx Highest supported data rate. +* +WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE I 4 19 +V RW NP +LIM +0 780 780 +V RW NP +LIM +0 780 780 + +* +* Tx Highest supported data rate. +* +WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE I 4 19 +V RW NP +LIM +0 780 780 +V RW NP +LIM +0 780 780 + +* +* VHT Operation Information +* Channel Width set to zero for 20/40MHz. +* set to 1 for 80MHz. 2->160Mhz, 3->80+80MHz +* +WNI_CFG_VHT_CHANNEL_WIDTH I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +#ENUM 20_40MHZ 0 +#ENUM 80MHZ 1 +#ENUM 160MHZ 2 +#ENUM 80_PLUS_80MHZ 3 +* +* Channel center freq Seg1 +* +WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1 I 4 19 +V RW NP +LIM +0 256 0 +V RW NP +LIM +0 256 0 + +* +* Channel center freq Seg2 for 80+80 Mhz +* +WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2 I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Basic MCS Set +* +WNI_CFG_VHT_BASIC_MCS_SET I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* +* MU-MIMO Capable STA Count +* +WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT I 4 19 +V RW NP +LIM +0 4 0 +V RW NP +LIM +0 4 0 + +* +* Spatial Stream Under-Utilization +* +WNI_CFG_VHT_SS_UNDER_UTIL I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Forty MHZ Utilization +* +WNI_CFG_VHT_40MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Eighty MHz Utilization +* +WNI_CFG_VHT_80MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Hundred Sixty MHz Utilization +* +WNI_CFG_VHT_160MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Maximum AMSDU length +* User can set it to either 3839 or 7935 bytes. +* +WNI_CFG_MAX_AMSDU_LENGTH I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 0 + +#ENUM SHORT_3839_BYTES 0 +#ENUM LONG_7935__BYTES 1 + + +* +* Minimum MPDU Start Spacing +* Determines the minimum time between the start of adjacent MPDUs within an AMPDU. +* Set to 0 for no restriction +* Set to 1 for 1/4 s +* Set to 2 for 1/2 s +* Set to 3 for 1 s +* Set to 4 for 2 s +* Set to 5 for 4 s +* Set to 6 for 8 s +* Set to 7 for 16 s +* default is set to 0 +WNI_CFG_MPDU_DENSITY I 4 7 +V RW NP RESTART +LIM +0 7 0 +V RW NP RESTART +LIM +0 7 0 + +* +* NUM BUFFERS ADVERTISED +* Defines number of buffers advertised in ADDBA +* +WNI_CFG_NUM_BUFF_ADVERT I 4 7 +V RW NP +LIM +0 128 64 +V RW NP +LIM +0 128 64 + +* +* Maximum Rx AMPDU Factor +* Indicates the maximum length of A-MPDU +* that the STA can receive. +* The Maximum Rx A-MPDU defined by this field is equal to (2 ^ (13 + MAX RX AMPDU FActor))-1 octets. +* Maximum Rx A-MPDU Factor is an integer in the range 0 to 3. +* default is set to 2 for 32K max RX side. +* +WNI_CFG_MAX_RX_AMPDU_FACTOR I 4 7 +V RW NP RESTART +LIM +0 3 3 +V RW NP RESTART +LIM +0 3 3 + + +* +* Short GI support for the reception of 20Mhz packets +* By default it is enabled +* +WNI_CFG_SHORT_GI_20MHZ I 4 7 +V RW NP RESTART +LIM +0 1 1 +V RW NP RESTART +LIM +0 1 1 + + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* +* Short GI support for the reception of 40Mhz packets +* By default it is enabled +* +WNI_CFG_SHORT_GI_40MHZ I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 1 + + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* +* RIFS support on TX Side +* on RX side it is always supported, it is mandatory +* +WNI_CFG_RIFS_ENABLED I 4 7 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* ********************************************************* +* +* Power Save Configuration +* +WNI_CFG_MAX_PS_POLL I 4 5 +V RW NP +LIM +0 255 0 +NV RW NP +LIM +0 255 0 + + +WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE I 4 5 +V RW NP +LIM +1 20 20 +NV RW NP +LIM +1 20 20 + + +* +* Period for which Firmware will collect the +* RSSI stats. Its in units of beacon interval. +* Rssi Filter period should always be >= +* the num_beacon_per_rssi_average. +* +WNI_CFG_RSSI_FILTER_PERIOD I 4 5 +V RW NP +LIM +0 255 5 +NV RW NP +LIM +0 255 5 + + +WNI_CFG_MIN_RSSI_THRESHOLD I 4 5 +V RW NP +LIM +0 10 10 +NV RW NP +LIM +0 10 10 + + +WNI_CFG_NTH_BEACON_FILTER I 4 5 +V RW NP +LIM +0 255 10 +NV RW NP +LIM +0 255 10 + + +WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE I 4 5 +V RW NP +LIM +0 1 0 +NV RW NP +LIM +0 1 0 + + +WNI_CFG_SCAN_IN_POWERSAVE I 4 5 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + + +* +* Ignore DTIM support - If disabled(value=0), HAL will +* try to align the Listen Interval to the DTIM +* period and the following rules will be applied: +* 1) If LI=DTIM, then set LI=DTIM +* 2) If LIDTIM, then set LI=DTIM +* +WNI_CFG_IGNORE_DTIM I 4 5 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* ********************************************************* +* +* WoWLAN Configuration The following configurations +* are valid only when magicPktEnable = 1. +* +WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_DEAUTH_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_DISASSOC_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_MAX_MISSED_BEACON I 4 5 +V RW NP +NONE +0 65535 40 +NV RW NP +NONE +0 65535 40 + +* +* Timeout value in units of us. It requests +* hardware to unconditionally wake up after +* it has stayed in WoWLAN mode for some time. +* +WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD I 4 5 +V RW NP +NONE +0 65535 65535 +NV RW NP +NONE +0 65535 65535 + + +* +* BA timeout in TUs, set to 1 minute = approx 58593 TUs +* 16 bit wide +* +WNI_CFG_BA_TIMEOUT I 4 7 +V RW NP RESTART +HAL +0 0xffff 0 +V RW NP +HAL +0 0xffff 0 + + +* +* This threshold is registered with a traffic monitoring interface (probably HAL), +* on a per-STA, per-TID basis. Once this threshold has been reached, +* HAL will indicate to PE that the threshold has been reached for that TID. +* PE is then free to negotiate a BA session for that peer +* defaults to 128 +* 16 bit wide +* +WNI_CFG_BA_THRESHOLD_HIGH I 4 7 +V RW NP RESTART +HAL +0 0xffff 0x80 +V RW NP +HAL +0 0xffff 0x80 + + +* +* MAX BA Buffers to be allocated. +* This count is system wide. +* 16 bit wide +* +WNI_CFG_MAX_BA_BUFFERS I 4 7 +V RW NP RESTART +HAL +0 2560 2560 +V RW NP +HAL +0 2560 2560 + + +* +* MAX BA Sessions. +* This count is system wide. +* 16 bit wide +* +WNI_CFG_MAX_BA_SESSIONS I 4 7 +V RW NP RESTART +HAL +0 64 40 +V RW NP +HAL +0 64 40 + + +* +* BA setup based on Traffic +* +WNI_CFG_BA_AUTO_SETUP I 4 7 +V RW NP RESTART +HAL +0 1 1 +V RW NP RESTART +HAL +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +* +* Decline an ADDBA Request +* +WNI_CFG_ADDBA_REQ_DECLINE I 4 7 +V RW NP RESTART +LIM +0 0xff 0 +V RW NP RESTART +LIM +0 0xff 0 + +* +* Delete all Rx BA sessions in 2.4 GHz +* when BTC requests to disable agg. +* +WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + + +* +* Valid Channel List +* + +WNI_CFG_BG_SCAN_CHANNEL_LIST S 100 8 +V RW NP +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 +V RW NP +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 + + +* +* AMPDU default TX medium Time (in us) +* +WNI_CFG_MAX_MEDIUM_TIME I 4 8 +V RW NP +HAL +0 65535 2048 +V RW NP +HAL +0 65535 2048 + + +* +* Maximum number of MPDUs in single A-MPDU. +* +WNI_CFG_MAX_MPDUS_IN_AMPDU I 4 8 +V RW NP +HAL +0 65535 64 +V RW NP +HAL +0 65535 64 + + +* +* Auto BSSID - When set, BSSID is generated automatically in IBSS, else BSSID in cfg will be used. +* + +WNI_CFG_IBSS_AUTO_BSSID I 4 0 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* Include Additional IEs in probe request. +* +WNI_CFG_PROBE_REQ_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in probe request. +* +WNI_CFG_PROBE_REQ_ADDNIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IEs in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA1 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA2 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA3 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IEs in assoc response. +* +WNI_CFG_ASSOC_RSP_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in assoc response. +* +WNI_CFG_ASSOC_RSP_ADDNIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional P2P IEs in probe request. +* +WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional P2P IE in probe request. +* +WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + + +* +* Include Additional IEs in probe response/beacon. +* +WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG I 4 0 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + + +* +* Include Additional IEs in probe response/beacon. +* +WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA S 255 0 +V RW NP +LIM +0 0 +V RW NP +LIM +0 0 + + +* +* wpsApEnable and wpsStaEnable is specified in here +* wpsApEnable is bit #0 and wpsStaEnable is bit #1 +* +WNI_CFG_WPS_ENABLE I 4 7 +V RW NP +LIM +0 0xff 0 +V RW NP +LIM +0 0xff 0 + +#ENUM AP 1 +#ENUM STA 2 + +WNI_CFG_WPS_STATE I 4 7 +V RW NP +LIM +0 0xff 1 +V RW NP +LIM +0 0xff 1 + +* +* TRUE => include this information in Probe Requests, FALSE => omit it +* + +WNI_CFG_WPS_PROBE_REQ_FLAG I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Wi-Fi Protected Setup Version +* +* This one-byte field is broken into a four-bit major +* part using the top MSBs and four-bit minor part +* using the LSBs. As an example, version 3.2 would be 0x32. +* + +WNI_CFG_WPS_VERSION I 4 7 +V RW NP +LIM +0 0xff 0x10 +V RW NP +LIM +0 0xff 0x10 + +* +* Wi-Fi Protected Setup Request type +* 0x00: Enrollee, Info only +* 0x01: Enrollee, open 802.1X +* 0x02: Registrar +* 0x03: WLAN Manager Registrar + +WNI_CFG_WPS_REQUEST_TYPE I 4 7 +V RW NP +LIM +0 0xff 0x00 +V RW NP +LIM +0 0xff 0x03 + +* Configuration Method(s) +* +* The Config Methods Data component lists the configuration methods +* the Enrollee or Registrar supports. The list is a bitwise OR of +* values from the table below. In addition to Config Methods, APs and +* STAs that support the UPnP Management Interface must support the +* Permitted Config Methods attribute, which is used to control the +* Config Methods that are enabled on that AP. +* +* Value Hardware Interface +* 0x0001 USBA (Flash Drive) +* 0x0002 Ethernet +* 0x0004 Label +* 0x0008 Display +* 0x0010 External NFC Token +* 0x0020 Integrated NFC Token +* 0x0040 NFC Interface +* 0x0080 PushButton +* 0x0100 Keypad +* +* The bottom 16 bits contain the configuration method(s) when acting +* as an Enrollee, and the top 16 when acting as a Registrar. +* +* QNE-TODO: Merge this with the inappropriately named +* 'WNI_CFG_WSC_AP_CFG_METHOD'-- this one can serve both puposes. +* + +WNI_CFG_WPS_CFG_METHOD I 4 7 +V RW NP +LIM +0 0xFFFFFFFF 0x00000008 +V RW NP +LIM +0 0xFFFFFFFF 0x018c018e + +* UUID +* The universally unique identifier (UUID) element is a unique +* GUID generated by the Enrollee or Registrar. It uniquely identifies +* an operational device and should survive reboots and resets. The +* UUID is provided in binary format. If the device also supports UPnP, +* then the UUID corresponds to the UPnP UUID. +* +* QNE-TODO: Re-name their cfg from 'WNI_CFG_UUID' + +WNI_CFG_WPS_UUID S 16 8 +V RW NP +LIM +6 0xa 0xb 0xc 0xd 0xe 0xf +V RW NP +LIM +6 0xa 0xb 0xc 0xd 0xe 0xf + +************************************************************************ +* The following cfgs contains the primary type of the device. Its format +* follows: +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Attribute ID | Length | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Category ID | OUI (1-2) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | OUI (3-4) | Sub Category ID | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* Vendor-specific sub-categories are designated by setting the OUI to the +* value associated with that vendor. Note that a four-byte subdivided OUI +* is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04 +* is used. The predefined values for Category ID and Sub Category ID are +* provided in the next table. There is no way to indicate a vendor-specific +* main device category. The OUI applies only to the interpretation of the +* Sub Category. If a vendor does not use sub categories for their OUI, the +* three-byte OUI occupies the first three bytes of the OUI field and the +* fourth byte is set to zero. +* +* Category ID Value Sub Category ID Value +* Computer 1 PC 1 +* Server 2 +* Media Center 3 +* Input Device 2 +* Printers, Scanners, Printer 1 +* Faxes and Copiers 3 Scanner 2 +* Camera 4 Digital Still Camera 1 +* Storage 5 NAS 1 +* Network AP 1 +* Infrastructure 6 Router 2 +* Switch 3 +* Displays 7 Television 1 +* Electronic Picture Frame 2 +* Projector 3 +* Multimedia Devices 8 DAR 1 +* PVR 2 +* MCX 3 +* Gaming Devices 9 Xbox 1 +* Xbox360 2 +* Playstation 3 +* Telephone 10 Windows Mobile 1 +* +************************************************************************ + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_CATEGORY' +WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY I 4 7 +V RW NP +LIM +0 0xffff 1 +V RW NP +LIM +0 0xffff 6 + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_OUI' +WNI_CFG_WPS_PIMARY_DEVICE_OUI I 4 7 +V RW NP +LIM +0 0xffffffff 0x0050f204 +V RW NP +LIM +0 0xffffffff 0x0050f204 + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_SUB_CATEGORY' +WNI_CFG_WPS_DEVICE_SUB_CATEGORY I 4 7 +V RW NP +LIM +0 0xffff 1 +V RW NP +LIM +0 0xffff 1 + +* Association State +* + +* The Association State component shows the configuration and previous +* association state of the wireless station when sending a Discovery +* request. +* +* Association State Description +* 0 Not Associated +* 1 Connection Success +* 2 Configuration Failure +* 3 Association Failure +* 4 IP Failure + +WNI_CFG_WPS_ASSOCIATION_STATE I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* Configuration Error +* +* The Configuration Error component shows the result of the device +* attempting to configure itself and to associate with the WLAN. +* +* Configuration Error Description +* 0 No Error +* 1 OOB Interface Read Error +* 2 Decryption CRC Failure +* 3 2.4 channel not supported +* 4 5.0 channel not supported +* 5 Signal too weak +* 6 Network auth failure +* 7 Network association failure +* 8 No DHCP response +* 9 Failed DHCP config +* 10 IP address conflict +* 11 Couldnt connect to Registrar +* 12 Multiple PBC sessions detected +* 13 Rogue activity suspected +* 14 Device busy +* 15 Setup locked +* 16 Message Timeout +* 17 Registration Session Timeout +* 18 Device Password Auth Failure +* +* The Device busy error is returned if the sending device is unable to +* respond to the request due to some internal conflict or resource +* contention issue. For example, if a device is only capable of +* performing a single instance of the Registration Protocol at a time, +* it may return this error in response to attempts to start another +* instance in the middle of an active session. + +WNI_CFG_WPS_CONFIGURATION_ERROR I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* Device Password ID +* + +* This attribute is used to identify a device password. There are six +* predefined values and ten reserved values. If the Device Password ID is +* Default, the Enrollee should use its PIN password (from the label or +* display). This password may correspond to the label, display, or a +* user-defined password that has been configured to replace the original +* device password. +* +* User-specified indicates that the user has overridden the password with a +* manually selected value. Machine-specified indicates that the original +* PIN password has been overridden by a strong, machinegenerated device +* password value. The Rekey value indicates that the device's 256-bit +* rekeying password will be used. The PushButton value indicates that the +* PIN is the all-zero value reserved for the PushButton Configuration +* method. +* +* The Registrar-specified value indicates a PIN that has been obtained from +* the Registrar (via a display or other out-of-band method). This value may +* be further augmented with the optional 'Identity' attribute in M1. This +* augmentation is useful when multiple predefined UserID/PIN pairs have been +* established by a Registrar such as an authenticator used for Hotspot +* access. If the Device Password ID in M1 is not one of the predefined or +* reserved values, it corresponds to a password given to the Registrar as an +* OOB Device Password. +* +* Value Description +* 0x0000 Default (PIN) +* 0x0001 User-specified +* 0x0002 Machine-specified +* 0x0003 Rekey +* 0x0004 PushButton +* 0x0005 Registrar-specified +* 0x0006 - 0x000F Reserved' +* + +WNI_CFG_WPS_DEVICE_PASSWORD_ID I 4 7 +V RW NP +LIM +0 0xffffffff 0 +V RW NP +LIM +0 0xffffffff 0 + +* +* WPS Association +* +* Wi-Fi Protected Setup requires a prospective enrollee to associate to +* an AP in the network in which the STA would like to enroll. Once +* associated, the enrollment takes place over an EAPOL conversation +* (there's actually a new EAP method: EAP-WSC). The STA would +* presumably send an EAPOL-Start over his new link, to which the AP +* would respond with an EAP Identity Request. When the STA sends back +* "WSC-Enrollee-1" as his EAP Identity, the AP knows that he's got a WPS +* supplicant on his hands, and proceeds to talk EAP-WSC. +* +* Toward the end of the specification's development, a problem came up. +* Microsoft's EAP supplicant on XP SP1 & SP2 will send an EAPOL-Start, +* no matter what. Even if the AP is beaconing WPA-PSK, say, the MS +* supplicant will send an EAPOL-Start. If it receives an EAP Identity +* Request in return, it decides that the AP is really using 802.1x +* authentication, and proceeds on that assumption. +* +* Now, imagine an AP that is configured for WPA-PSK, and is WPS-capable. +* It receives an association request from some STA, and then sees an +* EAPOL-Start from the newly joined STA. It naturally sends back an EAP +* Identity Request to see if the new STA wants to talk EAP-WSC. On +* Windows XP SP1 & SP2, the supplicant will take that to mean that this +* AP is using 802.1x authentication, and will never let the user provide +* the PSK. Consequently, WZC will never be able to associate with this +* AP. +* +* Naturally, Microsoft's solution was to have the world change to +* accommodate them. After a lot of back & forth, the WFA decided on the +* following change to the WPS spec: when associating for purposes of WPS +* enrollment, "A client that intends to use the EAP-WSC method with a +* WSC enabled AP may include a WSC IE in its 802.11 (re)association +* request. If a WSC IE is present in the (re)association request, the AP +* shall engage in EAP-WSC with the station and must not attempt other +* security handshake. If the client does not include a WSC IE in its +* 802.11 (re)association request, it must send its 802.11 Authentication +* frame with Authentication set to open and an 802.11 Association +* Request frame without an RSN IE or SSN IE, regardless of the network +* type that is hosted by the AP. On successful association, the client +* will then send an EAPOL-Start to the AP and wait for +* EAP-Request/Identity. When the client receives an EAP Request/ +* Identity, it will respond with EAP-Response/Identity and the +* appropriate WSC string to indicate if it is an Enrollee or Registrar. +* ' +* +* This configuration variable contains a bitvector: +* +* 0x0001 Incldue the WPS Information Element in Assoc Request frames +* 0x0002 Elide the the WPA and RSN Information Elements from the +* Assoc Request frame +* + +WNI_CFG_WPS_ASSOC_METHOD I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* +* Low gain override +* + +WNI_CFG_LOW_GAIN_OVERRIDE I 4 9 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* Listen Mode Enable/Disable +* + +WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE I 4 7 +V RW NP +HAL +0 128 128 +V RW NP +HAL +0 128 128 + +* +* On chip reodering polling threshold +* + +WNI_CFG_RPE_POLLING_THRESHOLD I 4 2 +V RW NP +HAL +0 65535 10 +V RW NP +HAL +0 65535 10 + +* +* On chip reodering aging threshold for AC0 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC1 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC2 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC3 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* Number of On-Chip reorder sessions +* + +WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS I 4 2 +V RW NP +HAL +0 2 1 +V RW NP +HAL +0 2 1 + + +* +* Single RC for all TID +* + +WNI_CFG_SINGLE_TID_RC I 4 7 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* RRM Enabled +* + +WNI_CFG_RRM_ENABLED I 4 8 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* RRM measurement max duration. Section 11.10.3 802.11k-2008. +* Max Duration represented as maxDuration inTUs = 2^(*WNI_CFG_RRM_IN_CHAN_MAX - 4) * bcnIntvl +* Operating channel max measurement duration. +* + +WNI_CFG_RRM_OPERATING_CHAN_MAX I 4 8 +V RW NP +NONE +0 8 0 +V RW NP +NONE +0 8 0 + +* +* Non-Operating channel max measurement duration. +* + +WNI_CFG_RRM_NON_OPERATING_CHAN_MAX I 4 8 +V RW NP +NONE +0 8 0 +V RW NP +NONE +0 8 0 + +* +* TX power control feature +* + +WNI_CFG_TX_PWR_CTRL_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* MCAST BCAST filter Setting +* 0: No filter, 1: Block Mcast, 2: Block Bcast, 3: Block Mcast and Bcast +* + +WNI_CFG_MCAST_BCAST_FILTER_SETTING I 4 7 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +* +* BTC DHCP No of Bt slots to block +* +WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK I 4 7 +V RW NP +HAL +0 0xFF 0 +V RW NP +HAL +0 0xFF 0 + +* +* Config parameter to Enable/Disable Dynamic PS-Poll mechanism +* 0: Disable, x: FW will send x number of NULL frames before switching to PS-Poll mexhanism +* +WNI_CFG_DYNAMIC_PS_POLL_VALUE I 4 7 +V RW NP +HAL +0 0xFF 0 +V RW NP +HAL +0 0xFF 0 + +* +* PS Data InActivity Timeout (TU) +* + +WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT I 4 7 +V RW NP +HAL +0 80 0 +NV RW NP +NONE +0 80 0 + +* +* Config parameter to Enable/Disable Telescopic Bcn Wakeups +* 0: Disable, 1: Enable +* + +WNI_CFG_TELE_BCN_WAKEUP_EN I 4 7 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + + +* +* Config parameter for Transient LI +* 0: Disable, x: Transient LI +* + +WNI_CFG_TELE_BCN_TRANS_LI I 4 7 +V RW NP +HAL +0 7 3 +V RW NP +HAL +0 7 3 + +* +* Config parameter for Idle bcns for Transient LI +* x: Num Idle bcns before switch to trans LI +* + +WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS I 4 7 +V RW NP +HAL +5 255 10 +V RW NP +HAL +5 255 10 + +* +* Config parameter for Max LI +* 0: Disable, x: Max LI +* + +WNI_CFG_TELE_BCN_MAX_LI I 4 7 +V RW NP +HAL +0 7 5 +V RW NP +HAL +0 7 5 + +* +* Config parameter for Idle bcns for max LI +* x: Num Idle bcns before switch to max LI +* + +WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS I 4 7 +V RW NP +HAL +5 255 15 +V RW NP +HAL +5 255 15 + +* +* BTC DHCP No of Bt sub interval during DHCP +* +WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS I 4 7 +V RW NP +HAL +0 0xFF 7 +V RW NP +HAL +0 0xFF 7 + +* +* Infra STA mode Keep alive period (in secs) for +* sending keep alive (Qos)Null frames to the AP. +* 0 = disabled. Recommended values is 30 secs +* +WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD I 4 7 +V RW NP +HAL +0 1000 0 +V RW NP +HAL +0 1000 0 + +* Limit on number of associated stations +* (applies to peer stations in IBSS, SoftAP, BT-AMP AP, & P2P-GO modes) +* + +WNI_CFG_ASSOC_STA_LIMIT I 4 8 +V RW NP +LIM +1 32 10 +V RW NP +LIM +1 32 10 + +* +* SAP channel select start channel number +* +WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL I 4 7 +V RW NP +NONE +1 0xFC 1 +V RW NP +NONE +1 0xFC 1 + +* +* SAP channel select end channel number +* +WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL I 4 7 +V RW NP +NONE +1 0xFC 11 +V RW NP +NONE +1 0xFC 11 + +* +* SAP channel select operating band +* 0- 2.4GHZ / 1- Low 5GHZ /2-MID /3-HIGH/4-Japan4.9GHZ +* +WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND I 4 7 +V RW NP +NONE +0 0x5 0 +V RW NP +NONE +0 0x5 0 + +* +* Softap data available poll period (in milliseconds) for +* queueing (Qos)Null frames to the station if there +* is no data available and PS-Poll/Trigger frame is pending. +* 0 = disabled. Recommended values is 5ms +* +WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD I 4 8 +V RW NP +NONE +0 65535 5 +V RW NP +NONE +0 65535 5 + +* +* Close loop power control will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_CLOSE_LOOP I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* LTE Coexistence will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_LTE_COEX I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* AP Keep Alive Timeout (TU) +* +WNI_CFG_AP_KEEP_ALIVE_TIMEOUT I 4 7 +V RW NP +HAL +1 65535 20 +V RW NP +HAL +1 65535 20 + +* +* GO Keep Alive Timeout (TU) +* +WNI_CFG_GO_KEEP_ALIVE_TIMEOUT I 4 7 +V RW NP +HAL +1 65535 20 +V RW NP +HAL +1 65535 20 + +* +* MC Addr List power control will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_MC_ADDR_LIST I 4 0 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* UC Filter will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_UC_FILTER I 4 0 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* Low Power Image Transition will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_LPWR_IMG_TRANSITION I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* MCC Adaptive Scheduler will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 +* +*Disable LDPC in STA mode when AP is TXBF capable +* +* +* +WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* AP Link Monitor Timeout (TU) +* +WNI_CFG_AP_LINK_MONITOR_TIMEOUT I 4 7 +V RW NP +HAL +1 255 3 +V RW NP +HAL +1 255 3 + +* +*TDLS Station's UAPSD MASK Configuration +* +* +* +WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK I 4 7 +V RW NP +LIM +0 15 0 +V RW NP +LIM +0 15 0 +* +*TDLS Stations Buffer STA Capability +* +* +* +WNI_CFG_TDLS_BUF_STA_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 +*TDLS Stations PUAPSD Inactivity Timer +* +* +* +WNI_CFG_TDLS_PUAPSD_INACT_TIME I 4 7 +V RW NP +LIM +0 10 0 +V RW NP +LIM +0 10 0 +*TDLS Stations PUAPSD RX Frame Threshold +* +* +* +WNI_CFG_TDLS_RX_FRAME_THRESHOLD I 4 7 +V RW NP +LIM +10 20 10 +V RW NP +LIM +10 20 10 + +* +* PMF SA Query Maximum Retries +* + +WNI_CFG_PMF_SA_QUERY_MAX_RETRIES I 4 1 +V RW NP RESTART +NONE +0 20 5 +V RW NP RESTART +NONE +0 20 5 + +* +* PMF SA Query Retry Interval (in TUs) +* + +WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL I 4 1 +V RW NP RESTART +NONE +10 2000 200 +V RW NP RESTART +NONE +10 2000 200 + + +* +*MCC ENABLE/DISABLE ADAPTIVE RX Drain feature +* +* +* +WNI_CFG_ENABLE_ADAPT_RX_DRAIN I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +HAL +0 1 1 + +* +* FlexConnect Power Factor +* Default is set to 0 (disable) +* +* +WNI_CFG_FLEX_CONNECT_POWER_FACTOR I 4 0 +V RW NP +NONE +0 9 0 +V RW NP +NONE +0 9 0 + +* +* Antenna Diversity +* +* 0 = disabled +* 1 = Ant 1 +* 2 = Ant 2 +* 3 = Adaptive +* +WNI_CFG_ANTENNA_DIVESITY I 4 7 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +* GO Link Monitor Timeout (TU) +* +WNI_CFG_GO_LINK_MONITOR_TIMEOUT I 4 7 +V RW NP +HAL +3 50 10 +V RW NP +HAL +3 50 10 +* +* + +* RMC action period frequency (milli seconds) +* +WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY I 4 7 +V RW NP +HAL +100 1000 300 +V RW NP +HAL +100 1000 300 +* +* + +* Current RSSI value (of connected AP) +* +WNI_CFG_CURRENT_RSSI I 4 7 +V RW NP +NONE +0 127 0 +V RW NP +NONE +0 127 0 + +* RTT3 Bit Value +* +WNI_CFG_RTT3_ENABLE I 1 1 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* Debug p2p remain on channel +* +WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* TDLS Off Channel Implementation +* +WNI_CFG_TDLS_OFF_CHANNEL_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +WNI_CFG_IBSS_ATIM_WIN_SIZE I 4 7 +V RW NP +NONE +0 100 0 +V RW NP +NONE +0 100 0 + +* +* DFS Master capability (11h) enable/disable +* + +WNI_CFG_DFS_MASTER_ENABLED I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +WNI_CFG_VHT_ENABLE_TXBF_20MHZ I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +*TDLS WMM Mode +* +* +WNI_CFG_TDLS_WMM_MODE_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms new file mode 100644 index 0000000000000..c2c74192d0ea6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/cfgUtil/dot11f.frms @@ -0,0 +1,4248 @@ +/* + * Copyright (c) 2006-2007, 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 2006-2007,2014 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + */ + +/** + * \file dot11f.frms + * + * \brief Primary 'frames' file for the MAC parser + * + * + * This file defines several 802.11 frames (along with their associated + * constituents) in a little language called "frames". When run through the + * 'framesc' program, it will generate C code for working with these frames: + * C structs representing the 802.11 frame together with functions for + * packing & unpacking them. + * + * For more information on the "frames" language, run 'framesc --help'... + * + * + */ + + +// Tell framesc what types to use for... +%8-bit-type tANI_U8 // 8, +%16-bit-type tANI_U16 // 16, +%32-bit-type tANI_U32 // & 32-bit unsigned integral types. These can also + // be specified on the command line. + +// Define some mnemonic constants; these are just for our use with the frames +// files we're compiling. IOW, they won't result in any C code being +// emitted. + +const EID_SSID = 0; +const EID_SUPP_RATES = 1; +const EID_FH_PARAM_SET = 2; +const EID_DS_PARAM_SET = 3; +const EID_CF_PARAM_SET = 4; +const EID_TIM = 5; +const EID_IBSS_PARAM_SET = 6; +const EID_COUNTRY = 7; +const EID_FH_PATTERN = 8; +const EID_FH_PATT_TABLE = 9; +const EID_REQUEST = 10; +const EID_QBSS_LOAD = 11; +const EID_EDCA_PARAM_SET = 12; +const EID_TSPEC = 13; +const EID_TCLAS = 14; +const EID_SCHEDULE = 15; +const EID_CHALLENGE_TEXT = 16; +const EID_POWER_CONSTRAINTS = 32; +const EID_POWER_CAPABILITY = 33; +const EID_TPC_REQUEST = 34; +const EID_TPC_REPORT = 35; +const EID_SUPPORTED_CHANNELS = 36; +const EID_CHANNEL_SWITCH_ANN = 37; +const EID_MEAS_REQUEST = 38; +const EID_MEAS_REPORT = 39; +const EID_QUIET = 40; +const EID_ERP_INFO = 42; +const EID_TS_DELAY = 43; +const EID_TCLASS_PROC = 44; +const EID_HT_CAPABILITIES = 45; +const EID_QOS_CAPABILITY = 46; +const EID_RSN = 48; +const EID_EXT_SUPP_RATES = 50; +const EID_AP_CHAN_REPORT = 51; +const EID_NEIGHBOR_REPORT = 52; +const EID_RCPI = 53; +const EID_FT_MOBILITY_DOMAIN = 54; +const EID_FT_INFO = 55; +const EID_TIMEOUT_INTERVAL = 56; +const EID_FT_RIC_DATA = 57; +const EID_SUPPORTED_OPER_CLASSES = 59; +const EID_HT_INFO = 61; +const EID_EXT_CHANNEL_SWITCH_ANN = 62; +const EID_RSNI = 65; +const EID_RRM_MEAS_PILOT_TX_INFO = 66; +const EID_WAPI = 68; +const EID_RRM_ENABLED_CAPS = 70; +const EID_MULTIPLE_BSSID = 71; +const EID_20_40_BSS_COEXISTENCE = 72; +const EID_20_40_BSS_INTOLERANT_REPORT= 73; +const EID_OBSS_SCAN_PARAMETERS = 74; +const EID_FT_RIC_DESCRIPTOR = 75; +const EID_LINK_IDENTIFIER = 101; +const EID_PTI_CONTROL = 105; +const EID_PU_BUFFER_STATUS = 106; +const EID_QOS_MAP_SET = 110; +const EID_ESE_SPECIFIC = 150; +const EID_ESE_CCKM_SPECIFIC = 156; +const EID_VHT_CAPABILITIES = 191; +const EID_VHT_OPERATION_ELEMENT = 192; +const EID_VHT_EXT_BSS_LOAD = 193; +const EID_AID = 197; +const EID_EXT_CAP = 127; +const EID_OPERATING_MODE = 199; +const EID_WIDER_BW_CHANNEL_SWITCH_ANN= 194; +const EID_CHANNEL_SWITCH_WRAPPER = 196; +const EID_VENDOR_SPECIFIC = 221; + +const SIR_MAC_PROP_EXT_RATES_TYPE = 0; +const SIR_MAC_PROP_AP_NAME_TYPE = 1; +const SIR_MAC_PROP_HCF_TYPE = 2; +const SIR_MAC_PROP_WDS_TYPE = 3; +const SIR_MAC_PROP_BP_IND_TYPE = 4; +const SIR_MAC_PROP_NEIGHBOR_BSS_TYPE = 5; +const SIR_MAC_PROP_LOAD_INFO_TYPE = 6; +const SIR_MAC_PROP_ASSOC_TYPE = 7; +const SIR_MAC_PROP_LOAD_BALANCE_TYPE = 8; +const SIR_MAC_PROP_LL_ATTR_TYPE = 9; +const SIR_MAC_PROP_CAPABILITY = 10; +const SIR_MAC_PROP_VERSION = 11; +const SIR_MAC_PROP_EDCAPARAMS = 12; +const SIR_MAC_PROP_TITAN = 14; +const SIR_MAC_PROP_CHANNEL_SWITCH = 15; +const SIR_MAC_PROP_QUIET_BSS = 16; +const SIR_MAC_PROP_TRIG_STA_BK_SCAN = 17; +const SIR_MAC_PROP_TAURUS = 18; + +const ANI_WDS_INFO_MAX_LENGTH = 64; +const SIR_MAC_MAX_NUMBER_OF_RATES = 12; +const HT_MAX_SUPPORTED_MCS_SET = 16; +const MAX_SUPPORTED_NEIGHBOR_RPT = 15; + +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Protected Setup TLV Identifiers // +// WSC Version 2.0.0 Table 28 // +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Simple Configuration TLV Identifiers // +// WFA Vendor Extension Subelements // +///////////////////////////////////////////////////////////////////////////// +const TLV_VERSION2 = 0; +const TLV_AUTHORIZED_MAC = 1; +const TLV_NETWORK_KEY_SHAREABLE = 2; +const TLV_REQUEST_TO_ENROLL = 3; +const TLV_SETTINGS_DELAY_TIME = 4; + +const TLV_VERSION = 0x104A; +const TLV_WI_FI_SIMPLE_CONFIG_STATE = 0x1044; +const TLV_AP_SETUP_LOCKED = 0x1057; +const TLV_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053; +const TLV_DEVICE_PASSWORD_ID = 0x1012; +const TLV_UUID_E = 0x1047; +const TLV_UUID_R = 0x1048; +const TLV_RF_BANDS = 0x103C; +const TLV_REQUEST_TYPE = 0x103A; +const TLV_RESPONSE_TYPE = 0x103B; +const TLV_CONFIG_METHODS = 0x1008; +const TLV_PRIMARY_DEVICE_TYPE = 0x1054; +const TLV_ASSOCIATION_STATE = 0x1002; +const TLV_CONFIGURATION_ERROR = 0x1009; +const TLV_MANUFACTURER = 0x1021; +const TLV_MODEL_NAME = 0x1023; +const TLV_MODEL_NUMBER = 0x1024; +const TLV_SERIAL_NUMBER = 0x1042; +const TLV_DEVICE_NAME = 0x1011; +const TLV_SELECTED_REGISTRAR = 0x1041; +const TLV_VENDOR_EXTENSION = 0x1049; +const TLV_REQUESTED_DEVICE_TYPE = 0x106A; + +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Direct/P2P TLV Identifiers // +///////////////////////////////////////////////////////////////////////////// +const TLV_P2P_STATUS = 0; +const TLV_MINOR_REASON_CODE = 1; +const TLV_P2P_CAPABILITY = 2; +const TLV_P2P_DEVICE_ID = 3; +const TLV_P2P_GROUP_OWNER_INTENT = 4; +const TLV_CONFIGURATION_TIMEOUT = 5; +const TLV_LISTEN_CHANNEL = 6; +const TLV_P2P_GROUP_BSSID = 7; +const TLV_EXTENDED_LISTEN_TIMING = 8; +const TLV_INTENDED_P2P_INTERFACE_ADDRESS = 9; +const TLV_P2P_MANAGEABILITY = 10; +const TLV_CHANNEL_LIST = 11; +const TLV_NOTICE_OF_ABSENCE = 12; +const TLV_P2P_DEVICE_INFO = 13; +const TLV_P2P_GROUP_INFO = 14; +const TLV_P2P_GROUP_ID = 15; +const TLV_P2P_INTERFACE = 16; +const TLV_OPERATING_CHANNEL = 17; +const TLV_INVITATION_FLAGS = 18; +const TLV_P2P_VENDOR_SPECIFIC = 221; + +///////////////////////////////////////////////////////////////////////////// +// Fixed Fields + +FF AuthAlgo (2) // C.f. Sec. 7.3.1.1 +{ + algo, 2; +} + +FF AuthSeqNo (2) // 7.3.1.2 +{ + no, 2; +} + +FF BeaconInterval (2) // 7.3.1.3 +{ + interval, 2; +} + +FF Capabilities (2) // 7.3.1.4 +{ + { + ess: 1; + ibss: 1; + cfPollable: 1; + cfPollReq: 1; + privacy: 1; + shortPreamble: 1; + pbcc: 1; + channelAgility: 1; + spectrumMgt: 1; + qos: 1; + shortSlotTime: 1; + apsd: 1; + rrm: 1; + dsssOfdm: 1; + delayedBA: 1; + immediateBA: 1; + } +} + +FF CurrentAPAddress(6) // 7.3.1.5 +{ + mac[6]; +} + +FF ListenInterval (2) // 7.3.1.6 +{ + interval, 2; +} + +FF Reason (2) // 7.3.1.7 +{ + code, 2; +} + +FF AID (2) // 7.3.1.8 +{ + associd, 2; +} + +FF Status (2) // 7.3.1.9 +{ + status, 2; +} + +FF TimeStamp (8) // 7.3.1.10 +{ + timestamp, 8; +} + +FF Category (1) // 7.3.1.11 +{ + category, 1; +} + +FF Action (1) // 7.3.1.11 +{ + action, 1; +} + +FF TransactionId (2) // 7.3.1.11 +{ + transId[2]; +} + +FF DialogToken (1) // 7.3.1.12 +{ + token, 1; +} + +FF StatusCode (1) // WMM Spec 2.2.10 +{ + statusCode, 1; +} + +FF OperatingMode (1) +{ + { + //Operating Mode field + chanWidth: 2; + reserved: 2; + rxNSS: 3; + rxNSSType: 1; + } +} +FF AddBAParameterSet (2) // 7.3.1.14 +{ + { + amsduSupported: 1; + policy: 1; + tid: 4; + bufferSize: 10; + } +} + +FF BATimeout (2) // 7.3.1.15 +{ + timeout, 2; +} + +FF BAStartingSequenceControl (2) // 7.2.1.7 +{ + { + fragNumber: 4; + ssn: 12; + } +} + +FF DelBAParameterSet (2) // 7.3.1.16 +{ + { + reserved: 11; + initiator: 1; + tid: 4; + } +} + +FF SMPowerModeSet (1) //7.3.1.25 +{ + { + PowerSave_En: 1; + Mode: 1; + reserved: 6; + } +} + +FF TSInfo (3) // 7.3.2.30 +{ + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + schedule: 1; + unused: 15; + } +} + +FF NumOfRepetitions (2) +{ + repetitions, 2; +} + +FF TxPower (1) +{ + txPower, 1; +} + +FF MaxTxPower (1) +{ + maxTxPower, 1; +} +FF TPCEleID (1) +{ + TPCId, 1; +} +FF TPCEleLen (1) +{ + TPCLen, 1; +} +FF LinkMargin (1) +{ + linkMargin, 1; +} +FF RxAntennaId (1) +{ + antennaId, 1; +} +FF TxAntennaId (1) +{ + antennaId, 1; +} +FF RCPI (1) +{ + rcpi, 1; +} +FF RSNI (1) +{ + rsni, 1; +} + +FF P2POUI (4) +{ + oui, 4; +} + +FF P2POUISubType (1) +{ + ouiSubtype, 1; +} + +FF VhtMembershipStatusArray(8) // 8.4.1.51 +{ + membershipStatusArray[8]; +} + +FF VhtUserPositionArray(16) // 8.4.1.52 +{ + userPositionArray[16]; +} + +///////////////////////////////////////////////////////////////////////////// +// TLVs // +///////////////////////////////////////////////////////////////////////////// + +/** + * \brief Version + * + * WPS 1.0h + * Version specifies the Easy Setup version. The one-byte field is broken + * into a four-bit major part using the top MSBs and four-bit minor part + * using the LSBs. As an example, version 3.2 would be 0x32. + * + * WSC 2.0.0 + * Deprecated Version mechanism. This attribute is always set to value 0x10 + * (version 1.0) for backwards compatibility. Version 1.0h of the specification + * did not fully describe the version negotiation mechanism and version 2.0 + * introduced a new subelement (Version2) for indicating the version number + * to avoid potential interoperability issues with deployed 1.0h-based devices. + * + */ + +TLV Version( TLV_VERSION ) ( 2 : 2 ) MSB +{ + { + minor: 4; + major: 4; + } +} + +/// Wi-Fi Protected Setup State +TLV WPSState( TLV_WI_FI_SIMPLE_CONFIG_STATE ) ( 2 : 2 ) MSB +{ + state, 1; +} + +/** + * \brief AP Setup Locked + * + * + * This variable indicates that the AP has entered a state in which it will + * refuse to allow an external Registrar to attempt to run the Registration + * Protocol using the AP?s PIN (with the AP acting as Enrollee). The AP + * should enter this state if it believes a brute force attack is underway + * against the AP?s PIN. + * + * When the AP is in this state, it MUST continue to allow other Enrollees to + * connect and run the Registration Protocol with any external Registrars or + * the AP's built-in Registrar (if any). It is only the use of the AP' PIN + * for adding external Registrars that is disabled in this state. + * + * The AP Setup Locked state can be reset to FALSE through an authenticated + * call to SetAPSettings. APs may provide other implementation-specific + * methods of resetting the AP Setup Locked state as well. + * + * + */ + +TLV APSetupLocked( TLV_AP_SETUP_LOCKED ) ( 2 : 2 ) MSB +{ + fLocked, 1; +} + +/** + * \brief Selected Registrar Config Methods + * + * + * This attribute has the same values that Config Methods have. It is used in + * Probe Response messages to convey the Config Methods of the selected + * Registrar. + * + * + */ + +TLV SelectedRegistrarConfigMethods ( TLV_SELECTED_REGISTRAR_CONFIG_METHODS ) ( 2 : 2 ) MSB +{ + methods, 2; +} + +/** + * \brief UUID-E + * + * + * The universally unique identifier (UUID) element is a unique GUID + * generated by the Enrollee. It uniquely identifies an operational device + * and should survive reboots and resets. The UUID is provided in binary + * format. If the device also supports UPnP, then the UUID corresponds to the + * UPnP UUID. + * + * + */ + +TLV UUID_E ( TLV_UUID_E ) ( 2 : 2 ) MSB +{ + uuid[ 16 ]; +} + +/** + * \brief UUID-R + * + * + * The universally unique identifier (UUID) element is a unique GUID + * generated by the Registrar. It uniquely identifies an operational device + * and should survive reboots and resets. The UUID is provided in binary + * format. If the device also supports UPnP, then the UUID corresponds to the + * UPnP UUID. + * + * + */ + +TLV UUID_R ( TLV_UUID_R ) ( 2 : 2 ) MSB +{ + uuid[ 16 ]; +} + +/** + * \brief RF Bands + * + * + \code + + 0x01 2.4GHz + 0x02 5.0GHz + + \endcode + * + * + */ + +TLV RFBands ( TLV_RF_BANDS ) ( 2 : 2 ) MSB +{ + bands, 1; +} + + +/** + * \brief Selected Registrar + * + * + * This field indicates that a Registrar has been selected by a user and that + * an Enrollee should proceed with setting up an 802.1X uncontrolled data + * port with the Registrar. + * + * + */ + +TLV SelectedRegistrar ( TLV_SELECTED_REGISTRAR ) ( 2 : 2 ) MSB +{ + selected, 1; +} + +/** + * \brief Config Methods + * + * + * The Config Methods Data component lists the configuration methods the + * Enrollee or Registrar supports. The list is a bitwise OR of values from + * the table below. In addition to Config Methods, APs and STAs that support + * the UPnP Management Interface must support the Permitted Config Methods + * attribute, which is used to control the Config Methods that are enabled on + * that AP. + * + \code + + Value Hardware Interface + 0x0001 USBA (Flash Drive) + 0x0002 Ethernet + 0x0004 Label + 0x0008 Display + 0x0010 External NFC Token + 0x0020 Integrated NFC Token + 0x0040 NFC Interface + 0x0080 PushButton + 0x0100 Keypad + + \endcode + * + * + */ + +TLV ConfigMethods ( TLV_CONFIG_METHODS ) ( 2 : 2 ) MSB +{ + methods, 2; +} + +/** + * \brief Association State + * + * + * The Association State component shows the configuration and previous + * association state of the wireless station when sending a Discovery + * request. + * + \code + + Association State Description + 0 Not Associated + 1 Connection Success + 2 Configuration Failure + 3 Association Failure + 4 IP Failure + + \endcode + * + * + */ + +TLV AssociationState ( TLV_ASSOCIATION_STATE ) ( 2 : 2 ) MSB +{ + state, 2; +} + +/** + * \brief Configuration Error + * + * + * The Configuration Error component shows the result of the device + * attempting to configure itself and to associate with the WLAN. + * + \code + + Configuration Error Description + 0 No Error + 1 OOB Interface Read Error + 2 Decryption CRC Failure + 3 2.4 channel not supported + 4 5.0 channel not supported + 5 Signal too weak + 6 Network auth failure + 7 Network association failure + 8 No DHCP response + 9 Failed DHCP config + 10 IP address conflict + 11 Couldn't connect to Registrar + 12 Multiple PBC sessions detected + 13 Rogue activity suspected + 14 Device busy + 15 Setup locked + 16 Message Timeout + 17 Registration Session Timeout + 18 Device Password Auth Failure + + \endcode + * + * The Device busy error is returned if the sending device is unable to + * respond to the request due to some internal conflict or resource + * contention issue. For example, if a device is only capable of performing a + * single instance of the Registration Protocol at a time, it may return this + * error in response to attempts to start another instance in the middle of + * an active session. + * + * + */ + +TLV ConfigurationError ( TLV_CONFIGURATION_ERROR ) ( 2 : 2 ) MSB +{ + error, 2; +} + +TLV Manufacturer ( TLV_MANUFACTURER ) ( 2 : 2 ) MSB +{ + name[ 0..64 ]; +} + +TLV ModelName ( TLV_MODEL_NAME ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV ModelNumber ( TLV_MODEL_NUMBER ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV SerialNumber ( TLV_SERIAL_NUMBER ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV DeviceName ( TLV_DEVICE_NAME ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +/** + * \brief Device Password ID + * + * + * This attribute is used to identify a device password. There are six + * predefined values and ten reserved values. If the Device Password ID is + * Default, the Enrollee should use its PIN password (from the label or + * display). This password may correspond to the label, display, or a + * user-defined password that has been configured to replace the original + * device password. + * + * User-specified indicates that the user has overridden the password with a + * manually selected value. Machine-specified indicates that the original + * PIN password has been overridden by a strong, machinegenerated device + * password value. The Rekey value indicates that the device's 256-bit + * rekeying password will be used. The PushButton value indicates that the + * PIN is the all-zero value reserved for the PushButton Configuration + * method. + * + * The Registrar-specified value indicates a PIN that has been obtained from + * the Registrar (via a display or other out-of-band method). This value may + * be further augmented with the optional 'Identity' attribute in M1. This + * augmentation is useful when multiple predefined UserID/PIN pairs have been + * established by a Registrar such as an authenticator used for Hotspot + * access. If the Device Password ID in M1 is not one of the predefined or + * reserved values, it corresponds to a password given to the Registrar as an + * OOB Device Password. + * + \code + + Value Description + + 0x0000 Default (PIN) + 0x0001 User-specified + 0x0002 Machine-specified + 0x0003 Rekey + 0x0004 PushButton + 0x0005 Registrar-specified + 0x0006 - 0x000F Reserved + + \endcode + * + * + */ + +TLV DevicePasswordID ( TLV_DEVICE_PASSWORD_ID ) ( 2 : 2 ) MSB +{ + id, 2; +} + + +/** + * \brief Primary Device Type + * + * + * This attribute contains the primary type of the device. Its format + * follows: + * + \code + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Attribute ID | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Category ID | OUI (1-2) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OUI (3-4) | Sub Category ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + \endcode + * + * Vendor-specific sub-categories are designated by setting the OUI to the + * value associated with that vendor. Note that a four-byte subdivided OUI + * is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04 + * is used. The predefined values for Category ID and Sub Category ID are + * provided in the next table. There is no way to indicate a vendor-specific + * main device category. The OUI applies only to the interpretation of the + * Sub Category. If a vendor does not use sub categories for their OUI, the + * three-byte OUI occupies the first three bytes of the OUI field and the + * fourth byte is set to zero. + * + * + \code + + Category ID Value Sub Category ID Value + Computer 1 PC 1 + Server 2 + Media Center 3 + Input Device 2 + Printers, Scanners, Printer 1 + Faxes and Copiers 3 Scanner 2 + Camera 4 Digital Still Camera 1 + Storage 5 NAS 1 + Network AP 1 + Infrastructure 6 Router 2 + Switch 3 + Displays 7 Television 1 + Electronic Picture Frame 2 + Projector 3 + Multimedia Devices 8 DAR 1 + PVR 2 + MCX 3 + Gaming Devices 9 Xbox 1 + Xbox360 2 + Playstation 3 + Telephone 10 Windows Mobile 1 + + \endcode + * + * + */ + +TLV PrimaryDeviceType ( TLV_PRIMARY_DEVICE_TYPE ) ( 2 : 2 ) MSB +{ + primary_category, 2; + oui[ 4 ]; + sub_category, 2; +} + + +/** + * \brief Request Type + * + * + * The Request Type component specifies the mode in which the device will + * operate in for this setup exchange. If the device is an Enrollee, it may + * send only discovery messages or it may also request that the Registrar + * proceed with opening a data connection. This protocol allows Enrollees to + * more efficiently discover devices on the network. + + * If the device indicates that it intends to engage setup either as a + * Registrar or an Enrollee, the Access Point continues to indicate that it + * will operate as an AP in the response. The Request Type attribute is + * carried throughout the 802.1X data channel setup process in the Wi-Fi + * Protected Setup IE. There are two sub-types of Registrars: WLAN Manager + * Registrar indicates that this Registrar intends to manage the AP or STA + * settings using UPnP. It will derive a UPnP AP or STA Management key. The + * ordinary Registrar type indicates that this Registrar does not intend to + * subsequently manage the Enrollee's settings. APs must not derive AP + * Management Keys for an ordinary Registrar. If a Registrar does not intend + * to be a WLAN Manager Registrar, it should set the Request Type to + * Registrar. Doing so avoids needlessly consuming resources on the AP. + + \code + + Request Type Value Description + 0x00 Enrollee, Info only + 0x01 Enrollee, open 802.1X + 0x02 Registrar + 0x03 WLAN Manager Registrar + + \endcode + * + * + */ + +TLV RequestType ( TLV_REQUEST_TYPE ) ( 2 : 2 ) MSB +{ + reqType, 1; +} + +/** + * \brief Response Type + * + * + * The Response Type component specifies the operational mode of the + * device for this setup exchange. The Response Type IE is carried + * throughout the 802.1X data channel setup process. + + \code + + Response Type Value Description + 0x00 Enrollee, Info only + 0x01 Enrollee, open 802.1X + 0x02 Registrar + 0x03 AP + +\endcode + * + * + */ + +TLV ResponseType ( TLV_RESPONSE_TYPE ) ( 2 : 2 ) MSB +{ + resType, 1; +} + + +/////////////////////////////////////////////////////////////////////////// +// WiFi Direct/P2P TLVs // +/////////////////////////////////////////////////////////////////////////// + +/** + * \brief P2P Status Attribute + */ + +TLV P2PStatus ( TLV_P2P_STATUS ) ( 1 : 2 ) LSB +{ + status, 1; +} + + +/** + * \brief Minor Reason Code Attribute + */ + +TLV MinorReasonCode ( TLV_MINOR_REASON_CODE ) ( 1 : 2 ) LSB +{ + minorReasonCode, 1; +} + + +/** + * \brief P2P Capability Attribute + */ + +TLV P2PCapability ( TLV_P2P_CAPABILITY ) ( 1 : 2 ) LSB +{ + deviceCapability, 1; + groupCapability, 1; +} + + +/** + * \brief P2P Device Id Attribute + */ + +TLV P2PDeviceId ( TLV_P2P_DEVICE_ID ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; +} + + +/** + * \brief Group Owner Intent Attribute + */ + +TLV GOIntent ( TLV_P2P_GROUP_OWNER_INTENT ) ( 1 : 2 ) LSB +{ + GOIntent, 1; +} + + +/** + * \brief Configuration Timeout Attribute + */ + +TLV ConfigurationTimeout ( TLV_CONFIGURATION_TIMEOUT ) ( 1 : 2 ) LSB +{ + GOConfigTimeout, 1; + CLConfigTimeout, 1; +} + + +/** + * \brief Listen Channel Attribute + */ + +TLV ListenChannel ( TLV_LISTEN_CHANNEL ) ( 1 : 2 ) LSB +{ + countryString[3]; + regulatoryClass, 1; + channel, 1; +} + + +/** + * \brief P2P Group BSSID Attribute + */ + +TLV P2PGroupBssid ( TLV_P2P_GROUP_BSSID ) ( 1 : 2 ) LSB +{ + P2PGroupBssid[6]; +} + + +/** + * \brief Extended Listen Attribute + */ + +TLV ExtendedListenTiming ( TLV_EXTENDED_LISTEN_TIMING ) ( 1 : 2 ) LSB +{ + availibilityPeriod, 2; + availibilityInterval, 2; +} + + +/** + * \brief Intended P2P Interface Address Attribute + */ + +TLV IntendedP2PInterfaceAddress ( TLV_INTENDED_P2P_INTERFACE_ADDRESS ) ( 1 : 2 ) LSB +{ + P2PInterfaceAddress[6]; +} + + +/** + * \brief P2P Manageability Attribute + */ + +TLV P2PManageability ( TLV_P2P_MANAGEABILITY ) ( 1 : 2 ) LSB +{ + manageability, 1; +} + + +/** + * \brief ChannelList Attribute + */ + +TLV ChannelList ( TLV_CHANNEL_LIST ) ( 1 : 2 ) LSB +{ + countryString[3]; + channelList[0..251]; +} + + +/** + * \brief Notice of Absence + */ + +TLV NoticeOfAbsence ( TLV_NOTICE_OF_ABSENCE ) ( 1 : 2 ) LSB +{ + index, 1; + CTSWindowOppPS, 1; + NoADesc[0..36]; +} + +/** + * \brief P2P Device Info Attribute + */ + +TLV P2PDeviceInfo ( TLV_P2P_DEVICE_INFO ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; + configMethod, 2 , FLIPBYTEORDER; + primaryDeviceType[8]; + MANDATORYTLV DeviceName; +} + + +/** + * \brief P2P Group Info Attribute + */ + +TLV P2PGroupInfo ( TLV_P2P_GROUP_INFO ) ( 1 : 2 ) LSB +{ + P2PClientInfoDesc[0..1024]; +} + + +/** + * \brief P2P Group Id Attribute + */ + +TLV P2PGroupId ( TLV_P2P_GROUP_ID ) ( 1 : 2 ) LSB +{ + deviceAddress[6]; + ssid[0..32]; +} + + +/** + * \brief P2P Interface Attribute + */ + +TLV P2PInterface ( TLV_P2P_INTERFACE ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; +} + + +/** + * \brief Operating Channel Attribute + */ + +TLV OperatingChannel ( TLV_OPERATING_CHANNEL ) ( 1 : 2 ) LSB +{ + countryString[3]; + regulatoryClass, 1; + channel, 1; +} + + +/** + * \brief Invitation Flags Attribute + */ + +TLV InvitationFlags ( TLV_INVITATION_FLAGS ) ( 1 : 2 ) LSB +{ + invitationFlags, 1; +} + +/** + * \brief Vendor Extension + * + * This variable permits vendor extensions in the Wi-Fi Simple + * Configuration TLV framework. The Vendor Extension figure + * illustrates the implementation of vendor extensions. Vendor + * ID is the SMI network management private enterprise code + * + * +-----------+----------------------+ + * | Vendor ID | Vendor Data | + * +-----------+----------------------+ + * |<--- 3 --->|<----- 1 - 1021 ----->| + * + */ + +TLV VendorExtension ( TLV_VENDOR_EXTENSION ) ( 2 : 2 ) MSB +{ + /* + * vendorId is the SMI network management private enterprise code. + * WFA Vendor ID 0x00372A + * + */ + vendorId[ 3 ]; + + /** + * \breif Version2 + * + * The Version2 field specifies the version Wi-Fi Simple + * Configuration implemented by the device sending this attribute. + * The one-byte field is broken into a four-bit major part using + * the top MSBs and four-bit minor part using the LSBs. As an example, + * version 3.2 would be 0x32. This subelement was added in the + * specification version 2.0 and if the subelement is not included + * in a message, the transmitter of the message is assumed to + * use version 1.0. + * + */ + OPTIONALTLV TLV Version2 ( TLV_VERSION2 ) ( 1 : 1 ) MSB + { + { + minor: 4; + major: 4; + } + } + /** + * \brief AuthorizedMACs + * + * This subelement contains a list of Enrollee MAC addresses (each + * being six bytes in length) that have been registered to start WSC. + * The AP includes this field in Beacon and Probe Response frames so + * Enrollees can tell if they have been registered to start WSC. There + * may be multiple Enrollees active on the network, but not all of them have + * been registered to start WSC. This element allows an Enrollee to detect + * if they should start WSC with the AP. The AuthorizedMACs field augments + * the use of the Selected Registrar. + * + */ + OPTIONALTLV TLV AuthorizedMACs ( TLV_AUTHORIZED_MAC ) ( 1 : 1 ) MSB + { + mac[6]; + } + + /** + * \brief Request to Enroll + * + * This optional subelement in the WSC IE in Probe Request or M1 indicates + * the desire to enroll in the network by setting its value to TRUE. If the + * Registrar gets this subelement it can use this as a trigger that a device + * wants to enroll (maybe an indication can be shown to the user). The device + * must set it to FALSE after the registration protocol completion. + * + */ + OPTIONALTLV TLV RequestToEnroll( TLV_REQUEST_TO_ENROLL ) ( 1 : 1 ) MSB + { + req, 1; + } +} + +/** + * \brief Requested Device Type + * + * This attribute contains the requested device type of a Wi-Fi + * Direct device. + * + * This attribute allows a device to specify the Primary Device Type + * or the Secondary Device Type of other devices it is interested in. + * Only a device that receives a Probe Request containing a WSC IE with + * this attribute and with a Primary Device Type or Secondary Device Type + * that matches the Requested Device Type will respond with a Probe Response. + * + * Its format and contents is identical to the 'Primary Device Type'. + * + * Both the Category ID and Sub Category ID can be used as a filter. If only + * looking for devices with a certain Category ID, the OUI and Sub Category ID + * fields will have to be set to zero. + * + */ +TLV RequestDeviceType ( TLV_REQUESTED_DEVICE_TYPE ) ( 2 : 2 ) MSB +{ + primary_category, 2; + oui[ 4 ]; + sub_category, 2; +} + +///////////////////////////////////////////////////////////////////////////// +// Information Elements + +IE SSID (EID_SSID) // C.f. Sec. 7.3.2.1 +{ + ssid[0..32]; +} + +IE SuppRates (EID_SUPP_RATES) // 7.3.2.2 +{ + rates[0..SIR_MAC_MAX_NUMBER_OF_RATES]; +} + +IE FHParamSet (EID_FH_PARAM_SET) // 7.3.2.3 +{ + dwell_time, 2; + hop_set, 1; + hop_pattern, 1; + hop_index, 1; +} + +IE DSParams (EID_DS_PARAM_SET) // 7.3.2.4 +{ + curr_channel, 1; +} + +IE CFParams (EID_CF_PARAM_SET) // 7.3.2.5 +{ + cfp_count, 1; + cfp_period, 1; + cfp_maxduration, 2; + cfp_durremaining, 2; +} + +IE TIM (EID_TIM) // 7.3.2.6 +{ + dtim_count, 1; + dtim_period, 1; + bmpctl, 1; + vbmp[1..251]; +} + +IE IBSSParams (EID_IBSS_PARAM_SET) // 7.3.2.7 +{ + atim, 2; +} + +IE ChallengeText (EID_CHALLENGE_TEXT) // 7.3.2.8 +{ + text[1..253]; +} + +IE RequestedInfo (EID_REQUEST) // 7.3.2.12 +{ + requested_eids[0..255]; +} + +IE Country (EID_COUNTRY) // 7.3.2.9 +{ + country[3]; + OPTIONAL triplets[3][0..84]; +} + +IE FHParams (EID_FH_PATTERN) // 7.3.2.10 +{ + radix, 1; + nchannels, 1; +} + +IE FHPattTable (EID_FH_PATT_TABLE) // 7.3.2.11 +{ + flag, 1; + nsets, 1; + modulus, 1; + offset, 1; + randtable[0..251]; +} + +IE ERPInfo (EID_ERP_INFO) // 7.3.2.13 +{ + { + non_erp_present : 1; + use_prot: 1; + barker_preamble: 1; + unused: 5; + } +} + +IE ExtSuppRates (EID_EXT_SUPP_RATES) // 7.3.2.14 +{ + rates[1..SIR_MAC_MAX_NUMBER_OF_RATES]; +} + +IE PowerConstraints (EID_POWER_CONSTRAINTS) // 7.3.2.15 +{ + localPowerConstraints, 1; +} + +IE PowerCaps (EID_POWER_CAPABILITY) // 7.3.2.16 +{ + minTxPower, 1; + maxTxPower, 1; +} + +IE TPCRequest (EID_TPC_REQUEST) // 7.3.2.17 +{ } + +IE TPCReport (EID_TPC_REPORT) // 7.3.2.18 +{ + tx_power, 1; + link_margin, 1; +} + +IE SuppChannels (EID_SUPPORTED_CHANNELS) // 7.2.3.19 +{ + bands[2][1..48]; +} + +IE SuppOperatingClasses (EID_SUPPORTED_OPER_CLASSES) +{ + classes[1..32]; +} + +IE ChanSwitchAnn (EID_CHANNEL_SWITCH_ANN) // 7.3.2.20 +{ + switchMode, 1; + newChannel, 1; + switchCount, 1; +} + +IE ExtChanSwitchAnn (EID_EXT_CHANNEL_SWITCH_ANN) // 7.3.2.20a +{ + secondaryChannelOffset, 1; +} + +IE Quiet (EID_QUIET) // 7.3.2.23 +{ + count, 1; + period, 1; + duration, 2; + offset, 2; +} + +IE RSN (EID_RSN) // 7.3.2.25 +{ + // The version is 2 octets, and we only support version 1. + version, 2 MUSTBE 1; + // The next four octets will be the Group Cipher Suite + gp_cipher_suite[4]; + // The IE *may* stop here; if there's any more, we should see two more + // octets giving the number of Pairwise Cipher Suites + OPTIONAL pwise_cipher_suite_count, 2; + // I don't see anything in the Standard limiting the number of Pairwise + // Cypher Suites, other than the maximum length of an IE, which limits us + // to 61. However, that seems needlessly wasteful of space. + pwise_cipher_suites[4][0..4] COUNTIS pwise_cipher_suite_count; + // Optional count of AKM suite selectors + OPTIONAL akm_suite_count, 2; + // Again, I see nothing in the Standard explicitly limiting the number of + // AKM suite selectors other than the maximum size of an IE. + akm_suites[4][0..4] COUNTIS akm_suite_count; + OPTIONAL RSN_Cap[2]; + // Finally, the IE may contain zero or more PMKIDs: + OPTIONAL pmkid_count, 2; + pmkid[16][0..4] COUNTIS pmkid_count; + OPTIONAL gp_mgmt_cipher_suite[4]; +} + +IE RSNOpaque (EID_RSN) // 7.3.2.25 +{ + data[ 6..253 ]; +} + +IE WAPI (EID_WAPI) // 7.3.2.25 +{ + // The version is 2 octets, and we only support version 1. + version, 2 MUSTBE 1; + // count of AKM suite selectors + akm_suite_count, 2; + // Again, I see nothing in the Standard explicitly limiting the number of + // AKM suite selectors other than the maximum size of an IE. + akm_suites[4][0..4] COUNTIS akm_suite_count; + // we should see two more + // octets giving the number of Unicast Cipher Suites + unicast_cipher_suite_count, 2; + // I don't see anything in the Standard limiting the number of Pairwise + // Cypher Suites, other than the maximum length of an IE, which limits us + // to 61. However, that seems needlessly wasteful of space. + unicast_cipher_suites[4][0..4] COUNTIS unicast_cipher_suite_count; + // The next four octets will be the Multicast Cipher Suite + multicast_cipher_suite[4]; + // WAPI capabilities + { + preauth: 1; + reserved: 15; + } + // Finally, the IE may contain zero or more BKIDs: + OPTIONAL bkid_count, 2; + bkid[16][0..4] COUNTIS bkid_count; +} + +IE WAPIOpaque (EID_WAPI) // 7.3.2.25 +{ + data[ 6..253 ]; +} + +IE QBSSLoad (EID_QBSS_LOAD) // 7.3.2.28 +{ + stacount, 2; + chautil, 1; + avail, 2; +} + +IE EDCAParamSet (EID_EDCA_PARAM_SET) // 7.3.2.29 +{ + qos, 1; // ToDo: This is a bitfield whose format + // depends on whether this is from an AP + // or a STA, information which I'm not + // sure we have at parse time... + reserved, 1; + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_acwmin: 4; + acbe_acwmax: 4; + } + acbe_txoplimit, 2; + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_acwmin: 4; + acbk_acwmax: 4; + } + acbk_txoplimit, 2; + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_acwmin: 4; + acvi_acwmax: 4; + } + acvi_txoplimit, 2; + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_acwmin: 4; + acvo_acwmax: 4; + } + acvo_txoplimit, 2; +} + +IE TSPEC (EID_TSPEC) // 7.3.2.30 +{ + + // TS Info + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + } + { + schedule: 1; + unused: 7; + } + + // Nominal MSDU Size + { + size: 15; + fixed: 1; + } + + max_msdu_size, 2; + min_service_int, 4; + max_service_int, 4; + inactivity_int, 4; + suspension_int, 4; + service_start_time, 4; + min_data_rate, 4; + mean_data_rate, 4; + peak_data_rate, 4; + burst_size, 4; + delay_bound, 4; + min_phy_rate, 4; + surplus_bw_allowance, 2; + medium_time, 2; + +} // End IE TSPEC. + +IE TCLAS (EID_TCLAS) // 7.3.2.31 +{ + user_priority, 1; + classifier_type, 1; + classifier_mask, 1; + UNION info (DISCRIMINATOR classifier_type) + { + EthParams (classifier_type IS 0) + { + source[6]; + dest[6]; + type, 2; + } + IpParams (classifier_type IS 1) + { + version, 1; + UNION params (DISCRIMINATOR version) + { + IpV4Params (version IS 4) + { + source[4]; + dest[4]; + src_port, 2; + dest_port, 2; + DSCP, 1; + proto, 1; + reserved, 1; + } + IpV6Params (version IS 6) + { + source[16]; + dest[16]; + src_port, 2; + dest_port, 2; + flow_label[3]; + } + }; + } + Params8021dq (classifier_type IS 2) + { + tag_type, 2; + } + }; +} // End IE TCLASS + +const EID_RRM_BEACON_REPORTING = 1; +const EID_RRM_BCN_REPORTING_DETAIL = 2; + +IE BeaconReporting (EID_RRM_BEACON_REPORTING) +{ + reportingCondition, 1; + threshold, 1; +} + +IE BcnReportingDetail (EID_RRM_BCN_REPORTING_DETAIL) +{ + reportingDetail, 1; +} + +IE APChannelReport (EID_AP_CHAN_REPORT) +{ + regulatoryClass, 1; + channelList[0..50]; +} + +IE MeasurementRequest (EID_MEAS_REQUEST) // 7.3.2.21 +{ + measurement_token, 1; + + // Measurement Request Mode + { + parallel: 1; + enable: 1; + request: 1; + report: 1; + durationMandatory: 1; + unused: 3; + } + + measurement_type, 1; + UNION measurement_request (DISCRIMINATOR measurement_type) + { + Basic (measurement_type IS 0) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + CCA (measurement_type IS 1) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + RPIHistogram (measurement_type IS 2) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + Beacon (measurement_type IS 5) + { + regClass, 1; + channel, 1; + randomization, 2; + meas_duration, 2; + meas_mode, 1; + BSSID[6]; + OPTIE SSID; + OPTIE BeaconReporting; + OPTIE BcnReportingDetail; + OPTIE RequestedInfo; + OPTIE APChannelReport[0..2]; + //OPTIONAL vendor_specific[1..239]; + } + + }; +} + +const EID_BCN_REPORT_FRAME_BODY = 1; +IE BeaconReportFrmBody (EID_BCN_REPORT_FRAME_BODY) +{ + reportedFields[0..224]; +} + +IE MeasurementReport (EID_MEAS_REPORT) // 7.3.2.22 +{ + token, 1; + // Measurement Report Mode + { + late: 1; + incapable: 1; + refused: 1; + unused: 5; + } + type, 1; + OPTIONAL UNION report (DISCRIMINATOR type) + { + Basic (type IS 0) // 7.3.2.22.1 + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + // Map + { + bss: 1; + ofdm_preamble: 1; + unid_signal: 1; + rader: 1; + unmeasured: 1; + unused: 3; + } + } + CCA (type IS 1) + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + cca_busy_fraction, 1; + } + RPIHistogram (type IS 2) + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + rpi0_density, 1; + rpi1_density, 1; + rpi2_density, 1; + rpi3_density, 1; + rpi4_density, 1; + rpi5_density, 1; + rpi6_density, 1; + rpi7_density, 1; + } + Beacon (type IS 5) + { + regClass, 1; + channel, 1; + meas_start_time, 8; + meas_duration, 2; + // reported_frame_info, + { + condensed_PHY: 7; + reported_frame_type: 1; + } + RCPI, 1; + RSNI, 1; + BSSID[6]; + antenna_id, 1; + parent_TSF, 4; + OPTIE BeaconReportFrmBody; + //IE vendor_specific + } + }; +} + +IE TSDelay (EID_TS_DELAY) // 7.3.2.32 +{ + delay, 4; +} + +IE TCLASSPROC (EID_TCLASS_PROC) // 7.3.2.33 +{ + processing, 1; +} + +IE Schedule (EID_SCHEDULE) // 7.3.2.34 +{ + { + aggregation: 1; + tsid: 4; + direction: 2; + reserved: 9; + } + service_start_time, 4; + service_interval, 4; + max_service_dur, 2; + spec_interval, 2; +} + +IE QOSCapsAp (EID_QOS_CAPABILITY) // 7.3.2.35 +{ + { + count: 4; + qack: 1; + qreq: 1; + txopreq: 1; + reserved: 1; + } +} + +IE QOSCapsStation (EID_QOS_CAPABILITY) // 7.3.2.35 +{ + { + acvo_uapsd: 1; + acvi_uapsd: 1; + acbk_uapsd: 1; + acbe_uapsd: 1; + qack: 1; + max_sp_length: 2; + more_data_ack: 1; + } +} + +IE LinkIdentifier (EID_LINK_IDENTIFIER) // 7.3.2.62 +{ + bssid[6]; + InitStaAddr[6]; + RespStaAddr[6]; +} + +IE WPA (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01) +{ + // This IE's first two octets should be interpreted as a version number; + // we only support version 1. + version, 2 MUSTBE 1; + // A four-octet Multicast Cipher may or may not appear next (hence the + // OPTIONAL keyword) + OPTIONAL multicast_cipher[4]; + // Optional Unicast Cipher count + OPTIONAL unicast_cipher_count, 2; + // Next comes an array of four-octet Cipher Suite selectors; the COUNTIS + // clause indicates that the actual number of selectors seen is in the + // member 'unicast_cipher_count'. + unicast_ciphers[4][0..4] COUNTIS unicast_cipher_count; + // (Optional) Authentication suites: + OPTIONAL auth_suite_count, 2; + auth_suites[4][0..4] COUNTIS auth_suite_count; + // This field is declared optional as per bugs 15234, 14755, & 14991. + OPTIONAL caps, 2; +} + +IE WPAOpaque (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01) +{ + data[ 2..249 ]; +} + +IE WMMInfoStation (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00) +{ + // This IE contains the QoS Info field when sent from WMM Station + version, 1; + { + acvo_uapsd: 1; + acvi_uapsd: 1; + acbk_uapsd: 1; + acbe_uapsd: 1; + reserved1: 1; + max_sp_length: 2; + reserved2: 1; + } +} + +IE WMMInfoAp (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00) +{ + // This IE contains the QoS Info field when sent from WMM AP + version, 1; + { + param_set_count: 4; + reserved: 3; + uapsd: 1; + } +} + + +IE WMMParams (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x01) +{ + version, 1 MUSTBE 1; + qosInfo, 1; // ToDo: This is actually a + // bitfield, but it's format + // varies depending on whether + // the sender is a STA or AP... + reserved2, 1; + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_acwmin: 4; + acbe_acwmax: 4; + } + acbe_txoplimit, 2; + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_acwmin: 4; + acbk_acwmax: 4; + } + acbk_txoplimit, 2; + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_acwmin: 4; + acvi_acwmax: 4; + } + acvi_txoplimit, 2; + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_acwmin: 4; + acvo_acwmax: 4; + } + acvo_txoplimit, 2; +} + +IE WMMTSPEC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xf2, 0x02, 0x02) +{ + version, 1 MUSTBE 1; + + // TS Info + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + } + { + tsinfo_rsvd: 7; + burst_size_defn: 1; + } + + // Nominal MSDU Size + { + size: 15; + fixed: 1; + } + + max_msdu_size, 2; + min_service_int, 4; + max_service_int, 4; + inactivity_int, 4; + suspension_int, 4; + service_start_time, 4; + min_data_rate, 4; + mean_data_rate, 4; + peak_data_rate, 4; + burst_size, 4; + delay_bound, 4; + min_phy_rate, 4; + surplus_bw_allowance, 2; + medium_time, 2; + +} // End IE WMMTSpec. + +IE WMMCaps (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x05) +{ + version, 1 MUSTBE 1; + { + reserved: 4; + qack: 1; + queue_request: 1; + txop_request: 1; + more_ack: 1; + } +} + +IE WMMTCLAS (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x06) +{ + version, 1 MUSTBE 1; + + user_priority, 1; + classifier_type, 1; + classifier_mask, 1; + UNION info (DISCRIMINATOR classifier_type) + { + EthParams (classifier_type IS 0) + { + source[6]; + dest[6]; + type, 2; + } + IpParams (classifier_type IS 1) + { + version, 1; + UNION params (DISCRIMINATOR version) + { + IpV4Params (version IS 4) + { + source[4]; + dest[4]; + src_port, 2; + dest_port, 2; + DSCP, 1; + proto, 1; + reserved, 1; + } + IpV6Params (version IS 6) + { + source[16]; + dest[16]; + src_port, 2; + dest_port, 2; + flow_label[3]; + } + }; + } + Params8021dq (classifier_type IS 2) + { + tag_type, 2; + } + }; + +} + +IE WMMTCLASPROC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x07) +{ + version, 1 MUSTBE 1; + processing, 1; +} + +IE WMMTSDelay (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x08) +{ + version, 1 MUSTBE 1; + delay, 4; +} + +IE WMMSchedule (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x09) +{ + version, 1 MUSTBE 1; + + { + aggregation: 1; + tsid: 4; + direction: 2; + reserved: 9; + } + + service_start_time, 4; + service_interval, 4; + max_service_dur, 2; + spec_interval, 2; +} + +IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01) +{ + + mgmt_state, 1; + + { + mbssid_mask: 3; + reserved: 5; + } + +} + +IE Vendor1IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x10, 0x18) +{ +} + +IE Vendor2IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x90, 0x4C) +{ +} + +IE Vendor3IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x16, 0x32) +{ +} + +IE ESETrafStrmMet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x07) +{ + tsid, 1; + state, 1; + msmt_interval, 2; +} + +IE ESETrafStrmRateSet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x08) +{ + tsid, 1; + tsrates[0..8]; +} + +IE ESEVersion (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x03) +{ + version, 1; +} + +IE ESETxmitPower (EID_ESE_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00) +{ + power_limit, 1; + reserved, 1; +} + +IE ESECckmOpaque (EID_ESE_CCKM_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00) +{ + data[ 6..20 ]; +} + +IE RRMEnabledCap (EID_RRM_ENABLED_CAPS) +{ + //Capability bitmap + { + LinkMeasurement: 1; + NeighborRpt: 1; + parallel: 1; + repeated: 1; + BeaconPassive: 1; + BeaconActive: 1; + BeaconTable: 1; + BeaconRepCond: 1; + } + { + FrameMeasurement: 1; + ChannelLoad: 1; + NoiseHistogram: 1; + statistics: 1; + LCIMeasurement: 1; + LCIAzimuth: 1; + TCMCapability: 1; + triggeredTCM: 1; + } + { + APChanReport: 1; + RRMMIBEnabled: 1; + operatingChanMax: 3; + nonOperatinChanMax: 3; + } + { + MeasurementPilot: 3; + MeasurementPilotEnabled: 1; + NeighborTSFOffset: 1; + RCPIMeasurement: 1; + RSNIMeasurement: 1; + BssAvgAccessDelay: 1; + } + { + BSSAvailAdmission: 1; + AntennaInformation: 1; + reserved: 6; + } +} + +IE MeasurementPilot (EID_RRM_MEAS_PILOT_TX_INFO) +{ + measurementPilot, 1; + vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now. +} + +IE MultiBssid (EID_MULTIPLE_BSSID) +{ + maxBSSIDIndicator, 1; + vendorSpecific[0..255]; +} + +IE OBSSScanParameters (EID_OBSS_SCAN_PARAMETERS) +{ + obssScanPassiveDwell, 2; + obssScanActiveDwell, 2; + bssChannelWidthTriggerScanInterval, 2; + obssScanPassiveTotalPerChannel, 2; + obssScanActiveTotalPerChannel, 2; + bssWidthChannelTransitionDelayFactor, 2; + obssScanActivityThreshold, 2; +} + +IE HT2040BSSCoexistence (EID_20_40_BSS_COEXISTENCE) +{ + // 20/40 BSS Coexistence Information + { + infoRequest: 1; + fortyMHzIntolerant: 1; + twentyMHzBssWidthReq: 1; + obssScanExemptionReq: 1; + obssScanExemptionGrant: 1; + unused: 3; + } +} + +IE HT2040BSSIntolerantReport (EID_20_40_BSS_INTOLERANT_REPORT) +{ + operatingClass, 1; + channelList[0..50]; +} + +const EID_RRM_NBR_RPT_TSF = 1; +const EID_RRM_NBR_CD_COUNTRY = 2; +const EID_RRM_NBR_MSMT_PILOT_TX_INFO = 66; + +IE NeighborReport (EID_NEIGHBOR_REPORT) +{ + bssid[6]; + //Bssid Info + { + APReachability: 2; + Security: 1; + KeyScope: 1; + //Capabilities + SpecMgmtCap: 1; + QosCap: 1; + apsd: 1; + rrm: 1; + } + //Capabilities contd. + { + DelayedBA: 1; + ImmBA: 1; + //Capabilities end. + MobilityDomain: 1; + reserved: 5; + } + + reserved1, 2; //part of BSSID Info. + + regulatoryClass, 1; + channel, 1; + PhyType, 1; + OPTIE IE TSFInfo (EID_RRM_NBR_RPT_TSF) + { + TsfOffset, 2; + BeaconIntvl, 2; + } + OPTIE IE CondensedCountryStr (EID_RRM_NBR_CD_COUNTRY) + { + countryStr[2]; + } + OPTIE IE MeasurementPilot; // (EID_RRM_NBR_MSMT_PILOT_TX_INFO) +// { +// measurementPilot, 1; +// vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now. +// } + OPTIE IE RRMEnabledCap; + OPTIE IE MultiBssid; + //Ignoring vendor specific. +} + +IE RCPIIE (EID_RCPI) +{ + rcpi, 1; +} + +IE RSNIIE (EID_RSNI) +{ + rsni, 1; +} + +IE WFATPC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x08, 0x00) +{ + txPower, 1; + linkMargin, 1; +} + +IE MobilityDomain (EID_FT_MOBILITY_DOMAIN) +{ + MDID, 2; + //FT Capability and policy + { + overDSCap: 1; + resourceReqCap: 1; + reserved: 6; + } +} +const SUB_EID_FT_R1KH_ID = 1; +const SUB_EID_FT_GTK = 2; +const SUB_EID_FT_R0KH_ID = 3; +const SUB_EID_FT_IGTK = 4; +IE FTInfo (EID_FT_INFO) +{ + // MicControl, 2; + { + reserved: 8; + IECount: 8; + } + MIC[16]; + Anonce[32]; + Snonce[32]; + + OPTIE IE R1KH_ID (SUB_EID_FT_R1KH_ID) + { + PMK_R1_ID[6]; + } + + OPTIE IE GTK (SUB_EID_FT_GTK) + { + //Key Info + { + keyId: 2; + reserved: 14; + } + keyLength, 1; + RSC[8]; + key[5..32]; + } + + OPTIE IE R0KH_ID (SUB_EID_FT_R0KH_ID) + { + PMK_R0_ID[1..48]; + } + + OPTIE IE IGTK (SUB_EID_FT_IGTK) + { + //Key Info + keyID[2]; + IPN[6]; + keyLength, 1; + key[24]; + } +} + +IE TimeoutInterval (EID_TIMEOUT_INTERVAL) +{ + timeoutType, 1; + timeoutValue, 4; +} + +//TODO: need to define this properly. +IE RICData (EID_FT_RIC_DATA) +{ + Identifier, 1; + resourceDescCount, 1; + statusCode, 2; +} + +IE RICDescriptor (EID_FT_RIC_DESCRIPTOR) +{ + resourceType, 1; + variableData[0..255]; //Block ack param set...TODO: +} + +IE WscIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x00, 0x50, 0xF2, 0x04 ) +{ + data[ 2..249 ]; +} + +IE P2PIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x09 ) +{ + data[ 2..249 ]; +} + +IE WFDIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x0A ) +{ + data[ 2..249 ]; +} + +IE PTIControl (EID_PTI_CONTROL) // 7.3.2.65 +{ + tid, 1; + sequence_control, 2; +} + +IE PUBufferStatus (EID_PU_BUFFER_STATUS) // 7.3.2.66 +{ + { + ac_bk_traffic_aval: 1; + ac_be_traffic_aval: 1; + ac_vi_traffic_aval: 1; + ac_vo_traffic_aval: 1; + reserved: 4; + } +} + + +///////////////////////////////////////////////////////////////////////////// +// Airgo Information Elements + + +IE Airgo (EID_VENDOR_SPECIFIC) OUI (0x00, 0x0A, 0xF5) +{ + // N.B. The fact that these IEs are defined inside the Airgo IE indicates + // that they can *only* occur inside the Airgo IE. + + OPTIE IE PropSuppRates (SIR_MAC_PROP_EXT_RATES_TYPE) + { + rates[1..12]; + } + + OPTIE IE APName (SIR_MAC_PROP_AP_NAME_TYPE) + { + name[1..32]; + } + + OPTIE IE HCF (SIR_MAC_PROP_HCF_TYPE) + { + enabled, 1; + } + + OPTIE IE WDS (SIR_MAC_PROP_WDS_TYPE) + { + wdsData[0..ANI_WDS_INFO_MAX_LENGTH]; + } + + OPTIE IE BPIndicator (SIR_MAC_PROP_BP_IND_TYPE) + { + indicator, 1; + type, 1; + } + + + // In Progress: I think SIR_MAC_PROP_NEIGHBOR_BSS_TYPE is going to need a + // custom parser... + + + OPTIE IE LoadInfo (SIR_MAC_PROP_LOAD_INFO_TYPE) MSB + { + num_stas, 2; + channel_util, 2; + } + + OPTIE IE LoadBalance (SIR_MAC_PROP_LOAD_BALANCE_TYPE) + { + bssid[6]; + channel, 1; + } + + OPTIE IE PropAssocType (SIR_MAC_PROP_ASSOC_TYPE) + { + type, 1; + } + + OPTIE IE LLAttr (SIR_MAC_PROP_LL_ATTR_TYPE) MSB + { + defer_threshold, 4; + } + + OPTIE IE PropCapability (SIR_MAC_PROP_CAPABILITY) + { + capability, 2; + } + + OPTIE IE Version (SIR_MAC_PROP_VERSION) + { + chip_rev, 4; + card_type, 1; + build_version[0..20]; + } + + OPTIE IE PropEDCAParams (SIR_MAC_PROP_EDCAPARAMS) + { + qos, 1; // ToDo: This is a bitfield whose format + // depends on whether this is from an AP + // or a STA, information which I'm not + // sure we have at parse time... + reserved, 1; + + // Best Effort + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_min: 4; + acbe_max: 4; + } + acbe_txoplimit, 2; + + // Background + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_min: 4; + acbk_max: 4; + } + acbk_txoplimit, 2; + + // Video + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_min: 4; + acvi_max: 4; + } + acvi_txoplimit, 2; + + // Voice + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_min: 4; + acvo_max: 4; + } + acvo_txoplimit, 2; + + } // End IE PropEDCAParams. + + /** + * \ie Titan + * + * \brief Proprietary Next Generation (TITAN) IE structure + * + * + * Based on the setting of the "Titan" proprietary bit in the + * tSirPropIEStruct.capability field (bit #6), this IE will be sent + * appropriately to all the ANIpeers in the following management frames - + * + * - Beacons + * - Assoc Req/Rsp + * - Reassoc Req/Rsp + * - Probe Req/Rsp + * + */ + + OPTIE IE Titan (SIR_MAC_PROP_TITAN) + { + concat_tcid_bitmap, 1; + compression_tcid_bitmap, 1; + + // Identifies the OPERATIONAL state of Channel Bonding + // This info is encoded as a bitmap as follows: + // + // b7 b6 b5 b4 b3 b2 b1 b0 + // -------------------------------------- + // |CCA_CB |CCA |ICE | AU|CS|U/D| O | A | + // -------------------------------------- + // where, + // A - Admin state of CB - [enabled(1)/disabled(0)] + // O - Oper state of CB - [on(1)/off(0)] + // U/D - Indicates where the secondary CB channel is + // parked - Up(1)/Down(0) from the primary + // CS - Channel Switch announcement in progress with + // respect to the secondary CB channel + // CS_on(1)/CS_off(0) + // This applies to an AP only + // AU - Autonomous updates. This indicates to an STA + // that it can send an unsolicited CB Report + // regarding its neighbor BSS during an Assoc/ + // ReAssoc REQ. + // AU_on(1)/AU_off(0) + // This applies to an AP only + // ICE - Intelligent Channel Expansion mode enable/disable + // ICE_on(1)/ICE_off(0) + // CCA - CCA mode to be used + // CCA_20MHz(0)/CCA_40MHz(1) + // CCA_CB - channel bonding enable/disable based on cca monitoring + // enable(1)/disable(0) + + cb_state, 1; + + // Identifies Reverse FCS pattern and state + // This info is encoded as a bitmap as follows: + // + // b7 b6 b5 b4 b3 b2 b1 b0 + // --------------------------------- + // | X | X | X | X | P | P | P | O | + // --------------------------------- + // where, + // O - Oper state of Reverse FCS - [on(1)/off(0)] + // P - Identifies the pattern ID to be used + // NOTE - These bits are used only during Assoc Req/Rsp + // management frames. Thus, the pattern ID needs to be + // looked up only during Assoc Req/Rsp. In other words, + // the pattern ID between an AP/STA is negotiated via + // the revFcsState during Assoc Req/Rsp + + rev_fcs_state, 1; + } + + OPTIE IE PropChannSwitchAnn (SIR_MAC_PROP_CHANNEL_SWITCH) + { + mode, 1; + primary_channel, 1; + sub_band, 1; + channel_switch_count, 1; + } + + /** + * \ie PropQuietBSS + * + * \brief Proprietary Quite BSS IE structure + * + * + * Based on the setting of the "Titan" proprietary bit in the + * tSirPropIEStruct.capability field (bit #6), this IE will be sent + * appropriately to all the ANI peers in the following management + * frames + * + * - Beacons + * - Probe Rsp + * + */ + + OPTIE IE PropQuietBSS (SIR_MAC_PROP_QUIET_BSS) + { + // Indicates the number of TBTT's until the next beacon + // interval during which the next quiet interval will + // start + // 1 - Quiet Interval will start during the beacon + // interval starting at the next TBTT + // 0 - Reserved + quiet_count, 1; + + // Shall be set to the number of beacon intervals between + // the start of regularly scheduled quiet intervals + // defined by this Quiet Element + // 0 - No periodic quiet interval is defined + quiet_period, 1; + + // Duration of the quiet interval, expressed in TUs + // 1 TU = 1024 microseconds?? + quiet_duration, 2; + + // Set to the offset of the start of the quiet interval + // from the TBTT specified by the quietCount field, + // expressed in TUs. The value of this offset field will + // be less than one beacon interval + // 1 TU = 1024 microseconds?? + quiet_offset, 2; + + } + + OPTIE IE TriggerStaBgScan (SIR_MAC_PROP_TRIG_STA_BK_SCAN) + { + enable, 1; + } + + OPTIE IE Taurus (SIR_MAC_PROP_TAURUS) + { + // TID bitmap indicating the TIDs for which BA is setup. + // bit0 for TID0, bit1 for TID1 and so on. + baTIDBitmap, 2; + + // Block Ack Policy: 0-Delayed BA 1-Immediate BA. + // One bit for each TID + baPolicy, 2; + + // Buffer size for each AC, in exponential notation. + // 3 bits reserved for each AC. + // bit0-2 for AC0[TID 0 and 3], bit3-5 for AC1[TID 1 and 2] + // and so on. + + // TID 8 & 11 will use AC0, TID 9 & 10 will use AC1, so use of AC is + // overloaded. This is done to reduce the size of IE in the beacons. + { + baBufferSize: 12; + rsvd: 4; + } + } + +} // End IE Airgo. + +IE VHTCaps (EID_VHT_CAPABILITIES) +{ + //VHT Capability Info + { + maxMPDULen: 2; + supportedChannelWidthSet: 2; + ldpcCodingCap: 1; + shortGI80MHz: 1; + shortGI160and80plus80MHz: 1; + txSTBC: 1; + rxSTBC: 3; + suBeamFormerCap: 1; + suBeamformeeCap: 1; + csnofBeamformerAntSup: 3; + numSoundingDim: 3; + muBeamformerCap: 1; + muBeamformeeCap: 1; + vhtTXOPPS: 1; + htcVHTCap: 1; + maxAMPDULenExp: 3; + vhtLinkAdaptCap: 2; + rxAntPattern: 1; + txAntPattern: 1; + reserved1: 2; + } + rxMCSMap, 2; + { + rxHighSupDataRate: 13; + reserved2: 3; + } + txMCSMap, 2; + { + txSupDataRate: 13; + reserved3: 3; + } +} + +IE VHTOperation (EID_VHT_OPERATION_ELEMENT) +{ + chanWidth, 1; + chanCenterFreqSeg1, 1; + chanCenterFreqSeg2, 1; + basicMCSSet, 2; +} + +IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD) +{ + muMIMOCapStaCount, 1; + ssUnderUtil, 1; + FortyMHzUtil, 1; + EightyMHzUtil, 1; + OneSixtyMHzUtil, 1; +} + +IE AID (EID_AID) +{ + assocId, 2; +} + +IE WiderBWChanSwitchAnn (EID_WIDER_BW_CHANNEL_SWITCH_ANN) +{ + newChanWidth, 1; + newCenterChanFreq0, 1; + newCenterChanFreq1, 1; +} + +IE ChannelSwitchWrapper (EID_CHANNEL_SWITCH_WRAPPER) +{ + OPTIE IE WiderBWChanSwitchAnn; +} +IE ExtCap (EID_EXT_CAP) +{ + bytes[8..9]; +} + +IE HTCaps (EID_HT_CAPABILITIES) +{ + // HT Capability Info + { + advCodingCap: 1; + supportedChannelWidthSet: 1; + mimoPowerSave: 2; + greenField: 1; + shortGI20MHz: 1; + shortGI40MHz: 1; + txSTBC: 1; + rxSTBC: 2; + delayedBA: 1; + maximalAMSDUsize: 1; + dsssCckMode40MHz: 1; + psmp: 1; + stbcControlFrame: 1; + lsigTXOPProtection: 1; + } + // HT Parameters Info; + { + maxRxAMPDUFactor: 2; + mpduDensity: 3; + reserved1: 3; + } + + supportedMCSSet[ HT_MAX_SUPPORTED_MCS_SET ]; + + // Extended HT Capability Info + { + pco: 1; + transitionTime: 2; + reserved2: 5; + mcsFeedback: 2; + reserved3: 6; + } + // TXBF Capability Info + { + txBF: 1; + rxStaggeredSounding: 1; + txStaggeredSounding: 1; + rxZLF: 1; + txZLF: 1; + implicitTxBF: 1; + calibration: 2; + explicitCSITxBF: 1; + explicitUncompressedSteeringMatrix: 1; + explicitBFCSIFeedback: 3; + explicitUncompressedSteeringMatrixFeedback: 3; + explicitCompressedSteeringMatrixFeedback: 3; + csiNumBFAntennae: 2; + uncompressedSteeringMatrixBFAntennae: 2; + compressedSteeringMatrixBFAntennae: 2; + reserved4: 7; + } + // AS Capability Info + { + antennaSelection: 1; + explicitCSIFeedbackTx: 1; + antennaIndicesFeedbackTx: 1; + explicitCSIFeedback: 1; + antennaIndicesFeedback: 1; + rxAS: 1; + txSoundingPPDUs: 1; + reserved5: 1; + } + //TODO: take it out when generic fix to remove extra bytes in IE is available. + //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE. + rsvd[0..32]; + +} // End IE HTCaps. + +IE HTInfo (EID_HT_INFO) +{ + primaryChannel, 1; + + // ahtInfoField1 + { + secondaryChannelOffset: 2; + recommendedTxWidthSet: 1; + rifsMode: 1; + controlledAccessOnly: 1; + serviceIntervalGranularity: 3; + } + + // ahtInfoField2 + + + // ahtInfoField2 + { + opMode: 2; + nonGFDevicesPresent: 1; + transmitBurstLimit: 1; + obssNonHTStaPresent:1; + reserved: 11; + } + + + // ahtInfoField3 + { + basicSTBCMCS: 7; + dualCTSProtection: 1; + secondaryBeacon: 1; + lsigTXOPProtectionFullSupport: 1; + pcoActive: 1; + pcoPhase: 1; + reserved2: 4; + } + + basicMCSSet[ HT_MAX_SUPPORTED_MCS_SET ]; + + //TODO: take it out when generic fix to remove extra bytes in IE is available. + //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE. + rsvd[0..32]; + +} // End IE HTInfo. + + +IE OperatingMode (EID_OPERATING_MODE) +{ + { //Operating Mode field + chanWidth: 2; + reserved: 2; + rxNSS: 3; + rxNSSType: 1; + } +} + +IE QosMapSet (EID_QOS_MAP_SET) +{ + dscp_exceptions[0..60]; +} + +CONTAINERIE RICDataDesc +{ + MANDIE RICData; + OPTIE RICDescriptor; + OPTIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + OPTIE TSDelay; + OPTIE Schedule; + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE WMMTSDelay; + OPTIE WMMSchedule; +} + +///////////////////////////////////////////////////////////////////////////// +// MULTIIEs // +///////////////////////////////////////////////////////////////////////////// + +MULTIIE WSC ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // Must be 0x10 + OPTIONALTLV WPSState; + OPTIONALTLV APSetupLocked; + OPTIONALTLV SelectedRegistrarConfigMethods; + OPTIONALTLV UUID_E; + OPTIONALTLV UUID_R; + OPTIONALTLV RFBands; + OPTIONALTLV SelectedRegistrar; + OPTIONALTLV ConfigMethods; + OPTIONALTLV AssociationState; + OPTIONALTLV ConfigurationError; + OPTIONALTLV Manufacturer; + OPTIONALTLV ModelName; + OPTIONALTLV ModelNumber; + OPTIONALTLV SerialNumber; + OPTIONALTLV DeviceName; + OPTIONALTLV DevicePasswordID; + OPTIONALTLV PrimaryDeviceType; + OPTIONALTLV RequestType; + OPTIONALTLV ResponseType; + OPTIONALTLV VendorExtension; + OPTIONALTLV RequestDeviceType; +} + +MULTIIE WscBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + OPTIONALTLV UUID_E; // The AP's UUID is provided + // only when the AP is a + // dual-band AP in push + // button mode and + // indicating push button + // mode on both radios + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // End Multi-IE WscBeacon. + +MULTIIE WscAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV RequestType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscAssocReq. + + +MULTIIE WscAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV ResponseType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscAssocRes. + +MULTIIE WscReassocRes ( 221 ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV ResponseType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscReassocRes + +MULTIIE WscProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV RequestType; // + // + MANDATORYTLV ConfigMethods; // Configuration methods the + // Enrollee or Registrar + // supports + MANDATORYTLV UUID_E; // unique GUID generated by + // the Enrollee. + MANDATORYTLV PrimaryDeviceType; + MANDATORYTLV RFBands; // Specific RF bands used + // for this message + MANDATORYTLV AssociationState; // Configuration and previous + // association state + MANDATORYTLV ConfigurationError; + MANDATORYTLV DevicePasswordID; + + // WSC 2.0 + OPTIONALTLV Manufacturer; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV ModelName; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV ModelNumber; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV DeviceName; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV VendorExtension; // Version2 and RequestToEntroll + + OPTIONALTLV RequestDeviceType; // When a device receives a Probe + // Request containing this type, + // It will only reponse if Primary + // or Secondary Device Type matches. + +} // End Multi-IE WscProbeReq. + +MULTIIE WscProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + MANDATORYTLV ResponseType; + MANDATORYTLV UUID_E; // unique identifier of AP + MANDATORYTLV Manufacturer; + MANDATORYTLV ModelName; + MANDATORYTLV ModelNumber; + MANDATORYTLV SerialNumber; + MANDATORYTLV PrimaryDeviceType; + MANDATORYTLV DeviceName; // User-friendly description + // of device + MANDATORYTLV ConfigMethods; // Config Methods corresponds + // to the methods the AP + // supports as an Enrollee + // for adding external + // Registrars. + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // WscProbeRes. + +// This MULTIIE combines the fields from the WSC IEs as they appear in +// Beacons *and* in Probe Responses, with the difference that they're all +// optional. In our device drivers, we combine Probe Responses and Beacons +// into one list, and parse their IEs later (c.f. frame BeaconIEs). Because +// the WSC IE differs in those two frames, we'd often see warning messages +// about either unexpected fields showing up (if we thought we were parsing a +// Beacon, and we in fact had data from a Probe Response) or mandatory fields +// missing (if we thought we were parsing a Probe Response, and in fact had +// data from a Beacon). + +// I created this MULTIIE to stuff into the BeaconIEs frames to avoid this. +// It's intended to be used on unpack only, and to do so in a very forgiving +// way. + +MULTIIE WscBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + OPTIONALTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + OPTIONALTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + OPTIONALTLV ResponseType; + OPTIONALTLV UUID_E; // unique identifier of AP + OPTIONALTLV Manufacturer; + OPTIONALTLV ModelName; + OPTIONALTLV ModelNumber; + OPTIONALTLV SerialNumber; + OPTIONALTLV PrimaryDeviceType; + OPTIONALTLV DeviceName; // User-friendly description + // of device + OPTIONALTLV ConfigMethods; // Config Methods corresponds + // to the methods the AP + // supports as an Enrollee + // for adding external + // Registrars. + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // WscProbeRes. +///////////////////////////////////////////////////////////////////////////// +// MULTIIEs // +///////////////////////////////////////////////////////////////////////////// + +MULTIIE P2PBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; // Contains P2P Device + // and P2P Group Capability + MANDATORYTLV P2PDeviceId; // Contains P2P Device + // Address + OPTIONALTLV NoticeOfAbsence; // Indicates Notice of + // Absence schedule and + // CT Window + +} // End P2PBeacon + + +MULTIIE P2PAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; // Contains P2P Device + // and P2P Group Capability + OPTIONALTLV ExtendedListenTiming; + MANDATORYTLV P2PDeviceInfo; + +} // End P2PAssocReq + + +MULTIIE P2PAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + OPTIONALTLV ExtendedListenTiming; + +} // End P2PAssocRes + + +MULTIIE P2PProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + OPTIONALTLV P2PDeviceId; + MANDATORYTLV ListenChannel; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV OperatingChannel; +} // End P2PProbeReq + + +MULTIIE P2PProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV NoticeOfAbsence; + MANDATORYTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupInfo; + +} // End P2PProbeRes + + +MULTIIE P2PBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + OPTIONALTLV P2PCapability; + OPTIONALTLV P2PDeviceId; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV NoticeOfAbsence; + OPTIONALTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupInfo; + +} // End P2PBeaconProbeRes + + +MULTIIE P2PGONegReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + MANDATORYTLV GOIntent; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV ListenChannel; + OPTIONALTLV ExtendedListenTiming; + MANDATORYTLV IntendedP2PInterfaceAddress; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PDeviceInfo; + MANDATORYTLV OperatingChannel; + +} // End P2PGONegReq + + +MULTIIE P2PGONegRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV P2PCapability; + MANDATORYTLV GOIntent; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV OperatingChannel; + MANDATORYTLV IntendedP2PInterfaceAddress; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupId; + +} // End P2PGONegRes + + +MULTIIE P2PGONegCnf ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV P2PCapability; + MANDATORYTLV OperatingChannel; + MANDATORYTLV ChannelList; + OPTIONALTLV P2PGroupId; + +} // End P2PGONegCnf + + +MULTIIE P2PGONegWPS ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; + MANDATORYTLV DevicePasswordID; + +} // End P2PGONegWPS + + +MULTIIE P2PDeAuth ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV MinorReasonCode; +} + + +MULTIIE P2PDisAssoc ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV MinorReasonCode; +} + + +MULTIIE P2PInvitationReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV InvitationFlags; + MANDATORYTLV OperatingChannel; + MANDATORYTLV P2PGroupBssid; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PGroupId; + MANDATORYTLV P2PDeviceInfo; +} + + +MULTIIE P2PInvitationRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV OperatingChannel; + MANDATORYTLV P2PGroupBssid; + MANDATORYTLV ChannelList; +} + + +MULTIIE P2PDeviceDiscoverabilityReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PDeviceId; + MANDATORYTLV P2PGroupId; +} + + +MULTIIE P2PDeviceDiscoverabilityRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; +} + + +MULTIIE P2PProvisionDiscoveryReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + MANDATORYTLV P2PDeviceInfo; + MANDATORYTLV P2PGroupId; +} + +MULTIIE P2PWSCProvisionDiscoveryRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV ConfigMethods; +} + + +MULTIIE P2PNoticeOfAbsence ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV NoticeOfAbsence; +} + + +MULTIIE P2PPresenceResponse ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV NoticeOfAbsence; +} + + +///////////////////////////////////////////////////////////////////////////// +// Frames + +FRAME Beacon // C.f. Sec. 7.2.3.1 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE TIM; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSN; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE QOSCapsAp; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscBeacon; + OPTIE P2PBeacon; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE Vendor1IE; + OPTIE Vendor2IE; + OPTIE Vendor3IE; + OPTIE ChannelSwitchWrapper; + OPTIE ESEVersion; +} // End frame Beacon. + +// Ok, here's the story on Beacon1 & Beacon2. We presumably beacon a lot +// more than we change configuration. So it makes sense to keep the beacon +// we plan to send next in serialized format. We do this in struct schMisc. +// Whenever our config changes in a way that would affect our beacons, we +// just update our internal datastructures & re-generate the serialized +// beacon. + +// The problem is that there are *some* fields that need to be updated at +// send time, specifically the CF Param Set & the TIM. So, what we do is +// this: whenever our config changes, call schSetFixedBeaconFields. There, +// we serialize the following Beacon fields into gSchBeaconFrameBegin (after +// the power template & MAC header): TimeStamp, BeaconInterval, Capabilities, +// SSID, SuppRates, DSParams, & IBSSParams. It sets gSchBeaconOffsetBegin to +// the length of this buffer (incl. power template & MAC header). + +// Next, it serializes the following fields into gSchBeaconFrameEnd: Country, +// EDCAParamSet, PowerConstraints, TPCReport, ChannelSwitchAnn, Quiet, +// ERPInfo, HTCaps, HTInfo, ExtSuppRates, Airgo (via +// sirFillPropIEsInBeaconPR), WPA, RSN, WMMInfo, WMMParams, WMMCaps. The +// length of *this* buffer is kept in gSchBeaconOffsetEnd. + +// Then, in 'schBeaconInterruptHandler', we write CFParams & TIM at the end +// of gSchBeaconFrameBegin, keeping track of the (new) size of this buffer in +// the local 'beaconSize'. + +// After that, we call 'specialBeaconProcessing'. Note that this may +// actually call schSetFixedBeaconFields repeatedly! The comments say they +// try to avoid this, but... + +// Finally, we call writeBeaconToTFP, where the first thing we do is copy the +// gSchBeaconFrameEnd buffer after the end of gSchBeaconFrameBegin. + +FRAME Beacon1 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE DSParams; + OPTIE IBSSParams; +} + +FRAME Beacon2 +{ + OPTIE Country; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSNOpaque; + OPTIE EDCAParamSet; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE Airgo; + OPTIE WscBeacon; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE P2PBeacon; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE Vendor1IE; + OPTIE Vendor2IE; + OPTIE Vendor3IE; + OPTIE ChannelSwitchWrapper; + OPTIE ESEVersion; +} + +// This frame is just Beacon with its Fixed Fields stripped out. It's handy +// for use with struct 'tSirBssDescription', which has members corresponding +// to some fixed fields, but keeps its IEs in un-parsed format. + +// Note that it also includes the IE 'WscBeaconProbeRes'. + +FRAME BeaconIEs +{ + + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE TIM; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSN; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE QOSCapsAp; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESEVersion; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscBeaconProbeRes; + OPTIE P2PBeaconProbeRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE Vendor1IE; + OPTIE Vendor2IE; + OPTIE Vendor3IE; + OPTIE ChannelSwitchWrapper; + +} // End frame BeaconIEs. + +FRAME Disassociation // 7.3.3.3 +{ + FF Reason; + OPTIE P2PDisAssoc; +} + +FRAME AssocRequest // 7.2.3.4 +{ + FF Capabilities; + FF ListenInterval; + MANDIE SSID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE PowerCaps; + OPTIE SuppChannels; + OPTIE RSNOpaque; + OPTIE QOSCapsStation; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPAOpaque; + OPTIE HTCaps; + OPTIE WMMCaps; + OPTIE WMMInfoStation; + OPTIE Airgo; + OPTIE WscIEOpaque; + OPTIE WAPIOpaque; + OPTIE ESERadMgmtCap; + OPTIE ESEVersion; + OPTIE P2PIEOpaque; + OPTIE WFDIEOpaque; + OPTIE VHTCaps; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE QosMapSet; +} // End frame AssocRequest. + +FRAME AssocResponse // 7.2.3.5 +{ + FF Capabilities; + FF Status; + FF AID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE EDCAParamSet; + OPTIE RCPIIE; + OPTIE RSNIIE; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPA; + OPTIE TimeoutInterval; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE WMMTSPEC[0..4]; + OPTIE Airgo; + OPTIE WscAssocRes; + OPTIE P2PAssocRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE QosMapSet; +} // End frame AssocResponse. + +FRAME ReAssocRequest // 7.2.3.6 +{ + FF Capabilities; + FF ListenInterval; + FF CurrentAPAddress; + MANDIE SSID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE PowerCaps; + OPTIE SuppChannels; + OPTIE RSNOpaque; + OPTIE QOSCapsStation; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPAOpaque; + OPTIE HTCaps; + OPTIE WMMCaps; + OPTIE WMMInfoStation; + OPTIE Airgo; + OPTIE WscIEOpaque; + OPTIE WAPIOpaque; + OPTIE ESERadMgmtCap; + OPTIE ESEVersion; + OPTIE ESECckmOpaque; + OPTIE WMMTSPEC[0..4]; + OPTIE ESETrafStrmRateSet; + OPTIE P2PIEOpaque; + OPTIE WFDIEOpaque; + OPTIE VHTCaps; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE QosMapSet; +} // End frame ReAssocRequest. + +FRAME ReAssocResponse // 7.2.3.7 +{ + FF Capabilities; + FF Status; + FF AID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE EDCAParamSet; + OPTIE RCPIIE; + OPTIE RSNIIE; + OPTIE RRMEnabledCap; + OPTIE RSNOpaque; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPA; + OPTIE TimeoutInterval; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE WMMParams; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE WMMTSPEC[0..4]; + OPTIE ESETrafStrmRateSet; + OPTIE Airgo; + OPTIE WscReassocRes; + OPTIE P2PAssocRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE QosMapSet; +} // End frame ReAssocResponse. + +FRAME ProbeRequest // 7.2.3.8 +{ + MANDIE SSID; + MANDIE SuppRates; + OPTIE RequestedInfo; + OPTIE ExtSuppRates; + OPTIE DSParams; + OPTIE HTCaps; + OPTIE WscProbeReq; + OPTIE WFATPC; + OPTIE P2PProbeReq; + OPTIE VHTCaps; +} // End frame ProbeRequest. + +FRAME ProbeResponse // 7.2.3.9 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSNOpaque; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE RRMEnabledCap; + OPTIE APChannelReport; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscProbeRes; + OPTIE P2PProbeRes; + + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE Vendor1IE; + OPTIE Vendor2IE; + OPTIE Vendor3IE; + OPTIE ChannelSwitchWrapper; + OPTIE ESEVersion; +} // End frame ProbeResponse. + +FRAME Authentication // 7.2.3.10 +{ + FF AuthAlgo; + FF AuthSeqNo; + FF Status; + OPTIE ChallengeText; + OPTIE RSNOpaque; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICDataDesc[2]; +} // End frame Auth. + +FRAME DeAuth // 7.2.3.11 +{ + FF Reason; + OPTIE P2PDeAuth; +} + +FRAME AddTSRequest // 7.4.2.1 +{ + + FF Category; + FF Action; + FF DialogToken; + MANDIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + + // These IEs aren't in the spec, but our extant code *will* parse them if + // they're present. I included them to preserve that capability + + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE ESETrafStrmRateSet; + +} // End frame AddTSRequest. + +FRAME WMMAddTSRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + MANDIE WMMTSPEC; + OPTIE ESETrafStrmRateSet; +} // End Frame WMMAddTSRequest + +FRAME AddTSResponse // 7.4.2.2 +{ + + FF Category; + FF Action; + FF DialogToken; + FF Status; + MANDIE TSDelay; + MANDIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + OPTIE Schedule; + + // These IEs aren't in the spec, but our extant code *will* parse them if + // they're present. I included them to preserve that capability + OPTIE WMMTSDelay; + OPTIE WMMSchedule; + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE ESETrafStrmMet; + +} // End frame AddTSResponse. + +FRAME WMMAddTSResponse +{ + + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + OPTIE WMMTSPEC; + OPTIE ESETrafStrmMet; + +} // End frame WMMAddTSResponse. + +FRAME DelTS // 7.4.2.3 +{ + FF Category; + FF Action; + FF TSInfo; + FF Reason; +} + +FRAME WMMDelTS +{ + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + MANDIE WMMTSPEC; +} + +FRAME TPCRequest +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE TPCRequest; +} + +FRAME TPCReport +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE TPCReport; +} + +FRAME ChannelSwitch +{ + FF Category; + FF Action; + MANDIE ChanSwitchAnn; + OPTIE ExtChanSwitchAnn; + OPTIE WiderBWChanSwitchAnn; +} + +FRAME MeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE MeasurementRequest[1..4]; +} + +FRAME MeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE MeasurementReport; +} + +FRAME AddBAReq +{ + FF Category; + FF Action; + FF DialogToken; + FF AddBAParameterSet; + FF BATimeout; + FF BAStartingSequenceControl; +} + +FRAME AddBARsp +{ + FF Category; + FF Action; + FF DialogToken; + FF Status; + FF AddBAParameterSet; + FF BATimeout; +} + +FRAME DelBAInd +{ + FF Category; + FF Action; + FF DelBAParameterSet; + FF Reason; +} + +FRAME SMPowerSave +{ + FF Category; + FF Action; + FF SMPowerModeSet; +} + +FRAME RadioMeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF NumOfRepetitions; + //Measurement Request IE. + MANDIE MeasurementRequest[1..2]; +} + +FRAME RadioMeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + //Measurement Report elements. + MANDIE MeasurementReport[1..4]; +} + +FRAME LinkMeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF TxPower; + FF MaxTxPower; + //Optional Sub Ies +} + +FRAME LinkMeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + FF TPCEleID; + FF TPCEleLen; + FF TxPower; + FF LinkMargin; + FF RxAntennaId; + FF TxAntennaId; + FF RCPI; + FF RSNI; + //Optional Vendor specific IEs ... ignoring +} + +FRAME NeighborReportRequest +{ + FF Category; + FF Action; + FF DialogToken; + OPTIE SSID; + //Optional vendor specific IE...ignoring. +} + +FRAME NeighborReportResponse +{ + FF Category; + FF Action; + FF DialogToken; + OPTIE NeighborReport[1..MAX_SUPPORTED_NEIGHBOR_RPT]; +} + +FRAME GONegReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegWPS; + MANDIE P2PGONegReq; +} + +FRAME GONegRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegWPS; + MANDIE P2PGONegRes; +} + + +FRAME GONegCnf +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegCnf; +} + + +FRAME InvitationReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PInvitationReq; +} + + +FRAME InvitationRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PInvitationRes; +} + + +FRAME DeviceDiscoverabilityReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PDeviceDiscoverabilityReq; +} + + +FRAME DeviceDiscoverabilityRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PDeviceDiscoverabilityRes; +} + + + +FRAME ProvisionDiscoveryReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PProvisionDiscoveryReq; +} + + +FRAME ProvisionDiscoveryRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PWSCProvisionDiscoveryRes; +} + + +FRAME NoticeOfAbs +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PNoticeOfAbsence; +} + + +FRAME PresenceReq +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PNoticeOfAbsence; +} + + +FRAME PresenceRes +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PPresenceResponse; +} + + +FRAME GODiscoverabilityReq +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; +} + +FRAME OperatingMode +{ + FF Category; + FF Action; + //Operating Mode field + FF OperatingMode; +} + +FRAME TDLSDisReq +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; +} + +FRAME TDLSDisRsp +{ + FF Category; + FF Action; + FF DialogToken; + FF Capabilities; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE SuppOperatingClasses; + OPTIE RSN; + OPTIE ExtCap; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + MANDIE LinkIdentifier; + OPTIE VHTCaps; +} + +FRAME TDLSSetupReq +{ + FF Category; + FF Action; + FF DialogToken; + FF Capabilities; + MANDIE SuppRates; + OPTIE Country; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE RSN; + OPTIE ExtCap; + OPTIE SuppOperatingClasses; + OPTIE QOSCapsStation; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + MANDIE LinkIdentifier; + OPTIE WMMInfoStation; + OPTIE AID; + OPTIE VHTCaps; +} + +FRAME TDLSSetupRsp +{ + FF Category; + FF Action; + FF Status; + FF DialogToken; + FF Capabilities ; + OPTIE SuppRates; + OPTIE Country; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE RSN; + OPTIE ExtCap; + OPTIE SuppOperatingClasses; + OPTIE QOSCapsStation; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + OPTIE LinkIdentifier; + OPTIE WMMInfoStation; + OPTIE AID; + OPTIE VHTCaps; + OPTIE OperatingMode; +} + +FRAME TDLSSetupCnf +{ + FF Category; + FF Action; + FF Status; + FF DialogToken; + OPTIE RSN; + OPTIE EDCAParamSet; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE HTInfo; + OPTIE LinkIdentifier; + OPTIE WMMParams; + OPTIE VHTOperation; + OPTIE OperatingMode; +} +FRAME TDLSTeardown +{ + FF Category; + FF Action; + FF Reason; + OPTIE FTInfo; + MANDIE LinkIdentifier; +} + +FRAME TDLSPeerTrafficInd +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; + OPTIE PTIControl; + MANDIE PUBufferStatus; +} + +FRAME TDLSPeerTrafficRsp +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; +} + +FRAME SaQueryReq +{ + FF Category; + FF Action; + FF TransactionId; +} + +FRAME SaQueryRsp +{ + FF Category; + FF Action; + FF TransactionId; +} + +FRAME QosMapConfigure +{ + FF Category; + FF Action; + MANDIE QosMapSet; +} + +FRAME VHTGidManagementActionFrame +{ + FF Category; + FF Action; + FF VhtMembershipStatusArray; + FF VhtUserPositionArray; +} + +FRAME HT2040BSSCoexistenceManagementActionFrame +{ + FF Category; + FF Action; + MANDIE HT2040BSSCoexistence; + MANDIE HT2040BSSIntolerantReport; +} + +// Local Variables: +// mode: c++ +// fill-column: 77 +// comment-column: 42 +// indent-tabs-mode: nil +// show-trailing-whitespace: t +// End: + +// parser.frms ends here. diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/polFile.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/polFile.h new file mode 100644 index 0000000000000..4851968459169 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/cfg/polFile.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//================================================================== +// +// File: polFile.h +// +// Description: Structures that define the firmware file format. +// +// Author: Larry Cawley +// +//// +// Change History: +// 04/09/2002 - LAC - Initial version. +// +//=================================================================== +#if !defined( __polFile_h__ ) +#define __polFile_h__ + + + + +// File format +// +// byte 0 1 2 3 +// +// +---------+---------+--------+-------+ <----+ +// | Major | Minor | | | | +// | Version | Version | Suffix | Build | FileVersion | +// +---------+---------+--------+-------+ | +// | Major | Minor | | | | +// | Version | Version | Suffix | Build | HwCapabilities | tPolFileHeader +// +---------+---------+--------+-------+ | +// | | | +// | FileLength | FileLength | +// +------------------------------------+ | +// | | | +// | Number of Directory Entries | NumDirectoryEntries | +// +------------------------------------+ <----+ +// | | | +// | Directory Entry 1 Type | DirEntryType | +// +------------------------------------+ | +// | | | tPolFileDirEntry 1 +// | Directory Entry 1 File Offset | DirEntryFileOffset | +// +------------------------------------+ | +// | | | +// | Directory Entry 1 Length | DirEntryLength | +// +------------------------------------+ <----+ +// | . . . | . . . +// +------------------------------------+ <----+ +// | | | +// | Directory Entry n Type | | +// +------------------------------------+ | +// | | | tpolFileDirEntry n +// | Directory Entry n File Offset | | +// +------------------------------------+ | +// | | | +// | Directory Entry n Length | | +// +------------------------------------+ <----+ +// | | +// | | +// | File data described by | +// | directory entry 1 | +// | | +// | | +// +------------------------------------+ +// | . . . | +// +------------------------------------+ +// | | +// | | +// | File data described by | +// | directory entry n | +// | | +// | | +// +---------+---------+----------------+ +// | | +// | File Checksum | +// +---------+---------+ +// +// +// +// + + +#pragma pack( push ) +#pragma pack( 1 ) + +typedef struct sPolFileVersion { + + unsigned char MajorVersion; + unsigned char MinorVersion; + unsigned char Suffix; + unsigned char Build; + +} tPolFileVersion; + + +typedef struct sPolFileHeader { + + tPolFileVersion FileVersion; + tPolFileVersion HWCapabilities; + unsigned int FileLength; + unsigned int NumDirectoryEntries; + +} tPolFileHeader; + + +typedef enum ePolFileDirTypes { + + ePOL_DIR_TYPE_BOOTLOADER = 0, + ePOL_DIR_TYPE_STA_FIRMWARE, + ePOL_DIR_TYPE_AP_FIRMWARE, + ePOL_DIR_TYPE_DIAG_FIRMWARE, + ePOL_DIR_TYPE_STA_CONFIG, + ePOL_DIR_TYPE_AP_CONFIG + +} tPolFileDirTypes; + + +typedef struct sPolFileDirEntry { + + unsigned int DirEntryType; + unsigned int DirEntryFileOffset; + unsigned int DirEntryLength; + +} tPolFileDirEntry; + + +#pragma pack( pop ) + + +__inline unsigned short polFileChkSum( unsigned short *FileData, unsigned long NumWords ) +{ + unsigned long Sum; + + for ( Sum = 0; NumWords > 0; NumWords-- ) { + + Sum += *FileData++; + } + + Sum = (Sum >> 16) + (Sum & 0xffff); // add carry + Sum += (Sum >> 16); // maybe last unsigned short + + return( (unsigned short)( ~Sum ) ); +} + + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.c new file mode 100644 index 0000000000000..c94290236a208 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.c @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file dphHashTable.cc implements the member functions of + * DPH hash table class. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "cfgApi.h" +#include "schApi.h" +#include "dphGlobal.h" +#include "limDebug.h" + + +#include "halMsgApi.h" + +// --------------------------------------------------------------------- +/** + * dphHashTableClass() + * + * FUNCTION: + * Constructor function + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void dphHashTableClassInit(tpAniSirGlobal pMac, dphHashTableClass* pDphHashTable) +{ + tANI_U16 i; + + for (i=0; isize; i++) + { + pDphHashTable->pHashTable[i] = 0; + } + + for (i=0; isize; i++) + { + pDphHashTable->pDphNodeArray[i].valid = 0; + pDphHashTable->pDphNodeArray[i].added = 0; + pDphHashTable->pDphNodeArray[i].assocId = i; + } + +} + +// --------------------------------------------------------------------- +/** + * hashFunction + * + * FUNCTION: + * Hashing function + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @return None + */ + +tANI_U16 hashFunction(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 numSta) +{ + int i; + tANI_U16 sum = 0; + + for (i=0; i<6; i++) + sum += staAddr[i]; + + return (sum % numSta); +} + +// --------------------------------------------------------------------- +/** + * dphLookupHashEntry + * + * FUNCTION: + * Look up an entry in hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param pStaId pointer to the Station ID assigned to the station + * @return pointer to STA hash entry if lookup was a success \n + * NULL if lookup was a failure + */ + +tpDphHashNode dphLookupHashEntry(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 *pAssocId, + dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr = NULL; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) + { + if (dphCompareMacAddr(staAddr, ptr->staAddr)) + { + *pAssocId = ptr->assocId; + break; + } + } + return ptr; +} + +// --------------------------------------------------------------------- +/** + * dphGetHashEntry + * + * FUNCTION: + * Get a pointer to the hash node + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staId Station ID + * @return pointer to STA hash entry if lookup was a success \n + * NULL if lookup was a failure + */ + +tpDphHashNode dphGetHashEntry(tpAniSirGlobal pMac, tANI_U16 peerIdx, dphHashTableClass* pDphHashTable) +{ + if (peerIdx < pDphHashTable->size) + { + if (pDphHashTable->pDphNodeArray[peerIdx].added) + return &pDphHashTable->pDphNodeArray[peerIdx]; + else + return NULL; + } + else + return NULL; + +} + +static inline tpDphHashNode getNode(tpAniSirGlobal pMac, tANI_U8 assocId, dphHashTableClass* pDphHashTable) +{ + return &pDphHashTable->pDphNodeArray[assocId]; +} + + + + +// --------------------------------------------------------------------- +/** + * dphLookupAssocId + * + * FUNCTION: + * This function looks up assocID given the station Id. It traverses the complete table to do this. + * Need to find an efficient way to do this. + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to global Mac structure. + * @param staIdx station ID + * @param *assocId pointer to associd to be returned by this function. + * @return pointer to the dph node. + */ +tpDphHashNode dphLookupAssocId(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U16* assocId, dphHashTableClass* pDphHashTable) +{ + tANI_U8 i; + + for(i=0; isize; i++) + { + if( (pDphHashTable->pDphNodeArray[i].added) && + (pDphHashTable->pDphNodeArray[i].staIndex == staIdx)) + { + *assocId = i; + break; + } + + } + if(i==pDphHashTable->size) + return NULL; + return &pDphHashTable->pDphNodeArray[i]; + +} + + + + +/** ------------------------------------------------------------- +\fn dphInitStaState +\brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId +\ if validStaIdx flag is set. Otherwise it sets the staId to invalid. +\param tpAniSirGlobal pMac +\param tSirMacAddr staAddr +\param tANI_U16 assocId +\param tANI_U8 validStaIdx - true ==> the staId in the DPH entry with given assocId is valid and restore it back. +\ false ==> set the staId to invalid. +\return tpDphHashNode - DPH hash node if found. + -------------------------------------------------------------*/ + +tpDphHashNode dphInitStaState(tpAniSirGlobal pMac, tSirMacAddr staAddr, + tANI_U16 assocId, tANI_U8 validStaIdx, dphHashTableClass* pDphHashTable) +{ + tANI_U32 val; + + tpDphHashNode pStaDs; + tANI_U16 staIdx = HAL_STA_INVALID_IDX; + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid Assoc Id %d"), assocId);) + return NULL; + } + + pStaDs = getNode(pMac, (tANI_U8) assocId, pDphHashTable); + staIdx = pStaDs->staIndex; + + PELOG1(limLog(pMac, LOG1, FL("Assoc Id %d, Addr %08X"), assocId, pStaDs);) + + // Clear the STA node except for the next pointer (last 4 bytes) + vos_mem_set( (tANI_U8 *) pStaDs, sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0); + + // Initialize the assocId + pStaDs->assocId = assocId; + if(true == validStaIdx) + pStaDs->staIndex = staIdx; + else + pStaDs->staIndex = HAL_STA_INVALID_IDX; + + // Initialize STA mac address + vos_mem_copy( pStaDs->staAddr, staAddr, sizeof(tSirMacAddr)); + + // Initialize fragmentation threshold + if (wlan_cfgGetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve fragmentation threshold")); + else + pStaDs->fragSize = (tANI_U16) val; + + pStaDs->added = 1; + pStaDs->encPolicy = HAL_ENC_POLICY_NULL; + +#ifdef WMM_APSD + pStaDs->stopQueue = 0; + pStaDs->spStatus = 0; + pStaDs->apsdMaxSpLen = 0; + pStaDs->acMode[0] = pStaDs->acMode[1] = pStaDs->acMode[2] = pStaDs->acMode[3] = 0; +#endif /* WMM_APSD */ + pStaDs->valid = 1; + return pStaDs; +} + +// --------------------------------------------------------------------- +/** + * dphAddHashEntry + * + * FUNCTION: + * Add entry to hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param staId Station ID assigned to the station + * @return Pointer to STA hash entry + */ + +tpDphHashNode dphAddHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 assocId, dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr, node; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + PELOG1(limLog(pMac, LOG1, FL("assocId %d index %d STA addr"), + assocId, index); + dphPrintMacAddr(pMac, staAddr, LOG1);) + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA id %d"), assocId);) + return NULL; + } + + if (pDphHashTable->pDphNodeArray[assocId].added) + { + PELOGE(limLog(pMac, LOGE, FL("already added STA %d"), assocId);) + return NULL; + } + + for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) + { + if (ptr == ptr->next) + { + PELOGE(limLog(pMac, LOGE, FL("Infinite Loop"));) + return NULL; + } + + if (dphCompareMacAddr(staAddr, ptr->staAddr) || ptr->assocId== assocId) + break; + } + + if (ptr) + { + // Duplicate entry + limLog(pMac, LOGE, FL("assocId %d hashIndex %d entry exists"), + assocId, index); + return NULL; + } + else + { + if (dphInitStaState(pMac, staAddr, assocId, false, pDphHashTable) == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("could not Init STAid=%d"), assocId);) + return NULL; + } + + // Add the node to the link list + pDphHashTable->pDphNodeArray[assocId].next = pDphHashTable->pHashTable[index]; + pDphHashTable->pHashTable[index] = &pDphHashTable->pDphNodeArray[assocId]; + + node = pDphHashTable->pHashTable[index]; + return node; + } +} + +// --------------------------------------------------------------------- +/** + * dphDeleteHashEntry + * + * FUNCTION: + * Delete entry from hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param staId Station ID assigned to the station + * @return eSIR_SUCCESS if successful,\n + * eSIR_FAILURE otherwise + */ + +tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 assocId, dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr, prev; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + + PELOG1(limLog(pMac, LOG1, FL("assocId %d index %d STA addr"), + assocId, index); + dphPrintMacAddr(pMac, staAddr, LOG1);) + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA id %d"), assocId);) + return eSIR_FAILURE; + } + + if (pDphHashTable->pDphNodeArray[assocId].added == 0) + { + PELOGE(limLog(pMac, LOGE, FL("STA %d never added"), assocId);) + return eSIR_FAILURE; + } + + + for (prev = 0, ptr = pDphHashTable->pHashTable[index]; + ptr; + prev = ptr, ptr = ptr->next) + { + if (dphCompareMacAddr(staAddr, ptr->staAddr)) + break; + if (prev == ptr) + { + PELOGE(limLog(pMac, LOGE, FL("Infinite Loop"));) + return eSIR_FAILURE; + } + } + + if (ptr) + { + /// Delete the entry after invalidating it + ptr->valid = 0; + memset(ptr->staAddr, 0, sizeof(ptr->staAddr)); + if (prev == 0) + pDphHashTable->pHashTable[index] = ptr->next; + else + prev->next = ptr->next; + ptr->added = 0; + ptr->next = 0; + } + else + { + /// Entry not present + PELOGE(limLog(pMac, LOGE, FL("Entry not present STA addr")); + dphPrintMacAddr(pMac, staAddr, LOGE);) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------- +/** + * dphPrintMacAddr + * + * FUNCTION: + * Print a MAC address + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param addr MAC address + * @return None + */ + +void +dphPrintMacAddr(tpAniSirGlobal pMac, tANI_U8 addr[], tANI_U32 level) +{ + limLog(pMac, (tANI_U16) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"), + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); +} + +// --------------------------------------------------------------------- diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.h new file mode 100644 index 0000000000000..da6d584393e52 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/dph/dphHashTable.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file dphHashTable.h contains the definition of the scheduler class. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __DPH_HASH_TABLE_H__ +#define __DPH_HASH_TABLE_H__ + +#include "aniGlobal.h" +/// Compare MAC addresses, return true if same +static inline tANI_U8 +dphCompareMacAddr(tANI_U8 addr1[], tANI_U8 addr2[]) +{ + return((addr1[0] == addr2[0]) && + (addr1[1] == addr2[1]) && + (addr1[2] == addr2[2]) && + (addr1[3] == addr2[3]) && + (addr1[4] == addr2[4]) && + (addr1[5] == addr2[5])); +} + +/// Hash table class +typedef struct +{ + + /// The hash table itself + tpDphHashNode *pHashTable; + + /// The state array + tDphHashNode *pDphNodeArray; + tANI_U16 size; +} dphHashTableClass; + +/// The hash table object +extern dphHashTableClass dphHashTable; + +/// Print MAC addresse +extern void dphPrintMacAddr(struct sAniSirGlobal *pMac, tANI_U8 addr[], tANI_U32); + +tpDphHashNode dphLookupHashEntry(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 *pStaId, dphHashTableClass* pDphHashTable); +tpDphHashNode dphLookupAssocId(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U16* assocId, dphHashTableClass* pDphHashTable); + + +/// Get a pointer to the hash node +extern tpDphHashNode dphGetHashEntry(tpAniSirGlobal pMac, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +/// Add an entry to the hash table +extern tpDphHashNode dphAddHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +/// Delete an entry from the hash table +extern tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +void dphHashTableClassInit(tpAniSirGlobal pMac, dphHashTableClass* pDphHashTable); +/// Initialize STA state +extern tpDphHashNode dphInitStaState(tpAniSirGlobal pMac, tSirMacAddr staAddr, + tANI_U16 staId, tANI_U8 validStaIdx, dphHashTableClass* pDphHashTable); + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgApi.h new file mode 100644 index 0000000000000..fbd2f582a8ce7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgApi.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGAPI_H +#define __CFGAPI_H + +#include +#include +#include +#include +#include + + +/*---------------------------------------------------------------------*/ +/* CFG definitions */ +/*---------------------------------------------------------------------*/ + +// CFG status +typedef enum eCfgStatusTypes { + CFG_INCOMPLETE, + CFG_SUCCESS, + CFG_FAILURE +} tCfgStatusTypes; + +// WEP key mapping table row structure +typedef struct +{ + tANI_U8 keyMappingAddr[SIR_MAC_ADDR_LENGTH]; + tANI_U32 wepOn; + tANI_U8 key[SIR_MAC_KEY_LENGTH]; + tANI_U32 status; +} tCfgWepKeyEntry; + + +/*---------------------------------------------------------------------*/ +/* CFG function prototypes */ +/*---------------------------------------------------------------------*/ + +tANI_U32 cfgNeedRestart(tpAniSirGlobal pMac, tANI_U16 cfgId) ; +tANI_U32 cfgNeedReload(tpAniSirGlobal pMac, tANI_U16 cfgId) ; + +/// CFG initialization function +void wlan_cfgInit(tpAniSirGlobal); + +/// Process host message +void cfgProcessMbMsg(tpAniSirGlobal, tSirMbMsg*); + +/// Set integer parameter value +tSirRetStatus cfgSetInt(tpAniSirGlobal, tANI_U16, tANI_U32); + +/// Check if the parameter is valid +tSirRetStatus cfgCheckValid(tpAniSirGlobal, tANI_U16); + +/// Get integer parameter value +tSirRetStatus wlan_cfgGetInt(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Set string parameter value +tSirRetStatus cfgSetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32); + +tSirRetStatus cfgSetStrNotify(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32, int); + +//Cfg Download function for Prima or Integrated solutions. +void processCfgDownloadReq(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Get string parameter value +tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*); + +/// Get string parameter maximum length +tSirRetStatus wlan_cfgGetStrMaxLen(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Get string parameter maximum length +tSirRetStatus wlan_cfgGetStrLen(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Get the regulatory tx power on given channel +tPowerdBm cfgGetRegulatoryMaxTransmitPower(tpAniSirGlobal pMac, tANI_U8 channel); + +/// Dump CFG data to memory +void cfgDump(tANI_U32*); + +/// Save parameters with P flag set +void cfgSave(void); + +/// Get capability info +extern tSirRetStatus cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession psessionEntry); + +/// Set capability info +extern void cfgSetCapabilityInfo(tpAniSirGlobal, tANI_U16); + +/// Cleanup CFG module +void cfgCleanup(tpAniSirGlobal pMac); + +extern tANI_U8 *gCfgParamName[]; + +#endif /* __CFGAPI_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgGlobal.h new file mode 100644 index 0000000000000..7b75548e91c28 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/cfgGlobal.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/09/03 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGGLOBAL_H +#define __CFGGLOBAL_H + +#include "sirCommon.h" +#include "sirTypes.h" +#include "wniCfgSta.h" + +#define CFG_MAX_NUM_STA SIR_MAX_NUM_STA_IN_IBSS + +#define CFG_MAX_STR_LEN 256 // as the number of channels grows, 128 is not big enough + +/*--------------------------------------------------------------------*/ +/* Configuration Control Structure */ +/*--------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 control; +} tCfgCtl; + + +typedef struct sAniSirCfg +{ + // CFG module status + tANI_U8 gCfgStatus; + + tCfgCtl *gCfgEntry; + tANI_U32 *gCfgIBufMin; + tANI_U32 *gCfgIBufMax; + tANI_U32 *gCfgIBuf; + tANI_U8 *gCfgSBuf; + + tANI_U16 gCfgMaxIBufSize; + tANI_U16 gCfgMaxSBufSize; + + // Static buffer for string parameter (must be word-aligned) + tANI_U8 *gSBuffer; + + // Message parameter list buffer (enough for largest possible response) + tANI_U32 *gParamList; +} tAniSirCfg, *tpAniSirCfg; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h new file mode 100644 index 0000000000000..4f362d97fa482 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h @@ -0,0 +1,7941 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef DOT11F_H +#define DOT11F_H +/** + * \file dot11f.h + * + * \brief Structures, function prototypes & definitions + * for working with 802.11 Frames + * + * + * + * + * This file was automatically generated by 'framesc' + * Fri Jan 30 11:23:47 2015 from the following file(s): + * + * dot11f.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * Instead, please update the input files & re-run + * 'framesc' For more information on 'framesc' & the + * frames language, run 'framesc --help'. + * + * + */ + +typedef tANI_U32 tDOT11F_U64[2]; + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4214) /* nonstandard extension used */ +#endif /* Microsoft C/C++ bit field types other than int */ + +/* + * Frames Return Codes: + * + * Success is indicated by a return value of zero. Failure is indicated + * by the presence of the high bit. Warnings encountered in the course + * of a successful parse are indicated by various bits in the lower 31 + * being turned on. + * + * For instance, a return value of 0x0000000a would indicate that the + * parse succeeded, but that a mandatory IE wasn't present, and some IE + * was found to be corrupt. + * + * + */ + +#define DOT11F_PARSE_SUCCESS ( 0x00000000 ) +#define DOT11F_UNKNOWN_IES ( 0x00000001 ) +#define DOT11F_MANDATORY_IE_MISSING ( 0x00000002 ) +#define DOT11F_INCOMPLETE_IE ( 0x00000004 ) +#define DOT11F_SKIPPED_BAD_IE ( 0x00000008 ) +#define DOT11F_LAST_IE_TOO_LONG ( 0x00000010 ) +#define DOT11F_DUPLICATE_IE ( 0x00000020 ) +#define DOT11F_BAD_FIXED_VALUE ( 0x00000040 ) +#define DOT11F_INCOMPLETE_TLV ( 0x00000080 ) +#define DOT11F_INVALID_TLV_LENGTH ( 0x00000100 ) +#define DOT11F_SKIPPED_BAD_TLV ( 0x00000200 ) +#define DOT11F_UNKNOWN_TLVS ( 0x00000400 ) +#define DOT11F_LAST_TLV_TOO_LONG ( 0x00000800 ) +#define DOT11F_INTERNAL_ERROR ( 0x10000001 ) +#define DOT11F_MISSING_FIXED_FIELD ( 0x10000002 ) +#define DOT11F_BAD_INPUT_BUFFER ( 0x10000003 ) +#define DOT11F_BAD_OUTPUT_BUFFER ( 0x10000004 ) +#define DOT11F_BUFFER_OVERFLOW ( 0x10000005 ) +#define DOT11F_MANDATORY_TLV_MISSING ( 0x00001000 ) +#define DOT11F_FAILED(code) ( (code) & 0x10000000 ) +#define DOT11F_WARNED(code) ( ( ( 0 == (code) ) & 0x10000000 ) && code) +#define DOT11F_SUCCEEDED(code) ( (code) == 0 ) + +/********************************************************************* + * Fixed Fields * + ********************************************************************/ + +typedef struct sDot11fFfAID { + tANI_U16 associd; +} tDot11fFfAID; + +#define DOT11F_FF_AID_LEN ( 2 ) + +void dot11fUnpackFfAID(tpAniSirGlobal, tANI_U8*, tDot11fFfAID*); + +void dot11fPackFfAID(tpAniSirGlobal, tDot11fFfAID*, tANI_U8*); + +typedef struct sDot11fFfAction { + tANI_U8 action; +} tDot11fFfAction; + +#define DOT11F_FF_ACTION_LEN ( 1 ) + +void dot11fUnpackFfAction(tpAniSirGlobal, tANI_U8*, tDot11fFfAction*); + +void dot11fPackFfAction(tpAniSirGlobal, tDot11fFfAction*, tANI_U8*); + +typedef struct sDot11fFfAddBAParameterSet { + tANI_U16 amsduSupported: 1; + tANI_U16 policy: 1; + tANI_U16 tid: 4; + tANI_U16 bufferSize: 10; +} tDot11fFfAddBAParameterSet; + +#define DOT11F_FF_ADDBAPARAMETERSET_LEN ( 2 ) + +void dot11fUnpackFfAddBAParameterSet(tpAniSirGlobal, tANI_U8*, tDot11fFfAddBAParameterSet*); + +void dot11fPackFfAddBAParameterSet(tpAniSirGlobal, tDot11fFfAddBAParameterSet*, tANI_U8*); + +#define ADDBAPARAMETERSET_AMSDUSUPPORTED_OFFSET 0 +#define ADDBAPARAMETERSET_AMSDUSUPPORTED_WIDTH 1 +#define ADDBAPARAMETERSET_POLICY_OFFSET 1 +#define ADDBAPARAMETERSET_POLICY_WIDTH 1 +#define ADDBAPARAMETERSET_TID_OFFSET 2 +#define ADDBAPARAMETERSET_TID_WIDTH 4 +#define ADDBAPARAMETERSET_BUFFERSIZE_OFFSET 6 +#define ADDBAPARAMETERSET_BUFFERSIZE_WIDTH 10 + +typedef struct sDot11fFfAuthAlgo { + tANI_U16 algo; +} tDot11fFfAuthAlgo; + +#define DOT11F_FF_AUTHALGO_LEN ( 2 ) + +void dot11fUnpackFfAuthAlgo(tpAniSirGlobal, tANI_U8*, tDot11fFfAuthAlgo*); + +void dot11fPackFfAuthAlgo(tpAniSirGlobal, tDot11fFfAuthAlgo*, tANI_U8*); + +typedef struct sDot11fFfAuthSeqNo { + tANI_U16 no; +} tDot11fFfAuthSeqNo; + +#define DOT11F_FF_AUTHSEQNO_LEN ( 2 ) + +void dot11fUnpackFfAuthSeqNo(tpAniSirGlobal, tANI_U8*, tDot11fFfAuthSeqNo*); + +void dot11fPackFfAuthSeqNo(tpAniSirGlobal, tDot11fFfAuthSeqNo*, tANI_U8*); + +typedef struct sDot11fFfBAStartingSequenceControl { + tANI_U16 fragNumber: 4; + tANI_U16 ssn: 12; +} tDot11fFfBAStartingSequenceControl; + +#define DOT11F_FF_BASTARTINGSEQUENCECONTROL_LEN ( 2 ) + +void dot11fUnpackFfBAStartingSequenceControl(tpAniSirGlobal, tANI_U8*, tDot11fFfBAStartingSequenceControl*); + +void dot11fPackFfBAStartingSequenceControl(tpAniSirGlobal, tDot11fFfBAStartingSequenceControl*, tANI_U8*); + +#define BASTARTINGSEQUENCECONTROL_FRAGNUMBER_OFFSET 0 +#define BASTARTINGSEQUENCECONTROL_FRAGNUMBER_WIDTH 4 +#define BASTARTINGSEQUENCECONTROL_SSN_OFFSET 4 +#define BASTARTINGSEQUENCECONTROL_SSN_WIDTH 12 + +typedef struct sDot11fFfBATimeout { + tANI_U16 timeout; +} tDot11fFfBATimeout; + +#define DOT11F_FF_BATIMEOUT_LEN ( 2 ) + +void dot11fUnpackFfBATimeout(tpAniSirGlobal, tANI_U8*, tDot11fFfBATimeout*); + +void dot11fPackFfBATimeout(tpAniSirGlobal, tDot11fFfBATimeout*, tANI_U8*); + +typedef struct sDot11fFfBeaconInterval { + tANI_U16 interval; +} tDot11fFfBeaconInterval; + +#define DOT11F_FF_BEACONINTERVAL_LEN ( 2 ) + +void dot11fUnpackFfBeaconInterval(tpAniSirGlobal, tANI_U8*, tDot11fFfBeaconInterval*); + +void dot11fPackFfBeaconInterval(tpAniSirGlobal, tDot11fFfBeaconInterval*, tANI_U8*); + +typedef struct sDot11fFfCapabilities { + tANI_U16 ess: 1; + tANI_U16 ibss: 1; + tANI_U16 cfPollable: 1; + tANI_U16 cfPollReq: 1; + tANI_U16 privacy: 1; + tANI_U16 shortPreamble: 1; + tANI_U16 pbcc: 1; + tANI_U16 channelAgility: 1; + tANI_U16 spectrumMgt: 1; + tANI_U16 qos: 1; + tANI_U16 shortSlotTime: 1; + tANI_U16 apsd: 1; + tANI_U16 rrm: 1; + tANI_U16 dsssOfdm: 1; + tANI_U16 delayedBA: 1; + tANI_U16 immediateBA: 1; +} tDot11fFfCapabilities; + +#define DOT11F_FF_CAPABILITIES_LEN ( 2 ) + +void dot11fUnpackFfCapabilities(tpAniSirGlobal, tANI_U8*, tDot11fFfCapabilities*); + +void dot11fPackFfCapabilities(tpAniSirGlobal, tDot11fFfCapabilities*, tANI_U8*); + +#define CAPABILITIES_ESS_OFFSET 0 +#define CAPABILITIES_ESS_WIDTH 1 +#define CAPABILITIES_IBSS_OFFSET 1 +#define CAPABILITIES_IBSS_WIDTH 1 +#define CAPABILITIES_CFPOLLABLE_OFFSET 2 +#define CAPABILITIES_CFPOLLABLE_WIDTH 1 +#define CAPABILITIES_CFPOLLREQ_OFFSET 3 +#define CAPABILITIES_CFPOLLREQ_WIDTH 1 +#define CAPABILITIES_PRIVACY_OFFSET 4 +#define CAPABILITIES_PRIVACY_WIDTH 1 +#define CAPABILITIES_SHORTPREAMBLE_OFFSET 5 +#define CAPABILITIES_SHORTPREAMBLE_WIDTH 1 +#define CAPABILITIES_PBCC_OFFSET 6 +#define CAPABILITIES_PBCC_WIDTH 1 +#define CAPABILITIES_CHANNELAGILITY_OFFSET 7 +#define CAPABILITIES_CHANNELAGILITY_WIDTH 1 +#define CAPABILITIES_SPECTRUMMGT_OFFSET 8 +#define CAPABILITIES_SPECTRUMMGT_WIDTH 1 +#define CAPABILITIES_QOS_OFFSET 9 +#define CAPABILITIES_QOS_WIDTH 1 +#define CAPABILITIES_SHORTSLOTTIME_OFFSET 10 +#define CAPABILITIES_SHORTSLOTTIME_WIDTH 1 +#define CAPABILITIES_APSD_OFFSET 11 +#define CAPABILITIES_APSD_WIDTH 1 +#define CAPABILITIES_RRM_OFFSET 12 +#define CAPABILITIES_RRM_WIDTH 1 +#define CAPABILITIES_DSSSOFDM_OFFSET 13 +#define CAPABILITIES_DSSSOFDM_WIDTH 1 +#define CAPABILITIES_DELAYEDBA_OFFSET 14 +#define CAPABILITIES_DELAYEDBA_WIDTH 1 +#define CAPABILITIES_IMMEDIATEBA_OFFSET 15 +#define CAPABILITIES_IMMEDIATEBA_WIDTH 1 + +typedef struct sDot11fFfCategory { + tANI_U8 category; +} tDot11fFfCategory; + +#define DOT11F_FF_CATEGORY_LEN ( 1 ) + +void dot11fUnpackFfCategory(tpAniSirGlobal, tANI_U8*, tDot11fFfCategory*); + +void dot11fPackFfCategory(tpAniSirGlobal, tDot11fFfCategory*, tANI_U8*); + +typedef struct sDot11fFfCurrentAPAddress { + tANI_U8 mac[6]; +} tDot11fFfCurrentAPAddress; + +#define DOT11F_FF_CURRENTAPADDRESS_LEN ( 6 ) + +void dot11fUnpackFfCurrentAPAddress(tpAniSirGlobal, tANI_U8*, tDot11fFfCurrentAPAddress*); + +void dot11fPackFfCurrentAPAddress(tpAniSirGlobal, tDot11fFfCurrentAPAddress*, tANI_U8*); + +typedef struct sDot11fFfDelBAParameterSet { + tANI_U16 reserved: 11; + tANI_U16 initiator: 1; + tANI_U16 tid: 4; +} tDot11fFfDelBAParameterSet; + +#define DOT11F_FF_DELBAPARAMETERSET_LEN ( 2 ) + +void dot11fUnpackFfDelBAParameterSet(tpAniSirGlobal, tANI_U8*, tDot11fFfDelBAParameterSet*); + +void dot11fPackFfDelBAParameterSet(tpAniSirGlobal, tDot11fFfDelBAParameterSet*, tANI_U8*); + +#define DELBAPARAMETERSET_RESERVED_OFFSET 0 +#define DELBAPARAMETERSET_RESERVED_WIDTH 11 +#define DELBAPARAMETERSET_INITIATOR_OFFSET 11 +#define DELBAPARAMETERSET_INITIATOR_WIDTH 1 +#define DELBAPARAMETERSET_TID_OFFSET 12 +#define DELBAPARAMETERSET_TID_WIDTH 4 + +typedef struct sDot11fFfDialogToken { + tANI_U8 token; +} tDot11fFfDialogToken; + +#define DOT11F_FF_DIALOGTOKEN_LEN ( 1 ) + +void dot11fUnpackFfDialogToken(tpAniSirGlobal, tANI_U8*, tDot11fFfDialogToken*); + +void dot11fPackFfDialogToken(tpAniSirGlobal, tDot11fFfDialogToken*, tANI_U8*); + +typedef struct sDot11fFfLinkMargin { + tANI_U8 linkMargin; +} tDot11fFfLinkMargin; + +#define DOT11F_FF_LINKMARGIN_LEN ( 1 ) + +void dot11fUnpackFfLinkMargin(tpAniSirGlobal, tANI_U8*, tDot11fFfLinkMargin*); + +void dot11fPackFfLinkMargin(tpAniSirGlobal, tDot11fFfLinkMargin*, tANI_U8*); + +typedef struct sDot11fFfListenInterval { + tANI_U16 interval; +} tDot11fFfListenInterval; + +#define DOT11F_FF_LISTENINTERVAL_LEN ( 2 ) + +void dot11fUnpackFfListenInterval(tpAniSirGlobal, tANI_U8*, tDot11fFfListenInterval*); + +void dot11fPackFfListenInterval(tpAniSirGlobal, tDot11fFfListenInterval*, tANI_U8*); + +typedef struct sDot11fFfMaxTxPower { + tANI_U8 maxTxPower; +} tDot11fFfMaxTxPower; + +#define DOT11F_FF_MAXTXPOWER_LEN ( 1 ) + +void dot11fUnpackFfMaxTxPower(tpAniSirGlobal, tANI_U8*, tDot11fFfMaxTxPower*); + +void dot11fPackFfMaxTxPower(tpAniSirGlobal, tDot11fFfMaxTxPower*, tANI_U8*); + +typedef struct sDot11fFfNumOfRepetitions { + tANI_U16 repetitions; +} tDot11fFfNumOfRepetitions; + +#define DOT11F_FF_NUMOFREPETITIONS_LEN ( 2 ) + +void dot11fUnpackFfNumOfRepetitions(tpAniSirGlobal, tANI_U8*, tDot11fFfNumOfRepetitions*); + +void dot11fPackFfNumOfRepetitions(tpAniSirGlobal, tDot11fFfNumOfRepetitions*, tANI_U8*); + +typedef struct sDot11fFfOperatingMode { + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +} tDot11fFfOperatingMode; + +#define DOT11F_FF_OPERATINGMODE_LEN ( 1 ) + +void dot11fUnpackFfOperatingMode(tpAniSirGlobal, tANI_U8*, tDot11fFfOperatingMode*); + +void dot11fPackFfOperatingMode(tpAniSirGlobal, tDot11fFfOperatingMode*, tANI_U8*); + +#define OPERATINGMODE_CHANWIDTH_OFFSET 0 +#define OPERATINGMODE_CHANWIDTH_WIDTH 2 +#define OPERATINGMODE_RESERVED_OFFSET 2 +#define OPERATINGMODE_RESERVED_WIDTH 2 +#define OPERATINGMODE_RXNSS_OFFSET 4 +#define OPERATINGMODE_RXNSS_WIDTH 3 +#define OPERATINGMODE_RXNSSTYPE_OFFSET 7 +#define OPERATINGMODE_RXNSSTYPE_WIDTH 1 + +typedef struct sDot11fFfP2POUI { + tANI_U32 oui; +} tDot11fFfP2POUI; + +#define DOT11F_FF_P2POUI_LEN ( 4 ) + +void dot11fUnpackFfP2POUI(tpAniSirGlobal, tANI_U8*, tDot11fFfP2POUI*); + +void dot11fPackFfP2POUI(tpAniSirGlobal, tDot11fFfP2POUI*, tANI_U8*); + +typedef struct sDot11fFfP2POUISubType { + tANI_U8 ouiSubtype; +} tDot11fFfP2POUISubType; + +#define DOT11F_FF_P2POUISUBTYPE_LEN ( 1 ) + +void dot11fUnpackFfP2POUISubType(tpAniSirGlobal, tANI_U8*, tDot11fFfP2POUISubType*); + +void dot11fPackFfP2POUISubType(tpAniSirGlobal, tDot11fFfP2POUISubType*, tANI_U8*); + +typedef struct sDot11fFfRCPI { + tANI_U8 rcpi; +} tDot11fFfRCPI; + +#define DOT11F_FF_RCPI_LEN ( 1 ) + +void dot11fUnpackFfRCPI(tpAniSirGlobal, tANI_U8*, tDot11fFfRCPI*); + +void dot11fPackFfRCPI(tpAniSirGlobal, tDot11fFfRCPI*, tANI_U8*); + +typedef struct sDot11fFfRSNI { + tANI_U8 rsni; +} tDot11fFfRSNI; + +#define DOT11F_FF_RSNI_LEN ( 1 ) + +void dot11fUnpackFfRSNI(tpAniSirGlobal, tANI_U8*, tDot11fFfRSNI*); + +void dot11fPackFfRSNI(tpAniSirGlobal, tDot11fFfRSNI*, tANI_U8*); + +typedef struct sDot11fFfReason { + tANI_U16 code; +} tDot11fFfReason; + +#define DOT11F_FF_REASON_LEN ( 2 ) + +void dot11fUnpackFfReason(tpAniSirGlobal, tANI_U8*, tDot11fFfReason*); + +void dot11fPackFfReason(tpAniSirGlobal, tDot11fFfReason*, tANI_U8*); + +typedef struct sDot11fFfRxAntennaId { + tANI_U8 antennaId; +} tDot11fFfRxAntennaId; + +#define DOT11F_FF_RXANTENNAID_LEN ( 1 ) + +void dot11fUnpackFfRxAntennaId(tpAniSirGlobal, tANI_U8*, tDot11fFfRxAntennaId*); + +void dot11fPackFfRxAntennaId(tpAniSirGlobal, tDot11fFfRxAntennaId*, tANI_U8*); + +typedef struct sDot11fFfSMPowerModeSet { + tANI_U8 PowerSave_En: 1; + tANI_U8 Mode: 1; + tANI_U8 reserved: 6; +} tDot11fFfSMPowerModeSet; + +#define DOT11F_FF_SMPOWERMODESET_LEN ( 1 ) + +void dot11fUnpackFfSMPowerModeSet(tpAniSirGlobal, tANI_U8*, tDot11fFfSMPowerModeSet*); + +void dot11fPackFfSMPowerModeSet(tpAniSirGlobal, tDot11fFfSMPowerModeSet*, tANI_U8*); + +#define SMPOWERMODESET_POWERSAVE_EN_OFFSET 0 +#define SMPOWERMODESET_POWERSAVE_EN_WIDTH 1 +#define SMPOWERMODESET_MODE_OFFSET 1 +#define SMPOWERMODESET_MODE_WIDTH 1 +#define SMPOWERMODESET_RESERVED_OFFSET 2 +#define SMPOWERMODESET_RESERVED_WIDTH 6 + +typedef struct sDot11fFfStatus { + tANI_U16 status; +} tDot11fFfStatus; + +#define DOT11F_FF_STATUS_LEN ( 2 ) + +void dot11fUnpackFfStatus(tpAniSirGlobal, tANI_U8*, tDot11fFfStatus*); + +void dot11fPackFfStatus(tpAniSirGlobal, tDot11fFfStatus*, tANI_U8*); + +typedef struct sDot11fFfStatusCode { + tANI_U8 statusCode; +} tDot11fFfStatusCode; + +#define DOT11F_FF_STATUSCODE_LEN ( 1 ) + +void dot11fUnpackFfStatusCode(tpAniSirGlobal, tANI_U8*, tDot11fFfStatusCode*); + +void dot11fPackFfStatusCode(tpAniSirGlobal, tDot11fFfStatusCode*, tANI_U8*); + +typedef struct sDot11fFfTPCEleID { + tANI_U8 TPCId; +} tDot11fFfTPCEleID; + +#define DOT11F_FF_TPCELEID_LEN ( 1 ) + +void dot11fUnpackFfTPCEleID(tpAniSirGlobal, tANI_U8*, tDot11fFfTPCEleID*); + +void dot11fPackFfTPCEleID(tpAniSirGlobal, tDot11fFfTPCEleID*, tANI_U8*); + +typedef struct sDot11fFfTPCEleLen { + tANI_U8 TPCLen; +} tDot11fFfTPCEleLen; + +#define DOT11F_FF_TPCELELEN_LEN ( 1 ) + +void dot11fUnpackFfTPCEleLen(tpAniSirGlobal, tANI_U8*, tDot11fFfTPCEleLen*); + +void dot11fPackFfTPCEleLen(tpAniSirGlobal, tDot11fFfTPCEleLen*, tANI_U8*); + +typedef struct sDot11fFfTSInfo { + tANI_U32 traffic_type: 1; + tANI_U32 tsid: 4; + tANI_U32 direction: 2; + tANI_U32 access_policy: 2; + tANI_U32 aggregation: 1; + tANI_U32 psb: 1; + tANI_U32 user_priority: 3; + tANI_U32 tsinfo_ack_pol: 2; + tANI_U32 schedule: 1; + tANI_U32 unused: 15; +} tDot11fFfTSInfo; + +#define DOT11F_FF_TSINFO_LEN ( 3 ) + +void dot11fUnpackFfTSInfo(tpAniSirGlobal, tANI_U8*, tDot11fFfTSInfo*); + +void dot11fPackFfTSInfo(tpAniSirGlobal, tDot11fFfTSInfo*, tANI_U8*); + +#define TSINFO_TRAFFIC_TYPE_OFFSET 0 +#define TSINFO_TRAFFIC_TYPE_WIDTH 1 +#define TSINFO_TSID_OFFSET 1 +#define TSINFO_TSID_WIDTH 4 +#define TSINFO_DIRECTION_OFFSET 5 +#define TSINFO_DIRECTION_WIDTH 2 +#define TSINFO_ACCESS_POLICY_OFFSET 7 +#define TSINFO_ACCESS_POLICY_WIDTH 2 +#define TSINFO_AGGREGATION_OFFSET 9 +#define TSINFO_AGGREGATION_WIDTH 1 +#define TSINFO_PSB_OFFSET 10 +#define TSINFO_PSB_WIDTH 1 +#define TSINFO_USER_PRIORITY_OFFSET 11 +#define TSINFO_USER_PRIORITY_WIDTH 3 +#define TSINFO_TSINFO_ACK_POL_OFFSET 14 +#define TSINFO_TSINFO_ACK_POL_WIDTH 2 +#define TSINFO_SCHEDULE_OFFSET 16 +#define TSINFO_SCHEDULE_WIDTH 1 +#define TSINFO_UNUSED_OFFSET 17 +#define TSINFO_UNUSED_WIDTH 15 + +typedef struct sDot11fFfTimeStamp { + tDOT11F_U64 timestamp; +} tDot11fFfTimeStamp; + +#define DOT11F_FF_TIMESTAMP_LEN ( 8 ) + +void dot11fUnpackFfTimeStamp(tpAniSirGlobal, tANI_U8*, tDot11fFfTimeStamp*); + +void dot11fPackFfTimeStamp(tpAniSirGlobal, tDot11fFfTimeStamp*, tANI_U8*); + +typedef struct sDot11fFfTransactionId { + tANI_U8 transId[2]; +} tDot11fFfTransactionId; + +#define DOT11F_FF_TRANSACTIONID_LEN ( 2 ) + +void dot11fUnpackFfTransactionId(tpAniSirGlobal, tANI_U8*, tDot11fFfTransactionId*); + +void dot11fPackFfTransactionId(tpAniSirGlobal, tDot11fFfTransactionId*, tANI_U8*); + +typedef struct sDot11fFfTxAntennaId { + tANI_U8 antennaId; +} tDot11fFfTxAntennaId; + +#define DOT11F_FF_TXANTENNAID_LEN ( 1 ) + +void dot11fUnpackFfTxAntennaId(tpAniSirGlobal, tANI_U8*, tDot11fFfTxAntennaId*); + +void dot11fPackFfTxAntennaId(tpAniSirGlobal, tDot11fFfTxAntennaId*, tANI_U8*); + +typedef struct sDot11fFfTxPower { + tANI_U8 txPower; +} tDot11fFfTxPower; + +#define DOT11F_FF_TXPOWER_LEN ( 1 ) + +void dot11fUnpackFfTxPower(tpAniSirGlobal, tANI_U8*, tDot11fFfTxPower*); + +void dot11fPackFfTxPower(tpAniSirGlobal, tDot11fFfTxPower*, tANI_U8*); + +typedef struct sDot11fFfVhtMembershipStatusArray { + tANI_U8 membershipStatusArray[8]; +} tDot11fFfVhtMembershipStatusArray; + +#define DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN ( 8 ) + +void dot11fUnpackFfVhtMembershipStatusArray(tpAniSirGlobal, tANI_U8*, tDot11fFfVhtMembershipStatusArray*); + +void dot11fPackFfVhtMembershipStatusArray(tpAniSirGlobal, tDot11fFfVhtMembershipStatusArray*, tANI_U8*); + +typedef struct sDot11fFfVhtUserPositionArray { + tANI_U8 userPositionArray[16]; +} tDot11fFfVhtUserPositionArray; + +#define DOT11F_FF_VHTUSERPOSITIONARRAY_LEN ( 16 ) + +void dot11fUnpackFfVhtUserPositionArray(tpAniSirGlobal, tANI_U8*, tDot11fFfVhtUserPositionArray*); + +void dot11fPackFfVhtUserPositionArray(tpAniSirGlobal, tDot11fFfVhtUserPositionArray*, tANI_U8*); + +/********************************************************************* + * TLVs * + ********************************************************************/ + +// ID 1 (0x0001) +typedef struct sDot11fTLVAuthorizedMACs { + tANI_U8 present; + tANI_U8 mac[6]; +} tDot11fTLVAuthorizedMACs; + +#define DOT11F_TLV_AUTHORIZEDMACS ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_AUTHORIZEDMACS_MIN_LEN ( 6 ) + +#define DOT11F_TLV_AUTHORIZEDMACS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAuthorizedMACs*); + +tANI_U32 dot11fPackTlvAuthorizedMACs(tpAniSirGlobal, tDot11fTLVAuthorizedMACs*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAuthorizedMACs(tpAniSirGlobal, tDot11fTLVAuthorizedMACs*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3 (0x0003) +typedef struct sDot11fTLVRequestToEnroll { + tANI_U8 present; + tANI_U8 req; +} tDot11fTLVRequestToEnroll; + +#define DOT11F_TLV_REQUESTTOENROLL ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTTOENROLL_MIN_LEN ( 1 ) + +#define DOT11F_TLV_REQUESTTOENROLL_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestToEnroll(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestToEnroll*); + +tANI_U32 dot11fPackTlvRequestToEnroll(tpAniSirGlobal, tDot11fTLVRequestToEnroll*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestToEnroll(tpAniSirGlobal, tDot11fTLVRequestToEnroll*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 0 (0x0000) +typedef struct sDot11fTLVVersion2 { + tANI_U8 present; + tANI_U8 minor: 4; + tANI_U8 major: 4; +} tDot11fTLVVersion2; + +#define DOT11F_TLV_VERSION2 ( 0 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VERSION2_MIN_LEN ( 1 ) + +#define DOT11F_TLV_VERSION2_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVersion2(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVersion2*); + +tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal, tDot11fTLVVersion2*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVersion2(tpAniSirGlobal, tDot11fTLVVersion2*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4183 (0x1057) +typedef struct sDot11fTLVAPSetupLocked { + tANI_U8 present; + tANI_U8 fLocked; +} tDot11fTLVAPSetupLocked; + +#define DOT11F_TLV_APSETUPLOCKED ( 4183 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_APSETUPLOCKED_MIN_LEN ( 3 ) + +#define DOT11F_TLV_APSETUPLOCKED_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAPSetupLocked(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAPSetupLocked*); + +tANI_U32 dot11fPackTlvAPSetupLocked(tpAniSirGlobal, tDot11fTLVAPSetupLocked*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAPSetupLocked(tpAniSirGlobal, tDot11fTLVAPSetupLocked*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4098 (0x1002) +typedef struct sDot11fTLVAssociationState { + tANI_U8 present; + tANI_U16 state; +} tDot11fTLVAssociationState; + +#define DOT11F_TLV_ASSOCIATIONSTATE ( 4098 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_ASSOCIATIONSTATE_MIN_LEN ( 4 ) + +#define DOT11F_TLV_ASSOCIATIONSTATE_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAssociationState(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAssociationState*); + +tANI_U32 dot11fPackTlvAssociationState(tpAniSirGlobal, tDot11fTLVAssociationState*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAssociationState(tpAniSirGlobal, tDot11fTLVAssociationState*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 11 (0x000b) +typedef struct sDot11fTLVChannelList { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 num_channelList; + tANI_U8 channelList[251]; +} tDot11fTLVChannelList; + +#define DOT11F_TLV_CHANNELLIST ( 11 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CHANNELLIST_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CHANNELLIST_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvChannelList(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVChannelList*); + +tANI_U32 dot11fPackTlvChannelList(tpAniSirGlobal, tDot11fTLVChannelList*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvChannelList(tpAniSirGlobal, tDot11fTLVChannelList*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4104 (0x1008) +typedef struct sDot11fTLVConfigMethods { + tANI_U8 present; + tANI_U16 methods; +} tDot11fTLVConfigMethods; + +#define DOT11F_TLV_CONFIGMETHODS ( 4104 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGMETHODS_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CONFIGMETHODS_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigMethods(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigMethods*); + +tANI_U32 dot11fPackTlvConfigMethods(tpAniSirGlobal, tDot11fTLVConfigMethods*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigMethods(tpAniSirGlobal, tDot11fTLVConfigMethods*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4105 (0x1009) +typedef struct sDot11fTLVConfigurationError { + tANI_U8 present; + tANI_U16 error; +} tDot11fTLVConfigurationError; + +#define DOT11F_TLV_CONFIGURATIONERROR ( 4105 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGURATIONERROR_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CONFIGURATIONERROR_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigurationError(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigurationError*); + +tANI_U32 dot11fPackTlvConfigurationError(tpAniSirGlobal, tDot11fTLVConfigurationError*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigurationError(tpAniSirGlobal, tDot11fTLVConfigurationError*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5 (0x0005) +typedef struct sDot11fTLVConfigurationTimeout { + tANI_U8 present; + tANI_U8 GOConfigTimeout; + tANI_U8 CLConfigTimeout; +} tDot11fTLVConfigurationTimeout; + +#define DOT11F_TLV_CONFIGURATIONTIMEOUT ( 5 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGURATIONTIMEOUT_MIN_LEN ( 3 ) + +#define DOT11F_TLV_CONFIGURATIONTIMEOUT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigurationTimeout(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigurationTimeout*); + +tANI_U32 dot11fPackTlvConfigurationTimeout(tpAniSirGlobal, tDot11fTLVConfigurationTimeout*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigurationTimeout(tpAniSirGlobal, tDot11fTLVConfigurationTimeout*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4113 (0x1011) +typedef struct sDot11fTLVDeviceName { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVDeviceName; + +#define DOT11F_TLV_DEVICENAME ( 4113 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_DEVICENAME_MIN_LEN ( 2 ) + +#define DOT11F_TLV_DEVICENAME_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvDeviceName(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVDeviceName*); + +tANI_U32 dot11fPackTlvDeviceName(tpAniSirGlobal, tDot11fTLVDeviceName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvDeviceName(tpAniSirGlobal, tDot11fTLVDeviceName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4114 (0x1012) +typedef struct sDot11fTLVDevicePasswordID { + tANI_U8 present; + tANI_U16 id; +} tDot11fTLVDevicePasswordID; + +#define DOT11F_TLV_DEVICEPASSWORDID ( 4114 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_DEVICEPASSWORDID_MIN_LEN ( 4 ) + +#define DOT11F_TLV_DEVICEPASSWORDID_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvDevicePasswordID(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVDevicePasswordID*); + +tANI_U32 dot11fPackTlvDevicePasswordID(tpAniSirGlobal, tDot11fTLVDevicePasswordID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvDevicePasswordID(tpAniSirGlobal, tDot11fTLVDevicePasswordID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 8 (0x0008) +typedef struct sDot11fTLVExtendedListenTiming { + tANI_U8 present; + tANI_U16 availibilityPeriod; + tANI_U16 availibilityInterval; +} tDot11fTLVExtendedListenTiming; + +#define DOT11F_TLV_EXTENDEDLISTENTIMING ( 8 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_EXTENDEDLISTENTIMING_MIN_LEN ( 5 ) + +#define DOT11F_TLV_EXTENDEDLISTENTIMING_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvExtendedListenTiming(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVExtendedListenTiming*); + +tANI_U32 dot11fPackTlvExtendedListenTiming(tpAniSirGlobal, tDot11fTLVExtendedListenTiming*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvExtendedListenTiming(tpAniSirGlobal, tDot11fTLVExtendedListenTiming*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4 (0x0004) +typedef struct sDot11fTLVGOIntent { + tANI_U8 present; + tANI_U8 GOIntent; +} tDot11fTLVGOIntent; + +#define DOT11F_TLV_GOINTENT ( 4 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_GOINTENT_MIN_LEN ( 2 ) + +#define DOT11F_TLV_GOINTENT_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvGOIntent(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVGOIntent*); + +tANI_U32 dot11fPackTlvGOIntent(tpAniSirGlobal, tDot11fTLVGOIntent*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvGOIntent(tpAniSirGlobal, tDot11fTLVGOIntent*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 9 (0x0009) +typedef struct sDot11fTLVIntendedP2PInterfaceAddress { + tANI_U8 present; + tANI_U8 P2PInterfaceAddress[6]; +} tDot11fTLVIntendedP2PInterfaceAddress; + +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS ( 9 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS_MIN_LEN ( 7 ) + +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVIntendedP2PInterfaceAddress*); + +tANI_U32 dot11fPackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tDot11fTLVIntendedP2PInterfaceAddress*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tDot11fTLVIntendedP2PInterfaceAddress*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 18 (0x0012) +typedef struct sDot11fTLVInvitationFlags { + tANI_U8 present; + tANI_U8 invitationFlags; +} tDot11fTLVInvitationFlags; + +#define DOT11F_TLV_INVITATIONFLAGS ( 18 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_INVITATIONFLAGS_MIN_LEN ( 2 ) + +#define DOT11F_TLV_INVITATIONFLAGS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvInvitationFlags(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVInvitationFlags*); + +tANI_U32 dot11fPackTlvInvitationFlags(tpAniSirGlobal, tDot11fTLVInvitationFlags*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvInvitationFlags(tpAniSirGlobal, tDot11fTLVInvitationFlags*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6 (0x0006) +typedef struct sDot11fTLVListenChannel { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 regulatoryClass; + tANI_U8 channel; +} tDot11fTLVListenChannel; + +#define DOT11F_TLV_LISTENCHANNEL ( 6 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_LISTENCHANNEL_MIN_LEN ( 6 ) + +#define DOT11F_TLV_LISTENCHANNEL_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvListenChannel(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVListenChannel*); + +tANI_U32 dot11fPackTlvListenChannel(tpAniSirGlobal, tDot11fTLVListenChannel*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvListenChannel(tpAniSirGlobal, tDot11fTLVListenChannel*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4129 (0x1021) +typedef struct sDot11fTLVManufacturer { + tANI_U8 present; + tANI_U8 num_name; + tANI_U8 name[64]; +} tDot11fTLVManufacturer; + +#define DOT11F_TLV_MANUFACTURER ( 4129 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MANUFACTURER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MANUFACTURER_MAX_LEN ( 66 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvManufacturer(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVManufacturer*); + +tANI_U32 dot11fPackTlvManufacturer(tpAniSirGlobal, tDot11fTLVManufacturer*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvManufacturer(tpAniSirGlobal, tDot11fTLVManufacturer*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1 (0x0001) +typedef struct sDot11fTLVMinorReasonCode { + tANI_U8 present; + tANI_U8 minorReasonCode; +} tDot11fTLVMinorReasonCode; + +#define DOT11F_TLV_MINORREASONCODE ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MINORREASONCODE_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MINORREASONCODE_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvMinorReasonCode(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVMinorReasonCode*); + +tANI_U32 dot11fPackTlvMinorReasonCode(tpAniSirGlobal, tDot11fTLVMinorReasonCode*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvMinorReasonCode(tpAniSirGlobal, tDot11fTLVMinorReasonCode*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4131 (0x1023) +typedef struct sDot11fTLVModelName { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVModelName; + +#define DOT11F_TLV_MODELNAME ( 4131 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MODELNAME_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MODELNAME_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvModelName(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVModelName*); + +tANI_U32 dot11fPackTlvModelName(tpAniSirGlobal, tDot11fTLVModelName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvModelName(tpAniSirGlobal, tDot11fTLVModelName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4132 (0x1024) +typedef struct sDot11fTLVModelNumber { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVModelNumber; + +#define DOT11F_TLV_MODELNUMBER ( 4132 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MODELNUMBER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MODELNUMBER_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvModelNumber(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVModelNumber*); + +tANI_U32 dot11fPackTlvModelNumber(tpAniSirGlobal, tDot11fTLVModelNumber*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvModelNumber(tpAniSirGlobal, tDot11fTLVModelNumber*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 12 (0x000c) +typedef struct sDot11fTLVNoticeOfAbsence { + tANI_U8 present; + tANI_U8 index; + tANI_U8 CTSWindowOppPS; + tANI_U8 num_NoADesc; + tANI_U8 NoADesc[36]; +} tDot11fTLVNoticeOfAbsence; + +#define DOT11F_TLV_NOTICEOFABSENCE ( 12 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_NOTICEOFABSENCE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_NOTICEOFABSENCE_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvNoticeOfAbsence(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVNoticeOfAbsence*); + +tANI_U32 dot11fPackTlvNoticeOfAbsence(tpAniSirGlobal, tDot11fTLVNoticeOfAbsence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvNoticeOfAbsence(tpAniSirGlobal, tDot11fTLVNoticeOfAbsence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 17 (0x0011) +typedef struct sDot11fTLVOperatingChannel { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 regulatoryClass; + tANI_U8 channel; +} tDot11fTLVOperatingChannel; + +#define DOT11F_TLV_OPERATINGCHANNEL ( 17 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_OPERATINGCHANNEL_MIN_LEN ( 6 ) + +#define DOT11F_TLV_OPERATINGCHANNEL_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvOperatingChannel(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVOperatingChannel*); + +tANI_U32 dot11fPackTlvOperatingChannel(tpAniSirGlobal, tDot11fTLVOperatingChannel*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvOperatingChannel(tpAniSirGlobal, tDot11fTLVOperatingChannel*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 2 (0x0002) +typedef struct sDot11fTLVP2PCapability { + tANI_U8 present; + tANI_U8 deviceCapability; + tANI_U8 groupCapability; +} tDot11fTLVP2PCapability; + +#define DOT11F_TLV_P2PCAPABILITY ( 2 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PCAPABILITY_MIN_LEN ( 3 ) + +#define DOT11F_TLV_P2PCAPABILITY_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PCapability(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PCapability*); + +tANI_U32 dot11fPackTlvP2PCapability(tpAniSirGlobal, tDot11fTLVP2PCapability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PCapability(tpAniSirGlobal, tDot11fTLVP2PCapability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3 (0x0003) +typedef struct sDot11fTLVP2PDeviceId { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; +} tDot11fTLVP2PDeviceId; + +#define DOT11F_TLV_P2PDEVICEID ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PDEVICEID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PDEVICEID_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PDeviceId(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PDeviceId*); + +tANI_U32 dot11fPackTlvP2PDeviceId(tpAniSirGlobal, tDot11fTLVP2PDeviceId*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PDeviceId(tpAniSirGlobal, tDot11fTLVP2PDeviceId*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 13 (0x000d) +typedef struct sDot11fTLVP2PDeviceInfo { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; + tANI_U16 configMethod; + tANI_U8 primaryDeviceType[8]; + tDot11fTLVDeviceName DeviceName; +} tDot11fTLVP2PDeviceInfo; + +#define DOT11F_TLV_P2PDEVICEINFO ( 13 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PDEVICEINFO_MIN_LEN ( 17 ) + +#define DOT11F_TLV_P2PDEVICEINFO_MAX_LEN ( 53 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PDeviceInfo(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PDeviceInfo*); + +tANI_U32 dot11fPackTlvP2PDeviceInfo(tpAniSirGlobal, tDot11fTLVP2PDeviceInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PDeviceInfo(tpAniSirGlobal, tDot11fTLVP2PDeviceInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 7 (0x0007) +typedef struct sDot11fTLVP2PGroupBssid { + tANI_U8 present; + tANI_U8 P2PGroupBssid[6]; +} tDot11fTLVP2PGroupBssid; + +#define DOT11F_TLV_P2PGROUPBSSID ( 7 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPBSSID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PGROUPBSSID_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupBssid(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupBssid*); + +tANI_U32 dot11fPackTlvP2PGroupBssid(tpAniSirGlobal, tDot11fTLVP2PGroupBssid*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupBssid(tpAniSirGlobal, tDot11fTLVP2PGroupBssid*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 15 (0x000f) +typedef struct sDot11fTLVP2PGroupId { + tANI_U8 present; + tANI_U8 deviceAddress[6]; + tANI_U8 num_ssid; + tANI_U8 ssid[32]; +} tDot11fTLVP2PGroupId; + +#define DOT11F_TLV_P2PGROUPID ( 15 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PGROUPID_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupId(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupId*); + +tANI_U32 dot11fPackTlvP2PGroupId(tpAniSirGlobal, tDot11fTLVP2PGroupId*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupId(tpAniSirGlobal, tDot11fTLVP2PGroupId*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 14 (0x000e) +typedef struct sDot11fTLVP2PGroupInfo { + tANI_U8 present; + tANI_U8 num_P2PClientInfoDesc; + tANI_U8 P2PClientInfoDesc[1024]; +} tDot11fTLVP2PGroupInfo; + +#define DOT11F_TLV_P2PGROUPINFO ( 14 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPINFO_MIN_LEN ( 1 ) + +#define DOT11F_TLV_P2PGROUPINFO_MAX_LEN ( 1025 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupInfo(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupInfo*); + +tANI_U32 dot11fPackTlvP2PGroupInfo(tpAniSirGlobal, tDot11fTLVP2PGroupInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupInfo(tpAniSirGlobal, tDot11fTLVP2PGroupInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 0 (0x0000) +typedef struct sDot11fTLVP2PStatus { + tANI_U8 present; + tANI_U8 status; +} tDot11fTLVP2PStatus; + +#define DOT11F_TLV_P2PSTATUS ( 0 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PSTATUS_MIN_LEN ( 2 ) + +#define DOT11F_TLV_P2PSTATUS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PStatus(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PStatus*); + +tANI_U32 dot11fPackTlvP2PStatus(tpAniSirGlobal, tDot11fTLVP2PStatus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PStatus(tpAniSirGlobal, tDot11fTLVP2PStatus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4180 (0x1054) +typedef struct sDot11fTLVPrimaryDeviceType { + tANI_U8 present; + tANI_U16 primary_category; + tANI_U8 oui[4]; + tANI_U16 sub_category; +} tDot11fTLVPrimaryDeviceType; + +#define DOT11F_TLV_PRIMARYDEVICETYPE ( 4180 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_PRIMARYDEVICETYPE_MIN_LEN ( 10 ) + +#define DOT11F_TLV_PRIMARYDEVICETYPE_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvPrimaryDeviceType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVPrimaryDeviceType*); + +tANI_U32 dot11fPackTlvPrimaryDeviceType(tpAniSirGlobal, tDot11fTLVPrimaryDeviceType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvPrimaryDeviceType(tpAniSirGlobal, tDot11fTLVPrimaryDeviceType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4156 (0x103c) +typedef struct sDot11fTLVRFBands { + tANI_U8 present; + tANI_U8 bands; +} tDot11fTLVRFBands; + +#define DOT11F_TLV_RFBANDS ( 4156 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_RFBANDS_MIN_LEN ( 3 ) + +#define DOT11F_TLV_RFBANDS_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRFBands(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRFBands*); + +tANI_U32 dot11fPackTlvRFBands(tpAniSirGlobal, tDot11fTLVRFBands*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRFBands(tpAniSirGlobal, tDot11fTLVRFBands*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4202 (0x106a) +typedef struct sDot11fTLVRequestDeviceType { + tANI_U8 present; + tANI_U16 primary_category; + tANI_U8 oui[4]; + tANI_U16 sub_category; +} tDot11fTLVRequestDeviceType; + +#define DOT11F_TLV_REQUESTDEVICETYPE ( 4202 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTDEVICETYPE_MIN_LEN ( 10 ) + +#define DOT11F_TLV_REQUESTDEVICETYPE_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestDeviceType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestDeviceType*); + +tANI_U32 dot11fPackTlvRequestDeviceType(tpAniSirGlobal, tDot11fTLVRequestDeviceType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestDeviceType(tpAniSirGlobal, tDot11fTLVRequestDeviceType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4154 (0x103a) +typedef struct sDot11fTLVRequestType { + tANI_U8 present; + tANI_U8 reqType; +} tDot11fTLVRequestType; + +#define DOT11F_TLV_REQUESTTYPE ( 4154 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTTYPE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_REQUESTTYPE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestType*); + +tANI_U32 dot11fPackTlvRequestType(tpAniSirGlobal, tDot11fTLVRequestType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestType(tpAniSirGlobal, tDot11fTLVRequestType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4155 (0x103b) +typedef struct sDot11fTLVResponseType { + tANI_U8 present; + tANI_U8 resType; +} tDot11fTLVResponseType; + +#define DOT11F_TLV_RESPONSETYPE ( 4155 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_RESPONSETYPE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_RESPONSETYPE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvResponseType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVResponseType*); + +tANI_U32 dot11fPackTlvResponseType(tpAniSirGlobal, tDot11fTLVResponseType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvResponseType(tpAniSirGlobal, tDot11fTLVResponseType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4161 (0x1041) +typedef struct sDot11fTLVSelectedRegistrar { + tANI_U8 present; + tANI_U8 selected; +} tDot11fTLVSelectedRegistrar; + +#define DOT11F_TLV_SELECTEDREGISTRAR ( 4161 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SELECTEDREGISTRAR_MIN_LEN ( 3 ) + +#define DOT11F_TLV_SELECTEDREGISTRAR_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSelectedRegistrar(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSelectedRegistrar*); + +tANI_U32 dot11fPackTlvSelectedRegistrar(tpAniSirGlobal, tDot11fTLVSelectedRegistrar*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSelectedRegistrar(tpAniSirGlobal, tDot11fTLVSelectedRegistrar*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4179 (0x1053) +typedef struct sDot11fTLVSelectedRegistrarConfigMethods { + tANI_U8 present; + tANI_U16 methods; +} tDot11fTLVSelectedRegistrarConfigMethods; + +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS ( 4179 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MIN_LEN ( 4 ) + +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSelectedRegistrarConfigMethods*); + +tANI_U32 dot11fPackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tDot11fTLVSelectedRegistrarConfigMethods*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tDot11fTLVSelectedRegistrarConfigMethods*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4162 (0x1042) +typedef struct sDot11fTLVSerialNumber { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVSerialNumber; + +#define DOT11F_TLV_SERIALNUMBER ( 4162 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SERIALNUMBER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_SERIALNUMBER_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSerialNumber(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSerialNumber*); + +tANI_U32 dot11fPackTlvSerialNumber(tpAniSirGlobal, tDot11fTLVSerialNumber*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSerialNumber(tpAniSirGlobal, tDot11fTLVSerialNumber*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4167 (0x1047) +typedef struct sDot11fTLVUUID_E { + tANI_U8 present; + tANI_U8 uuid[16]; +} tDot11fTLVUUID_E; + +#define DOT11F_TLV_UUID_E ( 4167 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_UUID_E_MIN_LEN ( 18 ) + +#define DOT11F_TLV_UUID_E_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvUUID_E(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVUUID_E*); + +tANI_U32 dot11fPackTlvUUID_E(tpAniSirGlobal, tDot11fTLVUUID_E*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvUUID_E(tpAniSirGlobal, tDot11fTLVUUID_E*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4168 (0x1048) +typedef struct sDot11fTLVUUID_R { + tANI_U8 present; + tANI_U8 uuid[16]; +} tDot11fTLVUUID_R; + +#define DOT11F_TLV_UUID_R ( 4168 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_UUID_R_MIN_LEN ( 18 ) + +#define DOT11F_TLV_UUID_R_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvUUID_R(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVUUID_R*); + +tANI_U32 dot11fPackTlvUUID_R(tpAniSirGlobal, tDot11fTLVUUID_R*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvUUID_R(tpAniSirGlobal, tDot11fTLVUUID_R*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4169 (0x1049) +typedef struct sDot11fTLVVendorExtension { + tANI_U8 present; + tANI_U8 vendorId[3]; + tDot11fTLVVersion2 Version2; + tDot11fTLVAuthorizedMACs AuthorizedMACs; + tDot11fTLVRequestToEnroll RequestToEnroll; +} tDot11fTLVVendorExtension; + +#define DOT11F_TLV_VENDOREXTENSION ( 4169 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VENDOREXTENSION_MIN_LEN ( 5 ) + +#define DOT11F_TLV_VENDOREXTENSION_MAX_LEN ( 19 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVendorExtension(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVendorExtension*); + +tANI_U32 dot11fPackTlvVendorExtension(tpAniSirGlobal, tDot11fTLVVendorExtension*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVendorExtension(tpAniSirGlobal, tDot11fTLVVendorExtension*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4170 (0x104a) +typedef struct sDot11fTLVVersion { + tANI_U8 present; + tANI_U8 minor: 4; + tANI_U8 major: 4; +} tDot11fTLVVersion; + +#define DOT11F_TLV_VERSION ( 4170 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VERSION_MIN_LEN ( 3 ) + +#define DOT11F_TLV_VERSION_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVersion(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVersion*); + +tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal, tDot11fTLVVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVersion(tpAniSirGlobal, tDot11fTLVVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4164 (0x1044) +typedef struct sDot11fTLVWPSState { + tANI_U8 present; + tANI_U8 state; +} tDot11fTLVWPSState; + +#define DOT11F_TLV_WPSSTATE ( 4164 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_WPSSTATE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_WPSSTATE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvWPSState(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVWPSState*); + +tANI_U32 dot11fPackTlvWPSState(tpAniSirGlobal, tDot11fTLVWPSState*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvWPSState(tpAniSirGlobal, tDot11fTLVWPSState*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 16 (0x0010) +typedef struct sDot11fTLVP2PInterface { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; +} tDot11fTLVP2PInterface; + +#define DOT11F_TLV_P2PINTERFACE ( 16 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PINTERFACE_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PINTERFACE_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PInterface(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PInterface*); + +tANI_U32 dot11fPackTlvP2PInterface(tpAniSirGlobal, tDot11fTLVP2PInterface*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PInterface(tpAniSirGlobal, tDot11fTLVP2PInterface*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 10 (0x000a) +typedef struct sDot11fTLVP2PManageability { + tANI_U8 present; + tANI_U8 manageability; +} tDot11fTLVP2PManageability; + +#define DOT11F_TLV_P2PMANAGEABILITY ( 10 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PMANAGEABILITY_MIN_LEN ( 2 ) + +#define DOT11F_TLV_P2PMANAGEABILITY_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PManageability(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PManageability*); + +tANI_U32 dot11fPackTlvP2PManageability(tpAniSirGlobal, tDot11fTLVP2PManageability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PManageability(tpAniSirGlobal, tDot11fTLVP2PManageability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +/********************************************************************* + * Information Elements * + ********************************************************************/ + +// EID 1 (0x01) +typedef struct sDot11fIEAPName { + tANI_U8 present; + tANI_U8 num_name; + tANI_U8 name[32]; +} tDot11fIEAPName; + +#define DOT11F_EID_APNAME ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_APNAME_MIN_LEN ( 1 ) + +#define DOT11F_IE_APNAME_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAPName(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAPName*); + +tANI_U32 dot11fPackIeAPName(tpAniSirGlobal, tDot11fIEAPName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAPName(tpAniSirGlobal, tDot11fIEAPName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIEBPIndicator { + tANI_U8 present; + tANI_U8 indicator; + tANI_U8 type; +} tDot11fIEBPIndicator; + +#define DOT11F_EID_BPINDICATOR ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BPINDICATOR_MIN_LEN ( 2 ) + +#define DOT11F_IE_BPINDICATOR_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBPIndicator(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBPIndicator*); + +tANI_U32 dot11fPackIeBPIndicator(tpAniSirGlobal, tDot11fIEBPIndicator*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBPIndicator(tpAniSirGlobal, tDot11fIEBPIndicator*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIECondensedCountryStr { + tANI_U8 present; + tANI_U8 countryStr[2]; +} tDot11fIECondensedCountryStr; + +#define DOT11F_EID_CONDENSEDCOUNTRYSTR ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MIN_LEN ( 2 ) + +#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCondensedCountryStr(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECondensedCountryStr*); + +tANI_U32 dot11fPackIeCondensedCountryStr(tpAniSirGlobal, tDot11fIECondensedCountryStr*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECondensedCountryStr(tpAniSirGlobal, tDot11fIECondensedCountryStr*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEGTK { + tANI_U8 present; + tANI_U16 keyId: 2; + tANI_U16 reserved: 14; + tANI_U8 keyLength; + tANI_U8 RSC[8]; + tANI_U8 num_key; + tANI_U8 key[32]; +} tDot11fIEGTK; + +#define DOT11F_EID_GTK ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_GTK_MIN_LEN ( 16 ) + +#define DOT11F_IE_GTK_MAX_LEN ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeGTK(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEGTK*); + +tANI_U32 dot11fPackIeGTK(tpAniSirGlobal, tDot11fIEGTK*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEGTK(tpAniSirGlobal, tDot11fIEGTK*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEHCF { + tANI_U8 present; + tANI_U8 enabled; +} tDot11fIEHCF; + +#define DOT11F_EID_HCF ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HCF_MIN_LEN ( 1 ) + +#define DOT11F_IE_HCF_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHCF(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHCF*); + +tANI_U32 dot11fPackIeHCF(tpAniSirGlobal, tDot11fIEHCF*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHCF(tpAniSirGlobal, tDot11fIEHCF*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIEIGTK { + tANI_U8 present; + tANI_U8 keyID[2]; + tANI_U8 IPN[6]; + tANI_U8 keyLength; + tANI_U8 key[24]; +} tDot11fIEIGTK; + +#define DOT11F_EID_IGTK ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_IGTK_MIN_LEN ( 33 ) + +#define DOT11F_IE_IGTK_MAX_LEN ( 33 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeIGTK(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEIGTK*); + +tANI_U32 dot11fPackIeIGTK(tpAniSirGlobal, tDot11fIEIGTK*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEIGTK(tpAniSirGlobal, tDot11fIEIGTK*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 9 (0x09) +typedef struct sDot11fIELLAttr { + tANI_U8 present; + tANI_U32 defer_threshold; +} tDot11fIELLAttr; + +#define DOT11F_EID_LLATTR ( 9 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LLATTR_MIN_LEN ( 4 ) + +#define DOT11F_IE_LLATTR_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLLAttr(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELLAttr*); + +tANI_U32 dot11fPackIeLLAttr(tpAniSirGlobal, tDot11fIELLAttr*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELLAttr(tpAniSirGlobal, tDot11fIELLAttr*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 8 (0x08) +typedef struct sDot11fIELoadBalance { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 channel; +} tDot11fIELoadBalance; + +#define DOT11F_EID_LOADBALANCE ( 8 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LOADBALANCE_MIN_LEN ( 7 ) + +#define DOT11F_IE_LOADBALANCE_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLoadBalance(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELoadBalance*); + +tANI_U32 dot11fPackIeLoadBalance(tpAniSirGlobal, tDot11fIELoadBalance*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELoadBalance(tpAniSirGlobal, tDot11fIELoadBalance*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 6 (0x06) +typedef struct sDot11fIELoadInfo { + tANI_U8 present; + tANI_U16 num_stas; + tANI_U16 channel_util; +} tDot11fIELoadInfo; + +#define DOT11F_EID_LOADINFO ( 6 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LOADINFO_MIN_LEN ( 4 ) + +#define DOT11F_IE_LOADINFO_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLoadInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELoadInfo*); + +tANI_U32 dot11fPackIeLoadInfo(tpAniSirGlobal, tDot11fIELoadInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELoadInfo(tpAniSirGlobal, tDot11fIELoadInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 7 (0x07) +typedef struct sDot11fIEPropAssocType { + tANI_U8 present; + tANI_U8 type; +} tDot11fIEPropAssocType; + +#define DOT11F_EID_PROPASSOCTYPE ( 7 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPASSOCTYPE_MIN_LEN ( 1 ) + +#define DOT11F_IE_PROPASSOCTYPE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropAssocType(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropAssocType*); + +tANI_U32 dot11fPackIePropAssocType(tpAniSirGlobal, tDot11fIEPropAssocType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropAssocType(tpAniSirGlobal, tDot11fIEPropAssocType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 10 (0x0a) +typedef struct sDot11fIEPropCapability { + tANI_U8 present; + tANI_U16 capability; +} tDot11fIEPropCapability; + +#define DOT11F_EID_PROPCAPABILITY ( 10 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPCAPABILITY_MIN_LEN ( 2 ) + +#define DOT11F_IE_PROPCAPABILITY_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropCapability(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropCapability*); + +tANI_U32 dot11fPackIePropCapability(tpAniSirGlobal, tDot11fIEPropCapability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropCapability(tpAniSirGlobal, tDot11fIEPropCapability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 15 (0x0f) +typedef struct sDot11fIEPropChannSwitchAnn { + tANI_U8 present; + tANI_U8 mode; + tANI_U8 primary_channel; + tANI_U8 sub_band; + tANI_U8 channel_switch_count; +} tDot11fIEPropChannSwitchAnn; + +#define DOT11F_EID_PROPCHANNSWITCHANN ( 15 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPCHANNSWITCHANN_MIN_LEN ( 4 ) + +#define DOT11F_IE_PROPCHANNSWITCHANN_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropChannSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropChannSwitchAnn*); + +tANI_U32 dot11fPackIePropChannSwitchAnn(tpAniSirGlobal, tDot11fIEPropChannSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropChannSwitchAnn(tpAniSirGlobal, tDot11fIEPropChannSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 12 (0x0c) +typedef struct sDot11fIEPropEDCAParams { + tANI_U8 present; + tANI_U8 qos; + tANI_U8 reserved; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_min: 4; + tANI_U8 acbe_max: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_min: 4; + tANI_U8 acbk_max: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_min: 4; + tANI_U8 acvi_max: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_min: 4; + tANI_U8 acvo_max: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEPropEDCAParams; + +#define DOT11F_EID_PROPEDCAPARAMS ( 12 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPEDCAPARAMS_MIN_LEN ( 18 ) + +#define DOT11F_IE_PROPEDCAPARAMS_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropEDCAParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropEDCAParams*); + +tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal, tDot11fIEPropEDCAParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropEDCAParams(tpAniSirGlobal, tDot11fIEPropEDCAParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 16 (0x10) +typedef struct sDot11fIEPropQuietBSS { + tANI_U8 present; + tANI_U8 quiet_count; + tANI_U8 quiet_period; + tANI_U16 quiet_duration; + tANI_U16 quiet_offset; +} tDot11fIEPropQuietBSS; + +#define DOT11F_EID_PROPQUIETBSS ( 16 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPQUIETBSS_MIN_LEN ( 6 ) + +#define DOT11F_IE_PROPQUIETBSS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropQuietBSS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropQuietBSS*); + +tANI_U32 dot11fPackIePropQuietBSS(tpAniSirGlobal, tDot11fIEPropQuietBSS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropQuietBSS(tpAniSirGlobal, tDot11fIEPropQuietBSS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 0 (0x00) +typedef struct sDot11fIEPropSuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIEPropSuppRates; + +#define DOT11F_EID_PROPSUPPRATES ( 0 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPSUPPRATES_MIN_LEN ( 1 ) + +#define DOT11F_IE_PROPSUPPRATES_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropSuppRates*); + +tANI_U32 dot11fPackIePropSuppRates(tpAniSirGlobal, tDot11fIEPropSuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropSuppRates(tpAniSirGlobal, tDot11fIEPropSuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIER0KH_ID { + tANI_U8 present; + tANI_U8 num_PMK_R0_ID; + tANI_U8 PMK_R0_ID[48]; +} tDot11fIER0KH_ID; + +#define DOT11F_EID_R0KH_ID ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_R0KH_ID_MIN_LEN ( 1 ) + +#define DOT11F_IE_R0KH_ID_MAX_LEN ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeR0KH_ID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIER0KH_ID*); + +tANI_U32 dot11fPackIeR0KH_ID(tpAniSirGlobal, tDot11fIER0KH_ID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIER0KH_ID(tpAniSirGlobal, tDot11fIER0KH_ID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIER1KH_ID { + tANI_U8 present; + tANI_U8 PMK_R1_ID[6]; +} tDot11fIER1KH_ID; + +#define DOT11F_EID_R1KH_ID ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_R1KH_ID_MIN_LEN ( 6 ) + +#define DOT11F_IE_R1KH_ID_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeR1KH_ID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIER1KH_ID*); + +tANI_U32 dot11fPackIeR1KH_ID(tpAniSirGlobal, tDot11fIER1KH_ID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIER1KH_ID(tpAniSirGlobal, tDot11fIER1KH_ID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIETSFInfo { + tANI_U8 present; + tANI_U16 TsfOffset; + tANI_U16 BeaconIntvl; +} tDot11fIETSFInfo; + +#define DOT11F_EID_TSFINFO ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSFINFO_MIN_LEN ( 4 ) + +#define DOT11F_IE_TSFINFO_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSFInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSFInfo*); + +tANI_U32 dot11fPackIeTSFInfo(tpAniSirGlobal, tDot11fIETSFInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSFInfo(tpAniSirGlobal, tDot11fIETSFInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 18 (0x12) +typedef struct sDot11fIETaurus { + tANI_U8 present; + tANI_U16 baTIDBitmap; + tANI_U16 baPolicy; + tANI_U16 baBufferSize: 12; + tANI_U16 rsvd: 4; +} tDot11fIETaurus; + +#define DOT11F_EID_TAURUS ( 18 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TAURUS_MIN_LEN ( 6 ) + +#define DOT11F_IE_TAURUS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTaurus(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETaurus*); + +tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal, tDot11fIETaurus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETaurus(tpAniSirGlobal, tDot11fIETaurus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 14 (0x0e) +typedef struct sDot11fIETitan { + tANI_U8 present; + tANI_U8 concat_tcid_bitmap; + tANI_U8 compression_tcid_bitmap; + tANI_U8 cb_state; + tANI_U8 rev_fcs_state; +} tDot11fIETitan; + +#define DOT11F_EID_TITAN ( 14 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TITAN_MIN_LEN ( 4 ) + +#define DOT11F_IE_TITAN_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTitan(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETitan*); + +tANI_U32 dot11fPackIeTitan(tpAniSirGlobal, tDot11fIETitan*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETitan(tpAniSirGlobal, tDot11fIETitan*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 17 (0x11) +typedef struct sDot11fIETriggerStaBgScan { + tANI_U8 present; + tANI_U8 enable; +} tDot11fIETriggerStaBgScan; + +#define DOT11F_EID_TRIGGERSTABGSCAN ( 17 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TRIGGERSTABGSCAN_MIN_LEN ( 1 ) + +#define DOT11F_IE_TRIGGERSTABGSCAN_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTriggerStaBgScan(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETriggerStaBgScan*); + +tANI_U32 dot11fPackIeTriggerStaBgScan(tpAniSirGlobal, tDot11fIETriggerStaBgScan*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETriggerStaBgScan(tpAniSirGlobal, tDot11fIETriggerStaBgScan*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 11 (0x0b) +typedef struct sDot11fIEVersion { + tANI_U8 present; + tANI_U32 chip_rev; + tANI_U8 card_type; + tANI_U8 num_build_version; + tANI_U8 build_version[20]; +} tDot11fIEVersion; + +#define DOT11F_EID_VERSION ( 11 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VERSION_MIN_LEN ( 5 ) + +#define DOT11F_IE_VERSION_MAX_LEN ( 25 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVersion(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVersion*); + +tANI_U32 dot11fPackIeVersion(tpAniSirGlobal, tDot11fIEVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVersion(tpAniSirGlobal, tDot11fIEVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIEWDS { + tANI_U8 present; + tANI_U8 num_wdsData; + tANI_U8 wdsData[64]; +} tDot11fIEWDS; + +#define DOT11F_EID_WDS ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WDS_MIN_LEN ( 0 ) + +#define DOT11F_IE_WDS_MAX_LEN ( 64 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWDS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWDS*); + +tANI_U32 dot11fPackIeWDS(tpAniSirGlobal, tDot11fIEWDS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWDS(tpAniSirGlobal, tDot11fIEWDS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 51 (0x33) +typedef struct sDot11fIEAPChannelReport { + tANI_U8 present; + tANI_U8 regulatoryClass; + tANI_U8 num_channelList; + tANI_U8 channelList[50]; +} tDot11fIEAPChannelReport; + +#define DOT11F_EID_APCHANNELREPORT ( 51 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_APCHANNELREPORT_MIN_LEN ( 1 ) + +#define DOT11F_IE_APCHANNELREPORT_MAX_LEN ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAPChannelReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAPChannelReport*); + +tANI_U32 dot11fPackIeAPChannelReport(tpAniSirGlobal, tDot11fIEAPChannelReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAPChannelReport(tpAniSirGlobal, tDot11fIEAPChannelReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEBcnReportingDetail { + tANI_U8 present; + tANI_U8 reportingDetail; +} tDot11fIEBcnReportingDetail; + +#define DOT11F_EID_BCNREPORTINGDETAIL ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BCNREPORTINGDETAIL_MIN_LEN ( 1 ) + +#define DOT11F_IE_BCNREPORTINGDETAIL_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBcnReportingDetail(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBcnReportingDetail*); + +tANI_U32 dot11fPackIeBcnReportingDetail(tpAniSirGlobal, tDot11fIEBcnReportingDetail*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBcnReportingDetail(tpAniSirGlobal, tDot11fIEBcnReportingDetail*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIEBeaconReportFrmBody { + tANI_U8 present; + tANI_U8 num_reportedFields; + tANI_U8 reportedFields[224]; +} tDot11fIEBeaconReportFrmBody; + +#define DOT11F_EID_BEACONREPORTFRMBODY ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BEACONREPORTFRMBODY_MIN_LEN ( 0 ) + +#define DOT11F_IE_BEACONREPORTFRMBODY_MAX_LEN ( 224 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBeaconReportFrmBody(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBeaconReportFrmBody*); + +tANI_U32 dot11fPackIeBeaconReportFrmBody(tpAniSirGlobal, tDot11fIEBeaconReportFrmBody*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBeaconReportFrmBody(tpAniSirGlobal, tDot11fIEBeaconReportFrmBody*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIEBeaconReporting { + tANI_U8 present; + tANI_U8 reportingCondition; + tANI_U8 threshold; +} tDot11fIEBeaconReporting; + +#define DOT11F_EID_BEACONREPORTING ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BEACONREPORTING_MIN_LEN ( 2 ) + +#define DOT11F_IE_BEACONREPORTING_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBeaconReporting(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBeaconReporting*); + +tANI_U32 dot11fPackIeBeaconReporting(tpAniSirGlobal, tDot11fIEBeaconReporting*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBeaconReporting(tpAniSirGlobal, tDot11fIEBeaconReporting*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 66 (0x42) +typedef struct sDot11fIEMeasurementPilot { + tANI_U8 present; + tANI_U8 measurementPilot; + tANI_U8 num_vendorSpecific; + tANI_U8 vendorSpecific[255]; +} tDot11fIEMeasurementPilot; + +#define DOT11F_EID_MEASUREMENTPILOT ( 66 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTPILOT_MIN_LEN ( 1 ) + +#define DOT11F_IE_MEASUREMENTPILOT_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementPilot(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementPilot*); + +tANI_U32 dot11fPackIeMeasurementPilot(tpAniSirGlobal, tDot11fIEMeasurementPilot*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementPilot(tpAniSirGlobal, tDot11fIEMeasurementPilot*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 71 (0x47) +typedef struct sDot11fIEMultiBssid { + tANI_U8 present; + tANI_U8 maxBSSIDIndicator; + tANI_U8 num_vendorSpecific; + tANI_U8 vendorSpecific[255]; +} tDot11fIEMultiBssid; + +#define DOT11F_EID_MULTIBSSID ( 71 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MULTIBSSID_MIN_LEN ( 1 ) + +#define DOT11F_IE_MULTIBSSID_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMultiBssid(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMultiBssid*); + +tANI_U32 dot11fPackIeMultiBssid(tpAniSirGlobal, tDot11fIEMultiBssid*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMultiBssid(tpAniSirGlobal, tDot11fIEMultiBssid*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 57 (0x39) +typedef struct sDot11fIERICData { + tANI_U8 present; + tANI_U8 Identifier; + tANI_U8 resourceDescCount; + tANI_U16 statusCode; +} tDot11fIERICData; + +#define DOT11F_EID_RICDATA ( 57 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDATA_MIN_LEN ( 4 ) + +#define DOT11F_IE_RICDATA_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICData(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICData*); + +tANI_U32 dot11fPackIeRICData(tpAniSirGlobal, tDot11fIERICData*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICData(tpAniSirGlobal, tDot11fIERICData*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 75 (0x4b) +typedef struct sDot11fIERICDescriptor { + tANI_U8 present; + tANI_U8 resourceType; + tANI_U8 num_variableData; + tANI_U8 variableData[255]; +} tDot11fIERICDescriptor; + +#define DOT11F_EID_RICDESCRIPTOR ( 75 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDESCRIPTOR_MIN_LEN ( 1 ) + +#define DOT11F_IE_RICDESCRIPTOR_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICDescriptor(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICDescriptor*); + +tANI_U32 dot11fPackIeRICDescriptor(tpAniSirGlobal, tDot11fIERICDescriptor*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICDescriptor(tpAniSirGlobal, tDot11fIERICDescriptor*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 70 (0x46) +typedef struct sDot11fIERRMEnabledCap { + tANI_U8 present; + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 operatingChanMax: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 MeasurementPilot: 3; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + tANI_U8 reserved: 6; +} tDot11fIERRMEnabledCap; + +#define DOT11F_EID_RRMENABLEDCAP ( 70 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RRMENABLEDCAP_MIN_LEN ( 5 ) + +#define DOT11F_IE_RRMENABLEDCAP_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERRMEnabledCap*); + +tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal, tDot11fIERRMEnabledCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERRMEnabledCap(tpAniSirGlobal, tDot11fIERRMEnabledCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 10 (0x0a) +typedef struct sDot11fIERequestedInfo { + tANI_U8 present; + tANI_U8 num_requested_eids; + tANI_U8 requested_eids[255]; +} tDot11fIERequestedInfo; + +#define DOT11F_EID_REQUESTEDINFO ( 10 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_REQUESTEDINFO_MIN_LEN ( 0 ) + +#define DOT11F_IE_REQUESTEDINFO_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRequestedInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERequestedInfo*); + +tANI_U32 dot11fPackIeRequestedInfo(tpAniSirGlobal, tDot11fIERequestedInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERequestedInfo(tpAniSirGlobal, tDot11fIERequestedInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 0 (0x00) +typedef struct sDot11fIESSID { + tANI_U8 present; + tANI_U8 num_ssid; + tANI_U8 ssid[32]; +} tDot11fIESSID; + +#define DOT11F_EID_SSID ( 0 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SSID_MIN_LEN ( 0 ) + +#define DOT11F_IE_SSID_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSSID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESSID*); + +tANI_U32 dot11fPackIeSSID(tpAniSirGlobal, tDot11fIESSID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESSID(tpAniSirGlobal, tDot11fIESSID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 15 (0x0f) +typedef struct sDot11fIESchedule { + tANI_U8 present; + tANI_U16 aggregation: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 reserved: 9; + tANI_U32 service_start_time; + tANI_U32 service_interval; + tANI_U16 max_service_dur; + tANI_U16 spec_interval; +} tDot11fIESchedule; + +#define DOT11F_EID_SCHEDULE ( 15 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SCHEDULE_MIN_LEN ( 14 ) + +#define DOT11F_IE_SCHEDULE_MAX_LEN ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESchedule*); + +tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal, tDot11fIESchedule*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESchedule(tpAniSirGlobal, tDot11fIESchedule*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 14 (0x0e) +typedef struct sDot11fIETCLAS { + tANI_U8 present; + tANI_U8 user_priority; + tANI_U8 classifier_type; + tANI_U8 classifier_mask; + union + { + struct + { + tANI_U8 source[6]; + tANI_U8 dest[6]; + tANI_U16 type; + } EthParams; /* classifier_type = 0 */ + struct + { + tANI_U8 version; + union + { + struct + { + tANI_U8 source[4]; + tANI_U8 dest[4]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 DSCP; + tANI_U8 proto; + tANI_U8 reserved; + } IpV4Params; /* version = 4 */ + struct + { + tANI_U8 source[16]; + tANI_U8 dest[16]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 flow_label[3]; + } IpV6Params; /* version = 6 */ + } params; + } IpParams; /* classifier_type = 1 */ + struct + { + tANI_U16 tag_type; + } Params8021dq; /* classifier_type = 2 */ + } info; +} tDot11fIETCLAS; + +#define DOT11F_EID_TCLAS ( 14 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TCLAS_MIN_LEN ( 5 ) + +#define DOT11F_IE_TCLAS_MAX_LEN ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETCLAS*); + +tANI_U32 dot11fPackIeTCLAS(tpAniSirGlobal, tDot11fIETCLAS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETCLAS(tpAniSirGlobal, tDot11fIETCLAS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 44 (0x2c) +typedef struct sDot11fIETCLASSPROC { + tANI_U8 present; + tANI_U8 processing; +} tDot11fIETCLASSPROC; + +#define DOT11F_EID_TCLASSPROC ( 44 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TCLASSPROC_MIN_LEN ( 1 ) + +#define DOT11F_IE_TCLASSPROC_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTCLASSPROC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETCLASSPROC*); + +tANI_U32 dot11fPackIeTCLASSPROC(tpAniSirGlobal, tDot11fIETCLASSPROC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETCLASSPROC(tpAniSirGlobal, tDot11fIETCLASSPROC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 43 (0x2b) +typedef struct sDot11fIETSDelay { + tANI_U8 present; + tANI_U32 delay; +} tDot11fIETSDelay; + +#define DOT11F_EID_TSDELAY ( 43 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSDELAY_MIN_LEN ( 4 ) + +#define DOT11F_IE_TSDELAY_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSDelay(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSDelay*); + +tANI_U32 dot11fPackIeTSDelay(tpAniSirGlobal, tDot11fIETSDelay*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSDelay(tpAniSirGlobal, tDot11fIETSDelay*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 13 (0x0d) +typedef struct sDot11fIETSPEC { + tANI_U8 present; + tANI_U16 traffic_type: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 access_policy: 2; + tANI_U16 aggregation: 1; + tANI_U16 psb: 1; + tANI_U16 user_priority: 3; + tANI_U16 tsinfo_ack_pol: 2; + tANI_U8 schedule: 1; + tANI_U8 unused: 7; + tANI_U16 size: 15; + tANI_U16 fixed: 1; + tANI_U16 max_msdu_size; + tANI_U32 min_service_int; + tANI_U32 max_service_int; + tANI_U32 inactivity_int; + tANI_U32 suspension_int; + tANI_U32 service_start_time; + tANI_U32 min_data_rate; + tANI_U32 mean_data_rate; + tANI_U32 peak_data_rate; + tANI_U32 burst_size; + tANI_U32 delay_bound; + tANI_U32 min_phy_rate; + tANI_U16 surplus_bw_allowance; + tANI_U16 medium_time; +} tDot11fIETSPEC; + +#define DOT11F_EID_TSPEC ( 13 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSPEC_MIN_LEN ( 55 ) + +#define DOT11F_IE_TSPEC_MAX_LEN ( 55 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSPEC*); + +tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal, tDot11fIETSPEC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSPEC(tpAniSirGlobal, tDot11fIETSPEC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x09} +typedef struct sDot11fIEWMMSchedule { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U16 aggregation: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 reserved: 9; + tANI_U32 service_start_time; + tANI_U32 service_interval; + tANI_U16 max_service_dur; + tANI_U16 spec_interval; +} tDot11fIEWMMSchedule; + +#define DOT11F_EID_WMMSCHEDULE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMSCHEDULE_MIN_LEN ( 20 ) + +#define DOT11F_IE_WMMSCHEDULE_MAX_LEN ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMSchedule*); + +tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal, tDot11fIEWMMSchedule*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMSchedule(tpAniSirGlobal, tDot11fIEWMMSchedule*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x06} +typedef struct sDot11fIEWMMTCLAS { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 user_priority; + tANI_U8 classifier_type; + tANI_U8 classifier_mask; + union + { + struct + { + tANI_U8 source[6]; + tANI_U8 dest[6]; + tANI_U16 type; + } EthParams; /* classifier_type = 0 */ + struct + { + tANI_U8 version; + union + { + struct + { + tANI_U8 source[4]; + tANI_U8 dest[4]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 DSCP; + tANI_U8 proto; + tANI_U8 reserved; + } IpV4Params; /* version = 4 */ + struct + { + tANI_U8 source[16]; + tANI_U8 dest[16]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 flow_label[3]; + } IpV6Params; /* version = 6 */ + } params; + } IpParams; /* classifier_type = 1 */ + struct + { + tANI_U16 tag_type; + } Params8021dq; /* classifier_type = 2 */ + } info; +} tDot11fIEWMMTCLAS; + +#define DOT11F_EID_WMMTCLAS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTCLAS_MIN_LEN ( 11 ) + +#define DOT11F_IE_WMMTCLAS_MAX_LEN ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTCLAS*); + +tANI_U32 dot11fPackIeWMMTCLAS(tpAniSirGlobal, tDot11fIEWMMTCLAS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTCLAS(tpAniSirGlobal, tDot11fIEWMMTCLAS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x07} +typedef struct sDot11fIEWMMTCLASPROC { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 processing; +} tDot11fIEWMMTCLASPROC; + +#define DOT11F_EID_WMMTCLASPROC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTCLASPROC_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMTCLASPROC_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTCLASPROC*); + +tANI_U32 dot11fPackIeWMMTCLASPROC(tpAniSirGlobal, tDot11fIEWMMTCLASPROC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTCLASPROC(tpAniSirGlobal, tDot11fIEWMMTCLASPROC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x08} +typedef struct sDot11fIEWMMTSDelay { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U32 delay; +} tDot11fIEWMMTSDelay; + +#define DOT11F_EID_WMMTSDELAY ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTSDELAY_MIN_LEN ( 10 ) + +#define DOT11F_IE_WMMTSDELAY_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTSDelay*); + +tANI_U32 dot11fPackIeWMMTSDelay(tpAniSirGlobal, tDot11fIEWMMTSDelay*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTSDelay(tpAniSirGlobal, tDot11fIEWMMTSDelay*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x02} +typedef struct sDot11fIEWMMTSPEC { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U16 traffic_type: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 access_policy: 2; + tANI_U16 aggregation: 1; + tANI_U16 psb: 1; + tANI_U16 user_priority: 3; + tANI_U16 tsinfo_ack_pol: 2; + tANI_U8 tsinfo_rsvd: 7; + tANI_U8 burst_size_defn: 1; + tANI_U16 size: 15; + tANI_U16 fixed: 1; + tANI_U16 max_msdu_size; + tANI_U32 min_service_int; + tANI_U32 max_service_int; + tANI_U32 inactivity_int; + tANI_U32 suspension_int; + tANI_U32 service_start_time; + tANI_U32 min_data_rate; + tANI_U32 mean_data_rate; + tANI_U32 peak_data_rate; + tANI_U32 burst_size; + tANI_U32 delay_bound; + tANI_U32 min_phy_rate; + tANI_U16 surplus_bw_allowance; + tANI_U16 medium_time; +} tDot11fIEWMMTSPEC; + +#define DOT11F_EID_WMMTSPEC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTSPEC_MIN_LEN ( 61 ) + +#define DOT11F_IE_WMMTSPEC_MAX_LEN ( 61 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTSPEC*); + +tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal, tDot11fIEWMMTSPEC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTSPEC(tpAniSirGlobal, tDot11fIEWMMTSPEC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 194 (0xc2) +typedef struct sDot11fIEWiderBWChanSwitchAnn { + tANI_U8 present; + tANI_U8 newChanWidth; + tANI_U8 newCenterChanFreq0; + tANI_U8 newCenterChanFreq1; +} tDot11fIEWiderBWChanSwitchAnn; + +#define DOT11F_EID_WIDERBWCHANSWITCHANN ( 194 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WIDERBWCHANSWITCHANN_MIN_LEN ( 3 ) + +#define DOT11F_IE_WIDERBWCHANSWITCHANN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWiderBWChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWiderBWChanSwitchAnn*); + +tANI_U32 dot11fPackIeWiderBWChanSwitchAnn(tpAniSirGlobal, tDot11fIEWiderBWChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWiderBWChanSwitchAnn(tpAniSirGlobal, tDot11fIEWiderBWChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 197 (0xc5) +typedef struct sDot11fIEAID { + tANI_U8 present; + tANI_U16 assocId; +} tDot11fIEAID; + +#define DOT11F_EID_AID ( 197 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_AID_MIN_LEN ( 2 ) + +#define DOT11F_IE_AID_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAID*); + +tANI_U32 dot11fPackIeAID(tpAniSirGlobal, tDot11fIEAID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAID(tpAniSirGlobal, tDot11fIEAID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x0a, 0xf5} +typedef struct sDot11fIEAirgo { + tANI_U8 present; + tDot11fIEPropSuppRates PropSuppRates; + tDot11fIEAPName APName; + tDot11fIEHCF HCF; + tDot11fIEWDS WDS; + tDot11fIEBPIndicator BPIndicator; + tDot11fIELoadInfo LoadInfo; + tDot11fIELoadBalance LoadBalance; + tDot11fIEPropAssocType PropAssocType; + tDot11fIELLAttr LLAttr; + tDot11fIEPropCapability PropCapability; + tDot11fIEVersion Version; + tDot11fIEPropEDCAParams PropEDCAParams; + tDot11fIETitan Titan; + tDot11fIEPropChannSwitchAnn PropChannSwitchAnn; + tDot11fIEPropQuietBSS PropQuietBSS; + tDot11fIETriggerStaBgScan TriggerStaBgScan; + tDot11fIETaurus Taurus; +} tDot11fIEAirgo; + +#define DOT11F_EID_AIRGO ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_AIRGO_MIN_LEN ( 3 ) + +#define DOT11F_IE_AIRGO_MAX_LEN ( 230 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAirgo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAirgo*); + +tANI_U32 dot11fPackIeAirgo(tpAniSirGlobal, tDot11fIEAirgo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAirgo(tpAniSirGlobal, tDot11fIEAirgo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIECFParams { + tANI_U8 present; + tANI_U8 cfp_count; + tANI_U8 cfp_period; + tANI_U16 cfp_maxduration; + tANI_U16 cfp_durremaining; +} tDot11fIECFParams; + +#define DOT11F_EID_CFPARAMS ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CFPARAMS_MIN_LEN ( 6 ) + +#define DOT11F_IE_CFPARAMS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCFParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECFParams*); + +tANI_U32 dot11fPackIeCFParams(tpAniSirGlobal, tDot11fIECFParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECFParams(tpAniSirGlobal, tDot11fIECFParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 16 (0x10) +typedef struct sDot11fIEChallengeText { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[253]; +} tDot11fIEChallengeText; + +#define DOT11F_EID_CHALLENGETEXT ( 16 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CHALLENGETEXT_MIN_LEN ( 1 ) + +#define DOT11F_IE_CHALLENGETEXT_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeChallengeText(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEChallengeText*); + +tANI_U32 dot11fPackIeChallengeText(tpAniSirGlobal, tDot11fIEChallengeText*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEChallengeText(tpAniSirGlobal, tDot11fIEChallengeText*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 37 (0x25) +typedef struct sDot11fIEChanSwitchAnn { + tANI_U8 present; + tANI_U8 switchMode; + tANI_U8 newChannel; + tANI_U8 switchCount; +} tDot11fIEChanSwitchAnn; + +#define DOT11F_EID_CHANSWITCHANN ( 37 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CHANSWITCHANN_MIN_LEN ( 3 ) + +#define DOT11F_IE_CHANSWITCHANN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEChanSwitchAnn*); + +tANI_U32 dot11fPackIeChanSwitchAnn(tpAniSirGlobal, tDot11fIEChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEChanSwitchAnn(tpAniSirGlobal, tDot11fIEChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 196 (0xc4) +typedef struct sDot11fIEChannelSwitchWrapper { + tANI_U8 present; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; +} tDot11fIEChannelSwitchWrapper; + +#define DOT11F_EID_CHANNELSWITCHWRAPPER ( 196 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CHANNELSWITCHWRAPPER_MIN_LEN ( 0 ) + +#define DOT11F_IE_CHANNELSWITCHWRAPPER_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeChannelSwitchWrapper(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEChannelSwitchWrapper*); + +tANI_U32 dot11fPackIeChannelSwitchWrapper(tpAniSirGlobal, tDot11fIEChannelSwitchWrapper*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEChannelSwitchWrapper(tpAniSirGlobal, tDot11fIEChannelSwitchWrapper*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 7 (0x07) +typedef struct sDot11fIECountry { + tANI_U8 present; + tANI_U8 country[3]; + tANI_U8 num_triplets; + tANI_U8 triplets[84][3]; +} tDot11fIECountry; + +#define DOT11F_EID_COUNTRY ( 7 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_COUNTRY_MIN_LEN ( 3 ) + +#define DOT11F_IE_COUNTRY_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCountry(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECountry*); + +tANI_U32 dot11fPackIeCountry(tpAniSirGlobal, tDot11fIECountry*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECountry(tpAniSirGlobal, tDot11fIECountry*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIEDSParams { + tANI_U8 present; + tANI_U8 curr_channel; +} tDot11fIEDSParams; + +#define DOT11F_EID_DSPARAMS ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_DSPARAMS_MIN_LEN ( 1 ) + +#define DOT11F_IE_DSPARAMS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeDSParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEDSParams*); + +tANI_U32 dot11fPackIeDSParams(tpAniSirGlobal, tDot11fIEDSParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEDSParams(tpAniSirGlobal, tDot11fIEDSParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 12 (0x0c) +typedef struct sDot11fIEEDCAParamSet { + tANI_U8 present; + tANI_U8 qos; + tANI_U8 reserved; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_acwmin: 4; + tANI_U8 acbe_acwmax: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_acwmin: 4; + tANI_U8 acbk_acwmax: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_acwmin: 4; + tANI_U8 acvi_acwmax: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_acwmin: 4; + tANI_U8 acvo_acwmax: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEEDCAParamSet; + +#define DOT11F_EID_EDCAPARAMSET ( 12 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EDCAPARAMSET_MIN_LEN ( 18 ) + +#define DOT11F_IE_EDCAPARAMSET_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEEDCAParamSet*); + +tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal, tDot11fIEEDCAParamSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEEDCAParamSet(tpAniSirGlobal, tDot11fIEEDCAParamSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 42 (0x2a) +typedef struct sDot11fIEERPInfo { + tANI_U8 present; + tANI_U8 non_erp_present: 1; + tANI_U8 use_prot: 1; + tANI_U8 barker_preamble: 1; + tANI_U8 unused: 5; +} tDot11fIEERPInfo; + +#define DOT11F_EID_ERPINFO ( 42 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ERPINFO_MIN_LEN ( 1 ) + +#define DOT11F_IE_ERPINFO_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeERPInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEERPInfo*); + +tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal, tDot11fIEERPInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEERPInfo(tpAniSirGlobal, tDot11fIEERPInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 156 (0x9c) {OUI 0x00, 0x40, 0x96, 0x00} +typedef struct sDot11fIEESECckmOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[20]; +} tDot11fIEESECckmOpaque; + +#define DOT11F_EID_ESECCKMOPAQUE ( 156 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESECCKMOPAQUE_MIN_LEN ( 10 ) + +#define DOT11F_IE_ESECCKMOPAQUE_MAX_LEN ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESECckmOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESECckmOpaque*); + +tANI_U32 dot11fPackIeESECckmOpaque(tpAniSirGlobal, tDot11fIEESECckmOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESECckmOpaque(tpAniSirGlobal, tDot11fIEESECckmOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x01} +typedef struct sDot11fIEESERadMgmtCap { + tANI_U8 present; + tANI_U8 mgmt_state; + tANI_U8 mbssid_mask: 3; + tANI_U8 reserved: 5; +} tDot11fIEESERadMgmtCap; + +#define DOT11F_EID_ESERADMGMTCAP ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESERADMGMTCAP_MIN_LEN ( 6 ) + +#define DOT11F_IE_ESERADMGMTCAP_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESERadMgmtCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESERadMgmtCap*); + +tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal, tDot11fIEESERadMgmtCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESERadMgmtCap(tpAniSirGlobal, tDot11fIEESERadMgmtCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x07} +typedef struct sDot11fIEESETrafStrmMet { + tANI_U8 present; + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tDot11fIEESETrafStrmMet; + +#define DOT11F_EID_ESETRAFSTRMMET ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETRAFSTRMMET_MIN_LEN ( 8 ) + +#define DOT11F_IE_ESETRAFSTRMMET_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETrafStrmMet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETrafStrmMet*); + +tANI_U32 dot11fPackIeESETrafStrmMet(tpAniSirGlobal, tDot11fIEESETrafStrmMet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETrafStrmMet(tpAniSirGlobal, tDot11fIEESETrafStrmMet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x08} +typedef struct sDot11fIEESETrafStrmRateSet { + tANI_U8 present; + tANI_U8 tsid; + tANI_U8 num_tsrates; + tANI_U8 tsrates[8]; +} tDot11fIEESETrafStrmRateSet; + +#define DOT11F_EID_ESETRAFSTRMRATESET ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETRAFSTRMRATESET_MIN_LEN ( 5 ) + +#define DOT11F_IE_ESETRAFSTRMRATESET_MAX_LEN ( 13 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETrafStrmRateSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETrafStrmRateSet*); + +tANI_U32 dot11fPackIeESETrafStrmRateSet(tpAniSirGlobal, tDot11fIEESETrafStrmRateSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETrafStrmRateSet(tpAniSirGlobal, tDot11fIEESETrafStrmRateSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 150 (0x96) {OUI 0x00, 0x40, 0x96, 0x00} +typedef struct sDot11fIEESETxmitPower { + tANI_U8 present; + tANI_U8 power_limit; + tANI_U8 reserved; +} tDot11fIEESETxmitPower; + +#define DOT11F_EID_ESETXMITPOWER ( 150 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETXMITPOWER_MIN_LEN ( 6 ) + +#define DOT11F_IE_ESETXMITPOWER_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETxmitPower(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETxmitPower*); + +tANI_U32 dot11fPackIeESETxmitPower(tpAniSirGlobal, tDot11fIEESETxmitPower*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETxmitPower(tpAniSirGlobal, tDot11fIEESETxmitPower*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x03} +typedef struct sDot11fIEESEVersion { + tANI_U8 present; + tANI_U8 version; +} tDot11fIEESEVersion; + +#define DOT11F_EID_ESEVERSION ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESEVERSION_MIN_LEN ( 5 ) + +#define DOT11F_IE_ESEVERSION_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESEVersion(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESEVersion*); + +tANI_U32 dot11fPackIeESEVersion(tpAniSirGlobal, tDot11fIEESEVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESEVersion(tpAniSirGlobal, tDot11fIEESEVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 127 (0x7f) +typedef struct sDot11fIEExtCap { + tANI_U8 present; + tANI_U8 num_bytes; + tANI_U8 bytes[9]; +} tDot11fIEExtCap; + +#define DOT11F_EID_EXTCAP ( 127 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTCAP_MIN_LEN ( 8 ) + +#define DOT11F_IE_EXTCAP_MAX_LEN ( 9 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtCap*); + +tANI_U32 dot11fPackIeExtCap(tpAniSirGlobal, tDot11fIEExtCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtCap(tpAniSirGlobal, tDot11fIEExtCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 62 (0x3e) +typedef struct sDot11fIEExtChanSwitchAnn { + tANI_U8 present; + tANI_U8 secondaryChannelOffset; +} tDot11fIEExtChanSwitchAnn; + +#define DOT11F_EID_EXTCHANSWITCHANN ( 62 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTCHANSWITCHANN_MIN_LEN ( 1 ) + +#define DOT11F_IE_EXTCHANSWITCHANN_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtChanSwitchAnn*); + +tANI_U32 dot11fPackIeExtChanSwitchAnn(tpAniSirGlobal, tDot11fIEExtChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtChanSwitchAnn(tpAniSirGlobal, tDot11fIEExtChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 50 (0x32) +typedef struct sDot11fIEExtSuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIEExtSuppRates; + +#define DOT11F_EID_EXTSUPPRATES ( 50 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTSUPPRATES_MIN_LEN ( 1 ) + +#define DOT11F_IE_EXTSUPPRATES_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtSuppRates*); + +tANI_U32 dot11fPackIeExtSuppRates(tpAniSirGlobal, tDot11fIEExtSuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtSuppRates(tpAniSirGlobal, tDot11fIEExtSuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEFHParamSet { + tANI_U8 present; + tANI_U16 dwell_time; + tANI_U8 hop_set; + tANI_U8 hop_pattern; + tANI_U8 hop_index; +} tDot11fIEFHParamSet; + +#define DOT11F_EID_FHPARAMSET ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPARAMSET_MIN_LEN ( 5 ) + +#define DOT11F_IE_FHPARAMSET_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHParamSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHParamSet*); + +tANI_U32 dot11fPackIeFHParamSet(tpAniSirGlobal, tDot11fIEFHParamSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHParamSet(tpAniSirGlobal, tDot11fIEFHParamSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 8 (0x08) +typedef struct sDot11fIEFHParams { + tANI_U8 present; + tANI_U8 radix; + tANI_U8 nchannels; +} tDot11fIEFHParams; + +#define DOT11F_EID_FHPARAMS ( 8 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPARAMS_MIN_LEN ( 2 ) + +#define DOT11F_IE_FHPARAMS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHParams*); + +tANI_U32 dot11fPackIeFHParams(tpAniSirGlobal, tDot11fIEFHParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHParams(tpAniSirGlobal, tDot11fIEFHParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 9 (0x09) +typedef struct sDot11fIEFHPattTable { + tANI_U8 present; + tANI_U8 flag; + tANI_U8 nsets; + tANI_U8 modulus; + tANI_U8 offset; + tANI_U8 num_randtable; + tANI_U8 randtable[251]; +} tDot11fIEFHPattTable; + +#define DOT11F_EID_FHPATTTABLE ( 9 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPATTTABLE_MIN_LEN ( 4 ) + +#define DOT11F_IE_FHPATTTABLE_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHPattTable(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHPattTable*); + +tANI_U32 dot11fPackIeFHPattTable(tpAniSirGlobal, tDot11fIEFHPattTable*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHPattTable(tpAniSirGlobal, tDot11fIEFHPattTable*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 55 (0x37) +typedef struct sDot11fIEFTInfo { + tANI_U8 present; + tANI_U16 reserved: 8; + tANI_U16 IECount: 8; + tANI_U8 MIC[16]; + tANI_U8 Anonce[32]; + tANI_U8 Snonce[32]; + tDot11fIER1KH_ID R1KH_ID; + tDot11fIEGTK GTK; + tDot11fIER0KH_ID R0KH_ID; + tDot11fIEIGTK IGTK; +} tDot11fIEFTInfo; + +#define DOT11F_EID_FTINFO ( 55 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FTINFO_MIN_LEN ( 82 ) + +#define DOT11F_IE_FTINFO_MAX_LEN ( 220 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFTInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFTInfo*); + +tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal, tDot11fIEFTInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFTInfo(tpAniSirGlobal, tDot11fIEFTInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 72 (0x48) +typedef struct sDot11fIEHT2040BSSCoexistence { + tANI_U8 present; + tANI_U8 infoRequest: 1; + tANI_U8 fortyMHzIntolerant: 1; + tANI_U8 twentyMHzBssWidthReq: 1; + tANI_U8 obssScanExemptionReq: 1; + tANI_U8 obssScanExemptionGrant: 1; + tANI_U8 unused: 3; +} tDot11fIEHT2040BSSCoexistence; + +#define DOT11F_EID_HT2040BSSCOEXISTENCE ( 72 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HT2040BSSCOEXISTENCE_MIN_LEN ( 1 ) + +#define DOT11F_IE_HT2040BSSCOEXISTENCE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHT2040BSSCoexistence(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHT2040BSSCoexistence*); + +tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal, tDot11fIEHT2040BSSCoexistence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHT2040BSSCoexistence(tpAniSirGlobal, tDot11fIEHT2040BSSCoexistence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 73 (0x49) +typedef struct sDot11fIEHT2040BSSIntolerantReport { + tANI_U8 present; + tANI_U8 operatingClass; + tANI_U8 num_channelList; + tANI_U8 channelList[50]; +} tDot11fIEHT2040BSSIntolerantReport; + +#define DOT11F_EID_HT2040BSSINTOLERANTREPORT ( 73 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HT2040BSSINTOLERANTREPORT_MIN_LEN ( 1 ) + +#define DOT11F_IE_HT2040BSSINTOLERANTREPORT_MAX_LEN ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHT2040BSSIntolerantReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHT2040BSSIntolerantReport*); + +tANI_U32 dot11fPackIeHT2040BSSIntolerantReport(tpAniSirGlobal, tDot11fIEHT2040BSSIntolerantReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHT2040BSSIntolerantReport(tpAniSirGlobal, tDot11fIEHT2040BSSIntolerantReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 45 (0x2d) +typedef struct sDot11fIEHTCaps { + tANI_U8 present; + tANI_U16 advCodingCap: 1; + tANI_U16 supportedChannelWidthSet: 1; + tANI_U16 mimoPowerSave: 2; + tANI_U16 greenField: 1; + tANI_U16 shortGI20MHz: 1; + tANI_U16 shortGI40MHz: 1; + tANI_U16 txSTBC: 1; + tANI_U16 rxSTBC: 2; + tANI_U16 delayedBA: 1; + tANI_U16 maximalAMSDUsize: 1; + tANI_U16 dsssCckMode40MHz: 1; + tANI_U16 psmp: 1; + tANI_U16 stbcControlFrame: 1; + tANI_U16 lsigTXOPProtection: 1; + tANI_U8 maxRxAMPDUFactor: 2; + tANI_U8 mpduDensity: 3; + tANI_U8 reserved1: 3; + tANI_U8 supportedMCSSet[16]; + tANI_U16 pco: 1; + tANI_U16 transitionTime: 2; + tANI_U16 reserved2: 5; + tANI_U16 mcsFeedback: 2; + tANI_U16 reserved3: 6; + tANI_U32 txBF: 1; + tANI_U32 rxStaggeredSounding: 1; + tANI_U32 txStaggeredSounding: 1; + tANI_U32 rxZLF: 1; + tANI_U32 txZLF: 1; + tANI_U32 implicitTxBF: 1; + tANI_U32 calibration: 2; + tANI_U32 explicitCSITxBF: 1; + tANI_U32 explicitUncompressedSteeringMatrix: 1; + tANI_U32 explicitBFCSIFeedback: 3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback: 3; + tANI_U32 explicitCompressedSteeringMatrixFeedback: 3; + tANI_U32 csiNumBFAntennae: 2; + tANI_U32 uncompressedSteeringMatrixBFAntennae: 2; + tANI_U32 compressedSteeringMatrixBFAntennae: 2; + tANI_U32 reserved4: 7; + tANI_U8 antennaSelection: 1; + tANI_U8 explicitCSIFeedbackTx: 1; + tANI_U8 antennaIndicesFeedbackTx: 1; + tANI_U8 explicitCSIFeedback: 1; + tANI_U8 antennaIndicesFeedback: 1; + tANI_U8 rxAS: 1; + tANI_U8 txSoundingPPDUs: 1; + tANI_U8 reserved5: 1; + tANI_U8 num_rsvd; + tANI_U8 rsvd[32]; +} tDot11fIEHTCaps; + +#define DOT11F_EID_HTCAPS ( 45 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HTCAPS_MIN_LEN ( 26 ) + +#define DOT11F_IE_HTCAPS_MAX_LEN ( 58 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHTCaps*); + +tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal, tDot11fIEHTCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHTCaps(tpAniSirGlobal, tDot11fIEHTCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 61 (0x3d) +typedef struct sDot11fIEHTInfo { + tANI_U8 present; + tANI_U8 primaryChannel; + tANI_U8 secondaryChannelOffset: 2; + tANI_U8 recommendedTxWidthSet: 1; + tANI_U8 rifsMode: 1; + tANI_U8 controlledAccessOnly: 1; + tANI_U8 serviceIntervalGranularity: 3; + tANI_U16 opMode: 2; + tANI_U16 nonGFDevicesPresent: 1; + tANI_U16 transmitBurstLimit: 1; + tANI_U16 obssNonHTStaPresent: 1; + tANI_U16 reserved: 11; + tANI_U16 basicSTBCMCS: 7; + tANI_U16 dualCTSProtection: 1; + tANI_U16 secondaryBeacon: 1; + tANI_U16 lsigTXOPProtectionFullSupport: 1; + tANI_U16 pcoActive: 1; + tANI_U16 pcoPhase: 1; + tANI_U16 reserved2: 4; + tANI_U8 basicMCSSet[16]; + tANI_U8 num_rsvd; + tANI_U8 rsvd[32]; +} tDot11fIEHTInfo; + +#define DOT11F_EID_HTINFO ( 61 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HTINFO_MIN_LEN ( 22 ) + +#define DOT11F_IE_HTINFO_MAX_LEN ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHTInfo*); + +tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal, tDot11fIEHTInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHTInfo(tpAniSirGlobal, tDot11fIEHTInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 6 (0x06) +typedef struct sDot11fIEIBSSParams { + tANI_U8 present; + tANI_U16 atim; +} tDot11fIEIBSSParams; + +#define DOT11F_EID_IBSSPARAMS ( 6 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_IBSSPARAMS_MIN_LEN ( 2 ) + +#define DOT11F_IE_IBSSPARAMS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeIBSSParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEIBSSParams*); + +tANI_U32 dot11fPackIeIBSSParams(tpAniSirGlobal, tDot11fIEIBSSParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEIBSSParams(tpAniSirGlobal, tDot11fIEIBSSParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 101 (0x65) +typedef struct sDot11fIELinkIdentifier { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 InitStaAddr[6]; + tANI_U8 RespStaAddr[6]; +} tDot11fIELinkIdentifier; + +#define DOT11F_EID_LINKIDENTIFIER ( 101 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LINKIDENTIFIER_MIN_LEN ( 18 ) + +#define DOT11F_IE_LINKIDENTIFIER_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLinkIdentifier(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELinkIdentifier*); + +tANI_U32 dot11fPackIeLinkIdentifier(tpAniSirGlobal, tDot11fIELinkIdentifier*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELinkIdentifier(tpAniSirGlobal, tDot11fIELinkIdentifier*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 39 (0x27) +typedef struct sDot11fIEMeasurementReport { + tANI_U8 present; + tANI_U8 token; + tANI_U8 late: 1; + tANI_U8 incapable: 1; + tANI_U8 refused: 1; + tANI_U8 unused: 5; + tANI_U8 type; + union + { + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 bss: 1; + tANI_U8 ofdm_preamble: 1; + tANI_U8 unid_signal: 1; + tANI_U8 rader: 1; + tANI_U8 unmeasured: 1; + tANI_U8 unused: 3; + } Basic; /* type = 0 */ + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 cca_busy_fraction; + } CCA; /* type = 1 */ + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 rpi0_density; + tANI_U8 rpi1_density; + tANI_U8 rpi2_density; + tANI_U8 rpi3_density; + tANI_U8 rpi4_density; + tANI_U8 rpi5_density; + tANI_U8 rpi6_density; + tANI_U8 rpi7_density; + } RPIHistogram; /* type = 2 */ + struct + { + tANI_U8 regClass; + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 condensed_PHY: 7; + tANI_U8 reported_frame_type: 1; + tANI_U8 RCPI; + tANI_U8 RSNI; + tANI_U8 BSSID[6]; + tANI_U8 antenna_id; + tANI_U32 parent_TSF; + tDot11fIEBeaconReportFrmBody BeaconReportFrmBody; + } Beacon; /* type = 5 */ + } report; +} tDot11fIEMeasurementReport; + +#define DOT11F_EID_MEASUREMENTREPORT ( 39 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTREPORT_MIN_LEN ( 3 ) + +#define DOT11F_IE_MEASUREMENTREPORT_MAX_LEN ( 29 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementReport*); + +tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal, tDot11fIEMeasurementReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementReport(tpAniSirGlobal, tDot11fIEMeasurementReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 38 (0x26) +typedef struct sDot11fIEMeasurementRequest { + tANI_U8 present; + tANI_U8 measurement_token; + tANI_U8 parallel: 1; + tANI_U8 enable: 1; + tANI_U8 request: 1; + tANI_U8 report: 1; + tANI_U8 durationMandatory: 1; + tANI_U8 unused: 3; + tANI_U8 measurement_type; + union + { + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } Basic; /* measurement_type = 0 */ + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } CCA; /* measurement_type = 1 */ + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } RPIHistogram; /* measurement_type = 2 */ + struct + { + tANI_U8 regClass; + tANI_U8 channel; + tANI_U16 randomization; + tANI_U16 meas_duration; + tANI_U8 meas_mode; + tANI_U8 BSSID[6]; + tDot11fIESSID SSID; + tDot11fIEBeaconReporting BeaconReporting; + tDot11fIEBcnReportingDetail BcnReportingDetail; + tDot11fIERequestedInfo RequestedInfo; + tANI_U16 num_APChannelReport; + tDot11fIEAPChannelReport APChannelReport[2]; + } Beacon; /* measurement_type = 5 */ + } measurement_request; +} tDot11fIEMeasurementRequest; + +#define DOT11F_EID_MEASUREMENTREQUEST ( 38 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN ( 14 ) + +#define DOT11F_IE_MEASUREMENTREQUEST_MAX_LEN ( 16 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementRequest*); + +tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal, tDot11fIEMeasurementRequest*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementRequest(tpAniSirGlobal, tDot11fIEMeasurementRequest*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 54 (0x36) +typedef struct sDot11fIEMobilityDomain { + tANI_U8 present; + tANI_U16 MDID; + tANI_U8 overDSCap: 1; + tANI_U8 resourceReqCap: 1; + tANI_U8 reserved: 6; +} tDot11fIEMobilityDomain; + +#define DOT11F_EID_MOBILITYDOMAIN ( 54 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MOBILITYDOMAIN_MIN_LEN ( 3 ) + +#define DOT11F_IE_MOBILITYDOMAIN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMobilityDomain(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMobilityDomain*); + +tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal, tDot11fIEMobilityDomain*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMobilityDomain(tpAniSirGlobal, tDot11fIEMobilityDomain*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 52 (0x34) +typedef struct sDot11fIENeighborReport { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 APReachability: 2; + tANI_U8 Security: 1; + tANI_U8 KeyScope: 1; + tANI_U8 SpecMgmtCap: 1; + tANI_U8 QosCap: 1; + tANI_U8 apsd: 1; + tANI_U8 rrm: 1; + tANI_U8 DelayedBA: 1; + tANI_U8 ImmBA: 1; + tANI_U8 MobilityDomain: 1; + tANI_U8 reserved: 5; + tANI_U16 reserved1; + tANI_U8 regulatoryClass; + tANI_U8 channel; + tANI_U8 PhyType; + tDot11fIETSFInfo TSFInfo; + tDot11fIECondensedCountryStr CondensedCountryStr; + tDot11fIEMeasurementPilot MeasurementPilot; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMultiBssid MultiBssid; +} tDot11fIENeighborReport; + +#define DOT11F_EID_NEIGHBORREPORT ( 52 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_NEIGHBORREPORT_MIN_LEN ( 13 ) + +#define DOT11F_IE_NEIGHBORREPORT_MAX_LEN ( 546 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIENeighborReport*); + +tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal, tDot11fIENeighborReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIENeighborReport(tpAniSirGlobal, tDot11fIENeighborReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 74 (0x4a) +typedef struct sDot11fIEOBSSScanParameters { + tANI_U8 present; + tANI_U16 obssScanPassiveDwell; + tANI_U16 obssScanActiveDwell; + tANI_U16 bssChannelWidthTriggerScanInterval; + tANI_U16 obssScanPassiveTotalPerChannel; + tANI_U16 obssScanActiveTotalPerChannel; + tANI_U16 bssWidthChannelTransitionDelayFactor; + tANI_U16 obssScanActivityThreshold; +} tDot11fIEOBSSScanParameters; + +#define DOT11F_EID_OBSSSCANPARAMETERS ( 74 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_OBSSSCANPARAMETERS_MIN_LEN ( 14 ) + +#define DOT11F_IE_OBSSSCANPARAMETERS_MAX_LEN ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeOBSSScanParameters(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEOBSSScanParameters*); + +tANI_U32 dot11fPackIeOBSSScanParameters(tpAniSirGlobal, tDot11fIEOBSSScanParameters*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEOBSSScanParameters(tpAniSirGlobal, tDot11fIEOBSSScanParameters*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 199 (0xc7) +typedef struct sDot11fIEOperatingMode { + tANI_U8 present; + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +} tDot11fIEOperatingMode; + +#define DOT11F_EID_OPERATINGMODE ( 199 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_OPERATINGMODE_MIN_LEN ( 1 ) + +#define DOT11F_IE_OPERATINGMODE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeOperatingMode(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEOperatingMode*); + +tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal, tDot11fIEOperatingMode*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEOperatingMode(tpAniSirGlobal, tDot11fIEOperatingMode*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PAssocReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; +} tDot11fIEP2PAssocReq; + +#define DOT11F_EID_P2PASSOCREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PASSOCREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PASSOCREQ_MAX_LEN ( 71 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PAssocReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PAssocReq*); + +tANI_U32 dot11fPackIeP2PAssocReq(tpAniSirGlobal, tDot11fIEP2PAssocReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PAssocReq(tpAniSirGlobal, tDot11fIEP2PAssocReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PAssocRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; +} tDot11fIEP2PAssocRes; + +#define DOT11F_EID_P2PASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PASSOCRES_MAX_LEN ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PAssocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PAssocRes*); + +tANI_U32 dot11fPackIeP2PAssocRes(tpAniSirGlobal, tDot11fIEP2PAssocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PAssocRes(tpAniSirGlobal, tDot11fIEP2PAssocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PBeacon { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PBeacon; + +#define DOT11F_EID_P2PBEACON ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PBEACON_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PBEACON_MAX_LEN ( 59 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PBeacon(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PBeacon*); + +tANI_U32 dot11fPackIeP2PBeacon(tpAniSirGlobal, tDot11fIEP2PBeacon*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PBeacon(tpAniSirGlobal, tDot11fIEP2PBeacon*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PBeaconProbeRes { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupInfo P2PGroupInfo; +} tDot11fIEP2PBeaconProbeRes; + +#define DOT11F_EID_P2PBEACONPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PBEACONPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PBEACONPROBERES_MAX_LEN ( 1148 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PBeaconProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PBeaconProbeRes*); + +tANI_U32 dot11fPackIeP2PBeaconProbeRes(tpAniSirGlobal, tDot11fIEP2PBeaconProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PBeaconProbeRes(tpAniSirGlobal, tDot11fIEP2PBeaconProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeAuth { + tANI_U8 present; + tDot11fTLVMinorReasonCode MinorReasonCode; +} tDot11fIEP2PDeAuth; + +#define DOT11F_EID_P2PDEAUTH ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEAUTH_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEAUTH_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeAuth(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeAuth*); + +tANI_U32 dot11fPackIeP2PDeAuth(tpAniSirGlobal, tDot11fIEP2PDeAuth*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeAuth(tpAniSirGlobal, tDot11fIEP2PDeAuth*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeviceDiscoverabilityReq { + tANI_U8 present; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PDeviceDiscoverabilityReq; + +#define DOT11F_EID_P2PDEVICEDISCOVERABILITYREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYREQ_MAX_LEN ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeviceDiscoverabilityReq*); + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeviceDiscoverabilityRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; +} tDot11fIEP2PDeviceDiscoverabilityRes; + +#define DOT11F_EID_P2PDEVICEDISCOVERABILITYRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYRES_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeviceDiscoverabilityRes*); + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDisAssoc { + tANI_U8 present; + tDot11fTLVMinorReasonCode MinorReasonCode; +} tDot11fIEP2PDisAssoc; + +#define DOT11F_EID_P2PDISASSOC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDISASSOC_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDISASSOC_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDisAssoc(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDisAssoc*); + +tANI_U32 dot11fPackIeP2PDisAssoc(tpAniSirGlobal, tDot11fIEP2PDisAssoc*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDisAssoc(tpAniSirGlobal, tDot11fIEP2PDisAssoc*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegCnf { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PGONegCnf; + +#define DOT11F_EID_P2PGONEGCNF ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGCNF_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGCNF_MAX_LEN ( 319 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegCnf(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegCnf*); + +tANI_U32 dot11fPackIeP2PGONegCnf(tpAniSirGlobal, tDot11fIEP2PGONegCnf*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegCnf(tpAniSirGlobal, tDot11fIEP2PGONegCnf*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVGOIntent GOIntent; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVListenChannel ListenChannel; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVIntendedP2PInterfaceAddress IntendedP2PInterfaceAddress; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVOperatingChannel OperatingChannel; +} tDot11fIEP2PGONegReq; + +#define DOT11F_EID_P2PGONEGREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGREQ_MAX_LEN ( 362 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegReq*); + +tANI_U32 dot11fPackIeP2PGONegReq(tpAniSirGlobal, tDot11fIEP2PGONegReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegReq(tpAniSirGlobal, tDot11fIEP2PGONegReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVGOIntent GOIntent; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVIntendedP2PInterfaceAddress IntendedP2PInterfaceAddress; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PGONegRes; + +#define DOT11F_EID_P2PGONEGRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGRES_MAX_LEN ( 392 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegRes*); + +tANI_U32 dot11fPackIeP2PGONegRes(tpAniSirGlobal, tDot11fIEP2PGONegRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegRes(tpAniSirGlobal, tDot11fIEP2PGONegRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEP2PGONegWPS { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVDevicePasswordID DevicePasswordID; +} tDot11fIEP2PGONegWPS; + +#define DOT11F_EID_P2PGONEGWPS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGWPS_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGWPS_MAX_LEN ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegWPS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegWPS*); + +tANI_U32 dot11fPackIeP2PGONegWPS(tpAniSirGlobal, tDot11fIEP2PGONegWPS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegWPS(tpAniSirGlobal, tDot11fIEP2PGONegWPS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} +typedef struct sDot11fIEP2PIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEP2PIEOpaque; + +#define DOT11F_EID_P2PIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_P2PIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PIEOpaque*); + +tANI_U32 dot11fPackIeP2PIEOpaque(tpAniSirGlobal, tDot11fIEP2PIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PIEOpaque(tpAniSirGlobal, tDot11fIEP2PIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PInvitationReq { + tANI_U8 present; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVInvitationFlags InvitationFlags; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVP2PGroupBssid P2PGroupBssid; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PGroupId P2PGroupId; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; +} tDot11fIEP2PInvitationReq; + +#define DOT11F_EID_P2PINVITATIONREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PINVITATIONREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PINVITATIONREQ_MAX_LEN ( 383 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PInvitationReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PInvitationReq*); + +tANI_U32 dot11fPackIeP2PInvitationReq(tpAniSirGlobal, tDot11fIEP2PInvitationReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PInvitationReq(tpAniSirGlobal, tDot11fIEP2PInvitationReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PInvitationRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVP2PGroupBssid P2PGroupBssid; + tDot11fTLVChannelList ChannelList; +} tDot11fIEP2PInvitationRes; + +#define DOT11F_EID_P2PINVITATIONRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PINVITATIONRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PINVITATIONRES_MAX_LEN ( 287 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PInvitationRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PInvitationRes*); + +tANI_U32 dot11fPackIeP2PInvitationRes(tpAniSirGlobal, tDot11fIEP2PInvitationRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PInvitationRes(tpAniSirGlobal, tDot11fIEP2PInvitationRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PNoticeOfAbsence { + tANI_U8 present; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PNoticeOfAbsence; + +#define DOT11F_EID_P2PNOTICEOFABSENCE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PNOTICEOFABSENCE_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PNOTICEOFABSENCE_MAX_LEN ( 45 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PNoticeOfAbsence(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PNoticeOfAbsence*); + +tANI_U32 dot11fPackIeP2PNoticeOfAbsence(tpAniSirGlobal, tDot11fIEP2PNoticeOfAbsence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PNoticeOfAbsence(tpAniSirGlobal, tDot11fIEP2PNoticeOfAbsence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PPresenceResponse { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PPresenceResponse; + +#define DOT11F_EID_P2PPRESENCERESPONSE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPRESENCERESPONSE_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPRESENCERESPONSE_MAX_LEN ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PPresenceResponse(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PPresenceResponse*); + +tANI_U32 dot11fPackIeP2PPresenceResponse(tpAniSirGlobal, tDot11fIEP2PPresenceResponse*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PPresenceResponse(tpAniSirGlobal, tDot11fIEP2PPresenceResponse*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProbeReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVListenChannel ListenChannel; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVOperatingChannel OperatingChannel; +} tDot11fIEP2PProbeReq; + +#define DOT11F_EID_P2PPROBEREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROBEREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROBEREQ_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProbeReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProbeReq*); + +tANI_U32 dot11fPackIeP2PProbeReq(tpAniSirGlobal, tDot11fIEP2PProbeReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProbeReq(tpAniSirGlobal, tDot11fIEP2PProbeReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProbeRes { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupInfo P2PGroupInfo; +} tDot11fIEP2PProbeRes; + +#define DOT11F_EID_P2PPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROBERES_MAX_LEN ( 1139 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProbeRes*); + +tANI_U32 dot11fPackIeP2PProbeRes(tpAniSirGlobal, tDot11fIEP2PProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProbeRes(tpAniSirGlobal, tDot11fIEP2PProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProvisionDiscoveryReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PProvisionDiscoveryReq; + +#define DOT11F_EID_P2PPROVISIONDISCOVERYREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROVISIONDISCOVERYREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROVISIONDISCOVERYREQ_MAX_LEN ( 105 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProvisionDiscoveryReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProvisionDiscoveryReq*); + +tANI_U32 dot11fPackIeP2PProvisionDiscoveryReq(tpAniSirGlobal, tDot11fIEP2PProvisionDiscoveryReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProvisionDiscoveryReq(tpAniSirGlobal, tDot11fIEP2PProvisionDiscoveryReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEP2PWSCProvisionDiscoveryRes { + tANI_U8 present; + tDot11fTLVConfigMethods ConfigMethods; +} tDot11fIEP2PWSCProvisionDiscoveryRes; + +#define DOT11F_EID_P2PWSCPROVISIONDISCOVERYRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PWSCPROVISIONDISCOVERYRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PWSCPROVISIONDISCOVERYRES_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PWSCProvisionDiscoveryRes*); + +tANI_U32 dot11fPackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tDot11fIEP2PWSCProvisionDiscoveryRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tDot11fIEP2PWSCProvisionDiscoveryRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 105 (0x69) +typedef struct sDot11fIEPTIControl { + tANI_U8 present; + tANI_U8 tid; + tANI_U16 sequence_control; +} tDot11fIEPTIControl; + +#define DOT11F_EID_PTICONTROL ( 105 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PTICONTROL_MIN_LEN ( 3 ) + +#define DOT11F_IE_PTICONTROL_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePTIControl(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPTIControl*); + +tANI_U32 dot11fPackIePTIControl(tpAniSirGlobal, tDot11fIEPTIControl*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPTIControl(tpAniSirGlobal, tDot11fIEPTIControl*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 106 (0x6a) +typedef struct sDot11fIEPUBufferStatus { + tANI_U8 present; + tANI_U8 ac_bk_traffic_aval: 1; + tANI_U8 ac_be_traffic_aval: 1; + tANI_U8 ac_vi_traffic_aval: 1; + tANI_U8 ac_vo_traffic_aval: 1; + tANI_U8 reserved: 4; +} tDot11fIEPUBufferStatus; + +#define DOT11F_EID_PUBUFFERSTATUS ( 106 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PUBUFFERSTATUS_MIN_LEN ( 1 ) + +#define DOT11F_IE_PUBUFFERSTATUS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePUBufferStatus(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPUBufferStatus*); + +tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal, tDot11fIEPUBufferStatus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPUBufferStatus(tpAniSirGlobal, tDot11fIEPUBufferStatus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 33 (0x21) +typedef struct sDot11fIEPowerCaps { + tANI_U8 present; + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tDot11fIEPowerCaps; + +#define DOT11F_EID_POWERCAPS ( 33 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_POWERCAPS_MIN_LEN ( 2 ) + +#define DOT11F_IE_POWERCAPS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePowerCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPowerCaps*); + +tANI_U32 dot11fPackIePowerCaps(tpAniSirGlobal, tDot11fIEPowerCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPowerCaps(tpAniSirGlobal, tDot11fIEPowerCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 32 (0x20) +typedef struct sDot11fIEPowerConstraints { + tANI_U8 present; + tANI_U8 localPowerConstraints; +} tDot11fIEPowerConstraints; + +#define DOT11F_EID_POWERCONSTRAINTS ( 32 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_POWERCONSTRAINTS_MIN_LEN ( 1 ) + +#define DOT11F_IE_POWERCONSTRAINTS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePowerConstraints(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPowerConstraints*); + +tANI_U32 dot11fPackIePowerConstraints(tpAniSirGlobal, tDot11fIEPowerConstraints*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPowerConstraints(tpAniSirGlobal, tDot11fIEPowerConstraints*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 11 (0x0b) +typedef struct sDot11fIEQBSSLoad { + tANI_U8 present; + tANI_U16 stacount; + tANI_U8 chautil; + tANI_U16 avail; +} tDot11fIEQBSSLoad; + +#define DOT11F_EID_QBSSLOAD ( 11 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QBSSLOAD_MIN_LEN ( 5 ) + +#define DOT11F_IE_QBSSLOAD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQBSSLoad(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQBSSLoad*); + +tANI_U32 dot11fPackIeQBSSLoad(tpAniSirGlobal, tDot11fIEQBSSLoad*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQBSSLoad(tpAniSirGlobal, tDot11fIEQBSSLoad*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 46 (0x2e) +typedef struct sDot11fIEQOSCapsAp { + tANI_U8 present; + tANI_U8 count: 4; + tANI_U8 qack: 1; + tANI_U8 qreq: 1; + tANI_U8 txopreq: 1; + tANI_U8 reserved: 1; +} tDot11fIEQOSCapsAp; + +#define DOT11F_EID_QOSCAPSAP ( 46 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSCAPSAP_MIN_LEN ( 1 ) + +#define DOT11F_IE_QOSCAPSAP_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQOSCapsAp(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQOSCapsAp*); + +tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal, tDot11fIEQOSCapsAp*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQOSCapsAp(tpAniSirGlobal, tDot11fIEQOSCapsAp*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 46 (0x2e) +typedef struct sDot11fIEQOSCapsStation { + tANI_U8 present; + tANI_U8 acvo_uapsd: 1; + tANI_U8 acvi_uapsd: 1; + tANI_U8 acbk_uapsd: 1; + tANI_U8 acbe_uapsd: 1; + tANI_U8 qack: 1; + tANI_U8 max_sp_length: 2; + tANI_U8 more_data_ack: 1; +} tDot11fIEQOSCapsStation; + +#define DOT11F_EID_QOSCAPSSTATION ( 46 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSCAPSSTATION_MIN_LEN ( 1 ) + +#define DOT11F_IE_QOSCAPSSTATION_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQOSCapsStation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQOSCapsStation*); + +tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal, tDot11fIEQOSCapsStation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQOSCapsStation(tpAniSirGlobal, tDot11fIEQOSCapsStation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 110 (0x6e) +typedef struct sDot11fIEQosMapSet { + tANI_U8 present; + tANI_U8 num_dscp_exceptions; + tANI_U8 dscp_exceptions[60]; +} tDot11fIEQosMapSet; + +#define DOT11F_EID_QOSMAPSET ( 110 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSMAPSET_MIN_LEN ( 0 ) + +#define DOT11F_IE_QOSMAPSET_MAX_LEN ( 60 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQosMapSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQosMapSet*); + +tANI_U32 dot11fPackIeQosMapSet(tpAniSirGlobal, tDot11fIEQosMapSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQosMapSet(tpAniSirGlobal, tDot11fIEQosMapSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 40 (0x28) +typedef struct sDot11fIEQuiet { + tANI_U8 present; + tANI_U8 count; + tANI_U8 period; + tANI_U16 duration; + tANI_U16 offset; +} tDot11fIEQuiet; + +#define DOT11F_EID_QUIET ( 40 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QUIET_MIN_LEN ( 6 ) + +#define DOT11F_IE_QUIET_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQuiet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQuiet*); + +tANI_U32 dot11fPackIeQuiet(tpAniSirGlobal, tDot11fIEQuiet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQuiet(tpAniSirGlobal, tDot11fIEQuiet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 53 (0x35) +typedef struct sDot11fIERCPIIE { + tANI_U8 present; + tANI_U8 rcpi; +} tDot11fIERCPIIE; + +#define DOT11F_EID_RCPIIE ( 53 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RCPIIE_MIN_LEN ( 1 ) + +#define DOT11F_IE_RCPIIE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRCPIIE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERCPIIE*); + +tANI_U32 dot11fPackIeRCPIIE(tpAniSirGlobal, tDot11fIERCPIIE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERCPIIE(tpAniSirGlobal, tDot11fIERCPIIE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 57 (0x39) +typedef struct sDot11fIERICDataDesc { + tANI_U8 present; + tDot11fIERICData RICData; + tDot11fIERICDescriptor RICDescriptor; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIETSDelay TSDelay; + tDot11fIESchedule Schedule; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEWMMTSDelay WMMTSDelay; + tDot11fIEWMMSchedule WMMSchedule; +} tDot11fIERICDataDesc; + +#define DOT11F_EID_RICDATADESC ( 57 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDATADESC_MIN_LEN ( 0 ) + +#define DOT11F_IE_RICDATADESC_MAX_LEN ( 548 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICDataDesc(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICDataDesc*); + +tANI_U32 dot11fPackIeRICDataDesc(tpAniSirGlobal, tDot11fIERICDataDesc*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICDataDesc(tpAniSirGlobal, tDot11fIERICDataDesc*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 48 (0x30) +typedef struct sDot11fIERSN { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U8 gp_cipher_suite[4]; + tANI_U16 pwise_cipher_suite_count; + tANI_U8 pwise_cipher_suites[4][4]; + tANI_U16 akm_suite_count; + tANI_U8 akm_suites[4][4]; + tANI_U8 RSN_Cap[2]; + tANI_U16 pmkid_count; + tANI_U8 pmkid[4][16]; + tANI_U8 gp_mgmt_cipher_suite[4]; +} tDot11fIERSN; + +#define DOT11F_EID_RSN ( 48 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSN_MIN_LEN ( 6 ) + +#define DOT11F_IE_RSN_MAX_LEN ( 114 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSN*); + +tANI_U32 dot11fPackIeRSN(tpAniSirGlobal, tDot11fIERSN*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSN(tpAniSirGlobal, tDot11fIERSN*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 65 (0x41) +typedef struct sDot11fIERSNIIE { + tANI_U8 present; + tANI_U8 rsni; +} tDot11fIERSNIIE; + +#define DOT11F_EID_RSNIIE ( 65 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSNIIE_MIN_LEN ( 1 ) + +#define DOT11F_IE_RSNIIE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSNIIE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSNIIE*); + +tANI_U32 dot11fPackIeRSNIIE(tpAniSirGlobal, tDot11fIERSNIIE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSNIIE(tpAniSirGlobal, tDot11fIERSNIIE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 48 (0x30) +typedef struct sDot11fIERSNOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[253]; +} tDot11fIERSNOpaque; + +#define DOT11F_EID_RSNOPAQUE ( 48 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSNOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_RSNOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSNOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSNOpaque*); + +tANI_U32 dot11fPackIeRSNOpaque(tpAniSirGlobal, tDot11fIERSNOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSNOpaque(tpAniSirGlobal, tDot11fIERSNOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 36 (0x24) +typedef struct sDot11fIESuppChannels { + tANI_U8 present; + tANI_U8 num_bands; + tANI_U8 bands[48][2]; +} tDot11fIESuppChannels; + +#define DOT11F_EID_SUPPCHANNELS ( 36 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPCHANNELS_MIN_LEN ( 2 ) + +#define DOT11F_IE_SUPPCHANNELS_MAX_LEN ( 96 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppChannels(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppChannels*); + +tANI_U32 dot11fPackIeSuppChannels(tpAniSirGlobal, tDot11fIESuppChannels*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppChannels(tpAniSirGlobal, tDot11fIESuppChannels*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 59 (0x3b) +typedef struct sDot11fIESuppOperatingClasses { + tANI_U8 present; + tANI_U8 num_classes; + tANI_U8 classes[32]; +} tDot11fIESuppOperatingClasses; + +#define DOT11F_EID_SUPPOPERATINGCLASSES ( 59 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPOPERATINGCLASSES_MIN_LEN ( 1 ) + +#define DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppOperatingClasses(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppOperatingClasses*); + +tANI_U32 dot11fPackIeSuppOperatingClasses(tpAniSirGlobal, tDot11fIESuppOperatingClasses*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppOperatingClasses(tpAniSirGlobal, tDot11fIESuppOperatingClasses*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIESuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIESuppRates; + +#define DOT11F_EID_SUPPRATES ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPRATES_MIN_LEN ( 0 ) + +#define DOT11F_IE_SUPPRATES_MAX_LEN ( 12 ) + +#define DOT11F_IS_BG_RATE(_x) (((_x) == 02) || \ + ((_x) == 04) || \ + ((_x) == 11) || \ + ((_x) == 22) || \ + ((_x) == 12) || \ + ((_x) == 18) || \ + ((_x) == 24) || \ + ((_x) == 36) || \ + ((_x) == 48) || \ + ((_x) == 72) || \ + ((_x) == 96) || \ + ((_x) == 108)) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppRates*); + +tANI_U32 dot11fPackIeSuppRates(tpAniSirGlobal, tDot11fIESuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppRates(tpAniSirGlobal, tDot11fIESuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 5 (0x05) +typedef struct sDot11fIETIM { + tANI_U8 present; + tANI_U8 dtim_count; + tANI_U8 dtim_period; + tANI_U8 bmpctl; + tANI_U8 num_vbmp; + tANI_U8 vbmp[251]; +} tDot11fIETIM; + +#define DOT11F_EID_TIM ( 5 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TIM_MIN_LEN ( 4 ) + +#define DOT11F_IE_TIM_MAX_LEN ( 254 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTIM(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETIM*); + +tANI_U32 dot11fPackIeTIM(tpAniSirGlobal, tDot11fIETIM*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETIM(tpAniSirGlobal, tDot11fIETIM*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 35 (0x23) +typedef struct sDot11fIETPCReport { + tANI_U8 present; + tANI_U8 tx_power; + tANI_U8 link_margin; +} tDot11fIETPCReport; + +#define DOT11F_EID_TPCREPORT ( 35 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TPCREPORT_MIN_LEN ( 2 ) + +#define DOT11F_IE_TPCREPORT_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTPCReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETPCReport*); + +tANI_U32 dot11fPackIeTPCReport(tpAniSirGlobal, tDot11fIETPCReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETPCReport(tpAniSirGlobal, tDot11fIETPCReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 34 (0x22) +typedef struct sDot11fIETPCRequest { + tANI_U8 present; +} tDot11fIETPCRequest; + +#define DOT11F_EID_TPCREQUEST ( 34 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TPCREQUEST_MIN_LEN ( 0 ) + +#define DOT11F_IE_TPCREQUEST_MAX_LEN ( 0 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTPCRequest(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETPCRequest*); + +tANI_U32 dot11fPackIeTPCRequest(tpAniSirGlobal, tDot11fIETPCRequest*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETPCRequest(tpAniSirGlobal, tDot11fIETPCRequest*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 56 (0x38) +typedef struct sDot11fIETimeoutInterval { + tANI_U8 present; + tANI_U8 timeoutType; + tANI_U32 timeoutValue; +} tDot11fIETimeoutInterval; + +#define DOT11F_EID_TIMEOUTINTERVAL ( 56 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TIMEOUTINTERVAL_MIN_LEN ( 5 ) + +#define DOT11F_IE_TIMEOUTINTERVAL_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTimeoutInterval(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETimeoutInterval*); + +tANI_U32 dot11fPackIeTimeoutInterval(tpAniSirGlobal, tDot11fIETimeoutInterval*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETimeoutInterval(tpAniSirGlobal, tDot11fIETimeoutInterval*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 191 (0xbf) +typedef struct sDot11fIEVHTCaps { + tANI_U8 present; + tANI_U32 maxMPDULen: 2; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 txSTBC: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 numSoundingDim: 3; + tANI_U32 muBeamformerCap: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 htcVHTCap: 1; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 rxAntPattern: 1; + tANI_U32 txAntPattern: 1; + tANI_U32 reserved1: 2; + tANI_U16 rxMCSMap; + tANI_U16 rxHighSupDataRate: 13; + tANI_U16 reserved2: 3; + tANI_U16 txMCSMap; + tANI_U16 txSupDataRate: 13; + tANI_U16 reserved3: 3; +} tDot11fIEVHTCaps; + +#define DOT11F_EID_VHTCAPS ( 191 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTCAPS_MIN_LEN ( 12 ) + +#define DOT11F_IE_VHTCAPS_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTCaps*); + +tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal, tDot11fIEVHTCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTCaps(tpAniSirGlobal, tDot11fIEVHTCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 193 (0xc1) +typedef struct sDot11fIEVHTExtBssLoad { + tANI_U8 present; + tANI_U8 muMIMOCapStaCount; + tANI_U8 ssUnderUtil; + tANI_U8 FortyMHzUtil; + tANI_U8 EightyMHzUtil; + tANI_U8 OneSixtyMHzUtil; +} tDot11fIEVHTExtBssLoad; + +#define DOT11F_EID_VHTEXTBSSLOAD ( 193 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTEXTBSSLOAD_MIN_LEN ( 5 ) + +#define DOT11F_IE_VHTEXTBSSLOAD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTExtBssLoad(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTExtBssLoad*); + +tANI_U32 dot11fPackIeVHTExtBssLoad(tpAniSirGlobal, tDot11fIEVHTExtBssLoad*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTExtBssLoad(tpAniSirGlobal, tDot11fIEVHTExtBssLoad*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 192 (0xc0) +typedef struct sDot11fIEVHTOperation { + tANI_U8 present; + tANI_U8 chanWidth; + tANI_U8 chanCenterFreqSeg1; + tANI_U8 chanCenterFreqSeg2; + tANI_U16 basicMCSSet; +} tDot11fIEVHTOperation; + +#define DOT11F_EID_VHTOPERATION ( 192 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTOPERATION_MIN_LEN ( 5 ) + +#define DOT11F_IE_VHTOPERATION_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTOperation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTOperation*); + +tANI_U32 dot11fPackIeVHTOperation(tpAniSirGlobal, tDot11fIEVHTOperation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTOperation(tpAniSirGlobal, tDot11fIEVHTOperation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x10, 0x18} +typedef struct sDot11fIEVendor1IE { + tANI_U8 present; +} tDot11fIEVendor1IE; + +#define DOT11F_EID_VENDOR1IE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VENDOR1IE_MIN_LEN ( 3 ) + +#define DOT11F_IE_VENDOR1IE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVendor1IE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVendor1IE*); + +tANI_U32 dot11fPackIeVendor1IE(tpAniSirGlobal, tDot11fIEVendor1IE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVendor1IE(tpAniSirGlobal, tDot11fIEVendor1IE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x90, 0x4c} +typedef struct sDot11fIEVendor2IE { + tANI_U8 present; +} tDot11fIEVendor2IE; + +#define DOT11F_EID_VENDOR2IE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VENDOR2IE_MIN_LEN ( 3 ) + +#define DOT11F_IE_VENDOR2IE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVendor2IE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVendor2IE*); + +tANI_U32 dot11fPackIeVendor2IE(tpAniSirGlobal, tDot11fIEVendor2IE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVendor2IE(tpAniSirGlobal, tDot11fIEVendor2IE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x16, 0x32} +typedef struct sDot11fIEVendor3IE { + tANI_U8 present; +} tDot11fIEVendor3IE; + +#define DOT11F_EID_VENDOR3IE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VENDOR3IE_MIN_LEN ( 3 ) + +#define DOT11F_IE_VENDOR3IE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVendor3IE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVendor3IE*); + +tANI_U32 dot11fPackIeVendor3IE(tpAniSirGlobal, tDot11fIEVendor3IE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVendor3IE(tpAniSirGlobal, tDot11fIEVendor3IE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 68 (0x44) +typedef struct sDot11fIEWAPI { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U16 akm_suite_count; + tANI_U8 akm_suites[4][4]; + tANI_U16 unicast_cipher_suite_count; + tANI_U8 unicast_cipher_suites[4][4]; + tANI_U8 multicast_cipher_suite[4]; + tANI_U16 preauth: 1; + tANI_U16 reserved: 15; + tANI_U16 bkid_count; + tANI_U8 bkid[4][16]; +} tDot11fIEWAPI; + +#define DOT11F_EID_WAPI ( 68 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WAPI_MIN_LEN ( 12 ) + +#define DOT11F_IE_WAPI_MAX_LEN ( 110 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWAPI*); + +tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal, tDot11fIEWAPI*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWAPI(tpAniSirGlobal, tDot11fIEWAPI*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 68 (0x44) +typedef struct sDot11fIEWAPIOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[253]; +} tDot11fIEWAPIOpaque; + +#define DOT11F_EID_WAPIOPAQUE ( 68 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WAPIOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WAPIOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWAPIOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWAPIOpaque*); + +tANI_U32 dot11fPackIeWAPIOpaque(tpAniSirGlobal, tDot11fIEWAPIOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWAPIOpaque(tpAniSirGlobal, tDot11fIEWAPIOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x08, 0x00} +typedef struct sDot11fIEWFATPC { + tANI_U8 present; + tANI_U8 txPower; + tANI_U8 linkMargin; +} tDot11fIEWFATPC; + +#define DOT11F_EID_WFATPC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WFATPC_MIN_LEN ( 7 ) + +#define DOT11F_IE_WFATPC_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWFATPC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWFATPC*); + +tANI_U32 dot11fPackIeWFATPC(tpAniSirGlobal, tDot11fIEWFATPC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWFATPC(tpAniSirGlobal, tDot11fIEWFATPC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x0a} +typedef struct sDot11fIEWFDIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWFDIEOpaque; + +#define DOT11F_EID_WFDIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WFDIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WFDIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWFDIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWFDIEOpaque*); + +tANI_U32 dot11fPackIeWFDIEOpaque(tpAniSirGlobal, tDot11fIEWFDIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWFDIEOpaque(tpAniSirGlobal, tDot11fIEWFDIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x05} +typedef struct sDot11fIEWMMCaps { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 reserved: 4; + tANI_U8 qack: 1; + tANI_U8 queue_request: 1; + tANI_U8 txop_request: 1; + tANI_U8 more_ack: 1; +} tDot11fIEWMMCaps; + +#define DOT11F_EID_WMMCAPS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMCAPS_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMCAPS_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMCaps*); + +tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal, tDot11fIEWMMCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMCaps(tpAniSirGlobal, tDot11fIEWMMCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} +typedef struct sDot11fIEWMMInfoAp { + tANI_U8 present; + tANI_U8 version; + tANI_U8 param_set_count: 4; + tANI_U8 reserved: 3; + tANI_U8 uapsd: 1; +} tDot11fIEWMMInfoAp; + +#define DOT11F_EID_WMMINFOAP ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMINFOAP_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMINFOAP_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMInfoAp(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMInfoAp*); + +tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal, tDot11fIEWMMInfoAp*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMInfoAp(tpAniSirGlobal, tDot11fIEWMMInfoAp*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} +typedef struct sDot11fIEWMMInfoStation { + tANI_U8 present; + tANI_U8 version; + tANI_U8 acvo_uapsd: 1; + tANI_U8 acvi_uapsd: 1; + tANI_U8 acbk_uapsd: 1; + tANI_U8 acbe_uapsd: 1; + tANI_U8 reserved1: 1; + tANI_U8 max_sp_length: 2; + tANI_U8 reserved2: 1; +} tDot11fIEWMMInfoStation; + +#define DOT11F_EID_WMMINFOSTATION ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMINFOSTATION_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMINFOSTATION_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMInfoStation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMInfoStation*); + +tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal, tDot11fIEWMMInfoStation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMInfoStation(tpAniSirGlobal, tDot11fIEWMMInfoStation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x01} +typedef struct sDot11fIEWMMParams { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 qosInfo; + tANI_U8 reserved2; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_acwmin: 4; + tANI_U8 acbe_acwmax: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_acwmin: 4; + tANI_U8 acbk_acwmax: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_acwmin: 4; + tANI_U8 acvi_acwmax: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_acwmin: 4; + tANI_U8 acvo_acwmax: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEWMMParams; + +#define DOT11F_EID_WMMPARAMS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMPARAMS_MIN_LEN ( 24 ) + +#define DOT11F_IE_WMMPARAMS_MAX_LEN ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMParams*); + +tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal, tDot11fIEWMMParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMParams(tpAniSirGlobal, tDot11fIEWMMParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} +typedef struct sDot11fIEWPA { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U8 multicast_cipher_present; //field added to fix the bug in dot11fPackIEWPA + tANI_U8 multicast_cipher[4]; + tANI_U16 unicast_cipher_count; + tANI_U8 unicast_ciphers[4][4]; + tANI_U16 auth_suite_count; + tANI_U8 auth_suites[4][4]; + tANI_U16 caps; +} tDot11fIEWPA; + +#define DOT11F_EID_WPA ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WPA_MIN_LEN ( 6 ) + +#define DOT11F_IE_WPA_MAX_LEN ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWPA*); + +tANI_U32 dot11fPackIeWPA(tpAniSirGlobal, tDot11fIEWPA*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWPA(tpAniSirGlobal, tDot11fIEWPA*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} +typedef struct sDot11fIEWPAOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWPAOpaque; + +#define DOT11F_EID_WPAOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WPAOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WPAOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWPAOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWPAOpaque*); + +tANI_U32 dot11fPackIeWPAOpaque(tpAniSirGlobal, tDot11fIEWPAOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWPAOpaque(tpAniSirGlobal, tDot11fIEWPAOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWSC { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVUUID_R UUID_R; + tDot11fTLVRFBands RFBands; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVAssociationState AssociationState; + tDot11fTLVConfigurationError ConfigurationError; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVRequestType RequestType; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; + tDot11fTLVRequestDeviceType RequestDeviceType; +} tDot11fIEWSC; + +#define DOT11F_EID_WSC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSC_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSC_MAX_LEN ( 366 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWSC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWSC*); + +tANI_U32 dot11fPackIeWSC(tpAniSirGlobal, tDot11fIEWSC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWSC(tpAniSirGlobal, tDot11fIEWSC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscAssocReq { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVRequestType RequestType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscAssocReq; + +#define DOT11F_EID_WSCASSOCREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCASSOCREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCASSOCREQ_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscAssocReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscAssocReq*); + +tANI_U32 dot11fPackIeWscAssocReq(tpAniSirGlobal, tDot11fIEWscAssocReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscAssocReq(tpAniSirGlobal, tDot11fIEWscAssocReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscAssocRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscAssocRes; + +#define DOT11F_EID_WSCASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCASSOCRES_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscAssocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscAssocRes*); + +tANI_U32 dot11fPackIeWscAssocRes(tpAniSirGlobal, tDot11fIEWscAssocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscAssocRes(tpAniSirGlobal, tDot11fIEWscAssocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscBeacon { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscBeacon; + +#define DOT11F_EID_WSCBEACON ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCBEACON_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCBEACON_MAX_LEN ( 82 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscBeacon(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscBeacon*); + +tANI_U32 dot11fPackIeWscBeacon(tpAniSirGlobal, tDot11fIEWscBeacon*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscBeacon(tpAniSirGlobal, tDot11fIEWscBeacon*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscBeaconProbeRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVResponseType ResponseType; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscBeaconProbeRes; + +#define DOT11F_EID_WSCBEACONPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCBEACONPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCBEACONPROBERES_MAX_LEN ( 317 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscBeaconProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscBeaconProbeRes*); + +tANI_U32 dot11fPackIeWscBeaconProbeRes(tpAniSirGlobal, tDot11fIEWscBeaconProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscBeaconProbeRes(tpAniSirGlobal, tDot11fIEWscBeaconProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} +typedef struct sDot11fIEWscIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWscIEOpaque; + +#define DOT11F_EID_WSCIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WSCIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscIEOpaque*); + +tANI_U32 dot11fPackIeWscIEOpaque(tpAniSirGlobal, tDot11fIEWscIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscIEOpaque(tpAniSirGlobal, tDot11fIEWscIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscProbeReq { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVRequestType RequestType; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVRFBands RFBands; + tDot11fTLVAssociationState AssociationState; + tDot11fTLVConfigurationError ConfigurationError; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVVendorExtension VendorExtension; + tDot11fTLVRequestDeviceType RequestDeviceType; +} tDot11fIEWscProbeReq; + +#define DOT11F_EID_WSCPROBEREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCPROBEREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCPROBEREQ_MAX_LEN ( 284 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscProbeReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscProbeReq*); + +tANI_U32 dot11fPackIeWscProbeReq(tpAniSirGlobal, tDot11fIEWscProbeReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscProbeReq(tpAniSirGlobal, tDot11fIEWscProbeReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscProbeRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVResponseType ResponseType; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscProbeRes; + +#define DOT11F_EID_WSCPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCPROBERES_MAX_LEN ( 317 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscProbeRes*); + +tANI_U32 dot11fPackIeWscProbeRes(tpAniSirGlobal, tDot11fIEWscProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscProbeRes(tpAniSirGlobal, tDot11fIEWscProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscReassocRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscReassocRes; + +#define DOT11F_EID_WSCREASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCREASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCREASSOCRES_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscReassocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscReassocRes*); + +tANI_U32 dot11fPackIeWscReassocRes(tpAniSirGlobal, tDot11fIEWscReassocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal, tDot11fIEWscReassocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +/************************************************************************ + * Frames + **********************************************************************/ + +typedef struct sDot11fAddBAReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfAddBAParameterSet AddBAParameterSet; + tDot11fFfBATimeout BATimeout; + tDot11fFfBAStartingSequenceControl BAStartingSequenceControl; +} tDot11fAddBAReq; + +#define DOT11F_ADDBAREQ ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddBAReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBAReq *pFrm); +tANI_U32 dot11fPackAddBAReq(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddBAReqSize(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddBARsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatus Status; + tDot11fFfAddBAParameterSet AddBAParameterSet; + tDot11fFfBATimeout BATimeout; +} tDot11fAddBARsp; + +#define DOT11F_ADDBARSP ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddBARsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBARsp *pFrm); +tANI_U32 dot11fPackAddBARsp(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddBARspSize(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddTSRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; +} tDot11fAddTSRequest; + +#define DOT11F_ADDTSREQUEST ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSRequest *pFrm); +tANI_U32 dot11fPackAddTSRequest(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddTSResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatus Status; + tDot11fIETSDelay TSDelay; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIESchedule Schedule; + tDot11fIEWMMTSDelay WMMTSDelay; + tDot11fIEWMMSchedule WMMSchedule; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEESETrafStrmMet ESETrafStrmMet; +} tDot11fAddTSResponse; + +#define DOT11F_ADDTSRESPONSE ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSResponse *pFrm); +tANI_U32 dot11fPackAddTSResponse(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAssocRequest{ + tDot11fFfCapabilities Capabilities; + tDot11fFfListenInterval ListenInterval; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEPowerCaps PowerCaps; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPAOpaque WPAOpaque; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAirgo Airgo; + tDot11fIEWscIEOpaque WscIEOpaque; + tDot11fIEWAPIOpaque WAPIOpaque; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESEVersion ESEVersion; + tDot11fIEP2PIEOpaque P2PIEOpaque; + tDot11fIEWFDIEOpaque WFDIEOpaque; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEQosMapSet QosMapSet; +} tDot11fAssocRequest; + +#define DOT11F_ASSOCREQUEST ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocRequest *pFrm); +tANI_U32 dot11fPackAssocRequest(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAssocRequestSize(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAssocResponse{ + tDot11fFfCapabilities Capabilities; + tDot11fFfStatus Status; + tDot11fFfAID AID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERCPIIE RCPIIE; + tDot11fIERSNIIE RSNIIE; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPA WPA; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEAirgo Airgo; + tDot11fIEWscAssocRes WscAssocRes; + tDot11fIEP2PAssocRes P2PAssocRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEQosMapSet QosMapSet; +} tDot11fAssocResponse; + +#define DOT11F_ASSOCRESPONSE ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocResponse *pFrm); +tANI_U32 dot11fPackAssocResponse(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAssocResponseSize(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAuthentication{ + tDot11fFfAuthAlgo AuthAlgo; + tDot11fFfAuthSeqNo AuthSeqNo; + tDot11fFfStatus Status; + tDot11fIEChallengeText ChallengeText; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; +} tDot11fAuthentication; + +#define DOT11F_AUTHENTICATION ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAuthentication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAuthentication *pFrm); +tANI_U32 dot11fPackAuthentication(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAuthenticationSize(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIETIM TIM; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSN RSN; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEQOSCapsAp QOSCapsAp; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeacon WscBeacon; + tDot11fIEP2PBeacon P2PBeacon; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEVendor1IE Vendor1IE; + tDot11fIEVendor2IE Vendor2IE; + tDot11fIEVendor3IE Vendor3IE; + tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper; + tDot11fIEESEVersion ESEVersion; +} tDot11fBeacon; + +#define DOT11F_BEACON ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon *pFrm); +tANI_U32 dot11fPackBeacon(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeaconSize(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon1{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEDSParams DSParams; + tDot11fIEIBSSParams IBSSParams; +} tDot11fBeacon1; + +#define DOT11F_BEACON1 ( 9 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon1(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon1 *pFrm); +tANI_U32 dot11fPackBeacon1(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeacon1Size(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon2{ + tDot11fIECountry Country; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeacon WscBeacon; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEP2PBeacon P2PBeacon; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEVendor1IE Vendor1IE; + tDot11fIEVendor2IE Vendor2IE; + tDot11fIEVendor3IE Vendor3IE; + tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper; + tDot11fIEESEVersion ESEVersion; +} tDot11fBeacon2; + +#define DOT11F_BEACON2 ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon2 *pFrm); +tANI_U32 dot11fPackBeacon2(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeacon2Size(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeaconIEs{ + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIETIM TIM; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSN RSN; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEQOSCapsAp QOSCapsAp; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESEVersion ESEVersion; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeaconProbeRes WscBeaconProbeRes; + tDot11fIEP2PBeaconProbeRes P2PBeaconProbeRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEVendor1IE Vendor1IE; + tDot11fIEVendor2IE Vendor2IE; + tDot11fIEVendor3IE Vendor3IE; + tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper; +} tDot11fBeaconIEs; + +#define DOT11F_BEACONIES ( 11 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeaconIEs *pFrm); +tANI_U32 dot11fPackBeaconIEs(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeaconIEsSize(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fChannelSwitch{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; +} tDot11fChannelSwitch; + +#define DOT11F_CHANNELSWITCH ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackChannelSwitch(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fChannelSwitch *pFrm); +tANI_U32 dot11fPackChannelSwitch(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedChannelSwitchSize(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeAuth{ + tDot11fFfReason Reason; + tDot11fIEP2PDeAuth P2PDeAuth; +} tDot11fDeAuth; + +#define DOT11F_DEAUTH ( 13 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeAuth *pFrm); +tANI_U32 dot11fPackDeAuth(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeAuthSize(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDelBAInd{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDelBAParameterSet DelBAParameterSet; + tDot11fFfReason Reason; +} tDot11fDelBAInd; + +#define DOT11F_DELBAIND ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDelBAInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelBAInd *pFrm); +tANI_U32 dot11fPackDelBAInd(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDelBAIndSize(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDelTS{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTSInfo TSInfo; + tDot11fFfReason Reason; +} tDot11fDelTS; + +#define DOT11F_DELTS ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelTS *pFrm); +tANI_U32 dot11fPackDelTS(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDelTSSize(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeviceDiscoverabilityReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PDeviceDiscoverabilityReq P2PDeviceDiscoverabilityReq; +} tDot11fDeviceDiscoverabilityReq; + +#define DOT11F_DEVICEDISCOVERABILITYREQ ( 16 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityReq *pFrm); +tANI_U32 dot11fPackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeviceDiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeviceDiscoverabilityRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PDeviceDiscoverabilityRes P2PDeviceDiscoverabilityRes; +} tDot11fDeviceDiscoverabilityRes; + +#define DOT11F_DEVICEDISCOVERABILITYRES ( 17 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityRes *pFrm); +tANI_U32 dot11fPackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeviceDiscoverabilityResSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDisassociation{ + tDot11fFfReason Reason; + tDot11fIEP2PDisAssoc P2PDisAssoc; +} tDot11fDisassociation; + +#define DOT11F_DISASSOCIATION ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDisassociation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDisassociation *pFrm); +tANI_U32 dot11fPackDisassociation(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDisassociationSize(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGODiscoverabilityReq{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; +} tDot11fGODiscoverabilityReq; + +#define DOT11F_GODISCOVERABILITYREQ ( 19 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGODiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGODiscoverabilityReq *pFrm); +tANI_U32 dot11fPackGODiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGODiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegCnf{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegCnf P2PGONegCnf; +} tDot11fGONegCnf; + +#define DOT11F_GONEGCNF ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegCnf *pFrm); +tANI_U32 dot11fPackGONegCnf(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegCnfSize(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegWPS P2PGONegWPS; + tDot11fIEP2PGONegReq P2PGONegReq; +} tDot11fGONegReq; + +#define DOT11F_GONEGREQ ( 21 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegReq *pFrm); +tANI_U32 dot11fPackGONegReq(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegReqSize(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegWPS P2PGONegWPS; + tDot11fIEP2PGONegRes P2PGONegRes; +} tDot11fGONegRes; + +#define DOT11F_GONEGRES ( 22 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegRes *pFrm); +tANI_U32 dot11fPackGONegRes(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegResSize(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fHT2040BSSCoexistenceManagementActionFrame{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIEHT2040BSSIntolerantReport HT2040BSSIntolerantReport; +} tDot11fHT2040BSSCoexistenceManagementActionFrame; + +#define DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME ( 23 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm); +tANI_U32 dot11fPackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fInvitationReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PInvitationReq P2PInvitationReq; +} tDot11fInvitationReq; + +#define DOT11F_INVITATIONREQ ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationReq *pFrm); +tANI_U32 dot11fPackInvitationReq(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedInvitationReqSize(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fInvitationRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PInvitationRes P2PInvitationRes; +} tDot11fInvitationRes; + +#define DOT11F_INVITATIONRES ( 25 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationRes *pFrm); +tANI_U32 dot11fPackInvitationRes(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedInvitationResSize(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fLinkMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfTPCEleID TPCEleID; + tDot11fFfTPCEleLen TPCEleLen; + tDot11fFfTxPower TxPower; + tDot11fFfLinkMargin LinkMargin; + tDot11fFfRxAntennaId RxAntennaId; + tDot11fFfTxAntennaId TxAntennaId; + tDot11fFfRCPI RCPI; + tDot11fFfRSNI RSNI; +} tDot11fLinkMeasurementReport; + +#define DOT11F_LINKMEASUREMENTREPORT ( 26 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackLinkMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementReport *pFrm); +tANI_U32 dot11fPackLinkMeasurementReport(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedLinkMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fLinkMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfTxPower TxPower; + tDot11fFfMaxTxPower MaxTxPower; +} tDot11fLinkMeasurementRequest; + +#define DOT11F_LINKMEASUREMENTREQUEST ( 27 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackLinkMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementRequest *pFrm); +tANI_U32 dot11fPackLinkMeasurementRequest(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedLinkMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIEMeasurementReport MeasurementReport; +} tDot11fMeasurementReport; + +#define DOT11F_MEASUREMENTREPORT ( 28 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementReport *pFrm); +tANI_U32 dot11fPackMeasurementReport(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_MeasurementRequest; + tDot11fIEMeasurementRequest MeasurementRequest[4]; +} tDot11fMeasurementRequest; + +#define DOT11F_MEASUREMENTREQUEST ( 29 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementRequest *pFrm); +tANI_U32 dot11fPackMeasurementRequest(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNeighborReportRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIESSID SSID; +} tDot11fNeighborReportRequest; + +#define DOT11F_NEIGHBORREPORTREQUEST ( 30 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNeighborReportRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportRequest *pFrm); +tANI_U32 dot11fPackNeighborReportRequest(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNeighborReportRequestSize(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNeighborReportResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_NeighborReport; + tDot11fIENeighborReport NeighborReport[15]; +} tDot11fNeighborReportResponse; + +#define DOT11F_NEIGHBORREPORTRESPONSE ( 31 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNeighborReportResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportResponse *pFrm); +tANI_U32 dot11fPackNeighborReportResponse(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNeighborReportResponseSize(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNoticeOfAbs{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PNoticeOfAbsence P2PNoticeOfAbsence; +} tDot11fNoticeOfAbs; + +#define DOT11F_NOTICEOFABS ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNoticeOfAbs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNoticeOfAbs *pFrm); +tANI_U32 dot11fPackNoticeOfAbs(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNoticeOfAbsSize(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fOperatingMode{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfOperatingMode OperatingMode; +} tDot11fOperatingMode; + +#define DOT11F_OPERATINGMODE ( 33 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fOperatingMode *pFrm); +tANI_U32 dot11fPackOperatingMode(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedOperatingModeSize(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fPresenceReq{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PNoticeOfAbsence P2PNoticeOfAbsence; +} tDot11fPresenceReq; + +#define DOT11F_PRESENCEREQ ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackPresenceReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceReq *pFrm); +tANI_U32 dot11fPackPresenceReq(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedPresenceReqSize(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fPresenceRes{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PPresenceResponse P2PPresenceResponse; +} tDot11fPresenceRes; + +#define DOT11F_PRESENCERES ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackPresenceRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceRes *pFrm); +tANI_U32 dot11fPackPresenceRes(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedPresenceResSize(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProbeRequest{ + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIERequestedInfo RequestedInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEDSParams DSParams; + tDot11fIEHTCaps HTCaps; + tDot11fIEWscProbeReq WscProbeReq; + tDot11fIEWFATPC WFATPC; + tDot11fIEP2PProbeReq P2PProbeReq; + tDot11fIEVHTCaps VHTCaps; +} tDot11fProbeRequest; + +#define DOT11F_PROBEREQUEST ( 36 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeRequest *pFrm); +tANI_U32 dot11fPackProbeRequest(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProbeRequestSize(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProbeResponse{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscProbeRes WscProbeRes; + tDot11fIEP2PProbeRes P2PProbeRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEVendor1IE Vendor1IE; + tDot11fIEVendor2IE Vendor2IE; + tDot11fIEVendor3IE Vendor3IE; + tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper; + tDot11fIEESEVersion ESEVersion; +} tDot11fProbeResponse; + +#define DOT11F_PROBERESPONSE ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeResponse *pFrm); +tANI_U32 dot11fPackProbeResponse(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProbeResponseSize(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProvisionDiscoveryReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PProvisionDiscoveryReq P2PProvisionDiscoveryReq; +} tDot11fProvisionDiscoveryReq; + +#define DOT11F_PROVISIONDISCOVERYREQ ( 38 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryReq *pFrm); +tANI_U32 dot11fPackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProvisionDiscoveryReqSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProvisionDiscoveryRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PWSCProvisionDiscoveryRes P2PWSCProvisionDiscoveryRes; +} tDot11fProvisionDiscoveryRes; + +#define DOT11F_PROVISIONDISCOVERYRES ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryRes *pFrm); +tANI_U32 dot11fPackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProvisionDiscoveryResSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fQosMapConfigure{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEQosMapSet QosMapSet; +} tDot11fQosMapConfigure; + +#define DOT11F_QOSMAPCONFIGURE ( 40 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackQosMapConfigure(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fQosMapConfigure *pFrm); +tANI_U32 dot11fPackQosMapConfigure(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedQosMapConfigureSize(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fRadioMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_MeasurementReport; + tDot11fIEMeasurementReport MeasurementReport[4]; +} tDot11fRadioMeasurementReport; + +#define DOT11F_RADIOMEASUREMENTREPORT ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackRadioMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementReport *pFrm); +tANI_U32 dot11fPackRadioMeasurementReport(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedRadioMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fRadioMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfNumOfRepetitions NumOfRepetitions; + tANI_U16 num_MeasurementRequest; + tDot11fIEMeasurementRequest MeasurementRequest[2]; +} tDot11fRadioMeasurementRequest; + +#define DOT11F_RADIOMEASUREMENTREQUEST ( 42 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackRadioMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementRequest *pFrm); +tANI_U32 dot11fPackRadioMeasurementRequest(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedRadioMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fReAssocRequest{ + tDot11fFfCapabilities Capabilities; + tDot11fFfListenInterval ListenInterval; + tDot11fFfCurrentAPAddress CurrentAPAddress; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEPowerCaps PowerCaps; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPAOpaque WPAOpaque; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAirgo Airgo; + tDot11fIEWscIEOpaque WscIEOpaque; + tDot11fIEWAPIOpaque WAPIOpaque; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESEVersion ESEVersion; + tDot11fIEESECckmOpaque ESECckmOpaque; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; + tDot11fIEP2PIEOpaque P2PIEOpaque; + tDot11fIEWFDIEOpaque WFDIEOpaque; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEQosMapSet QosMapSet; +} tDot11fReAssocRequest; + +#define DOT11F_REASSOCREQUEST ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocRequest *pFrm); +tANI_U32 dot11fPackReAssocRequest(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedReAssocRequestSize(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fReAssocResponse{ + tDot11fFfCapabilities Capabilities; + tDot11fFfStatus Status; + tDot11fFfAID AID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERCPIIE RCPIIE; + tDot11fIERSNIIE RSNIIE; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPA WPA; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEWMMParams WMMParams; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; + tDot11fIEAirgo Airgo; + tDot11fIEWscReassocRes WscReassocRes; + tDot11fIEP2PAssocRes P2PAssocRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEQosMapSet QosMapSet; +} tDot11fReAssocResponse; + +#define DOT11F_REASSOCRESPONSE ( 44 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackReAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocResponse *pFrm); +tANI_U32 dot11fPackReAssocResponse(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedReAssocResponseSize(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSMPowerSave{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfSMPowerModeSet SMPowerModeSet; +} tDot11fSMPowerSave; + +#define DOT11F_SMPOWERSAVE ( 45 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSMPowerSave(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSMPowerSave *pFrm); +tANI_U32 dot11fPackSMPowerSave(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSMPowerSaveSize(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSaQueryReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTransactionId TransactionId; +} tDot11fSaQueryReq; + +#define DOT11F_SAQUERYREQ ( 46 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSaQueryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryReq *pFrm); +tANI_U32 dot11fPackSaQueryReq(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSaQueryReqSize(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSaQueryRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTransactionId TransactionId; +} tDot11fSaQueryRsp; + +#define DOT11F_SAQUERYRSP ( 47 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSaQueryRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryRsp *pFrm); +tANI_U32 dot11fPackSaQueryRsp(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSaQueryRspSize(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSDisReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSDisReq; + +#define DOT11F_TDLSDISREQ ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSDisReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisReq *pFrm); +tANI_U32 dot11fPackTDLSDisReq(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSDisReqSize(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSDisRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEVHTCaps VHTCaps; +} tDot11fTDLSDisRsp; + +#define DOT11F_TDLSDISRSP ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSDisRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisRsp *pFrm); +tANI_U32 dot11fPackTDLSDisRsp(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSDisRspSize(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSPeerTrafficInd{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEPTIControl PTIControl; + tDot11fIEPUBufferStatus PUBufferStatus; +} tDot11fTDLSPeerTrafficInd; + +#define DOT11F_TDLSPEERTRAFFICIND ( 50 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficInd *pFrm); +tANI_U32 dot11fPackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSPeerTrafficIndSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSPeerTrafficRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSPeerTrafficRsp; + +#define DOT11F_TDLSPEERTRAFFICRSP ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficRsp *pFrm); +tANI_U32 dot11fPackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSPeerTrafficRspSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupCnf{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfStatus Status; + tDot11fFfDialogToken DialogToken; + tDot11fIERSN RSN; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTInfo HTInfo; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMParams WMMParams; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEOperatingMode OperatingMode; +} tDot11fTDLSSetupCnf; + +#define DOT11F_TDLSSETUPCNF ( 52 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupCnf *pFrm); +tANI_U32 dot11fPackTDLSSetupCnf(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupCnfSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIECountry Country; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAID AID; + tDot11fIEVHTCaps VHTCaps; +} tDot11fTDLSSetupReq; + +#define DOT11F_TDLSSETUPREQ ( 53 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupReq *pFrm); +tANI_U32 dot11fPackTDLSSetupReq(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupReqSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfStatus Status; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIECountry Country; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAID AID; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEOperatingMode OperatingMode; +} tDot11fTDLSSetupRsp; + +#define DOT11F_TDLSSETUPRSP ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupRsp *pFrm); +tANI_U32 dot11fPackTDLSSetupRsp(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupRspSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSTeardown{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfReason Reason; + tDot11fIEFTInfo FTInfo; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSTeardown; + +#define DOT11F_TDLSTEARDOWN ( 55 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSTeardown(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSTeardown *pFrm); +tANI_U32 dot11fPackTDLSTeardown(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSTeardownSize(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTPCReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETPCReport TPCReport; +} tDot11fTPCReport; + +#define DOT11F_TPCREPORT ( 56 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCReport *pFrm); +tANI_U32 dot11fPackTPCReport(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTPCReportSize(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTPCRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETPCRequest TPCRequest; +} tDot11fTPCRequest; + +#define DOT11F_TPCREQUEST ( 57 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCRequest *pFrm); +tANI_U32 dot11fPackTPCRequest(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTPCRequestSize(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fVHTGidManagementActionFrame{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfVhtMembershipStatusArray VhtMembershipStatusArray; + tDot11fFfVhtUserPositionArray VhtUserPositionArray; +} tDot11fVHTGidManagementActionFrame; + +#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME ( 58 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fVHTGidManagementActionFrame *pFrm); +tANI_U32 dot11fPackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedVHTGidManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMAddTSRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; +} tDot11fWMMAddTSRequest; + +#define DOT11F_WMMADDTSREQUEST ( 59 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSRequest *pFrm); +tANI_U32 dot11fPackWMMAddTSRequest(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMAddTSResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; + tDot11fIEESETrafStrmMet ESETrafStrmMet; +} tDot11fWMMAddTSResponse; + +#define DOT11F_WMMADDTSRESPONSE ( 60 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSResponse *pFrm); +tANI_U32 dot11fPackWMMAddTSResponse(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMDelTS{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; +} tDot11fWMMDelTS; + +#define DOT11F_WMMDELTS ( 61 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMDelTS *pFrm); +tANI_U32 dot11fPackWMMDelTS(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMDelTSSize(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#endif /* DOT11F_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dphGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dphGlobal.h new file mode 100644 index 0000000000000..b31f2456fd66b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dphGlobal.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + + * Author: Sandesh Goel + + * Date: 02/25/02 + + * History:- + + * Date Modified by Modification Information + + * -------------------------------------------------------------------- + + * + + */ + + +#ifndef __DPH_GLOBAL_H__ + +#define __DPH_GLOBAL_H__ + + +#include "limGlobal.h" + +#include "sirMacProtDef.h" + +#include "sirMacPropExts.h" + +#include "sirApi.h" + + +/// Following determines whether statistics are maintained or not + +#define DPH_STATS + +/// STAID for Management frames + +#define DPH_USE_MGMT_STAID -1 + + +// Keep Alive frames + +#define DPH_NON_KEEPALIVE_FRAME 0 + +#define DPH_KEEPALIVE_FRAME 1 + +//DPH Hash Index for BSS(STA's Peer) on station. + +#define DPH_STA_HASH_INDEX_PEER 1 + + +#ifdef WLAN_FEATURE_11W +//DPH PMF SA Query state for station + +#define DPH_SA_QUERY_NOT_IN_PROGRESS 1 + +#define DPH_SA_QUERY_IN_PROGRESS 2 + +#define DPH_SA_QUERY_TIMED_OUT 3 +#endif + + +typedef struct sDphRateBasedCtr + +{ + + tANI_U32 hi; + + tANI_U32 lo; + +} tDphRateBasedCtr; + + +typedef struct sDphPhyRates + +{ + + tANI_U8 dataRateX2; + + tANI_U8 ackRateX2; + + tANI_U8 rtsRateX2; + +} tDphPhyRates; + + +typedef struct sDphIFSValues + +{ + + tANI_U8 sifs; + + tANI_U8 pifs; + + tANI_U8 difs; + + tANI_U8 preamble; + +} tDphIFSValues; + + +typedef struct sDphQosParams + +{ + + tANI_U8 addtsPresent; + + tSirAddtsReqInfo addts; + + tSirMacQosCapabilityStaIE capability; + +} tDphQosParams; + + +/// Queue attribute structure + +typedef struct sDphQueueAttr + +{ + + tANI_U16 valid : 1; + + tANI_U16 seqNum : 12; + + tANI_U16 ackPolicy : 2; + + tANI_U16 rsvd : 1; + +} tDphQueueAttr, *tpDphQueueAttr; + + + +typedef struct sCfgTrafficClass { + + //Use Block ACK on this STA/TID + + // Fields used to store the default TC parameters for this TSPEC. + + // They will be used when the TSPEC is deleted. + + tANI_U8 fDisableTx:1; + + tANI_U8 fDisableRx:1; + + tANI_U8 fUseBATx:1; + + tANI_U8 fUseBARx:1; + + + // 1: expect to see frames with compressed BA coming from this peer MAC + + tANI_U8 fRxCompBA:1; + + tANI_U8 fTxCompBA:1; + + + // immediate ACK or delayed ACK for frames from this peer MAC + + tANI_U8 fRxBApolicy:1; + + + // immediate ACK or delayed ACK for frames to this peer MAC + + tANI_U8 fTxBApolicy:1; + + + //Initiator or recipient + + tANI_U8 role; + + + //Max # of MSDU received from this STA, negotiated at ADDBA + + // used for maintaining block ack state info + + tANI_U16 rxBufSize; + + + //Max # of MSDU send to this STA, negotiated at ADDBA + + tANI_U16 txBufSize; + + + //BA timeout negotiated at ADDBA. Unit: TU + + tANI_U16 tuTxBAWaitTimeout; //Time for Tx to wait for BA. 0 means no timeout + + + tANI_U16 tuRxBAWaitTimeout; //Time for Rx to wait for explicit/implicit BAR. 0 means no timeout + + +} tCfgTrafficClass; + + + +/// STA state node + +typedef struct sDphHashNode + +{ + + + //BYTE 0 + + // HASH ENTRY FIELDS NOT NEEDED IN HAL. + + /// This STA valid or not + + tANI_U8 valid : 1; + + tANI_U8 encPolicy : 3; + + tANI_U8 defaultKey : 1; + + tANI_U8 defaultKeyId : 2; + + tANI_U8 qosMode : 1; + + + //BYTE 1 + + tANI_U8 erpEnabled : 1; + + tANI_U8 added : 1; // This has been added to the dph hash table + + tANI_U8 linkTestOn : 1; + + tANI_U8 shortPreambleEnabled : 1; + + tANI_U8 shortSlotTimeEnabled : 1; + + tANI_U8 stopTx:1; + + tANI_U8 wmeEnabled: 1; // set if both ap and sta are wme capable + + tANI_U8 lleEnabled: 1; // set if both ap and sta are 11e capable + + + //BYTE 2 + + tANI_U8 wsmEnabled: 1; // set if both ap and sta are wsm capable + + tANI_U8 versionPresent:1; // station gave version info + + tANI_U8 burstEnableForce:1; // allow bursting regardless of qosMode + + tANI_U8 staAuthenticated:1; + + /// Whether the peer is ANI or not + + tANI_U8 aniPeer:1; + + tANI_U8 titanPeer:1; // flag to indicate if its a titan peer + + tANI_U8 fAniCount:1; + + tANI_U8 rmfEnabled:1; + + + /// Fragmentation size + + tANI_U16 fragSize; + + + /// LIM state + + tLimMlmStaContext mlmStaContext; + + + /// Number of Tim to wait if the STA doesn't respond / fetch data + + tANI_U8 timWaitCount; + + + /// Number of Successfull MPDU's being sent + + tANI_U32 curTxMpduCnt; + + + + + /// number of consecutive TIMs sent without response + + tANI_U8 numTimSent; + + + // qos parameter info + + tDphQosParams qos; + + + // station version info - valid only if versionPresent is set + + tSirMacPropVersion version; + + // station proprietary capability + + tANI_U16 propCapability; + + +#ifdef PLM_WDS + + tANI_U8 wdsIndex; + + tANI_U8 wdsPeerBeaconSeen; + +#endif + + + //Taurus capabilities + + tANI_U16 baPolicyFlag; //BA Policy for each TID. + + + /* + + * All the legacy and airgo supported rates. + + */ + + tSirSupportedRates supportedRates; + + + tANI_U8 htGreenfield:1; + + tANI_U8 htShortGI40Mhz:1; + + tANI_U8 htShortGI20Mhz:1; + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + + tANI_U8 htDsssCckRate40MHzSupport:1; + + // L-SIG TXOP Protection used only if peer support available + + tANI_U8 htLsigTXOPProtection:1; + + // A-MPDU Density + + // 000 - No restriction + + // 001 - 1/8 usec + + // 010 - 1/4 usec + + // 011 - 1/2 usec + + // 100 - 1 usec + + // 101 - 2 usec + + // 110 - 4 usec + + // 111 - 8 usec + + // + + tANI_U8 htAMpduDensity:3; + + + + + //Set to 0 for 3839 octets + + //Set to 1 for 7935 octets + + tANI_U8 htMaxAmsduLength; + + + + + // MIMO Power Save + + tSirMacHTMIMOPowerSaveState htMIMOPSState; + + + // + + + // Maximum Rx A-MPDU factor + + tANI_U8 htMaxRxAMpduFactor:3; + + // + + // Recommended Tx Width Set + + // 0 - use 20 MHz channel (control channel) + + // 1 - use 40 Mhz channel + + // + + tANI_U8 htSupportedChannelWidthSet:1; + tANI_U8 htSecondaryChannelOffset:2; + tANI_U8 rsvd1:2; + + + /////////////////////////////////////////////////////////////////////// + + // DPH HASH ENTRY FIELDS NEEDED IN HAL ONLY + + /////////////////////////////////////////////////////////////////////// + + tANI_U8 dpuSig:4; // DPU signiture + + tANI_U8 staSig:4; // STA signature + + tANI_U8 staType; + + + tANI_U16 bssId; // BSSID + + tANI_U16 assocId; // Association ID + + + + + //This is the real sta index generated by HAL + + tANI_U16 staIndex; + + tANI_U8 staAddr[6]; + + /*The DPU signatures will be sent eventually to TL to help it determine the + + association to which a packet belongs to*/ + + /*Unicast DPU signature*/ + + tANI_U8 ucUcastSig; + + + /*Broadcast DPU signature*/ + + tANI_U8 ucBcastSig; + + + // + + // PE needs this info on a per-STA, per-TID basis + + // At any point in time, when this data is sampled, + + // it gives a measure of: + + // a) All the active bA sessions + + // b) And the BA configuration itself + + // + + tCfgTrafficClass tcCfg[STACFG_MAX_TC]; + + + // Block Ack state + + // This is used between PE and HAL only. + + // can be set to one of the values from the following enum + + /*typedef enum eLimBAState + + { + + eLIM_BA_STATE_IDLE, // we are not waiting for anything from HAL. + + eLIM_BA_STATE_WT_ADD_RSP, //We are waiting for Add rsponse from HAL. + + eLIM_BA_STATE_WT_DEL_RSP // We are waiting for Del response from HAL. + + } tLimBAState; */ + + + + + //BA state bitmap 2 bits per tid + + // BA state for tid i = (baState >> tid*2) & 0x3 + + tANI_U32 baState; + +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtSupportedChannelWidthSet; + tANI_U8 vhtSupportedRxNss; + tANI_U8 vhtBeamFormerCapable; +#endif + +#ifdef WLAN_FEATURE_11W + tANI_U8 pmfSaQueryState; + tANI_U8 pmfSaQueryRetryCount; + tANI_U16 pmfSaQueryCurrentTransId; + tANI_U16 pmfSaQueryStartTransId; + TX_TIMER pmfSaQueryTimer; +#endif + + tANI_U8 htLdpcCapable; + tANI_U8 vhtLdpcCapable; + +#ifdef FEATURE_WLAN_TDLS + tANI_U16 ht_caps; + tANI_U32 vht_caps; +#endif + + /* Timing and fine Timing measurement capability clubbed together */ + tANI_U8 timingMeasCap; + /* key installed for this STA or not in the firmware */ + tANI_U8 isKeyInstalled; + + /* When a station with already an existing dph entry tries to + + * associate again, the old dph entry will be zeroed out except + + * for the next pointer. The next pointer must be defined at the + + * end of the structure. + + */ + + struct sDphHashNode *next; + + +} tDphHashNode, *tpDphHashNode; + + +#include "dphHashTable.h" + + +// ------------------------------------------------------------------- + + +typedef struct sAniSirDph + +{ + + /// The hash table object + + dphHashTableClass dphHashTable; + +} tAniSirDph, *tpAniSirDph; + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/parserApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/parserApi.h new file mode 100644 index 0000000000000..9cb7a53f5f574 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/parserApi.h @@ -0,0 +1,998 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file parserApi.h contains the definitions used + * for parsing received 802.11 frames + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __PARSE_H__ +#define __PARSE_H__ + +#include +#include "sirMacPropExts.h" +#include "dot11f.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" + +#define COUNTRY_STRING_LENGTH ( 3 ) +#define COUNTRY_INFO_MAX_CHANNEL ( 84 ) +#define MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE (COUNTRY_STRING_LENGTH * COUNTRY_INFO_MAX_CHANNEL) +#define HIGHEST_24GHZ_CHANNEL_NUM ( 14 ) + +#define IS_24G_CH(__chNum) ((__chNum > 0) && (__chNum < 15)) +#define IS_5G_CH(__chNum) ((__chNum >= 36) && (__chNum <= 165)) +#define IS_2X2_CHAIN(__chain) ((__chain & 0x3) == 0x3) +#define DISABLE_NSS2_MCS 0xC + +typedef struct sSirCountryInformation +{ + tANI_U8 countryString[COUNTRY_STRING_LENGTH]; + tANI_U8 numIntervals; //number of channel intervals + struct channelPowerLim + { + tANI_U8 channelNumber; + tANI_U8 numChannel; + tANI_U8 maxTransmitPower; + } channelTransmitPower[COUNTRY_INFO_MAX_CHANNEL]; +} tSirCountryInformation,*tpSirCountryInformation; + + +/// Structure common to Beaons & Probe Responses +typedef struct sSirProbeRespBeacon +{ + tSirMacTimeStamp timeStamp; + tANI_U16 beaconInterval; + tSirMacCapabilityInfo capabilityInfo; + + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirMacChanNum channelNumber; + tSirMacCfParamSet cfParamSet; + tSirMacTim tim; + tSirMacEdcaParamSetIE edcaParams; + tSirMacQosCapabilityIE qosCapability; + + tSirCountryInformation countryInfoParam; + tSirMacWpaInfo wpa; + tSirMacRsnInfo rsn; + + tSirMacErpInfo erpIEInfo; + + tSirPropIEStruct propIEinfo; + tDot11fIEPowerConstraints localPowerConstraint; + tDot11fIETPCReport tpcReport; + tDot11fIEChanSwitchAnn channelSwitchIE; + tDot11fIEExtChanSwitchAnn extChannelSwitchIE; + tSirMacAddr bssid; + tDot11fIEQuiet quietIE; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEP2PProbeRes P2PProbeRes; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdie[SIR_MDIE_SIZE]; +#endif +#ifdef FEATURE_WLAN_ESE + tDot11fIEESETxmitPower eseTxPwr; + tDot11fIEQBSSLoad QBSSLoad; +#endif + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + tANI_U8 cfPresent; + tANI_U8 dsParamsPresent; + tANI_U8 timPresent; + + tANI_U8 edcaPresent; + tANI_U8 qosCapabilityPresent; + tANI_U8 wmeEdcaPresent; + tANI_U8 wmeInfoPresent; + tANI_U8 wsmCapablePresent; + + tANI_U8 countryInfoPresent; + tANI_U8 wpaPresent; + tANI_U8 rsnPresent; + tANI_U8 erpPresent; + tANI_U8 channelSwitchPresent; + tANI_U8 extChannelSwitchPresent; + tANI_U8 quietIEPresent; + tANI_U8 tpcReportPresent; + tANI_U8 powerConstraintPresent; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdiePresent; +#endif + +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEOperatingMode OperatingMode; + tANI_U8 WiderBWChanSwitchAnnPresent; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; +#endif + tANI_U8 Vendor1IEPresent; + tANI_U8 Vendor2IEPresent; + tANI_U8 Vendor3IEPresent; + tDot11fIEIBSSParams IBSSParams; + +#ifdef FEATURE_WLAN_ESE + uint8_t is_ese_ver_ie_present; +#endif +} tSirProbeRespBeacon, *tpSirProbeRespBeacon; + +// probe Request structure +typedef struct sSirProbeReq +{ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tDot11fIEWscProbeReq probeReqWscIeInfo; + tDot11fIEHTCaps HTCaps; + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + tANI_U8 wscIePresent; + tANI_U8 p2pIePresent; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; +#endif + + +} tSirProbeReq, *tpSirProbeReq; + +/// Association Request structure (one day to be replaced by +/// tDot11fAssocRequest) +typedef struct sSirAssocReq +{ + + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 listenInterval; + tSirMacAddr currentApAddr; /* only in reassoc frames */ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + + tSirAddtsReqInfo addtsReq; + tSirMacQosCapabilityStaIE qosCapability; + + tSirMacWpaInfo wpa; + tSirMacRsnInfo rsn; + tSirAddie addIE; + + tSirPropIEStruct propIEinfo; + tSirMacPowerCapabilityIE powerCapability; + tSirMacSupportedChannelIE supportedChannels; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + /// This is set if the frame is a reassoc request: + tANI_U8 reassocRequest; + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + + tANI_U8 wmeInfoPresent; + tANI_U8 qosCapabilityPresent; + tANI_U8 addtsPresent; + tANI_U8 wsmCapablePresent; + + tANI_U8 wpaPresent; + tANI_U8 rsnPresent; + tANI_U8 addIEPresent; + + tANI_U8 powerCapabilityPresent; + tANI_U8 supportedChannelsPresent; + // keeing copy of assoction request received, this is + // required for indicating the frame to upper layers + tANI_U32 assocReqFrameLength; + tANI_U8* assocReqFrame; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEOperatingMode operMode; +#endif + tDot11fIEExtCap ExtCap; +} tSirAssocReq, *tpSirAssocReq; + + +/// Association Response structure (one day to be replaced by +/// tDot11fAssocRequest) +typedef struct sSirAssocRsp +{ + + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 aid; + tANI_U16 statusCode; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirPropIEStruct propIEinfo; + tSirMacEdcaParamSetIE edca; + tSirAddtsRspInfo addtsRsp; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; +#if defined WLAN_FEATURE_VOWIFI_11R + tDot11fIEFTInfo FTInfo; + tANI_U8 mdie[SIR_MDIE_SIZE]; + tANI_U8 num_RICData; + tDot11fIERICDataDesc RICData[2]; +#endif + +#ifdef FEATURE_WLAN_ESE + tANI_U8 num_tspecs; + tDot11fIEWMMTSPEC TSPECInfo[SIR_ESE_MAX_TSPEC_IES]; + tSirMacESETSMIE tsmIE; +#endif + + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + + tANI_U8 edcaPresent; + tANI_U8 wmeEdcaPresent; + tANI_U8 addtsPresent; + tANI_U8 wsmCapablePresent; +#if defined WLAN_FEATURE_VOWIFI_11R + tANI_U8 ftinfoPresent; + tANI_U8 mdiePresent; + tANI_U8 ricPresent; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 tspecPresent; + tANI_U8 tsmPresent; +#endif +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; +#endif + tDot11fIEExtCap ExtCap; + tSirQosMapSet QosMapSet; +#ifdef WLAN_FEATURE_11W + tDot11fIETimeoutInterval TimeoutInterval; +#endif +} tSirAssocRsp, *tpSirAssocRsp; + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +// Structure to hold ESE Beacon report mandatory IEs +typedef struct sSirEseBcnReportMandatoryIe +{ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacFHParamSet fhParamSet; + tSirMacDsParamSetIE dsParamSet; + tSirMacCfParamSet cfParamSet; + tSirMacIBSSParams ibssParamSet; + tSirMacTim tim; + tSirMacRRMEnabledCap rmEnabledCapabilities; + + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 fhParamPresent; + tANI_U8 dsParamsPresent; + tANI_U8 cfPresent; + tANI_U8 ibssParamPresent; + tANI_U8 timPresent; + tANI_U8 rrmPresent; +} tSirEseBcnReportMandatoryIe, *tpSirEseBcnReportMandatoryIe; +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +struct s_ext_cap { + uint8_t bssCoexistMgmtSupport: 1; + uint8_t reserved1: 1; + uint8_t extChanSwitch: 1; + uint8_t reserved2: 1; + uint8_t psmpCap: 1; + uint8_t reserved3: 1; + uint8_t spsmpCap: 1; + uint8_t event: 1; + uint8_t diagnostics: 1; + uint8_t multiDiagnostics: 1; + uint8_t locTracking: 1; + uint8_t FMS: 1; + uint8_t proxyARPService: 1; + uint8_t coLocIntfReporting: 1; + uint8_t civicLoc: 1; + uint8_t geospatialLoc: 1; + uint8_t TFS: 1; + uint8_t wnmSleepMode: 1; + uint8_t timBroadcast: 1; + uint8_t bssTransition: 1; + uint8_t qosTrafficCap: 1; + uint8_t acStaCnt: 1; + uint8_t multiBSSID: 1; + uint8_t timingMeas: 1; + uint8_t chanUsage: 1; + uint8_t ssidList: 1; + uint8_t DMS: 1; + uint8_t UTCTSFOffset: 1; + uint8_t TDLSPeerUAPSDBufferSTA: 1; + uint8_t TDLSPeerPSMSupp: 1; + uint8_t TDLSChannelSwitching: 1; + uint8_t interworkingService: 1; + uint8_t qosMap: 1; + uint8_t EBR: 1; + uint8_t sspnInterface: 1; + uint8_t reserved4: 1; + uint8_t msgCFCap: 1; + uint8_t TDLSSupport: 1; + uint8_t TDLSProhibited: 1; + uint8_t TDLSChanSwitProhibited: 1; + uint8_t rejectUnadmittedTraffic: 1; + uint8_t serviceIntervalGranularity: 3; + uint8_t identifierLoc: 1; + uint8_t uapsdCoexistence: 1; + uint8_t wnmNotification: 1; + uint8_t QABcapbility: 1; + uint8_t UTF8SSID: 1; + uint8_t QMFActivated: 1; + uint8_t QMFreconAct: 1; + uint8_t RobustAVStreaming: 1; + uint8_t AdvancedGCR: 1; + uint8_t MeshGCR: 1; + uint8_t SCS: 1; + uint8_t QLoadReport: 1; + uint8_t AlternateEDCA: 1; + uint8_t UnprotTXOPneg: 1; + uint8_t ProtTXOPneg: 1; + uint8_t reserved6: 1; + uint8_t ProtQLoadReport: 1; + uint8_t TDLSWiderBW: 1; + uint8_t operModeNotification: 1; + uint8_t maxNumOfMSDU_bit1: 1; + uint8_t maxNumOfMSDU_bit2: 1; + uint8_t ChanSchMgmt: 1; + uint8_t GeoDBInbandEnSignal: 1; + uint8_t NwChanControl: 1; + uint8_t WhiteSpaceMap: 1; + uint8_t ChanAvailQuery: 1; + uint8_t fineTimingMeas: 1; + uint8_t reserved7: 1; +}; + +tANI_U8 +sirIsPropCapabilityEnabled(struct sAniSirGlobal *pMac, tANI_U32 bitnum); + +tSirRetStatus +sirGetCfgPropCaps(struct sAniSirGlobal *, tANI_U16 *); + +void dot11fLog(tpAniSirGlobal pMac, int nSev, const char *lpszFormat, ...); + +#define CFG_GET_INT(nStatus, pMac, nItem, cfg ) do { \ + (nStatus) = wlan_cfgGetInt( (pMac), (nItem), & (cfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return nStatus; \ + } \ + } while (0) + +#define CFG_GET_INT_NO_STATUS(nStatus, pMac, nItem, cfg ) do { \ + (nStatus) = wlan_cfgGetInt( (pMac), (nItem), & (cfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return; \ + } \ + } while (0) + +#define CFG_GET_STR(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \ + (nCfg) = (nMaxCfg); \ + (nStatus) = wlan_cfgGetStr( (pMac), (nItem), (cfg), & (nCfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return nStatus; \ + } \ + } while (0) + +#define CFG_GET_STR_NO_STATUS(nStatus, pMac, nItem, cfg, nCfg, \ + nMaxCfg) do { \ + (nCfg) = (nMaxCfg); \ + (nStatus) = wlan_cfgGetStr( (pMac), (nItem), (cfg), & (nCfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return; \ + } \ + } while (0) + +void swapBitField16(tANI_U16 in, tANI_U16 *out); + +// Currently implemented as "shims" between callers & the new framesc- +// generated code: + +tSirRetStatus +sirConvertProbeReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tpSirProbeReq probe); + +tSirRetStatus +sirConvertProbeFrame2Struct(struct sAniSirGlobal *pMac, tANI_U8 *frame, + tANI_U32 len, + tpSirProbeRespBeacon probe); + +tSirRetStatus +sirConvertAssocReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocReq assoc); + +tSirRetStatus +sirConvertAssocRespFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocRsp assoc); + +tSirRetStatus +sirConvertReassocReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocReq assoc); + +tSirRetStatus +sirParseBeaconIE(struct sAniSirGlobal *pMac, + tpSirProbeRespBeacon pBeaconStruct, + tANI_U8 *pPayload, + tANI_U32 payloadLength); + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +tSirRetStatus +sirFillBeaconMandatoryIEforEseBcnReport(tpAniSirGlobal pMac, + tANI_U8 *pPayload, + const tANI_U32 payloadLength, + tANI_U8 **outIeBuf, + tANI_U32 *pOutIeLen); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +tSirRetStatus +sirConvertBeaconFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *pBeaconFrame, + tpSirProbeRespBeacon pBeaconStruct); + +tSirRetStatus +sirConvertAuthFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirMacAuthFrameBody auth); + +tSirRetStatus +sirConvertAddtsReq2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirAddtsReqInfo *addTs); + +tSirRetStatus +sirConvertAddtsRsp2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirAddtsRspInfo *addts); + +tSirRetStatus +sirConvertDeltsReq2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirDeltsReqInfo *delTs); +tSirRetStatus +sirConvertQosMapConfigureFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirQosMapSet *pQosMapSet); + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +sirConvertTpcReqFrame2Struct(struct sAniSirGlobal *, tANI_U8 *, + tpSirMacTpcReqActionFrame, tANI_U32); + +tSirRetStatus +sirConvertMeasReqFrame2Struct(struct sAniSirGlobal *, tANI_U8 *, + tpSirMacMeasReqActionFrame, tANI_U32); +#endif + + +/** + * \brief Populated a tDot11fFfCapabilities + * + * \sa PopulatedDot11fCapabilities2 + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pDot11f Address of a tDot11fFfCapabilities to be filled in + * + * + * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled, we'll clear the QOS + * bit in pDot11f + * + * + */ + +tSirRetStatus +PopulateDot11fCapabilities(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpPESession psessionEntry); + +/** + * \brief Populated a tDot11fFfCapabilities + * + * \sa PopulatedDot11fCapabilities2 + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pDot11f Address of a tDot11fFfCapabilities to be filled in + * + * \param pSta Pointer to a tDphHashNode representing a peer + * + * + * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled on our peer, we'll + * clear the QOS bit in pDot11f + * + * + */ + +struct sDphHashNode; + +tSirRetStatus +PopulateDot11fCapabilities2(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + struct sDphHashNode *pSta, + tpPESession psessionEntry); + +/// Populate a tDot11fIEChanSwitchAnn +void +PopulateDot11fChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEChanSwitchAnn *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11fIEChanSwitchAnn +void +PopulateDot11fExtChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEExtChanSwitchAnn *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11fIEChannelSwitchWrapper +void +PopulateDot11fChanSwitchWrapper(tpAniSirGlobal pMac, + tDot11fIEChannelSwitchWrapper *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11fIECountry +tSirRetStatus +PopulateDot11fCountry(tpAniSirGlobal pMac, + tDot11fIECountry *pDot11f, tpPESession psessionEntry); + +/// Populated a PopulateDot11fDSParams +tSirRetStatus +PopulateDot11fDSParams(tpAniSirGlobal pMac, + tDot11fIEDSParams *pDot11f, tANI_U8 channel, + tpPESession psessionEntry); + + +/// Populated a tDot11fIEEDCAParamSet +void +PopulateDot11fEDCAParamSet(tpAniSirGlobal pMac, + tDot11fIEEDCAParamSet *pDot11f, + tpPESession psessionEntry); + +tSirRetStatus +PopulateDot11fERPInfo(tpAniSirGlobal pMac, + tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry); + +tSirRetStatus +PopulateDot11fExtSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, tDot11fIEExtSuppRates *pDot11f, + tpPESession psessionEntry); + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus +PopulateDot11fBeaconReport(tpAniSirGlobal pMac, + tDot11fIEMeasurementReport *pDot11f, + tSirMacBeaconReport *pBeaconReport ); +#endif + +/** + * \brief Populate a tDot11fIEExtSuppRates + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param nChannelNum Channel on which the enclosing frame will be going out + * + * \param pDot11f Address of a tDot11fIEExtSuppRates struct to be filled in. + * + * + * This method is a NOP if the channel is greater than 14. + * + * + */ + +tSirRetStatus +PopulateDot11fExtSuppRates1(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f); + +tSirRetStatus +PopulateDot11fHCF(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEHCF *pDot11f); + +tSirRetStatus +PopulateDot11fHTCaps(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEHTCaps *pDot11f); + +tSirRetStatus +PopulateDot11fHTInfo(tpAniSirGlobal pMac, + tDot11fIEHTInfo *pDot11f, + tpPESession psessionEntry); + +void PopulateDot11fIBSSParams(tpAniSirGlobal pMac, + tDot11fIEIBSSParams *pDot11f, tpPESession psessionEntry); + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +PopulateDot11fMeasurementReport0(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); + +/// Populate a tDot11fIEMeasurementReport when the report type is CCA +tSirRetStatus +PopulateDot11fMeasurementReport1(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); + +/// Populate a tDot11fIEMeasurementReport when the report type is RPI Hist +tSirRetStatus +PopulateDot11fMeasurementReport2(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); +#endif //ANI_SUPPORT_11H + +/// Populate a tDot11fIEPowerCaps +void +PopulateDot11fPowerCaps(tpAniSirGlobal pMac, + tDot11fIEPowerCaps *pCaps, + tANI_U8 nAssocType,tpPESession psessionEntry); + +/// Populate a tDot11fIEPowerConstraints +tSirRetStatus +PopulateDot11fPowerConstraints(tpAniSirGlobal pMac, + tDot11fIEPowerConstraints *pDot11f); + +tSirRetStatus +PopulateDot11fPropCapability(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropCapability *pDot11f); + +void +PopulateDot11fPropChannSwitchAnn(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropChannSwitchAnn *pDot11f); + +void +PopulateDot11fPropEDCAParams(tpAniSirGlobal pMac, + tANI_U16 caps, + tDot11fIEPropEDCAParams *pDot11f); + +tSirRetStatus +PopulateDot11fPropSuppRates(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropSuppRates *pDot11f); + +void +PopulateDot11fQOSCapsAp(tpAniSirGlobal pMac, + tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry); + +void +PopulateDot11fQOSCapsStation(tpAniSirGlobal pMac, + tDot11fIEQOSCapsStation *pDot11f); + +tSirRetStatus +PopulateDot11fRSN(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSN *pDot11f); + +tSirRetStatus +PopulateDot11fRSNOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSNOpaque *pDot11f ); + +#if defined(FEATURE_WLAN_WAPI) + +tSirRetStatus +PopulateDot11fWAPI(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPI *pDot11f); + +tSirRetStatus PopulateDot11fWAPIOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPIOpaque *pDot11f ); + +#endif //defined(FEATURE_WLAN_WAPI) + +/// Populate a tDot11fIESSID given a tSirMacSSid +void +PopulateDot11fSSID(tpAniSirGlobal pMac, + tSirMacSSid *pInternal, + tDot11fIESSID *pDot11f); + +/// Populate a tDot11fIESSID from CFG +tSirRetStatus +PopulateDot11fSSID2(tpAniSirGlobal pMac, + tDot11fIESSID *pDot11f); + + +/** + * \brief Populate a tDot11fIESchedule + * + * \sa PopulateDot11fWMMSchedule + * + * + * \param pSchedule Address of a tSirMacScheduleIE struct + * + * \param pDot11f Address of a tDot11fIESchedule to be filled in + * + * + */ + +void +PopulateDot11fSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIESchedule *pDot11f); + +void +PopulateDot11fSuppChannels(tpAniSirGlobal pMac, + tDot11fIESuppChannels *pDot11f, + tANI_U8 nAssocType,tpPESession psessionEntry); + +/** + * \brief Populated a tDot11fIESuppRates + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param nChannelNum Channel the enclosing frame will be going out on; see + * below + * + * \param pDot11f Address of a tDot11fIESuppRates struct to be filled in. + * + * + * If nChannelNum is greater than 13, the supported rates will be + * WNI_CFG_SUPPORTED_RATES_11B. If it is less than or equal to 13, the + * supported rates will be WNI_CFG_SUPPORTED_RATES_11A. If nChannelNum is + * set to the sentinel value POPULATE_DOT11F_RATES_OPERATIONAL, the struct + * will be populated with WNI_CFG_OPERATIONAL_RATE_SET. + * + * + */ + +#define POPULATE_DOT11F_RATES_OPERATIONAL ( 0xff ) + +tSirRetStatus +PopulateDot11fSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIESuppRates *pDot11f,tpPESession); + +tSirRetStatus +populate_dot11f_rates_tdls(tpAniSirGlobal p_mac, + tDot11fIESuppRates *p_supp_rates, + tDot11fIEExtSuppRates *p_ext_supp_rates); + +tSirRetStatus PopulateDot11fTPCReport(tpAniSirGlobal pMac, + tDot11fIETPCReport *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11FfTSInfo +void PopulateDot11fTSInfo(tSirMacTSInfo *pInfo, + tDot11fFfTSInfo *pDot11f); + + +void PopulateDot11fWMM(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tDot11fIEWMMParams *pParams, + tDot11fIEWMMCaps *pCaps, + tpPESession psessionEntry); + +void PopulateDot11fWMMCaps(tDot11fIEWMMCaps *pCaps); + +#if defined(FEATURE_WLAN_ESE) +// Fill the ESE version IE +void PopulateDot11fESEVersion(tDot11fIEESEVersion *pESEVersion); +// Fill the Radio Management Capability +void PopulateDot11fESERadMgmtCap(tDot11fIEESERadMgmtCap *pESERadMgmtCap); +// Fill the CCKM IE +tSirRetStatus PopulateDot11fESECckmOpaque( tpAniSirGlobal pMac, + tpSirCCKMie pCCKMie, + tDot11fIEESECckmOpaque *pDot11f ); + +void PopulateDot11TSRSIE(tpAniSirGlobal pMac, + tSirMacESETSRSIE *pOld, + tDot11fIEESETrafStrmRateSet *pDot11f, + tANI_U8 rate_length); +void PopulateDot11fReAssocTspec(tpAniSirGlobal pMac, tDot11fReAssocRequest *pReassoc, tpPESession psessionEntry); +#endif + +void PopulateDot11fWMMInfoAp(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tpPESession psessionEntry); + +void PopulateDot11fWMMInfoStation(tpAniSirGlobal pMac, + tDot11fIEWMMInfoStation *pInfo); + +void PopulateDot11fWMMInfoStationPerSession(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEWMMInfoStation *pInfo); + +void PopulateDot11fWMMParams(tpAniSirGlobal pMac, + tDot11fIEWMMParams *pParams, + tpPESession psessionEntry); + +/** + * \brief Populate a tDot11fIEWMMSchedule + * + * \sa PopulatedDot11fSchedule + * + * + * \param pSchedule Address of a tSirMacScheduleIE struct + * + * \param pDot11f Address of a tDot11fIEWMMSchedule to be filled in + * + * + */ + +void +PopulateDot11fWMMSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIEWMMSchedule *pDot11f); + +tSirRetStatus +PopulateDot11fWPA(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPA *pDot11f); + +tSirRetStatus +PopulateDot11fWPAOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPAOpaque *pDot11f ); + +void +PopulateDot11fTSPEC(tSirMacTspecIE *pOld, + tDot11fIETSPEC *pDot11f); + +void +PopulateDot11fWMMTSPEC(tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pDot11f); + +tSirRetStatus +PopulateDot11fTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pDot11f); + +tSirRetStatus +PopulateDot11fWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pDot11f); + + +tSirRetStatus PopulateDot11fWsc(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus PopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus DePopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus PopulateDot11fProbeResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscProbeRes *pDot11f, tpPESession psessionEntry); +tSirRetStatus PopulateDot11fAssocResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscAssocRes *pDot11f, tpPESession psessionEntry); +tSirRetStatus PopulateDot11fBeaconWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscBeacon *pDot11f, tpPESession psessionEntry); + +tSirRetStatus PopulateDot11fWscInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + +tSirRetStatus PopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + +tSirRetStatus DePopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + + +tSirRetStatus PopulateDot11fAssocResWscIE(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq); + +tSirRetStatus PopulateDot11AssocResP2PIE(tpAniSirGlobal pMac, + tDot11fIEP2PAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq); + +tSirRetStatus PopulateDot11fWscInAssocRes(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f); + + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus PopulateDot11fWFATPC( tpAniSirGlobal pMac, + tDot11fIEWFATPC *pDot11f, tANI_U8 txPower, tANI_U8 linkMargin ); + +tSirRetStatus PopulateDot11fRRMIe( tpAniSirGlobal pMac, + tDot11fIERRMEnabledCap *pDot11f, + tpPESession psessionEntry ); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +void PopulateMDIE( tpAniSirGlobal pMac, + tDot11fIEMobilityDomain *pDot11f, tANI_U8 mdie[] ); +void PopulateFTInfo( tpAniSirGlobal pMac, + tDot11fIEFTInfo *pDot11f ); +#endif + +void PopulateDot11fAssocRspRates ( tpAniSirGlobal pMac, tDot11fIESuppRates *pSupp, + tDot11fIEExtSuppRates *pExt, tANI_U16 *_11bRates, tANI_U16 *_11aRates ); + +int FindIELocation( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tANI_U8 EID); +#endif + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +PopulateDot11fVHTCaps(tpAniSirGlobal pMac, tpPESession psessionEntry, + tDot11fIEVHTCaps *pDot11f); + +tSirRetStatus +PopulateDot11fVHTOperation(tpAniSirGlobal pMac, tDot11fIEVHTOperation *pDot11f); + +tSirRetStatus +PopulateDot11fVHTExtBssLoad(tpAniSirGlobal pMac, tDot11fIEVHTExtBssLoad *pDot11f); + +tSirRetStatus +PopulateDot11fExtCap(tpAniSirGlobal pMac, tANI_BOOLEAN isVHTEnabled, + tDot11fIEExtCap * pDot11f, tpPESession psessionEntry); + +tSirRetStatus +PopulateDot11fOperatingMode(tpAniSirGlobal pMac, tDot11fIEOperatingMode *pDot11f, tpPESession psessionEntry ); + +void +PopulateDot11fWiderBWChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEWiderBWChanSwitchAnn *pDot11f, + tpPESession psessionEntry); +#endif + +void PopulateDot11fTimeoutInterval( tpAniSirGlobal pMac, + tDot11fIETimeoutInterval *pDot11f, + tANI_U8 type, tANI_U32 value ); diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirCommon.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirCommon.h new file mode 100644 index 0000000000000..3e54eb334d2d6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirCommon.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sirCommon.h contains the common definitions used by all + * Firmware modules. + * + * Author: V. K. Kandarpa + * Date: 04/12/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIRCOMMON_H +#define __SIRCOMMON_H + +#include "sirApi.h" +#include "sirParams.h" +#include "VossWrapper.h" + +/* ********************************************* * + * * + * SIRIUS SYSTEM EXTERNAL GLOBALS * + * * + * ********************************************* */ + + +// All the following are resource definitions + +#endif /* __SIRCOMMON_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirDebug.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirDebug.h new file mode 100644 index 0000000000000..9407ee1f483fc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirDebug.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __POL_DEBUG_H__ +#define __POL_DEBUG_H__ + +#define LOGOFF 0 +#define LOGP 1 +#define LOGE 2 +#define LOGW 3 +#define LOG1 4 +#define LOG2 5 +#define LOG3 6 +#define LOG4 7 + +#ifdef WLAN_MDM_CODE_REDUCTION_OPT +#ifdef PE_DEBUG_LOGE +#define PELOGE(p) { p } +#else +#define PELOGE(p) { } +#endif + +#ifdef PE_DEBUG_LOGW +#define PELOGW(p) { p } +#else +#define PELOGW(p) { } +#endif + +#define PELOG1(p) { } +#define PELOG2(p) { } +#define PELOG3(p) { } +#define PELOG4(p) { } + + +#else /* WLAN_MDM_CODE_REDUCTION_OPT */ + +#ifdef PE_DEBUG_LOGE +#define PELOGE(p) { p } +#else +#define PELOGE(p) { } +#endif + +#ifdef PE_DEBUG_LOGW +#define PELOGW(p) { p } +#else +#define PELOGW(p) { } +#endif + +#ifdef PE_DEBUG_LOG1 +#define PELOG1(p) { p } +#else +#define PELOG1(p) { } +#endif + +#ifdef PE_DEBUG_LOG2 +#define PELOG2(p) { p } +#else +#define PELOG2(p) { } +#endif + +#ifdef PE_DEBUG_LOG3 +#define PELOG3(p) { p } +#else +#define PELOG3(p) { } +#endif + +#ifdef PE_DEBUG_LOG4 +#define PELOG4(p) { p } +#else +#define PELOG4(p) { } +#endif + +#endif /* WLAN_MDM_CODE_REDUCTION_OPT */ + +#define FL(x) "%s: %d: "\ + x, __func__, __LINE__ + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirParams.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirParams.h new file mode 100644 index 0000000000000..b07b86fba3ae7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sirParams.h @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file sirParams.h contains the common parameter definitions, which + * are not dependent on threadX API. These can be used by all Firmware + * modules. + * + * Author: Sandesh Goel + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIRPARAMS_H +#define __SIRPARAMS_H + +# include "sirTypes.h" + +// Firmware wide constants + +#define SIR_MAX_PACKET_SIZE 512 +#define SIR_MAX_NUM_CHANNELS 64 +#define SIR_MAX_NUM_STA_IN_IBSS 16 +#define SIR_ESE_MAX_MEAS_IE_REQS 8 + +typedef enum +{ + PHY_SINGLE_CHANNEL_CENTERED = 0, // 20MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, // 40MHz IF bandwidth with lower 20MHz supporting the primary channel + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, // 40MHz IF bandwidth with higher 20MHz supporting the primary channel +#ifdef WLAN_FEATURE_11AC + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + PHY_CHANNEL_BONDING_STATE_MAX = 11 +}ePhyChanBondState; + +#define MAX_BONDED_CHANNELS 4 + +#define SIR_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define SIR_MAX(a,b) (((a) > (b)) ? (a) : (b)) + +typedef enum { + MCC = 0, + P2P = 1, + DOT11AC = 2, + SLM_SESSIONIZATION = 3, + DOT11AC_OPMODE = 4, + SAP32STA = 5, + TDLS = 6, + P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7, + WLANACTIVE_OFFLOAD = 8, +#ifdef FEATURE_WLAN_EXTSCAN + EXTENDED_SCAN = 9, +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + PNO = 10, +#endif +#ifdef WLAN_FEATURE_NAN + NAN = 11, +#endif + RTT = 12, + WOW = 22, +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WLAN_ROAM_SCAN_OFFLOAD = 23, +#endif + IBSS_HEARTBEAT_OFFLOAD = 26, + WLAN_PERIODIC_TX_PTRN = 28, +#ifdef FEATURE_WLAN_TDLS + ADVANCE_TDLS = 29, + TDLS_OFF_CHANNEL = 30, +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + BATCH_SCAN = 31, +#endif + //MAX_FEATURE_SUPPORTED = 128 +} placeHolderInCapBitmap; + +typedef enum eSriLinkState { + eSIR_LINK_IDLE_STATE = 0, + eSIR_LINK_PREASSOC_STATE = 1, + eSIR_LINK_POSTASSOC_STATE = 2, + eSIR_LINK_AP_STATE = 3, + eSIR_LINK_IBSS_STATE = 4, + // BT-AMP Case + eSIR_LINK_BTAMP_PREASSOC_STATE = 5, + eSIR_LINK_BTAMP_POSTASSOC_STATE = 6, + eSIR_LINK_BTAMP_AP_STATE = 7, + eSIR_LINK_BTAMP_STA_STATE = 8, + + // Reserved for HAL internal use + eSIR_LINK_LEARN_STATE = 9, + eSIR_LINK_SCAN_STATE = 10, + eSIR_LINK_FINISH_SCAN_STATE = 11, + eSIR_LINK_INIT_CAL_STATE = 12, + eSIR_LINK_FINISH_CAL_STATE = 13, + eSIR_LINK_LISTEN_STATE = 14, + eSIR_LINK_SEND_ACTION_STATE = 15, + eSIR_LINK_DOWN_STATE = 16, +} tSirLinkState; + + +/// Message queue structure used across Sirius project. +/// NOTE: this structure should be multiples of a word size (4bytes) +/// as this is used in tx_queue where it expects to be multiples of 4 bytes. +typedef struct sSirMsgQ +{ + tANI_U16 type; + /* + * This field can be used as sequence number/dialog token for matching + * requests and responses. + */ + tANI_U16 reserved; + /** + * Based on the type either a bodyptr pointer into + * memory or bodyval as a 32 bit data is used. + * bodyptr: is always a freeable pointer, one should always + * make sure that bodyptr is always freeable. + * + * Messages should use either bodyptr or bodyval; not both !!!. + */ + void *bodyptr; + tANI_U32 bodyval; + + /* + * Some messages provide a callback function. The function signature + * must be agreed upon between the two entities exchanging the message + */ + void *callback; + +} tSirMsgQ, *tpSirMsgQ; + +/// Mailbox Message Structure Define +typedef struct sSirMbMsg +{ + tANI_U16 type; + + /** + * This length includes 4 bytes of header, that is, + * 2 bytes type + 2 bytes msgLen + n*4 bytes of data. + * This field is byte length. + */ + tANI_U16 msgLen; + + /** + * This is the first data word in the mailbox message. + * It is followed by n words of data. + * NOTE: data[1] is not a place holder to store data + * instead to dereference the message body. + */ + tANI_U32 data[1]; +} tSirMbMsg, *tpSirMbMsg; + +/// Mailbox Message Structure for P2P +typedef struct sSirMbMsgP2p +{ + tANI_U16 type; + + /** + * This length includes 4 bytes of header, that is, + * 2 bytes type + 2 bytes msgLen + n*4 bytes of data. + * This field is byte length. + */ + tANI_U16 msgLen; + + tANI_U8 sessionId; + tANI_U8 noack; + tANI_U16 wait; + + /** + * This is the first data word in the mailbox message. + * It is followed by n words of data. + * NOTE: data[1] is not a place holder to store data + * instead to dereference the message body. + */ + tANI_U32 data[1]; +} tSirMbMsgP2p, *tpSirMbMsgP2p; + + +/* ******************************************* * + * * + * SIRIUS MESSAGE TYPES * + * * + * ******************************************* */ + + +/* + * The following message types have bounds defined for each module for + * inter thread/module communications. + * Each module will get 256 message types in total. + * Note that message type definitions for mailbox messages for + * communication with Host are in wniApi.h file. + * + * Any addition/deletion to this message list should also be + * reflected in the halUtil_getMsgString() routine. + */ + +// HAL message types +#define SIR_HAL_MSG_TYPES_BEGIN (SIR_HAL_MODULE_ID << 8) +#define SIR_HAL_ITC_MSG_TYPES_BEGIN (SIR_HAL_MSG_TYPES_BEGIN+0x20) +#define SIR_HAL_RADAR_DETECTED_IND SIR_HAL_ITC_MSG_TYPES_BEGIN +#define SIR_HAL_WDT_KAM_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 1) +#define SIR_HAL_TIMER_TEMP_MEAS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 2) +#define SIR_HAL_TIMER_PERIODIC_STATS_COLLECT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 3) +#define SIR_HAL_CAL_REQ_NTF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 4) +#define SIR_HAL_MNT_OPEN_TPC_TEMP_MEAS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 5) +#define SIR_HAL_CCA_MONITOR_INTERVAL_TO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 6) +#define SIR_HAL_CCA_MONITOR_DURATION_TO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 7) +#define SIR_HAL_CCA_MONITOR_START (SIR_HAL_ITC_MSG_TYPES_BEGIN + 8) +#define SIR_HAL_CCA_MONITOR_STOP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 9) +#define SIR_HAL_CCA_CHANGE_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 10) +#define SIR_HAL_TIMER_WRAP_AROUND_STATS_COLLECT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 11) + +/* + * New Taurus related messages + */ +#define SIR_HAL_ADD_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 13) +#define SIR_HAL_ADD_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 14) +#define SIR_HAL_DELETE_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 15) +#define SIR_HAL_DELETE_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 16) +#define SIR_HAL_ADD_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 17) +#define SIR_HAL_ADD_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 18) +#define SIR_HAL_DELETE_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 19) +#define SIR_HAL_DELETE_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 20) +#define SIR_HAL_INIT_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 21) +#define SIR_HAL_INIT_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 22) +#define SIR_HAL_START_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 23) +#define SIR_HAL_START_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 24) +#define SIR_HAL_END_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 25) +#define SIR_HAL_END_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 26) +#define SIR_HAL_FINISH_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 27) +#define SIR_HAL_FINISH_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 28) +#define SIR_HAL_SEND_BEACON_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 29) +#define SIR_HAL_SEND_BEACON_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 30) + +#define SIR_HAL_INIT_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 31) +#define SIR_HAL_INIT_CFG_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 32) + +#define SIR_HAL_INIT_WM_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 33) +#define SIR_HAL_INIT_WM_CFG_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 34) + +#define SIR_HAL_SET_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 35) +#define SIR_HAL_SET_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 36) +#define SIR_HAL_SET_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 37) +#define SIR_HAL_SET_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 38) +#define SIR_HAL_DPU_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 39) +#define SIR_HAL_DPU_STATS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 40) +#define SIR_HAL_GET_DPUINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 41) +#define SIR_HAL_GET_DPUINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 42) + +#define SIR_HAL_UPDATE_EDCA_PROFILE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 43) + +#define SIR_HAL_UPDATE_STARATEINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 45) +#define SIR_HAL_UPDATE_STARATEINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 46) + +#define SIR_HAL_UPDATE_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 47) +#define SIR_HAL_UPDATE_CF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 48) +#define SIR_HAL_CHNL_SWITCH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 49) +#define SIR_HAL_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 50) +#define SIR_HAL_DEL_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 51) +#define SIR_HAL_SOFTMAC_TXSTAT_REPORT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 52) + +#define SIR_HAL_MBOX_SENDMSG_COMPLETE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 61) +#define SIR_HAL_EXIT_BMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 53) +#define SIR_HAL_EXIT_BMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 54) +#define SIR_HAL_EXIT_BMPS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 55) +#define SIR_HAL_ENTER_BMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 56) +#define SIR_HAL_ENTER_BMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 57) +#define SIR_HAL_BMPS_STATUS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 58) +#define SIR_HAL_MISSED_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 59) + +#define SIR_HAL_SWITCH_CHANNEL_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 60) +#define SIR_HAL_PWR_SAVE_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 62) + +#define SIR_HAL_REGISTER_PE_CALLBACK (SIR_HAL_ITC_MSG_TYPES_BEGIN + 63) +#define SIR_HAL_SOFTMAC_MEM_READREQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 64) +#define SIR_HAL_SOFTMAC_MEM_WRITEREQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 65) + +#define SIR_HAL_SOFTMAC_MEM_READRESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 66) +#define SIR_HAL_SOFTMAC_BULKREGWRITE_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 67) +#define SIR_HAL_SOFTMAC_BULKREGREAD_RESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 68) +#define SIR_HAL_SOFTMAC_HOSTMESG_MSGPROCESSRESULT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 69) + +#define SIR_HAL_ADDBA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 70) +#define SIR_HAL_ADDBA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 71) +#define SIR_HAL_DELBA_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 72) +#define SIR_HAL_DEL_BA_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 73) + +//message from sme to initiate delete block ack session. +#define SIR_HAL_DELBA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 74) +#define SIR_HAL_IBSS_STA_ADD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 75) +#define SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 76) +#define SIR_HAL_SET_LINK_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 77) +#define SIR_HAL_ENTER_IMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 78) +#define SIR_HAL_ENTER_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 79) +#define SIR_HAL_EXIT_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 80) +#define SIR_HAL_EXIT_IMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 81) +#define SIR_HAL_SOFTMAC_HOSTMESG_PS_STATUS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 82) +#define SIR_HAL_POSTPONE_ENTER_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 83) +#define SIR_HAL_STA_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 84) +#define SIR_HAL_GLOBAL_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 85) +#define SIR_HAL_AGGR_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 86) +#define SIR_HAL_STA_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 87) +#define SIR_HAL_GLOBAL_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 88) +#define SIR_HAL_AGGR_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89) +#define SIR_HAL_STAT_SUMM_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 90) +#define SIR_HAL_STAT_SUMM_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 92) +#define SIR_HAL_REMOVE_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 93) +#define SIR_HAL_REMOVE_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 94) +#define SIR_HAL_REMOVE_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 95) +#define SIR_HAL_REMOVE_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 96) +#define SIR_HAL_SET_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 97) +#define SIR_HAL_SET_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 98) +#define SIR_HAL_REMOVE_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 99) +#define SIR_HAL_REMOVE_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 100) +#define SIR_HAL_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101) +#define SIR_HAL_DPU_MIC_ERROR (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102) +#define SIR_HAL_TIMER_BA_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103) +#define SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 104) +#define SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 105) +#define SIR_HAL_TIMER_ADC_RSSI_STATS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 106) +#define SIR_HAL_MIC_FAILURE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 107) +#define SIR_HAL_UPDATE_UAPSD_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 108) +#define SIR_HAL_SET_MIMOPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 109) +#define SIR_HAL_SET_MIMOPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 110) +#define SIR_HAL_SYS_READY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 111) +#define SIR_HAL_SET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 112) +#define SIR_HAL_SET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 113) +#define SIR_HAL_GET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 114) +#define SIR_HAL_GET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 115) +#define SIR_HAL_GET_NOISE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 116) +#define SIR_HAL_GET_NOISE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 117) + +/* Messages to support transmit_halt and transmit_resume */ +#define SIR_HAL_TRANSMISSION_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 118) +/* Indication from LIM to HAL to Initialize radar interrupt */ +#define SIR_HAL_INIT_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 119) + +#define SIR_HAL_BEACON_PRE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 120) +#define SIR_HAL_ENTER_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 121) +#define SIR_HAL_ENTER_UAPSD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 122) +#define SIR_HAL_EXIT_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 123) +#define SIR_HAL_EXIT_UAPSD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 124) +#define SIR_HAL_LOW_RSSI_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 125) +#define SIR_HAL_BEACON_FILTER_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 126) +/// PE <-> HAL WOWL messages +#define SIR_HAL_WOWL_ADD_BCAST_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 127) +#define SIR_HAL_WOWL_DEL_BCAST_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 128) +#define SIR_HAL_WOWL_ENTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 129) +#define SIR_HAL_WOWL_ENTER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 130) +#define SIR_HAL_WOWL_EXIT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 131) +#define SIR_HAL_WOWL_EXIT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 132) +#define SIR_HAL_TX_COMPLETE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 133) +#define SIR_HAL_TIMER_RA_COLLECT_AND_ADAPT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 134) +/// PE <-> HAL statistics messages +#define SIR_HAL_GET_STATISTICS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 135) +#define SIR_HAL_GET_STATISTICS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 136) +#define SIR_HAL_SET_KEY_DONE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 137) + +/// PE <-> HAL BTC messages +#define SIR_HAL_BTC_SET_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 138) +#define SIR_HAL_SIGNAL_BT_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 139) +#define SIR_HAL_HANDLE_FW_MBOX_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 140) +#define SIR_HAL_SEND_PROBE_RSP_TMPL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 141) + +/* PE <-> HAL addr2 mismatch message */ +#define SIR_LIM_ADDR2_MISS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 142) +#ifdef FEATURE_OEM_DATA_SUPPORT +/* PE <-> HAL OEM_DATA RELATED MESSAGES */ +#define SIR_HAL_START_OEM_DATA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 143) +#define SIR_HAL_START_OEM_DATA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 144) +#define SIR_HAL_FINISH_OEM_DATA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 145) +#endif + +#define SIR_HAL_SET_MAX_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 146) +#define SIR_HAL_SET_MAX_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 147) + +#define SIR_HAL_SEND_MSG_COMPLETE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 148) + +/// PE <-> HAL Host Offload message +#define SIR_HAL_SET_HOST_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 149) + +#define SIR_HAL_ADD_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 150) +#define SIR_HAL_ADD_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 151) +#define SIR_HAL_DEL_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 152) +#define SIR_HAL_DEL_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153) +#define SIR_HAL_SIGNAL_BTAMP_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154) + +#define SIR_HAL_CFG_RXP_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155) +#define SIR_HAL_CFG_RXP_FILTER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 156) + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define SIR_HAL_AGGR_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 157) +#define SIR_HAL_AGGR_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 158) +#define SIR_HAL_AGGR_QOS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 159) +#define SIR_HAL_AGGR_QOS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160) +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* P2P <-> HAL P2P msg */ +#define SIR_HAL_SET_P2P_GO_NOA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) +#define SIR_HAL_P2P_NOA_ATTR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 162) +#define SIR_HAL_P2P_NOA_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 163) + +#define SIR_HAL_SET_LINK_STATE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 165) + + +#define SIR_HAL_WLAN_SUSPEND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 166) +#define SIR_HAL_WLAN_RESUME_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 167) + +/// PE <-> HAL Keep Alive message +#define SIR_HAL_SET_KEEP_ALIVE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 168) + +#ifdef WLAN_NS_OFFLOAD +#define SIR_HAL_SET_NS_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 169) +#endif //WLAN_NS_OFFLOAD + +#ifdef FEATURE_WLAN_SCAN_PNO +#define SIR_HAL_SET_PNO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 170) +#define SIR_HAL_SET_PNO_CHANGED_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 171) +#define SIR_HAL_UPDATE_SCAN_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 172) +#define SIR_HAL_SET_RSSI_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 173) +#endif // FEATURE_WLAN_SCAN_PNO + + +#define SIR_HAL_SET_TX_PER_TRACKING_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 174) + +#ifdef WLAN_FEATURE_PACKET_FILTERING +#define SIR_HAL_8023_MULTICAST_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 175) +#define SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 176) +#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 177) +#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 178) +#define SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 179) +#endif // WLAN_FEATURE_PACKET_FILTERING + +#define SIR_HAL_SET_POWER_PARAMS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 180) + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define SIR_HAL_GTK_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 181) +#define SIR_HAL_GTK_OFFLOAD_GETINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 182) +#define SIR_HAL_GTK_OFFLOAD_GETINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 183) +#endif //WLAN_FEATURE_GTK_OFFLOAD + +#ifdef FEATURE_WLAN_ESE +#define SIR_HAL_TSM_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 184) +#define SIR_HAL_TSM_STATS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 185) +#endif + + +#ifdef WLAN_WAKEUP_EVENTS +#define SIR_HAL_WAKE_REASON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 186) +#endif //WLAN_WAKEUP_EVENTS + +#define SIR_HAL_SET_TM_LEVEL_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 187) + +#ifdef WLAN_FEATURE_11AC +#define SIR_HAL_UPDATE_OP_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 188) +#endif + +#ifdef FEATURE_WLAN_TDLS +/// PE <-> HAL TDLS messages +#define SIR_HAL_TDLS_LINK_ESTABLISH (SIR_HAL_ITC_MSG_TYPES_BEGIN + 189) +#define SIR_HAL_TDLS_LINK_TEARDOWN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 190) +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_HAL_ROAM_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 191) +#define SIR_HAL_ROAM_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 192) +#endif +#define SIR_HAL_GET_ROAM_RSSI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 193) +#define SIR_HAL_GET_ROAM_RSSI_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194) + +#define SIR_HAL_TRAFFIC_STATS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 195) + +#ifdef WLAN_FEATURE_11W +#define SIR_HAL_EXCLUDE_UNENCRYPTED_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 196) +#endif +#ifdef FEATURE_WLAN_TDLS +/// PE <-> HAL TDLS messages +#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 197) +#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 198) +#define SIR_HAL_TDLS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 199) +#endif + +#define SIR_HAL_UPDATE_CHAN_LIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 200) +#define SIR_HAL_STOP_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 201) +#define SIR_HAL_STOP_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 202) +#define SIR_HAL_RX_SCAN_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 203) +#define SIR_HAL_DHCP_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 204) +#define SIR_HAL_DHCP_STOP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205) +#define SIR_HAL_IBSS_PEER_INACTIVITY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206) + +#define SIR_HAL_LPHB_CONF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207) +#define SIR_HAL_LPHB_WAIT_EXPIRE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208) + +#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209) +#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210) + +#define SIR_HAL_RATE_UPDATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 217) + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define SIR_HAL_SET_BATCH_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218) +#define SIR_HAL_SET_BATCH_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219) +#define SIR_HAL_STOP_BATCH_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220) +#define SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221) +#endif + + +#define SIR_HAL_START_ROAM_CANDIDATE_LOOKUP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222) + +#define SIR_HAL_CLI_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223) +#define SIR_HAL_CLI_GET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224) +#ifndef REMOVE_PKT_LOG +#define SIR_HAL_PKTLOG_ENABLE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225) +#endif +#ifdef FEATURE_WLAN_SCAN_PNO +#define SIR_HAL_SME_SCAN_CACHE_UPDATED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 226) +#endif +#define SIR_HAL_START_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 227) +#define SIR_HAL_START_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 228) +#define SIR_HAL_UPDATE_CHAN_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229) +#define SIR_CSA_OFFLOAD_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 231) + +#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \ + (SIR_HAL_ITC_MSG_TYPES_BEGIN + 232) +#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP \ + (SIR_HAL_ITC_MSG_TYPES_BEGIN + 233) + +#ifdef WLAN_FEATURE_11AC +#define SIR_HAL_UPDATE_MEMBERSHIP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 235) +#define SIR_HAL_UPDATE_USERPOS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 236) +#endif + +#ifdef FEATURE_WLAN_TDLS +#define SIR_HAL_UPDATE_FW_TDLS_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 237) +#define SIR_HAL_UPDATE_TDLS_PEER_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 238) +#define SIR_HAL_TDLS_SHOULD_DISCOVER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 239) +#define SIR_HAL_TDLS_SHOULD_TEARDOWN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 240) +#define SIR_HAL_TDLS_PEER_DISCONNECTED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 241) +#endif + +/* Handling of beacon tx indication from FW */ +#define SIR_HAL_BEACON_TX_SUCCESS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 242) +#define SIR_HAL_DFS_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 243) + +#define SIR_HAL_INIT_THERMAL_INFO_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 248) +#define SIR_HAL_SET_THERMAL_LEVEL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 249) + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define SIR_HAL_SET_PLM_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 250) +#endif + +#define SIR_HAL_SET_TX_POWER_LIMIT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 251) +#define SIR_HAL_SET_SAP_INTRABSS_DIS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 252) +#define SIR_HAL_FW_STATS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 253) + +#define SIR_HAL_MODEM_POWER_STATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 254) + +#define SIR_HAL_DISASSOC_TX_COMP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 255) +#define SIR_HAL_DEAUTH_TX_COMP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 256) + +#ifdef WLAN_FEATURE_11AC +#define SIR_HAL_UPDATE_RX_NSS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 257) +#endif + +#define SIR_HAL_VDEV_STOP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 258) + +#ifdef WLAN_FEATURE_STATS_EXT +#define SIR_HAL_STATS_EXT_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 259) +#define SIR_HAL_STATS_EXT_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 260) +#endif /* WLAN_FEATURE_STATS_EXT */ + +#define SIR_HAL_HIDE_SSID_VDEV_RESTART (SIR_HAL_ITC_MSG_TYPES_BEGIN + 261) + +#define SIR_HAL_VDEV_START_RSP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 262) +#define SIR_HAL_GET_LINK_SPEED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 263) + +#define SIR_HAL_ROAM_PREAUTH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 264) + +#define SIR_HAL_TBTT_UPDATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 265) + +#ifdef FEATURE_WLAN_EXTSCAN +#define SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 266) +#define SIR_HAL_EXTSCAN_START_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 267) +#define SIR_HAL_EXTSCAN_STOP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 268) +#define SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 269) +#define SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 270) +#define SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 271) +#define SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 272) +#define SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 273) +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef FEATURE_WLAN_CH_AVOID +#define SIR_HAL_CH_AVOID_UPDATE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 274) +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define SIR_HAL_LL_STATS_CLEAR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 275) +#define SIR_HAL_LL_STATS_SET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 276) +#define SIR_HAL_LL_STATS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 277) +#define SIR_HAL_LL_STATS_RESULTS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 278) +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 279) +#endif +#ifdef WLAN_FEATURE_NAN +#define SIR_HAL_NAN_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 280) +#endif /* WLAN_FEATURE_NAN */ + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +#define SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 281) +#endif + +#define SIR_HAL_SET_BASE_MACADDR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 282) + +#define SIR_HAL_UNIT_TEST_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 283) + +#define SIR_HAL_LINK_STATUS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 285) +#define SIR_HAL_GET_LINK_STATUS_RSP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 286) + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +#define SIR_HAL_CONFIG_EXT_WOW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 287) +#define SIR_HAL_CONFIG_APP_TYPE1_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 288) +#define SIR_HAL_CONFIG_APP_TYPE2_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 289) +#endif + +#define SIR_HAL_SET_SCAN_MAC_OUI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 291) + +#ifdef DHCP_SERVER_OFFLOAD +#define SIR_HAL_SET_DHCP_SERVER_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 292) +#endif /* DHCP_SERVER_OFFLOAD */ +#define SIR_HAL_LED_FLASHING_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 293) + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define SIR_HAL_ROAM_OFFLOAD_SYNCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 294) +#endif + +#ifdef FEATURE_WLAN_TDLS +#define SIR_HAL_TDLS_SET_OFFCHAN_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 295) +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 296) +#define SIR_HAL_ROAM_INVOKE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 297) +#endif + +#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) + +// CFG message types +#define SIR_CFG_MSG_TYPES_BEGIN (SIR_CFG_MODULE_ID << 8) +#define SIR_CFG_ITC_MSG_TYPES_BEGIN (SIR_CFG_MSG_TYPES_BEGIN+0xB0) +#define SIR_CFG_PARAM_UPDATE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN) +#define SIR_CFG_DOWNLOAD_COMPLETE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN + 1) +#define SIR_CFG_MSG_TYPES_END (SIR_CFG_MSG_TYPES_BEGIN+0xFF) + +// LIM message types +#define SIR_LIM_MSG_TYPES_BEGIN (SIR_LIM_MODULE_ID << 8) +#define SIR_LIM_ITC_MSG_TYPES_BEGIN (SIR_LIM_MSG_TYPES_BEGIN+0xB0) + +// Messages to/from HAL +// Removed as part of moving HAL down to FW + +// Message from ISR upon TFP retry interrupt +#define SIR_LIM_RETRY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 3) +// Message from BB Transport +#define SIR_BB_XPORT_MGMT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 4) +// UNUSED SIR_LIM_ITC_MSG_TYPES_BEGIN + 6 +// Message from ISR upon SP's Invalid session key interrupt +#define SIR_LIM_INV_KEY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 7) +// Message from ISR upon SP's Invalid key ID interrupt +#define SIR_LIM_KEY_ID_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 8) +// Message from ISR upon SP's Replay threshold reached interrupt +#define SIR_LIM_REPLAY_THRES_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 9) +// Message from HDD after the TD dummy packet is cleaned up +#define SIR_LIM_TD_DUMMY_CALLBACK_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xA) +// Message from SCH when the STA is ready to be deleted +#define SIR_LIM_SCH_CLEAN_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB) +// Message from ISR upon Radar Detection +#define SIR_LIM_RADAR_DETECT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC) + +///////////////////////////////////// +// message id Available +//////////////////////////////////// + + +// Message from Hal to send out a DEL-TS indication +#define SIR_LIM_DEL_TS_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE) +//Message from HAL to send BA global timer timeout +#define SIR_LIM_ADD_BA_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xF) +//Indication from HAL to delete all the BA sessions when the BA activity check timer is disabled +#define SIR_LIM_DEL_BA_ALL_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x10) +//Indication from HAL to delete Station context +#define SIR_LIM_DELETE_STA_CONTEXT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x11) +//Indication from HAL to delete BA +#define SIR_LIM_DEL_BA_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x12) +#define SIR_LIM_UPDATE_BEACON (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x13) + + +// LIM Timeout messages +#define SIR_LIM_TIMEOUT_MSG_START ((SIR_LIM_MODULE_ID << 8) + 0xD0) +#define SIR_LIM_MIN_CHANNEL_TIMEOUT SIR_LIM_TIMEOUT_MSG_START +#define SIR_LIM_MAX_CHANNEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 1) +#define SIR_LIM_JOIN_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 2) +#define SIR_LIM_AUTH_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 3) +#define SIR_LIM_AUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 4) +#define SIR_LIM_ASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 5) +#define SIR_LIM_REASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 6) +#define SIR_LIM_HEART_BEAT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 7) +// currently unused SIR_LIM_TIMEOUT_MSG_START + 0x8 +// Link Monitoring Messages +#define SIR_LIM_CHANNEL_SCAN_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xA) +#define SIR_LIM_PROBE_HB_FAILURE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xB) +#define SIR_LIM_ADDTS_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xC) +#define SIR_LIM_LINK_TEST_DURATION_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x13) +#define SIR_LIM_HASH_MISS_THRES_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x16) +#define SIR_LIM_CNF_WAIT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x17) +#define SIR_LIM_KEEPALIVE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x18) +#define SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x19) +#define SIR_LIM_CHANNEL_SWITCH_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1A) +#define SIR_LIM_QUIET_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1B) +#define SIR_LIM_QUIET_BSS_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1C) + +#define SIR_LIM_WPS_OVERLAP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1D) +#ifdef WLAN_FEATURE_VOWIFI_11R +#define SIR_LIM_FT_PREAUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1E) +#endif +#define SIR_LIM_REMAIN_CHN_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1F) +#define SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x20) + +#ifdef WMM_APSD +#define SIR_LIM_WMM_APSD_SP_START_MSG_TYPE (SIR_LIM_TIMEOUT_MSG_START + 0x21) +#define SIR_LIM_WMM_APSD_SP_END_MSG_TYPE (SIR_LIM_TIMEOUT_MSG_START + 0x22) +#endif +#define SIR_LIM_BEACON_GEN_IND (SIR_LIM_TIMEOUT_MSG_START + 0x23) +#define SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x24) +#ifdef FEATURE_WLAN_ESE +#define SIR_LIM_ESE_TSM_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x25) +#endif + +#define SIR_LIM_DISASSOC_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x26) +#define SIR_LIM_DEAUTH_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x27) +#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x28) + +#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C) + +#define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF) + +// SCH message types +#define SIR_SCH_MSG_TYPES_BEGIN (SIR_SCH_MODULE_ID << 8) +#define SIR_SCH_CHANNEL_SWITCH_REQUEST (SIR_SCH_MSG_TYPES_BEGIN) +#define SIR_SCH_START_SCAN_REQ (SIR_SCH_MSG_TYPES_BEGIN + 1) +#define SIR_SCH_START_SCAN_RSP (SIR_SCH_MSG_TYPES_BEGIN + 2) +#define SIR_SCH_END_SCAN_NTF (SIR_SCH_MSG_TYPES_BEGIN + 3) +#define SIR_SCH_MSG_TYPES_END (SIR_SCH_MSG_TYPES_BEGIN+0xFF) + +// PMM message types +#define SIR_PMM_MSG_TYPES_BEGIN (SIR_PMM_MODULE_ID << 8) +#define SIR_PMM_CHANGE_PM_MODE (SIR_PMM_MSG_TYPES_BEGIN) +#define SIR_PMM_CHANGE_IMPS_MODE (SIR_PMM_MSG_TYPES_BEGIN + 1) //for Idle mode power save +#define SIR_PMM_MSG_TYPES_END (SIR_PMM_MSG_TYPES_BEGIN+0xFF) + +// MNT message types +#define SIR_MNT_MSG_TYPES_BEGIN (SIR_MNT_MODULE_ID << 8) +#define SIR_MNT_RELEASE_BD (SIR_MNT_MSG_TYPES_BEGIN + 0) +#define SIR_MNT_MSG_TYPES_END (SIR_MNT_MSG_TYPES_BEGIN + 0xFF) + +// DVT message types +#define SIR_DVT_MSG_TYPES_BEGIN (SIR_DVT_MODULE_ID << 8) +#define SIR_DVT_ITC_MSG_TYPES_BEGIN (SIR_DVT_MSG_TYPES_BEGIN+0x0F) +#define SIR_DVT_MSG_TYPES_END (SIR_DVT_ITC_MSG_TYPES_BEGIN+0xFFF) + + +//PTT message types +#define SIR_PTT_MSG_TYPES_BEGIN 0x3000 +#define SIR_PTT_MSG_TYPES_END 0x3300 + + +/* ****************************************** * + * * + * EVENT TYPE Defintions * + * * + * ****************************************** */ + +// MMH Events that are used in other modules to post events to MMH +# define SIR_HAL_MMH_TXMB_READY_EVT 0x00000002 +# define SIR_HAL_MMH_RXMB_DONE_EVT 0x00000004 +# define SIR_HAL_MMH_MSGQ_NE_EVT 0x00000008 + +# define SIR_HSTEMUL_TXMB_DONE_EVT 0x00000100 +# define SIR_HSTEMUL_RXMB_READY_EVT 0x00000200 +# define SIR_HSTEMUL_MSGQ_NE_EVT 0x00000400 + +# define SIR_TST_XMIT_MSG_QS_EMPTY_EVT 0x00000080 + +//added for OBSS + +//Param Change Bitmap sent to HAL +#define PARAM_BCN_INTERVAL_CHANGED (1 << 0) +#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) +#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2) +#define PARAM_llACOEXIST_CHANGED (1 << 3) +#define PARAM_llBCOEXIST_CHANGED (1 << 4) +#define PARAM_llGCOEXIST_CHANGED (1 << 5) +#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6) +#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7) +#define PARAM_RIFS_MODE_CHANGED (1<<8) +#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9) +#define PARAM_OBSS_MODE_CHANGED (1<<10) +#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED|PARAM_SHORT_PREAMBLE_CHANGED|PARAM_SHORT_SLOT_TIME_CHANGED|PARAM_llACOEXIST_CHANGED |PARAM_llBCOEXIST_CHANGED|\ + PARAM_llGCOEXIST_CHANGED|PARAM_HT20MHZCOEXIST_CHANGED|PARAM_NON_GF_DEVICES_PRESENT_CHANGED|PARAM_RIFS_MODE_CHANGED|PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED| PARAM_OBSS_MODE_CHANGED) + + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sysGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sysGlobal.h new file mode 100644 index 0000000000000..375df2221f989 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/sysGlobal.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef __SYS_GLOBAL_H__ +#define __SYS_GLOBAL_H__ + +typedef struct sAniSirSys +{ + tANI_U32 abort; /* system is aborting and will be unloaded, only MMH thread is running */ + + tANI_U32 gSysFrameCount[4][16]; + tANI_U32 gSysBbtReceived; + tANI_U32 gSysBbtPostedToLim; + tANI_U32 gSysBbtPostedToSch; + tANI_U32 gSysBbtPostedToPmm; + tANI_U32 gSysBbtPostedToHal; + tANI_U32 gSysBbtDropped; + tANI_U32 gSysBbtNonLearnFrameInv; + tANI_U32 gSysBbtLearnFrameInv; + tANI_U32 gSysBbtCrcFail; + tANI_U32 gSysBbtDuplicates; + tANI_U32 gSysReleaseCount; + tANI_U32 probeError, probeBadSsid, probeIgnore, probeRespond; + + tANI_U32 gSysEnableLearnMode; + tANI_U32 gSysEnableScanMode; + tANI_U32 gSysEnableLinkMonitorMode; +} tAniSirSys, *tpAniSirSys; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsApi.h new file mode 100644 index 0000000000000..bc9e8cc4ea3ee --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsApi.h @@ -0,0 +1,738 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * + * Author: Kevin Nguyen + * Date: 02/27/02 + * History:- + * 02/12/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __UTILSAPI_H +#define __UTILSAPI_H + +#include +#include +#include "aniGlobal.h" +#include "utilsGlobal.h" +#include "VossWrapper.h" + +#define LOG_INDEX_FOR_MODULE( modId ) ( ( modId ) - LOG_FIRST_MODULE_ID ) +#define GET_MIN_VALUE(__val1, __val2) ((__val1 < __val2) ? __val1 : __val2) + +// The caller must check loglevel. This API assumes loglevel is good +extern void logDebug(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr, va_list marker); + +extern void logDbg(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr,...); + +extern tANI_U32 gPktAllocCnt, gPktFreeCnt; + +extern VOS_TRACE_LEVEL getVosDebugLevel(tANI_U32 debugLevel); + +/// Debug dumps +extern void logPrintf(tpAniSirGlobal, tANI_U32, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4); + +/// RTAI dump +extern int logRtaiDump(tpAniSirGlobal, tANI_U32, tANI_U32, tANI_U32, tANI_U32, tANI_U32, tANI_U8 *); + +/// Log initialization +extern tSirRetStatus logInit (tpAniSirGlobal); + +extern void +logDeinit(tpAniSirGlobal ); + +extern tSirRetStatus cfgInit(tpAniSirGlobal); +extern void cfgDeInit(tpAniSirGlobal); + +// ------------------------------------------------------------------- +/** + * sirDumpBuf() + * + * FUNCTION: + * This function is called to dump a buffer with a certain level + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf: buffer pointer + * @return None. + */ + +void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size); + + +// -------------------------------------------------------------------- +/** + * sirSwapU16() + * + * FUNCTION: + * This function is called to swap two U8s of an tANI_U16 value + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U16 value to be tANI_U8 swapped + * @return Swapped tANI_U16 value + */ + +static inline tANI_U16 +sirSwapU16(tANI_U16 val) +{ + return(((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8)); +}/*** end sirSwapU16() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU16ifNeeded() + * + * FUNCTION: + * This function is called to swap two U8s of an tANI_U16 value depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U16 value to be tANI_U8 swapped + * @return Swapped tANI_U16 value + */ + +static inline tANI_U16 +sirSwapU16ifNeeded(tANI_U16 val) +{ +#ifndef ANI_LITTLE_BYTE_ENDIAN + return sirSwapU16(val); +#else + return val; +#endif +}/*** end sirSwapU16ifNeeded() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU32() + * + * FUNCTION: + * This function is called to swap four U8s of an tANI_U32 value + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U32 value to be tANI_U8 swapped + * @return Swapped tANI_U32 value + */ + +static inline tANI_U32 +sirSwapU32(tANI_U32 val) +{ + return((val << 24) | + (val >> 24) | + ((val & 0x0000FF00) << 8) | + ((val & 0x00FF0000) >> 8)); +}/*** end sirSwapU32() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU32ifNeeded() + * + * FUNCTION: + * This function is called to swap U8s of an tANI_U32 value depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U32 value to be tANI_U8 swapped + * @return Swapped tANI_U32 value + */ + +static inline tANI_U32 +sirSwapU32ifNeeded(tANI_U32 val) +{ +#ifndef ANI_LITTLE_BYTE_ENDIAN + return sirSwapU32(val); +#else + return val; +#endif +}/*** end sirSwapU32ifNeeded() ***/ + + + + +// ------------------------------------------------------------------- +/** + * sirSwapU32Buf + * + * FUNCTION: + * It swaps N dwords into the same buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of tANI_U32 array + * @return void + * + */ + +static inline void +sirSwapU32Buf(tANI_U32 *ptr, tANI_U32 nWords) +{ + tANI_U32 i; + + for (i=0; i < nWords; i++) + ptr[i] = sirSwapU32(ptr[i]); +} + +// -------------------------------------------------------------------- +/** + * sirSwapU32BufIfNeeded() + * + * FUNCTION: + * This function is called to swap U8s of U32s in the buffer depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf Buffer that will get swapped + * @param nWords Number DWORDS will be swapped + * @return void + */ + +static inline void +sirSwapU32BufIfNeeded(tANI_U32* pBuf, tANI_U32 nWords) +{ +#ifdef ANI_LITTLE_BYTE_ENDIAN + sirSwapU32Buf(pBuf, nWords); +#endif +}/*** end sirSwapU32ifNeeded() ***/ + + +// -------------------------------------------------------------------- +/** + * sirSwapBDIfNeeded + * + * FUNCTION: + * Byte swap all the dwords in the BD, except the PHY/MAC headers + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBd BD that will get swapped + * @return void + */ + +static inline void +sirSwapBDIfNeeded(tANI_U32 *pBd) +{ + sirSwapU32BufIfNeeded(pBd, 6); + sirSwapU32BufIfNeeded(pBd+18, 14); +} + + +// ------------------------------------------------------------------- +/** + * sirStoreU16N + * + * FUNCTION: + * It stores a 16 bit number into the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU16N(tANI_U8 *ptr, tANI_U16 val) +{ + *ptr++ = (val >> 8) & 0xff; + *ptr = val & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32N + * + * FUNCTION: + * It stores a 32 bit number into the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU32N(tANI_U8 *ptr, tANI_U32 val) +{ + *ptr++ = (tANI_U8) (val >> 24) & 0xff; + *ptr++ = (tANI_U8) (val >> 16) & 0xff; + *ptr++ = (tANI_U8) (val >> 8) & 0xff; + *ptr = (tANI_U8) (val) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU16 + * + * FUNCTION: + * It stores a 16 bit number into the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU16(tANI_U8 *ptr, tANI_U16 val) +{ + *ptr++ = val & 0xff; + *ptr = (val >> 8) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32 + * + * FUNCTION: + * It stores a 32 bit number into the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU32(tANI_U8 *ptr, tANI_U32 val) +{ + *ptr++ = (tANI_U8) val & 0xff; + *ptr++ = (tANI_U8) (val >> 8) & 0xff; + *ptr++ = (tANI_U8) (val >> 16) & 0xff; + *ptr = (tANI_U8) (val >> 24) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32BufN + * + * FUNCTION: + * It stores a 32 bit number into the byte array in network byte order + * i.e. the least significant byte first. It performs the above operation + * on entire buffer and writes to the dst buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * Assumes that the pSrc buffer is of all tANI_U32 data type fields. + * + * NOTE: + * Must be used if all the fields in the buffer must be of tANI_U32 types. + * + * @param pDst address of destination byte array + * @param pSrc address of the source DWORD array + * @param length number of DWORDs + * @return None + */ + +static inline void +sirStoreBufN(tANI_U8* pDst, tANI_U32* pSrc, tANI_U32 length) +{ + while (length) + { + sirStoreU32N(pDst, *pSrc); + pDst += 4; + pSrc++; + length--; + } +} + +// ------------------------------------------------------------------- +/** + * sirReadU16N + * + * FUNCTION: + * It reads a 16 bit number from the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 16 bit value + */ + +static inline tANI_U16 +sirReadU16N(tANI_U8 *ptr) +{ + return(((*ptr) << 8) | + (*(ptr+1))); +} +/** + * sirSwapU32Buf + * + * FUNCTION: + * It swaps N dwords into the same buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of tANI_U32 array + * @return void + * + */ + +static inline void +sirSwapNStore(tANI_U32 *src, tANI_U32 *dst, tANI_U32 nWords) +{ + tANI_U32 i; + + for (i=0; i < nWords; i++) + dst[i] = sirSwapU32(src[i]); +} + +// ------------------------------------------------------------------- +/** + * sirReadU32N + * + * FUNCTION: + * It reads a 32 bit number from the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 32 bit value + */ + +static inline tANI_U32 +sirReadU32N(tANI_U8 *ptr) +{ + return((*(ptr) << 24) | + (*(ptr+1) << 16) | + (*(ptr+2) << 8) | + (*(ptr+3))); +} + +// ------------------------------------------------------------------- +/** + * sirReadU16 + * + * FUNCTION: + * It reads a 16 bit number from the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 16 bit value + */ + +static inline tANI_U16 +sirReadU16(tANI_U8 *ptr) +{ + return((*ptr) | + (*(ptr+1) << 8)); +} + +// ------------------------------------------------------------------- +/** + * sirReadU32 + * + * FUNCTION: + * It reads a 32 bit number from the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 32 bit value + */ + +static inline tANI_U32 +sirReadU32(tANI_U8 *ptr) +{ + return((*(ptr)) | + (*(ptr+1) << 8) | + (*(ptr+2) << 16) | + (*(ptr+3) << 24)); +} + +// ------------------------------------------------------------------- + + +/// Copy a MAC address from 'from' to 'to' +static inline void +sirCopyMacAddr(tANI_U8 to[], tANI_U8 from[]) +{ +#if defined( _X86_ ) + tANI_U32 align = (0x3 & ((tANI_U32) to | (tANI_U32) from )); + if( align ==0){ + *((tANI_U16 *) &(to[4])) = *((tANI_U16 *) &(from[4])); + *((tANI_U32 *) to) = *((tANI_U32 *) from); + }else if (align == 2){ + *((tANI_U16 *) &to[4]) = *((tANI_U16 *) &from[4]); + *((tANI_U16 *) &to[2]) = *((tANI_U16 *) &from[2]); + *((tANI_U16 *) &to[0]) = *((tANI_U16 *) &from[0]); + }else{ + to[5] = from[5]; + to[4] = from[4]; + to[3] = from[3]; + to[2] = from[2]; + to[1] = from[1]; + to[0] = from[0]; + } +#else + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; +#endif +} + +static inline tANI_U8 +sirCompareMacAddr(tANI_U8 addr1[], tANI_U8 addr2[]) +{ +#if defined( _X86_ ) + tANI_U32 align = (0x3 & ((tANI_U32) addr1 | (tANI_U32) addr2 )); + + if( align ==0){ + return ((*((tANI_U16 *) &(addr1[4])) == *((tANI_U16 *) &(addr2[4])))&& + (*((tANI_U32 *) addr1) == *((tANI_U32 *) addr2))); + }else if(align == 2){ + return ((*((tANI_U16 *) &addr1[4]) == *((tANI_U16 *) &addr2[4])) && + (*((tANI_U16 *) &addr1[2]) == *((tANI_U16 *) &addr2[2])) && + (*((tANI_U16 *) &addr1[0]) == *((tANI_U16 *) &addr2[0]))); + }else{ + return ( (addr1[5]==addr2[5])&& + (addr1[4]==addr2[4])&& + (addr1[3]==addr2[3])&& + (addr1[2]==addr2[2])&& + (addr1[1]==addr2[1])&& + (addr1[0]==addr2[0])); + } +#else + return ( (addr1[0]==addr2[0])&& + (addr1[1]==addr2[1])&& + (addr1[2]==addr2[2])&& + (addr1[3]==addr2[3])&& + (addr1[4]==addr2[4])&& + (addr1[5]==addr2[5])); +#endif +} + + +/* +* converts tANI_U16 CW value to 4 bit value to be inserted in IE +*/ +static inline tANI_U8 convertCW(tANI_U16 cw) +{ + tANI_U8 val = 0; + while (cw > 0) + { + val++; + cw >>= 1; + } + if (val > 15) + return 0xF; + return val; +} + +/* The user priority to AC mapping is such: + * UP(1, 2) ---> AC_BK(1) + * UP(0, 3) ---> AC_BE(0) + * UP(4, 5) ---> AC_VI(2) + * UP(6, 7) ---> AC_VO(3) + */ +#define WLAN_UP_TO_AC_MAP 0x33220110 +#define upToAc(up) ((WLAN_UP_TO_AC_MAP >> ((up) << 2)) & 0x03) + + +// ------------------------------------------------------------------- + +/// Parse the next IE in a message +extern tSirRetStatus sirParseNextIE(tpAniSirGlobal, tANI_U8 *pPayload, + tANI_U16 payloadLength, tANI_S16 lastType, + tANI_U8 *pType, tANI_U8 *pLength); + +/// Check if the given channel is 11b channel +#define SIR_IS_CHANNEL_11B(chId) (chId <= 14) + +// ------------------------------------------------------------------- +/** + * halRoundS32 + * + * FUNCTION: + * Performs integer rounding like returns 12346 for 123456 or -12346 for -123456 + * Note that a decimal place is lost. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param tANI_S32 input + * @return rounded number + */ +static inline tANI_S32 +halRoundS32(tANI_S32 p) +{ + tANI_S32 k, i, j; + + i = p/10; + j = p%10; + if (p > 0) + k = i + (j > 4 ? 1 : 0); + else if (p < 0) + k = i + (j < -5 ? -1 : 0); + else + k = p; + + return(k); +} + +// New functions for endianess conversion +#ifdef ANI_LITTLE_BYTE_ENDIAN +#define ani_cpu_to_be16(x) sirSwapU16((x)) +#define ani_cpu_to_le16(x) (x) +#define ani_cpu_to_be32(x) sirSwapU32((x)) +#define ani_cpu_to_le32(x) (x) +#else // ANI_LITTLE_BYTE_ENDIAN +#define ani_cpu_to_be16(x) (x) +#define ani_cpu_to_le16(x) sirSwapU16((x)) +#define ani_cpu_to_be32(x) (x) +#define ani_cpu_to_le32(x) sirSwapU32((x)) +#endif // ANI_LITTLE_BYTE_ENDIAN + +#define ani_le16_to_cpu(x) ani_cpu_to_le16(x) +#define ani_le32_to_cpu(x) ani_cpu_to_le32(x) +#define ani_be16_to_cpu(x) ani_cpu_to_be16(x) +#define ani_be32_to_cpu(x) ani_cpu_to_be32(x) + +void ConverttoBigEndian(void *ptr, tANI_U16 size); +void CreateScanCtsFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tSirMacAddr selfMac); +void CreateScanDataNullFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, + tANI_U8 pwrMgmt, tSirMacAddr bssid, + tSirMacAddr selfMacAddr); +void CreateInitScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role); +void CreateFinishScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role); + +#endif /* __UTILSAPI_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsGlobal.h new file mode 100644 index 0000000000000..e700ff92819db --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/utilsGlobal.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __UTILS_GLOBAL_H__ +#define __UTILS_GLOBAL_H__ + +#include "sirParams.h" + +/* + * Current debug and event log level + */ +#define LOG_FIRST_MODULE_ID SIR_FIRST_MODULE_ID +#define LOG_LAST_MODULE_ID SIR_LAST_MODULE_ID +#define LOG_ENTRY_NUM (LOG_LAST_MODULE_ID - LOG_FIRST_MODULE_ID + 1) + +typedef struct sAniSirUtils +{ + tANI_U32 gLogEvtLevel[LOG_ENTRY_NUM]; + tANI_U32 gLogDbgLevel[LOG_ENTRY_NUM]; + +} tAniSirUtils, *tpAniSirUtils; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limAdmitControl.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limAdmitControl.h new file mode 100644 index 0000000000000..e1cecd63d900b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limAdmitControl.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Dinesh Upadhyay + * Date: 10/24/06 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_ADMIT_CONTROL_H__ +#define __LIM_ADMIT_CONTROL_H__ + +#include "sirCommon.h" +#include "sirMacProtDef.h" + +#include "aniGlobal.h" + +tSirRetStatus +limTspecFindByAssocId(tpAniSirGlobal, tANI_U16, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *); + +// Add TSPEC in lim local table +tSirRetStatus limTspecAdd( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tANI_U16 assocId, + tSirMacTspecIE *pTspec, + tANI_U32 interval, + tpLimTspecInfo *ppInfo); + + +// admit control interface +extern tSirRetStatus +limAdmitControlAddTS( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirAddtsReqInfo *addts, + tSirMacQosCapabilityStaIE *qos, + tANI_U16 assocId, + tANI_U8 alloc, + tSirMacScheduleIE *pSch, + tANI_U8 *pTspecIdx ,//index to the lim tspec table. + tpPESession psessionEntry + ); + +static inline tSirRetStatus +limAdmitControlAddSta( + tpAniSirGlobal pMac, + tANI_U8 *staAddr, + tANI_U8 alloc) +{ return eSIR_SUCCESS;} + +extern tSirRetStatus +limAdmitControlDeleteSta( + tpAniSirGlobal pMac, + tANI_U16 assocId); + +extern tSirRetStatus +limAdmitControlDeleteTS( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *tsinfo, + tANI_U8 *tsStatus, + tANI_U8 *tspecIdx); + +extern tSirRetStatus +limUpdateAdmitPolicy( + tpAniSirGlobal pMac); + +tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_ESE +tSirRetStatus limSendHalMsgAddTs(tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirMacTspecIE tspecIE, + tANI_U8 sessionId, + tANI_U16 tsm_interval); +#else +tSirRetStatus limSendHalMsgAddTs(tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirMacTspecIE tspecIE, + tANI_U8 sessionId); +#endif + +tSirRetStatus limSendHalMsgDelTs(tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirDeltsReqInfo delts, + tANI_U8 sessionId, + tANI_U8 *bssId); +void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limApi.h new file mode 100644 index 0000000000000..9f95e3c6926a1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limApi.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limApi.h contains the definitions exported by + * LIM module. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_API_H +#define __LIM_API_H +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "schGlobal.h" +#include "utilsApi.h" +#include "limGlobal.h" +#include "halMsgApi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_wda.h" + +/* Macro to count heartbeat */ +#define limResetHBPktCount(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB = 0) + +/* Useful macros for fetching various states in pMac->lim */ +/* gLimSystemRole */ +#define GET_LIM_SYSTEM_ROLE(psessionEntry) (psessionEntry->limSystemRole) +#define LIM_IS_AP_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_AP_ROLE) +#define LIM_IS_STA_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_ROLE) +#define LIM_IS_IBSS_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) +/* gLimSmeState */ +#define GET_LIM_SME_STATE(pMac) (pMac->lim.gLimSmeState) +#define SET_LIM_SME_STATE(pMac, state) (pMac->lim.gLimSmeState = state) +/* gLimMlmState */ +#define GET_LIM_MLM_STATE(pMac) (pMac->lim.gLimMlmState) +#define SET_LIM_MLM_STATE(pMac, state) (pMac->lim.gLimMlmState = state) +/*tpdphHashNode mlmStaContext*/ +#define GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs) (pStaDs->mlmStaContext.mlmState) +#define SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, state) (pStaDs->mlmStaContext.mlmState = state) +/* gLimQuietState */ +#define GET_LIM_QUIET_STATE(pMac) (pMac->lim.gLimSpecMgmt.quietState) +#define SET_LIM_QUIET_STATE(pMac, state) (pMac->lim.gLimSpecMgmt.quietState = state) +#define LIM_IS_CONNECTION_ACTIVE(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB) +/*pMac->lim.gLimProcessDefdMsgs*/ +#define GET_LIM_PROCESS_DEFD_MESGS(pMac) (pMac->lim.gLimProcessDefdMsgs) +#define SET_LIM_PROCESS_DEFD_MESGS(pMac, val) (pMac->lim.gLimProcessDefdMsgs = val) +// LIM exported function templates +#define LIM_IS_RADAR_DETECTED(pMac) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan) +#define LIM_SET_RADAR_DETECTED(pMac, val) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan = val) +#define LIM_MIN_BCN_PR_LENGTH 12 +#define LIM_BCN_PR_CAPABILITY_OFFSET 10 +typedef enum eMgmtFrmDropReason +{ + eMGMT_DROP_NO_DROP, + eMGMT_DROP_NOT_LAST_IBSS_BCN, + eMGMT_DROP_INFRA_BCN_IN_IBSS, + eMGMT_DROP_SCAN_MODE_FRAME, + eMGMT_DROP_NON_SCAN_MODE_FRAME, + eMGMT_DROP_INVALID_SIZE, +}tMgmtFrmDropReason; + + +/** + * Function to initialize LIM state machines. + * This called upon LIM thread creation. + */ +extern tSirRetStatus limInitialize(tpAniSirGlobal); +tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam); +tSirRetStatus peClose(tpAniSirGlobal pMac); +tSirRetStatus limStart(tpAniSirGlobal pMac); +tSirRetStatus peStart(tpAniSirGlobal pMac); +void peStop(tpAniSirGlobal pMac); +tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +tSirRetStatus peProcessMsg(tpAniSirGlobal pMac, tSirMsgQ* limMsg); +void limDumpInit(tpAniSirGlobal pMac); +/** + * Function to cleanup LIM state. + * This called upon reset/persona change etc + */ +extern void limCleanup(tpAniSirGlobal); +/// Function to post messages to LIM thread +extern tANI_U32 limPostMsgApi(tpAniSirGlobal, tSirMsgQ *); +/** + * Function to process messages posted to LIM thread + * and dispatch to various sub modules within LIM module. + */ +extern void limMessageProcessor(tpAniSirGlobal, tpSirMsgQ); +extern void limProcessMessages(tpAniSirGlobal, tpSirMsgQ); // DT test alt deferred 2 +/** + * Function to check the LIM state if system is in Scan/Learn state. + */ +extern tANI_U8 limIsSystemInScanState(tpAniSirGlobal); +/** + * Function to handle IBSS coalescing. + * Beacon Processing module to call this. + */ +extern tSirRetStatus limHandleIBSScoalescing(tpAniSirGlobal, + tpSchBeaconStruct, + tANI_U8 *,tpPESession); +/// Function used by other Sirius modules to read global SME state + static inline tLimSmeStates +limGetSmeState(tpAniSirGlobal pMac) { return pMac->lim.gLimSmeState; } +/// Function used by other Sirius modules to read global system role + static inline tLimSystemRole +limGetSystemRole(tpPESession psessionEntry) { return psessionEntry->limSystemRole; } +extern void limReceivedHBHandler(tpAniSirGlobal, tANI_U8, tpPESession); +extern void limCheckAndQuietBSS(tpAniSirGlobal); +/// Function to send WDS info to WSM if needed +extern void limProcessWdsInfo(tpAniSirGlobal, tSirPropIEStruct); +/// Function to initialize WDS info params +extern void limInitWdsInfoParams(tpAniSirGlobal); +/// Function that triggers STA context deletion +extern void limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + +#ifdef FEATURE_WLAN_TDLS +// Function that sends TDLS Del Sta indication to SME +extern void limSendSmeTDLSDelStaInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry, tANI_U16 reasonCode); +#endif + +/// Function that checks for change in AP's capabilties on STA +extern void limDetectChangeInApCapabilities(tpAniSirGlobal, + tpSirProbeRespBeacon,tpPESession); +tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeacon, + tpUpdateBeaconParams pBeaconParams,tpPESession); + +/// creates an addts request action frame and sends it out to staid +extern void limSendAddtsReq (tpAniSirGlobal pMac, tANI_U16 staid, tANI_U8 tsid, tANI_U8 userPrio, tANI_U8 wme); +/// creates a delts request action frame and sends it out to staid +extern void limSendDeltsReq (tpAniSirGlobal pMac, tANI_U16 staid, tANI_U8 tsid, tANI_U8 userPrio, tANI_U8 wme); +#ifdef WLAN_FEATURE_11AC +extern ePhyChanBondState limGet11ACPhyCBState(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 htSecondaryChannelOffset, tANI_U8 CenterChan,tpPESession ); +#endif +tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac); + +void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void limPsOffloadHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void +limSendHeartBeatTimeoutInd(tpAniSirGlobal pMac, tpPESession psessionEntry); +tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType); +void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +void limRoamOffloadSynchInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +#endif +/* ----------------------------------------------------------------------- */ +// These used to be in DPH +extern void limGetMyMacAddr(tpAniSirGlobal pMac, tANI_U8 *mac); +#define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled) +#define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled) +#define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled) +#define limGet11dMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->lim11dEnabled) +#define limGetAckPolicy(pMac, pVal) (*(pVal) = pMac->lim.ackPolicy) +/* ----------------------------------------------------------------------- */ +static inline void limGetPhyMode(tpAniSirGlobal pMac, tANI_U32 *phyMode, tpPESession psessionEntry) +{ + *phyMode = psessionEntry ? psessionEntry->gLimPhyMode : pMac->lim.gLimPhyMode; +} + +/* ----------------------------------------------------------------------- */ +static inline void limGetRfBand(tpAniSirGlobal pMac, tSirRFBand *band, tpPESession psessionEntry) +{ + *band = psessionEntry ? psessionEntry->limRFBand : SIR_BAND_UNKNOWN; +} + +/*-------------------------------------------------------------------------- + + \brief peProcessMessages() - Message Processor for PE + + Voss calls this function to dispatch the message to PE + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ +tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +/** ------------------------------------------------------------- +\fn peFreeMsg +\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs) +\ to free a given PE message on the TX and MC thread. +\ This happens when there are messages pending in the PE +\ queue when system is being stopped and reset. +\param tpAniSirGlobal pMac +\param tSirMsgQ pMsg +\return none +-----------------------------------------------------------------*/ +v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg); + +/*-------------------------------------------------------------------------- + + \brief limRemainOnChnRsp() - API for sending remain on channel response. + + LIM calls this api to send the remain on channel response to SME. + + \param pMac - Pointer to Global MAC structure + \param status - status of the response + \param data - pointer to msg + + \return void + + --------------------------------------------------------------------------*/ +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); + +/*-------------------------------------------------------------------------- + + \brief limProcessAbortScanInd() - function for sending abort scan indication. + + LIM calls this function for sending abort scan indication. + + \param pMac - Pointer to Global MAC structure + + \return void + + --------------------------------------------------------------------------*/ +void limProcessAbortScanInd(tpAniSirGlobal pMac, tANI_U8 sessionId); + +/************************************************************/ +#endif /* __LIM_API_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFT.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFT.h new file mode 100644 index 0000000000000..1f81bf8d293f9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFT.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if defined WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + Macros and Function prototypes FT and 802.11R purposes + + ========================================================================*/ + +#ifndef __LIMFT_H__ +#define __LIMFT_H__ + + +#include +#include +#include +#include +#include + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +void limFTOpen(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limFTCleanup(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limFTCleanupPreAuthInfo(tpAniSirGlobal pMac, tpPESession psessionEntry); +int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); +void limPerformPostFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); +void limFTResumeLinkCb(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +void limPostFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry); +void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_len, + tpPESession psessionEntry); +void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf, + tpPESession psessionEntry); +void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac); +void limFillFTSession(tpAniSirGlobal pMac, tpSirBssDescription pbssDescription, + tpPESession pftSessionEntry, tpPESession psessionEntry); +tSirRetStatus limFTPrepareAddBssReq(tpAniSirGlobal pMac, tANI_U8 updateEntry, + tpPESession pftSessionEntry, + tpSirBssDescription bssDescription); +tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ); +tSirRetStatus limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ); +void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void limFTCleanupAllFTSessions(tpAniSirGlobal pMac); + +#endif /* __LIMFT_H__ */ + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFTDefs.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFTDefs.h new file mode 100644 index 0000000000000..9d3ba2a9dad89 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limFTDefs.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if defined WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + Macros and Function prototypes FT and 802.11R purposes + + ========================================================================*/ + +#ifndef __LIMFTDEFS_H__ +#define __LIMFTDEFS_H__ + + +#include +#include "halMsgApi.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define SIR_MDIE_SIZE 3 // MD ID(2 bytes), Capability(1 byte) +#define MAX_FTIE_SIZE 384 // Max size limited to 384, on acct. of IW custom events + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + FT Pre Auth Req SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthReq +{ + tANI_U16 messageType; // eWNI_SME_FT_PRE_AUTH_REQ + tANI_U16 length; + tANI_BOOLEAN bPreAuthRspProcessed; /* Track if response is processed for this request + We expect only one response per request. */ + tANI_U8 preAuthchannelNum; + tSirMacAddr currbssId; // BSSID currently associated to suspend the link + tSirMacAddr preAuthbssId; // BSSID to preauth to + tANI_U16 ft_ies_length; + tANI_U8 ft_ies[MAX_FTIE_SIZE]; + tpSirBssDescription pbssDescription; +} tSirFTPreAuthReq, *tpSirFTPreAuthReq; + +/*------------------------------------------------------------------------- + FT Pre Auth Rsp PE<->SME + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthRsp +{ + tANI_U16 messageType; // eWNI_SME_FT_PRE_AUTH_RSP + tANI_U16 length; + tANI_U8 smeSessionId; + tSirMacAddr preAuthbssId; // BSSID to preauth to + tSirRetStatus status; + tANI_U16 ft_ies_length; + tANI_U8 ft_ies[MAX_FTIE_SIZE]; + tANI_U16 ric_ies_length; + tANI_U8 ric_ies[MAX_FTIE_SIZE]; +} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp; + +/*-------------------------------------------------------------------------- + FT Pre Auth Rsp Key SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTUpdateKeyInfo +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U32 smeSessionId; + tSirMacAddr bssId; + tSirKeyMaterial keyMaterial; +} tSirFTUpdateKeyInfo, *tpSirFTUpdateKeyInfo; + +/*-------------------------------------------------------------------------- + FT Pre Auth Rsp Key SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthKeyInfo +{ + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tLimMlmSetKeysReq extSetStaKeyParam; //SetStaKeyParams for ext bss msg +} tSirFTPreAuthKeyInfo, *tpSirFTPreAuthKeyInfo; + +/*------------------------------------------------------------------------- + Global FT Information + ------------------------------------------------------------------------*/ +typedef struct sFTPEContext +{ + tpSirFTPreAuthReq pFTPreAuthReq; /* Saved FT Pre Auth Req */ + tSirRetStatus ftPreAuthStatus; + tANI_U16 saved_auth_rsp_length; + tANI_U8 saved_auth_rsp[MAX_FTIE_SIZE]; + tSirFTPreAuthKeyInfo PreAuthKeyInfo; + /* Items created for the new FT, session */ + void *pAddBssReq; /* Save add bss req */ + void *pAddStaReq; /*Save add sta req */ + tANI_U32 peSessionId; + tANI_U32 smeSessionId; + + /* This flag is required to indicate on which session the preauth + * has taken place, since the auth reponse for preauth will come + * for a new BSSID for which there is no session yet. This flag + * will be used to extract the session from the session preauth + * has been initiated + */ + tANI_BOOLEAN ftPreAuthSession; +} tftPEContext, *tpftPEContext; + +#endif /* __LIMFTDEFS_H__ */ + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limGlobal.h new file mode 100644 index 0000000000000..2260b0cf64a29 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limGlobal.h @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limGlobal.h contains the definitions exported by + * LIM module. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_GLOBAL_H +#define __LIM_GLOBAL_H + +#include "wniApi.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sirMacPropExts.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "wniCfgSta.h" +#include "csrApi.h" +#include "sapApi.h" +#include "dot11f.h" + +/// Maximum number of scan hash table entries +#define LIM_MAX_NUM_OF_SCAN_RESULTS 256 + +// Sending Disassociate frames threshold +#define LIM_SEND_DISASSOC_FRAME_THRESHOLD 2 +#define LIM_HASH_MISS_TIMER_MS 10000 + +// Deferred Message Queue Length +#define MAX_DEFERRED_QUEUE_LEN 80 + +// Maximum number of PS - TIM's to be sent with out wakeup from STA +#define LIM_TIM_WAIT_COUNT_FACTOR 5 + +/** Use this count if (LIM_TIM_WAIT_FACTOR * ListenInterval) is less than LIM_MIN_TIM_WAIT_CNT*/ +#define LIM_MIN_TIM_WAIT_COUNT 50 + +#define GET_TIM_WAIT_COUNT(LIntrvl) ((LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) > LIM_MIN_TIM_WAIT_COUNT ? \ + (LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) : LIM_MIN_TIM_WAIT_COUNT) +#define IS_5G_BAND(__rfBand) ((__rfBand & 0x3) == 0x2) +#define IS_24G_BAND(__rfBand) ((__rfBand & 0x3) == 0x1) + +#define LIM_MAX_CSA_IE_UPDATES ( 5 ) + +// enums exported by LIM are as follows + +/// System role definition +typedef enum eLimSystemRole +{ + eLIM_UNKNOWN_ROLE, + eLIM_AP_ROLE, + eLIM_STA_IN_IBSS_ROLE, + eLIM_STA_ROLE, + eLIM_BT_AMP_STA_ROLE, + eLIM_BT_AMP_AP_ROLE, + eLIM_P2P_DEVICE_ROLE, + eLIM_P2P_DEVICE_GO, + eLIM_P2P_DEVICE_CLIENT +} tLimSystemRole; + +/** + * SME state definition accessible across all Sirius modules. + * AP only states are LIM_SME_CHANNEL_SCAN_STATE & + * LIM_SME_NORMAL_CHANNEL_SCAN_STATE. + * Note that these states may also be present in STA + * side too when DFS support is present for a STA in IBSS mode. + */ +typedef enum eLimSmeStates +{ + eLIM_SME_OFFLINE_STATE, + eLIM_SME_IDLE_STATE, + eLIM_SME_SUSPEND_STATE, + eLIM_SME_WT_SCAN_STATE, + eLIM_SME_WT_JOIN_STATE, + eLIM_SME_WT_AUTH_STATE, + eLIM_SME_WT_ASSOC_STATE, + eLIM_SME_WT_REASSOC_STATE, + eLIM_SME_WT_REASSOC_LINK_FAIL_STATE, + eLIM_SME_JOIN_FAILURE_STATE, + eLIM_SME_ASSOCIATED_STATE, + eLIM_SME_REASSOCIATED_STATE, + eLIM_SME_LINK_EST_STATE, + eLIM_SME_LINK_EST_WT_SCAN_STATE, + eLIM_SME_WT_PRE_AUTH_STATE, + eLIM_SME_WT_DISASSOC_STATE, + eLIM_SME_WT_DEAUTH_STATE, + eLIM_SME_WT_START_BSS_STATE, + eLIM_SME_WT_STOP_BSS_STATE, + eLIM_SME_NORMAL_STATE, + eLIM_SME_CHANNEL_SCAN_STATE, + eLIM_SME_NORMAL_CHANNEL_SCAN_STATE +} tLimSmeStates; + +/** + * MLM state definition. + * While these states are present on AP too when it is + * STA mode, per-STA MLM state exclusive to AP is: + * eLIM_MLM_WT_AUTH_FRAME3. + */ +typedef enum eLimMlmStates +{ + eLIM_MLM_OFFLINE_STATE, + eLIM_MLM_IDLE_STATE, + eLIM_MLM_WT_PROBE_RESP_STATE, + eLIM_MLM_PASSIVE_SCAN_STATE, + eLIM_MLM_WT_JOIN_BEACON_STATE, + eLIM_MLM_JOINED_STATE, + eLIM_MLM_BSS_STARTED_STATE, + eLIM_MLM_WT_AUTH_FRAME2_STATE, + eLIM_MLM_WT_AUTH_FRAME3_STATE, + eLIM_MLM_WT_AUTH_FRAME4_STATE, + eLIM_MLM_AUTH_RSP_TIMEOUT_STATE, + eLIM_MLM_AUTHENTICATED_STATE, + eLIM_MLM_WT_ASSOC_RSP_STATE, + eLIM_MLM_WT_REASSOC_RSP_STATE, + eLIM_MLM_ASSOCIATED_STATE, + eLIM_MLM_REASSOCIATED_STATE, + eLIM_MLM_LINK_ESTABLISHED_STATE, + eLIM_MLM_WT_ASSOC_CNF_STATE, + eLIM_MLM_LEARN_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_STATE, + eLIM_MLM_WT_DEL_BSS_RSP_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE, + eLIM_MLM_WT_ADD_STA_RSP_STATE, + eLIM_MLM_WT_DEL_STA_RSP_STATE, + //MLM goes to this state when LIM initiates DELETE_STA as processing of Assoc req because + //the entry already exists. LIM comes out of this state when DELETE_STA response from + //HAL is received. LIM needs to maintain this state so that ADD_STA can be issued while + //processing DELETE_STA response from HAL. + eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE, + eLIM_MLM_WT_SET_BSS_KEY_STATE, + eLIM_MLM_WT_SET_STA_KEY_STATE, + eLIM_MLM_WT_SET_STA_BCASTKEY_STATE, + eLIM_MLM_WT_ADDBA_RSP_STATE, + eLIM_MLM_WT_REMOVE_BSS_KEY_STATE, + eLIM_MLM_WT_REMOVE_STA_KEY_STATE, + eLIM_MLM_WT_SET_MIMOPS_STATE, +#if defined WLAN_FEATURE_VOWIFI_11R + eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE, + eLIM_MLM_WT_FT_REASSOC_RSP_STATE, +#endif + eLIM_MLM_P2P_LISTEN_STATE, +} tLimMlmStates; + +// 11h channel quiet states +/* This enum indicates in which state the device is in + * when it receives quiet element in beacon or probe-response. + * The default quiet state of the device is always INIT + * eLIM_QUIET_BEGIN - When Quiet period is started + * eLIM_QUIET_CHANGED - When Quiet period is updated + * eLIM_QUIET_RUNNING - Between two successive Quiet updates + * eLIM_QUIET_END - When quiet period ends + */ +typedef enum eLimQuietStates +{ + eLIM_QUIET_INIT, + eLIM_QUIET_BEGIN, + eLIM_QUIET_CHANGED, + eLIM_QUIET_RUNNING, + eLIM_QUIET_END +} tLimQuietStates; + +// 11h channel switch states +/* This enum indicates in which state the channel-swith + * is presently operating. + * eLIM_11H_CHANSW_INIT - Default state + * eLIM_11H_CHANSW_RUNNING - When channel switch is running + * eLIM_11H_CHANSW_END - After channel switch is complete + */ +typedef enum eLimDot11hChanSwStates +{ + eLIM_11H_CHANSW_INIT, + eLIM_11H_CHANSW_RUNNING, + eLIM_11H_CHANSW_END +} tLimDot11hChanSwStates; + +#ifdef GEN4_SCAN + +//WLAN_SUSPEND_LINK Related +typedef void (*SUSPEND_RESUME_LINK_CALLBACK)(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); + +// LIM to HAL SCAN Management Message Interface states +typedef enum eLimHalScanState +{ + eLIM_HAL_IDLE_SCAN_STATE, + eLIM_HAL_INIT_SCAN_WAIT_STATE, + eLIM_HAL_START_SCAN_WAIT_STATE, + eLIM_HAL_END_SCAN_WAIT_STATE, + eLIM_HAL_FINISH_SCAN_WAIT_STATE, + eLIM_HAL_INIT_LEARN_WAIT_STATE, + eLIM_HAL_START_LEARN_WAIT_STATE, + eLIM_HAL_END_LEARN_WAIT_STATE, + eLIM_HAL_FINISH_LEARN_WAIT_STATE, + eLIM_HAL_SCANNING_STATE, +//WLAN_SUSPEND_LINK Related + eLIM_HAL_SUSPEND_LINK_WAIT_STATE, + eLIM_HAL_SUSPEND_LINK_STATE, + eLIM_HAL_RESUME_LINK_WAIT_STATE, +//end WLAN_SUSPEND_LINK Related +} tLimLimHalScanState; +#endif // GEN4_SCAN + +// LIM states related to A-MPDU/BA +// This is used for maintaining the state between PE and HAL only. +typedef enum eLimBAState +{ + eLIM_BA_STATE_IDLE, // we are not waiting for anything from HAL. + eLIM_BA_STATE_WT_ADD_RSP, //We are waiting for Add rsponse from HAL. + eLIM_BA_STATE_WT_DEL_RSP // We are waiting for Del response from HAL. +} tLimBAState; + + + + + +// MLM Req/Cnf structure definitions +typedef struct sLimMlmAuthReq +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tANI_U32 authFailureTimeout; + tANI_U8 sessionId; +} tLimMlmAuthReq, *tpLimMlmAuthReq; + +typedef struct sLimMlmJoinReq +{ + tANI_U32 joinFailureTimeout; + tSirMacRateSet operationalRateSet; + tANI_U8 sessionId; + tSirBssDescription bssDescription; +} tLimMlmJoinReq, *tpLimMlmJoinReq; + +typedef struct sLimMlmScanReq +{ + tSirBssType bssType; + tSirMacAddr bssId; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tSirScanType scanType; + tANI_U32 minChannelTime; + tANI_U32 maxChannelTime; + tANI_U32 minChannelTimeBtc; + tANI_U32 maxChannelTimeBtc; + tSirBackgroundScanMode backgroundScanMode; + tANI_U32 dot11mode; + /* Number of SSIDs to scan(send Probe request) */ + tANI_U8 numSsid; + + tANI_BOOLEAN p2pSearch; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + + tANI_U8 sessionId; + //channelList MUST be the last field of this structure + tSirChannelList channelList; + /*----------------------------- + tLimMlmScanReq.... + ----------------------------- + uIEFiledLen + ----------------------------- + uIEFiledOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEFiled + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tLimMlmScanReq, *tpLimMlmScanReq; + +typedef struct tLimScanResultNode tLimScanResultNode; +struct tLimScanResultNode +{ + tLimScanResultNode *next; + tSirBssDescription bssDescription; +}; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +// OEM Data related structure definitions +typedef struct sLimMlmOemDataReq +{ + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tLimMlmOemDataReq, *tpLimMlmOemDataReq; + +typedef struct sLimMlmOemDataRsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tLimMlmOemDataRsp, *tpLimMlmOemDataRsp; +#endif + +// Pre-authentication structure definition +typedef struct tLimPreAuthNode +{ + struct tLimPreAuthNode *next; + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tLimMlmStates mlmState; + tANI_U8 authNodeIdx; + tANI_U8 challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH]; + tANI_U8 fTimerStarted:1; + tANI_U8 fSeen:1; + tANI_U8 fFree:1; + tANI_U8 rsvd:5; + TX_TIMER timer; +}tLimPreAuthNode, *tpLimPreAuthNode; + +// Pre-authentication table definition +typedef struct tLimPreAuthTable +{ + tANI_U32 numEntry; + tpLimPreAuthNode pTable; +}tLimPreAuthTable, *tpLimPreAuthTable; + +/// Per STA context structure definition +typedef struct sLimMlmStaContext +{ + tLimMlmStates mlmState; + tAniAuthType authType; + tANI_U16 listenInterval; + tSirMacCapabilityInfo capabilityInfo; + tSirMacPropRateSet propRateSet; + tSirMacReasonCodes disassocReason; + tANI_U16 cleanupTrigger; + + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + + tANI_U8 subType:1; // Indicates ASSOC (0) or REASSOC (1) + tANI_U8 updateContext:1; + tANI_U8 schClean:1; + // 802.11n HT Capability in Station: Enabled 1 or DIsabled 0 + tANI_U8 htCapability:1; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability:1; +#endif +} tLimMlmStaContext, *tpLimMlmStaContext; + +// Structure definition to hold deferred messages queue parameters +typedef struct sLimDeferredMsgQParams +{ + tSirMsgQ deferredQueue[MAX_DEFERRED_QUEUE_LEN]; + tANI_U16 size; + tANI_U16 read; + tANI_U16 write; +} tLimDeferredMsgQParams, *tpLimDeferredMsgQParams; + +typedef struct sCfgProtection +{ + tANI_U32 overlapFromlla:1; + tANI_U32 overlapFromllb:1; + tANI_U32 overlapFromllg:1; + tANI_U32 overlapHt20:1; + tANI_U32 overlapNonGf:1; + tANI_U32 overlapLsigTxop:1; + tANI_U32 overlapRifs:1; + tANI_U32 overlapOBSS:1; /* added for obss */ + tANI_U32 fromlla:1; + tANI_U32 fromllb:1; + tANI_U32 fromllg:1; + tANI_U32 ht20:1; + tANI_U32 nonGf:1; + tANI_U32 lsigTxop:1; + tANI_U32 rifs:1; + tANI_U32 obss:1; /* added for Obss */ +}tCfgProtection, *tpCfgProtection; + +typedef enum eLimProtStaCacheType +{ + eLIM_PROT_STA_CACHE_TYPE_INVALID, + eLIM_PROT_STA_CACHE_TYPE_llB, + eLIM_PROT_STA_CACHE_TYPE_llG, + eLIM_PROT_STA_CACHE_TYPE_HT20 +}tLimProtStaCacheType; + +typedef struct sCacheParams +{ + tANI_U8 active; + tSirMacAddr addr; + tLimProtStaCacheType protStaCacheType; + +} tCacheParams, *tpCacheParams; + +#define LIM_PROT_STA_OVERLAP_CACHE_SIZE HAL_NUM_ASSOC_STA +#define LIM_PROT_STA_CACHE_SIZE HAL_NUM_ASSOC_STA + +typedef struct sLimProtStaParams +{ + tANI_U8 numSta; + tANI_U8 protectionEnabled; +} tLimProtStaParams, *tpLimProtStaParams; + + +typedef struct sLimNoShortParams +{ + tANI_U8 numNonShortPreambleSta; + tCacheParams staNoShortCache[LIM_PROT_STA_CACHE_SIZE]; +} tLimNoShortParams, *tpLimNoShortParams; + +typedef struct sLimNoShortSlotParams +{ + tANI_U8 numNonShortSlotSta; + tCacheParams staNoShortSlotCache[LIM_PROT_STA_CACHE_SIZE]; +} tLimNoShortSlotParams, *tpLimNoShortSlotParams; + + +typedef struct tLimIbssPeerNode tLimIbssPeerNode; +struct tLimIbssPeerNode +{ + tLimIbssPeerNode *next; + tSirMacAddr peerMacAddr; + tANI_U8 extendedRatesPresent:1; + tANI_U8 edcaPresent:1; + tANI_U8 wmeEdcaPresent:1; + tANI_U8 wmeInfoPresent:1; + tANI_U8 htCapable:1; + tANI_U8 vhtCapable:1; + tANI_U8 rsvd:1; + tANI_U8 htSecondaryChannelOffset; + tSirMacCapabilityInfo capabilityInfo; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tANI_U8 supportedMCSSet[SIZE_OF_SUPPORTED_MCS_SET]; + tSirMacEdcaParamSetIE edcaParams; + tANI_U16 propCapability; + tANI_U8 erpIePresent; + + //HT Capabilities of IBSS Peer + tANI_U8 htGreenfield; + tANI_U8 htShortGI40Mhz; + tANI_U8 htShortGI20Mhz; + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + tANI_U8 htDsssCckRate40MHzSupport; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState htMIMOPSState; + + // + // A-MPDU Density + // 000 - No restriction + // 001 - 1/8 usec + // 010 - 1/4 usec + // 011 - 1/2 usec + // 100 - 1 usec + // 101 - 2 usec + // 110 - 4 usec + // 111 - 8 usec + // + tANI_U8 htAMpduDensity; + + // Maximum Rx A-MPDU factor + tANI_U8 htMaxRxAMpduFactor; + + //Set to 0 for 3839 octets + //Set to 1 for 7935 octets + tANI_U8 htMaxAmsduLength; + + // + // Recommended Tx Width Set + // 0 - use 20 MHz channel (control channel) + // 1 - use 40 Mhz channel + // + tANI_U8 htSupportedChannelWidthSet; + + tANI_U8 htLdpcCapable; + + tANI_U8 beaconHBCount; + tANI_U8 heartbeatFailure; + + tANI_U8 *beacon; //Hold beacon to be sent to HDD/CSR + tANI_U16 beaconLen; + +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tANI_U8 vhtSupportedChannelWidthSet; + tANI_U8 vhtBeamFormerCapable; +#endif + /* + * Peer Atim Info + */ + tANI_U8 atimIePresent; + tANI_U32 peerAtimWindowLength; +}; + +// Enums used for channel switching. +typedef enum eLimChannelSwitchState +{ + eLIM_CHANNEL_SWITCH_IDLE, + eLIM_CHANNEL_SWITCH_PRIMARY_ONLY, + eLIM_CHANNEL_SWITCH_SECONDARY_ONLY, + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY +} tLimChannelSwitchState; + + +// Channel Switch Info +typedef struct sLimChannelSwitchInfo +{ + tLimChannelSwitchState state; + tANI_U8 primaryChannel; + ePhyChanBondState secondarySubBand; + tANI_S8 switchCount; + tANI_U32 switchTimeoutValue; + tANI_U8 switchMode; +} tLimChannelSwitchInfo, *tpLimChannelSwitchInfo; + +#ifdef WLAN_FEATURE_11AC +typedef struct sLimOperatingModeInfo +{ + tANI_U8 present; + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +}tLimOperatingModeInfo, *tpLimOperatingModeInfo; +#endif + +typedef struct sLimWiderBWChannelSwitch +{ + tANI_U8 newChanWidth; + tANI_U8 newCenterChanFreq0; + tANI_U8 newCenterChanFreq1; +}tLimWiderBWChannelSwitchInfo, *tpLimWiderBWChannelSwitchInfo; + +// Enums used when stopping the Tx. +typedef enum eLimQuietTxMode +{ + eLIM_TX_ALL = 0, /* Stops/resumes the transmission of all stations, Uses the global flag. */ + eLIM_TX_STA, /* Stops/resumes the transmission of specific stations identified by staId. */ + eLIM_TX_BSS, /* Stops/resumes the transmission of all the packets in BSS */ + eLIM_TX_BSS_BUT_BEACON /* Stops/resumes the transmission of all packets except beacons in BSS + * This is used when radar is detected in the current operating channel. + * Beacon has to be sent to notify the stations associated about the + * scheduled channel switch */ +} tLimQuietTxMode; + +typedef enum eLimControlTx +{ + eLIM_RESUME_TX = 0, + eLIM_STOP_TX +} tLimControlTx; + + +// -------------------------------------------------------------------- + +typedef __ani_attr_pre_packed struct sLimTspecInfo +{ + tANI_U8 inuse; // 0==free, else used + tANI_U8 idx; // index in list + tANI_U8 staAddr[6]; + tANI_U16 assocId; + tSirMacTspecIE tspec; + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; + tANI_U8 tclasProcPresent:1; //tclassProc is valid only if this is set to 1. +} __ani_attr_packed tLimTspecInfo, *tpLimTspecInfo; + +typedef struct sLimAdmitPolicyInfo +{ + tANI_U8 type; // admit control policy type + tANI_U8 bw_factor; // oversubscription factor : 0 means nothing is allowed + // valid only when 'type' is set BW_FACTOR +} tLimAdmitPolicyInfo, *tpLimAdmitPolicyInfo; + + +typedef enum eLimWscEnrollState +{ + eLIM_WSC_ENROLL_NOOP, + eLIM_WSC_ENROLL_BEGIN, + eLIM_WSC_ENROLL_IN_PROGRESS, + eLIM_WSC_ENROLL_END + +} tLimWscEnrollState; + +#define WSC_PASSWD_ID_PUSH_BUTTON (0x0004) + +typedef struct sLimWscIeInfo +{ + tANI_BOOLEAN apSetupLocked; + tANI_BOOLEAN selectedRegistrar; + tANI_U16 selectedRegistrarConfigMethods; + tLimWscEnrollState wscEnrollmentState; + tLimWscEnrollState probeRespWscEnrollmentState; + tANI_U8 reqType; + tANI_U8 respType; +} tLimWscIeInfo, *tpLimWscIeInfo; + +// maximum number of tspec's supported +#define LIM_NUM_TSPEC_MAX 15 + + +//structure to hold all 11h specific data +typedef struct sLimSpecMgmtInfo +{ + tLimQuietStates quietState; + tANI_U32 quietCount; + tANI_U32 quietDuration; /* This is in units of system TICKS */ + tANI_U32 quietDuration_TU; /* This is in units of TU, for over the air transmission */ + tANI_U32 quietTimeoutValue; /* After this timeout, actual quiet starts */ + tANI_BOOLEAN fQuietEnabled; /* Used on AP, if quiet is enabled during learning */ + + tLimDot11hChanSwStates dot11hChanSwState; + + tANI_BOOLEAN fRadarDetCurOperChan; /* Radar detected in cur oper chan on AP */ + tANI_BOOLEAN fRadarIntrConfigured; /* Whether radar interrupt has been configured */ +}tLimSpecMgmtInfo, *tpLimSpecMgmtInfo; + + +#ifdef FEATURE_WLAN_TDLS +/* + * Peer info needed for TDLS setup.. + */ +typedef struct tLimTDLSPeerSta +{ + struct tLimTDLSPeerSta *next; + tANI_U8 dialog ; + tSirMacAddr peerMac; + tSirMacCapabilityInfo capabilityInfo; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirMacQosCapabilityStaIE qosCaps; + tSirMacEdcaParamSetIE edcaParams; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + tANI_U8 tdls_bIsResponder ; + /* HT Capabilties */ + tDot11fIEHTCaps tdlsPeerHTCaps ; + tDot11fIEExtCap tdlsPeerExtCaps; + tANI_U8 tdls_flags ; + tANI_U8 tdls_link_state ; + tANI_U8 tdls_prev_link_state ; + tANI_U8 tdls_sessionId; + tANI_U8 ExtRatesPresent ; + TX_TIMER gLimTdlsLinkSetupRspTimeoutTimer ; + TX_TIMER gLimTdlsLinkSetupCnfTimeoutTimer ; +}tLimTdlsLinkSetupPeer, *tpLimTdlsLinkSetupPeer ; + +typedef struct tLimTdlsLinkSetupInfo +{ + tLimTdlsLinkSetupPeer *tdlsLinkSetupList ; + tANI_U8 num_tdls_peers ; + tANI_U8 tdls_flags ; + tANI_U8 tdls_state ; + tANI_U8 tdls_prev_state ; +}tLimTdlsLinkSetupInfo, *tpLimTdlsLinkSetupInfo ; + +typedef enum tdlsLinkMode +{ + TDLS_LINK_MODE_BG, + TDLS_LINK_MODE_N, + TDLS_LINK_MODE_AC, + TDLS_LINK_MODE_NONE +} eLimTdlsLinkMode ; +#endif /* FEATURE_WLAN_TDLS */ + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limSession.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limSession.h new file mode 100644 index 0000000000000..d05acb6666131 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limSession.h @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __LIM_SESSION_H ) +#define __LIM_SESSION_H + +/**========================================================================= + + \file limSession.h + + \brief prototype for lim Session related APIs + + \author Sunit Bhatia + + ========================================================================*/ + +/* Powersave Offload Implementation */ +typedef enum ePowersaveState +{ + PMM_FULL_POWER, + PMM_POWER_SAVE +}tPowersaveState; + +/* Master Structure: This will be part of PE Session Entry */ +typedef struct sPowersaveoffloadInfo +{ + tPowersaveState psstate; + tANI_U8 bcnmiss; +}tPowersaveoffloadInfo, tpPowersaveoffloadInfo; + +#ifdef WLAN_FEATURE_11W +/* + * This struct is needed for handling of ASSOC RSP with TRY AGAIN LATER + * It stores the context and state machine setting for MLM so that it can + * go back send ASSOC REQ frame again after the timer has expired. + */ +typedef struct tagComebackTimerInfo +{ + tpAniSirGlobal pMac; + tANI_U8 sessionID; + tLimMlmStates limPrevMlmState; /* Previous MLM State */ + tLimSmeStates limMlmState; /* MLM State */ +} tComebackTimerInfo; +#endif /* WLAN_FEATURE_11W */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define NUM_WEP_KEYS 4 + +// Maximum allowable size of a beacon frame +#define SCH_MAX_BEACON_SIZE 512 + +#define SCH_MAX_PROBE_RESP_SIZE 512 + +#define SCH_PROTECTION_RESET_TIME 4000 +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct +{ + tSirMacBeaconInterval beaconInterval; + tANI_U8 fShortPreamble; + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20Coexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fRIFSMode; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 gHTObssMode; +}tBeaconParams, *tpBeaconParams; + +typedef struct sPESession // Added to Support BT-AMP +{ + /* To check session table is in use or free*/ + tANI_U8 available; + tANI_U16 peSessionId; + tANI_U8 smeSessionId; + tANI_U16 transactionId; + + //In AP role: BSSID and selfMacAddr will be the same. + //In STA role: they will be different + tSirMacAddr bssId; + tSirMacAddr selfMacAddr; + tSirMacSSid ssId; + tANI_U8 bssIdx; + tANI_U8 valid; + tLimMlmStates limMlmState; //MLM State + tLimMlmStates limPrevMlmState; //Previous MLM State + tLimSmeStates limSmeState; //SME State + tLimSmeStates limPrevSmeState; //Previous SME State + tLimSystemRole limSystemRole; + tSirBssType bssType; + tANI_U8 operMode; // AP - 0; STA - 1 ; + tSirNwType nwType; + tpSirSmeStartBssReq pLimStartBssReq; //handle to smestart bss req + tpSirSmeJoinReq pLimJoinReq; // handle to sme join req + tpSirSmeJoinReq pLimReAssocReq; //handle to sme reassoc req + tpLimMlmJoinReq pLimMlmJoinReq; //handle to MLM join Req +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + void *pLimMlmReassocRetryReq; //keep reasoc req for retry +#endif + void *pLimMlmReassocReq; //handle to MLM reassoc Req + tANI_U16 channelChangeReasonCode; + tANI_U8 dot11mode; + tANI_U8 htCapability; + /* Supported Channel Width Set: 0-20MHz 1 - 40MHz */ + tANI_U8 htSupportedChannelWidthSet; + /* Recommended Tx Width Set + * 0 - use 20 MHz channel (control channel) + * 1 - use channel width enabled under Supported Channel Width Set + */ + tANI_U8 htRecommendedTxWidthSet; + /* Identifies the 40 MHz extension channel */ + ePhyChanBondState htSecondaryChannelOffset; + tSirRFBand limRFBand; + tANI_U8 limIbssActive; //TO SUPPORT CONCURRENCY + + /* These global varibales moved to session Table to support BT-AMP : Oct 9th review */ + tAniAuthType limCurrentAuthType; + tANI_U16 limCurrentBssCaps; + tANI_U8 limCurrentBssQosCaps; + tANI_U16 limCurrentBssPropCap; + tANI_U8 limSentCapsChangeNtf; + tANI_U16 limAID; + + /* Parameters For Reassociation */ + tSirMacAddr limReAssocbssId; + tSirMacChanNum limReassocChannelId; + /* CB paramaters required/duplicated for Reassoc since re-assoc mantains its own params in lim */ + tANI_U8 reAssocHtSupportedChannelWidthSet; + tANI_U8 reAssocHtRecommendedTxWidthSet; + ePhyChanBondState reAssocHtSecondaryChannelOffset; + tSirMacSSid limReassocSSID; + tANI_U16 limReassocBssCaps; + tANI_U8 limReassocBssQosCaps; + tANI_U16 limReassocBssPropCap; + + // Assoc or ReAssoc Response Data/Frame + void *limAssocResponseData; + + /** BSS Table parameters **/ + + /* + * staId: Start BSS: this is the Sta Id for the BSS. + * Join: this is the selfStaId + * In both cases above, the peer STA ID wll be stored in dph hash table. + */ + tANI_U16 staId; + tANI_U16 statypeForBss; //to know session is for PEER or SELF + tANI_U8 shortSlotTimeSupported; + tANI_U8 dtimPeriod; + tSirMacRateSet rateSet; + tSirMacRateSet extRateSet; + tSirMacHTOperatingMode htOperMode; + tANI_U8 currentOperChannel; + tANI_U8 currentReqChannel; + tANI_U8 LimRxedBeaconCntDuringHB; + + //Time stamp of the last beacon received from the BSS to which STA is connected. + tANI_U64 lastBeaconTimeStamp; + //RX Beacon count for the current BSS to which STA is connected. + tANI_U32 currentBssBeaconCnt; + tANI_U8 lastBeaconDtimCount; + tANI_U8 lastBeaconDtimPeriod; + + tANI_U32 bcnLen; + tANI_U8 *beacon; //Used to store last beacon / probe response before assoc. + + tANI_U32 assocReqLen; + tANI_U8 *assocReq; //Used to store association request frame sent out while associating. + + tANI_U32 assocRspLen; + tANI_U8 *assocRsp; //Used to store association response received while associating + tAniSirDph dph; + void * *parsedAssocReq; //Used to store parsed assoc req from various requesting station +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 RICDataLen; //Used to store the Ric data received in the assoc response + tANI_U8 *ricData; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 tspecLen; //Used to store the TSPEC IEs received in the assoc response + tANI_U8 *tspecIes; +#endif + tANI_U32 encryptType; + + tANI_BOOLEAN bTkipCntrMeasActive; // Used to keep record of TKIP counter measures start/stop + + tANI_U8 gLimProtectionControl; //used for 11n protection + + tANI_U8 gHTNonGFDevicesPresent; + + //protection related config cache + tCfgProtection cfgProtection; + + // Number of legacy STAs associated + tLimProtStaParams gLim11bParams; + + // Number of 11A STAs associated + tLimProtStaParams gLim11aParams; + + // Number of non-ht non-legacy STAs associated + tLimProtStaParams gLim11gParams; + + //Number of nonGf STA associated + tLimProtStaParams gLimNonGfParams; + + //Number of HT 20 STAs associated + tLimProtStaParams gLimHt20Params; + + //Number of Lsig Txop not supported STAs associated + tLimProtStaParams gLimLsigTxopParams; + + // Number of STAs that do not support short preamble + tLimNoShortParams gLimNoShortParams; + + // Number of STAs that do not support short slot time + tLimNoShortSlotParams gLimNoShortSlotParams; + + + // OLBC parameters + tLimProtStaParams gLimOlbcParams; + + // OLBC parameters + tLimProtStaParams gLimOverlap11gParams; + + tLimProtStaParams gLimOverlap11aParams; + tLimProtStaParams gLimOverlapHt20Params; + tLimProtStaParams gLimOverlapNonGfParams; + + //cache for each overlap + tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE]; + + tANI_U8 privacy; + tAniAuthType authType; + tSirKeyMaterial WEPKeyMaterial[NUM_WEP_KEYS]; + + tDot11fIERSN gStartBssRSNIe; + tDot11fIEWPA gStartBssWPAIe; + tSirAPWPSIEs APWPSIEs; + tANI_U8 apUapsdEnable; + tSirWPSPBCSession *pAPWPSPBCSession; + tANI_U32 DefProbeRspIeBitmap[8]; + tANI_U32 proxyProbeRspEn; + tDot11fProbeResponse probeRespFrame; + tANI_U8 ssidHidden; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_U8 wps_state; + + tANI_U8 limQosEnabled:1; //11E + tANI_U8 limWmeEnabled:1; //WME + tANI_U8 limWsmEnabled:1; //WSM + tANI_U8 limHcfEnabled:1; + tANI_U8 lim11dEnabled:1; +#ifdef WLAN_FEATURE_11W + tANI_U8 limRmfEnabled:1; //11W +#endif + tANI_U32 lim11hEnable; + + tPowerdBm maxTxPower; //MIN (Regulatory and local power constraint) + tVOS_CON_MODE pePersona; +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + tAniBool is11Rconnection; +#endif + +#ifdef FEATURE_WLAN_ESE + tAniBool isESEconnection; + tEsePEContext eseContext; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tAniBool isFastTransitionEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tAniBool isFastRoamIniFeatureEnabled; +#endif + tSirNoAParam p2pNoA; + tSirP2PNoaAttr p2pGoPsUpdate; + tANI_U32 defaultAuthFailureTimeout; + tSirP2PNoaStart p2pGoPsNoaStartInd; + + /* EDCA QoS parameters + * gLimEdcaParams - These EDCA parameters are used locally on AP or STA. + * If STA, then these are values taken from the Assoc Rsp when associating, + * or Beacons/Probe Response after association. If AP, then these are + * values originally set locally on AP. + * + * gLimEdcaParamsBC - These EDCA parameters are use by AP to broadcast + * to other STATIONs in the BSS. + * + * gLimEdcaParamsActive: These EDCA parameters are what's actively being + * used on station. Specific AC values may be downgraded depending on + * admission control for that particular AC. + */ + tSirMacEdcaParamRecord gLimEdcaParams[MAX_NUM_AC]; //used locally + tSirMacEdcaParamRecord gLimEdcaParamsBC[MAX_NUM_AC]; //used for broadcast + tSirMacEdcaParamRecord gLimEdcaParamsActive[MAX_NUM_AC]; + + tANI_U8 gLimEdcaParamSetCount; + + tBeaconParams beaconParams; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability; + tANI_U8 vhtTxChannelWidthSet; + tLimOperatingModeInfo gLimOperatingMode; + tANI_U8 vhtCapabilityPresentInBeacon; + tANI_U8 apCenterChan; + tANI_U8 apChanWidth; + tANI_U8 txBFIniFeatureEnabled; + tANI_U8 txMuBformee; + tANI_U8 enableVhtpAid; + tANI_U8 enableVhtGid; +#endif + tLimWiderBWChannelSwitchInfo gLimWiderBWChannelSwitch; + tANI_U8 enableAmpduPs; + tANI_U8 enableHtSmps; + tANI_U8 htSmpsvalue; + tANI_U8 spectrumMgtEnabled; + /* *********************11H related*****************************/ + tLimSpecMgmtInfo gLimSpecMgmt; + // CB Primary/Secondary Channel Switch Info + tLimChannelSwitchInfo gLimChannelSwitch; + /* *********************End 11H related*****************************/ + + /*Flag to Track Status/Indicate HBFailure on this session */ + tANI_BOOLEAN LimHBFailureStatus; + tANI_U32 gLimPhyMode; + tANI_U8 amsduSupportedInBA; + tANI_U8 txLdpcIniFeatureEnabled; + /** + * Following is the place holder for free peer index pool. + * A non-zero value indicates that peer index is available + * for assignment. + */ + tANI_U8 *gpLimPeerIdxpool; + tANI_U8 freePeerIdxHead; + tANI_U8 freePeerIdxTail; + tANI_U16 gLimNumOfCurrentSTAs; +#ifdef FEATURE_WLAN_TDLS + tANI_U32 peerAIDBitmap[2]; + bool tdls_prohibited; + bool tdls_chan_swit_prohibited; +#endif + tANI_BOOLEAN fWaitForProbeRsp; + tANI_BOOLEAN fIgnoreCapsChange; + tANI_BOOLEAN fDeauthReceived; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM + tANI_S8 rssi; +#endif + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 isCoalesingInIBSSAllowed; + + tSirHTConfig htConfig; + + /* + * Place holder for StartBssReq message + * received by SME state machine + */ + tANI_U8 gLimCurrentBssUapsd; + + /* Used on STA, this is a static UAPSD mask setting + * derived from SME_JOIN_REQ and SME_REASSOC_REQ. If a + * particular AC bit is set, it means the AC is both + * trigger enabled and delivery enabled. + */ + tANI_U8 gUapsdPerAcBitmask; + + /* Used on STA, this is a dynamic UPASD mask setting + * derived from AddTS Rsp and DelTS frame. If a + * particular AC bit is set, it means AC is trigger + * enabled. + */ + tANI_U8 gUapsdPerAcTriggerEnableMask; + + /* Used on STA, dynamic UPASD mask setting + * derived from AddTS Rsp and DelTs frame. If + * a particular AC bit is set, it means AC is + * delivery enabled. + */ + tANI_U8 gUapsdPerAcDeliveryEnableMask; + + /* Flag to skip CSA IE processing when CSA + * offload is enabled. + */ + tANI_U8 csaOffloadEnable; + + /* Used on STA for AC downgrade. This is a dynamic mask + * setting which keep tracks of ACs being admitted. + * If bit is set to 0: That partiular AC is not admitted + * If bit is set to 1: That particular AC is admitted + */ + tANI_U8 gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT]; + + /* Power Save Off load Parameters */ + tPowersaveoffloadInfo pmmOffloadInfo; + + /* SMPS mode */ + tANI_U8 smpsMode; + + tANI_U8 chainMask; + + /* Flag to indicate Chan Sw announcement is required */ + tANI_U8 dfsIncludeChanSwIe; + + /* Flag to indicate Chan Wrapper Element is required */ + tANI_U8 dfsIncludeChanWrapperIe; + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 cc_switch_mode; +#endif + + tANI_BOOLEAN isCiscoVendorAP; + + tSirAddIeParams addIeParams; + + tANI_U8 *pSchProbeRspTemplate; + // Beginning portion of the beacon frame to be written to TFP + tANI_U8 *pSchBeaconFrameBegin; + // Trailing portion of the beacon frame to be written to TFP + tANI_U8 *pSchBeaconFrameEnd; + // Size of the beginning portion + tANI_U16 schBeaconOffsetBegin; + // Size of the trailing portion + tANI_U16 schBeaconOffsetEnd; + tANI_BOOLEAN isOSENConnection; + /* DSCP to UP mapping for HS 2.0 */ + tSirQosMapSet QosMapSet; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_BOOLEAN bRoamSynchInProgress; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + /* Fast Transition (FT) */ + tftPEContext ftPEContext; +#endif + tANI_BOOLEAN isNonRoamReassoc; + tANI_U8 isKeyInstalled; +#ifdef WLAN_FEATURE_11W + vos_timer_t pmfComebackTimer; + tComebackTimerInfo pmfComebackTimerInfo; +#endif /* WLAN_FEATURE_11W */ + /* timer for reseting protection fileds at regular intervals */ + vos_timer_t protection_fields_reset_timer; + void *mac_ctx; + /* + * variable to store state of various protection struct like + * gLimOlbcParams, gLimOverlap11gParams, gLimOverlapHt20Params etc + */ + tANI_U16 old_protection_state; + tSirMacAddr prev_ap_bssid; + uint8_t sap_dot11mc; +#ifdef FEATURE_WLAN_ESE + uint8_t is_ese_version_ie_present; +#endif + /* flag to indicate country code in beacon */ + tANI_U8 countryInfoPresent; +} tPESession, *tpPESession; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + + \brief peCreateSession() - creates a new PE session given the BSSID + + This function returns the session context and the session ID if the + session corresponding to the passed BSSID is found in the PE session + table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the new session + \param sessionId - session ID is returned here, if session is + created. + \param bssType - bss type of new session to do conditional + memory allocation. + \return tpPESession - pointer to the session context or NULL if + session can not be created. + + \sa + + --------------------------------------------------------------------------*/ +tpPESession peCreateSession(tpAniSirGlobal pMac, + tANI_U8 *bssid, + tANI_U8* sessionId, + tANI_U16 numSta, + tSirBssType bssType); + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given the BSSID. + + This function returns the session context and the session ID if the session + corresponding to the given BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_U8* sessionId); + + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx. + + This function returns the session context if the session + corresponding to the given bssIdx is found in the PE session table. + \param pMac - pointer to global adapter context + \param bssIdx - bss index of the session + \return tpPESession - pointer to the session context or NULL if session is not found. + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac, tANI_U8 bssIdx); + + + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByPeerSta() - looks up the PE session given the Peer Station Address. + + This function returns the session context and the session ID if the session + corresponding to the given destination address is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sa - Peer STA Address of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac, tANI_U8* sa, tANI_U8* sessionId); + +/*-------------------------------------------------------------------------- + \brief peFindSessionBySessionId() - looks up the PE session given the session ID. + + This function returns the session context if the session + corresponding to the given session ID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sessionId -session ID for which session context needs to be looked up. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac , tANI_U8 sessionId); + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given staid. + + This function returns the session context and the session ID if the session + corresponding to the given StaId is found in the PE session table. + + \param pMac - pointer to global adapter context + \param staid - StaId of the session + \param sessionId - session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + +--------------------------------------------------------------------------*/ + tpPESession peFindSessionByStaId(tpAniSirGlobal pMac, tANI_U8 staid, tANI_U8* sessionId); + + + + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - deletes the PE session given the session ID. + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ +void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry); + +/** + * pe_find_session_by_sme_session_id() - looks up the PE session for given sme + * session id + * @mac_ctx: pointer to global adapter context + * @sme_session_id: sme session id + * + * looks up the PE session for given sme session id + * + * Return: pe session entry for given sme session if found else NULL + */ +tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx, + uint8_t sme_session_id); + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - Returns the SME session ID and Transaction ID . + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ + + +#endif //#if !defined( __LIM_SESSION_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limTrace.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limTrace.h new file mode 100644 index 0000000000000..66772e1af72fa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/limTrace.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + +* \file limTrace.h + +* \brief definition for trace related APIs + +* \author Sunit Bhatia + + ========================================================================*/ + + + +#ifndef __LIM_TRACE_H +#define __LIM_TRACE_H + +#include "limGlobal.h" +#include "macTrace.h" +#include "vos_trace.h" +#ifdef LIM_TRACE_RECORD + + + +#define LIM_TRACE_GET_SSN(data) (((data) >> 16) & 0xff) +#define LIM_TRACE_GET_SUBTYPE(data) (data & 0xff) +#define LIM_TRACE_GET_DEFERRED(data) (data & 0x80000000) +#define LIM_TRACE_GET_DEFRD_OR_DROPPED(data) (data & 0xc0000000) + +#define LIM_MSG_PROCESSED 0 +#define LIM_MSG_DEFERRED 1 +#define LIM_MSG_DROPPED 2 + +#define LIM_TRACE_MAKE_RXMGMT(type, ssn) \ + ((ssn << 16) | (type) ) +#define LIM_TRACE_MAKE_RXMSG(msg, action) \ + ((msg) | (action << 30) ) + + + + +enum { + TRACE_CODE_MLM_STATE, + TRACE_CODE_SME_STATE, + TRACE_CODE_TX_MGMT, + TRACE_CODE_RX_MGMT, + TRACE_CODE_RX_MGMT_TSF, + TRACE_CODE_TX_COMPLETE, + TRACE_CODE_TX_SME_MSG, + TRACE_CODE_RX_SME_MSG, + TRACE_CODE_TX_WDA_MSG, + TRACE_CODE_RX_WDA_MSG, + TRACE_CODE_TX_LIM_MSG, + TRACE_CODE_RX_LIM_MSG, + TRACE_CODE_TX_CFG_MSG, + TRACE_CODE_RX_CFG_MSG, + TRACE_CODE_RX_MGMT_DROP, + + TRACE_CODE_TIMER_ACTIVATE, + TRACE_CODE_TIMER_DEACTIVATE, + TRACE_CODE_INFO_LOG +}; + + + + + + +void limTraceInit(tpAniSirGlobal pMac); +void limTraceReset(tpAniSirGlobal pMac); +void limTraceUpdateMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); +void limTraceDumpMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); +tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState ); +tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState ); +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex); +void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); +void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); + +void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); +void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); +#endif //endof LIM_TRACE_RECORD MACRO + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmApi.h new file mode 100644 index 0000000000000..60f3541e7cf25 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmApi.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_API_H__ +#define __PMM_API_H__ + +#include "sirCommon.h" +#include "schApi.h" +#include "halMsgApi.h" + + +/// Initialize PMM +extern tSirRetStatus pmmInitialize(tpAniSirGlobal pMac); + +/// Post a message to PMM module +extern tSirRetStatus pmmPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + +/// Reset PMM beacon mode power save statistics +extern void pmmResetStats(void *pvMac); + +/// Process the next PM message +extern void pmmProcessMessage(tpAniSirGlobal, tpSirMsgQ); + +extern void pmmProcessPSPoll(tpAniSirGlobal, tANI_U8 *); +extern void pmmUpdatePSPollState(tpAniSirGlobal); +extern void pmmProcessRxActivity(tpAniSirGlobal, tANI_U16, tANI_U8); + +extern void pmmGenerateTIM(tpAniSirGlobal, tANI_U8 **, tANI_U16 *, tANI_U8); + + +void pmmUpdateTIM(tpAniSirGlobal pMac, tpBeaconGenParams pBeaconGenParams); + +/// Update the PM mode +extern void pmmUpdatePMMode(tpAniSirGlobal pMac, tANI_U16 staId, tANI_U8 pmMode); + +/// Update Power Mode +extern void pmmUpdatePollablePMMode(tpAniSirGlobal, tANI_U16, tANI_U8, tANI_U16); +extern void pmmUpdateNonPollablePMMode(tpAniSirGlobal, tANI_U16, tANI_U8, tANI_U16); + +/** Monitor the STA in PS*/ +void pmmHandleTimBasedDisassociation(tpAniSirGlobal pMac, tpPESession psessionEntry); + +//go into sleep state +void pmmInitBmpsPwrSave(tpAniSirGlobal pMac); +tSirRetStatus pmmSendInitPowerSaveMsg(tpAniSirGlobal pMac,tpPESession); +void pmmInitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmSendChangePowerSaveMsg(tpAniSirGlobal pMac); +tSirRetStatus pmmSendSleepIndicationToHal(tpAniSirGlobal pMac); + +//go into wakeup state +void pmmExitBmpsRequestHandler(tpAniSirGlobal pMac, tpExitBmpsInfo pExitBmpsInfo); +void pmmExitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) ; +void pmmMissedBeaconHandler(tpAniSirGlobal pMac); + +//handlling all UAPSD messages +void pmmEnterUapsdRequestHandler (tpAniSirGlobal pMac); +void pmmEnterUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void pmmExitUapsdRequestHandler (tpAniSirGlobal pMac); +void pmmExitUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode); + +// handling of all idle mode power save messages +void pmmEnterImpsRequestHandler(tpAniSirGlobal pMac); +void pmmEnterImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus); +void pmmExitImpsRequestHandler(tpAniSirGlobal pMac); +void pmmExitImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus); + +// handling WOWLAN messages +void pmmSendWowlAddBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void pmmSendWowlDelBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +tSirRetStatus pmmSendWowlEnterRequest(tpAniSirGlobal pMac, tpSirHalWowlEnterParams pHalWowlParams); +void pmmEnterWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmSendExitWowlReq(tpAniSirGlobal pMac, tpSirHalWowlExitParams pHalWowlParams); +void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +// update idle mode statistics +void pmmImpsUpdatePwrSaveStats(tpAniSirGlobal pMac); +void pmmImpsUpdateWakeupStats(tpAniSirGlobal pMac); +tSirRetStatus pmmImpsSendChangePwrSaveMsg(tpAniSirGlobal pMac, tANI_U8 mode); +void pmmImpsUpdateSleepErrStats(tpAniSirGlobal pMac, tSirRetStatus retStatus); +void pmmImpsUpdateWakeupErrStats(tpAniSirGlobal pMac, tSirRetStatus retStatus); +void pmmImpsUpdateErrStateStats(tpAniSirGlobal pMac); +void pmmImpsUpdatePktDropStats(tpAniSirGlobal pMac); + +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac); +void pmmBmpsUpdateHalReqFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateInitFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateInvalidStateCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac); +void pmmBmpsUpdateReqInInvalidRoleCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateSleepReqFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateWakeupIndCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateWakeupReqFailureCnt(tpAniSirGlobal pMac); +void pmmResetPmmState(tpAniSirGlobal pMac); +void pmmSendMessageToLim(tpAniSirGlobal pMac, tANI_U32 msgId); + +//Power Save CFG +tSirRetStatus pmmSendPowerSaveCfg(tpAniSirGlobal pMac, tpSirPowerSaveCfg pUpdatedPwrSaveCfg); + +//Handle Low RSSI Indication +void pmmLowRssiHandler(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void pmmFilterMatchCountResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void pmmGTKOffloadGetInfoResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +eHalStatus pmmPsOffloadOpen(tpAniSirGlobal pMac,tpPESession psessionEntry); +eHalStatus pmmPsOffloadClose(tpAniSirGlobal pMac, + tpPESession psessionEntry); +tANI_U8 pmmPsOffloadIsActive(tpAniSirGlobal pMac, + tpPESession psessionEntry); +void pmmOffloadProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmGlobal.h new file mode 100644 index 0000000000000..e24252071a689 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/pmmGlobal.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_GLOBAL_H__ +#define __PMM_GLOBAL_H__ + +#include "sirApi.h" + +typedef enum ePmmState +{ + ePMM_STATE_INVALID, + ePMM_STATE_READY, + //BMPS + ePMM_STATE_BMPS_WT_INIT_RSP, + ePMM_STATE_BMPS_WT_SLEEP_RSP, + ePMM_STATE_BMPS_SLEEP, + ePMM_STATE_BMPS_WT_WAKEUP_RSP, + ePMM_STATE_BMPS_WAKEUP, + //IMPS + ePMM_STATE_IMPS_WT_SLEEP_RSP, + ePMM_STATE_IMPS_SLEEP, + ePMM_STATE_IMPS_WT_WAKEUP_RSP, + ePMM_STATE_IMPS_WAKEUP, + //UAPSD + ePMM_STATE_UAPSD_WT_SLEEP_RSP, + ePMM_STATE_UAPSD_SLEEP, + ePMM_STATE_UAPSD_WT_WAKEUP_RSP, + + //WOWLAN + ePMM_STATE_WOWLAN, + + ePMM_STATE_ERROR, + ePMM_STATE_LAST, +}tPmmState; + +typedef struct sPmmStaInfo +{ + tANI_U16 assocId; + tANI_U32 staTxAckCnt; +}tPmmStaInfo, *tpPmmStaInfo; + +typedef struct sPmmTim +{ + tANI_U8 *pTim; /** Tim Bit Array*/ + tANI_U8 minAssocId; + tANI_U8 maxAssocId; + tANI_U8 dtimCount; + /** Remaining Members are needed for LinkMonitaring of the STA in PS*/ + tANI_U8 numStaWithData; /** Number of stations in power save, who have data pending*/ + tpPmmStaInfo pStaInfo; /** Points to 1st Instant of the Array of MaxSTA StaInfo */ +} tPmmTim, *tpPmmTim; + +typedef struct sAniSirPmm +{ + tANI_U64 BmpsmaxSleepTime; + tANI_U64 BmpsavgSleepTime; + tANI_U64 BmpsminSleepTime; + tANI_U64 BmpscntSleep; + + tANI_U64 BmpsmaxTimeAwake; + tANI_U64 BmpsavgTimeAwake; + tANI_U64 BmpsminTimeAwake; + tANI_U64 BmpscntAwake; + + tANI_U64 BmpsWakeupTimeStamp; + tANI_U64 BmpsSleepTimeStamp; + + // debug statistics + tANI_U64 BmpsPktDrpInSleepMode; + tANI_U64 BmpsInitFailCnt; + tANI_U64 BmpsSleeReqFailCnt; + tANI_U64 BmpsWakeupReqFailCnt; + tANI_U64 BmpsInvStateCnt; + tANI_U64 BmpsWakeupIndCnt; + tANI_U64 BmpsHalReqFailCnt; + tANI_U64 BmpsReqInInvalidRoleCnt; + + /* Add wakeup and sleep time stamps here */ + tANI_U64 ImpsWakeupTimeStamp; + tANI_U64 ImpsSleepTimeStamp; + + tANI_U64 ImpsMaxTimeAwake; + tANI_U64 ImpsMinTimeAwake; + tANI_U64 ImpsAvgTimeAwake; + tANI_U64 ImpsCntAwake; + + tANI_U64 ImpsCntSleep; + tANI_U64 ImpsMaxSleepTime; + tANI_U64 ImpsMinSleepTime; + tANI_U64 ImpsAvgSleepTime; + + tANI_U64 ImpsSleepErrCnt; + tANI_U64 ImpsWakeupErrCnt; + tANI_U64 ImpsLastErr; + + tANI_U64 ImpsInvalidStateCnt; + tANI_U64 ImpsPktDrpInSleepMode; + + + /// Next STA to be serviced in PS state + tANI_U16 gPmmNextSta; + + /// Next CF-pollable STA to be serviced in PS state + tANI_U16 gPmmNextCFPSta; + + /// Number of STAs in PS state + tANI_U16 gPmmNumSta; + + tANI_U8 gPmmPsPollUpdate:1; // set when any sta state is update due to PS-Poll + tANI_U8 rsvd: 7; + + /// STA Power management state array + /** + * An entry in this array records the power save state for an STA + * It also points to the next closest STA in power save state. + */ + + tANI_U32 gPmmBeaconInterval; //pmm keeps its won copy of beacon interval, default to 100ms + tSirPowerSaveCfg gPmmCfg; //pmm keeps a copy of Power Save config parameters sent to softmac. + /// Current PM state of the station + tPmmState gPmmState; + /// Flag to track if we are in a missed beacon scenario + tANI_U8 inMissedBeaconScenario; + + tPmmTim gPmmTim; + + + //Reason for which PMC is sending an EXIT_BMPS_REQ to PE + tExitBmpsReason gPmmExitBmpsReasonCode; + tANI_U8 sessionId; //This sessio Id is added to know the bsstype , infra/btamp .......in power save mode + +} tAniSirPmm, *tpAniSirPmm; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmApi.h new file mode 100644 index 0000000000000..c17028480a522 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmApi.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/**========================================================================= + + \file rrmApi.h + + \brief RRM APIs + + ========================================================================*/ + +/* $Header$ */ + +#ifndef __RRM_API_H__ +#define __RRM_API_H__ + +#define RRM_MIN_TX_PWR_CAP 13 +#define RRM_MAX_TX_PWR_CAP 19 + +#define RRM_BCN_RPT_NO_BSS_INFO 0 +#define RRM_BCN_RPT_MIN_RPT 1 + +tANI_U8 rrmGetMinOfMaxTxPower(tpAniSirGlobal pMac, tPowerdBm regMax, tPowerdBm apTxPower); + +extern tSirRetStatus rrmInitialize(tpAniSirGlobal pMac); + +extern tSirRetStatus rrmCleanup(tpAniSirGlobal pMac); + + +extern tSirRetStatus rrmProcessLinkMeasurementRequest( tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo, + tDot11fLinkMeasurementRequest *pLinkReq, + tpPESession pSessionEntry ); + +extern tSirRetStatus rrmProcessRadioMeasurementRequest( tpAniSirGlobal pMac, + tSirMacAddr peer, + tDot11fRadioMeasurementRequest *pRRMReq, + tpPESession pSessionEntry ); + +extern tSirRetStatus rrmProcessNeighborReportResponse( tpAniSirGlobal pMac, + tDot11fNeighborReportResponse *pNeighborRep, + tpPESession pSessionEntry ); + +extern void rrmProcessMessage(tpAniSirGlobal pMac, + tpSirMsgQ pMsg); + +extern tSirRetStatus rrmSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); + +extern tPowerdBm rrmGetMgmtTxPower ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmCacheMgmtTxPower ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); + +extern tpRRMCaps rrmGetCapabilities ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmUpdateConfig ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmGetStartTSF ( tpAniSirGlobal pMac, + tANI_U32 *pStartTSF ); + +extern void rrmUpdateStartTSF ( tpAniSirGlobal pMac, + tANI_U32 startTSF[2] ); + +extern tSirRetStatus rrmSetMaxTxPowerRsp ( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +extern tSirRetStatus +rrmProcessNeighborReportReq( tpAniSirGlobal pMac, + tpSirNeighborReportReqInd pNeighborReq ); +extern tSirRetStatus +rrmProcessBeaconReportXmit( tpAniSirGlobal pMac, + tpSirBeaconReportXmitInd pBcnReport); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmGlobal.h new file mode 100644 index 0000000000000..a1d9a666338b1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/rrmGlobal.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __RRMGLOBAL_H ) +#define __RRMGLOBAL_H + +/**========================================================================= + + \file rrmGlobal.h + + \brief Definitions for SME APIs + + ========================================================================*/ + +typedef enum eRrmRetStatus +{ + eRRM_SUCCESS, + eRRM_INCAPABLE, + eRRM_REFUSED, + eRRM_FAILURE +} tRrmRetStatus; + +typedef enum eRrmMsgReqSource +{ + eRRM_MSG_SOURCE_LEGACY_ESE = 1, /* legacy ese */ + eRRM_MSG_SOURCE_11K = 2, /* 11k */ + eRRM_MSG_SOURCE_ESE_UPLOAD = 3, /* ese upload approach */ +} tRrmMsgReqSource; + +typedef struct sSirChannelInfo +{ + tANI_U8 regulatoryClass; + tANI_U8 channelNum; +} tSirChannelInfo, * tpSirChannelInfo; + +typedef struct sSirBeaconReportReqInd +{ + tANI_U16 messageType; // eWNI_SME_BEACON_REPORT_REQ_IND + tANI_U16 length; + tSirMacAddr bssId; + tANI_U16 measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; //ms + tANI_U16 randomizationInterval; //ms + tSirChannelInfo channelInfo; + tSirMacAddr macaddrBssid; //0: wildcard + tANI_U8 fMeasurementtype[SIR_ESE_MAX_MEAS_IE_REQS]; //0:Passive, 1: Active, 2: table mode + tAniSSID ssId; //May be wilcard. + tANI_U16 uDialogToken; + tSirChannelList channelList; //From AP channel report. + tRrmMsgReqSource msgSource; +} tSirBeaconReportReqInd, * tpSirBeaconReportReqInd; + + +typedef struct sSirBeaconReportXmitInd +{ + tANI_U16 messageType; // eWNI_SME_BEACON_REPORT_RESP_XMIT_IND + tANI_U16 length; + tSirMacAddr bssId; + tANI_U16 uDialogToken; + tANI_U8 fMeasureDone; + tANI_U16 duration; + tANI_U8 regClass; + tANI_U8 numBssDesc; + tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC]; +} tSirBeaconReportXmitInd, * tpSirBeaconReportXmitInd; + +typedef struct sSirNeighborReportReqInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_REPORT_REQ_IND + tANI_U16 length; + tSirMacAddr bssId; //For the session. + tANI_U16 noSSID; //TRUE - dont include SSID in the request. + //FALSE include the SSID. It may be null (wildcard) + tSirMacSSid ucSSID; +} tSirNeighborReportReqInd, * tpSirNeighborReportReqInd; + + +typedef struct sSirNeighborBssDescription +{ + tANI_U16 length; + tSirMacAddr bssId; + tANI_U8 regClass; + tANI_U8 channel; + tANI_U8 phyType; + union sSirNeighborBssidInfo { + struct _rrmInfo { + tANI_U32 fApPreauthReachable:2; //see IEEE 802.11k Table 7-43a + tANI_U32 fSameSecurityMode:1; + tANI_U32 fSameAuthenticator:1; + tANI_U32 fCapSpectrumMeasurement:1; //see IEEE 802.11k Table 7-95d + tANI_U32 fCapQos:1; + tANI_U32 fCapApsd:1; + tANI_U32 fCapRadioMeasurement:1; + tANI_U32 fCapDelayedBlockAck:1; + tANI_U32 fCapImmediateBlockAck:1; + tANI_U32 fMobilityDomain:1; + tANI_U32 reserved:21; + } rrmInfo; + struct _eseInfo { + tANI_U32 channelBand:8; + tANI_U32 minRecvSigPower:8; + tANI_U32 apTxPower:8; + tANI_U32 roamHysteresis:8; + tANI_U32 adaptScanThres:8; + + tANI_U32 transitionTime:8; + tANI_U32 tsfOffset:16; + + tANI_U32 beaconInterval:16; + tANI_U32 reserved: 16; + } eseInfo; + } bssidInfo; + + //Optional sub IEs....ignoring for now. +}tSirNeighborBssDescription, *tpSirNeighborBssDescripton; + +typedef struct sSirNeighborReportInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_REPORT_IND + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 numNeighborReports; + tSirMacAddr bssId; //For the session. + tSirNeighborBssDescription sNeighborBssDescription[1]; +} tSirNeighborReportInd, * tpSirNeighborReportInd; + +typedef struct sRRMBeaconReportRequestedIes +{ + tANI_U8 num; + tANI_U8 *pElementIds; +}tRRMBeaconReportRequestedIes, *tpRRMBeaconReportRequestedIes; + +//Reporting detail defines. +//Reference - IEEE Std 802.11k-2008 section 7.3.2.21.6 Table 7-29h +#define BEACON_REPORTING_DETAIL_NO_FF_IE 0 +#define BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE 1 +#define BEACON_REPORTING_DETAIL_ALL_FF_IE 2 + + +typedef struct sRRMReq +{ + tANI_U8 dialog_token; //In action frame; + tANI_U8 token; //Within individual request; + tANI_U8 type; + union { + struct { + tANI_U8 reportingDetail; + tRRMBeaconReportRequestedIes reqIes; + }Beacon; + }request; + tANI_U8 sendEmptyBcnRpt; +}tRRMReq, *tpRRMReq; + +typedef struct sRRMCaps +{ + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + + tANI_U8 operatingChanMax; + tANI_U8 nonOperatingChanMax; + tANI_U8 MeasurementPilot; +}tRRMCaps, *tpRRMCaps; + +typedef struct sRrmPEContext +{ + tANI_U8 rrmEnable; + tANI_U32 startTSF[2]; //Used during scan/measurement to store the start TSF. this is not used directly in beacon reports. + //This value is stored into bssdescription and beacon report gets it from bss decsription. + tRRMCaps rrmEnabledCaps; + tPowerdBm txMgmtPower; + tANI_U8 DialogToken; //Dialog token for the request initiated from station. + tpRRMReq pCurrentReq; +}tRrmPEContext, *tpRrmPEContext; + +// 2008 11k spec reference: 18.4.8.5 RCPI Measurement +#define RCPI_LOW_RSSI_VALUE (-110) +#define RCPI_MAX_VALUE (220) +#define CALCULATE_RCPI(rssi) (((rssi) + 110) * 2) + + +#endif //#if defined __RRMGLOBAL_H diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schApi.h new file mode 100644 index 0000000000000..3c45a8b9bdced --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schApi.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_API_H__ +#define __SCH_API_H__ + +#include "sirCommon.h" +#include "sirMacProtDef.h" + +#include "aniGlobal.h" + +/// Send start scan response message +extern void schSendStartScanRsp(tpAniSirGlobal pMac); + +// update only the broadcast qos params +extern void schQosUpdateBroadcast(tpAniSirGlobal pMac, tpPESession psessionEntry); + +// fill in the default local edca parameter into gLimEdcaParams[] +extern void schSetDefaultEdcaParams(tpAniSirGlobal pMac, tpPESession psessionE); + +// update only local qos params +extern void schQosUpdateLocal(tpAniSirGlobal pMac, tpPESession psessionEntry); + +// update the edca profile parameters +extern void schEdcaProfileUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry); + +/// Set the fixed fields in a beacon frame +extern tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry); + +/// Initializations +extern void schInitialize(tpAniSirGlobal pMac); + +/// Initialize globals +extern void schInitGlobals(tpAniSirGlobal pMac); + +/// Initialize CF Poll template +extern void schInitializeCfPollTemplate(tpAniSirGlobal pMac); + +/// Initialize CF End template +extern void schInitializeCfEndTemplate(tpAniSirGlobal pMac); + +/// Process the scheduler messages +extern void schProcessMessage(tpAniSirGlobal pMac,tpSirMsgQ pSchMsg); + +/// The beacon Indication handler function +extern void schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +/// Post a message to the scheduler message queue +extern tSirRetStatus schPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + + +extern void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry); +extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry); + + +#define SCH_RR_TIMEOUT (SCH_RR_TIMEOUT_MS / SYS_TICK_DUR_MS) + +void schSetBeaconInterval(tpAniSirGlobal pMac,tpPESession psessionEntry); + +tSirRetStatus schSendBeaconReq( tpAniSirGlobal, tANI_U8 *, tANI_U16, tpPESession psessionEntry ); + +tSirRetStatus limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal, + tDot11fBeacon1*, tpPESession psessionEntry); +void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal,tDot11fBeacon2*,tANI_U32*,tDot11fProbeResponse*); +void SetProbeRspIeBitmap(tANI_U32*,tANI_U32); +tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal,tpPESession, + tANI_U32*); + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schGlobal.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schGlobal.h new file mode 100644 index 0000000000000..2b04ba2e4a6c2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/schGlobal.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_GLOBAL_H__ +#define __SCH_GLOBAL_H__ + +#include "sirMacPropExts.h" +#include "limGlobal.h" + +#include "parserApi.h" + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define TIM_IE_SIZE 0xB +#else +#define TIM_IE_SIZE 0x7 +#endif + +// ----------------------- Beacon processing ------------------------ + +/// Beacon structure +#define tSchBeaconStruct tSirProbeRespBeacon +#define tpSchBeaconStruct struct sSirProbeRespBeacon * + +// ------------------------------------------------------------------- + +//****************** MISC defs ********************************* + +struct schMisc { + tANI_U16 gSchBeaconInterval; + + /// Current CFP count + tANI_U8 gSchCFPCount; + + /// CFP Duration remaining + tANI_U8 gSchCFPDurRemaining; + + /// CFP Maximum Duration + tANI_U8 gSchCFPMaxDuration; + + /// Current DTIM count + tANI_U8 gSchDTIMCount; + + /// Whether we have initiated a CFP or not + tANI_U8 gSchCFPInitiated; + + /// Whether we have initiated a CFB or not + tANI_U8 gSchCFBInitiated; + + /// CFP is enabled and AP is configured as HCF + tANI_U8 gSchCFPEnabled; + + /// CFB is enabled and AP is configured as HCF + tANI_U8 gSchCFBEnabled; + + // --------- STA ONLY state ----------- + + /// Indicates whether RR timer is running or not + tANI_U8 rrTimer[8]; + + /// Indicates the remaining RR timeout value if the RR timer is running + tANI_U16 rrTimeout[8]; + + /// Number of RRs transmitted + tANI_U16 numRR[8]; + tANI_U16 numRRtimeouts[8]; + + /// flag to indicate that beacon template has been updated + tANI_U8 fBeaconChanged; + + tANI_U16 p2pIeOffset; + +}; + +//****************** MISC defs ********************************* + +typedef struct schStaWaitList +{ + tANI_U16 staId; + tANI_U16 count; +} tStaWaitList, *tpStaWaitList; + + +/// Global SCH structure +typedef struct sAniSirSch +{ + /// The scheduler object + struct schMisc schObject; + + // schQoSClass unsolicited; + + /// Whether HCF is enabled or not + tANI_U8 gSchHcfEnabled; + + /// Whether scan is requested by LIM or not + tANI_U8 gSchScanRequested; + + /// Whether scan request is received by SCH or not + tANI_U8 gSchScanReqRcvd; + + + /// Debug flag to disable beacon generation + tANI_U32 gSchGenBeacon; + +#define SCH_MAX_ARR 100 + tANI_U32 gSchBeaconsWritten; + tANI_U32 gSchBeaconsSent; + tANI_U32 gSchBBXportRcvCnt; + tANI_U32 gSchRRRcvCnt, qosNullCnt; + tANI_U32 gSchBcnRcvCnt; + tANI_U32 gSchUnknownRcvCnt; + + tANI_U32 gSchBcnParseErrorCnt; + tANI_U32 gSchBcnIgnored; + + tANI_U32 numPoll, numData, numCorrupt; + tANI_U32 numBogusInt, numTxAct0; + +#define SCH_MAX_NUM_SCH 21 + tANI_U32 lastBeaconLength; + tANI_U16 rrTimeout; + tANI_U32 pollPeriod; + tANI_U32 keepAlive; + tANI_U32 multipleSched; + tANI_U32 pollFeedbackHist[8]; + tANI_U32 dataFeedbackHist[8]; + tANI_U32 maxPollTimeouts; + tANI_U32 checkCfbFlagStuck; + + /// Sta Wait list + tpStaWaitList pStaWaitList; + + /// Pointer to next available entry in sta wait list + tANI_U16 staWaitListIn; + /// Pointer to first waiting sta in sta wait list + tANI_U16 staWaitListOut; + /// Total number of waiting STAs in sta wait list + tANI_U16 staWaitListCount; + /// Total number of schedules to be waited + tANI_U16 staWaitListTotalWait; + + /// Number of entries in DPH activity queue that were ignored + tANI_U32 ignoreDph; + +} tAniSirSch, *tpAniSirSch; + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/wmmApsd.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/wmmApsd.h new file mode 100644 index 0000000000000..fc112290d7a07 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/include/wmmApsd.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WMMAPSD_H__ +#define __WMMAPSD_H__ + +#include "aniGlobal.h" + +// UAPSD Flag for each AC (WMM spec 2.2.1) +#define LIM_UAPSD_BITOFFSET_ACVO 0 +#define LIM_UAPSD_BITOFFSET_ACVI 1 +#define LIM_UAPSD_BITOFFSET_ACBK 2 +#define LIM_UAPSD_BITOFFSET_ACBE 3 + +#define LIM_UAPSD_FLAG_ACVO (1 << LIM_UAPSD_BITOFFSET_ACVO) +#define LIM_UAPSD_FLAG_ACVI (1 << LIM_UAPSD_BITOFFSET_ACVI) +#define LIM_UAPSD_FLAG_ACBK (1 << LIM_UAPSD_BITOFFSET_ACBK) +#define LIM_UAPSD_FLAG_ACBE (1 << LIM_UAPSD_BITOFFSET_ACBE) + +#define LIM_UAPSD_GET(ac, mask) (((mask) & (LIM_UAPSD_FLAG_ ## ac)) >> LIM_UAPSD_BITOFFSET_ ## ac) + +// Definition for setting/clearing Uapsd Mask +#define SET_UAPSD_MASK 1 +#define CLEAR_UAPSD_MASK 0 + +#endif /* __WMMAPSD_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAIDmgmt.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAIDmgmt.c new file mode 100644 index 0000000000000..25600cb1dce83 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAIDmgmt.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limAIDmgmt.cc contains the functions related to + * AID pool management like initialization, assignment etc. + * Author: Chandra Modumudi + * Date: 03/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "palTypes.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "sirParams.h" +#include "limUtils.h" +#include "limTimerUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limSessionUtils.h" + +#define LIM_START_PEER_IDX 1 + +/** + * limInitPeerIdxpool() + * + *FUNCTION: + * This function is called while starting a BSS at AP + * to initialize AID pool. This may also be called while + * starting/joining an IBSS if 'Association' is allowed + * in IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitPeerIdxpool(tpAniSirGlobal pMac,tpPESession pSessionEntry) +{ + tANI_U8 i; + tANI_U8 maxAssocSta = pMac->lim.gLimAssocStaLimit; + + pSessionEntry->gpLimPeerIdxpool[0]=0; + +#ifdef FEATURE_WLAN_TDLS + //In station role, DPH_STA_HASH_INDEX_PEER (index 1) is reserved for peer + //station index corresponding to AP. Avoid choosing that index and get index + //starting from (DPH_STA_HASH_INDEX_PEER + 1) (index 2) for TDLS stations; + if (pSessionEntry->limSystemRole == eLIM_STA_ROLE ) + { + pSessionEntry->freePeerIdxHead = DPH_STA_HASH_INDEX_PEER + 1; + } + else +#endif +#ifdef QCA_IBSS_SUPPORT + if (pSessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + pSessionEntry->freePeerIdxHead=LIM_START_PEER_IDX; + maxAssocSta = pMac->lim.gLimIbssStaLimit; + } + else +#endif + { + pSessionEntry->freePeerIdxHead=LIM_START_PEER_IDX; + } + + for (i=pSessionEntry->freePeerIdxHead;igpLimPeerIdxpool[i] = i+1; + } + pSessionEntry->gpLimPeerIdxpool[i] = 0; + + pSessionEntry->freePeerIdxTail=i; + +} + + +/** + * limAssignPeerIdx() + * + *FUNCTION: + * This function is called to get a peer station index. This index is + * used during Association/Reassociation + * frame handling to assign association ID (aid) to a STA. + * In case of TDLS, this is used to assign a index into the Dph hash entry. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return peerIdx - assigned peer Station IDx for STA + */ + +tANI_U16 +limAssignPeerIdx(tpAniSirGlobal pMac, tpPESession pSessionEntry) +{ + tANI_U16 peerId; + + // make sure we haven't exceeded the configurable limit on associations + // This count is global to ensure that it doesnt exceed the hardware limits. + if (peGetCurrentSTAsCount(pMac) >= pMac->lim.gLimAssocStaLimit) + { + // too many associations already active + return 0; + } + + /* return head of free list */ + + if (pSessionEntry->freePeerIdxHead) + { + peerId=pSessionEntry->freePeerIdxHead; + pSessionEntry->freePeerIdxHead = pSessionEntry->gpLimPeerIdxpool[pSessionEntry->freePeerIdxHead]; + if (pSessionEntry->freePeerIdxHead==0) + pSessionEntry->freePeerIdxTail=0; + pSessionEntry->gLimNumOfCurrentSTAs++; + return peerId; + } + + return 0; /* no more free peer index */ +} + + +/** + * limReleasePeerIdx() + * + *FUNCTION: + * This function is called when a STA context is removed + * at AP (or at a STA in IBSS mode or TDLS) to return peer Index + * to free pool. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param peerIdx - peer station index that need to return to free pool + * + * @return None + */ + +void +limReleasePeerIdx(tpAniSirGlobal pMac, tANI_U16 peerIdx, tpPESession pSessionEntry) +{ + pSessionEntry->gLimNumOfCurrentSTAs--; + + /* insert at tail of free list */ + if (pSessionEntry->freePeerIdxTail) + { + pSessionEntry->gpLimPeerIdxpool[pSessionEntry->freePeerIdxTail]=(tANI_U8)peerIdx; + pSessionEntry->freePeerIdxTail=(tANI_U8)peerIdx; + } + else + { + pSessionEntry->freePeerIdxTail=pSessionEntry->freePeerIdxHead=(tANI_U8)peerIdx; + } + pSessionEntry->gpLimPeerIdxpool[(tANI_U8)peerIdx]=0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAdmitControl.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAdmitControl.c new file mode 100644 index 0000000000000..928e41bc87ad2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAdmitControl.c @@ -0,0 +1,1151 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file contains TSPEC and STA admit control related functions + * NOTE: applies only to AP builds + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "limDebug.h" +#include "sysDef.h" +#include "limApi.h" +#include "cfgApi.h" // wlan_cfgGetInt() +#include "limTrace.h" +#include "limSendSmeRspMessages.h" +#include "limTypes.h" + + +#define ADMIT_CONTROL_LOGLEVEL LOG1 +#define ADMIT_CONTROL_POLICY_LOGLEVEL LOG1 + +/* total available bandwidth in bps in each phy mode + * these should be defined in hal or dph - replace these later + */ +#define LIM_TOTAL_BW_11A 54000000 +#define LIM_MIN_BW_11A 6000000 +#define LIM_TOTAL_BW_11B 11000000 +#define LIM_MIN_BW_11B 1000000 +#define LIM_TOTAL_BW_11G LIM_TOTAL_BW_11A +#define LIM_MIN_BW_11G LIM_MIN_BW_11B + +// conversion factors +#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8) +#define LIM_CONVERT_RATE_MBPS(rate) ((rate)/1000000) + +/* ANI sta's support enhanced rates, so the effective medium time used is + * half that of other stations. This is the same as if they were requesting + * half the badnwidth - so we adjust ANI sta's accordingly for bandwidth + * calculations. Also enhanced rates apply only in case of non 11B mode. + */ +#define LIM_STA_BW_ADJUST(aniPeer, phyMode, bw) \ + (((aniPeer) && ((phyMode) != WNI_CFG_PHY_MODE_11B)) \ + ? ((bw)/2) : (bw)) + + +//------------------------------------------------------------------------------ +// local protos + +static tSirRetStatus +limCalculateSvcInt(tpAniSirGlobal, tSirMacTspecIE *, tANI_U32 *); +static tSirRetStatus +limValidateTspecEdca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession); +static tSirRetStatus +limValidateTspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession); +static void +limComputeMeanBwUsed(tpAniSirGlobal, tANI_U32 *, tANI_U32, tpLimTspecInfo, tpPESession); +static void +limGetAvailableBw(tpAniSirGlobal, tANI_U32 *, tANI_U32 *, tANI_U32, tANI_U32); +static tSirRetStatus +limAdmitPolicyOversubscription(tpAniSirGlobal, tSirMacTspecIE *, tpLimAdmitPolicyInfo, tpLimTspecInfo, tpPESession); +static tSirRetStatus +limTspecFindByStaAddr(tpAniSirGlobal, tANI_U8 *, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *); +static tSirRetStatus +limValidateAccessPolicy(tpAniSirGlobal, tANI_U8, tANI_U16, tpPESession); + + +/** ------------------------------------------------------------- +\fn limCalculateSvcInt +\brief TSPEC validation and servcie interval determination +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\param tANI_U32 *pSvcInt +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +static tSirRetStatus +limCalculateSvcInt( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tANI_U32 *pSvcInt) +{ + tANI_U32 msduSz, dataRate; + *pSvcInt = 0; + + // if a service interval is already specified, we are done + if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0)) + { + *pSvcInt = (pTspec->maxSvcInterval != 0) + ? pTspec->maxSvcInterval : pTspec->minSvcInterval; + return eSIR_SUCCESS; + } + + /* Masking off the fixed bits according to definition of MSDU size + * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size + * is defined as: Bit[0:14]=Size, Bit[15]=Fixed + */ + if (pTspec->nomMsduSz != 0) + msduSz = (pTspec->nomMsduSz & 0x7fff); + else if (pTspec->maxMsduSz != 0) + msduSz = pTspec->maxMsduSz; + else + { + PELOGE(limLog(pMac, LOGE, FL("MsduSize not specified"));) + return eSIR_FAILURE; + } + + /* need to calculate a reasonable service interval + * this is simply the msduSz/meanDataRate + */ + if (pTspec->meanDataRate != 0) dataRate = pTspec->meanDataRate; + else if (pTspec->peakDataRate != 0) dataRate = pTspec->peakDataRate; + else if (pTspec->minDataRate != 0) dataRate = pTspec->minDataRate; + else + { + PELOGE(limLog(pMac, LOGE, FL("DataRate not specified"));) + return eSIR_FAILURE; + } + + *pSvcInt = LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate); + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limValidateTspecEdca +\brief validate the parameters in the edca tspec + mandatory fields are derived from 11e Annex I (Table I.1) +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ +static tSirRetStatus +limValidateTspecEdca( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tANI_U32 maxPhyRate, minPhyRate; + tANI_U32 phyMode; + tSirRetStatus retval = eSIR_SUCCESS; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode, + 1 /* bandwidth mult factor */); + // mandatory fields are derived from 11e Annex I (Table I.1) + if ((pTspec->nomMsduSz == 0) || + (pTspec->meanDataRate == 0) || + (pTspec->surplusBw == 0) || + (pTspec->minPhyRate == 0) || + (pTspec->minPhyRate > maxPhyRate)) + { + limLog(pMac, LOGW, FL("Invalid EDCA Tspec: NomMsdu %d, meanDataRate %d, surplusBw %d, minPhyRate %d"), + pTspec->nomMsduSz, pTspec->meanDataRate, pTspec->surplusBw, pTspec->minPhyRate); + retval = eSIR_FAILURE; + } + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d"), retval); + return retval; +} + +/** ------------------------------------------------------------- +\fn limValidateTspec +\brief validate the offered tspec +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static tSirRetStatus +limValidateTspec( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_SUCCESS; + switch (pTspec->tsinfo.traffic.accessPolicy) + { + case SIR_MAC_ACCESSPOLICY_EDCA: + if ((retval = limValidateTspecEdca(pMac, pTspec, psessionEntry)) != eSIR_SUCCESS) + PELOGW(limLog(pMac, LOGW, FL("EDCA tspec invalid"));) + break; + + case SIR_MAC_ACCESSPOLICY_HCCA: + case SIR_MAC_ACCESSPOLICY_BOTH: + // TBD: should we support hybrid tspec as well?? for now, just fall through + default: + limLog(pMac, LOGW, FL("AccessType %d not supported"), + pTspec->tsinfo.traffic.accessPolicy); + retval = eSIR_FAILURE; + break; + } + return retval; +} + +//----------------------------------------------------------------------------- +// Admit Control Policy + + +/** ------------------------------------------------------------- +\fn limComputeMeanBwUsed +\brief determime the used/allocated bandwidth +\param tpAniSirGlobal pMac +\param tANI_U32 *pBw +\param tANI_U32 phyMode +\param tpLimTspecInfo pTspecInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static void +limComputeMeanBwUsed( + tpAniSirGlobal pMac, + tANI_U32 *pBw, + tANI_U32 phyMode, + tpLimTspecInfo pTspecInfo, + tpPESession psessionEntry) +{ + tANI_U32 ctspec; + *pBw = 0; + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) + { + if (pTspecInfo->inuse) + { + tpDphHashNode pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + // maybe we should delete the tspec?? + limLog(pMac, LOGE, FL("Tspec %d (assocId %d): dphNode not found"), + ctspec, pTspecInfo->assocId); + continue; + } + //FIXME: need to take care of taurusPeer, titanPeer, 11npeer too. + *pBw += LIM_STA_BW_ADJUST(pSta->aniPeer, phyMode, pTspecInfo->tspec.meanDataRate); + } + } +} + +/** ------------------------------------------------------------- +\fn limGetAvailableBw +\brief based on the phy mode and the bw_factor, determine the total bandwidth that + can be supported +\param tpAniSirGlobal pMac +\param tANI_U32 *pMaxBw +\param tANI_U32 *pMinBw +\param tANI_U32 phyMode +\param tANI_U32 bw_factor +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static void +limGetAvailableBw( + tpAniSirGlobal pMac, + tANI_U32 *pMaxBw, + tANI_U32 *pMinBw, + tANI_U32 phyMode, + tANI_U32 bw_factor) +{ + switch (phyMode) + { + case WNI_CFG_PHY_MODE_11B: + *pMaxBw = LIM_TOTAL_BW_11B; + *pMinBw = LIM_MIN_BW_11B; + break; + + case WNI_CFG_PHY_MODE_11A: + *pMaxBw = LIM_TOTAL_BW_11A; + *pMinBw = LIM_MIN_BW_11A; + break; + + case WNI_CFG_PHY_MODE_11G: + case WNI_CFG_PHY_MODE_NONE: + default: + *pMaxBw = LIM_TOTAL_BW_11G; + *pMinBw = LIM_MIN_BW_11G; + break; + } + *pMaxBw *= bw_factor; +} + +/** ------------------------------------------------------------- +\fn limAdmitPolicyOversubscription +\brief simple admission control policy based on oversubscription + if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then + reject the tspec, else admit it. The phy-bw is the peak available bw in the + current phy mode. The 'factor' is the configured oversubscription factor. +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\param tpLimAdmitPolicyInfo pAdmitPolicy +\param tpLimTspecInfo pTspecInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +/* + * simple admission control policy based on oversubscription + * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then + * reject the tspec, else admit it. The phy-bw is the peak available bw in the + * current phy mode. The 'factor' is the configured oversubscription factor. + */ +static tSirRetStatus +limAdmitPolicyOversubscription( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpLimAdmitPolicyInfo pAdmitPolicy, + tpLimTspecInfo pTspecInfo, + tpPESession psessionEntry) +{ + tANI_U32 totalbw, minbw, usedbw; + tANI_U32 phyMode; + + // determine total bandwidth used so far + limGetPhyMode(pMac, &phyMode, psessionEntry); + + limComputeMeanBwUsed(pMac, &usedbw, phyMode, pTspecInfo, psessionEntry); + + // determine how much bandwidth is available based on the current phy mode + limGetAvailableBw(pMac, &totalbw, &minbw, phyMode, pAdmitPolicy->bw_factor); + + if (usedbw > totalbw) // this can't possibly happen + return eSIR_FAILURE; + + if ((totalbw - usedbw) < pTspec->meanDataRate) + { + limLog(pMac, ADMIT_CONTROL_POLICY_LOGLEVEL, + FL("Total BW %d, Used %d, Tspec request %d not possible"), + totalbw, usedbw, pTspec->meanDataRate); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitPolicy +\brief determine the current admit control policy and apply it for the offered tspec +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limAdmitPolicy( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_FAILURE; + tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo; + + switch (pAdmitPolicy->type) + { + case WNI_CFG_ADMIT_POLICY_ADMIT_ALL: + retval = eSIR_SUCCESS; + break; + + case WNI_CFG_ADMIT_POLICY_BW_FACTOR: + retval = limAdmitPolicyOversubscription(pMac, pTspec, + &pMac->lim.admitPolicyInfo, &pMac->lim.tspecInfo[0], psessionEntry); + if (retval != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("rejected by BWFactor policy"));) + break; + + case WNI_CFG_ADMIT_POLICY_REJECT_ALL: + retval = eSIR_FAILURE; + break; + + default: + retval = eSIR_SUCCESS; + limLog(pMac, LOGE, FL("Admit Policy %d unknown, admitting all traffic"), + pAdmitPolicy->type); + break; + } + return retval; +} + +/** ------------------------------------------------------------- +\fn limTspecDelete +\brief delete the specified tspec +\param tpAniSirGlobal pMac +\param tpLimTspecInfo pInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +//----------------------------------------------------------------------------- +// delete the specified tspec +void limTspecDelete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo) +{ + if (pInfo == NULL) + return; + //pierre + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tspec entry = %d"), pInfo->idx); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("delete tspec %p"), pInfo); + pInfo->inuse = 0; + + return; +} + +/** ------------------------------------------------------------- +\fn limTspecFindByStaAddr +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param \param tANI_U8 *pAddr +\param tSirMacTspecIE *pTspecIE +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +// find the specified tspec in the list +static tSirRetStatus +limTspecFindByStaAddr( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirMacTspecIE *pTspecIE, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (vos_mem_compare(pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr))) + && (vos_mem_compare((tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, + sizeof(tSirMacTspecIE)))) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limTspecFindByAssocId +\brief find tspec with matchin staid and Tspec +\param tpAniSirGlobal pMac +\param tANI_U32 staid +\param tSirMacTspecIE *pTspecIE +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limTspecFindByAssocId( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTspecIE *pTspecIE, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d"), assocId); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"), + pTspecIE->tsinfo.traffic.direction, pTspecIE->tsinfo.traffic.tsid); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (assocId == pTspecList->assocId) + && (vos_mem_compare((tANI_U8 *)pTspecIE, (tANI_U8 *)&pTspecList->tspec, + sizeof(tSirMacTspecIE)))) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limFindTspec +\brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid +\param tANI_U16 assocId +\param tpAniSirGlobal pMac +\param tSirMacTSInfo *pTsInfo +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +tSirRetStatus +limFindTspec( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *pTsInfo, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d"), assocId); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"), + pTsInfo->traffic.direction, pTsInfo->traffic.tsid); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (assocId == pTspecList->assocId) + && (pTsInfo->traffic.direction == pTspecList->tspec.tsinfo.traffic.direction) + && (pTsInfo->traffic.tsid == pTspecList->tspec.tsinfo.traffic.tsid)) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limTspecAdd +\brief add or update the specified tspec to the tspec list +\param tpAniSirGlobal pMac +\param tANI_U8 *pAddr +\param tANI_U16 assocId +\param tSirMacTspecIE *pTspec +\param tANI_U32 interval +\param tpLimTspecInfo *ppInfo + +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +tSirRetStatus limTspecAdd( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tANI_U16 assocId, + tSirMacTspecIE *pTspec, + tANI_U32 interval, + tpLimTspecInfo *ppInfo) +{ + tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0]; + *ppInfo = NULL; + + // validate the assocId + if (assocId >= pMac->lim.maxStation) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid assocId 0x%x"), assocId);) + return eSIR_FAILURE; + } + + //decide whether to add/update + { + *ppInfo = NULL; + + if(eSIR_SUCCESS == limFindTspec(pMac, assocId, &pTspec->tsinfo, pTspecList, ppInfo)) + { + //update this entry. + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("updating TSPEC table entry = %d"), + (*ppInfo)->idx); + } + else + { + /* We didn't find one to update. So find a free slot in the + * LIM TSPEC list and add this new entry + */ + tANI_U8 ctspec = 0; + for (ctspec = 0 , pTspecList = &pMac->lim.tspecInfo[0]; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if (! pTspecList->inuse) + { + limLog(pMac, LOG1, FL("Found free slot in TSPEC list. Add to TSPEC table entry %d"), ctspec); + break; + } + } + + if (ctspec >= LIM_NUM_TSPEC_MAX) + return eSIR_FAILURE; + + //Record the new index entry + pTspecList->idx = ctspec; + } + } + + // update the tspec info + pTspecList->tspec = *pTspec; + pTspecList->assocId = assocId; + vos_mem_copy(pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr)); + + // for edca tspec's, we are all done + if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) + { + pTspecList->inuse = 1; + *ppInfo = pTspecList; + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for EDCA AccessPolicy")); + return eSIR_SUCCESS; + } + + /* + * for hcca tspec's, must set the parameterized bit in the queues + * the 'ts' bit in the queue data structure indicates that the queue is + * parameterized (hcca). When the schedule is written this bit is used + * in the tsid field (bit 3) and the other three bits (0-2) are simply + * filled in as the user priority (or qid). This applies only to uplink + * polls where the qos control field must contain the tsid specified in the + * tspec. + */ + pTspecList->inuse = 1; + *ppInfo = pTspecList; + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for HCCA AccessPolicy")); + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limValidateAccessPolicy +\brief Validates Access policy +\param tpAniSirGlobal pMac +\param tANI_U8 accessPolicy +\param tANI_U16 assocId +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static tSirRetStatus +limValidateAccessPolicy( + tpAniSirGlobal pMac, + tANI_U8 accessPolicy, + tANI_U16 assocId, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_FAILURE; + tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if ((pSta == NULL) || (! pSta->valid)) + { + PELOGE(limLog(pMac, LOGE, FL("invalid station address passed"));) + return eSIR_FAILURE; + } + + switch (accessPolicy) + { + case SIR_MAC_ACCESSPOLICY_EDCA: + if (pSta->wmeEnabled || pSta->lleEnabled) + retval = eSIR_SUCCESS; + break; + + case SIR_MAC_ACCESSPOLICY_HCCA: + case SIR_MAC_ACCESSPOLICY_BOTH: + default: + PELOGE(limLog(pMac, LOGE, FL("Invalid accessPolicy %d"), accessPolicy);) + break; + } + + if (retval != eSIR_SUCCESS) + limLog(pMac, LOGW, FL("failed (accPol %d, staId %d, lle %d, wme %d, wsm %d)"), + accessPolicy, pSta->staIndex, pSta->lleEnabled, pSta->wmeEnabled, pSta->wsmEnabled); + + return retval; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlAddTS +\brief Determine if STA with the specified TSPEC can be admitted. If it can, + a schedule element is provided +\param tpAniSirGlobal pMac +\param tANI_U8 *pAddr, +\param tSirAddtsReqInfo *pAddts, +\param tSirMacQosCapabilityIE *pQos, +\param tANI_U16 assocId, // assocId, valid only if alloc==true +\param tANI_U8 alloc, // true=>allocate bw for this tspec, + // else determine only if space is available +\param tSirMacScheduleIE *pSch, +\param tANI_U8 *pTspecIdx //index to the lim tspec table. +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limAdmitControlAddTS( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirAddtsReqInfo *pAddts, + tSirMacQosCapabilityStaIE *pQos, + tANI_U16 assocId, // assocId, valid only if alloc==true + tANI_U8 alloc, // true=>allocate bw for this tspec, + // else determine only if space is available + tSirMacScheduleIE *pSch, + tANI_U8 *pTspecIdx, //index to the lim tspec table. + tpPESession psessionEntry + ) +{ + tpLimTspecInfo pTspecInfo; + tSirRetStatus retval; + tANI_U32 svcInterval; + (void) pQos; + + // TBD: modify tspec as needed + // EDCA: need to fill in the medium time and the minimum phy rate + // to be consistent with the desired traffic parameters. + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tsid %d, directn %d, start %d, intvl %d, accPolicy %d, up %d"), + pAddts->tspec.tsinfo.traffic.tsid, pAddts->tspec.tsinfo.traffic.direction, + pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval, + pAddts->tspec.tsinfo.traffic.accessPolicy, pAddts->tspec.tsinfo.traffic.userPrio); + + // check for duplicate tspec + retval = (alloc) + ? limTspecFindByAssocId(pMac, assocId, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo) + : limTspecFindByStaAddr(pMac, pAddr, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo); + + if (retval == eSIR_SUCCESS) + { + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("duplicate tspec (index %d)!"), pTspecInfo->idx); + return eSIR_FAILURE; + } + + // check that the tspec's are well formed and acceptable + if (limValidateTspec(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("tspec validation failed"));) + return eSIR_FAILURE; + } + + // determine a service interval for the tspec + if (limCalculateSvcInt(pMac, &pAddts->tspec, &svcInterval) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("SvcInt calculate failed"));) + return eSIR_FAILURE; + } + + // determine if the tspec can be admitted or not based on current policy + if (limAdmitPolicy(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("tspec rejected by admit control policy"));) + return eSIR_FAILURE; + } + + // fill in a schedule if requested + if (pSch != NULL) + { + vos_mem_set((tANI_U8 *) pSch, sizeof(*pSch), 0); + pSch->svcStartTime = pAddts->tspec.svcStartTime; + pSch->svcInterval = svcInterval; + pSch->maxSvcDuration = (tANI_U16) pSch->svcInterval; // use SP = SI + pSch->specInterval = 0x1000; // fixed for now: TBD + + pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction; + pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid; + pSch->info.aggregation = 0; // no support for aggregation for now: TBD + } + + // if no allocation is requested, done + if (! alloc) + return eSIR_SUCCESS; + + // check that we are in the proper mode to deal with the tspec type + if (limValidateAccessPolicy(pMac, (tANI_U8) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGW, FL("AccessPolicy %d is not valid in current mode"), + pAddts->tspec.tsinfo.traffic.accessPolicy); + return eSIR_FAILURE; + } + + // add tspec to list + if (limTspecAdd(pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("no space in tspec list"));) + return eSIR_FAILURE; + } + + //passing lim tspec table index to the caller + *pTspecIdx = pTspecInfo->idx; + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlDeleteTS +\brief Delete the specified Tspec for the specified STA +\param tpAniSirGlobal pMac +\param tANI_U16 assocId +\param tSirMacTSInfo *pTsInfo +\param tANI_U8 *pTsStatus +\param tANI_U8 *ptspecIdx +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limAdmitControlDeleteTS( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *pTsInfo, + tANI_U8 *pTsStatus, + tANI_U8 *ptspecIdx) +{ + tpLimTspecInfo pTspecInfo = NULL; + + if (pTsStatus != NULL) + *pTsStatus = 0; + + if (limFindTspec(pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0], &pTspecInfo) == eSIR_SUCCESS) + { + if(pTspecInfo != NULL) + { + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Tspec entry %d found"), pTspecInfo->idx); + + *ptspecIdx = pTspecInfo->idx; + limTspecDelete(pMac, pTspecInfo); + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlDeleteSta +\brief Delete all TSPEC for the specified STA +\param tpAniSirGlobal pMac +\param tANI_U16 assocId +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limAdmitControlDeleteSta( + tpAniSirGlobal pMac, + tANI_U16 assocId) +{ + tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0]; + int ctspec; + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) + { + if (assocId == pTspecInfo->assocId) + { + limTspecDelete(pMac, pTspecInfo); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Deleting TSPEC %d for assocId %d"), + ctspec, assocId); + } + } + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("assocId %d done"), assocId); + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlInit +\brief init tspec table +\param tpAniSirGlobal pMac +\return eSirRetStatus - status + -------------------------------------------------------------*/ +tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac) +{ + vos_mem_set(pMac->lim.tspecInfo, LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo), 0); + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limUpdateAdmitPolicy +\brief Set the admit control policy based on CFG parameters +\param tpAniSirGlobal pMac +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limUpdateAdmitPolicy(tpAniSirGlobal pMac) +{ + tANI_U32 val; + if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_POLICY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_POLICY")); + return eSIR_FAILURE; + } + pMac->lim.admitPolicyInfo.type = (tANI_U8) val; + if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_BWFACTOR, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_BWFACTOR")); + return eSIR_FAILURE; + } + pMac->lim.admitPolicyInfo.bw_factor = (tANI_U8) val; + + PELOG1(limLog(pMac, LOG1, FL("LIM: AdmitPolicy %d, bw_factor %d"), + pMac->lim.admitPolicyInfo.type, pMac->lim.admitPolicyInfo.bw_factor);) + + return eSIR_SUCCESS; +} + + +/** ------------------------------------------------------------- +\fn limSendHalMsgAddTs +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param tANI_U16 staIdx +\param tANI_U8 tspecIdx +\param tSirMacTspecIE tspecIE +\param tSirTclasInfo *tclasInfo +\param tANI_U8 tclasProc +\param tANI_U16 tsm_interval +\return eSirRetStatus - status + -------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_ESE +tSirRetStatus +limSendHalMsgAddTs( + tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirMacTspecIE tspecIE, + tANI_U8 sessionId, + tANI_U16 tsm_interval) +#else +tSirRetStatus +limSendHalMsgAddTs( + tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirMacTspecIE tspecIE, + tANI_U8 sessionId) +#endif +{ + tSirMsgQ msg; + tpAddTsParams pAddTsParam; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tpPESession psessionEntry = peFindSessionBySessionId(pMac, sessionId); + if (psessionEntry == NULL) { + limLog( pMac, LOGP, + FL("Unable to get Session for session Id %d"), sessionId); + return eSIR_FAILURE; + } +#endif + + pAddTsParam = vos_mem_malloc(sizeof(tAddTsParams)); + if (NULL == pAddTsParam) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *)pAddTsParam, sizeof(tAddTsParams), 0); + pAddTsParam->staIdx = staIdx; + pAddTsParam->tspecIdx = tspecIdx; + vos_mem_copy(&pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE)); + pAddTsParam->sessionId = sessionId; + pAddTsParam->sme_session_id = psessionEntry->smeSessionId; + +#ifdef FEATURE_WLAN_ESE + pAddTsParam->tsm_interval = tsm_interval; +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadEnabled && + psessionEntry->is11Rconnection) + pAddTsParam->setRICparams = 1; +#endif + + msg.type = WDA_ADD_TS_REQ; + msg.bodyptr = pAddTsParam; + msg.bodyval = 0; + + /* We need to defer any incoming messages until we get a + * WDA_ADD_TS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, sessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddTsParam); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limSendHalMsgDelTs +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param tANI_U16 staIdx +\param tANI_U8 tspecIdx +\param tSirAddtsReqInfo addts +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limSendHalMsgDelTs( + tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirDeltsReqInfo delts, + tANI_U8 sessionId, + tANI_U8 *bssId) +{ + tSirMsgQ msg; + tpDelTsParams pDelTsParam; + tpPESession psessionEntry = NULL; + + pDelTsParam = vos_mem_malloc(sizeof(tDelTsParams)); + if (NULL == pDelTsParam) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return eSIR_MEM_ALLOC_FAILED; + } + + msg.type = WDA_DEL_TS_REQ; + msg.bodyptr = pDelTsParam; + msg.bodyval = 0; + vos_mem_set((tANI_U8 *)pDelTsParam, sizeof(tDelTsParams), 0); + + //filling message parameters. + pDelTsParam->staIdx = staIdx; + pDelTsParam->tspecIdx = tspecIdx; + vos_mem_copy(&pDelTsParam->bssId, bssId, sizeof(tSirMacAddr)); + + psessionEntry = peFindSessionBySessionId(pMac, sessionId); + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("Session does Not exist with given sessionId :%d "), + sessionId);) + goto err; + } + pDelTsParam->sessionId = psessionEntry->smeSessionId; + pDelTsParam->userPrio = delts.tsinfo.traffic.userPrio; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadEnabled && + psessionEntry->is11Rconnection) { + vos_mem_copy(&pDelTsParam->delTsInfo, &delts, sizeof(tSirDeltsReqInfo)); + pDelTsParam->setRICparams = 1; + } +#endif + + PELOGW(limLog(pMac, LOGW, FL("calling wdaPostCtrlMsg()"));) + MTRACE(macTraceMsgTx(pMac, sessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + goto err; + } + return eSIR_SUCCESS; + +err: + vos_mem_free(pDelTsParam); + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limProcessHalAddTsRsp +\brief This function process the WDA_ADD_TS_RSP from HAL. +\ If response is successful, then send back SME_ADDTS_RSP. +\ Otherwise, send DELTS action frame to peer and then +\ then send back SME_ADDTS_RSP. +\ +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +-------------------------------------------------------------*/ +void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpAddTsParams pAddTsRspMsg = NULL; + tpDphHashNode pSta = NULL; + tANI_U16 assocId =0; + tSirMacAddr peerMacAddr; + tANI_U8 rspReqd = 1; + tpPESession psessionEntry = NULL; + + + /* Need to process all the deferred messages enqueued + * since sending the WDA_ADD_TS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (NULL == limMsg->bodyptr) + { + limLog(pMac, LOGP, FL("Received WDA_ADD_TS_RSP with NULL ")); + goto end; + } + + pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr); + + // 090803: Use peFindSessionBySessionId() to obtain the PE session context + // from the sessionId in the Rsp Msg from HAL + psessionEntry = peFindSessionBySessionId(pMac, pAddTsRspMsg->sessionId); + + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId :%d "), pAddTsRspMsg->sessionId);) + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec, + pMac->lim.gLimAddtsReq.sessionId, pMac->lim.gLimAddtsReq.transactionId); + goto end; + } + + if(pAddTsRspMsg->status == eHAL_STATUS_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, FL("Received successful ADDTS response from HAL "));) + // Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_SUCCESS, psessionEntry, pAddTsRspMsg->tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + goto end; + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Received failure ADDTS response from HAL "));) + + // Send DELTS action frame to AP + // 090803: Get peer MAC addr from session + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + // 090803: Add the SME Session ID + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &pAddTsRspMsg->tspec.tsinfo, &pAddTsRspMsg->tspec, + psessionEntry); + + // Delete TSPEC + // 090803: Pull the hash table from the session + pSta = dphLookupAssocId(pMac, pAddTsRspMsg->staIdx, &assocId, + &psessionEntry->dph.dphHashTable); + if (pSta != NULL) + limAdmitControlDeleteTS(pMac, assocId, &pAddTsRspMsg->tspec.tsinfo, NULL, (tANI_U8 *)&pAddTsRspMsg->tspecIdx); + + // Send SME_ADDTS_RSP + // 090803: Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + goto end; + } + +end: + if (pAddTsRspMsg != NULL) + vos_mem_free(pAddTsRspMsg); + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limApi.c new file mode 100644 index 0000000000000..5e7a91c0c23ff --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limApi.c @@ -0,0 +1,2428 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limApi.cc contains the functions that are + * exported by LIM to other modules. + * + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniCfgSta.h" +#include "wniApi.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limApi.h" +#include "limGlobal.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limIbssPeerMgmt.h" +#include "limAdmitControl.h" +#include "pmmApi.h" +#include "logDump.h" +#include "limSendSmeRspMessages.h" +#include "wmmApsd.h" +#include "limTrace.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "wlan_qct_wda.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#include +#include "vos_types.h" +#include "vos_packet.h" +#include "vos_utils.h" +#include "wlan_qct_tl.h" +#include "sysStartup.h" + + +static void __limInitScanVars(tpAniSirGlobal pMac) +{ + pMac->lim.gLimUseScanModeForLearnMode = 1; + + pMac->lim.gLimSystemInScanLearnMode = 0; + + // Scan related globals on STA + pMac->lim.gLimReturnAfterFirstMatch = 0; + pMac->lim.gLim24Band11dScanDone = 0; + pMac->lim.gLim50Band11dScanDone = 0; + pMac->lim.gLimReturnUniqueResults = 0; + + // Background Scan related globals on STA + pMac->lim.gLimNumOfBackgroundScanSuccess = 0; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0; + pMac->lim.gLimNumOfForcedBkgndScan = 0; + pMac->lim.gLimBackgroundScanDisable = false; //based on BG timer + pMac->lim.gLimForceBackgroundScanDisable = false; //debug control flag + pMac->lim.gLimBackgroundScanTerminate = TRUE; //controlled by SME + pMac->lim.gLimReportBackgroundScanResults = FALSE; //controlled by SME + + pMac->lim.gLimCurrentScanChannelId = 0; + pMac->lim.gpLimMlmScanReq = NULL; + pMac->lim.gDeferMsgTypeForNOA = 0; + pMac->lim.gpDefdSmeMsgForNOA = NULL; + pMac->lim.gLimMlmScanResultLength = 0; + pMac->lim.gLimSmeScanResultLength = 0; + + vos_mem_set(pMac->lim.gLimCachedScanHashTable, + sizeof(pMac->lim.gLimCachedScanHashTable), 0); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + + pMac->lim.gLimMlmLfrScanResultLength = 0; + pMac->lim.gLimSmeLfrScanResultLength = 0; + + vos_mem_set(pMac->lim.gLimCachedLfrScanHashTable, + sizeof(pMac->lim.gLimCachedLfrScanHashTable), 0); +#endif + pMac->lim.gLimBackgroundScanChannelId = 0; + pMac->lim.gLimBackgroundScanStarted = 0; + pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT; + pMac->lim.gLimRestoreCBCount = 0; + vos_mem_set(pMac->lim.gLimLegacyBssidList, + sizeof(pMac->lim.gLimLegacyBssidList), 0); + + /* Fill in default values */ + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = 0; + + // abort scan is used to abort an on-going scan + pMac->lim.abortScan = 0; + vos_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0); + vos_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0); + +//WLAN_SUSPEND_LINK Related + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimResumeCallback = NULL; +//end WLAN_SUSPEND_LINK Related +} + + +static void __limInitBssVars(tpAniSirGlobal pMac) +{ + vos_mem_set((void*)pMac->lim.gpSession, + sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId, 0); + + /* This is for testing purposes only, be default should always be off */ + pMac->lim.gLimForceNoPropIE = 0; + pMac->lim.gpLimMlmSetKeysReq = NULL; + pMac->lim.gpLimMlmRemoveKeyReq = NULL; +} + + +static void __limInitStatsVars(tpAniSirGlobal pMac) +{ + pMac->lim.gLimNumBeaconsRcvd = 0; + pMac->lim.gLimNumBeaconsIgnored = 0; + + pMac->lim.gLimNumDeferredMsgs = 0; + + /// Variable to keep track of number of currently associated STAs + pMac->lim.gLimNumOfAniSTAs = 0; // count of ANI peers + + // Heart-Beat interval value + pMac->lim.gLimHeartBeatCount = 0; + + // Statistics to keep track of no. beacons rcvd in heart beat interval + vos_mem_set(pMac->lim.gLimHeartBeatBeaconStats, + sizeof(pMac->lim.gLimHeartBeatBeaconStats), 0); + +#ifdef WLAN_DEBUG + // Debug counters + pMac->lim.numTot = 0; + pMac->lim.numBbt = 0; + pMac->lim.numProtErr = 0; + pMac->lim.numLearn = 0; + pMac->lim.numLearnIgnore = 0; + pMac->lim.numSme = 0; + vos_mem_set(pMac->lim.numMAC, sizeof(pMac->lim.numMAC), 0); + pMac->lim.gLimNumAssocReqDropInvldState = 0; + pMac->lim.gLimNumAssocReqDropACRejectTS = 0; + pMac->lim.gLimNumAssocReqDropACRejectSta = 0; + pMac->lim.gLimNumReassocReqDropInvldState = 0; + pMac->lim.gLimNumHashMissIgnored = 0; + pMac->lim.gLimUnexpBcnCnt = 0; + pMac->lim.gLimBcnSSIDMismatchCnt = 0; + pMac->lim.gLimNumLinkEsts = 0; + pMac->lim.gLimNumRxCleanup = 0; + pMac->lim.gLim11bStaAssocRejectCount = 0; +#endif +} + +static void __limInitStates(tpAniSirGlobal pMac) +{ + // Counts Heartbeat failures + pMac->lim.gLimHBfailureCntInLinkEstState = 0; + pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0; + pMac->lim.gLimHBfailureCntInOtherStates = 0; + pMac->lim.gLimRspReqd = 0; + pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE; + + /// MLM State visible across all Sirius modules + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, eLIM_MLM_IDLE_STATE)); + pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE; + + /// Previous MLM State + pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE; + +#ifdef GEN4_SCAN + // LIM to HAL SCAN Management Message Interface states + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; +#endif // GEN4_SCAN + + /** + * Initialize state to eLIM_SME_OFFLINE_STATE + */ + pMac->lim.gLimSmeState = eLIM_SME_OFFLINE_STATE; + + /** + * By default assume 'unknown' role. This will be updated + * when SME_START_BSS_REQ is received. + */ + + vos_mem_set(&pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlapNonGfParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams), 0); + vos_mem_set(&pMac->lim.gLimNoShortSlotParams, sizeof(tLimNoShortSlotParams), 0); + + pMac->lim.gLimPhyMode = 0; + pMac->lim.scanStartTime = 0; // used to measure scan time + + vos_mem_set(pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr), 0); + pMac->lim.ackPolicy = 0; + + pMac->lim.gLimProbeRespDisableFlag = 0; // control over probe response +} + +static void __limInitVars(tpAniSirGlobal pMac) +{ + // Place holder for Measurement Req/Rsp/Ind related info + + // WDS info + pMac->lim.gLimNumWdsInfoInd = 0; + pMac->lim.gLimNumWdsInfoSet = 0; + vos_mem_set(&pMac->lim.gLimWdsInfo, sizeof(tSirWdsInfo), 0); + /* initialize some parameters */ + limInitWdsInfoParams(pMac); + + // Deferred Queue Paramters + vos_mem_set(&pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq), 0); + + // addts request if any - only one can be outstanding at any time + vos_mem_set(&pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq) , 0); + pMac->lim.gLimAddtsSent = 0; + pMac->lim.gLimAddtsRspTimerCount = 0; + + //protection related config cache + vos_mem_set(&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0); + pMac->lim.gLimProtectionControl = 0; + vos_mem_set(&pMac->lim.gLimAlternateRadio, sizeof(tSirAlternateRadioInfo), 0); + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + // WMM Related Flag + pMac->lim.gUapsdEnable = 0; + pMac->lim.gUapsdPerAcBitmask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + + // QoS-AC Downgrade: Initially, no AC is admitted + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0; + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0; + + //dialogue token List head/tail for Action frames request sent. + pMac->lim.pDialogueTokenHead = NULL; + pMac->lim.pDialogueTokenTail = NULL; + + vos_mem_set(&pMac->lim.tspecInfo, + sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX, 0); + + // admission control policy information + vos_mem_set(&pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo), 0); + + pMac->lim.gLastBeaconDtimCount = 0; + pMac->lim.gLastBeaconDtimPeriod = 0; + + //Scan in Power Save Flag + pMac->lim.gScanInPowersave = 0; + pMac->lim.probeCounter = 0; + pMac->lim.maxProbe = 0; +} + +static void __limInitAssocVars(tpAniSirGlobal pMac) +{ + tANI_U32 val; + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) + { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + pMac->lim.gLimAssocStaLimit = val; + pMac->lim.gLimIbssStaLimit = val; + // Place holder for current authentication request + // being handled + pMac->lim.gpLimMlmAuthReq = NULL; + + /// MAC level Pre-authentication related globals + pMac->lim.gLimPreAuthChannelNumber = 0; + pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM; + vos_mem_set(&pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr), 0); + pMac->lim.gLimNumPreAuthContexts = 0; + vos_mem_set(&pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable), 0); + + // Placed holder to deauth reason + pMac->lim.gLimDeauthReasonCode = 0; + + // Place holder for Pre-authentication node list + pMac->lim.pLimPreAuthList = NULL; + + // Send Disassociate frame threshold parameters + pMac->lim.gLimDisassocFrameThreshold = LIM_SEND_DISASSOC_FRAME_THRESHOLD; + pMac->lim.gLimDisassocFrameCredit = 0; + + //One cache for each overlap and associated case. + vos_mem_set(pMac->lim.protStaOverlapCache, + sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE, 0); + vos_mem_set(pMac->lim.protStaCache, + sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE, 0); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.pSessionEntry = NULL; + pMac->lim.reAssocRetryAttempt = 0; +#endif + +} + + +static void __limInitTitanVars(tpAniSirGlobal pMac) +{ + // Debug workaround for BEACON's + // State change triggered by "dump 222" + pMac->lim.gLimScanOverride = 1; + pMac->lim.gLimScanOverrideSaved = eSIR_ACTIVE_SCAN; + pMac->lim.gLimTitanStaCount = 0; + pMac->lim.gLimBlockNonTitanSta = 0; +} + +static void __limInitHTVars(tpAniSirGlobal pMac) +{ + pMac->lim.htCapabilityPresentInBeacon = 0; + pMac->lim.gHTGreenfield = 0; + pMac->lim.gHTShortGI40Mhz = 0; + pMac->lim.gHTShortGI20Mhz = 0; + pMac->lim.gHTMaxAmsduLength = 0; + pMac->lim.gHTDsssCckRate40MHzSupport = 0; + pMac->lim.gHTPSMPSupport = 0; + pMac->lim.gHTLsigTXOPProtection = 0; + pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC; + pMac->lim.gHTAMpduDensity = 0; + + pMac->lim.gMaxAmsduSizeEnabled = false; + pMac->lim.gHTMaxRxAMpduFactor = 0; + pMac->lim.gHTServiceIntervalGranularity = 0; + pMac->lim.gHTControlledAccessOnly = 0; + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + pMac->lim.gHTPCOActive = 0; + + pMac->lim.gHTPCOPhase = 0; + pMac->lim.gHTSecondaryBeacon = 0; + pMac->lim.gHTDualCTSProtection = 0; + pMac->lim.gHTSTBCBasicMCS = 0; + pMac->lim.gAddBA_Declined = 0; // Flag to Decline the BAR if the particular bit (0-7) is being set +} + +static tSirRetStatus __limInitConfig( tpAniSirGlobal pMac ) +{ + tANI_U32 val1, val2, val3; + tANI_U16 val16; + tANI_U8 val8; + tSirMacHTCapabilityInfo *pHTCapabilityInfo; + tSirMacHTInfoField1 *pHTInfoField1; + tpSirPowerSaveCfg pPowerSaveConfig; + tSirMacHTParametersInfo *pAmpduParamInfo; + + /* Read all the CFGs here that were updated before peStart is called */ + /* All these CFG READS/WRITES are only allowed in init, at start when there is no session + * and they will be used throughout when there is no session + */ + + if(wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + return eSIR_FAILURE; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG"));) + return eSIR_FAILURE; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + + //channel bonding mode could be set to anything from 0 to 4(Titan had these + // modes But for Taurus we have only two modes: enable(>0) or disable(=0) + pHTCapabilityInfo->supportedChannelWidthSet = val2 ? + WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + return eSIR_FAILURE; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG"));) + return eSIR_FAILURE; + } + + val8 = ( tANI_U8 ) val1; + pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8; + pHTInfoField1->recommendedTxWidthSet = + (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet; + if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field"));) + return eSIR_FAILURE; + } + + /* WNI_CFG_HEART_BEAT_THRESHOLD */ + + if( wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));) + return eSIR_FAILURE; + } + if(!val1) + { + limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER); + pMac->sys.gSysEnableLinkMonitorMode = 0; + } + else + { + //No need to activate the timer during init time. + pMac->sys.gSysEnableLinkMonitorMode = 1; + } + + /* WNI_CFG_SHORT_GI_20MHZ */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));) + return eSIR_FAILURE; + } + + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2; + pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val3; + + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != + eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + return eSIR_FAILURE; + } + + /* WNI_CFG_MAX_RX_AMPDU_FACTOR */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));) + return eSIR_FAILURE; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("cfg get short preamble failed")); + return eSIR_FAILURE; + } + + /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in + limHandleCFGparamUpdate do we want to update this? */ + if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get short preamble failed")); + return eSIR_FAILURE; + } + + /* WNI_CFG_MAX_PS_POLL */ + + if (!pMac->psOffloadEnabled) + { + /* Allocate and fill in power save configuration. */ + pPowerSaveConfig = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if (NULL == pPowerSaveConfig) + { + PELOGE(limLog(pMac, LOGE, + FL("LIM: Cannot allocate memory for power save configuration"));) + return eSIR_FAILURE; + } + + /* This context should be valid if power-save configuration message has + * been already dispatched during initialization process. Re-using the + * present configuration mask + */ + vos_mem_copy(pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg, + sizeof(tSirPowerSaveCfg)); + + /* Note: it is okay to do this since DAL/HAL is alrady started */ + if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, + FL("LIM: pmmSendPowerSaveCfg() failed "));) + return eSIR_FAILURE; + } + } + + /* WNI_CFG_BG_SCAN_CHANNEL_LIST_CHANNEL_LIST */ + + PELOG1(limLog(pMac, LOG1, + FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel"));) + pMac->lim.gLimBackgroundScanChannelId = 0; + + /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */ + + /* This was initially done after resume notification from HAL. Now, DAL is + started before PE so this can be done here */ + handleHTCapabilityandHTInfo(pMac, NULL); + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP, + (tANI_U32 *) &pMac->lim.disableLDPCWithTxbfAP)) + { + limLog(pMac, LOGP, FL("cfg get disableLDPCWithTxbfAP failed")); + return eSIR_FAILURE; + } +#ifdef FEATURE_WLAN_TDLS + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED, + (tANI_U32 *) &pMac->lim.gLimTDLSBufStaEnabled)) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSBufStaEnabled failed")); + return eSIR_FAILURE; + } + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + (tANI_U32 *) &pMac->lim.gLimTDLSUapsdMask)) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed")); + return eSIR_FAILURE; + } + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + (tANI_U32 *) &pMac->lim.gLimTDLSOffChannelEnabled)) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed")); + return eSIR_FAILURE; + } + + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_TDLS_WMM_MODE_ENABLED, + (tANI_U32 *) &pMac->lim.gLimTDLSWmmMode)) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSWmmMode failed")); + return eSIR_FAILURE; + } +#endif + return eSIR_SUCCESS; +} + +/* + limStart + This function is to replace the __limProcessSmeStartReq since there is no + eWNI_SME_START_REQ post to PE. +*/ +tSirRetStatus limStart(tpAniSirGlobal pMac) +{ + tSirResultCodes retCode = eSIR_SUCCESS; + + PELOG1(limLog(pMac, LOG1, FL(" enter"));) + + if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + + // By default do not return after first scan match + pMac->lim.gLimReturnAfterFirstMatch = 0; + + // Initialize MLM state machine + limInitMlm(pMac); + + // By default return unique scan results + pMac->lim.gLimReturnUniqueResults = true; + pMac->lim.gLimSmeScanResultLength = 0; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->lim.gLimSmeLfrScanResultLength = 0; +#endif + } + else + { + /** + * Should not have received eWNI_SME_START_REQ in states + * other than OFFLINE. Return response to host and + * log error + */ + limLog(pMac, LOGE, FL("Invalid SME state %X"),pMac->lim.gLimSmeState ); + retCode = eSIR_FAILURE; + } + + return retCode; +} + +/** + * limInitialize() + * + *FUNCTION: + * This function is called from LIM thread entry function. + * LIM related global data structures are initialized in this function. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @return None + */ + +tSirRetStatus +limInitialize(tpAniSirGlobal pMac) +{ + tSirRetStatus status = eSIR_SUCCESS; + + __limInitAssocVars(pMac); + __limInitVars(pMac); + __limInitStates(pMac); + __limInitStatsVars(pMac); + __limInitBssVars(pMac); + __limInitScanVars(pMac); + __limInitHTVars(pMac); + __limInitTitanVars(pMac); + + status = limStart(pMac); + if(eSIR_SUCCESS != status) + { + return status; + } + + // Initializations for maintaining peers in IBSS + limIbssInit(pMac); + + if(!pMac->psOffloadEnabled) + pmmInitialize(pMac); + +#if defined WLAN_FEATURE_VOWIFI + rrmInitialize(pMac); +#endif + + vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue); + + //Initialize the configurations needed by PE + if( eSIR_FAILURE == __limInitConfig(pMac)) + { + //We need to undo everything in limStart + limCleanupMlm(pMac); + return eSIR_FAILURE; + } + + //initialize the TSPEC admission control table. + //Note that this was initially done after resume notification from HAL. + //Now, DAL is started before PE so this can be done here + limAdmitControlInit(pMac); + limRegisterHalIndCallBack(pMac); + + return status; + +} /*** end limInitialize() ***/ + + + +/** + * limCleanup() + * + *FUNCTION: + * This function is called upon reset or persona change + * to cleanup LIM state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limCleanup(tpAniSirGlobal pMac) +{ + v_PVOID_t pvosGCTx; + VOS_STATUS retStatus; + +//Before destroying the list making sure all the nodes have been deleted. +//Which should be the normal case, but a memory leak has been reported. + + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL; + + while(vos_list_remove_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration) == VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("Fixing leak! Deallocating pLimMgmtRegistration node")); + + vos_mem_free(pLimMgmtRegistration); + } + + vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue); + + limCleanupMlm(pMac); + limCleanupLmm(pMac); + + // free up preAuth table + if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL) + { + vos_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable); + pMac->lim.gLimPreAuthTimerTable.pTable = NULL; + pMac->lim.gLimPreAuthTimerTable.numEntry = 0; + } + + if(NULL != pMac->lim.pDialogueTokenHead) + { + limDeleteDialogueTokenList(pMac); + } + + if(NULL != pMac->lim.pDialogueTokenTail) + { + vos_mem_free(pMac->lim.pDialogueTokenTail); + pMac->lim.pDialogueTokenTail = NULL; + } + + if (pMac->lim.gpLimMlmSetKeysReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + + if (pMac->lim.gpLimMlmAuthReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + } + + if (pMac->lim.gpLimMlmRemoveKeyReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + + if (pMac->lim.gpDefdSmeMsgForNOA != NULL) + { + vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA); + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } + + if (pMac->lim.gpLimMlmScanReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmScanReq); + pMac->lim.gpLimMlmScanReq = NULL; + } + + // Now, finally reset the deferred message queue pointers + limResetDeferredMsgQ(pMac); + + pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + retStatus = WLANTL_DeRegisterMgmtFrmClient(pvosGCTx); + + if ( retStatus != VOS_STATUS_SUCCESS ) + PELOGE(limLog(pMac, LOGE, FL("DeRegistering the PE Handle with TL has failed bailing out..."));) + +#if defined WLAN_FEATURE_VOWIFI + rrmCleanup(pMac); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + limFTCleanupAllFTSessions(pMac); +#endif + +} /*** end limCleanup() ***/ + + +/** ------------------------------------------------------------- +\fn peOpen +\brief will be called in Open sequence from macOpen +\param tpAniSirGlobal pMac +\param tHalOpenParameters *pHalOpenParam +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam) +{ + tSirRetStatus status = eSIR_SUCCESS; + + pMac->lim.maxBssId = pMacOpenParam->maxBssId; + pMac->lim.maxStation = pMacOpenParam->maxStation; + + if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0)) { + PELOGE(limLog(pMac, LOGE, + FL("max number of Bssid or Stations cannot be zero!"));) + return eSIR_FAILURE; + } + + pMac->lim.limTimers.gpLimCnfWaitTimer = vos_mem_malloc(sizeof(TX_TIMER) * + (pMac->lim.maxStation + 1)); + if (NULL == pMac->lim.limTimers.gpLimCnfWaitTimer) { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + return eSIR_FAILURE; + } + + pMac->lim.gpSession = vos_mem_malloc(sizeof(tPESession)* + pMac->lim.maxBssId); + if (NULL == pMac->lim.gpSession) { + limLog(pMac, LOGE, FL("memory allocate failed!")); + status = eSIR_FAILURE; + goto pe_open_psession_fail; + } + + vos_mem_set(pMac->lim.gpSession, sizeof(tPESession) * + pMac->lim.maxBssId, 0); + + pMac->pmm.gPmmTim.pTim = vos_mem_malloc(sizeof(tANI_U8) * + pMac->lim.maxStation); + if (NULL == pMac->pmm.gPmmTim.pTim) { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!"));) + status = eSIR_FAILURE; + goto pe_open_ptim_fail; + } + vos_mem_set(pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8) * + pMac->lim.maxStation, 0); + + pMac->lim.mgmtFrameSessionId = 0xff; + pMac->lim.deferredMsgCnt = 0; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->lim.lkPeGlobalLock))) { + PELOGE(limLog(pMac, LOGE, FL("pe lock init failed!"));) + status = eSIR_FAILURE; + goto pe_open_lock_fail; + } + pMac->lim.deauthMsgCnt = 0; + + /* + * peOpen is successful by now, so it is right time to initialize + * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build file + * then nothing will be logged for PE module. + */ +#ifdef LIM_TRACE_RECORD + MTRACE(limTraceInit(pMac)); +#endif + return status; /* status here will be eSIR_SUCCESS */ + +pe_open_lock_fail: + vos_mem_free(pMac->pmm.gPmmTim.pTim); + pMac->pmm.gPmmTim.pTim = NULL; +pe_open_ptim_fail: + vos_mem_free(pMac->lim.gpSession); + pMac->lim.gpSession = NULL; +pe_open_psession_fail: + vos_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer); + pMac->lim.limTimers.gpLimCnfWaitTimer = NULL; + + return status; +} + +/** ------------------------------------------------------------- +\fn peClose +\brief will be called in close sequence from macClose +\param tpAniSirGlobal pMac +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus peClose(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG) + return eSIR_SUCCESS; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + peDeleteSession(pMac,&pMac->lim.gpSession[i]); + } + } + vos_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer); + pMac->lim.limTimers.gpLimCnfWaitTimer = NULL; + + if (pMac->lim.gpLimMlmOemDataReq) { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + vos_mem_free(pMac->lim.gpSession); + pMac->lim.gpSession = NULL; + vos_mem_free(pMac->pmm.gPmmTim.pTim); + pMac->pmm.gPmmTim.pTim = NULL; + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->lim.lkPeGlobalLock ) ) ) + { + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn peStart +\brief will be called in start sequence from macStart +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +tSirRetStatus peStart(tpAniSirGlobal pMac) +{ + tSirRetStatus status = eSIR_SUCCESS; + + status = limInitialize(pMac); +#if defined(ANI_LOGDUMP) + limDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + + return status; +} + +/** ------------------------------------------------------------- +\fn peStop +\brief will be called in stop sequence from macStop +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +void peStop(tpAniSirGlobal pMac) +{ + limCleanup(pMac); + SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE); + return; +} + +/** ------------------------------------------------------------- +\fn peFreeMsg +\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs) +\ to free a given PE message on the TX and MC thread. +\ This happens when there are messages pending in the PE +\ queue when system is being stopped and reset. +\param tpAniSirGlobal pMac +\param tSirMsgQ pMsg +\return none +-----------------------------------------------------------------*/ +v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg) +{ + if (pMsg != NULL) + { + if (NULL != pMsg->bodyptr) + { + if (SIR_BB_XPORT_MGMT_MSG == pMsg->type) + { + vos_pkt_return_packet((vos_pkt_t *)pMsg->bodyptr); + } + else + { + vos_mem_free((v_VOID_t*)pMsg->bodyptr); + } + } + pMsg->bodyptr = 0; + pMsg->bodyval = 0; + pMsg->type = 0; + } + return; +} + + +/** + * The function checks if a particular timer should be allowed + * into LIM while device is sleeping + */ +tANI_U8 limIsTimerAllowedInPowerSaveState(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tANI_U8 retStatus = TRUE; + + if(!limIsSystemInActiveState(pMac)) + { + switch(pMsg->type) + { + /* Don't allow following timer messages if in sleep */ + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + retStatus = FALSE; + break; + /* May allow following timer messages in sleep mode */ + case SIR_LIM_HASH_MISS_THRES_TIMEOUT: + + /* Safe to allow as of today, this triggers background scan + * which will not be started if the device is in power-save mode + * might need to block in the future if we decide to implement + * spectrum management + */ + case SIR_LIM_QUIET_TIMEOUT: + + /* Safe to allow as of today, this triggers background scan + * which will not be started if the device is in power-save mode + * might need to block in the future if we decide to implement + * spectrum management + */ + case SIR_LIM_QUIET_BSS_TIMEOUT: + + /* Safe to allow this timermessage, triggers background scan + * which is blocked in sleep mode + */ + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + + /* Safe to allow this timer, since, while in IMPS this timer will not + * be started. In case of BMPS sleep, SoftMAC handles the heart-beat + * when heart-beat control is handled back to PE, device would have + * already woken-up due to EXIT_BMPS_IND mesage from SoftMAC + */ + case SIR_LIM_HEART_BEAT_TIMEOUT: + case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT: + + /* Safe to allow, PE is not handling this message as of now. May need + * to block it, basically, free the buffer and restart the timer + */ + case SIR_LIM_REASSOC_FAIL_TIMEOUT: + case SIR_LIM_JOIN_FAIL_TIMEOUT: + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + case SIR_LIM_AUTH_FAIL_TIMEOUT: + case SIR_LIM_ADDTS_RSP_TIMEOUT: + retStatus = TRUE; + break; + + /* by default allow rest of messages */ + default: + retStatus = TRUE; + break; + + + } + } + + return retStatus; + +} + + + +/** + * limPostMsgApi() + * + *FUNCTION: + * This function is called from other thread while posting a + * message to LIM message Queue gSirLimMsgQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg - Pointer to the message structure + * @return None + */ + +tANI_U32 +limPostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + return vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg); + + +} /*** end limPostMsgApi() ***/ + + +/*-------------------------------------------------------------------------- + + \brief pePostMsgApi() - A wrapper function to post message to Voss msg queues + + This function can be called by legacy code to post message to voss queues OR + legacy code may keep on invoking 'limPostMsgApi' to post the message to voss queue + for dispatching it later. + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ + +tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + return (tSirRetStatus)limPostMsgApi(pMac, pMsg); +} + +/*-------------------------------------------------------------------------- + + \brief peProcessMessages() - Message Processor for PE + + Voss calls this function to dispatch the message to PE + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ + +tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg) +{ + if(pMac->gDriverType == eDRIVER_TYPE_MFG) + { + return eSIR_SUCCESS; + } + /** + * If the Message to be handled is for CFG Module call the CFG Msg Handler and + * for all the other cases post it to LIM + */ + if ( SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type)) + cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr); + else + limMessageProcessor(pMac, pMsg); + return eSIR_SUCCESS; +} + + + +// --------------------------------------------------------------------------- +/** + * peHandleMgmtFrame + * + * FUNCTION: + * Process the Management frames from TL + * + * LOGIC: + * + * ASSUMPTIONS: TL sends the packet along with the VOS GlobalContext + * + * NOTE: + * + * @param pvosGCtx Global Vos Context + * @param vossBuff Packet + * @return None + */ + +VOS_STATUS peHandleMgmtFrame( v_PVOID_t pvosGCtx, v_PVOID_t vosBuff) +{ + tpAniSirGlobal pMac; + tpSirMacMgmtHdr mHdr; + tSirMsgQ msg; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + v_U8_t *pRxPacketInfo; + + pVosPkt = (vos_pkt_t *)vosBuff; + if (NULL == pVosPkt) + { + return VOS_STATUS_E_FAILURE; + } + + pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, pvosGCtx); + if (NULL == pMac) + { + // cannot log a failure without a valid pMac + vos_pkt_return_packet(pVosPkt); + pVosPkt = NULL; + return VOS_STATUS_E_FAILURE; + } + + vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (void *)&pRxPacketInfo, VOS_FALSE ); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + vos_pkt_return_packet(pVosPkt); + pVosPkt = NULL; + return VOS_STATUS_E_FAILURE; + } + + + // + // The MPDU header is now present at a certain "offset" in + // the BD and is specified in the BD itself + // + + mHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + if(mHdr->fc.type == SIR_MAC_MGMT_FRAME) { + PELOG1(limLog( pMac, LOG1, + FL("RxBd=%p mHdr=%p Type: %d Subtype: %d Sizes:FC%d Mgmt%d"), + pRxPacketInfo, mHdr, mHdr->fc.type, mHdr->fc.subType, + sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr));) + + limLog(pMac, LOG1, FL("mpdu_len:%d hdr_len:%d data_len:%d"), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo), + WDA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo), + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)); + + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT, + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo), + LIM_TRACE_MAKE_RXMGMT(mHdr->fc.subType, + (tANI_U16) (((tANI_U16)(mHdr->seqControl.seqNumHi << 4)) + | mHdr->seqControl.seqNumLo)));) + } + + + // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG + msg.type = SIR_BB_XPORT_MGMT_MSG; + msg.bodyptr = vosBuff; + msg.bodyval = 0; + + if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac, + &msg, + mHdr->fc.type, + mHdr->fc.subType )) + { + vos_pkt_return_packet(pVosPkt); + pVosPkt = NULL; + limLog( pMac, LOGW, + FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG" )); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +// --------------------------------------------------------------------------- +/** + * peRegisterTLHandle + * + * FUNCTION: + * Registers the Handler which, process the Management frames from TL + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @return None + */ + +void peRegisterTLHandle(tpAniSirGlobal pMac) +{ + v_PVOID_t pvosGCTx; + VOS_STATUS retStatus; + + pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + + retStatus = WLANTL_RegisterMgmtFrmClient(pvosGCTx, peHandleMgmtFrame); + + if (retStatus != VOS_STATUS_SUCCESS) + limLog( pMac, LOGP, FL("Registering the PE Handle with TL has failed bailing out...")); + +} + + +/** + * limIsSystemInScanState() + * + *FUNCTION: + * This function is called by various MAC software modules to + * determine if System is in Scan/Learn state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return true - System is in Scan/Learn state + * false - System is NOT in Scan/Learn state + */ + +tANI_U8 +limIsSystemInScanState(tpAniSirGlobal pMac) +{ + switch (pMac->lim.gLimSmeState) + { + case eLIM_SME_CHANNEL_SCAN_STATE: + case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: + case eLIM_SME_LINK_EST_WT_SCAN_STATE: + case eLIM_SME_WT_SCAN_STATE: + // System is in Learn mode + return true; + + default: + // System is NOT in Learn mode + return false; + } +} /*** end limIsSystemInScanState() ***/ + + + +/** + * limIsSystemInActiveState() + * + *FUNCTION: + * This function is called by various MAC software modules to + * determine if System is in Active/Wakeup state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return true - System is in Active state + * false - System is not in Active state + */ + +tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac) +{ + switch (pMac->pmm.gPmmState) + { + case ePMM_STATE_BMPS_WAKEUP: + case ePMM_STATE_IMPS_WAKEUP: + case ePMM_STATE_READY: + // System is in Active mode + return true; + default: + return false; + // System is NOT in Active mode + } +} + + + + + +/** +*\brief limReceivedHBHandler() +* +* This function is called by schBeaconProcess() upon +* receiving a Beacon on STA. This also gets called upon +* receiving Probe Response after heat beat failure is +* detected. +* +* param pMac - global mac structure +* param channel - channel number indicated in Beacon, Probe Response +* return - none +*/ + + +void +limReceivedHBHandler(tpAniSirGlobal pMac, tANI_U8 channelId, tpPESession psessionEntry) +{ + if((channelId == 0 ) || (channelId == psessionEntry->currentOperChannel) ) + psessionEntry->LimRxedBeaconCntDuringHB++; + + if(pMac->psOffloadEnabled) + psessionEntry->pmmOffloadInfo.bcnmiss = FALSE; + else + pMac->pmm.inMissedBeaconScenario = FALSE; +} /*** end limReceivedHBHandler() ***/ + + + +/* + * limProcessWdsInfo() + * + *FUNCTION: + * This function is called from schBeaconProcess in BP + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * @param propIEInfo - proprietary IE info + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * + *RETURNS: + * + */ + +void limProcessWdsInfo(tpAniSirGlobal pMac, + tSirPropIEStruct propIEInfo) +{ +} + + + +/** + * limInitWdsInfoParams() + * + *FUNCTION: + * This function is called while processing + * START_BSS/JOIN/REASSOC_REQ to initialize WDS info + * ind/set related parameters. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +void +limInitWdsInfoParams(tpAniSirGlobal pMac) +{ + pMac->lim.gLimWdsInfo.wdsLength = 0; + pMac->lim.gLimNumWdsInfoInd = 0; + pMac->lim.gLimNumWdsInfoSet = 0; +} /*** limInitWdsInfoParams() ***/ + + +/** ------------------------------------------------------------- +\fn limUpdateOverlapStaParam +\brief Updates overlap cache and param data structure +\param tpAniSirGlobal pMac +\param tSirMacAddr bssId +\param tpLimProtStaParams pStaParams +\return None + -------------------------------------------------------------*/ +void +limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams) +{ + int i; + if (!pStaParams->numSta) + { + vos_mem_copy(pMac->lim.protStaOverlapCache[0].addr, + bssId, + sizeof(tSirMacAddr)); + pMac->lim.protStaOverlapCache[0].active = true; + + pStaParams->numSta = 1; + + return; + } + + for (i=0; ilim.protStaOverlapCache[i].active) + { + if (vos_mem_compare( pMac->lim.protStaOverlapCache[i].addr, + bssId, + sizeof(tSirMacAddr))) { + return; } + } + else + break; + } + + if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE) + { + PELOG1(limLog(pMac, LOGW, FL("Overlap cache is full"));) + } + else + { + vos_mem_copy(pMac->lim.protStaOverlapCache[i].addr, + bssId, + sizeof(tSirMacAddr)); + pMac->lim.protStaOverlapCache[i].active = true; + + pStaParams->numSta++; + } +} + + +/** + * limIbssEncTypeMatched + * + *FUNCTION: + * This function compares the encryption type of the peer with self + * while operating in IBSS mode and detects mismatch. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pBeacon - Parsed Beacon Frame structure + * @param pSession - Pointer to the PE session + * + * @return eSIR_TRUE if encryption type is matched; eSIR_FALSE otherwise + */ +static tAniBool limIbssEncTypeMatched(tpSchBeaconStruct pBeacon, + tpPESession pSession) +{ + if (!pBeacon || !pSession) + return eSIR_FALSE; + + /* Open case */ + if (pBeacon->capabilityInfo.privacy == 0 + && pSession->encryptType == eSIR_ED_NONE) + return eSIR_TRUE; + + /* WEP case */ + if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 0 + && pBeacon->rsnPresent == 0 + && (pSession->encryptType == eSIR_ED_WEP40 + || pSession->encryptType == eSIR_ED_WEP104)) + return eSIR_TRUE; + + /* WPA-None case */ + if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1 + && pBeacon->rsnPresent == 0 + && pSession->encryptType == eSIR_ED_CCMP) + return eSIR_TRUE; + + return eSIR_FALSE; +} + + +/** + * limHandleIBSScoalescing() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pRxPacketInfo - Pointer to RX packet info structure + * + * @return Status whether to process or ignore received Beacon Frame + */ + +tSirRetStatus +limHandleIBSScoalescing( + tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tSirRetStatus retCode; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + /* Ignore the beacon when any of the conditions below is met: + 1. The beacon claims no IBSS network + 2. SSID in the beacon does not match SSID of self station + 3. Operational channel in the beacon does not match self station + 4. Encyption type in the beacon does not match with self station + */ + if ( (!pBeacon->capabilityInfo.ibss) || + (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) || + (psessionEntry->currentOperChannel != pBeacon->channelNumber) ) + retCode = eSIR_LIM_IGNORE_BEACON; + else if (limIbssEncTypeMatched(pBeacon, psessionEntry) != eSIR_TRUE) + { + PELOG3(limLog(pMac, LOG3, + FL("peer privacy %d peer wpa %d peer rsn %d self encType %d"), + pBeacon->capabilityInfo.privacy, + pBeacon->wpaPresent, + pBeacon->rsnPresent, + psessionEntry->encryptType);) + retCode = eSIR_LIM_IGNORE_BEACON; + } + else + { + tANI_U32 ieLen; + tANI_U16 tsfLater; + tANI_U8 *pIEs; + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + tsfLater = WDA_GET_RX_TSF_LATER(pRxPacketInfo); + pIEs = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + PELOG3(limLog(pMac, LOG3, FL("BEFORE Coalescing tsfLater val :%d"), tsfLater);) + retCode = limIbssCoalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,psessionEntry); + } + return retCode; +} /*** end limHandleIBSScoalescing() ***/ + + +/** + * limDetectChangeInApCapabilities() + * + *FUNCTION: + * This function is called while SCH is processing + * received Beacon from AP on STA to detect any + * change in AP's capabilities. If there any change + * is detected, Roaming is informed of such change + * so that it can trigger reassociation. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * Notification is enabled for STA product only since + * it is not a requirement on BP side. + * + * @param pMac Pointer to Global MAC structure + * @param pBeacon Pointer to parsed Beacon structure + * @return None + */ + +void +limDetectChangeInApCapabilities(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeacon, + tpPESession psessionEntry) +{ + tANI_U8 len; + tSirSmeApNewCaps apNewCaps; + tANI_U8 newChannel; + tSirRetStatus status = eSIR_SUCCESS; + apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo); + newChannel = (tANI_U8) pBeacon->channelNumber; + + if ( ( false == psessionEntry->limSentCapsChangeNtf ) && + ( ( ( !limIsNullSsid(&pBeacon->ssId) ) && + ( false == limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) ) ) || + ( (SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) != + SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) != + SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) != + SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) != + SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps) ) || + ( (newChannel != psessionEntry->currentOperChannel) && + (newChannel != 0) ) + ) ) ) + { + if( false == psessionEntry->fWaitForProbeRsp ) + { + /* If Beacon capabilities is not matching with the current capability, + * then send unicast probe request to AP and take decision after + * receiving probe response */ + if ( true == psessionEntry->fIgnoreCapsChange ) + { + limLog(pMac, LOGW, FL("Ignoring the Capability change as it is false alarm")); + return; + } + psessionEntry->fWaitForProbeRsp = true; + limLog(pMac, LOGW, FL("AP capabilities are not matching," + "sending directed probe request.. ")); + status = limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId, + psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + + if ( eSIR_SUCCESS != status ) + { + limLog(pMac, LOGE, FL("send ProbeReq failed")); + psessionEntry->fWaitForProbeRsp = false; + } + return; + } + /** + * BSS capabilities have changed. + * Inform Roaming. + */ + len = sizeof(tSirMacCapabilityInfo) + + sizeof(tSirMacAddr) + sizeof(tANI_U8) + + 3 * sizeof(tANI_U8) + // reserved fields + pBeacon->ssId.length + 1; + + vos_mem_copy(apNewCaps.bssId, + psessionEntry->bssId, + sizeof(tSirMacAddr)); + if (newChannel != psessionEntry->currentOperChannel) + { + PELOGE(limLog(pMac, LOGE, FL("Channel Change from %d --> %d - " + "Ignoring beacon!"), + psessionEntry->currentOperChannel, newChannel);) + return; + } + + /** + * When Cisco 1262 Enterprise APs are configured with WPA2-PSK with + * AES+TKIP Pairwise ciphers and WEP-40 Group cipher, they do not set + * the privacy bit in Beacons (wpa/rsnie is still present in beacons), + * the privacy bit is set in Probe and association responses. + * Due to this anomaly, we detect a change in + * AP capabilities when we receive a beacon after association and + * disconnect from the AP. The following check makes sure that we can + * connect to such APs + */ + else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) && + (pBeacon->rsnPresent || pBeacon->wpaPresent)) + { + PELOGE(limLog(pMac, LOGE, FL("BSS Caps (Privacy) bit 0 in beacon," + " but WPA or RSN IE present, Ignore Beacon!"));) + return; + } + else + apNewCaps.channelId = psessionEntry->currentOperChannel; + vos_mem_copy((tANI_U8 *) &apNewCaps.ssId, + (tANI_U8 *) &pBeacon->ssId, + pBeacon->ssId.length + 1); + + psessionEntry->fIgnoreCapsChange = false; + psessionEntry->fWaitForProbeRsp = false; + psessionEntry->limSentCapsChangeNtf = true; + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_AP_CAPS_CHANGED, + (tANI_U32 *) &apNewCaps, + len, psessionEntry->smeSessionId); + } + else if ( true == psessionEntry->fWaitForProbeRsp ) + { + /* Only for probe response frames and matching capabilities the control + * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp + * will be false, the control will not come here*/ + + limLog(pMac, LOG1, FL("capabilities in probe response are" + "matching with the current setting," + "Ignoring subsequent capability" + "mismatch")); + psessionEntry->fIgnoreCapsChange = true; + psessionEntry->fWaitForProbeRsp = false; + } + +} /*** limDetectChangeInApCapabilities() ***/ + + + + +// --------------------------------------------------------------------- +/** + * limUpdateShortSlot + * + * FUNCTION: + * Enable/Disable short slot + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param enable Flag to enable/disable short slot + * @return None + */ + +tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, tpSirProbeRespBeacon pBeacon, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + tSirSmeApNewCaps apNewCaps; + tANI_U32 nShortSlot; + tANI_U32 val = 0; + tANI_U32 phyMode; + + // Check Admin mode first. If it is disabled just return + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed")); + return eSIR_FAILURE; + } + if (val == false) + return eSIR_SUCCESS; + + // Check for 11a mode or 11b mode. In both cases return since slot time is constant and cannot/should not change in beacon + limGetPhyMode(pMac, &phyMode, psessionEntry); + if ((phyMode == WNI_CFG_PHY_MODE_11A) || (phyMode == WNI_CFG_PHY_MODE_11B)) + return eSIR_SUCCESS; + + apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo); + + // Earlier implementation: determine the appropriate short slot mode based on AP advertised modes + // when erp is present, apply short slot always unless, prot=on && shortSlot=off + // if no erp present, use short slot based on current ap caps + + // Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4); + + //Resolution : always use the shortSlot setting the capability info to decide slot time. + // The difference between the earlier implementation and the new one is only Case4. + /* + ERP IE Present | useProtection | shortSlot = QC STA Short Slot + Case1 1 1 1 1 //AP should not advertise this combination. + Case2 1 1 0 0 + Case3 1 0 1 1 + Case4 1 0 0 0 + Case5 0 1 1 1 + Case6 0 1 0 0 + Case7 0 0 1 1 + Case8 0 0 0 0 + */ + nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo); + + if (nShortSlot != psessionEntry->shortSlotTimeSupported) + { + // Short slot time capability of AP has changed. Adopt to it. + PELOG1(limLog(pMac, LOG1, FL("Shortslot capability of AP changed: %d"), nShortSlot);) + ((tpSirMacCapabilityInfo)&psessionEntry->limCurrentBssCaps)->shortSlotTime = (tANI_U16)nShortSlot; + psessionEntry->shortSlotTimeSupported = nShortSlot; + pBeaconParams->fShortSlotTime = (tANI_U8) nShortSlot; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + } + return eSIR_SUCCESS; +} + +/** ----------------------------------------------------------------- + \brief limHandleMissedBeaconInd() - handles missed beacon indication + + This function process the SIR_HAL_MISSED_BEACON_IND message from HAL, + and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND + to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'. + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + tpSirSmeMissedBeaconInd pSirMissedBeaconInd = + (tpSirSmeMissedBeaconInd)pMsg->bodyptr; + tpPESession psessionEntry = peFindSessionByBssIdx(pMac,pSirMissedBeaconInd->bssIdx); + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given BSSIdx:%d"), + pSirMissedBeaconInd->bssIdx); + return; + } +#endif + if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) || + (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)|| + (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) ) + { + pMac->pmm.inMissedBeaconScenario = TRUE; + PELOGE(limLog(pMac, LOGE, + FL("Sending EXIT_BMPS_IND to SME due to Missed beacon from FW"));) + limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD, psessionEntry); + } +/* ACTIVE_MODE_HB_OFFLOAD */ +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + else if(((pMac->pmm.gPmmState == ePMM_STATE_READY) || + (pMac->pmm.gPmmState == ePMM_STATE_BMPS_WAKEUP)) && + (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + pMac->pmm.inMissedBeaconScenario = TRUE; + PELOGE(limLog(pMac, LOGE, FL("Received Heart Beat Failure"));) + limMissedBeaconInActiveMode(pMac, psessionEntry); + } +#endif + else + { + limLog(pMac, LOGE, + FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d"), + pMac->pmm.gPmmState); + } + return; +} + +void +limSendHeartBeatTimeoutInd(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 statusCode; + tSirMsgQ msg; + + /* Prepare and post message to LIM Message Queue */ + msg.type = (tANI_U16) SIR_LIM_HEART_BEAT_TIMEOUT; + msg.bodyptr = psessionEntry; + msg.bodyval = 0; + limLog(pMac, LOGE, + FL("Heartbeat failure from Fw")); + + statusCode = limPostMsgApi(pMac, &msg); + + if(statusCode != eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("posting message %X to LIM failed, reason=%d"), + msg.type, statusCode); + } +} + +/** ----------------------------------------------------------------- + \brief limPsOffloadHandleMissedBeaconInd() - handles missed beacon indication + + This function process the SIR_HAL_MISSED_BEACON_IND message from HAL, + and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND + to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'. + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limPsOffloadHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeMissedBeaconInd pSirMissedBeaconInd = + (tpSirSmeMissedBeaconInd)pMsg->bodyptr; + tpPESession psessionEntry = + peFindSessionByBssIdx(pMac,pSirMissedBeaconInd->bssIdx); + + if(!psessionEntry) + { + limLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + return; + } + + /* Set Beacon Miss in Powersave Offload */ + psessionEntry->pmmOffloadInfo.bcnmiss = TRUE; + + /* + * If the session is in power save state then + * first need to come out of power save before + * triggering ap probing + */ + if(psessionEntry->pmmOffloadInfo.psstate == PMM_POWER_SAVE) + { + PELOGE(limLog(pMac, LOGE, + FL("Received Heart Beat Failure in Power Save State"));) + + /* Send Request for Full Power to SME */ + limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD, psessionEntry); + } + else + { + PELOGE(limLog(pMac, LOGE, + FL("Received Heart Beat Failure in active state"));) + /* Incase of Active state do AP probing immediately */ + limSendHeartBeatTimeoutInd(pMac, psessionEntry); + } + return; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus limRoamFillBssDescr(tpAniSirGlobal pMac, + tSirRoamOffloadSynchInd *pRoamOffloadSynchInd) +{ + v_U32_t uLen = 0; + tpSirProbeRespBeacon pParsedFrame; + tpSirMacMgmtHdr macHeader; + tANI_U8 *pBeaconProbeResp; + tSirBssDescription *pBssDescr = NULL; + + pBeaconProbeResp = (tANI_U8 *)pRoamOffloadSynchInd + + pRoamOffloadSynchInd->beaconProbeRespOffset; + macHeader = (tpSirMacMgmtHdr)pBeaconProbeResp; + pParsedFrame = + (tpSirProbeRespBeacon) vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if (NULL == pParsedFrame) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "%s: fail to allocate memory for frame",__func__); + return eHAL_STATUS_RESOURCES; + } + + if ( pRoamOffloadSynchInd->beaconProbeRespLength <= SIR_MAC_HDR_LEN_3A ) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "%s: Very few bytes in synchInd beacon / probe resp frame! length=%d", + __func__, pRoamOffloadSynchInd->beaconProbeRespLength); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,"LFR3: Beacon/Prb Rsp:"); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + pBeaconProbeResp, pRoamOffloadSynchInd->beaconProbeRespLength); + if (pRoamOffloadSynchInd->isBeacon) { + if (sirParseBeaconIE(pMac, pParsedFrame, + &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET], + pRoamOffloadSynchInd->beaconProbeRespLength - + SIR_MAC_HDR_LEN_3A) != eSIR_SUCCESS || !pParsedFrame->ssidPresent) { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "Parse error Beacon, length=%d", + pRoamOffloadSynchInd->beaconProbeRespLength); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + } + else { + if (sirConvertProbeFrame2Struct(pMac, + &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A], + pRoamOffloadSynchInd->beaconProbeRespLength - SIR_MAC_HDR_LEN_3A, + pParsedFrame) != eSIR_SUCCESS || + !pParsedFrame->ssidPresent) { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "Parse error ProbeResponse, length=%d", + pRoamOffloadSynchInd->beaconProbeRespLength); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + } + /* 24 byte MAC header and 12 byte to ssid IE */ + if (pRoamOffloadSynchInd->beaconProbeRespLength > + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) { + uLen = pRoamOffloadSynchInd->beaconProbeRespLength - + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET); + } + pRoamOffloadSynchInd->pbssDescription = + vos_mem_malloc(sizeof (tSirBssDescription) + uLen); /*De-allocated in + csrProcessRoamOffloadSynchInd*/ + pBssDescr = pRoamOffloadSynchInd->pbssDescription; + if (NULL == pBssDescr) + { + PELOGE(limLog( pMac, LOGE, "LFR3:Failed to allocate memory");) + VOS_ASSERT(pBssDescr != NULL); + return eHAL_STATUS_RESOURCES; + } + vos_mem_zero(pBssDescr, sizeof(tSirBssDescription)); + /* Length of BSS desription is without length of + * length itself and length of pointer + * that holds the next BSS description + */ + pBssDescr->length = (tANI_U16)( + sizeof(tSirBssDescription) - sizeof(tANI_U16) - + sizeof(tANI_U32) + uLen); + if (pParsedFrame->dsParamsPresent) + { + pBssDescr->channelId = pParsedFrame->channelNumber; + } + else if (pParsedFrame->HTInfo.present) + { + pBssDescr->channelId = pParsedFrame->HTInfo.primaryChannel; + } + else + { + /*If DS Params or HTIE is not present in the probe resp or beacon, + * then use the channel frequency provided by firmware to fill the + * channel in the BSS descriptor.*/ + pBssDescr->channelId = vos_freq_to_chan(pRoamOffloadSynchInd->chan_freq); + } + pBssDescr->channelIdSelf = pBssDescr->channelId; + + if ((pBssDescr->channelId > 0) && (pBssDescr->channelId < 15)) + { + int i; + /* 11b or 11g packet + * 11g if extended Rate IE is present or + * if there is an A rate in suppRate IE */ + for (i = 0; i < pParsedFrame->supportedRates.numRates; i++) { + if (sirIsArate(pParsedFrame->supportedRates.rate[i] & 0x7f)) { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + break; + } + } + if (pParsedFrame->extendedRatesPresent) { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + } + } else { + /* 11a packet */ + pBssDescr->nwType = eSIR_11A_NW_TYPE; + } + + pBssDescr->sinr = 0; + pBssDescr->beaconInterval = pParsedFrame->beaconInterval; + pBssDescr->timeStamp[0] = pParsedFrame->timeStamp[0]; + pBssDescr->timeStamp[1] = pParsedFrame->timeStamp[1]; + vos_mem_copy(&pBssDescr->capabilityInfo, + &pBeaconProbeResp[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_CAPAB_OFFSET], 2); + vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, + (tANI_U8 *) macHeader->bssId, + sizeof(tSirMacAddr)); + pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + if(pParsedFrame->mdiePresent) { + pBssDescr->mdiePresent = pParsedFrame->mdiePresent; + vos_mem_copy((tANI_U8 *)pBssDescr->mdie, (tANI_U8 *)pParsedFrame->mdie, + SIR_MDIE_SIZE); + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:BssDescr Info:", __func__); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + pBssDescr->bssId, sizeof(tSirMacAddr)); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "chan=%d, rssi=%d",pBssDescr->channelId,pBssDescr->rssi); + if (uLen) + { + vos_mem_copy(&pBssDescr->ieFields, + pBeaconProbeResp + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET), + uLen); + } + vos_mem_free(pParsedFrame); + return eHAL_STATUS_SUCCESS; +} + +/** ----------------------------------------------------------------- + * brief limRoamOffloadSynchInd() - Handles Roam Synch Indication + * param pMac - global mac structure + * return - none + ----------------------------------------------------------------- */ +void limRoamOffloadSynchInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpPESession psessionEntry; + tpPESession pftSessionEntry; + tANI_U8 sessionId; + tSirMsgQ mmhMsg; + tSirBssDescription *pbssDescription = NULL; + tpSirRoamOffloadSynchInd pRoamOffloadSynchInd = + (tpSirRoamOffloadSynchInd)pMsg->bodyptr; + + if (!pRoamOffloadSynchInd) { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "LFR3:%s:pRoamOffloadSynchInd is NULL", __func__); + return; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "LFR3: Received WDA_ROAM_OFFLOAD_SYNCH_IND"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:authStatus=%d, vdevId=%d", __func__, + pRoamOffloadSynchInd->authStatus, + pRoamOffloadSynchInd->roamedVdevId); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + pRoamOffloadSynchInd->bssId,6); + psessionEntry = peFindSessionByBssIdx(pMac, + pRoamOffloadSynchInd->roamedVdevId); + if (psessionEntry == NULL) { + PELOGE(limLog( pMac, LOGE, + "%s: LFR3:Unable to find session", __func__);) + return; + } + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) + return; + } + if (!HAL_STATUS_SUCCESS(limRoamFillBssDescr(pMac, + pRoamOffloadSynchInd))) { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "LFR3:%s:Failed to fill Bss Descr", __func__); + return; + } + pbssDescription = pRoamOffloadSynchInd->pbssDescription; + if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId, + &sessionId, pMac->lim.maxStation, + eSIR_INFRASTRUCTURE_MODE)) == NULL) { + limLog(pMac, LOGE, FL("LFR3: Session Can not be created for new AP" + "during Roam Offload Synch")); + limPrintMacAddr( pMac, pbssDescription->bssId, LOGE ); + return; + } + pftSessionEntry->peSessionId = sessionId; + sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr); + sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId); + pftSessionEntry->bssType = eSIR_INFRASTRUCTURE_MODE; + /*Set bRoamSynchInProgress here since this session is + * specific to roam synch indication. This flag will + * later be used to differentiate LFR3 with LFR2 in LIM + */ + pftSessionEntry->bRoamSynchInProgress = VOS_TRUE; + + if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + pftSessionEntry->limSystemRole = eLIM_STA_ROLE; + else { + limLog(pMac, LOGE, FL("LFR3:Invalid bss type")); + return; + } + pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; + pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:created session (%p) with id = %d", + __func__, pftSessionEntry, pftSessionEntry->peSessionId); + /* Update the ReAssoc BSSID of the current session */ + sirCopyMacAddr(psessionEntry->limReAssocbssId, pbssDescription->bssId); + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG2); + + /* Prepare the session right now with as much as possible */ + limFillFTSession(pMac, pbssDescription, pftSessionEntry, psessionEntry); + limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry, pbssDescription ); + mmhMsg.type = + pRoamOffloadSynchInd->messageType;/* eWNI_SME_ROAM_OFFLOAD_SYNCH_IND */ + mmhMsg.bodyptr = pRoamOffloadSynchInd; + mmhMsg.bodyval = 0; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:sending eWNI_SME_ROAM_OFFLOAD_SYNCH_IND", __func__); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +#endif +/** ----------------------------------------------------------------- + \brief limMicFailureInd() - handles mic failure indication + + This function process the SIR_HAL_MIC_FAILURE_IND message from HAL, + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeMicFailureInd pSirSmeMicFailureInd; + tpSirSmeMicFailureInd pSirMicFailureInd = (tpSirSmeMicFailureInd)pMsg->bodyptr; + tSirMsgQ mmhMsg; + tpPESession psessionEntry ; + tANI_U8 sessionId; + + if((psessionEntry = peFindSessionByBssid(pMac,pSirMicFailureInd->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + return; + } + + pSirSmeMicFailureInd = vos_mem_malloc(sizeof(tSirSmeMicFailureInd)); + if (NULL == pSirSmeMicFailureInd) + { + // Log error + limLog(pMac, LOGP, + FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND")); + return; + } + + pSirSmeMicFailureInd->messageType = eWNI_SME_MIC_FAILURE_IND; + pSirSmeMicFailureInd->length = sizeof(pSirSmeMicFailureInd); + pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId; + + vos_mem_copy(pSirSmeMicFailureInd->bssId, + pSirMicFailureInd->bssId, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.srcMacAddr, + pSirMicFailureInd->info.srcMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.taMacAddr, + pSirMicFailureInd->info.taMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.dstMacAddr, + pSirMicFailureInd->info.dstMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.rxMacAddr, + pSirMicFailureInd->info.rxMacAddr, + sizeof(tSirMacAddr)); + + pSirSmeMicFailureInd->info.multicast = + pSirMicFailureInd->info.multicast; + + pSirSmeMicFailureInd->info.keyId= + pSirMicFailureInd->info.keyId; + + pSirSmeMicFailureInd->info.IV1= + pSirMicFailureInd->info.IV1; + + vos_mem_copy(pSirSmeMicFailureInd->info.TSC, + pSirMicFailureInd->info.TSC,SIR_CIPHER_SEQ_CTR_SIZE); + + mmhMsg.type = eWNI_SME_MIC_FAILURE_IND; + mmhMsg.bodyptr = pSirSmeMicFailureInd; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +tANI_U8 limIsBeaconMissScenario(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + if(pMac->psOffloadEnabled) + { + tpSirMacMgmtHdr pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + tANI_U8 sessionId; + tpPESession psessionEntry = + peFindSessionByBssid(pMac,pHdr->bssId,&sessionId); + + if(psessionEntry && psessionEntry->pmmOffloadInfo.bcnmiss) + return true; + } + else if(pMac->pmm.inMissedBeaconScenario) + { + return true; + } + return false; +} + +/** ----------------------------------------------------------------- + \brief limIsPktCandidateForDrop() - decides whether to drop the frame or not + + This function is called before enqueuing the frame to PE queue for further processing. + This prevents unnecessary frames getting into PE Queue and drops them right away. + Frames will be droped in the following scenarios: + + - In Scan State, drop the frames which are not marked as scan frames + - In non-Scan state, drop the frames which are marked as scan frames. + - Drop INFRA Beacons and Probe Responses in IBSS Mode + - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ + +tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType) +{ + tANI_U32 framelen; + tANI_U8 *pBody; + tSirMacCapabilityInfo capabilityInfo; + tpSirMacMgmtHdr pHdr=NULL; + tpPESession psessionEntry=NULL; + tANI_U8 sessionId; + + /* + * + * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames. + * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames. + * Allow other mgmt frames, they must be from our own AP, as we don't allow + * other than beacons or probe responses in scan state. + */ + if( (subType == SIR_MAC_MGMT_BEACON) || + (subType == SIR_MAC_MGMT_PROBE_RSP)) + { + if(limIsBeaconMissScenario(pMac, pRxPacketInfo)) + { + MTRACE(macTrace(pMac, TRACE_CODE_INFO_LOG, 0, eLOG_NODROP_MISSED_BEACON_SCENARIO)); + return eMGMT_DROP_NO_DROP; + } + if (limIsSystemInScanState(pMac)) + { + return eMGMT_DROP_NO_DROP; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + else if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) + { + return eMGMT_DROP_NO_DROP; + } +#endif + else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo)) + { + return eMGMT_DROP_SCAN_MODE_FRAME; + } + } + + framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + //Drop INFRA Beacons and Probe Responses in IBSS Mode + if( (subType == SIR_MAC_MGMT_BEACON) || + (subType == SIR_MAC_MGMT_PROBE_RSP)) + { + //drop the frame if length is less than 12 + if(framelen < LIM_MIN_BCN_PR_LENGTH) + return eMGMT_DROP_INVALID_SIZE; + + *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET); + + /* Note sure if this is sufficient, basically this condition allows all probe responses and + * beacons from an infrastructure network + */ + if(!capabilityInfo.ibss) + return eMGMT_DROP_NO_DROP; + + //This can be enhanced to even check the SSID before deciding to enque the frame. + if(capabilityInfo.ess) + return eMGMT_DROP_INFRA_BCN_IN_IBSS; + } + else if( (subType == SIR_MAC_MGMT_PROBE_REQ) && + (!WDA_GET_RX_BEACON_SENT(pRxPacketInfo))) + { + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + psessionEntry = peFindSessionByBssid(pMac, pHdr->bssId, &sessionId); + if ((psessionEntry && + psessionEntry->limSystemRole != eLIM_STA_IN_IBSS_ROLE) || + (!psessionEntry)) + return eMGMT_DROP_NO_DROP; + + //Drop the Probe Request in IBSS mode, if STA did not send out the last beacon + //In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq + return eMGMT_DROP_NOT_LAST_IBSS_BCN; + } + + return eMGMT_DROP_NO_DROP; +} + +eHalStatus pe_AcquireGlobalLock( tAniSirLim *psPe) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psPe) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psPe->lkPeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} +eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if(psPe) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psPe->lkPeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.c new file mode 100644 index 0000000000000..66881d80a2763 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -0,0 +1,4923 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limAssocUtils.cc contains the utility functions + * LIM uses while processing (Re) Association messages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniApi.h" +#include "sirCommon.h" + +#include "wniCfgSta.h" +#include "pmmApi.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limAdmitControl.h" +#include "limSendMessages.h" +#include "limIbssPeerMgmt.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" + +#include "vos_types.h" +#include "wlan_qct_wda.h" + +/* + * fill up the rate info properly based on what is actually supported by the peer + * TBD TBD TBD + */ +void +limFillSupportedRatesInfo( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpSirSupportedRates pRates, + tpPESession psessionEntry) +{ + //pSta will be NULL for self entry, so get the opRateMode based on the self mode. + //For the peer entry get it from the peer Capabilities present in hash table + if(pSta == NULL) + pRates->opRateMode = limGetStaRateMode((tANI_U8)psessionEntry->dot11mode); + else + pRates->opRateMode = limGetStaPeerType(pMac, pSta, psessionEntry); + +} + + +/** + * limCmpSSid() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether received SSid is same as SSID in use. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *prxSSid - pointer to SSID structure + * + * @return status - true for SSID match else false. + */ + +tANI_U8 +limCmpSSid(tpAniSirGlobal pMac, tSirMacSSid *prxSSid,tpPESession psessionEntry) +{ + + if (vos_mem_compare((tANI_U8* ) prxSSid, (tANI_U8 *) &psessionEntry->ssId, + (tANI_U8) (psessionEntry->ssId.length + 1))) + return true; + else + return false; + +} /****** end limCmpSSid() ******/ + + + +/** + * limCompareCapabilities() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received capabilities + * match with local capabilities or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pAssocReq - Pointer to received Assoc Req frame + * @param pLocalCapabs - Pointer to local capabilities + * + * @return status - true for Capabilitity match else false. + */ + +tANI_U8 +limCompareCapabilities(tpAniSirGlobal pMac, + tSirAssocReq *pAssocReq, + tSirMacCapabilityInfo *pLocalCapabs,tpPESession psessionEntry) +{ + tANI_U32 val; + + + if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (pAssocReq->capabilityInfo.ibss) ) + { + // Requesting STA asserting IBSS capability. + limLog(pMac, LOG1,FL("Requesting STA asserting IBSS capability")); + return false; + } + + // Compare CF capabilities + if (pAssocReq->capabilityInfo.cfPollable || + pAssocReq->capabilityInfo.cfPollReq) + { + // AP does not support PCF functionality + limLog(pMac, LOG1,FL(" AP does not support PCF functionality")); + return false; + } + + // Compare short preamble capability + if (pAssocReq->capabilityInfo.shortPreamble && + (pAssocReq->capabilityInfo.shortPreamble != + pLocalCapabs->shortPreamble)) + { + // Allowing a STA requesting short preamble while + // AP does not support it + } + + + limLog(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d", + pAssocReq->capabilityInfo.qos, + pLocalCapabs->qos); + + // Compare QoS capability + if (pAssocReq->capabilityInfo.qos && + (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos)) + { + /*Temporary hack for UPF to skip 11e capability check in order to interop with + CSR - proper fix needs to be put in place*/ + if ( 0 != vos_get_skip_11e_check()) + { + limLog(pMac, LOG1, + FL("Received unmatched QOS but cfg to suppress - continuing")); + } + else + { + // AP does not support QoS capability + limLog(pMac, LOG1, FL("AP does not support QoS capability")); + return false; + } + } + + + /* + * If AP supports shortSlot and if apple user has + * enforced association only from shortSlot station, + * then AP must reject any station that does not support + * shortSlot + */ + if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && (pLocalCapabs->shortSlotTime == 1) ) + + { + if (wlan_cfgGetInt(pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY ")); + return false; + } + if(val) + { + if (pAssocReq->capabilityInfo.shortSlotTime != pLocalCapabs->shortSlotTime) + { + limLog(pMac, LOGE, + FL("AP rejects association as station doesnt support shortslot time")); + return false; + } + return false; + } + } + + return true; +} /****** end limCompareCapabilities() ******/ + + +/** + * limCheckRxBasicRates() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received rates in + * Assoc/Reassoc request frames include all BSS basic rates + * or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param rxRateSet - pointer to SSID structure + * + * @return status - true if ALL BSS basic rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckRxBasicRates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,tpPESession psessionEntry) +{ + tSirMacRateSet *pRateSet, basicRate; + tANI_U8 i, j, k, match; + + pRateSet = vos_mem_malloc(sizeof(tSirMacRateSet)); + if (NULL == pRateSet) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for RATESET")); + + return false; + } + + /* Copy operational rate set from session Entry */ + vos_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + + pRateSet->numRates = psessionEntry->rateSet.numRates; + + // Extract BSS basic rateset from operational rateset + for (i = 0, j = 0; ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)) ; i++) + { + if ((pRateSet->rate[i] & 0x80) == 0x80) + { + // msb is set, so this is a basic rate + basicRate.rate[j++] = pRateSet->rate[i]; + } + } + + /* + * For each BSS basic rate, find if it is present in the + * received rateset. + */ + for (k = 0; k < j; k++) + { + match = 0; + for (i = 0; ((i < rxRateSet.numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++) + { + if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k]) + match = 1; + } + + if (!match) + { + // Free up memory allocated for rateset + vos_mem_free((tANI_U8 *)pRateSet); + + return false; + } + } + + // Free up memory allocated for rateset + vos_mem_free((tANI_U8 *)pRateSet); + + return true; +} /****** end limCheckRxBasicRates() ******/ + + + +/** + * limCheckMCSSet() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received MCS rates in + * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param supportedMCSSet - pointer to Supported MCS Rate Set + * + * @return status - true if ALL MCS Basic Rate Set rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet) +{ + tANI_U8 basicMCSSet[SIZE_OF_BASIC_MCS_SET] = {0}; + tANI_U32 cfgLen = 0; + tANI_U8 i; + tANI_U8 validBytes; + tANI_U8 lastByteMCSMask = 0x1f; + + + cfgLen = WNI_CFG_BASIC_MCS_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_BASIC_MCS_SET, + (tANI_U8 *) basicMCSSet, + (tANI_U32 *) &cfgLen) != eSIR_SUCCESS) + { + /// Could not get Basic MCS rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve Basic MCS rateset")); + return false; + } + + validBytes = VALID_MCS_SIZE/8; + + //check if all the Basic MCS Bits are set in supported MCS bitmap + for (i=0; igStartBssRSNIe; + + // Check groupwise cipher suite + for (i = 0; i < sizeof(rxRSNIe.gp_cipher_suite); i++) + { + if (pRSNIe->gp_cipher_suite[i] != rxRSNIe.gp_cipher_suite[i]) + { + limLog(pMac, LOG3, FL("Invalid groupwise cipher suite")); + return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; + } + } + + /* + * For each Pairwise cipher suite check whether we support + * received pairwise + */ + match = 0; + for (i = 0; i < rxRSNIe.pwise_cipher_suite_count; i++) + { + for(j = 0; j < pRSNIe->pwise_cipher_suite_count; j++) + { + if (vos_mem_compare(&rxRSNIe.pwise_cipher_suites[i], + &pRSNIe->pwise_cipher_suites[j], + sizeof(pRSNIe->pwise_cipher_suites[j]))) + { + match = 1; + break; + } + } + + if ((staIsHT) +#ifdef ANI_LITTLE_BYTE_ENDIAN + &&( (rxRSNIe.pwise_cipher_suites[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#else + &&( (rxRSNIe.pwise_cipher_suites[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#endif + { + onlyNonHtCipher=0; + } + + } + + if ((!match) || ((staIsHT) && onlyNonHtCipher)) + { + limLog(pMac, LOG1, FL("Invalid pairwise cipher suite")); + return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS; + } + /* Check RSN capabilities + * Bit 0 of First Byte - PreAuthentication Capability + */ + if(((rxRSNIe.RSN_Cap[0] >> 0) & 0x1) == true) //this is supported by AP only + { + limLog(pMac, LOG1, FL("Invalid RSN information element capabilities")); + return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS; + } + + *pmfConnection = eANI_BOOLEAN_FALSE; + +#ifdef WLAN_FEATURE_11W + weArePMFCapable = pSessionEntry->pLimStartBssReq->pmfCapable; + weRequirePMF = pSessionEntry->pLimStartBssReq->pmfRequired; + theyArePMFCapable = (rxRSNIe.RSN_Cap[0] >> 7) & 0x1; + theyRequirePMF = (rxRSNIe.RSN_Cap[0] >> 6) & 0x1; + + if ((theyRequirePMF && theyArePMFCapable && !weArePMFCapable) || + (weRequirePMF && !theyArePMFCapable)) + { + limLog(pMac, LOG1, FL("Association fail, robust management frames " + "policy violation theyRequirePMF =%d theyArePMFCapable %d " + "weArePMFCapable %d weRequirePMF %d theyArePMFCapable %d"), + theyRequirePMF,theyArePMFCapable,weArePMFCapable,weRequirePMF, + theyArePMFCapable); + return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION; + } + + if(theyArePMFCapable && weArePMFCapable) + *pmfConnection = eANI_BOOLEAN_TRUE; + + limLog(pMac, LOG1, FL("weAreCapable %d, weRequire %d, theyAreCapable %d, " + "theyRequire %d, PMFconnection %d"), + weArePMFCapable, weRequirePMF, theyArePMFCapable, theyRequirePMF, *pmfConnection); +#endif + + return eSIR_SUCCESS; +} /****** end limCheckRxRSNIeMatch() ******/ + +/** + * limCheckRxWPAIeMatch() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received RSN in + * Assoc/Reassoc request frames include supported cipher suites or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param rxWPAIe - Received WPA IE in (Re)Assco req + * + * @return status - true if ALL BSS basic rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckRxWPAIeMatch(tpAniSirGlobal pMac, tDot11fIEWPA rxWPAIe,tpPESession pSessionEntry, tANI_U8 staIsHT) +{ + tDot11fIEWPA *pWPAIe; + tANI_U8 i, j, match, onlyNonHtCipher = 1; + + // WPA IE should be received from PE + pWPAIe = &pSessionEntry->gStartBssWPAIe; + + // Check groupwise cipher suite + for (i = 0; i < 4; i++) + { + if (pWPAIe->multicast_cipher[i] != rxWPAIe.multicast_cipher[i]) + { + limLog(pMac, LOG1, FL("Invalid groupwise cipher suite")); + return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; + } + } + + /* + * For each Pairwise cipher suite check whether we support + * received pairwise + */ + match = 0; + for (i = 0; i < rxWPAIe.unicast_cipher_count; i++) + { + for(j = 0; j < pWPAIe->unicast_cipher_count; j++) + { + if (vos_mem_compare(rxWPAIe.unicast_ciphers[i], + pWPAIe->unicast_ciphers[j], + 4)) + { + match = 1; + break; + } + } + + if ((staIsHT) +#ifdef ANI_LITTLE_BYTE_ENDIAN + &&( (rxWPAIe.unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#else + &&( (rxWPAIe.unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#endif + { + onlyNonHtCipher=0; + } + + } + + if ((!match) || ((staIsHT) && onlyNonHtCipher)) + { + limLog(pMac, LOG1, FL("Invalid pairwise cipher suite")); + return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS; + } + + return eSIR_SUCCESS; +} /****** end limCheckRxWPAIeMatch() ******/ + + +/** + * limCleanupRxPath() + * + *FUNCTION: + * This function is called to cleanup STA state at SP & RFP. + * + *LOGIC: + * To circumvent RFP's handling of dummy packet when it does not + * have an incomplete packet for the STA to be deleted, a packet + * with 'more framgents' bit set will be queued to RFP's WQ before + * queuing 'dummy packet'. + * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010 + * (Disassociation frame) and routing flags in BD set to eCPU's + * Low Priority WQ. + * RFP cleans up its local context for the STA id mentioned in the + * BD and then pushes BD to eCPU's low priority WQ. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pStaDs Pointer to the per STA data structure + * initialized by LIM and maintained at DPH + * + * @return None + */ + +tSirRetStatus +limCleanupRxPath(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + + + limLog( pMac, LOG1, FL("**Initiate cleanup")); + + limAbortBackgroundScan( pMac ); + psessionEntry->isCiscoVendorAP = FALSE; + + if (pMac->lim.gLimAddtsSent) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER)); + tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer); + } + + if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) + { + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, + pStaDs->assocId); + + if (!pStaDs->mlmStaContext.updateContext) + { + /** + * There is no context at Polaris to delete. + * Release our assigned AID back to the free pool + */ + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + } + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry); + + return retCode; + } + } + + //delete all tspecs associated with this sta. + limAdmitControlDeleteSta(pMac, pStaDs->assocId); + + + /** + * Make STA hash entry invalid at eCPU so that DPH + * does not process any more data packets and + * releases those BDs + */ + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + /* Deactivating probe after heart beat timer */ + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER); + pMac->lim.gLastBeaconDtimCount = 0; + pMac->lim.gLastBeaconDtimPeriod = 0; + +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + } +#ifdef WLAN_DEBUG + // increment a debug count + pMac->lim.gLimNumRxCleanup++; +#endif + + if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) { + retCode = limDelBss( pMac, pStaDs, psessionEntry->bssIdx, psessionEntry); + } + else + retCode = limDelSta( pMac, pStaDs, true, psessionEntry); + + return retCode; + +} /*** end limCleanupRxPath() ***/ + + +/** + * limSendDelStaCnf() + * + *FUNCTION: + * This function is called to send appropriate CNF message to SME + * + *LOGIC: + * + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param tpAniSirGlobal pMac, + * @param tSirMacAddr staDsAddr, + * @param tANI_U16 staDsAssocId, + * @param tLimMlmStaContext mlmStaContext, + * @param tSirResultCodes statusCode + * + * @return None + */ + +void +limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr, + tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry) +{ + + tLimMlmDisassocCnf mlmDisassocCnf; + tLimMlmDeauthCnf mlmDeauthCnf; + tLimMlmPurgeStaInd mlmPurgeStaInd; + + limLog(pMac, LOG1, FL("Sessionid: %d staDsAssocId: %d Trigger: %X " + "statusCode: %d staDsAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, + staDsAssocId, mlmStaContext.cleanupTrigger, statusCode, + MAC_ADDR_ARRAY(staDsAddr)); + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Set BSSID at CFG to null + tSirMacAddr nullAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + sirCopyMacAddr(nullAddr,psessionEntry->bssId); + + // Free up buffer allocated for JoinReq held by + // MLM state machine + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + psessionEntry->limAID = 0; + + + } + + if ((mlmStaContext.cleanupTrigger == + eLIM_HOST_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_LINK_MONITORING_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_PROMISCUOUS_MODE_DISASSOC)) + { + /** + * Host or LMM driven Disassociation. + * Issue Disassoc Confirm to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %X"), mlmStaContext.cleanupTrigger); + + + vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.resultCode = statusCode; + mlmDisassocCnf.disassocTrigger = + mlmStaContext.cleanupTrigger; + /* Update PE session Id*/ + mlmDisassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); + } + else if ((mlmStaContext.cleanupTrigger == + eLIM_HOST_DEAUTH) || + (mlmStaContext.cleanupTrigger == + eLIM_LINK_MONITORING_DEAUTH)) + { + /** + * Host or LMM driven Deauthentication. + * Issue Deauth Confirm to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %X"), mlmStaContext.cleanupTrigger); + vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.resultCode = statusCode; + mlmDeauthCnf.deauthTrigger = + mlmStaContext.cleanupTrigger; + /* PE session Id */ + mlmDeauthCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + } + else if ((mlmStaContext.cleanupTrigger == + eLIM_PEER_ENTITY_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_PEER_ENTITY_DEAUTH)) + { + /** + * Received Disassociation/Deauthentication from peer. + * Issue Purge Ind to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %X"), mlmStaContext.cleanupTrigger) ; + vos_mem_copy((tANI_U8 *) &mlmPurgeStaInd.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmPurgeStaInd.reasonCode = (tANI_U8) mlmStaContext.disassocReason; + mlmPurgeStaInd.aid = staDsAssocId; + mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger; + mlmPurgeStaInd.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_PURGE_STA_IND, + (tANI_U32 *) &mlmPurgeStaInd); + } + else if(mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE) + { + //PE setup the peer entry in HW upfront, right after join is completed. + //If there is a failure during rest of the assoc sequence, this context needs to be cleaned up. + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + //if it is a reassoc failure to join new AP + if((mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE) || + (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE) || + (mlmStaContext.resultCode == eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE)) + { + if(mlmStaContext.resultCode != eSIR_SME_SUCCESS ) + { + peDeleteSession(pMac, psessionEntry); + psessionEntry = NULL; + } + + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + mlmStaContext.resultCode, mlmStaContext.protStatusCode, psessionEntry, + smesessionId, smetransactionId); + } + else + { + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + + if(mlmStaContext.resultCode != eSIR_SME_SUCCESS) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, mlmStaContext.resultCode, mlmStaContext.protStatusCode, + psessionEntry, smesessionId, smetransactionId); + } + + } + + if((NULL != psessionEntry) + && (eLIM_AP_ROLE != psessionEntry->limSystemRole ) + ) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } +} + +/** + * limRejectAssociation() + * + *FUNCTION: + * This function is called whenever Re/Association Request need + * to be rejected due to failure in assigning an AID or failure + * in adding STA context at Polaris or reject by applications. + * + *LOGIC: + * Resources allocated if any are freedup and (Re) Association + * Response frame is sent to requesting STA. Pre-Auth context + * will be added for this STA if it does not exist already + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param *pBd - A pointer to Buffer descriptor + associated PDUs + * @param subType - Indicates whether it is Association Request (=0) or + * Reassociation Request (=1) frame + * @param addPreAuthContext - Indicates whether pre-auth context + * to be added for this STA + * @param authType - Indicates auth type to be added + * @param staId - Indicates staId of the STA being rejected + * association + * @param deleteSta - Indicates whether to delete STA context + * at Polaris + * @param rCode - Indicates what reasonCode to be sent in + * Re/Assoc response to STA + * + * @return None + */ + +void +limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType, + tANI_U8 addPreAuthContext, tAniAuthType authType, + tANI_U16 staId, tANI_U8 deleteSta, tSirResultCodes rCode, tpPESession psessionEntry ) +{ + tpDphHashNode pStaDs; + + limLog(pMac, LOG1, FL("Sessionid: %d authType: %d subType: %d " + "addPreAuthContext: %d staId: %d deleteSta: %d rCode : %d " + "peerAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, + authType, subType, addPreAuthContext, staId, deleteSta, rCode, + MAC_ADDR_ARRAY(peerAddr)); + + if (addPreAuthContext) + { + // Create entry for this STA in pre-auth list + struct tLimPreAuthNode *pAuthNode; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + + if (pAuthNode) + { + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + peerAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE; + pAuthNode->authType = (tAniAuthType) authType; + limAddPreAuthNode(pMac, pAuthNode); + } + } + + if (deleteSta == true) + { + pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + limLog(pMac, LOGW, + FL("No STA context, yet rejecting Association")); + + return; + } + + /** + * Polaris has state for this STA. + * Trigger cleanup. + */ + pStaDs->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT; + + // Receive path cleanup + limCleanupRxPath(pMac, pStaDs, psessionEntry); + + // Send Re/Association Response with + // status code to requesting STA. + limSendAssocRspMgmtFrame(pMac, + rCode, + 0, + peerAddr, + subType, 0,psessionEntry); + + if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL) + { + // Assoction confirmation is complete, free the copy of association request frame + if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; + } + vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + } + else + { + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS, + 1, + peerAddr, + subType, 0,psessionEntry); + // Log error + limLog(pMac, LOGW, + FL("received Re/Assoc req when max associated STAs reached from ")); + limPrintMacAddr(pMac, peerAddr, LOGW); + limSendSmeMaxAssocExceededNtf(pMac, peerAddr, psessionEntry->smeSessionId); + } +} /*** end limRejectAssociation() ***/ + + +/** ------------------------------------------------------------- +\fn limDecideApProtectionOnHt20Delete +\brief protection related function while HT20 station is getting deleted. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limDecideApProtectionOnHt20Delete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U32 i = 0; + PELOG1( limLog(pMac, LOG1, FL("(%d) A HT 20 STA is disassociated. Addr is "), + psessionEntry->gLimHt20Params.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimHt20Params.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare(psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimHt20Params.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimHt20Params.numSta == 0) + { + // disable protection + limLog(pMac, LOG1, FL("No 11B STA exists, PESessionID %d"), + psessionEntry->peSessionId); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + } +} +/** ------------------------------------------------------------- +\fn limDecideApProtectionOnDelete +\brief Decides about protection related settings when a station is getting deleted. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limDecideApProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U32 phyMode; + tHalBitVal erpEnabled = eHAL_CLEAR; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 i; + + if(NULL == pStaDs) + return; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_5_GHZ == rfBand) + { + //we are HT. if we are 11A, then protection is not required. + if(true == psessionEntry->htCapability) + { + //we are HT and 11A station is leaving. + //protection consideration required. + //HT station leaving ==> this case is commonly handled between both the bands below. + if((psessionEntry->beaconParams.llaCoexist) && + (false == pStaDs->mlmStaContext.htCapability)) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A 11A STA is disassociated. Addr is "), + psessionEntry->gLim11aParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11aParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11aParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if(psessionEntry->gLim11aParams.numSta == 0) + { + // disable protection + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + erpEnabled = pStaDs->erpEnabled; + //we are HT or 11G and 11B station is getting deleted. + if (((phyMode == WNI_CFG_PHY_MODE_11G) || + psessionEntry->htCapability) && + (erpEnabled == eHAL_CLEAR)) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A legacy STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11bParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11bParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11bParams.numSta == 0) + { + // disable protection + limEnable11gProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + //(non-11B station is leaving) or (we are not 11G or HT AP) + else if(psessionEntry->htCapability) + { //we are HT AP and non-11B station is leaving. + + //11g station is leaving + if(!pStaDs->mlmStaContext.htCapability) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A 11g STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11gParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11gParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11gParams.numSta == 0) + { + // disable protection + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + } + + //LSIG TXOP not supporting staiton leaving. applies to 2.4 as well as 5 GHZ. + if((true == psessionEntry->htCapability) && + (true == pStaDs->mlmStaContext.htCapability)) + { + //HT non-GF leaving + if(!pStaDs->htGreenfield) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-GF STA is disassociated. Addr is "), + psessionEntry->gLimNonGfParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimNonGfParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNonGfParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimNonGfParams.numSta == 0) + { + // disable protection + limEnableHTNonGfProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + //HT 20Mhz station leaving. + if(psessionEntry->beaconParams.ht20Coexist && + (eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet)) + { + limDecideApProtectionOnHt20Delete(pMac, pStaDs, pBeaconParams,psessionEntry); + } + + if(false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport && + (false == pStaDs->htLsigTXOPProtection)) + { + PELOG1( limLog(pMac, LOG1, FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is "), + psessionEntry->gLimLsigTxopParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimLsigTxopParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimLsigTxopParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimLsigTxopParams.numSta == 0) + { + // disable protection + limEnableHTLsigTxopProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + } + } +} + + + +/** ------------------------------------------------------------- +\fn limDecideShortPreamble +\brief Decides about any short preamble reated change because of new station joining. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void limDecideShortPreamble(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry ) +{ + tANI_U32 i; + + if (pStaDs->shortPreambleEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short preamble STA is disassociated. Addr is "), + psessionEntry->gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta > 0) + { + for (i=0; igLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNoShortParams.numNonShortPreambleSta--; + psessionEntry->gLimNoShortParams.staNoShortCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta == 0) + { + // enable short preamble + //reset the cache + vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortParams, + sizeof(tLimNoShortParams), 0); + if (limEnableShortPreamble(pMac, true, pBeaconParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Cannot enable short preamble"));) + } + } +} + +/** ------------------------------------------------------------- +\fn limDecideShortSlot +\brief Decides about any short slot time related change because of station leaving the BSS. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\return None + -------------------------------------------------------------*/ + +void +limDecideShortSlot(tpAniSirGlobal pMac, tpDphHashNode pStaDs, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 i, val; + if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short slottime STA is disassociated. Addr is "), + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta> 0) + { + for (i=0; igLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare(psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta--; + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = false; + break; + } + } + } + } + else + { + if (pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta> 0) + { + for (i=0; ilim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare(pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta--; + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = false; + break; + } + } + } + } + } + + wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val); + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta == 0)) + { + // enable short slot time + //reset the cache + vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortSlotParams, + sizeof(tLimNoShortSlotParams), 0); + // in case of AP set SHORT_SLOT_TIME to enable + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pBeaconParams->fShortSlotTime = true; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + psessionEntry->shortSlotTimeSupported = true; + } + } + else + { + if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta == 0) + { + // enable short slot time + //reset the cache + vos_mem_set((tANI_U8 *)&pMac->lim.gLimNoShortSlotParams, + sizeof(tLimNoShortSlotParams), 0); + // in case of AP set SHORT_SLOT_TIME to enable + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pBeaconParams->fShortSlotTime = true; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + psessionEntry->shortSlotTimeSupported = true; + } + } + } + } +} + +void +limPostReassocFailure(tpAniSirGlobal pMac, + tSirResultCodes resultCode, + tANI_U16 protStatusCode,tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + + mlmReassocCnf.resultCode = resultCode; + mlmReassocCnf.protStatusCode = protStatusCode; + /* Update PE session Id */ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, + LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlmReassocCnf); +} /*** end limPostReassocFailure() ***/ + +/** + * limRestorePreReassocState() + * + *FUNCTION: + * This function is called on STA role whenever Reasociation + * Response with a reject code is received from AP. + * + *LOGIC: + * Reassociation failure timer is stopped, Old (or current) AP's + * context is restored both at Polaris & software + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param resultCode - Result code that specifies why Reassociation + * attemp failed + * + * @return None + */ + +void +limRestorePreReassocState(tpAniSirGlobal pMac, + tSirResultCodes resultCode, + tANI_U16 protStatusCode,tpPESession psessionEntry) +{ + tANI_U8 chanNum, secChanOffset; + tLimMlmReassocCnf mlmReassocCnf; + + limLog(pMac, LOG1, FL("sessionid: %d protStatusCode: %d resultCode: %d"), + psessionEntry->smeSessionId, protStatusCode, resultCode); + + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + + /* To support BT-AMP */ + chanNum = psessionEntry->currentOperChannel; + secChanOffset = psessionEntry->htSecondaryChannelOffset; + + limSetChannel(pMac, chanNum, secChanOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); + + /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */ + + mlmReassocCnf.resultCode = resultCode; + mlmReassocCnf.protStatusCode = protStatusCode; + /* Update PE session Id */ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, + LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlmReassocCnf); +} /*** end limRestorePreReassocState() ***/ + + + +/** + * limIsReassocInProgress() + * + *FUNCTION: + * This function is called to see if STA is in wt-reassoc-rsp state. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return eANI_BOOLEAN_TRUE When STA is waiting for Reassoc response from AP \n + * else eANI_BOOLEAN_FALSE + */ + +eAniBoolean +limIsReassocInProgress(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + if (psessionEntry == NULL) + { + return eANI_BOOLEAN_FALSE; + } + if(((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) || + (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_LINK_FAIL_STATE))) + return eANI_BOOLEAN_TRUE; + + return eANI_BOOLEAN_FALSE; +} /*** end limIsReassocInProgress() ***/ + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tDot11fIEVHTCaps *pPeerVHTCaps, + tpPESession psessionEntry) +{ + tANI_U32 val; + tANI_U32 selfStaDot11Mode=0; + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); + + if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) + { + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_MCS_MAP,&val) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX MCS MAP"));) + goto error; + } + pRates->vhtRxMCSMap = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_MCS_MAP,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT TX MCS MAP"));) + goto error; + } + pRates->vhtTxMCSMap = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) + goto error; + } + pRates->vhtRxHighestDataRate = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) + goto error; + } + pRates->vhtTxHighestDataRate = (tANI_U16)val; + + if( pPeerVHTCaps != NULL) + { + tANI_U16 mcsMapMask = MCSMAPMASK1x1; + tANI_U16 mcsMapMask2x2 = 0; + pRates->vhtTxHighestDataRate = SIR_MIN(pRates->vhtTxHighestDataRate, pPeerVHTCaps->txSupDataRate); + pRates->vhtRxHighestDataRate = SIR_MIN(pRates->vhtRxHighestDataRate, pPeerVHTCaps->rxHighSupDataRate); + + if (pMac->roam.configParam.enable2x2) + { + if (psessionEntry) + { + if ((pMac->lteCoexAntShare) && + (IS_24G_CH(psessionEntry->currentOperChannel))) + { + if(IS_2X2_CHAIN(psessionEntry->chainMask)) + mcsMapMask2x2 = MCSMAPMASK2x2; + else + PELOGE(limLog(pMac, LOGE, FL("2x2 not enabled %d"), + psessionEntry->chainMask);) + } + else + { + mcsMapMask2x2 = MCSMAPMASK2x2; + } + } + else + { + mcsMapMask2x2 = MCSMAPMASK2x2; + } + } + + if ((pPeerVHTCaps->txMCSMap & mcsMapMask) < (pRates->vhtRxMCSMap & mcsMapMask)) { + pRates->vhtRxMCSMap &= ~(mcsMapMask); + pRates->vhtRxMCSMap |= (pPeerVHTCaps->txMCSMap & mcsMapMask); + } + if ((pPeerVHTCaps->rxMCSMap & mcsMapMask) < (pRates->vhtTxMCSMap & mcsMapMask)) { + pRates->vhtTxMCSMap &= ~(mcsMapMask); + pRates->vhtTxMCSMap |= (pPeerVHTCaps->rxMCSMap & mcsMapMask); + } + + if (mcsMapMask2x2) { + + tANI_U16 peerMcsMap, selfMcsMap; + + peerMcsMap = pPeerVHTCaps->txMCSMap & mcsMapMask2x2; + selfMcsMap = pRates->vhtRxMCSMap & mcsMapMask2x2; + + if ((selfMcsMap != mcsMapMask2x2) && + ((peerMcsMap == mcsMapMask2x2) || + (peerMcsMap < selfMcsMap))) { + pRates->vhtRxMCSMap &= ~mcsMapMask2x2; + pRates->vhtRxMCSMap |= peerMcsMap; + } + + peerMcsMap = (pPeerVHTCaps->rxMCSMap & mcsMapMask2x2); + selfMcsMap = (pRates->vhtTxMCSMap & mcsMapMask2x2); + + if ((selfMcsMap != mcsMapMask2x2) && + ((peerMcsMap == mcsMapMask2x2) || + (peerMcsMap < selfMcsMap))) { + pRates->vhtTxMCSMap &= ~mcsMapMask2x2; + pRates->vhtTxMCSMap |= peerMcsMap; + } + } + + limLog( pMac, LOG1, FL("enable2x2 - %d vhtRxMCSMap - %x vhtTxMCSMap - %x\n"), pMac->roam.configParam.enable2x2, pRates->vhtRxMCSMap, pRates->vhtTxMCSMap); + + } + } + return eSIR_SUCCESS; +error: + + return eSIR_FAILURE; + +} +#endif + +/** + * limPopulateOwnRateSet + * + * FUNCTION: + * This function is called by limProcessAssocRsp() or + * limAddStaInIBSS() + * - It creates a combined rate set of 12 rates max which + * comprises the basic and extended rates read from CFG + * - It sorts the combined rate Set and copy it in the + * rate array of the pSTA descriptor + * - It sets the erpEnabled bit of the STA descriptor + * + * NOTE: + * ERP bit is set iff the dph PHY mode is 11G and there is at least + * an A rate in the supported or extended rate sets + * + * @param pMac - Pointer to Global MAC structure + * @param basicOnly - When passed value is true, only basic + * rates are copied to DPH node else + * all supported rates are copied + * @return eSIR_SUCCESS or eSIR_FAILURE + * + */ +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) +#else +tSirRetStatus +limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry) +#endif + +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + tANI_U32 phyMode = 0; + tANI_U32 selfStaDot11Mode=0; + + isArate = 0; + + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + /* Include 11b rates only when the device configured in + auto, 11a/b/g or 11b_only */ + if ( (selfStaDot11Mode == WNI_CFG_DOT11_MODE_ALL) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11A) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11AC) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11N) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11G) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11B) ) + { + val = WNI_CFG_SUPPORTED_RATES_11B_LEN; + wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11B, + (tANI_U8 *)&tempRateSet.rate, &val ); + tempRateSet.numRates = (tANI_U8) val; + } + else + tempRateSet.numRates = 0; + + /* Include 11a rates when the device configured in non-11b mode */ + if (!IS_DOT11_MODE_11B(selfStaDot11Mode)) + { + val = WNI_CFG_SUPPORTED_RATES_11A_LEN; + wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11A, + (tANI_U8 *)&tempRateSet2.rate, &val ); + tempRateSet2.numRates = (tANI_U8) val; + } + else + tempRateSet2.numRates = 0; + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + //we are in big trouble + limLog(pMac, LOGP, FL("more than 12 rates in CFG")); + //panic + goto error; + } + + //copy all rates in tempRateSet, there are 12 rates max + for (i = 0;i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in pSupportedRates + */ + { + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + + vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + isArate = 0; + for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + } + + if (sirIsArate(tempRateSet.rate[min] & 0x7f)) + isArate = 1; + + /* + * HAL needs to know whether the rate is basic rate or not, as it needs to + * update the response rate table accordingly. e.g. if one of the 11a rates is + * basic rate, then that rate can be used for sending control frames. + * HAL updates the response rate table whenever basic rate set is changed. + */ + if (basicOnly) + { + if (tempRateSet.rate[min] & 0x80) + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + } + else + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + tempRateSet.rate[min] = 0xff; + } + + } + + if (IS_DOT11_MODE_HT(selfStaDot11Mode)) + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + pRates->supportedMCSSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));) + goto error; + } + + + //if supported MCS Set of the peer is passed in, then do the intersection + //else use the MCS set from local CFG. + + if(pSupportedMCSSet != NULL) + { + for(i=0; isupportedMCSSet[i] &= pSupportedMCSSet[i]; + + } + + PELOG2(limLog(pMac, LOG2, FL("MCS Rate Set Bitmap: "));) + for(i=0; isupportedMCSSet[i]);) + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, pRates , pVHTCaps,psessionEntry); +#endif + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} /*** limPopulateOwnRateSet() ***/ + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulatePeerRateSet(tpAniSirGlobal pMac, + + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) +#else +tSirRetStatus +limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry) +#endif +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + isArate = 0; + + /* copy operational rate set from psessionEntry */ + if ( psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX ) + { + vos_mem_copy((tANI_U8 *)tempRateSet.rate, + (tANI_U8*)(psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + tempRateSet.numRates = psessionEntry->rateSet.numRates; + } + else + { + limLog(pMac, LOGE, FL("more than SIR_MAC_RATESET_EID_MAX rates\n")); + goto error; + } + if (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) + { + + if (psessionEntry->extRateSet.numRates <= SIR_MAC_RATESET_EID_MAX) + { + vos_mem_copy((tANI_U8 *)tempRateSet2.rate, + (tANI_U8*)(psessionEntry->extRateSet.rate), + psessionEntry->extRateSet.numRates); + tempRateSet2.numRates = psessionEntry->extRateSet.numRates; + } + else { + limLog(pMac, LOGE, FL("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n")); + goto error; + } + } + else + tempRateSet2.numRates = 0; + if ((tempRateSet.numRates + tempRateSet2.numRates) > SIR_MAC_RATESET_EID_MAX) + { + //we are in big trouble + limLog(pMac, LOGP, FL("more than 12 rates in CFG")); + goto error; + } + + + //copy all rates in tempRateSet, there are 12 rates max + for (i = 0;i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + tempRateSet.numRates += tempRateSet2.numRates; + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in pSupportedRates + */ + { + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + isArate = 0; + for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + } + if (sirIsArate(tempRateSet.rate[min] & 0x7f)) + isArate = 1; + /* + * HAL needs to know whether the rate is basic rate or not, as it needs to + * update the response rate table accordingly. e.g. if one of the 11a rates is + * basic rate, then that rate can be used for sending control frames. + * HAL updates the response rate table whenever basic rate set is changed. + */ + if (basicOnly) + { + if (tempRateSet.rate[min] & 0x80) + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + } + else + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + tempRateSet.rate[min] = 0xff; + } + } + + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + pRates->supportedMCSSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));) + goto error; + } + //if supported MCS Set of the peer is passed in, then do the intersection + //else use the MCS set from local CFG. + if(pSupportedMCSSet != NULL) + { + for(i=0; isupportedMCSSet[i] &= pSupportedMCSSet[i]; + } + PELOG2(limLog(pMac, LOG2, FL("MCS Rate Set Bitmap: "));) + for(i=0; isupportedMCSSet[i]);) + } +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, pRates , pVHTCaps,psessionEntry); +#endif + return eSIR_SUCCESS; + error: + return eSIR_FAILURE; +} /*** limPopulatePeerRateSet() ***/ + +/** + * limPopulateMatchingRateSet + * FUNCTION: + * This is called at the time of Association Request + * processing on AP and while adding peer's context + * in IBSS role to process the CFG rate sets and + * the rate sets received in the Assoc request on AP + * or Beacon/Probe Response from peer in IBSS. + * + * LOGIC: + * 1. It makes the intersection between our own rate Sat + * and extemcded rate set and the ones received in the + * association request. + * 2. It creates a combined rate set of 12 rates max which + * comprised the basic and extended rates + * 3. It sorts the combined rate Set and copy it in the + * rate array of the pSTA descriptor + * + * ASSUMPTION: + * The parser has already ensured unicity of the rates in the + * association request structure + * + * @param: pMac - Pointer to Global MAC structure + * pStaDs - Pointer to DPH node + * pOperRateSet - Pointer to peer's supported rateset + * pExtRateSet - Pointer to peer's extended rateset + * + * @return: eSIR_SUCCESS or eSIR_FAILURE + */ +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) + +#else +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry) +#endif +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + tANI_U32 phyMode; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + + isArate=0; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + /* copy operational rate set from psessionEntry */ + vos_mem_copy((tempRateSet.rate), (psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + tempRateSet.numRates = (tANI_U8) psessionEntry->rateSet.numRates; + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + vos_mem_copy((tempRateSet2.rate), (psessionEntry->extRateSet.rate), + psessionEntry->extRateSet.numRates); + tempRateSet2.numRates = (tANI_U8) psessionEntry->extRateSet.numRates; + } + else + tempRateSet2.numRates = 0; + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG"));) + goto error; + } + + /** + * Handling of the rate set IEs is the following: + * - keep only rates that we support and that the station supports + * - sort and the rates into the pSta->rate array + */ + + // Copy all rates in tempRateSet, there are 12 rates max + for(i = 0; i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = + tempRateSet2.rate[i]; + + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in tempRateSet2 + */ + tempRateSet2.numRates = 0; + + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + + for(j = 0;j < tempRateSet.numRates; j++) + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + + tempRateSet2.rate[tempRateSet2.numRates++] = + tempRateSet.rate[min]; + tempRateSet.rate[min] = 0xff; + } + + + /** + * Copy received rates in tempRateSet, the parser has ensured + * unicity of the rates so there cannot be more than 12 + */ + for(i = 0; (i < pOperRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX) ; i++) + { + tempRateSet.rate[i] = pOperRateSet->rate[i]; + } + + tempRateSet.numRates = pOperRateSet->numRates; + + if (pExtRateSet->numRates) + { + if((tempRateSet.numRates + pExtRateSet->numRates) > 12 ) + { + limLog( pMac, LOG2, + "Sum of SUPPORTED and EXTENDED Rate Set (%1d) exceeds 12!", + tempRateSet.numRates + pExtRateSet->numRates ); + + if( tempRateSet.numRates < 12 ) + { + int found = 0; + int tail = tempRateSet.numRates; + + for( i = 0; (i < pExtRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX); i++ ) + { + found = 0; + for( j = 0; j < (tANI_U32) tail; j++ ) + { + if((tempRateSet.rate[j] & 0x7F) == + (pExtRateSet->rate[i] & 0x7F)) + { + found = 1; + break; + } + } + + if( !found ) + { + tempRateSet.rate[tempRateSet.numRates++] = + pExtRateSet->rate[i]; + + if( tempRateSet.numRates >= 12 ) + break; + } + } + } + else + limLog( pMac, LOG2, + "Relying only on the SUPPORTED Rate Set IE..." ); + } + else + { + for(j = 0; ((j < pExtRateSet->numRates) && (j < SIR_MAC_RATESET_EID_MAX) && ((i+j) < SIR_MAC_RATESET_EID_MAX)); j++) + tempRateSet.rate[i+j] = pExtRateSet->rate[j]; + + tempRateSet.numRates += pExtRateSet->numRates; + } + } + + { + tpSirSupportedRates rates = &pStaDs->supportedRates; + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set((tANI_U8 *) rates, sizeof(tSirSupportedRates), 0); + for(i = 0;(i < tempRateSet2.numRates && i < SIR_MAC_RATESET_EID_MAX ); i++) + { + for(j = 0;(j < tempRateSet.numRates && j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tempRateSet2.rate[i] & 0x7F) == + (tempRateSet.rate[j] & 0x7F)) + { + if (sirIsArate(tempRateSet2.rate[i] & 0x7f)) + { + isArate=1; + if (aRateIndex < SIR_NUM_11A_RATES) + rates->llaRates[aRateIndex++] = tempRateSet2.rate[i]; + } + else + { + if (bRateIndex < SIR_NUM_11B_RATES) + rates->llbRates[bRateIndex++] = tempRateSet2.rate[i]; + } + break; + } + } + } + + + //Now add the Polaris rates only when Proprietary rates are enabled. + val = 0; + if(wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_RATES_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve prop rate enabled flag from CFG")); + } + else if(val) + { + for(i=0; inumPropRates; i++) + rates->aniLegacyRates[i] = pAniLegRateSet->propRate[i]; + } + + } + + + //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n +#ifdef FEATURE_WLAN_TDLS + if(pStaDs->mlmStaContext.htCapability) +#else + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pStaDs->mlmStaContext.htCapability)) +#endif + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + mcsSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet")); + goto error; + } + + for(i=0; isupportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i]; + + PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from CFG and DPH : "));) + for(i=0; isupportedRates.supportedMCSSet[i]);) + } + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry); +#endif + /** + * Set the erpEnabled bit iff the phy is in G mode and at least + * one A rate is supported + */ + if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate) + pStaDs->erpEnabled = eHAL_SET; + + + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} /*** limPopulateMatchingRateSet() ***/ + + + +/** + * limAddSta() + * + *FUNCTION: + * This function is called to add an STA context at hardware + * whenever a STA is (Re) Associated. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limAddSta( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tANI_U8 updateEntry, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMacAddr staMac, *pStaAddr; + tANI_U8 i, nwType11b = 0; + tpSirAssocReq pAssocReq; + tLimIbssPeerNode *pPeerNode; /* for IBSS mode */ + tDot11fIEVHTCaps vht_caps; /* for IBSS mode */ + tANI_U8 *p2pIe = NULL; + + sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); + + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId, updateEntry, psessionEntry->limSystemRole); + + pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); + if (NULL == pAddStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) ) + pStaAddr = &pStaDs->staAddr; +#ifdef FEATURE_WLAN_TDLS + /* SystemRole shouldn't be matter if staType is TDLS peer */ + else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + pStaAddr = &pStaDs->staAddr ; + } +#endif + else + pStaAddr = &staMac; + + limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": Subtype(Assoc/Reassoc): %d "), + MAC_ADDR_ARRAY(*pStaAddr), pStaDs->mlmStaContext.subType); + + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) *pStaAddr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + vos_mem_copy(&pAddStaParams->capab_info, + &pStaDs->mlmStaContext.capabilityInfo, + sizeof(pAddStaParams->capab_info)); + + limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry); + + //Copy legacy rates + vos_mem_copy ((tANI_U8*)&pAddStaParams->supportedRates, + (tANI_U8*)&pStaDs->supportedRates, sizeof(tSirSupportedRates)); + + pAddStaParams->assocId = pStaDs->assocId; + + pAddStaParams->wmmEnabled = pStaDs->qosMode; + pAddStaParams->listenInterval = pStaDs->mlmStaContext.listenInterval; + pAddStaParams->shortPreambleSupported = pStaDs->shortPreambleEnabled; + if((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) && (pStaDs->mlmStaContext.subType == LIM_REASSOC)) + { + /* TBD - need to remove this REASSOC check after fixinf rmmod issue */ + pAddStaParams->updateSta = pStaDs->mlmStaContext.updateContext; + } + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + + limLog(pMac, LOG2, FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d" + " shortPreambleSupported: %d "), pAddStaParams->assocId, + pAddStaParams->wmmEnabled, pAddStaParams->listenInterval, + pAddStaParams->shortPreambleSupported); + // This will indicate HAL to "allocate" a new STA index +#ifdef FEATURE_WLAN_TDLS + /* As there is corner case in-between add_sta and change_sta,if del_sta for other staIdx happened, + * firmware return wrong staIdx (recently removed staIdx). Until we get a confirmation from the + * firmware team it is now return correct staIdx for same sta_mac_addr for update case, we want + * to get around it by passing valid staIdx given by add_sta time. + */ + if((STA_ENTRY_TDLS_PEER == pStaDs->staType) && + (true == updateEntry)) + pAddStaParams->staIdx = pStaDs->staIndex; + else +#endif + pAddStaParams->staIdx = HAL_STA_INVALID_IDX; + pAddStaParams->staType = pStaDs->staType; + + pAddStaParams->updateSta = updateEntry; + + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + //Update HT Capability + + if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||(limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) || (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + { + pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; +#endif + } +#ifdef FEATURE_WLAN_TDLS + /* SystemRole shouldn't be matter if staType is TDLS peer */ + else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; +#endif + } +#endif + else + { + pAddStaParams->htCapable = psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = psessionEntry->vhtCapability; +#endif + + } +#ifdef WLAN_FEATURE_11AC + limLog(pMac, LOG2, FL("vhtCapable: %d "),pAddStaParams->vhtCapable); +#endif + limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "), + pAddStaParams->staIdx,pAddStaParams->updateSta, + pAddStaParams->htCapable); + + pAddStaParams->greenFieldCapable = pStaDs->htGreenfield; + pAddStaParams->maxAmpduDensity= pStaDs->htAMpduDensity; + pAddStaParams->maxAmpduSize = pStaDs->htMaxRxAMpduFactor; + pAddStaParams->fDsssCckMode40Mhz = pStaDs->htDsssCckRate40MHzSupport; + pAddStaParams->fShortGI20Mhz = pStaDs->htShortGI20Mhz; + pAddStaParams->fShortGI40Mhz = pStaDs->htShortGI40Mhz; + pAddStaParams->lsigTxopProtection = pStaDs->htLsigTXOPProtection; + pAddStaParams->maxAmsduSize = pStaDs->htMaxAmsduLength; + pAddStaParams->txChannelWidthSet = pStaDs->htSupportedChannelWidthSet; + pAddStaParams->mimoPS = pStaDs->htMIMOPSState; + + limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d " + "maxAmpduDensity = %d"), pAddStaParams->greenFieldCapable, + pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); + + limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " + "fShortGI40Mhz: %d"), pAddStaParams->fDsssCckMode40Mhz, + pAddStaParams->fShortGI20Mhz, pAddStaParams->fShortGI40Mhz); + + limLog(pMac, LOG2, FL("lsigTxopProtection: %d maxAmsduSize: %d " + "txChannelWidthSet: %d mimoPS: %d "), pAddStaParams->lsigTxopProtection, + pAddStaParams->maxAmsduSize,pAddStaParams->txChannelWidthSet, + pAddStaParams->mimoPS); + +#ifdef WLAN_FEATURE_11AC + if(pAddStaParams->vhtCapable) + { + pAddStaParams->vhtTxChannelWidthSet = pStaDs->vhtSupportedChannelWidthSet; + pAddStaParams->vhtSupportedRxNss = pStaDs->vhtSupportedRxNss; + pAddStaParams->vhtTxBFCapable = +#ifdef FEATURE_WLAN_TDLS + (( STA_ENTRY_PEER == pStaDs->staType ) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ? + pStaDs->vhtBeamFormerCapable : psessionEntry->txBFIniFeatureEnabled ; +#else + ( STA_ENTRY_PEER == pStaDs->staType ) ? pStaDs->vhtBeamFormerCapable : + psessionEntry->txBFIniFeatureEnabled ; +#endif + limLog(pMac, LOG2, FL("vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddStaParams->vhtTxChannelWidthSet,pAddStaParams->vhtTxBFCapable); + } +#endif + +#ifdef FEATURE_WLAN_TDLS + if((STA_ENTRY_PEER == pStaDs->staType) || + (STA_ENTRY_TDLS_PEER == pStaDs->staType)) +#else + if (STA_ENTRY_PEER == pStaDs->staType) +#endif + { + /* peer STA get the LDPC capability from pStaDs, which populated from + * HT/VHT capability*/ + if(pAddStaParams->vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP) + { + pAddStaParams->htLdpcCapable = 0; + pAddStaParams->vhtLdpcCapable = 0; + } + else + { + pAddStaParams->htLdpcCapable = pStaDs->htLdpcCapable; + pAddStaParams->vhtLdpcCapable = pStaDs->vhtLdpcCapable; + } + } + else if( STA_ENTRY_SELF == pStaDs->staType) + { + /* For Self STA get the LDPC capability from config.ini*/ + pAddStaParams->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pAddStaParams->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + } + + /* Update PE session ID*/ + pAddStaParams->sessionId = psessionEntry->peSessionId; + + /* Update SME session ID */ + pAddStaParams->smesessionId = psessionEntry->smeSessionId; + + pAddStaParams->maxTxPower = psessionEntry->maxTxPower; + + if (psessionEntry->parsedAssocReq != NULL) + { + // Get a copy of the already parsed Assoc Request + pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId]; + if ( pAssocReq && pAssocReq->addIEPresent && pAssocReq->addIE.length ) { + p2pIe = limGetP2pIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + } + pAddStaParams->p2pCapableSta = (p2pIe != NULL); + if ( pAssocReq && pAddStaParams->htCapable ) { + vos_mem_copy(&pAddStaParams->ht_caps, ((tANI_U8 *) &pAssocReq->HTCaps) + 1, + sizeof(pAddStaParams->ht_caps)); + } + if ( pAssocReq && pAddStaParams->vhtCapable) { + pAddStaParams->vht_caps = + ((pAssocReq->VHTCaps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | + (pAssocReq->VHTCaps.supportedChannelWidthSet << + SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | + (pAssocReq->VHTCaps.ldpcCodingCap << + SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | + (pAssocReq->VHTCaps.shortGI80MHz << + SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | + (pAssocReq->VHTCaps.shortGI160and80plus80MHz << + SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | + (pAssocReq->VHTCaps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | + (pAssocReq->VHTCaps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | + (pAssocReq->VHTCaps.suBeamFormerCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | + (pAssocReq->VHTCaps.suBeamformeeCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | + (pAssocReq->VHTCaps.csnofBeamformerAntSup << + SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | + (pAssocReq->VHTCaps.numSoundingDim << + SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | + (pAssocReq->VHTCaps.muBeamformerCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| + (pAssocReq->VHTCaps.muBeamformeeCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | + (pAssocReq->VHTCaps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | + (pAssocReq->VHTCaps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | + (pAssocReq->VHTCaps.maxAMPDULenExp << + SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | + (pAssocReq->VHTCaps.vhtLinkAdaptCap << + SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | + (pAssocReq->VHTCaps.rxAntPattern << + SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | + (pAssocReq->VHTCaps.txAntPattern << + SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | + (pAssocReq->VHTCaps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); + } + } + else if (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) { + + /* in IBSS mode, use peer node as the source of ht_caps and vht_caps */ + pPeerNode = limIbssPeerFind(pMac, *pStaAddr); + if (!pPeerNode) { + limLog( pMac, LOGP, FL("Can't find IBSS peer node for ADD_STA")); + return eSIR_HAL_STA_DOES_NOT_EXIST; + } + + if (pPeerNode->atimIePresent) + { + pAddStaParams->atimIePresent = pPeerNode->atimIePresent; + pAddStaParams->peerAtimWindowLength = + pPeerNode->peerAtimWindowLength; + } + + pAddStaParams->ht_caps = + ( pPeerNode->htSupportedChannelWidthSet << + SIR_MAC_HT_CAP_CHWIDTH40_S ) | + ( pPeerNode->htGreenfield << + SIR_MAC_HT_CAP_GREENFIELD_S ) | + ( pPeerNode->htShortGI20Mhz << + SIR_MAC_HT_CAP_SHORTGI20MHZ_S ) | + ( pPeerNode->htShortGI40Mhz << + SIR_MAC_HT_CAP_SHORTGI40MHZ_S ) | + ( SIR_MAC_TXSTBC << + SIR_MAC_HT_CAP_TXSTBC_S ) | + ( SIR_MAC_RXSTBC << + SIR_MAC_HT_CAP_RXSTBC_S ) | + ( pPeerNode->htMaxAmsduLength << + SIR_MAC_HT_CAP_MAXAMSDUSIZE_S ) | + ( pPeerNode->htDsssCckRate40MHzSupport << + SIR_MAC_HT_CAP_DSSSCCK40_S ); + + vht_caps = pPeerNode->VHTCaps; + pAddStaParams->vht_caps = + ((vht_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | + (vht_caps.supportedChannelWidthSet << + SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | + (vht_caps.ldpcCodingCap << + SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | + (vht_caps.shortGI80MHz << + SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | + (vht_caps.shortGI160and80plus80MHz << + SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | + (vht_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | + (vht_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | + (vht_caps.suBeamFormerCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | + (vht_caps.suBeamformeeCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | + (vht_caps.csnofBeamformerAntSup << + SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | + (vht_caps.numSoundingDim << + SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | + (vht_caps.muBeamformerCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| + (vht_caps.muBeamformeeCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | + (vht_caps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | + (vht_caps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | + (vht_caps.maxAMPDULenExp << + SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | + (vht_caps.vhtLinkAdaptCap << + SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | + (vht_caps.rxAntPattern << + SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | + (vht_caps.txAntPattern << + SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | + (vht_caps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); + } + +#ifdef FEATURE_WLAN_TDLS + if (STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + pAddStaParams->ht_caps = pStaDs->ht_caps; + pAddStaParams->vht_caps = pStaDs->vht_caps; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x", + __func__, pAddStaParams->ht_caps, pAddStaParams->vht_caps); + } +#endif + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddStaParams->staTCParams[i].txUseBA = eBA_DISABLE; + pAddStaParams->staTCParams[i].rxUseBA = eBA_DISABLE; + } + +#ifdef FEATURE_WLAN_TDLS + if(pStaDs->wmeEnabled && \ + ((eLIM_AP_ROLE == psessionEntry->limSystemRole) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ) +#else + if(pStaDs->wmeEnabled && (eLIM_AP_ROLE == psessionEntry->limSystemRole)) +#endif + { + pAddStaParams->uAPSD = 0; + /* update UAPSD and send it to LIM to add STA */ + // bitmap MSB <- LSB MSB 4 bits are for + // trigger enabled AC setting and LSB 4 bits + // are for delivery enabled AC setting + // 7 6 5 4 3 2 1 0 + // BE BK VI VO BE BK VI VO + pAddStaParams->uAPSD |= pStaDs->qos.capability.qosInfo.acvo_uapsd; + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acvi_uapsd << 1); + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbk_uapsd << 2); + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbe_uapsd << 3); + //making delivery enabled and trigger enabled setting the same. + pAddStaParams->uAPSD |= pAddStaParams->uAPSD << 4; + + pAddStaParams->maxSPLen = pStaDs->qos.capability.qosInfo.maxSpLen; + limLog( pMac, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"), + pAddStaParams->uAPSD, pAddStaParams->maxSPLen); + } + +#ifdef WLAN_FEATURE_11W + pAddStaParams->rmfEnabled = pStaDs->rmfEnabled; + limLog( pMac, LOG1, FL( "PMF enabled %d"), pAddStaParams->rmfEnabled); +#endif + + limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d " + "p2pCapableSta: %d"), pAddStaParams->htLdpcCapable, + pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta); + + //we need to defer the message until we get the response back from HAL. + if (pAddStaParams->respReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + for (i = 0; i < SIR_NUM_11A_RATES; i++) + { + if (sirIsArate(pStaDs->supportedRates.llaRates[i] & 0x7F)) + { + nwType11b = 0; + break; + } + else + { + nwType11b = 1; + } + } + if (nwType11b) + { + pAddStaParams->nwType = eSIR_11B_NW_TYPE; + } + else + { + pAddStaParams->nwType = psessionEntry->nwType; + } + + msgQ.type = WDA_ADD_STA_REQ; + + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG1, FL("Sending WDA_ADD_STA_REQ for assocId %d"), + pStaDs->assocId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + if (pAddStaParams->respReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("ADD_STA_REQ for aId %d failed (reason %X)"), + pStaDs->assocId, retCode ); + vos_mem_free(pAddStaParams); + } + + return retCode; +} + + +/** + * limDelSta() + * + *FUNCTION: + * This function is called to delete an STA context at hardware + * whenever a STA is disassociated + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @param fRespReqd - flag to indicate whether the delete is synchronous (true) + * or not (false) + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limDelSta( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_BOOLEAN fRespReqd, + tpPESession psessionEntry) +{ + tpDeleteStaParams pDelStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + pDelStaParams = vos_mem_malloc(sizeof( tDeleteStaParams )); + if (NULL == pDelStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *) pDelStaParams, sizeof(tDeleteStaParams), 0); + + // + // DPH contains the STA index only for "peer" STA entries. + // LIM global contains "self" STA index + // Thus, + // if( STA role ) + // get STA index from LIM global + // else + // get STA index from DPH + // + +#ifdef FEATURE_WLAN_TDLS + if( ((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) && (pStaDs->staType != STA_ENTRY_TDLS_PEER)) ||(eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) +#else + if( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ||(eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) +#endif + pDelStaParams->staIdx= psessionEntry->staId; + + else + pDelStaParams->staIdx= pStaDs->staIndex; + + pDelStaParams->assocId = pStaDs->assocId; + pStaDs->valid = 0; + + if (! fRespReqd) + pDelStaParams->respReqd = 0; + else + { + //when limDelSta is called from processSmeAssocCnf then mlmState is already set properly. + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, eLIM_MLM_WT_DEL_STA_RSP_STATE); + } + if ( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) || + (eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + } + pDelStaParams->respReqd = 1; + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + } + + /* Update PE session ID*/ + pDelStaParams->sessionId = psessionEntry->peSessionId; + pDelStaParams->smesessionId = psessionEntry->smeSessionId; + + pDelStaParams->staType = pStaDs->staType; + vos_mem_copy((tANI_U8 *)pDelStaParams->staMac, + (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); + + pDelStaParams->status = eHAL_STATUS_SUCCESS; + msgQ.type = WDA_DELETE_STA_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pDelStaParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ " + "for STAID: %X and AssocID: %d MAC : "MAC_ADDRESS_STR ), + pDelStaParams->sessionId, + pDelStaParams->staIdx, pDelStaParams->assocId, + MAC_ADDR_ARRAY(pStaDs->staAddr)); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + if(fRespReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"), + retCode ); + vos_mem_free(pDelStaParams); + } + + return retCode; +} + +#if defined WLAN_FEATURE_VOWIFI_11R +/*------------------------------------------------------------------------ + * limAddFTStaSelf() + * + * FUNCTION: + * + * This function is called to add a STA once we have connected with a new + * AP, that we have performed an FT to. + * + * The Add STA Response is created and now after the ADD Bss Is Successful + * we add the self sta. We update with the association id from the reassoc + * response from the AP. + *------------------------------------------------------------------------ + */ +tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pAddStaParams = psessionEntry->ftPEContext.pAddStaReq; + pAddStaParams->assocId = assocId; + pAddStaParams->smesessionId = psessionEntry->smeSessionId; + + msgQ.type = WDA_ADD_STA_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "%s: Sending WDA_ADD_STA_REQ (aid %d)", + __func__, pAddStaParams->assocId); +#endif + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, + eLIM_MLM_WT_ADD_STA_RSP_STATE)); + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) { + limLog(pMac, LOGE, + FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode); + vos_mem_free(pAddStaParams); + } + psessionEntry->ftPEContext.pAddStaReq = NULL; + return retCode; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + * limAddStaSelf() + * + *FUNCTION: + * This function is called to add an STA context at hardware + * whenever a STA is (Re) Associated. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limAddStaSelf(tpAniSirGlobal pMac,tANI_U16 staIdx, tANI_U8 updateSta, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMacAddr staMac; + tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + tANI_U32 ampduLenExponent = 0; + /*This self Sta dot 11 mode comes from the cfg and the expectation here is + * that cfg carries the systemwide capability that device under + * consideration can support. This capability gets plumbed into the cfg + * cache at system initialization time via the .dat and .ini file override + * mechanisms and will not change. If it does change, it is the + * responsibility of SME to evict the selfSta and reissue a new AddStaSelf + * command.*/ + tANI_U32 selfStaDot11Mode=0, selfTxWidth=0; + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); + limLog( pMac, LOG1, FL("cfgDot11Mode %d"),(int)selfStaDot11Mode); + wlan_cfgGetInt(pMac,WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,&selfTxWidth); + limLog( pMac, LOG1, FL("SGI 20 %d"),(int)selfTxWidth); + limLog( pMac, LOG1, FL("Roam Channel Bonding Mode %d"),(int)pMac->roam.configParam.uCfgDot11Mode); + + sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); + limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": "),MAC_ADDR_ARRAY(staMac)); + pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); + if (NULL == pAddStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) staMac, sizeof(tSirMacAddr)); + + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + + pAddStaParams->assocId = psessionEntry->limAID; + pAddStaParams->staType = STA_ENTRY_SELF; + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + + /* Update PE session ID */ + pAddStaParams->sessionId = psessionEntry->peSessionId; + + /* Update SME session ID */ + pAddStaParams->smesessionId = psessionEntry->smeSessionId; + + pAddStaParams->maxTxPower = psessionEntry->maxTxPower; + + // This will indicate HAL to "allocate" a new STA index + pAddStaParams->staIdx = staIdx; + pAddStaParams->updateSta = updateSta; + + pAddStaParams->shortPreambleSupported = psessionEntry->beaconParams.fShortPreamble; + +#ifdef WLAN_FEATURE_11AC + limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry,NULL); +#else + limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry); +#endif + if ( IS_DOT11_MODE_HT(selfStaDot11Mode) ) + { + pAddStaParams->htCapable = TRUE ; +#ifdef DISABLE_GF_FOR_INTEROP + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + if( (psessionEntry->pLimJoinReq != NULL)) + { + limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry")); + pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } + else +#endif + { + pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode5GHz; + pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry); + pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + /* + * We will read the gShortGI20Mhz from ini file, and if it is set + * to 1 then we will tell Peer that we support 40Mhz short GI + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddStaParams->fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STAMAX; + } + else + { + pAddStaParams->fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddStaParams->fShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + /* + * We will read the gShortGI40Mhz from ini file, and if it is set + * to 1 then we will tell Peer that we support 40Mhz short GI + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddStaParams->fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STAMAX; + } + else + { + pAddStaParams->fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddStaParams->fShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d " + "maxAmpduSize = %d"), pAddStaParams->greenFieldCapable, + pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); + + limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " + "fShortGI40Mhz: %d lsigTxopProtection: %d"), + pAddStaParams->fDsssCckMode40Mhz, pAddStaParams->fShortGI20Mhz, + pAddStaParams->fShortGI40Mhz, pAddStaParams->lsigTxopProtection); + + limLog(pMac, LOG2, FL(" maxAmsduSize: %d txChannelWidthSet: %d " + "mimoPS: %d rifsMode %d delBASupport %d"), + pAddStaParams->maxAmsduSize, + pAddStaParams->txChannelWidthSet, pAddStaParams->mimoPS, + pAddStaParams->rifsMode, pAddStaParams->delBASupport ); + } + } +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode); + if (pAddStaParams->vhtCapable){ + pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; + limLog( pMac, LOG1, FL("VHT WIDTH SET %d"),pAddStaParams->vhtTxChannelWidthSet); + } + pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled; + limLog(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d "), + pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable); + + // In 11ac mode, the hardware is capable of supporting 128K AMPDU size + if ( IS_DOT11_MODE_VHT(selfStaDot11Mode) ) + { + if(wlan_cfgGetInt(pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &duLenExponent) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT")); + } + pAddStaParams->maxAmpduSize = (tANI_U8)ampduLenExponent; + } + pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee; + pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid; +#endif + pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs; + pAddStaParams->enableHtSmps = psessionEntry->enableHtSmps; + pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue; + + /* For Self STA get the LDPC capability from session i.e config.ini*/ + pAddStaParams->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pAddStaParams->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + + if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + pAddStaParams->listenInterval = (tANI_U16)listenInterval; + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) + { + pAddStaParams->p2pCapableSta = 1; + } + + pAddStaParams->supportedRates.opRateMode = + limGetStaRateMode((tANI_U8)selfStaDot11Mode); + + limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "), + pAddStaParams->staIdx,pAddStaParams->updateSta, + pAddStaParams->htCapable); + + limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d " + "p2pCapableSta: %d"), + pAddStaParams->htLdpcCapable,pAddStaParams->vhtLdpcCapable, + pAddStaParams->p2pCapableSta); + /* As part of HS2.0 certification need to send reassoc + * to the same AP to which STA connected .in this case + * we are not sending delsta but sending only addsta + * which is causing target asssert. to fix this + * set pAddStaParams->nonRoamReassoc = 1 and using this + * skip sending the addsta to firmware + */ + if (psessionEntry->isNonRoamReassoc) { + pAddStaParams->nonRoamReassoc = 1; + psessionEntry->isNonRoamReassoc = 0; + } + limLog(pMac, LOG2, FL("sessionid: %d Assoc ID: %d listenInterval = %d " + "shortPreambleSupported: %d"), psessionEntry->smeSessionId, + pAddStaParams->assocId, pAddStaParams->listenInterval, + pAddStaParams->shortPreambleSupported); + + msgQ.type = WDA_ADD_STA_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG1, FL(MAC_ADDRESS_STR":Sessionid %d : " + "Sending WDA_ADD_STA_REQ. (aid %d)"), + MAC_ADDR_ARRAY(pAddStaParams->staMac), + pAddStaParams->sessionId, + pAddStaParams->assocId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) { + limLog(pMac, LOGE, + FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode); + vos_mem_free(pAddStaParams); + } + return retCode; +} + + +/** + * limTeardownInfraBSS() + * + *FUNCTION: + * This function is called by various LIM functions to teardown + * an established Infrastructure BSS + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limTeardownInfraBss(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + /** + * Send Broadcast Disassociate frame with + * 'leaving BSS' reason. + */ + limSendDisassocMgmtFrame(pMac, + eSIR_MAC_DISASSOC_LEAVING_BSS_REASON, + bcAddr,psessionEntry, FALSE); +} /*** end limTeardownInfraBss() ***/ + + +/** + * limHandleCnfWaitTimeout() + * + *FUNCTION: + * This function is called by limProcessMessageQueue to handle + * various confirmation failure cases. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to a sta descriptor + * @return None + */ + +void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId) +{ + tpDphHashNode pStaDs; + tLimSystemRole systemRole; + tpPESession psessionEntry = NULL; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + systemRole = limGetSystemRole(psessionEntry); + pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + PELOGW(limLog(pMac, LOGW, FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));) + return; + } + + switch (pStaDs->mlmStaContext.mlmState) { + case eLIM_MLM_WT_ASSOC_CNF_STATE: + PELOGW(limLog(pMac, LOGW, FL("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"), pStaDs->assocId);) + limPrintMacAddr(pMac, pStaDs->staAddr, LOGW); + + if ( (systemRole == eLIM_AP_ROLE)|| (systemRole == eLIM_BT_AMP_AP_ROLE) ) + { + limRejectAssociation( + pMac, + pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, + pStaDs->mlmStaContext.authType, + pStaDs->assocId, + true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + } + break; + + default: + limLog(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"), + pStaDs->mlmStaContext.mlmState); + } +} + + +/** + * limDeleteDphHashEntry() + * + *FUNCTION: + * This function is called whenever we need to delete + * the dph hash entry + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tANI_U16 staId + * @return None + */ + +void +limDeleteDphHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId,tpPESession psessionEntry) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tUpdateBeaconParams beaconParams; + tLimSystemRole systemRole; + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, staId); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));) + return; + } + systemRole = limGetSystemRole(psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + pStaDs = dphLookupHashEntry(pMac, staAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X"), staId);) + // update the station count and perform associated actions + // do this before deleting the dph hash entry + limUtilCountStaDel(pMac, pStaDs, psessionEntry); + + if((eLIM_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole)) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE){ + limDecideApProtectionOnDelete(pMac, pStaDs, &beaconParams,psessionEntry); + } + } + + if(eLIM_STA_IN_IBSS_ROLE == systemRole) + limIbssDecideProtectionOnDelete(pMac, pStaDs, &beaconParams, psessionEntry); + + limDecideShortPreamble(pMac, pStaDs, &beaconParams, psessionEntry); + limDecideShortSlot(pMac, pStaDs, &beaconParams, psessionEntry); + + //Send message to HAL about beacon parameter change. + PELOGW(limLog(pMac, LOGW, FL("param bitmap = %d "), beaconParams.paramChangeBitmap);) + if((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + +#ifdef WLAN_FEATURE_11W + tx_timer_delete(&pStaDs->pmfSaQueryTimer); +#endif + } + if (dphDeleteHashEntry(pMac, staAddr, staId, &psessionEntry->dph.dphHashTable) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("error deleting hash entry")); + } +} + + + +/** + * limCheckAndAnnounceJoinSuccess() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * frame in WT_JOIN_BEACON_STATE to check if the received + * Beacon/Probe Response is from the BSS that we're attempting + * to join. + * + *LOGIC: + * If the Beacon/Probe Response is indeed from the BSS we're + * attempting to join, join success is sent to SME. + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pBPR Pointer to received Beacon/Probe Response + * @param pHdr Pointer to received Beacon/Probe Response + * MAC header + * @return None + */ + +void +limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac, + tSirProbeRespBeacon *pBPR, + tpSirMacMgmtHdr pHdr,tpPESession psessionEntry) +{ + tSirMacSSid currentSSID; + tLimMlmJoinCnf mlmJoinCnf; + tANI_U32 val = 0; + tANI_U32 *noa1DurationFromBcn = NULL; + tANI_U32 *noa2DurationFromBcn = NULL; + tANI_U32 noa; + tANI_U32 TotalNum_NoADesc = 0; + + vos_mem_copy(currentSSID.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + + currentSSID.length = (tANI_U8)psessionEntry->ssId.length ; + + if ( + /* Check for SSID only in probe response. Beacons may not carry + SSID information in hidden SSID case */ + ( (SIR_MAC_MGMT_FRAME == pHdr->fc.type) && + (SIR_MAC_MGMT_PROBE_RSP == pHdr->fc.subType) ) && + currentSSID.length && + (!vos_mem_compare((tANI_U8 *) &pBPR->ssId, + (tANI_U8 *) ¤tSSID, + (tANI_U8) (1 + currentSSID.length)) )) + { + /** + * Received SSID does not match with the one we've. + * Ignore received Beacon frame + */ + PELOG1(limLog(pMac, LOG1, FL("SSID received in Beacon does not match"));) +#ifdef WLAN_DEBUG + pMac->lim.gLimBcnSSIDMismatchCnt++; +#endif + return; + } + + if( (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + limLog(pMac, LOG1, FL("Received Beacon/PR with matching BSSID" + MAC_ADDRESS_STR "PESessionID %d"), + MAC_ADDR_ARRAY(psessionEntry->bssId), + psessionEntry->peSessionId ); + + // Deactivate Join Failure timer + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + // Deactivate Periodic Join timer + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && + pBPR->P2PProbeRes.NoticeOfAbsence.present) + { + + noa1DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + 1); + + if(pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc) + TotalNum_NoADesc = pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc/SIZE_OF_NOA_DESCRIPTOR; + + noa = *noa1DurationFromBcn; + + if(TotalNum_NoADesc > 1) + { + noa2DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + SIZE_OF_NOA_DESCRIPTOR + 1); + noa += *noa2DurationFromBcn; + } + + /*If MAX Noa exceeds 3 secs we will consider only 3 secs to + * avoid arbitary values in noa duration field + */ + noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ? MAX_NOA_PERIOD_IN_MICROSECS : noa; + noa = noa/1000; //Convert to ms + + if( wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,&val) == eSIR_SUCCESS ) + { + psessionEntry->defaultAuthFailureTimeout = val; + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT ,val + noa, NULL, eANI_BOOLEAN_FALSE); + } + } + else + { + psessionEntry->defaultAuthFailureTimeout = 0; + } + + // Update Beacon Interval at CFG database + + if ( pBPR->HTCaps.present ) + limUpdateStaRunTimeHTCapability( pMac, &pBPR->HTCaps ); + if ( pBPR->HTInfo.present ) + limUpdateStaRunTimeHTInfo( pMac, &pBPR->HTInfo, psessionEntry); + psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE)); + + + /** + * Announce join success by sending + * Join confirm to SME. + */ + mlmJoinCnf.resultCode = eSIR_SME_SUCCESS; + mlmJoinCnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS; + /* Update PE sessionId*/ + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); + } // if ((pMac->lim.gLimSystemRole == IBSS.... +} + +/** + * limExtractApCapabilities() + * + *FUNCTION: + * This function is called to extract all of the AP's capabilities + * from the IEs received from it in Beacon/Probe Response frames + * + *LOGIC: + * This routine mimics the limExtractApCapability() API. The difference here + * is that this API returns the entire tSirProbeRespBeacon info as is. It is + * left to the caller of this API to use this info as required + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pIE Pointer to starting IE in Beacon/Probe Response + * @param ieLen Length of all IEs combined + * @param beaconStruct A pointer to tSirProbeRespBeacon that needs to be + * populated + * @return status A status reporting eSIR_SUCCESS or eSIR_FAILURE + */ +tSirRetStatus limExtractApCapabilities( tpAniSirGlobal pMac, + tANI_U8 *pIE, + tANI_U16 ieLen, + tpSirProbeRespBeacon beaconStruct ) +{ + vos_mem_set((tANI_U8 *) beaconStruct, sizeof( tSirProbeRespBeacon ), 0); + + PELOG3(limLog( pMac, LOG3, + FL( "In limExtractApCapabilities: The IE's being received are:" )); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );) + + // Parse the Beacon IE's, Don't try to parse if we dont have anything in IE + if (ieLen > 0) { + if( eSIR_SUCCESS != sirParseBeaconIE( pMac, beaconStruct, pIE, (tANI_U32)ieLen )) + { + limLog( pMac, LOGE, FL("APCapExtract: Beacon parsing error!")); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; +} + + +/** + * limDelBss() + * + *FUNCTION: + * This function is called to delete BSS context at hardware + * whenever a STA is disassociated + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limDelBss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tANI_U16 bssIdx,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBssParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + pDelBssParams = vos_mem_malloc(sizeof(tDeleteBssParams)); + if (NULL == pDelBssParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_BSS" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pDelBssParams, sizeof(tDeleteBssParams), 0); + + + pDelBssParams->sessionId = psessionEntry->peSessionId; //update PE session Id + + //DPH was storing the AssocID in staID field, + //staID is actually assigned by HAL when AddSTA message is sent. + if (pStaDs != NULL) + { + pDelBssParams->bssIdx= pStaDs->bssId; + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + } + else + pDelBssParams->bssIdx = bssIdx; + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE)); + + if((psessionEntry->peSessionId == pMac->lim.limTimers.gLimJoinFailureTimer.sessionId) && + (VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) + { + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + } + + pDelBssParams->status= eHAL_STATUS_SUCCESS; + pDelBssParams->respReqd = 1; + vos_mem_copy(pDelBssParams->bssid, psessionEntry->bssId, sizeof(tSirMacAddr)); + pDelBssParams->smesessionId = psessionEntry->smeSessionId; + PELOGW(limLog( pMac, LOGW, FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ " + "for bss idx: %X BSSID:"MAC_ADDRESS_STR), pDelBssParams->sessionId, + pDelBssParams->bssIdx, + MAC_ADDR_ARRAY(psessionEntry->bssId));) + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_DELETE_BSS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pDelBssParams; + msgQ.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pDelBssParams); + } + + return retCode; +} + + + +/** + * limSendAddBss() + * + *FUNCTION: + * + *LOGIC: + * 1) LIM receives eWNI_SME_JOIN_REQ + * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends + * SIR_HAL_ADD_BSS_REQ to HAL + * + *ASSUMPTIONS: + * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq + * ADD BSS parameters can be obtained from two sources: + * 1) pMac->lim.gLimMlmJoinReq + * 2) beaconStruct, passed as paramter + * So, if a reqd parameter is found in bssDescriptions + * then it is given preference over beaconStruct + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * pAssocRsp contains the structured assoc/reassoc Response got from AP + * beaconstruct Has the ProbeRsp/Beacon structured details + * bssDescription bssDescription passed to PE from the SME + * @return None + */ + +tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, + tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry, + tpPESession psessionEntry) + +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + tANI_U8 i; + tpDphHashNode pStaDs = NULL; + tANI_U8 chanWidthSupp = 0; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + tANI_U32 enableTxBF20MHz; + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if (NULL == pAddBssParams) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during ADD_BSS" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + else + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + vos_mem_copy(pAddBssParams->bssId,bssDescription->bssId, + sizeof(tSirMacAddr)); + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId,updateEntry,psessionEntry->limSystemRole); + + limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->bssId)); + + if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + pAddBssParams->bssType = eSIR_BTAMP_AP_MODE; + } + else + { + pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE; + } + + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + /* Update PE session ID */ + pAddBssParams->sessionId = psessionEntry->peSessionId; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining; + + pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates); + + if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) && + bssDescription->nwType != eSIR_11B_NW_TYPE) { + pAddBssParams->nwType = eSIR_11B_NW_TYPE; + } else { + pAddBssParams->nwType = bssDescription->nwType; + } + + pAddBssParams->shortSlotTimeSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist; + + limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " + "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, + pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); + + limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" + " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, + pAddBssParams->cfParamSet.cfpMaxDuration, + pAddBssParams->cfParamSet.cfpDurRemaining, + pAddBssParams->rateSet.numRates); + + limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d" + "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), + pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, + pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, + pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); + + pAddBssParams->dot11_mode = psessionEntry->dot11mode; + limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode); + + // Use the advertised capabilities from the received beacon/PR + + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present )) + { + pAddBssParams->htCapable = pAssocRsp->HTCaps.present; + limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable); + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pAssocRsp->HTInfo.opMode; + pAddBssParams->dualCTSProtection = ( tANI_U8 ) pAssocRsp->HTInfo.dualCTSProtection; + chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); + if( (pAssocRsp->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = pAssocRsp->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode; + + limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d " + "txChannelWidthSet: %d currentExtChannel: %d "), + pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, + pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); + + limLog(pMac, LOG2, FL("llnNonGFCoexist: %d " + "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), + pAddBssParams->llnNonGFCoexist, + pAddBssParams->fLsigTXOPProtectionFullSupport, + pAddBssParams->fRIFSMode); + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + limLog(pMac, LOG2, FL("currentOperChannel %d"), + pAddBssParams->currentOperChannel); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && ( pAssocRsp->VHTCaps.present )) + { + pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = pAssocRsp->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + psessionEntry->apCenterChan, + psessionEntry); + + pAddBssParams->staContext.vht_caps = + ((pAssocRsp->VHTCaps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | + (pAssocRsp->VHTCaps.supportedChannelWidthSet << + SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | + (pAssocRsp->VHTCaps.ldpcCodingCap << + SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | + (pAssocRsp->VHTCaps.shortGI80MHz << + SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | + (pAssocRsp->VHTCaps.shortGI160and80plus80MHz << + SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | + (pAssocRsp->VHTCaps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | + (pAssocRsp->VHTCaps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | + (pAssocRsp->VHTCaps.suBeamFormerCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | + (pAssocRsp->VHTCaps.suBeamformeeCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | + (pAssocRsp->VHTCaps.csnofBeamformerAntSup << + SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | + (pAssocRsp->VHTCaps.numSoundingDim << + SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | + (pAssocRsp->VHTCaps.muBeamformerCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| + (pAssocRsp->VHTCaps.muBeamformeeCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | + (pAssocRsp->VHTCaps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | + (pAssocRsp->VHTCaps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | + (pAssocRsp->VHTCaps.maxAMPDULenExp << + SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | + (pAssocRsp->VHTCaps.vhtLinkAdaptCap << + SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | + (pAssocRsp->VHTCaps.rxAntPattern << + SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | + (pAssocRsp->VHTCaps.txAntPattern << + SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | + (pAssocRsp->VHTCaps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); + + pAddBssParams->staContext.maxAmpduSize = + SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( + pAddBssParams->staContext.vht_caps); + } + else + { + pAddBssParams->vhtCapable = 0; + } + limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d " + "currentExtChannel %d"),pAddBssParams->vhtCapable, + pAddBssParams->vhtTxChannelWidthSet, + pAddBssParams->currentExtChannel); +#endif + + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + /* staType = PEER*/ + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof( tSirMacAddr)); + pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval; + + /* Fill Assoc id from the dph table */ + pStaDs = dphLookupHashEntry(pMac, pAddBssParams->staContext.bssId, + &pAddBssParams->staContext.assocId, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Couldn't get assoc id for " + "MAC ADDR: " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac));) + return eSIR_FAILURE; + } + + if(!pMac->psOffloadEnabled) + { + pAddBssParams->staContext.uAPSD = 0; + } + else + { + pAddBssParams->staContext.uAPSD = + psessionEntry->gUapsdPerAcBitmask; + } + + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + + limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR + " shortPreambleSupported: %d"), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), + pAddBssParams->staContext.shortPreambleSupported); + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && pBeaconStruct->HTCaps.present) + { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 )pAssocRsp->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 )pAssocRsp->HTCaps.lsigTXOPProtection; + limLog(pMac, LOG2,FL("StaContext htCapable: %d greenFieldCapable: %d " + "lsigTxopProtection: %d"), pAddBssParams->staContext.htCapable, + pAddBssParams->staContext.greenFieldCapable, + pAddBssParams->staContext.lsigTxopProtection); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + pAddBssParams->staContext.vhtSupportedRxNss = pStaDs->vhtSupportedRxNss; + if ((pAssocRsp->VHTCaps.suBeamFormerCap || + pAssocRsp->VHTCaps.muBeamformerCap) && + psessionEntry->txBFIniFeatureEnabled) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + + if (pAssocRsp->VHTCaps.muBeamformerCap && + psessionEntry->txMuBformee ) + { + pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; + } + } +#endif + if( (pAssocRsp->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = pAssocRsp->VHTOperation.chanWidth; //pMac->lim.apChanWidth; + } + limLog(pMac, LOG2,FL("StaContext vhtCapable %d " + "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddBssParams->staContext.vhtCapable, + pAddBssParams->staContext.vhtTxChannelWidthSet, + pAddBssParams->staContext.vhtTxBFCapable); +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + &enableTxBF20MHz))) { + if (VOS_FALSE == enableTxBF20MHz) { + pAddBssParams->staContext.vhtTxBFCapable = 0; + } + } + } + pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 )pAssocRsp->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = pAssocRsp->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz; + /* + * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. + * if they are set then we will use what ever Assoc response coming + * from AP supports. If these values are set as 0 in ini file then + * we will hardcode this values to 0. + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddBssParams->staContext.fShortGI20Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz; + } + else + { + pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddBssParams->staContext.fShortGI40Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz; + } + else + { + pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + +#ifdef WLAN_FEATURE_11AC + if (!pAddBssParams->staContext.vhtCapable) + // Use max ampd factor advertised in HTCAP for non-vht connection +#endif + { + pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor; + } + else if (pAddBssParams->staContext.maxAmpduSize < pAssocRsp->HTCaps.maxRxAMPDUFactor) + { + pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor; + } + if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) + { + pAddBssParams->staContext.htLdpcCapable = 0; + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + else + { + pAddBssParams->staContext.htLdpcCapable = (tANI_U8)pAssocRsp->HTCaps.advCodingCap; + pAddBssParams->staContext.vhtLdpcCapable = (tANI_U8)pAssocRsp->VHTCaps.ldpcCodingCap; + } + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode; + + limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d" + " delBASupport: %d maxAmsduSize: %d"), + pAddBssParams->staContext.txChannelWidthSet, + pAddBssParams->staContext.mimoPS, + pAddBssParams->staContext.delBASupport, + pAddBssParams->staContext.maxAmsduSize); + + limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " + "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, + pAddBssParams->staContext.fDsssCckMode40Mhz, + pAddBssParams->staContext.fShortGI20Mhz); + + limLog(pMac, LOG2, FL("fShortGI40Mh: %d maxAmpduSize: %d " + "htLdpcCapable: %d vhtLdpcCapable: %d"), + pAddBssParams->staContext.fShortGI40Mhz, + pAddBssParams->staContext.maxAmpduSize, + pAddBssParams->staContext.htLdpcCapable, + pAddBssParams->staContext.vhtLdpcCapable); + } + pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId; + pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent; + pAddBssParams->staContext.wpa_rsn |= (pBeaconStruct->wpaPresent << 1); + /* For OSEN Connection AP does not advertise RSN or WPA IE + * so from the IEs we get from supplicant we get this info + * so for FW to transmit EAPOL message 4 we shall set + * wpa_rsn + */ + if ((!pAddBssParams->staContext.wpa_rsn) && (psessionEntry->isOSENConnection)) + pAddBssParams->staContext.wpa_rsn = 1; + vos_mem_copy(&pAddBssParams->staContext.capab_info, + &pAssocRsp->capabilityInfo, + sizeof(pAddBssParams->staContext.capab_info)); + vos_mem_copy(&pAddBssParams->staContext.ht_caps, + (tANI_U8 *)&pAssocRsp->HTCaps + sizeof(tANI_U8), + sizeof(pAddBssParams->staContext.ht_caps)); + + //If WMM IE or 802.11E IE is present then enable WMM + if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) || + (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent)) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + //Update the rates + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry); + vos_mem_copy((tANI_U8*)&pAddBssParams->staContext.supportedRates, + (tANI_U8*)&pStaDs->supportedRates, + sizeof(tSirSupportedRates)); + } + else + PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates."));) + + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE; + } + + pAddBssParams->staContext.encryptType = psessionEntry->encryptType; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; + limLog(pMac, LOG2,FL("maxTxPower: %d"), + pAddBssParams->maxTxPower); +#endif + // FIXME_GEN4 - Any other value that can be used for initialization? + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) + { + pAddBssParams->staContext.p2pCapableSta = 1; + } + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; + limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"), + pAddBssParams->extSetStaKeyParamValid); +#endif + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + // Set a new state for MLME + if( eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState ) + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE; + else + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d " + "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, + pAddBssParams->staContext.encryptType, + pAddBssParams->staContext.p2pCapableSta); + + limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " + "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, + pAddBssParams->halPersona, psessionEntry->limMlmState); + if (psessionEntry->isNonRoamReassoc) { + pAddBssParams->nonRoamReassoc = 1; + } + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_ADD_BSS_REQ; + /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG1, FL("SessionId:%d Sending WDA_ADD_BSS_REQ"), + psessionEntry->peSessionId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddBssParams); + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + + } + else + return retCode; + + returnFailure: + // Clean-up will be done by the caller... + return retCode; +} + + + + +tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + tANI_U8 i; + tSchBeaconStruct *pBeaconStruct; + tANI_U8 chanWidthSupp = 0; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + tpSirBssDescription bssDescription = &psessionEntry->pLimJoinReq->bssDescription; + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory during ADD_BSS") ); + return eSIR_MEM_ALLOC_FAILED; + } + + + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof(tAddBssParams)); + if (NULL == pAddBssParams) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during ADD_BSS" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + + limExtractApCapabilities( pMac, + (tANI_U8 *) bssDescription->ieFields, + limGetIElenFromBssDescription( bssDescription ), + pBeaconStruct ); + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId, + sizeof(tSirMacAddr)); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId,updateEntry,psessionEntry->limSystemRole); + + limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->bssId)); + /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on + * top of an already established Infra link. This lead to issues in + * concurrent data transfer. + */ + + pAddBssParams->bssType = psessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE; + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining; + + + pAddBssParams->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); + + pAddBssParams->nwType = bssDescription->nwType; + + pAddBssParams->shortSlotTimeSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist; + + limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " + "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, + pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); + + limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" + " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, + pAddBssParams->cfParamSet.cfpMaxDuration, + pAddBssParams->cfParamSet.cfpDurRemaining, + pAddBssParams->rateSet.numRates); + + limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d" + "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), + pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, + pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, + pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); + // Use the advertised capabilities from the received beacon/PR + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; + limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable); + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode; + pAddBssParams->dualCTSProtection = ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection; + + chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = pBeaconStruct->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode; + + limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d " + "txChannelWidthSet: %d currentExtChannel: %d "), + pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, + pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); + + limLog(pMac, LOG2, FL("llnNonGFCoexist: %d " + "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), + pAddBssParams->llnNonGFCoexist, + pAddBssParams->fLsigTXOPProtectionFullSupport, + pAddBssParams->fRIFSMode); + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + limLog(pMac, LOG2, FL("currentOperChannel %d"), + pAddBssParams->currentOperChannel); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = pBeaconStruct->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + psessionEntry->apCenterChan, + psessionEntry); + pAddBssParams->staContext.maxAmpduSize = + SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( + pAddBssParams->staContext.vht_caps); + } + else + { + pAddBssParams->vhtCapable = 0; + } + limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d " + "currentExtChannel %d"),pAddBssParams->vhtCapable, + pAddBssParams->vhtTxChannelWidthSet, + pAddBssParams->currentExtChannel); +#endif + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof(tSirMacAddr)); + pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval; + + pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this? + pAddBssParams->staContext.uAPSD = 0; + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + + limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR + " shortPreambleSupported: %d"), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), + pAddBssParams->staContext.shortPreambleSupported); + + pAddBssParams->dot11_mode = psessionEntry->dot11mode; + limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode); + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) pBeaconStruct->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection; + limLog(pMac, LOG2, FL("StaContext htCapable: %d " + "greenFieldCapable: %d lsigTxopProtection: %d"), + pAddBssParams->staContext.htCapable, + pAddBssParams->staContext.greenFieldCapable, + pAddBssParams->staContext.lsigTxopProtection); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + if ((pBeaconStruct->VHTCaps.suBeamFormerCap || + pBeaconStruct->VHTCaps.muBeamformerCap) && + psessionEntry->txBFIniFeatureEnabled ) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + + if ( pBeaconStruct->VHTCaps.muBeamformerCap && + psessionEntry->txMuBformee ) + { + pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; + } + } +#endif + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = + pBeaconStruct->VHTOperation.chanWidth; + } + limLog(pMac, LOG2,FL("StaContext vhtCapable %d " + "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddBssParams->staContext.vhtCapable, + pAddBssParams->staContext.vhtTxChannelWidthSet, + pAddBssParams->staContext.vhtTxBFCapable); +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz; + /* + * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. + * if they are set then we will use what ever Beacon coming from AP + * supports. If these values are set as 0 in ini file then + * we will hardcode this values to 0. + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddBssParams->staContext.fShortGI20Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz; + } + else + { + pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddBssParams->staContext.fShortGI40Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz; + } + else + { + pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + + pAddBssParams->staContext.maxAmpduSize= pBeaconStruct->HTCaps.maxRxAMPDUFactor; + if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) + { + pAddBssParams->staContext.htLdpcCapable = 0; + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + else + { + pAddBssParams->staContext.htLdpcCapable = (tANI_U8)pBeaconStruct->HTCaps.advCodingCap; + pAddBssParams->staContext.vhtLdpcCapable = (tANI_U8)pBeaconStruct->VHTCaps.ldpcCodingCap; + } + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = pBeaconStruct->HTInfo.rifsMode; + limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d" + " delBASupport: %d maxAmsduSize: %d"), + pAddBssParams->staContext.txChannelWidthSet, + pAddBssParams->staContext.mimoPS, + pAddBssParams->staContext.delBASupport, + pAddBssParams->staContext.maxAmsduSize); + + limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " + "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, + pAddBssParams->staContext.fDsssCckMode40Mhz, + pAddBssParams->staContext.fShortGI20Mhz); + + limLog(pMac, LOG2, FL("fShortGI40Mh: %d maxAmpduSize: %d " + "htLdpcCapable: %d vhtLdpcCapable: %d"), + pAddBssParams->staContext.fShortGI40Mhz, + pAddBssParams->staContext.maxAmpduSize, + pAddBssParams->staContext.htLdpcCapable, + pAddBssParams->staContext.vhtLdpcCapable); + } + + //If WMM IE or 802.11E IE is not present and AP is HT AP then enable WMM + if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent || pAddBssParams->staContext.htCapable)) || + (psessionEntry->limQosEnabled && (pBeaconStruct->edcaPresent || pAddBssParams->staContext.htCapable))) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + //Update the rates +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry, + &pBeaconStruct->VHTCaps); +#else + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry); +#endif + limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,psessionEntry); + + } + + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE; + } + + pAddBssParams->staContext.encryptType = psessionEntry->encryptType; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; + limLog(pMac, LOG2,FL("maxTxPower: %d"), + pAddBssParams->maxTxPower); +#endif + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId; + pAddBssParams->staContext.sessionId = psessionEntry->peSessionId; + pAddBssParams->sessionId = psessionEntry->peSessionId; + + pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; + limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"), + pAddBssParams->extSetStaKeyParamValid); +#endif + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + // Set a new state for MLME + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d " + "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, + pAddBssParams->staContext.encryptType, + pAddBssParams->staContext.p2pCapableSta); + + limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " + "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, + pAddBssParams->halPersona, psessionEntry->limMlmState); + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_ADD_BSS_REQ; + /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG1, FL("SessionId:%d Sending WDA_ADD_BSS_REQ"), + psessionEntry->peSessionId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddBssParams); + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + + } + else + { + vos_mem_free(pBeaconStruct); + return retCode; + } + + returnFailure: + // Clean-up will be done by the caller... + vos_mem_free(pBeaconStruct); + return retCode; +} + + + + + + +/** ------------------------------------------------------------- +\fn limPrepareAndSendDelStaCnf +\brief deletes DPH entry + changes the MLM mode for station. + calls limSendDelStaCnf +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\return none + -------------------------------------------------------------*/ + + +void +limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession psessionEntry) +{ + tANI_U16 staDsAssocId = 0; + tSirMacAddr staDsAddr; + tLimMlmStaContext mlmStaContext; + + if(pStaDs == NULL) + { + PELOGW(limLog(pMac, LOGW, FL("pStaDs is NULL"));) + return; + } + staDsAssocId = pStaDs->assocId; + vos_mem_copy((tANI_U8 *)staDsAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + + mlmStaContext = pStaDs->mlmStaContext; + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + } + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry); + + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + } + limSendDelStaCnf(pMac, staDsAddr, staDsAssocId, mlmStaContext, statusCode,psessionEntry); +} + +/** ------------------------------------------------------------- +\fn limGetStaRateMode +\brief Gets the Station Rate Mode. +\param tANI_U8 dot11Mode +\return none + -------------------------------------------------------------*/ +tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode) +{ + switch(dot11Mode) + { + case WNI_CFG_DOT11_MODE_11A: + return eSTA_11a; + case WNI_CFG_DOT11_MODE_11B: + return eSTA_11b; + case WNI_CFG_DOT11_MODE_11G: + return eSTA_11bg; + case WNI_CFG_DOT11_MODE_11N: + return eSTA_11n; +#ifdef WLAN_FEATURE_11AC + case WNI_CFG_DOT11_MODE_11AC: + return eSTA_11ac; +#endif + case WNI_CFG_DOT11_MODE_ALL: + default: + return eSTA_11n; + + } +} + +/** ------------------------------------------------------------- +\fn limInitPreAuthTimerTable +\brief Initialize the Pre Auth Tanle and creates the timer for + each node for the timeout value got from cfg. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pPreAuthTimerTable +\return none + -------------------------------------------------------------*/ +void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable) +{ + tANI_U32 cfgValue; + tANI_U32 authNodeIdx; + tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable; + + // Get AUTH_RSP Timers value + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /* + ** Could not get AUTH_RSP timeout value + ** from CFG. Log error. + **/ + limLog(pMac, LOGP, + FL("could not retrieve AUTH_RSP timeout value")); + return; + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + for(authNodeIdx=0; authNodeIdxnumEntry; authNodeIdx++, pAuthNode++) + { + if (tx_timer_create(&pAuthNode->timer, + "AUTH RESPONSE TIMEOUT", + limAuthResponseTimerHandler, + authNodeIdx, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create timer. Log error. + limLog(pMac, LOGP, FL("Cannot create Auth Rsp timer of Index :%d."), authNodeIdx); + return; + } + pAuthNode->authNodeIdx = (tANI_U8)authNodeIdx; + pAuthNode->fFree = 1; + } + +} + +/** ------------------------------------------------------------- +\fn limAcquireFreePreAuthNode +\brief Retrives a free Pre Auth node from Pre Auth Table. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pPreAuthTimerTable +\return none + -------------------------------------------------------------*/ +tLimPreAuthNode * limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable) +{ + tANI_U32 i; + tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable; + for (i=0; inumEntry; i++,pTempNode++) + { + if (pTempNode->fFree == 1) + { + pTempNode->fFree = 0; + return pTempNode; + } + } + + return NULL; +} + +/** ------------------------------------------------------------- +\fn limGetPreAuthNodeFromIndex +\brief Depending on the Index this retrives the pre auth node. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pAuthTable +\param tANI_U32 authNodeIdx +\return none + -------------------------------------------------------------*/ +tLimPreAuthNode * limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac, + tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx) +{ + if ((authNodeIdx >= pAuthTable->numEntry) || (pAuthTable->pTable == NULL)) + { + limLog(pMac, LOGE, FL("Invalid Auth Timer Index : %d NumEntry : %d"), + authNodeIdx, pAuthTable->numEntry); + return NULL; + } + + return pAuthTable->pTable + authNodeIdx; +} + +/* Util API to check if the channels supported by STA is within range */ +tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc) +{ + /* + * Allow all the stations to join with us. + * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs + * as an input into an algorithm used to select a new channel for the BSS. + * The specification of the algorithm is beyond the scope of this amendment. + */ + + return (eSIR_SUCCESS); +} + +/* Util API to check if the txpower supported by STA is within range */ +tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession psessionEntry) +{ + tPowerdBm localMaxTxPower; + tANI_U32 localPwrConstraint; + + localMaxTxPower = cfgGetRegulatoryMaxTransmitPower(pMac, psessionEntry->currentOperChannel); + + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return eSIR_FAILURE; + } + localMaxTxPower -= (tPowerdBm)localPwrConstraint; + + /** + * The min Tx Power of the associating station should not be greater than (regulatory + * max tx power - local power constraint configured on AP). + */ + if(assoc->powerCapability.minTxPower > localMaxTxPower) + { + limLog(pMac, LOGW, FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"), + assoc->powerCapability.minTxPower, localMaxTxPower); + return (eSIR_FAILURE); + } + + return (eSIR_SUCCESS); +} + +/** ------------------------------------------------------------- +\fn limFillRxHighestSupportedRate +\brief Fills in the Rx Highest Supported Data Rate field from +\ the 'supported MCS set' field in HT capability element. +\param tpAniSirGlobal pMac +\param tpSirSupportedRates pRates +\param tANI_U8* pSupportedMCSSet +\return none + -------------------------------------------------------------*/ +void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet) +{ + tSirMacRxHighestSupportRate *pRxHighestRate; + tANI_U8 *pBuf; + tANI_U16 rate=0; + + pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET; + rate = limGetU16(pBuf); + + pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate; + *rxHighestRate = pRxHighestRate->rate; + + return; +} + +#ifdef WLAN_FEATURE_11W +/** ------------------------------------------------------------- +\fn limSendSmeUnprotectedMgmtFrameInd +\brief Forwards the unprotected management frame to SME. +\param tpAniSirGlobal pMac +\param frameType - 802.11 frame type +\param frame - frame buffer +\param sessionId - id for the current session +\param psessionEntry - PE session context +\return none + -------------------------------------------------------------*/ +void limSendSmeUnprotectedMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, + tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeUnprotMgmtFrameInd * pSirSmeMgmtFrame = NULL; + tANI_U16 length; + + length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen; + + pSirSmeMgmtFrame = vos_mem_malloc(length); + if (NULL == pSirSmeMgmtFrame) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd")); + return; + } + vos_mem_set((void*)pSirSmeMgmtFrame, length, 0); + + pSirSmeMgmtFrame->sessionId = sessionId; + pSirSmeMgmtFrame->frameType = frameType; + + vos_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen); + pSirSmeMgmtFrame->frameLen = frameLen; + + mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND; + mmhMsg.bodyptr = pSirSmeMgmtFrame; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** ------------------------------------------------------------- +\fn limSendSmeTsmIEInd +\brief Forwards the TSM IE information to SME. +\param tpAniSirGlobal pMac +\param psessionEntry - PE session context +\param tid - traffic id +\param state - tsm state (enabled/disabled) +\param measurementInterval - measurement interval +\return none + -------------------------------------------------------------*/ +void limSendSmeTsmIEInd(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval) +{ + tSirMsgQ mmhMsg; + tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL; + + if (!pMac || !psessionEntry) + { + return; + } + pSirSmeTsmIeInd = vos_mem_malloc(sizeof(tSirSmeTsmIEInd)); + if (NULL == pSirSmeTsmIeInd) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for tSirSmeTsmIEInd")); + return; + } + vos_mem_set((void*)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0); + + pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId; + pSirSmeTsmIeInd->tsmIe.tsid = tid; + pSirSmeTsmIeInd->tsmIe.state= state; + pSirSmeTsmIeInd->tsmIe.msmt_interval= measInterval; + + mmhMsg.type = eWNI_SME_TSM_IE_IND; + mmhMsg.bodyptr = pSirSmeTsmIeInd; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.h new file mode 100644 index 0000000000000..0ba084232cf57 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limAssocUtils.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limAssocUtils.h contains the utility definitions + * LIM uses while processing Re/Association messages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ +#ifndef __LIM_ASSOC_UTILS_H +#define __LIM_ASSOC_UTILS_H + +#include "sirApi.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "limTypes.h" + + +tANI_U8 limCmpSSid(tpAniSirGlobal, tSirMacSSid *,tpPESession); +tANI_U8 limCompareCapabilities(tpAniSirGlobal, + tSirAssocReq *, + tSirMacCapabilityInfo *,tpPESession); +tANI_U8 limCheckRxBasicRates(tpAniSirGlobal, tSirMacRateSet,tpPESession); +tANI_U8 limCheckRxRSNIeMatch(tpAniSirGlobal, tDot11fIERSN, tpPESession, tANI_U8, tANI_BOOLEAN *); +tANI_U8 limCheckRxWPAIeMatch(tpAniSirGlobal, tDot11fIEWPA, tpPESession, tANI_U8); +tANI_U8 limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet); +void limPostDummyToTmRing(tpAniSirGlobal, tpDphHashNode); +void limPostPacketToTdRing(tpAniSirGlobal, + tpDphHashNode, + tANI_U8); +tSirRetStatus limCleanupRxPath(tpAniSirGlobal, tpDphHashNode,tpPESession); +void limRejectAssociation(tpAniSirGlobal , tSirMacAddr, tANI_U8, + tANI_U8 , tAniAuthType, + tANI_U16, tANI_U8, tSirResultCodes, tpPESession); + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); +#else +tSirRetStatus limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry); +#endif + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); + +#else +tSirRetStatus limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry); +#endif + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); +#else +tSirRetStatus limPopulateMatchingRateSet(tpAniSirGlobal, + tpDphHashNode, + tSirMacRateSet *, + tSirMacRateSet *, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *, tpPESession); + + +#endif + +#ifdef WLAN_FEATURE_11AC +#define MCSMAPMASK1x1 0x3 +#define MCSMAPMASK2x2 0xC +#endif + +tSirRetStatus limAddSta(tpAniSirGlobal, tpDphHashNode, tANI_U8, tpPESession); +tSirRetStatus limDelBss(tpAniSirGlobal, tpDphHashNode, tANI_U16, tpPESession); +tSirRetStatus limDelSta(tpAniSirGlobal, tpDphHashNode, tANI_BOOLEAN, tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, + tpPESession psessionEntry); +#endif /* WLAN_FEATURE_VOWIFI_11R */ +tSirRetStatus limAddStaSelf(tpAniSirGlobal, tANI_U16, tANI_U8, tpPESession); +tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode); + + +void limTeardownInfraBss(tpAniSirGlobal,tpPESession); +void limRestorePreReassocState(tpAniSirGlobal, + tSirResultCodes, + tANI_U16,tpPESession); +void limPostReassocFailure(tpAniSirGlobal, + tSirResultCodes, + tANI_U16,tpPESession); +eAniBoolean limIsReassocInProgress(tpAniSirGlobal,tpPESession); +void +limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr, + tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry); + +void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId); +void limDeleteDphHashEntry(tpAniSirGlobal, tSirMacAddr, tANI_U16,tpPESession); +void limCheckAndAnnounceJoinSuccess(tpAniSirGlobal, + tSirProbeRespBeacon *, + tpSirMacMgmtHdr,tpPESession); +void limUpdateReAssocGlobals(tpAniSirGlobal pMac, + tpSirAssocRsp pAssocRsp,tpPESession psessionEntry); + +void limUpdateAssocStaDatas(tpAniSirGlobal pMac, + tpDphHashNode pStaDs,tpSirAssocRsp pAssocRsp,tpPESession psessionEntry); +void +limFillSupportedRatesInfo( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpSirSupportedRates pRates, + tpPESession psessionEntry); + +tSirRetStatus limStaSendAddBss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, + tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry, tpPESession psessionEntry); +tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry); + +void limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession); +tSirRetStatus limExtractApCapabilities(tpAniSirGlobal pMac, tANI_U8 * pIE, tANI_U16 ieLen, tpSirProbeRespBeacon beaconStruct); +void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable); +tpLimPreAuthNode limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable); +tpLimPreAuthNode limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac, tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx); + +/* Util API to check if the channels supported by STA is within range */ +tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc); + +/* Util API to check if the txpower supported by STA is within range */ +tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession); + +/* API to re-add the same BSS during re-association */ +void limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + +/* API to fill in RX Highest Supported data Rate */ +void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void limSendRetryReassocReqFrame(tpAniSirGlobal pMac, tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry); +#endif +#ifdef WLAN_FEATURE_11W +void limSendSmeUnprotectedMgmtFrameInd(tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, tpPESession psessionEntry); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void limSendSmeTsmIEInd( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#endif /* __LIM_ASSOC_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.c new file mode 100644 index 0000000000000..9df867428c967 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + ========================================================================*/ + +#include "limDebug.h" + +void limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_LIM_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_LIM_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.h new file mode 100644 index 0000000000000..371ff401ce04a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limDebug.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limDebug.h contains log function called by LIM module. + * + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_DEBUG_H__ +#define __LIM_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +/* define this to show more message in the LIM during TDLS development */ +#define LIM_DEBUG_TDLS + +#ifdef LIM_DEBUG_TDLS +#define LIM_LOG_TDLS(x0) x0 +#else +#define LIM_LOG_TDLS(x0) +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limFT.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limFT.c new file mode 100644 index 0000000000000..a07bfcbf237fb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limFT.c @@ -0,0 +1,2020 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + \brief implementation for PE 11r VoWiFi FT Protocol + + ========================================================================*/ + +/* $Header$ */ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wmmApsd.h" + +extern void limSendSetStaKeyReq( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tANI_U16 staIdx, + tANI_U8 defWEPIdx, + tpPESession sessionEntry, + tANI_BOOLEAN sendRsp); + +/*-------------------------------------------------------------------------- + Initialize the FT variables. + ------------------------------------------------------------------------*/ +void limFTOpen(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry) + vos_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0); +} + +/*-------------------------------------------------------------------------- + Cleanup FT variables. + ------------------------------------------------------------------------*/ +void limFTCleanupPreAuthInfo(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tpPESession pReAssocSessionEntry = NULL; + tANI_U8 sessionId = 0; + if (!psessionEntry) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, "%s: psessionEntry is NULL", __func__);) +#endif + return; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + if (psessionEntry->ftPEContext.pFTPreAuthReq) { + pReAssocSessionEntry = + peFindSessionByBssid(pMac, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, + &sessionId); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog( pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"), + psessionEntry->ftPEContext.pFTPreAuthReq);) +#endif + if (psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { + vos_mem_free( + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription); + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); + psessionEntry->ftPEContext.pFTPreAuthReq = NULL; + } + + if (psessionEntry->ftPEContext.pAddBssReq) { + vos_mem_free(psessionEntry->ftPEContext.pAddBssReq); + psessionEntry->ftPEContext.pAddBssReq = NULL; + } + + if (psessionEntry->ftPEContext.pAddStaReq) { + vos_mem_free(psessionEntry->ftPEContext.pAddStaReq); + psessionEntry->ftPEContext.pAddStaReq = NULL; + } + + /* The session is being deleted, cleanup the contents */ + vos_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0); + + /* Delete the session created while handling pre-auth response */ + if (pReAssocSessionEntry) { + /* If we have successful pre-auth response, then we would have + * created a session on which reassoc request will be sent + */ + if (pReAssocSessionEntry->valid && + pReAssocSessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) { + limLog( pMac, LOG1, FL("Deleting Preauth Session %d"), + pReAssocSessionEntry->peSessionId); + peDeleteSession(pMac, pReAssocSessionEntry); + } + } +} + +void limFTCleanupAllFTSessions(tpAniSirGlobal pMac) +{ + /* Wrapper function to cleanup all FT sessions */ + int i; + + for (i = 0; i < pMac->lim.maxBssId; i++) { + if (VOS_TRUE == pMac->lim.gpSession[i].valid) { + /* The session is valid, may have FT data */ + limFTCleanup(pMac, &pMac->lim.gpSession[i]); + } + } +} + +void limFTCleanup(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (NULL == psessionEntry) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is NULL"));) +#endif + return; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog( pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"), + psessionEntry->ftPEContext.pFTPreAuthReq);) +#endif + if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { + vos_mem_free( + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription); + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); + psessionEntry->ftPEContext.pFTPreAuthReq = NULL; + } + + if (psessionEntry->ftPEContext.pAddBssReq) { + vos_mem_free(psessionEntry->ftPEContext.pAddBssReq); + psessionEntry->ftPEContext.pAddBssReq = NULL; + } + + if (psessionEntry->ftPEContext.pAddStaReq) { + vos_mem_free(psessionEntry->ftPEContext.pAddStaReq); + psessionEntry->ftPEContext.pAddStaReq = NULL; + } + + /* The session is being deleted, cleanup the contents */ + vos_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0); +} + +/*------------------------------------------------------------------ + * + * This is the handler after suspending the link. + * We suspend the link and then now proceed to switch channel. + * + *------------------------------------------------------------------*/ +void static +limFTPreAuthSuspendLinkHandler(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data) +{ + tpPESession psessionEntry = (tpPESession)data; + + /* The link is suspended of not */ + if (NULL == psessionEntry || + NULL == psessionEntry->ftPEContext.pFTPreAuthReq || + status != eHAL_STATUS_SUCCESS) { + PELOGE(limLog( pMac, LOGE, + FL("preAuth error, status = %d"), status);) + limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + return; + } + + /* Suspended, now move to a different channel. + * Perform some sanity check before proceeding + */ + if (psessionEntry->ftPEContext.pFTPreAuthReq) { + limChangeChannelWithCallback(pMac, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum, + limPerformFTPreAuth, NULL, psessionEntry); + return; + } +} + + +/*-------------------------------------------------------------------------- + In this function, we process the FT Pre Auth Req. + We receive Pre-Auth + Suspend link + Register a call back + In the call back, we will need to accept frames from the new bssid + Send out the auth req to new AP. + Start timer and when the timer is done or if we receive the Auth response + We change channel + Resume link + ------------------------------------------------------------------------*/ +int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + int bufConsumed = FALSE; + tpPESession psessionEntry; + tANI_U8 sessionId; + tpSirFTPreAuthReq ftPreAuthReq = + (tSirFTPreAuthReq *)pMsg->bodyptr; + + if (NULL == ftPreAuthReq) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("tSirFTPreAuthReq is NULL"));) +#endif + return bufConsumed; + } + + /* Get the current session entry */ + psessionEntry = + peFindSessionByBssid(pMac, ftPreAuthReq->currbssId, &sessionId); + if (psessionEntry == NULL) { + PELOGE(limLog( pMac, LOGE, + FL("Unable to find session for the following bssid"));) + limPrintMacAddr( pMac, ftPreAuthReq->currbssId, LOGE ); + + /* Post the FT Pre Auth Response to SME */ + limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + /* return FALSE, since the Pre-Auth Req will be freed in + * limPostFTPreAuthRsp on failure + */ + return bufConsumed; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + bufConsumed = TRUE; + return bufConsumed; + } + + /* Can set it only after sending auth */ + psessionEntry->ftPEContext.ftPreAuthStatus = eSIR_FAILURE; + psessionEntry->ftPEContext.ftPreAuthSession = VOS_TRUE; + + /* Indicate that this is the session on which preauth is being done */ + if (psessionEntry->ftPEContext.pFTPreAuthReq) { + if (psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) + { + vos_mem_free( + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription); + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); + psessionEntry->ftPEContext.pFTPreAuthReq = NULL; + } + + /* We need information from the Pre-Auth Req. Lets save that */ + psessionEntry->ftPEContext.pFTPreAuthReq = ftPreAuthReq; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, FL("PE Auth ft_ies_length=%02x%02x%02x"), + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies[0], + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies[1], + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies[2]);) +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT, + psessionEntry, 0, 0); +#endif + + /* Dont need to suspend if APs are in same channel */ + if (psessionEntry->currentOperChannel != + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + /* Need to suspend link only if the channels are different */ + PELOG2(limLog(pMac, LOG2, FL("Performing pre-auth on different" + " channel (session %p)"), psessionEntry);) + limSuspendLink(pMac, eSIR_CHECK_ROAMING_SCAN, + limFTPreAuthSuspendLinkHandler, + (tANI_U32 *)psessionEntry); + } else { + PELOG2(limLog(pMac, LOG2, FL("Performing pre-auth on same" + " channel (session %p)"), psessionEntry);) + /* We are in the same channel. Perform pre-auth */ + limPerformFTPreAuth(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry); + } + + return bufConsumed; +} + +/*------------------------------------------------------------------ + * Send the Auth1 + * Receive back Auth2 + *------------------------------------------------------------------*/ +void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + tSirMacAuthFrameBody authFrame; + + if (NULL == psessionEntry) { + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is NULL"));) + return; + } + + if (psessionEntry->is11Rconnection && + psessionEntry->ftPEContext.pFTPreAuthReq) { + /* Only 11r assoc has FT IEs */ + if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies == NULL) { + PELOGE(limLog( pMac, LOGE, + "%s: FTIEs for Auth Req Seq 1 is absent", + __func__);) + goto preauth_fail; + } + } + + if (status != eHAL_STATUS_SUCCESS) { + PELOGE(limLog( pMac, LOGE, + "%s: Change channel not successful for FT pre-auth", + __func__);) + goto preauth_fail; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG2(limLog(pMac,LOG2,"Entered wait auth2 state for FT" + " (old session %p)", psessionEntry);) +#endif + + if (psessionEntry->is11Rconnection) { + /* Now we are on the right channel and need to send out Auth1 and + * receive Auth2 + */ + authFrame.authAlgoNumber = eSIR_FT_AUTH; + } +#if defined FEATURE_WLAN_ESE || defined FEATURE_WLAN_LFR + else { + /* Will need to make isESEconnection a enum may be for further + * improvements to this to match this algorithm number + */ + authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; + } +#endif + authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrame.authStatusCode = 0; + + /* Start timer here to come back to operating channel */ + pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = + psessionEntry->peSessionId; + if(TX_SUCCESS != + tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, FL("FT Auth Rsp Timer Start Failed"));) +#endif + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, + eLIM_FT_PREAUTH_RSP_TIMER)); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog( pMac, LOG1, FL("FT Auth Rsp Timer Started"));) +#endif + + limSendAuthMgmtFrame(pMac, &authFrame, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, + LIM_NO_WEP_IN_FC, psessionEntry); + return; + +preauth_fail: + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + return; +} + +/*------------------------------------------------------------------ + * + * Create the new Add Bss Req to the new AP. + * This will be used when we are ready to FT to the new AP. + * The newly created ft Session entry is passed to this function + * + *------------------------------------------------------------------*/ +tSirRetStatus limFTPrepareAddBssReq( tpAniSirGlobal pMac, + tANI_U8 updateEntry, tpPESession pftSessionEntry, + tpSirBssDescription bssDescription ) +{ + tpAddBssParams pAddBssParams = NULL; + tANI_U8 i; + tANI_U8 chanWidthSupp = 0; + tSchBeaconStruct *pBeaconStruct; + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != pftSessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return eSIR_FAILURE; + } + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) { + limLog(pMac, LOGE, + FL("Unable to allocate memory for creating ADD_BSS") ); + return eSIR_MEM_ALLOC_FAILED; + } + + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if (NULL == pAddBssParams) { + vos_mem_free(pBeaconStruct); + limLog( pMac, LOGP, + FL( "Unable to allocate memory for creating ADD_BSS" )); + return (eSIR_MEM_ALLOC_FAILED); + } + + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + limExtractApCapabilities( pMac, + (tANI_U8 *) bssDescription->ieFields, + limGetIElenFromBssDescription( bssDescription ), pBeaconStruct ); + + if (pMac->lim.gLimProtectionControl != + WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, pftSessionEntry); + + vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId, + sizeof(tSirMacAddr)); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + + pAddBssParams->bssType = pftSessionEntry->bssType; + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + pAddBssParams->reassocReq = true; + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = + pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = + pBeaconStruct->cfParamSet.cfpDurRemaining; + + + pAddBssParams->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pBeaconStruct->supportedRates.rate, + pBeaconStruct->supportedRates.numRates); + + pAddBssParams->nwType = bssDescription->nwType; + + pAddBssParams->shortSlotTimeSupported = + (tANI_U8)pBeaconStruct->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = + (tANI_U8) pftSessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = + (tANI_U8) pftSessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = + (tANI_U8) pftSessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = + (tANI_U8) pftSessionEntry->beaconParams.ht20Coexist; +#ifdef WLAN_FEATURE_11W + pAddBssParams->rmfEnabled = pftSessionEntry->limRmfEnabled; +#endif + + // Use the advertised capabilities from the received beacon/PR + if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && + ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; + vos_mem_copy(&pAddBssParams->staContext.capab_info, + &pBeaconStruct->capabilityInfo, + sizeof(pAddBssParams->staContext.capab_info)); + vos_mem_copy(&pAddBssParams->staContext.ht_caps, + (tANI_U8 *)&pBeaconStruct->HTCaps + sizeof(tANI_U8), + sizeof(pAddBssParams->staContext.ht_caps)); + + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = + (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode; + pAddBssParams->dualCTSProtection = + ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection; + + chanWidthSupp = limGetHTCapability( pMac, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + pftSessionEntry); + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = + ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = + pBeaconStruct->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = + (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = + (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode; + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + pftSessionEntry->htSecondaryChannelOffset = + pAddBssParams->currentExtChannel; + +#ifdef WLAN_FEATURE_11AC + if (pftSessionEntry->vhtCapability && + pftSessionEntry->vhtCapabilityPresentInBeacon) + { + pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = + pBeaconStruct->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = + limGet11ACPhyCBState(pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + pftSessionEntry->apCenterChan, + pftSessionEntry); + pAddBssParams->staContext.vht_caps = + ((pBeaconStruct->VHTCaps.maxMPDULen << + SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | + (pBeaconStruct->VHTCaps.supportedChannelWidthSet << + SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | + (pBeaconStruct->VHTCaps.ldpcCodingCap << + SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | + (pBeaconStruct->VHTCaps.shortGI80MHz << + SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | + (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz << + SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | + (pBeaconStruct->VHTCaps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | + (pBeaconStruct->VHTCaps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | + (pBeaconStruct->VHTCaps.suBeamFormerCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | + (pBeaconStruct->VHTCaps.suBeamformeeCap << + SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | + (pBeaconStruct->VHTCaps.csnofBeamformerAntSup << + SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | + (pBeaconStruct->VHTCaps.numSoundingDim << + SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | + (pBeaconStruct->VHTCaps.muBeamformerCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| + (pBeaconStruct->VHTCaps.muBeamformeeCap << + SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | + (pBeaconStruct->VHTCaps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | + (pBeaconStruct->VHTCaps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | + (pBeaconStruct->VHTCaps.maxAMPDULenExp << + SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | + (pBeaconStruct->VHTCaps.vhtLinkAdaptCap << + SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | + (pBeaconStruct->VHTCaps.rxAntPattern << + SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | + (pBeaconStruct->VHTCaps.txAntPattern << + SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | + (pBeaconStruct->VHTCaps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); + } + else + { + pAddBssParams->vhtCapable = 0; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "SIR_HAL_ADD_BSS_REQ with channel = %d..." ), + pAddBssParams->currentOperChannel); +#endif + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof(tSirMacAddr)); + pAddBssParams->staContext.listenInterval = + bssDescription->beaconInterval; + + pAddBssParams->staContext.assocId = 0; + pAddBssParams->staContext.uAPSD = 0; + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = + (tANI_U8)pBeaconStruct->capabilityInfo.shortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + pAddBssParams->staContext.encryptType = pftSessionEntry->encryptType; +#ifdef WLAN_FEATURE_11W + pAddBssParams->staContext.rmfEnabled = pftSessionEntry->limRmfEnabled; +#endif + + if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && + ( pBeaconStruct->HTCaps.present )) { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = + ( tANI_U8 ) pBeaconStruct->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = + ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection; + if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp)) { + pAddBssParams->staContext.txChannelWidthSet = + ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; + } + else { + pAddBssParams->staContext.txChannelWidthSet = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } +#ifdef WLAN_FEATURE_11AC + if (pftSessionEntry->vhtCapability && + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + if ((pBeaconStruct->VHTCaps.suBeamFormerCap || + pBeaconStruct->VHTCaps.muBeamformerCap) && + pftSessionEntry->txBFIniFeatureEnabled) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + } +#endif + if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp)) + { + pAddBssParams->staContext.txChannelWidthSet = + (tANI_U8)pBeaconStruct->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = + pBeaconStruct->VHTOperation.chanWidth; + } +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + pAddBssParams->staContext.mimoPS = + (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = + ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = + ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = + pBeaconStruct->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = + (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz; + pAddBssParams->staContext.fShortGI20Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz; + pAddBssParams->staContext.fShortGI40Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz; + pAddBssParams->staContext.maxAmpduSize = + pBeaconStruct->HTCaps.maxRxAMPDUFactor; + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = + pBeaconStruct->HTInfo.rifsMode; + } + + if ((pftSessionEntry->limWmeEnabled && pBeaconStruct->wmeEdcaPresent) || + (pftSessionEntry->limQosEnabled && pBeaconStruct->edcaPresent)) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent; + /* For OSEN Connection AP does not advertise RSN or WPA IE + * so from the IEs we get from supplicant we get this info + * so for FW to transmit EAPOL message 4 we shall set + * wpa_rsn + */ + pAddBssParams->staContext.wpa_rsn |= (pBeaconStruct->wpaPresent << 1); + if ((!pAddBssParams->staContext.wpa_rsn) && + (pftSessionEntry->isOSENConnection)) + pAddBssParams->staContext.wpa_rsn = 1; + //Update the rates +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, + false,pftSessionEntry,&pBeaconStruct->VHTCaps); +#else + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + beaconStruct.HTCaps.supportedMCSSet, false,pftSessionEntry); +#endif + if (pftSessionEntry->htCapability) + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11n; + if (pftSessionEntry->vhtCapability) + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11ac; + } + else + { + if (pftSessionEntry->limRFBand == SIR_BAND_5_GHZ) + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11a; + } + else + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11bg; + } + } + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = + eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = + eBA_POLICY_IMMEDIATE; + } + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower; +#endif + +#ifdef WLAN_FEATURE_11W + if (pftSessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId; + pAddBssParams->staContext.smesessionId = pftSessionEntry->smeSessionId; + pAddBssParams->sessionId = pftSessionEntry->peSessionId; + + // Set a new state for MLME + + pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, pftSessionEntry->peSessionId, + eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE)); + pAddBssParams->halPersona=(tANI_U8)pftSessionEntry->pePersona; + + pftSessionEntry->ftPEContext.pAddBssReq = pAddBssParams; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..." )); +#endif + + vos_mem_free(pBeaconStruct); + return 0; +} + + +/*------------------------------------------------------------------ + * + * Setup the new session for the pre-auth AP. + * Return the newly created session entry. + * + *------------------------------------------------------------------*/ +void limFillFTSession(tpAniSirGlobal pMac, + tpSirBssDescription pbssDescription, + tpPESession pftSessionEntry, + tpPESession psessionEntry) +{ + tANI_U8 currentBssUapsd; + tPowerdBm localPowerConstraint; + tPowerdBm regMax; + tSchBeaconStruct *pBeaconStruct; + tANI_U32 selfDot11Mode; + ePhyChanBondState cbEnabledMode; + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOGE, + FL("Unable to allocate memory for creating limFillFTSession") ); +#endif + return; + } + + /* Retrieve the session that has already been created and update the entry */ +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, pbssDescription->bssId, LOG1); +#endif + pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled; + pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled; + pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled; + pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable; + pftSessionEntry->isOSENConnection = psessionEntry->isOSENConnection; + + // Fields to be filled later + pftSessionEntry->pLimJoinReq = NULL; + pftSessionEntry->smeSessionId = psessionEntry->smeSessionId; + pftSessionEntry->transactionId = 0; + + limExtractApCapabilities( pMac, + (tANI_U8 *) pbssDescription->ieFields, + limGetIElenFromBssDescription( pbssDescription ), + pBeaconStruct ); + + pftSessionEntry->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pftSessionEntry->rateSet.rate, + pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); + + pftSessionEntry->extRateSet.numRates = pBeaconStruct->extendedRates.numRates; + vos_mem_copy(pftSessionEntry->extRateSet.rate, + pBeaconStruct->extendedRates.rate, pftSessionEntry->extRateSet.numRates); + + pftSessionEntry->ssId.length = pBeaconStruct->ssId.length; + vos_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId, + pftSessionEntry->ssId.length); + + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode); + pftSessionEntry->dot11mode = selfDot11Mode; + pftSessionEntry->vhtCapability = + (IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode) + && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + pftSessionEntry->htCapability = (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) + && pBeaconStruct->HTCaps.present); +#ifdef WLAN_FEATURE_11AC + if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) && pBeaconStruct->VHTOperation.present) + { + pftSessionEntry->vhtCapabilityPresentInBeacon = 1; + pftSessionEntry->apCenterChan = + pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + pftSessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth; + } + else + { + pftSessionEntry->vhtCapabilityPresentInBeacon = 0; + } +#endif + sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr); + sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId); + sirCopyMacAddr(pftSessionEntry->prev_ap_bssid, psessionEntry->bssId); +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, pftSessionEntry->limReAssocbssId, LOG1); +#endif + + /* Store beaconInterval */ + pftSessionEntry->beaconParams.beaconInterval = + pbssDescription->beaconInterval; + pftSessionEntry->bssType = psessionEntry->bssType; + + pftSessionEntry->statypeForBss = STA_ENTRY_PEER; + pftSessionEntry->nwType = pbssDescription->nwType; + + /* Copy The channel Id to the session Table */ + pftSessionEntry->limReassocChannelId = pbssDescription->channelId; + pftSessionEntry->currentOperChannel = pbssDescription->channelId; + + if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + { + pftSessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else + { + /* Throw an error and return and make sure to delete the session.*/ + limLog(pMac, LOGE, FL("Invalid bss type")); + } + + pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo; + pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo; + if( pMac->roam.configParam.shortSlotTime && + SIR_MAC_GET_SHORT_SLOT_TIME(pftSessionEntry->limReassocBssCaps)) + { + pftSessionEntry->shortSlotTimeSupported = TRUE; + } + + regMax = cfgGetRegulatoryMaxTransmitPower(pMac, + pftSessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + limExtractApCapability( pMac, (tANI_U8 *) pbssDescription->ieFields, + limGetIElenFromBssDescription(pbssDescription), + &pftSessionEntry->limCurrentBssQosCaps, + &pftSessionEntry->limCurrentBssPropCap, + ¤tBssUapsd , &localPowerConstraint, psessionEntry); + + pftSessionEntry->limReassocBssQosCaps = + pftSessionEntry->limCurrentBssQosCaps; + pftSessionEntry->limReassocBssPropCap = + pftSessionEntry->limCurrentBssPropCap; + +#ifdef WLAN_FEATURE_VOWIFI_11R + pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection; +#endif +#ifdef FEATURE_WLAN_ESE + pftSessionEntry->isESEconnection = psessionEntry->isESEconnection; + pftSessionEntry->is_ese_version_ie_present = + pBeaconStruct->is_ese_ver_ie_present; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + pftSessionEntry->isFastTransitionEnabled = + psessionEntry->isFastTransitionEnabled; +#endif + +#ifdef FEATURE_WLAN_LFR + pftSessionEntry->isFastRoamIniFeatureEnabled = + psessionEntry->isFastRoamIniFeatureEnabled; +#endif + +#ifdef FEATURE_WLAN_ESE + pftSessionEntry->maxTxPower = + limGetMaxTxPower(regMax, localPowerConstraint, + pMac->roam.configParam.nTxPowerCap); +#else + pftSessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) ); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, + FL("Reg max = %d, local power = %d, ini tx power = %d, max tx = %d"), + regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap, + pftSessionEntry->maxTxPower); +#endif + + pftSessionEntry->limRFBand = + limGetRFBand(pftSessionEntry->currentOperChannel); + + pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; + pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, pftSessionEntry->peSessionId, + pftSessionEntry->limSmeState)); + + pftSessionEntry->encryptType = psessionEntry->encryptType; +#ifdef WLAN_FEATURE_11W + pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled; +#endif + + if (pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ) + { + cbEnabledMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + cbEnabledMode = pMac->roam.configParam.channelBondingMode5GHz; + } + pftSessionEntry->htSupportedChannelWidthSet = + (pBeaconStruct->HTInfo.present)? + (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet):0; + pftSessionEntry->htRecommendedTxWidthSet = + pftSessionEntry->htSupportedChannelWidthSet; + + vos_mem_free(pBeaconStruct); +} + +/*------------------------------------------------------------------ + * + * Setup the session and the add bss req for the pre-auth AP. + * + *------------------------------------------------------------------*/ +tSirRetStatus limFTSetupAuthSession(tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tpPESession pftSessionEntry = NULL; + tANI_U8 sessionId = 0; + + pftSessionEntry = + peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &sessionId); + if (pftSessionEntry == NULL) { + PELOGE(limLog(pMac, LOGE, + FL("Unable to find session for the following bssid"));) + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOGE); + return eSIR_FAILURE; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return eSIR_FAILURE; + } + + if (psessionEntry->ftPEContext.pFTPreAuthReq && + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { + limFillFTSession(pMac, + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription, + pftSessionEntry, + psessionEntry); + + limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry, + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription ); + } + + return eSIR_SUCCESS; +} + +/*------------------------------------------------------------------ + * Resume Link Call Back + *------------------------------------------------------------------*/ +void limFTProcessPreAuthResult(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data) +{ + tpPESession psessionEntry = (tpPESession)data; + + if (NULL == psessionEntry || + NULL == psessionEntry->ftPEContext.pFTPreAuthReq) + return; + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) { + psessionEntry->ftPEContext.ftPreAuthStatus = + limFTSetupAuthSession(pMac, psessionEntry); + } + + // Post the FT Pre Auth Response to SME + limPostFTPreAuthRsp(pMac, psessionEntry->ftPEContext.ftPreAuthStatus, + psessionEntry->ftPEContext.saved_auth_rsp, + psessionEntry->ftPEContext.saved_auth_rsp_length, psessionEntry); +} + +/*------------------------------------------------------------------ + * Resume Link Call Back + *------------------------------------------------------------------*/ +void limPerformPostFTPreAuthAndChannelChange(tpAniSirGlobal pMac, + eHalStatus status, + tANI_U32 *data, + tpPESession psessionEntry) +{ + /* Set the resume channel to Any valid channel (invalid) + * This will instruct HAL to set it to any previous valid channel. + */ + peSetResumeChannel(pMac, 0, 0); + limResumeLink(pMac, limFTProcessPreAuthResult, (tANI_U32 *)psessionEntry); +} + +/*------------------------------------------------------------------ + * + * Will post pre auth response to SME. + * + *------------------------------------------------------------------*/ +void limPostFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry) +{ + tpSirFTPreAuthRsp pFTPreAuthRsp; + tSirMsgQ mmhMsg; + tANI_U16 rspLen = sizeof(tSirFTPreAuthRsp); + + pFTPreAuthRsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rspLen); + if (NULL == pFTPreAuthRsp) { + PELOGE(limLog( pMac, LOGE, "Failed to allocate memory");) + VOS_ASSERT(pFTPreAuthRsp != NULL); + return; + } + vos_mem_zero( pFTPreAuthRsp, rspLen); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, FL("Auth Rsp = %p"), pFTPreAuthRsp);) +#endif + + if (psessionEntry) { + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + vos_mem_free(pFTPreAuthRsp); + return; + } + pFTPreAuthRsp->smeSessionId = psessionEntry->smeSessionId; + + /* The bssid of the AP we are sending Auth1 to. */ + if (psessionEntry->ftPEContext.pFTPreAuthReq) + sirCopyMacAddr(pFTPreAuthRsp->preAuthbssId, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId); + } + + pFTPreAuthRsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP; + pFTPreAuthRsp->length = (tANI_U16) rspLen; + pFTPreAuthRsp->status = status; + + /* Attach the auth response now back to SME */ + pFTPreAuthRsp->ft_ies_length = 0; + if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) { + /* Only 11r assoc has FT IEs */ + vos_mem_copy(pFTPreAuthRsp->ft_ies, auth_rsp, auth_rsp_length); + pFTPreAuthRsp->ft_ies_length = auth_rsp_length; + } + + if (status != eSIR_SUCCESS) { + /* Ensure that on Pre-Auth failure the cached Pre-Auth Req and + * other allocated memory is freed up before returning. + */ + limLog(pMac, LOG1, "Pre-Auth Failed, Cleanup!"); + limFTCleanup(pMac, psessionEntry); + } + + mmhMsg.type = pFTPreAuthRsp->messageType; + mmhMsg.bodyptr = pFTPreAuthRsp; + mmhMsg.bodyval = 0; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, + "Posted Auth Rsp to SME with status of 0x%x", status);) +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + if (status == eSIR_SUCCESS) + limDiagEventReport(pMac, WLAN_PE_DIAG_PREAUTH_DONE, psessionEntry, + status, 0); +#endif + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/*------------------------------------------------------------------ + * + * Send the FT Pre Auth Response to SME whenever we have a status + * ready to be sent to SME + * + * SME will be the one to send it up to the supplicant to receive + * FTIEs which will be required for Reassoc Req. + * + *------------------------------------------------------------------*/ +void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry) +{ + tpPESession pftSessionEntry = NULL; + tANI_U8 sessionId = 0; + tpSirBssDescription pbssDescription = NULL; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM + limDiagEventReport(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, + psessionEntry, (tANI_U16)status, 0); +#endif + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + /* Save the status of pre-auth */ + psessionEntry->ftPEContext.ftPreAuthStatus = status; + + /* Save the auth rsp, so we can send it to + * SME once we resume link + */ + psessionEntry->ftPEContext.saved_auth_rsp_length = 0; + if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) { + vos_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp, + auth_rsp, auth_rsp_length); + psessionEntry->ftPEContext.saved_auth_rsp_length = + auth_rsp_length; + } + + if (!psessionEntry->ftPEContext.pFTPreAuthReq || + !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { + limLog(pMac, LOGE, + FL("pFTPreAuthReq or pbssDescription is NULL")); + return; + } + + /* Create FT session for the re-association at this point */ + if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) { + pbssDescription = + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription; + limPrintMacAddr(pMac, pbssDescription->bssId, LOG1); + if((pftSessionEntry = + peCreateSession(pMac, pbssDescription->bssId, + &sessionId, pMac->lim.maxStation, + psessionEntry->bssType)) == NULL) { + limLog(pMac, LOGE, + FL("Session Can not be created for pre-auth 11R AP")); + return; + } + + pftSessionEntry->peSessionId = sessionId; + pftSessionEntry->smeSessionId = psessionEntry->smeSessionId; + sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr); + sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId); + pftSessionEntry->bssType = psessionEntry->bssType; + + if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) { + pftSessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) { + pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else { + limLog(pMac, LOGE, FL("Invalid bss type")); + } + pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; + vos_mem_copy(&(pftSessionEntry->htConfig), &(psessionEntry->htConfig), + sizeof(psessionEntry->htConfig)); + pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + + PELOGE(limLog(pMac, LOG1, "%s:created session (%p) with id = %d", + __func__, pftSessionEntry, pftSessionEntry->peSessionId);) + + /* Update the ReAssoc BSSID of the current session */ + sirCopyMacAddr(psessionEntry->limReAssocbssId, pbssDescription->bssId); + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG1); + } + + if (psessionEntry->currentOperChannel != + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + /* Need to move to the original AP channel */ + limChangeChannelWithCallback(pMac, psessionEntry->currentOperChannel, + limPerformPostFTPreAuthAndChannelChange, + NULL, psessionEntry); + } + else { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, + "Pre auth on same channel as connected AP channel %d", + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum);) +#endif + limFTProcessPreAuthResult(pMac, status, (tANI_U32 *)psessionEntry); + } +} + +/** + * lim_ft_reassoc_set_link_state_callback()- registered callback to perform post + * peer creation operations + * + * @mac: pointer to global mac structure + * @callback_arg: registered callback argument + * @status: peer creation status + * + * this is registered callback function during ft reassoc scenario to perform + * post peer creation operation based on the peer creation status + * + * Return: none + */ +void lim_ft_reassoc_set_link_state_callback(tpAniSirGlobal mac, + void *callback_arg, bool status) +{ + tpPESession session_entry; + tSirMsgQ msg_q; + tLimMlmReassocReq *mlm_reassoc_req = (tLimMlmReassocReq *) callback_arg; + tSirRetStatus ret_code = eSIR_SME_RESOURCES_UNAVAILABLE; + tLimMlmReassocCnf mlm_reassoc_cnf = {0}; + session_entry = peFindSessionBySessionId(mac, + mlm_reassoc_req->sessionId); + if (!status) { + limLog(mac, LOGE, FL("Failed to find pe session for session id:%d"), + mlm_reassoc_req->sessionId); + goto failure; + } + + /* + * we need to defer the message until we get the + * response back from HAL + */ + SET_LIM_PROCESS_DEFD_MESGS(mac, false); + + msg_q.type = SIR_HAL_ADD_BSS_REQ; + msg_q.reserved = 0; + msg_q.bodyptr = session_entry->ftPEContext.pAddBssReq; + msg_q.bodyval = 0; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(mac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ...")); +#endif + MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg_q.type)); + ret_code = wdaPostCtrlMsg(mac, &msg_q); + if(eSIR_SUCCESS != ret_code) { + vos_mem_free(session_entry->ftPEContext.pAddBssReq); + limLog(mac, LOGE, FL("Post ADD_BSS_REQ failed reason=%X"), + ret_code); + session_entry->ftPEContext.pAddBssReq = NULL; + goto failure; + } + + session_entry->pLimMlmReassocReq = mlm_reassoc_req; + session_entry->ftPEContext.pAddBssReq = NULL; + return; + +failure: + vos_mem_free(mlm_reassoc_req); + mlm_reassoc_cnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlm_reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE session Id*/ + mlm_reassoc_cnf.sessionId = session_entry->peSessionId; + limPostSmeMessage(mac, LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlm_reassoc_cnf); +} + +/*------------------------------------------------------------------ + * + * This function handles the 11R Reassoc Req from SME + * + *------------------------------------------------------------------*/ +void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf, + tpPESession psessionEntry) +{ + tANI_U8 smeSessionId = 0; + tANI_U16 transactionId = 0; + tANI_U8 chanNum = 0; + tLimMlmReassocReq *pMlmReassocReq; + tANI_U16 caps; + tANI_U32 val; + tANI_U32 teleBcnEn = 0; + tLimMlmReassocCnf mlm_reassoc_cnf = {0}; + + chanNum = psessionEntry->currentOperChannel; + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId); + psessionEntry->smeSessionId = smeSessionId; + psessionEntry->transactionId = transactionId; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOCIATING, psessionEntry, 0, 0); +#endif + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + if (NULL == psessionEntry->ftPEContext.pAddBssReq) { + limLog(pMac, LOGE, FL("pAddBssReq is NULL")); + goto end; + } + pMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if (NULL == pMlmReassocReq) { + limLog(pMac, LOGE, + FL("call to AllocateMemory failed for mlmReassocReq")); + goto end; + } + + vos_mem_copy(pMlmReassocReq->peerMacAddr, + psessionEntry->bssId, + sizeof(tSirMacAddr)); + + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout) + != eSIR_SUCCESS) { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve ReassocFailureTimeout value")); + vos_mem_free(pMlmReassocReq); + goto end; + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve Capabilities value")); + vos_mem_free(pMlmReassocReq); + goto end; + } + pMlmReassocReq->capabilityInfo = caps; + + /* Update PE sessionId*/ + pMlmReassocReq->sessionId = psessionEntry->peSessionId; + + /* If telescopic beaconing is enabled, set listen interval + to WNI_CFG_TELE_BCN_MAX_LI + */ + if (wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + vos_mem_free(pMlmReassocReq); + goto end; + } + + if (teleBcnEn) { + if (wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ListenInterval")); + vos_mem_free(pMlmReassocReq); + goto end; + } + } + else { + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS) { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ListenInterval")); + vos_mem_free(pMlmReassocReq); + goto end; + } + } + + pMlmReassocReq->listenInterval = (tANI_U16) val; + if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, + lim_ft_reassoc_set_link_state_callback, + pMlmReassocReq) != eSIR_SUCCESS) { + vos_mem_free(pMlmReassocReq); + goto end; + } + return; + +end: + mlm_reassoc_cnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlm_reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE session Id*/ + mlm_reassoc_cnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlm_reassoc_cnf); +} + +/*------------------------------------------------------------------ + * + * This function is called if preauth response is not received from the AP + * within this timeout while FT in progress + * + *------------------------------------------------------------------*/ +void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + + /* We have failed pre auth. We need to resume link and get back on + * home channel + */ + limLog(pMac, LOGE, FL("FT Pre-Auth Time Out!!!!")); + + if ((psessionEntry = + peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId)) == NULL) { + limLog(pMac, LOGE, FL("Session Does not exist for given sessionID")); + return; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + /* Reset the flag to indicate preauth request session */ + psessionEntry->ftPEContext.ftPreAuthSession = VOS_FALSE; + + if (NULL == + psessionEntry->ftPEContext.pFTPreAuthReq) { + limLog(pMac,LOGE,FL("pFTPreAuthReq is NULL")); + return; + } + + if (psessionEntry->ftPEContext.pFTPreAuthReq == NULL) { + limLog(pMac, LOGE, FL("Auth Rsp might already be posted to SME and " + "ftcleanup done! sessionId:%d"), + pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); + return; + } + + /* To handle the race condition where we recieve preauth rsp after + * timer has expired. + */ + if (eANI_BOOLEAN_TRUE == + psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) { + limLog(pMac,LOGE,FL("Auth rsp already posted to SME" + " (session %p)"), psessionEntry); + return; + } + else { + /* Here we are sending preauth rsp with failure state + * and which is forwarded to SME. Now, if we receive an preauth + * resp from AP with success it would create a FT pesession, but + * will be dropped in SME leaving behind the pesession. + * Mark Preauth rsp processed so that any rsp from AP is dropped in + * limProcessAuthFrameNoSession. + */ + limLog(pMac,LOG1,FL("Auth rsp not yet posted to SME" + " (session %p)"), psessionEntry); + psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = + eANI_BOOLEAN_TRUE; + } + + /* Attempted at Pre-Auth and failed. If we are off channel. We need + * to get back to home channel + */ + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); +} + + +/*------------------------------------------------------------------ + * + * This function is called to process the update key request from SME + * + *------------------------------------------------------------------*/ +tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ) +{ + tAddBssParams *pAddBssParams; + tSirFTUpdateKeyInfo *pKeyInfo; + tANI_U32 val = 0; + tpPESession psessionEntry; + tANI_U8 sessionId; + + /* Sanity Check */ + if( pMac == NULL || pMsgBuf == NULL ) + { + return VOS_FALSE; + } + + pKeyInfo = (tSirFTUpdateKeyInfo *)pMsgBuf; + + psessionEntry = + peFindSessionByBssid(pMac, pKeyInfo->bssId, &sessionId); + if (NULL == psessionEntry) + { + PELOGE(limLog( pMac, LOGE, + "%s: Unable to find session for the following bssid", + __func__);) + limPrintMacAddr( pMac, pKeyInfo->bssId, LOGE ); + return VOS_FALSE; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return VOS_FALSE; + } + + if (NULL == psessionEntry->ftPEContext.pAddBssReq) + { + // AddBss Req is NULL, save the keys to configure them later. + tpLimMlmSetKeysReq pMlmSetKeysReq = + &psessionEntry->ftPEContext.PreAuthKeyInfo.extSetStaKeyParam; + + vos_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); + vos_mem_copy(pMlmSetKeysReq->peerMacAddr, pKeyInfo->bssId, + sizeof(tSirMacAddr)); + pMlmSetKeysReq->sessionId = psessionEntry->peSessionId; + pMlmSetKeysReq->smesessionId = psessionEntry->smeSessionId; + pMlmSetKeysReq->edType = pKeyInfo->keyMaterial.edType; + pMlmSetKeysReq->numKeys = pKeyInfo->keyMaterial.numKeys; + vos_mem_copy((tANI_U8 *) &pMlmSetKeysReq->key, + (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof(tSirKeys)); + + psessionEntry->ftPEContext.PreAuthKeyInfo.extSetStaKeyParamValid = TRUE; + + limLog( pMac, LOGE, FL( "pAddBssReq is NULL" )); + + if (psessionEntry->ftPEContext.pAddStaReq == NULL) + { + limLog( pMac, LOGE, FL( "pAddStaReq is NULL" )); + limSendSetStaKeyReq(pMac, pMlmSetKeysReq, 0, 0, psessionEntry, + FALSE); + psessionEntry->ftPEContext.PreAuthKeyInfo.extSetStaKeyParamValid = + FALSE; + } + } + else + { + pAddBssParams = psessionEntry->ftPEContext.pAddBssReq; + + /* Store the key information in the ADD BSS parameters */ + pAddBssParams->extSetStaKeyParamValid = 1; + pAddBssParams->extSetStaKeyParam.encType = pKeyInfo->keyMaterial.edType; + vos_mem_copy((tANI_U8 *) &pAddBssParams->extSetStaKeyParam.key, + (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof(tSirKeys)); + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pAddBssParams->extSetStaKeyParam.singleTidRc = val; + PELOG1(limLog(pMac, LOG1, FL("Key valid %d"), + pAddBssParams->extSetStaKeyParamValid, + pAddBssParams->extSetStaKeyParam.key[0].keyLength);) + + pAddBssParams->extSetStaKeyParam.staIdx = 0; + + PELOG1(limLog(pMac, LOG1, + FL("BSSID = "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pKeyInfo->bssId));) + + sirCopyMacAddr(pAddBssParams->extSetStaKeyParam.peerMacAddr, + pKeyInfo->bssId); + + pAddBssParams->extSetStaKeyParam.sendRsp = FALSE; + + if(pAddBssParams->extSetStaKeyParam.key[0].keyLength == 16) + { + PELOG1(limLog(pMac, LOG1, + FL("BSS key = %02X-%02X-%02X-%02X-%02X-%02X-%02X- " + "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X"), + pAddBssParams->extSetStaKeyParam.key[0].key[0], + pAddBssParams->extSetStaKeyParam.key[0].key[1], + pAddBssParams->extSetStaKeyParam.key[0].key[2], + pAddBssParams->extSetStaKeyParam.key[0].key[3], + pAddBssParams->extSetStaKeyParam.key[0].key[4], + pAddBssParams->extSetStaKeyParam.key[0].key[5], + pAddBssParams->extSetStaKeyParam.key[0].key[6], + pAddBssParams->extSetStaKeyParam.key[0].key[7], + pAddBssParams->extSetStaKeyParam.key[0].key[8], + pAddBssParams->extSetStaKeyParam.key[0].key[9], + pAddBssParams->extSetStaKeyParam.key[0].key[10], + pAddBssParams->extSetStaKeyParam.key[0].key[11], + pAddBssParams->extSetStaKeyParam.key[0].key[12], + pAddBssParams->extSetStaKeyParam.key[0].key[13], + pAddBssParams->extSetStaKeyParam.key[0].key[14], + pAddBssParams->extSetStaKeyParam.key[0].key[15]);) + } + } + return TRUE; +} + +void +limFTSendAggrQosRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, + tpAggrAddTsParams aggrQosRsp, tANI_U8 smesessionId) +{ + tpSirAggrQosRsp rsp; + int i = 0; + + if (! rspReqd) + { + return; + } + + rsp = vos_mem_malloc(sizeof(tSirAggrQosRsp)); + if (NULL == rsp) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for tSirAggrQosRsp")); + return; + } + + vos_mem_set((tANI_U8 *) rsp, sizeof(*rsp), 0); + rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP; + rsp->sessionId = smesessionId; + rsp->length = sizeof(*rsp); + rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx; + + for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ ) + { + if( (1 << i) & aggrQosRsp->tspecIdx ) + { + rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i]; + rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i]; + } + } + + limSendSmeAggrQosRsp(pMac, rsp, smesessionId); + return; +} + +void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpAggrAddTsParams pAggrQosRspMsg = NULL; + tAddTsParams addTsParam = {0}; + tpDphHashNode pSta = NULL; + tANI_U16 assocId =0; + tSirMacAddr peerMacAddr; + tANI_U8 rspReqd = 1; + tpPESession psessionEntry = NULL; + int i = 0; + + PELOG1(limLog(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL"));) + + /* Need to process all the deferred messages enqueued since sending the + SIR_HAL_AGGR_ADD_TS_REQ */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr); + if (NULL == pAggrQosRspMsg) + { + PELOGE(limLog(pMac, LOGE, FL("NULL pAggrQosRspMsg"));) + return; + } + + psessionEntry = peFindSessionBySessionId(pMac, pAggrQosRspMsg->sessionId); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, + FL("Cant find session entry for %s"), __func__);) + if( pAggrQosRspMsg != NULL ) + { + vos_mem_free(pAggrQosRspMsg); + } + return; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + return; + } + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + if((((1 << i) & pAggrQosRspMsg->tspecIdx)) && + (pAggrQosRspMsg->status[i] != eHAL_STATUS_SUCCESS)) + { + /* send DELTS to the station */ + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + addTsParam.staIdx = pAggrQosRspMsg->staIdx; + addTsParam.sessionId = pAggrQosRspMsg->sessionId; + addTsParam.tspec = pAggrQosRspMsg->tspec[i]; + addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx; + + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, + &addTsParam.tspec.tsinfo, + &addTsParam.tspec, psessionEntry); + + pSta = dphLookupAssocId(pMac, addTsParam.staIdx, &assocId, + &psessionEntry->dph.dphHashTable); + if (pSta != NULL) + { + limAdmitControlDeleteTS(pMac, assocId, &addTsParam.tspec.tsinfo, + NULL, (tANI_U8 *)&addTsParam.tspecIdx); + } + } + } + + /* Send the Aggr QoS response to SME */ + limFTSendAggrQosRsp(pMac, rspReqd, pAggrQosRspMsg, + psessionEntry->smeSessionId); + if( pAggrQosRspMsg != NULL ) + { + vos_mem_free(pAggrQosRspMsg); + } + return; +} + +tSirRetStatus +limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ) +{ + tSirMsgQ msg; + tSirAggrQosReq * aggrQosReq = (tSirAggrQosReq *)pMsgBuf; + tpAggrAddTsParams pAggrAddTsParam; + tpPESession psessionEntry = NULL; + tpLimTspecInfo tspecInfo; + tANI_U8 ac; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U8 sessionId; + int i; + + pAggrAddTsParam = vos_mem_malloc(sizeof(tAggrAddTsParams)); + if (NULL == pAggrAddTsParam) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + return eSIR_MEM_ALLOC_FAILED; + } + + psessionEntry = peFindSessionByBssid(pMac, aggrQosReq->bssId, &sessionId); + + if (psessionEntry == NULL) { + PELOGE(limLog(pMac, LOGE, FL("psession Entry Null for sessionId = %d"), + aggrQosReq->sessionId);) + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + /* Nothing to be done if the session is not in STA mode */ + if (eLIM_STA_ROLE != psessionEntry->limSystemRole) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOGE, FL("psessionEntry is not in STA mode"));) +#endif + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + pSta = dphLookupHashEntry(pMac, aggrQosReq->bssId, &aid, + &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("Station context not found - ignoring AddTsRsp"));) + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + vos_mem_set((tANI_U8 *)pAggrAddTsParam, + sizeof(tAggrAddTsParams), 0); + pAggrAddTsParam->staIdx = psessionEntry->staId; + // Fill in the sessionId specific to PE + pAggrAddTsParam->sessionId = sessionId; + pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx; + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + if (aggrQosReq->aggrInfo.tspecIdx & (1<aggrInfo.aggrAddTsInfo[i].tspec; + /* Since AddTS response was successful, check for the PSB flag + * and directional flag inside the TS Info field. + * An AC is trigger enabled AC if the PSB subfield is set to 1 + * in the uplink direction. + * An AC is delivery enabled AC if the PSB subfield is set to 1 + * in the downlink direction. + * An AC is trigger and delivery enabled AC if the PSB subfield + * is set to 1 in the bi-direction field. + */ + if(!pMac->psOffloadEnabled) + { + if (pTspec->tsinfo.traffic.psb == 1) + { + limSetTspecUapsdMask(pMac, &pTspec->tsinfo, SET_UAPSD_MASK); + } + else + { + limSetTspecUapsdMask(pMac, &pTspec->tsinfo, + CLEAR_UAPSD_MASK); + } + /* + * ADDTS success, so AC is now admitted. + * We shall now use the default + * EDCA parameters as advertised by AP and + * send the updated EDCA params + * to HAL. + */ + ac = upToAc(pTspec->tsinfo.traffic.userPrio); + if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= + (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == + SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= + (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == + SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= + (1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= + (1 << ac); + } + } + else + { + if (pTspec->tsinfo.traffic.psb == 1) + { + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + &pTspec->tsinfo, + SET_UAPSD_MASK); + } + else + { + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + &pTspec->tsinfo, + CLEAR_UAPSD_MASK); + } + /* + * ADDTS success, so AC is now admitted. + * We shall now use the default + * EDCA parameters as advertised by AP and + * send the updated EDCA params + * to HAL. + */ + ac = upToAc(pTspec->tsinfo.traffic.userPrio); + if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= + (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == + SIR_MAC_DIRECTION_DNLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= + (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == + SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= + (1 << ac); + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= + (1 << ac); + } + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, + psessionEntry); + + if (pSta->aniPeer == eANI_BOOLEAN_TRUE) + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, + pSta->bssId, eANI_BOOLEAN_TRUE); + } + else + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, + pSta->bssId, eANI_BOOLEAN_FALSE); + } + + if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, + pTspec, 0, &tspecInfo)) + { + PELOGE(limLog(pMac, LOGE, + FL("Adding entry in lim Tspec Table failed "));) + pMac->lim.gLimAddtsSent = false; + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + pAggrAddTsParam->tspec[i] = + aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec; + } + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (!pMac->roam.configParam.isRoamOffloadEnabled || + (pMac->roam.configParam.isRoamOffloadEnabled && + !psessionEntry->is11Rconnection)) +#endif + { + msg.type = WDA_AGGR_QOS_REQ; + msg.bodyptr = pAggrAddTsParam; + msg.bodyval = 0; + + /* We need to defer any incoming messages until we get a + * WDA_AGGR_QOS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + else + { + /* Implies it is a LFR3.0 based 11r connection + * so donot send add ts request to fimware since it + * already has the RIC IEs */ + + /* Send the Aggr QoS response to SME */ + limFTSendAggrQosRsp(pMac, true, pAggrAddTsParam, + psessionEntry->smeSessionId); + if( pAggrAddTsParam != NULL ) + { + vos_mem_free(pAggrAddTsParam); + } + } +#endif + + return eSIR_SUCCESS; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c new file mode 100644 index 0000000000000..5c1117f1688a5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c @@ -0,0 +1,1800 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limIbssPeerMgmt.cc contains the utility functions + * LIM uses to maintain peers in IBSS. + * Author: Chandra Modumudi + * Date: 03/12/04 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "sirCommon.h" +#include "wniCfgSta.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limStaHashApi.h" +#include "schApi.h" // schSetFixedBeaconFields for IBSS coalesce +#include "limSecurityUtils.h" +#include "limSendMessages.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limIbssPeerMgmt.h" + + +/** + * ibss_peer_find + * + *FUNCTION: + * This function is called while adding a context at + * DPH & Polaris for a peer in IBSS. + * If peer is found in the list, capabilities from the + * returned BSS description are used at DPH node & Polaris. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param macAddr - MAC address of the peer + * + * @return Pointer to peer node if found, else NULL + */ + +static tLimIbssPeerNode * +ibss_peer_find( + tpAniSirGlobal pMac, + tSirMacAddr macAddr) +{ + tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList; + + while (pTempNode != NULL) + { + if (vos_mem_compare((tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr))) + break; + pTempNode = pTempNode->next; + } + return pTempNode; +} /*** end ibss_peer_find() ***/ + +/** + * ibss_peer_add + * + *FUNCTION: + * This is called on a STA in IBSS upon receiving Beacon/ + * Probe Response from a peer. + * + *LOGIC: + * Node is always added to the front of the list + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pPeerNode - Pointer to peer node to be added to the list. + * + * @return None + */ + +static tSirRetStatus +ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode) +{ +#ifdef ANI_SIR_IBSS_PEER_CACHING + tANI_U32 numIbssPeers = (2 * pMac->lim.maxStation); + + if (pMac->lim.gLimNumIbssPeers >= numIbssPeers) + { + /** + * Reached max number of peers to be maintained. + * Delete last entry & add new entry at the beginning. + */ + tLimIbssPeerNode *pTemp, *pPrev; + pTemp = pPrev = pMac->lim.gLimIbssPeerList; + while (pTemp->next != NULL) + { + pPrev = pTemp; + pTemp = pTemp->next; + } + if(pTemp->beacon) + { + vos_mem_free(pTemp->beacon); + } + + vos_mem_free(pTemp); + pPrev->next = NULL; + } + else +#endif + pMac->lim.gLimNumIbssPeers++; + + pPeerNode->next = pMac->lim.gLimIbssPeerList; + pMac->lim.gLimIbssPeerList = pPeerNode; + + return eSIR_SUCCESS; + +} /*** end limAddIbssPeerToList() ***/ + +/** + * ibss_peer_collect + * + *FUNCTION: + * This is called to collect IBSS peer information + * from received Beacon/Probe Response frame from it. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * @param pPeer - Pointer to IBSS peer node + * + * @return None + */ + +static void +ibss_peer_collect( + tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tpSirMacMgmtHdr pHdr, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ + vos_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr)); + + pPeer->capabilityInfo = pBeacon->capabilityInfo; + pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent; + pPeer->edcaPresent = pBeacon->edcaPresent; + pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent; + pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent; + + if (pBeacon->IBSSParams.present) + { + pPeer->atimIePresent = pBeacon->IBSSParams.present; + pPeer->peerAtimWindowLength = pBeacon->IBSSParams.atim; + } + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pBeacon->HTCaps.present)) + { + pPeer->htCapable = pBeacon->HTCaps.present; + vos_mem_copy((tANI_U8 *)pPeer->supportedMCSSet, + (tANI_U8 *)pBeacon->HTCaps.supportedMCSSet, + sizeof(pPeer->supportedMCSSet)); + pPeer->htGreenfield = (tANI_U8)pBeacon->HTCaps.greenField; + pPeer->htSupportedChannelWidthSet = ( tANI_U8 ) pBeacon->HTCaps.supportedChannelWidthSet; + pPeer->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pBeacon->HTCaps.mimoPowerSave; + pPeer->htMaxAmsduLength = ( tANI_U8 ) pBeacon->HTCaps.maximalAMSDUsize; + pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity; + pPeer->htDsssCckRate40MHzSupport = (tANI_U8)pBeacon->HTCaps.dsssCckMode40MHz; + pPeer->htShortGI20Mhz = (tANI_U8)pBeacon->HTCaps.shortGI20MHz; + pPeer->htShortGI40Mhz = (tANI_U8)pBeacon->HTCaps.shortGI40MHz; + pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor; + pPeer->htSecondaryChannelOffset = pBeacon->HTInfo.secondaryChannelOffset; + pPeer->htLdpcCapable = (tANI_U8)pBeacon->HTCaps.advCodingCap; + } + + /* Collect peer VHT capabilities based on the received beacon from the peer */ +#ifdef WLAN_FEATURE_11AC + if ( pBeacon->VHTCaps.present ) + { + pPeer->vhtSupportedChannelWidthSet = pBeacon->VHTOperation.chanWidth; + pPeer->vhtCapable = pBeacon->VHTCaps.present; + + // Collect VHT capabilities from beacon + vos_mem_copy((tANI_U8 *) &pPeer->VHTCaps, + (tANI_U8 *) &pBeacon->VHTCaps, + sizeof(tDot11fIEVHTCaps)); + } +#endif + pPeer->erpIePresent = pBeacon->erpPresent; + + vos_mem_copy((tANI_U8 *) &pPeer->supportedRates, + (tANI_U8 *) &pBeacon->supportedRates, + pBeacon->supportedRates.numRates + 1); + if (pPeer->extendedRatesPresent) + vos_mem_copy((tANI_U8 *) &pPeer->extendedRates, + (tANI_U8 *) &pBeacon->extendedRates, + pBeacon->extendedRates.numRates + 1); + else + pPeer->extendedRates.numRates = 0; + + pPeer->next = NULL; +} /*** end ibss_peer_collect() ***/ + +// handle change in peer qos/wme capabilities +static void +ibss_sta_caps_update( + tpAniSirGlobal pMac, + tLimIbssPeerNode *pPeerNode, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tpDphHashNode pStaDs; + + pPeerNode->beaconHBCount++; //Update beacon count. + + // if the peer node exists, update its qos capabilities + if ((pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable)) == NULL) + return; + + + //Update HT Capabilities + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable; + if (pPeerNode->htCapable) + { + pStaDs->htGreenfield = pPeerNode->htGreenfield; + pStaDs->htSupportedChannelWidthSet = pPeerNode->htSupportedChannelWidthSet; + pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState; + pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength; + pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity; + pStaDs->htDsssCckRate40MHzSupport = pPeerNode->htDsssCckRate40MHzSupport; + pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz; + pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz; + pStaDs->htMaxRxAMpduFactor = pPeerNode->htMaxRxAMpduFactor; + // In the future, may need to check for "delayedBA" + // For now, it is IMMEDIATE BA only on ALL TID's + pStaDs->baPolicyFlag = 0xFF; + pStaDs->htLdpcCapable = pPeerNode->htLdpcCapable; + } + } +#ifdef WLAN_FEATURE_11AC + if ( IS_DOT11_MODE_VHT(psessionEntry->dot11mode) ) + { + pStaDs->mlmStaContext.vhtCapability = pPeerNode->vhtCapable; + if ( pPeerNode->vhtCapable ) + { + pStaDs->vhtSupportedChannelWidthSet = pPeerNode->vhtSupportedChannelWidthSet; + + // If in 11AC mode and if session requires 11AC mode, consider peer's + // max AMPDU length factor + pStaDs->htMaxRxAMpduFactor = pPeerNode->VHTCaps.maxAMPDULenExp; + pStaDs->vhtLdpcCapable = (tANI_U8)pPeerNode->VHTCaps.ldpcCodingCap; + } + } +#endif + + // peer is 11e capable but is not 11e enabled yet + // some STA's when joining Airgo IBSS, assert qos capability even when + // they don't suport qos. however, they do not include the edca parameter + // set. so let's check for edcaParam in addition to the qos capability + if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled) && pPeerNode->edcaPresent) + { + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 0; + if (! pStaDs->lleEnabled) + { + pStaDs->lleEnabled = 1; + //dphSetACM(pMac, pStaDs); + } + return; + } + // peer is not 11e capable now but was 11e enabled earlier + else if (pStaDs->lleEnabled) + { + pStaDs->qosMode = 0; + pStaDs->lleEnabled = 0; + } + + // peer is wme capable but is not wme enabled yet + if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled) + { + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 0; + if (! pStaDs->wmeEnabled) + { + pStaDs->wmeEnabled = 1; + } + return; + } + /* When the peer device supports EDCA parameters, then we were not + considering. Added this code when we saw that one of the Peer Device + was advertising WMM param where we were not honouring that. CR# 210756 + */ + if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) { + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 0; + if (! pStaDs->wmeEnabled) { + pStaDs->wmeEnabled = 1; + } + return; + } + + // peer is not wme capable now but was wme enabled earlier + else if (pStaDs->wmeEnabled) + { + pStaDs->qosMode = 0; + pStaDs->wmeEnabled = 0; + } + +} + +static void +ibss_sta_rates_update( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ +#ifdef WLAN_FEATURE_11AC + limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates, + &pPeer->extendedRates, pPeer->supportedMCSSet, + &pStaDs->mlmStaContext.propRateSet,psessionEntry, &pPeer->VHTCaps); +#else + // Populate supported rateset + limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates, + &pPeer->extendedRates, pPeer->supportedMCSSet, + &pStaDs->mlmStaContext.propRateSet,psessionEntry); +#endif + + pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo; +} /*** end ibss_sta_info_update() ***/ + +/** + * ibss_sta_info_update + * + *FUNCTION: + * This is called to program both SW & Polaris context + * for peer in IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to DPH node + * @param pPeer - Pointer to IBSS peer node + * + * @return None + */ + +static void +ibss_sta_info_update( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ + pStaDs->staType = STA_ENTRY_PEER; + ibss_sta_caps_update(pMac, pPeer,psessionEntry); + ibss_sta_rates_update(pMac, pStaDs, pPeer,psessionEntry); +} /*** end ibss_sta_info_update() ***/ + +static void +ibss_coalesce_free( + tpAniSirGlobal pMac) +{ + if (pMac->lim.ibssInfo.pHdr != NULL) + vos_mem_free(pMac->lim.ibssInfo.pHdr); + if (pMac->lim.ibssInfo.pBeacon != NULL) + vos_mem_free(pMac->lim.ibssInfo.pBeacon); + + pMac->lim.ibssInfo.pHdr = NULL; + pMac->lim.ibssInfo.pBeacon = NULL; +} + +/* + * save the beacon params for use when adding the bss + */ +static void +ibss_coalesce_save( + tpAniSirGlobal pMac, + tpSirMacMgmtHdr pHdr, + tpSchBeaconStruct pBeacon) +{ + // get rid of any saved info + ibss_coalesce_free(pMac); + + pMac->lim.ibssInfo.pHdr = vos_mem_malloc(sizeof(*pHdr)); + if (NULL == pMac->lim.ibssInfo.pHdr) + { + PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pHdr"));) + return; + } + pMac->lim.ibssInfo.pBeacon = vos_mem_malloc(sizeof(*pBeacon)); + if (NULL == pMac->lim.ibssInfo.pBeacon) + { + PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pBeacon"));) + ibss_coalesce_free(pMac); + return; + } + + vos_mem_copy(pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr)); + vos_mem_copy(pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon)); +} + +/* + * tries to add a new entry to dph hash node + * if necessary, an existing entry is eliminated + */ +static tSirRetStatus +ibss_dph_entry_add( + tpAniSirGlobal pMac, + tSirMacAddr peerAddr, + tpDphHashNode *ppSta, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tpDphHashNode pStaDs; + + *ppSta = NULL; + + pStaDs = dphLookupHashEntry(pMac, peerAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + /* Trying to add context for already existing STA in IBSS */ + PELOGE(limLog(pMac, LOGE, FL("STA exists already "));) + limPrintMacAddr(pMac, peerAddr, LOGE); + return eSIR_FAILURE; + } + + /** + * Assign an AID, delete context existing with that + * AID and then add an entry to hash table maintained + * by DPH module. + */ + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx,psessionEntry); + } + + pStaDs = dphAddHashEntry(pMac, peerAddr, peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for peerIdx/aid=%d MACaddr:"), peerIdx);) + limPrintMacAddr(pMac, peerAddr, LOGE); + return eSIR_FAILURE; + } + + *ppSta = pStaDs; + return eSIR_SUCCESS; +} + +// send a status change notification +static void +ibss_status_chg_notify( + tpAniSirGlobal pMac, + tSirMacAddr peerAddr, + tANI_U16 staIndex, + tANI_U8 ucastSig, + tANI_U8 bcastSig, + tANI_U16 status, + tANI_U8 sessionId) +{ + + tLimIbssPeerNode *peerNode; + tANI_U8 *beacon = NULL; + tANI_U16 bcnLen = 0; + + + peerNode = ibss_peer_find(pMac,peerAddr); + if(peerNode != NULL) + { + if(peerNode->beacon == NULL) peerNode->beaconLen = 0; + beacon = peerNode->beacon; + bcnLen = peerNode->beaconLen; + peerNode->beacon = NULL; + peerNode->beaconLen = 0; + } + + limSendSmeIBSSPeerInd(pMac,peerAddr, staIndex, ucastSig, bcastSig, + beacon, bcnLen, status, sessionId); + + if(beacon != NULL) + { + vos_mem_free(beacon); + } +} + + +static void +ibss_bss_add( + tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tLimMlmStartReq mlmStartReq; + tANI_U32 cfg; + tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr; + tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon; + tANI_U8 numExtRates = 0; + + if ((pHdr == NULL) || (pBeacon == NULL)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to add BSS (no cached BSS info)"));) + return; + } + + vos_mem_copy(psessionEntry->bssId, pHdr->bssId, + sizeof(tSirMacAddr)); + + sirCopyMacAddr(pHdr->bssId,psessionEntry->bssId); + + /* Copy beacon interval from sessionTable */ + cfg = psessionEntry->beaconParams.beaconInterval; + if (cfg != pBeacon->beaconInterval) + psessionEntry->beaconParams.beaconInterval = pBeacon->beaconInterval; + + /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to + * adapt to peer's capability with respect to short slot time. Changes have been made to limApplyConfiguration() + * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt + * to peer's short slot using code below. + */ + /* If cfg is already set to current peer's capability then no need to set it again */ + if (psessionEntry->shortSlotTimeSupported != pBeacon->capabilityInfo.shortSlotTime) + { + psessionEntry->shortSlotTimeSupported = pBeacon->capabilityInfo.shortSlotTime; + } + vos_mem_copy((tANI_U8 *) &psessionEntry->pLimStartBssReq->operationalRateSet, + (tANI_U8 *) &pBeacon->supportedRates, + pBeacon->supportedRates.numRates); + + /** + * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when + * there is no extended rate IE present in beacon. This is especially important when + * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce. + * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to + * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile. + * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued. + * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12. + */ + + if(pBeacon->extendedRatesPresent) + numExtRates = pBeacon->extendedRates.numRates; + if (cfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pBeacon->extendedRates.rate, numExtRates) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not update ExtendedOperRateset at CFG")); + return; + } + + + /* + * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities + * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities + * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode + * even though all the nodes are capable of doing CB. + * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop. + */ + vos_mem_set((void *) &mlmStartReq, sizeof(mlmStartReq), 0); + + vos_mem_copy(mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr)); + mlmStartReq.rateSet.numRates = psessionEntry->pLimStartBssReq->operationalRateSet.numRates; + vos_mem_copy(&mlmStartReq.rateSet.rate[0], + &psessionEntry->pLimStartBssReq->operationalRateSet.rate[0], + mlmStartReq.rateSet.numRates); + mlmStartReq.bssType = eSIR_IBSS_MODE; + mlmStartReq.beaconPeriod = pBeacon->beaconInterval; + mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; //psessionEntry->nwType is also OK???? + mlmStartReq.htCapable = psessionEntry->htCapability; + mlmStartReq.htOperMode = pMac->lim.gHTOperMode; + mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection; + mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet; + + /* reading the channel num from session Table */ + mlmStartReq.channelNumber = psessionEntry->currentOperChannel; + + mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode; + + // Copy the SSID for RxP filtering based on SSID. + vos_mem_copy((tANI_U8 *) &mlmStartReq.ssId, + (tANI_U8 *) &psessionEntry->pLimStartBssReq->ssId, + psessionEntry->pLimStartBssReq->ssId.length + 1); + + PELOG1(limLog(pMac, LOG1, FL("invoking ADD_BSS as part of coalescing!"));) + if (limMlmAddBss(pMac, &mlmStartReq,psessionEntry) != eSIR_SME_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("AddBss failure"));) + return; + } + + // Update fields in Beacon + if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("*** Unable to set fixed Beacon fields ***"));) + return; + } + +} + + + +/* delete the current BSS */ +static void +ibss_bss_delete( + tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tSirRetStatus status; + PELOGW(limLog(pMac, LOGW, FL("Initiating IBSS Delete BSS"));) + if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) + { + limLog(pMac, LOGW, FL("Incorrect LIM MLM state for delBss (%d)"), + psessionEntry->limMlmState); + return; + } + status = limDelBss(pMac, NULL, psessionEntry->bssIdx, psessionEntry); + if (status != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d"), psessionEntry->bssIdx);) +} + +/** + * limIbssInit + * + *FUNCTION: + * This function is called while starting an IBSS + * to initialize list used to maintain IBSS peers. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limIbssInit( + tpAniSirGlobal pMac) +{ + pMac->lim.gLimIbssCoalescingHappened = 0; + pMac->lim.gLimIbssPeerList = NULL; + pMac->lim.gLimNumIbssPeers = 0; + + // ibss info - params for which ibss to join while coalescing + vos_mem_set(&pMac->lim.ibssInfo, sizeof(tAniSirLimIbss), 0); +} /*** end limIbssInit() ***/ + +/** + * limIbssDeleteAllPeers + * + *FUNCTION: + * This function is called to delete all peers. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limIbssDeleteAllPeers( tpAniSirGlobal pMac ,tpPESession psessionEntry) +{ + tLimIbssPeerNode *pCurrNode, *pTempNode; + tpDphHashNode pStaDs; + tANI_U16 peerIdx; + + pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList; + + while (pCurrNode != NULL) + { + if (!pMac->lim.gLimNumIbssPeers) + { + limLog(pMac, LOGP, + FL("Number of peers in the list is zero and node present")); + return; + } + /* Delete the dph entry for the station + * Since it is called to remove all peers, just delete from dph, + * no need to do any beacon related params i.e., dont call limDeleteDphHashEntry + */ + pStaDs = dphLookupHashEntry(pMac, pCurrNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if( pStaDs ) + { + + ibss_status_chg_notify( pMac, pCurrNode->peerMacAddr, pStaDs->staIndex, + pStaDs->ucUcastSig, pStaDs->ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, psessionEntry->smeSessionId ); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + dphDeleteHashEntry(pMac, pStaDs->staAddr, peerIdx, &psessionEntry->dph.dphHashTable); + } + + pTempNode = pCurrNode->next; + + /* TODO :Sessionize this code */ + /* Fix CR 227642: PeerList should point to the next node since the current node is being + * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this + * peer list to find the next peer. So this list needs to be updated with the no of peers left + * after each iteration in this while loop since one by one peers are deleted (freed) in this + * loop causing the lim.gLimIbssPeerList to point to some freed memory. + */ + pMac->lim.gLimIbssPeerList = pTempNode; + + if(pCurrNode->beacon) + { + vos_mem_free(pCurrNode->beacon); + } + vos_mem_free(pCurrNode); + if (pMac->lim.gLimNumIbssPeers > 0) // be paranoid + pMac->lim.gLimNumIbssPeers--; + pCurrNode = pTempNode; + } + + if (pMac->lim.gLimNumIbssPeers) + limLog(pMac, LOGP, FL("Number of peers[%d] in the list is non-zero"), + pMac->lim.gLimNumIbssPeers); + + pMac->lim.gLimNumIbssPeers = 0; + pMac->lim.gLimIbssPeerList = NULL; + +} +/** + * limIbssDelete + * + *FUNCTION: + * This function is called while tearing down an IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limIbssDelete( + tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + limIbssDeleteAllPeers(pMac,psessionEntry); + + ibss_coalesce_free(pMac); +} /*** end limIbssDelete() ***/ + +/** ------------------------------------------------------------- +\fn limIbssSetProtection +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssSetProtection(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + + if(!pMac->lim.cfgProtection.fromllb) + { + PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled"));) + return; + } + + if (enable) + { + psessionEntry->gLim11bParams.protectionEnabled = true; + if(false == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/) + { + PELOGE(limLog(pMac, LOGE, FL("=> IBSS: Enable Protection "));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/) + { + psessionEntry->gLim11bParams.protectionEnabled = false; + PELOGE(limLog(pMac, LOGE, FL("===> IBSS: Disable protection "));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + return; +} + + +/** ------------------------------------------------------------- +\fn limIbssUpdateProtectionParams +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssUpdateProtectionParams(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType, + tpPESession psessionEntry) +{ + tANI_U32 i; + + PELOG1(limLog(pMac,LOG1, FL("A STA is associated:")); + limLog(pMac,LOG1, FL("Addr : ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + + for (i=0; ilim.protStaCache[i].active) + { + PELOG1(limLog(pMac, LOG1, FL("Addr: "));) + PELOG1(limPrintMacAddr(pMac, pMac->lim.protStaCache[i].addr, LOG1);) + + if (vos_mem_compare(pMac->lim.protStaCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + { + PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active."), i);) + return; + } + } + } + + for (i=0; ilim.protStaCache[i].active) + break; + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache"));) + return; + } + + vos_mem_copy(pMac->lim.protStaCache[i].addr, + peerMacAddr, + sizeof(tSirMacAddr)); + + pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType; + pMac->lim.protStaCache[i].active = true; + if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) + { + psessionEntry->gLim11bParams.numSta++; + } + else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) + { + psessionEntry->gLim11gParams.numSta++; + } +} + + +/** ------------------------------------------------------------- +\fn limIbssDecideProtection +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssDecideProtection(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode; + tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; + + pBeaconParams->paramChangeBitmap = 0; + + if(NULL == pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("pStaDs is NULL"));) + return; + } + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ== rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //We are 11G or 11n. Check if we need protection from 11b Stations. + if ((phyMode == WNI_CFG_PHY_MODE_11G) || (psessionEntry->htCapability)) + { + /* As we found in the past, it is possible that a 11n STA sends + * Beacon with HT IE but not ERP IE. So the absense of ERP IE + * in the Beacon is not enough to conclude that STA is 11b. + */ + if ((pStaDs->erpEnabled == eHAL_CLEAR) && + (!pStaDs->mlmStaContext.htCapability)) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + PELOGE(limLog(pMac, LOGE, FL("Enable protection from 11B"));) + limIbssSetProtection(pMac, true, pBeaconParams,psessionEntry); + } + } + } + limIbssUpdateProtectionParams(pMac, pStaDs->staAddr, protStaCacheType, psessionEntry); + return; +} + +/** + * limIbssPeerFind() + * + *FUNCTION: + * This function is called while adding a context at + * DPH & Polaris for a peer in IBSS. + * If peer is found in the list, capabilities from the + * returned BSS description are used at DPH node & Polaris. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param macAddr - MAC address of the peer + * + * @return Pointer to peer node if found, else NULL + */ +tLimIbssPeerNode* limIbssPeerFind(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + return ibss_peer_find(pMac, macAddr); +} + +/** + * limIbssStaAdd() + * + *FUNCTION: + * This function is called to add an STA context in IBSS role + * whenever a data frame is received from/for a STA that failed + * hash lookup at DPH. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * @return retCode Indicates success or failure return code + * @return + */ + +tSirRetStatus +limIbssStaAdd( + tpAniSirGlobal pMac, + void *pBody, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tpDphHashNode pStaDs; + tLimIbssPeerNode *pPeerNode; + tLimMlmStates prevState; + tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody; + tUpdateBeaconParams beaconParams; + + vos_mem_set((tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams), 0); + + if (pBody == 0) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid IBSS AddSta"));) + return eSIR_FAILURE; + } + + PELOGE(limLog(pMac, LOGE, FL("Rx Add-Ibss-Sta for MAC:"));) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + + pPeerNode = ibss_peer_find(pMac, *pPeerAddr); + if (NULL != pPeerNode) + { + retCode = ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs, psessionEntry); + if (eSIR_SUCCESS == retCode) + { + prevState = pStaDs->mlmStaContext.mlmState; + pStaDs->erpEnabled = pPeerNode->erpIePresent; + + ibss_sta_info_update(pMac, pStaDs, pPeerNode, psessionEntry); + PELOGW(limLog(pMac, LOGW, FL("initiating ADD STA for the IBSS peer."));) + retCode = limAddSta(pMac, pStaDs, false, psessionEntry); + if (retCode != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("ibss-sta-add failed (reason %x)"), + retCode);) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + pStaDs->mlmStaContext.mlmState = prevState; + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, + &psessionEntry->dph.dphHashTable); + } + else + { + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limIbssDecideProtection(pMac, pStaDs, &beaconParams , psessionEntry); + + if(beaconParams.paramChangeBitmap) + { + PELOGE(limLog(pMac, LOGE, FL("---> Update Beacon Params "));) + schSetFixedBeaconFields(pMac, psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("hashTblAdd failed (reason %x)"), retCode);) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + } + } + else + { + retCode = eSIR_FAILURE; + } + + return retCode; +} + +/* handle the response from HAL for an ADD STA request */ +tSirRetStatus +limIbssAddStaRsp( + tpAniSirGlobal pMac, + void *msg,tpPESession psessionEntry) +{ + tpDphHashNode pStaDs; + tANI_U16 peerIdx; + tpAddStaParams pAddStaParams = (tpAddStaParams) msg; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pAddStaParams == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP with no body!"));) + return eSIR_FAILURE; + } + + pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP for unknown MAC addr "));) + limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE); + vos_mem_free(pAddStaParams); + return eSIR_FAILURE; + } + + if (pAddStaParams->status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP error (%x) "), pAddStaParams->status);) + limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE); + vos_mem_free(pAddStaParams); + return eSIR_FAILURE; + } + + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + pStaDs->ucUcastSig = pAddStaParams->ucUcastSig; + pStaDs->ucBcastSig = pAddStaParams->ucBcastSig; + pStaDs->valid = 1; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + + PELOGW(limLog(pMac, LOGW, FL("IBSS: sending IBSS_NEW_PEER msg to SME!"));) + + ibss_status_chg_notify(pMac, pAddStaParams->staMac, pStaDs->staIndex, + pStaDs->ucUcastSig, pStaDs->ucBcastSig, + eWNI_SME_IBSS_NEW_PEER_IND, + psessionEntry->smeSessionId); + + vos_mem_free(pAddStaParams); + + return eSIR_SUCCESS; +} + + + +void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; + + PELOGW(limLog(pMac, LOGW, FL("IBSS: DEL_BSS_RSP Rcvd during coalescing!"));) + + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) with no body!"));) + goto end; + } + + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx); + goto end; + } + //Delete peer entries. + limIbssDeleteAllPeers(pMac,psessionEntry); + + /* add the new bss */ + ibss_bss_add(pMac,psessionEntry); + + end: + if(pDelBss != NULL) + vos_mem_free(pDelBss); +} + + + +void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg, tpPESession pSessionEntry) +{ + tANI_U8 infoLen; + tSirSmeNewBssInfo newBssInfo; + + tpAddBssParams pAddBss = (tpAddBssParams) msg; + + tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr; + tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon; + + if ((pHdr == NULL) || (pBeacon == NULL)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)"));) + goto end; + } + + // Inform Host of IBSS coalescing + infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) + + sizeof(tANI_U8) + pBeacon->ssId.length + 1; + + vos_mem_set((void *) &newBssInfo, sizeof(newBssInfo), 0); + vos_mem_copy(newBssInfo.bssId, pHdr->bssId, sizeof(tSirMacAddr)); + newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel; + vos_mem_copy((tANI_U8 *) &newBssInfo.ssId, + (tANI_U8 *) &pBeacon->ssId, pBeacon->ssId.length + 1); + + PELOGW(limLog(pMac, LOGW, FL("Sending JOINED_NEW_BSS notification to SME."));) + + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_JOINED_NEW_BSS, + (tANI_U32 *) &newBssInfo, + infoLen,pSessionEntry->smeSessionId); + { + //Configure beacon and send beacons to HAL + limSendBeaconInd(pMac, pSessionEntry); + } + + end: + ibss_coalesce_free(pMac); +} + + + +void +limIbssDelBssRsp( + tpAniSirGlobal pMac, + void *msg,tpPESession psessionEntry) +{ + tSirResultCodes rc = eSIR_SME_SUCCESS; + tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP with no body!"));) + rc = eSIR_SME_REFUSED; + goto end; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + goto end; + } + + + /* + * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true. + * BSS has to be added again in this scenario, so this case needs to be handled separately. + * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to + * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME. + */ + if(true == pMac->lim.gLimIbssCoalescingHappened) + { + + limIbssDelBssRspWhenCoalescing(pMac,msg,psessionEntry); + return; + } + + + + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx);) + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + + + + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP setLinkState failed"));) + rc = eSIR_SME_REFUSED; + goto end; + } + + limIbssDelete(pMac,psessionEntry); + + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable); + limDeletePreAuthList(pMac); + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + psessionEntry->limSystemRole = eLIM_STA_ROLE; + + /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra + * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from limApplyConfiguration + */ + psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF; + + end: + if(pDelBss != NULL) + vos_mem_free(pDelBss); + /* Delete PE session once BSS is deleted */ + if (NULL != psessionEntry) { + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,psessionEntry->smeSessionId,psessionEntry->transactionId); + peDeleteSession(pMac, psessionEntry); + psessionEntry = NULL; + } +} + +static void +__limIbssSearchAndDeletePeer(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr macAddr) +{ + tLimIbssPeerNode *pTempNode, *pPrevNode; + tLimIbssPeerNode *pTempNextNode = NULL; + tpDphHashNode pStaDs=NULL; + tANI_U16 peerIdx=0; + tANI_U16 staIndex=0; + tANI_U8 ucUcastSig; + tANI_U8 ucBcastSig; + + pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList; + + limLog(pMac, LOG1, FL(" PEER ADDR :" MAC_ADDRESS_STR ),MAC_ADDR_ARRAY(macAddr)); + + /** Compare Peer */ + while (NULL != pTempNode) + { + pTempNextNode = pTempNode->next; + + /* Delete the STA with MAC address */ + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + pStaDs = dphLookupHashEntry(pMac, macAddr, + &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + staIndex = pStaDs->staIndex; + ucUcastSig = pStaDs->ucUcastSig; + ucBcastSig = pStaDs->ucBcastSig; + + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx, psessionEntry); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + /* Send indication to upper layers */ + ibss_status_chg_notify(pMac, macAddr, staIndex, + ucUcastSig, ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + psessionEntry->smeSessionId ); + if (pTempNode == pMac->lim.gLimIbssPeerList) + { + pMac->lim.gLimIbssPeerList = pTempNode->next; + pPrevNode = pMac->lim.gLimIbssPeerList; + } + else + pPrevNode->next = pTempNode->next; + + vos_mem_free(pTempNode); + pMac->lim.gLimNumIbssPeers--; + + pTempNode = pTempNextNode; + break; + } + } + pPrevNode = pTempNode; + pTempNode = pTempNextNode; + } + /* + * if it is the last peer walking out, we better + * we set IBSS state to inactive. + */ + if (0 == pMac->lim.gLimNumIbssPeers) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Last STA from IBSS walked out"); + psessionEntry->limIbssActive = false; + } +} + +/** + * limIbssCoalesce() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * + * @return Status whether to process or ignore received Beacon Frame + */ + +tSirRetStatus +limIbssCoalesce( + tpAniSirGlobal pMac, + tpSirMacMgmtHdr pHdr, + tpSchBeaconStruct pBeacon, + tANI_U8 *pIEs, + tANI_U32 ieLen, + tANI_U16 fTsfLater, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tSirMacAddr currentBssId; + tLimIbssPeerNode *pPeerNode; + tpDphHashNode pStaDs; + tUpdateBeaconParams beaconParams; + + vos_mem_set((tANI_U8 *)&beaconParams, sizeof(tUpdateBeaconParams), 0); + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + limLog(pMac, LOG1, FL("Current BSSID :" MAC_ADDRESS_STR " Received BSSID :" MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(currentBssId), MAC_ADDR_ARRAY(pHdr->bssId)); + + /* Check for IBSS Coalescing only if Beacon is from different BSS */ + if ( !vos_mem_compare(currentBssId, pHdr->bssId, sizeof( tSirMacAddr )) + && psessionEntry->isCoalesingInIBSSAllowed) + { + /* + * If STA entry is already available in the LIM hash table, then it is + * possible that the peer may have left and rejoined within the heartbeat + * timeout. In the offloaded case with 32 peers, the HB timeout is whopping + * 128 seconds. In that case, the FW will not let any frames come in until + * atleast the last sequence number is received before the peer is left + * Hence, if the coalescing peer is already there in the peer list and if + * the BSSID matches then, invoke delSta() to cleanup the entries. We will + * let the peer coalesce when we receive next beacon from the peer + */ + pPeerNode = ibss_peer_find(pMac, pHdr->sa); + if (NULL != pPeerNode) + { + __limIbssSearchAndDeletePeer (pMac, psessionEntry, pHdr->sa); + PELOGW(limLog(pMac, LOGW, + FL("** Peer attempting to reconnect before HB timeout, deleted **"));) + return eSIR_LIM_IGNORE_BEACON; + } + + if (! fTsfLater) // No Coalescing happened. + { + PELOGW(limLog(pMac, LOGW, FL("No Coalescing happened"));) + return eSIR_LIM_IGNORE_BEACON; + } + /* + * IBSS Coalescing happened. + * save the received beacon, and delete the current BSS. The rest of the + * processing will be done in the delBss response processing + */ + pMac->lim.gLimIbssCoalescingHappened = true; + PELOGW(limLog(pMac, LOGW, FL("IBSS Coalescing happened"));) + ibss_coalesce_save(pMac, pHdr, pBeacon); + limLog(pMac, LOGW, FL("Delete BSSID :" MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(currentBssId)); + ibss_bss_delete(pMac,psessionEntry); + return eSIR_SUCCESS; + } + else + { + if (!vos_mem_compare(currentBssId, pHdr->bssId, sizeof( tSirMacAddr ))) + return eSIR_LIM_IGNORE_BEACON; + } + + + // STA in IBSS mode and SSID matches with ours + pPeerNode = ibss_peer_find(pMac, pHdr->sa); + if (pPeerNode == NULL) + { + /* Peer not in the list - Collect BSS description & add to the list */ + tANI_U32 frameLen; + tSirRetStatus retCode; + + /* + * Limit the Max number of IBSS Peers allowed as the max + * number of STA's allowed + * pMac->lim.gLimNumIbssPeers will be increamented after exiting + * this function. so we will add additional 1 to compare against + * pMac->lim.gLimIbssStaLimit + */ + if ((pMac->lim.gLimNumIbssPeers+1) >= pMac->lim.gLimIbssStaLimit) + { + PELOGE(limLog(pMac, LOGE, FL("**** MAX STA LIMIT HAS REACHED ****"));) + return eSIR_LIM_MAX_STA_REACHED_ERROR; + } + PELOGW(limLog(pMac, LOGW, FL("IBSS Peer node does not exist, adding it***"));) + frameLen = sizeof(tLimIbssPeerNode) + ieLen - sizeof(tANI_U32); + + pPeerNode = vos_mem_malloc((tANI_U16)frameLen); + if (NULL == pPeerNode) + { + limLog(pMac, LOGP, FL("alloc fail (%d bytes) storing IBSS peer info"), + frameLen); + return eSIR_MEM_ALLOC_FAILED; + } + + pPeerNode->beacon = NULL; + pPeerNode->beaconLen = 0; + + ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,psessionEntry); + pPeerNode->beacon = vos_mem_malloc(ieLen); + if (NULL == pPeerNode->beacon) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));) + } + else + { + vos_mem_copy(pPeerNode->beacon, pIEs, ieLen); + pPeerNode->beaconLen = (tANI_U16)ieLen; + } + ibss_peer_add(pMac, pPeerNode); + + pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + /// DPH node already exists for the peer + PELOGW(limLog(pMac, LOGW, FL("DPH Node present for just learned peer"));) + PELOG1(limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOG1);) + ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry); + return eSIR_SUCCESS; + } + retCode = limIbssStaAdd(pMac, pPeerNode->peerMacAddr,psessionEntry); + if (retCode != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("lim-ibss-sta-add failed (reason %x)"), retCode);) + limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOGE); + return retCode; + } + + // Decide protection mode + pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limIbssDecideProtection(pMac, pStaDs, &beaconParams, psessionEntry); + + if(beaconParams.paramChangeBitmap) + { + PELOGE(limLog(pMac, LOGE, FL("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params "));) + schSetFixedBeaconFields(pMac, psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + } + else + ibss_sta_caps_update(pMac, pPeerNode,psessionEntry); + + if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) + return eSIR_SUCCESS; + + // Received Beacon from same IBSS we're + // currently part of. Inform Roaming algorithm + // if not already that IBSS is active. + if (psessionEntry->limIbssActive == false) + { + limResetHBPktCount(psessionEntry); + PELOGW(limLog(pMac, LOGW, FL("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME"));) + psessionEntry->limIbssActive = true; + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0, psessionEntry->smeSessionId); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + } + + return eSIR_SUCCESS; +} /*** end limHandleIBSScoalescing() ***/ + + +void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tLimIbssPeerNode *pTempNode, *pPrevNode; + tLimIbssPeerNode *pTempNextNode = NULL; + tANI_U16 peerIdx=0; + tpDphHashNode pStaDs=0; + tANI_U32 threshold=0; + tANI_U16 staIndex=0; + tANI_U8 ucUcastSig=0; + tANI_U8 ucBcastSig=0; + + /** MLM BSS is started and if PE in scanmode then MLM state will be waiting for probe resp. + * If Heart beat timeout triggers during this corner case then we need to reactivate HeartBeat timer + */ + if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) { + /****** + * Note: Use this code once you have converted all + * limReactivateHeartBeatTimer() calls to + * limReactivateTimer() calls. + * + ******/ + limReactivateHeartBeatTimer(pMac, psessionEntry); + return; + } + /** If LinkMonitor is Disabled */ + if(!pMac->sys.gSysEnableLinkMonitorMode) + return; + + pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList; + threshold = (pMac->lim.gLimNumIbssPeers / 4 ) + 1; + + /** Monitor the HeartBeat with the Individual PEERS in the IBSS */ + while (pTempNode != NULL) + { + pTempNextNode = pTempNode->next; + if(pTempNode->beaconHBCount) //There was a beacon for this peer during heart beat. + { + pTempNode->beaconHBCount = 0; + pTempNode->heartbeatFailure = 0; + } + else //There wasnt any beacon received during heartbeat timer. + { + pTempNode->heartbeatFailure++; + PELOGE(limLog(pMac, LOGE, FL("Heartbeat fail = %d thres = %d"), pTempNode->heartbeatFailure, pMac->lim.gLimNumIbssPeers);) + if(pTempNode->heartbeatFailure >= threshold ) + { + //Remove this entry from the list. + pStaDs = dphLookupHashEntry(pMac, pTempNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + staIndex = pStaDs->staIndex; + ucUcastSig = pStaDs->ucUcastSig; + ucBcastSig = pStaDs->ucBcastSig; + + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx,psessionEntry); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + //Send indication. + ibss_status_chg_notify( pMac, pTempNode->peerMacAddr, staIndex, + ucUcastSig, ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + psessionEntry->smeSessionId ); + } + if(pTempNode == pMac->lim.gLimIbssPeerList) + { + pMac->lim.gLimIbssPeerList = pTempNode->next; + pPrevNode = pMac->lim.gLimIbssPeerList; + } + else + pPrevNode->next = pTempNode->next; + + vos_mem_free(pTempNode); + pMac->lim.gLimNumIbssPeers--; + + pTempNode = pTempNextNode; //Since we deleted current node, prevNode remains same. + continue; + } + } + + pPrevNode = pTempNode; + pTempNode = pTempNextNode; + } + + /** General IBSS Activity Monitor, check if in IBSS Mode we are received any Beacons */ + if(pMac->lim.gLimNumIbssPeers) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + + limReactivateHeartBeatTimer(pMac, psessionEntry); + + // Reset number of beacons received + limResetHBPktCount(psessionEntry); + return; + } + else + { + + PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure"));) + pMac->lim.gLimHBfailureCntInLinkEstState++; + + if (psessionEntry->limIbssActive == true) + { + // We don't receive Beacon frames from any + // other STA in IBSS. Announce IBSS inactive + // to Roaming algorithm + PELOGW(limLog(pMac, LOGW, FL("Alone in IBSS"));) + psessionEntry->limIbssActive = false; + + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_INACTIVE, + NULL, 0, psessionEntry->smeSessionId); + } + } +} + + +/** ------------------------------------------------------------- +\fn limIbssDecideProtectionOnDelete +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 phyMode; + tHalBitVal erpEnabled = eHAL_CLEAR; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 i; + + if(NULL == pStaDs) + return; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ == rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + erpEnabled = pStaDs->erpEnabled; + //we are HT or 11G and 11B station is getting deleted. + if ( ((phyMode == WNI_CFG_PHY_MODE_11G) || psessionEntry->htCapability) + && (erpEnabled == eHAL_CLEAR)) + { + PELOGE(limLog(pMac, LOGE, FL("(%d) A legacy STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOGE);) + if (psessionEntry->gLim11bParams.numSta > 0) + { + for (i=0; ilim.protStaCache[i].active) + { + if (vos_mem_compare(pMac->lim.protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11bParams.numSta--; + pMac->lim.protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11bParams.numSta == 0) + { + PELOGE(limLog(pMac, LOGE, FL("No more 11B STA exists. Disable protection. "));) + limIbssSetProtection(pMac, false, pBeaconParams,psessionEntry); + } + } + } +} + +/** ----------------------------------------------------------------- +\fn __limIbssPeerInactivityHandler +\brief Internal function. Deletes FW indicated peer which is inactive +\ +\param tpAniSirGlobal pMac +\param tpPESession psessionEntry +\param tpSirIbssPeerInactivityInd peerInactivityInd +\return None + -----------------------------------------------------------------*/ +static void +__limIbssPeerInactivityHandler(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSirIbssPeerInactivityInd peerInactivityInd) +{ + if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + return; + } + + /* delete the peer for which heartbeat is observed */ + __limIbssSearchAndDeletePeer (pMac, psessionEntry, peerInactivityInd->peerAddr); + +} + +/** ------------------------------------------------------------- +\fn limProcessIbssPeerInactivity +\brief Peer inactivity message handler +\ +\param tpAniSirGlobal pMac +\param void* buf +\return None + -------------------------------------------------------------*/ +void +limProcessIbssPeerInactivity(tpAniSirGlobal pMac, void *buf) +{ + /* + * --------------- HEARTBEAT OFFLOAD CASE ------------------ + * This message handler is executed when the firmware identifies + * inactivity from one or more peer devices. We will come here + * for every inactive peer device + */ + tANI_U8 i; + + tSirIbssPeerInactivityInd *peerInactivityInd = + (tSirIbssPeerInactivityInd *) buf; + + /* + * If IBSS is not started or heartbeat offload is not enabled + * we should not handle this request + */ + if (eLIM_STA_IN_IBSS_ROLE != pMac->lim.gLimSystemRole && + !IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + return; + } + + /** If LinkMonitor is Disabled */ + if (!pMac->sys.gSysEnableLinkMonitorMode) + { + return; + } + + for (i = 0; i < pMac->lim.maxBssId; i++) + { + if (VOS_TRUE == pMac->lim.gpSession[i].valid && + eSIR_IBSS_MODE == pMac->lim.gpSession[i].bssType) + { + __limIbssPeerInactivityHandler(pMac, + &pMac->lim.gpSession[i], + peerInactivityInd); + break; + } + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h new file mode 100644 index 0000000000000..4b075a2758ba7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limIbssPeerMgmt.h contains prototypes for + * the utility functions LIM uses to maintain peers in IBSS. + * Author: Chandra Modumudi + * Date: 03/12/04 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "sirCommon.h" +#include "limUtils.h" + +#define IBSS_STATIONS_USED_DURING_INIT 4 //(broadcast + self + p2p + softap) + +void limIbssInit(tpAniSirGlobal); +void limIbssDelete(tpAniSirGlobal,tpPESession psessionEntry); +tSirRetStatus limIbssCoalesce(tpAniSirGlobal, tpSirMacMgmtHdr, tpSchBeaconStruct, tANI_U8*,tANI_U32, tANI_U16,tpPESession); +tSirRetStatus limIbssStaAdd(tpAniSirGlobal, void *,tpPESession); +tSirRetStatus limIbssAddStaRsp( tpAniSirGlobal, void *,tpPESession); +tLimIbssPeerNode* limIbssPeerFind(tpAniSirGlobal pMac, tSirMacAddr macAddr); +void limIbssDelBssRsp( tpAniSirGlobal, void *,tpPESession); +void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal, void *,tpPESession); +void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void * msg, tpPESession pSessionEntry); +void limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession pSessionEntry); +void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry); +void limProcessIbssPeerInactivity(tpAniSirGlobal pMac, void *buf); diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c new file mode 100644 index 0000000000000..50f68dc198e1b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limLinkMonitoringAlgo.cc contains the code for + * Link monitoring algorithm on AP and heart beat failure + * handling on STA. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "aniGlobal.h" +#include "wniCfgSta.h" +#include "cfgApi.h" + + +#include "schApi.h" +#include "pmmApi.h" +#include "utilsApi.h" +#include "limAssocUtils.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limPropExtsUtils.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limSerDesUtils.h" + + +/** + * limSendKeepAliveToPeer() + * + *FUNCTION: + * This function is called to send Keep alive message to peer + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSendKeepAliveToPeer(tpAniSirGlobal pMac) +{ + +} /*** limSendKeepAliveToPeer() ***/ + + +/** --------------------------------------------------------- +\fn limDeleteStaContext +\brief This function handles the message from HAL: +\ WDA_DELETE_STA_CONTEXT_IND. This function +\ validates that the given station id exist, and if so, +\ deletes the station by calling limTriggerSTAdeletion. +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +\return none + -----------------------------------------------------------*/ +void +limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpDeleteStaContext pMsg = (tpDeleteStaContext)limMsg->bodyptr; + tpDphHashNode pStaDs; + tpPESession psessionEntry ; + + if(NULL == pMsg) + { + PELOGE(limLog(pMac, LOGE,FL("Invalid body pointer in message"));) + return; + } + psessionEntry = pe_find_session_by_sme_session_id(pMac, pMsg->vdev_id); + if(NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("session not found for given sme session")); + vos_mem_free(pMsg); + return; + } + + switch(pMsg->reasonCode) + { + case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE: + if (LIM_IS_STA_ROLE(psessionEntry) && !pMsg->is_tdls) { + pStaDs = dphGetHashEntry(pMac, + DPH_STA_HASH_INDEX_PEER, + &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) { + limLog(pMac, LOGE, FL("Dph entry not found.")); + vos_mem_free(pMsg); + return; + } + limSendDeauthMgmtFrame(pMac, + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON, + pMsg->addr2, psessionEntry, FALSE); + limTearDownLinkWithAp(pMac, psessionEntry->peSessionId, + eSIR_MAC_UNSPEC_FAILURE_REASON); + /* only break for STA role (non TDLS) */ + break; + } + PELOGE(limLog(pMac, LOGE, FL(" Deleting station: staId = %d, reasonCode = %d"), pMsg->staId, pMsg->reasonCode);) + if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) + return; + + pStaDs = dphLookupAssocId(pMac, pMsg->staId, &pMsg->assocId, &psessionEntry->dph.dphHashTable); + + if (!pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("Skip STA deletion (invalid STA) limSystemRole=%d"),psessionEntry->limSystemRole);) + vos_mem_free(pMsg); + return; + } + + /* check and see if same staId. This is to avoid the scenario + * where we're trying to delete a staId we just added. + */ + if (pStaDs->staIndex != pMsg->staId) + { + PELOGE(limLog(pMac, LOGE, FL("staid mismatch: %d vs %d "), pStaDs->staIndex, pMsg->staId);) + vos_mem_free(pMsg); + return; + } + + if((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_AP_ROLE == psessionEntry->limSystemRole)) + { + PELOG1(limLog(pMac, LOG1, FL("SAP:lim Delete Station Context (staId: %d, assocId: %d) "), + pMsg->staId, pMsg->assocId);) + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + } + else + { +#ifdef FEATURE_WLAN_TDLS + if(eLIM_STA_ROLE == psessionEntry->limSystemRole && + STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + //TeardownLink with PEER + //Reason code HAL_DEL_STA_REASON_CODE_KEEP_ALIVE means + //eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + /*pMsg->reasonCode*/ eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE); + } + else + { +#endif + //TearDownLink with AP + tLimMlmDeauthInd mlmDeauthInd; + PELOGW(limLog(pMac, LOGW, FL("lim Delete Station Context (staId: %d, assocId: %d) "), + pMsg->staId, pMsg->assocId);) + + pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH; + + // Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger; + +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); +#ifdef FEATURE_WLAN_TDLS + } +#endif + } + break; + + case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2: + PELOGE(limLog(pMac, LOGE, FL(" Deleting Unknown station "));) + limPrintMacAddr(pMac, pMsg->addr2, LOGE); + limSendDeauthMgmtFrame( pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMsg->addr2, psessionEntry, FALSE); + break; + + default: + PELOGE(limLog(pMac, LOGE, FL(" Unknown reason code "));) + break; + + } + vos_mem_free(pMsg); + return; +} + + +/** + * limTriggerSTAdeletion() + * + *FUNCTION: + * This function is called to trigger STA context deletion + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param pStaDs - Pointer to internal STA Datastructure + * @return None + */ +void +limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tSirSmeDeauthReq *pSmeDeauthReq; + tANI_U8 *pBuf; + tANI_U8 *pLen; + tANI_U16 msgLength = 0; + + if (! pStaDs) + { + PELOGW(limLog(pMac, LOGW, FL("Skip STA deletion (invalid STA)"));) + return; + } + /** + * MAC based Authentication was used. Trigger + * Deauthentication frame to peer since it will + * take care of disassociation as well. + */ + + pSmeDeauthReq = vos_mem_malloc(sizeof(tSirSmeDeauthReq)); + if (NULL == pSmeDeauthReq) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_DEAUTH_REQ ")); + return; + } + + pBuf = (tANI_U8 *) &pSmeDeauthReq->messageType; + + //messageType + limCopyU16((tANI_U8*)pBuf, eWNI_SME_DISASSOC_REQ); + pBuf += sizeof(tANI_U16); + msgLength += sizeof(tANI_U16); + + //length + pLen = pBuf; + pBuf += sizeof(tANI_U16); + msgLength += sizeof(tANI_U16); + + //sessionId + *pBuf = psessionEntry->smeSessionId; + pBuf++; + msgLength++; + + //transactionId + limCopyU16((tANI_U8*)pBuf, psessionEntry->transactionId); + pBuf += sizeof(tANI_U16); + msgLength += sizeof(tANI_U16); + + //bssId + vos_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + msgLength += sizeof(tSirMacAddr); + + //peerMacAddr + vos_mem_copy(pBuf, pStaDs->staAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + msgLength += sizeof(tSirMacAddr); + + //reasonCode + limCopyU16((tANI_U8*)pBuf, (tANI_U16)eLIM_LINK_MONITORING_DISASSOC); + pBuf += sizeof(tANI_U16); + msgLength += sizeof(tANI_U16); + + //Do not send disassoc OTA + //pBuf[0] = 1 means do not send the disassoc frame over the air + //pBuf[0] = 0 means send the disassoc frame over the air + pBuf[0]= 0; + pBuf += sizeof(tANI_U8); + msgLength += sizeof(tANI_U8); + + + + //Fill in length + limCopyU16((tANI_U8*)pLen , msgLength); + + limPostSmeMessage(pMac, eWNI_SME_DISASSOC_REQ, (tANI_U32 *) pSmeDeauthReq); + vos_mem_free(pSmeDeauthReq); + +} /*** end limTriggerSTAdeletion() ***/ + + + +/** + * limTearDownLinkWithAp() + * + *FUNCTION: + * This function is called when heartbeat (beacon reception) + * fails on STA + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limTearDownLinkWithAp(tpAniSirGlobal pMac, tANI_U8 sessionId, tSirMacReasonCodes reasonCode) +{ + tpDphHashNode pStaDs = NULL; + + //tear down the following sessionEntry + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + /** + * Heart beat failed for upto threshold value + * and AP did not respond for Probe request. + * Trigger link tear down. + */ + if(pMac->psOffloadEnabled) + psessionEntry->pmmOffloadInfo.bcnmiss = FALSE; + else + pMac->pmm.inMissedBeaconScenario = FALSE; + + limLog(pMac, LOGW, + FL("No ProbeRsp from AP after HB failure. Tearing down link")); + + // Deactivate heartbeat timer + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + + // Announce loss of link to Roaming algorithm + // and cleanup by sending SME_DISASSOC_REQ to SME + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + + if (pStaDs != NULL) + { + tLimMlmDeauthInd mlmDeauthInd; + +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + + pStaDs->mlmStaContext.disassocReason = reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH; + + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger; + + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); + } +} /*** limTearDownLinkWithAp() ***/ + + + + +/** + * limHandleHeartBeatFailure() + * + *FUNCTION: + * This function is called when heartbeat (beacon reception) + * fails on STA + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limHandleHeartBeatFailure(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + vos_log_beacon_update_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* If gLimHeartBeatTimer fires between the interval of sending WDA_ENTER_BMPS_REQUEST + * to the HAL and receiving WDA_ENTER_BMPS_RSP from the HAL, then LIM (PE) tries to Process the + * SIR_LIM_HEAR_BEAT_TIMEOUT message but The PE state is ePMM_STATE_BMPS_SLEEP so PE dont + * want to handle heartbeat timeout in the BMPS, because Firmware handles it in BMPS. + * So just return from heartbeatfailure handler + */ + if(!pMac->psOffloadEnabled) + { + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE && (!limIsSystemInActiveState(pMac))) + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_beacon_update_pkt_type, LOG_WLAN_BEACON_UPDATE_C); + if(log_ptr) + log_ptr->bcn_rx_cnt = psessionEntry->LimRxedBeaconCntDuringHB; + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Ensure HB Status for the session has been reseted */ + psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE; + + if (((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + if (!pMac->sys.gSysEnableLinkMonitorMode) + return; + + /** + * Beacon frame not received within heartbeat timeout. + */ + PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure"));) + pMac->lim.gLimHBfailureCntInLinkEstState++; + + /** + * Check if connected on the DFS channel, if not connected on + * DFS channel then only send the probe request otherwise tear down the link + */ + if(!limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + { + /*** Detected continuous Beacon Misses ***/ + psessionEntry->LimHBFailureStatus= eANI_BOOLEAN_TRUE; + + /*Reset the HB packet count before sending probe*/ + limResetHBPktCount(psessionEntry); + /** + * Send Probe Request frame to AP to see if + * it is still around. Wait until certain + * timeout for Probe Response from AP. + */ + PELOGW(limLog(pMac, LOGW, FL("Heart Beat missed from AP. Sending Probe Req"));) + /* for searching AP, we don't include any additional IE */ + limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId, + psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + } + else + { + PELOGW(limLog(pMac, LOGW, + FL("Heart Beat missed from AP on DFS chanel moving to passive"));) + if (psessionEntry->currentOperChannel < SIR_MAX_24G_5G_CHANNEL_RANGE){ + limCovertChannelScanType(pMac, psessionEntry->currentOperChannel, false); + pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] = 0; + } + /* Connected on DFS channel so should not send the probe request + * tear down the link directly */ + limTearDownLinkWithAp(pMac, psessionEntry->peSessionId, eSIR_MAC_UNSPEC_FAILURE_REASON); + } + } + else + { + /** + * Heartbeat timer may have timed out + * while we're doing background scanning/learning + * or in states other than link-established state. + * Log error. + */ + PELOG1(limLog(pMac, LOG1, FL("received heartbeat timeout in state %X"), + psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState); + pMac->lim.gLimHBfailureCntInOtherStates++; + limReactivateHeartBeatTimer(pMac, psessionEntry); + } +} /*** limHandleHeartBeatFailure() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLogDump.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLogDump.c new file mode 100644 index 0000000000000..88f0e9ec43204 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limLogDump.c @@ -0,0 +1,2525 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +limLogDump.c + +Implements the dump commands specific to the lim module. + ============================================================================*/ + +#include "vos_types.h" +#include "limApi.h" + +#if defined(ANI_LOGDUMP) + + +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "schApi.h" +#include "limSerDesUtils.h" +#include "limAssocUtils.h" +#include "limSendMessages.h" +#include "logDump.h" +#include "limTrace.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif +#include "smeInside.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_wdi_dts.h" + +void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA); +#ifdef WLANTL_DEBUG +extern void WLANTLPrintPktsRcvdPerRssi(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush); +extern void WLANTLPrintPktsRcvdPerRateIdx(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush); +#endif + +static char *getRole( tLimSystemRole role ) +{ + switch (role) + { + case eLIM_UNKNOWN_ROLE: + return "eLIM_UNKNOWN_ROLE"; + case eLIM_AP_ROLE: + return "eLIM_AP_ROLE"; + case eLIM_STA_IN_IBSS_ROLE: + return "eLIM_STA_IN_IBSS_ROLE"; + case eLIM_STA_ROLE: + return "eLIM_STA_ROLE"; + case eLIM_BT_AMP_STA_ROLE: + return "eLIM_BT_AMP_STA_ROLE"; + case eLIM_BT_AMP_AP_ROLE: + return "eLIM_BT_AMP_AP_ROLE"; + default: + return "UNKNOWN"; + } +} + + + +char *dumpLim( tpAniSirGlobal pMac, char *p, tANI_U32 sessionId) +{ + #ifdef FIXME_GEN6 + //iterate through the sessionTable and dump sta entries for each session. + //Keep this code under 'WLAN_DEBUG' compile flag. + + tANI_U16 i, j; + + tpPESession psessionEntry = peFindSessionBySessionId(pMac, sessionId); + + if (psessionEntry == NULL) + { + p += log_sprintf( pMac, p, "Invalid sessionId: %d \n ", sessionId); + return p; + } + + p += log_sprintf( pMac,p, "\n ----- LIM Debug Information ----- \n"); + p += log_sprintf( pMac,p, "LIM Role = (%d) %s\n", + pMac->lim.gLimSystemRole, getRole(pMac->lim.gLimSystemRole)); + p += log_sprintf( pMac,p, "SME State = (%d) %s", + pMac->lim.gLimSmeState, limSmeStateStr(pMac->lim.gLimSmeState)); + p += log_sprintf( pMac,p, "MLM State = (%d) %s", + pMac->lim.gLimMlmState, limMlmStateStr(pMac->lim.gLimMlmState)); + p += log_sprintf( pMac,p, "802.11n session HT Capability: %s\n", + (psessionEntry->htCapability == 1) ? "Enabled" : "Disabled"); + p += log_sprintf( pMac,p, "gLimProcessDefdMsgs: %s\n", + (pMac->lim.gLimProcessDefdMsgs == 1) ? "Enabled" : "Disabled"); + + if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) + { + p += log_sprintf( pMac,p, "AID = %X\t\t\n", pMac->lim.gLimAID); + p += log_sprintf( pMac,p, "SSID mismatch in Beacon Count = %d\n", + pMac->lim.gLimBcnSSIDMismatchCnt); + p += log_sprintf( pMac,p, "Number of link establishments = %d\n", + pMac->lim.gLimNumLinkEsts); + } + else if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) + { + p += log_sprintf( pMac,p, "Num of STAs associated = %d\n", + peGetCurrentSTAsCount(pMac)); + + p += log_sprintf( pMac,p, "Num of Pre-auth contexts = %d\n", + pMac->lim.gLimNumPreAuthContexts); + + p += log_sprintf( pMac,p, "Num of AssocReq dropped in invalid State = %d\n", + pMac->lim.gLimNumAssocReqDropInvldState); + + p += log_sprintf( pMac,p, "Num of ReassocReq dropped in invalid State = %d\n", + pMac->lim.gLimNumReassocReqDropInvldState); + + p += log_sprintf( pMac,p, "Num of Hash Miss Event ignored = %d\n", + pMac->lim.gLimNumHashMissIgnored); + } + + p += log_sprintf( pMac,p, "Num of RxCleanup Count = %d\n", + pMac->lim.gLimNumRxCleanup); + p += log_sprintf( pMac,p, "Unexpected Beacon Count = %d\n", + pMac->lim.gLimUnexpBcnCnt); + p += log_sprintf( pMac,p, "Number of Re/Assoc rejects of 11b STAs = %d\n", + pMac->lim.gLim11bStaAssocRejectCount); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n", + pMac->lim.gLimHBfailureCntInLinkEstState); + p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n", + pMac->lim.gLimProbeFailureAfterHBfailedCnt); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n", + pMac->lim.gLimHBfailureCntInOtherStates); + p += log_sprintf( pMac,p, "No. of Beacons Rxed During HB Interval = %d\n", + pMac->lim.gLimRxedBeaconCntDuringHB); + p += log_sprintf( pMac,p, "Self Operating Mode = %s\n", limDot11ModeStr(pMac, (tANI_U8)pMac->lim.gLimDot11Mode)); + p += log_sprintf( pMac,p, "\n"); + + if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) + i = 2; + else + i = 1; + + + for (; i< pMac->lim.maxStation; i++) + { + tpDphHashNode pSta = dphGetHashEntry(pMac, (unsigned short)i); + if (pSta && pSta->added) + { + p += log_sprintf( pMac,p, "\nSTA AID: %d STA ID: %d Valid: %d AuthType: %d MLM State: %s", + i, pSta->staIndex, pSta->valid, + pSta->mlmStaContext.authType, + limMlmStateStr(pSta->mlmStaContext.mlmState)); + + p += log_sprintf( pMac,p, "\tAID:%-2d OpRateMode:%s ShPrmbl:%d HT:%d GF:%d TxChWidth:%d MimoPS:%d LsigProt:%d\n", + pSta->assocId, limStaOpRateModeStr(pSta->supportedRates.opRateMode), + pSta->shortPreambleEnabled, pSta->mlmStaContext.htCapability, + pSta->htGreenfield, pSta->htSupportedChannelWidthSet, + pSta->htMIMOPSState, pSta->htLsigTXOPProtection); + + p += log_sprintf( pMac,p, "\tAMPDU [MaxSz(Factor):%d, Dens: %d] AMSDU-MaxLen: %d\n", + pSta->htMaxRxAMpduFactor, pSta->htAMpduDensity,pSta->htMaxAmsduLength); + p += log_sprintf( pMac,p, "\tDSSCCkMode40Mhz: %d, SGI20: %d, SGI40: %d\n", + pSta->htDsssCckRate40MHzSupport, pSta->htShortGI20Mhz, + pSta->htShortGI40Mhz); + + p += log_sprintf( pMac,p, "\t11b Rates: "); + for(j=0; jsupportedRates.llbRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llbRates[j]); + + p += log_sprintf( pMac,p, "\n\t11a Rates: "); + for(j=0; jsupportedRates.llaRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llaRates[j]); + + p += log_sprintf( pMac,p, "\n\tPolaris Rates: "); + for(j=0; jsupportedRates.aniLegacyRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.aniLegacyRates[j]); + + p += log_sprintf( pMac,p, "\n\tTitan and Taurus Proprietary Rate Bitmap: %08x\n", + pSta->supportedRates.aniEnhancedRateBitmap); + p += log_sprintf( pMac,p, "\tMCS Rate Set Bitmap: "); + for(j=0; jsupportedRates.supportedMCSSet[j]); + + } + } + p += log_sprintf( pMac,p, "\nProbe response disable = %d\n", + pMac->lim.gLimProbeRespDisableFlag); + + p += log_sprintf( pMac,p, "Scan mode enable = %d\n", + pMac->sys.gSysEnableScanMode); + p += log_sprintf( pMac,p, "BackgroundScanDisable = %d\n", + pMac->lim.gLimBackgroundScanDisable); + p += log_sprintf( pMac,p, "ForceBackgroundScanDisable = %d\n", + pMac->lim.gLimForceBackgroundScanDisable); + p += log_sprintf( pMac,p, "LinkMonitor mode enable = %d\n", + pMac->sys.gSysEnableLinkMonitorMode); + p += log_sprintf( pMac,p, "Qos Capable = %d\n", + SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Wme Capable = %d\n", + LIM_BSS_CAPS_GET(WME, pMac->lim.gLimCurrentBssQosCaps)); + p += log_sprintf( pMac,p, "Wsm Capable = %d\n", + LIM_BSS_CAPS_GET(WSM, pMac->lim.gLimCurrentBssQosCaps)); + if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + p += log_sprintf( pMac,p, "Number of peers in IBSS = %d\n", + pMac->lim.gLimNumIbssPeers); + if (pMac->lim.gLimNumIbssPeers) + { + tLimIbssPeerNode *pTemp; + pTemp = pMac->lim.gLimIbssPeerList; + p += log_sprintf( pMac,p, "MAC-Addr Ani Edca WmeInfo HT Caps #S,#E(Rates)\n"); + while (pTemp != NULL) + { + p += log_sprintf( pMac,p, "%02X:%02X:%02X:%02X:%02X:%02X ", + pTemp->peerMacAddr[0], + pTemp->peerMacAddr[1], + pTemp->peerMacAddr[2], + pTemp->peerMacAddr[3], + pTemp->peerMacAddr[4], + pTemp->peerMacAddr[5]); + p += log_sprintf( pMac,p, " %d,%d %d %d %04X %d,%d\n", + pTemp->edcaPresent, pTemp->wmeEdcaPresent, + pTemp->wmeInfoPresent, + pTemp->htCapable, + pTemp->capabilityInfo, + pTemp->supportedRates.numRates, + pTemp->extendedRates.numRates); + pTemp = pTemp->next; + } + } + } + p += log_sprintf( pMac,p, "System Scan/Learn Mode bit = %d\n", + pMac->lim.gLimSystemInScanLearnMode); + p += log_sprintf( pMac,p, "Scan override = %d\n", + pMac->lim.gLimScanOverride); + p += log_sprintf( pMac,p, "CB State protection = %d\n", + pMac->lim.gLimCBStateProtection); + p += log_sprintf( pMac,p, "Count of Titan STA's = %d\n", + pMac->lim.gLimTitanStaCount); + + //current BSS capability + p += log_sprintf( pMac,p, "**********Current BSS Capability********\n"); + p += log_sprintf( pMac,p, "Ess = %d, ", SIR_MAC_GET_ESS(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Privacy = %d, ", SIR_MAC_GET_PRIVACY(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Short Preamble = %d, ", SIR_MAC_GET_SHORT_PREAMBLE(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Short Slot = %d, ", SIR_MAC_GET_SHORT_SLOT_TIME(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Qos = %d\n", SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps)); + + //Protection related information + p += log_sprintf( pMac,p, "*****Protection related information******\n"); + p += log_sprintf( pMac,p, "Protection %s\n", pMac->lim.gLimProtectionControl ? "Enabled" : "Disabled"); + + p += log_sprintf( pMac,p, "OBSS MODE = %d\n", pMac->lim.gHTObssMode); + p += log_sprintf( pMac, p, "HT operating Mode = %d, llbCoexist = %d, llgCoexist = %d, ht20Coexist = %d, nonGfPresent = %d, RifsMode = %d, lsigTxop = %d\n", + pMac->lim.gHTOperMode, pMac->lim.llbCoexist, pMac->lim.llgCoexist, + pMac->lim.ht20MhzCoexist, pMac->lim.gHTNonGFDevicesPresent, + pMac->lim.gHTRifsMode, pMac->lim.gHTLSigTXOPFullSupport); + p += log_sprintf(pMac, p, "2nd Channel offset = %d\n", + psessionEntry->hHTSecondaryChannelOffset); +#endif + return p; +} + +/******************************************* + * FUNCTION: triggerBeaconGen() + * + * This logdump sends SIR_SCH_BEACON_GEN_IND to SCH. + * SCH then proceeds to generate a beacon template + * and copy it to the Host/SoftMAC shared memory + * + * TODO - This routine can safely be deleted once + * beacon generation is working + ******************************************/ +char *triggerBeaconGen( tpAniSirGlobal pMac, char *p ) +{ + tSirMsgQ mesg = { (tANI_U16) SIR_LIM_BEACON_GEN_IND, (tANI_U16) 0, (tANI_U32) 0 }; + + pMac->lim.gLimSmeState = eLIM_SME_NORMAL_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + pMac->lim.gLimSystemRole = eLIM_AP_ROLE; + + p += log_sprintf( pMac, p, + "Posted SIR_LIM_BEACON_GEN_IND with result = %s\n", + (eSIR_SUCCESS == limPostMsgApi( pMac, &mesg ))? + "Success": "Failure" ); + + return p; +} + + +/******************************************* + * FUNCTION: testLimSendProbeRsp() + * + * This logdump sends SIR_MAC_MGMT_PROBE_RSP + * + * TODO - This routine can safely be deleted once + * the MGMT frame transmission is working + ******************************************/ +char *testLimSendProbeRsp( tpAniSirGlobal pMac, char *p ) +{ + tSirMacAddr peerMacAddr = { 0, 1, 2, 3, 4, 5 }; + tAniSSID ssId; + tANI_U32 len = SIR_MAC_MAX_SSID_LENGTH; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, + WNI_CFG_SSID, + (tANI_U8 *) &ssId.ssId, + (tANI_U32 *) &len )) + { + // Could not get SSID from CFG. Log error. + p += log_sprintf( pMac, p, "Unable to retrieve SSID\n" ); + return p; + } + else + ssId.length = (tANI_U8) len; + + p += log_sprintf( pMac, p, "Calling limSendProbeRspMgmtFrame...\n" ); + limSendProbeRspMgmtFrame( pMac, peerMacAddr, &ssId, -1, 1, psessionEntry , 0); + + return p; +} + + +static char *sendSmeScanReq(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + tSirSmeScanReq scanReq, *pScanReq; + + p += log_sprintf( pMac,p, "sendSmeScanReq: Preparing eWNI_SME_SCAN_REQ message\n"); + + pScanReq = (tSirSmeScanReq *) &scanReq; + + pScanReq = vos_mem_malloc(sizeof(tSirSmeScanReq)); + if (NULL == pScanReq) + { + p += log_sprintf( pMac,p,"sendSmeScanReq: AllocateMemory() failed \n"); + return p; + } + + pScanReq->messageType = eWNI_SME_SCAN_REQ; + pScanReq->minChannelTime = 30; + pScanReq->maxChannelTime = 130; + pScanReq->bssType = eSIR_INFRASTRUCTURE_MODE; + limGetMyMacAddr(pMac, pScanReq->bssId); + pScanReq->numSsid = 1; + vos_mem_copy((void *) &pScanReq->ssId[0].ssId, (void *)"Ivan", 4); + pScanReq->ssId[0].length = 4; + pScanReq->scanType = eSIR_ACTIVE_SCAN; + pScanReq->returnAfterFirstMatch = 0; + pScanReq->returnUniqueResults = 0; + /* Original code: + * pScanReq->returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS; + * + * Do not purge while starting a scan. Rome firmware sends results of + * roaming scan as normal entries. They land up in this scan cache. + * We should not lose those entries. + * This cached should be purged after filling in a query. + */ + pScanReq->returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS; + pScanReq->channelList.numChannels = 1; + pScanReq->channelList.channelNumber[0] = 6; + pScanReq->uIEFieldLen = 0; + pScanReq->uIEFieldOffset = sizeof(tSirSmeScanReq); + pScanReq->sessionId = 0; + + msg.type = eWNI_SME_SCAN_REQ; + msg.bodyptr = pScanReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeScanReq: limPostMsgApi(eWNI_SME_SCAN_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeDisAssocReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1 ,tANI_U32 arg2) +{ + + tpDphHashNode pStaDs; + tSirMsgQ msg; + tSirSmeDisassocReq *pDisAssocReq; + tpPESession psessionEntry; + + //arg1 - assocId + //arg2 - sessionId + if( arg1 < 1 ) + { + p += log_sprintf( pMac,p,"Invalid session OR Assoc ID \n"); + return p; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + + pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable); + + if(NULL == pStaDs) + { + p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1); + return p; + } + + pDisAssocReq = vos_mem_malloc(sizeof(tSirSmeDisassocReq)); + if (NULL == pDisAssocReq) + { + p += log_sprintf( pMac,p,"sendSmeDisAssocReq: AllocateMemory() failed \n"); + return p; + } + + if( ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) && + (psessionEntry->statypeForBss == STA_ENTRY_PEER)) + { + sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId); + sirCopyMacAddr(pDisAssocReq->peerMacAddr,psessionEntry->bssId); + } + if((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + sirCopyMacAddr(pDisAssocReq->peerMacAddr,pStaDs->staAddr); + sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId); + } + + pDisAssocReq->messageType = eWNI_SME_DISASSOC_REQ; + + pDisAssocReq->length = sizeof(tSirSmeDisassocReq); + + pDisAssocReq->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + + pDisAssocReq->sessionId = 0; + + pDisAssocReq->transactionId = 0; + + msg.type = eWNI_SME_DISASSOC_REQ; + msg.bodyptr = pDisAssocReq; + msg.bodyval = 0; + + p += log_sprintf( pMac,p, "sendSmeDisAssocReq: limPostMsgApi(eWNI_SME_DISASSOC_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + + +static char *sendSmeStartBssReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1) +{ + tSirMsgQ msg; + tSirSmeStartBssReq *pStartBssReq; + unsigned char *pBuf; + ePhyChanBondState cbMode; + tSirNwType nwType; + + p += log_sprintf( pMac,p, "sendSmeStartBssReq: Preparing eWNI_SME_START_BSS_REQ message\n"); + + if(arg1 > 2) + { + p += log_sprintf( pMac,p,"Invalid Argument1 \n"); + return p; + } + + pStartBssReq = vos_mem_malloc(sizeof(tSirSmeStartBssReq)); + if (NULL == pStartBssReq) + { + p += log_sprintf( pMac,p,"sendSmeStartBssReq: AllocateMemory() failed \n"); + return p; + } + + pStartBssReq->messageType = eWNI_SME_START_BSS_REQ; + pStartBssReq->length = 29; // 0x1d + + if(arg1 == 0) //BTAMP STATION + { + pStartBssReq->bssType = eSIR_BTAMP_STA_MODE; + + pStartBssReq->ssId.length = 5; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"BTSTA", 5); + } + else if(arg1 == 1) //BTAMP AP + { + pStartBssReq->bssType = eSIR_BTAMP_AP_MODE; + pStartBssReq->ssId.length = 4; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"BTAP", 4); + } + else //IBSS + { + pStartBssReq->bssType = eSIR_IBSS_MODE; + pStartBssReq->ssId.length = 4; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"Ibss", 4); + } + + // Filling in channel ID 6 + pBuf = &(pStartBssReq->ssId.ssId[pStartBssReq->ssId.length]); + *pBuf = 6; + pBuf++; + + // Filling in CB mode + cbMode = PHY_SINGLE_CHANNEL_CENTERED; + vos_mem_copy(pBuf, (tANI_U8 *)&cbMode, sizeof(ePhyChanBondState)); + pBuf += sizeof(ePhyChanBondState); + + // Filling in RSN IE Length to zero + vos_mem_set(pBuf, sizeof(tANI_U16), 0); //tSirRSNie->length + pBuf += sizeof(tANI_U16); + + // Filling in NW Type + nwType = eSIR_11G_NW_TYPE; + vos_mem_copy(pBuf, (tANI_U8 *)&nwType, sizeof(tSirNwType)); + pBuf += sizeof(tSirNwType); + + /* ---- To be filled by LIM later ---- + pStartBssReq->operationalRateSet + pStartBssReq->extendedRateSet + pStartBssReq->dot11mode + pStartBssReq->bssId + pStartBssReq->selfMacAddr + pStartBssReq->beaconInterval + pStartBssReq->sessionId = 0; + pStartBssReq->transactionId = 0; + * ------------------------------------ */ + + msg.type = eWNI_SME_START_BSS_REQ; + msg.bodyptr = pStartBssReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeStartBssReq: limPostMsgApi(eWNI_SME_START_BSS_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeStopBssReq(tpAniSirGlobal pMac, char *p, tANI_U32 sessionId) +{ + tSirMsgQ msg; + tSirSmeStopBssReq stopBssReq, *pStopBssReq; + tANI_U16 msgLen = 0; + tpPESession psessionEntry; + + psessionEntry = peFindSessionBySessionId(pMac, (tANI_U8)sessionId); + if ( psessionEntry == NULL ) + { + limLog(pMac, LOGP, FL("Session entry does not exist for given sessionID \n")); + return p; + } + + p += log_sprintf( pMac,p, "sendSmeStopBssReq: Preparing eWNI_SME_STOP_BSS_REQ message\n"); + pStopBssReq = (tSirSmeStopBssReq *) &stopBssReq; + + pStopBssReq = vos_mem_malloc(sizeof(tSirSmeStopBssReq)); + if (NULL == pStopBssReq) + { + p += log_sprintf( pMac,p,"sendSmeStopBssReq: AllocateMemory() failed \n"); + return p; + } + + pStopBssReq->messageType = eWNI_SME_STOP_BSS_REQ; + msgLen += sizeof(tANI_U32); // msgType + length + + pStopBssReq->reasonCode = eSIR_SME_SUCCESS; + msgLen += sizeof(tSirResultCodes); + + vos_mem_copy((void *) &pStopBssReq->bssId, (void *)psessionEntry->bssId, 6); + msgLen += sizeof(tSirMacAddr); + + pStopBssReq->sessionId = (tANI_U8)sessionId; + msgLen += sizeof(tANI_U8); + + pStopBssReq->transactionId = 0; + msgLen += sizeof(tANI_U16); + + pStopBssReq->length = msgLen; + + msg.type = eWNI_SME_STOP_BSS_REQ; + msg.bodyptr = pStopBssReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeStopBssReq: limPostMsgApi(eWNI_SME_STOP_BSS_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeJoinReq(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + tSirSmeJoinReq *pJoinReq; + unsigned char *pBuf; + tANI_U16 msgLen = 307; + + tANI_U8 msgDump[307] = { + 0x06, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, + 0xDE, 0xAD, 0xBA, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x21, 0x04, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0xA8, 0x85, 0x4F, 0x7A, 0x00, 0x06, 0x41, + 0x6E, 0x69, 0x4E, 0x65, 0x74, 0x01, 0x04, 0x82, 0x84, 0x8B, + 0x96, 0x03, 0x01, 0x06, 0x07, 0x06, 0x55, 0x53, 0x49, 0x01, + 0x0E, 0x1E, 0x2A, 0x01, 0x00, 0x32, 0x08, 0x0C, 0x12, 0x18, + 0x24, 0x30, 0x48, 0x60, 0x6C, 0x2D, 0x1A, 0xEE, 0x11, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3D, 0x16, 0x06, 0x07, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x18, 0x00, + 0x50, 0xF2, 0x02, 0x01, 0x01, 0x01, 0x00, 0x03, 0xA4, 0x00, + 0x00, 0x27, 0xA4, 0x00, 0x00, 0x42, 0x43, 0x5E, 0x00, 0x62, + 0x32, 0x2F, 0x00, 0xDD, 0x14, 0x00, 0x0A, 0xF5, 0x00, 0x03, + 0x01, 0x03, 0x05, 0x0A, 0x02, 0x80, 0xC0, 0x12, 0x06, 0xFF, + 0xFF, 0xFF, 0xFF, 0xB6, 0x0D, 0xDD, 0x6E, 0x00, 0x50, 0xF2, + 0x04, 0x10, 0x4A, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01, + 0x01, 0x10, 0x3B, 0x00, 0x01, 0x03, 0x10, 0x47, 0x00, 0x10, + 0xDB, 0xC6, 0x77, 0x28, 0xB9, 0xF3, 0xD8, 0x58, 0x86, 0xFF, + 0xFC, 0x6B, 0xB6, 0xB9, 0x27, 0x79, 0x10, 0x21, 0x00, 0x08, + 0x51, 0x75, 0x61, 0x6C, 0x63, 0x6F, 0x6D, 0x6D, 0x10, 0x23, + 0x00, 0x07, 0x57, 0x46, 0x52, 0x34, 0x30, 0x33, 0x31, 0x10, + 0x24, 0x00, 0x06, 0x4D, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10, + 0x42, 0x00, 0x06, 0x53, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10, + 0x54, 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xF2, 0x04, 0x00, + 0x01, 0x10, 0x11, 0x00, 0x06, 0x31, 0x31, 0x6E, 0x2D, 0x41, + 0x50, 0x10, 0x08, 0x00, 0x02, 0x01, 0x8E + }; + + pJoinReq = vos_mem_malloc(msgLen); + if (NULL == pJoinReq) + { + p += log_sprintf( pMac,p,"sendSmeJoinReq: AllocateMemory() failed \n"); + return p; + } + + pBuf = (unsigned char *)pJoinReq; + vos_mem_copy(pBuf, (tANI_U8 *)msgDump, msgLen); + + msg.type = eWNI_SME_JOIN_REQ; + msg.bodyptr = pJoinReq; + msg.bodyval = 0; + limPostMsgApi(pMac, &msg); + + return p; +} + + +static char *printSessionInfo(tpAniSirGlobal pMac, char *p) +{ + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + + p += log_sprintf( pMac, p, "Dump PE Session \n"); + + for(i=0; i < pMac->lim.maxBssId; i++) + { + if( pMac->lim.gpSession[i].valid ) + { + psessionEntry = &pMac->lim.gpSession[i]; + p += log_sprintf( pMac,p, "*****************************************\n"); + p += log_sprintf( pMac,p, " PE Session [%d] \n", i); + p += log_sprintf( pMac,p, "available: %d \n", psessionEntry->available); + p += log_sprintf( pMac,p, "peSessionId: %d, smeSessionId: %d, transactionId: %d \n", + psessionEntry->peSessionId, psessionEntry->smeSessionId, psessionEntry->smeSessionId); + p += log_sprintf( pMac,p, "bssId: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->bssId[0], psessionEntry->bssId[1], psessionEntry->bssId[2], + psessionEntry->bssId[3], psessionEntry->bssId[4], psessionEntry->bssId[5]); + p += log_sprintf( pMac,p, "selfMacAddr: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->selfMacAddr[0], psessionEntry->selfMacAddr[1], psessionEntry->selfMacAddr[2], + psessionEntry->selfMacAddr[3], psessionEntry->selfMacAddr[4], psessionEntry->selfMacAddr[5]); + p += log_sprintf( pMac,p, "bssIdx: %d \n", psessionEntry->bssIdx); + p += log_sprintf( pMac,p, "valid: %d \n", psessionEntry->valid); + p += log_sprintf( pMac,p, "limMlmState: (%d) %s ", psessionEntry->limMlmState, limMlmStateStr(psessionEntry->limMlmState) ); + p += log_sprintf( pMac,p, "limPrevMlmState: (%d) %s ", psessionEntry->limPrevMlmState, limMlmStateStr(psessionEntry->limMlmState) ); + p += log_sprintf( pMac,p, "limSmeState: (%d) %s ", psessionEntry->limSmeState, limSmeStateStr(psessionEntry->limSmeState) ); + p += log_sprintf( pMac,p, "limPrevSmeState: (%d) %s ", psessionEntry->limPrevSmeState, limSmeStateStr(psessionEntry->limPrevSmeState) ); + p += log_sprintf( pMac,p, "limSystemRole: (%d) %s \n", psessionEntry->limSystemRole, getRole(psessionEntry->limSystemRole) ); + p += log_sprintf( pMac,p, "bssType: (%d) %s \n", psessionEntry->bssType, limBssTypeStr(psessionEntry->bssType)); + p += log_sprintf( pMac,p, "operMode: %d \n", psessionEntry->operMode); + p += log_sprintf( pMac,p, "dot11mode: %d \n", psessionEntry->dot11mode); + p += log_sprintf( pMac,p, "htCapability: %d \n", psessionEntry->htCapability); + p += log_sprintf( pMac,p, "limRFBand: %d \n", psessionEntry->limRFBand); + p += log_sprintf( pMac,p, "limIbssActive: %d \n", psessionEntry->limIbssActive); + p += log_sprintf( pMac,p, "limCurrentAuthType: %d \n", psessionEntry->limCurrentAuthType); + p += log_sprintf( pMac,p, "limCurrentBssCaps: %d \n", psessionEntry->limCurrentBssCaps); + p += log_sprintf( pMac,p, "limCurrentBssQosCaps: %d \n", psessionEntry->limCurrentBssQosCaps); + p += log_sprintf( pMac,p, "limCurrentBssPropCap: %d \n", psessionEntry->limCurrentBssPropCap); + p += log_sprintf( pMac,p, "limSentCapsChangeNtf: %d \n", psessionEntry->limSentCapsChangeNtf); + p += log_sprintf( pMac,p, "LimAID: %d \n", psessionEntry->limAID); + p += log_sprintf( pMac,p, "ReassocbssId: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->limReAssocbssId[0], psessionEntry->limReAssocbssId[1], psessionEntry->limReAssocbssId[2], + psessionEntry->limReAssocbssId[3], psessionEntry->limReAssocbssId[4], psessionEntry->limReAssocbssId[5]); + p += log_sprintf( pMac,p, "limReassocChannelId: %d \n", psessionEntry->limReassocChannelId); + p += log_sprintf( pMac,p, "limReassocBssCaps: %d \n", psessionEntry->limReassocBssCaps); + p += log_sprintf( pMac,p, "limReassocBssQosCaps: %d \n", psessionEntry->limReassocBssQosCaps); + p += log_sprintf( pMac,p, "limReassocBssPropCap: %d \n", psessionEntry->limReassocBssPropCap); + p += log_sprintf( pMac,p, "********************************************\n"); + } + } + return p; +} + +void +limSetEdcaBcastACMFlag(tpAniSirGlobal pMac, tANI_U32 ac, tANI_U32 acmFlag) +{ + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + psessionEntry->gLimEdcaParamsBC[ac].aci.acm = (tANI_U8)acmFlag; + psessionEntry->gLimEdcaParamSetCount++; + schSetFixedBeaconFields(pMac,psessionEntry); +} + +static char * +limDumpEdcaParams(tpAniSirGlobal pMac, char *p) +{ + tANI_U8 i = 0; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + p += log_sprintf( pMac,p, "EDCA parameter set count = %d\n", psessionEntry->gLimEdcaParamSetCount); + p += log_sprintf( pMac,p, "Broadcast parameters\n"); + p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n"); + for(i = 0; i < MAX_NUM_AC; i++) + { + //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters. + p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i, + psessionEntry->gLimEdcaParamsBC[i].aci.aci, psessionEntry->gLimEdcaParamsBC[i].aci.acm, + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, psessionEntry->gLimEdcaParamsBC[i].cw.max, + psessionEntry->gLimEdcaParamsBC[i].cw.min, psessionEntry->gLimEdcaParamsBC[i].txoplimit); + } + + p += log_sprintf( pMac,p, "\nLocal parameters\n"); + p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n"); + for(i = 0; i < MAX_NUM_AC; i++) + { + //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters. + p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i, + psessionEntry->gLimEdcaParams[i].aci.aci, psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].aci.aifsn, psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].cw.min, psessionEntry->gLimEdcaParams[i].txoplimit); + } + + return p; +} + + +static char* limDumpTspecEntry(tpAniSirGlobal pMac, char *p, tANI_U32 tspecEntryNo) +{ + tpLimTspecInfo pTspecList; + if(tspecEntryNo >= LIM_NUM_TSPEC_MAX) + { + p += log_sprintf( pMac,p, "Tspec Entry no. %d is out of allowed range(0 .. %d)\n", + tspecEntryNo, (LIM_NUM_TSPEC_MAX - 1)); + return p; + } + pTspecList = &pMac->lim.tspecInfo[tspecEntryNo]; + if (pTspecList->inuse) + p += log_sprintf( pMac,p, "Entry %d is VALID\n", tspecEntryNo); + else + { + p += log_sprintf( pMac,p, "Entry %d is UNUSED\n", tspecEntryNo); + return p; + } + p += log_sprintf( pMac,p, "\tSta %0x:%0x:%0x:%0x:%0x:%0x, AID %d, Index %d\n", + pTspecList->staAddr[0], pTspecList->staAddr[1], + pTspecList->staAddr[2], pTspecList->staAddr[3], + pTspecList->staAddr[4], pTspecList->staAddr[5], + pTspecList->assocId, pTspecList->idx); + p += log_sprintf( pMac,p, "\tType %d, Length %d, ackPolicy %d, userPrio %d, accessPolicy = %d, Dir %d, tsid %d\n", + pTspecList->tspec.type, pTspecList->tspec.length, + pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio, + pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction, + pTspecList->tspec.tsinfo.traffic.tsid); + p += log_sprintf( pMac,p, "\tPsb %d, Agg %d, TrafficType %d, schedule %d; msduSz: nom %d, max %d\n", + pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation, + pTspecList->tspec.tsinfo.traffic.trafficType, pTspecList->tspec.tsinfo.schedule.schedule, + pTspecList->tspec.nomMsduSz, pTspecList->tspec.maxMsduSz); + p += log_sprintf( pMac,p, "\tSvcInt: Min %d, Max %d; dataRate: Min %d, mean %d, peak %d\n", + pTspecList->tspec.minSvcInterval, pTspecList->tspec.maxSvcInterval, + pTspecList->tspec.minDataRate, pTspecList->tspec.meanDataRate, + pTspecList->tspec.peakDataRate); + p += log_sprintf( pMac,p, "\tmaxBurstSz %d, delayBound %d, minPhyRate %d, surplusBw %d, mediumTime %d\n", + pTspecList->tspec.maxBurstSz, pTspecList->tspec.delayBound, + pTspecList->tspec.minPhyRate, pTspecList->tspec.surplusBw, + pTspecList->tspec.mediumTime); + + return p; +} + +static char* dumpTspecTableSummary(tpAniSirGlobal pMac, tpLimTspecInfo pTspecList, char *p, int ctspec) +{ + p += log_sprintf( pMac, p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + ctspec, pTspecList->idx, pTspecList->assocId, + pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio, + pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation, + pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction, + pTspecList->tspec.tsinfo.traffic.tsid, pTspecList->tspec.tsinfo.traffic.trafficType); + + return p; +} + + +static char* limDumpDphTableSummary(tpAniSirGlobal pMac,char *p) +{ + tANI_U8 i, j; + p += log_sprintf( pMac,p, "DPH Table dump\n"); + + for(j=0; j < pMac->lim.maxBssId; j++) + { + /* Find first free room in session table */ + if(pMac->lim.gpSession[j].valid) + { + p += log_sprintf( pMac,p, "aid staId bssid encPol qosMode wme 11e wsm staaddr\n"); + for(i = 0; i < pMac->lim.gpSession[j].dph.dphHashTable.size; i++) + { + if (pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].added) + { + p += log_sprintf( pMac,p, "%d %d %d %d %d %d %d %d %x:%x:%x:%x:%x:%x\n", + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].assocId, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staIndex, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].bssId, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].encPolicy, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].qosMode, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wmeEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].lleEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wsmEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAuthenticated, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[0], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[1], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[2], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[3], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[4], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[5]); + } + } + } + } + return p; +} + +// add the specified tspec to the tspec list +static char* limDumpTsecTable( tpAniSirGlobal pMac, char* p) +{ + int ctspec; + tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0]; + + p += log_sprintf( pMac,p, "=======LIM TSPEC TABLE DUMP\n"); + p += log_sprintf( pMac,p, "Num\tIdx\tAID\tAckPol\tUP\tPSB\tAgg\tAccessPol\tDir\tTSID\ttraffic\n"); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if (pTspecList->inuse) + p = dumpTspecTableSummary(pMac, pTspecList, p, ctspec); + } + return p; +} + +static char * +dump_lim_tspec_table( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = limDumpTsecTable(pMac, p); + return p; +} + +static char * +dump_lim_tspec_entry( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = limDumpTspecEntry(pMac, p, arg1); + return p; +} + +static char * +dump_lim_dph_table_summary( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = limDumpDphTableSummary(pMac, p); + return p; +} + + +static char * +dump_lim_link_monitor_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 ind, val; + + (void) arg2; (void) arg3; (void) arg4; + p += log_sprintf( pMac,p, "\n ----- LIM Heart Beat Stats ----- \n"); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n", + pMac->lim.gLimHBfailureCntInLinkEstState); + p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n", + pMac->lim.gLimProbeFailureAfterHBfailedCnt); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n", + pMac->lim.gLimHBfailureCntInOtherStates); + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val) == eSIR_SUCCESS) + p += log_sprintf( pMac,p, "Cfg HeartBeat Threshold = %d\n", val); + + p += log_sprintf( pMac,p, "# Beacons Rcvd in HB interval # of times\n"); + + for (ind = 1; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++) + { + p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d\t\t\t\t\t\t\t\t\t\t\t%8d\n", ind, + pMac->lim.gLimHeartBeatBeaconStats[ind]); + } + p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d>\t\t\t\t\t\t\t\t\t\t%8d\n", + MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL-1, + pMac->lim.gLimHeartBeatBeaconStats[0]); + + if (arg1 != 0) + { + for (ind = 0; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++) + pMac->lim.gLimHeartBeatBeaconStats[ind] = 0; + + pMac->lim.gLimHBfailureCntInLinkEstState = 0; + pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0; + pMac->lim.gLimHBfailureCntInOtherStates = 0; + + p += log_sprintf( pMac,p, "\nReset HeartBeat Statistics\n"); + } + return p; +} + +static char * +dump_lim_edca_params( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = limDumpEdcaParams(pMac, p); + return p; +} + +static char * +dump_lim_acm_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg3; (void) arg4; + limSetEdcaBcastACMFlag(pMac, arg1 /*ac(0..3)*/, arg2 /*(acmFlag = 1 to set ACM*/); + return p; +} + +static char * +dump_lim_bgscan_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->lim.gLimForceBackgroundScanDisable = (arg1 == 0) ? 1 : 0; + p += log_sprintf( pMac,p, "Bgnd scan is now %s\n", + (pMac->lim.gLimForceBackgroundScanDisable) ? "Disabled" : "On"); + return p; +} + +static char * +dump_lim_linkmonitor_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->sys.gSysEnableLinkMonitorMode = (arg1 == 0) ? 0 : 1; + p += log_sprintf( pMac,p, "LinkMonitor mode enable = %s\n", + (pMac->sys.gSysEnableLinkMonitorMode) ? "On" : "Off"); + return p; +} + +static char * +dump_lim_proberesp_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->lim.gLimProbeRespDisableFlag = (arg1 == 0) ? 0 : 1; + p += log_sprintf( pMac,p, "ProbeResponse mode disable = %s\n", + (pMac->lim.gLimProbeRespDisableFlag) ? "On" : "Off"); + return p; +} + +static char * +dump_lim_add_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +#ifdef FIXME_GEN6 + tpDphHashNode pStaDs; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + tSirMacAddr staMac = {0}; + tANI_U16 peerIdx; + if(arg2 > 5) + goto addStaFail; + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + pStaDs = dphGetHashEntry(pMac, peerIdx); + if(NULL == pStaDs) + { + staMac[5] = (tANI_U8) arg1; + pStaDs = dphAddHashEntry(pMac, staMac, peerIdx, &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + goto addStaFail; + + pStaDs->staType = STA_ENTRY_PEER; + switch(arg2) + { + //11b station + case 0: + { + pStaDs->mlmStaContext.htCapability = 0; + pStaDs->erpEnabled = 0; + p += log_sprintf( pMac,p, "11b"); + } + break; + //11g station + case 1: + { + pStaDs->mlmStaContext.htCapability = 0; + pStaDs->erpEnabled = 1; + p += log_sprintf( pMac,p, "11g"); + } + break; + //ht20 station non-GF + case 2: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 0; + pStaDs->htGreenfield = 0; + p += log_sprintf( pMac,p, "HT20 non-GF"); + } + break; + //ht20 station GF + case 3: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 0; + pStaDs->htGreenfield = 1; + p += log_sprintf( pMac,p, "HT20 GF"); + } + break; + //ht40 station non-GF + case 4: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 1; + pStaDs->htGreenfield = 0; + p += log_sprintf( pMac,p, "HT40 non-GF"); + } + break; + //ht40 station GF + case 5: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 1; + pStaDs->htGreenfield = 1; + p += log_sprintf( pMac,p, "HT40 GF"); + } + break; + default: + { + p += log_sprintf( pMac,p, "arg2 not in range [0..3]. Station not added.\n"); + goto addStaFail; + } + break; + } + + pStaDs->added = 1; + p += log_sprintf( pMac,p, " station with mac address 00:00:00:00:00:%x added.\n", (tANI_U8)arg1); + limAddSta(pMac, pStaDs,psessionEntry); + } + else + { +addStaFail: + p += log_sprintf( pMac,p, "Could not add station\n"); + p += log_sprintf( pMac,p, "arg1: 6th byte of the station MAC address\n"); + p += log_sprintf( pMac,p, "arg2[0..5] : station type as described below\n"); + p += log_sprintf( pMac,p, "\t 0: 11b, 1: 11g, 2: HT20 non-GF, 3: HT20 GF, 4: HT40 non-GF, 5: HT40 GF\n"); + } +#endif + return p; +} + +static char * +dump_lim_del_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + tpDphHashNode pStaDs; + tLimMlmDisassocInd mlmDisassocInd; + tpPESession psessionEntry; + tANI_U8 reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + + pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable); + + if(NULL == pStaDs) + { + p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1); + return p; + } + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + p += log_sprintf( pMac,p, "received Disassoc frame from peer that is in state %X \n", pStaDs->mlmStaContext.mlmState); + return p; + } + + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; + + // Issue Disassoc Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr, + (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr)); + mlmDisassocInd.reasonCode = reasonCode; + mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC; + + mlmDisassocInd.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, (tANI_U32 *) &mlmDisassocInd); + // Receive path cleanup + limCleanupRxPath(pMac, pStaDs,psessionEntry); + return p; +} + + + + +static char * +set_lim_prot_cfg( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + +/********************************** +* Protection Enable +* +*LOWER byte for associated stations +*UPPER byte for overlapping stations. +*11g ==> protection from 11g +*11b ==> protection from 11b +*each byte will have the following info +*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +*reserved reserved RIFS Lsig n-GF ht20 11g 11b +********************************** +WNI_CFG_PROTECTION_ENABLED I 4 9 +V RW NP RESTART +LIM +0 0xff 0xff +V RW NP RESTART +LIM +0 0xffff 0xffff + +#ENUM FROM_llB 0 +#ENUM FROM_llG 1 +#ENUM HT_20 2 +#ENUM NON_GF 3 +#ENUM LSIG_TXOP 4 +#ENUM RIFS 5 +#ENUM OLBC_FROM_llB 8 +#ENUM OLBC_FROM_llG 9 +#ENUM OLBC_HT20 10 +#ENUM OLBC_NON_GF 11 +#ENUM OLBC_LSIG_TXOP 12 +#ENUM OLBC_RIFS 13 +******************************************/ + if(1 == arg1) + dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, 0xff, arg3, arg4, p); + else if(2 == arg1) + dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, arg2 & 0xff, arg3, arg4, p); + else + { + p += log_sprintf( pMac,p, "To set protection config:\n"); + p += log_sprintf( pMac,p, "arg1: operation type(1 -> set to Default 0xff, 2-> set to a arg2, else print help)\n"); + } + return p; +} + + +static char * +dump_lim_set_protection_control( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + dump_cfg_set(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, arg1, arg2, arg3, p); + limSetCfgProtection(pMac, NULL); + return p; +} + + +static char * +dump_lim_send_SM_Power_Mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirMsgQ msg; + tpSirMbMsg pMBMsg; + tSirMacHTMIMOPowerSaveState state; + + p += log_sprintf( pMac,p, "%s: Verifying the Arguments\n", __func__); + if ((arg1 > 3) || (arg1 == 2)) + { + p += log_sprintf( pMac,p, "Invalid Argument , enter one of the valid states\n"); + return p; + } + + state = (tSirMacHTMIMOPowerSaveState) arg1; + + pMBMsg = vos_mem_malloc(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState)); + if (NULL == pMBMsg) + { + p += log_sprintf( pMac,p, "pMBMsg is NULL\n"); + return p; + } + pMBMsg->type = eWNI_PMC_SMPS_STATE_IND; + pMBMsg->msgLen = (tANI_U16)(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState)); + vos_mem_copy(pMBMsg->data, &state, sizeof(tSirMacHTMIMOPowerSaveState)); + + msg.type = eWNI_PMC_SMPS_STATE_IND; + msg.bodyptr = pMBMsg; + msg.bodyval = 0; + + if (limPostMsgApi(pMac, &msg) != TX_SUCCESS) + { + p += log_sprintf( pMac,p, "Updating the SMPower Request has failed \n"); + vos_mem_free(pMBMsg); + } + else + { + p += log_sprintf( pMac,p, "Updating the SMPower Request is Done \n"); + } + + return p; +} + + + + +static char * +dump_lim_addba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tSirRetStatus status; +tpDphHashNode pSta; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + + (void) arg4; + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + status = limPostMlmAddBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U16) arg3,psessionEntry); + p += log_sprintf( pMac, p, + "\n%s: Attempted to send an ADDBA Req to STA Index %d, for TID %d. Send Status = %s\n", + __func__, + pSta->staIndex, + arg2, + limResultCodeStr( status )); + } + + return p; +} + +static char * +dump_lim_delba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tSirRetStatus status; +tpDphHashNode pSta; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + status = limPostMlmDelBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U8) arg3, (tANI_U16) arg4 ,psessionEntry); + p += log_sprintf( pMac, p, + "\n%s: Attempted to send a DELBA Ind to STA Index %d, " + "as the BA \"%s\" for TID %d, with Reason code %d. " + "Send Status = %s\n", + __func__, + pSta->staIndex, + (arg2 == 1)? "Initiator": "Recipient", + arg3, // TID + arg4, // Reason Code + limResultCodeStr( status )); + } + + return p; +} + +static char * +dump_lim_ba_timeout( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + +/* FIXME: NO HAL IN UMAC for PRIMA */ + + p += log_sprintf( pMac, p, + "\n%s: Attempted to trigger a BA Timeout Ind to STA Index %d, for TID %d, Direction %d\n", + __func__, + arg1, // STA index + arg2, // TID + arg3 ); // BA Direction + + return p; +} + +static char * +dump_lim_list_active_ba( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tANI_U32 i; +tpDphHashNode pSta; + +//TBD-RAJESH HOW TO GET sessionEntry????? + +tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH + + (void) arg2; (void) arg3; (void) arg4; + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + p += log_sprintf( pMac, p, + "\nList of Active BA sessions for STA Index %d with Assoc ID %d\n", + pSta->staIndex, + arg1 ); + + p += log_sprintf( pMac, p, "TID\tRxBA\tTxBA\tRxBufferSize\tTxBufferSize\tRxBATimeout\tTxBATimeout\n"); + for( i = 0; i < STACFG_MAX_TC; i ++ ) + p += log_sprintf( pMac, p, + "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + i, // TID + pSta->tcCfg[i].fUseBARx, + pSta->tcCfg[i].fUseBATx, + pSta->tcCfg[i].rxBufSize, + pSta->tcCfg[i].txBufSize, + pSta->tcCfg[i].tuRxBAWaitTimeout, + pSta->tcCfg[i].tuTxBAWaitTimeout ); + } + + return p; +} + + +static char * +dump_lim_AddBA_DeclineStat( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + int Tid, Enable=(arg1 & 0x1); + tANI_U8 val; + + if (arg1 > 1) { + log_sprintf( pMac,p, "%s:Invalid Value is entered for Enable/Disable \n", __func__ ); + arg1 &= 1; + } + + val = pMac->lim.gAddBA_Declined; + + if (arg2 > 7) { + log_sprintf( pMac,p, "%s:Invalid Value is entered for Tid \n", __func__ ); + Tid = arg2 & 0x7; + } else + Tid = arg2; + + + if ( Enable) + val |= Enable << Tid; + else + val &= ~(0x1 << Tid); + + if (cfgSetInt(pMac, (tANI_U16)WNI_CFG_ADDBA_REQ_DECLINE, (tANI_U32) val) != eSIR_SUCCESS) + log_sprintf( pMac,p, "%s:Config Set for ADDBA REQ Decline has failed \n", __func__ ); + + log_sprintf( pMac,p, "%s:Decline value %d is being set for TID %d ,\n \tAddBA_Decline Cfg value is %d \n", __func__ , arg1, Tid, (int) val); + + return p; +} +static char * +dump_lim_set_dot11_mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + tpPESession psessionEntry =&pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + dump_cfg_set(pMac, WNI_CFG_DOT11_MODE, arg1, arg2, arg3, p); + if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + schSetFixedBeaconFields(pMac,psessionEntry); + p += log_sprintf( pMac,p, "The Dot11 Mode is set to %s", limDot11ModeStr(pMac, (tANI_U8)psessionEntry->dot11mode)); + return p; +} + + +static char* dump_lim_update_cb_Mode(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 localPwrConstraint; + tpPESession psessionEntry = peFindSessionBySessionId(pMac, arg1); + + if (psessionEntry == NULL) + { + p += log_sprintf( pMac, p, "Invalid sessionId: %d \n ", arg1); + return p; + } + + if ( !psessionEntry->htCapability ) + { + p += log_sprintf( pMac,p, "Error: Dot11 mode is non-HT, can not change the CB mode.\n"); + return p; + } + + psessionEntry->htSupportedChannelWidthSet = arg2?1:0; + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + psessionEntry->htSecondaryChannelOffset = arg2; + + if(eSIR_SUCCESS != cfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, + arg2 ? WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE)) + p += log_sprintf(pMac,p, "cfgSetInt failed for WNI_CFG_CHANNEL_BONDING_MODE\n"); + + wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint); + + limSendSwitchChnlParams(pMac, psessionEntry->currentOperChannel, psessionEntry->htSecondaryChannelOffset, + (tPowerdBm) localPwrConstraint, psessionEntry->peSessionId); + if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + schSetFixedBeaconFields(pMac,psessionEntry); + return p; + +} + +static char* dump_lim_abort_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + //csrScanAbortMacScan(pMac); + return p; + +} + +static char* dump_lim_start_stop_bg_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + } + + if(arg1 == 1) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + else + { + pMac->lim.gLimBackgroundScanTerminate = FALSE; + pMac->lim.gLimBackgroundScanDisable = false; + pMac->lim.gLimForceBackgroundScanDisable = false; + } + } + else + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + pMac->lim.gLimBackgroundScanChannelId = 0; + pMac->lim.gLimBackgroundScanDisable = true; + pMac->lim.gLimForceBackgroundScanDisable = true; + } + return p; + +} + +static char* +dump_lim_get_pe_statistics(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpAniGetPEStatsReq pReq; + tANI_U32 statsMask; + + (void) arg2; (void) arg3; (void) arg4; + + + switch(arg1) + { + case 1: + statsMask = PE_SUMMARY_STATS_INFO; + break; + case 2: + statsMask = PE_GLOBAL_CLASS_A_STATS_INFO; + break; + case 3: + statsMask = PE_GLOBAL_CLASS_B_STATS_INFO; + break; + case 4: + statsMask = PE_GLOBAL_CLASS_C_STATS_INFO; + break; + case 5: + statsMask = PE_PER_STA_STATS_INFO; + break; + default: + return p; + } + + pReq = vos_mem_malloc(sizeof(tAniGetPEStatsReq)); + if (NULL == pReq) + { + p += log_sprintf( pMac,p, "Error: Unable to allocate memory.\n"); + return p; + } + + vos_mem_set(pReq, sizeof(*pReq), 0); + + pReq->msgType = eWNI_SME_GET_STATISTICS_REQ; + pReq->statsMask = statsMask; + pReq->staId = (tANI_U16)arg2; + + pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE; + limPostSmeMessage(pMac, eWNI_SME_GET_STATISTICS_REQ, (tANI_U32 *) pReq); + + return p; + +} + +extern char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level ); +static char * +dump_lim_set_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + p = setLOGLevel(pMac, p, arg1, arg2); + return p; +} + +static char * +dump_lim_update_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + vos_trace_setLevel( arg1, arg2 ); + return p; +} + +static char * +dump_lim_scan_req_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeScanReq(pMac, p); + return p; +} + +static char * +dump_lim_send_start_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeStartBssReq(pMac, p,arg1); + return p; +} + +static char * +dump_lim_send_join_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeJoinReq(pMac, p); + return p; +} + +static char * +dump_lim_send_disassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + p = sendSmeDisAssocReq(pMac, p, arg1 ,arg2); + return p; +} + +static char * +dump_lim_stop_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = sendSmeStopBssReq(pMac, p, arg1); + return p; +} + + +static char * +dump_lim_session_print( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = printSessionInfo(pMac, p); + return p; +} + +static char * +dump_lim_sme_reassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 sessionId = arg1; + tCsrRoamModifyProfileFields modifyProfileFields; + tANI_U32 roamId; + + (void) arg2; (void) arg3; (void) arg4; + + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + csrReassoc( pMac, sessionId, &modifyProfileFields, &roamId, 0); + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + else + { + p += log_sprintf( pMac,p, "Invalid session = %d\n", sessionId); + } + + return p; +} + +static char * +dump_lim_dot11h_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + return p; +} + +static char * +dump_lim_enable_measurement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (arg1) + { + pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE; + p += log_sprintf(pMac, p, "Measurement enabled\n"); + } + else + { + pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_FALSE; + p += log_sprintf(pMac, p, "Measurement disabled\n"); + } + + return p; +} + +static char * +dump_lim_enable_quietIE( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + return p; +} + +static char * +dump_lim_disable_enable_scan( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (arg1) + { + pMac->lim.fScanDisabled = 1; + p += log_sprintf(pMac, p, "Scan disabled\n"); + } + else + { + pMac->lim.fScanDisabled = 0; + p += log_sprintf(pMac, p, "scan enabled\n"); + } + + return p; +} + +static char *finishScan(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + + p += log_sprintf( pMac,p, "logDump finishScan \n"); + + msg.type = SIR_LIM_MIN_CHANNEL_TIMEOUT; + msg.bodyval = 0; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); + return p; +} + + +static char * +dump_lim_info( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = dumpLim( pMac, p, arg1); + return p; +} + +static char * +dump_lim_finishscan_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = finishScan(pMac, p); + return p; +} + +static char * +dump_lim_prb_rsp_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = testLimSendProbeRsp( pMac, p ); + return p; +} + +static char * +dump_sch_beacon_trigger( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = triggerBeaconGen(pMac, p); + return p; +} + +static char* dump_lim_set_scan_in_powersave( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + p += log_sprintf( pMac,p, "logDump set scan in powersave to %d \n", arg1); + dump_cfg_set(pMac, WNI_CFG_SCAN_IN_POWERSAVE, arg1, arg2, arg3, p); + return p; +} + +#if defined WLAN_FEATURE_VOWIFI +static char * +dump_lim_send_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tSirMacRadioMeasureReport *pRRMReport = + vos_mem_malloc(4*sizeof(tSirMacRadioMeasureReport)); + tANI_U8 num = (tANI_U8)(arg4 > 4 ? 4 : arg4); + tANI_U8 i; + + if (!pRRMReport) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + goto done; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + goto done; + } + switch (arg3) + { + case 0: + /* send two reports with incapable bit set */ + pRRMReport[0].type = 6; + pRRMReport[1].type = 7; + limSendRadioMeasureReportActionFrame( pMac, 1, 2, &pRRMReport[0], psessionEntry->bssId, psessionEntry ); + break; + case 1: + for ( i = 0 ; i < num ; i++ ) + { + pRRMReport[i].type = 5; + if ( i == 3 ) + pRRMReport[i].refused = 1; + else + pRRMReport[i].refused = 0; + + pRRMReport[i].report.beaconReport.regClass = 32; + pRRMReport[i].report.beaconReport.channel = i; + pRRMReport[i].report.beaconReport.measDuration = 23; + pRRMReport[i].report.beaconReport.phyType = i << 4; //some value. + pRRMReport[i].report.beaconReport.bcnProbeRsp = 1; + pRRMReport[i].report.beaconReport.rsni = 10; + pRRMReport[i].report.beaconReport.rcpi = 40; + + pRRMReport[i].report.beaconReport.bssid[0] = 0x00; + pRRMReport[i].report.beaconReport.bssid[1] = 0xAA; + pRRMReport[i].report.beaconReport.bssid[2] = 0xBB; + pRRMReport[i].report.beaconReport.bssid[3] = 0xCC; + pRRMReport[i].report.beaconReport.bssid[4] = 0x00; + pRRMReport[i].report.beaconReport.bssid[5] = 0x01 << i; + + + pRRMReport[i].report.beaconReport.antennaId = 10; + pRRMReport[i].report.beaconReport.parentTSF = 0x1234; + + pRRMReport[i].report.beaconReport.numIes = i * 10; + { + tANI_U8 j; + for( j = 0; j < pRRMReport[i].report.beaconReport.numIes ; j++ ) + { + pRRMReport[i].report.beaconReport.Ies[j] = j + i; //Junk values. + } + } + + } + limSendRadioMeasureReportActionFrame( pMac, 1, num, &pRRMReport[0], psessionEntry->bssId, psessionEntry ); + break; + case 2: + //send Neighbor request. + { + tSirMacNeighborReportReq neighbor; + neighbor.dialogToken = 2; + neighbor.ssid_present = (tANI_U8) arg4; + neighbor.ssid.length = 5; + vos_mem_copy(neighbor.ssid.ssId, "abcde", 5); + + limSendNeighborReportRequestFrame( pMac, &neighbor, psessionEntry->bssId, psessionEntry ); + + } + + break; + case 3: + //send Link measure report. + { + tSirMacLinkReport link; + link.dialogToken = 4; + link.txPower = 34; + link.rxAntenna = 2; + link.txAntenna = 1; + link.rcpi = 9; + link.rsni = 3; + limSendLinkReportActionFrame( pMac, &link, psessionEntry->bssId, psessionEntry ); + } + break; + default: + break; + } + +done: + vos_mem_free(pRRMReport); + return p; +} + +static char * +dump_lim_unpack_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U32 status; + + tANI_U8 size[] = { + 0x2C, + 0x2F, + 0x25, + 0x2C, + 0x1C, + 0x05 + }; + + tANI_U8 pBody[][100] = { + { + /*Beacon Request 0*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x25, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x01, 0x30, 0x00, 0x14, 0x00, 0x01, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD + }, + { + /*Beacon Request 1*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x28, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0xFF, 0x30, 0x00, 0x14, 0x00, 0x01, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID +/* 0x00, 0x08, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, */ + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD, + //AP channel report + 0x33, 0x03, 0x0C, 0x01, 0x06, + 0x33, 0x03, 0x0C, 0x24, 0x30, + }, + { + /*Beacon Request 2*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x1E, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x00, 0x30, 0x00, 0x14, 0x00, 0x02, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //0x00, 0x08, 0x41, 0x53, 0x54, 0x2D, 0x57, 0x41, 0x50, 0x49, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x0 + //Request IE + }, + { + /*Beacon Request 3*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x25, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x01, 0x30, 0x00, 0x69, 0x00, 0x00, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD + }, + { + /*Neighbor report*/ + 0x05, 0x05, 0x01, + //Measurement request IE + 0x34, 0x17, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //BSSID INFOo + 0xED, 0x01, 0x00, 0x00, + //Reg class, channel, Phy type + 0x20, 0x01, 0x02, + //TSF Info + 0x01, 0x04, 0x02, 0x00, 0x60, 0x00, + //Condensed country + 0x02, 0x02, 0x62, 0x63 + }, + { + /* Link measurement request */ + 0x05, 0x02, 0x00, + //Txpower used + 0x00, + //Max Tx Power + 0x00 + } + }; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + switch (arg2) + { + case 0: + case 1: + case 2: + case 3: + { + tDot11fRadioMeasurementRequest *frm = + vos_mem_malloc(sizeof(tDot11fRadioMeasurementRequest)); + if (!frm) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + break; + } + if( (status = dot11fUnpackRadioMeasurementRequest( pMac, &pBody[arg2][0], size[arg2], frm )) != 0 ) + p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status); + else + rrmProcessRadioMeasurementRequest( pMac, psessionEntry->bssId, frm, psessionEntry ); + vos_mem_free(frm); + } + break; + case 4: + { + tDot11fNeighborReportResponse *frm = + vos_mem_malloc(sizeof(tDot11fNeighborReportResponse)); + if (!frm) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + break; + } + pBody[arg2][2] = (tANI_U8)arg3; //Dialog Token + if( (status = dot11fUnpackNeighborReportResponse( pMac, &pBody[arg2][0], size[arg2], frm )) != 0 ) + p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status); + else + rrmProcessNeighborReportResponse( pMac, frm, psessionEntry ); + vos_mem_free(frm); + } + break; + case 5: + { +// FIXME. + } + break; + case 6: + { + tPowerdBm localConstraint = (tPowerdBm) arg3; + tPowerdBm maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + maxTxPower = VOS_MIN( maxTxPower, maxTxPower-localConstraint ); + if( maxTxPower != psessionEntry->maxTxPower ) + { + rrmSendSetMaxTxPowerReq( pMac, maxTxPower, psessionEntry ); + psessionEntry->maxTxPower = maxTxPower; + } + } + break; + default: + p += log_sprintf( pMac, p, "Invalid option" ); + break; + } + return p; +} +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#ifdef RSSI_HACK +/* This dump command is needed to set the RSSI values in TL while testing handoff. Handoff code was tested + * using this dump command. Whatever the value gives as the first parameter will be considered as the average + * RSSI by TL and invokes corresponding callback registered by the clients */ +extern int dumpCmdRSSI; +static char * +dump_lim_set_tl_data_pkt_rssi( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + dumpCmdRSSI = arg1; + limLog(pMac, LOGE, FL("Setting TL data packet RSSI to %d"), dumpCmdRSSI); + return p; +} +#endif +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +/* This command is used to trigger FT Preauthentication with the AP with BSSID below */ +static char * +dump_lim_ft_event( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + static tANI_U8 macAddr[6] = {0x00, 0xde, 0xad, 0xaf, 0xaf, 0x04}; + tpPESession psessionEntry; + tSirMsgQ msg; + tpSirFTPreAuthReq pftPreAuthReq; + tANI_U16 auth_req_len = 0; + tCsrRoamConnectedProfile Profile; + tANI_U32 smeSessionId = arg2; + + if (!CSR_IS_SESSION_VALID( pMac, smeSessionId )) + { + p += log_sprintf( pMac, p, "smeSessionId is not valid\n"); + return p; + } + + csrRoamCopyConnectProfile(pMac, arg2, &Profile); + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + return p; + } + + switch (arg1) + { + case 0: + // Send Pre-auth event + { + /*----------------*/ + p += log_sprintf( pMac,p, "Preparing Pre Auth Req message\n"); + auth_req_len = sizeof(tSirFTPreAuthReq); + + pftPreAuthReq = vos_mem_malloc(auth_req_len); + if (NULL == pftPreAuthReq) + { + p += log_sprintf( pMac, p, + "Pre auth dump: AllocateMemory() failed \n"); + return p; + } + pftPreAuthReq->pbssDescription = + vos_mem_malloc(sizeof(Profile.pBssDesc->length)+ + Profile.pBssDesc->length); + + pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ; + pftPreAuthReq->length = + auth_req_len + sizeof(Profile.pBssDesc->length) + + Profile.pBssDesc->length; + pftPreAuthReq->preAuthchannelNum = 6; + + vos_mem_copy((void *) &pftPreAuthReq->currbssId, + (void *)psessionEntry->bssId, 6); + vos_mem_copy((void *) &pftPreAuthReq->preAuthbssId, + (void *)macAddr, 6); + pftPreAuthReq->ft_ies_length = + (tANI_U16)pMac->roam.roamSession[smeSessionId].ftSmeContext.auth_ft_ies_length; + + // Also setup the mac address in sme context. + vos_mem_copy( + pMac->roam.roamSession[smeSessionId].ftSmeContext.preAuthbssId, + macAddr, 6); + + vos_mem_copy(pftPreAuthReq->ft_ies, + pMac->roam.roamSession[smeSessionId].ftSmeContext.auth_ft_ies, + pMac->roam.roamSession[smeSessionId].ftSmeContext.auth_ft_ies_length); + + vos_mem_copy(Profile.pBssDesc->bssId, macAddr, 6); + + p += log_sprintf( pMac, p, + "\n ----- LIM Debug Information ----- \n"); + p += log_sprintf( pMac, p, "%s: length = %d\n", __func__, + (int)pMac->roam.roamSession[smeSessionId].ftSmeContext.auth_ft_ies_length); + p += log_sprintf( pMac, p, "%s: length = %02x\n", __func__, + (int)pMac->roam.roamSession[smeSessionId].ftSmeContext.auth_ft_ies[0]); + p += log_sprintf( pMac, p, "%s: Auth Req %02x %02x %02x\n", + __func__, pftPreAuthReq->ft_ies[0], + pftPreAuthReq->ft_ies[1], pftPreAuthReq->ft_ies[2]); + + p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x\n", __func__, + psessionEntry->bssId[0], + psessionEntry->bssId[1], psessionEntry->bssId[2]); + p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x %p\n", + __func__, + pftPreAuthReq->currbssId[0], + pftPreAuthReq->currbssId[1], + pftPreAuthReq->currbssId[2], pftPreAuthReq); + + Profile.pBssDesc->channelId = (tANI_U8)arg3; + vos_mem_copy((void *)pftPreAuthReq->pbssDescription, + (void *)Profile.pBssDesc, + Profile.pBssDesc->length); + + msg.type = eWNI_SME_FT_PRE_AUTH_REQ; + msg.bodyptr = pftPreAuthReq; + msg.bodyval = 0; + + p += log_sprintf(pMac, p, + "limPostMsgApi(eWNI_SME_FT_PRE_AUTH_REQ) \n"); + limPostMsgApi(pMac, &msg); + } + break; + + default: + break; + } + return p; +} +#endif +static char * +dump_lim_channel_switch_announcement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U8 nMode = arg2; + tANI_U8 nNewChannel = arg3; + tANI_U8 nCount = arg4; + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + + limSendChannelSwitchMgmtFrame( pMac, peer, nMode, nNewChannel, nCount, psessionEntry ); + + psessionEntry->gLimChannelSwitch.switchCount = nCount; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + psessionEntry->gLimChannelSwitch.switchMode = nMode; + psessionEntry->gLimChannelSwitch.primaryChannel = nNewChannel; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +#ifdef WLAN_FEATURE_11AC +static char * +dump_lim_vht_opmode_notification(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tANI_U8 nMode = arg2; + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 366 <0> sessionid channel \n"); + return p; + } + + limSendVHTOpmodeNotificationFrame(pMac, peer, nMode,psessionEntry); + + psessionEntry->gLimOperatingMode.present = 1; + psessionEntry->gLimOperatingMode.chanWidth = nMode; + psessionEntry->gLimOperatingMode.rxNSS = 0; + psessionEntry->gLimOperatingMode.rxNSSType = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +static char * +dump_lim_vht_channel_switch_notification(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U8 nChanWidth = arg2; + tANI_U8 nNewChannel = arg3; + tANI_U8 ncbMode = arg4; + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 367 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + + limSendVHTChannelSwitchMgmtFrame( pMac, peer, nChanWidth, nNewChannel, (ncbMode+1), psessionEntry ); + + psessionEntry->gLimChannelSwitch.switchCount = 0; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + psessionEntry->gLimChannelSwitch.switchMode = 1; + psessionEntry->gLimChannelSwitch.primaryChannel = nNewChannel; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = nChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = limGetCenterChannel(pMac,nNewChannel,(ncbMode+1),nChanWidth); + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +#endif +static char * +dump_lim_cancel_channel_switch_announcement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + psessionEntry->gLimChannelSwitch.switchCount = 0; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT; + psessionEntry->gLimChannelSwitch.switchMode = 0; + psessionEntry->gLimChannelSwitch.primaryChannel = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + + +static char * +dump_lim_mcc_policy_maker(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL, "dump_lim_mcc_policy_maker arg = %d",arg1); + + if(arg1 == 0) //Disable feature completely + { + WDA_TrafficStatsTimerActivate(FALSE); + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, FALSE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not get WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + } + else if(arg1 == 1) //Enable feature + { + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + } + else if(arg1 == 2) //Enable feature and activate periodic timer + { + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + WDA_TrafficStatsTimerActivate(TRUE); + } + else if(arg1 == 3) //Enable only stats collection - Used for unit testing + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL, "Enabling Traffic Stats in DTS"); + WDI_DS_ActivateTrafficStats(); + } + else if(arg1 == 4) //Send current stats snapshot to Riva -- Used for unit testing + { + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *pWDA = vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, NULL, eANI_BOOLEAN_FALSE); + if(pWDA != NULL) + { + WDA_TimerTrafficStatsInd(pWDA); + } + WDA_TrafficStatsTimerActivate(FALSE); + ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, FALSE,NULL, eANI_BOOLEAN_FALSE); + } + else if (arg1 == 5) //Change the periodicity of TX stats timer + { + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *pWDA = vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + if (pWDA != NULL && tx_timer_change(&pWDA->wdaTimers.trafficStatsTimer, arg2/10, arg2/10) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Disable timer before changing timeout value")); + } + } + return p; +} + +#ifdef WLANTL_DEBUG +/* API to print number of pkts received based on rate index */ +/* arg1 = station Id */ +/* arg2 = BOOLEAN value to either or not flush the counters */ +static char * +dump_lim_get_pkts_rcvd_per_rate_idx( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + /* if anything other than 1, then we need not flush the counters */ + if( arg2 != 1) + arg2 = FALSE; + + WLANTLPrintPktsRcvdPerRateIdx(pMac->roam.gVosContext, (tANI_U8)arg1, (v_BOOL_t)arg2); + return p; +} + +/* API to print number of pkts received based on rssi */ +/* arg1 = station Id */ +/* arg2 = BOOLEAN value to either or not flush the counters */ +static char * +dump_lim_get_pkts_rcvd_per_rssi_values( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + /* if anything other than 1, then we need not flush the counters */ + if( arg2 != 1) + arg2 = FALSE; + + WLANTLPrintPktsRcvdPerRssi(pMac->roam.gVosContext, (tANI_U8)arg1, (v_BOOL_t)arg2); + return p; +} +#endif + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +static char * +dump_send_plm_start(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirPlmReq pPlmRequest = NULL; + + pPlmRequest = vos_mem_malloc(sizeof(tSirPlmReq)); + if (NULL == pPlmRequest){ + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,"dump allocating PLM struct failed"); + return p; + } + + pPlmRequest->diag_token = 0x5; + pPlmRequest->meas_token = 0x4; + pPlmRequest->numBursts = 2; + pPlmRequest->burstInt = 10; + pPlmRequest->measDuration = 20; + pPlmRequest->burstLen = 1; + pPlmRequest->desiredTxPwr = 12; + pPlmRequest->macAddr[0] = 0xff; + pPlmRequest->macAddr[1] = 0xff; + pPlmRequest->macAddr[2] = 0xff; + pPlmRequest->macAddr[3] = 0xff; + pPlmRequest->macAddr[4] = 0xff; + pPlmRequest->macAddr[5] = 0xff; + pPlmRequest->plmNumCh = 0; + pPlmRequest->sessionId = 0; + pPlmRequest->enable = 1; + + status = sme_SetPlmRequest((tHalHandle)pMac, pPlmRequest); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,"dump sending PLM command failed"); + vos_mem_free(pPlmRequest); + pPlmRequest = NULL; + return p; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,"dump sending PLM command is SUCCESS"); + return p; +} +#endif + +static char * +dump_set_max_probe_req(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + if ((arg1 <= 0) || (arg1 > 4)){ + limLog(pMac, LOGE, + FL("invalid number. valid range 1 - 4 \n")); + return p; + } + pMac->lim.maxProbe = arg1; + return p; +} + +static tDumpFuncEntry limMenuDumpTable[] = { + {0, "PE (300-499)", NULL}, + {300, "LIM: Dump state(s)/statistics ", dump_lim_info}, + {301, "PE.LIM: dump TSPEC Table", dump_lim_tspec_table}, + {302, "PE.LIM: dump specified TSPEC entry (id)", dump_lim_tspec_entry}, + {303, "PE.LIM: dump EDCA params", dump_lim_edca_params}, + {304, "PE.LIM: dump DPH table summary", dump_lim_dph_table_summary}, + {305, "PE.LIM: dump link monitor stats", dump_lim_link_monitor_stats}, + {306, "PE.LIM:dump Set the BAR Decline stat(arg1= 1/0 (enable/disable) arg2 =TID", dump_lim_AddBA_DeclineStat}, + {307, "PE: LIM: dump CSR Send ReAssocReq", dump_lim_sme_reassoc_req}, + {308, "PE:LIM: dump all 11H related data", dump_lim_dot11h_stats}, + {309, "PE:LIM: dump to enable Measurement on AP", dump_lim_enable_measurement}, + {310, "PE:LIM: dump to enable QuietIE on AP", dump_lim_enable_quietIE}, + {311, "PE:LIM: disable/enable scan 1(disable)", dump_lim_disable_enable_scan}, + {320, "PE.LIM: send sme scan request", dump_lim_scan_req_send}, + + + /*FIXME_GEN6*/ + /* This dump command is more of generic dump cmd and hence it should + * be moved to logDump.c + */ + {321, "PE:LIM: Set Log Level ", dump_lim_update_log_level}, + {331, "PE.LIM: Send finish scan to LIM", dump_lim_finishscan_send}, + {332, "PE.LIM: force probe rsp send from LIM", dump_lim_prb_rsp_send}, + {333, "PE.SCH: Trigger to generate a beacon", dump_sch_beacon_trigger}, + {335, "PE.LIM: set ACM flag (0..3)", dump_lim_acm_set}, + {336, "PE.LIM: Send an ADDBA Req to peer MAC arg1=aid,arg2=tid, arg3=ssn", dump_lim_addba_req}, + {337, "PE.LIM: Send a DELBA Ind to peer MAC arg1=aid,arg2=recipient(0)/initiator(1),arg3=tid,arg4=reasonCode", dump_lim_delba_req}, + {338, "PE.LIM: Trigger a BA timeout for STA index", dump_lim_ba_timeout}, + {339, "PE.LIM: List active BA session(s) for AssocID", dump_lim_list_active_ba}, + {340, "PE.LIM: Set background scan flag (0-disable, 1-enable)",dump_lim_bgscan_toggle}, + {341, "PE.LIM: Set link monitoring mode", dump_lim_linkmonitor_toggle}, + {342, "PE.LIM: AddSta <6th byte of station Mac>", dump_lim_add_sta}, + {343, "PE.LIM: DelSta ", dump_lim_del_sta}, + {344, "PE.LIM: Set probe respond flag", dump_lim_proberesp_toggle}, + {345, "PE.LIM: set protection config bitmap", set_lim_prot_cfg}, + {346, "PE:LIM: Set the Dot11 Mode", dump_lim_set_dot11_mode}, + {347, "PE:Enable or Disable Protection", dump_lim_set_protection_control}, + {348, "PE:LIM: Send SM Power Mode Action frame", dump_lim_send_SM_Power_Mode}, + {349, "PE: LIM: Change CB Mode ",dump_lim_update_cb_Mode}, + {350, "PE: LIM: abort scan", dump_lim_abort_scan}, + {351, "PE: LIM: Start stop BG scan", dump_lim_start_stop_bg_scan}, + {352, "PE: LIM: PE statistics ", dump_lim_get_pe_statistics}, + {353, "PE: LIM: Set MAC log level ", dump_lim_set_log_level}, + {354, "PE: LIM: Set Scan in Power Save <0-disable, 1-enable>", dump_lim_set_scan_in_powersave}, + {355, "PE.LIM: send sme start BSS request", dump_lim_send_start_bss_req}, + {356, "PE.LIM: dump pesession info ", dump_lim_session_print}, + {357, "PE.LIM: send DisAssocRequest", dump_lim_send_disassoc_req}, + {358, "PE.LIM: send sme stop bss request ", dump_lim_stop_bss_req}, + {359, "PE.LIM: send sme join request", dump_lim_send_join_req}, +#if defined WLAN_FEATURE_VOWIFI + {360, "PE.LIM: send an RRM action frame", dump_lim_send_rrm_action}, + {361, "PE.LIM: unpack an RRM action frame", dump_lim_unpack_rrm_action}, +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#ifdef RSSI_HACK + {362, "TL Set current RSSI", dump_lim_set_tl_data_pkt_rssi}, +#endif +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + {363, "PE.LIM: trigger pre auth/reassoc event", dump_lim_ft_event}, +#endif + {364, "PE.LIM: Send a channel switch announcement", dump_lim_channel_switch_announcement}, + {365, "PE.LIM: Cancel channel switch announcement", dump_lim_cancel_channel_switch_announcement}, +#ifdef WLAN_FEATURE_11AC + {366, "PE.LIM: Send a VHT OPMode Action Frame", dump_lim_vht_opmode_notification}, + {367, "PE.LIM: Send a VHT Channel Switch Announcement", dump_lim_vht_channel_switch_notification}, + {368, "PE.LIM: MCC Policy Maker", dump_lim_mcc_policy_maker}, +#endif +#ifdef WLANTL_DEBUG + {369, "PE.LIM: pkts/rateIdx: iwpriv wlan0 dump 369 ", dump_lim_get_pkts_rcvd_per_rate_idx}, + {370, "PE.LIM: pkts/rssi: : iwpriv wlan0 dump 370 ", dump_lim_get_pkts_rcvd_per_rssi_values}, +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + {372, "PE.LIM: send PLM start command Usage: iwpriv wlan0 372", dump_send_plm_start }, +#endif + {376, "PE.LIM: max number of probe per scan", dump_set_max_probe_req }, +}; + + + +void limDumpInit(tpAniSirGlobal pMac) +{ + logDumpRegisterTable( pMac, &limMenuDumpTable[0], + sizeof(limMenuDumpTable)/sizeof(limMenuDumpTable[0]) ); +} + + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limP2P.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limP2P.c new file mode 100644 index 0000000000000..91b2e9849775d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limP2P.c @@ -0,0 +1,1233 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + L I M _ P 2 P . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Protocol Engine for + P2P. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2011-05-02 djindal Corrected file indentation and changed remain on channel + handling for concurrency. +===========================================================================*/ + + +#include "limUtils.h" +#include "limSessionUtils.h" +#include "wlan_qct_wda.h" + +#define PROBE_RSP_IE_OFFSET 36 +#define BSSID_OFFSET 16 +#define ADDR2_OFFSET 10 +#define ACTION_OFFSET 24 + +/* A DFS channel can be ACTIVE for max 9000 msec, from the last + received Beacon/Prpbe Resp. */ +#define MAX_TIME_TO_BE_ACTIVE_CHANNEL 9000 + + + +void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data); +void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); +void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); +extern tSirRetStatus limSetLinkState( + tpAniSirGlobal pMac, tSirLinkState state, + tSirMacAddr bssId, tSirMacAddr selfMacAddr, + tpSetLinkStateCallback callback, void *callbackArg); + +static tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession); +eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess); +/*------------------------------------------------------------------ + * + * Below function is callback function, it is called when + * WDA_SET_LINK_STATE_RSP is received from WDI. callback function for + * P2P of limSetLinkState + * + *------------------------------------------------------------------*/ +void limSetLinkStateP2PCallback(tpAniSirGlobal pMac, void *callbackArg, + bool status) +{ + //Send Ready on channel indication to SME + if(pMac->lim.gpLimRemainOnChanReq) + { + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RDY_IND, eHAL_STATUS_SUCCESS, + pMac->lim.gpLimRemainOnChanReq->sessionId, 0); + } + else + { + //This is possible in case remain on channel is aborted + limLog( pMac, LOGE, FL(" NULL pointer of gpLimRemainOnChanReq") ); + } +} + +/*------------------------------------------------------------------ + * + * Below function is called if pMac->fP2pListenOffload enabled and hdd + * requests a remain on channel. + * + *------------------------------------------------------------------*/ +static eHalStatus limSendHalReqRemainOnChanOffload(tpAniSirGlobal pMac, + tSirRemainOnChnReq *pRemOnChnReq) +{ + tSirScanOffloadReq *pScanOffloadReq; + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + tANI_U8 bssid[SIR_MAC_ADDR_LENGTH] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + pScanOffloadReq = vos_mem_malloc(sizeof(tSirScanOffloadReq)); + if (NULL == pScanOffloadReq) + { + limLog(pMac, LOGE, + FL("Memory allocation failed for pScanOffloadReq")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(pScanOffloadReq, sizeof(tSirScanOffloadReq)); + + msg.type = WDA_START_SCAN_OFFLOAD_REQ; + msg.bodyptr = pScanOffloadReq; + msg.bodyval = 0; + + vos_mem_copy((tANI_U8 *) pScanOffloadReq->selfMacAddr, + (tANI_U8 *) pRemOnChnReq->selfMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy((tANI_U8 *) pScanOffloadReq->bssId, + (tANI_U8 *) bssid, + sizeof(tSirMacAddr)); + pScanOffloadReq->scanType = eSIR_PASSIVE_SCAN; + pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_LISTEN; + pScanOffloadReq->minChannelTime = pRemOnChnReq->duration; + pScanOffloadReq->maxChannelTime = pRemOnChnReq->duration; + pScanOffloadReq->sessionId = pRemOnChnReq->sessionId; + pScanOffloadReq->channelList.numChannels = 1; + pScanOffloadReq->channelList.channelNumber[0] = pRemOnChnReq->chnNum; + + limLog(pMac, LOG1, + FL("Req-rem-on-channel: duration %u, session %hu, chan %hu"), + pRemOnChnReq->duration, pRemOnChnReq->sessionId, + pRemOnChnReq->chnNum); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure %u"), + rc); + vos_mem_free(pScanOffloadReq); + return eHAL_STATUS_FAILURE; + } + + pMac->lim.fOffloadScanPending = 1; + pMac->lim.fOffloadScanP2PListen = 1; + + return eHAL_STATUS_SUCCESS; +} + +/*------------------------------------------------------------------ + * + * Remain on channel req handler. Initiate the INIT_SCAN, CHN_CHANGE + * and SET_LINK Request from SME, chnNum and duration to remain on channel. + * + *------------------------------------------------------------------*/ +int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + + /* CONC_OPER_AND_LISTEN_CHNL_SAME_OPTIMIZE - Currently removed the special optimization when a concurrent session + * exists with operating channel same as P2P listen channel since it was causing issues in P2P search. The reason was + * STA-AP link entering BMPS when returning to home channel causing P2P search to miss Probe Reqs and hence not + * respond with Probe Rsp causing peer device to NOT find us. + * If we need this optimization, we need to find a way to keep the STA-AP link awake (no BMPS) on home channel when in listen state + */ +#ifdef CONC_OPER_AND_LISTEN_CHNL_SAME_OPTIMIZE + tANI_U8 i; + tpPESession psessionEntry; +#endif + + tSirRemainOnChnReq *MsgBuff = (tSirRemainOnChnReq *)pMsg; + pMac->lim.gpLimRemainOnChanReq = MsgBuff; + + if (pMac->fP2pListenOffload) + { + eHalStatus status; + + status = limSendHalReqRemainOnChanOffload(pMac, MsgBuff); + if (status != eHAL_STATUS_SUCCESS) + { + /* Post the meessage to Sme */ + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, status, + MsgBuff->sessionId, 0); + vos_mem_free(pMac->lim.gpLimRemainOnChanReq); + pMac->lim.gpLimRemainOnChanReq = NULL; + } + return FALSE; + } + +#ifdef CONC_OPER_AND_LISTEN_CHNL_SAME_OPTIMIZE + for (i =0; i < pMac->lim.maxBssId;i++) + { + psessionEntry = peFindSessionBySessionId(pMac,i); + + if ( (psessionEntry != NULL) ) + { + if (psessionEntry->currentOperChannel == MsgBuff->chnNum) + { + tANI_U32 val; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + pMac->lim.gTotalScanDuration = MsgBuff->duration; + + /* get the duration from the request */ + val = SYS_MS_TO_TICKS(MsgBuff->duration); + + limLog( pMac, LOG2, "Start listen duration = %d", val); + if (tx_timer_change( + &pMac->lim.limTimers.gLimRemainOnChannelTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change remain on channel Timer val")); + goto error; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate remain on channel Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); + goto error; + } + + + if ((limSetLinkState(pMac, MsgBuff->isProbeRequestAllowed? + eSIR_LINK_LISTEN_STATE:eSIR_LINK_SEND_ACTION_STATE, + nullBssid, pMac->lim.gSelfMacAddr, + limSetLinkStateP2PCallback, NULL)) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + goto error; + } + return FALSE; + } + } + } +#endif + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + pMac->lim.gLimMlmState = eLIM_MLM_P2P_LISTEN_STATE; + + pMac->lim.gTotalScanDuration = MsgBuff->duration; + + /* 1st we need to suspend link with callback to initiate change channel */ + limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, + limRemainOnChnlSuspendLinkHdlr, NULL); + return FALSE; + +#ifdef CONC_OPER_AND_LISTEN_CHNL_SAME_OPTIMIZE +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + /* pMsg is freed by the caller */ + return FALSE; +#endif +} + + +tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession) +{ + tSirRetStatus nSirStatus = eSIR_FAILURE; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 val; + + if(pMac->lim.gpLimRemainOnChanReq && ppP2pSession) + { + if((psessionEntry = peCreateSession(pMac, + pMac->lim.gpLimRemainOnChanReq->selfMacAddr, + &sessionId, 1, eSIR_INFRA_AP_MODE)) == NULL) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + /* send remain on chn failure */ + return nSirStatus; + } + /* Store PE sessionId in session Table */ + psessionEntry->peSessionId = sessionId; + psessionEntry->smeSessionId = pMac->lim.gpLimRemainOnChanReq->sessionId; + + psessionEntry->limSystemRole = eLIM_P2P_DEVICE_ROLE; + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + psessionEntry->rateSet.rate, val , SIR_MAC_MAX_NUMBER_OF_RATES ); + psessionEntry->rateSet.numRates = val; + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + psessionEntry->extRateSet.rate, val, + WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN ); + psessionEntry->extRateSet.numRates = val; + + sirCopyMacAddr(psessionEntry->selfMacAddr, + pMac->lim.gpLimRemainOnChanReq->selfMacAddr); + + psessionEntry->currentOperChannel = pMac->lim.gpLimRemainOnChanReq->chnNum; + nSirStatus = eSIR_SUCCESS; + *ppP2pSession = psessionEntry; + } + + return nSirStatus; +} + + +/*------------------------------------------------------------------ + * + * limSuspenLink callback, on success link suspend, trigger change chn + * + * + *------------------------------------------------------------------*/ + +tSirRetStatus limRemainOnChnlChangeChnReq(tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + tSirRetStatus nSirStatus = eSIR_FAILURE; + + if( NULL == pMac->lim.gpLimRemainOnChanReq ) + { + //RemainOnChannel may have aborted + PELOGE(limLog( pMac, LOGE, FL(" gpLimRemainOnChanReq is NULL") );) + return nSirStatus; + } + + /* The link is not suspended */ + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, FL(" Suspend link Failure ") );) + goto error; + } + + + if((psessionEntry = peFindSessionByBssid( + pMac,pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId)) != NULL) + { + goto change_channel; + } + else /* Session Entry does not exist for given BSSId */ + { + /* Try to Create a new session */ + if(eSIR_SUCCESS != limCreateSessionForRemainOnChn(pMac, &psessionEntry)) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + /* send remain on chn failure */ + goto error; + } + } + +change_channel: + /* change channel to the requested by RemainOn Chn*/ + limChangeChannelWithCallback(pMac, + pMac->lim.gpLimRemainOnChanReq->chnNum, + limRemainOnChnlSetLinkStat, NULL, psessionEntry); + return eSIR_SUCCESS; + +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return eSIR_FAILURE; +} + +void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data) +{ + limRemainOnChnlChangeChnReq(pMac, status, data); + return; +} + +/*------------------------------------------------------------------ + * + * Set the LINK state to LISTEN to allow only PROBE_REQ and Action frames + * + *------------------------------------------------------------------*/ +void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + tANI_U32 val; + tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if (status != eHAL_STATUS_SUCCESS) + { + limLog( pMac, LOGE, FL("Change channel not successful")); + goto error1; + } + + // Start timer here to come back to operating channel. + pMac->lim.limTimers.gLimRemainOnChannelTimer.sessionId = + psessionEntry->peSessionId; + pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + pMac->lim.gTotalScanDuration = MsgRemainonChannel->duration; + + /* get the duration from the request */ + val = SYS_MS_TO_TICKS(MsgRemainonChannel->duration); + + limLog( pMac, LOG2, "Start listen duration = %d", val); + if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Remain on channel Timer. Log error. + */ + limLog(pMac, LOGP, + FL("Unable to change remain on channel Timer val")); + goto error; + } + + if(TX_SUCCESS != + tx_timer_activate(&pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + limLog( pMac, LOGE, + "%s: remain on channel Timer Start Failed", __func__); + goto error; + } + + if ((limSetLinkState(pMac, MsgRemainonChannel->isProbeRequestAllowed? + eSIR_LINK_LISTEN_STATE:eSIR_LINK_SEND_ACTION_STATE,nullBssid, + pMac->lim.gSelfMacAddr, limSetLinkStateP2PCallback, + NULL)) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + goto error; + } + + return; +error: + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); +error1: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return; +} + +/*------------------------------------------------------------------ + * + * lim Insert NOA timer timeout callback - when timer fires, deactivate it and send + * scan rsp to csr/hdd + * + *------------------------------------------------------------------*/ +void limProcessInsertSingleShotNOATimeout(tpAniSirGlobal pMac) +{ + /* timeout means start NOA did not arrive; we need to deactivate and change the timer for + * future activations + */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + + /* Even if insert NOA timedout, go ahead and process/send stored SME request */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + + return; +} + +/*----------------------------------------------------------------- + * lim Insert Timer callback function to check active DFS channels + * and convert them to passive channels if there was no + * beacon/proberesp for MAX_TIME_TO_BE_ACTIVE_CHANNEL time + *------------------------------------------------------------------*/ +void limConvertActiveChannelToPassiveChannel(tpAniSirGlobal pMac ) +{ + tANI_U32 currentTime; + tANI_U32 lastTime = 0; + tANI_U32 timeDiff; + tANI_U8 i; + currentTime = vos_timer_get_system_time(); + for (i = 1; i < SIR_MAX_24G_5G_CHANNEL_RANGE ; i++) + { + if ((pMac->lim.dfschannelList.timeStamp[i]) != 0) + { + lastTime = pMac->lim.dfschannelList.timeStamp[i]; + if (currentTime >= lastTime) + { + timeDiff = (currentTime - lastTime); + } + else + { + timeDiff = (0xFFFFFFFF - lastTime) + currentTime; + } + + if (timeDiff >= MAX_TIME_TO_BE_ACTIVE_CHANNEL) + { + limCovertChannelScanType( pMac, i,FALSE); + pMac->lim.dfschannelList.timeStamp[i] = 0; + } + } + } + /* lastTime is zero if there is no DFS active channels in the list. + * If this is non zero then we have active DFS channels so restart the timer. + */ + if (lastTime != 0) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) + != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not activate Active to Passive Channel timer")); + } + } + + return; + +} + +/*------------------------------------------------------------------ + * + * limchannelchange callback, on success channel change, set the + * link_state to LISTEN + * + *------------------------------------------------------------------*/ + +void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + //Timer might get extended while Sending Action Frame + //In that case don't process Channel Timeout + if (tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + limLog( pMac, LOGE, + "still timer is running already and not processing limProcessRemainOnChnTimeout"); + return; + } + + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); + + if (NULL == pMac->lim.gpLimRemainOnChanReq) + { + limLog( pMac, LOGE, "No Remain on channel pending"); + return; + } + + /* get the previous valid LINK state */ + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + pMac->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + return; + } + + if (pMac->lim.gLimMlmState != eLIM_MLM_P2P_LISTEN_STATE ) + { + limRemainOnChnRsp(pMac,eHAL_STATUS_SUCCESS, NULL); + } + else + { + /* get the session */ + if((psessionEntry = peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimRemainOnChannelTimer.sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("Session Does not exist for given sessionID")); + goto error; + } + + limExitRemainOnChannel(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry); + return; +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + } + return; +} + + +/*------------------------------------------------------------------ + * + * limchannelchange callback, on success channel change, set the link_state + * to LISTEN + * + *------------------------------------------------------------------*/ + +void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, "Remain on Channel Failed");) + goto error; + } + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limResumeLink(pMac, limRemainOnChnRsp, NULL); + return; +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return; +} + +/*------------------------------------------------------------------ + * + * Send remain on channel respone: Success/ Failure + * + *------------------------------------------------------------------*/ +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if ( NULL == MsgRemainonChannel ) + { + PELOGE(limLog( pMac, LOGP, + "%s: No Pointer for Remain on Channel Req", __func__);) + return; + } + + //Incase of the Remain on Channel Failure Case + //Cleanup Everything + if(eHAL_STATUS_FAILURE == status) + { + //Deactivate Remain on Channel Timer + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); + + //Set the Link State to Idle + /* get the previous valid LINK state */ + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + pMac->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + } + + pMac->lim.gLimSystemInScanLearnMode = 0; + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + } + + /* delete the session */ + if((psessionEntry = peFindSessionByBssid(pMac, + MsgRemainonChannel->selfMacAddr,&sessionId)) != NULL) + { + if ( eLIM_P2P_DEVICE_ROLE == psessionEntry->limSystemRole ) + { + peDeleteSession( pMac, psessionEntry); + } + } + + /* Post the meessage to Sme */ + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, status, + MsgRemainonChannel->sessionId, 0); + + vos_mem_free(pMac->lim.gpLimRemainOnChanReq); + pMac->lim.gpLimRemainOnChanReq = NULL; + + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + + /* If remain on channel timer expired and action frame is pending then + * indicaiton confirmation with status failure */ + if (pMac->lim.mgmtFrameSessionId != 0xff) + { + limP2PActionCnf(pMac, 0); + } + + return; +} + +/*------------------------------------------------------------------ + * + * Indicate the Mgmt Frame received to SME to HDD callback + * handle Probe_req/Action frame currently + * + *------------------------------------------------------------------*/ +void limSendSmeMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, + tANI_U32 rxChannel, tpPESession psessionEntry, + tANI_S8 rxRssi) +{ + tSirMsgQ mmhMsg; + tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL; + tANI_U16 length; + + length = sizeof(tSirSmeMgmtFrameInd) + frameLen; + + pSirSmeMgmtFrame = vos_mem_malloc(length); + if (NULL == pSirSmeMgmtFrame) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for eWNI_SME_LISTEN_RSP")); + return; + } + vos_mem_set((void*)pSirSmeMgmtFrame, length, 0); + + pSirSmeMgmtFrame->mesgType = eWNI_SME_MGMT_FRM_IND; + pSirSmeMgmtFrame->mesgLen = length; + pSirSmeMgmtFrame->sessionId = sessionId; + pSirSmeMgmtFrame->frameType = frameType; + pSirSmeMgmtFrame->rxRssi = rxRssi; + + if (pMac->fP2pListenOffload) + goto send_frame; + + /* + * Work around to address LIM sending wrong channel to HDD for p2p action + * frames(In case of auto GO) recieved on 5GHz channel. + * As RXP has only 4bits to store the channel, we need some mechanism to + * to distinguish between 2.4Ghz/5GHz channel. if gLimRemainOnChannelTImer + * is not running and if we get a frame then pass the Go session + * operating channel to HDD. Some vendors create separate p2p interface + * after group formation. In that case LIM session entry will be NULL for + * p2p device address. So search for p2p go session and pass it's + * operating channel. + * Need to revisit this path in case of GO+CLIENT concurrency. + */ + if( VOS_FALSE == + tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer) ) + { + tpPESession pTempSessionEntry = psessionEntry; + if( ( (NULL != pTempSessionEntry) || + (pTempSessionEntry = limIsApSessionActive(pMac)) ) && + (SIR_BAND_5_GHZ == limGetRFBand(pTempSessionEntry->currentOperChannel)) ) + { + rxChannel = pTempSessionEntry->currentOperChannel; + } + } + + if(VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer) && + ( (psessionEntry != NULL) && (psessionEntry->pePersona != VOS_P2P_GO_MODE)) && + (frameType == SIR_MAC_MGMT_ACTION)) + { + unsigned int chanWaitTime, vStatus ; + + limLog( pMac, LOG1, FL("Rx: Extend the gLimRemainOnChannelTimer = %d "), + pMac->lim.gTotalScanDuration); + + pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + + chanWaitTime = SYS_MS_TO_TICKS(pMac->lim.gTotalScanDuration); + vStatus = tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer); + + if (VOS_STATUS_SUCCESS != vStatus) + { + limLog( pMac, LOGE, FL("Rx: Extend the gLimRemainOnChannelTimer")); + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer, chanWaitTime, 0) != TX_SUCCESS) + { + limLog( pMac, LOGE, FL("Unable to change the gLimRemainOnChannelTimer")); + } + + if (tx_timer_activate(&pMac->lim.limTimers.gLimRemainOnChannelTimer) != 0) + { + limLog( pMac, LOGE, FL("Unable to active the gLimRemainOnChannelTimer")); + } + } + else + { + if(frameType == SIR_MAC_MGMT_ACTION) + limLog( pMac, LOGE, FL("Rx: NO REMAIN ON CHANNEL and recd action frame ")); + } + +send_frame: + pSirSmeMgmtFrame->rxChan = rxChannel; + + vos_mem_zero(pSirSmeMgmtFrame->frameBuf,frameLen); + vos_mem_copy(pSirSmeMgmtFrame->frameBuf,frame,frameLen); + + mmhMsg.type = eWNI_SME_MGMT_FRM_IND; + mmhMsg.bodyptr = pSirSmeMgmtFrame; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} /*** end limSendSmeListenRsp() ***/ + + +eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess) +{ + if (pMac->lim.mgmtFrameSessionId != 0xff) + { + /* The session entry might be invalid(0xff) action confirmation received after + * remain on channel timer expired */ + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL), + pMac->lim.mgmtFrameSessionId, 0); + pMac->lim.mgmtFrameSessionId = 0xff; + } + + return eHAL_STATUS_SUCCESS; +} + + +void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tSirMbMsgP2p *pMbMsg = (tSirMbMsgP2p *)pMsg->bodyptr; + tANI_U32 nBytes; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tpSirMacFrameCtl pFc = (tpSirMacFrameCtl ) pMbMsg->data; + tANI_U8 noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + (2*SIR_P2P_IE_HEADER_LEN)]; + tANI_U8 origLen = 0; + tANI_U8 sessionId = 0; + v_U8_t *pP2PIe = NULL; + tpPESession psessionEntry = NULL; + v_U8_t *pPresenceRspNoaAttr = NULL; + v_U8_t *pNewP2PIe = NULL; + v_U16_t remainLen = 0; + tANI_U8 smeSessionId = 0; +#ifdef WLAN_FEATURE_11W + tpSirMacMgmtHdr pMacHdr; + tpSirMacActionFrameHdr pActionHdr; +#endif + + nBytes = pMbMsg->msgLen - sizeof(tSirMbMsg); + + limLog( pMac, LOG1, FL("sending pFc->type=%d pFc->subType=%d"), + pFc->type, pFc->subType); + if (pMac->fP2pListenOffload) + { + if ((!pMac->lim.gpLimRemainOnChanReq) && (0 != pMbMsg->wait)) + { + limLog(pMac, LOGE, + FL("Remain on channel is not running \n")); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + return; + } + smeSessionId = pMbMsg->sessionId; + goto send_action_frame; + } + + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + BSSID_OFFSET, &sessionId); + + /* Check for session corresponding to ADDR2 As Supplicant is filling + ADDR2 with BSSID */ + if( NULL == psessionEntry ) + { + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + ADDR2_OFFSET, &sessionId); + } + + if( NULL == psessionEntry ) + { + tANI_U8 isSessionActive = 0; + tANI_U8 i; + + /* If we are not able to find psessionEntry entry, then try to find + active session, if found any active sessions then send the + action frame, If no active sessions found then drop the frame */ + for (i =0; i < pMac->lim.maxBssId;i++) + { + psessionEntry = peFindSessionBySessionId(pMac,i); + if ( NULL != psessionEntry) + { + isSessionActive = 1; + break; + } + } + if( !isSessionActive ) + { + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + return; + } + } + + smeSessionId = psessionEntry->smeSessionId; + +send_action_frame: + if ((SIR_MAC_MGMT_FRAME == pFc->type)&& + ((SIR_MAC_MGMT_PROBE_RSP == pFc->subType)|| + (SIR_MAC_MGMT_ACTION == pFc->subType))) + { + //if this is a probe RSP being sent from wpa_supplicant + if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) + { + //get proper offset for Probe RSP + pP2PIe = limGetP2pIEPtr(pMac, + (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET, + nBytes - PROBE_RSP_IE_OFFSET); + while ((NULL != pP2PIe) && (SIR_MAC_MAX_IE_LENGTH == pP2PIe[1])) + { + remainLen = nBytes - (pP2PIe - (tANI_U8*)pMbMsg->data); + if (remainLen > 2) + { + pNewP2PIe = limGetP2pIEPtr(pMac, + pP2PIe+SIR_MAC_MAX_IE_LENGTH + 2, remainLen); + } + if (pNewP2PIe) + { + pP2PIe = pNewP2PIe; + pNewP2PIe = NULL; + } + else + { + break; + } + } //end of while + } + else + { + if (SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY == + *((v_U8_t *)pMbMsg->data+ACTION_OFFSET)) + { + tpSirMacP2PActionFrameHdr pActionHdr = + (tpSirMacP2PActionFrameHdr)((v_U8_t *)pMbMsg->data + + ACTION_OFFSET); + if (vos_mem_compare( pActionHdr->Oui, + SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE ) && + (SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP == + pActionHdr->OuiSubType)) + { //In case of Presence RSP response + pP2PIe = limGetP2pIEPtr(pMac, + (v_U8_t *)pMbMsg->data + ACTION_OFFSET + + sizeof(tSirMacP2PActionFrameHdr), + (nBytes - ACTION_OFFSET - + sizeof(tSirMacP2PActionFrameHdr))); + if( NULL != pP2PIe ) + { + //extract the presence of NoA attribute inside P2P IE + pPresenceRspNoaAttr = + limGetIEPtr(pMac,pP2PIe + SIR_P2P_IE_HEADER_LEN, + pP2PIe[1], SIR_P2P_NOA_ATTR,TWO_BYTE); + } + } + } + } + + if (pP2PIe != NULL) + { + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + //need to append NoA attribute in P2P IE + if (noaLen > 0) + { + origLen = pP2PIe[1]; + //if Presence Rsp has NoAttr + if (pPresenceRspNoaAttr) + { + v_U16_t noaAttrLen = pPresenceRspNoaAttr[1] | + (pPresenceRspNoaAttr[2]<<8); + /*One byte for attribute, 2bytes for length*/ + origLen -= (noaAttrLen + 1 + 2); + //remove those bytes to copy + nBytes -= (noaAttrLen + 1 + 2); + //remove NoA from original Len + pP2PIe[1] = origLen; + } + if ((pP2PIe[1] + (tANI_U16)noaLen)> SIR_MAC_MAX_IE_LENGTH) + { + //Form the new NoA Byte array in multiple P2P IEs + noaLen = limGetNoaAttrStreamInMultP2pIes(pMac, noaStream, + noaLen,((pP2PIe[1] + (tANI_U16)noaLen)- + SIR_MAC_MAX_IE_LENGTH)); + pP2PIe[1] = SIR_MAC_MAX_IE_LENGTH; + } + else + { + pP2PIe[1] += noaLen; //increment the length of P2P IE + } + nBytes += noaLen; + limLog( pMac, LOGE, + FL("noaLen=%d origLen=%d pP2PIe=%p" + " nBytes=%d nBytesToCopy=%zu "), + noaLen,origLen,pP2PIe,nBytes, + ((pP2PIe + origLen + 2) - (v_U8_t *)pMbMsg->data)); + } + } + + if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) + { + lim_set_ht_caps(pMac, psessionEntry, + (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET, + nBytes - PROBE_RSP_IE_OFFSET); + } + + if (pMac->fP2pListenOffload) + goto send_frame1; + + /* The minimum wait for any action frame should be atleast 100 ms. + * If supplicant sends action frame at the end of already running remain on channel time + * Then there is a chance to miss the response of the frame. So increase the remain on channel + * time for all action frame to make sure that we receive the response frame */ + if ((SIR_MAC_MGMT_ACTION == pFc->subType) && + (0 != pMbMsg->wait)) + { + if (tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + tANI_U32 val = 0; + tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer); + /* get the duration from the request */ + pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + pMac->lim.gTotalScanDuration = pMbMsg->wait; + + val = SYS_MS_TO_TICKS(pMbMsg->wait); + + limLog(pMac, LOG1, + FL("Tx: Extending the gLimRemainOnChannelTimer")); + if (tx_timer_change( + &pMac->lim.limTimers.gLimRemainOnChannelTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change remain on channel Timer val")); + return; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate remain on channel Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); + return; + } + } + else + { + limLog(pMac, LOGE, + FL("Failed to Send Action frame \n")); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + return; + } + } + } + +send_frame1: + // Ok-- try to allocate some memory: + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16)nBytes, ( void** ) &pFrame, (void**) &pPacket); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to allocate %d bytes for a Probe" + " Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set(pFrame, nBytes, 0); + + /* Add sequence number to action frames */ + /* Frames are handed over in .11 format by supplicant already */ + limPopulateP2pMacHeader(pMac, (tANI_U8*)pMbMsg->data); + + if ((noaLen > 0) && (noaLen<(SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN))) + { + // Add 2 bytes for length and Arribute field + v_U32_t nBytesToCopy = ((pP2PIe + origLen + 2 ) - + (v_U8_t *)pMbMsg->data); + vos_mem_copy(pFrame, pMbMsg->data, nBytesToCopy); + vos_mem_copy((pFrame + nBytesToCopy), noaStream, noaLen); + vos_mem_copy((pFrame + nBytesToCopy + noaLen), + pMbMsg->data + nBytesToCopy, nBytes - nBytesToCopy - noaLen); + + } + else + { + vos_mem_copy(pFrame, pMbMsg->data, nBytes); + } + +#ifdef WLAN_FEATURE_11W + pActionHdr = (tpSirMacActionFrameHdr) (pFrame + sizeof(tSirMacMgmtHdr)); + + /* + * Setting Protected bit for SA_QUERY Action Frame + * This has to be based on the current Connection with the station + * limSetProtectedBit API will set the protected bit if connection if PMF + */ + + if ((SIR_MAC_MGMT_ACTION == pFc->subType) && + (SIR_MAC_ACTION_SA_QUERY == pActionHdr->category)) + { + pMacHdr = (tpSirMacMgmtHdr ) pFrame; + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + BSSID_OFFSET, &sessionId); + + /* Check for session corresponding to ADDR2 ss supplicant is filling + ADDR2 with BSSID */ + if(NULL == psessionEntry) + { + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + ADDR2_OFFSET, &sessionId); + } + + if(NULL != psessionEntry) + { + limSetProtectedBit(pMac, psessionEntry, pMacHdr->da, pMacHdr); + } + else + { + limLog(pMac, LOGE, + FL("Dropping SA Query frame - Unable to find PE Session \n")); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + /* + * If wep bit is not set in MAC header then we are trying to + * send SA Query via non PMF connection. Drop the packet. + */ + + if(0 == pMacHdr->fc.wep) + { + limLog(pMac, LOGE, + FL("Dropping SA Query frame due to non PMF connection\n")); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + } +#endif + + /* Use BD rate 2 for all P2P related frames. As these frames need to go + * at OFDM rates. And BD rate2 we configured at 6Mbps. + */ + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + + if ( (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) || + (pMbMsg->noack) + ) + { + halstatus = halTxFrame( pMac, pPacket, (tANI_U16)nBytes, + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7, limTxComplete, pFrame, + txFlag, smeSessionId ); + + if (!pMbMsg->noack) + { + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + halstatus, pMbMsg->sessionId, 0); + } + pMac->lim.mgmtFrameSessionId = 0xff; + } + else + { + pMac->lim.mgmtFrameSessionId = pMbMsg->sessionId; + halstatus = halTxFrameWithTxComplete( pMac, pPacket, (tANI_U16)nBytes, + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7, limTxComplete, pFrame, + limP2PActionCnf, txFlag, smeSessionId, false ); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("could not send action frame!" )); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, halstatus, + pMbMsg->sessionId, 0); + pMac->lim.mgmtFrameSessionId = 0xff; + } + else + { + pMac->lim.mgmtFrameSessionId = pMbMsg->sessionId; + limLog( pMac, LOG2, FL("lim.actionFrameSessionId = %u" ), + pMac->lim.mgmtFrameSessionId); + + } + } + + return; +} + + +void limAbortRemainOnChan(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + if (pMac->fP2pListenOffload) + { + limProcessAbortScanInd(pMac, sessionId); + return; + } + + if(VOS_TRUE == tx_timer_running( + &pMac->lim.limTimers.gLimRemainOnChannelTimer)) + { + //TODO check for state and take appropriate actions + limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER); + limProcessRemainOnChnTimeout(pMac); + } + return; +} + +/* Power Save Related Functions */ +tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpP2pPsConfig pNoA; + tpP2pPsParams pMsgNoA; + tSirMsgQ msg; + + pNoA = (tpP2pPsConfig) pMsgBuf; + + pMsgNoA = vos_mem_malloc(sizeof( tP2pPsConfig )); + if (NULL == pMsgNoA) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during NoA Update" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig), 0); + pMsgNoA->opp_ps = pNoA->opp_ps; + pMsgNoA->ctWindow = pNoA->ctWindow; + pMsgNoA->duration = pNoA->duration; + pMsgNoA->interval = pNoA->interval; + pMsgNoA->count = pNoA->count; + pMsgNoA->single_noa_duration = pNoA->single_noa_duration; + pMsgNoA->psSelection = pNoA->psSelection; + pMsgNoA->sessionId = pNoA->sessionid; + + msg.type = WDA_SET_P2P_GO_NOA_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgNoA; + msg.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("halPostMsgApi failed")); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end __limProcessSmeGoNegReq() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c new file mode 100644 index 0000000000000..97c442c179dcf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c @@ -0,0 +1,2702 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limProcessActionFrame.cc contains the code + * for processing Action Frame. + * Author: Michael Lui + * Date: 05/23/03 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfgSta.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendSmeRspMessages.h" +#include "parserApi.h" +#include "limAdmitControl.h" +#include "wmmApsd.h" +#include "limSendMessages.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#include "limSessionUtils.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif +#include "wlan_qct_wda.h" + +#include "pmmApi.h" + +#define BA_DEFAULT_TX_BUFFER_SIZE 64 + +typedef enum +{ + LIM_ADDBA_RSP = 0, + LIM_ADDBA_REQ = 1 +}tLimAddBaValidationReqType; + +/* Note: The test passes if the STAUT stops sending any frames, and no further + frames are transmitted on this channel by the station when the AP has sent + the last 6 beacons, with the channel switch information elements as seen + with the sniffer.*/ +#define SIR_CHANSW_TX_STOP_MAX_COUNT 6 +/**----------------------------------------------------------------- +\fn limStopTxAndSwitchChannel +\brief Stops the transmission if channel switch mode is silent and + starts the channel switch timer. + +\param pMac +\return NONE +-----------------------------------------------------------------*/ +void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 isFullPowerRequested = 0; + tpPESession psessionEntry; + tANI_U8 isSessionPowerActive = false; + + psessionEntry = peFindSessionBySessionId( pMac , sessionId ); + + if( NULL == psessionEntry ) + { + limLog(pMac, LOGE, FL("Session %d not active"), sessionId); + return; + } + + /* + * Sme Session is passed in limSendSmePreChannelSwitchInd + * so that it can be passed till sme to request full power for + * particular session + */ + if(pMac->psOffloadEnabled) + { + isSessionPowerActive = pmmPsOffloadIsActive(pMac, psessionEntry); + } + else + { + isSessionPowerActive = limIsSystemInActiveState(pMac); + } + + PELOG1(limLog(pMac, LOG1, FL("Channel switch Mode == %d"), + psessionEntry->gLimChannelSwitch.switchMode);) + + if (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT || + psessionEntry->gLimChannelSwitch.switchCount <= SIR_CHANSW_TX_STOP_MAX_COUNT) + { + /* Freeze the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX); + + /*Request for Full power only if the device is in powersave*/ + if(!isSessionPowerActive) + { + /* Request Full Power */ + limSendSmePreChannelSwitchInd(pMac, psessionEntry); + isFullPowerRequested = 1; + } + } + else + { + /* Resume the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + } + + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId; + /* change the channel immediatly only if the channel switch count is 0 and the + * device is not in powersave + * If the device is in powersave channel switch should happen only after the + * device comes out of the powersave */ + if (psessionEntry->gLimChannelSwitch.switchCount == 0) + { + if(isSessionPowerActive) + { + limProcessChannelSwitchTimeout(pMac); + } + else if(!isFullPowerRequested) + { + /* + * If the Full power is already not requested + * Request Full Power so the channel switch happens + * after device comes to full power + */ + limSendSmePreChannelSwitchInd(pMac, psessionEntry); + } + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_CHANNEL_SWITCH_TIMER)); + + + if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_activate failed")); + } + return; +} + +/**------------------------------------------------------------ +\fn limStartChannelSwitch +\brief Switches the channel if switch count == 0, otherwise + starts the timer for channel switch and stops BG scan + and heartbeat timer tempororily. + +\param pMac +\param psessionEntry +\return NONE +------------------------------------------------------------*/ +tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + PELOG1(limLog(pMac, LOG1, FL("Starting the channel switch"));) + + /*If channel switch is already running and it is on a different session, just return*/ + /*This need to be removed for MCC */ + if ((limIsChanSwitchRunning (pMac) && + psessionEntry->gLimSpecMgmt.dot11hChanSwState != eLIM_11H_CHANSW_RUNNING) || + psessionEntry->csaOffloadEnable) + { + limLog(pMac, LOGW, FL("Ignoring channel switch on session %d"), psessionEntry->peSessionId); + return eSIR_SUCCESS; + } + + /* Deactivate and change reconfigure the timeout value */ + //limDeactivateAndChangeTimer(pMac, eLIM_CHANNEL_SWITCH_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed!")); + return eSIR_FAILURE; + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer, + psessionEntry->gLimChannelSwitch.switchTimeoutValue, + 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_change failed ")); + return eSIR_FAILURE; + } + + /* Follow the channel switch, forget about the previous quiet. */ + //If quiet is running, chance is there to resume tx on its timeout. + //so stop timer for a safer side. + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed")); + return eSIR_FAILURE; + } + } + else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed")); + return eSIR_FAILURE; + } + } + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + /* Prepare for 11h channel switch */ + limPrepareFor11hChannelSwitch(pMac, psessionEntry); + + /** Dont add any more statements here as we posted finish scan request + * to HAL, wait till we get the response + */ + return eSIR_SUCCESS; +} + + +/** + * __limProcessChannelSwitchActionFrame + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void + +__limProcessChannelSwitchActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tDot11fChannelSwitch *pChannelSwitchFrame; + tANI_U16 beaconPeriod; + tANI_U32 val; + tANI_U32 frameLen; + tANI_U32 nStatus; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG3(limLog(pMac, LOG3, FL("Received Channel switch action frame"));) + if (!psessionEntry->lim11hEnable) + return; + + pChannelSwitchFrame = vos_mem_malloc(sizeof(*pChannelSwitchFrame)); + if (NULL == pChannelSwitchFrame) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed")); + return; + } + + /* Unpack channel switch frame */ + nStatus = dot11fUnpackChannelSwitch(pMac, pBody, frameLen, pChannelSwitchFrame); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + vos_mem_free(pChannelSwitchFrame); + return; + } + else if(DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + } + + if (vos_mem_compare((tANI_U8 *) &psessionEntry->bssId, + (tANI_U8 *) &pHdr->sa, + sizeof(tSirMacAddr))) + { + /* copy the beacon interval from psessionEntry*/ + val = psessionEntry->beaconParams.beaconInterval; + + beaconPeriod = (tANI_U16) val; + + psessionEntry->gLimChannelSwitch.primaryChannel = pChannelSwitchFrame->ChanSwitchAnn.newChannel; + psessionEntry->gLimChannelSwitch.switchCount = pChannelSwitchFrame->ChanSwitchAnn.switchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = SYS_MS_TO_TICKS(beaconPeriod) * + psessionEntry->gLimChannelSwitch.switchCount; + psessionEntry->gLimChannelSwitch.switchMode = pChannelSwitchFrame->ChanSwitchAnn.switchMode; +#ifdef WLAN_FEATURE_11AC + if ( pChannelSwitchFrame->WiderBWChanSwitchAnn.present && psessionEntry->vhtCapability) + { + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = pChannelSwitchFrame->WiderBWChanSwitchAnn.newChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq0; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq1; + } +#endif + + PELOG3(limLog(pMac, LOG3, FL("Rcv Chnl Swtch Frame: Timeout in %d ticks"), + psessionEntry->gLimChannelSwitch.switchTimeoutValue);) + + /* Only primary channel switch element is present */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; + + if (psessionEntry->htSupportedChannelWidthSet) + { + if ((pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset; + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability && pChannelSwitchFrame->WiderBWChanSwitchAnn.present) + { + if (pChannelSwitchFrame->WiderBWChanSwitchAnn.newChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + if (pChannelSwitchFrame->ExtChanSwitchAnn.present && ((pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY))) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = + limGet11ACPhyCBState(pMac, + psessionEntry->gLimChannelSwitch.primaryChannel, + pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset, + pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq0, + psessionEntry); + } + } + } +#endif + } + + } + else + { + PELOG1(limLog(pMac, LOG1, FL("LIM: Received action frame not from our BSS, dropping..."));) + } + + if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry)) + { + PELOG1(limLog(pMac, LOG1, FL("Could not start channel switch"));) + } + + vos_mem_free(pChannelSwitchFrame); + return; +} /*** end limProcessChannelSwitchActionFrame() ***/ + + +#ifdef WLAN_FEATURE_11AC +static void +__limProcessOperatingModeActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tDot11fOperatingMode *pOperatingModeframe; + tANI_U32 frameLen; + tANI_U32 nStatus; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U8 operMode; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG3(limLog(pMac, LOG3, FL("Received Operating Mode action frame"));) + pOperatingModeframe = vos_mem_malloc(sizeof(*pOperatingModeframe)); + if (NULL == pOperatingModeframe) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed")); + return; + } + + /* Unpack channel switch frame */ + nStatus = dot11fUnpackOperatingMode(pMac, pBody, frameLen, pOperatingModeframe); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + vos_mem_free(pOperatingModeframe); + return; + } + else if(DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + } + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + operMode = pSta->vhtSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_80MHZ : pSta->htSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ; + if( operMode != pOperatingModeframe->OperatingMode.chanWidth) + { + limLog(pMac, LOGE, + FL(" received Chanwidth %d, staIdx = %d"), + (pOperatingModeframe->OperatingMode.chanWidth ), + pSta->staIndex); + + limLog(pMac, LOGE, + FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"), + pHdr->sa[0], + pHdr->sa[1], + pHdr->sa[2], + pHdr->sa[3], + pHdr->sa[4], + pHdr->sa[5]); + + if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_20MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + limCheckVHTOpModeChange( pMac, psessionEntry, + (pOperatingModeframe->OperatingMode.chanWidth), + pSta->staIndex, pHdr->sa); + } + + if (pSta->vhtSupportedRxNss != (pOperatingModeframe->OperatingMode.rxNSS + 1)) { + pSta->vhtSupportedRxNss = pOperatingModeframe->OperatingMode.rxNSS + 1; + limSetNssChange( pMac, psessionEntry, pSta->vhtSupportedRxNss, + pSta->staIndex, pHdr->sa); + } + + vos_mem_free(pOperatingModeframe); + return; +} + +static void +__limProcessGidManagementActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tDot11fVHTGidManagementActionFrame *pGidManagementframe; + tANI_U32 frameLen; + tANI_U32 nStatus; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U32 membership = 0; + tANI_U32 userPosition = 0; + tANI_U32 *pMemLower; + tANI_U32 *pMemUpper; + tANI_U32 *pMemCur; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG3(limLog(pMac, LOG3, FL("Received GID Management action frame"));) + pGidManagementframe = vos_mem_malloc(sizeof(*pGidManagementframe)); + if (NULL == pGidManagementframe) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed")); + return; + } + + /* Unpack Gid Mangement Action frame */ + nStatus = dot11fUnpackVHTGidManagementActionFrame(pMac, pBody, frameLen, pGidManagementframe); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an GidManagement Action frame (0x%08x, %d bytes):"), + nStatus, + frameLen); + vos_mem_free(pGidManagementframe); + return; + } + else if(DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an GidManagement Action frame (0x%08x, %d bytes):"), + nStatus, + frameLen); + } + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + { + limLog(pMac, LOGE, + FL(" received Gid Management Action Frame , staIdx = %d"), + pSta->staIndex); + + limLog(pMac, LOGE, + FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"), + pHdr->sa[0], + pHdr->sa[1], + pHdr->sa[2], + pHdr->sa[3], + pHdr->sa[4], + pHdr->sa[5]); + + pMemLower = (tANI_U32 *)pGidManagementframe->VhtMembershipStatusArray.membershipStatusArray; + pMemUpper = (tANI_U32 *)&pGidManagementframe->VhtMembershipStatusArray.membershipStatusArray[4]; + + if (*pMemLower && *pMemUpper) + { + limLog(pMac, LOGE, + FL(" received frame with multiple group ID set\ + , staIdx = %d"), pSta->staIndex); + goto out; + } + if (*pMemLower) + { + pMemCur = pMemLower; + } + else if (*pMemUpper) + { + pMemCur = pMemUpper; + membership += sizeof(tANI_U32); + } + else + { + limLog(pMac, LOGE, + FL(" received Gid Management Frame with no group ID set\ + , staIdx = %d"), pSta->staIndex); + goto out; + } + while (!(*pMemCur & 1)) + { + *pMemCur >>= 1; + ++membership; + } + if (*pMemCur) + { + limLog(pMac, LOGE, + FL(" received frame with multiple group ID set\ + , staIdx = %d"), pSta->staIndex); + goto out; + } + + /*Just read the last two bits */ + userPosition = pGidManagementframe->VhtUserPositionArray.userPositionArray[membership] + & 0x3; + + limCheckMembershipUserPosition( pMac, psessionEntry, membership, + userPosition, pSta->staIndex); + } +out: + vos_mem_free(pGidManagementframe); + return; +} + +#endif + +static void +__limProcessAddTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +} + + +static void +__limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tSirAddtsRspInfo addts; + tSirRetStatus retval; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U32 frameLen; + tANI_U8 *pBody; + tpLimTspecInfo tspecInfo; + tANI_U8 ac; + tpDphHashNode pStaDs = NULL; + tANI_U8 rspReqd = 1; + tANI_U32 cfgLen; + tSirMacAddr peerMacAddr; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + + PELOGW(limLog(pMac, LOGW, "Recv AddTs Response");) + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp recvd at AP: ignoring"));) + return; + } + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp"));) + return; + } + + retval = sirConvertAddtsRsp2Struct(pMac, pBody, frameLen, &addts); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp parsing failed (error %d)"), retval);) + return; + } + + // don't have to check for qos/wme capabilities since we wouldn't have this + // flag set otherwise + if (! pMac->lim.gLimAddtsSent) + { + // we never sent an addts request! + PELOGW(limLog(pMac, LOGW, "Recvd AddTsRsp but no request was ever sent - ignoring");) + return; + } + + if (pMac->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) + { + limLog(pMac, LOGW, "AddTsRsp: token mismatch (got %d, exp %d) - ignoring", + addts.dialogToken, pMac->lim.gLimAddtsReq.req.dialogToken); + return; + } + + /* + * for successful addts reponse, try to add the classifier. + * if this fails for any reason, we should send a delts request to the ap + * for now, its ok not to send a delts since we are going to add support for + * multiple tclas soon and until then we won't send any addts requests with + * multiple tclas elements anyway. + * In case of addClassifier failure, we just let the addts timer run out + */ + if (((addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) && + (addts.status == eSIR_MAC_SUCCESS_STATUS)) + { + // add the classifier - this should always succeed + if (addts.numTclas > 1) // currently no support for multiple tclas elements + { + limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported"), + aid, addts.numTclas); + return; + } + else if (addts.numTclas == 1) + { + limLog(pMac, LOGW, "AddTs Response from STA %d: tsid %d, UP %d, OK!", aid, + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio); + } + } + limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d ", + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio, + addts.status); + + // deactivate the response timer + limDeactivateAndChangeTimer(pMac, eLIM_ADDTS_RSP_TIMER); + + if (addts.status != eSIR_MAC_SUCCESS_STATUS) + { + limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d ", + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio, + addts.status); + limSendSmeAddtsRsp(pMac, true, addts.status, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + + // clear the addts flag + pMac->lim.gLimAddtsSent = false; + + return; + } +#ifdef FEATURE_WLAN_ESE + if (addts.tsmPresent) { + limLog(pMac, LOGW, "TSM IE Present"); + psessionEntry->eseContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio; + vos_mem_copy(&psessionEntry->eseContext.tsm.tsmInfo, + &addts.tsmIE,sizeof(tSirMacESETSMIE)); +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, addts.tsmIE.tsid, + addts.tsmIE.state, addts.tsmIE.msmt_interval); +#else + limActivateTSMStatsTimer(pMac, psessionEntry); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + } +#endif + /* Since AddTS response was successful, check for the PSB flag + * and directional flag inside the TS Info field. + * An AC is trigger enabled AC if the PSB subfield is set to 1 + * in the uplink direction. + * An AC is delivery enabled AC if the PSB subfield is set to 1 + * in the downlink direction. + * An AC is trigger and delivery enabled AC if the PSB subfield + * is set to 1 in the bi-direction field. + */ + if(!pMac->psOffloadEnabled) + { + if (addts.tspec.tsinfo.traffic.psb == 1) + limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, SET_UAPSD_MASK); + else + limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, CLEAR_UAPSD_MASK); + + + /* + * ADDTS success, so AC is now admitted. We shall now use the default + * EDCA parameters as advertised by AP and send the updated EDCA params + * to HAL. + */ + ac = upToAc(addts.tspec.tsinfo.traffic.userPrio); + if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + } + else + { + if (addts.tspec.tsinfo.traffic.psb == 1) + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + &addts.tspec.tsinfo, SET_UAPSD_MASK); + else + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + &addts.tspec.tsinfo, CLEAR_UAPSD_MASK); + + /* + * ADDTS success, so AC is now admitted. We shall now use the default + * EDCA parameters as advertised by AP and send the updated EDCA params + * to HAL. + */ + ac = upToAc(addts.tspec.tsinfo.traffic.userPrio); + if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + + + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + //if schedule is not present then add TSPEC with svcInterval as 0. + if(!addts.schedulePresent) + addts.schedule.svcInterval = 0; + if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, &addts.tspec, addts.schedule.svcInterval, &tspecInfo)) + { + PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed "));) + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec, + psessionEntry); + pMac->lim.gLimAddtsSent = false; + return; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status. + } + if((addts.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA) || + ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC))) + { +#ifdef FEATURE_WLAN_ESE + retval = limSendHalMsgAddTs(pMac, + pSta->staIndex, + tspecInfo->idx, + addts.tspec, + psessionEntry->peSessionId, + addts.tsmIE.msmt_interval); +#else + retval = limSendHalMsgAddTs(pMac, + pSta->staIndex, + tspecInfo->idx, + addts.tspec, + psessionEntry->peSessionId); +#endif + if(eSIR_SUCCESS != retval) + { + limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx); + + // Send DELTS action frame to AP + cfgLen = sizeof(tSirMacAddr); + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec, + psessionEntry); + limSendSmeAddtsRsp(pMac, true, retval, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + pMac->lim.gLimAddtsSent = false; + return; + } + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)"), + addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);) + } + else + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)"), + addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);) + PELOGW(limLog(pMac, LOGW, FL("no ACM: Bypass sending WDA_ADD_TS_REQ to HAL "));) + // Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, true, eSIR_SME_SUCCESS, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + + // clear the addts flag + pMac->lim.gLimAddtsSent = false; + return; +} + + +static void +__limProcessDelTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tSirRetStatus retval; + tSirDeltsReqInfo delts; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tANI_U32 frameLen; + tANI_U16 aid; + tANI_U8 *pBody; + tANI_U8 tsStatus; + tSirMacTSInfo *tsinfo; + tANI_U8 tspecIdx; + tANI_U8 ac; + tpDphHashNode pStaDs = NULL; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring DelTs"));) + return; + } + + // parse the delts request + retval = sirConvertDeltsReq2Struct(pMac, pBody, frameLen, &delts); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("DelTs parsing failed (error %d)"), retval);) + return; + } + + if (delts.wmeTspecPresent) + { + if ((!psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled)) + { + PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: wme not enabled/capable"));) + return; + } + PELOG2(limLog(pMac, LOG2, FL("WME Delts received"));) + } + else if ((psessionEntry->limQosEnabled) && pSta->lleEnabled) + { + PELOG2(limLog(pMac, LOG2, FL("11e QoS Delts received"));) + } + else if ((psessionEntry->limWsmEnabled) && pSta->wsmEnabled) + { + PELOG2(limLog(pMac, LOG2, FL("WSM Delts received"));) + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: qos not enabled/capable"));) + return; + } + + tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo; + + // if no Admit Control, ignore the request + if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)) + { + + if (upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) + { + limLog(pMac, LOGW, FL("DelTs with UP %d has no AC - ignoring request"), + tsinfo->traffic.userPrio); + return; + } + } + + if ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && + (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) + limSendSmeDeltsInd(pMac, &delts, aid,psessionEntry); + + // try to delete the TS + if (eSIR_SUCCESS != limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx)) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Delete TS"));) + return; + } + + else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) + { + //Edca only for now. + } + else + { + //send message to HAL to delete TS + if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, + pSta->staIndex, + tspecIdx, + delts, + psessionEntry->peSessionId, + psessionEntry->bssId)) + { + limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request"), + tsinfo->traffic.userPrio); + return; + } + } + + /* We successfully deleted the TSPEC. Update the dynamic UAPSD Mask. + * The AC for this TSPEC is no longer trigger enabled if this Tspec + * was set-up in uplink direction only. + * The AC for this TSPEC is no longer delivery enabled if this Tspec + * was set-up in downlink direction only. + * The AC for this TSPEC is no longer triiger enabled and delivery + * enabled if this Tspec was a bidirectional TSPEC. + */ + if(!pMac->psOffloadEnabled) + { + limSetTspecUapsdMask(pMac, tsinfo, CLEAR_UAPSD_MASK); + + + /* We're deleting the TSPEC. + * The AC for this TSPEC is no longer admitted in uplink/downlink direction + * if this TSPEC was set-up in uplink/downlink direction only. + * The AC for this TSPEC is no longer admitted in both uplink and downlink + * directions if this TSPEC was a bi-directional TSPEC. + * If ACM is set for this AC and this AC is admitted only in downlink + * direction, PE needs to downgrade the EDCA parameter + * (for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(tsinfo->traffic.userPrio); + + if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + } + else + { + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + tsinfo, CLEAR_UAPSD_MASK); + + + /* We're deleting the TSPEC. + * The AC for this TSPEC is no longer admitted in uplink/downlink direction + * if this TSPEC was set-up in uplink/downlink direction only. + * The AC for this TSPEC is no longer admitted in both uplink and downlink + * directions if this TSPEC was a bi-directional TSPEC. + * If ACM is set for this AC and this AC is admitted only in downlink + * direction, PE needs to downgrade the EDCA parameter + * (for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(tsinfo->traffic.userPrio); + + if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + + PELOG1(limLog(pMac, LOG1, FL("DeleteTS succeeded"));) + +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + +} + +static void +__limProcessQosMapConfigureFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 *pBody; + tSirRetStatus retval; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + retval = sirConvertQosMapConfigureFrame2Struct(pMac, pBody, frameLen, + &psessionEntry->QosMapSet); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGE, + FL("QosMapConfigure frame parsing failed (error %d)"), retval);) + return; + } + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, (tANI_U8*)pHdr, + frameLen + sizeof(tSirMacMgmtHdr), 0, + WDA_GET_RX_CH( pRxPacketInfo ), + psessionEntry, 0); +} + +#ifdef ANI_SUPPORT_11H +/** + * limProcessBasicMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a Basic measurement Request action frame. + * Station/BP receiving this should perform basic measurements + * and then send Basic Measurement Report. AP should not perform + * any measurements, and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to Basic Meas. Req structure + * @return None + */ +static void +__limProcessBasicMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr, tpPESession psessionEntry) +{ + // TBD - Station shall perform basic measurements + + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send Basic Meas report "));) + return; + } +} + + +/** + * limProcessCcaMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a CCA measurement Request action frame. + * Station/BP receiving this should perform CCA measurements + * and then send CCA Measurement Report. AP should not perform + * any measurements, and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to CCA Meas. Req structure + * @return None + */ +static void +__limProcessCcaMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr, tpPESession psessionEntry) +{ + // TBD - Station shall perform cca measurements + + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send CCA Meas report "));) + return; + } +} + + +/** + * __limProcessRpiMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a RPI measurement Request action frame. + * Station/BP/AP receiving this shall not perform any measurements, + * and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to RPI Meas. Req structure + * @return None + */ +static void +__limProcessRpiMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr, tpPESession psessionEntry) +{ + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send RPI Meas report "));) + return; + } +} + + +/** + * __limProcessMeasurementRequestFrame + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void +__limProcessMeasurementRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpSirMacMeasReqActionFrame pMeasReqFrame; + tANI_U32 frameLen; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + pMeasReqFrame = vos_mem_malloc(sizeof( tSirMacMeasReqActionFrame )); + if (NULL == pMeasReqFrame) + { + limLog(pMac, LOGE, + FL("limProcessMeasurementRequestFrame: AllocateMemory failed ")); + return; + } + + if (sirConvertMeasReqFrame2Struct(pMac, pBody, pMeasReqFrame, frameLen) != + eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Rcv invalid Measurement Request Action Frame "));) + return; + } + + + switch(pMeasReqFrame->measReqIE.measType) + { + case SIR_MAC_BASIC_MEASUREMENT_TYPE: + __limProcessBasicMeasReq(pMac, pMeasReqFrame, pHdr->sa, psessionEntry); + break; + + case SIR_MAC_CCA_MEASUREMENT_TYPE: + __limProcessCcaMeasReq(pMac, pMeasReqFrame, pHdr->sa, psessionEntry); + break; + + case SIR_MAC_RPI_MEASUREMENT_TYPE: + __limProcessRpiMeasReq(pMac, pMeasReqFrame, pHdr->sa, psessionEntry); + break; + + default: + PELOG1(limLog(pMac, LOG1, FL("Unknown Measurement Type %d "), + pMeasReqFrame->measReqIE.measType);) + break; + } + +} /*** end limProcessMeasurementRequestFrame ***/ + + +/** + * limProcessTpcRequestFrame + * + *FUNCTION: + * This function is called upon receiving Tpc Request frame. + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void +__limProcessTpcRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpSirMacTpcReqActionFrame pTpcReqFrame; + tANI_U32 frameLen; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG1(limLog(pMac, LOG1, FL("****LIM: Processing TPC Request from peer ****"));) + + pTpcReqFrame = vos_mem_malloc(sizeof( tSirMacTpcReqActionFrame )); + if (NULL == pTpcReqFrame) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed "));) + return; + } + + if (sirConvertTpcReqFrame2Struct(pMac, pBody, pTpcReqFrame, frameLen) != + eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Rcv invalid TPC Req Action Frame "));) + return; + } + + if (limSendTpcReportFrame(pMac, + pTpcReqFrame, + pHdr->sa, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send TPC Report Frame. "));) + return; + } +} +#endif + + +/** + * \brief Validate an ADDBA Req from peer with respect + * to our own BA configuration + * + * \sa __limValidateAddBAParameterSet + * + * \param pMac The global tpAniSirGlobal object + * + * \param baParameterSet The ADDBA Parameter Set. + * + * \param pDelBAFlag this parameter is NULL except for call from processAddBAReq + * delBAFlag is set when entry already exists. + * + * \param reqType ADDBA Req v/s ADDBA Rsp + * 1 - ADDBA Req + * 0 - ADDBA Rsp + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +static tSirMacStatusCodes +__limValidateAddBAParameterSet( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tDot11fFfAddBAParameterSet baParameterSet, + tANI_U8 dialogueToken, + tLimAddBaValidationReqType reqType , + tANI_U8* pDelBAFlag /*this parameter is NULL except for call from processAddBAReq*/) +{ + if(baParameterSet.tid >= STACFG_MAX_TC) + { + return eSIR_MAC_WME_INVALID_PARAMS_STATUS; + } + + //check if there is already a BA session setup with this STA/TID while processing AddBaReq + if((true == pSta->tcCfg[baParameterSet.tid].fUseBARx) && + (LIM_ADDBA_REQ == reqType)) + { + //There is already BA session setup for STA/TID. + limLog( pMac, LOGE, + FL( "AddBAReq rcvd when there is already a session for this StaId = %d, tid = %d\n " ), + pSta->staIndex, baParameterSet.tid); + limPrintMacAddr( pMac, pSta->staAddr, LOGW ); + + if(pDelBAFlag) + *pDelBAFlag = true; + } + return eSIR_MAC_SUCCESS_STATUS; +} + +/** + * \brief Validate a DELBA Ind from peer with respect + * to our own BA configuration + * + * \sa __limValidateDelBAParameterSet + * + * \param pMac The global tpAniSirGlobal object + * + * \param baParameterSet The DELBA Parameter Set. + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +static tSirMacStatusCodes +__limValidateDelBAParameterSet( tpAniSirGlobal pMac, + tDot11fFfDelBAParameterSet baParameterSet, + tpDphHashNode pSta ) +{ +tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS; + + // Validate if a BA is active for the requested TID + if( pSta->tcCfg[baParameterSet.tid].fUseBATx || + pSta->tcCfg[baParameterSet.tid].fUseBARx ) + { + statusCode = eSIR_MAC_SUCCESS_STATUS; + + limLog( pMac, LOGW, + FL("Valid DELBA Ind received. Time to send WDA_DELBA_IND to HAL...")); + } + else + limLog( pMac, LOGW, + FL("Received an INVALID DELBA Ind for TID %d..."), + baParameterSet.tid ); + + return statusCode; +} + +/** + * \brief Process an ADDBA REQ + * + * \sa limProcessAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the Rx packet info from HDD + * + * \return none + * + */ +static void +__limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tDot11fAddBAReq frmAddBAReq; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS; + tANI_U16 aid; + tANI_U32 frameLen, nStatus,val; + tANI_U8 *pBody; + tANI_U8 delBAFlag =0; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + val = 0; + + // Unpack the received frame + nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL("Failed to unpack and parse an ADDBA Request (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + + // Without an unpacked request we cannot respond, so silently ignore the request + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an ADDBA Request (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + psessionEntry->amsduSupportedInBA = frmAddBAReq.AddBAParameterSet.amsduSupported; + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGE ); + + // FIXME - Should we do this? + status = eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS; + goto returnAfterError; + } + + limLog( pMac, LOGW, + FL( "ADDBA Req from STA with AID %d, tid = %d" ), + aid, frmAddBAReq.AddBAParameterSet.tid); + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // we can only do BA on "hard" STAs + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + status = eSIR_MAC_REQ_DECLINED_STATUS; + goto returnAfterError; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + if (wlan_cfgGetInt(pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, &val) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("Unable to get WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC")); + val = 0; + } + if ((SIR_BAND_2_4_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) && + val) + { + limLog( pMac, LOGW, + FL( "BTC disabled aggregation - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + + status = eSIR_MAC_REQ_DECLINED_STATUS; + goto returnAfterError; + } + + // Now, validate the ADDBA Req + if( eSIR_MAC_SUCCESS_STATUS != + (status = __limValidateAddBAParameterSet( pMac, pSta, + frmAddBAReq.AddBAParameterSet, + 0, //dialogue token is don't care in request validation. + LIM_ADDBA_REQ, &delBAFlag))) + goto returnAfterError; + + //BA already set, so we need to delete it before adding new one. + if(delBAFlag) + { + if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac, + pSta, + (tANI_U8)frmAddBAReq.AddBAParameterSet.tid, + eBA_RECIPIENT,psessionEntry)) + { + status = eSIR_MAC_UNSPEC_FAILURE_STATUS; + goto returnAfterError; + } + } + + // Check if the ADD BA Declined configuration is Disabled + if ((pMac->lim.gAddBA_Declined & ( 1 << frmAddBAReq.AddBAParameterSet.tid ) )) { + limLog( pMac, LOGE, FL( "Declined the ADDBA Req for the TID %d " ), + frmAddBAReq.AddBAParameterSet.tid); + status = eSIR_MAC_REQ_DECLINED_STATUS; + goto returnAfterError; + } + + // + // Post WDA_ADDBA_REQ to HAL. + // If HAL/HDD decide to allow this ADDBA Req session, + // then this BA session is termed active + // + + // Change the Block Ack state of this STA to wait for + // ADDBA Rsp from HAL + LIM_SET_STA_BA_STATE(pSta, frmAddBAReq.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP); + + if (wlan_cfgGetInt(pMac, WNI_CFG_NUM_BUFF_ADVERT , &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_NUM_BUFF_ADVERT")); + return ; + } + + + if (frmAddBAReq.AddBAParameterSet.bufferSize) + { + frmAddBAReq.AddBAParameterSet.bufferSize = + VOS_MIN(val, frmAddBAReq.AddBAParameterSet.bufferSize); + } + else + { + frmAddBAReq.AddBAParameterSet.bufferSize = val; + } + limLog( pMac, LOG1, FL( "ADDBAREQ NUMBUFF %d" ), + frmAddBAReq.AddBAParameterSet.bufferSize); + + if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac, + pSta, + (tANI_U8) frmAddBAReq.DialogToken.token, + (tANI_U8) frmAddBAReq.AddBAParameterSet.tid, + (tANI_U8) frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.BATimeout.timeout, + (tANI_U16) frmAddBAReq.BAStartingSequenceControl.ssn, + eBA_RECIPIENT,psessionEntry)) + status = eSIR_MAC_UNSPEC_FAILURE_STATUS; + else + return; + +returnAfterError: + + // + // Package LIM_MLM_ADDBA_RSP to MLME, with proper + // status code. MLME will then send an ADDBA RSP + // over the air to the peer MAC entity + // + if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac, + pHdr->sa, + status, + frmAddBAReq.DialogToken.token, + (tANI_U8) frmAddBAReq.AddBAParameterSet.tid, + (tANI_U8) frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.BATimeout.timeout,psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_ADDBA_RSP to " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + } + +} + +/** + * \brief Process an ADDBA RSP + * + * \sa limProcessAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the packet info structure from HDD + * + * \return none + * + */ +static void +__limProcessAddBARsp( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +tDot11fAddBARsp frmAddBARsp; +tpSirMacMgmtHdr pHdr; +tpDphHashNode pSta; +tSirMacReasonCodes reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; +tANI_U16 aid; +tANI_U32 frameLen, nStatus; +tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // We can only do BA on "hard" STAs. We should not have issued an ADDBA + // Request, so we should never be processing a ADDBA Response + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + return; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + // Unpack the received frame + nStatus = dot11fUnpackAddBARsp( pMac, pBody, frameLen, &frmAddBARsp ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an ADDBA Response (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an ADDBA Response (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog( pMac, LOGE, + FL( "ADDBA Rsp from STA with AID %d, tid = %d, status = %d" ), + aid, frmAddBARsp.AddBAParameterSet.tid, frmAddBARsp.Status.status); + + //if there is no matchin dialougue token then ignore the response. + + if(eSIR_SUCCESS != limSearchAndDeleteDialogueToken(pMac, frmAddBARsp.DialogToken.token, + pSta->assocId, frmAddBARsp.AddBAParameterSet.tid)) + { + PELOGW(limLog(pMac, LOGE, FL("dialogueToken in received addBARsp did not match with outstanding requests"));) + return; + } + + // Check first if the peer accepted the ADDBA Req + if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status ) + { + //if peer responded with buffer size 0 then we should pick the default. + if(0 == frmAddBARsp.AddBAParameterSet.bufferSize) + frmAddBARsp.AddBAParameterSet.bufferSize = BA_DEFAULT_TX_BUFFER_SIZE; + + // Now, validate the ADDBA Rsp + if( eSIR_MAC_SUCCESS_STATUS != + __limValidateAddBAParameterSet( pMac, pSta, + frmAddBARsp.AddBAParameterSet, + (tANI_U8)frmAddBARsp.DialogToken.token, + LIM_ADDBA_RSP, NULL)) + goto returnAfterError; + } + else + goto returnAfterError; + + // Change STA state to wait for ADDBA Rsp from HAL + LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP); + + // + // Post WDA_ADDBA_REQ to HAL. + // If HAL/HDD decide to allow this ADDBA Rsp session, + // then this BA session is termed active + // + + if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac, + pSta, + (tANI_U8) frmAddBARsp.DialogToken.token, + (tANI_U8) frmAddBARsp.AddBAParameterSet.tid, + (tANI_U8) frmAddBARsp.AddBAParameterSet.policy, + frmAddBARsp.AddBAParameterSet.bufferSize, + frmAddBARsp.BATimeout.timeout, + 0, + eBA_INITIATOR,psessionEntry)) + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + else + return; + +returnAfterError: + + // TODO: Do we need to signal an error status to SME, + // if status != eSIR_MAC_SUCCESS_STATUS + + // Restore STA "BA" State + LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_IDLE); + // + // Need to send a DELBA IND to peer, who + // would have setup a BA session with this STA + // + if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status ) + { + // + // Package LIM_MLM_DELBA_REQ to MLME, with proper + // status code. MLME will then send a DELBA IND + // over the air to the peer MAC entity + // + if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac, + pSta, + eBA_INITIATOR, + (tANI_U8) frmAddBARsp.AddBAParameterSet.tid, + reasonCode, psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_DELBA_REQ to " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + } + } +} + +/** + * \brief Process a DELBA Indication + * + * \sa limProcessDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the Rx packet info from HDD + * + * \return none + * + */ +static void +__limProcessDelBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +tDot11fDelBAInd frmDelBAInd; +tpSirMacMgmtHdr pHdr; +tpDphHashNode pSta; +tANI_U16 aid; +tANI_U32 frameLen, nStatus; +tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, FL( "STA context not found - ignoring DELBA from ")); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + + limLog( pMac, LOG1, FL( "DELBA Ind from STA with AID %d" ), aid ); + + // Unpack the received frame + nStatus = dot11fUnpackDelBAInd( pMac, pBody, frameLen, &frmDelBAInd ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse a DELBA Indication (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking a DELBA Indication (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog( pMac, LOGW, + FL( "Received DELBA for TID %d, Reason code %d" ), + frmDelBAInd.DelBAParameterSet.tid, + frmDelBAInd.Reason.code ); + + // Now, validate the DELBA Ind + if( eSIR_MAC_SUCCESS_STATUS != __limValidateDelBAParameterSet( pMac, + frmDelBAInd.DelBAParameterSet, + pSta )) + return; + + // + // Post WDA_DELBA_IND to HAL and delete the + // existing BA session + // + // NOTE - IEEE 802.11-REVma-D8.0, Section 7.3.1.16 + // is kind of confusing... + // + if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac, + pSta, + (tANI_U8) frmDelBAInd.DelBAParameterSet.tid, + (eBA_RECIPIENT == frmDelBAInd.DelBAParameterSet.initiator)? + eBA_INITIATOR: eBA_RECIPIENT,psessionEntry)) + limLog( pMac, LOGE, FL( "Posting WDA_DELBA_IND to HAL failed ")); + + return; + +} + +static void +__limProcessSMPowerSaveUpdate(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tDot11fSMPowerSave frmSMPower; + tSirMacHTMIMOPowerSaveState state; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) { + limLog( pMac, LOGE,FL( "STA context not found - ignoring UpdateSM PSave Mode from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackSMPowerSave( pMac, pBody, frameLen, &frmSMPower); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with PS_Enable:%d" + "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En, + frmSMPower.SMPowerModeSet.Mode); + + /** Update in the DPH Table about the Update in the SM Power Save mode*/ + if (frmSMPower.SMPowerModeSet.PowerSave_En && frmSMPower.SMPowerModeSet.Mode) + state = eSIR_HT_MIMO_PS_DYNAMIC; + else if ((frmSMPower.SMPowerModeSet.PowerSave_En) && (frmSMPower.SMPowerModeSet.Mode ==0)) + state = eSIR_HT_MIMO_PS_STATIC; + else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0) && (frmSMPower.SMPowerModeSet.Mode == 0)) + state = eSIR_HT_MIMO_PS_NO_LIMIT; + else { + PELOGW(limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with invalid mode"));) + return; + } + + if (state == pSta->htMIMOPSState) { + PELOGE(limLog(pMac, LOGE, FL("The PEER is already set in the same mode"));) + return; + } + + /** Update in the HAL Station Table for the Update of the Protection Mode */ + pSta->htMIMOPSState = state; + limPostSMStateUpdate(pMac,pSta->staIndex, pSta->htMIMOPSState, + pSta->staAddr, psessionEntry->smeSessionId); +} + +#if defined WLAN_FEATURE_VOWIFI + +static void +__limProcessRadioMeasureRequest( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fRadioMeasurementRequest frm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + if( psessionEntry == NULL ) + { + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackRadioMeasurementRequest( pMac, pBody, frameLen, &frm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + // Call rrm function to handle the request. + + rrmProcessRadioMeasurementRequest( pMac, pHdr->sa, &frm, psessionEntry ); +} + +static void +__limProcessLinkMeasurementReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fLinkMeasurementRequest frm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + if( psessionEntry == NULL ) + { + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackLinkMeasurementRequest( pMac, pBody, frameLen, &frm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + // Call rrm function to handle the request. + + rrmProcessLinkMeasurementRequest( pMac, pRxPacketInfo, &frm, psessionEntry ); + +} + +static void +__limProcessNeighborReport( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fNeighborReportResponse *pFrm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pFrm = vos_mem_malloc(sizeof(tDot11fNeighborReportResponse)); + if (NULL == pFrm) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in __limProcessNeighborReport") ); + return; + } + + if(psessionEntry == NULL) + { + vos_mem_free(pFrm); + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackNeighborReportResponse( pMac, pBody, frameLen,pFrm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + vos_mem_free(pFrm); + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + //Call rrm function to handle the request. + rrmProcessNeighborReportResponse( pMac, pFrm, psessionEntry ); + + vos_mem_free(pFrm); +} + +#endif + +#ifdef WLAN_FEATURE_11W +/** + * limProcessSAQueryRequestActionFrame + * + *FUNCTION: + * This function is called by limProcessActionFrame() upon + * SA query request Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - Handle to the Rx packet info + * @param psessionEntry - PE session entry + * + * @return None + */ +static void __limProcessSAQueryRequestActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tANI_U8 transId[2]; + + /* Prima --- Below Macro not available in prima + pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd); + pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */ + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + /* If this is an unprotected SA Query Request, then ignore it. */ + if (pHdr->fc.wep == 0) + return; + + /*Extract 11w trsansId from SA query request action frame + In SA query response action frame we will send same transId + In SA query request action frame: + Category : 1 byte + Action : 1 byte + Transaction ID : 2 bytes */ + vos_mem_copy(&transId[0], &pBody[2], 2); + + //Send 11w SA query response action frame + if (limSendSaQueryResponseFrame(pMac, + transId, + pHdr->sa,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send SA query response action frame."));) + return; + } +} + +/** + * __limProcessSAQueryResponseActionFrame + * + *FUNCTION: + * This function is called by limProcessActionFrame() upon + * SA query response Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - Handle to the Rx packet info + * @param psessionEntry - PE session entry + * @return None + */ +static void __limProcessSAQueryResponseActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 *pBody; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U16 transId; + tANI_U8 retryNum; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("SA Query Response received...")) ; + + /* When a station, supplicant handles SA Query Response. + * Forward to SME to HDD to wpa_supplicant. + */ + if (eLIM_STA_ROLE == psessionEntry->limSystemRole) + { + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, (tANI_U8*)pHdr, + frameLen + sizeof(tSirMacMgmtHdr), 0, + WDA_GET_RX_CH( pRxPacketInfo ), + psessionEntry, 0); + return; + } + + /* If this is an unprotected SA Query Response, then ignore it. */ + if (pHdr->fc.wep == 0) + return; + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (NULL == pSta) + return; + + limLog(pMac, LOG1, + FL("SA Query Response source addr - %0x:%0x:%0x:%0x:%0x:%0x"), + pHdr->sa[0], pHdr->sa[1], pHdr->sa[2], pHdr->sa[3], + pHdr->sa[4], pHdr->sa[5]); + limLog(pMac, LOG1, + FL("SA Query state for station - %d"), pSta->pmfSaQueryState); + + if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState) + return; + + /* Extract 11w trsansId from SA query reponse action frame + In SA query response action frame: + Category : 1 byte + Action : 1 byte + Transaction ID : 2 bytes */ + vos_mem_copy(&transId, &pBody[2], 2); + + /* If SA Query is in progress with the station and the station + responds then the association request that triggered the SA + query is from a rogue station, just go back to initial state. */ + for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++) + if (transId == pSta->pmfSaQueryStartTransId + retryNum) + { + limLog(pMac, LOG1, + FL("Found matching SA Query Request - transaction ID %d"), transId); + tx_timer_deactivate(&pSta->pmfSaQueryTimer); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + break; + } +} +#endif + +#ifdef WLAN_FEATURE_11W +/** + * limDropUnprotectedActionFrame + * + *FUNCTION: + * This function checks if an Action frame should be dropped since it is + * a Robust Managment Frame, it is unprotected, and it is received on a + * connection where PMF is enabled. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Global MAC structure + * @param psessionEntry - PE session entry + * @param pHdr - Frame header + * @param category - Action frame category + * @return TRUE if frame should be dropped + */ + +static tANI_BOOLEAN +limDropUnprotectedActionFrame (tpAniSirGlobal pMac, tpPESession psessionEntry, + tpSirMacMgmtHdr pHdr, tANI_U8 category) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tANI_BOOLEAN rmfConnection = eANI_BOOLEAN_FALSE; + + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + if (pStaDs->rmfEnabled) + rmfConnection = eANI_BOOLEAN_TRUE; + } + else if (psessionEntry->limRmfEnabled) + rmfConnection = eANI_BOOLEAN_TRUE; + + if (rmfConnection && (pHdr->fc.wep == 0)) + { + PELOGE(limLog(pMac, LOGE, FL("Dropping unprotected Action category %d frame " + "since RMF is enabled."), category);) + return eANI_BOOLEAN_TRUE; + } + else + return eANI_BOOLEAN_FALSE; +} +#endif + +/** + * limProcessActionFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +void +limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + tpSirMacActionFrameHdr pActionHdr = (tpSirMacActionFrameHdr) pBody; +#ifdef WLAN_FEATURE_11W + tpSirMacMgmtHdr pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); +#endif + tANI_U32 frameLen; + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + switch (pActionHdr->category) + { + case SIR_MAC_ACTION_QOS_MGMT: +#ifdef WLAN_FEATURE_11W + if (limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, pActionHdr->category)) + break; +#endif + if ( (psessionEntry->limQosEnabled) || + (pActionHdr->actionID == SIR_MAC_QOS_MAP_CONFIGURE) ) + { + switch (pActionHdr->actionID) + { + case SIR_MAC_QOS_ADD_TS_REQ: + __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_ADD_TS_RSP: + __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_DEL_TS_REQ: + __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_MAP_CONFIGURE: + __limProcessQosMapConfigureFrame(pMac, + (tANI_U8 *) pRxPacketInfo, psessionEntry); + break; + default: + PELOGE(limLog(pMac, LOGE, FL("Qos action %d not handled"), pActionHdr->actionID);) + break; + } + break ; + } + + break; + + case SIR_MAC_ACTION_SPECTRUM_MGMT: +#ifdef WLAN_FEATURE_11W + if (limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, pActionHdr->category)) + break; +#endif + switch (pActionHdr->actionID) + { +#ifdef ANI_SUPPORT_11H + case SIR_MAC_ACTION_MEASURE_REQUEST_ID: + if(psessionEntry->lim11hEnable) + { + __limProcessMeasurementRequestFrame(pMac, pRxPacketInfo, psessionEntry); + } + break; + + case SIR_MAC_ACTION_TPC_REQUEST_ID: + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (pessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + if(psessionEntry->lim11hEnable) + { + __limProcessTpcRequestFrame(pMac, pRxPacketInfo, psessionEntry); + } + } + break; + +#endif + case SIR_MAC_ACTION_CHANNEL_SWITCH_ID: + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + __limProcessChannelSwitchActionFrame(pMac, pRxPacketInfo,psessionEntry); + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("Spectrum mgmt action id %d not handled"), pActionHdr->actionID);) + break; + } + break; + + case SIR_MAC_ACTION_WME: + if (! psessionEntry->limWmeEnabled) + { + limLog(pMac, LOGW, FL("WME mode disabled - dropping action frame %d"), + pActionHdr->actionID); + break; + } + switch(pActionHdr->actionID) + { + case SIR_MAC_QOS_ADD_TS_REQ: + __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_ADD_TS_RSP: + __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_DEL_TS_REQ: + __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_MAP_CONFIGURE: + __limProcessQosMapConfigureFrame(pMac, + (tANI_U8 *) pRxPacketInfo, psessionEntry); + break; + + default: + PELOGE(limLog(pMac, LOGE, FL("WME action %d not handled"), pActionHdr->actionID);) + break; + } + break; + + case SIR_MAC_ACTION_BLKACK: + // Determine the "type" of BA Action Frame +#ifdef WLAN_FEATURE_11W + if (limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, pActionHdr->category)) + break; +#endif + switch(pActionHdr->actionID) + { + case SIR_MAC_BLKACK_ADD_REQ: + __limProcessAddBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_BLKACK_ADD_RSP: + __limProcessAddBARsp( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_BLKACK_DEL: + __limProcessDelBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + default: + break; + } + + break; + case SIR_MAC_ACTION_HT: + /** Type of HT Action to be performed*/ + switch(pActionHdr->actionID) { + case SIR_MAC_SM_POWER_SAVE: + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) ) + __limProcessSMPowerSaveUpdate(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + default: + PELOGE(limLog(pMac, LOGE, FL("Action ID %d not handled in HT Action category"), pActionHdr->actionID);) + break; + } + break; + + case SIR_MAC_ACTION_WNM: + { +#ifdef WLAN_FEATURE_11W + if ((psessionEntry->limRmfEnabled) && (pHdr->fc.wep == 0)) + { + PELOGE(limLog(pMac, LOGE, FL + ("Dropping unprotected Action category %d frame since RMF is enabled."), + pActionHdr->category);) + break; + } +#endif + PELOGE(limLog(pMac, LOG1, FL("WNM Action category %d action %d."), + pActionHdr->category, pActionHdr->actionID);) + switch (pActionHdr->actionID) + { + case SIR_MAC_WNM_BSS_TM_QUERY: + case SIR_MAC_WNM_BSS_TM_REQUEST: + case SIR_MAC_WNM_BSS_TM_RESPONSE: + case SIR_MAC_WNM_NOTIF_REQUEST: + case SIR_MAC_WNM_NOTIF_RESPONSE: + { + tpSirMacMgmtHdr pHdr; + tANI_S8 rssi = WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + /* Forward to the SME to HDD to wpa_supplicant */ + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, (tANI_U8*)pHdr, + frameLen + sizeof(tSirMacMgmtHdr), + psessionEntry->smeSessionId, + WDA_GET_RX_CH( pRxPacketInfo ), + psessionEntry, rssi); + break; + } + default: + PELOGE(limLog(pMac, LOGE, + FL("Action ID %d not handled in WNM Action category"), + pActionHdr->actionID);) + break; + } + break; + } +#if defined WLAN_FEATURE_VOWIFI + case SIR_MAC_ACTION_RRM: +#ifdef WLAN_FEATURE_11W + if (limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, pActionHdr->category)) + break; +#endif + if( pMac->rrm.rrmPEContext.rrmEnable ) + { + switch(pActionHdr->actionID) { + case SIR_MAC_RRM_RADIO_MEASURE_REQ: + __limProcessRadioMeasureRequest( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_RRM_LINK_MEASUREMENT_REQ: + __limProcessLinkMeasurementReq( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_RRM_NEIGHBOR_RPT: + __limProcessNeighborReport( pMac, (tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + default: + PELOGE( limLog( pMac, LOGE, FL("Action ID %d not handled in RRM"), pActionHdr->actionID);) + break; + + } + } + else + { + // Else we will just ignore the RRM messages. + PELOGE( limLog( pMac, LOGE, FL("RRM Action frame ignored as RRM is disabled in cfg"));) + } + break; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY: + { + tpSirMacVendorSpecificFrameHdr pVendorSpecific = (tpSirMacVendorSpecificFrameHdr) pActionHdr; + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 Oui[] = { 0x00, 0x00, 0xf0 }; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + //Check if it is a vendor specific action frame. + if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && + (VOS_TRUE == vos_mem_compare(psessionEntry->selfMacAddr, + &pHdr->da[0], sizeof(tSirMacAddr))) && + IS_WES_MODE_ENABLED(pMac) && + vos_mem_compare(pVendorSpecific->Oui, Oui, 3)) + { + PELOGE( limLog( pMac, LOGW, FL("Received Vendor specific action frame, OUI %x %x %x"), + pVendorSpecific->Oui[0], pVendorSpecific->Oui[1], pVendorSpecific->Oui[2]);) + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), + psessionEntry->smeSessionId, + WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry, 0); + } + else + { + limLog( pMac, LOGE, FL("Dropping the vendor specific action frame because of( " + "WES Mode not enabled (WESMODE = %d) or OUI mismatch (%02x %02x %02x) or " + "not received with SelfSta Mac address) system role = %d"), + IS_WES_MODE_ENABLED(pMac), + pVendorSpecific->Oui[0], pVendorSpecific->Oui[1], + pVendorSpecific->Oui[2], + psessionEntry->limSystemRole ); + } + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || + FEATURE_WLAN_LFR */ + case SIR_MAC_ACTION_PUBLIC_USAGE: + switch(pActionHdr->actionID) { + case SIR_MAC_ACTION_VENDOR_SPECIFIC: + { + tpSirMacVendorSpecificPublicActionFrameHdr pPubAction = (tpSirMacVendorSpecificPublicActionFrameHdr) pActionHdr; + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 }; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + //Check if it is a P2P public action frame. + if (vos_mem_compare(pPubAction->Oui, P2POui, 4)) + { + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), + psessionEntry->smeSessionId, + WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry, 0); + } + else + { + limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"), + pPubAction->Oui[0], pPubAction->Oui[1], pPubAction->Oui[2], pPubAction->Oui[3] ); + } + } + break; + + case SIR_MAC_ACTION_2040_BSS_COEXISTENCE: + { + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), + psessionEntry->smeSessionId, + WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry, 0); + } + break; +#ifdef FEATURE_WLAN_TDLS + case SIR_MAC_TDLS_DIS_RSP: + { + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_S8 rssi; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + rssi = WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Public Action TDLS Discovery RSP ..")) ; + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), + psessionEntry->smeSessionId, + WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry, rssi); + } + break; +#endif + + default: + PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x "), pActionHdr->actionID);) + break; + } + break; + +#ifdef WLAN_FEATURE_11W + case SIR_MAC_ACTION_SA_QUERY: + { + PELOGE(limLog(pMac, LOG1, FL("SA Query Action category %d action %d."), pActionHdr->category, pActionHdr->actionID);) + if (limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, pActionHdr->category)) + break; + switch (pActionHdr->actionID) + { + case SIR_MAC_SA_QUERY_REQ: + /**11w SA query request action frame received**/ + /* Respond directly to the incoming request in LIM */ + __limProcessSAQueryRequestActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_SA_QUERY_RSP: + /**11w SA query response action frame received**/ + /* Handle based on the current SA Query state */ + __limProcessSAQueryResponseActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + default: + break; + } + break; + } +#endif +#ifdef WLAN_FEATURE_11AC + case SIR_MAC_ACTION_VHT: + { + if (psessionEntry->vhtCapability) + { + switch (pActionHdr->actionID) + { + case SIR_MAC_VHT_OPMODE_NOTIFICATION: + __limProcessOperatingModeActionFrame(pMac,pRxPacketInfo,psessionEntry); + break; + case SIR_MAC_VHT_GID_NOTIFICATION: + /* Only if ini supports it */ + if (psessionEntry->enableVhtGid) + __limProcessGidManagementActionFrame(pMac,pRxPacketInfo,psessionEntry); + break; + default: + break; + } + } + break; + } +#endif + default: + PELOGE(limLog(pMac, LOGE, FL("Action category %d not handled"), pActionHdr->category);) + break; + } +} + +/** + * limProcessActionFrameNoSession + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Action frame reception and no session. + * Currently only public action frames can be received from + * a non-associated station. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pBd - A pointer to Buffer descriptor + associated PDUs + * @return None + */ + +void +limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd) +{ + tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd); + tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr = (tpSirMacVendorSpecificPublicActionFrameHdr) pBody; + + limLog( pMac, LOG1, "Received a Action frame -- no session"); + + switch ( pActionHdr->category ) + { + case SIR_MAC_ACTION_PUBLIC_USAGE: + switch(pActionHdr->actionID) { + case SIR_MAC_ACTION_VENDOR_SPECIFIC: + { + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 }; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + //Check if it is a P2P public action frame. + if (vos_mem_compare(pActionHdr->Oui, P2POui, 4)) + { + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0, + WDA_GET_RX_CH( pBd ), NULL, 0); + } + else + { + limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"), + pActionHdr->Oui[0], pActionHdr->Oui[1], pActionHdr->Oui[2], pActionHdr->Oui[3] ); + } + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x "), pActionHdr->actionID);) + break; + } + break; + default: + PELOGE(limLog(pMac, LOG1, FL("Unhandled action frame without session -- %x "), pActionHdr->category);) + break; + + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c new file mode 100644 index 0000000000000..7c510d0dc5811 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c @@ -0,0 +1,1937 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessAssocReqFrame.cc contains the code + * for processing Re/Association Request Frame. + * Author: Chandra Modumudi + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniCfgSta.h" +#include "sirApi.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "pmmApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limAdmitControl.h" +#include "palApi.h" +#include "limSessionUtils.h" +#ifdef WLAN_FEATURE_11W +#include "wniCfgAp.h" +#endif + + +#include "vos_types.h" +#include "vos_utils.h" +/** + * limConvertSupportedChannels + * + *FUNCTION: + * This function is called by limProcessAssocReqFrame() to + * parse the channel support IE in the Assoc/Reassoc Request + * frame, and send relevant information in the SME_ASSOC_IND + * + *NOTE: + * + * @param pMac - A pointer to Global MAC structure + * @param pMlmAssocInd - A pointer to SME ASSOC/REASSOC IND + * @param assocReq - A pointer to ASSOC/REASSOC Request frame + * + * @return None + */ +static void +limConvertSupportedChannels(tpAniSirGlobal pMac, + tpLimMlmAssocInd pMlmAssocInd, + tSirAssocReq *assocReq) +{ + + tANI_U16 i, j, index=0; + tANI_U8 firstChannelNumber; + tANI_U8 numberOfChannel; + tANI_U8 nextChannelNumber; + + if(assocReq->supportedChannels.length >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + limLog(pMac, LOG1, FL("Number of supported channels:%d is more than " + "MAX"), assocReq->supportedChannels.length); + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + + for(i=0; i < (assocReq->supportedChannels.length); i++) + { + // Get First Channel Number + firstChannelNumber = assocReq->supportedChannels.supportedChannels[i]; + pMlmAssocInd->supportedChannels.channelList[index] = firstChannelNumber; + i++; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + // Get Number of Channels in a Subband + numberOfChannel = assocReq->supportedChannels.supportedChannels[i]; + PELOG2(limLog(pMac, LOG2, FL("Rcv AssocReq: chnl=%d, numOfChnl=%d "), + firstChannelNumber, numberOfChannel);) + + if (numberOfChannel > 1) + { + nextChannelNumber = firstChannelNumber; + if(SIR_BAND_5_GHZ == limGetRFBand(firstChannelNumber)) + { + for (j=1; j < numberOfChannel; j++) + { + nextChannelNumber += SIR_11A_FREQUENCY_OFFSET; + pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + } + } + else if(SIR_BAND_2_4_GHZ == limGetRFBand(firstChannelNumber)) + { + for (j=1; j < numberOfChannel; j++) + { + nextChannelNumber += SIR_11B_FREQUENCY_OFFSET; + pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + } + } + } + } + + pMlmAssocInd->supportedChannels.numChnl = (tANI_U8) index; + PELOG2(limLog(pMac, LOG2, + FL("Send AssocInd to WSM: spectrum ON, minPwr %d, maxPwr %d, " + "numChnl %d"), + pMlmAssocInd->powerCap.minTxPower, + pMlmAssocInd->powerCap.maxTxPower, + pMlmAssocInd->supportedChannels.numChnl);) +} + +/**--------------------------------------------------------------- +\fn lim_check_sta_in_pe_entries +\brief This function is called by limProcessAssocReqFrame() +\ to check if STA entry already exists in any of the +\ PE entries of the AP. If it exists, deauth will be +\ sent on that session and the STA deletion will +\ happen. After this, the ASSOC request will be +\ processed +\ +\param pMac - A pointer to Global MAC structure +\param pHdr - A pointer to the MAC header +\return None +------------------------------------------------------------------*/ +void lim_check_sta_in_pe_entries(tpAniSirGlobal pMac, tpSirMacMgmtHdr pHdr) +{ + tANI_U8 i; + tANI_U16 assocId = 0; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry=NULL; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + if ((&pMac->lim.gpSession[i] != NULL) && + (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].pePersona == VOS_STA_SAP_MODE)) { + + psessionEntry = &pMac->lim.gpSession[i]; + + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &assocId, + &psessionEntry->dph.dphHashTable); + if (pStaDs +#ifdef WLAN_FEATURE_11W + && !pStaDs->rmfEnabled +#endif + ) { + limLog(pMac, LOGE, + FL("Sending Deauth and Deleting existing STA entry: " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + (tANI_U8 *) pHdr->sa, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + break; + } + } + } +} + +/**--------------------------------------------------------------- +\fn limProcessAssocReqFrame +\brief This function is called by limProcessMessageQueue() +\ upon Re/Association Request frame reception in +\ BTAMP AP or Soft AP role. +\ +\param pMac +\param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs +\param subType - Indicates whether it is Association Request(=0) +\ or Reassociation Request(=1) frame +\return None +------------------------------------------------------------------*/ +void +limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tANI_U8 subType, tpPESession psessionEntry) +{ + tANI_U8 updateContext; + tANI_U8 *pBody; + tANI_U16 peerIdx, temp; + tANI_U32 val; + tANI_S32 framelen; + tSirRetStatus status; + tpSirMacMgmtHdr pHdr; + struct tLimPreAuthNode *pStaPreAuthContext; + tAniAuthType authType; + tSirMacCapabilityInfo localCapabilities; + tpDphHashNode pStaDs = NULL; + tpSirAssocReq pAssocReq, pTempAssocReq; + tLimMlmStates mlmPrevState; + tDot11fIERSN Dot11fIERSN; + tDot11fIEWPA Dot11fIEWPA; + tANI_U32 phyMode; + tHalBitVal qosMode; + tHalBitVal wsmMode, wmeMode; + tANI_U8 *wpsIe = NULL; + tANI_U8 *ht_cap_ie = NULL; + tSirMacRateSet basicRates; + tANI_U8 i = 0, j = 0; + tANI_BOOLEAN pmfConnection = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_11W + tPmfSaQueryTimerId timerId; + tANI_U32 retryInterval; +#endif + bool assoc_req_copied = false; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + limGetQosMode(psessionEntry, &qosMode); + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limLog(pMac, LOG1, FL("Received %s Req Frame on sessionid: %d systemrole %d" + " limMlmState %d from: "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, psessionEntry->limSystemRole, + psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->sa)); + + lim_check_sta_in_pe_entries(pMac, pHdr); + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE ) + { + limLog(pMac, LOGE, FL("received unexpected ASSOC REQ on sessionid: %d " + "sys subType=%d for role=%d from: "MAC_ADDRESS_STR), + psessionEntry->peSessionId, + subType, psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pHdr->sa)); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + WDA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen); + return; + } + + // Get pointer to Re/Association Request frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Re/Assoc Req frame from a BC/MC address + // Log error and ignore it + limLog(pMac, LOGE, FL("Received %s Req on sessionid: %d frame from a " + "BC/MC address"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, + MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, (tANI_U8 *) pBody, framelen); + + if (vos_mem_compare((tANI_U8* ) pHdr->sa, (tANI_U8 *) pHdr->da, + (tANI_U8) (sizeof(tSirMacAddr)))) + { + limLog(pMac, LOGE, FL("Rejected Assoc Req frame Since same mac as" + " SAP/GO")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + return ; + } + + // If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON + if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + limLog(pMac, LOGE, FL("TKIP counter measure is active")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_MIC_FAILURE_REASON, + 1, + pHdr->sa, + subType, 0, psessionEntry); + return; + } + + // Allocate memory for the Assoc Request frame + pAssocReq = vos_mem_malloc(sizeof(*pAssocReq)); + if (NULL == pAssocReq) + { + limLog(pMac, LOGP, FL("Allocate Memory failed in AssocReq")); + return; + } + vos_mem_set((void *)pAssocReq , sizeof(*pAssocReq), 0); + + // Parse Assoc Request frame + if (subType == LIM_ASSOC) + status = sirConvertAssocReqFrame2Struct(pMac, pBody, framelen, pAssocReq); + else + status = sirConvertReassocReqFrame2Struct(pMac, pBody, framelen, pAssocReq); + + if (status != eSIR_SUCCESS) + { + limLog(pMac, LOGW, FL("Parse error AssocRequest, length=%d from "MAC_ADDRESS_STR), + framelen, MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, pHdr->sa, subType, 0, psessionEntry); + goto error; + } + + pAssocReq->assocReqFrame = vos_mem_malloc(framelen); + if ( NULL == pAssocReq->assocReqFrame ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory for the assoc req, " + "length=%d from "),framelen); + goto error; + } + + vos_mem_copy((tANI_U8 *) pAssocReq->assocReqFrame, + (tANI_U8 *) pBody, framelen); + pAssocReq->assocReqFrameLength = framelen; + + if (cfgGetCapabilityInfo(pMac, &temp,psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve Capabilities")); + goto error; + } + limCopyU16((tANI_U8 *) &localCapabilities, temp); + + if (limCompareCapabilities(pMac, + pAssocReq, + &localCapabilities,psessionEntry) == false) + { + limLog(pMac, LOGW, FL("local caps mismatch received caps")); + limLog(pMac, LOGW, FL("Received %s Req with unsupported " + "capabilities from"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Capabilities of requesting STA does not match with + * local capabilities. Respond with 'unsupported capabilities' + * status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + } + + updateContext = false; + + if (limCmpSSid(pMac, &pAssocReq->ssId, psessionEntry) == false) + { + limLog(pMac, LOGW, FL("Received %s Req with unmatched ssid ( Received" + " SSID: %.*s current SSID: %.*s ) from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", pAssocReq->ssId.length, + pAssocReq->ssId.ssId, psessionEntry->ssId.length, + psessionEntry->ssId.ssId, MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Received Re/Association Request with either + * Broadcast SSID OR with SSID that does not + * match with local one. + * Respond with unspecified status code. + */ + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + } + + /*************************************************************** + ** Verify if the requested rates are available in supported rate + ** set or Extended rate set. Some APs are adding basic rates in + ** Extended rateset IE + ***************************************************************/ + basicRates.numRates = 0; + + for(i = 0; i < pAssocReq->supportedRates.numRates && (i < SIR_MAC_RATESET_EID_MAX); i++) + { + basicRates.rate[i] = pAssocReq->supportedRates.rate[i]; + basicRates.numRates++; + } + + for(j = 0; (j < pAssocReq->extendedRates.numRates) && (i < SIR_MAC_RATESET_EID_MAX); i++,j++) + { + basicRates.rate[i] = pAssocReq->extendedRates.rate[j]; + basicRates.numRates++; + } + if (limCheckRxBasicRates(pMac, basicRates, psessionEntry) == false) + { + limLog(pMac, LOGW, FL("Received %s Req with unsupported " + "rates from"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Requesting STA does not support ALL BSS basic + * rates. Respond with 'basic rates not supported' + * status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + } + + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) && + (pAssocReq->HTCaps.present)) + { + limLog(pMac, LOGE, FL("SOFTAP was in 11G only mode, rejecting legacy " + "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, pHdr->sa, subType, 0, psessionEntry ); + goto error; + + }//end if phyMode == 11G_only + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) && + (!pAssocReq->HTCaps.present)) + { + limLog(pMac, LOGE, FL("SOFTAP was in 11N only mode, rejecting legacy " + "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, pHdr->sa, subType, 0, psessionEntry ); + goto error; + }//end if PhyMode == 11N_only + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) && + (!pAssocReq->VHTCaps.present)) + { + limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, pHdr->sa, subType, 0, psessionEntry ); + limLog(pMac, LOGE, FL("SOFTAP was in 11AC only mode, reject")); + goto error; + }//end if PhyMode == 11AC_only + + /* Spectrum Management (11h) specific checks */ + if (localCapabilities.spectrumMgt) + { + tSirRetStatus status = eSIR_SUCCESS; + + /* If station is 11h capable, then it SHOULD send all mandatory + * IEs in assoc request frame. Let us verify that + */ + if (pAssocReq->capabilityInfo.spectrumMgt) + { + if (!((pAssocReq->powerCapabilityPresent) && (pAssocReq->supportedChannelsPresent))) + { + /* One or more required information elements are missing, log the peers error */ + if (!pAssocReq->powerCapabilityPresent) + { + limLog(pMac, LOG1, FL("LIM Info: Missing Power capability " + "IE in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + } + if (!pAssocReq->supportedChannelsPresent) + { + limLog(pMac, LOGW, FL("LIM Info: Missing Supported channel " + "IE in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + } + else + { + /* Assoc request has mandatory fields */ + status = limIsDot11hPowerCapabilitiesInRange(pMac, pAssocReq, psessionEntry); + if (eSIR_SUCCESS != status) + { + limLog(pMac, LOGW, FL("LIM Info: MinTxPower(STA) > " + "MaxTxPower(AP) in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + status = limIsDot11hSupportedChannelsValid(pMac, pAssocReq); + if (eSIR_SUCCESS != status) + { + limLog(pMac, LOGW, FL("LIM Info: wrong supported " + "channels (STA) in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + /* IEs are valid, use them if needed */ + } + } //if(assoc.capabilityInfo.spectrumMgt) + else + { + /* As per the capabiities, the spectrum management is not enabled on the station + * The AP may allow the associations to happen even if spectrum management is not + * allowed, if the transmit power of station is below the regulatory maximum + */ + + /* TODO: presently, this is not handled. In the current implemetation, the AP would + * allow the station to associate even if it doesn't support spectrum management. + */ + } + }// end of spectrum management related processing + + if ( (pAssocReq->HTCaps.present) && (limCheckMCSSet(pMac, pAssocReq->HTCaps.supportedMCSSet) == false)) + { + limLog(pMac, LOGW, FL("received %s req with unsupported" + "MCS Rate Set from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Requesting STA does not support ALL BSS MCS basic Rate set rates. + * Spec does not define any status code for this scenario. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + } + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_ONLY_POLICY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve 11g-only flag")); + goto error; + } + + if (!pAssocReq->extendedRatesPresent && val) + { + /** + * Received Re/Association Request from + * 11b STA when 11g only policy option + * is set. + * Reject with unspecified status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from 11b STA: ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + +#ifdef WLAN_DEBUG + pMac->lim.gLim11bStaAssocRejectCount++; +#endif + goto error; + } + } + +#ifdef WMM_APSD + // Save the QOS info element in assoc request.. + limGetWmeMode(pMac, &wmeMode); + if (wmeMode == eHAL_SET) + { + tpQosInfoSta qInfo; + + qInfo = (tpQosInfoSta) (pAssocReq->qosCapability.qosInfo); + + if ((pMac->lim.gWmmApsd.apsdEnable == 0) && (qInfo->ac_be || qInfo->ac_bk || qInfo->ac_vo || qInfo->ac_vi)) + { + limLog(pMac, LOGW, + FL("Rejecting Re/Assoc req from STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + limLog(pMac, LOGE, FL("APSD not enabled, qosInfo - 0x%x"), *qInfo); + + /** + * Received Re/Association Request from + * 11b STA when 11g only policy option + * is set. + * Reject with unspecified status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_WME_REFUSED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + limLog(pMac, LOGE, FL("APSD not enabled, qosInfo - 0x%x"), *qInfo); + goto error; + } + } +#endif + + // Check for 802.11n HT caps compatibility; are HT Capabilities + // turned on in lim? + if ( psessionEntry->htCapability ) + { + // There are; are they turned on in the STA? + if ( pAssocReq->HTCaps.present ) + { + // The station *does* support 802.11n HT capability... + + limLog( pMac, LOG1, FL( "AdvCodingCap:%d ChaWidthSet:%d " + "PowerSave:%d greenField:%d " + "shortGI20:%d shortGI40:%d" + "txSTBC:%d rxSTBC:%d delayBA:%d" + "maxAMSDUsize:%d DSSS/CCK:%d " + "PSMP:%d stbcCntl:%d lsigTXProt:%d"), + pAssocReq->HTCaps.advCodingCap, + pAssocReq->HTCaps.supportedChannelWidthSet, + pAssocReq->HTCaps.mimoPowerSave, + pAssocReq->HTCaps.greenField, + pAssocReq->HTCaps.shortGI20MHz, + pAssocReq->HTCaps.shortGI40MHz, + pAssocReq->HTCaps.txSTBC, + pAssocReq->HTCaps.rxSTBC, + pAssocReq->HTCaps.delayedBA, + pAssocReq->HTCaps.maximalAMSDUsize, + pAssocReq->HTCaps.dsssCckMode40MHz, + pAssocReq->HTCaps.psmp, + pAssocReq->HTCaps.stbcControlFrame, + pAssocReq->HTCaps.lsigTXOPProtection ); + + // Make sure the STA's caps are compatible with our own: + //11.15.2 Support of DSSS/CCK in 40 MHz + //the AP shall refuse association requests from an HT STA that has the DSSS/CCK + //Mode in 40 MHz subfield set to 1; + } + } // End if on HT caps turned on in lim. + + /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */ + vos_mem_set((tANI_U8*)&Dot11fIERSN, sizeof( Dot11fIERSN ), 0); + vos_mem_set((tANI_U8*)&Dot11fIEWPA, sizeof( Dot11fIEWPA ), 0); + + /* if additional IE is present, check if it has WscIE */ + if( pAssocReq->addIEPresent && pAssocReq->addIE.length ) + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + else + { + limLog(pMac, LOG1, FL("Assoc req addIEPresent = %d " + "addIE length = %d"), pAssocReq->addIEPresent, + pAssocReq->addIE.length); + } + /* when wpsIe is present, RSN/WPA IE is ignored */ + if( wpsIe == NULL ) + { + /** check whether as RSN IE is present */ + if(psessionEntry->limSystemRole == eLIM_AP_ROLE + && psessionEntry->pLimStartBssReq->privacy + && psessionEntry->pLimStartBssReq->rsnIE.length) + { + limLog(pMac, LOGE, + FL("RSN enabled auth, Re/Assoc req from STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + if(pAssocReq->rsnPresent) + { + if(pAssocReq->rsn.length) + { + // Unpack the RSN IE + dot11fUnpackIeRSN(pMac, + &pAssocReq->rsn.info[0], + pAssocReq->rsn.length, + &Dot11fIERSN); + + /* Check RSN version is supported or not */ + if(SIR_MAC_OUI_VERSION_1 == Dot11fIERSN.version) + { + /* check the groupwise and pairwise cipher suites */ + if(eSIR_SUCCESS != (status = limCheckRxRSNIeMatch(pMac, Dot11fIERSN, psessionEntry, + pAssocReq->HTCaps.present, &pmfConnection))) + { + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + /* some IE is not properly sent */ + /* received Association req frame with RSN IE but length is 0 */ + limSendAssocRspMgmtFrame( + pMac, + status, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + + } + } + else + { + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + /* received Association req frame with RSN IE version wrong */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + goto error; + + } + } + else + { + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA:" + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with RSN IE but length is 0 */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + + } + } /* end - if(pAssocReq->rsnPresent) */ + if((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent) + { + // Unpack the WPA IE + if(pAssocReq->wpa.length) + { + dot11fUnpackIeWPA(pMac, + &pAssocReq->wpa.info[4], //OUI is not taken care + pAssocReq->wpa.length, + &Dot11fIEWPA); + /* check the groupwise and pairwise cipher suites */ + if(eSIR_SUCCESS != (status = limCheckRxWPAIeMatch(pMac, Dot11fIEWPA, psessionEntry, pAssocReq->HTCaps.present))) + { + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with WPA IE but mismatch */ + limSendAssocRspMgmtFrame( + pMac, + status, + 1, + pHdr->sa, + subType, 0,psessionEntry); + goto error; + + } + } + else + { + limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with invalid WPA IE */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry); + + goto error; + }/* end - if(pAssocReq->wpa.length) */ + } /* end - if(pAssocReq->wpaPresent) */ + } /* end of if(psessionEntry->pLimStartBssReq->privacy + && psessionEntry->pLimStartBssReq->rsnIE->length) */ + + } /* end of if( ! pAssocReq->wscInfo.present ) */ + else + { + limLog(pMac, LOG1, FL("Assoc req WSE IE is present")); + } + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &peerIdx, &psessionEntry->dph.dphHashTable); + + /// Extract pre-auth context for the STA, if any. + pStaPreAuthContext = limSearchPreAuthList(pMac, pHdr->sa); + + if (pStaDs == NULL) + { + /// Requesting STA is not currently associated + if (peGetCurrentSTAsCount(pMac) == pMac->lim.gLimAssocStaLimit) + { + /** + * Maximum number of STAs that AP can handle reached. + * Send Association response to peer MAC entity + */ + limRejectAssociation(pMac, pHdr->sa, + subType, false, + (tAniAuthType) 0, 0, + false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + /// Check if STA is pre-authenticated. + if ((pStaPreAuthContext == NULL) || + (pStaPreAuthContext && + (pStaPreAuthContext->mlmState != + eLIM_MLM_AUTHENTICATED_STATE))) + { + /** + * STA is not pre-authenticated yet requesting + * Re/Association before Authentication. + * OR STA is in the process of getting authenticated + * and sent Re/Association request. + * Send Deauthentication frame with 'prior + * authentication required' reason code. + */ + limSendDeauthMgmtFrame( + pMac, + eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, //=9 + pHdr->sa, psessionEntry, FALSE); + + limLog(pMac, LOGW, FL("received %s req on sessionid: %d from STA " + "that does not have pre-auth context"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, + MAC_ADDR_ARRAY(pHdr->sa)); + goto error; + } + + /// Delete 'pre-auth' context of STA + authType = pStaPreAuthContext->authType; + limDeletePreAuthNode(pMac, pHdr->sa); + + // All is well. Assign AID (after else part) + + } // if (pStaDs == NULL) + else + { + // STA context does exist for this STA + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + /** + * Requesting STA is in some 'transient' state? + * Ignore the Re/Assoc Req frame by incrementing + * debug counter & logging error. + */ + if (subType == LIM_ASSOC) + { + +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropInvldState++; +#endif + limLog(pMac, LOG1, FL("received Assoc req in state " + "%X from "), pStaDs->mlmStaContext.mlmState); + } + else + { +#ifdef WLAN_DEBUG + pMac->lim.gLimNumReassocReqDropInvldState++; +#endif + limLog(pMac, LOG1, FL("received ReAssoc req in state %X" + " from "), pStaDs->mlmStaContext.mlmState); + } + limPrintMacAddr(pMac, pHdr->sa, LOG1); + limPrintMlmState(pMac, LOG1, (tLimMlmStates) pStaDs->mlmStaContext.mlmState); + + goto error; + } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + + /* STA sent association Request frame while already in + * 'associated' state */ + +#ifdef WLAN_FEATURE_11W + limLog(pMac, LOG1, FL("Re/Assoc request from station that is already associated")); + limLog(pMac, LOG1, FL("PMF enabled %d, SA Query state %d"), pStaDs->rmfEnabled, + pStaDs->pmfSaQueryState); + if (pStaDs->rmfEnabled) + { + switch (pStaDs->pmfSaQueryState) + { + + // start SA Query procedure, respond to Association Request + // with try again later + case DPH_SA_QUERY_NOT_IN_PROGRESS: + /* + * We should reset the retry counter before we start + * the SA query procedure, otherwise in next set of SA query + * procedure we will end up using the stale value. + */ + pStaDs->pmfSaQueryRetryCount = 0; + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1, + pHdr->sa, subType, pStaDs, psessionEntry); + limSendSaQueryRequestFrame( + pMac, (tANI_U8 *)&(pStaDs->pmfSaQueryCurrentTransId), + pHdr->sa, psessionEntry); + pStaDs->pmfSaQueryStartTransId = pStaDs->pmfSaQueryCurrentTransId; + pStaDs->pmfSaQueryCurrentTransId++; + + // start timer for SA Query retry + if (tx_timer_activate(&pStaDs->pmfSaQueryTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("PMF SA Query timer activation failed!")); + goto error; + } + + pStaDs->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS; + goto error; + + // SA Query procedure still going, respond to Association + // Request with try again later + case DPH_SA_QUERY_IN_PROGRESS: + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1, + pHdr->sa, subType, 0, psessionEntry); + goto error; + + // SA Query procedure timed out, accept Association Request + // normally + case DPH_SA_QUERY_TIMED_OUT: + pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + break; + } + } +#endif + + /* no change in the capability so drop the frame */ + if ((VOS_TRUE == vos_mem_compare(&pStaDs->mlmStaContext.capabilityInfo, + &pAssocReq->capabilityInfo, + sizeof(tSirMacCapabilityInfo)))&& + (subType == LIM_ASSOC)) + { + limLog(pMac, LOGE, FL(" Received Assoc req in state %X STAid=%d"), + pStaDs->mlmStaContext.mlmState,peerIdx); + goto error; + } + else + { + /** + * STA sent Re/association Request frame while already in + * 'associated' state. Update STA capabilities and + * send Association response frame with same AID + */ + pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo; + if (pStaPreAuthContext && + (pStaPreAuthContext->mlmState == + eLIM_MLM_AUTHENTICATED_STATE)) + { + /// STA has triggered pre-auth again + authType = pStaPreAuthContext->authType; + limDeletePreAuthNode(pMac, pHdr->sa); + } + else + authType = pStaDs->mlmStaContext.authType; + + updateContext = true; + if (dphInitStaState(pMac, pHdr->sa, peerIdx, true, &psessionEntry->dph.dphHashTable) + == NULL) + { + limLog(pMac, LOGE, FL("could not Init STAid=%d"), peerIdx); + goto error; + } + } + goto sendIndToSme; + } // end if (lookup for STA in perStaDs fails) + + + + // check if sta is allowed per QoS AC rules + limGetWmeMode(psessionEntry, &wmeMode); + if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET)) + { + // for a qsta, check if the requested Traffic spec + // is admissible + // for a non-qsta check if the sta can be admitted + if (pAssocReq->addtsPresent) + { + tANI_U8 tspecIdx = 0; //index in the sch tspec table. + if (limAdmitControlAddTS(pMac, pHdr->sa, &(pAssocReq->addtsReq), + &(pAssocReq->qosCapability), 0, false, NULL, &tspecIdx, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGW, FL("AdmitControl: TSPEC rejected")); + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_QAP_NO_BANDWIDTH_REASON, + 1, + pHdr->sa, + subType, 0,psessionEntry); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropACRejectTS++; +#endif + goto error; + } + } + else if (limAdmitControlAddSta(pMac, pHdr->sa, false) + != eSIR_SUCCESS) + { + limLog(pMac, LOGW, FL("AdmitControl: Sta rejected")); + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_QAP_NO_BANDWIDTH_REASON, + 1, + pHdr->sa, + subType, 0,psessionEntry); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropACRejectSta++; +#endif + goto error; + } + + // else all ok + limLog(pMac, LOG1, FL("AdmitControl: Sta OK!")); + } + + /** + * STA is Associated ! + */ + limLog(pMac, LOGE, FL("Received %s Req successful from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * AID for this association will be same as the peer Index used in DPH table. + * Assign unused/least recently used peer Index from perStaDs. + * NOTE: limAssignPeerIdx() assigns AID values ranging + * between 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT) + */ + + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + + if (!peerIdx) + { + // Could not assign AID + // Reject association + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + /** + * Add an entry to hash table maintained by DPH module + */ + + pStaDs = dphAddHashEntry(pMac, pHdr->sa, peerIdx, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + // Could not add hash table entry at DPH + limLog(pMac, LOGE, + FL("could not add hash entry at DPH for aid=%d, MacAddr:" + MAC_ADDRESS_STR), + peerIdx,MAC_ADDR_ARRAY(pHdr->sa)); + + // Release AID + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + +sendIndToSme: + /* + * check here if the parsedAssocReq already + * pointing to the AssocReq and free it before + * assigning this new pAssocReq + */ + if (psessionEntry->parsedAssocReq != NULL) + { + pTempAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + if (pTempAssocReq != NULL) + { + if (pTempAssocReq->assocReqFrame) + { + vos_mem_free(pTempAssocReq->assocReqFrame); + pTempAssocReq->assocReqFrame = NULL; + pTempAssocReq->assocReqFrameLength = 0; + } + vos_mem_free(pTempAssocReq); + pTempAssocReq = NULL; + } + + psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq; + assoc_req_copied = true; + } + + + pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present; +#ifdef WLAN_FEATURE_11AC + pStaDs->mlmStaContext.vhtCapability = pAssocReq->VHTCaps.present; +#endif + pStaDs->qos.addtsPresent = (pAssocReq->addtsPresent==0) ? false : true; + pStaDs->qos.addts = pAssocReq->addtsReq; + pStaDs->qos.capability = pAssocReq->qosCapability; + pStaDs->versionPresent = 0; + /* short slot and short preamble should be updated before doing limaddsta */ + pStaDs->shortPreambleEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortPreamble; + pStaDs->shortSlotTimeEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortSlotTime; + + if (pAssocReq->propIEinfo.versionPresent) //update STA version info + { + pStaDs->versionPresent = 1; + pStaDs->version = pAssocReq->propIEinfo.version; + } + pStaDs->propCapability = 0; + if (pAssocReq->propIEinfo.capabilityPresent) + { + if (sirGetCfgPropCaps(pMac, &pStaDs->propCapability)) + pStaDs->propCapability &= pAssocReq->propIEinfo.capability; + } + + pStaDs->valid = 0; + pStaDs->mlmStaContext.authType = authType; + pStaDs->staType = STA_ENTRY_PEER; + + //TODO: If listen interval is more than certain limit, reject the association. + //Need to check customer requirements and then implement. + pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval; + pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo; + + /* The following count will be used to knock-off the station if it doesn't + * come back to receive the buffered data. The AP will wait for numTimSent number + * of beacons after sending TIM information for the station, before assuming that + * the station is no more associated and disassociates it + */ + + /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/ + pStaDs->timWaitCount = (tANI_U8)GET_TIM_WAIT_COUNT(pAssocReq->listenInterval); + + /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */ + pStaDs->curTxMpduCnt = 0; + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) + { + pStaDs->htGreenfield = (tANI_U8)pAssocReq->HTCaps.greenField; + pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocReq->HTCaps.dsssCckMode40MHz; + pStaDs->htLsigTXOPProtection = (tANI_U8)pAssocReq->HTCaps.lsigTXOPProtection; + pStaDs->htMaxAmsduLength = (tANI_U8)pAssocReq->HTCaps.maximalAMSDUsize; + pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor; + pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave; + + /* pAssocReq will be copied to psessionEntry->parsedAssocReq later */ + ht_cap_ie = ((tANI_U8 *) &pAssocReq->HTCaps) + 1; + + /* check whether AP is enabled with shortGI */ + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val) != + eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, + FL("could not retrieve shortGI 20Mhz CFG"));) + goto error; + } + if (val) { + pStaDs->htShortGI20Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI20MHz; + } else { + /* Unset htShortGI20Mhz in ht_caps*/ + *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S); + pStaDs->htShortGI20Mhz = 0; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val) != + eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, + FL("could not retrieve shortGI 40Mhz CFG"));) + goto error; + } + if (val) { + pStaDs->htShortGI40Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI40MHz; + } else { + /* Unset htShortGI40Mhz in ht_caps */ + *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S); + pStaDs->htShortGI40Mhz = 0; + } + + pStaDs->htSupportedChannelWidthSet = (tANI_U8)pAssocReq->HTCaps.supportedChannelWidthSet; + /* peer just follows AP; so when we are softAP/GO, we just store our session entry's secondary channel offset here in peer INFRA STA + * However, if peer's 40MHz channel width support is disabled then secondary channel will be zero + */ + pStaDs->htSecondaryChannelOffset = (pStaDs->htSupportedChannelWidthSet)?psessionEntry->htSecondaryChannelOffset:0; +#ifdef WLAN_FEATURE_11AC + if(pAssocReq->operMode.present) + { + pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pAssocReq->operMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) ? WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ); + pStaDs->htSupportedChannelWidthSet = (tANI_U8)(pAssocReq->operMode.chanWidth ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ); + } + else if (pAssocReq->VHTCaps.present) + { + // Check if STA has enabled it's channel bonding mode. + // If channel bonding mode is enabled, we decide based on SAP's current configuration. + // else, we set it to VHT20. + pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pStaDs->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) ? + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ : + psessionEntry->vhtTxChannelWidthSet ); + pStaDs->htMaxRxAMpduFactor = pAssocReq->VHTCaps.maxAMPDULenExp; + } + + // Lesser among the AP and STA bandwidth of operation. + pStaDs->htSupportedChannelWidthSet = + (pStaDs->htSupportedChannelWidthSet < psessionEntry->htSupportedChannelWidthSet) ? + pStaDs->htSupportedChannelWidthSet : psessionEntry->htSupportedChannelWidthSet ; + +#endif + pStaDs->baPolicyFlag = 0xFF; + pStaDs->htLdpcCapable = (tANI_U8)pAssocReq->HTCaps.advCodingCap; + } + + if(pAssocReq->VHTCaps.present && pAssocReq->wmeInfoPresent) + { + pStaDs->vhtLdpcCapable = (tANI_U8)pAssocReq->VHTCaps.ldpcCodingCap; + } + + if (!pAssocReq->wmeInfoPresent) { + pStaDs->mlmStaContext.htCapability = 0; +#ifdef WLAN_FEATURE_11AC + pStaDs->mlmStaContext.vhtCapability = 0; +#endif + } +#ifdef WLAN_FEATURE_11AC +if (limPopulateMatchingRateSet(pMac, + pStaDs, + &(pAssocReq->supportedRates), + &(pAssocReq->extendedRates), + pAssocReq->HTCaps.supportedMCSSet, + &(pAssocReq->propIEinfo.propRates), + psessionEntry , &pAssocReq->VHTCaps) + != eSIR_SUCCESS) +#else + + if (limPopulateMatchingRateSet(pMac, + pStaDs, + &(pAssocReq->supportedRates), + &(pAssocReq->extendedRates), + pAssocReq->HTCaps.supportedMCSSet, + &(pAssocReq->propIEinfo.propRates), psessionEntry) != eSIR_SUCCESS) +#endif + { + // Could not update hash table entry at DPH with rateset + limLog(pMac, LOGE, + FL("could not update hash entry at DPH for aid=%d, MacAddr: " + MAC_ADDRESS_STR), + peerIdx, MAC_ADDR_ARRAY(pHdr->sa)); + + // Release AID + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, peerIdx, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + if(psessionEntry->parsedAssocReq) + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + +#ifdef WLAN_FEATURE_11AC + if(pAssocReq->operMode.present) + { + pStaDs->vhtSupportedRxNss = pAssocReq->operMode.rxNSS + 1; + } + else + { + pStaDs->vhtSupportedRxNss = ((pStaDs->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2) + == MCSMAPMASK2x2) ? 1 : 2; + } +#endif + + vos_mem_copy((tANI_U8 *) &pStaDs->mlmStaContext.propRateSet, + (tANI_U8 *) &(pAssocReq->propIEinfo.propRates), + pAssocReq->propIEinfo.propRates.numPropRates + 1); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + + pStaDs->qosMode = eANI_BOOLEAN_FALSE; + pStaDs->lleEnabled = eANI_BOOLEAN_FALSE; + if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET)) + { + pStaDs->lleEnabled = eANI_BOOLEAN_TRUE; + pStaDs->qosMode = eANI_BOOLEAN_TRUE; + } + + pStaDs->wmeEnabled = eANI_BOOLEAN_FALSE; + pStaDs->wsmEnabled = eANI_BOOLEAN_FALSE; + limGetWmeMode(psessionEntry, &wmeMode); + if ((! pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent && (wmeMode == eHAL_SET)) + { + pStaDs->wmeEnabled = eANI_BOOLEAN_TRUE; + pStaDs->qosMode = eANI_BOOLEAN_TRUE; + limGetWsmMode(psessionEntry, &wsmMode); + /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD + can coexist */ + if( pAssocReq->WMMInfoStation.present) + { + /* check whether AP supports or not */ + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) + && (psessionEntry->apUapsdEnable == 0) && (pAssocReq->WMMInfoStation.acbe_uapsd + || pAssocReq->WMMInfoStation.acbk_uapsd + || pAssocReq->WMMInfoStation.acvo_uapsd + || pAssocReq->WMMInfoStation.acvi_uapsd)) + { + + /** + * Received Re/Association Request from + * STA when UPASD is not supported. + */ + limLog( pMac, LOGE, FL( "AP do not support UPASD " + "REASSOC Failed" )); + /* During wlan fuzz tests for softAP when mal-formed assoc req is + * sent to AP due to delSTA is not done in firmnware UMAC is + * stuck in some bad state.if we set this flag delsta will happen + * and UMAC will recover*/ + if (updateContext) + { + pStaDs->mlmStaContext.updateContext = 1; + } + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, peerIdx, true, + (tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry); + + + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + else + { + /* update UAPSD and send it to LIM to add STA */ + pStaDs->qos.capability.qosInfo.acbe_uapsd = pAssocReq->WMMInfoStation.acbe_uapsd; + pStaDs->qos.capability.qosInfo.acbk_uapsd = pAssocReq->WMMInfoStation.acbk_uapsd; + pStaDs->qos.capability.qosInfo.acvo_uapsd = pAssocReq->WMMInfoStation.acvo_uapsd; + pStaDs->qos.capability.qosInfo.acvi_uapsd = pAssocReq->WMMInfoStation.acvi_uapsd; + pStaDs->qos.capability.qosInfo.maxSpLen = pAssocReq->WMMInfoStation.max_sp_length; + } + } + if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET)) + pStaDs->wsmEnabled = eANI_BOOLEAN_TRUE; + + } + + // Re/Assoc Response frame to requesting STA + pStaDs->mlmStaContext.subType = subType; + +#ifdef WLAN_FEATURE_11W + pStaDs->rmfEnabled = (pmfConnection) ? 1 : 0; + pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + timerId.fields.sessionId = psessionEntry->peSessionId; + timerId.fields.peerIdx = peerIdx; + if (wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + &retryInterval) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not retrieve PMF SA Query retry interval value")); + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + goto error; + } + if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_APMIN > retryInterval) + { + retryInterval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_APDEF; + } + if (tx_timer_create(&pStaDs->pmfSaQueryTimer, "PMF SA Query timer", + limPmfSaQueryTimerHandler, timerId.value, + SYS_MS_TO_TICKS((retryInterval * 1024) / 1000), + 0, TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not create PMF SA Query timer")); + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + goto error; + } +#endif + + if (pAssocReq->ExtCap.present) + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + pAssocReq->ExtCap.bytes; + pStaDs->timingMeasCap = 0; + pStaDs->timingMeasCap |= (p_ext_cap->timingMeas)? + RTT_TIMING_MEAS_CAPABILITY: + RTT_INVALID; + pStaDs->timingMeasCap |= (p_ext_cap->fineTimingMeas)? + RTT_FINE_TIMING_MEAS_CAPABILITY: + RTT_INVALID; + PELOG1(limLog(pMac, LOG1, + FL("ExtCap present, timingMeas: %d fineTimingMeas: %d"), + p_ext_cap->timingMeas, + p_ext_cap->fineTimingMeas);) + } + else + { + pStaDs->timingMeasCap = 0; + PELOG1(limLog(pMac, LOG1, FL("ExtCap not present"));) + } + + // BTAMP: Storing the parsed assoc request in the psessionEntry array + if(psessionEntry->parsedAssocReq) + psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq; + assoc_req_copied = true; + + /* BTAMP: If STA context already exist (ie. updateContext = 1) + * for this STA, then we should delete the old one, and add + * the new STA. This is taken care of in the limDelSta() routine. + * + * Prior to BTAMP, we were setting this flag so that when + * PE receives SME_ASSOC_CNF, and if this flag is set, then + * PE shall delete the old station and then add. But now in + * BTAMP, we're directly adding station before waiting for + * SME_ASSOC_CNF, so we can do this now. + */ + if (!updateContext) + { + pStaDs->mlmStaContext.updateContext = 0; + + // BTAMP: Add STA context at HW - issue WDA_ADD_STA_REQ to HAL + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not Add STA with assocId=%d"), + pStaDs->assocId); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + if(psessionEntry->parsedAssocReq) + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + } + else + { + pStaDs->mlmStaContext.updateContext = 1; + + mlmPrevState = pStaDs->mlmStaContext.mlmState; + + /* As per the HAL/FW needs the reassoc req need not be calling limDelSta */ + if(subType != LIM_REASSOC) + { + //we need to set the mlmState here in order differentiate in limDelSta. + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE; + if(limDelSta(pMac, pStaDs, true, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not DEL STA with assocId=%d staId %d"), + pStaDs->assocId, pStaDs->staIndex); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + //Restoring the state back. + pStaDs->mlmStaContext.mlmState = mlmPrevState; + if(psessionEntry->parsedAssocReq) + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + } + else + { + /* mlmState is changed in limAddSta context */ + /* use the same AID, already allocated */ + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, FL( "AP do not support UPASD " + "REASSOC Failed")); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry); + + //Restoring the state back. + pStaDs->mlmStaContext.mlmState = mlmPrevState; + if(psessionEntry->parsedAssocReq) + pAssocReq = + psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + + } + + } + + /* AddSta is sucess here */ + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) + { + + /** Update in the HAL Station Table for the Update of the Protection Mode */ + limPostSMStateUpdate(pMac,pStaDs->staIndex, + pStaDs->htMIMOPSState, + pStaDs->staAddr, psessionEntry->smeSessionId); + } + + return; + +error: + if (pAssocReq != NULL) { + if (pAssocReq->assocReqFrame) { + vos_mem_free(pAssocReq->assocReqFrame); + pAssocReq->assocReqFrame = NULL; + pAssocReq->assocReqFrameLength = 0; + } + vos_mem_free(pAssocReq); + if (assoc_req_copied) /* to avoid double free */ + if(psessionEntry->parsedAssocReq) + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + + /* If it is not duplicate Assoc request then only free the memory */ + if ((pStaDs != NULL) && + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) { + if (psessionEntry->parsedAssocReq != NULL) { + pTempAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + if (pTempAssocReq != NULL) { + if (pTempAssocReq->assocReqFrame) { + vos_mem_free(pTempAssocReq->assocReqFrame); + pTempAssocReq->assocReqFrame = NULL; + pTempAssocReq->assocReqFrameLength = 0; + } + vos_mem_free(pTempAssocReq); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + } + } + + return; + +} /*** end limProcessAssocReqFrame() ***/ + + + +/**--------------------------------------------------------------- +\fn limSendMlmAssocInd +\brief This function sends either LIM_MLM_ASSOC_IND +\ or LIM_MLM_REASSOC_IND to SME. +\ +\param pMac +\param *pStaDs - Station DPH hash entry +\param psessionEntry - PE session entry +\return None + + * ?????? How do I get + * - subtype =====> psessionEntry->parsedAssocReq.reassocRequest + * - aid =====> pStaDs->assocId + * - pHdr->sa =====> pStaDs->staAddr + * - authType + * - pHdr->seqControl =====> no longer needed + * - pStaDs +------------------------------------------------------------------*/ +void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tpLimMlmAssocInd pMlmAssocInd = NULL; + tpLimMlmReassocInd pMlmReassocInd; + tpSirAssocReq pAssocReq; + tANI_U16 temp; + tANI_U32 phyMode; + tANI_U8 subType; + tANI_U8 *wpsIe = NULL; + tANI_U32 tmp; + tANI_U16 i, j=0; + + // Get a copy of the already parsed Assoc Request + pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId]; + + // Get the phyMode + limGetPhyMode(pMac, &phyMode, psessionEntry); + // Extract pre-auth context for the peer BTAMP-STA, if any. + + // Determiine if its Assoc or ReAssoc Request + if (pAssocReq->reassocRequest == 1) + subType = LIM_REASSOC; + else + subType = LIM_ASSOC; + + limLog(pMac, LOG1, FL("Sessionid %d ssid %s subtype %d Associd %d staAddr " + MAC_ADDRESS_STR), psessionEntry->peSessionId, pAssocReq->ssId.ssId, + subType,pStaDs->assocId,MAC_ADDR_ARRAY(pStaDs->staAddr)); + + if (subType == LIM_ASSOC || subType == LIM_REASSOC) + { + temp = sizeof(tLimMlmAssocInd); + + pMlmAssocInd = vos_mem_malloc(temp); + if (NULL == pMlmAssocInd) + { + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + limLog(pMac, LOGP, FL("AllocateMemory failed for pMlmAssocInd")); + return; + } + vos_mem_set(pMlmAssocInd, temp ,0); + + vos_mem_copy((tANI_U8 *)pMlmAssocInd->peerMacAddr, + (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); + + pMlmAssocInd->aid = pStaDs->assocId; + vos_mem_copy((tANI_U8 *)&pMlmAssocInd->ssId, + (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1); + pMlmAssocInd->sessionId = psessionEntry->peSessionId; + pMlmAssocInd->authType = pStaDs->mlmStaContext.authType; + + pMlmAssocInd->capabilityInfo = pAssocReq->capabilityInfo; + + // Fill in RSN IE information + pMlmAssocInd->rsnIE.length = 0; + // if WPS IE is present, ignore RSN IE + if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) { + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + } + if (pAssocReq->rsnPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Assoc Req RSN IE len = %d"), + pAssocReq->rsn.length); + pMlmAssocInd->rsnIE.length = 2 + pAssocReq->rsn.length; + pMlmAssocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID; + pMlmAssocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length; + vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[2], + pAssocReq->rsn.info, + pAssocReq->rsn.length); + } + + // Fill in 802.11h related info + if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent) + { + pMlmAssocInd->spectrumMgtIndicator = eSIR_TRUE; + pMlmAssocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower; + pMlmAssocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower; + limConvertSupportedChannels(pMac, pMlmAssocInd, pAssocReq); + } + else + pMlmAssocInd->spectrumMgtIndicator = eSIR_FALSE; + + + /* This check is to avoid extra Sec IEs present incase of WPS */ + if (pAssocReq->wpaPresent && (NULL == wpsIe)) + { + if((pMlmAssocInd->rsnIE.length + pAssocReq->wpa.length) >= SIR_MAC_MAX_IE_LENGTH) + { + PELOGE(limLog(pMac, LOGE, FL("rsnIEdata index out of bounds %d"), + pMlmAssocInd->rsnIE.length);) + vos_mem_free(pMlmAssocInd); + return; + } + pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length] = SIR_MAC_WPA_EID; + pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 1] = pAssocReq->wpa.length; + vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 2], + pAssocReq->wpa.info, + pAssocReq->wpa.length); + pMlmAssocInd->rsnIE.length += 2 + pAssocReq->wpa.length; + } + + + pMlmAssocInd->addIE.length = 0; + if (pAssocReq->addIEPresent) + { + vos_mem_copy(&pMlmAssocInd->addIE.addIEdata, + pAssocReq->addIE.addIEdata, + pAssocReq->addIE.length); + + pMlmAssocInd->addIE.length = pAssocReq->addIE.length; + } + + /* Add HT Capabilities into addIE for OBSS processing in hostapd */ + if (pAssocReq->HTCaps.present) + { + if (pMlmAssocInd->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN + 2 < + SIR_MAC_MAX_IE_LENGTH) + { + pMlmAssocInd->addIE.addIEdata[pMlmAssocInd->addIE.length] = + SIR_MAC_HT_CAPABILITIES_EID; + pMlmAssocInd->addIE.addIEdata[pMlmAssocInd->addIE.length + 1] = + DOT11F_IE_HTCAPS_MIN_LEN; + vos_mem_copy( + &pMlmAssocInd->addIE.addIEdata[pMlmAssocInd->addIE.length + 2], + ((tANI_U8*)&pAssocReq->HTCaps)+1, + DOT11F_IE_HTCAPS_MIN_LEN); + pMlmAssocInd->addIE.length += 2 + DOT11F_IE_HTCAPS_MIN_LEN; + } + else + limLog(pMac, LOGP, FL("Cannot add HT capabilities IE to addIE")); + } + + if (pAssocReq->wmeInfoPresent) + { + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"), + WNI_CFG_WME_ENABLED ); + + /* check whether AP is enabled with WMM */ + if(tmp) + { + pMlmAssocInd->WmmStaInfoPresent = 1; + } + else + { + pMlmAssocInd->WmmStaInfoPresent= 0; + } + /* Note: we are not rejecting association here because IOT will fail */ + + } + + // Required for indicating the frames to upper layer + pMlmAssocInd->assocReqLength = pAssocReq->assocReqFrameLength; + pMlmAssocInd->assocReqPtr = pAssocReq->assocReqFrame; + + pMlmAssocInd->beaconPtr = psessionEntry->beacon; + pMlmAssocInd->beaconLength = psessionEntry->bcnLen; + + pMlmAssocInd->chan_info.chan_id = psessionEntry->currentOperChannel; + + pMlmAssocInd->chan_info.mhz = vos_chan_to_freq( + psessionEntry->currentOperChannel); + + pMlmAssocInd->chan_info.band_center_freq1 = vos_chan_to_freq( + psessionEntry->currentOperChannel); + + pMlmAssocInd->chan_info.band_center_freq2 = 0; + + pMlmAssocInd->chan_info.reg_info_1 = (psessionEntry->maxTxPower << 16); + pMlmAssocInd->chan_info.reg_info_2 = (psessionEntry->maxTxPower << 8); + + if (psessionEntry->limRFBand == SIR_BAND_2_4_GHZ) { + if (psessionEntry->vhtCapability && pAssocReq->VHTCaps.present) { + pMlmAssocInd->chan_info.info = MODE_11AC_VHT20_2G; + } else if (psessionEntry->htCapability && + pAssocReq->HTCaps.present) { + pMlmAssocInd->chan_info.info = MODE_11NG_HT20; + } else { + pMlmAssocInd->chan_info.info = MODE_11G; + } + } else { + if (psessionEntry->vhtCapability && pAssocReq->VHTCaps.present) { + if ((psessionEntry->vhtTxChannelWidthSet == + eHT_CHANNEL_WIDTH_80MHZ) && + pAssocReq->HTCaps.supportedChannelWidthSet) { + pMlmAssocInd->chan_info.band_center_freq1 = + vos_chan_to_freq(psessionEntry->apCenterChan); + pMlmAssocInd->chan_info.info = MODE_11AC_VHT80; + } else if ((psessionEntry->vhtTxChannelWidthSet == + eHT_CHANNEL_WIDTH_40MHZ) && + pAssocReq->HTCaps.supportedChannelWidthSet) { + pMlmAssocInd->chan_info.info = MODE_11AC_VHT40; + if (psessionEntry->htSecondaryChannelOffset == + PHY_DOUBLE_CHANNEL_LOW_PRIMARY) { + pMlmAssocInd->chan_info.band_center_freq1 += 10; + } else { + pMlmAssocInd->chan_info.band_center_freq1 -= 10; + } + } else + pMlmAssocInd->chan_info.info = MODE_11AC_VHT20; + } else if (psessionEntry->htCapability && + pAssocReq->HTCaps.present) { + if ((psessionEntry->vhtTxChannelWidthSet == + eHT_CHANNEL_WIDTH_40MHZ) && + pAssocReq->HTCaps.supportedChannelWidthSet) { + pMlmAssocInd->chan_info.info = MODE_11NA_HT40; + if (psessionEntry->htSecondaryChannelOffset == + PHY_DOUBLE_CHANNEL_LOW_PRIMARY) { + pMlmAssocInd->chan_info.band_center_freq1 += 10; + } else { + pMlmAssocInd->chan_info.band_center_freq1 -= 10; + } + } else + pMlmAssocInd->chan_info.info = MODE_11NA_HT20; + } else + pMlmAssocInd->chan_info.info = MODE_11A; + } + limPostSmeMessage(pMac, LIM_MLM_ASSOC_IND, (tANI_U32 *) pMlmAssocInd); + vos_mem_free(pMlmAssocInd); + } + else + { + // If its of Reassociation Request, then post LIM_MLM_REASSOC_IND + temp = sizeof(tLimMlmReassocInd); + + pMlmReassocInd = vos_mem_malloc(temp); + if (NULL == pMlmReassocInd) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for " + "pMlmReassocInd")); + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + return; + } + vos_mem_set(pMlmReassocInd, temp, 0); + + vos_mem_copy((tANI_U8 *) pMlmReassocInd->peerMacAddr, + (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *) pMlmReassocInd->currentApAddr, + (tANI_U8 *)&(pAssocReq->currentApAddr), sizeof(tSirMacAddr)); + pMlmReassocInd->aid = pStaDs->assocId; + pMlmReassocInd->authType = pStaDs->mlmStaContext.authType; + vos_mem_copy((tANI_U8 *)&pMlmReassocInd->ssId, + (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1); + + pMlmReassocInd->capabilityInfo = pAssocReq->capabilityInfo; + pMlmReassocInd->rsnIE.length = 0; + + if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + + if (pAssocReq->rsnPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Assoc Req: RSN IE length = %d"), + pAssocReq->rsn.length); + pMlmReassocInd->rsnIE.length = 2 + pAssocReq->rsn.length; + pMlmReassocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID; + pMlmReassocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length; + vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[2], + pAssocReq->rsn.info, pAssocReq->rsn.length); + } + + // 802.11h support + if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent) + { + pMlmReassocInd->spectrumMgtIndicator = eSIR_TRUE; + pMlmReassocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower; + pMlmReassocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower; + pMlmReassocInd->supportedChannels.numChnl = (tANI_U8)(pAssocReq->supportedChannels.length / 2); + + limLog(pMac, LOG1, + FL("Sending Reassoc Ind: spectrum ON, minPwr %d, " + "maxPwr %d, numChnl %d"), + pMlmReassocInd->powerCap.minTxPower, + pMlmReassocInd->powerCap.maxTxPower, + pMlmReassocInd->supportedChannels.numChnl); + + for(i=0; i < pMlmReassocInd->supportedChannels.numChnl; i++) + { + pMlmReassocInd->supportedChannels.channelList[i] = pAssocReq->supportedChannels.supportedChannels[j]; + limLog(pMac, LOG1, FL("Sending ReassocInd: chn[%d] = %d "), + i, pMlmReassocInd->supportedChannels.channelList[i]); + j+=2; + } + } + else + pMlmReassocInd->spectrumMgtIndicator = eSIR_FALSE; + + + /* This check is to avoid extra Sec IEs present incase of WPS */ + if (pAssocReq->wpaPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Received WPA IE length in Assoc Req is %d"), + pAssocReq->wpa.length); + pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length] = SIR_MAC_WPA_EID; + pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 1] = pAssocReq->wpa.length; + vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 2], + pAssocReq->wpa.info, + pAssocReq->wpa.length); + pMlmReassocInd->rsnIE.length += 2 + pAssocReq->wpa.length; + } + + pMlmReassocInd->addIE.length = 0; + if (pAssocReq->addIEPresent) + { + vos_mem_copy(&pMlmReassocInd->addIE.addIEdata, + pAssocReq->addIE.addIEdata, + pAssocReq->addIE.length); + + pMlmReassocInd->addIE.length = pAssocReq->addIE.length; + } + + if(pAssocReq->wmeInfoPresent) + { + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"), + WNI_CFG_WME_ENABLED ); + + /* check whether AP is enabled with WMM */ + if(tmp) + { + pMlmReassocInd->WmmStaInfoPresent = 1; + } + else + { + pMlmReassocInd->WmmStaInfoPresent = 0; + } + /* Note: we are not rejecting Re-association here because IOT will fail */ + + } + + // Required for indicating the frames to upper layer + pMlmReassocInd->assocReqLength = pAssocReq->assocReqFrameLength; + pMlmReassocInd->assocReqPtr = pAssocReq->assocReqFrame; + + pMlmReassocInd->beaconPtr = psessionEntry->beacon; + pMlmReassocInd->beaconLength = psessionEntry->bcnLen; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_IND, (tANI_U32 *) pMlmReassocInd); + vos_mem_free(pMlmReassocInd); + } + + return; + +} /*** end limSendMlmAssocInd() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c new file mode 100644 index 0000000000000..a4a40cb788251 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c @@ -0,0 +1,1054 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessAssocRspFrame.cc contains the code + * for processing Re/Association Response Frame. + * Author: Chandra Modumudi + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniApi.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "pmmApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limSendMessages.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry); + + +/** + * @function : limUpdateAssocStaDatas + * + * @brief : This function is called to Update the Station Descriptor (dph) Details from + * Association / ReAssociation Response Frame + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Station Descriptor in DPH + * @param pAssocRsp - Pointer to Association Response Structure + * + * @return None + */ +void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry) +{ + tANI_U32 prop; + tANI_U32 phyMode; + tANI_U32 val; + tANI_BOOLEAN qosMode; + tANI_U16 rxHighestRate = 0; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + pStaDs->staType= STA_ENTRY_SELF; + + limGetQosMode(psessionEntry, &qosMode); + // set the ani peer bit, if self mode is one of the proprietary modes + if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode)) + { + wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, &prop); + + if (prop) + { + pStaDs->aniPeer = eHAL_SET; + pStaDs->propCapability = pAssocRsp->propIEinfo.capability; + } + } + + pStaDs->mlmStaContext.authType = psessionEntry->limCurrentAuthType; + + // Add capabilities information, rates and AID + pStaDs->mlmStaContext.capabilityInfo = pAssocRsp->capabilityInfo; + pStaDs->shortPreambleEnabled= (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble; + + //Update HT Capabilites only when the self mode supports HT + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) { + pStaDs->mlmStaContext.htCapability = pAssocRsp->HTCaps.present; + + if ( pAssocRsp->HTCaps.present ) { + pStaDs->htGreenfield = ( tANI_U8 ) pAssocRsp->HTCaps.greenField; + pStaDs->htSupportedChannelWidthSet = ( tANI_U8 ) (pAssocRsp->HTCaps.supportedChannelWidthSet ? + pAssocRsp->HTInfo.recommendedTxWidthSet : + pAssocRsp->HTCaps.supportedChannelWidthSet ); + pStaDs->htLsigTXOPProtection = ( tANI_U8 ) pAssocRsp->HTCaps.lsigTXOPProtection; + pStaDs->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave; + pStaDs->htMaxAmsduLength = ( tANI_U8 ) pAssocRsp->HTCaps.maximalAMSDUsize; + pStaDs->htAMpduDensity = pAssocRsp->HTCaps.mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz; + pStaDs->htShortGI20Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz; + pStaDs->htShortGI40Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz; + pStaDs->htMaxRxAMpduFactor = pAssocRsp->HTCaps.maxRxAMPDUFactor; + limFillRxHighestSupportedRate(pMac, &rxHighestRate, pAssocRsp->HTCaps.supportedMCSSet); + pStaDs->supportedRates.rxHighestDataRate = rxHighestRate; + /* This is for AP as peer STA and we are INFRA STA. We will put APs offset in dph node which is peer STA */ + pStaDs->htSecondaryChannelOffset = (tANI_U8)pAssocRsp->HTInfo.secondaryChannelOffset; + + //FIXME_AMPDU + // In the future, may need to check for "assoc.HTCaps.delayedBA" + // For now, it is IMMEDIATE BA only on ALL TID's + pStaDs->baPolicyFlag = 0xFF; + } + } + +#ifdef WLAN_FEATURE_11AC + if(IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) + { + pStaDs->mlmStaContext.vhtCapability = pAssocRsp->VHTCaps.present; + } + + // If 11ac is supported and if the peer is sending VHT capabilities, + // then htMaxRxAMpduFactor should be overloaded with VHT maxAMPDULenExp + if (pAssocRsp->VHTCaps.present) + { + pStaDs->htMaxRxAMpduFactor = pAssocRsp->VHTCaps.maxAMPDULenExp; + } + + if (limPopulatePeerRateSet(pMac, &pStaDs->supportedRates, + pAssocRsp->HTCaps.supportedMCSSet, + false,psessionEntry , &pAssocRsp->VHTCaps) != eSIR_SUCCESS) +#else + if (limPopulatePeerRateSet(pMac, &pStaDs->supportedRates, pAssocRsp->HTCaps.supportedMCSSet, false,psessionEntry) != eSIR_SUCCESS) +#endif + { + limLog(pMac, LOGP, FL("could not get rateset and extended rate set")); + return; + } + +#ifdef WLAN_FEATURE_11AC + pStaDs->vhtSupportedRxNss = ((pStaDs->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2) + == MCSMAPMASK2x2) ? 1 : 2; +#endif + //If one of the rates is 11g rates, set the ERP mode. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && sirIsArate(pStaDs->supportedRates.llaRates[0] & 0x7f)) + pStaDs->erpEnabled = eHAL_SET; + + + val = WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pStaDs->mlmStaContext.propRateSet.propRate, + &val) != eSIR_SUCCESS) { + /// Could not get prop rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve prop rateset")); + return; + } + pStaDs->mlmStaContext.propRateSet.numPropRates = (tANI_U8) val; + + pStaDs->qosMode = 0; + pStaDs->lleEnabled = 0; + + // update TSID to UP mapping + if (qosMode) { + if (pAssocRsp->edcaPresent) { + tSirRetStatus status; + status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry); + PELOG2(limLog(pMac, LOG2, "Edca set update based on AssocRsp: status %d", + status);) + if (status != eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, FL("Edca error in AssocResp "));) + } else { // update default tidmap based on ACM + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 1; + } + } + } + + pStaDs->wmeEnabled = 0; + pStaDs->wsmEnabled = 0; + if (psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) + { + tSirRetStatus status; + status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry); + PELOGW(limLog(pMac, LOGW, "WME Edca set update based on AssocRsp: status %d", status);) + + if (status != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("WME Edca error in AssocResp - ignoring"));) + else { // update default tidmap based on HashACM + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 1; + } + } + else { + /* We received assoc rsp from a legacy AP. So fill in the default + * local EDCA params. This is needed (refer to bug #14989) as we'll + * be passing the gLimEdcaParams to HAL in limProcessStaMlmAddBssRsp(). + */ + schSetDefaultEdcaParams(pMac, psessionEntry); + } + + if(qosMode && (!pStaDs->qosMode) && pStaDs->mlmStaContext.htCapability) + { + // Enable QOS for all HT AP's even though WMM or 802.11E IE is not present + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 1; + } + +#ifdef WLAN_FEATURE_11W + if(psessionEntry->limRmfEnabled) + { + pStaDs->rmfEnabled = 1; + } +#endif +} + +/** + * @function : limUpdateReAssocGlobals + * + * @brief : This function is called to Update the Globals (LIM) during ReAssoc. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAssocRsp - Pointer to Association Response Structure + * + * @return None + */ + +void limUpdateReAssocGlobals(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry) +{ + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + + // Update the current Bss Information + vos_mem_copy(psessionEntry->bssId, + psessionEntry->limReAssocbssId, sizeof(tSirMacAddr)); + psessionEntry->currentOperChannel = psessionEntry->limReassocChannelId; + psessionEntry->htSecondaryChannelOffset = psessionEntry->reAssocHtSupportedChannelWidthSet; + psessionEntry->htRecommendedTxWidthSet = psessionEntry->reAssocHtRecommendedTxWidthSet; + psessionEntry->htSecondaryChannelOffset = psessionEntry->reAssocHtSecondaryChannelOffset; + psessionEntry->limCurrentBssCaps = psessionEntry->limReassocBssCaps; + psessionEntry->limCurrentBssQosCaps = psessionEntry->limReassocBssQosCaps; + psessionEntry->limCurrentBssPropCap = psessionEntry->limReassocBssPropCap; + + vos_mem_copy((tANI_U8 *) &psessionEntry->ssId, + (tANI_U8 *) &psessionEntry->limReassocSSID, + psessionEntry->limReassocSSID.length+1); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + /** Set the State Back to ReAssoc Rsp*/ + psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + +} + +/** + * @function : limProcessAssocRspFrame + * + * @brief : This function is called by limProcessMessageQueue() upon + * Re/Association Response frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @param subType - Indicates whether it is Association Response (=0) or + * Reassociation Response (=1) frame + * + * @return None + */ + +void +limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 subType,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 caps; + tANI_U32 frameLen; + tSirMacAddr currentBssId; + tpSirMacMgmtHdr pHdr = NULL; + tSirMacCapabilityInfo localCapabilities; + tpDphHashNode pStaDs; + tpSirAssocRsp pAssocRsp; + tLimMlmAssocCnf mlmAssocCnf; + tSchBeaconStruct *pBeaconStruct; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 smeSessionId = 0; +#endif + + //Initialize status code to success. +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) + pHdr = (tpSirMacMgmtHdr)pMac->roam.pReassocResp; + else +#endif + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + smeSessionId = psessionEntry->smeSessionId; +#endif + + mlmAssocCnf.resultCode = eSIR_SME_SUCCESS; + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + if (pHdr == NULL) { + limLog(pMac, LOGE, + FL("LFR3: Reassoc response packet header is NULL")); + return; + } else if ( pHdr->sa == NULL) { + limLog(pMac, LOGE, + FL("LFR3: Reassoc response packet source address is NULL")); + return; + } + + limLog(pMac, LOG1, + FL("received Re/Assoc(%d) resp on sessionid: %d with systemrole: %d " + "and mlmstate: %d RSSI %d from "MAC_ADDRESS_STR),subType, + psessionEntry->peSessionId, + psessionEntry->limSystemRole,psessionEntry->limMlmState, + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo)), + MAC_ADDR_ARRAY(pHdr->sa)); + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory") ); + return; + } + + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE ) + { + // Should not have received Re/Association Response + // frame on AP. Log error + limLog(pMac, LOGE, + FL("Should not recieved Re/Assoc Response in role %d "), + psessionEntry->limSystemRole); + + vos_mem_free(pBeaconStruct); + return; + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) + { + pHdr = (tpSirMacMgmtHdr)pMac->roam.pReassocResp; + frameLen = pMac->roam.reassocRespLen - SIR_MAC_HDR_LEN_3A; + } + else + { +#endif + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + } +#endif + if (((subType == LIM_ASSOC) && + (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) || + ((subType == LIM_REASSOC) && + ((psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + && (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE) +#endif + ))) + { + /// Received unexpected Re/Association Response frame + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("Recieved Re/Assoc rsp in unexpected " + "state %d on session=%d"), + psessionEntry->limMlmState, psessionEntry->peSessionId);) +#endif + // Log error + if (!pHdr->fc.retry) + { + limLog(pMac, LOGE, + FL("received Re/Assoc rsp frame is not a retry frame")); + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + } + vos_mem_free(pBeaconStruct); + return; + } + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if (subType == LIM_ASSOC) + { + if (!vos_mem_compare(pHdr->sa, currentBssId, sizeof(tSirMacAddr))) + { + /** + * Received Association Response frame from an entity + * other than one to which request was initiated. + * Ignore this and wait until Association Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received AssocRsp frame from unexpected peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + vos_mem_free(pBeaconStruct); + return; + } + } + else + { + if (!vos_mem_compare(pHdr->sa, psessionEntry->limReAssocbssId, sizeof(tSirMacAddr))) + { + /** + * Received Reassociation Response frame from an entity + * other than one to which request was initiated. + * Ignore this and wait until Reassociation Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received ReassocRsp frame from unexpected peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + vos_mem_free(pBeaconStruct); + + return; + } + } + + pAssocRsp = vos_mem_malloc(sizeof(*pAssocRsp)); + if (NULL == pAssocRsp) + { + limLog(pMac, LOGP, FL("Allocate Memory failed in AssocRsp")); + vos_mem_free(pBeaconStruct); + + return; + } + + // Get pointer to Re/Association Response frame body +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) + pBody = pMac->roam.pReassocResp + SIR_MAC_HDR_LEN_3A; + else +#endif + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + // parse Re/Association Response frame. + if (sirConvertAssocRespFrame2Struct( + pMac, pBody, frameLen, pAssocRsp) == eSIR_FAILURE) + { + vos_mem_free(pAssocRsp); + PELOGE(limLog(pMac, LOGE, FL("Parse error Assoc resp subtype %d," + "length=%d"), frameLen,subType);) + vos_mem_free(pBeaconStruct); + + return; + } + + if(!pAssocRsp->suppRatesPresent) + { + PELOGE(limLog(pMac, LOGE, FL("assoc response does not have supported rate set"));) + vos_mem_copy(&pAssocRsp->supportedRates, + &psessionEntry->rateSet, sizeof(tSirMacRateSet)); + } + + mlmAssocCnf.protStatusCode = pAssocRsp->statusCode; + + if( psessionEntry->assocRsp != NULL ) + { + limLog(pMac, LOGW, FL("psessionEntry->assocRsp is not NULL freeing it " + "and setting NULL")); + vos_mem_free(psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } + + psessionEntry->assocRsp = vos_mem_malloc(frameLen); + if (NULL == psessionEntry->assocRsp) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response, len = %d"), frameLen);) + } + else + { + //Store the Assoc response. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->assocRsp, pBody, frameLen); + psessionEntry->assocRspLen = frameLen; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->ricData != NULL) + { + vos_mem_free(psessionEntry->ricData); + psessionEntry->ricData = NULL; + } + if(pAssocRsp->ricPresent) + { + psessionEntry->RICDataLen = pAssocRsp->num_RICData * sizeof(tDot11fIERICDataDesc); + psessionEntry->ricData = vos_mem_malloc(psessionEntry->RICDataLen); + if ( NULL == psessionEntry->ricData ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));) + psessionEntry->RICDataLen = 0; + } + else + { + vos_mem_copy(psessionEntry->ricData, + &pAssocRsp->RICData[0], psessionEntry->RICDataLen); + } + } + else + { + limLog(pMac, LOG1, FL("Ric is not present Setting RICDataLen 0 and ricData " + "as NULL")); + psessionEntry->RICDataLen = 0; + psessionEntry->ricData = NULL; + } +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pAssocRsp->FTInfo.R0KH_ID.present) + { + pMac->roam.roamSession[smeSessionId].ftSmeContext.r0kh_id_len = + pAssocRsp->FTInfo.R0KH_ID.num_PMK_R0_ID; + vos_mem_copy(pMac->roam.roamSession[smeSessionId].ftSmeContext.r0kh_id, + pAssocRsp->FTInfo.R0KH_ID.PMK_R0_ID, + pMac->roam.roamSession[smeSessionId].ftSmeContext.r0kh_id_len); + } + else + { + pMac->roam.roamSession[smeSessionId].ftSmeContext.r0kh_id_len = 0; + vos_mem_zero(pMac->roam.roamSession[smeSessionId].ftSmeContext.r0kh_id, + SIR_ROAM_R0KH_ID_MAX_LEN); + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->tspecIes != NULL) + { + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + } + if(pAssocRsp->tspecPresent) + { + psessionEntry->tspecLen = pAssocRsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC); + psessionEntry->tspecIes = vos_mem_malloc(psessionEntry->tspecLen); + if ( NULL == psessionEntry->tspecIes ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));) + psessionEntry->tspecLen = 0; + } + else + { + vos_mem_copy(psessionEntry->tspecIes, + &pAssocRsp->TSPECInfo[0], psessionEntry->tspecLen); + } + PELOG1(limLog(pMac, LOG1, FL(" Tspec EID present in assoc rsp "));) + } + else + { + psessionEntry->tspecLen = 0; + psessionEntry->tspecIes = NULL; + PELOG1(limLog(pMac, LOG1, FL(" Tspec EID *NOT* present in assoc rsp "));) + } +#endif + + if (pAssocRsp->capabilityInfo.ibss) + { + /** + * Received Re/Association Response from peer + * with IBSS capability set. + * Ignore the frame and wait until Re/assoc + * failure timeout. + */ + + // Log error + limLog(pMac, LOGE, + FL("received Re/AssocRsp frame with IBSS capability")); + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + return; + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + limLog(pMac, LOGP, FL("could not retrieve Capabilities value")); + return; + } + limCopyU16((tANI_U8 *) &localCapabilities, caps); + + if (subType == LIM_ASSOC) // Stop Association failure timer + limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER); + else // Stop Reassociation failure timer + { +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.reAssocRetryAttempt = 0; + if ((NULL != pMac->lim.pSessionEntry) && (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)) + { + vos_mem_free(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq); + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL; + } +#endif + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + } + + if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS +#ifdef WLAN_FEATURE_11W + && pAssocRsp->statusCode != eSIR_MAC_TRY_AGAIN_LATER +#endif /* WLAN_FEATURE_11W */ + ) + { + // Re/Association response was received + // either with failure code. + // Log error. + PELOGE(limLog(pMac, LOGE, FL("received Re/AssocRsp frame failure code %d"), pAssocRsp->statusCode);) + // Need to update 'association failure' error counter + // along with STATUS CODE + + // Return Assoc confirm to SME with received failure code + + if (pAssocRsp->propIEinfo.loadBalanceInfoPresent) + { + mlmAssocCnf.resultCode = eSIR_SME_TRANSFER_STA; + vos_mem_copy(pMac->lim.gLimAlternateRadio.bssId, + pAssocRsp->propIEinfo.alternateRadio.bssId, sizeof(tSirMacAddr)); + pMac->lim.gLimAlternateRadio.channelId = + pAssocRsp->propIEinfo.alternateRadio.channelId; + }else + mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED; + + // Delete Pre-auth context for the associated BSS + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + goto assocReject; + } + else if ((pAssocRsp->aid & 0x3FFF) > 2007) + { + // Re/Association response was received + // with invalid AID value + // Log error + PELOGW(limLog(pMac, LOGE, FL("received Re/AssocRsp frame with" + "invalid aid %X"), pAssocRsp->aid);) + mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + // Send advisory Disassociation frame to AP + limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE); + + goto assocReject; + } + // Association Response received with success code + /* + * Set the link state to POSTASSOC now that we have received + * assoc/reassoc response + * NOTE: for BTAMP case, it is being handled in limProcessMlmAssocReq + */ + +#ifdef WLAN_FEATURE_11W + if (pAssocRsp->statusCode == eSIR_MAC_TRY_AGAIN_LATER) { + /* fetch timer value from IE */ + if (pAssocRsp->TimeoutInterval.present && + (pAssocRsp->TimeoutInterval.timeoutType == + SIR_MAC_TI_TYPE_ASSOC_COMEBACK) ) { + tANI_U16 timeout_value = pAssocRsp->TimeoutInterval.timeoutValue; + PELOGE(limLog(pMac, LOG1, + FL("ASSOC response with eSIR_MAC_TRY_AGAIN_LATER recvd. " + "Starting timer to wait timeout=%d."), + timeout_value);) + + /* start timer with callback */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&psessionEntry->pmfComebackTimer, + timeout_value)) { + PELOGE(limLog(pMac, LOGE, + FL("Failed to start comeback timer."));) + } + } else { + PELOGE(limLog(pMac, LOG1, + FL("ASSOC response with eSIR_MAC_TRY_AGAIN_LATER recvd." + "But try again time interval IE is wrong."));) + } + /* callback will send Assoc again */ + /* DO NOT send ASSOC CNF to MLM state machine */ + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; + } +#endif /* WLAN_FEATURE_11W */ + + if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) || + ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))) + { + if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Set link state to POSTASSOC failed"));) + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; + } + } + + if (subType == LIM_REASSOC) + { + // Log success + PELOG1(limLog(pMac, LOG1, FL("Successfully Reassociated with BSS"));) +#ifdef FEATURE_WLAN_ESE + { + tANI_U8 cnt = 0; + if (pAssocRsp->tsmPresent) + { + limLog(pMac, LOGW, "TSM IE Present in Reassoc Rsp"); + // Start the TSM timer only if the TSPEC Ie is present in the reassoc rsp + if (pAssocRsp->tspecPresent) { + // Find the TSPEC IE with VO user priority + for (cnt=0; cntnum_tspecs; cnt++) { + if ( upToAc(pAssocRsp->TSPECInfo[cnt].user_priority) == EDCA_AC_VO) { + psessionEntry->eseContext.tsm.tid = pAssocRsp->TSPECInfo[cnt].user_priority; + vos_mem_copy(&psessionEntry->eseContext.tsm.tsmInfo, + &pAssocRsp->tsmIE, sizeof(tSirMacESETSMIE)); +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, + psessionEntry, + pAssocRsp->tsmIE.tsid, + pAssocRsp->tsmIE.state, + pAssocRsp->tsmIE.msmt_interval); +#else + limActivateTSMStatsTimer(pMac, psessionEntry); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + if(psessionEntry->eseContext.tsm.tsmInfo.state) { + psessionEntry->eseContext.tsm.tsmMetrics.RoamingCount++; + } + break; + } + } + } else { + limLog(pMac, LOGE, "TSM present but TSPEC IE not present in Reassoc Rsp"); + } + } + } +#endif + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + psessionEntry->limAssocResponseData = (void *) pAssocRsp; /** Store the ReAssocRsp Frame in DphTable to be used + during processing DelSta nd DelBss to send AddBss again*/ + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + if(!pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("could not get hash entry at DPH for"));) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + // Send advisory Disassociation frame to AP + limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE); + + goto assocReject; + } + +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Sending self sta"));) +#endif + pmmResetPmmState(pMac); + + limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + + // Downgrade the EDCA parameters if needed + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + // Send the active EDCA parameters to HAL +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (!psessionEntry->bRoamSynchInProgress) + { +#endif + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, + pStaDs->bssId, eANI_BOOLEAN_TRUE); + } + else + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, + pStaDs->bssId, eANI_BOOLEAN_FALSE); + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + } +#endif + limAddFTStaSelf(pMac, (pAssocRsp->aid & 0x3FFF), psessionEntry); + vos_mem_free(pBeaconStruct); + + return; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + /* If we're re-associating to the same BSS, we don't want to invoke delete + * STA, delete BSS, as that would remove the already established TSPEC. + * Just go ahead and re-add the BSS, STA with new capability information. + * However, if we're re-associating to a different BSS, then follow thru + * with del STA, del BSS, add BSS, add STA. + */ + if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId)) + limHandleAddBssInReAssocContext(pMac, pStaDs, psessionEntry); + else + { + if(!pMac->psOffloadEnabled) + { + /* + * reset the uapsd mask settings + * since we're re-associating to new AP + */ + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + } + else + { + /* + * reset the uapsd mask settings since + * we're re-associating to new AP + */ + psessionEntry->gUapsdPerAcDeliveryEnableMask = 0; + psessionEntry->gUapsdPerAcTriggerEnableMask = 0; + } + + if (limCleanupRxPath(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not cleanup the rx path"));) + goto assocReject; + } + } + vos_mem_free(pBeaconStruct); + + return; + } + + // Log success + PELOG1(limLog(pMac, LOG1, FL("Successfully Associated with BSS "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->eseContext.tsm.tsmInfo.state) + { + psessionEntry->eseContext.tsm.tsmMetrics.RoamingCount = 0; + } +#endif + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + + + //STA entry was created during pre-assoc state. + if ((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not get hash entry at DPH for "));) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmAssocCnf.protStatusCode = eSIR_SME_SUCCESS; + + + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, + (tANI_U32 *) &mlmAssocCnf); + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + return; + } + + // Delete Pre-auth context for the associated BSS + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry); + // Extract the AP capabilities from the beacon that was received earlier + // TODO - Watch out for an error response! + limExtractApCapabilities( pMac, + (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields, + limGetIElenFromBssDescription( &psessionEntry->pLimJoinReq->bssDescription ), + pBeaconStruct ); + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + + if(pBeaconStruct->erpPresent) { + if (pBeaconStruct->erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = false; + else + psessionEntry->beaconParams.fShortPreamble = true; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CONNECTED, psessionEntry, 0, 0); +#endif + if( pAssocRsp->QosMapSet.present ) + { + vos_mem_copy(&psessionEntry->QosMapSet, + &pAssocRsp->QosMapSet, + sizeof(tSirQosMapSet)); + } + else + { + vos_mem_zero(&psessionEntry->QosMapSet, sizeof(tSirQosMapSet)); + } + + if (pAssocRsp->ExtCap.present) + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + pAssocRsp->ExtCap.bytes; + pStaDs->timingMeasCap = 0; + pStaDs->timingMeasCap |= (p_ext_cap->timingMeas)? + RTT_TIMING_MEAS_CAPABILITY: + RTT_INVALID; + pStaDs->timingMeasCap |= (p_ext_cap->fineTimingMeas)? + RTT_FINE_TIMING_MEAS_CAPABILITY: + RTT_INVALID; + PELOG1(limLog(pMac, LOG1, + FL("ExtCap present, timingMeas: %d fineTimingMeas: %d"), + p_ext_cap->timingMeas, + p_ext_cap->fineTimingMeas);) +#ifdef FEATURE_WLAN_TDLS + psessionEntry->tdls_prohibited = + p_ext_cap->TDLSProhibited; + psessionEntry->tdls_chan_swit_prohibited = + p_ext_cap->TDLSChanSwitProhibited; + + PELOG1(limLog(pMac, LOG1, + FL("ExtCap: tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"), + p_ext_cap->TDLSProhibited, + p_ext_cap->TDLSChanSwitProhibited);) +#endif + } + else + { + pStaDs->timingMeasCap = 0; +#ifdef FEATURE_WLAN_TDLS + psessionEntry->tdls_prohibited = false; + psessionEntry->tdls_chan_swit_prohibited = false; +#endif + PELOG1(limLog(pMac, LOG1, FL("ExtCap not present"));) + } + + //Update the BSS Entry, this entry was added during preassoc. + if( eSIR_SUCCESS == limStaSendAddBss( pMac, pAssocRsp, pBeaconStruct, + &psessionEntry->pLimJoinReq->bssDescription, true, psessionEntry)) + { + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + return; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not update the bss entry"));) + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + } + + + +assocReject: + if ((subType == LIM_ASSOC) +#ifdef WLAN_FEATURE_VOWIFI_11R + || ((subType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)) +#endif + ) { + PELOGE(limLog(pMac, LOGE, FL("Assoc Rejected by the peer. " + "mlmestate: %d sessionid %d Reason: %d MACADDR:" + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->peSessionId, mlmAssocCnf.resultCode, + MAC_ADDR_ARRAY(pHdr->sa));) + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + if (subType == LIM_ASSOC) + { + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } +#ifdef WLAN_FEATURE_VOWIFI_11R + else + { + mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + } else { + limRestorePreReassocState( pMac, + eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry); + } + + /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */ + /* notify TL that association is failed so that TL can flush the cached frame */ + PELOG1(limLog(pMac, LOG1, FL("notify TL that association is failed"));) + WLANTL_AssocFailed (psessionEntry->staId); + + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; +} /*** end limProcessAssocRspFrame() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c new file mode 100644 index 0000000000000..afcc913199c30 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c @@ -0,0 +1,1872 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessAuthFrame.cc contains the code + * for processing received Authentication Frame. + * Author: Chandra Modumudi + * Date: 03/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/12/2010 js To support Shared key authentication at AP side + * + */ + +#include "wniApi.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFT.h" +#endif +#include "vos_utils.h" + + +/** + * isAuthValid + * + *FUNCTION: + * This function is called by limProcessAuthFrame() upon Authentication + * frame reception. + * + *LOGIC: + * This function is used to test validity of auth frame: + * - AUTH1 and AUTH3 must be received in AP mode + * - AUTH2 and AUTH4 must be received in STA mode + * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to + * SIR_MAC_CHALLENGE_TEXT_EID by parser + * - + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param *auth - Pointer to extracted auth frame body + * + * @return 0 or 1 (Valid) + */ + + +static inline unsigned int isAuthValid(tpAniSirGlobal pMac, tpSirMacAuthFrameBody auth,tpPESession sessionEntry) { + unsigned int valid; + valid=1; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_1)|| + (auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)) && + ((sessionEntry->limSystemRole == eLIM_STA_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))) + valid=0; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_2)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&& + ((sessionEntry->limSystemRole == eLIM_AP_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))) + valid=0; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&& + (auth->type!=SIR_MAC_CHALLENGE_TEXT_EID)&&(auth->authAlgoNumber != eSIR_SHARED_KEY)) + valid=0; + + return valid; +} + + +/** + * limProcessAuthFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon Authentication + * frame reception. + * + *LOGIC: + * This function processes received Authentication frame and responds + * with either next Authentication frame in sequence to peer MAC entity + * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA. + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Authentication failures are reported to SME with same status code + * received from the peer MAC entity. + * 2. Authentication frame2/4 received with alogirthm number other than + * one requested in frame1/3 are logged with an error and auth confirm + * will be sent to SME only after auth failure timeout. + * 3. Inconsistency in the spec: + * On receiving Auth frame2, specs says that if WEP key mapping key + * or default key is NULL, Auth frame3 with a status code 15 (challenge + * failure to be returned to peer entity. However, section 7.2.3.10, + * table 14 says that status code field is 'reserved' for frame3 ! + * In the current implementation, Auth frame3 is returned with status + * code 15 overriding section 7.2.3.10. + * 4. If number pre-authentications reach configrable max limit, + * Authentication frame with 'unspecified failure' status code is + * returned to requesting entity. + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @return None + */ + +void +limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody, keyId, cfgPrivacyOptImp, + defaultKey[SIR_MAC_KEY_LENGTH], + encrAuthFrame[LIM_ENCR_AUTH_BODY_LEN], + plainBody[256]; + tANI_U16 frameLen; + tANI_U32 maxNumPreAuth, val; + tSirMacAuthFrameBody *pRxAuthFrameBody, rxAuthFrame, authFrame; + tpSirMacMgmtHdr pHdr; + tCfgWepKeyEntry *pKeyMapEntry = NULL; + struct tLimPreAuthNode *pAuthNode; + tLimMlmAuthInd mlmAuthInd; + tANI_U8 decryptResult; + tANI_U8 *pChallenge; + tANI_U32 key_length=8; + tANI_U8 challengeTextArray[SIR_MAC_AUTH_CHALLENGE_LENGTH]; + tpDphHashNode pStaDs = NULL; + tANI_U16 assocId = 0; + + // Get pointer to Authentication frame header and body + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + + if (!frameLen) + { + // Log error + limLog(pMac, LOGE, + FL("received Authentication frame with no body from ")); + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + return; + } + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Auth frame from a BC/MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from a BC/MC address - "));) + PELOGE( limPrintMacAddr(pMac, pHdr->sa, LOGE);) + + return; + } + + limLog(pMac, LOG1, + FL("Sessionid: %d System role : %d limMlmState: %d :Auth " + "Frame Received: BSSID: "MAC_ADDRESS_STR " (RSSI %d)"), + psessionEntry->peSessionId, psessionEntry->limSystemRole, + psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo))); + + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + //Restore default failure timeout + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout) + { + limLog(pMac, LOG1, FL("Restore default failure timeout")); + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT , + psessionEntry->defaultAuthFailureTimeout, NULL, eANI_BOOLEAN_FALSE); + } + + /// Determine if WEP bit is set in the FC or received MAC header + if (pHdr->fc.wep) + { + /** + * WEP bit is set in FC of MAC header. + */ + + // If TKIP counter measures enabled issue Deauth frame to station + if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + PELOGE( limLog(pMac, LOGE, + FL("Tkip counter measures Enabled, sending Deauth frame to")); ) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + limSendDeauthMgmtFrame( pMac, eSIR_MAC_MIC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE ); + return; + } + + // Extract key ID from IV (most 2 bits of 4th byte of IV) + + keyId = (*(pBody + 3)) >> 6; + + /** + * On STA in infrastructure BSS, Authentication frames received + * with WEP bit set in the FC must be rejected with challenge + * failure status code (wierd thing in the spec - this should have + * been rejected with unspecified failure or unexpected assertion + * of wep bit (this status code does not exist though) or + * Out-of-sequence-Authentication-Frame status code. + */ + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + { + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = eSIR_MAC_CHALLENGE_FAILURE_STATUS; + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame with wep bit set on role=%d " + MAC_ADDRESS_STR), psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pHdr->sa) );) + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + + if (frameLen < LIM_ENCR_AUTH_BODY_LEN) + { + // Log error + limLog(pMac, LOGE, + FL("Not enough size [%d] to decrypt received Auth frame"), + frameLen); + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + return; + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + // Accept Authentication frame only if Privacy is implemented + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve Privacy option")); + } + + cfgPrivacyOptImp = (tANI_U8)val; + if (cfgPrivacyOptImp) + { + /** + * Privacy option is implemented. + * Check if the received frame is Authentication + * frame3 and there is a context for requesting STA. + * If not, reject with unspecified failure status code + */ + pAuthNode = limSearchPreAuthList(pMac, pHdr->sa); + + if (pAuthNode == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that has no preauth context with WEP bit set " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * No 'pre-auth' context exists for this STA that sent + * an Authentication frame with FC bit set. + * Send Auth frame4 with 'out of sequence' status code. + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + else + { + /// Change the auth-response timeout + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + /// 'Pre-auth' status exists for STA + if ((pAuthNode->mlmState != + eLIM_MLM_WT_AUTH_FRAME3_STATE) && + (pAuthNode->mlmState != + eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that is in state %d " + MAC_ADDRESS_STR), + pAuthNode->mlmState, MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Should not have received Authentication frame + * with WEP bit set in FC in other states. + * Reject by sending Authenticaton frame with + * out of sequence Auth frame status code. + */ + + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + } + + /** + * Check if there exists a key mappping key + * for the STA that sent Authentication frame + */ + pKeyMapEntry = limLookUpKeyMappings(pHdr->sa); + + if (pKeyMapEntry) + { + if (!pKeyMapEntry->wepOn) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer that has NULL key map entry " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Key Mapping entry has null key. + * Send Authentication frame + * with challenge failure status code + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } // if (!pKeyMapEntry->wepOn) + else + { + decryptResult = limDecryptAuthFrame(pMac, pKeyMapEntry->key, + pBody, + plainBody, + key_length, + (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH)); + if (decryptResult == LIM_DECRYPT_ICV_FAIL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that failed decryption, Addr " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + limDeletePreAuthNode(pMac, + pHdr->sa); + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + + return; + } + + if ((sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, + &rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, &rxAuthFrame,psessionEntry))) + { + PELOGE(limLog(pMac, LOGE, FL( + "failed to convert Auth Frame to structure or Auth is not valid "));) + return; + } + } // end if (pKeyMapEntry->key == NULL) + } // if keyMappings has entry + else + { + + val = SIR_MAC_KEY_LENGTH; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + tpSirKeys pKey; + pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0]; + vos_mem_copy(defaultKey, pKey->key, pKey->keyLength); + val = pKey->keyLength; + } + else + if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId), + defaultKey, &val) != eSIR_SUCCESS) + { + /// Could not get Default key from CFG. + //Log error. + limLog(pMac, LOGP, + FL("could not retrieve Default key")); + + /** + * Send Authentication frame + * with challenge failure status code + */ + + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + return; + } + + key_length=val; + + decryptResult = limDecryptAuthFrame(pMac, defaultKey, + pBody, + plainBody, + key_length, + (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH)); + if (decryptResult == LIM_DECRYPT_ICV_FAIL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that failed decryption: " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + /// ICV failure + limDeletePreAuthNode(pMac, + pHdr->sa); + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + if ( ( sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, + &rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, &rxAuthFrame, psessionEntry) ) ) + { + limLog(pMac, LOGE, + FL("failed to convert Auth Frame to structure or Auth is not valid ")); + return; + } + } // End of check for Key Mapping/Default key presence + } + else + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame3 from peer that while privacy option is turned OFF " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Privacy option is not implemented. + * So reject Authentication frame received with + * WEP bit set by sending Authentication frame + * with 'challenge failure' status code. This is + * another strange thing in the spec. Status code + * should have been 'unsupported algorithm' status code. + */ + + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + } // if (fc.wep) + else + { + if ( ( sirConvertAuthFrame2Struct(pMac, pBody, + frameLen, &rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, &rxAuthFrame,psessionEntry) ) ) + { + PELOGE(limLog(pMac, LOGE, + FL("failed to convert Auth Frame to structure or Auth is not valid "));) + return; + } + } + + + pRxAuthFrameBody = &rxAuthFrame; + + PELOGW(limLog(pMac, LOGW, + FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"), + (tANI_U32) pRxAuthFrameBody->authAlgoNumber, + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber, + (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);) + + switch (pRxAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_1: + // AuthFrame 1 + + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, + &assocId, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + tLimMlmDisassocReq *pMlmDisassocReq = NULL; + tLimMlmDeauthReq *pMlmDeauthReq = NULL; + tAniBool isConnected = eSIR_TRUE; + + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for disassoc " + "frame is pending Issue delsta for " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));) + limProcessDisassocAckTimeout(pMac); + isConnected = eSIR_FALSE; + } + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for deauth frame " + "is pending Issue delsta for " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + limProcessDeauthAckTimeout(pMac); + isConnected = eSIR_FALSE; + } + + /* pStaDS != NULL and isConnected = 1 means the STA is already + * connected, But SAP received the Auth from that station. + * For non PMF connection send Deauth frame as STA will retry + * to connect back. + * + * For PMF connection the AP should not tear down or otherwise + * modify the state of the existing association until the + * SA-Query procedure determines that the original SA is + * invalid. + */ + if (isConnected +#ifdef WLAN_FEATURE_11W + && !pStaDs->rmfEnabled +#endif + ) + { + limLog(pMac, LOGE, + FL("STA is already connected but received auth frame" + "Send the Deauth and lim Delete Station Context" + "(staId: %d, assocId: %d) "), + pStaDs->staIndex, assocId); + limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + (tANI_U8 *) pHdr->sa, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + return; + } + } + + /// Check if there exists pre-auth context for this STA + pAuthNode = limSearchPreAuthList(pMac, pHdr->sa); + if (pAuthNode) + { + /// Pre-auth context exists for the STA + if (pHdr->fc.retry == 0) + { + /** + * STA is initiating brand-new Authentication + * sequence after local Auth Response timeout. + * Or STA retrying to transmit First Auth frame due to packet drop OTA + * Delete Pre-auth node and fall through. + */ + if(pAuthNode->fTimerStarted) + { + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + } + PELOGE(limLog(pMac, LOGE, FL("STA is initiating brand-new Authentication ..."));) + limDeletePreAuthNode(pMac, + pHdr->sa); + /** + * SAP Mode:Disassociate the station and + * delete its entry if we have its entry + * already and received "auth" from the + * same station. + */ + + for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8 + { + pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if (NULL == pStaDs) + continue; + + if (pStaDs->valid) + { + if (vos_mem_compare((tANI_U8 *) &pStaDs->staAddr, + (tANI_U8 *) &(pHdr->sa), (tANI_U8) (sizeof(tSirMacAddr))) ) + break; + } + + pStaDs = NULL; + } + + if (NULL != pStaDs +#ifdef WLAN_FEATURE_11W + && !pStaDs->rmfEnabled +#endif + ) + { + PELOGE(limLog(pMac, LOGE, + FL("lim Delete Station Context (staId: %d, assocId: %d) "), + pStaDs->staIndex, assocId);) + limSendDeauthMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_REASON, (tANI_U8 *) pAuthNode->peerMacAddr, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + return; + } + } + else + { + /* + * This can happen when first authentication frame is received + * but ACK lost at STA side, in this case 2nd auth frame is already + * in transmission queue + * */ + PELOGE(limLog(pMac, LOGE, FL("STA is initiating Authentication after ACK lost..."));) + return; + } + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + (tANI_U32 *) &maxNumPreAuth) != eSIR_SUCCESS) + { + /** + * Could not get MaxNumPreAuth + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve MaxNumPreAuth")); + } + if (pMac->lim.gLimNumPreAuthContexts == maxNumPreAuth) + { + PELOGE(limLog(pMac, LOGE, FL("Max number of preauth context reached"));) + /** + * Maximum number of pre-auth contexts + * reached. Send Authentication frame + * with unspecified failure + */ + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + return; + } + /// No Pre-auth context exists for the STA. + if (limIsAuthAlgoSupported( + pMac, + (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber, psessionEntry)) + { + switch (pRxAuthFrameBody->authAlgoNumber) + { + case eSIR_OPEN_SYSTEM: + PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_OPEN_SYSTEM ..."));) + /// Create entry for this STA in pre-auth list + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + return; + } + + PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer "), pAuthNode); + limPrintMacAddr(pMac, pHdr->sa, LOG1);) + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + + pAuthNode->mlmState = + eLIM_MLM_AUTHENTICATED_STATE; + pAuthNode->authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + pAuthNode->fSeen = 0; + pAuthNode->fTimerStarted = 0; + limAddPreAuthNode(pMac, pAuthNode); + + /** + * Send Authenticaton frame with Success + * status code. + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = eSIR_MAC_SUCCESS_STATUS; + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + /// Send Auth indication to SME + + vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr, + (tANI_U8 *) pHdr->sa, + sizeof(tSirMacAddr)); + mlmAuthInd.authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + mlmAuthInd.sessionId = psessionEntry->smeSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_IND, + (tANI_U32 *) &mlmAuthInd); + break; + + case eSIR_SHARED_KEY: + PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_SHARED_KEY ..."));) + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Privacy option")); + } + cfgPrivacyOptImp = (tANI_U8)val; + if (!cfgPrivacyOptImp) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame for unsupported auth algorithm %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Authenticator does not have WEP + * implemented. + * Reject by sending Authentication frame + * with Auth algorithm not supported status + * code. + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + else + { + // Create entry for this STA + //in pre-auth list + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + return; + } + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + + pAuthNode->mlmState = + eLIM_MLM_WT_AUTH_FRAME3_STATE; + pAuthNode->authType = + (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + pAuthNode->fSeen = 0; + pAuthNode->fTimerStarted = 0; + limAddPreAuthNode(pMac, pAuthNode); + + PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x id %d peer "), + pAuthNode, pAuthNode->authNodeIdx);) + PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);) + + /// Create and activate Auth Response timer + if (tx_timer_change_context(&pAuthNode->timer, pAuthNode->authNodeIdx) != TX_SUCCESS) + { + /// Could not start Auth response timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to chg context auth response timer for peer ")); + limPrintMacAddr(pMac, pHdr->sa, LOGP); + + /** + * Send Authenticaton frame with + * unspecified failure status code. + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + limDeletePreAuthNode(pMac, pHdr->sa); + return; + } + + limActivateAuthRspTimer(pMac, pAuthNode); + + pAuthNode->fTimerStarted = 1; + + // get random bytes and use as + // challenge text. If it fails we already have random stack bytes. + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH ) ) ) + { + limLog(pMac, LOGE,FL("Challenge text preparation failed in limProcessAuthFrame")); + } + + pChallenge = pAuthNode->challengeText; + + vos_mem_copy(pChallenge, + (tANI_U8 *) challengeTextArray, + sizeof(challengeTextArray)); + + /** + * Sending Authenticaton frame with challenge. + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_SUCCESS_STATUS; + authFrame.type = SIR_MAC_CHALLENGE_TEXT_EID; + authFrame.length = SIR_MAC_AUTH_CHALLENGE_LENGTH; + vos_mem_copy(authFrame.challengeText, + pAuthNode->challengeText, + SIR_MAC_AUTH_CHALLENGE_LENGTH); + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + } // if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + + break; + + default: + // Log error + PELOGE( limLog(pMac, LOGE, + FL("received Auth frame for unsupported auth algorithm %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Responding party does not support the + * authentication algorithm requested by + * sending party. + * Reject by sending Authentication frame + * with auth algorithm not supported status code + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } // end switch(pRxAuthFrameBody->authAlgoNumber) + } // if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber)) + else + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame for unsupported auth algorithm %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Responding party does not support the + * authentication algorithm requested by sending party. + * Reject Authentication with StatusCode=13. + */ + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } //end if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber)) + break; + + case SIR_MAC_AUTH_FRAME_2: + // AuthFrame 2 + + if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + /** + * Check if a Reassociation is in progress and this is a + * Pre-Auth frame + */ + if (((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) && + (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) && + (psessionEntry->ftPEContext.pFTPreAuthReq != NULL) && + (vos_mem_compare( + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, + pHdr->sa, sizeof(tSirMacAddr)))) + { + // Update the FTIEs in the saved auth response + PELOGW(limLog(pMac, LOGW, FL("received another PreAuth frame2" + " from peer " MAC_ADDRESS_STR" in Smestate %d"), + MAC_ADDR_ARRAY(pHdr->sa), psessionEntry->limSmeState);) + + psessionEntry->ftPEContext.saved_auth_rsp_length = 0; + if ((pBody != NULL) && (frameLen < MAX_FTIE_SIZE)) + { + vos_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp, + pBody, frameLen); + psessionEntry->ftPEContext.saved_auth_rsp_length = frameLen; + } + } + else +#endif + { + /** + * Received Authentication frame2 in an unexpected state. + * Log error and ignore the frame. + */ + + // Log error + PELOG1(limLog(pMac, LOG1, + FL("received Auth frame2 from peer in state %d, addr "), + psessionEntry->limMlmState);) + PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);) + } + + return; + + } + + if ( !vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + /** + * Received Authentication frame from an entity + * other than one request was initiated. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received Auth frame2 from unexpected peer " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS) + { + /** + * Interoperability workaround: Linksys WAP4400N is returning + * wrong authType in OpenAuth response in case of + * SharedKey AP configuration. Pretend we don't see that, + * so upper layer can fallback to SharedKey authType, + * and successfully connect to the AP. + */ + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + pRxAuthFrameBody->authAlgoNumber = + pMac->lim.gpLimMlmAuthReq->authType; + } + } + + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + /** + * Received Authentication frame with an auth + * algorithm other than one requested. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received Auth frame2 for unexpected auth algo number %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_SUCCESS_STATUS) + { + if (pRxAuthFrameBody->authAlgoNumber == + eSIR_OPEN_SYSTEM) + { + psessionEntry->limCurrentAuthType = eSIR_OPEN_SYSTEM; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + return; + } + + PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer "), pAuthNode);) + PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);) + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType; + limAddPreAuthNode(pMac, pAuthNode); + + limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) + else + { + // Shared key authentication + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Privacy option")); + } + cfgPrivacyOptImp = (tANI_U8)val; + if (!cfgPrivacyOptImp) + { + /** + * Requesting STA does not have WEP implemented. + * Reject with unsupported authentication algorithm + * Status code and wait until auth failure timeout + */ + + // Log error + PELOGE( limLog(pMac, LOGE, + FL("received Auth frame from peer for unsupported auth algo %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + else + { + + if (pRxAuthFrameBody->type != + SIR_MAC_CHALLENGE_TEXT_EID) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame with invalid challenge text IE"));) + + return; + } + + /** + * Check if there exists a key mappping key + * for the STA that sent Authentication frame + */ + pKeyMapEntry = limLookUpKeyMappings( + pHdr->sa); + + if (pKeyMapEntry) + { + if (pKeyMapEntry->key == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer when key mapping key is NULL" + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Key Mapping entry has null key. + * Send Auth frame with + * challenge failure status code + */ + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + limRestoreFromAuthState(pMac, eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + + return; + } // if (pKeyMapEntry->key == NULL) + else + { + ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber = + sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber); + ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber = + sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1)); + ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID; + ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH; + vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText, + pRxAuthFrameBody->challengeText, + SIR_MAC_AUTH_CHALLENGE_LENGTH); + + limEncryptAuthFrame(pMac, 0, + pKeyMapEntry->key, + plainBody, + encrAuthFrame,key_length); + + psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limSendAuthMgmtFrame(pMac, + (tpSirMacAuthFrameBody) encrAuthFrame, + pHdr->sa, + LIM_WEP_IN_FC,psessionEntry); + + break; + } // end if (pKeyMapEntry->key == NULL) + } // if (pKeyMapEntry) + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Default keyId + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Default keyId")); + } + keyId = (tANI_U8)val; + + val = SIR_MAC_KEY_LENGTH; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + tpSirKeys pKey; + pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0]; + vos_mem_copy(defaultKey, pKey->key, pKey->keyLength); + } + else + if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId), + defaultKey, + &val) + != eSIR_SUCCESS) + { + /// Could not get Default key from CFG. + //Log error. + limLog(pMac, LOGP, + FL("could not retrieve Default key")); + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + limRestoreFromAuthState(pMac, eSIR_SME_INVALID_WEP_DEFAULT_KEY, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + + break; + } + key_length=val; + ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber = + sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber); + ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber = + sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1)); + ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID; + ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH; + vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText, + pRxAuthFrameBody->challengeText, + SIR_MAC_AUTH_CHALLENGE_LENGTH); + + limEncryptAuthFrame(pMac, keyId, + defaultKey, + plainBody, + encrAuthFrame,key_length); + + psessionEntry->limMlmState = + eLIM_MLM_WT_AUTH_FRAME4_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limSendAuthMgmtFrame(pMac, + (tpSirMacAuthFrameBody) encrAuthFrame, + pHdr->sa, + LIM_WEP_IN_FC,psessionEntry); + + break; + } // end if (pKeyMapEntry) + } // end if (!wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + } // end if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) + } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + else + { + /** + * Authentication failure. + * Return Auth confirm with received failure code to SME + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer with failure code %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // end if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + + break; + + case SIR_MAC_AUTH_FRAME_3: + // AuthFrame 3 + + if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with auth algo number %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Received Authentication frame3 with algorithm other than + * Shared Key authentication type. Reject with Auth frame4 + * with 'out of sequence' status code. + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + /** + * Check if wep bit was set in FC. If not set, + * reject with Authentication frame4 with + * 'challenge failure' status code. + */ + if (!pHdr->fc.wep) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with no WEP bit set "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + /// WEP bit is not set in FC of Auth Frame3 + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + + pAuthNode = limSearchPreAuthList(pMac, + pHdr->sa); + if (pAuthNode == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGW, + FL("received AuthFrame3 from peer that has no preauth context " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + /** + * No 'pre-auth' context exists for + * this STA that sent an Authentication + * frame3. + * Send Auth frame4 with 'out of sequence' + * status code. + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + + if (pAuthNode->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) + { + // Log error + limLog(pMac, LOGW, + FL("auth response timer timedout for peer " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Received Auth Frame3 after Auth Response timeout. + * Reject by sending Auth Frame4 with + * Auth respone timeout Status Code. + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS; + + limSendAuthMgmtFrame( + pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + /// Delete pre-auth context of STA + limDeletePreAuthNode(pMac, + pHdr->sa); + + return; + } // end switch (pAuthNode->mlmState) + + if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) + { + /** + * Received Authenetication Frame 3 with status code + * other than success. Wait until Auth response timeout + * to delete STA context. + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with status code %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + /** + * Check if received challenge text is same as one sent in + * Authentication frame3 + */ + + if (vos_mem_compare(pRxAuthFrameBody->challengeText, + pAuthNode->challengeText, + SIR_MAC_AUTH_CHALLENGE_LENGTH)) + { + /// Challenge match. STA is autheticated ! + + /// Delete Authentication response timer if running + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + pAuthNode->fTimerStarted = 0; + pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE; + + /** + * Send Authentication Frame4 with 'success' Status Code. + */ + authFrame.authAlgoNumber = eSIR_SHARED_KEY; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = eSIR_MAC_SUCCESS_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + + /// Send Auth indication to SME + vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr, + (tANI_U8 *) pHdr->sa, + sizeof(tSirMacAddr)); + mlmAuthInd.authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + mlmAuthInd.sessionId = psessionEntry->smeSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_IND, + (tANI_U32 *) &mlmAuthInd); + + break; + } + else + { + // Log error + PELOGE( limLog(pMac, LOGW, + FL("Challenge failure for peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Challenge Failure. + * Send Authentication frame4 with 'challenge failure' + * status code and wait until Auth response timeout to + * delete STA context. + */ + + authFrame.authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame.authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame.authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, &authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC,psessionEntry); + return; + } + } // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE || ... + + break; + + case SIR_MAC_AUTH_FRAME_4: + // AuthFrame 4 + if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE) + { + /** + * Received Authentication frame4 in an unexpected state. + * Log error and ignore the frame. + */ + + // Log error + PELOG1(limLog(pMac, LOG1, + FL("received unexpected Auth frame4 from peer in state %d, addr " + MAC_ADDRESS_STR), psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) + { + /** + * Received Authentication frame4 with algorithm other than + * Shared Key authentication type. + * Wait until Auth failure timeout to report authentication + * failure to SME. + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame4 from peer with invalid auth algo %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + if ( !vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + /** + * Received Authentication frame from an entity + * other than one to which request was initiated. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGE(limLog(pMac, LOGW, + FL("received Auth frame4 from unexpected peer " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + /** + * Received Authentication frame with an auth algorithm + * other than one requested. + * Wait until Authentication Failure Timeout. + */ + + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer with invalid auth seq number %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authTransactionSeqNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_SUCCESS_STATUS) + { + /** + * Authentication Success ! + * Inform SME of same. + */ + psessionEntry->limCurrentAuthType = eSIR_SHARED_KEY; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + return; + } + PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer "), pAuthNode); + limPrintMacAddr(pMac, pHdr->sa, LOG1);) + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType; + limAddPreAuthNode(pMac, pAuthNode); + + limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS, + pRxAuthFrameBody->authStatusCode,psessionEntry); + + } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + else + { + /** + * Authentication failure. + * Return Auth confirm with received failure code to SME + */ + + // Log error + PELOGE(limLog(pMac, LOGE, FL("Authentication failure from peer " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // end if (pRxAuthFrameBody->Status == 0) + + break; + + default: + /// Invalid Authentication Frame received. Ignore it. + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer with invalid auth seq " + "number %d " MAC_ADDRESS_STR), + pRxAuthFrameBody->authTransactionSeqNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } // end switch (pRxAuthFrameBody->authTransactionSeqNumber) +} /*** end limProcessAuthFrame() ***/ + + + + + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*---------------------------------------------------------------------- + * + * Pass the received Auth frame. This is possibly the pre-auth from the + * neighbor AP, in the same mobility domain. + * This will be used in case of 11r FT. + * + * !!!! This is going to be renoved for the next checkin. We will be creating + * the session before sending out the Auth. Thus when auth response + * is received we will have a session in progress. !!!!! + *---------------------------------------------------------------------- + */ +tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, void *body) +{ + tpSirMacMgmtHdr pHdr; + tpPESession psessionEntry = NULL; + tANI_U8 *pBody; + tANI_U16 frameLen; + tSirMacAuthFrameBody rxAuthFrame; + tSirMacAuthFrameBody *pRxAuthFrameBody = NULL; + tSirRetStatus ret_status = eSIR_FAILURE; + int i; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + pBody = WDA_GET_RX_MPDU_DATA(pBd); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + limLog(pMac, LOG1, + FL("Auth Frame Received: BSSID "MAC_ADDRESS_STR" (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pBd))); + + /* Auth frame has come on a new BSS, however, we need to find the session + * from where the auth-req was sent to the new AP + */ + for (i = 0; i < pMac->lim.maxBssId; i++) { + /* Find first free room in session table */ + if (pMac->lim.gpSession[i].valid == TRUE && + pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession == VOS_TRUE) { + /* Found the session */ + psessionEntry = &pMac->lim.gpSession[i]; + pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession = VOS_FALSE; + } + } + + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, + FL("Error: Unable to find session id while in pre-auth phase for FT")); + return eSIR_FAILURE; + } + + if (psessionEntry->ftPEContext.pFTPreAuthReq == NULL) + { + limLog(pMac, LOGE, FL("Error: No FT")); + // No FT in progress. + return eSIR_FAILURE; + } + + if (frameLen == 0) + { + limLog(pMac, LOGE, FL("Error: Frame len = 0")); + return eSIR_FAILURE; + } +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limPrintMacAddr(pMac, pHdr->bssId, LOG2); + limPrintMacAddr(pMac, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, LOG2); + limLog(pMac,LOG2,FL("seqControl 0x%X"), + ((pHdr->seqControl.seqNumHi << 8) | + (pHdr->seqControl.seqNumLo << 4) | + (pHdr->seqControl.fragNum))); +#endif + + // Check that its the same bssId we have for preAuth + if (!vos_mem_compare(psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, + pHdr->bssId, sizeof( tSirMacAddr ))) + { + limLog(pMac, LOGE, FL("Error: Same bssid as preauth BSSID")); + // In this case SME if indeed has triggered a + // pre auth it will time out. + return eSIR_FAILURE; + } + + if (eANI_BOOLEAN_TRUE == + psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) + { + /* + * This is likely a duplicate for the same pre-auth request. + * PE/LIM already posted a response to SME. Hence, drop it. + * TBD: + * 1) How did we even receive multiple auth responses? + * 2) Do we need to delete pre-auth session? Suppose we + * previously received an auth resp with failure which + * would not have created the session and forwarded to SME. + * And, we subsequently received an auth resp with success + * which would have created the session. This will now be + * dropped without being forwarded to SME! However, it is + * very unlikely to receive auth responses from the same + * AP with different reason codes. + * NOTE: return eSIR_SUCCESS so that the packet is dropped + * as this was indeed a response from the BSSID we tried to + * pre-auth. + */ + PELOGE(limLog(pMac,LOG1,"Auth rsp already posted to SME" + " (session %p, FT session %p)", psessionEntry, + psessionEntry);); + return eSIR_SUCCESS; + } + else + { + PELOGE(limLog(pMac,LOGW,"Auth rsp not yet posted to SME" + " (session %p, FT session %p)", psessionEntry, + psessionEntry);); + psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = + eANI_BOOLEAN_TRUE; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor")); + limLog(pMac, LOG1, FL("Pre-Auth done state")); +#endif + // Stopping timer now, that we have our unicast from the AP + // of our choice. + limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER); + + + // Save off the auth resp. + if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS)) + { + limLog(pMac, LOGE, FL("failed to convert Auth frame to struct")); + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + return eSIR_FAILURE; + } + pRxAuthFrameBody = &rxAuthFrame; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, + FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"), + (tANI_U32) pRxAuthFrameBody->authAlgoNumber, + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber, + (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);) +#endif + + switch (pRxAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_2: + if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "Auth status code received is %d", + (tANI_U32) pRxAuthFrameBody->authStatusCode);); +#endif + if (eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS == pRxAuthFrameBody->authStatusCode) + ret_status = eSIR_LIM_MAX_STA_REACHED_ERROR; + } + else + { + ret_status = eSIR_SUCCESS; + } + break; + + default: +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "Seq. no incorrect expected 2 received %d", + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber);) +#endif + break; + } + + // Send the Auth response to SME + limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry); + + return ret_status; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c new file mode 100644 index 0000000000000..43c591eeb57ca --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessBeaconFrame.cc contains the code + * for processing Received Beacon Frame. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" + +/** + * limProcessBeaconFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon Beacon + * frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Beacons received in 'normal' state in IBSS are handled by + * Beacon Processing module. + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to RX packet info structure + * @return None + */ + +void +limProcessBeaconFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tSchBeaconStruct *pBeacon; + + pMac->lim.gLimNumBeaconsRcvd++; + + /* here is it required to increment session specific heartBeat beacon counter */ + + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + PELOG2(limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2);) + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + return; + } + + /** + * Expect Beacon only when + * 1. STA is in Scan mode waiting for Beacon/Probe response or + * 2. STA is waiting for Beacon/Probe Respose Frame + * to announce join success. + * 3. STA/AP is in Learn mode + */ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + || pMac->fScanOffload + ) + { + pBeacon = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeacon ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessBeaconFrame") ); + return; + } + + // Parse received Beacon + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, + pBeacon) != eSIR_SUCCESS) + { + // Received wrongly formatted/invalid Beacon. + // Ignore it and move on. + limLog(pMac, LOGW, + FL("Received invalid Beacon in state %X"), + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + vos_mem_free(pBeacon); + return; + } + + /*during scanning, when any session is active, and beacon/Pr belongs to + one of the session, fill up the following, TBD - HB couter */ + if ((!psessionEntry->lastBeaconDtimPeriod) && + (sirCompareMacAddr( psessionEntry->bssId, pBeacon->bssid))) + { + vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp, + ( tANI_U8* )pBeacon->timeStamp, sizeof(tANI_U64) ); + psessionEntry->lastBeaconDtimCount = pBeacon->tim.dtimCount; + psessionEntry->lastBeaconDtimPeriod= pBeacon->tim.dtimPeriod; + psessionEntry->currentBssBeaconCnt++; + } + + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[0]);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[1]);) + + if (pMac->fScanOffload) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + + } + + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, + ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE), + eANI_BOOLEAN_FALSE); + /* Calling dfsChannelList which will convert DFS channel + * to Active channel for x secs if this channel is DFS channel */ + limSetDFSChannelList(pMac, pBeacon->channelNumber, + &pMac->lim.dfschannelList); + } + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } + else if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + if( psessionEntry->beacon != NULL ) + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + psessionEntry->beacon = vos_mem_malloc(psessionEntry->bcnLen); + if ( NULL == psessionEntry->beacon ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));) + } + else + { + //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->beacon, WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + psessionEntry->bcnLen); + + } + + // STA in WT_JOIN_BEACON_STATE (IBSS) + limCheckAndAnnounceJoinSuccess(pMac, pBeacon, pHdr,psessionEntry); + } // if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) + vos_mem_free(pBeacon); + } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ... + else + { + // Ignore Beacon frame in all other states + if (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE || + psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME3_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME4_STATE || + psessionEntry->limMlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE || + psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_RSP_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE || + psessionEntry->limMlmState == eLIM_MLM_ASSOCIATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_REASSOCIATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_CNF_STATE || + limIsReassocInProgress(pMac,psessionEntry)) { + // nothing unexpected about beacon in these states + pMac->lim.gLimNumBeaconsIgnored++; + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Received Beacon in unexpected state %d"), + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState);) +#ifdef WLAN_DEBUG + pMac->lim.gLimUnexpBcnCnt++; +#endif + } + } + + return; +} /*** end limProcessBeaconFrame() ***/ + + +/**--------------------------------------------------------------- +\fn limProcessBeaconFrameNoSession +\brief This function is called by limProcessMessageQueue() +\ upon Beacon reception. +\ +\param pMac +\param *pRxPacketInfo - A pointer to Rx packet info structure +\return None +------------------------------------------------------------------*/ +void +limProcessBeaconFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tpSirMacMgmtHdr pHdr; + tSchBeaconStruct *pBeacon; + + pMac->lim.gLimNumBeaconsRcvd++; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + return; + } + + /** + * No session has been established. Expect Beacon only when + * 1. STA is in Scan mode waiting for Beacon/Probe response or + * 2. STA/AP is in Learn mode + */ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)) + { + pBeacon = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeacon ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessBeaconFrameNoSession") ); + return; + } + + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, pBeacon) != eSIR_SUCCESS) + { + // Received wrongly formatted/invalid Beacon. Ignore and move on. + limLog(pMac, LOGW, FL("Received invalid Beacon in global MLM state %X"), pMac->lim.gLimMlmState); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + vos_mem_free(pBeacon); + return; + } + + if ( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, + eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE); + /* Calling dfsChannelList which will convert DFS channel + * to Active channel for x secs if this channel is DFS channel */ + limSetDFSChannelList(pMac, pBeacon->channelNumber, + &pMac->lim.dfschannelList); + } + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } // end of eLIM_MLM_LEARN_STATE) + vos_mem_free(pBeacon); + } // end of (eLIM_MLM_WT_PROBE_RESP_STATE) || (eLIM_MLM_PASSIVE_SCAN_STATE) + else + { + limLog(pMac, LOG1, FL("Rcvd Beacon in unexpected MLM state %d"), pMac->lim.gLimMlmState); + limPrintMlmState(pMac, LOG1, pMac->lim.gLimMlmState); +#ifdef WLAN_DEBUG + pMac->lim.gLimUnexpBcnCnt++; +#endif + } + + return; +} /*** end limProcessBeaconFrameNoSession() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c new file mode 100644 index 0000000000000..43cbb1269eabb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c @@ -0,0 +1,795 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessCfgUpdates.cc contains the utility functions + * to handle various CFG parameter update events + * Author: Chandra Modumudi + * Date: 01/20/03 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniGlobal.h" + +#include "wniCfgSta.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limPropExtsUtils.h" +#include "schApi.h" +#include "pmmApi.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +static void limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry); + +/** + * limSetDefaultKeyIdAndKeys() + * + *FUNCTION: + * This function is called while applying configuration + * during JOIN/REASSOC/START_BSS. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +static void +limSetDefaultKeyIdAndKeys(tpAniSirGlobal pMac) +{ +#ifdef FIXME_GEN6 + tANI_U32 val; + tANI_U32 dkCfgId; + + PELOG1(limLog(pMac, LOG1, FL("Setting default keys at SP"));) + + if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve defaultKeyId from CFG")); + } + dkCfgId = limGetCfgIdOfDefaultKeyid(val); +#endif + +} /*** end limSetDefaultKeyIdAndKeys() ***/ + +/** ------------------------------------------------------------- +\fn limSetCfgProtection +\brief sets lim global cfg cache from the config. +\param tpAniSirGlobal pMac +\return None + -------------------------------------------------------------*/ +void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry) +{ + tANI_U32 val = 0; + + if(( pesessionEntry != NULL ) && (pesessionEntry->limSystemRole == eLIM_AP_ROLE )){ + if (pesessionEntry->gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE ) + vos_mem_set((void *)&pesessionEntry->cfgProtection, sizeof(tCfgProtection), 0); + else{ + limLog(pMac, LOG1, FL(" frm11a = %d, from11b = %d, frm11g = %d, " + "ht20 = %d, nongf = %d, lsigTxop = %d, " + "rifs = %d, obss = %d"), + pesessionEntry->cfgProtection.fromlla, + pesessionEntry->cfgProtection.fromllb, + pesessionEntry->cfgProtection.fromllg, + pesessionEntry->cfgProtection.ht20, + pesessionEntry->cfgProtection.nonGf, + pesessionEntry->cfgProtection.lsigTxop, + pesessionEntry->cfgProtection.rifs, + pesessionEntry->cfgProtection.obss); + } + } + else{ + if (wlan_cfgGetInt(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("reading WNI_CFG_FORCE_POLICY_PROTECTION cfg failed")); + return; + } + else + pMac->lim.gLimProtectionControl = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROTECTION_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("reading protection cfg failed")); + return; + } + + if (pMac->lim.gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + vos_mem_set((void *)&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0); + else + { + pMac->lim.cfgProtection.fromlla = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llA) & 1; + pMac->lim.cfgProtection.fromllb = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llB) & 1; + pMac->lim.cfgProtection.fromllg = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llG) & 1; + pMac->lim.cfgProtection.ht20 = (val >> WNI_CFG_PROTECTION_ENABLED_HT_20) & 1; + pMac->lim.cfgProtection.nonGf = (val >> WNI_CFG_PROTECTION_ENABLED_NON_GF) & 1; + pMac->lim.cfgProtection.lsigTxop = (val >> WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP) & 1; + pMac->lim.cfgProtection.rifs = (val >> WNI_CFG_PROTECTION_ENABLED_RIFS) & 1; + pMac->lim.cfgProtection.obss= (val >> WNI_CFG_PROTECTION_ENABLED_OBSS) & 1; + + } + } +} + + + +/** + * limUpdateTriggerStaBkScanFlag + * + * FUNCTION: + * This function updates the lim global gLimTriggerBackgroundScanDuringQuietBss + * based on cfg configuration. Usually triggered after a cfgSetInt call. + * + * PARAMS: + * pMac - Pointer to Global MAC structure + * + */ +static tSirRetStatus limUpdateTriggerStaBkScanFlag(tpAniSirGlobal pMac) +{ + tANI_U32 val; + tANI_U8 flag; + + if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN from cfg"));) + return eSIR_FAILURE; + } + + flag = (val) ? 1 : 0; + if(flag != pMac->lim.gLimTriggerBackgroundScanDuringQuietBss) + { + /* Update global flag */ + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = flag; + /*Update beacon prop IE also if we're an AP */ + + //call a wrapper and if the session role is other than the sta call this function schsetfixedbeacon fields function + limUpdateBeacon(pMac); + + } + + return eSIR_FAILURE; +} +/** + * limHandleParamUpdate() + * + *FUNCTION: + * This function is use to post a message whenever need indicate + * there is update of config parameter. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param cfgId - ID of CFG parameter that got updated + * @return None + */ +void +limHandleParamUpdate(tpAniSirGlobal pMac, eUpdateIEsType cfgId) +{ + tSirMsgQ msg = {0}; + tANI_U32 status; + + PELOG3(limLog(pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);) + switch (cfgId) + { + case eUPDATE_IE_PROBE_BCN: + { + msg.type = SIR_LIM_UPDATE_BEACON; + status = limPostMsgApi(pMac, &msg); + + if (status != TX_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed limPostMsgApi %u"), status);) + break; + } + default: + break; + } +} + +/** + * limHandleCFGparamUpdate() + * + *FUNCTION: + * This function is called by limProcessMessages() to + * whenever SIR_CFG_PARAM_UPDATE_IND message is posted + * to LIM (due to a set operation on a CFG parameter). + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param cfgId - ID of CFG parameter that got updated + * @return None + */ + +void +limHandleCFGparamUpdate(tpAniSirGlobal pMac, tANI_U32 cfgId) +{ + tANI_U32 val1, val2; + tANI_U16 val16; + tSirMacHTCapabilityInfo *pHTCapabilityInfo; + tSirMacHTParametersInfo *pAmpduParamInfo; + + PELOG3(limLog(pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);) + switch (cfgId) + { + case WNI_CFG_WEP_DEFAULT_KEYID: + + // !!LAC - when the default KeyID is changed, force all of the + // keys and the keyID to be reprogrammed. this allows the + // keys to change after the initial setting of the keys when the CFG was + // applied at association time through CFG changes of the keys. + limSetDefaultKeyIdAndKeys( pMac ); + + break; + + case WNI_CFG_EXCLUDE_UNENCRYPTED: + if (wlan_cfgGetInt(pMac, WNI_CFG_EXCLUDE_UNENCRYPTED, + &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve excludeUnencr from CFG")); + } + limLog(pMac, LOGE, + FL("Unsupported CFG: WNI_CFG_EXCLUDE_UNENCRYPTED")); + + break; + + case WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT: + if (pMac->lim.gLimMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) + { + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, + eLIM_ASSOC_FAIL_TIMER); + } + + break; + + case WNI_CFG_BACKGROUND_SCAN_PERIOD: + + + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + break; + } + if (val1 == 0) + break; + + + + if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) || + ( (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE))) + { + // Reactivate Background scan timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + /// Could not activate background scan timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = FALSE; + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + else + { + pMac->lim.gLimBackgroundScanStarted = TRUE; + pMac->lim.gLimBackgroundScanTerminate = FALSE; + } + + PELOG3(limLog(pMac, LOG3, + FL("Updated Background scan period"));) + } + + break; + + case WNI_CFG_BG_SCAN_CHANNEL_LIST: + PELOG1(limLog(pMac, LOG1, + FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel"));) + pMac->lim.gLimBackgroundScanChannelId = 0; + + break; + + case WNI_CFG_TRIG_STA_BK_SCAN: + if(limUpdateTriggerStaBkScanFlag(pMac) != eSIR_SUCCESS) + { + PELOG2(limLog(pMac, LOG2, + FL("Updating lim trigger sta bk scan global flag failed!"));) + } + break; + + case WNI_CFG_PROTECTION_ENABLED: + limSetCfgProtection(pMac, NULL); + break; + case WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG: + { + tSirMsgQ msg = {0}; + tANI_U32 status; + + msg.type = SIR_LIM_UPDATE_BEACON; + + status = limPostMsgApi(pMac, &msg); + + if (status != TX_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed limPostMsgApi %u"), status);) + break; + } + case WNI_CFG_GREENFIELD_CAPABILITY: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_GREENFIELD_CAPABILITY, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve GreenField CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->greenField = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_HT_RX_STBC: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_CAP_INFO "));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_RX_STBC, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_RX_STBC"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->rxSTBC = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_MAX_AMSDU_LENGTH: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_AMSDU_LENGTH, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max AMSDU Length CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->maximalAMSDUsize = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_SHORT_GI_20MHZ: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + case WNI_CFG_SHORT_GI_40MHZ: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + case WNI_CFG_MPDU_DENSITY: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MPDU_DENSITY, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve MPDU Density CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->mpduDensity = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));) + + break; + case WNI_CFG_MAX_RX_AMPDU_FACTOR: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));) + break; + + case WNI_CFG_HEART_BEAT_THRESHOLD: + if(pMac->psOffloadEnabled) + { + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));) + break; + } + if(!val1) + { + limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER); + pMac->sys.gSysEnableLinkMonitorMode = 0; + } + else + { + tANI_U16 sessionId; + pMac->sys.gSysEnableLinkMonitorMode = 1; + for(sessionId = 0; sessionId < pMac->lim.maxBssId; sessionId++) + { + if( (pMac->lim.gpSession[sessionId].valid )&& + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[sessionId].limMlmState) && + ( pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + PELOG2(limLog(pMac, LOG2, "HB link monitoring reactivated" + " for session=%d", sessionId);) + PELOGW(limLog(pMac, LOGW, "Before reactivating HB timer; parameters are" + " session=%d limMlmState=%d pmmState=%d", sessionId, + pMac->lim.gpSession[sessionId].limMlmState, + pMac->pmm.gPmmState);) + limReactivateHeartBeatTimer(pMac, &pMac->lim.gpSession[sessionId]); + } + else if ( pMac->lim.gpSession[sessionId].valid ) + { + PELOGW(limLog(pMac, LOGW, "HB link monitoring not reactivated-" + "session=%d, limMlmState=%d, gPmmState=%d", + sessionId, pMac->lim.gpSession[sessionId].limMlmState, + pMac->pmm.gPmmState);) + } + } + } + case WNI_CFG_MAX_PS_POLL: + case WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE: + case WNI_CFG_MIN_RSSI_THRESHOLD: + case WNI_CFG_NTH_BEACON_FILTER: + case WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE: + if(!pMac->psOffloadEnabled) + { + tpSirPowerSaveCfg pPowerSaveConfig; + + /* Allocate and fill in power save configuration. */ + pPowerSaveConfig = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if ( NULL == pPowerSaveConfig ) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save configuration"));) + break; + } + + /* This context should be valid if power-save configuration message has been already dispathed + * during initialization process. Re-using the present configuration mask + */ + vos_mem_copy(pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg, sizeof(tSirPowerSaveCfg)); + + if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed "));) + } + } + break; + + + case WNI_CFG_DOT11_MODE: + if (wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Dot11 Mode CFG"));) + break; + } + break; + case WNI_CFG_ADDBA_REQ_DECLINE: + if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get ADDBA_REQ_DECLINE cfg" )); + break; + } + pMac->lim.gAddBA_Declined = (tANI_U8)val1; + break; + + case WNI_CFG_SCAN_IN_POWERSAVE: + if(wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_SCAN_IN_POWERSAVE " )); + break; + } + pMac->lim.gScanInPowersave = (tANI_U8)val1; + break; + + + case WNI_CFG_ASSOC_STA_LIMIT: + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_ASSOC_STA_LIMIT" )); + break; + } + pMac->lim.gLimAssocStaLimit = (tANI_U16)val1; + break; + + case WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC: + if (wlan_cfgGetInt + (pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, &val1) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL( "Unable to get WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC")); + break; + } + if (val1) + { + limLog(pMac, LOGW, + FL("BTC requested to disable all RX BA sessions")); + limDelPerBssBASessionsBtc(pMac); + } + else + { + limLog(pMac, LOGW, + FL("Resetting the WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC")); + } + break; + + default: + break; + } +} /*** end limHandleCFGparamUpdate() ***/ + + + +/** + * limApplyConfiguration() + * + *FUNCTION: + * This function is called to apply the configured parameters + * before joining or reassociating with a BSS or starting a BSS. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limApplyConfiguration(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 val=0, phyMode; + + PELOG2(limLog(pMac, LOG2, FL("Applying config"));) + + limInitWdsInfoParams(pMac); + + psessionEntry->limSentCapsChangeNtf = false; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + // Set default keyId and keys + limSetDefaultKeyIdAndKeys(pMac); + + limUpdateConfig(pMac,psessionEntry); + + limGetShortSlotFromPhyMode(pMac, psessionEntry, phyMode, + &psessionEntry->shortSlotTimeSupported); + + limSetCfgProtection(pMac, psessionEntry); + + + /* Added for BT - AMP Support */ + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) + { + /* This check is required to ensure the beacon generation is not done + as a part of join request for a BT-AMP station */ + + if(psessionEntry->statypeForBss == STA_ENTRY_SELF) + { + PELOG1(limLog(pMac, LOG1, FL("Initializing BT-AMP beacon generation"));) + schSetBeaconInterval(pMac,psessionEntry); + schSetFixedBeaconFields(pMac,psessionEntry); + } + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve WNI_CFG_SCAN_IN_POWERSAVE")); + return; + } + + PELOG1(limLog(pMac, LOG1, FL("pMac->lim.gScanInPowersave = %hu"), + pMac->lim.gScanInPowersave);) + pMac->lim.gScanInPowersave = (tANI_U8) val; + +} /*** end limApplyConfiguration() ***/ + + +/** + * limUpdateConfig + * + * FUNCTION: + * Update the local state from CFG database + * (This used to be dphUpdateConfig) + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +static void +limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 val; + + sirCopyMacAddr(pMac->lim.gLimMyMacAddr,psessionEntry->selfMacAddr); + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get short preamble failed")); + psessionEntry->beaconParams.fShortPreamble = (val) ? 1 : 0; + + /* In STA case this parameter is filled during the join request */ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_WME_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get wme enabled failed")); + psessionEntry->limWmeEnabled = (val) ? 1 : 0; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_WSM_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get wsm enabled failed")); + psessionEntry->limWsmEnabled = (val) ? 1 : 0; + + if ((! psessionEntry->limWmeEnabled) && (psessionEntry->limWsmEnabled)) + { + PELOGE(limLog(pMac, LOGE, FL("Can't enable WSM without WME"));) + psessionEntry->limWsmEnabled = 0; + } + /* In STA , this parameter is filled during the join request */ + if (psessionEntry->limSystemRole== eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get qos enabled failed")); + psessionEntry->limQosEnabled = (val) ? 1 : 0; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_HCF_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get hcf enabled failed")); + psessionEntry->limHcfEnabled = (val) ? 1 : 0; + + // Update the ADD BA Declined configuration + if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val) != eSIR_SUCCESS) + limLog( pMac, LOGP, FL( "Unable to get ADDBA_REQ_DECLINE cfg" )); + pMac->lim.gAddBA_Declined = (val) ? 0xff : 0x0; + + // AP: WSM should enable HCF as well, for STA enable WSM only after + // association response is received + if (psessionEntry->limWsmEnabled && psessionEntry->limSystemRole == eLIM_AP_ROLE) + psessionEntry->limHcfEnabled = 1; + + if (wlan_cfgGetInt(pMac, WNI_CFG_11D_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get 11d enabled failed")); + psessionEntry->lim11dEnabled = (val) ? 1 : 0; + + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + if( (!WDI_getFwWlanFeatCaps(SAP32STA)) && (val >= WNI_CFG_ASSOC_STA_LIMIT_STAMAX)) + { + if(ccmCfgSetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, WNI_CFG_ASSOC_STA_LIMIT_STADEF, + NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + val = WNI_CFG_ASSOC_STA_LIMIT_STADEF; + } + pMac->lim.gLimAssocStaLimit = (tANI_U16)val; + +#if defined WLAN_FEATURE_VOWIFI + rrmUpdateConfig( pMac, psessionEntry ); +#endif + PELOG1(limLog(pMac, LOG1, FL("Updated Lim shadow state based on CFG"));) +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c new file mode 100644 index 0000000000000..8653b2abb0a2c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessDeauthFrame.cc contains the code + * for processing Deauthentication Frame. + * Author: Chandra Modumudi + * Date: 03/24/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "aniGlobal.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "schApi.h" +#include "limSendMessages.h" + + + +/** + * limProcessDeauthFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Deauthentication frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs + * @return None + */ + +void +limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 aid, reasonCode; + tpSirMacMgmtHdr pHdr; + tLimMlmAssocCnf mlmAssocCnf; + tLimMlmDeauthInd mlmDeauthInd; + tpDphHashNode pStaDs; + tpPESession pRoamSessionEntry=NULL; + tANI_U8 roamSessionId; +#ifdef WLAN_FEATURE_11W + tANI_U32 frameLen; +#endif + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + + if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && + ((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) || + (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) + { + /*Every 15th deauth frame will be logged in kmsg*/ + if(!(pMac->lim.deauthMsgCnt & 0xF)) + { + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in DEAUTH_WT_STATE" + "(already processing previously received DEAUTH frame).." + "Dropping this.. Deauth Failed %d"),++pMac->lim.deauthMsgCnt);) + } + else + { + pMac->lim.deauthMsgCnt++; + } + return; + } + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Deauth frame from a BC/MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame from a BC/MC address"));) + + return; + } + + if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da)) + { + // Received Deauth frame for a MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame for a MC address"));) + + return; + } + + if (!lim_validate_received_frame_a1_addr(pMac, pHdr->da, psessionEntry)) { + limLog(pMac, LOGE, + FL("rx frame doesn't have valid a1 address, dropping it")); + return; + } + +#ifdef WLAN_FEATURE_11W + /* PMF: If this session is a PMF session, then ensure that this frame was protected */ + if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR)) + { + PELOGE(limLog(pMac, LOGE, FL("received an unprotected deauth from AP"));) + // If the frame received is unprotected, forward it to the supplicant to initiate + // an SA query + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + //send the unprotected frame indication to SME + limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), + psessionEntry->smeSessionId, psessionEntry); + return; + } +#endif + + // Get reasonCode from Deauthentication frame body + reasonCode = sirReadU16(pBody); + + PELOGE(limLog(pMac, LOGE, + FL("Received Deauth frame for Addr: "MAC_ADDRESS_STR" (mlm state = %s," + " sme state = %d systemrole = %d) with reason code %d [%s] from " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da), + limMlmStateStr(psessionEntry->limMlmState), + psessionEntry->limSmeState, + psessionEntry->limSystemRole, reasonCode, + limDot11ReasonStr(reasonCode), + MAC_ADDR_ARRAY(pHdr->sa));) + + if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa)) + { + PELOGE(limLog(pMac, LOGE, + FL("Ignore the Deauth received, while waiting for ack of " + "disassoc/deauth"));) + limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1); + return; + } + + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE )||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + // Valid reasonCode in received Deauthentication frame + break; + + default: + // Invalid reasonCode in received Deauthentication frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame with invalid reasonCode %d from " + MAC_ADDRESS_STR), reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + } + else if (psessionEntry->limSystemRole == eLIM_STA_ROLE ||psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: + case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: + case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON: + // Valid reasonCode in received Deauth frame + break; + + default: + // Invalid reasonCode in received Deauth frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame with invalid reasonCode %d from " + MAC_ADDRESS_STR), reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + } + else + { + // Received Deauth frame in either IBSS + // or un-known role. Log and ignore it + limLog(pMac, LOGE, + FL("received Deauth frame with reasonCode %d in role %d from " + MAC_ADDRESS_STR),reasonCode, psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pHdr->sa)); + + return; + } + + /** If we are in the middle of ReAssoc, a few things could happen: + * - STA is reassociating to current AP, and receives deauth from: + * a) current AP + * b) other AP + * - STA is reassociating to a new AP, and receives deauth from: + * c) current AP + * d) reassoc AP + * e) other AP + * + * The logic is: + * 1) If rcv deauth from an AP other than the one we're trying to + * reassociate with, then drop the deauth frame (case b, c, e) + * 2) If rcv deauth from the "new" reassoc AP (case d), then restore + * context with previous AP and send SME_REASSOC_RSP failure. + * 3) If rcv deauth from the reassoc AP, which is also the same + * AP we're currently associated with (case a), then proceed + * with normal deauth processing. + */ + if ( psessionEntry->limReAssocbssId!=NULL ) + { + pRoamSessionEntry = peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId); + } + if (limIsReassocInProgress(pMac,psessionEntry) || limIsReassocInProgress(pMac,pRoamSessionEntry)) { + if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different " + "AP while ReAssoc. Ignore "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + PELOGE(limLog(pMac, LOGE, FL(" limReAssocbssId : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(psessionEntry->limReAssocbssId));) + return; + } + + /** Received deauth from the new AP to which we tried to ReAssociate. + * Drop ReAssoc and Restore the Previous context( current connected AP). + */ + if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("received DeAuth from the New AP to " + "which ReAssoc is sent "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + PELOGE(limLog(pMac, LOGE, FL(" psessionEntry->bssId: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(psessionEntry->bssId));) + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + } + + + /* If received DeAuth from AP other than the one we're trying to join with + * nor associated with, then ignore deauth and delete Pre-auth entry. + */ + if(psessionEntry->limSystemRole != eLIM_AP_ROLE ){ + if (!IS_CURRENT_BSSID(pMac, pHdr->bssId, psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("received DeAuth from an AP other " + "than we're trying to join. Ignore. "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + if (limSearchPreAuthList(pMac, pHdr->sa)) + { + PELOG1(limLog(pMac, LOG1, FL("Preauth entry exist. " + "Deleting... "));) + limDeletePreAuthNode(pMac, pHdr->sa); + } + return; + } + } + + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + // Check for pre-assoc states + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + /** + * AP sent Deauth frame while waiting + * for Auth frame2. Report Auth failure + * to SME. + */ + + // Log error + PELOG1(limLog(pMac, LOG1, + FL("received Deauth frame state %X with failure " + "code %d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + limRestoreFromAuthState(pMac, eSIR_SME_DEAUTH_WHILE_JOIN, + reasonCode,psessionEntry); + + return; + + case eLIM_MLM_AUTHENTICATED_STATE: + limLog(pMac, LOG1, + FL("received Deauth frame state %X with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = reasonCode; + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_IND, + (tANI_U32 *) &mlmDeauthInd); + return; + + case eLIM_MLM_WT_ASSOC_RSP_STATE: + /** + * AP may have 'aged-out' our Pre-auth + * context. Delete local pre-auth context + * if any and issue ASSOC_CNF to SME. + */ + limLog(pMac, LOG1, + FL("received Deauth frame state %X with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN; + mlmAssocCnf.protStatusCode = reasonCode; + + /* PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + + psessionEntry->limMlmState = + psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // Deactive Association response timeout + limDeactivateAndChangeTimer( + pMac, + eLIM_ASSOC_FAIL_TIMER); + + limPostSmeMessage( + pMac, + LIM_MLM_ASSOC_CNF, + (tANI_U32 *) &mlmAssocCnf); + + return; + + case eLIM_MLM_WT_ADD_STA_RSP_STATE: + psessionEntry->fDeauthReceived = true; + PELOGW(limLog(pMac, LOGW, + FL("Received Deauth frame in state %X with Reason " + "Code %d from Peer"MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + return ; + + case eLIM_MLM_IDLE_STATE: + case eLIM_MLM_LINK_ESTABLISHED_STATE: +#ifdef FEATURE_WLAN_TDLS + if ((NULL != pStaDs) && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in state %X with " + "reason code %d from Tdls peer" + MAC_ADDRESS_STR), + psessionEntry->limMlmState,reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + reasonCode); + return; + } + else + { + /* Delete all the TDLS peers only if Deauth + * is received from the AP + */ + if (IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + /** + * This could be Deauthentication frame from + * a BSS with which pre-authentication was + * performed. Delete Pre-auth entry if found. + */ + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); +#ifdef FEATURE_WLAN_TDLS + } +#endif + break; + + case eLIM_MLM_WT_REASSOC_RSP_STATE: + limLog(pMac, LOGE, + FL("received Deauth frame state %X with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + break; + + case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in FT state %X with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + break; + + default: + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in state %X with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + return; + } + break; + + case eLIM_STA_IN_IBSS_ROLE: + break; + + case eLIM_AP_ROLE: + break; + + default: // eLIM_AP_ROLE or eLIM_BT_AMP_AP_ROLE + + + return; + } // end switch (pMac->lim.gLimSystemRole) + + + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + if (NULL == pStaDs) + { + limLog(pMac, LOGE, FL("pStaDs is NULL")); + return; + } + + if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) + { + /** + * Already in the process of deleting context for the peer + * and received Deauthentication frame. Log and Ignore. + */ + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame from peer that is in state %X, addr " + MAC_ADDRESS_STR), + pStaDs->mlmStaContext.mlmState,MAC_ADDR_ARRAY(pHdr->sa));) + return; + } + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH; + + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH; + + + /* + * If we're in the middle of ReAssoc and received deauth from + * the ReAssoc AP, then notify SME by sending REASSOC_RSP with + * failure result code. SME will post the disconnect to the + * supplicant and the latter would start a fresh assoc. + */ + if (limIsReassocInProgress(pMac,psessionEntry)) { + /** + * AP may have 'aged-out' our Pre-auth + * context. Delete local pre-auth context + * if any and issue REASSOC_CNF to SME. + */ + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + if (psessionEntry->limAssocResponseData) { + vos_mem_free(psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + + PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from ReAssoc AP. " + "Issue REASSOC_CNF. "));) + /* + * TODO: Instead of overloading eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE + * it would have been good to define/use a different failure type. + * Using eSIR_SME_FT_REASSOC_FAILURE does not seem to clean-up + * properly and we end up seeing "transmit queue timeout". + */ + limPostReassocFailure(pMac, eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, + eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + return; + } + /* reset the deauthMsgCnt here since we are able to Process + * the deauth frame and sending up the indication as well */ + if(pMac->lim.deauthMsgCnt != 0) + { + pMac->lim.deauthMsgCnt = 0; + } + if (eLIM_STA_ROLE == psessionEntry->limSystemRole) + WDA_TxAbort(psessionEntry->smeSessionId); + + /// Deauthentication from peer MAC entity + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + // send eWNI_SME_DEAUTH_IND to SME + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); + return; + +} /*** end limProcessDeauthFrame() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c new file mode 100644 index 0000000000000..affeefae4fc52 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessDisassocFrame.cc contains the code + * for processing Disassocation Frame. + * Author: Chandra Modumudi + * Date: 03/24/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfgSta.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendMessages.h" +#include "schApi.h" + + +/** + * limProcessDisassocFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Disassociation frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'. + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @return None + */ +void +limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 aid, reasonCode; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pStaDs; + tLimMlmDisassocInd mlmDisassocInd; +#ifdef WLAN_FEATURE_11W + tANI_U32 frameLen; +#endif + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Disassoc frame from a BC/MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame from a BC/MC address"));) + + return; + } + + if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da)) + { + // Received Disassoc frame for a MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame for a MC address"));) + + return; + } + if (!lim_validate_received_frame_a1_addr(pMac, pHdr->da, psessionEntry)) { + limLog(pMac, LOGE, + FL("rx frame doesn't have valid a1 address, dropping it")); + return; + } + +#ifdef WLAN_FEATURE_11W + /* PMF: If this session is a PMF session, then ensure that this frame was protected */ + if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR)) + { + PELOGE(limLog(pMac, LOGE, FL("received an unprotected disassoc from AP"));) + // If the frame received is unprotected, forward it to the supplicant to initiate + // an SA query + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + //send the unprotected frame indication to SME + limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), + psessionEntry->smeSessionId, psessionEntry); + return; + } +#endif + + // Get reasonCode from Disassociation frame body + reasonCode = sirReadU16(pBody); + + PELOG2(limLog(pMac, LOGE, + FL("Received Disassoc frame for Addr: "MAC_ADDRESS_STR"(mlm state=%s, sme state=%d)," + "with reason code %d [%s] from "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da), + limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState, + reasonCode, limDot11ReasonStr(reasonCode), + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + /** + * Disassociating STA is not associated. + * Log error. + */ + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame from STA that does not have context " + "reasonCode=%d, addr "MAC_ADDRESS_STR), + reasonCode,MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa)) + { + PELOGE(limLog(pMac, LOGE, + FL("Ignore the DisAssoc received, while waiting " + "for ack of disassoc/deauth"));) + limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1); + return; + } + + /** If we are in the Wait for ReAssoc Rsp state */ + if (limIsReassocInProgress(pMac,psessionEntry)) { + /** If we had received the DisAssoc from, + * a. the Current AP during ReAssociate to different AP in same ESS + * b. Unknown AP + * drop/ignore the DisAssoc received + */ + if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("Ignore the DisAssoc received, while " + "Processing ReAssoc with different/unknown AP"));) + return; + } + /** If the Disassoc is received from the new AP to which we tried to ReAssociate + * Drop ReAssoc and Restore the Previous context( current connected AP). + */ + if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) { + PELOGW(limLog(pMac, LOGW, FL("received Disassoc from the New AP to which ReAssoc is sent "));) + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + } + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: + case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON: + case eSIR_MAC_MIC_FAILURE_REASON: + case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON: + case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON: + case eSIR_MAC_RSN_IE_MISMATCH_REASON: + case eSIR_MAC_1X_AUTH_FAILURE_REASON: + // Valid reasonCode in received Disassociation frame + break; + + default: + // Invalid reasonCode in received Disassociation frame + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame with invalid reasonCode " + "%d from "MAC_ADDRESS_STR), + reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + break; + } + } + else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) )) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON: + case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: + case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: + case eSIR_MAC_MIC_FAILURE_REASON: + case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON: + case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON: + case eSIR_MAC_RSN_IE_MISMATCH_REASON: + case eSIR_MAC_1X_AUTH_FAILURE_REASON: + case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: + // Valid reasonCode in received Disassociation frame + break; + + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON: + // Valid reasonCode in received Disassociation frame + // as long as we're not about to channel switch + if(psessionEntry->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE) + { + limLog(pMac, LOGE, + FL("Ignoring disassoc frame due to upcoming " + "channel switch, from "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + break; + + default: + // Invalid reasonCode in received Disassociation frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame with invalid reasonCode " + "%d from "MAC_ADDRESS_STR), reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + return; + } + } + else + { + // Received Disassociation frame in either IBSS + // or un-known role. Log and ignore it + limLog(pMac, LOGE, + FL("received Disassoc frame with invalid reasonCode %d in role " + "%d in sme state %d from "MAC_ADDRESS_STR), reasonCode, + psessionEntry->limSystemRole, psessionEntry->limSmeState, + MAC_ADDR_ARRAY(pHdr->sa)); + + return; + } + + if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) + { + /** + * Already in the process of deleting context for the peer + * and received Disassociation frame. Log and Ignore. + */ + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame in state %d from "MAC_ADDRESS_STR), + pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + /** + * Requesting STA is in some 'transient' state? + * Log error. + */ + if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) + pStaDs->mlmStaContext.updateContext = 1; + + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame from peer that is in state %X, addr " + MAC_ADDRESS_STR), + pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));) + + } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; + + // Issue Disassoc Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr, + (tANI_U8 *) pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDisassocInd.reasonCode = + (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC; + + /* Update PE session Id */ + mlmDisassocInd.sessionId = psessionEntry->peSessionId; + + if (limIsReassocInProgress(pMac,psessionEntry)) { + + /* If we're in the middle of ReAssoc and received disassoc from + * the ReAssoc AP, then notify SME by sending REASSOC_RSP with + * failure result code. By design, SME will then issue "Disassoc" + * and cleanup will happen at that time. + */ + PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting " + "for Reassoc Rsp"));) + + if (psessionEntry->limAssocResponseData) { + vos_mem_free(psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + + limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + + limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, + (tANI_U32 *) &mlmDisassocInd); + + + // send eWNI_SME_DISASSOC_IND to SME + limSendSmeDisassocInd(pMac, pStaDs,psessionEntry); + + return; +} /*** end limProcessDisassocFrame() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMessageQueue.c new file mode 100644 index 0000000000000..22ff905007a6c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -0,0 +1,2300 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file lim ProcessMessageQueue.cc contains the code + * for processing LIM message Queue. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_wda.h" + +#include "wniCfgSta.h" +#include "cfgApi.h" +#include "sirCommon.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" + +#include "limAdmitControl.h" +#include "pmmApi.h" +#include "limIbssPeerMgmt.h" +#include "schApi.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limSendMessages.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +#include "limFT.h" +#endif + +#ifdef WMM_APSD +#include "wmmApsd.h" +#endif + +#include "vos_types.h" +#include "vos_packet.h" +#include "vos_memory.h" + +void limLogSessionStates(tpAniSirGlobal pMac); + +/** ------------------------------------------------------------- +\fn defMsgDecision +\brief The function decides whether to defer a message or not in limProcessMessage function +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\param tSirMacTspecIE *ppInfo +\return none + -------------------------------------------------------------*/ + +tANI_U8 static +defMsgDecision(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + + +/* this function should not changed */ + if(pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limHandleDeferMsgError(pMac, limMsg); + } + return true; + } + + //When defer is requested then defer all the messages except HAL responses. + if((!limIsSystemInScanState(pMac)) && (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) && + !pMac->lim.gLimSystemInScanLearnMode) + { + if((limMsg->type != WDA_ADD_BSS_RSP) && + (limMsg->type != WDA_DELETE_BSS_RSP) && + (limMsg->type != WDA_ADD_STA_RSP) && + (limMsg->type != WDA_ADD_STA_SELF_RSP) && + (limMsg->type != WDA_DEL_STA_SELF_RSP) && + (limMsg->type != WDA_DELETE_STA_RSP)&& + (limMsg->type != WDA_SET_BSSKEY_RSP)&& + (limMsg->type != WDA_SET_STAKEY_RSP)&& + (limMsg->type != WDA_SET_STA_BCASTKEY_RSP) && + (limMsg->type != eWNI_SME_START_REQ) && + (limMsg->type != WDA_AGGR_QOS_RSP) && + (limMsg->type != WDA_REMOVE_BSSKEY_RSP) && + (limMsg->type != WDA_REMOVE_STAKEY_RSP) && + (limMsg->type != WDA_SET_MIMOPS_RSP)&& + (limMsg->type != WDA_ADDBA_RSP) && + (limMsg->type != WDA_ENTER_BMPS_RSP) && + (limMsg->type != WDA_EXIT_BMPS_RSP) && + (limMsg->type != WDA_ENTER_IMPS_RSP) && + (limMsg->type != WDA_EXIT_IMPS_RSP) && + (limMsg->type != WDA_ENTER_UAPSD_RSP) && + (limMsg->type != WDA_EXIT_UAPSD_RSP) && + (limMsg->type != WDA_WOWL_ENTER_RSP) && + (limMsg->type != WDA_WOWL_EXIT_RSP) && + (limMsg->type != WDA_SWITCH_CHANNEL_RSP) && + (limMsg->type != WDA_P2P_NOA_ATTR_IND) && + (limMsg->type != WDA_P2P_NOA_START_IND) && +#ifdef FEATURE_OEM_DATA_SUPPORT + (limMsg->type != WDA_START_OEM_DATA_RSP) && +#endif + (limMsg->type != WDA_ADD_TS_RSP)) + { + PELOG1(limLog(pMac, LOG1, FL("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode"), + limMsgStr(limMsg->type));) + + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limHandleDeferMsgError(pMac, limMsg); + + } + return true; + } + } + return false; +} + +#ifdef FEATURE_WLAN_EXTSCAN +static void +__limExtScanForwardBcnProbeRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tSirProbeRespBeacon *pFrame, tANI_U32 ieLen) +{ + tpSirWifiFullScanResultEvent fScanResult; + tANI_U8 *pBody; + tSirMsgQ mmhMsg; + tpSirMacMgmtHdr pHdr; + + fScanResult = vos_mem_malloc(sizeof(*fScanResult) + ieLen); + if (NULL == fScanResult) { + limLog(pMac, LOGE, FL("Memory allocation failed")); + return; + } + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + vos_mem_zero(fScanResult, sizeof(*fScanResult) + ieLen); + + /* Received frame does not have request id, hence set 0 */ + fScanResult->requestId = 0; + + fScanResult->moreData = 0; + fScanResult->ap.ts = vos_timer_get_system_time(); + fScanResult->ap.beaconPeriod = pFrame->beaconInterval; + fScanResult->ap.capability = limGetU16((tANI_U8 *)&pFrame->capabilityInfo); + fScanResult->ap.channel = WDA_GET_RX_CH(pRxPacketInfo); + fScanResult->ap.rssi = WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); + fScanResult->ap.rtt = 0; + fScanResult->ap.rtt_sd = 0; + fScanResult->ap.ieLength = ieLen; + + vos_mem_copy((tANI_U8 *) &fScanResult->ap.ssid[0], + (tANI_U8 *) pFrame->ssId.ssId, pFrame->ssId.length); + fScanResult->ap.ssid[pFrame->ssId.length] = '\0'; + vos_mem_copy((tANI_U8 *) &fScanResult->ap.bssid, (tANI_U8 *) pHdr->bssId, + sizeof(tSirMacAddr)); + /* Copy IE fields */ + vos_mem_copy((tANI_U8 *) &fScanResult->ap.ieData, + pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen); + + mmhMsg.type = eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND; + mmhMsg.bodyptr = fScanResult; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +static void +__limProcessExtScanBeaconProbeRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tANI_U8 subType) +{ + tSirProbeRespBeacon *pFrame; + tANI_U8 *pBody; + tANI_U32 frameLen; + tSirRetStatus status; + + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + if (frameLen <= SIR_MAC_B_PR_SSID_OFFSET) { + limLog(pMac, LOGP, + FL("RX packet has invalid length %d"), frameLen); + return; + } + + pFrame = vos_mem_malloc(sizeof(*pFrame)); + if (NULL == pFrame) { + limLog(pMac, LOGE, FL("Memory allocation failed")); + return; + } + + if (subType == SIR_MAC_MGMT_BEACON) { + limLog(pMac, LOG2, FL("Beacon due to ExtScan")); + status = sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *)pRxPacketInfo, + pFrame); + } else if (subType == SIR_MAC_MGMT_PROBE_RSP) { + limLog(pMac, LOG2, FL("Probe Rsp due to ExtScan")); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + status = sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pFrame); + } else { + vos_mem_free(pFrame); + return; + } + + if (status != eSIR_SUCCESS) { + limLog(pMac, LOGE, FL("Frame parsing failed")); + vos_mem_free(pFrame); + return; + } + + __limExtScanForwardBcnProbeRsp(pMac, pRxPacketInfo, pFrame, + (frameLen - SIR_MAC_B_PR_SSID_OFFSET)); + vos_mem_free(pFrame); +} +#endif + + +/* +* Beacon Handling Cases: +* during scanning, when no session is active: +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* during scanning, when any session is active, but beacon/Pr does not belong to that session, psessionEntry will be null. +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* during scanning, when any session is active, and beacon/Pr belongs to one of the session, psessionEntry will not be null. +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* Not scanning, no session: +* there should not be any beacon coming, if coming, should be dropped. +* Not Scanning, +*/ +static void +__limHandleBeacon(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tpPESession psessionEntry) +{ + /* checking for global SME state...*/ + tANI_U8 *pRxPacketInfo; + limGetBDfromRxPacket(pMac, pMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo); + + //This function should not be called if beacon is received in scan state. + //So not doing any checks for the global state. + + if(psessionEntry == NULL) + { + schBeaconProcess(pMac, pRxPacketInfo, NULL); + } + else if( (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) || + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)) + { + schBeaconProcess(pMac, pRxPacketInfo, psessionEntry); + } + else + limProcessBeaconFrame(pMac, pRxPacketInfo, psessionEntry); + + return; +} + + +//Fucntion prototype +void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd); + +/** + * limDeferMsg() + * + *FUNCTION: + * This function is called to defer the messages received + * during Learn mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg of type tSirMsgQ - Pointer to the message structure + * @return None + */ + +tANI_U32 +limDeferMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tANI_U32 retCode = TX_SUCCESS; + + retCode = limWriteDeferredMsgQ(pMac, pMsg); + + if (retCode == TX_SUCCESS) + { + limLog(pMac, LOG1, + FL("Deferred message(0x%X) limSmeState %d (prev sme state %d)" + " sysRole %d mlm state %d (prev mlm state %d)"), + pMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, + pMac->lim.gLimPrevMlmState); + MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED));) + } + else + { + limLog(pMac, LOGE, FL("Dropped lim message (0x%X)"), pMsg->type); + MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED));) + } + + return retCode; +} /*** end limDeferMsg() ***/ + + + +/** + * limHandleFramesInScanState() + * + *FUNCTION: + * This function is called to process 802.11 frames + * received by LIM in scan state. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Received message + * @param pRxPacketInfo - Pointer to Rx packet info structure + * @param deferMsg - Indicates whether the frame shall be deferred + * @return None + */ + +static void +limHandleFramesInScanState(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pRxPacketInfo, tANI_U8 *deferMsg, tpPESession psessionEntry) +{ + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr; + + *deferMsg = false; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + fc = pHdr->fc; + limLog( pMac, LOG2, FL("ProtVersion %d, Type %d, Subtype %d"), + fc.protVer, fc.type, fc.subType ); + + // defer all message in scan state except for Beacons and Probe Response + if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_BEACON)) + { + if (psessionEntry == NULL) + limProcessBeaconFrameNoSession(pMac, pRxPacketInfo); + else + limProcessBeaconFrame(pMac, pRxPacketInfo,psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_RSP)) + { + if (psessionEntry == NULL) + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + else + limProcessProbeRspFrame(pMac, pRxPacketInfo,psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_REQ)) + { + limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo, psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_ACTION)) + { + limProcessActionFrameNoSession( pMac, pRxPacketInfo); + } + else + { + *deferMsg = true; + return; + } + + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr); + return; + +} /*** end limHandleFramesInScanState() ***/ + +/** ------------------------------------------------------------ +\brief This function handles Unknown Unicast (A2 Index) +\ packets. +\param tpAniSirGlobal pMac Global Mac data structure +\param void *pRxPacketInfo Pointer to Buffer Descriptor +\return none +\ +\ -------------------------------------------------------------- */ +static void limHandleUnknownA2IndexFrames(tpAniSirGlobal pMac, void *pRxPacketInfo,tpPESession psessionEntry) +{ + /* addr2 mismatch interrupt occurred this means previous + disassociation was not successful + In Volans pRxPacketInfo only contains pointer 48-bit address2 field */ + /*Send disassociation message again*/ + //Dinesh need one more arguement. + //limSendDisassocMgmtFrame(pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON,(tANI_U8 *) pRxPacketInfo); + //TODO: verify this + //This could be a public action frame. + if( psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE ) + limProcessActionFrameNoSession(pMac, (tANI_U8 *) pRxPacketInfo); + +#ifdef FEATURE_WLAN_TDLS + { + tpSirMacDataHdr3a pMacHdr; + pMacHdr = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo); + + if (limIsGroupAddr(pMacHdr->addr2)) + { + PELOG2(limLog(pMac, LOG2, FL("Ignoring A2 Invalid Packet received for MC/BC:")); + limPrintMacAddr(pMac, pMacHdr->addr2, LOG2);) + + return; + } + /* TDLS_hklee: move down here to reject Addr2 == Group (first checking above) + and also checking if SystemRole == STA */ + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + /* ADD handling of Public Action Frame */ + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \ + ("limHandleUnknownA2IndexFrames: type=0x%x, subtype=0x%x"),pMacHdr->fc.type, pMacHdr->fc.subType)); + switch (pMacHdr->fc.type) + { + case SIR_MAC_MGMT_FRAME: + { + switch (pMacHdr->fc.subType) + { + case SIR_MAC_MGMT_ACTION: + { + limProcessActionFrame(pMac, pRxPacketInfo, psessionEntry) ; + break ; + } + default: + { + break ; + } + } + } + default: + { + break ; + } + } + } + } +#endif + + + return; +} + +/** + * limCheckMgmtRegisteredFrames() + * + *FUNCTION: + * This function is called to process to check if received frame match with + * any of the registered frame from HDD. If yes pass this frame to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pBd Pointer to the received Buffer Descriptor+payload + * @param *psessionEntry Pointer to session on which packet is received + * @return None + */ +static tANI_BOOLEAN +limCheckMgmtRegisteredFrames(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry) +{ + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL; + tANI_U16 frameType; + tANI_U16 framelen; + tANI_U8 type,subType; + tANI_BOOLEAN match = VOS_FALSE; + VOS_STATUS vosStatus; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + fc = pHdr->fc; + frameType = (fc.type << 2 ) | (fc.subType << 4); + pBody = WDA_GET_RX_MPDU_DATA(pBd); + framelen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration); + + while(pLimMgmtRegistration != NULL) + { + type = (pLimMgmtRegistration->frameType >> 2) & 0x03; + subType = (pLimMgmtRegistration->frameType >> 4) & 0x0f; + if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME) + && (subType == SIR_MAC_MGMT_RESERVED15) ) + { + limLog( pMac, LOG3, + FL("rcvd frame match with SIR_MAC_MGMT_RESERVED15")); + match = VOS_TRUE; + break; + } + + if (pLimMgmtRegistration->frameType == frameType) + { + if (pLimMgmtRegistration->matchLen > 0) + { + if (pLimMgmtRegistration->matchLen <= framelen) + { + if (vos_mem_compare(pLimMgmtRegistration->matchData, + pBody, pLimMgmtRegistration->matchLen)) + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + } + else + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + + vosStatus = + vos_list_peek_next ( &pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*) pLimMgmtRegistration, + (vos_list_node_t**) &pNext ); + pLimMgmtRegistration = pNext; + pNext = NULL; + } + + if (match) + { + limLog( pMac, LOG1, + FL("rcvd frame match with registered frame params")); + + /* Indicate this to SME */ + limSendSmeMgmtFrameInd( pMac, pHdr->fc.subType, (tANI_U8*)pHdr, + WDA_GET_RX_PAYLOAD_LEN(pBd) + sizeof(tSirMacMgmtHdr), + pLimMgmtRegistration->sessionId, + WDA_GET_RX_CH(pBd), psessionEntry, 0); + + if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME) + && (subType == SIR_MAC_MGMT_RESERVED15) ) + { + // These packets needs to be processed by PE/SME as well as HDD. + // If it returns TRUE here, the packet is forwarded to HDD only. + match = VOS_FALSE; + } + } + + return match; +} /*** end limCheckMgmtRegisteredFrames() ***/ + + +/** + * limHandle80211Frames() + * + *FUNCTION: + * This function is called to process 802.11 frames + * received by LIM. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg of type tSirMsgQ - Pointer to the message structure + * @return None + */ + +static void +limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg) +{ + tANI_U8 *pRxPacketInfo = NULL; + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr=NULL; + tpPESession psessionEntry=NULL; + tANI_U8 sessionId; + tAniBool isFrmFt = FALSE; + tANI_U16 fcOffset = WLANHAL_RX_BD_HEADER_SIZE; + + *pDeferMsg= false; + limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo); + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + isFrmFt = WDA_GET_RX_FT_DONE(pRxPacketInfo); + fcOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(pRxPacketInfo); + fc = pHdr->fc; + +#ifdef WLAN_DUMP_MGMTFRAMES + limLog( pMac, LOGE, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"), + fc.protVer, fc.type, fc.subType, + WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo)); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, pHdr, + WDA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo)); +#endif + if (pMac->fEnableDebugLog & 0x1) { + if ((fc.type == SIR_MAC_MGMT_FRAME) && + (fc.subType != SIR_MAC_MGMT_PROBE_REQ) && + (fc.subType != SIR_MAC_MGMT_PROBE_RSP) && + (fc.subType != SIR_MAC_MGMT_BEACON)) + { + limLog(pMac, LOGE, FL("RX MGMT - Type %hu, SubType %hu"), + fc.type, fc.subType); + } + } +#ifdef FEATURE_WLAN_EXTSCAN + if (WMA_IS_EXTSCAN_SCAN_SRC(pRxPacketInfo)) { + if (fc.subType == SIR_MAC_MGMT_BEACON || + fc.subType == SIR_MAC_MGMT_PROBE_RSP) { + __limProcessExtScanBeaconProbeRsp(pMac, pRxPacketInfo, fc.subType); + } else { + limLog(pMac, LOGE, FL("Wrong frameType %d, Subtype %d for EXTSCAN"), + fc.type, fc.subType); + } + goto end; + } +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if ( WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) + { + limLog(pMac, LOG2, FL("Notify SME with candidate ind")); + limSendSmeCandidateFoundInd(pMac, WDA_GET_SESSIONID(pRxPacketInfo)); + goto end; + } + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + if (fc.subType == SIR_MAC_MGMT_BEACON) + { + limLog( pMac, LOG2, FL("Save this beacon in LFR cache")); + __limHandleBeacon(pMac, limMsg, NULL); + } + else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP) + { + limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache")); + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + } + else + { + limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"), + fc.type, fc.subType); + } + goto end; + } +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if (fc.type == SIR_MAC_DATA_FRAME && isFrmFt) + { + limLog(pMac, LOGE, + FL("Need to port handling of IAPP frames to QCACLD for ESE")); + } else +#endif + /* Added For BT-AMP Support */ + if((psessionEntry = peFindSessionByBssid(pMac,pHdr->bssId,&sessionId))== NULL) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + if (fc.subType == SIR_MAC_MGMT_AUTH) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"), + fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->bssId, LOG1); +#endif + if (limProcessAuthFrameNoSession(pMac, pRxPacketInfo, limMsg->bodyptr) == eSIR_SUCCESS) + { + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr); + return; + } + } +#endif + if((fc.subType != SIR_MAC_MGMT_PROBE_RSP )&& + (fc.subType != SIR_MAC_MGMT_BEACON)&& + (fc.subType != SIR_MAC_MGMT_PROBE_REQ) + && (fc.subType != SIR_MAC_MGMT_ACTION ) //Public action frame can be received from non-associated stations. + ) + { + + if((psessionEntry = peFindSessionByPeerSta(pMac,pHdr->sa,&sessionId))== NULL) + { + limLog(pMac, LOG1, FL("session does not exist for given bssId")); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr); + return; + } + else + limLog(pMac,LOG1,"SessionId:%d Session Exist for given Bssid", + psessionEntry->peSessionId); + } + // For p2p resp frames search for valid session with DA as + // BSSID will be SA and session will be present with DA only + if(fc.subType == SIR_MAC_MGMT_ACTION ) + { + psessionEntry = peFindSessionByBssid(pMac,pHdr->da,&sessionId); + } + } + + + /* Check if frame is registered by HDD */ + if(limCheckMgmtRegisteredFrames(pMac, pRxPacketInfo, psessionEntry)) + { + limLog( pMac, LOG1, FL("Received frame is passed to SME")); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr); + return; + } + + + + if (fc.protVer != SIR_MAC_PROTOCOL_VERSION) + { // Received Frame with non-zero Protocol Version + limLog(pMac, LOGE, FL("Unexpected frame with protVersion %d received"), + fc.protVer); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr); +#ifdef WLAN_DEBUG + pMac->lim.numProtErr++; +#endif + return; + } + + if (!pMac->fScanOffload) + { + if (limIsSystemInScanState(pMac)) + { + limHandleFramesInScanState(pMac, limMsg, pRxPacketInfo, pDeferMsg, psessionEntry); + return; + } + } + +/* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */ + +#ifdef WLAN_DEBUG + pMac->lim.numMAC[fc.type][fc.subType]++; +#endif + + switch (fc.type) + { + case SIR_MAC_MGMT_FRAME: + { + // Received Management frame + switch (fc.subType) + { + case SIR_MAC_MGMT_ASSOC_REQ: + // Make sure the role supports Association + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_ASSOC, psessionEntry); + + else + { + // Unwanted messages - Log error + limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + break; + + case SIR_MAC_MGMT_ASSOC_RSP: + limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_ASSOC,psessionEntry); + break; + + case SIR_MAC_MGMT_REASSOC_REQ: + // Make sure the role supports Reassociation + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ){ + limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_REASSOC, psessionEntry); + } + else + { + // Unwanted messages - Log error + limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + break; + + case SIR_MAC_MGMT_REASSOC_RSP: + limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_REASSOC,psessionEntry); + break; + + case SIR_MAC_MGMT_PROBE_REQ: + limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_PROBE_RSP: + if(psessionEntry == NULL) + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + else + limProcessProbeRspFrame(pMac, pRxPacketInfo, psessionEntry); + break; + + case SIR_MAC_MGMT_BEACON: + __limHandleBeacon(pMac, limMsg,psessionEntry); + break; + + case SIR_MAC_MGMT_DISASSOC: + limProcessDisassocFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_AUTH: + limProcessAuthFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_DEAUTH: + limProcessDeauthFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_ACTION: + if(psessionEntry == NULL) + limProcessActionFrameNoSession(pMac, pRxPacketInfo); + else + { + if (WDA_GET_RX_UNKNOWN_UCAST(pRxPacketInfo)) + limHandleUnknownA2IndexFrames(pMac, pRxPacketInfo,psessionEntry); + else + limProcessActionFrame(pMac, pRxPacketInfo,psessionEntry); + } + break; + default: + // Received Management frame of 'reserved' subtype + break; + } // switch (fc.subType) + + } + break; + case SIR_MAC_DATA_FRAME: + { +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + /* We accept data frame (IAPP frame) only if Session is + * present and ese connection is established on that + * session + */ + if (psessionEntry && psessionEntry->isESEconnection) { + limProcessIappFrame(pMac, pRxPacketInfo, psessionEntry); + } +#endif + } + break; + default: + // Received frame of type 'reserved' + break; + + } // switch (fc.type) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +end: +#endif + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr) ; + return; +} /*** end limHandle80211Frames() ***/ + +/** + * limSendStopScanOffloadReq() + * + *FUNCTION: + * This function will be called to abort the ongoing offloaded scan + * request. + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return eHAL_STATUS_SUCCESS or eHAL_STATUS_FAILURE + */ +eHalStatus limSendStopScanOffloadReq(tpAniSirGlobal pMac, tANI_U8 SessionId) +{ + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + tAbortScanParams *pAbortScanParams; + + pAbortScanParams = vos_mem_malloc(sizeof(tAbortScanParams)); + if (NULL == pAbortScanParams) + { + limLog(pMac, LOGP, FL("Memory allocation failed for AbortScanParams")); + return eHAL_STATUS_FAILURE; + } + + pAbortScanParams->SessionId = SessionId; + msg.type = WDA_STOP_SCAN_OFFLOAD_REQ; + msg.bodyptr = pAbortScanParams; + msg.bodyval = 0; + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure")); + vos_mem_free(pAbortScanParams); + return eHAL_STATUS_FAILURE; + } + + limLog(pMac, LOG1, FL("Abort ongoing offload scan.")); + return eHAL_STATUS_SUCCESS; + +} + +/** + * limProcessAbortScanInd() + * + *FUNCTION: + * This function is called from HDD to abort the scan which is presently being run + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +void +limProcessAbortScanInd(tpAniSirGlobal pMac, tANI_U8 SessionId) +{ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Deactivate the gLimBackgroundScanTimer as part of the abort scan. + * SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication + * to start the background scan again + */ + PELOG2(limLog(pMac, LOG2, FL("Processing AbortScan Ind"));) + + limAbortBackgroundScan(pMac); + + if (pMac->fScanOffload) + { + /* send stop scan cmd to fw if scan offload is enabled. */ + limSendStopScanOffloadReq(pMac, SessionId); + } + else + { + /* Abort the scan if its running, else just return */ + if(limIsSystemInScanState(pMac)) + { + if( (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_START_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_END_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_FINISH_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) ) + { + //Simply signal we need to abort + limLog( pMac, LOGW, FL(" waiting for HAL, simply signal abort gLimHalScanState = %d"), pMac->lim.gLimHalScanState ); + pMac->lim.abortScan = 1; + } + else + { + //Force abort + limLog( pMac, LOGW, FL(" Force aborting scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + } + } + return; +} + +/** + * limMessageProcessor + * + *FUNCTION: + * Wrapper function for limProcessMessages when handling messages received by LIM. + * Could either defer messages or process them. + * @param pMac Pointer to Global MAC structure + * @param limMsg Received LIM message + * @return None + */ + +void limMessageProcessor(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + if (eLIM_MLM_OFFLINE_STATE == pMac->lim.gLimMlmState) + { + peFreeMsg(pMac, limMsg); + return; + } + + if (!defMsgDecision(pMac, limMsg)) + { + limProcessMessages(pMac, limMsg); + // process deferred message queue if allowed + { + if ( (! (pMac->lim.gLimAddtsSent)) + && + (! (limIsSystemInScanState(pMac))) + ) + { + if (true == GET_LIM_PROCESS_DEFD_MESGS(pMac)) + limProcessDeferredMessageQueue(pMac); + } + } + } +} + +#ifdef FEATURE_OEM_DATA_SUPPORT + +void limOemDataRspHandleResumeLinkRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* mlmOemDataRsp) +{ + if(status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("OEM Data Rsp failed to get the response for resume link")); + } + + if(NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + //"Failure" status doesn't mean that Oem Data Rsp did not happen + //and hence we need to respond to upper layers. Only Resume link is failed, but + //we got the oem data response already. + //Post the meessage to MLM + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)(mlmOemDataRsp)); + + return; +} + +void limProcessOemDataRsp(tpAniSirGlobal pMac, tANI_U32* body) +{ + tpLimMlmOemDataRsp mlmOemDataRsp = NULL; + + //Process all the messages for the lim queue + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + mlmOemDataRsp = (tpLimMlmOemDataRsp) body; + + PELOG1(limLog(pMac, LOG1, FL("%s: sending oem data response msg to sme"), + __func__);) + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)(mlmOemDataRsp)); + + return; +} + +#endif + +/** + * limProcessMessages + * + *FUNCTION: + * This function is called by limProcessMessageQueue function. This + * function processes messages received by LIM. + * + *LOGIC: + * Depending on the message type, corresponding function will be + * called, for example limProcessSmeMessages() will be called to + * process SME messages received from HDD/Upper layer software module. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param limMsg Received LIM message + * @return None + */ + +void +limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tANI_U8 deferMsg = false; + tLinkStateParams *linkStateParams; +#if defined WLAN_FEATURE_VOWIFI_11R + tpPESession pSession; +#endif +#if defined(ANI_DVT_DEBUG) + tSirMsgQ msgQ; +#endif + if(pMac->gDriverType == eDRIVER_TYPE_MFG) + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + if (limMsg == NULL) + { + limLog(pMac, LOGE, FL("Message pointer is Null")); + VOS_ASSERT(0); + return; + } +#ifdef WLAN_DEBUG + pMac->lim.numTot++; +#endif + + + PELOG3(limLog(pMac, LOG3, FL("rcvd msgType = %s, sme state = %s, mlm state = %s"), + limMsgStr(limMsg->type), limSmeStateStr(pMac->lim.gLimSmeState), + limMlmStateStr(pMac->lim.gLimMlmState));) + + MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(limMsg->type, LIM_MSG_PROCESSED));) + + switch (limMsg->type) + { + + case SIR_LIM_UPDATE_BEACON: + limUpdateBeacon(pMac); + break; + + case SIR_CFG_PARAM_UPDATE_IND: + /// CFG parameter updated + if (limIsSystemInScanState(pMac)) + { + // System is in DFS (Learn) mode + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + if(!(pMac->lim.deferredMsgCnt & 0xF)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + } + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + } + else + { + limHandleCFGparamUpdate(pMac, limMsg->bodyval); + } + + break; + + case WDA_INIT_SCAN_RSP: + limProcessInitScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_START_SCAN_RSP: + limProcessStartScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_END_SCAN_RSP: + limProcessEndScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_FINISH_SCAN_RSP: + limProcessFinishScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDA_START_OEM_DATA_RSP: + limProcessOemDataRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#endif + + case WDA_SWITCH_CHANNEL_RSP: + limProcessSwitchChannelRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + +#ifdef ANI_SIR_IBSS_PEER_CACHING + case WDA_IBSS_STA_ADD: + limIbssStaAdd(pMac, limMsg->bodyptr); + break; +#endif + case SIR_BB_XPORT_MGMT_MSG: + // These messages are from Peer MAC entity. +#ifdef WLAN_DEBUG + pMac->lim.numBbt++; +#endif + + { + v_U16_t pktLen = 0; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + tSirMsgQ limMsgNew; + + /* The original limMsg which we were deferring have the + * bodyPointer point to 'BD' instead of 'Vos pkt'. If we don't make a copy + * of limMsg, then vos_pkt_peek_data will overwrite the limMsg->bodyPointer. + * and next time when we try to process the msg, we will try to use 'BD' as + * 'Vos Pkt' which will cause a crash + */ + if (limMsg->bodyptr == NULL) + { + limLog(pMac, LOGE, FL("Message bodyptr is Null")); + VOS_ASSERT(0); + break; + } + vos_mem_copy((tANI_U8*)&limMsgNew, (tANI_U8*)limMsg, + sizeof(tSirMsgQ)); + pVosPkt = (vos_pkt_t *)limMsgNew.bodyptr; + vos_pkt_get_packet_length(pVosPkt, &pktLen); + + vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&limMsgNew.bodyptr, VOS_FALSE ); + + if( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_pkt_return_packet(pVosPkt); + break; + + } + limHandle80211Frames(pMac, &limMsgNew, &deferMsg); + + if ( deferMsg == true ) + { + PELOG1(limLog(pMac, LOG1, FL("Defer message type=%X "), limMsg->type);) + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, limMsg->type); + vos_pkt_return_packet(pVosPkt); + } + } + else + { + /* PE is not deferring this 802.11 frame so we need to call vos_pkt_return. + * Asumption here is when Rx mgmt frame processing is done, + * voss packet could be freed here. + */ + vos_pkt_return_packet(pVosPkt); + } + } + break; + + case eWNI_SME_SCAN_REQ: + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + case eWNI_SME_DISASSOC_REQ: + case eWNI_SME_DEAUTH_REQ: + case eWNI_SME_GET_SCANNED_CHANNEL_REQ: +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: +#endif +#ifdef FEATURE_WLAN_TDLS + case eWNI_SME_TDLS_SEND_MGMT_REQ: + case eWNI_SME_TDLS_ADD_STA_REQ: + case eWNI_SME_TDLS_DEL_STA_REQ: + case eWNI_SME_TDLS_LINK_ESTABLISH_REQ: +#endif + case eWNI_SME_RESET_AP_CAPS_CHANGED: + // These messages are from HDD + limProcessNormalHddMsg(pMac, limMsg, true); //need to response to hdd + break; + + case eWNI_SME_SCAN_ABORT_IND: + { + tSirMbMsg *pMsg = limMsg->bodyptr; + tANI_U8 sessionId; + if (pMsg) + { + sessionId = (tANI_U8) pMsg->data[0]; + limProcessAbortScanInd(pMac, sessionId); + vos_mem_free((v_VOID_t *)limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + } + break; + case eWNI_SME_START_REQ: + case eWNI_SME_SYS_READY_IND: + case eWNI_SME_JOIN_REQ: + case eWNI_SME_REASSOC_REQ: + case eWNI_SME_START_BSS_REQ: + case eWNI_SME_STOP_BSS_REQ: + case eWNI_SME_SWITCH_CHL_REQ: + case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ: + case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ: + case eWNI_SME_SETCONTEXT_REQ: + case eWNI_SME_REMOVEKEY_REQ: + case eWNI_SME_DISASSOC_CNF: + case eWNI_SME_DEAUTH_CNF: + case eWNI_SME_ASSOC_CNF: + case eWNI_SME_REASSOC_CNF: + case eWNI_SME_ADDTS_REQ: + case eWNI_SME_DELTS_REQ: + case eWNI_SME_DEL_BA_PEER_IND: + case eWNI_SME_SET_TX_POWER_REQ: + case eWNI_SME_GET_TX_POWER_REQ: + case eWNI_SME_GET_NOISE_REQ: + case eWNI_SME_GET_ASSOC_STAS_REQ: + case eWNI_SME_TKIP_CNTR_MEAS_REQ: + case eWNI_SME_UPDATE_APWPSIE_REQ: + case eWNI_SME_HIDE_SSID_REQ: + case eWNI_SME_GET_WPSPBC_SESSION_REQ: + case eWNI_SME_SET_APWPARSNIEs_REQ: + case eWNI_SME_CHNG_MCC_BEACON_INTERVAL: +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: +#endif +#if defined FEATURE_WLAN_ESE + case eWNI_SME_ESE_ADJACENT_AP_REPORT: +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_UPDATE_KEY: + case eWNI_SME_FT_PRE_AUTH_REQ: + case eWNI_SME_FT_AGGR_QOS_REQ: +#endif + case eWNI_SME_ADD_STA_SELF_REQ: + case eWNI_SME_DEL_STA_SELF_REQ: + case eWNI_SME_REGISTER_MGMT_FRAME_REQ: + case eWNI_SME_UPDATE_NOA: + case eWNI_SME_CLEAR_DFS_CHANNEL_LIST: + case eWNI_SME_CLEAR_LIM_SCAN_CACHE: + case eWNI_SME_STA_STAT_REQ: + case eWNI_SME_AGGR_STAT_REQ: + case eWNI_SME_GLOBAL_STAT_REQ: + case eWNI_SME_STAT_SUMM_REQ: + case eWNI_SME_GET_STATISTICS_REQ: +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + // These messages are from HDD + limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd + break; + + //Power Save Messages From HDD + case eWNI_PMC_PWR_SAVE_CFG: + case eWNI_PMC_ENTER_BMPS_REQ: + case eWNI_PMC_EXIT_BMPS_REQ: + case eWNI_PMC_ENTER_IMPS_REQ: + case eWNI_PMC_EXIT_IMPS_REQ: + case eWNI_PMC_ENTER_UAPSD_REQ: + case eWNI_PMC_EXIT_UAPSD_REQ: + case eWNI_PMC_ENTER_WOWL_REQ: + case eWNI_PMC_EXIT_WOWL_REQ: + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + if(!pMac->psOffloadEnabled) + pmmProcessMessage(pMac, limMsg); + else + pmmOffloadProcessMessage(pMac, limMsg); + break; + + case eWNI_PMC_SMPS_STATE_IND : + { + if(limMsg->bodyptr){ + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + } + break; + case eWNI_SME_SEND_ACTION_FRAME_IND: + limSendP2PActionFrame(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + case eWNI_SME_ABORT_REMAIN_ON_CHAN_IND: + { + tSirMbMsgP2p *pMbMsg = (tSirMbMsgP2p *)limMsg->bodyptr; + limAbortRemainOnChan(pMac, pMbMsg->sessionId); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + } + + case SIR_HAL_P2P_NOA_START_IND: + { + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + tANI_U8 p2pGOExists = 0; + + limLog(pMac, LOG1, "LIM received NOA start %x", limMsg->type); + + /* Since insert NOA is done and NOA start msg received, we should deactivate the Insert NOA timer */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + + for(i=0; i < pMac->lim.maxBssId; i++) + { + psessionEntry = &pMac->lim.gpSession[i]; + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { //Save P2P NOA start attributes for P2P Go persona + p2pGOExists = 1; + vos_mem_copy(&psessionEntry->p2pGoPsNoaStartInd, limMsg->bodyptr, + sizeof(tSirP2PNoaStart)); + if (psessionEntry->p2pGoPsNoaStartInd.status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGW, FL("GO NOA start failure status %d reported by FW." + " - still go ahead with deferred sme req. This is just info"), + psessionEntry->p2pGoPsNoaStartInd.status); + } + break; + } + } + + if (p2pGOExists == 0) + { + limLog(pMac, LOGW, FL("By the time, we received NOA start, GO is already removed." + " - still go ahead with deferred sme req. This is just info")); + } + + /* We received the NOA start indication. Now we can send down the SME request which requires off-channel operation */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; +#ifdef FEATURE_WLAN_TDLS + case SIR_HAL_TDLS_IND: + { + tSirTdlsInd *pTdlsInd = (tpSirTdlsInd)limMsg->bodyptr ; + tpDphHashNode pStaDs = NULL ; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + if((psessionEntry = peFindSessionByStaId(pMac,pTdlsInd->staIdx,&sessionId))== NULL) + { + limLog(pMac, LOG1, FL("session does not exist for given bssId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + if ((pStaDs = dphGetHashEntry(pMac, pTdlsInd->assocId, &psessionEntry->dph.dphHashTable)) == NULL) + { + limLog(pMac, LOG1, FL("pStaDs Does not exist for given staId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + if ((STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + limLog(pMac, LOGE, + FL("received TDLS Indication from the Firmware with Reason Code %d "), + pTdlsInd->reasonCode); + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + pTdlsInd->reasonCode); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; +#endif + case SIR_HAL_P2P_NOA_ATTR_IND: + { + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + + limLog(pMac, LOG1, FL("Received message Noa_ATTR %x"), limMsg->type); + for(i=0; i < pMac->lim.maxBssId; i++) + { + psessionEntry = &pMac->lim.gpSession[i]; + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { //Save P2P attributes for P2P Go persona + + vos_mem_copy(&psessionEntry->p2pGoPsUpdate, limMsg->bodyptr, + sizeof(tSirP2PNoaAttr)); + + limLog(pMac, LOG2, FL(" &psessionEntry->bssId " + MAC_ADDRESS_STR " ctWin=%d oppPsFlag=%d"), + MAC_ADDR_ARRAY(psessionEntry->bssId), + psessionEntry->p2pGoPsUpdate.ctWin, + psessionEntry->p2pGoPsUpdate.oppPsFlag); + + limLog(pMac, LOG2, FL(" uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d"), + psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt, + psessionEntry->p2pGoPsUpdate.uNoa1Duration, + psessionEntry->p2pGoPsUpdate.uNoa1Interval, + psessionEntry->p2pGoPsUpdate.uNoa1StartTime); + + + break; + } + } + + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + + break; + + + /* eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER Message comes after the + * device comes out of full power for the full power request sent + * because of channel switch with switch count as 0, so call the same + * function used in timeout case(i.e SIR_LIM_CHANNEL_SWITCH_TIMEOUT) + * for switching the channel*/ + case eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER: + if ( !tx_timer_running(&pMac->lim.limTimers.gLimChannelSwitchTimer) ) + { + limProcessChannelSwitchTimeout(pMac); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + //Power Save Related Messages From HAL + case WDA_ENTER_BMPS_RSP: + case WDA_EXIT_BMPS_RSP: + case WDA_EXIT_BMPS_IND: + case WDA_ENTER_IMPS_RSP: + case WDA_EXIT_IMPS_RSP: + case WDA_ENTER_UAPSD_RSP: + case WDA_EXIT_UAPSD_RSP: + case WDA_WOWL_ENTER_RSP: + case WDA_WOWL_EXIT_RSP: + if(!pMac->psOffloadEnabled) + pmmProcessMessage(pMac, limMsg); + else + pmmOffloadProcessMessage(pMac, limMsg); + break; + + case WDA_MISSED_BEACON_IND: + if(pMac->psOffloadEnabled) + limPsOffloadHandleMissedBeaconInd(pMac, limMsg); + else + limHandleMissedBeaconInd(pMac, limMsg); + + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + case WDA_MIC_FAILURE_IND: + limMicFailureInd(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WDA_ROAM_OFFLOAD_SYNCH_IND: + limRoamOffloadSynchInd(pMac, limMsg); + /* bodyPtr is freed after handling + * eWNI_SME_ROAM_OFFLOAD_SYNCH_IND in sme_ProcessMsg */ + break; +#endif + + + + case SIR_LIM_ADDTS_RSP_TIMEOUT: + limProcessSmeReqMessages(pMac,limMsg); + break; +#ifdef FEATURE_WLAN_ESE + case SIR_LIM_ESE_TSM_TIMEOUT: +#ifndef FEATURE_WLAN_ESE_UPLOAD + limProcessTsmTimeoutHandler(pMac,limMsg); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + break; + case WDA_TSM_STATS_RSP: +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmePEEseTsmRsp(pMac, (tAniGetTsmStatsRsp *)limMsg->bodyptr); +#else + limProcessHalEseTsmRsp(pMac, limMsg); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + break; +#endif + case WDA_ADD_TS_RSP: + limProcessHalAddTsRsp(pMac, limMsg); + break; + + case SIR_LIM_DEL_TS_IND: + limProcessDelTsInd(pMac, limMsg); + break; + case SIR_LIM_ADD_BA_IND: + limProcessAddBaInd(pMac, limMsg); + break; + case SIR_LIM_DEL_BA_ALL_IND: + limDelAllBASessions(pMac); + break; + case SIR_LIM_DEL_BA_IND: + limProcessMlmHalBADeleteInd( pMac, limMsg ); + break; + + case SIR_LIM_BEACON_GEN_IND: { + + if( pMac->lim.gLimSystemRole != eLIM_AP_ROLE ) + schProcessPreBeaconInd(pMac, limMsg); + + } + break; + + case SIR_LIM_DELETE_STA_CONTEXT_IND: + limDeleteStaContext(pMac, limMsg); + break; + + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + case SIR_LIM_JOIN_FAIL_TIMEOUT: + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + case SIR_LIM_AUTH_FAIL_TIMEOUT: + case SIR_LIM_AUTH_RSP_TIMEOUT: + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + case SIR_LIM_REASSOC_FAIL_TIMEOUT: +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: +#endif + case SIR_LIM_REMAIN_CHN_TIMEOUT: + case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT: + case SIR_LIM_DISASSOC_ACK_TIMEOUT: + case SIR_LIM_DEAUTH_ACK_TIMEOUT: + case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + // These timeout messages are handled by MLM sub module + + limProcessMlmReqMessages(pMac, + limMsg); + + break; + + case SIR_LIM_HEART_BEAT_TIMEOUT: + /** check if heart beat failed, even if one Beacon + * is rcvd within the Heart Beat interval continue + * normal processing + */ + + if(pMac->psOffloadEnabled) + { + /* Powersave Offload Case */ + /* TODO: Handle in Scan Case */ + /* TODO: handle in TDLS Case */ + if(NULL == limMsg->bodyptr) + { + limLog(pMac, LOGE, + FL("Cannot Process HearBeat Timeout - bodyptr is Null")); + } + else + { + tpPESession psessionEntry = (tpPESession)limMsg->bodyptr; + limLog(pMac, LOGE, + FL("Processing SIR_LIM_HEART_BEAT_TIMEOUT for Session %d"), + ((tpPESession)limMsg->bodyptr)->peSessionId); + limResetHBPktCount(psessionEntry); + limHandleHeartBeatTimeoutForSession(pMac, psessionEntry); + } + break; + } + if (limIsSystemInScanState(pMac)) + { + // System is in DFS (Learn) mode + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + } + } + else + { + if (NULL == limMsg->bodyptr) + { + limHandleHeartBeatTimeout(pMac); + } + else + { + limHandleHeartBeatTimeoutForSession(pMac, (tpPESession)limMsg->bodyptr); + } + } + break; + + case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT: + limHandleHeartBeatFailureTimeout(pMac); + break; + + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + /** + * Background scan timeout occurred on STA. + * This is handled by LMM sub module. + */ + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + //We will do background scan even in bcnps mode + //if (pMac->sys.gSysEnableScanMode) + pMac->lim.gLimReportBackgroundScanResults = FALSE; + limTriggerBackgroundScan(pMac); + break; + + + case SIR_LIM_HASH_MISS_THRES_TIMEOUT: + + /* + ** clear the credit to the send disassociate frame bucket + **/ + + pMac->lim.gLimDisassocFrameCredit = 0; + break; + + case SIR_LIM_CNF_WAIT_TIMEOUT: + + /* + ** Does not receive CNF or dummy packet + **/ + limHandleCnfWaitTimeout(pMac, (tANI_U16) limMsg->bodyval); + + break; + + case SIR_LIM_KEEPALIVE_TIMEOUT: + limSendKeepAliveToPeer(pMac); + + break; + + case SIR_LIM_RETRY_INTERRUPT_MSG: + // Message from ISR upon TFP's max retry limit interrupt + + break; + + case SIR_LIM_INV_KEY_INTERRUPT_MSG: + // Message from ISR upon SP's Invalid session key interrupt + + break; + + case SIR_LIM_KEY_ID_INTERRUPT_MSG: + // Message from ISR upon SP's Invalid key ID interrupt + + break; + + case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG: + // Message from ISR upon SP's Replay threshold interrupt + + break; + + case SIR_LIM_CHANNEL_SWITCH_TIMEOUT: + limProcessChannelSwitchTimeout(pMac); + break; + + case SIR_LIM_QUIET_TIMEOUT: + limProcessQuietTimeout(pMac); + break; + + case SIR_LIM_QUIET_BSS_TIMEOUT: + limProcessQuietBssTimeout(pMac); + break; + + case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: + limHandleUpdateOlbcCache(pMac); + break; + + +#ifdef FEATURE_WLAN_TDLS + case SIR_HAL_TDLS_SHOULD_DISCOVER: + case SIR_HAL_TDLS_SHOULD_TEARDOWN: + case SIR_HAL_TDLS_PEER_DISCONNECTED: + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("%s received tdls event: 0x%x"), + __func__, limMsg->type); + limSendSmeTdlsEventNotify(pMac, limMsg->type, + (void *)limMsg->bodyptr); + break; +#endif + + case WDA_ADD_BSS_RSP: + limProcessMlmAddBssRsp( pMac, limMsg ); + break; + + case WDA_ADD_STA_RSP: + + //call a wrapper by paasing bodyptr, their get sessionID and and call proper function from there. + limProcessAddStaRsp(pMac,limMsg); + break; + + case WDA_DELETE_STA_RSP: + limProcessMlmDelStaRsp(pMac, limMsg); + break; + + case WDA_ADD_STA_SELF_RSP: + limProcessAddStaSelfRsp(pMac, limMsg); + break; + case WDA_DEL_STA_SELF_RSP: + limProcessDelStaSelfRsp(pMac, limMsg); + break; + + case WDA_DELETE_BSS_RSP: + limHandleDeleteBssRsp(pMac,limMsg); //wrapper routine to handle delete bss response + break; + + case WDA_CSA_OFFLOAD_EVENT: + limHandleCSAoffloadMsg(pMac, limMsg); + break; + + case WDA_SET_BSSKEY_RSP: + case WDA_SET_STA_BCASTKEY_RSP: + limProcessMlmSetBssKeyRsp( pMac, limMsg ); + break; + case WDA_SET_STAKEY_RSP: + limProcessMlmSetStaKeyRsp( pMac, limMsg ); + break; + case WDA_REMOVE_BSSKEY_RSP: + case WDA_REMOVE_STAKEY_RSP: + limProcessMlmRemoveKeyRsp( pMac, limMsg ); + break; + case WDA_ADDBA_RSP: + limProcessMlmHalAddBARsp( pMac, limMsg ); + break; + + case WDA_STA_STAT_RSP: + case WDA_AGGR_STAT_RSP: + case WDA_GLOBAL_STAT_RSP: + case WDA_STAT_SUMM_RSP: + limSendSmeStatsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; + + case WDA_GET_STATISTICS_RSP: + limSendSmePEStatisticsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WDA_GET_ROAM_RSSI_RSP: + limSendSmePEGetRoamRssiRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; +#endif + + + case WDA_SET_MIMOPS_RSP: + case WDA_SET_TX_POWER_RSP: + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_SET_MAX_TX_POWER_RSP: +#if defined WLAN_FEATURE_VOWIFI + rrmSetMaxTxPowerRsp( pMac, limMsg ); +#endif + if(limMsg->bodyptr != NULL) + { + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; + + case SIR_LIM_ADDR2_MISS_IND: + { + limLog(pMac, LOGE, + FL("Addr2 mismatch interrupt received %X"), + limMsg->type); + /*a message from HAL indicating addr2 mismatch interrupt occurred + limMsg->bodyptr contains only pointer to 48-bit addr2 field*/ + + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + case WDA_AGGR_QOS_RSP: + limProcessFTAggrQoSRsp( pMac, limMsg ); + break; +#endif + + case WDA_SET_LINK_STATE_RSP: + linkStateParams = (tLinkStateParams *)limMsg->bodyptr; +#if defined WLAN_FEATURE_VOWIFI_11R + pSession = linkStateParams->session; + if(linkStateParams->ft +#if defined WLAN_FEATURE_ROAM_OFFLOAD + && !pSession->bRoamSynchInProgress +#endif + ) + { + limSendReassocReqWithFTIEsMgmtFrame(pMac, + pSession->pLimMlmReassocReq, + pSession); + } +#endif + if( linkStateParams->callback ) + { + linkStateParams->callback(pMac, linkStateParams->callbackArg, + linkStateParams->status); + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + pmmProcessMessage(pMac, limMsg); + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_GETINFO_RSP: + pmmProcessMessage(pMac, limMsg); + break; +#endif // WLAN_FEATURE_GTK_OFFLOAD + case eWNI_SME_SET_BCN_FILTER_REQ: + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + tpPESession psessionEntry; + tANI_U8 sessionId = (tANI_U8)limMsg->bodyval ; + psessionEntry = &pMac->lim.gpSession[sessionId]; + if(psessionEntry != NULL && IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + // sending beacon filtering information down to HAL + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; +#endif + } + break; +#ifdef FEATURE_WLAN_TDLS + case WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP: + { + tpPESession psessionEntry; + tANI_U8 sessionId; + tTdlsLinkEstablishParams *pTdlsLinkEstablishParams; + pTdlsLinkEstablishParams = (tTdlsLinkEstablishParams*) limMsg->bodyptr; + + if((psessionEntry = peFindSessionByStaId(pMac, + pTdlsLinkEstablishParams->staIdx, + &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session %u does not exist"), sessionId); + /* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP message to + * SME with session id as zero and status as FAILURE so, + * that message queued in SME queue can be freed to prevent + * the SME cmd buffer leak */ + limSendSmeTdlsLinkEstablishReqRsp(pMac, + 0, + NULL, + NULL, + eSIR_FAILURE); + } + else + { + limSendSmeTdlsLinkEstablishReqRsp(pMac, + psessionEntry->smeSessionId, + NULL, + NULL, + pTdlsLinkEstablishParams->status) ; + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } +#endif + + case WDA_RX_SCAN_EVENT: + limProcessRxScanEvent(pMac, limMsg->bodyptr); + break; + + case WDA_IBSS_PEER_INACTIVITY_IND: + { + limProcessIbssPeerInactivity(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } + + case WDA_DFS_RADAR_IND: + limSendSmeDfsEventNotify(pMac, limMsg->type, + (void *)limMsg->bodyptr); + /* limmsg->bodyptr will be freed up by SME/CSR */ + break; + + case WDA_DFS_BEACON_TX_SUCCESS_IND: + limProcessBeaconTxSuccessInd(pMac, limMsg->type, + (void *)limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_DISASSOC_TX_COMP: + limDisassocTxCompleteCnf(pMac , limMsg->bodyval); + break; + + case WDA_DEAUTH_TX_COMP: + limDeauthTxCompleteCnf(pMac, limMsg->bodyval); + break; + + case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_CHANNEL_CHANGE_REQ: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_START_BEACON_REQ: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_UPDATE_ADDITIONAL_IES: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_MODIFY_ADDITIONAL_IES: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + +#ifdef QCA_HT_2040_COEX + case eWNI_SME_SET_HT_2040_MODE: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#endif + default: + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + // Unwanted messages + // Log error + limLog(pMac, LOGE, + FL("Discarding unexpected message received %X"), + limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + break; + + } // switch (limMsg->type) + + PELOG2(limLog(pMac, LOG2, FL("Done Processing msgType = %d, sme state = %s, mlm state = %s"), + limMsg->type, limSmeStateStr(pMac->lim.gLimSmeState), + limMlmStateStr(pMac->lim.gLimMlmState));) + +} /*** end limProcessMessages() ***/ + + + +/** + * limProcessDeferredMessageQueue + * + *FUNCTION: + * This function is called by LIM while exiting from Learn + * mode. This function fetches messages posted to the LIM + * deferred message queue limDeferredMsgQ. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limProcessDeferredMessageQueue(tpAniSirGlobal pMac) +{ + tSirMsgQ limMsg = { 0, 0, 0 }; + + tSirMsgQ *readMsg; + tANI_U16 size; + + /* + ** check any deferred messages need to be processed + **/ + size = pMac->lim.gLimDeferredMsgQ.size; + if (size > 0) + { + while ((readMsg = limReadDeferredMsgQ(pMac)) != NULL) + { + vos_mem_copy((tANI_U8*) &limMsg, + (tANI_U8*) readMsg, sizeof(tSirMsgQ)); + size--; + limProcessMessages(pMac, &limMsg); + + if((limIsSystemInScanState(pMac)) || (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) || + (pMac->lim.gLimSystemInScanLearnMode)) + break; + } + } +} /*** end limProcessDeferredMessageQueue() ***/ + + +/* + * limProcessNormalHddMsg + * Function: this function checks the current lim state and decide whether the message passed shall be deffered. + * @param pMac - Pointer to Global MAC structure + * pLimMsg -- the message need to be processed + * fRspReqd -- whether return result to hdd + * @return None + */ +void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd) +{ + tANI_BOOLEAN fDeferMsg = eANI_BOOLEAN_TRUE; + + /* Added For BT-AMP Support */ + if ((pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_AP_ROLE ) + ||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_STA_ROLE) + ||(pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)) + { + /** This check is required only for the AP and in 2 cases. + * 1. If we are in learn mode and we receive any of these messages, + * you have to come out of scan and process the message, hence dont + * defer the message here. In handler, these message could be defered + * till we actually come out of scan mode. + * 2. If radar is detected, you might have to defer all of these + * messages except Stop BSS request/ Switch channel request. This + * decision is also made inside its handler. + * + * Please be careful while using the flag fDeferMsg. Possibly you + * might end up in an infinite loop. + **/ + if (((pLimMsg->type == eWNI_SME_START_BSS_REQ) || + (pLimMsg->type == eWNI_SME_STOP_BSS_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ))) + { + fDeferMsg = eANI_BOOLEAN_FALSE; + } + } + + /* limInsystemInscanState() refers the psessionEntry, how to get session Entry????*/ + if (((pMac->lim.gLimAddtsSent) || (limIsSystemInScanState(pMac))) && + fDeferMsg) { + // System is in DFS (Learn) mode or awaiting addts response + // or if radar is detected, Defer processsing this message + if (limDeferMsg(pMac, pLimMsg) != TX_SUCCESS) + { +#ifdef WLAN_DEBUG + pMac->lim.numSme++; +#endif + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + pLimMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, pLimMsg->type); + // Release body + vos_mem_free(pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + } + else + { + if(fRspReqd) + { + // These messages are from HDD + // Since these requests may also be generated + // internally within LIM module, need to + // distinquish and send response to host + pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE; + } +#ifdef WLAN_DEBUG + pMac->lim.numSme++; +#endif + if(limProcessSmeReqMessages(pMac, pLimMsg)) + { + // Release body + // limProcessSmeReqMessage consumed the buffer. We can free it. + vos_mem_free(pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + } +} + +void +handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessionEntry) +{ + tSirMacHTCapabilityInfo macHTCapabilityInfo; + tSirMacHTParametersInfo macHTParametersInfo; + tSirMacHTInfoField1 macHTInfoField1; + tSirMacHTInfoField2 macHTInfoField2; + tSirMacHTInfoField3 macHTInfoField3; + tANI_U32 cfgValue; + tANI_U8 *ptr; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_CAP_INFO value")); + return ; + } + ptr = (tANI_U8 *) &macHTCapabilityInfo; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTLsigTXOPProtection = (tANI_U8)macHTCapabilityInfo.lsigTXOPProtection; + pMac->lim.gHTMIMOPSState = (tSirMacHTMIMOPowerSaveState) macHTCapabilityInfo.mimoPowerSave; + pMac->lim.gHTGreenfield = (tANI_U8)macHTCapabilityInfo.greenField; + pMac->lim.gHTMaxAmsduLength = (tANI_U8)macHTCapabilityInfo.maximalAMSDUsize; + pMac->lim.gHTShortGI20Mhz = (tANI_U8)macHTCapabilityInfo.shortGI20MHz; + pMac->lim.gHTShortGI40Mhz = (tANI_U8)macHTCapabilityInfo.shortGI40MHz; + pMac->lim.gHTPSMPSupport = (tANI_U8)macHTCapabilityInfo.psmp; + pMac->lim.gHTDsssCckRate40MHzSupport = (tANI_U8)macHTCapabilityInfo.dsssCckMode40MHz; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_PARAM_INFO value")); + return ; + } + ptr = (tANI_U8 *) &macHTParametersInfo; + *ptr = (tANI_U8) (cfgValue & 0xff); + pMac->lim.gHTAMpduDensity = (tANI_U8)macHTParametersInfo.mpduDensity; + pMac->lim.gHTMaxRxAMpduFactor = (tANI_U8)macHTParametersInfo.maxRxAMPDUFactor; + + // Get HT IE Info + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD1 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField1; + *((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff); + pMac->lim.gHTServiceIntervalGranularity = (tANI_U8)macHTInfoField1.serviceIntervalGranularity; + pMac->lim.gHTControlledAccessOnly = (tANI_U8)macHTInfoField1.controlledAccessOnly; + pMac->lim.gHTRifsMode = (tANI_U8)macHTInfoField1.rifsMode; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD2, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD2 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField2; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTOperMode = (tSirMacHTOperatingMode) macHTInfoField2.opMode; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD3, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD3 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField3; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTPCOActive = (tANI_U8)macHTInfoField3.pcoActive; + pMac->lim.gHTPCOPhase = (tANI_U8)macHTInfoField3.pcoPhase; + pMac->lim.gHTSecondaryBeacon = (tANI_U8)macHTInfoField3.secondaryBeacon; + pMac->lim.gHTDualCTSProtection = (tANI_U8)macHTInfoField3.dualCTSProtection; + pMac->lim.gHTSTBCBasicMCS = (tANI_U8)macHTInfoField3.basicSTBCMCS; + + /* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session; + * instead direct cfg is read and used when no session for transmission of mgmt frames (same as old); + * For now, we might come here during init and join with sessionEntry = NULL; in that case just fill the globals which exist + * Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below + */ + if (psessionEntry != NULL) + { + psessionEntry->htCapability = IS_DOT11_MODE_HT(psessionEntry->dot11mode); + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = (tANI_U8)macHTInfoField3.lsigTXOPProtectionFullSupport; + } +} + +void limLogSessionStates(tpAniSirGlobal pMac) +{ +#ifdef WLAN_DEBUG + int i; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + PELOG1(limLog(pMac, LOG1, FL("Session[%d] sysRole(%d) limSmeState %d (prev sme state %d) mlm state %d (prev mlm state %d)"), + i, pMac->lim.gpSession[i].limSystemRole, pMac->lim.gpSession[i].limSmeState, + pMac->lim.gpSession[i].limPrevSmeState, pMac->lim.gpSession[i].limMlmState, + pMac->lim.gpSession[i].limPrevMlmState);) + } + } +#endif //ifdef WLAN_DEBUG +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c new file mode 100644 index 0000000000000..c4b27115ee9c0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c @@ -0,0 +1,4781 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessMlmMessages.cc contains the code + * for processing MLM request messages. + * Author: Chandra Modumudi + * Date: 02/12/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "sirParams.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSecurityUtils.h" +#include "limSendMessages.h" +#include "pmmApi.h" +#include "limSendMessages.h" +#include "limSessionUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM +#include "vos_diag_core_log.h" +#endif + + +// MLM REQ processing function templates +static void limProcessMlmStartReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmScanReq(tpAniSirGlobal, tANI_U32 *); +#ifdef FEATURE_OEM_DATA_SUPPORT +static void limProcessMlmOemDataReq(tpAniSirGlobal, tANI_U32 *); +#endif +static void limProcessMlmJoinReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmAuthReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmAssocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmReassocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmDisassocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmDeauthReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmSetKeysReq(tpAniSirGlobal, tANI_U32 *); + +static void limProcessMlmAddBAReq( tpAniSirGlobal, tANI_U32 * ); +static void limProcessMlmAddBARsp( tpAniSirGlobal, tANI_U32 * ); +static void limProcessMlmDelBAReq( tpAniSirGlobal, tANI_U32 * ); + +// MLM Timeout event handler templates +static void limProcessMinChannelTimeout(tpAniSirGlobal); +static void limProcessMaxChannelTimeout(tpAniSirGlobal); +static void limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac); +static void limProcessJoinFailureTimeout(tpAniSirGlobal); +static void limProcessAuthFailureTimeout(tpAniSirGlobal); +static void limProcessAuthRspTimeout(tpAniSirGlobal, tANI_U32); +static void limProcessAssocFailureTimeout(tpAniSirGlobal, tANI_U32); +static void limProcessPeriodicJoinProbeReqTimer(tpAniSirGlobal); + +static void limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf); +void +limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId); +#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_AGGRESSIVE_BACKGROUND_SCAN) +#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_NORMAL_BACKGROUND_SCAN) + +/** + * limProcessMlmReqMessages() + * + *FUNCTION: + * This function is called by limPostMlmMessage(). This + * function handles MLM primitives invoked by SME. + * + *LOGIC: + * Depending on the message type, corresponding function will be + * called. + * + *ASSUMPTIONS: + * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes + * APIs exposed by Beacon Processing module for setting parameters + * at MAC hardware. + * 2. If attempt to Reassociate with an AP fails, link with current + * AP is restored back. + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ + +void +limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg) +{ + MTRACE(macTraceMsgRx(pMac, NO_SESSION, Msg->type)); + switch (Msg->type) + { + case LIM_MLM_START_REQ: limProcessMlmStartReq(pMac, Msg->bodyptr); break; + case LIM_MLM_SCAN_REQ: limProcessMlmScanReq(pMac, Msg->bodyptr); break; +#ifdef FEATURE_OEM_DATA_SUPPORT + case LIM_MLM_OEM_DATA_REQ: limProcessMlmOemDataReq(pMac, Msg->bodyptr); break; +#endif + case LIM_MLM_JOIN_REQ: limProcessMlmJoinReq(pMac, Msg->bodyptr); break; + case LIM_MLM_AUTH_REQ: limProcessMlmAuthReq(pMac, Msg->bodyptr); break; + case LIM_MLM_ASSOC_REQ: limProcessMlmAssocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_REASSOC_REQ: limProcessMlmReassocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_DISASSOC_REQ: limProcessMlmDisassocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_DEAUTH_REQ: limProcessMlmDeauthReq(pMac, Msg->bodyptr); break; + case LIM_MLM_SETKEYS_REQ: limProcessMlmSetKeysReq(pMac, Msg->bodyptr); break; + case LIM_MLM_REMOVEKEY_REQ: limProcessMlmRemoveKeyReq(pMac, Msg->bodyptr); break; + case SIR_LIM_MIN_CHANNEL_TIMEOUT: limProcessMinChannelTimeout(pMac); break; + case SIR_LIM_MAX_CHANNEL_TIMEOUT: limProcessMaxChannelTimeout(pMac); break; + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + limProcessPeriodicProbeReqTimer(pMac); break; + case SIR_LIM_JOIN_FAIL_TIMEOUT: limProcessJoinFailureTimeout(pMac); break; + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + limProcessPeriodicJoinProbeReqTimer(pMac); break; + case SIR_LIM_AUTH_FAIL_TIMEOUT: limProcessAuthFailureTimeout(pMac); break; + case SIR_LIM_AUTH_RSP_TIMEOUT: limProcessAuthRspTimeout(pMac, Msg->bodyval); break; + case SIR_LIM_ASSOC_FAIL_TIMEOUT: limProcessAssocFailureTimeout(pMac, Msg->bodyval); break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: limProcessFTPreauthRspTimeout(pMac); break; +#endif + case SIR_LIM_REMAIN_CHN_TIMEOUT: limProcessRemainOnChnTimeout(pMac); break; + case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT: + limProcessInsertSingleShotNOATimeout(pMac); break; + case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + limConvertActiveChannelToPassiveChannel(pMac); break; + case SIR_LIM_DISASSOC_ACK_TIMEOUT: limProcessDisassocAckTimeout(pMac); break; + case SIR_LIM_DEAUTH_ACK_TIMEOUT: limProcessDeauthAckTimeout(pMac); break; + case LIM_MLM_ADDBA_REQ: limProcessMlmAddBAReq( pMac, Msg->bodyptr ); break; + case LIM_MLM_ADDBA_RSP: limProcessMlmAddBARsp( pMac, Msg->bodyptr ); break; + case LIM_MLM_DELBA_REQ: limProcessMlmDelBAReq( pMac, Msg->bodyptr ); break; + case LIM_MLM_TSPEC_REQ: + default: + break; + } // switch (msgType) +} /*** end limProcessMlmReqMessages() ***/ + + +/** + * limSetScanMode() + * + *FUNCTION: + * This function is called to setup system into Scan mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSetScanMode(tpAniSirGlobal pMac) +{ + tSirLinkTrafficCheck checkTraffic; + + /// Set current scan channel id to the first in the channel list + pMac->lim.gLimCurrentScanChannelId = 0; + + if ( IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) ) + { + checkTraffic = eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN; + } + else if (IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac)) + { + checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN; + } + else + checkTraffic = eSIR_CHECK_ROAMING_SCAN; + + PELOG1(limLog(pMac, LOG1, FL("Calling limSendHalInitScanReq"));) + limSendHalInitScanReq(pMac, eLIM_HAL_INIT_SCAN_WAIT_STATE, checkTraffic); + + return ; +} /*** end limSetScanMode() ***/ + +//WLAN_SUSPEND_LINK Related + +/* limIsLinkSuspended() + * + *FUNCTION: + * This function returns is link is suspended or not. + * + *LOGIC: + * Since Suspend link uses init scan, it just returns + * gLimSystemInScanLearnMode flag. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ +tANI_U8 +limIsLinkSuspended(tpAniSirGlobal pMac) +{ + return pMac->lim.gLimSystemInScanLearnMode; +} +/** + * limSuspendLink() + * + *FUNCTION: + * This function is called to suspend traffic. Internally this function uses WDA_INIT_SCAN_REQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param trafficCheck - Takes value from enum tSirLinkTrafficCheck. + * @param callback - Callback function to be called after suspending the link. + * @param data - Pointer to any buffer that will be passed to callback. + * @return None + */ +void +limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data) +{ + if( NULL == callback ) + { + limLog( pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ ); + return; + } + + if( pMac->lim.gpLimSuspendCallback ) + { + limLog( pMac, LOGE, "%s:%d: gLimSuspendLink callback is not NULL...something is wrong", __func__, __LINE__ ); + callback( pMac, eHAL_STATUS_FAILURE, data ); + return; + } + + pMac->lim.gLimSystemInScanLearnMode = 1; + pMac->lim.gpLimSuspendCallback = callback; + pMac->lim.gpLimSuspendData = data; + limSendHalInitScanReq(pMac, eLIM_HAL_SUSPEND_LINK_WAIT_STATE, trafficCheck ); + + WDA_TrafficStatsTimerActivate(FALSE); +} + +/** + * limResumeLink() + * + *FUNCTION: + * This function is called to Resume traffic after a suspend. Internally this function uses WDA_FINISH_SCAN_REQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param callback - Callback function to be called after Resuming the link. + * @param data - Pointer to any buffer that will be passed to callback. + * @return None + */ +void +limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data) +{ + if( NULL == callback ) + { + limLog( pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ ); + return; + } + + if( pMac->lim.gpLimResumeCallback ) + { + limLog( pMac, LOGE, "%s:%d: gLimResumeLink callback is not NULL...something is wrong", __func__, __LINE__ ); + callback( pMac, eHAL_STATUS_FAILURE, data ); + return; + } + + pMac->lim.gpLimResumeCallback = callback; + pMac->lim.gpLimResumeData = data; + + /* eLIM_HAL_IDLE_SCAN_STATE state indicate limSendHalInitScanReq failed. + * In case limSendHalInitScanReq is success, Scanstate would be + * eLIM_HAL_SUSPEND_LINK_STATE + */ + if( eLIM_HAL_IDLE_SCAN_STATE != pMac->lim.gLimHalScanState ) + { + limSendHalFinishScanReq(pMac, eLIM_HAL_RESUME_LINK_WAIT_STATE ); + } + else + { + limLog(pMac, LOGW, FL("Init Scan failed, we will not call finish scan." + " calling the callback with failure status")); + pMac->lim.gpLimResumeCallback( pMac, eSIR_FAILURE, pMac->lim.gpLimResumeData); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + + if(limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(TRUE); + } +} +//end WLAN_SUSPEND_LINK Related + + +/** + * + * limChangeChannelWithCallback() + * + * FUNCTION: + * This function is called to change channel and perform off channel operation + * if required. The caller registers a callback to be called at the end of the + * channel change. + * + */ +void +limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel, + CHANGE_CHANNEL_CALLBACK callback, + tANI_U32 *cbdata, tpPESession psessionEntry) +{ + // Sanity checks for the current and new channel +#if defined WLAN_VOWIFI_DEBUG + PELOGE(limLog( pMac, LOGE, "Switching channel to %d", newChannel);) +#endif + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + + pMac->lim.gpchangeChannelCallback = callback; + pMac->lim.gpchangeChannelData = cbdata; + + limSendSwitchChnlParams(pMac, newChannel, + PHY_SINGLE_CHANNEL_CENTERED, + psessionEntry->maxTxPower, psessionEntry->peSessionId); + + return; +} + + +/** + * limContinuePostChannelScan() + * + *FUNCTION: + * This function is called to scan the current channel. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ + +void limContinuePostChannelScan(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + tANI_U8 handleError = 0; + tANI_U8 i = 0; + tSirRetStatus status = eSIR_SUCCESS; + + if( pMac->lim.abortScan || (NULL == pMac->lim.gpLimMlmScanReq ) || + (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + + channelNum = limGetCurrentScanChannel(pMac); + if ((pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) && + (limActiveScanAllowed(pMac, channelNum))) + { + TX_TIMER *periodicScanTimer; + PELOG2(limLog(pMac, LOG2, FL("ACTIVE Scan chan %d, sending probe"), channelNum);) + + pMac->lim.probeCounter++; + do + { + /* Prepare and send Probe Request frame for all the SSIDs present in the saved MLM + */ + + PELOGE(limLog(pMac, LOG1, FL("sending ProbeReq number %d, for SSID %s on channel: %d"), + i, pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);) + // include additional IE if there is + status = limSendProbeReqMgmtFrame( pMac, &pMac->lim.gpLimMlmScanReq->ssId[i], + pMac->lim.gpLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr, + pMac->lim.gpLimMlmScanReq->dot11mode, + pMac->lim.gpLimMlmScanReq->uIEFieldLen, + (tANI_U8 *)(pMac->lim.gpLimMlmScanReq)+pMac->lim.gpLimMlmScanReq->uIEFieldOffset); + + if ( status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID %s on channel: %d"), + pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);) + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + i++; + } while (i < pMac->lim.gpLimMlmScanReq->numSsid); + + { +#if defined WLAN_FEATURE_VOWIFI + //If minChannelTime is set to zero, SME is requesting scan to not use min channel timer. + //This is used in 11k to request for beacon measurement request with a fixed duration in + //max channel time. + if( pMac->lim.gpLimMlmScanReq->minChannelTime != 0 ) + { +#endif + /// TXP has sent Probe Request + /// Activate minChannelTimer + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + +#ifdef GEN6_TODO + /* revisit this piece of code to assign the appropriate sessionId below + * priority - LOW/might not be needed + */ + pMac->lim.limTimers.gLimMinChannelTimer.sessionId = sessionId; +#endif + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MIN_CHANNEL_TIMER)); + + if (tx_timer_activate(&pMac->lim.limTimers.gLimMinChannelTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not start min channel timer")); + return; + } + + // Initialize max timer too + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); +#if defined WLAN_FEATURE_VOWIFI + } + else + { +#if defined WLAN_VOWIFI_DEBUG + PELOGE(limLog( pMac, LOGE, "Min channel time == 0, Use only max chan timer" );) +#endif + //No Need to start Min channel timer. Start Max Channel timer. + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, pMac->lim.limTimers.gLimMaxChannelTimer.sessionId, eLIM_MAX_CHANNEL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) + == TX_TIMER_ERROR) + { + /// Could not activate max channel timer. + // Log error + limLog(pMac,LOGP, FL("could not start max channel timer")); + return; + } + + } +#endif + } + /* Start peridic timer which will trigger probe req based on min/max + channel timer */ + periodicScanTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer; + if (tx_timer_activate(periodicScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not start periodic probe req " + "timer")); + return; + } + periodicScanTimer->sessionId = channelNum; + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, periodicScanTimer->sessionId, eLIM_PERIODIC_PROBE_REQ_TIMER)); + } + else + { + tANI_U32 val; + PELOG2(limLog(pMac, LOG2, FL("START PASSIVE Scan chan %d"), channelNum);) + + /// Passive Scanning. Activate maxChannelTimer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate max channel timer. + // Log error + limLog(pMac, LOGP, FL("Unable to deactivate max channel timer")); + return; + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + &val) != eSIR_SUCCESS) + { + /** + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve passive max channel value")); + return; + } + else + { + tANI_U32 val1 = 0; + + val = SYS_MS_TO_TICKS(val); + //Pick the longer stay time + val = (val > val1) ? val : val1; + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER)); + if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change max channel timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change max channel timer")); + return; + } + else if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not start max channel timer")); + return; + } + + } + } + // Wait for Beacons to arrive + } // if (pMac->lim.gLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) + + if( handleError ) + { + // + // FIXME - With this, LIM/SoftMAC will try and recover + // state, but eWNI_SME_SCAN_CNF maybe reporting an + // incorrect status back to the SME. Some of the possible + // errors are: + // eSIR_SME_HAL_SCAN_INIT_FAILED + // eSIR_SME_RESOURCES_UNAVAILABLE + // + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + } + else + { + limAddScanChannelInfo(pMac, channelNum); + } + + return; +} + + + + + +/* limCovertChannelScanType() + * + *FUNCTION: + * This function is called to get the list, change the channel type and set again. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: If a channel is ACTIVE, this function will make it as PASSIVE + * If a channel is PASSIVE, this fucntion will make it as ACTIVE + * NA + * + * @param pMac - Pointer to Global MAC structure + * channelNum - Channel which need to be convert + PassiveToActive - Boolean flag to convert channel + * + * @return None + */ + + +void limCovertChannelScanType(tpAniSirGlobal pMac,tANI_U8 channelNum, tANI_BOOLEAN passiveToActive) +{ + + tANI_U32 i; + tANI_U8 channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN]; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to get scan control list"));) + return ; + } + if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) + { + limLog(pMac, LOGE, FL("Invalid scan control list length:%d"), len); + return ; + } + for (i=0; (i+1) < len; i+=2) + { + if (channelPair[i] == channelNum) + { + if ((eSIR_PASSIVE_SCAN == channelPair[i+1]) && TRUE == passiveToActive) + { + PELOG1(limLog(pMac, LOG1, FL("Channel %d changed from Passive to Active"), + channelNum);) + channelPair[i+1] = eSIR_ACTIVE_SCAN; + break ; + } + if ((eSIR_ACTIVE_SCAN == channelPair[i+1]) && FALSE == passiveToActive) + { + PELOG1(limLog(pMac, LOG1, FL("Channel %d changed from Active to Passive"), + channelNum);) + channelPair[i+1] = eSIR_PASSIVE_SCAN; + break ; + } + } + } + + cfgSetStrNotify(pMac, WNI_CFG_SCAN_CONTROL_LIST, (tANI_U8 *)channelPair, len, FALSE); + return ; +} + + + + +/* limSetDFSChannelList() + * + *FUNCTION: + * This function is called to convert DFS channel list to active channel list when any + * beacon is present on that channel. This function store time for passive channels + * which help to know that for how much time channel has been passive. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: If a channel is ACTIVE, it won't store any time + * If a channel is PAssive, it will store time as timestamp + * NA + * + * @param pMac - Pointer to Global MAC structure + * dfsChannelList - DFS channel list. + * @return None + */ + +void limSetDFSChannelList(tpAniSirGlobal pMac,tANI_U8 channelNum, tSirDFSChannelList *dfsChannelList) +{ + + tANI_BOOLEAN passiveToActive = TRUE; + if ((1 <= channelNum) && (165 >= channelNum)) + { + if (eANI_BOOLEAN_TRUE == limIsconnectedOnDFSChannel(channelNum)) + { + if (dfsChannelList->timeStamp[channelNum] == 0) + { + //Received first beacon; Convert DFS channel to Active channel. + PELOG1(limLog(pMac, LOG1, FL("Received first beacon on DFS channel: %d"), channelNum);) + limCovertChannelScanType(pMac,channelNum, passiveToActive); + } + dfsChannelList->timeStamp[channelNum] = vos_timer_get_system_time(); + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Channel %d is Active"), channelNum);) + return; + } + if (!tx_timer_running(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer)) + { + tx_timer_activate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("Invalid Channel: %d"), channelNum);) + return; + } + + return; +} + + + + +/* +* Creates a Raw frame to be sent before every Scan, if required. +* If only infra link is active (mlmState = Link Estb), then send Data Null +* If only BT-AMP-AP link is active(mlmState = BSS_STARTED), then send CTS2Self frame. +* If only BT-AMP-STA link is active(mlmState = BSS_STARTED or Link Est) then send CTS2Self +* If Only IBSS link is active, then send CTS2Self +* for concurrent scenario: Infra+BT or Infra+IBSS, always send CTS2Self, no need to send Data Null +* +*/ +static void __limCreateInitScanRawFrame(tpAniSirGlobal pMac, + tpInitScanParams pInitScanParam) +{ + tANI_U8 i; + pInitScanParam->scanEntry.activeBSScnt = 0; + + /* Don't send CTS to self as we have issue with BTQM queues where BTQM can + * not handle transmition of CTS2self frames. Sending CTS 2 self at this + * juncture also doesn't serve much purpose as probe request frames go out + * immediately, No need to notify BSS in IBSS case. + * */ + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) && + (pInitScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID)) + { + pInitScanParam->scanEntry.bssIdx[pInitScanParam->scanEntry.activeBSScnt] + = pMac->lim.gpSession[i].bssIdx; + pInitScanParam->scanEntry.activeBSScnt++; + + } + } + else if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole ) + && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona ) + ) + { + pInitScanParam->useNoA = TRUE; + } + } + } + if (pInitScanParam->scanEntry.activeBSScnt) + { + pInitScanParam->notifyBss = TRUE; + pInitScanParam->frameType = SIR_MAC_DATA_FRAME; + pInitScanParam->frameLength = 0; + } +} + +/* +* Creates a Raw frame to be sent during finish scan, if required. +* Send data null frame, only when there is just one session active and that session is +* in 'link Estb' state. +* if more than one session is active, don't send any frame. +* for concurrent scenario: Infra+BT or Infra+IBSS, no need to send Data Null +* +*/ +static void __limCreateFinishScanRawFrame(tpAniSirGlobal pMac, + tpFinishScanParams pFinishScanParam) +{ + tANI_U8 i; + pFinishScanParam->scanEntry.activeBSScnt = 0; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + //BT-STA can either be in LINK-ESTB state or BSS_STARTED State + //for BT, need to send CTS2Self + if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) && + (pFinishScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID)) + { + pFinishScanParam->scanEntry.bssIdx[pFinishScanParam->scanEntry.activeBSScnt] + = pMac->lim.gpSession[i].bssIdx; + pFinishScanParam->scanEntry.activeBSScnt++; + } + } + } + } + + if (pFinishScanParam->scanEntry.activeBSScnt) + { + pFinishScanParam->notifyBss = TRUE; + pFinishScanParam->frameType = SIR_MAC_DATA_FRAME; + pFinishScanParam->frameLength = 0; + } +} + +void +limSendHalInitScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState, tSirLinkTrafficCheck trafficCheck) +{ + + + tSirMsgQ msg; + tpInitScanParams pInitScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + pInitScanParam = vos_mem_malloc(sizeof(*pInitScanParam)); + if ( NULL == pInitScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + /*Initialize the pInitScanParam with 0*/ + vos_mem_set((tANI_U8 *)pInitScanParam, sizeof(*pInitScanParam), 0); + + msg.type = WDA_INIT_SCAN_REQ; + msg.bodyptr = pInitScanParam; + msg.bodyval = 0; + + vos_mem_set((tANI_U8 *)&pInitScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr), 0); + if (nextState == eLIM_HAL_INIT_LEARN_WAIT_STATE) + { + pInitScanParam->notifyBss = TRUE; + pInitScanParam->notifyHost = FALSE; + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SCAN; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_LEARN; + } + + pInitScanParam->frameType = SIR_MAC_CTRL_CTS; + __limCreateInitScanRawFrame(pMac, pInitScanParam); + pInitScanParam->checkLinkTraffic = trafficCheck; + } + else + { + if(nextState == eLIM_HAL_SUSPEND_LINK_WAIT_STATE) + { + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SUSPEND_LINK; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK; + } + + } + else + { + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SCAN; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_SCAN; + } + } + __limCreateInitScanRawFrame(pMac, pInitScanParam); + if (pInitScanParam->useNoA) + { + pInitScanParam->scanDuration = pMac->lim.gTotalScanDuration; + } + /* Inform HAL whether it should check for traffic on the link + * prior to performing a background scan + */ + pInitScanParam->checkLinkTraffic = trafficCheck; + } + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + PELOG3(limLog(pMac, LOG3, FL("wdaPostCtrlMsg() return eSIR_SUCCESS pMac=%x nextState=%d"), + pMac, pMac->lim.gLimHalScanState);) + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pInitScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + +error: + switch(nextState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + break; + + + //WLAN_SUSPEND_LINK Related + case eLIM_HAL_SUSPEND_LINK_WAIT_STATE: + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + if( pMac->lim.gpLimSuspendCallback ) + { + pMac->lim.gpLimSuspendCallback( pMac, rc, pMac->lim.gpLimSuspendData ); + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimSuspendData = NULL; + } + pMac->lim.gLimSystemInScanLearnMode = 0; + break; + //end WLAN_SUSPEND_LINK Related + default: + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + + return ; +} + +void +limSendHalStartScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState) +{ + tSirMsgQ msg; + tpStartScanParams pStartScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + /** + * The Start scan request to be sent only if Start Scan is not already requested + */ + if(pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE) + { + + pStartScanParam = vos_mem_malloc(sizeof(*pStartScanParam)); + if ( NULL == pStartScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_START_SCAN_REQ; + msg.bodyptr = pStartScanParam; + msg.bodyval = 0; + pStartScanParam->status = eHAL_STATUS_SUCCESS; + pStartScanParam->scanChannel = (tANI_U8)channelNum; + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + limLog(pMac, LOG1, FL("Channel %d"), channelNum); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pStartScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + +error: + switch(nextState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + break; + + + default: + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Invalid state for START_SCAN_REQ message=%d"), pMac->lim.gLimHalScanState);) + } + + return; +} + +void limSendHalEndScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState) +{ + tSirMsgQ msg; + tpEndScanParams pEndScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + /** + * The End scan request to be sent only if End Scan is not already requested or + * Start scan is not already requestd. + * after finish scan rsp from firmware host is sending endscan request so adding + * check for IDLE SCAN STATE also added to avoid this issue + */ + if((pMac->lim.gLimHalScanState != eLIM_HAL_END_SCAN_WAIT_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_IDLE_SCAN_STATE) && + (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE)) + { + pEndScanParam = vos_mem_malloc(sizeof(*pEndScanParam)); + if ( NULL == pEndScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_END_SCAN_REQ; + msg.bodyptr = pEndScanParam; + msg.bodyval = 0; + pEndScanParam->status = eHAL_STATUS_SUCCESS; + pEndScanParam->scanChannel = (tANI_U8)channelNum; + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pEndScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + + error: + switch(nextState) + { + case eLIM_HAL_END_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_END_FAILED); + break; + + + default: + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg Rcvd invalid nextState %d"), nextState);) + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Invalid state for END_SCAN_REQ message=%d"), pMac->lim.gLimHalScanState);) + } + + + return; +} + +/** + * limSendHalFinishScanReq() + * + *FUNCTION: + * This function is called to finish scan/learn request.. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param nextState - this parameters determines whether this call is for scan or learn + * + * @return None + */ +void limSendHalFinishScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState) +{ + + tSirMsgQ msg; + tpFinishScanParams pFinishScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + if(pMac->lim.gLimHalScanState == nextState) + { + /* + * PE may receive multiple probe responses, while waiting for HAL to send 'FINISH_SCAN_RSP' message + * PE was sending multiple finish scan req messages to HAL + * this check will avoid that. + * If PE is already waiting for the 'finish_scan_rsp' message from HAL, it will ignore this request. + */ + PELOGW(limLog(pMac, LOGW, FL("Next Scan State is same as the current state: %d "), nextState);) + return; + } + + pFinishScanParam = vos_mem_malloc(sizeof(*pFinishScanParam)); + if ( NULL == pFinishScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_FINISH_SCAN_REQ; + msg.bodyptr = pFinishScanParam; + msg.bodyval = 0; + + peGetResumeChannel(pMac, &pFinishScanParam->currentOperChannel, &pFinishScanParam->cbState); + + vos_mem_set((tANI_U8 *)&pFinishScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr), 0); + + if (nextState == eLIM_HAL_FINISH_LEARN_WAIT_STATE) + { + //AP - No pkt need to be transmitted + pFinishScanParam->scanMode = eHAL_SYS_MODE_LEARN; + pFinishScanParam->notifyBss = FALSE; + pFinishScanParam->notifyHost = FALSE; + pFinishScanParam->frameType = 0; + + pFinishScanParam->frameLength = 0; + pMac->lim.gLimHalScanState = nextState; + } + else + { + /* If STA is associated with an AP (ie. STA is in + * LINK_ESTABLISHED state), then STA need to inform + * the AP via either DATA-NULL + */ + if (nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE) + { + pFinishScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK; + } + else + { + pFinishScanParam->scanMode = eHAL_SYS_MODE_SCAN; + } + pFinishScanParam->notifyHost = FALSE; + __limCreateFinishScanRawFrame(pMac, pFinishScanParam); + //WLAN_SUSPEND_LINK Related + pMac->lim.gLimHalScanState = nextState; + //end WLAN_SUSPEND_LINK Related + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pFinishScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + + error: + if(nextState == eLIM_HAL_FINISH_SCAN_WAIT_STATE) + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_FINISH_FAILED); + //WLAN_SUSPEND_LINK Related + else if ( nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE ) + { + if( pMac->lim.gpLimResumeCallback ) + { + pMac->lim.gpLimResumeCallback( pMac, rc, pMac->lim.gpLimResumeData ); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + } + //end WLAN_SUSPEND_LINK Related + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + return; +} + +/** + * limContinueChannelScan() + * + *FUNCTION: + * This function is called by limPerformChannelScan(). + * This function is called to continue channel scanning when + * Beacon/Probe Response frame are received. + * + *LOGIC: + * Scan criteria stored in pMac->lim.gLimMlmScanReq is used + * to perform channel scan. In this function MLM sub module + * makes channel switch, sends PROBE REQUEST frame in case of + * ACTIVE SCANNING, starts min/max channel timers, programs + * NAV to probeDelay timer and waits for Beacon/Probe Response. + * Once all required channels are scanned, LIM_MLM_SCAN_CNF + * primitive is used to send Scan results to SME sub module. + * + *ASSUMPTIONS: + * 1. In case of Active scanning, start MAX channel time iff + * MIN channel timer expired and activity is observed on + * the channel. + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limContinueChannelScan(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + + PELOG1(limLog(pMac, LOG1, FL("Continue SCAN : chan %d tot %d"), + pMac->lim.gLimCurrentScanChannelId, + pMac->lim.gpLimMlmScanReq->channelList.numChannels);) + + if (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1) + || pMac->lim.abortScan) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + + /// Done scanning all required channels + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + + /// Atleast one more channel is to be scanned + + if ((pMac->lim.gLimReturnAfterFirstMatch & 0x40) || + (pMac->lim.gLimReturnAfterFirstMatch & 0x80)) + { + while (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + if (((limGetCurrentScanChannel(pMac) <= 14) && + pMac->lim.gLim24Band11dScanDone) || + ((limGetCurrentScanChannel(pMac) > 14) && + pMac->lim.gLim50Band11dScanDone)) + { + limLog(pMac, LOGW, FL("skipping chan %d"), + limGetCurrentScanChannel(pMac)); + pMac->lim.gLimCurrentScanChannelId++; + } + else + break; + } + + if (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + /// Done scanning all required channels + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + } + + channelNum = limGetCurrentScanChannel(pMac); + PELOG2(limLog(pMac, LOG2, FL("Current Channel to be scanned is %d"), + channelNum);) + + limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_SCAN_WAIT_STATE); + return; +} /*** end limContinueChannelScan() ***/ + + + +/** + * limRestorePreScanState() + * + *FUNCTION: + * This function is called by limContinueChannelScan() + * to restore HW state prior to entering 'scan state' + * + *LOGIC + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limRestorePreScanState(tpAniSirGlobal pMac) +{ + int i; + + /// Deactivate MIN/MAX channel timers if running + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + + /* Re-activate Heartbeat timers for connected sessions as scan + * is done if the DUT is in active mode + * AND it is not a ROAMING ("background") scan */ + if(pMac->psOffloadEnabled) + { + if((pMac->lim.gLimBackgroundScanMode != eSIR_ROAMING_SCAN) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + for(i=0;ilim.maxBssId;i++) + { + tpPESession psessionEntry = peFindSessionBySessionId(pMac,i); + if(psessionEntry && psessionEntry->valid && + (eLIM_MLM_LINK_ESTABLISHED_STATE == + psessionEntry->limMlmState) && + (psessionEntry->pmmOffloadInfo.psstate == PMM_FULL_POWER)) + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + } + } + else if(((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) || + (ePMM_STATE_READY == pMac->pmm.gPmmState)) + && (pMac->lim.gLimBackgroundScanMode != eSIR_ROAMING_SCAN )) + { + for(i=0;ilim.maxBssId;i++) + { + if((peFindSessionBySessionId(pMac,i) != NULL) && + (pMac->lim.gpSession[i].valid == TRUE) && + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + limReactivateHeartBeatTimer(pMac, peFindSessionBySessionId(pMac,i)); + } + } + } + + pMac->lim.gLimSystemInScanLearnMode = 0; + PELOG1(limLog(pMac, LOG1, FL("Scan ended, took %d tu"), (tx_time_get() - pMac->lim.scanStartTime));) +} /*** limRestorePreScanState() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +void limSendHalOemDataReq(tpAniSirGlobal pMac) +{ + tSirMsgQ msg; + tpStartOemDataReq pStartOemDataReq = NULL; + tSirRetStatus rc = eSIR_SUCCESS; + tpLimMlmOemDataRsp pMlmOemDataRsp; + tANI_U32 reqLen = 0; + if(NULL == pMac->lim.gpLimMlmOemDataReq) + { + PELOGE(limLog(pMac, LOGE, FL("Null pointer"));) + goto error; + } + + reqLen = sizeof(tStartOemDataReq); + + pStartOemDataReq = vos_mem_malloc(reqLen); + if ( NULL == pStartOemDataReq ) + { + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: Could not allocate memory for pStartOemDataReq"));) + goto error; + } + + vos_mem_set((tANI_U8*)(pStartOemDataReq), reqLen, 0); + + //Now copy over the information to the OEM DATA REQ to HAL + vos_mem_copy(pStartOemDataReq->selfMacAddr, + pMac->lim.gpLimMlmOemDataReq->selfMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pStartOemDataReq->oemDataReq, + pMac->lim.gpLimMlmOemDataReq->oemDataReq, + OEM_DATA_REQ_SIZE); + + //Create the message to be passed to HAL + msg.type = WDA_START_OEM_DATA_REQ; + msg.bodyptr = pStartOemDataReq; + msg.bodyval = 0; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if(rc == eSIR_SUCCESS) + { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pStartOemDataReq); + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: posting WDA_START_OEM_DATA_REQ to HAL failed"));) + +error: + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( NULL == pMlmOemDataRsp ) + { + limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure")); + return; + } + + if(NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + + return; +} +/** + * limSetOemDataReqModeFailed() + * + * FUNCTION: + * This function is used as callback to resume link after the suspend fails while + * starting oem data req mode. + * LOGIC: + * NA + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limSetOemDataReqModeFailed(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data) +{ + tpLimMlmOemDataRsp pMlmOemDataRsp; + + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( NULL == pMlmOemDataRsp ) + { + limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure")); + return; + } + + if (NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + vos_mem_set(pMlmOemDataRsp, sizeof(tLimMlmOemDataRsp), 0); + + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + + return; +} + +/** + * limSetOemDataReqMode() + * + *FUNCTION: + * This function is called to setup system into OEM DATA REQ mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limSetOemDataReqMode(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data) +{ + if(status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("OEM_DATA: failed in suspend link")); + goto error; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: Calling limSendHalOemDataReq"));) + limSendHalOemDataReq(pMac); + return; + } + +error: + limResumeLink(pMac, limSetOemDataReqModeFailed, NULL); + return ; +} /*** end limSendHalOemDataReq() ***/ + +#endif //FEATURE_OEM_DATA_SUPPORT + +static void +mlm_add_sta( + tpAniSirGlobal pMac, + tpAddStaParams pSta, + tANI_U8 *pBssid, + tANI_U8 htCapable, + tpPESession psessionEntry) //psessionEntry may required in future +{ + tANI_U32 val; + int i; + tANI_U32 selfStaDot11Mode = 0; + + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); + pSta->staType = STA_ENTRY_SELF; // Identifying self + + vos_mem_copy(pSta->bssId, pBssid, sizeof( tSirMacAddr )); + vos_mem_copy(pSta->staMac, psessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + /* Configuration related parameters to be changed to support BT-AMP */ + + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_LISTEN_INTERVAL, &val )) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + + pSta->listenInterval = (tANI_U16) val; + + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) ) + limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE")); + pSta->shortPreambleSupported = (tANI_U8)val; + + pSta->assocId = 0; // Is SMAC OK with this? + pSta->wmmEnabled = 0; + pSta->uAPSD = 0; + pSta->maxSPLen = 0; + pSta->us32MaxAmpduDuration = 0; + pSta->maxAmpduSize = 0; // 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k + + + /* For Self STA get the LDPC capability from config.ini*/ + pSta->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pSta->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + pSta->htCapable = htCapable; + pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry ); + pSta->mimoPS = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pSta->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pSta->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pSta->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pSta->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + pSta->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry); + pSta->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry); + } +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability) + { + pSta->vhtCapable = VOS_TRUE; + pSta->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled; + pSta->vhtTxMUBformeeCapable = psessionEntry->txMuBformee; + } + + // Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE capabilities + if( IS_DOT11_MODE_VHT(selfStaDot11Mode) ) + { + val = 0; // Default 8K AMPDU size + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &val )) + limLog(pMac, LOGE, FL("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT")); + pSta->maxAmpduSize = (tANI_U8) val; + } + pSta->enableVhtpAid = psessionEntry->enableVhtpAid; +#endif + pSta->enableAmpduPs = psessionEntry->enableAmpduPs; + pSta->enableHtSmps = psessionEntry->enableHtSmps; + pSta->htSmpsconfig = psessionEntry->htSmpsvalue; + +#ifdef WLAN_FEATURE_11AC + limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry,NULL); +#else + limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry); +#endif + limFillSupportedRatesInfo(pMac, NULL, &pSta->supportedRates,psessionEntry); + + limLog( pMac, LOGE, FL( "GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d, SGI20: %d, SGI40%d") , + pSta->greenFieldCapable, pSta->txChannelWidthSet, pSta->mimoPS, pSta->lsigTxopProtection, + pSta->fDsssCckMode40Mhz,pSta->fShortGI20Mhz, pSta->fShortGI40Mhz); + + if (VOS_P2P_GO_MODE == psessionEntry->pePersona) + { + pSta->p2pCapableSta = 1; + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pSta->staTCParams[i].txUseBA = eBA_DISABLE; + pSta->staTCParams[i].rxUseBA = eBA_DISABLE; + } + +} + +// +// New HAL interface - WDA_ADD_BSS_REQ +// Package WDA_ADD_BSS_REQ to HAL, in order to start a BSS +// +tSirResultCodes +limMlmAddBss ( + tpAniSirGlobal pMac, + tLimMlmStartReq *pMlmStartReq, + tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + + // Package WDA_ADD_BSS_REQ message parameters + + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if ( NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Unable to allocate memory during ADD_BSS" )); + // Respond to SME with LIM_MLM_START_CNF + return eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + + vos_mem_set(pAddBssParams, sizeof(tAddBssParams), 0); + + // Fill in tAddBssParams members + vos_mem_copy(pAddBssParams->bssId, pMlmStartReq->bssId, + sizeof( tSirMacAddr )); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy (pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof( tSirMacAddr )); + + pAddBssParams->bssType = pMlmStartReq->bssType; + if ((pMlmStartReq->bssType == eSIR_IBSS_MODE) || + (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE)|| + (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE)) { + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + } + else if (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE){ + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_AP; + } + + pAddBssParams->shortSlotTimeSupported = psessionEntry->shortSlotTimeSupported; + + pAddBssParams->beaconInterval = pMlmStartReq->beaconPeriod; + pAddBssParams->dtimPeriod = pMlmStartReq->dtimPeriod; + pAddBssParams->cfParamSet.cfpCount = pMlmStartReq->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pMlmStartReq->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pMlmStartReq->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pMlmStartReq->cfParamSet.cfpDurRemaining; + + pAddBssParams->rateSet.numRates = pMlmStartReq->rateSet.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pMlmStartReq->rateSet.rate, pMlmStartReq->rateSet.numRates); + + pAddBssParams->nwType = pMlmStartReq->nwType; + + pAddBssParams->htCapable = pMlmStartReq->htCapable; +#ifdef WLAN_FEATURE_11AC + pAddBssParams->vhtCapable = psessionEntry->vhtCapability; + pAddBssParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; +#endif + pAddBssParams->htOperMode = pMlmStartReq->htOperMode; + pAddBssParams->dualCTSProtection = pMlmStartReq->dualCTSProtection; + pAddBssParams->txChannelWidthSet = pMlmStartReq->txChannelWidthSet; + + pAddBssParams->currentOperChannel = pMlmStartReq->channelNumber; + pAddBssParams->currentExtChannel = pMlmStartReq->cbMode; + +#ifdef WLAN_FEATURE_11W + pAddBssParams->rmfEnabled = psessionEntry->limRmfEnabled; +#endif + + /* Update PE sessionId*/ + pAddBssParams->sessionId = pMlmStartReq->sessionId; + + //Send the SSID to HAL to enable SSID matching for IBSS + vos_mem_copy(&(pAddBssParams->ssId.ssId), + pMlmStartReq->ssId.ssId, + pMlmStartReq->ssId.length); + pAddBssParams->ssId.length = pMlmStartReq->ssId.length; + pAddBssParams->bHiddenSSIDEn = pMlmStartReq->ssidHidden; + limLog( pMac, LOGE, FL( "TRYING TO HIDE SSID %d" ),pAddBssParams->bHiddenSSIDEn); + // CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed. + pAddBssParams->bProxyProbeRespEn = 0; + pAddBssParams->obssProtEnabled = pMlmStartReq->obssProtEnabled; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; +#endif + mlm_add_sta(pMac, &pAddBssParams->staContext, + pAddBssParams->bssId, pAddBssParams->htCapable,psessionEntry); + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = 1; + + // Set a new state for MLME + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + pAddBssParams->halPersona=psessionEntry->pePersona; //pass on the session persona to hal + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled || + limIsconnectedOnDFSChannel(pMlmStartReq->channelNumber); + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; +#endif + + pAddBssParams->dot11_mode = psessionEntry->dot11mode; + limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode); + + msgQ.type = WDA_ADD_BSS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + limLog( pMac, LOGW, FL( "Sending WDA_ADD_BSS_REQ..." )); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pAddBssParams); + return eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + + return eSIR_SME_SUCCESS; +} + + +/** + * limProcessMlmStartReq() + * + *FUNCTION: + * This function is called to process MLM_START_REQ message + * from SME + * + *LOGIC: + * 1) MLME receives LIM_MLM_START_REQ from LIM + * 2) MLME sends WDA_ADD_BSS_REQ to HAL + * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE + * MLME now waits for HAL to send WDA_ADD_BSS_RSP + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmStartReq *pMlmStartReq; + tLimMlmStartCnf mlmStartCnf; + tpPESession psessionEntry = NULL; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmStartReq = (tLimMlmStartReq *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmStartReq->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + mlmStartCnf.resultCode = eSIR_SME_REFUSED; + goto end; + } + + if (psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE) + { + /** + * Should not have received Start req in states other than idle. + * Return Start confirm with failure code. + */ + PELOGE(limLog(pMac, LOGE, FL("received unexpected MLM_START_REQ in state %X"),psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + goto end; + } + mlmStartCnf.resultCode = limMlmAddBss(pMac, pMlmStartReq,psessionEntry); + +end: + /* Update PE session Id */ + mlmStartCnf.sessionId = pMlmStartReq->sessionId; + + /// Free up buffer allocated for LimMlmScanReq + vos_mem_free(pMsgBuf); + + // + // Respond immediately to LIM, only if MLME has not been + // successfully able to send WDA_ADD_BSS_REQ to HAL. + // Else, LIM_MLM_START_CNF will be sent after receiving + // WDA_ADD_BSS_RSP from HAL + // + if( eSIR_SME_SUCCESS != mlmStartCnf.resultCode ) + limPostSmeMessage(pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf); +} /*** limProcessMlmStartReq() ***/ + + +/* +* This function checks if Scan is allowed or not. +* It checks each session and if any session is not in the normal state, +* it will return false. +* Note: BTAMP_STA can be in LINK_EST as well as BSS_STARTED State, so +* both cases are handled below. +*/ + +static tANI_U8 __limMlmScanAllowed(tpAniSirGlobal pMac) +{ + int i; + + if(pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE) + { + return FALSE; + } + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )|| + + ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) ) + || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE) + && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) ) + || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ) + && (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) ) + )) + { + return FALSE; + + } + } + } + + return TRUE; +} + + + +/** + * limProcessMlmScanReq() + * + *FUNCTION: + * This function is called to process MLM_SCAN_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmScanCnf mlmScanCnf; + tANI_U8 i = 0; + tANI_U32 val = 0; + + if (pMac->lim.gLimSystemInScanLearnMode) + { + PELOGE(limLog(pMac, LOGE, + FL("Sending START_SCAN from LIM while one req is pending"));) + vos_mem_free(pMsgBuf); + /*Send back a failure*/ + mlmScanCnf.resultCode = eSIR_SME_SCAN_FAILED; + mlmScanCnf.scanResultLength = 0; + limPostSmeMessage(pMac, + LIM_MLM_SCAN_CNF, + (tANI_U32 *) &mlmScanCnf); + return; + } + + if(__limMlmScanAllowed(pMac) && + (((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels != 0)) + + { + /// Hold onto SCAN REQ criteria + pMac->lim.gpLimMlmScanReq = (tLimMlmScanReq *) pMsgBuf; + + PELOG3(limLog(pMac, LOG3, FL("Number of channels to scan are %d "), + pMac->lim.gpLimMlmScanReq->channelList.numChannels);) + + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + + if (pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) + pMac->lim.gLimMlmState = eLIM_MLM_WT_PROBE_RESP_STATE; + else + pMac->lim.gLimMlmState = eLIM_MLM_PASSIVE_SCAN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMac->lim.gLimSystemInScanLearnMode = 1; + + /* temporary fix to handle case where NOA duration calculation is incorrect + * for scanning on DFS channels */ + + pMac->lim.gTotalScanDuration = 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve passive max channel value")); + + /* use a default value of 110ms */ + val = 110; + } + + for (i = 0; i < pMac->lim.gpLimMlmScanReq->channelList.numChannels; i++) { + tANI_U8 channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[i]; + + if (limActiveScanAllowed(pMac, channelNum)) { + /* Use min + max channel time to calculate the total duration of scan */ + pMac->lim.gTotalScanDuration += pMac->lim.gpLimMlmScanReq->minChannelTime + pMac->lim.gpLimMlmScanReq->maxChannelTime; + } else { + /* using the value from WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME as is done in + * void limContinuePostChannelScan(tpAniSirGlobal pMac) + */ + pMac->lim.gTotalScanDuration += val; + } + } + + /* Adding an overhead of 5ms to account for the scan messaging delays */ + pMac->lim.gTotalScanDuration += 5; + limSetScanMode(pMac); + } + else + { + /** + * Should not have received SCAN req in other states + * OR should not have received LIM_MLM_SCAN_REQ with + * zero number of channels + * Log error + */ + limLog(pMac, LOGW, + FL("received unexpected MLM_SCAN_REQ in state %X OR zero number of channels: %X"), + pMac->lim.gLimMlmState, ((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + + vos_mem_free(pMsgBuf); + + /// Return Scan confirm with INVALID_PARAMETERS + + mlmScanCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmScanCnf.scanResultLength = 0; + limPostSmeMessage(pMac, + LIM_MLM_SCAN_CNF, + (tANI_U32 *) &mlmScanCnf); + } +} /*** limProcessMlmScanReq() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT +static void limProcessMlmOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmOemDataRsp* pMlmOemDataRsp; + + if (((pMac->lim.gLimMlmState == eLIM_MLM_IDLE_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_JOINED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_AUTHENTICATED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_BSS_STARTED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))) + { + //Hold onto the oem data request criteria + + /* + * Free gpLimMlmOemDataReq to avoid memory leak due to + * second OEM data request + */ + if (pMac->lim.gpLimMlmOemDataReq) { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + pMac->lim.gpLimMlmOemDataReq = (tLimMlmOemDataReq*)pMsgBuf; + + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + + PELOG2(limLog(pMac, LOG2, + FL("%s: Calling limSendHalOemDataReq"), __func__);) + limSendHalOemDataReq(pMac); + } + else + { + /** + * Should not have received oem data req in other states + * Log error + */ + + PELOGW(limLog(pMac, LOGW, FL("OEM_DATA: unexpected LIM_MLM_OEM_DATA_REQ in invalid state %X"),pMac->lim.gLimMlmState);) + + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + + /// Free up buffer allocated + vos_mem_free(pMsgBuf); + + /// Return Meas confirm with INVALID_PARAMETERS + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( pMlmOemDataRsp != NULL) + { + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + vos_mem_free(pMlmOemDataRsp); + } + else + { + limLog(pMac, LOGP, FL("Could not allocate memory for pMlmOemDataRsp")); + return; + } + } + + return; +} +#endif //FEATURE_OEM_DATA_SUPPORT + +/** + * lim_post_join_set_link_state_callback()- registered callback to perform post + * peer creation operations + * + * @mac: pointer to global mac structure + * @callback_arg: registered callback argument + * @status: peer creation status + * + * this is registered callback function during association to perform + * post peer creation operation based on the peer creation status + * + * Return: none + */ +void lim_post_join_set_link_state_callback(tpAniSirGlobal mac, + void *callback_arg, bool status) +{ + uint8_t chan_num, sec_chan_offset; + tpPESession session_entry = (tpPESession) callback_arg; + tLimMlmJoinCnf mlm_join_cnf; + + limLog(mac, LOG1, FL("Sessionid %d set link state(%d) cb status:%d"), + session_entry->peSessionId, session_entry->limMlmState, + status); + + if (!status) { + limLog(mac, LOGE, FL("failed to find pe session for session id:%d"), + session_entry->peSessionId); + goto failure; + } + + if (session_entry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) { + chan_num = session_entry->currentOperChannel; + sec_chan_offset = session_entry->htSecondaryChannelOffset; + /* + * store the channel switch sessionEntry in the lim + * global variable + */ + session_entry->channelChangeReasonCode = + LIM_SWITCH_CHANNEL_JOIN; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + session_entry->pLimMlmReassocRetryReq = NULL; +#endif + limLog(mac, LOG1, FL("[limProcessMlmJoinReq]: suspend link on sessionid: %d setting channel to: %d with secChanOffset:%d and maxtxPower: %d"), + session_entry->peSessionId, chan_num, + sec_chan_offset, + session_entry->maxTxPower); + limSetChannel(mac, chan_num, sec_chan_offset, + session_entry->maxTxPower, + session_entry->peSessionId); + return; + } + +failure: + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId, + session_entry->limMlmState)); + session_entry->limMlmState = eLIM_MLM_IDLE_STATE; + mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlm_join_cnf.sessionId = session_entry->peSessionId; + mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(mac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlm_join_cnf); +} + +/** + * limProcessMlmPostJoinSuspendLink() + * + *FUNCTION: + * This function is called after the suspend link while joining + * off channel. + * + *LOGIC: + * Check for suspend state. + * If success, proceed with setting link state to recieve the + * probe response/beacon from intended AP. + * Switch to the APs channel. + * On an error case, send the MLM_JOIN_CNF with error status. + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param status status of suspend link. + * @param ctx passed while calling suspend link(psessionEntry) + * @return None + */ +static void +limProcessMlmPostJoinSuspendLink(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *ctx) +{ + tLimMlmJoinCnf mlmJoinCnf; + tpPESession psessionEntry = (tpPESession)ctx; + tSirLinkState linkState; + + if( eHAL_STATUS_SUCCESS != status ) + { + limLog(pMac, LOGE, FL("Sessionid %d Suspend link(NOTIFY_BSS) failed. " + "still proceeding with join"),psessionEntry->peSessionId); + } + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG1, FL("Sessionid %d prev lim state %d new lim state %d " + "systemrole = %d"), psessionEntry->peSessionId, + psessionEntry->limPrevMlmState, + psessionEntry->limMlmState,psessionEntry->limSystemRole); + + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimJoinFailureTimer.sessionId = psessionEntry->peSessionId; + + linkState = ((psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ? eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE); + limLog(pMac, LOG1, FL("[limProcessMlmJoinReq]: linkState:%d"),linkState); + + if (limSetLinkState(pMac, linkState, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, + psessionEntry->selfMacAddr, lim_post_join_set_link_state_callback, + psessionEntry) != eSIR_SUCCESS ) + { + limLog(pMac, LOGE, + FL("SessionId:%d limSetLinkState to eSIR_LINK_PREASSOC_STATE Failed!!"), + psessionEntry->peSessionId); + limPrintMacAddr(pMac, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId,LOGE); + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + goto error; + } + + return; +error: + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); +} + +/** + * limProcessMlmJoinReq() + * + *FUNCTION: + * This function is called to process MLM_JOIN_REQ message + * from SME + * + *LOGIC: + * 1) Initialize LIM, HAL, DPH + * 2) Configure the BSS for which the JOIN REQ was received + * a) Send WDA_ADD_BSS_REQ to HAL - + * This will identify the BSS that we are interested in + * --AND-- + * Add a STA entry for the AP (in a STA context) + * b) Wait for WDA_ADD_BSS_RSP + * c) Send WDA_ADD_STA_REQ to HAL + * This will add the "local STA" entry to the STA table + * 3) Continue as before, i.e, + * a) Send a PROBE REQ + * b) Wait for PROBE RSP/BEACON containing the SSID that + * we are interested in + * c) Then start an AUTH seq + * d) Followed by the ASSOC seq + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmJoinCnf mlmJoinCnf; + tANI_U8 sessionId; + tpPESession psessionEntry; + + sessionId = ((tpLimMlmJoinReq)pMsgBuf)->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac,sessionId))== NULL) + { + limLog(pMac, LOGE, FL("SessionId:%d session does not exist"),sessionId); + goto error; + } + + if (( (psessionEntry->limSystemRole != eLIM_AP_ROLE ) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE )) && + ( (psessionEntry->limMlmState == eLIM_MLM_IDLE_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE)) && + (SIR_MAC_GET_ESS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo) != + SIR_MAC_GET_IBSS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo))) + { + /// Hold onto Join request parameters + + psessionEntry->pLimMlmJoinReq =(tpLimMlmJoinReq) pMsgBuf; + + if( isLimSessionOffChannel(pMac, sessionId) ) + { + limLog(pMac,LOG1,"SessionId:%d LimSession is on OffChannel", + sessionId); + //suspend link + limLog(pMac, LOG1, FL("Suspend link as LimSession on sessionid %d" + "is off channel"),sessionId); + limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, + limProcessMlmPostJoinSuspendLink, (tANI_U32*)psessionEntry ); + } + else + { + limLog(pMac, LOG1, FL("No need to Suspend link as LimSession on " + "sessionid %d is not off channel, calling " + "limProcessMlmPostJoinSuspendLink with status as SUCCESS"), + sessionId); + //No need to suspend link. + limLog(pMac,LOG1,"SessionId:%d Join request on current channel", + sessionId); + limProcessMlmPostJoinSuspendLink( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) psessionEntry ); + } + + return; + } + else + { + /** + * Should not have received JOIN req in states other than + * Idle state or on AP. + * Return join confirm with invalid parameters code. + */ + PELOGE(limLog(pMac, LOGE, + FL("Unexpected Join request for role %d state %X"), + psessionEntry->limSystemRole, + psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + limLog(pMac, LOGE, + FL("SessionId:%d Unexpected Join request for role %d state %X "), + psessionEntry->peSessionId,psessionEntry->limSystemRole, + psessionEntry->limMlmState); + } + +error: + + + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.sessionId = sessionId; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); + + +} /*** limProcessMlmJoinReq() ***/ + + + +/** + * limProcessMlmAuthReq() + * + *FUNCTION: + * This function is called to process MLM_AUTH_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 numPreAuthContexts; + tSirMacAddr currentBssId; + tSirMacAuthFrameBody authFrameBody; + tLimMlmAuthCnf mlmAuthCnf; + struct tLimPreAuthNode *preAuthNode; + tpDphHashNode pStaDs; + tANI_U8 sessionId; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMac->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) pMsgBuf; + sessionId = pMac->lim.gpLimMlmAuthReq->sessionId; + if((psessionEntry= peFindSessionBySessionId(pMac,sessionId) )== NULL) + { + limLog(pMac, LOGP, FL("SessionId:%d Session Does not exist"), + sessionId); + return; + } + + limLog(pMac, LOG1,FL("Process Auth Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR" with authtype %d"), sessionId, + psessionEntry->limSystemRole,psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMac->lim.gpLimMlmAuthReq->peerMacAddr), + pMac->lim.gpLimMlmAuthReq->authType); + + + /** + * Expect Auth request only when: + * 1. STA joined/associated with a BSS or + * 2. STA is in IBSS mode + * and STA is going to authenticate with a unicast + * adress and requested authentication algorithm is + * supported. + */ + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if (((((psessionEntry->limSystemRole== eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + ((psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) || + (psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE))) || + ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))) && + (limIsGroupAddr(pMac->lim.gpLimMlmAuthReq->peerMacAddr) + == false) && + (limIsAuthAlgoSupported( + pMac, + pMac->lim.gpLimMlmAuthReq->authType, + psessionEntry) == true) + ) + { + /** + * This is a request for pre-authentication. + * Check if there exists context already for + * the requested peer OR + * if this request is for the AP we're currently + * associated with. + * If yes, return auth confirm immediately when + * requested auth type is same as the one used before. + */ + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) != NULL) && + (pMac->lim.gpLimMlmAuthReq->authType == + pStaDs->mlmStaContext.authType)) && + (vos_mem_compare(pMac->lim.gpLimMlmAuthReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) )) || + (((preAuthNode = + limSearchPreAuthList( + pMac, + pMac->lim.gpLimMlmAuthReq->peerMacAddr)) != NULL) && + (preAuthNode->authType == + pMac->lim.gpLimMlmAuthReq->authType))) + { + limLog(pMac, LOG2, + FL("Already have pre-auth context with peer: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMac->lim.gpLimMlmAuthReq->peerMacAddr)); + + mlmAuthCnf.resultCode = (tSirResultCodes) + eSIR_MAC_SUCCESS_STATUS; + + + goto end; + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + (tANI_U32 *) &numPreAuthContexts) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Could not retrieve NumPreAuthLimit from CFG")); + } + + if (pMac->lim.gLimNumPreAuthContexts == numPreAuthContexts) + { + PELOGW(limLog(pMac, LOGW, + FL("Number of pre-auth reached max limit"));) + + /// Return Auth confirm with reject code + mlmAuthCnf.resultCode = + eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED; + + goto end; + } + } + + // Delete pre-auth node if exists + if (preAuthNode) + limDeletePreAuthNode(pMac, + pMac->lim.gpLimMlmAuthReq->peerMacAddr); + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + /// Prepare & send Authentication frame + authFrameBody.authAlgoNumber = + (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType; + authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrameBody.authStatusCode = 0; + limSendAuthMgmtFrame(pMac, + &authFrameBody, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + LIM_NO_WEP_IN_FC,psessionEntry); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimAuthFailureTimer.sessionId = sessionId; + + // Activate Auth failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_AUTH_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer) + != TX_SUCCESS) + { + /// Could not start Auth failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Auth failure timer")); + // Cleanup as if auth timer expired + limProcessAuthFailureTimeout(pMac); + } + + return; + } + else + { + /** + * Unexpected auth request. + * Return Auth confirm with Invalid parameters code. + */ + mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + +end: + vos_mem_copy((tANI_U8 *) &mlmAuthCnf.peerMacAddr, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + + mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType; + mlmAuthCnf.sessionId = sessionId; + + vos_mem_free( pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + limLog(pMac,LOG1,"SessionId:%d LimPostSme LIM_MLM_AUTH_CNF ", + sessionId); + limPostSmeMessage(pMac, LIM_MLM_AUTH_CNF, (tANI_U32 *) &mlmAuthCnf); +} /*** limProcessMlmAuthReq() ***/ + + + +/** + * limProcessMlmAssocReq() + * + *FUNCTION: + * This function is called to process MLM_ASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmAssocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMacAddr currentBssId; + tLimMlmAssocReq *pMlmAssocReq; + tLimMlmAssocCnf mlmAssocCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmAssocReq = (tLimMlmAssocReq *) pMsgBuf; + + if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmAssocReq->sessionId) )== NULL) + { + limLog(pMac, LOGP,FL("SessionId:%d Session Does not exist"), + pMlmAssocReq->sessionId); + vos_mem_free(pMlmAssocReq); + return; + } + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if ( (psessionEntry->limSystemRole != eLIM_AP_ROLE && psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) && + (vos_mem_compare(pMlmAssocReq->peerMacAddr, currentBssId, sizeof(tSirMacAddr))) ) + { + + /// map the session entry pointer to the AssocFailureTimer + pMac->lim.limTimers.gLimAssocFailureTimer.sessionId = pMlmAssocReq->sessionId; + +#ifdef WLAN_FEATURE_11W + /* + * Store current MLM state in case ASSOC response returns with + * TRY_AGAIN_LATER return code. + */ + if (psessionEntry->limRmfEnabled) { + psessionEntry->pmfComebackTimerInfo.limPrevMlmState = + psessionEntry->limPrevMlmState; + psessionEntry->pmfComebackTimerInfo.limMlmState = + psessionEntry->limMlmState; + } +#endif /* WLAN_FEATURE_11W */ + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog(pMac,LOG1,"SessionId:%d Sending Assoc_Req Frame", + psessionEntry->peSessionId); + + /// Prepare and send Association request frame + limSendAssocReqMgmtFrame(pMac, pMlmAssocReq,psessionEntry); + + //Set the link state to postAssoc, so HW can start receiving frames from AP. + if ((psessionEntry->bssType == eSIR_BTAMP_STA_MODE)|| + ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))) + { + if(limSetLinkState(pMac, eSIR_LINK_BTAMP_POSTASSOC_STATE, currentBssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState"));) + } + /// Start association failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimAssocFailureTimer) + != TX_SUCCESS) + { + /// Could not start Assoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("SessionId:%d could not start Association failure timer"), + psessionEntry->peSessionId); + // Cleanup as if assoc timer expired + limProcessAssocFailureTimeout(pMac,LIM_ASSOC ); + + } + + return; + } + else + { + /** + * Received Association request either in invalid state + * or to a peer MAC entity whose address is different + * from one that STA is currently joined with or on AP. + * Return Assoc confirm with Invalid parameters code. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= " + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pMlmAssocReq->peerMacAddr));) + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + mlmAssocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + +end: + /* Update PE session Id*/ + mlmAssocCnf.sessionId = pMlmAssocReq->sessionId; + + /// Free up buffer allocated for assocReq + vos_mem_free(pMlmAssocReq); + + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); +} /*** limProcessMlmAssocReq() ***/ + + + +/** + * limProcessMlmReassocReq() + * + *FUNCTION: + * This function is called to process MLM_REASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U8 chanNum, secChannelOffset; + struct tLimPreAuthNode *pAuthNode; + tLimMlmReassocReq *pMlmReassocReq; + tLimMlmReassocCnf mlmReassocCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmReassocReq = (tLimMlmReassocReq *) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmReassocReq->sessionId)) == NULL) + { + limLog(pMac, LOGE,FL("Session Does not exist for given sessionId %d"), + pMlmReassocReq->sessionId); + vos_mem_free(pMlmReassocReq); + return; + } + + limLog(pMac, LOG1,FL("Process ReAssoc Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmReassocReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmReassocReq->peerMacAddr)); + + if (((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + if (psessionEntry->pLimMlmReassocReq) + vos_mem_free(psessionEntry->pLimMlmReassocReq); + + /* Hold Re-Assoc request as part of Session, knock-out pMac */ + /// Hold onto Reassoc request parameters + psessionEntry->pLimMlmReassocReq = pMlmReassocReq; + + // See if we have pre-auth context with new AP + pAuthNode = limSearchPreAuthList(pMac, psessionEntry->limReAssocbssId); + + if (!pAuthNode && + (!vos_mem_compare(pMlmReassocReq->peerMacAddr, + psessionEntry->bssId, + sizeof(tSirMacAddr)) )) + { + // Either pre-auth context does not exist AND + // we are not reassociating with currently + // associated AP. + // Return Reassoc confirm with not authenticated + mlmReassocCnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + + //assign the sessionId to the timer object + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = pMlmReassocReq->sessionId; + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + /** + * Derive channel from BSS description and + * store it at CFG. + */ + + chanNum = psessionEntry->limReassocChannelId; + secChannelOffset = psessionEntry->reAssocHtSecondaryChannelOffset; + + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + + //store the channel switch sessionEntry in the lim global var + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_REASSOC; + + /** Switch channel to the new Operating channel for Reassoc*/ + limSetChannel(pMac, chanNum, secChannelOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); + + return; + } + else + { + /** + * Received Reassoc request in invalid state or + * in AP role.Return Reassoc confirm with Invalid + * parameters code. + */ + + // Log error + limLog(pMac, LOGW, + FL("received unexpected MLM_REASSOC_CNF in state %X for role=%d, " + "MAC addr= " + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pMlmReassocReq->peerMacAddr)); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + mlmReassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + +end: + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = pMlmReassocReq->sessionId; + /// Free up buffer allocated for reassocReq + vos_mem_free(pMlmReassocReq); + psessionEntry->pLimReAssocReq = NULL; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} /*** limProcessMlmReassocReq() ***/ + + +static void +limProcessMlmDisassocReqNtf(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirMacAddr currentBssId; + tpDphHashNode pStaDs; + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDisassocCnf mlmDisassocCnf; + tpPESession psessionEntry; + extern tANI_BOOLEAN sendDisassocFrame; + + if(eHAL_STATUS_SUCCESS != suspendStatus) + { + PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X"), suspendStatus);) + } + + pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf; + + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL) + { + + limLog(pMac, LOGE, + FL("session does not exist for given sessionId %d"), + pMlmDisassocReq->sessionId); + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + limLog(pMac, LOG1,FL("Process DisAssoc Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmDisassocReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + if ( !vos_mem_compare(pMlmDisassocReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) ) + { + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DISASSOC_REQ with invalid BSS id "));) + limPrintMacAddr(pMac, pMlmDisassocReq->peerMacAddr, LOGW); + + /// Prepare and Send LIM_MLM_DISASSOC_CNF + + mlmDisassocCnf.resultCode = + eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + + break; + + default: // eLIM_AP_ROLE + + // Fall through + break; + + } // end switch (psessionEntry->limSystemRole) + + /** + * Check if there exists a context for the peer entity + * to be disassociated with. + */ + pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if ((pStaDs == NULL) || + (pStaDs && + ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_ASSOCIATED_STATE)))) + { + /** + * Received LIM_MLM_DISASSOC_REQ for STA that does not + * have context or in some transit state. + * Log error + */ + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DISASSOC_REQ for STA that either has no context " + "or in some transit state, Addr= " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));) + + /// Prepare and Send LIM_MLM_DISASSOC_CNF + + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) + pMlmDisassocReq->reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = pMlmDisassocReq->disassocTrigger; + + /// Send Disassociate frame to peer entity + if (sendDisassocFrame && (pMlmDisassocReq->reasonCode != eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) + { + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = pMlmDisassocReq; + /* Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE + * This is to address the issue of race condition between + * disconnect request from the HDD and deauth from AP + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + /* If the reason for disassociation is inactivity of STA, then + dont wait for acknowledgement */ + if ((pMlmDisassocReq->reasonCode == eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON) && + (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + + limSendDisassocMgmtFrame(pMac, + pMlmDisassocReq->reasonCode, + pMlmDisassocReq->peerMacAddr, + psessionEntry, FALSE); + + /* Send Disassoc CNF and receive path cleanup */ + limSendDisassocCnf(pMac); + } + else + { + limSendDisassocMgmtFrame(pMac, + pMlmDisassocReq->reasonCode, + pMlmDisassocReq->peerMacAddr, + psessionEntry, TRUE); + /* + * Abort Tx so that data frames won't be sent to the AP + * after sending Disassoc. + */ + if (eLIM_STA_ROLE == psessionEntry->limSystemRole) + WDA_TxAbort(psessionEntry->smeSessionId); + } + } + else + { + /* Disassoc frame is not sent OTA */ + sendDisassocFrame = 1; + // Receive path cleanup with dummy packet + if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs,psessionEntry)) + { + mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + // Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + } + + return; + +end: + vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.aid = pMlmDisassocReq->aid; + mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger; + + /* Update PE session ID*/ + mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId; + + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); +} + +tANI_BOOLEAN limCheckDisassocDeauthAckPending(tpAniSirGlobal pMac, + tANI_U8 *staMac + ) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDeauthReq *pMlmDeauthReq; + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if ( + (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + || + (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + ) + { + PELOG1(limLog(pMac, LOG1, FL("Disassoc/Deauth ack pending"));) + return eANI_BOOLEAN_TRUE; + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Disassoc/Deauth Ack not pending"));) + return eANI_BOOLEAN_FALSE; + } +} + +void limCleanUpDisassocDeauthReq(tpAniSirGlobal pMac, + tANI_U8 *staMac, + tANI_BOOLEAN cleanRxPath) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDeauthReq *pMlmDeauthReq; + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + if (cleanRxPath) + { + limProcessDisassocAckTimeout(pMac); + } + else + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + } + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + } + } + + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + if (cleanRxPath) + { + limProcessDeauthAckTimeout(pMac); + } + else + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + } + vos_mem_free(pMlmDeauthReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; + } + } +} + +void limProcessDisassocAckTimeout(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("")); + limSendDisassocCnf(pMac); +} + +/** + * limProcessMlmDisassocReq() + * + *FUNCTION: + * This function is called to process MLM_DISASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf; + limLog(pMac, LOG1,FL("Process DisAssoc Req on sessionID %d " + "from: "MAC_ADDRESS_STR), pMlmDisassocReq->sessionId, + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given sessionId %d"), + pMlmDisassocReq->sessionId); + return; + } + + limProcessMlmDisassocReqNtf( pMac, eHAL_STATUS_SUCCESS, (tANI_U32*) pMsgBuf ); + +} /*** limProcessMlmDisassocReq() ***/ + +static void +limProcessMlmDeauthReqNtf(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirMacAddr currentBssId; + tpDphHashNode pStaDs; + struct tLimPreAuthNode *pAuthNode; + tLimMlmDeauthReq *pMlmDeauthReq; + tLimMlmDeauthCnf mlmDeauthCnf; + tpPESession psessionEntry; + + + if(eHAL_STATUS_SUCCESS != suspendStatus) + { + PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X"), suspendStatus);) + } + + pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given sessionId %d"), + pMlmDeauthReq->sessionId); + vos_mem_free(pMlmDeauthReq); + return; + } + limLog(pMac, LOG1,FL("Process Deauth Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmDeauthReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr)); + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_IDLE_STATE: + // Attempting to Deauthenticate + // with a pre-authenticated peer. + // Deauthetiate with peer if there + // exists a pre-auth context below. + break; + + case eLIM_MLM_AUTHENTICATED_STATE: + case eLIM_MLM_WT_ASSOC_RSP_STATE: + case eLIM_MLM_LINK_ESTABLISHED_STATE: + if (!vos_mem_compare(pMlmDeauthReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) ) + { + limLog(pMac, LOGE, + FL("received MLM_DEAUTH_REQ with invalid BSS id " + "Peer MAC: "MAC_ADDRESS_STR " CFG BSSID Addr : " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr), + MAC_ADDR_ARRAY(currentBssId)); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + if ((psessionEntry->limMlmState == + eLIM_MLM_AUTHENTICATED_STATE) || + (psessionEntry->limMlmState == + eLIM_MLM_WT_ASSOC_RSP_STATE)) + { + // Send Deauthentication frame + // to peer entity + limSendDeauthMgmtFrame( + pMac, + pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, FALSE); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS; + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + goto end; + } + else + { + // LINK_ESTABLISED_STATE + // Cleanup RX & TX paths + // below + } + + break; + + default: + + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ with in state %d for peer "MAC_ADDRESS_STR), + psessionEntry->limMlmState,MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + mlmDeauthCnf.resultCode = + eSIR_SME_STA_NOT_AUTHENTICATED; + + goto end; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + vos_mem_free(pMlmDeauthReq); + + return; + + default: // eLIM_AP_ROLE + break; + + } // end switch (psessionEntry->limSystemRole) + + /** + * Check if there exists a context for the peer entity + * to be deauthenticated with. + */ + pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + /// Check if there exists pre-auth context for this STA + pAuthNode = limSearchPreAuthList(pMac, + pMlmDeauthReq->peerMacAddr); + + if (pAuthNode == NULL) + { + /** + * Received DEAUTH REQ for a STA that is neither + * Associated nor Pre-authenticated. Log error, + * Prepare and Send LIM_MLM_DEAUTH_CNF + */ + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ in mlme state %d for STA that " + "does not have context, Addr="MAC_ADDRESS_STR), + psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + + mlmDeauthCnf.resultCode = + eSIR_SME_STA_NOT_AUTHENTICATED; + } + else + { + mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS; + + /// Delete STA from pre-auth STA list + limDeletePreAuthNode(pMac, pMlmDeauthReq->peerMacAddr); + + /// Send Deauthentication frame to peer entity + limSendDeauthMgmtFrame(pMac, + pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, FALSE); + } + + goto end; + } + else if ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE)) + { + /** + * Received LIM_MLM_DEAUTH_REQ for STA that is n + * some transit state. Log error. + */ + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ for STA that either has no context or in some transit state, Addr=" + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + //pStaDs->mlmStaContext.rxPurgeReq = 1; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) + pMlmDeauthReq->reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = pMlmDeauthReq->deauthTrigger; + + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = pMlmDeauthReq; + + /* Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE + * This is to address the issue of race condition between + * disconnect request from the HDD and disassoc from + * inactivity timer. This will make sure that we will not + * process disassoc if deauth is in progress for the station + * and thus mlmStaContext.cleanupTrigger will not be overwritten. + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + /// Send Deauthentication frame to peer entity + limSendDeauthMgmtFrame(pMac, pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, TRUE); + + return; + +end: + vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger; + mlmDeauthCnf.aid = pMlmDeauthReq->aid; + mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId; + + // Free up buffer allocated + // for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + +} + + +void limProcessDeauthAckTimeout(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("")); + limSendDeauthCnf(pMac); +} + +/** + * limProcessMlmDeauthReq() + * + *FUNCTION: + * This function is called to process MLM_DEAUTH_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDeauthReq *pMlmDeauthReq; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf; + + limLog(pMac, LOG1,FL("Process Deauth Req on sessionID %d " + "from: "MAC_ADDRESS_STR), pMlmDeauthReq->sessionId, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr)); + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given sessionId %d"), + pMlmDeauthReq->sessionId); + return; + } + + limProcessMlmDeauthReqNtf( pMac, eHAL_STATUS_SUCCESS, (tANI_U32*) pMsgBuf ); + +} /*** limProcessMlmDeauthReq() ***/ + + + +/** + * @function : limProcessMlmSetKeysReq() + * + * @brief : This function is called to process MLM_SETKEYS_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmSetKeysReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ +tANI_U16 aid; +tANI_U16 staIdx = 0; +tANI_U32 defaultKeyId = 0; +tSirMacAddr currentBssId; +tpDphHashNode pStaDs; +tLimMlmSetKeysReq *pMlmSetKeysReq; +tLimMlmSetKeysCnf mlmSetKeysCnf; +tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + + pMlmSetKeysReq = (tLimMlmSetKeysReq *) pMsgBuf; + // Hold onto the SetKeys request parameters + pMac->lim.gpLimMlmSetKeysReq = (void *) pMlmSetKeysReq; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmSetKeysReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + return; + } + + limLog( pMac, LOGW, + FL( "Received MLM_SETKEYS_REQ with parameters:" + "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "), + pMlmSetKeysReq->aid, + pMlmSetKeysReq->edType, + pMlmSetKeysReq->numKeys ); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch( psessionEntry->limSystemRole ) { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + //In case of TDLS, peerMac address need not be BssId. Skip this check + //if TDLS is enabled. +#ifndef FEATURE_WLAN_TDLS + if((!limIsAddrBC( pMlmSetKeysReq->peerMacAddr ) ) && + (!vos_mem_compare(pMlmSetKeysReq->peerMacAddr, + currentBssId, sizeof(tSirMacAddr))) ){ + limLog( pMac, LOGW, FL("Received MLM_SETKEYS_REQ with invalid BSSID")); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_SETKEYS_CNF with error code + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } +#endif + // Fall thru' & 'Plumb' keys below + break; + case eLIM_STA_IN_IBSS_ROLE: + // update the IBSS PE session encrption type based on the key type + psessionEntry->encryptType = pMlmSetKeysReq->edType; + break; + default: // others + // Fall thru... + break; + } + + /** + * Use the "unicast" parameter to determine if the "Group Keys" + * are being set. + * pMlmSetKeysReq->key.unicast = 0 -> Multicast/broadcast + * pMlmSetKeysReq->key.unicast - 1 -> Unicast keys are being set + */ + if( limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) { + limLog( pMac, LOG1, FL("Trying to set Group Keys...%d "), pMlmSetKeysReq->sessionId); + /** When trying to set Group Keys for any + * security mode other than WEP, use the + * STA Index corresponding to the AP... + */ + switch( pMlmSetKeysReq->edType ) { + case eSIR_ED_CCMP: + +#ifdef WLAN_FEATURE_11W + case eSIR_ED_AES_128_CMAC: +#endif + staIdx = psessionEntry->staId; + break; + + default: + break; + } + }else { + limLog( pMac, LOG1, FL("Trying to set Unicast Keys...")); + /** + * Check if there exists a context for the + * peer entity for which keys need to be set. + */ + + + pStaDs = dphLookupHashEntry( pMac, pMlmSetKeysReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable); + + if ((pStaDs == NULL) || + ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) && (psessionEntry->limSystemRole != eLIM_AP_ROLE))) { + /** + * Received LIM_MLM_SETKEYS_REQ for STA + * that does not have context or in some + * transit state. Log error. + */ + limLog( pMac, LOG1, + FL("Received MLM_SETKEYS_REQ for STA that either has no context or in some transit state, Addr = ")); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } else + staIdx = pStaDs->staIndex; + } + + if ((pMlmSetKeysReq->numKeys == 0) && (pMlmSetKeysReq->edType != eSIR_ED_NONE)) { + // + // Broadcast/Multicast Keys (for WEP!!) are NOT sent + // via this interface!! + // + // This indicates to HAL that the WEP Keys need to be + // extracted from the CFG and applied to hardware + defaultKeyId = 0xff; + }else if(pMlmSetKeysReq->key[0].keyId && + ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || + (pMlmSetKeysReq->edType == eSIR_ED_WEP104))){ + /* If the Key Id is non zero and encryption mode is WEP, + * the key index is coming from the upper layers so that key only + * need to be used as the default tx key, This is being used only + * in case of WEP mode in HAL */ + defaultKeyId = pMlmSetKeysReq->key[0].keyId; + }else + defaultKeyId = 0; + + limLog( pMac, LOG1, + FL( "Trying to set keys for STA Index [%d], using defaultKeyId [%d]" ), + staIdx, + defaultKeyId ); + + if(limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) { + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog( pMac, LOG1, FL("Trying to set Group Keys...%d "), + psessionEntry->peSessionId); + + // Package WDA_SET_BSSKEY_REQ message parameters + limSendSetBssKeyReq(pMac, pMlmSetKeysReq,psessionEntry); + return; + }else { + // Package WDA_SET_STAKEY_REQ / WDA_SET_STA_BCASTKEY_REQ message parameters + limSendSetStaKeyReq(pMac, pMlmSetKeysReq, staIdx, (tANI_U8) defaultKeyId,psessionEntry, TRUE); + return; + } + +end: + mlmSetKeysCnf.sessionId= pMlmSetKeysReq->sessionId; + limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf ); + +} /*** limProcessMlmSetKeysReq() ***/ + +/** + * limProcessMlmRemoveKeyReq() + * + *FUNCTION: + * This function is called to process MLM_REMOVEKEY_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ +tANI_U16 aid; +tANI_U16 staIdx = 0; +tSirMacAddr currentBssId; +tpDphHashNode pStaDs; +tLimMlmRemoveKeyReq *pMlmRemoveKeyReq; +tLimMlmRemoveKeyCnf mlmRemoveKeyCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmRemoveKeyReq = (tLimMlmRemoveKeyReq *) pMsgBuf; + + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + vos_mem_free(pMsgBuf); + return; + } + + + if( pMac->lim.gpLimMlmRemoveKeyReq != NULL ) + { + // Free any previous requests. + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + // Hold onto the RemoveKeys request parameters + pMac->lim.gpLimMlmRemoveKeyReq = (void *) pMlmRemoveKeyReq; + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch( psessionEntry->limSystemRole ) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + if (( limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr ) != true ) && + (!vos_mem_compare(pMlmRemoveKeyReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)))) + { + limLog( pMac, LOGW, + FL("Received MLM_REMOVEKEY_REQ with invalid BSSID")); + limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF with error code + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_AP_ROLE + // Fall thru... + break; + } + + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + if(limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr )) //Second condition for IBSS or AP role. + { + psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_BSS_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + // Package WDA_REMOVE_BSSKEY_REQ message parameters + limSendRemoveBssKeyReq( pMac,pMlmRemoveKeyReq,psessionEntry); + return; + } + + /** + * Check if there exists a context for the + * peer entity for which keys need to be removed. + */ + pStaDs = dphLookupHashEntry( pMac, pMlmRemoveKeyReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if ((pStaDs == NULL) || + (pStaDs && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE))) + { + /** + * Received LIM_MLM_REMOVEKEY_REQ for STA + * that does not have context or in some + * transit state. Log error. + */ + limLog( pMac, LOGW, + FL("Received MLM_REMOVEKEYS_REQ for STA that either has no context or in some transit state, Addr = ")); + limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmRemoveKeyCnf.sessionId = pMlmRemoveKeyReq->sessionId; + + + goto end; + } + else + staIdx = pStaDs->staIndex; + + + + psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_STA_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // Package WDA_REMOVE_STAKEY_REQ message parameters + limSendRemoveStaKeyReq( pMac,pMlmRemoveKeyReq,staIdx,psessionEntry); + return; + +end: + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeyCnf ); + +} /*** limProcessMlmRemoveKeyReq() ***/ + + +/** + * limProcessMinChannelTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessMinChannelTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + +#ifdef GEN6_TODO + //if the min Channel is maintained per session, then use the below seesionEntry + //priority - LOW/might not be needed + + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimMinChannelTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } +#endif + + /*do not process if we are in finish scan wait state i.e. + scan is aborted or finished*/ + if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE && + pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) + { + PELOG1(limLog(pMac, LOG1, FL("Scanning : min channel timeout occurred"));) + + /// Min channel timer timed out + pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER); + pMac->lim.probeCounter = 0; + if (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + channelNum = (tANI_U8)limGetCurrentScanChannel(pMac); + } + else + { + // This shouldn't be the case, but when this happens, this timeout should be for the last channelId. + // Get the channelNum as close to correct as possible. + if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber) + { + channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1]; + } + else + { + channelNum = 1; + } + } + + limLog(pMac, LOGW, + FL("Sending End Scan req from MIN_CH_TIMEOUT in state %X ch-%d"), + pMac->lim.gLimMlmState,channelNum); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + } + else + { + /** + * MIN channel timer should not have timed out + * in states other than wait_probe_response. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected MIN channel timeout in mlme state %X and hal scan State %X"), + pMac->lim.gLimMlmState,pMac->lim.gLimHalScanState); + limPrintMlmState(pMac, LOGE, pMac->lim.gLimMlmState); + } +} /*** limProcessMinChannelTimeout() ***/ + + + +/** + * limProcessMaxChannelTimeout() + * + *FUNCTION: + * This function is called to process Max Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessMaxChannelTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + + /*do not process if we are in finish scan wait state i.e. + scan is aborted or finished*/ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE || + pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) && + pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) + { + PELOG1(limLog(pMac, LOG1, FL("Scanning : Max channel timed out"));) + /** + * MAX channel timer timed out + * Continue channel scan. + */ + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER); + pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff; + pMac->lim.probeCounter = 0; + + if (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + channelNum = limGetCurrentScanChannel(pMac); + } + else + { + if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber) + { + channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1]; + } + else + { + channelNum = 1; + } + } + limLog(pMac, LOGW, + FL("Sending End Scan req from MAX_CH_TIMEOUT in state %X on ch-%d"), + pMac->lim.gLimMlmState,channelNum); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + } + else + { + /** + * MAX channel timer should not have timed out + * in states other than wait_scan. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected MAX channel timeout in mlme state %X and hal scan state %X"), + pMac->lim.gLimMlmState, pMac->lim.gLimHalScanState); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + } +} /*** limProcessMaxChannelTimeout() ***/ + +/** + * limProcessPeriodicProbeReqTimer() + * + *FUNCTION: + * This function is called to process periodic probe request + * to send during scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + tANI_U8 i = 0; + tSirRetStatus status = eSIR_SUCCESS; + TX_TIMER *pPeriodicProbeReqTimer; + pPeriodicProbeReqTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer; + + if(vos_timer_getCurrentState(&pPeriodicProbeReqTimer->vosTimer) + != VOS_TIMER_STATE_STOPPED) + { + PELOG1(limLog(pMac, LOG1, FL("Invalid state of timer"));) + return; + } + + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && + (pPeriodicProbeReqTimer->sessionId != 0xff) && (pMac->lim.probeCounter < pMac->lim.maxProbe)) + { + tLimMlmScanReq *pLimMlmScanReq = pMac->lim.gpLimMlmScanReq; + PELOG1(limLog(pMac, LOG1, FL("Scanning : Periodic scanning"));) + pMac->lim.probeCounter++; + /** + * Periodic channel timer timed out + * to send probe request. + */ + channelNum = limGetCurrentScanChannel(pMac); + do + { + /* Prepare and send Probe Request frame for all the SSIDs + * present in the saved MLM + */ + + status = limSendProbeReqMgmtFrame( pMac, &pLimMlmScanReq->ssId[i], + pLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr, + pLimMlmScanReq->dot11mode, pLimMlmScanReq->uIEFieldLen, + (tANI_U8 *)(pLimMlmScanReq) + pLimMlmScanReq->uIEFieldOffset); + + + if ( status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID " + "%s on channel: %d"), + pLimMlmScanReq->ssId[i].ssId, + channelNum);) + return; + } + i++; + } while (i < pLimMlmScanReq->numSsid); + + /* Activate timer again */ + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, pPeriodicProbeReqTimer->sessionId, eLIM_PERIODIC_PROBE_REQ_TIMER)); + if (tx_timer_activate(pPeriodicProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not start periodic probe" + " req timer")); + return; + } + } + else + { + /** + * Periodic scan is timeout is happening in + * in states other than wait_scan. + * Log error. + */ + limLog(pMac, LOG1, + FL("received unexpected Periodic scan timeout in state %X"), + pMac->lim.gLimMlmState); + } +} /*** limProcessPeriodicProbeReqTimer() ***/ + +/** + * limProcessJoinFailureTimeout() + * + *FUNCTION: + * This function is called to process JoinFailureTimeout + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessJoinFailureTimeout(tpAniSirGlobal pMac) +{ + tLimMlmJoinCnf mlmJoinCnf; + tANI_U32 len; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimJoinFailureTimer.sessionId))== NULL) + { + limLog(pMac, LOGE, FL("Session Does not exist for given sessionID")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + len = sizeof(tSirMacAddr); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + // Change Periodic probe req timer for future activation + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + /** + * Issue MLM join confirm with timeout reason code + */ + PELOGE(limLog(pMac, LOGE, FL(" In state eLIM_MLM_WT_JOIN_BEACON_STATE."));) + PELOGE(limLog(pMac, LOGE, FL(" Join Failure Timeout occurred for session %d with BSS "), + psessionEntry->peSessionId); + limPrintMacAddr(pMac, psessionEntry->bssId, LOGE);) + + mlmJoinCnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState"));) + /* Update PE session Id */ + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + + + // Freeup buffer allocated to join request + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + limPostSmeMessage(pMac, + LIM_MLM_JOIN_CNF, + (tANI_U32 *) &mlmJoinCnf); + + return; + } + else + { + /** + * Join failure timer should not have timed out + * in states other than wait_join_beacon state. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected JOIN failure timeout in state %X"),psessionEntry->limMlmState); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + } +} /*** limProcessJoinFailureTimeout() ***/ + + +/** + * limProcessPeriodicJoinProbeReqTimer() + * + *FUNCTION: + * This function is called to process periodic probe request + * send during joining process. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void limProcessPeriodicJoinProbeReqTimer(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + tSirMacSSid ssId; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given SessionId : %d"), + pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId); + return; + } + + if((VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer)) && + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) + { + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + ssId.length = psessionEntry->ssId.length; + + limSendProbeReqMgmtFrame( pMac, &ssId, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, psessionEntry->currentOperChannel/*chanNum*/, + psessionEntry->selfMacAddr, psessionEntry->dot11mode, + psessionEntry->pLimJoinReq->addIEScan.length, psessionEntry->pLimJoinReq->addIEScan.addIEdata); + + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + // Activate Join Periodic Probe Req timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Periodic Join req failure timer")); + return; + } + } + return; +} /*** limProcessPeriodicJoinProbeReqTimer() ***/ + + +/** + * limProcessAuthFailureTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAuthFailureTimeout(tpAniSirGlobal pMac) +{ + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAuthFailureTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + limLog(pMac, LOGE, FL("received AUTH failure timeout in sessionid %d " + "limMlmstate %X limSmeState %X"), psessionEntry->peSessionId, + psessionEntry->limMlmState, psessionEntry->limSmeState); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + /** + * Requesting STA did not receive next auth frame + * before Auth Failure timeout. + * Issue MLM auth confirm with timeout reason code + */ + //Restore default failure timeout + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout) + { + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT , + psessionEntry->defaultAuthFailureTimeout, NULL, eANI_BOOLEAN_FALSE); + } + limRestoreFromAuthState(pMac,eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + break; + + default: + /** + * Auth failure timer should not have timed out + * in states other than wt_auth_frame2/4 + * Log error. + */ + PELOGE(limLog(pMac, LOGE, FL("received unexpected AUTH failure timeout in state %X"), psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + + break; + } +} /*** limProcessAuthFailureTimeout() ***/ + + + +/** + * limProcessAuthRspTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAuthRspTimeout(tpAniSirGlobal pMac, tANI_U32 authIndex) +{ + struct tLimPreAuthNode *pAuthNode; + tpPESession psessionEntry; + tANI_U8 sessionId; + + pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, authIndex); + + if (NULL == pAuthNode) + { + limLog(pMac, LOGW, FL("Invalid auth node")); + return; + } + + if ((psessionEntry = peFindSessionByBssid(pMac, pAuthNode->peerMacAddr, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("session does not exist for given BSSID ")); + return; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (pAuthNode->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) + { + /** + * Authentication response timer timedout + * in unexpected state. Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received AUTH rsp timeout in unexpected state " + "for MAC address: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAuthNode->peerMacAddr));) + } + else + { + // Authentication response timer + // timedout for an STA. + pAuthNode->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE; + pAuthNode->fTimerStarted = 0; + PELOG1( limLog(pMac, LOG1, + FL("AUTH rsp timedout for MAC address "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAuthNode->peerMacAddr));) + + // Change timer to reactivate it in future + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + limDeletePreAuthNode(pMac, pAuthNode->peerMacAddr); + } + } +} /*** limProcessAuthRspTimeout() ***/ + + +/** + * limProcessAssocFailureTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAssocFailureTimeout(tpAniSirGlobal pMac, tANI_U32 MsgType) +{ + + tLimMlmAssocCnf mlmAssocCnf; + tpPESession psessionEntry; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + //to fetch the lim/mlm state based on the sessionId, use the below sessionEntry + tANI_U8 sessionId; + + if(MsgType == LIM_ASSOC) + { + sessionId = pMac->lim.limTimers.gLimAssocFailureTimer.sessionId; + } + else + { + sessionId = pMac->lim.limTimers.gLimReassocFailureTimer.sessionId; + } + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + /** + * Expected Re/Association Response frame + * not received within Re/Association Failure Timeout. + */ + + + + + /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */ + /* notify TL that association is failed so that TL can flush the cached frame */ + WLANTL_AssocFailed (psessionEntry->staId); + + // Log error + PELOG1(limLog(pMac, LOG1, + FL("Re/Association Response not received before timeout "));) + + if (( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )|| + ( (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) && + (psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) && + (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) + { + /** + * Re/Assoc failure timer should not have timedout on AP + * or in a state other than wt_re/assoc_response. + */ + + // Log error + limLog(pMac, LOGW, + FL("received unexpected REASSOC failure timeout in state %X for role %d"), + psessionEntry->limMlmState, psessionEntry->limSystemRole); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + } + else + { + + if ((MsgType == LIM_ASSOC) || + ((MsgType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) + { + PELOGE(limLog(pMac, LOGE, FL("(Re)Assoc Failure Timeout occurred."));) + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER); + + // Free up buffer allocated for JoinReq held by + // MLM state machine + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + //To remove the preauth node in case of fail to associate + if (limSearchPreAuthList(pMac, psessionEntry->bssId)) + { + PELOG1(limLog(pMac, LOG1, FL(" delete pre auth node for " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(psessionEntry->bssId));) + limDeletePreAuthNode(pMac, psessionEntry->bssId); + } + + mlmAssocCnf.resultCode = + eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE; + mlmAssocCnf.protStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + if (MsgType == LIM_ASSOC) + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + else + { + /* Will come here only in case of 11r, Ese FT when reassoc rsp + is not received and we receive a reassoc - timesout */ + mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE; + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } + } + else + { + /** + * Restore pre-reassoc req state. + * Set BSSID to currently associated AP address. + */ + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry); + } + } +} /*** limProcessAssocFailureTimeout() ***/ + + + +/** + * limCompleteMlmScan() + * + *FUNCTION: + * This function is called to send MLM_SCAN_CNF message + * to SME state machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param retCode Result code to be sent + * @return None + */ + +void +limCompleteMlmScan(tpAniSirGlobal pMac, tSirResultCodes retCode) +{ + tLimMlmScanCnf mlmScanCnf; + + /// Restore previous MLM state + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + limRestorePreScanState(pMac); + + // Free up pMac->lim.gLimMlmScanReq + if( NULL != pMac->lim.gpLimMlmScanReq ) + { + vos_mem_free(pMac->lim.gpLimMlmScanReq); + pMac->lim.gpLimMlmScanReq = NULL; + } + + mlmScanCnf.resultCode = retCode; + mlmScanCnf.scanResultLength = pMac->lim.gLimMlmScanResultLength; + + limPostSmeMessage(pMac, LIM_MLM_SCAN_CNF, (tANI_U32 *) &mlmScanCnf); + +} /*** limCompleteMlmScan() ***/ + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limProcessMlmAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME ADDBA Req message buffer + * + * \return none + */ +void limProcessMlmAddBAReq( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmAddBAReq pMlmAddBAReq; +tpLimMlmAddBACnf pMlmAddBACnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmAddBAReq = (tpLimMlmAddBAReq) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBAReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + vos_mem_free(pMsgBuf); + return; + } + + + // Send ADDBA Req over the air + status = limSendAddBAReq( pMac, pMlmAddBAReq,psessionEntry); + + // + // Respond immediately to LIM, only if MLME has not been + // successfully able to send WDA_ADDBA_REQ to HAL. + // Else, LIM_MLM_ADDBA_CNF will be sent after receiving + // ADDBA Rsp from peer entity + // + if( eSIR_SUCCESS != status ) + { + // Allocate for LIM_MLM_ADDBA_CNF + + pMlmAddBACnf = vos_mem_malloc(sizeof( tLimMlmAddBACnf )); + if ( NULL == pMlmAddBACnf ) + { + limLog( pMac, LOGP, + FL("AllocateMemory failed")); + vos_mem_free(pMsgBuf); + return; + } + else + { + vos_mem_set((void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ), 0); + vos_mem_copy((void *) pMlmAddBACnf->peerMacAddr, + (void *) pMlmAddBAReq->peerMacAddr, + sizeof( tSirMacAddr )); + + pMlmAddBACnf->baDialogToken = pMlmAddBAReq->baDialogToken; + pMlmAddBACnf->baTID = pMlmAddBAReq->baTID; + pMlmAddBACnf->baPolicy = pMlmAddBAReq->baPolicy; + pMlmAddBACnf->baBufferSize = pMlmAddBAReq->baBufferSize; + pMlmAddBACnf->baTimeout = pMlmAddBAReq->baTimeout; + pMlmAddBACnf->sessionId = pMlmAddBAReq->sessionId; + + // Update the result code + pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limPostSmeMessage( pMac, + LIM_MLM_ADDBA_CNF, + (tANI_U32 *) pMlmAddBACnf ); + } + + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + } + + // Free the buffer allocated for tLimMlmAddBAReq + vos_mem_free(pMsgBuf); + +} + +/** + * \brief Send an ADDBA Rsp to peer STA in response + * to an ADDBA Req received earlier + * + * \sa limProcessMlmAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME ADDBA Rsp message buffer + * + * \return none + */ +void limProcessMlmAddBARsp( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tpLimMlmAddBARsp pMlmAddBARsp; + tANI_U16 aid; + tpDphHashNode pSta; + tpPESession psessionEntry; + + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmAddBARsp = (tpLimMlmAddBARsp) pMsgBuf; + + if(( psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBARsp->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given session ID"));) + vos_mem_free(pMsgBuf); + return; + } + + + // Send ADDBA Rsp over the air + if( eSIR_SUCCESS != limSendAddBARsp( pMac,pMlmAddBARsp,psessionEntry)) + { + limLog( pMac, LOGE, + FL("Failed to send ADDBA Rsp to peer ")); + limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGE ); + /* Clean the BA context maintained by HAL and TL on failure */ + pSta = dphLookupHashEntry( pMac, pMlmAddBARsp->peerMacAddr, &aid, + &psessionEntry->dph.dphHashTable); + if( NULL != pSta ) + { + limPostMsgDelBAInd( pMac, pSta, pMlmAddBARsp->baTID, eBA_RECIPIENT, + psessionEntry); + } + } + + // Time to post a WDA_DELBA_IND to HAL in order + // to cleanup the HAL and SoftMAC entries + + + // Free the buffer allocated for tLimMlmAddBARsp + vos_mem_free(pMsgBuf); + +} + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limProcessMlmDelBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME DELBA Req message buffer + * + * \return none + */ +void limProcessMlmDelBAReq( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpLimMlmDelBAReq pMlmDelBAReq; + tpLimMlmDelBACnf pMlmDelBACnf; + tpPESession psessionEntry; + + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + // TODO - Need to validate MLME state + pMlmDelBAReq = (tpLimMlmDelBAReq) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDelBAReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + vos_mem_free(pMsgBuf); + return; + } + + // Send DELBA Ind over the air + if( eSIR_SUCCESS != + (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry))) + status = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + else + { + tANI_U16 aid; + tpDphHashNode pSta; + + // Time to post a WDA_DELBA_IND to HAL in order + // to cleanup the HAL and SoftMAC entries + pSta = dphLookupHashEntry( pMac, pMlmDelBAReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable); + if( NULL != pSta ) + { + status = limPostMsgDelBAInd( pMac, + pSta, + pMlmDelBAReq->baTID, + pMlmDelBAReq->baDirection,psessionEntry); + + } + } + + // + // Respond immediately to SME with DELBA CNF using + // LIM_MLM_DELBA_CNF with appropriate status + // + + // Allocate for LIM_MLM_DELBA_CNF + + pMlmDelBACnf = vos_mem_malloc(sizeof( tLimMlmDelBACnf )); + if ( NULL == pMlmDelBACnf ) + { + limLog( pMac, LOGP, FL("AllocateMemory failed")); + vos_mem_free(pMsgBuf); + return; + } + else + { + vos_mem_set((void *) pMlmDelBACnf, sizeof( tLimMlmDelBACnf ), 0); + + vos_mem_copy((void *) pMlmDelBACnf, + (void *) pMlmDelBAReq, + sizeof( tLimMlmDelBAReq )); + + // Update DELBA result code + pMlmDelBACnf->delBAReasonCode = pMlmDelBAReq->delBAReasonCode; + + /* Update PE session Id*/ + pMlmDelBACnf->sessionId = pMlmDelBAReq->sessionId; + + limPostSmeMessage( pMac, + LIM_MLM_DELBA_CNF, + (tANI_U32 *) pMlmDelBACnf ); + } + + // Free the buffer allocated for tLimMlmDelBAReq + vos_mem_free(pMsgBuf); + +} + +/** + * @function : limSMPowerSaveStateInd( ) + * + * @brief : This function is called upon receiving the PMC Indication to update the STA's MimoPs State. + * + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Lim Message structure object with the MimoPSparam in body + * @return None + */ + +tSirRetStatus +limSMPowerSaveStateInd(tpAniSirGlobal pMac, tSirMacHTMIMOPowerSaveState state) +{ +return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState limGet11ACPhyCBState(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 htSecondaryChannelOffset,tANI_U8 peerCenterChan, tpPESession psessionEntry) +{ + ePhyChanBondState cbState = PHY_SINGLE_CHANNEL_CENTERED; + + if(!psessionEntry->apChanWidth) + { + return htSecondaryChannelOffset; + } + + if ( (htSecondaryChannelOffset + == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + ) + { + if ((channel + 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + else if ((channel + 6 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + else if ((channel - 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + else + limLog (pMac, LOGP, + FL("Invalid Channel Number = %d Center Chan = %d "), + channel, peerCenterChan); + } + if ( (htSecondaryChannelOffset + == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + ) + { + if ((channel - 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + else if ((channel + 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + else if ((channel - 6 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + else + limLog (pMac, LOGP, + FL("Invalid Channel Number = %d Center Chan = %d "), + channel, peerCenterChan); + } + return cbState; +} + +#endif + +void +limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + tpPESession peSession; + + peSession = peFindSessionBySessionId (pMac, peSessionId); + + if ( NULL == peSession) + { + limLog (pMac, LOGP, FL("Invalid PE session = %d"), peSessionId); + return; + } +#if defined WLAN_FEATURE_VOWIFI +#ifdef WLAN_FEATURE_11AC + if ( peSession->vhtCapability ) + { + limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset,peSession->apCenterChan, peSession), maxTxPower, peSessionId); + } + else +#endif + { + limSendSwitchChnlParams( pMac, channel, secChannelOffset, maxTxPower, peSessionId); + } +#else + if (wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not read WNI_CFG_LOCAL_POWER_CONSTRAINT from CFG")); + return; + } + // Send WDA_CHNL_SWITCH_IND to HAL +#ifdef WLAN_FEATURE_11AC + if ( peSession->vhtCapability && peSession->vhtCapabilityPresentInBeacon) + { + limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset,peSession->apCenterChan, peSession), maxTxPower, peSessionId); + } + else +#endif + { + limSendSwitchChnlParams( pMac, channel, secChannelOffset, (tPowerdBm)localPwrConstraint, peSessionId); + } +#endif + + } diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c new file mode 100644 index 0000000000000..9b5e3b5c808a3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c @@ -0,0 +1,4988 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessMlmRspMessages.cc contains the code + * for processing response messages from MLM state machine. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "wniApi.h" +#include "wniCfgSta.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limTimerUtils.h" +#include "limSendMessages.h" +#include "limAdmitControl.h" +#include "limSendMessages.h" +#include "limIbssPeerMgmt.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFT.h" +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limSessionUtils.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#include "wlan_qct_wda.h" +#include "vos_utils.h" + +#define MAX_SUPPORTED_PEERS_WEP 16 + +static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession); +static void limHandleSmeReaasocResult(tpAniSirGlobal, tSirResultCodes, tANI_U16, tpPESession); +void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *); +#ifdef FEATURE_OEM_DATA_SUPPORT +void limProcessMlmOemDataReqCnf(tpAniSirGlobal, tANI_U32 *); +#endif +void limProcessMlmJoinCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAuthCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmStartCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAuthInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAssocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAssocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmReassocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmReassocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmSetKeysCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDisassocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDisassocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDeauthInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDeauthCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmPurgeStaInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAddBACnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDelBACnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf); +static void limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry); +void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *); +static void +limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); +/** + * limProcessMlmRspMessages() + * + *FUNCTION: + * This function is called to processes various MLM response (CNF/IND + * messages from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmRspMessages(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_LIM_MSG, 0, msgType)); + switch (msgType) + { + case LIM_MLM_SCAN_CNF: + limProcessMlmScanCnf(pMac, pMsgBuf); + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case LIM_MLM_OEM_DATA_CNF: + limProcessMlmOemDataReqCnf(pMac, pMsgBuf); + pMsgBuf = NULL; + break; +#endif + + case LIM_MLM_AUTH_CNF: + limProcessMlmAuthCnf(pMac, pMsgBuf); + break; + case LIM_MLM_AUTH_IND: + limProcessMlmAuthInd(pMac, pMsgBuf); + break; + case LIM_MLM_ASSOC_CNF: + limProcessMlmAssocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_START_CNF: + limProcessMlmStartCnf(pMac, pMsgBuf); + break; + case LIM_MLM_JOIN_CNF: + limProcessMlmJoinCnf(pMac, pMsgBuf); + break; + case LIM_MLM_ASSOC_IND: + limProcessMlmAssocInd(pMac, pMsgBuf); + break; + case LIM_MLM_REASSOC_CNF: + limProcessMlmReassocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_REASSOC_IND: + limProcessMlmReassocInd(pMac, pMsgBuf); + break; + case LIM_MLM_DISASSOC_CNF: + limProcessMlmDisassocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_DISASSOC_IND: + limProcessMlmDisassocInd(pMac, pMsgBuf); + break; + case LIM_MLM_PURGE_STA_IND: + limProcessMlmPurgeStaInd(pMac, pMsgBuf); + break; + case LIM_MLM_DEAUTH_CNF: + limProcessMlmDeauthCnf(pMac, pMsgBuf); + break; + case LIM_MLM_DEAUTH_IND: + limProcessMlmDeauthInd(pMac, pMsgBuf); + break; + case LIM_MLM_SETKEYS_CNF: + limProcessMlmSetKeysCnf(pMac, pMsgBuf); + break; + case LIM_MLM_REMOVEKEY_CNF: + limProcessMlmRemoveKeyCnf(pMac, pMsgBuf); + break; + case LIM_MLM_TSPEC_CNF: + break; + case LIM_MLM_ADDBA_CNF: + limProcessMlmAddBACnf( pMac, pMsgBuf ); + pMsgBuf = NULL; + break; + case LIM_MLM_DELBA_CNF: + limProcessMlmDelBACnf( pMac, pMsgBuf ); + pMsgBuf = NULL; + break; + default: + break; + } // switch (msgType) + return; +} /*** end limProcessMlmRspMessages() ***/ + +/** + * limProcessMlmScanCnf() + * + *FUNCTION: + * This function is called to processes MLM_SCAN_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmScanCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + switch(pMac->lim.gLimSmeState) + { + case eLIM_SME_WT_SCAN_STATE: + //case eLIM_SME_LINK_EST_WT_SCAN_STATE: //TO SUPPORT BT-AMP + //case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: //TO SUPPORT BT-AMP + pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + pMac->lim.gLimSystemInScanLearnMode = 0; + break; + default: + /** + * Should not have received scan confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_SCAN_CNF in state %X"), + pMac->lim.gLimSmeState);) + return; + } + + /// Process received scan confirm + /// Increment length of cached scan results + pMac->lim.gLimSmeScanResultLength += + ((tLimMlmScanCnf *) pMsgBuf)->scanResultLength; + if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults) + { + tANI_U16 scanRspLen = 0; + /// Need to send response to Host + pMac->lim.gLimRspReqd = false; + if ((((tLimMlmScanCnf *) pMsgBuf)->resultCode == + eSIR_SME_SUCCESS) || + pMac->lim.gLimSmeScanResultLength) + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp); + } + if(pMac->lim.gLimReportBackgroundScanResults) + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + if (pMac->lim.gLimSmeScanResultLength == 0) + { + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + } + else + { + limSendSmeScanRsp(pMac, scanRspLen, + eSIR_SME_SUCCESS,pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + } + } // if (pMac->lim.gLimRspReqd) + //check to see whether we need to run bgScan timer + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + /// Could not activate background scan timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = FALSE; + } + else + { + pMac->lim.gLimBackgroundScanStarted = TRUE; + } + } +} /*** end limProcessMlmScanCnf() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + * limProcessMlmOemDataReqCnf() + * + *FUNCTION: + * This function is called to processes LIM_MLM_OEM_DATA_REQ_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ + +void limProcessMlmOemDataReqCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmOemDataRsp* measRsp; + + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + measRsp = (tLimMlmOemDataRsp*)(pMsgBuf); + + //Now send the meas confirm message to the sme + limSendSmeOemDataRsp(pMac, (tANI_U32*)measRsp, resultCode); + + //Dont free the memory here. It will be freed up by the callee + + return; +} +#endif + +/** + * limProcessMlmStartCnf() + * + *FUNCTION: + * This function is called to processes MLM_START_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmStartCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry = NULL; + tLimMlmStartCnf *pLimMlmStartCnf; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + tANI_U8 channelId; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pLimMlmStartCnf = (tLimMlmStartCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmStartCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + + if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE) + { + /** + * Should not have received Start confirm from MLM + * in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_START_CNF in state %X"), + psessionEntry->limSmeState);) + return; + } + if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == + eSIR_SME_SUCCESS) + { + + /** + * Update global SME state so that Beacon Generation + * module starts writing Beacon frames into TFP's + * Beacon file register. + */ + psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + if(psessionEntry->bssType == eSIR_BTAMP_STA_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP STA SIDE***")); + } + else if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP AP SIDE***")); + } + else if(psessionEntry->bssType == eSIR_INFRA_AP_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in INFRA AP SIDE***")); + } + else + PELOG1(limLog(pMac, LOG1, FL("*** Started BSS ***"));) + } + else + { + /// Start BSS is a failure + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + PELOGE(limLog(pMac, LOGE,FL("Start BSS Failed "));) + } + /// Send response to Host + limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, + ((tLimMlmStartCnf *) pMsgBuf)->resultCode,psessionEntry, + smesessionId,smetransactionId); + if ((psessionEntry != NULL) && + (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS)) + { + channelId = psessionEntry->pLimStartBssReq->channelId; + + // We should start beacon transmission only if the channel + // on which we are operating is non-DFS until the channel + // availability check is done. The PE will receive an explicit + // request from upper layers to start the beacon transmission + + + if ( (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) || + ((eLIM_AP_ROLE == psessionEntry->limSystemRole) && + (vos_nv_getChannelEnabledState(channelId) != NV_CHANNEL_DFS)) ) + { + //Configure beacon and send beacons to HAL + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("Start Beacon with ssid %s Ch %d"), + psessionEntry->ssId.ssId, + psessionEntry->currentOperChannel); + limSendBeaconInd(pMac, psessionEntry); + } + } +} + + /*** end limProcessMlmStartCnf() ***/ + +/** + * limProcessMlmJoinCnf() + * + *FUNCTION: + * This function is called to processes MLM_JOIN_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmJoinCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tLimMlmJoinCnf *pLimMlmJoinCnf; + tpPESession psessionEntry; + pLimMlmJoinCnf = (tLimMlmJoinCnf*)pMsgBuf; + if( (psessionEntry = peFindSessionBySessionId(pMac,pLimMlmJoinCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("SessionId:%d Session does not exist"), + pLimMlmJoinCnf->sessionId);) + return; + } + + if (psessionEntry->limSmeState!= eLIM_SME_WT_JOIN_STATE) + { + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_JOIN_CNF in state %X"), + psessionEntry->limSmeState);) + return; + } + + resultCode = ((tLimMlmJoinCnf *) pMsgBuf)->resultCode ; + /// Process Join confirm from MLM + if (resultCode == eSIR_SME_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, FL("***SessionId:%d Joined ESS ***"), + pLimMlmJoinCnf->sessionId);) + //Setup hardware upfront + if(limStaSendAddBssPreAssoc( pMac, false, psessionEntry) == eSIR_SUCCESS) + return; + else + resultCode = eSIR_SME_REFUSED; + } + { + /// Join failure + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /// Send Join response to Host + limHandleSmeJoinResult(pMac, resultCode, ((tLimMlmJoinCnf *) pMsgBuf)->protStatusCode, psessionEntry ); + } +} /*** end limProcessMlmJoinCnf() ***/ + +/* + * limSendMlmAssocReq() + * + * FUNCTION: + * This function is sends ASSOC request MLM message to MLM State machine. + * ASSOC request packet would be by picking parameters from psessionEntry + * automatically based on the current state of MLM state machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * this function is called in middle of connection state machine and is + * expected to be called after auth cnf has been received or after ASSOC rsp + * with TRY_AGAIN_LATER was received and required time has elapsed after that. + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param psessionEntry Pointer to session etnry + * + * @return None + */ + +void +limSendMlmAssocReq( tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tLimMlmAssocReq *pMlmAssocReq; + tANI_U32 val; + tANI_U16 caps; + tANI_U32 teleBcnEn = 0; + + /* Successful MAC based authentication. Trigger Association with BSS */ + PELOG1(limLog(pMac, LOG1, FL("SessionId:%d Authenticated with BSS"), + psessionEntry->peSessionId);) + + pMlmAssocReq = vos_mem_malloc(sizeof(tLimMlmAssocReq)); + if ( NULL == pMlmAssocReq ) { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmAssocReq")); + return; + } + val = sizeof(tSirMacAddr); + sirCopyMacAddr(pMlmAssocReq->peerMacAddr,psessionEntry->bssId); + if (wlan_cfgGetInt(pMac, + WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAssocReq->assocFailureTimeout) + != eSIR_SUCCESS) { + /* Could not get AssocFailureTimeout value from CFG. Log error */ + limLog(pMac, LOGP, FL("could not retrieve AssocFailureTimeout value")); + } + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) { + /* Could not get Capabilities value from CFG. Log error */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + + /* Clear spectrum management bit if AP doesn't support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & + LIM_SPECTRUM_MANAGEMENT_BIT_MASK)) { + /* + * AP doesn't support spectrum management + * clear spectrum management bit + */ + caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK); + } + + /* Clear rrm bit if AP doesn't support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo + & LIM_RRM_BIT_MASK)) { + caps &= (~LIM_RRM_BIT_MASK); + } + + /* Clear short preamble bit if AP does not support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & + (LIM_SHORT_PREAMBLE_BIT_MASK))) { + caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK); + limLog(pMac, LOG1, FL("Clearing short preamble:no AP support")); + } + + /* Clear immediate block ack bit if AP does not support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & + (LIM_IMMEDIATE_BLOCK_ACK_MASK))) { + caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK); + limLog(pMac, LOG1, FL("Clearing Immed Blk Ack:no AP support")); + } + + pMlmAssocReq->capabilityInfo = caps; + PELOG3(limLog(pMac, LOG3, + FL("Capabilities to be used in AssocReq=0x%X, " + "privacy bit=%x shortSlotTime %x"), + caps, + ((tpSirMacCapabilityInfo) &pMlmAssocReq->capabilityInfo)->privacy, + ((tpSirMacCapabilityInfo) &pMlmAssocReq->capabilityInfo)->shortSlotTime);) + + /* + * If telescopic beaconing is enabled, set listen interval to + * WNI_CFG_TELE_BCN_MAX_LI + */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + + val = WNI_CFG_LISTEN_INTERVAL_STADEF; + + if(teleBcnEn) + { + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != + eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } else { + if (wlan_cfgGetInt(pMac, + WNI_CFG_LISTEN_INTERVAL, + &val) != eSIR_SUCCESS) { + /* + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + + pMlmAssocReq->listenInterval = (tANI_U16)val; + /* Update PE session ID*/ + pMlmAssocReq->sessionId = psessionEntry->peSessionId; + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_ASSOC_STATE; + MTRACE(macTrace(pMac, + TRACE_CODE_SME_STATE, + psessionEntry->peSessionId, + psessionEntry->limSmeState)); + limPostMlmMessage(pMac, + LIM_MLM_ASSOC_REQ, + (tANI_U32 *) pMlmAssocReq); +} + +#ifdef WLAN_FEATURE_11W +void limPmfComebackTimerCallback(void *context) +{ + tComebackTimerInfo *pInfo = (tComebackTimerInfo *)context; + tpAniSirGlobal pMac = pInfo->pMac; + tpPESession psessionEntry = &pMac->lim.gpSession[pInfo->sessionID]; + + PELOGE(limLog(pMac, LOGE, + FL("comeback later timer expired. sending MLM ASSOC req"));) + /* set MLM state such that ASSOC REQ packet will be sent out */ + psessionEntry->limPrevMlmState = pInfo->limPrevMlmState; + psessionEntry->limMlmState = pInfo->limMlmState; + limSendMlmAssocReq(pMac, psessionEntry); +} +#endif /* WLAN_FEATURE_11W */ + +/** + * limProcessMlmAuthCnf() + * + *FUNCTION: + * This function is called to processes MLM_AUTH_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAuthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tAniAuthType cfgAuthType, authMode; + tLimMlmAuthReq *pMlmAuthReq; + tLimMlmAuthCnf *pMlmAuthCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmAuthCnf = (tLimMlmAuthCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAuthCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d session does not exist"), + pMlmAuthCnf->sessionId);) + return; + } + + if (((psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE)) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + /** + * Should not have received AUTH confirm + * from MLM in other states or on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("SessionId:%d received unexpected MLM_AUTH_CNF in state %X"), + psessionEntry->peSessionId,psessionEntry->limSmeState);) + return; + } + /// Process AUTH confirm from MLM + if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != eSIR_SME_SUCCESS) + { + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, + (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS) + { + /** + * Could not get AuthType value from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthType value")); + } + } + else + cfgAuthType = pMac->lim.gLimPreAuthType; + + if ((cfgAuthType == eSIR_AUTO_SWITCH) && + (((tLimMlmAuthCnf *) pMsgBuf)->authType == eSIR_OPEN_SYSTEM) + && (eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS == ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode)) + { + /** + * When Open authentication fails with reason code "13" and + * authType set to 'auto switch', Try with Shared Authentication + */ + authMode = eSIR_SHARED_KEY; + // Trigger MAC based Authentication + pMlmAuthReq = vos_mem_malloc(sizeof(tLimMlmAuthReq)); + if ( NULL == pMlmAuthReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmAuthReq")); + return; + } + vos_mem_set((tANI_U8 *) pMlmAuthReq, sizeof(tLimMlmAuthReq), 0); + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId); + } + else + vos_mem_copy((tANI_U8 *) &pMlmAuthReq->peerMacAddr, + (tANI_U8 *) &pMac->lim.gLimPreAuthPeerAddr, + sizeof(tSirMacAddr)); + pMlmAuthReq->authType = authMode; + /* Update PE session Id*/ + pMlmAuthReq->sessionId = pMlmAuthCnf->sessionId; + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAuthReq->authFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + limPostMlmMessage(pMac, + LIM_MLM_AUTH_REQ, + (tANI_U32 *) pMlmAuthReq); + return; + } + else + { + // MAC based authentication failure + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + PELOGE(limLog(pMac, LOGE, FL("Auth Failure occurred."));) + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + /** + * Need to send Join response with + * auth failure to Host. + */ + limHandleSmeJoinResult(pMac, + ((tLimMlmAuthCnf *) pMsgBuf)->resultCode, ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode,psessionEntry); + } + else + { + /** + * Pre-authentication failure. + * Send Pre-auth failure response to host + */ + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + } + } // end if (cfgAuthType == eAUTO_SWITCH) + } // if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ... + else + { + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + limSendMlmAssocReq(pMac, psessionEntry); + } + else + { + /* Successful Pre-authentication. Send Pre-auth response to host */ + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, + TRACE_CODE_SME_STATE, + psessionEntry->peSessionId, + psessionEntry->limSmeState)); + } + } // end if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ... +} /*** end limProcessMlmAuthCnf() ***/ + +/** + * limProcessMlmAssocCnf() + * + *FUNCTION: + * This function is called to processes MLM_ASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAssocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry; + tLimMlmAssocCnf *pLimMlmAssocCnf; + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + pLimMlmAssocCnf = (tLimMlmAssocCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmAssocCnf->sessionId)) == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("SessionId:%d Session does not exist"), + pLimMlmAssocCnf->sessionId);) + return; + } + if (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE || + psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry ->limSystemRole == eLIM_BT_AMP_AP_ROLE) + { + /** + * Should not have received Assocication confirm + * from MLM in other states OR on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("SessionId:%d Received unexpected MLM_ASSOC_CNF in state %X"), + psessionEntry->peSessionId,psessionEntry->limSmeState);) + return; + } + if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != eSIR_SME_SUCCESS) + { + // Association failure + PELOG1(limLog(pMac, LOG1, FL("SessionId:%d Association failure"), + psessionEntry->peSessionId);) + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, pMac->lim.gLimSmeState)); + /** + * Need to send Join response with + * Association failure to Host. + */ + limHandleSmeJoinResult(pMac, + ((tLimMlmAssocCnf *) pMsgBuf)->resultCode, + ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry); + } // if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != ... + else + { + // Successful Association + PELOG1(limLog(pMac, LOG1, FL("SessionId:%d Associated with BSS"), + psessionEntry->peSessionId);) + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /** + * Need to send Join response with + * Association success to Host. + */ + limHandleSmeJoinResult(pMac, + ((tLimMlmAssocCnf *) pMsgBuf)->resultCode, + ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry); + } // end if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != .... +} /*** end limProcessMlmAssocCnf() ***/ + +/** + * limProcessMlmReassocCnf() + * + *FUNCTION: + * This function is called to processes MLM_REASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmReassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry; + tLimMlmReassocCnf *pLimMlmReassocCnf; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pLimMlmReassocCnf = (tLimMlmReassocCnf*) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmReassocCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE, FL("session Does not exist for given session Id"));) + return; + } + if ((psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + /** + * Should not have received Reassocication confirm + * from MLM in other states OR on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("Rcv unexpected MLM_REASSOC_CNF in role %d, sme state 0x%X"), + psessionEntry->limSystemRole, psessionEntry->limSmeState);) + return; + } + if (psessionEntry->pLimReAssocReq) { + vos_mem_free(psessionEntry->pLimReAssocReq); + psessionEntry->pLimReAssocReq = NULL; + } + + /* Upon Reassoc success or failure, freeup the cached + * preauth request, to ensure that channel switch is now + * allowed following any change in HT params. + */ + if (psessionEntry->ftPEContext.pFTPreAuthReq) { + limLog(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"), + psessionEntry->ftPEContext.pFTPreAuthReq); + if (psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { + vos_mem_free( + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription); + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); + psessionEntry->ftPEContext.pFTPreAuthReq = NULL; + psessionEntry->ftPEContext.ftPreAuthSession = VOS_FALSE; + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:Re-set the LIM Ctxt Roam Synch In Progress"); + psessionEntry->bRoamSynchInProgress = VOS_FALSE; + } + +#endif + + PELOG1(limLog(pMac, LOG1, FL("Rcv MLM_REASSOC_CNF with result code %d"), pLimMlmReassocCnf->resultCode);) + if (pLimMlmReassocCnf->resultCode == eSIR_SME_SUCCESS) { + // Successful Reassociation + /* change logging before release */ + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "*** Reassociated with new BSS ***"); + + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /** + * Need to send Reassoc response with + * Reassociation success to Host. + */ + limSendSmeJoinReassocRsp( + pMac, eWNI_SME_REASSOC_RSP, + pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); + }else if (pLimMlmReassocCnf->resultCode == eSIR_SME_REASSOC_REFUSED) { + /** Reassociation failure With the New AP + * but we still have the link with the Older AP + */ + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /** + * Need to send Reassoc response with + * Association failure to Host. + */ + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); + }else { + // Reassociation failure + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /** + * Need to send Reassoc response with + * Association failure to Host. + */ + limHandleSmeReaasocResult(pMac, pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode, psessionEntry); + } +} /*** end limProcessMlmReassocCnf() ***/ + +/** + * limProcessMlmReassocInd() + * + *FUNCTION: + * This function is called to processes MLM_REASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmReassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tSirMsgQ msgQ; + tSirSmeReassocInd *pSirSmeReassocInd; + tpDphHashNode pStaDs=0; + tpPESession psessionEntry; + tANI_U8 sessionId; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + if((psessionEntry = peFindSessionByBssid(pMac,((tpLimMlmReassocInd)pMsgBuf)->peerMacAddr, &sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + return; + } + /// Inform Host of STA reassociation + len = sizeof(tSirSmeReassocInd); + pSirSmeReassocInd = vos_mem_malloc(len); + if ( NULL == pSirSmeReassocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_REASSOC_IND")); + return; + + } + sirStoreU16N((tANI_U8 *) &pSirSmeReassocInd->messageType, + eWNI_SME_REASSOC_IND); + limReassocIndSerDes(pMac, (tpLimMlmReassocInd) pMsgBuf, + (tANI_U8 *) &(pSirSmeReassocInd->length), psessionEntry); + + // Required for indicating the frames to upper layer + pSirSmeReassocInd->assocReqLength = ((tpLimMlmReassocInd) pMsgBuf)->assocReqLength; + pSirSmeReassocInd->assocReqPtr = ((tpLimMlmReassocInd) pMsgBuf)->assocReqPtr; + pSirSmeReassocInd->beaconPtr = psessionEntry->beacon; + pSirSmeReassocInd->beaconLength = psessionEntry->bcnLen; + + msgQ.type = eWNI_SME_REASSOC_IND; + msgQ.bodyptr = pSirSmeReassocInd; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + pStaDs = dphGetHashEntry(pMac, ((tpLimMlmReassocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable); + if (! pStaDs) + { + limLog( pMac, LOGP, FL("MLM ReAssocInd: Station context no longer valid (aid %d)"), + ((tpLimMlmReassocInd) pMsgBuf)->aid); + vos_mem_free(pSirSmeReassocInd); + return; + } + + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); + PELOG1(limLog(pMac, LOG1, + FL("Create CNF_WAIT_TIMER after received LIM_MLM_REASSOC_IND"));) + /* + ** turn on a timer to detect the loss of REASSOC CNF + **/ + limActivateCnfTimer(pMac, + (tANI_U16) ((tpLimMlmReassocInd) pMsgBuf)->aid, psessionEntry); +} /*** end limProcessMlmReassocInd() ***/ + +/** + * limProcessMlmAuthInd() + * + *FUNCTION: + * This function is called to processes MLM_AUTH_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAuthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msgQ; + tSirSmeAuthInd *pSirSmeAuthInd; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pSirSmeAuthInd = vos_mem_malloc(sizeof(tSirSmeAuthInd)); + if ( NULL == pSirSmeAuthInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_AUTH_IND")); + } + limCopyU16((tANI_U8 *) &pSirSmeAuthInd->messageType, eWNI_SME_AUTH_IND); + limAuthIndSerDes(pMac, (tpLimMlmAuthInd) pMsgBuf, + (tANI_U8 *) &(pSirSmeAuthInd->length)); + msgQ.type = eWNI_SME_AUTH_IND; + msgQ.bodyptr = pSirSmeAuthInd; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_AUTH_IND_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); +} /*** end limProcessMlmAuthInd() ***/ + + + + +void +limFillAssocIndParams(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd, + tSirSmeAssocInd *pSirSmeAssocInd, + tpPESession psessionEntry) +{ + pSirSmeAssocInd->length = sizeof(tSirSmeAssocInd); + pSirSmeAssocInd->sessionId = psessionEntry->smeSessionId; + + // Required for indicating the frames to upper layer + pSirSmeAssocInd->assocReqLength = pAssocInd->assocReqLength; + pSirSmeAssocInd->assocReqPtr = pAssocInd->assocReqPtr; + + pSirSmeAssocInd->beaconPtr = psessionEntry->beacon; + pSirSmeAssocInd->beaconLength = psessionEntry->bcnLen; + + // Fill in peerMacAddr + vos_mem_copy(pSirSmeAssocInd->peerMacAddr, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + + // Fill in aid + pSirSmeAssocInd->aid = pAssocInd->aid; + // Fill in bssId + vos_mem_copy(pSirSmeAssocInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + // Fill in authType + pSirSmeAssocInd->authType = pAssocInd->authType; + // Fill in ssId + vos_mem_copy((tANI_U8*)&pSirSmeAssocInd->ssId, + (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1); + pSirSmeAssocInd->rsnIE.length = pAssocInd->rsnIE.length; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->rsnIE.rsnIEdata, + (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata), + pAssocInd->rsnIE.length); + + pSirSmeAssocInd->addIE.length = pAssocInd->addIE.length; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->addIE.addIEdata, + (tANI_U8 *) &(pAssocInd->addIE.addIEdata), + pAssocInd->addIE.length); + + // Copy the new TITAN capabilities + pSirSmeAssocInd->spectrumMgtIndicator = pAssocInd->spectrumMgtIndicator; + if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE) + { + pSirSmeAssocInd->powerCap.minTxPower = pAssocInd->powerCap.minTxPower; + pSirSmeAssocInd->powerCap.maxTxPower = pAssocInd->powerCap.maxTxPower; + pSirSmeAssocInd->supportedChannels.numChnl = pAssocInd->supportedChannels.numChnl; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->supportedChannels.channelList, + (tANI_U8 *) &(pAssocInd->supportedChannels.channelList), + pAssocInd->supportedChannels.numChnl); + } + vos_mem_copy(&pSirSmeAssocInd->chan_info, &pAssocInd->chan_info, + sizeof(tSirSmeChanInfo)); + // Fill in WmmInfo + pSirSmeAssocInd->wmmEnabledSta = pAssocInd->WmmStaInfoPresent; +} /*** end limAssocIndSerDes() ***/ + + + +/** + * limProcessMlmAssocInd() + * + *FUNCTION: + * This function is called to processes MLM_ASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAssocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tSirMsgQ msgQ; + tSirSmeAssocInd *pSirSmeAssocInd; + tpDphHashNode pStaDs=0; + tpPESession psessionEntry; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + if((psessionEntry = peFindSessionBySessionId(pMac,((tpLimMlmAssocInd) pMsgBuf)->sessionId))== NULL) + { + limLog( pMac, LOGE, FL( "Session Does not exist for given sessionId" )); + return; + } + /// Inform Host of STA association + len = sizeof(tSirSmeAssocInd); + pSirSmeAssocInd = vos_mem_malloc(len); + if ( NULL == pSirSmeAssocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_ASSOC_IND")); + return; + } + + pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND; + limFillAssocIndParams(pMac, (tpLimMlmAssocInd) pMsgBuf, pSirSmeAssocInd, psessionEntry); + msgQ.type = eWNI_SME_ASSOC_IND; + msgQ.bodyptr = pSirSmeAssocInd; + msgQ.bodyval = 0; + pStaDs = dphGetHashEntry(pMac, + ((tpLimMlmAssocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable); + if (! pStaDs) + { // good time to panic... + limLog(pMac, LOGE, FL("MLM AssocInd: Station context no longer valid (aid %d)"), + ((tpLimMlmAssocInd) pMsgBuf)->aid); + vos_mem_free(pSirSmeAssocInd); + + return; + } + pSirSmeAssocInd->staId = pStaDs->staIndex; + pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType; + pSirSmeAssocInd->timingMeasCap = pStaDs->timingMeasCap; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); + + PELOG1(limLog(pMac, LOG1, + FL("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND"));) + /* + ** turn on a timer to detect the loss of ASSOC CNF + **/ + limActivateCnfTimer(pMac, (tANI_U16) ((tpLimMlmAssocInd) pMsgBuf)->aid, psessionEntry); + +// Enable this Compile flag to test the BT-AMP -AP assoc sequence +#ifdef TEST_BTAMP_AP +//tANI_U32 *pMsgBuf; +{ + tpSirSmeAssocCnf pSmeAssoccnf; + pSmeAssoccnf = vos_mem_malloc(sizeof(tSirSmeAssocCnf)); + if ( NULL == pSmeAssoccnf ) + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for pSmeAssoccnf "));) + pSmeAssoccnf->messageType = eWNI_SME_ASSOC_CNF; + pSmeAssoccnf->length = sizeof(tSirSmeAssocCnf); + vos_mem_copy(pSmeAssoccnf->peerMacAddr, + ((tpLimMlmAssocInd)pMsgBuf)->peerMacAddr, 6); + pSmeAssoccnf->statusCode = eSIR_SME_SUCCESS; + pSmeAssoccnf->aid = ((tpLimMlmAssocInd)pMsgBuf)->aid; + vos_mem_copy(pSmeAssoccnf->alternateBssId, + pSmeAssoccnf->peerMacAddr, sizeof(tSirMacAddr)); + pSmeAssoccnf->alternateChannelId = 6; + vos_mem_copy(pSmeAssoccnf->bssId, psessionEntry->selfMacAddr, 6); + pMsgBuf = (tANI_U32)pSmeAssoccnf; + __limProcessSmeAssocCnfNew(pMac, eWNI_SME_ASSOC_CNF, pMsgBuf); + vos_mem_free(pSmeAssoccnf); +} +#endif + + +} /*** end limProcessMlmAssocInd() ***/ + + + + +/** + * limProcessMlmDisassocInd() + * + *FUNCTION: + * This function is called to processes MLM_DISASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDisassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDisassocInd *pMlmDisassocInd; + tpPESession psessionEntry; + pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf; + if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocInd->sessionId) )== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + break; + default: // eLIM_AP_ROLE //eLIM_BT_AMP_AP_ROLE + PELOG1(limLog(pMac, LOG1, + FL("*** Peer staId=%d Disassociated ***"), + pMlmDisassocInd->aid);) + // Send SME_DISASOC_IND after Polaris cleanup + // (after receiving LIM_MLM_PURGE_STA_IND) + break; + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmDisassocInd() ***/ + +/** + * limProcessMlmDisassocCnf() + * + *FUNCTION: + * This function is called to processes MLM_DISASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tLimMlmDisassocCnf *pMlmDisassocCnf; + tpPESession psessionEntry; + pMlmDisassocCnf = (tLimMlmDisassocCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id"));) + return; + } + resultCode = (tSirResultCodes) + (pMlmDisassocCnf->disassocTrigger == + eLIM_LINK_MONITORING_DISASSOC) ? + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : + pMlmDisassocCnf->resultCode; + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Disassociate Confirm from MLM + if ( (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) ) + { + /** + * Should not have received + * Disassocate confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_DISASSOC_CNF in state %X"),psessionEntry->limSmeState);) + return; + } + if (pMac->lim.gLimRspReqd) + pMac->lim.gLimRspReqd = false; + if (pMlmDisassocCnf->disassocTrigger == + eLIM_PROMISCUOUS_MODE_DISASSOC) + { + if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS) + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + else + psessionEntry->limSmeState = eLIM_SME_OFFLINE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + } + else + { + if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS) + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + else + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr, + resultCode, + pMlmDisassocCnf->disassocTrigger, + pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } + } + else if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr, + resultCode, + pMlmDisassocCnf->disassocTrigger, + pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } +} /*** end limProcessMlmDisassocCnf() ***/ + +/** + * limProcessMlmDeauthInd() + * + *FUNCTION: + * This function is called to processes MLM_DEAUTH_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDeauthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDeauthInd *pMlmDeauthInd; + tpPESession psessionEntry; + tANI_U8 sessionId; + pMlmDeauthInd = (tLimMlmDeauthInd *) pMsgBuf; + if((psessionEntry = peFindSessionByBssid(pMac,pMlmDeauthInd->peerMacAddr,&sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + return; + } + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + default: // eLIM_AP_ROLE + { + PELOG1(limLog(pMac, LOG1, + FL("*** Received Deauthentication from staId=%d ***"), + pMlmDeauthInd->aid);) + } + // Send SME_DEAUTH_IND after Polaris cleanup + // (after receiving LIM_MLM_PURGE_STA_IND) + break; + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmDeauthInd() ***/ + +/** + * limProcessMlmDeauthCnf() + * + *FUNCTION: + * This function is called to processes MLM_DEAUTH_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDeauthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirResultCodes resultCode; + tLimMlmDeauthCnf *pMlmDeauthCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given session Id "));) + return; + } + + resultCode = (tSirResultCodes) + (pMlmDeauthCnf->deauthTrigger == + eLIM_LINK_MONITORING_DEAUTH) ? + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : + pMlmDeauthCnf->resultCode; + aid = (psessionEntry->limSystemRole == eLIM_AP_ROLE) ? + pMlmDeauthCnf->aid : 1; + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Deauth Confirm from MLM + if (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) + { + /** + * Should not have received Deauth confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_DEAUTH_CNF in state %X"), + psessionEntry->limSmeState);) + return; + } + if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) + { + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + PELOG1(limLog(pMac, LOG1, + FL("*** Deauthenticated with BSS ***"));) + } + else + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + if (pMac->lim.gLimRspReqd) + pMac->lim.gLimRspReqd = false; + } + // On STA or on BASIC AP, send SME_DEAUTH_RSP to host + limSendSmeDeauthNtf(pMac, pMlmDeauthCnf->peerMacAddr, + resultCode, + pMlmDeauthCnf->deauthTrigger, + aid,psessionEntry->smeSessionId,psessionEntry->transactionId); +} /*** end limProcessMlmDeauthCnf() ***/ + +/** + * limProcessMlmPurgeStaInd() + * + *FUNCTION: + * This function is called to processes MLM_PURGE_STA_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmPurgeStaInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tpLimMlmPurgeStaInd pMlmPurgeStaInd; + tpPESession psessionEntry; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmPurgeStaInd->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + return; + } + // Purge STA indication from MLM + resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode; + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + default: // eLIM_AP_ROLE + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) && + (psessionEntry->limSmeState != + eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + /** + * Should not have received + * Purge STA indication + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_PURGE_STA_IND in state %X"), + psessionEntry->limSmeState);) + break; + } + PELOG1(limLog(pMac, LOG1, + FL("*** Polaris cleanup completed for staId=%d ***"), + pMlmPurgeStaInd->aid);) + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + } + if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) + { + limSendSmeDeauthNtf(pMac, + pMlmPurgeStaInd->peerMacAddr, + resultCode, + pMlmPurgeStaInd->purgeTrigger, + pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId); + } + else + limSendSmeDisassocNtf(pMac, + pMlmPurgeStaInd->peerMacAddr, + resultCode, + pMlmPurgeStaInd->purgeTrigger, + pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmPurgeStaInd() ***/ + +/** + * limProcessMlmSetKeysCnf() + * + *FUNCTION: + * This function is called to processes MLM_SETKEYS_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmSetKeysCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // Prepare and send SME_SETCONTEXT_RSP message + tLimMlmSetKeysCnf *pMlmSetKeysCnf; + tpPESession psessionEntry; + tANI_U16 aid; + tpDphHashNode pStaDs; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf; + if ((psessionEntry = peFindSessionBySessionId(pMac, pMlmSetKeysCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId "));) + return; + } + psessionEntry->isKeyInstalled = 0; + limLog( pMac, LOG1, + FL("Received MLM_SETKEYS_CNF with resultCode = %d"), + pMlmSetKeysCnf->resultCode ); + /* if the status is success keys are installed in the + * Firmware so we can set the protection bit + */ + if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) { + psessionEntry->isKeyInstalled = 1; + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) { + pStaDs = dphLookupHashEntry(pMac, pMlmSetKeysCnf->peerMacAddr, &aid, + &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + pStaDs->isKeyInstalled = 1; + } + } + limSendSmeSetContextRsp(pMac, + pMlmSetKeysCnf->peerMacAddr, + 1, + (tSirResultCodes) pMlmSetKeysCnf->resultCode,psessionEntry,psessionEntry->smeSessionId, + psessionEntry->transactionId); +} /*** end limProcessMlmSetKeysCnf() ***/ +/** + * limProcessMlmRemoveKeyCnf() + * + *FUNCTION: + * This function is called to processes MLM_REMOVEKEY_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // Prepare and send SME_REMOVECONTEXT_RSP message + tLimMlmRemoveKeyCnf *pMlmRemoveKeyCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmRemoveKeyCnf = (tLimMlmRemoveKeyCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id"));) + return; + } + limLog( pMac, LOG1, + FL("Received MLM_REMOVEKEYS_CNF with resultCode = %d"), + pMlmRemoveKeyCnf->resultCode ); + limSendSmeRemoveKeyRsp(pMac, + pMlmRemoveKeyCnf->peerMacAddr, + (tSirResultCodes) pMlmRemoveKeyCnf->resultCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); +} /*** end limProcessMlmRemoveKeyCnf() ***/ + + +/** + * limHandleSmeJoinResult() + * + *FUNCTION: + * This function is called to process join/auth/assoc failures + * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or + * MLM_ASSOC_CNF with a success code in case of STA role and + * MLM_JOIN_CNF with success in case of STA in IBSS role. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param resultCode Failure code to be sent + * + * + * @return None + */ +static void +limHandleSmeJoinResult(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + /* Newly Added on oct 11 th*/ + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("psessionEntry is NULL "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */ + if(resultCode != eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_JOIN_FAILURE; + pStaDs->mlmStaContext.resultCode = resultCode; + pStaDs->mlmStaContext.protStatusCode = protStatusCode; + //Done: 7-27-2009. JIM_FIX_ME: at the end of limCleanupRxPath, make sure PE is sending eWNI_SME_JOIN_RSP to SME + limCleanupRxPath(pMac, pStaDs, psessionEntry); + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + return; + } + } + + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + //Delete teh session if JOIN failure occurred. + if(resultCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + if(limSetLinkState(pMac, eSIR_LINK_DOWN_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the DownState."));) + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState."));) + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, resultCode, protStatusCode,psessionEntry, + smesessionId, smetransactionId); +} /*** end limHandleSmeJoinResult() ***/ + +/** + * limHandleSmeReaasocResult() + * + *FUNCTION: + * This function is called to process reassoc failures + * upon receiving REASSOC_CNF with a failure code or + * MLM_REASSOC_CNF with a success code in case of STA role + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param resultCode Failure code to be sent + * + * + * @return None + */ +static void +limHandleSmeReaasocResult(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("psessionEntry is NULL "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */ + if(resultCode != eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_JOIN_FAILURE; + pStaDs->mlmStaContext.resultCode = resultCode; + pStaDs->mlmStaContext.protStatusCode = protStatusCode; + limCleanupRxPath(pMac, pStaDs, psessionEntry); + return; + } + } + + //Delete teh session if REASSOC failure occurred. + if(resultCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, resultCode, protStatusCode,psessionEntry, + smesessionId, smetransactionId); +} /*** end limHandleSmeReassocResult() ***/ + +/** + * limProcessMlmAddStaRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_STA_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry ) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry); + return; + } + limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry); +} +void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmAssocCnf mlmAssocCnf; + tpDphHashNode pStaDs; + tANI_U32 mesgType = LIM_MLM_ASSOC_CNF; + tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr; + tpPESession pftSessionEntry = NULL; + tANI_U8 ftSessionId; + + if(NULL == pAddStaParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + return; + } + + if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + { + mesgType = LIM_MLM_REASSOC_CNF; + } + + if (true == psessionEntry->fDeauthReceived) + { + PELOGE(limLog(pMac, LOGE, + FL("Received Deauth frame in ADD_STA_RESP state"));) + pAddStaParams->status = eHAL_STATUS_FAILURE; + } + + if ( eHAL_STATUS_SUCCESS == pAddStaParams->status ) + { + if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != psessionEntry->limMlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, + FL( "Received unexpected WDA_ADD_STA_RSP in state %X" ), + psessionEntry->limMlmState); + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + goto end; + } + if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + // Check if we have keys (PTK) to install in case of 11r + tpftPEContext pftPECntxt = &psessionEntry->ftPEContext; + pftSessionEntry = peFindSessionByBssid(pMac, + psessionEntry->limReAssocbssId, + &ftSessionId); + if (pftSessionEntry != NULL && + pftPECntxt->PreAuthKeyInfo.extSetStaKeyParamValid == TRUE) + { + tpLimMlmSetKeysReq pMlmStaKeys = &pftPECntxt->PreAuthKeyInfo.extSetStaKeyParam; + limSendSetStaKeyReq(pMac, pMlmStaKeys, 0, 0, pftSessionEntry, FALSE); + pftPECntxt->PreAuthKeyInfo.extSetStaKeyParamValid = FALSE; + } +#endif + } + // + // Update the DPH Hash Entry for this STA + // with proper state info + // + pStaDs = dphGetHashEntry( pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if( NULL != pStaDs) + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + else + limLog( pMac, LOGW, + FL( "Unable to get the DPH Hash Entry for AID - %d" ), + DPH_STA_HASH_INDEX_PEER); + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + /* + * Storing the self StaIndex(Generated by HAL) in session context, + * instead of storing it in DPH Hash entry for Self STA. + * DPH entry for the self STA stores the sta index for the BSS entry + * to which the STA is associated. + */ + psessionEntry->staId = pAddStaParams->staIdx; + //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) +#endif + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_KEEPALIVE_TIMER)); + + //assign the sessionId to the timer Object + pMac->lim.limTimers.gLimKeepaliveTimer.sessionId = psessionEntry->peSessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gLimKeepaliveTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Cannot activate keepalive timer.")); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumLinkEsts++; +#endif +#ifdef FEATURE_WLAN_TDLS + /* initialize TDLS peer related data */ + limInitTdlsData(pMac,psessionEntry); +#endif + // Return Assoc confirm to SME with success + // FIXME_GEN4 - Need the correct ASSOC RSP code to + // be passed in here.... + //mlmAssocCnf.resultCode = (tSirResultCodes) assoc.statusCode; + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "ADD_STA failed!")); + if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + mlmAssocCnf.resultCode = (tSirResultCodes)eSIR_SME_FT_REASSOC_FAILURE; + else + mlmAssocCnf.resultCode = (tSirResultCodes)eSIR_SME_REFUSED; + } +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddStaParams); + limMsgQ->bodyptr = NULL; + } + /* Updating PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf ); + if (true == psessionEntry->fDeauthReceived) + { + psessionEntry->fDeauthReceived = false; + } + return; +} +void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pMac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0; + + if (((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) && + (psessionEntry->statypeForBss == STA_ENTRY_SELF)) + { + limProcessBtAmpApMlmDelBssRsp(pMac, limMsgQ,psessionEntry); + return; + } + limProcessStaMlmDelBssRsp(pMac, limMsgQ,psessionEntry); + + if(!limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(FALSE); + } + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + if ( eSIR_SUCCESS != limSendExcludeUnencryptInd(pMac, TRUE, psessionEntry) ) + { + limLog( pMac, LOGE, + FL( "Could not send down Exclude Unencrypted Indication!" ) ); + } + } +#endif +} + +void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + + if (NULL == pDelBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pDelBssParams->status ) + { + PELOGW(limLog( pMac, LOGW, + FL( "STA received the DEL_BSS_RSP for BSSID: %X."),pDelBssParams->bssIdx);) + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + + { + PELOGE(limLog( pMac, LOGE, FL( "Failure in setting link state to IDLE"));) + statusCode = eSIR_SME_REFUSED; + goto end; + } + if(pStaDs == NULL) + { + limLog( pMac, LOGE, FL( "DPH Entry for STA 1 missing.")); + statusCode = eSIR_SME_REFUSED; + goto end; + } + if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + PELOGE(limLog( pMac, LOGE, FL( "Received unexpected WDA_DEL_BSS_RSP in state %X" ), + pStaDs->mlmStaContext.mlmState);) + statusCode = eSIR_SME_REFUSED; + goto end; + } + PELOG1(limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId ); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + } + else + { + limLog( pMac, LOGE, FL( "DEL BSS failed!" ) ); + statusCode = eSIR_SME_STOP_BSS_FAILURE; + } + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelBssParams); + limMsgQ->bodyptr = NULL; + } + if(pStaDs == NULL) + return; + if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE && + psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) && + pStaDs->mlmStaContext.cleanupTrigger != eLIM_JOIN_FAILURE) + { + /** The Case where the DelBss is invoked from + * context of other than normal DisAssoc / Deauth OR + * as part of Join Failure. + */ + limHandleDelBssInReAssocContext(pMac, pStaDs,psessionEntry); + return; + } + limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry); + return; +} + +void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tSirResultCodes rc = eSIR_SME_SUCCESS; + tSirRetStatus status; + tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if(psessionEntry == NULL) + { + limLog(pMac, LOGE,FL("Session entry passed is NULL")); + if(pDelBss != NULL) + { + vos_mem_free(pDelBss); + limMsgQ->bodyptr = NULL; + } + return; + } + + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!"));) + rc = eSIR_SME_REFUSED; + goto end; + } + pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState) + { + limLog( pMac, LOGE, + FL( "Received unexpected WDA_DEL_BSS_RSP in state %X" ), + psessionEntry->limMlmState); + rc = eSIR_SME_REFUSED; + goto end; + } + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx); + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + status = limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + psessionEntry->selfMacAddr, NULL, NULL); + if (status != eSIR_SUCCESS) + { + rc = eSIR_SME_REFUSED; + goto end; + } + /** Softmac may send all the buffered packets right after resuming the transmission hence + * to occupy the medium during non channel occupancy period. So resume the transmission after + * HAL gives back the response. + */ + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);//TBD-RAJESH is it needed ? + limDeletePreAuthList(pMac); + //Initialize number of associated stations during cleanup + psessionEntry->gLimNumOfCurrentSTAs = 0; + end: + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc, psessionEntry->smeSessionId, psessionEntry->transactionId); + peDeleteSession(pMac, psessionEntry); + + if(pDelBss != NULL) + { + vos_mem_free(pDelBss); + limMsgQ->bodyptr = NULL; + } +} + +void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + + tpPESession psessionEntry; + tpDeleteStaParams pDeleteStaParams; + pDeleteStaParams = (tpDeleteStaParams)limMsgQ->bodyptr; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(NULL == pDeleteStaParams || + NULL == (psessionEntry = peFindSessionBySessionId(pMac, pDeleteStaParams->sessionId))) + { + limLog(pMac, LOGP,FL("Session Does not exist or invalid body pointer in message")); + if(pDeleteStaParams != NULL) + { + vos_mem_free(pDeleteStaParams); + limMsgQ->bodyptr = NULL; + } + return; + } + + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + limProcessBtAmpApMlmDelStaRsp(pMac,limMsgQ,psessionEntry); + return; + } + limProcessStaMlmDelStaRsp(pMac, limMsgQ,psessionEntry); +} + +void limProcessBtAmpApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs; + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + if(limMsgQ->bodyptr == NULL) + { + return; + } + + pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId, &psessionEntry->dph.dphHashTable); + if(pStaDs == NULL) + { + limLog( pMac, LOGE, + FL( "DPH Entry for STA %X missing."), pDelStaParams->assocId); + statusCode = eSIR_SME_REFUSED; + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + + return; + } + if( eHAL_STATUS_SUCCESS == pDelStaParams->status ) + { + limLog( pMac, LOGW, + FL( "AP received the DEL_STA_RSP for assocID: %X."), pDelStaParams->assocId); + + if(( eLIM_MLM_WT_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) && + ( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)) + { + limLog( pMac, LOGE, + FL( "Received unexpected WDA_DEL_STA_RSP in state %s for staId %d assocId %d " ), + limMlmStateStr(pStaDs->mlmStaContext.mlmState), pStaDs->staIndex, pStaDs->assocId); + statusCode = eSIR_SME_REFUSED; + goto end; + } + + limLog( pMac, LOG1, + FL("Deleted STA AssocID %d staId %d MAC "), + pStaDs->assocId, pStaDs->staIndex); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == pStaDs->mlmStaContext.mlmState) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, + FL("could not Add STA with assocId=%d"), + pStaDs->assocId);) + // delete the TS if it has already been added. + // send the response with error status. + if(pStaDs->qos.addtsPresent) + { + tpLimTspecInfo pTspecInfo; + if(eSIR_SUCCESS == limTspecFindByAssocId(pMac, pStaDs->assocId, + &pStaDs->qos.addts.tspec, &pMac->lim.tspecInfo[0], &pTspecInfo)) + { + limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo, + NULL, &pTspecInfo->idx); + } + } + limRejectAssociation(pMac, + pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + } + return; + } + } + else + { + limLog( pMac, LOGW, + FL( "DEL STA failed!" )); + statusCode = eSIR_SME_REFUSED; + } + end: + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry); + } + return; +} + +void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = NULL; + if(NULL == pDelStaParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + goto end; + } + if( eHAL_STATUS_SUCCESS == pDelStaParams->status ) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing."), + pDelStaParams->assocId); + statusCode = eSIR_SME_REFUSED; + goto end; + } + if( eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ), + limMlmStateStr(psessionEntry->limMlmState)); + statusCode = eSIR_SME_REFUSED; + goto end; + } + PELOG1(limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId ); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + limLog( pMac, LOGW, FL( "DEL_STA_RSP received for assocID: %X"), pDelStaParams->assocId); + //we must complete all cleanup related to delSta before calling limDelBSS. + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + } + statusCode = (tSirResultCodes) limDelBss(pMac, pStaDs, 0,psessionEntry); + return; + } + else + { + limLog( pMac, LOGE, FL( "DEL_STA failed for sta Id %d" ), pDelStaParams->staIdx); + statusCode = eSIR_SME_REFUSED; + } +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + } + return; +} + +void limProcessBtAmpApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = NULL; + + if (NULL == pAddStaParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + + pStaDs = dphGetHashEntry(pMac, pAddStaParams->assocId, &psessionEntry->dph.dphHashTable); + if(pStaDs == NULL) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing."), pAddStaParams->assocId); + goto end; + } + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + //TODO: any check for pMac->lim.gLimMlmState ? + if( eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, + FL( "Received unexpected WDA_ADD_STA_RSP in state %X" ), + pStaDs->mlmStaContext.mlmState); + goto end; + } + if(eHAL_STATUS_SUCCESS != pAddStaParams->status) + { + PELOGE(limLog(pMac, LOGE, FL("Error! rcvd delSta rsp from HAL with status %d"),pAddStaParams->status);) + limRejectAssociation(pMac, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + goto end; + } + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state + pStaDs->valid = 1; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE; + limLog( pMac, LOG1, + FL("STA AssocID %d staId %d MAC "), + pStaDs->assocId, + pStaDs->staIndex); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + + /* For BTAMP-AP, the flow sequence shall be: + * 1) PE sends eWNI_SME_ASSOC_IND to SME + * 2) PE receives eWNI_SME_ASSOC_CNF from SME + * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA + */ + limSendMlmAssocInd(pMac, pStaDs, psessionEntry); + // fall though to reclaim the original Add STA Response message +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddStaParams); + limMsgQ->bodyptr = NULL; + } + return; +} + +/** + * limProcessApMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Init other remaining LIM variables + * > Init the AID pool, for that BSSID + * > Init the Pre-AUTH list, for that BSSID + * > Create LIM timers, specific to that BSSID + * > Init DPH related parameters that are specific to that BSSID + * > TODO - When do we do the actual change channel? + * + *LOGIC: + * SME sends eWNI_SME_START_BSS_REQ to LIM + * LIM sends LIM_MLM_START_REQ to MLME + * MLME sends WDA_ADD_BSS_REQ to HAL + * HAL responds with WDA_ADD_BSS_RSP to MLME + * MLME responds with LIM_MLM_START_CNF to LIM + * LIM responds with eWNI_SME_START_BSS_RSP to SME + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessApMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ) +{ + tLimMlmStartCnf mlmStartCnf; + tANI_U32 val; + tpPESession psessionEntry; + tANI_U8 isWepEnabled = FALSE; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + if(NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + goto end; + } + //TBD: free the memory before returning, do it for all places where lookup fails. + if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + if( NULL != pAddBssParams ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + return; + } + /* Update PE session Id*/ + mlmStartCnf.sessionId = pAddBssParams->sessionId; + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + PELOG2(limLog(pMac, LOG2, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS"));) + if (limSetLinkState(pMac, eSIR_LINK_AP_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE; + psessionEntry->chainMask = pAddBssParams->chainMask; + psessionEntry->smpsMode = pAddBssParams->smpsMode; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if( eSIR_IBSS_MODE == pAddBssParams->bssType ) + { + /** IBSS is 'active' when we receive + * Beacon frames from other STAs that are part of same IBSS. + * Mark internal state as inactive until then. + */ + psessionEntry->limIbssActive = false; + psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know session created for self/peer + limResetHBPktCount( psessionEntry ); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + } + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + + if ( eSIR_INFRA_AP_MODE == pAddBssParams->bssType ) + psessionEntry->limSystemRole = eLIM_AP_ROLE; + else + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + schEdcaProfileUpdate(pMac, psessionEntry); + limInitPreAuthList(pMac); + /* Check the SAP security configuration.If configured to + * WEP then max clients supported is 16 + */ + if (psessionEntry->privacy) + { + if ((psessionEntry->gStartBssRSNIe.present) || (psessionEntry->gStartBssWPAIe.present)) + limLog(pMac, LOG1, FL("WPA/WPA2 SAP configuration\n")); + else + { + if (pMac->lim.gLimAssocStaLimit > MAX_SUPPORTED_PEERS_WEP) + { + limLog(pMac, LOG1, FL("WEP SAP Configuration\n")); + pMac->lim.gLimAssocStaLimit = MAX_SUPPORTED_PEERS_WEP; + isWepEnabled = TRUE; + } + } + } + limInitPeerIdxpool(pMac,psessionEntry); + + // Start OLBC timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("tx_timer_activate failed")); + } + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + + /* In limApplyConfiguration gLimAssocStaLimit is assigned from cfg. + * So update the value to 16 in case SoftAP is configured in WEP. + */ + if ((pMac->lim.gLimAssocStaLimit > MAX_SUPPORTED_PEERS_WEP) && (isWepEnabled)) + pMac->lim.gLimAssocStaLimit = MAX_SUPPORTED_PEERS_WEP; + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ),pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + + +/** + * limProcessIbssMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Init other remaining LIM variables + * > Init the AID pool, for that BSSID + * > Init the Pre-AUTH list, for that BSSID + * > Create LIM timers, specific to that BSSID + * > Init DPH related parameters that are specific to that BSSID + * > TODO - When do we do the actual change channel? + * + *LOGIC: + * SME sends eWNI_SME_START_BSS_REQ to LIM + * LIM sends LIM_MLM_START_REQ to MLME + * MLME sends WDA_ADD_BSS_REQ to HAL + * HAL responds with WDA_ADD_BSS_RSP to MLME + * MLME responds with LIM_MLM_START_CNF to LIM + * LIM responds with eWNI_SME_START_BSS_RSP to SME + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessIbssMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmStartCnf mlmStartCnf; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tANI_U32 val; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + PELOG1(limLog(pMac, LOG1, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS"));) + if (limSetLinkState(pMac, eSIR_LINK_IBSS_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + /** IBSS is 'active' when we receive + * Beacon frames from other STAs that are part of same IBSS. + * Mark internal state as inactive until then. + */ + psessionEntry->limIbssActive = false; + limResetHBPktCount( psessionEntry ); + /* Timer related functions are not modified for BT-AMP : To be Done */ + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + psessionEntry->statypeForBss = STA_ENTRY_SELF; + schEdcaProfileUpdate(pMac, psessionEntry); + if (0 == psessionEntry->freePeerIdxHead) + limInitPeerIdxpool(pMac,psessionEntry); + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + //If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM + if(true == pMac->lim.gLimIbssCoalescingHappened) + { + limIbssAddBssRspWhenCoalescing(pMac, limMsgQ->bodyptr, psessionEntry); + goto end; + } + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ), + pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + //Send this message to SME, when ADD_BSS is initiated by SME + //If ADD_BSS is done as part of coalescing, this won't happen. + /* Update PE session Id*/ + mlmStartCnf.sessionId =psessionEntry->peSessionId; + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + +static void +limProcessStaMlmAddBssRspPreAssoc( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry ) +{ + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tAniAuthType cfgAuthType, authMode; + tLimMlmAuthReq *pMlmAuthReq; + tpDphHashNode pStaDs = NULL; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto joinFailure; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->staContext.staMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE); + goto joinFailure; + } + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + // Trigger Authentication with AP + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, + (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS) + { + /** + * Could not get AuthType from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthType")); + } + if (cfgAuthType == eSIR_AUTO_SWITCH) + authMode = eSIR_OPEN_SYSTEM; // Try Open Authentication first + else + authMode = cfgAuthType; + + // Trigger MAC based Authentication + pMlmAuthReq = vos_mem_malloc(sizeof(tLimMlmAuthReq)); + if ( NULL == pMlmAuthReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmAuthReq")); + return; + } + sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId); + + pMlmAuthReq->authType = authMode; + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAuthReq->authFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE)); + pMlmAuthReq->sessionId = psessionEntry->peSessionId; + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_AUTH_STATE; + // remember staId in case of assoc timeout/failure handling + psessionEntry->staId = pAddBssParams->staContext.staIdx; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, + psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac,LOG1,"SessionId:%d limPostMlmMessage LIM_MLM_AUTH_REQ with limSmeState:%d", + psessionEntry->peSessionId, + psessionEntry->limSmeState); + limPostMlmMessage(pMac, + LIM_MLM_AUTH_REQ, + (tANI_U32 *) pMlmAuthReq); + return; + } + +joinFailure: + { + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /// Send Join response to Host + limHandleSmeJoinResult(pMac, eSIR_SME_REFUSED, eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + } + +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*------------------------------------------------------------------------------------------ + * + * Function to handle WDA_ADD_BSS_RSP, in FT reassoc state. + * Function to Send ReAssociation Request. + * + * + *------------------------------------------------------------------------------------------ + */ +static inline void +limProcessStaMlmAddBssRspFT(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; // keep sme + tpDphHashNode pStaDs = NULL; + tpAddStaParams pAddStaParams = NULL; + tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tANI_U32 selfStaDot11Mode = 0; + + /* Sanity Checks */ + + if (pAddBssParams == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid parameters"));) + goto end; + } + if ( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE != psessionEntry->limMlmState ) + { + goto end; + } + + if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->bssId, DPH_STA_HASH_INDEX_PEER, + &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE); + goto end; + } + // Prepare and send Reassociation request frame + // start reassoc timer. +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress != VOS_TRUE) + { +#endif + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId; + /// Start reassociation failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + /// Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + goto end; + } +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.pSessionEntry = psessionEntry; + if(NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) + { + /* Take a copy of reassoc request for retrying */ + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq ) goto end; + vos_mem_set(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, sizeof(tLimMlmReassocReq), 0); + vos_mem_copy(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, + psessionEntry->pLimMlmReassocReq, + sizeof(tLimMlmReassocReq)); + } + pMac->lim.reAssocRetryAttempt = 0; +#endif + limSendReassocReqWithFTIEsMgmtFrame(pMac, psessionEntry->pLimMlmReassocReq, psessionEntry); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + } else + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:Do not activate timer and dont send the reassoc req"); + } +#endif + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_FT_REASSOC_RSP_STATE)); + PELOGE(limLog(pMac, LOG1, FL("Set the mlm state to %d session=%d"), + psessionEntry->limMlmState, psessionEntry->peSessionId);) + + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig; + pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig; + +#if defined WLAN_FEATURE_VOWIFI + rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry ); +#endif + + pAddStaParams = vos_mem_malloc(sizeof( tAddStaParams )); + if ( NULL == pAddStaParams ) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + goto end; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) psessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + + pAddStaParams->staType = STA_ENTRY_SELF; + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + + /* Update PE session ID */ + pAddStaParams->sessionId = psessionEntry->peSessionId; + pAddStaParams->smesessionId = psessionEntry->smeSessionId; + + // This will indicate HAL to "allocate" a new STA index +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress != VOS_TRUE) +#endif + pAddStaParams->staIdx = HAL_STA_INVALID_IDX; + pAddStaParams->updateSta = FALSE; + + pAddStaParams->shortPreambleSupported = (tANI_U8)psessionEntry->beaconParams.fShortPreamble; +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry, NULL); +#else + limPopulatePeerRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry); +#endif + + if( psessionEntry->htCapability) + { + pAddStaParams->htCapable = psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = psessionEntry->vhtCapability; + pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; +#endif +#ifdef DISABLE_GF_FOR_INTEROP + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + if( (psessionEntry->pLimJoinReq != NULL)) + { + limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry")); + pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } + else +#endif + + pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + if (psessionEntry->limRFBand == SIR_BAND_2_4_GHZ) + { + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode5GHz; + } + pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry); + pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry); + pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + pAddStaParams->listenInterval = (tANI_U16)listenInterval; + + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); + pAddStaParams->supportedRates.opRateMode = limGetStaRateMode((tANI_U8)selfStaDot11Mode); + pAddStaParams->encryptType = psessionEntry->encryptType; + pAddStaParams->maxTxPower = psessionEntry->maxTxPower; + + // Lets save this for when we receive the Reassoc Rsp + psessionEntry->ftPEContext.pAddStaReq = pAddStaParams; + + if (pAddBssParams != NULL) + { + vos_mem_free(pAddBssParams); + pAddBssParams = NULL; + limMsgQ->bodyptr = NULL; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:Prepare and save pAddStaReq in pMac for post-assoc-rsp"); + limProcessAssocRspFrame(pMac, pMac->roam.pReassocResp, LIM_REASSOC, + psessionEntry); + } +#endif + return; + +end: + // Free up buffer allocated for reassocReq + if (psessionEntry != NULL) + if (psessionEntry->pLimMlmReassocReq != NULL) + { + vos_mem_free(psessionEntry->pLimMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + + if (pAddBssParams != NULL) + { + vos_mem_free(pAddBssParams); + pAddBssParams = NULL; + limMsgQ->bodyptr = NULL; + } + + mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE session Id*/ + if (psessionEntry != NULL) + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + else + mlmReassocCnf.sessionId = 0; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ +/** + * limProcessStaMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Now, send an ADD_STA to HAL and ADD the "local" STA itself + * + *LOGIC: + * MLME had sent WDA_ADD_BSS_REQ to HAL + * HAL responded with WDA_ADD_BSS_RSP to MLME + * MLME now sends WDA_ADD_STA_REQ to HAL + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmJoinReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessStaMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tLimMlmAssocCnf mlmAssocCnf; + tANI_U32 mesgType = LIM_MLM_ASSOC_CNF; + tANI_U32 subType = LIM_ASSOC; + tpDphHashNode pStaDs = NULL; + tANI_U16 staIdx = HAL_STA_INVALID_IDX; + tANI_U8 updateSta = false; + mlmAssocCnf.resultCode = eSIR_SME_SUCCESS; + + if(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE == psessionEntry->limMlmState) + { + limLog(pMac,LOG1,"SessionId:%d limProcessStaMlmAddBssRspPreAssoc", + psessionEntry->peSessionId); + limProcessStaMlmAddBssRspPreAssoc(pMac, limMsgQ, psessionEntry); + goto end; + } + if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == psessionEntry->limMlmState +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + || (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState) +#endif + ) + { + mesgType = LIM_MLM_REASSOC_CNF; + subType = LIM_REASSOC; + //If Reassoc is happening for the same BSS, then use the existing StaId and indicate to HAL + //to update the existing STA entry. + //If Reassoc is happening for the new BSS, then old BSS and STA entry would have been already deleted + //before PE tries to add BSS for the new BSS, so set the updateSta to false and pass INVALID STA Index. + if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId)) + { + staIdx = psessionEntry->staId; + updateSta = true; + } + } + + if(pAddBssParams == 0) + goto end; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (psessionEntry->bRoamSynchInProgress) + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "LFR3:limProcessStaMlmAddBssRsp"); +#endif + + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState ) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Mlm=%d %d"), + psessionEntry->limMlmState, + eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);) +#endif + limProcessStaMlmAddBssRspFT( pMac, limMsgQ, psessionEntry); + goto end; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know the session started for self or for peer oct6th + // Now, send WDA_ADD_STA_REQ + limLog( pMac, LOGW, FL( "SessionId:%d On STA: ADD_BSS was successful"), + psessionEntry->peSessionId); + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d could not Add Self Entry for the station"), + psessionEntry->peSessionId);) + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + } + else + { + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig; + pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig; + // Downgrade the EDCA parameters if needed + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + // Send the active EDCA parameters to HAL + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + } else { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } +#if defined WLAN_FEATURE_VOWIFI + rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry ); +#endif + + if (subType == LIM_REASSOC) + limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER); + if (limAddStaSelf(pMac,staIdx, updateSta, psessionEntry) != eSIR_SUCCESS) + { + // Add STA context at HW + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d could not Add Self Entry for the station"), + psessionEntry->peSessionId);) + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + } + } + } else { + limLog(pMac, LOGP, FL("SessionId:%d ADD_BSS failed!"), + psessionEntry->peSessionId); + /* Return Assoc confirm to SME with failure */ + mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + } + + if(mlmAssocCnf.resultCode != eSIR_SME_SUCCESS) + { + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf ); + } + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + + + +/** + * limProcessMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *LOGIC: + * WDA_ADD_BSS_RSP can be received by MLME while the LIM is + * in the following two states: + * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE + * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE + * Based on these two states, this API will determine where to + * route the message to + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tLimMlmStartCnf mlmStartCnf; + tpPESession psessionEntry; + tpAddBssParams pAddBssParams = (tpAddBssParams) (limMsgQ->bodyptr); + + if(NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + return; + } + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + // Validate SME/LIM state + // Validate MLME state + if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL) + { + limLog( pMac, LOGE, FL( "SessionId:%d Session Does not exist" ), + pAddBssParams->sessionId); + if( NULL != pAddBssParams ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + return; + } + /* update PE session Id*/ + mlmStartCnf.sessionId = psessionEntry->peSessionId; + if( eSIR_IBSS_MODE == psessionEntry->bssType ) + limProcessIbssMlmAddBssRsp( pMac, limMsgQ, psessionEntry ); + else + { + if( eLIM_SME_WT_START_BSS_STATE == psessionEntry->limSmeState ) + { + if( eLIM_MLM_WT_ADD_BSS_RSP_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog( pMac, LOGE,FL( "SessionId:%d Received unexpected WDA_ADD_BSS_RSP in state %X" ), + psessionEntry->peSessionId,psessionEntry->limMlmState); + mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + } + else if ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE)||(psessionEntry->bssType == eSIR_BTAMP_STA_MODE)) + { + limProcessBtampAddBssRsp(pMac,limMsgQ,psessionEntry); + } + else + limProcessApMlmAddBssRsp( pMac,limMsgQ); + } + else + /* Called while processing assoc response */ + limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry); + } + + if(limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(TRUE); + } + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + if ( eSIR_SUCCESS != limSendExcludeUnencryptInd(pMac, FALSE, psessionEntry) ) + { + limLog( pMac, LOGE, + FL( "Could not send down Exclude Unencrypted Indication!" ) ); + } + } +#endif +} +/** + * limProcessMlmSetKeyRsp() + * + *FUNCTION: + * This function is called to process the following two + * messages from HAL: + * 1) WDA_SET_BSSKEY_RSP + * 2) WDA_SET_STAKEY_RSP + * 3) WDA_SET_STA_BCASTKEY_RSP + * Upon receipt of this message from HAL, + * MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *LOGIC: + * WDA_SET_BSSKEY_RSP/WDA_SET_STAKEY_RSP can be + * received by MLME while in the following state: + * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR-- + * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR-- + * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE + * Based on this state, this API will determine where to + * route the message to + * + *ASSUMPTIONS: + * ONLY the MLME state is being taken into account for now. + * This is because, it appears that the handling of the + * SETKEYS REQ is handled symmetrically on both the AP & STA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tANI_U8 respReqd = 1; + tLimMlmSetKeysCnf mlmSetKeysCnf; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ), 0); + //BTAMP + if( NULL == limMsgQ->bodyptr ) + { + PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is NULL"));) + return; + } + sessionId = ((tpSetStaKeyParams) limMsgQ->bodyptr)->sessionId; + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + if( eLIM_MLM_WT_SET_STA_KEY_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog( pMac, LOGE, FL( "Received unexpected [Mesg Id - %d] in state %X" ), limMsgQ->type, psessionEntry->limMlmState ); + // There's not much that MLME can do at this stage... + respReqd = 0; + } + else + mlmSetKeysCnf.resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status); + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if( respReqd ) + { + tpLimMlmSetKeysReq lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq; + // Prepare and Send LIM_MLM_SETKEYS_CNF + if( NULL != lpLimMlmSetKeysReq ) + { + vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + // Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + mlmSetKeysCnf.sessionId = sessionId; + limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf); + } +} +void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tLimMlmSetKeysCnf mlmSetKeysCnf; + tANI_U16 resultCode; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + tpLimMlmSetKeysReq lpLimMlmSetKeysReq; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ), 0); + if (NULL == limMsgQ->bodyptr) { + PELOGE(limLog(pMac, LOGE, FL("limMsgQ bodyptr is null"));) + return; + } + sessionId = ((tpSetBssKeyParams) limMsgQ->bodyptr)->sessionId; + if ((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId [%d]"), + sessionId);) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + if (eLIM_MLM_WT_SET_BSS_KEY_STATE == psessionEntry->limMlmState) + resultCode = (tANI_U16) (((tpSetBssKeyParams)limMsgQ->bodyptr)->status); + else + /*BCAST key also uses tpSetStaKeyParams. Done this way for readabilty */ + resultCode = (tANI_U16) (((tpSetStaKeyParams)limMsgQ->bodyptr)->status); + + if (eLIM_MLM_WT_SET_BSS_KEY_STATE != psessionEntry->limMlmState && + eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != psessionEntry->limMlmState) { + /* Mesg received from lower layer is in Invalid state */ + limLog(pMac, LOGE, + FL("Received unexpected [Mesg Id - %d] in state %X"), + limMsgQ->type, psessionEntry->limMlmState ); + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_STATE; + } + else + mlmSetKeysCnf.resultCode = resultCode; + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + /* Restore MLME state */ + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq; + mlmSetKeysCnf.sessionId = sessionId; + + /* Prepare and Send LIM_MLM_SETKEYS_CNF */ + if (NULL != lpLimMlmSetKeysReq) { + vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + /* Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq */ + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf); +} +/** + * limProcessMlmRemoveKeyRsp() + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tANI_U8 respReqd = 1; + tLimMlmRemoveKeyCnf mlmRemoveCnf; + tANI_U16 resultCode; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *) &mlmRemoveCnf, sizeof( tLimMlmRemoveKeyCnf ), 0); + + if( NULL == limMsgQ->bodyptr ) + { + PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is NULL"));) + return; + } + + if (limMsgQ->type == WDA_REMOVE_STAKEY_RSP) + sessionId = ((tpRemoveStaKeyParams) limMsgQ->bodyptr)->sessionId; + else if (limMsgQ->type == WDA_REMOVE_BSSKEY_RSP) + sessionId = ((tpRemoveBssKeyParams) limMsgQ->bodyptr)->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + return; + } + + if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE == psessionEntry->limMlmState ) + resultCode = (tANI_U16) (((tpRemoveBssKeyParams) limMsgQ->bodyptr)->status); + else + resultCode = (tANI_U16) (((tpRemoveStaKeyParams) limMsgQ->bodyptr)->status); + + // Validate MLME state + if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE != psessionEntry->limMlmState && + eLIM_MLM_WT_REMOVE_STA_KEY_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog(pMac, LOGW, + FL("Received unexpected [Mesg Id - %d] in state %X"), + limMsgQ->type, + psessionEntry->limMlmState ); + respReqd = 0; + } + else + mlmRemoveCnf.resultCode = resultCode; + + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + if( respReqd ) + { + tpLimMlmRemoveKeyReq lpLimMlmRemoveKeyReq = (tpLimMlmRemoveKeyReq) pMac->lim.gpLimMlmRemoveKeyReq; + mlmRemoveCnf.sessionId = sessionId; + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF + if( NULL != lpLimMlmRemoveKeyReq ) + { + vos_mem_copy((tANI_U8 *) &mlmRemoveCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmRemoveKeyReq->peerMacAddr, + sizeof( tSirMacAddr )); + // Free the buffer cached for the global pMac->lim.gpLimMlmRemoveKeyReq + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + limPostSmeMessage( pMac, LIM_MLM_REMOVEKEY_CNF, (tANI_U32 *) &mlmRemoveCnf ); + } +} + + +/** --------------------------------------------------------------------- +\fn limProcessInitScanRsp +\brief This function is called when LIM receives WDA_INIT_SCAN_RSP +\ message from HAL. If status code is failure, then +\ update the gLimNumOfConsecutiveBkgndScanFailure count. +\param tpAniSirGlobal pMac +\param tANI_U32 body +\return none +\ ----------------------------------------------------------------------- */ +void limProcessInitScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpInitScanParams pInitScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pInitScanParam = (tpInitScanParams) body; + status = pInitScanParam->status; + vos_mem_free(body); + + //Only abort scan if the we are scanning. + if( pMac->lim.abortScan && + (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) ) + { + limLog( pMac, LOGW, FL(" abort scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + if (status != eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("InitScnRsp failed status=%d"),status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure += 1; + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + return; + } + else + { + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + + } + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_INIT_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("InitScanRsp with failed status= %d"), status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure += 1; + /* + * On Windows eSIR_SME_HAL_SCAN_INIT_FAILED message to CSR may trigger + * another Scan request in the same context (happens when 11d is enabled + * and first scan request with 11d channels fails for whatever reason, then CSR issues next init + * scan in the same context but with bigger channel list), so the state needs to be + * changed before this response message is sent. + */ + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + return; + } + else if (status == eHAL_STATUS_SUCCESS) + { + /* since we have successfully triggered a background scan, + * reset the "consecutive bkgnd scan failure" count to 0 + */ + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0; + pMac->lim.gLimNumOfBackgroundScanSuccess += 1; + pMac->lim.probeCounter = 0; + } + limContinueChannelScan(pMac); + break; +//WLAN_SUSPEND_LINK Related + case eLIM_HAL_SUSPEND_LINK_WAIT_STATE: + if( pMac->lim.gpLimSuspendCallback ) + { + if( eHAL_STATUS_SUCCESS == status ) + { + pMac->lim.gLimHalScanState = eLIM_HAL_SUSPEND_LINK_STATE; + } + else + { + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + + pMac->lim.gpLimSuspendCallback( pMac, status, pMac->lim.gpLimSuspendData ); + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimSuspendData = NULL; + } + else + { + limLog( pMac, LOGP, "No suspend link callback set but station is in suspend state"); + return; + } + break; +//end WLAN_SUSPEND_LINK Related + default: + limLog(pMac, LOGW, FL("limProcessInitScanRsp: Rcvd InitScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +/** + * limProcessSwitchChannelReAssocReq() + * + *FUNCTION: + * This function is called to send the reassoc req mgmt frame after the + * switchChannelRsp message is received from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure. + * @param psessionEntry - session related information. + * @param status - channel switch success/failure. + * + * @return None + */ +static void limProcessSwitchChannelReAssocReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status) +{ + tLimMlmReassocCnf mlmReassocCnf; + tLimMlmReassocReq *pMlmReassocReq; + pMlmReassocReq = (tLimMlmReassocReq *)(psessionEntry->pLimMlmReassocReq); + if(pMlmReassocReq == NULL) + { + limLog(pMac, LOGP, FL("pLimMlmReassocReq does not exist for given switchChanSession")); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + if(status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!"));) + mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL; + goto end; + } + /// Start reassociation failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + /// Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + /// Prepare and send Reassociation request frame + limSendReassocReqMgmtFrame(pMac, pMlmReassocReq, psessionEntry); + return; +end: + // Free up buffer allocated for reassocReq + if(pMlmReassocReq != NULL) + { + /* Update PE session Id*/ + mlmReassocCnf.sessionId = pMlmReassocReq->sessionId; + vos_mem_free(pMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + else + { + mlmReassocCnf.sessionId = 0; + } + + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} +/** + * limProcessSwitchChannelJoinReq() + * + *FUNCTION: + * This function is called to send the probe req mgmt frame after the + * switchChannelRsp message is received from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure. + * @param psessionEntry - session related information. + * @param status - channel switch success/failure. + * + * @return None + */ +static void limProcessSwitchChannelJoinReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status) +{ + tANI_U32 val; + tSirMacSSid ssId; + tLimMlmJoinCnf mlmJoinCnf; + if(status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!"));) + goto error; + } + + if ( (NULL == psessionEntry ) || (NULL == psessionEntry->pLimMlmJoinReq) || + (NULL == psessionEntry->pLimJoinReq) ) + { + PELOGE(limLog(pMac, LOGE, FL("invalid pointer!!"));) + goto error; + } + + + /* eSIR_BTAMP_AP_MODE stroed as bss type in session Table when join req is received, is to be veified */ + if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + if (limSetLinkState(pMac, eSIR_LINK_BTAMP_PREASSOC_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("Sessionid: %d Set link state " + "failed!! BSSID:"MAC_ADDRESS_STR),psessionEntry->peSessionId, + MAC_ADDR_ARRAY(psessionEntry->bssId));) + goto error; + } + } + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("failed to get WNI_CFG_TRIG_STA_BK_SCAN cfg value!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac, psessionEntry); + /// Wait for Beacon to announce join success + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + ssId.length = psessionEntry->ssId.length; + + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId = psessionEntry->peSessionId; + limLog(pMac, LOG1, FL("Sessionid: %d Send Probe req on channel %d ssid: %s " + "BSSID: "MAC_ADDRESS_STR), psessionEntry->peSessionId, + psessionEntry->currentOperChannel, ssId.ssId, + MAC_ADDR_ARRAY(psessionEntry->pLimMlmJoinReq->bssDescription.bssId)); + + /* + * We need to wait for probe response, so start join timeout timer. + * This timer will be deactivated once we receive probe response. + */ + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_JOIN_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimJoinFailureTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Join failure timer")); + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, + pMac->lim.gLimMlmState)); + //memory is freed up below. + psessionEntry->pLimMlmJoinReq = NULL; + goto error; + } + + // include additional IE if there is + limSendProbeReqMgmtFrame( pMac, &ssId, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, psessionEntry->currentOperChannel/*chanNum*/, + psessionEntry->selfMacAddr, psessionEntry->dot11mode, + psessionEntry->pLimJoinReq->addIEScan.length, psessionEntry->pLimJoinReq->addIEScan.addIEdata); + + if( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) + { + // Activate Join Periodic Probe Req timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Periodic Join req failure timer")); + goto error; + } + } + + return; +error: + if(NULL != psessionEntry) + { + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + if (psessionEntry->pLimJoinReq) + { + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + } + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + } + else + { + mlmJoinCnf.sessionId = 0; + } + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); +} + +/** + * limProcessSwitchChannelRsp() + * + *FUNCTION: + * This function is called to process switchChannelRsp message from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param body - message body. + * + * @return None + */ +void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body) +{ + tpSwitchChannelParams pChnlParams = NULL; + eHalStatus status; + tANI_U16 channelChangeReasonCode; + tANI_U8 peSessionId; + tpPESession psessionEntry; + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pChnlParams = (tpSwitchChannelParams) body; + status = pChnlParams->status; + peSessionId = pChnlParams->peSessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac, peSessionId))== NULL) + { + limLog(pMac, LOGP, FL("session does not exist for given sessionId")); + return; + } +#if defined WLAN_FEATURE_VOWIFI + //HAL fills in the tx power used for mgmt frames in this field. + //Store this value to use in TPC report IE. + rrmCacheMgmtTxPower( pMac, pChnlParams->txMgmtPower, psessionEntry ); +#endif + channelChangeReasonCode = psessionEntry->channelChangeReasonCode; + // initialize it back to invalid id + psessionEntry->chainMask = pChnlParams->chainMask; + psessionEntry->smpsMode = pChnlParams->smpsMode; + psessionEntry->channelChangeReasonCode = 0xBAD; + limLog(pMac, LOG1, FL("channelChangeReasonCode %d"),channelChangeReasonCode); + switch(channelChangeReasonCode) + { + case LIM_SWITCH_CHANNEL_REASSOC: + limProcessSwitchChannelReAssocReq(pMac, psessionEntry, status); + break; + case LIM_SWITCH_CHANNEL_JOIN: + limProcessSwitchChannelJoinReq(pMac, psessionEntry, status); + break; + + case LIM_SWITCH_CHANNEL_OPERATION: + /* + * The above code should also use the callback. + * mechanism below, there is scope for cleanup here. + * THat way all this response handler does is call the call back + * We can get rid of the reason code here. + */ + if (pMac->lim.gpchangeChannelCallback) + { + PELOG1(limLog( pMac, LOG1, "Channel changed hence invoke registered call back");) + pMac->lim.gpchangeChannelCallback(pMac, status, pMac->lim.gpchangeChannelData, psessionEntry); + } + break; + case LIM_SWITCH_CHANNEL_SAP_DFS: + { + /* Note: This event code specific to SAP mode + * When SAP session issues channel change as performing + * DFS, we will come here. Other sessions, for e.g. P2P + * will have to define their own event code and channel + * switch handler. This is required since the SME may + * require completely different information for P2P unlike + * SAP. + */ + limSendSmeAPChannelSwitchResp(pMac, psessionEntry, pChnlParams); + } + break; + default: + break; + } + vos_mem_free(body); +} +/** + * limProcessStartScanRsp() + * + *FUNCTION: + * This function is called to process startScanRsp message from HAL. If scan/learn was successful + * then it will start scan/learn on the next channel. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param body - message body. + * + * @return None + */ + +void limProcessStartScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpStartScanParams pStartScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pStartScanParam = (tpStartScanParams) body; + status = pStartScanParam->status; +#if defined WLAN_FEATURE_VOWIFI + //HAL fills in the tx power used for mgmt frames in this field. + //Store this value to use in TPC report IE. + rrmCacheMgmtTxPower( pMac, pStartScanParam->txMgmtPower, NULL ); + //Store start TSF of scan start. This will be stored in BSS params. + rrmUpdateStartTSF( pMac, pStartScanParam->startTSF ); +#endif + vos_mem_free(body); + body = NULL; + if( pMac->lim.abortScan ) + { + limLog( pMac, LOGW, FL(" finish scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("StartScanRsp with failed status= %d"), status);) + // + // FIXME - With this, LIM will try and recover state, but + // eWNI_SME_SCAN_CNF maybe reporting an incorrect + // status back to the SME + // + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + } + else + { + pMac->lim.gLimHalScanState = eLIM_HAL_SCANNING_STATE; + limContinuePostChannelScan(pMac); + } + break; + default: + limLog(pMac, LOGW, FL("Rcvd StartScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +void limProcessEndScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpEndScanParams pEndScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pEndScanParam = (tpEndScanParams) body; + status = pEndScanParam->status; + vos_mem_free(body); + body = NULL; + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_END_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d"), status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + } + else + { + pMac->lim.gLimCurrentScanChannelId++; + limContinueChannelScan(pMac); + } + break; + default: + limLog(pMac, LOGW, FL("Rcvd endScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +/** + * limStopTxAndSwitch() + * + *FUNCTION: + * Start channel switch on all sessions that is in channel switch state. + * + * @param pMac - pointer to global adapter context + * + * @return None + * + */ +static void +limStopTxAndSwitch (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limStopTxAndSwitchChannel(pMac, i); + } + } + return; +} +/** + * limStartQuietOnSession() + * + *FUNCTION: + * This function is called to start quiet timer after finish scan if there is + * qeuieting on any session. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +static void +limStartQuietOnSession (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + limStartQuietTimer(pMac, i); + } + } + return; +} +void limProcessFinishScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpFinishScanParams pFinishScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pFinishScanParam = (tpFinishScanParams) body; + status = pFinishScanParam->status; + vos_mem_free(body); + body = NULL; + + limLog(pMac, LOGW, FL("Rcvd FinishScanRsp in state %d"), + pMac->lim.gLimHalScanState); + + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_FINISH_SCAN_WAIT_STATE: + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + limCompleteMlmScan(pMac, eSIR_SME_SUCCESS); + if (limIsChanSwitchRunning(pMac)) + { + /** Right time to stop tx and start the timer for channel switch */ + /* Sending Session ID 0, may not be correct, since SCAN is global there should not + * be any associated session id + */ + limStopTxAndSwitch(pMac); + } + else if (limIsQuietBegin(pMac)) + { + /** Start the quieting */ + /* Sending Session ID 0, may not be correct, since SCAN is global there should not + * be any associated session id + */ + limStartQuietOnSession(pMac); + } + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d"), status);) + } + break; +//WLAN_SUSPEND_LINK Related + case eLIM_HAL_RESUME_LINK_WAIT_STATE: + if( pMac->lim.gpLimResumeCallback ) + { + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gpLimResumeCallback( pMac, status, pMac->lim.gpLimResumeData ); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + else + { + limLog( pMac, LOGP, "No Resume link callback set but station is in suspend state"); + return; + } + break; +//end WLAN_SUSPEND_LINK Related + + default: + limLog(pMac, LOGE, FL("Rcvd FinishScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +/** + * @function : limProcessMlmHalAddBARsp + * + * @brief: Process WDA_ADDBA_RSP coming from HAL + * + * + * @param pMac The global tpAniSirGlobal object + * + * @param tSirMsgQ The MsgQ header containing the response buffer + * + * @return none + */ +void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ) +{ + // Send LIM_MLM_ADDBA_CNF to LIM + tpLimMlmAddBACnf pMlmAddBACnf; + tpPESession psessionEntry = NULL; + tpAddBAParams pAddBAParams = (tpAddBAParams) limMsgQ->bodyptr; + + //now LIM can process any defer message. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pAddBAParams == NULL) { + PELOGE(limLog(pMac, LOGE,FL("NULL ADD BA Response from HAL"));) + return; + } + if((psessionEntry = peFindSessionBySessionId(pMac, pAddBAParams->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionID: %d"),pAddBAParams->sessionId );) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + // Allocate for LIM_MLM_ADDBA_CNF + pMlmAddBACnf = vos_mem_malloc(sizeof(tLimMlmAddBACnf)); + if ( NULL == pMlmAddBACnf ) { + limLog( pMac, LOGP, FL(" AllocateMemory failed for pMlmAddBACnf")); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + vos_mem_set((void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ), 0); + // Copy the peer MAC + vos_mem_copy(pMlmAddBACnf->peerMacAddr, pAddBAParams->peerMacAddr, + sizeof( tSirMacAddr )); + // Copy other ADDBA Rsp parameters + pMlmAddBACnf->baDialogToken = pAddBAParams->baDialogToken; + pMlmAddBACnf->baTID = pAddBAParams->baTID; + pMlmAddBACnf->baPolicy = pAddBAParams->baPolicy; + pMlmAddBACnf->baBufferSize = pAddBAParams->baBufferSize; + pMlmAddBACnf->baTimeout = pAddBAParams->baTimeout; + pMlmAddBACnf->baDirection = pAddBAParams->baDirection; + pMlmAddBACnf->sessionId = psessionEntry->peSessionId; + if(eHAL_STATUS_SUCCESS == pAddBAParams->status) + pMlmAddBACnf->addBAResultCode = eSIR_MAC_SUCCESS_STATUS; + else + pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + // Send ADDBA CNF to LIM + limPostSmeMessage( pMac, LIM_MLM_ADDBA_CNF, (tANI_U32 *) pMlmAddBACnf ); +} +/** + * \brief Process LIM_MLM_ADDBA_CNF + * + * \sa limProcessMlmAddBACnf + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the response buffer + * + * \return none + */ +void limProcessMlmAddBACnf( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tpLimMlmAddBACnf pMlmAddBACnf; +tpDphHashNode pSta; +tANI_U16 aid; +tLimBAState curBaState; +tpPESession psessionEntry = NULL; +if(pMsgBuf == NULL) +{ + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; +} +pMlmAddBACnf = (tpLimMlmAddBACnf) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBACnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + vos_mem_free(pMsgBuf); + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pMlmAddBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + PELOGE(limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA CNF from HAL" ));) + vos_mem_free(pMsgBuf); + return; + } + LIM_GET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, &curBaState); + // Need to validate SME state + if( eLIM_BA_STATE_WT_ADD_RSP != curBaState) + { + PELOGE(limLog( pMac, LOGE, + FL( "Received unexpected ADDBA CNF when STA BA state is %d" ), + curBaState );) + vos_mem_free(pMsgBuf); + return; + } + // Restore STA BA state + LIM_SET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, eLIM_BA_STATE_IDLE); + if( eSIR_MAC_SUCCESS_STATUS == pMlmAddBACnf->addBAResultCode ) + { + // Update LIM internal cache... + if( eBA_RECIPIENT == pMlmAddBACnf->baDirection ) + { + pSta->tcCfg[pMlmAddBACnf->baTID].fUseBARx = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fRxCompBA = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fRxBApolicy = pMlmAddBACnf->baPolicy; + pSta->tcCfg[pMlmAddBACnf->baTID].rxBufSize = pMlmAddBACnf->baBufferSize; + pSta->tcCfg[pMlmAddBACnf->baTID].tuRxBAWaitTimeout = pMlmAddBACnf->baTimeout; + // Package LIM_MLM_ADDBA_RSP to MLME, with proper + // status code. MLME will then send an ADDBA RSP + // over the air to the peer MAC entity + if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac, + pMlmAddBACnf->peerMacAddr, + pMlmAddBACnf->addBAResultCode, + pMlmAddBACnf->baDialogToken, + (tANI_U8) pMlmAddBACnf->baTID, + (tANI_U8) pMlmAddBACnf->baPolicy, + pMlmAddBACnf->baBufferSize, + pMlmAddBACnf->baTimeout,psessionEntry)) + { + PELOGW(limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_ADDBA_RSP to " )); + limPrintMacAddr( pMac, pMlmAddBACnf->peerMacAddr, LOGW );) + } + } + else + { + pSta->tcCfg[pMlmAddBACnf->baTID].fUseBATx = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fTxCompBA = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fTxBApolicy = pMlmAddBACnf->baPolicy; + pSta->tcCfg[pMlmAddBACnf->baTID].txBufSize = pMlmAddBACnf->baBufferSize; + pSta->tcCfg[pMlmAddBACnf->baTID].tuTxBAWaitTimeout = pMlmAddBACnf->baTimeout; + } + } + // Free the memory allocated for LIM_MLM_ADDBA_CNF + vos_mem_free(pMsgBuf); + pMsgBuf = NULL; +} +/** + * \brief Process LIM_MLM_DELBA_CNF + * + * \sa limProcessMlmDelBACnf + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the response buffer + * + * \return none + */ +void limProcessMlmDelBACnf( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ + tpLimMlmDelBACnf pMlmDelBACnf; + tpDphHashNode pSta; + tANI_U16 aid; + tLimBAState curBaState; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmDelBACnf = (tpLimMlmDelBACnf) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDelBACnf->sessionId))== NULL) + { + limLog(pMac, LOGP,FL("SessionId:%d Session Does not exist"), + pMlmDelBACnf->sessionId); + vos_mem_free(pMsgBuf); + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pMlmDelBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring DELBA CNF from HAL" )); + vos_mem_free(pMsgBuf); + return; + } + if(NULL == pMlmDelBACnf) + { + limLog( pMac, LOGE, + FL( "pMlmDelBACnf is NULL - ignoring DELBA CNF from HAL" )); + return; + } + // Need to validate baState + LIM_GET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, &curBaState); + if( eLIM_BA_STATE_WT_DEL_RSP != curBaState ) + { + limLog( pMac, LOGE, + FL( "Received unexpected DELBA CNF when STA BA state is %d" ), + curBaState ); + vos_mem_free(pMsgBuf); + return; + } + // Restore STA BA state + LIM_SET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, eLIM_BA_STATE_IDLE); + // Free the memory allocated for LIM_MLM_DELBA_CNF + vos_mem_free(pMsgBuf); +} +/** + * \brief Process SIR_LIM_DEL_BA_IND + * + * \sa limProcessMlmHalBADeleteInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the indication buffer + * + * \return none + */ +void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpBADeleteParams pBADeleteParams; + tpDphHashNode pSta; + tANI_U16 aid; + tLimBAState curBaState; + tpPESession psessionEntry; + tANI_U8 sessionId; + + pBADeleteParams = (tpBADeleteParams) limMsgQ->bodyptr; + + if((psessionEntry = peFindSessionByBssid(pMac,pBADeleteParams->bssId,&sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pBADeleteParams->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring BA Delete IND from HAL" )); + goto returnAfterCleanup; + } + + // Need to validate BA state + LIM_GET_STA_BA_STATE(pSta, pBADeleteParams->baTID, &curBaState); + if( eLIM_BA_STATE_IDLE != curBaState ) + { + limLog( pMac, LOGE, + FL( "Received unexpected BA Delete IND when STA BA state is %d" ), + curBaState ); + goto returnAfterCleanup; + } + + // Validate if a BA is active for the requested TID + // AND in that desired direction + if( eBA_INITIATOR == pBADeleteParams->baDirection ) + { + if( 0 == pSta->tcCfg[pBADeleteParams->baTID].fUseBATx ) + status = eSIR_FAILURE; + } + else + { + if( 0 == pSta->tcCfg[pBADeleteParams->baTID].fUseBARx ) + status = eSIR_FAILURE; + } + if( eSIR_FAILURE == status ) + { + limLog( pMac, LOGW, + FL("Received an INVALID DELBA Delete Ind for TID %d..."), + pBADeleteParams->baTID ); + } + else + { + // Post DELBA REQ to MLME... + if( eSIR_SUCCESS != + (status = limPostMlmDelBAReq( pMac, + pSta, + pBADeleteParams->baDirection, + pBADeleteParams->baTID, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry ))) + { + limLog( pMac, LOGE, + FL( "Attempt to post LIM_MLM_DELBA_REQ failed with status %d" ), status); + } + else + { + limLog( pMac, LOGE, + FL( "BA Delete - Reason 0x%08x. Attempting to delete BA session for TID %d with peer STA " ), + pBADeleteParams->reasonCode, pBADeleteParams->baTID ); + limPrintMacAddr( pMac, pSta->staAddr, LOGE ); + } + } +returnAfterCleanup: + // Free the memory allocated for SIR_LIM_DEL_BA_IND + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; +} + +/** + * @function : limHandleDelBssInReAssocContext + * @brief : While Processing the ReAssociation Response Frame in STA, + * a. immediately after receiving the Reassoc Response the RxCleanUp is + * being issued and the end of DelBSS the new BSS is being added. + * + * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context + * change, We need to update CSR with ReAssocCNF Response with the + * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS + * context only + * + * @param : pMac - tpAniSirGlobal + * pStaDs - Station Descriptor + * + * @return : none + */ +static void +limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/ + /** Set the MlmState to IDLE*/ + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + /* Update PE session Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + switch (psessionEntry->limMlmState) { + case eLIM_SME_WT_REASSOC_STATE : + { + tpSirAssocRsp assocRsp; + tpDphHashNode pStaDs; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSchBeaconStruct beaconStruct; + /** Delete the older STA Table entry */ + limDeleteDphHashEntry(pMac, psessionEntry->bssId, DPH_STA_HASH_INDEX_PEER, psessionEntry); + /** + * Add an entry for AP to hash table + * maintained by DPH module + */ + if ((pStaDs = dphAddHashEntry(pMac, psessionEntry->limReAssocbssId, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOGE); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS; + goto Error; + } + /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame + * is being stored to be used here for sending ADDBSS + */ + assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData; + limUpdateAssocStaDatas(pMac, pStaDs, assocRsp,psessionEntry); + limUpdateReAssocGlobals(pMac, assocRsp,psessionEntry); + limExtractApCapabilities( pMac, + (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields, + limGetIElenFromBssDescription( &psessionEntry->pLimReAssocReq->bssDescription ), + &beaconStruct ); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, &beaconStruct, psessionEntry); + if(beaconStruct.erpPresent) { + if (beaconStruct.erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = 0; + else + psessionEntry->beaconParams.fShortPreamble = 1; + } + //updateBss flag is false, as in this case, PE is first deleting the existing BSS and then adding a new one. + if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, &beaconStruct, + &psessionEntry->pLimReAssocReq->bssDescription, false, psessionEntry)) { + limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed ")); + retStatus = eSIR_FAILURE; + } + if (retStatus != eSIR_SUCCESS) + { + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + vos_mem_free(assocRsp); + pMac->lim.gLimAssocResponseData = NULL; + goto Error; + } + vos_mem_free(assocRsp); + psessionEntry->limAssocResponseData = NULL; + } + break; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: + { + /** Case wherein the DisAssoc / Deauth + * being sent as response to ReAssoc Req*/ + /** Send the Reason code as the same received in Disassoc / Deauth Frame*/ + mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason; + mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger; + /** Set the SME State back to WT_Reassoc State*/ + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry); + if((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + } + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State"));) + mlmReassocCnf.resultCode = eSIR_SME_REFUSED; + mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto Error; + } + return; +Error: + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +/* Added For BT -AMP Support */ +static void +limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmStartCnf mlmStartCnf; + tANI_U32 val; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + limLog(pMac, LOG2, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS")); + if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + if (limSetLinkState(pMac, eSIR_LINK_BTAMP_AP_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + } else if (psessionEntry->bssType == eSIR_BTAMP_STA_MODE) { + if (limSetLinkState(pMac, eSIR_LINK_SCAN_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + } + + // Set MLME state + psessionEntry->limMlmState= eLIM_MLM_BSS_STARTED_STATE; + psessionEntry->statypeForBss = STA_ENTRY_SELF; // to know session started for peer or for self + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + schEdcaProfileUpdate(pMac, psessionEntry); + limInitPeerIdxpool(pMac,psessionEntry); + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ),pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + mlmStartCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + +/** + * @function : limHandleAddBssInReAssocContext + * @brief : While Processing the ReAssociation Response Frame in STA, + * a. immediately after receiving the Reassoc Response the RxCleanUp is + * being issued and the end of DelBSS the new BSS is being added. + * + * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context + * change, We need to update CSR with ReAssocCNF Response with the + * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS + * context only + * + * @param : pMac - tpAniSirGlobal + * pStaDs - Station Descriptor + * + * @return : none + */ +void +limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/ + /** Set the MlmState to IDLE*/ + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + switch (psessionEntry->limSmeState) { + case eLIM_SME_WT_REASSOC_STATE : { + tpSirAssocRsp assocRsp; + tpDphHashNode pStaDs; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSchBeaconStruct *pBeaconStruct; + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeaconStruct ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limHandleAddBssInReAssocContext") ); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto Error; + } + + // Get the AP entry from DPH hash table + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL("Fail to get STA PEER entry from hash"));) + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS; + vos_mem_free(pBeaconStruct); + goto Error; + } + /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame + * is being stored to be used here for sending ADDBSS + */ + assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData; + limUpdateAssocStaDatas(pMac, pStaDs, assocRsp, psessionEntry); + limUpdateReAssocGlobals(pMac, assocRsp, psessionEntry); + limExtractApCapabilities( pMac, + (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields, + limGetIElenFromBssDescription( &psessionEntry->pLimReAssocReq->bssDescription ), + pBeaconStruct ); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + + if(pBeaconStruct->erpPresent) + { + if (pBeaconStruct->erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = 0; + else + psessionEntry->beaconParams.fShortPreamble = 1; + } + /* to skip sending Add BSS and ADD STA incase of reassoc to + * same AP as part of HS2.0 set this flag + */ + psessionEntry->isNonRoamReassoc = 1; + if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, pBeaconStruct, + &psessionEntry->pLimReAssocReq->bssDescription, true, psessionEntry)) { + limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed ")); + retStatus = eSIR_FAILURE; + } + if (retStatus != eSIR_SUCCESS) + { + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + vos_mem_free(assocRsp); + pMac->lim.gLimAssocResponseData = NULL; + vos_mem_free(pBeaconStruct); + goto Error; + } + vos_mem_free(assocRsp); + psessionEntry->limAssocResponseData = NULL; + vos_mem_free(pBeaconStruct); + } + break; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: { /** Case wherein the DisAssoc / Deauth + * being sent as response to ReAssoc Req*/ + /** Send the Reason code as the same received in Disassoc / Deauth Frame*/ + mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason; + mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger; + /** Set the SME State back to WT_Reassoc State*/ + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry); + if(psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + } + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State"));) + mlmReassocCnf.resultCode = eSIR_SME_REFUSED; + mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto Error; + } +return; +Error: + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +void +limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry){ + tBeaconGenParams *pBeaconGenParams = NULL; + tSirMsgQ limMsg; + /** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/ + if(psessionEntry == NULL ){ + PELOGE( limLog( pMac, LOGE, + FL( "Error:Unable to get the PESessionEntry" ));) + return; + } + pBeaconGenParams = vos_mem_malloc(sizeof(*pBeaconGenParams)); + if ( NULL == pBeaconGenParams ) + { + PELOGE( limLog( pMac, LOGP, + FL( "Unable to allocate memory during sending beaconPreMessage" ));) + return; + } + vos_mem_set(pBeaconGenParams, sizeof(*pBeaconGenParams), 0); + vos_mem_copy((void *) pBeaconGenParams->bssId, + (void *)psessionEntry->bssId, + SIR_MAC_ADDR_LENGTH ); + limMsg.bodyptr = pBeaconGenParams; + schProcessPreBeaconInd(pMac, &limMsg); + return; +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + * limSendSmeScanCacheUpdatedInd() + * + *FUNCTION: + * This function is used to post WDA_SME_SCAN_CACHE_UPDATED message to WDA. + * This message is the indication to WDA that all scan cache results + * are updated from LIM to SME. Mainly used only in PNO offload case. + * + *LOGIC: + * + *ASSUMPTIONS: + * This function should be called after posting scan cache results to SME. + * + *NOTE: + * NA + * + * @return None + */ +void limSendSmeScanCacheUpdatedInd(tANI_U8 sessionId) +{ + vos_msg_t msg; + + msg.type = WDA_SME_SCAN_CACHE_UPDATED; + msg.reserved = 0; + msg.bodyptr = NULL; + msg.bodyval = sessionId; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SME_SCAN_CACHE_UPDATED message to WDA", __func__); +} +#endif + +void limSendScanOffloadComplete(tpAniSirGlobal pMac, + tSirScanOffloadEvent *pScanEvent) +{ + tANI_U16 scanRspLen = 0; + + pMac->lim.gLimSmeScanResultLength += + pMac->lim.gLimMlmScanResultLength; + pMac->lim.gLimRspReqd = false; + if ((pScanEvent->reasonCode == eSIR_SME_SUCCESS) && + pMac->lim.gLimSmeScanResultLength) { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + } + else + scanRspLen = sizeof(tSirSmeScanRsp); + + limSendSmeScanRsp(pMac, scanRspLen, pScanEvent->reasonCode, + pScanEvent->sessionId, + 0); +#ifdef FEATURE_WLAN_SCAN_PNO + limSendSmeScanCacheUpdatedInd(pScanEvent->sessionId); +#endif +} + + +void limProcessRxScanEvent(tpAniSirGlobal pMac, void *buf) +{ + tSirScanOffloadEvent *pScanEvent = (tSirScanOffloadEvent *) buf; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "scan_id = %u", pScanEvent->scanId); + + switch (pScanEvent->event) + { + case SCAN_EVENT_STARTED: + break; + case SCAN_EVENT_START_FAILED: + case SCAN_EVENT_COMPLETED: + pMac->lim.fOffloadScanPending = 0; + pMac->lim.fOffloadScanP2PSearch = 0; + pMac->lim.fOffloadScanP2PListen = 0; + if (P2P_SCAN_TYPE_LISTEN == pScanEvent->p2pScanType) + { + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, + eHAL_STATUS_SUCCESS, + pScanEvent->sessionId, 0); + vos_mem_free(pMac->lim.gpLimRemainOnChanReq); + pMac->lim.gpLimRemainOnChanReq = NULL; + } + else + { + limSendScanOffloadComplete(pMac, pScanEvent); + } + break; + case SCAN_EVENT_FOREIGN_CHANNEL: + if (P2P_SCAN_TYPE_LISTEN == pScanEvent->p2pScanType) + { + /*Send Ready on channel indication to SME */ + if (pMac->lim.gpLimRemainOnChanReq) + { + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RDY_IND, + eHAL_STATUS_SUCCESS, + pScanEvent->sessionId, 0); + } + else + { + limLog(pMac, LOGE, + FL(" NULL pointer of gpLimRemainOnChanReq")); + } + } + else + { + limAddScanChannelInfo(pMac, vos_freq_to_chan(pScanEvent->chanFreq)); + } + break; + case SCAN_EVENT_BSS_CHANNEL: + case SCAN_EVENT_DEQUEUED: + case SCAN_EVENT_PREEMPTED: + default: + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "Received unhandled scan event %u", pScanEvent->event); + } + vos_mem_free(buf); +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c new file mode 100644 index 0000000000000..c3e9dc412922b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessProbeReqFrame.cc contains the code + * for processing Probe Request Frame. + * Author: Chandra Modumudi + * Date: 02/28/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSerDesUtils.h" +#include "parserApi.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" + +void + +limSendSmeProbeReqInd(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U8 *pProbeReqIE, + tANI_U32 ProbeReqIELen, + tpPESession psessionEntry); + +/** + * limGetWPSPBCSessions + * + *FUNCTION: + * This function is called to query the WPS PBC overlap + * + *LOGIC: + * This function check WPS PBC probe request link list for PBC overlap + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param addr A pointer to probe request source MAC addresss + * @param uuid_e A pointer to UUIDE element of WPS IE in WPS PBC probe request + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr, + tANI_U8 *uuid_e, eWPSPBCOverlap *overlap, + tpPESession psessionEntry) +{ + int count = 0; + tSirWPSPBCSession *pbc; + tANI_TIMESTAMP curTime; + + curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND); + + vos_mem_set((tANI_U8 *)addr, sizeof(tSirMacAddr), 0); + vos_mem_set((tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN, 0); + + for (pbc = psessionEntry->pAPWPSPBCSession; pbc; pbc = pbc->next) { + + if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) + break; + + count++; + if(count > 1) + break; + + vos_mem_copy((tANI_U8 *)addr, (tANI_U8 *)pbc->addr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *)uuid_e, (tANI_U8 *)pbc->uuid_e, SIR_WPS_UUID_LEN); + } + + if (count > 1) + { + *overlap = eSAP_WPSPBC_OVERLAP_IN120S; // Overlap + } + else if(count == 0) + { + *overlap = eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S; // no WPS probe request in 120 second + } else + { + *overlap = eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S; // One WPS probe request in 120 second + } + + PELOGE(limLog(pMac, LOGE, FL("overlap = %d"), *overlap);) + PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, addr, sizeof(tSirMacAddr));) + PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, uuid_e, SIR_WPS_UUID_LEN);) + + return; +} + +/** + * limRemoveTimeoutPBCsessions + * + *FUNCTION: + * This function is called to remove the WPS PBC probe request entires from specific entry to end. + * + *LOGIC: + * + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pbc The beginning entry in WPS PBC probe request link list + * + * @return None + */ +static void limRemoveTimeoutPBCsessions(tpAniSirGlobal pMac, tSirWPSPBCSession *pbc) +{ + tSirWPSPBCSession *prev; + + while (pbc) { + prev = pbc; + pbc = pbc->next; + + PELOG4(limLog(pMac, LOG4, FL("WPS PBC sessions remove"));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->addr, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->uuid_e, SIR_WPS_UUID_LEN);) + + vos_mem_free(prev); + } +} + +void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry) +{ + tSirWPSPBCSession *pbc, *prev = NULL; + prev = pbc = psessionEntry->pAPWPSPBCSession; + + while (pbc) { + if (vos_mem_compare((tANI_U8 *)pbc->addr, + (tANI_U8 *)pRemoveMac, sizeof(tSirMacAddr))) { + prev->next = pbc->next; + if (pbc == psessionEntry->pAPWPSPBCSession) + psessionEntry->pAPWPSPBCSession = pbc->next; + vos_mem_free(pbc); + return; + } + prev = pbc; + pbc = pbc->next; + } + +} + +/** + * limUpdatePBCSessionEntry + * + *FUNCTION: + * This function is called when probe request with WPS PBC IE is received + * + *LOGIC: + * This function add the WPS PBC probe request in the WPS PBC probe request link list + * The link list is in decreased time order of probe request that is received. + * The entry that is more than 120 second is removed. + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param addr A pointer to probe request source MAC addresss + * @param uuid_e A pointer to UUIDE element of WPS IE + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +static void limUpdatePBCSessionEntry(tpAniSirGlobal pMac, + tANI_U8 *addr, tANI_U8 *uuid_e, + tpPESession psessionEntry) +{ + tSirWPSPBCSession *pbc, *prev = NULL; + + tANI_TIMESTAMP curTime; + + curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND); + + PELOG4(limLog(pMac, LOG4, FL("Receive WPS probe reques curTime=%d"), curTime);) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, addr, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, uuid_e, SIR_WPS_UUID_LEN);) + + pbc = psessionEntry->pAPWPSPBCSession; + + while (pbc) { + if (vos_mem_compare((tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr)) && + vos_mem_compare((tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN)) { + if (prev) + prev->next = pbc->next; + else + psessionEntry->pAPWPSPBCSession = pbc->next; + break; + } + prev = pbc; + pbc = pbc->next; + } + + if (!pbc) { + pbc = vos_mem_malloc(sizeof(tSirWPSPBCSession)); + if ( NULL == pbc ) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + return; + } + vos_mem_copy((tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr)); + + if (uuid_e) + vos_mem_copy((tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN); + } + + pbc->next = psessionEntry->pAPWPSPBCSession; + psessionEntry->pAPWPSPBCSession = pbc; + pbc->timestamp = curTime; + + /* remove entries that have timed out */ + prev = pbc; + pbc = pbc->next; + + while (pbc) { + if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) { + prev->next = NULL; + limRemoveTimeoutPBCsessions(pMac, pbc); + break; + } + prev = pbc; + pbc = pbc->next; + } +} + +/** + * limWPSPBCClose + * + *FUNCTION: + * This function is called when BSS is closed + * + *LOGIC: + * This function remove all the WPS PBC entries + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + limRemoveTimeoutPBCsessions(pMac, psessionEntry->pAPWPSPBCSession); + +} + +/** + * limCheck11bRates + * + *FUNCTION: + * This function is called by limProcessProbeReqFrame() upon + * Probe Request frame reception. + * + *LOGIC: + * This function check 11b rates in supportedRates and extendedRates rates + * + *NOTE: + * + * @param rate + * + * @return BOOLEAN + */ + +tANI_BOOLEAN limCheck11bRates(tANI_U8 rate) +{ + if ( ( 0x02 == (rate)) + || ( 0x04 == (rate)) + || ( 0x0b == (rate)) + || ( 0x16 == (rate)) + ) + { + return TRUE; + } + return FALSE; +} + +/** + * limProcessProbeReqFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Request frame reception. + * + *LOGIC: + * This function processes received Probe Request frame and responds + * with Probe Response. + * Only AP or STA in IBSS mode that sent last Beacon will respond to + * Probe Request. + * + *ASSUMPTIONS: + * 1. AP or STA in IBSS mode that sent last Beacon will always respond + * to Probe Request received with broadcast SSID. + * + *NOTE: + * 1. Dunno what to do with Rates received in Probe Request frame + * 2. Frames with out-of-order fields/IEs are dropped. + * + * @param pMac Pointer to Global MAC structure + * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs + * + * @return None + */ + +void +limProcessProbeReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tSirProbeReq probeReq; + tAniSSID ssId; + tSirMsgQ msgQ; + tSirSmeProbeReq *pSirSmeProbeReq; + tANI_U32 wpsApEnable=0, tmp; + + do{ + // Don't send probe responses if disabled + if (pMac->lim.gLimProbeRespDisableFlag) + break; + + // Don't send probe response if P2P go is scanning till scan come to idle state. + if((psessionEntry->pePersona == VOS_P2P_GO_MODE) && ((pMac->lim.gpLimRemainOnChanReq ) + || (pMac->lim.gLimHalScanState != eLIM_HAL_IDLE_SCAN_STATE))) + { + limLog(pMac, LOG3, + FL("While GO is scanning, don't send probe response on diff channel")); + break; + } + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)|| + ( (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (WDA_GET_RX_BEACON_SENT(pRxPacketInfo)) ) ) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG3(limLog(pMac, LOG3, FL("Received Probe Request %d bytes from "), frameLen); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + + // Get pointer to Probe Request frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + // Parse Probe Request frame + if (sirConvertProbeReqFrame2Struct(pMac, pBody, frameLen, &probeReq)==eSIR_FAILURE) + { + PELOGW(limLog(pMac, LOGW, FL("Parse error ProbeRequest, length=%d, SA is:"), frameLen);) + limPrintMacAddr(pMac, pHdr->sa, LOGW); + pMac->sys.probeError++; + break; + } + else + { + if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + tANI_U8 i = 0, rate_11b = 0, other_rates = 0; + // Check 11b rates in supported rates + for ( i = 0 ; i < probeReq.supportedRates.numRates; + i++ ) + { + if (limCheck11bRates(probeReq.supportedRates.rate[i] & 0x7f)) + { + rate_11b++; + } + else + { + other_rates++; + } + } + + // Check 11b rates in extended rates + for ( i = 0 ; i < probeReq.extendedRates.numRates; i++ ) + { + if (limCheck11bRates(probeReq.extendedRates.rate[i] & 0x7f)) + { + rate_11b++; + } + else + { + other_rates++; + } + } + + if ( (rate_11b > 0) && (other_rates == 0) ) + { + PELOG3(limLog(pMac, LOG3, + FL("Received a probe request frame with only 11b rates, SA is: ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + return; + } + } + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + + if ( (psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent & + SIR_WPS_PROBRSP_VER_PRESENT) && + (probeReq.wscIePresent == 1) && + (probeReq.probeReqWscIeInfo.DevicePasswordID.id == + WSC_PASSWD_ID_PUSH_BUTTON) && + (probeReq.probeReqWscIeInfo.UUID_E.present == 1)) + { + if(psessionEntry->fwdWPSPBCProbeReq) + { + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, + pHdr->sa, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBody, frameLen);) + limSendSmeProbeReqInd(pMac, pHdr->sa, pBody, frameLen, psessionEntry); + } + else + { + limUpdatePBCSessionEntry(pMac, + pHdr->sa, probeReq.probeReqWscIeInfo.UUID_E.uuid, psessionEntry); + } + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + if ((wpsApEnable) && + (probeReq.wscIePresent == 1) && + (probeReq.probeReqWscIeInfo.DevicePasswordID.id == WSC_PASSWD_ID_PUSH_BUTTON)) + { + // send the probe req to WSM when it is from a PBC station + pSirSmeProbeReq = vos_mem_malloc(sizeof(tSirSmeProbeReq)); + if ( NULL == pSirSmeProbeReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_PROBE_REQ")); + return; + } + msgQ.type = eWNI_SME_PROBE_REQ; + msgQ.bodyval = 0; + msgQ.bodyptr = pSirSmeProbeReq; + + pSirSmeProbeReq->messageType = eWNI_SME_PROBE_REQ; + pSirSmeProbeReq->length = sizeof(tSirSmeProbeReq); + pSirSmeProbeReq->sessionId = psessionEntry->smeSessionId; + vos_mem_copy(pSirSmeProbeReq->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr)); + pSirSmeProbeReq->devicePasswdId = probeReq.probeReqWscIeInfo.DevicePasswordID.id; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){ + PELOG3(limLog(pMac, LOG3, FL("couldnt send the probe req to wsm "));) + } + } + } + } + + ssId.length = psessionEntry->ssId.length; + /* Copy the SSID from sessio entry to local variable */ + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + + // Compare received SSID with current SSID. If they + // match, reply with Probe Response. + if (probeReq.ssId.length) + { + if (!ssId.length) + goto multipleSSIDcheck; + + if (vos_mem_compare((tANI_U8 *) &ssId, + (tANI_U8 *) &(probeReq.ssId), (tANI_U8) (ssId.length + 1)) ) + { + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + break; + } + else if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + tANI_U8 direct_ssid[7] = "DIRECT-"; + tANI_U8 direct_ssid_len = 7; + if (vos_mem_compare((tANI_U8 *) &direct_ssid, + (tANI_U8 *) &(probeReq.ssId.ssId), (tANI_U8) (direct_ssid_len)) ) + { + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + break; + } + } + else + { + PELOG3(limLog(pMac, LOG3, + FL("Ignoring ProbeReq frame with unmatched SSID received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeBadSsid++; + } + } + else + { + { + // Broadcast SSID in the Probe Request. + // Reply with SSID we're configured with. + //Turn off the SSID length to 0 if hidden SSID feature is present + if(psessionEntry->ssidHidden) + /*We are returning from here as probe request contains the broadcast SSID. + So no need to send the probe resp*/ + return; + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + } + break; + } +multipleSSIDcheck: + { + PELOG3(limLog(pMac, LOG3, + FL("Ignoring ProbeReq frame with unmatched SSID received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeBadSsid++; + } + } + else + { + // Ignore received Probe Request frame + PELOG3(limLog(pMac, LOG3, FL("Ignoring Probe Request frame received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeIgnore++; + break; + } + }while(0); + + return; +} /*** end limProcessProbeReqFrame() ***/ + +/** + * limIndicateProbeReqToHDD + * + *FUNCTION: + * This function is called by limProcessProbeReqFrame_multiple_BSS() upon + * Probe Request frame reception. + * + *LOGIC: + * This function processes received Probe Request frame and Pass + * Probe Request Frame to HDD. + * + * @param pMac Pointer to Global MAC structure + * @param *pBd A pointer to Buffer descriptor + associated PDUs + * @param psessionEntry A pointer to PE session + * + * @return None + */ + +static void +limIndicateProbeReqToHDD(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + + limLog( pMac, LOG1, "Received a probe request frame"); + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + //send the probe req to SME. + limSendSmeMgmtFrameInd( pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), + psessionEntry->smeSessionId, WDA_GET_RX_CH(pBd), + psessionEntry, 0); +} /*** end limIndicateProbeReqToHDD() ***/ + +/** + * limProcessProbeReqFrame_multiple_BSS + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Request frame reception. + * + *LOGIC: + * This function call limIndicateProbeReqToHDD function to indicate + * Probe Request frame to HDD. It also call limProcessProbeReqFrame + * function which process received Probe Request frame and responds + * with Probe Response. + * + * @param pMac Pointer to Global MAC structure + * @param *pBd A pointer to Buffer descriptor + associated PDUs + * @param psessionEntry A pointer to PE session + * + * @return None + */ + +void +limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal pMac, tANI_U8 *pBd, tpPESession psessionEntry) +{ + tANI_U8 i; + + if (psessionEntry != NULL) + { + if ((eLIM_AP_ROLE == psessionEntry->limSystemRole) + ) + { + limIndicateProbeReqToHDD(pMac, pBd, psessionEntry); + } + limProcessProbeReqFrame(pMac,pBd,psessionEntry); + return; + } + + for(i =0; i < pMac->lim.maxBssId;i++) + { + psessionEntry = peFindSessionBySessionId(pMac,i); + if ( (psessionEntry != NULL) ) + { + if ((eLIM_AP_ROLE == psessionEntry->limSystemRole) + ) + { + limIndicateProbeReqToHDD(pMac, pBd, psessionEntry); + } + if ( (eLIM_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole) + ) + { + limProcessProbeReqFrame(pMac,pBd,psessionEntry); + } + } + } + +} /*** end limProcessProbeReqFrame_multiple_BSS() ***/ + +/** + * limSendSmeProbeReqInd() + * + *FUNCTION: + * This function is to send + * eWNI_SME_WPS_PBC_PROBE_REQ_IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_WPS_PBC_PROBE_REQ_IND + * to host. + * + * @param peerMacAddr Indicates the peer MAC addr that the probe request + * is generated. + * @param pProbeReqIE pointer to RAW probe request IE + * @param ProbeReqIELen The length of probe request IE. + * @param psessionEntry A pointer to PE session + * + * @return None + */ +void +limSendSmeProbeReqInd(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U8 *pProbeReqIE, + tANI_U32 ProbeReqIELen, + tpPESession psessionEntry) +{ + tSirSmeProbeReqInd *pSirSmeProbeReqInd; + tSirMsgQ msgQ; + + pSirSmeProbeReqInd = vos_mem_malloc(sizeof(tSirSmeProbeReqInd)); + if ( NULL == pSirSmeProbeReqInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_PROBE_REQ")); + return; + } + + msgQ.type = eWNI_SME_WPS_PBC_PROBE_REQ_IND; + msgQ.bodyval = 0; + msgQ.bodyptr = pSirSmeProbeReqInd; + + pSirSmeProbeReqInd->messageType = eWNI_SME_WPS_PBC_PROBE_REQ_IND; + pSirSmeProbeReqInd->length = sizeof(tSirSmeProbeReq); + pSirSmeProbeReqInd->sessionId = psessionEntry->smeSessionId; + + vos_mem_copy(pSirSmeProbeReqInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + vos_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.peerMacAddr, peerMacAddr, sizeof(tSirMacAddr)); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIELen = (tANI_U16)ProbeReqIELen; + vos_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIE, pProbeReqIE, ProbeReqIELen); + + if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){ + PELOGE(limLog(pMac, LOGE, FL("couldnt send the probe req to hdd"));) + } + +} /*** end limSendSmeProbeReqInd() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c new file mode 100644 index 0000000000000..f67b2f7a1aa15 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessProbeRspFrame.cc contains the code + * for processing Probe Response Frame. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniApi.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limSendMessages.h" + +#include "parserApi.h" + +tSirRetStatus +limValidateIEInformationInProbeRspFrame (tANI_U8 *pRxPacketInfo) +{ + tSirRetStatus status = eSIR_SUCCESS; + + if (WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) < (SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) + { + status = eSIR_FAILURE; + } + + return status; +} + +/** + * limProcessProbeRspFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Response frame reception. + * + *LOGIC: + * This function processes received Probe Response frame. + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Frames with out-of-order IEs are dropped. + * 2. In case of IBSS, join 'success' makes MLM state machine + * transition into 'BSS started' state. This may have to change + * depending on supporting what kinda Authentication in IBSS. + * + * @param pMac Pointer to Global MAC structure + * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs + * @return None + */ + + +void +limProcessProbeRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U32 frameLen = 0; + tSirMacAddr currentBssId; + tpSirMacMgmtHdr pHdr; + tSirProbeRespBeacon *pProbeRsp; + tANI_U8 qosEnabled = false; + tANI_U8 wmeEnabled = false; + + if (!psessionEntry) + { + limLog(pMac, LOGE, FL("psessionEntry is NULL") ); + return; + } + limLog(pMac,LOG1,"SessionId:%d ProbeRsp Frame is received", + psessionEntry->peSessionId); + + pProbeRsp = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pProbeRsp ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessProbeRspFrame") ); + return; + } + + pProbeRsp->ssId.length = 0; + pProbeRsp->wpa.length = 0; + pProbeRsp->propIEinfo.apName.length = 0; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + PELOG2(limLog(pMac, LOG2, + FL("Received Probe Response frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2);) + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + { + vos_mem_free(pProbeRsp); + return; + } + } + + // Validate IE information before processing Probe Response Frame + if (limValidateIEInformationInProbeRspFrame(pRxPacketInfo) != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d"), frameLen);) + vos_mem_free(pProbeRsp); + return; + } + + /** + * Expect Probe Response only when + * 1. STA is in scan mode waiting for Beacon/Probe response or + * 2. STA is waiting for Beacon/Probe Response to announce + * join success or + * 3. STA is in IBSS mode in BSS started state or + * 4. STA/AP is in learn mode + * 5. STA in link established state. In this state, the probe response is + * expected for two scenarios: + * -- As part of heart beat mechanism, probe req is sent out + * -- If QoS Info IE in beacon has a different count for EDCA Params, + * and EDCA IE is not present in beacon, + * then probe req is sent out to get the EDCA params. + * + * Ignore Probe Response frame in all other states + */ + // TO SUPPORT BT-AMP + if (((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) || //mlm state check should be global - 18th oct + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )|| + ((GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)) || + pMac->fScanOffload) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED( + pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE || + !pProbeRsp->ssidPresent) // Enforce Mandatory IEs + { + PELOG1(limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d"), + frameLen);) + vos_mem_free(pProbeRsp); + return; + } + + if (pMac->fScanOffload) + { + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + + //To Support BT-AMP + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE), eANI_BOOLEAN_TRUE); + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) //mlm state check should be global - 18th oct + { + } + else if (psessionEntry->limMlmState == + eLIM_MLM_WT_JOIN_BEACON_STATE) + { + if( psessionEntry->beacon != NULL )//Either Beacon/probe response is required. Hence store it in same buffer. + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + psessionEntry->beacon = vos_mem_malloc(psessionEntry->bcnLen); + if ( NULL == psessionEntry->beacon ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store beacon"));) + } + else + { + //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->beacon, + WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + psessionEntry->bcnLen); + } + + // STA in WT_JOIN_BEACON_STATE + limCheckAndAnnounceJoinSuccess(pMac, pProbeRsp, pHdr, psessionEntry); + } + else if(psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + tpDphHashNode pStaDs = NULL; + /** + * Check if this Probe Response is for + * our Probe Request sent upon reaching + * heart beat threshold + */ + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if ( !vos_mem_compare(currentBssId, pHdr->bssId, sizeof(tSirMacAddr)) ) + { + vos_mem_free(pProbeRsp); + return; + } + + if (!LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + limLog(pMac, LOGW, + FL("Received Probe Resp from AP. So it is alive!!")); + + if (pProbeRsp->HTInfo.present) + limReceivedHBHandler(pMac, (tANI_U8)pProbeRsp->HTInfo.primaryChannel, psessionEntry); + else + limReceivedHBHandler(pMac, (tANI_U8)pProbeRsp->channelNumber, psessionEntry); + } + + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + if (pProbeRsp->channelSwitchPresent || + pProbeRsp->propIEinfo.propChannelSwitchPresent) + { + limUpdateChannelSwitch(pMac, pProbeRsp, psessionEntry); + } + else if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limCancelDot11hChannelSwitch(pMac, psessionEntry); + } + } + + + /** + * Now Process EDCA Parameters, if EDCAParamSet count is different. + * -- While processing beacons in link established state if it is determined that + * QoS Info IE has a different count for EDCA Params, + * and EDCA IE is not present in beacon, + * then probe req is sent out to get the EDCA params. + */ + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + limGetQosMode(psessionEntry, &qosEnabled); + limGetWmeMode(psessionEntry, &wmeEnabled); + PELOG2(limLog(pMac, LOG2, + FL("wmeEdcaPresent: %d wmeEnabled: %d, edcaPresent: %d, qosEnabled: %d, edcaParams.qosInfo.count: %d schObject.gLimEdcaParamSetCount: %d"), + pProbeRsp->wmeEdcaPresent, wmeEnabled, pProbeRsp->edcaPresent, qosEnabled, + pProbeRsp->edcaParams.qosInfo.count, psessionEntry->gLimEdcaParamSetCount);) + if (((pProbeRsp->wmeEdcaPresent && wmeEnabled) || + (pProbeRsp->edcaPresent && qosEnabled)) && + (pProbeRsp->edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount)) + { + if (schBeaconEdcaProcess(pMac, &pProbeRsp->edcaParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("EDCA parameter processing error"));) + else if (pStaDs != NULL) + { + // If needed, downgrade the EDCA parameters + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + PELOGE(limLog(pMac, LOGE, FL("Self Entry missing in Hash Table"));) + + } + + if (psessionEntry->fWaitForProbeRsp == true) + { + limLog(pMac, LOGW, FL("Checking probe response for capability change\n") ); + limDetectChangeInApCapabilities(pMac, pProbeRsp, psessionEntry); + } + } + else if ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)) + limHandleIBSScoalescing(pMac, pProbeRsp, pRxPacketInfo,psessionEntry); + } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ... + + vos_mem_free(pProbeRsp); + // Ignore Probe Response frame in all other states + return; +} /*** end limProcessProbeRspFrame() ***/ + + +void +limProcessProbeRspFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tANI_U8 *pBody; + tANI_U32 frameLen = 0; + tpSirMacMgmtHdr pHdr; + tSirProbeRespBeacon *pProbeRsp; + + pProbeRsp = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pProbeRsp ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessProbeRspFrameNoSession") ); + return; + } + + pProbeRsp->ssId.length = 0; + pProbeRsp->wpa.length = 0; + pProbeRsp->propIEinfo.apName.length = 0; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + limLog(pMac, LOG2, + FL("Received Probe Response frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || + WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))) + { +#endif + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + { + vos_mem_free(pProbeRsp); + return; + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + // Validate IE information before processing Probe Response Frame + if (limValidateIEInformationInProbeRspFrame(pRxPacketInfo) != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1,FL("Parse error ProbeResponse, length=%d"), + frameLen);) + vos_mem_free(pProbeRsp); + return; + } + /* Since there is no psessionEntry, PE cannot be in the following states: + * - eLIM_MLM_WT_JOIN_BEACON_STATE + * - eLIM_MLM_LINK_ESTABLISHED_STATE + * - eLIM_MLM_BSS_STARTED_STATE + * Hence, expect Probe Response only when + * 1. STA is in scan mode waiting for Beacon/Probe response + * 2. LFR logic in FW sends up candidate frames + * + * Ignore Probe Response frame in all other states + */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8) + WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE) + { + limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d\n"), frameLen); + vos_mem_free(pProbeRsp); + return; + } + limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache")); + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + else +#endif + if (pMac->fScanOffload) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) + == eSIR_FAILURE) + { + limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d\n"), frameLen); + vos_mem_free(pProbeRsp); + return; + } + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + else if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) ) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED( + pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE) + { + limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d"), frameLen); + vos_mem_free(pProbeRsp); + return; + } + + if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ) + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } + } + vos_mem_free(pProbeRsp); + return; +} /*** end limProcessProbeRspFrameNew() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c new file mode 100644 index 0000000000000..fa00aedc215d5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -0,0 +1,6608 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limProcessSmeReqMessages.cc contains the code + * for processing SME request messages. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniApi.h" +#include "wniCfgSta.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSmeReqUtils.h" +#include "limIbssPeerMgmt.h" +#include "limAdmitControl.h" +#include "dphHashTable.h" +#include "limSendMessages.h" +#include "limApi.h" +#include "wmmApsd.h" +#include "sirMacProtDef.h" + +#include "sapApi.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif + +/* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK + * in case of P2P Client and starting actual scanning with init scan req/rsp plus in case of concurrency, + * taking care of sending null data and receiving ACK to/from AP/Also SetChannel with calibration is taking + * around 7ms . + */ +#define SCAN_MESSAGING_OVERHEAD 20 // in msecs +#define JOIN_NOA_DURATION 2000 // in msecs +#define OEM_DATA_NOA_DURATION 60 // in msecs +#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME 110 // in msecs + +#define CONV_MS_TO_US 1024 //conversion factor from ms to us + +// SME REQ processing function templates +static void __limProcessSmeStartReq(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeSysReadyInd(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeStartBssReq(tpAniSirGlobal, tpSirMsgQ pMsg); +static void __limProcessSmeScanReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeJoinReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeReassocReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDisassocReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg); +static void limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, + tANI_U32 *pMsg); +static void limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, + tANI_U32 *pMsg); +static void limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg); + +static void limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen); + +static void limUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen); +static void limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg); + +static void limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg); + +void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *); + +extern void peRegisterTLHandle(tpAniSirGlobal pMac); + +#ifdef BACKGROUND_SCAN_ENABLED + +// start the background scan timers if it hasn't already started +static void +__limBackgroundScanInitiate(tpAniSirGlobal pMac) +{ + if (pMac->lim.gLimBackgroundScanStarted) + return; + + //make sure timer is created first + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = true; + pMac->lim.gLimBackgroundScanChannelId = 0; + } +} + +#endif // BACKGROUND_SCAN_ENABLED + +// determine if a fresh scan request must be issued or not +/* +* PE will do fresh scan, if all of the active sessions are in good state (Link Est or BSS Started) +* If one of the sessions is not in one of the above states, then PE does not do fresh scan +* If no session exists (scanning very first time), then PE will always do fresh scan if SME +* asks it to do that. +*/ +static tANI_U8 +__limFreshScanReqd(tpAniSirGlobal pMac, tANI_U8 returnFreshResults) +{ + + tANI_U8 validState = TRUE; + int i; + + limLog(pMac, LOG1, FL("gLimSmeState: %d, returnFreshResults 0x%x"), + pMac->lim.gLimSmeState, returnFreshResults); + if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE) + { + limLog(pMac, LOG1, FL("return FALSE")); + return FALSE; + } + for(i =0; i < pMac->lim.maxBssId; i++) + { + + if(pMac->lim.gpSession[i].valid == TRUE) + { + limLog(pMac, LOG1, + FL("session %d, bsstype %d, limSystemRole %d, limSmeState %d"), + i, + pMac->lim.gpSession[i].bssType, + pMac->lim.gpSession[i].limSystemRole, + pMac->lim.gpSession[i].limSmeState); + if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (pMac->lim.gpSession[i].limSmeState == eLIM_SME_LINK_EST_STATE) )|| + + ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) ) + || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE) + && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) ) + || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ) + && (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) ) + )) + { + validState = FALSE; + break; + } + + } + } + + + if((validState) && + (returnFreshResults & SIR_BG_SCAN_RETURN_FRESH_RESULTS)) { + limLog(pMac, LOG1, FL("validState: %d, return TRUE"), validState); + return TRUE; + } else { + limLog(pMac, LOG1, FL("validState: %d, return FALSE"), validState); + return FALSE; + } +} + + + +/** + * __limIsSmeAssocCnfValid() + * + *FUNCTION: + * This function is called by limProcessLmmMessages() upon + * receiving SME_ASSOC_CNF. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMeasReq Pointer to Received ASSOC_CNF message + * @return true When received SME_ASSOC_CNF is formatted + * correctly + * false otherwise + */ + +inline static tANI_U8 +__limIsSmeAssocCnfValid(tpSirSmeAssocCnf pAssocCnf) +{ + if (limIsGroupAddr(pAssocCnf->peerMacAddr)) + return false; + else + return true; +} /*** end __limIsSmeAssocCnfValid() ***/ + + +/** + * __limGetSmeJoinReqSizeForAlloc() + * + *FUNCTION: + * This function is called in various places to get IE length + * from tSirBssDescription structure + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBssDescr + * @return Total IE length + */ + +static tANI_U16 +__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf) +{ + tANI_U16 len = 0; + + if (!pBuf) + return len; + + pBuf += sizeof(tANI_U16); + len = limGetU16( pBuf ); + return (len + sizeof( tANI_U16 )); +} /*** end __limGetSmeJoinReqSizeForAlloc() ***/ + + +/**---------------------------------------------------------------- +\fn __limIsDeferedMsgForLearn + +\brief Has role only if 11h is enabled. Not used on STA side. + Defers the message if SME is in learn state and brings + the LIM back to normal mode. + +\param pMac +\param pMsg - Pointer to message posted from SME to LIM. +\return TRUE - If defered + FALSE - Otherwise +------------------------------------------------------------------*/ +static tANI_BOOLEAN +__limIsDeferedMsgForLearn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (limIsSystemInScanState(pMac)) + { + if (limDeferMsg(pMac, pMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);) + return eANI_BOOLEAN_FALSE; + } + PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"), + pMsg->type);) + + /** Send finish scan req to HAL only if LIM is not waiting for any response + * from HAL like init scan rsp, start scan rsp etc. + */ + if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) + { + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE); + } + + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +/**---------------------------------------------------------------- +\fn __limIsDeferedMsgForRadar + +\brief Has role only if 11h is enabled. Not used on STA side. + Defers the message if radar is detected. + +\param pMac +\param pMsg - Pointer to message posted from SME to LIM. +\return TRUE - If defered + FALSE - Otherwise +------------------------------------------------------------------*/ +static tANI_BOOLEAN +__limIsDeferedMsgForRadar(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + /** fRadarDetCurOperChan will be set only if we detect radar in current + * operating channel and System Role == AP ROLE */ + //TODO: Need to take care radar detection. + //if (LIM_IS_RADAR_DETECTED(pMac)) + if( 0 ) + { + if (limDeferMsg(pMac, pMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);) + return eANI_BOOLEAN_FALSE; + } + PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"), + pMsg->type);) + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + + +/** + * __limProcessSmeStartReq() + * + *FUNCTION: + * This function is called to process SME_START_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + PELOG1(limLog(pMac, LOG1, FL("Received START_REQ"));) + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + + /// By default do not return after first scan match + pMac->lim.gLimReturnAfterFirstMatch = 0; + + /// By default return unique scan results + pMac->lim.gLimReturnUniqueResults = true; + pMac->lim.gLimSmeScanResultLength = 0; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->lim.gLimSmeLfrScanResultLength = 0; +#endif + + if (((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd) + { + /* + * Need to indicate new BSSs found during background scanning to + * host. Update this parameter at CFG + */ + if (cfgSetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, ((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set NEIGHBOR_BSS_IND at CFG")); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + } + } + } + else + { + /** + * Should not have received eWNI_SME_START_REQ in states + * other than OFFLINE. Return response to host and + * log error + */ + limLog(pMac, LOGE, FL("Invalid SME_START_REQ received in SME state %X"),pMac->lim.gLimSmeState ); + limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + } + limSendSmeRsp(pMac, eWNI_SME_START_RSP, retCode,smesessionId,smetransactionId); +} /*** end __limProcessSmeStartReq() ***/ + + +/** ------------------------------------------------------------- +\fn __limProcessSmeSysReadyInd +\brief handles the notification from HDD. PE just forwards this message to HAL. +\param tpAniSirGlobal pMac +\param tANI_U32* pMsgBuf +\return TRUE-Posting to HAL failed, so PE will consume the buffer. +\ FALSE-Posting to HAL successful, so HAL will consume the buffer. + -------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeSysReadyInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + + msg.type = WDA_SYS_READY_IND; + msg.reserved = 0; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + + if (pMac->gDriverType != eDRIVER_TYPE_MFG) + { + peRegisterTLHandle(pMac); + } + PELOGW(limLog(pMac, LOGW, FL("sending WDA_SYS_READY_IND msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +#ifdef WLAN_FEATURE_11AC + +tANI_U32 limGetCenterChannel(tpAniSirGlobal pMac,tANI_U8 primarychanNum,ePhyChanBondState secondaryChanOffset, tANI_U8 chanWidth) +{ + if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + switch(secondaryChanOffset) + { + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return primarychanNum; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return primarychanNum + 6; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return primarychanNum - 6; + default : + return eSIR_CFG_INVALID_ID; + } + } + else if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + switch(secondaryChanOffset) + { + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + return primarychanNum + 2; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return primarychanNum; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return primarychanNum - 2; + default : + return eSIR_CFG_INVALID_ID; + } + } + return primarychanNum; +} + +#endif +/** + * __limHandleSmeStartBssRequest() + * + *FUNCTION: + * This function is called to process SME_START_BSS_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 size; + tANI_U32 val = 0; + tSirRetStatus retStatus; + tSirMacChanNum channelNumber; + tLimMlmStartReq *pMlmStartReq = NULL; + tpSirSmeStartBssReq pSmeStartBssReq = NULL; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U32 autoGenBssId = FALSE; //Flag Used in case of IBSS to Auto generate BSSID. + tANI_U8 sessionId; + tpPESession psessionEntry = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + //Since the session is not created yet, sending NULL. The response should have the correct state. + limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + PELOG1(limLog(pMac, LOG1, FL("Received START_BSS_REQ"));) + + /* Global Sme state and mlm states are not defined yet, for BT-AMP Suppoprt . TO BE DONE */ + if ( (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) || + (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) + { + size = sizeof(tSirSmeStartBssReq) + SIR_MAC_MAX_IE_LENGTH; + + pSmeStartBssReq = vos_mem_malloc(size); + if ( NULL == pSmeStartBssReq ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for pMac->lim.gpLimStartBssReq"));) + /// Send failure response to host + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + vos_mem_set((void *)pSmeStartBssReq, size, 0); + + if ((limStartBssReqSerDes(pMac, pSmeStartBssReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeStartBssReqValid(pMac, pSmeStartBssReq))) + { + PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));) + retCode = eSIR_SME_INVALID_PARAMETERS; + goto free; + } + + /* This is the place where PE is going to create a session. + * If session is not existed, then create a new session */ + if((psessionEntry = peFindSessionByBssid(pMac,pSmeStartBssReq->bssId,&sessionId)) != NULL) + { + limLog(pMac, LOGW, FL("Session Already exists for given BSSID")); + retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + psessionEntry = NULL; + goto free; + } + else + { + if((psessionEntry = peCreateSession(pMac, + pSmeStartBssReq->bssId, + &sessionId, + pMac->lim.maxStation, + pSmeStartBssReq->bssType)) == NULL) + { + limLog(pMac, LOGW, FL("Session Can not be created ")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + } + + /* Probe resp add ie */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespData_buff, + &psessionEntry->addIeParams.probeRespDataLen, + pSmeStartBssReq->addIeParams.probeRespData_buff, + pSmeStartBssReq->addIeParams.probeRespDataLen); + + /* Probe Beacon add ie */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespBCNData_buff, + &psessionEntry->addIeParams.probeRespBCNDataLen, + pSmeStartBssReq->addIeParams.probeRespBCNData_buff, + pSmeStartBssReq->addIeParams.probeRespBCNDataLen); + + /* Assoc resp IE */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.assocRespData_buff, + &psessionEntry->addIeParams.assocRespDataLen, + pSmeStartBssReq->addIeParams.assocRespData_buff, + pSmeStartBssReq->addIeParams.assocRespDataLen); + + /* Store the session related parameters in newly created session */ + psessionEntry->pLimStartBssReq = pSmeStartBssReq; + + /* Store PE sessionId in session Table */ + psessionEntry->peSessionId = sessionId; + + /* Store SME session Id in sessionTable */ + psessionEntry->smeSessionId = pSmeStartBssReq->sessionId; + + psessionEntry->transactionId = pSmeStartBssReq->transactionId; + + vos_mem_copy(&(psessionEntry->htConfig), &(pSmeStartBssReq->htConfig), + sizeof(psessionEntry->htConfig)); + + sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeStartBssReq->selfMacAddr); + + /* Copy SSID to session table */ + vos_mem_copy( (tANI_U8 *)&psessionEntry->ssId, + (tANI_U8 *)&pSmeStartBssReq->ssId, + (pSmeStartBssReq->ssId.length + 1)); + + psessionEntry->bssType = pSmeStartBssReq->bssType; + + psessionEntry->nwType = pSmeStartBssReq->nwType; + + psessionEntry->beaconParams.beaconInterval = pSmeStartBssReq->beaconInterval; + + /* Store the channel number in session Table */ + psessionEntry->currentOperChannel = pSmeStartBssReq->channelId; + + /*Store Persona */ + psessionEntry->pePersona = pSmeStartBssReq->bssPersona; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,FL("PE PERSONA=%d"), + psessionEntry->pePersona); + + /*Update the phymode*/ + psessionEntry->gLimPhyMode = pSmeStartBssReq->nwType; + + psessionEntry->maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac, + psessionEntry->currentOperChannel ); + /* Store the dot 11 mode in to the session Table*/ + psessionEntry->dot11mode = pSmeStartBssReq->dot11mode; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + psessionEntry->cc_switch_mode = pSmeStartBssReq->cc_switch_mode; +#endif + psessionEntry->htCapability = IS_DOT11_MODE_HT(psessionEntry->dot11mode); +#ifdef WLAN_FEATURE_11AC + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode); + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + FL("*****psessionEntry->vhtCapability = %d"),psessionEntry->vhtCapability); +#endif + + psessionEntry->txLdpcIniFeatureEnabled = + pSmeStartBssReq->txLdpcIniFeatureEnabled; + +#ifdef WLAN_FEATURE_11W + psessionEntry->limRmfEnabled = pSmeStartBssReq->pmfCapable ? 1 : 0; + limLog(pMac, LOG1, FL("Session RMF enabled: %d"), psessionEntry->limRmfEnabled); +#endif + + vos_mem_copy((void*)&psessionEntry->rateSet, + (void*)&pSmeStartBssReq->operationalRateSet, + sizeof(tSirMacRateSet)); + vos_mem_copy((void*)&psessionEntry->extRateSet, + (void*)&pSmeStartBssReq->extendedRateSet, + sizeof(tSirMacRateSet)); + + switch(pSmeStartBssReq->bssType) + { + case eSIR_INFRA_AP_MODE: + psessionEntry->limSystemRole = eLIM_AP_ROLE; + psessionEntry->privacy = pSmeStartBssReq->privacy; + psessionEntry->fwdWPSPBCProbeReq = pSmeStartBssReq->fwdWPSPBCProbeReq; + psessionEntry->authType = pSmeStartBssReq->authType; + /* Store the DTIM period */ + psessionEntry->dtimPeriod = (tANI_U8)pSmeStartBssReq->dtimPeriod; + /*Enable/disable UAPSD*/ + psessionEntry->apUapsdEnable = pSmeStartBssReq->apUapsdEnable; + if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + psessionEntry->proxyProbeRspEn = 0; + } + else + { + /* To detect PBC overlap in SAP WPS mode, Host handles + * Probe Requests. + */ + if(SAP_WPS_DISABLED == pSmeStartBssReq->wps_state) + { + psessionEntry->proxyProbeRspEn = 1; + } + else + { + psessionEntry->proxyProbeRspEn = 0; + } + } + psessionEntry->ssidHidden = pSmeStartBssReq->ssidHidden; + psessionEntry->wps_state = pSmeStartBssReq->wps_state; + psessionEntry->sap_dot11mc = pSmeStartBssReq->sap_dot11mc; + limGetShortSlotFromPhyMode(pMac, psessionEntry, + psessionEntry->gLimPhyMode, + &psessionEntry->shortSlotTimeSupported); + psessionEntry->isCoalesingInIBSSAllowed = + pSmeStartBssReq->isCoalesingInIBSSAllowed; + break; + case eSIR_IBSS_MODE: + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + limGetShortSlotFromPhyMode(pMac, psessionEntry, + psessionEntry->gLimPhyMode, + &psessionEntry->shortSlotTimeSupported); + + // initialize to "OPEN". will be updated upon key installation + psessionEntry->encryptType = eSIR_ED_NONE; + + break; + + case eSIR_BTAMP_AP_MODE: + psessionEntry->limSystemRole = eLIM_BT_AMP_AP_ROLE; + break; + + case eSIR_BTAMP_STA_MODE: + psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + break; + + /* There is one more mode called auto mode. which is used no where */ + + //FORBUILD -TEMPFIX.. HOW TO use AUTO MODE????? + + + default: + //not used anywhere...used in scan function + break; + } + + // BT-AMP: Allocate memory for the array of parsed (Re)Assoc request structure + if ( (pSmeStartBssReq->bssType == eSIR_BTAMP_AP_MODE) + || (pSmeStartBssReq->bssType == eSIR_INFRA_AP_MODE) + ) + { + psessionEntry->parsedAssocReq = vos_mem_malloc( + psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)); + if ( NULL == psessionEntry->parsedAssocReq ) + { + limLog(pMac, LOGW, FL("AllocateMemory() failed")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + vos_mem_set(psessionEntry->parsedAssocReq, + (psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)), + 0 ); + } + + /* Channel Bonding is not addressd yet for BT-AMP Support.. sunit will address channel bonding */ + if (pSmeStartBssReq->channelId) + { + channelNumber = pSmeStartBssReq->channelId; +#ifdef QCA_HT_2040_COEX + if (pSmeStartBssReq->obssEnabled) + psessionEntry->htSupportedChannelWidthSet = + IS_DOT11_MODE_HT(psessionEntry->dot11mode)?1:0; + else +#endif + psessionEntry->htSupportedChannelWidthSet = + (pSmeStartBssReq->cbMode)?1:0; + psessionEntry->htSecondaryChannelOffset = pSmeStartBssReq->cbMode; + psessionEntry->htRecommendedTxWidthSet = + (psessionEntry->htSecondaryChannelOffset)? 1:0; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("cbMode %u"), pSmeStartBssReq->cbMode); +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + tANI_U32 centerChan; + tANI_U32 chanWidth; + + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + + if(channelNumber <= RF_CHAN_14 && + chanWidth != eHT_CHANNEL_WIDTH_20MHZ) + { + chanWidth = eHT_CHANNEL_WIDTH_20MHZ; + limLog(pMac, LOG1, FL("Setting chanWidth to 20Mhz for" + " channel %d"),channelNumber); + } + + if(chanWidth == eHT_CHANNEL_WIDTH_20MHZ || + chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + " WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + } + if (chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + " WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + + centerChan = limGetCenterChannel( pMac, channelNumber, + pSmeStartBssReq->cbMode, + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ); + if(centerChan != eSIR_CFG_INVALID_ID) + { + limLog(pMac, LOGW, FL("***Center Channel for " + "80MHZ channel width = %d"),centerChan); + psessionEntry->apCenterChan = centerChan; + if (cfgSetInt(pMac, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + centerChan) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + } + } + + /* All the translation is done by now for gVhtChannelWidth + * from .ini file to the actual values as defined in spec. + * So, grabing the spec value which is + * updated in .dat file by the above logic */ + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + /*For Sta+p2p-Go concurrency + vhtTxChannelWidthSet is used for storing p2p-GO channel width + apChanWidth is used for storing the AP channel width that the Sta is going to associate. + Initialize the apChanWidth same as p2p-GO channel width this gets over written once the station joins the AP + */ + psessionEntry->vhtTxChannelWidthSet = chanWidth; + psessionEntry->apChanWidth = chanWidth; + } + psessionEntry->htSecondaryChannelOffset = limGetHTCBState(pSmeStartBssReq->cbMode); +#endif + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));) + retCode = eSIR_SME_INVALID_PARAMETERS; + goto free; + } + + // Delete pre-auth list if any + limDeletePreAuthList(pMac); + + psessionEntry->htCapability = IS_DOT11_MODE_HT(pSmeStartBssReq->dot11mode); + + /* keep the RSN/WPA IE information in PE Session Entry + * later will be using this to check when received (Re)Assoc req + * */ + limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac,&pSmeStartBssReq->rsnIE,psessionEntry); + + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)) { + psessionEntry->gLimProtectionControl = pSmeStartBssReq->protEnabled; + /*each byte will have the following info + *bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 + *reserved reserved RIFS Lsig n-GF ht20 11g 11b*/ + vos_mem_copy( (void *) &psessionEntry->cfgProtection, + (void *) &pSmeStartBssReq->ht_capab, + sizeof( tANI_U16 )); + psessionEntry->pAPWPSPBCSession = NULL; // Initialize WPS PBC session link list + } + + // Prepare and Issue LIM_MLM_START_REQ to MLM + pMlmStartReq = vos_mem_malloc(sizeof(tLimMlmStartReq)); + if ( NULL == pMlmStartReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmStartReq")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + + vos_mem_set((void *) pMlmStartReq, sizeof(tLimMlmStartReq), 0); + + /* Copy SSID to the MLM start structure */ + vos_mem_copy( (tANI_U8 *) &pMlmStartReq->ssId, + (tANI_U8 *) &pSmeStartBssReq->ssId, + pSmeStartBssReq->ssId.length + 1); + pMlmStartReq->ssidHidden = pSmeStartBssReq->ssidHidden; + pMlmStartReq->obssProtEnabled = pSmeStartBssReq->obssProtEnabled; + + + pMlmStartReq->bssType = psessionEntry->bssType; + + /* Fill PE session Id from the session Table */ + pMlmStartReq->sessionId = psessionEntry->peSessionId; + + if( (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE) || (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE ) + || (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE) + ) + { + /* Copy the BSSId from sessionTable to mlmStartReq struct */ + sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId); + } + + else // ibss mode + { + pMac->lim.gLimIbssCoalescingHappened = false; + + if((retStatus = wlan_cfgGetInt(pMac, WNI_CFG_IBSS_AUTO_BSSID, &autoGenBssId)) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not retrieve Auto Gen BSSID, retStatus=%d"), retStatus); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + + if(!autoGenBssId) + { + // We're not auto generating BSSID. Instead, get it from session entry + sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId); + + if(pMlmStartReq->bssId[0] & 0x01) + { + PELOGE(limLog(pMac, LOGE, FL("Request to start IBSS with group BSSID\n Autogenerating the BSSID"));) + autoGenBssId = TRUE; + } + } + + if( autoGenBssId ) + { //if BSSID is not any uc id. then use locally generated BSSID. + //Autogenerate the BSSID + limGetRandomBssid( pMac, pMlmStartReq->bssId); + pMlmStartReq->bssId[0]= 0x02; + + /* Copy randomly generated BSSID to the session Table */ + sirCopyMacAddr(psessionEntry->bssId,pMlmStartReq->bssId); + } + } + /* store the channel num in mlmstart req structure */ + pMlmStartReq->channelNumber = psessionEntry->currentOperChannel; + pMlmStartReq->cbMode = pSmeStartBssReq->cbMode; + pMlmStartReq->beaconPeriod = psessionEntry->beaconParams.beaconInterval; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + pMlmStartReq->dtimPeriod = psessionEntry->dtimPeriod; + pMlmStartReq->wps_state = psessionEntry->wps_state; + + }else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve DTIM Period")); + pMlmStartReq->dtimPeriod = (tANI_U8)val; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve Beacon interval")); + pMlmStartReq->cfParamSet.cfpPeriod = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve CFPMaxDuration")); + pMlmStartReq->cfParamSet.cfpMaxDuration = (tANI_U16) val; + + //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context. + vos_mem_copy((void*)&pMlmStartReq->rateSet, (void*)&psessionEntry->rateSet, + sizeof(tSirMacRateSet)); + + // Now populate the 11n related parameters + pMlmStartReq->nwType = psessionEntry->nwType; + pMlmStartReq->htCapable = psessionEntry->htCapability; + // + // FIXME_GEN4 - Determine the appropriate defaults... + // + pMlmStartReq->htOperMode = pMac->lim.gHTOperMode; + pMlmStartReq->dualCTSProtection = pMac->lim.gHTDualCTSProtection; // Unused + pMlmStartReq->txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet; + + psessionEntry->limRFBand = limGetRFBand(channelNumber); + + // Initialize 11h Enable Flag + psessionEntry->lim11hEnable = 0; + if((pMlmStartReq->bssType != eSIR_IBSS_MODE) && + (SIR_BAND_5_GHZ == psessionEntry->limRFBand) ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED ")); + psessionEntry->lim11hEnable = val; + + if (psessionEntry->lim11hEnable && + (eSIR_INFRA_AP_MODE == pMlmStartReq->bssType)) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_DFS_MASTER_ENABLED, &val) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("Fail to get WNI_CFG_DFS_MASTER_ENABLED")); + } + psessionEntry->lim11hEnable = val; + } + } + + if (!psessionEntry->lim11hEnable) + { + if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) != eSIR_SUCCESS) + limLog(pMac, LOGE, FL + ("Fail to set value for WNI_CFG_LOCAL_POWER_CONSTRAINT")); + } + + psessionEntry ->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry ->limSmeState = eLIM_SME_WT_START_BSS_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry ->limSmeState)); + + limPostMlmMessage(pMac, LIM_MLM_START_REQ, (tANI_U32 *) pMlmStartReq); + return; + } + else + { + + limLog(pMac, LOGE, FL("Received unexpected START_BSS_REQ, in state %X"),pMac->lim.gLimSmeState); + retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + goto end; + } // if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + +free: + if ((psessionEntry != NULL) && + (psessionEntry->pLimStartBssReq == pSmeStartBssReq)) + { + psessionEntry->pLimStartBssReq = NULL; + } + vos_mem_free( pSmeStartBssReq); + vos_mem_free( pMlmStartReq); + +end: + + /* This routine should return the sme sessionId and SME transaction Id */ + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId); + + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, retCode,psessionEntry,smesessionId,smetransactionId); +} /*** end __limHandleSmeStartBssRequest() ***/ + + +/**-------------------------------------------------------------- +\fn __limProcessSmeStartBssReq + +\brief Wrapper for the function __limHandleSmeStartBssRequest + This message will be defered until softmac come out of + scan mode or if we have detected radar on the current + operating channel. +\param pMac +\param pMsg + +\return TRUE - If we consumed the buffer + FALSE - If have defered the message. + ---------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeStartBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (__limIsDeferedMsgForLearn(pMac, pMsg) || + __limIsDeferedMsgForRadar(pMac, pMsg)) + { + /** + * If message defered, buffer is not consumed yet. + * So return false + */ + return eANI_BOOLEAN_FALSE; + } + + __limHandleSmeStartBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr); + return eANI_BOOLEAN_TRUE; +} + + +/** + * limGetRandomBssid() + * + * FUNCTION:This function is called to process generate the random number for bssid + * This function is called to process SME_SCAN_REQ message + * from HDD or upper layer application. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * 1. geneartes the unique random number for bssid in ibss + * + * @param pMac Pointer to Global MAC structure + * @param *data Pointer to bssid buffer + * @return None + */ +void limGetRandomBssid(tpAniSirGlobal pMac, tANI_U8 *data) +{ + tANI_U32 random[2] ; + random[0] = tx_time_get(); + random[0] |= (random[0] << 15) ; + random[1] = random[0] >> 1; + vos_mem_copy( data, (tANI_U8*)random, sizeof(tSirMacAddr)); +} + +static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac, + tpSirSmeScanReq pScanReq) +{ + tSirScanOffloadReq *pScanOffloadReq; + tANI_U8 *p; + tANI_U8 *ht_cap_ie; + tSirMsgQ msg; + tANI_U16 i, len, ht_cap_len = 0; + tSirRetStatus rc = eSIR_SUCCESS; + + pMac->lim.fOffloadScanPending = 0; + pMac->lim.fOffloadScanP2PSearch = 0; + + /* The tSirScanOffloadReq will reserve the space for first channel, + so allocate the memory for (numChannels - 1) and uIEFieldLen */ + len = sizeof(tSirScanOffloadReq) + (pScanReq->channelList.numChannels - 1) + + pScanReq->uIEFieldLen; + + if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) { + limLog(pMac, LOG1, + FL("Adding HT Caps IE since dot11mode=%d"), pScanReq->dot11mode); + ht_cap_len = 2 + sizeof(tHtCaps); /* 2 bytes for EID and Length */ + len += ht_cap_len; + } + + pScanOffloadReq = vos_mem_malloc(len); + if ( NULL == pScanOffloadReq ) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed for pScanOffloadReq")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_set( (tANI_U8 *) pScanOffloadReq, len, 0); + + msg.type = WDA_START_SCAN_OFFLOAD_REQ; + msg.bodyptr = pScanOffloadReq; + msg.bodyval = 0; + + vos_mem_copy((tANI_U8 *) pScanOffloadReq->bssId, + (tANI_U8*) pScanReq->bssId, + sizeof(tSirMacAddr)); + + if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) + { + limLog(pMac, LOGE, + FL("Invalid value (%d) for numSsid"), SIR_SCAN_MAX_NUM_SSID); + vos_mem_free (pScanOffloadReq); + return eHAL_STATUS_FAILURE; + } + + pScanOffloadReq->numSsid = pScanReq->numSsid; + for (i = 0; i < pScanOffloadReq->numSsid; i++) + { + pScanOffloadReq->ssId[i].length = pScanReq->ssId[i].length; + vos_mem_copy((tANI_U8 *) pScanOffloadReq->ssId[i].ssId, + (tANI_U8 *) pScanReq->ssId[i].ssId, + pScanOffloadReq->ssId[i].length); + } + + pScanOffloadReq->hiddenSsid = pScanReq->hiddenSsid; + vos_mem_copy((tANI_U8 *) pScanOffloadReq->selfMacAddr, + (tANI_U8 *) pScanReq->selfMacAddr, + sizeof(tSirMacAddr)); + pScanOffloadReq->bssType = pScanReq->bssType; + pScanOffloadReq->dot11mode = pScanReq->dot11mode; + pScanOffloadReq->scanType = pScanReq->scanType; + pScanOffloadReq->minChannelTime = pScanReq->minChannelTime; + pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime; + pScanOffloadReq->restTime= pScanReq->restTime; + + /* for normal scan, the value for p2pScanType should be 0 + always */ + if (pScanReq->p2pSearch) + pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_SEARCH; + + pScanOffloadReq->sessionId = pScanReq->sessionId; + + if (pScanOffloadReq->sessionId >= pMac->lim.maxBssId) + limLog(pMac, LOGE, FL("Invalid pe sessionID : %d"), + pScanOffloadReq->sessionId); + + pScanOffloadReq->channelList.numChannels = + pScanReq->channelList.numChannels; + p = &(pScanOffloadReq->channelList.channelNumber[0]); + for (i = 0; i < pScanOffloadReq->channelList.numChannels; i++) + p[i] = pScanReq->channelList.channelNumber[i]; + + pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen; + pScanOffloadReq->uIEFieldOffset = len - ht_cap_len - + pScanOffloadReq->uIEFieldLen; + vos_mem_copy( + (tANI_U8 *) pScanOffloadReq + pScanOffloadReq->uIEFieldOffset, + (tANI_U8 *) pScanReq + pScanReq->uIEFieldOffset, + pScanReq->uIEFieldLen); + + /* Copy HT Capability info if dot11mode is HT */ + if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) { + /* Populate EID and Length field here */ + ht_cap_ie = (tANI_U8 *) pScanOffloadReq + + pScanOffloadReq->uIEFieldOffset + + pScanOffloadReq->uIEFieldLen; + vos_mem_set(ht_cap_ie, ht_cap_len, 0); + *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID; + *(ht_cap_ie + 1) = ht_cap_len - 2; + lim_set_ht_caps(pMac, NULL, ht_cap_ie, len - ht_cap_len); + pScanOffloadReq->uIEFieldLen += ht_cap_len; + } + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure")); + vos_mem_free(pScanOffloadReq); + return eHAL_STATUS_FAILURE; + } + + pMac->lim.fOffloadScanPending = 1; + if (pScanReq->p2pSearch) + pMac->lim.fOffloadScanP2PSearch = 1; + + limLog(pMac, LOG1, FL("Processed Offload Scan Request Successfully")); + + return eHAL_STATUS_SUCCESS; +} + +/** + * __limProcessSmeScanReq() + * + *FUNCTION: + * This function is called to process SME_SCAN_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Periodic scanning should be requesting to return unique + * scan results. + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tLimMlmScanReq *pMlmScanReq; + tpSirSmeScanReq pScanReq; + tANI_U8 i = 0; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + pScanReq = (tpSirSmeScanReq) pMsgBuf; + limLog(pMac, LOG1, FL("SME SCAN REQ numChan %d min %d max %d IELen %d first %d fresh %d unique %d type %d mode %d rsp %d"), + pScanReq->channelList.numChannels, + pScanReq->minChannelTime, + pScanReq->maxChannelTime, + pScanReq->uIEFieldLen, + pScanReq->returnAfterFirstMatch, + pScanReq->returnFreshResults, + pScanReq->returnUniqueResults, + pScanReq->scanType, + pScanReq->backgroundScanMode, + pMac->lim.gLimRspReqd ? 1 : 0); + + /* Since scan req always requires a response, we will overwrite response required here. + * This is added esp to take care of the condition where in p2p go case, we hold the scan req and + * insert single NOA. We send the held scan request to FW later on getting start NOA ind from FW so + * we lose state of the gLimRspReqd flag for the scan req if any other request comes by then. + * e.g. While unit testing, we found when insert single NOA is done, we see a get stats request which turns the flag + * gLimRspReqd to FALSE; now when we actually start the saved scan req for init scan after getting + * NOA started, the gLimRspReqd being a global flag is showing FALSE instead of TRUE value for + * this saved scan req. Since all scan reqs coming to lim require a response, there is no harm in setting + * the global flag gLimRspReqd to TRUE here. + */ + pMac->lim.gLimRspReqd = TRUE; + + /*copy the Self MAC address from SmeReq to the globalplace, used for sending probe req*/ + sirCopyMacAddr(pMac->lim.gSelfMacAddr, pScanReq->selfMacAddr); + + /* This routine should return the sme sessionId and SME transaction Id */ + + if (!limIsSmeScanReqValid(pMac, pScanReq)) + { + limLog(pMac, LOGE, FL("Received SME_SCAN_REQ with invalid parameters")); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId); + + } // if (pMac->lim.gLimRspReqd) + + return; + } + + /* + * if scan is disabled then return as invalid scan request. + * if scan in power save is disabled, and system is in power save mode, + * then ignore scan request. + */ + if((pMac->lim.fScanDisabled) || + (!pMac->psOffloadEnabled && + !pMac->lim.gScanInPowersave && + !limIsSystemInActiveState(pMac))) + { + limLog(pMac, LOGE, FL("SCAN is disabled or SCAN in power save" + " is disabled and system is in power save.")); + + limSendSmeScanRsp(pMac, offsetof(tSirSmeScanRsp,bssDescription[0]), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId); + return; + } + + + /** + * If scan request is received in idle, joinFailed + * states or in link established state (in STA role) + * or in normal state (in STA-in-IBSS/AP role) with + * 'return fresh scan results' request from HDD or + * it is periodic background scanning request, + * trigger fresh scan request to MLM + */ + if (__limFreshScanReqd(pMac, pScanReq->returnFreshResults)) + { + limLog(pMac, LOG1, FL("Fresh scan is required")); + if (pMac->fScanOffload) + limFlushp2pScanResults(pMac); + + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) + { + // Discard previously cached scan results + limReInitScanResults(pMac); + } + + pMac->lim.gLim24Band11dScanDone = 0; + pMac->lim.gLim50Band11dScanDone = 0; + pMac->lim.gLimReturnAfterFirstMatch = + pScanReq->returnAfterFirstMatch; + pMac->lim.gLimBackgroundScanMode = + pScanReq->backgroundScanMode; + + pMac->lim.gLimReturnUniqueResults = + ((pScanReq->returnUniqueResults) > 0 ? true : false); + + if (pMac->psOffloadEnabled) + { + if ((pMac->lim.gLimBackgroundScanMode != eSIR_ROAMING_SCAN) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + for (i=0;ilim.maxBssId;i++) + { + tpPESession psessionEntry = peFindSessionBySessionId(pMac,i); + if (psessionEntry && psessionEntry->valid && + (eLIM_MLM_LINK_ESTABLISHED_STATE == + psessionEntry->limMlmState) && + (psessionEntry->pmmOffloadInfo.psstate == PMM_FULL_POWER)) + { + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + } + } + } + } + /* De-activate Heartbeat timers for connected sessions while + * scan is in progress if the system is in Active mode * + * AND it is not a ROAMING ("background") scan */ + else if (((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) || + (ePMM_STATE_READY == pMac->pmm.gPmmState)) && + (pScanReq->backgroundScanMode != eSIR_ROAMING_SCAN ) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + for(i=0;ilim.maxBssId;i++) + { + if((peFindSessionBySessionId(pMac,i) != NULL) && + (pMac->lim.gpSession[i].valid == TRUE) && + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState)) + { + limHeartBeatDeactivateAndChangeTimer(pMac, peFindSessionBySessionId(pMac,i)); + } + } + } + + if (pMac->fScanOffload) + { + if (eHAL_STATUS_SUCCESS != + limSendHalStartScanOffloadReq(pMac, pScanReq)) + { + limLog(pMac, LOGE, FL("Couldn't send Offload scan request")); + limSendSmeScanRsp(pMac, + offsetof(tSirSmeScanRsp, bssDescription[0]), + eSIR_SME_INVALID_PARAMETERS, + pScanReq->sessionId, + pScanReq->transactionId); + return; + } + } + else + { + + /*Change Global SME state */ + /* Store the previous SME state */ + limLog(pMac, LOG1, FL("Non Offload SCAN request ")); + pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState; + pMac->lim.gLimSmeState = eLIM_SME_WT_SCAN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, pScanReq->sessionId, pMac->lim.gLimSmeState)); + + if (pScanReq->channelList.numChannels == 0) + { + tANI_U32 cfg_len; + + limLog(pMac, LOG1, + FL("Scan all channels as Number of channels is 0")); + + // Scan all channels + len = sizeof(tLimMlmScanReq) + + (sizeof( pScanReq->channelList.channelNumber ) * (WNI_CFG_VALID_CHANNEL_LIST_LEN - 1)) + + pScanReq->uIEFieldLen; + pMlmScanReq = vos_mem_malloc(len); + if ( NULL == pMlmScanReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmScanReq (%d)"), len); + + return; + } + + // Initialize this buffer + vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0 ); + + cfg_len = WNI_CFG_VALID_CHANNEL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + pMlmScanReq->channelList.channelNumber, + &cfg_len) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Valid channel list")); + } + pMlmScanReq->channelList.numChannels = (tANI_U8) cfg_len; + } + else + { + len = sizeof( tLimMlmScanReq ) - sizeof( pScanReq->channelList.channelNumber ) + + (sizeof( pScanReq->channelList.channelNumber ) * pScanReq->channelList.numChannels ) + + pScanReq->uIEFieldLen; + + pMlmScanReq = vos_mem_malloc(len); + if ( NULL == pMlmScanReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmScanReq(%d)"), len); + + return; + } + + // Initialize this buffer + vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0); + if (pScanReq->channelList.numChannels <= SIR_ESE_MAX_MEAS_IE_REQS) + { + pMlmScanReq->channelList.numChannels = + pScanReq->channelList.numChannels; + } + else + { + limLog(pMac, LOGE, + FL("numChannels is more than the size(%d)"), + pScanReq->channelList.numChannels); + pMlmScanReq->channelList.numChannels = + SIR_ESE_MAX_MEAS_IE_REQS; + } + + vos_mem_copy( pMlmScanReq->channelList.channelNumber, + pScanReq->channelList.channelNumber, + pMlmScanReq->channelList.numChannels); + } + + pMlmScanReq->uIEFieldLen = pScanReq->uIEFieldLen; + pMlmScanReq->uIEFieldOffset = len - pScanReq->uIEFieldLen; + if(pScanReq->uIEFieldLen) + { + vos_mem_copy( (tANI_U8 *)pMlmScanReq+ pMlmScanReq->uIEFieldOffset, + (tANI_U8 *)pScanReq+(pScanReq->uIEFieldOffset), + pScanReq->uIEFieldLen); + } + + pMlmScanReq->bssType = pScanReq->bssType; + vos_mem_copy( pMlmScanReq->bssId, + pScanReq->bssId, + sizeof(tSirMacAddr)); + pMlmScanReq->numSsid = pScanReq->numSsid; + pMlmScanReq->sessionId = pScanReq->sessionId; + + i = 0; + while (i < pMlmScanReq->numSsid) + { + vos_mem_copy( (tANI_U8 *) &pMlmScanReq->ssId[i], + (tANI_U8 *) &pScanReq->ssId[i], + pScanReq->ssId[i].length + 1); + + i++; + } + + + pMlmScanReq->scanType = pScanReq->scanType; + pMlmScanReq->backgroundScanMode = pScanReq->backgroundScanMode; + pMlmScanReq->minChannelTime = pScanReq->minChannelTime; + pMlmScanReq->maxChannelTime = pScanReq->maxChannelTime; + pMlmScanReq->minChannelTimeBtc = pScanReq->minChannelTimeBtc; + pMlmScanReq->maxChannelTimeBtc = pScanReq->maxChannelTimeBtc; + pMlmScanReq->dot11mode = pScanReq->dot11mode; + pMlmScanReq->p2pSearch = pScanReq->p2pSearch; + + //Store the smeSessionID and transaction ID for later use. + pMac->lim.gSmeSessionId = pScanReq->sessionId; + pMac->lim.gTransactionId = pScanReq->transactionId; + + // Issue LIM_MLM_SCAN_REQ to MLM + limLog(pMac, LOG1, FL("Issue Scan request command to MLM ")); + limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq); + } + } // if ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ... + + else + { + /// In all other cases return 'cached' scan results + if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults) + { + tANI_U16 scanRspLen = sizeof(tSirSmeScanRsp); + + pMac->lim.gLimRspReqd = false; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pScanReq->returnFreshResults & SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS) + { + pMac->lim.gLimSmeLfrScanResultLength = pMac->lim.gLimMlmLfrScanResultLength; + limLog(pMac, LOG1, + FL("Returned scan results from LFR cache, length = %d"), + pMac->lim.gLimSmeLfrScanResultLength); + + if (pMac->lim.gLimSmeLfrScanResultLength == 0) + { + limSendSmeLfrScanRsp(pMac, scanRspLen, + eSIR_SME_SUCCESS, + pScanReq->sessionId, + pScanReq->transactionId); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeLfrScanResultLength - + sizeof(tSirBssDescription); + limSendSmeLfrScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } + } + else + { +#endif + limLog(pMac, LOG1, + FL("Returned scan results from normal cache, length = %d"), + pMac->lim.gLimSmeScanResultLength); + if (pMac->lim.gLimSmeScanResultLength == 0) + { + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + limLog(pMac, LOG1, FL("Cached scan results are returned ")); + + if (pMac->fScanOffload) + limFlushp2pScanResults(pMac); + + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) + { + // Discard previously cached scan results + limReInitScanResults(pMac); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_LFR_RESULTS) + { + // Discard previously cached scan results + limReInitLfrScanResults(pMac); + } +#endif + + } // if (pMac->lim.gLimRspReqd) + } // else ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ... + +#ifdef BACKGROUND_SCAN_ENABLED + // start background scans if needed + // There is a bug opened against softmac. Need to enable when the bug is fixed. + __limBackgroundScanInitiate(pMac); +#endif + +} /*** end __limProcessSmeScanReq() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +static void __limProcessSmeOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirOemDataReq pOemDataReq; + tLimMlmOemDataReq* pMlmOemDataReq; + + pOemDataReq = (tpSirOemDataReq) pMsgBuf; + + //post the lim mlm message now + pMlmOemDataReq = vos_mem_malloc(sizeof(tLimMlmOemDataReq)); + if ( NULL == pMlmOemDataReq ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for mlmOemDataReq")); + return; + } + + //Initialize this buffer + vos_mem_set( pMlmOemDataReq, (sizeof(tLimMlmOemDataReq)), 0); + + vos_mem_copy( pMlmOemDataReq->selfMacAddr, pOemDataReq->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( pMlmOemDataReq->oemDataReq, pOemDataReq->oemDataReq, + OEM_DATA_REQ_SIZE); + + //Issue LIM_MLM_OEM_DATA_REQ to MLM + limPostMlmMessage(pMac, LIM_MLM_OEM_DATA_REQ, (tANI_U32*)pMlmOemDataReq); + + return; + +} /*** end __limProcessSmeOemDataReq() ***/ + +#endif //FEATURE_OEM_DATA_SUPPORT + +/** + * __limProcessClearDfsChannelList() + * + *FUNCTION: + *Clear DFS channel list when country is changed/aquired. +.*This message is sent from SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void __limProcessClearDfsChannelList(tpAniSirGlobal pMac, + tpSirMsgQ pMsg) +{ + vos_mem_set( &pMac->lim.dfschannelList, + sizeof(tSirDFSChannelList), 0); +} + +/** + * __limProcessSmeJoinReq() + * + *FUNCTION: + * This function is called to process SME_JOIN_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // tANI_U8 *pBuf; + //tANI_U32 len; +// tSirMacAddr currentBssId; + tpSirSmeJoinReq pSmeJoinReq = NULL; + tLimMlmJoinReq *pMlmJoinReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U32 val = 0; + tANI_U16 nSize; + tANI_U8 sessionId; + tpPESession psessionEntry = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + tPowerdBm localPowerConstraint = 0, regMax = 0; + tANI_U16 ieLen; + v_U8_t *vendorIE; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + //Not sending any session, since it is not created yet. The response whould have correct state. + limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + PELOG1(limLog(pMac, LOG1, FL("Received SME_JOIN_REQ"));) + +#ifdef WLAN_FEATURE_VOWIFI + /* Need to read the CFG here itself as this is used in limExtractAPCapability() below. + * This CFG is actually read in rrmUpdateConfig() which is called later. Because this is not + * read, RRM related path before calling rrmUpdateConfig() is not getting executed causing issues + * like not honoring power constraint on 1st association after driver loading. */ + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get rrm enabled failed")); + pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0; + val = 0; +#endif /* WLAN_FEATURE_VOWIFI */ + + /** + * Expect Join request in idle state. + * Reassociate request is expected in link established state. + */ + + /* Global SME and LIM states are not defined yet for BT-AMP Support */ + if(pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) + { + nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8*) pMsgBuf); + + pSmeJoinReq = vos_mem_malloc(nSize); + if ( NULL == pSmeJoinReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for " + "pSmeJoinReq")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + (void) vos_mem_set((void *) pSmeJoinReq, nSize, 0); + + if ((limJoinReqSerDes(pMac, pSmeJoinReq, (tANI_U8 *)pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeJoinReqValid(pMac, pSmeJoinReq))) + { + /// Received invalid eWNI_SME_JOIN_REQ + // Log the event + limLog(pMac, LOGW, FL("SessionId:%d Received SME_JOIN_REQ with invalid data"), + pSmeJoinReq->sessionId); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + /* check for the existence of start BSS session */ +#ifdef FIXME_GEN6 + if(pSmeJoinReq->bsstype == eSIR_BTAMP_AP_MODE) + { + if(peValidateBtJoinRequest(pMac)!= TRUE) + { + limLog(pMac, LOGW, FL("SessionId:%d Start Bss session not present::SME_JOIN_REQ in unexpected state"), + pSmeJoinReq->sessionId); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + psessionEntry = NULL; + goto end; + } + } + +#endif + + + if((psessionEntry = peFindSessionByBssid(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId)) != NULL) + { + limLog(pMac, LOGE, FL("Session(%d) Already exists for BSSID: " + MAC_ADDRESS_STR" in limSmeState = %X"),sessionId, + MAC_ADDR_ARRAY(pSmeJoinReq->bssDescription.bssId), + psessionEntry->limSmeState); + + if(psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE && + psessionEntry->smeSessionId == pSmeJoinReq->sessionId) + { + // Received eWNI_SME_JOIN_REQ for same + // BSS as currently associated. + // Log the event and send success + PELOGW(limLog(pMac, LOGW, FL("SessionId:%d Received SME_JOIN_REQ for currently joined BSS"), + sessionId);) + /// Send Join success response to host + retCode = eSIR_SME_ALREADY_JOINED_A_BSS; + psessionEntry = NULL; + goto end; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("SME_JOIN_REQ not for" + "currently joined BSS"));) + retCode = eSIR_SME_REFUSED; + psessionEntry = NULL; + goto end; + } + } + else /* Session Entry does not exist for given BSSId */ + { + /* Try to Create a new session */ + if((psessionEntry = peCreateSession(pMac, + pSmeJoinReq->bssDescription.bssId, + &sessionId, + pMac->lim.maxStation, + eSIR_INFRASTRUCTURE_MODE )) == NULL) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + limLog(pMac,LOG1,FL("SessionId:%d New session created"), + sessionId); + } + handleHTCapabilityandHTInfo(pMac, psessionEntry); + psessionEntry->isAmsduSupportInAMPDU = pSmeJoinReq->isAmsduSupportInAMPDU; + + /* Store Session related parameters */ + /* Store PE session Id in session Table */ + psessionEntry->peSessionId = sessionId; + + /* store the smejoin req handle in session table */ + psessionEntry->pLimJoinReq = pSmeJoinReq; + + /* Store SME session Id in sessionTable */ + psessionEntry->smeSessionId = pSmeJoinReq->sessionId; + + /* Store SME transaction Id in session Table */ + psessionEntry->transactionId = pSmeJoinReq->transactionId; + + /* Store beaconInterval */ + psessionEntry->beaconParams.beaconInterval = pSmeJoinReq->bssDescription.beaconInterval; + + vos_mem_copy(&(psessionEntry->htConfig), &(pSmeJoinReq->htConfig), + sizeof(psessionEntry->htConfig)); + + /* Copying of bssId is already done, while creating session */ + sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeJoinReq->selfMacAddr); + psessionEntry->bssType = pSmeJoinReq->bsstype; + + psessionEntry->statypeForBss = STA_ENTRY_PEER; + psessionEntry->limWmeEnabled = pSmeJoinReq->isWMEenabled; + psessionEntry->limQosEnabled = pSmeJoinReq->isQosEnabled; + + /* Store vendor specfic IE for CISCO AP */ + ieLen = (pSmeJoinReq->bssDescription.length + + sizeof( pSmeJoinReq->bssDescription.length ) - + GET_FIELD_OFFSET( tSirBssDescription, ieFields )); + + vendorIE = limGetVendorIEOuiPtr(pMac, SIR_MAC_CISCO_OUI, + SIR_MAC_CISCO_OUI_SIZE, + ((tANI_U8 *)&pSmeJoinReq->bssDescription.ieFields) , ieLen); + + if ( NULL != vendorIE ) + { + limLog(pMac, LOGE, + FL("DUT is trying to connect to Cisco AP")); + psessionEntry->isCiscoVendorAP = TRUE; + } + else + { + psessionEntry->isCiscoVendorAP = FALSE; + } + + /* Copy the dot 11 mode in to the session table */ + + psessionEntry->dot11mode = pSmeJoinReq->dot11mode; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + psessionEntry->cc_switch_mode = pSmeJoinReq->cc_switch_mode; +#endif + psessionEntry->nwType = pSmeJoinReq->bssDescription.nwType; + psessionEntry->enableAmpduPs = pSmeJoinReq->enableAmpduPs; + psessionEntry->enableHtSmps = pSmeJoinReq->enableHtSmps; + psessionEntry->htSmpsvalue = pSmeJoinReq->htSmps; + + /*Store Persona */ + psessionEntry->pePersona = pSmeJoinReq->staPersona; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("PE PERSONA=%d cbMode %u"), psessionEntry->pePersona, + pSmeJoinReq->cbMode); +#ifdef WLAN_FEATURE_11AC + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: vhtCapability=%d****",psessionEntry->vhtCapability); + if (psessionEntry->vhtCapability ) + { + if (psessionEntry->pePersona == VOS_STA_MODE) + { + psessionEntry->txBFIniFeatureEnabled = pSmeJoinReq->txBFIniFeatureEnabled; + } + else + { + psessionEntry->txBFIniFeatureEnabled = 0; + } + psessionEntry->txMuBformee = pSmeJoinReq->txMuBformee; + psessionEntry->enableVhtpAid = pSmeJoinReq->enableVhtpAid; + psessionEntry->enableVhtGid = pSmeJoinReq->enableVhtGid; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: txBFIniFeatureEnabled=%d****", + psessionEntry->txBFIniFeatureEnabled); + + if( psessionEntry->txBFIniFeatureEnabled ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, psessionEntry->txBFIniFeatureEnabled) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: txBFCsnValue=%d****", + pSmeJoinReq->txBFCsnValue); + + if (cfgSetInt(pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, pSmeJoinReq->txBFCsnValue) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + } + } + +#endif + + /*Phy mode*/ + psessionEntry->gLimPhyMode = pSmeJoinReq->bssDescription.nwType; + + /* Copy The channel Id to the session Table */ + psessionEntry->currentOperChannel = pSmeJoinReq->bssDescription.channelId; + psessionEntry->htSupportedChannelWidthSet = (pSmeJoinReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + psessionEntry->htSecondaryChannelOffset = pSmeJoinReq->cbMode; + + /* Record if management frames need to be protected */ +#ifdef WLAN_FEATURE_11W + if(eSIR_ED_AES_128_CMAC == pSmeJoinReq->MgmtEncryptionType) + { + VOS_STATUS vosStatus; + psessionEntry->limRmfEnabled = 1; + /* + * For STA profile only: + * init pmf comeback timer and info struct only if PMF connection + */ + psessionEntry->pmfComebackTimerInfo.pMac = pMac; + psessionEntry->pmfComebackTimerInfo.sessionID = sessionId; + vosStatus = vos_timer_init(&psessionEntry->pmfComebackTimer, + VOS_TIMER_TYPE_SW, + limPmfComebackTimerCallback, + (void*)&psessionEntry->pmfComebackTimerInfo); + if (VOS_STATUS_SUCCESS != vosStatus) { + limLog(pMac, LOGP, + FL("cannot init pmf comeback timer.")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + } + else + { + psessionEntry->limRmfEnabled = 0; + } +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM + psessionEntry->rssi = pSmeJoinReq->bssDescription.rssi; +#endif + + + /* Copy the SSID from smejoinreq to session entry */ + psessionEntry->ssId.length = pSmeJoinReq->ssId.length; + vos_mem_copy( psessionEntry->ssId.ssId, + pSmeJoinReq->ssId.ssId, psessionEntry->ssId.length); + + // Determin 11r or ESE connection based on input from SME + // which inturn is dependent on the profile the user wants to connect + // to, So input is coming from supplicant +#ifdef WLAN_FEATURE_VOWIFI_11R + psessionEntry->is11Rconnection = pSmeJoinReq->is11Rconnection; +#endif +#ifdef FEATURE_WLAN_ESE + psessionEntry->isESEconnection = pSmeJoinReq->isESEconnection; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + psessionEntry->isFastTransitionEnabled = pSmeJoinReq->isFastTransitionEnabled; +#endif + +#ifdef FEATURE_WLAN_LFR + psessionEntry->isFastRoamIniFeatureEnabled = pSmeJoinReq->isFastRoamIniFeatureEnabled; +#endif + psessionEntry->txLdpcIniFeatureEnabled = pSmeJoinReq->txLdpcIniFeatureEnabled; + + if (psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + { + psessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else + { + /* Throw an error and return and make sure to delete the session.*/ + limLog(pMac, LOGE, FL("received SME_JOIN_REQ with invalid" + " bss type %d"), psessionEntry->bssType); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + if (pSmeJoinReq->addIEScan.length) + { + vos_mem_copy( &psessionEntry->pLimJoinReq->addIEScan, + &pSmeJoinReq->addIEScan, sizeof(tSirAddie)); + } + + if (pSmeJoinReq->addIEAssoc.length) + { + vos_mem_copy( &psessionEntry->pLimJoinReq->addIEAssoc, + &pSmeJoinReq->addIEAssoc, sizeof(tSirAddie)); + } + + val = sizeof(tLimMlmJoinReq) + psessionEntry->pLimJoinReq->bssDescription.length + 2; + pMlmJoinReq = vos_mem_malloc(val); + if ( NULL == pMlmJoinReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory " + "failed for mlmJoinReq")); + return; + } + (void) vos_mem_set((void *) pMlmJoinReq, val, 0); + + /* PE SessionId is stored as a part of JoinReq*/ + pMlmJoinReq->sessionId = psessionEntry->peSessionId; + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, (tANI_U32 *) &pMlmJoinReq->joinFailureTimeout) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve JoinFailureTimer value")); + + /* copy operational rate from psessionEntry*/ + vos_mem_copy((void*)&psessionEntry->rateSet, (void*)&pSmeJoinReq->operationalRateSet, + sizeof(tSirMacRateSet)); + vos_mem_copy((void*)&psessionEntry->extRateSet, (void*)&pSmeJoinReq->extendedRateSet, + sizeof(tSirMacRateSet)); + //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context. + vos_mem_copy((void*)&pMlmJoinReq->operationalRateSet, (void*)&psessionEntry->rateSet, + sizeof(tSirMacRateSet)); + + psessionEntry->encryptType = pSmeJoinReq->UCEncryptionType; + + pMlmJoinReq->bssDescription.length = psessionEntry->pLimJoinReq->bssDescription.length; + + vos_mem_copy((tANI_U8 *) &pMlmJoinReq->bssDescription.bssId, + (tANI_U8 *) &psessionEntry->pLimJoinReq->bssDescription.bssId, + psessionEntry->pLimJoinReq->bssDescription.length + 2); + + psessionEntry->limCurrentBssCaps = + psessionEntry->pLimJoinReq->bssDescription.capabilityInfo; + + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + + if(!pMac->psOffloadEnabled) + { + limExtractApCapability( pMac, + (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields, + limGetIElenFromBssDescription( + &psessionEntry->pLimJoinReq->bssDescription), + &psessionEntry->limCurrentBssQosCaps, + &psessionEntry->limCurrentBssPropCap, + &pMac->lim.gLimCurrentBssUapsd + , &localPowerConstraint, + psessionEntry + ); + } + else + { + limExtractApCapability( pMac, + (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields, + limGetIElenFromBssDescription( + &psessionEntry->pLimJoinReq->bssDescription), + &psessionEntry->limCurrentBssQosCaps, + &psessionEntry->limCurrentBssPropCap, + &psessionEntry->gLimCurrentBssUapsd, + &localPowerConstraint, + psessionEntry + ); + } + +#ifdef FEATURE_WLAN_ESE + psessionEntry->maxTxPower = limGetMaxTxPower(regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap); +#else + psessionEntry->maxTxPower = VOS_MIN( regMax, (localPowerConstraint) ); +#endif +#if defined WLAN_VOWIFI_DEBUG + limLog( pMac, LOGE, "Regulatory max = %d, local power constraint = %d," + " max tx = %d", regMax, localPowerConstraint, + psessionEntry->maxTxPower ); +#endif + + if(!pMac->psOffloadEnabled) + { + if (pMac->lim.gLimCurrentBssUapsd) + { + pMac->lim.gUapsdPerAcBitmask = + psessionEntry->pLimJoinReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, + FL("UAPSD flag for all AC - 0x%2x"), + pMac->lim.gUapsdPerAcBitmask); + + // resetting the dynamic uapsd mask + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + } + } + else + { + if (psessionEntry->gLimCurrentBssUapsd) + { + psessionEntry->gUapsdPerAcBitmask = + psessionEntry->pLimJoinReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, + FL("UAPSD flag for all AC - 0x%2x"), + psessionEntry->gUapsdPerAcBitmask); + + /* resetting the dynamic uapsd mask */ + psessionEntry->gUapsdPerAcDeliveryEnableMask = 0; + psessionEntry->gUapsdPerAcTriggerEnableMask = 0; + } + } + + psessionEntry->limRFBand = limGetRFBand(psessionEntry->currentOperChannel); + + // Initialize 11h Enable Flag + if(SIR_BAND_5_GHZ == psessionEntry->limRFBand) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED ")); + psessionEntry->lim11hEnable = val; + } + else + psessionEntry->lim11hEnable = 0; + + //To care of the scenario when STA transitions from IBSS to Infrastructure mode. + pMac->lim.gLimIbssCoalescingHappened = false; + + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_JOIN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limLog(pMac, LOG1, FL("SME JoinReq:Sessionid %d SSID len %d SSID : %s " + "Channel %d, BSSID "MAC_ADDRESS_STR), pMlmJoinReq->sessionId, + psessionEntry->ssId.length,psessionEntry->ssId.ssId, + psessionEntry->currentOperChannel, + MAC_ADDR_ARRAY(psessionEntry->bssId)); + + /* Indicate whether spectrum management is enabled*/ + psessionEntry->spectrumMgtEnabled = + pSmeJoinReq->spectrumMgtIndicator; + + /* Enable the spectrum management if this is a DFS channel */ + if (psessionEntry->countryInfoPresent && + limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + psessionEntry->spectrumMgtEnabled = TRUE; + + psessionEntry->isOSENConnection = + pSmeJoinReq->isOSENConnection; + + PELOG1(limLog(pMac,LOG1,FL("SessionId:%d MLM_JOIN_REQ is posted to MLM SM"), + pMlmJoinReq->sessionId)); + /* Issue LIM_MLM_JOIN_REQ to MLM */ + limPostMlmMessage(pMac, LIM_MLM_JOIN_REQ, (tANI_U32 *) pMlmJoinReq); + return; + + } + else + { + /* Received eWNI_SME_JOIN_REQ un expected state */ + limLog(pMac, LOGE, FL("received unexpected SME_JOIN_REQ " + "in state %X"), pMac->lim.gLimSmeState); + limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + psessionEntry = NULL; + goto end; + + } + +end: + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId); + + if(pSmeJoinReq) + { + vos_mem_free(pSmeJoinReq); + pSmeJoinReq = NULL; + if (NULL != psessionEntry) + { + psessionEntry->pLimJoinReq = NULL; + } + } + + if(retCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limLog(pMac, LOG1, FL("Sending failure status limSendSmeJoinReassocRsp" + "on sessionid: %d with retCode = %d"),smesessionId, retCode); + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry,smesessionId,smetransactionId); +} /*** end __limProcessSmeJoinReq() ***/ + + +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI +tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower, tANI_U8 iniTxPower) +{ + tANI_U8 maxTxPower = 0; + tANI_U8 txPower = VOS_MIN( regMax, (apTxPower) ); + txPower = VOS_MIN(txPower, iniTxPower); + if((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP)) + maxTxPower = txPower; + else if (txPower < MIN_TX_PWR_CAP) + maxTxPower = MIN_TX_PWR_CAP; + else + maxTxPower = MAX_TX_PWR_CAP; + + return (maxTxPower); +} +#endif + +/** + * __limProcessSmeReassocReq() + * + *FUNCTION: + * This function is called to process SME_REASSOC_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 caps; + tANI_U32 val; + tpSirSmeJoinReq pReassocReq = NULL; + tLimMlmReassocReq *pMlmReassocReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tANI_U8 smeSessionId; + tANI_U16 transactionId; + tPowerdBm localPowerConstraint = 0, regMax = 0; + tANI_U32 teleBcnEn = 0; + tANI_U16 nSize; + + + PELOG3(limLog(pMac, LOG3, FL("Received REASSOC_REQ"));) + + nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) pMsgBuf); + pReassocReq = vos_mem_malloc(nSize); + if ( NULL == pReassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for pReassocReq")); + + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + (void) vos_mem_set((void *) pReassocReq, nSize, 0); + if ((limJoinReqSerDes(pMac, (tpSirSmeJoinReq) pReassocReq, + (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeJoinReqValid(pMac, + (tpSirSmeJoinReq) pReassocReq))) + { + /// Received invalid eWNI_SME_REASSOC_REQ + // Log the event + limLog(pMac, LOGW, + FL("received SME_REASSOC_REQ with invalid data")); + + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac,pReassocReq->bssDescription.bssId,&sessionId))==NULL) + { + // Because of wrong bssid in ReAssoc request, we are not able to find + // pe session in our list of sessions, this is then sent to upper layer + // with sme_session id same as in request. Upper layers then cause a + // DISASSOC for sme session (wrong, this should not happen) + // Hence: + // Ideally we should not return error here to upper layer, + // since the request was for some other BSSID, session for which is not + // present in our sessions array + + // for IR-063901, an old roam command that is somehow coming after + // connection is established with a newer AP. Since older AP is already + // removed from our list, hence no session is found, causing disconnect + // with new AP instead. + limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE); + limLog(pMac, LOGE, FL("Session does not exist for given bssId")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + //pMac->lim.gpLimReassocReq = pReassocReq;//TO SUPPORT BT-AMP + + /* Store the reassoc handle in the session Table.. 23rd sep review */ + psessionEntry->pLimReAssocReq = pReassocReq; + /** + * Reassociate request is expected + * in link established state only. + */ + + if (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE) + { +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + { + // May be from 11r FT pre-auth. So lets check it before we bail out + limLog(pMac, LOG1, FL("Session in reassoc state is %d"), + psessionEntry->peSessionId); + + // Make sure its our preauth bssid + if (!vos_mem_compare( pReassocReq->bssDescription.bssId, + psessionEntry->limReAssocbssId, 6)) + { + limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE); + limLog(pMac, LOGP, FL("Unknown bssId in reassoc state")); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + limProcessMlmFTReassocReq(pMac, pMsgBuf, psessionEntry); + return; + } +#endif + /// Should not have received eWNI_SME_REASSOC_REQ + // Log the event + limLog(pMac, LOGE, + FL("received unexpected SME_REASSOC_REQ in state %X"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto end; + } + + vos_mem_copy( psessionEntry->limReAssocbssId, + psessionEntry->pLimReAssocReq->bssDescription.bssId, + sizeof(tSirMacAddr)); + + psessionEntry->limReassocChannelId = + psessionEntry->pLimReAssocReq->bssDescription.channelId; + + psessionEntry->reAssocHtSupportedChannelWidthSet = + (psessionEntry->pLimReAssocReq->cbMode)?1:0; + psessionEntry->reAssocHtRecommendedTxWidthSet = + psessionEntry->reAssocHtSupportedChannelWidthSet; + psessionEntry->reAssocHtSecondaryChannelOffset = + psessionEntry->pLimReAssocReq->cbMode; + + psessionEntry->limReassocBssCaps = + psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo; + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + + if(!pMac->psOffloadEnabled) + { + limExtractApCapability( pMac, + (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields, + limGetIElenFromBssDescription( + &psessionEntry->pLimReAssocReq->bssDescription), + &psessionEntry->limReassocBssQosCaps, + &psessionEntry->limReassocBssPropCap, + &pMac->lim.gLimCurrentBssUapsd + , &localPowerConstraint, + psessionEntry + ); + } + else + { + limExtractApCapability(pMac, + (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields, + limGetIElenFromBssDescription( + &psessionEntry->pLimReAssocReq->bssDescription), + &psessionEntry->limReassocBssQosCaps, + &psessionEntry->limReassocBssPropCap, + &psessionEntry->gLimCurrentBssUapsd, + &localPowerConstraint, + psessionEntry); + } + + psessionEntry->maxTxPower = VOS_MIN( regMax, (localPowerConstraint) ); +#if defined WLAN_VOWIFI_DEBUG + limLog( pMac, LOGE, "Regulatory max = %d, local power constraint " + "= %d, max tx = %d", regMax, localPowerConstraint, + psessionEntry->maxTxPower ); +#endif + { + + /* Copy the SSID from session entry to local variable */ + psessionEntry->limReassocSSID.length = pReassocReq->ssId.length; + vos_mem_copy(psessionEntry->limReassocSSID.ssId, + pReassocReq->ssId.ssId, psessionEntry->limReassocSSID.length); + + } + + if(!pMac->psOffloadEnabled) + { + if (pMac->lim.gLimCurrentBssUapsd) + { + pMac->lim.gUapsdPerAcBitmask = + psessionEntry->pLimReAssocReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, + FL("UAPSD flag for all AC - 0x%2x"), + pMac->lim.gUapsdPerAcBitmask); + } + } + else + { + if(psessionEntry->gLimCurrentBssUapsd) + { + psessionEntry->gUapsdPerAcBitmask = + psessionEntry->pLimReAssocReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, + FL("UAPSD flag for all AC - 0x%2x"), + psessionEntry->gUapsdPerAcBitmask); + } + } + + pMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pMlmReassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmReassocReq")); + + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + vos_mem_copy( pMlmReassocReq->peerMacAddr, + psessionEntry->limReAssocbssId, + sizeof(tSirMacAddr)); + + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + pMlmReassocReq->capabilityInfo = caps; + + /* Update PE sessionId*/ + pMlmReassocReq->sessionId = sessionId; + + /* If telescopic beaconing is enabled, set listen interval to + WNI_CFG_TELE_BCN_MAX_LI */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + + val = WNI_CFG_LISTEN_INTERVAL_STADEF; + + if(teleBcnEn) + { + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != + eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + + /* Delete all BA sessions before Re-Assoc. + * BA frames are class 3 frames and the session + * is lost upon disassociation and reassociation. + */ + + limDeleteBASessions(pMac, psessionEntry, BA_BOTH_DIRECTIONS); + + pMlmReassocReq->listenInterval = (tANI_U16) val; + + /* Indicate whether spectrum management is enabled*/ + psessionEntry->spectrumMgtEnabled = pReassocReq->spectrumMgtIndicator; + + /* Enable the spectrum management if this is a DFS channel */ + if (psessionEntry->countryInfoPresent && + limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + psessionEntry->spectrumMgtEnabled = TRUE; + + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limPostMlmMessage(pMac, + LIM_MLM_REASSOC_REQ, + (tANI_U32 *) pMlmReassocReq); + return; + +end: + if (pReassocReq) { + vos_mem_free( pReassocReq); + if (psessionEntry) + psessionEntry->pLimReAssocReq = NULL; + } + + if (psessionEntry) + { + // error occurred after we determined the session so extract + // session and transaction info from there + smeSessionId = psessionEntry->smeSessionId; + transactionId = psessionEntry->transactionId; + } + else + { + // error occurred before or during the time we determined the session + // so extract the session and transaction info from the message + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId); + } + + /// Send Reassoc failure response to host + /// (note psessionEntry may be NULL, but that's OK) + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry, smeSessionId, transactionId); + +} /*** end __limProcessSmeReassocReq() ***/ + + +tANI_BOOLEAN sendDisassocFrame = 1; +/** + * __limProcessSmeDisassocReq() + * + *FUNCTION: + * This function is called to process SME_DISASSOC_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 disassocTrigger, reasonCode; + tLimMlmDisassocReq *pMlmDisassocReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tSirRetStatus status; + tSirSmeDisassocReq smeDisassocReq; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + if (pMsgBuf == NULL) + { + limLog(pMac, LOGE, FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac, (tANI_U8 *)pMsgBuf,&smesessionId, &smetransactionId); + + status = limDisassocReqSerDes(pMac, &smeDisassocReq, (tANI_U8 *) pMsgBuf); + + if ( (eSIR_FAILURE == status) || + (!limIsSmeDisassocReqValid(pMac, &smeDisassocReq, psessionEntry)) ) + { + PELOGE(limLog(pMac, LOGE, + FL("received invalid SME_DISASSOC_REQ message"));) + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_INVALID_PARAMETERS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + + return; + } + + if((psessionEntry = peFindSessionByBssid(pMac,smeDisassocReq.bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(smeDisassocReq.bssId)); + retCode = eSIR_SME_INVALID_PARAMETERS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + + } + limLog(pMac, LOG1, FL("received DISASSOC_REQ message on sessionid %d" + "Systemrole %d Reason: %u SmeState: %d from: "MAC_ADDRESS_STR), + smesessionId,psessionEntry->limSystemRole, + smeDisassocReq.reasonCode, pMac->lim.gLimSmeState, + MAC_ADDR_ARRAY(smeDisassocReq.peerMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry, 0, smeDisassocReq.reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Update SME session Id and SME transaction ID*/ + + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limSmeState) + { + case eLIM_SME_ASSOCIATED_STATE: + case eLIM_SME_LINK_EST_STATE: + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE; +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "limSmeState: %d "),psessionEntry->limSmeState); + break; + + case eLIM_SME_WT_DEAUTH_STATE: + /* PE shall still process the DISASSOC_REQ and proceed with + * link tear down even if it had already sent a DEAUTH_IND to + * to SME. pMac->lim.gLimPrevSmeState shall remain the same as + * its been set when PE entered WT_DEAUTH_STATE. + */ + psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "SME_WT_DEAUTH_STATE. ")); + break; + + case eLIM_SME_WT_DISASSOC_STATE: + /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it + * received DISASSOC_REQ. Which means host is also trying to disconnect. + * PE can continue processing DISASSOC_REQ and send the response instead + * of failing the request. SME will anyway ignore DEAUTH_IND that was sent + * for disassoc frame. + * + * It will send a disassoc, which is ok. However, we can use the global flag + * sendDisassoc to not send disassoc frame. + */ + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "SME_WT_DISASSOC_STATE. ")); + break; + + case eLIM_SME_JOIN_FAILURE_STATE: { + /** Return Success as we are already in Disconnected State*/ + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "eLIM_SME_JOIN_FAILURE_STATE. ")); + if (pMac->lim.gLimRspReqd) { + retCode = eSIR_SME_SUCCESS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + }break; + default: + /** + * STA is not currently associated. + * Log error and send response to host + */ + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_REQ in state %X"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + if (pMac->lim.gLimRspReqd) + { + if (psessionEntry->limSmeState != + eLIM_SME_WT_ASSOC_STATE) + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + + return; + } + + break; + + case eLIM_AP_ROLE: + case eLIM_BT_AMP_AP_ROLE: + // Fall through + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_UNKNOWN_ROLE + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_REQ for role %d"), + psessionEntry->limSystemRole); + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } // end switch (pMac->lim.gLimSystemRole) + + if (smeDisassocReq.reasonCode == eLIM_LINK_MONITORING_DISASSOC) + { + /// Disassociation is triggered by Link Monitoring + limLog(pMac, LOG1, FL("**** Lost link with AP ****")); + disassocTrigger = eLIM_LINK_MONITORING_DISASSOC; + reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + } + else + { + disassocTrigger = eLIM_HOST_DISASSOC; + reasonCode = smeDisassocReq.reasonCode; + } + + if (smeDisassocReq.doNotSendOverTheAir) + { + limLog(pMac, LOG1, FL("do not send dissoc over the air")); + sendDisassocFrame = 0; + } + // Trigger Disassociation frame to peer MAC entity + + pMlmDisassocReq = vos_mem_malloc(sizeof(tLimMlmDisassocReq)); + if ( NULL == pMlmDisassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmDisassocReq")); + + return; + } + + vos_mem_copy( (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + (tANI_U8 *) &smeDisassocReq.peerMacAddr, + sizeof(tSirMacAddr)); + + pMlmDisassocReq->reasonCode = reasonCode; + pMlmDisassocReq->disassocTrigger = disassocTrigger; + + /* Update PE session ID*/ + pMlmDisassocReq->sessionId = sessionId; + + limPostMlmMessage(pMac, + LIM_MLM_DISASSOC_REQ, + (tANI_U32 *) pMlmDisassocReq); + return; + +sendDisassoc: + if (psessionEntry) + limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr, + retCode, + disassocTrigger, + 1,smesessionId,smetransactionId,psessionEntry); + else + limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr, + retCode, + disassocTrigger, + 1, smesessionId, smetransactionId, NULL); + + +} /*** end __limProcessSmeDisassocReq() ***/ + + +/** ----------------------------------------------------------------- + \brief __limProcessSmeDisassocCnf() - Process SME_DISASSOC_CNF + + This function is called to process SME_DISASSOC_CNF message + from HDD or upper layer application. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +static void +__limProcessSmeDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeDisassocCnf smeDisassocCnf; + tANI_U16 aid; + tpDphHashNode pStaDs; + tSirRetStatus status = eSIR_SUCCESS; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + PELOG1(limLog(pMac, LOG1, FL("received DISASSOC_CNF message"));) + + status = limDisassocCnfSerDes(pMac, &smeDisassocCnf,(tANI_U8 *) pMsgBuf); + + if (status == eSIR_FAILURE) + { + PELOGE(limLog(pMac, LOGE, FL("invalid SME_DISASSOC_CNF message"));) + return; + } + + if((psessionEntry = peFindSessionByBssid(pMac, smeDisassocCnf.bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + return; + } + + if (!limIsSmeDisassocCnfValid(pMac, &smeDisassocCnf, psessionEntry)) + { + limLog(pMac, LOGE, FL("received invalid SME_DISASSOC_CNF message")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF) + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0); + else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF) + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: //To test reconn + if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + limLog(pMac, LOGE, + FL("received unexp SME_DISASSOC_CNF in state %X"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + return; + } + break; + + case eLIM_AP_ROLE: + // Fall through + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_UNKNOWN_ROLE + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_CNF role %d"), + psessionEntry->limSystemRole); + + return; + } + + + if ( (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) || + (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + ) + { + pStaDs = dphLookupHashEntry(pMac, smeDisassocCnf.peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("received DISASSOC_CNF for a STA that " + "does not have context, addr= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));) + return; + } + +#if defined WLAN_FEATURE_VOWIFI_11R + /* Delete FT session if there exists one */ + limFTCleanupPreAuthInfo(pMac, psessionEntry); +#endif + limCleanupRxPath(pMac, pStaDs, psessionEntry); + + limCleanUpDisassocDeauthReq(pMac, (char*)&smeDisassocCnf.peerMacAddr, 0); + } + + return; +} + + +/** + * __limProcessSmeDeauthReq() + * + *FUNCTION: + * This function is called to process SME_DEAUTH_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 deauthTrigger, reasonCode; + tLimMlmDeauthReq *pMlmDeauthReq; + tSirSmeDeauthReq smeDeauthReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tSirRetStatus status = eSIR_SUCCESS; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + PELOG1(limLog(pMac, LOG1,FL("received DEAUTH_REQ message"));) + + status = limDeauthReqSerDes(pMac, &smeDeauthReq,(tANI_U8 *) pMsgBuf); + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + //We need to get a session first but we don't even know if the message is correct. + if((psessionEntry = peFindSessionByBssid(pMac, smeDeauthReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + + } + + if ((status == eSIR_FAILURE) || (!limIsSmeDeauthReqValid(pMac, &smeDeauthReq, psessionEntry))) + { + PELOGE(limLog(pMac, LOGE,FL + ("received invalid SME_DEAUTH_REQ message"));) + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + } + limLog(pMac, LOG1,FL("received DEAUTH_REQ message on sessionid %d " + "Systemrole %d with reasoncode %u in limSmestate %d from " + MAC_ADDRESS_STR), smesessionId, psessionEntry->limSystemRole, + smeDeauthReq.reasonCode, psessionEntry->limSmeState, + MAC_ADDR_ARRAY(smeDeauthReq.peerMacAddr)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_REQ_EVENT, psessionEntry, 0, smeDeauthReq.reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Update SME session ID and Transaction ID */ + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + + switch (psessionEntry->limSmeState) + { + case eLIM_SME_ASSOCIATED_STATE: + case eLIM_SME_LINK_EST_STATE: + case eLIM_SME_WT_ASSOC_STATE: + case eLIM_SME_JOIN_FAILURE_STATE: + case eLIM_SME_IDLE_STATE: + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + // Send Deauthentication request to MLM below + + break; + case eLIM_SME_WT_DEAUTH_STATE: + case eLIM_SME_WT_DISASSOC_STATE: + /* + * PE Recieved a Deauth/Disassoc frame. Normally it gets + * DEAUTH_CNF/DISASSOC_CNF but it received DEAUTH_REQ. Which + * means host is also trying to disconnect. + * PE can continue processing DEAUTH_REQ and send + * the response instead of failing the request. + * SME will anyway ignore DEAUTH_IND/DISASSOC_IND that + * was sent for deauth/disassoc frame. + */ + psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE; + limLog(pMac, LOG1, FL("Rcvd SME_DEAUTH_REQ while in " + "SME_WT_DEAUTH_STATE. ")); + break; + default: + /** + * STA is not in a state to deauthenticate with + * peer. Log error and send response to host. + */ + limLog(pMac, LOGE, + FL("received unexp SME_DEAUTH_REQ in state %X"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_STA_NOT_AUTHENTICATED; + deauthTrigger = eLIM_HOST_DEAUTH; + +/* + here we received deauth request from AP so sme state is + eLIM_SME_WT_DEAUTH_STATE.if we have ISSUED delSta then + mlm state should be eLIM_MLM_WT_DEL_STA_RSP_STATE and if + we got delBSS rsp then mlm state should be eLIM_MLM_IDLE_STATE + so the below condition captures the state where delSta + not done and firmware still in connected state. +*/ + + if (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE && + psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE && + psessionEntry->limMlmState != eLIM_MLM_WT_DEL_STA_RSP_STATE) + { + retCode = eSIR_SME_DEAUTH_STATUS; + } + goto sendDeauth; + } + + return; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + + return; + + case eLIM_AP_ROLE: + // Fall through + + break; + + default: + limLog(pMac, LOGE, + FL("received unexpected SME_DEAUTH_REQ for role %X"), + psessionEntry->limSystemRole); + + return; + } // end switch (pMac->lim.gLimSystemRole) + + if (smeDeauthReq.reasonCode == eLIM_LINK_MONITORING_DEAUTH) + { + /// Deauthentication is triggered by Link Monitoring + PELOG1(limLog(pMac, LOG1, FL("**** Lost link with AP ****"));) + deauthTrigger = eLIM_LINK_MONITORING_DEAUTH; + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + } + else + { + deauthTrigger = eLIM_HOST_DEAUTH; + reasonCode = smeDeauthReq.reasonCode; + } + + // Trigger Deauthentication frame to peer MAC entity + pMlmDeauthReq = vos_mem_malloc(sizeof(tLimMlmDeauthReq)); + if ( NULL == pMlmDeauthReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmDeauthReq")); + + return; + } + + vos_mem_copy( (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + (tANI_U8 *) &smeDeauthReq.peerMacAddr, + sizeof(tSirMacAddr)); + + pMlmDeauthReq->reasonCode = reasonCode; + pMlmDeauthReq->deauthTrigger = deauthTrigger; + + /* Update PE session Id*/ + pMlmDeauthReq->sessionId = sessionId; + + limPostMlmMessage(pMac, + LIM_MLM_DEAUTH_REQ, + (tANI_U32 *) pMlmDeauthReq); + return; + +sendDeauth: + limSendSmeDeauthNtf(pMac, smeDeauthReq.peerMacAddr, + retCode, + deauthTrigger, + 1, + smesessionId, smetransactionId); +} /*** end __limProcessSmeDeauthReq() ***/ + + + +/** + * __limProcessSmeSetContextReq() + * + *FUNCTION: + * This function is called to process SME_SETCONTEXT_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeSetContextReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSmeSetContextReq pSetContextReq; + tLimMlmSetKeysReq *pMlmSetKeysReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + PELOG1(limLog(pMac, LOG1, + FL("received SETCONTEXT_REQ message"));); + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pSetContextReq = vos_mem_malloc(sizeof(tSirKeys) * SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS); + if ( NULL == pSetContextReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pSetContextReq")); + return; + } + + if ((limSetContextReqSerDes(pMac, pSetContextReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeSetContextReqValid(pMac, pSetContextReq))) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if(pSetContextReq->keyMaterial.numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + PELOGE(limLog(pMac, LOGE, FL("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"), pSetContextReq->keyMaterial.numKeys);) + limSendSmeSetContextRsp(pMac, + pSetContextReq->peerMacAddr, + 1, + eSIR_SME_INVALID_PARAMETERS,NULL, + smesessionId,smetransactionId); + + goto end; + } + + + if((psessionEntry = peFindSessionByBssid(pMac, pSetContextReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + limSendSmeSetContextRsp(pMac, + pSetContextReq->peerMacAddr, + 1, + eSIR_SME_INVALID_PARAMETERS,NULL, + smesessionId,smetransactionId); + + goto end; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) || + (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) + { + // Trigger MLM_SETKEYS_REQ + pMlmSetKeysReq = vos_mem_malloc(sizeof(tLimMlmSetKeysReq)); + if ( NULL == pMlmSetKeysReq ) + { + // Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmSetKeysReq")); + goto end; + } + + pMlmSetKeysReq->edType = pSetContextReq->keyMaterial.edType; + pMlmSetKeysReq->numKeys = pSetContextReq->keyMaterial.numKeys; + if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + limLog(pMac, LOGP, FL("Num of keys exceeded max num of default keys limit")); + goto end; + } + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->peerMacAddr, + (tANI_U8 *) &pSetContextReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key, + (tANI_U8 *) &pSetContextReq->keyMaterial.key, + sizeof(tSirKeys) * (pMlmSetKeysReq->numKeys ? pMlmSetKeysReq->numKeys : 1)); + + pMlmSetKeysReq->sessionId = sessionId; + pMlmSetKeysReq->smesessionId = smesessionId; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, + FL("received SETCONTEXT_REQ message sessionId=%d"), pMlmSetKeysReq->sessionId);); +#endif + + if(((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) || (pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104)) + && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + if(pSetContextReq->keyMaterial.key[0].keyLength) + { + tANI_U8 keyId; + keyId = pSetContextReq->keyMaterial.key[0].keyId; + vos_mem_copy( (tANI_U8 *)&psessionEntry->WEPKeyMaterial[keyId], + (tANI_U8 *) &pSetContextReq->keyMaterial, sizeof(tSirKeyMaterial)); + } + else { + tANI_U32 i; + for( i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) + { + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key[i], + (tANI_U8 *)psessionEntry->WEPKeyMaterial[i].key, sizeof(tSirKeys)); + } + } + } + + limPostMlmMessage(pMac, LIM_MLM_SETKEYS_REQ, (tANI_U32 *) pMlmSetKeysReq); + } + else + { + limLog(pMac, LOGE, + FL("received unexpected SME_SETCONTEXT_REQ for role %d, state=%X"), + psessionEntry->limSystemRole, + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + limSendSmeSetContextRsp(pMac, pSetContextReq->peerMacAddr, + 1, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry, + smesessionId, + smetransactionId); + } + +end: + vos_mem_free( pSetContextReq); + return; +} /*** end __limProcessSmeSetContextReq() ***/ + +/** + * __limProcessSmeRemoveKeyReq() + * + *FUNCTION: + * This function is called to process SME_REMOVEKEY_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSmeRemoveKeyReq pRemoveKeyReq; + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + PELOG1(limLog(pMac, LOG1, + FL("received REMOVEKEY_REQ message"));) + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pRemoveKeyReq = vos_mem_malloc(sizeof(*pRemoveKeyReq)); + if ( NULL == pRemoveKeyReq ) + { + //Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for pRemoveKeyReq")); + + return; + } + + if ((limRemoveKeyReqSerDes(pMac, + pRemoveKeyReq, + (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, + FL("received invalid SME_REMOVECONTEXT_REQ message")); + + /* extra look up is needed since, session entry to be passed il limsendremovekey response */ + + if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + //goto end; + } + + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_INVALID_PARAMETERS,psessionEntry, + smesessionId,smetransactionId); + + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, NULL, + smesessionId, smetransactionId); + goto end; + } + + + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) || + (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) + { + // Trigger MLM_REMOVEKEYS_REQ + pMlmRemoveKeyReq = vos_mem_malloc(sizeof(tLimMlmRemoveKeyReq)); + if ( NULL == pMlmRemoveKeyReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmRemoveKeysReq")); + + goto end; + } + + pMlmRemoveKeyReq->edType = (tAniEdType)pRemoveKeyReq->edType; + pMlmRemoveKeyReq->keyId = pRemoveKeyReq->keyId; + pMlmRemoveKeyReq->wepType = pRemoveKeyReq->wepType; + pMlmRemoveKeyReq->unicast = pRemoveKeyReq->unicast; + + /* Update PE session Id */ + pMlmRemoveKeyReq->sessionId = sessionId; + + vos_mem_copy( (tANI_U8 *) &pMlmRemoveKeyReq->peerMacAddr, + (tANI_U8 *) &pRemoveKeyReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + limPostMlmMessage(pMac, + LIM_MLM_REMOVEKEY_REQ, + (tANI_U32 *) pMlmRemoveKeyReq); + } + else + { + limLog(pMac, LOGE, + FL("received unexpected SME_REMOVEKEY_REQ for role %d, state=%X"), + psessionEntry->limSystemRole, + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry, + smesessionId,smetransactionId); + } + +end: + vos_mem_free( pRemoveKeyReq); +} /*** end __limProcessSmeRemoveKeyReq() ***/ + +void limProcessSmeGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ mmhMsg; + tpSmeGetScanChnRsp pSirSmeRsp; + tANI_U16 len = 0; + tANI_U8 sessionId; + tANI_U16 transactionId; + + if(pMac->lim.scanChnInfo.numChnInfo > SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + limLog(pMac, LOGW, FL("numChn is out of bounds %d"), + pMac->lim.scanChnInfo.numChnInfo); + pMac->lim.scanChnInfo.numChnInfo = SIR_MAX_SUPPORTED_CHANNEL_LIST; + } + + PELOG2(limLog(pMac, LOG2, + FL("Sending message %s with number of channels %d"), + limMsgStr(eWNI_SME_GET_SCANNED_CHANNEL_RSP), pMac->lim.scanChnInfo.numChnInfo);) + + len = sizeof(tSmeGetScanChnRsp) + (pMac->lim.scanChnInfo.numChnInfo - 1) * sizeof(tLimScanChn); + pSirSmeRsp = vos_mem_malloc(len); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + + return; + } + vos_mem_set(pSirSmeRsp, len, 0); + + pSirSmeRsp->mesgType = eWNI_SME_GET_SCANNED_CHANNEL_RSP; + pSirSmeRsp->mesgLen = len; + + if (pMac->fScanOffload) + { + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&sessionId,&transactionId); + pSirSmeRsp->sessionId = sessionId; + } + else + pSirSmeRsp->sessionId = 0; + + if(pMac->lim.scanChnInfo.numChnInfo) + { + pSirSmeRsp->numChn = pMac->lim.scanChnInfo.numChnInfo; + vos_mem_copy( pSirSmeRsp->scanChn, pMac->lim.scanChnInfo.scanChn, + sizeof(tLimScanChn) * pSirSmeRsp->numChn); + } + //Clear the list + limRessetScanChannelInfo(pMac); + + mmhMsg.type = eWNI_SME_GET_SCANNED_CHANNEL_RSP; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + + pMac->lim.gLimRspReqd = false; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + + +void limProcessSmeGetAssocSTAsInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeGetAssocSTAsReq getAssocSTAsReq; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry = NULL; + tSap_Event sapEvent; + tpWLAN_SAPEventCB pSapEventCallback = NULL; + tpSap_AssocMacAddr pAssocStasTemp = NULL;// #include "sapApi.h" + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + tANI_U8 assocId = 0; + tANI_U8 staCount = 0; + + if (!limIsSmeGetAssocSTAsReqValid(pMac, &getAssocSTAsReq, (tANI_U8 *) pMsgBuf)) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message")); + goto limAssocStaEnd; + } + + switch (getAssocSTAsReq.modId) + { + case VOS_MODULE_ID_PE: + default: + break; + } + + // Get Associated stations from PE + // Find PE session Entry + if ((psessionEntry = peFindSessionByBssid(pMac, getAssocSTAsReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + goto limAssocStaEnd; + } + + if (psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + limLog(pMac, LOGE, + FL("Received unexpected message in state %X, in role %X"), + psessionEntry->limSmeState, psessionEntry->limSystemRole); + goto limAssocStaEnd; + } + + // Retrieve values obtained in the request message + pSapEventCallback = (tpWLAN_SAPEventCB)getAssocSTAsReq.pSapEventCallback; + pAssocStasTemp = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray; + + for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8 + { + pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if (NULL == pStaDs) + continue; + + if (pStaDs->valid) + { + vos_mem_copy((tANI_U8 *)&pAssocStasTemp->staMac, + (tANI_U8 *)&pStaDs->staAddr, + sizeof(v_MACADDR_t)); // Mac address + pAssocStasTemp->assocId = (v_U8_t)pStaDs->assocId; // Association Id + pAssocStasTemp->staId = (v_U8_t)pStaDs->staIndex; // Station Id + + vos_mem_copy((tANI_U8 *)&pAssocStasTemp->supportedRates, + (tANI_U8 *)&pStaDs->supportedRates, + sizeof(tSirSupportedRates)); + pAssocStasTemp->ShortGI40Mhz = pStaDs->htShortGI40Mhz; + pAssocStasTemp->ShortGI20Mhz = pStaDs->htShortGI20Mhz; + pAssocStasTemp->Support40Mhz = pStaDs->htDsssCckRate40MHzSupport; + + limLog(pMac, LOG1, FL("dph Station Number = %d"), staCount+1); + limLog(pMac, LOG1, FL("MAC = " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + limLog(pMac, LOG1, FL("Association Id = %d"),pStaDs->assocId); + limLog(pMac, LOG1, FL("Station Index = %d"),pStaDs->staIndex); + + pAssocStasTemp++; + staCount++; + } + } + +limAssocStaEnd: + // Call hdd callback with sap event to send the list of associated stations from PE + if (pSapEventCallback != NULL) + { + sapEvent.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT; + sapEvent.sapevt.sapAssocStaListEvent.module = VOS_MODULE_ID_PE; + sapEvent.sapevt.sapAssocStaListEvent.noOfAssocSta = staCount; + sapEvent.sapevt.sapAssocStaListEvent.pAssocStas = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray; + pSapEventCallback(&sapEvent, getAssocSTAsReq.pUsrContext); + } +} + + +/** + * limProcessSmeGetWPSPBCSessions + * + *FUNCTION: + * This function is called when query the WPS PBC overlap message is received + * + *LOGIC: + * This function parses get WPS PBC overlap information message and call callback to pass + * WPS PBC overlap information back to hdd. + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to WPS PBC overlap query message +* + * @return None + */ +void limProcessSmeGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeGetWPSPBCSessionsReq GetWPSPBCSessionsReq; + tpPESession psessionEntry = NULL; + tSap_Event sapEvent; + tpWLAN_SAPEventCB pSapEventCallback = NULL; + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + tSirMacAddr zeroMac = {0,0,0,0,0,0}; + + sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_E_FAULT; + + if (limIsSmeGetWPSPBCSessionsReqValid(pMac, &GetWPSPBCSessionsReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message")); + goto limGetWPSPBCSessionsEnd; + } + + // Get Associated stations from PE + // Find PE session Entry + if ((psessionEntry = peFindSessionByBssid(pMac, GetWPSPBCSessionsReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + goto limGetWPSPBCSessionsEnd; + } + + if (psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + limLog(pMac, LOGE, + FL("Received unexpected message in role %X"), + psessionEntry->limSystemRole); + goto limGetWPSPBCSessionsEnd; + } + + // Call hdd callback with sap event to send the WPS PBC overlap information + sapEvent.sapHddEventCode = eSAP_GET_WPSPBC_SESSION_EVENT; + sapEvent.sapevt.sapGetWPSPBCSessionEvent.module = VOS_MODULE_ID_PE; + + if (vos_mem_compare( zeroMac, GetWPSPBCSessionsReq.pRemoveMac, sizeof(tSirMacAddr))) + { //This is GetWpsSession call + + limGetWPSPBCSessions(pMac, + sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, sapEvent.sapevt.sapGetWPSPBCSessionEvent.UUID_E, + &sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap, psessionEntry); + } + else + { + limRemovePBCSessions(pMac, GetWPSPBCSessionsReq.pRemoveMac,psessionEntry); + /* don't have to inform the HDD/Host */ + return; + } + + PELOG4(limLog(pMac, LOGE, FL("wpsPBCOverlap %d"), sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap);) + PELOG4(limPrintMacAddr(pMac, sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, LOG4);) + + sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_SUCCESS; + +limGetWPSPBCSessionsEnd: + pSapEventCallback = (tpWLAN_SAPEventCB)GetWPSPBCSessionsReq.pSapEventCallback; + pSapEventCallback(&sapEvent, GetWPSPBCSessionsReq.pUsrContext); +} + + + +/** + * __limCounterMeasures() + * + * FUNCTION: + * This function is called to "implement" MIC counter measure + * and is *temporary* only + * + * LOGIC: on AP, disassoc all STA associated thru TKIP, + * we don't do the proper STA disassoc sequence since the + * BSS will be stoped anyway + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +__limCounterMeasures(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMacAddr mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) + + limSendDisassocMgmtFrame(pMac, eSIR_MAC_MIC_FAILURE_REASON, mac, psessionEntry, FALSE); + +}; + + +void +limProcessTkipCounterMeasures(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeTkipCntrMeasReq tkipCntrMeasReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + + if ( limTkipCntrMeasReqSerDes( pMac, &tkipCntrMeasReq, (tANI_U8 *) pMsgBuf ) != eSIR_SUCCESS ) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_TKIP_CNTR_MEAS_REQ message")); + return; + } + + if ( NULL == (psessionEntry = peFindSessionByBssid( pMac, tkipCntrMeasReq.bssId, &sessionId )) ) + { + limLog(pMac, LOGE, FL("session does not exist for given BSSID ")); + return; + } + + if ( tkipCntrMeasReq.bEnable ) + { + __limCounterMeasures( pMac, psessionEntry ); + } + + psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable; +} + + +static void +__limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeStopBssReq stopBssReq; + tSirRetStatus status; + tLimSmeStates prevState; + tANI_U8 sessionId; //PE sessionId + tpPESession psessionEntry; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + tANI_U8 i = 0; + tpDphHashNode pStaDs = NULL; + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + + + if ((limStopBssReqSerDes(pMac, &stopBssReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) || + !limIsSmeStopBssReqValid(pMsgBuf)) + { + PELOGW(limLog(pMac, LOGW, FL("received invalid SME_STOP_BSS_REQ message"));) + /// Send Stop BSS response to host + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId); + return; + } + + + if((psessionEntry = peFindSessionByBssid(pMac,stopBssReq.bssId,&sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("session does not exist for given BSSID ")); + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) || /* Added For BT -AMP Support */ + (psessionEntry->limSystemRole == eLIM_STA_ROLE )) + { + /** + * Should not have received STOP_BSS_REQ in states + * other than 'normal' state or on STA in Infrastructure + * mode. Log error and return response to host. + */ + limLog(pMac, LOGE, + FL("received unexpected SME_STOP_BSS_REQ in state %X, for role %d"), + psessionEntry->limSmeState, psessionEntry->limSystemRole); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + /// Send Stop BSS response to host + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,smesessionId,smetransactionId); + return; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + { + limWPSPBCClose(pMac, psessionEntry); + } + PELOGW(limLog(pMac, LOGW, FL("RECEIVED STOP_BSS_REQ with reason code=%d"), stopBssReq.reasonCode);) + + prevState = psessionEntry->limSmeState; + + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /* Update SME session Id and Transaction Id */ + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */ + if ( (eLIM_STA_IN_IBSS_ROLE != psessionEntry->limSystemRole) && (eLIM_BT_AMP_STA_ROLE != psessionEntry->limSystemRole) ) + { + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + if ((stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)) + // Send disassoc all stations associated thru TKIP + __limCounterMeasures(pMac,psessionEntry); + else + limSendDisassocMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, bcAddr, psessionEntry, FALSE); + } + + /* Free the buffer allocated in START_BSS_REQ */ + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespDataLen = 0; + psessionEntry->addIeParams.probeRespData_buff = NULL; + + vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); + psessionEntry->addIeParams.assocRespDataLen = 0; + psessionEntry->addIeParams.assocRespData_buff = NULL; + + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + + //limDelBss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. + pMac->lim.gLimIbssCoalescingHappened = false; + + for(i = 1 ; i < pMac->lim.gLimAssocStaLimit ; i++) + { + pStaDs = dphGetHashEntry(pMac, i, &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) + continue; + status = limDelSta(pMac, pStaDs, false, psessionEntry) ; + if(eSIR_SUCCESS == status) + { + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ; + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ; + } + else + { + limLog(pMac, LOGE, FL("limDelSta failed with Status : %d"), status); + VOS_ASSERT(0) ; + } + } + /* send a delBss to HAL and wait for a response */ + status = limDelBss(pMac, NULL,psessionEntry->bssIdx,psessionEntry); + + if (status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d"), psessionEntry->bssIdx);) + psessionEntry->limSmeState= prevState; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_STOP_BSS_FAILURE,smesessionId,smetransactionId); + } +} + + +/**-------------------------------------------------------------- +\fn __limProcessSmeStopBssReq + +\brief Wrapper for the function __limHandleSmeStopBssRequest + This message will be defered until softmac come out of + scan mode. Message should be handled even if we have + detected radar in the current operating channel. +\param pMac +\param pMsg + +\return TRUE - If we consumed the buffer + FALSE - If have defered the message. + ---------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeStopBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (__limIsDeferedMsgForLearn(pMac, pMsg)) + { + /** + * If message defered, buffer is not consumed yet. + * So return false + */ + return eANI_BOOLEAN_FALSE; + } + __limHandleSmeStopBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr); + return eANI_BOOLEAN_TRUE; +} /*** end __limProcessSmeStopBssReq() ***/ + + +void limProcessSmeDelBssRsp( + tpAniSirGlobal pMac, + tANI_U32 body,tpPESession psessionEntry) +{ + + (void) body; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limIbssDelete(pMac,psessionEntry); + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable); + limDeletePreAuthList(pMac); + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,psessionEntry->smeSessionId,psessionEntry->transactionId); + return; +} + + +/**--------------------------------------------------------------- +\fn __limProcessSmeAssocCnfNew +\brief This function handles SME_ASSOC_CNF/SME_REASSOC_CNF +\ in BTAMP AP. +\ +\param pMac +\param msgType - message type +\param pMsgBuf - a pointer to the SME message buffer +\return None +------------------------------------------------------------------*/ + + void +__limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + tSirSmeAssocCnf assocCnf; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry= NULL; + tANI_U8 sessionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE, FL("pMsgBuf is NULL ")); + goto end; + } + + if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + !__limIsSmeAssocCnfValid(&assocCnf)) + { + limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message ")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given bssId")); + goto end; + } + + if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) || + ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) + { + limLog(pMac, LOGE, FL("Received unexpected message %X in state %X, in role %X"), + msgType, psessionEntry->limSmeState, psessionEntry->limSystemRole); + goto end; + } + + pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + limLog(pMac, LOG1, + FL("Received invalid message %X due to no STA context, for aid %d, peer "), + msgType, assocCnf.aid); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + + /* + ** send a DISASSOC_IND message to WSM to make sure + ** the state in WSM and LIM is the same + **/ + limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED, + eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + goto end; + } + if ((pStaDs && + (( !vos_mem_compare( (tANI_U8 *) pStaDs->staAddr, + (tANI_U8 *) assocCnf.peerMacAddr, + sizeof(tSirMacAddr)) ) || + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) || + ((pStaDs->mlmStaContext.subType == LIM_ASSOC) && + (msgType != eWNI_SME_ASSOC_CNF)) || + ((pStaDs->mlmStaContext.subType == LIM_REASSOC) && + (msgType != eWNI_SME_ASSOC_CNF))))) // since softap is passing this as ASSOC_CNF and subtype differs + { + limLog(pMac, LOG1, + FL("Received invalid message %X due to peerMacAddr mismatched or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "), + msgType, assocCnf.aid); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + goto end; + } + + /* + ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF + ** has been received + **/ + limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer")); + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId); + + if (assocCnf.statusCode == eSIR_SME_SUCCESS) + { + /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence + * when it had received Assoc Request frame. Now, PE just needs to send + * Association Response frame to the requesting BTAMP-STA. + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) "), pStaDs->assocId); + limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, pStaDs, psessionEntry); + goto end; + } // (assocCnf.statusCode == eSIR_SME_SUCCESS) + else + { + // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated + /*Since the HAL sta entry is created for denied STA we need to remove this HAL entry.So to do that set updateContext to 1*/ + if(!pStaDs->mlmStaContext.updateContext) + pStaDs->mlmStaContext.updateContext = 1; + limRejectAssociation(pMac, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + } + +end: + if((psessionEntry != NULL) && (pStaDs != NULL)) + { + if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL ) + { + if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq) + (psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; + } + + vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + } + +} /*** end __limProcessSmeAssocCnfNew() ***/ + + + + +static void +__limProcessSmeAddtsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpDphHashNode pStaDs; + tSirMacAddr peerMac; + tpSirAddtsReq pSirAddts; + tANI_U32 timeout; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pSirAddts = (tpSirAddtsReq) pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pSirAddts->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + + /* if sta + * - verify assoc state + * - send addts request to ap + * - wait for addts response from ap + * if ap, just ignore with error log + */ + PELOG1(limLog(pMac, LOG1, + FL("Received SME_ADDTS_REQ (TSid %d, UP %d)"), + pSirAddts->req.tspec.tsinfo.traffic.tsid, + pSirAddts->req.tspec.tsinfo.traffic.userPrio);) + + if ((psessionEntry->limSystemRole != eLIM_STA_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE)) + { + PELOGE(limLog(pMac, LOGE, "AddTs received on AP - ignoring");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + //Ignore the request if STA is in 11B mode. + if(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B) + { + PELOGE(limLog(pMac, LOGE, "AddTS received while Dot11Mode is 11B - ignoring");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + if(pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, "Cannot find AP context for addts req");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if ((! pStaDs->valid) || + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + PELOGE(limLog(pMac, LOGE, "AddTs received in invalid MLM state");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + pSirAddts->req.wsmTspecPresent = 0; + pSirAddts->req.wmeTspecPresent = 0; + pSirAddts->req.lleTspecPresent = 0; + + if ((pStaDs->wsmEnabled) && + (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA)) + pSirAddts->req.wsmTspecPresent = 1; + else if (pStaDs->wmeEnabled) + pSirAddts->req.wmeTspecPresent = 1; + else if (pStaDs->lleEnabled) + pSirAddts->req.lleTspecPresent = 1; + else + { + PELOGW(limLog(pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled"));) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + limLog(pMac, LOGE, "AddTs received in invalid LIMsme state (%d)", + psessionEntry->limSmeState); + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if (pMac->lim.gLimAddtsSent) + { + limLog(pMac, LOGE, "Addts (token %d, tsid %d, up %d) is still pending", + pMac->lim.gLimAddtsReq.req.dialogToken, + pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid, + pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.userPrio); + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + sirCopyMacAddr(peerMac,psessionEntry->bssId); + + // save the addts request + pMac->lim.gLimAddtsSent = true; + vos_mem_copy( (tANI_U8 *) &pMac->lim.gLimAddtsReq, (tANI_U8 *) pSirAddts, sizeof(tSirAddtsReq)); + + // ship out the message now + limSendAddtsReqActionFrame(pMac, peerMac, &pSirAddts->req, + psessionEntry); + PELOG1(limLog(pMac, LOG1, "Sent ADDTS request");) + + // start a timer to wait for the response + if (pSirAddts->timeout) + timeout = pSirAddts->timeout; + else if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get Cfg param %d (Addts Rsp Timeout)"), + WNI_CFG_ADDTS_RSP_TIMEOUT); + return; + } + + timeout = SYS_MS_TO_TICKS(timeout); + if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer change failed!")); + return; + } + pMac->lim.gLimAddtsRspTimerCount++; + if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer, + pMac->lim.gLimAddtsRspTimerCount) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer change failed!")); + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER)); + + //add the sessionId to the timer object + pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer activation failed!")); + return; + } + return; +} + + +static void +__limProcessSmeDeltsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMacAddr peerMacAddr; + tANI_U8 ac; + tSirMacTSInfo *pTsinfo; + tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 status = eSIR_SUCCESS; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + if((psessionEntry = peFindSessionByBssid(pMac, pDeltsReq->bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + status = eSIR_FAILURE; + goto end; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDeltsReq, peerMacAddr,psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed"));) + status = eSIR_FAILURE; + limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_FAILURE,psessionEntry,smesessionId,smetransactionId); + return; + } + + PELOG1(limLog(pMac, LOG1, FL("Sent DELTS request to station with " + "assocId = %d MacAddr = "MAC_ADDRESS_STR), + pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));) + + limSendDeltsReqActionFrame(pMac, peerMacAddr, pDeltsReq->req.wmeTspecPresent, &pDeltsReq->req.tsinfo, &pDeltsReq->req.tspec, + psessionEntry); + + pTsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo : &pDeltsReq->req.tsinfo; + + /* We've successfully send DELTS frame to AP. Update the + * dynamic UAPSD mask. The AC for this TSPEC to be deleted + * is no longer trigger enabled or delivery enabled + */ + if(!pMac->psOffloadEnabled) + { + limSetTspecUapsdMask(pMac, pTsinfo, CLEAR_UAPSD_MASK); + + /* We're deleting the TSPEC, so this particular AC is no longer + * admitted. PE needs to downgrade the EDCA + * parameters(for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(pTsinfo->traffic.userPrio); + + if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + } + else + { + limSetTspecUapsdMaskPerSession(pMac, psessionEntry, + pTsinfo, CLEAR_UAPSD_MASK); + + /* We're deleting the TSPEC, so this particular AC is no longer + * admitted. PE needs to downgrade the EDCA + * parameters(for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(pTsinfo->traffic.userPrio); + + if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + status = eSIR_SUCCESS; + } + else + { + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + status = eSIR_FAILURE; + } +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + + // send an sme response back + end: + limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_SUCCESS,psessionEntry,smesessionId,smetransactionId); +} + + +void +limProcessSmeAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param) +{ + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAddtsRspTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if ( (psessionEntry->limSystemRole != eLIM_STA_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE) ) + { + limLog(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)", psessionEntry->limSystemRole); + pMac->lim.gLimAddtsSent = false; + return; + } + + if (! pMac->lim.gLimAddtsSent) + { + PELOGW(limLog(pMac, LOGW, "AddtsRspTimeout but no AddtsSent");) + return; + } + + if (param != pMac->lim.gLimAddtsRspTimerCount) + { + limLog(pMac, LOGE, FL("Invalid AddtsRsp Timer count %d (exp %d)"), + param, pMac->lim.gLimAddtsRspTimerCount); + return; + } + + // this a real response timeout + pMac->lim.gLimAddtsSent = false; + pMac->lim.gLimAddtsRspTimerCount++; + + limSendSmeAddtsRsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT, psessionEntry, pMac->lim.gLimAddtsReq.req.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); +} + + +/** + * __limProcessSmeStatsRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetStatsReq pStatsReq; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pStatsReq = (tpAniGetStatsReq) pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac,pStatsReq->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given bssId")); + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + + + switch(pStatsReq->msgType) + { + //Add Lim stats here. and send reqsponse. + + //HAL maintained Stats. + case eWNI_SME_STA_STAT_REQ: + msgQ.type = WDA_STA_STAT_REQ; + break; + case eWNI_SME_AGGR_STAT_REQ: + msgQ.type = WDA_AGGR_STAT_REQ; + break; + case eWNI_SME_GLOBAL_STAT_REQ: + msgQ.type = WDA_GLOBAL_STAT_REQ; + break; + case eWNI_SME_STAT_SUMM_REQ: + msgQ.type = WDA_STAT_SUMM_REQ; + break; + default: //Unknown request. + PELOGE(limLog(pMac, LOGE, "Unknown Statistics request");) + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + limLog(pMac, LOGP, "Unable to forward request"); + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + return; +} + + +/** + * __limProcessSmeGetStatisticsRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetStatisticsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetPEStatsReq pPEStatsReq; + tSirMsgQ msgQ; + + pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf; + + msgQ.type = WDA_GET_STATISTICS_REQ; + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } + + return; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** + *FUNCTION: __limProcessSmeGetTsmStatsRequest() + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetTsmStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msgQ; + + msgQ.type = WDA_TSM_STATS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + * __limProcessSmeGetRoamRssiRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetRoamRssiRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetRssiReq pPEGetRoamRssiReq = NULL; + tSirMsgQ msgQ; + + pPEGetRoamRssiReq = (tpAniGetRssiReq) pMsgBuf; + msgQ.type = WDA_GET_ROAM_RSSI_REQ; + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } + + return; +} +#endif + + +static void +__limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + PELOG1(limLog(pMac, LOG1, + FL("received UPDATE_APWPSIEs_REQ message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateAPWPSIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pUpdateAPWPSIEsReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPSIEsReq")); + return; + } + + if ((limUpdateAPWPSIEsReqSerDes(pMac, pUpdateAPWPSIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPSIEsReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + goto end; + } + + vos_mem_copy( &psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs, sizeof(tSirAPWPSIEs)); + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + +end: + vos_mem_free( pUpdateAPWPSIEsReq); + return; +} /*** end __limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +void +limSendVdevRestart(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tANI_U8 sessionId) +{ + tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + if ( psessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ );) + return; + } + + pHalHiddenSsidVdevRestart = vos_mem_malloc(sizeof(tHalHiddenSsidVdevRestart)); + if (NULL == pHalHiddenSsidVdevRestart) + { + PELOGE(limLog(pMac, LOGE, "%s:%d: Unable to allocate memory", __func__, __LINE__ );) + return; + } + + pHalHiddenSsidVdevRestart->ssidHidden = psessionEntry->ssidHidden; + pHalHiddenSsidVdevRestart->sessionId = sessionId; + + msgQ.type = WDA_HIDDEN_SSID_VDEV_RESTART; + msgQ.bodyptr = pHalHiddenSsidVdevRestart; + msgQ.bodyval = 0; + + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + PELOGE(limLog(pMac, LOGE, "%s:%d: wdaPostCtrlMsg() failed", __func__, __LINE__ );) + vos_mem_free(pHalHiddenSsidVdevRestart); + } +} + +static void +__limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateParams pUpdateParams; + tpPESession psessionEntry; + + PELOG1(limLog(pMac, LOG1, + FL("received HIDE_SSID message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateParams = (tpSirUpdateParams)pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac, pUpdateParams->sessionId)) == NULL) + { + limLog(pMac, LOGW, "Session does not exist for given sessionId %d", + pUpdateParams->sessionId); + return; + } + + /* Update the session entry */ + psessionEntry->ssidHidden = pUpdateParams->ssidHidden; + + /* Send vdev restart */ + limSendVdevRestart(pMac, psessionEntry, pUpdateParams->sessionId); + + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return; +} /*** end __limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +static void +__limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateAPWPARSNIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pUpdateAPWPARSNIEsReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPARSNIEsReq")); + return; + } + + if ((limUpdateAPWPARSNIEsReqSerDes(pMac, pUpdateAPWPARSNIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPARSNIEsReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + goto end; + } + + vos_mem_copy(&psessionEntry->pLimStartBssReq->rsnIE, + &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie)); + + limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac, &psessionEntry->pLimStartBssReq->rsnIE, psessionEntry); + + psessionEntry->pLimStartBssReq->privacy = 1; + psessionEntry->privacy = 1; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + +end: + vos_mem_free(pUpdateAPWPARSNIEsReq); + return; +} /*** end __limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +/* +Update the beacon Interval dynamically if beaconInterval is different in MCC +*/ +static void +__limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirChangeBIParams pChangeBIParams; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + tUpdateBeaconParams beaconParams; + + PELOG1(limLog(pMac, LOG1, + FL("received Update Beacon Interval message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + pChangeBIParams = (tpSirChangeBIParams)pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pChangeBIParams->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return; + } + + /*Update sessionEntry Beacon Interval*/ + if(psessionEntry->beaconParams.beaconInterval != + pChangeBIParams->beaconInterval ) + { + psessionEntry->beaconParams.beaconInterval = pChangeBIParams->beaconInterval; + } + + /*Update sch beaconInterval*/ + if(pMac->sch.schObject.gSchBeaconInterval != + pChangeBIParams->beaconInterval ) + { + pMac->sch.schObject.gSchBeaconInterval = pChangeBIParams->beaconInterval; + + PELOG1(limLog(pMac, LOG1, + FL("LIM send update BeaconInterval Indication : %d"),pChangeBIParams->beaconInterval);); + + if (VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + { + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + + beaconParams.bssIdx = psessionEntry->bssIdx; + //Set change in beacon Interval + beaconParams.beaconInterval = pChangeBIParams->beaconInterval; + beaconParams.paramChangeBitmap = PARAM_BCN_INTERVAL_CHANGED; + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + } + + return; +} /*** end __limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +#ifdef QCA_HT_2040_COEX +static void __limProcessSmeSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSetHT2040Mode pSetHT2040Mode; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + vos_msg_t msg; + tUpdateVHTOpMode *pHtOpMode = NULL; + tANI_U16 staId = 0; + tpDphHashNode pStaDs = NULL; + + PELOG1(limLog(pMac, LOG1, + FL("received Set HT 20/40 mode message"));); + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pSetHT2040Mode = (tpSirSetHT2040Mode)pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pSetHT2040Mode->bssId, + &sessionId)) == NULL) + { + limLog(pMac, LOG1, FL("Session does not exist for given BSSID ")); + limPrintMacAddr(pMac, pSetHT2040Mode->bssId, LOG1); + return; + } + + limLog(pMac, LOG1, FL("Update session entry for cbMod=%d"), + pSetHT2040Mode->cbMode); + /*Update sessionEntry HT related fields*/ + switch(pSetHT2040Mode->cbMode) + { + case PHY_SINGLE_CHANNEL_CENTERED: + psessionEntry->htSecondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED; + psessionEntry->htRecommendedTxWidthSet = 0; + if (pSetHT2040Mode->obssEnabled) + psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + else + psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + psessionEntry->htRecommendedTxWidthSet = 1; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + psessionEntry->htRecommendedTxWidthSet = 1; + break; + default: + limLog(pMac, LOGE,FL("Invalid cbMode")); + return; + } + + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + /* update OP Mode for each associated peer */ + for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++) + { + pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) + continue; + + if (pStaDs->valid && pStaDs->htSupportedChannelWidthSet) + { + pHtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode)); + if ( NULL == pHtOpMode ) + { + limLog(pMac, LOGE, + FL("%s: Not able to allocate memory for setting OP mode"), + __func__); + return; + } + pHtOpMode->opMode = (psessionEntry->htSecondaryChannelOffset == + PHY_SINGLE_CHANNEL_CENTERED)? + eHT_CHANNEL_WIDTH_20MHZ:eHT_CHANNEL_WIDTH_40MHZ; + pHtOpMode->staId = staId; + vos_mem_copy(pHtOpMode->peer_mac, &pStaDs->staAddr, + sizeof(tSirMacAddr)); + pHtOpMode->smesessionId = sessionId; + + msg.type = WDA_UPDATE_OP_MODE; + msg.reserved = 0; + msg.bodyptr = pHtOpMode; + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + limLog(pMac, LOGE, + FL("%s: Not able to post WDA_UPDATE_OP_MODE message to WDA"), + __func__); + vos_mem_free(pHtOpMode); + return; + } + limLog(pMac, LOG1, + FL("%s: Notifed FW about OP mode: %d for staId=%d"), + __func__, pHtOpMode->opMode, staId); + + } + else + limLog(pMac, LOG1, FL("%s: station %d does not support HT40\n"), + __func__, staId); + } + + return; +} +#endif + +/** ------------------------------------------------------------- +\fn limProcessSmeDelBaPeerInd +\brief handles indication message from HDD to send delete BA request +\param tpAniSirGlobal pMac +\param tANI_U32 pMsgBuf +\return None +-------------------------------------------------------------*/ +void +limProcessSmeDelBaPeerInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 assocId =0; + tpSmeDelBAPeerInd pSmeDelBAPeerInd = (tpSmeDelBAPeerInd)pMsgBuf; + tpDphHashNode pSta; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + + if(NULL == pSmeDelBAPeerInd) + return; + + if ((psessionEntry = peFindSessionByBssid(pMac,pSmeDelBAPeerInd->bssId,&sessionId))==NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + return; + } + limLog(pMac, LOGW, FL("called with staId = %d, tid = %d, baDirection = %d"), + pSmeDelBAPeerInd->staIdx, pSmeDelBAPeerInd->baTID, pSmeDelBAPeerInd->baDirection); + + pSta = dphLookupAssocId(pMac, pSmeDelBAPeerInd->staIdx, &assocId, &psessionEntry->dph.dphHashTable); + if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac, + pSta, + pSmeDelBAPeerInd->baDirection, + pSmeDelBAPeerInd->baTID, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_DELBA_REQ to " )); + if (pSta) + limPrintMacAddr(pMac, pSta->staAddr, LOGW); + } +} + +// -------------------------------------------------------------------- +/** + * __limProcessReportMessage + * + * FUNCTION: Processes the next received Radio Resource Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ +#ifdef WLAN_FEATURE_VOWIFI + switch (pMsg->type) + { + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + rrmProcessNeighborReportReq( pMac, pMsg->bodyptr ); + break; + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + { +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tpSirBeaconReportXmitInd pBcnReport=NULL; + tpPESession psessionEntry=NULL; + tANI_U8 sessionId; + + if(pMsg->bodyptr == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + pBcnReport = (tpSirBeaconReportXmitInd )pMsg->bodyptr; + if((psessionEntry = peFindSessionByBssid(pMac, pBcnReport->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + return; + } + if (psessionEntry->isESEconnection) + eseProcessBeaconReportXmit( pMac, pMsg->bodyptr); + else +#endif + rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr ); + } + break; + } +#endif +} + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_VOWIFI) +// -------------------------------------------------------------------- +/** + * limSendSetMaxTxPowerReq + * + * FUNCTION: Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + tpMaxTxPowerParams pMaxTxParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if( pSessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, "%s:%d: Inavalid parameters", __func__, __LINE__ );) + return eSIR_FAILURE; + } + + pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if ( NULL == pMaxTxParams ) + { + limLog( pMac, LOGP, "%s:%d:Unable to allocate memory for pMaxTxParams ", __func__, __LINE__); + return eSIR_MEM_ALLOC_FAILED; + + } +#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_ESE) + PELOG1(limLog( pMac, LOG1, "%s:%d: Allocated memory for pMaxTxParams...will be freed in other module", __func__, __LINE__ );) +#endif + if( pMaxTxParams == NULL ) + { + limLog( pMac, LOGE, "%s:%d: pMaxTxParams is NULL", __func__, __LINE__); + return eSIR_FAILURE; + } + pMaxTxParams->power = txPower; + vos_mem_copy( pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) ); + vos_mem_copy( pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) ); + + msgQ.type = WDA_SET_MAX_TX_POWER_REQ; + msgQ.bodyptr = pMaxTxParams; + msgQ.bodyval = 0; + PELOG1(limLog(pMac, LOG1, FL("Posting WDA_SET_MAX_TX_POWER_REQ to WDA"));) + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + PELOGE(limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));) + vos_mem_free(pMaxTxParams); + } + return retCode; +} +#endif + +/** + * __limProcessSmeAddStaSelfReq() + * + *FUNCTION: + * This function is called to process SME_ADD_STA_SELF_REQ message + * from SME. It sends a SIR_HAL_ADD_STA_SELF_REQ message to HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeAddStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + tpAddStaSelfParams pAddStaSelfParams; + tpSirSmeAddStaSelfReq pSmeReq = (tpSirSmeAddStaSelfReq) pMsgBuf; + + pAddStaSelfParams = vos_mem_malloc(sizeof(tAddStaSelfParams)); + if ( NULL == pAddStaSelfParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for tAddSelfStaParams") ); + return; + } + + vos_mem_copy( pAddStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) ); + pAddStaSelfParams->currDeviceMode = pSmeReq->currDeviceMode; + pAddStaSelfParams->sessionId = pSmeReq->sessionId; + pAddStaSelfParams->type = pSmeReq->type; + pAddStaSelfParams->subType = pSmeReq->subType; + pAddStaSelfParams->pkt_err_disconn_th = pSmeReq->pkt_err_disconn_th; + + msg.type = SIR_HAL_ADD_STA_SELF_REQ; + msg.reserved = 0; + msg.bodyptr = pAddStaSelfParams; + msg.bodyval = 0; + + PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + } + return; +} /*** end __limProcessAddStaSelfReq() ***/ + + +/** + * __limProcessSmeDelStaSelfReq() + * + *FUNCTION: + * This function is called to process SME_DEL_STA_SELF_REQ message + * from SME. It sends a SIR_HAL_DEL_STA_SELF_REQ message to HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDelStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + tpDelStaSelfParams pDelStaSelfParams; + tpSirSmeDelStaSelfReq pSmeReq = (tpSirSmeDelStaSelfReq) pMsgBuf; + + pDelStaSelfParams = vos_mem_malloc(sizeof( tDelStaSelfParams)); + if ( NULL == pDelStaSelfParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for tDelStaSelfParams") ); + return; + } + + vos_mem_copy( pDelStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) ); + + pDelStaSelfParams->sessionId = pSmeReq->sessionId; + msg.type = SIR_HAL_DEL_STA_SELF_REQ; + msg.reserved = 0; + msg.bodyptr = pDelStaSelfParams; + msg.bodyval = 0; + + PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + vos_mem_free(pDelStaSelfParams); + } + return; +} /*** end __limProcessSmeDelStaSelfReq() ***/ + + +/** + * __limProcessSmeRegisterMgmtFrameReq() + * + *FUNCTION: + * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message + * from SME. It Register this information within PE. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeRegisterMgmtFrameReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + VOS_STATUS vosStatus; + tpSirRegisterMgmtFrame pSmeReq = (tpSirRegisterMgmtFrame)pMsgBuf; + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL; + tANI_BOOLEAN match = VOS_FALSE; + PELOG1(limLog(pMac, LOG1, + FL("registerFrame %d, frameType %d, matchLen %d"), + pSmeReq->registerFrame, pSmeReq->frameType, pSmeReq->matchLen);) + + /* First check whether entry exists already*/ + + vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration); + + while(pLimMgmtRegistration != NULL) + { + if (pLimMgmtRegistration->frameType == pSmeReq->frameType) + { + if(pSmeReq->matchLen) + { + if (pLimMgmtRegistration->matchLen == pSmeReq->matchLen) + { + if (vos_mem_compare( pLimMgmtRegistration->matchData, + pSmeReq->matchData, pLimMgmtRegistration->matchLen)) + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + } + else + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + vosStatus = vos_list_peek_next ( + &pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*) pLimMgmtRegistration, + (vos_list_node_t**) &pNext ); + + pLimMgmtRegistration = pNext; + pNext = NULL; + + } + + if (match) + { + vos_list_remove_node(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*)pLimMgmtRegistration); + vos_mem_free(pLimMgmtRegistration); + } + + if(pSmeReq->registerFrame) + { + pLimMgmtRegistration = vos_mem_malloc(sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen); + if ( pLimMgmtRegistration != NULL) + { + vos_mem_set((void*)pLimMgmtRegistration, + sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen, 0 ); + pLimMgmtRegistration->frameType = pSmeReq->frameType; + pLimMgmtRegistration->matchLen = pSmeReq->matchLen; + pLimMgmtRegistration->sessionId = pSmeReq->sessionId; + if(pSmeReq->matchLen) + { + vos_mem_copy(pLimMgmtRegistration->matchData, + pSmeReq->matchData, pSmeReq->matchLen); + } + vos_list_insert_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + &pLimMgmtRegistration->node); + } + } + + return; +} /*** end __limProcessSmeRegisterMgmtFrameReq() ***/ + +static tANI_BOOLEAN +__limInsertSingleShotNOAForScan(tpAniSirGlobal pMac, tANI_U32 noaDuration) +{ + tpP2pPsParams pMsgNoA; + tSirMsgQ msg; + + pMsgNoA = vos_mem_malloc(sizeof( tP2pPsConfig )); + if ( NULL == pMsgNoA ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during NoA Update" )); + goto error; + } + + vos_mem_set((tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig), 0); + /* Below params used for opp PS/periodic NOA and are don't care in this case - so initialized to 0 */ + pMsgNoA->opp_ps = 0; + pMsgNoA->ctWindow = 0; + pMsgNoA->duration = 0; + pMsgNoA->interval = 0; + pMsgNoA->count = 0; + + /* Below params used for Single Shot NOA - so assign proper values */ + pMsgNoA->psSelection = P2P_SINGLE_NOA; + pMsgNoA->single_noa_duration = noaDuration; + + /* Start Insert NOA timer + * If insert NOA req fails or NOA rsp fails or start NOA indication doesn't come from FW due to GO session deletion + * or any other failure or reason, we still need to process the deferred SME req. The insert NOA + * timer of 500 ms will ensure the stored SME req always gets processed + */ + if (tx_timer_activate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) + == TX_TIMER_ERROR) + { + /// Could not activate Insert NOA timer. + // Log error + limLog(pMac, LOGP, FL("could not activate Insert Single Shot NOA during scan timer")); + + // send the scan response back with status failure and do not even call insert NOA + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_SCAN_FAILED, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + vos_mem_free(pMsgNoA); + goto error; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_INSERT_SINGLESHOT_NOA_TIMER)); + + msg.type = WDA_SET_P2P_GO_NOA_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgNoA; + msg.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + /* In this failure case, timer is already started, so its expiration will take care of sending scan response */ + limLog(pMac, LOGP, FL("wdaPost Msg failed")); + /* Deactivate the NOA timer in failure case */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + goto error; + } + return FALSE; + +error: + /* In any of the failure cases, just go ahead with the processing of registered deferred SME request without + * worrying about the NOA + */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + // msg buffer is consumed and freed in above function so return FALSE + return FALSE; + +} + +static void __limRegisterDeferredSmeReqForNOAStart(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 *pMsgBuf) +{ + limLog(pMac, LOG1, FL("Reg msgType %d"), msgType) ; + pMac->lim.gDeferMsgTypeForNOA = msgType; + pMac->lim.gpDefdSmeMsgForNOA = pMsgBuf; +} + +static void __limDeregisterDeferredSmeReqAfterNOAStart(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Dereg msgType %d"), pMac->lim.gDeferMsgTypeForNOA) ; + pMac->lim.gDeferMsgTypeForNOA = 0; + if (pMac->lim.gpDefdSmeMsgForNOA != NULL) + { + /* __limProcessSmeScanReq consumed the buffer. We can free it. */ + vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA); + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } +} + +static +tANI_U32 limCalculateNOADuration(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 *pMsgBuf) +{ + tANI_U32 noaDuration = 0; + + switch (msgType) + { + case eWNI_SME_SCAN_REQ: + { + tANI_U32 val; + tANI_U8 i; + tpSirSmeScanReq pScanReq = (tpSirSmeScanReq) pMsgBuf; + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve passive max channel value")); + + /* use a default value of 110ms */ + val = DEFAULT_PASSIVE_MAX_CHANNEL_TIME; + } + + for (i = 0; i < pScanReq->channelList.numChannels; i++) { + tANI_U8 channelNum = pScanReq->channelList.channelNumber[i]; + + if (limActiveScanAllowed(pMac, channelNum)) { + /* Use min + max channel time to calculate the total duration of scan */ + noaDuration += pScanReq->minChannelTime + pScanReq->maxChannelTime; + } else { + /* using the value from WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME as is done in + * void limContinuePostChannelScan(tpAniSirGlobal pMac) + */ + noaDuration += val; + } + } + + /* Adding an overhead of 20ms to account for the scan messaging delays */ + noaDuration += SCAN_MESSAGING_OVERHEAD; + noaDuration *= CONV_MS_TO_US; + + break; + } + +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + noaDuration = OEM_DATA_NOA_DURATION*CONV_MS_TO_US; // use 60 msec as default + break; +#endif + + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + { + tSirRemainOnChnReq *pRemainOnChnReq = (tSirRemainOnChnReq *) pMsgBuf; + noaDuration = (pRemainOnChnReq->duration)*CONV_MS_TO_US; + break; + } + + case eWNI_SME_JOIN_REQ: + noaDuration = JOIN_NOA_DURATION*CONV_MS_TO_US; + break; + + default: + noaDuration = 0; + break; + + } + limLog(pMac, LOGW, FL("msgType %d noa %d"), msgType, noaDuration); + return noaDuration; +} + +void limProcessRegdDefdSmeReqAfterNOAStart(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN bufConsumed = TRUE; + + limLog(pMac, LOG1, FL("Process defd sme req %d"), pMac->lim.gDeferMsgTypeForNOA); + if ( (pMac->lim.gDeferMsgTypeForNOA != 0) && + (pMac->lim.gpDefdSmeMsgForNOA != NULL) ) + { + switch (pMac->lim.gDeferMsgTypeForNOA) + { + case eWNI_SME_SCAN_REQ: + __limProcessSmeScanReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + __limProcessSmeOemDataReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; +#endif + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + bufConsumed = limProcessRemainOnChnlReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + /* limProcessRemainOnChnlReq doesnt want us to free the buffer since + * it is freed in limRemainOnChnRsp. this change is to avoid "double free" + */ + if (FALSE == bufConsumed) + { + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } + break; + case eWNI_SME_JOIN_REQ: + __limProcessSmeJoinReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; + default: + limLog(pMac, LOGE, FL("Unknown deferred msg type %d"), pMac->lim.gDeferMsgTypeForNOA); + break; + } + __limDeregisterDeferredSmeReqAfterNOAStart(pMac); + } + else + { + limLog( pMac, LOGW, FL("start received from FW when no sme deferred msg pending. Do nothing." + "It might happen sometime when NOA start ind and timeout happen at the same time")); + } +} + + +static void +__limProcessSmeResetApCapsChange(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirResetAPCapsChange pResetCapsChange; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + if (pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pResetCapsChange = (tpSirResetAPCapsChange)pMsgBuf; + psessionEntry = peFindSessionByBssid(pMac, pResetCapsChange->bssId, &sessionId); + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return; + } + + psessionEntry->limSentCapsChangeNtf = false; + return; +} + +/** + * limProcessSmeReqMessages() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the SME message type + * @param *pMsgBuf A pointer to the SME message buffer + * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed. + * FALSE - if pMsgBuf is not to be freed. + */ + +tANI_BOOLEAN +limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tANI_BOOLEAN bufConsumed = TRUE; //Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed. + tANI_U32 *pMsgBuf = pMsg->bodyptr; + tpSirSmeScanReq pScanReq; + PELOG1(limLog(pMac, LOG1, FL("LIM Received SME Message %s(%d) Global LimSmeState:%s(%d) Global LimMlmState: %s(%d)"), + limMsgStr(pMsg->type), pMsg->type, + limSmeStateStr(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState, + limMlmStateStr(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState );) + + pScanReq = (tpSirSmeScanReq) pMsgBuf; + /* Special handling of some SME Req msgs where we have an existing GO session and + * want to insert NOA before processing those msgs. These msgs will be processed later when + * start event happens + */ + MTRACE(macTraceMsgRx(pMac, NO_SESSION, pMsg->type)); + switch (pMsg->type) + { + case eWNI_SME_SCAN_REQ: + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + + /* If scan is disabled return from here + */ + if (pMac->lim.fScanDisabled) + { + if (pMsg->type == eWNI_SME_SCAN_REQ) + { + limSendSmeScanRsp(pMac, + offsetof(tSirSmeScanRsp,bssDescription[0]), + eSIR_SME_INVALID_PARAMETERS, + pScanReq->sessionId, + pScanReq->transactionId); + + bufConsumed = TRUE; + } + else if (pMsg->type == eWNI_SME_REMAIN_ON_CHANNEL_REQ) + { + pMac->lim.gpDefdSmeMsgForNOA = NULL; + pMac->lim.gpLimRemainOnChanReq = (tpSirRemainOnChnReq )pMsgBuf; + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + + /* + * limRemainOnChnRsp will free the buffer this change is to + * avoid "double free" + */ + bufConsumed = FALSE; + } + + limLog(pMac, LOGE, + FL("Error: Scan Disabled." + " Return with error status for SME Message %s(%d)"), + limMsgStr(pMsg->type), pMsg->type); + + return bufConsumed; + } + /* + * Do not add BREAK here + */ +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: +#endif + case eWNI_SME_JOIN_REQ: + /* If we have an existing P2P GO session we need to insert NOA before actually process this SME Req */ + if (!pMac->fScanOffload && (limIsNOAInsertReqd(pMac) == TRUE) && + IS_FEATURE_SUPPORTED_BY_FW(P2P_GO_NOA_DECOUPLE_INIT_SCAN)) + { + tANI_U32 noaDuration; + __limRegisterDeferredSmeReqForNOAStart(pMac, pMsg->type, pMsgBuf); + noaDuration = limCalculateNOADuration(pMac, pMsg->type, pMsgBuf); + bufConsumed = __limInsertSingleShotNOAForScan(pMac, noaDuration); + return bufConsumed; + } + } + /* If no insert NOA required then execute the code below */ + + switch (pMsg->type) + { + case eWNI_SME_START_REQ: + __limProcessSmeStartReq(pMac, pMsgBuf); + break; + + case eWNI_SME_SYS_READY_IND: + bufConsumed = __limProcessSmeSysReadyInd(pMac, pMsgBuf); + break; + + case eWNI_SME_START_BSS_REQ: + bufConsumed = __limProcessSmeStartBssReq(pMac, pMsg); + break; + + case eWNI_SME_SCAN_REQ: + __limProcessSmeScanReq(pMac, pMsgBuf); + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + __limProcessSmeOemDataReq(pMac, pMsgBuf); + break; +#endif + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + bufConsumed = limProcessRemainOnChnlReq(pMac, pMsgBuf); + break; + + case eWNI_SME_UPDATE_NOA: + __limProcessSmeNoAUpdate(pMac, pMsgBuf); + break; + case eWNI_SME_CLEAR_DFS_CHANNEL_LIST: + __limProcessClearDfsChannelList(pMac, pMsg); + break; + case eWNI_SME_CLEAR_LIM_SCAN_CACHE: + limReInitScanResults(pMac); + break; + case eWNI_SME_JOIN_REQ: + __limProcessSmeJoinReq(pMac, pMsgBuf); + break; + + case eWNI_SME_REASSOC_REQ: + __limProcessSmeReassocReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_DISASSOC_REQ: + __limProcessSmeDisassocReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_DISASSOC_CNF: + case eWNI_SME_DEAUTH_CNF: + __limProcessSmeDisassocCnf(pMac, pMsgBuf); + + break; + + case eWNI_SME_DEAUTH_REQ: + __limProcessSmeDeauthReq(pMac, pMsgBuf); + + break; + + + + case eWNI_SME_SETCONTEXT_REQ: + __limProcessSmeSetContextReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_REMOVEKEY_REQ: + __limProcessSmeRemoveKeyReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_STOP_BSS_REQ: + bufConsumed = __limProcessSmeStopBssReq(pMac, pMsg); + break; + + case eWNI_SME_ASSOC_CNF: + case eWNI_SME_REASSOC_CNF: + if (pMsg->type == eWNI_SME_ASSOC_CNF) + PELOG1(limLog(pMac, LOG1, FL("Received ASSOC_CNF message"));) + else + PELOG1(limLog(pMac, LOG1, FL("Received REASSOC_CNF message"));) + __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf); + break; + + case eWNI_SME_ADDTS_REQ: + PELOG1(limLog(pMac, LOG1, FL("Received ADDTS_REQ message"));) + __limProcessSmeAddtsReq(pMac, pMsgBuf); + break; + + case eWNI_SME_DELTS_REQ: + PELOG1(limLog(pMac, LOG1, FL("Received DELTS_REQ message"));) + __limProcessSmeDeltsReq(pMac, pMsgBuf); + break; + + case SIR_LIM_ADDTS_RSP_TIMEOUT: + PELOG1(limLog(pMac, LOG1, FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message "));) + limProcessSmeAddtsRspTimeout(pMac, pMsg->bodyval); + break; + + case eWNI_SME_STA_STAT_REQ: + case eWNI_SME_AGGR_STAT_REQ: + case eWNI_SME_GLOBAL_STAT_REQ: + case eWNI_SME_STAT_SUMM_REQ: + __limProcessSmeStatsRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; + case eWNI_SME_GET_STATISTICS_REQ: + __limProcessSmeGetStatisticsRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: + __limProcessSmeGetRoamRssiRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: + __limProcessSmeGetTsmStatsRequest( pMac, pMsgBuf); + bufConsumed = FALSE; + break; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_DEL_BA_PEER_IND: + limProcessSmeDelBaPeerInd(pMac, pMsgBuf); + break; + case eWNI_SME_GET_SCANNED_CHANNEL_REQ: + limProcessSmeGetScanChannelInfo(pMac, pMsgBuf); + break; + case eWNI_SME_GET_ASSOC_STAS_REQ: + limProcessSmeGetAssocSTAsInfo(pMac, pMsgBuf); + break; + case eWNI_SME_TKIP_CNTR_MEAS_REQ: + limProcessTkipCounterMeasures(pMac, pMsgBuf); + break; + + case eWNI_SME_HIDE_SSID_REQ: + __limProcessSmeHideSSID(pMac, pMsgBuf); + break; + case eWNI_SME_UPDATE_APWPSIE_REQ: + __limProcessSmeUpdateAPWPSIEs(pMac, pMsgBuf); + break; + case eWNI_SME_GET_WPSPBC_SESSION_REQ: + limProcessSmeGetWPSPBCSessions(pMac, pMsgBuf); + break; + + case eWNI_SME_SET_APWPARSNIEs_REQ: + __limProcessSmeSetWPARSNIEs(pMac, pMsgBuf); + break; + + case eWNI_SME_CHNG_MCC_BEACON_INTERVAL: + //Update the beaconInterval + __limProcessSmeChangeBI(pMac, pMsgBuf ); + break; + +#ifdef QCA_HT_2040_COEX + case eWNI_SME_SET_HT_2040_MODE: + __limProcessSmeSetHT2040Mode(pMac, pMsgBuf); + break; +#endif + +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + __limProcessReportMessage(pMac, pMsg); + break; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_PRE_AUTH_REQ: + bufConsumed = (tANI_BOOLEAN)limProcessFTPreAuthReq(pMac, pMsg); + break; + case eWNI_SME_FT_UPDATE_KEY: + limProcessFTUpdateKey(pMac, pMsgBuf); + break; + + case eWNI_SME_FT_AGGR_QOS_REQ: + limProcessFTAggrQosReq(pMac, pMsgBuf); + break; +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_ESE_ADJACENT_AP_REPORT: + limProcessAdjacentAPRepMsg ( pMac, pMsgBuf ); + break; +#endif + case eWNI_SME_ADD_STA_SELF_REQ: + __limProcessSmeAddStaSelfReq( pMac, pMsgBuf ); + break; + case eWNI_SME_DEL_STA_SELF_REQ: + __limProcessSmeDelStaSelfReq( pMac, pMsgBuf ); + break; + + case eWNI_SME_REGISTER_MGMT_FRAME_REQ: + __limProcessSmeRegisterMgmtFrameReq( pMac, pMsgBuf ); + break; +#ifdef FEATURE_WLAN_TDLS + case eWNI_SME_TDLS_SEND_MGMT_REQ: + limProcessSmeTdlsMgmtSendReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_ADD_STA_REQ: + limProcessSmeTdlsAddStaReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_DEL_STA_REQ: + limProcessSmeTdlsDelStaReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_LINK_ESTABLISH_REQ: + limProcesSmeTdlsLinkEstablishReq(pMac, pMsgBuf); + break; +#endif + case eWNI_SME_RESET_AP_CAPS_CHANGED: + __limProcessSmeResetApCapsChange(pMac, pMsgBuf); + break; + + case eWNI_SME_SET_TX_POWER_REQ: + limSendSetTxPowerReq(pMac, pMsgBuf); + break ; + + + case eWNI_SME_CHANNEL_CHANGE_REQ: + limProcessSmeChannelChangeRequest(pMac, pMsgBuf); + break; + + case eWNI_SME_START_BEACON_REQ: + limProcessSmeStartBeaconReq(pMac, pMsgBuf); + break; + + case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ: + limProcessSmeDfsCsaIeRequest(pMac, pMsgBuf); + break; + + case eWNI_SME_UPDATE_ADDITIONAL_IES: + limProcessUpdateAddIEs(pMac, pMsgBuf); + break; + + case eWNI_SME_MODIFY_ADDITIONAL_IES: + limProcessModifyAddIEs(pMac, pMsgBuf); + break; + + default: + vos_mem_free((v_VOID_t*)pMsg->bodyptr); + pMsg->bodyptr = NULL; + break; + } // switch (msgType) + + return bufConsumed; +} /*** end limProcessSmeReqMessages() ***/ + +/** + * limProcessSmeStartBeaconReq() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the SME message type + * @param *pMsgBuf A pointer to the SME message buffer + * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed. + * FALSE - if pMsgBuf is not to be freed. + */ +static void +limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, tANI_U32 * pMsg) +{ + tpSirStartBeaconIndication pBeaconStartInd; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + if( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pBeaconStartInd = (tpSirStartBeaconIndication)pMsg; + if((psessionEntry = + peFindSessionByBssid(pMac, pBeaconStartInd->bssid, &sessionId)) + == NULL) + { + limPrintMacAddr(pMac, pBeaconStartInd->bssid, LOGE); + PELOGE(limLog(pMac, LOGE, + "%s[%d]: Session does not exist for given bssId", + __func__, __LINE__ );) + return; + } + + if (pBeaconStartInd->beaconStartStatus == VOS_TRUE) + { + /* + * Currently this Indication comes from SAP + * to start Beacon Tx on a DFS channel + * since beaconing has to be done on DFS + * channel only after CAC WAIT is completed. + * On a DFS Channel LIM does not start beacon + * Tx right after the WDA_ADD_BSS_RSP. + */ + limApplyConfiguration(pMac,psessionEntry); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("Start Beacon with ssid %s Ch %d"), + psessionEntry->ssId.ssId, + psessionEntry->currentOperChannel); + limSendBeaconInd(pMac, psessionEntry); + } + else + { + limLog(pMac, LOGE,FL("Invalid Beacon Start Indication")); + return; + } +} + +static void +limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tpSirChanChangeRequest pChannelChangeReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tPowerdBm maxTxPwr; +#ifdef WLAN_FEATURE_11AC + tANI_U32 centerChan; + tANI_U32 chanWidth; +#endif + if( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("pMsg is NULL")); + return; + } + pChannelChangeReq = (tpSirChanChangeRequest)pMsg; + + if((psessionEntry = + peFindSessionByBssid(pMac, pChannelChangeReq->bssid, &sessionId)) + == NULL) + { + limPrintMacAddr(pMac, pChannelChangeReq->bssid, LOGE); + PELOGE(limLog(pMac, LOGE, + "%s[%d]: Session does not exist for given bssId", + __func__, __LINE__ );) + return; + } + + if (eLIM_AP_ROLE == psessionEntry->limSystemRole) + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_SAP_DFS; + else + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION; + + maxTxPwr = cfgGetRegulatoryMaxTransmitPower( pMac, + pChannelChangeReq->targetChannel ); + + if (pChannelChangeReq->messageType == eWNI_SME_CHANNEL_CHANGE_REQ + && + maxTxPwr != WDA_MAX_TXPOWER_INVALID) + { + + /* Store the New Channel Params in psessionEntry */ + if (psessionEntry->currentOperChannel != + pChannelChangeReq->targetChannel) + { + limLog(pMac, LOGW,FL("switch old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, + pChannelChangeReq->targetChannel); + + +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + + if(chanWidth == eHT_CHANNEL_WIDTH_20MHZ || chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + } + /* + * In case of DFS operation, If AP falls back to lower + * bandwidth [< 80Mhz] then there is no need of + * Center freq segment. So reset it to zero. + */ + if (cfgSetInt(pMac, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + 0) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("couldn't reset center freq seg 0 in beacon")); + } + psessionEntry->apCenterChan = 0; + } + if (chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + } + + centerChan = limGetCenterChannel(pMac, pChannelChangeReq->targetChannel, + pChannelChangeReq->cbMode,WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ); + if(centerChan != eSIR_CFG_INVALID_ID) + { + limLog(pMac, LOGW, FL("***Center Channel for 80MHZ channel width = %d"),centerChan); + psessionEntry->apCenterChan = centerChan; + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, centerChan) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + } + } + } + + /* All the translation is done by now for gVhtChannelWidth from .ini file to + * the actual values as defined in spec. So, grabing the spec value which is + * updated in .dat file by the above logic */ + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + psessionEntry->vhtTxChannelWidthSet = chanWidth; + psessionEntry->apChanWidth = chanWidth; + } + psessionEntry->htSecondaryChannelOffset = limGetHTCBState(pChannelChangeReq->cbMode); + psessionEntry->htSupportedChannelWidthSet = (pChannelChangeReq->cbMode ? 1 : 0); + + psessionEntry->htRecommendedTxWidthSet = + psessionEntry->htSupportedChannelWidthSet; + psessionEntry->currentOperChannel = + pChannelChangeReq->targetChannel; + + limSetChannel(pMac, pChannelChangeReq->targetChannel, + psessionEntry->htSecondaryChannelOffset, + maxTxPwr, + psessionEntry->peSessionId); +#endif + } + + } + else + { + limLog(pMac, LOGE,FL("Invalid Request/maxTxPwr")); + } +} + +/****************************************************************************** + * limStartBssUpdateAddIEBuffer() + * + *FUNCTION: + * This function checks the src buffer and its length and then malloc for + * dst buffer update the same + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param **pDstData_buff A pointer to pointer of tANI_U8 dst buffer + * @param *pDstDataLen A pointer to pointer of tANI_U16 dst buffer length + * @param *pSrcData_buff A pointer of tANI_U8 src buffer + * @param srcDataLen src buffer length +******************************************************************************/ + +static void +limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen) +{ + + if (srcDataLen > 0 && pSrcData_buff != NULL) + { + *pDstDataLen = srcDataLen; + + *pDstData_buff = vos_mem_malloc(*pDstDataLen); + + if (NULL == *pDstData_buff) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for " + "pDstData_buff"));) + return; + } + vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen); + } + else + { + *pDstData_buff = NULL; + *pDstDataLen = 0; + } +} +/****************************************************************************** + * limUpdateAddIEBuffer() + * + *FUNCTION: + * This function checks the src buffer and length if src buffer length more + * than dst buffer length then free the dst buffer and malloc for the new src + * length, and update the dst buffer and length. But if dst buffer is bigger + * than src buffer length then it just update the dst buffer and length + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param **pDstData_buff A pointer to pointer of tANI_U8 dst buffer + * @param *pDstDataLen A pointer to pointer of tANI_U16 dst buffer length + * @param *pSrcData_buff A pointer of tANI_U8 src buffer + * @param srcDataLen src buffer length +******************************************************************************/ + +static void +limUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen) +{ + + if (NULL == pSrcData_buff) + { + limLog(pMac, LOGE, FL("src buffer is null.")); + return; + } + + if (srcDataLen > *pDstDataLen) + { + *pDstDataLen = srcDataLen; + /* free old buffer */ + vos_mem_free(*pDstData_buff); + /* allocate a new */ + *pDstData_buff = vos_mem_malloc(*pDstDataLen); + + if (NULL == *pDstData_buff) + { + limLog(pMac, LOGE, FL("Memory allocation failed.")); + *pDstDataLen = 0; + return; + } + } + + /* copy the content of buffer into dst buffer + */ + *pDstDataLen = srcDataLen; + vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen); + +} + +/****************************************************************************** + * limProcessModifyAddIEs() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function update the PE buffers for additional IEs. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer +******************************************************************************/ +static void +limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tpSirModifyIEsInd pModifyAddIEs = (tpSirModifyIEsInd)pMsg; + tANI_U8 sessionId; + tANI_BOOLEAN ret = FALSE; + + /* Incoming message has smeSession, use BSSID to find PE session*/ + tpPESession psessionEntry = peFindSessionByBssid(pMac, + pModifyAddIEs->modifyIE.bssid, + &sessionId); + + if (NULL != psessionEntry) + { + if ((0 != pModifyAddIEs->modifyIE.ieBufferlength) && + (0 != pModifyAddIEs->modifyIE.ieIDLen) && + (NULL != pModifyAddIEs->modifyIE.pIEBuffer)) + { + + switch (pModifyAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + { + /* Probe resp */ + break; + } + case eUPDATE_IE_ASSOC_RESP: + /* assoc resp IE */ + if (psessionEntry->addIeParams.assocRespDataLen == 0) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("assoc resp add ie not present %d"), + psessionEntry->addIeParams.assocRespDataLen); + } + /* search through the buffer and modify the IE */ + break; + case eUPDATE_IE_PROBE_BCN: + { + /*probe beacon IE*/ + if (ret == TRUE && pModifyAddIEs->modifyIE.notify) + { + limHandleParamUpdate(pMac, pModifyAddIEs->updateType); + } + break; + } + default: + limLog(pMac, LOGE, FL("unhandled buffer type %d."), + pModifyAddIEs->updateType); + break; + } + } + else + { + limLog(pMac, LOGE, FL("Invalid request pIEBuffer %p ieBufferlength" + " %d ieIDLen %d ieID %d. update Type %d"), + pModifyAddIEs->modifyIE.pIEBuffer, + pModifyAddIEs->modifyIE.ieBufferlength, + pModifyAddIEs->modifyIE.ieID, + pModifyAddIEs->modifyIE.ieIDLen, + pModifyAddIEs->updateType); + } + } + else + { + limLog(pMac, LOGE, FL("Session not found for given bssid. " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pModifyAddIEs->modifyIE.bssid)); + } + vos_mem_free(pModifyAddIEs->modifyIE.pIEBuffer); + pModifyAddIEs->modifyIE.pIEBuffer = NULL; + +} + +/****************************************************************************** + * limProcessUpdateAddIEs() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function update the PE buffers for additional IEs. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer +******************************************************************************/ +static void +limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tpSirUpdateIEsInd pUpdateAddIEs = (tpSirUpdateIEsInd)pMsg; + tANI_U8 sessionId; + /* incoming message has smeSession, use BSSID to find PE session*/ + tpPESession psessionEntry = peFindSessionByBssid(pMac, + pUpdateAddIEs->updateIE.bssid, + &sessionId); + + if (NULL != psessionEntry) + { + /* if len is 0, upper layer requested freeing of buffer */ + if (0 == pUpdateAddIEs->updateIE.ieBufferlength) + { + switch (pUpdateAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespData_buff = NULL; + psessionEntry->addIeParams.probeRespDataLen = 0; + break; + case eUPDATE_IE_ASSOC_RESP: + vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); + psessionEntry->addIeParams.assocRespData_buff = NULL; + psessionEntry->addIeParams.assocRespDataLen = 0; + break; + case eUPDATE_IE_PROBE_BCN: + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + + if (pUpdateAddIEs->updateIE.notify) + { + limHandleParamUpdate(pMac, pUpdateAddIEs->updateType); + } + break; + default: + break; + } + return; + } + + switch (pUpdateAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + { + if (pUpdateAddIEs->updateIE.append) + { + /* In case of append, allocate new memory with combined length */ + tANI_U16 new_length = pUpdateAddIEs->updateIE.ieBufferlength + + psessionEntry->addIeParams.probeRespDataLen; + tANI_U8 *new_ptr = vos_mem_malloc(new_length); + if (NULL == new_ptr) + { + limLog(pMac, LOGE, FL("Memory allocation failed.")); + /* free incoming buffer in message */ + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); + return; + } + /* append buffer to end of local buffers */ + vos_mem_copy(new_ptr, + psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); + vos_mem_copy(&new_ptr[psessionEntry->addIeParams.probeRespDataLen], + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + /* free old memory*/ + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + /* adjust length accordingly */ + psessionEntry->addIeParams.probeRespDataLen = new_length; + /* save refernece of local buffer in PE session */ + psessionEntry->addIeParams.probeRespData_buff = new_ptr; + /* free incoming buffer in message */ + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); + return; + } + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespData_buff, + &psessionEntry->addIeParams.probeRespDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + break; + } + case eUPDATE_IE_ASSOC_RESP: + /*assoc resp IE*/ + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.assocRespData_buff, + &psessionEntry->addIeParams.assocRespDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + break; + case eUPDATE_IE_PROBE_BCN: + /*probe resp Bcn IE*/ + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespBCNData_buff, + &psessionEntry->addIeParams.probeRespBCNDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + if (pUpdateAddIEs->updateIE.notify) + { + limHandleParamUpdate(pMac, pUpdateAddIEs->updateType); + } + break; + default: + limLog(pMac, LOGE, FL("unhandled buffer type %d."), + pUpdateAddIEs->updateType); + break; + } + } + else + { + limLog(pMac, LOGE, FL("Session not found for given bssid. " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pUpdateAddIEs->updateIE.bssid)); + } + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); + pUpdateAddIEs->updateIE.pAdditionIEBuffer = NULL; + +} + +/** + * limProcessSmeDfsCsaIeRequest() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + */ +static void +limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + + tpSirDfsCsaIeRequest pDfsCsaIeRequest = (tSirDfsCsaIeRequest *)pMsg; + tpPESession psessionEntry = NULL; + tANI_U32 chanWidth = 0; + tANI_U8 sessionId; + + if ( pMsg == NULL ) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + if ((psessionEntry = + peFindSessionByBssid(pMac, + pDfsCsaIeRequest->bssid, + &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("Session not found for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pDfsCsaIeRequest->bssid)); + return; + } + + if (psessionEntry->valid && + eLIM_AP_ROLE != psessionEntry->limSystemRole) + { + limLog(pMac, LOGE, FL("Invalid SystemRole %d"), + psessionEntry->limSystemRole); + return; + } + + if ( psessionEntry ) + { + /* target channel */ + psessionEntry->gLimChannelSwitch.primaryChannel = + pDfsCsaIeRequest->targetChannel; + + /* Channel switch announcement needs to be included in beacon */ + psessionEntry->dfsIncludeChanSwIe = VOS_TRUE; + psessionEntry->gLimChannelSwitch.switchCount = LIM_MAX_CSA_IE_UPDATES; + if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_FALSE) + psessionEntry->gLimChannelSwitch.switchMode = 1; + + /* Validate if SAP is operating HT or VHT + * mode and set the Channel Switch Wrapper + * element with the Wide Band Switch + * subelement.. + */ +#ifdef WLAN_FEATURE_11AC + if (VOS_TRUE == psessionEntry->vhtCapability) + { + if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ == + psessionEntry->vhtTxChannelWidthSet) + { + chanWidth = eHT_CHANNEL_WIDTH_80MHZ; + } + else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ == + psessionEntry->vhtTxChannelWidthSet) + { + chanWidth = psessionEntry->htSupportedChannelWidthSet; + } + + /* + * Now encode the Wider Channel BW element + * depending on the chanWidth. + */ + switch(chanWidth) + { + case eHT_CHANNEL_WIDTH_20MHZ: + /* + * Wide channel BW sublement in channel + * wrapper element is not required in case + * of 20 Mhz operation. Currently It is set + * only set in case of 40/80 Mhz Operation. + */ + psessionEntry->dfsIncludeChanWrapperIe = VOS_FALSE; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + break; + case eHT_CHANNEL_WIDTH_40MHZ: + psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + break; + case eHT_CHANNEL_WIDTH_80MHZ: + psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + break; + case eHT_CHANNEL_WIDTH_160MHZ: + psessionEntry->dfsIncludeChanWrapperIe = VOS_TRUE; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; + break; + default: + psessionEntry->dfsIncludeChanWrapperIe = VOS_FALSE; + /* Need to handle 80+80 Mhz Scenario + * When 80+80 is supported set the + * gLimWiderBWChannelSwitch.newChanWidth + * to 3 + */ + PELOGE(limLog(pMac, LOGE, FL("Invalid Channel Width"));) + break; + } + /* + * Fetch the center channel based on the channel width + */ + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = + limGetCenterChannel(pMac, + pDfsCsaIeRequest->targetChannel, + psessionEntry->htSecondaryChannelOffset, + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth); + /* + * This is not applicable for 20/40/80 Mhz. + * Only used when we support 80+80 Mhz + * operation. In case of 80+80 Mhz, this + * parameter indicates center channel + * frequency index of 80 Mhz channel + * of frequency segment 1. + */ + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = 0; + } +#endif + + /* Send CSA IE request from here */ + if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));) + return; + } + + /* First beacon update request is sent here, the remaining updates are + * done when the FW responds back after sending the first beacon after + * the template update + */ + limSendBeaconInd(pMac, psessionEntry); + PELOG1(limLog(pMac, LOG1, + FL(" Updated CSA IE, IE COUNT = %d"), + psessionEntry->gLimChannelSwitch.switchCount );) + psessionEntry->gLimChannelSwitch.switchCount--; + } + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c new file mode 100644 index 0000000000000..9eda705f88954 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessTdls.c @@ -0,0 +1,3186 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + limProcessTdls.c + + OVERVIEW: + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +05/05/2010 Ashwani Initial Creation, added TDLS action frame functionality, + TDLS message exchange with SME..etc.. + +===========================================================================*/ + + +/** + * \file limProcessTdls.c + * + * \brief Code for preparing,processing and sending 802.11z action frames + * + */ + +#ifdef FEATURE_WLAN_TDLS + +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "dot11f.h" +#include "limStaHashApi.h" +#include "schApi.h" +#include "limSendMessages.h" +#include "utilsParser.h" +#include "limAssocUtils.h" +#include "dphHashTable.h" +#include "wlan_qct_wda.h" +#include "regdomain_common.h" + +/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630 +There was IOT issue with cisco 1252 open mode, where it pads +discovery req/teardown frame with some junk value up to min size. +To avoid this issue, we pad QCOM_VENDOR_IE. +If there is other IOT issue because of this bandage, define NO_PAD... +*/ +#ifndef NO_PAD_TDLS_MIN_8023_SIZE +#define MIN_IEEE_8023_SIZE 46 +#define MIN_VENDOR_SPECIFIC_IE_SIZE 5 +#endif +#ifdef WLAN_FEATURE_TDLS_DEBUG +#define TDLS_DEBUG_LOG_LEVEL VOS_TRACE_LEVEL_ERROR +#else +#define TDLS_DEBUG_LOG_LEVEL VOS_TRACE_LEVEL_INFO +#endif + +static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pAddStaReq, + tpPESession psessionEntry) ; +void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry, + tDot11fIELinkIdentifier *linkIden, + tSirMacAddr peerMac, tANI_U8 reqType) ; +void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEExtCap *extCapability) ; + +void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIESuppChannels *suppChannels, + tDot11fIESuppOperatingClasses *suppOperClasses); +void limLogVHTCap(tpAniSirGlobal pMac, + tDot11fIEVHTCaps *pDot11f); +tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tDot11fIEVHTCaps *pPeerVHTCaps, + tpPESession psessionEntry); +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode); + +/* + * TDLS data frames will go out/come in as non-qos data. + * so, eth_890d_header will be aligned access.. + */ +static const tANI_U8 eth_890d_header[] = +{ + 0xaa, 0xaa, 0x03, 0x00, + 0x00, 0x00, 0x89, 0x0d, +} ; + +/* + * type of links used in TDLS + */ +enum tdlsLinks +{ + TDLS_LINK_AP, + TDLS_LINK_DIRECT +} eTdlsLink ; + +/* + * node status in node searching + */ +enum tdlsLinkNodeStatus +{ + TDLS_NODE_NOT_FOUND, + TDLS_NODE_FOUND +} eTdlsLinkNodeStatus ; + + +enum tdlsReqType +{ + TDLS_INITIATOR, + TDLS_RESPONDER +} eTdlsReqType ; + +typedef enum tdlsLinkSetupStatus +{ + TDLS_SETUP_STATUS_SUCCESS = 0, + TDLS_SETUP_STATUS_FAILURE = 37 +}etdlsLinkSetupStatus ; + +/* These maps to Kernel TDLS peer capability + * flags and should get changed as and when necessary + */ +enum tdls_peer_capability { + TDLS_PEER_HT_CAP = 0, + TDLS_PEER_VHT_CAP = 1, + TDLS_PEER_WMM_CAP = 2 +} eTdlsPeerCapability; + +/* some local defines */ +#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier) +#define PTI_LINK_IDEN_OFFSET (5) +#define PTI_BUF_STATUS_OFFSET (25) + +/* TODO, Move this parameters to configuration */ +#define PEER_PSM_SUPPORT (0) +#define TDLS_SUPPORT (1) +#define TDLS_PROHIBITED (0) +#define TDLS_CH_SWITCH_PROHIBITED (1) +/** @brief Set bit manipulation macro */ +#define SET_BIT(value,mask) ((value) |= (1 << (mask))) +/** @brief Clear bit manipulation macro */ +#define CLEAR_BIT(value,mask) ((value) &= ~(1 << (mask))) +/** @brief Check bit manipulation macro */ +#define CHECK_BIT(value, mask) ((value) & (1 << (mask))) + +#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \ + if ((aid) < (sizeof(tANI_U32) << 3)) \ + SET_BIT(peer_bitmap[0], (aid)); \ + else if ((aid) < (sizeof(tANI_U32) << 4)) \ + SET_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3))); + +#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \ + if ((aid) < (sizeof(tANI_U32) << 3)) \ + CLEAR_BIT(peer_bitmap[0], (aid)); \ + else if ((aid) < (sizeof(tANI_U32) << 4)) \ + CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3))); + + +#ifdef LIM_DEBUG_TDLS + +#ifdef FEATURE_WLAN_TDLS +#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800) +#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200) +#endif + +#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \ + SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \ + (((psessionEntry)->limWmeEnabled ) && \ + LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps))) + +#define TID_AC_VI 4 +#define TID_AC_BK 1 + +const tANI_U8* limTraceTdlsActionString( tANI_U8 tdlsActionCode ) +{ + switch( tdlsActionCode ) + { + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF); + CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN); + CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND); + CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP); + } + return (const tANI_U8*)"UNKNOWN"; +} +#endif +/* + * initialize TDLS setup list and related data structures. + */ +void limInitTdlsData(tpAniSirGlobal pMac, tpPESession pSessionEntry) +{ + limInitPeerIdxpool(pMac, pSessionEntry) ; + + return ; +} +/* + * prepare TDLS frame header, it includes + * | | | | + * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD + * | | | | + */ +static tANI_U32 limPrepareTdlsFrameHeader(tpAniSirGlobal pMac, tANI_U8* pFrame, + tDot11fIELinkIdentifier *link_iden, tANI_U8 tdlsLinkType, tANI_U8 reqType, + tANI_U8 tid, tpPESession psessionEntry) +{ + tpSirMacDataHdr3a pMacHdr ; + tANI_U32 header_offset = 0 ; + tANI_U8 *addr1 = NULL ; + tANI_U8 *addr3 = NULL ; + tANI_U8 toDs = (tdlsLinkType == TDLS_LINK_AP) + ? ANI_TXDIR_TODS :ANI_TXDIR_IBSS ; + tANI_U8 *peerMac = (reqType == TDLS_INITIATOR) + ? link_iden->RespStaAddr : link_iden->InitStaAddr; + tANI_U8 *staMac = (reqType == TDLS_INITIATOR) + ? link_iden->InitStaAddr : link_iden->RespStaAddr; + + pMacHdr = (tpSirMacDataHdr3a) (pFrame); + + /* + * if TDLS frame goes through the AP link, it follows normal address + * pattern, if TDLS frame goes thorugh the direct link, then + * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID + */ + (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)), + (addr3 = (peerMac))) + : ((addr1 = (peerMac)), + (addr3 = (link_iden->bssid))) ; + /* + * prepare 802.11 header + */ + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = SIR_MAC_DATA_FRAME ; + pMacHdr->fc.subType = IS_QOS_ENABLED(psessionEntry) ? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA; + + /* + * TL is not setting up below fields, so we are doing it here + */ + pMacHdr->fc.toDS = toDs ; + pMacHdr->fc.powerMgmt = 0 ; + pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE)? 0 : 1; + + + vos_mem_copy( (tANI_U8 *) pMacHdr->addr1, + (tANI_U8 *)addr1, + sizeof( tSirMacAddr )); + vos_mem_copy( (tANI_U8 *) pMacHdr->addr2, + (tANI_U8 *) staMac, + sizeof( tSirMacAddr )); + + vos_mem_copy( (tANI_U8 *) pMacHdr->addr3, + (tANI_U8 *) (addr3), + sizeof( tSirMacAddr )); + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN, ("Preparing TDLS frame header to %s\n%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x"), + (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "TD", + pMacHdr->addr1[0], pMacHdr->addr1[1], pMacHdr->addr1[2], pMacHdr->addr1[3], pMacHdr->addr1[4], pMacHdr->addr1[5], + pMacHdr->addr2[0], pMacHdr->addr2[1], pMacHdr->addr2[2], pMacHdr->addr2[3], pMacHdr->addr2[4], pMacHdr->addr2[5], + pMacHdr->addr3[0], pMacHdr->addr3[1], pMacHdr->addr3[2], pMacHdr->addr3[3], pMacHdr->addr3[4], pMacHdr->addr3[5])); + + if (IS_QOS_ENABLED(psessionEntry)) + { + pMacHdr->qosControl.tid = tid; + header_offset += sizeof(tSirMacDataHdr3a); + } + else + header_offset += sizeof(tSirMacMgmtHdr); + + /* + * Now form RFC1042 header + */ + vos_mem_copy((tANI_U8 *)(pFrame + header_offset), + (tANI_U8 *)eth_890d_header, sizeof(eth_890d_header)) ; + + header_offset += sizeof(eth_890d_header) ; + + /* add payload type as TDLS */ + *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS ; + + return(header_offset += PAYLOAD_TYPE_TDLS_SIZE) ; +} + +/* + * TX Complete for Management frames + */ + eHalStatus limMgmtTXComplete(tpAniSirGlobal pMac, + tANI_U32 txCompleteSuccess) +{ + tpPESession psessionEntry = NULL ; + + if (0xff != pMac->lim.mgmtFrameSessionId) + { + psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.mgmtFrameSessionId); + if (NULL == psessionEntry) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("%s: sessionID %d is not found"), __func__, pMac->lim.mgmtFrameSessionId); + return eHAL_STATUS_FAILURE; + } + limSendSmeMgmtTXCompletion(pMac, psessionEntry, txCompleteSuccess); + pMac->lim.mgmtFrameSessionId = 0xff; + } + return eHAL_STATUS_SUCCESS; +} + +/* + * This function can be used for bacst or unicast discovery request + * We are not differentiating it here, it will all depnds on peer MAC address, + */ +tSirRetStatus limSendTdlsDisReqFrame(tpAniSirGlobal pMac, tSirMacAddr peer_mac, + tANI_U8 dialog, tpPESession psessionEntry) +{ + tDot11fTDLSDisReq tdlsDisReq ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 size = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + tANI_U8 smeSessionId = 0; + + if (NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL" )); + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( (tANI_U8*)&tdlsDisReq, + sizeof( tDot11fTDLSDisReq ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS ; + tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ ; + tdlsDisReq.DialogToken.token = dialog ; + + + size = sizeof(tSirMacAddr) ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisReq.LinkIdentifier, + peer_mac, TDLS_INITIATOR) ; + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSDisReqSize( pMac, &tdlsDisReq, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fTDLSDisReq ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE ; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP, TDLS_INITIATOR, TID_AC_VI, psessionEntry) ; + + status = dot11fPackTDLSDisReq( pMac, &tdlsDisReq, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req " + "(0x%08x)."), status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Discovery Request (0x%08x)."), status ); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"), + padLen )); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA "), + SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) )); + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, false ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} + + + + +/* + * This static function is consistent with any kind of TDLS management + * frames we are sending. Currently it is being used by limSendTdlsDisRspFrame, + * limSendTdlsLinkSetupReqFrame and limSendTdlsSetupRspFrame + */ +static void PopulateDot11fTdlsHtVhtCap(tpAniSirGlobal pMac, uint32 selfDot11Mode, + tDot11fIEHTCaps *htCap, tDot11fIEVHTCaps *vhtCap, + tpPESession psessionEntry) +{ + if (IS_DOT11_MODE_HT(selfDot11Mode)) + { + /* Include HT Capability IE */ + PopulateDot11fHTCaps( pMac, NULL, htCap ); + + /* Set channel width to 1 to indicate HT40 capability on TDLS link */ + htCap->supportedChannelWidthSet = 1; + } + else + { + htCap->present = 0; + } + limLog(pMac, LOG1, FL("HT present = %hu, Chan Width = %hu"), + htCap->present, htCap->supportedChannelWidthSet); +#ifdef WLAN_FEATURE_11AC + if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) && + pMac->roam.configParam.enableVhtFor24GHz) || + (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) + { + if (IS_DOT11_MODE_VHT(selfDot11Mode) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* Include VHT Capability IE */ + PopulateDot11fVHTCaps( pMac, psessionEntry, vhtCap ); + vhtCap->suBeamformeeCap = 0; + vhtCap->suBeamFormerCap = 0; + vhtCap->muBeamformeeCap = 0; + vhtCap->muBeamformerCap = 0; + } + else + { + vhtCap->present = 0; + } + } + else + { + /* Vht Disable from ini in 2.4 GHz */ + vhtCap->present = 0; + } + limLog(pMac, LOG1, FL("VHT present = %hu, Chan Width = %hu"), + vhtCap->present, vhtCap->supportedChannelWidthSet); +#endif +} + +/* + * Send TDLS discovery response frame on direct link. + */ + +static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, + tpPESession psessionEntry, tANI_U8 *addIe, + tANI_U16 addIeLen) +{ + tDot11fTDLSDisRsp tdlsDisRsp ; + tANI_U16 caps = 0 ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + tANI_U8 smeSessionId = 0; + + if (NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL" )); + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&tdlsDisRsp, + sizeof( tDot11fTDLSDisRsp ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE; + tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP ; + tdlsDisRsp.DialogToken.token = dialog ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisRsp.LinkIdentifier, + peerMac, TDLS_RESPONDER) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities ); + + /* populate supported rate and ext supported rate IE */ + if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac, &tdlsDisRsp.SuppRates, + &tdlsDisRsp.ExtSuppRates)) + limLog(pMac, LOGE, FL("could not populate supported data rates")); + + + /* Populate extended capability IE */ + PopulateDot11fTdlsExtCapability(pMac, psessionEntry, &tdlsDisRsp.ExtCap); + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsDisRsp.HTCaps, + &tdlsDisRsp.VHTCaps, psessionEntry ); + + /* Populate TDLS offchannel param only if offchannel is enabled + * and TDLS Channel Switching is not prohibited by AP in ExtCap + * IE in assoc/re-assoc response. + */ + if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) && + (!psessionEntry->tdls_chan_swit_prohibited)) + { + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsDisRsp.SuppChannels, + &tdlsDisRsp.SuppOperatingClasses); + if ( pMac->roam.configParam.bandCapability != eCSR_BAND_24) + { + tdlsDisRsp.HT2040BSSCoexistence.present = 1; + tdlsDisRsp.HT2040BSSCoexistence.infoRequest = 1; + } + } + else + { + limLog(pMac, LOG1, + FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"), + pMac->lim.gLimTDLSOffChannelEnabled, + psessionEntry->tdls_chan_swit_prohibited); + } + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSDisRspSize( pMac, &tdlsDisRsp, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * response frame + */ + + /* Make public Action Frame */ + + limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peerMac, psessionEntry->selfMacAddr); + + { + tpSirMacMgmtHdr pMacHdr; + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + pMacHdr->fc.toDS = ANI_TXDIR_IBSS; + pMacHdr->fc.powerMgmt = 0 ; + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + } + + status = dot11fPackTDLSDisRsp( pMac, &tdlsDisRsp, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req " + "(0x%08x)."), status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Discovery Request (0x%08x)."), status ); + } + if (0 != addIeLen) + { + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("Copy Additional Ie Len = %d"), addIeLen )); + vos_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + addIe, + addIeLen); + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("transmitting Discovery response on direct link")) ; + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -DIRECT-> OTA"), + SIR_MAC_TDLS_DIS_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_RSP) )); + + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; + /* + * Transmit Discovery response and watch if this is delivered to + * peer STA. + */ + /* In CLD 2.0, pass Discovery Response as mgmt frame so that + * wma does not do header conversion to 802.3 before calling tx/rx + * routine and subsequenly target also sends frame as is OTA + */ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_IBSS, + 0, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_SELF_STA_REQUESTED_MASK, smeSessionId, false ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} + +/* + * This static function is currently used by limSendTdlsLinkSetupReqFrame and + * limSendTdlsSetupRspFrame to populate the AID if device is 11ac capable. + */ +static void PopulateDotfTdlsVhtAID(tpAniSirGlobal pMac, uint32 selfDot11Mode, + tSirMacAddr peerMac, tDot11fIEAID *Aid, + tpPESession psessionEntry) +{ + if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) && + pMac->roam.configParam.enableVhtFor24GHz) || + (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) + { + if (IS_DOT11_MODE_VHT(selfDot11Mode) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + + tANI_U16 aid; + tpDphHashNode pStaDs; + + pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable); + if (NULL != pStaDs) + { + Aid->present = 1; + Aid->assocId = aid | LIM_AID_MASK; // set bit 14 and 15 1's + } + else + { + Aid->present = 0; + limLog( pMac, LOGE, FL("pStaDs is NULL for " MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(peerMac)); + } + } + } + else + { + Aid->present = 0; + limLog( pMac, LOGW, FL("Vht not enable from ini for 2.4GHz.")); + } +} + +/* + * TDLS setup Request frame on AP link + */ + +tSirRetStatus limSendTdlsLinkSetupReqFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSSetupReq tdlsSetupReq ; + tANI_U16 caps = 0 ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; + tANI_U8 smeSessionId = 0; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set(( tANI_U8* )&tdlsSetupReq, sizeof( tDot11fTDLSSetupReq ), 0); + tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS ; + tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ ; + tdlsSetupReq.DialogToken.token = dialog ; + + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupReq.LinkIdentifier, + peerMac, TDLS_INITIATOR) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + swapBitField16(caps, ( tANI_U16* )&tdlsSetupReq.Capabilities ); + + /* populate supported rate and ext supported rate IE */ + populate_dot11f_rates_tdls(pMac, &tdlsSetupReq.SuppRates, + &tdlsSetupReq.ExtSuppRates); + + /* Populate extended supported rates */ + PopulateDot11fTdlsExtCapability(pMac, psessionEntry, &tdlsSetupReq.ExtCap); + + if (1 == pMac->lim.gLimTDLSWmmMode) + { + tANI_U32 val = 0; + + /* include WMM IE */ + tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; + tdlsSetupReq.WMMInfoStation.acvo_uapsd = + (pMac->lim.gLimTDLSUapsdMask & 0x01); + tdlsSetupReq.WMMInfoStation.acvi_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupReq.WMMInfoStation.acbk_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupReq.WMMInfoStation.acbe_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, + FL("could not retrieve Max SP Length"));) + + tdlsSetupReq.WMMInfoStation.max_sp_length = (tANI_U8)val; + tdlsSetupReq.WMMInfoStation.present = 1; + } + else + { + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + /* Populate QOS info, needed for Peer U-APSD session */ + /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends + on AP's capability, and TDLS doesn't want to depend on AP's capability */ + tdlsSetupReq.QOSCapsStation.present = 1; + tdlsSetupReq.QOSCapsStation.max_sp_length = 0; + tdlsSetupReq.QOSCapsStation.qack = 0; + tdlsSetupReq.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + tdlsSetupReq.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupReq.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupReq.QOSCapsStation.acvo_uapsd = (pMac->lim.gLimTDLSUapsdMask & 0x01); + } + + /* + * we will always try to init TDLS link with 11n capabilities + * let TDLS setup response to come, and we will set our caps based + * of peer caps + */ + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupReq.HTCaps, + &tdlsSetupReq.VHTCaps, psessionEntry ); + + /* Populate AID */ + PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac, + &tdlsSetupReq.AID, psessionEntry ); + + /* Populate TDLS offchannel param only if offchannel is enabled + * and TDLS Channel Switching is not prohibited by AP in ExtCap + * IE in assoc/re-assoc response. + */ + if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) && + (!psessionEntry->tdls_chan_swit_prohibited)) + { + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsSetupReq.SuppChannels, + &tdlsSetupReq.SuppOperatingClasses); + if ( pMac->roam.configParam.bandCapability != eCSR_BAND_24) + { + tdlsSetupReq.HT2040BSSCoexistence.present = 1; + tdlsSetupReq.HT2040BSSCoexistence.infoRequest = 1; + } + } + else + { + limLog(pMac, LOG1, + FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"), + pMac->lim.gLimTDLSOffChannelEnabled, + psessionEntry->tdls_chan_swit_prohibited); + } + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupReqSize( pMac, &tdlsSetupReq, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupReq), TDLS_LINK_AP, TDLS_INITIATOR, TID_AC_BK, psessionEntry) ; + + limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"), + __func__, tdlsSetupReq.VHTCaps.supportedChannelWidthSet, tdlsSetupReq.VHTCaps.rxMCSMap, + tdlsSetupReq.VHTCaps.txMCSMap, tdlsSetupReq.VHTCaps.txSupDataRate ); + + status = dot11fPackTDLSSetupReq( pMac, &tdlsSetupReq, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req " + "(0x%08x)."), status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Discovery Request (0x%08x)."), status ); + } + + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"), + addIeLen )); + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"), + SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) )); + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; +#if defined(CONFIG_HL_SUPPORT) + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_BK, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, true ); +#else + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_BK, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, false ); +#endif + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} +/* + * Send TDLS Teardown frame on Direct link or AP link, depends on reason code. + */ + +tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSTeardown teardown ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + tANI_U8 smeSessionId = 0; + + if (NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL" )); + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&teardown, sizeof( tDot11fTDLSTeardown ), 0 ); + teardown.Category.category = SIR_MAC_ACTION_TDLS ; + teardown.Action.action = SIR_MAC_TDLS_TEARDOWN ; + teardown.Reason.code = reason ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier, + peerMac, (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR) ; + + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSTeardownSize( pMac, &teardown, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(teardown), + (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) + ? TDLS_LINK_AP : TDLS_LINK_DIRECT, + (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR, + TID_AC_VI, psessionEntry) ; + + status = dot11fPackTDLSTeardown( pMac, &teardown, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS Teardown req (0x%08x)."), + status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Teardown Request (0x%08x)."), status ); + } + + if( addIeLen != 0 ) + { + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"), + addIeLen )); + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"), + padLen )); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -%s-> OTA"), + SIR_MAC_TDLS_TEARDOWN, limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN), + (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP": "DIRECT" )); + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; +#if defined(CONFIG_HL_SUPPORT) + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, + (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? true : false ); +#else + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, + false ); +#endif + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + + } + return eSIR_SUCCESS; + +} + +/* + * Send Setup RSP frame on AP link. + */ +static tSirRetStatus limSendTdlsSetupRspFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry, + etdlsLinkSetupStatus setupStatus, tANI_U8 *addIe, tANI_U16 addIeLen ) +{ + tDot11fTDLSSetupRsp tdlsSetupRsp ; + tANI_U32 status = 0 ; + tANI_U16 caps = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + tANI_U8 smeSessionId = 0; + + if (NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL" )); + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&tdlsSetupRsp, sizeof( tDot11fTDLSSetupRsp ),0 ); + + /* + * setup Fixed fields, + */ + tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS; + tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP ; + tdlsSetupRsp.DialogToken.token = dialog; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupRsp.LinkIdentifier, + peerMac, TDLS_RESPONDER) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + swapBitField16(caps, ( tANI_U16* )&tdlsSetupRsp.Capabilities ); + + /* populate supported rate and ext supported rate IE */ + populate_dot11f_rates_tdls(pMac, &tdlsSetupRsp.SuppRates, + &tdlsSetupRsp.ExtSuppRates); + + /* Populate extended supported rates */ + PopulateDot11fTdlsExtCapability(pMac, psessionEntry, &tdlsSetupRsp.ExtCap); + + if (1 == pMac->lim.gLimTDLSWmmMode) + { + tANI_U32 val = 0; + + /* include WMM IE */ + tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; + tdlsSetupRsp.WMMInfoStation.acvo_uapsd = + (pMac->lim.gLimTDLSUapsdMask & 0x01); + tdlsSetupRsp.WMMInfoStation.acvi_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupRsp.WMMInfoStation.acbk_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupRsp.WMMInfoStation.acbe_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, + FL("could not retrieve Max SP Length"));) + + tdlsSetupRsp.WMMInfoStation.max_sp_length = (tANI_U8)val; + tdlsSetupRsp.WMMInfoStation.present = 1; + } + else + { + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + /* Populate QOS info, needed for Peer U-APSD session */ + /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and + TDLS doesn't want to depend on AP's capability */ + tdlsSetupRsp.QOSCapsStation.present = 1; + tdlsSetupRsp.QOSCapsStation.max_sp_length = 0; + tdlsSetupRsp.QOSCapsStation.qack = 0; + tdlsSetupRsp.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + tdlsSetupRsp.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupRsp.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupRsp.QOSCapsStation.acvo_uapsd = (pMac->lim.gLimTDLSUapsdMask & 0x01); + } + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps, + &tdlsSetupRsp.VHTCaps, psessionEntry ); + + /* Populate AID */ + PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac, + &tdlsSetupRsp.AID, psessionEntry ); + + /* Populate TDLS offchannel param only if offchannel is enabled + * and TDLS Channel Switching is not prohibited by AP in ExtCap + * IE in assoc/re-assoc response. + */ + if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) && + (!psessionEntry->tdls_chan_swit_prohibited)) + { + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsSetupRsp.SuppChannels, + &tdlsSetupRsp.SuppOperatingClasses); + if ( pMac->roam.configParam.bandCapability != eCSR_BAND_24) + { + tdlsSetupRsp.HT2040BSSCoexistence.present = 1; + tdlsSetupRsp.HT2040BSSCoexistence.infoRequest = 1; + } + } + else + { + limLog(pMac, LOG1, + FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"), + pMac->lim.gLimTDLSOffChannelEnabled, + psessionEntry->tdls_chan_swit_prohibited); + } + + tdlsSetupRsp.Status.status = setupStatus ; + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupRspSize( pMac, &tdlsSetupRsp, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), + TDLS_LINK_AP, TDLS_RESPONDER, + TID_AC_BK, psessionEntry) ; + + limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"), + __func__, tdlsSetupRsp.VHTCaps.supportedChannelWidthSet, tdlsSetupRsp.VHTCaps.rxMCSMap, + tdlsSetupRsp.VHTCaps.txMCSMap, tdlsSetupRsp.VHTCaps.txSupDataRate ); + status = dot11fPackTDLSSetupRsp( pMac, &tdlsSetupRsp, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req " + "(0x%08x)."), status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Discovery Request (0x%08x)."), status ); + } + + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"), + SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) )); + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; +#if defined(CONFIG_HL_SUPPORT) + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_BK, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, true ); +#else + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_BK, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, false ); +#endif + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} + +/* + * Send TDLS setup CNF frame on AP link + */ + +tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, + tANI_U8 dialog, + tANI_U32 peerCapability, + tpPESession psessionEntry, + tANI_U8* addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSSetupCnf tdlsSetupCnf ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + tANI_U8 smeSessionId = 0; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&tdlsSetupCnf, sizeof( tDot11fTDLSSetupCnf ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS; + tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF ; + tdlsSetupCnf.DialogToken.token = dialog ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupCnf.LinkIdentifier, + peerMac, TDLS_INITIATOR) ; + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + + /* Check self and peer WMM capable */ + if ((1 == pMac->lim.gLimTDLSWmmMode) && + (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) + { + PopulateDot11fWMMParams(pMac, &tdlsSetupCnf.WMMParams, psessionEntry); + } + + /* Check peer is VHT capable*/ + if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) + { + PopulateDot11fVHTOperation( pMac, &tdlsSetupCnf.VHTOperation); + PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry ); + } + else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) /* Check peer is HT capable */ + { + PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry ); + } + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupCnfSize( pMac, &tdlsSetupCnf, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a discovery Request (0x%08x)."), status ); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a discovery Request (" + "0x%08x)."), status ); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS" + "Discovery Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf), TDLS_LINK_AP, TDLS_INITIATOR, + TID_AC_VI, psessionEntry) ; + + status = dot11fPackTDLSSetupCnf( pMac, &tdlsSetupCnf, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req " + "(0x%08x)."), status ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing TDLS " + "Discovery Request (0x%08x)."), status ); + } + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"), + padLen )); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"), + SIR_MAC_TDLS_SETUP_CNF, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_CNF) )); + + pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId; +#if defined(CONFIG_HL_SUPPORT) + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, true ); +#else + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME, + smeSessionId, false ); +#endif + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" )); + return eSIR_FAILURE; + + } + + return eSIR_SUCCESS; +} + + +/* This Function is similar to PopulateDot11fHTCaps, except that the HT Capabilities + * are considered from the AddStaReq rather from the cfg.dat as in PopulateDot11fHTCaps + */ +static tSirRetStatus limTdlsPopulateDot11fHTCaps(tpAniSirGlobal pMac, tpPESession psessionEntry, + tSirTdlsAddStaReq *pTdlsAddStaReq, tDot11fIEHTCaps *pDot11f) +{ + tANI_U32 nCfgValue; + tANI_U8 nCfgValue8; + tSirMacHTParametersInfo *pHTParametersInfo; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + tSirMacExtendedHTCapabilityInfo extHtCapInfo; + } uHTCapabilityInfo; + + tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; + tSirMacASCapabilityInfo *pASCapabilityInfo; + + nCfgValue = pTdlsAddStaReq->htCap.capInfo; + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap; + pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave; + pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField; + pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz; + pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz; + pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC; + pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC; + pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA; + pDot11f->maximalAMSDUsize = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize; + pDot11f->dsssCckMode40MHz = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz; + pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp; + pDot11f->stbcControlFrame = uHTCapabilityInfo.htCapInfo.stbcControlFrame; + pDot11f->lsigTXOPProtection = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection; + + // All sessionized entries will need the check below + if (psessionEntry == NULL) // Only in case of NO session + { + pDot11f->supportedChannelWidthSet = uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet; + } + else + { + pDot11f->supportedChannelWidthSet = psessionEntry->htSupportedChannelWidthSet; + } + + /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is + eHT_CHANNEL_WIDTH_20MHZ */ + if(pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) + { + pDot11f->shortGI40MHz = 0; + } + + dot11fLog(pMac, LOG2, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"), + pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave, pDot11f->greenField, + pDot11f->shortGI20MHz, pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz); + + nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo; + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + pHTParametersInfo = ( tSirMacHTParametersInfo* ) &nCfgValue8; + + pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; + pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; + pDot11f->reserved1 = pHTParametersInfo->reserved; + + dot11fLog( pMac, LOG2, FL( "AMPDU Param: %x" ), nCfgValue); + + vos_mem_copy( pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet, + SIZE_OF_SUPPORTED_MCS_SET); + + nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo; + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; + pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; + pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; + + nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo; + + pTxBFCapabilityInfo = ( tSirMacTxBFCapabilityInfo* ) &nCfgValue; + pDot11f->txBF = pTxBFCapabilityInfo->txBF; + pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; + pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; + pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; + pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; + pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; + pDot11f->calibration = pTxBFCapabilityInfo->calibration; + pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; + pDot11f->explicitUncompressedSteeringMatrix = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; + pDot11f->explicitBFCSIFeedback = pTxBFCapabilityInfo->explicitBFCSIFeedback; + pDot11f->explicitUncompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; + pDot11f->explicitCompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; + pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; + pDot11f->uncompressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; + pDot11f->compressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; + + nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo; + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + + pASCapabilityInfo = ( tSirMacASCapabilityInfo* ) &nCfgValue8; + pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; + pDot11f->explicitCSIFeedbackTx = pASCapabilityInfo->explicitCSIFeedbackTx; + pDot11f->antennaIndicesFeedbackTx = pASCapabilityInfo->antennaIndicesFeedbackTx; + pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; + pDot11f->antennaIndicesFeedback = pASCapabilityInfo->antennaIndicesFeedback; + pDot11f->rxAS = pASCapabilityInfo->rxAS; + pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; + + pDot11f->present = pTdlsAddStaReq->htcap_present; + + return eSIR_SUCCESS; + +} + +tSirRetStatus +limTdlsPopulateDot11fVHTCaps(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pTdlsAddStaReq, + tDot11fIEVHTCaps *pDot11f) +{ + tANI_U32 nCfgValue=0; + union { + tANI_U32 nCfgValue32; + tSirMacVHTCapabilityInfo vhtCapInfo; + } uVHTCapabilityInfo; + union { + tANI_U16 nCfgValue16; + tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo; + tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo; + } uVHTSupDataRateInfo; + + pDot11f->present = pTdlsAddStaReq->vhtcap_present; + + nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo; + uVHTCapabilityInfo.nCfgValue32 = nCfgValue; + + pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen; + pDot11f->supportedChannelWidthSet = uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet; + pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap; + pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz; + pDot11f->shortGI160and80plus80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz; + pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC; + pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC; + pDot11f->suBeamFormerCap = 0; + pDot11f->suBeamformeeCap = 0; + pDot11f->csnofBeamformerAntSup = uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup; + pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim; + pDot11f->muBeamformerCap = 0; + pDot11f->muBeamformeeCap = 0; + pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS; + pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap; + pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp; + pDot11f->vhtLinkAdaptCap = uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap; + pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern; + pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern; + pDot11f->reserved1= uVHTCapabilityInfo.vhtCapInfo.reserved1; + + pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap; + + nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest; + uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; + pDot11f->rxHighSupDataRate = uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate; + + pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap; + + nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest; + uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; + pDot11f->txSupDataRate = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate; + + pDot11f->reserved3= uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved; + + limLogVHTCap(pMac, pDot11f); + + return eSIR_SUCCESS; + +} + +static tSirRetStatus +limTdlsPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 *pSupportedRateSet, + tANI_U8 supporteRatesLength, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) + +{ + tSirMacRateSet tempRateSet; + tANI_U32 i,j,val,min,isArate; + tSirMacRateSet tempRateSet2; + tANI_U32 phyMode; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + isArate=0; + tempRateSet2.numRates = 0; + + limGetPhyMode(pMac, &phyMode, NULL); + + // get own rate set + val = WNI_CFG_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet.rate, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve rateset")); + val = 0; + } + tempRateSet.numRates = val; + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + + // get own extended rate set + val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet2.rate, + &val) != eSIR_SUCCESS) + tempRateSet2.numRates = val; + } + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG"));) + goto error; + } + + /** + * Handling of the rate set IEs is the following: + * - keep only rates that we support and that the station supports + * - sort and the rates into the pSta->rate array + */ + + // Copy all rates in tempRateSet, there are 12 rates max + for (i = 0; i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in tempRateSet2 + */ + tempRateSet2.numRates = 0; + + for (i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + + for(j = 0;j < tempRateSet.numRates; j++) + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + + tempRateSet2.rate[tempRateSet2.numRates++] = tempRateSet.rate[min]; + tempRateSet.rate[min] = 0xff; + } + + /** + * Copy received rates in tempRateSet, the parser has ensured + * unicity of the rates so there cannot be more than 12 . + */ + if (supporteRatesLength > SIR_MAC_RATESET_EID_MAX) + { + limLog( pMac, LOGW, FL("Supported rates length %d more than " + "the Max limit, reset to Max"), + supporteRatesLength); + supporteRatesLength = SIR_MAC_RATESET_EID_MAX; + } + + for (i = 0; i < supporteRatesLength; i++) + { + tempRateSet.rate[i] = pSupportedRateSet[i]; + } + + tempRateSet.numRates = supporteRatesLength; + + { + tpSirSupportedRates rates = &pStaDs->supportedRates; + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set( (tANI_U8 *) rates, sizeof(tSirSupportedRates), 0); + + for (i = 0;i < tempRateSet2.numRates; i++) + { + for (j = 0;j < tempRateSet.numRates; j++) + { + if ((tempRateSet2.rate[i] & 0x7F) == + (tempRateSet.rate[j] & 0x7F)) + { +#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC + if ((bRateIndex > HAL_NUM_11B_RATES) || (aRateIndex > HAL_NUM_11A_RATES)) + { + limLog(pMac, LOGE, FL("Invalid number of rates (11b->%d, 11a->%d)"), + bRateIndex, aRateIndex); + return eSIR_FAILURE; + } +#endif + if (sirIsArate(tempRateSet2.rate[i] & 0x7f)) + { + isArate=1; + rates->llaRates[aRateIndex++] = tempRateSet2.rate[i]; + } + else + rates->llbRates[bRateIndex++] = tempRateSet2.rate[i]; + break; + } + } + } + } + + + //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n +#ifdef FEATURE_WLAN_TDLS + if (pStaDs->mlmStaContext.htCapability) +#else + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pStaDs->mlmStaContext.htCapability)) +#endif + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + mcsSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet")); + goto error; + } + + for (i=0; isupportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i]; + + PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from CFG and DPH :"));) + for (i=0; isupportedRates.supportedMCSSet[i]);) + } + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry); +#endif + /** + * Set the erpEnabled bit iff the phy is in G mode and at least + * one A rate is supported + */ + if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate) + pStaDs->erpEnabled = eHAL_SET; + + + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} + +/* + * update HASH node entry info + */ +static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs, + tSirTdlsAddStaReq *pTdlsAddStaReq, tpPESession psessionEntry) +{ + tDot11fIEHTCaps htCap = {0,}; + tDot11fIEHTCaps *htCaps; + tDot11fIEVHTCaps *pVhtCaps = NULL; + tDot11fIEVHTCaps *pVhtCaps_txbf = NULL; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps vhtCap; + tANI_U8 cbMode; +#endif + tpDphHashNode pSessStaDs = NULL; + tANI_U16 aid; + + if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) + { + PopulateDot11fHTCaps(pMac, psessionEntry, &htCap); + } + else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) + { + limTdlsPopulateDot11fHTCaps(pMac, NULL, pTdlsAddStaReq, &htCap); + } + htCaps = &htCap; + if (htCaps->present) + { + pStaDs->mlmStaContext.htCapability = 1 ; + pStaDs->htGreenfield = htCaps->greenField ; + pStaDs->htSupportedChannelWidthSet = htCaps->supportedChannelWidthSet ; + pStaDs->htMIMOPSState = htCaps->mimoPowerSave ; + pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize; + pStaDs->htAMpduDensity = htCaps->mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz ; + pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz; + pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz; + pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor; + limFillRxHighestSupportedRate(pMac, + &pStaDs->supportedRates.rxHighestDataRate, + htCaps->supportedMCSSet); + pStaDs->baPolicyFlag = 0xFF; + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N ; + pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo; + } + else + { + pStaDs->mlmStaContext.htCapability = 0 ; + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG ; + } +#ifdef WLAN_FEATURE_11AC + limTdlsPopulateDot11fVHTCaps(pMac, pTdlsAddStaReq, &vhtCap); + pVhtCaps = &vhtCap; + if (pVhtCaps->present) + { + pStaDs->mlmStaContext.vhtCapability = 1 ; + + if ((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) && + pMac->roam.configParam.enableVhtFor24GHz) + { + pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + else + { + pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ ; + } + + pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap; + pStaDs->vhtBeamFormerCapable = 0; + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC; + pVhtCaps_txbf = (tDot11fIEVHTCaps *)(&pTdlsAddStaReq->vhtCap); + pVhtCaps_txbf->suBeamformeeCap = 0; + pVhtCaps_txbf->suBeamFormerCap = 0; + pVhtCaps_txbf->muBeamformerCap = 0; + pVhtCaps_txbf->muBeamformeeCap = 0; + pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo; + } + else + { + pStaDs->mlmStaContext.vhtCapability = 0 ; + pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + } +#endif + /*Calculate the Secondary Coannel Offset */ + cbMode = limSelectCBMode(pStaDs, psessionEntry, + psessionEntry->currentOperChannel, + pStaDs->vhtSupportedChannelWidthSet); + + pStaDs->htSecondaryChannelOffset = cbMode; + +#ifdef WLAN_FEATURE_11AC + if ( pStaDs->mlmStaContext.vhtCapability ) + { + pStaDs->htSecondaryChannelOffset = limGetHTCBState(cbMode); + } +#endif + + pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid, + &psessionEntry->dph.dphHashTable) ; + + /* Lets enable QOS parameter */ + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 1; + pStaDs->lleEnabled = 0; + /* TDLS Dummy AddSTA does not have qosInfo , is it OK ?? + */ + pStaDs->qos.capability.qosInfo = (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues); + + /* populate matching rate set */ + + /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ?? + */ + limTdlsPopulateMatchingRateSet(pMac, pStaDs, pTdlsAddStaReq->supported_rates, + pTdlsAddStaReq->supported_rates_length, + (tANI_U8 *)pTdlsAddStaReq->htCap.suppMcsSet, + &pStaDs->mlmStaContext.propRateSet, + psessionEntry, pVhtCaps); + + /* TDLS Dummy AddSTA does not have right capability , is it OK ?? + */ + pStaDs->mlmStaContext.capabilityInfo = ( *(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability); + + return ; +} + +/* + * Add STA for TDLS setup procedure + */ +static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pAddStaReq, + tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL ; + tSirRetStatus status = eSIR_SUCCESS ; + tANI_U16 aid = 0 ; + + pStaDs = dphLookupHashEntry(pMac, pAddStaReq->peerMac, &aid, + &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + aid = limAssignPeerIdx(pMac, psessionEntry) ; + + if( !aid ) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("%s: No more free AID for peer " MAC_ADDRESS_STR), + __func__, MAC_ADDR_ARRAY(pAddStaReq->peerMac)) ; + return eSIR_FAILURE; + } + + /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */ + SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid); + + VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, + ("limTdlsSetupAddSta: Aid = %d, for peer =" MAC_ADDRESS_STR), + aid, MAC_ADDR_ARRAY(pAddStaReq->peerMac)); + pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs) + { + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry); + } + + pStaDs = dphAddHashEntry(pMac, pAddStaReq->peerMac, aid, + &psessionEntry->dph.dphHashTable) ; + + if(NULL == pStaDs) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + (" add hash entry failed")) ; + VOS_ASSERT(0) ; + return eSIR_FAILURE; + } + } + + limTdlsUpdateHashNodeInfo(pMac, pStaDs, pAddStaReq, psessionEntry) ; + + pStaDs->staType = STA_ENTRY_TDLS_PEER ; + + status = limAddSta(pMac, pStaDs, (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) ? true: false, psessionEntry); + + if(eSIR_SUCCESS != status) + { + /* should not fail */ + VOS_ASSERT(0) ; + } + return status ; +} + +/* + * Del STA, after Link is teardown or discovery response sent on direct link + */ +static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac, + tpPESession psessionEntry) +{ + tSirRetStatus status = eSIR_SUCCESS ; + tANI_U16 peerIdx = 0 ; + tpDphHashNode pStaDs = NULL ; + + pStaDs = dphLookupHashEntry(pMac, peerMac, &peerIdx, + &psessionEntry->dph.dphHashTable) ; + + if(pStaDs) + { + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("DEL STA peer MAC: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + + VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, + ("limTdlsDelSta: STA type = %x, sta idx = %x"),pStaDs->staType, + pStaDs->staIndex) ; + + status = limDelSta(pMac, pStaDs, false, psessionEntry) ; + } + + return pStaDs ; +} + + +/* + * Once Link is setup with PEER, send Add STA ind to SME + */ +static eHalStatus limSendSmeTdlsAddStaRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tANI_U8 updateSta, + tDphHashNode *pStaDs, tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + tSirTdlsAddStaRsp *addStaRsp = NULL ; + mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ; + + addStaRsp = vos_mem_malloc(sizeof(tSirTdlsAddStaRsp)); + if ( NULL == addStaRsp ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return eSIR_FAILURE; + } + + addStaRsp->sessionId = sessionId; + addStaRsp->statusCode = status; + if( pStaDs ) + { + addStaRsp->staId = pStaDs->staIndex ; + addStaRsp->ucastSig = pStaDs->ucUcastSig ; + addStaRsp->bcastSig = pStaDs->ucBcastSig ; + } + if( peerMac ) + { + vos_mem_copy( addStaRsp->peerMac, + (tANI_U8 *) peerMac, sizeof(tSirMacAddr)); + } + if (updateSta) + addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE; + else + addStaRsp->tdlsAddOper = TDLS_OPER_ADD; + + addStaRsp->length = sizeof(tSirTdlsAddStaRsp) ; + addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP ; + + mmhMsg.bodyptr = addStaRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return eSIR_SUCCESS ; + +} +/* + * STA RSP received from HAL + */ +eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, + tpPESession psessionEntry) +{ + tAddStaParams *pAddStaParams = (tAddStaParams *) msg ; + tANI_U8 status = eSIR_SUCCESS ; + tDphHashNode *pStaDs = NULL ; + tANI_U16 aid = 0 ; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, + ("limTdlsAddStaRsp: staIdx=%d, staMac="MAC_ADDRESS_STR), pAddStaParams->staIdx, + MAC_ADDR_ARRAY(pAddStaParams->staMac)); + + if (pAddStaParams->status != eHAL_STATUS_SUCCESS) + { + VOS_ASSERT(0) ; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("Add sta failed ")) ; + status = eSIR_FAILURE; + goto add_sta_error; + } + + pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid, + &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("pStaDs is NULL ")) ; + status = eSIR_FAILURE; + goto add_sta_error; + } + + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + pStaDs->ucUcastSig = pAddStaParams->ucUcastSig; + pStaDs->ucBcastSig = pAddStaParams->ucBcastSig; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + pStaDs->valid = 1 ; +add_sta_error: + status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId, + pAddStaParams->staMac, pAddStaParams->updateSta, pStaDs, status) ; + vos_mem_free( pAddStaParams ); + return status ; +} + +void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIESuppChannels *suppChannels, + tDot11fIESuppOperatingClasses *suppOperClasses) +{ + tANI_U32 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tANI_U8 validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 i; + tANI_U8 valid_count = 0; + tANI_U8 chanOffset; + tANI_U8 op_class; + tANI_U8 numClasses; + tANI_U8 classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Valid channel list")); + } + + /* validating the channel list for DFS channels */ + for (i = 0U; i < numChans; i++) + { + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(validChan[i])) + { + limLog(pMac, LOG1, + FL("skipping DFS channel %d from the valid channel list"), + validChan[i]); + continue; + } + suppChannels->bands[valid_count][0] = validChan[i]; + suppChannels->bands[valid_count][1] = 1; + valid_count++; + } + + suppChannels->num_bands = valid_count; + suppChannels->present = 1 ; + + /* find channel offset and get op class for current operating channel */ + switch (psessionEntry->htSecondaryChannelOffset) + { + case PHY_SINGLE_CHANNEL_CENTERED: + chanOffset = BW20; + break; + + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + chanOffset = BW40_LOW_PRIMARY; + break; + + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + chanOffset = BW40_HIGH_PRIMARY; + break; + + default: + chanOffset = BWALL; + break; + + } + + op_class = regdm_get_opclass_from_channel(pMac->scan.countryCodeCurrent, + psessionEntry->currentOperChannel, + chanOffset); + if (op_class == 0) + { + PELOGE(limLog(pMac, LOGE, FL("Present Operating class is wrong, countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d"), + pMac->scan.countryCodeCurrent, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset, + chanOffset);) + } + else + { + PELOGE(limLog(pMac, LOG1, FL("Present Operating channel: %d chanOffset: %d, op class=%d"), + psessionEntry->currentOperChannel, + chanOffset, + op_class);) + } + suppOperClasses->present = 1; + suppOperClasses->classes[0] = op_class; + + regdm_get_curr_opclasses(&numClasses, &classes[0]); + + for (i = 0; i < numClasses; i++) + { + suppOperClasses->classes[i+1] = classes[i]; + } + /* add one for present operating class, added in the beginning */ + suppOperClasses->num_classes = numClasses + 1; + + return ; +} +/* + * FUNCTION: Populate Link Identifier element IE + * + */ + + +void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry, + tDot11fIELinkIdentifier *linkIden, + tSirMacAddr peerMac, tANI_U8 reqType) +{ + tANI_U8 *initStaAddr = NULL ; + tANI_U8 *respStaAddr = NULL ; + + (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr), + (respStaAddr = linkIden->RespStaAddr)) + : ((respStaAddr = linkIden->InitStaAddr ), + (initStaAddr = linkIden->RespStaAddr)) ; + vos_mem_copy( (tANI_U8 *)linkIden->bssid, + (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ; + + vos_mem_copy( (tANI_U8 *)initStaAddr, + psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ; + + vos_mem_copy( (tANI_U8 *)respStaAddr, (tANI_U8 *) peerMac, + sizeof( tSirMacAddr )); + + linkIden->present = 1 ; + return ; + +} + +void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEExtCap *extCapability) +{ + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes; + + p_ext_cap->TDLSPeerPSMSupp = PEER_PSM_SUPPORT ; + p_ext_cap->TDLSPeerUAPSDBufferSTA = pMac->lim.gLimTDLSBufStaEnabled; + + /* Set TDLS channel switching bits only if offchannel is enabled + * and TDLS Channel Switching is not prohibited by AP in ExtCap + * IE in assoc/re-assoc response. + */ + if ((1== pMac->lim.gLimTDLSOffChannelEnabled) && + (!psessionEntry->tdls_chan_swit_prohibited)) { + p_ext_cap->TDLSChannelSwitching = 1; + p_ext_cap->TDLSChanSwitProhibited = 0; + } else { + p_ext_cap->TDLSChannelSwitching = 0; + p_ext_cap->TDLSChanSwitProhibited = TDLS_CH_SWITCH_PROHIBITED; + } + + p_ext_cap->TDLSSupport = TDLS_SUPPORT ; + p_ext_cap->TDLSProhibited = TDLS_PROHIBITED ; + + extCapability->present = 1 ; + /* For STA cases we alwasy support 11mc - Allow MAX length */ + extCapability->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; + + return ; +} + + +/* + * Process Send Mgmt Request from SME and transmit to AP. + */ +tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsSendMgmtReq *pSendMgmtReq = (tSirTdlsSendMgmtReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirResultCodes resultCode = eSIR_SME_INVALID_PARAMETERS; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Send Mgmt Recieved")) ; + + if((psessionEntry = peFindSessionByBssid(pMac, pSendMgmtReq->bssid, &sessionId)) + == NULL) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "PE Session does not exist for given sme sessionId %d", + pSendMgmtReq->sessionId); + goto lim_tdls_send_mgmt_error; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "send mgmt received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_send_mgmt_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, "send mgmt received in invalid LIMsme " + "state (%d)", psessionEntry->limSmeState); + goto lim_tdls_send_mgmt_error; + } + + switch( pSendMgmtReq->reqType ) + { + case SIR_MAC_TDLS_DIS_REQ: + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Transmit Discovery Request Frame") ; + /* format TDLS discovery request frame and transmit it */ + limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, + pSendMgmtReq->dialog, + psessionEntry) ; + resultCode = eSIR_SME_SUCCESS; + break; + case SIR_MAC_TDLS_DIS_RSP: + { + //Send a response mgmt action frame + limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac, + pSendMgmtReq->dialog, psessionEntry, + &pSendMgmtReq->addIe[0], + (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_REQ: + { + limSendTdlsLinkSetupReqFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_RSP: + { + limSendTdlsSetupRspFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_CNF: + { + limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, pSendMgmtReq->peerCapability, + psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_TEARDOWN: + { + limSendTdlsTeardownFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, pSendMgmtReq->responder, psessionEntry, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_PEER_TRAFFIC_IND: + { + } + break; + case SIR_MAC_TDLS_CH_SWITCH_REQ: + { + } + break; + case SIR_MAC_TDLS_CH_SWITCH_RSP: + { + } + break; + case SIR_MAC_TDLS_PEER_TRAFFIC_RSP: + { + } + break; + default: + break; + } + +lim_tdls_send_mgmt_error: + + limSendSmeRsp( pMac, eWNI_SME_TDLS_SEND_MGMT_RSP, + resultCode, pSendMgmtReq->sessionId, pSendMgmtReq->transactionId); + + return eSIR_SUCCESS; +} + +/* + * Send Response to Link Establish Request to SME + */ +void limSendSmeTdlsLinkEstablishReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + + tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL ; + + pTdlsLinkEstablishReqRsp = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp)); + if ( NULL == pTdlsLinkEstablishReqRsp ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return ; + } + pTdlsLinkEstablishReqRsp->statusCode = status ; + if ( peerMac ) + { + vos_mem_copy(pTdlsLinkEstablishReqRsp->peerMac, peerMac, sizeof(tSirMacAddr)); + } + pTdlsLinkEstablishReqRsp->sessionId = sessionId; + mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP ; + mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return ; + + +} + +/* + * Once link is teardown, send Del Peer Ind to SME + */ +static eHalStatus limSendSmeTdlsDelStaRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + tSirTdlsDelStaRsp *pDelSta = NULL ; + mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP ; + + pDelSta = vos_mem_malloc(sizeof(tSirTdlsDelStaRsp)); + if ( NULL == pDelSta ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return eSIR_FAILURE; + } + + pDelSta->sessionId = sessionId; + pDelSta->statusCode = status ; + if( pStaDs ) + { + pDelSta->staId = pStaDs->staIndex ; + } + else + pDelSta->staId = HAL_STA_INVALID_IDX; + + if( peerMac ) + { + vos_mem_copy(pDelSta->peerMac, peerMac, sizeof(tSirMacAddr)); + } + + pDelSta->length = sizeof(tSirTdlsDelStaRsp) ; + pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP ; + + mmhMsg.bodyptr = pDelSta; + + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return eSIR_SUCCESS ; + +} + +/* + * Process Send Mgmt Request from SME and transmit to AP. + */ +tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Send Mgmt Recieved")) ; + + if((psessionEntry = peFindSessionByBssid(pMac, pAddStaReq->bssid, &sessionId)) + == NULL) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "PE Session does not exist for given sme sessionId %d", + pAddStaReq->sessionId); + goto lim_tdls_add_sta_error; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "send mgmt received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_add_sta_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, "send mgmt received in invalid LIMsme " + "state (%d)", psessionEntry->limSmeState); + goto lim_tdls_add_sta_error; + } + + pMac->lim.gLimAddStaTdls = true ; + + /* To start with, send add STA request to HAL */ + if (eSIR_FAILURE == limTdlsSetupAddSta(pMac, pAddStaReq, psessionEntry)) + { + limLog(pMac, LOGE, "%s: Add TDLS Station request failed ", __func__); + goto lim_tdls_add_sta_error; + } + return eSIR_SUCCESS; +lim_tdls_add_sta_error: + limSendSmeTdlsAddStaRsp(pMac, + pAddStaReq->sessionId, pAddStaReq->peerMac, + (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE), NULL, eSIR_FAILURE ); + + return eSIR_SUCCESS; +} +/* + * Process Del Sta Request from SME . + */ +tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + tpDphHashNode pStaDs = NULL ; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Send Mgmt Recieved")) ; + + if((psessionEntry = peFindSessionByBssid(pMac, pDelStaReq->bssid, &sessionId)) + == NULL) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "PE Session does not exist for given sme sessionId %d", + pDelStaReq->sessionId); + limSendSmeTdlsDelStaRsp(pMac, pDelStaReq->sessionId, pDelStaReq->peerMac, + NULL, eSIR_FAILURE) ; + return eSIR_FAILURE; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "Del sta received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_del_sta_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, "Del Sta received in invalid LIMsme state (%d)", + psessionEntry->limSmeState); + goto lim_tdls_del_sta_error; + } + + pStaDs = limTdlsDelSta(pMac, pDelStaReq->peerMac, psessionEntry) ; + + /* now send indication to SME-->HDD->TL to remove STA from TL */ + + if(pStaDs) + { + limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac, + pStaDs, eSIR_SUCCESS) ; + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ; + + /* Clear the aid in peerAIDBitmap as this aid is now in freepool */ + CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, pStaDs->assocId); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ; + + return eSIR_SUCCESS; + + } + +lim_tdls_del_sta_error: + limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac, + NULL, eSIR_FAILURE) ; + + return eSIR_SUCCESS; +} + +/* Intersects the two input arrays and outputs an array */ +/* For now the array length of tANI_U8 suffices */ +static void limTdlsGetIntersection(tANI_U8 *input_array1,tANI_U8 input1_length, + tANI_U8 *input_array2,tANI_U8 input2_length, + tANI_U8 *output_array,tANI_U8 *output_length) +{ + tANI_U8 i,j,k=0,flag=0; + for(i=0;ibssid, &sessionId)) + == NULL) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "PE Session does not exist for given sme sessionId %d", + pTdlsLinkEstablishReq->sessionId); + limSendSmeTdlsLinkEstablishReqRsp(pMac, pTdlsLinkEstablishReq->sessionId, pTdlsLinkEstablishReq->peerMac, + NULL, eSIR_FAILURE) ; + return eSIR_FAILURE; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "TDLS Link Establish Request received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_link_establish_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, "TDLS Link Establish Request received in " + "invalid LIMsme state (%d)", psessionEntry->limSmeState); + goto lim_tdls_link_establish_error; + } + /*TODO Sunil , TDLSPeer Entry has the STA ID , Use it */ + pStaDs = dphLookupHashEntry(pMac, pTdlsLinkEstablishReq->peerMac, &peerIdx, + &psessionEntry->dph.dphHashTable) ; + if ( NULL == pStaDs ) + { + limLog( pMac, LOGE, FL( "pStaDs is NULL" )); + goto lim_tdls_link_establish_error; + + } + pMsgTdlsLinkEstablishReq = vos_mem_malloc(sizeof( tTdlsLinkEstablishParams )); + if ( NULL == pMsgTdlsLinkEstablishReq ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory TDLS Link Establish Request" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set( (tANI_U8 *)pMsgTdlsLinkEstablishReq, sizeof(tpTdlsLinkEstablishParams), 0); + + pMsgTdlsLinkEstablishReq->staIdx = pStaDs->staIndex; + pMsgTdlsLinkEstablishReq->isResponder = pTdlsLinkEstablishReq->isResponder; + pMsgTdlsLinkEstablishReq->uapsdQueues = pTdlsLinkEstablishReq->uapsdQueues; + pMsgTdlsLinkEstablishReq->maxSp = pTdlsLinkEstablishReq->maxSp; + pMsgTdlsLinkEstablishReq->isBufsta = pTdlsLinkEstablishReq->isBufSta; + pMsgTdlsLinkEstablishReq->isOffChannelSupported = + pTdlsLinkEstablishReq->isOffChannelSupported; + + if ( 0 != pTdlsLinkEstablishReq->supportedChannelsLen) + { + tANI_U32 selfNumChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tANI_U8 selfSupportedChannels[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + selfSupportedChannels, &selfNumChans) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Valid channel list")); + } + + if (selfNumChans > WNI_CFG_VALID_CHANNEL_LIST_LEN) { + limLog(pMac, LOGE, + FL("Channel List more than Valid Channel list")); + selfNumChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + + if (pTdlsLinkEstablishReq->supportedChannelsLen + > SIR_MAC_MAX_SUPP_CHANNELS ) { + limLog(pMac, LOGE, + FL("Channel List is more than the supported Channel list")); + pTdlsLinkEstablishReq->supportedChannelsLen + = SIR_MAC_MAX_SUPP_CHANNELS; + } + + limTdlsGetIntersection(selfSupportedChannels, selfNumChans, + pTdlsLinkEstablishReq->supportedChannels, + pTdlsLinkEstablishReq->supportedChannelsLen, + pMsgTdlsLinkEstablishReq->validChannels, + &pMsgTdlsLinkEstablishReq->validChannelsLen); + } + vos_mem_copy(pMsgTdlsLinkEstablishReq->validOperClasses, + pTdlsLinkEstablishReq->supportedOperClasses, pTdlsLinkEstablishReq->supportedOperClassesLen); + pMsgTdlsLinkEstablishReq->validOperClassesLen = + pTdlsLinkEstablishReq->supportedOperClassesLen; + msg.type = WDA_SET_TDLS_LINK_ESTABLISH_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgTdlsLinkEstablishReq; + msg.bodyval = 0; + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("halPostMsgApi failed")); + goto lim_tdls_link_establish_error; + } + return eSIR_SUCCESS; +lim_tdls_link_establish_error: + limSendSmeTdlsLinkEstablishReqRsp(pMac, psessionEntry->smeSessionId, pTdlsLinkEstablishReq->peerMac, + NULL, eSIR_FAILURE) ; + + return eSIR_SUCCESS; +} + + +/* Delete all the TDLS peer connected before leaving the BSS */ +tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL ; + int i, aid; + + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));) + return eSIR_FAILURE; + } + + /* Check all the set bit in peerAIDBitmap and delete the peer (with that aid) entry + from the hash table and add the aid in free pool */ + for (i = 0; i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); i++) + { + for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) + { + if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) + { + pStaDs = dphGetHashEntry(pMac, (aid + i*(sizeof(tANI_U32) << 3)), &psessionEntry->dph.dphHashTable); + + if (NULL != pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("Deleting "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr));); + + limSendDeauthMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + pStaDs->staAddr, psessionEntry, FALSE); + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable); + } + limReleasePeerIdx(pMac, (aid + i*(sizeof(tANI_U32) << 3)), psessionEntry) ; + CLEAR_BIT(psessionEntry->peerAIDBitmap[i], aid); + } + } + } + limSendSmeTDLSDeleteAllPeerInd(pMac, psessionEntry); + + return eSIR_SUCCESS; +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.c new file mode 100644 index 0000000000000..d2340801fea55 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limPropExtsUtils.cc contains the utility functions + * to populate, parse proprietary extensions required to + * support ANI feature set. + * + * Author: Chandra Modumudi + * Date: 11/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "aniGlobal.h" +#include "wniCfgSta.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "utilsApi.h" +#include "cfgApi.h" +#include "limApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limTrace.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#define LIM_GET_NOISE_MAX_TRY 5 +/** + * limExtractApCapability() + * + *FUNCTION: + * This function is called to extract AP's HCF/WME/WSM capability + * from the IEs received from it in Beacon/Probe Response frames + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pIE Pointer to starting IE in Beacon/Probe Response + * @param ieLen Length of all IEs combined + * @param qosCap Bits are set according to capabilities + * @return 0 - If AP does not assert HCF capability & 1 - otherwise + */ +void +limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen, + tANI_U8 *qosCap, tANI_U16 *propCap, tANI_U8 *uapsd, + tPowerdBm *localConstraint, + tpPESession psessionEntry + ) +{ + tSirProbeRespBeacon *pBeaconStruct; +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPowerConstraints = 0; +#endif + tANI_U32 enableTxBF20MHz; + + pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pBeaconStruct ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limExtractApCapability") ); + return; + } + + vos_mem_set( (tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); + *qosCap = 0; + *propCap = 0; + *uapsd = 0; + PELOG3(limLog( pMac, LOG3, + FL("In limExtractApCapability: The IE's being received are:")); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );) + if (sirParseBeaconIE(pMac, pBeaconStruct, pIE, (tANI_U32)ieLen) == eSIR_SUCCESS) + { + if (pBeaconStruct->wmeInfoPresent || pBeaconStruct->wmeEdcaPresent) + LIM_BSS_CAPS_SET(WME, *qosCap); + if (LIM_BSS_CAPS_GET(WME, *qosCap) && pBeaconStruct->wsmCapablePresent) + LIM_BSS_CAPS_SET(WSM, *qosCap); + if (pBeaconStruct->propIEinfo.capabilityPresent) + *propCap = pBeaconStruct->propIEinfo.capability; + if (pBeaconStruct->HTCaps.present) + pMac->lim.htCapabilityPresentInBeacon = 1; + else + pMac->lim.htCapabilityPresentInBeacon = 0; + +#ifdef WLAN_FEATURE_11AC + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***beacon.VHTCaps.present*****=%d BSS_VHT_CAPABLE:%d", + pBeaconStruct->VHTCaps.present, + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***beacon.SU Beamformer Capable*****=%d",pBeaconStruct->VHTCaps.suBeamFormerCap); + + if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) && pBeaconStruct->VHTOperation.present) + { + psessionEntry->vhtCapabilityPresentInBeacon = 1; + psessionEntry->apCenterChan = pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + psessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth; + + if (pBeaconStruct->Vendor1IEPresent && + pBeaconStruct->Vendor2IEPresent && + pBeaconStruct->Vendor3IEPresent) + { + if (((pBeaconStruct->VHTCaps.txMCSMap & VHT_MCS_3x3_MASK) == + VHT_MCS_3x3_MASK) && + ((pBeaconStruct->VHTCaps.txMCSMap & VHT_MCS_2x2_MASK) != + VHT_MCS_2x2_MASK)) + { + psessionEntry->txBFIniFeatureEnabled = 0; + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, 0) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + } + } + } + if (!psessionEntry->htSupportedChannelWidthSet) { + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + &enableTxBF20MHz))) { + if (VOS_FALSE == enableTxBF20MHz) { + psessionEntry->txBFIniFeatureEnabled = 0; + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, 0) + != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + } + } + } + } + } + else + { + psessionEntry->vhtCapabilityPresentInBeacon = 0; + } +#endif + // Extract the UAPSD flag from WMM Parameter element + if (pBeaconStruct->wmeEdcaPresent) + *uapsd = pBeaconStruct->edcaParams.qosInfo.uapsd; +#if defined FEATURE_WLAN_ESE + /* If there is Power Constraint Element specifically, + * adapt to it. Hence there is else condition check + * for this if statement. + */ + if ( pBeaconStruct->eseTxPwr.present) + { + *localConstraint = pBeaconStruct->eseTxPwr.power_limit; + } + psessionEntry->is_ese_version_ie_present = + pBeaconStruct->is_ese_ver_ie_present; +#endif + if (pBeaconStruct->powerConstraintPresent) + { +#if defined WLAN_FEATURE_VOWIFI + *localConstraint -= pBeaconStruct->localPowerConstraint.localPowerConstraints; +#else + localPowerConstraints = (tANI_U32)pBeaconStruct->localPowerConstraint.localPowerConstraints; +#endif + } +#if !defined WLAN_FEATURE_VOWIFI + if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.")); + } +#endif + psessionEntry->countryInfoPresent = FALSE; + /* Initializing before first use */ + if (pBeaconStruct->countryInfoPresent) + psessionEntry->countryInfoPresent = TRUE; + } + vos_mem_free(pBeaconStruct); + return; +} /****** end limExtractApCapability() ******/ + +/** + * limGetHTCBState + * + *FUNCTION: + * This routing provides the translation of Airgo Enum to HT enum for determining + * secondary channel offset. + * Airgo Enum is required for backward compatibility purposes. + * + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return The corresponding HT enumeration + */ +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode) +{ + switch ( aniCBMode ) + { +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: +#endif + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: +#endif + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return PHY_SINGLE_CHANNEL_CENTERED; +#endif + default : + return PHY_SINGLE_CHANNEL_CENTERED; + } +} + + /* + * limGetStaPeerType + * + *FUNCTION: + * Based on a combination of the following - + * 1) tDphHashNode.aniPeer + * 2) tDphHashNode.propCapability + * this API determines if a given STA is an ANI peer or not + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the tpDphHashNode of the STA + * under consideration + * @return tStaRateMode + */ +tStaRateMode limGetStaPeerType( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tpPESession psessionEntry) +{ +tStaRateMode staPeerType = eSTA_11b; + // Determine the peer-STA type + if( pStaDs->aniPeer ) + { + if(PROP_CAPABILITY_GET( TAURUS, pStaDs->propCapability )) + staPeerType = eSTA_TAURUS; + else if( PROP_CAPABILITY_GET( TITAN, pStaDs->propCapability )) + staPeerType = eSTA_TITAN; + else + staPeerType = eSTA_POLARIS; + } +#ifdef WLAN_FEATURE_11AC + else if(pStaDs->mlmStaContext.vhtCapability) + staPeerType = eSTA_11ac; +#endif + else if(pStaDs->mlmStaContext.htCapability) + staPeerType = eSTA_11n; + else if(pStaDs->erpEnabled) + staPeerType = eSTA_11bg; + else if(psessionEntry->limRFBand == SIR_BAND_5_GHZ) + staPeerType = eSTA_11a; + return staPeerType; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.h new file mode 100644 index 0000000000000..612292d78ade8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limPropExtsUtils.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limPropExtsUtils.h contains the definitions + * used by all LIM modules to support proprietary features. + * Author: Chandra Modumudi + * Date: 12/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_PROP_EXTS_UTILS_H +#define __LIM_PROP_EXTS_UTILS_H + + +// Function templates +void limQuietBss(tpAniSirGlobal, tANI_U32); +void limCleanupMeasData(tpAniSirGlobal); +void limDeleteMeasTimers(tpAniSirGlobal); +void limStopMeasTimers(tpAniSirGlobal pMac); +void limCleanupMeasResources(tpAniSirGlobal); +void limRestorePreLearnState(tpAniSirGlobal); +void limCollectMeasurementData(tpAniSirGlobal, + tANI_U32 *, tpSchBeaconStruct); +void limCollectRSSI(tpAniSirGlobal); +void limDeleteCurrentBssWdsNode(tpAniSirGlobal); +tANI_U32 limComputeAvg(tpAniSirGlobal, tANI_U32, tANI_U32); + + +/// Function to extract AP's HCF capability from IE fields +void limExtractApCapability(tpAniSirGlobal, tANI_U8 *, tANI_U16, tANI_U8 *, tANI_U16 *, tANI_U8 *, tPowerdBm*, tpPESession); + +tStaRateMode limGetStaPeerType( tpAniSirGlobal, tpDphHashNode ,tpPESession); +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode) ; +#endif + + +#endif /* __LIM_PROP_EXTS_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limRoamingAlgo.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limRoamingAlgo.c new file mode 100644 index 0000000000000..045d5c544d70c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limRoamingAlgo.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limRoamingAlgo.cc contains the code for LIM + * algorithms. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfgSta.h" +#include "cfgApi.h" +#include "limTypes.h" +#include "limTimerUtils.h" +#include "limTrace.h" + + + +/** ---------------------------------------------------------------------- +\fn limSelectsBackgroundScanMode() +\brief This function is called by limIsBackgroundScanAllowed(). +\ Here LIM decides whether we shall enforce this background +\ scan or let HAL decide whether to proceed with the background +\ scan as HAL sees fits. LIM shall enforce background scan if: +\ 1) station is not in link established state +\ 2) station is in link established state, but there has been +\ max number of consecutive background scan failure. +\ +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------------------- */ +tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal pMac) +{ + tANI_U32 cfgVal; + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, &cfgVal) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE value")); + return eSIR_NORMAL_BACKGROUND_SCAN; + } + + if (cfgVal == 0) + return eSIR_NORMAL_BACKGROUND_SCAN; + + /* If the "number of consecutive background scan failure" + * exceeds the maximum allowed, then LIM shall trigger an + * aggressive background scan. + */ + if (pMac->lim.gLimNumOfConsecutiveBkgndScanFailure >= cfgVal) + { + pMac->lim.gLimNumOfForcedBkgndScan += 1; + limLog(pMac, LOGE, + FL("Had %d consec scan fail(when expect < %d). Trigger AGGRESSIVE bkgnd scan."), + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure, cfgVal); + return eSIR_AGGRESSIVE_BACKGROUND_SCAN; + } + + return eSIR_NORMAL_BACKGROUND_SCAN; +} + + +/** ----------------------------------------------------------- +\fn limIsBackgroundScanAllowed +\brief This function determines if background scan should be +\ allowed. It is called by limTriggerBackgroundScan(). +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------- */ +static tANI_U8 limIsBackgroundScanAllowed(tpAniSirGlobal pMac) +{ + // if we are in the middle of a scan already, skip the background scan + if (limIsSystemInScanState(pMac) || + (pMac->lim.gLimBackgroundScanDisable) || + (pMac->lim.gLimForceBackgroundScanDisable) || + (pMac->lim.gLimBackgroundScanTerminate)) + return false; + + //need to do background scan in IBSS mode. + if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE) + return false; + return true; + } + + // If station is not in link established state, then skip background scan + if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) && (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) ) + return false; + + /* now that we have checked for scan state, check for other transitional + * states which should not be interrupted by scans + */ + if ((! (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ) && + (! (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE) ) && + (! (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE) ) ) + return false; + + return true; +} + + +/** --------------------------------------------------------------- +\fn limTriggerBackgroundScan() +\brief This function is called upon background scan interval +\ when there is an exisiting link with an AP. +\ SME_SCAN_REQ is issued to SME state machine with Active +\ scanning is performed on one channel at a time. +\ +\ Assumptions: +\ Valid channel list at CFG is either populated by Roaming +\ algorithm upon determining/selecting a regulatory domain +\ or by default has all 36 possible channels. +\ +\param tpAniSirGlobal pMac +\return none +\ ----------------------------------------------------------------- */ +void limTriggerBackgroundScan(tpAniSirGlobal pMac) +{ + tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN; + tANI_U32 ssidLen = SIR_MAC_MAX_SSID_LENGTH; + tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + tSirSmeScanReq smeScanReq; + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tSirBackgroundScanMode backgroundScan; + + PELOG1(limLog(pMac, LOG1, FL("Background Scan: %d success, %d consec fail "), + pMac->lim.gLimNumOfBackgroundScanSuccess, pMac->lim.gLimNumOfConsecutiveBkgndScanFailure);) + + if (! limIsBackgroundScanAllowed(pMac)) + { + PELOG1(limLog(pMac, LOG1, FL("Skipping Background Scan "));) + return; + } + + // Get background scan channel list from CFG + if (wlan_cfgGetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, + (tANI_U8 *) bgScanChannelList, + (tANI_U32 *) &len) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));) + + return; + } + + // Time to perform background scan. Prepare and issue + // SME_SCAN_REQ to SME State machine + smeScanReq.messageType = eWNI_SME_SCAN_REQ; + smeScanReq.length = sizeof(tSirSmeScanReq); + smeScanReq.bssType = eSIR_INFRASTRUCTURE_MODE; + vos_mem_copy( (tANI_U8 *) smeScanReq.bssId, + (tANI_U8 *) &bcAddr, sizeof(tSirMacAddr)); + + if (wlan_cfgGetStr(pMac, WNI_CFG_SSID, + (tANI_U8 *) (smeScanReq.ssId[0].ssId), + (tANI_U32 *) &ssidLen) != eSIR_SUCCESS) + { + /// Could not get SSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve SSID")); + } + smeScanReq.ssId[0].length = (tANI_U8) ssidLen; + smeScanReq.numSsid = 1; + + smeScanReq.scanType = eSIR_ACTIVE_SCAN; + smeScanReq.sessionId = 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + &smeScanReq.minChannelTime) != eSIR_SUCCESS) + { + /// Could not get minChlTime value from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve minChlTime value"));) + + return; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + &smeScanReq.maxChannelTime) != eSIR_SUCCESS) + { + /// Could not get maxChlTime value from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve maxChlTime value"));) + + return; + } + + smeScanReq.returnAfterFirstMatch = 0; + smeScanReq.returnUniqueResults = 1; + + //At the first channel scan, clear the cached results + if(pMac->lim.gLimBackgroundScanChannelId == 0) + { + /* + * Do not purge while starting a scan. Rome firmware sends results + * of roaming scan into this cache. + */ + smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS; + } + else + { + smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS; + } + + + smeScanReq.channelList.numChannels = 1; + if (pMac->lim.gLimBackgroundScanChannelId >= len) + { + pMac->lim.gLimBackgroundScanChannelId = 0; + + PELOGE(limLog(pMac, LOGE, FL("Skipping Background Scan since the channel list is exhausted."));) + PELOGE(limLog(pMac, LOGE, FL("SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication to start the background scan again."));) + + /* Stop the BG scan timer here. SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD + * indication to start the background scan again. + */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer) + != TX_SUCCESS) + { + // Could not deactivate BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate BackgroundScanTimer timer")); + } + } + + pMac->lim.gLimBackgroundScanTerminate = TRUE; + + PELOGE(limLog(pMac, LOGE, FL("Send dummy scan with returnFreshResults as 0 to report BG scan results to SME."));) + return; + } + smeScanReq.channelList.channelNumber[0] = + bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId++]; + + smeScanReq.uIEFieldLen = 0; + smeScanReq.uIEFieldOffset = sizeof(tSirSmeScanReq); + + backgroundScan = limSelectsBackgroundScanMode(pMac); + PELOG1(limLog(pMac, LOG1, FL("Performing (mode %d) Background Scan "), backgroundScan);) + smeScanReq.backgroundScanMode = backgroundScan; + + //determine whether to send the results or not, If so, notify the BG scan results to SME + if (pMac->lim.gLimBackgroundScanChannelId >= len) + { + pMac->lim.gLimReportBackgroundScanResults = TRUE; + } + + limPostSmeMessage(pMac, + eWNI_SME_SCAN_REQ, + (tANI_U32 *) &smeScanReq); +} /*** limTriggerBackgroundScan() ***/ + + +/** ---------------------------------------------------------------------- +\fn limAbortBackgroundScan +\brief This function aborts background scan and send scan +\ response to SME. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------------------- */ +void limAbortBackgroundScan(tpAniSirGlobal pMac) +{ + tANI_U16 scanRspLen = 8; + + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + limLog(pMac, LOGE, FL("Abort Background Scan ")); + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + } + + pMac->lim.gLimBackgroundScanTerminate = TRUE; + pMac->lim.gLimBackgroundScanStarted = FALSE; + + if (pMac->lim.gLimSmeScanResultLength == 0) + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0); + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0); + } + } + + // reset background scan variables + pMac->lim.gLimBackgroundScanChannelId = 0; + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c new file mode 100644 index 0000000000000..e9d13f9cbc2b4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -0,0 +1,1385 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limScanResultUtils.cc contains the utility functions + * LIM uses for maintaining and accessing scan results on STA. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "limTypes.h" +#include "limUtils.h" +#include "limSerDesUtils.h" +#include "limApi.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#include "vos_utils.h" + +/** + * limDeactiveMinChannelTimerDuringScan() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to deactivate MIN channel + * timer if running. + * + * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return eSIR_SUCCESS in case of success + */ + +tANI_U32 +limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac) +{ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE)) + { + /** + * Beacon/Probe Response is received during active scanning. + * Deactivate MIN channel timer if running. + */ + + limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) + == TX_TIMER_ERROR) + { + /// Could not activate max channel timer. + // Log error + limLog(pMac,LOGP, FL("could not activate max channel timer")); + + limCompleteMlmScan(pMac, eSIR_SME_RESOURCES_UNAVAILABLE); + return TX_TIMER_ERROR; + } + } + return eSIR_SUCCESS; +} /*** end limDeactivateMinChannelTimerDuringScan() ***/ + + + +/** + * limCollectBssDescription() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * frame matches scan criteria, collect BSS description + * and add it to cached scan results. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBPR - Pointer to parsed Beacon/Probe Response structure + * @param pRxPacketInfo - Pointer to Received frame's BD + * ---------if defined WLAN_FEATURE_VOWIFI------ + * @param fScanning - flag to indicate if it is during scan. + * --------------------------------------------- + * + * @return None + */ +#if defined WLAN_FEATURE_VOWIFI +eHalStatus +limCollectBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pBssDescr, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo, + tANI_U8 fScanning) +#else +eHalStatus +limCollectBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pBssDescr, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo) +#endif +{ + tANI_U8 *pBody; + tANI_U32 ieLen = 0; + tpSirMacMgmtHdr pHdr; + tANI_U8 channelNum; + tANI_U8 rxChannel; + tANI_U8 rfBand = 0; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + if (SIR_MAC_B_PR_SSID_OFFSET > WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)) + { + VOS_ASSERT(WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >= SIR_MAC_B_PR_SSID_OFFSET); + return eHAL_STATUS_FAILURE; + } + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; + rxChannel = WDA_GET_RX_CH(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + + /** + * Drop all the beacons and probe response without P2P IE during P2P search + */ + if ((NULL != pMac->lim.gpLimMlmScanReq && pMac->lim.gpLimMlmScanReq->p2pSearch) || + (pMac->fScanOffload && pMac->lim.fOffloadScanPending && + (pMac->lim.fOffloadScanP2PSearch || + pMac->lim.fOffloadScanP2PListen))) + { + if (NULL == limGetP2pIEPtr(pMac, (pBody + SIR_MAC_B_PR_SSID_OFFSET), ieLen)) + { + limLog( pMac, LOG3, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHdr->bssId)); + return eHAL_STATUS_FAILURE; + } + } + + /** + * Length of BSS desription is without length of + * length itself and length of pointer + * that holds the next BSS description + */ + pBssDescr->length = (tANI_U16)( + sizeof(tSirBssDescription) - sizeof(tANI_U16) - + sizeof(tANI_U32) + ieLen); + + // Copy BSS Id + vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, + (tANI_U8 *) pHdr->bssId, + sizeof(tSirMacAddr)); + + // Copy Timestamp, Beacon Interval and Capability Info + pBssDescr->scanSysTimeMsec = vos_timer_get_system_time(); + + pBssDescr->timeStamp[0] = pBPR->timeStamp[0]; + pBssDescr->timeStamp[1] = pBPR->timeStamp[1]; + pBssDescr->beaconInterval = pBPR->beaconInterval; + pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); + + if(!pBssDescr->beaconInterval ) + { + limLog(pMac, LOGW, + FL("Beacon Interval is ZERO, making it to default 100 " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId)); + pBssDescr->beaconInterval= 100; + } + /* + * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut + * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz + * band, so not relying on the 'last Scanned Channel' stored in LIM. + * Instead use the value returned by RXP in BD. This the the same value which HAL programs into + * RXP before every channel switch. + * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from + * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen. + * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it + * is not present in the beacon, we go for the channel info present in RXP. + * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. + * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. + */ + pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR); + + if (pBssDescr->channelId == 0) + { + /* If the channel Id is not retrieved from Beacon, extract the channel from BD */ + /* Unmapped the channel.This We have to do since we have done mapping in the hal to + overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/ + if ((!rfBand) || IS_5G_BAND(rfBand)) + { + rxChannel = limUnmapChannel(rxChannel); + } + if (!rxChannel) + { + rxChannel = pMac->lim.gLimCurrentScanChannelId; + } + pBssDescr->channelId = rxChannel; + } + + pBssDescr->channelIdSelf = pBssDescr->channelId; + //set the network type in bss description + channelNum = pBssDescr->channelId; + pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); + + // Copy RSSI & SINR from BD + + PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** "); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 ); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );) + + pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo); + pBssDescr->rssi_raw = (tANI_S8)WDA_GET_RX_RSSI_RAW(pRxPacketInfo); + + //SINR no longer reported by HW + pBssDescr->sinr = 0; + limLog(pMac, LOG3, + FL(MAC_ADDRESS_STR " rssi: normalized = %d, absolute = %d"), + MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->rssi, pBssDescr->rssi_raw); + + pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + +#if defined WLAN_FEATURE_VOWIFI + if( fScanning ) + { + rrmGetStartTSF( pMac, pBssDescr->startTSF ); + pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo); + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + // MobilityDomain + pBssDescr->mdie[0] = 0; + pBssDescr->mdie[1] = 0; + pBssDescr->mdie[2] = 0; + pBssDescr->mdiePresent = FALSE; + // If mdie is present in the probe resp we + // fill it in the bss description + if( pBPR->mdiePresent) + { + pBssDescr->mdiePresent = TRUE; + pBssDescr->mdie[0] = pBPR->mdie[0]; + pBssDescr->mdie[1] = pBPR->mdie[1]; + pBssDescr->mdie[2] = pBPR->mdie[2]; + } +#endif + +#ifdef FEATURE_WLAN_ESE + pBssDescr->QBSSLoad_present = FALSE; + pBssDescr->QBSSLoad_avail = 0; + if( pBPR->QBSSLoad.present) + { + pBssDescr->QBSSLoad_present = TRUE; + pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail; + } +#endif + // Copy IE fields + vos_mem_copy((tANI_U8 *) &pBssDescr->ieFields, + pBody + SIR_MAC_B_PR_SSID_OFFSET, + ieLen); + + /*set channel number in beacon in case it is not present*/ + pBPR->channelNumber = pBssDescr->channelId; + + limLog( pMac, LOG3, + FL("Collected BSS Description for Channel(%1d), length(%u), IE Fields(%u)"), + pBssDescr->channelId, + pBssDescr->length, + ieLen ); + + return eHAL_STATUS_SUCCESS; +} /*** end limCollectBssDescription() ***/ + +/** + * limIsScanRequestedSSID() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * SSID is present in the list of requested SSIDs in scan + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param ssId - SSID Received in beacons/Probe responses that is compared against the + requeusted SSID in scan list + * --------------------------------------------- + * + * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise + */ + +tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId) +{ + tANI_U8 i = 0; + + for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++) + { + if ( eANI_BOOLEAN_TRUE == vos_mem_compare((tANI_U8 *) ssId, + (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i], + (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1))) + { + return eANI_BOOLEAN_TRUE; + } + } + return eANI_BOOLEAN_FALSE; +} + +/** + * limCheckAndAddBssDescription() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * frame matches scan criteria, collect BSS description + * and add it to cached scan results. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBPR - Pointer to parsed Beacon/Probe Response structure + * @param pRxPacketInfo - Pointer to Received frame's BD + * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon + * + * @return None + */ + +void +limCheckAndAddBssDescription(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo, + tANI_BOOLEAN fScanning, + tANI_U8 fProbeRsp) +{ + tLimScanResultNode *pBssDescr; + tANI_U32 frameLen, ieLen = 0; + tANI_U8 rxChannelInBeacon = 0; + eHalStatus status; + tANI_U8 dontUpdateAll = 0; + tANI_U8 rfBand = 0; + tANI_U8 rxChannelInBD = 0; + + tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_BOOLEAN fFound = FALSE; + tpSirMacDataHdr3a pHdr; + + pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo); + + //Checking if scanning for a particular BSSID + if ((fScanning) && (pMac->lim.gpLimMlmScanReq)) + { + fFound = vos_mem_compare(pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6); + if (!fFound) + { + if ((pMac->lim.gpLimMlmScanReq->p2pSearch) && + (vos_mem_compare(pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, + &pMac->lim.gpLimMlmScanReq->bssId, 6))) + { + fFound = eANI_BOOLEAN_TRUE; + } + } + } + + /** + * Compare SSID with the one sent in + * Probe Request frame, if any. + * If they don't match, ignore the + * Beacon frame. + * pMac->lim.gLimMlmScanReq->ssId.length == 0 + * indicates Broadcast SSID. + * When gLimReturnAfterFirstMatch is set, it means the scan has to match + * a SSID (if it is also set). Ignore the other BSS in that case. + */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) + { +#endif + if ((pMac->lim.gpLimMlmScanReq) && + (((fScanning) && + ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) && + (pMac->lim.gpLimMlmScanReq->numSsid) && + !limIsScanRequestedSSID(pMac, &pBPR->ssId)) || + (!fFound && (pMac->lim.gpLimMlmScanReq && + pMac->lim.gpLimMlmScanReq->bssId) && + !vos_mem_compare(bssid, + &pMac->lim.gpLimMlmScanReq->bssId, 6)))) + { + /** + * Received SSID does not match with + * the one we're scanning for. + * Ignore received Beacon frame + */ + + return; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + /* There is no point in caching & reporting the scan results for APs + * which are in the process of switching the channel. So, we are not + * caching the scan results for APs which are adverzing the channel-switch + * element in their beacons and probe responses. + */ + if(pBPR->channelSwitchPresent) + { + return; + } + + /* If beacon/probe resp DS param channel does not match with + * RX BD channel then don't save the results. It might be a beacon + * from another channel heard as noise on the current scanning channel + */ + + if ((pBPR->dsParamsPresent) || (pBPR->HTInfo.present)) + { + /* This means that we are in 2.4GHz mode or 5GHz 11n mode */ + rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR); + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo); + + if ((!rfBand) || IS_5G_BAND(rfBand)) + { + rxChannelInBD = limUnmapChannel(rxChannelInBD); + } + + if(rxChannelInBD != rxChannelInBeacon) + { + /* BCAST Frame, if CH do not match, Drop */ + if(WDA_IS_RX_BCAST(pRxPacketInfo)) + { + limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. " + "Channel in beacon" " %d"), + WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR)); + return; + } + /* Unit cast frame, Probe RSP, do not drop */ + else + { + dontUpdateAll = 1; + limLog(pMac, LOG3, FL("SSID %s, CH in ProbeRsp %d, CH in BD %d, miss-match, Do Not Drop"), + pBPR->ssId.ssId, + rxChannelInBeacon, + WDA_GET_RX_CH(pRxPacketInfo)); + WDA_GET_RX_CH(pRxPacketInfo) = rxChannelInBeacon; + } + } + } + + /** + * Allocate buffer to hold BSS description from + * received Beacon frame. + * Include size of fixed fields and IEs length + */ + + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET) + { + limLog(pMac, LOGP, + FL("RX packet has invalid length %d"), ieLen); + return; + } + + ieLen -= SIR_MAC_B_PR_SSID_OFFSET; + + frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); //Sizeof(tANI_U32) is for ieFields[1] + + pBssDescr = vos_mem_malloc(frameLen); + if ( NULL == pBssDescr ) + { + // Log error + limLog(pMac, LOGP, + FL("call for AllocateMemory failed for storing BSS description")); + + return; + } + + // In scan state, store scan result. +#if defined WLAN_FEATURE_VOWIFI + status = limCollectBssDescription(pMac, &pBssDescr->bssDescription, + pBPR, pRxPacketInfo, fScanning); + if (eHAL_STATUS_SUCCESS != status) + { + goto last; + } +#else + status = limCollectBssDescription(pMac, &pBssDescr->bssDescription, + pBPR, pRxPacketInfo); + if (eHAL_STATUS_SUCCESS != status) + { + goto last; + } +#endif + pBssDescr->bssDescription.fProbeRsp = fProbeRsp; + + pBssDescr->next = NULL; + + /** + * Depending on whether to store unique or all + * scan results, pass hash update/add parameter + * For LFR candidates just add them on it's own cache + */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + limLog(pMac, LOG2, FL(" pHdr->addr1:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr1)); + limLog(pMac, LOG2, FL(" pHdr->addr2:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr2)); + limLog(pMac, LOG2, FL(" pHdr->addr3:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr3)); + limLog( pMac, LOG2, FL("Save this entry in LFR cache")); + status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + } + else +#endif + //If it is not scanning, only save unique results + if (pMac->lim.gLimReturnUniqueResults || (!fScanning)) + { + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll); + } + else + { + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + } + + if(fScanning) + { + if ((pBssDescr->bssDescription.channelId <= 14) && + (pMac->lim.gLimReturnAfterFirstMatch & 0x40) && + pBPR->countryInfoPresent) + pMac->lim.gLim24Band11dScanDone = 1; + + if ((pBssDescr->bssDescription.channelId > 14) && + (pMac->lim.gLimReturnAfterFirstMatch & 0x80) && + pBPR->countryInfoPresent) + pMac->lim.gLim50Band11dScanDone = 1; + + if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) || + ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) || + ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) ) || + fFound ) + { + /** + * Stop scanning and return the BSS description(s) + * collected so far. + */ + limLog(pMac, + LOGW, + FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id"), + pMac->lim.gLim24Band11dScanDone, + pMac->lim.gLim50Band11dScanDone); + + //Need to disable the timers. If they fire, they will send END_SCAN + //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + } + }//(eANI_BOOLEAN_TRUE == fScanning) + +last: + if( eHAL_STATUS_SUCCESS != status ) + { + vos_mem_free( pBssDescr ); + } + return; +} /****** end limCheckAndAddBssDescription() ******/ + + + +/** + * limScanHashFunction() + * + *FUNCTION: + * This function is called during scan hash entry operations + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param bssId - Received BSSid + * + * @return Hash index + */ + +tANI_U8 +limScanHashFunction(tSirMacAddr bssId) +{ + tANI_U16 i, hash = 0; + + for (i = 0; i < sizeof(tSirMacAddr); i++) + hash += bssId[i]; + + return hash % LIM_MAX_NUM_OF_SCAN_RESULTS; +} /****** end limScanHashFunction() ******/ + + + +/** + * limInitHashTable() + * + *FUNCTION: + * This function is called upon receiving SME_START_REQ + * to initialize global cached scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitHashTable(tpAniSirGlobal pMac) +{ + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + pMac->lim.gLimCachedScanHashTable[i] = NULL; +} /****** end limInitHashTable() ******/ + + + +/** + * limLookupNaddHashEntry() + * + *FUNCTION: + * This function is called upon receiving a Beacon or + * Probe Response frame during scan phase to store + * received BSS description into scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBssDescr - Pointer to BSS description to be + * added to the scan result hash table. + * @param action - Indicates action to be performed + * when same BSS description is found. This is + * dependent on whether unique scan result to + * be stored or not. + * + * @return None + */ + +eHalStatus +limLookupNaddHashEntry(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr, tANI_U8 action, + tANI_U8 dontUpdateAll) +{ + tANI_U8 index, ssidLen = 0; + tANI_U8 found = false; + tLimScanResultNode *ptemp, *pprev; + tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; + int idx, len; + tANI_U8 *pbIe; + tANI_S8 rssi = 0; + + index = limScanHashFunction(pBssDescr->bssDescription.bssId); + ptemp = pMac->lim.gLimCachedScanHashTable[index]; + + //ieFields start with TLV of SSID IE + ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; + + for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) + { + //For infrastructure, check BSSID and SSID. For IBSS, check more + pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; + if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first + (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, + (tANI_U8 *) ptemp->bssDescription.bssId, + sizeof(tSirMacAddr))) && //matching BSSID + // matching band to update new channel info + (vos_chan_to_band(pBssDescr->bssDescription.channelId) == + vos_chan_to_band(ptemp->bssDescription.channelId)) && + vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), + (tANI_U8) (ssidLen + 1)) && + ((pSirCapTemp->ess) || //we are done for infrastructure + //For IBSS, nwType and channelId + (((pBssDescr->bssDescription.nwType == + ptemp->bssDescription.nwType) && + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId)))) + ) + { + if (ptemp->bssDescription.fProbeRsp && + !pBssDescr->bssDescription.fProbeRsp) + { + /* If the previously saved frame is probe response + * and the current frame is beacon, then no need + * to update the scan database. Probe response is + * going to have more proper information than beacon + * frame. So it is better to inform the probe + * response frame instead of beacon for proper + * information. */ + return eHAL_STATUS_FAILURE; + } + // Found the same BSS description + if (action == LIM_HASH_UPDATE) + { + if(dontUpdateAll) + { + rssi = ptemp->bssDescription.rssi; + } + + if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) + { + //We get a different, save the old frame WSC IE if it is there + idx = 0; + len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + + sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; + //Save WPS IE if it exists + pBssDescr->bssDescription.WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Found it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy(pBssDescr->bssDescription.WscIeProbeRsp, + pbIe, pbIe[1] + 2); + pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } + + + if(NULL != pMac->lim.gpLimMlmScanReq) + { + if((pMac->lim.gpLimMlmScanReq->numSsid)&& + ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) + &pBssDescr->bssDescription.ieFields + 1)))) + return eHAL_STATUS_FAILURE; + } + + // Delete this entry + if (ptemp == pMac->lim.gLimCachedScanHashTable[index]) + pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next; + else + pprev->next = ptemp->next; + + pMac->lim.gLimMlmScanResultLength -= + ptemp->bssDescription.length + sizeof(tANI_U16); + + vos_mem_free(ptemp); + } + found = true; + break; + } + } + + //for now, only rssi, we can add more if needed + if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) + { + pBssDescr->bssDescription.rssi = rssi; + } + + // Add this BSS description at same index + if (pprev == pMac->lim.gLimCachedScanHashTable[index]) + { + pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index]; + pMac->lim.gLimCachedScanHashTable[index] = pBssDescr; + } + else + { + pBssDescr->next = pprev->next; + pprev->next = pBssDescr; + } + pMac->lim.gLimMlmScanResultLength += + pBssDescr->bssDescription.length + sizeof(tANI_U16); + + PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id"), + pBssDescr->bssDescription.length, + pMac->lim.gLimMlmScanResultLength); + limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) + + // Send new BSS found indication to HDD if CFG option is set + if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr); + + // + // TODO: IF applicable, do we need to send: + // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF + // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP + // + return eHAL_STATUS_SUCCESS; +} + + + +/** + * limDeleteHashEntry() + * + *FUNCTION: + * This function is called upon to delete + * a BSS description from scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * Yet to find the utility of the function + * + * @param pBssDescr - Pointer to BSS description to be + * deleted from the scan result hash table. + * + * @return None + */ + +void limDeleteHashEntry(tLimScanResultNode *pBssDescr) +{ +} /****** end limDeleteHashEntry() ******/ + + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limInitLfrHashTable() + * + *FUNCTION: + * This function is called upon receiving SME_START_REQ + * to initialize global cached Lfr scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitLfrHashTable(tpAniSirGlobal pMac) +{ + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + pMac->lim.gLimCachedLfrScanHashTable[i] = NULL; +} /****** end limInitLfrHashTable() ******/ + + + +/** + * limLookupNaddLfrHashEntry() + * + *FUNCTION: + * This function is called upon receiving a Beacon or + * Probe Response frame during Lfr scan phase from FW to store + * received BSS description into Lfr scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBssDescr - Pointer to BSS description to be + * added to the Lfr scan result hash table. + * @param action - Indicates action to be performed + * when same BSS description is found. This is + * dependent on whether unique scan result to + * be stored or not. + * + * @return None + */ + +eHalStatus +limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr, tANI_U8 action, + tANI_U8 dontUpdateAll) +{ + tANI_U8 index, ssidLen = 0; + tLimScanResultNode *ptemp, *pprev; + tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; + int idx, len; + tANI_U8 *pbIe; + tANI_S8 rssi = 0; + + index = limScanHashFunction(pBssDescr->bssDescription.bssId); + ptemp = pMac->lim.gLimCachedLfrScanHashTable[index]; + + //ieFields start with TLV of SSID IE + ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; + + for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) + { + //For infrastructure, check BSSID and SSID. For IBSS, check more + pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; + if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first + (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, + (tANI_U8 *) ptemp->bssDescription.bssId, + sizeof(tSirMacAddr))) && //matching BSSID + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId) && + vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), + (tANI_U8) (ssidLen + 1)) && + ((pSirCapTemp->ess) || //we are done for infrastructure + //For IBSS, nwType and channelId + (((pBssDescr->bssDescription.nwType == + ptemp->bssDescription.nwType) && + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId)))) + ) + { + // Found the same BSS description + if (action == LIM_HASH_UPDATE) + { + if(dontUpdateAll) + { + rssi = ptemp->bssDescription.rssi; + } + + if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) + { + //We get a different, save the old frame WSC IE if it is there + idx = 0; + len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + + sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; + //Save WPS IE if it exists + pBssDescr->bssDescription.WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && + (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Found it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy( pBssDescr->bssDescription.WscIeProbeRsp, + pbIe, pbIe[1] + 2); + pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } + + + if(NULL != pMac->lim.gpLimMlmScanReq) + { + if((pMac->lim.gpLimMlmScanReq->numSsid)&& + ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) + &pBssDescr->bssDescription.ieFields + 1)))) + return eHAL_STATUS_FAILURE; + } + + // Delete this entry + if (ptemp == pMac->lim.gLimCachedLfrScanHashTable[index]) + pprev = pMac->lim.gLimCachedLfrScanHashTable[index] = ptemp->next; + else + pprev->next = ptemp->next; + + pMac->lim.gLimMlmLfrScanResultLength -= + ptemp->bssDescription.length + sizeof(tANI_U16); + + vos_mem_free(ptemp); + } + break; + } + } + + //for now, only rssi, we can add more if needed + if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) + { + pBssDescr->bssDescription.rssi = rssi; + } + + // Add this BSS description at same index + if (pprev == pMac->lim.gLimCachedLfrScanHashTable[index]) + { + pBssDescr->next = pMac->lim.gLimCachedLfrScanHashTable[index]; + pMac->lim.gLimCachedLfrScanHashTable[index] = pBssDescr; + } + else + { + pBssDescr->next = pprev->next; + pprev->next = pBssDescr; + } + pMac->lim.gLimMlmLfrScanResultLength += + pBssDescr->bssDescription.length + sizeof(tANI_U16); + + PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"), + pBssDescr->bssDescription.length, + pMac->lim.gLimMlmLfrScanResultLength); + limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) + + // + // TODO: IF applicable, do we need to send: + // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF + // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP + // + return eHAL_STATUS_SUCCESS; +} + + + +/** + * limDeleteLfrHashEntry() + * + *FUNCTION: + * This function is called upon to delete + * a BSS description from LFR scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * Yet to find the utility of the function + * + * @param pBssDescr - Pointer to BSS description to be + * deleted from the LFR scan result hash table. + * + * @return None + */ + +void limDeleteLfrHashEntry(tLimScanResultNode *pBssDescr) +{ +} /****** end limDeleteLfrHashEntry() ******/ + +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** + * limCopyScanResult() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() while + * sending SME_SCAN_RSP with scan result to HDD. + * + *LOGIC: + * This function traverses the scan list stored in scan hash table + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pDest - Destination pointer + * + * @return None + */ + +void +limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest) +{ + tLimScanResultNode *ptemp; + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + while(ptemp) + { + /// Copy entire BSS description including length + vos_mem_copy( pDest, + (tANI_U8 *) &ptemp->bssDescription, + ptemp->bssDescription.length + 2); + pDest += ptemp->bssDescription.length + 2; + ptemp = ptemp->next; + } + } + } +} /****** end limCopyScanResult() ******/ + + + +/** + * limDeleteCachedScanResults() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SCAN_REQ with fresh scan result flag set. + * + *LOGIC: + * This function traverses the scan list stored in scan hash table + * and deletes the entries if any + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeleteCachedScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode; + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + while (pNode) + { + pNextNode = pNode->next; + + // Delete the current node + vos_mem_free(pNode); + + pNode = pNextNode; + } + } + } + + pMac->lim.gLimSmeScanResultLength = 0; +} /****** end limDeleteCachedScanResults() ******/ + +/** + * limFlushp2pScanResults() + * + *FUNCTION: + * This function is called before scan to flush the + * the p2p scan entries from LIM + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limFlushp2pScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode, *pPrev, *pHead, *pTemp; + tANI_U16 i; + tANI_U8 *pSsidStr; + tSirMacSSid *pSsid; + + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + pPrev = pNode; + pHead = pNode; + while (pNode) + { + pSsid = (tSirMacSSid *)((tANI_U8 *)&pNode->bssDescription.ieFields + 1); + pSsidStr = pSsid->ssId; + if (vos_mem_compare(pSsidStr, "DIRECT-", 7)) + { + if (pNode == pHead) + { + pTemp = pNode; + pNode = pNode->next; + pMac->lim.gLimSmeScanResultLength -= + (pTemp->bssDescription.length + + sizeof(pTemp->bssDescription.length)); + pPrev = pNode; + pHead = pNode; + vos_mem_free(pTemp); + pMac->lim.gLimCachedScanHashTable[i]= pHead; + } + else + { + pNextNode = pNode->next; + pMac->lim.gLimSmeScanResultLength -= + (pNode->bssDescription.length + + sizeof(pNode->bssDescription.length)); + vos_mem_free(pNode); + pPrev->next = pNextNode; + pNode = pNextNode; + } + } + else + { + pPrev = pNode; + pNode = pNode->next; + } + } + } + } +} /****** end limFlushp2pScanResults() ******/ + +/** + * limReInitScanResults() + * + *FUNCTION: + * This function is called delete exisiting scan results + * and initialize the scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limReInitScanResults(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Re initialize scan hash table.")); + limDeleteCachedScanResults(pMac); + limInitHashTable(pMac); + + // !!LAC - need to clear out the global scan result length + // since the list was just purged from the hash table. + pMac->lim.gLimMlmScanResultLength = 0; + +} /****** end limReInitScanResults() ******/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limDeleteCachedLfrScanResults() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SCAN_REQ with flush scan result flag set for LFR. + * + *LOGIC: + * This function traverses the scan list stored in lfr scan hash + * table and deletes the entries if any + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeleteCachedLfrScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode; + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedLfrScanHashTable[i]) != NULL) + { + while (pNode) + { + pNextNode = pNode->next; + + // Delete the current node + vos_mem_free(pNode); + + pNode = pNextNode; + } + } + } + + pMac->lim.gLimSmeLfrScanResultLength = 0; +} /****** end limDeleteCachedLfrScanResults() ******/ + + + +/** + * limReInitLfrScanResults() + * + *FUNCTION: + * This function is called delete exisiting scan results + * and initialize the lfr scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limReInitLfrScanResults(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Re initialize lfr scan hash table.")); + limDeleteCachedLfrScanResults(pMac); + limInitLfrHashTable(pMac); + + // !!LAC - need to clear out the global scan result length + // since the list was just purged from the hash table. + pMac->lim.gLimMlmLfrScanResultLength = 0; + +} /****** end limReInitLfrScanResults() ******/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h new file mode 100644 index 0000000000000..7f04c94a49fca --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limScanResultUtils.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limScanResultUtils.h contains the utility definitions + * LIM uses for maintaining and accessing scan results on STA. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SCAN_UTILS_H +#define __LIM_SCAN_UTILS_H + +#include "parserApi.h" +#include "limTypes.h" + +// Scan result hash related functions +tANI_U8 limScanHashFunction(tSirMacAddr); +void limInitHashTable(tpAniSirGlobal); +eHalStatus + limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); +void limDeleteHashEntry(tLimScanResultNode *); +void limFlushp2pScanResults(tpAniSirGlobal); +void limDeleteCachedScanResults(tpAniSirGlobal); +void limRestorePreScanState(tpAniSirGlobal); +void limCopyScanResult(tpAniSirGlobal, tANI_U8 *); +void limReInitScanResults(tpAniSirGlobal); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limInitLfrHashTable(tpAniSirGlobal); +eHalStatus + limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); +void limDeleteLfrHashEntry(tLimScanResultNode *); +void limDeleteCachedLfrScanResults(tpAniSirGlobal); +void limReInitLfrScanResults(tpAniSirGlobal); +#endif +tANI_U32 limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal); +void limCheckAndAddBssDescription(tpAniSirGlobal, tpSirProbeRespBeacon, tANI_U8 *, tANI_BOOLEAN, tANI_U8); +#if defined WLAN_FEATURE_VOWIFI +eHalStatus limCollectBssDescription(tpAniSirGlobal, + tSirBssDescription *, + tpSirProbeRespBeacon, + tANI_U8 *, + tANI_U8); +#else +eHalStatus limCollectBssDescription(tpAniSirGlobal, + tSirBssDescription *, + tpSirProbeRespBeacon, + tANI_U8 *); +#endif + +#endif /* __LIM_SCAN_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c new file mode 100644 index 0000000000000..8f8c10f781141 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c @@ -0,0 +1,1292 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limUtils.cc contains the utility functions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniGlobal.h" +#include "wniApi.h" + +#include "sirCommon.h" +#include "wniCfgSta.h" +#include "cfgApi.h" + + +#include "utilsApi.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" + + +#define LIM_SEED_LENGTH 16 + +/** + * limIsAuthAlgoSupported() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed authentication algorithm is enabled + * or not + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param authType Indicates MAC based authentication type + * (eSIR_OPEN_SYSTEM or eSIR_SHARED_KEY) + * If Shared Key authentication to be used, + * 'Privacy Option Implemented' flag is also + * checked. + * + * @return true if passed authType is enabled else false + */ +tANI_U8 +limIsAuthAlgoSupported(tpAniSirGlobal pMac, tAniAuthType authType, tpPESession psessionEntry) +{ + tANI_U32 algoEnable, privacyOptImp; + + if (authType == eSIR_OPEN_SYSTEM) + { + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if((psessionEntry->authType == eSIR_OPEN_SYSTEM) || (psessionEntry->authType == eSIR_AUTO_SWITCH)) + return true; + else + return false; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE, + &algoEnable) != eSIR_SUCCESS) + { + /** + * Could not get AuthAlgo1 Enable value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve AuthAlgo1 Enable value")); + + return false; + } + else + return ( (algoEnable > 0 ? true : false) ); + } + else + { + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if((psessionEntry->authType == eSIR_SHARED_KEY) || (psessionEntry->authType == eSIR_AUTO_SWITCH)) + algoEnable = true; + else + algoEnable = false; + + } + else + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHARED_KEY_AUTH_ENABLE, + &algoEnable) != eSIR_SUCCESS) + { + /** + * Could not get AuthAlgo2 Enable value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve AuthAlgo2 Enable value")); + + return false; + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + privacyOptImp = psessionEntry->privacy; + } + else + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacyOptImp) != eSIR_SUCCESS) + { + /** + * Could not get PrivacyOptionImplemented value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve PrivacyOptImplemented value")); + + return false; + } + return (algoEnable && privacyOptImp); + } +} /****** end limIsAuthAlgoSupported() ******/ + + + +/** + * limInitPreAuthList + * + *FUNCTION: + * This function is called while starting a BSS at AP + * to initialize MAC authenticated STA list. This may also be called + * while joining/starting an IBSS if MAC authentication is allowed + * in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitPreAuthList(tpAniSirGlobal pMac) +{ + pMac->lim.pLimPreAuthList = NULL; + +} /*** end limInitPreAuthList() ***/ + + + +/** + * limDeletePreAuthList + * + *FUNCTION: + * This function is called cleanup Pre-auth list either on + * AP or on STA when moving from one persona to other. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeletePreAuthList(tpAniSirGlobal pMac) +{ + struct tLimPreAuthNode *pCurrNode, *pTempNode; + + pCurrNode = pTempNode = pMac->lim.pLimPreAuthList; + while (pCurrNode != NULL) + { + pTempNode = pCurrNode->next; + + PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthList "));) + limReleasePreAuthNode(pMac, pCurrNode); + + pCurrNode = pTempNode; + } + pMac->lim.pLimPreAuthList = NULL; +} /*** end limDeletePreAuthList() ***/ + + + +/** + * limSearchPreAuthList + * + *FUNCTION: + * This function is called when Authentication frame is received + * by AP (or at a STA in IBSS supporting MAC based authentication) + * to search if a STA is in the middle of MAC Authentication + * transaction sequence. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param macAddr - MAC address of the STA that sent + * Authentication frame. + * + * @return Pointer to pre-auth node if found, else NULL + */ + +struct tLimPreAuthNode * +limSearchPreAuthList(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + struct tLimPreAuthNode *pTempNode = pMac->lim.pLimPreAuthList; + + while (pTempNode != NULL) + { + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + break; + + pTempNode = pTempNode->next; + } + + return pTempNode; +} /*** end limSearchPreAuthList() ***/ + + + +/** + * limAddPreAuthNode + * + *FUNCTION: + * This function is called at AP while sending Authentication + * frame2. + * This may also be called on a STA in IBSS if MAC authentication is + * allowed in IBSS mode. + * + *LOGIC: + * Node is always added to the front of the list + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAuthNode - Pointer to pre-auth node to be added to the list. + * + * @return None + */ + +void +limAddPreAuthNode(tpAniSirGlobal pMac, struct tLimPreAuthNode *pAuthNode) +{ + pMac->lim.gLimNumPreAuthContexts++; + + pAuthNode->next = pMac->lim.pLimPreAuthList; + + pMac->lim.pLimPreAuthList = pAuthNode; +} /*** end limAddPreAuthNode() ***/ + + +/** + * limReleasePreAuthNode + * + *FUNCTION: + * This function is called to realease the accquired + * pre auth node from list. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAuthNode - Pointer to Pre Auth node to be released + * @return None + */ + +void +limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode) +{ + pAuthNode->fFree = 1; + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_PRE_AUTH_CLEANUP_TIMER)); + tx_timer_deactivate(&pAuthNode->timer); + pMac->lim.gLimNumPreAuthContexts--; +} /*** end limReleasePreAuthNode() ***/ + + +/** + * limDeletePreAuthNode + * + *FUNCTION: + * This function is called at AP when a pre-authenticated STA is + * Associated/Reassociated or when AuthFrame4 is received after + * Auth Response timeout. + * This may also be called on a STA in IBSS if MAC authentication and + * Association/Reassociation is allowed in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param peerMacAddr - MAC address of the STA that need to be deleted + * from pre-auth node list. + * + * @return None + */ + +void +limDeletePreAuthNode(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + struct tLimPreAuthNode *pPrevNode, *pTempNode; + + pTempNode = pPrevNode = pMac->lim.pLimPreAuthList; + + if (pTempNode == NULL) + return; + + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + // First node to be deleted + + pMac->lim.pLimPreAuthList = pTempNode->next; + + + PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthNode : first node to delete"));) + PELOG1(limLog(pMac, LOG1, FL("Release data entry: %x id %d peer "), + pTempNode, pTempNode->authNodeIdx); + limPrintMacAddr(pMac, macAddr, LOG1);) + limReleasePreAuthNode(pMac, pTempNode); + + return; + } + + pTempNode = pTempNode->next; + + while (pTempNode != NULL) + { + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + // Found node to be deleted + + pPrevNode->next = pTempNode->next; + + PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthNode : subsequent node to delete")); + limLog(pMac, LOG1, FL("Release data entry: %x id %d peer "), + pTempNode, pTempNode->authNodeIdx); + limPrintMacAddr(pMac, macAddr, LOG1);) + limReleasePreAuthNode(pMac, pTempNode); + + return; + } + + pPrevNode = pTempNode; + pTempNode = pTempNode->next; + } + + // Should not be here + // Log error + limLog(pMac, LOGP, FL("peer not found in pre-auth list, addr= ")); + limPrintMacAddr(pMac, macAddr, LOGP); + +} /*** end limDeletePreAuthNode() ***/ + + + + + +/** + * limRestoreFromPreAuthState + * + *FUNCTION: + * This function is called on STA whenever an Authentication + * sequence is complete and state prior to auth need to be + * restored. + * + *LOGIC: + * MLM_AUTH_CNF is prepared and sent to SME state machine. + * In case of restoring from pre-auth: + * - Channel Id is programmed at LO/RF synthesizer + * - BSSID is programmed at RHP + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param resultCode - result of authentication attempt + * @return None + */ + +void +limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode,tpPESession sessionEntry) +{ + tSirMacAddr currentBssId; + tLimMlmAuthCnf mlmAuthCnf; + + vos_mem_copy( (tANI_U8 *) &mlmAuthCnf.peerMacAddr, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType; + mlmAuthCnf.resultCode = resultCode; + mlmAuthCnf.protStatusCode = protStatusCode; + + /* Update PE session ID*/ + mlmAuthCnf.sessionId = sessionEntry->peSessionId; + + /// Free up buffer allocated + /// for pMac->lim.gLimMlmAuthReq + vos_mem_free(pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + + sessionEntry->limMlmState = sessionEntry->limPrevMlmState; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER); + + sirCopyMacAddr(currentBssId,sessionEntry->bssId); + + if (sessionEntry->limSmeState == eLIM_SME_WT_PRE_AUTH_STATE) + { + pMac->lim.gLimPreAuthChannelNumber = 0; + } + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_CNF, + (tANI_U32 *) &mlmAuthCnf); +} /*** end limRestoreFromAuthState() ***/ + + + +/** + * limLookUpKeyMappings() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to determine if there exists a Key Mapping key for a given + * MAC address. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr MAC address of the peer STA for which existence + * of Key Mapping key is to be determined + * + * @return pKeyMapEntry - Pointer to the keyMapEntry returned by CFG + */ + +tCfgWepKeyEntry * +limLookUpKeyMappings(tSirMacAddr macAddr) +{ + return NULL; +} /****** end limLookUpKeyMappings() ******/ + + + +/** + * limEncryptAuthFrame() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to encrypt Authentication frame3 body. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param keyId key id to used + * @param pKey Pointer to the key to be used for encryption + * @param pPlainText Pointer to the body to be encrypted + * @param pEncrBody Pointer to the encrypted auth frame body + * @param keyLength 8 (WEP40) or 16 (WEP104) + * @return None + */ + +void +limEncryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 keyId, tANI_U8 *pKey, tANI_U8 *pPlainText, + tANI_U8 *pEncrBody, tANI_U32 keyLength) +{ + tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH]; + + keyLength += 3; + + // Bytes 0-2 of seed is IV + // Read TSF timestamp into seed to get random IV - 1st 3 bytes + halGetTxTSFtimer(pMac, (tSirMacTimeStamp *) &seed); + + // Bytes 3-7 of seed is key + vos_mem_copy((tANI_U8 *) &seed[3], pKey, keyLength - 3); + + // Compute CRC-32 and place them in last 4 bytes of plain text + limComputeCrc32(icv, pPlainText, sizeof(tSirMacAuthFrameBody)); + + vos_mem_copy( pPlainText + sizeof(tSirMacAuthFrameBody), + icv, SIR_MAC_WEP_ICV_LENGTH); + + // Run RC4 on plain text with the seed + limRC4(pEncrBody + SIR_MAC_WEP_IV_LENGTH, + (tANI_U8 *) pPlainText, seed, keyLength, + LIM_ENCR_AUTH_BODY_LEN - SIR_MAC_WEP_IV_LENGTH); + + // Prepare IV + pEncrBody[0] = seed[0]; + pEncrBody[1] = seed[1]; + pEncrBody[2] = seed[2]; + pEncrBody[3] = keyId << 6; +} /****** end limEncryptAuthFrame() ******/ + + + +/** + * limComputeCrc32() + * + *FUNCTION: + * This function is called to compute CRC-32 on a given source. + * Used while encrypting/decrypting Authentication frame 3. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDest Destination location for computed CRC + * @param pSrc Source location to be CRC computed + * @param len Length over which CRC to be computed + * @return None + */ + +void +limComputeCrc32(tANI_U8 *pDest, tANI_U8 * pSrc, tANI_U8 len) +{ + tANI_U32 crc; + int i; + + crc = 0; + crc = ~crc; + + while(len-- > 0) + crc = limCrcUpdate(crc, *pSrc++); + + crc = ~crc; + + for (i=0; i < SIR_MAC_WEP_IV_LENGTH; i++) + { + pDest[i] = (tANI_U8)crc; + crc >>= 8; + } +} /****** end limComputeCrc32() ******/ + + + +/** + * limRC4() + * + *FUNCTION: + * This function is called to run RC4 algorithm. Called while + * encrypting/decrypting Authentication frame 3. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDest Destination location for encrypted text + * @param pSrc Source location to be encrypted + * @param seed Contains seed (IV + key) for PRNG + * @param keyLength 8 (WEP40) or 16 (WEP104) + * @param frameLen Length of the frame + * + * @return None + */ + +void +limRC4(tANI_U8 *pDest, tANI_U8 *pSrc, tANI_U8 *seed, tANI_U32 keyLength, tANI_U16 frameLen) +{ + typedef struct + { + tANI_U8 i, j; + tANI_U8 sbox[256]; + } tRC4Context; + + tRC4Context ctx; + + { + tANI_U16 i, j, k; + + // + // Initialize sbox using seed + // + + ctx.i = ctx.j = 0; + for (i=0; i<256; i++) + ctx.sbox[i] = (tANI_U8)i; + + j = 0; + k = 0; + for (i=0; i<256; i++) + { + tANI_U8 temp; + if ( k < LIM_SEED_LENGTH ) + j = (tANI_U8)(j + ctx.sbox[i] + seed[k]); + temp = ctx.sbox[i]; + ctx.sbox[i] = ctx.sbox[j]; + ctx.sbox[j] = temp; + + if (++k >= keyLength) + k = 0; + } + } + + { + tANI_U8 i = ctx.i; + tANI_U8 j = ctx.j; + tANI_U8 len = (tANI_U8) frameLen; + + while (len-- > 0) + { + tANI_U8 temp1, temp2; + + i = (tANI_U8)(i+1); + temp1 = ctx.sbox[i]; + j = (tANI_U8)(j + temp1); + + ctx.sbox[i] = temp2 = ctx.sbox[j]; + ctx.sbox[j] = temp1; + + temp1 = (tANI_U8)(temp1 + temp2); + temp1 = ctx.sbox[temp1]; + temp2 = (tANI_U8)(pSrc ? *pSrc++ : 0); + + *pDest++ = (tANI_U8)(temp1 ^ temp2); + } + + ctx.i = i; + ctx.j = j; + } +} /****** end limRC4() ******/ + + + +/** + * limDecryptAuthFrame() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to decrypt received Authentication frame3 body. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pKey Pointer to the key to be used for decryption + * @param pEncrBody Pointer to the body to be decrypted + * @param pPlainBody Pointer to the decrypted body + * @param keyLength 8 (WEP40) or 16 (WEP104) + * + * @return Decrypt result - eSIR_SUCCESS for success and + * LIM_DECRYPT_ICV_FAIL for ICV mismatch. + * If decryption is a success, pBody will + * have decrypted auth frame body. + */ + +tANI_U8 +limDecryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pKey, tANI_U8 *pEncrBody, + tANI_U8 *pPlainBody, tANI_U32 keyLength, tANI_U16 frameLen) +{ + tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH]; + int i; + keyLength += 3; + + + // Bytes 0-2 of seed is received IV + vos_mem_copy((tANI_U8 *) seed, pEncrBody, SIR_MAC_WEP_IV_LENGTH - 1); + + // Bytes 3-7 of seed is key + vos_mem_copy((tANI_U8 *) &seed[3], pKey, keyLength - 3); + + // Run RC4 on encrypted text with the seed + limRC4(pPlainBody, + pEncrBody + SIR_MAC_WEP_IV_LENGTH, + seed, + keyLength, + frameLen); + + PELOG4(limLog(pMac, LOG4, FL("plainbody is ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pPlainBody, frameLen);) + + // Compute CRC-32 and place them in last 4 bytes of encrypted body + limComputeCrc32(icv, + (tANI_U8 *) pPlainBody, + (tANI_U8) (frameLen - SIR_MAC_WEP_ICV_LENGTH)); + + // Compare RX_ICV with computed ICV + for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++) + { + PELOG4(limLog(pMac, LOG4, FL(" computed ICV%d[%x], rxed ICV%d[%x]"), + i, icv[i], i, pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]);) + if (icv[i] != pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]) + return LIM_DECRYPT_ICV_FAIL; + } + + return eSIR_SUCCESS; +} /****** end limDecryptAuthFrame() ******/ + +/** + * limPostSmeSetKeysCnf + * + * A utility API to send MLM_SETKEYS_CNF to SME + */ +void limPostSmeSetKeysCnf( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tLimMlmSetKeysCnf *mlmSetKeysCnf) +{ + // Prepare and Send LIM_MLM_SETKEYS_CNF + vos_mem_copy( (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr, + (tANI_U8 *) pMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy( (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr, + (tANI_U8 *) pMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + /// Free up buffer allocated for mlmSetKeysReq + vos_mem_free( pMlmSetKeysReq ); + pMac->lim.gpLimMlmSetKeysReq = NULL; + + limPostSmeMessage( pMac, + LIM_MLM_SETKEYS_CNF, + (tANI_U32 *) mlmSetKeysCnf ); +} + +/** + * limPostSmeRemoveKeysCnf + * + * A utility API to send MLM_REMOVEKEY_CNF to SME + */ +void limPostSmeRemoveKeyCnf( tpAniSirGlobal pMac, + tpPESession psessionEntry, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tLimMlmRemoveKeyCnf *mlmRemoveKeyCnf) +{ + // Prepare and Send LIM_MLM_REMOVEKEYS_CNF + vos_mem_copy( (tANI_U8 *) &mlmRemoveKeyCnf->peerMacAddr, + (tANI_U8 *) pMlmRemoveKeyReq->peerMacAddr, + sizeof(tSirMacAddr)); + + /// Free up buffer allocated for mlmRemoveKeysReq + vos_mem_free( pMlmRemoveKeyReq ); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; //Restore the state. + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limPostSmeMessage( pMac, + LIM_MLM_REMOVEKEY_CNF, + (tANI_U32 *) mlmRemoveKeyCnf ); +} + +/** + * limSendSetBssKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmSetKeysReq(), + * when PE is trying to setup the Group Keys related + * to a specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer + * @return none + */ +void limSendSetBssKeyReq( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpSetBssKeyParams pSetBssKeyParams = NULL; +tLimMlmSetKeysCnf mlmSetKeysCnf; +tSirRetStatus retCode; +tANI_U32 val = 0; + + if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + limLog( pMac, LOG1, + FL( "numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS" ), pMlmSetKeysReq->numKeys); + + // Respond to SME with error code + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + // Package WDA_SET_BSSKEY_REQ message parameters + + pSetBssKeyParams = vos_mem_malloc(sizeof( tSetBssKeyParams )); + if ( NULL == pSetBssKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during SET_BSSKEY" )); + + // Respond to SME with error code + mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pSetBssKeyParams, + sizeof( tSetBssKeyParams ), 0); + + // Update the WDA_SET_BSSKEY_REQ parameters + pSetBssKeyParams->bssIdx = psessionEntry->bssIdx; + pSetBssKeyParams->encType = pMlmSetKeysReq->edType; + + + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pSetBssKeyParams->singleTidRc = (tANI_U8)val; + + /* Update PE session Id*/ + pSetBssKeyParams->sessionId = psessionEntry ->peSessionId; + + pSetBssKeyParams->smesessionId = pMlmSetKeysReq->smesessionId; + + if(pMlmSetKeysReq->key[0].keyId && + ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || + (pMlmSetKeysReq->edType == eSIR_ED_WEP104)) + ) + { + /* IF the key id is non-zero and encryption type is WEP, Send all the 4 + * keys to HAL with filling the key at right index in pSetBssKeyParams->key. */ + pSetBssKeyParams->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + vos_mem_copy( (tANI_U8 *) &pSetBssKeyParams->key[pMlmSetKeysReq->key[0].keyId], + (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof(pMlmSetKeysReq->key[0])); + + } + else + { + pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys; + vos_mem_copy( (tANI_U8 *) &pSetBssKeyParams->key, + (tANI_U8 *) &pMlmSetKeysReq->key, + sizeof( tSirKeys ) * pMlmSetKeysReq->numKeys ); + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + msgQ.type = WDA_SET_BSSKEY_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pSetBssKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_SET_BSSKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, + FL("Posting SET_BSSKEY to HAL failed, reason=%X"), + retCode ); + + // Respond to SME with LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; // Continue after WDA_SET_BSSKEY_RSP... + +end: + limPostSmeSetKeysCnf( pMac, + pMlmSetKeysReq, + &mlmSetKeysCnf ); + +} + +/** + * @function : limSendSetStaKeyReq() + * + * @brief : This function is called from limProcessMlmSetKeysReq(), + * when PE is trying to setup the Unicast Keys related + * to a specified STA with specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer + * @param staIdx STA index for which the keys are being set + * @param defWEPIdx The default WEP key index [0..3] + * @return none + */ +void limSendSetStaKeyReq( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tANI_U16 staIdx, + tANI_U8 defWEPIdx, + tpPESession sessionEntry, + tANI_BOOLEAN sendRsp) +{ + tSirMsgQ msgQ; + tpSetStaKeyParams pSetStaKeyParams = NULL; + tLimMlmSetKeysCnf mlmSetKeysCnf; + tSirRetStatus retCode; + tANI_U32 val = 0; + + // Package WDA_SET_STAKEY_REQ message parameters + pSetStaKeyParams = vos_mem_malloc(sizeof( tSetStaKeyParams )); + if ( NULL == pSetStaKeyParams ) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during SET_BSSKEY" )); + return; + } + else + vos_mem_set( (void *) pSetStaKeyParams, sizeof( tSetStaKeyParams ), 0); + + // Update the WDA_SET_STAKEY_REQ parameters + pSetStaKeyParams->staIdx = staIdx; + pSetStaKeyParams->encType = pMlmSetKeysReq->edType; + + + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pSetStaKeyParams->singleTidRc = (tANI_U8)val; + + /* Update PE session ID*/ + pSetStaKeyParams->sessionId = sessionEntry->peSessionId; + + /** + * For WEP - defWEPIdx indicates the default WEP + * Key to be used for TX + * For all others, there's just one key that can + * be used and hence it is assumed that + * defWEPIdx = 0 (from the caller) + */ + + pSetStaKeyParams->defWEPIdx = defWEPIdx; + + pSetStaKeyParams->smesessionId = pMlmSetKeysReq->smesessionId; + vos_mem_copy(pSetStaKeyParams->peerMacAddr, + pMlmSetKeysReq->peerMacAddr, sizeof(tSirMacAddr)); + + if(sendRsp == eANI_BOOLEAN_TRUE) + { + /** Store the Previous MlmState*/ + sessionEntry->limPrevMlmState = sessionEntry->limMlmState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + } + + if(sessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && !pMlmSetKeysReq->key[0].unicast) { + if (sendRsp == eANI_BOOLEAN_TRUE) + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE; + msgQ.type = WDA_SET_STA_BCASTKEY_REQ; + }else { + if (sendRsp == eANI_BOOLEAN_TRUE) + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE; + msgQ.type = WDA_SET_STAKEY_REQ; + } + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + + /** + * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP + * the Key[0] contains the KEY, so just copy that alone, + * for the case of WEP_STATIC the hal gets the key from cfg + */ + switch( pMlmSetKeysReq->edType ) { + case eSIR_ED_WEP40: + case eSIR_ED_WEP104: + // FIXME! Is this OK? + if( 0 == pMlmSetKeysReq->numKeys ) { + tANI_U32 i; + + for(i=0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS ;i++) + { + vos_mem_copy( (tANI_U8 *) &pSetStaKeyParams->key[i], + (tANI_U8 *) &pMlmSetKeysReq->key[i], sizeof( tSirKeys )); + } + pSetStaKeyParams->wepType = eSIR_WEP_STATIC; + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + }else { + /*This case the keys are coming from upper layer so need to fill the + * key at the default wep key index and send to the HAL */ + if (defWEPIdx < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + vos_mem_copy((tANI_U8 *) &pSetStaKeyParams->key[defWEPIdx], + (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof( pMlmSetKeysReq->key[0] )); + pMlmSetKeysReq->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + } + else + { + limLog( pMac, LOGE, FL( "Wrong Key Index %d" ), defWEPIdx); + } + } + break; + case eSIR_ED_TKIP: + case eSIR_ED_CCMP: +#ifdef FEATURE_WLAN_WAPI + case eSIR_ED_WPI: +#endif + { + vos_mem_copy( (tANI_U8 *) &pSetStaKeyParams->key, + (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof( tSirKeys )); + } + break; + default: + break; + } + + pSetStaKeyParams->sendRsp = sendRsp; + + msgQ.reserved = 0; + msgQ.bodyptr = pSetStaKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "Sending WDA_SET_STAKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, sessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) { + limLog( pMac, LOGE, FL("Posting SET_STAKEY to HAL failed, reason=%X"), retCode ); + // Respond to SME with LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + }else + return; // Continue after WDA_SET_STAKEY_RSP... + + if(sendRsp == eANI_BOOLEAN_TRUE) + limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf ); +} + +/** + * limSendRemoveBssKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmRemoveReq(), + * when PE is trying to Remove a Group Key related + * to a specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmRemoveKeyReq Pointer to MLM_REMOVEKEY_REQ buffer + * @return none + */ +void limSendRemoveBssKeyReq( tpAniSirGlobal pMac, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpRemoveBssKeyParams pRemoveBssKeyParams = NULL; +tLimMlmRemoveKeyCnf mlmRemoveKeysCnf; +tSirRetStatus retCode; + + // Package WDA_REMOVE_BSSKEY_REQ message parameters + pRemoveBssKeyParams = vos_mem_malloc(sizeof( tRemoveBssKeyParams )); + if ( NULL == pRemoveBssKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during REMOVE_BSSKEY" )); + + // Respond to SME with error code + mlmRemoveKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pRemoveBssKeyParams, + sizeof( tRemoveBssKeyParams ), 0); + + // Update the WDA_REMOVE_BSSKEY_REQ parameters + pRemoveBssKeyParams->bssIdx = psessionEntry->bssIdx; + pRemoveBssKeyParams->encType = pMlmRemoveKeyReq->edType; + pRemoveBssKeyParams->keyId = pMlmRemoveKeyReq->keyId; + pRemoveBssKeyParams->wepType = pMlmRemoveKeyReq->wepType; + + /* Update PE session Id*/ + + pRemoveBssKeyParams->sessionId = psessionEntry->peSessionId; + + msgQ.type = WDA_REMOVE_BSSKEY_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pRemoveBssKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_REMOVE_BSSKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, + FL("Posting REMOVE_BSSKEY to HAL failed, reason=%X"), + retCode ); + + // Respond to SME with LIM_MLM_REMOVEKEYS_CNF + mlmRemoveKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; + +end: + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeysCnf ); + +} + +/** + * limSendRemoveStaKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmRemoveKeysReq(), + * when PE is trying to setup the Unicast Keys related + * to a specified STA with specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmRemoveKeysReq Pointer to MLM_REMOVEKEYS_REQ buffer + * @param staIdx STA index for which the keys are being set + * @return none + */ +void limSendRemoveStaKeyReq( tpAniSirGlobal pMac, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tANI_U16 staIdx, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpRemoveStaKeyParams pRemoveStaKeyParams = NULL; +tLimMlmRemoveKeyCnf mlmRemoveKeyCnf; +tSirRetStatus retCode; + + pRemoveStaKeyParams = vos_mem_malloc(sizeof( tRemoveStaKeyParams )); + if ( NULL == pRemoveStaKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during REMOVE_STAKEY" )); + + // Respond to SME with error code + mlmRemoveKeyCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pRemoveStaKeyParams, + sizeof( tRemoveStaKeyParams ), 0); + + if( (pMlmRemoveKeyReq->edType == eSIR_ED_WEP104 || pMlmRemoveKeyReq->edType == eSIR_ED_WEP40) && + pMlmRemoveKeyReq->wepType == eSIR_WEP_STATIC ) + { + PELOGE(limLog(pMac, LOGE, FL("Request to remove static WEP keys through station interface\n Should use BSS interface"));) + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + // Update the WDA_REMOVEKEY_REQ parameters + pRemoveStaKeyParams->staIdx = staIdx; + pRemoveStaKeyParams->encType = pMlmRemoveKeyReq->edType; + pRemoveStaKeyParams->keyId = pMlmRemoveKeyReq->keyId; + pRemoveStaKeyParams->unicast = pMlmRemoveKeyReq->unicast; + + /* Update PE session ID*/ + pRemoveStaKeyParams->sessionId = psessionEntry->peSessionId; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_REMOVE_STAKEY_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pRemoveStaKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_REMOVE_STAKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if (eSIR_SUCCESS != retCode) + { + limLog( pMac, LOGE, + FL("Posting REMOVE_STAKEY to HAL failed, reason=%X"), + retCode ); + vos_mem_free(pRemoveStaKeyParams); + pRemoveStaKeyParams = NULL; + + // Respond to SME with LIM_MLM_REMOVEKEY_CNF + mlmRemoveKeyCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; + +end: + if (pRemoveStaKeyParams) + { + vos_mem_free(pRemoveStaKeyParams); + } + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeyCnf ); + +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h new file mode 100644 index 0000000000000..51bf714268fc2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSecurityUtils.h contains the utility definitions + * related to WEP encryption/decryption etc. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SECURITY_UTILS_H +#define __LIM_SECURITY_UTILS_H +#include "sirMacProtDef.h" //for tSirMacAuthFrameBody + +#define LIM_ENCR_AUTH_BODY_LEN (sizeof(tSirMacAuthFrameBody) + \ + SIR_MAC_WEP_IV_LENGTH + \ + SIR_MAC_WEP_ICV_LENGTH) +struct tLimPreAuthNode; + +tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession); + +// MAC based authentication related functions +void limInitPreAuthList(tpAniSirGlobal); +void limDeletePreAuthList(tpAniSirGlobal); +struct tLimPreAuthNode *limSearchPreAuthList(tpAniSirGlobal, tSirMacAddr); +void limAddPreAuthNode(tpAniSirGlobal, struct tLimPreAuthNode *); +void limDeletePreAuthNode(tpAniSirGlobal, tSirMacAddr); +void limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode); +void limRestoreFromAuthState(tpAniSirGlobal, + tSirResultCodes, tANI_U16,tpPESession); + +// Encryption/Decryption related functions +tCfgWepKeyEntry *limLookUpKeyMappings(tSirMacAddr); +void limComputeCrc32(tANI_U8 *, tANI_U8 *, tANI_U8); +void limRC4(tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16); +void limEncryptAuthFrame(tpAniSirGlobal, tANI_U8, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32); +tANI_U8 limDecryptAuthFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16); + +void limSendSetBssKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *,tpPESession ); +void limSendSetStaKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *, tANI_U16, tANI_U8,tpPESession, tANI_BOOLEAN sendRsp); +void limPostSmeSetKeysCnf( tpAniSirGlobal, tLimMlmSetKeysReq *, tLimMlmSetKeysCnf * ); + +void limSendRemoveBssKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq,tpPESession); +void limSendRemoveStaKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tANI_U16 staIdx,tpPESession); +void limPostSmeRemoveKeyCnf(tpAniSirGlobal pMac, tpPESession psessionEntry, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tLimMlmRemoveKeyCnf * mlmRemoveKeyCnf); + +#define PTAPS 0xedb88320 + +static inline tANI_U32 +limCrcUpdate(tANI_U32 crc, tANI_U8 x) +{ + + // Update CRC computation for 8 bits contained in x + // + tANI_U32 z; + tANI_U32 fb; + int i; + + z = crc^x; + for (i=0; i<8; i++) { + fb = z & 1; + z >>= 1; + if (fb) z ^= PTAPS; + } + return z; +} + +#endif /* __LIM_SECURITY_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c new file mode 100644 index 0000000000000..641b334a4e484 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -0,0 +1,6594 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * \file limSendManagementFrames.c + * + * \brief Code for preparing and sending 802.11 Management frames + * + * + */ + +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "limPropExtsUtils.h" +#include "dot11f.h" +#include "limStaHashApi.h" +#include "schApi.h" +#include "limSendMessages.h" +#include "limAssocUtils.h" +#include "limFT.h" +#ifdef WLAN_FEATURE_11W +#include "wniCfgAp.h" +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_utils.h" +#include "sme_Trace.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#include "wlan_qct_wda.h" + + +//////////////////////////////////////////////////////////////////////// + + +tSirRetStatus limStripOffExtCapIE(tpAniSirGlobal pMac, + tANI_U8 *addIE, + tANI_U16 *addnIELen, + tANI_U8 *pExtractedExtCapIEBuf ) +{ + tANI_U8* tempbuf = NULL; + tANI_U16 tempLen = 0; + int left = *addnIELen; + tANI_U8 *ptr = addIE; + tANI_U8 elem_id, elem_len; + + if (NULL == addIE) + { + PELOGE(limLog(pMac, LOG1, FL("NULL addIE pointer"));) + return eSIR_IGNORE_IE ; + } + + tempbuf = vos_mem_malloc(left); + if ( NULL == tempbuf ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + return eSIR_MEM_ALLOC_FAILED; + } + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if (elem_len > left) + { + limLog( pMac, LOGE, + FL("Invalid IEs eid = %d elem_len=%d left=%d"), + elem_id,elem_len,left); + vos_mem_free(tempbuf); + return eSIR_FAILURE; + } + if ( !(DOT11F_EID_EXTCAP == elem_id) ) + { + vos_mem_copy (tempbuf + tempLen, &ptr[0], elem_len + 2); + tempLen += (elem_len + 2); + } + else + { /*Est Cap present size is 8 + 2 byte at present*/ + if ( NULL != pExtractedExtCapIEBuf ) + { + vos_mem_set(pExtractedExtCapIEBuf, + DOT11F_IE_EXTCAP_MAX_LEN + 2, 0); + if (elem_len <= DOT11F_IE_EXTCAP_MAX_LEN ) + { + vos_mem_copy (pExtractedExtCapIEBuf, &ptr[0], + elem_len + 2); + } + } + } + left -= elem_len; + ptr += (elem_len + 2); + } + vos_mem_copy (addIE, tempbuf, tempLen); + *addnIELen = tempLen; + vos_mem_free(tempbuf); + return eSIR_SUCCESS; +} + +void limUpdateExtCapIEtoStruct(tpAniSirGlobal pMac, + tANI_U8 *pBuf, + tDot11fIEExtCap *pDst) +{ + tANI_U8 pOut[DOT11F_IE_EXTCAP_MAX_LEN]; + + if ( NULL == pBuf ) + { + limLog( pMac, LOGE, + FL("Invalid Buffer Address")); + return; + } + if(NULL == pDst) + { + PELOGE(limLog(pMac, LOGE, + FL("NULL pDst pointer"));) + return ; + } + + if ( DOT11F_EID_EXTCAP != pBuf[0] || + pBuf[1] > DOT11F_IE_EXTCAP_MAX_LEN ) + { + limLog( pMac, LOG1, + FL("Invalid IEs eid = %d elem_len=%d "), + pBuf[0],pBuf[1]); + return; + } + vos_mem_set(( tANI_U8* )&pOut[0], DOT11F_IE_EXTCAP_MAX_LEN, 0); + vos_mem_copy(&pOut[0], &pBuf[2], DOT11F_IE_EXTCAP_MAX_LEN); + + if ( DOT11F_PARSE_SUCCESS != dot11fUnpackIeExtCap( pMac, + &pOut[0], DOT11F_IE_EXTCAP_MAX_LEN, pDst) ) + { + limLog( pMac, LOGE, + FL("dot11fUnpackIeExtCap Parse Error ")); + } +} + +tSirRetStatus limStripOffExtCapIEAndUpdateStruct(tpAniSirGlobal pMac, + tANI_U8* addIE, + tANI_U16 *addnIELen, + tDot11fIEExtCap * pDst ) +{ + tANI_U8 pExtractedExtCapIEBuf[DOT11F_IE_EXTCAP_MAX_LEN + 2]; + tSirRetStatus nSirStatus; + + vos_mem_set(( tANI_U8* )&pExtractedExtCapIEBuf[0], + DOT11F_IE_EXTCAP_MAX_LEN + 2, 0); + nSirStatus = limStripOffExtCapIE(pMac, addIE, addnIELen, + pExtractedExtCapIEBuf); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOG1, FL("Failed to strip off in" + "limStripOffExtCapIE status = (%d)."), + nSirStatus ); + return nSirStatus; + } + /* update the extracted ExtCap to struct*/ + limUpdateExtCapIEtoStruct(pMac, pExtractedExtCapIEBuf, pDst); + return nSirStatus; +} + +void limMergeExtCapIEStruct(tDot11fIEExtCap *pDst, + tDot11fIEExtCap *pSrc) +{ + tANI_U8 *tempDst = (tANI_U8 *)pDst->bytes; + tANI_U8 *tempSrc = (tANI_U8 *)pSrc->bytes; + tANI_U8 structlen = member_size(tDot11fIEExtCap, bytes); + + while(tempDst && tempSrc && structlen--) + { + *tempDst |= *tempSrc; + tempDst++; + tempSrc++; + } +} + +/** + * + * \brief This function is called to add the sequence number to the + * management frames + * + * \param pMac Pointer to Global MAC structure + * + * \param pMacHdr Pointer to MAC management header + * + * The pMacHdr argument points to the MAC management header. The + * sequence number stored in the pMac structure will be incremented + * and updated to the MAC management header. The start sequence + * number is WLAN_HOST_SEQ_NUM_MIN and the end value is + * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence + * number will roll over. + * + */ +void +limAddMgmtSeqNum (tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr) +{ + if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) { + pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN-1; + } + + pMac->mgmtSeqNum++; + + pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK); + pMacHdr->seqControl.seqNumHi = + ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET); +} + +/** + * + * \brief This function is called before sending a p2p action frame + * inorder to add sequence numbers to action packets + * + * \param pMac Pointer to Global MAC structure + * + * \param pBD Pointer to the frame buffer that needs to be populate + * + * The pMacHdr argument points to the MAC management header. The + * sequence number stored in the pMac structure will be incremented + * and updated to the MAC management header. The start sequence + * number is WLAN_HOST_SEQ_NUM_MIN and the end value is + * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence + * number will roll over. + * + */ +void +limPopulateP2pMacHeader(tpAniSirGlobal pMac, tANI_U8* pBD) +{ + tpSirMacMgmtHdr pMacHdr; + + /// Prepare MAC management header + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + /* Prepare sequence number */ + limAddMgmtSeqNum(pMac, pMacHdr); + limLog(pMac, LOG1,"seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d", + pMacHdr->seqControl.seqNumLo, + pMacHdr->seqControl.seqNumHi, + pMac->mgmtSeqNum); +} + +/** + * + * \brief This function is called by various LIM modules to prepare the + * 802.11 frame MAC header + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pBD Pointer to the frame buffer that needs to be populate + * + * \param type Type of the frame + * + * \param subType Subtype of the frame + * + * \return eHalStatus + * + * + * The pFrameBuf argument points to the beginning of the frame buffer to + * which - a) The 802.11 MAC header is set b) Following this MAC header + * will be the MGMT frame payload The payload itself is populated by the + * caller API + * + * + */ + +tSirRetStatus limPopulateMacHeader( tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /// Prepare MAC management header + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + // Prepare FC + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + // Prepare Address 1 + vos_mem_copy( (tANI_U8 *) pMacHdr->da, + (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + + // Prepare Address 2 + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + // Prepare Address 3 + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + + /* Prepare sequence number */ + limAddMgmtSeqNum(pMac, pMacHdr); + limLog(pMac, LOG1,"seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d", + pMacHdr->seqControl.seqNumLo, + pMacHdr->seqControl.seqNumHi, + pMac->mgmtSeqNum); + + return statusCode; +} /*** end limPopulateMacHeader() ***/ + +/** + * \brief limSendProbeReqMgmtFrame + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pSsid SSID to be sent in Probe Request frame + * + * \param bssid BSSID to be sent in Probe Request frame + * + * \param nProbeDelay probe delay to be used before sending Probe Request + * frame + * + * \param nChannelNum Channel # on which the Probe Request is going out + * + * \param nAdditionalIELen if non-zero, include pAdditionalIE in the Probe Request frame + * + * \param pAdditionalIE if nAdditionalIELen is non zero, include this field in the Probe Request frame + * + * This function is called by various LIM modules to send Probe Request frame + * during active scan/learn phase. + * Probe request is sent out in the following scenarios: + * --heartbeat failure: session needed + * --join req: session needed + * --foreground scan: no session + * --background scan: no session + * --schBeaconProcessing: to get EDCA parameters: session needed + * + * + */ +tSirRetStatus +limSendProbeReqMgmtFrame(tpAniSirGlobal pMac, + tSirMacSSid *pSsid, + tSirMacAddr bssid, + tANI_U8 nChannelNum, + tSirMacAddr SelfMacAddr, + tANI_U32 dot11mode, + tANI_U32 nAdditionalIELen, + tANI_U8 *pAdditionalIE) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U8 *p2pIe = NULL; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + +#ifndef GEN4_SCAN + return eSIR_FAILURE; +#endif + +#if defined ( ANI_DVT_DEBUG ) + return eSIR_FAILURE; +#endif + + /* The probe req should not send 11ac capabilieties if band is 2.4GHz, + * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz + * is false and dot11mode is 11ac set it to 11n. + */ + if ( nChannelNum <= SIR_11B_CHANNEL_END && + ( FALSE == pMac->roam.configParam.enableVhtFor24GHz ) && + ( WNI_CFG_DOT11_MODE_11AC == dot11mode || + WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode ) ) + dot11mode = WNI_CFG_DOT11_MODE_11N; + /* + * session context may or may not be present, when probe request needs to be sent out. + * following cases exist: + * --heartbeat failure: session needed + * --join req: session needed + * --foreground scan: no session + * --background scan: no session + * --schBeaconProcessing: to get EDCA parameters: session needed + * If session context does not exist, some IEs will be populated from CFGs, + * e.g. Supported and Extended rate set IEs + */ + psessionEntry = peFindSessionByBssid(pMac,bssid,&sessionId); + + if (psessionEntry != NULL ) + smeSessionId = psessionEntry->smeSessionId; + + // The scheme here is to fill out a 'tDot11fProbeRequest' structure + // and then hand it off to 'dot11fPackProbeRequest' (for + // serialization). We start by zero-initializing the structure: + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + // & delegating to assorted helpers: + PopulateDot11fSSID( pMac, pSsid, &pr.SSID ); + + if( nAdditionalIELen && pAdditionalIE ) + { + p2pIe = limGetP2pIEPtr(pMac, pAdditionalIE, nAdditionalIELen); + } + /* Don't include 11b rate only when device is doing P2P Search */ + if( ( WNI_CFG_DOT11_MODE_11B != dot11mode ) && + ( p2pIe != NULL ) && + /* Don't include 11b rate if it is a P2P serach or probe request is sent by P2P Client */ + ( ( ( pMac->lim.gpLimMlmScanReq != NULL ) && + pMac->lim.gpLimMlmScanReq->p2pSearch ) || + ( ( psessionEntry != NULL ) && + ( VOS_P2P_CLIENT_MODE == psessionEntry->pePersona ) ) + ) + ) + { + /* In the below API pass channel number > 14, do that it fills only + * 11a rates in supported rates */ + PopulateDot11fSuppRates( pMac, 15, &pr.SuppRates,psessionEntry); + } + else + { + PopulateDot11fSuppRates( pMac, nChannelNum, + &pr.SuppRates,psessionEntry); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + } + +#if defined WLAN_FEATURE_VOWIFI + //Table 7-14 in IEEE Std. 802.11k-2008 says + //DS params "can" be present in RRM is disabled and "is" present if + //RRM is enabled. It should be ok even if we add it into probe req when + //RRM is not enabled. + PopulateDot11fDSParams( pMac, &pr.DSParams, nChannelNum, psessionEntry ); + //Call RRM module to get the tx power for management used. + { + tANI_U8 txPower = (tANI_U8) rrmGetMgmtTxPower( pMac, psessionEntry ); + PopulateDot11fWFATPC( pMac, &pr.WFATPC, txPower, 0 ); + } +#endif + + if (psessionEntry != NULL ) { + psessionEntry->htCapability = IS_DOT11_MODE_HT(dot11mode); + //Include HT Capability IE + if (psessionEntry->htCapability) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pr.HTCaps ); + } + } else { //psessionEntry == NULL + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pr.HTCaps ); + } + } + + /* Set channelbonding information as "disabled" when tunned to a 2.4 GHz channel */ + if( nChannelNum <= SIR_11B_CHANNEL_END) + { + if (pMac->roam.configParam.channelBondingMode24GHz + == PHY_SINGLE_CHANNEL_CENTERED) { + pr.HTCaps.supportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + pr.HTCaps.shortGI40MHz = 0; + } else { + pr.HTCaps.supportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + } + +#ifdef WLAN_FEATURE_11AC + if (psessionEntry != NULL ) { + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(dot11mode); + //Include HT Capability IE + if (psessionEntry->vhtCapability) + { + PopulateDot11fVHTCaps( pMac, psessionEntry, &pr.VHTCaps ); + } + } else { + if (IS_DOT11_MODE_VHT(dot11mode)) + { + PopulateDot11fVHTCaps( pMac, psessionEntry, &pr.VHTCaps ); + } + } +#endif + + + // That's it-- now we pack it. First, how much space are we going to + // need? + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Probe Request (0x%08x)."), nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAdditionalIELen; + + // Ok-- try to allocate some memory: + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro" + "be Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssid, SelfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; // allocated! + } + + // That done, pack the Probe Request: + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Probe Request (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a P" + "robe Request (0x%08x)."), nStatus ); + } + + // Append any AddIE if present. + if( nAdditionalIELen ) + { + vos_mem_copy( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + pAdditionalIE, nAdditionalIELen ); + nPayload += nAdditionalIELen; + } + + /* If this probe request is sent during P2P Search State, then we need + * to send it at OFDM rate. + */ + if( ( SIR_BAND_5_GHZ == limGetRFBand(nChannelNum)) + || (( pMac->lim.gpLimMlmScanReq != NULL) && + pMac->lim.gpLimMlmScanReq->p2pSearch ) + /* For unicast probe req mgmt from Join function + we don't set above variables. So we need to add + one more check whether it is pePersona is P2P_CLIENT or not */ + || ( ( psessionEntry != NULL ) && + ( VOS_P2P_CLIENT_MODE == psessionEntry->pePersona ) ) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) sizeof(tSirMacMgmtHdr) + nPayload, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("could not send Probe Request frame!" )); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} // End limSendProbeReqMgmtFrame. + +tSirRetStatus limGetAddnIeForProbeResp(tpAniSirGlobal pMac, + tANI_U8* addIE, tANI_U16 *addnIELen, + tANI_U8 probeReqP2pIe) +{ + /* If Probe request doesn't have P2P IE, then take out P2P IE + from additional IE */ + if(!probeReqP2pIe) + { + tANI_U8* tempbuf = NULL; + tANI_U16 tempLen = 0; + int left = *addnIELen; + v_U8_t *ptr = addIE; + v_U8_t elem_id, elem_len; + + if(NULL == addIE) + { + PELOGE(limLog(pMac, LOGE, + FL(" NULL addIE pointer"));) + return eSIR_FAILURE; + } + + tempbuf = vos_mem_malloc(left); + if ( NULL == tempbuf ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + return eSIR_MEM_ALLOC_FAILED; + } + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + vos_mem_free(tempbuf); + return eSIR_FAILURE; + } + if ( !( (SIR_MAC_EID_VENDOR == elem_id) && + (memcmp(&ptr[2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)==0) ) ) + { + vos_mem_copy (tempbuf + tempLen, &ptr[0], elem_len + 2); + tempLen += (elem_len + 2); + } + left -= elem_len; + ptr += (elem_len + 2); + } + vos_mem_copy (addIE, tempbuf, tempLen); + *addnIELen = tempLen; + vos_mem_free(tempbuf); + } + return eSIR_SUCCESS; +} + +void +limSendProbeRspMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tpAniSSID pSsid, + short nStaId, + tANI_U8 nKeepAlive, + tpPESession psessionEntry, + tANI_U8 probeReqP2pIe) +{ + tDot11fProbeResponse *pFrm; + tSirRetStatus nSirStatus; + tANI_U32 cfg, nPayload, nBytes, nStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tANI_U32 addnIEPresent = VOS_FALSE; + + tANI_U16 totalAddnIeLen = 0; + tANI_U32 wpsApEnable=0, tmp; + tANI_U8 txFlag = 0; + tANI_U8 *addIE = NULL; + tANI_U8 *pP2pIe = NULL; + tANI_U8 noaLen = 0; + tANI_U8 total_noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + + SIR_P2P_IE_HEADER_LEN]; + tANI_U8 noaIe[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; + tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_TRUE; + if(pMac->gDriverType == eDRIVER_TYPE_MFG) // We don't answer requests + { + return; // in this case. + } + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + pFrm = vos_mem_malloc(sizeof(tDot11fProbeResponse)); + if ( NULL == pFrm ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limSendProbeRspMgmtFrame") ); + return; + } + + // Fill out 'frm', after which we'll just hand the struct off to + // 'dot11fPackProbeResponse'. + vos_mem_set(( tANI_U8* )pFrm, sizeof( tDot11fProbeResponse ), 0); + + // Timestamp to be updated by TFP, below. + + // Beacon Interval: + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pFrm->BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval; + } + else + { + nSirStatus = wlan_cfgGetInt( pMac, WNI_CFG_BEACON_INTERVAL, &cfg); + if (eSIR_SUCCESS != nSirStatus) + { + limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BEACON_INTERVAL from CFG (%d)."), + nSirStatus ); + vos_mem_free(pFrm); + return; + } + pFrm->BeaconInterval.interval = ( tANI_U16 ) cfg; + } + + PopulateDot11fCapabilities( pMac, &pFrm->Capabilities, psessionEntry ); + PopulateDot11fSSID( pMac, ( tSirMacSSid* )pSsid, &pFrm->SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->SuppRates,psessionEntry); + + PopulateDot11fDSParams( pMac, &pFrm->DSParams, psessionEntry->currentOperChannel,psessionEntry); + PopulateDot11fIBSSParams( pMac, &pFrm->IBSSParams, psessionEntry ); + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + PopulateDot11fProbeResWPSIEs(pMac, &pFrm->WscProbeRes, psessionEntry); + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + + if (wpsApEnable) + { + PopulateDot11fWscInProbeRes(pMac, &pFrm->WscProbeRes); + } + + if (pMac->lim.wscIeInfo.probeRespWscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) + { + PopulateDot11fWscRegistrarInfoInProbeRes(pMac, &pFrm->WscProbeRes); + pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS; + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END) + { + DePopulateDot11fWscRegistrarInfoInProbeRes(pMac, &pFrm->WscProbeRes); + pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_NOOP; + } + } + + PopulateDot11fCountry( pMac, &pFrm->Country, psessionEntry); + PopulateDot11fEDCAParamSet( pMac, &pFrm->EDCAParamSet, psessionEntry); + + + if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B) + PopulateDot11fERPInfo( pMac, &pFrm->ERPInfo, psessionEntry); + + + // N.B. In earlier implementations, the RSN IE would be placed in + // the frame here, before the WPA IE, if 'RSN_BEFORE_WPA' was defined. + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->ExtSuppRates, psessionEntry ); + + //Populate HT IEs, when operating in 11n or Taurus modes. + if ( psessionEntry->htCapability ) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pFrm->HTCaps ); + PopulateDot11fHTInfo( pMac, &pFrm->HTInfo, psessionEntry ); + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + limLog( pMac, LOG1, FL("Populate VHT IE in Probe Response")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &pFrm->VHTCaps ); + PopulateDot11fVHTOperation( pMac, &pFrm->VHTOperation ); + // we do not support multi users yet + //PopulateDot11fVHTExtBssLoad( pMac, &frm.VHTExtBssLoad ); + isVHTEnabled = eANI_BOOLEAN_TRUE; + } +#endif + + PopulateDot11fExtCap(pMac, isVHTEnabled, &pFrm->ExtCap, psessionEntry); + + if ( psessionEntry->pLimStartBssReq ) + { + PopulateDot11fWPA( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->WPA ); + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->RSNOpaque ); + } + + PopulateDot11fWMM( pMac, &pFrm->WMMInfoAp, &pFrm->WMMParams, &pFrm->WMMCaps, psessionEntry ); + +#if defined(FEATURE_WLAN_WAPI) + if( psessionEntry->pLimStartBssReq ) + { + PopulateDot11fWAPI( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->WAPI ); + } + +#endif // defined(FEATURE_WLAN_WAPI) + + + nStatus = dot11fGetPackedProbeResponseSize( pMac, pFrm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Probe Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a Probe Response " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + + if( pMac->lim.gpLimRemainOnChanReq ) + { + nBytes += (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq ) ); + } + //Only use CFG for non-listen mode. This CFG is not working for concurrency + //In listening mode, probe rsp IEs is passed in the message from SME to PE + else + { + addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0); + } + + if (addnIEPresent) + { + + addIE = vos_mem_malloc(psessionEntry->addIeParams.probeRespDataLen); + if ( NULL == addIE ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + vos_mem_free(pFrm); + return; + } + + vos_mem_copy(addIE, psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); + totalAddnIeLen = psessionEntry->addIeParams.probeRespDataLen; + + if(eSIR_SUCCESS != limGetAddnIeForProbeResp(pMac, addIE, + &totalAddnIeLen, probeReqP2pIe)) + { + limLog(pMac, LOGP, + FL("Unable to get final Additional IE for Probe Req")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + + vos_mem_set(( tANI_U8* )&extractedExtCap, + sizeof( tDot11fIEExtCap ), 0); + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, + addIE, + &totalAddnIeLen, + &extractedExtCap ); + if(eSIR_SUCCESS != nSirStatus ) + { + extractedExtCapFlag = eANI_BOOLEAN_FALSE; + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Probe Rsp")); + } + + nBytes = nBytes + totalAddnIeLen; + + if (probeReqP2pIe) + { + pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], totalAddnIeLen); + if (pP2pIe != NULL) + { + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + if (noaLen != 0) + { + total_noaLen = limBuildP2pIe(pMac, &noaIe[0], + &noaStream[0], noaLen); + nBytes = nBytes + total_noaLen; + } + } + } + } + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro" + "be Response."), nBytes ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_RSP, peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + /*merge ExtCap IE*/ + if (extractedExtCapFlag) + { + limMergeExtCapIEStruct(&pFrm->ExtCap, &extractedExtCap); + } + // That done, pack the Probe Response: + nStatus = dot11fPackProbeResponse( pMac, pFrm, pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a P" + "robe Response (0x%08x)."), nStatus ); + } + + PELOG3(limLog( pMac, LOG3, FL("Sending Probe Response frame to ") ); + limPrintMacAddr( pMac, peerMacAddr, LOG3 );) + + pMac->sys.probeRespond++; + + if( pMac->lim.gpLimRemainOnChanReq ) + { + vos_mem_copy ( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + pMac->lim.gpLimRemainOnChanReq->probeRspIe, (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq )) ); + } + + if ( addnIEPresent ) + { + vos_mem_copy(pFrame+sizeof(tSirMacMgmtHdr)+nPayload, &addIE[0], totalAddnIeLen); + } + if (noaLen != 0) + { + if (total_noaLen > (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) + { + limLog(pMac, LOGE, + FL("Not able to insert NoA because of length constraint")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else + { + vos_mem_copy( &pFrame[nBytes - (total_noaLen)], + &noaIe[0], total_noaLen); + } + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + // Queue Probe Response frame in high priority WQ + halstatus = halTxFrame( ( tHalHandle ) pMac, pPacket, + ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Could not send Probe Response.") ); + //Pkt will be freed up by the callback + } + + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + + vos_mem_free(pFrm); + return; + + +} // End limSendProbeRspMgmtFrame. + +void +limSendAddtsReqActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirAddtsReqInfo *pAddTS, + tpPESession psessionEntry) +{ + tANI_U16 i; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tDot11fAddTSRequest AddTSReq; + tDot11fWMMAddTSRequest WMMAddTSReq; + tANI_U32 nPayload, nBytes, nStatus; + tpSirMacMgmtHdr pMacHdr; + void *pPacket; +#ifdef FEATURE_WLAN_ESE + tANI_U32 phyMode; +#endif + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + if ( ! pAddTS->wmeTspecPresent ) + { + vos_mem_set(( tANI_U8* )&AddTSReq, sizeof( AddTSReq ), 0); + + AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ; + AddTSReq.DialogToken.token = pAddTS->dialogToken; + AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT; + if ( pAddTS->lleTspecPresent ) + { + PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSReq.TSPEC ); + } + else + { + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSReq.WMMTSPEC ); + } + + if ( pAddTS->lleTspecPresent ) + { + AddTSReq.num_WMMTCLAS = 0; + AddTSReq.num_TCLAS = pAddTS->numTclas; + for ( i = 0; i < pAddTS->numTclas; ++i) + { + PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSReq.TCLAS[i] ); + } + } + else + { + AddTSReq.num_TCLAS = 0; + AddTSReq.num_WMMTCLAS = pAddTS->numTclas; + for ( i = 0; i < pAddTS->numTclas; ++i) + { + PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSReq.WMMTCLAS[i] ); + } + } + + if ( pAddTS->tclasProcPresent ) + { + if ( pAddTS->lleTspecPresent ) + { + AddTSReq.TCLASSPROC.processing = pAddTS->tclasProc; + AddTSReq.TCLASSPROC.present = 1; + } + else + { + AddTSReq.WMMTCLASPROC.version = 1; + AddTSReq.WMMTCLASPROC.processing = pAddTS->tclasProc; + AddTSReq.WMMTCLASPROC.present = 1; + } + } + + nStatus = dot11fGetPackedAddTSRequestSize( pMac, &AddTSReq, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or an Add TS Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for an Add TS Request" + " (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set(( tANI_U8* )&WMMAddTSReq, sizeof( WMMAddTSReq ), 0); + + WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ; + WMMAddTSReq.DialogToken.token = pAddTS->dialogToken; + WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME; + + // WMM spec 2.2.10 - status code is only filled in for ADDTS response + WMMAddTSReq.StatusCode.statusCode = 0; + + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSReq.WMMTSPEC ); +#ifdef FEATURE_WLAN_ESE + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A) + { + pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS; + } + else + { + pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS; + } + PopulateDot11TSRSIE(pMac,&pAddTS->tsrsIE, &WMMAddTSReq.ESETrafStrmRateSet,sizeof(tANI_U8)); +#endif + // fillWmeTspecIE + + nStatus = dot11fGetPackedWMMAddTSRequestSize( pMac, &WMMAddTSReq, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a WMM Add TS Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a WMM Add TS Requ" + "est (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peerMacAddr, pMacHdr); +#endif + + // That done, pack the struct: + if ( ! pAddTS->wmeTspecPresent ) + { + nStatus = dot11fPackAddTSRequest( pMac, &AddTSReq, + pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Add TS Request " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "an Add TS Request (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMAddTSRequest( pMac, &WMMAddTSReq, + pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Add TS Request (0x%08x)."), nStatus ); + } + } + + PELOG3(limLog( pMac, LOG3, FL("Sending an Add TS Request frame to ") ); + limPrintMacAddr( pMac, peerMacAddr, LOG3 );) + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + + // Queue Addts Response frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL( "*** Could not send an Add TS Request" + " (%X) ***" ), halstatus ); + //Pkt will be freed up by the callback + } + +} // End limSendAddtsReqActionFrame. + + + +void +limSendAssocRspMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 statusCode, + tANI_U16 aid, + tSirMacAddr peerMacAddr, + tANI_U8 subType, + tpDphHashNode pSta,tpPESession psessionEntry) +{ + static tDot11fAssocResponse frm; + tANI_U8 *pFrame, *macAddr; + tpSirMacMgmtHdr pMacHdr; + tSirRetStatus nSirStatus; + tANI_U8 lleMode = 0, fAddTS, edcaInclude = 0; + tHalBitVal qosMode, wmeMode; + tANI_U32 nPayload, nBytes, nStatus; + void *pPacket; + eHalStatus halstatus; + tUpdateBeaconParams beaconParams; + tANI_U8 txFlag = 0; + tANI_U32 addnIEPresent = false; + tANI_U32 addnIELen=0; + tANI_U8 addIE[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN]; + tpSirAssocReq pAssocReq = NULL; + tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + tANI_U16 addStripoffIELen = 0; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_11W + tANI_U32 retryInterval; + tANI_U32 maxRetries; +#endif + + if(NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL")); + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + limGetQosMode(psessionEntry, &qosMode); + limGetWmeMode(psessionEntry, &wmeMode); + + // An Add TS IE is added only if the AP supports it and the requesting + // STA sent a traffic spec. + fAddTS = ( qosMode && pSta && pSta->qos.addtsPresent ) ? 1 : 0; + + frm.Status.status = statusCode; + + frm.AID.associd = aid | LIM_AID_MASK; + + if ( NULL == pSta ) + { + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.SuppRates,psessionEntry); + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates, psessionEntry ); + } + else + { + PopulateDot11fAssocRspRates( pMac, &frm.SuppRates, &frm.ExtSuppRates, + pSta->supportedRates.llbRates, pSta->supportedRates.llaRates ); + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if( pSta != NULL && eSIR_SUCCESS == statusCode ) + { + pAssocReq = + (tpSirAssocReq) psessionEntry->parsedAssocReq[pSta->assocId]; + /* populate P2P IE in AssocRsp when assocReq from the peer includes P2P IE */ + if( pAssocReq != NULL && pAssocReq->addIEPresent ) { + PopulateDot11AssocResP2PIE(pMac, &frm.P2PAssocRes, pAssocReq); + } + } + } + + if ( NULL != pSta ) + { + if ( eHAL_SET == qosMode ) + { + if ( pSta->lleEnabled ) + { + lleMode = 1; + if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) ) + { + PopulateDot11fEDCAParamSet( pMac, &frm.EDCAParamSet, psessionEntry); + } + } // End if on .11e enabled in 'pSta'. + } // End if on QOS Mode on. + + if ( ( ! lleMode ) && ( eHAL_SET == wmeMode ) && pSta->wmeEnabled ) + { + if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) ) + { + + PopulateDot11fWMMParams( pMac, &frm.WMMParams, psessionEntry); + + if ( pSta->wsmEnabled ) + { + PopulateDot11fWMMCaps(&frm.WMMCaps ); + } + } + } + + if ( pSta->aniPeer ) + { + if ( ( lleMode && PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) || + ( pSta->wmeEnabled && PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) ) + { + edcaInclude = 1; + } + + } // End if on Airgo peer. + + if ( pSta->mlmStaContext.htCapability && + psessionEntry->htCapability ) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + PopulateDot11fHTInfo( pMac, &frm.HTInfo, psessionEntry ); + } + +#ifdef WLAN_FEATURE_11AC + if( pSta->mlmStaContext.vhtCapability && + psessionEntry->vhtCapability ) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Assoc Response")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &frm.VHTCaps ); + PopulateDot11fVHTOperation( pMac, &frm.VHTOperation); + isVHTEnabled = eANI_BOOLEAN_TRUE; + } +#endif + + PopulateDot11fExtCap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry); + +#ifdef WLAN_FEATURE_11W + if( eSIR_MAC_TRY_AGAIN_LATER == statusCode ) + { + if ( wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + &maxRetries ) != eSIR_SUCCESS ) + limLog( pMac, LOGE, FL("Could not retrieve PMF SA " + "Query maximum retries value") ); + else + if ( wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + &retryInterval ) != eSIR_SUCCESS) + limLog( pMac, LOGE, FL("Could not retrieve PMF SA " + "Query timer interval value") ); + else + PopulateDot11fTimeoutInterval( + pMac, &frm.TimeoutInterval, + SIR_MAC_TI_TYPE_ASSOC_COMEBACK, + (maxRetries - pSta->pmfSaQueryRetryCount) * retryInterval ); + } +#endif + } // End if on non-NULL 'pSta'. + + vos_mem_set(( tANI_U8* )&beaconParams, sizeof( tUpdateBeaconParams), 0); + + if( psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideApProtection(pMac, peerMacAddr, &beaconParams,psessionEntry); + } + + limUpdateShortPreamble(pMac, peerMacAddr, &beaconParams, psessionEntry); + limUpdateShortSlotTime(pMac, peerMacAddr, &beaconParams, psessionEntry); + + /* Populate Do11capabilities after updating session with Assos req details + */ + PopulateDot11fCapabilities( pMac, &frm.Capabilities, psessionEntry ); + + beaconParams.bssIdx = psessionEntry->bssIdx; + + //Send message to HAL about beacon parameter change. + if((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + + // Allocate a buffer for this frame: + nStatus = dot11fGetPackedAssocResponseSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to calculate the packed size f" + "or an Association Response (0x%08x)."), + nStatus ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an Association Re" + "sponse (0x%08x)."), nStatus ); + } + + nBytes = sizeof( tSirMacMgmtHdr ) + nPayload; + + if ( pAssocReq != NULL ) + { + addnIEPresent = (psessionEntry->addIeParams.assocRespDataLen != 0); + + if (addnIEPresent) + { + //Assoc rsp IE available + + addnIELen = psessionEntry->addIeParams.assocRespDataLen; + + if (addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN && addnIELen && + (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) + { + vos_mem_copy(addIE, psessionEntry->addIeParams.assocRespData_buff, + psessionEntry->addIeParams.assocRespDataLen); + + if (addnIELen) + + { + vos_mem_set(( tANI_U8* )&extractedExtCap, + sizeof( tDot11fIEExtCap ), 0); + + addStripoffIELen = addnIELen; + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, + &addIE[0], + &addStripoffIELen, + &extractedExtCap ); + if(eSIR_SUCCESS != nSirStatus) + { + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Assoc Rsp")); + } + else + { + addnIELen = addStripoffIELen; + extractedExtCapFlag = eANI_BOOLEAN_TRUE; + } + nBytes = nBytes + addnIELen; + } + } + } + else + { + limLog(pMac, LOG1, FL("addnIEPresent = %d for Assoc Resp : %d"), + addnIEPresent, pAssocReq->addIEPresent); + } + } + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGP, FL("Call to bufAlloc failed for RE/ASSOC RSP.")); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + ( LIM_ASSOC == subType ) ? + SIR_MAC_MGMT_ASSOC_RSP : + SIR_MAC_MGMT_REASSOC_RSP, + peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + /* merge the ExtCap struct*/ + if (extractedExtCapFlag) + { + limMergeExtCapIEStruct(&(frm.ExtCap), &extractedExtCap); + } + nStatus = dot11fPackAssocResponse( pMac, &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Association Response" + " (0x%08x)."), nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing an " + "Association Response (0x%08x)."), nStatus ); + } + + macAddr = pMacHdr->da; + + if (subType == LIM_ASSOC) + { + PELOG1(limLog(pMac, LOG1, + FL("*** Sending Assoc Resp status %d aid %d to "), + statusCode, aid);) + } + else{ + PELOG1(limLog(pMac, LOG1, + FL("*** Sending ReAssoc Resp status %d aid %d to "), + statusCode, aid);) + } + PELOG1(limPrintMacAddr(pMac, pMacHdr->da, LOG1);) + + if ( addnIEPresent && addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN ) + { + vos_mem_copy( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + &addIE[0], addnIELen ) ; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + /// Queue Association Response frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("*** Could not Send Re/AssocRsp, retCode=%X ***"), + nSirStatus); + + //Pkt will be freed up by the callback + } + + // update the ANI peer station count + //FIXME_PROTECTION : take care of different type of station + // counter inside this function. + limUtilCountStaAdd(pMac, pSta, psessionEntry); + +} // End limSendAssocRspMgmtFrame. + + + +void +limSendAddtsRspActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U16 nStatusCode, + tSirAddtsReqInfo *pAddTS, + tSirMacScheduleIE *pSchedule, + tpPESession psessionEntry) +{ + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tDot11fAddTSResponse AddTSRsp; + tDot11fWMMAddTSResponse WMMAddTSRsp; + tSirRetStatus nSirStatus; + tANI_U32 i, nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + if ( ! pAddTS->wmeTspecPresent ) + { + vos_mem_set( ( tANI_U8* )&AddTSRsp, sizeof( AddTSRsp ), 0 ); + + AddTSRsp.Category.category = SIR_MAC_ACTION_QOS_MGMT; + AddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP; + AddTSRsp.DialogToken.token = pAddTS->dialogToken; + AddTSRsp.Status.status = nStatusCode; + + // The TsDelay information element is only filled in for a specific + // status code: + if ( eSIR_MAC_TS_NOT_CREATED_STATUS == nStatusCode ) + { + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.WMMTSDelay.version = 1; + AddTSRsp.WMMTSDelay.delay = 10; + AddTSRsp.WMMTSDelay.present = 1; + } + else + { + AddTSRsp.TSDelay.delay = 10; + AddTSRsp.TSDelay.present = 1; + } + } + + if ( pAddTS->wsmTspecPresent ) + { + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSRsp.WMMTSPEC ); + } + else + { + PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSRsp.TSPEC ); + } + + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.num_WMMTCLAS = 0; + AddTSRsp.num_TCLAS = pAddTS->numTclas; + for ( i = 0; i < AddTSRsp.num_TCLAS; ++i) + { + PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSRsp.TCLAS[i] ); + } + } + else + { + AddTSRsp.num_TCLAS = 0; + AddTSRsp.num_WMMTCLAS = pAddTS->numTclas; + for ( i = 0; i < AddTSRsp.num_WMMTCLAS; ++i) + { + PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSRsp.WMMTCLAS[i] ); + } + } + + if ( pAddTS->tclasProcPresent ) + { + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.WMMTCLASPROC.version = 1; + AddTSRsp.WMMTCLASPROC.processing = pAddTS->tclasProc; + AddTSRsp.WMMTCLASPROC.present = 1; + } + else + { + AddTSRsp.TCLASSPROC.processing = pAddTS->tclasProc; + AddTSRsp.TCLASSPROC.present = 1; + } + } + + // schedule element is included only if requested in the tspec and we are + // using hcca (or both edca and hcca) + // 11e-D8.0 is inconsistent on whether the schedule element is included + // based on tspec schedule bit or not. Sec 7.4.2.2. says one thing but + // pg 46, line 17-18 says something else. So just include it and let the + // sta figure it out + if ((pSchedule != NULL) && + ((pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))) + { + if ( pAddTS->wsmTspecPresent ) + { + PopulateDot11fWMMSchedule( pSchedule, &AddTSRsp.WMMSchedule ); + } + else + { + PopulateDot11fSchedule( pSchedule, &AddTSRsp.Schedule ); + } + } + + nStatus = dot11fGetPackedAddTSResponseSize( pMac, &AddTSRsp, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for an Add TS Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for an Add TS" + " Response (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set( ( tANI_U8* )&WMMAddTSRsp, sizeof( WMMAddTSRsp ), 0 ); + + WMMAddTSRsp.Category.category = SIR_MAC_ACTION_WME; + WMMAddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP; + WMMAddTSRsp.DialogToken.token = pAddTS->dialogToken; + WMMAddTSRsp.StatusCode.statusCode = (tANI_U8)nStatusCode; + + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSRsp.WMMTSPEC ); + + nStatus = dot11fGetPackedWMMAddTSResponseSize( pMac, &WMMAddTSRsp, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a WMM Add TS Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fWMMAddTSResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a WMM Add" + "TS Response (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Response."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // That done, pack the struct: + if ( ! pAddTS->wmeTspecPresent ) + { + nStatus = dot11fPackAddTSResponse( pMac, &AddTSRsp, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Add TS Response " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "an Add TS Response (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMAddTSResponse( pMac, &WMMAddTSRsp, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Response " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Add TS Response (0x%08x)."), nStatus ); + } + } + + PELOG1(limLog( pMac, LOG1, FL("Sending an Add TS Response (status %d) to "), + nStatusCode ); + limPrintMacAddr( pMac, pMacHdr->da, LOG1 );) + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + // Queue the frame in high priority WQ: + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Add TS Response (%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + } + +} // End limSendAddtsRspActionFrame. + +void +limSendDeltsReqActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 wmmTspecPresent, + tSirMacTSInfo *pTsinfo, + tSirMacTspecIE *pTspecIe, + tpPESession psessionEntry) +{ + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tDot11fDelTS DelTS; + tDot11fWMMDelTS WMMDelTS; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + if ( ! wmmTspecPresent ) + { + vos_mem_set( ( tANI_U8* )&DelTS, sizeof( DelTS ), 0 ); + + DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT; + DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ; + PopulateDot11fTSInfo( pTsinfo, &DelTS.TSInfo ); + + nStatus = dot11fGetPackedDelTSSize( pMac, &DelTS, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a Del TS (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelTS ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a Del TS" + " (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set( ( tANI_U8* )&WMMDelTS, sizeof( WMMDelTS ), 0 ); + + WMMDelTS.Category.category = SIR_MAC_ACTION_WME; + WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ; + WMMDelTS.DialogToken.token = 0; + WMMDelTS.StatusCode.statusCode = 0; + PopulateDot11fWMMTSPEC( pTspecIe, &WMMDelTS.WMMTSPEC ); + nStatus = dot11fGetPackedWMMDelTSSize( pMac, &WMMDelTS, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a WMM Del TS (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelTS ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a WMM De" + "l TS (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Response."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, + psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId, psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // That done, pack the struct: + if ( !wmmTspecPresent ) + { + nStatus = dot11fPackDelTS( pMac, &DelTS, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Del TS frame (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a Del TS frame (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMDelTS( pMac, &WMMDelTS, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Del TS frame (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Del TS frame (0x%08x)."), nStatus ); + } + } + + PELOG1(limLog(pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes); + limPrintMacAddr(pMac, pMacHdr->da, LOG1);) + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId,pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Del TS (%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + } + +} // End limSendDeltsReqActionFrame. + +void +limSendAssocReqMgmtFrame(tpAniSirGlobal pMac, + tLimMlmAssocReq *pMlmAssocReq, + tpPESession psessionEntry) +{ + tDot11fAssocRequest *pFrm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tLimMlmAssocCnf mlmAssocCnf; + tANI_U32 nBytes, nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; + tANI_U8 *wpsIe = NULL; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_TRUE; + tpSirMacMgmtHdr pMacHdr; + + if(NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("psessionEntry is NULL") ); + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimJoinReq) + { + limLog(pMac, LOGE, FL("psessionEntry->pLimJoinReq is NULL") ); + return; + } + nAddIELen = psessionEntry->pLimJoinReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimJoinReq->addIEAssoc.addIEdata; + + pFrm = vos_mem_malloc(sizeof(tDot11fAssocRequest)); + if ( NULL == pFrm ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory") ); + return; + } + + + vos_mem_set( ( tANI_U8* )pFrm, sizeof( tDot11fAssocRequest ), 0 ); + + vos_mem_set(( tANI_U8* )&extractedExtCap, sizeof( tDot11fIEExtCap ), 0); + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, pAddIE, + &nAddIELen, + &extractedExtCap ); + if(eSIR_SUCCESS != nSirStatus ) + { + extractedExtCapFlag = eANI_BOOLEAN_FALSE; + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Assoc Req")); + } + else + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + extractedExtCap.bytes; + if (p_ext_cap->interworkingService) + p_ext_cap->qosMap = 1; + } + + caps = pMlmAssocReq->capabilityInfo; + if ( PROP_CAPABILITY_GET( 11EQOS, psessionEntry->limCurrentBssPropCap ) ) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&pFrm->Capabilities ); + + pFrm->ListenInterval.interval = pMlmAssocReq->listenInterval; + PopulateDot11fSSID2( pMac, &pFrm->SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled) && + SIR_MAC_GET_QOS( psessionEntry->limCurrentBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limCurrentBssQosCaps ); + + // We prefer .11e asociations: + if ( fQosEnabled ) fWmeEnabled = false; + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limCurrentBssQosCaps ); + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + + PopulateDot11fPowerCaps( pMac, &pFrm->PowerCaps, LIM_ASSOC,psessionEntry); +#endif + PopulateDot11fSuppChannels( pMac, &pFrm->SuppChannels, LIM_ASSOC,psessionEntry); + + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &pFrm->PowerCaps, LIM_ASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limCurrentBssPropCap))) + PopulateDot11fQOSCapsStation( pMac, &pFrm->QOSCapsStation ); + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &pFrm->RRMEnabledCap, psessionEntry ); + } +#endif + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr (pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->WPAOpaque ); +#if defined(FEATURE_WLAN_WAPI) + PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->WAPIOpaque ); +#endif // defined(FEATURE_WLAN_WAPI) + } + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limCurrentBssPropCap ) ) + { + if(!pMac->psOffloadEnabled) + PopulateDot11fWMMInfoStation( pMac, &pFrm->WMMInfoStation ); + else + PopulateDot11fWMMInfoStationPerSession(pMac, psessionEntry, + &pFrm->WMMInfoStation); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limCurrentBssPropCap ))) + { + PopulateDot11fWMMCaps( &pFrm->WMMCaps ); + } + } + + //Populate HT IEs, when operating in 11n or Taurus modes AND + //when AP is also operating in 11n mode. + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pFrm->HTCaps ); +#ifdef DISABLE_GF_FOR_INTEROP + + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + + if(psessionEntry->pLimJoinReq != NULL) + { + limLog( pMac, LOG1, FL("Sending Assoc Req to Non-TQ AP," + " Turning off Greenfield")); + pFrm->HTCaps.greenField = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } +#endif + + } +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Assoc Request")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &pFrm->VHTCaps ); + isVHTEnabled = eANI_BOOLEAN_TRUE; + } +#endif + + PopulateDot11fExtCap( pMac, isVHTEnabled, &pFrm->ExtCap, psessionEntry); + +#if defined WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->pLimJoinReq->is11Rconnection) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("mdie = %02x %02x %02x"), + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[0], + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[1], + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[2]); +#endif + PopulateMDIE( pMac, &pFrm->MobilityDomain, + psessionEntry->pLimJoinReq->bssDescription.mdie); + } + else + { + // No 11r IEs dont send any MDIE + limLog( pMac, LOG1, FL("MDIE not present")); + } +#endif + +#ifdef FEATURE_WLAN_ESE + /* + * ESE Version IE will be included in association request + * when ESE is enabled on DUT through ini and it is also + * advertised by the peer AP to which we are trying to + * associate to. + */ + if (psessionEntry->is_ese_version_ie_present && + pMac->roam.configParam.isEseIniFeatureEnabled) + { + PopulateDot11fESEVersion(&pFrm->ESEVersion); + } + /* For ESE Associations fill the ESE IEs */ + if (psessionEntry->isESEconnection && + psessionEntry->pLimJoinReq->isESEFeatureIniEnabled) + { +#ifndef FEATURE_DISABLE_RM + PopulateDot11fESERadMgmtCap(&pFrm->ESERadMgmtCap); +#endif + } +#endif + + nStatus = dot11fGetPackedAssocRequestSize( pMac, pFrm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or an Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an As" + "sociation Request."), nBytes ); + + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + + + /* Update PE session id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + + limPostSmeMessage( pMac, LIM_MLM_ASSOC_CNF, + ( tANI_U32* ) &mlmAssocCnf); + + vos_mem_free(pFrm); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ASSOC_REQ, psessionEntry->bssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + vos_mem_free(pFrm); + return; + } + /* merge the ExtCap struct*/ + if (extractedExtCapFlag) + { + limMergeExtCapIEStruct(&pFrm->ExtCap, &extractedExtCap); + } + + // That done, pack the Assoc Request: + nStatus = dot11fPackAssocRequest( pMac, pFrm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Assoc Request (0x%0" + "8x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + vos_mem_free(pFrm); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a Assoc" + "Request (0x%08x)."), nStatus ); + } + + PELOG1(limLog( pMac, LOG1, FL("*** Sending Association Request length %d" + "to "), + nBytes );) + if (psessionEntry->assocReq != NULL) { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store " + "assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy( psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Association Request (%X)!"), + halstatus ); + //Pkt will be freed up by the callback + vos_mem_free(pFrm); + return; + } + + // Free up buffer allocated for mlmAssocReq + vos_mem_free(pMlmAssocReq); + pMlmAssocReq = NULL; + vos_mem_free(pFrm); + return; +} // End limSendAssocReqMgmtFrame + + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*------------------------------------------------------------------------------------ + * + * Send Reassoc Req with FTIEs. + * + *----------------------------------------------------------------------------------- + */ +void +limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry) +{ + static tDot11fReAssocRequest frm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tANI_U16 ft_ies_length = 0; + tANI_U8 *pBody; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; +#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tANI_U8 *wpsIe = NULL; +#endif + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + tpSirMacMgmtHdr pMacHdr; + + if (NULL == psessionEntry) { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimReAssocReq) { + return; + } + nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata; + limLog( pMac, LOG1, FL("limSendReassocReqWithFTIEsMgmtFrame received in " + "state (%d)."), psessionEntry->limMlmState); + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + caps = pMlmReassocReq->capabilityInfo; + if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap)) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&frm.Capabilities ); + + frm.ListenInterval.interval = pMlmReassocReq->listenInterval; + + /* * + * Get the bssid of the older AP. + * The previous ap bssid is stored in the FT Session + * while creating the PE FT Session for reassociation. + * */ + vos_mem_copy((tANI_U8*)frm.CurrentAPAddress.mac, + psessionEntry->prev_ap_bssid, sizeof(tSirMacAddr)); + + PopulateDot11fSSID2( pMac, &frm.SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled) && + SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps ); + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps ); + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + + PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, + LIM_REASSOC,psessionEntry); + PopulateDot11fSuppChannels(pMac, &frm.SuppChannels, LIM_REASSOC, + psessionEntry); +#endif + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) )) + { + PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation ); + } + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry ); + } +#endif + + // Ideally this should be enabled for 11r also. But 11r does + // not follow the usual norm of using the Opaque object + // for rsnie and fties. Instead we just add + // the rsnie and fties at the end of the pack routine for 11r. + // This should ideally! be fixed. +#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + // + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if (!psessionEntry->is11Rconnection) + { + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WPAOpaque ); + } + +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->pLimReAssocReq->cckmIE.length) + { + PopulateDot11fESECckmOpaque( pMac, &( psessionEntry->pLimReAssocReq->cckmIE ), + &frm.ESECckmOpaque ); + } +#endif //FEATURE_WLAN_ESE + } + +#ifdef FEATURE_WLAN_ESE + /* + * ESE Version IE will be included in association request + * when ESE is enabled on DUT through ini and it is also + * advertised by the peer AP to which we are trying to + * associate to. + */ + if (psessionEntry->is_ese_version_ie_present && + pMac->roam.configParam.isEseIniFeatureEnabled) + { + PopulateDot11fESEVersion(&frm.ESEVersion); + } + // For ESE Associations fill the ESE IEs + if (psessionEntry->isESEconnection && + psessionEntry->pLimReAssocReq->isESEFeatureIniEnabled) + { +#ifndef FEATURE_DISABLE_RM + PopulateDot11fESERadMgmtCap(&frm.ESERadMgmtCap); +#endif + } +#endif //FEATURE_WLAN_ESE +#endif //FEATURE_WLAN_ESE || FEATURE_WLAN_LFR + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) ) + { + if(!pMac->psOffloadEnabled) + PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation ); + else + PopulateDot11fWMMInfoStationPerSession(pMac, psessionEntry, + &frm.WMMInfoStation); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap ))) + { + PopulateDot11fWMMCaps( &frm.WMMCaps ); + } +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->isESEconnection) + { + PopulateDot11fReAssocTspec(pMac, &frm, psessionEntry); + + // Populate the TSRS IE if TSPEC is included in the reassoc request + if (psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs) + { + tANI_U32 phyMode; + tSirMacESETSRSIE tsrsIE; + limGetPhyMode(pMac, &phyMode, psessionEntry); + + tsrsIE.tsid = 0; + if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A) + { + tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS; + } + else + { + tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS; + } + PopulateDot11TSRSIE(pMac,&tsrsIE, &frm.ESETrafStrmRateSet, sizeof(tANI_U8)); + } + } +#endif + } + + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + } + +#if defined WLAN_FEATURE_VOWIFI_11R + if ( psessionEntry->pLimReAssocReq->bssDescription.mdiePresent && + (pMac->roam.roamSession[smeSessionId].ftSmeContext.addMDIE == TRUE) +#if defined FEATURE_WLAN_ESE + && !psessionEntry->isESEconnection +#endif + ) + { + PopulateMDIE( pMac, &frm.MobilityDomain, psessionEntry->pLimReAssocReq->bssDescription.mdie); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Re-Assoc Request")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &frm.VHTCaps ); + isVHTEnabled = eANI_BOOLEAN_TRUE; + PopulateDot11fExtCap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry); + } +#endif + + nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Re-Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fReAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Re-Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("FT IE Reassoc Req (%d)."), + pMac->roam.roamSession[smeSessionId].ftSmeContext.reassoc_ft_ies_length); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->is11Rconnection) + { + ft_ies_length = + pMac->roam.roamSession[smeSessionId].ftSmeContext.reassoc_ft_ies_length; + } +#endif + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes+ft_ies_length, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As" + "sociation Request."), nBytes ); + goto end; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes + ft_ies_length, 0); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG1); +#endif + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_REASSOC_REQ, + psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + + pMacHdr = (tpSirMacMgmtHdr) pFrame; + // That done, pack the ReAssoc Request: + nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a R" + "e-Association Request (0x%08x)."), nStatus ); + } + + PELOG3(limLog( pMac, LOG3, + FL("*** Sending Re-Association Request length %d %d to "), + nBytes, nPayload );) + if( psessionEntry->assocReq != NULL ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy( psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if (psessionEntry->is11Rconnection && + pMac->roam.roamSession[smeSessionId].ftSmeContext.reassoc_ft_ies) + { + int i = 0; + + pBody = pFrame + nBytes; + for (i=0; iroam.roamSession[smeSessionId].ftSmeContext.reassoc_ft_ies[i]; + pBody++; + } + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Re-assoc Req Frame is: ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, + (tANI_U8 *)pFrame, + (nBytes + ft_ies_length));) +#endif + + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if( NULL != psessionEntry->assocReq ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + psessionEntry->assocReq = vos_mem_malloc(ft_ies_length); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));) + psessionEntry->assocReqLen = 0; + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy( psessionEntry->assocReq, + pMac->roam.roamSession[smeSessionId].ftSmeContext.reassoc_ft_ies, + (ft_ies_length)); + psessionEntry->assocReqLen = (ft_ies_length); + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (nBytes + ft_ies_length), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Re-Association Request" + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + goto end; + } + +end: + // Free up buffer allocated for mlmAssocReq + vos_mem_free( pMlmReassocReq ); + psessionEntry->pLimMlmReassocReq = NULL; + +} + +void limSendRetryReassocReqFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq, + tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; // keep sme + tLimMlmReassocReq *pTmpMlmReassocReq = NULL; + if(NULL == pTmpMlmReassocReq) + { + pTmpMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pTmpMlmReassocReq ) goto end; + vos_mem_set( pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0); + vos_mem_copy( pTmpMlmReassocReq, pMlmReassocReq, sizeof(tLimMlmReassocReq)); + } + + // Prepare and send Reassociation request frame + // start reassoc timer. + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId; + // Start reassociation failure timer + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + // Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + goto end; + } + + limSendReassocReqWithFTIEsMgmtFrame(pMac, pTmpMlmReassocReq, psessionEntry); + return; + +end: + // Free up buffer allocated for reassocReq + if (pMlmReassocReq != NULL) + { + vos_mem_free(pMlmReassocReq); + pMlmReassocReq = NULL; + } + if (pTmpMlmReassocReq != NULL) + { + vos_mem_free(pTmpMlmReassocReq); + pTmpMlmReassocReq = NULL; + } + mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +void +limSendReassocReqMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry) +{ + static tDot11fReAssocRequest frm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; + tANI_U8 *wpsIe = NULL; + tANI_U8 txFlag = 0; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + tpSirMacMgmtHdr pMacHdr; + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimReAssocReq) + { + return; + } + nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + caps = pMlmReassocReq->capabilityInfo; + if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap)) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&frm.Capabilities ); + + frm.ListenInterval.interval = pMlmReassocReq->listenInterval; + + vos_mem_copy(( tANI_U8* )frm.CurrentAPAddress.mac, + ( tANI_U8* )psessionEntry->bssId, 6 ); + + PopulateDot11fSSID2( pMac, &frm.SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled ) && + SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps ); + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps ); + + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_REASSOC,psessionEntry); + PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_REASSOC,psessionEntry); +#endif + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) )) + { + PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation ); + } + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry ); + } +#endif + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WPAOpaque ); +#if defined(FEATURE_WLAN_WAPI) + PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WAPIOpaque ); +#endif // defined(FEATURE_WLAN_WAPI) + } + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) ) + { + if(!pMac->psOffloadEnabled) + PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation ); + else + PopulateDot11fWMMInfoStationPerSession(pMac, psessionEntry, + &frm.WMMInfoStation); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap ))) + { + PopulateDot11fWMMCaps( &frm.WMMCaps ); + } + } + + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + } +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &frm.VHTCaps ); + isVHTEnabled = eANI_BOOLEAN_TRUE; + } +#endif + + PopulateDot11fExtCap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry); + + nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Re-Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fReAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Re-Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog(pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As" + "sociation Request."), nBytes ); + goto end; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_REASSOC_REQ, + psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + + pMacHdr = (tpSirMacMgmtHdr) pFrame; + + // That done, pack the Probe Request: + nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a R" + "e-Association Request (0x%08x)."), nStatus ); + } + + PELOG1(limLog( pMac, LOG1, FL("*** Sending Re-Association Request length %d" + "to "), + nBytes );) + + if( psessionEntry->assocReq != NULL ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Re-Association Request" + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + goto end; + } + +end: + // Free up buffer allocated for mlmAssocReq + vos_mem_free( pMlmReassocReq ); + psessionEntry->pLimMlmReassocReq = NULL; + +} // limSendReassocReqMgmtFrame + +/** + * \brief Send an Authentication frame + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pAuthFrameBody Pointer to Authentication frame structure that need + * to be sent + * + * \param peerMacAddr MAC address of the peer entity to which Authentication + * frame is destined + * + * \param wepBit Indicates whether wep bit to be set in FC while sending + * Authentication frame3 + * + * + * This function is called by limProcessMlmMessages(). Authentication frame + * is formatted and sent when this function is called. + * + * + */ + +void +limSendAuthMgmtFrame(tpAniSirGlobal pMac, + tpSirMacAuthFrameBody pAuthFrameBody, + tSirMacAddr peerMacAddr, + tANI_U8 wepBit, + tpPESession psessionEntry + ) +{ + tANI_U8 *pFrame, *pBody; + tANI_U32 frameLen = 0, bodyLen = 0; + tpSirMacMgmtHdr pMacHdr; + tANI_U16 i; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("Error: psession Entry is NULL")); + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + limLog(pMac, LOG1, + FL("Sending Auth seq# %d status %d (%d) to "MAC_ADDRESS_STR), + pAuthFrameBody->authTransactionSeqNumber, + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(peerMacAddr)); + if (wepBit == LIM_WEP_IN_FC) + { + /// Auth frame3 to be sent with encrypted framebody + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each for + * auth algorithm number, transaction number, status code, + * 128 bytes for challenge text and 4 bytes each for + * IV & ICV. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + LIM_ENCR_AUTH_BODY_LEN; + + bodyLen = LIM_ENCR_AUTH_BODY_LEN; + } // if (wepBit == LIM_WEP_IN_FC) + else + { + switch (pAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_1: + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus 2 bytes + * each for auth algorithm number, transaction number + * and status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + +#if defined WLAN_FEATURE_VOWIFI_11R + if (pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH) + { + if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq && + 0 != psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length) + { + frameLen += + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length; + limLog(pMac, LOG3, FL("Auth frame, FTIES length added=%d"), + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length); + } + else + { + limLog(pMac, LOG3, FL("Auth frame, Does not contain " + "FTIES!!!")); + frameLen += (2+SIR_MDIE_SIZE); + } + } +#endif + break; + + case SIR_MAC_AUTH_FRAME_2: + if ((pAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) || + ((pAuthFrameBody->authAlgoNumber == eSIR_SHARED_KEY) && + (pAuthFrameBody->authStatusCode != + eSIR_MAC_SUCCESS_STATUS))) + { + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus + * 2 bytes each for auth algorithm number, + * transaction number and status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + } + else + { + // Shared Key algorithm with challenge text + // to be sent + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus + * 2 bytes each for auth algorithm number, + * transaction number, status code and 128 bytes + * for challenge text. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + sizeof(tSirMacAuthFrame); + bodyLen = sizeof(tSirMacAuthFrameBody); + } + + break; + + case SIR_MAC_AUTH_FRAME_3: + /// Auth frame3 to be sent without encrypted framebody + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each + * for auth algorithm number, transaction number and + * status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + + break; + + case SIR_MAC_AUTH_FRAME_4: + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each + * for auth algorithm number, transaction number and + * status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + + break; + } // switch (pAuthFrameBody->authTransactionSeqNumber) + } // end if (wepBit == LIM_WEP_IN_FC) + + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )frameLen, ( void** ) &pFrame, ( void** ) &pPacket ); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + // Log error + limLog(pMac, LOGP, FL("call to bufAlloc failed for AUTH frame")); + + return; + } + + for (i = 0; i < frameLen; i++) + pFrame[i] = 0; + + // Prepare BD + if (limPopulateMacHeader(pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_AUTH, peerMacAddr,psessionEntry->selfMacAddr) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("call to limPopulateMacHeader failed for " + "AUTH frame")); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + pMacHdr->fc.wep = wepBit; + + // Prepare BSSId + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + } + + /// Prepare Authentication frame body + pBody = pFrame + sizeof(tSirMacMgmtHdr); + + if (wepBit == LIM_WEP_IN_FC) + { + vos_mem_copy(pBody, (tANI_U8 *) pAuthFrameBody, bodyLen); + + PELOG1(limLog(pMac, LOG1, + FL("*** Sending Auth seq# 3 status %d (%d) to"MAC_ADDRESS_STR), + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(pMacHdr->da));) + + } + else + { + *((tANI_U16 *)(pBody)) = + sirSwapU16ifNeeded(pAuthFrameBody->authAlgoNumber); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + + *((tANI_U16 *)(pBody)) = + sirSwapU16ifNeeded(pAuthFrameBody->authTransactionSeqNumber); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + + *((tANI_U16 *)(pBody)) = + sirSwapU16ifNeeded(pAuthFrameBody->authStatusCode); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + if ( bodyLen <= (sizeof (pAuthFrameBody->type) + + sizeof (pAuthFrameBody->length) + + sizeof (pAuthFrameBody->challengeText))) + vos_mem_copy(pBody, (tANI_U8 *) &pAuthFrameBody->type, bodyLen); + +#if defined WLAN_FEATURE_VOWIFI_11R + if ((pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH) && + (pAuthFrameBody->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1)) + { + + int i = 0; + if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq) + { + if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG2(limLog(pMac, LOG2, FL("Auth1 Frame FTIE is: ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + (tANI_U8 *)pBody, + (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length));) +#endif + for (i = 0; + i < psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies_length; + i++) + { + *pBody = + psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies[i]; + pBody++; + } + } + else + { + /* MDID attr is 54*/ + *pBody = 54; + pBody++; + *pBody = SIR_MDIE_SIZE; + pBody++; + if (NULL != + psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) + { + for(i=0;iftPEContext.pFTPreAuthReq->pbssDescription->mdie[i]; + pBody++; + } + } + } + } + } +#endif + + PELOG1(limLog(pMac, LOG1, + FL("*** Sending Auth seq# %d status %d (%d) to "MAC_ADDRESS_STR), + pAuthFrameBody->authTransactionSeqNumber, + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(pMacHdr->da));) + } + PELOG2(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, pFrame, frameLen);) + + if( (SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) || + (psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE) +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + || ((NULL != psessionEntry->ftPEContext.pFTPreAuthReq) && + (SIR_BAND_5_GHZ == + limGetRFBand(psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum))) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + /// Queue Authentication frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("*** Could not send Auth frame, retCode=%X ***"), + halstatus); + + //Pkt will be freed up by the callback + } + + return; +} /*** end limSendAuthMgmtFrame() ***/ + +eHalStatus limSendDeauthCnf(tpAniSirGlobal pMac) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tLimMlmDeauthReq *pMlmDeauthReq; + tLimMlmDeauthCnf mlmDeauthCnf; + tpPESession psessionEntry; + + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq) + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + } + + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDeauthReq->sessionId))== NULL) + { + + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + + /// Receive path cleanup with dummy packet + limFTCleanupPreAuthInfo(pMac,psessionEntry); + limCleanupRxPath(pMac, pStaDs,psessionEntry); + /// Free up buffer allocated for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; + } + return eHAL_STATUS_SUCCESS; +end: + vos_mem_copy( (tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger; + mlmDeauthCnf.aid = pMlmDeauthReq->aid; + mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId; + + // Free up buffer allocated + // for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus limSendDisassocCnf(tpAniSirGlobal pMac) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tLimMlmDisassocCnf mlmDisassocCnf; + tpPESession psessionEntry; + tLimMlmDisassocReq *pMlmDisassocReq; + + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq) + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + } + + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDisassocReq->sessionId))== NULL) + { + + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + /// Receive path cleanup with dummy packet + if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs, psessionEntry)) + { + mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE ) && + ( +#ifdef FEATURE_WLAN_ESE + (psessionEntry->isESEconnection ) || +#endif +#ifdef FEATURE_WLAN_LFR + (psessionEntry->isFastRoamIniFeatureEnabled ) || +#endif + (psessionEntry->is11Rconnection )) && + (pMlmDisassocReq->reasonCode != + eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) + { + PELOGE(limLog(pMac, LOGE, + FL("FT Preauth Session (%p,%d) Cleanup"), + psessionEntry, psessionEntry->peSessionId);); + +#if defined WLAN_FEATURE_VOWIFI_11R + /* Delete FT session if there exists one */ + limFTCleanupPreAuthInfo(pMac, psessionEntry); +#endif + } + else + { + PELOGE(limLog(pMac, LOGE, + FL("No FT Preauth Session Cleanup in role %d" +#ifdef FEATURE_WLAN_ESE + " isESE %d" +#endif +#ifdef FEATURE_WLAN_LFR + " isLFR %d" +#endif + " is11r %d reason %d"), + psessionEntry->limSystemRole, +#ifdef FEATURE_WLAN_ESE + psessionEntry->isESEconnection, +#endif +#ifdef FEATURE_WLAN_LFR + psessionEntry->isFastRoamIniFeatureEnabled, +#endif + psessionEntry->is11Rconnection, + pMlmDisassocReq->reasonCode);); + } +#endif + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + return eHAL_STATUS_SUCCESS; + } + else + { + return eHAL_STATUS_SUCCESS; + } +end: + vos_mem_copy( (tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.aid = pMlmDisassocReq->aid; + mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger; + + /* Update PE session ID*/ + mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId; + + if(pMlmDisassocReq != NULL) + { + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + } + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus limDisassocTxCompleteCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess) +{ + return limSendDisassocCnf(pMac); +} + +eHalStatus limDeauthTxCompleteCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess) +{ + return limSendDeauthCnf(pMac); +} + +/** + * \brief This function is called to send Disassociate frame. + * + * + * \param pMac Pointer to Global MAC structure + * + * \param nReason Indicates the reason that need to be sent in + * Disassociation frame + * + * \param peerMacAddr MAC address of the STA to which Disassociation frame is + * sent + * + * + */ + +void +limSendDisassocMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 nReason, + tSirMacAddr peer, + tpPESession psessionEntry, + tANI_BOOLEAN waitForAck) +{ + tDot11fDisassociation frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U32 val = 0; + tANI_U8 smeSessionId = 0; + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0); + + frm.Reason.code = nReason; + + nStatus = dot11fGetPackedDisassociationSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Disassociation (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDisassociation ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Disassociation " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Dis" + "association."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_DISASSOC, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Disassociation (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + // Prepare the BSSID + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackDisassociation( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Disassociation (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a D" + "isassociation (0x%08x)."), nStatus ); + } + + limLog( pMac, LOG1, FL("***Sessionid %d Sending Disassociation frame with " + "reason %u and waitForAck %d to "MAC_ADDRESS_STR" ,From " + MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason, waitForAck, + MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if((psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + + if (waitForAck) + { + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + /* get the duration from the request */ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, limDisassocTxCompleteCnf, + txFlag, smeSessionId, false ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + + val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); + + if (tx_timer_change( + &pMac->lim.limTimers.gLimDisassocAckTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change Disassoc ack Timer val")); + return; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate Disassoc ack Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + return; + } + } + else + { + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Disassociation " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + } +} // End limSendDisassocMgmtFrame. + +/** + * \brief This function is called to send a Deauthenticate frame + * + * + * \param pMac Pointer to global MAC structure + * + * \param nReason Indicates the reason that need to be sent in the + * Deauthenticate frame + * + * \param peeer address of the STA to which the frame is to be sent + * + * + */ + +void +limSendDeauthMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 nReason, + tSirMacAddr peer, + tpPESession psessionEntry, + tANI_BOOLEAN waitForAck) +{ + tDot11fDeAuth frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U32 val = 0; +#ifdef FEATURE_WLAN_TDLS + tANI_U16 aid; + tpDphHashNode pStaDs; +#endif + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return; + } + + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* ) &frm, sizeof( frm ), 0 ); + + frm.Reason.code = nReason; + + nStatus = dot11fGetPackedDeAuthSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a De-Authentication (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDeAuth ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a De-Authentication " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-" + "Authentication."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_DEAUTH, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a De-Authentication (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + // Prepare the BSSID + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackDeAuth( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a DeAuthentication (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a D" + "e-Authentication (0x%08x)."), nStatus ); + } + limLog( pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with " + "reason %u and waitForAck %d to "MAC_ADDRESS_STR" ,From " + MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason, waitForAck, + MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if((psessionEntry->pePersona == VOS_P2P_CLIENT_MODE) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + +#ifdef FEATURE_WLAN_TDLS + pStaDs = dphLookupHashEntry(pMac, peer, &aid, &psessionEntry->dph.dphHashTable); +#endif + + if (waitForAck) + { + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, limDeauthTxCompleteCnf, txFlag, + smeSessionId, false ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send De-Authentication " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback limTxComplete + + /*Call limProcessDeauthAckTimeout which will send + * DeauthCnf for this frame + */ + limProcessDeauthAckTimeout(pMac); + return; + } + + val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); + + if (tx_timer_change( + &pMac->lim.limTimers.gLimDeauthAckTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change Deauth ack Timer val")); + return; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate Deauth ack Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + return; + } + } + else + { + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); +#ifdef FEATURE_WLAN_TDLS + if ((NULL != pStaDs) && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_IBSS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + } + else + { +#endif + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); +#ifdef FEATURE_WLAN_TDLS + } +#endif + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send De-Authentication " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + } + +} // End limSendDeauthMgmtFrame. + + +#ifdef ANI_SUPPORT_11H +/** + * \brief Send a Measurement Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendMeasReportFrame(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peer, + tpPESession psessionEntry) +{ + tDot11fMeasurementReport frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID; + frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken; + + switch ( pMeasReqFrame->measReqIE.measType ) + { + case SIR_MAC_BASIC_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport0( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + case SIR_MAC_CCA_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport1( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + case SIR_MAC_RPI_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport2( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + default: + limLog( pMac, LOGE, FL("Unknown measurement type %d in limSen" + "dMeasReportFrame."), + pMeasReqFrame->measReqIE.measType ); + return eSIR_FAILURE; + } + + if ( eSIR_SUCCESS != nSirStatus ) return eSIR_FAILURE; + + nStatus = dot11fGetPackedMeasurementReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Measurement Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fMeasurementReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Measurement Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-" + "Authentication."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Measurement Report (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + vos_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackMeasurementReport( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Measurement Report (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a M" + "easurement Report (0x%08x)."), nStatus ); + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, 0 ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Measurement Report " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; // just allocated... + } + + return eSIR_SUCCESS; + +} // End limSendMeasReportFrame. + + +/** + * \brief Send a TPC Request Action frame + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which the frame should be sent + * + * + */ + +void +limSendTpcRequestFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tpPESession psessionEntry) +{ + tDot11fTPCRequest frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID; + frm.DialogToken.token = 1; + frm.TPCRequest.present = 1; + + nStatus = dot11fGetPackedTPCRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a TPC Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fTPCRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a TPC Request (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set(pFrame, nBytes,0); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a TPC Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + vos_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackTPCRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a T" + "PC Request (0x%08x)."), nStatus ); + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, 0 ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a TPC Request " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + +} // End limSendTpcRequestFrame. + + +/** + * \brief Send a TPC Report Action frame + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pTpcReqFrame Pointer to the received TPC Request + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendTpcReportFrame(tpAniSirGlobal pMac, + tpSirMacTpcReqActionFrame pTpcReqFrame, + tSirMacAddr peer, + tpPESession psessionEntry) +{ + tDot11fTPCReport frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID; + frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken; + + frm.TPCReport.tx_power = 0; + frm.TPCReport.link_margin = 0; + frm.TPCReport.present = 1; + + nStatus = dot11fGetPackedTPCReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a TPC Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fTPCReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a TPC Report (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a TPC Report (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + vos_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackTPCReport( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a T" + "PC Report (0x%08x)."), nStatus ); + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, 0 ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a TPC Report " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; // just allocated... + } + + return eSIR_SUCCESS; + +} // End limSendTpcReportFrame. +#endif //ANI_SUPPORT_11H + + +/** + * \brief Send a Channel Switch Announcement + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which this frame will be sent + * + * \param nMode + * + * \param nNewChannel + * + * \param nCount + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendChannelSwitchMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nMode, + tANI_U8 nNewChannel, + tANI_U8 nCount, + tpPESession psessionEntry ) +{ + tDot11fChannelSwitch frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + + tANI_U8 smeSessionId = 0; + + if (psessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!"));) + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID; + frm.ChanSwitchAnn.switchMode = nMode; + frm.ChanSwitchAnn.newChannel = nNewChannel; + frm.ChanSwitchAnn.switchCount = nCount; + frm.ChanSwitchAnn.present = 1; + + nStatus = dot11fGetPackedChannelSwitchSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Channel Switch (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fChannelSwitch ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Channel Switch (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Channel Switch (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Channel Switch (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a C" + "hannel Switch (0x%08x)."), nStatus ); + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End limSendChannelSwitchMgmtFrame. + + + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limSendVHTOpmodeNotificationFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nMode, + tpPESession psessionEntry ) +{ + tDot11fOperatingMode frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload = 0, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + + tANI_U8 smeSessionId = 0; + + if (psessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!"));) + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_VHT; + frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION; + frm.OperatingMode.chanWidth = nMode; + frm.OperatingMode.rxNSS = 0; + frm.OperatingMode.rxNSSType = 0; + + nStatus = dot11fGetPackedOperatingModeSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Operating Mode (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fOperatingMode); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Operating Mode (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Operating Mode" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + + // Next, we fill out the buffer descriptor: + if(psessionEntry->pePersona == VOS_STA_SAP_MODE) { + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + } else + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, psessionEntry->bssId, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Operating Mode (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + nStatus = dot11fPackOperatingMode( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Operating Mode (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a Operating Mode" + " (0x%08x)."), nStatus ); + } + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +/** + * \brief Send a VHT Channel Switch Announcement + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which this frame will be sent + * + * \param nChanWidth + * + * \param nNewChannel + * + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendVHTChannelSwitchMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nChanWidth, + tANI_U8 nNewChannel, + tANI_U8 ncbMode, + tpPESession psessionEntry ) +{ + tDot11fChannelSwitch frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + + tANI_U8 smeSessionId = 0; + + if (psessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!"));) + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID; + frm.ChanSwitchAnn.switchMode = 1; + frm.ChanSwitchAnn.newChannel = nNewChannel; + frm.ChanSwitchAnn.switchCount = 1; + frm.ExtChanSwitchAnn.secondaryChannelOffset = limGetHTCBState(ncbMode); + frm.ExtChanSwitchAnn.present = 1; + frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth; + frm.WiderBWChanSwitchAnn.newCenterChanFreq0 = limGetCenterChannel(pMac,nNewChannel,ncbMode,nChanWidth); + frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0; + frm.ChanSwitchAnn.present = 1; + frm.WiderBWChanSwitchAnn.present = 1; + + nStatus = dot11fGetPackedChannelSwitchSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Channel Switch (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fChannelSwitch ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Channel Switch (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Channel Switch (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Channel Switch (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a C" + "hannel Switch (0x%08x)."), nStatus ); + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End limSendVHTChannelSwitchMgmtFrame. + + + +#endif + +/** + * \brief Send an ADDBA Req Action Frame to peer + * + * \sa limSendAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMlmAddBAReq A pointer to tLimMlmAddBAReq. This contains + * the necessary parameters reqd by PE send the ADDBA Req Action + * Frame to the peer + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac, + tpLimMlmAddBAReq pMlmAddBAReq, tpPESession psessionEntry) +{ + tDot11fAddBAReq frmAddBAReq; + tANI_U8 *pAddBAReqBuffer = NULL; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return eSIR_FAILURE; + } + + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( (void *) &frmAddBAReq, sizeof( frmAddBAReq ), 0); + + // Category - 3 (BA) + frmAddBAReq.Category.category = SIR_MAC_ACTION_BLKACK; + + // Action - 0 (ADDBA Req) + frmAddBAReq.Action.action = SIR_MAC_BLKACK_ADD_REQ; + + // FIXME - Dialog Token, generalize this... + frmAddBAReq.DialogToken.token = pMlmAddBAReq->baDialogToken; + + // Fill the ADDBA Parameter Set + frmAddBAReq.AddBAParameterSet.tid = pMlmAddBAReq->baTID; + frmAddBAReq.AddBAParameterSet.policy = pMlmAddBAReq->baPolicy; + frmAddBAReq.AddBAParameterSet.bufferSize = pMlmAddBAReq->baBufferSize; + + // BA timeout + // 0 - indicates no BA timeout + frmAddBAReq.BATimeout.timeout = pMlmAddBAReq->baTimeout; + + // BA Starting Sequence Number + // Fragment number will always be zero + if (pMlmAddBAReq->baSSN < LIM_TX_FRAMES_THRESHOLD_ON_CHIP) { + pMlmAddBAReq->baSSN = LIM_TX_FRAMES_THRESHOLD_ON_CHIP; + } + + frmAddBAReq.BAStartingSequenceControl.ssn = + pMlmAddBAReq->baSSN - LIM_TX_FRAMES_THRESHOLD_ON_CHIP; + + nStatus = dot11fGetPackedAddBAReqSize( pMac, &frmAddBAReq, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an ADDBA Request (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddBAReq ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an ADDBA Req (0x%08x)."), + nStatus ); + } + + // Add the MGMT header to frame length + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Need to allocate a buffer for ADDBA AF + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pAddBAReqBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pAddBAReqBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pAddBAReqBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmAddBAReq->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pAddBAReqBuffer; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmAddBAReq->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackAddBAReq( pMac, + &frmAddBAReq, + pAddBAReqBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an ADDBA Req (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an ADDBA Req (0x%08x)."), + nStatus ); + } + + limLog( pMac, LOGW, + FL( "Sending an ADDBA REQ to " )); + limPrintMacAddr( pMac, pMlmAddBAReq->peerMacAddr, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pAddBAReqBuffer, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halStatus)); + if (eHAL_STATUS_SUCCESS != halStatus ) + { + limLog( pMac, LOGE, + FL( "halTxFrame FAILED! Status [%d]"), + halStatus ); + + // FIXME - Need to convert eHalStatus to tSirRetStatus + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + + // Release buffer, if allocated + if( NULL != pAddBAReqBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pAddBAReqBuffer, + (void *) pPacket ); + + return statusCode; +} + +/** + * \brief Send an ADDBA Rsp Action Frame to peer + * + * \sa limSendAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMlmAddBARsp A pointer to tLimMlmAddBARsp. This contains + * the necessary parameters reqd by PE send the ADDBA Rsp Action + * Frame to the peer + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac, + tpLimMlmAddBARsp pMlmAddBARsp, + tpPESession psessionEntry) +{ + tDot11fAddBARsp frmAddBARsp; + tANI_U8 *pAddBARspBuffer = NULL; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!"));) + return eSIR_FAILURE; + } + + vos_mem_set( (void *) &frmAddBARsp, sizeof( frmAddBARsp ), 0); + + // Category - 3 (BA) + frmAddBARsp.Category.category = SIR_MAC_ACTION_BLKACK; + // Action - 1 (ADDBA Rsp) + frmAddBARsp.Action.action = SIR_MAC_BLKACK_ADD_RSP; + + // Should be same as the one we received in the ADDBA Req + frmAddBARsp.DialogToken.token = pMlmAddBARsp->baDialogToken; + + // ADDBA Req status + frmAddBARsp.Status.status = pMlmAddBARsp->addBAResultCode; + + // Fill the ADDBA Parameter Set as provided by caller + frmAddBARsp.AddBAParameterSet.tid = pMlmAddBARsp->baTID; + frmAddBARsp.AddBAParameterSet.policy = pMlmAddBARsp->baPolicy; + frmAddBARsp.AddBAParameterSet.bufferSize = pMlmAddBARsp->baBufferSize; + + if(psessionEntry->isAmsduSupportInAMPDU) + { + frmAddBARsp.AddBAParameterSet.amsduSupported = + psessionEntry->amsduSupportedInBA; + } + else + { + frmAddBARsp.AddBAParameterSet.amsduSupported = 0; + } + + // BA timeout + // 0 - indicates no BA timeout + frmAddBARsp.BATimeout.timeout = pMlmAddBARsp->baTimeout; + + nStatus = dot11fGetPackedAddBARspSize( pMac, &frmAddBARsp, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an ADDBA Response (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddBARsp ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an ADDBA Rsp (0x%08x)."), + nStatus ); + } + + // Need to allocate a buffer for ADDBA AF + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Allocate shared memory + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pAddBARspBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pAddBARspBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pAddBARspBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmAddBARsp->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + + pMacHdr = ( tpSirMacMgmtHdr ) pAddBARspBuffer; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmAddBARsp->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackAddBARsp( pMac, + &frmAddBARsp, + pAddBARspBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an ADDBA Rsp (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an ADDBA Rsp (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending an ADDBA RSP to " )); + limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pAddBARspBuffer, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halStatus)); + if (eHAL_STATUS_SUCCESS != halStatus ) + { + limLog( pMac, LOGE, + FL( "halTxFrame FAILED! Status [%d]" ), + halStatus ); + + // FIXME - HAL error codes are different from PE error + // codes!! And, this routine is returning tSirRetStatus + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + + returnAfterError: + + // Release buffer, if allocated + if( NULL != pAddBARspBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pAddBARspBuffer, + (void *) pPacket ); + + return statusCode; +} + +/** + * \brief Send a DELBA Indication Action Frame to peer + * + * \sa limSendDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param peerMacAddr MAC Address of peer + * + * \param reasonCode Reason for the DELBA notification + * + * \param pBAParameterSet The DELBA Parameter Set. + * This identifies the TID for which the BA session is + * being deleted. + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac, + tpLimMlmDelBAReq pMlmDelBAReq,tpPESession psessionEntry) +{ + tDot11fDelBAInd frmDelBAInd; + tANI_U8 *pDelBAIndBuffer = NULL; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if(NULL == psessionEntry) + { + return eSIR_FAILURE; + } + + smeSessionId = psessionEntry->smeSessionId; + vos_mem_set( (void *) &frmDelBAInd, sizeof( frmDelBAInd ), 0); + + // Category - 3 (BA) + frmDelBAInd.Category.category = SIR_MAC_ACTION_BLKACK; + // Action - 2 (DELBA) + frmDelBAInd.Action.action = SIR_MAC_BLKACK_DEL; + + // Fill the DELBA Parameter Set as provided by caller + frmDelBAInd.DelBAParameterSet.tid = pMlmDelBAReq->baTID; + frmDelBAInd.DelBAParameterSet.initiator = pMlmDelBAReq->baDirection; + + // BA Starting Sequence Number + // Fragment number will always be zero + frmDelBAInd.Reason.code = pMlmDelBAReq->delBAReasonCode; + + nStatus = dot11fGetPackedDelBAIndSize( pMac, &frmDelBAInd, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an DELBA Indication (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelBAInd ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an DELBA Ind (0x%08x)."), + nStatus ); + } + + // Add the MGMT header to frame length + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Allocate shared memory + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pDelBAIndBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pDelBAIndBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pDelBAIndBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmDelBAReq->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pDelBAIndBuffer; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmDelBAReq->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackDelBAInd( pMac, + &frmDelBAInd, + pDelBAIndBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an DELBA Ind (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an DELBA Ind (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending a DELBA IND to " )); + limPrintMacAddr( pMac, pMlmDelBAReq->peerMacAddr, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pDelBAIndBuffer, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halStatus)); + if (eHAL_STATUS_SUCCESS != halStatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halStatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + + returnAfterError: + + // Release buffer, if allocated + if( NULL != pDelBAIndBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pDelBAIndBuffer, + (void *) pPacket ); + + return statusCode; +} + +#if defined WLAN_FEATURE_VOWIFI + +/** + * \brief Send a Neighbor Report Request Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pNeighborReq Address of a tSirMacNeighborReportReq + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendNeighborReportRequestFrame(tpAniSirGlobal pMac, + tpSirMacNeighborReportReq pNeighborReq, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tDot11fNeighborReportRequest frm; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Neighbor Report request action frame") ); + return eSIR_FAILURE; + } + smeSessionId = psessionEntry->smeSessionId; + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_RRM; + frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ; + frm.DialogToken.token = pNeighborReq->dialogToken; + + + if( pNeighborReq->ssid_present ) + { + PopulateDot11fSSID( pMac, &pNeighborReq->ssid, &frm.SSID ); + } + + nStatus = dot11fGetPackedNeighborReportRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Neighbor Report Request(0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fNeighborReportRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Neighbor Rep" + "ort Request(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Neighbor " + "Report Request."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackNeighborReportRequest( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Neighbor Report Request (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Neighbor Report " + "Request (0x%08x)." ), nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending a Neighbor Report Request to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pFrame, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if (eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + + return statusCode; +} // End limSendNeighborReportRequestFrame. + +/** + * \brief Send a Link Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pLinkReport Address of a tSirMacLinkReport + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendLinkReportActionFrame(tpAniSirGlobal pMac, + tpSirMacLinkReport pLinkReport, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tDot11fLinkMeasurementReport frm; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Link Report action frame") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_RRM; + frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT; + frm.DialogToken.token = pLinkReport->dialogToken; + + + //IEEE Std. 802.11 7.3.2.18. for the report element. + //Even though TPC report an IE, it is represented using fixed fields since it is positioned + //in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 + //and frame parser always expects IEs to come after all fixed fields. It is easier to handle + //such case this way than changing the frame parser. + frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID; + frm.TPCEleLen.TPCLen = 2; + frm.TxPower.txPower = pLinkReport->txPower; + frm.LinkMargin.linkMargin = 0; + + frm.RxAntennaId.antennaId = pLinkReport->rxAntenna; + frm.TxAntennaId.antennaId = pLinkReport->txAntenna; + frm.RCPI.rcpi = pLinkReport->rcpi; + frm.RSNI.rsni = pLinkReport->rsni; + + nStatus = dot11fGetPackedLinkMeasurementReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Link Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fLinkMeasurementReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Link Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Link " + "Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackLinkMeasurementReport( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Link Report (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Link Report (0x%08x)." ), + nStatus ); + } + + limLog( pMac, LOGW, + FL( "Sending a Link Report to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if ((SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pFrame, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if (eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + + return statusCode; +} // End limSendLinkReportActionFrame. + +/** + * \brief Send a Beacon Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param dialog_token dialog token to be used in the action frame. + * + * \param num_report number of reports in pRRMReport. + * + * \param pRRMReport Address of a tSirMacRadioMeasureReport. + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendRadioMeasureReportActionFrame(tpAniSirGlobal pMac, + tANI_U8 dialog_token, + tANI_U8 num_report, + tpSirMacRadioMeasureReport pRRMReport, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 i; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + tDot11fRadioMeasurementReport *frm = + vos_mem_malloc(sizeof(tDot11fRadioMeasurementReport)); + if (!frm) { + limLog( pMac, LOGE, FL("Not enough memory to allocate tDot11fRadioMeasurementReport") ); + return eSIR_FAILURE; + } + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Beacon Report action frame") ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + vos_mem_set( ( tANI_U8* )frm, sizeof( *frm ), 0 ); + + frm->Category.category = SIR_MAC_ACTION_RRM; + frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT; + frm->DialogToken.token = dialog_token; + + frm->num_MeasurementReport = (num_report > RADIO_REPORTS_MAX_IN_A_FRAME ) ? RADIO_REPORTS_MAX_IN_A_FRAME : num_report; + + for( i = 0 ; i < frm->num_MeasurementReport ; i++ ) + { + frm->MeasurementReport[i].type = pRRMReport[i].type; + frm->MeasurementReport[i].token = pRRMReport[i].token; + frm->MeasurementReport[i].late = 0; //IEEE 802.11k section 7.3.22. (always zero in rrm) + switch( pRRMReport[i].type ) + { + case SIR_MAC_RRM_BEACON_TYPE: + PopulateDot11fBeaconReport( pMac, &frm->MeasurementReport[i], &pRRMReport[i].report.beaconReport ); + frm->MeasurementReport[i].incapable = pRRMReport[i].incapable; + frm->MeasurementReport[i].refused = pRRMReport[i].refused; + frm->MeasurementReport[i].present = 1; + break; + default: + frm->MeasurementReport[i].incapable = pRRMReport[i].incapable; + frm->MeasurementReport[i].refused = pRRMReport[i].refused; + frm->MeasurementReport[i].present = 1; + break; + } + } + + nStatus = dot11fGetPackedRadioMeasurementReportSize( pMac, frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Radio Measure Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fLinkMeasurementReport ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Radio Measure Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Radio Measure " + "Report."), nBytes ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackRadioMeasurementReport( pMac, + frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Radio Measure Report (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Radio " + "Measure Report (0x%08x)." ), nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending a Radio Measure Report to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pFrame, txFlag, smeSessionId); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if (eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + vos_mem_free(frm); + return statusCode; + } + else + { + vos_mem_free(frm); + return eSIR_SUCCESS; + } + +returnAfterError: + vos_mem_free(frm); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return statusCode; +} // End limSendBeaconReportActionFrame. + +#endif + +#ifdef WLAN_FEATURE_11W +/** + * \brief Send SA query request action frame to peer + * + * \sa limSendSaQueryRequestFrame + * + * + * \param pMac The global tpAniSirGlobal object + * + * \param transId Transaction identifier + * + * \param peer The Mac address of the station to which this action frame is addressed + * + * \param psessionEntry The PE session entry + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +tSirRetStatus limSendSaQueryRequestFrame( tpAniSirGlobal pMac, tANI_U8 *transId, + tSirMacAddr peer, tpPESession psessionEntry ) +{ + + tDot11fSaQueryReq frm; // SA query request action frame + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + frm.Category.category = SIR_MAC_ACTION_SA_QUERY; + /* 11w action field is : + action: 0 --> SA Query Request action frame + action: 1 --> SA Query Response action frame */ + frm.Action.action = SIR_MAC_SA_QUERY_REQ; + /* 11w SA Query Request transId */ + vos_mem_copy( &frm.TransactionId.transId[0], &transId[0], 2 ); + + nStatus = dot11fGetPackedSaQueryReqSize(pMac, &frm, &nPayload); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size " + "for an SA Query Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fSaQueryReq ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an SA Query Request" + " (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a SA Query Request " + "action frame"), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr ); + if ( eSIR_SUCCESS != nSirStatus ) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + + // Since this is a SA Query Request, set the "protect" (aka WEP) bit + // in the FC + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); + + // Pack 11w SA Query Request frame + nStatus = dot11fPackSaQueryReq( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if ( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an SA Query Request (0x%08x)." ), + nStatus ); + // FIXME - Need to convert to tSirRetStatus + nSirStatus = eSIR_FAILURE; + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing SA Query Request (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, + FL( "Sending an SA Query Request to " )); + limPrintMacAddr( pMac, peer, LOG1 ); + limLog( pMac, LOG1, + FL( "Sending an SA Query Request from " )); + limPrintMacAddr( pMac, psessionEntry->selfMacAddr, LOG1 ); + + if ( ( SIR_BAND_5_GHZ == limGetRFBand( psessionEntry->currentOperChannel ) ) +#ifdef WLAN_FEATURE_P2P + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE ) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + smeSessionId = psessionEntry->smeSessionId; + + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pFrame, txFlag, smeSessionId); + if ( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + nSirStatus = eSIR_FAILURE; + //Pkt will be freed up by the callback + return nSirStatus; + } + else { + return eSIR_SUCCESS; + } + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; +} // End limSendSaQueryRequestFrame + +/** + * \brief Send SA query response action frame to peer + * + * \sa limSendSaQueryResponseFrame + * + * + * \param pMac The global tpAniSirGlobal object + * + * \param transId Transaction identifier received in SA query request action frame + * + * \param peer The Mac address of the AP to which this action frame is addressed + * + * \param psessionEntry The PE session entry + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, tANI_U8 *transId, +tSirMacAddr peer,tpPESession psessionEntry) +{ + + tDot11fSaQueryRsp frm; // SA query reponse action frame + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 smeSessionId = 0; + + smeSessionId = psessionEntry->smeSessionId; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + frm.Category.category = SIR_MAC_ACTION_SA_QUERY; + /*11w action field is : + action: 0 --> SA query request action frame + action: 1 --> SA query response action frame */ + frm.Action.action = SIR_MAC_SA_QUERY_RSP; + /*11w SA query response transId is same as + SA query request transId*/ + vos_mem_copy( &frm.TransactionId.transId[0], &transId[0], 2 ); + + nStatus = dot11fGetPackedSaQueryRspSize(pMac, &frm, &nPayload); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a SA Query Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fSaQueryRsp ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an SA Query Response" + " (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a SA query response" + " action frame"), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr ); + if ( eSIR_SUCCESS != nSirStatus ) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + + // Since this is a SA Query Response, set the "protect" (aka WEP) bit + // in the FC + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); + + // Pack 11w SA query response frame + nStatus = dot11fPackSaQueryRsp( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if ( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an SA Query Response (0x%08x)." ), + nStatus ); + // FIXME - Need to convert to tSirRetStatus + nSirStatus = eSIR_FAILURE; + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing SA Query Response (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, + FL( "Sending a SA Query Response to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if ( ( SIR_BAND_5_GHZ == limGetRFBand( psessionEntry->currentOperChannel ) ) +#ifdef WLAN_FEATURE_P2P + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE ) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, + limTxComplete, + pFrame, txFlag, smeSessionId ); + MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, halstatus)); + if ( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + nSirStatus = eSIR_FAILURE; + //Pkt will be freed up by the callback + return nSirStatus; + } + else { + return eSIR_SUCCESS; + } + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; +} // End limSendSaQueryResponseFrame +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.c new file mode 100644 index 0000000000000..834d15f14af5e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.c @@ -0,0 +1,948 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * limSendMessages.c: Provides functions to send messages or Indications to HAL. + * Author: Sunit Bhatia + * Date: 09/21/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ +#include "limSendMessages.h" +#include "cfgApi.h" +#include "limTrace.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +/* When beacon filtering is enabled, firmware will + * analyze the selected beacons received during BMPS, + * and monitor any changes in the IEs as listed below. + * The format of the table is: + * - EID + * - Check for IE presence + * - Byte offset + * - Byte value + * - Bit Mask + * - Byte refrence + */ +static tBeaconFilterIe beaconFilterTable[] = { + {SIR_MAC_DS_PARAM_SET_EID, 0, {0, 0, DS_PARAM_CHANNEL_MASK, 0}}, + {SIR_MAC_ERP_INFO_EID, 0, {0, 0, ERP_FILTER_MASK, 0}}, + {SIR_MAC_EDCA_PARAM_SET_EID, 0, {0, 0, EDCA_FILTER_MASK, 0}}, + {SIR_MAC_QOS_CAPABILITY_EID, 0, {0, 0, QOS_FILTER_MASK, 0}}, + {SIR_MAC_CHNL_SWITCH_ANN_EID, 1, {0, 0, 0, 0}}, + {SIR_MAC_HT_INFO_EID, 0, {0, 0, HT_BYTE0_FILTER_MASK, 0}}, + {SIR_MAC_HT_INFO_EID, 0, {2, 0, HT_BYTE2_FILTER_MASK, 0}}, + {SIR_MAC_HT_INFO_EID, 0, {5, 0, HT_BYTE5_FILTER_MASK, 0}} +#if defined WLAN_FEATURE_VOWIFI + ,{SIR_MAC_PWR_CONSTRAINT_EID, 0, {0, 0, 0, 0}} +#endif +#ifdef WLAN_FEATURE_11AC + ,{SIR_MAC_VHT_OPMODE_EID, 0, {0, 0, 0, 0}} + ,{SIR_MAC_VHT_OPERATION_EID, 0, {0, 0, VHTOP_CHWIDTH_MASK, 0}} +#endif +}; + +/** + * limSendCFParams() + * + *FUNCTION: + * This function is called to send CFP Parameters to WDA, when they are changed. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param bssIdx Bss Index of the BSS to which STA is associated. + * @param cfpCount CFP Count, if that is changed. + * @param cfpPeriod CFP Period if that is changed. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod) +{ + tpUpdateCFParams pCFParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pCFParams = vos_mem_malloc(sizeof( tUpdateCFParams )); + if ( NULL == pCFParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update CF Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + vos_mem_set( (tANI_U8 *) pCFParams, sizeof(tUpdateCFParams), 0); + pCFParams->cfpCount = cfpCount; + pCFParams->cfpPeriod = cfpPeriod; + pCFParams->bssIdx = bssIdx; + + msgQ.type = WDA_UPDATE_CF_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pCFParams; + msgQ.bodyval = 0; + limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_CF_IND..." )); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pCFParams); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_CF_IND to WDA failed, reason=%X"), + retCode ); + } +returnFailure: + return retCode; +} + +/** + * limSendBeaconParams() + * + *FUNCTION: + * This function is called to send beacnon interval, short preamble or other + * parameters to WDA, which are changed and indication is received in beacon. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param tpUpdateBeaconParams pointer to the structure, + which contains the beacon parameters which are changed. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, + tpUpdateBeaconParams pUpdatedBcnParams, + tpPESession psessionEntry ) +{ + tpUpdateBeaconParams pBcnParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pBcnParams = vos_mem_malloc(sizeof(*pBcnParams)); + if ( NULL == pBcnParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Beacon Params" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *) pBcnParams, pUpdatedBcnParams, sizeof(*pBcnParams)); + msgQ.type = WDA_UPDATE_BEACON_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pBcnParams; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_BEACON_IND, paramChangeBitmap in hex = %x" ), + pUpdatedBcnParams->paramChangeBitmap);) + if(NULL == psessionEntry) + { + vos_mem_free(pBcnParams); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + return eSIR_FAILURE; + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + pBcnParams->smeSessionId = psessionEntry->smeSessionId; + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBcnParams); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_BEACON_IND to WDA failed, reason=%X"), + retCode ); + } + limSendBeaconInd(pMac, psessionEntry); + return retCode; +} + +/** + * limSendSwitchChnlParams() + * + *FUNCTION: + * This function is called to send Channel Switch Indication to WDA + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param chnlNumber New Channel Number to be switched to. + * @param secondaryChnlOffset an enum for secondary channel offset. + * @param localPowerConstraint 11h local power constraint value + * + * @return success if message send is ok, else false. + */ +#if !defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, + tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tANI_U8 localPwrConstraint, tANI_U8 peSessionId) +#else +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, + tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tPowerdBm maxTxPower, tANI_U8 peSessionId) +#endif +{ + tpSwitchChannelParams pChnlParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpPESession pSessionEntry; + if((pSessionEntry = peFindSessionBySessionId(pMac, peSessionId)) == NULL) + { + limLog( pMac, LOGP, + FL( "Unable to get Session for session Id %d" ), peSessionId); + return eSIR_FAILURE; + } + pChnlParams = vos_mem_malloc(sizeof( tSwitchChannelParams )); + if ( NULL == pChnlParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Switch Channel Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + vos_mem_set((tANI_U8 *) pChnlParams, sizeof(tSwitchChannelParams), 0); + pChnlParams->secondaryChannelOffset = secondaryChnlOffset; + pChnlParams->channelNumber= chnlNumber; + vos_mem_copy( pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) ); +#if defined WLAN_FEATURE_VOWIFI + pChnlParams->maxTxPower = maxTxPower; +#else + pChnlParams->localPowerConstraint = localPwrConstraint; +#endif + vos_mem_copy( pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) ); + pChnlParams->peSessionId = peSessionId; + pChnlParams->vhtCapable = pSessionEntry->vhtCapability; + pChnlParams->dot11_mode = pSessionEntry->dot11mode; + + /*Set DFS flag for DFS channel*/ + if (vos_nv_getChannelEnabledState(chnlNumber) == NV_CHANNEL_DFS) + pChnlParams->isDfsChannel= VOS_TRUE; + else + pChnlParams->isDfsChannel = VOS_FALSE; + + //we need to defer the message until we get the response back from WDA. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + msgQ.type = WDA_CHNL_SWITCH_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pChnlParams; + msgQ.bodyval = 0; +#if defined WLAN_FEATURE_VOWIFI + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, maxTxPower - %d"), + pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->maxTxPower);) +#else + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, LocalPowerConstraint - %d"), + pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->localPowerConstraint);) +#endif + MTRACE(macTraceMsgTx(pMac, peSessionId, msgQ.type)); + limLog(pMac,LOG1,"SessionId:%d WDA_CHNL_SWITCH_REQ for SSID:%s",peSessionId, + pSessionEntry->ssId.ssId); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pChnlParams); + limLog(pMac, LOGP, + FL("Posting WDA_CHNL_SWITCH_REQ to WDA failed, reason=%X"), + retCode ); + } +returnFailure: + return retCode; +} + +/** + * limSendEdcaParams() + * + *FUNCTION: + * This function is called to send dynamically changing EDCA Parameters to WDA. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param tpUpdatedEdcaParams pointer to the structure which contains + * dynamically changing EDCA parameters. + * @param highPerformance If the peer is Airgo (taurus) then switch to highPerformance is true. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance) +{ + tEdcaParams *pEdcaParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pEdcaParams = vos_mem_malloc(sizeof(tEdcaParams)); + if ( NULL == pEdcaParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update EDCA Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + return retCode; + } + pEdcaParams->bssIdx = bssIdx; + pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE]; + pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK]; + pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI]; + pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO]; + pEdcaParams->highPerformance = highPerformance; + msgQ.type = WDA_UPDATE_EDCA_PROFILE_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pEdcaParams; + msgQ.bodyval = 0; + { + tANI_U8 i; + PELOG1(limLog( pMac, LOG1,FL("Sending WDA_UPDATE_EDCA_PROFILE_IND with EDCA Parameters:" ));) + for(i=0; igLimEdcaParamsActive[EDCA_AC_BE] = plocalEdcaParams[EDCA_AC_BE]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK] = plocalEdcaParams[EDCA_AC_BK]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI] = plocalEdcaParams[EDCA_AC_VI]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO] = plocalEdcaParams[EDCA_AC_VO]; + /* An AC requires downgrade if the ACM bit is set, and the AC has not + * yet been admitted in uplink or bi-directions. + * If an AC requires downgrade, it will downgrade to the next beset AC + * for which ACM is not enabled. + * + * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence + * start the for loop with AC_BK. + * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then + * traverse thru the AC list. If we do find the next best AC which is + * better than AC_BE, then use that one. For example, if ACM bits are set + * such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0 + * then all AC will be downgraded to AC_BE. + */ + if(!pMac->psOffloadEnabled) + { + limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "), + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] ); + limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "), + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] ); + } + else + { + limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "), + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] ); + limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "), + psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] ); + } + for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++) + { + if(!pMac->psOffloadEnabled) + { + acAdmitted = ( (pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & + (1 << ac)) >> ac ); + } + else + { + acAdmitted = + ((psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & + (1 << ac)) >> ac ); + } + + limLog(pMac, LOG1, FL("For AC[%d]: acm=%d, acAdmit=%d "), ac, plocalEdcaParams[ac].aci.acm, acAdmitted); + if ( (plocalEdcaParams[ac].aci.acm == 1) && (acAdmitted == 0) ) + { + limLog(pMac, LOG1, FL("We need to downgrade AC %d!! "), ac); + newAc = EDCA_AC_BE; + for (i=ac-1; i>0; i--) + { + if (plocalEdcaParams[i].aci.acm == 0) + { + newAc = i; + break; + } + } + limLog(pMac, LOGW, FL("Downgrading AC %d ---> AC %d "), ac, newAc); + psessionEntry->gLimEdcaParamsActive[ac] = plocalEdcaParams[newAc]; + } + } +//log: LOG_WLAN_QOS_EDCA_C +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C); + if(log_ptr) + { + log_ptr->aci_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].aci.aci; + log_ptr->cw_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.min; + log_ptr->txoplimit_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].txoplimit; + log_ptr->aci_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].aci.aci; + log_ptr->cw_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.min; + log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].txoplimit; + log_ptr->aci_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].aci.aci; + log_ptr->cw_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.min; + log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].txoplimit; + log_ptr->aci_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].aci.aci; + log_ptr->cw_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.min; + log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].txoplimit; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + return; + } + +/** --------------------------------------------------------- +\fn limSetLinkState +\brief LIM sends a message to WDA to set the link state +\param tpAniSirGlobal pMac +\param tSirLinkState state +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId, + tSirMacAddr selfMacAddr, tpSetLinkStateCallback callback, + void *callbackArg) +{ + tSirMsgQ msgQ; + tSirRetStatus retCode; + tpLinkStateParams pLinkStateParams = NULL; + // Allocate memory. + pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams)); + if ( NULL == pLinkStateParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory while sending Set Link State" )); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + return retCode; + } + vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0); + pLinkStateParams->state = state; + pLinkStateParams->callback = callback; + pLinkStateParams->callbackArg = callbackArg; + + /* Copy Mac address */ + sirCopyMacAddr(pLinkStateParams->bssid,bssId); + sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr); + + msgQ.type = WDA_SET_LINK_STATE; + msgQ.reserved = 0; + msgQ.bodyptr = pLinkStateParams; + msgQ.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ); + if (retCode != eSIR_SUCCESS) + { + vos_mem_free(pLinkStateParams); + limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), + state, retCode); + } + return retCode; +} +#ifdef WLAN_FEATURE_VOWIFI_11R +extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState +state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tSirRetStatus retCode; + tpLinkStateParams pLinkStateParams = NULL; + // Allocate memory. + pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams)); + if ( NULL == pLinkStateParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory while sending Set Link State" )); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + return retCode; + } + vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0); + pLinkStateParams->state = state; + /* Copy Mac address */ + sirCopyMacAddr(pLinkStateParams->bssid,bssId); + sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr); + pLinkStateParams->ft = 1; + pLinkStateParams->session = psessionEntry; + + msgQ.type = WDA_SET_LINK_STATE; + msgQ.reserved = 0; + msgQ.bodyptr = pLinkStateParams; + msgQ.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + + retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ); + if (retCode != eSIR_SUCCESS) + { + vos_mem_free(pLinkStateParams); + limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), + state, retCode); + } + return retCode; +} +#endif + +/** --------------------------------------------------------- +\fn limSendSetTxPowerReq +\brief LIM sends a WDA_SET_TX_POWER_REQ message to WDA +\param tpAniSirGlobal pMac +\param tpSirSetTxPowerReq request message +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSetTxPowerReq *txPowerReq; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + + if (NULL == pMsgBuf) + return eSIR_FAILURE; + + txPowerReq = vos_mem_malloc(sizeof(tSirSetTxPowerReq)); + if ( NULL == txPowerReq ) + { + return eSIR_FAILURE; + } + vos_mem_copy(txPowerReq, (tSirSetTxPowerReq *)pMsgBuf, sizeof(tSirSetTxPowerReq)); + + /* Found corresponding seesion to find BSS IDX */ + psessionEntry = peFindSessionByBssid(pMac, txPowerReq->bssId, &sessionId); + if (NULL == psessionEntry) + { + vos_mem_free(txPowerReq); + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return eSIR_FAILURE; + } + + /* FW API requests BSS IDX */ + txPowerReq->bssIdx = psessionEntry->bssIdx; + + msgQ.type = WDA_SET_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = txPowerReq; + msgQ.bodyval = 0; + PELOGW(limLog(pMac, LOGW, FL("Sending WDA_SET_TX_POWER_REQ to WDA"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + limLog(pMac, LOGP, FL("Posting WDA_SET_TX_POWER_REQ to WDA failed, reason=%X"), retCode); + vos_mem_free(txPowerReq); + return retCode; + } + + return retCode; +} +/** --------------------------------------------------------- +\fn limSendGetTxPowerReq +\brief LIM sends a WDA_GET_TX_POWER_REQ message to WDA +\param tpAniSirGlobal pMac +\param tpSirGetTxPowerReq request message +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + if (NULL == pTxPowerReq) + return retCode; + msgQ.type = WDA_GET_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pTxPowerReq; + msgQ.bodyval = 0; + PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_GET_TX_POWER_REQ to WDA"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGP, FL("Posting WDA_GET_TX_POWER_REQ to WDA failed, reason=%X"), retCode ); + if (NULL != pTxPowerReq) + { + vos_mem_free(pTxPowerReq); + } + return retCode; + } + return retCode; +} +/** --------------------------------------------------------- +\fn limSendBeaconFilterInfo +\brief LIM sends beacon filtering info to WDA +\param tpAniSirGlobal pMac +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tpBeaconFilterMsg pBeaconFilterMsg = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tANI_U8 *ptr; + tANI_U32 i; + tANI_U32 msgSize; + tpBeaconFilterIe pIe; + + if( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("Fail to find the right session ")); + retCode = eSIR_FAILURE; + return retCode; + } + msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable); + pBeaconFilterMsg = vos_mem_malloc(msgSize); + if ( NULL == pBeaconFilterMsg ) + { + limLog( pMac, LOGP, FL("Fail to allocate memory for beaconFiilterMsg ")); + retCode = eSIR_MEM_ALLOC_FAILED; + return retCode; + } + vos_mem_set((tANI_U8 *) pBeaconFilterMsg, msgSize, 0); + // Fill in capability Info and mask + //TBD-RAJESH get the BSS capability from session. + //Don't send this message if no active Infra session is found. + pBeaconFilterMsg->capabilityInfo = psessionEntry->limCurrentBssCaps; + pBeaconFilterMsg->capabilityMask = CAPABILITY_FILTER_MASK; + pBeaconFilterMsg->beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval; + // Fill in number of IEs in beaconFilterTable + pBeaconFilterMsg->ieNum = (tANI_U16) (sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe)); + //Fill the BSSIDX + pBeaconFilterMsg->bssIdx = psessionEntry->bssIdx; + + //Fill message with info contained in the beaconFilterTable + ptr = (tANI_U8 *)pBeaconFilterMsg + sizeof(tBeaconFilterMsg); + for(i=0; i < (pBeaconFilterMsg->ieNum); i++) + { + pIe = (tpBeaconFilterIe) ptr; + pIe->elementId = beaconFilterTable[i].elementId; + pIe->checkIePresence = beaconFilterTable[i].checkIePresence; + pIe->byte.offset = beaconFilterTable[i].byte.offset; + pIe->byte.value = beaconFilterTable[i].byte.value; + pIe->byte.bitMask = beaconFilterTable[i].byte.bitMask; + pIe->byte.ref = beaconFilterTable[i].byte.ref; + ptr += sizeof(tBeaconFilterIe); + } + msgQ.type = WDA_BEACON_FILTER_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pBeaconFilterMsg; + msgQ.bodyval = 0; + limLog( pMac, LOG3, FL( "Sending WDA_BEACON_FILTER_IND..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBeaconFilterMsg); + limLog( pMac, LOGP, + FL("Posting WDA_BEACON_FILTER_IND to WDA failed, reason=%X"), + retCode ); + return retCode; + } + return retCode; +} + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limSendModeUpdate(tpAniSirGlobal pMac, + tUpdateVHTOpMode *pTempParam, + tpPESession psessionEntry ) +{ + tUpdateVHTOpMode *pVhtOpMode = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pVhtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode)); + if ( NULL == pVhtOpMode ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Op Mode" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *)pVhtOpMode, pTempParam, sizeof(tUpdateVHTOpMode)); + msgQ.type = WDA_UPDATE_OP_MODE; + msgQ.reserved = 0; + msgQ.bodyptr = pVhtOpMode; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_OP_MODE" ));) + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pVhtOpMode); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_OP_MODE to WDA failed, reason=%X"), + retCode ); + } + + return retCode; +} + +tSirRetStatus limSendRxNssUpdate(tpAniSirGlobal pMac, + tUpdateRxNss *pTempParam, + tpPESession psessionEntry ) +{ + tUpdateRxNss *pRxNss = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pRxNss = vos_mem_malloc(sizeof(tUpdateRxNss)); + if ( NULL == pRxNss ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Rx Nss" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *)pRxNss, pTempParam, sizeof(tUpdateRxNss)); + msgQ.type = WDA_UPDATE_RX_NSS; + msgQ.reserved = 0; + msgQ.bodyptr = pRxNss; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_RX_NSS" ));) + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pRxNss); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_RX_NSS to WDA failed, reason=%X"), + retCode ); + } + + return retCode; +} + +tSirRetStatus limSetMembership(tpAniSirGlobal pMac, + tUpdateMembership *pTempParam, + tpPESession psessionEntry ) +{ + tUpdateMembership *pMembership = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pMembership = vos_mem_malloc(sizeof(tUpdateMembership)); + if ( NULL == pMembership ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Membership Mode" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *)pMembership, pTempParam, sizeof(tUpdateMembership)); + + msgQ.type = WDA_UPDATE_MEMBERSHIP; + msgQ.reserved = 0; + msgQ.bodyptr = pMembership; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_MEMBERSHIP" ));) + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pMembership); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_MEMBERSHIP to WDA failed, reason=%X"), + retCode ); + } + + return retCode; +} + +tSirRetStatus limSetUserPos(tpAniSirGlobal pMac, + tUpdateUserPos *pTempParam, + tpPESession psessionEntry ) +{ + tUpdateUserPos *pUserPos = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pUserPos = vos_mem_malloc(sizeof(tUpdateUserPos)); + if ( NULL == pUserPos ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update User Position" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *)pUserPos, pTempParam, sizeof(tUpdateUserPos)); + + msgQ.type = WDA_UPDATE_USERPOS; + msgQ.reserved = 0; + msgQ.bodyptr = pUserPos; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_USERPOS" ));) + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pUserPos); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_USERPOS to WDA failed, reason=%X"), + retCode ); + } + + return retCode; +} + +#endif + + +#ifdef WLAN_FEATURE_11W +/** --------------------------------------------------------- +\fn limSendExcludeUnencryptInd +\brief LIM sends a message to HAL to indicate whether to + ignore or indicate the unprotected packet error +\param tpAniSirGlobal pMac +\param tANI_BOOLEAN excludeUnenc - true: ignore, false: + indicate +\param tpPESession psessionEntry - session context +\return status + -----------------------------------------------------------*/ +tSirRetStatus limSendExcludeUnencryptInd(tpAniSirGlobal pMac, + tANI_BOOLEAN excludeUnenc, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tSirWlanExcludeUnencryptParam * pExcludeUnencryptParam; + + pExcludeUnencryptParam = vos_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam)); + if ( NULL == pExcludeUnencryptParam ) + { + limLog(pMac, LOGP, + FL( "Unable to allocate memory during limSendExcludeUnencryptInd")); + return eSIR_MEM_ALLOC_FAILED; + } + + pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc; + sirCopyMacAddr(pExcludeUnencryptParam->bssId, psessionEntry->bssId); + + msgQ.type = WDA_EXCLUDE_UNENCRYPTED_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pExcludeUnencryptParam; + msgQ.bodyval = 0; + PELOG3(limLog(pMac, LOG3, + FL("Sending WDA_EXCLUDE_UNENCRYPTED_IND"));) + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + vos_mem_free(pExcludeUnencryptParam); + limLog(pMac, LOGP, + FL("Posting WDA_EXCLUDE_UNENCRYPTED_IND to WDA failed, reason=%X"), + retCode); + } + + return retCode; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.h new file mode 100644 index 0000000000000..5258cae97bbdd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendMessages.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * limSendMessages.h: Provides functions to send messages or Indications to HAL. + * Author: Sunit Bhatia + * Date: 09/21/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ +#ifndef __LIM_SEND_MESSAGES_H +#define __LIM_SEND_MESSAGES_H + +#include "aniGlobal.h" +#include "limTypes.h" +#include "halMsgApi.h" +#include "sirParams.h" +tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod); +tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, + tpUpdateBeaconParams pUpdatedBcnParams, + tpPESession psessionEntry ); +//tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, tpUpdateBeaconParams pUpdatedBcnParams); +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limSendModeUpdate(tpAniSirGlobal pMac, + tUpdateVHTOpMode *tempParam, + tpPESession psessionEntry ); +tSirRetStatus limSendRxNssUpdate(tpAniSirGlobal pMac, + tUpdateRxNss *tempParam, + tpPESession psessionEntry ); + +tANI_U32 limGetCenterChannel(tpAniSirGlobal pMac, + tANI_U8 primarychanNum, + ePhyChanBondState secondaryChanOffset, + tANI_U8 chanWidth); + +tSirRetStatus limSetMembership(tpAniSirGlobal pMac, + tUpdateMembership *pTempParam, + tpPESession psessionEntry ); + +tSirRetStatus limSetUserPos(tpAniSirGlobal pMac, + tUpdateUserPos *pTempParam, + tpPESession psessionEntry ); +#endif +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tPowerdBm maxTxPower,tANI_U8 peSessionId); +#else +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tANI_U8 localPwrConstraint,tANI_U8 peSessionId); +#endif +tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance); +tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state, tSirMacAddr bssId, + tSirMacAddr selfMac, tpSetLinkStateCallback callback, + void *callbackArg); +#ifdef WLAN_FEATURE_VOWIFI_11R +extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState +state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry); +#endif +tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tANI_U32 *pTxPowerReq); +tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq); +void limSetActiveEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *plocalEdcaParams, tpPESession psessionEntry); +#define CAPABILITY_FILTER_MASK 0x73CF +#define ERP_FILTER_MASK 0xF8 +#define EDCA_FILTER_MASK 0xF0 +#define QOS_FILTER_MASK 0xF0 +#define HT_BYTE0_FILTER_MASK 0x0 +#define HT_BYTE2_FILTER_MASK 0xEB +#define HT_BYTE5_FILTER_MASK 0xFD +#define DS_PARAM_CHANNEL_MASK 0x0 +#define VHTOP_CHWIDTH_MASK 0xFC + +tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac, tpPESession psessionEntry); + +#ifdef WLAN_FEATURE_11W +tSirRetStatus limSendExcludeUnencryptInd(tpAniSirGlobal pMac, + tANI_BOOLEAN excludeUnenc, + tpPESession psessionEntry ); +#endif +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c new file mode 100644 index 0000000000000..6a0db8366ba56 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -0,0 +1,3282 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limSendSmeRspMessages.cc contains the functions + * for sending SME response/notification messages to applications + * above MAC software. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "vos_types.h" +#include "wniApi.h" +#include "sirCommon.h" +#include "aniGlobal.h" + +#include "wniCfgSta.h" +#include "sysDef.h" +#include "cfgApi.h" + + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendSmeRspMessages.h" +#include "limIbssPeerMgmt.h" +#include "limSessionUtils.h" + +#include "sirApi.h" + +/** + * limRemoveSsidFromScanCache() + * + *FUNCTION: + * This function is called by limSendSmeLfrScanRsp() to clean given + * ssid from scan cache. + * + *PARAMS: + * @param pMac Pointer to Global MAC structure + * @param pSsid SSID to clean from scan list + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @return entriesLeft Number of SSID left in scan cache + */ +tANI_S16 limRemoveSsidFromScanCache(tpAniSirGlobal pMac, tSirMacSSid *pSsid) +{ + tANI_U16 i = 0; + tLimScanResultNode *pCurr = NULL; + tLimScanResultNode *pPrev = NULL; + tANI_S16 entriesLeft = 0; + + if (pSsid == NULL) + { + limLog(pMac, LOGW, FL("pSsid is NULL")); + return -1; + } + + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if (pMac->lim.gLimCachedScanHashTable[i] != NULL) + { + pPrev = pMac->lim.gLimCachedScanHashTable[i]; + pCurr = pPrev->next; + while (pCurr) + { + entriesLeft++; + if (vos_mem_compare((tANI_U8* ) pCurr->bssDescription.ieFields+1, + (tANI_U8 *) &pSsid->length, + (tANI_U8) (pSsid->length + 1)) == VOS_TRUE) + { + pCurr=pCurr->next; + vos_mem_free(pPrev->next); + pPrev->next = pCurr; + entriesLeft--; + } + else + { + pCurr = pCurr->next; + pPrev = pPrev->next; + } + } /* while(pCurr) */ + pCurr = pMac->lim.gLimCachedScanHashTable[i]; + if (vos_mem_compare((tANI_U8* ) pCurr->bssDescription.ieFields+1, + (tANI_U8 *) &pSsid->length, + (tANI_U8) (pSsid->length + 1)) == VOS_TRUE) + { + pMac->lim.gLimCachedScanHashTable[i] = pMac->lim.gLimCachedScanHashTable[i]->next; + vos_mem_free(pCurr); + } + else + { + entriesLeft++; + } + } /* if( pMac->lim.gLimCachedScanHashTable[i] != NULL) */ + } /* for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) */ + return entriesLeft; +} + +/** + * limSendSmeRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_START_RSP, eWNI_SME_MEASUREMENT_RSP, eWNI_SME_STOP_BSS_RSP + * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeRsp(tpAniSirGlobal pMac, tANI_U16 msgType, + tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tSirMsgQ mmhMsg; + tSirSmeRsp *pSirSmeRsp; + + PELOG1(limLog(pMac, LOG1, + FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode));) + + pSirSmeRsp = vos_mem_malloc(sizeof(tSirSmeRsp)); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_*_RSP")); + + return; + } + + pSirSmeRsp->messageType = msgType; + pSirSmeRsp->length = sizeof(tSirSmeRsp); + pSirSmeRsp->statusCode = resultCode; + + /* Update SME session Id and Transaction Id */ + pSirSmeRsp->sessionId = smesessionId; + pSirSmeRsp->transactionId = smetransactionId; + + + mmhMsg.type = msgType; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, smesessionId, mmhMsg.type)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + { + tpPESession psessionEntry = peGetValidPowerSaveSession(pMac); + switch(msgType) + { + case eWNI_PMC_ENTER_BMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_BMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_IMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_IMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_UAPSD_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_UAPSD_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_SME_SWITCH_CHL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); + break; + case eWNI_SME_STOP_BSS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_WOWL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_WOWL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeRsp() ***/ + + +/** + * limSendSmeJoinReassocRspAfterResume() + * + *FUNCTION: + * This function is called to send Join/Reassoc rsp + * message to SME after the resume link. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param status Resume link status + * @param ctx context passed while calling resmune link. + * (join response to be sent) + * + * @return None + */ +static void limSendSmeJoinReassocRspAfterResume( tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *ctx) +{ + tSirMsgQ mmhMsg; + tpSirSmeJoinRsp pSirSmeJoinRsp = (tpSirSmeJoinRsp) ctx; + + mmhMsg.type = pSirSmeJoinRsp->messageType; + mmhMsg.bodyptr = pSirSmeJoinRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + + +/** + * limSendSmeJoinReassocRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications + * above MAC Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeJoinReassocRsp(tpAniSirGlobal pMac, tANI_U16 msgType, + tSirResultCodes resultCode, tANI_U16 protStatusCode, + tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + tpSirSmeJoinRsp pSirSmeJoinRsp; + tANI_U32 rspLen; + tpDphHashNode pStaDs = NULL; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + if (msgType == eWNI_SME_REASSOC_RSP) + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + else + limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + PELOG1(limLog(pMac, LOG1, + FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode));) + + if(psessionEntry == NULL) + { + + rspLen = sizeof(tSirSmeJoinRsp); + + pSirSmeJoinRsp = vos_mem_malloc(rspLen); + if ( NULL == pSirSmeJoinRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + return; + } + + vos_mem_set((tANI_U8*)pSirSmeJoinRsp, rspLen, 0); + + + pSirSmeJoinRsp->beaconLength = 0; + pSirSmeJoinRsp->assocReqLength = 0; + pSirSmeJoinRsp->assocRspLength = 0; + } + + else + { + rspLen = psessionEntry->assocReqLen + psessionEntry->assocRspLen + + psessionEntry->bcnLen + +#ifdef WLAN_FEATURE_VOWIFI_11R + psessionEntry->RICDataLen + +#endif +#ifdef FEATURE_WLAN_ESE + psessionEntry->tspecLen + +#endif + sizeof(tSirSmeJoinRsp) - sizeof(tANI_U8) ; + + pSirSmeJoinRsp = vos_mem_malloc(rspLen); + if ( NULL == pSirSmeJoinRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + + return; + } + + vos_mem_set((tANI_U8*)pSirSmeJoinRsp, rspLen, 0); + + if (resultCode == eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("could not Get Self Entry for the station"));) + } + else + { + //Pass the peer's staId + pSirSmeJoinRsp->staId = pStaDs->staIndex; + pSirSmeJoinRsp->ucastSig = pStaDs->ucUcastSig; + pSirSmeJoinRsp->bcastSig = pStaDs->ucBcastSig; + pSirSmeJoinRsp->timingMeasCap = pStaDs->timingMeasCap; +#ifdef FEATURE_WLAN_TDLS + pSirSmeJoinRsp->tdls_prohibited = + psessionEntry->tdls_prohibited; + pSirSmeJoinRsp->tdls_chan_swit_prohibited = + psessionEntry->tdls_chan_swit_prohibited; +#endif + } + } + + pSirSmeJoinRsp->beaconLength = 0; + pSirSmeJoinRsp->assocReqLength = 0; + pSirSmeJoinRsp->assocRspLength = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + pSirSmeJoinRsp->parsedRicRspLen = 0; +#endif +#ifdef FEATURE_WLAN_ESE + pSirSmeJoinRsp->tspecIeLen = 0; +#endif + + if(resultCode == eSIR_SME_SUCCESS) + { + + if(psessionEntry->beacon != NULL) + { + pSirSmeJoinRsp->beaconLength = psessionEntry->bcnLen; + vos_mem_copy( pSirSmeJoinRsp->frames, psessionEntry->beacon, + pSirSmeJoinRsp->beaconLength); + vos_mem_free( psessionEntry->beacon); + psessionEntry->beacon = NULL; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("Beacon=%d"), psessionEntry->bcnLen);) +#endif + } + + if(psessionEntry->assocReq != NULL) + { + pSirSmeJoinRsp->assocReqLength = psessionEntry->assocReqLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen, + psessionEntry->assocReq, pSirSmeJoinRsp->assocReqLength); + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("AssocReq=%d"), psessionEntry->assocReqLen);) +#endif + } + if(psessionEntry->assocRsp != NULL) + { + pSirSmeJoinRsp->assocRspLength = psessionEntry->assocRspLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen, + psessionEntry->assocRsp, + pSirSmeJoinRsp->assocRspLength); + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if(psessionEntry->ricData != NULL) + { + pSirSmeJoinRsp->parsedRicRspLen = psessionEntry->RICDataLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen + psessionEntry->assocRspLen, + psessionEntry->ricData, pSirSmeJoinRsp->parsedRicRspLen); + vos_mem_free(psessionEntry->ricData); + psessionEntry->ricData = NULL; + PELOG1(limLog(pMac, LOG1, FL("RicLength=%d"), pSirSmeJoinRsp->parsedRicRspLen);) + } +#endif +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->tspecIes != NULL) + { + pSirSmeJoinRsp->tspecIeLen = psessionEntry->tspecLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen + psessionEntry->assocRspLen + + psessionEntry->RICDataLen, + psessionEntry->tspecIes, pSirSmeJoinRsp->tspecIeLen); + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + PELOG1(limLog(pMac, LOG1, FL("ESE-TspecLen=%d"), psessionEntry->tspecLen);) + } +#endif + pSirSmeJoinRsp->aid = psessionEntry->limAID; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("AssocRsp=%d"), psessionEntry->assocRspLen);) +#endif +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (psessionEntry->cc_switch_mode != VOS_MCC_TO_SCC_SWITCH_DISABLE) { + pSirSmeJoinRsp->HTProfile.htSupportedChannelWidthSet = + psessionEntry->htSupportedChannelWidthSet; + pSirSmeJoinRsp->HTProfile.htRecommendedTxWidthSet = + psessionEntry->htRecommendedTxWidthSet; + pSirSmeJoinRsp->HTProfile.htSecondaryChannelOffset = + psessionEntry->htSecondaryChannelOffset; + pSirSmeJoinRsp->HTProfile.dot11mode = + psessionEntry->dot11mode; + pSirSmeJoinRsp->HTProfile.htCapability = + psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pSirSmeJoinRsp->HTProfile.vhtCapability = + psessionEntry->vhtCapability; + pSirSmeJoinRsp->HTProfile.vhtTxChannelWidthSet = + psessionEntry->vhtTxChannelWidthSet; + pSirSmeJoinRsp->HTProfile.apCenterChan = + psessionEntry->apCenterChan; + pSirSmeJoinRsp->HTProfile.apChanWidth = + psessionEntry->apChanWidth; +#endif + } +#endif + } + else + { + + if(psessionEntry->beacon != NULL) + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + + if(psessionEntry->assocReq != NULL) + { + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if(psessionEntry->assocRsp != NULL) + { + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if(psessionEntry->ricData != NULL) + { + vos_mem_free( psessionEntry->ricData); + psessionEntry->ricData = NULL; + } +#endif + +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->tspecIes != NULL) + { + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + } +#endif + } + } + + + pSirSmeJoinRsp->messageType = msgType; + pSirSmeJoinRsp->length = (tANI_U16) rspLen; + pSirSmeJoinRsp->statusCode = resultCode; + pSirSmeJoinRsp->protStatusCode = protStatusCode; + + /* Update SME session ID and transaction Id */ + pSirSmeJoinRsp->sessionId = smesessionId; + pSirSmeJoinRsp->transactionId = smetransactionId; + + if(IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) ) + { + if( psessionEntry && psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE ) + { + +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability) + { + ePhyChanBondState htSecondaryChannelOffset; + /*Get 11ac cbState from 11n cbState*/ + htSecondaryChannelOffset = limGet11ACPhyCBState(pMac, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset, + psessionEntry->apCenterChan, + psessionEntry); + peSetResumeChannel( pMac, psessionEntry->currentOperChannel, htSecondaryChannelOffset); + } + else +#endif + peSetResumeChannel( pMac, psessionEntry->currentOperChannel, psessionEntry->htSecondaryChannelOffset); + } + else + { + peSetResumeChannel( pMac, 0, 0); + } + limResumeLink( pMac, limSendSmeJoinReassocRspAfterResume, + (tANI_U32*) pSirSmeJoinRsp ); + } + else + { + limSendSmeJoinReassocRspAfterResume( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pSirSmeJoinRsp ); + } +} /*** end limSendSmeJoinReassocRsp() ***/ + + + +/** + * limSendSmeStartBssRsp() + * + *FUNCTION: + * This function is called to send eWNI_SME_START_BSS_RSP + * message to applications above MAC Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeStartBssRsp(tpAniSirGlobal pMac, + tANI_U16 msgType, tSirResultCodes resultCode,tpPESession psessionEntry, + tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + + + tANI_U16 size = 0; + tSirMsgQ mmhMsg; + tSirSmeStartBssRsp *pSirSmeRsp; + tANI_U16 ieLen; + tANI_U16 ieOffset, curLen; + + PELOG1(limLog(pMac, LOG1, FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode));) + + size = sizeof(tSirSmeStartBssRsp); + + if(psessionEntry == NULL) + { + pSirSmeRsp = vos_mem_malloc(size); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP,FL("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); + return; + } + vos_mem_set((tANI_U8*)pSirSmeRsp, size, 0); + + } + else + { + //subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID + ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET; + ieLen = psessionEntry->schBeaconOffsetBegin + + psessionEntry->schBeaconOffsetEnd - ieOffset; + //calculate the memory size to allocate + size += ieLen; + + pSirSmeRsp = vos_mem_malloc(size); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); + + return; + } + vos_mem_set((tANI_U8*)pSirSmeRsp, size, 0); + size = sizeof(tSirSmeStartBssRsp); + if (resultCode == eSIR_SME_SUCCESS) + { + + sirCopyMacAddr(pSirSmeRsp->bssDescription.bssId, psessionEntry->bssId); + + /* Read beacon interval from session */ + pSirSmeRsp->bssDescription.beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval; + pSirSmeRsp->bssType = psessionEntry->bssType; + + if (cfgGetCapabilityInfo( pMac, &pSirSmeRsp->bssDescription.capabilityInfo,psessionEntry) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve Capabilities value")); + + limGetPhyMode(pMac, (tANI_U32 *)&pSirSmeRsp->bssDescription.nwType, psessionEntry); + + pSirSmeRsp->bssDescription.channelId = psessionEntry->currentOperChannel; + + curLen = psessionEntry->schBeaconOffsetBegin - ieOffset; + vos_mem_copy( (tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields, + psessionEntry->pSchBeaconFrameBegin + ieOffset, + (tANI_U32)curLen); + + vos_mem_copy( ((tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields) + curLen, + psessionEntry->pSchBeaconFrameEnd, + (tANI_U32)psessionEntry->schBeaconOffsetEnd); + + + //subtracting size of length indicator itself and size of pointer to ieFields + pSirSmeRsp->bssDescription.length = sizeof(tSirBssDescription) - + sizeof(tANI_U16) - sizeof(tANI_U32) + + ieLen; + //This is the size of the message, subtracting the size of the pointer to ieFields + size += ieLen - sizeof(tANI_U32); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (psessionEntry->cc_switch_mode + != VOS_MCC_TO_SCC_SWITCH_DISABLE) { + pSirSmeRsp->HTProfile.htSupportedChannelWidthSet = + psessionEntry->htSupportedChannelWidthSet; + pSirSmeRsp->HTProfile.htRecommendedTxWidthSet = + psessionEntry->htRecommendedTxWidthSet; + pSirSmeRsp->HTProfile.htSecondaryChannelOffset = + psessionEntry->htSecondaryChannelOffset; + pSirSmeRsp->HTProfile.dot11mode = + psessionEntry->dot11mode; + pSirSmeRsp->HTProfile.htCapability = + psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pSirSmeRsp->HTProfile.vhtCapability = + psessionEntry->vhtCapability; + pSirSmeRsp->HTProfile.vhtTxChannelWidthSet = + psessionEntry->vhtTxChannelWidthSet; + pSirSmeRsp->HTProfile.apCenterChan = + psessionEntry->apCenterChan; + pSirSmeRsp->HTProfile.apChanWidth = + psessionEntry->apChanWidth; +#endif + } +#endif + } + + + + + } + + pSirSmeRsp->messageType = msgType; + pSirSmeRsp->length = size; + + /* Update SME session Id and transaction Id */ + pSirSmeRsp->sessionId = smesessionId; + pSirSmeRsp->transactionId = smetransactionId; + pSirSmeRsp->statusCode = resultCode; + if(psessionEntry != NULL ) + pSirSmeRsp->staId = psessionEntry->staId; //else it will be always zero smeRsp StaID = 0 + + + mmhMsg.type = msgType; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + if(psessionEntry == NULL) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeStartBssRsp() ***/ + + + + + +#define LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED 20 +#define LIM_SIZE_OF_EACH_BSS 400 // this is a rough estimate + + +/** + * limSendSmeScanRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_SCAN_RSP message to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SCAN_REQ message + * + * @return None + */ + +void +limSendSmeScanRsp(tpAniSirGlobal pMac, tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId) +{ + tSirMsgQ mmhMsg; + tpSirSmeScanRsp pSirSmeScanRsp=NULL; + tLimScanResultNode *ptemp = NULL; + tANI_U16 msgLen, allocLength, curMsgLen = 0; + tANI_U16 i, bssCount; + tANI_U8 *pbBuf; + tSirBssDescription *pDesc; + + limLog(pMac, LOG1, + FL("Sending message SME_SCAN_RSP with length=%d reasonCode %s"), + length, limResultCodeStr(resultCode)); + + if (resultCode != eSIR_SME_SUCCESS) + { + limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId); + return; + } + + mmhMsg.type = eWNI_SME_SCAN_RSP; + i = 0; + bssCount = 0; + msgLen = 0; + allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS; + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP")); + + return; + } + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + //when ptemp is not NULL it is a left over + ptemp = pMac->lim.gLimCachedScanHashTable[i]; + while(ptemp) + { + pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen; + if(0 == bssCount) + { + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + } + else + { + msgLen += ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = (tSirBssDescription *)pbBuf; + } + if( (allocLength < msgLen) || + (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) ) + { + pSirSmeScanRsp->statusCode = + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP")); + return; + } + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + bssCount = 1; + } + curMsgLen = msgLen; + + PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d"), + msgLen, ptemp->bssDescription.length);) + pDesc->length + = ptemp->bssDescription.length; + vos_mem_copy( (tANI_U8 *) &pDesc->bssId, + (tANI_U8 *) &ptemp->bssDescription.bssId, + ptemp->bssDescription.length); + + PELOG2(limLog(pMac, LOG2, FL("BssId ")); + limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);) + + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + ptemp = ptemp->next; + } //while(ptemp) + } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + + if(0 == bssCount) + { + length = sizeof(tSirSmeScanRsp); + limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId); + if (NULL != pSirSmeScanRsp) + { + vos_mem_free( pSirSmeScanRsp); + pSirSmeScanRsp = NULL; + } + } + else + { + // send last message + pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + + /* Update SME session Id and SME transcation Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + PELOG2(limLog(pMac, LOG2, FL("statusCode : eSIR_SME_SUCCESS"));) + } + // Discard previously cached scan results + limReInitScanResults(pMac); + + return; + +} /*** end limSendSmeScanRsp() ***/ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limSendSmeLfrScanRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_SCAN_RSP message to applications above MAC Software + * only for sending up the roam candidates. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SCAN_REQ message + * + * @return None + */ + +void +limSendSmeLfrScanRsp(tpAniSirGlobal pMac, tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId) +{ + tSirMsgQ mmhMsg; + tpSirSmeScanRsp pSirSmeScanRsp=NULL; + tLimScanResultNode *ptemp = NULL; + tANI_U16 msgLen, allocLength, curMsgLen = 0; + tANI_U16 i, bssCount; + tANI_U8 *pbBuf; + tSirBssDescription *pDesc; + tANI_S16 scanEntriesLeft = 0; + tANI_U8 *currentBssid = + pMac->roam.roamSession[smesessionId].connectedProfile.bssid; + + limLog(pMac, LOG1, + FL("Sending message SME_SCAN_RSP with length=%d reasonCode %s\n"), + length, limResultCodeStr(resultCode)); + + if (resultCode != eSIR_SME_SUCCESS) + { + limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId); + return; + } + + mmhMsg.type = eWNI_SME_SCAN_RSP; + i = 0; + bssCount = 0; + msgLen = 0; + allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS; + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP\n")); + + return; + } + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + //when ptemp is not NULL it is a left over + ptemp = pMac->lim.gLimCachedLfrScanHashTable[i]; + while(ptemp) + { + if (vos_mem_compare(ptemp->bssDescription.bssId, + currentBssid, + sizeof(tSirMacAddr))) + { + ptemp = ptemp->next; + continue; + } + + pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen; + if(0 == bssCount) + { + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + } + else + { + msgLen += ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = (tSirBssDescription *)pbBuf; + } + if ( (allocLength < msgLen) || + (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) ) + { + pSirSmeScanRsp->statusCode = + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP\n")); + return; + } + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + bssCount = 1; + } + curMsgLen = msgLen; + + PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d\n"), + msgLen, ptemp->bssDescription.length);) + pDesc->length + = ptemp->bssDescription.length; + vos_mem_copy( (tANI_U8 *) &pDesc->bssId, + (tANI_U8 *) &ptemp->bssDescription.bssId, + ptemp->bssDescription.length); + + PELOG2(limLog(pMac, LOG2, FL("BssId ")); + limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);) + + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + ptemp = ptemp->next; + } //while(ptemp) + } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + + /* Repeat for normal scan cache */ + if (pMac->roam.roamSession[smesessionId].connectedProfile.SSID.length != 0) { + tSirMacSSid *pSsid = &pMac->roam.roamSession[smesessionId].connectedProfile.SSID; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + ptemp = pMac->lim.gLimCachedScanHashTable[i]; + while(ptemp) + { + if(vos_mem_compare((tANI_U8* ) ptemp->bssDescription.ieFields+1, + (tANI_U8 *) &pSsid->length, + (tANI_U8) (pSsid->length + 1))) + { + if (vos_mem_compare(ptemp->bssDescription.bssId, + currentBssid, + sizeof(tSirMacAddr))) + { + ptemp = ptemp->next; + continue; + } + + pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen; + if(0 == bssCount) + { + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + } + else + { + msgLen += ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = (tSirBssDescription *)pbBuf; + } + if ( (allocLength < msgLen) || + (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) ) + { + pSirSmeScanRsp->statusCode = + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP\n")); + return; + } + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + bssCount = 1; + } + curMsgLen = msgLen; + + PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d\n"), + msgLen, ptemp->bssDescription.length);) + pDesc->length + = ptemp->bssDescription.length; + vos_mem_copy((tANI_U8 *) &pDesc->bssId, + (tANI_U8 *) &ptemp->bssDescription.bssId, + ptemp->bssDescription.length); + + PELOG2(limLog(pMac, LOG2, FL("BssId ")); + limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);) + + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + } + ptemp = ptemp->next; + } //while(ptemp) + } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + } + if (0 == bssCount) + { + limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId); + if (NULL != pSirSmeScanRsp) + { + vos_mem_free( pSirSmeScanRsp); + pSirSmeScanRsp = NULL; + } + } + else + { + // send last message + pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + + /* Update SME session Id and SME transcation Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + PELOG2(limLog(pMac, LOG2, FL("statusCode : eSIR_SME_SUCCESS\n"));) + } + // Discard previously cached scan results + limReInitLfrScanResults(pMac); + + // delete the returned entries from normal cache (gLimCachedScanHashTable) + scanEntriesLeft = limRemoveSsidFromScanCache(pMac, + &pMac->roam.roamSession[smesessionId].connectedProfile.SSID); + PELOG2(limLog(pMac, + LOG2, + FL("Scan Entries Left after cleanup: %d", + scanEntriesLeft))); + + return; + +} /*** end limSendSmeLfrScanRsp() ***/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** + * limPostSmeScanRspMessage() + * + *FUNCTION: + * This function is called by limSendSmeScanRsp() to send + * eWNI_SME_SCAN_RSP message with failed result code + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode failed result code + * + * @return None + */ + +void +limPostSmeScanRspMessage(tpAniSirGlobal pMac, + tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tpSirSmeScanRsp pSirSmeScanRsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOG1, + FL("limPostSmeScanRspMessage: send SME_SCAN_RSP (len %d, reasonCode %s). "), + length, limResultCodeStr(resultCode)); + + pSirSmeScanRsp = vos_mem_malloc(length); + if ( NULL == pSirSmeScanRsp ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_SCAN_RSP")); + return; + } + vos_mem_set((void*)pSirSmeScanRsp, length, 0); + + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = length; + + if(sizeof(tSirSmeScanRsp) <= length) + { + pSirSmeScanRsp->bssDescription->length = sizeof(tSirBssDescription); + } + + pSirSmeScanRsp->statusCode = resultCode; + + /*Update SME session Id and transaction Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetransactionId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; + +} /*** limPostSmeScanRspMessage ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + * limSendSmeOemDataRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_OEM_DATA_RSP message to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf Indicates the mlm message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_OEM_DATA_RSP message + * + * @return None + */ + +void limSendSmeOemDataRsp(tpAniSirGlobal pMac, tANI_U32* pMsgBuf, tSirResultCodes resultCode) +{ + tSirMsgQ mmhMsg; + tSirOemDataRsp* pSirSmeOemDataRsp=NULL; + tLimMlmOemDataRsp* pMlmOemDataRsp=NULL; + tANI_U16 msgLength; + + + //get the pointer to the mlm message + pMlmOemDataRsp = (tLimMlmOemDataRsp*)(pMsgBuf); + + msgLength = sizeof(tSirOemDataRsp); + + //now allocate memory for the char buffer + pSirSmeOemDataRsp = vos_mem_malloc(msgLength); + if (NULL == pSirSmeOemDataRsp) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pSirSmeOemDataRsp")); + return; + } + +#if defined (ANI_LITTLE_BYTE_ENDIAN) + sirStoreU16N((tANI_U8*)&pSirSmeOemDataRsp->length, msgLength); + sirStoreU16N((tANI_U8*)&pSirSmeOemDataRsp->messageType, eWNI_SME_OEM_DATA_RSP); +#else + pSirSmeOemDataRsp->length = msgLength; + pSirSmeOemDataRsp->messageType = eWNI_SME_OEM_DATA_RSP; +#endif + + vos_mem_copy(pSirSmeOemDataRsp->oemDataRsp, pMlmOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); + + //Now free the memory from MLM Rsp Message + vos_mem_free(pMlmOemDataRsp); + + mmhMsg.type = eWNI_SME_OEM_DATA_RSP; + mmhMsg.bodyptr = pSirSmeOemDataRsp; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} /*** limSendSmeOemDataRsp ***/ + +#endif + + +void limSendSmeDisassocDeauthNtf( tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *pCtx ) +{ + tSirMsgQ mmhMsg; + tSirMsgQ *pMsg = (tSirMsgQ*) pCtx; + + mmhMsg.type = pMsg->type; + mmhMsg.bodyptr = pMsg; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} +/** + * limSendSmeDisassocNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_DISASSOC_RSP/IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_DISASSOC_CNF, + * or eWNI_SME_DISASSOC_IND to host depending on + * disassociation trigger. + * + * @param peerMacAddr Indicates the peer MAC addr to which + * disassociate was initiated + * @param reasonCode Indicates the reason for Disassociation + * @param disassocTrigger Indicates the trigger for Disassociation + * @param aid Indicates the STAID. This parameter is + * present only on AP. + * + * @return None + */ +void +limSendSmeDisassocNtf(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirResultCodes reasonCode, + tANI_U16 disassocTrigger, + tANI_U16 aid, + tANI_U8 smesessionId, + tANI_U16 smetransactionId, + tpPESession psessionEntry) +{ + + tANI_U8 *pBuf; + tSirSmeDisassocRsp *pSirSmeDisassocRsp; + tSirSmeDisassocInd *pSirSmeDisassocInd; + tANI_U32 *pMsg; + + switch (disassocTrigger) + { + case eLIM_PEER_ENTITY_DISASSOC: + if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) + return; + + case eLIM_HOST_DISASSOC: + /** + * Disassociation response due to + * host triggered disassociation + */ + + pSirSmeDisassocRsp = vos_mem_malloc(sizeof(tSirSmeDisassocRsp)); + if ( NULL == pSirSmeDisassocRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_RSP")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP; + pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp); + //sessionId + pBuf = (tANI_U8 *) &pSirSmeDisassocRsp->sessionId; + *pBuf = smesessionId; + pBuf++; + + //transactionId + limCopyU16(pBuf, smetransactionId); + pBuf += sizeof(tANI_U16); + + //statusCode + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + //peerMacAddr + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // Clear Station Stats + //for sta, it is always 1, IBSS is handled at halInitSta + + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT, + psessionEntry, (tANI_U16)reasonCode, 0); +#endif + pMsg = (tANI_U32*) pSirSmeDisassocRsp; + break; + + default: + /** + * Disassociation indication due to Disassociation + * frame reception from peer entity or due to + * loss of link with peer entity. + */ + pSirSmeDisassocInd = vos_mem_malloc(sizeof(tSirSmeDisassocInd)); + if ( NULL == pSirSmeDisassocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_IND")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; + pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); + + /* Update SME session Id and Transaction Id */ + pSirSmeDisassocInd->sessionId = smesessionId; + pSirSmeDisassocInd->transactionId = smetransactionId; + pSirSmeDisassocInd->reasonCode = reasonCode; + pBuf = (tANI_U8 *) &pSirSmeDisassocInd->statusCode; + + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, + psessionEntry, (tANI_U16)reasonCode, 0); +#endif + pMsg = (tANI_U32*) pSirSmeDisassocInd; + + break; + } + + /* Delete the PE session Created */ + if((psessionEntry != NULL) && ((psessionEntry ->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE)) ) + { + peDeleteSession(pMac,psessionEntry); + } + + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); +} /*** end limSendSmeDisassocNtf() ***/ + + +/** ----------------------------------------------------------------- + \brief limSendSmeDisassocInd() - sends SME_DISASSOC_IND + + After receiving disassociation frame from peer entity, this + function sends a eWNI_SME_DISASSOC_IND to SME with a specific + reason code. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeDisassocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeDisassocInd *pSirSmeDisassocInd; + + pSirSmeDisassocInd = vos_mem_malloc(sizeof(tSirSmeDisassocInd)); + if ( NULL == pSirSmeDisassocInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND")); + return; + } + + pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; + pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); + + pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId; + pSirSmeDisassocInd->transactionId = psessionEntry->transactionId; + pSirSmeDisassocInd->statusCode = pStaDs->mlmStaContext.disassocReason; + pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason; + + vos_mem_copy( pSirSmeDisassocInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + + vos_mem_copy( pSirSmeDisassocInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr)); + + pSirSmeDisassocInd->staId = pStaDs->staIndex; + + mmhMsg.type = eWNI_SME_DISASSOC_IND; + mmhMsg.bodyptr = pSirSmeDisassocInd; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry, 0, (tANI_U16)pStaDs->mlmStaContext.disassocReason); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} /*** end limSendSmeDisassocInd() ***/ + + +/** ----------------------------------------------------------------- + \brief limSendSmeDeauthInd() - sends SME_DEAUTH_IND + + After receiving deauthentication frame from peer entity, this + function sends a eWNI_SME_DEAUTH_IND to SME with a specific + reason code. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeDeauthInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeDeauthInd *pSirSmeDeauthInd; + + pSirSmeDeauthInd = vos_mem_malloc(sizeof(tSirSmeDeauthInd)); + if ( NULL == pSirSmeDeauthInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND ")); + return; + } + + pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; + pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); + + pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId; + pSirSmeDeauthInd->transactionId = psessionEntry->transactionId; + if(eSIR_INFRA_AP_MODE == psessionEntry->bssType) + { + pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.cleanupTrigger; + } + else + { + //Need to indicatet he reascon code over the air + pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.disassocReason; + } + //BSSID + vos_mem_copy( pSirSmeDeauthInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + //peerMacAddr + vos_mem_copy( pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr)); + pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason; + + + pSirSmeDeauthInd->staId = pStaDs->staIndex; + + mmhMsg.type = eWNI_SME_DEAUTH_IND; + mmhMsg.bodyptr = pSirSmeDeauthInd; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry, 0, pStaDs->mlmStaContext.cleanupTrigger); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} /*** end limSendSmeDeauthInd() ***/ + +#ifdef FEATURE_WLAN_TDLS +/** + * limSendSmeTDLSDelStaInd() + * + *FUNCTION: + * This function is called to send the TDLS STA context deletion to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param pStaDs - Pointer to internal STA Datastructure + * @param psessionEntry - Pointer to the session entry + * @param reasonCode - Reason for TDLS sta deletion + * @return None + */ +void +limSendSmeTDLSDelStaInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry, tANI_U16 reasonCode) +{ + tSirMsgQ mmhMsg; + tSirTdlsDelStaInd *pSirTdlsDelStaInd; + + pSirTdlsDelStaInd = vos_mem_malloc(sizeof(tSirTdlsDelStaInd)); + if ( NULL == pSirTdlsDelStaInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND ")); + return; + } + + //messageType + pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND; + pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd); + + //sessionId + pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId; + + //peerMacAddr + vos_mem_copy( pSirTdlsDelStaInd->peerMac, pStaDs->staAddr, sizeof(tSirMacAddr)); + + //staId + limCopyU16((tANI_U8*)(&pSirTdlsDelStaInd->staId), (tANI_U16)pStaDs->staIndex); + + //reasonCode + limCopyU16((tANI_U8*)(&pSirTdlsDelStaInd->reasonCode), reasonCode); + + mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND; + mmhMsg.bodyptr = pSirTdlsDelStaInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDelStaInd() ***/ + +/** + * limSendSmeTDLSDeleteAllPeerInd() + * + *FUNCTION: + * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND + * message to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param psessionEntry - Pointer to the session entry + * @return None + */ +void +limSendSmeTDLSDeleteAllPeerInd(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd; + + pSirTdlsDelAllPeerInd = vos_mem_malloc(sizeof(tSirTdlsDelAllPeerInd)); + if ( NULL == pSirTdlsDelAllPeerInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND")); + return; + } + + //messageType + pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND; + pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd); + + //sessionId + pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId; + + mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND; + mmhMsg.bodyptr = pSirTdlsDelAllPeerInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDeleteAllPeerInd() ***/ + +/** + * limSendSmeMgmtTXCompletion() + * + *FUNCTION: + * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND + * message to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param psessionEntry - Pointer to the session entry + * @param txCompleteStatus - TX Complete Status of Mgmt Frames + * @return None + */ +void +limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tANI_U32 txCompleteStatus) +{ + tSirMsgQ mmhMsg; + tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd; + + pSirMgmtTxCompletionInd = vos_mem_malloc(sizeof(tSirMgmtTxCompletionInd)); + if ( NULL == pSirMgmtTxCompletionInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND")); + return; + } + + //messageType + pSirMgmtTxCompletionInd->messageType = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; + pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd); + + //sessionId + pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId; + + pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus; + + mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; + mmhMsg.bodyptr = pSirMgmtTxCompletionInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDeleteAllPeerInd() ***/ + +void limSendSmeTdlsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, + void *events) +{ + tSirMsgQ mmhMsg; + + switch (msgType) + { + case SIR_HAL_TDLS_SHOULD_DISCOVER: + mmhMsg.type = eWNI_SME_TDLS_SHOULD_DISCOVER; + break; + case SIR_HAL_TDLS_SHOULD_TEARDOWN: + mmhMsg.type = eWNI_SME_TDLS_SHOULD_TEARDOWN; + break; + case SIR_HAL_TDLS_PEER_DISCONNECTED: + mmhMsg.type = eWNI_SME_TDLS_PEER_DISCONNECTED; + break; + } + + mmhMsg.bodyptr = events; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} +#endif /* FEATURE_WLAN_TDLS */ + + +/** + * limSendSmeDeauthNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_DISASSOC_RSP/IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_DEAUTH_CNF or + * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger. + * + * @param peerMacAddr Indicates the peer MAC addr to which + * deauthentication was initiated + * @param reasonCode Indicates the reason for Deauthetication + * @param deauthTrigger Indicates the trigger for Deauthetication + * @param aid Indicates the STAID. This parameter is present + * only on AP. + * + * @return None + */ +void +limSendSmeDeauthNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes reasonCode, + tANI_U16 deauthTrigger, tANI_U16 aid,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tANI_U8 *pBuf; + tSirSmeDeauthRsp *pSirSmeDeauthRsp; + tSirSmeDeauthInd *pSirSmeDeauthInd; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 *pMsg; + + psessionEntry = peFindSessionByBssid(pMac,peerMacAddr,&sessionId); + switch (deauthTrigger) + { + case eLIM_PEER_ENTITY_DEAUTH: + return; + + case eLIM_HOST_DEAUTH: + /** + * Deauthentication response to host triggered + * deauthentication. + */ + pSirSmeDeauthRsp = vos_mem_malloc(sizeof(tSirSmeDeauthRsp)); + if ( NULL == pSirSmeDeauthRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with " + "retCode: %d for"MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP; + pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp); + pSirSmeDeauthRsp->statusCode = reasonCode; + pSirSmeDeauthRsp->sessionId = smesessionId; + pSirSmeDeauthRsp->transactionId = smetransactionId; + + pBuf = (tANI_U8 *) pSirSmeDeauthRsp->peerMacAddr; + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT, + psessionEntry, 0, (tANI_U16)reasonCode); +#endif + pMsg = (tANI_U32*)pSirSmeDeauthRsp; + + break; + + default: + /** + * Deauthentication indication due to Deauthentication + * frame reception from peer entity or due to + * loss of link with peer entity. + */ + pSirSmeDeauthInd = vos_mem_malloc(sizeof(tSirSmeDeauthInd)); + if ( NULL == pSirSmeDeauthInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; + pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); + pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + + // sessionId + pBuf = (tANI_U8*) &pSirSmeDeauthInd->sessionId; + *pBuf++ = smesessionId; + + //transaction ID + limCopyU16(pBuf, smetransactionId); + pBuf += sizeof(tANI_U16); + + // status code + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + //bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + //peerMacAddr + vos_mem_copy( pSirSmeDeauthInd->peerMacAddr, peerMacAddr, sizeof(tSirMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, + psessionEntry, 0, (tANI_U16)reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + pMsg = (tANI_U32*)pSirSmeDeauthInd; + + break; + } + + /*Delete the PE session created */ + if(psessionEntry != NULL) + { + peDeleteSession(pMac,psessionEntry); + } + + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); + +} /*** end limSendSmeDeauthNtf() ***/ + + +/** + * limSendSmeWmStatusChangeNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_WM_STATUS_CHANGE_NTF message to host. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param statusChangeCode Indicates the change in the wireless medium. + * @param statusChangeInfo Indicates the information associated with + * change in the wireless medium. + * @param infoLen Indicates the length of status change information + * being sent. + * + * @return None + */ +void +limSendSmeWmStatusChangeNtf(tpAniSirGlobal pMac, tSirSmeStatusChangeCode statusChangeCode, + tANI_U32 *pStatusChangeInfo, tANI_U16 infoLen, tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSirSmeWmStatusChangeNtf *pSirSmeWmStatusChangeNtf; + pSirSmeWmStatusChangeNtf = vos_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf)); + if ( NULL == pSirSmeWmStatusChangeNtf ) + { + limLog(pMac, LOGE, + FL("call to AllocateMemory failed for eWNI_SME_WM_STATUS_CHANGE_NTF")); + return; + } + + + mmhMsg.type = eWNI_SME_WM_STATUS_CHANGE_NTF; + mmhMsg.bodyval = 0; + mmhMsg.bodyptr = pSirSmeWmStatusChangeNtf; + + switch(statusChangeCode) + { + case eSIR_SME_RADAR_DETECTED: + + break; + + case eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP: + break; + + case eSIR_SME_BACKGROUND_SCAN_FAIL: + limPackBkgndScanFailNotify(pMac, + statusChangeCode, + (tpSirBackgroundScanInfo)pStatusChangeInfo, + pSirSmeWmStatusChangeNtf, sessionId); + break; + + default: + pSirSmeWmStatusChangeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF; + pSirSmeWmStatusChangeNtf->statusChangeCode = statusChangeCode; + pSirSmeWmStatusChangeNtf->length = sizeof(tSirSmeWmStatusChangeNtf); + pSirSmeWmStatusChangeNtf->sessionId = sessionId; + if(sizeof(pSirSmeWmStatusChangeNtf->statusChangeInfo) >= infoLen) + { + vos_mem_copy( (tANI_U8 *)&pSirSmeWmStatusChangeNtf->statusChangeInfo, + (tANI_U8 *)pStatusChangeInfo, infoLen); + } + limLog(pMac, LOGE, FL("***---*** StatusChg: code 0x%x, length %d ***---***"), + statusChangeCode, infoLen); + break; + } + + + MTRACE(macTraceMsgTx(pMac, sessionId, mmhMsg.type)); + if (eSIR_SUCCESS != limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT)) + { + vos_mem_free(pSirSmeWmStatusChangeNtf); + limLog( pMac, LOGP, FL("limSysProcessMmhMsgApi failed")); + } + +} /*** end limSendSmeWmStatusChangeNtf() ***/ + + +/** + * limSendSmeSetContextRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_SETCONTEXT_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param peerMacAddr Indicates the peer MAC addr to which + * setContext was performed + * @param aid Indicates the aid corresponding to the peer MAC + * address + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SETCONTEXT_RSP message + * + * @return None + */ +void +limSendSmeSetContextRsp(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, tANI_U16 aid, + tSirResultCodes resultCode, + tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + + tANI_U8 *pBuf; + tSirMsgQ mmhMsg; + tSirSmeSetContextRsp *pSirSmeSetContextRsp; + + pSirSmeSetContextRsp = vos_mem_malloc(sizeof(tSirSmeSetContextRsp)); + if ( NULL == pSirSmeSetContextRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for SmeSetContextRsp")); + + return; + } + + pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP; + pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp); + pSirSmeSetContextRsp->statusCode = resultCode; + + pBuf = pSirSmeSetContextRsp->peerMacAddr; + + vos_mem_copy( pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + + /* Update SME session and transaction Id*/ + pSirSmeSetContextRsp->sessionId = smesessionId; + pSirSmeSetContextRsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_SETCONTEXT_RSP; + mmhMsg.bodyptr = pSirSmeSetContextRsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeSetContextRsp() ***/ + +/** + * limSendSmeRemoveKeyRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_REMOVEKEY_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param peerMacAddr Indicates the peer MAC addr to which + * Removekey was performed + * @param aid Indicates the aid corresponding to the peer MAC + * address + * @param resultCode Indicates the result of previously issued + * eWNI_SME_REMOVEKEY_RSP message + * + * @return None + */ +void +limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirResultCodes resultCode, + tpPESession psessionEntry,tANI_U8 smesessionId, + tANI_U16 smetransactionId) +{ + tANI_U8 *pBuf; + tSirMsgQ mmhMsg; + tSirSmeRemoveKeyRsp *pSirSmeRemoveKeyRsp; + + pSirSmeRemoveKeyRsp = vos_mem_malloc(sizeof(tSirSmeRemoveKeyRsp)); + if ( NULL == pSirSmeRemoveKeyRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for SmeRemoveKeyRsp")); + + return; + } + + + + if(psessionEntry != NULL) + { + pBuf = pSirSmeRemoveKeyRsp->peerMacAddr; + vos_mem_copy( pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr)); + } + + pSirSmeRemoveKeyRsp->messageType = eWNI_SME_REMOVEKEY_RSP; + pSirSmeRemoveKeyRsp->length = sizeof(tSirSmeRemoveKeyRsp); + pSirSmeRemoveKeyRsp->statusCode = resultCode; + + /* Update SME session and transaction Id*/ + pSirSmeRemoveKeyRsp->sessionId = smesessionId; + pSirSmeRemoveKeyRsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_REMOVEKEY_RSP; + mmhMsg.bodyptr = pSirSmeRemoveKeyRsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + } + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeSetContextRsp() ***/ + + +/** + * limSendSmeNeighborBssInd() + * + *FUNCTION: + * This function is called by limLookupNaddHashEntry() to send + * eWNI_SME_NEIGHBOR_BSS_IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to + * host upon detecting new BSS during background scanning if CFG + * option is enabled for sending such indication + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSendSmeNeighborBssInd(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr) +{ + tSirMsgQ msgQ; + tANI_U32 val; + tSirSmeNeighborBssInd *pNewBssInd; + + if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) || + ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) && + pMac->lim.gLimRspReqd)) + { + // LIM is not in background scan state OR + // current scan is initiated by HDD. + // No need to send new BSS indication to HDD + return; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not get NEIGHBOR_BSS_IND from CFG")); + + return; + } + + if (val == 0) + return; + + /** + * Need to indicate new BSSs found during + * background scanning to host. + * Allocate buffer for sending indication. + * Length of buffer is length of BSS description + * and length of header itself + */ + val = pBssDescr->bssDescription.length + sizeof(tANI_U16) + sizeof(tANI_U32) + sizeof(tANI_U8); + pNewBssInd = vos_mem_malloc(val); + if ( NULL == pNewBssInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND")); + + return; + } + + pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND; + pNewBssInd->length = (tANI_U16) val; + pNewBssInd->sessionId = 0; + + vos_mem_copy( (tANI_U8 *) pNewBssInd->bssDescription, + (tANI_U8 *) &pBssDescr->bssDescription, + pBssDescr->bssDescription.length + sizeof(tANI_U16)); + + msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND; + msgQ.bodyptr = pNewBssInd; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); +} /*** end limSendSmeNeighborBssInd() ***/ + +/** ----------------------------------------------------------------- + \brief limSendSmeAddtsRsp() - sends SME ADDTS RSP + \ This function sends a eWNI_SME_ADDTS_RSP to SME. + \ SME only looks at rc and tspec field. + \param pMac - global mac structure + \param rspReqd - is SmeAddTsRsp required + \param status - status code of SME_ADD_TS_RSP + \return tspec + \sa + ----------------------------------------------------------------- */ +void +limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry, + tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tpSirAddtsRsp rsp; + tSirMsgQ mmhMsg; + + if (! rspReqd) + return; + + rsp = vos_mem_malloc(sizeof(tSirAddtsRsp)); + if ( NULL == rsp ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP")); + return; + } + + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + rsp->messageType = eWNI_SME_ADDTS_RSP; + rsp->rc = status; + rsp->rsp.status = (enum eSirMacStatusCodes) status; + rsp->rsp.tspec = tspec; + /* Update SME session Id and transcation Id */ + rsp->sessionId = smesessionId; + rsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_ADDTS_RSP; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +void +limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts) +{ + tpSirAddtsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeAddtsInd (token %d, tsid %d, up %d)", + addts->dialogToken, + addts->tspec.tsinfo.traffic.tsid, + addts->tspec.tsinfo.traffic.userPrio); + + rsp = vos_mem_malloc(sizeof(tSirAddtsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for ADDTS_IND")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + rsp->messageType = eWNI_SME_ADDTS_IND; + + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) addts, sizeof(*addts)); + + mmhMsg.type = eWNI_SME_ADDTS_IND; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +void +limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + tpSirDeltsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d", + delts->aid, + delts->req.tsinfo.traffic.tsid, + delts->req.tsinfo.traffic.userPrio, + status); + if (! delts->rspReqd) + return; + + rsp = vos_mem_malloc(sizeof(tSirDeltsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + if(psessionEntry != NULL) + { + + rsp->aid = delts->aid; + vos_mem_copy( (tANI_U8 *) &rsp->macAddr[0], (tANI_U8 *) &delts->macAddr[0], 6); + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) &delts->req, sizeof(tSirDeltsReqInfo)); + } + + + rsp->messageType = eWNI_SME_DELTS_RSP; + rsp->rc = status; + + /* Update SME session Id and transcation Id */ + rsp->sessionId = smesessionId; + rsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_DELTS_RSP; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry, (tANI_U16)status, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +void +limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession psessionEntry) +{ + tpSirDeltsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)", + aid, + delts->tsinfo.traffic.tsid, + delts->tsinfo.traffic.userPrio); + + rsp = vos_mem_malloc(sizeof(tSirDeltsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + rsp->messageType = eWNI_SME_DELTS_IND; + rsp->rc = eSIR_SUCCESS; + rsp->aid = aid; + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) delts, sizeof(*delts)); + + /* Update SME session Id and SME transaction Id */ + + rsp->sessionId = psessionEntry->smeSessionId; + rsp->transactionId = psessionEntry->transactionId; + + mmhMsg.type = eWNI_SME_DELTS_IND; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/** + * limSendSmeStatsRsp() + * + *FUNCTION: + * This function is called to send 802.11 statistics response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request for statistics. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tSirSmeRsp *pMsgHdr = (tSirSmeRsp*) stats; + + switch(msgType) + { + case WDA_STA_STAT_RSP: + mmhMsg.type = eWNI_SME_STA_STAT_RSP; + break; + case WDA_AGGR_STAT_RSP: + mmhMsg.type = eWNI_SME_AGGR_STAT_RSP; + break; + case WDA_GLOBAL_STAT_RSP: + mmhMsg.type = eWNI_SME_GLOBAL_STAT_RSP; + break; + case WDA_STAT_SUMM_RSP: + mmhMsg.type = eWNI_SME_STAT_SUMM_RSP; + break; + default: + mmhMsg.type = msgType; //Response from within PE + break; + } + + pMsgHdr->messageType = mmhMsg.type; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmeStatsRsp() ***/ + +/** + * limSendSmePEStatisticsRsp() + * + *FUNCTION: + * This function is called to send 802.11 statistics response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request for statistics. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats; + tpPESession pPeSessionEntry; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + + pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP; + + + //msgType should be WDA_GET_STATISTICS_RSP + mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmePEStatisticsRsp() ***/ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + * limSendSmePEGetRoamRssiRsp() + * + *FUNCTION: + * This function is called to send roam rssi response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request to get roam rssi. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmePEGetRoamRssiRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetRoamRssiRsp *pPeStats = (tAniGetRoamRssiRsp *) stats; + tpPESession pPeSessionEntry = NULL; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + + pPeStats->msgType = eWNI_SME_GET_ROAM_RSSI_RSP; + + //msgType should be WDA_GET_STATISTICS_RSP + mmhMsg.type = eWNI_SME_GET_ROAM_RSSI_RSP; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmePEGetRoamRssiRsp() ***/ + +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** + * limSendSmePEEseTsmRsp() + * + *FUNCTION: + * This function is called to send tsm stats response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request to get tsm stats. + * + *PARAMS: + * @param pMac - Pointer to global pMac structure + * @param pStats - Pointer to TSM Stats + * + * @return none + */ + +void +limSendSmePEEseTsmRsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats; + tpPESession pPeSessionEntry = NULL; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("Session not found for the Sta id(%d)"), + pPeStats->staId);) + return; + } + + pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP; + pPeStats->tsmMetrics.RoamingCount + = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount; + pPeStats->tsmMetrics.RoamingDly + = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly; + + mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP; + mmhMsg.bodyptr = pStats; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} /*** end limSendSmePEEseTsmRsp() ***/ + +#endif /* FEATURE_WLAN_ESE) && FEATURE_WLAN_ESE_UPLOAD */ + +void +limSendSmeIBSSPeerInd( + tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U16 staIndex, + tANI_U8 ucastIdx, + tANI_U8 bcastIdx, + tANI_U8 *beacon, + tANI_U16 beaconLen, + tANI_U16 msgType, + tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSmeIbssPeerInd *pNewPeerInd; + + pNewPeerInd = vos_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen); + if ( NULL == pNewPeerInd ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return; + } + + vos_mem_set((void *) pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen), 0); + + vos_mem_copy( (tANI_U8 *) pNewPeerInd->peerAddr, + peerMacAddr, sizeof(tSirMacAddr)); + pNewPeerInd->staId= staIndex; + pNewPeerInd->ucastSig = ucastIdx; + pNewPeerInd->bcastSig = bcastIdx; + pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen; + pNewPeerInd->mesgType = msgType; + pNewPeerInd->sessionId = sessionId; + + if ( beacon != NULL ) + { + vos_mem_copy((void*) ((tANI_U8*)pNewPeerInd+sizeof(tSmeIbssPeerInd)), + (void*)beacon, beaconLen); + } + + mmhMsg.type = msgType; + mmhMsg.bodyptr = pNewPeerInd; + MTRACE(macTraceMsgTx(pMac, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + + +/** ----------------------------------------------------------------- + \brief limSendExitBmpsInd() - sends exit bmps indication + + This function sends a eWNI_PMC_EXIT_BMPS_IND with a specific reason + code to SME. This will trigger SME to get out of BMPS mode. + + \param pMac - global mac structure + \param reasonCode - reason for which PE wish to exit BMPS + \return none + \sa + ----------------------------------------------------------------- */ +void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode, + tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tANI_U16 msgLen = 0; + tpSirSmeExitBmpsInd pExitBmpsInd; + + msgLen = sizeof(tSirSmeExitBmpsInd); + pExitBmpsInd = vos_mem_malloc(msgLen); + if ( NULL == pExitBmpsInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for PMC_EXIT_BMPS_IND ")); + return; + } + vos_mem_set(pExitBmpsInd, msgLen, 0); + + pExitBmpsInd->mesgType = eWNI_PMC_EXIT_BMPS_IND; + pExitBmpsInd->mesgLen = msgLen; + pExitBmpsInd->exitBmpsReason = reasonCode; + pExitBmpsInd->statusCode = eSIR_SME_SUCCESS; + pExitBmpsInd->smeSessionId = psessionEntry->smeSessionId; + + mmhMsg.type = eWNI_PMC_EXIT_BMPS_IND; + mmhMsg.bodyptr = pExitBmpsInd; + mmhMsg.bodyval = 0; + + PELOG1(limLog(pMac, LOG1, FL("Sending eWNI_PMC_EXIT_BMPS_IND to SME. "));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT, peGetValidPowerSaveSession(pMac), 0, (tANI_U16)reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; + +} /*** end limSendExitBmpsInd() ***/ + +/*-------------------------------------------------------------------------- + \brief limHandleCSAoffloadMsg() - Handle CSA offload message + \param pMac - pointer to global adapter context + \param MsgQ - Message pointer. + \sa + --------------------------------------------------------------------------*/ +void limHandleCSAoffloadMsg(tpAniSirGlobal pMac,tpSirMsgQ MsgQ) +{ + tpPESession psessionEntry; + tSirMsgQ mmhMsg; + tpCSAOffloadParams csa_params = (tpCSAOffloadParams)(MsgQ->bodyptr); + tpSmeCsaOffloadInd pCsaOffloadInd; + tpDphHashNode pStaDs = NULL ; + tANI_U8 sessionId; + tANI_U16 aid = 0 ; + + if (!csa_params) { + limLog(pMac, LOGE, FL("limMsgQ body ptr is NULL")); + return; + } + + psessionEntry = peFindSessionByBssid(pMac, csa_params->bssId, &sessionId); + if (!psessionEntry) { + limLog(pMac, LOGE, FL("Session does not exist for given sessionID")); + goto err; + } + + pStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid, + &psessionEntry->dph.dphHashTable); + + if (!pStaDs) { + limLog(pMac, LOGE, FL("pStaDs does not exist for given sessionID")); + goto err; + } + + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + psessionEntry->gLimChannelSwitch.switchMode = csa_params->switchmode; + /* timer already started by firmware, switch immediately */ + psessionEntry->gLimChannelSwitch.switchCount = 0; + psessionEntry->gLimChannelSwitch.primaryChannel = csa_params->channel; + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; + +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + if ( csa_params->ies_present_flag & lim_wbw_ie_present ) + { + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = + csa_params->new_ch_width; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = + csa_params->new_ch_freq_seg1; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = + csa_params->new_ch_freq_seg2; + + psessionEntry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + + psessionEntry->gLimChannelSwitch.secondarySubBand = + limSelectCBMode(pStaDs, + psessionEntry, + csa_params->channel, + csa_params->new_ch_width); + } + + } else +#endif + if (psessionEntry->htCapability) { + psessionEntry->gLimChannelSwitch.secondarySubBand = + limSelectCBMode(pStaDs, + psessionEntry, + csa_params->channel, + csa_params->new_ch_width); + if (psessionEntry->gLimChannelSwitch.secondarySubBand) { + psessionEntry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + } + } + limLog(pMac, LOG1, FL("secondarySubBand = %d"), + psessionEntry->gLimChannelSwitch.secondarySubBand); + + limPrepareFor11hChannelSwitch(pMac, psessionEntry); + pCsaOffloadInd = vos_mem_malloc(sizeof(tSmeCsaOffloadInd)); + if (NULL == pCsaOffloadInd) { + limLog(pMac, LOGE, + FL("AllocateMemory failed for eWNI_SME_CSA_OFFLOAD_EVENT")); + goto err; + } + + vos_mem_set(pCsaOffloadInd, sizeof(tSmeCsaOffloadInd), 0); + pCsaOffloadInd->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT; + pCsaOffloadInd->mesgLen = sizeof(tSmeCsaOffloadInd); + vos_mem_copy(pCsaOffloadInd->bssId, psessionEntry->bssId, + sizeof(tSirMacAddr)); + mmhMsg.type = eWNI_SME_CSA_OFFLOAD_EVENT; + mmhMsg.bodyptr = pCsaOffloadInd; + mmhMsg.bodyval = 0; + PELOG1(limLog(pMac, LOG1, FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME. "));) + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + limReInitScanResults(pMac); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + } + +err: + vos_mem_free(csa_params); +} + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - Handle the Delete BSS Response from HAL. + + + \param pMac - pointer to global adapter context + \param sessionId - Message pointer. + + \sa + --------------------------------------------------------------------------*/ + +void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ) +{ + tpPESession psessionEntry; + tpDeleteBssParams pDelBss = (tpDeleteBssParams)(MsgQ->bodyptr); + if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL) + { + limLog(pMac, LOGE,FL("Session Does not exist for given sessionID %d"), + pDelBss->sessionId); + return; + } + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + limIbssDelBssRsp(pMac, MsgQ->bodyptr,psessionEntry); + } + else if(psessionEntry->limSystemRole == eLIM_UNKNOWN_ROLE) + { + limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry); + } + + else + limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry); + +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** ----------------------------------------------------------------- + \brief limSendSmeAggrQosRsp() - sends SME FT AGGR QOS RSP + \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME. + \ SME only looks at rc and tspec field. + \param pMac - global mac structure + \param rspReqd - is SmeAddTsRsp required + \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP + \return tspec + \sa + ----------------------------------------------------------------- */ +void +limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp, + tANI_U8 smesessionId) +{ + tSirMsgQ mmhMsg; + + mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP; + mmhMsg.bodyptr = aggrQosRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, smesessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} +#endif + +/** ----------------------------------------------------------------- + \brief limSendSmePreChannelSwitchInd() - sends an indication to SME + before switching channels for spectrum manangement. + + This function sends a eWNI_SME_PRE_SWITCH_CHL_IND to SME. + + \param pMac - global mac structure + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tANI_U16 msgLen = 0; + tpSirSmePreSwitchChannelInd pPreSwitchChInd; + + msgLen = sizeof(tSirSmePreSwitchChannelInd); + pPreSwitchChInd = vos_mem_malloc(msgLen); + if (NULL == pPreSwitchChInd) + { + limLog(pMac, LOGP, + FL("Memory allocation failed for eWNI_SME_PRE_SWITCH_CHL_IND ")); + return; + } + vos_mem_zero(pPreSwitchChInd, msgLen); + + pPreSwitchChInd->mesgType = eWNI_SME_PRE_SWITCH_CHL_IND; + pPreSwitchChInd->mesgLen = msgLen; + pPreSwitchChInd->sessionId = psessionEntry->smeSessionId; + + mmhMsg.type = eWNI_SME_PRE_SWITCH_CHL_IND; + mmhMsg.bodyptr = pPreSwitchChInd; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} + +/** ----------------------------------------------------------------- + \brief limSendSmePostChannelSwitchInd() - sends an indication to SME + after channel switch for spectrum manangement is complete. + + This function sends a eWNI_SME_POST_SWITCH_CHL_IND to SME. + + \param pMac - global mac structure + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac) +{ + tSirMsgQ mmhMsg; + + mmhMsg.type = eWNI_SME_POST_SWITCH_CHL_IND; + mmhMsg.bodyptr = NULL; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} + +void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tANI_U8 smesessionId) +{ + tSirMsgQ mmhMsg; + tSmeMaxAssocInd *pSmeMaxAssocInd; + + pSmeMaxAssocInd = vos_mem_malloc(sizeof(tSmeMaxAssocInd)); + if ( NULL == pSmeMaxAssocInd ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return; + } + vos_mem_set((void *) pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd),0); + vos_mem_copy( (tANI_U8 *)pSmeMaxAssocInd->peerMac, + (tANI_U8 *)peerMacAddr, sizeof(tSirMacAddr)); + pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED; + pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd); + pSmeMaxAssocInd->sessionId = smesessionId; + mmhMsg.type = pSmeMaxAssocInd->mesgType; + mmhMsg.bodyptr = pSmeMaxAssocInd; + PELOG1(limLog(pMac, LOG1, FL("msgType %s peerMacAddr "MAC_ADDRESS_STR + " sme session id %d"), "eWNI_SME_MAX_ASSOC_EXCEEDED", MAC_ADDR_ARRAY(peerMacAddr));) + MTRACE(macTraceMsgTx(pMac, smesessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** ----------------------------------------------------------------- + \brief limSendSmeCandidateFoundInd() - sends + eWNI_SME_CANDIDATE_FOUND_IND + + After receiving candidate found indication frame from FW, this + function sends a eWNI_SME_CANDIDATE_FOUND_IND to SME to notify + roam candidate(s) are available. + + \param pMac - global mac structure + \param psessionEntry - session info + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeCandidateFoundInd(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd; + + pSirSmeCandidateFoundInd = vos_mem_malloc(sizeof(tSirSmeCandidateFoundInd)); + if (NULL == pSirSmeCandidateFoundInd) { + limLog(pMac, LOGP, + FL("AllocateMemory failed for eWNI_SME_CANDIDATE_FOUND_IND")); + return; + } + + pSirSmeCandidateFoundInd->messageType = eWNI_SME_CANDIDATE_FOUND_IND; + pSirSmeCandidateFoundInd->length = sizeof(tSirSmeCandidateFoundInd); + + pSirSmeCandidateFoundInd->sessionId = sessionId; + + + limLog( pMac, LOG1, FL("posting candidate ind to SME")); + mmhMsg.type = eWNI_SME_CANDIDATE_FOUND_IND; + mmhMsg.bodyptr = pSirSmeCandidateFoundInd; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} /*** end limSendSmeCandidateFoundInd() ***/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** ----------------------------------------------------------------- + \brief limSendSmeDfsEventNotify() - sends + eWNI_SME_DFS_RADAR_FOUND + After receiving WMI_PHYERR_EVENTID indication frame from FW, this + function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify + that a RADAR is found on current operating channel and SAP- + has to move to a new channel. + \param pMac - global mac structure + \param msgType - message type received from lower layer + \param event - event data received from lower layer + \return none + \sa +----------------------------------------------------------------- */ +void +limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, void *event) +{ + tSirMsgQ mmhMsg; + mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND; + mmhMsg.bodyptr = event; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + + +/*-------------------------------------------------------------------------- + \brief limSendDfsChanSwIEUpdate() + This timer handler updates the channel switch IE in beacon template + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + \sa + --------------------------------------------------------------------------*/ +static void +limSendDfsChanSwIEUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + /* Update the beacon template and send to FW */ + if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));) + return; + } + + /* Send update beacon template message */ + limSendBeaconInd(pMac, psessionEntry); + PELOG1(limLog(pMac, LOG1, + FL(" Updated CSA IE, IE COUNT = %d"), + psessionEntry->gLimChannelSwitch.switchCount );) + + return; +} + + +/** ----------------------------------------------------------------- + \brief limSendSmeAPChannelSwitchResp() - sends + eWNI_SME_CHANNEL_CHANGE_RSP + After receiving WDA_SWITCH_CHANNEL_RSP indication this + function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify + that the Channel change has been done to the specified target + channel in the Channel change request + \param pMac - global mac structure + \param psessionEntry - session info + \param pChnlParams - Channel switch params +--------------------------------------------------------------------*/ +void +limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSwitchChannelParams pChnlParams) +{ + tSirMsgQ mmhMsg; + tpSwitchChannelParams pSmeSwithChnlParams; + tANI_U8 channelId; + + pSmeSwithChnlParams = (tSwitchChannelParams *) + vos_mem_malloc(sizeof(tSwitchChannelParams)); + if (NULL == pSmeSwithChnlParams) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for pSmeSwithChnlParams\n")); + return; + } + + vos_mem_set((v_VOID_t*)pSmeSwithChnlParams, + sizeof(tSwitchChannelParams), 0); + + vos_mem_copy(pSmeSwithChnlParams, pChnlParams, + sizeof(tSwitchChannelParams)); + + channelId = pSmeSwithChnlParams->channelNumber; + + /* + * Pass the sme sessionID to SME instead + * PE session ID. + */ + pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId; + + mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP; + mmhMsg.bodyptr = (void *)pSmeSwithChnlParams; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + /* + * We should start beacon transmission only if the new + * channel after channel change is Non-DFS. For a DFS + * channel, PE will receive an explicit request from + * upper layers to start the beacon transmission . + */ + + if (NV_CHANNEL_DFS != vos_nv_getChannelEnabledState(channelId)) + { + if (channelId == psessionEntry->currentOperChannel) + { + limApplyConfiguration(pMac,psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + } + else + { + PELOG1(limLog(pMac, LOG1, + FL("Failed to Transmit Beacons on channel = %d" + "after AP channel change response"), + psessionEntry->bcnLen);) + } + } + return; +} + +/** ----------------------------------------------------------------- + \brief limProcessBeaconTxSuccessInd() - This function is used + explicitely to handle successful beacon transmission indication + from the FW. This is a generic event generated by the FW afer the + first beacon is sent out after the beacon template update by the + host + \param pMac - global mac structure + \param psessionEntry - session info + \return none + \sa +----------------------------------------------------------------- */ +void +limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType, void *event) +{ + /* Currently, this event is used only for DFS channel switch announcement + * IE update in the template. If required to be used for other IE updates + * add appropriate code by introducing a state variable + */ + tpPESession psessionEntry; + tSirMsgQ mmhMsg; + tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse; + tANI_U8 length = sizeof(tSirSmeCSAIeTxCompleteRsp); + tpSirFirstBeaconTxCompleteInd pBcnTxInd = + (tSirFirstBeaconTxCompleteInd *)event; + + if((psessionEntry = + peFindSessionByBssIdx(pMac, pBcnTxInd->bssIdx))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if (eLIM_AP_ROLE == psessionEntry->limSystemRole && + VOS_TRUE == psessionEntry->dfsIncludeChanSwIe) + { + /* Send only 5 beacons with CSA IE Set in when a radar is detected */ + if (psessionEntry->gLimChannelSwitch.switchCount > 0) + { + /* + * Send the next beacon with updated CSA IE count + */ + limSendDfsChanSwIEUpdate(pMac, psessionEntry); + /* Decrement the IE count */ + psessionEntry->gLimChannelSwitch.switchCount--; + } + else + { + /* Done with CSA IE update, send response back to SME */ + psessionEntry->gLimChannelSwitch.switchCount = 0; + if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_FALSE) + psessionEntry->gLimChannelSwitch.switchMode = 0; + psessionEntry->dfsIncludeChanSwIe = VOS_FALSE; + psessionEntry->dfsIncludeChanWrapperIe = VOS_FALSE; + + + pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *) + vos_mem_malloc(length); + + if (NULL == pChanSwTxResponse) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp")); + return; + } + + vos_mem_set((void*)pChanSwTxResponse, length, 0); + pChanSwTxResponse->sessionId = psessionEntry->smeSessionId; + pChanSwTxResponse->chanSwIeTxStatus = VOS_STATUS_SUCCESS; + + mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND; + mmhMsg.bodyptr = pChanSwTxResponse; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + } + } + + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h new file mode 100644 index 0000000000000..676a9f8cab9ca --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limSendSmeRspMessages.h contains the definitions for + * sending SME response/notification messages to applications above + * MAC software. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_SEND_SME_RSP_H +#define __LIM_SEND_SME_RSP_H + +#include "sirCommon.h" +#include "sirApi.h" +#include "sirMacProtDef.h" + + +// Functions for sending responses to Host +void limSendSmeRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U8 , tANI_U16); +void limSendSmeStartBssRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16); +void limSendSmeScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limSendSmeLfrScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16); +#endif +void limPostSmeScanRspMessage(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8,tANI_U16); + +void limSendSmeJoinReassocRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U16,tpPESession,tANI_U8,tANI_U16); +void limSendSmeDisassocNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16,tANI_U8,tANI_U16,tpPESession); +void limSendSmeDeauthNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16, tANI_U8, tANI_U16); +void limSendSmeDisassocInd(tpAniSirGlobal, tpDphHashNode,tpPESession); +void limSendSmeDeauthInd(tpAniSirGlobal, tpDphHashNode, tpPESession psessionEntry); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limSendSmeCandidateFoundInd(tpAniSirGlobal, tANI_U8); +#endif + +void limSendSmeWmStatusChangeNtf(tpAniSirGlobal, tSirSmeStatusChangeCode, tANI_U32 *, tANI_U16, tANI_U8); +void limSendSmeSetContextRsp(tpAniSirGlobal, + tSirMacAddr, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16); +void limSendSmeNeighborBssInd(tpAniSirGlobal, + tLimScanResultNode *); +void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ); +void limHandleCSAoffloadMsg(tpAniSirGlobal pMac,tpSirMsgQ MsgQ); + +#ifdef WLAN_FEATURE_VOWIFI_11R +void +limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp, + tANI_U8 smesessionId); +#endif /*WLAN_FEATURE_VOWIFI_11R*/ + + +void limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry, tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId); +void limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts); +void limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smessionId,tANI_U16 smetransactionId); +void limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession); +void limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); + +void limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +void limSendSmePEGetRoamRssiRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); +#endif +#ifdef FEATURE_WLAN_ESE_UPLOAD +void limSendSmePEEseTsmRsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats); +#endif +void limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes resultCode,tpPESession,tANI_U8,tANI_U16); + + +void limSendSmeGetTxPowerRsp(tpAniSirGlobal pMac, tANI_U32 power, tANI_U32 status); +void limSendSmeGetNoiseRsp(tpAniSirGlobal pMac, tSirMacNoise noise); +void limSendSmeIBSSPeerInd(tpAniSirGlobal pMac,tSirMacAddr peerMacAddr,tANI_U16 staIndex,tANI_U8 ucastIdx,tANI_U8 bcastIdx, + tANI_U8 *beacon,tANI_U16 beaconLen, tANI_U16 msgType, tANI_U8 sessionId); +void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode, + tpPESession psessionEntry); + +#ifdef FEATURE_OEM_DATA_SUPPORT +void limSendSmeOemDataRsp(tpAniSirGlobal pMac, tANI_U32* pMsgBuf, tSirResultCodes resultCode); +#endif +void limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac, + tpPESession psessionEntry); + +void limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac); +void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tANI_U8 smesessionId); +#ifdef FEATURE_WLAN_TDLS +void limSendSmeTdlsDisRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tANI_U16 msgType); +void limSendSmeTdlsLinkStartRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tSirMacAddr peerMac, tANI_U16 msgType); +void limSendSmeTdlsTeardownRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tSirMacAddr peerMac, tANI_U16 msgType); +void limSendSmeTdlsLinkEstablishReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status); +void limSendSmeTdlsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, + void *events); +#endif + +void limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, + void *event); +void limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSwitchChannelParams pChnlParams); +void +limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType, + void *event); + +typedef enum { + lim_csa_ie_present = 0x00000001, + lim_xcsa_ie_present = 0x00000002, + lim_wbw_ie_present = 0x00000004, + lim_cswarp_ie_present = 0x00000008, +}lim_csa_event_ies_present_flag; + +#endif /* __LIM_SEND_SME_RSP_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.c new file mode 100644 index 0000000000000..37215a751852b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.c @@ -0,0 +1,2852 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSerDesUtils.cc contains the serializer/deserializer + * utility functions LIM uses while communicating with upper layer + * software entities + * Author: Chandra Modumudi + * Date: 10/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniSystemDefs.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSerDesUtils.h" + + + +/** + * limCheckRemainingLength() + * + *FUNCTION: + * This function is called while de-serializing received SME_REQ + * message. + * + *LOGIC: + * Remaining message length is checked for > 0. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param len - Remaining message length + * @return retCode - eSIR_SUCCESS if len > 0, else eSIR_FAILURE + */ + +static inline tSirRetStatus +limCheckRemainingLength(tpAniSirGlobal pMac, tANI_S16 len) +{ + if (len > 0) + return eSIR_SUCCESS; + else + { + limLog(pMac, LOGW, + FL("Received SME message with invalid rem length=%d"), + len); + return eSIR_FAILURE; + } +} /*** end limCheckRemainingLength(pMac, ) ***/ + +/** + * limGetBssDescription() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * BSS description from a tANI_U8* buffer pointer to tSirBssDescription + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBssDescription Pointer to the BssDescription to be copied + * @param *pBuf Pointer to the source buffer + * @param rLen Remaining message length being extracted + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * failure (eSIR_FAILURE). + */ + +static tSirRetStatus +limGetBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBssDescription, + tANI_S16 rLen, tANI_S16 *lenUsed, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + pBssDescription->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len = pBssDescription->length; + + if (rLen < (tANI_S16) (len + sizeof(tANI_U16))) + return eSIR_FAILURE; + + *lenUsed = len + sizeof(tANI_U16); + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pBssDescription->bssId, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract timer + vos_mem_copy( (tANI_U8 *) (&pBssDescription->scanSysTimeMsec), + pBuf, sizeof(v_TIME_t)); + pBuf += sizeof(v_TIME_t); + len -= sizeof(v_TIME_t); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract timeStamp + vos_mem_copy( (tANI_U8 *) pBssDescription->timeStamp, + pBuf, sizeof(tSirMacTimeStamp)); + pBuf += sizeof(tSirMacTimeStamp); + len -= sizeof(tSirMacTimeStamp); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract beaconInterval + pBssDescription->beaconInterval = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract capabilityInfo + pBssDescription->capabilityInfo = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract nwType + pBssDescription->nwType = (tSirNwType) limGetU32(pBuf); + pBuf += sizeof(tSirNwType); + len -= sizeof(tSirNwType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract rssi + pBssDescription->rssi = (tANI_S8) *pBuf++; + len --; + + /* Extract raw rssi value */ + pBssDescription->rssi_raw = (tANI_S8) *pBuf++; + len--; + + // Extract sinr + pBssDescription->sinr = (tANI_S8) *pBuf++; + len --; + + // Extract channelId + pBssDescription->channelId = *pBuf++; + len --; + + // Extract channelIdSelf + pBssDescription->channelIdSelf = *pBuf++; + len --; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reserved bssDescription + pBuf += sizeof(pBssDescription->sSirBssDescriptionRsvd); + len -= sizeof(pBssDescription->sSirBssDescriptionRsvd); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //pass the timestamp + pBssDescription->nReceivedTime = limGetU32( pBuf ); + pBuf += sizeof(tANI_TIMESTAMP); + len -= sizeof(tANI_TIMESTAMP); + +#if defined WLAN_FEATURE_VOWIFI + //TSF when the beacon received (parent TSF) + pBssDescription->parentTSF = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + + //start TSF of scan during which this BSS desc was updated. + pBssDescription->startTSF[0] = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + + //start TSF of scan during which this BSS desc was updated. + pBssDescription->startTSF[1] = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + // MobilityDomain + pBssDescription->mdiePresent = *pBuf++; + len --; + pBssDescription->mdie[0] = *pBuf++; + len --; + pBssDescription->mdie[1] = *pBuf++; + len --; + pBssDescription->mdie[2] = *pBuf++; + len --; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("mdie=%02x %02x %02x"), + pBssDescription->mdie[0], + pBssDescription->mdie[1], + pBssDescription->mdie[2]);) +#endif +#endif + +#ifdef FEATURE_WLAN_ESE + pBssDescription->QBSSLoad_present = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract QBSSLoad_avail + pBssDescription->QBSSLoad_avail = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + /* 4 reserved bytes for padding */ + pBuf += sizeof(tANI_U32); + len -= 4; +#endif + pBssDescription->fProbeRsp = *pBuf++; + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + /* 3 reserved bytes for padding */ + pBuf += (3 * sizeof(tANI_U8)); + len -= 3; + + pBssDescription->WscIeLen = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + if (WSCIE_PROBE_RSP_LEN < len) + { + /* Do not copy with WscIeLen + * if WscIeLen is not set properly, memory overwrite happen + * Ended up with memory corruption and crash + * Copy with Fixed size */ + vos_mem_copy( (tANI_U8 *) pBssDescription->WscIeProbeRsp, + pBuf, + WSCIE_PROBE_RSP_LEN); + + } + else + { + limLog(pMac, LOGE, + FL("remaining bytes len %d is less than WSCIE_PROBE_RSP_LEN"), + pBssDescription->WscIeLen); + return eSIR_FAILURE; + } + + /* 1 reserved byte padding */ + pBuf += (WSCIE_PROBE_RSP_LEN + 1); + len -= (WSCIE_PROBE_RSP_LEN + 1); + + if (len > 0) + { + vos_mem_copy( (tANI_U8 *) pBssDescription->ieFields, + pBuf, + len); + } + else if (len < 0) + { + limLog(pMac, LOGE, + FL("remaining length is negative. len = %d, actual length = %d"), + len, pBssDescription->length); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limGetBssDescription() ***/ + + + +/** + * limCopyBssDescription() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * BSS description to a tANI_U8 buffer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *pBuf Pointer to the destination buffer + * @param pBssDescription Pointer to the BssDescription being copied + * @return Length of BSSdescription written + */ + +tANI_U16 +limCopyBssDescription(tpAniSirGlobal pMac, tANI_U8 *pBuf, tSirBssDescription *pBssDescription) +{ + tANI_U16 len = 0; + + limCopyU16(pBuf, pBssDescription->length); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + vos_mem_copy( pBuf, + (tANI_U8 *) pBssDescription->bssId, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len += sizeof(tSirMacAddr); + + PELOG3(limLog(pMac, LOG3, + FL("Copying BSSdescr:channel is %d, bssId is "), + pBssDescription->channelId); + limPrintMacAddr(pMac, pBssDescription->bssId, LOG3);) + + vos_mem_copy( pBuf, + (tANI_U8 *) (&pBssDescription->scanSysTimeMsec), + sizeof(v_TIME_t)); + pBuf += sizeof(v_TIME_t); + len += sizeof(v_TIME_t); + + limCopyU32(pBuf, pBssDescription->timeStamp[0]); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + limCopyU32(pBuf, pBssDescription->timeStamp[1]); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + limCopyU16(pBuf, pBssDescription->beaconInterval); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + limCopyU16(pBuf, pBssDescription->capabilityInfo); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + limCopyU32(pBuf, pBssDescription->nwType); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + *pBuf++ = pBssDescription->rssi; + len++; + + *pBuf++ = pBssDescription->rssi_raw; + len++; + + *pBuf++ = pBssDescription->sinr; + len++; + + *pBuf++ = pBssDescription->channelId; + len++; + + vos_mem_copy( pBuf, (tANI_U8 *) &(pBssDescription->ieFields), + limGetIElenFromBssDescription(pBssDescription)); + + return (len + sizeof(tANI_U16)); +} /*** end limCopyBssDescription() ***/ + + + + + +/** + * limGetKeysInfo() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * key information from a tANI_U8* buffer pointer to tSirKeys + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *pKeyInfo Pointer to the keyInfo to be copied + * @param *pBuf Pointer to the source buffer + * + * @return Length of key info extracted + */ + +static tANI_U32 +limGetKeysInfo(tpAniSirGlobal pMac, tpSirKeys pKeyInfo, tANI_U8 *pBuf) +{ + tANI_U32 len = 0; + + pKeyInfo->keyId = *pBuf++; + len++; + pKeyInfo->unicast = *pBuf++; + len++; + pKeyInfo->keyDirection = (tAniKeyDirection) limGetU32(pBuf); + len += sizeof(tAniKeyDirection); + pBuf += sizeof(tAniKeyDirection); + + vos_mem_copy( pKeyInfo->keyRsc, pBuf, WLAN_MAX_KEY_RSC_LEN); + pBuf += WLAN_MAX_KEY_RSC_LEN; + len += WLAN_MAX_KEY_RSC_LEN; + + pKeyInfo->paeRole = *pBuf++; + len++; + + pKeyInfo->keyLength = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + vos_mem_copy( pKeyInfo->key, pBuf, pKeyInfo->keyLength); + pBuf += pKeyInfo->keyLength; + len += pKeyInfo->keyLength; + + PELOG3(limLog(pMac, LOG3, + FL("Extracted keyId=%d, keyLength=%d, Key is :"), + pKeyInfo->keyId, pKeyInfo->keyLength); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + pKeyInfo->key, pKeyInfo->keyLength);) + + return len; +} /*** end limGetKeysInfo() ***/ + + + +/** + * limStartBssReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_START_BSS_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pStartBssReq Pointer to tSirSmeStartBssReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limStartBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStartBssReq pStartBssReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pStartBssReq || !pBuf) + return eSIR_FAILURE; + + pStartBssReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pStartBssReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_START_BSS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pStartBssReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pStartBssReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pStartBssReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract selfMacAddr + vos_mem_copy( (tANI_U8 *) pStartBssReq->selfMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract beaconInterval + pStartBssReq->beaconInterval = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract dot11Mode + pStartBssReq->dot11mode = *pBuf++; + len --; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + // Extract mcc to scc switch mode + pStartBssReq->cc_switch_mode = *pBuf++; + len --; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; +#endif + + // Extract bssType + pStartBssReq->bssType = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract ssId + if (*pBuf > SIR_MAC_MAX_SSID_LENGTH) + { + // SSID length is more than max allowed 32 bytes + PELOGW(limLog(pMac, LOGW, FL("Invalid SSID length, len=%d"), *pBuf);) + return eSIR_FAILURE; + } + + pStartBssReq->ssId.length = *pBuf++; + len--; + if (len < pStartBssReq->ssId.length) + { + limLog(pMac, LOGW, + FL("SSID length is longer that the remaining length. SSID len=%d, remaining len=%d"), + pStartBssReq->ssId.length, len); + return eSIR_FAILURE; + } + + vos_mem_copy( (tANI_U8 *) pStartBssReq->ssId.ssId, + pBuf, + pStartBssReq->ssId.length); + pBuf += pStartBssReq->ssId.length; + len -= pStartBssReq->ssId.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract channelId + pStartBssReq->channelId = *pBuf++; + len--; + + // Extract CB secondary channel info + pStartBssReq->cbMode = (ePhyChanBondState)limGetU32( pBuf ); + pBuf += sizeof( tANI_U32 ); + len -= sizeof( tANI_U32 ); + + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + // Extract privacy setting + pStartBssReq->privacy = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract Uapsd Enable + pStartBssReq->apUapsdEnable = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract SSID hidden + pStartBssReq->ssidHidden = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pStartBssReq->fwdWPSPBCProbeReq = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract HT Protection Enable + pStartBssReq->protEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract OBSS Protection Enable + pStartBssReq->obssProtEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pStartBssReq->ht_capab = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract AuthType + pStartBssReq->authType = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract dtimPeriod + pStartBssReq->dtimPeriod = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract wps state + pStartBssReq->wps_state = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract isCoalesingInIBSSAllowed + pStartBssReq->isCoalesingInIBSSAllowed = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssPersona + pStartBssReq->bssPersona = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + // Extract txLdpcIniFeatureEnabled + pStartBssReq->txLdpcIniFeatureEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + +#ifdef WLAN_FEATURE_11W + // Extract MFP capable/required + pStartBssReq->pmfCapable = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + pStartBssReq->pmfRequired = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; +#endif + + // Extract rsnIe + pStartBssReq->rsnIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + // Check for RSN IE length (that includes length of type & length + if (pStartBssReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2) + { + limLog(pMac, LOGW, + FL("Invalid RSN IE length %d in SME_START_BSS_REQ"), + pStartBssReq->rsnIE.length); + return eSIR_FAILURE; + } + + vos_mem_copy( pStartBssReq->rsnIE.rsnIEdata, + pBuf, pStartBssReq->rsnIE.length); + + len -= (sizeof(tANI_U16) + pStartBssReq->rsnIE.length); + pBuf += pStartBssReq->rsnIE.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract nwType + pStartBssReq->nwType = (tSirNwType) limGetU32(pBuf); + pBuf += sizeof(tSirNwType); + len -= sizeof(tSirNwType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract operationalRateSet + pStartBssReq->operationalRateSet.numRates = *pBuf++; + + // Check for number of rates + if (pStartBssReq->operationalRateSet.numRates > + SIR_MAC_MAX_NUMBER_OF_RATES) + { + limLog(pMac, LOGW, FL("Invalid numRates %d in SME_START_BSS_REQ"), + pStartBssReq->operationalRateSet.numRates); + return eSIR_FAILURE; + } + + len--; + if (len < pStartBssReq->operationalRateSet.numRates) + return eSIR_FAILURE; + + vos_mem_copy( (tANI_U8 *) pStartBssReq->operationalRateSet.rate, + pBuf, + pStartBssReq->operationalRateSet.numRates); + pBuf += pStartBssReq->operationalRateSet.numRates; + len -= pStartBssReq->operationalRateSet.numRates; + + // Extract extendedRateSet + pStartBssReq->extendedRateSet.numRates = *pBuf++; + len--; + if ((pStartBssReq->nwType == eSIR_11G_NW_TYPE) || + (pStartBssReq->nwType == eSIR_11N_NW_TYPE )) + { + vos_mem_copy( pStartBssReq->extendedRateSet.rate, + pBuf, pStartBssReq->extendedRateSet.numRates); + pBuf += pStartBssReq->extendedRateSet.numRates; + len -= pStartBssReq->extendedRateSet.numRates; + } + else + { + pBuf += pStartBssReq->extendedRateSet.numRates; + len -= pStartBssReq->extendedRateSet.numRates; + pStartBssReq->extendedRateSet.numRates = 0; + } + + vos_mem_copy(&(pStartBssReq->htConfig), pBuf, + sizeof(tSirHTConfig)); + len -= sizeof(tSirHTConfig); + pBuf += sizeof(tSirHTConfig); + + vos_mem_copy(&(pStartBssReq->addIeParams), pBuf, sizeof(tSirAddIeParams)); + len -= sizeof(tSirAddIeParams); + pBuf += sizeof(tSirAddIeParams); + + /* extract obssEnabled */ + pStartBssReq->obssEnabled = *pBuf++; + len--; + + /* extract sap_dot11mc */ + pStartBssReq->sap_dot11mc = *pBuf++; + len--; + + if (len) + { + limLog(pMac, LOGW, FL("Extra bytes left in SME_START_BSS_REQ, len=%d"), len); + } + + return eSIR_SUCCESS; +} /*** end limStartBssReqSerDes() ***/ + + + +/** + * limStopBssReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_STOP_BSS_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pStopBssReq Pointer to tSirSmeStopBssReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limStopBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStopBssReq pStopBssReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + pStopBssReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pStopBssReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_STOP_BSS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pStopBssReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pStopBssReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + // Extract reasonCode + pStopBssReq->reasonCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + len -= sizeof(tSirResultCodes); + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pStopBssReq->bssId, pBuf, sizeof(tSirMacAddr)); + len -= sizeof(tSirMacAddr); + + if (len) + return eSIR_FAILURE; + else + return eSIR_SUCCESS; + +} /*** end limStopBssReqSerDes() ***/ + + + +/** + * limJoinReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_JOIN_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pJoinReq Pointer to tSirSmeJoinReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limJoinReqSerDes(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + tANI_S16 lenUsed = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pJoinReq || !pBuf) + { + PELOGE(limLog(pMac, LOGE, FL("pJoinReq or pBuf is NULL"));) + return eSIR_FAILURE; + } + + // Extract messageType + pJoinReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + // Extract length + len = pJoinReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (pJoinReq->messageType == eWNI_SME_JOIN_REQ) + PELOG1(limLog(pMac, LOG3, FL("SME_JOIN_REQ length %d bytes is:"), len);) + else + PELOG1(limLog(pMac, LOG3, FL("SME_REASSOC_REQ length %d bytes is:"), + len);) + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + { + PELOGE(limLog(pMac, LOGE, FL("len %d is too short"), len);) + return eSIR_FAILURE; + } + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + // Extract sessionId + pJoinReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + // Extract transactionId + pJoinReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract ssId + pJoinReq->ssId.length = *pBuf++; + len--; + vos_mem_copy( (tANI_U8 *) pJoinReq->ssId.ssId, pBuf, pJoinReq->ssId.length); + pBuf += pJoinReq->ssId.length; + len -= pJoinReq->ssId.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract selfMacAddr + vos_mem_copy( pJoinReq->selfMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract bsstype + pJoinReq->bsstype = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract dot11mode + pJoinReq->dot11mode= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + // Extract mcc to scc switch mode + pJoinReq->cc_switch_mode= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + + // Extract bssPersona + pJoinReq->staPersona = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract cbMode + pJoinReq->cbMode = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract uapsdPerAcBitmask + pJoinReq->uapsdPerAcBitmask = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + + // Extract operationalRateSet + pJoinReq->operationalRateSet.numRates= *pBuf++; + len--; + if (pJoinReq->operationalRateSet.numRates) + { + vos_mem_copy( (tANI_U8 *) pJoinReq->operationalRateSet.rate, pBuf, + pJoinReq->operationalRateSet.numRates); + pBuf += pJoinReq->operationalRateSet.numRates; + len -= pJoinReq->operationalRateSet.numRates; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + // Extract extendedRateSet + pJoinReq->extendedRateSet.numRates = *pBuf++; + len--; + if (pJoinReq->extendedRateSet.numRates) + { + vos_mem_copy( pJoinReq->extendedRateSet.rate, pBuf, pJoinReq->extendedRateSet.numRates); + pBuf += pJoinReq->extendedRateSet.numRates; + len -= pJoinReq->extendedRateSet.numRates; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + // Extract RSN IE + pJoinReq->rsnIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + if (pJoinReq->rsnIE.length) + { + // Check for RSN IE length (that includes length of type & length) + if ((pJoinReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2) || + (pJoinReq->rsnIE.length != 2 + *(pBuf + 1))) + { + limLog(pMac, LOGW, + FL("Invalid RSN IE length %d in SME_JOIN_REQ"), + pJoinReq->rsnIE.length); + return eSIR_FAILURE; + } + vos_mem_copy( (tANI_U8 *) pJoinReq->rsnIE.rsnIEdata, + pBuf, pJoinReq->rsnIE.length); + pBuf += pJoinReq->rsnIE.length; + len -= pJoinReq->rsnIE.length; // skip RSN IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + +#ifdef FEATURE_WLAN_ESE + // Extract CCKM IE + pJoinReq->cckmIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (pJoinReq->cckmIE.length) + { + // Check for CCKM IE length (that includes length of type & length) + if ((pJoinReq->cckmIE.length > SIR_MAC_MAX_IE_LENGTH) || + (pJoinReq->cckmIE.length != (2 + *(pBuf + 1)))) + { + limLog(pMac, LOGW, + FL("Invalid CCKM IE length %d/%d in SME_JOIN/REASSOC_REQ"), + pJoinReq->cckmIE.length, 2 + *(pBuf + 1)); + return eSIR_FAILURE; + } + vos_mem_copy((tANI_U8 *) pJoinReq->cckmIE.cckmIEdata, + pBuf, pJoinReq->cckmIE.length); + pBuf += pJoinReq->cckmIE.length; + len -= pJoinReq->cckmIE.length; // skip CCKM IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } +#endif + + // Extract Add IE for scan + pJoinReq->addIEScan.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + if (pJoinReq->addIEScan.length) + { + // Check for IE length (that includes length of type & length) + if (pJoinReq->addIEScan.length > SIR_MAC_MAX_ADD_IE_LENGTH + 2) + { + limLog(pMac, LOGE, + FL("Invalid addIE Scan length %d in SME_JOIN_REQ"), + pJoinReq->addIEScan.length); + return eSIR_FAILURE; + } + // Check for P2P IE length (that includes length of type & length) + vos_mem_copy( (tANI_U8 *) pJoinReq->addIEScan.addIEdata, + pBuf, pJoinReq->addIEScan.length); + pBuf += pJoinReq->addIEScan.length; + len -= pJoinReq->addIEScan.length; // skip add IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + pJoinReq->addIEAssoc.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + // Extract Add IE for assoc + if (pJoinReq->addIEAssoc.length) + { + // Check for IE length (that includes length of type & length) + if (pJoinReq->addIEAssoc.length > SIR_MAC_MAX_IE_LENGTH + 2) + { + limLog(pMac, LOGE, + FL("Invalid addIE Assoc length %d in SME_JOIN_REQ"), + pJoinReq->addIEAssoc.length); + return eSIR_FAILURE; + } + // Check for P2P IE length (that includes length of type & length) + vos_mem_copy( (tANI_U8 *) pJoinReq->addIEAssoc.addIEdata, + pBuf, pJoinReq->addIEAssoc.length); + pBuf += pJoinReq->addIEAssoc.length; + len -= pJoinReq->addIEAssoc.length; // skip add IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + pJoinReq->UCEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + pJoinReq->MCEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#ifdef WLAN_FEATURE_11W + pJoinReq->MgmtEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + //is11Rconnection; + pJoinReq->is11Rconnection = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef FEATURE_WLAN_ESE + //ESE version IE + pJoinReq->isESEFeatureIniEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //isESEconnection; + pJoinReq->isESEconnection = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // TSPEC information + pJoinReq->eseTspecInfo.numTspecs = *pBuf++; + len -= sizeof(tANI_U8); + vos_mem_copy((void*)&pJoinReq->eseTspecInfo.tspec[0], pBuf, + (sizeof(tTspecInfo)* pJoinReq->eseTspecInfo.numTspecs)); + pBuf += sizeof(tTspecInfo)*SIR_ESE_MAX_TSPEC_IES; + len -= sizeof(tTspecInfo)*SIR_ESE_MAX_TSPEC_IES; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + //isFastTransitionEnabled; + pJoinReq->isFastTransitionEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef FEATURE_WLAN_LFR + //isFastRoamIniFeatureEnabled; + pJoinReq->isFastRoamIniFeatureEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + + //txLdpcIniFeatureEnabled + pJoinReq->txLdpcIniFeatureEnabled= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //HT Config + vos_mem_copy(&(pJoinReq->htConfig), pBuf, sizeof(tSirHTConfig)); + len -= sizeof(tSirHTConfig); + pBuf += sizeof(tSirHTConfig); + + //txBFIniFeatureEnabled + pJoinReq->txBFIniFeatureEnabled= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //txBFCsnValue + pJoinReq->txBFCsnValue= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //MuBformee + pJoinReq->txMuBformee= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //enableVhtpAid + pJoinReq->enableVhtpAid= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //enableVhtGid + pJoinReq->enableVhtGid= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //enableAmpduPs + pJoinReq->enableAmpduPs= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //enableHtSmps + pJoinReq->enableHtSmps= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // htSmps + pJoinReq->htSmps= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pJoinReq->isAmsduSupportInAMPDU= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pJoinReq->isWMEenabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pJoinReq->isQosEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pJoinReq->isOSENConnection = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + // Extract Titan CB Neighbor BSS info + pJoinReq->cbNeighbors.cbBssFoundPri = *pBuf; + pBuf++; + pJoinReq->cbNeighbors.cbBssFoundSecUp = *pBuf; + pBuf++; + pJoinReq->cbNeighbors.cbBssFoundSecDown = *pBuf; + pBuf++; + len -= 3; + + // Extract Spectrum Mgt Indicator + pJoinReq->spectrumMgtIndicator = (tAniBool) limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + + pJoinReq->powerCap.minTxPower = *pBuf++; + pJoinReq->powerCap.maxTxPower = *pBuf++; + len -=2; + + pJoinReq->supportedChannels.numChnl = *pBuf++; + len--; + vos_mem_copy( (tANI_U8 *) pJoinReq->supportedChannels.channelList, + pBuf, pJoinReq->supportedChannels.numChnl); + pBuf += pJoinReq->supportedChannels.numChnl; + len-= pJoinReq->supportedChannels.numChnl; + + PELOG2(limLog(pMac, LOG2, + FL("spectrumInd ON: minPower %d, maxPower %d , numChnls %d"), + pJoinReq->powerCap.minTxPower, + pJoinReq->powerCap.maxTxPower, + pJoinReq->supportedChannels.numChnl);) + + // Extract uapsdPerAcBitmask + pJoinReq->uapsdPerAcBitmask = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // + // NOTE - tSirBssDescription is now moved to the end + // of tSirSmeJoinReq structure. This is to accomodate + // the variable length data member ieFields[1] + // + if (limGetBssDescription( pMac, &pJoinReq->bssDescription, + len, &lenUsed, pBuf) == eSIR_FAILURE) + { + PELOGE(limLog(pMac, LOGE, FL("get bss description failed"));) + return eSIR_FAILURE; + } + PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + (tANI_U8 *) &(pJoinReq->bssDescription), + pJoinReq->bssDescription.length + 2);) + pBuf += lenUsed; + len -= lenUsed; + + return eSIR_SUCCESS; +} /*** end limJoinReqSerDes() ***/ + + +/**--------------------------------------------------------------- +\fn limAssocIndSerDes +\brief This function is called by limProcessMlmAssocInd() to +\ populate the SME_ASSOC_IND message based on the received +\ MLM_ASSOC_IND. +\ +\param pMac +\param pAssocInd - Pointer to the received tLimMlmAssocInd +\param pBuf - Pointer to serialized buffer +\param psessionEntry - pointer to PE session entry +\ +\return None +------------------------------------------------------------------*/ +void +limAssocIndSerDes(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd, tANI_U8 *pBuf, tpPESession psessionEntry) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + + mLen = sizeof(tANI_U32); + mLen += sizeof(tANI_U8); + pBuf += sizeof(tANI_U16); + *pBuf = psessionEntry->smeSessionId; + pBuf += sizeof(tANI_U8); + + // Fill in peerMacAddr + vos_mem_copy( pBuf, pAssocInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in aid + limCopyU16(pBuf, pAssocInd->aid); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in staId + limCopyU16(pBuf, psessionEntry->staId); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in authType + limCopyU32(pBuf, pAssocInd->authType); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + + // Fill in ssId + vos_mem_copy( pBuf, (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1); + pBuf += (1 + pAssocInd->ssId.length); + mLen += (1 + pAssocInd->ssId.length); + + // Fill in rsnIE + limCopyU16(pBuf, pAssocInd->rsnIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + vos_mem_copy( pBuf, (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata), + pAssocInd->rsnIE.length); + pBuf += pAssocInd->rsnIE.length; + mLen += pAssocInd->rsnIE.length; + + + limCopyU32(pBuf, pAssocInd->spectrumMgtIndicator); + pBuf += sizeof(tAniBool); + mLen += sizeof(tAniBool); + + if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE) + { + *pBuf = pAssocInd->powerCap.minTxPower; + pBuf++; + *pBuf = pAssocInd->powerCap.maxTxPower; + pBuf++; + mLen += sizeof(tSirMacPowerCapInfo); + + *pBuf = pAssocInd->supportedChannels.numChnl; + pBuf++; + mLen++; + + vos_mem_copy( pBuf, + (tANI_U8 *) &(pAssocInd->supportedChannels.channelList), + pAssocInd->supportedChannels.numChnl); + + + pBuf += pAssocInd->supportedChannels.numChnl; + mLen += pAssocInd->supportedChannels.numChnl; + } + limCopyU32(pBuf, pAssocInd->WmmStaInfoPresent); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + // Fill in length of SME_ASSOC_IND message + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_ASSOC_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) +} /*** end limAssocIndSerDes() ***/ + + + +/** + * limAssocCnfSerDes() + * + *FUNCTION: + * This function is called by limProcessLmmMessages() when + * SME_ASSOC_CNF or SME_REASSOC_CNF message is received from + * upper layer software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAssocCnf Pointer to tSirSmeAssocCnf being extracted into + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limAssocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeAssocCnf pAssocCnf, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pAssocCnf || !pBuf) + return eSIR_FAILURE; + + pAssocCnf->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + pAssocCnf->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (pAssocCnf->messageType == eWNI_SME_ASSOC_CNF) + { + PELOG1(limLog(pMac, LOG1, FL("SME_ASSOC_CNF length %d bytes is:"), pAssocCnf->length);) + } + else + { + PELOG1(limLog(pMac, LOG1, FL("SME_REASSOC_CNF length %d bytes is:"), pAssocCnf->length);) + } + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pAssocCnf->length);) + + // status code + pAssocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + + // bssId + vos_mem_copy( pAssocCnf->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // peerMacAddr + vos_mem_copy( pAssocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + + pAssocCnf->aid = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + // alternateBssId + vos_mem_copy( pAssocCnf->alternateBssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // alternateChannelId + pAssocCnf->alternateChannelId = *pBuf; + pBuf++; + + return eSIR_SUCCESS; +} /*** end limAssocCnfSerDes() ***/ + + + +/** + * limDisassocCnfSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() when + * SME_DISASSOC_CNF message is received from upper layer software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDisassocCnf Pointer to tSirSmeDisassocCnf being + * extracted into + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limDisassocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeDisassocCnf pDisassocCnf, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDisassocCnf || !pBuf) + return eSIR_FAILURE; + + pDisassocCnf->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + pDisassocCnf->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_CNF length %d bytes is:"), pDisassocCnf->length);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pDisassocCnf->length);) + + pDisassocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + + vos_mem_copy( pDisassocCnf->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + vos_mem_copy( pDisassocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + + + return eSIR_SUCCESS; +} /*** end limDisassocCnfSerDes() ***/ + + + + + +/**--------------------------------------------------------------- +\fn limReassocIndSerDes +\brief This function is called by limProcessMlmReassocInd() to +\ populate the SME_REASSOC_IND message based on the received +\ MLM_REASSOC_IND. +\ +\param pMac +\param pReassocInd - Pointer to the received tLimMlmReassocInd +\param pBuf - Pointer to serialized buffer +\param psessionEntry - pointer to PE session entry +\ +\return None +------------------------------------------------------------------*/ +void +limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8 *pBuf, tpPESession psessionEntry) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + + mLen = sizeof(tANI_U32); + pBuf += sizeof(tANI_U16); + *pBuf++ = psessionEntry->smeSessionId; + mLen += sizeof(tANI_U8); + + // Fill in peerMacAddr + vos_mem_copy( pBuf, pReassocInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in oldMacAddr + vos_mem_copy( pBuf, pReassocInd->currentApAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in aid + limCopyU16(pBuf, pReassocInd->aid); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in staId + limCopyU16(pBuf, psessionEntry->staId); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in authType + limCopyU32(pBuf, pReassocInd->authType); + pBuf += sizeof(tAniAuthType); + mLen += sizeof(tAniAuthType); + + // Fill in ssId + vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->ssId), + pReassocInd->ssId.length + 1); + pBuf += 1 + pReassocInd->ssId.length; + mLen += pReassocInd->ssId.length + 1; + + // Fill in rsnIE + limCopyU16(pBuf, pReassocInd->rsnIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->rsnIE.rsnIEdata), + pReassocInd->rsnIE.length); + pBuf += pReassocInd->rsnIE.length; + mLen += pReassocInd->rsnIE.length; + + // Fill in addIE + limCopyU16(pBuf, pReassocInd->addIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + vos_mem_copy( pBuf, (tANI_U8*) &(pReassocInd->addIE.addIEdata), + pReassocInd->addIE.length); + pBuf += pReassocInd->addIE.length; + mLen += pReassocInd->addIE.length; + + + limCopyU32(pBuf, pReassocInd->spectrumMgtIndicator); + pBuf += sizeof(tAniBool); + mLen += sizeof(tAniBool); + + if (pReassocInd->spectrumMgtIndicator == eSIR_TRUE) + { + *pBuf = pReassocInd->powerCap.minTxPower; + pBuf++; + *pBuf = pReassocInd->powerCap.maxTxPower; + pBuf++; + mLen += sizeof(tSirMacPowerCapInfo); + + *pBuf = pReassocInd->supportedChannels.numChnl; + pBuf++; + mLen++; + + vos_mem_copy( pBuf, + (tANI_U8 *) &(pReassocInd->supportedChannels.channelList), + pReassocInd->supportedChannels.numChnl); + + pBuf += pReassocInd->supportedChannels.numChnl; + mLen += pReassocInd->supportedChannels.numChnl; + } + limCopyU32(pBuf, pReassocInd->WmmStaInfoPresent); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + + // Fill in length of SME_REASSOC_IND message + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_REASSOC_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) +} /*** end limReassocIndSerDes() ***/ + + +/** + * limAuthIndSerDes() + * + *FUNCTION: + * This function is called by limProcessMlmAuthInd() while sending + * SME_AUTH_IND to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAuthInd Pointer to tSirSmeAuthInd being sent + * @param pBuf Pointer to serialized buffer + * + * @return None + */ + +void +limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + mLen = sizeof(tANI_U32); + pBuf += sizeof(tANI_U16); + *pBuf++ = pAuthInd->sessionId; + mLen += sizeof(tANI_U8); + + // BTAMP TODO: Fill in bssId + vos_mem_set(pBuf, sizeof(tSirMacAddr), 0); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + vos_mem_copy( pBuf, pAuthInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + limCopyU32(pBuf, pAuthInd->authType); + pBuf += sizeof(tAniAuthType); + mLen += sizeof(tAniAuthType); + + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_AUTH_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) +} /*** end limAuthIndSerDes() ***/ + + + +/** + * limSetContextReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SETCONTEXT_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pSetContextReq Pointer to tSirSmeSetContextReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limSetContextReqSerDes(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + tANI_U16 totalKeySize = sizeof(tANI_U8); // initialized to sizeof numKeys + tANI_U8 numKeys; + tANI_U8 *pKeys; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + if (!pSetContextReq || !pBuf) + return eSIR_FAILURE; + + pSetContextReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pSetContextReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_SETCONTEXT_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pSetContextReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pSetContextReq->transactionId = sirReadU16N(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + vos_mem_copy( (tANI_U8 *) pSetContextReq->peerMacAddr, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + vos_mem_copy( pSetContextReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pSetContextReq->keyMaterial.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pSetContextReq->keyMaterial.edType = (tAniEdType) limGetU32(pBuf); + pBuf += sizeof(tAniEdType); + len -= sizeof(tAniEdType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + numKeys = pSetContextReq->keyMaterial.numKeys = *pBuf++; + len -= sizeof(numKeys); + + if (numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + return eSIR_FAILURE; + + /** Initialize the Default Keys if no Keys are being sent from the upper layer*/ + if( limCheckRemainingLength(pMac, len) == eSIR_FAILURE) { + tpSirKeys pKeyinfo = pSetContextReq->keyMaterial.key; + + pKeyinfo->keyId = 0; + pKeyinfo->keyDirection = eSIR_TX_RX; + pKeyinfo->keyLength = 0; + + if (!limIsAddrBC(pSetContextReq->peerMacAddr)) + pKeyinfo->unicast = 1; + else + pKeyinfo->unicast = 0; + }else { + pKeys = (tANI_U8 *) pSetContextReq->keyMaterial.key; + do { + tANI_U32 keySize = limGetKeysInfo(pMac, (tpSirKeys) pKeys, + pBuf); + pBuf += keySize; + pKeys += sizeof(tSirKeys); + totalKeySize += (tANI_U16) keySize; + if (numKeys == 0) + break; + numKeys--; + }while (numKeys); + } + return eSIR_SUCCESS; +} /*** end limSetContextReqSerDes() ***/ + +/** + * limRemoveKeyReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_REMOVEKEY_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pRemoveKeyReq Pointer to tSirSmeRemoveKeyReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + if (!pRemoveKeyReq || !pBuf) + return eSIR_FAILURE; + + pRemoveKeyReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pRemoveKeyReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_REMOVEKEY_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + vos_mem_copy( (tANI_U8 *) pRemoveKeyReq->peerMacAddr, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + pRemoveKeyReq->edType = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->wepType = *pBuf; + + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->keyId = *pBuf; + + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->unicast = *pBuf; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( pRemoveKeyReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pRemoveKeyReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pRemoveKeyReq->transactionId = sirReadU16N(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + return eSIR_SUCCESS; +} /*** end limRemoveKeyReqSerDes() ***/ + + + +/** + * limDisassocReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_DISASSOC_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDisassocReq Pointer to tSirSmeDisassocReq being extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limDisassocReqSerDes(tpAniSirGlobal pMac, tSirSmeDisassocReq *pDisassocReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDisassocReq || !pBuf) + return eSIR_FAILURE; + + pDisassocReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pDisassocReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionID + pDisassocReq->sessionId = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionid + pDisassocReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pDisassocReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract peerMacAddr + vos_mem_copy( pDisassocReq->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reasonCode + pDisassocReq->reasonCode = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pDisassocReq->doNotSendOverTheAir = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + + + return eSIR_SUCCESS; +} /*** end limDisassocReqSerDes() ***/ + + + +/** + * limDeauthReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_DEAUTH_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDeauthReq Pointer to tSirSmeDeauthReq being extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ +tSirRetStatus +limDeauthReqSerDes(tpAniSirGlobal pMac, tSirSmeDeauthReq *pDeauthReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDeauthReq || !pBuf) + return eSIR_FAILURE; + + pDeauthReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pDeauthReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DEAUTH_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pDeauthReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pDeauthReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( pDeauthReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract peerMacAddr + vos_mem_copy( pDeauthReq->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reasonCode + pDeauthReq->reasonCode = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + + return eSIR_SUCCESS; +} /*** end limDisassocReqSerDes() ***/ + + +/** + * limStatSerDes() + * + *FUNCTION: + * This function is called by limSendSmeDisassocNtf() while sending + * SME_DISASSOC_IND/eWNI_SME_DISASSOC_RSP to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAssocInd Pointer to tpAniStaStatStruct being sent + * @param pBuf Pointer to serialized buffer + * + * @return None + */ + +void +limStatSerDes(tpAniSirGlobal pMac, tpAniStaStatStruct pStat, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + limCopyU32(pBuf, pStat->sentAesBlksUcastHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->sentAesBlksUcastLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->recvAesBlksUcastHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->recvAesBlksUcastLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesFormatErrorUcastCnts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesReplaysUcast); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesDecryptErrUcast); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->singleRetryPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->failedTxPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->ackTimeouts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->multiRetryPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->fragTxCntsHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->fragTxCntsLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->transmittedPktsHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->transmittedPktsLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->phyStatHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->phyStatLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkRssi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkSinr); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkRate); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkRssi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkSinr); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkRate); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->nRcvBytes); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->nXmitBytes); + pBuf += sizeof(tANI_U32); + + PELOG1(limLog(pMac, LOG1, FL("STAT: length %d bytes is:"), sizeof(tAniStaStatStruct));) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, sizeof(tAniStaStatStruct));) + +} /*** end limStatSerDes() ***/ + + + + +/** + * limPackBkgndScanFailNotify() + * + *FUNCTION: + * This function is called by limSendSmeWmStatusChangeNtf() + * to pack the tSirBackgroundScanInfo message + * + */ +void +limPackBkgndScanFailNotify(tpAniSirGlobal pMac, + tSirSmeStatusChangeCode statusChangeCode, + tpSirBackgroundScanInfo pScanInfo, + tSirSmeWmStatusChangeNtf *pSmeNtf, + tANI_U8 sessionId) +{ + + tANI_U16 length = (sizeof(tANI_U16) * 2) + sizeof(tANI_U8) + + sizeof(tSirSmeStatusChangeCode) + + sizeof(tSirBackgroundScanInfo); + + pSmeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF; + pSmeNtf->statusChangeCode = statusChangeCode; + pSmeNtf->length = length; + pSmeNtf->sessionId = sessionId; + pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanSuccess = pScanInfo->numOfScanSuccess; + pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanFailure = pScanInfo->numOfScanFailure; + pSmeNtf->statusChangeInfo.bkgndScanInfo.reserved = pScanInfo->reserved; +} + + +/** + * limIsSmeGetAssocSTAsReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_GET_ASSOC_STAS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pBuf - Pointer to a serialized SME_GET_ASSOC_STAS_REQ message + * @param pSmeMsg - Pointer to a tSirSmeGetAssocSTAsReq structure + * @return true if SME_GET_ASSOC_STAS_REQ message is formatted correctly + * false otherwise + */ +tANI_BOOLEAN +limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + pGetAssocSTAsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pGetAssocSTAsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pGetAssocSTAsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract modId + pGetAssocSTAsReq->modId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pUsrContext + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pUsrContext, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pSapEventCallback + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pSapEventCallback, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pAssocStasArray + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pAssocStasArray, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + + PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_ASSOC_STAS_REQ invalid length"));) + return eANI_BOOLEAN_FALSE; + } + + return eANI_BOOLEAN_TRUE; +} + +/** + * limTkipCntrMeasReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * eWNI_SME_TKIP_CNTR_MEAS_REQ from host HDD + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param tpSirSmeTkipCntrMeasReq Pointer to tSirSmeTkipCntrMeasReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ +tSirRetStatus +limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq pTkipCntrMeasReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + pTkipCntrMeasReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pTkipCntrMeasReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pTkipCntrMeasReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pTkipCntrMeasReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pTkipCntrMeasReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bEnable + pTkipCntrMeasReq->bEnable = *pBuf++; + len --; + + PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length consumed %d bytes "), len);) + + if (len) + { + PELOGE(limLog(pMac, LOGE, FL("SME_TKIP_CNTR_MEAS_REQ invalid "));) + return eSIR_FAILURE; + } + else + return eSIR_SUCCESS; +} + +/** + * limIsSmeGetWPSPBCSessionsReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeGetWPSPBCSessions() upon + * receiving query WPS PBC overlap information message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pBuf - Pointer to a serialized SME_GET_WPSPBC_SESSION_REQ message + * @param pGetWPSPBCSessionsReq - Pointer to a tSirSmeGetWPSPBCSessionsReq structure + * @return true if SME_GET_WPSPBC_SESSION_REQ message is formatted correctly + * false otherwise + */ + +tSirRetStatus +limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirSmeGetWPSPBCSessionsReq));) + + pGetWPSPBCSessionsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pGetWPSPBCSessionsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pUsrContext + vos_mem_copy((tANI_U8 *)pGetWPSPBCSessionsReq->pUsrContext, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pSapEventCallback + vos_mem_copy((tANI_U8 *)pGetWPSPBCSessionsReq->pSapEventCallback, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pGetWPSPBCSessionsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + + // Extract MAC address of Station to be removed + vos_mem_copy( (tANI_U8 *) pGetWPSPBCSessionsReq->pRemoveMac, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + + PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + + +/**--------------------------------------------------------------- +\fn limGetSessionInfo +\brief This function returns the sessionId and transactionId +\ of a message. This assumes that the message structure +\ is of format: +\ tANI_U16 messageType +\ tANI_U16 messageLength +\ tANI_U8 sessionId +\ tANI_U16 transactionId +\param pMac - pMac global structure +\param *pBuf - pointer to the message buffer +\param sessionId - returned session id value +\param transactionId - returned transaction ID value +\return None +------------------------------------------------------------------*/ +void +limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *sessionId, tANI_U16 *transactionId) +{ + if (!pBuf) + { + limLog(pMac, LOGE, FL("NULL ptr received. ")); + return; + } + + pBuf += sizeof(tANI_U16); // skip message type + pBuf += sizeof(tANI_U16); // skip message length + + *sessionId = *pBuf; // get sessionId + pBuf++; + *transactionId = limGetU16(pBuf); // get transactionId + + return; +} + + +/** + * limUpdateAPWPSIEsReqSerDes() + * + *FUNCTION: + * This function is to deserialize UpdateAPWPSIEs message + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pUpdateAPWPSIEsReq Pointer to tSirUpdateAPWPSIEsReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPSIEsReq));) + + if (!pUpdateAPWPSIEsReq || !pBuf) + return eSIR_FAILURE; + + pUpdateAPWPSIEsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pUpdateAPWPSIEsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pUpdateAPWPSIEsReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pUpdateAPWPSIEsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pUpdateAPWPSIEsReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract APWPSIEs + vos_mem_copy( (tSirAPWPSIEs *) &pUpdateAPWPSIEsReq->APWPSIEs, pBuf, sizeof(tSirAPWPSIEs)); + pBuf += sizeof(tSirAPWPSIEs); + len -= sizeof(tSirAPWPSIEs); + + PELOG1(limLog(pMac, LOG1, FL("SME_UPDATE_APWPSIE_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_UPDATE_APWPSIE_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limSetContextReqSerDes() ***/ + +/** + * limUpdateAPWPARSNIEsReqSerDes () + * + *FUNCTION: + * This function is to deserialize UpdateAPWPSIEs message + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pUpdateAPWPARSNIEsReq Pointer to tpSirUpdateAPWPARSNIEsReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPARSNIEsReq));) + + if (!pUpdateAPWPARSNIEsReq || !pBuf) + return eSIR_FAILURE; + + pUpdateAPWPARSNIEsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pUpdateAPWPARSNIEsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pUpdateAPWPARSNIEsReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof(tANI_U16); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pUpdateAPWPARSNIEsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pUpdateAPWPARSNIEsReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract APWPARSNIEs + vos_mem_copy( (tSirRSNie *) &pUpdateAPWPARSNIEsReq->APWPARSNIEs, pBuf, sizeof(tSirRSNie)); + pBuf += sizeof(tSirRSNie); + len -= sizeof(tSirRSNie); + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limUpdateAPWPARSNIEsReqSerDes() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.h new file mode 100644 index 0000000000000..62e6129fe898f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSerDesUtils.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSerDesUtils.h contains the utility definitions + * LIM uses while processing messages from upper layer software + * modules + * Author: Chandra Modumudi + * Date: 10/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SERDES_UTILS_H +#define __LIM_SERDES_UTILS_H + +#include "sirApi.h" +#include "aniSystemDefs.h" +#include "sirMacProtDef.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limPropExtsUtils.h" + +tSirRetStatus limStartBssReqSerDes(tpAniSirGlobal, tpSirSmeStartBssReq, tANI_U8 *); +tSirRetStatus limStopBssReqSerDes(tpAniSirGlobal, tpSirSmeStopBssReq, tANI_U8 *); +tSirRetStatus limJoinReqSerDes(tpAniSirGlobal, tpSirSmeJoinReq, tANI_U8 *); +void limAssocIndSerDes(tpAniSirGlobal, tpLimMlmAssocInd, tANI_U8 *, tpPESession); +void limReassocIndSerDes(tpAniSirGlobal, tpLimMlmReassocInd, tANI_U8 *, tpPESession psessionEntry); +tSirRetStatus limAssocCnfSerDes(tpAniSirGlobal, tpSirSmeAssocCnf, tANI_U8 *); +tSirRetStatus limDisassocCnfSerDes(tpAniSirGlobal, tpSirSmeDisassocCnf, tANI_U8 *); +tSirRetStatus limSetContextReqSerDes(tpAniSirGlobal, tpSirSmeSetContextReq, tANI_U8 *); +tSirRetStatus limDisassocReqSerDes(tpAniSirGlobal, tSirSmeDisassocReq *, tANI_U8 *); +tSirRetStatus limDeauthReqSerDes(tpAniSirGlobal, tSirSmeDeauthReq *, tANI_U8 *); +void limAuthIndSerDes(tpAniSirGlobal, tpLimMlmAuthInd, tANI_U8 *); +void limStatSerDes(tpAniSirGlobal, tpAniStaStatStruct, tANI_U8 *); +void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *); + + +void limPackBkgndScanFailNotify(tpAniSirGlobal, tSirSmeStatusChangeCode, + tpSirBackgroundScanInfo, tSirSmeWmStatusChangeNtf *, tANI_U8); + + +tSirRetStatus limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 * pBuf); + +tANI_BOOLEAN limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf); +tSirRetStatus limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq ptkipCntrMeasReq, tANI_U8 *pBuf); + +tSirRetStatus limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf); +tSirRetStatus limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf); + + +// Byte String <--> tANI_U16/tANI_U32 copy functions +static inline void limCopyU16(tANI_U8 *ptr, tANI_U16 u16Val) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + *ptr++ = (tANI_U8) (u16Val & 0xff); + *ptr = (tANI_U8) ((u16Val >> 8) & 0xff); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline tANI_U16 limGetU16(tANI_U8 *ptr) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + return (((tANI_U16) (*(ptr+1) << 8)) | + ((tANI_U16) (*ptr))); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline void limCopyU32(tANI_U8 *ptr, tANI_U32 u32Val) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + *ptr++ = (tANI_U8) (u32Val & 0xff); + *ptr++ = (tANI_U8) ((u32Val >> 8) & 0xff); + *ptr++ = (tANI_U8) ((u32Val >> 16) & 0xff); + *ptr = (tANI_U8) ((u32Val >> 24) & 0xff); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline tANI_U32 limGetU32(tANI_U8 *ptr) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + return ((*(ptr+3) << 24) | + (*(ptr+2) << 16) | + (*(ptr+1) << 8) | + (*(ptr))); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +#endif /* __LIM_SERDES_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSession.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSession.c new file mode 100644 index 0000000000000..b6bc342458af4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSession.c @@ -0,0 +1,799 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limSession.c + + \brief implementation for lim Session related APIs + + \author Sunit Bhatia + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "limDebug.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#include "limFT.h" +#endif +#include "limSession.h" +#include "limUtils.h" +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#include "pmmApi.h" +#include "schApi.h" +#include "limSendMessages.h" + +/*-------------------------------------------------------------------------- + + \brief peInitBeaconParams() - Initialize the beaconParams structure + + + \param tpPESession - pointer to the session context or NULL if session can not be created. + \return void + \sa + + --------------------------------------------------------------------------*/ + +void peInitBeaconParams(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + psessionEntry->beaconParams.beaconInterval = 0; + psessionEntry->beaconParams.fShortPreamble = 0; + psessionEntry->beaconParams.llaCoexist = 0; + psessionEntry->beaconParams.llbCoexist = 0; + psessionEntry->beaconParams.llgCoexist = 0; + psessionEntry->beaconParams.ht20Coexist = 0; + psessionEntry->beaconParams.llnNonGFCoexist = 0; + psessionEntry->beaconParams.fRIFSMode = 0; + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0; + psessionEntry->beaconParams.gHTObssMode = 0; + + // Number of legacy STAs associated + vos_mem_set((void*)&psessionEntry->gLim11bParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLim11aParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLim11gParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimNonGfParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimHt20Params, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimLsigTxopParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimOlbcParams, sizeof(tLimProtStaParams), 0); +} + +/** + * pe_reset_protection_callback() - resets protection structs so that when an AP + * causing use of protection goes away, corresponding protection bit can be + * reset + * @ptr: pointer to pSessionEntry + * + * This function resets protection structs so that when an AP causing use of + * protection goes away, corresponding protection bit can be reset. This allowes + * protection bits to be reset once legacy overlapping APs are gone. + * + * Return: void + */ +void pe_reset_protection_callback(void *ptr) +{ + tpPESession pe_session_entry = (tpPESession)ptr; + tpAniSirGlobal mac_ctx = (tpAniSirGlobal)pe_session_entry->mac_ctx; + int8_t i = 0; + tUpdateBeaconParams beacon_params; + tANI_U16 current_protection_state = 0; + tpDphHashNode station_hash_node = NULL; + + if (pe_session_entry->valid == false) { + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_ERROR, + FL("session already deleted. exiting timer callback")); + return; + } + + current_protection_state |= + pe_session_entry->gLimOverlap11gParams.protectionEnabled | + pe_session_entry->gLimOverlap11aParams.protectionEnabled << 1 | + pe_session_entry->gLimOverlapHt20Params.protectionEnabled << 2 | + pe_session_entry->gLimOverlapNonGfParams.protectionEnabled << 3 ; + + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_INFO, + FL("old protection state: 0x%04X, " + "new protection state: 0x%04X\n"), + pe_session_entry->old_protection_state, + current_protection_state); + + vos_mem_zero(&pe_session_entry->gLimOverlap11gParams, + sizeof(pe_session_entry->gLimOverlap11gParams)); + vos_mem_zero(&pe_session_entry->gLimOverlap11aParams, + sizeof(pe_session_entry->gLimOverlap11aParams)); + vos_mem_zero(&pe_session_entry->gLimOverlapHt20Params, + sizeof(pe_session_entry->gLimOverlapHt20Params)); + vos_mem_zero(&pe_session_entry->gLimOverlapNonGfParams, + sizeof(pe_session_entry->gLimOverlapNonGfParams)); + + vos_mem_zero(&pe_session_entry->beaconParams, + sizeof(pe_session_entry->beaconParams)); + + /* index 0, is self node, peers start from 1 */ + for(i = 1 ; i < mac_ctx->lim.gLimAssocStaLimit ; i++) + { + station_hash_node = dphGetHashEntry(mac_ctx, i, + &pe_session_entry->dph.dphHashTable); + if (NULL == station_hash_node) + continue; + limDecideApProtection(mac_ctx, station_hash_node->staAddr, + &beacon_params, pe_session_entry); + } + + if ((current_protection_state != pe_session_entry->old_protection_state) && + (VOS_FALSE == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) { + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_INFO, + FL("protection changed, update beacon template\n")); + /* update beacon fix params and send update to FW */ + vos_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams)); + beacon_params.bssIdx = pe_session_entry->bssIdx; + beacon_params.fShortPreamble = + pe_session_entry->beaconParams.fShortPreamble; + beacon_params.beaconInterval = + pe_session_entry->beaconParams.beaconInterval; + beacon_params.llaCoexist = + pe_session_entry->beaconParams.llaCoexist; + beacon_params.llbCoexist = + pe_session_entry->beaconParams.llbCoexist; + beacon_params.llgCoexist = + pe_session_entry->beaconParams.llgCoexist; + beacon_params.ht20MhzCoexist = + pe_session_entry->beaconParams.ht20Coexist; + beacon_params.llnNonGFCoexist = + pe_session_entry->beaconParams.llnNonGFCoexist; + beacon_params.fLsigTXOPProtectionFullSupport = + pe_session_entry->beaconParams.fLsigTXOPProtectionFullSupport; + beacon_params.fRIFSMode = + pe_session_entry->beaconParams.fRIFSMode; + beacon_params.smeSessionId = + pe_session_entry->smeSessionId; + schSetFixedBeaconFields(mac_ctx, pe_session_entry); + limSendBeaconParams(mac_ctx, &beacon_params, pe_session_entry); + } + pe_session_entry->old_protection_state = current_protection_state; + if (VOS_STATUS_SUCCESS != vos_timer_start( + &pe_session_entry->protection_fields_reset_timer, + SCH_PROTECTION_RESET_TIME)) { + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_ERROR, + FL("cannot create or start protectionFieldsResetTimer\n")); + } +} + +/*-------------------------------------------------------------------------- + + \brief peCreateSession() - creates a new PE session given the BSSID + + This function returns the session context and the session ID if the session + corresponding to the passed BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the new session + \param sessionId - session ID is returned here, if session is created. + \param bssType - station or a + \return tpPESession - pointer to the session context or NULL if session + can not be created. + + \sa + + --------------------------------------------------------------------------*/ +tpPESession peCreateSession(tpAniSirGlobal pMac, + tANI_U8 *bssid, + tANI_U8* sessionId, + tANI_U16 numSta, + tSirBssType bssType) +{ + VOS_STATUS status; + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + /* Find first free room in session table */ + if(pMac->lim.gpSession[i].valid == FALSE) + { + vos_mem_set((void*)&pMac->lim.gpSession[i], sizeof(tPESession), 0); + + //Allocate space for Station Table for this session. + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = vos_mem_malloc( + sizeof(tpDphHashNode)* (numSta + 1)); + if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pHashTable ) + { + limLog(pMac, LOGE, FL("memory allocate failed!")); + return NULL; + } + pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = vos_mem_malloc( + sizeof(tDphHashNode) * (numSta + 1)); + if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray ) + { + limLog(pMac, LOGE, FL("memory allocate failed!")); + vos_mem_free(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable); + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL; + return NULL; + } + + pMac->lim.gpSession[i].dph.dphHashTable.size = numSta + 1; + + dphHashTableClassInit(pMac, + &pMac->lim.gpSession[i].dph.dphHashTable); + + pMac->lim.gpSession[i].gpLimPeerIdxpool = vos_mem_malloc(sizeof( + *pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1)); + if ( NULL == pMac->lim.gpSession[i].gpLimPeerIdxpool ) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + vos_mem_free(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable); + vos_mem_free(pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray); + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL; + pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = NULL; + return NULL; + } + vos_mem_set(pMac->lim.gpSession[i].gpLimPeerIdxpool, + sizeof(*pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1), 0); + pMac->lim.gpSession[i].freePeerIdxHead = 0; + pMac->lim.gpSession[i].freePeerIdxTail = 0; + pMac->lim.gpSession[i].gLimNumOfCurrentSTAs = 0; + + /* Copy the BSSID to the session table */ + sirCopyMacAddr(pMac->lim.gpSession[i].bssId, bssid); + pMac->lim.gpSession[i].valid = TRUE; + + /* Intialize the SME and MLM states to IDLE */ + pMac->lim.gpSession[i].limMlmState = eLIM_MLM_IDLE_STATE; + pMac->lim.gpSession[i].limSmeState = eLIM_SME_IDLE_STATE; + pMac->lim.gpSession[i].limCurrentAuthType = eSIR_OPEN_SYSTEM; + peInitBeaconParams(pMac, &pMac->lim.gpSession[i]); +#ifdef WLAN_FEATURE_VOWIFI_11R + pMac->lim.gpSession[i].is11Rconnection = FALSE; +#endif + +#ifdef FEATURE_WLAN_ESE + pMac->lim.gpSession[i].isESEconnection = FALSE; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + pMac->lim.gpSession[i].isFastTransitionEnabled = FALSE; +#endif +#ifdef FEATURE_WLAN_LFR + pMac->lim.gpSession[i].isFastRoamIniFeatureEnabled = FALSE; +#endif + *sessionId = i; + + pMac->lim.gpSession[i].gLimPhyMode = WNI_CFG_PHY_MODE_11G; //TODO :Check with the team what should be default mode + /* Initialize CB mode variables when session is created */ + pMac->lim.gpSession[i].htSupportedChannelWidthSet = 0; + pMac->lim.gpSession[i].htRecommendedTxWidthSet = 0; + pMac->lim.gpSession[i].htSecondaryChannelOffset = 0; +#ifdef FEATURE_WLAN_TDLS + vos_mem_set(pMac->lim.gpSession[i].peerAIDBitmap, + sizeof(pMac->lim.gpSession[i].peerAIDBitmap), 0); + pMac->lim.gpSession[i].tdls_prohibited = false; + pMac->lim.gpSession[i].tdls_chan_swit_prohibited = false; +#endif + pMac->lim.gpSession[i].fWaitForProbeRsp = 0; + pMac->lim.gpSession[i].fIgnoreCapsChange = 0; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "Create a new PE session (%d) with BSSID: " + MAC_ADDRESS_STR " Max No. of STA %d", + pMac->lim.gpSession[i].peSessionId, + MAC_ADDR_ARRAY(bssid), numSta); + + /* Initialize PMM Ps Offload Module */ + if(pMac->psOffloadEnabled) + { + if(pmmPsOffloadOpen(pMac, &pMac->lim.gpSession[i]) + != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, + FL("Failed to open ps offload for pe session %x\n"),i); + } + } + + if (eSIR_INFRA_AP_MODE == bssType || + eSIR_IBSS_MODE == bssType || + eSIR_BTAMP_AP_MODE == bssType) + { + pMac->lim.gpSession[i].pSchProbeRspTemplate = + vos_mem_malloc(SCH_MAX_PROBE_RESP_SIZE); + pMac->lim.gpSession[i].pSchBeaconFrameBegin = + vos_mem_malloc(SCH_MAX_BEACON_SIZE); + pMac->lim.gpSession[i].pSchBeaconFrameEnd = + vos_mem_malloc(SCH_MAX_BEACON_SIZE); + if ( (NULL == pMac->lim.gpSession[i].pSchProbeRspTemplate) + || (NULL == pMac->lim.gpSession[i].pSchBeaconFrameBegin) + || (NULL == pMac->lim.gpSession[i].pSchBeaconFrameEnd) ) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + vos_mem_free(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable); + vos_mem_free(pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray); + vos_mem_free(pMac->lim.gpSession[i].gpLimPeerIdxpool); + vos_mem_free(pMac->lim.gpSession[i].pSchProbeRspTemplate); + vos_mem_free(pMac->lim.gpSession[i].pSchBeaconFrameBegin); + vos_mem_free(pMac->lim.gpSession[i].pSchBeaconFrameEnd); + + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL; + pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = NULL; + pMac->lim.gpSession[i].gpLimPeerIdxpool = NULL; + pMac->lim.gpSession[i].pSchProbeRspTemplate = NULL; + pMac->lim.gpSession[i].pSchBeaconFrameBegin = NULL; + pMac->lim.gpSession[i].pSchBeaconFrameEnd = NULL; + return NULL; + } + } + +#if defined WLAN_FEATURE_VOWIFI_11R + if (eSIR_INFRASTRUCTURE_MODE == bssType) { + limFTOpen(pMac, &pMac->lim.gpSession[i]); + } +#endif + + if (eSIR_INFRA_AP_MODE == bssType) { + pMac->lim.gpSession[i].old_protection_state = 0; + pMac->lim.gpSession[i].mac_ctx = (void *)pMac; + status = vos_timer_init( + &pMac->lim.gpSession[i].protection_fields_reset_timer, + VOS_TIMER_TYPE_SW, pe_reset_protection_callback, + (void *)&pMac->lim.gpSession[i]); + if (status == VOS_STATUS_SUCCESS) { + status = vos_timer_start( + &pMac->lim.gpSession[i].protection_fields_reset_timer, + SCH_PROTECTION_RESET_TIME); + } + if (status != VOS_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_PE, + VOS_TRACE_LEVEL_ERROR, + FL("cannot create or start " + "protectionFieldsResetTimer\n")); + } + } + + return(&pMac->lim.gpSession[i]); + } + } + limLog(pMac, LOGE, FL("Session can not be created.. Reached Max permitted sessions \n ")); + return NULL; +} + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given the BSSID. + + This function returns the session context and the session ID if the session + corresponding to the given BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_U8* sessionId) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + /* If BSSID matches return corresponding tables address*/ + if( (pMac->lim.gpSession[i].valid) && (sirCompareMacAddr(pMac->lim.gpSession[i].bssId, bssid))) + { + *sessionId = i; + return(&pMac->lim.gpSession[i]); + } + } + + limLog(pMac, LOG4, FL("Session lookup fails for BSSID: \n ")); + limPrintMacAddr(pMac, bssid, LOG4); + return(NULL); + +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx. + + This function returns the session context if the session + corresponding to the given bssIdx is found in the PE session table. + \param pMac - pointer to global adapter context + \param bssIdx - bss index of the session + \return tpPESession - pointer to the session context or NULL if session is not found. + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac, tANI_U8 bssIdx) +{ + tANI_U8 i; + for (i = 0; i < pMac->lim.maxBssId; i++) + { + /* If BSSID matches return corresponding tables address*/ + if ( (pMac->lim.gpSession[i].valid) && (pMac->lim.gpSession[i].bssIdx == bssIdx)) + { + return &pMac->lim.gpSession[i]; + } + } + limLog(pMac, LOG4, FL("Session lookup fails for bssIdx: %d"), bssIdx); + return NULL; +} + +/** + * pe_find_session_by_sme_session_id() - looks up the PE session for given sme + * session id + * @mac_ctx: pointer to global adapter context + * @sme_session_id: sme session id + * + * looks up the PE session for given sme session id + * + * Return: pe session entry for given sme session if found else NULL + */ +tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx, + tANI_U8 sme_session_id) +{ + uint8_t i; + for (i = 0; i < mac_ctx->lim.maxBssId; i++) { + if ( (mac_ctx->lim.gpSession[i].valid) && + (mac_ctx->lim.gpSession[i].smeSessionId == + sme_session_id) ) { + return &mac_ctx->lim.gpSession[i]; + } + } + limLog(mac_ctx, LOG4, + FL("Session lookup fails for smeSessionID: %d"), + sme_session_id); + return NULL; +} + +/*-------------------------------------------------------------------------- + \brief peFindSessionBySessionId() - looks up the PE session given the session ID. + + This function returns the session context if the session + corresponding to the given session ID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sessionId -session ID for which session context needs to be looked up. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + if(sessionId >= pMac->lim.maxBssId) + { + limLog(pMac, LOGE, FL("Invalid sessionId: %d \n "), sessionId); + return(NULL); + } + if((pMac->lim.gpSession[sessionId].valid == TRUE)) + { + return(&pMac->lim.gpSession[sessionId]); + } + limLog(pMac, LOG1, FL("Session %d not active\n "), sessionId); + return(NULL); + +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByStaId() - looks up the PE session given staid. + + This function returns the session context and the session ID if the session + corresponding to the given StaId is found in the PE session table. + + \param pMac - pointer to global adapter context + \param staid - StaId of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByStaId(tpAniSirGlobal pMac, tANI_U8 staid, tANI_U8* sessionId) +{ + tANI_U8 i, j; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + for(j = 0; j < pMac->lim.gpSession[i].dph.dphHashTable.size; j++) + { + if((pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].valid) && + (pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].added) && + (staid == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].staIndex)) + { + *sessionId = i; + return(&pMac->lim.gpSession[i]); + } + } + } + } + + limLog(pMac, LOG4, FL("Session lookup fails for StaId: %d\n "), staid); + return(NULL); +} + + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - deletes the PE session given the session ID. + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ +void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U16 i = 0; + tANI_U16 n; + TX_TIMER *timer_ptr; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "Trying to delete PE session %d Opmode %d BssIdx %d" + " BSSID: " MAC_ADDRESS_STR, psessionEntry->peSessionId, + psessionEntry->operMode, psessionEntry->bssIdx, + MAC_ADDR_ARRAY(psessionEntry->bssId)); + + for (n = 0; n < (pMac->lim.maxStation + 1); n++) + { + timer_ptr = &pMac->lim.limTimers.gpLimCnfWaitTimer[n]; + + if(psessionEntry->peSessionId == timer_ptr->sessionId) + { + if(VOS_TRUE == tx_timer_running(timer_ptr)) + { + tx_timer_deactivate(timer_ptr); + } + } + } + + if (LIM_IS_AP_ROLE(psessionEntry)) { + vos_timer_stop(&psessionEntry->protection_fields_reset_timer); + vos_timer_destroy(&psessionEntry->protection_fields_reset_timer); + } + +#if defined (WLAN_FEATURE_VOWIFI_11R) + /* Delete FT related information */ + limFTCleanup(pMac, psessionEntry); +#endif + + if (psessionEntry->pLimStartBssReq != NULL) + { + vos_mem_free( psessionEntry->pLimStartBssReq ); + psessionEntry->pLimStartBssReq = NULL; + } + + if (psessionEntry->pLimJoinReq != NULL) + { + vos_mem_free( psessionEntry->pLimJoinReq ); + psessionEntry->pLimJoinReq = NULL; + } + + if (psessionEntry->pLimReAssocReq != NULL) + { + vos_mem_free( psessionEntry->pLimReAssocReq ); + psessionEntry->pLimReAssocReq = NULL; + } + + if (psessionEntry->pLimMlmJoinReq != NULL) + { + vos_mem_free( psessionEntry->pLimMlmJoinReq ); + psessionEntry->pLimMlmJoinReq = NULL; + } + + if (psessionEntry->dph.dphHashTable.pHashTable != NULL) + { + vos_mem_free(psessionEntry->dph.dphHashTable.pHashTable); + psessionEntry->dph.dphHashTable.pHashTable = NULL; + } + + if (psessionEntry->dph.dphHashTable.pDphNodeArray != NULL) + { + vos_mem_free(psessionEntry->dph.dphHashTable.pDphNodeArray); + psessionEntry->dph.dphHashTable.pDphNodeArray = NULL; + } + + if (psessionEntry->gpLimPeerIdxpool != NULL) + { + vos_mem_free(psessionEntry->gpLimPeerIdxpool); + psessionEntry->gpLimPeerIdxpool = NULL; + } + + if (psessionEntry->beacon != NULL) + { + vos_mem_free( psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + + if (psessionEntry->assocReq != NULL) + { + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if (psessionEntry->assocRsp != NULL) + { + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } + + + if (psessionEntry->parsedAssocReq != NULL) + { + // Cleanup the individual allocation first + for (i=0; i < psessionEntry->dph.dphHashTable.size; i++) + { + if ( psessionEntry->parsedAssocReq[i] != NULL ) + { + if( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame ) + { + vos_mem_free(((tpSirAssocReq) + (psessionEntry->parsedAssocReq[i]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame = NULL; + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrameLength = 0; + } + vos_mem_free(psessionEntry->parsedAssocReq[i]); + psessionEntry->parsedAssocReq[i] = NULL; + } + } + // Cleanup the whole block + vos_mem_free(psessionEntry->parsedAssocReq); + psessionEntry->parsedAssocReq = NULL; + } + if (NULL != psessionEntry->limAssocResponseData) + { + vos_mem_free( psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (NULL != psessionEntry->pLimMlmReassocRetryReq) + { + vos_mem_free( psessionEntry->pLimMlmReassocRetryReq); + psessionEntry->pLimMlmReassocRetryReq = NULL; + } +#endif + + if (NULL != psessionEntry->pLimMlmReassocReq) + { + vos_mem_free( psessionEntry->pLimMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + limCleanupEseCtxt(pMac, psessionEntry); +#endif + + /* Initialize PMM Ps Offload Module */ + if(pMac->psOffloadEnabled) + { + if(pmmPsOffloadClose(pMac, psessionEntry) + != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGW, + FL("Failed to close ps offload for pe session %x"), + psessionEntry->peSessionId); + } + } + + if (NULL != psessionEntry->pSchProbeRspTemplate) + { + vos_mem_free(psessionEntry->pSchProbeRspTemplate); + psessionEntry->pSchProbeRspTemplate = NULL; + } + + if (NULL != psessionEntry->pSchBeaconFrameBegin) + { + vos_mem_free(psessionEntry->pSchBeaconFrameBegin); + psessionEntry->pSchBeaconFrameBegin = NULL; + } + + if (NULL != psessionEntry->pSchBeaconFrameEnd) + { + vos_mem_free(psessionEntry->pSchBeaconFrameEnd); + psessionEntry->pSchBeaconFrameEnd = NULL; + } + + /* Must free the buffer before peSession invalid */ + if (NULL != psessionEntry->addIeParams.probeRespData_buff) + { + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespData_buff = NULL; + psessionEntry->addIeParams.probeRespDataLen = 0; + } + if (NULL != psessionEntry->addIeParams.assocRespData_buff) + { + vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); + psessionEntry->addIeParams.assocRespData_buff = NULL; + psessionEntry->addIeParams.assocRespDataLen = 0; + } + if (NULL != psessionEntry->addIeParams.probeRespBCNData_buff) + { + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + } + +#ifdef WLAN_FEATURE_11W + /* if PMF connection */ + if (psessionEntry->limRmfEnabled) { + vos_timer_destroy(&psessionEntry->pmfComebackTimer); + } +#endif + + psessionEntry->valid = FALSE; + return; +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByPeerSta() - looks up the PE session given the Station Address. + + This function returns the session context and the session ID if the session + corresponding to the given station address is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sa - Peer STA Address of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac, tANI_U8* sa, tANI_U8* sessionId) +{ + tANI_U8 i; + tpDphHashNode pSta; + tANI_U16 aid; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid)) + { + pSta = dphLookupHashEntry(pMac, sa, &aid, &pMac->lim.gpSession[i].dph.dphHashTable); + if (pSta != NULL) + { + *sessionId = i; + return &pMac->lim.gpSession[i]; + } + } + } + + limLog(pMac, LOG1, FL("Session lookup fails for Peer StaId: \n ")); + limPrintMacAddr(pMac, sa, LOG1); + return NULL; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.c new file mode 100644 index 0000000000000..d3b6ddc66ac2c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limSessionUtils.c + \brief implementation for lim Session Utility APIs + \author Sunit Bhatia +========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "limDebug.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "limSessionUtils.h" +#include "limUtils.h" + +/*-------------------------------------------------------------------------- + \brief peGetVhtCapable() - Returns the Vht capable from a valid session. + + This function itrates the session Table and returns the VHT capable from first valid session + if no sessions are valid/present it returns FALSE + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +tANI_U8 peGetVhtCapable(tpAniSirGlobal pMac) + +{ +#ifdef WLAN_FEATURE_11AC + tANI_U8 i; + //assumption here is that all the sessions will be on the same channel. + //This function will not work, once we have multiple channel support. + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + return(pMac->lim.gpSession[i].vhtCapability); + } + } +#endif + return FALSE; +} +/*-------------------------------------------------------------------------- + \brief peGetCurrentChannel() - Returns the channel number for scanning, + from a valid session. + This function itrates the session Table and returns the channel number + from first valid session if no sessions are valid/present it returns zero + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + \sa + --------------------------------------------------------------------------*/ +tANI_U8 peGetCurrentChannel(tpAniSirGlobal pMac) +{ + tANI_U8 i; + //assumption here is that all the sessions will be on the same channel. + //This function will not work, once we have multiple channel support. + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + return(pMac->lim.gpSession[i].currentOperChannel); + } + } + return(HAL_INVALID_CHANNEL_ID); +} + + +/*-------------------------------------------------------------------------- + + \brief peValidateJoinReq() - validates the Join request . + + This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present + this function returns TRUE else returns FALSE. + PE will force SME to first issue ''START_BSS' request for BTAMP_STA, before sending a JOIN request. + + \param pMac - pointer to global adapter context + \return - return TRUE if start BSS session is present else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac) +{ + + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].bssType == eSIR_BTAMP_STA_MODE) && + (pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF)) + { + return(TRUE); + } + + } + return(FALSE); + +} + +/*-------------------------------------------------------------------------- + \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave . + + This function is called to check the valid session for power save, if more than one session is active , this function + it returns NULL. + if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry. + For all other cases it returns NULL. + + \param pMac - pointer to global adapter context + \return - return session is address if valid session is present else return NULL. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 sessioncount = 0; + tANI_U8 sessionId = 0; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid == TRUE)&& + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) { + sessioncount++; + sessionId = i; + + if(sessioncount > 1) + { + return(NULL); + } + } + + } + + if( (pMac->lim.gpSession[sessionId].valid == TRUE)&& + (pMac->lim.gpSession[sessionId].limSystemRole == eLIM_STA_ROLE)&& + (pMac->lim.gpSession[sessionId].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) + + { + return(&pMac->lim.gpSession[sessionId]); + } + return(NULL); + +} +/*-------------------------------------------------------------------------- + \brief peIsAnySessionActive() - checks for the active session presence . + + This function returns TRUE if atleast one valid session is present else it returns FALSE + + \param pMac - pointer to global adapter context + \return - return TRUE if atleast one session is active else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + + +tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + return(TRUE); + } + + } + return(FALSE); + +} + +/*-------------------------------------------------------------------------- + \brief pePrintActiveSession() - print all the active pesession present . + + This function print all the active pesession present + + \param pMac - pointer to global adapter context + + \sa + --------------------------------------------------------------------------*/ + + +void pePrintActiveSession(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + limLog(pMac, LOGE, FL("Active sessionId: %d BSID: "MAC_ADDRESS_STR + "opmode = %d bssIdx = %d"), i, + MAC_ADDR_ARRAY(pMac->lim.gpSession[i].bssId), + pMac->lim.gpSession[i].operMode, + pMac->lim.gpSession[i].bssIdx); + } + } + return; +} + +/*-------------------------------------------------------------------------- + \brief isLimSessionOffChannel() - Determines if the there is any other off channel + session. + + This function returns TRUE if the session Id passed needs to be on a different + channel than atleast one session already active. + + \param pMac - pointer to global adapter context + \param sessionId - session ID of the session to be verified. + + \return tANI_U8 - Boolean value for off-channel operation. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 +isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 i; + + if(sessionId >= pMac->lim.maxBssId) + { + limLog(pMac, LOGE, FL("Invalid sessionId: %d \n "), sessionId); + return FALSE; + } + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( i == sessionId ) + { + //Skip the sessionId that is to be joined. + continue; + } + //if another ession is valid and it is on different channel + //it is an off channel operation. + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].currentOperChannel != + pMac->lim.gpSession[sessionId].currentOperChannel) ) + { + return TRUE; + } + } + + return FALSE; + +} + +/*-------------------------------------------------------------------------- + \brief peGetActiveSessionChannel() - Gets the operating channel of first + valid session. Returns 0 if there is no + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - operating channel. + + \sa + --------------------------------------------------------------------------*/ +void +peGetActiveSessionChannel (tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState) +{ + tANI_U8 i; + ePhyChanBondState prevPhyCbState = PHY_SINGLE_CHANNEL_CENTERED; + + // Initialize the pointers passed to INVALID values in case we don't find a valid session + *resumeChannel = 0; + *resumePhyCbState = 0; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + *resumeChannel = pMac->lim.gpSession[i].currentOperChannel; + *resumePhyCbState = pMac->lim.gpSession[i].htSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_11AC + if ((pMac->lim.gpSession[i].vhtCapability)) + { + /*Get 11ac cbState from 11n cbState*/ + *resumePhyCbState = limGet11ACPhyCBState(pMac, + pMac->lim.gpSession[i].currentOperChannel, + pMac->lim.gpSession[i].htSecondaryChannelOffset, + pMac->lim.gpSession[i].apCenterChan, + &pMac->lim.gpSession[i]); + } +#endif + *resumePhyCbState = (*resumePhyCbState > prevPhyCbState )? *resumePhyCbState : prevPhyCbState; + prevPhyCbState = *resumePhyCbState; + } + } + return; +} + +/*-------------------------------------------------------------------------- + \brief limIsChanSwitchRunning() - Check if channel switch is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann switching running. + 0 - if chann switching is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsChanSwitchRunning (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + return 1; + } + } + return 0; +} +/*-------------------------------------------------------------------------- + \brief limIsInQuietDuration() - Check if channel quieting is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInQuietDuration (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + return 1; + } + } + return 0; +} +/*-------------------------------------------------------------------------- + \brief limIsQuietBegin() - Check if channel quieting is begining on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsQuietBegin (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + return 1; + } + } + return 0; +} + +/*-------------------------------------------------------------------------- + \brief limIsInMCC() - Check if Device is in MCC. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - TRUE - if in MCC. + FALSE - NOT in MCC. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInMCC (tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 chan = 0; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + //if another session is valid and it is on different channel + //it is an off channel operation. + if( (pMac->lim.gpSession[i].valid) ) + { + if( chan == 0 ) + { + chan = pMac->lim.gpSession[i].currentOperChannel; + } + else if( chan != pMac->lim.gpSession[i].currentOperChannel) + { + return TRUE; + } + } + } + return FALSE; +} + +/*-------------------------------------------------------------------------- + \brief peGetCurrentSTAsCount() - Returns total stations associated on + all session. + + \param pMac - pointer to global adapter context + \return - Number of station active on all sessions. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peGetCurrentSTAsCount(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 staCount = 0; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + staCount += pMac->lim.gpSession[i].gLimNumOfCurrentSTAs; + } + } + return staCount; +} + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief limIsFastRoamEnabled() - Check LFR is enabled or not + + This function returns the TRUE if LFR is enabled + + \param pMac - pointer to global adapter context + \param sessionId - session ID is returned here, if session is found. + + \return int - TRUE if enabled or else FALSE + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 limIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + if(TRUE == pMac->lim.gpSession[sessionId].valid) + { + if((eSIR_INFRASTRUCTURE_MODE == pMac->lim.gpSession[sessionId].bssType) && + (pMac->lim.gpSession[sessionId].isFastRoamIniFeatureEnabled)) + { + return TRUE; + } + } + + return FALSE; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.h new file mode 100644 index 0000000000000..28561190c8e1e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSessionUtils.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if!defined( __LIM_SESSION_UTILS_H ) +#define __LIM_SESSION_UTILS_H + +/**========================================================================= + + \file limSessionUtils.h + + \brief prototype for lim Session Utility related APIs + + \author Sunit Bhatia + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + + \brief peGetVhtCapable() - Returns the Vht capable from a valid session. + + This function iterates the session Table and returns the VHT capable from first valid session + if no sessions are valid/present it returns FALSE + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +tANI_U8 peGetVhtCapable(tpAniSirGlobal pMac); + + +/*-------------------------------------------------------------------------- + \brief peValidateJoinReq() - validates the Join request . + + This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present + this function returns TRUE else returns FALSE. + + \param pMac - pointer to global adapter context + \return - return TRUE if start BSS session is present else return FALSE. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave . + + This function is called to check the valid session for power save, if more than one session is active , this function + it returns NULL. + if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry. + For all other cases it returns NULL. + + \param pMac - pointer to global adapter context + \return - return session is address if valid session is present else return NULL. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief peIsAnySessionActive() - checks for the active session presence . + + This function returns TRUE if atleast one valid session is present else it returns FALSE + + \param pMac - pointer to global adapter context + \return - return TRUE if atleast one session is active else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief pePrintActiveSession() - print all the active pesession present . + + This function print all the active pesession present + + \param pMac - pointer to global adapter context + + \sa + --------------------------------------------------------------------------*/ + +void pePrintActiveSession(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + \brief isLimSessionOffChannel() - Determines if the session is + off channel. + + This function returns TRUE if the session Id passed needs to be on a different + channel than atleast one session already active. + + \param pMac - pointer to global adapter context + \param sessionId - session ID of the session to be verified. + + \return tANI_U8 - Boolean value for off-channel operation. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId); +/* --------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief peGetActiveSessionChannel() - Gets the first valid sessions primary and secondary + channel. If not found returns invalid channel ID (=0) + \param pMac - pointer to global adapter context + \param resumeChannel - Primary channel of the first valid session. This is an output argument. + \return resumePhyCbState - Secondary channel of the first valid session. This is an output argument. +--------------------------------------------------------------------------*/ +void +peGetActiveSessionChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState); + +/*-------------------------------------------------------------------------- + \brief limIsChanSwitchRunning() - Check if channel switch is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann switching running. + 0 - if chann switching is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsChanSwitchRunning (tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief limIsInQuietDuration() - Check if channel quieting is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInQuietDuration (tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief limIsQuietBegin() - Check if channel quieting is begining on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsQuietBegin (tpAniSirGlobal pMac); +/*-------------------------------------------------------------------------- + \brief limIsInMCC() - Check if Device is in MCC. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - TRUE - if in MCC. + FALSE - NOT in MCC. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInMCC (tpAniSirGlobal pMac); +/*-------------------------------------------------------------------------- + \brief peGetCurrentSTAsCount() - Returns total stations associated on + all session. + + \param pMac - pointer to global adapter context + \return - Number of station active on all sessions. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +peGetCurrentSTAsCount(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief limIsFastRoamEnabled() - To check Fast roaming is enabled or not + + \param pMac - pointer to global adapter context + \param sessionId - session id + \return - TRUE or FALSE + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U8 sessionId); +#endif + + +#endif //#if !defined( __LIM_SESSION_UTILS_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c new file mode 100644 index 0000000000000..6385aa1b2a3e2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.c @@ -0,0 +1,1106 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSmeReqUtils.cc contains the utility functions + * for processing SME request messages. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ + +#include "wniApi.h" +#include "wniCfgSta.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" + + + +/** + * limIsRSNieValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the RSN IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * RSN IE validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pRSNie Pointer to received RSN IE + * @return true when RSN IE is valid, false otherwise + */ + +static tANI_U8 +limIsRSNieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirRSNie pRSNie) +{ + tANI_U8 startPos = 0; + tANI_U32 privacy, val; + int len; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacy) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve RSN_ENABLED from CFG")); + } + + if (pRSNie->length && (!privacy || !val)) + { + // Privacy & RSN not enabled in CFG. + /** + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d"), + pRSNie->length, privacy, val);) + } + + if (pRSNie->length) + { + if ((pRSNie->rsnIEdata[0] != DOT11F_EID_RSN) && + (pRSNie->rsnIEdata[0] != DOT11F_EID_WPA) +#ifdef FEATURE_WLAN_WAPI + && (pRSNie->rsnIEdata[0] != DOT11F_EID_WAPI) +#endif + ) + { + limLog(pMac, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]"), + pRSNie->rsnIEdata[0], DOT11F_EID_RSN, + DOT11F_EID_WPA); + return false; + } + + len = pRSNie->length; + startPos = 0; + while(len > 0) + { + // Check validity of RSN IE + if (pRSNie->rsnIEdata[startPos] == DOT11F_EID_RSN) + { + if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_RSN_MAX_LEN) || + (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_RSN_MIN_LEN)) + { + limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_RSN_MIN_LEN, + DOT11F_IE_RSN_MAX_LEN); + return false; + } + } + else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WPA) + { + // Check validity of WPA IE + if (SIR_MAC_MAX_IE_LENGTH > startPos) + { + if (startPos <= (SIR_MAC_MAX_IE_LENGTH - sizeof(tANI_U32))) + val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[startPos + 2]); + if((pRSNie->rsnIEdata[startPos + 1] < DOT11F_IE_WPA_MIN_LEN) || + (pRSNie->rsnIEdata[startPos + 1] > DOT11F_IE_WPA_MAX_LEN) || + (SIR_MAC_WPA_OUI != val)) + { + limLog(pMac, LOGE, + FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WPA_MIN_LEN, + DOT11F_IE_WPA_MAX_LEN, val, SIR_MAC_WPA_OUI); + + return false; + } + } + } +#ifdef FEATURE_WLAN_WAPI + else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WAPI) + { + if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_WAPI_MAX_LEN) || + (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_WAPI_MIN_LEN)) + { + limLog(pMac, LOGE, + FL("WAPI IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WAPI_MIN_LEN, + DOT11F_IE_WAPI_MAX_LEN); + + return false; + } + } +#endif + else + { + //we will never be here, simply for completeness + return false; + } + startPos += 2 + pRSNie->rsnIEdata[startPos+1]; //EID + length field + length + len -= startPos; + }//while + + } + + return true; +} /*** end limIsRSNieValidInSmeReqMessage() ***/ + +/** + * limIsAddieValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the Add IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * Add IE validity checks are performed on only length + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pWSCie Pointer to received WSC IE + * @return true when WSC IE is valid, false otherwise + */ + +static tANI_U8 +limIsAddieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirAddie pAddie) +{ + int left = pAddie->length; + tANI_U8 *ptr = pAddie->addIEdata; + tANI_U8 elem_id, elem_len; + + if (left == 0) + return true; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid Add IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + return false; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + // there shouldn't be any left byte + + + return true; +} /*** end limIsAddieValidInSmeReqMessage() ***/ + +/** + * limSetRSNieWPAiefromSmeStartBSSReqMessage() + * + *FUNCTION: + * This function is called to verify if the RSN IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * RSN IE validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pRSNie Pointer to received RSN IE + * @return true when RSN IE is valid, false otherwise + */ + +tANI_U8 +limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac, + tpSirRSNie pRSNie, + tpPESession pSessionEntry) +{ + tANI_U8 wpaIndex = 0; + tANI_U32 privacy, val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacy) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve RSN_ENABLED from CFG")); + } + + if (pRSNie->length && (!privacy || !val)) + { + // Privacy & RSN not enabled in CFG. + /** + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d"), + pRSNie->length, privacy, val);) + } + + if (pRSNie->length) + { + if ((pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) && + (pRSNie->rsnIEdata[0] != SIR_MAC_WPA_EID)) + { + limLog(pMac, LOGE, FL("RSN/WPA EID %d not [%d || %d]"), + pRSNie->rsnIEdata[0], SIR_MAC_RSN_EID, + SIR_MAC_WPA_EID); + return false; + } + + // Check validity of RSN IE + if ((pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID) && + (pRSNie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH)) + { + limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH, + SIR_MAC_RSN_IE_MAX_LENGTH); + return false; + } + + if (pRSNie->length > pRSNie->rsnIEdata[1] + 2) + { + if (pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) + { + limLog(pMac, + LOGE, + FL("First byte[%d] in rsnIEdata is not RSN_EID"), + pRSNie->rsnIEdata[1]); + return false; + } + + limLog(pMac, + LOG1, + FL("WPA IE is present along with WPA2 IE")); + wpaIndex = 2 + pRSNie->rsnIEdata[1]; + } + else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) && + (pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID)) + { + limLog(pMac, + LOG1, + FL("Only RSN IE is present")); + dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], + (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + } + else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) && + (pRSNie->rsnIEdata[0] == SIR_MAC_WPA_EID)) + { + limLog(pMac, + LOG1, + FL("Only WPA IE is present")); + + dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6],(tANI_U8)pRSNie->length-4, + &pSessionEntry->gStartBssWPAIe); + } + + // Check validity of WPA IE + if(wpaIndex +6 < SIR_MAC_MAX_IE_LENGTH ) + { + val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[wpaIndex + 2]); + + if ((pRSNie->rsnIEdata[wpaIndex] == SIR_MAC_WPA_EID) && + ((pRSNie->rsnIEdata[wpaIndex + 1] < SIR_MAC_WPA_IE_MIN_LENGTH) || + (SIR_MAC_WPA_OUI != val))) + { + limLog(pMac, LOGE, + FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"), + pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH, + SIR_MAC_RSN_IE_MAX_LENGTH, val, SIR_MAC_WPA_OUI); + + return false; + } + else + { + /* Both RSN and WPA IEs are present */ + dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], + (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + + dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[wpaIndex + 6], + pRSNie->rsnIEdata[wpaIndex + 1]-4, + &pSessionEntry->gStartBssWPAIe); + + } + } + else + { + return false; + } + } + + return true; +} /*** end limSetRSNieWPAiefromSmeStartBSSReqMessage() ***/ + + + + +/** + * limIsBssDescrValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the BSS Descr + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * BSS Descritipion validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pBssDescr Pointer to received Bss Descritipion + * @return true when BSS description is valid, false otherwise + */ + +static tANI_U8 +limIsBssDescrValidInSmeReqMessage(tpAniSirGlobal pMac, + tpSirBssDescription pBssDescr) +{ + tANI_U8 valid = true; + + if (limIsAddrBC(pBssDescr->bssId) || + !pBssDescr->channelId) + { + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsBssDescrValidInSmeReqMessage() ***/ + + + +/** + * limIsSmeStartReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_START_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_START_BSS_REQ message + * @return true when received SME_START_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStartReqValid(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tANI_U8 valid = true; + + if (((tpSirSmeStartReq) pMsg)->length != sizeof(tSirSmeStartReq)) + { + /** + * Invalid length in START_REQ message + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid length %d in eWNI_SME_START_REQ"), + ((tpSirSmeStartReq) pMsg)->length); + + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsSmeStartReqValid() ***/ + + + +/** + * limIsSmeStartBssReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_START_BSS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pStartBssReq Pointer to received SME_START_BSS_REQ message + * @return true when received SME_START_BSS_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStartBssReqValid(tpAniSirGlobal pMac, + tpSirSmeStartBssReq pStartBssReq) +{ + tANI_U8 i = 0; + tANI_U8 valid = true; + + PELOG1(limLog(pMac, LOG1, + FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d, SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d"), + pStartBssReq->bssType, + pStartBssReq->channelId, + pStartBssReq->ssId.length, + pStartBssReq->rsnIE.length, + pStartBssReq->nwType, + pStartBssReq->operationalRateSet.numRates);) + + switch (pStartBssReq->bssType) + { + case eSIR_INFRASTRUCTURE_MODE: + /** + * Should not have received start BSS req with bssType + * Infrastructure on STA. + * Log error. + */ + limLog(pMac, LOGE, + FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"), + pStartBssReq->bssType); + valid = false; + goto end; + break; + + case eSIR_IBSS_MODE: + break; + + /* Added for BT AMP support */ + case eSIR_BTAMP_STA_MODE: + break; + + /* Added for BT AMP support */ + case eSIR_BTAMP_AP_MODE: + break; + + /* Added for SoftAP support */ + case eSIR_INFRA_AP_MODE: + break; + + default: + /** + * Should not have received start BSS req with bssType + * other than Infrastructure/IBSS. + * Log error + */ + limLog(pMac, LOGW, + FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"), + pStartBssReq->bssType); + + valid = false; + goto end; + } + + /* This below code is client specific code. TODO */ + if (pStartBssReq->bssType == eSIR_IBSS_MODE) + { + if (!pStartBssReq->ssId.length || + (pStartBssReq->ssId.length > SIR_MAC_MAX_SSID_LENGTH)) + { + // Invalid length for SSID. + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid SSID length in eWNI_SME_START_BSS_REQ")); + + valid = false; + goto end; + } + } + + + if (!limIsRSNieValidInSmeReqMessage(pMac, &pStartBssReq->rsnIE)) + { + valid = false; + goto end; + } + + if (pStartBssReq->nwType != eSIR_11A_NW_TYPE && + pStartBssReq->nwType != eSIR_11B_NW_TYPE && + pStartBssReq->nwType != eSIR_11G_NW_TYPE) + { + valid = false; + goto end; + } + + if (pStartBssReq->nwType == eSIR_11A_NW_TYPE) + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsArate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + // check if all the rates in the operatioal rate set are legal 11G rates + else if (pStartBssReq->nwType == eSIR_11G_NW_TYPE) + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsGrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + else + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsBrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + +end: + return valid; +} /*** end limIsSmeStartBssReqValid() ***/ + + + +/** + * limIsSmeJoinReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_JOIN_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pJoinReq Pointer to received SME_JOIN_REQ message + * @return true when received SME_JOIN_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeJoinReqValid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq) +{ + tANI_U8 valid = true; + + + if (!limIsRSNieValidInSmeReqMessage(pMac, &pJoinReq->rsnIE)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid RSNIE")); + valid = false; + goto end; + } + + if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEScan)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid additional IE for scan")); + valid = false; + goto end; + } + + if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEAssoc)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid additional IE for assoc")); + valid = false; + goto end; + } + + + if (!limIsBssDescrValidInSmeReqMessage(pMac, + &pJoinReq->bssDescription)) + { + /// Received eWNI_SME_JOIN_REQ with invalid BSS Info + // Log the event + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid bssInfo")); + + valid = false; + goto end; + } + + /* + Reject Join Req if the Self Mac Address and + the Ap's Mac Address is same + */ + if ( vos_mem_compare( (tANI_U8* ) pJoinReq->selfMacAddr, + (tANI_U8 *) pJoinReq->bssDescription.bssId, + (tANI_U8) (sizeof(tSirMacAddr)))) + { + // Log the event + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with Self Mac and BSSID Same")); + + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsSmeJoinReqValid() ***/ + + + +/** + * limIsSmeDisassocReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DISASSOC_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message + * @return true When received SME_DISASSOC_REQ is formatted + * correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDisassocReqValid(tpAniSirGlobal pMac, + tpSirSmeDisassocReq pDisassocReq, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDisassocReq->peerMacAddr) && + !limIsAddrBC(pDisassocReq->peerMacAddr)) + return false; + + + return true; +} /*** end limIsSmeDisassocReqValid() ***/ + + + +/** + * limIsSmeDisassocCnfValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DISASSOC_CNF message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message + * @return true When received SME_DISASSOC_CNF is formatted + * correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDisassocCnfValid(tpAniSirGlobal pMac, + tpSirSmeDisassocCnf pDisassocCnf, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDisassocCnf->peerMacAddr)) + return false; + + return true; +} /*** end limIsSmeDisassocCnfValid() ***/ + + + +/** + * limIsSmeDeauthReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DEAUTH_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message + * @return true When received SME_DEAUTH_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDeauthReqValid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDeauthReq->peerMacAddr) && + !limIsAddrBC(pDeauthReq->peerMacAddr)) + return false; + + return true; +} /*** end limIsSmeDeauthReqValid() ***/ + + + +/** + * limIsSmeScanReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_SCAN_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pScanReq Pointer to received SME_SCAN_REQ message + * @return true when received SME_SCAN_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq) +{ + tANI_U8 valid = true; + tANI_U8 i = 0; + + if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) + { + valid = false; + limLog(pMac, LOGE, FL("Number of SSIDs > SIR_SCAN_MAX_NUM_SSID")); + goto end; + } + + for (i = 0; i < pScanReq->numSsid; i++) + { + if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH) + { + limLog(pMac, LOGE, + FL("Requested SSID length > SIR_MAC_MAX_SSID_LENGTH")); + valid = false; + goto end; + } + } + if ((pScanReq->bssType < 0) || (pScanReq->bssType > eSIR_AUTO_MODE)) + { + limLog(pMac, LOGE, FL("Invalid BSS Type")); + valid = false; + } + if (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) + { + valid = false; + limLog(pMac, LOGE, FL("BSSID is group addr and is not Broadcast Addr")); + } + if (!(pScanReq->scanType == eSIR_PASSIVE_SCAN || pScanReq->scanType == eSIR_ACTIVE_SCAN)) + { + valid = false; + limLog(pMac, LOGE, FL("Invalid Scan Type")); + } + if (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS) + { + valid = false; + limLog(pMac, LOGE, FL("Number of Channels > SIR_MAX_NUM_CHANNELS")); + } + + /* + ** check min/max channelTime range + **/ + if (valid) + { + if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) && + (pScanReq->maxChannelTime < pScanReq->minChannelTime)) + { + limLog(pMac, LOGE, FL("Max Channel Time < Min Channel Time")); + valid = false; + goto end; + } + } + +end: + return valid; +} /*** end limIsSmeScanReqValid() ***/ + + +/** + * limIsSmeSetContextReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_SET_CONTEXT_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message + * @return true when received SME_SET_CONTEXT_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeSetContextReqValid(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq) +{ + tANI_U8 i = 0; + tANI_U8 valid = true; + tpSirKeys pKey = pSetContextReq->keyMaterial.key; + + if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) && + (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) && + (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) && +#ifdef FEATURE_WLAN_WAPI + (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) && +#endif + !pSetContextReq->keyMaterial.numKeys) + { + /** + * No keys present in case of TKIP or CCMP + * Log error. + */ + limLog(pMac, LOGW, + FL("No keys present in SME_SETCONTEXT_REQ for edType=%d"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + + if (pSetContextReq->keyMaterial.numKeys && + (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE)) + { + /** + * Keys present in case of no ED policy + * Log error. + */ + limLog(pMac, LOGW, + FL("Keys present in SME_SETCONTEXT_REQ for edType=%d"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + + if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED) + { + /** + * Invalid edType in the message + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid edType=%d in SME_SETCONTEXT_REQ"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE) + { + tANI_U32 poi; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &poi) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (!poi) + { + /** + * Privacy is not enabled + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, + FL("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ"), + pSetContextReq->keyMaterial.edType);) + } + } + + for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++) + { + if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) && + (pKey->keyLength != 5)) || + ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) && + (pKey->keyLength != 13)) || + ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) && + (pKey->keyLength != 32)) || +#ifdef FEATURE_WLAN_WAPI + ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) && + (pKey->keyLength != 32)) || +#endif + ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) && + (pKey->keyLength != 16))) + { + /** + * Invalid key length for a given ED type + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ"), + pKey->keyLength, pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + pKey++; + } + +end: + return valid; +} /*** end limIsSmeSetContextReqValid() ***/ + + + +/** + * limIsSmeStopBssReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_STOP_BSS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_STOP_BSS_REQ message + * @return true when received SME_STOP_BSS_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStopBssReqValid(tANI_U32 *pMsg) +{ + tANI_U8 valid = true; + + return valid; +} /*** end limIsSmeStopBssReqValid() ***/ + + +/** + * limGetBssIdFromSmeJoinReqMsg() + * + *FUNCTION: + * This function is called in various places to get BSSID + * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/ + * SME_REASSOC_REQ message. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ + * message + * @return pBssId - Pointer to BSSID + */ + +tANI_U8* +limGetBssIdFromSmeJoinReqMsg(tANI_U8 *pBuf) +{ + if (!pBuf) + return NULL; + + pBuf += sizeof(tANI_U32); // skip message header + + + pBuf += limGetU16(pBuf) + sizeof(tANI_U16); // skip RSN IE + + pBuf += sizeof(tANI_U16); // skip length of BSS description + + return (pBuf); +} /*** end limGetBssIdFromSmeJoinReqMsg() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.h new file mode 100644 index 0000000000000..6dbf0fe642624 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSmeReqUtils.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSmeReqUtils.h contains the utility definitions + * LIM uses while processing SME request messsages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SME_REQ_UTILS_H +#define __LIM_SME_REQ_UTILS_H + +#include "sirApi.h" +#include "limTypes.h" + + +// LIM SME request messages related utility functions +tANI_U8 limIsSmeStartReqValid(tpAniSirGlobal, tANI_U32 *); +tANI_U8 limIsSmeStartBssReqValid(tpAniSirGlobal, tpSirSmeStartBssReq); +tANI_U8 limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal, + tpSirRSNie, + tpPESession); +tANI_U8 limIsSmeScanReqValid(tpAniSirGlobal, tpSirSmeScanReq); +tANI_U8 limIsSmeJoinReqValid(tpAniSirGlobal, tpSirSmeJoinReq); +tANI_U8 limIsSmeDisassocReqValid(tpAniSirGlobal, tpSirSmeDisassocReq, tpPESession); +tANI_U8 limIsSmeDeauthReqValid(tpAniSirGlobal, tpSirSmeDeauthReq, tpPESession); +tANI_U8 limIsSmeSetContextReqValid(tpAniSirGlobal, tpSirSmeSetContextReq); +tANI_U8 limIsSmeStopBssReqValid(tANI_U32 *); +tANI_U8* limGetBssIdFromSmeJoinReqMsg(tANI_U8 *); +tANI_U8 limIsSmeDisassocCnfValid(tpAniSirGlobal, tpSirSmeDisassocCnf, tpPESession); + +#endif /* __LIM_SME_REQ_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.c new file mode 100644 index 0000000000000..7c9476973dfc9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * limStaHashApi.c: Provides access functions to get/set values of station hash entry fields. + * Author: Sunit Bhatia + * Date: 09/19/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ + +#include "limStaHashApi.h" + + +/** + * limGetStaHashBssidx() + * + *FUNCTION: + * This function is called to Get the Bss Index of the currently associated Station. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param assocId AssocID of the Station. + * @param bssidx pointer to the bss index, which will be returned by the function. + * + * @return success if GET operation is ok, else Failure. + */ + +tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx, tpPESession psessionEntry) +{ + tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA %d"), assocId);) + return eSIR_LIM_INVALID_STA; + } + + *bssidx = (tANI_U8)pSta->bssId; + return eSIR_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.h new file mode 100644 index 0000000000000..06704a21bb910 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limStaHashApi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limStaHashApi.h contains the + * function prototypes for accessing station hash entry fields. + * + * Author: Sunit Bhatia + * Date: 09/19/2006 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_STA_HASH_API_H__ +#define __LIM_STA_HASH_API_H__ + + +#include "aniGlobal.h" +#include "limTypes.h" + +tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx,tpPESession psessionEntry); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.c new file mode 100644 index 0000000000000..2ca8e66750bf9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.c @@ -0,0 +1,2219 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limTimerUtils.cc contains the utility functions + * LIM uses for handling various timers. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "pmmApi.h" + + +// default value 5000 ms for background scan period when it is disabled +#define LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS 5000 +// channel Switch Timer in ticks +#define LIM_CHANNEL_SWITCH_TIMER_TICKS 1 +// Lim Quite timer in ticks +#define LIM_QUIET_TIMER_TICKS 100 +// Lim Quite BSS timer interval in ticks +#define LIM_QUIET_BSS_TIMER_TICK 100 +// Lim KeepAlive timer default (3000)ms +#define LIM_KEEPALIVE_TIMER_MS 3000 +// Lim JoinProbeRequest Retry timer default (200)ms +#define LIM_JOIN_PROBE_REQ_TIMER_MS 200 + +//default beacon interval value used in HB timer interval calculation +#define LIM_HB_TIMER_BEACON_INTERVAL 100 + +/* This timer is a periodic timer which expires at every 1 sec to + convert ACTIVE DFS channel to DFS channels */ +#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000 + +/** + * limCreateTimers() + * + *FUNCTION: + * This function is called upon receiving + * 1. SME_START_REQ for STA in ESS role + * 2. SME_START_BSS_REQ for AP role & STA in IBSS role + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ + +v_UINT_t +limCreateTimers(tpAniSirGlobal pMac) +{ + tANI_U32 cfgValue, i=0; + tANI_U32 cfgValue1; + + PELOG1(limLog(pMac, LOG1, FL("Creating Timers used by LIM module in Role %d"), pMac->lim.gLimSystemRole);) + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get MinChannelTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve MinChannelTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create MIN/MAX channel timers and activate them later + if (tx_timer_create(&pMac->lim.limTimers.gLimMinChannelTimer, + "MIN CHANNEL TIMEOUT", + limTimerHandler, SIR_LIM_MIN_CHANNEL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start min channel timer. + // Log error + limLog(pMac, LOGP, FL("could not create MIN channel timer")); + return TX_TIMER_ERROR; + } + PELOG2(limLog(pMac, LOG2, FL("Created MinChannelTimer"));) + + /* Periodic probe request timer value is half of the Min channel + * timer. Probe request sends periodically till min/max channel + * timer expires + */ + + cfgValue1 = cfgValue/2 ; + if( cfgValue1 >= 1) + { + // Create periodic probe request timer and activate them later + if (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, + "Periodic Probe Request Timer", + limTimerHandler, SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT, + cfgValue1, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start Periodic Probe Req timer. + // Log error + limLog(pMac, LOGP, FL("could not create periodic probe timer")); + goto err_timer; + } + } + + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get MAXChannelTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve MAXChannelTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + /* Limiting max numm of probe req for each channel scan */ + pMac->lim.maxProbe = (cfgValue/cfgValue1); + + if (tx_timer_create(&pMac->lim.limTimers.gLimMaxChannelTimer, + "MAX CHANNEL TIMEOUT", + limTimerHandler, SIR_LIM_MAX_CHANNEL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start max channel timer. + // Log error + limLog(pMac, LOGP, FL("could not create MAX channel timer")); + + goto err_timer; + } + PELOG2(limLog(pMac, LOG2, FL("Created MaxChannelTimer"));) + + if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE) + { + // Create Channel Switch Timer + if (tx_timer_create(&pMac->lim.limTimers.gLimChannelSwitchTimer, + "CHANNEL SWITCH TIMER", + limChannelSwitchTimerHandler, + 0, // expiration_input + LIM_CHANNEL_SWITCH_TIMER_TICKS, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Channel Switch timer")); + goto err_timer; + } + + // + // Create Quiet Timer + // This is used on the STA to go and shut-off + // Tx/Rx "after" the specified quiteInterval + // + if (tx_timer_create(&pMac->lim.limTimers.gLimQuietTimer, + "QUIET TIMER", + limQuietTimerHandler, + SIR_LIM_QUIET_TIMEOUT, // expiration_input + LIM_QUIET_TIMER_TICKS, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer")); + goto err_timer; + } + + // + // Create Quiet BSS Timer + // After the specified quiteInterval, determined by + // gLimQuietTimer, this timer, gLimQuietBssTimer, + // trigger and put the STA to sleep for the specified + // gLimQuietDuration + // + if (tx_timer_create(&pMac->lim.limTimers.gLimQuietBssTimer, + "QUIET BSS TIMER", + limQuietBssTimerHandler, + SIR_LIM_QUIET_BSS_TIMEOUT, // expiration_input + LIM_QUIET_BSS_TIMER_TICK, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get JoinFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve JoinFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Join failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimJoinFailureTimer, + "JOIN FAILURE TIMEOUT", + limTimerHandler, SIR_LIM_JOIN_FAIL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + + goto err_timer; + } + + //Send unicast probe req frame every 200 ms + if ((tx_timer_create(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, + "Periodic Join Probe Request Timer", + limTimerHandler, SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT, + SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS), 0, + TX_NO_ACTIVATE)) != TX_SUCCESS) + { + /// Could not create Periodic Join Probe Request timer. + // Log error + limLog(pMac, LOGP, FL("could not create Periodic Join Probe Request timer")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get AssocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AssocFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Association failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAssocFailureTimer, + "ASSOC FAILURE TIMEOUT", + limAssocFailureTimerHandler, LIM_ASSOC, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Assoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not create Association failure timer")); + + goto err_timer; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Association failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimReassocFailureTimer, + "REASSOC FAILURE TIMEOUT", + limAssocFailureTimerHandler, LIM_REASSOC, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not create Reassociation failure timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &cfgValue) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_ADDTS_RSP_TIMEOUT ")); + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Addts response timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAddtsRspTimer, + "ADDTS RSP TIMEOUT", + limAddtsResponseTimerHandler, + SIR_LIM_ADDTS_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Auth failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Addts response timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Auth failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAuthFailureTimer, + "AUTH FAILURE TIMEOUT", + limTimerHandler, + SIR_LIM_AUTH_FAIL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Auth failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Auth failure timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get BEACON_INTERVAL value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve BEACON_INTERVAL value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimHeartBeatTimer, + "Heartbeat TIMEOUT", + limTimerHandler, + SIR_LIM_HEART_BEAT_TIMEOUT, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("call to create heartbeat timer failed")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get PROBE_AFTER_HB_FAILURE + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value")); + } + + // Change timer to reactivate it in future + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimProbeAfterHBTimer, + "Probe after Heartbeat TIMEOUT", + limTimerHandler, + SIR_LIM_PROBE_HB_FAILURE_TIMEOUT, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not creat wt-probe-after-HeartBeat-failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to create ProbeAfterHBTimer")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get Background scan period value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Background scan period value")); + } + + /* + * setting period to zero means disabling background scans when associated + * the way we do this is to set a flag indicating this and keeping + * the timer running, since it will be used for PDU leak workarounds + * as well as background scanning during SME idle states + */ + if (cfgValue == 0) + { + cfgValue = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS; + pMac->lim.gLimBackgroundScanDisable = true; + } + else + pMac->lim.gLimBackgroundScanDisable = false; + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimBackgroundScanTimer, + "Background scan TIMEOUT", + limTimerHandler, + SIR_LIM_CHANNEL_SCAN_TIMEOUT, + cfgValue, + cfgValue, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start background scan timer. + // Log error + limLog(pMac, LOGP, + FL("call to create background scan timer failed")); + goto err_timer; + } + } + + + cfgValue = SYS_MS_TO_TICKS(LIM_HASH_MISS_TIMER_MS); + + if (tx_timer_create( + &pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer, + "Disassoc throttle TIMEOUT", + limSendDisassocFrameThresholdHandler, + SIR_LIM_HASH_MISS_THRES_TIMEOUT, + cfgValue, + cfgValue, + TX_AUTO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start Send Disassociate Frame Threshold timer. + // Log error + limLog(pMac, LOGP, + FL("create Disassociate throttle timer failed")); + goto err_timer; + } + PELOG1(limLog(pMac, LOG1, + FL("Created Disassociate throttle timer "));) + + /** + * Create keepalive timer and activate it right away for AP role + */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get keepalive timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve keepalive timeout value")); + } + + // A value of zero implies keep alive should be disabled + if (cfgValue == 0) + { + cfgValue = LIM_KEEPALIVE_TIMER_MS; + pMac->sch.keepAlive = 0; + } else + pMac->sch.keepAlive = 1; + + + cfgValue = SYS_MS_TO_TICKS(cfgValue + SYS_TICK_DUR_MS - 1); + + if (tx_timer_create(&pMac->lim.limTimers.gLimKeepaliveTimer, + "KEEPALIVE_TIMEOUT", + limKeepaliveTmerHandler, + 0, + cfgValue, + cfgValue, + (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ? + TX_AUTO_ACTIVATE : TX_NO_ACTIVATE) + != TX_SUCCESS) + { + // Cannot create keepalive timer. Log error. + limLog(pMac, LOGP, FL("Cannot create keepalive timer.")); + goto err_timer; + } + + /** + * Create all CNF_WAIT Timers upfront + */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get CNF_WAIT timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve CNF timeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + for (i=0; i < (pMac->lim.maxStation + 1); i++) + { + if (tx_timer_create(&pMac->lim.limTimers.gpLimCnfWaitTimer[i], + "CNF_MISS_TIMEOUT", + limCnfWaitTmerHandler, + (tANI_U32)i, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create timer. Log error. + limLog(pMac, LOGP, FL("Cannot create CNF wait timer.")); + goto err_timer; + } + } + + /* + ** Alloc and init table for the preAuth timer list + ** + **/ + + // get max number of Preauthentication + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + &cfgValue) != eSIR_SUCCESS) + { + /* + ** Could not get max preauth value + ** from CFG. Log error. + **/ + limLog(pMac, LOGP, + FL("could not retrieve mac preauth value")); + } + pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue; + pMac->lim.gLimPreAuthTimerTable.pTable = vos_mem_malloc(cfgValue*sizeof(tLimPreAuthNode)); + if(pMac->lim.gLimPreAuthTimerTable.pTable == NULL) + { + limLog(pMac, LOGP, FL("AllocateMemory failed!")); + goto err_timer; + } + + limInitPreAuthTimerTable(pMac, &pMac->lim.gLimPreAuthTimerTable); + PELOG1(limLog(pMac, LOG1, FL("alloc and init table for preAuth timers"));) + + + { + /** + * Create OLBC cache aging timer + */ + if (wlan_cfgGetInt(pMac, WNI_CFG_OLBC_DETECT_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get OLBC detect timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve OLBD detect timeout value")); + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create( + &pMac->lim.limTimers.gLimUpdateOlbcCacheTimer, + "OLBC UPDATE CACHE TIMEOUT", + limUpdateOlbcCacheTimerHandler, + SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, + cfgValue, + cfgValue, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create update OLBC cache timer + // Log error + limLog(pMac, LOGP, FL("Cannot create update OLBC cache timer")); + goto err_timer; + } + } +#ifdef WLAN_FEATURE_VOWIFI_11R + // In future we need to use the auth timer, cause + // the pre auth session will be introduced before sending + // Auth frame. + // We need to go off channel and come back to home channel + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimFTPreAuthRspTimer, + "FT PREAUTH RSP TIMEOUT", + limTimerHandler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + goto err_timer; + } +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + cfgValue = 5000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimEseTsmTimer, + "ESE TSM Stats TIMEOUT", + limTimerHandler, SIR_LIM_ESE_TSM_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + goto err_timer; + } +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimRemainOnChannelTimer, + "FT PREAUTH RSP TIMEOUT", + limTimerHandler, SIR_LIM_REMAIN_CHN_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + goto err_timer; + } + + + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimDisassocAckTimer, + "DISASSOC ACK TIMEOUT", + limTimerHandler, SIR_LIM_DISASSOC_ACK_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not DISASSOC ACK TIMEOUT timer")); + goto err_timer; + } + + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimDeauthAckTimer, + "DISASSOC ACK TIMEOUT", + limTimerHandler, SIR_LIM_DEAUTH_ACK_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create DEAUTH ACK TIMEOUT timer")); + goto err_timer; + } + + cfgValue = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE; // (> no of BI* no of TUs per BI * 1TU in msec + p2p start time offset*1 TU in msec = 2*100*1.024 + 5*1.024 = 204.8 + 5.12 = 209.20) + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, + "Single Shot NOA Insert timeout", + limTimerHandler, SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create Single Shot NOA Insert Timeout timer")); + goto err_timer; + } + + cfgValue = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, + "ACTIVE TO PASSIVE CHANNEL", limTimerHandler, + SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGW,FL("could not create timer for passive channel to active channel")); + goto err_timer; + } + + + return TX_SUCCESS; + + err_timer: + tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimRemainOnChannelTimer); + #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer); + #endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + while(((tANI_S32)--i) >= 0) + { + tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[i]); + } + tx_timer_delete(&pMac->lim.limTimers.gLimKeepaliveTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimBackgroundScanTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimHeartBeatTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + + if(NULL != pMac->lim.gLimPreAuthTimerTable.pTable) + { + vos_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable); + pMac->lim.gLimPreAuthTimerTable.pTable = NULL; + } + + return TX_TIMER_ERROR; + +} /****** end limCreateTimers() ******/ + + + +/** + * limTimerHandler() + * + *FUNCTION: + * This function is called upon + * 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning + * 2. JOIN_FAILURE timer expiration while joining a BSS + * 3. AUTH_FAILURE timer expiration while authenticating with a peer + * 4. Heartbeat timer expiration on STA + * 5. Background scan timer expiration on STA + * 6. AID release, Pre-auth cleanup and Link monitoring timer + * expiration on AP + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Message corresponding to the timer that expired + * + * @return None + */ + +void +limTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tANI_U32 statusCode; + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = (tANI_U16) param; + msg.bodyptr = NULL; + msg.bodyval = 0; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting message %X to LIM failed, reason=%d"), + msg.type, statusCode); +} /****** end limTimerHandler() ******/ + + +/** + * limAddtsResponseTimerHandler() + * + *FUNCTION: + * This function is called upon Addts response timer expiration on sta + * + *LOGIC: + * Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - pointer to pre-auth node + * + * @return None + */ + +void +limAddtsResponseTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT; + msg.bodyval = param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limAuthResponseTimerHandler() ******/ + + +/** + * limAuthResponseTimerHandler() + * + *FUNCTION: + * This function is called upon Auth response timer expiration on AP + * + *LOGIC: + * Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - pointer to pre-auth node + * + * @return None + */ + +void +limAuthResponseTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_AUTH_RSP_TIMEOUT; + msg.bodyptr = NULL; + msg.bodyval = (tANI_U32)param; + + limPostMsgApi(pMac, &msg); +} /****** end limAuthResponseTimerHandler() ******/ + + + +/** + * limAssocFailureTimerHandler() + * + *FUNCTION: + * This function is called upon Re/Assoc failure timer expiration + * on STA + * + *LOGIC: + * Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Indicates whether this is assoc or reassoc + * failure timeout + * @return None + */ + +void +limAssocFailureTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if((LIM_REASSOC == param) && + (NULL != pMac->lim.pSessionEntry) && + (pMac->lim.pSessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)) + { + limLog(pMac, LOGE, FL("Reassoc timeout happened")); + if(pMac->lim.reAssocRetryAttempt < LIM_MAX_REASSOC_RETRY_LIMIT) + { + limSendRetryReassocReqFrame(pMac, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, pMac->lim.pSessionEntry); + pMac->lim.reAssocRetryAttempt++; + limLog(pMac, LOGW, FL("Reassoc request retry is sent %d times"), pMac->lim.reAssocRetryAttempt); + return; + } + else + { + limLog(pMac, LOGW, FL("Reassoc request retry MAX(%d) reached"), LIM_MAX_REASSOC_RETRY_LIMIT); + if(NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) + { + vos_mem_free( pMac->lim.pSessionEntry->pLimMlmReassocRetryReq); + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL; + } + } + } +#endif + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limAssocFailureTimerHandler() ******/ + + +/** + * limUpdateOlbcCacheTimerHandler() + * + *FUNCTION: + * This function is called upon update olbc cache timer expiration + * on STA + * + *LOGIC: + * Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param + * + * @return None + */ +void +limUpdateOlbcCacheTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT; + msg.bodyval = 0; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limUpdateOlbcCacheTimerHandler() ******/ + +/** + * limDeactivateAndChangeTimer() + * + *FUNCTION: + * This function is called to deactivate and change a timer + * for future re-activation + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param timerId - enum of timer to be deactivated and changed + * This enum is defined in limUtils.h file + * + * @return None + */ + +void +limDeactivateAndChangeTimer(tpAniSirGlobal pMac, tANI_U32 timerId) +{ + tANI_U32 val=0, val1=0; + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId)); + + switch (timerId) + { + case eLIM_ADDTS_RSP_TIMER: + pMac->lim.gLimAddtsRspTimerCount++; + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS) + { + // Could not deactivate AddtsRsp Timer + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate AddtsRsp timer")); + } + break; + + case eLIM_MIN_CHANNEL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate min channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate min channel timer")); + } + + if (pMac->lim.gpLimMlmScanReq) { + val = + SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime); + if (pMac->btc.btcScanCompromise) { + if (pMac->lim.gpLimMlmScanReq->minChannelTimeBtc) { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->minChannelTimeBtc); + limLog(pMac, LOG1, + FL("Using BTC Min Active Scan time")); + } else { + limLog(pMac, LOGE, + FL("BTC Active Scan Min Time is Not Set")); + } + } + } else { + limLog(pMac, LOGE, FL("gpLimMlmScanReq is NULL")); + break; + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimMinChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change min channel timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change min channel timer")); + } + + break; + + case eLIM_PERIODIC_PROBE_REQ_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer) + != TX_SUCCESS) + { + // Could not deactivate min channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate periodic timer")); + } + + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime)/2; + if (pMac->btc.btcScanCompromise) + { + if (pMac->lim.gpLimMlmScanReq->minChannelTimeBtc) + { + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTimeBtc)/2; + } + else + { + limLog(pMac, LOGE, FL("BTC Active Scan Min Time is Not Set")); + } + } + if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, + val, 0) != TX_SUCCESS) + { + // Could not change min channel timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change periodic timer")); + } + + break; + + case eLIM_MAX_CHANNEL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate max channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate max channel timer")); + } + + // If a background was triggered via Quiet BSS, + // then we need to adjust the MIN and MAX channel + // timer's accordingly to the Quiet duration that + // was specified + if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE) + { + if (pMac->lim.gpLimMlmScanReq) { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->maxChannelTime); + if (pMac->btc.btcScanCompromise) { + if (pMac->lim.gpLimMlmScanReq->maxChannelTimeBtc) { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->maxChannelTimeBtc); + limLog(pMac, LOG1, + FL("Using BTC Max Active Scan time")); + } else { + limLog(pMac, LOGE, + FL("BTC Active Scan Max Time is Not Set")); + } + } + } else { + limLog(pMac, LOGE, FL("gpLimMlmScanReq is NULL")); + break; + } + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change max channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to change max channel timer")); + } + + break; + + case eLIM_JOIN_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer) + != TX_SUCCESS) + { + /** + * Could not deactivate Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, + FL("Unable to deactivate Join Failure timer")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get JoinFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve JoinFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, + FL("Unable to change Join Failure timer")); + } + + break; + + case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) + != TX_SUCCESS) + { + // Could not deactivate periodic join req Times. + limLog(pMac, LOGP, + FL("Unable to deactivate periodic join request timer")); + } + + val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS); + if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, + val, 0) != TX_SUCCESS) + { + // Could not change periodic join req times. + // Log error + limLog(pMac, LOGP, FL("Unable to change periodic join request timer")); + } + + break; + + case eLIM_AUTH_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer) + != TX_SUCCESS) + { + // Could not deactivate Auth failure timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate auth failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Authentication failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Auth failure timer")); + } + + break; + + case eLIM_ASSOC_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer) != + TX_SUCCESS) + { + // Could not deactivate Association failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Association failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get AssocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AssocFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Association failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Assoc failure timer")); + } + + break; + + case eLIM_REASSOC_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) != + TX_SUCCESS) + { + // Could not deactivate Reassociation failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Reassoc failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Reassociation failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Reassociation failure timer")); + } + + break; + + case eLIM_HEART_BEAT_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) != + TX_SUCCESS) + { + // Could not deactivate Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Heartbeat timer")); + } + else + { + limLog(pMac, LOGW, FL("Deactivated heartbeat link monitoring")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, + &val) != eSIR_SUCCESS) + { + /** + * Could not get BEACON_INTERVAL value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve BEACON_INTERVAL value")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != + eSIR_SUCCESS) + limLog(pMac, LOGP, + FL("could not retrieve heartbeat failure value")); + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val * val1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + val, 0) != TX_SUCCESS) + { + // Could not change HeartBeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change HeartBeat timer")); + } + else + { + limLog(pMac, LOGW, FL("HeartBeat timer value is changed = %u"), val); + } + break; + + case eLIM_PROBE_AFTER_HB_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != + TX_SUCCESS) + { + // Could not deactivate Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate probeAfterHBTimer")); + } + else + { + limLog(pMac, LOG1, FL("Deactivated probe after hb timer")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get PROBE_AFTER_HB_FAILURE + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value")); + } + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer, + val, 0) != TX_SUCCESS) + { + // Could not change HeartBeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change ProbeAfterHBTimer")); + } + else + { + limLog(pMac, LOGW, FL("Probe after HB timer value is changed = %u"), val); + } + + break; + + case eLIM_KEEPALIVE_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer) + != TX_SUCCESS) + { + // Could not deactivate Keepalive timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate KeepaliveTimer timer")); + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get keepalive timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve keepalive timeout value")); + } + if (val == 0) + { + val = 3000; + pMac->sch.keepAlive = 0; + } else + pMac->sch.keepAlive = 1; + + + + val = SYS_MS_TO_TICKS(val + SYS_TICK_DUR_MS - 1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimKeepaliveTimer, + val, val) != TX_SUCCESS) + { + // Could not change KeepaliveTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change KeepaliveTimer timer")); + } + + break; + + case eLIM_BACKGROUND_SCAN_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer) + != TX_SUCCESS) + { + // Could not deactivate BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate BackgroundScanTimer timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Background scan period value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Background scan period value")); + } + if (val == 0) + { + val = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS; + pMac->lim.gLimBackgroundScanDisable = true; + } + else + pMac->lim.gLimBackgroundScanDisable = false; + + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimBackgroundScanTimer, + val, val) != TX_SUCCESS) + { + // Could not change BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change BackgroundScanTimer timer")); + } + + break; + + case eLIM_LEARN_DURATION_TIMER: + break; + +#ifdef WLAN_FEATURE_VOWIFI_11R + case eLIM_FT_PREAUTH_RSP_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Preauth response Failure timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimFTPreAuthRspTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change Join Failure timer")); + return; + } + break; +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + case eLIM_TSM_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer) + != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("Unable to deactivate TSM timer")); + } + break; +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + case eLIM_REMAIN_CHN_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Remain on Chn timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Active to passive channel timer. + ** Log error. + **/ + limLog(pMac, LOGP, FL("Unable to Deactivate " + "Active to passive channel timer")); + return; + } + val = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change timer to check scan type for passive channel. + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_DISASSOC_ACK_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Disassoc ack timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimDisassocAckTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_DEAUTH_ACK_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Deauth ack timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimDeauthAckTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_INSERT_SINGLESHOT_NOA_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate SingleShot NOA Insert + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate SingleShot NOA Insert timer")); + return; + } + val = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Single Shot NOA Insert + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + default: + // Invalid timerId. Log error + break; + } +} /****** end limDeactivateAndChangeTimer() ******/ + + + +/**--------------------------------------------------------------- +\fn limHeartBeatDeactivateAndChangeTimer +\brief This function deactivates and changes the heart beat +\ timer, eLIM_HEART_BEAT_TIMER. +\ +\param pMac +\param psessionEntry +\return None +------------------------------------------------------------------*/ +void +limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 val, val1; + + if (NULL == psessionEntry) { + limLog(pMac, LOGE, FL("%s: received session id NULL." + " Heartbeat timer config failed"), __func__); + return; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + return; +#endif + + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Fail to deactivate HeartBeatTimer ")); + + /* HB Timer sessionisation: In case of 2 or more sessions, the HB interval keeps + changing. to avoid this problem, HeartBeat interval is made constant, by + fixing beacon interval to 100ms immaterial of the beacon interval of the session */ + + //val = psessionEntry->beaconParams.beaconInterval; + val = LIM_HB_TIMER_BEACON_INTERVAL; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_HEART_BEAT_THRESHOLD ")); + + PELOGW(limLog(pMac,LOGW, + FL("HB Timer Int.=100ms * %d, Beacon Int.=%dms,Session Id=%d "), + val1, psessionEntry->beaconParams.beaconInterval, + psessionEntry->peSessionId);) + + /* The HB timer timeout value of 4 seconds (40 beacon intervals) is not + * enough to judge the peer device inactivity when 32 peers are connected. + * Hence increasing the HB timer timeout to + * HBtimeout = (TBTT * num_beacons * num_peers) + */ + if (eSIR_IBSS_MODE == psessionEntry->bssType && + pMac->lim.gLimNumIbssPeers > 0) + { + val1 = val1 * pMac->lim.gLimNumIbssPeers; + } + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val * val1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, val, 0) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Fail to change HeartBeatTimer")); + +} /****** end limHeartBeatDeactivateAndChangeTimer() ******/ + + +/**--------------------------------------------------------------- +\fn limReactivateHeartBeatTimer +\brief This function s called to deactivate, change and +\ activate a timer. +\ +\param pMac - Pointer to Global MAC structure +\param psessionEntry +\return None +------------------------------------------------------------------*/ +void +limReactivateHeartBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + PELOG3(limLog(pMac, LOG3, FL("Rxed Heartbeat. Count=%d"), psessionEntry->LimRxedBeaconCntDuringHB);) + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + limLog(pMac, LOGW, FL("Active offload feature is enabled, FW takes care of HB monitoring")); + return; + } +#endif + + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + + //only start the hearbeat-timer if the timeout value is non-zero + if(pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs > 0) + { + /* + * There is increasing need to limit the apps wakeup due to WLAN + * activity. During HB monitoring, the beacons from peer are sent to + * the host causing the host to wakeup. Hence, offloading the HB + * monitoring to LMAC + */ + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && + IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGP,FL("IBSS HeartBeat Offloaded, Could not deactivate Heartbeat timer")); + } + else + { + limLog(pMac, LOGE, FL("IBSS HeartBeat Offloaded, Deactivated heartbeat link monitoring")); + } + } + else + { + if (tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGP,FL("could not activate Heartbeat timer")); + } + else + { + limLog(pMac, LOGW, FL("Reactivated heartbeat link monitoring")); + } + } + limResetHBPktCount(psessionEntry); + } + +} /****** end limReactivateHeartBeatTimer() ******/ + + +/** + * limActivateHearBeatTimer() + * + * + * @brief: This function is called to activate heartbeat timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry - Session Entry + * + * @return TX_SUCCESS - timer is activated + * errors - fail to start the timer + */ +v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + v_UINT_t status = TX_TIMER_ERROR; + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + return (TX_SUCCESS); +#endif + + if(TX_AIRGO_TMR_SIGNATURE == pMac->lim.limTimers.gLimHeartBeatTimer.tmrSignature) + { + //consider 0 interval a ok case + if( pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs ) + { + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && + IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + /* HB offload in IBSS mode */ + status = tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + if (TX_SUCCESS != status) + { + PELOGE(limLog(pMac, LOGE, + FL("IBSS HB Offload, Could not deactivate HB timer status(%d)"), + status);) + } + else + { + PELOGE(limLog(pMac, LOGE, + FL("%s] IBSS HB Offloaded, Heartbeat timer deactivated"), + __func__);) + } + + } + else + { + status = tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer); + if ( TX_SUCCESS != status ) + { + PELOGE(limLog(pMac, LOGE, + FL("could not activate Heartbeat timer status(%d)"), status);) + } + else + { + PELOGE(limLog(pMac, LOGW, + FL("%s] Activated Heartbeat timer status(%d)"), __func__, status);) + } + } + } + else + { + status = TX_SUCCESS; + } + } + + return (status); +} + + + +/** + * limDeactivateAndChangePerStaIdTimer() + * + * + * @brief: This function is called to deactivate and change a per STA timer + * for future re-activation + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param timerId - enum of timer to be deactivated and changed + * This enum is defined in limUtils.h file + * @param staId - staId + * + * @return None + */ + +void +limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal pMac, tANI_U32 timerId, tANI_U16 staId) +{ + tANI_U32 val; + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId)); + + switch (timerId) + { + case eLIM_CNF_WAIT_TIMER: + + if (tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId]) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to deactivate CNF wait timer")); + + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get cnf timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve cnf timeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId], + val, val) != TX_SUCCESS) + { + // Could not change cnf timer. + // Log error + limLog(pMac, LOGP, FL("unable to change cnf wait timer")); + } + + break; + + case eLIM_AUTH_RSP_TIMER: + { + tLimPreAuthNode *pAuthNode; + + pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, staId); + + if (pAuthNode == NULL) + { + limLog(pMac, LOGP, FL("Invalid Pre Auth Index passed :%d"), staId); + break; + } + + if (tx_timer_deactivate(&pAuthNode->timer) != TX_SUCCESS) + { + // Could not deactivate auth response timer. + // Log error + limLog(pMac, LOGP, FL("unable to deactivate auth response timer")); + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, &val) != eSIR_SUCCESS) + { + /** + * Could not get auth rsp timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve auth response timeout value")); + } + + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pAuthNode->timer, val, 0) != TX_SUCCESS) + { + // Could not change auth rsp timer. + // Log error + limLog(pMac, LOGP, FL("unable to change auth rsp timer")); + } + } + break; + + + default: + // Invalid timerId. Log error + break; + + } +} + + +/** + * limActivateCnfTimer() + * + *FUNCTION: + * This function is called to activate a per STA timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param StaId - staId + * + * @return None + */ + +void limActivateCnfTimer(tpAniSirGlobal pMac, tANI_U16 staId, tpPESession psessionEntry) +{ + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_CNF_WAIT_TIMER)); + pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId = psessionEntry->peSessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId]) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("could not activate cnf wait timer")); + } +} + +/** + * limActivateAuthRspTimer() + * + *FUNCTION: + * This function is called to activate a per STA timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param id - id + * + * @return None + */ + +void limActivateAuthRspTimer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode) +{ + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_AUTH_RESP_TIMER)); + if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS) + { + /// Could not activate auth rsp timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate auth rsp timer")); + } +} + + +/** + * limSendDisassocFrameThresholdHandler() + * + *FUNCTION: + * This function reloads the credit to the send disassociate frame bucket + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param + * + * @return None + */ + +void +limSendDisassocFrameThresholdHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tANI_U32 statusCode; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_HASH_MISS_THRES_TIMEOUT; + msg.bodyval = 0; + msg.bodyptr = NULL; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting to LIM failed, reason=%d"), statusCode); + +} + +/** + * limAssocCnfWaitTmerHandler() + * + *FUNCTION: + * This function post a message to send a disassociate frame out. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param + * + * @return None + */ + +void +limCnfWaitTmerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tANI_U32 statusCode; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_CNF_WAIT_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting to LIM failed, reason=%d"), statusCode); + +} + +/** + * limKeepaliveTmerHandler() + * + *FUNCTION: + * This function post a message to send a NULL data frame. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param + * + * @return None + */ + +void +limKeepaliveTmerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tANI_U32 statusCode; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_KEEPALIVE_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting to LIM failed, reason=%d"), statusCode); + +} + +void +limChannelSwitchTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + PELOG1(limLog(pMac, LOG1, + FL("ChannelSwitch Timer expired. Posting msg to LIM "));) + + msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} + +void +limQuietTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_QUIET_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + PELOG1(limLog(pMac, LOG1, + FL("Post SIR_LIM_QUIET_TIMEOUT msg. "));) + limPostMsgApi(pMac, &msg); +} + +void +limQuietBssTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_QUIET_BSS_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + PELOG1(limLog(pMac, LOG1, + FL("Post SIR_LIM_QUIET_BSS_TIMEOUT msg. "));) + limPostMsgApi(pMac, &msg); +} + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +/* ACTIVE_MODE_HB_OFFLOAD */ +/** + * limMissedBeaconInActiveMode() + * + *FUNCTION: + * This function handle beacon miss indication from FW + * in Active mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Msg Type + * + * @return None + */ +void +limMissedBeaconInActiveMode(void *pMacGlobal, tpPESession psessionEntry) +{ + tANI_U32 statusCode; + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + msg.type = (tANI_U16) SIR_LIM_HEART_BEAT_TIMEOUT; + msg.bodyptr = psessionEntry; + msg.bodyval = 0; + limLog(pMac, LOGE, + FL("Heartbeat failure from Riva")); + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting message %X to LIM failed, reason=%d"), + msg.type, statusCode); + } +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.h new file mode 100644 index 0000000000000..e7fca727cd001 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTimerUtils.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limTimerUtils.h contains the utility definitions + * LIM uses for timer handling. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_TIMER_UTILS_H +#define __LIM_TIMER_UTILS_H + +#include "limTypes.h" + + +// Timer related functions +enum +{ + eLIM_MIN_CHANNEL_TIMER, + eLIM_MAX_CHANNEL_TIMER, + eLIM_JOIN_FAIL_TIMER, + eLIM_AUTH_FAIL_TIMER, + eLIM_AUTH_RESP_TIMER, + eLIM_ASSOC_FAIL_TIMER, + eLIM_REASSOC_FAIL_TIMER, + eLIM_PRE_AUTH_CLEANUP_TIMER, + eLIM_HEART_BEAT_TIMER, + eLIM_BACKGROUND_SCAN_TIMER, + eLIM_KEEPALIVE_TIMER, + eLIM_CNF_WAIT_TIMER, + eLIM_AUTH_RSP_TIMER, + eLIM_UPDATE_OLBC_CACHE_TIMER, + eLIM_PROBE_AFTER_HB_TIMER, + eLIM_ADDTS_RSP_TIMER, + eLIM_CHANNEL_SWITCH_TIMER, + eLIM_LEARN_DURATION_TIMER, + eLIM_QUIET_TIMER, + eLIM_QUIET_BSS_TIMER, + eLIM_WPS_OVERLAP_TIMER, +#ifdef WLAN_FEATURE_VOWIFI_11R + eLIM_FT_PREAUTH_RSP_TIMER, +#endif + eLIM_REMAIN_CHN_TIMER, + eLIM_PERIODIC_PROBE_REQ_TIMER, +#ifdef FEATURE_WLAN_ESE + eLIM_TSM_TIMER, +#endif + eLIM_DISASSOC_ACK_TIMER, + eLIM_DEAUTH_ACK_TIMER, + eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER, + eLIM_INSERT_SINGLESHOT_NOA_TIMER, + eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE +}; + +#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500 +#define LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE 500 + + +// Timer Handler functions +v_UINT_t limCreateTimers(tpAniSirGlobal); +void limTimerHandler(void *, tANI_U32); +void limAuthResponseTimerHandler(void *, tANI_U32); +void limAssocFailureTimerHandler(void *, tANI_U32); +void limReassocFailureTimerHandler(void *, tANI_U32); + +void limDeactivateAndChangeTimer(tpAniSirGlobal, tANI_U32); +void limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal, tpPESession); +void limReactivateHeartBeatTimer(tpAniSirGlobal, tpPESession); +void limDummyPktExpTimerHandler(void *, tANI_U32); +void limSendDisassocFrameThresholdHandler(void *, tANI_U32); +void limCnfWaitTmerHandler(void *, tANI_U32); +void limKeepaliveTmerHandler(void *, tANI_U32); +void limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal, tANI_U32, tANI_U16); +void limActivateCnfTimer(tpAniSirGlobal, tANI_U16, tpPESession); +void limActivateAuthRspTimer(tpAniSirGlobal, tLimPreAuthNode *); +void limUpdateOlbcCacheTimerHandler(void *, tANI_U32); +void limAddtsResponseTimerHandler(void *, tANI_U32); +void limChannelSwitchTimerHandler(void *, tANI_U32); +void limQuietTimerHandler(void *, tANI_U32); +void limQuietBssTimerHandler(void *, tANI_U32); +void limCBScanIntervalTimerHandler(void *, tANI_U32); +void limCBScanDurationTimerHandler(void *, tANI_U32); +/** + * limActivateHearBeatTimer() + * + * + * @brief: This function is called to activate heartbeat timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry - Pointer to PE session entry + * + * @return TX_SUCCESS - timer is activated + * errors - fail to start the timer + */ +v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry); + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +void limMissedBeaconInActiveMode(void *pMacGlobal, tpPESession psessionEntry); +#endif +#endif /* __LIM_TIMER_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTrace.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTrace.c new file mode 100644 index 0000000000000..94bc668eecd82 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTrace.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limTrace.c + + \brief implementation for trace related APIs + + \author Sunit Bhatia + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include "aniGlobal.h" //for tpAniSirGlobal + +#include "limTrace.h" +#include "limTimerUtils.h" +#include "vos_trace.h" + + +#ifdef LIM_TRACE_RECORD +tANI_U32 gMgmtFrameStats[14]; + +#define LIM_TRACE_MAX_SUBTYPES 14 + + +static tANI_U8* __limTraceGetTimerString( tANI_U16 timerId ) +{ + switch( timerId ) + { + CASE_RETURN_STRING(eLIM_MIN_CHANNEL_TIMER); + CASE_RETURN_STRING(eLIM_MAX_CHANNEL_TIMER); + CASE_RETURN_STRING(eLIM_JOIN_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_RESP_TIMER); + CASE_RETURN_STRING(eLIM_ASSOC_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_REASSOC_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_PRE_AUTH_CLEANUP_TIMER); + CASE_RETURN_STRING(eLIM_HEART_BEAT_TIMER); + CASE_RETURN_STRING(eLIM_BACKGROUND_SCAN_TIMER); + CASE_RETURN_STRING(eLIM_KEEPALIVE_TIMER); + CASE_RETURN_STRING(eLIM_CNF_WAIT_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_RSP_TIMER); + CASE_RETURN_STRING(eLIM_UPDATE_OLBC_CACHE_TIMER); + CASE_RETURN_STRING(eLIM_PROBE_AFTER_HB_TIMER); + CASE_RETURN_STRING(eLIM_ADDTS_RSP_TIMER); + CASE_RETURN_STRING(eLIM_CHANNEL_SWITCH_TIMER); + CASE_RETURN_STRING(eLIM_LEARN_DURATION_TIMER); + CASE_RETURN_STRING(eLIM_QUIET_TIMER); + CASE_RETURN_STRING(eLIM_QUIET_BSS_TIMER); + CASE_RETURN_STRING(eLIM_WPS_OVERLAP_TIMER); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eLIM_FT_PREAUTH_RSP_TIMER); +#endif + CASE_RETURN_STRING(eLIM_REMAIN_CHN_TIMER); + CASE_RETURN_STRING(eLIM_PERIODIC_PROBE_REQ_TIMER); +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(eLIM_TSM_TIMER); +#endif + CASE_RETURN_STRING(eLIM_DISASSOC_ACK_TIMER); + CASE_RETURN_STRING(eLIM_DEAUTH_ACK_TIMER); + CASE_RETURN_STRING(eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER); + CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE); + default: + return( "UNKNOWN" ); + break; + } +} + + +static tANI_U8* __limTraceGetMgmtDropReasonString( tANI_U16 dropReason ) +{ + + switch( dropReason ) + { + CASE_RETURN_STRING(eMGMT_DROP_INFRA_BCN_IN_IBSS); + CASE_RETURN_STRING(eMGMT_DROP_INVALID_SIZE); + CASE_RETURN_STRING(eMGMT_DROP_NON_SCAN_MODE_FRAME); + CASE_RETURN_STRING(eMGMT_DROP_NOT_LAST_IBSS_BCN); + CASE_RETURN_STRING(eMGMT_DROP_NO_DROP); + CASE_RETURN_STRING(eMGMT_DROP_SCAN_MODE_FRAME); + + default: + return( "UNKNOWN" ); + break; + } +} + + + +void limTraceInit(tpAniSirGlobal pMac) +{ + vosTraceRegister(VOS_MODULE_ID_PE, (tpvosTraceCb)&limTraceDump); +} + + + + +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) +{ + + static char *frameSubtypeStr[LIM_TRACE_MAX_SUBTYPES] = + { + "Association request", + "Association response", + "Reassociation request", + "Reassociation response", + "Probe request", + "Probe response", + NULL, + NULL, + "Beacon", + "ATIM", + "Disassocation", + "Authentication", + "Deauthentication", + "Action" + }; + + + switch (pRecord->code) { + case TRACE_CODE_MLM_STATE: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "MLM State:", limTraceGetMlmStateString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_SME_STATE: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "SME State:", limTraceGetSmeStateString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_TX_MGMT: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "TX Mgmt:", frameSubtypeStr[pRecord->data], pRecord->data ); + break; + + case TRACE_CODE_RX_MGMT: + if (LIM_TRACE_MAX_SUBTYPES <= LIM_TRACE_GET_SUBTYPE(pRecord->data)) + { + limLog(pMac, LOGE, "Wrong Subtype - %d", LIM_TRACE_GET_SUBTYPE(pRecord->data)); + } + else + { + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(%d) SN: %d ", recIndex, pRecord->time, pRecord->session, + "RX Mgmt:", frameSubtypeStr[LIM_TRACE_GET_SUBTYPE(pRecord->data)], + LIM_TRACE_GET_SUBTYPE(pRecord->data), + LIM_TRACE_GET_SSN(pRecord->data) ); + } + break; + case TRACE_CODE_RX_MGMT_DROP: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(%d) ", recIndex, pRecord->time, pRecord->session, + "Drop RX Mgmt:", __limTraceGetMgmtDropReasonString((tANI_U16)pRecord->data), pRecord->data); + break; + + + case TRACE_CODE_RX_MGMT_TSF: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s0x%x(%d) ", recIndex, pRecord->time, pRecord->session, + "RX Mgmt TSF:", " ", pRecord->data, pRecord->data ); + break; + + case TRACE_CODE_TX_COMPLETE: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %d " , recIndex, pRecord->time, pRecord->session, + "TX Complete", pRecord->data ); + break; + + case TRACE_CODE_TX_SME_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "TX SME Msg:", macTraceGetSmeMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_RX_SME_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX Sme Msg:", + macTraceGetSmeMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + + case TRACE_CODE_TX_WDA_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "TX WDA Msg:", macTraceGetWdaMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + + case TRACE_CODE_RX_WDA_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX WDA Msg:", + macTraceGetWdaMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + + case TRACE_CODE_TX_LIM_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "TX LIM Msg:", macTraceGetLimMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_RX_LIM_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX LIM Msg", + macTraceGetLimMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_TX_CFG_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "TX CFG Msg:", macTraceGetCfgMsgString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_RX_CFG_MSG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX CFG Msg:", + macTraceGetCfgMsgString((tANI_U16)MAC_TRACE_GET_MSG_ID(pRecord->data)), + pRecord->data ); + break; + + case TRACE_CODE_TIMER_ACTIVATE: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "Timer Actvtd", __limTraceGetTimerString((tANI_U16)pRecord->data), pRecord->data ); + break; + case TRACE_CODE_TIMER_DEACTIVATE: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex, pRecord->time, pRecord->session, + "Timer DeActvtd", __limTraceGetTimerString((tANI_U16)pRecord->data), pRecord->data ); + break; + + case TRACE_CODE_INFO_LOG: + limLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session, + "INFORMATION_LOG", macTraceGetInfoLogString((tANI_U16)pRecord->data), pRecord->data ); + break; + default : + limLog(pMac, LOGE, "%04d %012llu S%d %-14s(%d) (0x%x) ", recIndex, pRecord->time, pRecord->session, + "Unknown Code", pRecord->code, pRecord->data ); + break; + } +} + + +void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data) +{ + + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTrace(pMac, TRACE_CODE_TX_LIM_MSG, session, data); + else + macTrace(pMac, TRACE_CODE_TX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTrace(pMac, TRACE_CODE_TX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTrace(pMac, TRACE_CODE_TX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + +void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTraceNew(pMac, module, TRACE_CODE_TX_LIM_MSG, session, data); + else + macTraceNew(pMac, module, TRACE_CODE_TX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_TX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_TX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + +/* +* bit31: Rx message defferred or not +* bit 0-15: message ID: +*/ +void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTrace(pMac, TRACE_CODE_RX_LIM_MSG, session, data); + else + macTrace(pMac, TRACE_CODE_RX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTrace(pMac, TRACE_CODE_RX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTrace(pMac, TRACE_CODE_RX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + + +/* +* bit31: Rx message defferred or not +* bit 0-15: message ID: +*/ +void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTraceNew(pMac, module, TRACE_CODE_RX_LIM_MSG, session, data); + else + macTraceNew(pMac, module, TRACE_CODE_RX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_RX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_RX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + + +tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState ) +{ + switch( mlmState ) + { + CASE_RETURN_STRING( eLIM_MLM_OFFLINE_STATE); + CASE_RETURN_STRING( eLIM_MLM_IDLE_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_PROBE_RESP_STATE); + CASE_RETURN_STRING( eLIM_MLM_PASSIVE_SCAN_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_JOIN_BEACON_STATE); + CASE_RETURN_STRING( eLIM_MLM_JOINED_STATE); + CASE_RETURN_STRING( eLIM_MLM_BSS_STARTED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME2_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME3_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME4_STATE); + CASE_RETURN_STRING( eLIM_MLM_AUTH_RSP_TIMEOUT_STATE); + CASE_RETURN_STRING( eLIM_MLM_AUTHENTICATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REASSOC_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_ASSOCIATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_REASSOCIATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_LINK_ESTABLISHED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_CNF_STATE); + CASE_RETURN_STRING( eLIM_MLM_LEARN_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_DEL_BSS_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_DEL_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_BSS_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_BCASTKEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADDBA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_STA_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_MIMOPS_STATE); + default: + return( "UNKNOWN" ); + break; + } +} + + +tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState ) +{ + switch( smeState ) + { + + CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_SME_IDLE_STATE); + CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE); + CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE); + CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE); + CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE); + default: + return( "UNKNOWN" ); + break; + } +} + + + + + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTypes.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTypes.h new file mode 100644 index 0000000000000..dc8961920fc07 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limTypes.h @@ -0,0 +1,1073 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limTypes.h contains the definitions used by all + * all LIM modules. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_TYPES_H +#define __LIM_TYPES_H + +#include "wniApi.h" +#include "sirApi.h" +#include "sirCommon.h" +#include "sirMacProtDef.h" +#include "utilsApi.h" + +#include "wlan_qct_wdi_ds.h" + +#include "limApi.h" +#include "limDebug.h" +#include "limSendSmeRspMessages.h" +#include "sysGlobal.h" +#include "dphGlobal.h" +#include "parserApi.h" + +#define LINK_TEST_DEFER 1 + +#define TRACE_EVENT_CNF_TIMER_DEACT 0x6600 +#define TRACE_EVENT_CNF_TIMER_ACT 0x6601 +#define TRACE_EVENT_AUTH_RSP_TIMER_DEACT 0x6602 +#define TRACE_EVENT_AUTH_RSP_TIMER_ACT 0x6603 + +// MLM message types +#define LIM_MLM_MSG_START 1000 +#define LIM_MLM_SCAN_REQ LIM_MLM_MSG_START +#define LIM_MLM_SCAN_CNF (LIM_MLM_MSG_START + 1) +#define LIM_MLM_START_REQ (LIM_MLM_MSG_START + 2) +#define LIM_MLM_START_CNF (LIM_MLM_MSG_START + 3) +#define LIM_MLM_JOIN_REQ (LIM_MLM_MSG_START + 4) +#define LIM_MLM_JOIN_CNF (LIM_MLM_MSG_START + 5) +#define LIM_MLM_AUTH_REQ (LIM_MLM_MSG_START + 6) +#define LIM_MLM_AUTH_CNF (LIM_MLM_MSG_START + 7) +#define LIM_MLM_AUTH_IND (LIM_MLM_MSG_START + 8) +#define LIM_MLM_ASSOC_REQ (LIM_MLM_MSG_START + 9) +#define LIM_MLM_ASSOC_CNF (LIM_MLM_MSG_START + 10) +#define LIM_MLM_ASSOC_IND (LIM_MLM_MSG_START + 11) +#define LIM_MLM_DISASSOC_REQ (LIM_MLM_MSG_START + 12) +#define LIM_MLM_DISASSOC_CNF (LIM_MLM_MSG_START + 13) +#define LIM_MLM_DISASSOC_IND (LIM_MLM_MSG_START + 14) +#define LIM_MLM_REASSOC_REQ (LIM_MLM_MSG_START + 15) +#define LIM_MLM_REASSOC_CNF (LIM_MLM_MSG_START + 16) +#define LIM_MLM_REASSOC_IND (LIM_MLM_MSG_START + 17) +#define LIM_MLM_DEAUTH_REQ (LIM_MLM_MSG_START + 18) +#define LIM_MLM_DEAUTH_CNF (LIM_MLM_MSG_START + 19) +#define LIM_MLM_DEAUTH_IND (LIM_MLM_MSG_START + 20) +#define LIM_MLM_TSPEC_REQ (LIM_MLM_MSG_START + 21) +#define LIM_MLM_TSPEC_CNF (LIM_MLM_MSG_START + 22) +#define LIM_MLM_TSPEC_IND (LIM_MLM_MSG_START + 23) +#define LIM_MLM_SETKEYS_REQ (LIM_MLM_MSG_START + 24) +#define LIM_MLM_SETKEYS_CNF (LIM_MLM_MSG_START + 25) +#define LIM_MLM_LINK_TEST_STOP_REQ (LIM_MLM_MSG_START + 30) +#define LIM_MLM_PURGE_STA_IND (LIM_MLM_MSG_START + 31) +#define LIM_MLM_ADDBA_REQ (LIM_MLM_MSG_START + 32) +#define LIM_MLM_ADDBA_CNF (LIM_MLM_MSG_START + 33) +#define LIM_MLM_ADDBA_IND (LIM_MLM_MSG_START + 34) +#define LIM_MLM_ADDBA_RSP (LIM_MLM_MSG_START + 35) +#define LIM_MLM_DELBA_REQ (LIM_MLM_MSG_START + 36) +#define LIM_MLM_DELBA_CNF (LIM_MLM_MSG_START + 37) +#define LIM_MLM_DELBA_IND (LIM_MLM_MSG_START + 38) +#define LIM_MLM_REMOVEKEY_REQ (LIM_MLM_MSG_START + 39) +#define LIM_MLM_REMOVEKEY_CNF (LIM_MLM_MSG_START + 40) + +#ifdef FEATURE_OEM_DATA_SUPPORT +#define LIM_MLM_OEM_DATA_REQ (LIM_MLM_MSG_START + 41) +#define LIM_MLM_OEM_DATA_CNF (LIM_MLM_MSG_START + 42) +#endif + +#define LIM_HASH_ADD 0 +#define LIM_HASH_UPDATE 1 + +#define LIM_WEP_IN_FC 1 +#define LIM_NO_WEP_IN_FC 0 + +#define LIM_DECRYPT_ICV_FAIL 1 + +/// Definitions to distinquish between Association/Reassociaton +#define LIM_ASSOC 0 +#define LIM_REASSOC 1 + +/// Minimum Memory blocks require for different scenario +#define LIM_MIN_MEM_ASSOC 4 + +/// Verifies whether given mac addr matches the CURRENT Bssid +#define IS_CURRENT_BSSID(pMac, addr,psessionEntry) (vos_mem_compare( addr, \ + psessionEntry->bssId, \ + sizeof(psessionEntry->bssId))) +/// Verifies whether given addr matches the REASSOC Bssid +#define IS_REASSOC_BSSID(pMac, addr,psessionEntry) (vos_mem_compare( addr, \ + psessionEntry->limReAssocbssId, \ + sizeof(psessionEntry->limReAssocbssId))) + +#define REQ_TYPE_REGISTRAR (0x2) +#define REQ_TYPE_WLAN_MANAGER_REGISTRAR (0x3) + +#define RESP_TYPE_REGISTRAR (0x2) +#define RESP_TYPE_ENROLLEE_INFO_ONLY (0x0) +#define RESP_TYPE_ENROLLEE_OPEN_8021X (0x1) +#define RESP_TYPE_AP (0x3) +#define LIM_TX_FRAMES_THRESHOLD_ON_CHIP 300 + + +// enums used by LIM are as follows + +enum eLimDisassocTrigger +{ + eLIM_HOST_DISASSOC, + eLIM_PEER_ENTITY_DISASSOC, + eLIM_LINK_MONITORING_DISASSOC, + eLIM_PROMISCUOUS_MODE_DISASSOC, + eLIM_HOST_DEAUTH, + eLIM_PEER_ENTITY_DEAUTH, + eLIM_LINK_MONITORING_DEAUTH, + eLIM_JOIN_FAILURE, + eLIM_REASSOC_REJECT +}; + +/* Reason code to determine the channel change context while sending + * WDA_CHNL_SWITCH_REQ message to HAL + */ +enum eChannelChangeReasonCodes +{ + LIM_SWITCH_CHANNEL_REASSOC, + LIM_SWITCH_CHANNEL_JOIN, + LIM_SWITCH_CHANNEL_OPERATION, // Generic change channel + LIM_SWITCH_CHANNEL_SAP_DFS, // DFS channel change +}; + +typedef struct sLimAuthRspTimeout +{ + tSirMacAddr peerMacAddr; +} tLimAuthRspTimeout; + +typedef struct sLimMlmStartReq +{ + tSirMacSSid ssId; + tSirBssType bssType; + tSirMacAddr bssId; + tSirMacBeaconInterval beaconPeriod; + tANI_U8 dtimPeriod; + tSirMacCfParamSet cfParamSet; + tSirMacChanNum channelNumber; + ePhyChanBondState cbMode; + tANI_U16 atimWindow; + tSirMacRateSet rateSet; + tANI_U8 sessionId; //Added For BT-AMP Support + + // Parameters reqd for new HAL (message) interface + tSirNwType nwType; + tANI_U8 htCapable; + tSirMacHTOperatingMode htOperMode; + tANI_U8 dualCTSProtection; + tANI_U8 txChannelWidthSet; + tANI_U8 ssidHidden; + tANI_U8 wps_state; + tANI_U8 obssProtEnabled; +} tLimMlmStartReq, *tpLimMlmStartReq; + +typedef struct sLimMlmStartCnf +{ + tSirResultCodes resultCode; + tANI_U8 sessionId; +} tLimMlmStartCnf, *tpLimMlmStartCnf; + +typedef struct sLimMlmScanCnf +{ + tSirResultCodes resultCode; + tANI_U16 scanResultLength; + tSirBssDescription bssDescription[1]; + tANI_U8 sessionId; +} tLimMlmScanCnf, *tpLimMlmScanCnf; + +typedef struct sLimScanResult +{ + tANI_U16 numBssDescriptions; + tSirBssDescription bssDescription[1]; +} tLimScanResult; + +typedef struct sLimMlmJoinCnf +{ + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + tANI_U8 sessionId; +} tLimMlmJoinCnf, *tpLimMlmJoinCnf; + +typedef struct sLimMlmAssocReq +{ + tSirMacAddr peerMacAddr; + tANI_U32 assocFailureTimeout; + tANI_U16 capabilityInfo; + tSirMacListenInterval listenInterval; + tANI_U8 sessionId; +} tLimMlmAssocReq, *tpLimMlmAssocReq; + +typedef struct sLimMlmAssocCnf +{ + tSirResultCodes resultCode; //Internal status code. + tANI_U16 protStatusCode; //Protocol Status code. + tANI_U8 sessionId; +} tLimMlmAssocCnf, *tpLimMlmAssocCnf; + +typedef struct sLimMlmAssocInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tAniAuthType authType; + tAniSSID ssId; + tSirRSNie rsnIE; + tSirAddie addIE; // additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. + tSirMacCapabilityInfo capabilityInfo; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + tANI_U8 sessionId; + + + tAniBool WmmStaInfoPresent; + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + tSirSmeChanInfo chan_info; +} tLimMlmAssocInd, *tpLimMlmAssocInd; + +typedef struct sLimMlmReassocReq +{ + tSirMacAddr peerMacAddr; + tANI_U32 reassocFailureTimeout; + tANI_U16 capabilityInfo; + tSirMacListenInterval listenInterval; + tANI_U8 sessionId; +} tLimMlmReassocReq, *tpLimMlmReassocReq; + +typedef struct sLimMlmReassocCnf +{ + tSirResultCodes resultCode; + tANI_U16 protStatusCode; //Protocol Status code. + tANI_U8 sessionId; +} tLimMlmReassocCnf, *tpLimMlmReassocCnf; + +typedef struct sLimMlmReassocInd +{ + tSirMacAddr peerMacAddr; + tSirMacAddr currentApAddr; + tANI_U16 aid; + tAniAuthType authType; + tAniSSID ssId; + tSirRSNie rsnIE; + tSirAddie addIE; // additional IE received from the peer, which can be WSC IE and/or P2P IE. + tSirMacCapabilityInfo capabilityInfo; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + + tAniBool WmmStaInfoPresent; + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; +} tLimMlmReassocInd, *tpLimMlmReassocInd; + +typedef struct sLimMlmAuthCnf +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + tANI_U8 sessionId; +} tLimMlmAuthCnf, *tpLimMlmAuthCnf; + +typedef struct sLimMlmAuthInd +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tANI_U8 sessionId; +} tLimMlmAuthInd, *tpLimMlmAuthInd; + +typedef struct sLimMlmDeauthReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; + tANI_U8 sessionId; //Added for BT-AMP SUPPORT + +} tLimMlmDeauthReq, *tpLimMlmDeauthReq; + +typedef struct sLimMlmDeauthCnf +{ + tSirMacAddr peerMacAddr; + tSirResultCodes resultCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDeauthCnf, *tpLimMLmDeauthCnf; + +typedef struct sLimMlmDeauthInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; +} tLimMlmDeauthInd, *tpLimMlmDeauthInd; + +typedef struct sLimMlmDisassocReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocReq, *tpLimMlmDisassocReq; + +typedef struct sLimMlmDisassocCnf +{ + tSirMacAddr peerMacAddr; + tSirResultCodes resultCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocCnf, *tpLimMlmDisassocCnf; + +typedef struct sLimMlmDisassocInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocInd, *tpLimMlmDisassocInd; + +typedef struct sLimMlmPurgeStaReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tANI_U8 sessionId;//Added For BT-AMP Support +} tLimMlmPurgeStaReq, *tpLimMlmPurgeStaReq; + +typedef struct sLimMlmPurgeStaInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 purgeTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmPurgeStaInd, *tpLimMlmPurgeStaInd; + +typedef struct sLimMlmSetKeysCnf +{ + tSirMacAddr peerMacAddr; + tANI_U16 resultCode; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmSetKeysCnf, *tpLimMlmSetKeysCnf; + +typedef struct sLimMlmRemoveKeyReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; //Added FOr BT-AMP Support + tAniEdType edType; // Encryption/Decryption type + tANI_U8 wepType; //STATIC / DYNAMIC specifier + tANI_U8 keyId; //Key Id To be removed. + tANI_BOOLEAN unicast; +} tLimMlmRemoveKeyReq, *tpLimMlmRemoveKeyReq; + +typedef struct sLimMlmRemoveKeyCnf +{ + tSirMacAddr peerMacAddr; + tANI_U16 resultCode; + tANI_U8 sessionId; +} tLimMlmRemoveKeyCnf, *tpLimMlmRemoveKeyCnf; + + +typedef struct sLimMlmResetReq +{ + tSirMacAddr macAddr; + tANI_U8 performCleanup; + tANI_U8 sessionId; +} tLimMlmResetReq, *tpLimMlmResetReq; + +typedef struct sLimMlmResetCnf +{ + tSirMacAddr macAddr; + tSirResultCodes resultCode; + tANI_U8 sessionId; +} tLimMlmResetCnf, *tpLimMlmResetCnf; + + +typedef struct sLimMlmLinkTestStopReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; +} tLimMlmLinkTestStopReq, *tpLimMlmLinkTestStopReq; + + +// +// Block ACK related MLME data structures +// + +typedef struct sLimMlmAddBAReq +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // ADDBA failure timeout in TU's + // Greater than or equal to 1 + tANI_U16 addBAFailureTimeout; + + // BA Starting Sequence Number + tANI_U16 baSSN; + + tANI_U8 sessionId; + +} tLimMlmAddBAReq, *tpLimMlmAddBAReq; + +typedef struct sLimMlmAddBACnf +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA status code + tSirMacStatusCodes addBAResultCode; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // ADDBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + tANI_U8 sessionId; + + +} tLimMlmAddBACnf, *tpLimMlmAddBACnf; + +typedef struct sLimMlmAddBAInd +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + +} tLimMlmAddBAInd, *tpLimMlmAddBAInd; + +typedef struct sLimMlmAddBARsp +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA status code + tSirMacStatusCodes addBAResultCode; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + //reserved for alignment + tANI_U8 rsvd[2]; + + /* PE session id*/ + tANI_U8 sessionId; + + } tLimMlmAddBARsp, *tpLimMlmAddBARsp; + +// +// NOTE - Overloading DELBA IND and DELBA CNF +// to use the same data structure as DELBA REQ +// as the parameters do not vary too much. +// +typedef struct sLimMlmDelBAReq +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // DELBA requested for TID + tANI_U8 baTID; + + // DELBA reason code + tSirMacReasonCodes delBAReasonCode; + + tANI_U8 sessionId; + +} tLimMlmDelBAReq, *tpLimMlmDelBAReq, tLimMlmDelBAInd, *tpLimMlmDelBAInd, tLimMlmDelBACnf, *tpLimMlmDelBACnf; + +// Function templates + +tANI_BOOLEAN limProcessSmeReqMessages(tpAniSirGlobal, tpSirMsgQ); +void limProcessMlmReqMessages(tpAniSirGlobal, tpSirMsgQ); +void limProcessMlmRspMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *); +void limProcessLmmMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *); +void limProcessSmeDelBssRsp( tpAniSirGlobal , tANI_U32,tpPESession); + +void limGetRandomBssid(tpAniSirGlobal pMac ,tANI_U8 *data); + +// Function to handle HT and HT IE CFG parameter intializations +void handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessionEntry); + +// Function to handle CFG parameter updates +void limHandleCFGparamUpdate(tpAniSirGlobal, tANI_U32); + +void limHandleParamUpdate(tpAniSirGlobal pMac, eUpdateIEsType cfgId); + +// Function to apply CFG parameters before join/reassoc/start BSS +void limApplyConfiguration(tpAniSirGlobal,tpPESession); + +void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry); + + +// Function to Initialize MLM state machine on STA +void limInitMlm(tpAniSirGlobal); + +// Function to cleanup MLM state machine +void limCleanupMlm(tpAniSirGlobal); + +// Function to cleanup LMM state machine +void limCleanupLmm(tpAniSirGlobal); + +// Management frame handling functions +void limProcessBeaconFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessBeaconFrameNoSession(tpAniSirGlobal, tANI_U8 *); +void limProcessProbeReqFrame(tpAniSirGlobal, tANI_U8 *, tpPESession); +void limProcessProbeRspFrame(tpAniSirGlobal, tANI_U8 *, tpPESession); +void limProcessProbeRspFrameNoSession(tpAniSirGlobal, tANI_U8 *); +void limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal, tANI_U8 *,tpPESession); + + +// Process Auth frame when we have a session in progress. +void limProcessAuthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *, void *body); +#endif + +void limProcessAssocReqFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8, tpPESession); +void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + + +void limProcessAssocRspFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8,tpPESession); +void limProcessDisassocFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessDeauthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessActionFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxMetaInfo); + +void limPopulateP2pMacHeader(tpAniSirGlobal, tANI_U8*); +tSirRetStatus limPopulateMacHeader(tpAniSirGlobal, tANI_U8*, tANI_U8, tANI_U8, tSirMacAddr,tSirMacAddr); +tSirRetStatus limSendProbeReqMgmtFrame(tpAniSirGlobal, tSirMacSSid *, tSirMacAddr, tANI_U8, tSirMacAddr, tANI_U32, tANI_U32, tANI_U8 *); +void limSendProbeRspMgmtFrame(tpAniSirGlobal, tSirMacAddr, tpAniSSID, short, tANI_U8, tpPESession, tANI_U8); +void limSendAuthMgmtFrame(tpAniSirGlobal, tSirMacAuthFrameBody *, tSirMacAddr, tANI_U8,tpPESession); +void limSendAssocReqMgmtFrame(tpAniSirGlobal, tLimMlmAssocReq *,tpPESession); +void limSendReassocReqMgmtFrame(tpAniSirGlobal, tLimMlmReassocReq *,tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +void limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry); +#endif +void limSendDeltsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peer, + tANI_U8 wmmTspecPresent, tSirMacTSInfo *pTsinfo, + tSirMacTspecIE *pTspecIe, tpPESession psessionEntry); +void limSendAddtsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tSirAddtsReqInfo *addts,tpPESession); +void limSendAddtsRspActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tANI_U16 statusCode, tSirAddtsReqInfo *addts, tSirMacScheduleIE *pSchedule,tpPESession); + +void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr, tANI_U8, tpDphHashNode pSta,tpPESession); + +void limSendNullDataFrame(tpAniSirGlobal, tpDphHashNode); +void limSendDisassocMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck); +void limSendDeauthMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck); + +void limContinueChannelScan(tpAniSirGlobal); +tSirResultCodes limMlmAddBss(tpAniSirGlobal, tLimMlmStartReq *,tpPESession psessionEntry); + +tSirRetStatus limSendChannelSwitchMgmtFrame(tpAniSirGlobal, tSirMacAddr, tANI_U8, tANI_U8, tANI_U8, tpPESession); + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limSendVHTOpmodeNotificationFrame(tpAniSirGlobal pMac,tSirMacAddr peer,tANI_U8 nMode, tpPESession psessionEntry ); +tSirRetStatus limSendVHTChannelSwitchMgmtFrame(tpAniSirGlobal pMac,tSirMacAddr peer,tANI_U8 nChanWidth, tANI_U8 nNewChannel, tANI_U8 ncbMode, tpPESession psessionEntry ); +#endif + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendNeighborReportRequestFrame(tpAniSirGlobal, tpSirMacNeighborReportReq, tSirMacAddr, tpPESession); +tSirRetStatus limSendLinkReportActionFrame(tpAniSirGlobal, tpSirMacLinkReport, tSirMacAddr, tpPESession ); +tSirRetStatus limSendRadioMeasureReportActionFrame(tpAniSirGlobal, tANI_U8, tANI_U8, tpSirMacRadioMeasureReport, tSirMacAddr, tpPESession); +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void limProcessIappFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +#endif + +#ifdef FEATURE_WLAN_TDLS +void limInitTdlsData(tpAniSirGlobal, tpPESession); +tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcesSmeTdlsLinkEstablishReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +void limSendSmeTDLSDeleteAllPeerInd(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tANI_U32 txCompleteStatus); +tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry); +eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, tpPESession); +tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen); +#endif + +// Algorithms & Link Monitoring related functions +tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal); +void limTriggerBackgroundScan(tpAniSirGlobal); +void limAbortBackgroundScan(tpAniSirGlobal); + +/// Function that handles heartbeat failure +void limHandleHeartBeatFailure(tpAniSirGlobal,tpPESession); + +/// Function that triggers link tear down with AP upon HB failure +void limTearDownLinkWithAp(tpAniSirGlobal,tANI_U8, tSirMacReasonCodes); + + +/// Function that sends keep alive message to peer(s) +void limSendKeepAliveToPeer(tpAniSirGlobal); + +/// Function that processes Max retries interrupt from TFP +void limHandleMaxRetriesInterrupt(tANI_U32); + +/// Function that processes messages deferred during Learn mode +void limProcessDeferredMessageQueue(tpAniSirGlobal); + +/// Function that defers the messages received +tANI_U32 limDeferMsg(tpAniSirGlobal, tSirMsgQ *); + +/// Function that sets system into scan mode +void limSetScanMode(tpAniSirGlobal pMac); + +/// Function that Switches the Channel and sets the CB Mode +void limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId); + +/// Function that completes channel scan +void limCompleteMlmScan(tpAniSirGlobal, tSirResultCodes); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/// Funtion that sets system into meas mode for oem data req +void limSetOemDataReqMode(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data); +#endif + +#ifdef ANI_SUPPORT_11H +/// Function that sends Measurement Report action frame +tSirRetStatus limSendMeasReportFrame(tpAniSirGlobal, tpSirMacMeasReqActionFrame, + tSirMacAddr, tpPESession psessionEntry); + +/// Function that sends TPC Report action frame +tSirRetStatus limSendTpcReportFrame(tpAniSirGlobal, tpSirMacTpcReqActionFrame, tSirMacAddr, + tpPESession psessionEntry); +#endif + +/// Function that sends TPC Request action frame +void limSendTpcRequestFrame(tpAniSirGlobal, tSirMacAddr, tpPESession psessionEntry); + +// Function(s) to handle responses received from HAL +void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQt,tpPESession psessionEntry); +void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession); +void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); +void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry); +void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); +void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); + + + +#ifdef GEN4_SCAN +// Function to process WDA_INIT_SCAN_RSP message +void limProcessInitScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_START_SCAN_RSP message +void limProcessStartScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_END_SCAN_RSP message +void limProcessEndScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_FINISH_SCAN_RSP message +void limProcessFinishScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_SWITCH_CHANNEL_RSP message +void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void * ); + +void limSendHalInitScanReq( tpAniSirGlobal, tLimLimHalScanState, tSirLinkTrafficCheck); +void limSendHalStartScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState); +void limSendHalEndScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState); +void limSendHalFinishScanReq( tpAniSirGlobal, tLimLimHalScanState); + +void limContinuePostChannelScan(tpAniSirGlobal pMac); +void limCovertChannelScanType(tpAniSirGlobal pMac,tANI_U8 channelNum, tANI_BOOLEAN passiveToActive); +void limSetDFSChannelList(tpAniSirGlobal pMac,tANI_U8 channelNum, tSirDFSChannelList *dfsChannelList); +void limContinueChannelLearn( tpAniSirGlobal ); +//WLAN_SUSPEND_LINK Related +tANI_U8 limIsLinkSuspended(tpAniSirGlobal pMac); +void limSuspendLink(tpAniSirGlobal, tSirLinkTrafficCheck, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*); +void limResumeLink(tpAniSirGlobal, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*); +//end WLAN_SUSPEND_LINK Related +#endif // GEN4_SCAN + +tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac, + tpLimMlmAddBAReq pMlmAddBAReq,tpPESession); + +tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac, + tpLimMlmAddBARsp pMlmAddBARsp,tpPESession); + +tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac, + tpLimMlmDelBAReq pMlmDelBAReq ,tpPESession psessionEntry); + +void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); + +void limProcessLearnIntervalTimeout(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_11W +//11w send SA query request action frame +tSirRetStatus limSendSaQueryRequestFrame( tpAniSirGlobal pMac, tANI_U8 *transId, + tSirMacAddr peer, tpPESession psessionEntry ); +//11w SA query request action frame handler +tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, + tANI_U8 *transId, tSirMacAddr peer,tpPESession psessionEntry); +#endif + +// Inline functions + +/** + * limPostSmeMessage() + * + *FUNCTION: + * This function is called by limProcessMlmMessages(). In this + * function MLM sub-module invokes MLM ind/cnf primitives. + * + *LOGIC: + * Initially MLM makes an SME function call to invoke MLM ind/cnf + * primitive. In future this can be enhanced to 'post' messages to SME. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +static inline void +limPostSmeMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + msg.type = (tANI_U16)msgType; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + if (msgType > eWNI_SME_MSG_TYPES_BEGIN) + limProcessSmeReqMessages(pMac, &msg); + else + limProcessMlmRspMessages(pMac, msgType, pMsgBuf); +} /*** end limPostSmeMessage() ***/ + +/** + * limPostMlmMessage() + * + *FUNCTION: + * This function is called by limProcessSmeMessages(). In this + * function SME invokes MLME primitives. + * + *PARAMS: + * + *LOGIC: + * Initially SME makes an MLM function call to invoke MLM primitive. + * In future this can be enhanced to 'post' messages to MLM. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +static inline void +limPostMlmMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + + tSirMsgQ msg; + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + msg.type = (tANI_U16) msgType; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + limProcessMlmReqMessages(pMac, &msg); +} /*** end limPostMlmMessage() ***/ + + + +/** + * limGetCurrentScanChannel() + * + *FUNCTION: + * This function is called in various places to get current channel + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return Channel number + */ +static inline tANI_U8 +limGetCurrentScanChannel(tpAniSirGlobal pMac) +{ + tANI_U8 *pChanNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber; + + return (*(pChanNum + pMac->lim.gLimCurrentScanChannelId)); +} /*** end limGetCurrentScanChannel() ***/ + + + +/** + * limGetIElenFromBssDescription() + * + *FUNCTION: + * This function is called in various places to get IE length + * from tSirBssDescription structure + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBssDescr + * @return Total IE length + */ + +static inline tANI_U16 +limGetIElenFromBssDescription(tpSirBssDescription pBssDescr) +{ + if (!pBssDescr) + return 0; + + return ((tANI_U16) (pBssDescr->length + sizeof(tANI_U16) + + sizeof(tANI_U32) - sizeof(tSirBssDescription))); +} /*** end limGetIElenFromBssDescription() ***/ + +/** + * limSendBeaconInd() + * + *FUNCTION: + * This function is called to send the beacon indication + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: +*/ + +void +limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry); + +void +limSendVdevRestart(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 sessionId); + +void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr, tANI_U8 *uuid_e, eWPSPBCOverlap *overlap, tpPESession psessionEntry); +void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry); + + +tSirRetStatus +limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf); + +#define LIM_WPS_OVERLAP_TIMER_MS 10000 + +void +limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data); +void +limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data); + +void +limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel, + CHANGE_CHANNEL_CALLBACK callback, tANI_U32 *cbdata, tpPESession psessionEntry); + +void limSendSmeMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, + tANI_U32 rxChan, tpPESession psessionEntry, + tANI_S8 rxRssi); +void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac); +void limProcessInsertSingleShotNOATimeout(tpAniSirGlobal pMac); +void limConvertActiveChannelToPassiveChannel(tpAniSirGlobal pMac); +void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void limAbortRemainOnChan(tpAniSirGlobal pMac, tANI_U8 sessionId); +tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf); +void limProcessRegdDefdSmeReqAfterNOAStart(tpAniSirGlobal pMac); + +void limProcessDisassocAckTimeout(tpAniSirGlobal pMac); +void limProcessDeauthAckTimeout(tpAniSirGlobal pMac); +eHalStatus limSendDisassocCnf(tpAniSirGlobal pMac); +eHalStatus limSendDeauthCnf(tpAniSirGlobal pMac); +eHalStatus limDisassocTxCompleteCnf(tpAniSirGlobal pMac, + tANI_U32 txCompleteSuccess); +eHalStatus limDeauthTxCompleteCnf(tpAniSirGlobal pMac, + tANI_U32 txCompleteSuccess); + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct sSetLinkCbackParams +{ + void * cbackDataPtr; +} tSetLinkCbackParams; +#endif + +void limProcessRxScanEvent(tpAniSirGlobal mac, void *buf); + +int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg); +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +#endif /* __LIM_TYPES_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c new file mode 100644 index 0000000000000..f7e49c403b381 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.c @@ -0,0 +1,8202 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limUtils.cc contains the utility functions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "schApi.h" +#include "limUtils.h" +#include "limTypes.h" +#include "limSecurityUtils.h" +#include "limPropExtsUtils.h" +#include "limSendMessages.h" +#include "limSerDesUtils.h" +#include "limAdmitControl.h" +#include "limStaHashApi.h" +#include "dot11f.h" +#include "dot11fdefs.h" +#include "wmmApsd.h" +#include "limTrace.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +#include "limIbssPeerMgmt.h" +#include "limSessionUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFTDefs.h" +#endif +#include "limSession.h" +#include "vos_nvitem.h" + +#include "pmmApi.h" +#ifdef WLAN_FEATURE_11W +#include "wniCfgAp.h" +#endif + +/* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET + * and limTriggerBackgroundScanDuringQuietBss() returned failure. In this case, we will stop data + * traffic instead of going into scan. The recover function limProcessQuietBssTimeout() needs to have + * this information. */ +static tAniBool glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE; + +/* 11A Channel list to decode RX BD channel information */ +static const tANI_U8 abChannel[]= {36,40,44,48,52,56,60,64,100,104,108,112,116, + 120,124,128,132,136,140,149,153,157,161,165 +#ifdef FEATURE_WLAN_CH144 + ,144 +#endif +}; +#define abChannelSize (sizeof(abChannel)/ \ + sizeof(abChannel[0])) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static const tANI_U8 aUnsortedChannelList[]= {52,56,60,64,100,104,108,112,116, + 120,124,128,132,136,140,36,40,44,48,149,153,157,161,165 +#ifdef FEATURE_WLAN_CH144 + ,144 +#endif +}; +#define aUnsortedChannelListSize (sizeof(aUnsortedChannelList)/ \ + sizeof(aUnsortedChannelList[0])) +#endif + +#define SUCCESS 1 + +#define MAX_BA_WINDOW_SIZE_FOR_CISCO 25 + +/** ------------------------------------------------------------- +\fn limAssignDialogueToken +\brief Assigns dialogue token. +\param tpAniSirGlobal pMac +\return tpDialogueToken - dialogueToken data structure. + -------------------------------------------------------------*/ + +tpDialogueToken +limAssignDialogueToken(tpAniSirGlobal pMac) +{ + static tANI_U8 token; + tpDialogueToken pCurrNode; + pCurrNode = vos_mem_malloc(sizeof(tDialogueToken)); + if ( NULL == pCurrNode ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed"));) + return NULL; + } + + vos_mem_set((void *) pCurrNode, sizeof(tDialogueToken), 0); + //first node in the list is being added. + if(NULL == pMac->lim.pDialogueTokenHead) + { + pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenTail = pCurrNode; + } + else + { + pMac->lim.pDialogueTokenTail->next = pCurrNode; + pMac->lim.pDialogueTokenTail = pCurrNode; + } + //assocId and tid of the node will be filled in by caller. + pCurrNode->next = NULL; + pCurrNode->token = token++; + + /* Dialog token should be a non-zero value */ + if (0 == pCurrNode->token) + pCurrNode->token = token; + + PELOG4(limLog(pMac, LOG4, FL("token assigned = %d"), pCurrNode->token);) + return pCurrNode; +} + +/** ------------------------------------------------------------- +\fn limSearchAndDeleteDialogueToken +\brief search dialogue token in the list and deletes it if found. returns failure if not found. +\param tpAniSirGlobal pMac +\param tANI_U8 token +\param tANI_U16 assocId +\param tANI_U16 tid +\return eSirRetStatus - status of the search + -------------------------------------------------------------*/ + + +tSirRetStatus +limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid) +{ + tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead; + tpDialogueToken pPrevNode = pMac->lim.pDialogueTokenHead; + + //if the list is empty + if(NULL == pCurrNode) + return eSIR_FAILURE; + + // if the matching node is the first node. + if(pCurrNode && + (assocId == pCurrNode->assocId) && + (tid == pCurrNode->tid)) + { + pMac->lim.pDialogueTokenHead = pCurrNode->next; + //there was only one node in the list. So tail pointer also needs to be adjusted. + if(NULL == pMac->lim.pDialogueTokenHead) + pMac->lim.pDialogueTokenTail = NULL; + vos_mem_free(pCurrNode); + pMac->lim.pDialogueTokenHead = NULL; + return eSIR_SUCCESS; + } + + //first node did not match. so move to the next one. + pCurrNode = pCurrNode->next; + while(NULL != pCurrNode ) + { + if(token == pCurrNode->token) + { + break; + } + + pPrevNode = pCurrNode; + pCurrNode = pCurrNode->next; + } + + if(pCurrNode && + (assocId == pCurrNode->assocId) && + (tid == pCurrNode->tid)) + { + pPrevNode->next = pCurrNode->next; + //if the node being deleted is the last one then we also need to move the tail pointer to the prevNode. + if(NULL == pCurrNode->next) + pMac->lim.pDialogueTokenTail = pPrevNode; + vos_mem_free(pCurrNode); + pMac->lim.pDialogueTokenHead = NULL; + return eSIR_SUCCESS; + } + + PELOGW(limLog(pMac, LOGW, FL("LIM does not have matching dialogue token node"));) + return eSIR_FAILURE; + +} + + +/** ------------------------------------------------------------- +\fn limDeleteDialogueTokenList +\brief deletes the complete lim dialogue token linked list. +\param tpAniSirGlobal pMac +\return None + -------------------------------------------------------------*/ +void +limDeleteDialogueTokenList(tpAniSirGlobal pMac) +{ + tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead; + + while(NULL != pMac->lim.pDialogueTokenHead) + { + pCurrNode = pMac->lim.pDialogueTokenHead; + pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenHead->next; + vos_mem_free(pCurrNode); + pCurrNode = NULL; + } + pMac->lim.pDialogueTokenTail = NULL; +} + +void +limGetBssidFromBD(tpAniSirGlobal pMac, tANI_U8 * pRxPacketInfo, tANI_U8 *bssId, tANI_U32 *pIgnore) +{ + tpSirMacDataHdr3a pMh = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo); + *pIgnore = 0; + + if (pMh->fc.toDS == 1 && pMh->fc.fromDS == 0) + { + vos_mem_copy( bssId, pMh->addr1, 6); + *pIgnore = 1; + } + else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 1) + { + vos_mem_copy ( bssId, pMh->addr2, 6); + *pIgnore = 1; + } + else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 0) + { + vos_mem_copy( bssId, pMh->addr3, 6); + *pIgnore = 0; + } + else + { + vos_mem_copy( bssId, pMh->addr1, 6); + *pIgnore = 1; + } +} + + +char * +limDot11ReasonStr(tANI_U16 reasonCode) +{ + switch (reasonCode) + { + case 0: return " "; + CASE_RETURN_STRING(eSIR_MAC_UNSPEC_FAILURE_REASON); + CASE_RETURN_STRING(eSIR_MAC_PREV_AUTH_NOT_VALID_REASON); + CASE_RETURN_STRING(eSIR_MAC_DEAUTH_LEAVING_BSS_REASON); + CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON); + CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON); + CASE_RETURN_STRING(eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON); + CASE_RETURN_STRING(eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON); + CASE_RETURN_STRING(eSIR_MAC_DISASSOC_LEAVING_BSS_REASON); + CASE_RETURN_STRING(eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON); + CASE_RETURN_STRING(eSIR_MAC_PWR_CAPABILITY_BAD_REASON); + CASE_RETURN_STRING(eSIR_MAC_SPRTD_CHANNELS_BAD_REASON); + + CASE_RETURN_STRING(eSIR_MAC_INVALID_IE_REASON); + CASE_RETURN_STRING(eSIR_MAC_MIC_FAILURE_REASON); + CASE_RETURN_STRING(eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON); + CASE_RETURN_STRING(eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON); + CASE_RETURN_STRING(eSIR_MAC_RSN_IE_MISMATCH_REASON); + + CASE_RETURN_STRING(eSIR_MAC_INVALID_MC_CIPHER_REASON); + CASE_RETURN_STRING(eSIR_MAC_INVALID_UC_CIPHER_REASON); + CASE_RETURN_STRING(eSIR_MAC_INVALID_AKMP_REASON); + CASE_RETURN_STRING(eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON); + CASE_RETURN_STRING(eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON); + CASE_RETURN_STRING(eSIR_MAC_1X_AUTH_FAILURE_REASON); + CASE_RETURN_STRING(eSIR_MAC_CIPHER_SUITE_REJECTED_REASON); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE); + CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); +#endif + /* Reserved 27 - 30*/ +#ifdef WLAN_FEATURE_11W + CASE_RETURN_STRING(eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION); +#endif + CASE_RETURN_STRING(eSIR_MAC_QOS_UNSPECIFIED_REASON); + CASE_RETURN_STRING(eSIR_MAC_QAP_NO_BANDWIDTH_REASON); + CASE_RETURN_STRING(eSIR_MAC_XS_UNACKED_FRAMES_REASON); + CASE_RETURN_STRING(eSIR_MAC_BAD_TXOP_USE_REASON); + CASE_RETURN_STRING(eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON); + CASE_RETURN_STRING(eSIR_MAC_PEER_REJECT_MECHANISIM_REASON); + CASE_RETURN_STRING(eSIR_MAC_MECHANISM_NOT_SETUP_REASON); + + CASE_RETURN_STRING(eSIR_MAC_PEER_TIMEDOUT_REASON); + CASE_RETURN_STRING(eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON); + CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON); + /* Reserved 47 - 65535 */ + default: + return "Unknown"; + } +} + + +char * +limMlmStateStr(tLimMlmStates state) +{ + switch (state) + { + case eLIM_MLM_OFFLINE_STATE: + return "eLIM_MLM_OFFLINE_STATE"; + case eLIM_MLM_IDLE_STATE: + return "eLIM_MLM_IDLE_STATE"; + case eLIM_MLM_WT_PROBE_RESP_STATE: + return "eLIM_MLM_WT_PROBE_RESP_STATE"; + case eLIM_MLM_PASSIVE_SCAN_STATE: + return "eLIM_MLM_PASSIVE_SCAN_STATE"; + case eLIM_MLM_WT_JOIN_BEACON_STATE: + return "eLIM_MLM_WT_JOIN_BEACON_STATE"; + case eLIM_MLM_JOINED_STATE: + return "eLIM_MLM_JOINED_STATE"; + case eLIM_MLM_BSS_STARTED_STATE: + return "eLIM_MLM_BSS_STARTED_STATE"; + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + return "eLIM_MLM_WT_AUTH_FRAME2_STATE"; + case eLIM_MLM_WT_AUTH_FRAME3_STATE: + return "eLIM_MLM_WT_AUTH_FRAME3_STATE"; + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + return "eLIM_MLM_WT_AUTH_FRAME4_STATE"; + case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE: + return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE"; + case eLIM_MLM_AUTHENTICATED_STATE: + return "eLIM_MLM_AUTHENTICATED_STATE"; + case eLIM_MLM_WT_ASSOC_RSP_STATE: + return "eLIM_MLM_WT_ASSOC_RSP_STATE"; + case eLIM_MLM_WT_REASSOC_RSP_STATE: + return "eLIM_MLM_WT_REASSOC_RSP_STATE"; + case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: + return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE"; + case eLIM_MLM_WT_DEL_STA_RSP_STATE: + return "eLIM_MLM_WT_DEL_STA_RSP_STATE"; + case eLIM_MLM_WT_DEL_BSS_RSP_STATE: + return "eLIM_MLM_WT_DEL_BSS_RSP_STATE"; + case eLIM_MLM_WT_ADD_STA_RSP_STATE: + return "eLIM_MLM_WT_ADD_STA_RSP_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_STATE"; + case eLIM_MLM_REASSOCIATED_STATE: + return "eLIM_MLM_REASSOCIATED_STATE"; + case eLIM_MLM_LINK_ESTABLISHED_STATE: + return "eLIM_MLM_LINK_ESTABLISHED_STATE"; + case eLIM_MLM_WT_ASSOC_CNF_STATE: + return "eLIM_MLM_WT_ASSOC_CNF_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE"; + case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE: + return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE"; + case eLIM_MLM_WT_SET_BSS_KEY_STATE: + return "eLIM_MLM_WT_SET_BSS_KEY_STATE"; + case eLIM_MLM_WT_SET_STA_KEY_STATE: + return "eLIM_MLM_WT_SET_STA_KEY_STATE"; + default: + return "INVALID MLM state"; + } +} + +void +limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state) +{ + limLog(pMac, logLevel, limMlmStateStr(state)); +} + +char * +limSmeStateStr(tLimSmeStates state) +{ +#ifdef FIXME_GEN6 + switch (state) + { + case eLIM_SME_OFFLINE_STATE: + return "eLIM_SME_OFFLINE_STATE"; + case eLIM_SME_IDLE_STATE: + return "eLIM_SME_IDLE_STATE"; + case eLIM_SME_SUSPEND_STATE: + return "eLIM_SME_SUSPEND_STATE"; + case eLIM_SME_WT_SCAN_STATE: + return "eLIM_SME_WT_SCAN_STATE"; + case eLIM_SME_WT_JOIN_STATE: + return "eLIM_SME_WT_JOIN_STATE"; + case eLIM_SME_WT_AUTH_STATE: + return "eLIM_SME_WT_AUTH_STATE"; + case eLIM_SME_WT_ASSOC_STATE: + return "eLIM_SME_WT_ASSOC_STATE"; + case eLIM_SME_WT_REASSOC_STATE: + return "eLIM_SME_WT_REASSOC_STATE"; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: + return "eLIM_SME_WT_REASSOC_LINK_FAIL_STATE"; + case eLIM_SME_JOIN_FAILURE_STATE: + return "eLIM_SME_JOIN_FAILURE_STATE"; + case eLIM_SME_ASSOCIATED_STATE: + return "eLIM_SME_ASSOCIATED_STATE"; + case eLIM_SME_REASSOCIATED_STATE: + return "eLIM_SME_REASSOCIATED_STATE"; + case eLIM_SME_LINK_EST_STATE: + return "eLIM_SME_LINK_EST_STATE"; + case eLIM_SME_LINK_EST_WT_SCAN_STATE: + return "eLIM_SME_LINK_EST_WT_SCAN_STATE"; + case eLIM_SME_WT_PRE_AUTH_STATE: + return "eLIM_SME_WT_PRE_AUTH_STATE"; + case eLIM_SME_WT_DISASSOC_STATE: + return "eLIM_SME_WT_DISASSOC_STATE"; + case eLIM_SME_WT_DEAUTH_STATE: + return "eLIM_SME_WT_DEAUTH_STATE"; + case eLIM_SME_WT_START_BSS_STATE: + return "eLIM_SME_WT_START_BSS_STATE"; + case eLIM_SME_WT_STOP_BSS_STATE: + return "eLIM_SME_WT_STOP_BSS_STATE"; + case eLIM_SME_NORMAL_STATE: + return "eLIM_SME_NORMAL_STATE"; + case eLIM_SME_CHANNEL_SCAN_STATE: + return "eLIM_SME_CHANNEL_SCAN_STATE"; + case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: + return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE"; + default: + return "INVALID SME state"; + } +#endif +return ""; +} + + +char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode) +{ +#ifdef FIXME_GEN6 + + switch(dot11Mode) + { + case WNI_CFG_DOT11_MODE_ALL: + return "ALL"; + case WNI_CFG_DOT11_MODE_11A: + return "11A"; + case WNI_CFG_DOT11_MODE_11B: + return "11B"; + case WNI_CFG_DOT11_MODE_11G: + return "11G"; + case WNI_CFG_DOT11_MODE_11N: + return "11N"; + case WNI_CFG_DOT11_MODE_POLARIS: + return "Polaris"; + case WNI_CFG_DOT11_MODE_TITAN: + return "Titan"; + case WNI_CFG_DOT11_MODE_TAURUS: + return "Taurus"; + default: + return "Invalid Dot11 Mode"; + } +#endif +return ""; +} + + +char* limStaOpRateModeStr(tStaRateMode opRateMode) +{ +#ifdef FIXME_GEN6 + + switch(opRateMode) + { + case eSTA_TAURUS: + return "Taurus"; + case eSTA_11a: + return "11A"; + case eSTA_11b: + return "11B"; + case eSTA_11bg: + return "11G"; + case eSTA_11n: + return "11N"; + case eSTA_POLARIS: + return "Polaris"; + case eSTA_TITAN: + return "Titan"; + default: + return "Invalid Dot11 Mode"; + } +#endif +return ""; +} + +char* limBssTypeStr(tSirBssType bssType) +{ + switch(bssType) + { + case eSIR_INFRASTRUCTURE_MODE: + return "eSIR_INFRASTRUCTURE_MODE"; + case eSIR_IBSS_MODE: + return "eSIR_IBSS_MODE"; + case eSIR_BTAMP_STA_MODE: + return "eSIR_BTAMP_STA_MODE"; + case eSIR_BTAMP_AP_MODE: + return "eSIR_BTAMP_AP_MODE"; + case eSIR_AUTO_MODE: + return "eSIR_AUTO_MODE"; + default: + return "Invalid BSS Type"; + } +} + +void +limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state) +{ + limLog(pMac, logLevel, limSmeStateStr(state)); +} + +char *limMsgStr(tANI_U32 msgType) +{ +#ifdef FIXME_GEN6 + switch (msgType) + { + case eWNI_SME_START_REQ: + return "eWNI_SME_START_REQ"; + case eWNI_SME_START_RSP: + return "eWNI_SME_START_RSP"; + case eWNI_SME_SYS_READY_IND: + return "eWNI_SME_SYS_READY_IND"; + case eWNI_SME_SCAN_REQ: + return "eWNI_SME_SCAN_REQ"; +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + return "eWNI_SME_OEM_DATA_REQ"; + case eWNI_SME_OEM_DATA_RSP: + return "eWNI_SME_OEM_DATA_RSP"; +#endif + case eWNI_SME_SCAN_RSP: + return "eWNI_SME_SCAN_RSP"; + case eWNI_SME_JOIN_REQ: + return "eWNI_SME_JOIN_REQ"; + case eWNI_SME_JOIN_RSP: + return "eWNI_SME_JOIN_RSP"; + case eWNI_SME_SETCONTEXT_REQ: + return "eWNI_SME_SETCONTEXT_REQ"; + case eWNI_SME_SETCONTEXT_RSP: + return "eWNI_SME_SETCONTEXT_RSP"; + case eWNI_SME_REASSOC_REQ: + return "eWNI_SME_REASSOC_REQ"; + case eWNI_SME_REASSOC_RSP: + return "eWNI_SME_REASSOC_RSP"; + case eWNI_SME_DISASSOC_REQ: + return "eWNI_SME_DISASSOC_REQ"; + case eWNI_SME_DISASSOC_RSP: + return "eWNI_SME_DISASSOC_RSP"; + case eWNI_SME_DISASSOC_IND: + return "eWNI_SME_DISASSOC_IND"; + case eWNI_SME_DISASSOC_CNF: + return "eWNI_SME_DISASSOC_CNF"; + case eWNI_SME_DEAUTH_REQ: + return "eWNI_SME_DEAUTH_REQ"; + case eWNI_SME_DEAUTH_RSP: + return "eWNI_SME_DEAUTH_RSP"; + case eWNI_SME_DEAUTH_IND: + return "eWNI_SME_DEAUTH_IND"; + case eWNI_SME_WM_STATUS_CHANGE_NTF: + return "eWNI_SME_WM_STATUS_CHANGE_NTF"; + case eWNI_SME_START_BSS_REQ: + return "eWNI_SME_START_BSS_REQ"; + case eWNI_SME_START_BSS_RSP: + return "eWNI_SME_START_BSS_RSP"; + case eWNI_SME_AUTH_IND: + return "eWNI_SME_AUTH_IND"; + case eWNI_SME_ASSOC_IND: + return "eWNI_SME_ASSOC_IND"; + case eWNI_SME_ASSOC_CNF: + return "eWNI_SME_ASSOC_CNF"; + case eWNI_SME_REASSOC_IND: + return "eWNI_SME_REASSOC_IND"; + case eWNI_SME_REASSOC_CNF: + return "eWNI_SME_REASSOC_CNF"; + case eWNI_SME_SWITCH_CHL_REQ: + return "eWNI_SME_SWITCH_CHL_REQ"; + case eWNI_SME_SWITCH_CHL_RSP: + return "eWNI_SME_SWITCH_CHL_RSP"; + case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ: + return "eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ"; + case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ: + return "eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ"; + case eWNI_SME_STOP_BSS_REQ: + return "eWNI_SME_STOP_BSS_REQ"; + case eWNI_SME_STOP_BSS_RSP: + return "eWNI_SME_STOP_BSS_RSP"; + case eWNI_SME_NEIGHBOR_BSS_IND: + return "eWNI_SME_NEIGHBOR_BSS_IND"; + case eWNI_SME_MEASUREMENT_REQ: + return "eWNI_SME_MEASUREMENT_REQ"; + case eWNI_SME_MEASUREMENT_RSP: + return "eWNI_SME_MEASUREMENT_RSP"; + case eWNI_SME_MEASUREMENT_IND: + return "eWNI_SME_MEASUREMENT_IND"; + case eWNI_SME_SET_WDS_INFO_REQ: + return "eWNI_SME_SET_WDS_INFO_REQ"; + case eWNI_SME_SET_WDS_INFO_RSP: + return "eWNI_SME_SET_WDS_INFO_RSP"; + case eWNI_SME_WDS_INFO_IND: + return "eWNI_SME_WDS_INFO_IND"; + case eWNI_SME_DEAUTH_CNF: + return "eWNI_SME_DEAUTH_CNF"; + case eWNI_SME_MIC_FAILURE_IND: + return "eWNI_SME_MIC_FAILURE_IND"; + case eWNI_SME_ADDTS_REQ: + return "eWNI_SME_ADDTS_REQ"; + case eWNI_SME_ADDTS_RSP: + return "eWNI_SME_ADDTS_RSP"; + case eWNI_SME_ADDTS_CNF: + return "eWNI_SME_ADDTS_CNF"; + case eWNI_SME_ADDTS_IND: + return "eWNI_SME_ADDTS_IND"; + case eWNI_SME_DELTS_REQ: + return "eWNI_SME_DELTS_REQ"; + case eWNI_SME_DELTS_RSP: + return "eWNI_SME_DELTS_RSP"; + case eWNI_SME_DELTS_IND: + return "eWNI_SME_DELTS_IND"; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: + return "eWNI_SME_GET_ROAM_RSSI_REQ"; + case eWNI_SME_GET_ROAM_RSSI_RSP: + return "eWNI_SME_GET_ROAM_RSSI_RSP"; +#endif + + case WDA_SUSPEND_ACTIVITY_RSP: + return "WDA_SUSPEND_ACTIVITY_RSP"; + case SIR_LIM_RETRY_INTERRUPT_MSG: + return "SIR_LIM_RETRY_INTERRUPT_MSG"; + case SIR_BB_XPORT_MGMT_MSG: + return "SIR_BB_XPORT_MGMT_MSG"; + case SIR_LIM_INV_KEY_INTERRUPT_MSG: + return "SIR_LIM_INV_KEY_INTERRUPT_MSG"; + case SIR_LIM_KEY_ID_INTERRUPT_MSG: + return "SIR_LIM_KEY_ID_INTERRUPT_MSG"; + case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG: + return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG"; + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + return "SIR_LIM_MIN_CHANNEL_TIMEOUT"; + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + return "SIR_LIM_MAX_CHANNEL_TIMEOUT"; + case SIR_LIM_JOIN_FAIL_TIMEOUT: + return "SIR_LIM_JOIN_FAIL_TIMEOUT"; + case SIR_LIM_AUTH_FAIL_TIMEOUT: + return "SIR_LIM_AUTH_FAIL_TIMEOUT"; + case SIR_LIM_AUTH_RSP_TIMEOUT: + return "SIR_LIM_AUTH_RSP_TIMEOUT"; + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + return "SIR_LIM_ASSOC_FAIL_TIMEOUT"; + case SIR_LIM_REASSOC_FAIL_TIMEOUT: + return "SIR_LIM_REASSOC_FAIL_TIMEOUT"; + case SIR_LIM_HEART_BEAT_TIMEOUT: + return "SIR_LIM_HEART_BEAT_TIMEOUT"; + case SIR_LIM_ADDTS_RSP_TIMEOUT: + return "SIR_LIM_ADDTS_RSP_TIMEOUT"; + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + return "SIR_LIM_CHANNEL_SCAN_TIMEOUT"; + case SIR_LIM_LINK_TEST_DURATION_TIMEOUT: + return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT"; + case SIR_LIM_HASH_MISS_THRES_TIMEOUT: + return "SIR_LIM_HASH_MISS_THRES_TIMEOUT"; + case SIR_LIM_KEEPALIVE_TIMEOUT: + return "SIR_LIM_KEEPALIVE_TIMEOUT"; + case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: + return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT"; + case SIR_LIM_CNF_WAIT_TIMEOUT: + return "SIR_LIM_CNF_WAIT_TIMEOUT"; + case SIR_LIM_RADAR_DETECT_IND: + return "SIR_LIM_RADAR_DETECT_IND"; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: + return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT"; +#endif + + case SIR_HAL_APP_SETUP_NTF: + return "SIR_HAL_APP_SETUP_NTF"; + case SIR_HAL_INITIAL_CAL_FAILED_NTF: + return "SIR_HAL_INITIAL_CAL_FAILED_NTF"; + case SIR_HAL_NIC_OPER_NTF: + return "SIR_HAL_NIC_OPER_NTF"; + case SIR_HAL_INIT_START_REQ: + return "SIR_HAL_INIT_START_REQ"; + case SIR_HAL_SHUTDOWN_REQ: + return "SIR_HAL_SHUTDOWN_REQ"; + case SIR_HAL_SHUTDOWN_CNF: + return "SIR_HAL_SHUTDOWN_CNF"; + case SIR_HAL_RESET_REQ: + return "SIR_HAL_RESET_REQ"; + case SIR_HAL_RESET_CNF: + return "SIR_HAL_RESET_CNF"; + case SIR_WRITE_TO_TD: + return "SIR_WRITE_TO_TD"; + + case WNI_CFG_PARAM_UPDATE_IND: + return "WNI_CFG_PARAM_UPDATE_IND"; + case WNI_CFG_DNLD_REQ: + return "WNI_CFG_DNLD_REQ"; + case WNI_CFG_DNLD_CNF: + return "WNI_CFG_DNLD_CNF"; + case WNI_CFG_GET_RSP: + return "WNI_CFG_GET_RSP"; + case WNI_CFG_SET_CNF: + return "WNI_CFG_SET_CNF"; + case WNI_CFG_GET_ATTRIB_RSP: + return "WNI_CFG_GET_ATTRIB_RSP"; + case WNI_CFG_ADD_GRP_ADDR_CNF: + return "WNI_CFG_ADD_GRP_ADDR_CNF"; + case WNI_CFG_DEL_GRP_ADDR_CNF: + return "WNI_CFG_DEL_GRP_ADDR_CNF"; + case ANI_CFG_GET_RADIO_STAT_RSP: + return "ANI_CFG_GET_RADIO_STAT_RSP"; + case ANI_CFG_GET_PER_STA_STAT_RSP: + return "ANI_CFG_GET_PER_STA_STAT_RSP"; + case ANI_CFG_GET_AGG_STA_STAT_RSP: + return "ANI_CFG_GET_AGG_STA_STAT_RSP"; + case ANI_CFG_CLEAR_STAT_RSP: + return "ANI_CFG_CLEAR_STAT_RSP"; + case WNI_CFG_DNLD_RSP: + return "WNI_CFG_DNLD_RSP"; + case WNI_CFG_GET_REQ: + return "WNI_CFG_GET_REQ"; + case WNI_CFG_SET_REQ: + return "WNI_CFG_SET_REQ"; + case WNI_CFG_SET_REQ_NO_RSP: + return "WNI_CFG_SET_REQ_NO_RSP"; + case eWNI_PMC_ENTER_IMPS_RSP: + return "eWNI_PMC_ENTER_IMPS_RSP"; + case eWNI_PMC_EXIT_IMPS_RSP: + return "eWNI_PMC_EXIT_IMPS_RSP"; + case eWNI_PMC_ENTER_BMPS_RSP: + return "eWNI_PMC_ENTER_BMPS_RSP"; + case eWNI_PMC_EXIT_BMPS_RSP: + return "eWNI_PMC_EXIT_BMPS_RSP"; + case eWNI_PMC_EXIT_BMPS_IND: + return "eWNI_PMC_EXIT_BMPS_IND"; + case eWNI_SME_SET_BCN_FILTER_REQ: + return "eWNI_SME_SET_BCN_FILTER_REQ"; +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: + return "eWNI_SME_GET_TSM_STATS_REQ"; + case eWNI_SME_GET_TSM_STATS_RSP: + return "eWNI_SME_GET_TSM_STATS_RSP"; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_CSA_OFFLOAD_EVENT: + return "eWNI_SME_CSA_OFFLOAD_EVENT"; + default: + return "INVALID SME message"; + } +#endif +return ""; +} + + + +char *limResultCodeStr(tSirResultCodes resultCode) +{ + switch (resultCode) + { + case eSIR_SME_SUCCESS: + return "eSIR_SME_SUCCESS"; + case eSIR_EOF_SOF_EXCEPTION: + return "eSIR_EOF_SOF_EXCEPTION"; + case eSIR_BMU_EXCEPTION: + return "eSIR_BMU_EXCEPTION"; + case eSIR_LOW_PDU_EXCEPTION: + return "eSIR_LOW_PDU_EXCEPTION"; + case eSIR_USER_TRIG_RESET: + return"eSIR_USER_TRIG_RESET"; + case eSIR_LOGP_EXCEPTION: + return "eSIR_LOGP_EXCEPTION"; + case eSIR_CP_EXCEPTION: + return "eSIR_CP_EXCEPTION"; + case eSIR_STOP_BSS: + return "eSIR_STOP_BSS"; + case eSIR_AHB_HANG_EXCEPTION: + return "eSIR_AHB_HANG_EXCEPTION"; + case eSIR_DPU_EXCEPTION: + return "eSIR_DPU_EXCEPTION"; + case eSIR_RXP_EXCEPTION: + return "eSIR_RXP_EXCEPTION"; + case eSIR_MCPU_EXCEPTION: + return "eSIR_MCPU_EXCEPTION"; + case eSIR_MCU_EXCEPTION: + return "eSIR_MCU_EXCEPTION"; + case eSIR_MTU_EXCEPTION: + return "eSIR_MTU_EXCEPTION"; + case eSIR_MIF_EXCEPTION: + return "eSIR_MIF_EXCEPTION"; + case eSIR_FW_EXCEPTION: + return "eSIR_FW_EXCEPTION"; + case eSIR_MAILBOX_SANITY_CHK_FAILED: + return "eSIR_MAILBOX_SANITY_CHK_FAILED"; + case eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF: + return "eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF"; + case eSIR_CFB_FLAG_STUCK_EXCEPTION: + return "eSIR_CFB_FLAG_STUCK_EXCEPTION"; + case eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS: + return "eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS"; + case eSIR_SME_INVALID_PARAMETERS: + return "eSIR_SME_INVALID_PARAMETERS"; + case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE: + return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE"; + case eSIR_SME_RESOURCES_UNAVAILABLE: + return "eSIR_SME_RESOURCES_UNAVAILABLE"; + case eSIR_SME_SCAN_FAILED: + return "eSIR_SME_SCAN_FAILED"; + case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED: + return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED"; + case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE: + return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE"; + case eSIR_SME_REFUSED: + return "eSIR_SME_REFUSED"; + case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE: + return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE"; + case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE: + return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE"; + case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE: + return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE"; + case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE: + return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE"; + case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED: + return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED"; + case eSIR_SME_AUTH_REFUSED: + return "eSIR_SME_AUTH_REFUSED"; + case eSIR_SME_INVALID_WEP_DEFAULT_KEY: + return "eSIR_SME_INVALID_WEP_DEFAULT_KEY"; + case eSIR_SME_ASSOC_REFUSED: + return "eSIR_SME_ASSOC_REFUSED"; + case eSIR_SME_REASSOC_REFUSED: + return "eSIR_SME_REASSOC_REFUSED"; + case eSIR_SME_STA_NOT_AUTHENTICATED: + return "eSIR_SME_STA_NOT_AUTHENTICATED"; + case eSIR_SME_STA_NOT_ASSOCIATED: + return "eSIR_SME_STA_NOT_ASSOCIATED"; + case eSIR_SME_STA_DISASSOCIATED: + return "eSIR_SME_STA_DISASSOCIATED"; + case eSIR_SME_ALREADY_JOINED_A_BSS: + return "eSIR_SME_ALREADY_JOINED_A_BSS"; + case eSIR_ULA_COMPLETED: + return "eSIR_ULA_COMPLETED"; + case eSIR_ULA_FAILURE: + return "eSIR_ULA_FAILURE"; + case eSIR_SME_LINK_ESTABLISHED: + return "eSIR_SME_LINK_ESTABLISHED"; + case eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS: + return "eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS"; + case eSIR_SME_UNABLE_TO_PERFORM_DFS: + return "eSIR_SME_UNABLE_TO_PERFORM_DFS"; + case eSIR_SME_DFS_FAILED: + return "eSIR_SME_DFS_FAILED"; + case eSIR_SME_TRANSFER_STA: + return "eSIR_SME_TRANSFER_STA"; + case eSIR_SME_INVALID_LINK_TEST_PARAMETERS: + return "eSIR_SME_INVALID_LINK_TEST_PARAMETERS"; + case eSIR_SME_LINK_TEST_MAX_EXCEEDED: + return "eSIR_SME_LINK_TEST_MAX_EXCEEDED"; + case eSIR_SME_UNSUPPORTED_RATE: + return "eSIR_SME_UNSUPPORTED_RATE"; + case eSIR_SME_LINK_TEST_TIMEOUT: + return "eSIR_SME_LINK_TEST_TIMEOUT"; + case eSIR_SME_LINK_TEST_COMPLETE: + return "eSIR_SME_LINK_TEST_COMPLETE"; + case eSIR_SME_LINK_TEST_INVALID_STATE: + return "eSIR_SME_LINK_TEST_INVALID_STATE"; + case eSIR_SME_LINK_TEST_INVALID_ADDRESS: + return "eSIR_SME_LINK_TEST_INVALID_ADDRESS"; + case eSIR_SME_POLARIS_RESET: + return "eSIR_SME_POLARIS_RESET"; + case eSIR_SME_SETCONTEXT_FAILED: + return "eSIR_SME_SETCONTEXT_FAILED"; + case eSIR_SME_BSS_RESTART: + return "eSIR_SME_BSS_RESTART"; + case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW: + return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW"; + case eSIR_SME_INVALID_ASSOC_RSP_RXED: + return "eSIR_SME_INVALID_ASSOC_RSP_RXED"; + case eSIR_SME_MIC_COUNTER_MEASURES: + return "eSIR_SME_MIC_COUNTER_MEASURES"; + case eSIR_SME_ADDTS_RSP_TIMEOUT: + return "eSIR_SME_ADDTS_RSP_TIMEOUT"; + case eSIR_SME_RECEIVED: + return "eSIR_SME_RECEIVED"; + case eSIR_SME_CHANNEL_SWITCH_FAIL: + return "eSIR_SME_CHANNEL_SWITCH_FAIL"; +#ifdef GEN4_SCAN + case eSIR_SME_CHANNEL_SWITCH_DISABLED: + return "eSIR_SME_CHANNEL_SWITCH_DISABLED"; + case eSIR_SME_HAL_SCAN_INIT_FAILED: + return "eSIR_SME_HAL_SCAN_INIT_FAILED"; + case eSIR_SME_HAL_SCAN_START_FAILED: + return "eSIR_SME_HAL_SCAN_START_FAILED"; + case eSIR_SME_HAL_SCAN_END_FAILED: + return "eSIR_SME_HAL_SCAN_END_FAILED"; + case eSIR_SME_HAL_SCAN_FINISH_FAILED: + return "eSIR_SME_HAL_SCAN_FINISH_FAILED"; + case eSIR_SME_HAL_SEND_MESSAGE_FAIL: + return "eSIR_SME_HAL_SEND_MESSAGE_FAIL"; +#else // GEN4_SCAN + case eSIR_SME_CHANNEL_SWITCH_DISABLED: + return "eSIR_SME_CHANNEL_SWITCH_DISABLED"; + case eSIR_SME_HAL_SEND_MESSAGE_FAIL: + return "eSIR_SME_HAL_SEND_MESSAGE_FAIL"; +#endif // GEN4_SCAN + + default: + return "INVALID resultCode"; + } +} + +void +limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType) +{ + limLog(pMac, logLevel, limMsgStr(msgType)); +} + +void +limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg) +{ + if (logLevel <= pMac->utils.gLogDbgLevel[SIR_LIM_MODULE_ID - LOG_FIRST_MODULE_ID]) + { + switch (msg->type) + { + case SIR_BB_XPORT_MGMT_MSG: + limPrintMsgName(pMac, logLevel,msg->type); + break; + default: + limPrintMsgName(pMac, logLevel,msg->type); + break; + } + } +} + +/** + * limInitMlm() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to + * initialize MLM state machine on STA + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limInitMlm(tpAniSirGlobal pMac) +{ + tANI_U32 retVal; + + pMac->lim.gLimTimersCreated = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + /// Initialize scan result hash table + limReInitScanResults(pMac); //sep26th review + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /// Initialize lfr scan result hash table + // Could there be a problem in multisession with SAP/P2P GO, when in the + // middle of FW bg scan, SAP started; Again that could be a problem even on + // infra + SAP/P2P GO too - TBD + limReInitLfrScanResults(pMac); +#endif + + /// Initialize number of pre-auth contexts + pMac->lim.gLimNumPreAuthContexts = 0; + + /// Initialize MAC based Authentication STA list + limInitPreAuthList(pMac); + + // Create timers used by LIM + retVal = limCreateTimers(pMac); + if(retVal == TX_SUCCESS) + { + pMac->lim.gLimTimersCreated = 1; + } + else + { + limLog(pMac, LOGP, FL(" limCreateTimers Failed to create lim timers ")); + } +} /*** end limInitMlm() ***/ + + + +/** + * limCleanupMlm() + * + *FUNCTION: + * This function is called to cleanup any resources + * allocated by the MLM state machine. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * It is assumed that BSS is already informed that we're leaving it + * before this function is called. + * + * @param pMac Pointer to Global MAC structure + * @param None + * @return None + */ +void +limCleanupMlm(tpAniSirGlobal pMac) +{ + tANI_U32 n; + tLimPreAuthNode *pAuthNode; +#ifdef WLAN_FEATURE_11W + tANI_U32 bss_entry, sta_entry; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry = NULL; +#endif + + if (pMac->lim.gLimTimersCreated == 1) + { + // Deactivate and delete MIN/MAX channel timers. + tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + + + // Deactivate and delete channel switch timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer); + + + // Deactivate and delete addts response timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer); + + // Deactivate and delete Join failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer); + + // Deactivate and delete Periodic Join Probe Request timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + + // Deactivate and delete Association failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer); + + // Deactivate and delete Reassociation failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer); + + // Deactivate and delete Authentication failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer); + + // Deactivate and delete Heartbeat timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimHeartBeatTimer); + + // Deactivate and delete wait-for-probe-after-Heartbeat timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + + // Deactivate and delete Quiet timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer); + + // Deactivate and delete Quiet BSS timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer); + + // Deactivate and delete LIM background scan timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimBackgroundScanTimer); + + + // Deactivate and delete cnf wait timer + for (n = 0; n < (pMac->lim.maxStation + 1); n++) + { + tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]); + tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]); + } + + // Deactivate and delete keepalive timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimKeepaliveTimer); + + pAuthNode = pMac->lim.gLimPreAuthTimerTable.pTable; + + //Deactivate any Authentication response timers + limDeletePreAuthList(pMac); + + for (n = 0; n < pMac->lim.gLimPreAuthTimerTable.numEntry; n++,pAuthNode++) + { + // Delete any Authentication response + // timers, which might have been started. + tx_timer_delete(&pAuthNode->timer); + } + + // Deactivate and delete Hash Miss throttle timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimPreAuthClnupTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPreAuthClnupTimer); + +#ifdef WLAN_FEATURE_VOWIFI_11R + // Deactivate and delete FT Preauth response timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); +#endif + + // Deactivate and delete remain on channel timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimRemainOnChannelTimer); + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + // Deactivate and delete TSM + tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer); +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + + tx_timer_deactivate(&pMac->lim.limTimers.gLimDisassocAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + + pMac->lim.gLimTimersCreated = 0; + } + +#ifdef WLAN_FEATURE_11W + /* + * When SSR is triggered, we need to loop through + * each STA associated per BSSId and deactivate/delete + * the pmfSaQueryTimer for it + */ + if (vos_is_logp_in_progress(VOS_MODULE_ID_PE, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("SSR is detected, proceed to clean up pmfSaQueryTimer")); + for (bss_entry = 0; bss_entry < pMac->lim.maxBssId; bss_entry++) + { + if (pMac->lim.gpSession[bss_entry].valid) + { + for (sta_entry = 1; sta_entry < pMac->lim.gLimAssocStaLimit; + sta_entry++) + { + psessionEntry = &pMac->lim.gpSession[bss_entry]; + pStaDs = dphGetHashEntry(pMac, sta_entry, + &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) + { + continue; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("Deleting pmfSaQueryTimer for staid[%d]"), + pStaDs->staIndex) ; + tx_timer_deactivate(&pStaDs->pmfSaQueryTimer); + tx_timer_delete(&pStaDs->pmfSaQueryTimer); + } + } + } + } +#endif + + /// Cleanup cached scan list + limReInitScanResults(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /// Cleanup cached scan list + limReInitLfrScanResults(pMac); +#endif + +} /*** end limCleanupMlm() ***/ + + + +/** + * limCleanupLmm() + * + *FUNCTION: + * This function is called to cleanup any resources + * allocated by LMM sub-module. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +void +limCleanupLmm(tpAniSirGlobal pMac) +{ +} /*** end limCleanupLmm() ***/ + + + +/** + * limIsAddrBC() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed MAC address is a broadcast or not + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr Indicates MAC address that need to be determined + * whether it is Broadcast address or not + * + * @return true if passed address is Broadcast address else false + */ + +tANI_U8 +limIsAddrBC(tSirMacAddr macAddr) +{ + int i; + for (i = 0; i < 6; i++) + { + if ((macAddr[i] & 0xFF) != 0xFF) + return false; + } + + return true; +} /****** end limIsAddrBC() ******/ + + + +/** + * limIsGroupAddr() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed MAC address is a group address or not + * + *LOGIC: + * If least significant bit of first octet of the MAC address is + * set to 1, it is a Group address. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr Indicates MAC address that need to be determined + * whether it is Group address or not + * + * @return true if passed address is Group address else false + */ + +tANI_U8 +limIsGroupAddr(tSirMacAddr macAddr) +{ + if ((macAddr[0] & 0x01) == 0x01) + return true; + else + return false; +} /****** end limIsGroupAddr() ******/ + +/** + * limPostMsgApiNoWait() + * + *FUNCTION: + * This function is called from other thread while posting a + * message to LIM message Queue gSirLimMsgQ with NO_WAIT option + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMsg - Pointer to the Global MAC structure + * @param pMsg - Pointer to the message structure + * @return None + */ + +tANI_U32 +limPostMsgApiNoWait(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + limProcessMessages(pMac, pMsg); + return TX_SUCCESS; +} /*** end limPostMsgApiNoWait() ***/ + + + +/** + * limPrintMacAddr() + * + *FUNCTION: + * This function is called to print passed MAC address + * in : format. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * @param macAddr - MacAddr to be printed + * @param logLevel - Loglevel to be used + * + * @return None. + */ + +void +limPrintMacAddr(tpAniSirGlobal pMac, tSirMacAddr macAddr, tANI_U8 logLevel) +{ + limLog(pMac, logLevel, + FL(MAC_ADDRESS_STR), MAC_ADDR_ARRAY(macAddr)); +} /****** end limPrintMacAddr() ******/ + + + + + + +/* + * limResetDeferredMsgQ() + * + *FUNCTION: + * This function resets the deferred message queue parameters. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + *RETURNS: + * None + */ + +void limResetDeferredMsgQ(tpAniSirGlobal pMac) +{ + pMac->lim.gLimDeferredMsgQ.size = + pMac->lim.gLimDeferredMsgQ.write = + pMac->lim.gLimDeferredMsgQ.read = 0; + +} + + +#define LIM_DEFERRED_Q_CHECK_THRESHOLD (MAX_DEFERRED_QUEUE_LEN/2) +#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2) + +/* + * limWriteDeferredMsgQ() + * + *FUNCTION: + * This function queues up a deferred message for later processing on the + * STA side. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * @param limMsg - a LIM message + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + *RETURNS: + * None + */ + +tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + PELOG1(limLog(pMac, LOG1, + FL("** Queue a deferred message (size %d, write %d) - type 0x%x **"), + pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.write, + limMsg->type);) + + /* + ** check if the deferred message queue is full + **/ + if (pMac->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN) + { + if(!(pMac->lim.deferredMsgCnt & 0xF)) + { + PELOGE(limLog(pMac, LOGE, FL("Deferred Message Queue is full. Msg:%d Messages Failed:%d"), limMsg->type, ++pMac->lim.deferredMsgCnt);) + } + else + { + pMac->lim.deferredMsgCnt++; + } + return TX_QUEUE_FULL; + } + + /* + ** In the application, there should not be more than 1 message get + ** queued up. If happens, flags a warning. In the future, this can + ** happen. + **/ + if (pMac->lim.gLimDeferredMsgQ.size > 0) + { + PELOGW(limLog(pMac, LOGW, FL("%d Deferred messages (type 0x%x, scan %d, global sme %d, global mlme %d, addts %d)"), + pMac->lim.gLimDeferredMsgQ.size, limMsg->type, + limIsSystemInScanState(pMac), + pMac->lim.gLimSmeState, pMac->lim.gLimMlmState, + pMac->lim.gLimAddtsSent);) + } + + /* + ** To prevent the deferred Q is full of management frames, only give them certain space + **/ + if( SIR_BB_XPORT_MGMT_MSG == limMsg->type ) + { + if( LIM_DEFERRED_Q_CHECK_THRESHOLD < pMac->lim.gLimDeferredMsgQ.size ) + { + tANI_U16 idx, count = 0; + for(idx = 0; idx < pMac->lim.gLimDeferredMsgQ.size; idx++) + { + if( SIR_BB_XPORT_MGMT_MSG == pMac->lim.gLimDeferredMsgQ.deferredQueue[idx].type ) + { + count++; + } + } + if( LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count ) + { + //We reach the quota for management frames, drop this one + PELOGW(limLog(pMac, LOGW, FL("Cannot deferred. Msg: %d Too many (count=%d) already"), limMsg->type, count);) + //Return error, caller knows what to do + return TX_QUEUE_FULL; + } + } + } + + ++pMac->lim.gLimDeferredMsgQ.size; + + /* reset the count here since we are able to defer the message */ + if(pMac->lim.deferredMsgCnt != 0) + { + pMac->lim.deferredMsgCnt = 0; + } + + /* + ** if the write pointer hits the end of the queue, rewind it + **/ + if (pMac->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN) + pMac->lim.gLimDeferredMsgQ.write = 0; + + /* + ** save the message to the queue and advanced the write pointer + **/ + vos_mem_copy( (tANI_U8 *)&pMac->lim.gLimDeferredMsgQ.deferredQueue[ + pMac->lim.gLimDeferredMsgQ.write++], + (tANI_U8 *)limMsg, + sizeof(tSirMsgQ)); + return TX_SUCCESS; + +} + +/* + * limReadDeferredMsgQ() + * + *FUNCTION: + * This function dequeues a deferred message for processing on the + * STA side. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * + *RETURNS: + * Returns the message at the head of the deferred message queue + */ + +tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac) +{ + tSirMsgQ *msg; + + /* + ** check any messages left. If no, return + **/ + if (pMac->lim.gLimDeferredMsgQ.size <= 0) + return NULL; + + /* + ** decrement the queue size + **/ + pMac->lim.gLimDeferredMsgQ.size--; + + /* + ** retrieve the message from the head of the queue + **/ + msg = &pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.gLimDeferredMsgQ.read]; + + /* + ** advance the read pointer + **/ + pMac->lim.gLimDeferredMsgQ.read++; + + /* + ** if the read pointer hits the end of the queue, rewind it + **/ + if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN) + pMac->lim.gLimDeferredMsgQ.read = 0; + + PELOG1(limLog(pMac, LOG1, + FL("** DeQueue a deferred message (size %d read %d) - type 0x%x **"), + pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.read, + msg->type);) + + PELOG1(limLog(pMac, LOG1, FL("DQ msg -- scan %d, global sme %d, global mlme %d, addts %d"), + limIsSystemInScanState(pMac), + pMac->lim.gLimSmeState, pMac->lim.gLimMlmState, + pMac->lim.gLimAddtsSent);) + + return(msg); +} + +tSirRetStatus +limSysProcessMmhMsgApi(tpAniSirGlobal pMac, + tSirMsgQ *pMsg, + tANI_U8 qType) +{ +// FIXME + SysProcessMmhMsg(pMac, pMsg); + return eSIR_SUCCESS; +} + +char *limFrameStr(tANI_U32 type, tANI_U32 subType) +{ +#ifdef FIXME_GEN6 + + if (type == SIR_MAC_MGMT_FRAME) + { + switch (subType) + { + case SIR_MAC_MGMT_ASSOC_REQ: + return "MAC_MGMT_ASSOC_REQ"; + case SIR_MAC_MGMT_ASSOC_RSP: + return "MAC_MGMT_ASSOC_RSP"; + case SIR_MAC_MGMT_REASSOC_REQ: + return "MAC_MGMT_REASSOC_REQ"; + case SIR_MAC_MGMT_REASSOC_RSP: + return "MAC_MGMT_REASSOC_RSP"; + case SIR_MAC_MGMT_PROBE_REQ: + return "MAC_MGMT_PROBE_REQ"; + case SIR_MAC_MGMT_PROBE_RSP: + return "MAC_MGMT_PROBE_RSP"; + case SIR_MAC_MGMT_BEACON: + return "MAC_MGMT_BEACON"; + case SIR_MAC_MGMT_ATIM: + return "MAC_MGMT_ATIM"; + case SIR_MAC_MGMT_DISASSOC: + return "MAC_MGMT_DISASSOC"; + case SIR_MAC_MGMT_AUTH: + return "MAC_MGMT_AUTH"; + case SIR_MAC_MGMT_DEAUTH: + return "MAC_MGMT_DEAUTH"; + case SIR_MAC_MGMT_ACTION: + return "MAC_MGMT_ACTION"; + case SIR_MAC_MGMT_RESERVED15: + return "MAC_MGMT_RESERVED15"; + default: + return "Unknown MGMT Frame"; + } + } + + else if (type == SIR_MAC_CTRL_FRAME) + { + switch (subType) + { + case SIR_MAC_CTRL_RR: + return "MAC_CTRL_RR"; + case SIR_MAC_CTRL_BAR: + return "MAC_CTRL_BAR"; + case SIR_MAC_CTRL_BA: + return "MAC_CTRL_BA"; + case SIR_MAC_CTRL_PS_POLL: + return "MAC_CTRL_PS_POLL"; + case SIR_MAC_CTRL_RTS: + return "MAC_CTRL_RTS"; + case SIR_MAC_CTRL_CTS: + return "MAC_CTRL_CTS"; + case SIR_MAC_CTRL_ACK: + return "MAC_CTRL_ACK"; + case SIR_MAC_CTRL_CF_END: + return "MAC_CTRL_CF_END"; + case SIR_MAC_CTRL_CF_END_ACK: + return "MAC_CTRL_CF_END_ACK"; + default: + return "Unknown CTRL Frame"; + } + } + + else if (type == SIR_MAC_DATA_FRAME) + { + switch (subType) + { + case SIR_MAC_DATA_DATA: + return "MAC_DATA_DATA"; + case SIR_MAC_DATA_DATA_ACK: + return "MAC_DATA_DATA_ACK"; + case SIR_MAC_DATA_DATA_POLL: + return "MAC_DATA_DATA_POLL"; + case SIR_MAC_DATA_DATA_ACK_POLL: + return "MAC_DATA_DATA_ACK_POLL"; + case SIR_MAC_DATA_NULL: + return "MAC_DATA_NULL"; + case SIR_MAC_DATA_NULL_ACK: + return "MAC_DATA_NULL_ACK"; + case SIR_MAC_DATA_NULL_POLL: + return "MAC_DATA_NULL_POLL"; + case SIR_MAC_DATA_NULL_ACK_POLL: + return "MAC_DATA_NULL_ACK_POLL"; + case SIR_MAC_DATA_QOS_DATA: + return "MAC_DATA_QOS_DATA"; + case SIR_MAC_DATA_QOS_DATA_ACK: + return "MAC_DATA_QOS_DATA_ACK"; + case SIR_MAC_DATA_QOS_DATA_POLL: + return "MAC_DATA_QOS_DATA_POLL"; + case SIR_MAC_DATA_QOS_DATA_ACK_POLL: + return "MAC_DATA_QOS_DATA_ACK_POLL"; + case SIR_MAC_DATA_QOS_NULL: + return "MAC_DATA_QOS_NULL"; + case SIR_MAC_DATA_QOS_NULL_ACK: + return "MAC_DATA_QOS_NULL_ACK"; + case SIR_MAC_DATA_QOS_NULL_POLL: + return "MAC_DATA_QOS_NULL_POLL"; + case SIR_MAC_DATA_QOS_NULL_ACK_POLL: + return "MAC_DATA_QOS_NULL_ACK_POLL"; + default: + return "Unknown Data Frame"; + } + } + else + return "Unknown"; +#endif +return ""; +} + +void limHandleUpdateOlbcCache(tpAniSirGlobal pMac) +{ + int i; + static int enable; + tUpdateBeaconParams beaconParams; + + tpPESession psessionEntry = limIsApSessionActive(pMac); + + if (psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE, FL(" Session not found"));) + return; + } + + vos_mem_set( ( tANI_U8* )&beaconParams, sizeof( tUpdateBeaconParams), 0); + beaconParams.bssIdx = psessionEntry->bssIdx; + + beaconParams.paramChangeBitmap = 0; + /* + ** This is doing a 2 pass check. The first pass is to invalidate + ** all the cache entries. The second pass is to decide whether to + ** disable protection. + **/ + if (!enable) + { + + PELOG2(limLog(pMac, LOG2, FL("Resetting OLBC cache"));) + psessionEntry->gLimOlbcParams.numSta = 0; + psessionEntry->gLimOverlap11gParams.numSta = 0; + psessionEntry->gLimOverlapHt20Params.numSta = 0; + psessionEntry->gLimNonGfParams.numSta = 0; + psessionEntry->gLimLsigTxopParams.numSta = 0; + + for (i=0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++) + pMac->lim.protStaOverlapCache[i].active = false; + + enable = 1; + } + else + { + + if (!psessionEntry->gLimOlbcParams.numSta) + { + if (psessionEntry->gLimOlbcParams.protectionEnabled) + { + if (!psessionEntry->gLim11bParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11B STA detected"));) + limEnable11gProtection(pMac, false, true, &beaconParams, psessionEntry); + } + } + } + + if (!psessionEntry->gLimOverlap11gParams.numSta) + { + if (psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + if (!psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11G STA detected"));) + limEnableHtProtectionFrom11g(pMac, false, true, &beaconParams,psessionEntry); + } + } + } + + if (!psessionEntry->gLimOverlapHt20Params.numSta) + { + if (psessionEntry->gLimOverlapHt20Params.protectionEnabled) + { + if (!psessionEntry->gLimHt20Params.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no HT20 STA detected"));) + limEnable11gProtection(pMac, false, true, &beaconParams,psessionEntry); + } + } + } + + enable = 0; + } + + if ((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + + // Start OLBC timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("tx_timer_activate failed")); + } +} + +/** + * limIsNullSsid() + * + *FUNCTION: + * This function checks if Ssid supplied is Null SSID + * + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param tSirMacSSid * + * + * + * @return true if SSID is Null SSID else false + */ + +tANI_U8 +limIsNullSsid( tSirMacSSid *pSsid ) +{ + tANI_U8 fNullSsid = false; + tANI_U32 SsidLength; + tANI_U8 *pSsidStr; + + do + { + if ( 0 == pSsid->length ) + { + fNullSsid = true; + break; + } + +#define ASCII_SPACE_CHARACTER 0x20 + /* If the first charactes is space, then check if all characters in + * SSID are spaces to consider it as NULL SSID*/ + if( ASCII_SPACE_CHARACTER == pSsid->ssId[0]) + { + SsidLength = pSsid->length; + pSsidStr = pSsid->ssId; + /* check if all the charactes in SSID are spaces*/ + while ( SsidLength ) + { + if( ASCII_SPACE_CHARACTER != *pSsidStr ) + break; + + pSsidStr++; + SsidLength--; + } + + if( 0 == SsidLength ) + { + fNullSsid = true; + break; + } + } + else + { + /* check if all the charactes in SSID are NULL*/ + SsidLength = pSsid->length; + pSsidStr = pSsid->ssId; + + while ( SsidLength ) + { + if( *pSsidStr ) + break; + + pSsidStr++; + SsidLength--; + } + + if( 0 == SsidLength ) + { + fNullSsid = true; + break; + } + } + } + while( 0 ); + + return fNullSsid; +} /****** end limIsNullSsid() ******/ + + + + +/** ------------------------------------------------------------- +\fn limUpdateProtStaParams +\brief updates protection related counters. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tLimProtStaCacheType protStaCacheType +\param tHalBitVal gfSupported +\param tHalBitVal lsigTxopSupported +\return None + -------------------------------------------------------------*/ +void +limUpdateProtStaParams(tpAniSirGlobal pMac, +tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType, +tHalBitVal gfSupported, tHalBitVal lsigTxopSupported, +tpPESession psessionEntry) +{ + tANI_U32 i; + + PELOG1(limLog(pMac,LOG1, FL("A STA is associated:")); + limLog(pMac,LOG1, FL("Addr : ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + + for (i=0; iprotStaCache[i].active) + { + PELOG1(limLog(pMac, LOG1, FL("Addr: "));) + PELOG1(limPrintMacAddr(pMac, psessionEntry->protStaCache[i].addr, LOG1);) + + if (vos_mem_compare( + psessionEntry->protStaCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + { + PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active."), i);) + return; + } + } + } + + for (i=0; iprotStaCache[i].active) + break; + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache"));) + return; + } + + vos_mem_copy( psessionEntry->protStaCache[i].addr, + peerMacAddr, + sizeof(tSirMacAddr)); + + psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType; + psessionEntry->protStaCache[i].active = true; + if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) + { + psessionEntry->gLim11bParams.numSta++; + limLog(pMac,LOG1, FL("11B, ")); + } + else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) + { + psessionEntry->gLim11gParams.numSta++; + limLog(pMac,LOG1, FL("11G, ")); + } + else if(eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType) + { + psessionEntry->gLimHt20Params.numSta++; + limLog(pMac,LOG1, FL("HT20, ")); + } + + if(!gfSupported) + { + psessionEntry->gLimNonGfParams.numSta++; + limLog(pMac,LOG1, FL("NonGf, ")); + } + if(!lsigTxopSupported) + { + psessionEntry->gLimLsigTxopParams.numSta++; + limLog(pMac,LOG1, FL("!lsigTxopSupported")); + } +}// --------------------------------------------------------------------- + +/** ------------------------------------------------------------- +\fn limDecideApProtection +\brief Decides all the protection related staiton coexistence and also sets +\ short preamble and short slot appropriately. This function will be called +\ when AP is ready to send assocRsp tp the station joining right now. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\return None + -------------------------------------------------------------*/ +void +limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode; + tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; + tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET; + + pBeaconParams->paramChangeBitmap = 0; + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + PELOG1(limLog(pMac, LOG1, FL("pStaDs is NULL"));) + return; + } + limGetRfBand(pMac, &rfBand, psessionEntry); + //if we are in 5 GHZ band + if(SIR_BAND_5_GHZ == rfBand) + { + //We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. + //HT20 case is common between both the bands and handled down as common code. + if(true == psessionEntry->htCapability) + { + //we are 11N and 11A station is joining. + //protection from 11A required. + if(false == pStaDs->mlmStaContext.htCapability) + { + limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry); + return; + } + } + } + else if(SIR_BAND_2_4_GHZ== rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //We are 11G. Check if we need protection from 11b Stations. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && + (false == psessionEntry->htCapability)) + { + + if (pStaDs->erpEnabled== eHAL_CLEAR) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + // enable protection + PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B"));) + limEnable11gProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + } + + //HT station. + if (true == psessionEntry->htCapability) + { + //check if we need protection from 11b station + if ((pStaDs->erpEnabled == eHAL_CLEAR) && + (!pStaDs->mlmStaContext.htCapability)) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + // enable protection + PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B"));) + limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry); + } + //station being joined is non-11b and non-ht ==> 11g device + else if(!pStaDs->mlmStaContext.htCapability) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG; + //enable protection + limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams, psessionEntry); + } + //ERP mode is enabled for the latest station joined + //latest station joined is HT capable + //This case is being handled in common code (commn between both the bands) below. + } + } + + //we are HT and HT station is joining. This code is common for both the bands. + if((true == psessionEntry->htCapability) && + (true == pStaDs->mlmStaContext.htCapability)) + { + if(!pStaDs->htGreenfield) + { + limEnableHTNonGfProtection(pMac, true, false, pBeaconParams, psessionEntry); + gfSupported = eHAL_CLEAR; + } + //Station joining is HT 20Mhz + if(eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20; + limEnableHT20Protection(pMac, true, false, pBeaconParams, psessionEntry); + } + //Station joining does not support LSIG TXOP Protection + if(!pStaDs->htLsigTXOPProtection) + { + limEnableHTLsigTxopProtection(pMac, false, false, pBeaconParams,psessionEntry); + lsigTxopSupported = eHAL_CLEAR; + } + } + + limUpdateProtStaParams(pMac, peerMacAddr, protStaCacheType, + gfSupported, lsigTxopSupported, psessionEntry); + + return; +} + + +/** ------------------------------------------------------------- +\fn limEnableOverlap11gProtection +\brief wrapper function for setting overlap 11g protection. +\param tpAniSirGlobal pMac +\param tpUpdateBeaconParams pBeaconParams +\param tpSirMacMgmtHdr pMh +\return None + -------------------------------------------------------------*/ +void +limEnableOverlap11gProtection(tpAniSirGlobal pMac, +tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry) +{ + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOlbcParams)); + + if (psessionEntry->gLimOlbcParams.numSta && + !psessionEntry->gLimOlbcParams.protectionEnabled) + { + // enable protection + PELOG1(limLog(pMac, LOG1, FL("OLBC happens!!!"));) + limEnable11gProtection(pMac, true, true, pBeaconParams,psessionEntry); + } +} + + +/** ------------------------------------------------------------- +\fn limUpdateShortPreamble +\brief Updates short preamble if needed when a new station joins. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tANI_U32 phyMode; + tANI_U16 i; + + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G) + + { + if (pStaDs->shortPreambleEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac,LOG1,FL("Short Preamble is not enabled in Assoc Req from ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( + psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if (pMac->lim.gLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( + pMac->lim.gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + } + } + + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->gLimNoShortParams.staNoShortCache[i].active) + break; + else + { + if (!pMac->lim.gLimNoShortParams.staNoShortCache[i].active) + break; + } + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "), + i, psessionEntry->gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + else + { + limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "), + i, pMac->lim.gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + + } + + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE){ + vos_mem_copy( psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + psessionEntry->gLimNoShortParams.staNoShortCache[i].active = true; + psessionEntry->gLimNoShortParams.numNonShortPreambleSta++; + }else + { + vos_mem_copy( pMac->lim.gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + pMac->lim.gLimNoShortParams.staNoShortCache[i].active = true; + pMac->lim.gLimNoShortParams.numNonShortPreambleSta++; + } + + + // enable long preamble + PELOG1(limLog(pMac, LOG1, FL("Disabling short preamble"));) + + if (limEnableShortPreamble(pMac, false, pBeaconParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Cannot enable long preamble"));) + } + } +} + +/** ------------------------------------------------------------- +\fn limUpdateShortSlotTime +\brief Updates short slot time if needed when a new station joins. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ + +void +limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tANI_U32 phyMode; + tANI_U32 val; + tANI_U16 i; + + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + /* Only in case of softap in 11g mode, slot time might change depending on the STA being added. In 11a case, it should + * be always 1 and in 11b case, it should be always 0 + */ + if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G) + { + /* Only when the new STA has short slot time disabled, we need to change softap's overall slot time settings + * else the default for softap is always short slot enabled. When the last long slot STA leaves softAP, we take care of + * it in limDecideShortSlot + */ + if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("Short Slot Time is not enabled in Assoc Req from ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare( + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare( + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + } + } + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active) + break; + else + { + if (!pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + break; + } + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "), + i, psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + }else + { + limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "), + i, pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + } + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + vos_mem_copy( psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = true; + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta++; + }else + { + vos_mem_copy( pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = true; + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta++; + } + wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val); + + /* Here we check if we are AP role and short slot enabled (both admin and oper modes) but we have atleast one STA connected with + * only long slot enabled, we need to change our beacon/pb rsp to broadcast short slot disabled + */ + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta && psessionEntry->shortSlotTimeSupported)) + { + // enable long slot time + pBeaconParams->fShortSlotTime = false; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time."));) + psessionEntry->shortSlotTimeSupported = false; + } + else if ( psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta && psessionEntry->shortSlotTimeSupported) + { + // enable long slot time + pBeaconParams->fShortSlotTime = false; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time."));) + psessionEntry->shortSlotTimeSupported = false; + } + } + } + } +} + + +/** ------------------------------------------------------------- +\fn limDecideStaProtectionOnAssoc +\brief Decide protection related settings on Sta while association. +\param tpAniSirGlobal pMac +\param tpSchBeaconStruct pBeaconStruct +\return None + -------------------------------------------------------------*/ +void +limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac, + tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry) +{ + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE; + + limGetRfBand(pMac, &rfBand, psessionEntry); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode)) + { + if(pMac->lim.cfgProtection.fromlla) + psessionEntry->beaconParams.llaCoexist = true; + } + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBeaconStruct->HTInfo.opMode) + { + if(pMac->lim.cfgProtection.ht20) + psessionEntry->beaconParams.ht20Coexist = true; + } + + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + //spec 7.3.2.13 + //UseProtection will be set when nonERP STA is associated. + //NonERPPresent bit will be set when: + //--nonERP Sta is associated OR + //--nonERP Sta exists in overlapping BSS + //when useProtection is not set then protection from nonERP stations is optional. + + //CFG protection from 11b is enabled and + //11B device in the BSS + /* TODO, This is not sessionized */ + if (phyMode != WNI_CFG_PHY_MODE_11B) + { + if (pMac->lim.cfgProtection.fromllb && + pBeaconStruct->erpPresent && + (pBeaconStruct->erpIEInfo.useProtection || + pBeaconStruct->erpIEInfo.nonErpPresent)) + { + psessionEntry->beaconParams.llbCoexist = true; + } + //AP has no 11b station associated. + else + { + psessionEntry->beaconParams.llbCoexist = false; + } + } + //following code block is only for HT station. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + + //Obss Non HT STA present mode + psessionEntry->beaconParams.gHTObssMode = (tANI_U8)htInfo.obssNonHTStaPresent; + + + //CFG protection from 11G is enabled and + //our AP has at least one 11G station associated. + if(pMac->lim.cfgProtection.fromllg && + ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&& + (!psessionEntry->beaconParams.llbCoexist)) + { + if(pMac->lim.cfgProtection.fromllg) + psessionEntry->beaconParams.llgCoexist = true; + } + + //AP has only HT stations associated and at least one station is HT 20 + //disable protection from any non-HT devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) + { + //Disable protection from 11G station. + psessionEntry->beaconParams.llgCoexist = false; + //CFG protection from HT 20 is enabled. + if(pMac->lim.cfgProtection.ht20) + psessionEntry->beaconParams.ht20Coexist = true; + } + //Disable protection from non-HT and HT20 devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_PURE == htInfo.opMode) + { + psessionEntry->beaconParams.llgCoexist = false; + psessionEntry->beaconParams.ht20Coexist = false; + } + + } + } + + //protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + psessionEntry->beaconParams.fRIFSMode = + ( tANI_U8 ) htInfo.rifsMode; + psessionEntry->beaconParams.llnNonGFCoexist = + ( tANI_U8 )htInfo.nonGFDevicesPresent; + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport; + } +} + + +/** ------------------------------------------------------------- +\fn limDecideStaProtection +\brief Decides protection related settings on Sta while processing beacon. +\param tpAniSirGlobal pMac +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limDecideStaProtection(tpAniSirGlobal pMac, + tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE; + + limGetRfBand(pMac, &rfBand, psessionEntry); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + //we are HT capable. + if((true == psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + //we are HT capable, AP's HT OPMode is mixed / overlap legacy ==> need protection from 11A. + if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode)) + { + limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + //we are HT capable, AP's HT OPMode is HT20 ==> disable protection from 11A if enabled. enabled + //protection from HT20 if needed. + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT== pBeaconStruct->HTInfo.opMode) + { + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry); + } + else if(eSIR_HT_OP_MODE_PURE == pBeaconStruct->HTInfo.opMode) + { + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + /* spec 7.3.2.13 + * UseProtection will be set when nonERP STA is associated. + * NonERPPresent bit will be set when: + * --nonERP Sta is associated OR + * --nonERP Sta exists in overlapping BSS + * when useProtection is not set then protection from nonERP stations is optional. + */ + + if (phyMode != WNI_CFG_PHY_MODE_11B) + { + if (pBeaconStruct->erpPresent && + (pBeaconStruct->erpIEInfo.useProtection || + pBeaconStruct->erpIEInfo.nonErpPresent)) + { + limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry); + } + //AP has no 11b station associated. + else + { + //disable protection from 11b station + limEnable11gProtection(pMac, false, false, pBeaconParams, psessionEntry); + } + } + + //following code block is only for HT station. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + //AP has at least one 11G station associated. + if(((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&& + (!psessionEntry->beaconParams.llbCoexist)) + { + limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams,psessionEntry); + + } + + //no HT operating mode change ==> no change in protection settings except for MIXED_MODE/Legacy Mode. + //in Mixed mode/legacy Mode even if there is no change in HT operating mode, there might be change in 11bCoexist + //or 11gCoexist. that is why this check is being done after mixed/legacy mode check. + if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )htInfo.opMode ) + { + pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )htInfo.opMode; + + //AP has only HT stations associated and at least one station is HT 20 + //disable protection from any non-HT devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) + { + //Disable protection from 11G station. + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + + limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry); + } + //Disable protection from non-HT and HT20 devices. + //decision for disabling protection from 11b has already been taken above. + else if(eSIR_HT_OP_MODE_PURE == htInfo.opMode) + { + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + + } + } + } + } + + //following code block is only for HT station. ( 2.4 GHZ as well as 5 GHZ) + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + //Check for changes in protection related factors other than HT operating mode. + //Check for changes in RIFS mode, nonGFDevicesPresent, lsigTXOPProtectionFullSupport. + if ( psessionEntry->beaconParams.fRIFSMode != + ( tANI_U8 ) htInfo.rifsMode ) + { + pBeaconParams->fRIFSMode = + psessionEntry->beaconParams.fRIFSMode = + ( tANI_U8 ) htInfo.rifsMode; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + + if ( psessionEntry->beaconParams.llnNonGFCoexist != + htInfo.nonGFDevicesPresent ) + { + pBeaconParams->llnNonGFCoexist = + psessionEntry->beaconParams.llnNonGFCoexist = + ( tANI_U8 )htInfo.nonGFDevicesPresent; + pBeaconParams->paramChangeBitmap |= + PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + + if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport != + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport ) + { + pBeaconParams->fLsigTXOPProtectionFullSupport = + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport; + pBeaconParams->paramChangeBitmap |= + PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + + // For Station just update the global lim variable, no need to send message to HAL + // Station already taking care of HT OPR Mode=01, meaning AP is seeing legacy + //stations in overlapping BSS. + if ( psessionEntry->beaconParams.gHTObssMode != ( tANI_U8 )htInfo.obssNonHTStaPresent ) + psessionEntry->beaconParams.gHTObssMode = ( tANI_U8 )htInfo.obssNonHTStaPresent ; + + } +} + + +/** + * limProcessChannelSwitchTimeout() + * + *FUNCTION: + * This function is invoked when Channel Switch Timer expires at + * the STA. Now, STA must stop traffic, and then change/disable + * primary or secondary channel. + * + * + *NOTE: + * @param pMac - Pointer to Global MAC structure + * @return None + */ +void limProcessChannelSwitchTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry = NULL; + tANI_U8 channel; // This is received and stored from channelSwitch Action frame + tANI_U8 isSessionPowerActive = false; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + PELOGW(limLog(pMac, LOGW, "Channel switch can be done only in STA role, Current Role = %d", psessionEntry->limSystemRole);) + return; + } + + if(pMac->psOffloadEnabled) + { + isSessionPowerActive = pmmPsOffloadIsActive(pMac, psessionEntry); + } + else + { + isSessionPowerActive = limIsSystemInActiveState(pMac); + } + + channel = psessionEntry->gLimChannelSwitch.primaryChannel; + /* + * This potentially can create issues if the function tries to set + * channel while device is in power-save, hence putting an extra check + * to verify if the device is in power-save or not + */ + if(!isSessionPowerActive) + { + PELOGW(limLog(pMac, LOGW, FL("Device is not in active state, cannot switch channel"));) + return; + } + + // Restore Channel Switch parameters to default + psessionEntry->gLimChannelSwitch.switchTimeoutValue = 0; + + /* Channel-switch timeout has occurred. reset the state */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END; + + /* Check if the AP is switching to a channel that we support. + * Else, just don't bother to switch. Indicate HDD to look for a + * better AP to associate + */ + if(!limIsChannelValidForChannelSwitch(pMac, channel)) + { + /* We need to restore pre-channelSwitch state on the STA */ + if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + return; + } + + /* If the channel-list that AP is asking us to switch is invalid, + * then we cannot switch the channel. Just disassociate from AP. + * We will find a better AP !!! + */ + limTearDownLinkWithAp(pMac, + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId, + eSIR_MAC_UNSPEC_FAILURE_REASON); + return; + } + limCovertChannelScanType(pMac, psessionEntry->currentOperChannel, false); + pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] = 0; + switch(psessionEntry->gLimChannelSwitch.state) + { + case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY: + PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_ONLY "));) + limSwitchPrimaryChannel(pMac, psessionEntry->gLimChannelSwitch.primaryChannel,psessionEntry); + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; + break; + + case eLIM_CHANNEL_SWITCH_SECONDARY_ONLY: + PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_SECONDARY_ONLY "));) + limSwitchPrimarySecondaryChannel(pMac, psessionEntry, + psessionEntry->currentOperChannel, + psessionEntry->gLimChannelSwitch.secondarySubBand); + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; + break; + + case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY: + PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY"));) + limSwitchPrimarySecondaryChannel(pMac, psessionEntry, + psessionEntry->gLimChannelSwitch.primaryChannel, + psessionEntry->gLimChannelSwitch.secondarySubBand); + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; + break; + + case eLIM_CHANNEL_SWITCH_IDLE: + default: + PELOGE(limLog(pMac, LOGE, FL("incorrect state "));) + if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + } + return; /* Please note, this is 'return' and not 'break' */ + } +} + +/** + * limUpdateChannelSwitch() + * + *FUNCTION: + * This function is invoked whenever Station receives + * either 802.11h channel switch IE or airgo proprietary + * channel switch IE. + * + *NOTE: + * @param pMac - Pointer to Global MAC structure + * @return tpSirProbeRespBeacon - Pointer to Beacon/Probe Rsp + * @param psessionentry + */ +void +limUpdateChannelSwitch(struct sAniSirGlobal *pMac, tpSirProbeRespBeacon pBeacon, tpPESession psessionEntry) +{ + + tANI_U16 beaconPeriod; + tChannelSwitchPropIEStruct *pPropChnlSwitch; + tDot11fIEChanSwitchAnn *pChnlSwitch; +#ifdef WLAN_FEATURE_11AC + tDot11fIEWiderBWChanSwitchAnn *pWiderChnlSwitch; +#endif + + beaconPeriod = psessionEntry->beaconParams.beaconInterval; + + /* STA either received proprietary channel switch IE or 802.11h + * standard channel switch IE. + */ + if (pBeacon->propIEinfo.propChannelSwitchPresent) + { + pPropChnlSwitch = &(pBeacon->propIEinfo.channelSwitch); + + /* Add logic to determine which change this is: */ + /* primary, secondary, both. For now assume both. */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.primaryChannel = pPropChnlSwitch->primaryChannel; + psessionEntry->gLimChannelSwitch.secondarySubBand = (ePhyChanBondState)pPropChnlSwitch->subBand; + psessionEntry->gLimChannelSwitch.switchCount = pPropChnlSwitch->channelSwitchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = + SYS_MS_TO_TICKS(beaconPeriod)* (pPropChnlSwitch->channelSwitchCount); + psessionEntry->gLimChannelSwitch.switchMode = pPropChnlSwitch->mode; + } + else + { + pChnlSwitch = &(pBeacon->channelSwitchIE); + psessionEntry->gLimChannelSwitch.primaryChannel = pChnlSwitch->newChannel; + psessionEntry->gLimChannelSwitch.switchCount = pChnlSwitch->switchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = + SYS_MS_TO_TICKS(beaconPeriod)* (pChnlSwitch->switchCount); + psessionEntry->gLimChannelSwitch.switchMode = pChnlSwitch->switchMode; +#ifdef WLAN_FEATURE_11AC + pWiderChnlSwitch = &(pBeacon->WiderBWChanSwitchAnn); + if(pBeacon->WiderBWChanSwitchAnnPresent) + { + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = pWiderChnlSwitch->newChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = pWiderChnlSwitch->newCenterChanFreq0; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = pWiderChnlSwitch->newCenterChanFreq1; + } +#endif + + /* Only primary channel switch element is present */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; + + /* Do not bother to look and operate on extended channel switch element + * if our own channel-bonding state is not enabled + */ + if (psessionEntry->htSupportedChannelWidthSet) + { + if (pBeacon->extChannelSwitchPresent) + { + if ((pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = pBeacon->extChannelSwitchIE.secondaryChannelOffset; + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability && pBeacon->WiderBWChanSwitchAnnPresent) + { + if (pWiderChnlSwitch->newChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + if(pBeacon->extChannelSwitchPresent) + { + if ((pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = limGet11ACPhyCBState(pMac, + psessionEntry->gLimChannelSwitch.primaryChannel, + pBeacon->extChannelSwitchIE.secondaryChannelOffset, + pWiderChnlSwitch->newCenterChanFreq0, + psessionEntry); + } + } + } + } +#endif + } + } + } + if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry)) + { + PELOGW(limLog(pMac, LOGW, FL("Could not start Channel Switch"));) + } + + limLog(pMac, LOGW, + FL("session %d primary chl %d, subband %d, count %d (%d ticks) "), + psessionEntry->peSessionId, + psessionEntry->gLimChannelSwitch.primaryChannel, + psessionEntry->gLimChannelSwitch.secondarySubBand, + psessionEntry->gLimChannelSwitch.switchCount, + psessionEntry->gLimChannelSwitch.switchTimeoutValue); + return; +} + +/** + * limCancelDot11hChannelSwitch + * + *FUNCTION: + * This function is called when STA does not send updated channel-swith IE + * after indicating channel-switch start. This will cancel the channel-swith + * timer which is already running. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + PELOGW(limLog(pMac, LOGW, FL("Received a beacon without channel switch IE"));) + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); + + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed!"));) + } + + /* We need to restore pre-channelSwitch state on the STA */ + if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: Could not restore pre-channelSwitch (11h) state, resetting the system"));) + + } +} + +/**---------------------------------------------- +\fn limCancelDot11hQuiet +\brief Cancel the quieting on Station if latest + beacon doesn't contain quiet IE in it. + +\param pMac +\return NONE +-----------------------------------------------*/ +void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed"));) + } + } + else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed"));) + } + /** + * If the channel switch is already running in silent mode, dont resume the + * transmission. Channel switch timer when timeout, transmission will be resumed. + */ + if(!((psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) && + (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT))) + { + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + } + } + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; +} + +/** + * limProcessQuietTimeout + * + * FUNCTION: + * This function is active only on the STA. + * Handles SIR_LIM_QUIET_TIMEOUT + * + * LOGIC: + * This timeout can occur under only one circumstance: + * + * 1) When gLimQuietState = eLIM_QUIET_BEGIN + * This indicates that the timeout "interval" has + * expired. This is a trigger for the STA to now + * shut-off Tx/Rx for the specified gLimQuietDuration + * -> The TIMER object gLimQuietBssTimer is + * activated + * -> With timeout = gLimQuietDuration + * -> gLimQuietState is set to eLIM_QUIET_RUNNING + * + * ASSUMPTIONS: + * Using two TIMER objects - + * gLimQuietTimer & gLimQuietBssTimer + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limProcessQuietTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietTimer.sessionId))== NULL) + { + limLog(pMac, LOGE,FL("Session Does not exist for given sessionID")); + return; + } + + PELOG1(limLog(pMac, LOG1, FL("quietState = %d"), psessionEntry->gLimSpecMgmt.quietState);) + switch( psessionEntry->gLimSpecMgmt.quietState ) + { + case eLIM_QUIET_BEGIN: + // Time to Stop data traffic for quietDuration + //limDeactivateAndChangeTimer(pMac, eLIM_QUIET_BSS_TIMER); + if (TX_SUCCESS != + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)) + { + limLog( pMac, LOGE, + FL("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway...")); + } + + // gLimQuietDuration appears to be in units of ticks + // Use it as is + if (TX_SUCCESS != + tx_timer_change( &pMac->lim.limTimers.gLimQuietBssTimer, + psessionEntry->gLimSpecMgmt.quietDuration, + 0)) + { + limLog( pMac, LOGE, + FL("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway...")); + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, pMac->lim.limTimers.gLimQuietTimer.sessionId, eLIM_QUIET_BSS_TIMER)); +#ifdef GEN6_TODO + /* revisit this piece of code to assign the appropriate sessionId below + * priority - HIGH + */ + pMac->lim.limTimers.gLimQuietBssTimer.sessionId = sessionId; +#endif + if( TX_SUCCESS != + tx_timer_activate( &pMac->lim.limTimers.gLimQuietBssTimer )) + { + limLog( pMac, LOGW, + FL("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS...")); + } + else + { + // Transition to eLIM_QUIET_RUNNING + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_RUNNING; + + /* If we have sta bk scan triggered and trigger bk scan actually started successfully, */ + /* print message, otherwise, stop data traffic and stay quiet */ + if( pMac->lim.gLimTriggerBackgroundScanDuringQuietBss && + (eSIR_TRUE == (glimTriggerBackgroundScanDuringQuietBss_Status = limTriggerBackgroundScanDuringQuietBss( pMac ))) ) + { + limLog( pMac, LOG2, + FL("Attempting to trigger a background scan...")); + } + else + { + // Shut-off Tx/Rx for gLimSpecMgmt.quietDuration + /* freeze the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX); + + limLog( pMac, LOG2, + FL("Quiet BSS: STA shutting down for %d ticks"), + psessionEntry->gLimSpecMgmt.quietDuration ); + } + } + break; + + case eLIM_QUIET_RUNNING: + case eLIM_QUIET_INIT: + case eLIM_QUIET_END: + default: + // + // As of now, nothing to be done + // + break; + } +} + +/** + * limProcessQuietBssTimeout + * + * FUNCTION: + * This function is active on the AP and STA. + * Handles SIR_LIM_QUIET_BSS_TIMEOUT + * + * LOGIC: + * On the AP - + * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is + * an indication for the AP to START sending out the + * Quiet BSS IE. + * If 802.11H is enabled, the Quiet BSS IE is sent as per + * the 11H spec + * If 802.11H is not enabled, the Quiet BSS IE is sent as + * a Proprietary IE. This will be understood by all the + * TITAN STA's + * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will + * initiate the SCH to include the Quiet BSS IE in all + * its subsequent Beacons/PR's. + * The Quiet BSS IE will be included in all the Beacons + * & PR's until the next DTIM period + * + * On the STA - + * When gLimQuietState = eLIM_QUIET_RUNNING + * This indicates that the STA was successfully shut-off + * for the specified gLimQuietDuration. This is a trigger + * for the STA to now resume data traffic. + * -> gLimQuietState is set to eLIM_QUIET_INIT + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limProcessQuietBssTimeout( tpAniSirGlobal pMac ) +{ + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietBssTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + PELOG1(limLog(pMac, LOG1, FL("quietState = %d"), psessionEntry->gLimSpecMgmt.quietState);) + if (eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + } + else + { + // eLIM_STA_ROLE + switch( psessionEntry->gLimSpecMgmt.quietState ) + { + case eLIM_QUIET_RUNNING: + // Transition to eLIM_QUIET_INIT + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + if( !pMac->lim.gLimTriggerBackgroundScanDuringQuietBss || (glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE) ) + { + // Resume data traffic only if channel switch is not running in silent mode. + if (!((psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) && + (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT))) + { + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + } + + /* Reset status flag */ + if(glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE) + glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE; + + limLog( pMac, LOG2, + FL("Quiet BSS: Resuming traffic...")); + } + else + { + // + // Nothing specific to be done in this case + // A background scan that was triggered during + // SIR_LIM_QUIET_TIMEOUT will complete on its own + // + limLog( pMac, LOG2, + FL("Background scan should be complete now...")); + } + break; + + case eLIM_QUIET_INIT: + case eLIM_QUIET_BEGIN: + case eLIM_QUIET_END: + PELOG2(limLog(pMac, LOG2, FL("Quiet state not in RUNNING"));) + /* If the quiet period has ended, then resume the frame transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + break; + + default: + // + // As of now, nothing to be done + // + break; + } + } +} + +/**---------------------------------------------- +\fn limStartQuietTimer +\brief Starts the quiet timer. + +\param pMac +\return NONE +-----------------------------------------------*/ +void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpPESession psessionEntry; + psessionEntry = peFindSessionBySessionId(pMac, sessionId); + + if(psessionEntry == NULL) { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + // First, de-activate Timer, if its already active + limCancelDot11hQuiet(pMac, psessionEntry); + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_QUIET_TIMER)); + if( TX_SUCCESS != tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) + { + limLog( pMac, LOGE, + FL( "Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + + // Set the NEW timeout value, in ticks + if( TX_SUCCESS != tx_timer_change( &pMac->lim.limTimers.gLimQuietTimer, + SYS_MS_TO_TICKS(psessionEntry->gLimSpecMgmt.quietTimeoutValue), 0)) + { + limLog( pMac, LOGE, + FL( "Unable to change gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + + pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId; + if( TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer)) + { + limLog( pMac, LOGE, + FL("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!")); + limRestorePreQuietState(pMac, psessionEntry); + + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + return; + } +} + + +/** ------------------------------------------------------------------------ **/ +/** + * keep track of the number of ANI peers associated in the BSS + * For the first and last ANI peer, we have to update EDCA params as needed + * + * When the first ANI peer joins the BSS, we notify SCH + * When the last ANI peer leaves the BSS, we notfiy SCH + */ +void +limUtilCountStaAdd( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + + if ((! pSta) || (! pSta->valid) || (! pSta->aniPeer) || (pSta->fAniCount)) + return; + + pSta->fAniCount = 1; + + if (pMac->lim.gLimNumOfAniSTAs++ != 0) + return; + + // get here only if this is the first ANI peer in the BSS + schEdcaProfileUpdate(pMac, psessionEntry); +} + +void +limUtilCountStaDel( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + + if ((pSta == NULL) || (pSta->aniPeer == eHAL_CLEAR) || (! pSta->fAniCount)) + return; + + /* Only if sta is invalid and the validInDummyState bit is set to 1, + * then go ahead and update the count and profiles. This ensures + * that the "number of ani station" count is properly incremented/decremented. + */ + if (pSta->valid == 1) + return; + + pSta->fAniCount = 0; + + if (pMac->lim.gLimNumOfAniSTAs <= 0) + { + limLog(pMac, LOGE, FL("CountStaDel: ignoring Delete Req when AniPeer count is %d"), + pMac->lim.gLimNumOfAniSTAs); + return; + } + + pMac->lim.gLimNumOfAniSTAs--; + + if (pMac->lim.gLimNumOfAniSTAs != 0) + return; + + // get here only if this is the last ANI peer in the BSS + schEdcaProfileUpdate(pMac, psessionEntry); +} + +/** + * limSwitchChannelCback() + * + *FUNCTION: + * This is the callback function registered while requesting to switch channel + * after AP indicates a channel switch for spectrum management (11h). + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param status Status of channel switch request + * @param data User data + * @param psessionEntry Session information + * @return NONE + */ +void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg = {0}; + tSirSmeSwitchChannelInd *pSirSmeSwitchChInd; + + psessionEntry->currentOperChannel = psessionEntry->currentReqChannel; + + /* We need to restore pre-channelSwitch state on the STA */ + if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + return; + } + + mmhMsg.type = eWNI_SME_SWITCH_CHL_REQ; + pSirSmeSwitchChInd = vos_mem_malloc(sizeof(tSirSmeSwitchChannelInd)); + if ( NULL == pSirSmeSwitchChInd ) + { + limLog(pMac, LOGP, FL("Failed to allocate buffer for buffer descriptor")); + return; + } + + pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_REQ; + pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd); + pSirSmeSwitchChInd->newChannelId = psessionEntry->gLimChannelSwitch.primaryChannel; + pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId; + vos_mem_copy( pSirSmeSwitchChInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + mmhMsg.bodyptr = pSirSmeSwitchChInd; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); + + SysProcessMmhMsg(pMac, &mmhMsg); +} + +/** + * limSwitchPrimaryChannel() + * + *FUNCTION: + * This function changes the current operating channel + * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL. + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param newChannel new chnannel ID + * @return NONE + */ +void limSwitchPrimaryChannel(tpAniSirGlobal pMac, tANI_U8 newChannel,tpPESession psessionEntry) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + + PELOG3(limLog(pMac, LOG3, FL("limSwitchPrimaryChannel: old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, newChannel);) + psessionEntry->currentReqChannel = newChannel; + psessionEntry->limRFBand = limGetRFBand(newChannel); + + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + + pMac->lim.gpchangeChannelCallback = limSwitchChannelCback; + pMac->lim.gpchangeChannelData = NULL; + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams(pMac, newChannel, PHY_SINGLE_CHANNEL_CENTERED, + psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) + { + limLog( pMac, LOGP, FL( "Unable to read Local Power Constraint from cfg" )); + return; + } + limSendSwitchChnlParams(pMac, newChannel, PHY_SINGLE_CHANNEL_CENTERED, + (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + return; +} + +/** + * limSwitchPrimarySecondaryChannel() + * + *FUNCTION: + * This function changes the primary and secondary channel. + * If 11h is enabled and user provides a "new channel ID" + * that is different from the current operating channel, + * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL, + * assign notify LIM of such change. + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param newChannel New chnannel ID (or current channel ID) + * @param subband CB secondary info: + * - eANI_CB_SECONDARY_NONE + * - eANI_CB_SECONDARY_UP + * - eANI_CB_SECONDARY_DOWN + * @return NONE + */ +void limSwitchPrimarySecondaryChannel(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 newChannel, ePhyChanBondState subband) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + +#if !defined WLAN_FEATURE_VOWIFI + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams(pMac, newChannel, subband, psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + limSendSwitchChnlParams(pMac, newChannel, subband, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + + // Store the new primary and secondary channel in session entries if different + if (psessionEntry->currentOperChannel != newChannel) + { + limLog(pMac, LOGW, + FL("switch old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, newChannel); + psessionEntry->currentOperChannel = newChannel; + } + if (psessionEntry->htSecondaryChannelOffset != subband) + { + limLog(pMac, LOGW, + FL("switch old sec chnl %d --> new sec chnl %d "), + psessionEntry->htSecondaryChannelOffset, subband); + psessionEntry->htSecondaryChannelOffset = subband; + if (psessionEntry->htSecondaryChannelOffset == PHY_SINGLE_CHANNEL_CENTERED) + { + psessionEntry->htSupportedChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + else + { + psessionEntry->htSupportedChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + } + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + } + + return; +} + + +/** + * limActiveScanAllowed() + * + *FUNCTION: + * Checks if active scans are permitted on the given channel + * + *LOGIC: + * The config variable SCAN_CONTROL_LIST contains pairs of (channelNum, activeScanAllowed) + * Need to check if the channelNum matches, then depending on the corresponding + * scan flag, return true (for activeScanAllowed==1) or false (otherwise). + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param channelNum channel number + * @return None + */ + +tANI_U8 limActiveScanAllowed( + tpAniSirGlobal pMac, + tANI_U8 channelNum) +{ + tANI_U32 i; + tANI_U8 channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN]; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to get scan control list"));) + return false; + } + + if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) + { + limLog(pMac, LOGE, FL("Invalid scan control list length:%d"), + len); + return false; + } + + for (i=0; (i+1) < len; i+=2) + { + if (channelPair[i] == channelNum) + return ((channelPair[i+1] == eSIR_ACTIVE_SCAN) ? true : false); + } + return false; +} + +/** + * limTriggerBackgroundScanDuringQuietBss() + * + *FUNCTION: + * This function is applicable to the STA only. + * This function is called by limProcessQuietTimeout(), + * when it is time to honor the Quiet BSS IE from the AP. + * + *LOGIC: + * If 11H is enabled: + * We cannot trigger a background scan. The STA needs to + * shut-off Tx/Rx. + * If 11 is not enabled: + * Determine if the next channel that we are going to + * scan is NOT the same channel (or not) on which the + * Quiet BSS was requested. + * If yes, then we cannot trigger a background scan on + * this channel. Return with a false. + * If no, then trigger a background scan. Return with + * a true. + * + *ASSUMPTIONS: + * + *NOTE: + * This API is redundant if the existing API, + * limTriggerBackgroundScan(), were to return a valid + * response instead of returning void. + * If possible, try to revisit this API + * + * @param pMac Pointer to Global MAC structure + * @return eSIR_TRUE, if a background scan was attempted + * eSIR_FALSE, if not + */ +tAniBool limTriggerBackgroundScanDuringQuietBss( tpAniSirGlobal pMac ) +{ + tAniBool bScanTriggered = eSIR_FALSE; + + + + //TBD-RAJESH HOW TO GET sessionEntry????? + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return bScanTriggered; + + if( !psessionEntry->lim11hEnable ) + { + tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN; + + // Determine the next scan channel + + // Get background scan channel list from CFG + if( eSIR_SUCCESS == wlan_cfgGetStr( pMac, + WNI_CFG_BG_SCAN_CHANNEL_LIST, + (tANI_U8 *) bgScanChannelList, + (tANI_U32 *) &len )) + { + // Ensure that we do not go off scanning on the same + // channel on which the Quiet BSS was requested + if( psessionEntry->currentOperChannel!= + bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId] ) + { + // For now, try and attempt a background scan. It will + // be ideal if this API actually returns a success or + // failure instead of having a void return type + limTriggerBackgroundScan( pMac ); + + bScanTriggered = eSIR_TRUE; + } + else + { + limLog( pMac, LOGW, + FL("The next SCAN channel is the current operating channel on which a Quiet BSS is requested.! A background scan will not be triggered during this Quiet BSS period...")); + } + } + else + { + limLog( pMac, LOGW, + FL("Unable to retrieve WNI_CFG_VALID_CHANNEL_LIST from CFG! A background scan will not be triggered during this Quiet BSS period...")); + } + } + return bScanTriggered; +} + + +/** + * limGetHTCapability() + * + *FUNCTION: + * A utility function that returns the "current HT capability state" for the HT + * capability of interest (as requested in the API) + * + *LOGIC: + * This routine will return with the "current" setting of a requested HT + * capability. This state info could be retrieved from - + * a) CFG (for static entries) + * b) Run time info + * - Dynamic state maintained by LIM + * - Configured at radio init time by SME + * + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param htCap The HT capability being queried + * @return tANI_U8 The current state of the requested HT capability is returned in a + * tANI_U8 variable + */ + +tANI_U8 limGetHTCapability( tpAniSirGlobal pMac, + tANI_U32 htCap, tpPESession psessionEntry) +{ +tANI_U8 retVal = 0; +tANI_U8 *ptr; +tANI_U32 cfgValue; +tSirMacHTCapabilityInfo macHTCapabilityInfo = {0}; +tSirMacExtendedHTCapabilityInfo macExtHTCapabilityInfo = {0}; +tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = {0}; +tSirMacASCapabilityInfo macASCapabilityInfo = {0}; + + // + // Determine which CFG to read from. Not ALL of the HT + // related CFG's need to be read each time this API is + // accessed + // + if( htCap >= eHT_ANTENNA_SELECTION && + htCap < eHT_SI_GRANULARITY ) + { + // Get Antenna Seletion HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_AS_CAP, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macASCapabilityInfo; + *((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff); + } + else + { + if( htCap >= eHT_TX_BEAMFORMING && + htCap < eHT_ANTENNA_SELECTION ) + { + // Get Transmit Beam Forming HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TX_BF_CAP, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macTxBFCapabilityInfo; + *((tANI_U32 *)ptr) = (tANI_U32) (cfgValue); + } + else + { + if( htCap >= eHT_PCO && + htCap < eHT_TX_BEAMFORMING ) + { + // Get Extended HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_EXT_HT_CAP_INFO, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macExtHTCapabilityInfo; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + } + else + { + if( htCap < eHT_MAX_RX_AMPDU_FACTOR ) + { + // Get HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_HT_CAP_INFO, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macHTCapabilityInfo; + // CR 265282 MDM SoftAP 2.4PL: SoftAP boot up crash in 2.4 PL builds while same WLAN SU is working on 2.1 PL + *ptr++ = cfgValue & 0xff; + *ptr = (cfgValue >> 8) & 0xff; + } + } + } + } + + switch( htCap ) + { + case eHT_LSIG_TXOP_PROTECTION: + retVal = pMac->lim.gHTLsigTXOPProtection; + break; + + case eHT_STBC_CONTROL_FRAME: + retVal = (tANI_U8) macHTCapabilityInfo.stbcControlFrame; + break; + + case eHT_PSMP: + retVal = pMac->lim.gHTPSMPSupport; + break; + + case eHT_DSSS_CCK_MODE_40MHZ: + retVal = pMac->lim.gHTDsssCckRate40MHzSupport; + break; + + case eHT_MAX_AMSDU_LENGTH: + retVal = (tANI_U8) macHTCapabilityInfo.maximalAMSDUsize; + break; + + case eHT_DELAYED_BA: + retVal = (tANI_U8) macHTCapabilityInfo.delayedBA; + break; + + case eHT_RX_STBC: + retVal = (tANI_U8) psessionEntry->htConfig.ht_rx_stbc; + break; + + case eHT_TX_STBC: + retVal = (tANI_U8) psessionEntry->htConfig.ht_tx_stbc; + break; + + case eHT_SHORT_GI_40MHZ: + retVal =(tANI_U8) + (psessionEntry->htConfig.ht_sgi)? macHTCapabilityInfo.shortGI40MHz : 0; + break; + + case eHT_SHORT_GI_20MHZ: + retVal = (tANI_U8) + (psessionEntry->htConfig.ht_sgi)? macHTCapabilityInfo.shortGI20MHz : 0; + break; + + case eHT_GREENFIELD: + retVal = (tANI_U8) macHTCapabilityInfo.greenField; + break; + + case eHT_MIMO_POWER_SAVE: + retVal = (tANI_U8) pMac->lim.gHTMIMOPSState; + break; + + case eHT_SUPPORTED_CHANNEL_WIDTH_SET: + retVal = (tANI_U8) psessionEntry->htSupportedChannelWidthSet; + break; + + case eHT_ADVANCED_CODING: + retVal = (tANI_U8) psessionEntry->htConfig.ht_rx_ldpc; + break; + + case eHT_MAX_RX_AMPDU_FACTOR: + retVal = pMac->lim.gHTMaxRxAMpduFactor; + break; + + case eHT_MPDU_DENSITY: + retVal = pMac->lim.gHTAMpduDensity; + break; + + case eHT_PCO: + retVal = (tANI_U8) macExtHTCapabilityInfo.pco; + break; + + case eHT_TRANSITION_TIME: + retVal = (tANI_U8) macExtHTCapabilityInfo.transitionTime; + break; + + case eHT_MCS_FEEDBACK: + retVal = (tANI_U8) macExtHTCapabilityInfo.mcsFeedback; + break; + + case eHT_TX_BEAMFORMING: + retVal = (tANI_U8) macTxBFCapabilityInfo.txBF; + break; + + case eHT_ANTENNA_SELECTION: + retVal = (tANI_U8) macASCapabilityInfo.antennaSelection; + break; + + case eHT_SI_GRANULARITY: + retVal = pMac->lim.gHTServiceIntervalGranularity; + break; + + case eHT_CONTROLLED_ACCESS: + retVal = pMac->lim.gHTControlledAccessOnly; + break; + + case eHT_RIFS_MODE: + retVal = psessionEntry->beaconParams.fRIFSMode; + break; + + case eHT_RECOMMENDED_TX_WIDTH_SET: + retVal = psessionEntry->htRecommendedTxWidthSet; + break; + + case eHT_EXTENSION_CHANNEL_OFFSET: + retVal = psessionEntry->htSecondaryChannelOffset; + break; + + case eHT_OP_MODE: + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + retVal = psessionEntry->htOperMode; + else + retVal = pMac->lim.gHTOperMode; + break; + + case eHT_BASIC_STBC_MCS: + retVal = pMac->lim.gHTSTBCBasicMCS; + break; + + case eHT_DUAL_CTS_PROTECTION: + retVal = pMac->lim.gHTDualCTSProtection; + break; + + case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT: + retVal = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport; + break; + + case eHT_PCO_ACTIVE: + retVal = pMac->lim.gHTPCOActive; + break; + + case eHT_PCO_PHASE: + retVal = pMac->lim.gHTPCOPhase; + break; + + default: + break; + } + + return retVal; +} + +void limGetMyMacAddr(tpAniSirGlobal pMac, tANI_U8 *mac) +{ + vos_mem_copy( mac, pMac->lim.gLimMyMacAddr, sizeof(tSirMacAddr)); + return; +} + + + + +/** ------------------------------------------------------------- +\fn limEnable11aProtection +\brief based on config setting enables\disables 11a protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(NULL == psessionEntry) + { + PELOG3(limLog(pMac, LOG3, FL("psessionEntry is NULL"));) + return eSIR_FAILURE; + } + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (!psessionEntry->cfgProtection.fromlla)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11a is disabled"));) + return eSIR_SUCCESS; + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + if(((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))&& + (true == psessionEntry->htCapability)) + { + if(overlap) + { + pMac->lim.gLimOverlap11aParams.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLim11aParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llaCoexist) + { + PELOG1(limLog(pMac, LOG1, FL(" => protection from 11A Enabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llaCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlap11aParams.protectionEnabled = false; + + //We need to take care of HT OP mode iff we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(pMac->lim.gLimOverlap11aParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11A stations. + psessionEntry->gLim11aParams.protectionEnabled = false; + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Check if any other non-HT protection enabled. + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + + //Change HT OP mode to 01 if any overlap protection enabled + if(pMac->lim.gLimOverlap11aParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + if(!pMac->lim.gLimOverlap11aParams.protectionEnabled && + !psessionEntry->gLim11aParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnable11gProtection +\brief based on config setting enables\disables 11g protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ + +tSirRetStatus +limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.fromllb) + { + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if(!pMac->lim.cfgProtection.fromllb) + { + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + psessionEntry->gLimOlbcParams.protectionEnabled = true; + PELOGE(limLog(pMac, LOG1, FL("protection from olbc is enabled"));) + if(true == psessionEntry->htCapability) + { + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + // This fixes issue of OBSS bit not set after 11b, 11g station leaves + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + //Not processing OBSS bit from other APs, as we are already taking care + //of Protection from overlapping BSS based on erp IE or useProtection bit + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + } + else + { + psessionEntry->gLim11bParams.protectionEnabled = true; + PELOGE(limLog(pMac, LOG1, FL("protection from 11b is enabled"));) + if(true == psessionEntry->htCapability) + { + if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + }else if ((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) && + (true == psessionEntry->htCapability)) + { + if(overlap) + { + psessionEntry->gLimOlbcParams.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + // This fixes issue of OBSS bit not set after 11b, 11g station leaves + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + //Not processing OBSS bit from other APs, as we are already taking care + //of Protection from overlapping BSS based on erp IE or useProtection bit + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + else + { + psessionEntry->gLim11bParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llbCoexist) + { + PELOG1(limLog(pMac, LOG1, FL("=> 11G Protection Enabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llbCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOlbcParams.protectionEnabled = false; + + //We need to take care of HT OP mode if we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + if(psessionEntry->gLimHt20Params.protectionEnabled){ + //Commenting out beacuse of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + else + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11B stations. + psessionEntry->gLim11bParams.protectionEnabled = false; + PELOGE(limLog(pMac, LOG1, FL("===> 11B Protection Disabled"));) + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11gParams.protectionEnabled) + { + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + PELOGE(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + PELOGE(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOlbcParams.protectionEnabled && + !psessionEntry->gLim11bParams.protectionEnabled) + { + PELOGE(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOlbcParams.protectionEnabled = false; + + //We need to take care of HT OP mode iff we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11B stations. + psessionEntry->gLim11bParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11gParams.protectionEnabled) + { + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOlbcParams.protectionEnabled && + !psessionEntry->gLim11bParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHtProtectionFrom11g +\brief based on cofig enables\disables protection from 11g. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // protection from 11g is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && (!psessionEntry->cfgProtection.overlapFromllg)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled"));); + return eSIR_SUCCESS; + }else if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) && (!pMac->lim.cfgProtection.overlapFromllg)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled"));); + return eSIR_SUCCESS; + } + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.fromllg){ + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if(!pMac->lim.cfgProtection.fromllg) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled"));) + return eSIR_SUCCESS; + } + } + } + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + psessionEntry->gLimOverlap11gParams.protectionEnabled = true; + //11g exists in overlap BSS. + //need not to change the operating mode to overlap_legacy + //if higher or same protection operating mode is enabled right now. + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + else + { + //11g is associated to an AP operating in 11n mode. + //Change the HT operating mode to 'mixed mode'. + psessionEntry->gLim11gParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + pMac->lim.gLimOverlap11gParams.protectionEnabled = true; + //11g exists in overlap BSS. + //need not to change the operating mode to overlap_legacy + //if higher or same protection operating mode is enabled right now. + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + //11g is associated to an AP operating in 11n mode. + //Change the HT operating mode to 'mixed mode'. + psessionEntry->gLim11gParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llgCoexist) + { + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + else if (true == psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + // As operating mode changed after G station assoc some way to update beacon + // This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled + //pMac->sch.schObject.fBeaconChanged = 1; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llgCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + if (psessionEntry->gLim11gParams.numSta == 0) + psessionEntry->gLimOverlap11gParams.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled){ + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + else + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLim11gParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11bParams.protectionEnabled) + { + + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled) + + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOverlap11gParams.protectionEnabled && + !psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlap11gParams.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLim11gParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11bParams.protectionEnabled) + { + + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!pMac->lim.gLimOverlap11gParams.protectionEnabled && + !psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + return eSIR_SUCCESS; +} +//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. +//This check will be done at the caller. + +/** ------------------------------------------------------------- +\fn limEnableHtObssProtection +\brief based on cofig enables\disables obss protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtOBSSProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + //overlapping protection configuration check. + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && !psessionEntry->cfgProtection.obss) + { //ToDo Update this field + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if(!pMac->lim.cfgProtection.obss) + { //ToDo Update this field + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled"));) + return eSIR_SUCCESS; + } + } + } + + + if (eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) ) + { + PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled"));) + psessionEntry->beaconParams.gHTObssMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE + + } + else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled"));) + psessionEntry->beaconParams.gHTObssMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; + + } +//CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + if (!enable && !overlap) + { + psessionEntry->gLimOverlap11gParams.protectionEnabled = false; + } + } else + { + if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) ) + { + PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled"));) + psessionEntry->beaconParams.gHTObssMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE + + } + else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode)) + { + + PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled"));) + psessionEntry->beaconParams.gHTObssMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; + + } + } + return eSIR_SUCCESS; +} +/** ------------------------------------------------------------- +\fn limEnableHT20Protection +\brief based on cofig enables\disables protection from Ht20. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.ht20) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if(!pMac->lim.cfgProtection.ht20) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if(overlap) + { + psessionEntry->gLimOverlapHt20Params.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLimHt20Params.protectionEnabled = true; + if(eSIR_HT_OP_MODE_PURE == psessionEntry->htOperMode) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + pMac->lim.gLimOverlapHt20Params.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLimHt20Params.protectionEnabled = true; + if(eSIR_HT_OP_MODE_PURE == pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.ht20Coexist) + { + PELOG1(limLog(pMac, LOG1, FL("=> Prtection from HT20 Enabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.ht20Coexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOverlapHt20Params.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commented beacuse of CR 258588 for WFA Cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLimHt20Params.protectionEnabled = false; + + //Change HT op mode appropriately. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlapHt20Params.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + { + + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLimHt20Params.protectionEnabled = false; + + //Change HT op mode appropriately. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHTNonGfProtection +\brief based on cofig enables\disables protection from NonGf. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.nonGf) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + //normal protection config check + if(!pMac->lim.cfgProtection.nonGf) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled"));) + return eSIR_SUCCESS; + } + } + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + }else + { + if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHTLsigTxopProtection +\brief based on cofig enables\disables LsigTxop protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.lsigTxop) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + //normal protection config check + if(!pMac->lim.cfgProtection.lsigTxop) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled"));) + return eSIR_SUCCESS; + } + } + } + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + }else + { + if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + } + return eSIR_SUCCESS; +} +//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. +//This check will be done at the caller. +/** ------------------------------------------------------------- +\fn limEnableHtRifsProtection +\brief based on cofig enables\disables Rifs protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + !psessionEntry->cfgProtection.rifs) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + //normal protection config check + if(!pMac->lim.cfgProtection.rifs) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS + if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS + else if (enable && (true == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + }else + { + // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS + if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS + else if (enable && (true == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + } + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------- +/** + * limEnableShortPreamble + * + * FUNCTION: + * Enable/Disable short preamble + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param enable Flag to enable/disable short preamble + * @return None + */ + +tSirRetStatus +limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + { + /* Could not get short preamble enabled flag from CFG. Log error. */ + limLog(pMac, LOGP, FL("could not retrieve short preamble flag")); + return eSIR_FAILURE; + } + + if (!val) + return eSIR_SUCCESS; + + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve 11G short preamble switching enabled flag")); + return eSIR_FAILURE; + } + + if (!val) // 11G short preamble switching is disabled. + return eSIR_SUCCESS; + + if ( psessionEntry->limSystemRole == eLIM_AP_ROLE ) + { + if (enable && (psessionEntry->beaconParams.fShortPreamble == 0)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Enabled"));) + psessionEntry->beaconParams.fShortPreamble = true; + pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED; + } + else if (!enable && (psessionEntry->beaconParams.fShortPreamble == 1)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Disabled"));) + psessionEntry->beaconParams.fShortPreamble = false; + pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED; + } + } + + return eSIR_SUCCESS; + } + +/** + * limTxComplete + * + * Function: + * This is LIM's very own "TX MGMT frame complete" completion routine. + * + * Logic: + * LIM wants to send a MGMT frame (broadcast or unicast) + * LIM allocates memory using palPktAlloc( ..., **pData, **pPacket ) + * LIM transmits the MGMT frame using the API: + * halTxFrame( ... pPacket, ..., (void *) limTxComplete, pData ) + * HDD, via halTxFrame/DXE, "transfers" the packet over to BMU + * HDD, if it determines that a TX completion routine (in this case + * limTxComplete) has been provided, will invoke this callback + * LIM will try to free the TX MGMT packet that was earlier allocated, in order + * to send this MGMT frame, using the PAL API palPktFree( ... pData, pPacket ) + * + * Assumptions: + * Presently, this is ONLY being used for MGMT frames/packets + * TODO: + * Would it do good for LIM to have some sort of "signature" validation to + * ensure that the pData argument passed in was a buffer that was actually + * allocated by LIM and/or is not corrupted? + * + * Note: FIXME and TODO + * Looks like palPktFree() is interested in pPacket. But, when this completion + * routine is called, only pData is made available to LIM!! + * + * @param void A pointer to pData. Shouldn't it be pPacket?! + * + * @return none + */ +void limTxComplete( tHalHandle hHal, void *pData, v_BOOL_t free) +{ + tpAniSirGlobal pMac; + pMac = (tpAniSirGlobal)hHal; + +#ifdef FIXME_PRIMA + /* the trace logic needs to be fixed for Prima. Refer to CR 306075 */ +#ifdef TRACE_RECORD + { + tpSirMacMgmtHdr mHdr; + v_U8_t *pRxBd; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + + + + pVosPkt = (vos_pkt_t *)pData; + vosStatus = vos_pkt_peek_data( pVosPkt, 0, (v_PVOID_t *)&pRxBd, WLANHAL_RX_BD_HEADER_SIZE); + + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + mHdr = WDA_GET_RX_MAC_HEADER(pRxBd); + + } + } +#endif +#endif + + if (free) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) NULL, /* this is ignored and will likely be removed */ + (void *) pData ); /* lim passed in pPacket in pData pointer */ +} + +/** + * \brief This function updates lim global structure, if CB parameters in the BSS + * have changed, and sends an indication to HAL also with the + * updated HT Parameters. + * This function does not detect the change in the primary channel, that is done as part + * of channel Swtich IE processing. + * If STA is configured with '20Mhz only' mode, then this function does not do anything + * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz' + * + * + * \param pMac Pointer to global MAC structure + * + * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or + * Probe Response + * + * \param bssIdx BSS Index of the Bss to which Station is associated. + * + * + */ + +void limUpdateStaRunTimeHTSwitchChnlParams( tpAniSirGlobal pMac, + tDot11fIEHTInfo *pHTInfo, + tANI_U8 bssIdx, + tpPESession psessionEntry) +{ + ePhyChanBondState secondaryChnlOffset = PHY_SINGLE_CHANNEL_CENTERED; +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + + //If self capability is set to '20Mhz only', then do not change the CB mode. + if( !limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry )) + return; + +#if !defined WLAN_FEATURE_VOWIFI + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return; + } +#endif + + if (psessionEntry->ftPEContext.ftPreAuthSession) { + limLog( pMac, LOGE, FL( "FT PREAUTH channel change is in progress")); + return; + } + + + if ( psessionEntry->htSecondaryChannelOffset != ( tANI_U8 ) pHTInfo->secondaryChannelOffset || + psessionEntry->htRecommendedTxWidthSet != ( tANI_U8 ) pHTInfo->recommendedTxWidthSet ) + { + psessionEntry->htSecondaryChannelOffset = ( ePhyChanBondState ) pHTInfo->secondaryChannelOffset; + psessionEntry->htRecommendedTxWidthSet = ( tANI_U8 ) pHTInfo->recommendedTxWidthSet; + if ( eHT_CHANNEL_WIDTH_40MHZ == psessionEntry->htRecommendedTxWidthSet ) + secondaryChnlOffset = (ePhyChanBondState)pHTInfo->secondaryChannelOffset; + + // Notify HAL + limLog( pMac, LOGW, FL( "Channel Information in HT IE change" + "d; sending notification to HAL." ) ); + limLog( pMac, LOGW, FL( "Primary Channel: %d, Secondary Chan" + "nel Offset: %d, Channel Width: %d" ), + pHTInfo->primaryChannel, secondaryChnlOffset, + psessionEntry->htRecommendedTxWidthSet ); + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + pMac->lim.gpchangeChannelCallback = NULL; + pMac->lim.gpchangeChannelData = NULL; + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel, + secondaryChnlOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel, + secondaryChnlOffset, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + + //In case of IBSS, if STA should update HT Info IE in its beacons. + if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) + { + schSetFixedBeaconFields(pMac,psessionEntry); + } + + } +} // End limUpdateStaRunTimeHTParams. + +/** + * \brief This function updates the lim global structure, if any of the + * HT Capabilities have changed. + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pHTCapability Pointer to HT Capability Information Element + * obtained from a Beacon or Probe Response + * + * + * + */ + +void limUpdateStaRunTimeHTCapability( tpAniSirGlobal pMac, + tDot11fIEHTCaps *pHTCaps ) +{ + + if ( pMac->lim.gHTLsigTXOPProtection != ( tANI_U8 ) pHTCaps->lsigTXOPProtection ) + { + pMac->lim.gHTLsigTXOPProtection = ( tANI_U8 ) pHTCaps->lsigTXOPProtection; + // Send change notification to HAL + } + + if ( pMac->lim.gHTAMpduDensity != ( tANI_U8 ) pHTCaps->mpduDensity ) + { + pMac->lim.gHTAMpduDensity = ( tANI_U8 ) pHTCaps->mpduDensity; + // Send change notification to HAL + } + + if ( pMac->lim.gHTMaxRxAMpduFactor != ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor ) + { + pMac->lim.gHTMaxRxAMpduFactor = ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor; + // Send change notification to HAL + } + + +} // End limUpdateStaRunTimeHTCapability. + +/** + * \brief This function updates lim global structure, if any of the HT + * Info Parameters have changed. + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or + * Probe Response + * + * + */ + +void limUpdateStaRunTimeHTInfo( tpAniSirGlobal pMac, + tDot11fIEHTInfo *pHTInfo, tpPESession psessionEntry) +{ + if ( psessionEntry->htRecommendedTxWidthSet != ( tANI_U8 )pHTInfo->recommendedTxWidthSet ) + { + psessionEntry->htRecommendedTxWidthSet = ( tANI_U8 )pHTInfo->recommendedTxWidthSet; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.fRIFSMode != ( tANI_U8 )pHTInfo->rifsMode ) + { + psessionEntry->beaconParams.fRIFSMode = ( tANI_U8 )pHTInfo->rifsMode; + // Send change notification to HAL + } + + if ( pMac->lim.gHTServiceIntervalGranularity != ( tANI_U8 )pHTInfo->serviceIntervalGranularity ) + { + pMac->lim.gHTServiceIntervalGranularity = ( tANI_U8 )pHTInfo->serviceIntervalGranularity; + // Send change notification to HAL + } + + if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )pHTInfo->opMode ) + { + pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )pHTInfo->opMode; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.llnNonGFCoexist != pHTInfo->nonGFDevicesPresent ) + { + psessionEntry->beaconParams.llnNonGFCoexist = ( tANI_U8 )pHTInfo->nonGFDevicesPresent; + } + + if ( pMac->lim.gHTSTBCBasicMCS != ( tANI_U8 )pHTInfo->basicSTBCMCS ) + { + pMac->lim.gHTSTBCBasicMCS = ( tANI_U8 )pHTInfo->basicSTBCMCS; + // Send change notification to HAL + } + + if ( pMac->lim.gHTDualCTSProtection != ( tANI_U8 )pHTInfo->dualCTSProtection ) + { + pMac->lim.gHTDualCTSProtection = ( tANI_U8 )pHTInfo->dualCTSProtection; + // Send change notification to HAL + } + + if ( pMac->lim.gHTSecondaryBeacon != ( tANI_U8 )pHTInfo->secondaryBeacon ) + { + pMac->lim.gHTSecondaryBeacon = ( tANI_U8 )pHTInfo->secondaryBeacon; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport != ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport ) + { + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport; + // Send change notification to HAL + } + + if ( pMac->lim.gHTPCOActive != ( tANI_U8 )pHTInfo->pcoActive ) + { + pMac->lim.gHTPCOActive = ( tANI_U8 )pHTInfo->pcoActive; + // Send change notification to HAL + } + + if ( pMac->lim.gHTPCOPhase != ( tANI_U8 )pHTInfo->pcoPhase ) + { + pMac->lim.gHTPCOPhase = ( tANI_U8 )pHTInfo->pcoPhase; + // Send change notification to HAL + } + +} // End limUpdateStaRunTimeHTInfo. + + +/** ------------------------------------------------------------- +\fn limProcessHalIndMessages +\brief callback function for HAL indication +\param tpAniSirGlobal pMac +\param tANI_U32 mesgId +\param void *mesgParam +\return tSirRetStatu - status + -------------------------------------------------------------*/ + +tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 msgId, void *msgParam ) +{ + //its PE's responsibility to free msgparam when its done extracting the message parameters. + tSirMsgQ msg; + + switch(msgId) + { + case SIR_LIM_DEL_TS_IND: + case SIR_LIM_ADD_BA_IND: + case SIR_LIM_DEL_BA_ALL_IND: + case SIR_LIM_DELETE_STA_CONTEXT_IND: + case SIR_LIM_BEACON_GEN_IND: + msg.type = (tANI_U16) msgId; + msg.bodyptr = msgParam; + msg.bodyval = 0; + break; + + default: + vos_mem_free(msgParam); + limLog(pMac, LOGP, FL("invalid message id = %d received"), msgId); + return eSIR_FAILURE; + } + + if (limPostMsgApi(pMac, &msg) != eSIR_SUCCESS) + { + vos_mem_free(msgParam); + limLog(pMac, LOGP, FL("limPostMsgApi failed for msgid = %d"), msg.type); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limValidateDeltsReq +\brief Validates DelTs req originated by SME or by HAL and also sends halMsg_DelTs to HAL +\param tpAniSirGlobal pMac +\param tpSirDeltsReq pDeltsReq +\param tSirMacAddr peerMacAddr +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry) +{ + tpDphHashNode pSta; + tANI_U8 tsStatus; + tSirMacTSInfo *tsinfo; + tANI_U32 i; + tANI_U8 tspecIdx; + /* if sta + * - verify assoc state + * - del tspec locally + * if ap, + * - verify sta is in assoc state + * - del sta tspec locally + */ + if(pDeltsReq == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Delete TS request pointer is NULL"));) + return eSIR_FAILURE; + } + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + tANI_U32 val; + + // station always talks to the AP + pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + val = sizeof(tSirMacAddr); + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + } + else + { + tANI_U16 assocId; + tANI_U8 *macaddr = (tANI_U8 *) peerMacAddr; + + assocId = pDeltsReq->aid; + if (assocId != 0) + pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + else + pSta = dphLookupHashEntry(pMac, pDeltsReq->macAddr, &assocId, &psessionEntry->dph.dphHashTable); + + if (pSta != NULL) + // TBD: check sta assoc state as well + for (i =0; i < sizeof(tSirMacAddr); i++) + macaddr[i] = pSta->staAddr[i]; + } + + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, "Cannot find station context for delts req");) + return eSIR_FAILURE; + } + + if ((! pSta->valid) || + (pSta->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + PELOGE(limLog(pMac, LOGE, "Invalid Sta (or state) for DelTsReq");) + return eSIR_FAILURE; + } + + pDeltsReq->req.wsmTspecPresent = 0; + pDeltsReq->req.wmeTspecPresent = 0; + pDeltsReq->req.lleTspecPresent = 0; + + if ((pSta->wsmEnabled) && + (pDeltsReq->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA)) + pDeltsReq->req.wsmTspecPresent = 1; + else if (pSta->wmeEnabled) + pDeltsReq->req.wmeTspecPresent = 1; + else if (pSta->lleEnabled) + pDeltsReq->req.lleTspecPresent = 1; + else + { + PELOGW(limLog(pMac, LOGW, FL("DELTS_REQ ignore - qos is disabled"));) + return eSIR_FAILURE; + } + + tsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo + : &pDeltsReq->req.tsinfo; + PELOG1(limLog(pMac, LOG1, + FL("received DELTS_REQ message (wmeTspecPresent = %d, lleTspecPresent = %d, wsmTspecPresent = %d, tsid %d, up %d, direction = %d)"), + pDeltsReq->req.wmeTspecPresent, pDeltsReq->req.lleTspecPresent, pDeltsReq->req.wsmTspecPresent, + tsinfo->traffic.tsid, tsinfo->traffic.userPrio, tsinfo->traffic.direction);) + + // if no Access Control, ignore the request + + if (limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, "ERROR DELTS request for sta assocId %d (tsid %d, up %d)", + pSta->assocId, tsinfo->traffic.tsid, tsinfo->traffic.userPrio);) + return eSIR_FAILURE; + } + else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) + { + //edca only now. + } + else + { + if(tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) + { + //send message to HAL to delete TS + if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, + pSta->staIndex, + tspecIdx, + pDeltsReq->req, + psessionEntry->peSessionId, + psessionEntry->bssId)) + { + limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request"), + tsinfo->traffic.userPrio); + return eSIR_FAILURE; + } + } + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limRegisterHalIndCallBack +\brief registers callback function to HAL for any indication. +\param tpAniSirGlobal pMac +\return none. + -------------------------------------------------------------*/ +void +limRegisterHalIndCallBack(tpAniSirGlobal pMac) +{ + tSirMsgQ msg; + tpHalIndCB pHalCB; + + pHalCB = vos_mem_malloc(sizeof(tHalIndCB)); + if ( NULL == pHalCB ) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return; + } + + pHalCB->pHalIndCB = limProcessHalIndMessages; + + msg.type = WDA_REGISTER_PE_CALLBACK; + msg.bodyptr = pHalCB; + msg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + vos_mem_free(pHalCB); + limLog(pMac, LOGP, FL("wdaPostCtrlMsg() failed")); + } + + return; +} + + +/** ------------------------------------------------------------- +\fn limProcessAddBaInd + +\brief handles the BA activity check timeout indication coming from HAL. + Validates the request, posts request for sending addBaReq message for every candidate in the list. +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\return None +-------------------------------------------------------------*/ +void +limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tANI_U8 i; + tANI_U8 tid; + tANI_U16 assocId; + tpDphHashNode pSta; + tpAddBaCandidate pBaCandidate; + tANI_U32 baCandidateCnt; + tpBaActivityInd pBaActivityInd; + tpPESession psessionEntry; + tANI_U8 sessionId; +#ifdef FEATURE_WLAN_TDLS + boolean htCapable = FALSE; +#endif + + + if (limMsg->bodyptr == NULL) + return; + + pBaActivityInd = (tpBaActivityInd)limMsg->bodyptr; + baCandidateCnt = pBaActivityInd->baCandidateCnt; + + if ((psessionEntry = peFindSessionByBssid(pMac,pBaActivityInd->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given BSSId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + //if we are not HT capable we don't need to handle BA timeout indication from HAL. +#ifdef FEATURE_WLAN_TDLS + if ((baCandidateCnt > pMac->lim.maxStation)) +#else + if ((baCandidateCnt > pMac->lim.maxStation) || !psessionEntry->htCapability ) +#endif + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + +#ifdef FEATURE_WLAN_TDLS + //if we have TDLS peers, we should look at peers HT capability, which can be different than + //AP capability + pBaCandidate = (tpAddBaCandidate) (((tANI_U8*)pBaActivityInd) + sizeof(tBaActivityInd)); + + for (i=0; istaAddr, &assocId, &psessionEntry->dph.dphHashTable); + if ((NULL == pSta) || (!pSta->valid)) + continue; + + if (STA_ENTRY_TDLS_PEER == pSta->staType) + htCapable = pSta->mlmStaContext.htCapability; + else + htCapable = psessionEntry->htCapability; + + if (htCapable) + break; + } + if (!htCapable) + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } +#endif + + //delete the complete dialoguetoken linked list + limDeleteDialogueTokenList(pMac); + pBaCandidate = (tpAddBaCandidate) (((tANI_U8*)pBaActivityInd) + sizeof(tBaActivityInd)); + + for (i=0; istaAddr, &assocId, &psessionEntry->dph.dphHashTable); + if ((NULL == pSta) || (!pSta->valid)) + continue; + + for (tid=0; tidtcCfg[tid].fUseBATx) && + (pBaCandidate->baInfo[tid].fBaEnable)) + { + limLog(pMac, LOG1, FL("BA setup for staId = %d, TID: %d, SSN: %d"), + pSta->staIndex, tid, pBaCandidate->baInfo[tid].startingSeqNum); + limPostMlmAddBAReq(pMac, pSta, tid, pBaCandidate->baInfo[tid].startingSeqNum,psessionEntry); + } + } + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; +} + + +/** ------------------------------------------------------------- +\fn limDeleteBASessions +\brief Deletes all the exisitng BA sessions for given session + and BA direction. +\param tpAniSirGlobal pMac +\param tpPESession pSessionEntry +\param tANI_U32 baDirection +\return None +-------------------------------------------------------------*/ + +void +limDeleteBASessions(tpAniSirGlobal pMac, tpPESession pSessionEntry, + tANI_U32 baDirection) +{ + tANI_U32 i; + tANI_U8 tid; + tpDphHashNode pSta; + + if (NULL == pSessionEntry) + { + limLog(pMac, LOGE, FL("Session does not exist")); + } + else + { + for(tid = 0; tid < STACFG_MAX_TC; tid++) + { + if ((eLIM_AP_ROLE == pSessionEntry->limSystemRole) || + (pSessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) || + (eLIM_STA_IN_IBSS_ROLE == pSessionEntry->limSystemRole) || + (pSessionEntry->limSystemRole == eLIM_P2P_DEVICE_GO)) + { + for (i = 0; i < pMac->lim.maxStation; i++) + { + pSta = pSessionEntry->dph.dphHashTable.pDphNodeArray + i; + if (pSta && pSta->added) + { + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBATx) && + (baDirection & BA_INITIATOR)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, + eSIR_MAC_UNSPEC_FAILURE_REASON, + pSessionEntry); + } + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBARx) && + (baDirection & BA_RECIPIENT)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, + eSIR_MAC_UNSPEC_FAILURE_REASON, + pSessionEntry); + } + } + } + } + else if ((eLIM_STA_ROLE == pSessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == pSessionEntry->limSystemRole) || + (eLIM_P2P_DEVICE_ROLE == pSessionEntry->limSystemRole)) + { + pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, + &pSessionEntry->dph.dphHashTable); + if (pSta && pSta->added) + { + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBATx) && + (baDirection & BA_INITIATOR)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, + eSIR_MAC_UNSPEC_FAILURE_REASON, + pSessionEntry); + } + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBARx) && + (baDirection & BA_RECIPIENT)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, + eSIR_MAC_UNSPEC_FAILURE_REASON, + pSessionEntry); + } + } + } + } + } +} + +/** ------------------------------------------------------------- +\fn limDelAllBASessions +\brief Deletes all the exisitng BA sessions. +\param tpAniSirGlobal pMac +\return None +-------------------------------------------------------------*/ + +void limDelAllBASessions(tpAniSirGlobal pMac) +{ + tANI_U32 i; + tpPESession pSessionEntry; + + for (i = 0; i < pMac->lim.maxBssId; i++) + { + pSessionEntry = peFindSessionBySessionId(pMac, i); + if (pSessionEntry) + { + limDeleteBASessions(pMac, pSessionEntry, BA_BOTH_DIRECTIONS); + } + } +} + +/** ------------------------------------------------------------- +\fn limDelAllBASessionsBtc +\brief Deletes all the exisitng BA receipent sessions in 2.4GHz + band. +\param tpAniSirGlobal pMac +\return None +-------------------------------------------------------------*/ + +void limDelPerBssBASessionsBtc(tpAniSirGlobal pMac) +{ + tANI_U8 sessionId; + tpPESession pSessionEntry; + pSessionEntry = peFindSessionByBssid(pMac,pMac->btc.btcBssfordisableaggr, + &sessionId); + if (pSessionEntry) + { + PELOGW(limLog(pMac, LOGW, + "Deleting the BA for session %d as host got BTC event", sessionId);) + limDeleteBASessions(pMac, pSessionEntry, BA_RECIPIENT); + } +} + +/** ------------------------------------------------------------- +\fn limProcessDelTsInd +\brief handles the DeleteTS indication coming from HAL or generated by PE itself in some error cases. + Validates the request, sends the DelTs action frame to the Peer and sends DelTs indicatoin to HDD. +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\return None +-------------------------------------------------------------*/ +void +limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpDphHashNode pSta; + tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr); + tpSirDeltsReq pDelTsReq = NULL; + tSirMacAddr peerMacAddr; + tpSirDeltsReqInfo pDelTsReqInfo; + tpLimTspecInfo pTspecInfo; + tpPESession psessionEntry; + tANI_U8 sessionId; + +if((psessionEntry = peFindSessionByBssid(pMac,pDelTsParam->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given BssId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]); + if(pTspecInfo->inuse == false) + { + PELOGE(limLog(pMac, LOGE, FL("tspec entry with index %d is not in use"), pDelTsParam->tspecIdx);) + goto error1; + } + + pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable); + if(pSta == NULL) + { + limLog(pMac, LOGE, FL("Could not find entry in DPH table for assocId = %d"), + pTspecInfo->assocId); + goto error1; + } + + pDelTsReq = vos_mem_malloc(sizeof(tSirDeltsReq)); + if ( NULL == pDelTsReq ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + goto error1; + } + + vos_mem_set( (tANI_U8 *)pDelTsReq, sizeof(tSirDeltsReq), 0); + + if(pSta->wmeEnabled) + vos_mem_copy( &(pDelTsReq->req.tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE)); + else + vos_mem_copy( &(pDelTsReq->req.tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo)); + + + //validate the req + if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDelTsReq, peerMacAddr,psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed"));) + goto error2; + } + PELOG1(limLog(pMac, LOG1, "Sent DELTS request to station with " + "assocId = %d MacAddr = "MAC_ADDRESS_STR, + pDelTsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));) + + limSendDeltsReqActionFrame(pMac, peerMacAddr, pDelTsReq->req.wmeTspecPresent, &pDelTsReq->req.tsinfo, &pDelTsReq->req.tspec, + psessionEntry); + + // prepare and send an sme indication to HDD + pDelTsReqInfo = vos_mem_malloc(sizeof(tSirDeltsReqInfo)); + if ( NULL == pDelTsReqInfo ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + goto error3; + } + vos_mem_set( (tANI_U8 *)pDelTsReqInfo, sizeof(tSirDeltsReqInfo), 0); + + if(pSta->wmeEnabled) + vos_mem_copy( &(pDelTsReqInfo->tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE)); + else + vos_mem_copy( &(pDelTsReqInfo->tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo)); + + limSendSmeDeltsInd(pMac, pDelTsReqInfo, pDelTsReq->aid,psessionEntry); + +error3: + vos_mem_free(pDelTsReqInfo); +error2: + vos_mem_free(pDelTsReq); +error1: + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; +} + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limPostMlmAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pStaDs DPH Hash Node object of peer STA + * + * \param tid TID for which a BA is being setup. + * If this is set to 0xFFFF, then we retrieve + * the default TID from the CFG + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpLimMlmAddBAReq pMlmAddBAReq = NULL; + tpDialogueToken dialogueTokenNode; + tANI_U32 val = 0; + + // Check if the peer is a 11n capable STA + // FIXME - Need a 11n peer indication in DPH. + // For now, using the taurusPeer attribute + //if( 0 == pStaDs->taurusPeer == ) + //return eSIR_SUCCESS; + + // Allocate for LIM_MLM_ADDBA_REQ + pMlmAddBAReq = vos_mem_malloc(sizeof( tLimMlmAddBAReq )); + if ( NULL == pMlmAddBAReq ) + { + limLog( pMac, LOGP, FL("AllocateMemory failed")); + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmAddBAReq, sizeof( tLimMlmAddBAReq ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmAddBAReq->peerMacAddr, + pStaDs->staAddr, + sizeof( tSirMacAddr )); + + // Update the TID + pMlmAddBAReq->baTID = tid; + + // Determine the supported BA policy of local STA + // for the TID of interest + pMlmAddBAReq->baPolicy = (pStaDs->baPolicyFlag >> tid) & 0x1; + + // BA Buffer Size + // Requesting the ADDBA recipient to populate the size. + // If ADDBA is accepted, a non-zero buffer size should + // be returned in the ADDBA Rsp + if ((TRUE == psessionEntry->isCiscoVendorAP) && + (eHT_CHANNEL_WIDTH_80MHZ != pStaDs->htSupportedChannelWidthSet)) + { + /* Cisco AP has issues in receiving more than 25 "mpdu in ampdu" + causing very low throughput in HT40 case */ + limLog( pMac, LOGW, + FL( "Requesting ADDBA with Cisco 1225 AP, window size 25")); + pMlmAddBAReq->baBufferSize = MAX_BA_WINDOW_SIZE_FOR_CISCO; + } + else + pMlmAddBAReq->baBufferSize = 0; + + limLog( pMac, LOGW, + FL( "Requesting an ADDBA to setup a %s BA session with STA %d for TID %d" ), + (pMlmAddBAReq->baPolicy ? "Immediate": "Delayed"), + pStaDs->staIndex, + tid ); + + // BA Timeout + if (wlan_cfgGetInt(pMac, WNI_CFG_BA_TIMEOUT, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not retrieve BA TIME OUT Param CFG")); + status = eSIR_FAILURE; + goto returnFailure; + } + pMlmAddBAReq->baTimeout = val; // In TU's + + // ADDBA Failure Timeout + // FIXME_AMPDU - Need to retrieve this from CFG. + //right now we are not checking for response timeout. so this field is dummy just to be compliant with the spec. + pMlmAddBAReq->addBAFailureTimeout = 2000; // In TU's + + // BA Starting Sequence Number + pMlmAddBAReq->baSSN = startingSeqNum; + + /* Update PE session Id*/ + pMlmAddBAReq->sessionId = psessionEntry->peSessionId; + + LIM_SET_STA_BA_STATE(pStaDs, tid, eLIM_BA_STATE_WT_ADD_RSP); + + dialogueTokenNode = limAssignDialogueToken(pMac); + if (NULL == dialogueTokenNode) + { + limLog(pMac, LOGE, FL("could not assign dialogue token")); + status = eSIR_FAILURE; + goto returnFailure; + } + + pMlmAddBAReq->baDialogToken = dialogueTokenNode->token; + //set assocId and tid information in the lim linked list + dialogueTokenNode->assocId = pStaDs->assocId; + dialogueTokenNode->tid = tid; + // Send ADDBA Req to MLME + limPostMlmMessage( pMac, + LIM_MLM_ADDBA_REQ, + (tANI_U32 *) pMlmAddBAReq ); + return eSIR_SUCCESS; + +returnFailure: + vos_mem_free(pMlmAddBAReq); + return status; +} + +/** + * \brief Post LIM_MLM_ADDBA_RSP to MLME. MLME + * will then send an ADDBA Rsp to peer MAC entity + * with the appropriate ADDBA status code + * + * \sa limPostMlmAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param peerMacAddr MAC address of peer entity that will + * be the recipient of this ADDBA Rsp + * + * \param baStatusCode ADDBA Rsp status code + * + * \param baDialogToken ADDBA Rsp dialog token + * + * \param baTID TID of interest + * + * \param baPolicy The BA policy + * + * \param baBufferSize The BA buffer size + * + * \param baTimeout BA timeout in TU's + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirMacStatusCodes baStatusCode, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tpPESession psessionEntry) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmAddBARsp pMlmAddBARsp; + + // Allocate for LIM_MLM_ADDBA_RSP + pMlmAddBARsp = vos_mem_malloc(sizeof( tLimMlmAddBARsp )); + if ( NULL == pMlmAddBARsp ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed with error code %d"), + status ); + + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmAddBARsp, sizeof( tLimMlmAddBARsp ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmAddBARsp->peerMacAddr, + peerMacAddr, + sizeof( tSirMacAddr )); + + pMlmAddBARsp->baDialogToken = baDialogToken; + pMlmAddBARsp->addBAResultCode = baStatusCode; + pMlmAddBARsp->baTID = baTID; + pMlmAddBARsp->baPolicy = baPolicy; + pMlmAddBARsp->baBufferSize = baBufferSize; + pMlmAddBARsp->baTimeout = baTimeout; + + /* UPdate PE session ID*/ + pMlmAddBARsp->sessionId = psessionEntry->peSessionId; + + // Send ADDBA Rsp to MLME + limPostMlmMessage( pMac, + LIM_MLM_ADDBA_RSP, + (tANI_U32 *) pMlmAddBARsp ); + +returnFailure: + + return status; +} + +/** + * \brief Post LIM_MLM_DELBA_REQ to MLME. MLME + * will then send an DELBA Ind to peer MAC entity + * with the appropriate DELBA status code + * + * \sa limPostMlmDelBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta DPH Hash Node object of peer MAC entity + * for which the BA session is being deleted + * + * \param baDirection DELBA direction + * + * \param baTID TID for which the BA session is being deleted + * + * \param baReasonCode DELBA Req reason code + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDirection, + tANI_U8 baTID, + tSirMacReasonCodes baReasonCode, + tpPESession psessionEntry) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmDelBAReq pMlmDelBAReq; +tLimBAState curBaState; + +if(NULL == pSta) + return eSIR_FAILURE; + +LIM_GET_STA_BA_STATE(pSta, baTID, &curBaState); + + // Need to validate the current BA State. + if( eLIM_BA_STATE_IDLE != curBaState) + { + limLog( pMac, LOGE, + FL( "Received unexpected DELBA REQ when STA BA state for tid = %d is %d" ), + baTID, + curBaState); + + status = eSIR_FAILURE; + goto returnFailure; + } + + // Allocate for LIM_MLM_DELBA_REQ + pMlmDelBAReq = vos_mem_malloc(sizeof( tLimMlmDelBAReq )); + if ( NULL == pMlmDelBAReq ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed with error code %d"), + status ); + + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmDelBAReq, sizeof( tLimMlmDelBAReq ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmDelBAReq->peerMacAddr, + pSta->staAddr, + sizeof( tSirMacAddr )); + + pMlmDelBAReq->baDirection = baDirection; + pMlmDelBAReq->baTID = baTID; + pMlmDelBAReq->delBAReasonCode = baReasonCode; + + /* Update PE session ID*/ + pMlmDelBAReq->sessionId = psessionEntry->peSessionId; + + //we don't have valid BA session for the given direction. + // HDD wants to get the BA session deleted on PEER in this case. + // in this case we just need to send DelBA to the peer. + if(((eBA_RECIPIENT == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBARx)) || + ((eBA_INITIATOR == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBATx))) + { + // Send DELBA Ind over the air + if( eSIR_SUCCESS != + (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry))) + status = eSIR_FAILURE; + + vos_mem_free(pMlmDelBAReq); + return status; + } + + + // Update the BA state in STA + LIM_SET_STA_BA_STATE(pSta, pMlmDelBAReq->baTID, eLIM_BA_STATE_WT_DEL_RSP); + + // Send DELBA Req to MLME + limPostMlmMessage( pMac, + LIM_MLM_DELBA_REQ, + (tANI_U32 *) pMlmDelBAReq ); + +returnFailure: + + return status; +} + +/** + * \brief Send WDA_ADDBA_REQ to HAL, in order + * to setup a new BA session with a peer + * + * \sa limPostMsgAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \param baDialogToken The Action Frame dialog token + * + * \param baTID TID for which the BA session is being setup + * + * \param baPolicy BA Policy + * + * \param baBufferSize The requested BA buffer size + * + * \param baTimeout BA Timeout. 0 indicates no BA timeout enforced + * + * \param baSSN Starting Sequence Number for this BA session + * + * \param baDirection BA Direction: 1 - Initiator, 0 - Recipient + * + * \return none + * + */ +tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tANI_U16 baSSN, + tANI_U8 baDirection, + tpPESession psessionEntry) +{ +tpAddBAParams pAddBAParams = NULL; +tSirRetStatus retCode = eSIR_SUCCESS; +tSirMsgQ msgQ; + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // we can only do BA on "hard" STAs + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + retCode = eHAL_STATUS_FAILURE; + goto returnFailure; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + // Allocate for WDA_ADDBA_REQ + pAddBAParams = vos_mem_malloc(sizeof( tAddBAParams )); + if ( NULL == pAddBAParams ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed") + ); + + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pAddBAParams, sizeof( tAddBAParams ), 0); + + // Copy the peer MAC address + vos_mem_copy( + (void *) pAddBAParams->peerMacAddr, + (void *) pSta->staAddr, + sizeof( tSirMacAddr )); + + // Populate the REQ parameters + pAddBAParams->staIdx = pSta->staIndex; + pAddBAParams->baDialogToken = baDialogToken; + pAddBAParams->baTID = baTID; + pAddBAParams->baPolicy = baPolicy; + pAddBAParams->baBufferSize = baBufferSize; + pAddBAParams->baTimeout = baTimeout; + pAddBAParams->baSSN = baSSN; + pAddBAParams->baDirection = baDirection; + pAddBAParams->respReqd = 1; + + /* UPdate PE session ID */ + pAddBAParams->sessionId = psessionEntry->peSessionId; + + // Post WDA_ADDBA_REQ to HAL. + msgQ.type = WDA_ADDBA_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddBAParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_ADDBA_REQ..." )); + + //defer any other message until we get response back. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + limLog( pMac, LOGE, + FL("Posting WDA_ADDBA_REQ to HAL failed! Reason = %d"), + retCode ); + else + return retCode; + +returnFailure: + + // Clean-up... + if( NULL != pAddBAParams ) + vos_mem_free( pAddBAParams ); + + return retCode; + +} + +/** + * \brief Send WDA_DELBA_IND to HAL, in order + * to delete an existing BA session with peer + * + * \sa limPostMsgDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \param baTID TID for which the BA session is being setup + * + * \param baDirection Identifies whether the DELBA Ind was + * sent by the BA initiator or recipient + * + * \return none + * + */ +tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baTID, + tANI_U8 baDirection, + tpPESession psessionEntry) +{ +tpDelBAParams pDelBAParams = NULL; +tSirRetStatus retCode = eSIR_SUCCESS; +tSirMsgQ msgQ; + + // Allocate for SIR_HAL_DELBA_IND + pDelBAParams = vos_mem_malloc(sizeof( tDelBAParams )); + if ( NULL == pDelBAParams ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed") + ); + + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pDelBAParams, sizeof( tDelBAParams ), 0); + + // Populate the REQ parameters + pDelBAParams->staIdx = pSta->staIndex; + pDelBAParams->baTID = baTID; + pDelBAParams->baDirection = baDirection; + + /* Update PE session ID */ + + + //TBD-RAJESH Updating of the session ID is requird for SIR_HAL_DELBA_IND????? + //pDelBAParams->sessionId = psessionEntry->peSessionId; + + // Post WDA_DELBA_IND to HAL. + msgQ.type = WDA_DELBA_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pDelBAParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending SIR_HAL_DELBA_IND..." )); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_DELBA_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + limLog( pMac, LOGE, + FL("Posting WDA_DELBA_IND to HAL failed! Reason = %d"), + retCode ); + else + { + // Update LIM's internal cache... + if( eBA_INITIATOR == baDirection) + { + pSta->tcCfg[baTID].fUseBATx = 0; + pSta->tcCfg[baTID].txBufSize = 0; + } + else + { + pSta->tcCfg[baTID].fUseBARx = 0; + pSta->tcCfg[baTID].rxBufSize = 0; + } + + return retCode; + } + +returnFailure: + + // Clean-up... + if( NULL != pDelBAParams ) + vos_mem_free( pDelBAParams ); + + return retCode; + +} + +/** + * @function : limPostSMStateUpdate() + * + * @brief : This function Updates the HAL and Softmac about the change in the STA's SMPS state. + * + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Lim Message structure object with the MimoPSparam in body + * @return None + */ +tSirRetStatus +limPostSMStateUpdate(tpAniSirGlobal pMac, + tANI_U16 staIdx, tSirMacHTMIMOPowerSaveState state, + tANI_U8 *pPeerStaMac, tANI_U8 sessionId) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpSetMIMOPS pMIMO_PSParams; + + msgQ.reserved = 0; + msgQ.type = WDA_SET_MIMOPS_REQ; + + // Allocate for WDA_SET_MIMOPS_REQ + pMIMO_PSParams = vos_mem_malloc(sizeof(tSetMIMOPS)); + if ( NULL == pMIMO_PSParams ) + { + limLog( pMac, LOGP,FL(" AllocateMemory failed")); + return eSIR_MEM_ALLOC_FAILED; + } + + pMIMO_PSParams->htMIMOPSState = state; + pMIMO_PSParams->staIdx = staIdx; + pMIMO_PSParams->fsendRsp = true; + pMIMO_PSParams->sessionId = sessionId; + vos_mem_copy(pMIMO_PSParams->peerMac, pPeerStaMac, + sizeof( tSirMacAddr )); + + msgQ.bodyptr = pMIMO_PSParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG2, FL( "Sending WDA_SET_MIMOPS_REQ..." )); + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if (eSIR_SUCCESS != retCode) + { + limLog( pMac, LOGP, FL("Posting WDA_SET_MIMOPS_REQ to HAL failed! Reason = %d"), retCode ); + vos_mem_free(pMIMO_PSParams); + return retCode; + } + + return retCode; +} + +void limPktFree ( + tpAniSirGlobal pMac, + eFrameType frmType, + tANI_U8 *pRxPacketInfo, + void *pBody) +{ + (void) pMac; (void) frmType; (void) pRxPacketInfo; (void) pBody; +} + +/** + * limGetBDfromRxPacket() + * + *FUNCTION: + * This function is called to get pointer to Polaris + * Buffer Descriptor containing MAC header & other control + * info from the body of the message posted to LIM. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param body - Received message body + * @param pRxPacketInfo - Pointer to received BD + * @return None + */ + +void +limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pRxPacketInfo) +{ + *pRxPacketInfo = (tANI_U32 *) body; +} /*** end limGetBDfromRxPacket() ***/ + + + + + +void limRessetScanChannelInfo(tpAniSirGlobal pMac) +{ + vos_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0); +} + + +void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId) +{ + tANI_U8 i; + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + + for(i = 0; i < pMac->lim.scanChnInfo.numChnInfo; i++) + { + if(pMac->lim.scanChnInfo.scanChn[i].channelId == channelId) + { + pMac->lim.scanChnInfo.scanChn[i].numTimeScan++; + fFound = eANI_BOOLEAN_TRUE; + break; + } + } + if(eANI_BOOLEAN_FALSE == fFound) + { + if(pMac->lim.scanChnInfo.numChnInfo < SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo].channelId = channelId; + pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo++].numTimeScan = 1; + } + else + { + PELOGW(limLog(pMac, LOGW, FL(" -- number of channels exceed mac"));) + } + } +} + + +/** + * @function : limIsChannelValidForChannelSwitch() + * + * @brief : This function checks if the channel to which AP + * is expecting us to switch, is a valid channel for us. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param channel - New channel to which we are expected to move + * @return None + */ +tAniBool +limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U8 index; + tANI_U32 validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + (tANI_U8 *)validChannelList, + (tANI_U32 *)&validChannelListLen) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));) + return (eSIR_FALSE); + } + + for(index = 0; index < validChannelListLen; index++) + { + if(validChannelList[index] == channel) + return (eSIR_TRUE); + } + + /* channel does not belong to list of valid channels */ + return (eSIR_FALSE); +} + +/**------------------------------------------------------ +\fn __limFillTxControlParams +\brief Fill the message for stopping/resuming tx. + +\param pMac +\param pTxCtrlMsg - Pointer to tx control message. +\param type - Which way we want to stop/ resume tx. +\param mode - To stop/resume. + -------------------------------------------------------*/ +static eHalStatus +__limFillTxControlParams(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg, + tLimQuietTxMode type, tLimControlTx mode) +{ + + //TBD-RAJESH HOW TO GET sessionEntry????? + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + + if (mode == eLIM_STOP_TX) + pTxCtrlMsg->stopTx = eANI_BOOLEAN_TRUE; + else + pTxCtrlMsg->stopTx = eANI_BOOLEAN_FALSE; + + switch (type) + { + case eLIM_TX_ALL: + /** Stops/resumes transmission completely */ + pTxCtrlMsg->fCtrlGlobal = 1; + break; + + case eLIM_TX_BSS_BUT_BEACON: + /** Stops/resumes transmission on a particular BSS. Stopping BSS, doesnt + * stop beacon transmission. + */ + pTxCtrlMsg->ctrlBss = 1; + pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx); + break; + + case eLIM_TX_STA: + /** Memory for station bitmap is allocated dynamically in caller of this + * so decode properly here and fill the bitmap. Now not implemented, + * fall through. + */ + case eLIM_TX_BSS: + //Fall thru... + default: + PELOGW(limLog(pMac, LOGW, FL("Invalid case: Not Handled"));) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/** + * @function : limFrameTransmissionControl() + * + * @brief : This API is called by the user to halt/resume any frame + * transmission from the device. If stopped, all frames will be + * queued starting from hardware. Then back-pressure + * is built till the driver. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ +void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpTxControlParams pTxCtrlMsg; + tSirMsgQ msgQ; + tANI_U8 nBytes = 0; // No of bytes required for station bitmap. + + /** Allocate only required number of bytes for station bitmap + * Make it to align to 4 byte boundary */ + nBytes = (tANI_U8)HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation); + + pTxCtrlMsg = vos_mem_malloc(sizeof(*pTxCtrlMsg) + nBytes); + if ( NULL == pTxCtrlMsg ) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return; + } + + vos_mem_set((void *) pTxCtrlMsg, + (sizeof(*pTxCtrlMsg) + nBytes), 0); + status = __limFillTxControlParams(pMac, pTxCtrlMsg, type, mode); + if (status != eHAL_STATUS_SUCCESS) + { + vos_mem_free(pTxCtrlMsg); + limLog(pMac, LOGP, FL("__limFillTxControlParams failed, status = %d"), status); + return; + } + + msgQ.bodyptr = (void *) pTxCtrlMsg; + msgQ.bodyval = 0; + msgQ.reserved = 0; + msgQ.type = WDA_TRANSMISSION_CONTROL_IND; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if(wdaPostCtrlMsg( pMac, &msgQ) != eSIR_SUCCESS) + { + vos_mem_free(pTxCtrlMsg); + limLog( pMac, LOGP, FL("Posting Message to HAL failed")); + return; + } + + if (mode == eLIM_STOP_TX) + { + PELOG1(limLog(pMac, LOG1, FL("Stopping the transmission of all packets, indicated softmac"));) + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Resuming the transmission of all packets, indicated softmac"));) + } + return; +} + + +/** + * @function : limRestorePreChannelSwitchState() + * + * @brief : This API is called by the user to undo any + * specific changes done on the device during + * channel switch. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +tSirRetStatus +limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 val = 0; + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return retCode; + + /* Channel switch should be ready for the next time */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT; + + /* Restore the frame transmission, all the time. */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + + /* Free to enter BMPS */ + limSendSmePostChannelSwitchInd(pMac); + + //Background scan is now enabled by SME + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + /* Enable background scan if already enabled, else don't bother */ + if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val)) != eSIR_SUCCESS) + + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + return (retCode); + } + + if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_BACKGROUND_SCAN_TIMER)); + if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP")); + return (eSIR_FAILURE); + } + + } + } + + /* Enable heartbeat timer */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if((limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP")); + return (eSIR_FAILURE); + } + } + return (retCode); +} + + +/**-------------------------------------------- +\fn limRestorePreQuietState +\brief Restore the pre quiet state + +\param pMac +\return NONE +---------------------------------------------*/ +tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 val = 0; + + if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE) + return retCode; + + /* Quiet should be ready for the next time */ + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + /* Restore the frame transmission, all the time. */ + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + + + //Background scan is now enabled by SME + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + /* Enable background scan if already enabled, else don't bother */ + if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val)) != eSIR_SUCCESS) + + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + return (retCode); + } + + if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_BACKGROUND_SCAN_TIMER)); + if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP")); + return (eSIR_FAILURE); + } + + } + } + + /* Enable heartbeat timer */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if(limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP")); + return (eSIR_FAILURE); + } + } + return (retCode); +} + + +/** + * @function: limPrepareFor11hChannelSwitch() + * + * @brief : This API is called by the user to prepare for + * 11h channel switch. As of now, the API does + * very minimal work. User can add more into the + * same API if needed. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry + * @return None + */ +void +limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + /* Flag to indicate 11h channel switch in progress */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + + /* Disable, Stop background scan if enabled and running */ + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + /* Stop heart-beat timer to stop heartbeat disassociation */ + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + + if(pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE || + pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE) + { + PELOGE(limLog(pMac, LOG1, FL("Posting finish scan as we are in scan state"));) + /* Stop ongoing scanning if any */ + if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) + { + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + else + { + limRestorePreChannelSwitchState(pMac, psessionEntry); + } + return; + } + else + { + PELOGE(limLog(pMac, LOG1, FL("Not in scan state, start channel switch timer"));) + /** We are safe to switch channel at this point */ + limStopTxAndSwitchChannel(pMac, psessionEntry->peSessionId); + } +} + + + +/**---------------------------------------------------- +\fn limGetNwType + +\brief Get type of the network from data packet or beacon +\param pMac +\param channelNum - Channel number +\param type - Type of packet. +\param pBeacon - Pointer to beacon or probe response + +\return Network type a/b/g. +-----------------------------------------------------*/ +tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon) +{ + tSirNwType nwType = eSIR_11B_NW_TYPE; + + if (type == SIR_MAC_DATA_FRAME) + { + if ((channelNum > 0) && (channelNum < 15)) + { + nwType = eSIR_11G_NW_TYPE; + } + else + { + nwType = eSIR_11A_NW_TYPE; + } + } + else + { + if ((channelNum > 0) && (channelNum < 15)) + { + int i; + // 11b or 11g packet + // 11g iff extended Rate IE is present or + // if there is an A rate in suppRate IE + for (i = 0; i < pBeacon->supportedRates.numRates; i++) + { + if (sirIsArate(pBeacon->supportedRates.rate[i] & 0x7f)) + { + nwType = eSIR_11G_NW_TYPE; + break; + } + } + if (pBeacon->extendedRatesPresent) + { + PELOG3(limLog(pMac, LOG3, FL("Beacon, nwtype=G"));) + nwType = eSIR_11G_NW_TYPE; + } + } + else + { + // 11a packet + PELOG3(limLog(pMac, LOG3,FL("Beacon, nwtype=A"));) + nwType = eSIR_11A_NW_TYPE; + } + } + return nwType; +} + + +/**--------------------------------------------------------- +\fn limGetChannelFromBeacon +\brief To extract channel number from beacon + +\param pMac +\param pBeacon - Pointer to beacon or probe rsp +\return channel number +-----------------------------------------------------------*/ +tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon) +{ + tANI_U8 channelNum = 0; + + if (pBeacon->dsParamsPresent) + channelNum = pBeacon->channelNumber; + else if(pBeacon->HTInfo.present) + channelNum = pBeacon->HTInfo.primaryChannel; + else + channelNum = pBeacon->channelNumber; + + return channelNum; +} + + +/** --------------------------------------------------------- +\fn limSetTspecUapsdMask +\brief This function sets the PE global variable: +\ 1) gUapsdPerAcTriggerEnableMask and +\ 2) gUapsdPerAcDeliveryEnableMask +\ based on the user priority field and direction field +\ in the TS Info Fields. +\ +\ An AC is a trigger-enabled AC if the PSB subfield +\ is set to 1 in the uplink direction. +\ An AC is a delivery-enabled AC if the PSB subfield +\ is set to 1 in the down-link direction. +\ +\param tpAniSirGlobal pMac +\param tSirMacTSInfo pTsInfo +\param tANI_U32 action +\return None + ------------------------------------------------------------*/ +void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action) +{ + tANI_U8 userPrio = (tANI_U8)pTsInfo->traffic.userPrio; + tANI_U16 direction = pTsInfo->traffic.direction; + tANI_U8 ac = upToAc(userPrio); + + PELOG1(limLog(pMac, LOG1, FL(" Set UAPSD mask for AC %d, direction %d, action=%d (1=set,0=clear) "),ac, direction, action );) + + /* Converting AC to appropriate Uapsd Bit Mask + * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3) + * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2) + * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1) + * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0) + */ + ac = ((~ac) & 0x3); + + if (action == CLEAR_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + } + } + else if (action == SET_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac); + pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac); + } + } + + limLog(pMac, LOG1, FL("New pMac->lim.gUapsdPerAcTriggerEnableMask = 0x%x "), pMac->lim.gUapsdPerAcTriggerEnableMask ); + limLog(pMac, LOG1, FL("New pMac->lim.gUapsdPerAcDeliveryEnableMask = 0x%x "), pMac->lim.gUapsdPerAcDeliveryEnableMask ); + + return; +} + +void limSetTspecUapsdMaskPerSession(tpAniSirGlobal pMac, + tpPESession psessionEntry, tSirMacTSInfo *pTsInfo, tANI_U32 action) +{ + tANI_U8 userPrio = (tANI_U8)pTsInfo->traffic.userPrio; + tANI_U16 direction = pTsInfo->traffic.direction; + tANI_U8 ac = upToAc(userPrio); + + PELOG1(limLog(pMac, LOG1, FL("Set UAPSD mask for AC %d, dir %d, action=%d") + ,ac, direction, action );) + + /* Converting AC to appropriate Uapsd Bit Mask + * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3) + * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2) + * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1) + * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0) + */ + ac = ((~ac) & 0x3); + + if (action == CLEAR_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + psessionEntry->gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + psessionEntry->gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + psessionEntry->gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + } + } + else if (action == SET_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + psessionEntry->gUapsdPerAcTriggerEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + psessionEntry->gUapsdPerAcDeliveryEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + psessionEntry->gUapsdPerAcTriggerEnableMask |= (1 << ac); + psessionEntry->gUapsdPerAcDeliveryEnableMask |= (1 << ac); + } + } + + limLog(pMac, LOG1, + FL("New psessionEntry->gUapsdPerAcTriggerEnableMask = 0x%x "), + psessionEntry->gUapsdPerAcTriggerEnableMask ); + limLog(pMac, LOG1, + FL("New psessionEntry->gUapsdPerAcDeliveryEnableMask = 0x%x "), + psessionEntry->gUapsdPerAcDeliveryEnableMask ); + + return; +} + +void limHandleHeartBeatTimeout(tpAniSirGlobal pMac ) +{ + + tANI_U8 i; + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if(pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE) + { + limIbssHeartBeatHandle(pMac,&pMac->lim.gpSession[i]); + break; + } + + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + limHandleHeartBeatFailure(pMac,&pMac->lim.gpSession[i]); + } + } + } + for(i=0; i< pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + if(pMac->lim.gpSession[i].LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + /* Activate Probe After HeartBeat Timer incase HB Failure detected */ + PELOGW(limLog(pMac, LOGW,FL("Sending Probe for Session: %d"), + i);) + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PROBE_AFTER_HB_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to re-activate Probe-after-heartbeat timer")); + limReactivateHeartBeatTimer(pMac, &pMac->lim.gpSession[i]); + } + break; + } + } + } + } +} + +void limHandleHeartBeatTimeoutForSession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if(psessionEntry->valid == TRUE ) + { + if(psessionEntry->bssType == eSIR_IBSS_MODE) + { + limIbssHeartBeatHandle(pMac,psessionEntry); + } + if((psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) && + (psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + limHandleHeartBeatFailure(pMac,psessionEntry); + } + } + /* In the function limHandleHeartBeatFailure things can change so check for the session entry valid + and the other things again */ + if(psessionEntry->valid == TRUE ) + { + if((psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) && + (psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + if(psessionEntry->LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + /* Activate Probe After HeartBeat Timer incase HB Failure detected */ + PELOGW(limLog(pMac, LOGW,FL("Sending Probe for Session: %d"), + psessionEntry->bssIdx);) + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PROBE_AFTER_HB_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to re-activate Probe-after-heartbeat timer")); + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + } + } +} + + +tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + return pMac->lim.gpSession[i].currentOperChannel; + } + } + } + return 0; +} + +void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + tpPESession psessionEntry; + tpAddStaParams pAddStaParams; + + pAddStaParams = (tpAddStaParams)limMsgQ->bodyptr; + + if((psessionEntry = peFindSessionBySessionId(pMac,pAddStaParams->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + vos_mem_free(pAddStaParams); + return; + } + psessionEntry->csaOffloadEnable = pAddStaParams->csaOffloadEnable; + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + (void) limIbssAddStaRsp(pMac, limMsgQ->bodyptr,psessionEntry); +#ifdef FEATURE_WLAN_TDLS + else if(pMac->lim.gLimAddStaTdls) + { + limProcessTdlsAddStaRsp(pMac, limMsgQ->bodyptr, psessionEntry) ; + pMac->lim.gLimAddStaTdls = FALSE ; + } +#endif + else + limProcessMlmAddStaRsp(pMac, limMsgQ,psessionEntry); + +} + + +void limUpdateBeacon(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if( ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE) ) + && (eLIM_SME_NORMAL_STATE == pMac->lim.gpSession[i].limSmeState) + ) + { + schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]); + if (VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + { + limSendBeaconInd(pMac, &pMac->lim.gpSession[i]); + } + } + else + { + if( (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + + if(pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF) + { + schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]); + } + } + } + } + } +} + +void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tpPESession psessionEntry; + /* Probe response is not received after HB failure. This is handled by LMM sub module. */ + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + psessionEntry = &pMac->lim.gpSession[i]; + if(psessionEntry->LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + limLog(pMac, LOGE, FL("Probe_hb_failure: SME %d, MLME %d, HB-Count %d"),psessionEntry->limSmeState, + psessionEntry->limMlmState, psessionEntry->LimRxedBeaconCntDuringHB); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HB_FAILURE_TIMEOUT, psessionEntry, 0, 0); +#endif + if (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + if ((!LIM_IS_CONNECTION_ACTIVE(psessionEntry))&& + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + limLog(pMac, LOGE, FL("Probe_hb_failure: for session:%d " ),psessionEntry->peSessionId); + /* AP did not respond to Probe Request. Tear down link with it.*/ + limTearDownLinkWithAp(pMac, + psessionEntry->peSessionId, + eSIR_BEACON_MISSED); + pMac->lim.gLimProbeFailureAfterHBfailedCnt++ ; + } + else // restart heartbeat timer + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + else + { + limLog(pMac, LOGE, FL("Unexpected wt-probe-timeout in state ")); + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + + } + } + } + /* Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer, need not deactivate the timer */ + // tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer); +} + + +/* +* This function assumes there will not be more than one IBSS session active at any time. +*/ +tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE)) + return (&pMac->lim.gpSession[i]); + } + + return NULL; +} + +tpPESession limIsApSessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if( (pMac->lim.gpSession[i].valid) && + ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE))) + return (&pMac->lim.gpSession[i]); + } + + return NULL; +} + +/**--------------------------------------------------------- +\fn limHandleDeferMsgError +\brief handles error scenario, when the msg can not be deferred. +\param pMac +\param pLimMsg LIM msg, which could not be deferred. +\return void +-----------------------------------------------------------*/ + +void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg) +{ + if(SIR_BB_XPORT_MGMT_MSG == pLimMsg->type) + { + vos_pkt_return_packet((vos_pkt_t*)pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + else if(pLimMsg->bodyptr != NULL) + { + vos_mem_free(pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + +} + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/**--------------------------------------------------------- +\fn limDiagEventReport +\brief This function reports Diag event +\param pMac +\param eventType +\param bssid +\param status +\param reasonCode +\return void +-----------------------------------------------------------*/ +void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode) +{ + tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 }; + WLAN_VOS_DIAG_EVENT_DEF(peEvent, vos_event_wlan_pe_payload_type); + + vos_mem_set(&peEvent, sizeof(vos_event_wlan_pe_payload_type), 0); + + if (NULL == pSessionEntry) + { + vos_mem_copy( peEvent.bssid, nullBssid, sizeof(tSirMacAddr)); + peEvent.sme_state = (tANI_U16)pMac->lim.gLimSmeState; + peEvent.mlm_state = (tANI_U16)pMac->lim.gLimMlmState; + + } + else + { + vos_mem_copy(peEvent.bssid, pSessionEntry->bssId, sizeof(tSirMacAddr)); + peEvent.sme_state = (tANI_U16)pSessionEntry->limSmeState; + peEvent.mlm_state = (tANI_U16)pSessionEntry->limMlmState; + } + peEvent.event_type = eventType; + peEvent.status = status; + peEvent.reason_code = reasonCode; + + WLAN_VOS_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE); + return; +} + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + + tpAddStaSelfParams pAddStaSelfParams; + tSirMsgQ mmhMsg; + tpSirSmeAddStaSelfRsp pRsp; + + + pAddStaSelfParams = (tpAddStaSelfParams)limMsgQ->bodyptr; + + pRsp = vos_mem_malloc(sizeof(tSirSmeAddStaSelfRsp)); + if ( NULL == pRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for Add Sta self RSP")); + vos_mem_free(pAddStaSelfParams); + limMsgQ->bodyptr = NULL; + return; + } + + vos_mem_set((tANI_U8*)pRsp, sizeof(tSirSmeAddStaSelfRsp), 0); + + pRsp->mesgType = eWNI_SME_ADD_STA_SELF_RSP; + pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeAddStaSelfRsp); + pRsp->status = pAddStaSelfParams->status; + + vos_mem_copy( pRsp->selfMacAddr, pAddStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) ); + + vos_mem_free(pAddStaSelfParams); + limMsgQ->bodyptr = NULL; + + mmhMsg.type = eWNI_SME_ADD_STA_SELF_RSP; + mmhMsg.bodyptr = pRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + +void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + + tpDelStaSelfParams pDelStaSelfParams; + tSirMsgQ mmhMsg; + tpSirSmeDelStaSelfRsp pRsp; + + + pDelStaSelfParams = (tpDelStaSelfParams)limMsgQ->bodyptr; + + pRsp = vos_mem_malloc(sizeof(tSirSmeDelStaSelfRsp)); + if ( NULL == pRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for Add Sta self RSP")); + vos_mem_free(pDelStaSelfParams); + limMsgQ->bodyptr = NULL; + return; + } + + vos_mem_set((tANI_U8*)pRsp, sizeof(tSirSmeDelStaSelfRsp), 0); + + pRsp->mesgType = eWNI_SME_DEL_STA_SELF_RSP; + pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeDelStaSelfRsp); + pRsp->status = pDelStaSelfParams->status; + + vos_mem_copy( pRsp->selfMacAddr, pDelStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) ); + + vos_mem_free(pDelStaSelfParams); + limMsgQ->bodyptr = NULL; + + mmhMsg.type = eWNI_SME_DEL_STA_SELF_RSP; + mmhMsg.bodyptr = pRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + +/*************************************************************** +* tANI_U8 limUnmapChannel(tANI_U8 mapChannel) +* To unmap the channel to reverse the effect of mapping +* a band channel in hal .Mapping was done hal to overcome the +* limitation of the rxbd which use only 4 bit for channel number. +*****************************************************************/ +tANI_U8 limUnmapChannel(tANI_U8 mapChannel) +{ + return WDA_MapChannel(mapChannel); +} + + +v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field) +{ + int left = length; + v_U8_t *ptr = pIes; + v_U8_t elem_id; + v_U16_t elem_len; + + while(left >= (size_of_len_field+1)) + { + elem_id = ptr[0]; + if (size_of_len_field == TWO_BYTE) + { + elem_len = ((v_U16_t) ptr[1]) | (ptr[2]<<8); + } + else + { + elem_len = ptr[1]; + } + + + left -= (size_of_len_field+1); + if(elem_len > left) + { + limLog(pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + (size_of_len_field+1)); + } + return NULL; +} + +/* return NULL if oui is not found in ie + return !NULL pointer to vendor IE (starting from 0xDD) if oui is found + */ +v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len) +{ + int left = ie_len; + v_U8_t *ptr = ie; + v_U8_t elem_id, elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + return NULL; + } + if (SIR_MAC_EID_VENDOR == elem_id) + { + if(memcmp(&ptr[2], oui, oui_size)==0) + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +//Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream + +v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len) +{ + int length = 0; + tANI_U8 *ptr = ie; + + ptr[length++] = SIR_MAC_EID_VENDOR; + ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE; + vos_mem_copy(&ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); + vos_mem_copy(&ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len); + return (ie_len + SIR_P2P_IE_HEADER_LEN); +} + +//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream + +v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen) +{ + v_U8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN]; + + if ((noaLen <= (SIR_MAX_NOA_ATTR_LEN+SIR_P2P_IE_HEADER_LEN)) && + (noaLen >= overFlowLen) && (overFlowLen <= SIR_MAX_NOA_ATTR_LEN)) + { + vos_mem_copy(overFlowP2pStream, + noaStream + noaLen - overFlowLen, overFlowLen); + noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR; + noaStream[noaLen - overFlowLen + 1] = overFlowLen + SIR_MAC_P2P_OUI_SIZE; + vos_mem_copy(noaStream+noaLen-overFlowLen + 2, + SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); + vos_mem_copy(noaStream+noaLen + 2 + SIR_MAC_P2P_OUI_SIZE - overFlowLen, + overFlowP2pStream, overFlowLen); + } + + return (noaLen + SIR_P2P_IE_HEADER_LEN); + +} + +//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream +v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry) +{ + v_U8_t len=0; + + v_U8_t *pBody = pNoaStream; + + + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration)) && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration)) + && (!psessionEntry->p2pGoPsUpdate.oppPsFlag) + ) + return 0; //No NoA Descriptor then return 0 + + + pBody[0] = SIR_P2P_NOA_ATTR; + + pBody[3] = psessionEntry->p2pGoPsUpdate.index; + pBody[4] = psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->p2pGoPsUpdate.oppPsFlag<<7); + len = 5; + pBody += len; + + + if (psessionEntry->p2pGoPsUpdate.uNoa1Duration) + { + *pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt; + pBody += 1; + len +=1; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Duration); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Interval); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1StartTime); + pBody += sizeof(tANI_U32); + len +=4; + + } + + if (psessionEntry->p2pGoPsUpdate.uNoa2Duration) + { + *pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt; + pBody += 1; + len +=1; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Duration); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Interval); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2StartTime); + pBody += sizeof(tANI_U32); + len +=4; + + } + + + pBody = pNoaStream + 1; + *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(len-3);/*one byte for Attr and 2 bytes for length*/ + + return (len); + + } + return 0; + +} + +void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, ePhyChanBondState phyCbState) +{ + + pMac->lim.gResumeChannel = channel; + pMac->lim.gResumePhyCbState = phyCbState; +} + +/*-------------------------------------------------------------------------- + + \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session. + + This function returns the channel to resume to during link resume. channel id of 0 means HAL will + resume to previous channel before link suspend + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +void peGetResumeChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState) +{ + + //Rationale - this could be the suspend/resume for assoc and it is essential that + //the new BSS is active for some time. Other BSS was anyway suspended. + //TODO: Comeup with a better alternative. Sending NULL with PM=0 on other BSS means + //there will be trouble. But since it is sent on current channel, it will be missed by peer + //and hence should be ok. Need to discuss this further + if( !limIsInMCC(pMac) ) + { + //Get current active session channel + peGetActiveSessionChannel(pMac, resumeChannel, resumePhyCbState); + } + else + { + *resumeChannel = pMac->lim.gResumeChannel; + *resumePhyCbState = pMac->lim.gResumePhyCbState; + } + return; +} + +tANI_BOOLEAN limIsNOAInsertReqd(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole ) + && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona ) + ) + { + return TRUE; + } + } + } + return FALSE; +} + + +tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel) +{ + if(NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(currentChannel)) + { + return eANI_BOOLEAN_TRUE; + } + else + { + return eANI_BOOLEAN_FALSE; + } +} + +#ifdef WLAN_FEATURE_11W +void limPmfSaQueryTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + tPmfSaQueryTimerId timerId; + tpPESession psessionEntry; + tpDphHashNode pSta; + tANI_U32 maxRetries; + + limLog(pMac, LOG1, FL("SA Query timer fires")); + timerId.value = param; + + // Check that SA Query is in progress + if ((psessionEntry = peFindSessionBySessionId( + pMac, timerId.fields.sessionId)) == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given session ID %d"), + timerId.fields.sessionId); + return; + } + if ((pSta = dphGetHashEntry(pMac, timerId.fields.peerIdx, + &psessionEntry->dph.dphHashTable)) == NULL) + { + limLog(pMac, LOGE, FL("Entry does not exist for given peer index %d"), + timerId.fields.peerIdx); + return; + } + if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState) + return; + + // Increment the retry count, check if reached maximum + if (wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + &maxRetries) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not retrieve PMF SA Query maximum retries value")); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + return; + } + pSta->pmfSaQueryRetryCount++; + if (pSta->pmfSaQueryRetryCount >= maxRetries) + { + limLog(pMac, LOGE, FL("SA Query timed out")); + pSta->pmfSaQueryState = DPH_SA_QUERY_TIMED_OUT; + return; + } + + // Retry SA Query + limSendSaQueryRequestFrame(pMac, (tANI_U8 *)&(pSta->pmfSaQueryCurrentTransId), + pSta->staAddr, psessionEntry); + pSta->pmfSaQueryCurrentTransId++; + limLog(pMac, LOGE, FL("Starting SA Query retry %d"), pSta->pmfSaQueryRetryCount); + if (tx_timer_activate(&pSta->pmfSaQueryTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("PMF SA Query timer activation failed!")); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + } +} +#endif + + +#ifdef WLAN_FEATURE_11AC +tANI_BOOLEAN limCheckVHTOpModeChange( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 chanWidth, tANI_U8 staId, tANI_U8 *peerMac) +{ + tUpdateVHTOpMode tempParam; + + tempParam.opMode = chanWidth; + tempParam.staId = staId; + tempParam.smesessionId = psessionEntry->smeSessionId; + vos_mem_copy(tempParam.peer_mac, peerMac, + sizeof(tSirMacAddr)); + + limSendModeUpdate( pMac, &tempParam, psessionEntry ); + + return eANI_BOOLEAN_TRUE; +} + +tANI_BOOLEAN limSetNssChange( tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 rxNss, + tANI_U8 staId, tANI_U8 *peerMac) +{ + tUpdateRxNss tempParam; + + tempParam.rxNss = rxNss; + tempParam.staId = staId; + tempParam.smesessionId = psessionEntry->smeSessionId; + vos_mem_copy(tempParam.peer_mac, peerMac, + sizeof(tSirMacAddr)); + + limSendRxNssUpdate( pMac, &tempParam, psessionEntry ); + + return eANI_BOOLEAN_TRUE; +} + +tANI_BOOLEAN limCheckMembershipUserPosition( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U32 membership, tANI_U32 userPosition, + tANI_U8 staId) +{ + tUpdateMembership tempParamMembership; + tUpdateUserPos tempParamUserPosition; + + tempParamMembership.membership = membership; + tempParamMembership.staId = staId; + tempParamMembership.smesessionId = psessionEntry->smeSessionId; + vos_mem_copy(tempParamMembership.peer_mac, psessionEntry->bssId, + sizeof( tSirMacAddr )); + + + limSetMembership( pMac, &tempParamMembership, psessionEntry ); + + tempParamUserPosition.userPos = userPosition; + tempParamUserPosition.staId = staId; + tempParamUserPosition.smesessionId = psessionEntry->smeSessionId; + vos_mem_copy(tempParamUserPosition.peer_mac, psessionEntry->bssId, + sizeof( tSirMacAddr )); + + + limSetUserPos( pMac, &tempParamUserPosition, psessionEntry ); + + return eANI_BOOLEAN_TRUE; +} +#endif + +void limGetShortSlotFromPhyMode(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U32 phyMode, tANI_U8 *pShortSlotEnabled) +{ + tANI_U8 val=0; + + //only 2.4G band should have short slot enable, rest it should be default + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + /* short slot is default in all other modes */ + if ((psessionEntry->pePersona == VOS_STA_SAP_MODE) || + (psessionEntry->pePersona == VOS_IBSS_MODE) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + val = true; + } + // Program Polaris based on AP capability + if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + // Joining BSS. + val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limCurrentBssCaps); + } + else if (psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE) + { + // Reassociating with AP. + val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limReassocBssCaps); + } + } + else + { + /* + * 11B does not short slot and short slot is default + * for 11A mode. Hence, not need to set this bit + */ + val = false; + } + + limLog(pMac, LOG1, FL("phyMode = %u shortslotsupported = %u"), phyMode, val); + *pShortSlotEnabled = val; +} + +void limUtilsframeshtons(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U16 pIn, + tANI_U8 fMsb) +{ + (void)pCtx; +#if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +#else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } +#endif +} + +void limUtilsframeshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tANI_U8 fMsb) +{ + (void)pCtx; +#if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +#else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } +#endif +} + +#ifdef WLAN_FEATURE_11W +/** + * + * \brief This function is called by various LIM modules to correctly set + * the Protected bit in the Frame Control Field of the 802.11 frame MAC header + * + * + * \param pMac Pointer to Global MAC structure + * + * \param psessionEntry Pointer to session corresponding to the connection + * + * \param peer Peer address of the STA to which the frame is to be sent + * + * \param pMacHdr Pointer to the frame MAC header + * + * \return nothing + * + * + */ +void +limSetProtectedBit(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr peer, + tpSirMacMgmtHdr pMacHdr) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + + if( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + + pStaDs = dphLookupHashEntry( pMac, peer, &aid, + &psessionEntry->dph.dphHashTable ); + if( pStaDs != NULL ) + /* rmfenabled will be set at the time of addbss. + * but sometimes EAP auth fails and keys are not + * installed then if we send any management frame + * like deauth/disassoc with this bit set then + * firmware crashes. so check for keys are + * installed or not also before setting the bit + */ + if (pStaDs->rmfEnabled && pStaDs->isKeyInstalled) + pMacHdr->fc.wep = 1; + } + else if ( psessionEntry->limRmfEnabled && psessionEntry->isKeyInstalled) + pMacHdr->fc.wep = 1; +} /*** end limSetProtectedBit() ***/ +#endif + +tANI_U8* lim_get_ie_ptr(tANI_U8 *pIes, int length, tANI_U8 eid) +{ + int left = length; + tANI_U8 *ptr = pIes; + tANI_U8 elem_id, elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len, left); + + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +void lim_set_ht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry, + tANI_U8 *p_ie_start,tANI_U32 num_bytes) +{ + v_U8_t *p_ie=NULL; + tDot11fIEHTCaps dot11_ht_cap = {0,}; + + PopulateDot11fHTCaps(p_mac, p_session_entry, &dot11_ht_cap); + p_ie = limGetIEPtr(p_mac, p_ie_start, num_bytes, DOT11F_EID_HTCAPS, + ONE_BYTE); + limLog( p_mac, LOG2, FL("p_ie %p dot11_ht_cap.supportedMCSSet[0]=0x%x"), + p_ie, dot11_ht_cap.supportedMCSSet[0]); + + if(p_ie) + { + /* convert from unpacked to packed structure */ + tHtCaps *p_ht_cap = (tHtCaps *)&p_ie[2]; + + p_ht_cap->advCodingCap = dot11_ht_cap.advCodingCap; + p_ht_cap->supportedChannelWidthSet = + dot11_ht_cap.supportedChannelWidthSet; + p_ht_cap->mimoPowerSave = dot11_ht_cap.mimoPowerSave; + p_ht_cap->greenField = dot11_ht_cap.greenField; + p_ht_cap->shortGI20MHz = dot11_ht_cap.shortGI20MHz; + p_ht_cap->shortGI40MHz = dot11_ht_cap.shortGI40MHz; + p_ht_cap->txSTBC = dot11_ht_cap.txSTBC; + p_ht_cap->rxSTBC = dot11_ht_cap.rxSTBC; + p_ht_cap->delayedBA = dot11_ht_cap.delayedBA ; + p_ht_cap->maximalAMSDUsize = dot11_ht_cap.maximalAMSDUsize; + p_ht_cap->dsssCckMode40MHz = dot11_ht_cap.dsssCckMode40MHz; + p_ht_cap->psmp = dot11_ht_cap.psmp; + p_ht_cap->stbcControlFrame = dot11_ht_cap.stbcControlFrame; + p_ht_cap->lsigTXOPProtection = dot11_ht_cap.lsigTXOPProtection; + p_ht_cap->maxRxAMPDUFactor = dot11_ht_cap.maxRxAMPDUFactor; + p_ht_cap->mpduDensity = dot11_ht_cap.mpduDensity; + vos_mem_copy((void *)p_ht_cap->supportedMCSSet, + (void *)(dot11_ht_cap.supportedMCSSet), + sizeof(p_ht_cap->supportedMCSSet)); + p_ht_cap->pco = dot11_ht_cap.pco; + p_ht_cap->transitionTime = dot11_ht_cap.transitionTime; + p_ht_cap->mcsFeedback = dot11_ht_cap.mcsFeedback; + p_ht_cap->txBF = dot11_ht_cap.txBF; + p_ht_cap->rxStaggeredSounding = dot11_ht_cap.rxStaggeredSounding; + p_ht_cap->txStaggeredSounding = dot11_ht_cap.txStaggeredSounding; + p_ht_cap->rxZLF = dot11_ht_cap.rxZLF; + p_ht_cap->txZLF = dot11_ht_cap.txZLF; + p_ht_cap->implicitTxBF = dot11_ht_cap.implicitTxBF; + p_ht_cap->calibration = dot11_ht_cap.calibration; + p_ht_cap->explicitCSITxBF = dot11_ht_cap.explicitCSITxBF; + p_ht_cap->explicitUncompressedSteeringMatrix = + dot11_ht_cap.explicitUncompressedSteeringMatrix; + p_ht_cap->explicitBFCSIFeedback = dot11_ht_cap.explicitBFCSIFeedback; + p_ht_cap->explicitUncompressedSteeringMatrixFeedback = + dot11_ht_cap.explicitUncompressedSteeringMatrixFeedback; + p_ht_cap->explicitCompressedSteeringMatrixFeedback = + dot11_ht_cap.explicitCompressedSteeringMatrixFeedback; + p_ht_cap->csiNumBFAntennae = dot11_ht_cap.csiNumBFAntennae; + p_ht_cap->uncompressedSteeringMatrixBFAntennae = + dot11_ht_cap.uncompressedSteeringMatrixBFAntennae; + p_ht_cap->compressedSteeringMatrixBFAntennae = + dot11_ht_cap.compressedSteeringMatrixBFAntennae; + p_ht_cap->antennaSelection = dot11_ht_cap.antennaSelection; + p_ht_cap->explicitCSIFeedbackTx = dot11_ht_cap.explicitCSIFeedbackTx; + p_ht_cap->antennaIndicesFeedbackTx = + dot11_ht_cap.antennaIndicesFeedbackTx; + p_ht_cap->explicitCSIFeedback = dot11_ht_cap.explicitCSIFeedback; + p_ht_cap->antennaIndicesFeedback = dot11_ht_cap.antennaIndicesFeedback; + p_ht_cap->rxAS = dot11_ht_cap.rxAS; + p_ht_cap->txSoundingPPDUs = dot11_ht_cap.txSoundingPPDUs; + } +} + +/** + * lim_validate_received_frame_a1_addr() - To validate received frame's A1 addr + * @mac_ctx: pointer to mac context + * @a1: received frame's a1 address which is nothing but our self address + * @session: PE session pointer + * + * This routine will validate, A1 addres of the received frame + * + * Return: true or false + */ +bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx, + tSirMacAddr a1, tpPESession session) +{ + if (mac_ctx == NULL || session == NULL) { + limLog(mac_ctx, LOGE, + FL("NULL pointer")); + /* let main routine handle it */ + return true; + } + if (limIsGroupAddr(a1) || limIsAddrBC(a1)) { + /* just for fail safe, don't handle MC/BC a1 in this routine */ + return true; + } + if (!vos_mem_compare(a1, session->selfMacAddr, 6)) { + limLog(mac_ctx, LOGE, + FL("Invalid A1 address in received frame")); + return false; + } + return true; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h new file mode 100644 index 0000000000000..f86d4646c67b3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limUtils.h @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limUtils.h contains the utility definitions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_UTILS_H +#define __LIM_UTILS_H + +#include "sirApi.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "limTypes.h" +#include "limScanResultUtils.h" +#include "limTimerUtils.h" +#include "limTrace.h" +typedef enum +{ + ONE_BYTE = 1, + TWO_BYTE = 2 +} eSizeOfLenField; + +#define LIM_STA_ID_MASK 0x00FF +#define LIM_AID_MASK 0xC000 +#define LIM_SPECTRUM_MANAGEMENT_BIT_MASK 0x0100 +#define LIM_RRM_BIT_MASK 0x1000 +#define LIM_SHORT_PREAMBLE_BIT_MASK 0x0020 +#define LIM_IMMEDIATE_BLOCK_ACK_MASK 0x8000 +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define LIM_MAX_REASSOC_RETRY_LIMIT 2 +#endif + +// classifier ID is coded as 0-3: tsid, 4-5:direction +#define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4)) + +#define LIM_SET_STA_BA_STATE(pSta, tid, newVal) \ +{\ + pSta->baState = ((pSta->baState | (0x3 << tid*2)) & ((newVal << tid*2) | ~(0x3 << tid*2)));\ +} + +#define LIM_GET_STA_BA_STATE(pSta, tid, pCurVal)\ +{\ + *pCurVal = (tLimBAState)(((pSta->baState >> tid*2) & 0x3));\ +} + +#define VHT_MCS_3x3_MASK 0x30 +#define VHT_MCS_2x2_MASK 0x0C + +typedef struct sAddBaInfo +{ + tANI_U16 fBaEnable : 1; + tANI_U16 startingSeqNum: 12; + tANI_U16 reserved : 3; +}tAddBaInfo, *tpAddBaInfo; + +typedef struct sAddBaCandidate +{ + tSirMacAddr staAddr; + tAddBaInfo baInfo[STACFG_MAX_TC]; +}tAddBaCandidate, *tpAddBaCandidate; + +#ifdef WLAN_FEATURE_11W +typedef union uPmfSaQueryTimerId +{ + struct + { + tANI_U8 sessionId; + tANI_U16 peerIdx; + } fields; + tANI_U32 value; +} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId; +#endif + +// LIM utility functions +void limGetBssidFromPkt(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U32 *); +char * limDot11ReasonStr(tANI_U16 reasonCode); +char * limMlmStateStr(tLimMlmStates state); +char * limSmeStateStr(tLimSmeStates state); +char * limMsgStr(tANI_U32 msgType); +char * limResultCodeStr(tSirResultCodes resultCode); +char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode); +char* limStaOpRateModeStr(tStaRateMode opRateMode); +void limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state); +void limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state); +void limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType); +void limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg); +char* limBssTypeStr(tSirBssType bssType); + +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI +extern tSirRetStatus limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); +extern tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower, tANI_U8 iniTxPower); +#endif + +tANI_U32 limPostMsgApiNoWait(tpAniSirGlobal, tSirMsgQ *); +tANI_U8 limIsAddrBC(tSirMacAddr); +tANI_U8 limIsGroupAddr(tSirMacAddr); + +// check for type of scan allowed +tANI_U8 limActiveScanAllowed(tpAniSirGlobal, tANI_U8); + +// AID pool management functions +void limInitPeerIdxpool(tpAniSirGlobal,tpPESession); +tANI_U16 limAssignPeerIdx(tpAniSirGlobal,tpPESession); + +void limEnableOverlap11gProtection(tpAniSirGlobal pMac, tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry); +void limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams); +void limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +void limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); + +/* + * The below 'product' check tobe removed if 'Association' is + * allowed in IBSS. + */ +void limReleasePeerIdx(tpAniSirGlobal, tANI_U16, tpPESession); + + +void limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession); +void +limDecideApProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); + +extern tSirRetStatus limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession sessionEntry); +extern tSirRetStatus limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +extern tSirRetStatus limEnableHtOBSSProtection (tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams, tpPESession); +void limDecideStaProtection(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +void limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry); +void limUpdateStaRunTimeHTSwitchChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo * pHTInfo, tANI_U8 bssIdx, tpPESession psessionEntry); +// Print MAC address utility function +void limPrintMacAddr(tpAniSirGlobal, tSirMacAddr, tANI_U8); + + + +// Deferred Message Queue read/write +tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac); +void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg); + +// Deferred Message Queue Reset +void limResetDeferredMsgQ(tpAniSirGlobal pMac); + +tSirRetStatus limSysProcessMmhMsgApi(tpAniSirGlobal, tSirMsgQ*, tANI_U8); + +void limHandleUpdateOlbcCache(tpAniSirGlobal pMac); + +tANI_U8 limIsNullSsid( tSirMacSSid *pSsid ); + +void limProcessAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param); + +// 11h Support +void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId); +void limProcessChannelSwitchTimeout(tpAniSirGlobal); +tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limUpdateChannelSwitch(tpAniSirGlobal, tpSirProbeRespBeacon, tpPESession psessionEntry); +void limProcessQuietTimeout(tpAniSirGlobal); +void limProcessQuietBssTimeout(tpAniSirGlobal); + +void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId); +void limSwitchPrimaryChannel(tpAniSirGlobal, tANI_U8,tpPESession); +void limSwitchPrimarySecondaryChannel(tpAniSirGlobal, tpPESession, tANI_U8, ePhyChanBondState); +tAniBool limTriggerBackgroundScanDuringQuietBss(tpAniSirGlobal); +void limUpdateStaRunTimeHTSwtichChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo *pRcvdHTInfo, tANI_U8 bssIdx); +void limUpdateStaRunTimeHTCapability(tpAniSirGlobal pMac, tDot11fIEHTCaps *pHTCaps); +void limUpdateStaRunTimeHTInfo(struct sAniSirGlobal *pMac, tDot11fIEHTInfo *pRcvdHTInfo, tpPESession psessionEntry); +void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry); +tAniBool limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel); +void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode); +tSirRetStatus limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry); +tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac, tpPESession psessionEntry); + +void limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); + +static inline tSirRFBand limGetRFBand(tANI_U8 channel) +{ + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + return SIR_BAND_5_GHZ; + + if ((channel >= SIR_11B_CHANNEL_BEGIN) && + (channel <= SIR_11B_CHANNEL_END)) + return SIR_BAND_2_4_GHZ; + + return SIR_BAND_UNKNOWN; +} + + +static inline tSirRetStatus +limGetMgmtStaid(tpAniSirGlobal pMac, tANI_U16 *staid, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + *staid = 1; + else if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + *staid = 0; + else + return eSIR_FAILURE; + + return eSIR_SUCCESS; +} + +static inline tANI_U8 +limIsSystemInSetMimopsState(tpAniSirGlobal pMac) +{ + if (pMac->lim.gLimMlmState == eLIM_MLM_WT_SET_MIMOPS_STATE) + return true; + return false; +} + +static inline tANI_U8 + isEnteringMimoPS(tSirMacHTMIMOPowerSaveState curState, tSirMacHTMIMOPowerSaveState newState) + { + if (curState == eSIR_HT_MIMO_PS_NO_LIMIT && + (newState == eSIR_HT_MIMO_PS_DYNAMIC ||newState == eSIR_HT_MIMO_PS_STATIC)) + return TRUE; + return FALSE; +} + +static inline int limSelectCBMode(tDphHashNode *pStaDs, tpPESession psessionEntry, + tANI_U8 channel, tANI_U8 chan_bw) +{ + if ( pStaDs->mlmStaContext.vhtCapability && chan_bw) + { + if ( channel== 36 || channel == 52 || channel == 100 || + channel == 116 || channel == 149 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1; + } + else if ( channel == 40 || channel == 56 || channel == 104 || + channel == 120 || channel == 153 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1; + } + else if ( channel == 44 || channel == 60 || channel == 108 || + channel == 124 || channel == 157 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1; + } + else if ( channel == 48 || channel == 64 || channel == 112 || + channel == 128 || channel == 161 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1; + } + else if ( channel == 165 ) + { + return PHY_SINGLE_CHANNEL_CENTERED; + } + } + else if ( pStaDs->mlmStaContext.htCapability ) + { + if ( channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 144 || channel == 153 || channel == 161 ) + { + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + } + else if ( channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 140 || channel == 149 || channel == 157 ) + { + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + } + else if ( channel == 165 ) + { + return PHY_SINGLE_CHANNEL_CENTERED; + } + } + return PHY_SINGLE_CHANNEL_CENTERED; +} + +/// ANI peer station count management and associated actions +void limUtilCountStaAdd(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry); +void limUtilCountStaDel(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry); + +tANI_U8 limGetHTCapability( tpAniSirGlobal, tANI_U32, tpPESession); +void limTxComplete( tHalHandle hHal, void *pData, v_BOOL_t free ); + +/**********Admit Control***************************************/ + +//callback function for HAL to issue DelTS request to PE. +//This function will be registered with HAL for callback when TSPEC inactivity timer fires. + +void limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 mesgId, void *mesgParam ); +tSirRetStatus limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry); +/**********************************************************/ + +//callback function registration to HAL for any indication. +void limRegisterHalIndCallBack(tpAniSirGlobal pMac); +void limPktFree ( + tpAniSirGlobal pMac, + eFrameType frmType, + tANI_U8 *pBD, + void *body); + + + +void limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pBD); + +/** + * \brief Given a base(X) and power(Y), this API will return + * the result of base raised to power - (X ^ Y) + * + * \sa utilsPowerXY + * + * \param base Base value + * + * \param power Base raised to this Power value + * + * \return Result of X^Y + * + */ +static inline tANI_U32 utilsPowerXY( tANI_U16 base, tANI_U16 power ) +{ +tANI_U32 result = 1, i; + + for( i = 0; i < power; i++ ) + result *= base; + + return result; +} + + + +tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry); +tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirMacStatusCodes baStatusCode, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tpPESession psessionEntry); +tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDirection, + tANI_U8 baTID, + tSirMacReasonCodes baReasonCode , + tpPESession psessionEntry); +tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tANI_U16 baSSN, + tANI_U8 baDirection, + tpPESession psessionEntry); +tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baTID, + tANI_U8 baDirection, + tpPESession psessionEntry); + +tSirRetStatus limPostSMStateUpdate(tpAniSirGlobal pMac, + tANI_U16 StaIdx, + tSirMacHTMIMOPowerSaveState MIMOPSState, + tANI_U8 *pPeerStaMac, tANI_U8 sessionId); + +void limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void limDeleteBASessions(tpAniSirGlobal pMac, tpPESession pSessionEntry, tANI_U32 baDirection); +void limDelPerBssBASessionsBtc(tpAniSirGlobal pMac); +void limDelAllBASessions(tpAniSirGlobal pMac); +void limDeleteDialogueTokenList(tpAniSirGlobal pMac); +tSirRetStatus limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid); +void limRessetScanChannelInfo(tpAniSirGlobal pMac); +void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId); + +tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon); +tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon); +void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action); + +void limSetTspecUapsdMaskPerSession(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacTSInfo *pTsInfo, + tANI_U32 action); + +void limHandleHeartBeatTimeout(tpAniSirGlobal pMac); +void limHandleHeartBeatTimeoutForSession(tpAniSirGlobal pMac, tpPESession psessionEntry); + +//void limProcessBtampAddBssRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ,tpPESession peSession); +void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ); + +void limUpdateBeacon(tpAniSirGlobal pMac); + +void limProcessBtAmpApMlmAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ, tpPESession psessionEntry); +void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry); + +void limProcessBtAmpApMlmDelStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ,tpPESession psessionEntry); +tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac); +tpPESession limIsApSessionActive(tpAniSirGlobal pMac); +void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac); + +void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ); +void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ); +v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field); + +tANI_U8 limUnmapChannel(tANI_U8 mapChannel); + +#define limGetWscIEPtr(pMac, ie, ie_len) \ + limGetVendorIEOuiPtr(pMac, SIR_MAC_WSC_OUI, SIR_MAC_WSC_OUI_SIZE, ie, ie_len) + +#define limGetP2pIEPtr(pMac, ie, ie_len) \ + limGetVendorIEOuiPtr(pMac, SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, ie, ie_len) + +v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen); +v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry); + +v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len); +tANI_BOOLEAN limIsNOAInsertReqd(tpAniSirGlobal pMac); +v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len); +tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel); +tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_11AC +tANI_BOOLEAN limCheckVHTOpModeChange( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 chanWidth, tANI_U8 staId, tANI_U8 *peerMac); +tANI_BOOLEAN limSetNssChange( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 rxNss, tANI_U8 staId, tANI_U8 *peerMac); +tANI_BOOLEAN limCheckMembershipUserPosition( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U32 membership, tANI_U32 userPosition, + tANI_U8 staId); +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +typedef enum +{ + WLAN_PE_DIAG_SCAN_REQ_EVENT = 0, + WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, + WLAN_PE_DIAG_SCAN_RSP_EVENT, + WLAN_PE_DIAG_JOIN_REQ_EVENT, + WLAN_PE_DIAG_JOIN_RSP_EVENT, + WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, + WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, + WLAN_PE_DIAG_REASSOC_REQ_EVENT, + WLAN_PE_DIAG_REASSOC_RSP_EVENT, + WLAN_PE_DIAG_AUTH_REQ_EVENT, + WLAN_PE_DIAG_AUTH_RSP_EVENT, + WLAN_PE_DIAG_DISASSOC_REQ_EVENT, + WLAN_PE_DIAG_DISASSOC_RSP_EVENT, + WLAN_PE_DIAG_DISASSOC_IND_EVENT, + WLAN_PE_DIAG_DISASSOC_CNF_EVENT, + WLAN_PE_DIAG_DEAUTH_REQ_EVENT, + WLAN_PE_DIAG_DEAUTH_RSP_EVENT, + WLAN_PE_DIAG_DEAUTH_IND_EVENT, + WLAN_PE_DIAG_START_BSS_REQ_EVENT, + WLAN_PE_DIAG_START_BSS_RSP_EVENT, + WLAN_PE_DIAG_AUTH_IND_EVENT, + WLAN_PE_DIAG_ASSOC_IND_EVENT, + WLAN_PE_DIAG_ASSOC_CNF_EVENT, + WLAN_PE_DIAG_REASSOC_IND_EVENT, + WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, + WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT, + WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, + WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, + WLAN_PE_DIAG_DEAUTH_CNF_EVENT, + WLAN_PE_DIAG_ADDTS_REQ_EVENT, + WLAN_PE_DIAG_ADDTS_RSP_EVENT, + WLAN_PE_DIAG_DELTS_REQ_EVENT, + WLAN_PE_DIAG_DELTS_RSP_EVENT, + WLAN_PE_DIAG_DELTS_IND_EVENT, + WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT, + WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT, + WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT, + WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT, + WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT, + WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT, + WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT, + WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT, + WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT, + WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT, + WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT, + WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT, + WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT, + WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT, + WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT, + WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT, + WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT, + WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, + WLAN_PE_DIAG_HAL_DELBA_IND_EVENT, + WLAN_PE_DIAG_HB_FAILURE_TIMEOUT, + WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT, + WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, + WLAN_PE_DIAG_PREAUTH_DONE, + WLAN_PE_DIAG_REASSOCIATING, + WLAN_PE_DIAG_CONNECTED, +}WLAN_PE_DIAG_EVENT_TYPE; + +void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, ePhyChanBondState cbState); +/*-------------------------------------------------------------------------- + + \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session. + + This function returns the channel to resume to during link resume. channel id of 0 means HAL will + resume to previous channel before link suspend + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +void peGetResumeChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState); + + +void limGetShortSlotFromPhyMode(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U32 phyMode, + tANI_U8 *pShortSlotEnable); + +void limCleanUpDisassocDeauthReq(tpAniSirGlobal pMac, tANI_U8 *staMac, tANI_BOOLEAN cleanRxPath); + +tANI_BOOLEAN limCheckDisassocDeauthAckPending(tpAniSirGlobal pMac, tANI_U8 *staMac); + +#ifdef WLAN_FEATURE_11W +void limPmfSaQueryTimerHandler(void *pMacGlobal, tANI_U32 param); +#endif + + + +void limUtilsframeshtons(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U16 pIn, + tANI_U8 fMsb); + +void limUtilsframeshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tANI_U8 fMsb); + +void limSetProtectedBit(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr peer, + tpSirMacMgmtHdr pMacHdr); + +tANI_U8* lim_get_ie_ptr(tANI_U8 *pIes, int length, tANI_U8 eid); + +#ifdef WLAN_FEATURE_11W +void limPmfComebackTimerCallback(void *context); +#endif /* WLAN_FEATURE_11W */ + +void lim_set_ht_caps(tpAniSirGlobal p_mac, + tpPESession p_session_entry, + tANI_U8 *p_ie_start, + tANI_U32 num_bytes); +bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx, + tSirMacAddr a1, tpPESession session); + +#endif /* __LIM_UTILS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmAP.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmAP.c new file mode 100644 index 0000000000000..d3ee1b4d54cea --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmAP.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file pmmAP.cc contains AP PM functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "sirCommon.h" + +#include "aniGlobal.h" + +#include "schApi.h" +#include "limApi.h" +#include "cfgApi.h" +#include "wniCfgSta.h" + +#include "pmmApi.h" +#include "pmmDebug.h" + +/** + * pmmGenerateTIM + * + * FUNCTION: + * Generate TIM + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to global mac structure + * @param **pPtr pointer to the buffer, where the TIM bit is to be written. + * @param *timLength pointer to limLength, which needs to be returned. + * @return None + */ +void pmmGenerateTIM(tpAniSirGlobal pMac, tANI_U8 **pPtr, tANI_U16 *timLength, tANI_U8 dtimPeriod) +{ + tANI_U8 *ptr = *pPtr; + tANI_U32 val = 0; + tANI_U32 minAid = 1; // Always start with AID 1 as minimum + tANI_U32 maxAid = HAL_NUM_STA; + + + // Generate partial virtual bitmap + tANI_U8 N1 = minAid / 8; + tANI_U8 N2 = maxAid / 8; + if (N1 & 1) N1--; + + *timLength = N2 - N1 + 4; + val = dtimPeriod; + + /* + * 09/23/2011 - ASW team decision; + * Write 0xFF to firmware's field to detect firmware's mal-function early. + * DTIM count and bitmap control usually cannot be 0xFF, so it is easy to know that + * firmware never updated DTIM count/bitmap control field after host driver downloaded + * beacon template if end-user complaints that DTIM count and bitmapControl is 0xFF. + */ + *ptr++ = SIR_MAC_TIM_EID; + *ptr++ = (tANI_U8)(*timLength); + *ptr++ = 0xFF; // location for dtimCount. will be filled in by FW. + *ptr++ = (tANI_U8)val; + + *ptr++ = 0xFF; // location for bitmap control. will be filled in by FW. + ptr += (N2 - N1 + 1); + + PELOG2(sirDumpBuf(pMac, SIR_PMM_MODULE_ID, LOG2, *pPtr, (*timLength)+2);) + *pPtr = ptr; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmApi.c new file mode 100644 index 0000000000000..cba7b151acf59 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmApi.c @@ -0,0 +1,3683 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file pmmApi.cc contains functions related to the API exposed + * by power management module + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfgSta.h" + +#include "sirCommon.h" +#include "aniGlobal.h" + +#include "schApi.h" +#include "limApi.h" +#include "limSendMessages.h" +#include "cfgApi.h" +#include "limSessionUtils.h" +#include "limFT.h" + +#include "pmmApi.h" +#include "pmmDebug.h" +#include "sirApi.h" +#include "wmmApsd.h" + +#include "limSendSmeRspMessages.h" +#include "limTimerUtils.h" +#include "limTrace.h" +#include "limUtils.h" +#include "VossWrapper.h" +#include "vos_status.h" //VOS_STATUS +#include "vos_mq.h" //vos_mq_post_message() + +#include "wlan_qct_wda.h" + +#define LIM_ADMIT_MASK_FLAG_ACBE 1 +#define LIM_ADMIT_MASK_FLAG_ACBK 2 +#define LIM_ADMIT_MASK_FLAG_ACVI 4 +#define LIM_ADMIT_MASK_FLAG_ACVO 8 + +// -------------------------------------------------------------------- +/** + * pmmInitialize + * + * FUNCTION: + * Initialize PMM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode + * @param rate + * @return None + */ + +tSirRetStatus +pmmInitialize(tpAniSirGlobal pMac) +{ + + + pmmResetStats(pMac); + + pMac->pmm.gPmmBeaconInterval = WNI_CFG_BEACON_INTERVAL_STADEF; + pMac->pmm.gPmmState = ePMM_STATE_READY; + + + + pMac->pmm.inMissedBeaconScenario = FALSE; + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * pmmResetStats + * + * FUNCTION: + * Resets the statistics + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac + * + * @return None + */ + +void +pmmResetStats(void *pvMac) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)pvMac; + + pMac->pmm.BmpsmaxSleepTime = 0; + pMac->pmm.BmpsavgSleepTime = 0; + pMac->pmm.BmpsminSleepTime = 0; + pMac->pmm.BmpscntSleep = 0; + + pMac->pmm.BmpsmaxTimeAwake = 0; + pMac->pmm.BmpsavgTimeAwake = 0; + pMac->pmm.BmpsminTimeAwake = 0; + pMac->pmm.BmpscntAwake = 0; + + pMac->pmm.BmpsWakeupTimeStamp = 0; + pMac->pmm.BmpsSleepTimeStamp = 0; + + pMac->pmm.BmpsHalReqFailCnt = 0; + pMac->pmm.BmpsInitFailCnt = 0; + pMac->pmm.BmpsInitFailCnt= 0; + pMac->pmm.BmpsInvStateCnt= 0; + pMac->pmm.BmpsPktDrpInSleepMode= 0; + pMac->pmm.BmpsReqInInvalidRoleCnt= 0; + pMac->pmm.BmpsSleeReqFailCnt= 0; + pMac->pmm.BmpsWakeupIndCnt= 0; + + pMac->pmm.ImpsWakeupTimeStamp = 0; + pMac->pmm.ImpsSleepTimeStamp = 0; + pMac->pmm.ImpsMaxTimeAwake = 0; + pMac->pmm.ImpsMinTimeAwake = 0; + pMac->pmm.ImpsAvgTimeAwake = 0; + pMac->pmm.ImpsCntAwake = 0; + + pMac->pmm.ImpsCntSleep = 0; + pMac->pmm.ImpsMaxSleepTime = 0; + pMac->pmm.ImpsMinSleepTime = 0; + pMac->pmm.ImpsAvgSleepTime = 0; + + pMac->pmm.ImpsSleepErrCnt = 0; + pMac->pmm.ImpsWakeupErrCnt = 0; + pMac->pmm.ImpsLastErr = 0; + pMac->pmm.ImpsInvalidStateCnt = 0; + + return; +} + + + +// -------------------------------------------------------------------- +/** + * pmmInitBmpsResponseHandler + * + * FUNCTION: + * This function processes the SIR_HAL_ENTER_BMPS_RSP from HAL. + * If the response is successful, it puts PMM in ePMM_STATE_BMP_SLEEP state + * and sends back success response to PMC. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * @return None + */ + +void pmmInitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg ) +{ + + + tPmmState nextState = pMac->pmm.gPmmState; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + tpPESession psessionEntry; + tpEnterBmpsParams pEnterBmpsParams; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_ENTER_BMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_INIT_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: Received 'InitPwrSaveRsp' while in incorrect state: %d"), + pMac->pmm.gPmmState);) + + retStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + goto failure; + } + + if (NULL == limMsg->bodyptr) + { + PELOGE(pmmLog(pMac, LOGE, FL("pmmBmps: Received SIR_HAL_ENTER_BMPS_RSP with NULL "));) + goto failure; + } + pEnterBmpsParams = (tpEnterBmpsParams)(limMsg->bodyptr); + + //if response is success, then set PMM to BMPS_SLEEP state and send response back to PMC. + //If response is failure, then send the response back to PMC and reset its state. + if(pEnterBmpsParams->status == eHAL_STATUS_SUCCESS) + { + PELOG2(pmmLog(pMac, LOG2, + FL("pmmBmps: Received successful response from HAL to enter BMPS_POWER_SAVE "));) + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + + // Disable background scan mode + pMac->sys.gSysEnableScanMode = false; + + if (pMac->lim.gLimTimersCreated) + { + /* Disable heartbeat timer as well */ + if(pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_HEART_BEAT_TIMER)); + tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + } + } + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0); + } + else + { + //if init req failed, then go back to WAKEUP state. + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: BMPS_INIT_PWR_SAVE_REQ failed, informing SME"));) + + pmmBmpsUpdateInitFailureCnt(pMac); + nextState = ePMM_STATE_BMPS_WAKEUP; + retStatus = eSIR_SME_BMPS_REQ_FAILED; + goto failure; + } + return; + +failure: + psessionEntry = peGetValidPowerSaveSession(pMac); + if(psessionEntry != NULL) + { + if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer)) + { + PELOGE(pmmLog(pMac, LOGE, FL("Unexpected heartbeat timer not running"));) + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + } + + //Generate an error response back to PMC + pMac->pmm.gPmmState = nextState; + pmmBmpsUpdateSleepReqFailureCnt(pMac); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0); + return; + +} + +// -------------------------------------------------------------------- +/** + * pmmExitBmpsRequestHandler + * + * FUNCTION: + * This function will send the wakeup message to HAL + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to Global Mac structure. + + * @return None + */ + +void pmmExitBmpsRequestHandler(tpAniSirGlobal pMac, tpExitBmpsInfo pExitBmpsInfo) +{ + tSirResultCodes respStatus = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + + if (NULL == pExitBmpsInfo) + { + respStatus = eSIR_SME_BMPS_REQ_REJECT; + PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Rcvd EXIT_BMPS with NULL body"));) + goto failure; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT, + peGetValidPowerSaveSession(pMac), 0, + (tANI_U16)pExitBmpsInfo->exitBmpsReason); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* PMC is not aware of Background scan, which is done in + * BMPS mode while Nth Beacon is delivered. Essentially, PMC + * can request the device to get out of power-save while + * background scanning is happening. since, the device is already + * out of powersave, just inform that device is out of powersave + */ + if(limIsSystemInScanState(pMac)) + { + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Device is already awake and scanning, returning success to PMC "));) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0); + return; + } + + /* send wakeup request, only when in sleep state */ + PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Sending eWNI_PMC_EXIT_BMPS_REQ to HAL"));) + if (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) + { + /* Store the reason code for exiting BMPS. This value will be + * checked when PMM receives SIR_HAL_EXIT_BMPS_RSP from HAL + */ + pMac->pmm.gPmmExitBmpsReasonCode = pExitBmpsInfo->exitBmpsReason; + vos_mem_free(pExitBmpsInfo); + + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Rcvd EXIT_BMPS with reason code%d "), pMac->pmm.gPmmExitBmpsReasonCode);) + + + // Set PMM to BMPS_WT_WAKEUP_RSP state + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_WAKEUP_RSP; + if(pmmSendChangePowerSaveMsg(pMac) != eSIR_SUCCESS) + { + /* Wakeup request failed */ + respStatus = eSIR_SME_BMPS_REQ_REJECT; + pmmBmpsUpdateHalReqFailureCnt(pMac); + goto failure; + } + else + { + PELOG1(pmmLog(pMac, LOG1, + FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ was successfully sent to HAL"));) + } + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ received in invalid state: %d"), + pMac->pmm.gPmmState );) + + respStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + vos_mem_free(pExitBmpsInfo); + goto failure; + } + return; + +failure: + pMac->pmm.gPmmState = origState; + pmmBmpsUpdateWakeupReqFailureCnt(pMac); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmInitBmpsPwrSave + * + * FUNCTION: + * This function process the eWNI_PMC_ENTER_PMC_REQ from PMC. + * It checks for certain conditions before it puts PMM into + * BMPS power save state: ePMM_STATE_BMPS_WT_INIT_RSP + * It also invokes pmmSendInitPowerSaveMsg() to send ENTER_BMPS_REQ + * to HAL. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode can be either 0(sleep mode) or 1 (active mode) + * @param pMac pointer to Global Mac structure. + + * @return None + */ + + +void pmmInitBmpsPwrSave(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes respStatus = eSIR_SME_SUCCESS; + tpPESession psessionEntry; + + tPmmState origState = pMac->pmm.gPmmState; + + if((psessionEntry = peGetValidPowerSaveSession(pMac))== NULL) + { + respStatus = eSIR_SME_BMPS_REQ_REJECT; + goto failure; + } +#ifndef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + // sending beacon filtering information down to HAL + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } +#else + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } + } +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) && + (pMac->pmm.gPmmState != ePMM_STATE_BMPS_WAKEUP)) || + limIsSystemInScanState(pMac) || + limIsChanSwitchRunning(pMac) || + limIsInQuietDuration(pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: BMPS Request received in invalid state PMM=%d, SME=%d, rejecting the initpwrsave request"), + pMac->pmm.gPmmState, pMac->lim.gLimSmeState);) + + respStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + goto failure; + } + + //If we are in a missed beacon scenario, we should not be attempting to enter BMPS as heartbeat probe is going on + if(pMac->pmm.inMissedBeaconScenario) + { + if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer)) + { + PELOGE(pmmLog(pMac, LOGE, FL("Unexpected heartbeat timer not running"));) + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + respStatus = eSIR_SME_BMPS_REQ_REJECT; + goto failure; + } + + /* At this point, device is associated and PMM is not in BMPS_SLEEP state. + * Heartbeat timer not running is an indication that PE have detected a + * loss of link. In this case, reject BMPS request. + */ + + //If the following function returns SUCCESS, then PMM will wait for an explicit + //response message from softmac. + + //changing PMM state before posting message to HAL, as this is a synchronous call to HAL + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_INIT_RSP; + if((retStatus = pmmSendInitPowerSaveMsg(pMac,psessionEntry)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: Init Power Save Request Failed: Sending Response: %d"), + retStatus);) + + respStatus = eSIR_SME_BMPS_REQ_REJECT; + pmmBmpsUpdateHalReqFailureCnt(pMac); + goto failure; + } + //Update the powerSave sessionId + pMac->pmm.sessionId = psessionEntry->peSessionId; + return; + +failure: + + // Change the state back to original state + pMac->pmm.gPmmState =origState; + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, respStatus, 0, 0); + return; +} + + +/** + * pmmSendChangePowerSaveMsg() + * + *FUNCTION: + * This function is called to send SIR_HAL_EXIT_BMPS_REQ to HAL. + * This message will trigger HAL to program HW to wake up. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @return success if message send is ok, else false. + */ +tSirRetStatus pmmSendChangePowerSaveMsg(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tpExitBmpsParams pExitBmpsParams; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 currentOperatingChannel = limGetCurrentOperatingChannel(pMac); + + pExitBmpsParams = vos_mem_malloc(sizeof(*pExitBmpsParams)); + if ( NULL == pExitBmpsParams ) + { + pmmLog(pMac, LOGW, FL("Failed to allocate memory")); + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + if((psessionEntry = peGetValidPowerSaveSession(pMac)) == NULL ) + { + retStatus = eSIR_FAILURE; + vos_mem_free(pExitBmpsParams); + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pExitBmpsParams, sizeof(*pExitBmpsParams), 0); + msgQ.type = WDA_EXIT_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pExitBmpsParams; + msgQ.bodyval = 0; + + /* If reason for full power is disconnecting (ie. link is + * disconnected) or becasue of channel switch or full power requested + * because of beacon miss and connected on DFS channel + * then we should not send data null. + * For all other reason code, send data null. + */ + if ( !(SIR_IS_FULL_POWER_REASON_DISCONNECTED(pMac->pmm.gPmmExitBmpsReasonCode) || + ( (eSME_MISSED_BEACON_IND_RCVD == pMac->pmm.gPmmExitBmpsReasonCode) && + limIsconnectedOnDFSChannel(currentOperatingChannel)))) + pExitBmpsParams->sendDataNull = 1; + + pExitBmpsParams->bssIdx = psessionEntry->bssIdx; + + /* we need to defer any incoming messages until we + * get a WDA_EXIT_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg( pMac, &msgQ); + if( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog( pMac, LOGE, FL("Sending WDA_EXIT_BMPS_REQ failed, reason=%X "), retStatus );) + vos_mem_free(pExitBmpsParams); + return retStatus; + } + + PELOG1(pmmLog(pMac, LOG1, FL("WDA_EXIT_BMPS_REQ has been successfully sent to HAL"));) + return retStatus; +} + + +/** + * pmmSendInitPowerSaveMsg() + * + *FUNCTION: + * This function is called to send ENTER_BMPS_REQ message to HAL. + * This message is sent to intialize the process of bringing the + * station into power save state. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param mode The Power Save or Active State + * + * @return success if message send is ok, else false. + */ + +tSirRetStatus pmmSendInitPowerSaveMsg(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpEnterBmpsParams pBmpsParams = NULL; + tANI_U32 rssiFilterPeriod = 5; + tANI_U32 numBeaconPerRssiAverage = 20; + tANI_U32 bRssiFilterEnable = FALSE; + + if(psessionEntry->currentBssBeaconCnt == 0 ) + { + PELOGE(pmmLog( pMac, LOGE, FL("Beacon count is zero, can not retrieve the TSF, failing the Enter Bmps Request"));) + return eSIR_FAILURE; + } + + pBmpsParams = vos_mem_malloc(sizeof(tEnterBmpsParams)); + if ( NULL == pBmpsParams ) + { + pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for Enter Bmps"); + return eSIR_FAILURE; + } + + pMac->pmm.inMissedBeaconScenario = FALSE; + pBmpsParams->respReqd = TRUE; + + pBmpsParams->tbtt = psessionEntry->lastBeaconTimeStamp; + pBmpsParams->dtimCount = psessionEntry->lastBeaconDtimCount; + pBmpsParams->dtimPeriod = psessionEntry->lastBeaconDtimPeriod; + pBmpsParams->bssIdx = psessionEntry->bssIdx; + + /* TODO: Config parameters (Rssi filter period, FW RSSI Monitoring + and Number of beacons per RSSI average) values sent down to FW during + initial exchange (driver load) is same as ENTER_BMPS_REQ. + Sending these values again in ENTER_BMPS_REQ is not required + (can be removed). This is kept as-is for now to support + backward compatibility with the older host running on new FW. */ + + if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period")); + pBmpsParams->rssiFilterPeriod = (tANI_U8)rssiFilterPeriod; + + if(wlan_cfgGetInt(pMac, WNI_CFG_PS_ENABLE_RSSI_MONITOR, &bRssiFilterEnable) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi monitor enable flag")); + pBmpsParams->bRssiFilterEnable = bRssiFilterEnable; + + /* The numBeaconPerRssiAverage should be less than + the max allowed (default set to 20 in CFG) */ + if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi")); + + pBmpsParams->numBeaconPerRssiAverage = + (tANI_U8)GET_MIN_VALUE((tANI_U8) numBeaconPerRssiAverage, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX); + + pmmLog (pMac, LOG1, + "%s: [INFOLOG]RssiFilterInfo..%d %x %x", __func__, (int)pBmpsParams->bRssiFilterEnable, + (unsigned int)pBmpsParams->rssiFilterPeriod, (unsigned int)pBmpsParams->numBeaconPerRssiAverage); + + msgQ.type = WDA_ENTER_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pBmpsParams; + msgQ.bodyval = 0; + + PELOG2(pmmLog( pMac, LOG2, + FL( "pmmBmps: Sending WDA_ENTER_BMPS_REQ" ));) + + /* we need to defer any incoming messages until we get a + * WDA_ENTER_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBmpsParams); + PELOGE(pmmLog( pMac, LOGE, + FL("Posting WDA_ENTER_BMPS_REQ to HAL failed, reason=%X"), + retCode );) + } + + return retCode; +} + +/** + * pmmSendPowerSaveCfg() + * + *FUNCTION: + * This function is called to send power save configurtion. + * + *NOTE: + * + * @param pMac pointer to Global Mac structure. + * @param mode The Power Save or Active State + * + * @return success if message send is ok, else false. + */ +tSirRetStatus pmmSendPowerSaveCfg(tpAniSirGlobal pMac, tpSirPowerSaveCfg pUpdatedPwrSaveCfg) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tANI_U32 listenInterval; + tANI_U32 HeartBeatCount = 1; + tANI_U32 maxPsPoll; + tANI_U32 numBeaconPerRssiAverage; + tANI_U32 minRssiThreshold; + tANI_U32 nthBeaconFilter; + tANI_U32 broadcastFrameFilter; + tANI_U32 rssiFilterPeriod; + tANI_U32 ignoreDtim; + + if (NULL == pUpdatedPwrSaveCfg) + goto returnFailure; + + if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE ) + { + pmmLog(pMac, LOGE, + FL("pmmCfg: Power Save Configuration received in invalid global sme state %d"), + pMac->lim.gLimSmeState); + retCode = eSIR_SME_INVALID_STATE; + goto returnFailure; + } + + // Get power save configuration CFG values + if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for listen interval")); + pUpdatedPwrSaveCfg->listenInterval = (tANI_U16)listenInterval; + + if(wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &HeartBeatCount) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for heart beat thresh")); + + pMac->lim.gLimHeartBeatCount = HeartBeatCount; + pUpdatedPwrSaveCfg->HeartBeatCount = HeartBeatCount; + + if(wlan_cfgGetInt(pMac, WNI_CFG_NTH_BEACON_FILTER, &nthBeaconFilter) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter")); + pUpdatedPwrSaveCfg->nthBeaconFilter = nthBeaconFilter; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_PS_POLL, &maxPsPoll) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for max poll")); + pUpdatedPwrSaveCfg->maxPsPoll = maxPsPoll; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MIN_RSSI_THRESHOLD, &minRssiThreshold) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for min RSSI Threshold")); + pUpdatedPwrSaveCfg->minRssiThreshold = minRssiThreshold; + + if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi")); + pUpdatedPwrSaveCfg->numBeaconPerRssiAverage = (tANI_U8) numBeaconPerRssiAverage; + + if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period")); + pUpdatedPwrSaveCfg->rssiFilterPeriod = (tANI_U8) rssiFilterPeriod; + + if(wlan_cfgGetInt(pMac, WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE, &broadcastFrameFilter) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter")); + pUpdatedPwrSaveCfg->broadcastFrameFilter = (tANI_U8) broadcastFrameFilter; + + if(wlan_cfgGetInt(pMac, WNI_CFG_IGNORE_DTIM, &ignoreDtim) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for ignoreDtim")); + pUpdatedPwrSaveCfg->ignoreDtim = (tANI_U8) ignoreDtim; + + //Save a copy of the CFG in global pmm context. + vos_mem_copy( (tANI_U8 *) &pMac->pmm.gPmmCfg, pUpdatedPwrSaveCfg, sizeof(tSirPowerSaveCfg)); + + + msgQ.type = WDA_PWR_SAVE_CFG; + msgQ.reserved = 0; + msgQ.bodyptr = pUpdatedPwrSaveCfg; + msgQ.bodyval = 0; + + PELOG1(pmmLog( pMac, LOG1, FL( "pmmBmps: Sending WDA_PWR_SAVE_CFG to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + pmmLog( pMac, LOGP, + FL("Posting WDA_PWR_SAVE_CFG to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + } + return retCode; + +returnFailure: + + /* In case of failure, we need to free the memory */ + if (NULL != pUpdatedPwrSaveCfg) + { + vos_mem_free(pUpdatedPwrSaveCfg); + } + return retCode; +} + +/** + * pmmExitBmpsResponseHandler + * + *FUNCTION: + * This function processes the Wakeup Rsp from HAL and if successfull, + * sends a respnose back to PMC layer. + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param rspStatus Status of the response, Success or an error code. + * + * @return none. + */ +void pmmExitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpExitBmpsParams pExitBmpsRsp; + eHalStatus rspStatus; + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + + /* Copy the power save sessionId to the local variable */ + PowersavesessionId = pMac->pmm.sessionId; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_EXIT_BMPS_REQ. + */ + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if (NULL == limMsg->bodyptr) + { + pmmLog(pMac, LOGE, FL("Received SIR_HAL_EXIT_BMPS_RSP with NULL ")); + return; + } + pExitBmpsRsp = (tpExitBmpsParams)(limMsg->bodyptr); + rspStatus = pExitBmpsRsp->status; + + if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received SIR_HAL_EXIT_BMPS_RSP while in incorrect state: %d"), + pMac->pmm.gPmmState);) + + retStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + } + else + { + PELOGW(pmmLog(pMac, LOGW, FL("Received SIR_HAL_EXIT_BMPS_RSP in correct state. "));) + } + + /* PE is going to wakeup irrespective of whether + * SIR_HAL_EXIT_BMPS_REQ was successful or not + */ + switch (rspStatus) + { + case eHAL_STATUS_SUCCESS: + retStatus = eSIR_SME_SUCCESS; + break; + + default: + { + /* PE is going to be awake irrespective of whether EXIT_BMPS_REQ + * failed or not. This is mainly to eliminate the dead-lock condition + * But, PMC will be informed about the error. + */ + retStatus = eSIR_SME_BMPS_REQ_FAILED; + } + break; + + } + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP; + + // turn on background scan + pMac->sys.gSysEnableScanMode = true; + + // send response to PMC + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) ) + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus, 0, 0); + } + + if ( pMac->pmm.gPmmExitBmpsReasonCode == eSME_MISSED_BEACON_IND_RCVD) + { + PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP with MISSED_BEACON"));) + pmmMissedBeaconHandler(pMac); + } + else if(pMac->pmm.inMissedBeaconScenario) + { + PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP in missed beacon scenario but reason code not correct"));) + pmmMissedBeaconHandler(pMac); + } + else + { + // Enable heartbeat timer + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + return; +} + + +/** + * pmmMissedBeaconHandler() + * + *FUNCTION: + * This function is called when PMM receives an eWNI_PMC_EXIT_BMPS_REQ + * with reason code being eSME_MISSED_BEACON_IND_RCVD. + * + *NOTE: + * @param pMac pointer to Global Mac structure. + * @return none + */ +void pmmMissedBeaconHandler(tpAniSirGlobal pMac) +{ + tANI_U8 pwrSaveSessionId; + tANI_U32 beaconInterval = 0; + tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount; + tpPESession psessionEntry; + + /* Copy the power save sessionId to the local variable */ + pwrSaveSessionId = pMac->pmm.sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac,pwrSaveSessionId))==NULL) + { + pmmLog(pMac, LOGE,FL("Session Does not exist for given sessionID")); + return; + } + + + PELOGE(pmmLog(pMac, LOG1, FL("The device woke up due to MISSED BEACON "));) + + /* Proceed only if HeartBeat timer is created */ + if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) && + (pMac->lim.gLimTimersCreated)) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &beaconInterval) != eSIR_SUCCESS) + PELOG1(pmmLog(pMac, LOG1, FL("Fail to get BEACON_INTERVAL value"));) + + /* Change timer to reactivate it in future */ + heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval); + + if( tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS) + { + PELOG1(pmmLog(pMac, LOG1, FL("Fail to change HeartBeat timer"));) + } + + /* update some statistics */ + if(LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + } + + /* To handle the missed beacon failure, message is being posted to self as if the + * actual timer has expired. This is done to make sure that there exists one + * common entry and exit points + */ + limResetHBPktCount(psessionEntry); // 090805: This is what it SHOULD be. If we even need it. + pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT); + } + else + { + PELOGE(pmmLog(pMac, LOGE, FL("HeartBeat Timer is not created, cannot re-activate"));) + } + + return; +} + + +/** + * pmmExitBmpsIndicationHandler + * + *FUNCTION: + * This function sends a Power Save Indication. back to PMC layer. + * This indication is originated from softmac and will occur in the following two + * scenarios: + * 1) When softmac is in sleep state and wakes up to parse TIM and finds that + * AP has the data pending for this STA, then it sends this indication to let PMC know + * that it is going to be awake and pass the control over to PMC + * 2) When softmac is in sleep state and wakes up to parse TIM and determines that + * current TIM is DTIM and AP has buffered broadcast/multicast frames. + * In this scenario, softmac needs to remain awake for broadcast/multicast frames and it + * sends an indication to PMC that it is awake and passes the control over to PMC. + * 3) If station is awake and 'fEnablePwrSaveImmediately' flag is set, then softmac will transmit all + * frames in its queues and go to sleep. Before going to sleep it sends the notification to PMC that + * it is going to sleep. + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param rspStatus Status of the response, Success or an error code. + * + * @return none. + */ + +void pmmExitBmpsIndicationHandler(tpAniSirGlobal pMac, tANI_U8 mode, eHalStatus rspStatus) +{ + + tANI_U32 beaconInterval = 0; + tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount; + tANI_U8 powersavesessionId; + tpPESession psessionEntry; + + /* Copy the power save sessionId to the local variable */ + powersavesessionId = pMac->pmm.sessionId; + + psessionEntry = peFindSessionBySessionId(pMac,powersavesessionId); + + if(psessionEntry == NULL) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Session does Not exist with given sessionId :%d "),powersavesessionId);) + return; + } + + /* Since, the hardware is already wokenup, PE also wakesup and informs + * the upper layers that the system is waking up. Hence always Success is + * sent in the reason code for the message sent to PMC + */ + + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Received SIR_HAL_EXIT_BMPS_IND from HAL, Exiting BMPS sleep mode")); ) + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP; + + /* turn on background scan */ + pMac->sys.gSysEnableScanMode = true; + + pmmBmpsUpdateWakeupIndCnt(pMac); + + /* Inform SME about the system awake state */ + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_BMPS_IND, + eSIR_SME_SUCCESS, 0, 0); + + switch(rspStatus) + { + + /* The SoftMAC sends wakeup indication even when Heart-Beat timer expired + * The PE should start taking action against this as soon as it identifies + * that the SoftMAC has identified heart-beat miss + */ + case eHAL_STATUS_HEARTBEAT_TMOUT: + { + PELOG1(pmmLog(pMac, LOG1, + FL("pmmBmps: The device woke up due to HeartBeat Timeout"));) + + /* Proceed only if HeartBeat timer is created */ + if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) && + (pMac->lim.gLimTimersCreated)) + { + + /* Read the beacon interval from sessionTable */ + beaconInterval = psessionEntry->beaconParams.beaconInterval; + + /* Change timer to reactivate it in future */ + heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval); + + if(tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS) + { + PELOG1(pmmLog(pMac, LOG1, + FL("pmmBmps: Unable to change HeartBeat timer"));) + } + + /* update some statistics */ + if(LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + } + + /* To handle the heartbeat failure, message is being posted to self as if the + * actual timer has expired. This is done to make sure that there exists one + * common entry and exit points + */ + pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT); + + } + else + { + + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: HeartBeat Timer is not created, cannot re-activate"));) + } + } + break; + + case eHAL_STATUS_NTH_BEACON_DELIVERY: + break; + + default: + break; + + } + + return; + +} + + +// -------------------------------------------------------------------- +/** + * pmmProcessMessage + * + * FUNCTION: Processes the next received Power Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void pmmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + switch (pMsg->type) + { + case eWNI_PMC_PWR_SAVE_CFG: + { + tpSirPowerSaveCfg pPSCfg; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + pPSCfg = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if ( NULL == pPSCfg ) + { + pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for PMC Config"); + } + (void) vos_mem_copy(pPSCfg, pMbMsg->data, sizeof(tSirPowerSaveCfg)); + (void) pmmSendPowerSaveCfg(pMac, pPSCfg); + } + break; + + case eWNI_PMC_ENTER_BMPS_REQ: + pmmInitBmpsPwrSave(pMac); + break; + + case WDA_ENTER_BMPS_RSP: + pmmInitBmpsResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_BMPS_REQ: + { + tpExitBmpsInfo pExitBmpsInfo; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + pExitBmpsInfo = vos_mem_malloc(sizeof(tExitBmpsInfo)); + if ( NULL == pExitBmpsInfo ) + { + pmmLog(pMac, LOGP, "PMM: Failed to allocate memory for Exit BMPS Info "); + } + (void) vos_mem_copy(pExitBmpsInfo, pMbMsg->data, sizeof(tExitBmpsInfo)); + (void) pmmExitBmpsRequestHandler(pMac, pExitBmpsInfo); + } + break; + + case WDA_EXIT_BMPS_RSP: + pmmExitBmpsResponseHandler(pMac, pMsg); + break; + + case WDA_EXIT_BMPS_IND: + pmmExitBmpsIndicationHandler(pMac, SIR_PM_ACTIVE_MODE, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_ENTER_IMPS_REQ: + pmmEnterImpsRequestHandler(pMac); + break; + + case WDA_ENTER_IMPS_RSP: + pmmEnterImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_EXIT_IMPS_REQ: + pmmExitImpsRequestHandler(pMac); + break; + + case WDA_EXIT_IMPS_RSP: + pmmExitImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_ENTER_UAPSD_REQ: + pmmEnterUapsdRequestHandler(pMac); + break; + + case WDA_ENTER_UAPSD_RSP: + pmmEnterUapsdResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_UAPSD_REQ: + pmmExitUapsdRequestHandler(pMac); + break; + + case WDA_EXIT_UAPSD_RSP: + pmmExitUapsdResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + pmmSendWowlAddBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + pmmSendWowlDelBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_ENTER_WOWL_REQ: + pmmEnterWowlRequestHandler(pMac, pMsg); + break; + + case WDA_WOWL_ENTER_RSP: + pmmEnterWowlanResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_WOWL_REQ: + pmmExitWowlanRequestHandler(pMac, pMsg); + break; + + case WDA_WOWL_EXIT_RSP: + pmmExitWowlanResponseHandler(pMac, pMsg); + break; +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + pmmFilterMatchCountResponseHandler(pMac, pMsg); + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_GETINFO_RSP: + pmmGTKOffloadGetInfoResponseHandler(pMac, pMsg); + break; +#endif // WLAN_FEATURE_GTK_OFFLOAD + + default: + PELOGW(pmmLog(pMac, LOGW, + FL("PMM: Unknown message in pmmMsgQ type %d, potential memory leak!!"), + pMsg->type);) + } + + if (NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + pMsg->bodyptr = NULL; + } +} + + + + + + +// -------------------------------------------------------------------- +/** + * pmmPostMessage + * + * FUNCTION: + * Post a message to the pmm message queue + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMsg pointer to message + * @return None + */ + +tSirRetStatus +pmmPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + VOS_STATUS vosStatus; + vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + pmmLog(pMac, LOGP, FL("vos_mq_post_message failed with status code %d"), vosStatus); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * pmmEnterImpsRequestHandler + * + * FUNCTION: + * This function sends the idle mode power save request from host device + * drive to HAL. This function is called from pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmEnterImpsRequestHandler (tpAniSirGlobal pMac) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /*Returns True even single active session present */ + if(peIsAnySessionActive(pMac)) + { + /* Print active pesession and tracedump once in every 16 + * continous error. + */ + if (!(pMac->pmc.ImpsReqFailCnt & 0xF)) + { + pePrintActiveSession(pMac); + } + resultCode = eSIR_SME_INVALID_STATE; + pmmLog(pMac, LOGE, FL("Session is active go to failure resultCode = " + "eSIR_SME_INVALID_STATE (%d)"),resultCode); + goto failure; + } + + if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) && + (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WAKEUP)) || + ((pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE) && + (pMac->lim.gLimSmeState != eLIM_SME_JOIN_FAILURE_STATE)) || + (pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE) || + limIsChanSwitchRunning (pMac) || + limIsInQuietDuration (pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request"), + pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + goto failure; + } + + // change PE state and send the request to HAL + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_SLEEP_RSP; + if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: IMPS Sleep Request failed: sending response: %x"), retStatus);) + + resultCode = eSIR_SME_IMPS_REQ_FAILED; + goto failure; + } + else + { + PELOG1(pmmLog(pMac, LOG1, + FL("pmmImps: Waiting for SoftMac response for IMPS request"));) + } + return; + +failure: + pMac->pmm.gPmmState = origState; + pmmImpsUpdateSleepErrStats(pMac, retStatus); + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); + +} + +// -------------------------------------------------------------------- +/** + * pmmEnterImpsResponseHandler + * + * FUNCTION: + * This function receives the response from HAL layer for the idle mode + * power save request sent. The function is also responsible for checking + * the correctness of the system state before configuring the new state + * on success. This function is called by pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC, Status code + * @return None + */ +void pmmEnterImpsResponseHandler (tpAniSirGlobal pMac, eHalStatus rspStatus) +{ + tPmmState nextState = pMac->pmm.gPmmState; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued since + * the initiating the WDA_ENTER_IMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_SLEEP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Receives IMPS sleep rsp in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + + goto failure; + } + + if(eHAL_STATUS_SUCCESS == rspStatus) + { + //if success, change the state to IMPS sleep mode + pMac->pmm.gPmmState = ePMM_STATE_IMPS_SLEEP; + + PELOG2(pmmLog(pMac, LOG2, + FL("pmmImps: Received successful WDA_ENTER_IMPS_RSP from HAL"));) + + //update power save statistics + pmmImpsUpdatePwrSaveStats(pMac); + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); + } + else + { + // go back to previous state if request failed + nextState = ePMM_STATE_IMPS_WAKEUP; + resultCode = eSIR_SME_CANNOT_ENTER_IMPS; + goto failure; + } + return; + +failure: + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImpsSleepRsp failed, Ret Code: %d, next state will be: %d"), + rspStatus, + pMac->pmm.gPmmState);) + + pMac->pmm.gPmmState = nextState; + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitImpsRequestHandler + * + * FUNCTION: + * This function is called by pmmProcessMsg(). The function sends a request + * to HAL to wakeup the device from idle mode power save mode. + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitImpsRequestHandler (tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if (ePMM_STATE_IMPS_SLEEP == pMac->pmm.gPmmState) + { + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_WAKEUP_RSP; + if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) != + eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Wakeup request message sent to SoftMac failed"));) + resultCode = eSIR_SME_IMPS_REQ_FAILED; + goto failure; + } + } + else + { + // PE in invalid state + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Wakeup Req received in invalid state: %x"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + + goto failure; + } + return; + +failure: + PELOGE(pmmLog (pMac, LOGE, + FL("pmmImps: Changing to IMPS wakeup mode failed, Ret Code: %d, Next State: %d"), + retStatus, pMac->pmm.gPmmState);) + + pMac->pmm.gPmmState = origState; + pmmImpsUpdateWakeupErrStats(pMac, retStatus); + + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_IMPS_RSP, + resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitImpsResponseHandler + * + * FUNCTION: + * This function receives the response from HAL layer for the idle mode + * power save request sent. The function is also responsible for checking + * the correctness of the system state before configuring the new state + * on success. This function is called by pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued since + * the initiating the WDA_EXIT_IMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Received 'Wakeup' response in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + } + + switch(rspStatus) + { + case eHAL_STATUS_SUCCESS: + { + resultCode = eSIR_SME_SUCCESS; + PELOG2(pmmLog(pMac, LOG2, + FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Successful response from HAL"));) + } + break; + + default: + { + resultCode = eSIR_SME_IMPS_REQ_FAILED; + PELOGW(pmmLog(pMac, LOGW, + FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Failure Status from HAL"));) + } + break; + + } + + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WAKEUP; + + //update power save statistics + pmmImpsUpdateWakeupStats(pMac); + + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_IMPS_RSP, + resultCode, 0, 0); + return; + +} + +// -------------------------------------------------------------------- +/** + * pmmEnterUapsdRequestHandler + * + * FUNCTION: + * This function process the eWNI_PMC_ENTER_UAPSD_REQ from PMC, + * checks the correctness of the system state before configuring + * PMM to the new ePMM_STATE_UAPSD_WT_SLEEP_RSP state, and invokes + * invokes pmmUapsdSendChangePwrSaveMsg() to send + * WDA_ENTER_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmEnterUapsdRequestHandler (tpAniSirGlobal pMac) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( (pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) || + limIsSystemInScanState(pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request"), + pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_SLEEP_RSP; + + if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: HAL_ENTER_UAPSD_REQ failed with response: %x"), retStatus);) + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + goto failure; + } + + PELOG1(pmmLog(pMac, LOG1, FL("pmmUapsd: Waiting for WDA_ENTER_UAPSD_RSP "));) + return; + +failure: + pMac->pmm.gPmmState = origState; + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, resultCode, 0, 0); + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmEnterUapsdResponseHandler + * + * FUNCTION: + * This function processes the SIR_HAL_ENTER_UAPSD_RSP from HAL. + * If the response is successful, it puts PMM into ePMM_STATE_UAPSD_SLEEP + * state and sends back success response to PMC. + * + * NOTE: + * + * @param limMsg + * @return None + */ +void pmmEnterUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpUapsdParams pUapsdRspMsg; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_ENTER_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + /* Copy the power save sessionId to the local variable */ + PowersavesessionId = pMac->pmm.sessionId; + + if (NULL == limMsg->bodyptr) + { + PELOGE(pmmLog(pMac, LOGE, FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP with NULL "));) + return; + } + + pUapsdRspMsg = (tpUapsdParams)(limMsg->bodyptr); + + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if(pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_SLEEP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP while in incorrect state: %d"), + pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0); + return; + } + + if(pUapsdRspMsg->status == eHAL_STATUS_SUCCESS) + { + PELOGW(pmmLog(pMac, LOGW, + FL("pmmUapsd: Received successful response from HAL to enter UAPSD mode "));) + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_SLEEP; + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: SIR_HAL_ENTER_UAPSD_RSP failed, informing SME"));) + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + retStatus = eSIR_SME_UAPSD_REQ_FAILED; + } + + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus, 0, 0); + } + + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmExitUapsdRequestHandler + * + * FUNCTION: + * This function process the eWNI_PMC_EXIT_UAPSD_REQ from PMC, + * checks the correctness of the system state before configuring + * PMM to the new ePMM_STATE_UAPSD_WT_WAKEUP_RSP state, and + * invokes pmmUapsdSendChangePwrSaveMsg() to send + * SIR_HAL_EXIT_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitUapsdRequestHandler(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if (ePMM_STATE_UAPSD_SLEEP == pMac->pmm.gPmmState) + { + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_WAKEUP_RSP; + if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) != + eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: sending EXIT_UAPSD to HAL failed "));) + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + goto failure; + } + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Rcv EXIT_UAPSD from PMC in invalid state: %x"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + return; + +failure: + pMac->pmm.gPmmState = origState; + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Waking up from UAPSD mode failed, Ret Code: %d, Next State: %d"), + retStatus, pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitUapsdResponseHandler + * + * FUNCTION: + * This function receives the SIR_HAL_EXIT_UAPSD_RSP from HAL and is + * responsible for checking the correctness of the system state + * before configuring PMM to the new ePMM_STATE_BMPS_SLEEP state + * and send eWNI_PMC_EXIT_UAPSD_RSP to PMC. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + tUapsdParams *pUapsdExitRspParams; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_EXIT_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received HAL_EXIT_UAPSD_RSP in invalid state: %d"), + pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0); + return; + } + pUapsdExitRspParams = (tUapsdParams *)(limMsg->bodyptr); + + PowersavesessionId = pMac->pmm.sessionId; + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if(NULL == pUapsdExitRspParams ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received HAL_EXIT_UAPSD_RSP message with zero parameters:"));) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_UAPSD_REQ_FAILED, 0, 0); + return; + } + switch(pUapsdExitRspParams->status) + { + case eHAL_STATUS_SUCCESS: + resultCode = eSIR_SME_SUCCESS; + PELOGW(pmmLog(pMac, LOGW, + FL("Received SIR_HAL_EXIT_UAPSD_RSP with Successful response "));) + break; + default: + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + PELOGE(pmmLog(pMac, LOGW, + FL("Received SIR_HAL_EXIT_UAPSD_RSP with Failure Status"));) + break; + } + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0); + } + return; +} + +/** ------------------------------------------------------------ +\fn pmmSendWowlAddBcastPtrn +\brief This function sends a SIR_HAL_WOWL_ADD_BCAST_PTRN +\ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + --------------------------------------------------------------*/ +void pmmSendWowlAddBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirWowlAddBcastPtrn pBcastPtrn; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pBcastPtrn = vos_mem_malloc(sizeof(*pBcastPtrn)); + if ( NULL == pBcastPtrn ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Add Bcast Pattern ")); + return; + } + (void) vos_mem_copy(pBcastPtrn, pMbMsg->data, sizeof(*pBcastPtrn)); + + if (NULL == pBcastPtrn) + { + pmmLog(pMac, LOGE, FL("Add broadcast pattern message is NULL ")); + return; + } + + msgQ.type = WDA_WOWL_ADD_BCAST_PTRN; + msgQ.reserved = 0; + msgQ.bodyptr = pBcastPtrn; + msgQ.bodyval = 0; + + pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_ADD_BCAST_PTRN to HAL")); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + if (pBcastPtrn != NULL) + vos_mem_free(pBcastPtrn); + pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_ADD_BCAST_PTRN failed, reason=%X"), retCode ); + } + return; +} + +/** ------------------------------------------------------------ +\fn pmmSendWowlDelBcastPtrn +\brief This function sends a SIR_HAL_WOWL_DEL_BCAST_PTRN +\ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + --------------------------------------------------------------*/ +void pmmSendWowlDelBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirWowlDelBcastPtrn pDeletePtrn; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pDeletePtrn = vos_mem_malloc(sizeof(*pDeletePtrn)); + if ( NULL == pDeletePtrn ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern ")); + return; + } + (void) vos_mem_copy(pDeletePtrn, pMbMsg->data, sizeof(*pDeletePtrn)); + + if (NULL == pDeletePtrn) + { + pmmLog(pMac, LOGE, FL("Delete broadcast pattern message is NULL ")); + return; + } + + msgQ.type = WDA_WOWL_DEL_BCAST_PTRN; + msgQ.reserved = 0; + msgQ.bodyptr = pDeletePtrn; + msgQ.bodyval = 0; + + pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_DEL_BCAST_PTRN")); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + if (NULL != pDeletePtrn) + vos_mem_free(pDeletePtrn); + pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_DEL_BCAST_PTRN failed, reason=%X"), retCode ); + } + return; +} + +/** --------------------------------------------------------- +\fn pmmEnterWowlRequestHandler +\brief LIM process the eWNI_PMC_ENTER_WOWL_REQ message, and +\ invokes pmmSendWowlEnterRequest() to send +\ WDA_WOWL_ENTER_REQ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + ------------------------------------------------------------*/ +void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeWowlEnterParams pSmeWowlParams = NULL; + tpSirHalWowlEnterParams pHalWowlParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 cfgValue = 0; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tpPESession pSessionEntry = NULL; + tANI_U8 peSessionId = 0; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + pSmeWowlParams = (tpSirSmeWowlEnterParams)(pMbMsg->data); + if (NULL == pSmeWowlParams) + { + pmmLog(pMac, LOGE, + FL("NULL message received")); + return; + } + + if (pMac->psOffloadEnabled) + goto skip_pmm_state_check; + + pSessionEntry = peFindSessionByBssid(pMac, pSmeWowlParams->bssId, + &peSessionId); + if (NULL == pSessionEntry) + { + pmmLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + goto end; + } + pMac->pmm.sessionId = peSessionId; + + if ((pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && (pMac->pmm.gPmmState != ePMM_STATE_WOWLAN)) + { + pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ in invalid Power Save state ")); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0); + goto end; + } + +skip_pmm_state_check: + + pHalWowlParams = vos_mem_malloc(sizeof(*pHalWowlParams)); + if ( NULL == pHalWowlParams ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for Enter Wowl Request ")); + goto end; + } + (void) vos_mem_set((tANI_U8 *)pHalWowlParams, sizeof(*pHalWowlParams), 0); + + // fill in the message field + pHalWowlParams->ucMagicPktEnable = pSmeWowlParams->ucMagicPktEnable; + pHalWowlParams->ucPatternFilteringEnable = pSmeWowlParams->ucPatternFilteringEnable; + (void)vos_mem_copy( (tANI_U8 *)pHalWowlParams->magicPtrn, (tANI_U8 *)pSmeWowlParams->magicPtrn, + sizeof(tSirMacAddr) ); + +#ifdef WLAN_WAKEUP_EVENTS + pHalWowlParams->ucWoWEAPIDRequestEnable = pSmeWowlParams->ucWoWEAPIDRequestEnable; + pHalWowlParams->ucWoWEAPOL4WayEnable = pSmeWowlParams->ucWoWEAPOL4WayEnable; + pHalWowlParams->ucWowNetScanOffloadMatch = pSmeWowlParams->ucWowNetScanOffloadMatch; + pHalWowlParams->ucWowGTKRekeyError = pSmeWowlParams->ucWowGTKRekeyError; + pHalWowlParams->ucWoWBSSConnLoss = pSmeWowlParams->ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + if (!pMac->psOffloadEnabled) + pHalWowlParams->bssIdx = pSessionEntry->bssIdx; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE")); + goto end; + } + pHalWowlParams->ucUcastPatternFilteringEnable = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE")); + goto end; + } + pHalWowlParams->ucWowChnlSwitchRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE ")); + goto end; + } + pHalWowlParams->ucWowDeauthRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE ")); + goto end; + } + pHalWowlParams->ucWowDisassocRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_MISSED_BEACON, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_MISSED_BEACON ")); + goto end; + } + pHalWowlParams->ucWowMaxMissedBeacons = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD ")); + goto end; + } + pHalWowlParams->ucWowMaxSleepUsec = (tANI_U8)cfgValue; + + pHalWowlParams->sessionId = pSmeWowlParams->sessionId; + //Send message to HAL + if( eSIR_SUCCESS != (retCode = pmmSendWowlEnterRequest( pMac, pHalWowlParams))) + { + pmmLog(pMac, LOGE, FL("Send ENTER_WOWL_REQ to HAL failed, reasonCode %d "), retCode); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_WOWL_ENTER_REQ_FAILED, 0, 0); + goto end; + } + return; + +end: + if (pHalWowlParams != NULL) + vos_mem_free(pHalWowlParams); + return; +} + + +/** ------------------------------------------------------------ +\fn pmmSendWowlEnterRequest +\brief LIM sends a WDA_WOWL_ENTER_REQ message to HAL with +\ the message structure pHalWowlParams. HAL shall later +\ send a WDA_WOWL_ENTER_RSP with the same pointer +\ to the message structure back to PMM. +\param tpAniSirGlobal pMac +\param tpSirHalWowlEnterParams pHalWowlParams +\return tSirRetStatus + --------------------------------------------------------------*/ +tSirRetStatus pmmSendWowlEnterRequest(tpAniSirGlobal pMac, tpSirHalWowlEnterParams pHalWowlParams) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (NULL == pHalWowlParams) + return eSIR_FAILURE; + + msgQ.type = WDA_WOWL_ENTER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pHalWowlParams; + msgQ.bodyval = 0; + + if (!pMac->psOffloadEnabled) + { + /* Defer any incoming message until we get + * a WDA_WOWL_ENTER_RSP from HAL + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + } + + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if( eSIR_SUCCESS != retCode ) + { + pmmLog( pMac, LOGE, FL("Posting WDA_WOWL_ENTER_REQ failed, reason=%X"), retCode ); + return retCode; + } + return retCode; +} + +/** --------------------------------------------------------- +\fn pmmEnterWowlanResponseHandler +\brief LIM process the WDA_WOWL_ENTER_RSP message. +\ and sends eWNI_PMC_ENTER_WOWL_RSP to SME. +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +\return None + ------------------------------------------------------------*/ +void pmmEnterWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirHalWowlEnterParams pWowlEnterParams; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_WOWL_ENTER_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pWowlEnterParams = (tpSirHalWowlEnterParams)(limMsg->bodyptr); + if (NULL == pWowlEnterParams) + { + pmmLog(pMac, LOGE, FL("Recvd WDA_WOWL_ENTER_RSP with NULL msg ")); + smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED; + } + else + { + rspStatus = pWowlEnterParams->status; + + if(rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to enter WOWLAN ")); + pMac->pmm.gPmmState = ePMM_STATE_WOWLAN; + } + else + { + pmmLog(pMac, LOGE, FL("HAL enter WOWLAN failed, informing SME")); + smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, smeRspCode, 0, 0); + return; +} + +/** --------------------------------------------------------- +\fn pmmExitWowlanRequestHandler +\brief PE process the eWNI_PMC_EXIT_WOWL_REQ message. +\ and sends WDA_WOWL_EXIT_REQ to HAL. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeWowlExitParams pSmeWowlParams = NULL; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + tpPESession pSessionEntry = NULL; + tpSirHalWowlExitParams pHalWowlMsg = NULL; + tANI_U8 PowersavesessionId = 0; + + pSmeWowlParams = (tpSirSmeWowlExitParams)(pMbMsg->data); + if (NULL == pSmeWowlParams) + { + limLog(pMac, LOGE, + FL("NULL message received")); + return; + } + + if (pMac->psOffloadEnabled) + goto skip_pe_session_lookup; + + PowersavesessionId = pMac->pmm.sessionId; + + if((pSessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId)) == NULL ) + { + PELOGW(pmmLog(pMac, LOGE, FL("pmmWowl : failed to allocate memory"));) + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + +skip_pe_session_lookup: + + pHalWowlMsg = vos_mem_malloc(sizeof(*pHalWowlMsg)); + if ( NULL == pHalWowlMsg ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Add Bcast Pattern ")); + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( !pMac->psOffloadEnabled && pMac->pmm.gPmmState != ePMM_STATE_WOWLAN ) + { + pmmLog(pMac, LOGE, + FL("Exit WOWLAN Request received in invalid state PMM=%d "), + pMac->pmm.gPmmState); + smeRspCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + + (void) vos_mem_set((tANI_U8 *)pHalWowlMsg, sizeof(*pHalWowlMsg), 0); + + if (!pMac->psOffloadEnabled) + pHalWowlMsg->bssIdx = pSessionEntry->bssIdx; + + pHalWowlMsg->sessionId = pSmeWowlParams->sessionId; + if((retStatus = pmmSendExitWowlReq(pMac, pHalWowlMsg)) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, + FL("Fail to send WDA_WOWL_EXIT_REQ, reason code %d"), + retStatus); + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + return; + +failure: + if (pHalWowlMsg != NULL) + vos_mem_free(pHalWowlMsg); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, smeRspCode, 0, 0); + return; +} + +/** --------------------------------------------------------- +\fn pmmSendExitWowlReq +\brief This function sends the WDA_WOWL_EXIT_REQ +\ message to HAL. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +tSirRetStatus pmmSendExitWowlReq(tpAniSirGlobal pMac, tpSirHalWowlExitParams pHalWowlParams) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (NULL == pHalWowlParams) + return eSIR_FAILURE; + + msgQ.type = WDA_WOWL_EXIT_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pHalWowlParams; + msgQ.bodyval = 0; + + pmmLog(pMac, LOGW, FL("Sending WDA_WOWL_EXIT_REQ")); + + if (!pMac->psOffloadEnabled) + { + /* we need to defer any incoming messages until + * we get a WDA_WOWL_EXIT_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + } + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + pmmLog( pMac, LOGE, + FL("Posting WDA_WOWL_EXIT_REQ failed, reason=%X"), + retCode ); + + return retCode; +} + +/** --------------------------------------------------------- +\fn pmmExitWowlanResponseHandler +\brief This function process the WDA_WOWL_EXIT_RSP message. +\ and sends back eWNI_PMC_EXIT_WOWL_RSP to SME. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + + tpSirHalWowlExitParams pHalWowlRspMsg; + eHalStatus rspStatus = eHAL_STATUS_FAILURE; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_WOWL_EXIT_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pHalWowlRspMsg = (tpSirHalWowlExitParams)(limMsg->bodyptr); + if (NULL == pHalWowlRspMsg) + { + pmmLog(pMac, LOGE, FL("Recvd WDA_WOWL_ENTER_RSP with NULL msg ")); + } + else + { + // restore PMM state to BMPS mode + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + rspStatus = pHalWowlRspMsg->status; + } + + if( rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcvd successful rsp from HAL to exit WOWLAN ")); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_SUCCESS, 0, 0); + } + else + { + pmmLog(pMac, LOGE, FL("Rcvd failure rsp from HAL to exit WOWLAN ")); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_WOWL_EXIT_REQ_FAILED, 0, 0); + } + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmImpsSendChangePwrSaveMsg + * + * FUNCTION: + * This function is called to toggle the Idle mode power save mode + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @param mode to be configured + * @return None + */ + +tSirRetStatus pmmImpsSendChangePwrSaveMsg(tpAniSirGlobal pMac, tANI_U8 mode) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (SIR_PM_SLEEP_MODE == mode) + { + msgQ.type = WDA_ENTER_IMPS_REQ; + PELOG2(pmmLog (pMac, LOG2, FL("Sending WDA_ENTER_IMPS_REQ to HAL"));) + } + else + { + msgQ.type = WDA_EXIT_IMPS_REQ; + PELOG2(pmmLog (pMac, LOG2, FL("Sending WDA_EXIT_IMPS_REQ to HAL"));) + } + + msgQ.reserved = 0; + msgQ.bodyptr = NULL; + msgQ.bodyval = 0; + + /* we need to defer any incoming messages until we get a + * WDA_ENTER_IMPS_REQ or WDA_EXIT_IMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg(pMac, &msgQ); + if ( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("WDA_ENTER/EXIT_IMPS_REQ to HAL failed, reason=%X"), retStatus);) + } + + return retStatus; +} + +// -------------------------------------------------------------------- +/** + * pmmUapsdSendChangePwrSaveMsg + * + * FUNCTION: + * This function is called to send either WDA_ENTER_UAPSD_REQ + * or WDA_EXIT_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param pMac Global handle to MAC + * @param mode mode to be configured + * @return tSirRetStatus + */ +tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tpUapsdParams pUapsdParams = NULL; + tSirMsgQ msgQ; + tpPESession pSessionEntry; + tpExitUapsdParams pExitUapsdParams = NULL; + + if((pSessionEntry = peGetValidPowerSaveSession(pMac)) == NULL ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_FAILURE; + return retStatus; + } + + if (SIR_PM_SLEEP_MODE == mode) + { + pUapsdParams = vos_mem_malloc(sizeof(tUapsdParams)); + if ( NULL == pUapsdParams ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pUapsdParams, sizeof(tUapsdParams), 0); + msgQ.type = WDA_ENTER_UAPSD_REQ; + msgQ.bodyptr = pUapsdParams; + + /* + * An AC is delivery enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_DLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + + /* + * An AC is trigger enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + + pUapsdParams->bssIdx = pSessionEntry->bssIdx; + + PELOGW(pmmLog(pMac, LOGW, + FL("UAPSD Mask: static = 0x%x, DeliveryEnabled = 0x%x, TriggerEnabled = 0x%x "), + pMac->lim.gUapsdPerAcBitmask, + pMac->lim.gUapsdPerAcDeliveryEnableMask, + pMac->lim.gUapsdPerAcTriggerEnableMask);) + + PELOGW(pmmLog(pMac, LOGW, FL("Delivery Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d "), + pUapsdParams->bkDeliveryEnabled, + pUapsdParams->beDeliveryEnabled, + pUapsdParams->viDeliveryEnabled, + pUapsdParams->voDeliveryEnabled);) + + PELOGW(pmmLog(pMac, LOGW, FL("Trigger Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d "), + pUapsdParams->bkTriggerEnabled, + pUapsdParams->beTriggerEnabled, + pUapsdParams->viTriggerEnabled, + pUapsdParams->voTriggerEnabled);) + + PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_ENTER_UAPSD_REQ to HAL"));) + } + else + { + pExitUapsdParams = vos_mem_malloc(sizeof(tExitUapsdParams)); + if ( NULL == pExitUapsdParams ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pExitUapsdParams, sizeof(tExitUapsdParams), 0); + msgQ.type = WDA_EXIT_UAPSD_REQ; + msgQ.bodyptr = pExitUapsdParams; + pExitUapsdParams->bssIdx = pSessionEntry->bssIdx; + PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_EXIT_UAPSD_REQ to HAL"));) + } + + /* we need to defer any incoming messages until we get a + * WDA_ENTER/EXIT_UAPSD_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.reserved = 0; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg(pMac, &msgQ); + if ( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: WDA_ENTER/EXIT_UAPSD_REQ to HAL failed, reason=%X"), + retStatus);) + if (SIR_PM_SLEEP_MODE == mode) + vos_mem_free(pUapsdParams); + else + vos_mem_free(pExitUapsdParams); + } + + return retStatus; +} + + +// -------------------------------------------------------------------- +/** + * pmmUpdateImpsPwrSaveStats + * + * FUNCTION: + * This function is called to update the power save statistics in MAC + * for Idle mode power save + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ + +void pmmImpsUpdatePwrSaveStats(tpAniSirGlobal pMac) +{ +} + + +// -------------------------------------------------------------------- +/** + * pmmImpsUpdateWakeupStats + * + * FUNCTION: + * This function is called to update the Wake up statistics in MAC + * for Idle mode power save + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ + +void pmmImpsUpdateWakeupStats (tpAniSirGlobal pMac) +{ +} + +// Collects number of times error occurred while going to sleep mode +void pmmImpsUpdateSleepErrStats(tpAniSirGlobal pMac, + tSirRetStatus retStatus) +{ + pMac->pmm.ImpsSleepErrCnt++; + pMac->pmm.ImpsLastErr = retStatus; + return; +} + +// Collects number of times error occurred while waking up from sleep mode +void pmmImpsUpdateWakeupErrStats(tpAniSirGlobal pMac, + tSirRetStatus retStatus) +{ + pMac->pmm.ImpsWakeupErrCnt++; + pMac->pmm.ImpsLastErr = retStatus; + return; +} + + +// Collects number of times the system has received request or +// response in an invalid state +void pmmImpsUpdateErrStateStats(tpAniSirGlobal pMac) +{ + pMac->pmm.ImpsInvalidStateCnt++; + return; +} + +// Collects number of packets dropped while in IMPS mode +void pmmImpsUpdatePktDropStats(tpAniSirGlobal pMac) +{ + + pMac->pmm.ImpsPktDrpInSleepMode++; + return; +} + +// Collects number of packets dropped while in BMPS mode +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsPktDrpInSleepMode++; + return; +} + +// Collects statistics for number of times BMPS init failed +void pmmBmpsUpdateInitFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsInitFailCnt++; + return; +} + +// Collects statistics for number of times sleep request failed +void pmmBmpsUpdateSleepReqFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsSleeReqFailCnt++; + return; +} + +// Collects statistics for number of times Wakeup request failed +void pmmBmpsUpdateWakeupReqFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsWakeupReqFailCnt++; + return; +} + +// Collects statistics for number of times request / response received in invalid state +void pmmBmpsUpdateInvalidStateCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsInvStateCnt++; + return; +} + +// Collects statistics for number of times wakeup indications received +void pmmBmpsUpdateWakeupIndCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsWakeupIndCnt++; + return; +} + +// Collects statistics for number of times wakeup indications received +void pmmBmpsUpdateHalReqFailureCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsHalReqFailCnt++; + return; +} + +// Collects statistics for number of times requests received from HDD in +// invalid device role +void pmmBmpsUpdateReqInInvalidRoleCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsReqInInvalidRoleCnt++; + return; +} + +// Resets PMM state ePMM_STATE_READY +void pmmResetPmmState(tpAniSirGlobal pMac) +{ + pMac->pmm.gPmmState = ePMM_STATE_READY; + + pMac->pmm.inMissedBeaconScenario = FALSE; + return; +} + +/* Sends Background scan message back to Lim */ +void pmmSendMessageToLim(tpAniSirGlobal pMac, + tANI_U32 msgId) +{ + tSirMsgQ limMsg; + tANI_U32 statusCode; + + limMsg.type = (tANI_U16) msgId; + limMsg.bodyptr = NULL; + limMsg.bodyval = 0; + + if ((statusCode = limPostMsgApi(pMac, &limMsg)) != eSIR_SUCCESS) + { + PELOGW(pmmLog(pMac, LOGW, + FL("posting message %X to LIM failed, reason=%d"), + limMsg.type, statusCode);) + } +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void pmmFilterMatchCountResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirRcvFltPktMatchRsp pRcvFltPktMatchCntRsp; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pRcvFltPktMatchCntRsp = (tpSirRcvFltPktMatchRsp)(limMsg->bodyptr); + if (NULL == pRcvFltPktMatchCntRsp) + { + pmmLog(pMac, LOGE, FL("Received " + "WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP with NULL msg ")); + smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED; + } + else + { + rspStatus = pRcvFltPktMatchCntRsp->status; + if (eHAL_STATUS_SUCCESS == rspStatus) + { + pmmLog(pMac, LOGE, FL("Rcv successful response from HAL to get " + "Packet Coalescing Filter Match Count")); + } + else + { + pmmLog(pMac, LOGE, FL("HAL failed to get Packet Coalescing " + "Filter Match Count, informing SME")); + smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP, + smeRspCode, 0, 0); + return; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void pmmGTKOffloadGetInfoResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRspParams; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_GTK_OFFLOAD_GETINFO_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pGtkOffloadGetInfoRspParams = (tpSirGtkOffloadGetInfoRspParams)(limMsg->bodyptr); + if (NULL == pGtkOffloadGetInfoRspParams) + { + pmmLog(pMac, LOGE, FL("Received WDA_GTK_OFFLOAD_GETINFO_RSP with NULL msg ")); + smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED; + } + else + { + rspStatus = pGtkOffloadGetInfoRspParams->ulStatus; + if(rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to get GTK Offload Information")); + } + else + { + pmmLog(pMac, LOGE, FL("HAL failed to get GTK Offload Information, informing SME")); + smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP, smeRspCode, 0, 0); + return; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/* Powersave Offload Implementation */ +eHalStatus pmmPsOffloadOpen(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + if(psessionEntry->valid) + { + psessionEntry->pmmOffloadInfo.psstate = PMM_FULL_POWER; + psessionEntry->pmmOffloadInfo.bcnmiss = FALSE; + + pmmLog(pMac, LOG1, + FL("ps offload open success for pe session %x"), + psessionEntry->peSessionId); + + return eHAL_STATUS_SUCCESS; + } + else + { + pmmLog(pMac, LOGE, + FL("ps offload open failed:invalid pe session")); + return eHAL_STATUS_FAILURE; + } +} + +eHalStatus pmmPsOffloadClose(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if(psessionEntry->valid) + { + psessionEntry->pmmOffloadInfo.psstate = PMM_FULL_POWER; + psessionEntry->pmmOffloadInfo.bcnmiss = FALSE; + pmmLog(pMac, LOG1, + FL("ps offload close success for pe session %x"), + psessionEntry->peSessionId); + return eHAL_STATUS_SUCCESS; + } + else + { + pmmLog(pMac, LOGW, + FL("ps offload close failed:invalid pe session")); + return eHAL_STATUS_FAILURE; + } +} + +tANI_U8 pmmPsOffloadIsActive(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if(psessionEntry->valid && + psessionEntry->pmmOffloadInfo.psstate == PMM_FULL_POWER) + { + /* Session is in Active State */ + return TRUE; + } + else + { + /* Session is in Power Save State */ + return FALSE; + } +} + +tSirRetStatus pmmOffloadEnterBmpsRespHandler(tpAniSirGlobal pMac, + void *pRespData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpEnablePsParams psRespData = (tpEnablePsParams)pRespData; + + /* + * we need to process all the deferred messages enqueued since + * initiating SIR_HAL_ENTER_BMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(!pRespData) + { + pmmLog(pMac, LOGE, " No Ps Resp Data: Invalid Enter Bmps Resp"); + return eSIR_FAILURE; + } + + pmmLog(pMac, LOG1, + "pmmOffloadEnterBmpsRespHandler Status %x", psRespData->status); + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psRespData->bssid, &sessionId); + + if(!psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Bmps Request"); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_SME_INVALID_STATE, + psRespData->sessionid, 0); + return eSIR_FAILURE; + } + + if(eHAL_STATUS_SUCCESS == psRespData->status) + { + psessionEntry->pmmOffloadInfo.psstate = PMM_POWER_SAVE; + pmmLog(pMac, LOG1, + "EnterBmpsResp Success PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_SUCCESS, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + pmmLog(pMac, LOGE, + "EnterBmpsResp Failed PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + return eSIR_SUCCESS; +} + +eHalStatus pmmOffloadFillUapsdParams(tpPESession psessionEntry, + tpUapsd_Params pUapsdParams) +{ + /* + * If gAcAdmitMask[SIR_MAC_DIRECTION_DLINK] is set,DeliveryEnabled bits are filled + * based on PSB from addts dynamically. If it is not set, DeliveryEnabled bits are + * filled from static values as per UapsdMask in ini file. + */ + + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask); + } + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask); + } + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask); + } + + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask); + } + + /* + * If gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] is set,TriggerEnabled bits are filled + * based on PSB from addts dynamically. If it is not set, TriggerEnabled bits are + * filled from static values as per UapsdMask in ini file. + */ + + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask); + } + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask); + } + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask); + } + + if ( psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask); + } + + return eHAL_STATUS_SUCCESS; +} + +tSirRetStatus pmmOffloadEnterBmpsReqHandler(tpAniSirGlobal pMac, + void *pReqData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpEnablePsParams pEnablePsReqParams; + tSirMsgQ msgQ; + tpSirPsReqData psReqData = (tpSirPsReqData)pReqData; + + if(!psReqData) + { + pmmLog(pMac, LOGE, " No Ps Req Data: Invalid Enter Bmps Request"); + return eSIR_FAILURE; + } + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psReqData->bssId, &sessionId); + + if(NULL == psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Bmps Request"); + return eSIR_FAILURE; + } + + /* Missed Beacon Scenario. Don't allow Power Save */ + if(TRUE == psessionEntry->pmmOffloadInfo.bcnmiss) + { + pmmLog(pMac, LOGE, "Enter Bmps Request in Missed Beacon Scenario"); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + return eSIR_SUCCESS; + } + + pEnablePsReqParams = vos_mem_malloc(sizeof(tEnablePsParams)); + if (NULL == pEnablePsReqParams) + { + pmmLog(pMac, LOGE, + FL("Memory allocation failed for pEnablePsReqParams")); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + return eSIR_MEM_ALLOC_FAILED; + } + + /* Fill the BSSID corresponding to PS Req */ + vos_mem_copy(pEnablePsReqParams->bssid, psReqData->bssId, + sizeof(tSirMacAddr)); + + /* Fill the Sme Session Id */ + pEnablePsReqParams->sessionid = psessionEntry->smeSessionId; + + /* Fill the Last Beacon DTIM Period */ + pEnablePsReqParams->bcnDtimPeriod = psessionEntry->lastBeaconDtimPeriod; + + /* Fill the additional power save setting */ + pEnablePsReqParams->psSetting = psReqData->addOnReq; + + if(eSIR_ADDON_ENABLE_UAPSD == pEnablePsReqParams->psSetting) + { + pmmOffloadFillUapsdParams(psessionEntry, + &pEnablePsReqParams->uapsdParams); + } + + msgQ.type = WDA_ENTER_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pEnablePsReqParams; + msgQ.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msgQ)) + { + pmmLog(pMac, LOGE, FL("Posting WDA_ENTER_BMPS_REQ failed")); + vos_mem_free(pEnablePsReqParams); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + return eSIR_FAILURE; + } + /* + * we need to defer any incoming messages until we + * get a WDA_EXIT_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + pmmLog(pMac, LOG1, FL("WDA_ENTER_BMPS_REQ Successfully sendt to WDA")); + + return eSIR_SUCCESS; +} + +tSirRetStatus pmmOffloadExitBmpsRespHandler(tpAniSirGlobal pMac, + void *pRespData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpDisablePsParams psRespData = (tpDisablePsParams)pRespData; + + /* + * we need to process all the deferred messages enqueued since + * initiating SIR_HAL_EXIT_BMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(!pRespData) + { + pmmLog(pMac, LOGE, " No Ps Resp Data: Invalid Enter Bmps Resp"); + return eSIR_FAILURE; + } + + pmmLog(pMac, LOG1, + "pmmOffloadExitBmpsRespHandler Status %x", psRespData->status); + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psRespData->bssid, &sessionId); + + if(!psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Exit Bmps Request"); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, eSIR_SME_INVALID_STATE, + psRespData->sessionid, 0); + return eSIR_FAILURE; + } + + if(eHAL_STATUS_SUCCESS == psRespData->status) + { + psessionEntry->pmmOffloadInfo.psstate = PMM_FULL_POWER; + pmmLog(pMac, LOG1, + "ExitBmpsResp Success PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, eSIR_SUCCESS, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + pmmLog(pMac, LOGE, + "ExitBmpsResp Failed PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + + if(TRUE == psessionEntry->pmmOffloadInfo.bcnmiss) + { + pmmLog(pMac, LOGE, + "Exit BMPS:- Missed Bcn Scenario PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + /* Missed Beacon Scenario */ + limSendHeartBeatTimeoutInd(pMac, psessionEntry); + } + return eSIR_SUCCESS; +} + +tSirRetStatus pmmOffloadExitBmpsReqHandler(tpAniSirGlobal pMac, + void *pReqData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpDisablePsParams pDisablePsReqParams; + tSirMsgQ msgQ; + tpSirPsReqData psReqData = (tpSirPsReqData)pReqData; + + if(!psReqData) + { + pmmLog(pMac, LOGE, " No Ps Req Data: Invalid Exit Bmps Request"); + return eSIR_FAILURE; + } + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psReqData->bssId, &sessionId); + + if(NULL == psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Bmps Request"); + return eSIR_FAILURE; + } + + pDisablePsReqParams = vos_mem_malloc(sizeof(tDisablePsParams)); + if (NULL == pDisablePsReqParams) + { + pmmLog(pMac, LOGE, FL("Memory allocation failed for tDisablePsParams")); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + return eSIR_MEM_ALLOC_FAILED; + } + + /* Fill the BSSID corresponding to PS Req */ + vos_mem_copy(pDisablePsReqParams->bssid, psReqData->bssId, + sizeof(tSirMacAddr)); + + /* Fill the Sme Session Id */ + pDisablePsReqParams->sessionid = psessionEntry->smeSessionId; + + msgQ.type = WDA_EXIT_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pDisablePsReqParams; + msgQ.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msgQ)) + { + pmmLog(pMac, LOGE, FL("Posting WDA_EXIT_BMPS_REQ failed")); + vos_mem_free(pDisablePsReqParams); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + return eSIR_FAILURE; + } + /* + * we need to defer any incoming messages until we + * get a WDA_EXIT_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + pmmLog(pMac, LOG1, FL("WDA_EXIT_BMPS_REQ Successfully sendt to WDA")); + + return eSIR_SUCCESS; +} + +tSirRetStatus pmmOffloadEnterUapsdRespHandler(tpAniSirGlobal pMac, + void *pRespData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpEnableUapsdParams psRespData = (tpEnableUapsdParams)pRespData; + + /* + * we need to process all the deferred messages enqueued since + * initiating SIR_HAL_ENTER_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(!pRespData) + { + pmmLog(pMac, LOGE, " No Ps Resp Data: Invalid Enter Uapsd Resp"); + return eSIR_FAILURE; + } + + pmmLog(pMac, LOG1, + "pmmOffloadEnterUapsdRespHandler Status %x", psRespData->status); + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psRespData->bssid, &sessionId); + + if(!psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Uapsd Request"); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_SME_INVALID_STATE, + psRespData->sessionid, 0); + return eSIR_FAILURE; + } + + if(eHAL_STATUS_SUCCESS == psRespData->status) + { + pmmLog(pMac, LOG1, + "EnterUapsdResp Success PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_SUCCESS, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + pmmLog(pMac, LOGE, + "EnterUapsdResp Failed PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + return eSIR_SUCCESS; +} + + +tSirRetStatus pmmOffloadEnterUapsdReqHandler(tpAniSirGlobal pMac, + void *pReqData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpEnableUapsdParams pEnableUapsdReqParams; + tSirMsgQ msgQ; + tpSirPsReqData psReqData = (tpSirPsReqData)pReqData; + tANI_U8 uapsdDeliveryMask = 0; + tANI_U8 uapsdTriggerMask = 0; + + if(!psReqData) + { + pmmLog(pMac, LOGE, " No Ps Req Data: Invalid Enter Uapsd Request"); + return eSIR_FAILURE; + } + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psReqData->bssId, &sessionId); + + if(NULL == psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Uapsd Request"); + return eSIR_FAILURE; + } + + pEnableUapsdReqParams = vos_mem_malloc(sizeof(tEnableUapsdParams)); + if (NULL == pEnableUapsdReqParams) + { + pmmLog(pMac, LOGE, + FL("Memory allocation failed for pEnableUapsdReqParams")); + return eSIR_MEM_ALLOC_FAILED; + } + + uapsdDeliveryMask = (psessionEntry->gUapsdPerAcBitmask | + psessionEntry->gUapsdPerAcDeliveryEnableMask); + + uapsdTriggerMask = (psessionEntry->gUapsdPerAcBitmask | + psessionEntry->gUapsdPerAcTriggerEnableMask); + + pEnableUapsdReqParams->uapsdParams.bkDeliveryEnabled = + LIM_UAPSD_GET(ACBK, uapsdDeliveryMask); + + pEnableUapsdReqParams->uapsdParams.beDeliveryEnabled = + LIM_UAPSD_GET(ACBE, uapsdDeliveryMask); + + pEnableUapsdReqParams->uapsdParams.viDeliveryEnabled = + LIM_UAPSD_GET(ACVI, uapsdDeliveryMask); + + pEnableUapsdReqParams->uapsdParams.voDeliveryEnabled = + LIM_UAPSD_GET(ACVO, uapsdDeliveryMask); + + pEnableUapsdReqParams->uapsdParams.bkTriggerEnabled = + LIM_UAPSD_GET(ACBK, uapsdTriggerMask); + + pEnableUapsdReqParams->uapsdParams.beTriggerEnabled = + LIM_UAPSD_GET(ACBE, uapsdTriggerMask); + + pEnableUapsdReqParams->uapsdParams.viTriggerEnabled = + LIM_UAPSD_GET(ACVI, uapsdTriggerMask); + + pEnableUapsdReqParams->uapsdParams.voTriggerEnabled = + LIM_UAPSD_GET(ACVO, uapsdTriggerMask); + + /* Fill the BSSID corresponding to PS Req */ + vos_mem_copy(pEnableUapsdReqParams->bssid, psReqData->bssId, + sizeof(tSirMacAddr)); + + /* Fill the Sme Session Id */ + pEnableUapsdReqParams->sessionid = psessionEntry->smeSessionId; + + msgQ.type = WDA_ENTER_UAPSD_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pEnableUapsdReqParams; + msgQ.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msgQ)) + { + pmmLog(pMac, LOGE, FL("Posting WDA_ENTER_UAPSD_REQ failed")); + vos_mem_free(pEnableUapsdReqParams); + return eSIR_FAILURE; + } + + /* + * we need to defer any incoming messages until we + * get a WDA_EXIT_UAPSD_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + pmmLog(pMac, LOG1, FL("WDA_ENTER_UAPSD_REQ Successfully sendt to WDA")); + return eSIR_SUCCESS; +} + +tSirRetStatus pmmOffloadExitUapsdRespHandler(tpAniSirGlobal pMac, + void *pRespData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpDisableUapsdParams psRespData = (tpDisableUapsdParams)pRespData; + + /* + * we need to process all the deferred messages enqueued since + * initiating SIR_HAL_EXIT_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(!pRespData) + { + pmmLog(pMac, LOGE, " No Ps Resp Data: Invalid Exit Uapsd Resp"); + return eSIR_FAILURE; + } + + pmmLog(pMac, LOG1, + "pmmOffloadExitUapsdRespHandler Status %x", psRespData->status); + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psRespData->bssid, &sessionId); + + if(!psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Exit Uapsd Request"); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_INVALID_STATE, + psRespData->sessionid, 0); + return eSIR_FAILURE; + } + + if(eHAL_STATUS_SUCCESS == psRespData->status) + { + pmmLog(pMac, LOG1, + "ExitUapsdResp Success PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SUCCESS, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + pmmLog(pMac, LOGE, + "ExitUapsdResp Failed PeSessionId %x SmeSessionId %x", + psessionEntry->peSessionId, psessionEntry->smeSessionId); + + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_FAILURE, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + return eSIR_SUCCESS; +} + +tSirRetStatus pmmOffloadExitUapsdReqHandler(tpAniSirGlobal pMac, + void *pReqData) +{ + tANI_U8 sessionId; + tpPESession psessionEntry; + tpDisableUapsdParams pDisableUapsdReqParams; + tSirMsgQ msgQ; + tpSirPsReqData psReqData = (tpSirPsReqData)pReqData; + + if(!psReqData) + { + pmmLog(pMac, LOGE, " No Ps Req Data: Invalid Exit Uapsd Request"); + return eSIR_FAILURE; + } + + /* Get the PE Session Corresponding to BSSID */ + psessionEntry = peFindSessionByBssid(pMac, psReqData->bssId, &sessionId); + + if(NULL == psessionEntry) + { + pmmLog(pMac, LOGE, + " No PE Session for given BSSID : Invalid Enter Uapsd Request"); + return eSIR_FAILURE; + } + + pDisableUapsdReqParams = vos_mem_malloc(sizeof(tDisablePsParams)); + if (NULL == pDisableUapsdReqParams) + { + pmmLog(pMac, LOGE, + FL("Memory allocation failed for pDisableUapsdReqParams")); + return eSIR_MEM_ALLOC_FAILED; + } + + /* Fill the BSSID corresponding to PS Req */ + vos_mem_copy(pDisableUapsdReqParams->bssid, psReqData->bssId, + sizeof(tSirMacAddr)); + + /* Fill the Sme Session Id */ + pDisableUapsdReqParams->sessionid = psessionEntry->smeSessionId; + + msgQ.type = WDA_EXIT_UAPSD_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pDisableUapsdReqParams; + msgQ.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msgQ)) + { + pmmLog(pMac, LOGE, FL("Posting WDA_EXIT_UAPSD_REQ failed")); + vos_mem_free(pDisableUapsdReqParams); + return eSIR_FAILURE; + } + + /* + * we need to defer any incoming messages until we + * get a WDA_EXIT_UAPSD_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + pmmLog(pMac, LOG1, FL("WDA_EXIT_UAPSD_REQ Successfully sendt to WDA")); + return eSIR_SUCCESS; +} + +void pmmOffloadProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + switch (pMsg->type) + { + case eWNI_PMC_ENTER_BMPS_REQ: + { + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + if(eSIR_SUCCESS != + pmmOffloadEnterBmpsReqHandler(pMac, pMbMsg->data)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process eWNI_PMC_ENTER_BMPS_REQ"); + } + } + break; + + case WDA_ENTER_BMPS_RSP: + if(eSIR_SUCCESS != + pmmOffloadEnterBmpsRespHandler(pMac, pMsg->bodyptr)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process WDA_ENTER_BMPS_RSP"); + } + break; + + case eWNI_PMC_EXIT_BMPS_REQ: + { + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + if(eSIR_SUCCESS != + pmmOffloadExitBmpsReqHandler(pMac, pMbMsg->data)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process eWNI_PMC_EXIT_BMPS_REQ"); + } + } + break; + + case WDA_EXIT_BMPS_RSP: + if(eSIR_SUCCESS != + pmmOffloadExitBmpsRespHandler(pMac, pMsg->bodyptr)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process WDA_EXIT_BMPS_RSP"); + } + break; + + case eWNI_PMC_ENTER_UAPSD_REQ: + { + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + if(eSIR_SUCCESS != + pmmOffloadEnterUapsdReqHandler(pMac, pMbMsg->data)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process eWNI_PMC_ENTER_UAPSD_REQ"); + } + } + break; + + case WDA_ENTER_UAPSD_RSP: + if(eSIR_SUCCESS != + pmmOffloadEnterUapsdRespHandler(pMac, pMsg->bodyptr)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process WDA_ENTER_UAPSD_RSP"); + } + break; + + case eWNI_PMC_EXIT_UAPSD_REQ: + { + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + if(eSIR_SUCCESS != + pmmOffloadExitUapsdReqHandler(pMac, pMbMsg->data)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process eWNI_PMC_EXIT_UAPSD_REQ"); + } + } + break; + + case WDA_EXIT_UAPSD_RSP: + if(eSIR_SUCCESS != + pmmOffloadExitUapsdRespHandler(pMac, pMsg->bodyptr)) + { + pmmLog(pMac, LOGE, + "PMM: Failed to Process WDA_EXIT_UAPSD_RSP"); + } + break; + + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + pmmSendWowlAddBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + pmmSendWowlDelBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_ENTER_WOWL_REQ: + pmmEnterWowlRequestHandler(pMac, pMsg); + break; + + case WDA_WOWL_ENTER_RSP: + pmmLog(pMac, LOGE, + "PMM: WDA_WOWL_ENTER_RSP not supported yet"); + break; + + case eWNI_PMC_EXIT_WOWL_REQ: + pmmExitWowlanRequestHandler(pMac, pMsg); + break; + + case WDA_WOWL_EXIT_RSP: + pmmLog(pMac, LOGE, + "PMM: WDA_WOWL_EXIT_RSP not supported yet"); + break; + + default: + PELOGW(pmmLog(pMac, LOGW, + FL("PMM: Unknown message in pmmMsgQ type %d, potential memory leak!!"), + pMsg->type);) + } + + if (NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + pMsg->bodyptr = NULL; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.c new file mode 100644 index 0000000000000..2f0be76ce1078 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file pmmDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + ========================================================================*/ + +#include "vos_trace.h" +#include "pmmDebug.h" +#define LOG_SIZE 256 + +void pmmLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) + { + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level */ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + + VOS_TRACE(VOS_MODULE_ID_PMC, vosDebugLevel, "%s", logBuffer); + va_end( marker ); + } diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.h new file mode 100644 index 0000000000000..6a748c4d32949 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/pmm/pmmDebug.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_DEBUG_H__ +#define __PMM_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#define UL_HI( field ) ( *( ( (ULONG *)(&(field)) ) + 1 ) ) +#define UL_LO( field ) ( *( ( (ULONG *)(&(field)) ) + 0 ) ) + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) pmmLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...) ; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c new file mode 100644 index 0000000000000..6f96e37420e1c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c @@ -0,0 +1,1342 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file rrmApi.c + + \brief implementation for PE RRM APIs + +========================================================================*/ + +/* $Header$ */ + +#if defined WLAN_FEATURE_VOWIFI + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfgSta.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSendSmeRspMessages.h" +#include "parserApi.h" +#include "limSendMessages.h" +#include "rrmGlobal.h" +#include "rrmApi.h" + +tANI_U8 +rrmGetMinOfMaxTxPower(tpAniSirGlobal pMac, + tPowerdBm regMax, tPowerdBm apTxPower) +{ + tANI_U8 maxTxPower = 0; + tANI_U8 txPower = VOS_MIN( regMax, (apTxPower) ); + if((txPower >= RRM_MIN_TX_PWR_CAP) && (txPower <= RRM_MAX_TX_PWR_CAP)) + maxTxPower = txPower; + else if (txPower < RRM_MIN_TX_PWR_CAP) + maxTxPower = RRM_MIN_TX_PWR_CAP; + else + maxTxPower = RRM_MAX_TX_PWR_CAP; + + limLog( pMac, LOG3, + "%s: regulatoryMax = %d, apTxPwr = %d, maxTxpwr = %d", + __func__, regMax, apTxPower, maxTxPower ); + return maxTxPower; +} + +// -------------------------------------------------------------------- +/** + * rrmCacheMgmtTxPower + ** + * FUNCTION: Store Tx power for management frames. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry session entry. + * @return None + */ +void +rrmCacheMgmtTxPower ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + limLog( pMac, LOG3, "Cache Mgmt Tx Power = %d", txPower ); + + if( pSessionEntry == NULL ) + { + limLog( pMac, LOG3, "%s: pSessionEntry is NULL", __func__); + pMac->rrm.rrmPEContext.txMgmtPower = txPower; + } + else + pSessionEntry->txMgmtPower = txPower; +} + +// -------------------------------------------------------------------- +/** + * rrmGetMgmtTxPower + * + * FUNCTION: Get the Tx power for management frames. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry session entry. + * @return txPower + */ +tPowerdBm +rrmGetMgmtTxPower ( tpAniSirGlobal pMac, tpPESession pSessionEntry ) +{ + limLog( pMac, LOG3, "RrmGetMgmtTxPower called" ); + + if( pSessionEntry == NULL ) + { + limLog( pMac, LOG3, "%s: txpower from rrmPEContext: %d", + __func__, pMac->rrm.rrmPEContext.txMgmtPower); + return pMac->rrm.rrmPEContext.txMgmtPower; + } + + return pSessionEntry->txMgmtPower; +} + +// -------------------------------------------------------------------- +/** + * rrmSendSetMaxTxPowerReq + * + * FUNCTION: Send WDA_SET_MAX_TX_POWER_REQ message to change the max tx power. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + tpMaxTxPowerParams pMaxTxParams; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if( pSessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL(" Inavalid parameters"));) + return eSIR_FAILURE; + } + pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if ( NULL == pMaxTxParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for pMaxTxParams ") ); + return eSIR_MEM_ALLOC_FAILED; + + } + /* Allocated memory for pMaxTxParams...will be freed in other module */ + pMaxTxParams->power = txPower; + vos_mem_copy(pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + vos_mem_copy(pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + + msgQ.type = WDA_SET_MAX_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMaxTxParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG3, + FL( "Sending WDA_SET_MAX_TX_POWER_REQ with power(%d) to HAL"), + txPower); + + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGP, FL("Posting WDA_SET_MAX_TX_POWER_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pMaxTxParams); + return retCode; + } + return retCode; +} + + +// -------------------------------------------------------------------- +/** + * rrmSetMaxTxPowerRsp + * + * FUNCTION: Process WDA_SET_MAX_TX_POWER_RSP message. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmSetMaxTxPowerRsp ( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tpMaxTxPowerParams pMaxTxParams = (tpMaxTxPowerParams) limMsgQ->bodyptr; + tpPESession pSessionEntry; + tANI_U8 sessionId, i; + tSirMacAddr bssid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if( vos_mem_compare(bssid, pMaxTxParams->bssId, sizeof(tSirMacAddr))) + { + for (i =0;i < pMac->lim.maxBssId;i++) + { + if ( (pMac->lim.gpSession[i].valid == TRUE )) + { + pSessionEntry = &pMac->lim.gpSession[i]; + rrmCacheMgmtTxPower ( pMac, pMaxTxParams->power, pSessionEntry ); + } + } + } + else + { + if((pSessionEntry = peFindSessionByBssid(pMac, pMaxTxParams->bssId, &sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to find session:") );) + retCode = eSIR_FAILURE; + } + else + { + rrmCacheMgmtTxPower ( pMac, pMaxTxParams->power, pSessionEntry ); + } + } + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return retCode; +} +// -------------------------------------------------------------------- +/** + * rrmProcessLinkMeasurementRequest + * + * FUNCTION: Processes the Link measurement request and send the report. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBd pointer to BD to extract RSSI and SNR + * @param pLinkReq pointer to the Link request frame structure. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessLinkMeasurementRequest( tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo, + tDot11fLinkMeasurementRequest *pLinkReq, + tpPESession pSessionEntry ) +{ + tSirMacLinkReport LinkReport; + tpSirMacMgmtHdr pHdr; + v_S7_t currentRSSI = 0; + + limLog( pMac, LOG3, "Received Link measurement request"); + + if( pRxPacketInfo == NULL || pLinkReq == NULL || pSessionEntry == NULL ) + { + PELOGE(limLog( pMac, LOGE, + "%s Invalid parameters - Ignoring the request", __func__);) + return eSIR_FAILURE; + } + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + + LinkReport.txPower = limGetMaxTxPower (pLinkReq->MaxTxPower.maxTxPower, + pLinkReq->MaxTxPower.maxTxPower, + pMac->roam.configParam.nTxPowerCap); + + if ((LinkReport.txPower != (uint8)(pSessionEntry->maxTxPower)) && + (eSIR_SUCCESS == rrmSendSetMaxTxPowerReq (pMac, + (tPowerdBm)(LinkReport.txPower), + pSessionEntry))) + { + PELOGW (limLog (pMac, + LOGW, + FL(" maxTx power in link report is not same as local..." + " Local = %d Link Request TxPower = %d" + " Link Report TxPower = %d"), + pSessionEntry->maxTxPower, + LinkReport.txPower, + pLinkReq->MaxTxPower.maxTxPower);) + pSessionEntry->maxTxPower = (tPowerdBm)(LinkReport.txPower); + } + + LinkReport.dialogToken = pLinkReq->DialogToken.token; + LinkReport.rxAntenna = 0; + LinkReport.txAntenna = 0; + currentRSSI = WDA_GET_RX_RSSI_RAW(pRxPacketInfo); + + limLog( pMac, LOG1, + "Received Link report frame with %d", currentRSSI); + + // 2008 11k spec reference: 18.4.8.5 RCPI Measurement + if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE) + LinkReport.rcpi = 0; + else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0)) + LinkReport.rcpi = CALCULATE_RCPI(currentRSSI); + else + LinkReport.rcpi = RCPI_MAX_VALUE; + + LinkReport.rsni = WDA_GET_RX_SNR(pRxPacketInfo); + + limLog( pMac, LOG3, "Sending Link report frame"); + + return limSendLinkReportActionFrame( pMac, &LinkReport, pHdr->sa, pSessionEntry ); +} + +// -------------------------------------------------------------------- +/** + * rrmProcessNeighborReportResponse + * + * FUNCTION: Processes the Neighbor Report response from the peer AP. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pNeighborRep pointer to the Neighbor report frame structure. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessNeighborReportResponse( tpAniSirGlobal pMac, + tDot11fNeighborReportResponse *pNeighborRep, + tpPESession pSessionEntry ) +{ + tSirRetStatus status = eSIR_FAILURE; + tpSirNeighborReportInd pSmeNeighborRpt = NULL; + tANI_U16 length; + tANI_U8 i; + tSirMsgQ mmhMsg; + + if( pNeighborRep == NULL || pSessionEntry == NULL ) + { + PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters") );) + return status; + } + + limLog( pMac, LOG3, FL("Neighbor report response received ") ); + + // Dialog token + if( pMac->rrm.rrmPEContext.DialogToken != pNeighborRep->DialogToken.token ) + { + PELOGE(limLog( pMac, LOGE, + "Dialog token mismatch in the received Neighbor report");) + return eSIR_FAILURE; + } + if( pNeighborRep->num_NeighborReport == 0 ) + { + PELOGE(limLog( pMac, LOGE, "No neighbor report in the frame...Dropping it");) + return eSIR_FAILURE; + } + length = (sizeof( tSirNeighborReportInd )) + + (sizeof( tSirNeighborBssDescription ) * (pNeighborRep->num_NeighborReport - 1) ) ; + + //Prepare the request to send to SME. + pSmeNeighborRpt = vos_mem_malloc(length); + if( NULL == pSmeNeighborRpt ) + { + PELOGE(limLog( pMac, LOGP, FL("Unable to allocate memory") );) + return eSIR_MEM_ALLOC_FAILED; + + } + vos_mem_set(pSmeNeighborRpt, length, 0); + + /* Allocated memory for pSmeNeighborRpt...will be freed by other module */ + + for( i = 0 ; i < pNeighborRep->num_NeighborReport ; i++ ) + { + pSmeNeighborRpt->sNeighborBssDescription[i].length = sizeof( tSirNeighborBssDescription ); /*+ any optional ies */ + vos_mem_copy(pSmeNeighborRpt->sNeighborBssDescription[i].bssId, + pNeighborRep->NeighborReport[i].bssid, + sizeof(tSirMacAddr)); + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fApPreauthReachable = pNeighborRep->NeighborReport[i].APReachability; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameSecurityMode = pNeighborRep->NeighborReport[i].Security; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameAuthenticator = pNeighborRep->NeighborReport[i].KeyScope; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapSpectrumMeasurement = pNeighborRep->NeighborReport[i].SpecMgmtCap; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapQos = pNeighborRep->NeighborReport[i].QosCap; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapApsd = pNeighborRep->NeighborReport[i].apsd; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapRadioMeasurement = pNeighborRep->NeighborReport[i].rrm; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapDelayedBlockAck = pNeighborRep->NeighborReport[i].DelayedBA; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapImmediateBlockAck = pNeighborRep->NeighborReport[i].ImmBA; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fMobilityDomain = pNeighborRep->NeighborReport[i].MobilityDomain; + + pSmeNeighborRpt->sNeighborBssDescription[i].regClass = pNeighborRep->NeighborReport[i].regulatoryClass; + pSmeNeighborRpt->sNeighborBssDescription[i].channel = pNeighborRep->NeighborReport[i].channel; + pSmeNeighborRpt->sNeighborBssDescription[i].phyType = pNeighborRep->NeighborReport[i].PhyType; + } + + pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND; + pSmeNeighborRpt->length = length; + pSmeNeighborRpt->sessionId = pSessionEntry->smeSessionId; + pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport; + vos_mem_copy(pSmeNeighborRpt->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + + //Send request to SME. + mmhMsg.type = pSmeNeighborRpt->messageType; + mmhMsg.bodyptr = pSmeNeighborRpt; + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, mmhMsg.type)); + status = limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return status; + +} + +// -------------------------------------------------------------------- +/** + * rrmProcessNeighborReportReq + * + * FUNCTION: + * + * LOGIC: Create a Neighbor report request and send it to peer. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pNeighborReq Neighbor report request params . + * @return None + */ +tSirRetStatus +rrmProcessNeighborReportReq( tpAniSirGlobal pMac, + tpSirNeighborReportReqInd pNeighborReq ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tSirMacNeighborReportReq NeighborReportReq; + tpPESession pSessionEntry ; + tANI_U8 sessionId; + + if( pNeighborReq == NULL ) + { + PELOGE(limLog( pMac, LOGE, "NeighborReq is NULL" );) + return eSIR_FAILURE; + } + if ((pSessionEntry = peFindSessionByBssid(pMac,pNeighborReq->bssId,&sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + return eSIR_FAILURE; + } + + limLog( pMac, LOG1, FL("SSID present = %d "), pNeighborReq->noSSID ); + + vos_mem_set(&NeighborReportReq,sizeof( tSirMacNeighborReportReq ), 0); + + NeighborReportReq.dialogToken = ++pMac->rrm.rrmPEContext.DialogToken; + NeighborReportReq.ssid_present = !pNeighborReq->noSSID; + if( NeighborReportReq.ssid_present ) + { + vos_mem_copy(&NeighborReportReq.ssid, &pNeighborReq->ucSSID, sizeof(tSirMacSSid)); + PELOGE(sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGE, (tANI_U8*) NeighborReportReq.ssid.ssId, NeighborReportReq.ssid.length );) + } + + status = limSendNeighborReportRequestFrame( pMac, &NeighborReportReq, pNeighborReq->bssId, pSessionEntry ); + + return status; +} + +#define ABS(x) ((x < 0) ? -x : x) +// -------------------------------------------------------------------- +/** + * rrmProcessBeaconReportReq + * + * FUNCTION: Processes the Beacon report request from the peer AP. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pCurrentReq pointer to the current Req comtext. + * @param pBeaconReq pointer to the beacon report request IE from the peer. + * @param pSessionEntry session entry. + * @return None + */ +static tRrmRetStatus +rrmProcessBeaconReportReq( tpAniSirGlobal pMac, + tpRRMReq pCurrentReq, + tDot11fIEMeasurementRequest *pBeaconReq, + tpPESession pSessionEntry ) +{ + tSirMsgQ mmhMsg; + tpSirBeaconReportReqInd pSmeBcnReportReq; + tANI_U8 num_channels = 0, num_APChanReport; + tANI_U16 measDuration, maxMeasduration; + tANI_S8 maxDuration; + tANI_U8 sign; + + if( pBeaconReq->measurement_request.Beacon.BeaconReporting.present && + (pBeaconReq->measurement_request.Beacon.BeaconReporting.reportingCondition != 0) ) + { + //Repeated measurement is not supported. This means number of repetitions should be zero.(Already checked) + //All test case in VoWifi(as of version 0.36) use zero for number of repetitions. + //Beacon reporting should not be included in request if number of repetitons is zero. + // IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1 + + PELOGE(limLog( pMac, LOGE, "Dropping the request: Reporting condition included in beacon report request and it is not zero");) + return eRRM_INCAPABLE; + } + + /* The logic here is to check the measurement duration passed in the beacon request. Following are the cases handled. + Case 1: If measurement duration received in the beacon request is greater than the max measurement duration advertised + in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 1, REFUSE the beacon request + Case 2: If measurement duration received in the beacon request is greater than the max measurement duration advertised + in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 0, perform measurement for + the duration advertised in the RRM capabilities + + maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval + */ + maxDuration = pMac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4; + sign = (maxDuration < 0) ? 1 : 0; + maxDuration = (1L << ABS(maxDuration)); + if (!sign) + maxMeasduration = maxDuration * pSessionEntry->beaconParams.beaconInterval; + else + maxMeasduration = pSessionEntry->beaconParams.beaconInterval / maxDuration; + + measDuration = pBeaconReq->measurement_request.Beacon.meas_duration; + + limLog( pMac, LOG3, + "maxDuration = %d sign = %d maxMeasduration = %d measDuration = %d", + maxDuration, sign, maxMeasduration, measDuration ); + + if( maxMeasduration < measDuration ) + { + if( pBeaconReq->durationMandatory ) + { + PELOGE(limLog( pMac, LOGE, "Dropping the request: duration mandatory and maxduration > measduration");) + return eRRM_REFUSED; + } + else + measDuration = maxMeasduration; + } + + //Cache the data required for sending report. + pCurrentReq->request.Beacon.reportingDetail = pBeaconReq->measurement_request.Beacon.BcnReportingDetail.present ? + pBeaconReq->measurement_request.Beacon.BcnReportingDetail.reportingDetail : + BEACON_REPORTING_DETAIL_ALL_FF_IE ; + + if( pBeaconReq->measurement_request.Beacon.RequestedInfo.present ) + { + pCurrentReq->request.Beacon.reqIes.pElementIds = vos_mem_malloc(sizeof(tANI_U8) * + pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids); + if ( NULL == pCurrentReq->request.Beacon.reqIes.pElementIds ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory for request IEs buffer" )); + return eRRM_FAILURE; + } + limLog( pMac, LOG3, FL(" Allocated memory for pElementIds") ); + + pCurrentReq->request.Beacon.reqIes.num = pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids; + vos_mem_copy(pCurrentReq->request.Beacon.reqIes.pElementIds, + pBeaconReq->measurement_request.Beacon.RequestedInfo.requested_eids, + pCurrentReq->request.Beacon.reqIes.num); + } + + if( pBeaconReq->measurement_request.Beacon.num_APChannelReport ) + { + for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ ) + num_channels += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList; + } + + //Prepare the request to send to SME. + pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd )); + if ( NULL == pSmeBcnReportReq ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Beacon Report Req Ind to SME" )); + + return eRRM_FAILURE; + + } + + vos_mem_set(pSmeBcnReportReq,sizeof( tSirBeaconReportReqInd ),0); + + /* Allocated memory for pSmeBcnReportReq....will be freed by other modulea*/ + vos_mem_copy(pSmeBcnReportReq->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ); + pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token; + pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_11K; + pSmeBcnReportReq->randomizationInterval = SYS_TU_TO_MS (pBeaconReq->measurement_request.Beacon.randomization); + pSmeBcnReportReq->channelInfo.regulatoryClass = pBeaconReq->measurement_request.Beacon.regClass; + pSmeBcnReportReq->channelInfo.channelNum = pBeaconReq->measurement_request.Beacon.channel; + pSmeBcnReportReq->measurementDuration[0] = SYS_TU_TO_MS(measDuration); + pSmeBcnReportReq->fMeasurementtype[0] = pBeaconReq->measurement_request.Beacon.meas_mode; + vos_mem_copy(pSmeBcnReportReq->macaddrBssid, pBeaconReq->measurement_request.Beacon.BSSID, + sizeof(tSirMacAddr)); + + if( pBeaconReq->measurement_request.Beacon.SSID.present ) + { + pSmeBcnReportReq->ssId.length = pBeaconReq->measurement_request.Beacon.SSID.num_ssid; + vos_mem_copy(pSmeBcnReportReq->ssId.ssId, + pBeaconReq->measurement_request.Beacon.SSID.ssid, + pSmeBcnReportReq->ssId.length); + } + + pCurrentReq->token = pBeaconReq->measurement_token; + + pSmeBcnReportReq->channelList.numChannels = num_channels; + if( pBeaconReq->measurement_request.Beacon.num_APChannelReport ) + { + tANI_U8 *pChanList = pSmeBcnReportReq->channelList.channelNumber; + for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ ) + { + vos_mem_copy(pChanList, + pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].channelList, + pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList); + + pChanList += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList; + } + } + + //Send request to SME. + mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND; + mmhMsg.bodyptr = pSmeBcnReportReq; + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, mmhMsg.type)); + return limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +// -------------------------------------------------------------------- +/** + * rrmFillBeaconIes + * + * FUNCTION: + * + * LOGIC: Fills Fixed fields and Ies in bss description to an array of tANI_U8. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pIes - pointer to the buffer that should be populated with ies. + * @param pNumIes - returns the num of ies filled in this param. + * @param pIesMaxSize - Max size of the buffer pIes. + * @param eids - pointer to array of eids. If NULL, all ies will be populated. + * @param numEids - number of elements in array eids. + * @param pBssDesc - pointer to Bss Description. + * @return None + */ +static void +rrmFillBeaconIes( tpAniSirGlobal pMac, + tANI_U8 *pIes, tANI_U8 *pNumIes, tANI_U8 pIesMaxSize, + tANI_U8 *eids, tANI_U8 numEids, + tpSirBssDescription pBssDesc ) +{ + tANI_U8 len, *pBcnIes, count = 0, i; + tANI_U8 BcnNumIes; + + if( (pIes == NULL) || (pNumIes == NULL) || (pBssDesc == NULL) ) + { + PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters") );) + return; + } + + //Make sure that if eid is null, numEids is set to zero. + numEids = (eids == NULL) ? 0 : numEids; + + pBcnIes = (tANI_U8*) &pBssDesc->ieFields[0]; + BcnNumIes = (tANI_U8)GET_IE_LEN_IN_BSS( pBssDesc->length ); + + *pNumIes = 0; + + *((tANI_U32*)pIes) = pBssDesc->timeStamp[0]; + *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32); + *((tANI_U32*)pIes) = pBssDesc->timeStamp[1]; + *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32); + *((tANI_U16*)pIes) = pBssDesc->beaconInterval; + *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16); + *((tANI_U16*)pIes) = pBssDesc->capabilityInfo; + *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16); + + while ( BcnNumIes > 0 ) + { + len = *(pBcnIes + 1) + 2; //element id + length. + limLog( pMac, LOG3, "EID = %d, len = %d total = %d", + *pBcnIes, *(pBcnIes+1), len ); + + i = 0; + do + { + if( ( (eids == NULL) || ( *pBcnIes == eids[i] ) ) && + ( (*pNumIes) + len) < pIesMaxSize ) + { + limLog( pMac, LOG3, "Adding Eid %d, len=%d", *pBcnIes, len ); + + vos_mem_copy(pIes, pBcnIes, len); + pIes += len; + *pNumIes += len; + count++; + break; + } + i++; + }while( i < numEids ); + + pBcnIes += len; + BcnNumIes -= len; + } + limLog( pMac, LOG1, "Total length of Ies added = %d", *pNumIes ); +} + +// -------------------------------------------------------------------- +/** + * rrmProcessBeaconReportXmit + * + * FUNCTION: + * + * LOGIC: Create a Radio measurement report action frame and send it to peer. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBcnReport Data for beacon report IE from SME. + * @return None + */ +tSirRetStatus +rrmProcessBeaconReportXmit( tpAniSirGlobal pMac, + tpSirBeaconReportXmitInd pBcnReport) +{ + tSirRetStatus status = eSIR_SUCCESS; + tSirMacRadioMeasureReport *pReport = NULL; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + tpPESession pSessionEntry ; + tANI_U8 sessionId; + v_U8_t flagBSSPresent = FALSE, bssDescCnt = 0; + + limLog( pMac, LOG1, "Received beacon report xmit indication"); + + if (NULL == pBcnReport) + { + PELOGE(limLog( pMac, LOGE, + "Received pBcnReport is NULL in PE");) + return eSIR_FAILURE; + } + + if (NULL == pCurrentReq) + { + PELOGE(limLog( pMac, LOGE, + "Received report xmit while there is no request pending in PE");) + return eSIR_FAILURE; + } + + if( (pBcnReport->numBssDesc) || + (!pBcnReport->numBssDesc && pCurrentReq->sendEmptyBcnRpt) ) + { + pBcnReport->numBssDesc = (pBcnReport->numBssDesc == RRM_BCN_RPT_NO_BSS_INFO)? + RRM_BCN_RPT_MIN_RPT : pBcnReport->numBssDesc; + + if (NULL == (pSessionEntry = peFindSessionByBssid(pMac, + pBcnReport->bssId, + &sessionId))) + { + PELOGE(limLog(pMac, LOGE, FL("session does not exist for given bssId"));) + return eSIR_FAILURE; + } + + pReport = vos_mem_malloc(pBcnReport->numBssDesc * + sizeof(tSirMacRadioMeasureReport)); + + if (NULL == pReport) + { + PELOGE(limLog(pMac, LOGE, FL("RRM Report is NULL, allocation failed"));) + return eSIR_FAILURE; + } + + vos_mem_zero( pReport, + pBcnReport->numBssDesc * sizeof(tSirMacRadioMeasureReport) ); + + for (bssDescCnt = 0; bssDescCnt < pBcnReport->numBssDesc; bssDescCnt++) + { + //Prepare the beacon report and send it to the peer. + pReport[bssDescCnt].token = pBcnReport->uDialogToken; + pReport[bssDescCnt].refused = 0; + pReport[bssDescCnt].incapable = 0; + pReport[bssDescCnt].type = SIR_MAC_RRM_BEACON_TYPE; + + //If the scan result is NULL then send report request with + //option subelement as NULL.. + if ( NULL != pBcnReport->pBssDescription[bssDescCnt] ) + { + flagBSSPresent = TRUE; + } + + //Valid response is included if the size of beacon xmit + //is == size of beacon xmit ind + ies + if ( pBcnReport->length >= sizeof( tSirBeaconReportXmitInd ) ) + { + pReport[bssDescCnt].report.beaconReport.regClass = pBcnReport->regClass; + if ( flagBSSPresent ) + { + pReport[bssDescCnt].report.beaconReport.channel = + pBcnReport->pBssDescription[bssDescCnt]->channelId; + vos_mem_copy( pReport[bssDescCnt].report.beaconReport.measStartTime, + pBcnReport->pBssDescription[bssDescCnt]->startTSF, + sizeof( pBcnReport->pBssDescription[bssDescCnt]->startTSF) ); + pReport[bssDescCnt].report.beaconReport.measDuration = + SYS_MS_TO_TU(pBcnReport->duration); + pReport[bssDescCnt].report.beaconReport.phyType = + pBcnReport->pBssDescription[bssDescCnt]->nwType; + pReport[bssDescCnt].report.beaconReport.bcnProbeRsp = 1; + pReport[bssDescCnt].report.beaconReport.rsni = + pBcnReport->pBssDescription[bssDescCnt]->sinr; + pReport[bssDescCnt].report.beaconReport.rcpi = + pBcnReport->pBssDescription[bssDescCnt]->rssi; + + pReport[bssDescCnt].report.beaconReport.antennaId = 0; + pReport[bssDescCnt].report.beaconReport.parentTSF = + pBcnReport->pBssDescription[bssDescCnt]->parentTSF; + vos_mem_copy( pReport[bssDescCnt].report.beaconReport.bssid, + pBcnReport->pBssDescription[bssDescCnt]->bssId, + sizeof(tSirMacAddr)); + } + + switch ( pCurrentReq->request.Beacon.reportingDetail ) + { + case BEACON_REPORTING_DETAIL_NO_FF_IE: + //0 No need to include any elements. + limLog(pMac, LOG3, "No reporting detail requested"); + break; + case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE: + //1: Include all FFs and Requested Ies. + limLog(pMac, LOG3, + "Only requested IEs in reporting detail requested"); + + if ( flagBSSPresent ) + { + rrmFillBeaconIes( pMac, + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0], + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes, + BEACON_REPORT_MAX_IES, + pCurrentReq->request.Beacon.reqIes.pElementIds, + pCurrentReq->request.Beacon.reqIes.num, + pBcnReport->pBssDescription[bssDescCnt] ); + } + + break; + case BEACON_REPORTING_DETAIL_ALL_FF_IE: + //2 / default - Include all FFs and all Ies. + default: + limLog(pMac, LOG3, "Default all IEs and FFs"); + if ( flagBSSPresent ) + { + rrmFillBeaconIes( pMac, + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0], + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes, + BEACON_REPORT_MAX_IES, + NULL, 0, + pBcnReport->pBssDescription[bssDescCnt] ); + } + break; + } + } + } + + limLog( pMac, LOG1, "Sending Action frame with %d bss info", bssDescCnt); + limSendRadioMeasureReportActionFrame( pMac, + pCurrentReq->dialog_token, + bssDescCnt, + pReport, + pBcnReport->bssId, + pSessionEntry ); + + pCurrentReq->sendEmptyBcnRpt = false; + } + + if( pBcnReport->fMeasureDone ) + { + limLog( pMac, LOG3, "Measurement done....cleanup the context"); + + rrmCleanup(pMac); + } + + if( NULL != pReport ) + vos_mem_free(pReport); + + return status; +} + +void rrmProcessBeaconRequestFailure(tpAniSirGlobal pMac, tpPESession pSessionEntry, + tSirMacAddr peer, tRrmRetStatus status) +{ + tpSirMacRadioMeasureReport pReport = NULL; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0); + pReport->token = pCurrentReq->token; + pReport->type = SIR_MAC_RRM_BEACON_TYPE; + + switch (status) + { + case eRRM_REFUSED: + pReport->refused = 1; + break; + case eRRM_INCAPABLE: + pReport->incapable = 1; + break; + default: + PELOGE(limLog( pMac, LOGE, + FL(" Beacon request processing failed no report sent with status %d "), + status);); + vos_mem_free(pReport); + return; + } + + limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, 1, + pReport, peer, pSessionEntry ); + + vos_mem_free(pReport); + limLog( pMac, LOG3, FL(" Free memory for pReport") ); + return; +} + +// -------------------------------------------------------------------- +/** + * rrmProcessRadioMeasurementRequest + * + * FUNCTION: Processes the Radio Resource Measurement request. + * + * LOGIC: + + +* + * ASSUMPTIONS: + * + * NOTE: + * + * @param peer Macaddress of the peer requesting the radio measurement. + * @param pRRMReq Array of Measurement request IEs + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessRadioMeasurementRequest( tpAniSirGlobal pMac, + tSirMacAddr peer, + tDot11fRadioMeasurementRequest *pRRMReq, + tpPESession pSessionEntry ) +{ + tANI_U8 i; + tSirRetStatus status = eSIR_SUCCESS; + tpSirMacRadioMeasureReport pReport = NULL; + tANI_U8 num_report = 0; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + tRrmRetStatus rrmStatus = eRRM_SUCCESS; + + if( !pRRMReq->num_MeasurementRequest ) + { + //No measurement requests.... + // + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport),0); + PELOGE(limLog( pMac, LOGE, + FL("No requestIes in the measurement request, sending incapable report"));) + pReport->incapable = 1; + num_report = 1; + limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report, + pReport, peer, pSessionEntry ); + vos_mem_free(pReport); + return eSIR_FAILURE; + } + + // PF Fix + if( pRRMReq->NumOfRepetitions.repetitions > 0 ) + { + limLog( pMac, LOG1, + FL(" number of repetitions %d"), + pRRMReq->NumOfRepetitions.repetitions ); + + //Send a report with incapable bit set. Not supporting repetitions. + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0); + PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pReport") );) + pReport->incapable = 1; + pReport->type = pRRMReq->MeasurementRequest[0].measurement_type; + num_report = 1; + goto end; + + } + + for( i= 0; i < pRRMReq->num_MeasurementRequest; i++ ) + { + switch( pRRMReq->MeasurementRequest[i].measurement_type ) + { + case SIR_MAC_RRM_BEACON_TYPE: + //Process beacon request. + if( pCurrentReq ) + { + if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests. + { + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i)); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, + sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i), + 0); + limLog( pMac, LOG3, + FL(" rrm beacon type refused of %d report in beacon table"), + num_report ); + + } + pReport[num_report].refused = 1; + pReport[num_report].type = SIR_MAC_RRM_BEACON_TYPE; + pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token; + num_report++; + continue; + } + else + { + pCurrentReq = vos_mem_malloc(sizeof( *pCurrentReq )); + if ( NULL == pCurrentReq ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + vos_mem_free(pReport); + return eSIR_MEM_ALLOC_FAILED; + } + limLog( pMac, LOG3, FL(" Processing Beacon Report request") ); + vos_mem_set(pCurrentReq, sizeof( *pCurrentReq ), 0); + pCurrentReq->dialog_token = pRRMReq->DialogToken.token; + pCurrentReq->token = pRRMReq->MeasurementRequest[i].measurement_token; + pCurrentReq->sendEmptyBcnRpt = true; + pMac->rrm.rrmPEContext.pCurrentReq = pCurrentReq; + rrmStatus = rrmProcessBeaconReportReq( pMac, pCurrentReq, &pRRMReq->MeasurementRequest[i], pSessionEntry ); + if (eRRM_SUCCESS != rrmStatus) + { + rrmProcessBeaconRequestFailure(pMac, pSessionEntry, peer, rrmStatus); + rrmCleanup(pMac); + } + } + break; + default: + //Send a report with incapabale bit set. + if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests. + { + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i)); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, + sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i), + 0); + limLog( pMac, LOG3, + FL(" rrm beacon type incapble of %d report "), + num_report ); + } + pReport[num_report].incapable = 1; + pReport[num_report].type = pRRMReq->MeasurementRequest[i].measurement_type; + pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token; + num_report++; + break; + } + } + +end: + if( pReport ) + { + limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report, + pReport, peer, pSessionEntry ); + + vos_mem_free(pReport); + limLog( pMac, LOG3, FL(" Free memory for pReport") ); + } + return status; + +} + +// -------------------------------------------------------------------- +/** + * rrmUpdateStartTSF + ** + * FUNCTION: Store start TSF of measurement. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param startTSF - TSF value at the start of measurement. + * @return None + */ +void +rrmUpdateStartTSF ( tpAniSirGlobal pMac, tANI_U32 startTSF[2] ) +{ + pMac->rrm.rrmPEContext.startTSF[0] = startTSF[0]; + pMac->rrm.rrmPEContext.startTSF[1] = startTSF[1]; +} + +// -------------------------------------------------------------------- +/** + * rrmGetStartTSF + * + * FUNCTION: Get the Start TSF. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param startTSF - store star TSF in this buffer. + * @return txPower + */ +void +rrmGetStartTSF ( tpAniSirGlobal pMac, tANI_U32 *pStartTSF ) +{ + pStartTSF[0] = pMac->rrm.rrmPEContext.startTSF[0]; + pStartTSF[1] = pMac->rrm.rrmPEContext.startTSF[1]; + +} +// -------------------------------------------------------------------- +/** + * rrmGetCapabilities + * + * FUNCTION: + * Returns a pointer to tpRRMCaps with all the caps enabled in RRM + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry + * @return pointer to tRRMCaps + */ +tpRRMCaps rrmGetCapabilities ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ) +{ + return &pMac->rrm.rrmPEContext.rrmEnabledCaps; +} + +// -------------------------------------------------------------------- +/** + * rrmUpdateConfig + * + * FUNCTION: + * Update the configuration. This is called from limUpdateConfig. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry + * @return pointer to tRRMCaps + */ +void rrmUpdateConfig ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ) +{ + tANI_U32 val; + tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm enabled failed")); + return; + } + pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm operating channel max measurement duration failed")); + return; + } + pRRMCaps->operatingChanMax = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm non-operating channel max measurement duration failed")); + return; + } + pRRMCaps->nonOperatingChanMax =(tANI_U8) val; + + limLog( pMac, LOG1, + "RRM enabled = %d OperatingChanMax = %d NonOperatingMax = %d", + pMac->rrm.rrmPEContext.rrmEnable, + pRRMCaps->operatingChanMax, pRRMCaps->nonOperatingChanMax ); +} +// -------------------------------------------------------------------- +/** + * rrmInitialize + * + * FUNCTION: + * Initialize RRM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @return None + */ + +tSirRetStatus +rrmInitialize(tpAniSirGlobal pMac) +{ + tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps; + + pMac->rrm.rrmPEContext.pCurrentReq = NULL; + pMac->rrm.rrmPEContext.txMgmtPower = 0; + pMac->rrm.rrmPEContext.DialogToken = 0; + + pMac->rrm.rrmPEContext.rrmEnable = 0; + + vos_mem_set(pRRMCaps, sizeof(tRRMCaps), 0); + pRRMCaps->LinkMeasurement = 1; + pRRMCaps->NeighborRpt = 1; + pRRMCaps->BeaconPassive = 1; + pRRMCaps->BeaconActive = 1; + pRRMCaps->BeaconTable = 1; + pRRMCaps->APChanReport = 1; + + pRRMCaps->operatingChanMax = 3; + pRRMCaps->nonOperatingChanMax = 3; + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * rrmCleanup + * + * FUNCTION: + * cleanup RRM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode + * @param rate + * @return None + */ + +tSirRetStatus +rrmCleanup(tpAniSirGlobal pMac) +{ + if( pMac->rrm.rrmPEContext.pCurrentReq ) + { + if( pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds ) + { + vos_mem_free(pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds); + limLog( pMac, LOG4, FL(" Free memory for pElementIds") ); + } + + vos_mem_free(pMac->rrm.rrmPEContext.pCurrentReq); + limLog( pMac, LOG4, FL(" Free memory for pCurrentReq") ); + } + + pMac->rrm.rrmPEContext.pCurrentReq = NULL; + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * rrmProcessMessage + * + * FUNCTION: Processes the next received Radio Resource Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void rrmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + switch (pMsg->type) + { + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + rrmProcessNeighborReportReq( pMac, pMsg->bodyptr ); + break; + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr ); + break; + } + +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c new file mode 100644 index 0000000000000..88f8b862884fa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schApi.c @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schApi.cc contains functions related to the API exposed + * by scheduler module + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniCfgSta.h" + +#include "sirMacProtDef.h" +#include "sirMacPropExts.h" +#include "sirCommon.h" + + +#include "cfgApi.h" +#include "pmmApi.h" + +#include "limApi.h" + +#include "schApi.h" +#include "schDebug.h" + +#include "schSysParams.h" +#include "limTrace.h" +#include "limTypes.h" + +#include "wlan_qct_wda.h" + +//-------------------------------------------------------------------- +// +// Static Variables +// +//------------------------------------------------------------------- + +// -------------------------------------------------------------------- +/** + * schGetCFPCount + * + * FUNCTION: + * Function used by other Sirius modules to read CFPcount + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tANI_U8 +schGetCFPCount(tpAniSirGlobal pMac) +{ + return pMac->sch.schObject.gSchCFPCount; +} + +// -------------------------------------------------------------------- +/** + * schGetCFPDurRemaining + * + * FUNCTION: + * Function used by other Sirius modules to read CFPDuration remaining + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tANI_U16 +schGetCFPDurRemaining(tpAniSirGlobal pMac) +{ + return pMac->sch.schObject.gSchCFPDurRemaining; +} + + +// -------------------------------------------------------------------- +/** + * schInitialize + * + * FUNCTION: + * Initialize + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schInitialize(tpAniSirGlobal pMac) +{ + pmmInitialize(pMac); +} + +// -------------------------------------------------------------------- +/** + * schInitGlobals + * + * FUNCTION: + * Initialize globals + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schInitGlobals(tpAniSirGlobal pMac) +{ + pMac->sch.gSchHcfEnabled = false; + + pMac->sch.gSchScanRequested = false; + pMac->sch.gSchScanReqRcvd = false; + + pMac->sch.gSchGenBeacon = 1; + pMac->sch.gSchBeaconsSent = 0; + pMac->sch.gSchBeaconsWritten = 0; + pMac->sch.gSchBcnParseErrorCnt = 0; + pMac->sch.gSchBcnIgnored = 0; + pMac->sch.gSchBBXportRcvCnt = 0; + pMac->sch.gSchUnknownRcvCnt = 0; + pMac->sch.gSchBcnRcvCnt = 0; + pMac->sch.gSchRRRcvCnt = 0; + pMac->sch.qosNullCnt = 0; + pMac->sch.numData = 0; + pMac->sch.numPoll = 0; + pMac->sch.numCorrupt = 0; + pMac->sch.numBogusInt = 0; + pMac->sch.numTxAct0 = 0; + pMac->sch.rrTimeout = SCH_RR_TIMEOUT; + pMac->sch.pollPeriod = SCH_POLL_PERIOD; + pMac->sch.keepAlive = 0; + pMac->sch.multipleSched = 1; + pMac->sch.maxPollTimeouts = 20; + pMac->sch.checkCfbFlagStuck = 0; +} + +// -------------------------------------------------------------------- +/** + * schPostMessage + * + * FUNCTION: + * Post the beacon message to the scheduler message queue + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMsg pointer to message + * @return None + */ + +tSirRetStatus +schPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + schProcessMessage(pMac, pMsg); + + return eSIR_SUCCESS; +} + + + + + +// --------------------------------------------------------------------------- +/** + * schSendStartScanRsp + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schSendStartScanRsp(tpAniSirGlobal pMac) +{ + tSirMsgQ msgQ; + tANI_U32 retCode; + + PELOG1(schLog(pMac, LOG1, FL("Sending LIM message to go into scan"));) + msgQ.type = SIR_SCH_START_SCAN_RSP; + if ((retCode = limPostMsgApi(pMac, &msgQ)) != eSIR_SUCCESS) + schLog(pMac, LOGE, + FL("Posting START_SCAN_RSP to LIM failed, reason=%X"), retCode); +} + +/** + * schSendBeaconReq + * + * FUNCTION: + * + * LOGIC: + * 1) SCH received SIR_SCH_BEACON_GEN_IND + * 2) SCH updates TIM IE and other beacon related IE's + * 3) SCH sends WDA_SEND_BEACON_REQ to HAL. HAL then copies the beacon + * template to memory + * + * ASSUMPTIONS: + * Memory allocation is reqd to send this message and SCH allocates memory. + * The assumption is that HAL will "free" this memory. + * + * NOTE: + * + * @param pMac global + * + * @param beaconPayload + * + * @param size - Length of the beacon + * + * @return eHalStatus + */ +tSirRetStatus schSendBeaconReq( tpAniSirGlobal pMac, tANI_U8 *beaconPayload, tANI_U16 size, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpSendbeaconParams beaconParams = NULL; + tSirRetStatus retCode; + + schLog( pMac, LOG2, + FL( "Indicating HAL to copy the beacon template [%d bytes] to memory" ), + size ); + + beaconParams = vos_mem_malloc(sizeof(tSendbeaconParams)); + if ( NULL == beaconParams ) + return eSIR_FAILURE; + + msgQ.type = WDA_SEND_BEACON_REQ; + + // No Dialog Token reqd, as a response is not solicited + msgQ.reserved = 0; + + // Fill in tSendbeaconParams members + vos_mem_copy(beaconParams->bssId, psessionEntry->bssId, sizeof(psessionEntry->bssId)); + + if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) + { + beaconParams->timIeOffset = 0; + } + else + { + beaconParams->timIeOffset = psessionEntry->schBeaconOffsetBegin; + } + + /* p2pIeOffset should be atleast greater than timIeOffset */ + if ((pMac->sch.schObject.p2pIeOffset != 0) && + (pMac->sch.schObject.p2pIeOffset < + psessionEntry->schBeaconOffsetBegin)) + { + schLog(pMac, LOGE,FL("Invalid p2pIeOffset:[%d]"), + pMac->sch.schObject.p2pIeOffset); + VOS_ASSERT( 0 ); + vos_mem_free(beaconParams); + return eSIR_FAILURE; + } + beaconParams->p2pIeOffset = pMac->sch.schObject.p2pIeOffset; +#ifdef WLAN_SOFTAP_FW_BEACON_TX_PRNT_LOG + schLog(pMac, LOGE,FL("TimIeOffset:[%d]"),beaconParams->TimIeOffset ); +#endif + + beaconParams->beacon = beaconPayload; + beaconParams->beaconLength = (tANI_U32) size; + msgQ.bodyptr = beaconParams; + msgQ.bodyval = 0; + + // Keep a copy of recent beacon frame sent + + // free previous copy of the beacon + if (psessionEntry->beacon ) + { + vos_mem_free(psessionEntry->beacon); + } + + psessionEntry->bcnLen = 0; + psessionEntry->beacon = NULL; + + psessionEntry->beacon = vos_mem_malloc(size); + if ( psessionEntry->beacon != NULL ) + { + vos_mem_copy(psessionEntry->beacon, beaconPayload, size); + psessionEntry->bcnLen = size; + } + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + schLog( pMac, LOGE, + FL("Posting SEND_BEACON_REQ to HAL failed, reason=%X"), + retCode ); + } else + { + schLog( pMac, LOG2, + FL("Successfully posted WDA_SEND_BEACON_REQ to HAL")); + + if( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + && (pMac->sch.schObject.fBeaconChanged)) + { + if(eSIR_SUCCESS != (retCode = limSendProbeRspTemplateToHal(pMac,psessionEntry, + &psessionEntry->DefProbeRspIeBitmap[0]))) + { + /* check whether we have to free any memory */ + schLog(pMac, LOGE, FL("FAILED to send probe response template with retCode %d"), retCode); + } + } + } + + return retCode; +} + +tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal pMac,tpPESession psessionEntry + ,tANI_U32* IeBitmap) +{ + tSirMsgQ msgQ; + tANI_U8 *pFrame2Hal = psessionEntry->pSchProbeRspTemplate; + tpSendProbeRespParams pprobeRespParams=NULL; + tANI_U32 retCode = eSIR_FAILURE; + tANI_U32 nPayload,nBytes,nStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 addnIEPresent = VOS_FALSE; + tANI_U32 addnIELen=0; + tSirRetStatus nSirStatus; + tANI_U8 *addIE = NULL; + + nStatus = dot11fGetPackedProbeResponseSize( pMac, &psessionEntry->probeRespFrame, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to calculate the packed size f" + "or a Probe Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while calculating" + "the packed size for a Probe Response " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + //Check if probe response IE is present or not + addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0); + if (addnIEPresent) + { + //Probe rsp IE available + /*need to check the data length*/ + addIE = vos_mem_malloc(psessionEntry->addIeParams.probeRespDataLen); + if ( NULL == addIE ) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length")); + return retCode; + } + addnIELen = psessionEntry->addIeParams.probeRespDataLen; + + + if (addnIELen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIELen && + (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) + { + + + vos_mem_copy(addIE, psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); + } + } + + if (addnIEPresent) + { + if ((nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE ) + nBytes += addnIELen; + else + addnIEPresent = false; //Dont include the IE. + } + + // Paranoia: + vos_mem_set(pFrame2Hal, nBytes, 0); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame2Hal, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_RSP, psessionEntry->selfMacAddr,psessionEntry->selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + schLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Response (%d)."), + nSirStatus ); + + vos_mem_free(addIE); + return retCode; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame2Hal; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + // That done, pack the Probe Response: + nStatus = dot11fPackProbeResponse( pMac, &psessionEntry->probeRespFrame, pFrame2Hal + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%08x)."), + nStatus ); + + vos_mem_free(addIE); + return retCode; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a P" + "robe Response (0x%08x)."), nStatus ); + } + + if (addnIEPresent) + { + vos_mem_copy ( &pFrame2Hal[nBytes - addnIELen], + &addIE[0], addnIELen); + } + + /* free the allocated Memory */ + vos_mem_free(addIE); + + pprobeRespParams = vos_mem_malloc(sizeof( tSendProbeRespParams )); + if ( NULL == pprobeRespParams ) + { + schLog( pMac, LOGE, FL("limSendProbeRspTemplateToHal: HAL probe response params malloc failed for bytes %d"), nBytes ); + } + else + { + sirCopyMacAddr( pprobeRespParams->bssId, psessionEntry->bssId); + pprobeRespParams->pProbeRespTemplate = pFrame2Hal; + pprobeRespParams->probeRespTemplateLen = nBytes; + vos_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap,IeBitmap,(sizeof(tANI_U32) * 8)); + msgQ.type = WDA_SEND_PROBE_RSP_TMPL; + msgQ.reserved = 0; + msgQ.bodyptr = pprobeRespParams; + msgQ.bodyval = 0; + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + /* free the allocated Memory */ + schLog( pMac,LOGE, FL("limSendProbeRspTemplateToHal: FAIL bytes %d retcode[%X]"), nBytes, retCode ); + vos_mem_free(pprobeRespParams); + } + else + { + schLog( pMac,LOG1, FL("limSendProbeRspTemplateToHal: Probe response template msg posted to HAL of bytes %d"),nBytes ); + } + } + + return retCode; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c new file mode 100644 index 0000000000000..86b9684d330e4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconGen.c @@ -0,0 +1,858 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schBeaconGen.cc contains beacon generation related + * functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" + +#include "limUtils.h" +#include "limApi.h" + + +#include "halMsgApi.h" +#include "cfgApi.h" +#include "pmmApi.h" +#include "schApi.h" + +#include "parserApi.h" + +#include "schDebug.h" + +// +// March 15, 2006 +// Temporarily (maybe for all of Alpha-1), assuming TIM = 0 +// + +const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9}; + + +tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset) +{ + tSirRetStatus status = eSIR_FAILURE; + *pP2pIeOffset = 0; + + // Extra IE is not present + if(0 == extraIeLen) + { + return status; + } + + // Calculate the P2P IE Offset + do + { + if(*pExtraIe == 0xDD) + { + if ( vos_mem_compare ( (void *)(pExtraIe+2), &P2pOui, sizeof(P2pOui) ) ) + { + status = eSIR_SUCCESS; + break; + } + } + + (*pP2pIeOffset)++; + pExtraIe++; + }while(--extraIeLen > 0); + + return status; +} + +tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 *pFrame, tANI_U32 maxBeaconSize, + tANI_U32 *nBytes) +{ + tSirRetStatus status = eSIR_FAILURE; + tANI_U32 present, len; + tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN]; + + present = (psessionEntry->addIeParams.probeRespBCNDataLen != 0); + if(present) + { + len = psessionEntry->addIeParams.probeRespBCNDataLen; + + if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && + ((len + *nBytes) <= maxBeaconSize)) + { + + vos_mem_copy(&addIE[0], + psessionEntry->addIeParams.probeRespBCNData_buff, len); + + { + tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len); + if ((pP2pIe != NULL) && !pMac->beacon_offload) + { + tANI_U8 noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + if(noaLen) + { + if(noaLen + len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) + { + vos_mem_copy(&addIE[len], noaStream, noaLen); + len += noaLen; + /* Update IE Len */ + pP2pIe[1] += noaLen; + } + else + { + schLog(pMac, LOGE, + FL("Not able to insert NoA because of length constraint")); + } + } + } + if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) + { + vos_mem_copy(pFrame, &addIE[0], len); + *nBytes = *nBytes + len; + } + else + { + schLog(pMac, LOGW, FL("Not able to insert because of" + " length constraint %d"), len); + } + } + } + } + + return status; +} + +// -------------------------------------------------------------------- +/** + * schSetFixedBeaconFields + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tpAniBeaconStruct pBeacon = (tpAniBeaconStruct) + psessionEntry->pSchBeaconFrameBegin; + tpSirMacMgmtHdr mac; + tANI_U16 offset; + tANI_U8 *ptr; + tDot11fBeacon1 *pBcn1; + tDot11fBeacon2 *pBcn2; + tANI_U32 i, nStatus, nBytes; + tANI_U32 wpsApEnable=0, tmp; + tDot11fIEWscProbeRes *pWscProbeRes; + tANI_U8 *pExtraIe = NULL; + tANI_U32 extraIeLen =0; + tANI_U16 extraIeOffset = 0; + tANI_U16 p2pIeOffset = 0; + tSirRetStatus status = eSIR_SUCCESS; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; + + pBcn1 = vos_mem_malloc(sizeof(tDot11fBeacon1)); + if ( NULL == pBcn1 ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + + pBcn2 = vos_mem_malloc(sizeof(tDot11fBeacon2)); + if ( NULL == pBcn2 ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + vos_mem_free(pBcn1); + return eSIR_FAILURE; + } + + pWscProbeRes = vos_mem_malloc(sizeof(tDot11fIEWscProbeRes)); + if ( NULL == pWscProbeRes ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + return eSIR_FAILURE; + } + + PELOG1(schLog(pMac, LOG1, FL("Setting fixed beacon fields"));) + + /* + * First set the fixed fields + */ + + // set the TFP headers + + // set the mac header + vos_mem_set(( tANI_U8*) &pBeacon->macHdr, sizeof( tSirMacMgmtHdr ),0); + mac = (tpSirMacMgmtHdr) &pBeacon->macHdr; + mac->fc.type = SIR_MAC_MGMT_FRAME; + mac->fc.subType = SIR_MAC_MGMT_BEACON; + + for (i=0; i<6; i++) + mac->da[i] = 0xff; + + vos_mem_copy(mac->sa, psessionEntry->selfMacAddr, sizeof(psessionEntry->selfMacAddr)); + vos_mem_copy(mac->bssId, psessionEntry->bssId, sizeof (psessionEntry->bssId)); + + mac->fc.fromDS = 0; + mac->fc.toDS = 0; + + /* + * Now set the beacon body + */ + + vos_mem_set(( tANI_U8*) pBcn1, sizeof( tDot11fBeacon1 ), 0); + + // Skip over the timestamp (it'll be updated later). + + pBcn1->BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval; + PopulateDot11fCapabilities( pMac, &pBcn1->Capabilities, psessionEntry ); + if (psessionEntry->ssidHidden) + { + pBcn1->SSID.present = 1; //rest of the fileds are 0 for hidden ssid + if((psessionEntry->ssId.length) && + (psessionEntry->ssidHidden == eHIDDEN_SSID_ZERO_CONTENTS)) + pBcn1->SSID.num_ssid = psessionEntry->ssId.length; + } + else + { + PopulateDot11fSSID( pMac, &psessionEntry->ssId, &pBcn1->SSID ); + } + + + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &pBcn1->SuppRates,psessionEntry); + PopulateDot11fDSParams( pMac, &pBcn1->DSParams, psessionEntry->currentOperChannel, psessionEntry); + PopulateDot11fIBSSParams( pMac, &pBcn1->IBSSParams,psessionEntry); + + offset = sizeof( tAniBeaconStruct ); + ptr = psessionEntry->pSchBeaconFrameBegin + offset; + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + /* Initialize the default IE bitmap to zero */ + vos_mem_set(( tANI_U8* )&(psessionEntry->DefProbeRspIeBitmap), (sizeof( tANI_U32 ) * 8), 0); + + /* Initialize the default IE bitmap to zero */ + vos_mem_set(( tANI_U8* )&(psessionEntry->probeRespFrame), + sizeof(psessionEntry->probeRespFrame), 0); + + /* Can be efficiently updated whenever new IE added + * in Probe response in future + */ + if (limUpdateProbeRspTemplateIeBitmapBeacon1(pMac, pBcn1, + psessionEntry) != eSIR_SUCCESS) { + schLog(pMac, LOGE, + FL("Failed to build ProbeRsp template")); + } + } + + nStatus = dot11fPackBeacon1( pMac, pBcn1, ptr, + SCH_MAX_BEACON_SIZE - offset, + &nBytes ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon1 (0x%0" + "8x.)."), nStatus ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a tDo" + "t11fBeacon1 (0x%08x.)."), nStatus ); + } + /*changed to correct beacon corruption */ + vos_mem_set(( tANI_U8*) pBcn2, sizeof( tDot11fBeacon2 ), 0); + psessionEntry->schBeaconOffsetBegin = offset + ( tANI_U16 )nBytes; + schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d"), offset ); + + /* + * Initialize the 'new' fields at the end of the beacon + */ + + + PopulateDot11fCountry( pMac, &pBcn2->Country, psessionEntry); + if(pBcn1->Capabilities.qos) + { + PopulateDot11fEDCAParamSet( pMac, &pBcn2->EDCAParamSet, psessionEntry); + } + + if(psessionEntry->lim11hEnable) + { + PopulateDot11fPowerConstraints( pMac, &pBcn2->PowerConstraints ); + PopulateDot11fTPCReport( pMac, &pBcn2->TPCReport, psessionEntry); + + /* Need to insert channel switch announcement here */ + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_P2P_DEVICE_GO) && + psessionEntry->dfsIncludeChanSwIe == VOS_TRUE) + { + /* Channel switch announcement only if radar is detected + * and SAP has instructed to announce channel switch IEs + * in beacon and probe responses + */ + PopulateDot11fChanSwitchAnn(pMac, &pBcn2->ChanSwitchAnn, + psessionEntry); + + /* TODO: depending the CB mode, extended channel switch announcement + * need to be called + */ + /*PopulateDot11fExtChanSwitchAnn(pMac, &pBcn2->ExtChanSwitchAnn, + psessionEntry);*/ +#ifdef WLAN_FEATURE_11AC + /* TODO: If in 11AC mode, wider bw channel switch announcement needs + * to be called + */ + /*PopulateDot11fWiderBWChanSwitchAnn(pMac, &pBcn2->WiderBWChanSwitchAnn, + psessionEntry);*/ +#endif + /* + * Populate the Channel Switch Wrapper Element if + * SAP operates in 40/80 Mhz Channel Width. + */ + if (VOS_TRUE == psessionEntry->dfsIncludeChanWrapperIe) + { + PopulateDot11fChanSwitchWrapper(pMac, + &pBcn2->ChannelSwitchWrapper, + psessionEntry); + } + } + } + + + if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B) + PopulateDot11fERPInfo( pMac, &pBcn2->ERPInfo, psessionEntry ); + + if(psessionEntry->htCapability) + { + PopulateDot11fHTCaps( pMac,psessionEntry, &pBcn2->HTCaps ); + PopulateDot11fHTInfo( pMac, &pBcn2->HTInfo, psessionEntry ); + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + schLog( pMac, LOGW, FL("Populate VHT IEs in Beacon")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &pBcn2->VHTCaps ); + PopulateDot11fVHTOperation( pMac, &pBcn2->VHTOperation); + isVHTEnabled = eANI_BOOLEAN_TRUE; + // we do not support multi users yet + //PopulateDot11fVHTExtBssLoad( pMac, &bcn2.VHTExtBssLoad); + if(psessionEntry->gLimOperatingMode.present) + PopulateDot11fOperatingMode( pMac, &pBcn2->OperatingMode, psessionEntry ); + } +#endif + + PopulateDot11fExtCap(pMac, isVHTEnabled, &pBcn2->ExtCap, psessionEntry); + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pBcn2->ExtSuppRates, psessionEntry ); + + if( psessionEntry->pLimStartBssReq != NULL ) + { + PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE, + &pBcn2->WPA ); + PopulateDot11fRSNOpaque( pMac, &psessionEntry->pLimStartBssReq->rsnIE, + &pBcn2->RSNOpaque ); + } + + if(psessionEntry->limWmeEnabled) + { + PopulateDot11fWMM( pMac, &pBcn2->WMMInfoAp, &pBcn2->WMMParams, &pBcn2->WMMCaps, psessionEntry); + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry); + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + schLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + + if (wpsApEnable) + { + PopulateDot11fWsc(pMac, &pBcn2->WscBeacon); + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) + { + PopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon); + pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS; + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END) + { + DePopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon); + pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_NOOP; + } + } + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + /* Can be efficiently updated whenever new IE added in Probe response in future */ + limUpdateProbeRspTemplateIeBitmapBeacon2(pMac,pBcn2,&psessionEntry->DefProbeRspIeBitmap[0], + &psessionEntry->probeRespFrame); + + /* update probe response WPS IE instead of beacon WPS IE + * */ + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + if(psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent) + { + PopulateDot11fProbeResWPSIEs(pMac, pWscProbeRes, psessionEntry); + } + else + { + pWscProbeRes->present = 0; + } + if(pWscProbeRes->present) + { + SetProbeRspIeBitmap(&psessionEntry->DefProbeRspIeBitmap[0],SIR_MAC_WPA_EID); + vos_mem_copy((void *)&psessionEntry->probeRespFrame.WscProbeRes, + (void *)pWscProbeRes, + sizeof(tDot11fIEWscProbeRes)); + } + } + + } + + nStatus = dot11fPackBeacon2( pMac, pBcn2, + psessionEntry->pSchBeaconFrameEnd, + SCH_MAX_BEACON_SIZE, &nBytes ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon2 (0x%0" + "8x.)."), nStatus ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a tDo" + "t11fBeacon2 (0x%08x.)."), nStatus ); + } + + pExtraIe = psessionEntry->pSchBeaconFrameEnd + nBytes; + extraIeOffset = nBytes; + + //TODO: Append additional IE here. + schAppendAddnIE(pMac, psessionEntry, + psessionEntry->pSchBeaconFrameEnd + nBytes, + SCH_MAX_BEACON_SIZE, &nBytes); + + psessionEntry->schBeaconOffsetEnd = ( tANI_U16 )nBytes; + + extraIeLen = nBytes - extraIeOffset; + + //Get the p2p Ie Offset + status = schGetP2pIeOffset(pExtraIe, extraIeLen, &p2pIeOffset); + + if(eSIR_SUCCESS == status) + { + //Update the P2P Ie Offset + pMac->sch.schObject.p2pIeOffset = + psessionEntry->schBeaconOffsetBegin + TIM_IE_SIZE + + extraIeOffset + p2pIeOffset; + } + else + { + pMac->sch.schObject.p2pIeOffset = 0; + } + + schLog( pMac, LOG1, FL("Initialized beacon end, offset %d"), + psessionEntry->schBeaconOffsetEnd ); + + pMac->sch.schObject.fBeaconChanged = 1; + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_SUCCESS; +} + +tSirRetStatus limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac, + tDot11fBeacon1* beacon1, + tpPESession psessionEntry) +{ + tANI_U32* DefProbeRspIeBitmap; + tDot11fProbeResponse* prb_rsp; + + if (!psessionEntry) { + schLog(pMac, LOGE, FL("PESession is null!")); + return eSIR_FAILURE; + } + + DefProbeRspIeBitmap = &psessionEntry->DefProbeRspIeBitmap[0]; + prb_rsp = &psessionEntry->probeRespFrame; + + prb_rsp->BeaconInterval = beacon1->BeaconInterval; + vos_mem_copy((void *)&prb_rsp->Capabilities, (void *)&beacon1->Capabilities, + sizeof(beacon1->Capabilities)); + + /* SSID */ + if(beacon1->SSID.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_SSID_EID); + /* populating it, because probe response has to go with + * SSID even in hidden case + */ + PopulateDot11fSSID(pMac, &psessionEntry->ssId, &prb_rsp->SSID); + } + /* supported rates */ + if(beacon1->SuppRates.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RATESET_EID); + vos_mem_copy((void *)&prb_rsp->SuppRates, (void *)&beacon1->SuppRates, + sizeof(beacon1->SuppRates)); + + } + /* DS Parameter set */ + if(beacon1->DSParams.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_DS_PARAM_SET_EID); + vos_mem_copy((void *)&prb_rsp->DSParams, (void *)&beacon1->DSParams, + sizeof(beacon1->DSParams)); + + } + + /* IBSS params will not be present in the Beacons transmitted by AP */ + + return eSIR_SUCCESS; +} + +void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal pMac, + tDot11fBeacon2* beacon2, + tANI_U32* DefProbeRspIeBitmap, + tDot11fProbeResponse* prb_rsp) +{ + /* IBSS parameter set - will not be present in probe response tx by AP */ + /* country */ + if(beacon2->Country.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_COUNTRY_EID); + vos_mem_copy((void *)&prb_rsp->Country, (void *)&beacon2->Country, + sizeof(beacon2->Country)); + + } + /* Power constraint */ + if(beacon2->PowerConstraints.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_PWR_CONSTRAINT_EID); + vos_mem_copy((void *)&prb_rsp->PowerConstraints, (void *)&beacon2->PowerConstraints, + sizeof(beacon2->PowerConstraints)); + + } + /* Channel Switch Annoouncement SIR_MAC_CHNL_SWITCH_ANN_EID */ + if(beacon2->ChanSwitchAnn.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_CHNL_SWITCH_ANN_EID); + vos_mem_copy((void *)&prb_rsp->ChanSwitchAnn, (void *)&beacon2->ChanSwitchAnn, + sizeof(beacon2->ChanSwitchAnn)); + + } + /* ERP information */ + if(beacon2->ERPInfo.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_ERP_INFO_EID); + vos_mem_copy((void *)&prb_rsp->ERPInfo, (void *)&beacon2->ERPInfo, + sizeof(beacon2->ERPInfo)); + + } + /* Extended supported rates */ + if(beacon2->ExtSuppRates.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EXTENDED_RATE_EID); + vos_mem_copy((void *)&prb_rsp->ExtSuppRates, (void *)&beacon2->ExtSuppRates, + sizeof(beacon2->ExtSuppRates)); + + } + + /* WPA */ + if(beacon2->WPA.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WPA, (void *)&beacon2->WPA, + sizeof(beacon2->WPA)); + + } + + /* RSN */ + if(beacon2->RSNOpaque.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RSN_EID); + vos_mem_copy((void *)&prb_rsp->RSNOpaque, (void *)&beacon2->RSNOpaque, + sizeof(beacon2->RSNOpaque)); + } + + /* EDCA Parameter set */ + if(beacon2->EDCAParamSet.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EDCA_PARAM_SET_EID); + vos_mem_copy((void *)&prb_rsp->EDCAParamSet, (void *)&beacon2->EDCAParamSet, + sizeof(beacon2->EDCAParamSet)); + + } + /* Vendor specific - currently no vendor specific IEs added */ + /* Requested IEs - currently we are not processing this will be added later */ + //HT capability IE + if(beacon2->HTCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_CAPABILITIES_EID); + vos_mem_copy((void *)&prb_rsp->HTCaps, (void *)&beacon2->HTCaps, + sizeof(beacon2->HTCaps)); + } + // HT Info IE + if(beacon2->HTInfo.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_INFO_EID); + vos_mem_copy((void *)&prb_rsp->HTInfo, (void *)&beacon2->HTInfo, + sizeof(beacon2->HTInfo)); + } + +#ifdef WLAN_FEATURE_11AC + if(beacon2->VHTCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_CAPABILITIES_EID); + vos_mem_copy((void *)&prb_rsp->VHTCaps, (void *)&beacon2->VHTCaps, + sizeof(beacon2->VHTCaps)); + } + if(beacon2->VHTOperation.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_OPERATION_EID); + vos_mem_copy((void *)&prb_rsp->VHTOperation, (void *)&beacon2->VHTOperation, + sizeof(beacon2->VHTOperation)); + } + if(beacon2->VHTExtBssLoad.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_EXT_BSS_LOAD_EID); + vos_mem_copy((void *)&prb_rsp->VHTExtBssLoad, (void *)&beacon2->VHTExtBssLoad, + sizeof(beacon2->VHTExtBssLoad)); + } +#endif + + //WMM IE + if(beacon2->WMMParams.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WMMParams, (void *)&beacon2->WMMParams, + sizeof(beacon2->WMMParams)); + } + //WMM capability - most of the case won't be present + if(beacon2->WMMCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WMMCaps, (void *)&beacon2->WMMCaps, + sizeof(beacon2->WMMCaps)); + } + +} + +void SetProbeRspIeBitmap(tANI_U32* IeBitmap,tANI_U32 pos) +{ + tANI_U32 index,temp; + + index = pos >> 5; + if(index >= 8 ) + { + return; + } + temp = IeBitmap[index]; + + temp |= 1 << (pos & 0x1F); + + IeBitmap[index] = temp; +} + + + +// -------------------------------------------------------------------- +/** + * writeBeaconToMemory + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @param size Size of the beacon to write to memory + * @param length Length field of the beacon to write to memory + * @return None + */ + +void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tpPESession psessionEntry) +{ + tANI_U16 i; + tpAniBeaconStruct pBeacon; + + // copy end of beacon only if length > 0 + if (length > 0) + { + for (i=0; i < psessionEntry->schBeaconOffsetEnd; i++) + psessionEntry->pSchBeaconFrameBegin[size++] = psessionEntry->pSchBeaconFrameEnd[i]; + } + + // Update the beacon length + pBeacon = (tpAniBeaconStruct) psessionEntry->pSchBeaconFrameBegin; + // Do not include the beaconLength indicator itself + if (length == 0) + { + pBeacon->beaconLength = 0; + // Dont copy entire beacon, Copy length field alone + size = 4; + } + else + pBeacon->beaconLength = (tANI_U32) size - sizeof( tANI_U32 ); + + // write size bytes from pSchBeaconFrameBegin + PELOG2(schLog(pMac, LOG2, FL("Beacon size - %d bytes"), size);) + PELOG2(sirDumpBuf(pMac, SIR_SCH_MODULE_ID, LOG2, psessionEntry->pSchBeaconFrameBegin, size);) + + if (! pMac->sch.schObject.fBeaconChanged) + return; + + pMac->sch.gSchGenBeacon = 1; + if (pMac->sch.gSchGenBeacon) + { + pMac->sch.gSchBeaconsSent++; + + // + // Copy beacon data to SoftMAC shared memory... + // Do this by sending a message to HAL + // + + size = (size + 3) & (~3); + if( eSIR_SUCCESS != schSendBeaconReq( pMac, psessionEntry->pSchBeaconFrameBegin, + size, psessionEntry)) + PELOGE(schLog(pMac, LOGE, FL("schSendBeaconReq() returned an error (zsize %d)"), size);) + else + { + pMac->sch.gSchBeaconsWritten++; + } + } + pMac->sch.schObject.fBeaconChanged = 0; +} + +// -------------------------------------------------------------------- +/** + * @function: SchProcessPreBeaconInd + * + * @brief : Process the PreBeacon Indication from the Lim + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param : pMac - tpAniSirGlobal + * + * @return None + */ + +void +schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpBeaconGenParams pMsg = (tpBeaconGenParams)limMsg->bodyptr; + tANI_U32 beaconSize; + tpPESession psessionEntry; + tANI_U8 sessionId; + + if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId, &sessionId))== NULL) + { + PELOGE(schLog(pMac, LOGE, FL("session lookup fails"));) + goto end; + } + + + beaconSize = psessionEntry->schBeaconOffsetBegin; + + // If SME is not in normal mode, no need to generate beacon + if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) + { + PELOGE(schLog(pMac, LOG1, FL("PreBeaconInd received in invalid state: %d"), psessionEntry->limSmeState);) + goto end; + } + + switch(psessionEntry->limSystemRole){ + + case eLIM_STA_IN_IBSS_ROLE: + case eLIM_BT_AMP_AP_ROLE: + case eLIM_BT_AMP_STA_ROLE: + // generate IBSS parameter set + if(psessionEntry->statypeForBss == STA_ENTRY_SELF) + writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry); + else + PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));) + break; + + case eLIM_AP_ROLE:{ + tANI_U8 *ptr = &psessionEntry->pSchBeaconFrameBegin[psessionEntry->schBeaconOffsetBegin]; + tANI_U16 timLength = 0; + if(psessionEntry->statypeForBss == STA_ENTRY_SELF){ + pmmGenerateTIM(pMac, &ptr, &timLength, psessionEntry->dtimPeriod); + beaconSize += 2 + timLength; + writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry); + } + else + PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));) + } + break; + + + default: + PELOGE(schLog(pMac, LOGE, FL("Error-PE has Receive PreBeconGenIndication when System is in %d role"), + psessionEntry->limSystemRole);) + } + +end: + vos_mem_free(pMsg); + +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconProcess.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconProcess.c new file mode 100644 index 0000000000000..f1336345d138a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schBeaconProcess.c @@ -0,0 +1,882 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schBeaconProcess.cc contains beacon processing related + * functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfgSta.h" + +#include "cfgApi.h" +#include "pmmApi.h" +#include "limApi.h" +#include "utilsApi.h" +#include "schDebug.h" +#include "schApi.h" + + +#include "limUtils.h" +#include "limSendMessages.h" +#include "limStaHashApi.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT + +/** + * Number of bytes of variation in beacon length from the last beacon + * to trigger reprogramming of rx delay register + */ +#define SCH_BEACON_LEN_DELTA 3 + +// calculate 2^cw - 1 +#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1)) + +static void +ap_beacon_process( + tpAniSirGlobal pMac, + tANI_U8* pRxPacketInfo, + tpSchBeaconStruct pBcnStruct, + tpUpdateBeaconParams pBeaconParams, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + tANI_U32 phyMode; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + //Get RF band from psessionEntry + rfBand = psessionEntry->limRFBand; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + if (psessionEntry->htCapability) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + //11a (non HT) AP overlaps or + //HT AP with HT op mode as mixed overlaps. + //HT AP with HT op mode as overlap legacy overlaps. + if ((!pBcnStruct->HTInfo.present) || + (eSIR_HT_OP_MODE_MIXED == pBcnStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlap11aParams)); + + if (pMac->lim.gLimOverlap11aParams.numSta && + !pMac->lim.gLimOverlap11aParams.protectionEnabled) + { + limEnable11aProtection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + //HT AP with HT20 op mode overlaps. + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlapHt20Params)); + + if (pMac->lim.gLimOverlapHt20Params.numSta && + !pMac->lim.gLimOverlapHt20Params.protectionEnabled) + { + limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + //We are 11G AP. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && + (false == psessionEntry->htCapability)) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + if (((!(pBcnStruct->erpPresent)) && + !(pBcnStruct->HTInfo.present))|| + //if erp not present then 11B AP overlapping + (pBcnStruct->erpPresent && + (pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent))) + { +#ifdef FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__, + pBcnStruct->erpPresent, + pBcnStruct->erpIEInfo.useProtection, + pBcnStruct->erpIEInfo.nonErpPresent); + } +#endif + limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry); + } + + } + } + // handling the case when HT AP has overlapping legacy BSS. + else if(psessionEntry->htCapability) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + if (((!(pBcnStruct->erpPresent)) && + !(pBcnStruct->HTInfo.present))|| + //if erp not present then 11B AP overlapping + (pBcnStruct->erpPresent && + (pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent))) + { +#ifdef FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__, + pBcnStruct->erpPresent, + pBcnStruct->erpIEInfo.useProtection, + pBcnStruct->erpIEInfo.nonErpPresent); + } +#endif + limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry); + } + + //11g device overlaps + if (pBcnStruct->erpPresent && + !(pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent) && !(pBcnStruct->HTInfo.present)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams)); + + if (psessionEntry->gLimOverlap11gParams.numSta && + !psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry); + } + } + + //ht device overlaps. + //here we will check for HT related devices only which might need protection. + //check for 11b and 11g is already done in the previous blocks. + //so we will not check for HT operating mode as MIXED. + if (pBcnStruct->HTInfo.present) + { + //if we are not already in mixed mode or legacy mode as HT operating mode + //and received beacon has HT operating mode as legacy + //then we need to enable protection from 11g station. + //we don't need protection from 11b because if that's needed then our operating + //mode would have already been set to legacy in the previous blocks. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode) + { + if((eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams)); + if (psessionEntry->gLimOverlap11gParams.numSta && + !psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlapHt20Params)); + if (psessionEntry->gLimOverlapHt20Params.numSta && + !psessionEntry->gLimOverlapHt20Params.protectionEnabled) + { + limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + + } + } + } + pMac->sch.gSchBcnIgnored++; +} +// -------------------------------------------------------------------- + + + + +/** + * __schBeaconProcessNoSession + * + * FUNCTION: + * Process the received beacon frame when + * -- Station is not scanning + * -- No corresponding session is found + * + * LOGIC: + * Following scenarios exist when Session Does not exist: + * * IBSS Beacons, when IBSS session already exists with same SSID, + * but from STA which has not yet joined and has a different BSSID. + * - invoke limHandleIBSScoalescing with the session context of existing IBSS session. + * + * * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists, + * then save the beacon in the scan results and throw it away. + * + * * Infra Beacons + * - beacons received when no session active + * should not come here, it should be handled as part of scanning, + * else they should not be getting received, should update scan results and drop it if that happens. + * - beacons received when IBSS session active: + * update scan results and drop it. + * - beacons received when Infra session(STA) is active: + * update scan results and drop it + * - beacons received when BT-STA session is active: + * update scan results and drop it. + * - beacons received when Infra/BT-STA or Infra/IBSS is active. + * update scan results and drop it. + * + + */ +static void __schBeaconProcessNoSession(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon,tANI_U8* pRxPacketInfo) +{ + tpPESession psessionEntry = NULL; + + if( (psessionEntry = limIsIBSSSessionActive(pMac)) != NULL) + { + limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry); + } + + //If station(STA/BT-STA/BT-AP/IBSS) mode, Always save the beacon in the scan results, if atleast one session is active + //schBeaconProcessNoSession will be called only when there is atleast one session active, so not checking + //it again here. + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + return; +} + + + +/* + * __schBeaconProcessForSession + * + * FUNCTION: + * Process the received beacon frame when + * -- Station is not scanning + * -- Corresponding session is found + * + * LOGIC: + * Following scenarios exist when Session exists + * * IBSS STA receving beacons from IBSS Peers, who are part of IBSS. + * - call limHandleIBSScoalescing with that session context. + * * Infra STA receving beacons from AP to which it is connected + * - call schBeaconProcessFromAP with that session's context. + * * BTAMP STA receving beacons from BTAMP AP + * - call schBeaconProcessFromAP with that session's context. + * * BTAMP AP receiving beacons from BTAMP STA + * (here need to make sure BTAP creates session entry for BT STA) + * - just update the beacon count for heart beat purposes for now, + * for now, don't process the beacon. + * * Infra/IBSS both active and receives IBSS beacon: + * - call limHandleIBSScoalescing with that session context. + * * Infra/IBSS both active and receives Infra beacon: + * - call schBeaconProcessFromAP with that session's context. + * any updates to EDCA parameters will be effective for IBSS as well, + * even though no WMM for IBSS ?? Need to figure out how to handle this scenario. + * * Infra/BTSTA both active and receive Infra beacon. + * - change in EDCA parameters on Infra affect the BTSTA link. + * Update the same parameters on BT link + * * Infra/BTSTA both active and receive BT-AP beacon. + * -update beacon cnt for heartbeat + * * Infra/BTAP both active and receive Infra beacon. + * - BT-AP starts advertising BE parameters from Infra AP, if they get changed. + * + * * Infra/BTAP both active and receive BTSTA beacon. + * - update beacon cnt for heartbeat + */ + +static void __schBeaconProcessForSession( tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tANI_U8* pRxPacketInfo, + tpPESession psessionEntry) +{ + tANI_U32 bi; + tANI_U8 bssIdx = 0; + //tpSirMacMgmtHdr pMh = SIR_MAC_BD_TO_MPDUHEADER(pRxPacketInfo); + //tANI_U8 bssid[sizeof(tSirMacAddr)]; + tUpdateBeaconParams beaconParams; + tANI_U8 sendProbeReq = FALSE; + tpDphHashNode pStaDs = NULL; +#ifdef WLAN_FEATURE_11AC + tpSirMacMgmtHdr pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + tANI_U16 aid; + tANI_U8 operMode; + tANI_U8 chWidth = 0; +#endif +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI + tPowerdBm regMax = 0,maxTxPower = 0; +#endif + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + + if(eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry); + } + else if( (eLIM_STA_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole)) + { + /* + * This handles two cases: + * -- Infra STA receving beacons from AP + * -- BTAMP_STA receving beacons from BTAMP_AP + */ + //Always save the beacon into LIM's cached scan results + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + + /** + * This is the Beacon received from the AP we're currently associated with. Check + * if there are any changes in AP's capabilities + */ + if((tANI_U8) pBeacon->channelNumber != psessionEntry->currentOperChannel) + { + PELOGE(schLog(pMac, LOGE, FL("Channel Change from %d --> %d - " + "Ignoring beacon!"), + psessionEntry->currentOperChannel, pBeacon->channelNumber);) + goto fail; + } + limDetectChangeInApCapabilities(pMac, pBeacon, psessionEntry); + if(limGetStaHashBssidx(pMac, DPH_STA_HASH_INDEX_PEER, &bssIdx, psessionEntry) != eSIR_SUCCESS) + goto fail; + beaconParams.bssIdx = bssIdx; + vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp, + ( tANI_U8* )pBeacon->timeStamp, sizeof(tANI_U64)); + psessionEntry->lastBeaconDtimCount = pBeacon->tim.dtimCount; + psessionEntry->lastBeaconDtimPeriod= pBeacon->tim.dtimPeriod; + psessionEntry->currentBssBeaconCnt++; + + + + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[0]);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[1]);) + + /* Read beacon interval session Entry */ + bi = psessionEntry->beaconParams.beaconInterval; + if (bi != pBeacon->beaconInterval) + { + PELOG1(schLog(pMac, LOG1, FL("Beacon interval changed from %d to %d"), + pBeacon->beaconInterval, bi);) + + bi = pBeacon->beaconInterval; + psessionEntry->beaconParams.beaconInterval = (tANI_U16) bi; + beaconParams.paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED; + beaconParams.beaconInterval = (tANI_U16)bi; + } + + if (pBeacon->cfPresent) + { + cfgSetInt(pMac, WNI_CFG_CFP_PERIOD, pBeacon->cfParamSet.cfpPeriod); + limSendCFParams(pMac, bssIdx, pBeacon->cfParamSet.cfpCount, pBeacon->cfParamSet.cfpPeriod); + } + + if (pBeacon->timPresent) + { + cfgSetInt(pMac, WNI_CFG_DTIM_PERIOD, pBeacon->tim.dtimPeriod); + //No need to send DTIM Period and Count to HAL/SMAC + //SMAC already parses TIM bit. + } + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + + limDecideStaProtection(pMac, pBeacon, &beaconParams, psessionEntry); + if (pBeacon->erpPresent) + { + if (pBeacon->erpIEInfo.barkerPreambleMode) + limEnableShortPreamble(pMac, false, &beaconParams, psessionEntry); + else + limEnableShortPreamble(pMac, true, &beaconParams, psessionEntry); + } + limUpdateShortSlot(pMac, pBeacon, &beaconParams,psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if ((pBeacon->wmeEdcaPresent && (psessionEntry->limWmeEnabled)) || + (pBeacon->edcaPresent && (psessionEntry->limQosEnabled))) + { + if(pBeacon->edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount) + { + if (schBeaconEdcaProcess(pMac, &pBeacon->edcaParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(schLog(pMac, LOGE, FL("EDCA parameter processing error"));) + else if(pStaDs != NULL) + { + // If needed, downgrade the EDCA parameters + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + PELOGE(schLog(pMac, LOGE, FL("Self Entry missing in Hash Table"));) + } + } + else if( (pBeacon->qosCapabilityPresent && psessionEntry->limQosEnabled) && + (pBeacon->qosCapability.qosInfo.count != psessionEntry->gLimEdcaParamSetCount)) + sendProbeReq = TRUE; + } + + if ( psessionEntry->htCapability && pBeacon->HTInfo.present ) + { + limUpdateStaRunTimeHTSwitchChnlParams( pMac, &pBeacon->HTInfo, bssIdx,psessionEntry); + } + + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) ) + { + /* Channel Switch information element updated */ + if(pBeacon->channelSwitchPresent || + pBeacon->propIEinfo.propChannelSwitchPresent) + { + limUpdateChannelSwitch(pMac, pBeacon, psessionEntry); + } + else if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limCancelDot11hChannelSwitch(pMac, psessionEntry); + } + } + +#ifdef WLAN_FEATURE_11AC + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)) + { + // check for VHT capability + pStaDs = dphLookupHashEntry(pMac, pMh->sa, &aid, + &psessionEntry->dph.dphHashTable); + if (NULL != pStaDs) + { + if (psessionEntry->vhtCapability && pBeacon->OperatingMode.present ) + { + operMode = pStaDs->vhtSupportedChannelWidthSet ? + eHT_CHANNEL_WIDTH_80MHZ : + pStaDs->htSupportedChannelWidthSet ? + eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ; + if (operMode != pBeacon->OperatingMode.chanWidth) + { + PELOG1(schLog(pMac, LOG1, + FL(" received OpMode Chanwidth %d, staIdx = %d"), + pBeacon->OperatingMode.chanWidth, + pStaDs->staIndex);) + PELOG1(schLog(pMac, LOG1, FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"), + pMh->sa[0], + pMh->sa[1], + pMh->sa[2], + pMh->sa[3], + pMh->sa[4], + pMh->sa[5]);) + + if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 80MHz"));) + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 40MHz"));) + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if (pBeacon->OperatingMode.chanWidth == + eHT_CHANNEL_WIDTH_20MHZ) + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 20MHz"));) + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + limCheckVHTOpModeChange(pMac, psessionEntry, + pBeacon->OperatingMode.chanWidth, + pStaDs->staIndex, pMh->sa); + } + /* Update Nss setting */ + if (pStaDs->vhtSupportedRxNss != + (pBeacon->OperatingMode.rxNSS + 1)) { + pStaDs->vhtSupportedRxNss = + (pBeacon->OperatingMode.rxNSS + 1); + limSetNssChange( pMac, psessionEntry, + pStaDs->vhtSupportedRxNss, + pStaDs->staIndex, pMh->sa); + } + } + else if (psessionEntry->vhtCapability && pBeacon->VHTOperation.present) + { + operMode = pStaDs->vhtSupportedChannelWidthSet; + if (operMode != pBeacon->VHTOperation.chanWidth) + { + PELOG1(schLog(pMac, LOG1, + FL(" received VHTOP CHWidth %d staIdx = %d"), + pBeacon->VHTOperation.chanWidth, + pStaDs->staIndex);) + PELOG1(schLog(pMac, LOG1, FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"), + pMh->sa[0], + pMh->sa[1], + pMh->sa[2], + pMh->sa[3], + pMh->sa[4], + pMh->sa[5]);) + + if (pBeacon->VHTOperation.chanWidth == + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 80MHz"));) + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + chWidth = eHT_CHANNEL_WIDTH_80MHZ; + } + else if (pBeacon->VHTOperation.chanWidth == + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + if (pBeacon->HTCaps.supportedChannelWidthSet) + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 40MHz"));) + pStaDs->htSupportedChannelWidthSet = + eHT_CHANNEL_WIDTH_40MHZ; + chWidth = eHT_CHANNEL_WIDTH_40MHZ; + } + else + { + PELOG1(schLog(pMac, LOG1, + FL("Updating the CH Width to 20MHz"));) + pStaDs->htSupportedChannelWidthSet = + eHT_CHANNEL_WIDTH_20MHZ; + chWidth = eHT_CHANNEL_WIDTH_20MHZ; + } + } + limCheckVHTOpModeChange(pMac, psessionEntry, + chWidth, pStaDs->staIndex, pMh->sa); + + } + } + } + } +#endif + +#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI) + /* Obtain the Max Tx power for the current regulatory */ + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); +#endif + +#if defined WLAN_FEATURE_VOWIFI + { + tPowerdBm localRRMConstraint = 0; + if ( pMac->rrm.rrmPEContext.rrmEnable && pBeacon->powerConstraintPresent ) + { + localRRMConstraint = pBeacon->localPowerConstraint.localPowerConstraints; + } + else + { + localRRMConstraint = 0; + } + maxTxPower = limGetMaxTxPower(regMax, regMax - localRRMConstraint, + pMac->roam.configParam.nTxPowerCap); + } +#elif defined FEATURE_WLAN_ESE + maxTxPower = regMax; +#endif + +#if defined FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + tPowerdBm localESEConstraint = 0; + if (pBeacon->eseTxPwr.present) + { + localESEConstraint = pBeacon->eseTxPwr.power_limit; + maxTxPower = limGetMaxTxPower(maxTxPower, localESEConstraint, pMac->roam.configParam.nTxPowerCap); + } + schLog( pMac, LOG1, "RegMax = %d, localEseCons = %d, MaxTx = %d", regMax, localESEConstraint, maxTxPower ); + } +#endif + +#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI) + { + //If maxTxPower is increased or decreased + if( maxTxPower != psessionEntry->maxTxPower ) + { + schLog( pMac, LOG1, "Local power constraint change..updating new maxTx power %d to HAL",maxTxPower); + if( limSendSetMaxTxPowerReq ( pMac, maxTxPower, psessionEntry ) == eSIR_SUCCESS ) + psessionEntry->maxTxPower = maxTxPower; + } + } +#endif + + // Indicate to LIM that Beacon is received + + if (pBeacon->HTInfo.present) + limReceivedHBHandler(pMac, (tANI_U8)pBeacon->HTInfo.primaryChannel, psessionEntry); + else + limReceivedHBHandler(pMac, (tANI_U8)pBeacon->channelNumber, psessionEntry); + + // I don't know if any additional IE is required here. Currently, not include addIE. + if(sendProbeReq) + limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, + psessionEntry->bssId, psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + + if ((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + PELOGW(schLog(pMac, LOGW, FL("Beacon for session[%d] got changed. "), psessionEntry->peSessionId);) + PELOGW(schLog(pMac, LOGW, FL("sending beacon param change bitmap: 0x%x "), beaconParams.paramChangeBitmap);) + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + +fail: + return; + +} + + + +/** + * schBeaconProcess + * + * FUNCTION: + * Process the received beacon frame + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pRxPacketInfo pointer to buffer descriptor + * @return None + */ + +void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8* pRxPacketInfo, tpPESession psessionEntry) +{ + static tSchBeaconStruct beaconStruct; + tUpdateBeaconParams beaconParams; + tpPESession pAPSession = NULL; +#ifdef WLAN_FEATURE_MBSSID + tANI_U8 i; +#endif + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + + pMac->sch.gSchBcnRcvCnt++; + + // Convert the beacon frame into a structure + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, &beaconStruct)!= eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("beacon parsing failed"));) + pMac->sch.gSchBcnParseErrorCnt++; + return; + } + + if (beaconStruct.ssidPresent) + { + beaconStruct.ssId.ssId[beaconStruct.ssId.length] = 0; + } + + /* + * First process the beacon in the context of any existing AP or BTAP session. + * This takes cares of following two scenarios: + * - psessionEntry = NULL: + * e.g. beacon received from a neighboring BSS, you want to apply the protection settings to BTAP/InfraAP beacons + * - psessionEntry is non NULL: + * e.g. beacon received is from the INFRA AP to which you are connected on another concurrent link. + * In this case also, we want to apply the protection settings(as advertised by Infra AP) to BTAP beacons + * + * + */ + +#ifdef WLAN_FEATURE_MBSSID + + for (i =0; i < pMac->lim.maxBssId; i++) + { + if (((pAPSession = peFindSessionBySessionId(pMac, i)) != NULL) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) +#endif + ) + { + if (eLIM_AP_ROLE != pAPSession->limSystemRole) + { + continue; + } + + beaconParams.bssIdx = pAPSession->bssIdx; + if (pAPSession->gLimProtectionControl != + WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + ap_beacon_process(pMac, pRxPacketInfo, &beaconStruct, + &beaconParams, pAPSession); + + if ((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + //Update the beacons and apply the new settings to HAL + schSetFixedBeaconFields(pMac, pAPSession); + PELOG1(schLog(pMac, LOG1, + FL("Beacon for PE session[%d] got changed."), + pAPSession->peSessionId);) + PELOG1(schLog(pMac, LOG1, + FL("sending beacon param change bitmap: 0x%x"), + beaconParams.paramChangeBitmap);) + limSendBeaconParams(pMac, &beaconParams, pAPSession); + } + } + } + +#else + + if (((pAPSession = limIsApSessionActive(pMac)) != NULL) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) +#endif + ) + { + beaconParams.bssIdx = pAPSession->bssIdx; + if (pAPSession->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + ap_beacon_process(pMac, pRxPacketInfo, &beaconStruct, &beaconParams, pAPSession); + + if ((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + && beaconParams.paramChangeBitmap) + { + //Update the beacons and apply the new settings to HAL + schSetFixedBeaconFields(pMac, pAPSession); + PELOG1(schLog(pMac, LOG1, FL("Beacon for PE session[%d] got changed. "), pAPSession->peSessionId);) + PELOG1(schLog(pMac, LOG1, FL("sending beacon param change bitmap: 0x%x "), beaconParams.paramChangeBitmap);) + limSendBeaconParams(pMac, &beaconParams, pAPSession); + } + } + +#endif + + /* + * Now process the beacon in the context of the BSS which is transmitting the beacons, if one is found + */ + if(psessionEntry == NULL) + { + __schBeaconProcessNoSession(pMac, &beaconStruct, pRxPacketInfo ); + } + else + { + __schBeaconProcessForSession(pMac, &beaconStruct, pRxPacketInfo, psessionEntry ); + } + +} + + + + + +// -------------------------------------------------------------------- +/** + * schBeaconEdcaProcess + * + * FUNCTION: + * Process the EDCA parameter set in the received beacon frame + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param edca reference to edca parameters in beacon struct + * @return success + */ + +tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry) +{ + tANI_U8 i; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_log_qos_edca_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + + PELOG1(schLog(pMac, LOG1, FL("Updating parameter set count: Old %d ---> new %d"), + psessionEntry->gLimEdcaParamSetCount, edca->qosInfo.count);) + + psessionEntry->gLimEdcaParamSetCount = edca->qosInfo.count; + psessionEntry->gLimEdcaParams[EDCA_AC_BE] = edca->acbe; + psessionEntry->gLimEdcaParams[EDCA_AC_BK] = edca->acbk; + psessionEntry->gLimEdcaParams[EDCA_AC_VI] = edca->acvi; + psessionEntry->gLimEdcaParams[EDCA_AC_VO] = edca->acvo; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C); + if(log_ptr) + { + log_ptr->aci_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].aci.aci; + log_ptr->cw_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.min; + log_ptr->txoplimit_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].txoplimit; + log_ptr->aci_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].aci.aci; + log_ptr->cw_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.min; + log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].txoplimit; + log_ptr->aci_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].aci.aci; + log_ptr->cw_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.min; + log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].txoplimit; + log_ptr->aci_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].aci.aci; + log_ptr->cw_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.min; + log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].txoplimit; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + PELOG1(schLog(pMac, LOGE, FL("Updating Local EDCA Params(gLimEdcaParams) to: "));) + for(i=0; igLimEdcaParams[i].aci.aifsn, + psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].cw.min, + psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].txoplimit);) + } + + return eSIR_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.c new file mode 100644 index 0000000000000..61178feef0d86 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schDebug.cc contains some debug functions. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + + +#include "vos_trace.h" +#include "schDebug.h" +#define LOG_SIZE 256 + +void schLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) +{ + + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level*/ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + VOS_TRACE(VOS_MODULE_ID_PE, vosDebugLevel, "%s", logBuffer); + va_end( marker ); + } + + + +// -------------------------------------------------------------------- diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.h new file mode 100644 index 0000000000000..4bf6ac6b61ad8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schDebug.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schDebug.h contains some debug macros. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_DEBUG_H__ +#define __SCH_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) schLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schMessage.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schMessage.c new file mode 100644 index 0000000000000..bd33de47d557e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schMessage.c @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schMessage.cc contains the message handler + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "sirCommon.h" + +#include "wniCfgSta.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "limApi.h" +#include "pmmApi.h" +#include "limSendMessages.h" + + +#include "schApi.h" +#include "schDebug.h" + +/// Minimum beacon interval allowed (in Kus) +#define SCH_BEACON_INTERVAL_MIN 10 + +/// Maximum beacon interval allowed (in Kus) +#define SCH_BEACON_INTERVAL_MAX 10000 + +/// convert the CW values into a tANI_U16 +#define GET_CW(pCw) ((tANI_U16) ((*(pCw) << 8) + *((pCw) + 1))) + +// local functions +static tSirRetStatus getWmmLocalParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]); +static void setSchEdcaParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], tpPESession psessionEntry); + +// -------------------------------------------------------------------- +/** + * schSetBeaconInterval + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void schSetBeaconInterval(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 bi; + + bi = psessionEntry->beaconParams.beaconInterval; + + if (bi < SCH_BEACON_INTERVAL_MIN || bi > SCH_BEACON_INTERVAL_MAX) + { + schLog(pMac, LOGE, FL("Invalid beacon interval %d (should be [%d,%d]"), + bi, SCH_BEACON_INTERVAL_MIN, SCH_BEACON_INTERVAL_MAX); + return; + } + + pMac->sch.schObject.gSchBeaconInterval = (tANI_U16)bi; +} + + +// -------------------------------------------------------------------- +/** + * schProcessMessage + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void schProcessMessage(tpAniSirGlobal pMac,tpSirMsgQ pSchMsg) +{ +#ifdef FIXME_GEN6 + tANI_U32 *pBD; + tpSirMacMgmtHdr mh; + void *pPacket; +#endif + tANI_U32 val; + + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + PELOG3(schLog(pMac, LOG3, FL("Received message (%x) "), pSchMsg->type);) + + switch (pSchMsg->type) + { +#ifdef FIXME_GEN6 + case SIR_BB_XPORT_MGMT_MSG: + pMac->sch.gSchBBXportRcvCnt++; + + + pBD = (tANI_U32 *) pSchMsg->bodyptr; + + + mh = SIR_MAC_BD_TO_MPDUHEADER( pBD ); + + if (mh->fc.type == SIR_MAC_MGMT_FRAME && + mh->fc.subType == SIR_MAC_MGMT_BEACON) + schBeaconProcess(pMac, pBD); + else + { + schLog(pMac, LOGE, FL("Unexpected message (%d,%d) rcvd"), + mh->fc.type, mh->fc.subType); + pMac->sch.gSchUnknownRcvCnt++; + } + break; +#endif + + case SIR_SCH_CHANNEL_SWITCH_REQUEST: + schLog(pMac, LOGE, + FL("Channel switch request not handled")); + break; + + case SIR_SCH_START_SCAN_REQ: + pMac->sch.gSchScanReqRcvd = true; + if (pMac->sch.gSchHcfEnabled) + { + // In HCF mode, wait for TFP to stop before sending a response + if (pMac->sch.schObject.gSchCFBInitiated || + pMac->sch.schObject.gSchCFPInitiated) + { + PELOG1(schLog(pMac, LOG1, + FL("Waiting for TFP to halt before sending " + "start scan response"));) + } + else + schSendStartScanRsp(pMac); + } + else + { + // In eDCF mode, send the response right away + schSendStartScanRsp(pMac); + } + break; + + case SIR_SCH_END_SCAN_NTF: + PELOG3(schLog(pMac, LOG3, + FL("Received STOP_SCAN_NTF from LIM"));) + pMac->sch.gSchScanReqRcvd = false; + break; + + case SIR_CFG_PARAM_UPDATE_IND: + + if (wlan_cfgGetInt(pMac, (tANI_U16) pSchMsg->bodyval, &val) != eSIR_SUCCESS) + schLog(pMac, LOGP, FL("failed to cfg get id %d"), pSchMsg->bodyval); + + switch (pSchMsg->bodyval) + { + case WNI_CFG_BEACON_INTERVAL: + // What to do for IBSS ?? - TBD + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + schSetBeaconInterval(pMac,psessionEntry); + break; + + + case WNI_CFG_DTIM_PERIOD: + pMac->sch.schObject.gSchDTIMCount = 0; + break; + + case WNI_CFG_CFP_PERIOD: + pMac->sch.schObject.gSchCFPCount = 0; + break; + + case WNI_CFG_EDCA_PROFILE: + schEdcaProfileUpdate(pMac, psessionEntry); + break; + + case WNI_CFG_EDCA_ANI_ACBK_LOCAL: + case WNI_CFG_EDCA_ANI_ACBE_LOCAL: + case WNI_CFG_EDCA_ANI_ACVI_LOCAL: + case WNI_CFG_EDCA_ANI_ACVO_LOCAL: + case WNI_CFG_EDCA_WME_ACBK_LOCAL: + case WNI_CFG_EDCA_WME_ACBE_LOCAL: + case WNI_CFG_EDCA_WME_ACVI_LOCAL: + case WNI_CFG_EDCA_WME_ACVO_LOCAL: + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + schQosUpdateLocal(pMac, psessionEntry); + break; + + case WNI_CFG_EDCA_ANI_ACBK: + case WNI_CFG_EDCA_ANI_ACBE: + case WNI_CFG_EDCA_ANI_ACVI: + case WNI_CFG_EDCA_ANI_ACVO: + case WNI_CFG_EDCA_WME_ACBK: + case WNI_CFG_EDCA_WME_ACBE: + case WNI_CFG_EDCA_WME_ACVI: + case WNI_CFG_EDCA_WME_ACVO: + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + psessionEntry->gLimEdcaParamSetCount++; + schQosUpdateBroadcast(pMac, psessionEntry); + } + break; + + default: + schLog(pMac, LOGE, FL("Cfg param %d indication not handled"), + pSchMsg->bodyval); + } + break; + + default: + schLog(pMac, LOGE, FL("Unknown message in schMsgQ type %d"), + pSchMsg->type); + } + +} + + +// get the local or broadcast parameters based on the profile sepcified in the config +// params are delivered in this order: BK, BE, VI, VO +tSirRetStatus +schGetParams( + tpAniSirGlobal pMac, + tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], + tANI_U8 local) +{ + tANI_U32 val; + tANI_U32 i,idx; + tANI_U32 *prf; + + tANI_U32 ani_l[] = { WNI_CFG_EDCA_ANI_ACBE_LOCAL,WNI_CFG_EDCA_ANI_ACBK_LOCAL, + WNI_CFG_EDCA_ANI_ACVI_LOCAL, WNI_CFG_EDCA_ANI_ACVO_LOCAL }; + tANI_U32 wme_l[] = {WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL}; + tANI_U32 demo_l[] = {WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL, WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL, WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL}; + tANI_U32 ani_b[] = {WNI_CFG_EDCA_ANI_ACBE, WNI_CFG_EDCA_ANI_ACBK, + WNI_CFG_EDCA_ANI_ACVI, WNI_CFG_EDCA_ANI_ACVO}; + tANI_U32 wme_b[] = {WNI_CFG_EDCA_WME_ACBE, WNI_CFG_EDCA_WME_ACBK, + WNI_CFG_EDCA_WME_ACVI, WNI_CFG_EDCA_WME_ACVO}; + tANI_U32 demo_b[] = {WNI_CFG_EDCA_TIT_DEMO_ACBE, WNI_CFG_EDCA_TIT_DEMO_ACBK, + WNI_CFG_EDCA_TIT_DEMO_ACVI, WNI_CFG_EDCA_TIT_DEMO_ACVO}; + + if (wlan_cfgGetInt(pMac, WNI_CFG_EDCA_PROFILE, &val) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("failed to cfg get EDCA_PROFILE id %d"), + WNI_CFG_EDCA_PROFILE); + return eSIR_FAILURE; + } + + if (val >= WNI_CFG_EDCA_PROFILE_MAX) + { + schLog(pMac, LOGE, FL("Invalid EDCA_PROFILE %d, using %d instead"), + val, WNI_CFG_EDCA_PROFILE_ANI); + val = WNI_CFG_EDCA_PROFILE_ANI; + } + + schLog(pMac, LOGW, FL("EdcaProfile: Using %d (%s)"), val, + ((val == WNI_CFG_EDCA_PROFILE_WMM) ? "WMM" + : ( (val == WNI_CFG_EDCA_PROFILE_TIT_DEMO) ? "Titan" : "HiPerf"))); + + if (local) + { + switch (val) + { + case WNI_CFG_EDCA_PROFILE_WMM: + prf = &wme_l[0]; + break; + case WNI_CFG_EDCA_PROFILE_TIT_DEMO: + prf = &demo_l[0]; + break; + case WNI_CFG_EDCA_PROFILE_ANI: + default: + prf = &ani_l[0]; + break; + } + } + else + { + switch (val) + { + case WNI_CFG_EDCA_PROFILE_WMM: + prf = &wme_b[0]; + break; + case WNI_CFG_EDCA_PROFILE_TIT_DEMO: + prf = &demo_b[0]; + break; + case WNI_CFG_EDCA_PROFILE_ANI: + default: + prf = &ani_b[0]; + break; + } + } + + for (i=0; i < 4; i++) + { + tANI_U8 data[WNI_CFG_EDCA_ANI_ACBK_LEN]; + tANI_U32 len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN; + if (wlan_cfgGetStr(pMac, (tANI_U16) prf[i], (tANI_U8 *) &data[0], &len) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]); + return eSIR_FAILURE; + } + if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) + { + schLog(pMac, LOGE, FL("cfgGet for %d: length is %d instead of %d"), + prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN); + return eSIR_FAILURE; + } + for (idx=0; idx < len; idx++) + params[i][idx] = (tANI_U32) data[idx]; + } + PELOG1(schLog(pMac, LOG1, FL("GetParams: local=%d, profile = %d Done"), local, val);) + return eSIR_SUCCESS; +} + +static void broadcastWMMOfConcurrentSTASession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U8 i,j; + tpPESession pConcurrentStaSessionEntry; + + for (i =0;i < pMac->lim.maxBssId;i++) + { + /* Find another INFRA STA AP session on same operating channel. The session entry passed to this API is for GO/SoftAP session that is getting added currently */ + if ( (pMac->lim.gpSession[i].valid == TRUE ) && + (pMac->lim.gpSession[i].peSessionId != psessionEntry->peSessionId) && + (pMac->lim.gpSession[i].currentOperChannel == psessionEntry->currentOperChannel) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE) + ) + { + pConcurrentStaSessionEntry = &(pMac->lim.gpSession[i]); + for (j=0; jgLimEdcaParamsBC[j].aci.acm = pConcurrentStaSessionEntry->gLimEdcaParams[j].aci.acm; + psessionEntry->gLimEdcaParamsBC[j].aci.aifsn = pConcurrentStaSessionEntry->gLimEdcaParams[j].aci.aifsn; + psessionEntry->gLimEdcaParamsBC[j].cw.min = pConcurrentStaSessionEntry->gLimEdcaParams[j].cw.min; + psessionEntry->gLimEdcaParamsBC[j].cw.max = pConcurrentStaSessionEntry->gLimEdcaParams[j].cw.max; + psessionEntry->gLimEdcaParamsBC[j].txoplimit= pConcurrentStaSessionEntry->gLimEdcaParams[j].txoplimit; + + PELOG1(schLog(pMac, LOG1, "QoSUpdateBCast changed again due to concurrent INFRA STA session: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d", + j, + psessionEntry->gLimEdcaParamsBC[j].aci.aifsn, + psessionEntry->gLimEdcaParamsBC[j].aci.acm, + psessionEntry->gLimEdcaParamsBC[j].cw.min, + psessionEntry->gLimEdcaParamsBC[j].cw.max, + psessionEntry->gLimEdcaParamsBC[j].txoplimit);) + + } + /* Once atleast one concurrent session on same channel is found and WMM broadcast params for current SoftAP/GO session updated, return*/ + break; + } + } +} + +void +schQosUpdateBroadcast(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + tANI_U32 cwminidx, cwmaxidx, txopidx; + tANI_U32 phyMode; + tANI_U8 i; + + if (schGetParams(pMac, params, false) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("QosUpdateBroadcast: failed"));) + return; + } + limGetPhyMode(pMac, &phyMode, psessionEntry); + + PELOG1(schLog(pMac, LOG1, "QosUpdBcast: mode %d", phyMode);) + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX; + } + else if (phyMode == WNI_CFG_PHY_MODE_11B) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX; + } + else // This can happen if mode is not set yet, assume 11a mode + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX; + } + + + for(i=0; igLimEdcaParamsBC[i].aci.acm = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX]; + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX]; + psessionEntry->gLimEdcaParamsBC[i].cw.min = convertCW(GET_CW(¶ms[i][cwminidx])); + psessionEntry->gLimEdcaParamsBC[i].cw.max = convertCW(GET_CW(¶ms[i][cwmaxidx])); + psessionEntry->gLimEdcaParamsBC[i].txoplimit= (tANI_U16) params[i][txopidx]; + + PELOG1(schLog(pMac, LOG1, "QoSUpdateBCast: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d", i, + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, + psessionEntry->gLimEdcaParamsBC[i].aci.acm, + psessionEntry->gLimEdcaParamsBC[i].cw.min, + psessionEntry->gLimEdcaParamsBC[i].cw.max, + psessionEntry->gLimEdcaParamsBC[i].txoplimit);) + + } + + /* If there exists a concurrent STA-AP session, use its WMM params to broadcast in beacons. WFA Wifi Direct test plan 6.1.14 requirement */ + broadcastWMMOfConcurrentSTASession(pMac, psessionEntry); + + if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS) + PELOGE(schLog(pMac, LOGE, "Unable to set beacon fields!");) +} + +void +schQosUpdateLocal(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + tANI_BOOLEAN highPerformance=eANI_BOOLEAN_TRUE; + + if (schGetParams(pMac, params, true /*local*/) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("schGetParams(local) failed"));) + return; + } + + setSchEdcaParams(pMac, params, psessionEntry); + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if (pMac->lim.gLimNumOfAniSTAs) + highPerformance = eANI_BOOLEAN_TRUE; + else + highPerformance = eANI_BOOLEAN_FALSE; + } + else if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + highPerformance = eANI_BOOLEAN_TRUE; + } + + //For AP, the bssID is stored in LIM Global context. + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry->bssIdx, highPerformance); +} + +/** ---------------------------------------------------------- +\fn schSetDefaultEdcaParams +\brief This function sets the gLimEdcaParams to the default +\ local wmm profile. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +void +schSetDefaultEdcaParams(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + + if (getWmmLocalParams(pMac, params) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("getWmmLocalParams() failed"));) + return; + } + + setSchEdcaParams(pMac, params, psessionEntry); + return; +} + + +/** ---------------------------------------------------------- +\fn setSchEdcaParams +\brief This function fills in the gLimEdcaParams structure +\ with the given edca params. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +static void +setSchEdcaParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], tpPESession psessionEntry) +{ + tANI_U32 i; + tANI_U32 cwminidx, cwmaxidx, txopidx; + tANI_U32 phyMode; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + PELOG1(schLog(pMac, LOG1, FL("limGetPhyMode() = %d"), phyMode);) + + //if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11G) + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX; + } + //else if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11B) + else if (phyMode == WNI_CFG_PHY_MODE_11B) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX; + } + else // This can happen if mode is not set yet, assume 11a mode + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX; + } + + for(i=0; igLimEdcaParams[i].aci.acm = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX]; + psessionEntry->gLimEdcaParams[i].aci.aifsn = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX]; + psessionEntry->gLimEdcaParams[i].cw.min = convertCW(GET_CW(¶ms[i][cwminidx])); + psessionEntry->gLimEdcaParams[i].cw.max = convertCW(GET_CW(¶ms[i][cwmaxidx])); + psessionEntry->gLimEdcaParams[i].txoplimit= (tANI_U16) params[i][txopidx]; + + PELOG1(schLog(pMac, LOG1, FL("AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"), i, + psessionEntry->gLimEdcaParams[i].aci.aifsn, + psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].cw.min, + psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].txoplimit);) + + } + return; +} + +/** ---------------------------------------------------------- +\fn getWmmLocalParams +\brief This function gets the WMM local edca parameters. +\param tpAniSirGlobal pMac +\param tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN] +\return none +\ ------------------------------------------------------------ */ +static tSirRetStatus +getWmmLocalParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]) +{ + tANI_U32 i,idx; + tANI_U32 *prf; + tANI_U32 wme_l[] = {WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL}; + + prf = &wme_l[0]; + for (i=0; i < 4; i++) + { + tANI_U8 data[WNI_CFG_EDCA_ANI_ACBK_LEN]; + tANI_U32 len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN; + if (wlan_cfgGetStr(pMac, (tANI_U16) prf[i], (tANI_U8 *) &data[0], &len) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]); + return eSIR_FAILURE; + } + if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) + { + schLog(pMac, LOGE, FL("cfgGet for %d: length is %d instead of %d"), + prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN); + return eSIR_FAILURE; + } + for (idx=0; idx < len; idx++) + params[i][idx] = (tANI_U32) data[idx]; + } + return eSIR_SUCCESS; +} + + +/** ---------------------------------------------------------- +\fn schEdcaProfileUpdate +\brief This function updates the local and broadcast +\ EDCA params in the gLimEdcaParams structure. It also +\ updates the edcaParamSetCount. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +void +schEdcaProfileUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + schQosUpdateLocal(pMac, psessionEntry); + psessionEntry->gLimEdcaParamSetCount++; + schQosUpdateBroadcast(pMac, psessionEntry); + } +} + +// -------------------------------------------------------------------- diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schSysParams.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schSysParams.h new file mode 100644 index 0000000000000..55ddf027935eb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/sch/schSysParams.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schSysParams.h contains scheduler parameter definitions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_SYS_PARAMS_H__ +#define __SCH_SYS_PARAMS_H__ + +/// Unsolicited poll period (ms) (0 to disable) +#define SCH_POLL_PERIOD 1000 + +/// RR timeout value (ms) (0 to disable) +#define SCH_RR_TIMEOUT_MS 40 + +/// Default CP:CFP ratio +#define SCH_DEFAULT_CP_TO_CFP_RATIO 0 + +/// Default maximum CFP duration (us) +#define SCH_DEFAULT_MAX_CFP_TIME 60000 + +/// Default minimum CP duration (us) +#define SCH_DEFAULT_MIN_CP_TIME 100 + +/// Amount of delay prior to starting CFP (us) +#define SCH_CFP_START_DELAY 100 + +/// Unit of Txop in micro seconds +#define TXOP_UNIT_IN_USEC 32 + +/// Minimum amount of time granted per instruction on average (units of txop) +#define MIN_TXOP_PER_INSTRUCTION 50 + +/// Maximum amount of time granted per instruction (units of txop) +#define MAX_TXOP_PER_INSTRUCTION 300 // HACK - 100 + +/// Maximum amount of time granted to one entire schedule (units of txop) +#define MAX_TXOP_PER_SCHEDULE 400 + +/// Scheduling quantum (units of TXOP) +#define SCH_QUANTUM_QUEUE 4 + +/// Maximum unused quantum allowed to be accumulated by a queue +#define MAX_ACCUMULATED_QUANTUM 500 + +/// Minimum allocated quantum for an uplink flow before a poll instruction is written +#define SCH_MIN_UL_ALLOC 12 + +// ---- Scheduling Policy ---- + +/// Number of QOS classes +#define SCH_NUM_QOS_CLASSES 2 + +#define SCH_POLICY_STRICT_PRI 0 +#define SCH_POLICY_DRR 1 + +/// Scheduling quantum for each class if using DRR +#define SCH_QUANTUM_CLASS 100 + +/// The default scheduling policy between classes +#define SCH_POLICY_DEFAULT SCH_POLICY_STRICT_PRI + +// Scheduling weights for each priority + +#define SCH_QUANTUM_0 40 +#define SCH_QUANTUM_1 36 +#define SCH_QUANTUM_2 32 +#define SCH_QUANTUM_3 28 +#define SCH_QUANTUM_4 24 +#define SCH_QUANTUM_5 20 +#define SCH_QUANTUM_6 16 +#define SCH_QUANTUM_7 12 + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/inc/sapApi.h b/drivers/staging/qcacld-2.0/CORE/SAP/inc/sapApi.h new file mode 100644 index 0000000000000..d3589dcebd92f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/inc/sapApi.h @@ -0,0 +1,2313 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANSAP_H +#define WLAN_QCT_WLANSAP_H + +/*=========================================================================== + + W L A N S O F T A P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan SAP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/SAP/inc/sapApi.h,v 1.21 2009/03/09 08:58:26 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/01/08 SAP team Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +#include "vos_types.h" + +#include "p2p_Api.h" +#include "sme_Api.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + defines and enum + ------------------------------------------------------------------------*/ + +#define MAX_SSID_LEN 32 +#define MAX_ACL_MAC_ADDRESS 32 +#define AUTO_CHANNEL_SELECT 0 +#define MAX_ASSOC_IND_IE_LEN 255 + +/* defines for WPS config states */ +#define SAP_WPS_DISABLED 0 +#define SAP_WPS_ENABLED_UNCONFIGURED 1 +#define SAP_WPS_ENABLED_CONFIGURED 2 + +#define MAX_NAME_SIZE 64 +#define MAX_TEXT_SIZE 32 + +#define MAX_CHANNEL_LIST_LEN 256 +#ifdef WLAN_FEATURE_MBSSID +#define VOS_MAX_NO_OF_SAP_MODE 2 // max # of SAP +#else +#define VOS_MAX_NO_OF_SAP_MODE 1 // max # of SAP +#endif +#define SAP_MAX_NUM_SESSION 5 +#define SAP_MAX_OBSS_STA_CNT 1 // max # of OBSS STA + +/*-------------------------------------------------------------------------- + reasonCode take form 802.11 standard Table 7-22 to be passed to WLANSAP_DisassocSta api. + ------------------------------------------------------------------------*/ + +typedef enum{ + eSAP_RC_RESERVED0, /*0*/ + eSAP_RC_UNSPECIFIED, /*1*/ + eSAP_RC_PREV_AUTH_INVALID, /*2*/ + eSAP_RC_STA_LEFT_DEAUTH, /*3*/ + eSAP_RC_INACTIVITY_DISASSOC, /*4*/ + eSAP_RC_AP_CAPACITY_FULL, /*5*/ + eSAP_RC_CLS2_FROM_NON_AUTH_STA, /*6*/ + eSAP_RC_CLS3_FROM_NON_AUTH_STA, /*7*/ + eSAP_RC_STA_LEFT_DISASSOC, /*8*/ + eSAP_RC_STA_NOT_AUTH, /*9*/ + eSAP_RC_PC_UNACCEPTABLE, /*10*/ + eSAP_RC_SC_UNACCEPTABLE, /*11*/ + eSAP_RC_RESERVED1, /*12*/ + eSAP_RC_INVALID_IE, /*13*/ + eSAP_RC_MIC_FAIL, /*14*/ + eSAP_RC_4_WAY_HANDSHAKE_TO, /*15*/ + eSAP_RC_GO_KEY_HANDSHAKE_TO, /*16*/ + eSAP_RC_IE_MISMATCH, /*17*/ + eSAP_RC_INVALID_GRP_CHIPHER, /*18*/ + eSAP_RC_INVALID_PAIR_CHIPHER, /*19*/ + eSAP_RC_INVALID_AKMP, /*20*/ + eSAP_RC_UNSUPPORTED_RSN, /*21*/ + eSAP_RC_INVALID_RSN, /*22*/ + eSAP_RC_1X_AUTH_FAILED, /*23*/ + eSAP_RC_CHIPER_SUITE_REJECTED, /*24*/ +}eSapReasonCode; + +typedef enum { + eSAP_DOT11_MODE_abg = 0x0001, + eSAP_DOT11_MODE_11a = 0x0002, + eSAP_DOT11_MODE_11b = 0x0004, + eSAP_DOT11_MODE_11g = 0x0008, + eSAP_DOT11_MODE_11n = 0x0010, + eSAP_DOT11_MODE_11g_ONLY = 0x0080, + eSAP_DOT11_MODE_11n_ONLY = 0x0100, + eSAP_DOT11_MODE_11b_ONLY = 0x0400, +#ifdef WLAN_FEATURE_11AC + eSAP_DOT11_MODE_11ac = 0x1000, + eSAP_DOT11_MODE_11ac_ONLY = 0x2000 +#endif +} eSapPhyMode; + +typedef enum { + eSAP_ACCEPT_UNLESS_DENIED = 0, + eSAP_DENY_UNLESS_ACCEPTED = 1, + eSAP_SUPPORT_ACCEPT_AND_DENY = 2, /* this type is added to support both accept and deny lists at the same time */ + eSAP_ALLOW_ALL = 3, /*In this mode all MAC addresses are allowed to connect*/ +} eSapMacAddrACL; + +typedef enum { + eSAP_BLACK_LIST = 0, /* List of mac addresses NOT allowed to assoc */ + eSAP_WHITE_LIST = 1, /* List of mac addresses allowed to assoc */ +} eSapACLType; + +typedef enum { + ADD_STA_TO_ACL = 0, /* cmd to add STA to access control list */ + DELETE_STA_FROM_ACL = 1, /* cmd to delete STA from access control list */ +} eSapACLCmdType; + +typedef enum { + eSAP_START_BSS_EVENT = 0, /*Event sent when BSS is started*/ + eSAP_STOP_BSS_EVENT, /*Event sent when BSS is stopped*/ + eSAP_STA_ASSOC_IND, /* Indicate the association request to upper layers */ + eSAP_STA_ASSOC_EVENT, /*Event sent when we have successfully associated a station and + upper layer neeeds to allocate a context*/ + eSAP_STA_REASSOC_EVENT, /*Event sent when we have successfully reassociated a station and + upper layer neeeds to allocate a context*/ + eSAP_STA_DISASSOC_EVENT, /*Event sent when associated a station has disassociated as a result of various conditions */ + eSAP_STA_SET_KEY_EVENT, /*Event sent when user called WLANSAP_SetKeySta */ + eSAP_STA_DEL_KEY_EVENT, /*Event sent when user called WLANSAP_DelKeySta */ + eSAP_STA_MIC_FAILURE_EVENT, /*Event sent whenever there is MIC failure detected */ + eSAP_ASSOC_STA_CALLBACK_EVENT, /*Event sent when user called WLANSAP_GetAssocStations */ + eSAP_GET_WPSPBC_SESSION_EVENT, /* Event send when user call WLANSAP_getWpsSessionOverlap */ + eSAP_WPS_PBC_PROBE_REQ_EVENT, /* Event send on WPS PBC probe request is received */ + eSAP_INDICATE_MGMT_FRAME, + eSAP_REMAIN_CHAN_READY, + eSAP_SEND_ACTION_CNF, + eSAP_DISCONNECT_ALL_P2P_CLIENT, + eSAP_MAC_TRIG_STOP_BSS_EVENT, + eSAP_UNKNOWN_STA_JOIN, /* Event send when a STA in neither white list or black list tries to associate in softap mode */ + eSAP_MAX_ASSOC_EXCEEDED, /* Event send when a new STA is rejected association since softAP max assoc limit has reached */ + eSAP_CHANNEL_CHANGE_EVENT, + eSAP_DFS_CAC_START, + eSAP_DFS_CAC_END, + eSAP_DFS_RADAR_DETECT, + eSAP_DFS_NOL_GET, /* Event sent when user need to get the DFS NOL from CNSS */ + eSAP_DFS_NOL_SET, /* Event sent when user need to set the DFS NOL to CNSS */ + eSAP_DFS_NO_AVAILABLE_CHANNEL, /* No ch available after DFS RADAR detect */ +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + eSAP_ACS_SCAN_SUCCESS_EVENT, +#endif +} eSapHddEvent; + +typedef enum { + eSAP_OPEN_SYSTEM, + eSAP_SHARED_KEY, + eSAP_AUTO_SWITCH + } eSapAuthType; + +typedef enum { + eSAP_MAC_INITATED_DISASSOC = 0x10000, /*Disassociation was internally initated from CORE stack*/ + eSAP_USR_INITATED_DISASSOC /*Disassociation was internally initated from host by invoking WLANSAP_DisassocSta call*/ + } eSapDisassocReason; + +/*Handle boolean over here*/ +typedef enum { + eSAP_FALSE, + eSAP_TRUE, +}eSapBool; + +typedef enum { + eSAP_DFS_NOL_CLEAR, + eSAP_DFS_NOL_RANDOMIZE, +}eSapDfsNolType; + +/*--------------------------------------------------------------------------- +SAP PAL "status" and "reason" error code defines + ---------------------------------------------------------------------------*/ +typedef enum { + eSAP_STATUS_SUCCESS, /* Success. */ + eSAP_STATUS_FAILURE, /* General Failure. */ + eSAP_START_BSS_CHANNEL_NOT_SELECTED, /* Channel not selected during intial scan. */ + eSAP_ERROR_MAC_START_FAIL, /* Failed to start Infra BSS */ +}eSapStatus; + +/*--------------------------------------------------------------------------- +SAP PAL "status" and "reason" error code defines + ---------------------------------------------------------------------------*/ +typedef enum { + eSAP_WPSPBC_OVERLAP_IN120S, /* Overlap */ + eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S, /* no WPS probe request in 120 second */ + eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S, /* One WPS probe request in 120 second */ +}eWPSPBCOverlap; + +typedef enum { + eSAP_RF_SUBBAND_2_4_GHZ = 0, + eSAP_RF_SUBBAND_5_LOW_GHZ = 1, //Low & Mid U-NII + eSAP_RF_SUBBAND_5_MID_GHZ = 2, //ETSI + eSAP_RF_SUBBAND_5_HIGH_GHZ = 3, //High U-NII + eSAP_RF_SUBBAND_4_9_GHZ = 4, + eSAP_RF_SUBBAND_5_ALL_GHZ = 5, //All 5 GHZ, +}eSapOperatingBand; + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +typedef struct sap_StartBssCompleteEvent_s { + v_U8_t status; + v_U8_t operatingChannel; + v_U16_t staId; //self StaID + v_U8_t sessionId; /* SoftAP SME session ID */ +} tSap_StartBssCompleteEvent; + +typedef struct sap_StopBssCompleteEvent_s { + v_U8_t status; +} tSap_StopBssCompleteEvent; + +typedef struct sap_StationAssocIndication_s { + v_MACADDR_t staMac; + v_U8_t assoId; + v_U8_t staId; + v_U8_t status; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + tANI_BOOLEAN fWmmEnabled; + eCsrAuthType negotiatedAuthType; + eCsrEncryptionType negotiatedUCEncryptionType; + eCsrEncryptionType negotiatedMCEncryptionType; + tANI_BOOLEAN fAuthRequired; +} tSap_StationAssocIndication; + +typedef struct sap_StationAssocReassocCompleteEvent_s { + v_MACADDR_t staMac; + v_U8_t staId; + v_U8_t status; + v_U8_t ies[MAX_ASSOC_IND_IE_LEN]; + v_U16_t iesLen; + v_U32_t statusCode; + eSapAuthType SapAuthType; + v_BOOL_t wmmEnabled; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + tANI_U32 assocRespLength; + tANI_U8* assocRespPtr; + tANI_U8 timingMeasCap; + tSirSmeChanInfo chan_info; +} tSap_StationAssocReassocCompleteEvent; + +typedef struct sap_StationDisassocCompleteEvent_s { + v_MACADDR_t staMac; + v_U8_t staId; //STAID should not be used + v_U8_t status; + v_U32_t statusCode; + eSapDisassocReason reason; +} tSap_StationDisassocCompleteEvent; + +typedef struct sap_StationSetKeyCompleteEvent_s { + v_U8_t status; + v_MACADDR_t peerMacAddr; +} tSap_StationSetKeyCompleteEvent; + +/*struct corresponding to SAP_STA_DEL_KEY_EVENT */ +typedef struct sap_StationDeleteKeyCompleteEvent_s { + v_U8_t status; + v_U8_t keyId; /* Key index */ +} tSap_StationDeleteKeyCompleteEvent; + +/*struct corresponding to SAP_STA_MIC_FAILURE_EVENT */ +typedef struct sap_StationMICFailureEvent_s { + v_MACADDR_t srcMacAddr; //address used to compute MIC + v_MACADDR_t staMac; //taMacAddr transmitter address + v_MACADDR_t dstMacAddr; + eSapBool multicast; + v_U8_t IV1; // first byte of IV + v_U8_t keyId; // second byte of IV + v_U8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + +} tSap_StationMICFailureEvent; +/*Structure to return MAC address of associated stations */ +typedef struct sap_AssocMacAddr_s { + v_MACADDR_t staMac; /*MAC address of Station that is associated*/ + v_U8_t assocId; /*Association ID for the station that is associated*/ + v_U8_t staId; /*Station Id that is allocated to the station*/ + v_U8_t ShortGI40Mhz; + v_U8_t ShortGI20Mhz; + v_U8_t Support40Mhz; + v_U32_t requestedMCRate; + tSirSupportedRates supportedRates; +} tSap_AssocMacAddr, *tpSap_AssocMacAddr; + +/*struct corresponding to SAP_ASSOC_STA_CALLBACK_EVENT */ +typedef struct sap_AssocStaListEvent_s { + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + v_U8_t noOfAssocSta; /* Number of associated stations*/ + tpSap_AssocMacAddr pAssocStas; /*Pointer to pre allocated memory to obtain list of associated + stations passed in WLANSAP_GetAssocStations API*/ +} tSap_AssocStaListEvent; + +typedef struct sap_GetWPSPBCSessionEvent_s { + v_U8_t status; + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_MACADDR_t addr; + eWPSPBCOverlap wpsPBCOverlap; +} tSap_GetWPSPBCSessionEvent; + +typedef struct sap_WPSPBCProbeReqEvent_s { + v_U8_t status; + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + tSirWPSPBCProbeReq WPSPBCProbeReq; +} tSap_WPSPBCProbeReqEvent; + +typedef struct sap_ManagementFrameInfo_s { + tANI_U32 nFrameLength; + tANI_U8 frameType; + tANI_U32 rxChan; //Channel of where packet is received + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. +} tSap_ManagementFrameInfo; + +typedef struct sap_SendActionCnf_s { + eSapStatus actionSendSuccess; +} tSap_SendActionCnf; + +typedef struct sap_UnknownSTAJoinEvent_s { + v_MACADDR_t macaddr; +} tSap_UnknownSTAJoinEvent; + +typedef struct sap_MaxAssocExceededEvent_s { + v_MACADDR_t macaddr; +} tSap_MaxAssocExceededEvent; + +typedef struct sap_OperatingChannelChangeEvent_s { + tANI_U8 operatingChannel; +} tSap_OperatingChannelChangeEvent; + +typedef struct sap_DfsNolInfo_s { + v_U16_t sDfsList; /* size of pDfsList in byte */ + v_PVOID_t pDfsList; /* pointer to pDfsList buffer */ +} tSap_DfsNolInfo; + +/* + This struct will be filled in and passed to tpWLAN_SAPEventCB that is provided during WLANSAP_StartBss call + The event id corresponding to structure in the union is defined in comment next to the structure +*/ + +typedef struct sap_Event_s { + eSapHddEvent sapHddEventCode; + union { + tSap_StartBssCompleteEvent sapStartBssCompleteEvent; /*SAP_START_BSS_EVENT*/ + tSap_StopBssCompleteEvent sapStopBssCompleteEvent; /*SAP_STOP_BSS_EVENT*/ + tSap_StationAssocIndication sapAssocIndication; /*SAP_ASSOC_INDICATION */ + tSap_StationAssocReassocCompleteEvent sapStationAssocReassocCompleteEvent; /*SAP_STA_ASSOC_EVENT, SAP_STA_REASSOC_EVENT*/ + tSap_StationDisassocCompleteEvent sapStationDisassocCompleteEvent;/*SAP_STA_DISASSOC_EVENT*/ + tSap_StationSetKeyCompleteEvent sapStationSetKeyCompleteEvent;/*SAP_STA_SET_KEY_EVENT*/ + tSap_StationDeleteKeyCompleteEvent sapStationDeleteKeyCompleteEvent;/*SAP_STA_DEL_KEY_EVENT*/ + tSap_StationMICFailureEvent sapStationMICFailureEvent; /*SAP_STA_MIC_FAILURE_EVENT */ + tSap_AssocStaListEvent sapAssocStaListEvent; /*SAP_ASSOC_STA_CALLBACK_EVENT */ + tSap_GetWPSPBCSessionEvent sapGetWPSPBCSessionEvent; /*SAP_GET_WPSPBC_SESSION_EVENT */ + tSap_WPSPBCProbeReqEvent sapPBCProbeReqEvent; /*eSAP_WPS_PBC_PROBE_REQ_EVENT */ + tSap_ManagementFrameInfo sapManagementFrameInfo; /*eSAP_INDICATE_MGMT_FRAME*/ + tSap_SendActionCnf sapActionCnf; /* eSAP_SEND_ACTION_CNF */ + tSap_UnknownSTAJoinEvent sapUnknownSTAJoin; /* eSAP_UNKNOWN_STA_JOIN */ + tSap_MaxAssocExceededEvent sapMaxAssocExceeded; /* eSAP_MAX_ASSOC_EXCEEDED */ + tSap_OperatingChannelChangeEvent sapChannelChange; /* eSAP_CHANNEL_CHANGE_EVENT */ + tSap_DfsNolInfo sapDfsNolInfo; /*eSAP_DFS_NOL_XXX */ + } sapevt; +} tSap_Event, *tpSap_Event; + + +typedef __ani_attr_pre_packed struct sap_SSID { + v_U8_t length; + v_U8_t ssId[MAX_SSID_LEN]; +} __ani_attr_packed tSap_SSID_t; + +typedef __ani_attr_pre_packed struct sap_SSIDInfo { + tSap_SSID_t ssid; /*SSID of the AP*/ + v_U8_t ssidHidden; /*SSID shouldn't/should be broadcast in probe RSP and beacon*/ +} __ani_attr_packed tSap_SSIDInfo_t; + +typedef struct sap_Config { + tSap_SSIDInfo_t SSIDinfo; + eSapPhyMode SapHw_mode; /* Wireless Mode */ + eSapMacAddrACL SapMacaddr_acl; + v_MACADDR_t accept_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */ + v_BOOL_t ieee80211d; /*Specify if 11D is enabled or disabled*/ + v_BOOL_t protEnabled; /*Specify if protection is enabled or disabled*/ + v_BOOL_t obssProtEnabled; /*Specify if OBSS protection is enabled or disabled*/ + v_MACADDR_t deny_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */ + v_MACADDR_t self_macaddr; //self macaddress or BSSID + + v_U8_t channel; /* Operation channel */ + v_U8_t max_num_sta; /* maximum number of STAs in station table */ + v_U8_t dtim_period; /* dtim interval */ + v_U8_t num_accept_mac; + v_U8_t num_deny_mac; + /* Max ie length 255 * 2(WPA+RSN) + 2 bytes(vendor specific ID) * 2 */ + v_U8_t RSNWPAReqIE[(SIR_MAC_MAX_IE_LENGTH * 2) + 4]; + v_U8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //it is ignored if [0] is 0. + v_U8_t RSNAuthType; + v_U8_t RSNEncryptType; + v_U8_t mcRSNEncryptType; + eSapAuthType authType; + v_BOOL_t privacy; + v_BOOL_t UapsdEnable; + v_BOOL_t fwdWPSPBCProbeReq; + v_U8_t wps_state; // 0 - disabled, 1 - not configured , 2 - configured + + v_U16_t ht_capab; + v_U16_t RSNWPAReqIELength; //The byte count in the pWPAReqIE + + v_U32_t beacon_int; /* Beacon Interval */ + v_U32_t ap_table_max_size; + v_U32_t ap_table_expiration_time; + v_U32_t ht_op_mode_fixed; + tVOS_CON_MODE persona; /*Tells us which persona it is GO or AP for now*/ + v_U8_t disableDFSChSwitch; + eCsrBand scanBandPreference; + v_BOOL_t enOverLapCh; + char acsAllowedChnls[MAX_CHANNEL_LIST_LEN]; + v_U16_t acsBandSwitchThreshold; + v_BOOL_t apAutoChannelSelection; + v_U8_t apStartChannelNum; + v_U8_t apEndChannelNum; + v_U8_t apOperatingBand; + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + v_U8_t skip_acs_scan_status; + v_U8_t skip_acs_scan_range1_stch; + v_U8_t skip_acs_scan_range1_endch; + v_U8_t skip_acs_scan_range2_stch; + v_U8_t skip_acs_scan_range2_endch; +#endif + +#ifdef WLAN_FEATURE_11W + v_BOOL_t mfpRequired; + v_BOOL_t mfpCapable; +#endif +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + v_U8_t cc_switch_mode; +#endif + + v_U16_t probeRespIEsBufferLen; + v_PVOID_t pProbeRespIEsBuffer; /* buffer for addn ies comes from hostapd*/ + + v_U16_t assocRespIEsLen; + v_PVOID_t pAssocRespIEsBuffer; /* buffer for addn ies comes from hostapd*/ + + v_U16_t probeRespBcnIEsLen; + v_PVOID_t pProbeRespBcnIEsBuffer; /* buffer for addn ies comes from hostapd*/ + uint8_t sap_dot11mc; /* Specify if 11MC is enabled or disabled*/ + +} tsap_Config_t; + +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE +typedef enum { + eSAP_DO_NEW_ACS_SCAN, + eSAP_DO_PAR_ACS_SCAN, + eSAP_SKIP_ACS_SCAN +} tSap_skip_acs_scan; +#endif + +typedef enum { + eSAP_WPS_PROBE_RSP_IE, + eSAP_WPS_BEACON_IE, + eSAP_WPS_ASSOC_RSP_IE +} eSapWPSIE_CODE; + +typedef struct sSapName { + v_U8_t num_name; + v_U8_t name[MAX_NAME_SIZE]; +} tSapName; + +typedef struct sSapText { + v_U8_t num_text; + v_U8_t text[MAX_TEXT_SIZE]; +} tSapText; + +typedef enum +{ + eSAP_DFS_DO_NOT_SKIP_CAC, + eSAP_DFS_SKIP_CAC +} eSapDfsCACState_t; + +typedef enum +{ + eSAP_DFS_CHANNEL_USABLE, + eSAP_DFS_CHANNEL_AVAILABLE, + eSAP_DFS_CHANNEL_UNAVAILABLE +} eSapDfsChanStatus_t; + +typedef struct sSapDfsNolInfo +{ + v_U8_t dfs_channel_number; + eSapDfsChanStatus_t radar_status_flag; + v_U64_t radar_found_timestamp; +} tSapDfsNolInfo; + +typedef struct sSapDfsInfo +{ + vos_timer_t sap_dfs_cac_timer; + v_U8_t sap_radar_found_status; + /* + * New channel to move to when a Radar is + * detected on current Channel + */ + v_U8_t target_channel; + v_U8_t last_radar_found_channel; + v_U8_t ignore_cac; + eSapDfsCACState_t cac_state; + v_U8_t user_provided_target_channel; + + /* Requests for Channel Switch Announcement IE + * generation and transmission + */ + v_U8_t csaIERequired; + v_U8_t numCurrentRegDomainDfsChannels; + tSapDfsNolInfo sapDfsChannelNolList[NUM_5GHZ_CHANNELS]; + v_U8_t is_dfs_cac_timer_running; + /* + * New channel width and new channel bonding mode + * will only be updated via channel fallback mechanism + */ + tANI_U8 orig_cbMode; + tANI_U8 orig_chanWidth; + tANI_U8 new_chanWidth; + tANI_U8 new_cbMode; + + /* + * INI param to enable/disable SAP W53 + * channel operation. + */ + v_U8_t is_dfs_w53_disabled; + + /* + * sap_operating_channel_location holds SAP indoor, + * outdoor location information. Currently, if this + * param is set this Indoor/outdoor channel interop + * restriction will only be implemented for JAPAN + * regulatory domain. + * + * 0 - Indicates that location unknown + * (or) SAP Indoor/outdoor interop is allowed + * + * 1 - Indicates device is operating on Indoor channels + * and SAP cannot pick next random channel from outdoor + * list of channels when a radar is found on current operating + * DFS channel. + * + * 2 - Indicates device is operating on Outdoor Channels + * and SAP cannot pick next random channel from indoor + * list of channels when a radar is found on current + * operating DFS channel. + */ + v_U8_t sap_operating_chan_preferred_location; + + /* + * Flag to indicate if DFS test mode is enabled and + * channel switch is disabled. + */ + v_U8_t disable_dfs_ch_switch; +} tSapDfsInfo; + +typedef struct tagSapCtxList +{ + v_U8_t sessionID; + v_VOID_t* pSapContext; + tVOS_CON_MODE sapPersona; +} tSapCtxList, tpSapCtxList; + +typedef struct tagSapStruct +{ + //Information Required for SAP DFS Master mode + tSapDfsInfo SapDfsInfo; + tSapCtxList sapCtxList[SAP_MAX_NUM_SESSION]; +} tSapStruct, *tpSapStruct; + +#define WPS_PROBRSP_VER_PRESENT 0x00000001 +#define WPS_PROBRSP_STATE_PRESENT 0x00000002 +#define WPS_PROBRSP_APSETUPLOCK_PRESENT 0x00000004 +#define WPS_PROBRSP_SELECTEDREGISTRA_PRESENT 0x00000008 +#define WPS_PROBRSP_DEVICEPASSWORDID_PRESENT 0x00000010 +#define WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define WPS_PROBRSP_RESPONSETYPE_PRESENT 0x00000040 +#define WPS_PROBRSP_UUIDE_PRESENT 0x00000080 +#define WPS_PROBRSP_MANUFACTURE_PRESENT 0x00000100 +#define WPS_PROBRSP_MODELNAME_PRESENT 0x00000200 +#define WPS_PROBRSP_MODELNUMBER_PRESENT 0x00000400 +#define WPS_PROBRSP_SERIALNUMBER_PRESENT 0x00000800 +#define WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT 0x00001000 +#define WPS_PROBRSP_DEVICENAME_PRESENT 0x00002000 +#define WPS_PROBRSP_CONFIGMETHODS_PRESENT 0x00004000 +#define WPS_PROBRSP_RF_BANDS_PRESENT 0x00008000 + +typedef struct sap_WPSProbeRspIE_s { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t ResponseType; // Response type + v_U8_t UUID_E[16]; // Unique identifier of the AP. + tSapName Manufacture; + tSapText ModelName; + tSapText ModelNumber; + tSapText SerialNumber; + v_U32_t PrimaryDeviceCategory ; // Device Category ID: 1Computer, 2Input Device, ... + v_U8_t PrimaryDeviceOUI[4] ; // Vendor specific OUI for Device Sub Category + v_U32_t DeviceSubCategory ; // Device Sub Category ID: 1-PC, 2-Server if Device Category ID is computer + tSapText DeviceName; + v_U16_t ConfigMethod; // Configuaration method + v_U8_t RFBand; // RF bands available on the AP +} tSap_WPSProbeRspIE; + +#define WPS_BEACON_VER_PRESENT 0x00000001 +#define WPS_BEACON_STATE_PRESENT 0x00000002 +#define WPS_BEACON_APSETUPLOCK_PRESENT 0x00000004 +#define WPS_BEACON_SELECTEDREGISTRA_PRESENT 0x00000008 +#define WPS_BEACON_DEVICEPASSWORDID_PRESENT 0x00000010 +#define WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define WPS_BEACON_UUIDE_PRESENT 0x00000080 +#define WPS_BEACON_RF_BANDS_PRESENT 0x00000100 + +typedef struct sap_WPSBeaconIE_s { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_U8_t RFBand; // RF bands available on the AP +} tSap_WPSBeaconIE; + +#define WPS_ASSOCRSP_VER_PRESENT 0x00000001 +#define WPS_ASSOCRSP_RESPONSETYPE_PRESENT 0x00000002 + +typedef struct sap_WPSAssocRspIE_s { + v_U32_t FieldPresent; + v_U32_t Version; + v_U8_t ResposeType; +} tSap_WPSAssocRspIE; + +typedef struct sap_WPSIE_s { + eSapWPSIE_CODE sapWPSIECode; + union { + tSap_WPSProbeRspIE sapWPSProbeRspIE; /*WPS Set Probe Respose IE*/ + tSap_WPSBeaconIE sapWPSBeaconIE; /*WPS Set Beacon IE*/ + tSap_WPSAssocRspIE sapWPSAssocRspIE; /*WPS Set Assoc Response IE*/ + } sapwpsie; +} tSap_WPSIE, *tpSap_WPSIE; + +#ifdef WLANTL_DEBUG +#define MAX_RATE_INDEX 136 +#define MAX_NUM_RSSI 100 +#define MAX_RSSI_INTERVAL 5 +#endif + +typedef struct sap_SoftapStats_s { + v_U32_t txUCFcnt; + v_U32_t txMCFcnt; + v_U32_t txBCFcnt; + v_U32_t txUCBcnt; + v_U32_t txMCBcnt; + v_U32_t txBCBcnt; + v_U32_t rxUCFcnt; + v_U32_t rxMCFcnt; + v_U32_t rxBCFcnt; + v_U32_t rxUCBcnt; + v_U32_t rxMCBcnt; + v_U32_t rxBCBcnt; + v_U32_t rxBcnt; + v_U32_t rxBcntCRCok; + v_U32_t rxRate; +#ifdef WLANTL_DEBUG + v_U32_t pktCounterRateIdx[MAX_RATE_INDEX]; + v_U32_t pktCounterRssi[MAX_NUM_RSSI]; +#endif +} tSap_SoftapStats, *tpSap_SoftapStats; + +int sapSetPreferredChannel +( +#ifdef WLAN_FEATURE_MBSSID + v_PVOID_t sapContext, +#endif + tANI_U8* ptr +); + +/* Channel/Frequency table */ +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +#ifdef FEATURE_WLAN_CH_AVOID +/* Store channel safety information */ +typedef struct +{ + v_U16_t channelNumber; + v_BOOL_t isSafe; +} sapSafeChannelType; +#endif //FEATURE_WLAN_CH_AVOID + +#ifdef WLAN_FEATURE_MBSSID +void sapCleanupChannelList(v_PVOID_t sapContext); +#else +void sapCleanupChannelList(void); +#endif + +void sapCleanupAllChannelList(void); + +/*========================================================================== + FUNCTION WLANSAP_Set_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to set WPS IE. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pWPSIE: tSap_WPSIE structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_WpsIe +( + v_PVOID_t pvosGCtx, + tSap_WPSIE *pWPSIe +); + +/*========================================================================== + FUNCTION WLANSAP_Update_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to start WPS session. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Update_WpsIe +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Stop_Wps + + DESCRIPTION + This api function provides for Ap App/HDD to stop WPS session. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop_Wps +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Get_WPS_State + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS state. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + OUT +pbWPSState: Pointer to variable to indicate if it is in WPS Registration state + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_WPS_State +( + v_PVOID_t pvosGCtx, + v_BOOL_t * pbWPSState +); + +/*---------------------------------------------------------------------------- + * Opaque SAP handle Type Declaration + * -------------------------------------------------------------------------*/ + +typedef v_PVOID_t tSapHandle, *ptSapHandle; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION WLANSAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). SAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +#ifdef WLAN_FEATURE_MBSSID +v_PVOID_t +#else +VOS_STATUS +#endif +WLANSAP_Open +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in SAP, before close. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. SAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Close +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION (*tpWLAN_SAPEventCB) + + DESCRIPTION + Implements the callback for ALL asynchronous events. + Including Events resulting from: + * Start BSS + * Stop BSS,... + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSapEvent: pointer to the union of "Sap Event" structures. This now encodes ALL event types. + Including Command Complete and Command Status + pUsrContext : pUsrContext parameter that was passed to sapStartBss + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pSapEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +typedef VOS_STATUS (*tpWLAN_SAPEventCB)( tpSap_Event pSapEvent, v_PVOID_t pUsrContext); + + + +/*========================================================================== + FUNCTION WLANSAP_getState + + DESCRIPTION + This api returns the current SAP state to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + + RETURN VALUE + Returns the SAP FSM state. +============================================================================*/ + +v_U8_t WLANSAP_getState +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_StartBss + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_HDD_PHYSICAL_LINK_CREATE for +starting AP BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pConfig: Pointer to configuration structure passed down from HDD(HostApd for Android) +hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD about SAP results +usrDataForCallback: Parameter that will be passed back in all the SAP callback events. + + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StartBss +( + v_PVOID_t pvosGCtx, + tpWLAN_SAPEventCB pSapEventCallback, + tsap_Config_t *pConfig, + v_PVOID_t pUsrContext +); + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/*========================================================================== + FUNCTION WLANSAP_CheckCCIntf + + DESCRIPTION Restart SAP if Concurrent Channel interfering + + DEPENDENCIES NA. + + PARAMETERS + IN + Ctx: Pointer to vos Context or Sap Context based on MBSSID + + RETURN VALUE Interference channel value + + SIDE EFFECTS +============================================================================*/ +v_U16_t WLANSAP_CheckCCIntf(v_PVOID_t Ctx); +#endif +/*========================================================================== + FUNCTION WLANSAP_SetMacACL + + DESCRIPTION + This api function provides SAP to set mac list entry in accept list as well + as deny list + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pConfig: Pointer to configuration structure passed down from + HDD(HostApd for Android) + + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMacACL +( + v_PVOID_t pvosGCtx, + tsap_Config_t *pConfig +); + +/*========================================================================== + FUNCTION WLANSAP_Stop + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_HDD_PHYSICAL_LINK_DISCONNECT for +stopping BSS + + DEPENDENCIES + NA. + + PARAMETERS W + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StopBss +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_DisassocSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated disassociation of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : Mac address of the station to disassociate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DisassocSta +( + v_PVOID_t pvosGCtx, + v_U8_t *pPeerStaMac +); + +/*========================================================================== + FUNCTION WLANSAP_DeauthSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated deauthentication of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : Mac address of the station to deauthenticate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DeauthSta +( + v_PVOID_t pvosGCtx, + v_U8_t *pPeerStaMac +); + +/*========================================================================== + FUNCTION WLANSAP_SetChannelChangeWithCsa + + DESCRIPTION + This api function does a channel change to the target channel specified + through an iwpriv. CSA IE is included in the beacons before doing a + channel change. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + targetChannel : New target channel to change to. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelChangeWithCsa(v_PVOID_t pvosGCtx, v_U32_t targetChannel); + +/*========================================================================== + FUNCTION WLANSAP_SetChannelRange + + DESCRIPTION + This api function sets the range of channels for SoftAP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + startChannel : start channel + endChannel : End channel + operatingBand : Operating band (2.4GHz/5GHz) + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelRange(tHalHandle hHal,v_U8_t startChannel, v_U8_t endChannel, + eSapOperatingBand operatingBand); + +/*========================================================================== + FUNCTION WLANSAP_SetKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetKeySta +( + v_PVOID_t pvosGCtx, + tCsrRoamSetKey *pSetKeyInfo +); + +/*========================================================================== + FUNCTION WLANSAP_DelKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DelKeySta +( + v_PVOID_t pvosGCtx, + tCsrRoamRemoveKey *pDelKeyInfo +); + + +/*========================================================================== + FUNCTION WLANSAP_GetAssocStations + + DESCRIPTION + This api function is used to probe the list of associated stations from various modules of CORE stack + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +mod: Module from whom list of associtated stations is supposed to be probed. If an invalid module is passed +then by default VOS_MODULE_ID_PE will be probed + IN/OUT +pNoOfAssocStas:- Number of associated stations that are known to the module specified in mod parameter +pAssocStas: Pointer to list of associated stations that are known to the module specified in mod parameter +NOTE:- The memory for this list will be allocated by the caller of this API + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetAssocStations +( + v_PVOID_t pvosGCtx, + VOS_MODULE_ID module, + tpSap_AssocMacAddr pAssocStas +); +/*========================================================================== + FUNCTION WLANSAP_RemoveWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to remove an entry from session session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pRemoveMac: pointer to v_MACADDR_t for session MAC address that needs to be removed from wps session + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Session is not dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_RemoveWpsSessionOverlap + +( + v_PVOID_t pvosGCtx, + v_MACADDR_t pRemoveMac +); + +/*========================================================================== + FUNCTION WLANSAP_getWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSessionMac: pointer to v_MACADDR_t for session MAC address +uuide: Pointer to 16 bytes array for session UUID_E + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Overlap is dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_getWpsSessionOverlap +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_SetCounterMeasure + + DESCRIPTION + This api function is used to disassociate all the stations and prevent + association for any other station.Whenever Authenticator receives 2 mic failures + within 60 seconds, Authenticator will enable counter measure at SAP Layer. + Authenticator will start the 60 seconds timer. Core stack will not allow any + STA to associate till HDD disables counter meassure. Core stack shall kick out all the + STA which are currently associated and DIASSOC Event will be propogated to HDD for + each STA to clean up the HDD STA table.Once the 60 seconds timer expires, Authenticator + will disable the counter meassure at core stack. Now core stack can allow STAs to associate. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +bEnable: If TRUE than all stations will be disassociated and no more will be allowed to associate. If FALSE than CORE +will come out of this state. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetCounterMeasure +( + v_PVOID_t pvosGCtx, + v_BOOL_t bEnable +); + +/*========================================================================== + FUNCTION WLANSap_getstationIE_information + + DESCRIPTION + This api function provides for Ap App/HDD to retrive the WPA and RSNIE of a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pLen : length of WPARSN elment IE where it would be copied + pBuf : buf to copy the WPARSNIe + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSap_getstationIE_information +( + v_PVOID_t pvosGCtx, + v_U32_t *pLen, + v_U8_t *pBuf +); + +/*========================================================================== + FUNCTION WLANSAP_ClearACL + + DESCRIPTION + This api function removes all the entries in both accept and deny lists. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ClearACL +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_GetACLAcceptList + + DESCRIPTION + This api function to get ACL accept list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pAcceptList: ACL Accept list entries + nAcceptList: Number of entries in ACL Accept list + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetACLAcceptList +( + v_PVOID_t pvosGCtx, + v_MACADDR_t *pAcceptList, + v_U8_t *nAcceptList +); + +/*========================================================================== + FUNCTION WLANSAP_GetACLDenyList + + DESCRIPTION + This api function to get ACL Deny list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pAcceptList: ACL Deny list entries + nAcceptList: Number of entries in ACL Deny list + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetACLDenyList +( + v_PVOID_t pCtx, + v_MACADDR_t *pDenyList, + v_U8_t *nDenyList +); + +/*========================================================================== + FUNCTION WLANSAP_SetMode + + DESCRIPTION + This api is used to set mode for ACL + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMode +( + v_PVOID_t pvosGCtx, + v_U32_t mode +); + +/*========================================================================== + FUNCTION WLANSAP_GetACLMode + + DESCRIPTION + This api is used to get mode for ACL + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + mode: Current Mode of the ACL + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetACLMode +( + v_PVOID_t pvosGCtx, + eSapMacAddrACL *mode +); + +/*========================================================================== + FUNCTION WLANSAP_ModifyACL + + DESCRIPTION + This api function provides for Ap App/HDD to add/remove mac addresses from black/white lists (ACLs). + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : MAC address to be added or removed + listType : add/remove to be done on black or white list + cmd : Are we doing to add or delete a mac addr from an ACL. + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ModifyACL +( + v_PVOID_t pvosGCtx, + v_U8_t *pPeerStaMac, + eSapACLType listType, + eSapACLCmdType cmd +); + +/*========================================================================== + FUNCTION WLANSAP_Set_WPARSNIes + + DESCRIPTION + This api function provides for Ap App/HDD to set AP WPA and RSN IE in its beacon and probe response. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pWPARSNIEs: buffer to the WPA/RSN IEs + WPARSNIEsLen: length of WPA/RSN IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_WPARSNIes +( + v_PVOID_t pvosGCtx, + v_U8_t *pWPARSNIEs, + v_U32_t WPARSNIEsLen +); + +/*========================================================================== + FUNCTION WLANSAP_GetStatistics + + DESCRIPTION + This api function provides for Ap App/HDD to get TL statistics for all stations of Soft AP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + bReset: If set TL statistics will be cleared after reading + OUT + statBuf: Buffer to get the statistics + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_GetStatistics +( + v_PVOID_t pvosGCtx, + tSap_SoftapStats *statBuf, + v_BOOL_t bReset +); + +/*========================================================================== + + FUNCTION WLANSAP_SendAction + + DESCRIPTION + This api function provides to send action frame sent by upper layer. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pBuf: Pointer of the action frame to be transmitted + len: Length of the action frame + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_SendAction +( + v_PVOID_t pvosGCtx, + const tANI_U8 *pBuf, + tANI_U32 len, + tANI_U16 wait +); + +/*========================================================================== + + FUNCTION WLANSAP_RemainOnChannel + + DESCRIPTION + This api function provides to set Remain On channel on specified channel + for specified duration. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + channel: Channel on which driver has to listen + duration: Duration for which driver has to listen on specified channel + callback: Callback function to be called once Listen is done. + pContext: Context needs to be called in callback function. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RemainOnChannel +( + v_PVOID_t pvosGCtx, + tANI_U8 channel, + tANI_U32 duration, + remainOnChanCallback callback, + void *pContext +); + +/*========================================================================== + + FUNCTION WLANSAP_CancelRemainOnChannel + + DESCRIPTION + This api cancel previous remain on channel request. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_CancelRemainOnChannel +( + v_PVOID_t pvosGCtx +); + + +/*========================================================================== + + FUNCTION WLANSAP_RegisterMgmtFrame + + DESCRIPTION + HDD use this API to register specified type of frame with CORE stack. + On receiving such kind of frame CORE stack should pass this frame to HDD + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RegisterMgmtFrame +( + v_PVOID_t pvosGCtx, + tANI_U16 frameType, + tANI_U8* matchData, + tANI_U16 matchLen +); + +/*========================================================================== + + FUNCTION WLANSAP_DeRegisterMgmtFrame + + DESCRIPTION + This API is used to deregister previously registered frame. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be De-registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_DeRegisterMgmtFrame +( + v_PVOID_t pvosGCtx, + tANI_U16 frameType, + tANI_U8* matchData, + tANI_U16 matchLen +); + +/*========================================================================== + + FUNCTION WLANSAP_ChannelChangeRequest + DESCRIPTION + This API is used to send an Indication to SME/PE to change the + current operating channel to a different target channel. + + The Channel change will be issued by SAP under the following + scenarios. + 1. A radar indication is received during SAP CAC WAIT STATE and + channel change is required. + 2. A radar indication is received during SAP STARTED STATE and + channel change is required. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pvosGCtx: Pointer to vos global context structure + TargetChannel: New target channel for channel change. + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_ChannelChangeRequest(v_PVOID_t pvosGCtx, tANI_U8 tArgetChannel); + +/*========================================================================== + + FUNCTION WLANSAP_StartBeaconReq + DESCRIPTION + This API is used to send an Indication to SME/PE to start + beaconing on the current operating channel. + + Brief:When SAP is started on DFS channel and when ADD BSS RESP is received + LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When + CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon + request to LIM. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pvosGCtx: Pointer to vos global context structure + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx); + +/*========================================================================== + FUNCTION WLANSAP_DfsSendCSAIeRequest + + DESCRIPTION + This API is used to send channel switch announcement request to PE + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DfsSendCSAIeRequest(v_PVOID_t pSapCtx); + +/*========================================================================== + FUNCTION WLANSAP_Get_Dfs_Ignore_CAC + + DESCRIPTION + This API is used to get ignore_cac flag. + + DEPENDENCIES + NA. + + PARAMETERS + IN + pvosGCtx: Pointer to vos global context structure + + PARAMETERS + OUT + pIgnore_cac: pointer to variable + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_Get_Dfs_Ignore_CAC(tHalHandle hHal, v_U8_t *pIgnore_cac); + + +/*========================================================================== + FUNCTION WLANSAP_Set_Dfs_Ignore_CAC + + DESCRIPTION + This API is used to set ignore_cac flag, used for ignoring the CAC operation for DFS channel. + If the flag set to 1 or TRUE then it will avoid CAC. + + DEPENDENCIES + NA. + + PARAMETERS + IN + pvosGCtx: Pointer to vos global context structure + + PARAMETERS + IN + ignore_cac: value to be set + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_Set_Dfs_Ignore_CAC(tHalHandle hHal, v_U8_t ignore_cac); + +/*========================================================================== + FUNCTION WLANSAP_set_Dfs_Restrict_JapanW53 + + DESCRIPTION + This API is used to enable or disable Japan W53 Band + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + disable_Dfs_JapanW3 :Indicates if Japan W53 is disabled when set to 1 + Indicates if Japan W53 is enabled when set to 0 + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_set_Dfs_Restrict_JapanW53(tHalHandle hHal, v_U8_t disable_Dfs_JapanW3); + +/*========================================================================== + FUNCTION WLANSAP_set_Dfs_Preferred_Channel_location + + DESCRIPTION + This API is used to set sap preferred channels location + to resetrict the DFS random channel selection algorithm + either Indoor/Outdoor channels only. + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + dfs_Preferred_Channels_location : + 0 - Indicates No preferred channel location restrictions + 1 - Indicates SAP Indoor Channels operation only. + 2 - Indicates SAP Outdoor Channels operation only. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_set_Dfs_Preferred_Channel_location(tHalHandle hHal, + v_U8_t dfs_Preferred_Channels_location); + +/*========================================================================== + FUNCTION WLANSAP_Set_Dfs_Target_Chnl + + DESCRIPTION + This API is used to set next target chnl as provided channel. + you can provide any valid channel to this API. + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal: Pointer to HAL + + PARAMETERS + IN + target_channel: target channel number + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_Set_Dfs_Target_Chnl(tHalHandle hHal, + v_U8_t target_channel); + + + +/*========================================================================== + FUNCTION WLANSAP_UpdateSapConfigAddIE + + DESCRIPTION + This API is used to set sap config parameter. + + DEPENDENCIES + NA. + + PARAMETERS + IN OUT + pConfig: Pointer to sap config + + PARAMETERS + IN + additionIEBuffer - buffer containing addition IE from hostapd + + PARAMETERS + IN + additionIELength - length of buffer + + PARAMETERS + IN + updateType - Type of buffer + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, + const tANI_U8 *pAdditionIEBuffer, + tANI_U16 additionIELength, + eUpdateIEsType updateType); + +/*========================================================================== + FUNCTION WLANSAP_ResetSapConfigAddIE + + DESCRIPTION + This API is used to reset and clear the buffer in sap config. + + DEPENDENCIES + NA. + + PARAMETERS + IN OUT + pConfig: Pointer to sap config + PARAMETERS + IN + updateType: type buffer + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig, + eUpdateIEsType updateType); + + + +/*========================================================================== +FUNCTION sapConvertSapPhyModeToCsrPhyMode + +DESCRIPTION Function to implement selection of CSR PhyMode using SAP PhyMode + +DEPENDENCIES PARAMETERS + +IN sapPhyMode : SAP Phy Module + +RETURN VALUE If SUCCESS or FAILURE + +SIDE EFFECTS +============================================================================*/ +eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode ); + +/*========================================================================== +FUNCTION WLANSAP_extend_to_acs_range + +DESCRIPTION Function extends give channel range to consider ACS chan bonding + +DEPENDENCIES PARAMETERS + +IN /OUT +*startChannelNum : ACS extend start ch +*endChannelNum : ACS extended End ch +*bandStartChannel: Band start ch +*bandEndChannel : Band end ch + +RETURN VALUE NONE + +SIDE EFFECTS +============================================================================*/ +v_VOID_t WLANSAP_extend_to_acs_range(v_U8_t operatingBand, + v_U8_t *startChannelNum, + v_U8_t *endChannelNum, + v_U8_t *bandStartChannel, + v_U8_t *bandEndChannel); + +/*========================================================================== + FUNCTION WLANSAP_Get_DfsNol + + DESCRIPTION + This API is used to dump the dfs nol + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_DfsNol(v_PVOID_t pSapCtx); + +/*========================================================================== + FUNCTION WLANSAP_Set_DfsNol + + DESCRIPTION + This API is used to set the dfs nol + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + conf: set type + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_DfsNol(v_PVOID_t pSapCtx, eSapDfsNolType conf); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANSAP_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapApiLinkCntl.c b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapApiLinkCntl.c new file mode 100644 index 0000000000000..d944cf82dd2a8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapApiLinkCntl.c @@ -0,0 +1,961 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p A p i L i n k C n t l . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + Link Control functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/c/Dropbox/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_SAP_PAL/CORE/SAP/src/sapApiLinkCntl.c,v 1.7 2008/12/18 19:44:11 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_trace.h" +// Pick up the CSR callback definition +#include "csrApi.h" +#include "sme_Api.h" +// SAP Internal API header file +#include "sapInternal.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define SAP_DEBUG + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION WLANSAP_ScanCallback() + + DESCRIPTION + Callback for Scan (scan results) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle : tHalHandle passed in with the scan request + *pContext : The second context pass in for the caller (sapContext) + scanID : scanID got after the scan + status : Status of scan -success, failure or abort + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +eHalStatus +WLANSAP_ScanCallback +( + tHalHandle halHandle, + void *pContext, /* Opaque SAP handle */ + v_U8_t sessionId, + v_U32_t scanID, + eCsrScanStatus scanStatus +) +{ + tScanResultHandle pResult = NULL; + eHalStatus scanGetResultStatus = eHAL_STATUS_FAILURE; + ptSapContext psapContext = (ptSapContext)pContext; + tWLAN_SAPEvent sapEvent; /* State machine event */ + v_U8_t operChannel = 0; + VOS_STATUS sapstatus; +#ifdef SOFTAP_CHANNEL_RANGE + v_U32_t operatingBand; + v_U32_t event; +#endif + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on scanStatus = %d", __func__, scanStatus); + + switch (scanStatus) + { + case eCSR_SCAN_SUCCESS: + // sapScanCompleteCallback with eCSR_SCAN_SUCCESS + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR scanStatus = %s (%d)", __func__, "eCSR_SCAN_SUCCESS", scanStatus); + + // Get scan results, Run channel selection algorithm, select channel and keep in pSapContext->Channel + scanGetResultStatus = sme_ScanGetResult(halHandle, psapContext->sessionId, NULL, &pResult); + + if ((scanGetResultStatus != eHAL_STATUS_SUCCESS)&& (scanGetResultStatus != eHAL_STATUS_E_NULL_VALUE)) + { + // No scan results + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, Get scan result failed! ret = %d", + __func__, scanGetResultStatus); + break; + } +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + if (scanID != 0) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Sending ACS Scan skip event", __func__); + sapSignalHDDevent(psapContext, NULL, + eSAP_ACS_SCAN_SUCCESS_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + } else + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: ACS scan id: %d (skipped ACS SCAN)", __func__, scanID); +#endif + operChannel = sapSelectChannel(halHandle, psapContext, pResult); + + sme_ScanResultPurge(halHandle, pResult); + event = eSAP_MAC_SCAN_COMPLETE; + break; + + default: + event = eSAP_CHANNEL_SELECTION_FAILED; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR scanStatus = %s (%d)", __func__, "eCSR_SCAN_ABORT/FAILURE", scanStatus); + } + + if (operChannel == SAP_CHANNEL_NOT_SELECTED) +#ifdef SOFTAP_CHANNEL_RANGE + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: No suitable channel selected", + __func__); + + if ( eCSR_BAND_ALL == psapContext->scanBandPreference || + psapContext->allBandScanned == eSAP_TRUE) + { + if(psapContext->channelList != NULL) + { + psapContext->channel = psapContext->channelList[0]; + } + else + { + /* if the channel list is empty then there is no valid channel in + the selected sub-band so select default channel in the + BAND(2.4GHz/5GHZ) */ + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + if(eSAP_RF_SUBBAND_2_4_GHZ == operatingBand ) + psapContext->channel = SAP_DEFAULT_CHANNEL; + else + psapContext->channel = SAP_DEFAULT_5GHZ_CHANNEL; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: Has scan band preference", + __func__); + if (eCSR_BAND_24 == psapContext->currentPreferredBand) + psapContext->currentPreferredBand = eCSR_BAND_5G; + else + psapContext->currentPreferredBand = eCSR_BAND_24; + + psapContext->allBandScanned = eSAP_TRUE; + //go back to DISCONNECT state, scan next band + psapContext->sapsMachine = eSAP_DISCONNECTED; + event = eSAP_CHANNEL_SELECTION_FAILED; + } + } +#else + psapContext->channel = SAP_DEFAULT_CHANNEL; +#endif + else + { + psapContext->channel = operChannel; + } + + sme_SelectCBMode(halHandle, + sapConvertSapPhyModeToCsrPhyMode(psapContext->csrRoamProfile.phyMode), + psapContext->channel); +#ifdef SOFTAP_CHANNEL_RANGE + if(psapContext->channelList != NULL) + { + /* Always free up the memory for channel selection whatever + * the result */ + vos_mem_free(psapContext->channelList); + psapContext->channelList = NULL; + } +#endif + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Channel selected = %d", __func__, psapContext->channel); + + /* Fill in the event structure */ + sapEvent.event = event; + sapEvent.params = 0; // pCsrRoamInfo; + sapEvent.u1 = scanStatus; // roamstatus + sapEvent.u2 = 0; // roamResult + + /* Handle event */ + sapstatus = sapFsm(psapContext, &sapEvent); + + return sapstatus; +}// WLANSAP_ScanCallback + +/*========================================================================== + FUNCTION WLANSAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext : pContext passed in with the roam request + pCsrRoamInfo : Pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: For detail valid members. It may be NULL + roamId : To identify the callback related roam request. 0 means unsolicited + roamStatus : Flag indicating the status of the callback + roamResult : Result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +eHalStatus +WLANSAP_RoamCallback +( + void *pContext, /* Opaque SAP handle */ + tCsrRoamInfo *pCsrRoamInfo, + v_U32_t roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +) +{ + /* sapContext value */ + ptSapContext sapContext = (ptSapContext) pContext; + tWLAN_SAPEvent sapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac = NULL; + tANI_U8 dfs_beacon_start_req = 0; + + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + halStatus = eHAL_STATUS_FAILED_ALLOC; + return halStatus; + } + else + { + pMac = PMAC_STRUCT( hHal ); + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamStatus = %d\n", __func__, roamStatus); + switch(roamStatus) + { + case eCSR_ROAM_SESSION_OPENED: + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s calling sme_RoamConnect with eCSR_BSS_TYPE_INFRA_AP", __func__); + sapContext->isSapSessionOpen = eSAP_TRUE; + halStatus = sme_RoamConnect(hHal, sapContext->sessionId, + &sapContext->csrRoamProfile, + &sapContext->csrRoamId); + break; + } + + case eCSR_ROAM_INFRA_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_INFRA_IND", roamStatus); + if(roamResult == eCSR_ROAM_RESULT_INFRA_START_FAILED) + { + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_START_FAILS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + break; + + case eCSR_ROAM_LOSTLINK: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_LOSTLINK", roamStatus); + break; + + case eCSR_ROAM_MIC_ERROR_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_MIC_ERROR_IND", roamStatus); + break; + + case eCSR_ROAM_SET_KEY_COMPLETE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_SET_KEY_COMPLETE", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_REMOVE_KEY_COMPLETE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_REMOVE_KEY_COMPLETE", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_DEL_KEY_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_ASSOCIATION_COMPLETION: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_ASSOCIATION_COMPLETION", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_DISASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_DISASSOCIATED", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_MIC_FAILURE) + { + /* Format the MIC failure event to return... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_WPS_PBC_PROBE_REQ_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)\n", + __func__, "eCSR_ROAM_WPS_PBC_PROBE_REQ_IND", roamStatus); + break; + + case eCSR_ROAM_INDICATE_MGMT_FRAME: + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_INDICATE_MGMT_FRAME, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + break; + case eCSR_ROAM_REMAIN_CHAN_READY: + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_REMAIN_CHAN_READY, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + break; + case eCSR_ROAM_SEND_ACTION_CNF: + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_SEND_ACTION_CNF, + (v_PVOID_t)((eSapStatus)((roamResult == eCSR_ROAM_RESULT_NONE) + ? eSAP_STATUS_SUCCESS : eSAP_STATUS_FAILURE))); + break; + + case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS: + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_DISCONNECT_ALL_P2P_CLIENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS ); + break; + + case eCSR_ROAM_SEND_P2P_STOP_BSS: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Received stopbss", __func__); + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_MAC_TRIG_STOP_BSS_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS ); + break; + + case eCSR_ROAM_DFS_RADAR_IND: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Received Radar Indication")); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Indicate eSAP_DFS_RADAR_DETECT to HDD"); + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_RADAR_DETECT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + /* sync to latest DFS-NOL */ + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_GET, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + pMac->sap.SapDfsInfo.target_channel = + sapIndicateRadar(sapContext, &pCsrRoamInfo->dfs_event); + + /* if there is an assigned next channel hopping */ + if (0 < pMac->sap.SapDfsInfo.user_provided_target_channel) + { + pMac->sap.SapDfsInfo.target_channel = + pMac->sap.SapDfsInfo.user_provided_target_channel; + pMac->sap.SapDfsInfo.user_provided_target_channel = 0; + } + + if (pMac->sap.SapDfsInfo.target_channel == 0) { + /* No available channel found */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("No available channel found, StopBss!!!")); + WLANSAP_StopBss((v_PVOID_t)sapContext); + break; + } + + pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; + sap_CacResetNotify(hHal); + + /* set DFS-NOL back to keep it update-to-date in CNSS */ + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_SET, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + break; + + case eCSR_ROAM_DFS_CHAN_SW_NOTIFY: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Received Chan Sw Update Notification", __func__); + break; + + case eCSR_ROAM_SET_CHANNEL_RSP: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Received set channel response", __func__); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamStatus not handled roamStatus = %s (%d)\n", + __func__, get_eRoamCmdStatus_str(roamStatus), roamStatus); + break; + + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamResult = %d\n", + __func__, roamResult); + + switch (roamResult) + { + case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND", roamResult); + sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen; + + if(sapContext->nStaWPARSnReqIeLength) + vos_mem_copy( sapContext->pStaWpaRsnReqIE, + pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength); + + sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen; + + if(sapContext->nStaAddIeLength) + vos_mem_copy( sapContext->pStaAddIE, + pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength); + + sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta; + // MAC filtering + vosStatus = sapIsPeerMacAllowed(sapContext, (v_U8_t *)pCsrRoamInfo->peerMac); + + if ( VOS_STATUS_SUCCESS == vosStatus ) + { + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_IND, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, CSR roamResult = (%d) MAC (" + MAC_ADDRESS_STR") fail", __func__, roamResult, + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac)); + halStatus = eHAL_STATUS_FAILURE; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "In %s, CSR roamResult = (%d) MAC (" + MAC_ADDRESS_STR") not allowed", __func__, roamResult, + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac)); + halStatus = eHAL_STATUS_FAILURE; + } + + break; + + case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF", roamResult); + + sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen; + if (sapContext->nStaWPARSnReqIeLength) + vos_mem_copy( sapContext->pStaWpaRsnReqIE, + pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength); + + sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen; + if(sapContext->nStaAddIeLength) + vos_mem_copy( sapContext->pStaAddIE, + pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength); + + sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta; + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_DISASSOC_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_DISASSOC_IND", roamResult); + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_DEAUTH_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_DEAUTH_IND", roamResult); + /* Fill in the event structure */ + //TODO: we will use the same event inorder to inform HDD to disassociate the station + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_GROUP: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_MIC_ERROR_GROUP", roamResult); + /* Fill in the event structure */ + //TODO: support for group key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST", roamResult); + /* Fill in the event structure */ + //TODO: support for unicast key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_AUTHENTICATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_AUTHENTICATED", roamResult); + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_ASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_ASSOCIATED", roamResult); + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + break; + + case eCSR_ROAM_RESULT_INFRA_STARTED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_INFRA_STARTED", roamResult); + + /* In the current implementation, hostapd is not aware that + * drive will support DFS. Hence, driver should inform + * eSAP_MAC_START_BSS_SUCCESS to upper layers and then perform + * CAC underneath + */ + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_INFRA_STOPPED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_INFRA_STOPPED", roamResult); + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND", roamResult); + /* Fill in the event structure */ + //TODO: support for group key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_WPS_PBC_PROBE_REQ_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_FORCED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_FORCED", roamResult); + //This event can be used to inform hdd about user triggered disassoc event + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + break; + + case eCSR_ROAM_RESULT_NONE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_NONE", roamResult); + //This event can be used to inform hdd about user triggered disassoc event + /* Fill in the event structure */ + if ( roamStatus == eCSR_ROAM_SET_KEY_COMPLETE) + { + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS); + } + else if (roamStatus == eCSR_ROAM_REMOVE_KEY_COMPLETE ) + { + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_DEL_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS); + } + break; + + case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n", + __func__, "eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED", roamResult); + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_MAX_ASSOC_EXCEEDED, (v_PVOID_t)NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + + break; + + case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND: + if (eSAP_DFS_CAC_WAIT == sapContext->sapsMachine) + { + if (sapContext->csrRoamProfile.disableDFSChSwitch) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "sapdfs: DFS channel switch disabled"); + break; + } + if (VOS_TRUE == pMac->sap.SapDfsInfo.sap_radar_found_status) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs:Posting event eSAP_DFS_CHANNEL_CAC_RADAR_FOUND"); + /* + * If Radar is found, while in DFS CAC WAIT State then + * post stop and destroy the CAC timer and post a + * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND to sapFsm. + */ + vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; + + sapEvent.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + } + else if(eSAP_STARTED == sapContext->sapsMachine) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs:Posting event eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START"); + + /* Radar found on the operating channel in STARTED state, + * new operating channel has already been selected. Send + * request to SME-->PE for sending CSA IE + */ + sapEvent.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + else + { + /* Further actions to be taken here */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in" + "(%d) state\n", __func__, sapContext->sapsMachine); + } + break; + + case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS: + case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE: + { + eCsrPhyMode phyMode = + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode); + + if (sapContext->csrRoamProfile.disableDFSChSwitch) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "sapdfs: DFS channel switch disabled"); + /* + * Send a beacon start request to PE. CSA IE required + * flag from beacon template will be cleared by now. + * A new beacon template with no CSA IE will be sent + * to firmware. + */ + dfs_beacon_start_req = VOS_TRUE; + halStatus = sme_RoamStartBeaconReq( hHal, + sapContext->bssid, + dfs_beacon_start_req); + break; + } + + /* Both success and failure cases are handled intentionally handled + * together. Irrespective of whether the channel switch IE was + * sent out successfully or not, SAP should still vacate the + * channel immediately + */ + if (eSAP_STARTED == sapContext->sapsMachine) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: from state %s => %s", + "eSAP_STARTED", "eSAP_DISCONNECTING"); + + /* SAP to be moved to DISCONNECTING state */ + sapContext->sapsMachine = eSAP_DISCONNECTING; + + /* The associated stations have been informed to move + * to a different channel. However, the AP may not always + * select the advertised channel for operation if the radar + * is seen. In that case, the stations will experience link-loss + * and return back through scanning if they wish to + */ + + /* Send channel change request + * From spec it is required that the AP should continue to + * operate in the same mode as it is operating currently. + * For e.g. 20/40/80 MHz operation + */ + if (pMac->sap.SapDfsInfo.target_channel) + { + sme_SelectCBMode(hHal, phyMode, + pMac->sap.SapDfsInfo.target_channel); + } + + /* Send channel switch request */ + sapEvent.event = eWNI_SME_CHANNEL_CHANGE_REQ; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Posting event eWNI_SME_CHANNEL_CHANGE_REQ to sapFSM"); + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + else + { + /* Further actions to be taken here */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in" + "(%d) state\n", __func__, sapContext->sapsMachine); + } + break; + } + case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS: + { + /* Channel change is successful. If the new channel is a DFS + * channel, then we will to perform channel availability check + * for 60 seconds + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: changing target channel to [%d]", + pMac->sap.SapDfsInfo.target_channel); + + sapContext->channel = + pMac->sap.SapDfsInfo.target_channel; + + /* Identify if this is channel change in radar detected state */ + if (eSAP_DISCONNECTING == sapContext->sapsMachine) + { + /* check if currently selected channel is a DFS channel */ + if (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(sapContext->channel)) + { + if ((VOS_FALSE == pMac->sap.SapDfsInfo.ignore_cac) && + (eSAP_DFS_DO_NOT_SKIP_CAC == + pMac->sap.SapDfsInfo.cac_state)) + { + sapContext->sapsMachine = eSAP_DISCONNECTED; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: from state %s => %s with ignore cac FALSE on sapctx[%p]", + "eSAP_DISCONNECTING", "DISCONNECTED", sapContext); + + /* DFS Channel */ + sapEvent.event = eSAP_DFS_CHANNEL_CAC_START; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: from state %s => %s with ignore cac TRUE on sapctx[%p]", + "eSAP_DISCONNECTING", "eSAP_STARTING", sapContext); + + /* Start beaconing on the new channel */ + WLANSAP_StartBeaconReq((v_PVOID_t)sapContext); + sapContext->sapsMachine = eSAP_STARTING; + pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE; + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = eCSR_ROAM_INFRA_IND; + sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: from state %s => %s on sapctx[%p]", + "eSAP_DISCONNECTING", "eSAP_STARTING", sapContext); + + /* non-DFS channel */ + sapContext->sapsMachine = eSAP_STARTING; + pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE; + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = eCSR_ROAM_INFRA_IND; + sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED; + } + + /* Handle the event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + + } + else + { + /* We may have a requirment in the future for SAP to perform + * channel change, hence leaving this here + */ + } + + break; + } + case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE: + { + /* This is much more serious issue, we have to vacate the + * channel due to the presence of radar but our channel change + * failed, stop the BSS operation completely and inform hostapd + */ + sapContext->sapsMachine = eSAP_DISCONNECTED; + + /* Inform cfg80211 and hostapd that BSS is not alive anymore */ + } + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamResult = %s (%d) not handled\n", + __func__,get_eCsrRoamResult_str(roamResult),roamResult); + break; + } + + return halStatus; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.c b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.c new file mode 100644 index 0000000000000..dccfcc836a0e9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.c @@ -0,0 +1,2673 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p C h S e l e c t . C + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions for channel selection. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 SOFTAP Created module + +===========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files +------------------------------------------------------------------------*/ +#include "vos_trace.h" +#include "csrApi.h" +#include "sme_Api.h" +#include "sapChSelect.h" +#include "sapInternal.h" +#ifdef ANI_OS_TYPE_QNX +#include "stdio.h" +#endif +#include "wlan_hdd_main.h" + +/*-------------------------------------------------------------------------- + Function definitions +--------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Defines +--------------------------------------------------------------------------*/ +#define SAP_DEBUG + +#define IS_RSSI_VALID( extRssi, rssi ) \ +( \ + ((extRssi < rssi)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#ifdef FEATURE_WLAN_CH_AVOID +sapSafeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] = +{ + /*CH , SAFE, default safe */ + {1 , VOS_TRUE}, //RF_CHAN_1, + {2 , VOS_TRUE}, //RF_CHAN_2, + {3 , VOS_TRUE}, //RF_CHAN_3, + {4 , VOS_TRUE}, //RF_CHAN_4, + {5 , VOS_TRUE}, //RF_CHAN_5, + {6 , VOS_TRUE}, //RF_CHAN_6, + {7 , VOS_TRUE}, //RF_CHAN_7, + {8 , VOS_TRUE}, //RF_CHAN_8, + {9 , VOS_TRUE}, //RF_CHAN_9, + {10 , VOS_TRUE}, //RF_CHAN_10, + {11 , VOS_TRUE}, //RF_CHAN_11, + {12 , VOS_TRUE}, //RF_CHAN_12, + {13 , VOS_TRUE}, //RF_CHAN_13, + {14 , VOS_TRUE}, //RF_CHAN_14, + {240, VOS_TRUE}, //RF_CHAN_240, + {244, VOS_TRUE}, //RF_CHAN_244, + {248, VOS_TRUE}, //RF_CHAN_248, + {252, VOS_TRUE}, //RF_CHAN_252, + {208, VOS_TRUE}, //RF_CHAN_208, + {212, VOS_TRUE}, //RF_CHAN_212, + {216, VOS_TRUE}, //RF_CHAN_216, + {36 , VOS_TRUE}, //RF_CHAN_36, + {40 , VOS_TRUE}, //RF_CHAN_40, + {44 , VOS_TRUE}, //RF_CHAN_44, + {48 , VOS_TRUE}, //RF_CHAN_48, + {52 , VOS_TRUE}, //RF_CHAN_52, + {56 , VOS_TRUE}, //RF_CHAN_56, + {60 , VOS_TRUE}, //RF_CHAN_60, + {64 , VOS_TRUE}, //RF_CHAN_64, + {100, VOS_TRUE}, //RF_CHAN_100, + {104, VOS_TRUE}, //RF_CHAN_104, + {108, VOS_TRUE}, //RF_CHAN_108, + {112, VOS_TRUE}, //RF_CHAN_112, + {116, VOS_TRUE}, //RF_CHAN_116, + {120, VOS_TRUE}, //RF_CHAN_120, + {124, VOS_TRUE}, //RF_CHAN_124, + {128, VOS_TRUE}, //RF_CHAN_128, + {132, VOS_TRUE}, //RF_CHAN_132, + {136, VOS_TRUE}, //RF_CHAN_136, + {140, VOS_TRUE}, //RF_CHAN_140, + {149, VOS_TRUE}, //RF_CHAN_149, + {153, VOS_TRUE}, //RF_CHAN_153, + {157, VOS_TRUE}, //RF_CHAN_157, + {161, VOS_TRUE}, //RF_CHAN_161, + {165, VOS_TRUE}, //RF_CHAN_165, +}; +#endif + +typedef struct +{ + v_U16_t chStartNum; + v_U32_t weight; +} sapAcsChannelInfo; + +#define ACS_WEIGHT_MAX 4444 + +sapAcsChannelInfo acsHT40Channels5G[ ] = { + {36, ACS_WEIGHT_MAX}, + {44, ACS_WEIGHT_MAX}, + {52, ACS_WEIGHT_MAX}, + {60, ACS_WEIGHT_MAX}, + {100, ACS_WEIGHT_MAX}, + {108, ACS_WEIGHT_MAX}, + {116, ACS_WEIGHT_MAX}, + {124, ACS_WEIGHT_MAX}, + {132, ACS_WEIGHT_MAX}, + {140, ACS_WEIGHT_MAX}, + {149, ACS_WEIGHT_MAX}, + {157, ACS_WEIGHT_MAX}, +}; + +sapAcsChannelInfo acsHT80Channels[ ] = { + {36, ACS_WEIGHT_MAX}, + {52, ACS_WEIGHT_MAX}, + {100, ACS_WEIGHT_MAX}, + {116, ACS_WEIGHT_MAX}, + {132, ACS_WEIGHT_MAX}, + {149, ACS_WEIGHT_MAX}, +}; + +sapAcsChannelInfo acsHT40Channels24G[ ] = { + {1, ACS_WEIGHT_MAX}, + {2, ACS_WEIGHT_MAX}, + {3, ACS_WEIGHT_MAX}, + {4, ACS_WEIGHT_MAX}, + {9, ACS_WEIGHT_MAX}, +}; + +typedef enum { + CHWIDTH_HT20, + CHWIDTH_HT40, + CHWIDTH_HT80, +} eChannelWidthInfo; + +#define CHANNEL_165 165 + +#ifdef FEATURE_WLAN_CH_AVOID +/*========================================================================== + FUNCTION sapUpdateUnsafeChannelList + + DESCRIPTION + Function Undate unsafe channel list table + + DEPENDENCIES + NA. + + IN + NULL + + RETURN VALUE + NULL +============================================================================*/ +void sapUpdateUnsafeChannelList() +{ + v_U16_t i, j; + + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); + struct hdd_context_s *hdd_ctxt; + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "VOSS Global Context is NULL"); + return ; + } + + hdd_ctxt = (struct hdd_context_s *) vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx); + + if (NULL == hdd_ctxt) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "HDD Context is NULL"); + return ; + } + + /* Flush, default set all channel safe */ + for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) + { + safeChannels[i].isSafe = VOS_TRUE; + } + + /* Try to find unsafe channel */ + for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) + { + for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++) + { + if(safeChannels[j].channelNumber == hdd_ctxt->unsafe_channel_list[i]) + { + /* Found unsafe channel, update it */ + safeChannels[j].isSafe = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s : CH %d is not safe", + __func__, hdd_ctxt->unsafe_channel_list[i]); + break; + } + } + } + + return; +} + +#endif /* FEATURE_WLAN_CH_AVOID */ + +/*========================================================================== + FUNCTION sapCleanupChannelList + + DESCRIPTION + Function sapCleanupChannelList frees up the memory allocated to the channel list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + NULL + + RETURN VALUE + NULL +============================================================================*/ + +void sapCleanupChannelList +( +#ifdef WLAN_FEATURE_MBSSID + v_PVOID_t pvosGCtx +#else + void +#endif +) +{ +#ifndef WLAN_FEATURE_MBSSID + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); +#endif + ptSapContext pSapCtx; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "Cleaning up the channel list structure"); + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Global Context is NULL"); + return ; + } + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Context is NULL"); + return ; + } + + pSapCtx->SapChnlList.numChannel = 0; + if (pSapCtx->SapChnlList.channelList) { + vos_mem_free(pSapCtx->SapChnlList.channelList); + pSapCtx->SapChnlList.channelList = NULL; + } + + pSapCtx->SapAllChnlList.numChannel = 0; + if (pSapCtx->SapAllChnlList.channelList) { + vos_mem_free(pSapCtx->SapAllChnlList.channelList); + pSapCtx->SapAllChnlList.channelList = NULL; + } +} + +/*========================================================================== + FUNCTION sapSetPreferredChannel + + DESCRIPTION + Function sapSetPreferredChannel sets the channel list which has been configured + into sap context (pSapCtx) which will be used at the time of best channel selection. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *ptr: pointer having the command followed by the arguments in string format + + RETURN VALUE + int: return 0 when success else returns error code. +============================================================================*/ + +int sapSetPreferredChannel +( +#ifdef WLAN_FEATURE_MBSSID + v_PVOID_t pvosGCtx, +#endif + tANI_U8* ptr +) +{ +#ifndef WLAN_FEATURE_MBSSID + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); +#endif + ptSapContext pSapCtx; + tANI_U8* param; + int tempInt; + int j; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Enter: %s", __func__); + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Global Context is NULL"); + return -EINVAL; + } + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Context is NULL"); + return -EINVAL; + } + + if (NULL != pSapCtx->SapChnlList.channelList) + { +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + } + + param = strchr(ptr, ' '); + /*no argument after the command*/ + if (NULL == param) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *param) + { + return -EINVAL; + } + + param++; + + /*removing empty spaces*/ + while((SPACE_ASCII_VALUE == *param)&& ('\0' != *param) ) param++; + + /*no argument followed by spaces*/ + if('\0' == *param) + { + return -EINVAL; + } + + /*getting the first argument ie the number of channels*/ + if (sscanf(param, "%d ", &tempInt) != 1) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot get number of channels from input", __func__); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Number of channel added are: %d", __func__, tempInt); + + if (tempInt <= 0 || tempInt > 255) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Number of channel received", __func__); + return -EINVAL; + } + + /*allocating space for the desired number of channels*/ + pSapCtx->SapChnlList.channelList = (v_U8_t *)vos_mem_malloc(tempInt); + + if (NULL == pSapCtx->SapChnlList.channelList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, VOS_MALLOC_ERR", __func__); + return -EINVAL; + } + + pSapCtx->SapChnlList.numChannel = tempInt; + for(j=0;jSapChnlList.numChannel;j++) + { + + /*param pointing to the beginning of first space after number of channels*/ + param = strpbrk( param, " " ); + /*no channel list after the number of channels argument*/ + if (NULL == param) + { +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + return -EINVAL; + } + + param++; + + /*removing empty space*/ + while((SPACE_ASCII_VALUE == *param) && ('\0' != *param) ) param++; + + /*no channel list after the number of channels argument and spaces*/ + if( '\0' == *param ) + { +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + return -EINVAL; + } + + if (sscanf(param, "%d ", &tempInt) != 1) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot read channel number", __func__); +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + return -EINVAL; + } + if (tempInt < 0 || tempInt > 255) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid channel number received", __func__); +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + return -EINVAL; + } + + pSapCtx->SapChnlList.channelList[j] = tempInt; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Channel %d added to preferred channel list", + __func__, pSapCtx->SapChnlList.channelList[j] ); + + } + + /*extra arguments check*/ + param = strpbrk( param, " " ); + if (NULL != param) + { + while((SPACE_ASCII_VALUE == *param) && ('\0' != *param) ) param++; + + if('\0' != *param) + { +#ifdef WLAN_FEATURE_MBSSID + sapCleanupChannelList(pSapCtx); +#else + sapCleanupChannelList(); +#endif + return -EINVAL; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Exit: %s", __func__); + + return 0; +} + +/*========================================================================== + FUNCTION sapSelectPreferredChannelFromChannelList + + DESCRIPTION + Function sapSelectPreferredChannelFromChannelList calculates the best channel + among the configured channel list. If channel list not configured then returns + the best channel calculated among all the channel list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure + bestChNum: best channel already calculated among all the chanels + pSapCtx: having info of channel list from which best channel is selected + + RETURN VALUE + v_U8_t: best channel +============================================================================*/ +v_U8_t sapSelectPreferredChannelFromChannelList(v_U8_t bestChNum, + ptSapContext pSapCtx, + tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t j = 0; + v_U8_t count = 0; + + //If Channel List is not Configured don't do anything + //Else return the Best Channel from the Channel List + if((NULL == pSapCtx->SapChnlList.channelList) || + (NULL == pSpectInfoParams) || + (0 == pSapCtx->SapChnlList.numChannel)) + { + return bestChNum; + } + + if (bestChNum > 0 && bestChNum <= 252) + { + for(count=0; count < pSpectInfoParams->numSpectChans ; count++) + { + bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[count].chNum; + // Select the best channel from allowed list + for(j=0;j< pSapCtx->SapChnlList.numChannel;j++) + { + if( (pSapCtx->SapChnlList.channelList[j]) == bestChNum) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Best channel computed from Channel List is: %d", + bestChNum); + return bestChNum; + } + } + } + + return SAP_CHANNEL_NOT_SELECTED; + } + else + return SAP_CHANNEL_NOT_SELECTED; +} + + +/*========================================================================== + FUNCTION sapChanSelInit + + DESCRIPTION + Function sapChanSelInit allocates the memory, intializes the + structures used by the channel selection algorithm + + DEPENDENCIES + NA. + + PARAMETERS + + IN + halHandle : Pointer to tHalHandle + *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure + pSapCtx : Pointer to SAP Context + + RETURN VALUE + v_BOOL_t: Success or FAIL + + SIDE EFFECTS +============================================================================*/ +v_BOOL_t sapChanSelInit(tHalHandle halHandle, + tSapChSelSpectInfo *pSpectInfoParams, + ptSapContext pSapCtx) +{ + tSapSpectChInfo *pSpectCh = NULL; + v_U8_t *pChans = NULL; + v_U16_t channelnum = 0; + tpAniSirGlobal pMac = PMAC_STRUCT(halHandle); + v_BOOL_t chSafe = VOS_TRUE; +#ifdef FEATURE_WLAN_CH_AVOID + v_U16_t i; +#endif + v_U32_t dfs_master_cap_enabled; + v_BOOL_t include_dfs_ch = VOS_TRUE; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__); + + pSpectInfoParams->numSpectChans = pMac->scan.base20MHzChannels.numChannels; + + // Allocate memory for weight computation of 2.4GHz + pSpectCh = (tSapSpectChInfo *)vos_mem_malloc((pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh)); + + if(pSpectCh == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, VOS_MALLOC_ERR", __func__); + return eSAP_FALSE; + } + + vos_mem_zero(pSpectCh, (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh)); + + // Initialize the pointers in the DfsParams to the allocated memory + pSpectInfoParams->pSpectCh = pSpectCh; + + pChans = pMac->scan.base20MHzChannels.channelList; +#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) || defined(WLAN_FEATURE_MBSSID) + if (pSapCtx->dfs_ch_disable == VOS_TRUE) + include_dfs_ch = VOS_FALSE; +#endif + ccmCfgGetInt(halHandle, WNI_CFG_DFS_MASTER_ENABLED, + &dfs_master_cap_enabled); + if (dfs_master_cap_enabled == 0) + include_dfs_ch = VOS_FALSE; + + // Fill the channel number in the spectrum in the operating freq band + for (channelnum = 0; + channelnum < pSpectInfoParams->numSpectChans; + channelnum++, pChans++) { + chSafe = VOS_TRUE; + + /* check if the channel is in NOL blacklist */ + if(sapDfsIsChannelInNolList(pSapCtx, *pChans, + PHY_SINGLE_CHANNEL_CENTERED)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Ch %d is in NOL list", __func__, *pChans); + chSafe = VOS_FALSE; + continue; + } + + if (include_dfs_ch == VOS_FALSE) { + if (VOS_IS_DFS_CH(*pChans)) { + chSafe = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, DFS Ch %d not considered for ACS", __func__, + *pChans); + continue; + } + } + +#ifdef FEATURE_WLAN_CH_AVOID + for(i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) { + if((safeChannels[i].channelNumber == *pChans) && + (VOS_FALSE == safeChannels[i].isSafe)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Ch %d is not safe", + __func__, *pChans); + chSafe = VOS_FALSE; + break; + } + } +#endif /* FEATURE_WLAN_CH_AVOID */ + + /* OFDM rates are not supported on channel 14 */ + if(*pChans == 14 && + eCSR_DOT11_MODE_11b != sme_GetPhyMode(halHandle)) + { + continue; + } + + if (VOS_TRUE == chSafe) + { + pSpectCh->chNum = *pChans; + pSpectCh->valid = eSAP_TRUE; + pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;// Initialise for all channels + pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; // Initialise 20MHz for all the Channels + pSpectCh++; + } + } + return eSAP_TRUE; +} + +/*========================================================================== + FUNCTION sapweightRssiCount + + DESCRIPTION + Function weightRssiCount calculates the channel weight due to rssi + and data count(here number of BSS observed) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + rssi : Max signal strength receieved from a BSS for the channel + count : Number of BSS observed in the channel + + RETURN VALUE + v_U32_t : Calculated channel weight based on above two + + SIDE EFFECTS +============================================================================*/ +v_U32_t sapweightRssiCount(v_S7_t rssi, v_U16_t count) +{ + v_S31_t rssiWeight=0; + v_S31_t countWeight=0; + v_U32_t rssicountWeight=0; + + // Weight from RSSI + rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI) + /(SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI); + + if(rssiWeight > SOFTAP_RSSI_WEIGHT) + rssiWeight = SOFTAP_RSSI_WEIGHT; + else if (rssiWeight < 0) + rssiWeight = 0; + + // Weight from data count + countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT) + /(SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT); + + if(countWeight > SOFTAP_COUNT_WEIGHT) + countWeight = SOFTAP_COUNT_WEIGHT; + else if (countWeight < 0) + countWeight = 0; + + rssicountWeight = rssiWeight + countWeight; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d", + __func__, rssiWeight, countWeight, rssicountWeight); + + return(rssicountWeight); +} + + +/*========================================================================== + FUNCTION sapInterferenceRssiCount + + DESCRIPTION + Function sapInterferenceRssiCount Considers the Adjacent channel rssi + and data count(here number of BSS observed) + + DEPENDENCIES + NA. + + PARAMETERS + + pSpectCh : Channel Information + + RETURN VALUE + NA. + + SIDE EFFECTS +============================================================================*/ +void sapInterferenceRssiCount(tSapSpectChInfo *pSpectCh) +{ + tSapSpectChInfo *pExtSpectCh = NULL; + v_S31_t rssi; + + if (NULL == pSpectCh) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: pSpectCh is NULL", __func__); + return; + } + + switch(pSpectCh->chNum) + { + case CHANNEL_1: + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_2: + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + case CHANNEL_3: + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + case CHANNEL_4: + pExtSpectCh = (pSpectCh - 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_5: + case CHANNEL_6: + case CHANNEL_7: + case CHANNEL_8: + case CHANNEL_9: + case CHANNEL_10: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_11: + pExtSpectCh = (pSpectCh - 4); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_12: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_13: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if ((pExtSpectCh != NULL) && (pExtSpectCh->chNum <= CHANNEL_14)) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_14: + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + default: + break; + } +} + +/*========================================================================== + FUNCTION sapComputeSpectWeight + + DESCRIPTION + Main function for computing the weight of each channel in the + spectrum based on the RSSI value of the BSSes on the channel + and number of BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSpectInfoParams structure + halHandle : Pointer to HAL handle + pResult : Pointer to tScanResultHandle + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapComputeSpectWeight( tSapChSelSpectInfo* pSpectInfoParams, + tHalHandle halHandle, tScanResultHandle pResult) +{ + v_S7_t rssi = 0; + v_U8_t chn_num = 0; + v_U8_t channel_id = 0; + + tCsrScanResultInfo *pScanResult; + tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh; + v_U32_t operatingBand; + v_U16_t channelWidth; + v_U16_t secondaryChannelOffset; + v_U16_t centerFreq; + v_U16_t vhtSupport; + v_U32_t ieLen = 0; + tSirProbeRespBeacon *pBeaconStruct; + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + + pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pBeaconStruct ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Unable to allocate memory in sapComputeSpectWeight\n"); + return; + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Computing spectral weight", __func__); + + /** + * Soft AP specific channel weight calculation using DFS formula + */ + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + + pScanResult = sme_ScanResultGetFirst(halHandle, pResult); + + while (pScanResult) { + pSpectCh = pSpectInfoParams->pSpectCh; + // Defining the default values, so that any value will hold the default values + channelWidth = eHT_CHANNEL_WIDTH_20MHZ; + secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED; + vhtSupport = 0; + centerFreq = 0; + + if (pScanResult->BssDescriptor.ieFields != NULL) + { + ieLen = (pScanResult->BssDescriptor.length + sizeof(tANI_U16) + sizeof(tANI_U32) - sizeof(tSirBssDescription)); + vos_mem_set((tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); + + if ((sirParseBeaconIE(pMac, pBeaconStruct,(tANI_U8 *)( pScanResult->BssDescriptor.ieFields), ieLen)) == eSIR_SUCCESS) + { + if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) + { + channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet; + secondaryChannelOffset = pBeaconStruct->HTInfo.secondaryChannelOffset; + if(pBeaconStruct->VHTOperation.present) + { + vhtSupport = pBeaconStruct->VHTOperation.present; + if(pBeaconStruct->VHTOperation.chanWidth > WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + channelWidth = eHT_CHANNEL_WIDTH_80MHZ; + centerFreq = pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + } + } + } + } + } + // Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list + for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans; chn_num++) { + + /* + * if the Beacon has channel ID, use it other wise we will + * rely on the channelIdSelf + */ + if(pScanResult->BssDescriptor.channelId == 0) + channel_id = pScanResult->BssDescriptor.channelIdSelf; + else + channel_id = pScanResult->BssDescriptor.channelId; + + if (pSpectCh && (channel_id == pSpectCh->chNum)) { + if (pSpectCh->rssiAgr < pScanResult->BssDescriptor.rssi) + pSpectCh->rssiAgr = pScanResult->BssDescriptor.rssi; + + ++pSpectCh->bssCount; // Increment the count of BSS + + if(operatingBand) // Connsidering the Extension Channel only in a channels + { + /* Updating the received ChannelWidth */ + if (pSpectCh->channelWidth != channelWidth) + pSpectCh->channelWidth = channelWidth; + /* If received ChannelWidth is other than HT20, we need to update the extension channel Params as well */ + /* channelWidth == 0, HT20 */ + /* channelWidth == 1, HT40 */ + /* channelWidth == 2, VHT80*/ + switch(pSpectCh->channelWidth) + { + case eHT_CHANNEL_WIDTH_40MHZ: //HT40 + switch( secondaryChannelOffset) + { + tSapSpectChInfo *pExtSpectCh = NULL; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: // Above the Primary Channel + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + // REducing the rssi by -20 and assigning it to Extension channel + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: // Below the Primary channel + pExtSpectCh = (pSpectCh - 1); + if(pExtSpectCh != NULL) + { + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + ++pExtSpectCh->bssCount; + } + break; + } + break; + case eHT_CHANNEL_WIDTH_80MHZ: // VHT80 + if((centerFreq - channel_id) == 6) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -20 and assigning it to Subband 1 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -30 and assigning it to Subband 2 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -40 and assigning it to Subband 3 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == 2) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == -2) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == -6) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + break; + } + } + else if(operatingBand == eSAP_RF_SUBBAND_2_4_GHZ) + { + sapInterferenceRssiCount(pSpectCh); + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%p, ChannelWidth %d, secondaryChanOffset %d, center frequency %d \n", + __func__, pScanResult->BssDescriptor.channelIdSelf, pScanResult->BssDescriptor.channelId, pScanResult->BssDescriptor.rssi, pSpectCh->bssCount, pScanResult,pSpectCh->channelWidth,secondaryChannelOffset,centerFreq); + pSpectCh++; + break; + } else { + pSpectCh++; + } + } + + pScanResult = sme_ScanResultGetNext(halHandle, pResult); + } + + // Calculate the weights for all channels in the spectrum pSpectCh + pSpectCh = pSpectInfoParams->pSpectCh; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Spectrum Channels Weight", __func__); + + for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans); chn_num++) { + + /* + rssi : Maximum received signal strength among all BSS on that channel + bssCount : Number of BSS on that channel + */ + + rssi = (v_S7_t)pSpectCh->rssiAgr; + + pSpectCh->weight = SAPDFS_NORMALISE_1000 * sapweightRssiCount(rssi, pSpectCh->bssCount); + pSpectCh->weight_copy = pSpectCh->weight; + + //------ Debug Info ------ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d", __func__, + pSpectCh->chNum, pSpectCh->weight, + pSpectCh->rssiAgr, pSpectCh->bssCount); + //------ Debug Info ------ + pSpectCh++; + } + vos_mem_free(pBeaconStruct); +} + +/*========================================================================== + FUNCTION sapChanSelExit + + DESCRIPTION + Exit function for free out the allocated memory, to be called + at the end of the dfsSelectChannel function + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapChanSelExit( tSapChSelSpectInfo *pSpectInfoParams ) +{ + // Free all the allocated memory + vos_mem_free(pSpectInfoParams->pSpectCh); +} + +/*========================================================================== + FUNCTION sapSortChlWeight + + DESCRIPTION + Funtion to sort the channels with the least weight first for 20MHz channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeight(tSapChSelSpectInfo *pSpectInfoParams) +{ + tSapSpectChInfo temp; + + tSapSpectChInfo *pSpectCh = NULL; + v_U32_t i = 0, j = 0, minWeightIndex = 0; + + pSpectCh = pSpectInfoParams->pSpectCh; + for (i = 0; i < pSpectInfoParams->numSpectChans; i++) { + minWeightIndex = i; + for( j = i + 1; j < pSpectInfoParams->numSpectChans; j++) { + if(pSpectCh[j].weight < pSpectCh[minWeightIndex].weight) { + minWeightIndex = j; + } + } + if(minWeightIndex != i) { + vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh)); + } + } +} + +/*========================================================================== + FUNCTION sapSortChlWeightHT80 + + DESCRIPTION + Funtion to sort the channels with the least weight first for HT80 channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT80(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j, n; + tSapSpectChInfo *pSpectInfo; + v_U8_t minIdx; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /* for each HT80 channel, calculate the combined weight of the + four 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT80Channels); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( pSpectInfo[j].chNum == acsHT80Channels[i].chStartNum ) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + /*found the channel, add the 4 adjacent channels' weight*/ + if (((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) && + ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum) && + ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum)) + { + acsHT80Channels[i].weight = pSpectInfo[j].weight + + pSpectInfo[j+1].weight + + pSpectInfo[j+2].weight + + pSpectInfo[j+3].weight; + /* find best channel among 4 channels as the primary channel */ + if ((pSpectInfo[j].weight + pSpectInfo[j+1].weight) < + (pSpectInfo[j+2].weight + pSpectInfo[j+3].weight)) + { + /* lower 2 channels are better choice */ + if (pSpectInfo[j].weight < pSpectInfo[j+1].weight) + minIdx = 0; + else + minIdx = 1; + } + else + { + /* upper 2 channels are better choice */ + if (pSpectInfo[j+2].weight <= pSpectInfo[j+3].weight) + minIdx = 2; + else + minIdx = 3; + } + + /* set all 4 channels to max value first, then reset the + best channel as the selected primary channel, update its + weightage with the combined weight value */ + for (n=0; n<4; n++) + pSpectInfo[j+n].weight = ACS_WEIGHT_MAX * 4; + + pSpectInfo[j+minIdx].weight = acsHT80Channels[i].weight; + } + else + { + /* some channels does not exist in pSectInfo array, + skip this channel and those in the same HT80 width*/ + pSpectInfo[j].weight = ACS_WEIGHT_MAX; + if ((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) + pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 4; + if ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum) + pSpectInfo[j+2].weight = ACS_WEIGHT_MAX * 4; + if ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum) + pSpectInfo[j+3].weight = ACS_WEIGHT_MAX * 4; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( CHANNEL_165 == pSpectInfo[j].chNum ) + { + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4; + break; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectInfo->chNum, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; + } + + sapSortChlWeight(pSpectInfoParams); +} + +/*========================================================================== + FUNCTION sapSortChlWeightHT40_24G + + DESCRIPTION + Funtion to sort the channels with the least weight first for HT40 channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT40_24G(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j; + tSapSpectChInfo *pSpectInfo; + v_U32_t tmpWeight1, tmpWeight2; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /*for each HT40 channel, calculate the combined weight of the + two 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT40Channels24G); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if (pSpectInfo[j].chNum == acsHT40Channels24G[i].chStartNum) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + if ((pSpectInfo[j].chNum +4) == pSpectInfo[j+4].chNum) + { + /* check if there is another channel combination possiblity + e.g., {1, 5} & {5, 9} */ + if ((pSpectInfo[j+4].chNum + 4)== pSpectInfo[j+8].chNum) + { + /* need to compare two channel pairs */ + tmpWeight1 = pSpectInfo[j].weight + pSpectInfo[j+4].weight; + tmpWeight2 = pSpectInfo[j+4].weight + pSpectInfo[j+8].weight; + if (tmpWeight1 <= tmpWeight2) + { + if (pSpectInfo[j].weight <= pSpectInfo[j+4].weight) + { + pSpectInfo[j].weight = tmpWeight1; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+4].weight = tmpWeight1; + /* for secondary channel selection */ + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2 - 1; + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2; + } + } + else + { + if (pSpectInfo[j+4].weight <= pSpectInfo[j+8].weight) + { + pSpectInfo[j+4].weight = tmpWeight2; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + /* for secondary channel selection */ + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2 - 1; + } + else + { + pSpectInfo[j+8].weight = tmpWeight2; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + } + } + } + else + { + tmpWeight1 = pSpectInfo[j].weight + pSpectInfo[j+4].weight; + if (pSpectInfo[j].weight <= pSpectInfo[j+4].weight) + { + pSpectInfo[j].weight = tmpWeight1; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+4].weight = tmpWeight1; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + } + } + else + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + sapSortChlWeight(pSpectInfoParams); +} + + +/*========================================================================== + FUNCTION sapSortChlWeightHT40_5G + + DESCRIPTION + Funtion to sort the channels with the least weight first for HT40 channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT40_5G(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j; + tSapSpectChInfo *pSpectInfo; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /*for each HT40 channel, calculate the combined weight of the + two 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT40Channels5G); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if (pSpectInfo[j].chNum == acsHT40Channels5G[i].chStartNum) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + /* found the channel, add the two adjacent channels' weight */ + if ( (pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) + { + acsHT40Channels5G[i].weight = pSpectInfo[j].weight + + pSpectInfo[j+1].weight; + /* select better of the adjact channel as the primary channel */ + if (pSpectInfo[j].weight <= pSpectInfo[j+1].weight) + { + pSpectInfo[j].weight = acsHT40Channels5G[i].weight; + /* mark the adjacent channel's weight as max value so + that it will be sorted to the bottom */ + pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+1].weight = acsHT40Channels5G[i].weight; + /* mark the adjacent channel's weight as max value so + that it will be sorted to the bottom */ + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + } + else + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + /* avoid channel 165 by setting its weight to max */ + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( CHANNEL_165 == pSpectInfo[j].chNum ) + { + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + break; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectInfo->chNum, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; + } + + sapSortChlWeight(pSpectInfoParams); +} + +/*========================================================================== + FUNCTION sapSortChlWeightAll + + DESCRIPTION + Funtion to sort the channels with the least weight first + + DEPENDENCIES + NA. + + PARAMETERS + + IN + ptSapContext : Pointer to the ptSapContext structure + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightAll(ptSapContext pSapCtx, + tSapChSelSpectInfo *pSpectInfoParams, + eChannelWidthInfo chWidth, + v_U32_t operatingBand) +{ + tSapSpectChInfo *pSpectCh = NULL; + v_U32_t j = 0; +#ifndef SOFTAP_CHANNEL_RANGE + v_U32_t i = 0; +#endif + + pSpectCh = pSpectInfoParams->pSpectCh; +#ifdef SOFTAP_CHANNEL_RANGE + + switch (chWidth) + { + case CHWIDTH_HT40: + if (eSAP_RF_SUBBAND_2_4_GHZ == operatingBand) + sapSortChlWeightHT40_24G(pSpectInfoParams); + else + sapSortChlWeightHT40_5G(pSpectInfoParams); + break; + + case CHWIDTH_HT80: + sapSortChlWeightHT80(pSpectInfoParams); + break; + + case CHWIDTH_HT20: + default: + /* Sorting the channels as per weights as 20MHz channels */ + sapSortChlWeight(pSpectInfoParams); + } + +#else + /* Sorting the channels as per weights */ + for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) { + minWeightIndex = i; + for( j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) { + if(pSpectCh[j].weight < pSpectCh[minWeightIndex].weight) { + minWeightIndex = j; + } + } + if(minWeightIndex != i) { + vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], + sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh)); + } + } +#endif + + /* For testing */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Sorted Spectrum Channels Weight", __func__); + pSpectCh = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectCh->chNum, pSpectCh->weight, + pSpectCh->rssiAgr, pSpectCh->bssCount); + pSpectCh++; + } + +} + +eChannelWidthInfo sapGetChannelWidthInfo(tHalHandle halHandle, ptSapContext pSapCtx, + v_U32_t operatingBand, eSapPhyMode phyMode) +{ + v_U32_t cbMode; + eChannelWidthInfo chWidth = CHWIDTH_HT20; + + if (eSAP_RF_SUBBAND_2_4_GHZ == operatingBand) + cbMode = sme_GetChannelBondingMode24G(halHandle); + else + cbMode = sme_GetChannelBondingMode5G(halHandle); + + if (phyMode == eSAP_DOT11_MODE_11n || + phyMode == eSAP_DOT11_MODE_11n_ONLY) + { + if (cbMode) + chWidth = CHWIDTH_HT40; + else + chWidth = CHWIDTH_HT20; + } + else if (pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac || + pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac_ONLY) { + chWidth = CHWIDTH_HT80; + } + else { + /* Sorting the channels as per weights as 20MHz channels */ + chWidth = CHWIDTH_HT20; + } + + return chWidth; +} +/*========================================================================== + FUNCTION sapFilterOverLapCh + + DESCRIPTION + return true if ch is acceptable. + This function will decide if we will filter over lap channel or not. + + DEPENDENCIES + shall called after ap start. + + PARAMETERS + + IN + pSapCtx : Pointer to ptSapContext. + chNum : Filter channel number. + + RETURN VALUE + v_BOOL_t : true if channel is accepted. + + SIDE EFFECTS +============================================================================*/ +v_BOOL_t sapFilterOverLapCh(ptSapContext pSapCtx, v_U16_t chNum) +{ + if (pSapCtx->enableOverLapCh) + return eSAP_TRUE; + else if((chNum == CHANNEL_1) || + (chNum == CHANNEL_6) || + (chNum == CHANNEL_11)) + return eSAP_TRUE; + + return eSAP_FALSE; +} + +/*========================================================================== + FUNCTION sapSelectChannel + + DESCRIPTION + Runs a algorithm to select the best channel to operate in based on BSS + rssi and bss count on each channel + + DEPENDENCIES + NA. + + PARAMETERS + + IN + halHandle : Pointer to HAL handle + pResult : Pointer to tScanResultHandle + + RETURN VALUE + v_U8_t : Success - channel number, Fail - zero + + SIDE EFFECTS +============================================================================*/ +v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResultHandle pScanResult) +{ + // DFS param object holding all the data req by the algo + tSapChSelSpectInfo oSpectInfoParams = {NULL,0}; + tSapChSelSpectInfo *pSpectInfoParams = &oSpectInfoParams; // Memory? NB + v_U8_t bestChNum = SAP_CHANNEL_NOT_SELECTED; +#ifdef FEATURE_WLAN_CH_AVOID + v_U8_t i; + v_U8_t firstSafeChannelInRange = SAP_CHANNEL_NOT_SELECTED; +#endif +#ifdef SOFTAP_CHANNEL_RANGE + v_U32_t startChannelNum; + v_U32_t endChannelNum; + v_U32_t operatingBand = 0; + v_U32_t tmpChNum; + v_U8_t count; + eChannelWidthInfo chWidth; +#endif + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch Select", __func__); + +#ifdef FEATURE_WLAN_CH_AVOID + sapUpdateUnsafeChannelList(); +#endif + + if (NULL == pScanResult) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: No external AP present\n", __func__); + +#ifndef SOFTAP_CHANNEL_RANGE + return bestChNum; +#else + //scan is successfull, but no AP is present + switch (pSapCtx->scanBandPreference) + { + case eCSR_BAND_24: + startChannelNum = 1; + endChannelNum = 11; + break; + + case eCSR_BAND_5G: + startChannelNum = 36; + endChannelNum = 165; + break; + + case eCSR_BAND_ALL: + default: + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: start - end: %d - %d\n", __func__, + startChannelNum, endChannelNum); + +#ifndef FEATURE_WLAN_CH_AVOID /* FEATURE_WLAN_CH_AVOID NOT defined case*/ + // pick the first channel in configured range + return startChannelNum; +#else /* FEATURE_WLAN_CH_AVOID defined */ + + // any safe channels in the configured range? + for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) + { + if((safeChannels[i].channelNumber >= startChannelNum) && + (safeChannels[i].channelNumber <= endChannelNum)) + { + if (safeChannels[i].isSafe == VOS_TRUE) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: channel %d in the configuration is safe\n", __func__, + safeChannels[i].channelNumber); + firstSafeChannelInRange = safeChannels[i].channelNumber; + break; + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: channel %d in the configuration is unsafe\n", __func__, + safeChannels[i].channelNumber); + } + } + + // preference is given to channels in the configured range which are safe + // if there is not such one, then we return start channel in the configuration + if (firstSafeChannelInRange != SAP_CHANNEL_NOT_SELECTED) + return firstSafeChannelInRange; + else + return startChannelNum; +#endif /* !FEATURE_WLAN_CH_AVOID */ +#endif /* SOFTAP_CHANNEL_RANGE */ + } + + // Initialize the structure pointed by pSpectInfoParams + if (sapChanSelInit( halHandle, pSpectInfoParams, pSapCtx ) != eSAP_TRUE ) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, Ch Select initialization failed", __func__); + return SAP_CHANNEL_NOT_SELECTED; + } + + // Compute the weight of the entire spectrum in the operating band + sapComputeSpectWeight( pSpectInfoParams, halHandle, pScanResult); + +#ifdef SOFTAP_CHANNEL_RANGE + if (eCSR_BAND_ALL == pSapCtx->scanBandPreference) + { + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + &startChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + &endChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + &operatingBand); + } + else + { + if (eCSR_BAND_24 == pSapCtx->currentPreferredBand) + { + startChannelNum = rfChannels[RF_CHAN_1].channelNum; + endChannelNum = rfChannels[RF_CHAN_14].channelNum; + operatingBand = eSAP_RF_SUBBAND_2_4_GHZ; + } + else + { + startChannelNum = rfChannels[RF_CHAN_36].channelNum; + endChannelNum = rfChannels[RF_CHAN_165].channelNum; + operatingBand = RF_BAND_5_GHZ; + } + } + + pSapCtx->acsBestChannelInfo.channelNum = 0; + pSapCtx->acsBestChannelInfo.weight = CFG_ACS_BAND_SWITCH_THRESHOLD_MAX; + /* find the channel width info */ + chWidth = sapGetChannelWidthInfo(halHandle, pSapCtx, operatingBand, pSapCtx->csrRoamProfile.phyMode); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, chWidth=%u", __func__, chWidth); + + /* Sort the channel list as per the computed weights, lesser weight first.*/ + sapSortChlWeightAll(pSapCtx, pSpectInfoParams, chWidth, operatingBand); + + /*Loop till get the best channel in the given range */ + for (count=0; count < pSpectInfoParams->numSpectChans ; count++) + { + if ((startChannelNum <= pSpectInfoParams->pSpectCh[count].chNum)&& + (endChannelNum >= pSpectInfoParams->pSpectCh[count].chNum)) + { + if (bestChNum == SAP_CHANNEL_NOT_SELECTED) + { + bestChNum = pSpectInfoParams->pSpectCh[count].chNum; + /* check if bestChNum is in preferred channel list */ + bestChNum = sapSelectPreferredChannelFromChannelList( + bestChNum, pSapCtx, pSpectInfoParams); + if (bestChNum == SAP_CHANNEL_NOT_SELECTED) + { + /* not in preferred channel list, go to next best channel*/ + continue; + } + + if (pSpectInfoParams->pSpectCh[count].weight_copy > + pSapCtx->acsBandSwitchThreshold) + { + /* the best channel exceeds the threshold + check if need to scan next band */ + if ((eCSR_BAND_ALL != pSapCtx->scanBandPreference) && + !pSapCtx->allBandScanned) + { + /* store best channel for later comparison */ + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight; + bestChNum = SAP_CHANNEL_NOT_SELECTED; + break; + } + else + { + /* all bands are scanned, compare current best channel + with channel scanned previously */ + if ( pSpectInfoParams->pSpectCh[count].weight_copy > + pSapCtx->acsBestChannelInfo.weight) + { + /* previous stored channel is better */ + bestChNum = pSapCtx->acsBestChannelInfo.channelNum; + } + else + { + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight_copy; + } + } + } + else + { + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight_copy; + } + } + + if (bestChNum != SAP_CHANNEL_NOT_SELECTED) + { + if (operatingBand == RF_SUBBAND_2_4_GHZ) + { + /* Give preference to Non-overlap channels */ + if (sapFilterOverLapCh(pSapCtx, + pSpectInfoParams->pSpectCh[count].chNum) && + (pSpectInfoParams->pSpectCh[count].weight_copy <= + pSapCtx->acsBestChannelInfo.weight)) + { + tmpChNum = pSpectInfoParams->pSpectCh[count].chNum; + tmpChNum = sapSelectPreferredChannelFromChannelList( + tmpChNum, pSapCtx, pSpectInfoParams); + if ( tmpChNum != SAP_CHANNEL_NOT_SELECTED) + { + bestChNum = tmpChNum; + break; + } + } + } + } + } + } +#else + // Sort the channel list as per the computed weights, lesser weight first. + sapSortChlWeightAll(pSapCtx, halHandle, pSpectInfoParams); + // Get the first channel in sorted array as best 20M Channel + bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[0].chNum; + //Select Best Channel from Channel List if Configured + bestChNum = sapSelectPreferredChannelFromChannelList(bestChNum, + pSapCtx, pSpectInfoParams); +#endif + + /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */ + if ((operatingBand == RF_SUBBAND_2_4_GHZ) && (chWidth == CHWIDTH_HT40) && + (bestChNum >= 5) && (bestChNum <= 7)) { + int weight_below, weight_above, i; + tSmeConfigParams *pSmeConfig; + tSapSpectChInfo *pSpectInfo; + + weight_below = weight_above = ACS_WEIGHT_MAX; + pSpectInfo = pSpectInfoParams->pSpectCh; + + for (i = 0; i < pSpectInfoParams->numSpectChans ; i++) { + if (pSpectInfo[i].chNum == (bestChNum - 4)) + weight_below = pSpectInfo[i].weight; + + if (pSpectInfo[i].chNum == (bestChNum + 4)) + weight_above = pSpectInfo[i].weight; + } + + pSmeConfig = vos_mem_malloc(sizeof(*pSmeConfig)); + if (NULL != pSmeConfig) { + sme_GetConfigParam(halHandle, pSmeConfig); + + if (weight_below < weight_above) + pSmeConfig->csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else + pSmeConfig->csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + + sme_UpdateConfig(halHandle, pSmeConfig); + vos_mem_free(pSmeConfig); + } + } + + // Free all the allocated memory + sapChanSelExit(pSpectInfoParams); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch select Completed, Ch=%d", + __func__, bestChNum); + if (bestChNum > 0 && bestChNum <= 252) + return bestChNum; + else + return SAP_CHANNEL_NOT_SELECTED; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.h b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.h new file mode 100644 index 0000000000000..9f037eeaf5e2f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapChSelect.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SAP_CH_SELECT_H ) +#define __SAP_CH_SELECT_H + +/*=========================================================================== + + s a p C h S e l e c t . h + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions for channel selection. + + DEPENDENCIES: + + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- ----- -------------------------------------------------------- +2010-03-15 SoftAP Created module + +===========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files +------------------------------------------------------------------------*/ +#include "aniGlobal.h" +/*-------------------------------------------------------------------------- + defines and enum +--------------------------------------------------------------------------*/ + +#define SPECT_24GHZ_CH_COUNT (11) // USA regulatory domain +#define SAPDFS_NORMALISE_1000 (1000/9) // Case of spec20 with channel diff = 0 +/* Gen 5 values +#define SOFTAP_MIN_RSSI (-85) +#define SOFTAP_MAX_RSSI (-45) +*/ +#define SOFTAP_MIN_RSSI (-100) +#define SOFTAP_MAX_RSSI (0) +#define SOFTAP_MIN_COUNT (0) +#define SOFTAP_MAX_COUNT (60) +#define SOFTAP_RSSI_WEIGHT (20) +#define SOFTAP_COUNT_WEIGHT (20) + +#define SAP_DEFAULT_CHANNEL (6) +#define SAP_DEFAULT_5GHZ_CHANNEL (40) +#define SAP_CHANNEL_NOT_SELECTED (0) + +#define SOFTAP_HT20_CHANNELWIDTH 0 +#define SAP_SUBBAND1_RSSI_EFFECT_PRIMARY (-20) // In HT40/VHT80, Effect of primary Channel RSSi on Subband1 +#define SAP_SUBBAND2_RSSI_EFFECT_PRIMARY (-30) // In VHT80, Effect of primary Channel RSSI on Subband2 +#define SAP_SUBBAND3_RSSI_EFFECT_PRIMARY (-40) // In VHT80, Effect of Primary Channel RSSI on Subband3 + +#define SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-10) // In 2.4GHZ, Effect of Primary Channel RSSI on First Overlapping Channel +#define SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-20) // In 2.4GHZ, Effect of Primary Channel RSSI on Second Overlapping Channel +#define SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-30) // In 2.4GHZ, Effect of Primary Channel RSSI on Third Overlapping Channel +#define SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-40) // In 2.4GHZ, Effect of Primary Channel RSSI on Fourth Overlapping Channel + +typedef enum +{ + CHANNEL_1 = 1, + CHANNEL_2, + CHANNEL_3, + CHANNEL_4, + CHANNEL_5, + CHANNEL_6, + CHANNEL_7, + CHANNEL_8, + CHANNEL_9, + CHANNEL_10, + CHANNEL_11, + CHANNEL_12, + CHANNEL_13, + CHANNEL_14 +} tSapChannel; + +#define MAX_80MHZ_BANDS 6 +#define SAP_80MHZ_MASK 0x0F +#define SAP_40MHZ_MASK_L 0x03 +#define SAP_40MHZ_MASK_H 0x0C + +/* + * structs for holding channel bonding bitmap + * used for finding new channel when SAP is on + * DFS channel and radar is detected. + */ +typedef struct sChannelBondingInfo { + v_U8_t channelMap:4; + v_U8_t rsvd:4; + v_U8_t startChannel; +} tChannelBondingInfo; + +typedef struct __chan_bonding_bitmap { + tChannelBondingInfo chanBondingSet[MAX_80MHZ_BANDS]; +} chan_bonding_bitmap; + +/** +* Structure holding information of each channel in the spectrum, +* it contains the channel number, the computed weight +*/ +typedef struct sChannelInfo { + v_U8_t channel; + v_BOOL_t valid; // if the channel is valid to be picked as new channel +} tChannelInfo; + +typedef struct sAll5GChannelList{ + v_U8_t numChannel; + tChannelInfo *channelList; +} tAll5GChannelList; + +typedef struct sSapChannelListInfo{ + v_U8_t numChannel; + v_U8_t *channelList; +} tSapChannelListInfo; + +typedef struct { + v_U16_t chNum; // Channel Number + v_U16_t channelWidth; // Channel Width + v_U16_t bssCount; // bss found in scanresult for this channel + v_S31_t rssiAgr; // Max value of rssi among all BSS(es) from scanresult for this channel + v_U32_t weight; // Weightage of this channel + v_U32_t weight_copy; //copy of the orignal weight + v_BOOL_t valid; // Is this a valid center frequency for regulatory domain +} tSapSpectChInfo;//tDfsSpectChInfo; + +/** +* Structure holding all the information required to make a +* decision for the best operating channel based on dfs formula +*/ + +typedef struct { + tSapSpectChInfo *pSpectCh;//tDfsSpectChInfo *pSpectCh; // Ptr to the channels in the entire spectrum band + v_U8_t numSpectChans; // Total num of channels in the spectrum +} tSapChSelSpectInfo;//tDfsChSelParams; + +/** + * Structure for channel weight calculation parameters + */ +typedef struct sSapChSelParams { + void *pSpectInfoParams;//*pDfsParams; // Filled with tSapChSelSpectInfo + v_U16_t numChannels; +} tSapChSelParams; + +#define SAP_TX_LEAKAGE_THRES 310 +#define SAP_TX_LEAKAGE_MAX 1000 +#define SAP_TX_LEAKAGE_MIN 200 + +typedef struct sSapTxLeakInfo { + v_U8_t leak_chan; /* leak channel */ + v_U32_t leak_lvl; /* tx leakage lvl */ +} tSapTxLeakInfo; + +typedef struct sSapChanMatrixInfo { + v_U8_t channel; /* channel to switch from */ +#ifdef FEATURE_WLAN_CH144 + tSapTxLeakInfo chan_matrix[RF_CHAN_144 - RF_CHAN_36 + 1]; +#else + tSapTxLeakInfo chan_matrix[RF_CHAN_140 - RF_CHAN_36 + 1]; +#endif +} tSapChanMatrixInfo; + +#endif // if !defined __SAP_CH_SELECT_H diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm.c b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm.c new file mode 100644 index 0000000000000..4cbdf80c16cec --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm.c @@ -0,0 +1,4667 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p F s m . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP Finite + State Machine modules + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 Created module + +===========================================================================*/ + + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "sapInternal.h" +// Pick up the SME API definitions +#include "sme_Api.h" +// Pick up the PMC API definitions +#include "pmcApi.h" +#include "wlan_nv.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_CH_AVOID +extern sapSafeChannelType safeChannels[]; +#endif /* FEATURE_WLAN_CH_AVOID */ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION +/* + * TODO: At present SAP Channel leakage matrix for ch 144 + * is not available from system's team. So to play it safe + * and avoid crash if channel 144 is request, in following + * matix channel 144 is added such that it will cause code + * to avoid selecting channel 144. + * + * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS + * PROVIDED BY SYSTEM'S TEAM. + */ +/* channel tx leakage table - ht80 */ +tSapChanMatrixInfo ht80_chan[] = +{ + {52, + {{36, 148}, {40, 199}, + {44, 193}, {48, 197}, + {52, SAP_TX_LEAKAGE_MIN}, {56, 153}, + {60, 137}, {64, 134}, + {100, 358}, {104, 350}, + {108, 404}, {112, 344}, + {116, 424}, {120, 429}, + {124, 437}, {128, 435}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + + {56, + {{36, 171}, {40, 178}, + {44, 171}, {48, 178}, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, SAP_TX_LEAKAGE_MIN}, {64, 280}, + {100, 351}, {104, 376}, + {108, 362}, {112, 362}, + {116, 403}, {120, 397}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {60, + {{36, 156}, {40, 146}, + {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN}, + {52, 180}, {56, SAP_TX_LEAKAGE_MIN}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 376}, {104, 360}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, 395}, {120, 399}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {64, + {{36, 217}, {40, 221}, + {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN}, + {52, 176}, {56, 176}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 384}, {104, 390}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, 375}, {120, 374}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {100, + {{36, 357}, {40, 326}, + {44, 321}, {48, 326}, + {52, 378}, {56, 396}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN}, + {108, 196}, {112, 116}, + {116, 166}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {104, + {{36, 325}, {40, 325}, + {44, 305}, {48, 352}, + {52, 411}, {56, 411}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN}, + {108, SAP_TX_LEAKAGE_MIN},{112, 460}, + {116, 198}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {108, + {{36, 304}, {40, 332}, + {44, 310}, {48, 335}, + {52, 431}, {56, 391}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 280}, {104, SAP_TX_LEAKAGE_MIN}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 185}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {112, + {{36, 327}, {40, 335}, + {44, 331}, {48, 345}, + {52, 367}, {56, 401}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 131}, {104, 132}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 189}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {116, + {{36, 384}, {40, 372}, + {44, 389}, {48, 396}, + {52, 348}, {56, 336}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 172}, {104, 169}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {120, + {{36, 395}, {40, 419}, + {44, 439}, {48, 407}, + {52, 321}, {56, 334}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 134}, {104, 186}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, 159}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {124, + {{36, 469}, {40, 433}, + {44, 434}, {48, 435}, + {52, 332}, {56, 345}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 146}, {104, 177}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 350}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, 138}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {128, + {{36, 408}, {40, 434}, + {44, 449}, {48, 444}, + {52, 341}, {56, 374}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 205}, {104, 208}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 142}, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {132, + {{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX }, + {44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX }, + {52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX }, + {60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN }, + {100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN }, + {108, SAP_TX_LEAKAGE_MIN }, {112, SAP_TX_LEAKAGE_MIN }, + {116, SAP_TX_LEAKAGE_MIN },{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN } +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {136, + {{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX }, + {44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX }, + {52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX }, + {60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN }, + {100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN }, + {108, SAP_TX_LEAKAGE_MIN },{112, SAP_TX_LEAKAGE_MIN }, + {116, SAP_TX_LEAKAGE_MIN }, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN } +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {140, + {{36, SAP_TX_LEAKAGE_MAX }, {40, SAP_TX_LEAKAGE_MAX }, + {44, SAP_TX_LEAKAGE_MAX }, {48, SAP_TX_LEAKAGE_MAX }, + {52, SAP_TX_LEAKAGE_MAX }, {56, SAP_TX_LEAKAGE_MAX }, + {60, SAP_TX_LEAKAGE_MIN }, {64, SAP_TX_LEAKAGE_MIN }, + {100, SAP_TX_LEAKAGE_MIN },{104, SAP_TX_LEAKAGE_MIN }, + {108, SAP_TX_LEAKAGE_MIN },{112, SAP_TX_LEAKAGE_MIN }, + {116, SAP_TX_LEAKAGE_MIN }, {120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, +}; + +/* channel tx leakage table - ht40 */ +tSapChanMatrixInfo ht40_chan[] = +{ + {52, + {{36, 328}, {40, 328 }, + {44, 230}, {48, 230 }, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, 323}, {64, 323 }, + {100, 625}, {104, 323 }, + {108, 646},{112, 646 }, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {56, + {{36, 446}, {40, 446 }, + {44, 300}, {48, 300 }, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 611},{104, 611 }, + {108, 617},{112, 617 }, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {60, + {{36, 481}, {40, 481 }, + {44, 407}, {48, 407 }, + {52, 190}, {56, 190}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 608},{104, 608 }, + {108, 623},{112, 623 }, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {64, + {{36, 524}, {40, 524 }, + {44, 527}, {48, 527 }, + {52, 295}, {56, 295 }, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 594}, {104, 594 }, + {108, 625},{112, 625 }, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {100, + {{36, 618}, {40, 618 }, + {44, 604}, {48, 604 }, + {52, 596}, {56, 596 }, + {60, 584}, {64, 584 }, + {100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN }, + {108, 299}, {112, 299 }, + {116, 486}, {120, 486 }, + {124, 498}, {128, 498 }, + {132, 538}, {136, 538 }, + {140, 598} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {104, + {{36, 636}, {40, 636 }, + {44, 601}, {48, 601 }, + {52, 616}, {56, 616 }, + {60, 584}, {64, 584 }, + {100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 396},{120, 396 }, + {124, 483}, {128, 483 }, + {132, 553}, {136, 553 }, + {140, 568} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {108, + {{36, 600}, {40, 600 }, + {44, 627}, {48, 627 }, + {52, 611}, {56, 611 }, + {60, 611}, {64, 611 }, + {100, 214},{104, 214}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 323},{120, 323}, + {124, 494},{128, 494}, + {132, 566},{136, 566 }, + {140, 534} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {112, + {{36, 645}, {40, 645 }, + {44, 641}, {48, 641 }, + {52, 618}, {56, 618 }, + {60, 612}, {64, 612 }, + {100, 293},{104, 293}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, 414},{128, 414}, + {132, 533},{136, 533 }, + {140, 521} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {116, + {{36, 661}, {40, 661 }, + {44, 624}, {48, 624 }, + {52, 634}, {56, 634 }, + {60, 611}, {64, 611 }, + {100, 371},{104, 371}, + {108, 217},{112, 217 }, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, 309},{128, 309 }, + {132, 412},{136, 412}, + {140, 509} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {120, + {{36, 667}, {40, 667 }, + {44, 645}, {48, 645 }, + {52, 633}, {56, 633 }, + {60, 619}, {64, 619 }, + {100, 467}, {104, 467}, + {108, 291},{112, 291}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, 434},{136, 434}, + {140, 514} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {124, + {{36, 676}, {40, 676 }, + {44, 668}, {48, 668 }, + {52, 595}, {56, 595 }, + {60, 622}, {64, 622 }, + {100, 494}, {104, 494}, + {108, 393},{112, 393}, + {116, 225},{120, 225}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, 327},{136, 327}, + {140, 468} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {128, + {{36, 678}, {40, 678 }, + {44, 664}, {48, 664 }, + {52, 651}, {56, 651 }, + {60, 643}, {64, 643 }, + {100, 502}, {104, 502 }, + {108, 503},{112, 503}, + {116, 293},{120, 293}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, 415} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {132, + {{36, 689}, {40, 689 }, + {44, 669}, {48, 669 }, + {52, 662}, {56, 662 }, + {60, 609}, {64, 609 }, + {100, 538},{104, 538 }, + {108, 534}, {112, 534 }, + {116, 428},{120, 428}, + {124, 247},{128, 247}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN } +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {136, + {{36, 703}, {40, 703 }, + {44, 688}, {48, SAP_TX_LEAKAGE_MIN }, + {52, 671}, {56, 671 }, + {60, 658}, {64, 658 }, + {100, 504},{104, 504 }, + {108, 513},{112, 513 }, + {116, 428}, {120, 428}, + {124, 289},{128, 289}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN } +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {140, + {{36, 695}, {40, 695 }, + {44, 684}, {48, 684 }, + {52, 664}, {56, 664 }, + {60, 658}, {64, 658 }, + {100, 601},{104, 601 }, + {108, 545},{112, 545 }, + {116, 529}, {120, 529}, + {124, 432},{128, 432}, + {132, 262},{136, 262}, + {140, SAP_TX_LEAKAGE_MIN } +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, +}; + + +/* channel tx leakage table - ht20 */ +tSapChanMatrixInfo ht20_chan[] = +{ + {52, + {{36, 398}, {40, 286}, + {44, 225}, {48, 121}, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, 300}, {64, 335}, + {100, 637}, {104, SAP_TX_LEAKAGE_MAX}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {56, + {{36, 468}, {40, 413}, + {44, 374}, {48, 206}, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {60, + {{36, 507}, {40, 440}, + {44, 431}, {48, 313}, + {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {64, + {{36, 516}, {40, 520}, + {44, 506}, {48, 424}, + {52, 301}, {56, 258}, + {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN}, + {100, 620}, {104, 617}, + {108, SAP_TX_LEAKAGE_MAX},{112, SAP_TX_LEAKAGE_MAX}, + {116, SAP_TX_LEAKAGE_MAX},{120, SAP_TX_LEAKAGE_MAX}, + {124, SAP_TX_LEAKAGE_MAX},{128, SAP_TX_LEAKAGE_MAX}, + {132, SAP_TX_LEAKAGE_MAX},{136, SAP_TX_LEAKAGE_MAX}, + {140, SAP_TX_LEAKAGE_MAX} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {100, + {{36, 616}, {40, 601}, + {44, 604}, {48, 589}, + {52, 612}, {56, 592}, + {60, 590}, {64, 582}, + {100, SAP_TX_LEAKAGE_MIN},{104, 131}, + {108, 327}, {112, 380}, + {116, 462}, {120, 522}, + {124, 571}, {128, 589}, + {132, 593}, {136, 598}, + {140, 594} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {104, + {{36, 622}, {40, 624}, + {44, 618}, {48, 610}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, SAP_TX_LEAKAGE_MIN},{104, SAP_TX_LEAKAGE_MIN}, + {108, SAP_TX_LEAKAGE_MIN},{112, 463}, + {116, 483},{120, 503}, + {124, 523}, {128, 565}, + {132, 570}, {136, 588}, + {140, 585} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {108, + {{36, 620}, {40, 638}, + {44, 611}, {48, 614}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 477},{104, SAP_TX_LEAKAGE_MIN}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, 477},{120, 497}, + {124, 517},{128, 537}, + {132, 557},{136, 577}, + {140, 603} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {112, + {{36, 636}, {40, 623}, + {44, 638}, {48, 628}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, 606}, + {100, 501},{104, 481}, + {108, SAP_TX_LEAKAGE_MIN},{112, SAP_TX_LEAKAGE_MIN}, + {116, SAP_TX_LEAKAGE_MIN},{120, 481}, + {124, 501},{128, 421}, + {132, 541},{136, 561}, + {140, 583} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {116, + {{36, 646}, {40, 648}, + {44, 633}, {48, 634}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, 615}, {64, 594}, + {100, 575},{104, 554}, + {108, 534},{112, SAP_TX_LEAKAGE_MIN}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, 534},{136, 554}, + {140, 574} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {120, + {{36, 643}, {40, 649}, + {44, 654}, {48, 629}, + {52, SAP_TX_LEAKAGE_MAX}, {56, 621}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 565}, {104, 545}, + {108, 525},{112, 505}, + {116, SAP_TX_LEAKAGE_MIN},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, 505}, + {132, 525},{136, 545}, + {140, 565} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {124, + {{36, 638}, {40, 657}, + {44, 663}, {48, 649}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 581}, {104, 561}, + {108, 541},{112, 521}, + {116, 499},{120, SAP_TX_LEAKAGE_MIN}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, 499},{136, 519}, + {140, 539} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {128, + {{36, 651}, {40, 651}, + {44, 674}, {48, 640}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, 603}, {104, 560}, + {108, 540},{112, 520}, + {116, 499},{120, 479}, + {124, SAP_TX_LEAKAGE_MIN},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, 479}, + {140, 499} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {132, + {{36, 643}, {40, 668}, + {44, 651}, {48, 657}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, SAP_TX_LEAKAGE_MAX},{104, 602}, + {108, 578}, {112, 570}, + {116, 550},{120, 530}, + {124, 510},{128, SAP_TX_LEAKAGE_MIN}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, 490} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {136, + {{36, 654}, {40, 667}, + {44, 666}, {48, 642}, + {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX}, + {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX}, + {100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX}, + {108, SAP_TX_LEAKAGE_MAX},{112, 596}, + {116, 555}, {120, 535}, + {124, 515},{128, 495}, + {132, SAP_TX_LEAKAGE_MIN},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, + + {140, + {{36, 679}, {40, 673}, + {44, 667}, {48, 656}, + {52, 634}, {56, 663}, + {60, 662}, {64, 660}, + {100, SAP_TX_LEAKAGE_MAX},{104, SAP_TX_LEAKAGE_MAX}, + {108, SAP_TX_LEAKAGE_MAX},{112, 590}, + {116, 573}, {120, 553}, + {124, 533},{128, 513}, + {132, 490},{136, SAP_TX_LEAKAGE_MIN}, + {140, SAP_TX_LEAKAGE_MIN} +#ifdef FEATURE_WLAN_CH144 + ,{144, SAP_TX_LEAKAGE_MIN} +#endif +}}, +}; +#endif //end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ +#ifdef SOFTAP_CHANNEL_RANGE +static VOS_STATUS sapGetChannelList(ptSapContext sapContext, v_U8_t **channelList, + v_U8_t *numberOfChannels); +#endif + +/*========================================================================== + FUNCTION sapGet5GHzChannelList + + DESCRIPTION + Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available + channels in the current regulatory domain. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext: SAP Context + + RETURN VALUE + NA + + SIDE EFFECTS +============================================================================*/ +static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext); + +/*========================================================================== + FUNCTION sapStopDfsCacTimer + + DESCRIPTION + Function to sttop the DFS CAC timer when SAP is stopped + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext: SAP Context + RETURN VALUE + DFS Timer start status + SIDE EFFECTS +============================================================================*/ + +static int sapStopDfsCacTimer(ptSapContext sapContext); + +/*========================================================================== + FUNCTION sapStartDfsCacTimer + + DESCRIPTION + Function to start the DFS CAC timer when SAP is started on DFS Channel + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext: SAP Context + RETURN VALUE + DFS Timer start status + SIDE EFFECTS +============================================================================*/ + +int sapStartDfsCacTimer(ptSapContext sapContext); + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION sapEventInit + + DESCRIPTION + Function for initializing sWLAN_SAPEvent structure + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapEvent : State machine event + + RETURN VALUE + + None + + SIDE EFFECTS +============================================================================*/ +static inline void sapEventInit(ptWLAN_SAPEvent sapEvent) +{ + sapEvent->event = eSAP_MAC_SCAN_COMPLETE; + sapEvent->params = 0; + sapEvent->u1 = 0; + sapEvent->u2 = 0; +} + +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION +/* + * This function gives the leakage matrix for given NOL channel and cbMode + * + * PARAMETERS + * IN + * sapContext : Pointer to vos global context structure + * cbMode : target channel bonding mode + * NOL_channel : the NOL channel whose leakage matrix is required + * pTarget_chnl_mtrx : pointer to target channel matrix returned. + * + * RETURN VALUE + * BOOLEAN + * TRUE: leakage matrix was found + * FALSE: leakage matrix was not found + */ +v_BOOL_t +sapFindTargetChannelInChannelMatrix(ptSapContext sapContext, + ePhyChanBondState cbMode, + v_U8_t NOL_channel, + tSapTxLeakInfo **pTarget_chnl_mtrx) +{ + tSapTxLeakInfo *target_chan_matrix = NULL; + tSapChanMatrixInfo *pchan_matrix = NULL; + v_U32_t nchan_matrix; + int i = 0; + + switch (cbMode) { + case PHY_SINGLE_CHANNEL_CENTERED: + /* HT20 */ + pchan_matrix = ht20_chan; + nchan_matrix = sizeof(ht20_chan)/sizeof(tSapChanMatrixInfo); + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + /* HT40 */ + pchan_matrix = ht40_chan; + nchan_matrix = sizeof(ht40_chan)/sizeof(tSapChanMatrixInfo); + break; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + /* HT80 */ + pchan_matrix = ht80_chan; + nchan_matrix = sizeof(ht80_chan)/sizeof(tSapChanMatrixInfo); + break; +#endif + default: + /* handle exception and fall back to HT20 table */ + pchan_matrix = ht20_chan; + nchan_matrix = sizeof(ht20_chan)/sizeof(tSapChanMatrixInfo); + break; + } + + for (i = 0; i < nchan_matrix; i++) + { + /* find the SAP channel to map the leakage matrix */ + if (NOL_channel == pchan_matrix[i].channel) + { + target_chan_matrix = pchan_matrix[i].chan_matrix; + break; + } + } + + if (NULL == target_chan_matrix) + { + return VOS_FALSE; + } else { + *pTarget_chnl_mtrx = target_chan_matrix; + return VOS_TRUE; + } +} + +/* + * This function removes the channels from temp channel list that + * (if selected as target channel) will cause leakage in one of + * the NOL channels + * + * PARAMETERS + * IN + * sapContext : Pointer to vos global context structure + * cbMode : target channel bonding mode + * pNol : DFS NOL + * pTempChannelList : the target channel list + * + * RETURN VALUE + * VOS_STATUS code associated with performing the operation + */ + +VOS_STATUS +sapMarkChannelsLeakingIntoNOL(ptSapContext sapContext, + ePhyChanBondState cbMode, + tSapDfsNolInfo *pNol, + v_U8_t tempChannelListSize, + v_U8_t *pTempChannelList) +{ + tSapTxLeakInfo *target_chan_matrix = NULL; +#ifdef FEATURE_WLAN_CH144 + v_U32_t num_channel = (RF_CHAN_144 - RF_CHAN_36) + 1; +#else + v_U32_t num_channel = (RF_CHAN_140 - RF_CHAN_36) + 1; +#endif + v_U32_t i = 0; + v_U32_t j = 0; + v_U32_t k = 0; + v_U8_t dfs_nol_channel; + + + /* traverse target_chan_matrix and */ + for (i = 0; i < NUM_5GHZ_CHANNELS ; i++) { + dfs_nol_channel = pNol[i].dfs_channel_number; + if ( pNol[i].radar_status_flag == eSAP_DFS_CHANNEL_USABLE || + pNol[i].radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE ) { + /* not present in NOL */ + continue; + } + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, + FL("sapdfs: processing NOL channel: %d"), + dfs_nol_channel ); + if (VOS_FALSE == sapFindTargetChannelInChannelMatrix(sapContext, + cbMode, + dfs_nol_channel, + &target_chan_matrix)) + { + /* + * should never happen, we should always find a table here, + * if we don't, need a fix here! + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Couldn't find target channel matrix!")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* + * following is based on assumption that both pTempChannelList + * and target channel matrix are in increasing order of channelID + */ + for (j = 0, k = 0; j < tempChannelListSize && + k < num_channel; ) { + if (pTempChannelList[j] == 0) { + j++; + } else { + if (target_chan_matrix[k].leak_chan != pTempChannelList[j]) { + k++; + } else { + /* check leakage from candidate channel to NOL channel */ + if (target_chan_matrix[k].leak_lvl <= SAP_TX_LEAKAGE_THRES) + { + /* + * this means that candidate channel will have bad + * leakage in NOL channel, remove the candidate channel + * from temp list + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: channel: %d will have bad leakage" + " due to channel: %d\n"), + dfs_nol_channel, + pTempChannelList[j]); + pTempChannelList[j] = 0; + break; + } + j++; + k++; + } + } + } /* end of for loop checking temp channel list leakage into NOL */ + } /* end of loop that selects each NOL */ + return VOS_STATUS_SUCCESS; +} + +#endif // end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + +/* + * This function adds availabe channel to bitmap + * + * PARAMETERS + * IN + * pBitmap: bitmap to populate + * channel: channel to set in bitmap + */ +static void sapSetBitmap(chan_bonding_bitmap *pBitmap, v_U8_t channel) +{ + int i = 0; + int start_channel = 0; + for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) { + start_channel = pBitmap->chanBondingSet[i].startChannel; + if (channel >= start_channel && channel <= start_channel + 12) { + pBitmap->chanBondingSet[i].channelMap |= + 1 << ((channel - start_channel)/4); + return; + } + } + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Channel=%d is not in the bitmap"), channel); +} + +/* + * This function reads the bitmap and populates available channel + * list according to channel bonding mode. This will be called for + * 80 MHz and 40 Mhz only. For 20 MHz no need for bitmap hence list + * is directly created while parsing the main list + * + * PARAMETERS + * IN + * pBitmap: bitmap to populate + * cbModeCurrent: cb mode to check for channel availability + * availableChannels: available channel list to populate + * + * RETURN VALUE + * number of channels found + */ +static v_U8_t sapPopulateAvailableChannels(chan_bonding_bitmap *pBitmap, + ePhyChanBondState cbModeCurrent, + v_U8_t *availableChannels) +{ + v_U8_t i = 0; + v_U8_t channelCount = 0; + v_U8_t start_channel = 0; + + switch (cbModeCurrent) { +#ifdef WLAN_FEATURE_11AC + /* HT80 */ + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) { + start_channel = pBitmap->chanBondingSet[i].startChannel; + if (pBitmap->chanBondingSet[i].channelMap == SAP_80MHZ_MASK) { + availableChannels[channelCount++] = start_channel; + availableChannels[channelCount++] = start_channel + 4; + availableChannels[channelCount++] = start_channel + 8; + availableChannels[channelCount++] = start_channel + 12; + } + } + break; +#endif + /* HT40 */ + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + for ( i = 0; i < MAX_80MHZ_BANDS; i++ ) { + start_channel = pBitmap->chanBondingSet[i].startChannel; + if ((pBitmap->chanBondingSet[i].channelMap & SAP_40MHZ_MASK_L) + == SAP_40MHZ_MASK_L) { + availableChannels[channelCount++] = start_channel; + availableChannels[channelCount++] = start_channel + 4; + } else { + if ((pBitmap->chanBondingSet[i].channelMap & + SAP_40MHZ_MASK_H) == SAP_40MHZ_MASK_H) { + availableChannels[channelCount++] = start_channel + 8; + availableChannels[channelCount++] = start_channel + 12; + } + } + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Invalid case.")); + break; + } + + return channelCount; +} + +/* + * FUNCTION sapFetchRegulatoryDomain + * + * DESCRIPTION Fetches the Regulatory domain based up on the coutry code. + * + * DEPENDENCIES PARAMETERS + * IN hHAL : HAL pointer + * + * RETURN VALUE : v_REGDOMAIN_t, returns the regulatory domain + * + * SIDE EFFECTS + */ +v_REGDOMAIN_t sapFetchRegulatoryDomain(tHalHandle hHal) +{ + tpAniSirGlobal pMac; + v_COUNTRYCODE_t country_code; + v_REGDOMAIN_t regDomain; + pMac = PMAC_STRUCT(hHal); + + /* + * Fetch the REG DOMAIN from the country code. + */ + country_code[0] = pMac->scan.countryCodeCurrent[0]; + country_code[1] = pMac->scan.countryCodeCurrent[1]; + + vos_nv_getRegDomainFromCountryCode(®Domain, + country_code, COUNTRY_QUERY); + + return regDomain; +} + +/* + * FUNCTION sapDfsIsW53Invalid + * + * DESCRIPTION Checks if the passed channel is W53 and returns if + * SAP W53 opearation is allowed. + * + * DEPENDENCIES PARAMETERS + * IN hHAL : HAL pointer + * channelID: Channel Number to be verified + * + * RETURN VALUE : v_BOOL_t + * VOS_TRUE: If W53 operation is disabled + * VOS_FALSE: If W53 operation is enabled + * + * SIDE EFFECTS + */ +v_BOOL_t sapDfsIsW53Invalid(tHalHandle hHal, v_U8_t channelID) +{ + tpAniSirGlobal pMac; + + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid pMac")); + return VOS_FALSE; + } + + /* + * Check for JAPAN W53 Channel operation capability + */ + if (VOS_TRUE == pMac->sap.SapDfsInfo.is_dfs_w53_disabled && + VOS_TRUE == IS_CHAN_JAPAN_W53(channelID)) + { + return VOS_TRUE; + } + + return VOS_FALSE; +} + +/* + * FUNCTION sapDfsIsChannelInPreferredLocation + * + * DESCRIPTION Checks if the passed channel is in accordance with preferred + * Channel location settings. + * + * DEPENDENCIES PARAMETERS + * IN hHAL : HAL pointer + * channelID: Channel Number to be verified + * + * RETURN VALUE :v_BOOL_t + * VOS_TRUE:If Channel location is same as the preferred location + * VOS_FALSE:If Channel location is not same as the preferred location + * + * SIDE EFFECTS + */ +v_BOOL_t sapDfsIsChannelInPreferredLocation(tHalHandle hHal, v_U8_t channelID) +{ + tpAniSirGlobal pMac; + + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid pMac")); + return VOS_TRUE; + } + if ( (SAP_CHAN_PREFERRED_INDOOR == + pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) && + (VOS_TRUE == IS_CHAN_JAPAN_OUTDOOR(channelID)) ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("CHAN=%d is Outdoor so invalid,preferred Indoor only"), + channelID); + return VOS_FALSE; + } + else if ( (SAP_CHAN_PREFERRED_OUTDOOR == + pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) && + (VOS_TRUE == IS_CHAN_JAPAN_INDOOR(channelID)) ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("CHAN=%d is Indoor so invalid,preferred Outdoor only"), + channelID); + return VOS_FALSE; + } + + return VOS_TRUE; +} + +/* + * This function randomly pick up an AVAILABLE channel + */ +static v_U8_t sapRandomChannelSel(ptSapContext sapContext) +{ + v_U32_t random_byte = 0; + v_U8_t available_chnl_count = 0; + v_U8_t valid_chnl_count = 0; + v_U8_t availableChannels[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,}; + v_U8_t target_channel = 0; + v_BOOL_t isChannelNol = VOS_FALSE; + v_BOOL_t isOutOfRange = VOS_FALSE; + chan_bonding_bitmap channelBitmap; + v_U8_t i = 0; + v_U8_t channelID; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac; + tANI_U32 chanWidth; + ePhyChanBondState cbModeCurrent; + v_REGDOMAIN_t regDomain; + v_U8_t *tempChannels = NULL; + + if (NULL == hHal) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid hHal")); + return target_channel; + } + + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid pMac")); + return target_channel; + } + + /* + * Retrieve the original one and store it. + * use the stored original value when you call this function next time + * so fall back mechanism always starts with original ini value. + */ + if (pMac->sap.SapDfsInfo.orig_cbMode == 0) + { + pMac->sap.SapDfsInfo.orig_cbMode = + pMac->roam.configParam.channelBondingMode5GHz; + cbModeCurrent = pMac->sap.SapDfsInfo.orig_cbMode; + } + else + { + cbModeCurrent = pMac->sap.SapDfsInfo.orig_cbMode; + } + + /* + * Retrieve the original one and store it. + * use the stored original value when you call this function next time + * so fall back mechanism always starts with original ini value. + */ + if (pMac->sap.SapDfsInfo.orig_chanWidth == 0) + { + pMac->sap.SapDfsInfo.orig_chanWidth = + pMac->roam.configParam.nVhtChannelWidth; + chanWidth = pMac->sap.SapDfsInfo.orig_chanWidth; + } + else + { + chanWidth = pMac->sap.SapDfsInfo.orig_chanWidth; + } + + if (sapGet5GHzChannelList(sapContext)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("Getting 5Ghz channel list failed")); + return target_channel; + } + + regDomain = sapFetchRegulatoryDomain(hHal); + + /* + * valid_chnl_count will be used to find number of valid channels + * after following for loop ends + */ + valid_chnl_count = sapContext->SapAllChnlList.numChannel; + /* loop to check ACS range or NOL channels */ + for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++) + { + channelID = sapContext->SapAllChnlList.channelList[i].channel; + + /* + * IN JAPAN REGULATORY DOMAIN CHECK IF THE FOLLOWING TWO + * TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS + * ACCORDINGLY. + * + * 1. If we are operating in Japan regulatory domain + * Check if Japan W53 Channel operation is NOT + * allowed and if its not allowed then mark all the + * W53 channels as Invalid. + * + * 2. If we are operating in Japan regulatory domain + * Check if channel switch between Indoor/Outdoor + * is allowed. If it is not allowed then limit + * the avaiable channels to Indoor or Outdoor + * channels only based up on the SAP Channel location + * indicated by "sap_operating_channel_location" param. + */ + if (REGDOMAIN_JAPAN == regDomain) + { + /* + * Check for JAPAN W53 Channel operation capability + */ + if (VOS_TRUE == sapDfsIsW53Invalid(hHal, channelID)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"), + i, channelID); + sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE; + valid_chnl_count--; + continue; + } + + /* + * If SAP's preferred channel location is Indoor + * then set all the outdoor channels in the domain + * to invalid.If the preferred channel location is + * outdoor then set all the Indoor channels in the + * domain to Invalid. + */ + if (VOS_FALSE == + sapDfsIsChannelInPreferredLocation(hHal, channelID)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("CHAN=%d is invalid,preferred Channel Location %d Only"), + channelID, + pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location); + sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE; + valid_chnl_count--; + continue; + } + } + + if (vos_nv_getChannelEnabledState(channelID) == NV_CHANNEL_DFS) + { + isChannelNol = sapDfsIsChannelInNolList(sapContext, + channelID, + PHY_SINGLE_CHANNEL_CENTERED); + if (VOS_TRUE == isChannelNol) + { + /* + * Mark this channel invalid since it is still in + * DFS Non-Occupancy-Period which is 30 mins. + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("index: %d, Channel = %d Present in NOL"), + i, channelID); + sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE; + valid_chnl_count--; + continue; + } + } + + /* check if the channel is within ACS channel range */ + isOutOfRange = sapAcsChannelCheck(sapContext, + channelID); + if (VOS_TRUE == isOutOfRange) + { + /* + * mark this channel invalid since it is out of ACS channel range + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("index: %d, Channel = %d out of ACS channel range"), + i, channelID); + sapContext->SapAllChnlList.channelList[i].valid = VOS_FALSE; + valid_chnl_count--; + continue; + } + } /* end of check for NOL or ACS channels */ + + /* valid_chnl_count now have number of valid channels */ + tempChannels = vos_mem_malloc(valid_chnl_count); + if (tempChannels == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("sapdfs: memory alloc failed")); + return target_channel; + } + + do + { + v_U8_t j = 0; +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + tSapDfsNolInfo *pNol = pMac->sap.SapDfsInfo.sapDfsChannelNolList; +#endif + + /* prepare temp list of just the valid channels */ + for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++) { + if (sapContext->SapAllChnlList.channelList[i].valid) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("sapdfs: Adding Channel = %d to temp List"), + sapContext->SapAllChnlList.channelList[i].channel); + tempChannels[j++] = + sapContext->SapAllChnlList.channelList[i].channel; + } + } + +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("sapdfs: Processing temp channel list against NOL.")); + if (VOS_STATUS_SUCCESS != sapMarkChannelsLeakingIntoNOL(sapContext, + cbModeCurrent, + pNol, + valid_chnl_count, + tempChannels)) { + vos_mem_free(tempChannels); + return target_channel; + } +#endif + vos_mem_zero(availableChannels, sizeof(availableChannels)); + vos_mem_zero(&channelBitmap, sizeof(channelBitmap)); + channelBitmap.chanBondingSet[0].startChannel = 36; + channelBitmap.chanBondingSet[1].startChannel = 52; + channelBitmap.chanBondingSet[2].startChannel = 100; + channelBitmap.chanBondingSet[3].startChannel = 116; + channelBitmap.chanBondingSet[3].startChannel = 132; + channelBitmap.chanBondingSet[4].startChannel = 149; + /* now loop through whatever is left of channel list */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("sapdfs: Moving temp channel list to final.")); + for (i = 0; i < valid_chnl_count; i++ ){ + /* + * add channel from temp channel list to bitmap or fianl + * channel list (in case of 20MHz width) + */ + if (tempChannels[i] != 0) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, + FL("sapdfs: processing channel: %d "), + tempChannels[i]); + /* for 20MHz, directly create available channel list */ + if (cbModeCurrent == PHY_SINGLE_CHANNEL_CENTERED) { + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_DEBUG, + FL("sapdfs: Channel=%d added to available list"), + tempChannels[i]); + availableChannels[available_chnl_count++] = + tempChannels[i]; + } else { + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_DEBUG, + FL("sapdfs: Channel=%d added to bitmap"), + tempChannels[i]); + sapSetBitmap(&channelBitmap, tempChannels[i]); + } + } + } + + /* if 40 MHz or 80 MHz, populate available channel list from bitmap */ + if (cbModeCurrent != PHY_SINGLE_CHANNEL_CENTERED) { + available_chnl_count = sapPopulateAvailableChannels(&channelBitmap, + cbModeCurrent, + availableChannels); + /* if no valid channel bonding found, fallback to lower bandwidth */ + if (available_chnl_count == 0) { + if (cbModeCurrent >= + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED) { + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:No 80MHz cb found, falling to 40MHz")); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:Changing chanWidth from [%d] to [%d]"), + chanWidth, eHT_CHANNEL_WIDTH_40MHZ); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:Changing CB mode from [%d] to [%d]"), + cbModeCurrent, PHY_DOUBLE_CHANNEL_LOW_PRIMARY); + cbModeCurrent = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + chanWidth = eHT_CHANNEL_WIDTH_40MHZ; + /* continue to start of do loop */ + continue; + } else if (cbModeCurrent >= + PHY_DOUBLE_CHANNEL_LOW_PRIMARY ) { + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:No 40MHz cb found, falling to 20MHz")); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:Changing chanWidth from [%d] to [%d]"), + chanWidth, eHT_CHANNEL_WIDTH_20MHZ); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_WARN, + FL("sapdfs:Changing CB mode from [%d] to [%d]"), + cbModeCurrent, PHY_SINGLE_CHANNEL_CENTERED); + cbModeCurrent = PHY_SINGLE_CHANNEL_CENTERED; + chanWidth = eHT_CHANNEL_WIDTH_20MHZ; + /* continue to start of do loop */ + continue; + } + } + } + + /* + * by now, available channels list will be populated or + * no channels are avaialbe + */ + if (available_chnl_count) { + get_random_bytes(&random_byte, 1); + i = (random_byte + jiffies) % available_chnl_count; + /* Random channel selection from available list */ + target_channel = availableChannels[i]; + pMac->sap.SapDfsInfo.new_chanWidth = chanWidth; + pMac->sap.SapDfsInfo.new_cbMode = cbModeCurrent; + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: New CB mode = %d"), + pMac->sap.SapDfsInfo.new_cbMode); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: New Channel width = %d"), + pMac->sap.SapDfsInfo.new_chanWidth); + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: target_channel = %d"), target_channel); + } + else { + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("No target channel found")); + } + break; + } while(1); /* this loop will iterate at max 3 times */ + + vos_mem_free(tempChannels); + return target_channel; +} + +v_BOOL_t +sapAcsChannelCheck(ptSapContext sapContext, v_U8_t channelNumber) +{ + if (!sapContext->apAutoChannelSelection) + return VOS_FALSE; + + if ((channelNumber < sapContext->apStartChannelNum) || + (channelNumber > sapContext->apEndChannelNum)) + return VOS_TRUE; + + return VOS_FALSE; +} + +/* + * Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE + */ +void sapMarkDfsChannels(ptSapContext sapContext, v_U8_t* channels, + v_U8_t numChannels, v_U64_t time) +{ + int i, j; + tSapDfsNolInfo *psapDfsChannelNolList = NULL; + v_U8_t nRegDomainDfsChannels; + tHalHandle hHal; + tpAniSirGlobal pMac; + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == channels) + return; + + if (NULL == hHal) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid hHal")); + return; + } + + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("invalid pMac")); + return; + } + + /* + * Mark the current channel on which Radar is found + * in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE. + */ + + psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList; + nRegDomainDfsChannels = pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; + + for (i = 0; i < numChannels; i++) { + for (j = 0; j <= nRegDomainDfsChannels; j++) + { + if (psapDfsChannelNolList[j].dfs_channel_number == + channels[i]) + { + /* If channel is already in NOL, don't update it again. + * This is useful when marking bonding channels which are + * already unavailable. + */ + if( psapDfsChannelNolList[j].radar_status_flag == + eSAP_DFS_CHANNEL_UNAVAILABLE) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Channel=%d already in NOL"), + channels[i]); + } + else + { + /* + * Capture the Radar Found timestamp on the Current + * Channel in ms. + */ + psapDfsChannelNolList[j].radar_found_timestamp = time; + /* Mark the Channel to be UNAVAILABLE for next 30 mins */ + psapDfsChannelNolList[j].radar_status_flag = + eSAP_DFS_CHANNEL_UNAVAILABLE; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Channel=%d Added to NOL LIST"), + channels[i]); + } + } + } + } +} + + +/* + * This Function is to get bonding channels from primary channel. + * + */ +v_U8_t sapGetBondingChannels(ptSapContext sapContext, v_U8_t channel, + v_U8_t* channels, v_U8_t size, ePhyChanBondState chanBondState) +{ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac; + v_U8_t numChannel; + + if(channels == NULL) + return 0; + + if(size < MAX_BONDED_CHANNELS) return 0; + + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + return 0; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("cbmode: %d, channel: %d"), + chanBondState, channel); + + switch (chanBondState) { + case PHY_SINGLE_CHANNEL_CENTERED: + numChannel = 1; + channels[0] = channel; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + numChannel = 2; + channels[0] = channel - 4; + channels[1] = channel; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + numChannel = 2; + channels[0] = channel; + channels[1] = channel + 4; + break; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + numChannel = 4; + channels[0] = channel; + channels[1] = channel + 4; + channels[2] = channel + 8; + channels[3] = channel + 12; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + numChannel = 4; + channels[0] = channel - 4; + channels[1] = channel; + channels[2] = channel + 4; + channels[3] = channel + 8; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + numChannel = 4; + channels[0] = channel - 8; + channels[1] = channel - 4; + channels[2] = channel; + channels[3] = channel + 4; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + numChannel = 4; + channels[0] = channel - 12; + channels[1] = channel - 8; + channels[2] = channel - 4; + channels[3] = channel; + break; +#endif + default: + numChannel = 1; + channels[0] = channel; + break; + } + + return numChannel; +} + +/* + * This Function Checks if a given bonded channel is AVAILABLE or USABLE + * for DFS operation. + */ +v_BOOL_t +sapDfsIsChannelInNolList(ptSapContext sapContext, v_U8_t channelNumber, + ePhyChanBondState chanBondState) +{ + int i, j; + v_U64_t timeElapsedSinceLastRadar,timeWhenRadarFound,currentTime = 0; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac; + v_U8_t channels[MAX_BONDED_CHANNELS]; + v_U8_t numChannels; + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return VOS_FALSE; + } + else + { + pMac = PMAC_STRUCT( hHal ); + } + + if ((pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels == 0) || + (pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels > + NUM_5GHZ_CHANNELS)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s: invalid dfs channel count %d", + __func__, + pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels); + return VOS_FALSE; + } + + /* get the bonded channels */ + numChannels = sapGetBondingChannels(sapContext, channelNumber, channels, + MAX_BONDED_CHANNELS, chanBondState ); + + /* check for NOL, first on will break the loop */ + for (j=0; j < numChannels; j++) + { + for (i =0 ; i< pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; i++) + { + if(pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .dfs_channel_number == channels[j]) + { + if ( (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_status_flag == eSAP_DFS_CHANNEL_USABLE) + || + (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE) ) + { + /* + * Allow SAP operation on this channel + * either the DFS channel has not been used + * for SAP operation or it is available for + * SAP operation since it is past Non-Occupancy-Period + * so, return FALSE. + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("Channel = %d not in NOL, CHANNEL AVAILABLE"), + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .dfs_channel_number); + } + else if (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE) + { + /* + * If a DFS Channel is UNAVAILABLE then + * check to see if it is past Non-occupancy-period + * of 30 minutes. If it is past 30 mins then + * mark the channel as AVAILABLE and return FALSE + * as the channel is not anymore in NON-Occupancy-Period. + */ + timeWhenRadarFound = pMac->sap.SapDfsInfo + .sapDfsChannelNolList[i] + .radar_found_timestamp; + currentTime = vos_get_monotonic_boottime(); + timeElapsedSinceLastRadar = currentTime - timeWhenRadarFound; + if (timeElapsedSinceLastRadar >= SAP_DFS_NON_OCCUPANCY_PERIOD) + { + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_found_timestamp = 0; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("Channel=%d not in NOL, CHANNEL AVAILABLE"), + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .dfs_channel_number); + } + else + { + /* + * Channel is not still available for SAP operation + * so return TRUE; As the Channel is still + * in Non-occupancy-Period. + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + FL("Channel=%d still in NOL, CHANNEL UNAVAILABLE"), + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .dfs_channel_number); + break; + } + } + } /* if */ + } /* loop for dfs channels */ + + if (i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) + break; + + } /* loop for bonded channels */ + + /* if any of the channel is not available, mark all available channels as + * unavailable with same time stamp. + */ + if (j < numChannels && + i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) + { + if (numChannels > MAX_BONDED_CHANNELS) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + FL( "numChannels > MAX_BONDED_CHANNELS so resetting")); + numChannels = MAX_BONDED_CHANNELS; + } + sapMarkDfsChannels(sapContext, + channels, + numChannels, + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_found_timestamp); + + /* set DFS-NOL back to keep it update-to-date in CNSS */ + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_SET, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + return VOS_TRUE; + } + + return VOS_FALSE; +} + + +/*========================================================================== + FUNCTION sapGotoChannelSel + + DESCRIPTION + Function for initiating scan request for SME + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoChannelSel +( + ptSapContext sapContext, + ptWLAN_SAPEvent sapEvent +) +{ + /* Initiate a SCAN request */ + eHalStatus halStatus; + tCsrScanRequest scanRequest;/* To be initialised if scan is required */ + v_U32_t scanRequestID = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + +#ifdef SOFTAP_CHANNEL_RANGE + v_U8_t *channelList = NULL; + v_U8_t numOfChannels = 0 ; +#endif + tHalHandle hHal; +#ifndef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 channel; +#endif + + hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, sapContext->pvosGCtx); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + +#ifdef WLAN_FEATURE_MBSSID + if (vos_concurrent_sap_sessions_running()) { + v_U16_t con_sap_ch = sme_GetConcurrentOperationChannel(hHal); + + if (con_sap_ch && sapContext->channel == AUTO_CHANNEL_SELECT) { + sapContext->dfs_ch_disable = VOS_TRUE; + } else if (con_sap_ch && sapContext->channel != con_sap_ch && + VOS_IS_DFS_CH(sapContext->channel)) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "In %s, MCC DFS not supported in AP_AP Mode", __func__); + return VOS_STATUS_E_ABORTED; + } + } +#endif + + if (vos_get_concurrency_mode() == VOS_STA_SAP) + { +#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + if (sapContext->channel == AUTO_CHANNEL_SELECT) + sapContext->dfs_ch_disable = VOS_TRUE; + else if (VOS_IS_DFS_CH(sapContext->channel)) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "In %s, DFS not supported in STA_AP Mode", __func__); + return VOS_STATUS_E_ABORTED; + } +#endif +#ifndef FEATURE_WLAN_MCC_TO_SCC_SWITCH + /* If STA-AP concurrency is enabled take the concurrent connected + * channel first. In other cases wpa_supplicant should take care */ + channel = sme_GetConcurrentOperationChannel(hHal); + if (channel) + { /*if a valid channel is returned then use concurrent channel. + Else take whatever comes from configuartion*/ + sapContext->channel = channel; + sme_SelectCBMode(hHal, + sapConvertSapPhyModeToCsrPhyMode( + sapContext->csrRoamProfile.phyMode), + channel); + } +#endif + } + + if (sapContext->channel == AUTO_CHANNEL_SELECT) + { +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s skip_acs_status = %d ", __func__, + sapContext->skip_acs_scan_status); + if (sapContext->skip_acs_scan_status != eSAP_SKIP_ACS_SCAN) { +#endif + vos_mem_zero(&scanRequest, sizeof(scanRequest)); + + /* Set scanType to Passive scan */ + scanRequest.scanType = eSIR_PASSIVE_SCAN; + + /* Set min and max channel time to zero */ + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + + /* Set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + +#ifndef SOFTAP_CHANNEL_RANGE + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 0; + + scanRequest.ChannelInfo.ChannelList = NULL; + + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + //eCSR_SCAN_REQUEST_11D_SCAN; + +#else + + sapGetChannelList(sapContext, &channelList, &numOfChannels); +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + if (numOfChannels != 0) { +#endif + /*Scan the channels in the list*/ + scanRequest.ChannelInfo.numOfChannels = numOfChannels; + + scanRequest.ChannelInfo.ChannelList = channelList; + + scanRequest.requestType = eCSR_SCAN_SOFTAP_CHANNEL_RANGE; + + sapContext->channelList = channelList; + +#endif + /* Set requestType to Full scan */ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, calling sme_ScanRequest", __func__); +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + if (sapContext->skip_acs_scan_status == eSAP_DO_NEW_ACS_SCAN) { +#endif + sme_ScanFlushResult(hHal, sapContext->sessionId); +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + } +#endif + halStatus = sme_ScanRequest(hHal, + sapContext->sessionId, + &scanRequest, + /*, when ID == 0 11D scan/active scan with callback, + * min-maxChntime set in csrScanRequest()? + */ + &scanRequestID, + /*csrScanCompleteCallback callback,*/ + &WLANSAP_ScanCallback, + /* pContext scanRequestID filled up*/ + sapContext); + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s:sme_ScanRequest fail %d!!!", __func__, halStatus); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "SoftAP Configuring for default channel, Ch= %d", + sapContext->channel); + /* In case of error, switch to default channel */ + sapContext->channel = SAP_DEFAULT_CHANNEL; + +#ifdef SOFTAP_CHANNEL_RANGE + if(sapContext->channelList != NULL) + { + sapContext->channel = sapContext->channelList[0]; + vos_mem_free(sapContext->channelList); + sapContext->channelList = NULL; + } +#endif + /* Fill in the event structure */ + sapEventInit(sapEvent); + /* Handle event */ + vosStatus = sapFsm(sapContext, sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, return from sme_ScanReq, scanID=%d, Ch= %d", + __func__, scanRequestID, sapContext->channel); + } +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + } else + sapContext->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN; + } + + if (sapContext->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "## %s SKIPPED ACS SCAN", __func__); + WLANSAP_ScanCallback(hHal, sapContext, sapContext->sessionId, 0, + eCSR_SCAN_SUCCESS); + } +#endif + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, for configured channel, Ch= %d", + __func__, sapContext->channel); + /* Fill in the event structure */ + // Eventhough scan was not done, means a user set channel was chosen + sapEventInit(sapEvent); + /* Handle event */ + vosStatus = sapFsm(sapContext, sapEvent); + } + + /* If scan failed, get default channel and advance state machine as success with default channel */ + /* Have to wait for the call back to be called to get the channel cannot advance state machine here as said above */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before exiting sapGotoChannelSel channel=%d", __func__, sapContext->channel); + + return VOS_STATUS_SUCCESS; +}// sapGotoChannelSel + +/*========================================================================== + FUNCTION sap_OpenSession + + DESCRIPTION + Function for opening SME and SAP sessions when system is in SoftAP role + + DEPENDENCIES + NA. + + PARAMETERS + + IN + hHal : Hal handle + sapContext : Sap Context value + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sap_OpenSession (tHalHandle hHal, ptSapContext sapContext) +{ + tANI_U32 type, subType; + eHalStatus halStatus; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (sapContext->csrRoamProfile.csrPersona == VOS_P2P_GO_MODE) + status = vos_get_vdev_types(VOS_P2P_GO_MODE, &type, &subType); + else + status = vos_get_vdev_types(VOS_STA_SAP_MODE, &type, &subType); + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, "failed to get vdev type"); + return VOS_STATUS_E_FAILURE; + } + /* Open SME Session for Softap */ + halStatus = sme_OpenSession(hHal, + &WLANSAP_RoamCallback, + sapContext, + sapContext->self_mac_addr, + &sapContext->sessionId, + type, subType); + + if(eHAL_STATUS_SUCCESS != halStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Error: In %s calling sme_RoamConnect status = %d", + __func__, halStatus); + + return VOS_STATUS_E_FAILURE; + } + + pMac->sap.sapCtxList [ sapContext->sessionId ].sessionID = + sapContext->sessionId; + pMac->sap.sapCtxList [ sapContext->sessionId ].pSapContext = sapContext; + pMac->sap.sapCtxList [ sapContext->sessionId ].sapPersona= + sapContext->csrRoamProfile.csrPersona; + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION sapGotoStarting + + DESCRIPTION + Function for initiating start bss request for SME + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + bssType : Type of bss to start, INRA AP + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoStarting +( + ptSapContext sapContext, + ptWLAN_SAPEvent sapEvent, + eCsrRoamBssType bssType +) +{ + /* tHalHandle */ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + eHalStatus halStatus; + + /*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/ + char key_material[32]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,}; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + sapContext->key_type = 0x05; + sapContext->key_length = 32; + vos_mem_copy(sapContext->key_material, key_material, sizeof(key_material)); /* Need a key size define */ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__); + + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + + /* No Need to Req for Power with power offload enabled */ + if(!pMac->psOffloadEnabled) + { + //TODO: What shall we do if failure???? + halStatus = pmcRequestFullPower( hHal, + WLANSAP_pmcFullPwrReqCB, + sapContext, + eSME_REASON_OTHER); + } + + halStatus = sap_OpenSession(hHal, sapContext); + + if(eHAL_STATUS_SUCCESS != halStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Error: In %s calling sap_OpenSession status = %d", + __func__, halStatus); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +}// sapGotoStarting + +/*========================================================================== + FUNCTION sapGotoDisconnecting + + DESCRIPTION + Processing of SAP FSM Disconnecting state + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoDisconnecting +( + ptSapContext sapContext +) +{ + eHalStatus halStatus; + tHalHandle hHal; + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + + sapFreeRoamProfile(&sapContext->csrRoamProfile); + halStatus = sme_RoamStopBss(hHal, sapContext->sessionId); + if(eHAL_STATUS_SUCCESS != halStatus ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Error: In %s calling sme_RoamStopBss status = %d", __func__, halStatus); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static eHalStatus sapRoamSessionCloseCallback(void *pContext) +{ + ptSapContext sapContext = (ptSapContext)pContext; + return sapSignalHDDevent(sapContext, NULL, + eSAP_STOP_BSS_EVENT, (v_PVOID_t) eSAP_STATUS_SUCCESS); +} + +/*========================================================================== + FUNCTION sapGotoDisconnected + + DESCRIPTION + Function for setting the SAP FSM to Disconnection state + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoDisconnected +( + ptSapContext sapContext +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + tWLAN_SAPEvent sapEvent; + // Processing has to be coded + // Clean up stations from TL etc as AP BSS is shut down then set event + sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;// hardcoded + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + + return vosStatus; +} + +/*========================================================================== + FUNCTION sapSignalHDDevent + + DESCRIPTION + Function for HDD to send the event notification using callback + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR roam information + sapHddevent : SAP HDD event + context : to pass the element for future support + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapSignalHDDevent +( + ptSapContext sapContext, /* sapContext value */ + tCsrRoamInfo *pCsrRoamInfo, + eSapHddEvent sapHddevent, + void *context +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tSap_Event sapApAppEvent; /* This now encodes ALL event types */ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Start BSS Complete event to return... */ + if (NULL == sapContext->pfnSapEventCallback) + { + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return VOS_STATUS_E_FAILURE; + } + pMac = PMAC_STRUCT( hHal ); + + switch (sapHddevent) + { + case eSAP_STA_ASSOC_IND: + // TODO - Indicate the assoc request indication to OS + sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_IND; + + vos_mem_copy( &sapApAppEvent.sapevt.sapAssocIndication.staMac, pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapAssocIndication.staId = pCsrRoamInfo->staId; + sapApAppEvent.sapevt.sapAssocIndication.status = 0; + // Required for indicating the frames to upper layer + sapApAppEvent.sapevt.sapAssocIndication.beaconLength = pCsrRoamInfo->beaconLength; + sapApAppEvent.sapevt.sapAssocIndication.beaconPtr = pCsrRoamInfo->beaconPtr; + sapApAppEvent.sapevt.sapAssocIndication.assocReqLength = pCsrRoamInfo->assocReqLength; + sapApAppEvent.sapevt.sapAssocIndication.assocReqPtr = pCsrRoamInfo->assocReqPtr; + sapApAppEvent.sapevt.sapAssocIndication.fWmmEnabled = pCsrRoamInfo->wmmEnabledSta; + if ( pCsrRoamInfo->u.pConnectedProfile != NULL ) + { + sapApAppEvent.sapevt.sapAssocIndication.negotiatedAuthType = pCsrRoamInfo->u.pConnectedProfile->AuthType; + sapApAppEvent.sapevt.sapAssocIndication.negotiatedUCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->EncryptionType; + sapApAppEvent.sapevt.sapAssocIndication.negotiatedMCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->mcEncryptionType; + sapApAppEvent.sapevt.sapAssocIndication.fAuthRequired = pCsrRoamInfo->fAuthRequired; + } + break; + case eSAP_START_BSS_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_START_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_START_BSS_EVENT; + sapApAppEvent.sapevt.sapStartBssCompleteEvent.status = (eSapStatus )context; + if(pCsrRoamInfo != NULL ){ + sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId = pCsrRoamInfo->staId; + } + else + { + sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId = 0; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s(eSAP_START_BSS_EVENT): staId = %d", + __func__, sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId); + + sapApAppEvent.sapevt.sapStartBssCompleteEvent.operatingChannel = (v_U8_t)sapContext->channel; + sapApAppEvent.sapevt.sapStartBssCompleteEvent.sessionId = + sapContext->sessionId; + break; + + case eSAP_DFS_CAC_START: + case eSAP_DFS_CAC_END: + case eSAP_DFS_RADAR_DETECT: + case eSAP_DFS_NO_AVAILABLE_CHANNEL: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s : %d", __func__, + "eSAP_DFS event", sapHddevent); +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + case eSAP_ACS_SCAN_SUCCESS_EVENT: +#endif + sapApAppEvent.sapHddEventCode = sapHddevent; + sapApAppEvent.sapevt.sapStopBssCompleteEvent.status = + (eSapStatus )context; + break; + + case eSAP_STOP_BSS_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STOP_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STOP_BSS_EVENT; + sapApAppEvent.sapevt.sapStopBssCompleteEvent.status = (eSapStatus )context; + break; + + case eSAP_STA_ASSOC_EVENT: + case eSAP_STA_REASSOC_EVENT: + { + tSirSmeChanInfo *pChanInfo; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STA_ASSOC_EVENT"); + if (pCsrRoamInfo->fReassocReq) + sapApAppEvent.sapHddEventCode = eSAP_STA_REASSOC_EVENT; + else + sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_EVENT; + + //TODO: Need to fill the SET KEY information and pass to HDD + vos_mem_copy( &sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.staMac, + pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.staId = pCsrRoamInfo->staId ; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.statusCode = pCsrRoamInfo->statusCode; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen = pCsrRoamInfo->rsnIELen; + vos_mem_copy(sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.ies, pCsrRoamInfo->prsnIE, + pCsrRoamInfo->rsnIELen); + + if(pCsrRoamInfo->addIELen) + { + v_U8_t len = sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen + += pCsrRoamInfo->addIELen; + vos_mem_copy(&sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.ies[len], pCsrRoamInfo->paddIE, + pCsrRoamInfo->addIELen); + } + + /* also fill up the channel info from the csrRoamInfo */ + pChanInfo = + &sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.chan_info; + + pChanInfo->chan_id = pCsrRoamInfo->chan_info.chan_id; + pChanInfo->mhz = pCsrRoamInfo->chan_info.mhz; + pChanInfo->info = pCsrRoamInfo->chan_info.info; + pChanInfo->band_center_freq1 = pCsrRoamInfo->chan_info.band_center_freq1; + pChanInfo->band_center_freq2 = pCsrRoamInfo->chan_info.band_center_freq2; + pChanInfo->reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1; + pChanInfo->reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2; + + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled = pCsrRoamInfo->wmmEnabledSta; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.status = (eSapStatus )context; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.timingMeasCap = pCsrRoamInfo->timingMeasCap; + //TODO: Need to fill sapAuthType + //sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.SapAuthType = pCsrRoamInfo->pProfile->negotiatedAuthType; + break; + } + + case eSAP_STA_DISASSOC_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STA_DISASSOC_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; + + vos_mem_copy( &sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staMac, + pCsrRoamInfo->peerMac, sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staId = pCsrRoamInfo->staId; + if (pCsrRoamInfo->reasonCode == eCSR_ROAM_RESULT_FORCED) + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_USR_INITATED_DISASSOC; + else + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_MAC_INITATED_DISASSOC; + + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.statusCode = pCsrRoamInfo->statusCode; + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.status = (eSapStatus )context; + break; + + case eSAP_STA_SET_KEY_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STA_SET_KEY_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; + sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.status = (eSapStatus )context; + vos_mem_copy(&sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.peerMacAddr, + pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + break; + + case eSAP_STA_DEL_KEY_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STA_DEL_KEY_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_DEL_KEY_EVENT; + sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.status = (eSapStatus )context; + //TODO: Should we need to send the key information + //sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.keyId = ; + break; + + case eSAP_STA_MIC_FAILURE_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_STA_MIC_FAILURE_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.srcMacAddr, + pCsrRoamInfo->u.pMICFailureInfo->srcMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.staMac, + pCsrRoamInfo->u.pMICFailureInfo->taMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.dstMacAddr, + pCsrRoamInfo->u.pMICFailureInfo->dstMacAddr, + sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationMICFailureEvent.multicast = pCsrRoamInfo->u.pMICFailureInfo->multicast; + sapApAppEvent.sapevt.sapStationMICFailureEvent.IV1 = pCsrRoamInfo->u.pMICFailureInfo->IV1; + sapApAppEvent.sapevt.sapStationMICFailureEvent.keyId = pCsrRoamInfo->u.pMICFailureInfo->keyId; + vos_mem_copy( sapApAppEvent.sapevt.sapStationMICFailureEvent.TSC, + pCsrRoamInfo->u.pMICFailureInfo->TSC, + SIR_CIPHER_SEQ_CTR_SIZE); + break; + + case eSAP_ASSOC_STA_CALLBACK_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, SAP event callback event = %s", + __func__, "eSAP_ASSOC_STA_CALLBACK_EVENT"); + break; + + case eSAP_WPS_PBC_PROBE_REQ_EVENT: + sapApAppEvent.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; + + vos_mem_copy( &sapApAppEvent.sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq, + pCsrRoamInfo->u.pWPSPBCProbeReq, + sizeof(tSirWPSPBCProbeReq)); + break; + + case eSAP_INDICATE_MGMT_FRAME: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_INDICATE_MGMT_FRAME"); + sapApAppEvent.sapHddEventCode = eSAP_INDICATE_MGMT_FRAME; + sapApAppEvent.sapevt.sapManagementFrameInfo.nFrameLength + = pCsrRoamInfo->nFrameLength; + sapApAppEvent.sapevt.sapManagementFrameInfo.pbFrames + = pCsrRoamInfo->pbFrames; + sapApAppEvent.sapevt.sapManagementFrameInfo.frameType + = pCsrRoamInfo->frameType; + sapApAppEvent.sapevt.sapManagementFrameInfo.rxChan + = pCsrRoamInfo->rxChan; + + break; + case eSAP_REMAIN_CHAN_READY: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_REMAIN_CHAN_READY"); + sapApAppEvent.sapHddEventCode = eSAP_REMAIN_CHAN_READY; + break; + case eSAP_SEND_ACTION_CNF: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_SEND_ACTION_CNF"); + sapApAppEvent.sapHddEventCode = eSAP_SEND_ACTION_CNF; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + case eSAP_DISCONNECT_ALL_P2P_CLIENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_DISCONNECT_ALL_P2P_CLIENT"); + sapApAppEvent.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + case eSAP_MAC_TRIG_STOP_BSS_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_MAC_TRIG_STOP_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + + case eSAP_UNKNOWN_STA_JOIN: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_UNKNOWN_STA_JOIN"); + sapApAppEvent.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; + vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapUnknownSTAJoin.macaddr.bytes, + (v_PVOID_t)context, sizeof(v_MACADDR_t)); + break; + + case eSAP_MAX_ASSOC_EXCEEDED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_MAX_ASSOC_EXCEEDED"); + sapApAppEvent.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; + vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapMaxAssocExceeded.macaddr.bytes, + (v_PVOID_t)pCsrRoamInfo->peerMac, sizeof(v_MACADDR_t)); + break; + + case eSAP_CHANNEL_CHANGE_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_CHANNEL_CHANGE_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; + sapApAppEvent.sapevt.sapChannelChange.operatingChannel = + pMac->sap.SapDfsInfo.target_channel; + break; + + case eSAP_DFS_NOL_GET: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_DFS_NOL_GET"); + sapApAppEvent.sapHddEventCode = eSAP_DFS_NOL_GET; + sapApAppEvent.sapevt.sapDfsNolInfo.sDfsList = + NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo); + sapApAppEvent.sapevt.sapDfsNolInfo.pDfsList = + (v_PVOID_t)(&pMac->sap.SapDfsInfo.sapDfsChannelNolList[0]); + break; + + case eSAP_DFS_NOL_SET: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_DFS_NOL_SET"); + sapApAppEvent.sapHddEventCode = eSAP_DFS_NOL_SET; + sapApAppEvent.sapevt.sapDfsNolInfo.sDfsList = + pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels * + sizeof(tSapDfsNolInfo); + sapApAppEvent.sapevt.sapDfsNolInfo.pDfsList = + (v_PVOID_t)(&pMac->sap.SapDfsInfo.sapDfsChannelNolList[0]); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, SAP Unknown callback event = %d", + __func__,sapHddevent); + break; + } + vosStatus = (*sapContext->pfnSapEventCallback) + ( + &sapApAppEvent, + sapContext->pUsrContext//userdataforcallback - hdd opaque handle + ); + + return vosStatus; + +} /* sapSignalApAppStartBssEvent */ + +/*========================================================================== + FUNCTION sap_find_valid_concurrent_session + + DESCRIPTION + This function will return sapcontext of any valid sap session. + + PARAMETERS + + IN + hHal : HAL pointer + + RETURN VALUE + ptSapContext : valid sap context + + SIDE EFFECTS + NA +============================================================================*/ +ptSapContext sap_find_valid_concurrent_session (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_U8_t intf = 0; + + for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + if (VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona && + pMac->sap.sapCtxList[intf].pSapContext != NULL) + { + return pMac->sap.sapCtxList[intf].pSapContext; + } + } + + return NULL; +} + +/*========================================================================== + FUNCTION sap_CloseSession + + DESCRIPTION + This function will close all the sme sessions as well as zero-out the + sap global structure + + PARAMETERS + + IN + hHal : HAL pointer + sapContext : Sap Context value + callback : Roam Session close callback + valid : Sap context is valid or no + + RETURN VALUE + The eHalStatus code associated with performing the operation + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + NA +============================================================================*/ +eHalStatus sap_CloseSession(tHalHandle hHal, + ptSapContext sapContext, + csrRoamSessionCloseCallback callback, + v_BOOL_t valid) +{ + eHalStatus halstatus; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (FALSE == valid) + { + halstatus = sme_CloseSession(hHal, + sapContext->sessionId, + callback, NULL); + } + else + { + halstatus = sme_CloseSession(hHal, + sapContext->sessionId, + callback, sapContext); + } + + sapContext->isCacStartNotified = VOS_FALSE; + sapContext->isCacEndNotified = VOS_FALSE; + pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL; + + if (NULL == sap_find_valid_concurrent_session(hHal)) + { + /* If timer is running then stop the timer and destory + * it + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: no session are valid, so clearing dfs global structure"); + /* + * CAC timer will be initiated and started only when SAP starts on + * DFS channel and it will be stopped and destroyed immediately once the + * radar detected or timedout. So as per design CAC timer should be + * destroyed after stop. + */ + + if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) + { + vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; + vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + } + pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC; + sap_CacResetNotify(hHal); + vos_mem_zero(&pMac->sap, sizeof(pMac->sap)); + } + + return halstatus; +} + +/*========================================================================== + FUNCTION sap_CacResetNotify + + DESCRIPTION Function will be called up on stop bss indication to clean up + DFS global structure. + + DEPENDENCIES PARAMETERS + IN hHAL : HAL pointer + + RETURN VALUE : void. + + SIDE EFFECTS +============================================================================*/ +void sap_CacResetNotify(tHalHandle hHal) +{ + v_U8_t intf = 0; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + ptSapContext pSapContext = + (ptSapContext)pMac->sap.sapCtxList [intf].pSapContext; + if (VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona && + pMac->sap.sapCtxList [intf].pSapContext != NULL) + { + pSapContext->isCacStartNotified = VOS_FALSE; + pSapContext->isCacEndNotified = VOS_FALSE; + } + } +} + +/*========================================================================== + FUNCTION sap_CacStartNotify + + DESCRIPTION Function will be called to Notify eSAP_DFS_CAC_START event + to HDD + + DEPENDENCIES PARAMETERS + IN hHAL : HAL pointer + + RETURN VALUE : VOS_STATUS. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS sap_CacStartNotify(tHalHandle hHal) +{ + v_U8_t intf = 0; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + + for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + ptSapContext pSapContext = + (ptSapContext)pMac->sap.sapCtxList [intf].pSapContext; + if (VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona && + pMac->sap.sapCtxList [intf].pSapContext != NULL && + (VOS_FALSE == pSapContext->isCacStartNotified)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%p]", + pSapContext); + + vosStatus = sapSignalHDDevent(pSapContext, NULL, + eSAP_DFS_CAC_START, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, failed setting isCacStartNotified on interface[%d]", + __func__, intf); + return vosStatus; + } + pSapContext->isCacStartNotified = VOS_TRUE; + } + } + return vosStatus; +} + +/*========================================================================== + FUNCTION sap_CacEndNotify + + DESCRIPTION Function will be called to Notify eSAP_DFS_CAC_END event + to HDD + + DEPENDENCIES PARAMETERS + IN hHAL : HAL pointer + + RETURN VALUE : VOS_STATUS. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS sap_CacEndNotify(tHalHandle hHal, tCsrRoamInfo *roamInfo) +{ + v_U8_t intf; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + + /* + * eSAP_DFS_CHANNEL_CAC_END: + * CAC Period elapsed and there was no radar + * found so, SAP can continue beaconing. + * sap_radar_found_status is set to 0 + */ + for ( intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + ptSapContext pSapContext = + (ptSapContext)pMac->sap.sapCtxList [intf].pSapContext; + if (VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona && + pMac->sap.sapCtxList [intf].pSapContext != NULL && + (VOS_FALSE == pSapContext->isCacEndNotified)) + { + pSapContext = pMac->sap.sapCtxList [intf].pSapContext; + vosStatus = sapSignalHDDevent(pSapContext, NULL, + eSAP_DFS_CAC_END, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, failed setting isCacEndNotified on interface[%d]", + __func__, intf); + return vosStatus; + } + pSapContext->isCacEndNotified = VOS_TRUE; + pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Start beacon request on sapctx[%p]", + pSapContext); + + /* Start beaconing on the new channel */ + WLANSAP_StartBeaconReq((v_PVOID_t)pSapContext); + + /* Transition from eSAP_STARTING to eSAP_STARTED + * (both without substates) + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: channel[%d] from state %s => %s", + pSapContext->channel, "eSAP_STARTING", + "eSAP_STARTED"); + + pSapContext->sapsMachine = eSAP_STARTED; + + /*Action code for transition */ + vosStatus = sapSignalHDDevent(pSapContext, roamInfo, + eSAP_START_BSS_EVENT, + (v_PVOID_t)eSAP_STATUS_SUCCESS); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, failed setting isCacEndNotified on interface[%d]", + __func__, intf); + return vosStatus; + } + + /* Transition from eSAP_STARTING to eSAP_STARTED + * (both without substates) + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", + __func__, "eSAP_DFS_CAC_WAIT", "eSAP_STARTED"); + } + } + /* + * All APs are done with CAC timer, all APs should start beaconing. + * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets + * say AP1 goes down and comes back on same DFS channel. In this case + * AP1 shouldn't start CAC timer and start beacon immediately beacause + * AP2 is already beaconing on this channel. This case will be handled + * by checking against eSAP_DFS_SKIP_CAC while starting the timer. + */ + pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC; + return vosStatus; +} + +/*========================================================================== + FUNCTION sapFsm + + DESCRIPTION + SAP State machine entry function + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent /* State machine event */ +) +{ + /* Retrieve the phy link state machine structure + * from the sapContext value + */ + eSapFsmStates_t stateVar = sapContext->sapsMachine; /*state var that keeps track of state machine*/ + tCsrRoamInfo *roamInfo = (tCsrRoamInfo *)(sapEvent->params); + v_U32_t msg = sapEvent->event; /* State machine input event message */ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + tpAniSirGlobal pMac; + v_U32_t cbMode; + v_BOOL_t b_leak_chan = FALSE; +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + v_U8_t temp_chan; + tSapDfsNolInfo *pNol; +#endif + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return VOS_STATUS_E_FAILURE; + } + pMac = PMAC_STRUCT( hHal ); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, "%s: sapContext=%p, stateVar=%d, msg=0x%x", __func__, sapContext, stateVar, msg); + + switch (stateVar) + { + case eSAP_DISCONNECTED: + if ((msg == eSAP_HDD_START_INFRA_BSS)) + { + /* Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, new from state %s => %s", + __func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); + + /* There can be one SAP Session for softap */ + if (sapContext->isSapSessionOpen == eSAP_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "%s:SME Session is already opened\n",__func__); + return VOS_STATUS_E_EXISTS; + } + + sapContext->sessionId = 0xff; + + if ((sapContext->channel == AUTO_CHANNEL_SELECT) && + (sapContext->isScanSessionOpen == eSAP_FALSE)) + { + tANI_U32 type, subType; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_DISCONNECTED", msg); + } + else if(VOS_STATUS_SUCCESS == vos_get_vdev_types(VOS_STA_MODE, + &type, &subType)) { + /* Open SME Session for scan */ + if(eHAL_STATUS_SUCCESS != sme_OpenSession(hHal, + NULL, sapContext, sapContext->self_mac_addr, + &sapContext->sessionId, type, subType)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Error: In %s calling sme_OpenSession", __func__); + } else { + sapContext->isScanSessionOpen = eSAP_TRUE; + } + } + } + /* init dfs channel nol */ + sapInitDfsChannelNolList(sapContext); + + /* Set SAP device role */ + sapContext->sapsMachine = eSAP_CH_SELECT; + + /* Perform sme_ScanRequest */ + vosStatus = sapGotoChannelSel(sapContext, sapEvent); + + /* Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); + } + else if (msg == eSAP_DFS_CHANNEL_CAC_START) + { + /* No need of state check here, caller is expected to perform + * the checks before sending the event + */ + sapContext->sapsMachine = eSAP_DFS_CAC_WAIT; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT"); + if ( pMac->sap.SapDfsInfo.is_dfs_cac_timer_running != VOS_TRUE) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: starting dfs cac timer on sapctx[%p]", + sapContext); + sapStartDfsCacTimer(sapContext); + } + + vosStatus = sap_CacStartNotify(hHal); + } + else if (msg == eSAP_CHANNEL_SELECTION_FAILED) + { + /* Set SAP device role */ + sapContext->sapsMachine = eSAP_CH_SELECT; + + /* Perform sme_ScanRequest */ + vosStatus = sapGotoChannelSel(sapContext, sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, event msg %d", + __func__, "eSAP_DISCONNECTED", msg); + } + + break; + + case eSAP_CH_SELECT: + if (sapContext->isScanSessionOpen == eSAP_TRUE) + { + /* scan completed, so close the session */ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_CH_SELECT", msg); + } else { + if(eHAL_STATUS_SUCCESS != sme_CloseSession(hHal, + sapContext->sessionId, NULL, NULL)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s CloseSession error event msg %d", + __func__, msg); + } else { + sapContext->isScanSessionOpen = eSAP_FALSE; + } + } + sapContext->sessionId = 0xff; + } + + if (msg == eSAP_MAC_SCAN_COMPLETE) + { + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d ", __func__, + "eSAP_CH_SELECT", msg); + return VOS_STATUS_E_FAULT; + } +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (sapContext->cc_switch_mode != VOS_MCC_TO_SCC_SWITCH_DISABLE) + { + v_U16_t con_ch; + + con_ch = sme_CheckConcurrentChannelOverlap(hHal, + sapContext->channel, + sapConvertSapPhyModeToCsrPhyMode( + sapContext->csrRoamProfile.phyMode), + sapContext->cc_switch_mode); + if (con_ch) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Override Chosen Ch:%d to %d due to CC Intf!!", + __func__,sapContext->channel, con_ch); + sapContext->channel = con_ch; + sme_SelectCBMode(hHal, + sapConvertSapPhyModeToCsrPhyMode( + sapContext->csrRoamProfile.phyMode), + sapContext->channel); + } + } +#endif + + /* get the bonding mode */ + if (sapContext->channel <= 14) + cbMode = sme_GetCBPhyStateFromCBIniValue( + sme_GetChannelBondingMode24G(hHal)); + else + cbMode = sme_GetCBPhyStateFromCBIniValue( + sme_GetChannelBondingMode5G(hHal)); + +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + temp_chan = sapContext->channel; + pNol = pMac->sap.SapDfsInfo.sapDfsChannelNolList; + + sapMarkChannelsLeakingIntoNOL(sapContext, + cbMode, pNol, 1, &temp_chan); + + /* if selelcted channel has leakage to channels + in NOL, the temp_chan will be reset */ + b_leak_chan = (temp_chan != sapContext->channel); +#endif + /* check if channel is in DFS_NOL or + if the channel has leakage to the channels in NOL */ + if (sapDfsIsChannelInNolList(sapContext, sapContext->channel, + cbMode) || b_leak_chan) + { + v_U8_t ch; + + /* find a new available channel */ + ch = sapRandomChannelSel(sapContext); + if (ch == 0) { + /* No available channel found */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("No available channel found!!!")); + sapSignalHDDevent(sapContext, NULL, + eSAP_DFS_NO_AVAILABLE_CHANNEL, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("channel %d is in NOL, StartBss on new channel %d"), + sapContext->channel, ch); + + sapContext->channel = ch; + sme_SelectCBMode(hHal, + sapConvertSapPhyModeToCsrPhyMode( + sapContext->csrRoamProfile.phyMode), + sapContext->channel); + } + if (sapContext->channel > 14 && + (sapContext->csrRoamProfile.phyMode == + eSAP_DOT11_MODE_11g || + sapContext->csrRoamProfile.phyMode == + eSAP_DOT11_MODE_11g_ONLY)) + sapContext->csrRoamProfile.phyMode = eSAP_DOT11_MODE_11a; + +#ifdef WLAN_FEATURE_MBSSID + /* when AP2 is started while AP1 is performing ACS, we may not + * have the AP1 channel yet.So here after the completion of AP2 + * ACS check if AP1 ACS resulting channel is DFS and if yes + * override AP2 ACS scan result with AP1 DFS channel + */ + if (vos_concurrent_sap_sessions_running()) { + v_U16_t con_ch; + + con_ch = sme_GetConcurrentOperationChannel(hHal); + if (con_ch && VOS_IS_DFS_CH(con_ch)) + sapContext->channel = con_ch; + } +#endif + /* Transition from eSAP_CH_SELECT to eSAP_STARTING (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_CH_SELECT", "eSAP_STARTING"); + // Channel selected. Now can sapGotoStarting + sapContext->sapsMachine = eSAP_STARTING; + // Specify the channel + sapContext->csrRoamProfile.ChannelInfo.numOfChannels = 1; + sapContext->csrRoamProfile.ChannelInfo.ChannelList = &sapContext->csrRoamProfile.operationChannel; + sapContext->csrRoamProfile.operationChannel = (tANI_U8)sapContext->channel; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: notify hostapd about channel selection: %d", + __func__, sapContext->channel); + if (sapContext->apAutoChannelSelection && + (sapContext->csrRoamProfile.phyMode == + eSAP_DOT11_MODE_11n || + sapContext->csrRoamProfile.phyMode == + eSAP_DOT11_MODE_11n_ONLY)) { + tSap_Event sapApAppEvent; + sapApAppEvent.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT; + sapApAppEvent.sapevt.sapChannelChange.operatingChannel = + sapContext->channel; + (*sapContext->pfnSapEventCallback) (&sapApAppEvent, + sapContext->pUsrContext); + } + vosStatus = sapGotoStarting( sapContext, sapEvent, eCSR_BSS_TYPE_INFRA_AP); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_CH_SELECT", msg); + } + break; + + case eSAP_DFS_CAC_WAIT: + if (msg == eSAP_DFS_CHANNEL_CAC_START) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT"); + if ( pMac->sap.SapDfsInfo.is_dfs_cac_timer_running != VOS_TRUE) + sapStartDfsCacTimer(sapContext); + + vosStatus = sap_CacStartNotify(hHal); + + } + else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) + { + v_U8_t intf; + /* Radar found while performing channel availability + * check, need to switch the channel again + */ + eCsrPhyMode phyMode = + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode); + tHalHandle hHal = + (tHalHandle)vos_get_context(VOS_MODULE_ID_SME, sapContext->pvosGCtx); + + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n"); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_DFS_CAC_WAIT", msg); + } + else if (pMac->sap.SapDfsInfo.target_channel) + { + sme_SelectCBMode(hHal, phyMode, + pMac->sap.SapDfsInfo.target_channel); + } + + for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + ptSapContext sapContext; + if (VOS_STA_SAP_MODE == + pMac->sap.sapCtxList[intf].sapPersona && + pMac->sap.sapCtxList [intf].pSapContext != NULL) + { + sapContext = pMac->sap.sapCtxList [intf].pSapContext; + /* SAP to be moved to DISCONNECTING state */ + sapContext->sapsMachine = eSAP_DISCONNECTING; + /* + * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND: + * A Radar is found on current DFS Channel + * while in CAC WAIT period So, do a channel switch + * to randomly selected target channel. + * Send the Channel change message to SME/PE. + * sap_radar_found_status is set to 1 + */ + sapSignalHDDevent(sapContext, NULL, + eSAP_DFS_RADAR_DETECT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext, + pMac->sap.SapDfsInfo.target_channel); + } + } + } + else if (msg == eSAP_DFS_CHANNEL_CAC_END) + { + vosStatus = sap_CacEndNotify(hHal, roamInfo); + } + else if (msg == eSAP_HDD_STOP_INFRA_BSS) + { + /* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", + __func__, + "eSAP_DFS_CAC_WAIT", + "eSAP_DISCONNECTING"); + + /* + * Stop the CAC timer only in following conditions + * single AP: if there is a single AP then stop the timer + * mulitple APs: incase of multiple APs, make sure that + * all APs are down. + */ + if (NULL == sap_find_valid_concurrent_session(hHal)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: no sessions are valid, stopping timer"); + + sapStopDfsCacTimer(sapContext); + } + + sapContext->sapsMachine = eSAP_DISCONNECTING; + vosStatus = sapGotoDisconnecting(sapContext); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_DFS_CAC_WAIT", msg); + } + break; + + case eSAP_STARTING: + if (msg == eSAP_MAC_START_BSS_SUCCESS ) + { + /* Transition from eSAP_STARTING to eSAP_STARTED (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state channel = %d %s => %s", + __func__,sapContext->channel, "eSAP_STARTING", "eSAP_STARTED"); + + sapContext->sapsMachine = eSAP_STARTED; + + /*Action code for transition */ + vosStatus = sapSignalHDDevent( sapContext, roamInfo, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + + /* The upper layers have been informed that AP is up and + * running, however, the AP is still not beaconing, until + * CAC is done if the operating channel is DFS + */ + if (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(sapContext->channel) + ) + { + if ((VOS_FALSE == pMac->sap.SapDfsInfo.ignore_cac) && + (eSAP_DFS_DO_NOT_SKIP_CAC == + pMac->sap.SapDfsInfo.cac_state)) + { + /* Move the device in CAC_WAIT_STATE */ + sapContext->sapsMachine = eSAP_DFS_CAC_WAIT; + + /* TODO: Need to stop the OS transmit queues, + * so that no traffic can flow down the stack + */ + + /* Start CAC wait timer */ + if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running != + TRUE) + sapStartDfsCacTimer(sapContext); + + vosStatus = sap_CacStartNotify(hHal); + + } + else + { + WLANSAP_StartBeaconReq((v_PVOID_t)sapContext); + } + } + } + else if (msg == eSAP_MAC_START_FAILS) + { + /*Transition from STARTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, from state %s => %s", + __func__, "eSAP_STARTING", "eSAP_DISCONNECTED"); + + /*Action code for transition */ + vosStatus = sapSignalHDDevent( sapContext, NULL, eSAP_START_BSS_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE); + vosStatus = sapGotoDisconnected(sapContext); + + /*Advance outer statevar */ + sapContext->sapsMachine = eSAP_DISCONNECTED; + } + else if (msg == eSAP_HDD_STOP_INFRA_BSS) + { + /*Transition from eSAP_STARTING to eSAP_DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_STARTING", "eSAP_DISCONNECTED"); + + /*Advance outer statevar */ + sapContext->sapsMachine = eSAP_DISCONNECTED; + vosStatus = sapSignalHDDevent( sapContext, NULL, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + vosStatus = sapGotoDisconnected(sapContext); + /* Close the SME session*/ + + if (eSAP_TRUE == sapContext->isSapSessionOpen) + { + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_STARTING", msg); + } + else if (eHAL_STATUS_SUCCESS == + sap_CloseSession(hHal, + sapContext, NULL, FALSE)) + { + sapContext->isSapSessionOpen = eSAP_FALSE; + } + } + } + else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) + { + /* The operating channel has changed, update hostapd */ + sapContext->channel = + (tANI_U8)pMac->sap.SapDfsInfo.target_channel; + + sapContext->sapsMachine = eSAP_STARTED; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, from state %s => %s", + __func__, "eSAP_STARTING", "eSAP_STARTED"); + + /* Indicate change in the state to upper layers */ + vosStatus = sapSignalHDDevent(sapContext, roamInfo, + eSAP_START_BSS_EVENT, + (v_PVOID_t)eSAP_STATUS_SUCCESS); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_STARTING", msg); + /* Intentionally left blank */ + } + break; + + case eSAP_STARTED: + if (msg == eSAP_HDD_STOP_INFRA_BSS) + { + /* Transition from eSAP_STARTED to eSAP_DISCONNECTING (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_STARTED", "eSAP_DISCONNECTING"); + sapContext->sapsMachine = eSAP_DISCONNECTING; + vosStatus = sapGotoDisconnecting(sapContext); + } + else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) + { + v_U8_t intf; + /* Radar is seen on the current operating channel + * send CSA IE for all associated stations + */ + if (pMac != NULL) + { + /* Request for CSA IE transmission */ + for ( intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) + { + ptSapContext pSapContext; + + if (VOS_STA_SAP_MODE == pMac->sap.sapCtxList [intf].sapPersona && + pMac->sap.sapCtxList [intf].pSapContext != NULL ) + { + pSapContext = pMac->sap.sapCtxList [intf].pSapContext; + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Sending CSAIE for sapctx[%p]", + pSapContext); + + vosStatus = + WLANSAP_DfsSendCSAIeRequest((v_PVOID_t)pSapContext); + } + } + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_STARTED", msg); + } + break; + + case eSAP_DISCONNECTING: + if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) + { + /* Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); + + sapContext->sapsMachine = eSAP_DISCONNECTED; + + /* Close the SME session*/ + if (eSAP_TRUE == sapContext->isSapSessionOpen) + { + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_DISCONNECTING", msg); + } + else + { + sapContext->isSapSessionOpen = eSAP_FALSE; + if (!HAL_STATUS_SUCCESS( + sap_CloseSession(hHal, + sapContext, + sapRoamSessionCloseCallback, TRUE))) + { + vosStatus = sapSignalHDDevent(sapContext, NULL, + eSAP_STOP_BSS_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + } + } + } + } + else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Send channel change request on sapctx[%p]", + sapContext); + /* Most likely, radar has been detected and SAP wants to + * change the channel + */ + vosStatus = WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext, + pMac->sap.SapDfsInfo.target_channel); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "In %s, Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ", + __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_DISCONNECTING", msg); + } + break; + } + return vosStatus; +}// sapFsm + + +eSapStatus +sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, tCsrRoamProfile *profile) +{ + //Create Roam profile for SoftAP to connect + profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; + profile->SSIDs.numOfSSIDs = 1; + profile->csrPersona = pconfig_params->persona; + profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; + + vos_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); + + //Flag to not broadcast the SSID information + profile->SSIDs.SSIDList[0].ssidHidden = pconfig_params->SSIDinfo.ssidHidden; + + profile->SSIDs.SSIDList[0].SSID.length = pconfig_params->SSIDinfo.ssid.length; + vos_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, pconfig_params->SSIDinfo.ssid.ssId, + sizeof(pconfig_params->SSIDinfo.ssid.ssId)); + + profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if (pconfig_params->authType == eSAP_OPEN_SYSTEM) + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + } + else if (pconfig_params->authType == eSAP_SHARED_KEY) + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; + } + else + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; + } + + profile->AuthType.numEntries = 1; + profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + //Always set the Encryption Type + profile->EncryptionType.numEntries = 1; + profile->EncryptionType.encryptionType[0] = pconfig_params->RSNEncryptType; + + profile->mcEncryptionType.numEntries = 1; + profile->mcEncryptionType.encryptionType[0] = pconfig_params->mcRSNEncryptType; + + if (pconfig_params->privacy & eSAP_SHARED_KEY) + { + profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; + } + + profile->privacy = pconfig_params->privacy; + profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; + + if (pconfig_params->authType == eSAP_SHARED_KEY) + { + profile->csr80211AuthType = eSIR_SHARED_KEY; + } + else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) + { + profile->csr80211AuthType = eSIR_OPEN_SYSTEM; + } + else + { + profile->csr80211AuthType = eSIR_AUTO_SWITCH; + } + + //Initialize we are not going to use it + profile->pWPAReqIE = NULL; + profile->nWPAReqIELength = 0; + + //set the RSN/WPA IE + profile->pRSNReqIE = NULL; + profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; + if (pconfig_params->RSNWPAReqIELength) + { + profile->pRSNReqIE = vos_mem_malloc(pconfig_params->RSNWPAReqIELength); + if( NULL == profile->pRSNReqIE ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, " %s Fail to alloc memory", __func__); + return eSAP_STATUS_FAILURE; + } + vos_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, + pconfig_params->RSNWPAReqIELength); + profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; + } + + // Turn off CB mode + profile->CBMode = eCSR_CB_OFF; + + //set the phyMode to accept anything + //Best means everything because it covers all the things we support + /*eCSR_DOT11_MODE_BEST*/ + profile->phyMode = + sapConvertSapPhyModeToCsrPhyMode(pconfig_params->SapHw_mode); + + //Configure beaconInterval + profile->beaconInterval = (tANI_U16)pconfig_params->beacon_int; + + // set DTIM period + profile->dtimPeriod = pconfig_params->dtim_period; + + //set Uapsd enable bit + profile->ApUapsdEnable = pconfig_params->UapsdEnable; + + //Enable protection parameters + profile->protEnabled = pconfig_params->protEnabled; + profile->obssProtEnabled = pconfig_params->obssProtEnabled; + profile->cfg_protection = pconfig_params->ht_capab; + + //country code + if (pconfig_params->countryCode[0]) + vos_mem_copy(profile->countryCode, pconfig_params->countryCode, WNI_CFG_COUNTRY_CODE_LEN); + profile->ieee80211d = pconfig_params->ieee80211d; + //wps config info + profile->wps_state = pconfig_params->wps_state; + +#ifdef WLAN_FEATURE_11W + // MFP capable/required + profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; + profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; +#endif + + if (pconfig_params->probeRespIEsBufferLen > 0 && + pconfig_params->pProbeRespIEsBuffer != NULL) + { + profile->addIeParams.probeRespDataLen = + pconfig_params->probeRespIEsBufferLen; + profile->addIeParams.probeRespData_buff = + pconfig_params->pProbeRespIEsBuffer; + } + else + { + profile->addIeParams.probeRespDataLen = 0; + profile->addIeParams.probeRespData_buff = NULL; + } + /*assoc resp IE */ + if (pconfig_params->assocRespIEsLen > 0 && + pconfig_params->pAssocRespIEsBuffer != NULL) + { + profile->addIeParams.assocRespDataLen = + pconfig_params->assocRespIEsLen; + profile->addIeParams.assocRespData_buff = + pconfig_params->pAssocRespIEsBuffer; + } + else + { + profile->addIeParams.assocRespDataLen = 0; + profile->addIeParams.assocRespData_buff = NULL; + } + + if (pconfig_params->probeRespBcnIEsLen > 0 && + pconfig_params->pProbeRespBcnIEsBuffer!= NULL) + { + profile->addIeParams.probeRespBCNDataLen = + pconfig_params->probeRespBcnIEsLen; + profile->addIeParams.probeRespBCNData_buff = + pconfig_params->pProbeRespBcnIEsBuffer; + } + else + { + profile->addIeParams.probeRespBCNDataLen = 0; + profile->addIeParams.probeRespBCNData_buff = NULL; + } + profile->sap_dot11mc = pconfig_params->sap_dot11mc; + + return eSAP_STATUS_SUCCESS; /* Success. */ +} + +/** + * FUNCTION: sapConvertSapPhyModeToCsrPhyMode + * Called internally by SAP + */ +eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode ) +{ + switch (sapPhyMode) + { + case (eSAP_DOT11_MODE_abg): + return eCSR_DOT11_MODE_abg; + case (eSAP_DOT11_MODE_11b): + return eCSR_DOT11_MODE_11b; + case (eSAP_DOT11_MODE_11g): + return eCSR_DOT11_MODE_11g; + case (eSAP_DOT11_MODE_11n): + return eCSR_DOT11_MODE_11n; + case (eSAP_DOT11_MODE_11g_ONLY): + return eCSR_DOT11_MODE_11g_ONLY; + case (eSAP_DOT11_MODE_11n_ONLY): + return eCSR_DOT11_MODE_11n_ONLY; + case (eSAP_DOT11_MODE_11b_ONLY): + return eCSR_DOT11_MODE_11b_ONLY; +#ifdef WLAN_FEATURE_11AC + case (eSAP_DOT11_MODE_11ac_ONLY): + return eCSR_DOT11_MODE_11ac_ONLY; + case (eSAP_DOT11_MODE_11ac): + return eCSR_DOT11_MODE_11ac; +#endif + default: + return eCSR_DOT11_MODE_AUTO; + } +} + +void sapFreeRoamProfile(tCsrRoamProfile *profile) +{ + if(profile->pRSNReqIE) + { + vos_mem_free(profile->pRSNReqIE); + profile->pRSNReqIE = NULL; + } +} + + +void +sapSortMacList(v_MACADDR_t *macList, v_U8_t size) +{ + v_U8_t outer, inner; + v_MACADDR_t temp; + v_SINT_t nRes = -1; + + if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("either buffer is NULL or size = %d is more."), size); + return; + } + + for(outer = 0; outer < size; outer++) + { + for(inner = 0; inner < size - 1; inner++) + { + nRes = vos_mem_compare2((macList + inner)->bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t)); + if (nRes > 0) + { + vos_mem_copy(temp.bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t)); + vos_mem_copy((macList + inner + 1)->bytes, (macList + inner)->bytes, sizeof(v_MACADDR_t)); + vos_mem_copy((macList + inner)->bytes, temp.bytes, sizeof(v_MACADDR_t)); + } + } + } +} + +eSapBool +sapSearchMacList(v_MACADDR_t *macList, v_U8_t num_mac, v_U8_t *peerMac, v_U8_t *index) +{ + v_SINT_t nRes = -1; + v_S7_t nStart = 0, nEnd, nMiddle; + nEnd = num_mac - 1; + + if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("either buffer is NULL or size = %d is more."), + num_mac); + return eSAP_FALSE; + } + + while (nStart <= nEnd) + { + nMiddle = (nStart + nEnd) / 2; + nRes = vos_mem_compare2(&macList[nMiddle], peerMac, sizeof(v_MACADDR_t)); + + if (0 == nRes) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "search SUCC"); + // "index equals NULL" means the caller does not need the + // index value of the peerMac being searched + if (index != NULL) + { + *index = (v_U8_t) nMiddle; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "index %d", *index); + } + return eSAP_TRUE; + } + if (nRes < 0) + nStart = nMiddle + 1; + else + nEnd = nMiddle - 1; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "search not succ"); + return eSAP_FALSE; +} + +void +sapAddMacToACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t *peerMac) +{ + v_SINT_t nRes = -1; + int i; + + if ((NULL == macList) || (*size > MAX_ACL_MAC_ADDRESS)) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("either buffer is NULL or size = %d is incorrect."), + *size); + return; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"add acl entered"); + for (i=((*size)-1); i>=0; i--) + { + nRes = vos_mem_compare2(&macList[i], peerMac, sizeof(v_MACADDR_t)); + if (nRes > 0) + { + /* Move alphabetically greater mac addresses one index down to allow for insertion + of new mac in sorted order */ + vos_mem_copy((macList+i+1)->bytes,(macList+i)->bytes, sizeof(v_MACADDR_t)); + } + else + { + break; + } + } + //This should also take care of if the element is the first to be added in the list + vos_mem_copy((macList+i+1)->bytes, peerMac, sizeof(v_MACADDR_t)); + // increment the list size + (*size)++; +} + +void +sapRemoveMacFromACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t index) +{ + int i; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"remove acl entered"); + /* return if the list passed is empty. Ideally this should never happen since this funcn is always + called after sapSearchMacList to get the index of the mac addr to be removed and this will + only get called if the search is successful. Still no harm in having the check */ + if ((NULL == macList) || (*size == 0) || (*size > MAX_ACL_MAC_ADDRESS)) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("either buffer is NULL or size = %d is incorrect"), + *size); + return; + } + + for (i=index; i<((*size)-1); i++) + { + /* Move mac addresses starting from "index" passed one index up to delete the void + created by deletion of a mac address in ACL */ + vos_mem_copy((macList+i)->bytes,(macList+i+1)->bytes, sizeof(v_MACADDR_t)); + } + // The last space should be made empty since all mac addesses moved one step up + vos_mem_zero((macList+(*size)-1)->bytes, sizeof(v_MACADDR_t)); + //reduce the list size by 1 + (*size)--; +} + +void sapPrintACL(v_MACADDR_t *macList, v_U8_t size) +{ + int i; + v_BYTE_t *macArray; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"print acl entered"); + + if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, either buffer is NULL or size %d is incorrect." + , __func__, size); + return; + } + + for (i=0; ibytes; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "** ACL entry %i - "MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(macArray)); + } + return; +} + +VOS_STATUS +sapIsPeerMacAllowed(ptSapContext sapContext, v_U8_t *peerMac) +{ + if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) + return VOS_STATUS_SUCCESS; + + if (sapSearchMacList(sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) + return VOS_STATUS_SUCCESS; + + if (sapSearchMacList(sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" in deny list", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + + // A new station CAN associate, unless in deny list. Less stringent mode + if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) + return VOS_STATUS_SUCCESS; + + // A new station CANNOT associate, unless in accept list. More stringent mode + if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + + /* The new STA is neither in accept list nor in deny list. In this case, deny the association + * but send a wifi event notification indicating the mac address being denied + */ + if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) + { + sapSignalHDDevent(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, (v_PVOID_t)peerMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +#ifdef SOFTAP_CHANNEL_RANGE +static VOS_STATUS sapGetChannelList(ptSapContext sapContext, + v_U8_t **channelList, v_U8_t *numberOfChannels) +{ + v_U32_t cfg_startChannelNum; + v_U32_t cfg_endChannelNum; + v_U32_t operatingBand; + v_U8_t loopCount; + v_U8_t *list; + v_U8_t channelCount; + v_U8_t startChannelNum, bandStartChannel; + v_U8_t endChannelNum, bandEndChannel ; + v_U32_t enableLTECoex; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); +#ifdef FEATURE_WLAN_CH_AVOID + v_U8_t i; +#endif + tpAniSirGlobal pmac = PMAC_STRUCT(hHal); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HAL pointer from pvosGCtx on sapGetChannelList"); + *numberOfChannels = 0; + *channelList = NULL; + return VOS_STATUS_E_FAULT; + } + + if ( eCSR_BAND_ALL == sapContext->scanBandPreference) + { + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &cfg_startChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &cfg_endChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: startChannel %d,EndChannel %d,Operatingband:%d", + __func__,startChannelNum,endChannelNum,operatingBand); + + startChannelNum = cfg_startChannelNum; + endChannelNum = cfg_endChannelNum; + WLANSAP_extend_to_acs_range(operatingBand, &startChannelNum, &endChannelNum, + &bandStartChannel, &bandEndChannel); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: expanded startChannel %d,EndChannel %d,Operatingband:%d", + __func__,startChannelNum,endChannelNum,operatingBand); + } + else + { + if ( sapContext->allBandScanned == eSAP_FALSE ) + { + //first band scan + sapContext->currentPreferredBand = sapContext->scanBandPreference; + } + else + { + //scan next band + if ( eCSR_BAND_24 == sapContext->scanBandPreference ) + sapContext->currentPreferredBand = eCSR_BAND_5G; + else + sapContext->currentPreferredBand = eCSR_BAND_24; + } + switch(sapContext->currentPreferredBand) + { + case eCSR_BAND_24: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + + case eCSR_BAND_5G: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + startChannelNum = 36; + endChannelNum = 165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:bandPreference not valid "); + /* assume 2.4 GHz */ + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + } + } + + ccmCfgGetInt(hHal, WNI_CFG_ENABLE_LTE_COEX, &enableLTECoex); + + /*Check if LTE coex is enabled and 2.4GHz is selected*/ + if (enableLTECoex && (bandStartChannel == RF_CHAN_1) + && (bandEndChannel == RF_CHAN_14)) + { + /*Set 2.4GHz upper limit to channel 9 for LTE COEX*/ + bandEndChannel = RF_CHAN_9; + } + /* Allocate the max number of channel supported */ + list = (v_U8_t *)vos_mem_malloc(NUM_5GHZ_CHANNELS); + if (NULL == list) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate channel list", __func__); + *numberOfChannels = 0; + *channelList = NULL; + return VOS_STATUS_E_RESOURCES; + } + + /*Search for the Active channels in the given range */ + channelCount = 0; + for( loopCount = bandStartChannel; loopCount <= bandEndChannel; loopCount++ ) + { + if((startChannelNum <= rfChannels[loopCount].channelNum)&& + (endChannelNum >= rfChannels[loopCount].channelNum )) + { + if (((TRUE == pmac->scan.fEnableDFSChnlScan) && + (regChannels[loopCount].enabled)) || + ((FALSE == pmac->scan.fEnableDFSChnlScan) && + (NV_CHANNEL_ENABLE == regChannels[loopCount].enabled))) + { +#ifdef FEATURE_WLAN_CH_AVOID + for( i = 0; i < NUM_20MHZ_RF_CHANNELS; i++ ) + { + if( (safeChannels[i].channelNumber == + rfChannels[loopCount].channelNum) ) + { + /* Check if channel is safe */ + if(VOS_TRUE == safeChannels[i].isSafe) + { +#endif +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + v_U8_t ch; + ch = rfChannels[loopCount].channelNum; + if ((sapContext->skip_acs_scan_status + == eSAP_DO_PAR_ACS_SCAN)) { + if ((ch >= sapContext->skip_acs_scan_range1_stch && + ch <= sapContext->skip_acs_scan_range1_endch) || + (ch >= sapContext->skip_acs_scan_range2_stch && + ch <= sapContext->skip_acs_scan_range2_endch)) { + + list[channelCount] = + rfChannels[loopCount].channelNum; + channelCount++; + VOS_TRACE( VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO, + "%s:%d %d added to ACS ch range", + __func__, channelCount, ch); + } else + VOS_TRACE( VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_HIGH, + "%s:%d %d skipped from ACS ch range", + __func__, channelCount, ch); + + } else { + list[channelCount] = + rfChannels[loopCount].channelNum; + channelCount++; + VOS_TRACE( VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO, + "%s:%d %d added to ACS ch range", + __func__, channelCount, ch); + } +#else + list[channelCount] = + rfChannels[loopCount].channelNum; + channelCount++; +#endif +#ifdef FEATURE_WLAN_CH_AVOID + } + break; + } + } +#endif + } + } + } + if (0 == channelCount) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:No active channels present in the given range for the current region"); + /*LTE COEX: channel range outside the restricted 2.4GHz band limits*/ + if (enableLTECoex && (startChannelNum > bandEndChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "sapGetChannelList:SAP cannot be started as LTE COEX restricted 2.4GHz limits"); + } + } + + /* return the channel list and number of channels to scan*/ + *numberOfChannels = channelCount; + if(channelCount != 0) + { + *channelList = list; + } + else + { + *channelList = NULL; + vos_mem_free(list); + } + + for (loopCount = 0; loopCount SapAllChnlList.channelList) { + vos_mem_free(sapContext->SapAllChnlList.channelList); + sapContext->SapAllChnlList.channelList = NULL; + } + + sapContext->SapAllChnlList.channelList = + (tChannelInfo *)vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN * + sizeof(tChannelInfo)); + if (NULL == sapContext->SapAllChnlList.channelList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + " Memory Allocation failed sapGetChannelList"); + return VOS_STATUS_E_FAULT; + } + + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + if( regChannels[i].enabled == NV_CHANNEL_ENABLE || + regChannels[i].enabled == NV_CHANNEL_DFS ) + { + sapContext->SapAllChnlList.channelList[count].channel = + rfChannels[i].channelNum; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d] CHANNEL = %d",__func__, __LINE__, + sapContext->SapAllChnlList.channelList[count].channel); + sapContext->SapAllChnlList.channelList[count].valid = VOS_TRUE; + count++; + } + } + + sapContext->SapAllChnlList.numChannel = count; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d] NUMBER OF CHANNELS count = %d" + "sapContext->SapAllChnlList.numChannel = %d", + __func__,__LINE__,count,sapContext->SapAllChnlList.numChannel); + return VOS_STATUS_SUCCESS; +} + +/* + * This function randomly selects the channel to switch after the detection + * of radar + * param sapContext - sap context + * dfs_event - Dfs information from DFS + * return - channel to which AP wishes to switch + */ +v_U8_t sapIndicateRadar(ptSapContext sapContext, tSirSmeDfsEventInd *dfs_event) +{ + v_U8_t target_channel = 0; + tHalHandle hHal; + tpAniSirGlobal pMac; + + if (NULL == sapContext || NULL == dfs_event) + { + /* Invalid sap context of dfs event passed */ + return 0; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return 0; + } + pMac = PMAC_STRUCT( hHal ); + + if (!dfs_event->dfs_radar_status) + { + /*dfs status does not indicate a radar on the channel-- False Alarm*/ + return 0; + } + + /* + * SAP needs to generate Channel Switch IE + * if the radar is found in the STARTED state + */ + if (eSAP_STARTED == sapContext->sapsMachine) + pMac->sap.SapDfsInfo.csaIERequired = VOS_TRUE; + + if (sapContext->csrRoamProfile.disableDFSChSwitch) + { + return sapContext->channel; + } + + /* set the Radar Found flag in SapDfsInfo */ + pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_TRUE; + + sapGet5GHzChannelList(sapContext); + + if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting")); + dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH; + } + + sapMarkDfsChannels(sapContext, dfs_event->chan_list.channels, + dfs_event->chan_list.nchannels, vos_get_monotonic_boottime()); + + /* + * (1) skip static turbo channel as it will require STA to be in + * static turbo to work. + * (2) skip channel which's marked with radar detction + * (3) WAR: we allow user to config not to use any DFS channel + * (4) When we pick a channel, skip excluded 11D channels + * (5) Create the available channel list with the above rules + */ + + target_channel = sapRandomChannelSel(sapContext); + if (0 == target_channel) + { + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NO_AVAILABLE_CHANNEL, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + } + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + FL("sapdfs: New selected target channel is [%d]"), + target_channel); + return target_channel; +} + +/* + * CAC timer callback function. + * Post eSAP_DFS_CHANNEL_CAC_END event to sapFsm(). + */ +void sapDfsCacTimerCallback(void *data) +{ + ptSapContext sapContext; + tWLAN_SAPEvent sapEvent; + tHalHandle hHal = (tHalHandle)data; + tpAniSirGlobal pMac; + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return; + } + pMac = PMAC_STRUCT( hHal ); + sapContext = sap_find_valid_concurrent_session(hHal); + + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s no SAP contexts are found", __func__); + return; + } + + /* Check to ensure that SAP is in DFS WAIT state*/ + if (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT) + { + vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = VOS_FALSE; + + + /* + * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sapFsm + */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%p]", + sapContext->channel, sapContext); + + sapEvent.event = eSAP_DFS_CHANNEL_CAC_END; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + + sapFsm(sapContext, &sapEvent); + } + +} + +/* + * Function to stop the DFS CAC Timer + */ +static int sapStopDfsCacTimer(ptSapContext sapContext) +{ + tHalHandle hHal; + tpAniSirGlobal pMac; + if (sapContext == NULL) + return 0; + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return 0; + } + pMac = PMAC_STRUCT(hHal); + + if (VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState( + &pMac->sap.SapDfsInfo.sap_dfs_cac_timer)) { + return 0; + } + + vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; + + return 0; +} + +/* + * Function to start the DFS CAC Timer + * when SAP is started on a DFS channel + */ +int sapStartDfsCacTimer(ptSapContext sapContext) +{ + VOS_STATUS status; + v_U32_t cacTimeOut; + v_REGDOMAIN_t regDomain; + tHalHandle hHal = NULL; + tpAniSirGlobal pMac = NULL; + + if (sapContext == NULL) + { + return 0; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return 0; + } + pMac = PMAC_STRUCT( hHal ); + + if (pMac->sap.SapDfsInfo.ignore_cac) + { + /* + * If User has set to ignore the CAC + * so, continue without CAC Timer. + */ + return 2; + } + cacTimeOut = DEFAULT_CAC_TIMEOUT; + vos_nv_getRegDomainFromCountryCode(®Domain, + sapContext->csrRoamProfile.countryCode, COUNTRY_QUERY); + if ((regDomain == REGDOMAIN_ETSI) && + (IS_ETSI_WEATHER_CH(sapContext->channel))) + { + cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT; + } + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec", + sapContext->channel, cacTimeOut/1000); + + vos_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, + VOS_TIMER_TYPE_SW, + sapDfsCacTimerCallback, (v_PVOID_t)hHal); + + /*Start the CAC timer*/ + status = vos_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer, cacTimeOut); + if (status == VOS_STATUS_SUCCESS) + { + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = VOS_TRUE; + return 1; + } + else + { + return 0; + } +} + +/* + * This function initializes the NOL list + * parameters required to track the radar + * found DFS channels in the current Reg. Domain . + */ +VOS_STATUS sapInitDfsChannelNolList(ptSapContext sapContext) +{ + v_U8_t count = 0; + int i; + v_BOOL_t bFound = FALSE; + tHalHandle hHal; + tpAniSirGlobal pMac; + + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid sapContext pointer on sapInitDfsChannelNolList"); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + /* to indicate hdd to get cnss dfs nol */ + if (VOS_STATUS_SUCCESS == sapSignalHDDevent(sapContext, NULL, + eSAP_DFS_NOL_GET, + (v_PVOID_t) eSAP_STATUS_SUCCESS)) + { + bFound = TRUE; + } + + for ( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + if ( regChannels[i].enabled == NV_CHANNEL_DFS ) + { + /* if dfs nol is not found, initialize it */ + if (!bFound) + { + pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] + .dfs_channel_number = rfChannels[i].channelNum; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s: CHANNEL = %d", __func__, + pMac->sap.SapDfsInfo + .sapDfsChannelNolList[count].dfs_channel_number); + + pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] + .radar_status_flag = eSAP_DFS_CHANNEL_USABLE; + pMac->sap.SapDfsInfo.sapDfsChannelNolList[count] + .radar_found_timestamp = 0; + } + count++; + } + } + + pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s[%d] NUMBER OF DFS CHANNELS = %d", + __func__, __LINE__, + pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels); + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm_ext.h b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm_ext.h new file mode 100644 index 0000000000000..58d77e5274281 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapFsm_ext.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 */ + + +#ifndef __SAPFSM_EXT_H__ +#define __SAPFSM_EXT_H__ + +/* Events that can be sent to the SAP state-machine */ +typedef enum +{ + eSAP_TIMER_CONNECT_ACCEPT_TIMEOUT=0U, + eSAP_MAC_CONNECT_COMPLETED, + eSAP_CHANNEL_SELECTION_FAILED, + eSAP_MAC_CONNECT_INDICATION, + eSAP_MAC_KEY_SET_SUCCESS, + eSAP_RSN_FAILURE, + eSAP_MAC_SCAN_COMPLETE, + eSAP_HDD_START_INFRA_BSS, + eSAP_MAC_READY_FOR_CONNECTIONS, + eSAP_MAC_START_BSS_SUCCESS, + eSAP_MAC_START_BSS_FAILURE, + eSAP_RSN_SUCCESS, + eSAP_MAC_START_FAILS, + eSAP_HDD_STOP_INFRA_BSS, + eSAP_WRITE_REMOTE_AMP_ASSOC, + eSAP_DFS_CHANNEL_CAC_START, + eSAP_DFS_CHANNEL_CAC_RADAR_FOUND, + eSAP_DFS_CHANNEL_CAC_END, + eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START, + eSAP_OPERATING_CHANNEL_CHANGED, + + eSAP_NO_MSG +}eSapMsg_t; + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapInternal.h b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapInternal.h new file mode 100644 index 0000000000000..d3c20caee38f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapInternal.h @@ -0,0 +1,985 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANSAP_INTERNAL_H +#define WLAN_QCT_WLANSAP_INTERNAL_H + +/*=========================================================================== + + W L A N S A P P A L L A Y E R + I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal API exposed by the wlan SAP PAL layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/src/bapInternal.h,v 1.7 2009/03/09 08:50:43 rgidvani Exp rgidvani $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/15/08 SOFTAP Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" + +// Pick up the CSR API definitions +#include "csrApi.h" +#include "sapApi.h" +#include "sapFsm_ext.h" +#include "sapChSelect.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +//DFS Non Occupancy Period =30 minutes, in microseconds +#define SAP_DFS_NON_OCCUPANCY_PERIOD (30 * 60 * 1000 * 1000) + +#define SAP_DEBUG +// Used to enable or disable security on the BT-AMP link +#define WLANSAP_SECURITY_ENABLED_STATE VOS_TRUE +#ifdef WLAN_FEATURE_MBSSID +// When MBSSID feature is enabled, SAP context is directly passed to SAP APIs +#define VOS_GET_SAP_CB(ctx) (ptSapContext)(ctx) +#else +// How do I get SAP context from voss context? +#define VOS_GET_SAP_CB(ctx) vos_get_context( VOS_MODULE_ID_SAP, ctx) +#endif + +#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_PE, ctx) +//MAC Address length +#define ANI_EAPOL_KEY_RSN_NONCE_SIZE 32 + +#define IS_ETSI_WEATHER_CH(_ch) ((_ch >= 120) && (_ch <= 130)) +#define IS_CHAN_JAPAN_W53(_ch) ((_ch >= 52) && (_ch <= 64)) +#define IS_CHAN_JAPAN_INDOOR(_ch) ((_ch >= 36) && (_ch <= 64)) +#define IS_CHAN_JAPAN_OUTDOOR(_ch)((_ch >= 100) && (_ch <= 140)) +#define DEFAULT_CAC_TIMEOUT (60 * 1000) //msecs - 1 min +#define ETSI_WEATHER_CH_CAC_TIMEOUT (10 * 60 * 1000) //msecs - 10 min +#define SAP_CHAN_PREFERRED_INDOOR 1 +#define SAP_CHAN_PREFERRED_OUTDOOR 2 + +extern const sRegulatoryChannel *regChannels; + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +typedef struct sSapContext tSapContext; +// tSapContext, *ptSapContext; +/*---------------------------------------------------------------------------- + * Type Declarations - For internal SAP context information + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Opaque SAP context Type Declaration + * -------------------------------------------------------------------------*/ +// We were only using this syntax, when this was truly opaque. +// (I.E., it was defined in a different file.) + + +/* SAP FSM states for Access Point role */ +typedef enum { + eSAP_DISCONNECTED, + eSAP_CH_SELECT, + eSAP_DFS_CAC_WAIT, + eSAP_STARTING, + eSAP_STARTED, + eSAP_DISCONNECTING +} eSapFsmStates_t; + +/*---------------------------------------------------------------------------- + * SAP context Data Type Declaration + * -------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------- + * Type Declarations - QOS related + * -------------------------------------------------------------------------*/ +/* SAP QOS config */ +typedef struct sSapQosCfg { + v_U8_t WmmIsEnabled; +} tSapQosCfg; + +typedef struct sSapAcsChannelInfo { + v_U32_t channelNum; + v_U32_t weight; +}tSapAcsChannelInfo; + +typedef struct sSapContext { + + vos_lock_t SapGlobalLock; + + // Include the current channel of AP + v_U32_t channel; + + // Include the SME(CSR) sessionId here + v_U8_t sessionId; + + // Include the key material for this physical link + v_U8_t key_type; + v_U8_t key_length; + v_U8_t key_material[32]; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[VOS_MAC_ADDRESS_LEN]; + + // Own SSID + v_U8_t ownSsid[MAX_SSID_LEN]; + v_U32_t ownSsidLen; + + // Flag for signaling if security is enabled + v_U8_t ucSecEnabled; + + // Include the SME(CSR) context here + tCsrRoamProfile csrRoamProfile; + v_U32_t csrRoamId; + + //Sap session + tANI_BOOLEAN isSapSessionOpen; + + // SAP event Callback to hdd + tpWLAN_SAPEventCB pfnSapEventCallback; + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // Include the state machine structure here, state var that keeps track of state machine + eSapFsmStates_t sapsMachine; + + // Actual storage for AP and self (STA) SSID + tCsrSSIDInfo SSIDList[2]; + + // Actual storage for AP bssid + tCsrBssid bssid; + + // Mac filtering settings + eSapMacAddrACL eSapMacAddrAclMode; + v_MACADDR_t acceptMacList[MAX_ACL_MAC_ADDRESS]; + v_U8_t nAcceptMac; + v_MACADDR_t denyMacList[MAX_ACL_MAC_ADDRESS]; + v_U8_t nDenyMac; + + // QOS config + tSapQosCfg SapQosCfg; + + v_PVOID_t pUsrContext; + + v_U32_t nStaWPARSnReqIeLength; + v_U8_t pStaWpaRsnReqIE[MAX_ASSOC_IND_IE_LEN]; + tSirAPWPSIEs APWPSIEs; + tSirRSNie APWPARSNIEs; + + v_U32_t nStaAddIeLength; + v_U8_t pStaAddIE[MAX_ASSOC_IND_IE_LEN]; + v_U8_t *channelList; + tSapChannelListInfo SapChnlList; + + // session to scan + tANI_BOOLEAN isScanSessionOpen; + /* + * This list of channels will hold 5Ghz enabled,DFS in the + * Current RegDomain.This list will be used to select a channel, + * for SAP to start including any DFS channel and also to select + * any random channel[5Ghz-(NON-DFS/DFS)],if SAP is operating + * on a DFS channel and a RADAR is detected on the channel. + */ + tAll5GChannelList SapAllChnlList; + + + tANI_BOOLEAN allBandScanned; + eCsrBand currentPreferredBand; + eCsrBand scanBandPreference; + v_U16_t acsBandSwitchThreshold; + tSapAcsChannelInfo acsBestChannelInfo; + tANI_BOOLEAN enableOverLapCh; + v_BOOL_t apAutoChannelSelection; + v_U8_t apStartChannelNum; + v_U8_t apEndChannelNum; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + v_U8_t cc_switch_mode; +#endif +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + v_U8_t skip_acs_scan_status; + v_U8_t skip_acs_scan_range1_stch; + v_U8_t skip_acs_scan_range1_endch; + v_U8_t skip_acs_scan_range2_stch; + v_U8_t skip_acs_scan_range2_endch; +#endif + +#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) ||\ + defined(WLAN_FEATURE_MBSSID) + v_BOOL_t dfs_ch_disable; +#endif + tANI_BOOLEAN isCacEndNotified; + tANI_BOOLEAN isCacStartNotified; +} *ptSapContext; + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// The main per-Physical Link (per WLAN association) context. +extern ptSapContext gpSapCtx; + +/*---------------------------------------------------------------------------- + * SAP state machine event definition + * -------------------------------------------------------------------------*/ +/* The event structure */ +typedef struct sWLAN_SAPEvent { + v_PVOID_t params; /* A VOID pointer type for all possible inputs */ + v_U32_t event; /* State machine input event message */ + v_U32_t u1; /* introduced to handle csrRoamCompleteCallback roamStatus */ + v_U32_t u2; /* introduced to handle csrRoamCompleteCallback roamResult */ +} tWLAN_SAPEvent, *ptWLAN_SAPEvent; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANSAP_ScanCallback() + + DESCRIPTION + Callback for Scan (scan results) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle: the tHalHandle passed in with the scan request + *p2: the second context pass in for the caller, opaque sap Handle here + scanID: + sessionId: Session identifier + status: Status of scan -success, failure or abort + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +============================================================================*/ +eHalStatus +WLANSAP_ScanCallback +( + tHalHandle halHandle, + void *pContext, + v_U8_t sessionId, + v_U32_t scanID, + eCsrScanStatus scanStatus +); + +/*========================================================================== + + FUNCTION WLANSAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pCsrRoamInfo: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +============================================================================*/ +eHalStatus +WLANSAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + v_U32_t roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +); + +/*========================================================================== + + FUNCTION WLANSAP_CleanCB + + DESCRIPTION + Clear out all fields in the SAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pSapCtx: pointer to the SAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANSAP_CleanCB +( + ptSapContext pSapCtx, + v_U32_t freeFlag /* If 0 do not empty */ +); +/*========================================================================== + + FUNCTION WLANSapFsm + + DESCRIPTION + SAP forward state machine to handle the states of the SAP + + DEPENDENCIES + + PARAMETERS + + IN + sapContext: pointer to the SAP control block + sapEvent : SAP event + status : status of SAP state machine + + RETURN VALUE + Status of the SAP forward machine + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +SapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent, /* State machine event */ + v_U8_t *status /* return the SAP status here */ +); + +/*========================================================================== + + FUNCTION WLANSAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANSAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +); + +/*========================================================================== + + FUNCTION sapSelectChannel + + DESCRIPTION + Runs a algorithm to select the best channel to operate in for Soft AP in 2.4GHz band + + DEPENDENCIES + + PARAMETERS + + IN + halHandle : Pointer to HAL handle + pSapCtx : Pointer to SAP context + pResult : Pointer to tScanResultHandle + + RETURN VALUE + If SUCCESS channel number or zero for FAILURE. + + SIDE EFFECTS + +============================================================================*/ + +v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResultHandle pScanResult); + +/*========================================================================== + + FUNCTION sapSignalHDDevent + + DESCRIPTION + SAP HDD event callback function + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + pCsrRoamInfo : csrRoamprofile + sapHddevent : SAP HDD callback event + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +sapSignalHDDevent( ptSapContext sapContext, tCsrRoamInfo * pCsrRoamInfo, eSapHddEvent sapHddevent, void *); + +/*========================================================================== + + FUNCTION sapFsm + + DESCRIPTION + SAP Forward state machine + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + sapEvent : state machine event + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent /* State machine event */ +); + +/*========================================================================== + + FUNCTION sapConvertToCsrProfile + + DESCRIPTION + sapConvertToCsrProfile + + DEPENDENCIES + + PARAMETERS + + IN + pconfig_params : Pointer to configuration structure + bssType : SoftAP type + profile : pointer to a csrProfile that needs to be passed + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +eSapStatus +sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, tCsrRoamProfile *profile); + +/*========================================================================== + + FUNCTION sapFreeRoamProfile + + DESCRIPTION + sapConvertToCsrProfile + + DEPENDENCIES + + PARAMETERS + + IN + profile : pointer to a csrProfile that needs to be freed + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +void sapFreeRoamProfile(tCsrRoamProfile *profile); + +/*========================================================================== + + FUNCTION sapIsPeerMacAllowed + + DESCRIPTION + Function to implement MAC filtering for station association in SoftAP + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sapIsPeerMacAllowed(ptSapContext sapContext, v_U8_t *peerMac); + +/*========================================================================== + + FUNCTION sapSortMacList + + DESCRIPTION + Function to implement sorting of MAC addresses + + DEPENDENCIES + + PARAMETERS + + IN + macList : Pointer to mac address array + size : Number of entries in mac address array + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +sapSortMacList(v_MACADDR_t *macList, v_U8_t size); + +/*========================================================================== + + FUNCTION sapAddMacToACL + + DESCRIPTION + Function to ADD a mac address in an ACL. + The function ensures that the ACL list remains sorted after the addition. + This API does not take care of buffer overflow i.e. if the list is already + maxed out while adding a mac address, it will still try to add. + The caller must take care that the ACL size is less than MAX_ACL_MAC_ADDRESS + before calling this function. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size (I/O) : size of the ACL. It is an I/O arg. The API takes care + of incrementing the size by 1. + peerMac : Mac address of the peer to be added + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapAddMacToACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t *peerMac); + +/*========================================================================== + + FUNCTION sapRemoveMacFromACL + + DESCRIPTION + Function to REMOVE a mac address from an ACL. + The function ensures that the ACL list remains sorted after the DELETION. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size (I/O) : size of the ACL. It is an I/O arg. The API takes care of decrementing the size by 1. + index : index in the ACL list where the peerMac is present + This index can be found by using the "sapSearchMacList" API which returns the index of the MAC + addr, if found in an ACL, in one of the arguments passed by the caller. + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapRemoveMacFromACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t index); + +/*========================================================================== + + FUNCTION sapPrintACL + + DESCRIPTION + Function to print all the mac address of an ACL. + Useful for debug. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size : size of the ACL + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapPrintACL(v_MACADDR_t *macList, v_U8_t size); + +/*========================================================================== + + FUNCTION sapSearchMacList + + DESCRIPTION + Function to search for a mac address in an ACL + + DEPENDENCIES + + PARAMETERS + + IN + macList : list of mac addresses (black/white list) + num_mac : size of the ACL + peerMac : Mac address of the peer + OP + index : the index at which the peer mac is found + this value gets filled in this function. If the caller is not interested + in the index of the peerMac to be searched, it can pass NULL here. + + RETURN VALUE + SUCCESS : if the mac addr being searched for is found + FAILURE : if the mac addr being searched for is NOT found + + SIDE EFFECTS + +============================================================================*/ +eSapBool +sapSearchMacList(v_MACADDR_t *macList, v_U8_t num_mac, v_U8_t *peerMac, v_U8_t *index); + + +/*========================================================================== + + FUNCTION sap_AcquireGlobalLock + + DESCRIPTION + Function to implement acquire SAP global lock + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sap_AcquireGlobalLock( ptSapContext pSapCtx ); + +/*========================================================================== + + FUNCTION sapIsPeerMacAllowed + + DESCRIPTION + Function to implement release SAP global lock + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sap_ReleaseGlobalLock( ptSapContext pSapCtx ); + +#ifdef FEATURE_WLAN_CH_AVOID +/*========================================================================== + FUNCTION sapUpdateUnsafeChannelList + + DESCRIPTION + Function sapUpdateUnsafeChannelList updates the SAP context of unsafe channels. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + NULL + + RETURN VALUE + NULL +============================================================================*/ +void sapUpdateUnsafeChannelList(void); +#endif /* FEATURE_WLAN_CH_AVOID */ + +/*--------------------------------------------------------------------------- +FUNCTION sapIndicateRadar + +DESCRIPTION Function to implement actions on Radar Detection when SAP is on + DFS Channel + +DEPENDENCIES PARAMETERS +IN sapContext : Sap Context which hold SapDfsInfo + dfs_event : Event from DFS Module + +RETURN VALUE : Target Channel For SAP to Move on to when Radar is Detected. + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +v_U8_t +sapIndicateRadar(ptSapContext sapContext,tSirSmeDfsEventInd *dfs_event); + +/* + * This function initializes the NOL list + * parameters required to track the radar + * found DFS channels in the current Reg. Domain. + */ +VOS_STATUS +sapInitDfsChannelNolList(ptSapContext sapContext); + +/* + * This Function Checks if a given channel is AVAILABLE or USABLE + * for DFS operation. + */ +v_BOOL_t sapDfsIsChannelInNolList(ptSapContext sapContext, + v_U8_t channelNumber, ePhyChanBondState chanBondState); +/*--------------------------------------------------------------------------- +FUNCTION sapDfsCacTimerCallback + +DESCRIPTION Function will be called up on DFS CAC timer expiry + +DEPENDENCIES PARAMETERS + data : void pointer to the data which being passed. + +RETURN VALUE : void + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +void sapDfsCacTimerCallback(void *data); + + +/*--------------------------------------------------------------------------- +FUNCTION sap_CacResetNotify + +DESCRIPTION Function will be called up on stop bss indication to clean up + DFS global structure. + +DEPENDENCIES PARAMETERS +IN hHAL : HAL pointer + +RETURN VALUE : void. + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +void sap_CacResetNotify(tHalHandle hHal); + +v_BOOL_t sapAcsChannelCheck(ptSapContext sapContext, v_U8_t channelNumber); + +/* + * This function is added to check if channel is in tx leak range + * + * PARAMETERS + * IN + * sapContext: Pointer to vos global context structure + * target_channel: the target channel to switch to + * + * RETURN VALUE + * BOOLEAN to indicate if the target channel is good or bad to switch + * + * TRUE: the channel is above the tx leak threshold + * FALSE: good to be used + */ +v_BOOL_t +sapChannelMatrixCheck(ptSapContext sapContext, + ePhyChanBondState cbMode, + v_U8_t target_channel); + +/* + * This function will find the concurrent sap context apart from + * passed sap context and return its channel change ready status + * + * PARAMETERS + * IN + * sapContext: pointer to sap context + * hHal: pointer to hal structure. + * + * RETURN VALUE + * v_BOOL_t + * returns change change ready indication for concurrent sapctx + */ +v_BOOL_t is_concurrent_sap_ready_for_channel_change(tHalHandle hHal, + ptSapContext sapContext); + +/* + * This function will calculate how many interfaces + * have sap persona and returns total number of sap persona. + * + * PARAMETERS + * IN + * hHal: pointer to hal structure. + * + * RETURN VALUE + * v_U8_t + * Returns total number of sap interfaces. + * + */ +v_U8_t sap_get_total_number_sap_intf(tHalHandle hHal); +/*--------------------------------------------------------------------------- +FUNCTION sapFetchRegulatoryDomain + +DESCRIPTION Fetches the Regulatory domain based up on the coutry code. + +DEPENDENCIES PARAMETERS +IN hHAL : HAL pointer + +RETURN VALUE : v_REGDOMAIN_t, returns the regulatory domain + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +v_REGDOMAIN_t sapFetchRegulatoryDomain(tHalHandle hHal); + +/*--------------------------------------------------------------------------- +FUNCTION sapDfsIsW53Invalid + +DESCRIPTION Checks if the passed channel is W53 and returns if + SAP W53 opearation is allowed. + +DEPENDENCIES PARAMETERS +IN hHAL : HAL pointer +channelID: Channel Number to be verified + +RETURN VALUE : v_BOOL_t + VOS_TRUE: If W53 operation is disabled + VOS_FALSE: If W53 operation is enabled + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +v_BOOL_t sapDfsIsW53Invalid(tHalHandle hHal, v_U8_t channelID); + +/*--------------------------------------------------------------------------- +FUNCTION sapDfsIsChannelInPreferredLocation + +DESCRIPTION Checks if the passed channel is in accordance with preferred + Channel location settings. + +DEPENDENCIES PARAMETERS +IN hHAL : HAL pointer +channelID: Channel Number to be verified + +RETURN VALUE :v_BOOL_t + VOS_TRUE:If Channel location is same as the preferred location + VOS_FALSE:If Channel location is not same as the preferred location + +SIDE EFFECTS +---------------------------------------------------------------------------*/ +v_BOOL_t sapDfsIsChannelInPreferredLocation(tHalHandle hHal, v_U8_t channelID); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef WLAN_QCT_WLANSAP_INTERNAL_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SAP/src/sapModule.c b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapModule.c new file mode 100644 index 0000000000000..0786da6558d1c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SAP/src/sapModule.c @@ -0,0 +1,3704 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p M o d u l e . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions providing EXTERNAL APIs. It is also where the global SAP module + context gets initialised + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +03/15/10 SOFTAP team Created module +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure + +===========================================================================*/ + +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tl.h" +#include "vos_trace.h" + +// Pick up the sme callback registration API +#include "sme_Api.h" + +// SAP API header file + +#include "sapInternal.h" +#include "smeInside.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define SAP_DEBUG + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// No! Get this from VOS. +// The main per-Physical Link (per WLAN association) context. +ptSapContext gpSapCtx; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION WLANSAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). SAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + + RETURN VALUE + The result code associated with performing the operation + +#ifdef WLAN_FEATURE_MBSSID + v_PVOID_t : Pointer to the SAP context +#else + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success +#endif + + SIDE EFFECTS +============================================================================*/ +#ifdef WLAN_FEATURE_MBSSID +v_PVOID_t +#else +VOS_STATUS +#endif +WLANSAP_Open +( + v_PVOID_t pvosGCtx +) +{ + ptSapContext pSapCtx = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ +#ifdef WLAN_FEATURE_MBSSID + // amically allocate the sapContext + pSapCtx = (ptSapContext)vos_mem_malloc(sizeof(tSapContext)); +#else + if (NULL == pvosGCtx) + { + VOS_ASSERT(pvosGCtx); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) SAP control block + ------------------------------------------------------------------------*/ + vos_alloc_context(pvosGCtx, VOS_MODULE_ID_SAP, (v_VOID_t **)&pSapCtx, sizeof(tSapContext)); +#endif + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); +#ifdef WLAN_FEATURE_MBSSID + return NULL; +#else + return VOS_STATUS_E_FAULT; +#endif + } + + vos_mem_zero(pSapCtx, sizeof(tSapContext)); + + /*------------------------------------------------------------------------ + Clean up SAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_Open"); + + WLANSAP_CleanCB(pSapCtx, 0 /*do not empty*/); + + // Setup the "link back" to the VOSS context + pSapCtx->pvosGCtx = pvosGCtx; + + // Store a pointer to the SAP context provided by VOSS + gpSapCtx = pSapCtx; + + /*------------------------------------------------------------------------ + Allocate internal resources + ------------------------------------------------------------------------*/ + +#ifdef WLAN_FEATURE_MBSSID + return pSapCtx; +#else + return VOS_STATUS_SUCCESS; +#endif +}// WLANSAP_Open + +/*========================================================================== + FUNCTION WLANSAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). SAP will + use this call to register with TL as the SAP entity for + SAP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_Start +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Start invoked successfully"); + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + pSapCtx = VOS_GET_SAP_CB(pCtx); + + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + For now, presume security is not enabled. + -----------------------------------------------------------------------*/ + pSapCtx->ucSecEnabled = WLANSAP_SECURITY_ENABLED_STATE; + + + /*------------------------------------------------------------------------ + Now configure the roaming profile links. To SSID and bssid. + ------------------------------------------------------------------------*/ + // We have room for two SSIDs. + pSapCtx->csrRoamProfile.SSIDs.numOfSSIDs = 1; // This is true for now. + pSapCtx->csrRoamProfile.SSIDs.SSIDList = pSapCtx->SSIDList; //Array of two + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].SSID.length = 0; + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].handoffPermitted = VOS_FALSE; + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].ssidHidden = pSapCtx->SSIDList[0].ssidHidden; + + pSapCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; // This is true for now. + pSapCtx->csrRoamProfile.BSSIDs.bssid = &pSapCtx->bssid; + + // Now configure the auth type in the roaming profile. To open. + pSapCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pSapCtx->SapGlobalLock))) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "WLANSAP_Start failed init lock"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Start */ + +/*========================================================================== + + FUNCTION WLANSAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in SAP, before close. SAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Stop invoked successfully "); + + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sapFreeRoamProfile(&pSapCtx->csrRoamProfile); + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pSapCtx->SapGlobalLock ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "WLANSAP_Stop failed destroy lock"); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Stop SAP (de-register RSN handler!?) + ------------------------------------------------------------------------*/ + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Stop */ + +/*========================================================================== + FUNCTION WLANSAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. SAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Close +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Close invoked"); + + + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Cleanup SAP control block. + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_Close"); + WLANSAP_CleanCB(pSapCtx, VOS_TRUE /* empty queues/lists/pkts if any*/); + +#ifdef WLAN_FEATURE_MBSSID + vos_mem_free(pSapCtx); +#else + /*------------------------------------------------------------------------ + Free SAP context from VOSS global + ------------------------------------------------------------------------*/ + vos_free_context(pCtx, VOS_MODULE_ID_SAP, pSapCtx); +#endif + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Close */ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANSAP_CleanCB + + DESCRIPTION + Clear out all fields in the SAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_CleanCB +( + ptSapContext pSapCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +) +{ + /*------------------------------------------------------------------------ + Sanity check SAP control block + ------------------------------------------------------------------------*/ + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up SAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_CleanCB"); + + vos_mem_zero( pSapCtx, sizeof(tSapContext)); + + pSapCtx->pvosGCtx = NULL; + + pSapCtx->sapsMachine= eSAP_DISCONNECTED; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initializing State: %d, sapContext value = %p", + __func__, pSapCtx->sapsMachine, pSapCtx); + pSapCtx->sessionId = 0; + pSapCtx->channel = 0; + pSapCtx->isSapSessionOpen = eSAP_FALSE; + + return VOS_STATUS_SUCCESS; +}// WLANSAP_CleanCB + +/*========================================================================== + FUNCTION WLANSAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + RETURN VALUE + None + + SIDE EFFECTS +============================================================================*/ +void +WLANSAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +) +{ + if(HAL_STATUS_SUCCESS(status)) + { + //If success what else to be handled??? + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "WLANSAP_pmcFullPwrReqCB: PMC failed to put the chip in Full power"); + + } + +}// WLANSAP_pmcFullPwrReqCB + +/*========================================================================== + FUNCTION WLANSAP_getState + + DESCRIPTION + This api returns the current SAP state to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + Returns the SAP FSM state. +============================================================================*/ + +v_U8_t WLANSAP_getState +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = NULL; + + pSapCtx = VOS_GET_SAP_CB(pCtx); + + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + return pSapCtx->sapsMachine; +} + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/*========================================================================== + FUNCTION WLANSAP_CheckCCIntf + + DESCRIPTION Restart SAP if Concurrent Channel interfering + + DEPENDENCIES NA. + + PARAMETERS + IN + Ctx: Pointer to vos Context or Sap Context based on MBSSID + + RETURN VALUE NONE + + SIDE EFFECTS +============================================================================*/ +v_U16_t WLANSAP_CheckCCIntf(v_PVOID_t Ctx) +{ + tHalHandle hHal; + v_U16_t intf_ch; + ptSapContext pSapCtx = VOS_GET_SAP_CB(Ctx); + + hHal = (tHalHandle)VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid MAC context from pvosGCtx", __func__); + return 0; + } + intf_ch = sme_CheckConcurrentChannelOverlap(hHal, 0, 0, + pSapCtx->cc_switch_mode); + return intf_ch; +} +#endif +/*========================================================================== + FUNCTION WLANSAP_StartBss + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_PHYSICAL_LINK_CREATE for + starting AP BSS + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pQctCommitConfig : Pointer to configuration structure passed down from HDD(HostApd for Android) + hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD about SAP results + pUsrContext : Parameter that will be passed back in all the SAP callback events. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StartBss +( + v_PVOID_t pCtx,//pwextCtx + tpWLAN_SAPEventCB pSapEventCallback, + tsap_Config_t *pConfig, + v_PVOID_t pUsrContext +) +{ + tWLAN_SAPEvent sapEvent; /* State machine event*/ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + tANI_BOOLEAN restartNeeded; + tHalHandle hHal; + tpAniSirGlobal pmac = NULL; + int ret; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_StartBss: sapContext=%p", pSapCtx); + + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pSapCtx->sapsMachine = eSAP_DISCONNECTED; + + /* Channel selection is auto or configured */ + pSapCtx->channel = pConfig->channel; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + pSapCtx->cc_switch_mode = pConfig->cc_switch_mode; +#endif + pSapCtx->scanBandPreference = pConfig->scanBandPreference; + pSapCtx->acsBandSwitchThreshold = pConfig->acsBandSwitchThreshold; + pSapCtx->pUsrContext = pUsrContext; + pSapCtx->apAutoChannelSelection = pConfig->apAutoChannelSelection; + pSapCtx->apStartChannelNum = pConfig->apStartChannelNum; + pSapCtx->apEndChannelNum = pConfig->apEndChannelNum; +#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE + pSapCtx->skip_acs_scan_status = pConfig->skip_acs_scan_status; + pSapCtx->skip_acs_scan_range1_endch = pConfig->skip_acs_scan_range1_endch; + pSapCtx->skip_acs_scan_range1_stch = pConfig->skip_acs_scan_range1_stch; + pSapCtx->skip_acs_scan_range2_endch = pConfig->skip_acs_scan_range2_endch; + pSapCtx->skip_acs_scan_range2_stch = pConfig->skip_acs_scan_range2_stch; +#endif + pSapCtx->enableOverLapCh = pConfig->enOverLapCh; + if (strlen(pConfig->acsAllowedChnls) > 0) + { +#ifdef WLAN_FEATURE_MBSSID + ret = sapSetPreferredChannel(pSapCtx, pConfig->acsAllowedChnls); +#else + ret = sapSetPreferredChannel(pConfig->acsAllowedChnls); +#endif + if (0 != ret) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: ACS set preferred channel failed!", __func__); + } + } + + //Set the BSSID to your "self MAC Addr" read the mac address from Configuation ITEM received from HDD + pSapCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pSapCtx->csrRoamProfile.BSSIDs.bssid, + pSapCtx->self_mac_addr, + sizeof( tCsrBssid ) ); + + //Save a copy to SAP context + vos_mem_copy(pSapCtx->csrRoamProfile.BSSIDs.bssid, + pConfig->self_macaddr.bytes, sizeof(v_MACADDR_t)); + vos_mem_copy(pSapCtx->self_mac_addr, + pConfig->self_macaddr.bytes, sizeof(v_MACADDR_t)); + + //copy the configuration items to csrProfile + sapconvertToCsrProfile( pConfig, eCSR_BSS_TYPE_INFRA_AP, &pSapCtx->csrRoamProfile); + hHal = (tHalHandle)VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid MAC context from pvosGCtx", __func__); + } + else + { + //If concurrent session is running that is already associated + //then we just follow that sessions country info (whether + //present or not doesn't maater as we have to follow whatever + //STA session does) + if ((0 == sme_GetConcurrentOperationChannel(hHal)) && + pConfig->ieee80211d) + { + /* Setting the region/country information */ + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + } + + pmac = PMAC_STRUCT( hHal ); + /* + * Copy the DFS Test Mode setting to pmac for + * access in lower layers + */ + pmac->sap.SapDfsInfo.disable_dfs_ch_switch = + pConfig->disableDFSChSwitch; + // Copy MAC filtering settings to sap context + pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; + vos_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac, sizeof(pConfig->accept_mac)); + pSapCtx->nAcceptMac = pConfig->num_accept_mac; + sapSortMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + vos_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, sizeof(pConfig->deny_mac)); + pSapCtx->nDenyMac = pConfig->num_deny_mac; + sapSortMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac); + /* Fill in the event structure for FSM */ + sapEvent.event = eSAP_HDD_START_INFRA_BSS; + sapEvent.params = 0;//pSapPhysLinkCreate + + /* Store the HDD callback in SAP context */ + pSapCtx->pfnSapEventCallback = pSapEventCallback; + + /* Handle event*/ + vosStatus = sapFsm(pSapCtx, &sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "SoftAp role has not been enabled"); + } + + return vosStatus; +}// WLANSAP_StartBss + +/*========================================================================== + FUNCTION WLANSAP_SetMacACL + + DESCRIPTION + This api function provides SAP to set mac list entry in accept list as well + as deny list + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pQctCommitConfig : Pointer to configuration structure passed down from + HDD(HostApd for Android) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMacACL +( + v_PVOID_t pCtx, //pwextCtx + tsap_Config_t *pConfig +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_SetMacACL"); + + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + // Copy MAC filtering settings to sap context + pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; + + if (eSAP_DENY_UNLESS_ACCEPTED == pSapCtx->eSapMacAddrAclMode) + { + vos_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac, + sizeof(pConfig->accept_mac)); + pSapCtx->nAcceptMac = pConfig->num_accept_mac; + sapSortMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + } + else if (eSAP_ACCEPT_UNLESS_DENIED == pSapCtx->eSapMacAddrAclMode) + { + vos_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, + sizeof(pConfig->deny_mac)); + pSapCtx->nDenyMac = pConfig->num_deny_mac; + sapSortMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s : SoftAp role has not been enabled", __func__); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +}//WLANSAP_SetMacACL + +/*========================================================================== + FUNCTION WLANSAP_StopBss + + DESCRIPTION + This api function provides SAP FSM event eSAP_HDD_STOP_INFRA_BSS for + stopping AP BSS + + DEPENDENCIES + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to VOSS GC is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StopBss +( + v_PVOID_t pCtx +) +{ + tWLAN_SAPEvent sapEvent; /* State machine event*/ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if ( NULL == pCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Global VOSS handle", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx = VOS_GET_SAP_CB(pCtx); + + if (NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the event structure for FSM */ + sapEvent.event = eSAP_HDD_STOP_INFRA_BSS; + sapEvent.params = 0; + + /* Handle event*/ + vosStatus = sapFsm(pSapCtx, &sapEvent); + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_GetAssocStations + + DESCRIPTION + This api function is used to probe the list of associated stations from various modules of CORE stack + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + modId : Module from whom list of associtated stations is supposed to be probed. If an invalid module is passed + then by default VOS_MODULE_ID_PE will be probed + IN/OUT + pAssocStas : Pointer to list of associated stations that are known to the module specified in mod parameter + + NOTE: The memory for this list will be allocated by the caller of this API + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetAssocStations +( + v_PVOID_t pCtx, + VOS_MODULE_ID modId, + tpSap_AssocMacAddr pAssocStas +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetAssociatedStas( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + modId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + (v_U8_t *)pAssocStas ); + + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WLANSAP_RemoveWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to remove an entry from session session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pRemoveMac: pointer to v_MACADDR_t for session MAC address + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Session is not dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_RemoveWpsSessionOverlap + +( + v_PVOID_t pCtx, + v_MACADDR_t pRemoveMac +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetWpsSessionOverlap( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + pRemoveMac); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_getWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_getWpsSessionOverlap +( + v_PVOID_t pCtx +) +{ + v_MACADDR_t pRemoveMac = VOS_MAC_ADDR_ZERO_INITIALIZER; + + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetWpsSessionOverlap( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + pRemoveMac); + + return VOS_STATUS_SUCCESS; +} + + +/* This routine will set the mode of operation for ACL dynamically*/ +VOS_STATUS +WLANSAP_SetMode +( + v_PVOID_t pCtx, + v_U32_t mode +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx->eSapMacAddrAclMode = (eSapMacAddrACL)mode; + return VOS_STATUS_SUCCESS; +} + +/* Get ACL Mode */ +VOS_STATUS +WLANSAP_GetACLMode +( + v_PVOID_t pCtx, + eSapMacAddrACL *mode +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + *mode = pSapCtx->eSapMacAddrAclMode; + return VOS_STATUS_SUCCESS; +} + +/* API to get ACL Accept List */ +VOS_STATUS +WLANSAP_GetACLAcceptList +( + v_PVOID_t pCtx, + v_MACADDR_t *pAcceptList, + v_U8_t *nAcceptList +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + memcpy((void *)pAcceptList, (void *)pSapCtx->acceptMacList, + (pSapCtx->nAcceptMac*sizeof(v_MACADDR_t))); + *nAcceptList = pSapCtx->nAcceptMac; + return VOS_STATUS_SUCCESS; +} + +/* API to get Deny List */ +VOS_STATUS +WLANSAP_GetACLDenyList +( + v_PVOID_t pCtx, + v_MACADDR_t *pDenyList, + v_U8_t *nDenyList +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + memcpy((void *)pDenyList, (void *)pSapCtx->denyMacList, + (pSapCtx->nDenyMac*sizeof(v_MACADDR_t))); + *nDenyList = pSapCtx->nDenyMac; + return VOS_STATUS_SUCCESS; +} + +/* This routine will clear all the entries in accept list as well as deny list */ + +VOS_STATUS +WLANSAP_ClearACL +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + v_U8_t i; + + if (NULL == pSapCtx) + { + return VOS_STATUS_E_RESOURCES; + } + + if (pSapCtx->denyMacList != NULL) + { + for (i = 0; i < (pSapCtx->nDenyMac-1); i++) + { + vos_mem_zero((pSapCtx->denyMacList+i)->bytes, sizeof(v_MACADDR_t)); + + } + } + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + pSapCtx->nDenyMac = 0; + + if (pSapCtx->acceptMacList!=NULL) + { + for (i = 0; i < (pSapCtx->nAcceptMac-1); i++) + { + vos_mem_zero((pSapCtx->acceptMacList+i)->bytes, sizeof(v_MACADDR_t)); + + } + } + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + pSapCtx->nAcceptMac = 0; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS +WLANSAP_ModifyACL +( + v_PVOID_t pCtx, + v_U8_t *pPeerStaMac, + eSapACLType listType, + eSapACLCmdType cmd +) +{ + eSapBool staInWhiteList=eSAP_FALSE, staInBlackList=eSAP_FALSE; + v_U8_t staWLIndex, staBLIndex; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP Context", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"Modify ACL entered\n" + "Before modification of ACL\n" + "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** WHITE LIST ***"); + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** BLACK LIST ***"); + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + + /* the expectation is a mac addr will not be in both the lists at the same time. + It is the responsiblity of userspace to ensure this */ + staInWhiteList = sapSearchMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac, pPeerStaMac, &staWLIndex); + staInBlackList = sapSearchMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac, pPeerStaMac, &staBLIndex); + + if (staInWhiteList && staInBlackList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Peer mac "MAC_ADDRESS_STR" found in white and black lists." + "Initial lists passed incorrect. Cannot execute this command.", + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + + } + + switch(listType) + { + case eSAP_WHITE_LIST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "cmd %d", cmd); + if (cmd == ADD_STA_TO_ACL) + { + //error check + // if list is already at max, return failure + if (pSapCtx->nAcceptMac == MAX_ACL_MAC_ADDRESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "White list is already maxed out. Cannot accept "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + if (staInWhiteList) + { + //Do nothing if already present in white list. Just print a warning + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address already present in white list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + } else + { + if (staInBlackList) + { + //remove it from black list before adding to the white list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "STA present in black list so first remove from it"); + sapRemoveMacFromACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, staBLIndex); + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "... Now add to the white list"); + sapAddMacToACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + } + else if (cmd == DELETE_STA_FROM_ACL) + { + if (staInWhiteList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "Delete from white list"); + sapRemoveMacFromACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, staWLIndex); + /* If a client is deleted from white list and the client is connected, send deauth*/ + WLANSAP_DeauthSta(pCtx, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address to be deleted is not present in the white list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Invalid cmd type passed"); + return VOS_STATUS_E_FAILURE; + } + break; + + case eSAP_BLACK_LIST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "cmd %d", cmd); + if (cmd == ADD_STA_TO_ACL) + { + //error check + // if list is already at max, return failure + if (pSapCtx->nDenyMac == MAX_ACL_MAC_ADDRESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Black list is already maxed out. Cannot accept "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + if (staInBlackList) + { + //Do nothing if already present in white list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address already present in black list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + } else + { + if (staInWhiteList) + { + //remove it from white list before adding to the black list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "Present in white list so first remove from it"); + sapRemoveMacFromACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, staWLIndex); + } + /* If we are adding a client to the black list; if its connected, send deauth */ + WLANSAP_DeauthSta(pCtx, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "... Now add to black list"); + sapAddMacToACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + } + else if (cmd == DELETE_STA_FROM_ACL) + { + if (staInBlackList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "Delete from black list"); + sapRemoveMacFromACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, staBLIndex); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"no accept and deny mac %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address to be deleted is not present in the black list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Invalid cmd type passed"); + return VOS_STATUS_E_FAILURE; + } + break; + + default: + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid list type passed %d",listType); + return VOS_STATUS_E_FAILURE; + } + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"After modification of ACL"); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** WHITE LIST ***"); + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** BLACK LIST ***"); + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_DisassocSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated disassociation of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pPeerStaMac : Mac address of the station to disassociate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DisassocSta +( + v_PVOID_t pCtx, + v_U8_t *pPeerStaMac +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamDisconnectSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pPeerStaMac); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_DeauthSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated deauthentication of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pPeerStaMac : Mac address of the station to deauthenticate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DeauthSta +( + v_PVOID_t pCtx, + v_U8_t *pPeerStaMac +) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return vosStatus; + } + + halStatus = sme_RoamDeauthSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pPeerStaMac); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + vosStatus = VOS_STATUS_SUCCESS; + } + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_SetChannelChangeWithCsa + + DESCRIPTION + This api function does a channel change to the target channel specified + through an iwpriv. CSA IE is included in the beacons before doing a + channel change. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + targetChannel : New target channel to change to. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelChangeWithCsa(v_PVOID_t pvosGCtx, v_U32_t targetChannel) +{ + + ptSapContext sapContext = NULL; + tWLAN_SAPEvent sapEvent; + tpAniSirGlobal pMac = NULL; + v_PVOID_t hHal = NULL; + + sapContext = VOS_GET_SAP_CB( pvosGCtx ); + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + /* + * Validate if the new target channel is a valid + * 5 Ghz Channel. We prefer to move to another + * channel in 5 Ghz band. + */ + if ( (targetChannel < rfChannels[RF_CHAN_36].channelNum) + || + (targetChannel > rfChannels[RF_CHAN_165].channelNum) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel = %d passed,Channel not in 5GHz band", + __func__, targetChannel); + + return VOS_STATUS_E_FAULT; + } + + /* + * Now, validate if the passed channel is valid in the + * current regulatory domain. + */ + if ( (vos_nv_getChannelEnabledState(targetChannel) == NV_CHANNEL_ENABLE) + || + (vos_nv_getChannelEnabledState(targetChannel) == NV_CHANNEL_DFS) ) + { + /* + * Post a CSA IE request to SAP state machine with + * target channel information and also CSA IE required + * flag set in sapContext only, if SAP is in eSAP_STARTED + * state. + */ + if (eSAP_STARTED == sapContext->sapsMachine) + { + /* + * Copy the requested target channel + * to sap context. + */ + pMac->sap.SapDfsInfo.target_channel = targetChannel; + + /* + * Set the CSA IE required flag. + */ + pMac->sap.SapDfsInfo.csaIERequired = VOS_TRUE; + + /* + * Set the radar found status to allow the channel + * change to happen same as in the case of a radar + * detection. Since, this will allow SAP to be in + * correct state and also resume the netif queues + * that were suspended in HDD before the channel + * request was issued. + */ + pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_TRUE; + + /* + * Post the eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START + * to SAP state machine to process the channel + * request with CSA IE set in the beacons. + */ + sapEvent.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START; + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + + sapFsm(sapContext, &sapEvent); + + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to request Channel Change, since" + "SAP is not in eSAP_STARTED state", __func__); + return VOS_STATUS_E_FAULT; + } + + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Channel = %d is not valid in the current" + "regulatory domain", + __func__, targetChannel); + + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Posted eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START" + "successfully to sapFsm for Channel = %d", + __func__, targetChannel); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_SetChannelRange + + DESCRIPTION + This api function sets the range of channels for AP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + startChannel : start channel + endChannel : End channel + operatingBand : Operating band (2.4GHz/5GHz) + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelRange(tHalHandle hHal,v_U8_t startChannel, v_U8_t endChannel, + eSapOperatingBand operatingBand) +{ + + v_U8_t validChannelFlag =0; + v_U8_t loopStartCount =0; + v_U8_t loopEndCount =0; + v_U8_t bandStartChannel =0; + v_U8_t bandEndChannel =0; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "WLANSAP_SetChannelRange:startChannel %d,EndChannel %d,Operatingband:%d", + startChannel,endChannel,operatingBand); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN > operatingBand) || + (WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX < operatingBand)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid operatingBand on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + if (( WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN > startChannel) || + (WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX < startChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid startChannel value on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + if (( WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN > endChannel) || + (WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX < endChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid endChannel value on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + switch(operatingBand) + { + case eSAP_RF_SUBBAND_2_4_GHZ: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + + case eSAP_RF_SUBBAND_5_LOW_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_64; + break; + + case eSAP_RF_SUBBAND_5_MID_GHZ: + bandStartChannel = RF_CHAN_100; +#ifndef FEATURE_WLAN_CH144 + bandEndChannel = RF_CHAN_140; +#else + bandEndChannel = RF_CHAN_144; +#endif /* FEATURE_WLAN_CH144 */ + break; + + case eSAP_RF_SUBBAND_5_HIGH_GHZ: + bandStartChannel = RF_CHAN_149; + bandEndChannel = RF_CHAN_165; + break; + + case eSAP_RF_SUBBAND_5_ALL_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid operatingBand value on WLANSAP_SetChannelRange"); + break; + } + + /* Validating the start channel is in range or not*/ + for(loopStartCount = bandStartChannel ; loopStartCount <= bandEndChannel ; + loopStartCount++) + { + if(rfChannels[loopStartCount].channelNum == startChannel ) + { + /* start channel is in the range */ + break; + } + } + /* Validating the End channel is in range or not*/ + for(loopEndCount = bandStartChannel ; loopEndCount <= bandEndChannel ; + loopEndCount++) + { + if(rfChannels[loopEndCount].channelNum == endChannel ) + { + /* End channel is in the range */ + break; + } + } + if((loopStartCount > bandEndChannel)||(loopEndCount > bandEndChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid startChannel-%d or EndChannel-%d for band -%d", + __func__,startChannel,endChannel,operatingBand); + /* Supplied channels are nt in the operating band so set the default + channels for the given operating band */ + startChannel = rfChannels[bandStartChannel].channelNum; + endChannel = rfChannels[bandEndChannel].channelNum; + } + + /*Search for the Active channels in the given range */ + for( loopStartCount = bandStartChannel; loopStartCount <= bandEndChannel; loopStartCount++ ) + { + if((startChannel <= rfChannels[loopStartCount].channelNum)&& + (endChannel >= rfChannels[loopStartCount].channelNum )) + { + if( regChannels[loopStartCount].enabled ) + { + validChannelFlag = 1; + break; + } + } + } + if(0 == validChannelFlag) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s-No active channels present in the given range for the current region", + __func__); + /* There is no active channel in the supplied range.Updating the config + with the default channels in the given band so that we can select the best channel in the sub-band*/ + startChannel = rfChannels[bandStartChannel].channelNum; + endChannel = rfChannels[bandEndChannel].channelNum; + } + + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + operatingBand, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND to CCn"); + return VOS_STATUS_E_FAULT; + } + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + startChannel, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL to CCM"); + return VOS_STATUS_E_FAULT; + + } + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + endChannel, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL to CCM"); + return VOS_STATUS_E_FAULT; + } + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_SetCounterMeasure + + DESCRIPTION + This api function is used to disassociate all the stations and prevent + association for any other station.Whenever Authenticator receives 2 mic failures + within 60 seconds, Authenticator will enable counter measure at SAP Layer. + Authenticator will start the 60 seconds timer. Core stack will not allow any + STA to associate till HDD disables counter meassure. Core stack shall kick out all the + STA which are currently associated and DIASSOC Event will be propogated to HDD for + each STA to clean up the HDD STA table.Once the 60 seconds timer expires, Authenticator + will disable the counter meassure at core stack. Now core stack can allow STAs to associate. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + bEnable: If TRUE than all stations will be disassociated and no more + will be allowed to associate. If FALSE than CORE + will come out of this state. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetCounterMeasure +( + v_PVOID_t pCtx, + v_BOOL_t bEnable +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamTKIPCounterMeasures(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, bEnable); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION WLANSAP_SetKeysSta + + DESCRIPTION + This api function provides for Ap App/HDD to set key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pSetKeyInfo : tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetKeySta +( + v_PVOID_t pCtx, + tCsrRoamSetKey *pSetKeyInfo +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_U32_t roamId=0xFF; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + halStatus = sme_RoamSetKey(hHal, pSapCtx->sessionId, pSetKeyInfo, &roamId); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + vosStatus = VOS_STATUS_SUCCESS; + } else + { + vosStatus = VOS_STATUS_E_FAULT; + } + } + else + vosStatus = VOS_STATUS_E_FAULT; + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_DelKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pSetKeyInfo : tCsrRoamRemoveKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DelKeySta +( + v_PVOID_t pCtx, + tCsrRoamRemoveKey *pRemoveKeyInfo +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_U32_t roamId=0xFF; + tCsrRoamRemoveKey RemoveKeyInfo; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero(&RemoveKeyInfo, sizeof(RemoveKeyInfo)); + RemoveKeyInfo.encType = pRemoveKeyInfo->encType; + vos_mem_copy(RemoveKeyInfo.peerMac, pRemoveKeyInfo->peerMac, VOS_MAC_ADDR_SIZE); + RemoveKeyInfo.keyId = pRemoveKeyInfo->keyId; + + halStatus = sme_RoamRemoveKey(hHal, pSapCtx->sessionId, &RemoveKeyInfo, &roamId); + + if (HAL_STATUS_SUCCESS(halStatus)) + { + vosStatus = VOS_STATUS_SUCCESS; + } + else + { + vosStatus = VOS_STATUS_E_FAULT; + } + } + else + vosStatus = VOS_STATUS_E_FAULT; + + return vosStatus; +} + +VOS_STATUS +WLANSap_getstationIE_information +( + v_PVOID_t pCtx, + v_U32_t *pLen, + v_U8_t *pBuf +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + ptSapContext pSapCtx = NULL; + v_U32_t len = 0; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + if (pLen) + { + len = *pLen; + *pLen = pSapCtx->nStaWPARSnReqIeLength; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: WPAIE len : %x", __func__, *pLen); + if(pBuf) + { + if(len >= pSapCtx->nStaWPARSnReqIeLength) + { + vos_mem_copy( pBuf, pSapCtx->pStaWpaRsnReqIE, pSapCtx->nStaWPARSnReqIeLength); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: WPAIE: %02x:%02x:%02x:%02x:%02x:%02x", + __func__, + pBuf[0], pBuf[1], pBuf[2], + pBuf[3], pBuf[4], pBuf[5]); + vosStatus = VOS_STATUS_SUCCESS; + } + } + } + } + + if( VOS_STATUS_E_FAILURE == vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Error unable to populate the RSNWPAIE", + __func__); + } + + return vosStatus; + +} + +/*========================================================================== + FUNCTION WLANSAP_Set_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to set WPS IE. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pWPSIE : tSap_WPSIE structure that include WPS IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_WpsIe +( + v_PVOID_t pCtx, + tSap_WPSIE *pSap_WPSIe +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )) { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( sap_AcquireGlobalLock( pSapCtx ) == VOS_STATUS_SUCCESS ) + { + if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_BEACON_IE) + { + vos_mem_copy(&pSapCtx->APWPSIEs.SirWPSBeaconIE, &pSap_WPSIe->sapwpsie.sapWPSBeaconIE, sizeof(tSap_WPSBeaconIE)); + } + else if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_PROBE_RSP_IE) + { + vos_mem_copy(&pSapCtx->APWPSIEs.SirWPSProbeRspIE, &pSap_WPSIe->sapwpsie.sapWPSProbeRspIE, sizeof(tSap_WPSProbeRspIE)); + } + else + { + sap_ReleaseGlobalLock( pSapCtx ); + return VOS_STATUS_E_FAULT; + } + sap_ReleaseGlobalLock( pSapCtx ); + return VOS_STATUS_SUCCESS; + } + else + return VOS_STATUS_E_FAULT; + } + else + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + FUNCTION WLANSAP_Update_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to update WPS IEs. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Update_WpsIe +( + v_PVOID_t pCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + ptSapContext pSapCtx = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RoamUpdateAPWPSIE( hHal, pSapCtx->sessionId, &pSapCtx->APWPSIEs); + + if(halStatus == eHAL_STATUS_SUCCESS) { + vosStatus = VOS_STATUS_SUCCESS; + } else + { + vosStatus = VOS_STATUS_E_FAULT; + } + + } + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_Get_WPS_State + + DESCRIPTION + This api function provides for Ap App/HDD to check if WPS session in process. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + OUT + pbWPSState: Pointer to variable to indicate if it is in WPS Registration state + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_WPS_State +( + v_PVOID_t pCtx, + v_BOOL_t *bWPSState +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + + pSapCtx = VOS_GET_SAP_CB(pCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( sap_AcquireGlobalLock(pSapCtx ) == VOS_STATUS_SUCCESS ) + { + if(pSapCtx->APWPSIEs.SirWPSProbeRspIE.FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) + *bWPSState = eANI_BOOLEAN_TRUE; + else + *bWPSState = eANI_BOOLEAN_FALSE; + + sap_ReleaseGlobalLock( pSapCtx ); + + return VOS_STATUS_SUCCESS; + } + else + return VOS_STATUS_E_FAULT; + } + else + return VOS_STATUS_E_FAULT; + +} + +VOS_STATUS +sap_AcquireGlobalLock +( + ptSapContext pSapCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &pSapCtx->SapGlobalLock) ) ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + return (vosStatus); +} + +VOS_STATUS +sap_ReleaseGlobalLock +( + ptSapContext pSapCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &pSapCtx->SapGlobalLock) ) ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + return (vosStatus); +} + +/*========================================================================== + FUNCTION WLANSAP_Set_WPARSNIes + + DESCRIPTION + This api function provides for Ap App/HDD to set AP WPA and RSN IE in its beacon and probe response. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pWPARSNIEs : buffer to the WPA/RSN IEs + WPARSNIEsLen: length of WPA/RSN IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_WPARSNIes +( + v_PVOID_t pCtx, + v_U8_t *pWPARSNIEs, + v_U32_t WPARSNIEsLen +) +{ + ptSapContext pSapCtx = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx->APWPARSNIEs.length = (tANI_U16)WPARSNIEsLen; + vos_mem_copy(pSapCtx->APWPARSNIEs.rsnIEdata, pWPARSNIEs, WPARSNIEsLen); + + halStatus = sme_RoamUpdateAPWPARSNIEs( hHal, pSapCtx->sessionId, &pSapCtx->APWPARSNIEs); + + if(halStatus == eHAL_STATUS_SUCCESS) { + return VOS_STATUS_SUCCESS; + } else + { + return VOS_STATUS_E_FAULT; + } + } + + return VOS_STATUS_E_FAULT; +} + +VOS_STATUS WLANSAP_GetStatistics +( + v_PVOID_t pCtx, + tSap_SoftapStats *statBuf, + v_BOOL_t bReset +) +{ + if (NULL == pCtx) + { + return VOS_STATUS_E_FAULT; + } + + return (WLANTL_GetSoftAPStatistics(pCtx, statBuf, bReset)); +} + +/*========================================================================== + + FUNCTION WLANSAP_SendAction + + DESCRIPTION + This api function provides to send action frame sent by upper layer. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + pBuf: Pointer of the action frame to be transmitted + len: Length of the action frame + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_SendAction +( + v_PVOID_t pCtx, + const tANI_U8 *pBuf, + tANI_U32 len, tANI_U16 wait +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_sendAction( hHal, pSapCtx->sessionId, pBuf, len, 0 , 0); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Send Action Frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_RemainOnChannel + + DESCRIPTION + This api function provides to set Remain On channel on specified channel + for specified duration. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + channel: Channel on which driver has to listen + duration: Duration for which driver has to listen on specified channel + callback: Callback function to be called once Listen is done. + pContext: Context needs to be called in callback function. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RemainOnChannel +( + v_PVOID_t pCtx, + tANI_U8 channel, + tANI_U32 duration, + remainOnChanCallback callback, + void *pContext +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RemainOnChannel( hHal, pSapCtx->sessionId, + channel, duration, callback, pContext, TRUE ); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Set Remain on Channel"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_CancelRemainOnChannel + + DESCRIPTION + This api cancel previous remain on channel request. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_CancelRemainOnChannel +( + v_PVOID_t pCtx +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_CancelRemainOnChannel( hHal, pSapCtx->sessionId ); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Cancel Remain on Channel"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_RegisterMgmtFrame + + DESCRIPTION + HDD use this API to register specified type of frame with CORE stack. + On receiving such kind of frame CORE stack should pass this frame to HDD + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + frameType: frameType that needs to be registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RegisterMgmtFrame +( + v_PVOID_t pCtx, + tANI_U16 frameType, + tANI_U8* matchData, + tANI_U16 matchLen +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RegisterMgmtFrame(hHal, pSapCtx->sessionId, + frameType, matchData, matchLen); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Register MGMT frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_DeRegisterMgmtFrame + + DESCRIPTION + This API is used to deregister previously registered frame. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + When MBSSID feature is enabled, SAP context is directly + passed to SAP APIs + frameType: frameType that needs to be De-registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_DeRegisterMgmtFrame +( + v_PVOID_t pCtx, + tANI_U16 frameType, + tANI_U8* matchData, + tANI_U16 matchLen +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB(pCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_DeregisterMgmtFrame( hHal, pSapCtx->sessionId, + frameType, matchData, matchLen ); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Deregister MGMT frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + FUNCTION WLANSAP_ChannelChangeRequest + + DESCRIPTION + This API is used to send an Indication to SME/PE to change the + current operating channel to a different target channel. + + The Channel change will be issued by SAP under the following + scenarios. + 1. A radar indication is received during SAP CAC WAIT STATE and + channel change is required. + 2. A radar indication is received during SAP STARTED STATE and + channel change is required. + DEPENDENCIES + NA. + + PARAMETERS + IN + pSapCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ChannelChangeRequest(v_PVOID_t pSapCtx, tANI_U8 tArgetChannel) +{ + ptSapContext sapContext = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + sapContext = (ptSapContext)pSapCtx; + + if ( NULL == sapContext ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RoamChannelChangeReq( hHal, sapContext->bssid, + tArgetChannel, + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode) ); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + sapSignalHDDevent(sapContext, NULL, eSAP_CHANNEL_CHANGE_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_StartBeaconReq + DESCRIPTION + This API is used to send an Indication to SME/PE to start + beaconing on the current operating channel. + + Brief:When SAP is started on DFS channel and when ADD BSS RESP is received + LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When + CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon + request to LIM. + + DEPENDENCIES + NA. + +PARAMETERS + +IN + pSapCtx: Pointer to vos global context structure + +RETURN VALUE + The VOS_STATUS code associated with performing the operation + +VOS_STATUS_SUCCESS: Success + +SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx) +{ + ptSapContext sapContext = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + tANI_U8 dfsCacWaitStatus = 0; + tpAniSirGlobal pMac = NULL; + sapContext = (ptSapContext)pSapCtx; + + if ( NULL == sapContext ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + /* No Radar was found during CAC WAIT, So start Beaconing */ + if (pMac->sap.SapDfsInfo.sap_radar_found_status == VOS_FALSE) + { + /* CAC Wait done without any Radar Detection */ + dfsCacWaitStatus = VOS_TRUE; + halStatus = sme_RoamStartBeaconReq( hHal, + sapContext->bssid, dfsCacWaitStatus); + if (halStatus == eHAL_STATUS_SUCCESS) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_E_FAULT; +} + + +/*========================================================================== + FUNCTION WLANSAP_DfsSendCSAIeRequest + + DESCRIPTION + This API is used to send channel switch announcement request to PE + DEPENDENCIES + NA. + + PARAMETERS + IN + pSapCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DfsSendCSAIeRequest(v_PVOID_t pSapCtx) +{ + ptSapContext sapContext = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + tpAniSirGlobal pMac = NULL; + sapContext = (ptSapContext)pSapCtx; + + if ( NULL == sapContext ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + halStatus = sme_RoamCsaIeRequest(hHal, + sapContext->bssid, + pMac->sap.SapDfsInfo.target_channel, + pMac->sap.SapDfsInfo.csaIERequired); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + FUNCTION WLANSAP_Get_Dfs_Ignore_CAC + + DESCRIPTION + This API is used to get the value of ignore_cac value + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + pIgnore_cac : pointer to ignore_cac variable + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Get_Dfs_Ignore_CAC(tHalHandle hHal, v_U8_t *pIgnore_cac) +{ + tpAniSirGlobal pMac = NULL; + + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + *pIgnore_cac = pMac->sap.SapDfsInfo.ignore_cac; + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_Set_Dfs_Ignore_CAC + + DESCRIPTION + This API is used to Set the value of ignore_cac value + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + ignore_cac : value to set for ignore_cac variable in DFS global structure. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_Dfs_Ignore_CAC(tHalHandle hHal, v_U8_t ignore_cac) +{ + tpAniSirGlobal pMac = NULL; + + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + pMac->sap.SapDfsInfo.ignore_cac = (ignore_cac >= VOS_TRUE)? + VOS_TRUE : VOS_FALSE; + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_set_Dfs_Restrict_JapanW53 + + DESCRIPTION + This API is used to enable or disable Japan W53 Band + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + disable_Dfs_JapanW3 :Indicates if Japan W53 is disabled when set to 1 + Indicates if Japan W53 is enabled when set to 0 + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_set_Dfs_Restrict_JapanW53(tHalHandle hHal, v_U8_t disable_Dfs_W53) +{ + tpAniSirGlobal pMac = NULL; + v_REGDOMAIN_t regDomain; + VOS_STATUS status; + + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + regDomain = sapFetchRegulatoryDomain(hHal); + + /* + * Set the JAPAN W53 restriction only if the current + * regulatory domain is JAPAN. + */ + if (REGDOMAIN_JAPAN == regDomain) + { + pMac->sap.SapDfsInfo.is_dfs_w53_disabled = disable_Dfs_W53; + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: SET DFS JAPAN W53 DISABLED = %d"), + pMac->sap.SapDfsInfo.is_dfs_w53_disabled); + + status = VOS_STATUS_SUCCESS; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Regdomain not japan, set disable JP W53 not valid")); + + status = VOS_STATUS_E_FAULT; + } + + return status; +} + +/*========================================================================== + FUNCTION WLANSAP_set_Dfs_Preferred_Channel_location + + DESCRIPTION + This API is used to set sap preferred channels location + to resetrict the DFS random channel selection algorithm + either Indoor/Outdoor channels only. + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + dfs_Preferred_Channels_location : + 0 - Indicates No preferred channel location restrictions + 1 - Indicates SAP Indoor Channels operation only. + 2 - Indicates SAP Outdoor Channels operation only. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_set_Dfs_Preferred_Channel_location(tHalHandle hHal, + v_U8_t dfs_Preferred_Channels_location) +{ + tpAniSirGlobal pMac = NULL; + v_REGDOMAIN_t regDomain; + VOS_STATUS status; + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + regDomain = sapFetchRegulatoryDomain(hHal); + + /* + * The Indoor/Outdoor only random channel selection + * restriction is currently enforeced only for + * JAPAN regulatory domain. + */ + if (REGDOMAIN_JAPAN == regDomain) + { + pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location = + dfs_Preferred_Channels_location; + VOS_TRACE(VOS_MODULE_ID_SAP, + VOS_TRACE_LEVEL_INFO_LOW, + FL("sapdfs:Set Preferred Operating Channel location=%d"), + pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location); + + status = VOS_STATUS_SUCCESS; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("sapdfs:NOT JAPAN REG, Invalid Set preferred chans location")); + + status = VOS_STATUS_E_FAULT; + } + + return status; +} + +/*========================================================================== + FUNCTION WLANSAP_Set_Dfs_Target_Chnl + + DESCRIPTION + This API is used to set next target chnl as provided channel. + you can provide any valid channel to this API. + + DEPENDENCIES + NA. + + PARAMETERS + IN + hHal : HAL pointer + target_channel : target channel to be set + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_Dfs_Target_Chnl(tHalHandle hHal, v_U8_t target_channel) +{ + tpAniSirGlobal pMac = NULL; + + if (NULL != hHal) + { + pMac = PMAC_STRUCT( hHal ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal pointer", __func__); + return VOS_STATUS_E_FAULT; + } + if (target_channel > 0) + { + pMac->sap.SapDfsInfo.user_provided_target_channel = target_channel; + } + else + { + pMac->sap.SapDfsInfo.user_provided_target_channel = 0; + } + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS +WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, + const tANI_U8 *pAdditionIEBuffer, + tANI_U16 additionIELength, + eUpdateIEsType updateType) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tANI_U8 bufferValid = VOS_FALSE; + tANI_U16 bufferLength = 0; + tANI_U8 *pBuffer = NULL; + + if (NULL == pConfig) + { + return VOS_STATUS_E_FAULT; + } + + if ( (pAdditionIEBuffer != NULL) && (additionIELength != 0) ) + { + /* initialize the buffer pointer so that pe can copy*/ + if (additionIELength > 0) + { + bufferLength = additionIELength; + pBuffer = vos_mem_malloc(bufferLength); + if (NULL == pBuffer) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Could not allocate the buffer ")); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength); + bufferValid = VOS_TRUE; + } + } + + switch(updateType) + { + case eUPDATE_IE_PROBE_BCN: + if (bufferValid) + { + pConfig->probeRespBcnIEsLen = bufferLength; + pConfig->pProbeRespBcnIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pProbeRespBcnIEsBuffer); + pConfig->probeRespBcnIEsLen = 0; + pConfig->pProbeRespBcnIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Probe Resp beacone IE received in set beacon")); + } + break; + case eUPDATE_IE_PROBE_RESP: + if (bufferValid) + { + pConfig->probeRespIEsBufferLen= bufferLength; + pConfig->pProbeRespIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pProbeRespIEsBuffer); + pConfig->probeRespIEsBufferLen = 0; + pConfig->pProbeRespIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Probe Response IE received in set beacon")); + } + break; + case eUPDATE_IE_ASSOC_RESP: + if (bufferValid) + { + pConfig->assocRespIEsLen = bufferLength; + pConfig->pAssocRespIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pAssocRespIEsBuffer); + pConfig->assocRespIEsLen = 0; + pConfig->pAssocRespIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Assoc Response IE received in set beacon")); + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No matching buffer type %d"), updateType); + if (pBuffer != NULL) + vos_mem_free(pBuffer); + break; + } + + return (status); +} + + +VOS_STATUS +WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig, + eUpdateIEsType updateType) +{ + if (NULL == pConfig) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Config pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + switch (updateType) + { + case eUPDATE_IE_ALL: /*only used to reset*/ + case eUPDATE_IE_PROBE_RESP: + vos_mem_free( pConfig->pProbeRespIEsBuffer); + pConfig->probeRespIEsBufferLen = 0; + pConfig->pProbeRespIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + case eUPDATE_IE_ASSOC_RESP: + vos_mem_free( pConfig->pAssocRespIEsBuffer); + pConfig->assocRespIEsLen = 0; + pConfig->pAssocRespIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + case eUPDATE_IE_PROBE_BCN: + vos_mem_free(pConfig->pProbeRespBcnIEsBuffer ); + pConfig->probeRespBcnIEsLen = 0; + pConfig->pProbeRespBcnIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + default: + if(eUPDATE_IE_ALL != updateType) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Invalid buffer type %d"), updateType); + break; + } + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== +FUNCTION WLANSAP_extend_to_acs_range + +DESCRIPTION Function extends give channel range to consider ACS chan bonding + +DEPENDENCIES PARAMETERS + +IN /OUT +*startChannelNum : ACS extend start ch +*endChannelNum : ACS extended End ch +*bandStartChannel: Band start ch +*bandEndChannel : Band end ch + +RETURN VALUE NONE + +SIDE EFFECTS +============================================================================*/ +v_VOID_t WLANSAP_extend_to_acs_range(v_U8_t operatingBand, + v_U8_t *startChannelNum, + v_U8_t *endChannelNum, + v_U8_t *bandStartChannel, + v_U8_t *bandEndChannel) +{ +#define ACS_2G_EXTEND 4 +#define ACS_5G_EXTEND 12 + + switch(operatingBand) + { + case eSAP_RF_SUBBAND_2_4_GHZ: + *bandStartChannel = RF_CHAN_1; + *bandEndChannel = RF_CHAN_14; + *startChannelNum = *startChannelNum > 5 ? + (*startChannelNum - ACS_2G_EXTEND): 1; + *endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ? + (*endChannelNum + ACS_2G_EXTEND):14; + break; + + case eSAP_RF_SUBBAND_5_LOW_GHZ: + *bandStartChannel = RF_CHAN_36; + *bandEndChannel = RF_CHAN_64; + *startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ? + (*startChannelNum - ACS_5G_EXTEND):36; + *endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 64? + (*endChannelNum + ACS_5G_EXTEND):64; + break; + + case eSAP_RF_SUBBAND_5_MID_GHZ: + *bandStartChannel = RF_CHAN_100; + *startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 100 ? + (*startChannelNum - ACS_5G_EXTEND):100; +#ifndef FEATURE_WLAN_CH144 + *bandEndChannel = RF_CHAN_140; + *endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 140 ? + (*endChannelNum + ACS_5G_EXTEND):140; +#else + *bandEndChannel = RF_CHAN_144; + *endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 144 ? + (*endChannelNum + ACS_5G_EXTEND):144; +#endif /* FEATURE_WLAN_CH144 */ + break; + + case eSAP_RF_SUBBAND_5_HIGH_GHZ: + *bandStartChannel = RF_CHAN_149; + *bandEndChannel = RF_CHAN_165; + *startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 149 ? + (*startChannelNum - ACS_5G_EXTEND):149; + *endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ? + (*endChannelNum + ACS_5G_EXTEND):165; + break; + + case eSAP_RF_SUBBAND_5_ALL_GHZ: + *bandStartChannel = RF_CHAN_36; + *bandEndChannel = RF_CHAN_165; + *startChannelNum = (*startChannelNum - ACS_5G_EXTEND) > 36 ? + (*startChannelNum - ACS_5G_EXTEND):36; + *endChannelNum = (*endChannelNum + ACS_5G_EXTEND) <= 165 ? + (*endChannelNum + ACS_5G_EXTEND):165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:OperatingBand not valid "); + /* assume 2.4 GHz */ + *bandStartChannel = RF_CHAN_1; + *bandEndChannel = RF_CHAN_14; + *startChannelNum = *startChannelNum > 5 ? + (*startChannelNum - ACS_2G_EXTEND): 1; + *endChannelNum = (*endChannelNum + ACS_2G_EXTEND) <= 14 ? + (*endChannelNum + ACS_2G_EXTEND):14; + break; + } +} + +/*========================================================================== + FUNCTION WLANSAP_Get_DfsNol + + DESCRIPTION + This API is used to dump the dfs nol + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_DfsNol(v_PVOID_t pSapCtx) +{ + int i = 0; + ptSapContext sapContext = (ptSapContext)pSapCtx; + v_PVOID_t hHal = NULL; + tpAniSirGlobal pMac = NULL; + v_U64_t current_time, found_time, elapsed_time; + unsigned long left_time; + tSapDfsNolInfo *dfs_nol = NULL; + v_BOOL_t bAvailable = FALSE; + + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: DFS NOL is empty", __func__); + return VOS_STATUS_SUCCESS; + } + + dfs_nol = pMac->sap.SapDfsInfo.sapDfsChannelNolList; + + if (!dfs_nol) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: DFS NOL context is null", __func__); + return VOS_STATUS_E_FAULT; + } + + for (i = 0; i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; i++) + { + if (!dfs_nol[i].dfs_channel_number) + continue; + + current_time = vos_get_monotonic_boottime(); + found_time = dfs_nol[i].radar_found_timestamp; + + elapsed_time = abs(current_time - found_time); + + /* check if channel is available + * if either channel is usable or available, or timer expired 30mins + */ + bAvailable = + ((dfs_nol[i].radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE) || + (dfs_nol[i].radar_status_flag == eSAP_DFS_CHANNEL_USABLE) || + (elapsed_time >= SAP_DFS_NON_OCCUPANCY_PERIOD)); + + if (bAvailable) + { + dfs_nol[i].radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; + dfs_nol[i].radar_found_timestamp = 0; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Channel[%d] is AVAILABLE", + __func__, + dfs_nol[i].dfs_channel_number); + } else { + + /* the time left in min */ + left_time = SAP_DFS_NON_OCCUPANCY_PERIOD - elapsed_time; + left_time = left_time / (60 * 1000 * 1000); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Channel[%d] is UNAVAILABLE [%lu min left]", + __func__, + dfs_nol[i].dfs_channel_number, + left_time); + } + } + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_Set_DfsNol + + DESCRIPTION + This API is used to set the dfs nol + DEPENDENCIES + NA. + + PARAMETERS + IN + sapContext: Pointer to vos global context structure + conf: set type + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_DfsNol(v_PVOID_t pSapCtx, eSapDfsNolType conf) +{ + int i = 0; + ptSapContext sapContext = (ptSapContext)pSapCtx; + v_PVOID_t hHal = NULL; + tpAniSirGlobal pMac = NULL; + + if (NULL == sapContext) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pMac = PMAC_STRUCT( hHal ); + + if (!pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: DFS NOL is empty", __func__); + return VOS_STATUS_SUCCESS; + } + + if (conf == eSAP_DFS_NOL_CLEAR) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: clear the DFS NOL", + __func__); + + for (i = 0; i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; + i++) + { + if (!pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + dfs_channel_number) + continue; + + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + radar_found_timestamp = 0; + } + } else if (conf == eSAP_DFS_NOL_RANDOMIZE) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Randomize the DFS NOL", + __func__); + + /* random 1/0 to decide to put the channel into NOL */ + for (i = 0; i < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; + i++) + { + v_U32_t random_bytes = 0; + get_random_bytes(&random_bytes, 1); + + if (!pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + dfs_channel_number) + continue; + + if ((random_bytes + jiffies) % 2) { + /* mark the channel unavailable */ + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_status_flag = eSAP_DFS_CHANNEL_UNAVAILABLE; + + /* mark the timestamp */ + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .radar_found_timestamp = vos_get_monotonic_boottime(); + } else { + /* mark the channel available */ + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE; + + /* clear the timestamp */ + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + radar_found_timestamp = 0; + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Set channel[%d] %s", + __func__, + pMac->sap.SapDfsInfo.sapDfsChannelNolList[i] + .dfs_channel_number, + (pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]. + radar_status_flag > eSAP_DFS_CHANNEL_AVAILABLE) ? + "UNAVAILABLE" : "AVAILABLE"); + } + } else { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: unsupport type %d", + __func__, conf); + } + + /* set DFS-NOL back to keep it update-to-date in CNSS */ + sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_SET, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h new file mode 100644 index 0000000000000..e75534a5d49d0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320V2_DBG_REGTABLE_H_ +#define _AR6320V2_DBG_REGTABLE_H_ + +#include "regtable.h" + +#define AR6320_REV2_1_REG_SIZE 0x0007F820 +#define AR6320_REV3_REG_SIZE 0x0007F820 + +#ifdef HIF_PCI +/* + * Redefine the register list. To minimize the size of the array, the list must + * obey the below format. {start0, end0}, {start1, end1}, {start2, end2}....... + * The value below must obey to "start0 < end0 < start1 < end1 < start2 < ...", + * otherwise we may encouter error in the dump processing. + */ + +static const tgt_reg_section ar6320v2_reg_table[] = +{ + {0x800, 0x810}, + {0x820, 0x82C}, + {0x830, 0x8F4}, + {0x90C, 0x91C}, + {0xA14, 0xA18}, + {0xA84, 0xA94}, + {0xAA8, 0xAD4}, + {0xADC, 0xB40}, + {0x1000, 0x10A4}, + {0x10BC, 0x111C}, + {0x1134, 0x1138}, + {0x1144, 0x114C}, + {0x1150, 0x115C}, + {0x1160, 0x1178}, + {0x1240, 0x1260}, + {0x2000, 0x207C}, + {0x3000, 0x3014}, + {0x4000, 0x4014}, + {0x5000, 0x5124}, + {0x6000, 0x6040}, + {0x6080, 0x60CC}, + {0x6100, 0x611C}, + {0x6140, 0x61D8}, + {0x6200, 0x6238}, + {0x6240, 0x628C}, + {0x62C0, 0x62EC}, + {0x6380, 0x63E8}, + {0x6400, 0x6440}, + {0x6480, 0x64CC}, + {0x6500, 0x651C}, + {0x6540, 0x6580}, + {0x6600, 0x6638}, + {0x6640, 0x668C}, + {0x66C0, 0x66EC}, + {0x6780, 0x67E8}, + {0x7080, 0x708C}, + {0x70C0, 0x70C8}, + {0x7400, 0x741C}, + {0x7440, 0x7454}, + {0x7800, 0x7818}, + {0x8000, 0x8004}, + {0x8010, 0x8064}, + {0x8080, 0x8084}, + {0x80A0, 0x80A4}, + {0x80C0, 0x80C4}, + {0x80E0, 0x80F4}, + {0x8100, 0x8104}, + {0x8110, 0x812C}, + {0x9000, 0x9004}, + {0x9800, 0x982C}, + {0x9830, 0x9838}, + {0x9840, 0x986C}, + {0x9870, 0x9898}, + {0x9A00, 0x9C00}, + {0xD580, 0xD59C}, + {0xF000, 0xF0E0}, + {0xF140, 0xF190}, + {0xF250, 0xF25C}, + {0xF260, 0xF268}, + {0xF26C, 0xF2A8}, + {0x10008, 0x1000C}, + {0x10014, 0x10018}, + {0x1001C, 0x10020}, + {0x10024, 0x10028}, + {0x10030, 0x10034}, + {0x10040, 0x10054}, + {0x10058, 0x1007C}, + {0x10080, 0x100C4}, + {0x100C8, 0x10114}, + {0x1012C, 0x10130}, + {0x10138, 0x10144}, + {0x10200, 0x10220}, + {0x10230, 0x10250}, + {0x10260, 0x10280}, + {0x10290, 0x102B0}, + {0x102C0, 0x102DC}, + {0x102E0, 0x102F4}, + {0x102FC, 0x1037C}, + {0x10380, 0x10390}, + {0x10800, 0x10828}, + {0x10840, 0x10844}, + {0x10880, 0x10884}, + {0x108C0, 0x108E8}, + {0x10900, 0x10928}, + {0x10940, 0x10944}, + {0x10980, 0x10984}, + {0x109C0, 0x109E8}, + {0x10A00, 0x10A28}, + {0x10A40, 0x10A50}, + {0x11000, 0x11028}, + {0x11030, 0x11034}, + {0x11038, 0x11068}, + {0x11070, 0x11074}, + {0x11078, 0x110A8}, + {0x110B0, 0x110B4}, + {0x110B8, 0x110E8}, + {0x110F0, 0x110F4}, + {0x110F8, 0x11128}, + {0x11138, 0x11144}, + {0x11178, 0x11180}, + {0x111B8, 0x111C0}, + {0x111F8, 0x11200}, + {0x11238, 0x1123C}, + {0x11270, 0x11274}, + {0x11278, 0x1127C}, + {0x112B0, 0x112B4}, + {0x112B8, 0x112BC}, + {0x112F0, 0x112F4}, + {0x112F8, 0x112FC}, + {0x11338, 0x1133C}, + {0x11378, 0x1137C}, + {0x113B8, 0x113BC}, + {0x113F8, 0x113FC}, + {0x11438, 0x11440}, + {0x11478, 0x11480}, + {0x114B8, 0x114BC}, + {0x114F8, 0x114FC}, + {0x11538, 0x1153C}, + {0x11578, 0x1157C}, + {0x115B8, 0x115BC}, + {0x115F8, 0x115FC}, + {0x11638, 0x1163C}, + {0x11678, 0x1167C}, + {0x116B8, 0x116BC}, + {0x116F8, 0x116FC}, + {0x11738, 0x1173C}, + {0x11778, 0x1177C}, + {0x117B8, 0x117BC}, + {0x117F8, 0x117FC}, + {0x17000, 0x1701C}, + {0x17020, 0x170AC}, + {0x18000, 0x18050}, + {0x18054, 0x18074}, + {0x18080, 0x180D4}, + {0x180DC, 0x18104}, + {0x18108, 0x1813C}, + {0x18144, 0x18148}, + {0x18168, 0x18174}, + {0x18178, 0x18180}, + {0x181C8, 0x181E0}, + {0x181E4, 0x181E8}, + {0x181EC, 0x1820C}, + {0x1825C, 0x18280}, + {0x18284, 0x18290}, + {0x18294, 0x182A0}, + {0x18300, 0x18304}, + {0x18314, 0x18320}, + {0x18328, 0x18350}, + {0x1835C, 0x1836C}, + {0x18370, 0x18390}, + {0x18398, 0x183AC}, + {0x183BC, 0x183D8}, + {0x183DC, 0x183F4}, + {0x18400, 0x186F4}, + {0x186F8, 0x1871C}, + {0x18720, 0x18790}, + {0x19800, 0x19830}, + {0x19834, 0x19840}, + {0x19880, 0x1989C}, + {0x198A4, 0x198B0}, + {0x198BC, 0x19900}, + {0x19C00, 0x19C88}, + {0x19D00, 0x19D20}, + {0x19E00, 0x19E7C}, + {0x19E80, 0x19E94}, + {0x19E98, 0x19EAC}, + {0x19EB0, 0x19EBC}, + {0x19F70, 0x19F74}, + {0x19F80, 0x19F8C}, + {0x19FA0, 0x19FB4}, + {0x19FC0, 0x19FD8}, + {0x1A000, 0x1A200}, + {0x1A204, 0x1A210}, + {0x1A228, 0x1A22C}, + {0x1A230, 0x1A248}, + {0x1A250, 0x1A270}, + {0x1A280, 0x1A290}, + {0x1A2A0, 0x1A2A4}, + {0x1A2C0, 0x1A2EC}, + {0x1A300, 0x1A3BC}, + {0x1A3F0, 0x1A3F4}, + {0x1A3F8, 0x1A434}, + {0x1A438, 0x1A444}, + {0x1A448, 0x1A468}, + {0x1A580, 0x1A58C}, + {0x1A644, 0x1A654}, + {0x1A670, 0x1A698}, + {0x1A6AC, 0x1A6B0}, + {0x1A6D0, 0x1A6D4}, + {0x1A6EC, 0x1A70C}, + {0x1A710, 0x1A738}, + {0x1A7C0, 0x1A7D0}, + {0x1A7D4, 0x1A7D8}, + {0x1A7DC, 0x1A7E4}, + {0x1A7F0, 0x1A7F8}, + {0x1A888, 0x1A89C}, + {0x1A8A8, 0x1A8AC}, + {0x1A8C0, 0x1A8DC}, + {0x1A8F0, 0x1A8FC}, + {0x1AE04, 0x1AE08}, + {0x1AE18, 0x1AE24}, + {0x1AF80, 0x1AF8C}, + {0x1AFA0, 0x1AFB4}, + {0x1B000, 0x1B200}, + {0x1B284, 0x1B288}, + {0x1B2D0, 0x1B2D8}, + {0x1B2DC, 0x1B2EC}, + {0x1B300, 0x1B340}, + {0x1B374, 0x1B378}, + {0x1B380, 0x1B384}, + {0x1B388, 0x1B38C}, + {0x1B404, 0x1B408}, + {0x1B420, 0x1B428}, + {0x1B440, 0x1B444}, + {0x1B448, 0x1B44C}, + {0x1B450, 0x1B458}, + {0x1B45C, 0x1B468}, + {0x1B584, 0x1B58C}, + {0x1B68C, 0x1B690}, + {0x1B6AC, 0x1B6B0}, + {0x1B7F0, 0x1B7F8}, + {0x1C800, 0x1CC00}, + {0x1CE00, 0x1CE04}, + {0x1CF80, 0x1CF84}, + {0x1D200, 0x1D800}, + {0x1E000, 0x20014}, + {0x20100, 0x20124}, + {0x21400, 0x217A8}, + {0x21800, 0x21BA8}, + {0x21C00, 0x21FA8}, + {0x22000, 0x223A8}, + {0x22400, 0x227A8}, + {0x22800, 0x22BA8}, + {0x22C00, 0x22FA8}, + {0x23000, 0x233A8}, + {0x24000, 0x24034}, + + /* + * EFUSE0,1,2 is disabled here + * because it's state may be reset + * + * {0x24800, 0x24804}, + * {0x25000, 0x25004}, + * {0x25800, 0x25804}, + */ + + {0x26000, 0x26064}, + {0x27000, 0x27024}, + {0x34000, 0x3400C}, + {0x34400, 0x3445C}, + {0x34800, 0x3485C}, + {0x34C00, 0x34C5C}, + {0x35000, 0x3505C}, + {0x35400, 0x3545C}, + {0x35800, 0x3585C}, + {0x35C00, 0x35C5C}, + {0x36000, 0x3605C}, + {0x38000, 0x38064}, + {0x38070, 0x380E0}, + {0x3A000, 0x3A064}, + + /* DBI windows is skipped here, it can be only accessed when pcie + * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 && + * PCIE_CTRL_APP_LTSSM_ENALBE=0. + * {0x3C000 , 0x3C004}, + */ + + {0x40000, 0x400A4}, + + /* + * SI register is skiped here. + * Because it will cause bus hang + * + * {0x50000, 0x50018}, + */ + + {0x80000, 0x8000C}, + {0x80010, 0x80020}, +}; + +static const tgt_reg_section ar6320v3_reg_table[] = +{ + {0x800, 0x810}, + {0x820, 0x82C}, + {0x830, 0x8F4}, + {0x90C, 0x91C}, + {0xA14, 0xA18}, + {0xA84, 0xA94}, + {0xAA8, 0xAD4}, + {0xADC, 0xB40}, + {0x1000, 0x10A4}, + {0x10BC, 0x111C}, + {0x1134, 0x1138}, + {0x1144, 0x114C}, + {0x1150, 0x115C}, + {0x1160, 0x1178}, + {0x1240, 0x1260}, + {0x2000, 0x207C}, + {0x3000, 0x3014}, + {0x4000, 0x4014}, + {0x5000, 0x5124}, + {0x6000, 0x6040}, + {0x6080, 0x60CC}, + {0x6100, 0x611C}, + {0x6140, 0x61D8}, + {0x6200, 0x6238}, + {0x6240, 0x628C}, + {0x62C0, 0x62EC}, + {0x6380, 0x63E8}, + {0x6400, 0x6440}, + {0x6480, 0x64CC}, + {0x6500, 0x651C}, + {0x6540, 0x6580}, + {0x6600, 0x6638}, + {0x6640, 0x668C}, + {0x66C0, 0x66EC}, + {0x6780, 0x67E8}, + {0x7080, 0x708C}, + {0x70C0, 0x70C8}, + {0x7400, 0x741C}, + {0x7440, 0x7454}, + {0x7800, 0x7818}, + {0x8000, 0x8004}, + {0x8010, 0x8064}, + {0x8080, 0x8084}, + {0x80A0, 0x80A4}, + {0x80C0, 0x80C4}, + {0x80E0, 0x80F4}, + {0x8100, 0x8104}, + {0x8110, 0x812C}, + {0x9000, 0x9004}, + {0x9800, 0x982C}, + {0x9830, 0x9838}, + {0x9840, 0x986C}, + {0x9870, 0x9898}, + {0x9A00, 0x9C00}, + {0xD580, 0xD59C}, + {0xF000, 0xF0E0}, + {0xF140, 0xF190}, + {0xF250, 0xF25C}, + {0xF260, 0xF268}, + {0xF26C, 0xF2A8}, + {0x10008, 0x1000C}, + {0x10014, 0x10018}, + {0x1001C, 0x10020}, + {0x10024, 0x10028}, + {0x10030, 0x10034}, + {0x10040, 0x10054}, + {0x10058, 0x1007C}, + {0x10080, 0x100C4}, + {0x100C8, 0x10114}, + {0x1012C, 0x10130}, + {0x10138, 0x10144}, + {0x10200, 0x10220}, + {0x10230, 0x10250}, + {0x10260, 0x10280}, + {0x10290, 0x102B0}, + {0x102C0, 0x102DC}, + {0x102E0, 0x102F4}, + {0x102FC, 0x1037C}, + {0x10380, 0x10390}, + {0x10800, 0x10828}, + {0x10840, 0x10844}, + {0x10880, 0x10884}, + {0x108C0, 0x108E8}, + {0x10900, 0x10928}, + {0x10940, 0x10944}, + {0x10980, 0x10984}, + {0x109C0, 0x109E8}, + {0x10A00, 0x10A28}, + {0x10A40, 0x10A50}, + {0x11000, 0x11028}, + {0x11030, 0x11034}, + {0x11038, 0x11068}, + {0x11070, 0x11074}, + {0x11078, 0x110A8}, + {0x110B0, 0x110B4}, + {0x110B8, 0x110E8}, + {0x110F0, 0x110F4}, + {0x110F8, 0x11128}, + {0x11138, 0x11144}, + {0x11178, 0x11180}, + {0x111B8, 0x111C0}, + {0x111F8, 0x11200}, + {0x11238, 0x1123C}, + {0x11270, 0x11274}, + {0x11278, 0x1127C}, + {0x112B0, 0x112B4}, + {0x112B8, 0x112BC}, + {0x112F0, 0x112F4}, + {0x112F8, 0x112FC}, + {0x11338, 0x1133C}, + {0x11378, 0x1137C}, + {0x113B8, 0x113BC}, + {0x113F8, 0x113FC}, + {0x11438, 0x11440}, + {0x11478, 0x11480}, + {0x114B8, 0x114BC}, + {0x114F8, 0x114FC}, + {0x11538, 0x1153C}, + {0x11578, 0x1157C}, + {0x115B8, 0x115BC}, + {0x115F8, 0x115FC}, + {0x11638, 0x1163C}, + {0x11678, 0x1167C}, + {0x116B8, 0x116BC}, + {0x116F8, 0x116FC}, + {0x11738, 0x1173C}, + {0x11778, 0x1177C}, + {0x117B8, 0x117BC}, + {0x117F8, 0x117FC}, + {0x17000, 0x1701C}, + {0x17020, 0x170AC}, + {0x18000, 0x18050}, + {0x18054, 0x18074}, + {0x18080, 0x180D4}, + {0x180DC, 0x18104}, + {0x18108, 0x1813C}, + {0x18144, 0x18148}, + {0x18168, 0x18174}, + {0x18178, 0x18180}, + {0x181C8, 0x181E0}, + {0x181E4, 0x181E8}, + {0x181EC, 0x1820C}, + {0x1825C, 0x18280}, + {0x18284, 0x18290}, + {0x18294, 0x182A0}, + {0x18300, 0x18304}, + {0x18314, 0x18320}, + {0x18328, 0x18350}, + {0x1835C, 0x1836C}, + {0x18370, 0x18390}, + {0x18398, 0x183AC}, + {0x183BC, 0x183D8}, + {0x183DC, 0x183F4}, + {0x18400, 0x186F4}, + {0x186F8, 0x1871C}, + {0x18720, 0x18790}, + {0x19800, 0x19830}, + {0x19834, 0x19840}, + {0x19880, 0x1989C}, + {0x198A4, 0x198B0}, + {0x198BC, 0x19900}, + {0x19C00, 0x19C88}, + {0x19D00, 0x19D20}, + {0x19E00, 0x19E7C}, + {0x19E80, 0x19E94}, + {0x19E98, 0x19EAC}, + {0x19EB0, 0x19EBC}, + {0x19F70, 0x19F74}, + {0x19F80, 0x19F8C}, + {0x19FA0, 0x19FB4}, + {0x19FC0, 0x19FD8}, + {0x1A000, 0x1A200}, + {0x1A204, 0x1A210}, + {0x1A228, 0x1A22C}, + {0x1A230, 0x1A248}, + {0x1A250, 0x1A270}, + {0x1A280, 0x1A290}, + {0x1A2A0, 0x1A2A4}, + {0x1A2C0, 0x1A2EC}, + {0x1A300, 0x1A3BC}, + {0x1A3F0, 0x1A3F4}, + {0x1A3F8, 0x1A434}, + {0x1A438, 0x1A444}, + {0x1A448, 0x1A468}, + {0x1A580, 0x1A58C}, + {0x1A644, 0x1A654}, + {0x1A670, 0x1A698}, + {0x1A6AC, 0x1A6B0}, + {0x1A6D0, 0x1A6D4}, + {0x1A6EC, 0x1A70C}, + {0x1A710, 0x1A738}, + {0x1A7C0, 0x1A7D0}, + {0x1A7D4, 0x1A7D8}, + {0x1A7DC, 0x1A7E4}, + {0x1A7F0, 0x1A7F8}, + {0x1A888, 0x1A89C}, + {0x1A8A8, 0x1A8AC}, + {0x1A8C0, 0x1A8DC}, + {0x1A8F0, 0x1A8FC}, + {0x1AE04, 0x1AE08}, + {0x1AE18, 0x1AE24}, + {0x1AF80, 0x1AF8C}, + {0x1AFA0, 0x1AFB4}, + {0x1B000, 0x1B200}, + {0x1B284, 0x1B288}, + {0x1B2D0, 0x1B2D8}, + {0x1B2DC, 0x1B2EC}, + {0x1B300, 0x1B340}, + {0x1B374, 0x1B378}, + {0x1B380, 0x1B384}, + {0x1B388, 0x1B38C}, + {0x1B404, 0x1B408}, + {0x1B420, 0x1B428}, + {0x1B440, 0x1B444}, + {0x1B448, 0x1B44C}, + {0x1B450, 0x1B458}, + {0x1B45C, 0x1B468}, + {0x1B584, 0x1B58C}, + {0x1B68C, 0x1B690}, + {0x1B6AC, 0x1B6B0}, + {0x1B7F0, 0x1B7F8}, + {0x1C800, 0x1CC00}, + {0x1CE00, 0x1CE04}, + {0x1CF80, 0x1CF84}, + {0x1D200, 0x1D800}, + {0x1E000, 0x20014}, + {0x20100, 0x20124}, + {0x21400, 0x217A8}, + {0x21800, 0x21BA8}, + {0x21C00, 0x21FA8}, + {0x22000, 0x223A8}, + {0x22400, 0x227A8}, + {0x22800, 0x22BA8}, + {0x22C00, 0x22FA8}, + {0x23000, 0x233A8}, + {0x24000, 0x24034}, + + /* + * EFUSE0,1,2 is disabled here + * because it's state may be reset + * + * {0x24800, 0x24804}, + * {0x25000, 0x25004}, + * {0x25800, 0x25804}, + */ + + {0x26000, 0x26064}, + {0x27000, 0x27024}, + {0x34000, 0x3400C}, + {0x34400, 0x3445C}, + {0x34800, 0x3485C}, + {0x34C00, 0x34C5C}, + {0x35000, 0x3505C}, + {0x35400, 0x3545C}, + {0x35800, 0x3585C}, + {0x35C00, 0x35C5C}, + {0x36000, 0x3605C}, + {0x38000, 0x38064}, + {0x38070, 0x380E0}, + {0x3A000, 0x3A074}, + + /* + * DBI windows is skipped here, it can be only accessed when pcie + * is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 && + * PCIE_CTRL_APP_LTSSM_ENALBE=0. + * {0x3C000 , 0x3C004}, + */ + + {0x40000, 0x400A4}, + + /* + * SI register is skiped here. + * Because it will cause bus hang + * + * {0x50000, 0x50018}, + */ + + {0x80000, 0x8000C}, + {0x80010, 0x80020}, +}; +#endif +#endif /* #ifndef _AR6320V2_DBG_REGTABLE_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bin_sig.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bin_sig.h new file mode 100644 index 0000000000000..7266945cc7050 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bin_sig.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef BIN_SIGN_H_ +#define BIN_SIGN_H_ + +#define SIGN_HEADER_MAGIC 0x454D4F52 + +/* Signed binary MetaData */ +typedef struct { + unsigned int magic_num; + unsigned int total_len; + unsigned int rampatch_len; + unsigned int product_id; + unsigned int patch_ver; + unsigned short sign_format_ver; + unsigned short sign_algorithm; + unsigned char reserved[8]; +} SIGN_HEADER_T; + +#endif /* BIN_SIGN_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi.c new file mode 100644 index 0000000000000..94b1d3dec9da0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi.c @@ -0,0 +1,897 @@ +/* + * copyright (c) 2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "hif.h" +#include "bmi.h" +#include "bmi_internal.h" +#include "ol_fw.h" + +#ifdef HIF_MESSAGE_BASED + +#ifdef HIF_USB +#include "a_usb_defs.h" +#endif + +#if defined(HIF_BMI_MAX_TRANSFER_SIZE) + +#if BMI_DATASZ_MAX > HIF_BMI_MAX_TRANSFER_SIZE + /* override */ +#undef BMI_DATASZ_MAX +#define BMI_DATASZ_MAX HIF_BMI_MAX_TRANSFER_SIZE +#endif +#endif + +#endif + +#ifdef DEBUG +static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = { + { ATH_DEBUG_BMI , "BMI Tracing"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi, + "bmi", + "Boot Manager Interface", + ATH_DEBUG_MASK_DEFAULTS, + ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc), + bmi_debug_desc); + +#endif + +/* +Although we had envisioned BMI to run on top of HTC, this is not how the +final implementation ended up. On the Target side, BMI is a part of the BSP +and does not use the HTC protocol nor even DMA -- it is intentionally kept +very simple. +*/ + +#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ + sizeof(A_UINT32) /* cmd */ + \ + sizeof(A_UINT32) /* addr */ + \ + sizeof(A_UINT32))/* length */ +#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ) +#define BMI_EXCHANGE_TIMEOUT_MS 1000 + +/* APIs visible to the driver */ +void +BMIInit(struct ol_softc *scn) +{ + if (!scn) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n")); + ASSERT(0); + return; + } + scn->bmiDone = FALSE; + + /* + * On some platforms, it's not possible to DMA to a static variable + * in a device driver (e.g. Linux loadable driver module). + * So we need to A_MALLOC space for "command credits" and for commands. + * + * Note: implicitly relies on A_MALLOC to provide a buffer that is + * suitable for DMA (or PIO). This buffer will be passed down the + * bus stack. + */ + + if (!scn->pBMICmdBuf) { +#ifndef HIF_PCI + scn->pBMICmdBuf = + (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ); +#else + scn->pBMICmdBuf = + (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev, + MAX_BMI_CMDBUF_SZ, + &scn->BMICmd_pa); +#endif + ASSERT(scn->pBMICmdBuf); + } + + if (!scn->pBMIRspBuf) { +#ifndef HIF_PCI + scn->pBMIRspBuf = + (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ); +#else + scn->pBMIRspBuf = + (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev, + MAX_BMI_CMDBUF_SZ, + &scn->BMIRsp_pa); +#endif + ASSERT(scn->pBMIRspBuf); + } + + A_REGISTER_MODULE_DEBUG_INFO(bmi); +} + +void +BMICleanup(struct ol_softc *scn) +{ + if (scn->pBMICmdBuf) { +#ifndef HIF_PCI + A_FREE(scn->pBMICmdBuf ); +#else + pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ, + scn->pBMICmdBuf, scn->BMICmd_pa); +#endif + scn->pBMICmdBuf = NULL; + scn->BMICmd_pa = 0; + } + + if (scn->pBMIRspBuf) { +#ifndef HIF_PCI + A_FREE(scn->pBMIRspBuf); +#else + pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ, + scn->pBMIRspBuf, scn->BMIRsp_pa); +#endif + scn->pBMIRspBuf = NULL; + scn->BMIRsp_pa = 0; + } +} + +static A_STATUS +BMIDone(HIF_DEVICE *device, struct ol_softc *scn) +{ + A_STATUS status; + A_UINT32 cid; + + if (!scn) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n")); + ASSERT(0); + return A_ERROR; + } + + if (scn->bmiDone) { + AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); + return A_OK; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)); + +#if defined(A_SIMOS_DEVHOST) + /* Let HIF layer know that BMI phase is done. + * Note that this call enqueues a bunch of receive buffers, + * so it is important that this complete before we tell the + * target about BMI_DONE. + */ + (void)HIFConfigureDevice(device, HIF_BMI_DONE, NULL, 0); +#endif + + scn->bmiDone = TRUE; + cid = BMI_DONE; + + if (!scn->pBMICmdBuf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn BMICmdBuff\n")); + ASSERT(0); + return A_ERROR; + } + + A_MEMCPY(scn->pBMICmdBuf,&cid,sizeof(cid)); + + status = HIFExchangeBMIMsg(device, scn->pBMICmdBuf, sizeof(cid), NULL, NULL, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + + if (scn->pBMICmdBuf) { +#ifndef HIF_PCI + A_FREE(scn->pBMICmdBuf); +#else + pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ, + scn->pBMICmdBuf, scn->BMICmd_pa); +#endif + scn->pBMICmdBuf = NULL; + scn->BMICmd_pa = 0; + } + + if (scn->pBMIRspBuf) { +#ifndef HIF_PCI + A_FREE(scn->pBMIRspBuf); +#else + pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ, + scn->pBMIRspBuf, scn->BMIRsp_pa); +#endif + scn->pBMIRspBuf = NULL; + scn->BMIRsp_pa = 0; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n")); + + return A_OK; +} + +A_STATUS bmi_done(struct ol_softc *scn) +{ + HIFClaimDevice(scn->hif_hdl, scn); + + if (BMIDone(scn->hif_hdl, scn) != A_OK) + return -1; + + return 0; +} + +#ifndef HIF_MESSAGE_BASED +extern A_STATUS HIFRegBasedGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); +#endif + +static A_STATUS +BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info, struct ol_softc *scn) +{ +#ifndef HIF_MESSAGE_BASED +#else + A_STATUS status; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf; +#endif + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Get Target Info Command disallowed\n")); + return A_ERROR; + } + +#ifndef HIF_MESSAGE_BASED + /* getting the target ID requires special handling because of the variable length + * message */ + return HIFRegBasedGetTargetInfo(device,targ_info); +#else + + { + A_UINT32 cid; + A_UINT32 length; + + cid = BMI_GET_TARGET_INFO; + + A_MEMCPY(pBMICmdBuf,&cid,sizeof(cid)); + length = sizeof(struct bmi_target_info); + + status = HIFExchangeBMIMsg(device, + pBMICmdBuf, + sizeof(cid), + (A_UINT8 *)pBMIRspBuf, + &length, + BMI_EXCHANGE_TIMEOUT_MS); + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to get target information from the device\n")); + return A_ERROR; + } + + A_MEMCPY(targ_info, pBMIRspBuf, length); + return status; + } +#endif +} + +A_STATUS bmi_download_firmware(struct ol_softc *scn) +{ + struct bmi_target_info targ_info; + OS_MEMZERO(&targ_info, sizeof(targ_info)); + + if (!scn){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n")); + ASSERT(0); + return A_EINVAL; + } + + /* Initialize BMI */ + BMIInit(scn); + + if (scn->pBMICmdBuf == NULL || scn->pBMIRspBuf == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIInit failed!\n")); + return -1; + } + + /* Get target information */ + if (BMIGetTargetInfo(scn->hif_hdl, &targ_info, scn) != A_OK) + return -1; + + scn->target_type = targ_info.target_type; + scn->target_version = targ_info.target_ver; + + /* Configure target */ + if (ol_configure_target(scn) != A_OK) + return -1; + + if (ol_download_firmware(scn) != EOK) + return -EIO; + + return 0; +} + +A_STATUS +BMIReadMemory(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UINT32 remaining, rxlen; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf; + A_UINT32 align; + + ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length))); + memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); + memset (pBMIRspBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", + device, address, length)); + + cid = BMI_READ_MEMORY; +#if defined(SDIO_3_0) + /* 4bytes align operation */ + align = 4 - (length & 3); + remaining = length + align; +#else + align = 0; + remaining = length; +#endif + while (remaining) + { + rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen)); + offset += sizeof(length); + + status = HIFExchangeBMIMsg(device, + pBMICmdBuf, + offset, + pBMIRspBuf, /* note we reuse the same buffer to receive on */ + &rxlen, + BMI_EXCHANGE_TIMEOUT_MS); + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); + return A_ERROR; + } + if (remaining == rxlen) { + A_MEMCPY(&buffer[length - remaining + align], pBMIRspBuf, rxlen - align); /* last align bytes are invalid */ + } else { + A_MEMCPY(&buffer[length - remaining + align], pBMIRspBuf, rxlen); + } + remaining -= rxlen; address += rxlen; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n")); + return A_OK; +} + +A_STATUS +BMIWriteMemory(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UINT32 remaining, txlen; + const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); + A_UCHAR alignedBuffer[BMI_DATASZ_MAX]; + A_UCHAR *src; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + + ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); + memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", + device, address, length)); + + cid = BMI_WRITE_MEMORY; + + remaining = length; + while (remaining) + { + src = &buffer[length - remaining]; + if (remaining < (BMI_DATASZ_MAX - header)) { + if (remaining & 3) { + /* align it with 4 bytes */ + remaining = remaining + (4 - (remaining & 3)); + memcpy(alignedBuffer, src, remaining); + src = alignedBuffer; + } + txlen = remaining; + } else { + txlen = (BMI_DATASZ_MAX - header); + } + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); + offset += sizeof(txlen); + A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen); + offset += txlen; + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, BMI_EXCHANGE_TIMEOUT_MS); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + remaining -= txlen; address += txlen; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n")); + + return A_OK; +} + +A_STATUS +BMIExecute(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 *param, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UINT32 paramLen; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); + memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); + memset (pBMIRspBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n", + device, address, *param)); + + cid = BMI_EXECUTE; + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param)); + offset += sizeof(*param); + paramLen = sizeof(*param); + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, ¶mLen, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); + return A_ERROR; + } + + A_MEMCPY(param, pBMIRspBuf, sizeof(*param)); + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); + return A_OK; +} + +A_STATUS +BMISetAppStart(HIF_DEVICE *device, + A_UINT32 address, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); + memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n", + device, address)); + + cid = BMI_SET_APP_START; + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n")); + return A_OK; +} + +A_STATUS +BMIReadSOCRegister(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 *param, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset,paramLen; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); + memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); + memset (pBMIRspBuf, 0, sizeof(cid) + sizeof(address)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n", + device, address)); + + cid = BMI_READ_SOC_REGISTER; + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + paramLen = sizeof(*param); + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, ¶mLen, BMI_EXCHANGE_TIMEOUT_MS); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); + return A_ERROR; + } + A_MEMCPY(param, pBMIRspBuf, sizeof(*param)); + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param)); + return A_OK; +} + +A_STATUS +BMIWriteSOCRegister(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 param, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); + memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n", + device, address, param)); + + cid = BMI_WRITE_SOC_REGISTER; + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); + offset += sizeof(param); + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n")); + return A_OK; +} + +A_STATUS +BMILZData(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UINT32 remaining, txlen; + const A_UINT32 header = sizeof(cid) + sizeof(length); + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + + ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header)); + memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n", + device, length)); + + cid = BMI_LZ_DATA; + + remaining = length; + while (remaining) + { + txlen = (remaining < (BMI_DATASZ_MAX - header)) ? + remaining : (BMI_DATASZ_MAX - header); + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); + offset += sizeof(txlen); + A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); + offset += txlen; + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + remaining -= txlen; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n")); + + return A_OK; +} + +A_STATUS +BMISignStreamStart(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); + A_UCHAR alignedBuffer[BMI_DATASZ_MAX + 4]; + A_UCHAR *src; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UINT32 remaining, txlen; + + ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); + memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + header); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI SIGN Stream Start: Enter (device: 0x%p, address: 0x%x, length: %d)\n", + device, address, length)); + + cid = BMI_SIGN_STREAM_START; + remaining = length; + while (remaining) + { + src = &buffer[length - remaining]; + if (remaining < (BMI_DATASZ_MAX - header)) { + /* Actually it shall be aligned binary from header definition. + * Not necessary for align process. Kept for possible changes + */ + if (remaining & 0x3) { + remaining = remaining + (4 - (remaining & 0x3)); + memcpy(alignedBuffer, src, remaining); + src = alignedBuffer; + } + txlen = remaining; + } else { + txlen = (BMI_DATASZ_MAX - header); + } + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(offset); + A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); + offset += sizeof(txlen); + A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen); + offset += txlen; + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, BMI_EXCHANGE_TIMEOUT_MS); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + remaining -= txlen; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI SIGN Stream Start: Exit\n")); + + return A_OK; +} + +A_STATUS +BMILZStreamStart(HIF_DEVICE *device, + A_UINT32 address, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); + memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n", + device, address)); + + cid = BMI_LZ_STREAM_START; + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + offset += sizeof(address); + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n")); + + return A_OK; +} + +A_STATUS +BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, struct ol_softc *scn) +{ + A_STATUS status = A_ERROR; + A_UINT32 lastWord = 0; + A_UINT32 lastWordOffset = length & ~0x3; + A_UINT32 unalignedBytes = length & 0x3; + + status = BMILZStreamStart (device, address, scn); + if (A_FAILED(status)) { + return A_ERROR; + } + + if (unalignedBytes) { + /* copy the last word into a zero padded buffer */ + A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes); + } + + status = BMILZData(device, buffer, lastWordOffset, scn); + + if (A_FAILED(status)) { + return A_ERROR; + } + + if (unalignedBytes) { + status = BMILZData(device, (A_UINT8 *)&lastWord, 4, scn); + } + + if (A_SUCCESS(status)) { + // + // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. + // + status = BMILZStreamStart (device, 0x00, scn); + if (A_FAILED(status)) { + return A_ERROR; + } + } + return status; +} + +A_STATUS +BMInvramProcess(HIF_DEVICE *device, A_UCHAR *seg_name, A_UINT32 *retval, + struct ol_softc *scn) +{ + A_UINT32 cid; + A_STATUS status; + A_UINT32 offset; + A_UINT32 retvalLen; + A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf; + A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf; + + ASSERT(BMI_COMMAND_FITS(sizeof(cid) + BMI_NVRAM_SEG_NAME_SZ)); + + if (scn->bmiDone) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); + return A_ERROR; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + ("BMI NVRAM Process: Enter (device: 0x%p, name: %s)\n", + device, seg_name)); + + cid = BMI_NVRAM_PROCESS; + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + A_MEMCPY(&(pBMICmdBuf[offset]), seg_name, BMI_NVRAM_SEG_NAME_SZ); + offset += BMI_NVRAM_SEG_NAME_SZ; + retvalLen = sizeof(*retval); + status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, &retvalLen, 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to access the device\n")); + return A_ERROR; + } + + A_MEMCPY(retval, pBMIRspBuf, sizeof(*retval)); + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI NVRAM Process: Exit\n")); + + return A_OK; +} + +#ifdef HIF_MESSAGE_BASED + +/* TODO.. stubs.. for message-based HIFs, the RAW access APIs need to be changed + */ + +A_STATUS +BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) +{ + /* TODO */ + return A_ERROR; +} + +A_STATUS +BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) +{ + /* TODO */ + return A_ERROR; +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi_internal.h new file mode 100644 index 0000000000000..5f5d775bcdc06 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/bmi_internal.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef BMI_INTERNAL_H +#define BMI_INTERNAL_H + +#include +//#include "a_config.h" +#include "athdefs.h" +#include "a_types.h" +#include "osapi_linux.h" +#define ATH_MODULE_NAME bmi +#include "a_debug.h" +#include "bmi_msg.h" + +#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) + +/* ------ Global Variable Declarations ------- */ +//A_BOOL bmiDone; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/fw_one_bin.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/fw_one_bin.h new file mode 100644 index 0000000000000..4f7c40cb22420 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/fw_one_bin.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * fw_one_bin.h + */ + +#ifndef FW_ONE_BIN_H_ +#define FW_ONE_BIN_H_ + +/* Firmware Single Binary Magic Number */ +#define ONE_BIN_MAGIC_NUM ('Q' | 'C' << 8 | 'A' << 16 | 'W' << 24) + +/* Format version */ +#define ONE_BIN_FORMAT_MAJOR 0x1 +#define ONE_BIN_FORMAT_MINOR 0 +#define ONE_BIN_FORMAT_VER (ONE_BIN_FORMAT_MAJOR << 16 | ONE_BIN_FORMAT_MINOR) + +/* CHIP ID */ +#define AR6320_1_0_CHIP_ID 0x5000000 +#define AR6320_1_1_CHIP_ID 0x5000001 +#define AR6320_1_3_CHIP_ID 0x5000003 +#define AR6320_2_0_CHIP_ID 0x5010000 + +/* WLAN BINARY_ID */ +#define WLAN_SETUP_BIN_ID 0x01 +#define WLAN_OTP_BIN_ID 0x02 +#define WLAN_ATHWLAN_BIN_ID 0x0F + +/* UTF BINARY_ID */ +#define UTF_SETUP_BIN_ID 0x10 +#define UTF_OTP_BIN_ID 0x20 +#define UTF_UTF_BIN_ID 0xF0 + +/* BINARY_GROUP_ID */ +#define WLAN_GROUP_ID 0x80000000 +#define UTF_GROUP_ID 0x40000000 + +/* ACTION */ +#define ACTION_PARSE_SIG 0x80000000 /* parse signature */ +#define ACTION_DOWNLOAD 0x1 /* download only */ +#define ACTION_DOWNLOAD_EXEC 0x3 /* download binary and execute */ + +/* Binary Meta Header */ +typedef struct { + unsigned int magic_num; /* = ONE_BIN_MAGIC_NUM */ + unsigned int total_len; /* single binary file length */ + unsigned int format_ver; /* single binary format version */ + unsigned int fst_tag_off; /* offset of the first binary's CHIP_ID */ +} FW_ONE_BIN_META_T; + +/* Binary description header */ +typedef struct { + unsigned int chip_id; /* CHIP_ID */ + unsigned int binary_id; /* BINARY_ID */ + unsigned int bin_group_id; /* BINARY_GROUP_ID */ + unsigned int next_tag_off; /* Offset of the next binary's CHIP_ID */ + unsigned int binary_off; /* Offset of binary */ + unsigned int binary_len; /* Length of binary */ + unsigned int action; /* Action of binary operation */ + unsigned int reserved; /* 0, reserved */ +} FW_BIN_HEADER_T; + +#endif /* FW_ONE_BIN_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.c new file mode 100644 index 0000000000000..7a0c1dbaa9f22 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.c @@ -0,0 +1,2390 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include "ol_if_athvar.h" +#include "ol_fw.h" +#include "targaddrs.h" +#include "bmi.h" +#include "ol_cfg.h" +#include "vos_api.h" +#include "wma_api.h" +#include "wma.h" +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#else +#include "if_ath_sdio.h" +#include "regtable.h" +#endif + + +#define ATH_MODULE_NAME bmi +#include "a_debug.h" +#include "fw_one_bin.h" +#include "bin_sig.h" +#include "ar6320v2_dbg_regtable.h" +#include "epping_main.h" +#if defined(CONFIG_CNSS) +#include +#endif + +#include "qwlan_version.h" + +#ifdef FEATURE_SECURE_FIRMWARE +#define MAX_FIRMWARE_SIZE (1*1024*1024) + +static u8 fw_mem[MAX_FIRMWARE_SIZE]; +static struct hash_fw fw_hash; +#endif + +#ifdef HIF_PCI +static u_int32_t refclk_speed_to_hz[] = { + 48000000, /* SOC_REFCLK_48_MHZ */ + 19200000, /* SOC_REFCLK_19_2_MHZ */ + 24000000, /* SOC_REFCLK_24_MHZ */ + 26000000, /* SOC_REFCLK_26_MHZ */ + 37400000, /* SOC_REFCLK_37_4_MHZ */ + 38400000, /* SOC_REFCLK_38_4_MHZ */ + 40000000, /* SOC_REFCLK_40_MHZ */ + 52000000, /* SOC_REFCLK_52_MHZ */ +}; +#endif + +#ifdef HIF_SDIO +static struct ol_fw_files FW_FILES_QCA6174_FW_1_1 = { + "qwlan11.bin", "bdwlan11.bin", "otp11.bin", "utf11.bin", + "utfbd11.bin", "qsetup11.bin", "epping11.bin"}; +static struct ol_fw_files FW_FILES_QCA6174_FW_2_0 = { + "qwlan20.bin", "bdwlan20.bin", "otp20.bin", "utf20.bin", + "utfbd20.bin", "qsetup20.bin", "epping20.bin"}; +static struct ol_fw_files FW_FILES_QCA6174_FW_1_3 = { + "qwlan13.bin", "bdwlan13.bin", "otp13.bin", "utf13.bin", + "utfbd13.bin", "qsetup13.bin", "epping13.bin"}; +static struct ol_fw_files FW_FILES_QCA6174_FW_3_0 = { + "qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin", + "utfbd30.bin", "qsetup30.bin", "epping30.bin"}; +static struct ol_fw_files FW_FILES_DEFAULT = { + "qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin", + "utfbd.bin", "qsetup.bin", "epping.bin"}; + +static A_STATUS ol_sdio_extra_initialization(struct ol_softc *scn); + +static int ol_get_fw_files_for_target(struct ol_fw_files *pfw_files, + u32 target_version) +{ + if (!pfw_files) + return -ENODEV; + + switch (target_version) { + case AR6320_REV1_VERSION: + case AR6320_REV1_1_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_1_1, sizeof(*pfw_files)); + break; + case AR6320_REV1_3_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_1_3, sizeof(*pfw_files)); + break; + case AR6320_REV2_1_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_2_0, sizeof(*pfw_files)); + break; + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files)); + break; + default: + memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files)); + pr_err("%s version mismatch 0x%X ", + __func__, target_version); + break; + } + return 0; +} +#endif + +extern int +dbglog_parse_debug_logs(ol_scn_t scn, u_int8_t *datap, u_int32_t len); + +static int ol_transfer_single_bin_file(struct ol_softc *scn, + u_int32_t address, + bool compressed) +{ + int status = EOK; + const char *filename = AR61X4_SINGLE_FILE; + const struct firmware *fw_entry; + u_int32_t fw_entry_size; + u_int8_t *temp_eeprom = NULL; + FW_ONE_BIN_META_T *one_bin_meta_header = NULL; + FW_BIN_HEADER_T *one_bin_header = NULL; + SIGN_HEADER_T *sign_header = NULL; + unsigned char *fw_entry_data = NULL; + u_int32_t groupid = WLAN_GROUP_ID; + u_int32_t binary_offset = 0; + u_int32_t binary_len = 0; + u_int32_t next_tag_offset = 0; + u_int32_t param = 0; + bool meta_header = FALSE; + bool fw_sign = FALSE; + bool is_group = FALSE; + +#ifdef QCA_WIFI_FTM + if (vos_get_conparam() == VOS_FTM_MODE) + groupid = UTF_GROUP_ID; +#endif + + if (groupid == WLAN_GROUP_ID) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + ("%s: Downloading mission mode firmware\n", + __func__)); + } + else { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + ("%s: Downloading test mode firmware\n", + __func__)); + } + + if (request_firmware(&fw_entry, filename, scn->sc_osdev->device) != 0) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: Failed to get %s\n", + __func__, filename)); + return -ENOENT; + } + + fw_entry_size = fw_entry->size; + fw_entry_data = (unsigned char *)fw_entry->data; + binary_len = fw_entry_size; + + temp_eeprom = OS_MALLOC(scn->sc_osdev, fw_entry_size, GFP_ATOMIC); + if (!temp_eeprom) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: Memory allocation failed\n", + __func__)); + release_firmware(fw_entry); + return A_ERROR; + } + + OS_MEMCPY(temp_eeprom, (u_int8_t *)fw_entry->data, fw_entry_size); + + is_group = FALSE; + do { + if (!meta_header) { + if (fw_entry_size <= sizeof(FW_ONE_BIN_META_T) + + sizeof(FW_BIN_HEADER_T)) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: file size error!\n", + __func__)); + status = A_ERROR; + goto exit; + } + + one_bin_meta_header = (FW_ONE_BIN_META_T*)fw_entry_data; + if (one_bin_meta_header->magic_num != ONE_BIN_MAGIC_NUM) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: one binary magic num err: %d\n", + __func__, + one_bin_meta_header->magic_num)); + status = A_ERROR; + goto exit; + } + if (one_bin_meta_header->fst_tag_off + + sizeof(FW_BIN_HEADER_T) >= fw_entry_size) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: one binary first tag offset error: %d\n", + __func__, one_bin_meta_header->fst_tag_off)); + status = A_ERROR; + goto exit; + } + + one_bin_header = (FW_BIN_HEADER_T *)( + (u_int8_t *)fw_entry_data + + one_bin_meta_header->fst_tag_off); + + while (one_bin_header->bin_group_id != groupid) + { + if (one_bin_header->next_tag_off + + sizeof(FW_BIN_HEADER_T) > fw_entry_size) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: tag offset is error: bin id: %d, bin len: %d, tag offset: %d \n", + __func__, one_bin_header->binary_id, + one_bin_header->binary_len, + one_bin_header->next_tag_off)); + status = A_ERROR; + goto exit; + } + + one_bin_header = (FW_BIN_HEADER_T *)( + (u_int8_t *)fw_entry_data + + one_bin_header->next_tag_off); + } + + meta_header = TRUE; + } + + binary_offset = one_bin_header->binary_off; + binary_len = one_bin_header->binary_len; + next_tag_offset = one_bin_header->next_tag_off; + + if (one_bin_header->action & ACTION_PARSE_SIG) + fw_sign = TRUE; + else + fw_sign = FALSE; + + if (fw_sign) + { + if (binary_len < sizeof(SIGN_HEADER_T)) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: sign header size is error: bin id: %d, bin len: %d, sign header size: %zu \n", + __func__, one_bin_header->binary_id, + one_bin_header->binary_len, + sizeof(SIGN_HEADER_T))); + status = A_ERROR; + goto exit; + } + sign_header = (SIGN_HEADER_T *)((u_int8_t *)fw_entry_data + + binary_offset); + + status = BMISignStreamStart(scn->hif_hdl, address, + (u_int8_t *)fw_entry_data + + binary_offset, + sizeof(SIGN_HEADER_T), scn); + if (status != EOK) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: unable to start sign stream\n", + __func__)); + status = A_ERROR; + goto exit; + } + + binary_offset += sizeof(SIGN_HEADER_T); + binary_len = sign_header->rampatch_len + - sizeof(SIGN_HEADER_T); + } + + if (compressed) + status = BMIFastDownload(scn->hif_hdl, address, + (u_int8_t *)fw_entry_data + + binary_offset, + binary_len, scn); + else + status = BMIWriteMemory(scn->hif_hdl, address, + (u_int8_t *)fw_entry_data + + binary_offset, + binary_len, scn); + + if (fw_sign) + { + binary_offset += binary_len; + binary_len = sign_header->total_len + - sign_header->rampatch_len; + + if (binary_len > 0) + { + status = BMISignStreamStart(scn->hif_hdl, 0, + (u_int8_t *)fw_entry_data + + binary_offset, + binary_len, scn); + if (status != EOK) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s:sign stream error\n", + __func__)); + } + } + } + + if ((one_bin_header->action & ACTION_DOWNLOAD_EXEC) \ + == ACTION_DOWNLOAD_EXEC) + { + param = 0; + BMIExecute(scn->hif_hdl, address, ¶m, scn); + } + + if ((next_tag_offset) > 0 && + (one_bin_header->bin_group_id == groupid)) + { + one_bin_header = (FW_BIN_HEADER_T *)( + (u_int8_t *)fw_entry_data + + one_bin_header->next_tag_off); + if (one_bin_header->bin_group_id == groupid) + is_group = TRUE; + else + is_group = FALSE; + } + else { + is_group = FALSE; + } + + if (!is_group) + next_tag_offset = 0; + + } while (next_tag_offset > 0); + +exit: + if (temp_eeprom) + OS_FREE(temp_eeprom); + + if (status != EOK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("BMI operation failed: %d\n", __LINE__)); + release_firmware(fw_entry); + return -1; + } + + release_firmware(fw_entry); + + return status; +} + +#ifdef FEATURE_SECURE_FIRMWARE +static int ol_check_fw_hash(const u8* data, u32 data_size, ATH_BIN_FILE file) +{ + u8 *hash = NULL; +#ifdef CONFIG_CNSS + u8 digest[SHA256_DIGEST_SIZE]; +#endif + u8 temp[SHA256_DIGEST_SIZE] = {}; + int ret = 0; + + switch(file) { + case ATH_BOARD_DATA_FILE: + hash = fw_hash.bdwlan; + break; + case ATH_OTP_FILE: + hash = fw_hash.otp; + break; + case ATH_FIRMWARE_FILE: +#ifdef QCA_WIFI_FTM + if (vos_get_conparam() == VOS_FTM_MODE) { + hash = fw_hash.utf; + break; + } +#endif + hash = fw_hash.qwlan; + default: + break; + } + + if (!hash) { + pr_err("No entry for file:%d Download FW in non-secure mode\n", file); + goto end; + } + + if (!OS_MEMCMP(hash, temp, SHA256_DIGEST_SIZE)) { + pr_err("Download FW in non-secure mode:%d\n", file); + goto end; + } + +#ifdef CONFIG_CNSS + ret = cnss_get_sha_hash(data, data_size, "sha256", digest); + + if (ret) { + pr_err("Sha256 Hash computation fialed err:%d\n", ret); + goto end; + } + + if (OS_MEMCMP(hash, digest, SHA256_DIGEST_SIZE) != 0) { + pr_err("Hash Mismatch"); + vos_trace_hex_dump(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + digest, SHA256_DIGEST_SIZE); + vos_trace_hex_dump(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + hash, SHA256_DIGEST_SIZE); + ret = A_ERROR; + } +#endif +end: + return ret; +} +#endif + +static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, + u_int32_t address, bool compressed) +{ + int status = EOK; + const char *filename = NULL; + const struct firmware *fw_entry; + u_int32_t fw_entry_size; + u_int8_t *tempEeprom; + u_int32_t board_data_size; +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bool bin_sign = FALSE; + int bin_off, bin_len; + SIGN_HEADER_T *sign_header; +#endif + int ret; + + if (scn->enablesinglebinary && file != ATH_BOARD_DATA_FILE) { + /* + * Fallback to load split binaries if single binary is not found + */ + ret = ol_transfer_single_bin_file(scn, + address, + compressed); + + if (!ret) + return ret; + + if (ret != -ENOENT) + return -1; + } + + switch (file) { + default: + printk("%s: Unknown file type\n", __func__); + return -1; + case ATH_OTP_FILE: +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.otp_data; +#else + filename = QCA_OTP_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = TRUE; +#endif + break; + case ATH_FIRMWARE_FILE: + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.epping_file; +#else + filename = QCA_FIRMWARE_EPPING_FILE; +#endif + printk(KERN_INFO "%s: Loading epping firmware file %s\n", + __func__, filename); + break; + } +#ifdef QCA_WIFI_FTM + if (vos_get_conparam() == VOS_FTM_MODE) { +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.utf_file; +#else + filename = QCA_UTF_FIRMWARE_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = TRUE; +#endif + printk(KERN_INFO "%s: Loading firmware file %s\n", + __func__, filename); + break; + } +#endif +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.image_file; +#else + filename = QCA_FIRMWARE_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = TRUE; +#endif + break; + case ATH_PATCH_FILE: + printk("%s: no Patch file defined\n", __func__); + return EOK; + case ATH_BOARD_DATA_FILE: +#ifdef QCA_WIFI_FTM + if (vos_get_conparam() == VOS_FTM_MODE) { +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.utf_board_data; +#else + filename = QCA_BOARD_DATA_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = TRUE; +#endif + printk(KERN_INFO "%s: Loading board data file %s\n", + __func__, filename); + break; + } +#endif /* QCA_WIFI_FTM */ +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + filename = scn->fw_files.board_data; +#else + filename = QCA_BOARD_DATA_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = FALSE; +#endif + break; + case ATH_SETUP_FILE: + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { +#ifdef CONFIG_CNSS + printk("%s: no Setup file defined\n", __func__); + return -1; +#else +#ifdef HIF_SDIO + filename = scn->fw_files.setup_file; +#else + filename = QCA_SETUP_FILE; +#endif +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + bin_sign = TRUE; +#endif + printk(KERN_INFO "%s: Loading setup file %s\n", + __func__, filename); +#endif /* CONFIG_CNSS */ + } else { + printk("%s: no Setup file needed\n", __func__); + return -1; + } + break; + } + + if (request_firmware(&fw_entry, filename, scn->sc_osdev->device) != 0) + { + printk("%s: Failed to get %s\n", __func__, filename); + + if (file == ATH_OTP_FILE) + return -ENOENT; + +#if defined(QCA_WIFI_FTM) && (defined(CONFIG_CNSS) || defined(HIF_SDIO)) + /* Try default board data file if FTM specific + * board data file is not present. */ + if (filename == scn->fw_files.utf_board_data) { + filename = scn->fw_files.board_data; + printk("%s: Trying to load default %s\n", + __func__, filename); + if (request_firmware(&fw_entry, filename, + scn->sc_osdev->device) != 0) { + printk("%s: Failed to get %s\n", + __func__, filename); + return -1; + } + } else { + return -1; + } +#else + return -1; +#endif + } + + if (!fw_entry || !fw_entry->data) { + printk("Invalid fw_entries\n"); + return A_ERROR; + } + + fw_entry_size = fw_entry->size; + tempEeprom = NULL; + +#ifdef FEATURE_SECURE_FIRMWARE + if (fw_entry_size <= MAX_FIRMWARE_SIZE) { + OS_MEMCPY(fw_mem, fw_entry->data, fw_entry_size); + } else { + pr_err("%s: No enough memory to copy FW data!", __func__); + status = A_ERROR; + goto end; + } + + if (scn->enable_fw_hash_check && + ol_check_fw_hash(fw_entry->data, fw_entry_size, file)) { + pr_err("Hash Check failed for file:%s\n", filename); + status = A_ERROR; + goto end; + } +#endif + + if (file == ATH_BOARD_DATA_FILE) + { + u_int32_t board_ext_address; + int32_t board_ext_data_size; + + tempEeprom = OS_MALLOC(scn->sc_osdev, fw_entry_size, GFP_ATOMIC); + if (!tempEeprom) { + printk("%s: Memory allocation failed\n", __func__); + release_firmware(fw_entry); + return A_ERROR; + } + + OS_MEMCPY(tempEeprom, (u_int8_t *)fw_entry->data, fw_entry_size); + + switch (scn->target_type) { + default: + board_data_size = 0; + board_ext_data_size = 0; + break; + case TARGET_TYPE_AR6004: + board_data_size = AR6004_BOARD_DATA_SZ; + board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ; + case TARGET_TYPE_AR9888: + board_data_size = AR9888_BOARD_DATA_SZ; + board_ext_data_size = AR9888_BOARD_EXT_DATA_SZ; + break; + } + + /* Determine where in Target RAM to write Board Data */ + BMIReadMemory(scn->hif_hdl, + HOST_INTEREST_ITEM_ADDRESS(scn->target_type, hi_board_ext_data), + (u_int8_t *)&board_ext_address, 4, scn); + printk("Board extended Data download address: 0x%x\n", board_ext_address); + + /* + * Check whether the target has allocated memory for extended board + * data and file contains extended board data + */ + if ((board_ext_address) && (fw_entry_size == (board_data_size + board_ext_data_size))) + { + u_int32_t param; + + status = BMIWriteMemory(scn->hif_hdl, board_ext_address, + (u_int8_t *)(tempEeprom + board_data_size), board_ext_data_size, scn); + + if (status != EOK) + goto end; + + /* Record the fact that extended board Data IS initialized */ + param = (board_ext_data_size << 16) | 1; + BMIWriteMemory(scn->hif_hdl, + HOST_INTEREST_ITEM_ADDRESS(scn->target_type, hi_board_ext_data_config), + (u_int8_t *)¶m, 4, scn); + + fw_entry_size = board_data_size; + } + } + +#ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT + if (bin_sign) { + u_int32_t chip_id; + + if (fw_entry_size < sizeof(SIGN_HEADER_T)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: Invalid binary size %d\n", __func__, + fw_entry_size)); + status = A_ERROR; + goto end; + } + + sign_header = (SIGN_HEADER_T *)fw_entry->data; + chip_id = cpu_to_le32(sign_header->product_id); + if (sign_header->magic_num == SIGN_HEADER_MAGIC + && (chip_id == AR6320_REV1_1_VERSION + || chip_id == AR6320_REV1_3_VERSION + || chip_id == AR6320_REV2_1_VERSION)) { + + status = BMISignStreamStart(scn->hif_hdl, address, + (u_int8_t *)fw_entry->data, + sizeof(SIGN_HEADER_T), scn); + if (status != EOK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: unable to start sign stream\n", + __func__)); + status = A_ERROR; + goto end; + } + + bin_off = sizeof(SIGN_HEADER_T); + bin_len = sign_header->rampatch_len + - sizeof(SIGN_HEADER_T); + } else { + bin_sign = FALSE; + bin_off = 0; + bin_len = fw_entry_size; + } + } else { + bin_len = fw_entry_size; + bin_off = 0; + } + + if (compressed) { + status = BMIFastDownload(scn->hif_hdl, address, + (u_int8_t *)fw_entry->data + bin_off, + bin_len, scn); + } else { + if (file == ATH_BOARD_DATA_FILE && fw_entry->data) { + status = BMIWriteMemory(scn->hif_hdl, address, + (u_int8_t *)tempEeprom, + fw_entry_size, scn); + } else { + status = BMIWriteMemory(scn->hif_hdl, address, + (u_int8_t *)fw_entry->data + + bin_off, + bin_len, scn); + } + } + + if (bin_sign) { + bin_off += bin_len; + bin_len = sign_header->total_len + - sign_header->rampatch_len; + + if (bin_len > 0) { + status = BMISignStreamStart(scn->hif_hdl, 0, + (u_int8_t *)fw_entry->data + bin_off, + bin_len, scn); + if (status != EOK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s:sign stream error\n", + __func__)); + } + } + } +#else + if (compressed) { + status = BMIFastDownload(scn->hif_hdl, address, + (u_int8_t *)fw_entry->data, + fw_entry_size, scn); + } else { + if (file == ATH_BOARD_DATA_FILE && fw_entry->data) { + status = BMIWriteMemory(scn->hif_hdl, address, + (u_int8_t *)tempEeprom, + fw_entry_size, scn); + } else { + status = BMIWriteMemory(scn->hif_hdl, address, + (u_int8_t *)fw_entry->data, + fw_entry_size, scn); + } + } +#endif /* QCA_SIGNED_SPLIT_BINARY_SUPPORT */ + +end: + if (tempEeprom) { + OS_FREE(tempEeprom); + } + + if (status != EOK) { + printk("%s, BMI operation failed: %d\n", __func__, __LINE__); + release_firmware(fw_entry); + return A_ERROR; + } + + release_firmware(fw_entry); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: transferring file: %s size %d bytes done!", __func__, + (filename!=NULL)?filename:"", fw_entry_size); + + return status; +} + +static int ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file, + u_int32_t address, bool compressed) +{ + int ret; + +#ifdef CONFIG_CNSS + /* Wait until suspend and resume are completed before loading FW */ + cnss_lock_pm_sem(); +#endif + + ret = __ol_transfer_bin_file(scn, file, address, compressed); + +#ifdef CONFIG_CNSS + cnss_release_pm_sem(); +#endif + + return ret; +} + +u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offset) +{ + switch (target_type) { + default: + ASSERT(0); + case TARGET_TYPE_AR6002: + return (AR6002_HOST_INTEREST_ADDRESS + item_offset); + case TARGET_TYPE_AR6003: + return (AR6003_HOST_INTEREST_ADDRESS + item_offset); + case TARGET_TYPE_AR6004: + return (AR6004_HOST_INTEREST_ADDRESS + item_offset); + case TARGET_TYPE_AR6006: + return (AR6006_HOST_INTEREST_ADDRESS + item_offset); + case TARGET_TYPE_AR9888: + return (AR9888_HOST_INTEREST_ADDRESS + item_offset); + case TARGET_TYPE_AR6320: + case TARGET_TYPE_AR6320V2: + return (AR6320_HOST_INTEREST_ADDRESS + item_offset); + } +} + +#ifdef HIF_PCI +int dump_CE_register(struct ol_softc *scn) +{ +#ifdef HIF_USB + struct hif_usb_softc *sc = scn->hif_sc; +#else + struct hif_pci_softc *sc = scn->hif_sc; +#endif + A_UINT32 CE_reg_address = CE0_BASE_ADDRESS; + A_UINT32 CE_reg_values[8][CE_USEFUL_SIZE>>2]; + A_UINT32 CE_reg_word_size = CE_USEFUL_SIZE>>2; + A_UINT16 i, j; + + for(i = 0; i < 8; i++, CE_reg_address += CE_OFFSET) { + if (HIFDiagReadMem(scn->hif_hdl, CE_reg_address, + (A_UCHAR*)&CE_reg_values[i][0], + CE_reg_word_size * sizeof(A_UINT32)) != A_OK) + { + printk(KERN_ERR "Dumping CE register failed!\n"); + return -EACCES; + } + } + + for (i = 0; i < 8; i++) { + printk("CE%d Registers:\n", i); + for (j = 0; j < CE_reg_word_size; j++) { + printk("0x%08x ", CE_reg_values[i][j]); + if (!((j+1)%5) || (CE_reg_word_size - 1) == j) + printk("\n"); + } + } + + return EOK; +} +#endif + +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) +static struct ol_softc *ramdump_scn; + +int ol_copy_ramdump(struct ol_softc *scn) +{ + int ret; + + if (!scn->ramdump_base || !scn->ramdump_size) { + pr_info("%s: No RAM dump will be collected since ramdump_base " + "is NULL or ramdump_size is 0!\n", __func__); + ret = -EACCES; + goto out; + } + + ret = ol_target_coredump(scn, scn->ramdump_base, scn->ramdump_size); + +out: + return ret; +} + +static void ramdump_work_handler(struct work_struct *ramdump) +{ +#if !defined(HIF_SDIO) + int ret; +#endif + u_int32_t host_interest_address; + u_int32_t dram_dump_values[4]; + + if (!ramdump_scn) { + printk("No RAM dump will be collected since ramdump_scn is NULL!\n"); + goto out_fail; + } +#if !defined(HIF_SDIO) +#ifdef DEBUG + ret = hif_pci_check_soc_status(ramdump_scn->hif_sc); + if (ret) + goto out_fail; + + ret = dump_CE_register(ramdump_scn); + if (ret) + goto out_fail; + + dump_CE_debug_register(ramdump_scn->hif_sc); +#endif +#endif + + if (HIFDiagReadMem(ramdump_scn->hif_hdl, + host_interest_item_address(ramdump_scn->target_type, + offsetof(struct host_interest_s, hi_failure_state)), + (A_UCHAR *)&host_interest_address, sizeof(u_int32_t)) != A_OK) { + printk(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n"); +#if !defined(HIF_SDIO) + ol_copy_ramdump(ramdump_scn); + cnss_device_crashed(); + return; +#endif + goto out_fail; + } + printk("Host interest item address: 0x%08x\n", host_interest_address); + + if (HIFDiagReadMem(ramdump_scn->hif_hdl, host_interest_address, + (A_UCHAR *)&dram_dump_values[0], 4 * sizeof(u_int32_t)) != A_OK) + { + printk("HifDiagReadiMem FW Dump Area failed!\n"); + goto out_fail; + } + printk("FW Assertion at PC: 0x%08x BadVA: 0x%08x TargetID: 0x%08x\n", + dram_dump_values[2], dram_dump_values[3], dram_dump_values[0]); + + if (ol_copy_ramdump(ramdump_scn)) + goto out_fail; + + printk("%s: RAM dump collecting completed!\n", __func__); + +#if defined(HIF_SDIO) + panic("CNSS Ram dump collected\n"); +#else + /* Notify SSR framework the target has crashed. */ + cnss_device_crashed(); +#endif + return; + +out_fail: + /* Silent SSR on dump failure */ +#ifdef CNSS_SELF_RECOVERY +#if !defined(HIF_SDIO) + cnss_device_self_recovery(); +#endif +#else + +#if defined(HIF_SDIO) + panic("CNSS Ram dump collection failed \n"); +#else + cnss_device_crashed(); +#endif +#endif + return; +} + +static DECLARE_WORK(ramdump_work, ramdump_work_handler); + +void ol_schedule_ramdump_work(struct ol_softc *scn) +{ + ramdump_scn = scn; + schedule_work(&ramdump_work); +} + +static void fw_indication_work_handler(struct work_struct *fw_indication) +{ +#if !defined(HIF_SDIO) + cnss_device_self_recovery(); +#endif +} + +static DECLARE_WORK(fw_indication_work, fw_indication_work_handler); + +void ol_schedule_fw_indication_work(struct ol_softc *scn) +{ + schedule_work(&fw_indication_work); +} +#endif + +#ifdef HIF_USB +/* Save memory addresses where we save FW ram dump, and then we could obtain + * them by symbol table. */ +A_UINT32 fw_stack_addr; +void *fw_ram_seg_addr[FW_RAM_SEG_CNT]; + +/* ol_ramdump_handler is to receive information of firmware crash dump, and + * save it in host memory. It consists of 5 parts: registers, call stack, + * DRAM dump, IRAM dump, and AXI dump, and they are reported to host in order. + * + * registers: wrapped in a USB packet by starting as FW_ASSERT_PATTERN and + * 60 registers. + * call stack: wrapped in multiple USB packets, and each of them starts as + * FW_REG_PATTERN and contains multiple double-words. The tail + * of the last packet is FW_REG_END_PATTERN. + * DRAM dump: wrapped in multiple USB pakcets, and each of them start as + * FW_RAMDUMP_PATTERN and contains multiple double-wors. The tail + * of the last packet is FW_RAMDUMP_END_PATTERN; + * IRAM dump and AXI dump are with the same format as DRAM dump. + */ +void ol_ramdump_handler(struct ol_softc *scn) +{ + A_UINT32 *reg, pattern, i, start_addr = 0; + A_UINT32 MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0, len; + A_UINT8 *data; + A_UINT8 str_buf[128]; + A_UINT8 *ram_ptr = NULL; + A_UINT32 remaining; + char *fw_ram_seg_name[FW_RAM_SEG_CNT] = {"DRAM", "IRAM", "AXI"}; + + data = scn->hif_sc->fw_data; + len = scn->hif_sc->fw_data_len; + pattern = *((A_UINT32 *) data); + + if (pattern == FW_ASSERT_PATTERN) { + MSPId = (scn->target_fw_version & 0xf0000000) >> 28; + mSPId = (scn->target_fw_version & 0xf000000) >> 24; + SIId = (scn->target_fw_version & 0xf00000) >> 20; + CRMId = scn->target_fw_version & 0x7fff; + pr_err("Firmware crash detected...\n"); + pr_err("Host SW version: %s\n", QWLAN_VERSIONSTR); + pr_err("FW version: %d.%d.%d.%d", MSPId, mSPId, SIId, CRMId); + reg = (A_UINT32 *) (data + 4); + print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, 16, 4, reg, + min_t(A_UINT32, len - 4, FW_REG_DUMP_CNT * 4), + false); + scn->fw_ram_dumping = 0; + } + else if (pattern == FW_REG_PATTERN) { + reg = (A_UINT32 *) (data + 4); + start_addr = *reg++; + if (scn->fw_ram_dumping == 0) { + pr_err("Firmware stack dump:"); + scn->fw_ram_dumping = 1; + fw_stack_addr = start_addr; + } + remaining = len - 8; + /* len is in byte, but it's printed in double-word. */ + for (i = 0; i < (len - 8); i += 16) { + if ((*reg == FW_REG_END_PATTERN) && (i == len - 12)) { + scn->fw_ram_dumping = 0; + pr_err("Stack start address = %#08x\n", + fw_stack_addr); + break; + } + hex_dump_to_buffer(reg, remaining, 16, 4, str_buf, + sizeof(str_buf), false); + pr_err("%#08x: %s\n", start_addr + i, str_buf); + remaining -= 16; + reg += 4; + } + } + else if ((!scn->enableFwSelfRecovery)&& + ((pattern & FW_RAMDUMP_PATTERN_MASK) == + FW_RAMDUMP_PATTERN)) { + VOS_ASSERT(scn->ramdump_index < FW_RAM_SEG_CNT); + i = scn->ramdump_index; + reg = (A_UINT32 *) (data + 4); + if (scn->fw_ram_dumping == 0) { + scn->fw_ram_dumping = 1; + pr_err("Firmware %s dump:\n", fw_ram_seg_name[i]); + scn->ramdump[i] = kmalloc(sizeof(struct fw_ramdump) + + FW_RAMDUMP_SEG_SIZE, + GFP_KERNEL); + if (!scn->ramdump[i]) { + pr_err("Fail to allocate memory for ram dump"); + VOS_BUG(0); + } + (scn->ramdump[i])->mem = + (A_UINT8 *) (scn->ramdump[i] + 1); + fw_ram_seg_addr[i] = (scn->ramdump[i])->mem; + pr_err("FW %s start addr = %#08x\n", + fw_ram_seg_name[i], *reg); + pr_err("Memory addr for %s = %#08x\n", + fw_ram_seg_name[i], + (A_UINT32) (scn->ramdump[i])->mem); + (scn->ramdump[i])->start_addr = *reg; + (scn->ramdump[i])->length = 0; + } + reg++; + ram_ptr = (scn->ramdump[i])->mem + (scn->ramdump[i])->length; + (scn->ramdump[i])->length += (len - 8); + memcpy(ram_ptr, (A_UINT8 *) reg, len - 8); + + if (pattern == FW_RAMDUMP_END_PATTERN) { + pr_err("%s memory size = %d\n", fw_ram_seg_name[i], + (scn->ramdump[i])->length); + if (i == (FW_RAM_SEG_CNT - 1)) { + VOS_BUG(0); + } + + scn->ramdump_index++; + scn->fw_ram_dumping = 0; + } + } +} +#endif + +#define REGISTER_DUMP_LEN_MAX 60 +#define REG_DUMP_COUNT 60 + +void ol_target_failure(void *instance, A_STATUS status) +{ + struct ol_softc *scn = (struct ol_softc *)instance; + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); +#ifndef CONFIG_CNSS + A_UINT32 reg_dump_area = 0; + A_UINT32 reg_dump_values[REGISTER_DUMP_LEN_MAX]; + A_UINT32 reg_dump_cnt = 0; + A_UINT32 i; + A_UINT32 dbglog_hdr_address; + struct dbglog_hdr_host dbglog_hdr; + struct dbglog_buf_host dbglog_buf; + A_UINT8 *dbglog_data; +#else + int ret; +#endif + +#ifdef HIF_USB + /* Currently, only firmware crash triggers ol_target_failure. + In case, we need to dump RAM data. */ + if (status == A_USB_ERROR) { + ol_ramdump_handler(scn); + return; + } +#endif + + vos_event_set(&wma->recovery_event); + + if (OL_TRGET_STATUS_RESET == scn->target_status) { + printk("Target is already asserted, ignore!\n"); + return; + } + + scn->target_status = OL_TRGET_STATUS_RESET; + + if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + pr_info("%s: LOGP is in progress, ignore!\n", __func__); + return; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + printk("%s: Loading/Unloading is in progress, ignore!\n", + __func__); + return; + } + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + +#ifdef CONFIG_CNSS + ret = hif_pci_check_fw_reg(scn->hif_sc); + if (0 == ret) { + ol_schedule_fw_indication_work(scn); + return; + } else if (-1 == ret) { + return; + } +#endif + + printk("XXX TARGET ASSERTED XXX\n"); + +#ifndef CONFIG_CNSS + if (HIFDiagReadMem(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_failure_state)), + (A_UCHAR *)®_dump_area, + sizeof(A_UINT32))!= A_OK) + { + printk("HifDiagReadiMem FW Dump Area Pointer failed\n"); + return; + } + + printk("Target Register Dump Location 0x%08X\n", reg_dump_area); + + reg_dump_cnt = REG_DUMP_COUNT; + + if (HIFDiagReadMem(scn->hif_hdl, + reg_dump_area, + (A_UCHAR*)®_dump_values[0], + reg_dump_cnt * sizeof(A_UINT32))!= A_OK) + { + printk("HifDiagReadiMem for FW Dump Area failed\n"); + return; + } + + printk("Target Register Dump\n"); + for (i = 0; i < reg_dump_cnt; i++) { + printk("[%02d] : 0x%08X\n", i, reg_dump_values[i]); + } + + if (HIFDiagReadMem(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_dbglog_hdr)), + (A_UCHAR *)&dbglog_hdr_address, + sizeof(dbglog_hdr_address))!= A_OK) + { + printk("HifDiagReadiMem FW dbglog_hdr_address failed\n"); + return; + } + + if (HIFDiagReadMem(scn->hif_hdl, + dbglog_hdr_address, + (A_UCHAR *)&dbglog_hdr, + sizeof(dbglog_hdr))!= A_OK) + { + printk("HifDiagReadiMem FW dbglog_hdr failed\n"); + return; + } + + if (HIFDiagReadMem(scn->hif_hdl, + (A_UINT32)dbglog_hdr.dbuf, + (A_UCHAR *)&dbglog_buf, + sizeof(dbglog_buf))!= A_OK) + { + printk("HifDiagReadiMem FW dbglog_buf failed\n"); + return; + } + + dbglog_data = adf_os_mem_alloc(scn->adf_dev, dbglog_buf.length + 4); + if (dbglog_data) { + if (HIFDiagReadMem(scn->hif_hdl, + (A_UINT32)dbglog_buf.buffer, + dbglog_data + 4, + dbglog_buf.length)!= A_OK) + { + printk("HifDiagReadiMem FW dbglog_data failed\n"); + } else { + printk("dbglog_hdr.dbuf=%u dbglog_data=%p dbglog_buf.buffer=%u dbglog_buf.length=%u\n", + dbglog_hdr.dbuf, dbglog_data, dbglog_buf.buffer, dbglog_buf.length); + + + OS_MEMCPY(dbglog_data, &dbglog_hdr.dropped, 4); + wma->is_fw_assert = 1; + (void)dbglog_parse_debug_logs(wma, dbglog_data, dbglog_buf.length + 4); + } + + adf_os_mem_free(dbglog_data); + } +#endif + +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + /* Collect the RAM dump through a workqueue */ + ol_schedule_ramdump_work(scn); +#endif + + return; +} + +int +ol_configure_target(struct ol_softc *scn) +{ + u_int32_t param; +#ifdef CONFIG_CNSS + struct cnss_platform_cap cap; +#endif + + /* Tell target which HTC version it is used*/ + param = HTC_PROTOCOL_VERSION; + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_app_host_interest)), + (u_int8_t *)¶m, + 4, scn)!= A_OK) + { + printk("BMIWriteMemory for htc version failed \n"); + return -1; + } + + /* set the firmware mode to STA/IBSS/AP */ + { + if (BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (A_UCHAR *)¶m, + 4, scn)!= A_OK) + { + printk("BMIReadMemory for setting fwmode failed \n"); + return A_ERROR; + } + + /* TODO following parameters need to be re-visited. */ + param |= (1 << HI_OPTION_NUM_DEV_SHIFT); //num_device + param |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT); //Firmware mode ?? + param |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); //mac_addr_method + param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); //firmware_bridge + param |= (0 << HI_OPTION_FW_SUBMODE_SHIFT); //fwsubmode + + printk("NUM_DEV=%d FWMODE=0x%x FWSUBMODE=0x%x FWBR_BUF %d\n", + 1, HI_OPTION_FW_MODE_AP, 0, 0); + + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (A_UCHAR *)¶m, + 4, scn) != A_OK) + { + printk("BMIWriteMemory for setting fwmode failed \n"); + return A_ERROR; + } + } + +#if defined(HIF_PCI) +#if (CONFIG_DISABLE_CDC_MAX_PERF_WAR) + { + /* set the firmware to disable CDC max perf WAR */ + if (BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, + 4, scn)!= A_OK) + { + printk("BMIReadMemory for setting cdc max perf failed \n"); + return A_ERROR; + } + + param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR; + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, + 4, scn) != A_OK) + { + printk("BMIWriteMemory for setting cdc max perf failed \n"); + return A_ERROR; + } + } +#endif /* CONFIG_CDC_MAX_PERF_WAR */ + +#endif /*HIF_PCI*/ + +#ifdef CONFIG_CNSS + { + int ret; + + ret = cnss_get_platform_cap(&cap); + if (ret) + pr_err("platform capability info from CNSS not available\n"); + + if (!ret && cap.cap_flag & CNSS_HAS_EXTERNAL_SWREG) { + if (BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, 4, scn)!= A_OK) { + printk("BMIReadMemory for setting external SWREG failed\n"); + return A_ERROR; + } + + param |= HI_OPTION_USE_EXT_LDO; + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, 4, scn) != A_OK) { + printk("BMIWriteMemory for setting external SWREG failed\n"); + return A_ERROR; + } + } + } +#endif + +#ifdef WLAN_FEATURE_LPSS + if (scn->enablelpasssupport) { + if (BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, 4, scn)!= A_OK) { + printk("BMIReadMemory for setting LPASS Support failed\n"); + return A_ERROR; + } + + param |= HI_OPTION_DBUART_SUPPORT; + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_option_flag2)), + (A_UCHAR *)¶m, 4, scn) != A_OK) { + printk("BMIWriteMemory for setting LPASS Support failed\n"); + return A_ERROR; + } + } +#endif + + /* If host is running on a BE CPU, set the host interest area */ + { +#ifdef BIG_ENDIAN_HOST + param = 1; +#else + param = 0; +#endif + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_be)), + (A_UCHAR *)¶m, + 4, scn) != A_OK) + { + printk("BMIWriteMemory for setting host CPU BE mode failed \n"); + return A_ERROR; + } + } + + /* FW descriptor/Data swap flags */ + { + param = 0; + if (BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_fw_swap)), + (A_UCHAR *)¶m, + 4, scn) != A_OK) + { + printk("BMIWriteMemory for setting FW data/desc swap flags failed \n"); + return A_ERROR; + } + } + + return A_OK; +} + +static int +ol_check_dataset_patch(struct ol_softc *scn, u_int32_t *address) +{ + /* Check if patch file needed for this target type/version. */ + return 0; +} + +#ifdef HIF_PCI + +A_STATUS ol_fw_populate_clk_settings(A_refclk_speed_t refclk, + struct cmnos_clock_s *clock_s) +{ + if (!clock_s) + return A_ERROR; + + switch (refclk) { + case SOC_REFCLK_48_MHZ: + clock_s->wlan_pll.div = 0xE; + clock_s->wlan_pll.rnfrac = 0x2AAA8; + clock_s->pll_settling_time = 2400; + break; + case SOC_REFCLK_19_2_MHZ: + clock_s->wlan_pll.div = 0x24; + clock_s->wlan_pll.rnfrac = 0x2AAA8; + clock_s->pll_settling_time = 960; + break; + case SOC_REFCLK_24_MHZ: + clock_s->wlan_pll.div = 0x1D; + clock_s->wlan_pll.rnfrac = 0x15551; + clock_s->pll_settling_time = 1200; + break; + case SOC_REFCLK_26_MHZ: + clock_s->wlan_pll.div = 0x1B; + clock_s->wlan_pll.rnfrac = 0x4EC4; + clock_s->pll_settling_time = 1300; + break; + case SOC_REFCLK_37_4_MHZ: + clock_s->wlan_pll.div = 0x12; + clock_s->wlan_pll.rnfrac = 0x34B49; + clock_s->pll_settling_time = 1870; + break; + case SOC_REFCLK_38_4_MHZ: + clock_s->wlan_pll.div = 0x12; + clock_s->wlan_pll.rnfrac = 0x15551; + clock_s->pll_settling_time = 1920; + break; + case SOC_REFCLK_40_MHZ: + clock_s->wlan_pll.div = 0x11; + clock_s->wlan_pll.rnfrac = 0x26665; + clock_s->pll_settling_time = 2000; + break; + case SOC_REFCLK_52_MHZ: + clock_s->wlan_pll.div = 0x1B; + clock_s->wlan_pll.rnfrac = 0x4EC4; + clock_s->pll_settling_time = 2600; + break; + case SOC_REFCLK_UNKNOWN: + clock_s->wlan_pll.refdiv = 0; + clock_s->wlan_pll.div = 0; + clock_s->wlan_pll.rnfrac = 0; + clock_s->wlan_pll.outdiv = 0; + clock_s->pll_settling_time = 1024; + clock_s->refclk_hz = 0; + default: + return A_ERROR; + } + + clock_s->refclk_hz = refclk_speed_to_hz[refclk]; + clock_s->wlan_pll.refdiv = 0; + clock_s->wlan_pll.outdiv = 1; + + return A_OK; +} + +A_STATUS ol_patch_pll_switch(struct ol_softc * scn) +{ + HIF_DEVICE *hif_device = scn->hif_hdl; + A_STATUS status; + u_int32_t addr = 0; + u_int32_t reg_val = 0; + u_int32_t mem_val = 0; + struct cmnos_clock_s clock_s; + u_int32_t cmnos_core_clk_div_addr = 0; + u_int32_t cmnos_cpu_pll_init_done_addr = 0; + u_int32_t cmnos_cpu_speed_addr = 0; +#ifdef HIF_USB/* fail for USB case */ + struct hif_usb_softc *sc = scn->hif_sc; +#else + struct hif_pci_softc *sc = scn->hif_sc; +#endif + + switch (scn->target_version) { + case AR6320_REV1_1_VERSION: + cmnos_core_clk_div_addr = AR6320_CORE_CLK_DIV_ADDR; + cmnos_cpu_pll_init_done_addr = AR6320_CPU_PLL_INIT_DONE_ADDR; + cmnos_cpu_speed_addr = AR6320_CPU_SPEED_ADDR; + break; + case AR6320_REV1_3_VERSION: + case AR6320_REV2_1_VERSION: + cmnos_core_clk_div_addr = AR6320V2_CORE_CLK_DIV_ADDR; + cmnos_cpu_pll_init_done_addr = AR6320V2_CPU_PLL_INIT_DONE_ADDR; + cmnos_cpu_speed_addr = AR6320V2_CPU_SPEED_ADDR; + break; + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + cmnos_core_clk_div_addr = AR6320V3_CORE_CLK_DIV_ADDR; + cmnos_cpu_pll_init_done_addr = AR6320V3_CPU_PLL_INIT_DONE_ADDR; + cmnos_cpu_speed_addr = AR6320V3_CPU_SPEED_ADDR; + break; + default: + pr_err("%s: Unsupported target version %x\n", __func__, + scn->target_version); + return A_ERROR; + } + + addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read EFUSE Addr\n"); + return status; + } + + status = ol_fw_populate_clk_settings(EFUSE_XTAL_SEL_GET(reg_val), + &clock_s); + if (status != A_OK) { + pr_err("Failed to set clock settings\n"); + return status; + } + pr_debug("crystal_freq: %dHz\n", clock_s.refclk_hz); + + /* ------Step 1----*/ + reg_val = 0; + addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read PLL_CONFIG Addr\n"); + return status; + } + pr_debug("Step 1a: %8X\n", reg_val); + + reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK); + reg_val |= (BB_PLL_CONFIG_FRAC_SET(clock_s.wlan_pll.rnfrac) | + BB_PLL_CONFIG_OUTDIV_SET(clock_s.wlan_pll.outdiv)); + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_CONFIG Addr\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back PLL_CONFIG Addr\n"); + return status; + } + pr_debug("Step 1b: %8X\n", reg_val); + + /* ------Step 2----*/ + reg_val = 0; + addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read PLL_SETTLE Addr\n"); + return status; + } + pr_debug("Step 2a: %8X\n", reg_val); + + reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK; + reg_val |= WLAN_PLL_SETTLE_TIME_SET(clock_s.pll_settling_time); + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_SETTLE Addr\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back PLL_SETTLE Addr\n"); + return status; + } + pr_debug("Step 2b: %8X\n", reg_val); + + /* ------Step 3----*/ + reg_val = 0; + addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read CLK_CTRL Addr\n"); + return status; + } + pr_debug("Step 3a: %8X\n", reg_val); + + reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK; + reg_val |= SOC_CORE_CLK_CTRL_DIV_SET(1); + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write CLK_CTRL Addr\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back CLK_CTRL Addr\n"); + return status; + } + pr_debug("Step 3b: %8X\n", reg_val); + + /* ------Step 4-----*/ + mem_val = 1; + status = BMIWriteMemory(hif_device, cmnos_core_clk_div_addr, + (A_UCHAR *)&mem_val, 4, scn); + if (status != A_OK) { + pr_err("Failed to write CLK_DIV Addr\n"); + return status; + } + + /* ------Step 5-----*/ + reg_val = 0; + addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read PLL_CTRL Addr\n"); + return status; + } + pr_debug("Step 5a: %8X\n", reg_val); + + reg_val &= ~(WLAN_PLL_CONTROL_REFDIV_MASK | WLAN_PLL_CONTROL_DIV_MASK | + WLAN_PLL_CONTROL_NOPWD_MASK); + reg_val |= (WLAN_PLL_CONTROL_REFDIV_SET(clock_s.wlan_pll.refdiv) | + WLAN_PLL_CONTROL_DIV_SET(clock_s.wlan_pll.div) | + WLAN_PLL_CONTROL_NOPWD_SET(1)); + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_CTRL Addr\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back PLL_CTRL Addr\n"); + return status; + } + OS_DELAY(100); + pr_debug("Step 5b: %8X\n", reg_val); + + /* ------Step 6-------*/ + do { + reg_val = 0; + status = BMIReadSOCRegister(hif_device, (RTC_WMAC_BASE_ADDRESS | + RTC_SYNC_STATUS_OFFSET), ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read RTC_SYNC_STATUS Addr\n"); + return status; + } + } while(RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val)); + + /* ------Step 7-------*/ + reg_val = 0; + addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read PLL_CTRL Addr for CTRL_BYPASS\n"); + return status; + } + pr_debug("Step 7a: %8X\n", reg_val); + + reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK; + reg_val |= WLAN_PLL_CONTROL_BYPASS_SET(0); + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_CTRL Addr for CTRL_BYPASS\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back PLL_CTRL Addr for CTRL_BYPASS\n"); + return status; + } + pr_debug("Step 7b: %8X\n", reg_val); + + /* ------Step 8--------*/ + do { + reg_val = 0; + status = BMIReadSOCRegister(hif_device, + (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET), + ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read SYNC_STATUS Addr\n"); + return status; + } + } while(RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val)); + + /* ------Step 9--------*/ + reg_val = 0; + addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read CPU_CLK Addr\n"); + return status; + } + pr_debug("Step 9a: %8X\n", reg_val); + + reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK; + reg_val |= SOC_CPU_CLOCK_STANDARD_SET(1);; + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write CPU_CLK Addr\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back CPU_CLK Addr\n"); + return status; + } + pr_debug("Step 9b: %8X\n", reg_val); + + /* ------Step 10-------*/ + reg_val = 0; + addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read PLL_CTRL Addr for NOPWD\n"); + return status; + } + pr_debug("Step 10a: %8X\n", reg_val); + + reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK; + status = BMIWriteSOCRegister(hif_device, addr, reg_val, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_CTRL Addr for NOPWD\n"); + return status; + } + + reg_val = 0; + status = BMIReadSOCRegister(hif_device, addr, ®_val, scn); + if (status != A_OK) { + pr_err("Failed to read back PLL_CTRL Addr for NOPWD\n"); + return status; + } + pr_debug("Step 10b: %8X\n", reg_val); + + /* ------Step 11-------*/ + mem_val = 1; + status = BMIWriteMemory(hif_device, cmnos_cpu_pll_init_done_addr, + (A_UCHAR *)&mem_val, 4, scn); + if (status != A_OK) { + pr_err("Failed to write PLL_INIT Addr\n"); + return status; + } + + mem_val = TARGET_CPU_FREQ; + status = BMIWriteMemory(hif_device, cmnos_cpu_speed_addr, + (A_UCHAR *)&mem_val, 4, scn); + if (status != A_OK) { + pr_err("Failed to write CPU_SPEED Addr\n"); + return status; + } + + return status; +} +#endif + +#ifdef CONFIG_CNSS +/* AXI Start Address */ +#define TARGET_ADDR (0xa0000) + +void ol_transfer_codeswap_struct(struct ol_softc *scn) { + struct hif_pci_softc *sc = scn->hif_sc; + struct codeswap_codeseg_info wlan_codeswap; + A_STATUS rv; + + if (!sc || !sc->hif_device) { + pr_err("%s: hif_pci_softc is null\n", __func__); + return; + } + + if (cnss_get_codeswap_struct(&wlan_codeswap)) { + pr_err("%s: failed to get codeswap structure\n", __func__); + return; + } + + rv = BMIWriteMemory(scn->hif_hdl, TARGET_ADDR, + (u_int8_t *)&wlan_codeswap, sizeof(wlan_codeswap), scn); + + if (rv != A_OK) { + pr_err("Failed to Write 0xa0000 for Target Memory Expansion\n"); + return; + } + pr_info("%s:codeswap structure is successfully downloaded\n", __func__); +} +#endif + +int ol_download_firmware(struct ol_softc *scn) +{ + u_int32_t param, address = 0; + int status = !EOK; +#if defined(HIF_PCI) + A_STATUS ret; +#endif + +#ifdef CONFIG_CNSS + if (0 != cnss_get_fw_files_for_target(&scn->fw_files, + scn->target_type, + scn->target_version)) { + printk("%s: No FW files from CNSS driver\n", __func__); + return -1; + } +#elif defined(HIF_SDIO) + if (0 != ol_get_fw_files_for_target(&scn->fw_files, + scn->target_version)) { + printk("%s: No FW files from driver\n", __func__); + return -1; + } +#endif + /* Transfer Board Data from Target EEPROM to Target RAM */ + /* Determine where in Target RAM to write Board Data */ + BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_board_data)), + (u_int8_t *)&address, 4, scn); + + if (!address) { + address = AR6004_REV5_BOARD_DATA_ADDRESS; + printk("%s: Target address not known! Using 0x%x\n", __func__, address); + } + +#if defined(HIF_PCI) + ret = ol_patch_pll_switch(scn); + if (ret) { + pr_err("pll switch failed. status %d\n", ret); + return -1; + } +#endif + + if (scn->cal_in_flash) { + /* Write EEPROM or Flash data to Target RAM */ + status = ol_transfer_bin_file(scn, ATH_FLASH_FILE, address, FALSE); + } + + if (status == EOK) { + /* Record the fact that Board Data is initialized */ + param = 1; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_board_data_initialized)), + (u_int8_t *)¶m, 4, scn); + } else { + /* Flash is either not available or invalid */ + if (ol_transfer_bin_file(scn, ATH_BOARD_DATA_FILE, address, FALSE) != EOK) { + return -1; + } + + /* Record the fact that Board Data is initialized */ + param = 1; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, hi_board_data_initialized)), + (u_int8_t *)¶m, 4, scn); + + /* Transfer One Time Programmable data */ + address = BMI_SEGMENTED_WRITE_ADDR; + printk("%s: Using 0x%x for the remainder of init\n", __func__, address); + + if ( scn->enablesinglebinary == FALSE ) { +#ifdef CONFIG_CNSS + ol_transfer_codeswap_struct(scn); +#endif + + status = ol_transfer_bin_file(scn, ATH_OTP_FILE, + address, TRUE); + if (status == EOK) { + /* Execute the OTP code only if entry found and downloaded */ + param = 0; + BMIExecute(scn->hif_hdl, address, ¶m, scn); + } else if (status < 0) { + return status; + } + } + } + if (scn->target_version == AR6320_REV1_1_VERSION){ + /* To disable PCIe use 96 AXI memory as internal buffering, + * highest bit of PCIE_TXBUF_ADDRESS need be set as 1 + */ + u_int32_t addr = 0x3A058; /* PCIE_TXBUF_ADDRESS */ + u_int32_t value = 0; + /* Disable PCIe AXI memory */ + BMIReadMemory(scn->hif_hdl, addr, (A_UCHAR*)&value, 4, scn); + value |= 0x80000000; /* PCIE_TXBUF_BYPASS_SET(1) */ + BMIWriteMemory(scn->hif_hdl, addr, (A_UCHAR*)&value, 4, scn); + value = 0; + BMIReadMemory(scn->hif_hdl, addr, (A_UCHAR*)&value, 4, scn); + printk("Disable PCIe use AXI memory:0x%08X-0x%08X\n", addr, value); + } + + if (scn->enablesinglebinary == FALSE) { + if (ol_transfer_bin_file(scn, ATH_SETUP_FILE, + BMI_SEGMENTED_WRITE_ADDR, TRUE) == EOK) { + /* Execute the SETUP code only if entry found and downloaded */ + param = 0; + BMIExecute(scn->hif_hdl, address, ¶m, scn); + } + } + + /* Download Target firmware - TODO point to target specific files in runtime */ + address = BMI_SEGMENTED_WRITE_ADDR; + if (ol_transfer_bin_file(scn, ATH_FIRMWARE_FILE, address, TRUE) != EOK) { + return -1; + } + + /* Apply the patches */ + if (ol_check_dataset_patch(scn, &address)) + { + if ((ol_transfer_bin_file(scn, ATH_PATCH_FILE, address, FALSE)) != EOK) { + return -1; + } + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_dset_list_head)), + (u_int8_t *)&address, 4, scn); + } + + if (scn->enableuartprint || + (WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && + WLAN_IS_EPPING_FW_UART(vos_get_conparam()))) { + switch (scn->target_version){ + case AR6004_VERSION_REV1_3: + param = 11; + break; + case AR6320_REV1_VERSION: + case AR6320_REV2_VERSION: + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + case AR6320_REV4_VERSION: + case AR6320_DEV_VERSION: + /* for SDIO, debug uart output gpio is 29, otherwise it is 6. */ +#ifdef HIF_SDIO + param = 19; +#else + param = 6; +#endif + break; + default: + /* Configure GPIO AR9888 UART */ + param = 7; + } + + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_dbg_uart_txpin)), + (u_int8_t *)¶m, 4, scn); + param = 1; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_serial_enable)), + (u_int8_t *)¶m, 4, scn); + } else { + /* + * Explicitly setting UART prints to zero as target turns it on + * based on scratch registers. + */ + param = 0; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s,hi_serial_enable)), + (u_int8_t *)¶m, 4, scn); + } + +#ifdef HIF_SDIO + /* HACK override dbg TX pin to avoid side effects of default GPIO_6 */ + param = 19; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, + hi_dbg_uart_txpin)), + (u_int8_t *)¶m, 4, scn); +#endif + + + if (scn->enablefwlog) { + BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (u_int8_t *)¶m, 4, scn); + + param &= ~(HI_OPTION_DISABLE_DBGLOG); + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (u_int8_t *)¶m, 4, scn); + } else { + /* + * Explicitly setting fwlog prints to zero as target turns it on + * based on scratch registers. + */ + BMIReadMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (u_int8_t *)¶m, 4, scn); + + param |= HI_OPTION_DISABLE_DBGLOG; + BMIWriteMemory(scn->hif_hdl, + host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag)), + (u_int8_t *)¶m, 4, scn); + } + +#ifdef HIF_SDIO + status = ol_sdio_extra_initialization(scn); +#endif + + return status; +} + +#if defined(HIF_PCI) || defined(HIF_SDIO) +int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer, + u_int32_t pos, size_t count) +{ + int result = 0; + + if ((4 == count) && ((pos & 3) == 0)) { + result = HIFDiagReadAccess(scn->hif_hdl, pos, + (u_int32_t*)buffer); + } else { +#ifdef HIF_PCI + size_t amountRead = 0; + size_t readSize = PCIE_READ_LIMIT; + size_t remainder = 0; + if (count > PCIE_READ_LIMIT) { + while ((amountRead < count) && (0 == result)) { + result = HIFDiagReadMem(scn->hif_hdl, pos, + buffer, readSize); + if (0 == result) { + buffer += readSize; + pos += readSize; + amountRead += readSize; + remainder = count - amountRead; + if (remainder < PCIE_READ_LIMIT) + readSize = remainder; + } + } + } else { +#endif + result = HIFDiagReadMem(scn->hif_hdl, pos, + buffer, count); +#ifdef HIF_PCI + } +#endif + } + + if (!result) { + return count; + } else { + return -EIO; + } +} + +#if defined(HIF_PCI) +static int ol_ath_get_reg_table(A_UINT32 target_version, + tgt_reg_table *reg_table) +{ + int section_len = 0; + + if (!reg_table) { + ASSERT(0); + return section_len; + } + + switch (target_version) { + case AR6320_REV2_1_VERSION: + reg_table->section = (tgt_reg_section *)&ar6320v2_reg_table[0]; + reg_table->section_size = sizeof(ar6320v2_reg_table) + /sizeof(ar6320v2_reg_table[0]); + section_len = AR6320_REV2_1_REG_SIZE; + break; + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + reg_table->section = (tgt_reg_section *)&ar6320v3_reg_table[0]; + reg_table->section_size = sizeof(ar6320v3_reg_table) + /sizeof(ar6320v3_reg_table[0]); + section_len = AR6320_REV3_REG_SIZE; + break; + default: + reg_table->section = (void *)NULL; + reg_table->section_size = 0; + section_len = 0; + } + + return section_len; +} + +static int ol_diag_read_reg_loc(struct ol_softc *scn, u_int8_t *buffer, + u_int32_t buffer_len) +{ + int i, len, section_len, fill_len; + int dump_len, result = 0; + tgt_reg_table reg_table; + tgt_reg_section *curr_sec, *next_sec; + + section_len = ol_ath_get_reg_table(scn->target_version, ®_table); + + if (!reg_table.section || !reg_table.section_size || !section_len) { + printk(KERN_ERR "%s: failed to get reg table\n", __func__); + result = -EIO; + goto out; + } + + curr_sec = reg_table.section; + for (i = 0; i < reg_table.section_size; i++) { + + dump_len = curr_sec->end_addr - curr_sec->start_addr; + + if ((buffer_len - result) < dump_len) { + printk("Not enough memory to dump the registers:" + " %d: 0x%08x-0x%08x\n", i, + curr_sec->start_addr, + curr_sec->end_addr); + goto out; + } + + len = ol_diag_read(scn, buffer, curr_sec->start_addr, dump_len); + + if (len != -EIO) { + buffer += len; + result += len; + } else { + printk(KERN_ERR "%s: can't read reg 0x%08x len = %d\n", + __func__, curr_sec->start_addr, dump_len); + result = -EIO; + goto out; + } + + if (result < section_len) { + next_sec = (tgt_reg_section *)((u_int8_t *)curr_sec + + sizeof(*curr_sec)); + fill_len = next_sec->start_addr - curr_sec->end_addr; + if ((buffer_len - result) < fill_len) { + printk("Not enough memory to fill registers:" + " %d: 0x%08x-0x%08x\n", i, + curr_sec->end_addr, + next_sec->start_addr); + goto out; + } + + if (fill_len) { + buffer += fill_len; + result += fill_len; + } + } + curr_sec++; + } + +out: + return result; +} + +void ol_dump_target_memory(HIF_DEVICE *hif_device, void *memoryBlock) +{ + char *bufferLoc = memoryBlock; + u_int32_t sectionCount = 0; + u_int32_t address = 0; + u_int32_t size = 0; + + for ( ; sectionCount < 2; sectionCount++) { + switch (sectionCount) { + case 0: + address = DRAM_LOCAL_BASE_ADDRESS; + size = DRAM_SIZE; + break; + case 1: + address = AXI_LOCATION; + size = AXI_SIZE; + default: + break; + } + + HIFDumpTargetMemory(hif_device, bufferLoc, address, size); + bufferLoc += size; + } +} +#endif + +/**--------------------------------------------------------------------------- + * \brief ol_target_coredump + * + * Function to perform core dump for the target + * + * \param: scn - ol_softc handler + * memoryBlock - non-NULL reserved memory location + * blockLength - size of the dump to collect + * + * \return: None + * --------------------------------------------------------------------------*/ +int ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) +{ + struct ol_softc *scn = (struct ol_softc *)inst; + char *bufferLoc = memoryBlock; + int result = 0; + int ret = 0; + u_int32_t amountRead = 0; + u_int32_t sectionCount = 0; + u_int32_t pos = 0; + u_int32_t readLen = 0; + + /* + * SECTION = DRAM + * START = 0x00400000 + * LENGTH = 0x000a8000 + * + * SECTION = AXI + * START = 0x000a0000 + * LENGTH = 0x00018000 + * + * SECTION = REG + * START = 0x00000800 + * LENGTH = 0x0007F820 + */ + + while ((sectionCount < 3) && (amountRead < blockLength)) { + switch (sectionCount) { + case 0: + /* DRAM SECTION */ + pos = DRAM_LOCATION; + readLen = DRAM_SIZE; + printk("%s: Dumping DRAM section...\n", __func__); + break; + case 1: + /* AXI SECTION */ + pos = AXI_LOCATION; + readLen = AXI_SIZE; + printk("%s: Dumping AXI section...\n", __func__); + break; + case 2: + /* REG SECTION */ + pos = REGISTER_LOCATION; + /* ol_diag_read_reg_loc checks for buffer overrun */ + readLen = 0; + printk("%s: Dumping Register section...\n", __func__); + break; + } + + if ((blockLength - amountRead) >= readLen) { +#if !defined(HIF_SDIO) + if (pos == REGISTER_LOCATION) + result = ol_diag_read_reg_loc(scn, bufferLoc, + blockLength - amountRead); + else +#endif + result = ol_diag_read(scn, bufferLoc, + pos, readLen); + if (result != -EIO) { + amountRead += result; + bufferLoc += result; + sectionCount++; + } else { +#ifdef CONFIG_HL_SUPPORT +#else + printk(KERN_ERR "Could not read dump section!\n"); + dump_CE_register(scn); + dump_CE_debug_register(scn->hif_sc); + ol_dump_target_memory(scn->hif_hdl, memoryBlock); + ret = -EACCES; +#endif + break; /* Could not read the section */ + } + } else { + printk(KERN_ERR "Insufficient room in dump buffer!\n"); + break; /* Insufficient room in buffer */ + } + } + return ret; +} +#endif + +#if defined(CONFIG_HL_SUPPORT) +#define MAX_SUPPORTED_PEERS_REV1_1 9 +#define MAX_SUPPORTED_PEERS_REV1_3 9 +#else +#define MAX_SUPPORTED_PEERS_REV1_1 14 +#define MAX_SUPPORTED_PEERS_REV1_3 32 +#endif + +u_int8_t ol_get_number_of_peers_supported(struct ol_softc *scn) +{ + u_int8_t max_no_of_peers = 0; + + switch (scn->target_version) { + case AR6320_REV1_1_VERSION: + if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_1) + max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_1; + else + max_no_of_peers = scn->max_no_of_peers; + break; + + default: + if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_3) + max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_3; + else + max_no_of_peers = scn->max_no_of_peers; + break; + + } + return max_no_of_peers; +} + +#ifdef HIF_SDIO +/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/ +static A_STATUS +ol_sdio_extra_initialization(struct ol_softc *scn) +{ + + A_STATUS status; + +#ifdef CONFIG_DISABLE_SLEEP_BMI_OPTION + uint32 value; +#endif + + do{ + A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; + unsigned int MboxIsrYieldValue = 99; + A_UINT32 TargetType = TARGET_TYPE_AR6320; + /* get the block sizes */ + status = HIFConfigureDevice(scn->hif_hdl, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, + blocksizes, sizeof(blocksizes)); + + if (A_FAILED(status)) { + printk("Failed to get block size info from HIF layer...\n"); + break; + } + /* note: we actually get the block size for mailbox 1, for SDIO the block + size on mailbox 0 is artificially set to 1 must be a power of 2 */ + A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0); + + /* set the host interest area for the block size */ + status = BMIWriteMemory(scn->hif_hdl, + HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz), + (A_UCHAR *)&blocksizes[1], + 4, + scn); + + if (A_FAILED(status)) { + printk("BMIWriteMemory for IO block size failed \n"); + break; + } + + if (MboxIsrYieldValue != 0) { + /* set the host interest area for the mbox ISR yield limit */ + status = BMIWriteMemory(scn->hif_hdl, + HOST_INTEREST_ITEM_ADDRESS(TargetType, + hi_mbox_isr_yield_limit), + (A_UCHAR *)&MboxIsrYieldValue, + 4, + scn); + + if (A_FAILED(status)) { + printk("BMIWriteMemory for yield limit failed \n"); + break; + } + } + +#ifdef CONFIG_DISABLE_SLEEP_BMI_OPTION + + printk("%s: prevent ROME from sleeping\n",__func__); + BMIReadSOCRegister(scn->hif_hdl, + MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET, + /* this address should be 0x80C0 for ROME*/ + &value, + scn); + + value |= SOC_OPTION_SLEEP_DISABLE; + + BMIWriteSOCRegister(scn->hif_hdl, + MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET, + value, + scn); +#endif + + }while(FALSE); + + return status; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.h new file mode 100644 index 0000000000000..0de84573383e4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/BMI/ol_fw.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_FW_H_ +#define _OL_FW_H_ + +#ifdef QCA_WIFI_FTM +#include "vos_types.h" +#endif + +#define AR6004_VERSION_REV1_3 0x31c8088a + +#define AR9888_REV1_VERSION 0x4000002c +#define AR9888_REV2_VERSION 0x4100016c +#define QCA_VERSION 0x4100270f +#define AR6320_REV1_VERSION 0x5000000 +#define AR6320_REV1_1_VERSION 0x5000001 +#define AR6320_REV1_VERSION_1 AR6320_REV1_1_VERSION +#define AR6320_REV1_3_VERSION 0x5000003 +#define AR6320_REV2_VERSION AR6320_REV1_1_VERSION +#define AR6320_REV2_1_VERSION 0x5010000 +#define AR6320_REV3_VERSION 0x5020000 +#define AR6320_REV3_2_VERSION 0x5030000 +#define AR6320_REV4_VERSION AR6320_REV2_1_VERSION +#define AR6320_DEV_VERSION 0x1000000 +#define QCA_FIRMWARE_FILE "athwlan.bin" +#define QCA_UTF_FIRMWARE_FILE "utf.bin" +#define QCA_BOARD_DATA_FILE "fakeboar.bin" +#define QCA_OTP_FILE "otp.bin" +#define QCA_SETUP_FILE "athsetup.bin" +#define AR61X4_SINGLE_FILE "qca61x4.bin" +#define QCA_FIRMWARE_EPPING_FILE "epping.bin" + +/* Configuration for statistics pushed by firmware */ +#define PDEV_DEFAULT_STATS_UPDATE_PERIOD 500 +#define VDEV_DEFAULT_STATS_UPDATE_PERIOD 500 +#define PEER_DEFAULT_STATS_UPDATE_PERIOD 500 + +/* + * Note that not all the register locations are accessible. + * A list of accessible target registers are specified with + * their start and end addresses in a table for given target + * version. We should NOT access other locations as either + * they are invalid locations or host does not have read + * access to it or the value of the particular register + * read might change + */ +#define REGISTER_LOCATION 0x00000800 + +#define DRAM_LOCATION 0x00400000 +#define DRAM_SIZE 0x000a8000 +#define DRAM_LOCAL_BASE_ADDRESS (0x100000) + +#define IRAM_LOCATION 0x00980000 +#define IRAM_SIZE 0x00038000 + +#define AXI_LOCATION 0x000a0000 +#define AXI_SIZE 0x00018000 + +#define CE_OFFSET 0x00000400 +#define CE_USEFUL_SIZE 0x00000058 + +#define TOTAL_DUMP_SIZE 0x00200000 +#define PCIE_READ_LIMIT 0x00005000 + +#define SHA256_DIGEST_SIZE 32 + +struct hash_fw { + u8 qwlan[SHA256_DIGEST_SIZE]; + u8 otp[SHA256_DIGEST_SIZE]; + u8 bdwlan[SHA256_DIGEST_SIZE]; + u8 utf[SHA256_DIGEST_SIZE]; +}; + +int ol_target_coredump(void *instance, void* memoryBlock, + u_int32_t blockLength); +int ol_diag_read(struct ol_softc *scn, u_int8_t* buffer, + u_int32_t pos, size_t count); +void ol_schedule_ramdump_work(struct ol_softc *scn); +void ol_schedule_fw_indication_work(struct ol_softc *scn); +int ol_copy_ramdump(struct ol_softc *scn); +int dump_CE_register(struct ol_softc *scn); +int ol_download_firmware(struct ol_softc *scn); +int ol_configure_target(struct ol_softc *scn); +void ol_target_failure(void *instance, A_STATUS status); +u_int8_t ol_get_number_of_peers_supported(struct ol_softc *scn); +#endif /* _OL_FW_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/_ieee80211_common.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/_ieee80211_common.h new file mode 100644 index 0000000000000..c52fb22517cd9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/_ieee80211_common.h @@ -0,0 +1,550 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _COMMON__IEEE80211_H_ +#define _COMMON__IEEE80211_H_ + +/* These defines should match the table from ah_internal.h */ +typedef enum { + DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */ + DFS_FCC_DOMAIN = 1, /* FCC3 dfs domain */ + DFS_ETSI_DOMAIN = 2, /* ETSI dfs domain */ + DFS_MKK4_DOMAIN = 3 /* Japan dfs domain */ +}HAL_DFS_DOMAIN; + +/* XXX not really a mode; there are really multiple PHY's */ +enum ieee80211_phymode { + IEEE80211_MODE_AUTO = 0, /* autoselect */ + IEEE80211_MODE_11A = 1, /* 5GHz, OFDM */ + IEEE80211_MODE_11B = 2, /* 2GHz, CCK */ + IEEE80211_MODE_11G = 3, /* 2GHz, OFDM */ + IEEE80211_MODE_FH = 4, /* 2GHz, GFSK */ + IEEE80211_MODE_TURBO_A = 5, /* 5GHz, OFDM, 2x clock dynamic turbo */ + IEEE80211_MODE_TURBO_G = 6, /* 2GHz, OFDM, 2x clock dynamic turbo */ + IEEE80211_MODE_11NA_HT20 = 7, /* 5Ghz, HT20 */ + IEEE80211_MODE_11NG_HT20 = 8, /* 2Ghz, HT20 */ + IEEE80211_MODE_11NA_HT40PLUS = 9, /* 5Ghz, HT40 (ext ch +1) */ + IEEE80211_MODE_11NA_HT40MINUS = 10, /* 5Ghz, HT40 (ext ch -1) */ + IEEE80211_MODE_11NG_HT40PLUS = 11, /* 2Ghz, HT40 (ext ch +1) */ + IEEE80211_MODE_11NG_HT40MINUS = 12, /* 2Ghz, HT40 (ext ch -1) */ + IEEE80211_MODE_11NG_HT40 = 13, /* 2Ghz, Auto HT40 */ + IEEE80211_MODE_11NA_HT40 = 14, /* 2Ghz, Auto HT40 */ + IEEE80211_MODE_11AC_VHT20 = 15, /* 5Ghz, VHT20 */ + IEEE80211_MODE_11AC_VHT40PLUS = 16, /* 5Ghz, VHT40 (Ext ch +1) */ + IEEE80211_MODE_11AC_VHT40MINUS = 17, /* 5Ghz VHT40 (Ext ch -1) */ + IEEE80211_MODE_11AC_VHT40 = 18, /* 5Ghz, VHT40 */ + IEEE80211_MODE_11AC_VHT80 = 19, /* 5Ghz, VHT80 */ + IEEE80211_MODE_2G_AUTO = 20, /* 2G 11 b/g/n autoselect */ + IEEE80211_MODE_5G_AUTO = 21, /* 5G 11 a/n/ac autoselect */ +}; +#define IEEE80211_MODE_MAX (IEEE80211_MODE_11AC_VHT80 + 1) + +enum ieee80211_opmode { + IEEE80211_M_STA = 1, /* infrastructure station */ + IEEE80211_M_IBSS = 0, /* IBSS (adhoc) station */ + IEEE80211_M_AHDEMO = 3, /* Old lucent compatible adhoc demo */ + IEEE80211_M_HOSTAP = 6, /* Software Access Point */ + IEEE80211_M_MONITOR = 8, /* Monitor mode */ + IEEE80211_M_WDS = 2, /* WDS link */ + IEEE80211_M_BTAMP = 9, /* VAP for BT AMP */ + + IEEE80211_M_P2P_GO = 33, /* P2P GO */ + IEEE80211_M_P2P_CLIENT = 34, /* P2P Client */ + IEEE80211_M_P2P_DEVICE = 35, /* P2P Device */ + + + IEEE80211_OPMODE_MAX = IEEE80211_M_BTAMP, /* Highest numbered opmode in the list */ + + IEEE80211_M_ANY = 0xFF /* Any of the above; used by NDIS 6.x */ +}; + +/* + * 802.11n + */ +#define IEEE80211_CWM_EXTCH_BUSY_THRESHOLD 30 + +enum ieee80211_cwm_mode { + IEEE80211_CWM_MODE20, + IEEE80211_CWM_MODE2040, + IEEE80211_CWM_MODE40, + IEEE80211_CWM_MODEMAX + +}; + +enum ieee80211_cwm_extprotspacing { + IEEE80211_CWM_EXTPROTSPACING20, + IEEE80211_CWM_EXTPROTSPACING25, + IEEE80211_CWM_EXTPROTSPACINGMAX +}; + +enum ieee80211_cwm_width { + IEEE80211_CWM_WIDTH20, + IEEE80211_CWM_WIDTH40, + IEEE80211_CWM_WIDTH80, + IEEE80211_CWM_WIDTHINVALID = 0xff /* user invalid value */ +}; + +enum ieee80211_cwm_extprotmode { + IEEE80211_CWM_EXTPROTNONE, /* no protection */ + IEEE80211_CWM_EXTPROTCTSONLY, /* CTS to self */ + IEEE80211_CWM_EXTPROTRTSCTS, /* RTS-CTS */ + IEEE80211_CWM_EXTPROTMAX +}; + +enum ieee80211_fixed_rate_mode { + IEEE80211_FIXED_RATE_NONE = 0, + IEEE80211_FIXED_RATE_MCS = 1, /* HT rates */ + IEEE80211_FIXED_RATE_LEGACY = 2, /* legacy rates */ + IEEE80211_FIXED_RATE_VHT = 3 /* VHT rates */ +}; + +/* Holds the fixed rate information for each VAP */ +struct ieee80211_fixed_rate { + enum ieee80211_fixed_rate_mode mode; + u_int32_t series; + u_int32_t retries; +}; + +/* + * 802.11g protection mode. + */ +enum ieee80211_protmode { + IEEE80211_PROT_NONE = 0, /* no protection */ + IEEE80211_PROT_CTSONLY = 1, /* CTS to self */ + IEEE80211_PROT_RTSCTS = 2, /* RTS-CTS */ +}; + +/* + * Roaming mode is effectively who controls the operation + * of the 802.11 state machine when operating as a station. + * State transitions are controlled either by the driver + * (typically when management frames are processed by the + * hardware/firmware), the host (auto/normal operation of + * the 802.11 layer), or explicitly through ioctl requests + * when applications like wpa_supplicant want control. + */ +enum ieee80211_roamingmode { + IEEE80211_ROAMING_DEVICE= 0, /* driver/hardware control */ + IEEE80211_ROAMING_AUTO = 1, /* 802.11 layer control */ + IEEE80211_ROAMING_MANUAL= 2, /* application control */ +}; + +/* + * Scanning mode controls station scanning work; this is + * used only when roaming mode permits the host to select + * the bss to join/channel to use. + */ +enum ieee80211_scanmode { + IEEE80211_SCAN_DEVICE = 0, /* driver/hardware control */ + IEEE80211_SCAN_BEST = 1, /* 802.11 layer selects best */ + IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ +}; + +#define IEEE80211_NWID_LEN 32 +#define IEEE80211_CHAN_MAX 255 +#define IEEE80211_CHAN_BYTES 32 /* howmany(IEEE80211_CHAN_MAX, NBBY) */ +#define IEEE80211_CHAN_ANY (-1) /* token for ``any channel'' */ +#define IEEE80211_CHAN_ANYC \ + ((struct ieee80211_channel *) IEEE80211_CHAN_ANY) + +#define IEEE80211_CHAN_DEFAULT 11 +#define IEEE80211_CHAN_DEFAULT_11A 52 +#define IEEE80211_CHAN_ADHOC_DEFAULT1 10 +#define IEEE80211_CHAN_ADHOC_DEFAULT2 11 + +#define IEEE80211_RADAR_11HCOUNT 5 +#define IEEE80211_RADAR_TEST_MUTE_CHAN_11A 36 /* Move to channel 36 for mute test */ +#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT20 36 +#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT40U 36 +#define IEEE80211_RADAR_TEST_MUTE_CHAN_11NHT40D 40 /* Move to channel 40 for HT40D mute test */ +#define IEEE80211_RADAR_DETECT_DEFAULT_DELAY 60000 /* STA ignore AP beacons during this period in millisecond */ + +#define IEEE80211_2GCSA_TBTTCOUNT 3 + +/* bits 0-3 are for private use by drivers */ +/* channel attributes */ +#define IEEE80211_CHAN_TURBO 0x00000010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x00000020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x00000040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x00000080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x00000100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x00000200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x00000400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x00000800 /* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_RADAR_DFS 0x00001000 /* Radar found on channel */ +#define IEEE80211_CHAN_STURBO 0x00002000 /* 11a static turbo channel only */ +#define IEEE80211_CHAN_HALF 0x00004000 /* Half rate channel */ +#define IEEE80211_CHAN_QUARTER 0x00008000 /* Quarter rate channel */ +#define IEEE80211_CHAN_HT20 0x00010000 /* HT 20 channel */ +#define IEEE80211_CHAN_HT40PLUS 0x00020000 /* HT 40 with extension channel above */ +#define IEEE80211_CHAN_HT40MINUS 0x00040000 /* HT 40 with extension channel below */ +#define IEEE80211_CHAN_HT40INTOL 0x00080000 /* HT 40 Intolerant */ +#define IEEE80211_CHAN_VHT20 0x00100000 /* VHT 20 channel */ +#define IEEE80211_CHAN_VHT40PLUS 0x00200000 /* VHT 40 with extension channel above */ +#define IEEE80211_CHAN_VHT40MINUS 0x00400000 /* VHT 40 with extension channel below */ +#define IEEE80211_CHAN_VHT80 0x00800000 /* VHT 80 channel */ + +/* flagext */ +#define IEEE80211_CHAN_RADAR_FOUND 0x01 +#define IEEE80211_CHAN_DFS 0x0002 /* DFS required on channel */ +#define IEEE80211_CHAN_DFS_CLEAR 0x0008 /* if channel has been checked for DFS */ +#define IEEE80211_CHAN_11D_EXCLUDED 0x0010 /* excluded in 11D */ +#define IEEE80211_CHAN_CSA_RECEIVED 0x0020 /* Channel Switch Announcement received on this channel */ +#define IEEE80211_CHAN_DISALLOW_ADHOC 0x0040 /* ad-hoc is not allowed */ +#define IEEE80211_CHAN_DISALLOW_HOSTAP 0x0080 /* Station only channel */ + +/* + * Useful combinations of channel characteristics. + */ +#define IEEE80211_CHAN_FHSS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_PUREG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) +#define IEEE80211_CHAN_108A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_108G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) +#define IEEE80211_CHAN_ST \ + (IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO) + +#define IEEE80211_IS_CHAN_11AC_2G(_c) \ + (IEEE80211_IS_CHAN_2GHZ((_c)) && IEEE80211_IS_CHAN_VHT((_c))) +#define IEEE80211_CHAN_11AC_VHT20_2G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT20) +#define IEEE80211_CHAN_11AC_VHT40_2G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS) +#define IEEE80211_CHAN_11AC_VHT80_2G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_VHT80) + +#define IEEE80211_IS_CHAN_11AC_VHT20_2G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT20_2G) == IEEE80211_CHAN_11AC_VHT20_2G) +#define IEEE80211_IS_CHAN_11AC_VHT40_2G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40_2G) != 0) +#define IEEE80211_IS_CHAN_11AC_VHT80_2G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80_2G) == IEEE80211_CHAN_11AC_VHT80_2G) + +#define IEEE80211_CHAN_11NG_HT20 \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT20) +#define IEEE80211_CHAN_11NA_HT20 \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT20) +#define IEEE80211_CHAN_11NG_HT40PLUS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT40PLUS) +#define IEEE80211_CHAN_11NG_HT40MINUS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_HT40MINUS) +#define IEEE80211_CHAN_11NA_HT40PLUS \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT40PLUS) +#define IEEE80211_CHAN_11NA_HT40MINUS \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT40MINUS) + +#define IEEE80211_CHAN_ALL \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \ + IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | \ + IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS | \ + IEEE80211_CHAN_VHT20 | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS | IEEE80211_CHAN_VHT80 | \ + IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER) +#define IEEE80211_CHAN_ALLTURBO \ + (IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO) + +#define IEEE80211_IS_CHAN_FHSS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) +#define IEEE80211_IS_CHAN_A(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) +#define IEEE80211_IS_CHAN_B(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) +#define IEEE80211_IS_CHAN_PUREG(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) +#define IEEE80211_IS_CHAN_G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) +#define IEEE80211_IS_CHAN_ANYG(_c) \ + (IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c)) +#define IEEE80211_IS_CHAN_ST(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST) +#define IEEE80211_IS_CHAN_108A(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_108A) == IEEE80211_CHAN_108A) +#define IEEE80211_IS_CHAN_108G(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G) + +#define IEEE80211_IS_CHAN_2GHZ(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_2GHZ) != 0) +#define IEEE80211_IS_CHAN_5GHZ(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_5GHZ) != 0) +#define IEEE80211_IS_CHAN_OFDM(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_OFDM) != 0) +#define IEEE80211_IS_CHAN_CCK(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_CCK) != 0) +#define IEEE80211_IS_CHAN_GFSK(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0) +#define IEEE80211_IS_CHAN_TURBO(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_TURBO) != 0) +#define IEEE80211_IS_CHAN_WEATHER_RADAR(_c) \ + ((((_c)->ic_freq >= 5600) && ((_c)->ic_freq <= 5650)) \ + || (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) && (5580 == (_c)->ic_freq))) +#define IEEE80211_IS_CHAN_STURBO(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_STURBO) != 0) +#define IEEE80211_IS_CHAN_DTURBO(_c) \ + (((_c)->ic_flags & \ + (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) == IEEE80211_CHAN_TURBO) +#define IEEE80211_IS_CHAN_HALF(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HALF) != 0) +#define IEEE80211_IS_CHAN_QUARTER(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_QUARTER) != 0) +#define IEEE80211_IS_CHAN_PASSIVE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_PASSIVE) != 0) + +#define IEEE80211_IS_CHAN_DFS(_c) \ + (((_c)->ic_flagext & (IEEE80211_CHAN_DFS|IEEE80211_CHAN_DFS_CLEAR)) == IEEE80211_CHAN_DFS) +#define IEEE80211_IS_CHAN_DFSFLAG(_c) \ + (((_c)->ic_flagext & IEEE80211_CHAN_DFS) == IEEE80211_CHAN_DFS) +#define IEEE80211_IS_CHAN_DISALLOW_ADHOC(_c) \ + (((_c)->ic_flagext & IEEE80211_CHAN_DISALLOW_ADHOC) != 0) +#define IEEE80211_IS_CHAN_11D_EXCLUDED(_c) \ + (((_c)->ic_flagext & IEEE80211_CHAN_11D_EXCLUDED) != 0) +#define IEEE80211_IS_CHAN_CSA(_c) \ + (((_c)->ic_flagext & IEEE80211_CHAN_CSA_RECEIVED) != 0) +#define IEEE80211_IS_CHAN_ODD(_c) \ + (((_c)->ic_freq == 5170) || ((_c)->ic_freq == 5190) || \ + ((_c)->ic_freq == 5210) || ((_c)->ic_freq == 5230)) +#define IEEE80211_IS_CHAN_DISALLOW_HOSTAP(_c) \ + (((_c)->ic_flagext & IEEE80211_CHAN_DISALLOW_HOSTAP) != 0) + +#define IEEE80211_IS_CHAN_11NG_HT20(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NG_HT20) == IEEE80211_CHAN_11NG_HT20) +#define IEEE80211_IS_CHAN_11NA_HT20(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NA_HT20) == IEEE80211_CHAN_11NA_HT20) +#define IEEE80211_IS_CHAN_11NG_HT40PLUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NG_HT40PLUS) == IEEE80211_CHAN_11NG_HT40PLUS) +#define IEEE80211_IS_CHAN_11NG_HT40MINUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NG_HT40MINUS) == IEEE80211_CHAN_11NG_HT40MINUS) +#define IEEE80211_IS_CHAN_11NA_HT40PLUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NA_HT40PLUS) == IEEE80211_CHAN_11NA_HT40PLUS) +#define IEEE80211_IS_CHAN_11NA_HT40MINUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11NA_HT40MINUS) == IEEE80211_CHAN_11NA_HT40MINUS) + +#define IEEE80211_IS_CHAN_11N(_c) \ + (((_c)->ic_flags & (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS)) != 0) +#define IEEE80211_IS_CHAN_11N_HT20(_c) \ + (((_c)->ic_flags & (IEEE80211_CHAN_HT20)) != 0) +#define IEEE80211_IS_CHAN_11N_HT40(_c) \ + (((_c)->ic_flags & (IEEE80211_CHAN_HT40PLUS | IEEE80211_CHAN_HT40MINUS)) != 0) +#define IEEE80211_IS_CHAN_11NG(_c) \ + (IEEE80211_IS_CHAN_2GHZ((_c)) && IEEE80211_IS_CHAN_11N((_c))) +#define IEEE80211_IS_CHAN_11NA(_c) \ + (IEEE80211_IS_CHAN_5GHZ((_c)) && IEEE80211_IS_CHAN_11N((_c))) +#define IEEE80211_IS_CHAN_11N_HT40PLUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) != 0) +#define IEEE80211_IS_CHAN_11N_HT40MINUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) != 0) + +#define IEEE80211_IS_CHAN_HT20_CAPABLE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT20) == IEEE80211_CHAN_HT20) +#define IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) == IEEE80211_CHAN_HT40PLUS) +#define IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) == IEEE80211_CHAN_HT40MINUS) +#define IEEE80211_IS_CHAN_HT40_CAPABLE(_c) \ + (IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(_c) || IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(_c)) +#define IEEE80211_IS_CHAN_HT_CAPABLE(_c) \ + (IEEE80211_IS_CHAN_HT20_CAPABLE(_c) || IEEE80211_IS_CHAN_HT40_CAPABLE(_c)) +#define IEEE80211_IS_CHAN_11N_CTL_CAPABLE(_c) IEEE80211_IS_CHAN_HT20_CAPABLE(_c) +#define IEEE80211_IS_CHAN_11N_CTL_U_CAPABLE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) == IEEE80211_CHAN_HT40PLUS) +#define IEEE80211_IS_CHAN_11N_CTL_L_CAPABLE(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) == IEEE80211_CHAN_HT40MINUS) +#define IEEE80211_IS_CHAN_11N_CTL_40_CAPABLE(_c) \ + (IEEE80211_IS_CHAN_11N_CTL_U_CAPABLE((_c)) || IEEE80211_IS_CHAN_11N_CTL_L_CAPABLE((_c))) + + +#define IEEE80211_IS_CHAN_VHT(_c) \ + (((_c)->ic_flags & (IEEE80211_CHAN_VHT20 | \ + IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS | IEEE80211_CHAN_VHT80)) != 0) +#define IEEE80211_IS_CHAN_11AC(_c) \ + ( IEEE80211_IS_CHAN_5GHZ((_c)) && IEEE80211_IS_CHAN_VHT((_c)) ) +#define IEEE80211_CHAN_11AC_VHT20 \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT20) +#define IEEE80211_CHAN_11AC_VHT40 \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS ) +#define IEEE80211_CHAN_11AC_VHT40PLUS \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40PLUS) +#define IEEE80211_CHAN_11AC_VHT40MINUS \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT40MINUS) +#define IEEE80211_CHAN_11AC_VHT80 \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT80) +#define IEEE80211_IS_CHAN_11AC_VHT20(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT20) == IEEE80211_CHAN_11AC_VHT20) + +#define IEEE80211_IS_CHAN_11AC_VHT40(_c) \ + (((_c)->ic_flags & (IEEE80211_CHAN_VHT40PLUS | IEEE80211_CHAN_VHT40MINUS)) !=0) +#define IEEE80211_IS_CHAN_11AC_VHT40PLUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40PLUS) == IEEE80211_CHAN_11AC_VHT40PLUS) +#define IEEE80211_IS_CHAN_11AC_VHT40MINUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT40MINUS) == IEEE80211_CHAN_11AC_VHT40MINUS) +#define IEEE80211_IS_CHAN_11AC_VHT80(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80) == IEEE80211_CHAN_11AC_VHT80) + +#define IEEE80211_IS_CHAN_RADAR(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_RADAR_DFS) == IEEE80211_CHAN_RADAR_DFS) +#define IEEE80211_CHAN_SET_RADAR(_c) \ + ((_c)->ic_flags |= IEEE80211_CHAN_RADAR_DFS) +#define IEEE80211_CHAN_CLR_RADAR(_c) \ + ((_c)->ic_flags &= ~IEEE80211_CHAN_RADAR_DFS) +#define IEEE80211_CHAN_SET_DISALLOW_ADHOC(_c) \ + ((_c)->ic_flagext |= IEEE80211_CHAN_DISALLOW_ADHOC) +#define IEEE80211_CHAN_SET_DISALLOW_HOSTAP(_c) \ + ((_c)->ic_flagext |= IEEE80211_CHAN_DISALLOW_HOSTAP) +#define IEEE80211_CHAN_SET_DFS(_c) \ + ((_c)->ic_flagext |= IEEE80211_CHAN_DFS) +#define IEEE80211_CHAN_SET_DFS_CLEAR(_c) \ + ((_c)->ic_flagext |= IEEE80211_CHAN_DFS_CLEAR) +#define IEEE80211_CHAN_EXCLUDE_11D(_c) \ + ((_c)->ic_flagext |= IEEE80211_CHAN_11D_EXCLUDED) + +/* channel encoding for FH phy */ +#define IEEE80211_FH_CHANMOD 80 +#define IEEE80211_FH_CHAN(set,pat) (((set)-1)*IEEE80211_FH_CHANMOD+(pat)) +#define IEEE80211_FH_CHANSET(chan) ((chan)/IEEE80211_FH_CHANMOD+1) +#define IEEE80211_FH_CHANPAT(chan) ((chan)%IEEE80211_FH_CHANMOD) + +/* + * 802.11 rate set. + */ +#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ +#define IEEE80211_RATE_MAXSIZE 36 /* max rates we'll handle */ +#define IEEE80211_HT_RATE_SIZE 128 +#define IEEE80211_RATE_SINGLE_STREAM_MCS_MAX 7 /* MCS7 */ + +#define IEEE80211_RATE_MCS 0x8000 +#define IEEE80211_RATE_MCS_VAL 0x7FFF + +#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8))) + +/* + * RSSI range + */ +#define IEEE80211_RSSI_MAX -10 /* in db */ +#define IEEE80211_RSSI_MIN -200 + +/* + * 11n A-MPDU & A-MSDU limits + */ +#define IEEE80211_AMPDU_LIMIT_MIN (1 * 1024) +#define IEEE80211_AMPDU_LIMIT_MAX (64 * 1024 - 1) +#define IEEE80211_AMPDU_LIMIT_DEFAULT IEEE80211_AMPDU_LIMIT_MAX +#define IEEE80211_AMPDU_SUBFRAME_MIN 2 +#define IEEE80211_AMPDU_SUBFRAME_MAX 64 +#define IEEE80211_AMPDU_SUBFRAME_DEFAULT 32 +#define IEEE80211_AMSDU_LIMIT_MAX 4096 +#define IEEE80211_RIFS_AGGR_DIV 10 +#define IEEE80211_MAX_AMPDU_MIN 0 +#define IEEE80211_MAX_AMPDU_MAX 3 + +/* + * 11ac A-MPDU limits + */ +#define IEEE80211_VHT_MAX_AMPDU_MIN 0 +#define IEEE80211_VHT_MAX_AMPDU_MAX 7 + + + +struct ieee80211_rateset { + u_int8_t rs_nrates; + u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE]; +}; + +struct ieee80211_beacon_info{ + u_int8_t essid[IEEE80211_NWID_LEN+1]; + u_int8_t esslen; + u_int8_t rssi_ctl_0; + u_int8_t rssi_ctl_1; + u_int8_t rssi_ctl_2; + int numchains; +}; + +struct ieee80211_ibss_peer_list{ + u_int8_t bssid[6]; +}; + +struct ieee80211_roam { + int8_t rssi11a; /* rssi thresh for 11a bss */ + int8_t rssi11b; /* for 11g sta in 11b bss */ + int8_t rssi11bOnly; /* for 11b sta */ + u_int8_t pad1; + u_int8_t rate11a; /* rate thresh for 11a bss */ + u_int8_t rate11b; /* for 11g sta in 11b bss */ + u_int8_t rate11bOnly; /* for 11b sta */ + u_int8_t pad2; +}; + +#define IEEE80211_TID_SIZE 17 /* total number of TIDs */ +#define IEEE80211_NON_QOS_SEQ 16 /* index for non-QoS (including management) sequence number space */ +#define IEEE80211_SEQ_MASK 0xfff /* sequence generator mask*/ +#define MIN_SW_SEQ 0x100 /* minimum sequence for SW generate packect*/ + +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ + +/* crypto related defines*/ +#define IEEE80211_KEYBUF_SIZE 16 +#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ + +enum ieee80211_clist_cmd { + CLIST_UPDATE, + CLIST_DFS_UPDATE, + CLIST_NEW_COUNTRY, + CLIST_NOL_UPDATE +}; + +enum ieee80211_nawds_param { + IEEE80211_NAWDS_PARAM_NUM = 0, + IEEE80211_NAWDS_PARAM_MODE, + IEEE80211_NAWDS_PARAM_DEFCAPS, + IEEE80211_NAWDS_PARAM_OVERRIDE, +}; + +struct ieee80211_mib_cycle_cnts { + u_int32_t tx_frame_count; + u_int32_t rx_frame_count; + u_int32_t rx_clear_count; + u_int32_t cycle_count; + u_int8_t is_rx_active; + u_int8_t is_tx_active; +}; + +struct ieee80211_chanutil_info { + u_int32_t rx_clear_count; + u_int32_t cycle_count; + u_int8_t value; + u_int32_t beacon_count; + u_int8_t beacon_intervals; +}; + +#endif /* _COMMON__IEEE80211_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_debug.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_debug.h new file mode 100644 index 0000000000000..7ef6e2b43afb7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_debug.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _A_DEBUG_H_ +#define _A_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "osapi_linux.h" + + /* standard debug print masks bits 0..7 */ +#define ATH_DEBUG_ERR (1 << 0) /* errors */ +#define ATH_DEBUG_WARN (1 << 1) /* warnings */ +#define ATH_DEBUG_INFO (1 << 2) /* informational (module startup info) */ +#define ATH_DEBUG_TRC (1 << 3) /* generic function call tracing */ +#define ATH_DEBUG_RSVD1 (1 << 4) +#define ATH_DEBUG_RSVD2 (1 << 5) +#define ATH_DEBUG_RSVD3 (1 << 6) +#define ATH_DEBUG_RSVD4 (1 << 7) + +#define ATH_DEBUG_MASK_DEFAULTS (ATH_DEBUG_ERR | ATH_DEBUG_WARN) +#define ATH_DEBUG_ANY 0xFFFF + + /* other aliases used throughout */ +#define ATH_DEBUG_ERROR ATH_DEBUG_ERR +#define ATH_LOG_ERR ATH_DEBUG_ERR +#define ATH_LOG_INF ATH_DEBUG_INFO +#define ATH_LOG_TRC ATH_DEBUG_TRC +#define ATH_DEBUG_TRACE ATH_DEBUG_TRC +#define ATH_DEBUG_INIT ATH_DEBUG_INFO + + /* bits 8..31 are module-specific masks */ +#define ATH_DEBUG_MODULE_MASK_SHIFT 8 + + /* macro to make a module-specific masks */ +#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index))) + +void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); + +/* Debug support on a per-module basis + * + * Usage: + * + * Each module can utilize it's own debug mask variable. A set of commonly used + * masks are provided (ERRORS, WARNINGS, TRACE etc..). It is up to each module + * to define module-specific masks using the macros above. + * + * Each module defines a single debug mask variable debug_XXX where the "name" of the module is + * common to all C-files within that module. This requires every C-file that includes a_debug.h + * to define the module name in that file. + * + * Example: + * + * #define ATH_MODULE_NAME htc + * #include "a_debug.h" + * + * This will define a debug mask structure called debug_htc and all debug macros will reference this + * variable. + * + * A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro: + * + * #define ATH_DEBUG_MY_MASK1 ATH_DEBUG_MAKE_MODULE_MASK(0) + * #define ATH_DEBUG_MY_MASK2 ATH_DEBUG_MAKE_MODULE_MASK(1) + * + * The instantiation of the debug structure should be made by the module. When a module is + * instantiated, the module can set a description string, a default mask and an array of description + * entries containing information on each module-defined debug mask. + * NOTE: The instantiation is statically allocated, only one instance can exist per module. + * + * Example: + * + * + * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) + * + * #ifdef DEBUG + * static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = { + * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask + * }; + * + * ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi, + * "bmi" <== module name + * "Boot Manager Interface", <== description of module + * ATH_DEBUG_MASK_DEFAULTS, <== defaults + * ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc), + * bmi_debug_desc); + * + * #endif + * + * A module can optionally register it's debug module information in order for other tools to change the + * bit mask at runtime. A module can call A_REGISTER_MODULE_DEBUG_INFO() in it's module + * init code. This macro can be called multiple times without consequence. The debug info maintains + * state to indicate whether the information was previously registered. + * + * */ + +#define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32 +#define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64 + +typedef struct { + A_UINT32 Mask; + A_CHAR Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; +} ATH_DEBUG_MASK_DESCRIPTION; + +#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0) + +typedef struct _ATH_DEBUG_MODULE_DBG_INFO{ + struct _ATH_DEBUG_MODULE_DBG_INFO *pNext; + A_CHAR ModuleName[16]; + A_CHAR ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH]; + A_UINT32 Flags; + A_UINT32 CurrentMask; + int MaxDescriptions; + ATH_DEBUG_MASK_DESCRIPTION *pMaskDescriptions; /* pointer to array of descriptions */ +} ATH_DEBUG_MODULE_DBG_INFO; + +#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(ATH_DEBUG_MASK_DESCRIPTION))) + +#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s) +#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask +#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s + +#ifdef DEBUG + + /* for source files that will instantiate the debug variables */ +#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \ +ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \ + {NULL,(name),(moddesc),0,(initmask),count,(descriptions)} + +#ifdef ATH_MODULE_NAME +extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME); +#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl)) +#endif /* ATH_MODULE_NAME */ + +#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl) + +#define ATH_DEBUG_DECLARE_EXTERN(s) \ + extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) + +#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc) + + +#define AR_DEBUG_ASSERT A_ASSERT + +void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); +void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); +#ifdef A_SIMOS_DEVHOST +#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s))) +#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s))) +#else +#define A_DUMP_MODULE_DEBUG_INFO(s) +#define A_REGISTER_MODULE_DEBUG_INFO(s) +#endif + +#else /* !DEBUG */ + /* NON DEBUG */ +#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) +#define AR_DEBUG_LVL_CHECK(lvl) 0 +#define AR_DEBUG_PRINTBUF(buffer, length, desc) +#define AR_DEBUG_ASSERT(test) +#define ATH_DEBUG_DECLARE_EXTERN(s) +#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) +#define A_DUMP_MODULE_DEBUG_INFO(s) +#define A_REGISTER_MODULE_DEBUG_INFO(s) + +#endif + +A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask); +A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask); +void a_dump_module_debug_info_by_name(A_CHAR *module_name); +void a_module_debug_support_init(void); +void a_module_debug_support_cleanup(void); + +#if defined(__linux__) && !defined(LINUX_EMULATION) +#include "debug_linux.h" +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_osapi.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_osapi.h new file mode 100644 index 0000000000000..a8c9c2b0e946e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_osapi.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//============================================================================== +// This file contains the definitions of the basic atheros data types. +// It is used to map the data types in atheros files to a platform specific +// type. +// +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_OSAPI_H_ +#define _A_OSAPI_H_ + +#if defined(__linux__) && !defined(LINUX_EMULATION) +#include "osapi_linux.h" +#endif + +/*=== the following primitives have the same definition for all platforms ===*/ + +#define A_COMPILE_TIME_ASSERT(assertion_name, predicate) \ + typedef char assertion_name[(predicate) ? 1 : -1] + +/* + * If N is a power of 2, then N and N-1 are orthogonal + * (N-1 has all the least-significant bits set which are zero in N) + * so N ^ (N-1) = (N << 1) - 1 + */ +#define A_COMPILE_TIME_ASSERT_IS_PWR2(assertion_name, value) \ + A_COMPILE_TIME_ASSERT(assertion_name, \ + (((value) ^ ((value)-1)) == ((value) << 1) - 1)) + +#ifndef __ubicom32__ +#define HIF_MALLOC_DIAGMEM(osdev, size, pa, context, retry) \ + OS_MALLOC_CONSISTENT(osdev, size, pa, context, retry) +#define HIF_FREE_DIAGMEM(osdev, size, vaddr, pa, context) \ + OS_FREE_CONSISTENT(osdev, size, vaddr, pa, context) +#define HIF_DIAGMEM_SYNC(osdev, pa, size, dir, context) +#else +#define HIF_MALLOC_DIAGMEM(osdev, size, pa, context, retry) \ + OS_MALLOC_NONCONSISTENT(osdev, size, pa, context, retry) +#define HIF_FREE_DIAGMEM(osdev, size, vaddr, pa, context) \ + OS_FREE_NONCONSISTENT(osdev, size, vaddr, pa, context) +#define HIF_DIAGMEM_SYNC(osdev, pa, size, dir, context) \ + OS_SYNC_SINGLE(osdev, pa, size, dir, context) +#endif /* ubicom32 */ + +#endif /* _OSAPI_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_types.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_types.h new file mode 100644 index 0000000000000..768a7a80c2e7d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_types.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//depot/sw/qca_main/perf_pwr_offload/drivers/host/include/a_types.h#7 - integrate change 1327637 (ktext) +//============================================================================== +// This file contains the definitions of the basic atheros data types. +// It is used to map the data types in atheros files to a platform specific +// type. +// +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _A_TYPES_H_ +#define _A_TYPES_H_ +#include + +typedef unsigned int A_UINT32; +typedef unsigned long long A_UINT64; +typedef unsigned short A_UINT16; +typedef unsigned char A_UINT8; +typedef int A_INT32; +typedef short A_INT16; +typedef char A_INT8; +typedef unsigned char A_UCHAR; +typedef char A_CHAR; +typedef _Bool A_BOOL; + +#endif /* _ATHTYPES_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_usb_defs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_usb_defs.h new file mode 100644 index 0000000000000..5208f42735787 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/a_usb_defs.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* +* This file was originally distributed by Qualcomm Atheros, Inc. +* under proprietary terms before Copyright ownership was assigned +* to the Linux Foundation. +*/ +/* + * Shared USB definitions + * + * + * + * + */ + +#ifndef __A_USB_DEFS_H__ +#define __A_USB_DEFS_H__ + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif + +/* USB endpoint definitions */ + +#define USB_EP_ADDR_APP_CTRL_IN 0x81 +#define USB_EP_ADDR_APP_DATA_IN 0x82 +#define USB_EP_ADDR_APP_DATA2_IN 0x83 +#define USB_EP_ADDR_APP_INT_IN 0x84 + + + +#define USB_EP_ADDR_APP_CTRL_OUT 0x01 +#define USB_EP_ADDR_APP_DATA_LP_OUT 0x02 +#define USB_EP_ADDR_APP_DATA_MP_OUT 0x03 +#define USB_EP_ADDR_APP_DATA_HP_OUT 0x04 + +#define USB_CONTROL_REQ_SEND_BMI_CMD 1 +#define USB_CONTROL_REQ_RECV_BMI_RESP 2 +#define USB_CONTROL_REQ_DIAG_CMD 3 +#define USB_CONTROL_REQ_DIAG_RESP 4 + + +/* #define USB_CONTROL_MAX_BMI_TRANSFER_SIZE 64 */ +#define USB_CONTROL_MAX_BMI_TRANSFER_SIZE 252 + +#define HIF_BMI_MAX_TRANSFER_SIZE USB_CONTROL_MAX_BMI_TRANSFER_SIZE + +/* 512 Bytes Maxp for High Speed for BULK EP */ +#define USB_HS_BULK_MAXP_SIZE 0x200 +/* 64 Bytes Maxp for Full Speed for BULK EP */ +#define USB_FS_BULK_MAXP_SIZE 0x40 + + + +/* diagnostic command defnitions */ +#define USB_CTRL_DIAG_CC_READ 0 +#define USB_CTRL_DIAG_CC_WRITE 1 +#define USB_CTRL_DIAG_CC_WARM_RESET 2 + +typedef PREPACK struct { + A_UINT32 Cmd; + A_UINT32 Address; + A_UINT32 Value; + A_UINT32 _pad[1]; +} POSTPACK USB_CTRL_DIAG_CMD_WRITE; + +typedef PREPACK struct { + A_UINT32 Cmd; + A_UINT32 Address; +} POSTPACK USB_CTRL_DIAG_CMD_READ; + +typedef PREPACK struct { + A_UINT32 ReadValue; +} POSTPACK USB_CTRL_DIAG_RESP_READ; + +#define USB_CTRL_MAX_DIAG_CMD_SIZE (sizeof(USB_CTRL_DIAG_CMD_WRITE)) +#define USB_CTRL_MAX_DIAG_RESP_SIZE (sizeof(USB_CTRL_DIAG_RESP_READ)) + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/a_base_types.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/a_base_types.h new file mode 100644 index 0000000000000..ac80788b700f5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/a_base_types.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef __A_BASE_TYPES_H +#define __A_BASE_TYPES_H + + + +/** + * @brief The basic data types + */ +typedef __a_uint8_t a_uint8_t; /**< 1 Byte */ +typedef __a_uint16_t a_uint16_t;/**< 2 Bytes */ +typedef __a_uint32_t a_uint32_t;/**< 4 Bytes */ +typedef __a_uint64_t a_uint64_t;/**< 4 Bytes */ + +typedef __a_int8_t a_int8_t; /**< 1 Byte */ +typedef __a_int16_t a_int16_t;/**< 2 Bytes */ +typedef __a_int32_t a_int32_t;/**< 4 Bytes */ +typedef __a_int64_t a_int64_t;/**< 4 Bytes */ + +enum a_bool { + A_FALSE = 0, + A_TRUE = 1 +}; +typedef a_uint8_t a_bool_t;/**< 1 Byte */ + + +/** + * @brief Generic status for the API's + */ +enum { + A_STATUS_OK = 0, + A_STATUS_FAILED, + A_STATUS_ENOENT, + A_STATUS_ENOMEM, + A_STATUS_EINVAL, + A_STATUS_EINPROGRESS, + A_STATUS_ENOTSUPP, + A_STATUS_EBUSY, + A_STATUS_E2BIG, + A_STATUS_ENOSPC, + A_STATUS_EADDRNOTAVAIL, + A_STATUS_ENXIO, + A_STATUS_ENETDOWN, + A_STATUS_EFAULT, + A_STATUS_EIO, + A_STATUS_ENETRESET, + A_STATUS_EEXIST, + A_STATUS_SIG /* Exit due to received SIGINT */ +}; +typedef a_uint32_t a_status_t; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.c new file mode 100644 index 0000000000000..7dcbbbc200f6f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include +#include +#include +#include +#include +#include + +adf_nbuf_trace_update_t trace_update_cb = NULL; + +/* + * @brief This allocates an nbuf aligns if needed and reserves + * some space in the front, since the reserve is done + * after alignment the reserve value if being unaligned + * will result in an unaligned address. + * + * @param hdl + * @param size + * @param reserve + * @param align + * + * @return nbuf or NULL if no memory + */ +struct sk_buff * +__adf_nbuf_alloc(adf_os_device_t osdev, size_t size, int reserve, int align, int prio) +{ + struct sk_buff *skb; + unsigned long offset; + + if(align) + size += (align - 1); + + skb = dev_alloc_skb(size); + + if (!skb) { + printk("ERROR:NBUF alloc failed\n"); + return NULL; + } + memset(skb->cb, 0x0, sizeof(skb->cb)); + + /* + * The default is for netbuf fragments to be interpreted + * as wordstreams rather than bytestreams. + * Set the CVG_NBUF_MAX_EXTRA_FRAGS+1 wordstream_flags bits, + * to provide this default. + */ + NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) = + (1 << (CVG_NBUF_MAX_EXTRA_FRAGS + 1)) - 1; + + /** + * XXX:how about we reserve first then align + */ + + /** + * Align & make sure that the tail & data are adjusted properly + */ + if(align){ + offset = ((unsigned long) skb->data) % align; + if(offset) + skb_reserve(skb, align - offset); + } + + /** + * NOTE:alloc doesn't take responsibility if reserve unaligns the data + * pointer + */ + skb_reserve(skb, reserve); + + return skb; +} + +/* + * @brief free the nbuf its interrupt safe + * @param skb + */ +void +__adf_nbuf_free(struct sk_buff *skb) +{ +#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD) + if( (NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID) && NBUF_CALLBACK_FN(skb) ) + NBUF_CALLBACK_FN_EXEC(skb); + else +#endif + dev_kfree_skb_any(skb); +} + + +/* + * @brief Reference the nbuf so it can get held until the last free. + * @param skb + */ + +void +__adf_nbuf_ref(struct sk_buff *skb) +{ + skb_get(skb); +} + +/** + * @brief Check whether the buffer is shared + * @param skb: buffer to check + * + * Returns true if more than one person has a reference to this + * buffer. + */ +int +__adf_nbuf_shared(struct sk_buff *skb) +{ + return skb_shared(skb); +} +/** + * @brief create a nbuf map + * @param osdev + * @param dmap + * + * @return a_status_t + */ +a_status_t +__adf_nbuf_dmamap_create(adf_os_device_t osdev, __adf_os_dma_map_t *dmap) +{ + a_status_t error = A_STATUS_OK; + /** + * XXX: driver can tell its SG capablity, it must be handled. + * XXX: Bounce buffers if they are there + */ + (*dmap) = kzalloc(sizeof(struct __adf_os_dma_map), GFP_KERNEL); + if(!(*dmap)) + error = A_STATUS_ENOMEM; + + return error; +} + +/** + * @brief free the nbuf map + * + * @param osdev + * @param dmap + */ +void +__adf_nbuf_dmamap_destroy(adf_os_device_t osdev, __adf_os_dma_map_t dmap) +{ + kfree(dmap); +} + +/** + * @brief get the dma map of the nbuf + * + * @param osdev + * @param bmap + * @param skb + * @param dir + * + * @return a_status_t + */ +a_status_t +__adf_nbuf_map( + adf_os_device_t osdev, + struct sk_buff *skb, + adf_os_dma_dir_t dir) +{ +#ifdef ADF_OS_DEBUG + struct skb_shared_info *sh = skb_shinfo(skb); +#endif + adf_os_assert( + (dir == ADF_OS_DMA_TO_DEVICE) || (dir == ADF_OS_DMA_FROM_DEVICE)); + + /* + * Assume there's only a single fragment. + * To support multiple fragments, it would be necessary to change + * adf_nbuf_t to be a separate object that stores meta-info + * (including the bus address for each fragment) and a pointer + * to the underlying sk_buff. + */ + adf_os_assert(sh->nr_frags == 0); + + return __adf_nbuf_map_single(osdev, skb, dir); + + return A_STATUS_OK; +} + +/** + * @brief adf_nbuf_unmap() - to unmap a previously mapped buf + */ +void +__adf_nbuf_unmap( + adf_os_device_t osdev, + struct sk_buff *skb, + adf_os_dma_dir_t dir) +{ + adf_os_assert( + (dir == ADF_OS_DMA_TO_DEVICE) || (dir == ADF_OS_DMA_FROM_DEVICE)); + + adf_os_assert(((dir == ADF_OS_DMA_TO_DEVICE) || (dir == ADF_OS_DMA_FROM_DEVICE))); + /* + * Assume there's a single fragment. + * If this is not true, the assertion in __adf_nbuf_map will catch it. + */ + __adf_nbuf_unmap_single(osdev, skb, dir); +} + +a_status_t +__adf_nbuf_map_single( + adf_os_device_t osdev, adf_nbuf_t buf, adf_os_dma_dir_t dir) +{ + u_int32_t paddr_lo; + +/* tempory hack for simulation */ +#ifdef A_SIMOS_DEVHOST + NBUF_MAPPED_PADDR_LO(buf) = paddr_lo = (u_int32_t) buf->data; + return A_STATUS_OK; +#else + /* assume that the OS only provides a single fragment */ + NBUF_MAPPED_PADDR_LO(buf) = paddr_lo = + dma_map_single(osdev->dev, buf->data, + skb_end_pointer(buf) - buf->data, dir); + return dma_mapping_error(osdev->dev, paddr_lo) ? + A_STATUS_FAILED : A_STATUS_OK; +#endif /* #ifdef A_SIMOS_DEVHOST */ +} + +void +__adf_nbuf_unmap_single( + adf_os_device_t osdev, adf_nbuf_t buf, adf_os_dma_dir_t dir) +{ +#if !defined(A_SIMOS_DEVHOST) + dma_unmap_single(osdev->dev, NBUF_MAPPED_PADDR_LO(buf), + skb_end_pointer(buf) - buf->data, dir); +#endif /* #if !defined(A_SIMOS_DEVHOST) */ +} + +/** + * @brief return the dma map info + * + * @param[in] bmap + * @param[out] sg (map_info ptr) + */ +void +__adf_nbuf_dmamap_info(__adf_os_dma_map_t bmap, adf_os_dmamap_info_t *sg) +{ + adf_os_assert(bmap->mapped); + adf_os_assert(bmap->nsegs <= ADF_OS_MAX_SCATTER); + + memcpy(sg->dma_segs, bmap->seg, bmap->nsegs * + sizeof(struct __adf_os_segment)); + sg->nsegs = bmap->nsegs; +} +/** + * @brief return the frag data & len, where frag no. is + * specified by the index + * + * @param[in] buf + * @param[out] sg (scatter/gather list of all the frags) + * + */ +void +__adf_nbuf_frag_info(struct sk_buff *skb, adf_os_sglist_t *sg) +{ +#if defined(ADF_OS_DEBUG) || defined(__ADF_SUPPORT_FRAG_MEM) + struct skb_shared_info *sh = skb_shinfo(skb); +#endif + adf_os_assert(skb != NULL); + sg->sg_segs[0].vaddr = skb->data; + sg->sg_segs[0].len = skb->len; + sg->nsegs = 1; + +#ifndef __ADF_SUPPORT_FRAG_MEM + adf_os_assert(sh->nr_frags == 0); +#else + for(int i = 1; i <= sh->nr_frags; i++){ + skb_frag_t *f = &sh->frags[i - 1]; + sg->sg_segs[i].vaddr = (uint8_t *)(page_address(f->page) + + f->page_offset); + sg->sg_segs[i].len = f->size; + + adf_os_assert(i < ADF_OS_MAX_SGLIST); + } + sg->nsegs += i; +#endif +} + +a_status_t +__adf_nbuf_set_rx_cksum(struct sk_buff *skb, adf_nbuf_rx_cksum_t *cksum) +{ + switch (cksum->l4_result) { + case ADF_NBUF_RX_CKSUM_NONE: + skb->ip_summed = CHECKSUM_NONE; + break; + case ADF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY: + skb->ip_summed = CHECKSUM_UNNECESSARY; + break; + case ADF_NBUF_RX_CKSUM_TCP_UDP_HW: + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = cksum->val; + break; + default: + printk("ADF_NET:Unknown checksum type\n"); + adf_os_assert(0); + return A_STATUS_ENOTSUPP; + } + return A_STATUS_OK; +} + +adf_nbuf_tx_cksum_t +__adf_nbuf_get_tx_cksum(struct sk_buff *skb) +{ + switch (skb->ip_summed) { + case CHECKSUM_NONE: + return ADF_NBUF_TX_CKSUM_NONE; + case CHECKSUM_PARTIAL: + /* XXX ADF and Linux checksum don't map with 1-to-1. This is not 100% + * correct. */ + return ADF_NBUF_TX_CKSUM_TCP_UDP; + case CHECKSUM_COMPLETE: + return ADF_NBUF_TX_CKSUM_TCP_UDP_IP; + default: + return ADF_NBUF_TX_CKSUM_NONE; + } +} + +a_status_t +__adf_nbuf_get_vlan_info(adf_net_handle_t hdl, struct sk_buff *skb, + adf_net_vlanhdr_t *vlan) +{ + return A_STATUS_OK; +} + +a_uint8_t +__adf_nbuf_get_tid(struct sk_buff *skb) +{ + return skb->priority; +} + +void +__adf_nbuf_set_tid(struct sk_buff *skb, a_uint8_t tid) +{ + skb->priority = tid; +} + +a_uint8_t +__adf_nbuf_get_exemption_type(struct sk_buff *skb) +{ + return ADF_NBUF_EXEMPT_NO_EXEMPTION; +} + +void +__adf_nbuf_dmamap_set_cb(__adf_os_dma_map_t dmap, void *cb, void *arg) +{ + return; +} + +void +__adf_nbuf_reg_trace_cb(adf_nbuf_trace_update_t cb_func_ptr) +{ + trace_update_cb = cb_func_ptr; + return; +} + +#ifdef QCA_PKT_PROTO_TRACE +void +__adf_nbuf_trace_update(struct sk_buff *buf, char *event_string) +{ + char string_buf[NBUF_PKT_TRAC_MAX_STRING]; + + if ((!trace_update_cb) || (!event_string)) { + return; + } + + if (!adf_nbuf_trace_get_proto_type(buf)) { + return; + } + + /* Buffer over flow */ + if (NBUF_PKT_TRAC_MAX_STRING <= + (adf_os_str_len(event_string) + NBUF_PKT_TRAC_PROTO_STRING)) { + return; + } + + adf_os_mem_zero(string_buf, + NBUF_PKT_TRAC_MAX_STRING); + adf_os_mem_copy(string_buf, + event_string, adf_os_str_len(event_string)); + if (NBUF_PKT_TRAC_TYPE_EAPOL & + adf_nbuf_trace_get_proto_type(buf)) { + adf_os_mem_copy(string_buf + adf_os_str_len(event_string), + "EPL", + NBUF_PKT_TRAC_PROTO_STRING); + } + else if (NBUF_PKT_TRAC_TYPE_DHCP & + adf_nbuf_trace_get_proto_type(buf)) { + adf_os_mem_copy(string_buf + adf_os_str_len(event_string), + "DHC", + NBUF_PKT_TRAC_PROTO_STRING); + } else if (NBUF_PKT_TRAC_TYPE_MGMT_ACTION & + adf_nbuf_trace_get_proto_type(buf)) { + adf_os_mem_copy(string_buf + adf_os_str_len(event_string), + "MACT", + NBUF_PKT_TRAC_PROTO_STRING); + } + + trace_update_cb(string_buf); + return; +} +#endif /* QCA_PKT_PROTO_TRACE */ + +EXPORT_SYMBOL(__adf_nbuf_alloc); +EXPORT_SYMBOL(__adf_nbuf_free); +EXPORT_SYMBOL(__adf_nbuf_ref); +EXPORT_SYMBOL(__adf_nbuf_shared); +EXPORT_SYMBOL(__adf_nbuf_frag_info); +EXPORT_SYMBOL(__adf_nbuf_dmamap_create); +EXPORT_SYMBOL(__adf_nbuf_dmamap_destroy); +EXPORT_SYMBOL(__adf_nbuf_map); +EXPORT_SYMBOL(__adf_nbuf_unmap); +EXPORT_SYMBOL(__adf_nbuf_map_single); +EXPORT_SYMBOL(__adf_nbuf_unmap_single); +EXPORT_SYMBOL(__adf_nbuf_dmamap_info); +EXPORT_SYMBOL(__adf_nbuf_set_rx_cksum); +EXPORT_SYMBOL(__adf_nbuf_get_tx_cksum); +EXPORT_SYMBOL(__adf_nbuf_get_vlan_info); +EXPORT_SYMBOL(__adf_nbuf_get_tid); +EXPORT_SYMBOL(__adf_nbuf_set_tid); +EXPORT_SYMBOL(__adf_nbuf_get_exemption_type); +EXPORT_SYMBOL(__adf_nbuf_dmamap_set_cb); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.h new file mode 100644 index 0000000000000..abec0928b53db --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_nbuf.h @@ -0,0 +1,1136 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @defgroup adf_nbuf_public network buffer API + */ + +/** + * @ingroup adf_nbuf_public + * @file adf_nbuf.h + * This file defines the network buffer abstraction. + */ + +#ifndef _ADF_NBUF_H +#define _ADF_NBUF_H +#include +#include +#include +#include +#include + +#ifdef IPA_OFFLOAD +#define IPA_NBUF_OWNER_ID 0xaa55aa55 +#endif + +#define NBUF_PKT_TRAC_TYPE_EAPOL 0x02 +#define NBUF_PKT_TRAC_TYPE_DHCP 0x04 +#define NBUF_PKT_TRAC_TYPE_MGMT_ACTION 0x08 +#define NBUF_PKT_TRAC_MAX_STRING 12 +#define NBUF_PKT_TRAC_PROTO_STRING 4 + +/** + * @brief Platform indepedent packet abstraction + */ +typedef __adf_nbuf_t adf_nbuf_t; + +/** + * @brief Dma map callback prototype + */ +typedef void (*adf_os_dma_map_cb_t)(void *arg, adf_nbuf_t buf, + adf_os_dma_map_t dmap); + +/** + * @brief invalid handle + */ +#define ADF_NBUF_NULL __ADF_NBUF_NULL +/** + * @brief Platform independent packet queue abstraction + */ +typedef __adf_nbuf_queue_t adf_nbuf_queue_t; + +/** + * BUS/DMA mapping routines + */ + +/** + * @brief Create a DMA map. This can later be used to map + * networking buffers. They : + * - need space in adf_drv's software descriptor + * - are typically created during adf_drv_create + * - need to be created before any API(adf_nbuf_map) that uses them + * + * @param[in] osdev os device + * @param[out] dmap map handle + * + * @return status of the operation + */ +static inline a_status_t +adf_nbuf_dmamap_create(adf_os_device_t osdev, + adf_os_dma_map_t *dmap) +{ + return (__adf_nbuf_dmamap_create(osdev, dmap)); +} + + +/** + * @brief Delete a dmap map + * + * @param[in] osdev os device + * @param[in] dmap + */ +static inline void +adf_nbuf_dmamap_destroy(adf_os_device_t osdev, adf_os_dma_map_t dmap) +{ + __adf_nbuf_dmamap_destroy(osdev, dmap); +} + +/** + * @brief Setup the map callback for a dma map + * + * @param[in] map DMA map + * @param[in] cb callback function + * @param[in] arg context for callback function + */ +static inline void +adf_nbuf_dmamap_set_cb(adf_os_dma_map_t dmap, adf_os_dma_map_cb_t cb, + void *arg) +{ + __adf_nbuf_dmamap_set_cb(dmap, cb, arg); +} + +/** + * @brief Map a buffer to local bus address space + * + * @param[in] osdev os device + * @param[in] buf buf to be mapped + * (mapping info is stored in the buf's meta-data area) + * @param[in] dir DMA direction + * + * @return status of the operation + */ +static inline a_status_t +adf_nbuf_map(adf_os_device_t osdev, + adf_nbuf_t buf, + adf_os_dma_dir_t dir) +{ +#if defined(HIF_PCI) + return __adf_nbuf_map(osdev, buf, dir); +#else + return 0; +#endif +} + + +/** + * @brief Unmap a previously mapped buf + * + * @param[in] osdev os device + * @param[in] buf buf to be unmapped + * (mapping info is stored in the buf's meta-data area) + * @param[in] dir DMA direction + */ +static inline void +adf_nbuf_unmap(adf_os_device_t osdev, + adf_nbuf_t buf, + adf_os_dma_dir_t dir) +{ +#if defined(HIF_PCI) + __adf_nbuf_unmap(osdev, buf, dir); +#endif +} + +static inline a_status_t +adf_nbuf_map_single( + adf_os_device_t osdev, adf_nbuf_t buf, adf_os_dma_dir_t dir) +{ +#if defined(HIF_PCI) + return __adf_nbuf_map_single(osdev, buf, dir); +#else + return 0; +#endif +} + +static inline void +adf_nbuf_unmap_single( + adf_os_device_t osdev, adf_nbuf_t buf, adf_os_dma_dir_t dir) +{ +#if defined(HIF_PCI) + __adf_nbuf_unmap_single(osdev, buf, dir); +#endif +} + +static inline int +adf_nbuf_get_num_frags(adf_nbuf_t buf) +{ + return __adf_nbuf_get_num_frags(buf); +} + +static inline int +adf_nbuf_get_frag_len(adf_nbuf_t buf, int frag_num) +{ + return __adf_nbuf_get_frag_len(buf, frag_num); +} + +static inline unsigned char * +adf_nbuf_get_frag_vaddr(adf_nbuf_t buf, int frag_num) +{ + return __adf_nbuf_get_frag_vaddr(buf, frag_num); +} + +static inline a_uint32_t +adf_nbuf_get_frag_paddr_lo(adf_nbuf_t buf, int frag_num) +{ + return __adf_nbuf_get_frag_paddr_lo(buf, frag_num); +} + +static inline int +adf_nbuf_get_frag_is_wordstream(adf_nbuf_t buf, int frag_num) +{ + return __adf_nbuf_get_frag_is_wordstream(buf, frag_num); +} + +static inline void +adf_nbuf_set_frag_is_wordstream(adf_nbuf_t buf, int frag_num, int is_wordstream) +{ + __adf_nbuf_set_frag_is_wordstream(buf, frag_num, is_wordstream); +} + +static inline void +adf_nbuf_frag_push_head( + adf_nbuf_t buf, + int frag_len, + char *frag_vaddr, + u_int32_t frag_paddr_lo, + u_int32_t frag_paddr_hi) +{ + __adf_nbuf_frag_push_head( + buf, frag_len, frag_vaddr, frag_paddr_lo, frag_paddr_hi); +} + +/** + * @brief returns information about the mapped buf + * + * @param[in] bmap map handle + * @param[out] sg map info + */ +static inline void +adf_nbuf_dmamap_info(adf_os_dma_map_t bmap, adf_os_dmamap_info_t *sg) +{ + __adf_nbuf_dmamap_info(bmap, sg); +} + + + +/* + * nbuf allocation rouines + */ + + +/** + * @brief Allocate adf_nbuf + * + * The nbuf created is guarenteed to have only 1 physical segment + * + * @param[in] hdl platform device object + * @param[in] size data buffer size for this adf_nbuf including max header + * size + * @param[in] reserve headroom to start with. + * @param[in] align alignment for the start buffer. + * @param[i] prio Indicate if the nbuf is high priority (some OSes e.g darwin + * polls few times if allocation fails and priority is TRUE) + * + * @return The new adf_nbuf instance or NULL if there's not enough memory. + */ +static inline adf_nbuf_t +adf_nbuf_alloc(adf_os_device_t osdev, + adf_os_size_t size, + int reserve, + int align, + int prio) +{ + return __adf_nbuf_alloc(osdev, size, reserve,align, prio); +} + + +/** + * @brief Free adf_nbuf + * + * @param[in] buf buffer to free + */ +static inline void +adf_nbuf_free(adf_nbuf_t buf) +{ + __adf_nbuf_free(buf); +} + +/** + * @brief Free adf_nbuf + * + * @param[in] buf buffer to free + */ +static inline void +adf_nbuf_ref(adf_nbuf_t buf) +{ + __adf_nbuf_ref(buf); +} + +/** + * @brief Check whether the buffer is shared + * @param skb: buffer to check + * + * Returns true if more than one person has a reference to this + * buffer. + */ +static inline int +adf_nbuf_shared(adf_nbuf_t buf) +{ + return __adf_nbuf_shared(buf); +} + + +/** + * @brief Free a list of adf_nbufs and tell the OS their tx status (if req'd) + * + * @param[in] bufs - list of netbufs to free + * @param[in] tx_err - whether the tx frames were transmitted successfully + */ +static inline void +adf_nbuf_tx_free(adf_nbuf_t buf_list, int tx_err) +{ + __adf_nbuf_tx_free(buf_list, tx_err); +} + +/** + * @brief Reallocate such that there's required headroom in + * buf. Note that this can allocate a new buffer, or + * change geometry of the orignial buffer. The new buffer + * is returned in the (new_buf). + * + * @param[in] buf (older buffer) + * @param[in] headroom + * + * @return newly allocated buffer + */ +static inline adf_nbuf_t +adf_nbuf_realloc_headroom(adf_nbuf_t buf, a_uint32_t headroom) +{ + return (__adf_nbuf_realloc_headroom(buf, headroom)); +} + + +/** + * @brief expand the tailroom to the new tailroom, but the buffer + * remains the same + * + * @param[in] buf buffer + * @param[in] tailroom new tailroom + * + * @return expanded buffer or NULL on failure + */ +static inline adf_nbuf_t +adf_nbuf_realloc_tailroom(adf_nbuf_t buf, a_uint32_t tailroom) +{ + return (__adf_nbuf_realloc_tailroom(buf, tailroom)); +} + + +/** + * @brief this will expand both tail & head room for a given + * buffer, you may or may not get a new buffer.Use it + * only when its required to expand both. Otherwise use + * realloc (head/tail) will solve the purpose. Reason for + * having an extra API is that some OS do this in more + * optimized way, rather than calling realloc (head/tail) + * back to back. + * + * @param[in] buf buffer + * @param[in] headroom new headroom + * @param[in] tailroom new tailroom + * + * @return expanded buffer + */ +static inline adf_nbuf_t +adf_nbuf_expand(adf_nbuf_t buf, a_uint32_t headroom, a_uint32_t tailroom) +{ + return (__adf_nbuf_expand(buf,headroom,tailroom)); +} + + +/** + * @brief Copy src buffer into dst. This API is useful, for + * example, because most native buffer provide a way to + * copy a chain into a single buffer. Therefore as a side + * effect, it also "linearizes" a buffer (which is + * perhaps why you'll use it mostly). It creates a + * writeable copy. + * + * @param[in] buf source nbuf to copy from + * + * @return the new nbuf + */ +static inline adf_nbuf_t +adf_nbuf_copy(adf_nbuf_t buf) +{ + return(__adf_nbuf_copy(buf)); +} + + +/** + * @brief link two nbufs, the new buf is piggybacked into the + * older one. + * + * @param[in] dst buffer to piggyback into + * @param[in] src buffer to put + * + * @return status of the call - 0 successful + */ +static inline a_status_t +adf_nbuf_cat(adf_nbuf_t dst, adf_nbuf_t src) +{ + return __adf_nbuf_cat(dst, src); +} + + +/** + * @brief return the length of the copy bits for skb + * + * @param skb, offset, len, to + * + * @return int32_t + */ +static inline int32_t +adf_nbuf_copy_bits(adf_nbuf_t nbuf, u_int32_t offset, u_int32_t len, void *to) +{ + return __adf_nbuf_copy_bits(nbuf, offset, len, to); +} + + +/** + * @brief clone the nbuf (copy is readonly) + * + * @param[in] buf nbuf to clone from + * + * @return cloned buffer + */ +static inline adf_nbuf_t +adf_nbuf_clone(adf_nbuf_t buf) +{ + return(__adf_nbuf_clone(buf)); +} + + +/** + * @brief Create a version of the specified nbuf whose + * contents can be safely modified without affecting + * other users.If the nbuf is a clone then this function + * creates a new copy of the data. If the buffer is not + * a clone the original buffer is returned. + * + * @param[in] buf source nbuf to create a writable copy from + * + * @return new buffer which is writeable + */ +static inline adf_nbuf_t +adf_nbuf_unshare(adf_nbuf_t buf) +{ + return(__adf_nbuf_unshare(buf)); +} + + + +/* + * nbuf manipulation routines + */ + +/** + * @brief return the address of an nbuf's buffer + * + * @param[in] buf netbuf + * + * @return head address + */ +static inline a_uint8_t * +adf_nbuf_head(adf_nbuf_t buf) +{ + return __adf_nbuf_head(buf); +} + +/** + * @brief return the address of the start of data within an nbuf + * + * @param[in] buf buffer + * + * @return data address + */ +static inline a_uint8_t * +adf_nbuf_data(adf_nbuf_t buf) +{ + return __adf_nbuf_data(buf); +} + + +/** + * @brief return the amount of headroom int the current nbuf + * + * @param[in] buf buffer + * + * @return amount of head room + */ +static inline a_uint32_t +adf_nbuf_headroom(adf_nbuf_t buf) +{ + return (__adf_nbuf_headroom(buf)); +} + + +/** + * @brief return the amount of tail space available + * + * @param[in] buf buffer + * + * @return amount of tail room + */ +static inline a_uint32_t +adf_nbuf_tailroom(adf_nbuf_t buf) +{ + return (__adf_nbuf_tailroom(buf)); +} + + +/** + * @brief Push data in the front + * + * @param[in] buf buf instance + * @param[in] size size to be pushed + * + * @return New data pointer of this buf after data has been pushed, + * or NULL if there is not enough room in this buf. + */ +static inline a_uint8_t * +adf_nbuf_push_head(adf_nbuf_t buf, adf_os_size_t size) +{ + return __adf_nbuf_push_head(buf, size); +} + + +/** + * @brief Puts data in the end + * + * @param[in] buf buf instance + * @param[in] size size to be pushed + * + * @return data pointer of this buf where new data has to be + * put, or NULL if there is not enough room in this buf. + */ +static inline a_uint8_t * +adf_nbuf_put_tail(adf_nbuf_t buf, adf_os_size_t size) +{ + return __adf_nbuf_put_tail(buf, size); +} + +/** + * @brief before put buf into pool,turn it to init state + * + * @param[in] buf buf instance + * @param[in] reserve headroom to start with. + * @param[in] align alignment for the start buffer. + * @param[in] tail_size put size to the tail of buffer + * + * @return data pointer of this buf where new data has to be + * put, or NULL if there is not enough room in this buf. + */ + +static inline a_uint8_t * +adf_nbuf_init(adf_nbuf_t buf, adf_os_size_t reverse, adf_os_size_t align, adf_os_size_t tail_size) +{ + return __adf_nbuf_init(buf, reverse, align, tail_size); +} + +static inline void +adf_nbuf_free_pool(adf_nbuf_t buf) +{ + __adf_nbuf_free_pool(buf); +} + +/** + * @brief pull data out from the front + * + * @param[in] buf buf instance + * @param[in] size size to be popped + * + * @return New data pointer of this buf after data has been popped, + * or NULL if there is not sufficient data to pull. + */ +static inline a_uint8_t * +adf_nbuf_pull_head(adf_nbuf_t buf, adf_os_size_t size) +{ + return __adf_nbuf_pull_head(buf, size); +} + + +/** + * + * @brief trim data out from the end + * + * @param[in] buf buf instance + * @param[in] size size to be popped + * + * @return none + */ +static inline void +adf_nbuf_trim_tail(adf_nbuf_t buf, adf_os_size_t size) +{ + __adf_nbuf_trim_tail(buf, size); +} + + +/** + * @brief Get the length of the buf + * + * @param[in] buf the buf instance + * + * @return The total length of this buf. + */ +static inline adf_os_size_t +adf_nbuf_len(adf_nbuf_t buf) +{ + return (__adf_nbuf_len(buf)); +} + +/** + * @brief Set the length of the buf + * + * @param[in] buf the buf instance + * @param[in] size to be set + * + * @return none + */ +static inline void +adf_nbuf_set_pktlen(adf_nbuf_t buf, uint32_t len) +{ + __adf_nbuf_set_pktlen(buf, len); +} + +/** + * @brief test whether the nbuf is cloned or not + * + * @param[in] buf buffer + * + * @return TRUE if it is cloned, else FALSE + */ +static inline a_bool_t +adf_nbuf_is_cloned(adf_nbuf_t buf) +{ + return (__adf_nbuf_is_cloned(buf)); +} + +/** + * + * @brief trim data out from the end + * + * @param[in] buf buf instance + * @param[in] size size to be popped + * + * @return none + */ +static inline void +adf_nbuf_reserve(adf_nbuf_t buf, adf_os_size_t size) +{ + __adf_nbuf_reserve(buf, size); +} + + +/* + * nbuf frag routines + */ + +/** + * @brief return the frag pointer & length of the frag + * + * @param[in] buf buffer + * @param[out] sg this will return all the frags of the nbuf + * + */ +static inline void +adf_nbuf_frag_info(adf_nbuf_t buf, adf_os_sglist_t *sg) +{ + __adf_nbuf_frag_info(buf, sg); +} +/** + * @brief return the data pointer & length of the header + * + * @param[in] buf nbuf + * @param[out] addr data pointer + * @param[out] len length of the data + * + */ +static inline void +adf_nbuf_peek_header(adf_nbuf_t buf, a_uint8_t **addr, a_uint32_t *len) +{ + __adf_nbuf_peek_header(buf, addr, len); +} +/* + * nbuf private context routines + */ + +/** + * @brief get the priv pointer from the nbuf'f private space + * + * @param[in] buf + * + * @return data pointer to typecast into your priv structure + */ +static inline a_uint8_t * +adf_nbuf_get_priv(adf_nbuf_t buf) +{ + return (__adf_nbuf_get_priv(buf)); +} + + +/* + * nbuf queue routines + */ + + +/** + * @brief Initialize buf queue + * + * @param[in] head buf queue head + */ +static inline void +adf_nbuf_queue_init(adf_nbuf_queue_t *head) +{ + __adf_nbuf_queue_init(head); +} + + +/** + * @brief Append a nbuf to the tail of the buf queue + * + * @param[in] head buf queue head + * @param[in] buf buf + */ +static inline void +adf_nbuf_queue_add(adf_nbuf_queue_t *head, adf_nbuf_t buf) +{ + __adf_nbuf_queue_add(head, buf); +} + +/** + * @brief Insert nbuf at the head of queue + * + * @param[in] head buf queue head + * @param[in] buf buf + */ +static inline void +adf_nbuf_queue_insert_head(adf_nbuf_queue_t *head, adf_nbuf_t buf) +{ + __adf_nbuf_queue_insert_head(head, buf); +} + +/** + * @brief Retrieve a buf from the head of the buf queue + * + * @param[in] head buf queue head + * + * @return The head buf in the buf queue. + */ +static inline adf_nbuf_t +adf_nbuf_queue_remove(adf_nbuf_queue_t *head) +{ + return __adf_nbuf_queue_remove(head); +} + + +/** + * @brief get the length of the queue + * + * @param[in] head buf queue head + * + * @return length of the queue + */ +static inline a_uint32_t +adf_nbuf_queue_len(adf_nbuf_queue_t *head) +{ + return __adf_nbuf_queue_len(head); +} + + +/** + * @brief get the first guy/packet in the queue + * + * @param[in] head buf queue head + * + * @return first buffer in queue + */ +static inline adf_nbuf_t +adf_nbuf_queue_first(adf_nbuf_queue_t *head) +{ + return (__adf_nbuf_queue_first(head)); +} + + +/** + * @brief get the next guy/packet of the given buffer (or + * packet) + * + * @param[in] buf buffer + * + * @return next buffer/packet + */ +static inline adf_nbuf_t +adf_nbuf_queue_next(adf_nbuf_t buf) +{ + return (__adf_nbuf_queue_next(buf)); +} + + +/** + * @brief Check if the buf queue is empty + * + * @param[in] nbq buf queue handle + * + * @return TRUE if queue is empty + * @return FALSE if queue is not emty + */ +static inline a_bool_t +adf_nbuf_is_queue_empty(adf_nbuf_queue_t * nbq) +{ + return __adf_nbuf_is_queue_empty(nbq); +} + + +/** + * @brief get the next packet in the linked list + * @details + * This function can be used when nbufs are directly linked into a list, + * rather than using a separate network buffer queue object. + * + * @param[in] buf buffer + * + * @return next network buffer in the linked list + */ +static inline adf_nbuf_t +adf_nbuf_next(adf_nbuf_t buf) +{ + return __adf_nbuf_next(buf); +} + + +/** + * @brief add a packet to a linked list + * @details + * This function can be used to directly link nbufs, rather than using + * a separate network buffer queue object. + * + * @param[in] this_buf predecessor buffer + * @param[in] next_buf successor buffer + */ +static inline void +adf_nbuf_set_next(adf_nbuf_t this_buf, adf_nbuf_t next_buf) +{ + __adf_nbuf_set_next(this_buf, next_buf); +} + + +/* + * nbuf extension routines XXX + */ + +/** + * @brief link extension of this packet contained in a new nbuf + * @details + * This function is used to link up many nbufs containing a single logical + * packet - not a collection of packets. Do not use for linking the first + * extension to the head + * @param[in] this_buf predecessor buffer + * @param[in] next_buf successor buffer + */ +static inline void +adf_nbuf_set_next_ext(adf_nbuf_t this_buf, adf_nbuf_t next_buf) +{ + __adf_nbuf_set_next_ext(this_buf, next_buf); +} + +/** + * @brief get the next packet extension in the linked list + * @details + * + * @param[in] buf buffer + * + * @return next network buffer in the linked list + */ +static inline adf_nbuf_t +adf_nbuf_next_ext(adf_nbuf_t buf) +{ + return __adf_nbuf_next_ext(buf); +} + +/** + * @brief link list of packet extensions to the head segment + * @details + * This function is used to link up a list of packet extensions (seg1, 2, + * ...) to the nbuf holding the head segment (seg0) + * @param[in] head_buf nbuf holding head segment (single) + * @param[in] ext_list nbuf list holding linked extensions to the head + * @param[in] ext_len Total length of all buffers in the extension list + */ +static inline void +adf_nbuf_append_ext_list(adf_nbuf_t head_buf, adf_nbuf_t ext_list, + adf_os_size_t ext_len) +{ + __adf_nbuf_append_ext_list(head_buf, ext_list, ext_len); +} + +/** + * @brief Gets the tx checksumming to be performed on this buf + * + * @param[in] buf buffer + * @param[out] hdr_off the (tcp) header start + * @param[out] where the checksum offset + */ +static inline adf_net_cksum_type_t +adf_nbuf_tx_cksum_info(adf_nbuf_t buf, a_uint8_t **hdr_off, a_uint8_t **where) +{ + return(__adf_nbuf_tx_cksum_info(buf, hdr_off, where)); +} + + +/** + * @brief Gets the tx checksum offload demand + * + * @param[in] buf buffer + * @return adf_nbuf_tx_cksum_t checksum offload demand for the frame + */ +static inline adf_nbuf_tx_cksum_t +adf_nbuf_get_tx_cksum(adf_nbuf_t buf) +{ + return (__adf_nbuf_get_tx_cksum(buf)); +} + +/** + * @brief Drivers that support hw checksumming use this to + * indicate checksum info to the stack. + * + * @param[in] buf buffer + * @param[in] cksum checksum + */ +static inline void +adf_nbuf_set_rx_cksum(adf_nbuf_t buf, adf_nbuf_rx_cksum_t *cksum) +{ + __adf_nbuf_set_rx_cksum(buf, cksum); +} + + +/** + * @brief Drivers that are capable of TCP Large segment offload + * use this to get the offload info out of an buf. + * + * @param[in] buf buffer + * @param[out] tso offload info + */ +static inline void +adf_nbuf_get_tso_info(adf_nbuf_t buf, adf_nbuf_tso_t *tso) +{ + __adf_nbuf_get_tso_info(buf, tso); +} + + +/*static inline void +adf_nbuf_set_vlan_info(adf_nbuf_t buf, adf_net_vlan_tag_t vlan_tag) +{ + __adf_nbuf_set_vlan_info(buf, vlan_tag); +}*/ + +/** + * @brief This function extracts the vid & priority from an + * nbuf + * + * + * @param[in] hdl net handle + * @param[in] buf buffer + * @param[in] vlan vlan header + * + * @return status of the operation + */ +static inline a_status_t +adf_nbuf_get_vlan_info(adf_net_handle_t hdl, adf_nbuf_t buf, + adf_net_vlanhdr_t *vlan) +{ + return __adf_nbuf_get_vlan_info(hdl, buf, vlan); +} + +/** + * @brief This function extracts the TID value from nbuf + * + * @param[in] buf buffer + * + * @return TID value + */ +static inline a_uint8_t +adf_nbuf_get_tid(adf_nbuf_t buf) +{ + return __adf_nbuf_get_tid(buf); +} + +/** + * @brief This function sets the TID value in nbuf + * + * @param[in] buf buffer + * + * @param[in] tid TID value + */ +static inline void +adf_nbuf_set_tid(adf_nbuf_t buf, a_uint8_t tid) +{ + __adf_nbuf_set_tid(buf, tid); +} + +/** + * @brief This function extracts the exemption type from nbuf + * + * @param[in] buf buffer + * + * @return exemption type + */ +static inline a_uint8_t +adf_nbuf_get_exemption_type(adf_nbuf_t buf) +{ + return __adf_nbuf_get_exemption_type(buf); +} + +static inline void +adf_nbuf_reset_ctxt(__adf_nbuf_t nbuf) +{ + __adf_nbuf_reset_ctxt(nbuf); +} + +/** + * @brief This function peeks data into the buffer at given offset + * + * @param[in] buf buffer + * @param[out] data peeked output buffer + * @param[in] off offset + * @param[in] len length of buffer requested beyond offset + * + * @return status of operation + */ +static inline a_status_t +adf_nbuf_peek_data(adf_nbuf_t buf, void **data, a_uint32_t off, + a_uint32_t len) +{ + return __adf_nbuf_peek_data(buf, data, off, len); +} + +/** + * @brief This function peeks data into the buffer at given offset + * + * @param[in] buf buffer + * @param[in] proto protocol + */ +static inline void +adf_nbuf_set_protocol(adf_nbuf_t buf, uint16_t proto) +{ + __adf_nbuf_set_protocol(buf, proto); +} + +/** + * @brief This function return packet proto type + * + * @param[in] buf buffer + */ +static inline uint8_t +adf_nbuf_trace_get_proto_type(adf_nbuf_t buf) +{ + return __adf_nbuf_trace_get_proto_type(buf); +} + +/** + * @brief This function updates packet proto type + * + * @param[in] buf buffer + * @param[in] proto_type protocol type +*/ +static inline void +adf_nbuf_trace_set_proto_type(adf_nbuf_t buf, uint8_t proto_type) +{ + __adf_nbuf_trace_set_proto_type(buf, proto_type); +} + +/** + * @brief This function registers protocol trace callback + * + * @param[in] adf_nbuf_trace_update_t callback pointer + */ +static inline void +adf_nbuf_reg_trace_cb(adf_nbuf_trace_update_t cb_func_ptr) +{ + __adf_nbuf_reg_trace_cb(cb_func_ptr); +} + +/** + * @brief This function updates protocol event + * + * @param[in] buf buffer + * @param[in] char * event string + */ +static inline void +adf_nbuf_trace_update(adf_nbuf_t buf, char *event_string) +{ + __adf_nbuf_trace_update(buf, event_string); +} + +/** + * @brief This function stores a flag specifying this TX frame + * is suitable for downloading though a 2nd TX data pipe + * that is used for short frames for protocols that can + * accept out-of-order delivery. + * + * @param[in] buf buffer + * @param[in] candi candidate of parallel download frame + */ +static inline void +adf_nbuf_set_tx_parallel_dnload_frm(adf_nbuf_t buf, uint8_t candi) +{ + __adf_nbuf_set_tx_htt2_frm(buf, candi); +} + +/** + * @brief This function return whether this TX frame is allow + * to download though a 2nd TX data pipe or not. + * + * @param[in] buf buffer + */ +static inline uint8_t +adf_nbuf_get_tx_parallel_dnload_frm(adf_nbuf_t buf) +{ + return __adf_nbuf_get_tx_htt2_frm(buf); +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_net_types.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_net_types.h new file mode 100644 index 0000000000000..95428eb5596b2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_net_types.h @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @ingroup adf_net_public + * @file adf_net_types.h + * This file defines types used in the networking stack abstraction. + */ + +#ifndef _ADF_NET_TYPES_H +#define _ADF_NET_TYPES_H + +#include /* a_uint8_t, etc. */ + +/** + * @brief These control/get info from the device + */ +#define ADF_NET_CMD(_x) \ + ADF_NET_CMD_GET_##_x, \ + ADF_NET_CMD_SET_##_x + +/** + * @brief Get/Set commands from anet to adf_drv + */ +typedef enum { + ADF_NET_CMD(LINK_INFO), + ADF_NET_CMD(POLL_INFO), + ADF_NET_CMD(CKSUM_INFO), + ADF_NET_CMD(RING_INFO), + ADF_NET_CMD(MAC_ADDR), + ADF_NET_CMD(MTU), + ADF_NET_CMD_GET_DMA_INFO, + ADF_NET_CMD_GET_OFFLOAD_CAP, + ADF_NET_CMD_GET_STATS, + ADF_NET_CMD_ADD_VID, + ADF_NET_CMD_DEL_VID, + ADF_NET_CMD_SET_MCAST, + ADF_NET_CMD_GET_MCAST_CAP +}adf_net_cmd_t; + + + +/** + * @brief Indicates what features are supported by the interface. + */ +#define ADF_NET_LINK_SUPP_10baseT_Half (1 << 0) +#define ADF_NET_LINK_SUPP_10baseT_Full (1 << 1) +#define ADF_NET_LINK_SUPP_100baseT_Half (1 << 2) +#define ADF_NET_LINK_SUPP_100baseT_Full (1 << 3) +#define ADF_NET_LINK_SUPP_1000baseT_Half (1 << 4) +#define ADF_NET_LINK_SUPP_1000baseT_Full (1 << 5) +#define ADF_NET_LINK_SUPP_Autoneg (1 << 6) +#define ADF_NET_LINK_SUPP_Pause (1 << 7) +#define ADF_NET_LINK_SUPP_Asym_Pause (1 << 8) + +#define ADF_NET_LINK_SUPP_100 (ADF_NET_LINK_SUPP_10baseT_Half | \ + ADF_NET_LINK_SUPP_10baseT_Full | \ + ADF_NET_LINK_SUPP_100baseT_Half | \ + ADF_NET_LINK_SUPP_100baseT_Full) + +#define ADF_NET_LINK_SUPP_1000 (ADF_NET_LINK_SUPP_100 | \ + ADF_NET_LINK_SUPP_1000baseT_Full) + +/** + * @brief Indicates what features are advertised by the interface. + */ +#define ADF_NET_LINK_ADV_10baseT_Half (1 << 0) +#define ADF_NET_LINK_ADV_10baseT_Full (1 << 1) +#define ADF_NET_LINK_ADV_100baseT_Half (1 << 2) +#define ADF_NET_LINK_ADV_100baseT_Full (1 << 3) +#define ADF_NET_LINK_ADV_1000baseT_Half (1 << 4) +#define ADF_NET_LINK_ADV_1000baseT_Full (1 << 5) +#define ADF_NET_LINK_ADV_Autoneg (1 << 6) +#define ADF_NET_LINK_ADV_Pause (1 << 7) +#define ADF_NET_LINK_ADV_Asym_Pause (1 << 8) + +#define ADF_NET_LINK_ADV_100 (ADF_NET_LINK_ADV_10baseT_Half | \ + ADF_NET_LINK_ADV_10baseT_Full | \ + ADF_NET_LINK_ADV_100baseT_Half | \ + ADF_NET_LINK_ADV_100baseT_Full) + +#define ADF_NET_LINK_ADV_1000 (ADF_NET_LINK_ADV_100 | \ + ADF_NET_LINK_ADV_1000baseT_Full) + +/** + * @brief The forced/current speed/duplex/autoneg + */ +#define ADF_NET_LINK_SPEED_10 10 +#define ADF_NET_LINK_SPEED_100 100 +#define ADF_NET_LINK_SPEED_1000 1000 + +#define ADF_NET_LINK_DUPLEX_HALF 0x00 +#define ADF_NET_LINK_DUPLEX_FULL 0x01 + +#define ADF_NET_LINK_AUTONEG_DISABLE 0x00 +#define ADF_NET_LINK_AUTONEG_ENABLE 0x01 + +#define ADF_NET_MAC_ADDR_MAX_LEN 6 +#define ADF_NET_IF_NAME_SIZE 64 +#define ADF_NET_ETH_LEN ADF_NET_MAC_ADDR_MAX_LEN +#define ADF_NET_MAX_MCAST_ADDR 64 + + +/** + * @brief Extended Traffic ID passed to target if the TID is unknown + */ +#define ADF_NBUF_TX_EXT_TID_INVALID 0x1f + + +/** + * @brief Specify whether to encrypt frame or not + */ +enum adf_nbuf_exemption_type { + ADF_NBUF_EXEMPT_NO_EXEMPTION = 0, + ADF_NBUF_EXEMPT_ALWAYS, + ADF_NBUF_EXEMPT_ON_KEY_MAPPING_KEY_UNAVAILABLE +}; + +typedef enum adf_net_flags{ + ADF_NET_IS_RUNNING = 0x0001, + ADF_NET_IS_UP = 0x0002, + ADF_NET_IS_ALLMULTI = 0x0004, + ADF_NET_IS_PROMISC = 0x0008 +}adf_net_flags_t; +/** + * @brief link info capability/parameters for the device + * Note the flags below + */ +typedef struct { + a_uint32_t supported; /*RO Features this if supports*/ + a_uint32_t advertized; /*Features this interface advertizes*/ + a_int16_t speed; /*Force speed 10M, 100M, gigE*/ + a_int8_t duplex; /*duplex full or half*/ + a_uint8_t autoneg; /*Enabled/disable autoneg*/ +}adf_net_cmd_link_info_t; + +typedef struct adf_net_ethaddr{ + a_uint8_t addr[ADF_NET_ETH_LEN]; +} adf_net_ethaddr_t; +typedef struct { + a_uint8_t ether_dhost[ADF_NET_ETH_LEN]; /* destination eth addr */ + a_uint8_t ether_shost[ADF_NET_ETH_LEN]; /* source ether addr */ + a_uint16_t ether_type; /* packet type ID field */ +}adf_net_ethhdr_t; + +typedef struct { +#if defined (ADF_LITTLE_ENDIAN_MACHINE) + a_uint8_t ip_hl:4, + ip_version:4; +#elif defined (ADF_BIG_ENDIAN_MACHINE) + a_uint8_t ip_version:4, + ip_hl:4; +#else +#error "Please fix" +#endif + a_uint8_t ip_tos; + + a_uint16_t ip_len; + a_uint16_t ip_id; + a_uint16_t ip_frag_off; + a_uint8_t ip_ttl; + a_uint8_t ip_proto; + a_uint16_t ip_check; + a_uint32_t ip_saddr; + a_uint32_t ip_daddr; + /*The options start here. */ + }adf_net_iphdr_t; + +typedef struct { + a_uint16_t src_port; + a_uint16_t dst_port; + a_uint16_t udp_len; + a_uint16_t udp_cksum; + }adf_net_udphdr_t; + +typedef struct { + a_uint8_t dhcp_msg_type; + a_uint8_t dhcp_hw_type; + a_uint8_t dhcp_hw_addr_len; + a_uint8_t dhcp_num_hops; + a_uint32_t dhcp_transc_id; + a_uint16_t dhcp_secs_elapsed; + a_uint16_t dhcp_flags; + a_uint32_t dhcp_ciaddr; /* client IP (if client is in BOUND, RENEW or REBINDING state) */ + a_uint32_t dhcp_yiaddr; /* 'your' (client) IP address */ + /* IP address of next server to use in bootstrap, returned in DHCPOFFER, DHCPACK by server */ + a_uint32_t dhcp_siaddr_nip; + a_uint32_t dhcp_gateway_nip; /* relay agent IP address */ + a_uint8_t dhcp_chaddr[16]; /* link-layer client hardware address (MAC) */ + a_uint8_t dhcp_sname[64]; /* server host name (ASCIZ) */ + a_uint8_t dhcp_file[128]; /* boot file name (ASCIZ) */ + a_uint8_t dhcp_cookie[4]; /* fixed first four option bytes (99,130,83,99 dec) */ + } adf_net_dhcphdr_t; + +/* @brief V3 group record types [grec_type] */ +#define IGMPV3_MODE_IS_INCLUDE 1 +#define IGMPV3_MODE_IS_EXCLUDE 2 +#define IGMPV3_CHANGE_TO_INCLUDE 3 +#define IGMPV3_CHANGE_TO_EXCLUDE 4 +#define IGMPV3_ALLOW_NEW_SOURCES 5 +#define IGMPV3_BLOCK_OLD_SOURCES 6 + +typedef struct { + a_uint8_t igmp_type; + a_uint8_t igmp_code; /* For newer IGMP */ + a_uint16_t igmp_csum; + a_uint32_t igmp_group; +} adf_net_igmphdr_t; + +typedef struct { + a_uint8_t grec_type; + a_uint8_t grec_auxwords; + a_uint16_t grec_nsrcs; + a_uint32_t grec_mca; + a_uint32_t grec_src[1]; +} adf_net_igmpv3_grec_t; + +/** + * @brief IGMP version 3 specific datatypes + */ +typedef struct { + a_uint8_t igmpv3_type; + a_uint8_t igmpv3_resv1; + a_uint16_t igmpv3_csum; + a_uint16_t igmpv3_resv2; + a_uint16_t igmpv3_ngrec; + adf_net_igmpv3_grec_t igmpv3_grec[1]; +} adf_net_igmpv3_report_t; + + +/** + * @brief Vlan header + */ +typedef struct adf_net_vlanhdr{ + a_uint16_t tpid; +#if defined (ADF_LITTLE_ENDIAN_MACHINE) + a_uint16_t vid:12; /* Vlan id*/ + a_uint8_t cfi:1; /* reserved for CFI, don't use*/ + a_uint8_t prio:3; /* Priority*/ +#elif defined (ADF_BIG_ENDIAN_MACHINE) + a_uint8_t prio:3; /* Priority*/ + a_uint8_t cfi:1; /* reserved for CFI, don't use*/ + a_uint16_t vid:12; /* Vlan id*/ +#else +#error "Please fix" +#endif +}adf_net_vlanhdr_t; + +typedef struct adf_net_vid{ +#if defined (ADF_LITTLE_ENDIAN_MACHINE) + a_uint16_t val:12; + a_uint8_t res:4; +#elif defined (ADF_BIG_ENDIAN_MACHINE) + a_uint8_t res:4; + a_uint16_t val:12; +#else +#error "Please fix" +#endif +}adf_net_vid_t; + + +/** + * @brief Command for setting ring paramters. + */ +typedef struct { + a_uint32_t rx_bufsize; /*Ro field. For shim's that maintain a pool*/ + a_uint32_t rx_ndesc; + a_uint32_t tx_ndesc; +}adf_net_cmd_ring_info_t; + +/** + * @brief Whether the interface is polled or not. If so, the polling bias (number of + * packets it wants to process per invocation + */ +typedef struct { + a_bool_t polled; + a_uint32_t poll_wt; +}adf_net_cmd_poll_info_t; + +/** + * @brief Basic device info + */ +typedef struct { + a_uint8_t if_name[ADF_NET_IF_NAME_SIZE]; + a_uint8_t dev_addr[ADF_NET_MAC_ADDR_MAX_LEN]; + a_uint16_t header_len; + a_uint16_t mtu_size; +}adf_net_dev_info_t; + +typedef struct adf_dma_info { + adf_os_dma_mask_t dma_mask; + a_uint32_t sg_nsegs; /**< scatter segments */ +}adf_net_cmd_dma_info_t; + +/** + * @brief Defines the TX and RX checksumming capabilities/state of the device + * The actual checksum handling happens on an adf_nbuf + * If offload capability command not supported, all offloads are assumed to be + * none. + */ +typedef enum { + ADF_NET_CKSUM_NONE, /*Cannot do any checksum*/ + ADF_NET_CKSUM_TCP_UDP_IPv4, /*tcp/udp on ipv4 with pseudo hdr*/ + ADF_NET_CKSUM_TCP_UDP_IPv6, /*tcp/udp on ipv6*/ +}adf_net_cksum_type_t; + +typedef struct { + adf_net_cksum_type_t tx_cksum; + adf_net_cksum_type_t rx_cksum; +}adf_net_cksum_info_t; + +typedef adf_net_cksum_info_t adf_net_cmd_cksum_info_t; /*XXX needed?*/ + +/** + * @brief Command for set/unset vid + */ +typedef a_uint16_t adf_net_cmd_vid_t ; /*get/set vlan id*/ + +typedef enum { + ADF_NET_TSO_NONE, + ADF_NET_TSO_IPV4, /**< for tsp ipv4 only*/ + ADF_NET_TSO_ALL, /**< ip4 & ipv6*/ +}adf_net_tso_type_t; + +/** + * @brief Command for getting offloading capabilities of a device + */ +typedef struct { + adf_net_cksum_info_t cksum_cap; + adf_net_tso_type_t tso; + a_uint8_t vlan_supported; +}adf_net_cmd_offload_cap_t; + +/** + * @brief Command for getting general stats from a device + */ +typedef struct { + a_uint32_t tx_packets; /**< total packets transmitted*/ + a_uint32_t rx_packets; /**< total packets recieved*/ + a_uint32_t tx_bytes; /**< total bytes transmitted*/ + a_uint32_t rx_bytes; /**< total bytes recieved*/ + a_uint32_t tx_dropped; /**< total tx dropped because of lack of buffers*/ + a_uint32_t rx_dropped; /**< total rx dropped because of lack of buffers*/ + a_uint32_t rx_errors; /**< bad packet recieved*/ + a_uint32_t tx_errors; /**< transmisison problems*/ +}adf_net_cmd_stats_t; + +typedef enum adf_net_cmd_mcast_cap{ + ADF_NET_MCAST_SUP=0, + ADF_NET_MCAST_NOTSUP +}adf_net_cmd_mcast_cap_t; + +typedef struct adf_net_devaddr{ + a_uint32_t num; /**< No. of mcast addresses*/ + a_uint8_t *da_addr[ADF_NET_MAX_MCAST_ADDR]; +}adf_net_devaddr_t; + +typedef adf_net_devaddr_t adf_net_cmd_mcaddr_t; +typedef adf_net_ethaddr_t adf_net_cmd_macaddr_t; + +typedef union { + adf_net_cmd_link_info_t link_info; + adf_net_cmd_poll_info_t poll_info; + adf_net_cmd_cksum_info_t cksum_info; + adf_net_cmd_ring_info_t ring_info; + adf_net_cmd_dma_info_t dma_info; + adf_net_cmd_vid_t vid; + adf_net_cmd_offload_cap_t offload_cap; + adf_net_cmd_stats_t stats; + adf_net_cmd_mcaddr_t mcast_info; + adf_net_cmd_mcast_cap_t mcast_cap; + adf_net_cmd_macaddr_t mac_addr; +}adf_net_cmd_data_t; + +/** + * @brief For polled devices, adf_drv responds with one of the following status in + * its poll function. + */ +typedef enum { + ADF_NET_POLL_DONE, + ADF_NET_POLL_NOT_DONE, + ADF_NET_POLL_OOM, +}adf_net_poll_resp_t; + +/** + * @brief For transmit checksum API + */ + +typedef enum { + ADF_NBUF_TX_CKSUM_NONE, /* No ckecksum offload */ + ADF_NBUF_TX_CKSUM_IP, /* IP header ckecksum offload */ + ADF_NBUF_TX_CKSUM_TCP_UDP, /* TCP/UDP ckecksum offload */ + ADF_NBUF_TX_CKSUM_TCP_UDP_IP, /* TCP/UDP checksum and IP header ckecksum offload */ + +}adf_nbuf_tx_cksum_t; + +/** + * @brief For recieve checksum API + */ +typedef enum { + ADF_NBUF_RX_CKSUM_TCP = 0x0001, + ADF_NBUF_RX_CKSUM_UDP = 0x0002, + ADF_NBUF_RX_CKSUM_TCPIPV6 = 0x0010, + ADF_NBUF_RX_CKSUM_UDPIPV6 = 0x0020, + ADF_NBUF_RX_CKSUM_TCP_NOPSEUDOHEADER = 0x0100, + ADF_NBUF_RX_CKSUM_UDP_NOPSEUDOHEADER = 0x0200, + ADF_NBUF_RX_CKSUM_TCPSUM16 = 0x1000, +}adf_nbuf_l4_rx_cksum_type_t; + +typedef enum { + ADF_NBUF_RX_CKSUM_NONE = 0x0000, /* device failed to ckecksum */ + ADF_NBUF_RX_CKSUM_TCP_UDP_HW = 0x0010, /* TCP/UDP cksum successful and value returned */ + ADF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY = 0x0020, /* TCP/UDP cksum successful, no value */ +}adf_nbuf_l4_rx_cksum_result_t; + +typedef struct { + adf_nbuf_l4_rx_cksum_type_t l4_type; + adf_nbuf_l4_rx_cksum_result_t l4_result; + a_uint32_t val; +}adf_nbuf_rx_cksum_t; + +/** + * @brief For TCP large Segment Offload + */ +typedef struct { + adf_net_tso_type_t type; + a_uint16_t mss; + a_uint8_t hdr_off; +}adf_nbuf_tso_t; + +/** + * @brief Wireless events + * ADF_IEEE80211_ASSOC = station associate (bss mode) + * ADF_IEEE80211_REASSOC = station re-associate (bss mode) + * ADF_IEEE80211_DISASSOC = station disassociate (bss mode) + * ADF_IEEE80211_JOIN = station join (ap mode) + * ADF_IEEE80211_LEAVE = station leave (ap mode) + * ADF_IEEE80211_SCAN = scan complete, results available + * ADF_IEEE80211_REPLAY = sequence counter replay detected + * ADF_IEEE80211_MICHAEL = Michael MIC failure detected + * ADF_IEEE80211_REJOIN = station re-associate (ap mode) + * ADF_CUSTOM_PUSH_BUTTON = + */ +typedef enum adf_net_wireless_events{ + ADF_IEEE80211_ASSOC = __ADF_IEEE80211_ASSOC, + ADF_IEEE80211_REASSOC = __ADF_IEEE80211_REASSOC, + ADF_IEEE80211_DISASSOC = __ADF_IEEE80211_DISASSOC, + ADF_IEEE80211_JOIN = __ADF_IEEE80211_JOIN, + ADF_IEEE80211_LEAVE = __ADF_IEEE80211_LEAVE, + ADF_IEEE80211_SCAN = __ADF_IEEE80211_SCAN, + ADF_IEEE80211_REPLAY = __ADF_IEEE80211_REPLAY, + ADF_IEEE80211_MICHAEL = __ADF_IEEE80211_MICHAEL, + ADF_IEEE80211_REJOIN = __ADF_IEEE80211_REJOIN, + ADF_CUSTOM_PUSH_BUTTON = __ADF_CUSTOM_PUSH_BUTTON +}adf_net_wireless_event_t; + +#define ADF_ARP_REQ 1 /* ARP request */ +#define ADF_ARP_RSP 2 /* ARP response */ +#define ADF_ARP_RREQ 3 /* RARP request */ +#define ADF_ARP_RRSP 4 /* RARP response */ + +#define ADF_NEXTHDR_ICMP 58 /* ICMP for IPv6. */ + +/* Neighbor Discovery */ +#define ADF_ND_RSOL 133 /* Router Solicitation */ +#define ADF_ND_RADVT 134 /* Router Advertisement */ +#define ADF_ND_NSOL 135 /* Neighbor Solicitation */ +#define ADF_ND_NADVT 136 /* Neighbor Advertisement */ + +/** + * @brief IPv6 Address + */ +typedef struct { + union { + a_uint8_t u6_addr8[16]; + a_uint16_t u6_addr16[8]; + a_uint32_t u6_addr32[4]; + } in6_u; +//#define s6_addr in6_u.u6_addr8 +//#define s6_addr16 in6_u.u6_addr16 +//#define s6_addr32 in6_u.u6_addr32 +} adf_net_ipv6_addr_t; + +/** + * @brief IPv6 Header + */ +typedef struct { +#if defined(ADF_LITTLE_ENDIAN_MACHINE) + a_uint8_t ipv6_priority:4, + ipv6_version:4; +#elif defined(ADF_BIG_ENDIAN_MACHINE) + a_uint8_t ipv6_version:4, + ipv6_priority:4; +#else +#error "Please fix" +#endif + a_uint8_t ipv6_flow_lbl[3]; + + a_uint16_t ipv6_payload_len; + a_uint8_t ipv6_nexthdr, + ipv6_hop_limit; + + adf_net_ipv6_addr_t ipv6_saddr, + ipv6_daddr; +} adf_net_ipv6hdr_t; + +/** + * @brief ICMPv6 Header + */ +typedef struct { + + a_uint8_t icmp6_type; + a_uint8_t icmp6_code; + a_uint16_t icmp6_cksum; + + union { + a_uint32_t un_data32[1]; + a_uint16_t un_data16[2]; + a_uint8_t un_data8[4]; + + struct { + a_uint16_t identifier; + a_uint16_t sequence; + } u_echo; + + struct { +#if defined(ADF_LITTLE_ENDIAN_MACHINE) + a_uint32_t reserved:5, + override:1, + solicited:1, + router:1, + reserved2:24; +#elif defined(ADF_BIG_ENDIAN_MACHINE) + a_uint32_t router:1, + solicited:1, + override:1, + reserved:29; +#else +#error "Please fix" +#endif + } u_nd_advt; + + struct { + a_uint8_t hop_limit; +#if defined(ADF_LITTLE_ENDIAN_MACHINE) + a_uint8_t reserved:6, + other:1, + managed:1; + +#elif defined(ADF_BIG_ENDIAN_MACHINE) + a_uint8_t managed:1, + other:1, + reserved:6; +#else +#error "Please fix" +#endif + a_uint16_t rt_lifetime; + } u_nd_ra; + + } icmp6_dataun; + +} adf_net_icmpv6hdr_t; + +/** + * @brief Neighbor Discovery Message + */ +typedef struct { + adf_net_icmpv6hdr_t nd_icmph; + adf_net_ipv6_addr_t nd_target; + a_uint8_t nd_opt[0]; +} adf_net_nd_msg_t; + +#define adf_csum_ipv6(s, d, l, p, sum) \ + csum_ipv6_magic((struct in6_addr *)s, \ + (struct in6_addr *)d, l, p, sum) +/** + * @brief + * + * @param addr1 + * @param addr2 + * + * @return Compare two ethernet addresses, returns A_TRUE if equal + * + */ +static adf_os_inline a_bool_t +adf_net_cmp_ether_addr(const a_uint8_t *addr1,const a_uint8_t *addr2) +{ + const a_uint16_t *a = (const a_uint16_t *) addr1; + const a_uint16_t *b = (const a_uint16_t *) addr2; + + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; +} + +#endif /*_ADF_NET_TYPES_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_atomic.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_atomic.h new file mode 100644 index 0000000000000..4e386dc90953c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_atomic.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_atomic.h + * This file abstracts an atomic counter. + */ + +#ifndef _ADF_OS_ATOMIC_H +#define _ADF_OS_ATOMIC_H + +#include +/** + * @brief Atomic type of variable. + * Use this when you want a simple resource counter etc. which is atomic + * across multiple CPU's. These maybe slower than usual counters on some + * platforms/OS'es, so use them with caution. + */ +typedef __adf_os_atomic_t adf_os_atomic_t; + +/** + * @brief Initialize an atomic type variable + * @param[in] v a pointer to an opaque atomic variable + */ +static inline void +adf_os_atomic_init(adf_os_atomic_t *v) +{ + __adf_os_atomic_init(v); +} + +/** + * @brief Read the value of an atomic variable. + * @param[in] v a pointer to an opaque atomic variable + * + * @return the current value of the variable + */ +static inline a_uint32_t +adf_os_atomic_read(adf_os_atomic_t *v) +{ + return (__adf_os_atomic_read(v)); +} + +/** + * @brief Increment the value of an atomic variable. + * @param[in] v a pointer to an opaque atomic variable + */ +static inline void +adf_os_atomic_inc(adf_os_atomic_t *v) +{ + __adf_os_atomic_inc(v); +} + +/** + * @brief Decrement the value of an atomic variable. + * @param v a pointer to an opaque atomic variable + */ +static inline void +adf_os_atomic_dec(adf_os_atomic_t *v) +{ + __adf_os_atomic_dec(v); +} + +/** + * @brief Add a value to the value of an atomic variable. + * @param v a pointer to an opaque atomic variable + * @param i the amount by which to increase the atomic counter + */ +static inline void +adf_os_atomic_add(int i, adf_os_atomic_t *v) +{ + __adf_os_atomic_add(i, v); +} + +/** + * @brief Decrement an atomic variable and check if the new value is zero. + * @param v a pointer to an opaque atomic variable + * @return + * true (non-zero) if the new value is zero, + * or false (0) if the new value is non-zero + */ +static inline a_uint32_t +adf_os_atomic_dec_and_test(adf_os_atomic_t *v) +{ + return __adf_os_atomic_dec_and_test(v); +} + +/** + * @brief Set a value to the value of an atomic variable. + * @param v a pointer to an opaque atomic variable + * @param i the amount by which to increase the atomic counter + */ +static inline void +adf_os_atomic_set(adf_os_atomic_t *v, int i) +{ + __adf_os_atomic_set(v, i); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_bitops.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_bitops.h new file mode 100644 index 0000000000000..42a64d797124a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_bitops.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_bitops.h + * This file abstracts bit-level operations on a stream of bytes. + */ + +#ifndef _ADF_OS_BITOPS_H +#define _ADF_OS_BITOPS_H + +#include + +/** + * @brief Set a bit atomically + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_set_bit_a(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_set_bit_a(nr, addr); +} + +/** + * @brief Set a bit + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_set_bit(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_set_bit(nr, addr); +} + +/** + * @brief Clear a bit atomically + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_clear_bit_a(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_clear_bit_a(nr, addr); +} + +/** + * @brief Clear a bit + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_clear_bit(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_clear_bit(nr, addr); +} + +/** + * @brief Toggle a bit atomically + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_change_bit_a(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_change_bit_a(nr, addr); +} + +/** + * @brief Toggle a bit + * @param[in] nr Bit to change + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_change_bit(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_change_bit(nr, addr); +} + +/** + * @brief Test and Set a bit atomically + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_set_bit_a(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_set_bit_a(nr, addr); +} + +/** + * @brief Test and Set a bit + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_set_bit(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_set_bit(nr, addr); +} + +/** + * @brief Test and clear a bit atomically + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_clear_bit_a(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_clear_bit_a(nr, addr); +} + +/** + * @brief Test and clear a bit + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_clear_bit(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_clear_bit(nr, addr); +} + +/** + * @brief Test and change a bit atomically + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its atomic and cannot be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_change_bit_a(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_change_bit_a(nr, addr); +} + +/** + * @brief Test and clear a bit + * @param[in] nr Bit to set + * @param[in] addr Address to start counting from + * + * @note its not atomic and can be re-ordered. + * Note that nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static inline void adf_os_test_and_change_bit(a_uint32_t nr, + volatile a_uint32_t *addr) +{ + __adf_os_test_and_change_bit(nr, addr); +} + +/** + * @brief test_bit - Determine whether a bit is set + * @param[in] nr bit number to test + * @param[in] addr Address to start counting from + * + * @return 1 if set, 0 if not + */ +static inline int adf_os_test_bit(a_uint32_t nr, volatile a_uint32_t *addr) +{ + __adf_os_test_bit(nr, addr); +} + + +#endif /**_AOD_BITOPS_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_defer.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_defer.h new file mode 100644 index 0000000000000..2ec5635c0758b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_defer.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_defer.h + * This file abstracts deferred execution contexts. + */ + +#ifndef __ADF_OS_DEFER_H +#define __ADF_OS_DEFER_H + +#include +#include + +/** + * TODO This implements work queues (worker threads, kernel threads etc.). + * Note that there is no cancel on a scheduled work. You cannot free a work + * item if its queued. You cannot know if a work item is queued or not unless + * its running, whence you know its not queued. + * + * so if, say, a module is asked to unload itself, how exactly will it make + * sure that the work's not queued, for OS'es that dont provide such a + * mechanism?? + */ + +/** + * @brief Representation of a work queue. + */ +typedef __adf_os_work_t adf_os_work_t; +typedef __adf_os_delayed_work_t adf_os_delayed_work_t; +typedef __adf_os_workqueue_t adf_os_workqueue_t; +/** + * @brief Representation of a bottom half. + */ +typedef __adf_os_bh_t adf_os_bh_t; + + + +/** + * @brief This creates the Bottom half deferred handler + * + * @param[in] hdl OS handle + * @param[in] bh bottom instance + * @param[in] func deferred function to run at bottom half interrupt + * context. + * @param[in] arg argument for the deferred function + */ +static inline void +adf_os_create_bh(adf_os_handle_t hdl, adf_os_bh_t *bh, + adf_os_defer_fn_t func,void *arg) +{ + __adf_os_init_bh(hdl, bh, func, arg); +} + + +/** + * @brief schedule a bottom half (DPC) + * + * @param[in] hdl OS handle + * @param[in] bh bottom instance + */ +static inline void +adf_os_sched_bh(adf_os_handle_t hdl, adf_os_bh_t *bh) +{ + __adf_os_sched_bh(hdl, bh); +} + +/** + * @brief destroy the bh (synchronous) + * + * @param[in] hdl OS handle + * @param[in] bh bottom instance + */ +static inline void +adf_os_destroy_bh(adf_os_handle_t hdl, adf_os_bh_t *bh) +{ + __adf_os_disable_bh(hdl,bh); +} + +/*********************Non-Interrupt Context deferred Execution***************/ + +/** + * @brief create a work/task queue, This runs in non-interrupt + * context, so can be preempted by H/W & S/W intr + * + * @param[in] hdl OS handle + * @param[in] work work instance + * @param[in] func deferred function to run at bottom half non-interrupt + * context. + * @param[in] arg argument for the deferred function + */ +static inline void +adf_os_create_work(adf_os_handle_t hdl, adf_os_work_t *work, + adf_os_defer_fn_t func, void *arg) +{ + __adf_os_init_work(hdl, work, func, arg); +} + +static inline void +adf_os_create_delayed_work(adf_os_handle_t hdl, adf_os_delayed_work_t *work, + adf_os_defer_fn_t func, void *arg) +{ + __adf_os_init_delayed_work(hdl, work, func, arg); +} + +static inline adf_os_workqueue_t* +adf_os_create_workqueue(char *name) +{ + return __adf_os_create_workqueue(name); +} + +static inline void +adf_os_queue_work(adf_os_handle_t hdl, adf_os_workqueue_t *wqueue, adf_os_work_t* work) +{ + return __adf_os_queue_work(hdl, wqueue, work); +} + +static inline void +adf_os_queue_delayed_work(adf_os_handle_t hdl, adf_os_workqueue_t *wqueue, adf_os_delayed_work_t* work, a_uint32_t delay) +{ + return __adf_os_queue_delayed_work(hdl, wqueue, work, delay); +} + +static inline void +adf_os_flush_workqueue(adf_os_handle_t hdl, adf_os_workqueue_t *wqueue) +{ + return __adf_os_flush_workqueue(hdl, wqueue); +} + +static inline void +adf_os_destroy_workqueue(adf_os_handle_t hdl, adf_os_workqueue_t *wqueue) +{ + return __adf_os_destroy_workqueue(hdl, wqueue); +} + +/** + * @brief Schedule a deferred task on non-interrupt context + * + * @param[in] hdl OS handle + * @param[in] work work instance + */ +static inline void +adf_os_sched_work(adf_os_handle_t hdl, adf_os_work_t *work) +{ + __adf_os_sched_work(hdl, work); +} + +/** + *@brief destroy the deferred task (synchronous) + * + *@param[in] hdl OS handle + *@param[in] work work instance + */ +static inline void +adf_os_destroy_work(adf_os_handle_t hdl, adf_os_work_t *work) +{ + __adf_os_disable_work(hdl, work); +} + + +/** + * XXX API to specify processor while scheduling a bh => only on vista + */ + + +#endif /*_ADF_OS_DEFER_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_dma.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_dma.h new file mode 100644 index 0000000000000..f18bcdeb9022c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_dma.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @ingroup adf_os_public + * @file adf_os_dma.h + * This file abstracts DMA operations. + */ + +#ifndef _ADF_OS_DMA_H +#define _ADF_OS_DMA_H + +#include +#include + +/* + * @brief a dma address representation of a platform + */ + +/** + * @brief Allocate a DMA buffer and map it to local bus address space + * + * @param[in] osdev platform device instance + * @param[in] size DMA buffer size + * @param[in] coherent 0 => cached. + * @param[out] dmap opaque coherent memory handle + * + * @return returns the virtual address of the memory + */ +static inline void * +adf_os_dmamem_alloc(adf_os_device_t osdev, + adf_os_size_t size, + a_bool_t coherent, + adf_os_dma_map_t *dmap) +{ + return __adf_os_dmamem_alloc(osdev, size, coherent, dmap); +} + +/** + * @brief Free a previously mapped DMA buffer + * + * @param[in] osdev platform device instance + * @param[in] size DMA buffer size + * @param[in] coherent 0 => cached. + * @param[in] vaddr virtual address of DMA buffer + * @param[in] dmap memory handle + */ +static inline void +adf_os_dmamem_free(adf_os_device_t osdev, + adf_os_size_t size, + a_bool_t coherent, + void *vaddr, + adf_os_dma_map_t dmap) +{ + __adf_os_dmamem_free(osdev, size, coherent, vaddr, dmap); +} + +/** + * @brief given a dmamem map, returns the (bus) address + * + * @param[in] dmap memory handle + * + * @return the (bus) address + */ +static inline adf_os_dma_addr_t +adf_os_dmamem_map2addr(adf_os_dma_map_t dmap) +{ + return(__adf_os_dmamem_map2addr(dmap)); +} + +/** + * @brief Flush and invalidate cache for a given dmamem map + * + * @param[in] osdev platform device instance + * @param[in] dmap mem handle + * @param[in] op op code for sync type, (see @ref adf_os_types.h) + */ +static inline void +adf_os_dmamem_cache_sync(adf_os_device_t osdev, + adf_os_dma_map_t dmap, + adf_os_cache_sync_t op) +{ + __adf_os_dmamem_cache_sync(osdev, dmap, op); +} + +/** + * @brief Get the cpu cache line size + * + * @return The CPU cache line size in bytes. + */ +static inline adf_os_size_t +adf_os_cache_line_size(void) +{ + return __adf_os_cache_line_size(); +} + +/** + * @brief invalidate the virtual address range specified by + * start and end addresses. + * Note: This does not write back the cache entries. + * + * @return void + */ +static inline void +adf_os_invalidate_range(void * start, void * end) +{ + return __adf_os_invalidate_range(start, end); +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_io.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_io.h new file mode 100644 index 0000000000000..40baece1d63c5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_io.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_io.h + * This file abstracts I/O operations. + */ + +#ifndef _ADF_OS_IO_H +#define _ADF_OS_IO_H + +#include + + +/** + * @brief Read an 8-bit register value + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * + * @return An 8-bit register value. + */ +#define adf_os_reg_read8(osdev, addr) __adf_os_reg_read8(osdev, addr) + +/** + * @brief Read a 16-bit register value + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * + * @return A 16-bit register value. + */ +#define adf_os_reg_read16(osdev, addr) __adf_os_reg_read16(osdev, addr) + +/** + * @brief Read a 32-bit register value + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * + * @return A 32-bit register value. + */ +#define adf_os_reg_read32(osdev, addr) __adf_os_reg_read32(osdev, addr) + +/** + * @brief Read a 64-bit register value + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * + * @return A 64-bit register value. + */ +#define adf_os_reg_read64(osdev, addr) __adf_os_reg_read64(osdev, addr) + +/** + * @brief Write an 8-bit value into register + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * @param[in] b the 8-bit value to be written + */ +#define adf_os_reg_write8(osdev, addr, b) __adf_os_reg_write8(osdev, addr, b) + +/** + * @brief Write a 16-bit value into register + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * @param[in] w the 16-bit value to be written + */ +#define adf_os_reg_write16(osdev, addr, w) __adf_os_reg_write16(osdev, addr, w) + +/** + * @brief Write a 32-bit value into register + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * @param[in] l the 32-bit value to be written + */ +#define adf_os_reg_write32(osdev, addr, l) __adf_os_reg_write32(osdev, addr, l) + +/** + * @brief Write a 64-bit value into register + * + * @param[in] osdev platform device object + * @param[in] addr register addr + * @param[in] q the 64-bit value to be written + */ +#define adf_os_reg_write64(osdev, addr, q) __adf_os_reg_write64(osdev, addr, q) + + +/** + * @brief io remaps a physical address to a i/o address + * + * @param[in] addr physical address + * @param[in] size size of memeory to be remaped + */ +#define adf_os_ioremap(addr, size) __adf_os_ioremap(addr, size) + +/** + * @brief Convert a 16-bit value from network byte order to host byte order + */ +#define adf_os_ntohs(x) __adf_os_ntohs(x) + +/** + * @brief Convert a 32-bit value from network byte order to host byte order + */ +#define adf_os_ntohl(x) __adf_os_ntohl(x) + +/** + * @brief Convert a 16-bit value from host byte order to network byte order + */ +#define adf_os_htons(x) __adf_os_htons(x) + +/** + * @brief Convert a 32-bit value from host byte order to network byte order + */ +#define adf_os_htonl(x) __adf_os_htonl(x) + +/** + * @brief Convert a 16-bit value from CPU byte order to big-endian byte order + */ +#define adf_os_cpu_to_be16(x) __adf_os_cpu_to_be16(x) + +/** + * @brief Convert a 32-bit value from CPU byte order to big-endian byte order + */ +#define adf_os_cpu_to_be32(x) __adf_os_cpu_to_be32(x) + +/** + * @brief Convert a 64-bit value from CPU byte order to big-endian byte order + */ +#define adf_os_cpu_to_be64(x) __adf_os_cpu_to_be64(x) + +/** + * @brief Convert a 16-bit value from CPU byte order to little-endian byte order + */ +#define adf_os_cpu_to_le16(x) __adf_os_cpu_to_le16(x) + +/** + * @brief Convert a 32-bit value from CPU byte order to little-endian byte order + */ +#define adf_os_cpu_to_le32(x) __adf_os_cpu_to_le32(x) + +/** + * @brief Convert a 64-bit value from CPU byte order to little-endian byte order + */ +#define adf_os_cpu_to_le64(x) __adf_os_cpu_to_le64(x) + +/** + * @brief Convert a 16-bit value from big-endian byte order to CPU byte order + */ +#define adf_os_be16_to_cpu(x) __adf_os_be16_to_cpu(x) + +/** + * @brief Convert a 32-bit value from big-endian byte order to CPU byte order + */ +#define adf_os_be32_to_cpu(x) __adf_os_be32_to_cpu(x) + +/** + * @brief Convert a 64-bit value from big-endian byte order to CPU byte order + */ +#define adf_os_be64_to_cpu(x) __adf_os_be64_to_cpu(x) + +/** + * @brief Convert a 16-bit value from little-endian byte order to CPU byte order + */ +#define adf_os_le16_to_cpu(x) __adf_os_le16_to_cpu(x) + +/** + * @brief Convert a 32-bit value from little-endian byte order to CPU byte order + */ +#define adf_os_le32_to_cpu(x) __adf_os_le32_to_cpu(x) + +/** + * @brief Convert a 64-bit value from little-endian byte order to CPU byte order + */ +#define adf_os_le64_to_cpu(x) __adf_os_le64_to_cpu(x) + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.c new file mode 100644 index 0000000000000..77104a4fc9130 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include + +void adf_os_spin_lock_bh_outline(adf_os_spinlock_t *lock) +{ + adf_os_spin_lock_bh(lock); +} + +void adf_os_spin_unlock_bh_outline(adf_os_spinlock_t *lock) +{ + adf_os_spin_unlock_bh(lock); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.h new file mode 100644 index 0000000000000..9e0a733e36ad6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_lock.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_lock.h + * This file abstracts locking operations. + */ + +#ifndef _ADF_OS_LOCK_H +#define _ADF_OS_LOCK_H + +#include +#include + +/** + * @brief Platform spinlock object + */ +typedef __adf_os_spinlock_t adf_os_spinlock_t; +/** + * @brief Platform mutex object + */ +typedef __adf_os_mutex_t adf_os_mutex_t; + + + +/** + * @brief Initialize a mutex + * + * @param[in] m mutex to initialize + */ +static inline void adf_os_init_mutex(adf_os_mutex_t *m) +{ + __adf_os_init_mutex(m); +} + + +/** + * @brief Take the mutex + * + * @param[in] m mutex to take + */ +static inline int adf_os_mutex_acquire(adf_os_device_t osdev, adf_os_mutex_t *m) +{ + return (__adf_os_mutex_acquire(osdev, m)); +} + +/** + * @brief Give the mutex + * + * @param[in] m mutex to give + */ +static inline void adf_os_mutex_release(adf_os_device_t osdev, adf_os_mutex_t *m) +{ + __adf_os_mutex_release(osdev, m); +} +/** + * @brief Platform specific semaphore object + */ +typedef __adf_os_mutex_t adf_os_sem_t; +#define adf_os_sem_init adf_os_init_mutex +#define adf_os_sem_acquire adf_os_mutex_acquire +#define adf_os_sem_release adf_os_mutex_release + + +/** + * @brief Initialize a spinlock + * + * @param[in] lock spinlock object pointer + */ +static inline void +adf_os_spinlock_init(adf_os_spinlock_t *lock) +{ + __adf_os_spinlock_init(lock); +} + +/** + * @brief Delete a spinlock + * + * @param[in] lock spinlock object pointer + */ +static inline void +adf_os_spinlock_destroy(adf_os_spinlock_t *lock) +{ + __adf_os_spinlock_destroy(lock); +} + +#define adf_os_spin_lock( _lock) __adf_os_spin_lock(_lock) +#define adf_os_spin_unlock( _lock ) __adf_os_spin_unlock(_lock) +#define adf_os_spin_lock_irqsave( _lock) __adf_os_spin_lock_irqsave(_lock) +#define adf_os_spin_unlock_irqrestore( _lock ) \ + __adf_os_spin_unlock_irqrestore(_lock) + +/** + * @brief locks the spinlock mutex in soft irq context + * + * @param[in] lock spinlock object pointer + */ +static inline void +adf_os_spin_lock_bh(adf_os_spinlock_t *lock) +{ + __adf_os_spin_lock_bh(lock); +} + +void adf_os_spin_lock_bh_outline(adf_os_spinlock_t *lock); + +/** + * @brief unlocks the spinlock mutex in soft irq context + * + * @param[in] lock spinlock object pointer + */ +static inline void +adf_os_spin_unlock_bh(adf_os_spinlock_t *lock) +{ + __adf_os_spin_unlock_bh(lock); +} + +void adf_os_spin_unlock_bh_outline(adf_os_spinlock_t *lock); + +/** + * @brief Execute the input function with spinlock held and interrupt disabled. + * + * @param[in] hdl OS handle + * @param[in] lock spinlock to be held for the critical region + * @param[in] func critical region function that to be executed + * @param[in] context context of the critical region function + * + * @return Boolean status returned by the critical region function + */ +static inline a_bool_t +adf_os_spinlock_irq_exec(adf_os_handle_t hdl, + adf_os_spinlock_t *lock, + adf_os_irqlocked_func_t func, + void *arg) +{ + return __adf_os_spinlock_irq_exec(hdl, lock, func, arg); +} + +/** + * @brief locks the spinlock in irq context + * + * @param[in] lock spinlock object pointer + * @param[in] flags flags value + * + */ +#define adf_os_spin_lock_irq(_pLock, _flags) __adf_os_spin_lock_irq(_pLock, _flags) +#define adf_os_spin_unlock_irq(_pLock, _flags) __adf_os_spin_unlock_irq(_pLock, _flags) + +#define adf_os_in_softirq() __adf_os_in_softirq() + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.c new file mode 100644 index 0000000000000..e28d099db8471 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include + +void * +adf_os_mem_alloc_outline(adf_os_device_t osdev, size_t size) +{ + return __adf_os_mem_alloc(osdev, size); +} + +void +adf_os_mem_free_outline(void *buf) +{ + __adf_os_mem_free(buf); +} + +void +adf_os_mem_zero_outline(void *buf, adf_os_size_t size) +{ + __adf_os_mem_zero(buf, size); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.h new file mode 100644 index 0000000000000..5bd278be4a99c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_mem.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @ingroup adf_os_public + * @file adf_os_mem.h + * This file abstracts memory operations. + */ + +#ifndef _ADF_OS_MEM_H +#define _ADF_OS_MEM_H + +#include +#include +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC +#ifdef CONFIG_CNSS +#include +#else +#include +#endif +#endif + +/** + * @brief Allocate a memory buffer. Note this call can block. + * + * @param[in] size buffer size + * + * @return Buffer pointer or NULL if there's not enough memory. + */ +static inline void * +adf_os_mem_alloc(adf_os_device_t osdev, adf_os_size_t size) +{ +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + void *p_mem; +#endif + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD) + { + p_mem = wcnss_prealloc_get(size); + if (NULL != p_mem) + return p_mem; + } +#endif + + return __adf_os_mem_alloc(osdev, size); +} + +void * +adf_os_mem_alloc_outline(adf_os_device_t osdev, adf_os_size_t size); + +/** + * @brief Free malloc'ed buffer + * + * @param[in] buf buffer pointer allocated by @ref adf_os_mem_alloc + */ +static inline void +adf_os_mem_free(void *buf) +{ +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if (wcnss_prealloc_put(buf)) + { + return; + } +#endif + + __adf_os_mem_free(buf); +} + +void +adf_os_mem_free_outline(void *buf); + +static inline void * +adf_os_mem_alloc_consistent( + adf_os_device_t osdev, adf_os_size_t size, adf_os_dma_addr_t *paddr, adf_os_dma_context_t mctx) +{ + return __adf_os_mem_alloc_consistent(osdev, size, paddr, mctx); +} + +static inline void +adf_os_mem_free_consistent( + adf_os_device_t osdev, + adf_os_size_t size, + void *vaddr, + adf_os_dma_addr_t paddr, + adf_os_dma_context_t memctx) +{ + __adf_os_mem_free_consistent(osdev, size, vaddr, paddr, memctx); +} + +/** + * @brief Move a memory buffer. Overlapping regions are not allowed. + * + * @param[in] dst destination address + * @param[in] src source address + * @param[in] size buffer size + */ +static inline __ahdecl void +adf_os_mem_copy(void *dst, const void *src, adf_os_size_t size) +{ + __adf_os_mem_copy(dst, src, size); +} + +/** + * @brief Does a non-destructive copy of memory buffer + * + * @param[in] dst destination address + * @param[in] src source address + * @param[in] size buffer size + */ +static inline void +adf_os_mem_move(void *dst, void *src, adf_os_size_t size) +{ + __adf_os_mem_move(dst,src,size); +} + + +/** + * @brief Fill a memory buffer + * + * @param[in] buf buffer to be filled + * @param[in] b byte to fill + * @param[in] size buffer size + */ +static inline void +adf_os_mem_set(void *buf, a_uint8_t b, adf_os_size_t size) +{ + __adf_os_mem_set(buf, b, size); +} + + +/** + * @brief Zero a memory buffer + * + * @param[in] buf buffer to be zeroed + * @param[in] size buffer size + */ +static inline __ahdecl void +adf_os_mem_zero(void *buf, adf_os_size_t size) +{ + __adf_os_mem_zero(buf, size); +} + +void +adf_os_mem_zero_outline(void *buf, adf_os_size_t size); + +/** + * @brief Compare two memory buffers + * + * @param[in] buf1 first buffer + * @param[in] buf2 second buffer + * @param[in] size buffer size + * + * @retval 0 equal + * @retval 1 not equal + */ +static inline int +adf_os_mem_cmp(const void *buf1, const void *buf2, adf_os_size_t size) +{ + return __adf_os_mem_cmp(buf1, buf2, size); +} + +/** + * @brief Compare two strings + * + * @param[in] str1 First string + * @param[in] str2 Second string + * + * @retval 0 equal + * @retval >0 not equal, if str1 sorts lexicographically after str2 + * @retval <0 not equal, if str1 sorts lexicographically before str2 + */ +static inline a_int32_t +adf_os_str_cmp(const char *str1, const char *str2) +{ + return __adf_os_str_cmp(str1, str2); +} + +/** + * @brief Returns the length of a string + * + * @param[in] str input string + * + * @return length of string + */ +static inline a_int32_t +adf_os_str_len(const char *str) +{ + return (a_int32_t)__adf_os_str_len(str); +} + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_module.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_module.h new file mode 100644 index 0000000000000..a67a9d678d772 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_module.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_module.h + * This file abstracts "kernel module" semantics. + */ + +#ifndef _ADF_OS_MODULE_H +#define _ADF_OS_MODULE_H + +#include + +typedef a_status_t (*module_init_func_t)(void); + +/** + * @brief Specify the module's entry point. + */ +#define adf_os_virt_module_init(_mod_init_func) __adf_os_virt_module_init(_mod_init_func) + +/** + * @brief Specify the module's exit point. + */ +#define adf_os_virt_module_exit(_mod_exit_func) __adf_os_virt_module_exit(_mod_exit_func) + +/** + * @brief Specify the module's name. + */ +#define adf_os_virt_module_name(_name) __adf_os_virt_module_name(_name) + +/** + * @brief Specify the module's dependency on another module. + */ +#define adf_os_module_dep(_name,_dep) __adf_os_module_dep(_name,_dep) +/** + * @brief Module parameter of type char + */ +#define ADF_OS_PARAM_TYPE_INT8 __ADF_OS_PARAM_TYPE_INT8 + +/** + * @brief Module parameter of type unsigned char + */ +#define ADF_OS_PARAM_TYPE_UINT8 __ADF_OS_PARAM_TYPE_UINT8 +/** + * @brief Module parameter of type short + */ +#define ADF_OS_PARAM_TYPE_INT16 __ADF_OS_PARAM_TYPE_INT16 + +/** + * @brief Module parameter of type unsigned short + */ +#define ADF_OS_PARAM_TYPE_UINT16 __ADF_OS_PARAM_TYPE_UINT16 + +/** + * @brief Module parameter of type integer. + */ +#define ADF_OS_PARAM_TYPE_INT32 __ADF_OS_PARAM_TYPE_INT32 + +/** + * @brief Module parameter of type unsigned integer. + */ +#define ADF_OS_PARAM_TYPE_UINT32 __ADF_OS_PARAM_TYPE_UINT32 + +/** + * @brief Module parameter of type string. + */ +#define ADF_OS_PARAM_TYPE_STRING __ADF_OS_PARAM_TYPE_STRING + +/** + * @brief Export a symbol from a module. + */ +#define adf_os_export_symbol(_sym) __adf_os_export_symbol(_sym) +/** + * @brief Declare a module parameter. + + */ +#define adf_os_declare_param(name, type) __adf_os_declare_param(name, type) + +/** + * @brief Read a parameter's value + * + */ +#define adf_os_read_param(osdev, name, type, pval) \ + __adf_os_read_param(osdev, name, type, pval) + +#endif /*_ADF_OS_MODULE_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_stdtypes.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_stdtypes.h new file mode 100644 index 0000000000000..a4f07ead473f5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_stdtypes.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @defgroup adf_os_public OS abstraction API + */ + +/** + * @ingroup adf_os_public + * @file adf_os_stdtypes.h + * This file defines standard types. + */ + +#ifndef _ADF_OS_STDTYPES_H +#define _ADF_OS_STDTYPES_H +#include +#include + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_time.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_time.h new file mode 100644 index 0000000000000..a60e5bfcbebaf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_time.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_time.h + * This file abstracts time related functionality. + */ +#ifndef _ADF_OS_TIME_H +#define _ADF_OS_TIME_H + +#include +#ifdef CONFIG_CNSS +#include +#endif + +typedef __adf_time_t adf_os_time_t; + +/** + * @brief count the number of ticks elapsed from the time when + * the system booted + * + * @return ticks + */ +static inline unsigned long +adf_os_ticks(void) +{ + return __adf_os_ticks(); +} + +/** + * @brief convert ticks to milliseconds + * + * @param[in] ticks number of ticks + * @return time in milliseconds + */ +static inline a_uint32_t +adf_os_ticks_to_msecs(unsigned long clock_ticks) +{ + return (__adf_os_ticks_to_msecs(clock_ticks)); +} + +/** + * @brief convert milliseconds to ticks + * + * @param[in] time in milliseconds + * @return number of ticks + */ +static inline unsigned long +adf_os_msecs_to_ticks(a_uint32_t msecs) +{ + return (__adf_os_msecs_to_ticks(msecs)); +} + +/** + * @brief Return a monotonically increasing time. This increments once per HZ ticks + */ +static inline unsigned long +adf_os_getuptime(void) +{ + return (__adf_os_getuptime()); +} + +/** + * @brief Return current timestamp. + */ +static inline unsigned long +adf_os_gettimestamp(void) +{ + return (__adf_os_gettimestamp()); +} + +/** + * @brief Delay in microseconds + * + * @param[in] microseconds to delay + */ +static inline void +adf_os_udelay(int usecs) +{ + __adf_os_udelay(usecs); +} + +/** + * @brief Delay in milliseconds. + * + * @param[in] milliseconds to delay + */ +static inline void +adf_os_mdelay(int msecs) +{ + __adf_os_mdelay(msecs); +} + +/** + * @brief Check if _a is later than _b. + */ +#define adf_os_time_after(_a, _b) __adf_os_time_after(_a, _b) + +/** + * @brief Check if _a is prior to _b. + */ +#define adf_os_time_before(_a, _b) __adf_os_time_before(_a, _b) + +/** + * @brief Check if _a atleast as recent as _b, if not later. + */ +#define adf_os_time_after_eq(_a, _b) __adf_os_time_after_eq(_a, _b) + +/** + * @brief Get kernel boot time. + * + * @return Time in microseconds + */ +static inline a_uint64_t adf_get_boottime(void) +{ +#ifdef CONFIG_CNSS + struct timespec ts; + + cnss_get_boottime(&ts); + + return (((a_uint64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000)); +#else + return adf_os_ticks_to_msecs(adf_os_ticks()) * 1000; +#endif /* CONFIG_CNSS */ +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_timer.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_timer.h new file mode 100644 index 0000000000000..fdbe31227cf6b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_timer.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/** + * @ingroup adf_os_public + * @file adf_os_timer.h + * This file abstracts OS timers. + */ + +#ifndef _ADF_OS_TIMER_H +#define _ADF_OS_TIMER_H + +#include +#include + + +/** + * @brief Platform timer object + */ +typedef __adf_os_timer_t adf_os_timer_t; + + +/** + * @brief Initialize a timer + * + * @param[in] hdl OS handle + * @param[in] timer timer object pointer + * @param[in] func timer function + * @param[in] context context of timer function + */ +static inline void +adf_os_timer_init(adf_os_handle_t hdl, + adf_os_timer_t *timer, + adf_os_timer_func_t func, + void *arg, + uint8_t type) +{ + __adf_os_timer_init(hdl, timer, func, arg, type); +} + +/** + * @brief Start a one-shot timer + * + * @param[in] timer timer object pointer + * @param[in] msec expiration period in milliseconds + */ +static inline void +adf_os_timer_start(adf_os_timer_t *timer, int msec) +{ + __adf_os_timer_start(timer, msec); +} + +/** + * @brief Modify existing timer to new timeout value + * + * @param[in] timer timer object pointer + * @param[in] msec expiration period in milliseconds + */ +static inline void +adf_os_timer_mod(adf_os_timer_t *timer, int msec) +{ + __adf_os_timer_mod(timer, msec); +} + +/** + * @brief Cancel a timer + * The function will return after any running timer completes. + * + * @param[in] timer timer object pointer + * + * @retval TRUE timer was cancelled and deactived + * @retval FALSE timer was cancelled but already got fired. + */ +static inline a_bool_t +adf_os_timer_cancel(adf_os_timer_t *timer) +{ + return __adf_os_timer_cancel(timer); +} + +/** + * @brief Free a timer + * The function will return after any running timer completes. + * + * @param[in] timer timer object pointer + * + */ +static inline void +adf_os_timer_free(adf_os_timer_t *timer) +{ + __adf_os_timer_free(timer); +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_types.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_types.h new file mode 100644 index 0000000000000..5a67902711ef5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_types.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @ingroup adf_os_public + * @file adf_os_types.h + * This file defines types used in the OS abstraction API. + */ + +#ifndef _ADF_OS_TYPES_H +#define _ADF_OS_TYPES_H + + +#include +#include + +#ifndef __ahdecl +#ifdef __i386__ +#define __ahdecl __attribute__((regparm(0))) +#else +#define __ahdecl +#endif +#endif + +#define ADF_OS_MAX_SCATTER __ADF_OS_MAX_SCATTER +/** + * @brief Max number of scatter-gather segments. + */ +#define ADF_OS_MAX_SGLIST 4 + +/** + * @brief denotes structure is packed. + */ +#define adf_os_packed __adf_os_packed + +/** + * @brief handles opaque to each other + */ +typedef void * adf_net_handle_t; + +typedef void * adf_netlink_handle_t; +typedef void * adf_drv_handle_t; +typedef void * adf_os_handle_t; + +/* + * XXX FIXME For compilation only. + * + */ +typedef void * adf_os_pm_t; + +/** + * @brief Platform/bus generic handle. Used for bus specific functions. + */ +typedef __adf_os_device_t adf_os_device_t; + +/** + * @brief size of an object + */ +typedef __adf_os_size_t adf_os_size_t; + +/** + * @brief offset for API's that need them. + */ +typedef __adf_os_off_t adf_os_off_t; + +/** + * @brief abstraction for completion structure + */ +typedef __adf_os_comp_t adf_os_comp_t; +/** + * @brief DMA mapping object. + */ +typedef __adf_os_dma_map_t adf_os_dma_map_t; + +/** + * @brief DMA address. + */ +typedef __adf_os_dma_addr_t adf_os_dma_addr_t; + +/** + * @brief DMA size. + */ +typedef __adf_os_dma_size_t adf_os_dma_size_t; + +/** + * @brief DMA context. + */ +typedef __adf_os_dma_context_t adf_os_dma_context_t; + +/** + * @brief Information inside a DMA map. + */ +typedef struct adf_os_dmamap_info{ + a_uint32_t nsegs; /**< total number mapped segments*/ + struct __dma_segs{ + adf_os_dma_addr_t paddr; /**< physical(dma'able) address of the segment*/ + adf_os_dma_size_t len; /**< length of the segment*/ + } dma_segs[ADF_OS_MAX_SCATTER]; + +}adf_os_dmamap_info_t; + +/** + * @brief Representation of a scatter-gather list. + */ +typedef struct adf_os_sglist{ + a_uint32_t nsegs; /**< total number of segments*/ + struct __sg_segs{ + a_uint8_t *vaddr; /**< Virtual address of the segment*/ + a_uint32_t len; /**< Length of the segment*/ + } sg_segs[ADF_OS_MAX_SGLIST]; + +}adf_os_sglist_t; + +/** + * @brief All operations specified below are performed from + * the host memory point of view, where a read + * implies data coming from the device to the host + * memory, and a write implies data going from the + * host memory to the device. Alternately, the + * operations can be thought of in terms of driver + * operations, where reading a network packet or + * storage sector corresponds to a read operation in + * bus_dma. + * + * ADF_SYNC_PREREAD Perform any synchronization + * required prior to an update + * of host memory by the DMA + * read operation. + * ADF_SYNC_PREWRITE Perform any synchronization + * required after an update of + * host memory by the CPU and + * prior to DMA write + * operations. + * ADF_SYNC_POSTREAD Perform any synchronization + * required after DMA read + * operations and prior to CPU + * access to host + * memory. + * ADF_SYNC_POSTWRITE Perform any synchronization + * required after DMA write + * operations. + */ + +typedef enum adf_os_cache_sync{ + ADF_SYNC_PREREAD=__ADF_SYNC_PREREAD, + ADF_SYNC_PREWRITE=__ADF_SYNC_PREWRITE, + ADF_SYNC_POSTREAD=__ADF_SYNC_POSTREAD, + ADF_SYNC_POSTWRITE=__ADF_SYNC_POSTWRITE +}adf_os_cache_sync_t; + +/** + * @brief Generic status to be used by adf_drv. + */ +/** + * @brief An ecore needs to provide a table of all pci device/vendor id's it + * supports + * + * This table should be terminated by a NULL entry , i.e. {0} + */ +typedef struct { + a_uint32_t vendor; + a_uint32_t device; + a_uint32_t subvendor; + a_uint32_t subdevice; +}adf_os_pci_dev_id_t; + +#define ADF_OS_PCI_ANY_ID (~0) + +/** + * @brief Typically core's can use this macro to create a table of various device + * ID's + */ +#define ADF_OS_PCI_DEVICE(_vendor, _device) \ + (_vendor), (_device), ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID + + +#define adf_os_iomem_t __adf_os_iomem_t; +/** + * @brief These define the hw resources the OS has allocated for the device + * Note that start defines a mapped area. + */ +typedef enum { + ADF_OS_RESOURCE_TYPE_MEM, + ADF_OS_RESOURCE_TYPE_IO, +}adf_os_resource_type_t; + +/** + * @brief Representation of a h/w resource. + */ +typedef struct { + a_uint64_t start; + a_uint64_t end; + adf_os_resource_type_t type; +}adf_os_resource_t; + +#define ADF_OS_DEV_ID_TABLE_MAX 256 + +/** + * @brief Representation of bus registration data. + */ +typedef union { + adf_os_pci_dev_id_t *pci; + void *raw; +}adf_os_bus_reg_data_t; + +/** + * @brief Representation of data required for attach. + */ +typedef union { + adf_os_pci_dev_id_t pci; + void *raw; +}adf_os_attach_data_t; + +#define ADF_OS_REGIONS_MAX 5 + +/** + * @brief Types of buses. + */ +typedef enum { + ADF_OS_BUS_TYPE_PCI = 1, + ADF_OS_BUS_TYPE_GENERIC, +}adf_os_bus_type_t; + +/** + * @brief IRQ handler response codes. + */ +typedef enum { + ADF_OS_IRQ_NONE, + ADF_OS_IRQ_HANDLED, +}adf_os_irq_resp_t; + +/** + * @brief DMA mask types. + */ +typedef enum { + ADF_OS_DMA_MASK_32BIT, + ADF_OS_DMA_MASK_64BIT, +}adf_os_dma_mask_t; + + +/** + * @brief DMA directions + * ADF_OS_DMA_TO_DEVICE (data going from device to memory) + * ADF_OS_DMA_FROM_DEVICE (data going from memory to device) + */ +typedef enum { + ADF_OS_DMA_BIDIRECTIONAL = __ADF_OS_DMA_BIDIRECTIONAL, + ADF_OS_DMA_TO_DEVICE = __ADF_OS_DMA_TO_DEVICE, + ADF_OS_DMA_FROM_DEVICE = __ADF_OS_DMA_FROM_DEVICE, +} adf_os_dma_dir_t; + +/* + * Protoypes shared between public and private headers + */ + + +/** + * @brief work queue(kernel thread)/DPC function callback + */ +typedef void (*adf_os_defer_fn_t)(void *); + +/** + * @brief Prototype of the critical region function that is to be + * executed with spinlock held and interrupt disalbed + */ +typedef a_bool_t (*adf_os_irqlocked_func_t)(void *); + + +/** + * @brief Prototype of timer function + */ +typedef void (*adf_os_timer_func_t)(void *); + +/** + * @brief Prototype of IRQ function. + */ +typedef adf_os_irq_resp_t (*adf_os_drv_intr)(adf_drv_handle_t hdl); + +/** + * @brief The OS print routine. + */ +#define adf_os_print __adf_os_print +#define adf_os_vprint __adf_os_vprint +#define adf_os_snprint __adf_os_snprint +#define adf_os_vsnprint __adf_os_vsnprint +#define adf_os_inline __adf_os_inline +/** + * @brief driver info structure needed while we do the register + * for the driver to the shim. + */ +typedef struct _adf_drv_info{ + /** + * @brief driver specific functions + */ + adf_drv_handle_t (*drv_attach) (adf_os_resource_t *res, int count, + adf_os_attach_data_t *data, + adf_os_device_t osdev); + void (*drv_detach) (adf_drv_handle_t hdl); + void (*drv_suspend) (adf_drv_handle_t hdl, adf_os_pm_t pm); + void (*drv_resume) (adf_drv_handle_t hdl); + /** + * @brief driver specific data + */ + adf_os_bus_type_t bus_type; + adf_os_bus_reg_data_t bus_data; + unsigned char *mod_name; + unsigned char *ifname; +}adf_drv_info_t; + +#define adf_os_offsetof(type, field) offsetof(type, field) + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_util.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_util.h new file mode 100644 index 0000000000000..5676ca8097dd7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/adf_os_util.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @ingroup adf_os_public + * @file adf_os_util.h + * This file defines utility functions. + */ + +#ifndef _ADF_OS_UTIL_H +#define _ADF_OS_UTIL_H + +#include + +/** + * @brief Compiler-dependent macro denoting code likely to execute. + */ +#define adf_os_unlikely(_expr) __adf_os_unlikely(_expr) + +/** + * @brief Compiler-dependent macro denoting code unlikely to execute. + */ +#define adf_os_likely(_expr) __adf_os_likely(_expr) + +/** + * @brief read memory barrier. + */ +#define adf_os_wmb() __adf_os_wmb() + +/** + * @brief write memory barrier. + */ +#define adf_os_rmb() __adf_os_rmb() + +/** + * @brief read + write memory barrier. + */ +#define adf_os_mb() __adf_os_mb() + +/** + * @brief return the lesser of a, b + */ +#define adf_os_min(_a, _b) __adf_os_min(_a, _b) + +/** + * @brief return the larger of a, b + */ +#define adf_os_max(_a, _b) __adf_os_max(_a, _b) + +/** + * @brief assert "expr" evaluates to false. + */ +#ifdef ADF_OS_DEBUG +#define adf_os_assert(expr) __adf_os_assert(expr) +#else +#define adf_os_assert(expr) +#endif /* ADF_OS_DEBUG */ + +/** + * @brief alway assert "expr" evaluates to false. + */ +#define adf_os_assert_always(expr) __adf_os_assert(expr) + +/** + * @brief warn & dump backtrace if expr evaluates true + */ +#define adf_os_warn(expr) __adf_os_warn(expr) +/** + * @brief supply pseudo-random numbers + */ +static inline void adf_os_get_rand(adf_os_handle_t hdl, + a_uint8_t *ptr, + a_uint32_t len) +{ + __adf_os_get_rand(hdl, ptr, len); +} + + + +/** + * @brief return the absolute value of a + */ +#define adf_os_abs(_a) __adf_os_abs(_a) + +/** + * @brief replace with the name of the current function + */ +#define adf_os_function __adf_os_function + + + +/** + * @brief return square root + */ + +/** + * @brief Math function for getting a square root + * + * @param[in] x Number to compute the sqaure root + * + * @return Sqaure root as integer + */ +static adf_os_inline a_uint32_t +adf_os_int_sqrt(a_uint32_t x) +{ + return __adf_os_int_sqrt(x); +} + +/** + * @brief initialize completion structure + * + * @param[in] ptr - completion structure + */ +static inline void +adf_os_init_completion(adf_os_comp_t *ptr) +{ + __adf_os_init_completion(ptr); +} + +/** + * @brief wait for completion till timeout + * @param[in] ptr - completion structure + * @param[in] timeout - timeout value in jiffies + * + * @Return: 0 if timed out, and positive on completion + */ +static inline unsigned long +adf_os_wait_for_completion_timeout(adf_os_comp_t *ptr, unsigned long timeout) +{ + return __adf_os_wait_for_completion_timeout(ptr, timeout); +} + +/** + * @brief wake up the thread waiting for this completion + * + * @param[in] ptr - completion structure + */ +static inline void +adf_os_complete(adf_os_comp_t *ptr) +{ + __adf_os_complete(ptr); +} +#endif /*_ADF_OS_UTIL_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h new file mode 100644 index 0000000000000..fa168f4d40b6c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h @@ -0,0 +1,1199 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * Linux implemenation of skbuf + */ +#ifndef _ADF_CMN_NET_PVT_BUF_H +#define _ADF_CMN_NET_PVT_BUF_H + +#include +#include +#include +#include +#include +#include + +#define __ADF_NBUF_NULL NULL + +/* + * Use socket buffer as the underlying implentation as skbuf . + * Linux use sk_buff to represent both packet and data, + * so we use sk_buffer to represent both skbuf . + */ +typedef struct sk_buff * __adf_nbuf_t; + +typedef void (*__adf_nbuf_callback_fn) (struct sk_buff *skb); +#define OSDEP_EAPOL_TID 6 /* send it on VO queue */ + +/* CVG_NBUF_MAX_OS_FRAGS - + * max tx fragments provided by the OS + */ +#define CVG_NBUF_MAX_OS_FRAGS 1 + +/* CVG_NBUF_MAX_EXTRA_FRAGS - + * max tx fragments added by the driver + * The driver will always add one tx fragment (the tx descriptor) and may + * add a second tx fragment (e.g. a TSO segment's modified IP header). + */ +#define CVG_NBUF_MAX_EXTRA_FRAGS 2 + +typedef void (*adf_nbuf_trace_update_t)(char *); + +struct cvg_nbuf_cb { + /* + * Store a pointer to a parent network buffer. + * This is used during TSO to allow the network buffers used for + * segments of the jumbo tx frame to reference the jumbo frame's + * original network buffer, so as each TSO segment's network buffer + * is freed, the original jumbo tx frame's reference count can be + * decremented, and ultimately freed once all the segments have been + * freed. + */ + struct sk_buff *parent; + + /* + * Store the DMA mapping info for the network buffer fragments + * provided by the OS. + */ + u_int32_t mapped_paddr_lo[CVG_NBUF_MAX_OS_FRAGS]; + + /* store extra tx fragments provided by the driver */ + struct { + /* vaddr - + * CPU address (a.k.a. virtual address) of the tx fragments added + * by the driver + */ + unsigned char *vaddr[CVG_NBUF_MAX_EXTRA_FRAGS]; + /* paddr_lo - + * bus address (a.k.a. physical address) of the tx fragments added + * by the driver + */ + u_int32_t paddr_lo[CVG_NBUF_MAX_EXTRA_FRAGS]; + u_int16_t len[CVG_NBUF_MAX_EXTRA_FRAGS]; + u_int8_t num; /* how many extra frags has the driver added */ + u_int8_t + /* + * Store a wordstream vs. bytestream flag for each extra fragment, + * plus one more flag for the original fragment(s) of the netbuf. + */ + wordstream_flags : CVG_NBUF_MAX_EXTRA_FRAGS+1; + } extra_frags; + uint32_t owner_id; + __adf_nbuf_callback_fn adf_nbuf_callback_fn; +#ifdef IPA_OFFLOAD + unsigned long priv_data; +#endif +#ifdef QCA_PKT_PROTO_TRACE + unsigned char proto_type; + unsigned char vdev_id; +#endif /* QCA_PKT_PROTO_TRACE */ +#ifdef QCA_TX_HTT2_SUPPORT + unsigned char tx_htt2_frm: 1; + unsigned char tx_htt2_reserved: 7; +#endif /* QCA_TX_HTT2_SUPPORT */ +}; +#define NBUF_OWNER_ID(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->owner_id) +#ifdef IPA_OFFLOAD +#define NBUF_OWNER_PRIV_DATA(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->priv_data) +#endif +#define NBUF_CALLBACK_FN(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->adf_nbuf_callback_fn) +#define NBUF_CALLBACK_FN_EXEC(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->adf_nbuf_callback_fn)(skb) +#define NBUF_MAPPED_PADDR_LO(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->mapped_paddr_lo[0]) +#define NBUF_NUM_EXTRA_FRAGS(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.num) +#define NBUF_EXTRA_FRAG_VADDR(skb, frag_num) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.vaddr[(frag_num)]) +#define NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.paddr_lo[(frag_num)]) +#define NBUF_EXTRA_FRAG_LEN(skb, frag_num) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.len[(frag_num)]) +#define NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.wordstream_flags) + +#ifdef QCA_PKT_PROTO_TRACE +#define NBUF_SET_PROTO_TYPE(skb, proto_type) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->proto_type = proto_type) +#define NBUF_GET_PROTO_TYPE(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->proto_type) +#else +#define NBUF_SET_PROTO_TYPE(skb, proto_type); +#define NBUF_GET_PROTO_TYPE(skb) 0; +#endif /* QCA_PKT_PROTO_TRACE */ + +#ifdef QCA_TX_HTT2_SUPPORT +#define NBUF_SET_TX_HTT2_FRM(skb, candi) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->tx_htt2_frm = candi) +#define NBUF_GET_TX_HTT2_FRM(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->tx_htt2_frm) +#else +#define NBUF_SET_TX_HTT2_FRM(skb, candi) +#define NBUF_GET_TX_HTT2_FRM(skb) 0 +#endif /* QCA_TX_HTT2_SUPPORT */ + +#define __adf_nbuf_get_num_frags(skb) \ + /* assume the OS provides a single fragment */ \ + (NBUF_NUM_EXTRA_FRAGS(skb) + 1) + + +#define __adf_nbuf_frag_push_head( \ + skb, frag_len, frag_vaddr, frag_paddr_lo, frag_paddr_hi) \ + do { \ + int frag_num = NBUF_NUM_EXTRA_FRAGS(skb)++; \ + NBUF_EXTRA_FRAG_VADDR(skb, frag_num) = frag_vaddr; \ + NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) = frag_paddr_lo; \ + NBUF_EXTRA_FRAG_LEN(skb, frag_num) = frag_len; \ + } while (0) + +#define __adf_nbuf_get_frag_len(skb, frag_num) \ + ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \ + NBUF_EXTRA_FRAG_LEN(skb, frag_num) : (skb)->len) + +#define __adf_nbuf_get_frag_vaddr(skb, frag_num) \ + ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \ + NBUF_EXTRA_FRAG_VADDR(skb, frag_num) : ((skb)->data)) + +#define __adf_nbuf_get_frag_paddr_lo(skb, frag_num) \ + ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \ + NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) : \ + /* assume that the OS only provides a single fragment */ \ + NBUF_MAPPED_PADDR_LO(skb)) + +#define __adf_nbuf_get_frag_is_wordstream(skb, frag_num) \ + ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \ + (NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) >> \ + (frag_num)) & 0x1 : \ + (NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) >> \ + (CVG_NBUF_MAX_EXTRA_FRAGS)) & 0x1) + +#define __adf_nbuf_set_frag_is_wordstream(skb, frag_num, is_wordstream) \ + do { \ + if (frag_num >= NBUF_NUM_EXTRA_FRAGS(skb)) { \ + frag_num = CVG_NBUF_MAX_EXTRA_FRAGS; \ + } \ + /* clear the old value */ \ + NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) &= ~(1 << frag_num); \ + /* set the new value */ \ + NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) |= \ + ((is_wordstream) << frag_num); \ + } while (0) + +#define __adf_nbuf_trace_set_proto_type(skb, proto_type) \ + NBUF_SET_PROTO_TYPE(skb, proto_type) +#define __adf_nbuf_trace_get_proto_type(skb) \ + NBUF_GET_PROTO_TYPE(skb); + +typedef struct __adf_nbuf_qhead { + struct sk_buff *head; + struct sk_buff *tail; + unsigned int qlen; +}__adf_nbuf_queue_t; + +// typedef struct sk_buff_head __adf_nbuf_queue_t; + +// struct anet_dma_info { +// dma_addr_t daddr; +// uint32_t len; +// }; +// +// struct __adf_nbuf_map { +// int nelem; +// struct anet_dma_info dma[1]; +// }; +// +// typedef struct __adf_nbuf_map *__adf_nbuf_dmamap_t; + + +/* + * Use sk_buff_head as the implementation of adf_nbuf_queue_t. + * Because the queue head will most likely put in some structure, + * we don't use pointer type as the definition. + */ + + +/* + * prototypes. Implemented in adf_nbuf_pvt.c + */ +__adf_nbuf_t __adf_nbuf_alloc(__adf_os_device_t osdev, size_t size, int reserve, int align, int prio); +void __adf_nbuf_free (struct sk_buff *skb); +void __adf_nbuf_ref (struct sk_buff *skb); +int __adf_nbuf_shared (struct sk_buff *skb); +a_status_t __adf_nbuf_dmamap_create(__adf_os_device_t osdev, + __adf_os_dma_map_t *dmap); +void __adf_nbuf_dmamap_destroy(__adf_os_device_t osdev, + __adf_os_dma_map_t dmap); +a_status_t __adf_nbuf_map(__adf_os_device_t osdev, + struct sk_buff *skb, adf_os_dma_dir_t dir); +void __adf_nbuf_unmap(__adf_os_device_t osdev, + struct sk_buff *skb, adf_os_dma_dir_t dir); +a_status_t __adf_nbuf_map_single(__adf_os_device_t osdev, + struct sk_buff *skb, adf_os_dma_dir_t dir); +void __adf_nbuf_unmap_single(__adf_os_device_t osdev, + struct sk_buff *skb, adf_os_dma_dir_t dir); +void __adf_nbuf_dmamap_info(__adf_os_dma_map_t bmap, adf_os_dmamap_info_t *sg); +void __adf_nbuf_frag_info(struct sk_buff *skb, adf_os_sglist_t *sg); +void __adf_nbuf_dmamap_set_cb(__adf_os_dma_map_t dmap, void *cb, void *arg); +void __adf_nbuf_reg_trace_cb(adf_nbuf_trace_update_t cb_func_ptr); + +#ifdef QCA_PKT_PROTO_TRACE +void +__adf_nbuf_trace_update(struct sk_buff *buf, char *event_string); +#else +#define __adf_nbuf_trace_update(skb, event_string) +#endif /* QCA_PKT_PROTO_TRACE */ + +static inline a_status_t +__adf_os_to_status(signed int error) +{ + switch(error){ + case 0: + return A_STATUS_OK; + case ENOMEM: + case -ENOMEM: + return A_STATUS_ENOMEM; + default: + return A_STATUS_ENOTSUPP; + } +} + + + +/** + * @brief This keeps the skb shell intact expands the headroom + * in the data region. In case of failure the skb is + * released. + * + * @param skb + * @param headroom + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_realloc_headroom(struct sk_buff *skb, uint32_t headroom) +{ + if(pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)){ + dev_kfree_skb_any(skb); + skb = NULL; + } + return skb; +} +/** + * @brief This keeps the skb shell intact exapnds the tailroom + * in data region. In case of failure it releases the + * skb. + * + * @param skb + * @param tailroom + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_realloc_tailroom(struct sk_buff *skb, uint32_t tailroom) +{ + if(likely(!pskb_expand_head(skb, 0, tailroom, GFP_ATOMIC))) + return skb; + /** + * unlikely path + */ + dev_kfree_skb_any(skb); + return NULL; +} +/** + * @brief return the amount of valid data in the skb, If there + * are frags then it returns total length. + * + * @param skb + * + * @return size_t + */ +static inline size_t +__adf_nbuf_len(struct sk_buff *skb) +{ + int i, extra_frag_len = 0; + + i = NBUF_NUM_EXTRA_FRAGS(skb); + while (i-- > 0) { + extra_frag_len += NBUF_EXTRA_FRAG_LEN(skb, i); + } + return (extra_frag_len + skb->len); +} + + +/** + * @brief link two nbufs, the new buf is piggybacked into the + * older one. The older (src) skb is released. + * + * @param dst( buffer to piggyback into) + * @param src (buffer to put) + * + * @return a_status_t (status of the call) if failed the src skb + * is released + */ +static inline a_status_t +__adf_nbuf_cat(struct sk_buff *dst, struct sk_buff *src) +{ + a_status_t error = 0; + + adf_os_assert(dst && src); + + /* + * Since pskb_expand_head unconditionally reallocates the skb->head buffer, + * first check whether the current buffer is already large enough. + */ + if (skb_tailroom(dst) < src->len) { + error = pskb_expand_head(dst, 0, src->len, GFP_ATOMIC); + if (error) { + return __adf_os_to_status(error); + } + } + memcpy(skb_tail_pointer(dst), src->data, src->len); + + skb_put(dst, src->len); + dev_kfree_skb_any(src); + + return __adf_os_to_status(error); +} + + +/** + * @brief create a version of the specified nbuf whose contents + * can be safely modified without affecting other + * users.If the nbuf is a clone then this function + * creates a new copy of the data. If the buffer is not + * a clone the original buffer is returned. + * + * @param skb (source nbuf to create a writable copy from) + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_unshare(struct sk_buff *skb) +{ + return skb_unshare(skb, GFP_ATOMIC); +} +/**************************nbuf manipulation routines*****************/ + +static inline int +__adf_nbuf_headroom(struct sk_buff *skb) +{ + return skb_headroom(skb); +} +/** + * @brief return the amount of tail space available + * + * @param buf + * + * @return amount of tail room + */ +static inline uint32_t +__adf_nbuf_tailroom(struct sk_buff *skb) +{ + return skb_tailroom(skb); +} + +/** + * @brief Push data in the front + * + * @param[in] buf buf instance + * @param[in] size size to be pushed + * + * @return New data pointer of this buf after data has been pushed, + * or NULL if there is not enough room in this buf. + */ +static inline uint8_t * +__adf_nbuf_push_head(struct sk_buff *skb, size_t size) +{ + if(NBUF_MAPPED_PADDR_LO(skb)) { + NBUF_MAPPED_PADDR_LO(skb) -= size; + } + return skb_push(skb, size); +} +/** + * @brief Puts data in the end + * + * @param[in] buf buf instance + * @param[in] size size to be pushed + * + * @return data pointer of this buf where new data has to be + * put, or NULL if there is not enough room in this buf. + */ +static inline uint8_t * +__adf_nbuf_put_tail(struct sk_buff *skb, size_t size) +{ + if (skb_tailroom(skb) < size) { + if(unlikely(pskb_expand_head(skb, 0, size-skb_tailroom(skb), GFP_ATOMIC))) { + dev_kfree_skb_any(skb); + return NULL; + } + } + return skb_put(skb, size); +} + +/** + * @brief pull data out from the front + * + * @param[in] buf buf instance + * @param[in] size size to be popped + * + * @return New data pointer of this buf after data has been popped, + * or NULL if there is not sufficient data to pull. + */ +static inline uint8_t * +__adf_nbuf_pull_head(struct sk_buff *skb, size_t size) +{ + if(NBUF_MAPPED_PADDR_LO(skb)) { + NBUF_MAPPED_PADDR_LO(skb) += size; + } + return skb_pull(skb, size); +} +/** + * + * @brief trim data out from the end + * + * @param[in] buf buf instance + * @param[in] size size to be popped + * + * @return none + */ +static inline void +__adf_nbuf_trim_tail(struct sk_buff *skb, size_t size) +{ + return skb_trim(skb, skb->len - size); +} + +/** + * @brief test whether the nbuf is cloned or not + * + * @param buf + * + * @return a_bool_t (TRUE if it is cloned or else FALSE) + */ +static inline a_bool_t +__adf_nbuf_is_cloned(struct sk_buff *skb) +{ + return skb_cloned(skb); +} + +/* TODO: Fix this */ +static inline uint8_t * +__adf_nbuf_init(struct sk_buff *skb, size_t reserve, size_t align, size_t tail_size) +{ +#if 0 + unsigned long offset; + /** + * Align & make sure that the tail & data are adjusted properly + */ + if(align){ + offset = ((unsigned long) skb->data) % align; + if(offset) + skb_reserve(skb, align - offset); + } + + /** + * NOTE:alloc doesn't take responsibility if reserve unaligns the data + * pointer + */ + skb_reserve(skb, reserve); + return skb; +#endif + return NULL; +} + +static inline void +__adf_nbuf_free_pool(struct sk_buff *skb) +{ + return; +} + +/*********************nbuf private buffer routines*************/ + +/** + * @brief get the priv pointer from the nbuf'f private space + * + * @param buf + * + * @return data pointer to typecast into your priv structure + */ +static inline uint8_t * +__adf_nbuf_get_priv(struct sk_buff *skb) +{ + return &skb->cb[8]; +} + +/** + * @brief This will return the header's addr & m_len + */ +static inline void +__adf_nbuf_peek_header(struct sk_buff *skb, uint8_t **addr, + uint32_t *len) +{ + *addr = skb->data; + *len = skb->len; +} + + /* adf_nbuf_queue_init() - initialize a skbuf queue + */ +/* static inline void */ +/* __adf_nbuf_queue_init(struct sk_buff_head *qhead) */ +/* { */ +/* skb_queue_head_init(qhead); */ +/* } */ + +/* /\* */ +/* * adf_nbuf_queue_add() - add a skbuf to the end of the skbuf queue */ + +/* * We use the non-locked version because */ +/* * there's no need to use the irq safe version of spinlock. */ +/* * However, the caller has to do synchronization by itself. */ +/* *\/ */ +/* static inline void */ +/* __adf_nbuf_queue_add(struct sk_buff_head *qhead, */ +/* struct sk_buff *skb) */ +/* { */ +/* __skb_queue_tail(qhead, skb); */ +/* adf_os_assert(qhead->next == qhead->prev); */ +/* } */ + +/* /\* */ +/* * adf_nbuf_queue_remove() - remove a skbuf from the head of the skbuf queue */ +/* * */ +/* * We use the non-locked version because */ +/* * there's no need to use the irq safe version of spinlock. */ +/* * However, the caller has to do synchronization by itself. */ +/* *\/ */ +/* static inline struct sk_buff * */ +/* __adf_nbuf_queue_remove(struct sk_buff_head * qhead) */ +/* { */ +/* adf_os_assert(qhead->next == qhead->prev); */ +/* return __skb_dequeue(qhead); */ +/* } */ + +/* static inline uint32_t */ +/* __adf_nbuf_queue_len(struct sk_buff_head * qhead) */ +/* { */ +/* adf_os_assert(qhead->next == qhead->prev); */ +/* return qhead->qlen; */ +/* } */ +/* /\** */ +/* * @brief returns the first guy in the Q */ +/* * @param qhead */ +/* * */ +/* * @return (NULL if the Q is empty) */ +/* *\/ */ +/* static inline struct sk_buff * */ +/* __adf_nbuf_queue_first(struct sk_buff_head *qhead) */ +/* { */ +/* adf_os_assert(qhead->next == qhead->prev); */ +/* return (skb_queue_empty(qhead) ? NULL : qhead->next); */ +/* } */ +/* /\** */ +/* * @brief return the next packet from packet chain */ +/* * */ +/* * @param buf (packet) */ +/* * */ +/* * @return (NULL if no packets are there) */ +/* *\/ */ +/* static inline struct sk_buff * */ +/* __adf_nbuf_queue_next(struct sk_buff *skb) */ +/* { */ +/* return NULL; // skb->next; */ +/* } */ +/* /\** */ +/* * adf_nbuf_queue_empty() - check if the skbuf queue is empty */ +/* *\/ */ +/* static inline a_bool_t */ +/* __adf_nbuf_is_queue_empty(struct sk_buff_head *qhead) */ +/* { */ +/* adf_os_assert(qhead->next == qhead->prev); */ +/* return skb_queue_empty(qhead); */ +/* } */ + +/******************Custom queue*************/ + + + +/** + * @brief initiallize the queue head + * + * @param qhead + */ +static inline a_status_t +__adf_nbuf_queue_init(__adf_nbuf_queue_t *qhead) +{ + memset(qhead, 0, sizeof(struct __adf_nbuf_qhead)); + return A_STATUS_OK; +} + + +/** + * @brief add an skb in the tail of the queue. This is a + * lockless version, driver must acquire locks if it + * needs to synchronize + * + * @param qhead + * @param skb + */ +static inline void +__adf_nbuf_queue_add(__adf_nbuf_queue_t *qhead, + struct sk_buff *skb) +{ + skb->next = NULL;/*Nullify the next ptr*/ + + if(!qhead->head) + qhead->head = skb; + else + qhead->tail->next = skb; + + qhead->tail = skb; + qhead->qlen++; +} + +/** + * @brief add an skb at the head of the queue. This is a + * lockless version, driver must acquire locks if it + * needs to synchronize + * + * @param qhead + * @param skb + */ +static inline void +__adf_nbuf_queue_insert_head(__adf_nbuf_queue_t *qhead, + __adf_nbuf_t skb) +{ + if(!qhead->head){ + /*Empty queue Tail pointer Must be updated */ + qhead->tail = skb; + } + skb->next = qhead->head; + qhead->head = skb; + qhead->qlen++; +} + +/** + * @brief remove a skb from the head of the queue, this is a + * lockless version. Driver should take care of the locks + * + * @param qhead + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_queue_remove(__adf_nbuf_queue_t * qhead) +{ + __adf_nbuf_t tmp = NULL; + + if (qhead->head) { + qhead->qlen--; + tmp = qhead->head; + if ( qhead->head == qhead->tail ) { + qhead->head = NULL; + qhead->tail = NULL; + } else { + qhead->head = tmp->next; + } + tmp->next = NULL; + } + return tmp; +} +/** + * @brief return the queue length + * + * @param qhead + * + * @return uint32_t + */ +static inline uint32_t +__adf_nbuf_queue_len(__adf_nbuf_queue_t * qhead) +{ + return qhead->qlen; +} +/** + * @brief returns the first skb in the queue + * + * @param qhead + * + * @return (NULL if the Q is empty) + */ +static inline struct sk_buff * +__adf_nbuf_queue_first(__adf_nbuf_queue_t *qhead) +{ + return qhead->head; +} +/** + * @brief return the next skb from packet chain, remember the + * skb is still in the queue + * + * @param buf (packet) + * + * @return (NULL if no packets are there) + */ +static inline struct sk_buff * +__adf_nbuf_queue_next(struct sk_buff *skb) +{ + return skb->next; +} +/** + * @brief check if the queue is empty or not + * + * @param qhead + * + * @return a_bool_t + */ +static inline a_bool_t +__adf_nbuf_is_queue_empty(__adf_nbuf_queue_t *qhead) +{ + return (qhead->qlen == 0); +} + +/* + * Use sk_buff_head as the implementation of adf_nbuf_queue_t. + * Because the queue head will most likely put in some structure, + * we don't use pointer type as the definition. + */ + + +/* + * prototypes. Implemented in adf_nbuf_pvt.c + */ +adf_nbuf_tx_cksum_t __adf_nbuf_get_tx_cksum(struct sk_buff *skb); +a_status_t __adf_nbuf_set_rx_cksum(struct sk_buff *skb, + adf_nbuf_rx_cksum_t *cksum); +a_status_t __adf_nbuf_get_vlan_info(adf_net_handle_t hdl, + struct sk_buff *skb, + adf_net_vlanhdr_t *vlan); +a_uint8_t __adf_nbuf_get_tid(struct sk_buff *skb); +void __adf_nbuf_set_tid(struct sk_buff *skb, a_uint8_t tid); +a_uint8_t __adf_nbuf_get_exemption_type(struct sk_buff *skb); +/* + * adf_nbuf_pool_init() implementation - do nothing in Linux + */ +static inline a_status_t +__adf_nbuf_pool_init(adf_net_handle_t anet) +{ + return A_STATUS_OK; +} + +/* + * adf_nbuf_pool_delete() implementation - do nothing in linux + */ +#define __adf_nbuf_pool_delete(osdev) + + +/** + * @brief Expand both tailroom & headroom. In case of failure + * release the skb. + * + * @param skb + * @param headroom + * @param tailroom + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_expand(struct sk_buff *skb, uint32_t headroom, uint32_t tailroom) +{ + if(likely(!pskb_expand_head(skb, headroom, tailroom, GFP_ATOMIC))) + return skb; + + dev_kfree_skb_any(skb); + return NULL; +} + + +/** + * @brief clone the nbuf (copy is readonly) + * + * @param src_nbuf (nbuf to clone from) + * @param dst_nbuf (address of the cloned nbuf) + * + * @return status + * + * @note if GFP_ATOMIC is overkill then we can check whether its + * called from interrupt context and then do it or else in + * normal case use GFP_KERNEL + * @example use "in_irq() || irqs_disabled()" + * + * + */ +static inline struct sk_buff * +__adf_nbuf_clone(struct sk_buff *skb) +{ + return skb_clone(skb, GFP_ATOMIC); +} +/** + * @brief returns a private copy of the skb, the skb returned is + * completely modifiable + * + * @param skb + * + * @return skb or NULL + */ +static inline struct sk_buff * +__adf_nbuf_copy(struct sk_buff *skb) +{ + return skb_copy(skb, GFP_ATOMIC); +} + +#define __adf_nbuf_reserve skb_reserve + +/***********************XXX: misc api's************************/ +static inline a_bool_t +__adf_nbuf_tx_cksum_info(struct sk_buff *skb, uint8_t **hdr_off, + uint8_t **where) +{ +// if (skb->ip_summed == CHECKSUM_NONE) +// return A_FALSE; +// +// if (skb->ip_summed == CHECKSUM_HW) { +// *hdr_off = (uint8_t *)(skb->h.raw - skb->data); +// *where = *hdr_off + skb->csum; +// return A_TRUE; +// } + + adf_os_assert(0); + return A_FALSE; +} + + +/* + * XXX What about other unions in skb? Windows might not have it, but we + * should penalize linux drivers for it. + * Besides this function is not likely doint the correct thing. + */ +static inline a_status_t +__adf_nbuf_get_tso_info(struct sk_buff *skb, adf_nbuf_tso_t *tso) +{ + adf_os_assert(0); + return A_STATUS_ENOTSUPP; +/* + if (!skb_shinfo(skb)->tso_size) { + tso->type = adf_net_TSO_NONE; + return; + } + + tso->mss = skb_shinfo(skb)->tso_size; +*/ +// tso->hdr_off = (uint8_t)(skb->h.raw - skb->data); +// +// if (skb->protocol == ntohs(ETH_P_IP)) +// tso->type = ADF_NET_TSO_IPV4; +// else if (skb->protocol == ntohs(ETH_P_IPV6)) +// tso->type = ADF_NET_TSO_ALL; +// else +// tso->type = ADF_NET_TSO_NONE; +} + +/** + * @brief return the pointer the skb's buffer + * + * @param skb + * + * @return uint8_t * + */ +static inline uint8_t * +__adf_nbuf_head(struct sk_buff *skb) +{ + return skb->head; +} + +/** + * @brief return the pointer to data header in the skb + * + * @param skb + * + * @return uint8_t * + */ +static inline uint8_t * +__adf_nbuf_data(struct sk_buff *skb) +{ + return skb->data; +} + +/** + * @brief return the priority value of the skb + * + * @param skb + * + * @return uint32_t + */ +static inline uint32_t +__adf_nbuf_get_priority(struct sk_buff *skb) +{ + return skb->priority; +} + +/** + * @brief sets the priority value of the skb + * + * @param skb, priority + * + * @return void + */ +static inline void +__adf_nbuf_set_priority(struct sk_buff *skb, uint32_t p) +{ + skb->priority = p; +} + +/** + * @brief sets the next skb pointer of the current skb + * + * @param skb and next_skb + * + * @return void + */ +static inline void +__adf_nbuf_set_next(struct sk_buff *skb, struct sk_buff *skb_next) +{ + skb->next = skb_next; +} + +/** + * @brief return the next skb pointer of the current skb + * + * @param skb - the current skb + * + * @return the next skb pointed to by the current skb + */ +static inline struct sk_buff * +__adf_nbuf_next(struct sk_buff *skb) +{ + return skb->next; +} + +/** + * @brief sets the next skb pointer of the current skb. This fn is used to + * link up extensions to the head skb. Does not handle linking to the head + * + * @param skb and next_skb + * + * @return void + */ +static inline void +__adf_nbuf_set_next_ext(struct sk_buff *skb, struct sk_buff *skb_next) +{ + skb->next = skb_next; +} + +/** + * @brief return the next skb pointer of the current skb + * + * @param skb - the current skb + * + * @return the next skb pointed to by the current skb + */ +static inline struct sk_buff * +__adf_nbuf_next_ext(struct sk_buff *skb) +{ + return skb->next; +} + +/** + * @brief link list of packet extensions to the head segment + * @details + * This function is used to link up a list of packet extensions (seg1, 2, + * ...) to the nbuf holding the head segment (seg0) + * @param[in] head_buf nbuf holding head segment (single) + * @param[in] ext_list nbuf list holding linked extensions to the head + * @param[in] ext_len Total length of all buffers in the extension list + */ +static inline void +__adf_nbuf_append_ext_list( + struct sk_buff *skb_head, + struct sk_buff * ext_list, + size_t ext_len) +{ + skb_shinfo(skb_head)->frag_list = ext_list; + skb_head->data_len = ext_len; + skb_head->len += skb_head->data_len; +} + +static inline void +__adf_nbuf_tx_free(struct sk_buff *bufs, int tx_err) +{ + while (bufs) { + struct sk_buff *next = __adf_nbuf_next(bufs); + __adf_nbuf_free(bufs); + bufs = next; + } +} + +/** + * @brief return the checksum value of the skb + * + * @param skb + * + * @return uint32_t + */ +static inline uint32_t +__adf_nbuf_get_age(struct sk_buff *skb) +{ + return skb->csum; +} + +/** + * @brief sets the checksum value of the skb + * + * @param skb, value + * + * @return void + */ +static inline void +__adf_nbuf_set_age(struct sk_buff *skb, uint32_t v) +{ + skb->csum = v; +} + +/** + * @brief adjusts the checksum/age value of the skb + * + * @param skb, adj + * + * @return void + */ +static inline void +__adf_nbuf_adj_age(struct sk_buff *skb, uint32_t adj) +{ + skb->csum -= adj; +} + +/** + * @brief return the length of the copy bits for skb + * + * @param skb, offset, len, to + * + * @return int32_t + */ +static inline int32_t +__adf_nbuf_copy_bits(struct sk_buff *skb, int32_t offset, int32_t len, void *to) +{ + return skb_copy_bits(skb, offset, to, len); +} + +/** + * @brief sets the length of the skb and adjust the tail + * + * @param skb, length + * + * @return void + */ +static inline void +__adf_nbuf_set_pktlen(struct sk_buff *skb, uint32_t len) +{ + if (skb->len > len) { + skb_trim(skb, len); + } + else { + if (skb_tailroom(skb) < len - skb->len) { + if(unlikely(pskb_expand_head( + skb, 0, len - skb->len -skb_tailroom(skb), GFP_ATOMIC))) + { + dev_kfree_skb_any(skb); + //KASSERT(0, ("No enough tailroom for skb, failed to alloc")); + adf_os_assert(0); + } + } + skb_put(skb, (len - skb->len)); + } +} + +/** + * @brief sets the protocol value of the skb + * + * @param skb, protocol + * + * @return void + */ +static inline void +__adf_nbuf_set_protocol(struct sk_buff *skb, uint16_t protocol) +{ + skb->protocol = protocol; +} + +/** + * @brief test whether the nbuf is nonlinear or not + * + * @param buf + * + * @return a_bool_t (TRUE if it is nonlinear or else FALSE) + */ +static inline a_bool_t +__adf_nbuf_is_nonlinear(struct sk_buff *skb) +{ + return skb_is_nonlinear(skb); +} + +/** + * @brief zeros out cb + * + * @param nbuf + * + * @return void + */ +static inline void +__adf_nbuf_reset_ctxt(__adf_nbuf_t nbuf) +{ + adf_os_mem_zero(nbuf->cb, sizeof(nbuf->cb)); +} + +/** + * @brief This function peeks data into the buffer at given offset + * + * @param[in] buf buffer + * @param[out] data peeked output buffer + * @param[in] off offset + * @param[in] len length of buffer requested beyond offset + * + * @return status of operation + */ +static inline a_status_t +__adf_nbuf_peek_data(__adf_nbuf_t buf, void **data, a_uint32_t off, + a_uint32_t len) +{ + /* check if we can peek data of len bytes from the offset */ + if (buf->len < (off + len)) { + *data = NULL; + return A_STATUS_ENOMEM; + } + + *data = (void*)&buf->data[off]; + + return A_STATUS_OK; +} + +#define __adf_nbuf_set_tx_htt2_frm(skb, candi) \ + NBUF_SET_TX_HTT2_FRM(skb, candi) +#define __adf_nbuf_get_tx_htt2_frm(skb) \ + NBUF_GET_TX_HTT2_FRM(skb) + +#endif /*_adf_nbuf_PVT_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_atomic_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_atomic_pvt.h new file mode 100644 index 0000000000000..4b4c8ff544e2e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_atomic_pvt.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef ADF_OS_ATOMIC_PVT_H +#define ADF_OS_ATOMIC_PVT_H + +#include /* a_status_t */ + +#include + +typedef atomic_t __adf_os_atomic_t; + +static inline a_status_t +__adf_os_atomic_init(__adf_os_atomic_t *v) +{ + atomic_set(v, 0); + + return A_STATUS_OK; +} + +static inline a_uint32_t +__adf_os_atomic_read(__adf_os_atomic_t *v) +{ + return (atomic_read(v)); +} +static inline void +__adf_os_atomic_inc(__adf_os_atomic_t *v) +{ + atomic_inc(v); +} + +static inline void +__adf_os_atomic_dec(__adf_os_atomic_t *v) +{ + atomic_dec(v); +} + +static inline void +__adf_os_atomic_add(int i, __adf_os_atomic_t *v) +{ + atomic_add(i, v); +} + +static inline a_uint32_t + __adf_os_atomic_dec_and_test(__adf_os_atomic_t *v) +{ + return(atomic_dec_and_test(v)); +} + +static inline void + __adf_os_atomic_set(__adf_os_atomic_t *v, int i) +{ + atomic_set(v, i); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.c new file mode 100644 index 0000000000000..e54b99e830527 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include +#include +#include +#include + +#include "adf_os_defer_pvt.h" + +void +__adf_os_defer_func(struct work_struct *work) +{ + __adf_os_work_t *ctx = container_of(work, __adf_os_work_t, work); + if (ctx->fn == NULL) + { + printk("BugCheck: Callback is not initilized while creating work queue\n"); + return; + } + ctx->fn(ctx->arg); +} + +void +__adf_os_defer_delayed_func(struct work_struct *dwork) +{ + __adf_os_delayed_work_t *ctx = container_of(dwork, __adf_os_delayed_work_t, dwork.work); + if (ctx->fn == NULL) + { + printk("BugCheck: Callback is not initilized while creating delayed work queue\n"); + return; + } + ctx->fn(ctx->arg); +} +EXPORT_SYMBOL(__adf_os_defer_func); +EXPORT_SYMBOL(__adf_os_defer_delayed_func); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h new file mode 100644 index 0000000000000..1b1462503ec26 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_defer_pvt.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_DEFER_PVT_H +#define _ADF_CMN_OS_DEFER_PVT_H + +#include +#include +#include +#ifdef CONFIG_CNSS +#include +#endif +#include + +typedef struct tasklet_struct __adf_os_bh_t; +typedef struct workqueue_struct __adf_os_workqueue_t; + +/** + * wrapper around the real task func + */ +typedef struct { + struct work_struct work; + adf_os_defer_fn_t fn; + void *arg; +}__adf_os_work_t; + +typedef struct { + struct delayed_work dwork; + adf_os_defer_fn_t fn; + void *arg; +}__adf_os_delayed_work_t; + +extern void __adf_os_defer_func(struct work_struct *work); +extern void __adf_os_defer_delayed_func(struct work_struct *work); + +typedef void (*__adf_os_bh_fn_t)(unsigned long arg); + +static inline a_status_t +__adf_os_init_work(adf_os_handle_t hdl, + __adf_os_work_t *work, + adf_os_defer_fn_t func, + void *arg) +{ + /*Initilize func and argument in work struct */ + work->fn = func; + work->arg = arg; +#ifdef CONFIG_CNSS + cnss_init_work(&work->work, __adf_os_defer_func); +#else + INIT_WORK(&work->work, __adf_os_defer_func); +#endif + return A_STATUS_OK; +} + +static inline a_status_t +__adf_os_init_delayed_work(adf_os_handle_t hdl, + __adf_os_delayed_work_t *work, + adf_os_defer_fn_t func, + void *arg) +{ + /*Initilize func and argument in work struct */ + work->fn = func; + work->arg = arg; +#ifdef CONFIG_CNSS + cnss_init_delayed_work(&work->dwork, __adf_os_defer_delayed_func); +#else + INIT_DELAYED_WORK(&work->dwork, __adf_os_defer_delayed_func); +#endif + return A_STATUS_OK; +} + +static inline __adf_os_workqueue_t* __adf_os_create_workqueue(char *name) +{ + return create_workqueue(name); +} + +static inline void __adf_os_queue_work(adf_os_handle_t hdl, __adf_os_workqueue_t *wqueue, __adf_os_work_t* work) +{ + queue_work(wqueue, &work->work); +} + +static inline void __adf_os_queue_delayed_work(adf_os_handle_t hdl, __adf_os_workqueue_t *wqueue, __adf_os_delayed_work_t* work, a_uint32_t delay) +{ + queue_delayed_work(wqueue, &work->dwork, delay); +} + +static inline void __adf_os_flush_workqueue(adf_os_handle_t hdl, __adf_os_workqueue_t *wqueue) +{ + flush_workqueue(wqueue); +} + +static inline void __adf_os_destroy_workqueue(adf_os_handle_t hdl, __adf_os_workqueue_t *wqueue) +{ + destroy_workqueue(wqueue); +} + +static inline a_status_t __adf_os_init_bh(adf_os_handle_t hdl, + struct tasklet_struct *bh, + adf_os_defer_fn_t func, + void *arg) +{ + tasklet_init(bh, (__adf_os_bh_fn_t)func, (unsigned long)arg); + + return A_STATUS_OK; +} + +static inline a_status_t +__adf_os_sched_work(adf_os_handle_t hdl, __adf_os_work_t * work) +{ + schedule_work(&work->work); + return A_STATUS_OK; +} + +static inline a_status_t __adf_os_sched_bh(adf_os_handle_t hdl, + struct tasklet_struct * bh) +{ + tasklet_schedule(bh); + + return A_STATUS_OK; +} + +static inline a_status_t +__adf_os_disable_work(adf_os_handle_t hdl, __adf_os_work_t * work) +{ + /** + * XXX:??? + */ + return A_STATUS_OK; +} +static inline a_status_t +__adf_os_disable_bh(adf_os_handle_t hdl, struct tasklet_struct *bh) +{ + tasklet_kill(bh); + + return A_STATUS_OK; +} +#endif /*_ADF_CMN_OS_DEFER_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_dma_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_dma_pvt.h new file mode 100644 index 0000000000000..d0e9e6322ed4f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_dma_pvt.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_DMA_PVT_H +#define _ADF_CMN_OS_DMA_PVT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + * XXX:error handling + * + * @brief allocate a DMA buffer mapped to local bus Direction + * doesnt matter, since this API is called at init time. + * + * @param size + * @param coherentSMP_CACHE_BYTES + * @param dmap + * + * @return void* + */ +static inline void * +__adf_os_dmamem_alloc(adf_os_device_t osdev, + size_t size, + a_bool_t coherent, + __adf_os_dma_map_t *dmap) +{ + void *vaddr; + __adf_os_dma_map_t lmap; + + lmap = kzalloc(sizeof(struct __adf_os_dma_map), GFP_KERNEL); + + adf_os_assert(lmap); + + lmap->nsegs = 1; + lmap->coherent = coherent; + + if(coherent) + vaddr = dma_alloc_coherent(osdev->dev, size, &lmap->seg[0].daddr, + GFP_ATOMIC); + else + vaddr = dma_alloc_noncoherent(osdev->dev, size, &lmap->seg[0].daddr, + GFP_ATOMIC); + + adf_os_assert(vaddr); + + lmap->seg[0].len = size; + lmap->mapped = 1; + + (*dmap) = lmap; + + return vaddr; +} + +/* + * Free a previously mapped DMA buffer + * Direction doesnt matter, since this API is called at closing time. + */ +static inline void +__adf_os_dmamem_free(adf_os_device_t osdev, __adf_os_size_t size, + a_bool_t coherent, void *vaddr, __adf_os_dma_map_t dmap) +{ + adf_os_assert(dmap->mapped); + + if(coherent) + dma_free_coherent(osdev->dev, size, vaddr, dmap->seg[0].daddr); + else + dma_free_noncoherent(osdev->dev, size, vaddr, dmap->seg[0].daddr); + + kfree(dmap); +} + + +#define __adf_os_dmamem_map2addr(_dmap) ((_dmap)->seg[0].daddr) + +static inline void +__adf_os_dmamem_cache_sync(__adf_os_device_t osdev, __adf_os_dma_map_t dmap, + adf_os_cache_sync_t sync) +{ + if(!dmap->coherent){ + dma_sync_single_for_cpu(osdev->dev, dmap->seg[0].daddr, dmap->seg[0].len, + DMA_BIDIRECTIONAL); + } +} +static inline adf_os_size_t +__adf_os_cache_line_size(void) +{ + return SMP_CACHE_BYTES; +} + +static inline void +__adf_os_invalidate_range(void * start, void * end) +{ +#ifdef MSM_PLATFORM + dmac_inv_range(start, end); +#else + //TODO figure out how to invalidate cache on x86 and other non-MSM platform + __adf_os_print("Cache Invalidate not yet implemented for non-MSM platform\n"); + return; +#endif +} + + +#endif /*_ADF_CMN_OS_DMA_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_io_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_io_pvt.h new file mode 100644 index 0000000000000..04050fd5682fa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_io_pvt.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_IO_PVT_H +#define _ADF_CMN_OS_IO_PVT_H + +#include +#include + +#ifdef QCA_PARTNER_PLATFORM +#include "ath_carr_pltfrm.h" +#else +#include +#endif + + +#define __adf_os_reg_read8(_dev, _addr) \ + readb((volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_read16(_dev, _addr) \ + readw((volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_read32(_dev, _addr) \ + readl((volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_read64(_dev, _addr) \ + readq((volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + + +#define __adf_os_reg_write8(_dev, _addr, _val) \ + writeb(_val, (volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_write16(_dev, _addr, _val) \ + writew(_val, (volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_write32(_dev, _addr, _val) \ + writel(_val, (volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_reg_write64(_dev, _addr, _val) \ + writeq(_val, (volatile void __iomem *)((_dev)->res.vaddr + (_addr))) + +#define __adf_os_ioremap(_addr, _len) \ + ioremap(_addr, _len) + + +#define __adf_os_ntohs ntohs +#define __adf_os_ntohl ntohl + +#define __adf_os_htons htons +#define __adf_os_htonl htonl + +#define __adf_os_cpu_to_le16 cpu_to_le16 +#define __adf_os_cpu_to_le32 cpu_to_le32 +#define __adf_os_cpu_to_le64 cpu_to_le64 + +#define __adf_os_cpu_to_be16 cpu_to_be16 +#define __adf_os_cpu_to_be32 cpu_to_be32 +#define __adf_os_cpu_to_be64 cpu_to_be64 + +#define __adf_os_le16_to_cpu le16_to_cpu +#define __adf_os_le32_to_cpu le32_to_cpu +#define __adf_os_le64_to_cpu le64_to_cpu + +#define __adf_os_be16_to_cpu be16_to_cpu +#define __adf_os_be32_to_cpu be32_to_cpu +#define __adf_os_be64_to_cpu be64_to_cpu + +#endif /*_ADF_CMN_OS_IO_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.c new file mode 100644 index 0000000000000..c24684f1c1963 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include + +#include "adf_os_lock.h" + +EXPORT_SYMBOL(adf_os_spin_lock_bh_outline); +EXPORT_SYMBOL(adf_os_spin_unlock_bh_outline); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h new file mode 100644 index 0000000000000..9bfdb501dde21 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_LOCK_PVT_H +#define _ADF_CMN_OS_LOCK_PVT_H + +#include +#include +#include +#include + +typedef struct __adf_os_linux_spinlock { + spinlock_t spinlock; + unsigned int flags; + unsigned long _flags; +} adf_os_linux_spinlock_t; + +/* define for flag */ +#define ADF_OS_LINUX_UNLOCK_BH 1 + +typedef adf_os_linux_spinlock_t __adf_os_spinlock_t; +typedef struct semaphore __adf_os_mutex_t; + +/** + * @brief Initialize the mutex + * + * @param mutex + * + * @return + */ +static inline a_status_t +__adf_os_init_mutex(struct semaphore *m) +{ + sema_init(m, 1); + return A_STATUS_OK; +} + + + + +static inline int +__adf_os_mutex_acquire(adf_os_device_t osdev, struct semaphore *m) +{ + down(m); + return 0; +} + +static inline void +__adf_os_mutex_release(adf_os_device_t osdev, struct semaphore *m) +{ + up(m); +} + +static inline a_status_t +__adf_os_spinlock_init(__adf_os_spinlock_t *lock) +{ + spin_lock_init(&lock->spinlock); + lock->flags = 0; + + return A_STATUS_OK; +} + +#define __adf_os_spinlock_destroy(lock) +/** + * @brief Acquire a Spinlock (SMP) & disable Preemption (Preemptive) + * + * @param lock (Lock object) + * @param flags (Current IRQ mask) + */ +static inline void +__adf_os_spin_lock(__adf_os_spinlock_t *lock) +{ + spin_lock(&lock->spinlock); +} + +/** + * @brief Unlock the spinlock and enables the Preemption + * + * @param lock + * @param flags + */ +static inline void +__adf_os_spin_unlock(__adf_os_spinlock_t *lock) +{ + spin_unlock(&lock->spinlock); +} + +/** + * @brief Acquire a Spinlock (SMP) & disable Preemption (Preemptive) + * Disable IRQs + * @param lock (Lock object) + */ +static inline void +__adf_os_spin_lock_irqsave(__adf_os_spinlock_t *lock) +{ + spin_lock_irqsave(&lock->spinlock, lock->_flags); +} + +/** + * @brief Unlock the spinlock and enables the Preemption + * Enable IRQ + * @param lock (Lock object) + */ +static inline void +__adf_os_spin_unlock_irqrestore(__adf_os_spinlock_t *lock) +{ + spin_unlock_irqrestore(&lock->spinlock, lock->_flags); +} + +/** + * @brief Acquire the spinlock and disable bottom halves + * + * @param lock + */ + +/* + * Synchronous versions - only for OS' that have interrupt disable + */ +#define __adf_os_spin_lock_irq(_pLock, _flags) spin_lock_irqsave(_pLock, _flags) +#define __adf_os_spin_unlock_irq(_pLock, _flags) spin_unlock_irqrestore(_pLock, _flags) + +static inline void +__adf_os_spin_lock_bh(__adf_os_spinlock_t *lock) +{ + if (likely(irqs_disabled() || in_softirq())) { + spin_lock(&lock->spinlock); + } else { + spin_lock_bh(&lock->spinlock); + lock->flags |= ADF_OS_LINUX_UNLOCK_BH; + } + +} +static inline void +__adf_os_spin_unlock_bh(__adf_os_spinlock_t *lock) +{ + if (unlikely(lock->flags & ADF_OS_LINUX_UNLOCK_BH)) { + lock->flags &= ~ADF_OS_LINUX_UNLOCK_BH; + spin_unlock_bh(&lock->spinlock); + } else + spin_unlock(&lock->spinlock); +} + +static inline a_bool_t +__adf_os_spinlock_irq_exec(adf_os_handle_t hdl, + __adf_os_spinlock_t *lock, + adf_os_irqlocked_func_t func, + void *arg) +{ + unsigned long flags; + a_bool_t ret; + + spin_lock_irqsave(&lock->spinlock, flags); + ret = func(arg); + spin_unlock_irqrestore(&lock->spinlock, flags); + + return ret; +} + + +static inline a_bool_t +__adf_os_in_softirq(void) +{ + return (in_softirq()); +} +#endif /*_ADF_CMN_OS_LOCK_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.c new file mode 100644 index 0000000000000..511f97a5de6d7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include "adf_os_mem.h" +#include "adf_os_module.h" + + +int adf_dbg_mask; +adf_os_declare_param(adf_dbg_mask, ADF_OS_PARAM_TYPE_INT32); + + +EXPORT_SYMBOL(adf_os_mem_alloc_outline); +EXPORT_SYMBOL(adf_os_mem_free_outline); +EXPORT_SYMBOL(adf_os_mem_zero_outline); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.h new file mode 100644 index 0000000000000..19b9b80eec6bf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_mem_pvt.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef ADF_CMN_OS_MEM_PVT_H +#define ADF_CMN_OS_MEM_PVT_H + +#ifdef __KERNEL__ +#include +#include +#include +#include +#if defined(HIF_USB) +#include +#elif defined(HIF_PCI) +#include /* pci_alloc_consistent */ +#endif +#else +/* + * Provide dummy defs for kernel data types, functions, and enums + * used in this header file. + */ +#define GFP_KERNEL 0 +#define GFP_ATOMIC 0 +#define kzalloc(size, flags) NULL +#define vmalloc(size) NULL +#define kfree(buf) +#define vfree(buf) +#define pci_alloc_consistent(dev, size, paddr) NULL +#endif /* __KERNEL__ */ + +static inline void * +__adf_os_mem_alloc(adf_os_device_t osdev, size_t size) +{ + int flags = GFP_KERNEL; + + if(in_interrupt() || irqs_disabled()) + flags = GFP_ATOMIC; + + return kzalloc(size, flags); +} + + +static inline void +__adf_os_mem_free(void *buf) +{ + kfree(buf); +} + + +static inline void * +__adf_os_mem_alloc_consistent( + adf_os_device_t osdev, adf_os_size_t size, adf_os_dma_addr_t *paddr, adf_os_dma_context_t memctx) +{ +#if defined(A_SIMOS_DEVHOST) + static int first = 1; + void *vaddr; + + if (first) { + first = 0; + printk("Warning: bypassing %s\n", __func__); + } + vaddr = __adf_os_mem_alloc(osdev, size); + *paddr = ((adf_os_dma_addr_t) vaddr); + return vaddr; +#else + void* alloc_mem = NULL; + alloc_mem = dma_alloc_coherent(osdev->dev, size, paddr, GFP_KERNEL); + if (alloc_mem == NULL) + pr_err("%s Warning: unable to alloc consistent memory of size %zu!\n", + __func__, size); + return alloc_mem; +#endif +} + +static inline void +__adf_os_mem_free_consistent( + adf_os_device_t osdev, + adf_os_size_t size, + void *vaddr, + adf_os_dma_addr_t paddr, + adf_os_dma_context_t memctx) +{ +#if defined(A_SIMOS_DEVHOST) + static int first = 1; + + if (first) { + first = 0; + printk("Warning: bypassing %s\n", __func__); + } + __adf_os_mem_free(vaddr); + return; +#else + dma_free_coherent(osdev->dev, size, vaddr, paddr); +#endif +} + +/* move a memory buffer */ +static inline void +__adf_os_mem_copy(void *dst, const void *src, size_t size) +{ + memcpy(dst, src, size); +} + +/* set a memory buffer */ +static inline void +__adf_os_mem_set(void *buf, uint8_t b, size_t size) +{ + memset(buf, b, size); +} + +/* zero a memory buffer */ +static inline void +__adf_os_mem_zero(void *buf, size_t size) +{ + memset(buf, 0, size); +} + +/* compare two memory buffers */ +static inline int +__adf_os_mem_cmp(const void *buf1, const void *buf2, size_t size) +{ + return memcmp(buf1, buf2, size); +} + +/** + * @brief Unlike memcpy(), memmove() copes with overlapping + * areas. + * @param src + * @param dst + * @param size + */ +static inline void +__adf_os_mem_move(void *dst, const void *src, size_t size) +{ + memmove(dst, src, size); +} + +/** + * @brief Compare two strings + * + * @param[in] str1 First string + * @param[in] str2 Second string + * + * @retval 0 equal + * @retval >0 not equal, if str1 sorts lexicographically after str2 + * @retval <0 not equal, if str1 sorts lexicographically before str2 + */ +static inline a_int32_t +__adf_os_str_cmp(const char *str1, const char *str2) +{ + return strcmp(str1, str2); +} + +/** + * @brief Returns the length of a string + * + * @param[in] str input string + * + * @retval length of string + */ +static inline adf_os_size_t +__adf_os_str_len(const char *str) +{ + return strlen(str); +} + +#endif /*ADF_OS_MEM_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_module_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_module_pvt.h new file mode 100644 index 0000000000000..a1e7595e8700a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_module_pvt.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_MODULE_PVT_H +#define _ADF_CMN_OS_MODULE_PVT_H + +#include +#include +#include +#include + + +#define __adf_os_virt_module_init(_x) \ + static int _x##_mod(void) \ + { \ + a_status_t st; \ + st = (_x)(); \ + if (st != A_STATUS_OK) \ + return -1; \ + else \ + return 0; \ + } \ + module_init(_x##_mod); + +#define __adf_os_virt_module_exit(_x) module_exit(_x) + +#define __adf_os_virt_module_name(_name) MODULE_LICENSE("Dual BSD/GPL"); + +#define __adf_os_module_dep(_name, _dep) + +#define __adf_os_export_symbol(_sym) EXPORT_SYMBOL(_sym) + + + +#define __ADF_OS_PARAM_TYPE_INT8 byte +#define __ADF_OS_PARAM_TYPE_INT16 short +#define __ADF_OS_PARAM_TYPE_INT32 int + + +#define __ADF_OS_PARAM_TYPE_UINT8 byte +#define __ADF_OS_PARAM_TYPE_UINT16 ushort +#define __ADF_OS_PARAM_TYPE_UINT32 uint + +#define __ADF_OS_PARAM_TYPE_STRING charp + +#define __adf_os_declare_param(_name, _type) \ + module_param(_name, _type, 0600) + +#define __adf_os_read_param(_osdev, _name, _type, _pval) + +#endif /*_ADF_CMN_OS_MODULE_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_postpack_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_postpack_pvt.h new file mode 100644 index 0000000000000..ce26e170295cd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_postpack_pvt.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @brief Linux does not require a postpack # directive. + */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_prepack_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_prepack_pvt.h new file mode 100644 index 0000000000000..17e49f860add1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_prepack_pvt.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** + * @brief Linux does not require a prepack # directive. + */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_pseudo_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_pseudo_pvt.h new file mode 100644 index 0000000000000..605aa1360d5c5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_pseudo_pvt.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef __ADF_HST_OS_PSEUDO_PVT_H +#define __ADF_HST_OS_PSEUDO_PVT_H + +#include + +#define NUM_PSEUDO_DEVS 2 + +#define __adf_os_pseudo_module_init(_fn) \ + static inline int __adf_os_pseudo_mod_init(void) \ + { \ + a_status_t st; \ + int i = 0; \ + st = (_fn)(); \ + for(i = 0; i < NUM_PSEUDO_DEVS; i++) \ + __adf_net_pseudo_attach(mod_name); \ + return st; \ + } \ + module_init(__adf_os_pseudo_mod_init); + +#define __adf_os_pseudo_module_exit(_fn) \ + static inline void __adf_os_pseudo_mod_exit(void) \ + { \ + int i = 0; \ + for(i = 0; i < NUM_PSEUDO_DEVS; i++) \ + __adf_net_pseudo_detach(mod_name); \ + (_fn)(); \ + } \ + module_exit(__adf_os_pseudo_mod_exit); + + +/** + * initiallize the PCI driver structure + * Instance name will be _pci_info + */ +#define __adf_os_pseudo_set_drv_info(_name, _ifname, _pseudo_ids, _attach, _detach, \ + _suspend, _resume) \ +{ \ + .drv_attach = (_attach), \ + .drv_detach = (_detach), \ + .drv_suspend = (_suspend), \ + .drv_resume = (_resume), \ + .pci_id = (_pseudo_ids), \ + .mod_name = #_name, \ + .ifname = #_ifname, \ +}; \ +const char *mod_name = #_name; \ +extern int __adf_net_pseudo_attach(const char *mod_name); \ +extern int __adf_net_pseudo_detach(const char *mod_name); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_time_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_time_pvt.h new file mode 100644 index 0000000000000..d8e07af896140 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_time_pvt.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_TIME_PVT_H +#define _ADF_CMN_OS_TIME_PVT_H + +#include +#include + +typedef unsigned long __adf_time_t; + +static inline __adf_time_t +__adf_os_ticks(void) +{ + return (jiffies); +} +static inline uint32_t +__adf_os_ticks_to_msecs(unsigned long ticks) +{ + return (jiffies_to_msecs(ticks)); +} +static inline __adf_time_t +__adf_os_msecs_to_ticks(a_uint32_t msecs) +{ + return (msecs_to_jiffies(msecs)); +} +static inline __adf_time_t +__adf_os_getuptime(void) +{ + return jiffies; +} + +static inline __adf_time_t +__adf_os_gettimestamp(void) +{ + return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ); +} + +static inline void +__adf_os_udelay(a_uint32_t usecs) +{ +#ifdef CONFIG_ARM + /* + ** This is in support of XScale build. They have a limit on the udelay + ** value, so we have to make sure we don't approach the limit + */ + + a_uint32_t mticks; + a_uint32_t leftover; + int i; + + /* + ** slice into 1024 usec chunks (simplifies calculation) + */ + + mticks = usecs >> 10; + leftover = usecs - (mticks << 10); + + for(i = 0;i < mticks;i++) + { + udelay(1024); + } + + udelay(leftover); + +#else + /* + * Normal Delay functions. Time specified in microseconds. + */ + udelay(usecs); + +#endif +} + +static inline void +__adf_os_mdelay(a_uint32_t msecs) +{ + mdelay(msecs); +} + +/** + * @brief Check if _a is later than _b. + */ +static inline a_bool_t +__adf_os_time_after(__adf_time_t a, __adf_time_t b) +{ + return ((long)(b) - (long)(a) < 0); +} + +/** + * @brief Check if _a is prior to _b. + */ +static inline a_bool_t +__adf_os_time_before(__adf_time_t a, __adf_time_t b) +{ + return __adf_os_time_after(b,a); +} + +/** + * @brief Check if _a atleast as recent as _b, if not later. + */ +static inline a_bool_t +__adf_os_time_after_eq(__adf_time_t a, __adf_time_t b) +{ + return ((long)(a) - (long)(b) >= 0); +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_timer_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_timer_pvt.h new file mode 100644 index 0000000000000..b57b1b6573d3c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_timer_pvt.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_TIMER_PVT_H +#define _ADF_CMN_OS_TIMER_PVT_H + +#include +#include +#include +#include +#include + +#define ADF_DEFERRABLE_TIMER 0 +#define ADF_NON_DEFERRABLE_TIMER 1 + +/* + * timer data type + */ +typedef struct timer_list __adf_os_timer_t; + +/* + * ugly - but every other OS takes, sanely, a void* + */ + +typedef void (*adf_dummy_timer_func_t)(unsigned long arg); + +/* + * Initialize a timer + */ +static inline a_status_t +__adf_os_timer_init(adf_os_handle_t hdl, + struct timer_list *timer, + adf_os_timer_func_t func, + void *arg, + uint8_t type) +{ + if (ADF_DEFERRABLE_TIMER == type) + init_timer_deferrable(timer); + else + init_timer(timer); + timer->function = (adf_dummy_timer_func_t)func; + timer->data = (unsigned long)arg; + + return A_STATUS_OK; +} + +/* + * start a timer + */ +static inline a_status_t +__adf_os_timer_start(struct timer_list *timer, a_uint32_t delay) +{ + timer->expires = jiffies + msecs_to_jiffies(delay); + add_timer(timer); + + return A_STATUS_OK; +} + +/* + * modify a timer + */ +static inline a_status_t +__adf_os_timer_mod(struct timer_list *timer, a_uint32_t delay) +{ + mod_timer(timer, jiffies + msecs_to_jiffies(delay)); + + return A_STATUS_OK; +} + +/* + * Cancel a timer + * + * Return: TRUE if timer was cancelled and deactived, + * FALSE if timer was cancelled but already got fired. + */ +static inline a_bool_t +__adf_os_timer_cancel(struct timer_list *timer) +{ + if (likely(del_timer(timer))) + return 1; + else + return 0; +} + +/* + * Free a timer + * + * Return: TRUE if timer was cancelled and deactived, + * FALSE if timer was cancelled but already got fired. + */ +static inline void +__adf_os_timer_free(struct timer_list *timer) +{ + del_timer_sync(timer); +} + +/* + * XXX Synchronously canel a timer + * + * Return: TRUE if timer was cancelled and deactived, + * FALSE if timer was cancelled but already got fired. + * + * Synchronization Rules: + * 1. caller must make sure timer function will not use + * adf_os_set_timer to add iteself again. + * 2. caller must not hold any lock that timer function + * is likely to hold as well. + * 3. It can't be called from interrupt context. + */ +static inline a_bool_t +__adf_os_timer_sync_cancel(struct timer_list *timer) +{ + return del_timer_sync(timer); +} + + + +#endif /*_ADF_OS_TIMER_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_trace.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_trace.h new file mode 100644 index 0000000000000..4532fdaae638c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_trace.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_TRACE_H +#define _ADF_TRACE_H + +#include + +/* + * Log levels +*/ +#define ADF_DEBUG_FUNCTRACE 0x01 +#define ADF_DEBUG_LEVEL0 0x02 +#define ADF_DEBUG_LEVEL1 0x04 +#define ADF_DEBUG_LEVEL2 0x08 +#define ADf_DEBUG_LEVEL3 0x10 +#define ADF_DEBUG_ERROR 0x20 +#define ADF_DEBUG_CFG 0x40 + +#define adf_trace(log_level, args...) \ + do{ \ + extern int adf_dbg_mask; \ + if(adf_dbg_mask >= log_level) { \ + printk("adf: "args); \ + printk("\n"); \ + } \ + }while(0) + + +#endif //_ADF_TRACE_H diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_types_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_types_pvt.h new file mode 100644 index 0000000000000..0ed82e1503811 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_types_pvt.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_TYPES_PVT_H +#define _ADF_CMN_OS_TYPES_PVT_H + +#ifndef __KERNEL__ +#define __iomem +#else +#include +#endif + +#include +#include +#include + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#else +/* + * Provide dummy defs for kernel data types, functions, and enums + * used in this header file. + */ + +/* + * Hack - coexist with prior defs of dma_addr_t. + * Eventually all other defs of dma_addr_t should be removed. + * At that point, the "already_defined" wrapper can be removed. + */ +#ifndef __dma_addr_t_already_defined__ +#define __dma_addr_t_already_defined__ +typedef unsigned long dma_addr_t; +#endif + +#define uint64_t u_int64_t +#define uint32_t u_int32_t +#define uint16_t u_int16_t +#define uint8_t u_int8_t +#define SIOCGIWAP 0 +#define IWEVCUSTOM 0 +#define IWEVREGISTERED 0 +#define IWEVEXPIRED 0 +#define SIOCGIWSCAN 0 +#define DMA_TO_DEVICE 0 +#define DMA_FROM_DEVICE 0 +#define __iomem +#endif /* __KERNEL__ */ + +/** + * max sg that we support + */ +#define __ADF_OS_MAX_SCATTER 1 +#define __ADF_OS_NAME_SIZE IFNAMSIZ + +#if defined(__LITTLE_ENDIAN_BITFIELD) +#define ADF_LITTLE_ENDIAN_MACHINE +#elif defined (__BIG_ENDIAN_BITFIELD) +#define ADF_BIG_ENDIAN_MACHINE +#else +#error "Please fix " +#endif + +#define __adf_os_packed __attribute__ ((packed)) + +#define __adf_os_ull(_num) _num ## ULL + +typedef struct completion __adf_os_comp_t; +struct __adf_net_drv; + +typedef int (*__adf_os_intr)(void *); +/** + * Private definitions of general data types + */ +typedef dma_addr_t __adf_os_dma_addr_t; +typedef size_t __adf_os_dma_size_t; +typedef dma_addr_t __adf_os_dma_context_t; + +#define adf_os_dma_mem_context(context) dma_addr_t context +#define adf_os_get_dma_mem_context(var, field) ((adf_os_dma_context_t)(var->field)) + + +typedef enum __adf_os_cache_sync{ + __ADF_SYNC_PREREAD, + __ADF_SYNC_PREWRITE, + __ADF_SYNC_POSTREAD, + __ADF_SYNC_POSTWRITE +}__adf_os_cache_sync_t; + +typedef struct __adf_os_resource{ + unsigned long paddr; + void __iomem * vaddr; + unsigned long len; +}__adf_os_resource_t; + +/** + * generic data types + */ +struct __adf_device { + void *drv; + void *drv_hdl; + char *drv_name; + int irq; + struct device *dev; + __adf_os_resource_t res; + __adf_os_intr func;/*Interrupt handler*/ +}; + +typedef struct __adf_device *__adf_os_device_t; + +typedef size_t __adf_os_size_t; +typedef off_t __adf_os_off_t; +typedef uint8_t __iomem * __adf_os_iomem_t; + +typedef struct __adf_os_segment{ + dma_addr_t daddr; + uint32_t len; +}__adf_os_segment_t; + +struct __adf_os_dma_map{ + uint32_t mapped; + uint32_t nsegs; + uint32_t coherent; + __adf_os_segment_t seg[__ADF_OS_MAX_SCATTER]; +}; +typedef struct __adf_os_dma_map *__adf_os_dma_map_t; +typedef uint32_t ath_dma_addr_t; +typedef uint8_t __a_uint8_t; +typedef int8_t __a_int8_t; +typedef uint16_t __a_uint16_t; +typedef int16_t __a_int16_t; +typedef uint32_t __a_uint32_t; +typedef int32_t __a_int32_t; +typedef uint64_t __a_uint64_t; +typedef int64_t __a_int64_t; + +enum __adf_net_wireless_evcode{ + __ADF_IEEE80211_ASSOC = SIOCGIWAP, + __ADF_IEEE80211_REASSOC =IWEVCUSTOM, + __ADF_IEEE80211_DISASSOC = SIOCGIWAP, + __ADF_IEEE80211_JOIN = IWEVREGISTERED, + __ADF_IEEE80211_LEAVE = IWEVEXPIRED, + __ADF_IEEE80211_SCAN = SIOCGIWSCAN, + __ADF_IEEE80211_REPLAY = IWEVCUSTOM, + __ADF_IEEE80211_MICHAEL = IWEVCUSTOM, + __ADF_IEEE80211_REJOIN = IWEVCUSTOM, + __ADF_CUSTOM_PUSH_BUTTON = IWEVCUSTOM, +}; + +#define __adf_os_print printk +#define __adf_os_vprint vprintk +#define __adf_os_snprint snprintf +#define __adf_os_vsnprint vsnprintf + +#define __ADF_OS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL +#define __ADF_OS_DMA_TO_DEVICE DMA_TO_DEVICE +#define __ADF_OS_DMA_FROM_DEVICE DMA_FROM_DEVICE +#define __adf_os_inline inline + +#endif /*_ADF_CMN_OS_TYPES_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_util_pvt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_util_pvt.h new file mode 100644 index 0000000000000..5584698fe31af --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/adf/linux/adf_os_util_pvt.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ADF_CMN_OS_UTIL_PVT_H +#define _ADF_CMN_OS_UTIL_PVT_H + +#include +#include +#include + +#include + +//#include +#include +/* + * Generic compiler-dependent macros if defined by the OS + */ + +#define __adf_os_unlikely(_expr) unlikely(_expr) +#define __adf_os_likely(_expr) likely(_expr) + +/** + * @brief memory barriers. + */ +#define __adf_os_wmb() wmb() +#define __adf_os_rmb() rmb() +#define __adf_os_mb() mb() + +#define __adf_os_min(_a, _b) ((_a) < (_b) ? _a : _b) +#define __adf_os_max(_a, _b) ((_a) > (_b) ? _a : _b) + +#define __adf_os_abs(_a) __builtin_abs(_a) + +/** + * @brief Assert + */ +#define __adf_os_assert(expr) do { \ + if(unlikely(!(expr))) { \ + printk(KERN_ERR "Assertion failed! %s:%s %s:%d\n", \ + #expr, __FUNCTION__, __FILE__, __LINE__); \ + dump_stack(); \ + BUG_ON(1); \ + } \ +}while(0) + +/** + * @brief Warning + */ +#define __adf_os_warn(cond) ({ \ + int __ret_warn = !!(cond); \ + if (unlikely(__ret_warn)) { \ + printk("WARNING: at %s:%d %s()\n", __FILE__, \ + __LINE__, __FUNCTION__); \ + dump_stack(); \ + } \ + unlikely(__ret_warn); \ +}) + +/** + * @brief replace with the name of the function + */ +#define __adf_os_function __FUNCTION__ + +static inline a_status_t +__adf_os_get_rand(adf_os_handle_t hdl, uint8_t *ptr, uint32_t len) +{ + get_random_bytes(ptr, len); + + return A_STATUS_OK; +} + +/** + * @brief return square root + */ +static __adf_os_inline a_uint32_t __adf_os_int_sqrt(a_uint32_t x) +{ + return int_sqrt(x); +} + +/** + * @brief completion structure initialization + */ +static __adf_os_inline void +__adf_os_init_completion(adf_os_comp_t *ptr) +{ + init_completion(ptr); +} + + +/** + * @brief wait for completion till timeout + * + * @Return: 0 if timed out, and positive on completion + */ +static __adf_os_inline unsigned long +__adf_os_wait_for_completion_timeout(adf_os_comp_t *ptr, unsigned long timeout) +{ + return wait_for_completion_timeout(ptr, timeout); +} + +static __adf_os_inline void +__adf_os_complete(adf_os_comp_t *ptr) +{ + complete(ptr); +} +#endif /*_ADF_CMN_OS_UTIL_PVT_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ah_osdep.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ah_osdep.h new file mode 100644 index 0000000000000..44e3e5c3ee68a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ah_osdep.h @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ATH_AH_OSDEP_H_ + +#define _ATH_AH_OSDEP_H_ + +/* + + * Atheros Hardware Access Layer (HAL) OS Dependent Definitions. + + */ + + + +/* + + * We're releasing binary HAL as a stand-alone module, so we don't + + * need to worry about compatibilities regarding calling convention. + + * By default, Windows uses PASCAL convention. + + */ + +#ifndef __ahdecl + +#define __ahdecl + +#endif + + + +#define __va_list va_list + +#define OS_INLINE __inline + +#ifndef inline + +#define inline __inline + +#endif + +//typedef unsigned int uintptr_t; + +//typedef unsigned long dma_addr_t; + +typedef int bus_space_tag_t; + +typedef char * bus_space_handle_t; + +typedef u_int32_t bus_addr_t; + + + +typedef void* HAL_SOFTC; + +typedef bus_space_handle_t HAL_BUS_HANDLE; + +typedef void* HAL_ADAPTER_HANDLE; + +typedef u_int32_t HAL_BUS_ADDR; /* XXX architecture dependent */ + +typedef bus_space_tag_t HAL_BUS_TAG; + +/* + + * Atomic interface + + */ + +typedef u_int32_t os_atomic_t; + + +/* no-ops */ +#define HAL_USE_INTERSPERSED_READS +#define HAL_NO_INTERSPERSED_READS + +//#define OS_ATOMIC_READ(_patomic_arg) (*(_patomic_arg)) + +//#define OS_ATOMIC_SET(_patomic_arg, v) InterlockedExchange(_patomic_arg, (v)) + +//#define OS_ATOMIC_ADD(v, _patomic_arg) InterlockedExchangeAdd(_patomic_arg, (v)) + +#define OS_ATOMIC_INC(_patomic_arg) ((*_patomic_arg)++) + +#define OS_ATOMIC_DEC(_patomic_arg) ((*_patomic_arg)--) + +//#define OS_ATOMIC_DEC_AND_TEST(_patomic_arg) (NdisInterlockedDecrement(_patomic_arg) == 0) + + + +//#define OS_CMPXCHG(_m, _old, _new) InterlockedCompareExchange(_m, _new, _old) + + + +/* + + * Supported Bus types + + */ + +typedef enum ath_hal_bus_type { + + HAL_BUS_TYPE_PCI, + HAL_BUS_TYPE_AHB, + HAL_BUS_TYPE_SIM, /* simulator */ + HAL_BUS_TYPE_SDIO, +} HAL_BUS_TYPE; + + + + + +/* + + * Bus to hal context handoff + + */ + +typedef struct hal_bus_context { + + HAL_BUS_TAG bc_tag; + + HAL_BUS_HANDLE bc_handle; + + HAL_BUS_TYPE bc_bustype; + +} HAL_BUS_CONTEXT; + + + +#ifndef abs + +#define abs(_a) ( (_a) < 0 ? -(_a) : (_a) ) + +#endif + + + +#define __printflike(_a,_b) \ + __attribute__ ((__format__ (__printf__, _a, _b))) + + + +struct ath_hal; + +struct hal_reg_parm { + + u_int8_t halPciePowerSaveEnable; // Program Serdes; Use ASPM + + u_int8_t halPcieL1SKPEnable; // Enable L1 SKP workaround + + u_int8_t halPcieClockReq; + + u_int32_t halPciePowerReset; + + u_int32_t halPcieWaen; + + u_int32_t halPcieDetach; + + u_int8_t halPcieRestore; + + u_int8_t halPllPwrSave; + + u_int8_t htEnable; // Enable/disable 11n mode + + u_int32_t ofdmTrigLow; + + u_int32_t ofdmTrigHigh; + + u_int32_t cckTrigHigh; + + u_int32_t cckTrigLow; + + u_int32_t enableANI; + + u_int8_t noiseImmunityLvl; + + u_int32_t ofdmWeakSigDet; + + u_int32_t cckWeakSigThr; + + u_int8_t spurImmunityLvl; + + u_int8_t firStepLvl; + + int8_t rssiThrHigh; + + int8_t rssiThrLow; + + u_int16_t diversityControl; // Enable/disable antenna diversity + + u_int16_t antennaSwitchSwap; + + u_int32_t forceBias; + + u_int32_t forceBiasAuto; + + int calInFlash; + +#ifdef ATH_SUPPORT_TxBF + + u_int8_t CVTimeOut; + + u_int16_t TxBFCtl; + +#endif + +}; + + + +/* + + * Byte order/swapping support. + + */ + +#define AH_LITTLE_ENDIAN 1234 + +#define AH_BIG_ENDIAN 4321 + + + +#ifdef MIPS32 + +#define AH_BYTE_ORDER AH_BIG_ENDIAN + +#endif + + + +#if AH_BYTE_ORDER == AH_BIG_ENDIAN + +/* + + * This could be optimized but since we only use it for + + * a few registers there's little reason to do so. + + */ + +static OS_INLINE u_int32_t + +__bswap32(u_int32_t _x) + +{ + + return ((u_int32_t)( + + (((const u_int8_t *)(&_x))[0] ) | + + (((const u_int8_t *)(&_x))[1]<< 8) | + + (((const u_int8_t *)(&_x))[2]<<16) | + + (((const u_int8_t *)(&_x))[3]<<24)) + + ); + +} + + + +#ifndef __BIG_ENDIAN__ + +#define __BIG_ENDIAN__ + +#endif + + + +#else + +#define __bswap32(_x) (_x) + +#endif + + + +/* + + * Register read/write; we assume the registers will always + + * be memory-mapped. Note that register accesses are done + + * using target-specific functions when debugging is enabled + + * (AH_DEBUG) or we are explicitly configured this way. The + + * latter is used on some platforms where the full i/o space + + * cannot be directly mapped. + + * + + * The hardware registers are native little-endian byte order. + + * Big-endian hosts are handled by enabling hardware byte-swap + + * of register reads and writes at reset. But the PCI clock + + * domain registers are not byte swapped! Thus, on big-endian + + * platforms we have to byte-swap thoese registers specifically. + + * Most of this code is collapsed at compile time because the + + * register values are constants. + + */ + + + +#if AH_BYTE_ORDER == AH_BIG_ENDIAN + + + +#define _OS_REG_WRITE(_ah, _reg, _val) \ + *((volatile u_int32_t *)(AH_PRIVATE(_ah)->ah_sh + (_reg))) = (_val) + +#define _OS_REG_READ(_ah, _reg) \ + *((volatile u_int32_t *)(AH_PRIVATE(_ah)->ah_sh + (_reg))) + + + +#else /* _BYTE_ORDER == _LITTLE_ENDIAN */ + +#define __bswap32(_x) (_x) + +#define _OS_REG_WRITE(_ah, _reg, _val) \ + bus_space_write_4(AH_PRIVATE(_ah)->ah_st, AH_PRIVATE(_ah)->ah_sh, (_reg), (_val)) + +#define _OS_REG_READ(_ah, _reg) \ + ((u_int32_t) bus_space_read_4(AH_PRIVATE(_ah)->ah_st, AH_PRIVATE(_ah)->ah_sh, (_reg))) + +#endif /* _BYTE_ORDER */ + + +#ifndef ATH_SUPPORT_HTC + +/* no-op for non-USB solutions */ +#define ENABLE_REG_WRITE_BUFFER +#define DISABLE_REG_WRITE_BUFFER +#define OS_REG_WRITE_FLUSH(_ah) +#define HTC_SET_PS_STATE(_ah, _mode) + +#else /* ATH_SUPPORT_HTC */ + +#define ENABLE_REG_WRITE_BUFFER \ + if (!AH_PRIVATE(ah)->ah_reg_write_buffer_flag) \ + AH_PRIVATE(ah)->ah_reg_write_buffer_flag = 1; \ + else \ + HDPRINTF(ah, HAL_DBG_REG_IO, "%s: Error:REG_WRITE_BUFFER " \ + "had not been correctly disabled!\n", __func__); + +#define DISABLE_REG_WRITE_BUFFER \ + if (AH_PRIVATE(ah)->ah_reg_write_buffer_flag) \ + AH_PRIVATE(ah)->ah_reg_write_buffer_flag = 0; \ + else \ + HDPRINTF(ah, HAL_DBG_REG_IO, "%s: Error:REG_WRITE_BUFFER " \ + "had not been correctly disabled!\n", _func__); + +#define OS_REG_WRITE_FLUSH(_ah) \ + if (AH_PRIVATE(_ah)->ah_reg_write_buffer_flag) { \ + _OS_REG_WRITE_FLUSH(_ah); \ + } else \ + HDPRINTF(ah, HAL_DBG_REG_IO, "%s: Error:REG_WRITE_BUFFER " \ + "must be enabled!\n", _func__); + +extern void ath_hal_wmi_ps_set_state(struct ath_hal *ah, u_int16_t mode); + +#define HTC_SET_PS_STATE(_ah, _mode) \ + ath_hal_wmi_ps_set_state(_ah, _mode); + +#endif /* ATH_SUPPORT_HTC */ + + +#if defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || defined(AH_DEBUG_ALQ) + +#define OS_REG_WRITE(_ah, _reg, _val) ath_hal_reg_write(_ah, _reg, _val) +#define OS_REG_READ(_ah, _reg) ath_hal_reg_read(_ah, _reg) + +u_int32_t __ahdecl ath_hal_reg_read(struct ath_hal *, u_int32_t); +void __ahdecl ath_hal_reg_write(struct ath_hal *, u_int32_t, u_int32_t); + +#else + +#define OS_REG_WRITE(_ah, _reg, _val) _OS_REG_WRITE(_ah, _reg, _val) +#define OS_REG_READ(_ah, _reg) _OS_REG_READ(_ah, _reg) + +#endif /* AH_DEBUG || AH_REGFUNC || AH_DEBUG_ALQ */ + + +#ifdef AH_DEBUG_ALQ +extern void __ahdecl OS_MARK(struct ath_hal *, u_int id, u_int32_t value); +#else +#define OS_MARK(_ah, _id, _v) +#endif + + +/* + * Linux-specific attach/detach methods needed for module reference counting. + * + * XXX We can't use HAL_STATUS because the type isn't defined at this + * point (circular dependency); we wack the type and patch things + * up in the function. + * + * NB: These are intentionally not marked __ahdecl since they are + * compiled with the default calling convetion and are not called + * from within the HAL. + */ + +typedef u_int32_t (*HAL_BUS_CONFIG_READER)(HAL_SOFTC sc, u_int32_t offset, void *pBuffer, u_int32_t length); + +struct ath_hal_callback { + /* Callback Functions */ + HAL_BUS_CONFIG_READER read_pci_config_space; +}; + + +/* + * osdev_t specific flags. + */ +#define ATH_ATTACHED 0x0001 /* attach has succeeded */ +#define ATH_ENABLED 0x0002 /* chip is enabled */ +#define ATH_RXREFILL 0x0004 /* Refill the recv bufs */ + +#define ATH_IS_ENABLED(osdev) ((osdev)->sc_flags & ATH_ENABLED) + +#ifdef AR9100 +extern void ath_hal_ahb_mac_reset(void); +extern void ath_hal_get_chip_revisionid(u_int32_t *); +#endif + +#ifndef ARRAY_LENGTH +#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#endif /* _ATH_AH_OSDEP_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/apb_athr_wlan_map.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/apb_athr_wlan_map.h new file mode 100644 index 0000000000000..f88171fcb32d6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/apb_athr_wlan_map.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _APB_ATHR_WLAN_MAP_H_ +#define _APB_ATHR_WLAN_MAP_H_ + +#define RTC_SOC_BASE_ADDRESS 0x00004000 +#define RTC_WMAC_BASE_ADDRESS 0x00005000 +#define MAC_COEX_BASE_ADDRESS 0x00006000 +#define BT_COEX_BASE_ADDRESS 0x00007000 +#define SOC_PCIE_BASE_ADDRESS 0x00008000 +#define SOC_CORE_BASE_ADDRESS 0x00009000 +#define WLAN_UART_BASE_ADDRESS 0x0000c000 +#define WLAN_SI_BASE_ADDRESS 0x00010000 +#define WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 +#define WLAN_MAC_BASE_ADDRESS 0x00020000 +#define EFUSE_BASE_ADDRESS 0x00030000 +#define FPGA_REG_BASE_ADDRESS 0x00039000 +#define WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define CE_WRAPPER_BASE_ADDRESS 0x00057000 +#define CE0_BASE_ADDRESS 0x00057400 +#define CE1_BASE_ADDRESS 0x00057800 +#define CE2_BASE_ADDRESS 0x00057c00 +#define CE3_BASE_ADDRESS 0x00058000 +#define CE4_BASE_ADDRESS 0x00058400 +#define CE5_BASE_ADDRESS 0x00058800 +#define CE6_BASE_ADDRESS 0x00058c00 +#define CE7_BASE_ADDRESS 0x00059000 +#define DBI_BASE_ADDRESS 0x00060000 +#define WLAN_MBOX_BASE_ADDRESS 0x00068000 +#define WLAN_DBG_UART_BASE_ADDRESS 0x00069000 +#define USB_DMA_BASE_ADDRESS 0x0006a000 + +#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athdefs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athdefs.h new file mode 100644 index 0000000000000..11ce362e3f85d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athdefs.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHDEFS_H__ +#define __ATHDEFS_H__ + +/* + * This file contains definitions that may be used across both + * Host and Target software. Nothing here is module-dependent + * or platform-dependent. + */ + +/* + * Generic error codes that can be used by hw, sta, ap, sim, dk + * and any other environments. Since these are enums, feel free to + * add any more codes that you need. + */ + +typedef enum { + A_ERROR = -1, /* Generic error return */ + A_OK = 0, /* success */ + /* Following values start at 1 */ + A_DEVICE_NOT_FOUND, /* not able to find PCI device */ + A_NO_MEMORY, /* not able to allocate memory, not available */ + A_MEMORY_NOT_AVAIL, /* memory region is not free for mapping */ + A_NO_FREE_DESC, /* no free descriptors available */ + A_BAD_ADDRESS, /* address does not match descriptor */ + A_WIN_DRIVER_ERROR, /* used in NT_HW version, if problem at init */ + A_REGS_NOT_MAPPED, /* registers not correctly mapped */ + A_EPERM, /* Not superuser */ + A_EACCES, /* Access denied */ + A_ENOENT, /* No such entry, search failed, etc. */ + A_EEXIST, /* The object already exists (can't create) */ + A_EFAULT, /* Bad address fault */ + A_EBUSY, /* Object is busy */ + A_EINVAL, /* Invalid parameter */ + A_EMSGSIZE, /* Inappropriate message buffer length */ + A_ECANCELED, /* Operation canceled */ + A_ENOTSUP, /* Operation not supported */ + A_ECOMM, /* Communication error on send */ + A_EPROTO, /* Protocol error */ + A_ENODEV, /* No such device */ + A_EDEVNOTUP, /* device is not UP */ + A_NO_RESOURCE, /* No resources for requested operation */ + A_HARDWARE, /* Hardware failure */ + A_PENDING, /* Asynchronous routine; will send up results la +ter (typically in callback) */ + A_EBADCHANNEL, /* The channel cannot be used */ + A_DECRYPT_ERROR, /* Decryption error */ + A_PHY_ERROR, /* RX PHY error */ + A_CONSUMED, /* Object was consumed */ + A_CLONE, /* The buffer is cloned */ + A_USB_ERROR, /* Rome USB Target error */ +} A_STATUS; + +#define A_SUCCESS(x) (x == A_OK) +#define A_FAILED(x) (!A_SUCCESS(x)) + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif /* __ATHDEFS_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athendpack.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athendpack.h new file mode 100644 index 0000000000000..cff17850abee4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athendpack.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef VXWORKS +#endif /* VXWORKS */ + +#if defined(LINUX) || defined(__linux__) +#endif /* LINUX */ + +#ifdef QNX +#endif /* QNX */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athstartpack.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athstartpack.h new file mode 100644 index 0000000000000..1a8db88c6d7f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/athstartpack.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// start compiler-specific structure packing +// +// Author(s): ="Atheros" +//============================================================================== +#ifndef _ATHSTARTPACK_H +#define _ATHSTARTPACK_H + +#if defined(LINUX) || defined(__linux__) +#include "osapi_linux.h" +#endif /* LINUX */ + +#ifdef QNX +#endif /* QNX */ + +#if __LONG_MAX__ == __INT_MAX__ +/* 32-bit compilation */ +#define PREPACK64 +#define POSTPACK64 +#else +/* 64-bit compilation */ +#define PREPACK64 PREPACK +#define POSTPACK64 POSTPACK +#endif + +#endif /* _ATHSTARTPACK_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi.h new file mode 100644 index 0000000000000..a70f695fe558c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//============================================================================== +// BMI declarations and prototypes +// +// Author(s): ="Atheros" +//============================================================================== +#ifndef _BMI_H_ +#define _BMI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Header files */ +#include "athdefs.h" +#include "a_types.h" +#include "hif.h" +#include "osapi_linux.h" +#include "bmi_msg.h" +#include "ol_if_athvar.h" + +A_STATUS bmi_download_firmware(struct ol_softc *scn); + +void +BMICleanup(struct ol_softc *scn); + +A_STATUS +bmi_done(struct ol_softc *scn); + +A_STATUS +BMIReadMemory(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn); + +A_STATUS +BMIWriteMemory(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn); + +A_STATUS +BMIExecute(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 *param, + struct ol_softc *scn); + +A_STATUS +BMISetAppStart(HIF_DEVICE *device, + A_UINT32 address, + struct ol_softc *scn); + +A_STATUS +BMIReadSOCRegister(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 *param, + struct ol_softc *scn); + +A_STATUS +BMIWriteSOCRegister(HIF_DEVICE *device, + A_UINT32 address, + A_UINT32 param, + struct ol_softc *scn); + +A_STATUS +BMIrompatchInstall(HIF_DEVICE *device, + A_UINT32 ROM_addr, + A_UINT32 RAM_addr, + A_UINT32 nbytes, + A_UINT32 do_activate, + A_UINT32 *patch_id, + struct ol_softc *scn); + +A_STATUS +BMIrompatchUninstall(HIF_DEVICE *device, + A_UINT32 rompatch_id, + struct ol_softc *scn); + +A_STATUS +BMIrompatchActivate(HIF_DEVICE *device, + A_UINT32 rompatch_count, + A_UINT32 *rompatch_list, + struct ol_softc *scn); + +A_STATUS +BMIrompatchDeactivate(HIF_DEVICE *device, + A_UINT32 rompatch_count, + A_UINT32 *rompatch_list, + struct ol_softc *scn); + +A_STATUS +BMISignStreamStart(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn); + +A_STATUS +BMILZStreamStart(HIF_DEVICE *device, + A_UINT32 address, + struct ol_softc *scn); + +A_STATUS +BMILZData(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn); + +A_STATUS +BMIFastDownload(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + struct ol_softc *scn); + +A_STATUS +BMInvramProcess(HIF_DEVICE *device, + A_UCHAR *seg_name, + A_UINT32 *retval, + struct ol_softc *scn); + +A_STATUS +BMIRawWrite(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length); + +A_STATUS +BMIRawRead(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length, + A_BOOL want_timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _BMI_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi_msg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi_msg.h new file mode 100644 index 0000000000000..bff2ed63d076d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/bmi_msg.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// Copyright (c) 2004-2012 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __BMI_MSG_H__ +#define __BMI_MSG_H__ + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif + +/* + * Bootloader Messaging Interface (BMI) + * + * BMI is a very simple messaging interface used during initialization + * to read memory, write memory, execute code, and to define an + * application entry PC. + * + * It is used to download an application to AR6K, to provide + * patches to code that is already resident on AR6K, and generally + * to examine and modify state. The Host has an opportunity to use + * BMI only once during bootup. Once the Host issues a BMI_DONE + * command, this opportunity ends. + * + * The Host writes BMI requests to mailbox0, and reads BMI responses + * from mailbox0. BMI requests all begin with a command + * (see below for specific commands), and are followed by + * command-specific data. + * + * Flow control: + * The Host can only issue a command once the Target gives it a + * "BMI Command Credit", using AR6K Counter #4. As soon as the + * Target has completed a command, it issues another BMI Command + * Credit (so the Host can issue the next command). + * + * BMI handles all required Target-side cache flushing. + */ + + +/* Maximum data size used for BMI transfers */ +#define BMI_DATASZ_MAX 256 + +/* BMI Commands */ + +#define BMI_NO_COMMAND 0 + +#define BMI_DONE 1 + /* + * Semantics: Host is done using BMI + * Request format: + * A_UINT32 command (BMI_DONE) + * Response format: none + */ + +#define BMI_READ_MEMORY 2 + /* + * Semantics: Host reads AR6K memory + * Request format: + * A_UINT32 command (BMI_READ_MEMORY) + * A_UINT32 address + * A_UINT32 length, at most BMI_DATASZ_MAX + * Response format: + * A_UINT8 data[length] + */ + +#define BMI_WRITE_MEMORY 3 + /* + * Semantics: Host writes AR6K memory + * Request format: + * A_UINT32 command (BMI_WRITE_MEMORY) + * A_UINT32 address + * A_UINT32 length, at most BMI_DATASZ_MAX + * A_UINT8 data[length] + * Response format: none + */ +/* + * Capbility to write "segmented files" is provided for two reasons + * 1) backwards compatibility for certain situations where Hosts + * have limited flexibility + * 2) because it's darn convenient. + * + * A segmented file consists of a file header followed by an arbitrary number + * of segments. Each segment contains segment metadata -- a Target address and + * a length -- followed by "length" bytes of data. A segmented file ends with + * a segment that specifies length=BMI_SGMTFILE_DONE. When a segmented file + * is sent to the Target, firmware writes each segment to the specified address. + * + * Special cases: + * 1) If a segment's metadata indicates length=BMI_SGMTFILE_EXEC, then the + * specified address is used as a function entry point for a brief function + * with prototype "(void *)(void)". That function is called immediately. + * After execution of the function completes, firmware continues with the + * next segment. No data is expected when length=BMI_SGMTFILE_EXEC. + * + * 2) If a segment's metadata indicates length=BMI_SGMTFILE_BEGINADDR, then + * the specified address is established as the application start address + * so that a subsequent BMI_DONE jumps there. + * + * 3) If a segment's metadata indicates length=BMI_SGMTFILE_BDDATA, then + * the specified address is used as the (possibly compressed) length of board + * data, which is loaded into the proper Target address as specified by + * hi_board_data. In addition, the hi_board_data_initialized flag is set. + * + * A segmented file is sent to the Target using a sequence of 1 or more + * BMI_WRITE_MEMORY commands. The first such command must have + * address=BMI_SEGMENTED_WRITE_ADDR. Subsequent BMI_WRITE_MEMORY commands + * can use an arbitrary address. In each BMI_WRITE_MEMORY command, the + * length specifies the number of data bytes transmitted (except for the + * special cases listed above). + * + * Alternatively, a segmented file may be sent to the Target using a + * BMI_LZ_STREAM_START command with address=BMI_SEGMENTED_WRITE_ADDR + * followed by a series of BMI_LZ_DATA commands that each send the next portion + * of the segmented file. + * + * The data segments may be lz77 compressed. In this case, the segmented file + * header flag, BMI_SGMTFILE_FLAG_COMPRESS, must be set. Note that segmented + * file METAdata is never compressed; only the data segments themselves are + * compressed. There is no way to mix compressed and uncompressed data segments + * in a single segmented file. Compressed (or uncompressed) segments are handled + * by both BMI_WRITE_MEMORY and by BMI_LZ_DATA commands. (Compression is an + * attribute of the segmented file rather than of the command used to transmit + * it.) + */ +#define BMI_SEGMENTED_WRITE_ADDR 0x1234 + +/* File header for a segmented file */ +struct bmi_segmented_file_header { + A_UINT32 magic_num; + A_UINT32 file_flags; +}; +#define BMI_SGMTFILE_MAGIC_NUM 0x544d4753 /* "SGMT" */ +#define BMI_SGMTFILE_FLAG_COMPRESS 1 + +/* Metadata for a segmented file segment */ +struct bmi_segmented_metadata { + A_UINT32 addr; + A_UINT32 length; +}; +/* Special values for bmi_segmented_metadata.length (all have high bit set) */ +#define BMI_SGMTFILE_DONE 0xffffffff /* end of segmented data */ +#define BMI_SGMTFILE_BDDATA 0xfffffffe /* Board Data segment */ +#define BMI_SGMTFILE_BEGINADDR 0xfffffffd /* set beginning address */ +#define BMI_SGMTFILE_EXEC 0xfffffffc /* immediate function execution */ + +#define BMI_EXECUTE 4 + /* + * Semantics: Causes AR6K to execute code + * Request format: + * A_UINT32 command (BMI_EXECUTE) + * A_UINT32 address + * A_UINT32 parameter + * Response format: + * A_UINT32 return value + */ +/* + * Note: In order to support the segmented file feature + * (see BMI_WRITE_MEMORY), when the address specified in a + * BMI_EXECUTE command matches (same physical address) + * BMI_SEGMENTED_WRITE_ADDR, it is ignored. Instead, execution + * begins at the address specified by hi_app_start. + */ + +#define BMI_SET_APP_START 5 + /* + * Semantics: Set Target application starting address + * Request format: + * A_UINT32 command (BMI_SET_APP_START) + * A_UINT32 address + * Response format: none + */ + +#define BMI_READ_SOC_REGISTER 6 +#define BMI_READ_SOC_WORD 6 + /* + * Semantics: Read a 32-bit Target SOC word. + * Request format: + * A_UINT32 command (BMI_READ_REGISTER) + * A_UINT32 address + * Response format: + * A_UINT32 value + */ + +#define BMI_WRITE_SOC_REGISTER 7 +#define BMI_WRITE_SOC_WORD 7 + /* + * Semantics: Write a 32-bit Target SOC word. + * Request format: + * A_UINT32 command (BMI_WRITE_REGISTER) + * A_UINT32 address + * A_UINT32 value + * + * Response format: none + */ + +#define BMI_GET_TARGET_ID 8 +#define BMI_GET_TARGET_INFO 8 + /* + * Semantics: Fetch the 4-byte Target information + * Request format: + * A_UINT32 command (BMI_GET_TARGET_ID/INFO) + * + * Response format1 (old firmware): + * A_UINT32 TargetVersionID + * + * Response format2 (intermediate firmware, during transition): + * A_UINT32 TARGET_VERSION_SENTINAL + * struct bmi_target_info; + * + * Response format3 (newest firmware) + * struct bmi_target_info; + */ + +PREPACK struct bmi_target_info { + A_UINT32 target_info_byte_count; /* size of this structure */ + A_UINT32 target_ver; /* Target Version ID */ + A_UINT32 target_type; /* Target type */ +} POSTPACK; +#define TARGET_VERSION_SENTINAL 0xffffffff +#define TARGET_TYPE_UNKNOWN 0 +#define TARGET_TYPE_AR6001 1 +#define TARGET_TYPE_AR6002 2 +#define TARGET_TYPE_AR6003 3 +#define TARGET_TYPE_AR6004 5 +#define TARGET_TYPE_AR6006 6 +#define TARGET_TYPE_AR9888 7 +#define TARGET_TYPE_AR6320 8 +#define TARGET_TYPE_AR900B 9 +/* For attach Peregrine 2.0 board target_reg_tbl only */ +#define TARGET_TYPE_AR9888V2 10 +/* For attach Rome1.0 target_reg_tbl only*/ +#define TARGET_TYPE_AR6320V1 11 +/* For Rome2.0/2.1 target_reg_tbl ID*/ +#define TARGET_TYPE_AR6320V2 12 +/* For Rome3.0 target_reg_tbl ID*/ +#define TARGET_TYPE_AR6320V3 13 +/* For Tufello1.0 target_reg_tbl ID*/ +#define TARGET_TYPE_QCA9377V1 14 + +#define BMI_ROMPATCH_INSTALL 9 + /* + * Semantics: Install a ROM Patch. + * Request format: + * A_UINT32 command (BMI_ROMPATCH_INSTALL) + * A_UINT32 Target ROM Address + * A_UINT32 Target RAM Address or Value (depending on Target Type) + * A_UINT32 Size, in bytes + * A_UINT32 Activate? 1-->activate; + * 0-->install but do not activate + * Response format: + * A_UINT32 PatchID + */ + +#define BMI_ROMPATCH_UNINSTALL 10 + /* + * Semantics: Uninstall a previously-installed ROM Patch, + * automatically deactivating, if necessary. + * Request format: + * A_UINT32 command (BMI_ROMPATCH_UNINSTALL) + * A_UINT32 PatchID + * + * Response format: none + */ + +#define BMI_ROMPATCH_ACTIVATE 11 + /* + * Semantics: Activate a list of previously-installed ROM Patches. + * Request format: + * A_UINT32 command (BMI_ROMPATCH_ACTIVATE) + * A_UINT32 rompatch_count + * A_UINT32 PatchID[rompatch_count] + * + * Response format: none + */ + +#define BMI_ROMPATCH_DEACTIVATE 12 + /* + * Semantics: Deactivate a list of active ROM Patches. + * Request format: + * A_UINT32 command (BMI_ROMPATCH_DEACTIVATE) + * A_UINT32 rompatch_count + * A_UINT32 PatchID[rompatch_count] + * + * Response format: none + */ + + +#define BMI_LZ_STREAM_START 13 + /* + * Semantics: Begin an LZ-compressed stream of input + * which is to be uncompressed by the Target to an + * output buffer at address. The output buffer must + * be sufficiently large to hold the uncompressed + * output from the compressed input stream. This BMI + * command should be followed by a series of 1 or more + * BMI_LZ_DATA commands. + * A_UINT32 command (BMI_LZ_STREAM_START) + * A_UINT32 address + * Note: Not supported on all versions of ROM firmware. + */ + +#define BMI_LZ_DATA 14 + /* + * Semantics: Host writes AR6K memory with LZ-compressed + * data which is uncompressed by the Target. This command + * must be preceded by a BMI_LZ_STREAM_START command. A series + * of BMI_LZ_DATA commands are considered part of a single + * input stream until another BMI_LZ_STREAM_START is issued. + * Request format: + * A_UINT32 command (BMI_LZ_DATA) + * A_UINT32 length (of compressed data), + * at most BMI_DATASZ_MAX + * A_UINT8 CompressedData[length] + * Response format: none + * Note: Not supported on all versions of ROM firmware. + */ + +#define BMI_NVRAM_PROCESS 15 +#define BMI_NVRAM_SEG_NAME_SZ 16 + /* + * Semantics: Cause Target to search NVRAM (if any) for a + * segment with the specified name and process it according + * to NVRAM metadata. + * Request format: + * A_UINT32 command (BMI_NVRAM_PROCESS) + * A_UCHAR name[BMI_NVRAM_SEG_NAME_SZ] name (LE format) + * Response format: + * A_UINT32 0, if nothing was executed; + * otherwise the value returned from the + * last NVRAM segment that was executed + */ + +#define BMI_SIGN_STREAM_START 17 + /* + * Semantics: Trigger target start/end binary signature verification + * flow. + * Request format: + * A_UINT32 command (BMI_SIGN_STREAM_START) + * A_UINT32 address + * A_UINT32 length, at most BMI_DATASZ_MAX + * A_UINT8 data[length] + * Response format: none + */ + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + +/* TBDXXX: Need a better place for these */ +#define BMI_CE_NUM_TO_TARG 0 +#define BMI_CE_NUM_TO_HOST 1 + +#endif /* __BMI_MSG_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog.h new file mode 100644 index 0000000000000..9874ac8998b26 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2012, 2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _DBGLOG_H_ +#define _DBGLOG_H_ + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif + +#include "wlan_module_ids.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define DBGLOG_TIMESTAMP_OFFSET 0 +#define DBGLOG_TIMESTAMP_MASK 0xFFFFFFFF /* Bit 0-15. Contains bit + 8-23 of the LF0 timer */ +#define DBGLOG_DBGID_OFFSET 0 +#define DBGLOG_DBGID_MASK 0x000003FF /* Bit 0-9 */ +#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */ + +#define DBGLOG_MODULEID_OFFSET 10 +#define DBGLOG_MODULEID_MASK 0x0003FC00 /* Bit 10-17 */ +#define DBGLOG_MODULEID_NUM_MAX 32 /* Upper limit is width of mask */ + +#define DBGLOG_VDEVID_OFFSET 18 +#define DBGLOG_VDEVID_MASK 0x03FC0000 /* Bit 20-25*/ +#define DBGLOG_VDEVID_NUM_MAX 16 + +#define DBGLOG_NUM_ARGS_OFFSET 26 +#define DBGLOG_NUM_ARGS_MASK 0xFC000000 /* Bit 26-31 */ +#define DBGLOG_NUM_ARGS_MAX 9 /* it is bcoz of limitation + of corebsp MSG*() to accept max 9 arg */ + +#define DBGLOG_LOG_BUFFER_SIZE 1500 +#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90 + +#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE + +#define DBGLOG_GET_DBGID(arg) \ + ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET) + +#define DBGLOG_GET_MODULEID(arg) \ + ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET) + +#define DBGLOG_GET_VDEVID(arg) \ + ((arg & DBGLOG_VDEVID_MASK) >> DBGLOG_VDEVID_OFFSET) + +#define DBGLOG_GET_NUMARGS(arg) \ + ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET) + +#define DBGLOG_GET_TIME_STAMP(arg) \ + ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET) + + +#define DIAG_FWID_OFFSET 24 +#define DIAG_FWID_MASK 0xFF000000 /* Bit 24-31 */ + +#define DIAG_TIMESTAMP_OFFSET 0 +#define DIAG_TIMESTAMP_MASK 0x00FFFFFF /* Bit 0-23 */ + +#define DIAG_ID_OFFSET 16 +#define DIAG_ID_MASK 0xFFFF0000 /* Bit 16-31 */ + +#define DIAG_VDEVID_OFFSET 11 +#define DIAG_VDEVID_MASK 0x0000F800 /* Bit 11-15 */ +#define DIAG_VDEVID_NUM_MAX 16 + +#define DIAG_VDEVLEVEL_OFFSET 8 +#define DIAG_VDEVLEVEL_MASK 0x00000700 /* Bit 8-10 */ + +#define DIAG_PAYLEN_OFFSET 0 +#define DIAG_PAYLEN_MASK 0x000000FF /* Bit 0-7 */ + +#define DIAG_PAYLEN_OFFSET16 0 +#define DIAG_PAYLEN_MASK16 0x0000FFFF /* Bit 0-16 */ + +#define DIAG_GET_TYPE(arg) \ + ((arg & DIAG_FWID_MASK) >> DIAG_FWID_OFFSET) + +#define DIAG_GET_TIME_STAMP(arg) \ + ((arg & DIAG_TIMESTAMP_MASK) >> DIAG_TIMESTAMP_OFFSET) + +#define DIAG_GET_ID(arg) \ + ((arg & DIAG_ID_MASK) >> DIAG_ID_OFFSET) + +#define DIAG_GET_VDEVID(arg) \ + ((arg & DIAG_VDEVID_MASK) >> DIAG_VDEVID_OFFSET) + +#define DIAG_GET_VDEVLEVEL(arg) \ + ((arg & DIAG_VDEVLEVEL_MASK) >> DIAG_VDEVLEVEL_OFFSET) + +#define DIAG_GET_PAYLEN(arg) \ + ((arg & DIAG_PAYLEN_MASK) >> DIAG_PAYLEN_OFFSET) + +#define DIAG_GET_PAYLEN16(arg) \ + ((arg & DIAG_PAYLEN_MASK16) >> DIAG_PAYLEN_OFFSET16) + +/* Debug Log levels*/ + +typedef enum { + DBGLOG_VERBOSE = 0, + DBGLOG_INFO, + DBGLOG_INFO_LVL_1, + DBGLOG_INFO_LVL_2, + DBGLOG_WARN, + DBGLOG_ERR, + DBGLOG_LVL_MAX +}DBGLOG_LOG_LVL; + +PREPACK struct dbglog_buf_s { + struct dbglog_buf_s *next; + A_UINT8 *buffer; + A_UINT32 bufsize; + A_UINT32 length; + A_UINT32 count; + A_UINT32 free; +} POSTPACK; + +PREPACK struct dbglog_hdr_s { + struct dbglog_buf_s *dbuf; + A_UINT32 dropped; +} POSTPACK; + +PREPACK struct dbglog_buf_host { + A_UINT32 next; + A_UINT32 buffer; + A_UINT32 bufsize; + A_UINT32 length; + A_UINT32 count; + A_UINT32 free; +} POSTPACK; + +PREPACK struct dbglog_hdr_host { + A_UINT32 dbuf; + A_UINT32 dropped; +} POSTPACK; + +#define DBGLOG_MAX_VDEVID 15 /* 0-15 */ + +#ifdef __cplusplus +} +#endif + + +#endif /* _DBGLOG_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_host.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_host.h new file mode 100644 index 0000000000000..ee5e02581f84c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_host.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _DBGLOG_HOST_H_ +#define _DBGLOG_HOST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "dbglog_id.h" +#include "dbglog.h" +#include "ol_defines.h" + +#define MAX_DBG_MSGS 256 + +#define CLD_NETLINK_USER 17 + +#define LOGFILE_FLAG 0x01 +#define CONSOLE_FLAG 0x02 +#define QXDM_FLAG 0x04 +#define SILENT_FLAG 0x08 +#define DEBUG_FLAG 0x10 + +#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 + +#define HDRLEN 16 +#define RECLEN (HDRLEN + ATH6KL_FWLOG_PAYLOAD_SIZE) + +#define DBGLOG_PRINT_PREFIX "FWLOG: " + +/* Handy Macros to read data length and type from FW */ +#define WLAN_DIAG_0_TYPE_S 0 +#define WLAN_DIAG_0_TYPE 0x000000ff +#define WLAN_DIAG_0_TYPE_GET(x) WMI_F_MS(x, WLAN_DIAG_0_TYPE) +#define WLAN_DIAG_0_TYPE_SET(x, y) WMI_F_RMW(x, y, WLAN_DIAG_0_TYPE) +/* bits 8-15 reserved */ + +/* length includes the size of wlan_diag_data */ +#define WLAN_DIAG_0_LEN_S 16 +#define WLAN_DIAG_0_LEN 0xffff0000 +#define WLAN_DIAG_0_LEN_GET(x) WMI_F_MS(x, WLAN_DIAG_0_LEN) +#define WLAN_DIAG_0_LEN_SET(x, y) WMI_F_RMW(x, y, WLAN_DIAG_0_LEN) + +#define CNSS_DIAG_SLEEP_INTERVAL 5 /* In secs */ + +#define SIZEOF_NL_MSG_LOAD 28 /* sizeof nlmsg and load length */ +#define SIZEOF_NL_MSG_UNLOAD 28 /* sizeof nlmsg and Unload length */ +#define SIZEOF_NL_MSG_DBG_MSG 1532 +#define ATH6KL_FWLOG_MAX_ENTRIES 20 +#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 + +#define DIAG_WLAN_DRIVER_UNLOADED 6 +#define DIAG_WLAN_DRIVER_LOADED 7 +#define DIAG_TYPE_LOGS 1 +#define DIAG_TYPE_EVENTS 2 + + +typedef enum { + DBGLOG_PROCESS_DEFAULT = 0, + DBGLOG_PROCESS_PRINT_RAW, /* print them in debug view */ + DBGLOG_PROCESS_POOL_RAW, /* user buffer pool to save them */ + DBGLOG_PROCESS_NET_RAW, /* user buffer pool to save them */ + DBGLOG_PROCESS_MAX, +} dbglog_process_t; + +enum cnss_diag_type { + DIAG_TYPE_FW_EVENT, /* send fw event- to diag*/ + DIAG_TYPE_FW_LOG, /* send log event- to diag*/ + DIAG_TYPE_FW_DEBUG_MSG, /* send dbg message- to diag*/ + DIAG_TYPE_INIT_REQ, /* cnss_diag nitialization- from diag */ + DIAG_TYPE_FW_MSG, /* fw msg command-to diag */ + DIAG_TYPE_HOST_MSG, /* host command-to diag */ + DIAG_TYPE_CRASH_INJECT, /*crash inject-from diag */ + DIAG_TYPE_DBG_LEVEL, /* DBG LEVEL-from diag */ +}; + +enum wlan_diag_config_type { + DIAG_VERSION_INFO, +}; + +enum wlan_diag_frame_type { + WLAN_DIAG_TYPE_CONFIG, + WLAN_DIAG_TYPE_EVENT, + WLAN_DIAG_TYPE_LOG, + WLAN_DIAG_TYPE_MSG, + WLAN_DIAG_TYPE_LEGACY_MSG, +}; + +/* log/event are always 32-bit aligned. Padding is inserted after + * optional payload to satisify this requirement */ +struct wlan_diag_data { + unsigned int word0; /* type, length */ + unsigned int target_time; + unsigned int code; /* Diag log or event Code */ + u_int8_t payload[0]; +}; + + +struct dbglog_slot { + unsigned int diag_type; + unsigned int timestamp; + unsigned int length; + unsigned int dropped; + /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */ + u_int8_t payload[0]; +}__packed; + +typedef struct event_report_s { + unsigned int diag_type; + unsigned short event_id; + unsigned short length; +} event_report_t; + +typedef struct wlan_bringup_s { + unsigned short wlanStatus; + char driverVersion[10]; +} wlan_bringup_t; + +static inline unsigned int get_32(const unsigned char *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +/* + * set the dbglog parser type + */ +int +dbglog_parser_type_init(wmi_unified_t wmi_handle, int type); + +/** dbglog_int - Registers a WMI event handle for WMI_DBGMSG_EVENT +* @brief wmi_handle - handle to wmi module +*/ +int +dbglog_init(wmi_unified_t wmi_handle); + +/** dbglog_deinit - UnRegisters a WMI event handle for WMI_DBGMSG_EVENT +* @brief wmi_handle - handle to wmi module +*/ +int +dbglog_deinit(wmi_unified_t wmi_handle); + +/** set the size of the report size +* @brief wmi_handle - handle to Wmi module +* @brief size - Report size +*/ +int +dbglog_set_report_size(wmi_unified_t wmi_handle, A_UINT16 size); + +/** Set the resolution for time stamp +* @brief wmi_handle - handle to Wmi module +* @ brief tsr - time stamp resolution +*/ +int +dbglog_set_timestamp_resolution(wmi_unified_t wmi_handle, A_UINT16 tsr); + +/** Enable reporting. If it is set to false then Traget wont deliver +* any debug information +*/ +int +dbglog_report_enable(wmi_unified_t wmi_handle, A_BOOL isenable); + +/** Set the log level +* @brief DBGLOG_INFO - Information lowest log level +* @brief DBGLOG_WARNING +* @brief DBGLOG_ERROR - default log level +*/ +int +dbglog_set_log_lvl(wmi_unified_t wmi_handle, DBGLOG_LOG_LVL log_lvl); + +/* + * set the debug log level for a given module + * mod_id_lvl : the format is more user friendly. + * module_id = mod_id_lvl/10; + * log_level = mod_id_lvl%10; + * example : mod_id_lvl is 153. then module id is 15 and log level is 3. this format allows + * user to pass a sinlge value (which is the most convenient way for most of the OSs) + * to be passed from user to the driver. + */ +int +dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, A_UINT32 mod_id_lvl); + +/** Enable/Disable the logging for VAP */ +int +dbglog_vap_log_enable(wmi_unified_t wmi_handle, A_UINT16 vap_id, + A_BOOL isenable); +/** Enable/Disable logging for Module */ +int +dbglog_module_log_enable(wmi_unified_t wmi_handle, A_UINT32 mod_id, + A_BOOL isenable); + +/** set vap enablie bitmap */ +void +dbglog_set_vap_enable_bitmap(wmi_unified_t wmi_handle, A_UINT32 vap_enable_bitmap); + +/** set log level for all the modules specified in the bitmap. for all other modules + * with 0 in the bitmap (or) outside the bitmap , the log level be reset to DBGLOG_ERR. + */ +void +dbglog_set_mod_enable_bitmap(wmi_unified_t wmi_handle,A_UINT32 log_level, + A_UINT32 *mod_enable_bitmap, A_UINT32 bitmap_len ); + +/** Custome debug_print handlers */ +/* Args: + module Id + vap id + debug msg id + Time stamp + no of arguments + pointer to the buffer holding the args +*/ +typedef A_BOOL (*module_dbg_print) (A_UINT32, A_UINT16, A_UINT32, A_UINT32, + A_UINT16, A_UINT32 *); + +/** Register module specific dbg print*/ +void dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn); + +/** Register the cnss_diag activate with the wlan driver */ +int cnss_diag_activate_service(void); +int cnss_diag_notify_wlan_close(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_HOST_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_id.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_id.h new file mode 100644 index 0000000000000..494eed51965f0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dbglog_id.h @@ -0,0 +1,1440 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _DBGLOG_ID_H_ +#define _DBGLOG_ID_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The target state machine framework will send dbglog messages on behalf on + * other modules. We do this do avoid each target module adding identical + * dbglog code for state transitions and event processing. We also don't want + * to force each module to define the the same XXX_DBGID_SM_MSG with the same + * value below. Instead we use a special ID that the host dbglog code + * recognizes as a message sent by the SM on behalf on another module. + */ +#define DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG 1000 + +/* + * The nomenclature for the debug identifiers is MODULE_DESCRIPTION. + * Please ensure that the definition of any new debugid introduced is captured + * between the _DBGID_DEFINITION_START and + * _DBGID_DEFINITION_END defines. The structure is required for the + * parser to correctly pick up the values for different debug identifiers. + */ + +/* +* The target state machine framework will send dbglog messages on behalf on +* other modules. We do this do avoid each module adding identical dbglog code +* for state transitions and event processing. We also don't want to force each +* module to define the the same XXX_DBGID_SM_MSG with the same value below. +* Instead we use a special ID that the host dbglog code recognizes as a +* message sent by the SM on behalf on another module. +*/ +#define DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG 1000 + + +/* INF debug identifier definitions */ +#define INF_DBGID_DEFINITION_START 0 +#define INF_ASSERTION_FAILED 1 +#define INF_TARGET_ID 2 +#define INF_TARGET_MEM_REMAING 3 +#define INF_TARGET_MEM_EXT_REMAING 4 +#define INF_TARGET_MEM_ALLOC_TRACK 5 +#define INF_TARGET_MEM_ALLOC_RAM 6 +#define INF_DBGID_DEFINITION_END 7 + +/* WMI debug identifier definitions */ +#define WMI_DBGID_DEFINITION_START 0 +#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1 +#define WMI_EXTENDED_CMD_NOT_HANDLED 2 +#define WMI_CMD_RX_PKT_TOO_SHORT 3 +#define WMI_CALLING_WMI_EXTENSION_FN 4 +#define WMI_CMD_NOT_HANDLED 5 +#define WMI_IN_SYNC 6 +#define WMI_TARGET_WMI_SYNC_CMD 7 +#define WMI_SET_SNR_THRESHOLD_PARAMS 8 +#define WMI_SET_RSSI_THRESHOLD_PARAMS 9 +#define WMI_SET_LQ_TRESHOLD_PARAMS 10 +#define WMI_TARGET_CREATE_PSTREAM_CMD 11 +#define WMI_WI_DTM_INUSE 12 +#define WMI_TARGET_DELETE_PSTREAM_CMD 13 +#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14 +#define WMI_TARGET_GET_BIT_RATE_CMD 15 +#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16 +#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17 +#define WMI_TARGET_GET_TX_PWR_CMD 18 +#define WMI_FREE_EVBUF_WMIBUF 19 +#define WMI_FREE_EVBUF_DATABUF 20 +#define WMI_FREE_EVBUF_BADFLAG 21 +#define WMI_HTC_RX_ERROR_DATA_PACKET 22 +#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23 +#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24 +#define WMI_SENDING_READY_EVENT 25 +#define WMI_SETPOWER_MDOE_TO_MAXPERF 26 +#define WMI_SETPOWER_MDOE_TO_REC 27 +#define WMI_BSSINFO_EVENT_FROM 28 +#define WMI_TARGET_GET_STATS_CMD 29 +#define WMI_SENDING_SCAN_COMPLETE_EVENT 30 +#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31 +#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32 +#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33 +#define WMI_SENDING_ERROR_REPORT_EVENT 34 +#define WMI_SENDING_CAC_EVENT 35 +#define WMI_TARGET_GET_ROAM_TABLE_CMD 36 +#define WMI_TARGET_GET_ROAM_DATA_CMD 37 +#define WMI_SENDING_GPIO_INTR_EVENT 38 +#define WMI_SENDING_GPIO_ACK_EVENT 39 +#define WMI_SENDING_GPIO_DATA_EVENT 40 +#define WMI_CMD_RX 41 +#define WMI_CMD_RX_XTND 42 +#define WMI_EVENT_SEND 43 +#define WMI_EVENT_SEND_XTND 44 +#define WMI_CMD_PARAMS_DUMP_START 45 +#define WMI_CMD_PARAMS_DUMP_END 46 +#define WMI_CMD_PARAMS 47 +#define WMI_EVENT_ALLOC_FAILURE 48 +#define WMI_DBGID_DCS_PARAM_CMD 49 +#define WMI_SEND_EVENT_WRONG_TLV 50 +#define WMI_SEND_EVENT_NO_TLV_DEF 51 +#define WMI_DBGID_DEFINITION_END 52 + +/* PM Message definition*/ +#define PS_STA_DEFINITION_START 0 +#define PS_STA_PM_ARB_REQUEST 1 +#define PS_STA_DELIVER_EVENT 2 +#define PS_STA_PSPOLL_SEQ_DONE 3 +#define PS_STA_COEX_MODE 4 +#define PS_STA_PSPOLL_ALLOW 5 +#define PS_STA_SET_PARAM 6 +#define PS_STA_SPECPOLL_TIMER_STARTED 7 +#define PS_STA_SPECPOLL_TIMER_STOPPED 8 +#define PS_STA_AVG_CHANNEL_CONGESTION 9 +#define PS_STA_DEFINITION_END 10 + +/** RESMGR dbg ids */ +/* TODO: 1. Segregate IDs as per sub-module. (Give 100 per sub-module?) + * 2. Add chmgr IDs over here. + * 3. Update prints in dbglog_host.c + * 4. Deprecate WLAN_MODULE_RESMGR_CHAN_MANAGER */ +#define RESMGR_DEFINITION_START 0 +#define RESMGR_OCS_ALLOCRAM_SIZE 1 +#define RESMGR_OCS_RESOURCES 2 +#define RESMGR_LINK_CREATE 3 +#define RESMGR_LINK_DELETE 4 +#define RESMGR_OCS_CHREQ_CREATE 5 +#define RESMGR_OCS_CHREQ_DELETE 6 +#define RESMGR_OCS_CHREQ_START 7 +#define RESMGR_OCS_CHREQ_STOP 8 +#define RESMGR_OCS_SCHEDULER_INVOKED 9 +#define RESMGR_OCS_CHREQ_GRANT 10 +#define RESMGR_OCS_CHREQ_COMPLETE 11 +#define RESMGR_OCS_NEXT_TSFTIME 12 +#define RESMGR_OCS_TSF_TIMEOUT_US 13 +#define RESMGR_OCS_CURR_CAT_WINDOW 14 +#define RESMGR_OCS_CURR_CAT_WINDOW_REQ 15 +#define RESMGR_OCS_CURR_CAT_WINDOW_TIMESLOT 16 +#define RESMGR_OCS_CHREQ_RESTART 17 +#define RESMGR_OCS_CLEANUP_CH_ALLOCATORS 18 +#define RESMGR_OCS_PURGE_CHREQ 19 +#define RESMGR_OCS_CH_ALLOCATOR_FREE 20 +#define RESMGR_OCS_RECOMPUTE_SCHEDULE 21 +#define RESMGR_OCS_NEW_CAT_WINDOW_REQ 22 +#define RESMGR_OCS_NEW_CAT_WINDOW_TIMESLOT 23 +#define RESMGR_OCS_CUR_CH_ALLOC 24 +#define RESMGR_OCS_WIN_CH_ALLOC 25 +#define RESMGR_OCS_SCHED_CH_CHANGE 26 +#define RESMGR_OCS_CONSTRUCT_CAT_WIN 27 +#define RESMGR_OCS_CHREQ_PREEMPTED 28 +#define RESMGR_OCS_CH_SWITCH_REQ 29 +#define RESMGR_OCS_CHANNEL_SWITCHED 30 +#define RESMGR_OCS_CLEANUP_STALE_REQS 31 +#define RESMGR_OCS_CHREQ_UPDATE 32 +#define RESMGR_OCS_REG_NOA_NOTIF 33 +#define RESMGR_OCS_DEREG_NOA_NOTIF 34 +#define RESMGR_OCS_GEN_PERIODIC_NOA 35 +#define RESMGR_OCS_RECAL_QUOTAS 36 +#define RESMGR_OCS_GRANTED_QUOTA_STATS 37 +#define RESMGR_OCS_ALLOCATED_QUOTA_STATS 38 +#define RESMGR_OCS_REQ_QUOTA_STATS 39 +#define RESMGR_OCS_TRACKING_TIME_FIRED 40 +#define RESMGR_VC_ARBITRATE_ATTRIBUTES 41 +#define RESMGR_OCS_LATENCY_STRICT_TIME_SLOT 42 +#define RESMGR_OCS_CURR_TSF 43 +#define RESMGR_OCS_QUOTA_REM 44 +#define RESMGR_OCS_LATENCY_CASE_NO 45 +#define RESMGR_OCS_WIN_CAT_DUR 46 +#define RESMGR_VC_UPDATE_CUR_VC 47 +#define RESMGR_VC_REG_UNREG_LINK 48 +#define RESMGR_VC_PRINT_LINK 49 +#define RESMGR_OCS_MISS_TOLERANCE 50 +#define RESMGR_DYN_SCH_ALLOCRAM_SIZE 51 +#define RESMGR_DYN_SCH_ENABLE 52 +#define RESMGR_DYN_SCH_ACTIVE 53 +#define RESMGR_DYN_SCH_CH_STATS_START 54 +#define RESMGR_DYN_SCH_CH_SX_STATS 55 +#define RESMGR_DYN_SCH_TOT_UTIL_PER 56 +#define RESMGR_DYN_SCH_HOME_CH_QUOTA 57 +#define RESMGR_OCS_REG_RECAL_QUOTA_NOTIF 58 +#define RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF 59 +#define RESMGR_DYN_SCH_CH_STATS_END 60 +#define RESMGR_DEFINITION_END 61 + +/* RESMGR CHNMGR debug ids */ +#define RESMGR_CHMGR_DEFINITION_START 0 +#define RESMGR_CHMGR_PAUSE_COMPLETE 1 +#define RESMGR_CHMGR_CHANNEL_CHANGE 2 +#define RESMGR_CHMGR_RESUME_COMPLETE 3 +#define RESMGR_CHMGR_VDEV_PAUSE 4 +#define RESMGR_CHMGR_VDEV_UNPAUSE 5 +#define RESMGR_CHMGR_CTS2S_TX_COMP 6 +#define RESMGR_CHMGR_CFEND_TX_COMP 7 +#define RESMGR_CHMGR_DEFINITION_END 8 + +/* VDEV manager debug ids */ +#define VDEV_MGR_DEFINITION_START 0 +#define VDEV_MGR_FIRST_BMISS_DETECTED 1 +#define VDEV_MGR_FINAL_BMISS_DETECTED 2 +#define VDEV_MGR_BCN_IN_SYNC 3 +#define VDEV_MGR_AP_KEEPALIVE_IDLE 4 +#define VDEV_MGR_AP_KEEPALIVE_INACTIVE 5 +#define VDEV_MGR_AP_KEEPALIVE_UNRESPONSIVE 6 +#define VDEV_MGR_AP_TBTT_CONFIG 7 +#define VDEV_MGR_FIRST_BCN_RECEIVED 8 +#define VDEV_MGR_VDEV_START 9 +#define VDEV_MGR_VDEV_UP 10 +#define VDEV_MGR_PEER_AUTHORIZED 11 +#define VDEV_MGR_OCS_HP_LP_REQ_POSTED 12 +#define VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE 13 +#define VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP 14 +#define VDEV_MGR_HP_START_TIME 15 +#define VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE 16 +#define VDEV_MGR_VDEV_PAUSE_FAIL 17 +#define VDEV_MGR_GEN_PERIODIC_NOA 18 +#define VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP 19 +#define VDEV_MGR_DEFINITION_END 20 + +/* WHAL debug identifier definitions */ +#define WHAL_DBGID_DEFINITION_START 0 +#define WHAL_ERROR_ANI_CONTROL 1 +#define WHAL_ERROR_CHIP_TEST1 2 +#define WHAL_ERROR_CHIP_TEST2 3 +#define WHAL_ERROR_EEPROM_CHECKSUM 4 +#define WHAL_ERROR_EEPROM_MACADDR 5 +#define WHAL_ERROR_INTERRUPT_HIU 6 +#define WHAL_ERROR_KEYCACHE_RESET 7 +#define WHAL_ERROR_KEYCACHE_SET 8 +#define WHAL_ERROR_KEYCACHE_TYPE 9 +#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10 +#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11 +#define WHAL_ERROR_PHY_INVALID_CHANNEL 12 +#define WHAL_ERROR_POWER_AWAKE 13 +#define WHAL_ERROR_POWER_SET 14 +#define WHAL_ERROR_RECV_STOPDMA 15 +#define WHAL_ERROR_RECV_STOPPCU 16 +#define WHAL_ERROR_RESET_CHANNF1 17 +#define WHAL_ERROR_RESET_CHANNF2 18 +#define WHAL_ERROR_RESET_PM 19 +#define WHAL_ERROR_RESET_OFFSETCAL 20 +#define WHAL_ERROR_RESET_RFGRANT 21 +#define WHAL_ERROR_RESET_RXFRAME 22 +#define WHAL_ERROR_RESET_STOPDMA 23 +#define WHAL_ERROR_RESET_ERRID 24 +#define WHAL_ERROR_RESET_ADCDCCAL1 25 +#define WHAL_ERROR_RESET_ADCDCCAL2 26 +#define WHAL_ERROR_RESET_TXIQCAL 27 +#define WHAL_ERROR_RESET_RXIQCAL 28 +#define WHAL_ERROR_RESET_CARRIERLEAK 29 +#define WHAL_ERROR_XMIT_COMPUTE 30 +#define WHAL_ERROR_XMIT_NOQUEUE 31 +#define WHAL_ERROR_XMIT_ACTIVEQUEUE 32 +#define WHAL_ERROR_XMIT_BADTYPE 33 +#define WHAL_ERROR_XMIT_STOPDMA 34 +#define WHAL_ERROR_INTERRUPT_BB_PANIC 35 +#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 36 +#define WHAL_ERROR_QCU_HW_PAUSE_MISMATCH 37 +#define WHAL_ERROR_POWER_RFLP_CONFIG 38 +#define WHAL_ERROR_POWER_RFLP_SYNTHBYPASS_CONFIG 39 +#define WHAL_ERROR_POWER_RFLP_BIAS2X_CONFIG 40 +#define WHAL_ERROR_POWER_RFLP_PLLBYPASS_CONFIG 41 +#define WHAL_ERROR_POWER_RFLP_OFF1CHAN_CONFIG 42 +#define WHAL_ERROR_POWER_ANTENNA_LMIT 43 +#define WHAL_ERROR_POWER_REGDMN_TX_LMIT 44 +#define WHAL_ERROR_POWER_MODE_SCALED_PWR 45 +#define WHAL_ERROR_POWER_EDGE_PWR_TPSCALE 46 +#define WHAL_ERROR_POWER_CHAN_REGALLOW 47 +#define WHAL_ERROR_WAIT_REG_TIMEOUT 48 +#define WHAL_ERROR_XTAL_SET 49 +#define WHAL_DBGID_DEFINITION_END 50 + +#define COEX_DEBUGID_START 0 +#define BTCOEX_DBG_MCI_1 1 +#define BTCOEX_DBG_MCI_2 2 +#define BTCOEX_DBG_MCI_3 3 +#define BTCOEX_DBG_MCI_4 4 +#define BTCOEX_DBG_MCI_5 5 +#define BTCOEX_DBG_MCI_6 6 +#define BTCOEX_DBG_MCI_7 7 +#define BTCOEX_DBG_MCI_8 8 +#define BTCOEX_DBG_MCI_9 9 +#define BTCOEX_DBG_MCI_10 10 +#define COEX_WAL_BTCOEX_INIT 11 +#define COEX_WAL_PAUSE 12 +#define COEX_WAL_RESUME 13 +#define COEX_UPDATE_AFH 14 +#define COEX_HWQ_EMPTY_CB 15 +#define COEX_MCI_TIMER_HANDLER 16 +#define COEX_MCI_RECOVER 17 +#define ERROR_COEX_MCI_ISR 18 +#define ERROR_COEX_MCI_GPM 19 +#define COEX_ProfileType 20 +#define COEX_LinkID 21 +#define COEX_LinkState 22 +#define COEX_LinkRole 23 +#define COEX_LinkRate 24 +#define COEX_VoiceType 25 +#define COEX_TInterval 26 +#define COEX_WRetrx 27 +#define COEX_Attempts 28 +#define COEX_PerformanceState 29 +#define COEX_LinkType 30 +#define COEX_RX_MCI_GPM_VERSION_QUERY 31 +#define COEX_RX_MCI_GPM_VERSION_RESPONSE 32 +#define COEX_RX_MCI_GPM_STATUS_QUERY 33 +#define COEX_STATE_WLAN_VDEV_DOWN 34 +#define COEX_STATE_WLAN_VDEV_START 35 +#define COEX_STATE_WLAN_VDEV_CONNECTED 36 +#define COEX_STATE_WLAN_VDEV_SCAN_STARTED 37 +#define COEX_STATE_WLAN_VDEV_SCAN_END 38 +#define COEX_STATE_WLAN_DEFAULT 39 +#define COEX_CHANNEL_CHANGE 40 +#define COEX_POWER_CHANGE 41 +#define COEX_CONFIG_MGR 42 +#define COEX_TX_MCI_GPM_BT_CAL_REQ 43 +#define COEX_TX_MCI_GPM_BT_CAL_GRANT 44 +#define COEX_TX_MCI_GPM_BT_CAL_DONE 45 +#define COEX_TX_MCI_GPM_WLAN_CAL_REQ 46 +#define COEX_TX_MCI_GPM_WLAN_CAL_GRANT 47 +#define COEX_TX_MCI_GPM_WLAN_CAL_DONE 48 +#define COEX_TX_MCI_GPM_BT_DEBUG 49 +#define COEX_TX_MCI_GPM_VERSION_QUERY 50 +#define COEX_TX_MCI_GPM_VERSION_RESPONSE 51 +#define COEX_TX_MCI_GPM_STATUS_QUERY 52 +#define COEX_TX_MCI_GPM_HALT_BT_GPM 53 +#define COEX_TX_MCI_GPM_WLAN_CHANNELS 54 +#define COEX_TX_MCI_GPM_BT_PROFILE_INFO 55 +#define COEX_TX_MCI_GPM_BT_STATUS_UPDATE 56 +#define COEX_TX_MCI_GPM_BT_UPDATE_FLAGS 57 +#define COEX_TX_MCI_GPM_UNKNOWN 58 +#define COEX_TX_MCI_SYS_WAKING 59 +#define COEX_TX_MCI_LNA_TAKE 60 +#define COEX_TX_MCI_LNA_TRANS 61 +#define COEX_TX_MCI_SYS_SLEEPING 62 +#define COEX_TX_MCI_REQ_WAKE 63 +#define COEX_TX_MCI_REMOTE_RESET 64 +#define COEX_TX_MCI_TYPE_UNKNOWN 65 +#define COEX_WHAL_MCI_RESET 66 +#define COEX_POLL_BT_CAL_DONE_TIMEOUT 67 +#define COEX_WHAL_PAUSE 68 +#define COEX_RX_MCI_GPM_BT_CAL_REQ 69 +#define COEX_RX_MCI_GPM_BT_CAL_DONE 70 +#define COEX_RX_MCI_GPM_BT_CAL_GRANT 71 +#define COEX_WLAN_CAL_START 72 +#define COEX_WLAN_CAL_RESULT 73 +#define COEX_BtMciState 74 +#define COEX_BtCalState 75 +#define COEX_WlanCalState 76 +#define COEX_RxReqWakeCount 77 +#define COEX_RxRemoteResetCount 78 +#define COEX_RESTART_CAL 79 +#define COEX_SENDMSG_QUEUE 80 +#define COEX_RESETSEQ_LNAINFO_TIMEOUT 81 +#define COEX_MCI_ISR_IntRaw 82 +#define COEX_MCI_ISR_Int1Raw 83 +#define COEX_MCI_ISR_RxMsgRaw 84 +#define COEX_WHAL_COEX_RESET 85 +#define COEX_WAL_COEX_INIT 86 +#define COEX_TXRX_CNT_LIMIT_ISR 87 +#define COEX_CH_BUSY 88 +#define COEX_REASSESS_WLAN_STATE 89 +#define COEX_BTCOEX_WLAN_STATE_UPDATE 90 +#define COEX_BT_NUM_OF_PROFILES 91 +#define COEX_BT_NUM_OF_HID_PROFILES 92 +#define COEX_BT_NUM_OF_ACL_PROFILES 93 +#define COEX_BT_NUM_OF_HI_ACL_PROFILES 94 +#define COEX_BT_NUM_OF_VOICE_PROFILES 95 +#define COEX_WLAN_AGGR_LIMIT 96 +#define COEX_BT_LOW_PRIO_BUDGET 97 +#define COEX_BT_HI_PRIO_BUDGET 98 +#define COEX_BT_IDLE_TIME 99 +#define COEX_SET_COEX_WEIGHT 100 +#define COEX_WLAN_WEIGHT_GROUP 101 +#define COEX_BT_WEIGHT_GROUP 102 +#define COEX_BT_INTERVAL_ALLOC 103 +#define COEX_BT_SCHEME 104 +#define COEX_BT_MGR 105 +#define COEX_BT_SM_ERROR 106 +#define COEX_SYSTEM_UPDATE 107 +#define COEX_LOW_PRIO_LIMIT 108 +#define COEX_HI_PRIO_LIMIT 109 +#define COEX_BT_INTERVAL_START 110 +#define COEX_WLAN_INTERVAL_START 111 +#define COEX_NON_LINK_BUDGET 112 +#define COEX_CONTENTION_MSG 113 +#define COEX_SET_NSS 114 +#define COEX_SELF_GEN_MASK 115 +#define COEX_PROFILE_ERROR 116 +#define COEX_WLAN_INIT 117 +#define COEX_BEACON_MISS 118 +#define COEX_BEACON_OK 119 +#define COEX_BTCOEX_SCAN_ACTIVITY 120 +#define COEX_SCAN_ACTIVITY 121 +#define COEX_FORCE_QUIETTIME 122 +#define COEX_BT_MGR_QUIETTIME 123 +#define COEX_BT_INACTIVITY_TRIGGER 124 +#define COEX_BT_INACTIVITY_REPORTED 125 +#define COEX_TX_MCI_GPM_WLAN_PRIO 126 +#define COEX_TX_MCI_GPM_BT_PAUSE_PROFILE 127 +#define COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY 128 +#define COEX_RX_MCI_GPM_BT_ACL_INACTIVITY_REPORT 129 +#define COEX_GENERIC_ERROR 130 +#define COEX_RX_RATE_THRESHOLD 131 +#define COEX_RSSI 132 + +#define COEX_WLAN_VDEV_NOTIF_START 133 +#define COEX_WLAN_VDEV_NOTIF_UP 134 +#define COEX_WLAN_VDEV_NOTIF_DOWN 135 +#define COEX_WLAN_VDEV_NOTIF_STOP 136 +#define COEX_WLAN_VDEV_NOTIF_ADD_PEER 137 +#define COEX_WLAN_VDEV_NOTIF_DELETE_PEER 138 +#define COEX_WLAN_VDEV_NOTIF_CONNECTED_PEER 139 +#define COEX_WLAN_VDEV_NOTIF_PAUSE 140 +#define COEX_WLAN_VDEV_NOTIF_UNPAUSED 141 +#define COEX_STATE_WLAN_VDEV_PEER_ADD 142 +#define COEX_STATE_WLAN_VDEV_CONNECTED_PEER 143 +#define COEX_STATE_WLAN_VDEV_DELETE_PEER 144 +#define COEX_STATE_WLAN_VDEV_PAUSE 145 +#define COEX_STATE_WLAN_VDEV_UNPAUSED 146 +#define COEX_SCAN_CALLBACK 147 +#define COEX_RC_SET_CHAINMASK 148 +#define COEX_TX_MCI_GPM_WLAN_SET_BT_RXSS_THRES 149 +#define COEX_TX_MCI_GPM_BT_RXSS_THRES_QUERY 150 +#define COEX_BT_RXSS_THRES 151 +#define COEX_BT_PROFILE_ADD_RMV 152 +#define COEX_BT_SCHED_INFO 153 +#define COEX_TRF_MGMT 154 +#define COEX_SCHED_START 155 +#define COEX_SCHED_RESULT 156 +#define COEX_SCHED_ERROR 157 +#define COEX_SCHED_PRE_OP 158 +#define COEX_SCHED_POST_OP 159 +#define COEX_RX_RATE 160 +#define COEX_ACK_PRIORITY 161 +#define COEX_STATE_WLAN_VDEV_UP 162 +#define COEX_STATE_WLAN_VDEV_PEER_UPDATE 163 +#define COEX_STATE_WLAN_VDEV_STOP 164 +#define COEX_WLAN_PAUSE_PEER 165 +#define COEX_WLAN_UNPAUSE_PEER 166 +#define COEX_WLAN_PAUSE_INTERVAL_START 167 +#define COEX_WLAN_POSTPAUSE_INTERVAL_START 168 +#define COEX_TRF_FREERUN 169 +#define COEX_TRF_SHAPE_PM 170 +#define COEX_TRF_SHAPE_PSP 171 +#define COEX_TRF_SHAPE_S_CTS 172 +#define COEX_CHAIN_CONFIG 173 +#define COEX_SYSTEM_MONITOR 174 +#define COEX_SINGLECHAIN_INIT 175 +#define COEX_MULTICHAIN_INIT 176 +#define COEX_SINGLECHAIN_DBG_1 177 +#define COEX_SINGLECHAIN_DBG_2 178 +#define COEX_SINGLECHAIN_DBG_3 179 +#define COEX_MULTICHAIN_DBG_1 180 +#define COEX_MULTICHAIN_DBG_2 181 +#define COEX_MULTICHAIN_DBG_3 182 +#define COEX_PSP_TX_CB 183 +#define COEX_PSP_RX_CB 184 +#define COEX_PSP_STAT_1 185 +#define COEX_PSP_SPEC_POLL 186 +#define COEX_PSP_READY_STATE 187 +#define COEX_PSP_TX_STATUS_STATE 188 +#define COEX_PSP_RX_STATUS_STATE_1 189 +#define COEX_PSP_NOT_READY_STATE 190 +#define COEX_PSP_DISABLED_STATE 191 +#define COEX_PSP_ENABLED_STATE 192 +#define COEX_PSP_SEND_PSPOLL 193 +#define COEX_PSP_MGR_ENTER 194 +#define COEX_PSP_MGR_RESULT 195 +#define COEX_PSP_NONWLAN_INTERVAL 196 +#define COEX_PSP_STAT_2 197 +#define COEX_PSP_RX_STATUS_STATE_2 198 +#define COEX_PSP_ERROR 199 +#define COEX_T2BT 200 +#define COEX_BT_DURATION 201 +#define COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG 202 +#define COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP 203 +#define COEX_TX_MCI_GPM_SCAN_OP 204 +#define COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX 205 +#define COEX_CTS2S_SEND 206 +#define COEX_CTS2S_RESULT 207 +#define COEX_ENTER_OCS 208 +#define COEX_EXIT_OCS 209 +#define COEX_UPDATE_OCS 210 +#define COEX_STATUS_OCS 211 +#define COEX_STATS_BT 212 + +#define COEX_MWS_WLAN_INIT 213 +#define COEX_MWS_WBTMR_SYNC 214 +#define COEX_MWS_TYPE2_RX 215 +#define COEX_MWS_TYPE2_TX 216 +#define COEX_MWS_WLAN_CHAVD 217 +#define COEX_MWS_WLAN_CHAVD_INSERT 218 +#define COEX_MWS_WLAN_CHAVD_MERGE 219 +#define COEX_MWS_WLAN_CHAVD_RPT 220 +#define COEX_MWS_CP_MSG_SEND 221 +#define COEX_MWS_CP_ESCAPE 222 +#define COEX_MWS_CP_UNFRAME 223 +#define COEX_MWS_CP_SYNC_UPDATE 224 +#define COEX_MWS_CP_SYNC 225 +#define COEX_MWS_CP_WLAN_STATE_IND 226 +#define COEX_MWS_CP_SYNCRESP_TIMEOUT 227 +#define COEX_MWS_SCHEME_UPDATE 228 +#define COEX_MWS_WLAN_EVENT 229 +#define COEX_MWS_UART_UNESCAPE 230 +#define COEX_MWS_UART_ENCODE_SEND 231 +#define COEX_MWS_UART_RECV_DECODE 232 +#define COEX_MWS_UL_HDL 233 +#define COEX_MWS_REMOTE_EVENT 234 +#define COEX_MWS_OTHER 235 +#define COEX_MWS_ERROR 236 +#define COEX_MWS_ANT_DIVERSITY 237 + +#define COEX_P2P_GO 238 +#define COEX_P2P_CLIENT 239 +#define COEX_SCC_1 240 +#define COEX_SCC_2 241 +#define COEX_MCC_1 242 +#define COEX_MCC_2 243 +#define COEX_TRF_SHAPE_NOA 244 +#define COEX_NOA_ONESHOT 245 +#define COEX_NOA_PERIODIC 246 +#define COEX_LE_1 247 +#define COEX_LE_2 248 +#define COEX_ANT_1 249 +#define COEX_ANT_2 250 +#define COEX_ENTER_NOA 251 +#define COEX_EXIT_NOA 252 +#define COEX_BT_SCAN_PROTECT 253 + +#define COEX_DEBUG_ID_END 254 + +#define SCAN_START_COMMAND_FAILED 0 +#define SCAN_STOP_COMMAND_FAILED 1 +#define SCAN_EVENT_SEND_FAILED 2 +#define SCAN_ENGINE_START 3 +#define SCAN_ENGINE_CANCEL_COMMAND 4 +#define SCAN_ENGINE_STOP_DUE_TO_TIMEOUT 5 +#define SCAN_EVENT_SEND_TO_HOST 6 +#define SCAN_FWLOG_EVENT_ADD 7 +#define SCAN_FWLOG_EVENT_REM 8 +#define SCAN_FWLOG_EVENT_PREEMPTED 9 +#define SCAN_FWLOG_EVENT_RESTARTED 10 +#define SCAN_FWLOG_EVENT_COMPLETED 11 +#define SCAN_SM_REQ_NEXT_CH 12 +#define SCAN_DBGID_DEFINITION_END 13 + +#define BEACON_EVENT_SWBA_SEND_FAILED 0 +#define BEACON_EVENT_EARLY_RX_BMISS_STATUS 1 +#define BEACON_EVENT_EARLY_RX_SLEEP_SLOP 2 +#define BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT 3 +#define BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM 4 +#define BEACON_EVENT_EARLY_RX_CLK_DRIFT 5 +#define BEACON_EVENT_EARLY_RX_AP_DRIFT 6 +#define BEACON_EVENT_EARLY_RX_BCN_TYPE 7 + +#define RATECTRL_DBGID_DEFINITION_START 0 +#define RATECTRL_DBGID_ASSOC 1 +#define RATECTRL_DBGID_NSS_CHANGE 2 +#define RATECTRL_DBGID_CHAINMASK_ERR 3 +#define RATECTRL_DBGID_UNEXPECTED_FRAME 4 +#define RATECTRL_DBGID_WAL_RCQUERY 5 +#define RATECTRL_DBGID_WAL_RCUPDATE 6 +#define RATECTRL_DBGID_GTX_UPDATE 7 +#define RATECTRL_DBGID_DEFINITION_END 8 + +#define AP_PS_DBGID_DEFINITION_START 0 +#define AP_PS_DBGID_UPDATE_TIM 1 +#define AP_PS_DBGID_PEER_STATE_CHANGE 2 +#define AP_PS_DBGID_PSPOLL 3 +#define AP_PS_DBGID_PEER_CREATE 4 +#define AP_PS_DBGID_PEER_DELETE 5 +#define AP_PS_DBGID_VDEV_CREATE 6 +#define AP_PS_DBGID_VDEV_DELETE 7 +#define AP_PS_DBGID_SYNC_TIM 8 +#define AP_PS_DBGID_NEXT_RESPONSE 9 +#define AP_PS_DBGID_START_SP 10 +#define AP_PS_DBGID_COMPLETED_EOSP 11 +#define AP_PS_DBGID_TRIGGER 12 +#define AP_PS_DBGID_DUPLICATE_TRIGGER 13 +#define AP_PS_DBGID_UAPSD_RESPONSE 14 +#define AP_PS_DBGID_SEND_COMPLETE 15 +#define AP_PS_DBGID_SEND_N_COMPLETE 16 +#define AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA 17 +#define AP_PS_DBGID_DELIVER_CAB 18 +#define AP_PS_DBGID_NO_CLIENT 27 +#define AP_PS_DBGID_CLIENT_IN_PS_ACTIVE 28 +#define AP_PS_DBGID_CLIENT_IN_PS_NON_ACTIVE 29 +#define AP_PS_DBGID_CLIENT_IN_AWAKE 30 + +/* WLAN_MODULE_MGMT_TXRX Debugids*/ +#define MGMT_TXRX_DBGID_DEFINITION_START 0 +#define MGMT_TXRX_FORWARD_TO_HOST 1 +#define MGMT_TXRX_DBGID_DEFINITION_END 2 + +#define WAL_DBGID_DEFINITION_START 0 +#define WAL_DBGID_FAST_WAKE_REQUEST 1 +#define WAL_DBGID_FAST_WAKE_RELEASE 2 +#define WAL_DBGID_SET_POWER_STATE 3 +#define WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET 5 +#define WAL_DBGID_CHANNEL_CHANGE 6 +#define WAL_DBGID_VDEV_START 7 +#define WAL_DBGID_VDEV_STOP 8 +#define WAL_DBGID_VDEV_UP 9 +#define WAL_DBGID_VDEV_DOWN 10 +#define WAL_DBGID_SW_WDOG_RESET 11 +#define WAL_DBGID_TX_SCH_REGISTER_TIDQ 12 +#define WAL_DBGID_TX_SCH_UNREGISTER_TIDQ 13 +#define WAL_DBGID_TX_SCH_TICKLE_TIDQ 14 + + +#define WAL_DBGID_XCESS_FAILURES 15 +#define WAL_DBGID_AST_ADD_WDS_ENTRY 16 +#define WAL_DBGID_AST_DEL_WDS_ENTRY 17 +#define WAL_DBGID_AST_WDS_ENTRY_PEER_CHG 18 +#define WAL_DBGID_AST_WDS_SRC_LEARN_FAIL 19 +#define WAL_DBGID_STA_KICKOUT 20 +#define WAL_DBGID_BAR_TX_FAIL 21 +#define WAL_DBGID_BAR_ALLOC_FAIL 22 +#define WAL_DBGID_LOCAL_DATA_TX_FAIL 23 +#define WAL_DBGID_SECURITY_PM4_QUEUED 24 +#define WAL_DBGID_SECURITY_GM1_QUEUED 25 +#define WAL_DBGID_SECURITY_PM4_SENT 26 +#define WAL_DBGID_SECURITY_ALLOW_DATA 27 +#define WAL_DBGID_SECURITY_UCAST_KEY_SET 28 +#define WAL_DBGID_SECURITY_MCAST_KEY_SET 29 +#define WAL_DBGID_SECURITY_ENCR_EN 30 +#define WAL_DBGID_BB_WDOG_TRIGGERED 31 +#define WAL_DBGID_RX_LOCAL_BUFS_LWM 32 +#define WAL_DBGID_RX_LOCAL_DROP_LARGE_MGMT 33 +#define WAL_DBGID_VHT_ILLEGAL_RATE_PHY_ERR_DETECTED 34 +#define WAL_DBGID_DEV_RESET 35 +#define WAL_DBGID_TX_BA_SETUP 36 +#define WAL_DBGID_RX_BA_SETUP 37 +#define WAL_DBGID_DEV_TX_TIMEOUT 38 +#define WAL_DBGID_DEV_RX_TIMEOUT 39 +#define WAL_DBGID_STA_VDEV_XRETRY 40 +#define WAL_DBGID_DCS 41 +#define WAL_DBGID_MGMT_TX_FAIL 42 +#define WAL_DBGID_SET_M4_SENT_MANUALLY 43 +#define WAL_DBGID_PROCESS_4_WAY_HANDSHAKE 44 +#define WAL_DBGID_WAL_CHANNEL_CHANGE_START 45 +#define WAL_DBGID_WAL_CHANNEL_CHANGE_COMPLETE 46 +#define WAL_DBGID_WHAL_CHANNEL_CHANGE_START 47 +#define WAL_DBGID_WHAL_CHANNEL_CHANGE_COMPLETE 48 +#define WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN 49 +#define WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN 50 +#define WAL_DBGID_TX_DISCARD 51 +#define WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS 52 +#define WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS 53 +#define WAL_DBGID_RESET_PCU_CYCLE_CNT 54 +#define WAL_DBGID_SETUP_RSSI_INTERRUPTS 55 +#define WAL_DBGID_BRSSI_CONFIG 56 +#define WAL_DBGID_CURRENT_BRSSI_AVE 57 +#define WAL_DBGID_BCN_TX_COMP 58 +#define WAL_DBGID_RX_REENTRY 59 +#define WAL_DBGID_SET_HW_CHAINMASK 60 +#define WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL 61 +#define WAL_DBGID_GET_HW_CHAINMASK 62 +#define WAL_DBGID_SMPS_DISABLE 63 +#define WAL_DBGID_SMPS_ENABLE_HW_CNTRL 64 +#define WAL_DBGID_SMPS_SWSEL_CHAINMASK 65 +#define WAL_DBGID_SUSPEND 66 +#define WAL_DBGID_RESUME 67 +#define WAL_DBGID_PEER_TX_FAIL_CNT_THRES_EXCEEDED 68 +#define WAL_DBGID_RX_FULL_REORDER_SUPPORT 69 +#if defined(AR900B) +#define WAL_DBGID_HCM_BIN 70 +#define WAL_DBGID_HCM_BIN_PENALIZE 71 +#define WAL_DBGID_HCM_BIN_DEPENALIZE 72 +#define WAL_DBGID_AST_UPDATE_WDS_ENTRY 73 +#define WAL_DBGID_PEER_EXT_STATS 74 +#define WAL_DBGID_TX_AC_BUFFER_SET 75 +#define WAL_DBGID_AST_ENTRY_EXIST 76 +#define WAL_DBGID_AST_ENTRY_FULL 77 +#define WAL_DBGID_DEFINITION_END 78 +#else +#define WAL_DBGID_DEFINITION_END 70 +#endif + +#define ANI_DBGID_POLL 0 +#define ANI_DBGID_CONTROL 1 +#define ANI_DBGID_OFDM_PARAMS 2 +#define ANI_DBGID_CCK_PARAMS 3 +#define ANI_DBGID_RESET 4 +#define ANI_DBGID_RESTART 5 +#define ANI_DBGID_OFDM_LEVEL 6 +#define ANI_DBGID_CCK_LEVEL 7 +#define ANI_DBGID_FIRSTEP 8 +#define ANI_DBGID_CYCPWR 9 +#define ANI_DBGID_MRC_CCK 10 +#define ANI_DBGID_SELF_CORR_LOW 11 +#define ANI_DBGID_ENABLE 12 + +#define ANI_DBGID_CURRENT_LEVEL 13 +#define ANI_DBGID_POLL_PERIOD 14 +#define ANI_DBGID_LISTEN_PERIOD 15 +#define ANI_DBGID_OFDM_LEVEL_CFG 16 +#define ANI_DBGID_CCK_LEVEL_CFG 17 + +/* OFFLOAD Manager Debugids*/ +#define OFFLOAD_MGR_DBGID_DEFINITION_START 0 +#define OFFLOADMGR_REGISTER_OFFLOAD 1 +#define OFFLOADMGR_DEREGISTER_OFFLOAD 2 +#define OFFLOADMGR_NO_REG_DATA_HANDLERS 3 +#define OFFLOADMGR_NO_REG_EVENT_HANDLERS 4 +#define OFFLOADMGR_REG_OFFLOAD_FAILED 5 +#define OFFLOADMGR_DEREG_OFFLOAD_FAILED 6 +#define OFFLOADMGR_ENTER_FAILED 7 +#define OFFLOADMGR_EXIT_FAILED 8 +#define OFFLOADMGR_DBGID_DEFINITION_END 9 + +/*Resource Debug IDs*/ +#define RESOURCE_DBGID_DEFINITION_START 0 +#define RESOURCE_PEER_ALLOC 1 +#define RESOURCE_PEER_FREE 2 +#define RESOURCE_PEER_ALLOC_WAL_PEER 3 +#define RESOURCE_PEER_NBRHOOD_MGMT_ALLOC 4 +#define RESOURCE_PEER_NBRHOOD_MGMT_INFO 5 +#define RESOURCE_DBGID_DEFINITION_END 6 + +/* DCS debug IDs*/ +#define WLAN_DCS_DBGID_INIT 0 +#define WLAN_DCS_DBGID_WMI_CWINT 1 +#define WLAN_DCS_DBGID_TIMER 2 +#define WLAN_DCS_DBGID_CMDG 3 +#define WLAN_DCS_DBGID_CMDS 4 +#define WLAN_DCS_DBGID_DINIT 5 + +/*P2P Module ids*/ +#define P2P_DBGID_DEFINITION_START 0 +#define P2P_DEV_REGISTER 1 +#define P2P_HANDLE_NOA 2 +#define P2P_UPDATE_SCHEDULE_OPPS 3 +#define P2P_UPDATE_SCHEDULE 4 +#define P2P_UPDATE_START_TIME 5 +#define P2P_UPDATE_START_TIME_DIFF_TSF32 6 +#define P2P_UPDATE_START_TIME_FINAL 7 +#define P2P_SETUP_SCHEDULE_TIMER 8 +#define P2P_PROCESS_SCHEDULE_AFTER_CALC 9 +#define P2P_PROCESS_SCHEDULE_STARTED_TIMER 10 +#define P2P_CALC_SCHEDULES_FIRST_CALL_ALL_NEXT_EVENT 11 +#define P2P_CALC_SCHEDULES_FIRST_VALUE 12 +#define P2P_CALC_SCHEDULES_EARLIEST_NEXT_EVENT 13 +#define P2P_CALC_SCHEDULES_SANITY_COUNT 14 +#define P2P_CALC_SCHEDULES_CALL_ALL_NEXT_EVENT_FROM_WHILE_LOOP 15 +#define P2P_CALC_SCHEDULES_TIMEOUT_1 16 +#define P2P_CALC_SCHEDULES_TIMEOUT_2 17 +#define P2P_FIND_ALL_NEXT_EVENTS_REQ_EXPIRED 18 +#define P2P_FIND_ALL_NEXT_EVENTS_REQ_ACTIVE 19 +#define P2P_FIND_NEXT_EVENT_REQ_NOT_STARTED 20 +#define P2P_FIND_NEXT_EVENT_REQ_COMPLETE_NON_PERIODIC 21 +#define P2P_FIND_NEXT_EVENT_IN_MID_OF_NOA 22 +#define P2P_FIND_NEXT_EVENT_REQ_COMPLETE 23 +#define P2P_SCHEDULE_TIMEOUT 24 +#define P2P_CALC_SCHEDULES_ENTER 25 +#define P2P_PROCESS_SCHEDULE_ENTER 26 +#define P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_AFTER_CHANGE 27 +#define P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_BEFORE_CHANGE 28 +#define P2P_FIND_ALL_NEXT_EVENTS_ENTER 29 +#define P2P_FIND_NEXT_EVENT_ENTER 30 +#define P2P_NOA_GO_PRESENT 31 +#define P2P_NOA_GO_ABSENT 32 +#define P2P_GO_NOA_NOTIF 33 +#define P2P_GO_TBTT_OFFSET 34 +#define P2P_GO_GET_NOA_INFO 35 +#define P2P_GO_ADD_ONE_SHOT_NOA 36 +#define P2P_GO_GET_NOA_IE 37 +#define P2P_GO_BCN_TX_COMP 38 +#define P2P_DBGID_DEFINITION_END 39 + + +//CSA modules DBGIDs +#define CSA_DBGID_DEFINITION_START 0 +#define CSA_OFFLOAD_POOL_INIT 1 +#define CSA_OFFLOAD_REGISTER_VDEV 2 +#define CSA_OFFLOAD_DEREGISTER_VDEV 3 +#define CSA_DEREGISTER_VDEV_ERROR 4 +#define CSA_OFFLOAD_BEACON_RECEIVED 5 +#define CSA_OFFLOAD_BEACON_CSA_RECV 6 +#define CSA_OFFLOAD_CSA_RECV_ERROR_IE 7 +#define CSA_OFFLOAD_CSA_TIMER_ERROR 8 +#define CSA_OFFLOAD_CSA_TIMER_EXP 9 +#define CSA_OFFLOAD_WMI_EVENT_ERROR 10 +#define CSA_OFFLOAD_WMI_EVENT_SENT 11 +#define CSA_OFFLOAD_WMI_CHANSWITCH_RECV 12 +#define CSA_DBGID_DEFINITION_END 13 + +/* Chatter module DBGIDs */ +#define WLAN_CHATTER_DBGID_DEFINITION_START 0 +#define WLAN_CHATTER_ENTER 1 +#define WLAN_CHATTER_EXIT 2 +#define WLAN_CHATTER_FILTER_HIT 3 +#define WLAN_CHATTER_FILTER_MISS 4 +#define WLAN_CHATTER_FILTER_FULL 5 +#define WLAN_CHATTER_FILTER_TM_ADJ 6 +#define WLAN_CHATTER_BUFFER_FULL 7 +#define WLAN_CHATTER_TIMEOUT 8 +#define WLAN_CHATTER_MC_FILTER_ADD 9 +#define WLAN_CHATTER_MC_FILTER_DEL 10 +#define WLAN_CHATTER_MC_FILTER_ALLOW 11 +#define WLAN_CHATTER_MC_FILTER_DROP 12 +#define WLAN_CHATTER_COALESCING_FILTER_ADD 13 +#define WLAN_CHATTER_COALESCING_FILTER_DEL 14 +#define WLAN_CHATTER_DBGID_DEFINITION_END 15 + +#define WOW_DBGID_DEFINITION_START 0 +#define WOW_ENABLE_CMDID 1 +#define WOW_RECV_DATA_PKT 2 +#define WOW_WAKE_HOST_DATA 3 +#define WOW_RECV_MGMT 4 +#define WOW_WAKE_HOST_MGMT 5 +#define WOW_RECV_EVENT 6 +#define WOW_WAKE_HOST_EVENT 7 +#define WOW_INIT 8 +#define WOW_RECV_MAGIC_PKT 9 +#define WOW_RECV_BITMAP_PATTERN 10 +#define WOW_AP_VDEV_DISALLOW 11 +#define WOW_STA_VDEV_DISALLOW 12 +#define WOW_P2PGO_VDEV_DISALLOW 13 +#define WOW_NS_OFLD_ENABLE 14 +#define WOW_ARP_OFLD_ENABLE 15 +#define WOW_NS_ARP_OFLD_DISABLE 16 +#define WOW_NS_RECEIVED 17 +#define WOW_NS_REPLIED 18 +#define WOW_ARP_RECEIVED 19 +#define WOW_ARP_REPLIED 20 +#define WOW_BEACON_OFFLOAD_TX 21 +#define WOW_BEACON_OFFLOAD_CFG 22 +#define WOW_IBSS_VDEV_ALLOW 23 +#define WOW_DBGID_DEFINITION_END 24 + +/* SWBMISS module DBGIDs */ +#define SWBMISS_DBGID_DEFINITION_START 0 +#define SWBMISS_ENABLED 1 +#define SWBMISS_DISABLED 2 +#define SWBMISS_DBGID_DEFINITION_END 3 + +/* WLAN module DBGIDS */ +#define ROAM_DBGID_DEFINITION_START 0 +#define ROAM_MODULE_INIT 1 +#define ROAM_DEV_START 2 +#define ROAM_CONFIG_RSSI_THRESH 3 +#define ROAM_CONFIG_SCAN_PERIOD 4 +#define ROAM_CONFIG_AP_PROFILE 5 +#define ROAM_CONFIG_CHAN_LIST 6 +#define ROAM_CONFIG_SCAN_PARAMS 7 +#define ROAM_CONFIG_RSSI_CHANGE 8 +#define ROAM_SCAN_TIMER_START 9 +#define ROAM_SCAN_TIMER_EXPIRE 10 +#define ROAM_SCAN_TIMER_STOP 11 +#define ROAM_SCAN_STARTED 12 +#define ROAM_SCAN_COMPLETE 13 +#define ROAM_SCAN_CANCELLED 14 +#define ROAM_CANDIDATE_FOUND 15 +#define ROAM_RSSI_ACTIVE_SCAN 16 +#define ROAM_RSSI_ACTIVE_ROAM 17 +#define ROAM_RSSI_GOOD 18 +#define ROAM_BMISS_FIRST_RECV 19 +#define ROAM_DEV_STOP 20 +#define ROAM_FW_OFFLOAD_ENABLE 21 +#define ROAM_CANDIDATE_SSID_MATCH 22 +#define ROAM_CANDIDATE_SECURITY_MATCH 23 +#define ROAM_LOW_RSSI_INTERRUPT 24 +#define ROAM_HIGH_RSSI_INTERRUPT 25 +#define ROAM_SCAN_REQUESTED 26 +#define ROAM_BETTER_CANDIDATE_FOUND 27 +#define ROAM_BETTER_AP_EVENT 28 +#define ROAM_CANCEL_LOW_PRIO_SCAN 29 +#define ROAM_FINAL_BMISS_RECVD 30 +#define ROAM_CONFIG_SCAN_MODE 31 +#define ROAM_BMISS_FINAL_SCAN_ENABLE 32 +#define ROAM_SUITABLE_AP_EVENT 33 +#define ROAM_RSN_IE_PARSE_ERROR 34 +#define ROAM_WPA_IE_PARSE_ERROR 35 +#define ROAM_SCAN_CMD_FROM_HOST 36 +#define ROAM_HO_SORT_CANDIDATE 37 +#define ROAM_HO_SAVE_CANDIDATE 38 +#define ROAM_HO_GET_CANDIDATE 39 +#define ROAM_HO_OFFLOAD_SET_PARAM 40 +#define ROAM_HO_SM 41 +#define ROAM_HO_HTT_SAVED 42 +#define ROAM_HO_SYNC_START 43 +#define ROAM_HO_START 44 +#define ROAM_HO_SYNC_COMPLETE 45 +#define ROAM_HO_STOP 46 +#define ROAM_HO_HTT_FORWARD 47 +#define ROAM_CONFIG_SCAN_PARAMS_1 48 +#define ROAM_SCAN_COMPLETE_1 49 +#define ROAM_SWBMISS_BCN_RECV_VAL 50 +#define ROAM_SWBMISS_BCN_RECV_THRE2 51 +#define ROAM_SCAN_REQUESTED_1 52 +#define ROAM_HO_SORT_CANDIDATE_CUR 53 +#define ROAM_HO_SAVE_CANDIDATE_DUP 54 +#define ROAM_HO_SM_EVENT 55 +#define ROAM_HO_ENTER_CH 56 +#define ROAM_HO_MGMT_RX 57 +#define ROAM_HO_CANDIDATE_INFO 58 +#define ROAM_HO_OFFLD_DATA_STORE 59 +#define ROAM_HO_HTT_DATA_STORE 60 +#define ROAM_HO_UPDATE_STATUS 61 +#define ROAM_HO_OCS_CH_CB 62 +#define ROAM_RSSI_INTERRUPT_STATE 63 +#define ROAM_INVOKE_PARAM_CHECK 64 +#define ROAM_INVOKE_PARAM_CHAN 65 +#define ROAM_INVOKE_PARAM_BSSID 66 +#define ROAM_INVOKE_STATE_CHECK 67 +#define ROAM_INVOKE_START_SUCCESS 68 +#define ROAM_INVOKE_START_FAILURE 69 +#define ROAM_INVOKE_BSSID_CHECK 70 +#define ROAM_CANDIDATE_INFO 71 +#define ROAM_CANDIDATE_FILTER_MATCH 72 +#define ROAM_CANDIDATE_RSSI_ADJUST 73 +#define ROAM_DBGID_DEFINITION_END 74 + +/* DATA_TXRX module DBGIDs*/ +#define DATA_TXRX_DBGID_DEFINITION_START 0 +#define DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO 1 +#define DATA_TXRX_DBGID_REPLAY_CHECK 2 +#define DATA_TXRX_DBGID_DUP_CHECK 3 +#define DATA_TXRX_DBGID_DEFINITION_END 4 + +/* TDLS module DBGIDs*/ +#define TDLS_DBGID_DEFINITION_START 0 +#define TDLS_DBGID_VDEV_CREATE 1 +#define TDLS_DBGID_VDEV_DELETE 2 +#define TDLS_DBGID_ENABLED_PASSIVE 3 +#define TDLS_DBGID_ENABLED_ACTIVE 4 +#define TDLS_DBGID_DISABLED 5 +#define TDLS_DBGID_CONNTRACK_TIMER 6 +#define TDLS_DBGID_WAL_SET 7 +#define TDLS_DBGID_WAL_GET 8 +#define TDLS_DBGID_WAL_PEER_UPDATE_SET 9 +#define TDLS_DBGID_WAL_PEER_UPDATE_EVT 10 +#define TDLS_DBGID_WAL_VDEV_CREATE 11 +#define TDLS_DBGID_WAL_VDEV_DELETE 12 +#define TDLS_DBGID_WLAN_EVENT 13 +#define TDLS_DBGID_WLAN_PEER_UPDATE_SET 14 +#define TDLS_DBGID_PEER_EVT_DRP_THRESH 15 +#define TDLS_DBGID_PEER_EVT_DRP_RATE 16 +#define TDLS_DBGID_PEER_EVT_DRP_RSSI 17 +#define TDLS_DBGID_PEER_EVT_DISCOVER 18 +#define TDLS_DBGID_PEER_EVT_DELETE 19 +#define TDLS_DBGID_PEER_CAP_UPDATE 20 +#define TDLS_DBGID_UAPSD_SEND_PTI_FRAME 21 +#define TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER 22 +#define TDLS_DBGID_UAPSD_START_PTR_TIMER 23 +#define TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER 24 +#define TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT 25 +#define TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER 26 +#define TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER 27 +#define TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS 28 +#define TDLS_DBGID_UAPSD_GENERIC 29 + + +/* TXBF Module IDs */ +#define TXBFEE_DBGID_START 0 +#define TXBFEE_DBGID_NDPA_RECEIVED 1 +#define TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE 2 +#define TXBFER_DBGID_SEND_NDPA 3 +#define TXBFER_DBGID_GET_NDPA_BUF_FAIL 4 +#define TXBFER_DBGID_SEND_NDPA_FAIL 5 +#define TXBFER_DBGID_GET_NDP_BUF_FAIL 6 +#define TXBFER_DBGID_SEND_NDP_FAIL 7 +#define TXBFER_DBGID_GET_BRPOLL_BUF_FAIL 8 +#define TXBFER_DBGID_SEND_BRPOLL_FAIL 9 +#define TXBFER_DBGID_HOST_CONFIG_CMDID 10 +#define TXBFEE_DBGID_HOST_CONFIG_CMDID 11 +#define TXBFEE_DBGID_ENABLE_UPLOAD_H 12 +#define TXBFEE_DBGID_UPLOADH_CV_TAG 13 +#define TXBFEE_DBGID_UPLOADH_H_TAG 14 +#define TXBFEE_DBGID_CAPTUREH_RECEIVED 15 +#define TXBFEE_DBGID_PACKET_IS_STEERED 16 +#define TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL 17 +#define TXBFEE_DBGID_SW_WAR_AID_ZERO 18 +#define TXBFEE_DBGID_BRPOLL_RECEIVED 19 +#define TXBFEE_DBGID_GID_RECEIVED 20 +#define TXBFEE_DBGID_END 21 + +/* SMPS module DBGIDs */ +#define STA_SMPS_DBGID_DEFINITION_START 0 +#define STA_SMPS_DBGID_CREATE_PDEV_INSTANCE 1 +#define STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE 2 +#define STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE 3 +#define STA_SMPS_DBGID_CREATE_STA_INSTANCE 4 +#define STA_SMPS_DBGID_DELETE_STA_INSTANCE 5 +#define STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START 6 +#define STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP 7 +#define STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME 8 +#define STA_SMPS_DBGID_HOST_FORCED_MODE 9 +#define STA_SMPS_DBGID_FW_FORCED_MODE 10 +#define STA_SMPS_DBGID_RSSI_THRESHOLD_CROSSED 11 +#define STA_SMPS_DBGID_SMPS_ACTION_FRAME_COMPLETION 12 +#define STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE 13 +#define STA_SMPS_DBGID_DTIM_CHMASK_UPDATE 14 +#define STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE 15 +#define STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE 16 +#define STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP 17 +#define STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE 18 + +#define STA_SMPS_DBGID_DEFINITION_END 18 + +/* RTT module DBGIDs*/ +#define RTT_CALL_FLOW 0 +#define RTT_REQ_SUB_TYPE 1 +#define RTT_MEAS_REQ_HEAD 2 +#define RTT_MEAS_REQ_BODY 3 +#define RTT_INIT_GLOBAL_STATE 6 +#define RTT_REPORT 8 +#define RTT_ERROR_REPORT 10 +#define RTT_TIMER_STOP 11 +#define RTT_SEND_TM_FRAME 12 +#define RTT_V3_RESP_CNT 13 +#define RTT_V3_RESP_FINISH 14 +#define RTT_CHANNEL_SWITCH_REQ 15 +#define RTT_CHANNEL_SWITCH_GRANT 16 +#define RTT_CHANNEL_SWITCH_COMPLETE 17 +#define RTT_CHANNEL_SWITCH_PREEMPT 18 +#define RTT_CHANNEL_SWITCH_STOP 19 +#define RTT_TIMER_START 20 +/* WLAN HB module DBGIDs */ +#define WLAN_HB_DBGID_DEFINITION_START 0 +#define WLAN_HB_DBGID_INIT 1 +#define WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL 2 +#define WLAN_HB_DBGID_TCP_SEND_FAIL 3 +#define WLAN_HB_DBGID_BSS_PEER_NULL 4 +#define WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL 5 +#define WLAN_HB_DBGID_UDP_SEND_FAIL 6 +#define WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM 7 +#define WLAN_HB_DBGID_WMI_CMD_INVALID_OP 8 +#define WLAN_HB_DBGID_WOW_NOT_ENTERED 9 +#define WLAN_HB_DBGID_ALLOC_SESS_FAIL 10 +#define WLAN_HB_DBGID_CTX_NULL 11 +#define WLAN_HB_DBGID_CHKSUM_ERR 12 +#define WLAN_HB_DBGID_UDP_TX 13 +#define WLAN_HB_DBGID_TCP_TX 14 +#define WLAN_HB_DBGID_DEFINITION_END 15 + +/* Thermal Manager DBGIDs*/ +#define THERMAL_MGR_DBGID_DEFINITION_START 0 +#define THERMAL_MGR_NEW_THRESH 1 +#define THERMAL_MGR_THRESH_CROSSED 2 +#define THERMAL_MGR_DBGID_DEFINITION_END 3 + +/* WLAN PHYERR DFS(parse/filter) DBGIDs */ +#define WLAN_PHYERR_DFS_DBGID_DEFINITION_START 0 +#define WLAN_PHYERR_DFS_PHYERR_INFO_CHAN_BUFLEN 1 +#define WLAN_PHYERR_DFS_PHYERR_INFO_PPDU 2 +#define WLAN_PHYERR_DFS_DBDID_RADAR_SUMMARY 3 +#define WLAN_PHYERR_DFS_DBDID_SEARCH_FFT 4 +#define WLAN_PHTERR_DFS_DBDID_FILTER_STATUS 5 +#define WLAN_PHYERR_DFS_DBGID_DEFINITION_END 6 + +/* RMC DBGIDs */ +#define RMC_DBGID_DEFINITION_START 0 +#define RMC_SM_INIT_ERR 1 +#define RMC_VDEV_ALLOC_ERR 2 +#define RMC_CREATE_INSTANCE 3 +#define RMC_DELETE_INSTANCE 4 +#define RMC_NEW_PRI_LEADER 5 +#define RMC_NEW_SEC_LEADER 6 +#define RMC_NO_LDR_CHANGE 7 +#define RMC_LDR_INFORM_SENT 8 +#define RMC_PEER_ADD 9 +#define RMC_PEER_DELETE 10 +#define RMC_PEER_UNKNOWN 11 +#define RMC_PRI_LDR_RSSI_UPDATE 12 +#define RMC_SEC_LDR_RSSI_UPDATE 13 +#define RMC_SET_MODE 14 +#define RMC_SET_ACTION_PERIOD 15 +#define RMC_DBGID_DEFINITION_END 16 + +/* UNIT_TEST module DBGIDs */ +#define UNIT_TEST_GEN 0 + +/* MLME module DBGIDs */ +#define MLME_DEBUG_CMN 0 +#define MLME_DEBUG_IF 1 +#define MLME_DEBUG_AUTH 2 +#define MLME_DEBUG_REASSOC 3 +#define MLME_DEBUG_DEAUTH 4 +#define MLME_DEBUG_DISASSOC 5 +#define MLME_DEBUG_ROAM 6 +#define MLME_DEBUG_RETRY 7 +#define MLME_DEBUG_TIMER 8 +#define MLME_DEBUG_FRAMEPARSE 9 + +/* SUPPL module DBGIDs */ +#define SUPPL_DBGID_INIT 0 +#define SUPPL_DBGID_RECV_EAPOL 1 +#define SUPPL_DBGID_RECV_EAPOL_TIMEOUT 2 +#define SUPPL_DBGID_SEND_EAPOL 3 +#define SUPPL_DBGID_MIC_MISMATCH 4 +#define SUPPL_DBGID_FINISH 5 + +/* Stats Module DBGIDs */ +#define WLAN_STATS_DBGID_DEFINITION_START 0 +#define WLAN_STATS_DBGID_EST_LINKSPEED_VDEV_EN_DIS 1 +#define WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_START 2 +#define WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_END 3 +#define WLAN_STATS_DBGID_EST_LINKSPEED_CALC 4 +#define WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN 5 +#define WLAN_STATS_DBGID_DEFINITION_END 6 +/* NAN DBGIDs */ +#define NAN_DBGID_START 0 + +/* Debug IDs for debug logs. 3 args max, not fixed. */ +#define NAN_DBGID_DBG_LOG_FIRST 1 +#define NAN_DBGID_FUNC_BEGIN NAN_DBGID_DBG_LOG_FIRST +#define NAN_DBGID_FUNC_END 2 +#define NAN_DBGID_MAIN_DEBUG 3 +#define NAN_DBGID_MAC_DEBUG 4 +#define NAN_DBGID_BLOOM_FILTER_DEBUG 5 +#define NAN_DBGID_MAC_ADDR 6 +#define NAN_DBGID_PARAM_UPDATED 7 +#define NAN_DBGID_NULL_PTR 8 +#define NAN_DBGID_INVALID_FUNC_ARG 9 +#define NAN_DBGID_INVALID_MSG_PARAM 10 +#define NAN_DBGID_MISSING_MSG_PARAM 11 +#define NAN_DBGID_DEPRECATED_MSG_PARAM 12 +#define NAN_DBGID_UNSUPPORTED_MSG_PARAM 13 +#define NAN_DBGID_INVALID_PKT_DATA 14 +#define NAN_DBGID_LOG_PKT_DATA 15 +#define NAN_DBGID_INVALID_VALUE 16 +#define NAN_DBGID_INVALID_OPERATION 17 +#define NAN_DBGID_INVALID_STATE 18 +#define NAN_DBGID_FUNCTION_ENABLED 19 +#define NAN_DBGID_FUNCTION_DISABLED 20 +#define NAN_DBGID_INVALID_FUNCTION_STATE 21 +#define NAN_DBGID_READ_ERROR 22 +#define NAN_DBGID_WRITE_ERROR 23 +#define NAN_DBGID_RECEIVE_ERROR 24 +#define NAN_DBGID_TRANSMIT_ERROR 25 +#define NAN_DBGID_PARSE_ERROR 26 +#define NAN_DBGID_RES_ALLOC_ERROR 27 +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_DBG_LOG_LAST 28 + +/* Debug IDs for event logs. */ + +#define NAN_DBGID_EVT_BASE NAN_DBGID_DBG_LOG_LAST +/* args: */ +#define NAN_DBGID_NAN_ENABLED (NAN_DBGID_EVT_BASE + 0) +/* args: */ +#define NAN_DBGID_NAN_DISABLED (NAN_DBGID_EVT_BASE + 1) +/* args: */ +#define NAN_DBGID_CONFIG_RESTORED (NAN_DBGID_EVT_BASE + 2) +/* args: framesQueued */ +#define NAN_DBGID_SDF_QUEUED (NAN_DBGID_EVT_BASE + 3) +/* args: old, new */ +#define NAN_DBGID_TW_CHANGED (NAN_DBGID_EVT_BASE + 4) +/* args: */ +#define NAN_DBGID_DW_START (NAN_DBGID_EVT_BASE + 5) +/* args: busyDiff */ +#define NAN_DBGID_DW_END (NAN_DBGID_EVT_BASE + 6) +/* args: oldClusterId, newClusterId */ +#define NAN_DBGID_CLUSTER_ID_CHANGED (NAN_DBGID_EVT_BASE + 7) +/* args: cmd, buffer, length */ +#define NAN_DBGID_WMI_CMD_RECEIVED (NAN_DBGID_EVT_BASE + 8) +/* args: pEventPkt, pEventBuf, eventSize, dataSize */ +#define NAN_DBGID_WMI_EVT_SENT (NAN_DBGID_EVT_BASE + 9) +/* args: type length, readLen */ +#define NAN_DBGID_TLV_READ (NAN_DBGID_EVT_BASE + 10) +/* args: type length, writeLen */ +#define NAN_DBGID_TLV_WRITE (NAN_DBGID_EVT_BASE + 11) +/* args: handle */ +#define NAN_DBGID_PUBSUB_UPDATED (NAN_DBGID_EVT_BASE + 12) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_DEFERED (NAN_DBGID_EVT_BASE + 13) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_PENDING (NAN_DBGID_EVT_BASE + 14) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVED (NAN_DBGID_EVT_BASE + 15) +/* args: handle */ +#define NAN_DBGID_PUBSUB_PROCESSED (NAN_DBGID_EVT_BASE + 16) +/* args: handle, sid1, sid2, svcCtrl, length */ +#define NAN_DBGID_PUBSUB_MATCHED (NAN_DBGID_EVT_BASE + 17) +/* args: handle, flags */ +#define NAN_DBGID_PUBSUB_PREPARED (NAN_DBGID_EVT_BASE + 18) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_TRANSMIT (NAN_DBGID_EVT_BASE + 19) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_RECEIVED (NAN_DBGID_EVT_BASE + 20) +/* args: subscribeHandle, matchHandle, oldTimeout, newTimeout */ +#define NAN_DBGID_SUBSCRIBE_UNMATCH_TIMEOUT_UPDATE (NAN_DBGID_EVT_BASE + 21) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_NEW (NAN_DBGID_EVT_BASE + 22) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_REPEAT (NAN_DBGID_EVT_BASE + 23) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_EXPIRED (NAN_DBGID_EVT_BASE + 24) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp */ +#define NAN_DBGID_SUBSCRIBE_MATCH_LOG (NAN_DBGID_EVT_BASE + 25) +/* args: sid1, sid2 */ +#define NAN_DBGID_SERVICE_ID_CREATED (NAN_DBGID_EVT_BASE + 26) +/* args: size */ +#define NAN_DBGID_SD_ATTR_BUILT (NAN_DBGID_EVT_BASE + 27) +/* args: offset */ +#define NAN_DBGID_SERVICE_RSP_OFFSET (NAN_DBGID_EVT_BASE + 28) +/* args: offset */ +#define NAN_DBGID_SERVICE_INFO_OFFSET (NAN_DBGID_EVT_BASE + 29) +/* args: chan, interval, start_time */ +#define NAN_DBGID_CHREQ_CREATE (NAN_DBGID_EVT_BASE + 30) +/* args: start_time, status */ +#define NAN_DBGID_CHREQ_UPDATE (NAN_DBGID_EVT_BASE + 31) +/* args: chan, interval, status */ +#define NAN_DBGID_CHREQ_REMOVE (NAN_DBGID_EVT_BASE + 32) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_GRANT (NAN_DBGID_EVT_BASE + 33) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_END (NAN_DBGID_EVT_BASE + 34) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_ERROR (NAN_DBGID_EVT_BASE + 35) +/* args: type, length, timestamp, rssi */ +#define NAN_DBGID_RX_CALLBACK (NAN_DBGID_EVT_BASE + 36) +/* args: type, handle, bufp, status, timestamp */ +#define NAN_DBGID_TX_COMPLETE (NAN_DBGID_EVT_BASE + 37) +/* args: tsf, tsf */ +#define NAN_DBGID_TSF_TIMEOUT (NAN_DBGID_EVT_BASE + 38) +/* args: clusterId, clusterStart */ +#define NAN_DBGID_SYNC_START (NAN_DBGID_EVT_BASE + 39) +/* args: clusterId */ +#define NAN_DBGID_SYNC_STOP (NAN_DBGID_EVT_BASE + 40) +/* args: enable, scanType, rval */ +#define NAN_DBGID_NAN_SCAN (NAN_DBGID_EVT_BASE + 41) +/* args: scanType */ +#define NAN_DBGID_NAN_SCAN_COMPLETE (NAN_DBGID_EVT_BASE + 42) +/* args: masterPref */ +#define NAN_DBGID_MPREF_CHANGE (NAN_DBGID_EVT_BASE + 43) +/* args: masterPref, randFactor */ +#define NAN_DBGID_WARMUP_EXPIRE (NAN_DBGID_EVT_BASE + 44) +/* args: randFactor */ +#define NAN_DBGID_RANDOM_FACTOR_EXPIRE (NAN_DBGID_EVT_BASE + 45) +/* args: tsf, tsf */ +#define NAN_DBGID_DW_SKIP (NAN_DBGID_EVT_BASE + 46) +/* args: type, tsfDiff */ +#define NAN_DBGID_DB_SKIP (NAN_DBGID_EVT_BASE + 47) +/* args: TBD */ +#define NAN_DBGID_BEACON_RX (NAN_DBGID_EVT_BASE + 48) +/* args: TBD */ +#define NAN_DBGID_BEACON_TX (NAN_DBGID_EVT_BASE + 49) +/* args: clusterId */ +#define NAN_DBGID_CLUSTER_MERGE (NAN_DBGID_EVT_BASE + 50) +/* args: cmd, status, value */ +#define NAN_DBGID_TEST_CMD_EXEC (NAN_DBGID_EVT_BASE + 51) +/* args: tsfHi, tsfLo, age */ +#define NAN_DBGID_APPLY_BEACON_TSF (NAN_DBGID_EVT_BASE + 52) +/* args: behindFlag, diff */ +#define NAN_DBGID_TSF_UPDATE (NAN_DBGID_EVT_BASE + 53) +/* args: argc==4 (rawTsfHi, rawTsfLo, nanTsfHi, nanTsfLo), argc==2(offsetHi, offsetLo) */ +#define NAN_DBGID_SET_TSF (NAN_DBGID_EVT_BASE + 54) +/* args: rankHi, rankLo, mp, rf */ +#define NAN_DBGID_NEW_MASTERRANK (NAN_DBGID_EVT_BASE + 55) +/* args: amRankHi, amRankLo, mp, rf */ +#define NAN_DBGID_NEW_ANCHORMASTER (NAN_DBGID_EVT_BASE + 56) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_UPDATE (NAN_DBGID_EVT_BASE + 57) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_EXPIRED (NAN_DBGID_EVT_BASE + 58) +/* args: reason, transitionsToAM */ +#define NAN_DBGID_BECOMING_ANCHORMASTER (NAN_DBGID_EVT_BASE + 59) +/* args: oldRole, newRole */ +#define NAN_DBGID_ROLE_CHANGE (NAN_DBGID_EVT_BASE + 60) +/* args: TBD */ +#define NAN_DBGID_SYNC_BEACON_DW_STATS (NAN_DBGID_EVT_BASE + 61) +/* args: attrId */ +#define NAN_DBGID_RX_UNSUPPORTED_SDF_ATTR_ID (NAN_DBGID_EVT_BASE + 62) +/* args: handle, sid1, sid2, svcCtrl, length */ +#define NAN_DBGID_PUBSUB_MATCHED_SKIPPED_SSI (NAN_DBGID_EVT_BASE + 63) +/* args: offset */ +#define NAN_DBGID_MATCH_FILTER_OFFSET (NAN_DBGID_EVT_BASE + 64) +/* args: twSize, n, twIndex */ +#define NAN_DBGID_TW_PARAMS (NAN_DBGID_EVT_BASE + 65) +/* args: */ +#define NAN_DBGID_BEACON_SENDER (NAN_DBGID_EVT_BASE + 66) +/* args: currTsf, nextDwTsf */ +#define NAN_DBGID_TSF_DUMP (NAN_DBGID_EVT_BASE + 67) +/* args: chan, startSlot, numSlots, repeat */ +#define NAN_DBGID_FAW_CONFIG (NAN_DBGID_EVT_BASE + 68) +/* args: */ +#define NAN_DBGID_FAW_START (NAN_DBGID_EVT_BASE + 69) +/* args: */ +#define NAN_DBGID_FAW_END (NAN_DBGID_EVT_BASE + 70) +/* args: offset, oldval, newval */ +#define NAN_DBGID_CONFIG_PARAM_CHANGED (NAN_DBGID_EVT_BASE + 71) +/* args: */ +#define NAN_DBGID_CONN_CAP_ATTR_CLEARED (NAN_DBGID_EVT_BASE + 72) +/* args: connType */ +#define NAN_DBGID_POST_DISC_ATTR_CLEARED (NAN_DBGID_EVT_BASE + 73) +/* args: */ +#define NAN_DBGID_VENDOR_SPECIFIC_ATTR_CLEARED (NAN_DBGID_EVT_BASE + 74) +/* args: offset */ +#define NAN_DBGID_WLAN_INFRA_MAP_CTRL_OFFSET (NAN_DBGID_EVT_BASE + 75) +/* args: offset */ +#define NAN_DBGID_WLAN_INFRA_AI_BITMAP_OFFSET (NAN_DBGID_EVT_BASE + 76) +/* args: offset */ +#define NAN_DBGID_WLAN_INFRA_DEVICE_ROLE_OFFSET (NAN_DBGID_EVT_BASE + 77) +/* args: offset */ +#define NAN_DBGID_MESH_ID_OFFSET (NAN_DBGID_EVT_BASE + 78) +/* args: */ +#define NAN_DBGID_SPARE_79 (NAN_DBGID_EVT_BASE + 79) +/* args: */ +#define NAN_DBGID_SPARE_80 (NAN_DBGID_EVT_BASE + 80) +/* args: */ +#define NAN_DBGID_SPARE_81 (NAN_DBGID_EVT_BASE + 81) +/* args: */ +#define NAN_DBGID_SPARE_82 (NAN_DBGID_EVT_BASE + 82) +/* args: */ +#define NAN_DBGID_SPARE_83 (NAN_DBGID_EVT_BASE + 83) +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_EVT_LOG_LAST (NAN_DBGID_EVT_BASE + 84) + +/* Debug IDs for message logs. */ +#define NAN_DBGID_API_MSG_BASE NAN_DBGID_EVT_LOG_LAST +#define NAN_DBGID_API_MSG_HEADER (NAN_DBGID_API_MSG_BASE + 0) +#define NAN_DBGID_API_MSG_DATA (NAN_DBGID_API_MSG_BASE + 1) +#define NAN_DBGID_API_MSG_LAST (NAN_DBGID_API_MSG_BASE + 2) + +/* Debug IDs for packet logs. */ +#define NAN_DBGID_OTA_PKT_BASE NAN_DBGID_API_MSG_LAST +#define NAN_DBGID_OTA_PKT_HEADER (NAN_DBGID_OTA_PKT_BASE + 0) +#define NAN_DBGID_OTA_PKT_DATA (NAN_DBGID_OTA_PKT_BASE + 1) +#define NAN_DBGID_OTA_PKT_LAST (NAN_DBGID_OTA_PKT_BASE + 2) + +#define NAN_DBGID_END NAN_DBGID_OTA_PKT_LAST + + +/* IBSS PS module DBGIDs*/ +#define IBSS_PS_DBGID_DEFINITION_START 0 +#define IBSS_PS_DBGID_PEER_CREATE 1 +#define IBSS_PS_DBGID_PEER_DELETE 2 +#define IBSS_PS_DBGID_VDEV_CREATE 3 +#define IBSS_PS_DBGID_VDEV_DELETE 4 +#define IBSS_PS_DBGID_VDEV_EVENT 5 +#define IBSS_PS_DBGID_PEER_EVENT 6 +#define IBSS_PS_DBGID_DELIVER_CAB 7 +#define IBSS_PS_DBGID_DELIVER_UC_DATA 8 +#define IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR 9 +#define IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART 10 +#define IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART 11 +#define IBSS_PS_DBGID_NULL_TX_COMPLETION 12 +#define IBSS_PS_DBGID_ATIM_TIMER_START 13 +#define IBSS_PS_DBGID_UC_ATIM_SEND 14 +#define IBSS_PS_DBGID_BC_ATIM_SEND 15 +#define IBSS_PS_DBGID_UC_TIMEOUT 16 +#define IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED 17 +#define IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED 18 +#define IBSS_PS_DBGID_SET_PARAM 19 +#define IBSS_PS_DBGID_HOST_TX_PAUSE 20 +#define IBSS_PS_DBGID_HOST_TX_UNPAUSE 21 +#define IBSS_PS_DBGID_PS_DESC_BIN_HWM 22 +#define IBSS_PS_DBGID_PS_DESC_BIN_LWM 23 +#define IBSS_PS_DBGID_PS_KICKOUT_PEER 24 +#define IBSS_PS_DBGID_SET_PEER_PARAM 25 +#define IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH 26 +#define IBSS_PS_DBGID_RX_CHAINMASK_CHANGE 27 + +/* HIF UART Interface DBGIDs */ +#define HIF_UART_DBGID_START 0 +#define HIF_UART_DBGID_POWER_STATE 1 +#define HIF_UART_DBGID_TXRX_FLOW 2 +#define HIF_UART_DBGID_TXRX_CTRL_CHAR 3 +#define HIF_UART_DBGID_TXRX_BUF_DUMP 4 + +/* EXTSCAN DBGIDs */ +#define EXTSCAN_START 0 +#define EXTSCAN_STOP 1 +#define EXTSCAN_CLEAR_ENTRY_CONTENT 2 +#define EXTSCAN_GET_FREE_ENTRY_SUCCESS 3 +#define EXTSCAN_GET_FREE_ENTRY_INCONSISTENT 4 +#define EXTSCAN_GET_FREE_ENTRY_NO_MORE_ENTRIES 5 +#define EXTSCAN_CREATE_ENTRY_SUCCESS 6 +#define EXTSCAN_CREATE_ENTRY_ERROR 7 +#define EXTSCAN_SEARCH_SCAN_ENTRY_QUEUE 8 +#define EXTSCAN_SEARCH_SCAN_ENTRY_KEY_FOUND 9 +#define EXTSCAN_SEARCH_SCAN_ENTRY_KEY_NOT_FOUND 10 +#define EXTSCAN_ADD_ENTRY 11 +#define EXTSCAN_BUCKET_SEND_OPERATION_EVENT 12 +#define EXTSCAN_BUCKET_SEND_OPERATION_EVENT_FAILED 13 +#define EXTSCAN_BUCKET_START_SCAN_CYCLE 14 +#define EXTSCAN_BUCKET_PERIODIC_TIMER 15 +#define EXTSCAN_SEND_START_STOP_EVENT 16 +#define EXTSCAN_NOTIFY_WLAN_CHANGE 17 +#define EXTSCAN_NOTIFY_WLAN_HOTLIST_MATCH 18 +#define EXTSCAN_MAIN_RECEIVED_FRAME 19 +#define EXTSCAN_MAIN_NO_SSID_IE 20 +#define EXTSCAN_MAIN_MALFORMED_FRAME 21 +#define EXTSCAN_FIND_BSSID_BY_REFERENCE 22 +#define EXTSCAN_FIND_BSSID_BY_REFERENCE_ERROR 23 +#define EXTSCAN_NOTIFY_TABLE_USAGE 24 +#define EXTSCAN_FOUND_RSSI_ENTRY 25 +#define EXTSCAN_BSSID_FOUND_RSSI_SAMPLE 26 +#define EXTSCAN_BSSID_ADDED_RSSI_SAMPLE 27 +#define EXTSCAN_BSSID_REPLACED_RSSI_SAMPLE 28 +#define EXTSCAN_BSSID_TRANSFER_CURRENT_SAMPLES 29 +#define EXTSCAN_BUCKET_PROCESS_SCAN_EVENT 30 +#define EXTSCAN_BUCKET_CANNOT_FIND_BUCKET 31 +#define EXTSCAN_START_SCAN_REQUEST_FAILED 32 +#define EXTSCAN_BUCKET_STOP_CURRENT_SCANS 33 +#define EXTSCAN_BUCKET_SCAN_STOP_REQUEST 34 +#define EXTSCAN_BUCKET_PERIODIC_TIMER_ERROR 35 +#define EXTSCAN_BUCKET_START_OPERATION 36 +#define EXTSCAN_START_INTERNAL_ERROR 37 +#define EXTSCAN_NOTIFY_HOTLIST_MATCH 38 +#define EXTSCAN_CONFIG_HOTLIST_TABLE 39 +#define EXTSCAN_CONFIG_WLAN_CHANGE_TABLE 40 + +/* NLO DBGIDs */ +#define NLO_DBGID_SSID_TO_BE_SCANNED_LIST 0 +#define NLO_DBGID_SSID_TO_BE_SKIPPED_LIST 1 + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_ID_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/debug_linux.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/debug_linux.h new file mode 100644 index 0000000000000..3636ad350411c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/debug_linux.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _DEBUG_LINUX_H_ +#define _DEBUG_LINUX_H_ + + /* macro to remove parens */ +#define ATH_PRINTX_ARG(arg...) arg + +#ifdef DEBUG + /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros + * which may be compiler dependent. */ +#define AR_DEBUG_PRINTF(mask, args) do { \ + if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \ + A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \ + } \ +} while (0) +#else + /* on non-debug builds, keep in error and warning messages in the driver, all other + * message tracing will get compiled out */ +#define AR_DEBUG_PRINTF(mask, args) \ + if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); } + +#endif + + /* compile specific macro to get the function name string */ +#define _A_FUNCNAME_ __func__ + + +#endif /* _DEBUG_LINUX_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dl_list.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dl_list.h new file mode 100644 index 0000000000000..241c81a91e4a7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/dl_list.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//============================================================================== +// Double-link list definitions (adapted from Atheros SDIO stack) +// +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __DL_LIST_H___ +#define __DL_LIST_H___ + +#define A_CONTAINING_STRUCT(address, struct_type, field_name)\ + ((struct_type *)((char *)(address) - (char *)(&((struct_type *)0)->field_name))) + +/* list functions */ +/* pointers for the list */ +typedef struct _DL_LIST { + struct _DL_LIST *pPrev; + struct _DL_LIST *pNext; +}DL_LIST, *PDL_LIST; +/* + * DL_LIST_INIT , initialize doubly linked list +*/ +#define DL_LIST_INIT(pList)\ + {(pList)->pPrev = pList; (pList)->pNext = pList;} + +/* faster macro to init list and add a single item */ +#define DL_LIST_INIT_AND_ADD(pList,pItem) \ +{ (pList)->pPrev = (pItem); \ + (pList)->pNext = (pItem); \ + (pItem)->pNext = (pList); \ + (pItem)->pPrev = (pList); \ +} + +#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList))) +#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext +#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev +/* + * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member + * NOT: do not use this function if the items in the list are deleted inside the + * iteration loop +*/ +#define ITERATE_OVER_LIST(pStart, pTemp) \ + for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext) + +static __inline bool DL_ListIsEntryInList(const DL_LIST * pList, const DL_LIST * pEntry) { + const DL_LIST * pTmp; + + if (pList == pEntry) return true; + + ITERATE_OVER_LIST(pList, pTmp) { + if (pTmp == pEntry) { + return true; + } + } + + return false; +} + +/* safe iterate macro that allows the item to be removed from the list + * the iteration continues to the next item in the list + */ +#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \ +{ \ + PDL_LIST pTemp; \ + pTemp = (pStart)->pNext; \ + while (pTemp != (pStart)) { \ + (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \ + pTemp = pTemp->pNext; \ + +#define ITERATE_IS_VALID(pStart) DL_ListIsEntryInList(pStart, pTemp) +#define ITERATE_RESET(pStart) pTemp=(pStart)->pNext + +#define ITERATE_END }} + +/* + * DL_ListInsertTail - insert pAdd to the end of the list +*/ +static __inline PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) { + /* insert at tail */ + pAdd->pPrev = pList->pPrev; + pAdd->pNext = pList; + if (pList->pPrev) { + pList->pPrev->pNext = pAdd; + } + pList->pPrev = pAdd; + return pAdd; +} + +/* + * DL_ListInsertHead - insert pAdd into the head of the list +*/ +static __inline PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) { + /* insert at head */ + pAdd->pPrev = pList; + pAdd->pNext = pList->pNext; + pList->pNext->pPrev = pAdd; + pList->pNext = pAdd; + return pAdd; +} + +#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem)) +/* + * DL_ListRemove - remove pDel from list +*/ +static __inline PDL_LIST DL_ListRemove(PDL_LIST pDel) { + if (pDel->pNext != NULL) { + pDel->pNext->pPrev = pDel->pPrev; + } + if (pDel->pPrev != NULL) { + pDel->pPrev->pNext = pDel->pNext; + } + + /* point back to itself just to be safe, incase remove is called again */ + pDel->pNext = pDel; + pDel->pPrev = pDel; + return pDel; +} + +/* + * DL_ListRemoveItemFromHead - get a list item from the head +*/ +static __inline PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) { + PDL_LIST pItem = NULL; + if (pList->pNext != pList) { + pItem = pList->pNext; + /* remove the first item from head */ + DL_ListRemove(pItem); + } + return pItem; +} + +static __inline PDL_LIST DL_ListRemoveItemFromTail(PDL_LIST pList) { + PDL_LIST pItem = NULL; + if (pList->pPrev != pList) { + pItem = pList->pPrev; + /* remove the item from tail */ + DL_ListRemove(pItem); + } + return pItem; +} + +/* transfer src list items to the tail of the destination list */ +static __inline void DL_ListTransferItemsToTail(PDL_LIST pDest, PDL_LIST pSrc) { + /* only concatenate if src is not empty */ + if (!DL_LIST_IS_EMPTY(pSrc)) { + /* cut out circular list in src and re-attach to end of dest */ + pSrc->pPrev->pNext = pDest; + pSrc->pNext->pPrev = pDest->pPrev; + pDest->pPrev->pNext = pSrc->pNext; + pDest->pPrev = pSrc->pPrev; + /* terminate src list, it is now empty */ + pSrc->pPrev = pSrc; + pSrc->pNext = pSrc; + } +} + +/* transfer src list items to the head of the destination list */ +static __inline void DL_ListTransferItemsToHead(PDL_LIST pDest, PDL_LIST pSrc) { + /* only concatenate if src is not empty */ + if (!DL_LIST_IS_EMPTY(pSrc)) { + /* cut out circular list in src and re-attach to start of dest */ + pSrc->pNext->pPrev = pDest; + pDest->pNext->pPrev = pSrc->pPrev; + pSrc->pPrev->pNext = pDest->pNext; + pDest->pNext = pSrc->pNext; + /* terminate src list, it is now empty */ + pSrc->pPrev = pSrc; + pSrc->pNext = pSrc; + } +} + +#endif /* __DL_LIST_H___ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/efuse_reg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/efuse_reg.h new file mode 100644 index 0000000000000..29fe800f5af82 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/efuse_reg.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _EFUSE_REG_REG_H_ +#define _EFUSE_REG_REG_H_ + +#define EFUSE_WR_ENABLE_REG_ADDRESS 0x00000000 +#define EFUSE_WR_ENABLE_REG_OFFSET 0x00000000 +#define EFUSE_WR_ENABLE_REG_V_MSB 0 +#define EFUSE_WR_ENABLE_REG_V_LSB 0 +#define EFUSE_WR_ENABLE_REG_V_MASK 0x00000001 +#define EFUSE_WR_ENABLE_REG_V_GET(x) (((x) & EFUSE_WR_ENABLE_REG_V_MASK) >> EFUSE_WR_ENABLE_REG_V_LSB) +#define EFUSE_WR_ENABLE_REG_V_SET(x) (((x) << EFUSE_WR_ENABLE_REG_V_LSB) & EFUSE_WR_ENABLE_REG_V_MASK) + +#define EFUSE_INT_ENABLE_REG_ADDRESS 0x00000004 +#define EFUSE_INT_ENABLE_REG_OFFSET 0x00000004 +#define EFUSE_INT_ENABLE_REG_V_MSB 0 +#define EFUSE_INT_ENABLE_REG_V_LSB 0 +#define EFUSE_INT_ENABLE_REG_V_MASK 0x00000001 +#define EFUSE_INT_ENABLE_REG_V_GET(x) (((x) & EFUSE_INT_ENABLE_REG_V_MASK) >> EFUSE_INT_ENABLE_REG_V_LSB) +#define EFUSE_INT_ENABLE_REG_V_SET(x) (((x) << EFUSE_INT_ENABLE_REG_V_LSB) & EFUSE_INT_ENABLE_REG_V_MASK) + +#define EFUSE_INT_STATUS_REG_ADDRESS 0x00000008 +#define EFUSE_INT_STATUS_REG_OFFSET 0x00000008 +#define EFUSE_INT_STATUS_REG_V_MSB 0 +#define EFUSE_INT_STATUS_REG_V_LSB 0 +#define EFUSE_INT_STATUS_REG_V_MASK 0x00000001 +#define EFUSE_INT_STATUS_REG_V_GET(x) (((x) & EFUSE_INT_STATUS_REG_V_MASK) >> EFUSE_INT_STATUS_REG_V_LSB) +#define EFUSE_INT_STATUS_REG_V_SET(x) (((x) << EFUSE_INT_STATUS_REG_V_LSB) & EFUSE_INT_STATUS_REG_V_MASK) + +#define BITMASK_WR_REG_ADDRESS 0x0000000c +#define BITMASK_WR_REG_OFFSET 0x0000000c +#define BITMASK_WR_REG_V_MSB 31 +#define BITMASK_WR_REG_V_LSB 0 +#define BITMASK_WR_REG_V_MASK 0xffffffff +#define BITMASK_WR_REG_V_GET(x) (((x) & BITMASK_WR_REG_V_MASK) >> BITMASK_WR_REG_V_LSB) +#define BITMASK_WR_REG_V_SET(x) (((x) << BITMASK_WR_REG_V_LSB) & BITMASK_WR_REG_V_MASK) + +#define VDDQ_SETTLE_TIME_REG_ADDRESS 0x00000010 +#define VDDQ_SETTLE_TIME_REG_OFFSET 0x00000010 +#define VDDQ_SETTLE_TIME_REG_V_MSB 31 +#define VDDQ_SETTLE_TIME_REG_V_LSB 0 +#define VDDQ_SETTLE_TIME_REG_V_MASK 0xffffffff +#define VDDQ_SETTLE_TIME_REG_V_GET(x) (((x) & VDDQ_SETTLE_TIME_REG_V_MASK) >> VDDQ_SETTLE_TIME_REG_V_LSB) +#define VDDQ_SETTLE_TIME_REG_V_SET(x) (((x) << VDDQ_SETTLE_TIME_REG_V_LSB) & VDDQ_SETTLE_TIME_REG_V_MASK) + +#define VDDQ_HOLD_TIME_REG_ADDRESS 0x00000014 +#define VDDQ_HOLD_TIME_REG_OFFSET 0x00000014 +#define VDDQ_HOLD_TIME_REG_V_MSB 31 +#define VDDQ_HOLD_TIME_REG_V_LSB 0 +#define VDDQ_HOLD_TIME_REG_V_MASK 0xffffffff +#define VDDQ_HOLD_TIME_REG_V_GET(x) (((x) & VDDQ_HOLD_TIME_REG_V_MASK) >> VDDQ_HOLD_TIME_REG_V_LSB) +#define VDDQ_HOLD_TIME_REG_V_SET(x) (((x) << VDDQ_HOLD_TIME_REG_V_LSB) & VDDQ_HOLD_TIME_REG_V_MASK) + +#define RD_STROBE_PW_REG_ADDRESS 0x00000018 +#define RD_STROBE_PW_REG_OFFSET 0x00000018 +#define RD_STROBE_PW_REG_V_MSB 31 +#define RD_STROBE_PW_REG_V_LSB 0 +#define RD_STROBE_PW_REG_V_MASK 0xffffffff +#define RD_STROBE_PW_REG_V_GET(x) (((x) & RD_STROBE_PW_REG_V_MASK) >> RD_STROBE_PW_REG_V_LSB) +#define RD_STROBE_PW_REG_V_SET(x) (((x) << RD_STROBE_PW_REG_V_LSB) & RD_STROBE_PW_REG_V_MASK) + +#define PG_STROBE_PW_REG_ADDRESS 0x0000001c +#define PG_STROBE_PW_REG_OFFSET 0x0000001c +#define PG_STROBE_PW_REG_V_MSB 31 +#define PG_STROBE_PW_REG_V_LSB 0 +#define PG_STROBE_PW_REG_V_MASK 0xffffffff +#define PG_STROBE_PW_REG_V_GET(x) (((x) & PG_STROBE_PW_REG_V_MASK) >> PG_STROBE_PW_REG_V_LSB) +#define PG_STROBE_PW_REG_V_SET(x) (((x) << PG_STROBE_PW_REG_V_LSB) & PG_STROBE_PW_REG_V_MASK) + +#define PGENB_SETUP_HOLD_TIME_REG_ADDRESS 0x00000020 +#define PGENB_SETUP_HOLD_TIME_REG_OFFSET 0x00000020 +#define PGENB_SETUP_HOLD_TIME_REG_V_MSB 31 +#define PGENB_SETUP_HOLD_TIME_REG_V_LSB 0 +#define PGENB_SETUP_HOLD_TIME_REG_V_MASK 0xffffffff +#define PGENB_SETUP_HOLD_TIME_REG_V_GET(x) (((x) & PGENB_SETUP_HOLD_TIME_REG_V_MASK) >> PGENB_SETUP_HOLD_TIME_REG_V_LSB) +#define PGENB_SETUP_HOLD_TIME_REG_V_SET(x) (((x) << PGENB_SETUP_HOLD_TIME_REG_V_LSB) & PGENB_SETUP_HOLD_TIME_REG_V_MASK) + +#define STROBE_PULSE_INTERVAL_REG_ADDRESS 0x00000024 +#define STROBE_PULSE_INTERVAL_REG_OFFSET 0x00000024 +#define STROBE_PULSE_INTERVAL_REG_V_MSB 31 +#define STROBE_PULSE_INTERVAL_REG_V_LSB 0 +#define STROBE_PULSE_INTERVAL_REG_V_MASK 0xffffffff +#define STROBE_PULSE_INTERVAL_REG_V_GET(x) (((x) & STROBE_PULSE_INTERVAL_REG_V_MASK) >> STROBE_PULSE_INTERVAL_REG_V_LSB) +#define STROBE_PULSE_INTERVAL_REG_V_SET(x) (((x) << STROBE_PULSE_INTERVAL_REG_V_LSB) & STROBE_PULSE_INTERVAL_REG_V_MASK) + +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_ADDRESS 0x00000028 +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_OFFSET 0x00000028 +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_V_MSB 31 +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_V_LSB 0 +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_V_MASK 0xffffffff +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_V_GET(x) (((x) & CSB_ADDR_LOAD_SETUP_HOLD_REG_V_MASK) >> CSB_ADDR_LOAD_SETUP_HOLD_REG_V_LSB) +#define CSB_ADDR_LOAD_SETUP_HOLD_REG_V_SET(x) (((x) << CSB_ADDR_LOAD_SETUP_HOLD_REG_V_LSB) & CSB_ADDR_LOAD_SETUP_HOLD_REG_V_MASK) + +#define EFUSE_INTF0_ADDRESS 0x00000800 +#define EFUSE_INTF0_OFFSET 0x00000800 +#define EFUSE_INTF0_R_MSB 31 +#define EFUSE_INTF0_R_LSB 0 +#define EFUSE_INTF0_R_MASK 0xffffffff +#define EFUSE_INTF0_R_GET(x) (((x) & EFUSE_INTF0_R_MASK) >> EFUSE_INTF0_R_LSB) +#define EFUSE_INTF0_R_SET(x) (((x) << EFUSE_INTF0_R_LSB) & EFUSE_INTF0_R_MASK) + +#define EFUSE_INTF1_ADDRESS 0x00001000 +#define EFUSE_INTF1_OFFSET 0x00001000 +#define EFUSE_INTF1_R_MSB 31 +#define EFUSE_INTF1_R_LSB 0 +#define EFUSE_INTF1_R_MASK 0xffffffff +#define EFUSE_INTF1_R_GET(x) (((x) & EFUSE_INTF1_R_MASK) >> EFUSE_INTF1_R_LSB) +#define EFUSE_INTF1_R_SET(x) (((x) << EFUSE_INTF1_R_LSB) & EFUSE_INTF1_R_MASK) + +#ifndef __ASSEMBLER__ +typedef struct efuse_reg_reg_s { + volatile unsigned int efuse_wr_enable_reg; + volatile unsigned int efuse_int_enable_reg; + volatile unsigned int efuse_int_status_reg; + volatile unsigned int bitmask_wr_reg; + volatile unsigned int vddq_settle_time_reg; + volatile unsigned int vddq_hold_time_reg; + volatile unsigned int rd_strobe_pw_reg; + volatile unsigned int pg_strobe_pw_reg; + volatile unsigned int pgenb_setup_hold_time_reg; + volatile unsigned int strobe_pulse_interval_reg; + volatile unsigned int csb_addr_load_setup_hold_reg; + unsigned char pad0[2004]; /* pad to 0x800 */ + volatile unsigned int efuse_intf0[512]; + volatile unsigned int efuse_intf1[512]; +} efuse_reg_reg_t; +#endif /* __ASSEMBLER__ */ + +#endif /* _EFUSE_REG_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/enet.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/enet.h new file mode 100644 index 0000000000000..a9f03b7e68694 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/enet.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _ENET__H_ +#define _ENET__H_ + +#if defined(ATH_TARGET) +#include /* A_UINT8 */ +#else +#include /* A_UINT8 */ +#endif + + +#define ETHERNET_ADDR_LEN 6 /* bytes */ +#define ETHERNET_TYPE_LEN 2 /* bytes - length of the Ethernet type field */ + +struct ethernet_hdr_t { + A_UINT8 dest_addr[ETHERNET_ADDR_LEN]; + A_UINT8 src_addr[ETHERNET_ADDR_LEN]; + A_UINT8 ethertype[ETHERNET_TYPE_LEN]; +}; + +#define ETHERNET_HDR_LEN (sizeof(struct ethernet_hdr_t)) + +#define ETHERNET_CRC_LEN 4 /* bytes - length of the Ethernet CRC */ +#define ETHERNET_MAX_LEN 1518 /* bytes */ + +#define ETHERNET_MTU (ETHERNET_MAX_LEN - (ETHERNET_HDR_LEN + ETHER_CRC_LEN)) + + +struct llc_snap_hdr_t { + A_UINT8 dsap; + A_UINT8 ssap; + A_UINT8 cntl; + A_UINT8 org_code[3]; + A_UINT8 ethertype[2]; +}; + +#define LLC_SNAP_HDR_LEN (sizeof(struct llc_snap_hdr_t)) +#define LLC_SNAP_HDR_OFFSET_ETHERTYPE \ + (offsetof(struct llc_snap_hdr_t, ethertype[0])) + +#define ETHERTYPE_VLAN_LEN 4 + +struct ethernet_vlan_hdr_t { + A_UINT8 dest_addr[ETHERNET_ADDR_LEN]; + A_UINT8 src_addr[ETHERNET_ADDR_LEN]; + A_UINT8 vlan_tpid[2]; + A_UINT8 vlan_tci[2]; + A_UINT8 ethertype[2]; +}; + +#define ETHERTYPE_IS_EAPOL_WAPI(typeorlen) \ + ((typeorlen) == ETHERTYPE_PAE || \ + (typeorlen) == ETHERTYPE_WAI) + +#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600) + +#ifndef ETHERTYPE_IPV4 +#define ETHERTYPE_IPV4 0x0800 /* Internet Protocol, Version 4 (IPv4) */ +#endif + +#ifndef ETHERTYPE_AARP +#define ETHERTYPE_AARP 0x80f3 /* Internal QCA AARP protocol */ +#endif + +#ifndef ETHERTYPE_IPX +#define ETHERTYPE_IPX 0x8137 /* IPX over DIX protocol */ +#endif + +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* Address Resolution Protocol (ARP) */ +#endif + +#ifndef ETHERTYPE_RARP +#define ETHERTYPE_RARP 0x8035 /* Reverse Address Resolution Protocol (RARP) */ +#endif + +#ifndef ETHERTYPE_VLAN +#define ETHERTYPE_VLAN 0x8100 /* VLAN TAG protocol */ +#endif + +#ifndef ETHERTYPE_SNMP +#define ETHERTYPE_SNMP 0x814C /* Simple Network Management Protocol (SNMP) */ +#endif + +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86DD /* Internet Protocol, Version 6 (IPv6) */ +#endif + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888E /* EAP over LAN (EAPOL) */ +#endif + +#ifndef ETHERTYPE_WAI +#define ETHERTYPE_WAI 0x88B4 /* WAPI */ +#endif + +#ifndef ETHERTYPE_TDLS +#define ETHERTYPE_TDLS 0x890D /* TDLS */ +#endif + +#define LLC_SNAP_LSAP 0xaa +#define LLC_UI 0x3 + +#define RFC1042_SNAP_ORGCODE_0 0x00 +#define RFC1042_SNAP_ORGCODE_1 0x00 +#define RFC1042_SNAP_ORGCODE_2 0x00 + +#define BTEP_SNAP_ORGCODE_0 0x00 +#define BTEP_SNAP_ORGCODE_1 0x00 +#define BTEP_SNAP_ORGCODE_2 0xf8 + + +#define IS_SNAP(_llc) ((_llc)->dsap == LLC_SNAP_LSAP && \ + (_llc)->ssap == LLC_SNAP_LSAP && \ + (_llc)->cntl == LLC_UI) + +#define IS_RFC1042(_llc) ((_llc)->org_code[0] == RFC1042_SNAP_ORGCODE_0 && \ + (_llc)->org_code[1] == RFC1042_SNAP_ORGCODE_1 && \ + (_llc)->org_code[2] == RFC1042_SNAP_ORGCODE_2) + +#define IS_BTEP(_llc) ((_llc)->org_code[0] == BTEP_SNAP_ORGCODE_0 && \ + (_llc)->org_code[1] == BTEP_SNAP_ORGCODE_1 && \ + (_llc)->org_code[2] == BTEP_SNAP_ORGCODE_2) + + +#endif /* _ENET__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h new file mode 100644 index 0000000000000..b228d37121c90 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h @@ -0,0 +1,820 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//============================================================================== +// HIF specific declarations and prototypes +// +// Author(s): ="Atheros" +//============================================================================== +#ifndef _HIF_H_ +#define _HIF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Header files */ +//#include "a_config.h" +#include "athdefs.h" +#include "a_types.h" +#include "osapi_linux.h" +#include "dl_list.h" + +#define ENABLE_MBOX_DUMMY_SPACE_FEATURE 1 + +typedef struct htc_callbacks HTC_CALLBACKS; +typedef struct hif_device HIF_DEVICE; +typedef void __iomem *A_target_id_t; + +#define HIF_TYPE_AR6002 2 +#define HIF_TYPE_AR6003 3 +#define HIF_TYPE_AR6004 5 +#define HIF_TYPE_AR9888 6 +#define HIF_TYPE_AR6320 7 +#define HIF_TYPE_AR6320V2 8 +/* For attaching Peregrine 2.0 board host_reg_tbl only */ +#define HIF_TYPE_AR9888V2 8 + +/* + * direction - Direction of transfer (HIF_READ/HIF_WRITE). + */ +#define HIF_READ 0x00000001 +#define HIF_WRITE 0x00000002 +#define HIF_DIR_MASK (HIF_READ | HIF_WRITE) + +/* + * type - An interface may support different kind of read/write commands. + * For example: SDIO supports CMD52/CMD53s. In case of MSIO it + * translates to using different kinds of TPCs. The command type + * is thus divided into a basic and an extended command and can + * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO. + */ +#define HIF_BASIC_IO 0x00000004 +#define HIF_EXTENDED_IO 0x00000008 +#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO) + +/* + * emode - This indicates the whether the command is to be executed in a + * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ + * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been + * implemented using the asynchronous mode allowing the the bus + * driver to indicate the completion of operation through the + * registered callback routine. The requirement primarily comes + * from the contexts these operations get called from (a driver's + * transmit context or the ISR context in case of receive). + * Support for both of these modes is essential. + */ +#define HIF_SYNCHRONOUS 0x00000010 +#define HIF_ASYNCHRONOUS 0x00000020 +#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) + +/* + * dmode - An interface may support different kinds of commands based on + * the tradeoff between the amount of data it can carry and the + * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ + * HIF_BLOCK_BASIS). In case of latter, the data is rounded off + * to the nearest block size by padding. The size of the block is + * configurable at compile time using the HIF_BLOCK_SIZE and is + * negotiated with the target during initialization after the + * AR6000 interrupts are enabled. + */ +#define HIF_BYTE_BASIS 0x00000040 +#define HIF_BLOCK_BASIS 0x00000080 +#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) + +/* + * amode - This indicates if the address has to be incremented on AR6000 + * after every read/write operation (HIF?FIXED_ADDRESS/ + * HIF_INCREMENTAL_ADDRESS). + */ +#define HIF_FIXED_ADDRESS 0x00000100 +#define HIF_INCREMENTAL_ADDRESS 0x00000200 +#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) + +/* + * dummy - data written into the dummy space will not put into the final mbox FIFO + */ +#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 + + +#define HIF_WR_ASYNC_BYTE_FIX \ + (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) +#define HIF_WR_ASYNC_BYTE_INC \ + (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_WR_ASYNC_BLOCK_INC \ + (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_WR_SYNC_BYTE_FIX \ + (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) +#define HIF_WR_SYNC_BYTE_INC \ + (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_WR_SYNC_BLOCK_INC \ + (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_WR_ASYNC_BLOCK_FIX \ + (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) +#define HIF_WR_SYNC_BLOCK_FIX \ + (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) +#define HIF_RD_SYNC_BYTE_INC \ + (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_RD_SYNC_BYTE_FIX \ + (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) +#define HIF_RD_ASYNC_BYTE_FIX \ + (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) +#define HIF_RD_ASYNC_BLOCK_FIX \ + (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) +#define HIF_RD_ASYNC_BYTE_INC \ + (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_RD_ASYNC_BLOCK_INC \ + (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_RD_SYNC_BLOCK_INC \ + (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) +#define HIF_RD_SYNC_BLOCK_FIX \ + (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) + +typedef enum { + HIF_DEVICE_POWER_STATE = 0, + HIF_DEVICE_GET_MBOX_BLOCK_SIZE, + HIF_DEVICE_GET_MBOX_ADDR, + HIF_DEVICE_GET_PENDING_EVENTS_FUNC, + HIF_DEVICE_GET_IRQ_PROC_MODE, + HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, + HIF_DEVICE_POWER_STATE_CHANGE, + HIF_DEVICE_GET_IRQ_YIELD_PARAMS, + HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT, + HIF_DEVICE_GET_OS_DEVICE, + HIF_DEVICE_DEBUG_BUS_STATE, + HIF_BMI_DONE, + HIF_DEVICE_SET_TARGET_TYPE, + HIF_DEVICE_SET_HTC_CONTEXT, + HIF_DEVICE_GET_HTC_CONTEXT, +} HIF_DEVICE_CONFIG_OPCODE; + +/* + * HIF CONFIGURE definitions: + * + * HIF_DEVICE_GET_MBOX_BLOCK_SIZE + * input : none + * output : array of 4 u_int32_ts + * notes: block size is returned for each mailbox (4) + * + * HIF_DEVICE_GET_MBOX_ADDR + * input : none + * output : HIF_DEVICE_MBOX_INFO + * notes: + * + * HIF_DEVICE_GET_PENDING_EVENTS_FUNC + * input : none + * output: HIF_PENDING_EVENTS_FUNC function pointer + * notes: this is optional for the HIF layer, if the request is + * not handled then it indicates that the upper layer can use + * the standard device methods to get pending events (IRQs, mailbox messages etc..) + * otherwise it can call the function pointer to check pending events. + * + * HIF_DEVICE_GET_IRQ_PROC_MODE + * input : none + * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode) + * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF + * layer can report whether IRQ processing is requires synchronous behavior or + * can be processed using asynchronous bus requests (typically faster). + * + * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC + * input : + * output : HIF_MASK_UNMASK_RECV_EVENT function pointer + * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism + * to mask receive message events. The upper layer can call this pointer when it needs + * to mask/unmask receive events (in case it runs out of buffers). + * + * HIF_DEVICE_POWER_STATE_CHANGE + * + * input : HIF_DEVICE_POWER_CHANGE_TYPE + * output : none + * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change + * requests in an interconnect specific way. This is highly OS and bus driver dependent. + * The caller must guarantee that no HIF read/write requests will be made after the device + * is powered down. + * + * HIF_DEVICE_GET_IRQ_YIELD_PARAMS + * + * input : none + * output : HIF_DEVICE_IRQ_YIELD_PARAMS + * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler. + * The DSR callback handler will exit after a fixed number of RX packets or events are processed. + * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY. + * The HIF implementation can ignore this command if it does not desire the DSR callback to yield. + * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the + * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is + * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning. + * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared + * to process interrupts again. + * + * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT + * input : none + * output : HIF_DEVICE_SCATTER_SUPPORT_INFO + * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests + * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for + * multi-message transfers that can better utilize the bus interconnect. + * + * + * HIF_DEVICE_GET_OS_DEVICE + * intput : none + * output : HIF_DEVICE_OS_DEVICE_INFO; + * note: On some operating systems, the HIF layer has a parent device object for the bus. This object + * may be required to register certain types of logical devices. + * + * HIF_DEVICE_DEBUG_BUS_STATE + * input : none + * output : none + * note: This configure option triggers the HIF interface to dump as much bus interface state. This + * configuration request is optional (No-OP on some HIF implementations) + * + * HIF_DEVICE_SET_TARGET_TYPE + * input : TARGET_TYPE_* + * output : none + * note: Some HIF implementations may need to know TargetType in order to access + * Target registers or Host Interest Area. (No-OP on some HIF implementations) + */ + +typedef struct { + u_int32_t ExtendedAddress; /* extended address for larger writes */ + u_int32_t ExtendedSize; +} HIF_MBOX_PROPERTIES; + +#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ + +typedef struct { + u_int32_t MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in + and ARRAY of 32-bit words */ + + /* the following describe extended mailbox properties */ + HIF_MBOX_PROPERTIES MboxProp[4]; + /* if the HIF supports the GMbox extended address region it can report it + * here, some interfaces cannot support the GMBOX address range and not set this */ + u_int32_t GMboxAddress; + u_int32_t GMboxSize; + u_int32_t Flags; /* flags to describe mbox behavior or usage */ +} HIF_DEVICE_MBOX_INFO; + +typedef enum { + HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all + interrupts before returning */ + HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts + using ASYNC I/O (that is HIFAckInterrupt can be called at a + later time */ +} HIF_DEVICE_IRQ_PROCESSING_MODE; + +typedef enum { + HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */ + HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */ + HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures + to completely power-off the module and associated hardware (i.e. cut power supplies) + */ +} HIF_DEVICE_POWER_CHANGE_TYPE; + +typedef enum { + HIF_DEVICE_STATE_ON, + HIF_DEVICE_STATE_DEEPSLEEP, + HIF_DEVICE_STATE_CUTPOWER, + HIF_DEVICE_STATE_WOW +} HIF_DEVICE_STATE; + +typedef struct { + int RecvPacketYieldCount; /* max number of packets to force DSR to return */ +} HIF_DEVICE_IRQ_YIELD_PARAMS; + + +typedef struct _HIF_SCATTER_ITEM { + u_int8_t *pBuffer; /* CPU accessible address of buffer */ + int Length; /* length of transfer to/from this buffer */ + void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */ +} HIF_SCATTER_ITEM; + +struct _HIF_SCATTER_REQ; + +typedef void ( *HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *); + +typedef enum _HIF_SCATTER_METHOD { + HIF_SCATTER_NONE = 0, + HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */ + HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */ +} HIF_SCATTER_METHOD; + +typedef struct _HIF_SCATTER_REQ { + DL_LIST ListLink; /* link management */ + u_int32_t Address; /* address for the read/write operation */ + u_int32_t Request; /* request flags */ + u_int32_t TotalLength; /* total length of entire transfer */ + u_int32_t CallerFlags; /* caller specific flags can be stored here */ + HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */ + int CompletionStatus; /* status of completion */ + void *Context; /* caller context for this request */ + int ValidScatterEntries; /* number of valid entries set by caller */ + HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ + void *HIFPrivate[4]; /* HIF private area */ + u_int8_t *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ + HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */ +} HIF_SCATTER_REQ; + +typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); +typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); +typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); + +typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO { + /* information returned from HIF layer */ + HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc; + HIF_FREE_SCATTER_REQUEST pFreeReqFunc; + HIF_READWRITE_SCATTER pReadWriteScatterFunc; + int MaxScatterEntries; + int MaxTransferSizePerScatterReq; +} HIF_DEVICE_SCATTER_SUPPORT_INFO; + +typedef struct { + void *pOSDevice; +} HIF_DEVICE_OS_DEVICE_INFO; + +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +typedef struct _HID_ACCESS_LOG { + A_UINT32 seqnum; + bool is_write; + void *addr; + A_UINT32 value; +}HIF_ACCESS_LOG; +#endif + +#define HIF_MAX_DEVICES 1 + +struct htc_callbacks { + void *context; /* context to pass to the dsrhandler + note : rwCompletionHandler is provided the context passed to HIFReadWrite */ + int (* rwCompletionHandler)(void *rwContext, int status); + int (* dsrHandler)(void *context); +}; + +typedef struct osdrv_callbacks { + void *context; /* context to pass for all callbacks except deviceRemovedHandler + the deviceRemovedHandler is only called if the device is claimed */ + int (* deviceInsertedHandler)(void *context, void *hif_handle); + int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle); + int (* deviceSuspendHandler)(void *context); + int (* deviceResumeHandler)(void *context); + int (* deviceWakeupHandler)(void *context); + int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config); +} OSDRV_CALLBACKS; + +#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host + needs to read the register table to figure out what */ +#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ + +typedef struct _HIF_PENDING_EVENTS_INFO { + u_int32_t Events; + u_int32_t LookAhead; + u_int32_t AvailableRecvBytes; +} HIF_PENDING_EVENTS_INFO; + + /* function to get pending events , some HIF modules use special mechanisms + * to detect packet available and other interrupts */ +typedef int ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, + HIF_PENDING_EVENTS_INFO *pEvents, + void *AsyncContext); + +#define HIF_MASK_RECV TRUE +#define HIF_UNMASK_RECV FALSE + /* function to mask recv events */ +typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, + bool Mask, + void *AsyncContext); + + +/* + * This API is used to perform any global initialization of the HIF layer + * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer + * + */ +int HIFInit(OSDRV_CALLBACKS *callbacks); + +/* This API claims the HIF device and provides a context for handling removal. + * The device removal callback is only called when the OSDRV layer claims + * a device. The claimed context must be non-NULL */ +void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext); +/* release the claimed device */ +void HIFReleaseDevice(HIF_DEVICE *device); + +/* This API allows the HTC layer to attach to the HIF device */ +int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks); +/* This API detaches the HTC layer from the HIF device */ +void HIFDetachHTC(HIF_DEVICE *device); + +/* + * This API is used to provide the read/write interface over the specific bus + * interface. + * address - Starting address in the AR6000's address space. For mailbox + * writes, it refers to the start of the mbox boundary. It should + * be ensured that the last byte falls on the mailbox's EOM. For + * mailbox reads, it refers to the end of the mbox boundary. + * buffer - Pointer to the buffer containg the data to be transmitted or + * received. + * length - Amount of data to be transmitted or received. + * request - Characterizes the attributes of the command. + */ +int +HIFReadWrite(HIF_DEVICE *device, + u_int32_t address, + u_char *buffer, + u_int32_t length, + u_int32_t request, + void *context); + +/* + * This can be initiated from the unload driver context when the OSDRV layer has no more use for + * the device. + */ +void HIFShutDownDevice(HIF_DEVICE *device); +void HIFSurpriseRemoved(HIF_DEVICE *device); + +/* + * This should translate to an acknowledgment to the bus driver indicating that + * the previous interrupt request has been serviced and the all the relevant + * sources have been cleared. HTC is ready to process more interrupts. + * This should prevent the bus driver from raising an interrupt unless the + * previous one has been serviced and acknowledged using the previous API. + */ +void HIFAckInterrupt(HIF_DEVICE *device); + +void HIFMaskInterrupt(HIF_DEVICE *device); + +void HIFUnMaskInterrupt(HIF_DEVICE *device); + +int +HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, + void *config, u_int32_t configLen); + +/* + * This API wait for the remaining MBOX messages to be drained + * This should be moved to HTC AR6K layer + */ +int hifWaitForPendingRecv(HIF_DEVICE *device); + +/****************************************************************/ +/* BMI and Diag window abstraction */ +/****************************************************************/ + +#define HIF_BMI_EXCHANGE_NO_TIMEOUT ((u_int32_t)(0)) + +#define DIAG_TRANSFER_LIMIT 2048U /* maximum number of bytes that can be + handled atomically by DiagRead/DiagWrite */ + + /* API to handle HIF-specific BMI message exchanges, this API is synchronous + * and only allowed to be called from a context that can block (sleep) */ +int HIFExchangeBMIMsg(HIF_DEVICE *device, + u_int8_t *pSendMessage, + u_int32_t Length, + u_int8_t *pResponseMessage, + u_int32_t *pResponseLength, + u_int32_t TimeoutMS); + + + + /* + * APIs to handle HIF specific diagnostic read accesses. These APIs are + * synchronous and only allowed to be called from a context that can block (sleep). + * They are not high performance APIs. + * + * HIFDiagReadAccess reads a 4 Byte aligned/length value from a Target register + * or memory word. + * + * HIFDiagReadMem reads an arbitrary length of arbitrarily aligned memory. + */ +int HIFDiagReadAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 *data); +int HIFDiagReadMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes); +void HIFDumpTargetMemory(HIF_DEVICE *hif_device, void *ramdump_base, + u_int32_t address, u_int32_t size); + /* + * APIs to handle HIF specific diagnostic write accesses. These APIs are + * synchronous and only allowed to be called from a context that can block (sleep). + * They are not high performance APIs. + * + * HIFDiagWriteAccess writes a 4 Byte aligned/length value to a Target register + * or memory word. + * + * HIFDiagWriteMem writes an arbitrary length of arbitrarily aligned memory. + */ +int HIFDiagWriteAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 data); +int HIFDiagWriteMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes); +#if defined(HIF_PCI) && ! defined(A_SIMOS_DEVHOST) +/* + * This API allows the Host to access Target registers of a given + * A_target_id_t directly and relatively efficiently over PCIe. + * This allows the Host to avoid extra overhead associated with + * sending a message to firmware and waiting for a response message + * from firmware, as is done on other interconnects. + * + * Yet there is some complexity with direct accesses because the + * Target's power state is not known a priori. The Host must issue + * special PCIe reads/writes in order to explicitly wake the Target + * and to verify that it is awake and will remain awake. + * + * NB: Host endianness conversion is left for the caller to handle. + * These interfaces handle access; not interpretation. + * + * Usage: + * During initialization, use A_TARGET_ID to obtain an 'target ID' + * for use with these interfaces. + * + * Use A_TARGET_READ and A_TARGET_WRITE to access Target space. + * These calls must be bracketed by A_TARGET_ACCESS_BEGIN and + * A_TARGET_ACCESS_END. A single BEGIN/END pair is adequate for + * multiple READ/WRITE operations. + * + * Use A_TARGET_ACCESS_BEGIN to put the Target in a state in + * which it is legal for the Host to directly access it. This + * may involve waking the Target from a low power state, which + * may take up to 2Ms! + * + * Use A_TARGET_ACCESS_END to tell the Target that as far as + * this code path is concerned, it no longer needs to remain + * directly accessible. BEGIN/END is under a reference counter; + * multiple code paths may issue BEGIN/END on a single targid. + * + * For added efficiency, the Host may use A_TARGET_ACCESS_LIKELY. + * The LIKELY interface works just like A_TARGET_ACCESS_BEGIN, + * except that it may return before the Target is actually + * available. It's a vague indication that some Target accesses + * are expected "soon". When the LIKELY API is used, + * A_TARGET_ACCESS_BEGIN must be used before any access. + * + * There are several uses for the LIKELY/UNLIKELY API: + * -If there is some potential time before Target accesses + * and we want to get a head start on waking the Target + * (e.g. to overlap Target wake with Host-side malloc) + * -High-level code knows that it will call low-level + * functions that will use BEGIN/END, and we don't want + * to allow the Target to sleep until the entire sequence + * has completed. + * + * A_TARGET_ACCESS_OK verifies that the Target can be + * accessed. In general, this should not be needed, but it + * may be useful for debugging or for special uses. + * + * Note that there must be a matching END for each BEGIN + * AND there must be a matching UNLIKELY for each LIKELY! + * + * NB: This API is designed to allow some flexibility in tradeoffs + * between Target power utilization and Host efficiency and + * system performance. + */ + +/* + * For maximum performance and no power management, set this to 1. + * For power management at the cost of performance, set this to 0. + */ +#define CONFIG_ATH_PCIE_MAX_PERF 0 + +/* + * For keeping the target awake till the driver is + * loaded, set this to 1 + */ +#define CONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD 1 + +/* + * When CONFIG_ATH_PCIE_MAX_PERF is 0: + * To use LIKELY hints, set this to 1 (slightly better performance, more power) + * To ignore "LIKELY" hints, set this to 0 (slightly worse performance, less power) + */ +#if defined(CONFIG_ATH_PCIE_MAX_PERF) +#define CONFIG_ATH_PCIE_ACCESS_LIKELY 0 +#else +#define CONFIG_ATH_PCIE_ACCESS_LIKELY 1 +#endif + +/* + * Enable/disable CDC max performance workaround + * For max-performace set this to 0 + * To allow SoC to enter sleep set this to 1 + */ +#define CONFIG_DISABLE_CDC_MAX_PERF_WAR 0 + +/* + * PCI-E L1 ASPPM sub-states + * To enable clock gating in L1 state, set this to 1. (less power, slightly more wakeup latency) + * To disable clock gating in L1 state, set this to 0. (slighly more power) + */ +#define CONFIG_PCIE_ENABLE_L1_CLOCK_GATE 1 + +/* + * PCIE_ACCESS_LOG_NUM specifies the number of + * read/write records to store + */ +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +#define PCIE_ACCESS_LOG_NUM 500 +#endif + +/* 64-bit MSI support */ +#define CONFIG_PCIE_64BIT_MSI 0 + +/* BAR0 ready checking for AR6320v2 */ +#define PCIE_BAR0_READY_CHECKING 0 + +/* AXI gating when L1, L2 to reduce power consumption */ +#define CONFIG_PCIE_ENABLE_AXI_CLK_GATE 0 + +extern A_target_id_t HIFGetTargetId(HIF_DEVICE *hifDevice); +extern int HIFTargetSleepStateAdjust(A_target_id_t targid, A_BOOL sleep_ok, A_BOOL wait_for_it); +extern void +HIFSetTargetSleep(HIF_DEVICE *hif_device, A_BOOL sleep_ok, A_BOOL wait_for_it); +extern A_BOOL HIFTargetForcedAwake(A_target_id_t targid); +extern void +HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device); + +#define A_TARGET_ID(hifDevice) HIFGetTargetId(hifDevice) + +#if CONFIG_ATH_PCIE_MAX_PERF +#define A_TARGET_ACCESS_BEGIN(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_END(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_OK(targid) 1 + +#define A_TARGET_ACCESS_LIKELY(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_UNLIKELY(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_READ(targid, offset) \ + A_PCI_READ32(TARGID_TO_PCI_ADDR(targid)+(offset)) + +#if 0 +#define A_TARGET_WRITE(targid, offset, value) \ + A_PCI_WRITE32(TARGID_TO_PCI_ADDR(targid)+(offset), (value)) +#else /* WORKAROUND */ +void WAR_PCI_WRITE32(char *addr, u32 offset, u32 value); +#define A_TARGET_WRITE(targid, offset, value) \ + WAR_PCI_WRITE32(TARGID_TO_PCI_ADDR(targid), (offset), (value)) +#endif +#define A_TARGET_ACCESS_BEGIN_RET(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_BEGIN_RET_EXT(targid, val) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_BEGIN_RET_PTR(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_END_RET(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_END_RET_EXT(targid, val) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_END_RET_PTR(targid) \ + do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0) + +#else /* CONFIG_ATH_PCIE_MAX_PERF */ + +void WAR_PCI_WRITE32(char *addr, u32 offset, u32 value); + +#define A_TARGET_ACCESS_BEGIN_RET_EXT(targid, val) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0 ) \ + val = -1; + +#define A_TARGET_ACCESS_BEGIN_RET(targid) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0) \ + return -1; + +#define A_TARGET_ACCESS_BEGIN_RET_PTR(targid) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0) \ + return NULL; + +#define A_TARGET_ACCESS_BEGIN(targid) \ + if(Q_TARGET_ACCESS_BEGIN(targid) < 0) \ + return; + +#define Q_TARGET_ACCESS_BEGIN(targid) \ + HIFTargetSleepStateAdjust((targid), FALSE, TRUE) + +#define A_TARGET_ACCESS_END_RET(targid) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \ + return -1; + +#define A_TARGET_ACCESS_END_RET_EXT(targid, val) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \ + val = -1; + +#define A_TARGET_ACCESS_END_RET_PTR(targid) \ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \ + return NULL; + +#define A_TARGET_ACCESS_END(targid) \ + if (Q_TARGET_ACCESS_END(targid) < 0) \ + return; + +#define Q_TARGET_ACCESS_END(targid) \ + HIFTargetSleepStateAdjust((targid), TRUE, FALSE) + +#define A_TARGET_ACCESS_OK(targid) HIFTargetForcedAwake(targid) + +#if CONFIG_ATH_PCIE_ACCESS_LIKELY +#define A_TARGET_ACCESS_LIKELY(targid) HIFTargetSleepStateAdjust((targid), FALSE, FALSE) +#define A_TARGET_ACCESS_UNLIKELY(targid) HIFTargetSleepStateAdjust((targid), TRUE, FALSE) +#else /* CONFIG_ATH_PCIE_ACCESS_LIKELY */ +#define A_TARGET_ACCESS_LIKELY(targid) \ + do {unsigned long unused = (unsigned long)(targid); unused = unused;} while(0) + +#define A_TARGET_ACCESS_UNLIKELY(targid) \ + do {unsigned long unused = (unsigned long)(targid); unused = unused;} while(0) +#endif /* CONFIG_ATH_PCIE_ACCESS_LIKELY */ + +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +extern A_UINT32 HIFTargetReadChecked(A_target_id_t targid, A_UINT32 offset); +extern void HIFTargetWriteChecked(A_target_id_t targid, A_UINT32 offset, A_UINT32 value); +#define A_TARGET_READ(targid, offset) HIFTargetReadChecked((targid), (offset)) +#define A_TARGET_WRITE(targid, offset, value) HIFTargetWriteChecked((targid), (offset), (value)) +#else /* CONFIG_ATH_PCIE_ACCESS_DEBUG */ +#define A_TARGET_READ(targid, offset) A_PCI_READ32(TARGID_TO_PCI_ADDR(targid)+(offset)) +#if 0 +#define A_TARGET_WRITE(targid, offset, value) \ + A_PCI_WRITE32(TARGID_TO_PCI_ADDR(targid)+(offset), (value)) +#else /* WORKAROUND */ +#define A_TARGET_WRITE(targid, offset, value) \ + WAR_PCI_WRITE32(TARGID_TO_PCI_ADDR(targid), (offset), (value)) +#endif +#endif + +#endif /* CONFIG_ATH_PCIE_MAX_PERF */ + +/*Macro to increment the HIF layer packet error count*/ +#define OL_ATH_HIF_PKT_ERROR_COUNT_INCR(_hif_state,_hif_ecode);\ +{\ + if(_hif_ecode==HIF_PIPE_NO_RESOURCE)(_hif_state->sc->ol_sc->pkt_stats.hif_pipe_no_resrc_count)+=1;\ +} +/* + * This macro implementation is exposed for efficiency only. + * The implementation may change and callers should + * consider the targid to be a completely opaque handle. + */ +#define TARGID_TO_PCI_ADDR(targid) (*((A_target_id_t *)(targid))) + +void *HIFDeviceToOsDevice(HIF_DEVICE *hif_device); + +#elif defined(A_SIMOS_DEVHOST) + +struct ol_softc; + +u_int32_t sim_target_register_read(struct ol_softc *scn, u_int32_t addr); +void sim_target_register_write(struct ol_softc *scn, u_int32_t addr, u_int32_t val); + +#define A_TARGET_ID(hifDevice) 0 +#define A_TARGET_READ(ar, addr) sim_target_register_read(ar, addr) +#define A_TARGET_WRITE(ar, addr, val) sim_target_register_write(ar, addr, val) +#define A_TARGET_ACCESS_BEGIN(targid) +#define A_TARGET_ACCESS_END(targid) + +#define HIFDeviceToOsDevice(hif_device) NULL + +#else + +#define HIFDeviceToOsDevice(hif_device) NULL + +#endif + +#ifdef IPA_UC_OFFLOAD +/* + * IPA micro controller data path offload feature enabled, + * HIF should release copy engine related resource information to IPA UC + * IPA UC will access hardware resource with released information + */ +void HIFIpaGetCEResource(HIF_DEVICE *hif_device, + A_UINT32 *ce_sr_base_paddr, + A_UINT32 *ce_sr_ring_size, + A_UINT32 *ce_reg_paddr); +#endif /* IPA_UC_OFFLOAD */ + +#ifdef __cplusplus +} +#endif + +#endif /* _HIF_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif_msg_based.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif_msg_based.h new file mode 100644 index 0000000000000..74028eaeefdb4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif_msg_based.h @@ -0,0 +1,151 @@ +/* + *Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +//============================================================================== +// HIF definitions for message based HIFs +//============================================================================== +#ifndef _HIF_MSG_BASED_H_ +#define _HIF_MSG_BASED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "hif.h" + +/** + * @brief List of callbacks - filled in by HTC. + */ +typedef struct { + void *Context; /**< context meaningful to HTC */ + A_STATUS (*txCompletionHandler)(void *Context, adf_nbuf_t wbuf, + unsigned transferID); + A_STATUS (*rxCompletionHandler)(void *Context, adf_nbuf_t wbuf, + u_int8_t pipeID); + void (*txResourceAvailHandler)(void *context, u_int8_t pipe); + void (*fwEventHandler)(void *context, A_STATUS status); +} MSG_BASED_HIF_CALLBACKS; + +int HIF_deregister(void); + +/** + * @brief: This API is used by the HTC layer to initialize the HIF layer and to + * register different callback routines. Support for following events has + * been captured - DSR, Read/Write completion, Device insertion/removal, + * Device suspension/resumption/wakeup. In addition to this, the API is + * also used to register the name and the revision of the chip. The latter + * can be used to verify the revision of the chip read from the device + * before reporting it to HTC. + * @param[in]: callbacks - List of HTC callbacks + * @param[out]: + * @return: an opaque HIF handle + */ +//void *HIFInit(void *hHTC, HTC_CALLBACKS *callbacks); + +void HIFPostInit(HIF_DEVICE *hifDevice, void *hHTC, MSG_BASED_HIF_CALLBACKS *callbacks); + +A_STATUS HIFStart(HIF_DEVICE *hifDevice); + +void HIFStop(HIF_DEVICE *hifDevice); +void HIFFlushSurpriseRemove(HIF_DEVICE *hifDevice); + +void HIFGrowBuffers(void* hif_hdl); + +void HIFDump(HIF_DEVICE *hifDevice, u_int8_t CmdId, bool start); +/** + * @brief: Send a buffer to HIF for transmission to the target. + * @param[in]: hifDevice - HIF handle + * @param[in]: pipeID - pipe to use + * @param[in]: hdr_buf - unused + * @param[in]: buf - buffer to send + * @param[out]: + * @return: Status of the send operation. + */ +int HIFSend(HIF_DEVICE *hifDevice, u_int8_t PipeID, + adf_nbuf_t hdr_buf, adf_nbuf_t wbuf); + +/** + * @brief: Send the head of a buffer to HIF for transmission to the target. + * @param[in]: hifDevice - HIF handle + * @param[in]: pipeID - pipe to use + * @param[in]: transferID - upper-layer ID for this transfer, used in the + * send completion callback to identify the transfer + * @param[in]: nbytes - number of initial bytes to send + * @param[in]: buf - buffer to send + * @param[out]: + * @return: Status of the send operation. + */ +int HIFSend_head(HIF_DEVICE *hifDevice, u_int8_t PipeID, + unsigned int transferID, unsigned int nbytes, adf_nbuf_t wbuf); + +/** + * @brief: Check if prior sends have completed. + * @details: + * Check whether the pipe in question has any completed sends that have + * not yet been processed. + * This function is only relevant for HIF pipes that are configured to be + * polled rather than interrupt-driven. + * + * @param[in]: hifDevice - HIF handle + * @param[in]: pipeID - pipe used for the prior sends + * @param[in]: force - whether this is a poll suggestion or poll command + */ +void HIFSendCompleteCheck(HIF_DEVICE *hifDevice, u_int8_t PipeID, int force); +void HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device); + +/** + * @brief: Shutdown the HIF layer. + * @param[in]: HIFHandle - opaque HIF handle. + * @param[out]: + * @return: + */ +void HIFShutDown(HIF_DEVICE *hifDevice); + +u_int32_t HIFQueryQueueDepth(HIF_DEVICE *hifDevice, u_int8_t epnum); + +void HIFGetDefaultPipe(HIF_DEVICE *hifDevice, u_int8_t *ULPipe, u_int8_t *DLPipe); + +int HIFMapServiceToPipe(HIF_DEVICE *hifDevice, u_int16_t ServiceId, u_int8_t *ULPipe, u_int8_t *DLPipe, int *ul_is_polled, int *dl_is_polled); + +u_int8_t HIFGetULPipeNum(void); +u_int8_t HIFGetDLPipeNum(void); + +//a_status_t HIFGetProductInfo(HIF_DEVICE *hifDevice, adf_net_dev_product_info_t *info); + +u_int16_t HIFGetFreeQueueNumber(HIF_DEVICE *hifDevice, u_int8_t PipeID); +u_int16_t HIFGetMaxQueueNumber(HIF_DEVICE *hifDevice, u_int8_t PipeID); + +void HIFDumpInfo(HIF_DEVICE *hifDevice); +void *hif_get_targetdef(HIF_DEVICE *hif_device); +void HIFsuspendwow(HIF_DEVICE *hif_device); + +#ifdef __cplusplus +} +#endif + +#endif /* _HIF_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc.h new file mode 100644 index 0000000000000..dd6ecb50ab892 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc.h @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __HTC_H__ +#define __HTC_H__ + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif +#undef MS +#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) +#undef SM +#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) +#undef WO +#define WO(_f) ((_f##_OFFSET) >> 2) + +#undef GET_FIELD +#define GET_FIELD(_addr, _f) MS(*((A_UINT32 *)(_addr) + WO(_f)), _f) +#undef SET_FIELD +#define SET_FIELD(_addr, _f, _val) \ + (*((A_UINT32 *)(_addr) + WO(_f)) = \ + (*((A_UINT32 *)(_addr) + WO(_f)) & ~_f##_MASK) | SM(_val, _f)) + +#define HTC_GET_FIELD(_msg_buf, _msg_type, _f) \ + GET_FIELD(_msg_buf, _msg_type ## _ ## _f) + +#define HTC_SET_FIELD(_msg_buf, _msg_type, _f, _val) \ + SET_FIELD(_msg_buf, _msg_type ## _ ## _f, _val) + +#define HTC_WRITE32(_addr, _val) \ + (*(A_UINT32 *)(_addr) = (_val)) + +#ifndef A_OFFSETOF +#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field)) +#endif + +#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ + (((A_UINT16)(((A_UINT8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((A_UINT8 *)(p))[(lowbyte)])) + +/****** DANGER DANGER *************** + * + * The frame header length and message formats defined herein were + * selected to accommodate optimal alignment for target processing. This reduces code + * size and improves performance. + * + * Any changes to the header length may alter the alignment and cause exceptions + * on the target. When adding to the message structures insure that fields are + * properly aligned. + * + */ + +/* HTC frame header */ +typedef PREPACK struct _HTC_FRAME_HDR{ + /* do not remove or re-arrange these fields, these are minimally required + * to take advantage of 4-byte lookaheads in some hardware implementations */ + A_UINT32 EndpointID : 8, + Flags : 8, + PayloadLen : 16; /* length of data (including trailer) that follows the header */ + + /***** end of 4-byte lookahead ****/ + + A_UINT32 ControlBytes0 : 8, /* used for CRC check if CRC_CHECK flag set */ + ControlBytes1 : 8, /* used for seq check if SEQ_CHECK flag set */ + reserved : 16; /* used by bundle processing in SDIO systems */ + + /* message payload starts after the header */ + +} POSTPACK HTC_FRAME_HDR; + +#define HTC_FRAME_HDR_ENDPOINTID_LSB 0 +#define HTC_FRAME_HDR_ENDPOINTID_MASK 0x000000ff +#define HTC_FRAME_HDR_ENDPOINTID_OFFSET 0x00000000 +#define HTC_FRAME_HDR_FLAGS_LSB 8 +#define HTC_FRAME_HDR_FLAGS_MASK 0x0000ff00 +#define HTC_FRAME_HDR_FLAGS_OFFSET 0x00000000 +#define HTC_FRAME_HDR_PAYLOADLEN_LSB 16 +#define HTC_FRAME_HDR_PAYLOADLEN_MASK 0xffff0000 +#define HTC_FRAME_HDR_PAYLOADLEN_OFFSET 0x00000000 +#define HTC_FRAME_HDR_CONTROLBYTES0_LSB 0 +#define HTC_FRAME_HDR_CONTROLBYTES0_MASK 0x000000ff +#define HTC_FRAME_HDR_CONTROLBYTES0_OFFSET 0x00000004 +#define HTC_FRAME_HDR_CONTROLBYTES1_LSB 8 +#define HTC_FRAME_HDR_CONTROLBYTES1_MASK 0x0000ff00 +#define HTC_FRAME_HDR_CONTROLBYTES1_OFFSET 0x00000004 +#define HTC_FRAME_HDR_RESERVED_LSB 16 +#define HTC_FRAME_HDR_RESERVED_MASK 0xffff0000 +#define HTC_FRAME_HDR_RESERVED_OFFSET 0x00000004 + +/* frame header flags */ + + /* send direction */ +#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) +#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */ +#define HTC_FLAGS_SEQ_CHECK (1 << 2) /* seq check on rx side */ +#define HTC_FLAGS_CRC CHECK (1 << 3) /* CRC check on rx side */ + + + /* receive direction */ +#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */ +#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */ +#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */ +#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */ +#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */ +#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4 + +#define HTC_HDR_LENGTH (sizeof(HTC_FRAME_HDR)) +#define HTC_HDR_ALIGNMENT_PADDING \ + (((sizeof(HTC_FRAME_HDR) + 3) & (~0x3)) - sizeof(HTC_FRAME_HDR)) +#define HTC_MAX_TRAILER_LENGTH 255 +#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(HTC_FRAME_HDR)) + +/* HTC control message IDs */ + +#define HTC_MSG_READY_ID 1 +#define HTC_MSG_CONNECT_SERVICE_ID 2 +#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3 +#define HTC_MSG_SETUP_COMPLETE_ID 4 +#define HTC_MSG_SETUP_COMPLETE_EX_ID 5 +#define HTC_MSG_SEND_SUSPEND_COMPLETE 6 +#define HTC_MSG_NACK_SUSPEND 7 + +#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256 + +/* base message ID header */ +typedef PREPACK struct { + A_UINT32 MessageID : 16, + reserved : 16; +} POSTPACK HTC_UNKNOWN_MSG; + +#define HTC_UNKNOWN_MSG_MESSAGEID_LSB 0 +#define HTC_UNKNOWN_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_UNKNOWN_MSG_MESSAGEID_OFFSET 0x00000000 + +/* HTC ready message + * direction : target-to-host */ +typedef PREPACK struct { + A_UINT32 MessageID : 16, /* ID */ + CreditCount: 16; /* number of credits the target can offer */ + A_UINT32 CreditSize : 16, /* size of each credit */ + MaxEndpoints : 8, /* maximum number of endpoints the target has resources for */ + _Pad1 : 8; +} POSTPACK HTC_READY_MSG; + +#define HTC_READY_MSG_MESSAGEID_LSB 0 +#define HTC_READY_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_READY_MSG_MESSAGEID_OFFSET 0x00000000 +#define HTC_READY_MSG_CREDITCOUNT_LSB 16 +#define HTC_READY_MSG_CREDITCOUNT_MASK 0xffff0000 +#define HTC_READY_MSG_CREDITCOUNT_OFFSET 0x00000000 +#define HTC_READY_MSG_CREDITSIZE_LSB 0 +#define HTC_READY_MSG_CREDITSIZE_MASK 0x0000ffff +#define HTC_READY_MSG_CREDITSIZE_OFFSET 0x00000004 +#define HTC_READY_MSG_MAXENDPOINTS_LSB 16 +#define HTC_READY_MSG_MAXENDPOINTS_MASK 0x00ff0000 +#define HTC_READY_MSG_MAXENDPOINTS_OFFSET 0x00000004 + + /* extended HTC ready message */ +typedef PREPACK struct { + HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */ + /* extended information */ + A_UINT32 HTCVersion : 8, + MaxMsgsPerHTCBundle : 8, + reserved : 16; +} POSTPACK HTC_READY_EX_MSG; + +#define HTC_READY_EX_MSG_HTCVERSION_LSB 0 +#define HTC_READY_EX_MSG_HTCVERSION_MASK 0x000000ff +#define HTC_READY_EX_MSG_HTCVERSION_OFFSET sizeof(HTC_READY_MSG) +#define HTC_READY_EX_MSG_MAXMSGSPERHTCBUNDLE_LSB 8 +#define HTC_READY_EX_MSG_MAXMSGSPERHTCBUNDLE_MASK 0x0000ff00 +#define HTC_READY_EX_MSG_MAXMSGSPERHTCBUNDLE_OFFSET sizeof(HTC_READY_MSG) + +#define HTC_VERSION_2P0 0x00 +#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */ + +#define HTC_SERVICE_META_DATA_MAX_LENGTH 128 + +/* connect service + * direction : host-to-target */ +typedef PREPACK struct { + A_UINT32 MessageID : 16, + ServiceID : 16; /* service ID of the service to connect to */ + A_UINT32 ConnectionFlags : 16, /* connection flags */ + +#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when + the host needs credits */ +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3) +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3 + /* disable credit flow control on a specific service */ +#define HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL (1 << 3) + /* enable htc schedule on a specific service */ +#define HTC_CONNECT_FLAGS_ENABLE_HTC_SCHEDULE (1 << 4) + + ServiceMetaLength : 8, /* length of meta data that follows */ + _Pad1 : 8; + + /* service-specific meta data starts after the header */ + +} POSTPACK HTC_CONNECT_SERVICE_MSG; + +#define HTC_CONNECT_SERVICE_MSG_MESSAGEID_LSB 0 +#define HTC_CONNECT_SERVICE_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_CONNECT_SERVICE_MSG_MESSAGEID_OFFSET 0x00000000 +#define HTC_CONNECT_SERVICE_MSG_SERVICE_ID_LSB 16 +#define HTC_CONNECT_SERVICE_MSG_SERVICE_ID_MASK 0xffff0000 +#define HTC_CONNECT_SERVICE_MSG_SERVICE_ID_OFFSET 0x00000000 +#define HTC_CONNECT_SERVICE_MSG_CONNECTIONFLAGS_LSB 0 +#define HTC_CONNECT_SERVICE_MSG_CONNECTIONFLAGS_MASK 0x0000ffff +#define HTC_CONNECT_SERVICE_MSG_CONNECTIONFLAGS_OFFSET 0x00000004 +#define HTC_CONNECT_SERVICE_MSG_SERVICEMETALENGTH_LSB 16 +#define HTC_CONNECT_SERVICE_MSG_SERVICEMETALENGTH_MASK 0x00ff0000 +#define HTC_CONNECT_SERVICE_MSG_SERVICEMETALENGTH_OFFSET 0x00000004 + +#define HTC_SET_RECV_ALLOC_SHIFT 8 +#define HTC_SET_RECV_ALLOC_MASK 0xFF00 +#define HTC_CONNECT_FLAGS_SET_RECV_ALLOCATION(value) (((A_UINT8)value) << HTC_SET_RECV_ALLOC_SHIFT) +#define HTC_CONNECT_FLAGS_GET_RECV_ALLOCATION(value) (A_UINT8)(((value) & HTC_SET_RECV_ALLOC_MASK) >> HTC_SET_RECV_ALLOC_SHIFT) + +/* connect response + * direction : target-to-host */ +typedef PREPACK struct { + A_UINT32 MessageID : 16, + ServiceID : 16; /* service ID that the connection request was made */ + A_UINT32 Status : 8, /* service connection status */ + EndpointID : 8, /* assigned endpoint ID */ + MaxMsgSize : 16; /* maximum expected message size on this endpoint */ + A_UINT32 ServiceMetaLength : 8, /* length of meta data that follows */ + _Pad1 : 8, + reserved : 16; + + /* service-specific meta data starts after the header */ + +} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG; + +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MESSAGEID_LSB 0 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MESSAGEID_OFFSET 0x00000000 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEID_LSB 16 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEID_MASK 0xffff0000 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEID_OFFSET 0x00000000 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_STATUS_LSB 0 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_STATUS_MASK 0x000000ff +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_STATUS_OFFSET 0x00000004 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_ENDPOINTID_LSB 8 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_ENDPOINTID_MASK 0x0000ff00 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_ENDPOINTID_OFFSET 0x00000004 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MAXMSGSIZE_LSB 16 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MAXMSGSIZE_MASK 0xffff0000 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_MAXMSGSIZE_OFFSET 0x00000004 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEMETALENGTH_LSB 0 +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEMETALENGTH_MASK 0x000000ff +#define HTC_CONNECT_SERVICE_RESPONSE_MSG_SERVICEMETALENGTH_OFFSET 0x00000008 + +typedef PREPACK struct { + A_UINT32 MessageID : 16, + reserved : 16; + /* currently, no other fields */ +} POSTPACK HTC_SETUP_COMPLETE_MSG; + +#define HTC_SETUP_COMPLETE_MSG_MESSAGEID_LSB 0 +#define HTC_SETUP_COMPLETE_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_SETUP_COMPLETE_MSG_MESSAGEID_OFFSET 0x00000000 + + /* extended setup completion message */ +typedef PREPACK struct { + A_UINT32 MessageID : 16, + reserved : 16; + A_UINT32 SetupFlags : 32; + A_UINT32 MaxMsgsPerBundledRecv : 8, + Rsvd0 : 8, + Rsvd1 : 8, + Rsvd2 : 8; +} POSTPACK HTC_SETUP_COMPLETE_EX_MSG; + +#define HTC_SETUP_COMPLETE_EX_MSG_MESSAGEID_LSB 0 +#define HTC_SETUP_COMPLETE_EX_MSG_MESSAGEID_MASK 0x0000ffff +#define HTC_SETUP_COMPLETE_EX_MSG_MESSAGEID_OFFSET 0x00000000 +#define HTC_SETUP_COMPLETE_EX_MSG_SETUPFLAGS_LSB 0 +#define HTC_SETUP_COMPLETE_EX_MSG_SETUPFLAGS_MASK 0xffffffff +#define HTC_SETUP_COMPLETE_EX_MSG_SETUPFLAGS_OFFSET 0x00000004 +#define HTC_SETUP_COMPLETE_EX_MSG_MAXMSGSPERBUNDLEDRECV_LSB 0 +#define HTC_SETUP_COMPLETE_EX_MSG_MAXMSGSPERBUNDLEDRECV_MASK 0x000000ff +#define HTC_SETUP_COMPLETE_EX_MSG_MAXMSGSPERBUNDLEDRECV_OFFSET 0x00000008 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD0_LSB 8 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD0_MASK 0x0000ff00 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD0_OFFSET 0x00000008 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD1_LSB 16 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD1_MASK 0x00ff0000 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD1_OFFSET 0x00000008 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD2_LSB 24 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD2_MASK 0xff000000 +#define HTC_SETUP_COMPLETE_EX_MSG_RSVD2_OFFSET 0x00000008 + +#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0) /* enable recv bundling from target */ +#define HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW (1 << 1) /* disable credit based flow control, + only supported on some interconnects */ + +/* connect response status codes */ +#define HTC_SERVICE_SUCCESS 0 /* success */ +#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */ +#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */ +#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */ +#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more + endpoints */ + +/* report record IDs */ + +#define HTC_RECORD_NULL 0 +#define HTC_RECORD_CREDITS 1 +#define HTC_RECORD_LOOKAHEAD 2 +#define HTC_RECORD_LOOKAHEAD_BUNDLE 3 + +typedef PREPACK struct { + A_UINT32 RecordID : 8, /* Record ID */ + Length : 8, /* Length of record */ + reserved : 16; +} POSTPACK HTC_RECORD_HDR; + +#define HTC_RECORD_HDR_RECORDID_LSB 0 +#define HTC_RECORD_HDR_RECORDID_MASK 0x000000ff +#define HTC_RECORD_HDR_RECORDID_OFFSET 0x00000000 +#define HTC_RECORD_HDR_LENGTH_LSB 8 +#define HTC_RECORD_HDR_LENGTH_MASK 0x0000ff00 +#define HTC_RECORD_HDR_LENGTH_OFFSET 0x00000000 + +typedef PREPACK struct { + A_UINT32 EndpointID : 8, /* Endpoint that owns these credits */ + Credits : 8, /* credits to report since last report */ + reserved : 16; +} POSTPACK HTC_CREDIT_REPORT; + +#define HTC_CREDIT_REPORT_ENDPOINTID_LSB 0 +#define HTC_CREDIT_REPORT_ENDPOINTID_MASK 0x000000ff +#define HTC_CREDIT_REPORT_ENDPOINTID_OFFSET 0x00000000 +#define HTC_CREDIT_REPORT_CREDITS_LSB 8 +#define HTC_CREDIT_REPORT_CREDITS_MASK 0x0000ff00 +#define HTC_CREDIT_REPORT_CREDITS_OFFSET 0x00000000 + +typedef PREPACK struct { + A_UINT32 PreValid : 8, /* pre valid guard */ + reserved0 : 24; + A_UINT32 LookAhead0 : 8, /* 4 byte lookahead */ + LookAhead1 : 8, + LookAhead2 : 8, + LookAhead3 : 8; + A_UINT32 PostValid : 8, /* post valid guard */ + reserved1 : 24; + + /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes. + * The PreValid bytes must equal the inverse of the PostValid byte */ + +} POSTPACK HTC_LOOKAHEAD_REPORT; + +#define HTC_LOOKAHEAD_REPORT_PREVALID_LSB 0 +#define HTC_LOOKAHEAD_REPORT_PREVALID_MASK 0x000000ff +#define HTC_LOOKAHEAD_REPORT_PREVALID_OFFSET 0x00000000 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD0_LSB 0 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD0_MASK 0x000000ff +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD0_OFFSET 0x00000004 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD1_LSB 8 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD1_MASK 0x0000ff00 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD1_OFFSET 0x00000004 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD2_LSB 16 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD2_MASK 0x00ff0000 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD2_OFFSET 0x00000004 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD3_LSB 24 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD3_MASK 0xff000000 +#define HTC_LOOKAHEAD_REPORT_LOOKAHEAD3_OFFSET 0x00000004 +#define HTC_LOOKAHEAD_REPORT_POSTVALID_LSB 0 +#define HTC_LOOKAHEAD_REPORT_POSTVALID_MASK 0x000000ff +#define HTC_LOOKAHEAD_REPORT_POSTVALID_OFFSET 0x00000008 + +typedef PREPACK struct { + A_UINT32 LookAhead0 : 8, /* 4 byte lookahead */ + LookAhead1 : 8, + LookAhead2 : 8, + LookAhead3 : 8; +} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT; + +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD0_LSB 0 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD0_MASK 0x000000ff +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD0_OFFSET 0x00000000 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD1_LSB 8 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD1_MASK 0x0000ff00 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD1_OFFSET 0x00000000 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD2_LSB 16 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD2_MASK 0x00ff0000 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD2_OFFSET 0x00000000 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD3_LSB 24 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD3_MASK 0xff000000 +#define HTC_BUNDLED_LOOKAHEAD_REPORT_LOOKAHEAD3_OFFSET 0x00000000 + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + + +#endif /* __HTC_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_api.h new file mode 100644 index 0000000000000..05a358e53b033 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_api.h @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _HTC_API_H_ +#define _HTC_API_H_ + +#include +#include "osapi_linux.h" +#include "htc_packet.h" +#include +#include +#include /* adf_os_device_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* TODO.. for BMI */ +#define ENDPOINT1 0 +// TODO -remove me, but we have to fix BMI first +#define HTC_MAILBOX_NUM_MAX 4 + +/* this is the amount of header room required by users of HTC */ +#define HTC_HEADER_LEN HTC_HDR_LENGTH + +typedef void *HTC_HANDLE; + +typedef A_UINT16 HTC_SERVICE_ID; + +typedef void (*HTC_TARGET_FAILURE)(void *Instance, A_STATUS Status); + +typedef struct _HTC_INIT_INFO { + void *pContext; /* context for target notifications */ + void (*TargetFailure)(void *Instance, A_STATUS Status); + void (*TargetSendSuspendComplete)(void *ctx); +} HTC_INIT_INFO; + +/* Struct for HTC layer packet stats*/ +struct ol_ath_htc_stats { + int htc_get_pkt_q_fail_count; + int htc_pkt_q_empty_count; + int htc_send_q_empty_count; +}; + +/* per service connection send completion */ +typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *); +/* per service connection callback when a plurality of packets have been sent + * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) + * to hold a list of completed send packets. + * If the handler cannot fully traverse the packet queue before returning, it should + * transfer the items of the queue into the caller's private queue using: + * HTC_PACKET_ENQUEUE() */ +typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,HTC_PACKET_QUEUE *); +/* per service connection pkt received */ +typedef void (*HTC_EP_RECV_PKT)(void *,HTC_PACKET *); +/* per service connection callback when a plurality of packets are received + * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) + * to hold a list of recv packets. + * If the handler cannot fully traverse the packet queue before returning, it should + * transfer the items of the queue into the caller's private queue using: + * HTC_PACKET_ENQUEUE() */ +typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,HTC_PACKET_QUEUE *); + +/* Optional per service connection receive buffer re-fill callback, + * On some OSes (like Linux) packets are allocated from a global pool and indicated up + * to the network stack. The driver never gets the packets back from the OS. For these OSes + * a refill callback can be used to allocate and re-queue buffers into HTC. + * + * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and + * the driver can re-queue these buffers into HTC. In this regard a refill callback is + * unnecessary */ +typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint); + +/* Optional per service connection receive buffer allocation callback. + * On some systems packet buffers are an extremely limited resource. Rather than + * queue largest-possible-sized buffers to HTC, some systems would rather + * allocate a specific size as the packet is received. The trade off is + * slightly more processing (callback invoked for each RX packet) + * for the benefit of committing fewer buffer resources into HTC. + * + * The callback is provided the length of the pending packet to fetch. This includes the + * HTC header length plus the length of payload. The callback can return a pointer to + * the allocated HTC packet for immediate use. + * + * Alternatively a variant of this handler can be used to allocate large receive packets as needed. + * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to + * handle the case where a large packet buffer is required. This can significantly reduce the + * amount of "committed" memory used to receive packets. + * + * */ +typedef HTC_PACKET *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length); + +typedef enum _HTC_SEND_FULL_ACTION { + HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */ + HTC_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */ +} HTC_SEND_FULL_ACTION; + +/* Optional per service connection callback when a send queue is full. This can occur if the + * host continues queueing up TX packets faster than credits can arrive + * To prevent the host (on some Oses like Linux) from continuously queueing packets + * and consuming resources, this callback is provided so that that the host + * can disable TX in the subsystem (i.e. network stack). + * This callback is invoked for each packet that "overflows" the HTC queue. The callback can + * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or + * dropped (HTC_SEND_FULL_DROP). If a packet is dropped, the EpTxComplete handler will be called + * and the packet's status field will be set to A_NO_RESOURCE. + * Other OSes require a "per-packet" indication for each completed TX packet, this + * closed loop mechanism will prevent the network stack from overunning the NIC + * The packet to keep or drop is passed for inspection to the registered handler the handler + * must ONLY inspect the packet, it may not free or reclaim the packet. */ +typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_PACKET *pPacket); + +typedef struct _HTC_EP_CALLBACKS { + void *pContext; /* context for each callback */ + HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */ + HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */ + HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */ + HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */ + HTC_EP_RECV_ALLOC EpRecvAlloc; /* OPTIONAL recv allocation callback */ + HTC_EP_RECV_ALLOC EpRecvAllocThresh; /* OPTIONAL recv allocation callback based on a threshold */ + HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete + indications (EpTxComplete must be NULL) */ + HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple + recv packet indications (EpRecv must be NULL) */ + int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the + threshold value to the current recv packet length and invoke + the EpRecvAllocThresh callback to acquire a packet buffer */ + int RecvRefillWaterMark; /* if a EpRecvRefill handler is provided, this value + can be used to set a trigger refill callback + when the recv queue drops below this value + if set to 0, the refill is only called when packets + are empty */ +} HTC_EP_CALLBACKS; + +/* service connection information */ +typedef struct _HTC_SERVICE_CONNECT_REQ { + HTC_SERVICE_ID ServiceID; /* service ID to connect to */ + A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */ + A_UINT8 *pMetaData; /* ptr to optional service-specific meta-data */ + A_UINT8 MetaDataLength; /* optional meta data length */ + HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ + int MaxSendQueueDepth; /* maximum depth of any send queue */ + A_UINT32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ + unsigned int MaxSendMsgSize; /* override max message size in send direction */ +} HTC_SERVICE_CONNECT_REQ; + +#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */ + +/* service connection response information */ +typedef struct _HTC_SERVICE_CONNECT_RESP { + A_UINT8 *pMetaData; /* caller supplied buffer to optional meta-data */ + A_UINT8 BufferLength; /* length of caller supplied buffer */ + A_UINT8 ActualLength; /* actual length of meta data */ + HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ + unsigned int MaxMsgLength; /* max length of all messages over this endpoint */ + A_UINT8 ConnectRespCode; /* connect response code from target */ +} HTC_SERVICE_CONNECT_RESP; + +/* endpoint distribution structure */ +typedef struct _HTC_ENDPOINT_CREDIT_DIST { + struct _HTC_ENDPOINT_CREDIT_DIST *pNext; + struct _HTC_ENDPOINT_CREDIT_DIST *pPrev; + HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */ + HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */ + A_UINT32 DistFlags; /* distribution flags, distribution function can + set default activity using SET_EP_ACTIVE() macro */ + int TxCreditsNorm; /* credits for normal operation, anything above this + indicates the endpoint is over-subscribed, this field + is only relevant to the credit distribution function */ + int TxCreditsMin; /* floor for credit distribution, this field is + only relevant to the credit distribution function */ + int TxCreditsAssigned; /* number of credits assigned to this EP, this field + is only relevant to the credit dist function */ + int TxCredits; /* current credits available, this field is used by + HTC to determine whether a message can be sent or + must be queued */ + int TxCreditsToDist; /* pending credits to distribute on this endpoint, this + is set by HTC when credit reports arrive. + The credit distribution functions sets this to zero + when it distributes the credits */ + int TxCreditsSeek; /* this is the number of credits that the current pending TX + packet needs to transmit. This is set by HTC when + and endpoint needs credits in order to transmit */ + int TxCreditSize; /* size in bytes of each credit (set by HTC) */ + int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */ + void *pHTCReserved; /* reserved for HTC use */ + int TxQueueDepth; /* current depth of TX queue , i.e. messages waiting for credits + This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE + or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint + that has non-zero credits to recover + */ +} HTC_ENDPOINT_CREDIT_DIST; + +#define HTC_EP_ACTIVE ((A_UINT32) (1u << 31)) + +/* macro to check if an endpoint has gone active, useful for credit + * distributions */ +#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE) +#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE + + /* credit distibution code that is passed into the distrbution function, + * there are mandatory and optional codes that must be handled */ +typedef enum _HTC_CREDIT_DIST_REASON { + HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed + send operations (MANDATORY) resulting in credit reports */ + HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occured (OPTIONAL) */ + HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */ + HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by + the distribution function */ +} HTC_CREDIT_DIST_REASON; + +typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context, + HTC_ENDPOINT_CREDIT_DIST *pEPList, + HTC_CREDIT_DIST_REASON Reason); + +typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context, + HTC_ENDPOINT_CREDIT_DIST *pEPList, + int TotalCredits); + + /* endpoint statistics action */ +typedef enum _HTC_ENDPOINT_STAT_ACTION { + HTC_EP_STAT_SAMPLE = 0, /* only read statistics */ + HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */ + HTC_EP_STAT_CLEAR /* clear only */ +} HTC_ENDPOINT_STAT_ACTION; + + /* endpoint statistics */ +typedef struct _HTC_ENDPOINT_STATS { + A_UINT32 TxPosted; /* number of TX packets posted to the endpoint */ + A_UINT32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on + this endpoint */ + A_UINT32 TxIssued; /* running count of total TX packets issued */ + A_UINT32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */ + A_UINT32 TxBundles; /* running count of TX bundles that were issued */ + A_UINT32 TxDropped; /* tx packets that were dropped */ + A_UINT32 TxCreditRpts; /* running count of total credit reports received for this endpoint */ + A_UINT32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */ + A_UINT32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */ + A_UINT32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */ + A_UINT32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */ + A_UINT32 TxCreditsFromOther; /* count of credits received via another endpoint */ + A_UINT32 TxCreditsFromEp0; /* count of credits received via another endpoint */ + A_UINT32 TxCreditsConsummed; /* count of consummed credits */ + A_UINT32 TxCreditsReturned; /* count of credits returned */ + A_UINT32 RxReceived; /* count of RX packets received */ + A_UINT32 RxLookAheads; /* count of lookahead records + found in messages received on this endpoint */ + A_UINT32 RxPacketsBundled; /* count of recv packets received in a bundle */ + A_UINT32 RxBundleLookAheads; /* count of number of bundled lookaheads */ + A_UINT32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ + A_UINT32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */ + A_UINT32 RxAllocThreshBytes; /* total number of bytes */ +} HTC_ENDPOINT_STATS; + +/* ------ Function Prototypes ------ */ +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Create an instance of HTC over the underlying HIF device + @function name: HTCCreate + @input: HifDevice - hif device handle, + pInfo - initialization information + @output: + @return: HTC_HANDLE on success, NULL on failure + @notes: + @example: + @see also: HTCDestroy ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +HTC_HANDLE HTCCreate(void *HifDevice, + HTC_INIT_INFO *pInfo, + adf_os_device_t osdev); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Get the underlying HIF device handle + @function name: HTCGetHifDevice + @input: HTCHandle - handle passed into the AddInstance callback + @output: + @return: opaque HIF device handle usable in HIF API calls. + @notes: + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void *HTCGetHifDevice(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Set credit distribution parameters + @function name: HTCSetCreditDistribution + @input: HTCHandle - HTC handle + pCreditDistCont - caller supplied context to pass into distribution functions + CreditDistFunc - Distribution function callback + CreditDistInit - Credit Distribution initialization callback + ServicePriorityOrder - Array containing list of service IDs, lowest index is highest + priority + ListLength - number of elements in ServicePriorityOrder + @output: + @return: + @notes: The user can set a custom credit distribution function to handle special requirements + for each endpoint. A default credit distribution routine can be used by setting + CreditInitFunc to NULL. The default credit distribution is only provided for simple + "fair" credit distribution without regard to any prioritization. + + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, + void *pCreditDistContext, + HTC_CREDIT_DIST_CALLBACK CreditDistFunc, + HTC_CREDIT_INIT_CALLBACK CreditInitFunc, + HTC_SERVICE_ID ServicePriorityOrder[], + int ListLength); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Wait for the target to indicate the HTC layer is ready + @function name: HTCWaitTarget + @input: HTCHandle - HTC handle + @output: + @return: + @notes: This API blocks until the target responds with an HTC ready message. + The caller should not connect services until the target has indicated it is + ready. + @example: + @see also: HTCConnectService ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Start target service communications + @function name: HTCStart + @input: HTCHandle - HTC handle + @output: + @return: + @notes: This API indicates to the target that the service connection phase is complete + and the target can freely start all connected services. This API should only be + called AFTER all service connections have been made. TCStart will issue a + SETUP_COMPLETE message to the target to indicate that all service connections + have been made and the target can start communicating over the endpoints. + @example: + @see also: HTCConnectService ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCStart(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Add receive packet to HTC + @function name: HTCAddReceivePkt + @input: HTCHandle - HTC handle + pPacket - HTC receive packet to add + @output: + @return: A_OK on success + @notes: user must supply HTC packets for capturing incomming HTC frames. The caller + must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() + macro. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Connect to an HTC service + @function name: HTCConnectService + @input: HTCHandle - HTC handle + pReq - connection details + @output: pResp - connection response + @return: + @notes: Service connections must be performed before HTCStart. User provides callback handlers + for various endpoint events. + @example: + @see also: HTCStart ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, + HTC_SERVICE_CONNECT_REQ *pReq, + HTC_SERVICE_CONNECT_RESP *pResp); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: HTC register log dump + @function name: HTCDump + @input: HTCHandle - HTC handle + CmdId - Log command + start - start/print logs + @output: + @return: + @notes: Register logs will be started/printed. + be flushed. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +void HTCDump(HTC_HANDLE HTCHandle, u_int8_t CmdId, bool start); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Send an HTC packet + @function name: HTCSendPkt + @input: HTCHandle - HTC handle + pPacket - packet to send + @output: + @return: A_OK + @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro. + This interface is fully asynchronous. On error, HTC SendPkt will + call the registered Endpoint callback to cleanup the packet. + @example: + @see also: HTCFlushEndpoint ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Send an HTC packet containing a tx descriptor and data + @function name: HTCSendDataPkt + @input: HTCHandle - HTC handle + pPacket - packet to send + @output: + @return: A_OK + @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro. + Caller must provide headroom in an initial fragment added to the + network buffer to store a HTC_FRAME_HDR. + This interface is fully asynchronous. On error, HTCSendDataPkt will + call the registered Endpoint EpDataTxComplete callback to cleanup + the packet. + @example: + @see also: HTCSendPkt ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#ifdef ATH_11AC_TXCOMPACT +A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, adf_nbuf_t netbuf, + int Epid, int ActualLength); +#else /*ATH_11AC_TXCOMPACT*/ +A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket, + A_UINT8 more_data); +#endif /*ATH_11AC_TXCOMPACT*/ +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Flush HTC when target is removed surprisely service communications + @function name: HTCFlushSurpriseRemove + @input: HTCHandle - HTC handle + @output: + @return: + @notes: All receive and pending TX packets will + be flushed. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCFlushSurpriseRemove(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Stop HTC service communications + @function name: HTCStop + @input: HTCHandle - HTC handle + @output: + @return: + @notes: HTC communications is halted. All receive and pending TX packets will + be flushed. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCStop(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Destory HTC service + @function name: HTCDestroy + @input: HTCHandle + @output: + @return: + @notes: This cleans up all resources allocated by HTCCreate(). + @example: + @see also: HTCCreate ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCDestroy(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Flush pending TX packets + @function name: HTCFlushEndpoint + @input: HTCHandle - HTC handle + Endpoint - Endpoint to flush + Tag - flush tag + @output: + @return: + @notes: The Tag parameter is used to selectively flush packets with matching tags. + The value of 0 forces all packets to be flush regardless of tag. + @example: + @see also: HTCSendPkt ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Dump credit distribution state + @function name: HTCDumpCreditStates + @input: HTCHandle - HTC handle + @output: + @return: + @notes: This dumps all credit distribution information to the debugger + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCDumpCreditStates(HTC_HANDLE HTCHandle); +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Indicate a traffic activity change on an endpoint + @function name: HTCIndicateActivityChange + @input: HTCHandle - HTC handle + Endpoint - endpoint in which activity has changed + Active - TRUE if active, FALSE if it has become inactive + @output: + @return: + @notes: This triggers the registered credit distribution function to + re-adjust credits for active/inactive endpoints. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint, + A_BOOL Active); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Get endpoint statistics + @function name: HTCGetEndpointStatistics + @input: HTCHandle - HTC handle + Endpoint - Endpoint identifier + Action - action to take with statistics + @output: + pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR) + + @return: TRUE if statistics profiling is enabled, otherwise FALSE. + + @notes: Statistics is a compile-time option and this function may return FALSE + if HTC is not compiled with profiling. + + The caller can specify the statistic "action" to take when sampling + the statistics. This includes: + + HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values. + HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics + are cleared. + HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for + pStats + + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint, + HTC_ENDPOINT_STAT_ACTION Action, + HTC_ENDPOINT_STATS *pStats); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Unblock HTC message reception + @function name: HTCUnblockRecv + @input: HTCHandle - HTC handle + @output: + @return: + @notes: + HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet. + The caller can use this API to indicate to HTC when resources (buffers) are available + such that the receiver can be unblocked and HTC may re-attempt fetching the pending message. + + This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket() + API to recycle or provide receive packets to HTC. + + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCUnblockRecv(HTC_HANDLE HTCHandle); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: send a series of HTC packets + @function name: HTCSendPktsMultiple + @input: HTCHandle - HTC handle + pPktQueue - local queue holding packets to send + @output: + @return: A_OK + @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro. + The queue must only contain packets directed at the same endpoint. + Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the TX packets in FIFO order. + This API will remove the packets from the pkt queue and place them into the HTC Tx Queue + and bundle messages where possible. + The caller may allocate the pkt queue on the stack to hold the packets. + This interface is fully asynchronous. On error, HTCSendPkts will + call the registered Endpoint callback to cleanup the packet. + @example: + @see also: HTCFlushEndpoint ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Add multiple receive packets to HTC + @function name: HTCAddReceivePktMultiple + @input: HTCHandle - HTC handle + pPktQueue - HTC receive packet queue holding packets to add + @output: + @return: A_OK on success + @notes: user must supply HTC packets for capturing incomming HTC frames. The caller + must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() + macro. The queue must only contain recv packets for the same endpoint. + Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the recv packet. + This API will remove the packets from the pkt queue and place them into internal + recv packet list. + The caller may allocate the pkt queue on the stack to hold the packets. + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Check if an endpoint is marked active + @function name: HTCIsEndpointActive + @input: HTCHandle - HTC handle + Endpoint - endpoint to check for active state + @output: + @return: returns TRUE if Endpoint is Active + @notes: + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint); + + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Get the number of recv buffers currently queued into an HTC endpoint + @function name: HTCGetNumRecvBuffers + @input: HTCHandle - HTC handle + Endpoint - endpoint to check + @output: + @return: returns number of buffers in queue + @notes: + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint); + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @desc: Set the target failure handling callback in HTC layer + @function name: HTCSetTargetFailureCallback + @input: HTCHandle - HTC handle + Callback - target failure handling callback + @output: + @return: + @notes: + @example: + @see also: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +void HTCSetTargetFailureCallback(HTC_HANDLE HTCHandle, + HTC_TARGET_FAILURE Callback); + +/* internally used functions for testing... */ +void HTCEnableRecv(HTC_HANDLE HTCHandle); +void HTCDisableRecv(HTC_HANDLE HTCHandle); +A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, + A_UINT32 TimeoutInMs, + A_BOOL *pbIsRecvPending); + +/* function to fetch stats from htc layer*/ +struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE HTCHandle); + +#ifdef HIF_USB +#define HTCReturnReceivePkt(target,p,osbuf) \ + A_NETBUF_FREE(osbuf); \ + if(p->Status == A_CLONE) { \ + A_FREE(p); \ + } +#else +#define HTCReturnReceivePkt(target,p,osbuf) HTCAddReceivePkt(target,p) +#endif + +#ifdef __cplusplus +} +#endif + +void HTCGetControlEndpointTxHostCredits(HTC_HANDLE HTCHandle, int *credit); +void HTC_dump_counter_info(HTC_HANDLE HTCHandle); +void *htc_get_targetdef(HTC_HANDLE htc_handle); +void HTCSetTargetToSleep(void *context); +void HTCCancelDeferredTargetSleep(void *context); + +/* Disable ASPM : Disable PCIe low power */ +void htc_disable_aspm(void); + +#ifdef IPA_UC_OFFLOAD +void HTCIpaGetCEResource(HTC_HANDLE htc_handle, + a_uint32_t *ce_sr_base_paddr, + a_uint32_t *ce_sr_ring_size, + a_uint32_t *ce_reg_paddr); +#endif/* IPA_UC_OFFLOAD */ +#endif /* _HTC_API_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_packet.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_packet.h new file mode 100644 index 0000000000000..2530f9ddda7ef --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_packet.h @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HTC_PACKET_H_ +#define HTC_PACKET_H_ + +#include +#include /* A_UINT16, etc. */ +#include "dl_list.h" + +/* ------ Endpoint IDS ------ */ +typedef enum +{ + ENDPOINT_UNUSED = -1, + ENDPOINT_0 = 0, + ENDPOINT_1 = 1, + ENDPOINT_2 = 2, + ENDPOINT_3, + ENDPOINT_4, + ENDPOINT_5, + ENDPOINT_6, + ENDPOINT_7, + ENDPOINT_8, + ENDPOINT_MAX, +} HTC_ENDPOINT_ID; + +struct _HTC_PACKET; + +typedef void (* HTC_PACKET_COMPLETION)(void *,struct _HTC_PACKET *); + +typedef A_UINT16 HTC_TX_TAG; + +typedef struct _HTC_TX_PACKET_INFO { + HTC_TX_TAG Tag; /* tag used to selective flush packets */ + int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */ + A_UINT8 SendFlags; /* send flags (HTC internal) */ + int SeqNo; /* internal seq no for debugging (HTC internal) */ + A_UINT32 Flags; /* internal use */ +} HTC_TX_PACKET_INFO; + +#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */ +#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */ +#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */ +#define HTC_TX_PACKET_TAG_BUNDLED HTC_TX_PACKET_TAG_USER_DEFINED + 1 /* indicate this is bundled TX packet */ + +#define HTC_TX_PACKET_FLAG_FIXUP_NETBUF (1 << 0) + +typedef struct _HTC_RX_PACKET_INFO { + A_UINT32 ExpectedHdr; /* HTC internal use */ + A_UINT32 HTCRxFlags; /* HTC internal use */ + A_UINT32 IndicationFlags; /* indication flags set on each RX packet indication */ +} HTC_RX_PACKET_INFO; + +#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */ + +/* wrapper around endpoint-specific packets */ +typedef struct _HTC_PACKET { + DL_LIST ListLink; /* double link */ + void *pPktContext; /* caller's per packet specific context */ + + A_UINT8 *pBufferStart; /* the true buffer start , the caller can + store the real buffer start here. In + receive callbacks, the HTC layer sets pBuffer + to the start of the payload past the header. This + field allows the caller to reset pBuffer when it + recycles receive packets back to HTC */ + /* + * Pointer to the start of the buffer. In the transmit + * direction this points to the start of the payload. In the + * receive direction, however, the buffer when queued up + * points to the start of the HTC header but when returned + * to the caller points to the start of the payload + */ + A_UINT8 *pBuffer; /* payload start (RX/TX) */ + A_UINT32 BufferLength; /* length of buffer */ + A_UINT32 ActualLength; /* actual length of payload */ + HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ + A_STATUS Status; /* completion status */ + union { + HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */ + HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */ + } PktInfo; + + /* the following fields are for internal HTC use */ + A_UINT32 netbufOrigHeadRoom; + HTC_PACKET_COMPLETION Completion; /* completion */ + void *pContext; /* HTC private completion context */ + void *pNetBufContext; /* optimization for network-oriented data, the HTC packet + can pass the network buffer corresponding to the HTC packet + lower layers may optimized the transfer knowing this is + a network buffer */ +} HTC_PACKET; + + + +#define COMPLETE_HTC_PACKET(p,status) \ +{ \ + (p)->Status = (status); \ + (p)->Completion((p)->pContext,(p)); \ +} + +#define INIT_HTC_PACKET_INFO(p,b,len) \ +{ \ + (p)->pBufferStart = (b); \ + (p)->BufferLength = (len); \ +} + +/* macro to set an initial RX packet for refilling HTC */ +#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \ +{ \ + (p)->pPktContext = (c); \ + (p)->pBuffer = (b); \ + (p)->pBufferStart = (b); \ + (p)->BufferLength = (len); \ + (p)->Endpoint = (ep); \ +} + +/* fast macro to recycle an RX packet that will be re-queued to HTC */ +#define HTC_PACKET_RESET_RX(p) \ + { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; } + +/* macro to set packet parameters for TX */ +#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \ +{ \ + (p)->pPktContext = (c); \ + (p)->pBuffer = (b); \ + (p)->ActualLength = (len); \ + (p)->Endpoint = (ep); \ + (p)->PktInfo.AsTx.Tag = (tag); \ + (p)->PktInfo.AsTx.Flags = 0; \ +} + +#define SET_HTC_PACKET_NET_BUF_CONTEXT(p,nb) \ + (p)->pNetBufContext = (nb) + +#define GET_HTC_PACKET_NET_BUF_CONTEXT(p) (p)->pNetBufContext + +/* HTC Packet Queueing Macros */ +typedef struct _HTC_PACKET_QUEUE { + DL_LIST QueueHead; + int Depth; +} HTC_PACKET_QUEUE; + +/* initialize queue */ +#define INIT_HTC_PACKET_QUEUE(pQ) \ +{ \ + DL_LIST_INIT(&(pQ)->QueueHead); \ + (pQ)->Depth = 0; \ +} + +/* enqueue HTC packet to the tail of the queue */ +#define HTC_PACKET_ENQUEUE(pQ,p) \ +{ DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \ + (pQ)->Depth++; \ +} + +/* enqueue HTC packet to the tail of the queue */ +#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p) \ +{ DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \ + (pQ)->Depth++; \ +} +/* test if a queue is empty */ +#define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0) +/* get packet at head without removing it */ +static INLINE HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { + if (queue->Depth == 0) { + return NULL; + } + return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),HTC_PACKET,ListLink); +} +/* remove a packet from a queue, where-ever it is in the queue */ +#define HTC_PACKET_REMOVE(pQ,p) \ +{ \ + DL_ListRemove(&(p)->ListLink); \ + (pQ)->Depth--; \ +} + +/* dequeue an HTC packet from the head of the queue */ +static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { + DL_LIST *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); + if (pItem != NULL) { + queue->Depth--; + return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); + } + return NULL; +} + +/* dequeue an HTC packet from the tail of the queue */ +static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { + DL_LIST *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); + if (pItem != NULL) { + queue->Depth--; + return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); + } + return NULL; +} + +#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth + + +#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint +#define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag + + /* transfer the packets from one queue to the tail of another queue */ +#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \ +{ \ + DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \ + (pQDest)->Depth += (pQSrc)->Depth; \ + (pQSrc)->Depth = 0; \ +} + +/* + * Transfer the packets from one queue to the head of another queue. + * This xfer_to_head(q1,q2) is basically equivalent to xfer_to_tail(q2,q1), + * but it updates the queue descriptor object for the initial queue to refer + * to the concatenated queue. + */ +#define HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(pQDest, pQSrc) \ +{ \ + DL_ListTransferItemsToHead(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \ + (pQDest)->Depth += (pQSrc)->Depth; \ + (pQSrc)->Depth = 0; \ +} + + /* fast version to init and add a single packet to a queue */ +#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \ +{ \ + DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink) \ + (pQ)->Depth = 1; \ +} + +#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \ + ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), HTC_PACKET, ListLink) + +#define HTC_PACKET_QUEUE_ITERATE_IS_VALID(pQ) ITERATE_IS_VALID(&(pQ)->QueueHead) +#define HTC_PACKET_QUEUE_ITERATE_RESET(pQ) ITERATE_RESET(&(pQ)->QueueHead) + +#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END + +#endif /*HTC_PACKET_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_services.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_services.h new file mode 100644 index 0000000000000..73062f3fdcbde --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/htc_services.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2007 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __HTC_SERVICES_H__ +#define __HTC_SERVICES_H__ + +/* Current service IDs */ + +typedef enum { + RSVD_SERVICE_GROUP = 0, + WMI_SERVICE_GROUP = 1, + NMI_SERVICE_GROUP = 2, + HTT_SERVICE_GROUP = 3, + CFG_NV_SERVICE_GROUP = 4, +#ifdef IPA_UC_OFFLOAD + WDI_IPA_SERVICE_GROUP = 5, +#endif /* IPA_UC_OFFLOAD */ + HTC_TEST_GROUP = 254, + HTC_SERVICE_GROUP_LAST = 255 +}HTC_SERVICE_GROUP_IDS; + +#define MAKE_SERVICE_ID(group,index) \ + (int)(((int)group << 8) | (int)(index)) + +/* NOTE: service ID of 0x0000 is reserved and should never be used */ +#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1) +#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0) +#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1) +#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2) +#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3) +#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4) +#define WMI_MAX_SERVICES 5 + +#define NMI_CONTROL_SVC MAKE_SERVICE_ID(NMI_SERVICE_GROUP,0) +#define NMI_DATA_SVC MAKE_SERVICE_ID(NMI_SERVICE_GROUP,1) + +#define HTT_DATA_MSG_SVC MAKE_SERVICE_ID(HTT_SERVICE_GROUP,0) +#define HTT_DATA2_MSG_SVC MAKE_SERVICE_ID(HTT_SERVICE_GROUP,1) + +/* raw stream service (i.e. flash, tcmd, calibration apps) */ +#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0) + +#define CFG_NV_SVC MAKE_SERVICE_ID(CFG_NV_SERVICE_GROUP,0) +#ifdef IPA_UC_OFFLOAD +#define WDI_IPA_TX_SVC MAKE_SERVICE_ID(WDI_IPA_SERVICE_GROUP,0) +#endif /* IPA_UC_OFFLOAD */ +/* + * Directions for interconnect pipe configuration. + * These definitions may be used during configuration and are shared + * between Host and Target. + * + * Pipe Directions are relative to the Host, so PIPEDIR_IN means + * "coming IN over air through Target to Host" as with a WiFi Rx operation. + * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air" + * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man" + * Target since things that are "PIPEDIR_OUT" are coming IN to the Target + * over the interconnect. + */ +typedef A_UINT32 PIPEDIR; +#define PIPEDIR_NONE 0 +#define PIPEDIR_IN 1 /* Target-->Host, WiFi Rx direction */ +#define PIPEDIR_OUT 2 /* Host->Target, WiFi Tx direction */ +#define PIPEDIR_INOUT 3 /* bidirectional */ +#define PIPEDIR_MATCH(d1, d2) (((PIPEDIR)(d1) & (PIPEDIR)(d2)) != 0) + +/* Establish a mapping between a service/direction and a pipe. */ +struct service_to_pipe { + A_UINT32 service_id; + A_UINT32 pipedir; + A_UINT32 pipenum; +}; + + +#endif /*HTC_SERVICES_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hwdef.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hwdef.h new file mode 100644 index 0000000000000..9aacae9c88d6f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hwdef.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _HW_DEF_H +#define _HW_DEF_H + +/* + * Atheros-specific + */ +typedef enum { + ANTENNA_CONTROLLABLE, + ANTENNA_FIXED_A, + ANTENNA_FIXED_B, + ANTENNA_DUMMY_MAX +} ANTENNA_CONTROL; + +/* + * Number of (OEM-defined) functions using GPIO pins currently defined + * + * Function 0: Link/Power LED + * Function 1: Network/Activity LED + * Function 2: Connection LED + */ +#define NUM_GPIO_FUNCS 3 + +/* +** Default cache line size, in bytes. +** Used when PCI device not fully initialized by bootrom/BIOS +*/ + +#define DEFAULT_CACHELINE 32 + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_common.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_common.h new file mode 100644 index 0000000000000..fd9692bfe5e74 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_common.h @@ -0,0 +1,2235 @@ +/* + * Copyright (c) 2011,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#ifndef EXTERNAL_USE_ONLY +#include "osdep.h" +#endif /* EXTERNAL_USE_ONLY */ +#include "_ieee80211_common.h" + +#ifndef _COMMON_IEEE80211_H_ +#define _COMMON_IEEE80211_H_ + +/* + * 802.11 protocol definitions. + */ + +/* is 802.11 address multicast/broadcast? */ +#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) + +#define IEEE80211_IS_IPV4_MULTICAST(_a) (*(_a) == 0x01) + +#define IEEE80211_IS_IPV6_MULTICAST(_a) \ + ((_a)[0] == 0x33 && \ + (_a)[1] == 0x33) + + +#define IEEE80211_IS_BROADCAST(_a) \ + ((_a)[0] == 0xff && \ + (_a)[1] == 0xff && \ + (_a)[2] == 0xff && \ + (_a)[3] == 0xff && \ + (_a)[4] == 0xff && \ + (_a)[5] == 0xff) + +/* IEEE 802.11 PLCP header */ +struct ieee80211_plcp_hdr { + u_int16_t i_sfd; + u_int8_t i_signal; + u_int8_t i_service; + u_int16_t i_length; + u_int16_t i_crc; +} __packed; + +#define IEEE80211_PLCP_SFD 0xF3A0 +#define IEEE80211_PLCP_SERVICE 0x00 + +/* + * generic definitions for IEEE 802.11 frames + */ +struct ieee80211_frame { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + union { + struct { + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + }; + u_int8_t i_addr_all[3 * IEEE80211_ADDR_LEN]; + }; + u_int8_t i_seq[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} __packed; + +struct ieee80211_qosframe { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_qos[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} __packed; + +struct ieee80211_qoscntl { + u_int8_t i_qos[2]; +}; + +struct ieee80211_frame_addr4 { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_addr4[IEEE80211_ADDR_LEN]; +} __packed; + +struct ieee80211_qosframe_addr4 { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_addr4[IEEE80211_ADDR_LEN]; + u_int8_t i_qos[2]; +} __packed; + +/* HTC frame for TxBF*/ +// for TxBF RC +struct ieee80211_frame_min_one { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + +} __packed;// For TxBF RC + +struct ieee80211_qosframe_htc { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_qos[2]; + u_int8_t i_htc[4]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} __packed; +struct ieee80211_qosframe_htc_addr4 { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + u_int8_t i_addr4[IEEE80211_ADDR_LEN]; + u_int8_t i_qos[2]; + u_int8_t i_htc[4]; +} __packed; +struct ieee80211_htc { + u_int8_t i_htc[4]; +}; +/*HTC frame for TxBF*/ + +struct ieee80211_ctlframe_addr2 { + u_int8_t i_fc[2]; + u_int8_t i_aidordur[2]; /* AID or duration */ + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; +} __packed; + +#define IEEE80211_WHQ(wh) ((struct ieee80211_qosframe *)(wh)) +#define IEEE80211_WH4(wh) ((struct ieee80211_frame_addr4 *)(wh)) +#define IEEE80211_WHQ4(wh) ((struct ieee80211_qosframe_addr4 *)(wh)) + +#define IEEE80211_FC0_VERSION_MASK 0x03 +#define IEEE80211_FC0_VERSION_SHIFT 0 +#define IEEE80211_FC0_VERSION_0 0x00 +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_SHIFT 2 +#define IEEE80211_FC0_TYPE_MGT 0x00 +#define IEEE80211_FC0_TYPE_CTL 0x04 +#define IEEE80211_FC0_TYPE_DATA 0x08 + +#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 +#define IEEE80211_FC0_SUBTYPE_SHIFT 4 +/* for TYPE_MGT */ +#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 +#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 +#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 +#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 +#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 +#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 +#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 +#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 +#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 +#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 +#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 +#define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 +#define IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK 0xe0 +/* for TYPE_CTL */ +#define IEEE80211_FCO_SUBTYPE_Control_Wrapper 0x70 // For TxBF RC +#define IEEE80211_FC0_SUBTYPE_BAR 0x80 +#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 +#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 +#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 +#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 +#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 +#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 +/* for TYPE_DATA (bit combination) */ +#define IEEE80211_FC0_SUBTYPE_DATA 0x00 +#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 +#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 +#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 +#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 +#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 +#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 +#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 + +#define IEEE80211_FC1_DIR_MASK 0x03 +#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ +#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ +#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ +#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ + +#define IEEE80211_FC1_MORE_FRAG 0x04 +#define IEEE80211_FC1_RETRY 0x08 +#define IEEE80211_FC1_PWR_MGT 0x10 +#define IEEE80211_FC1_MORE_DATA 0x20 +#define IEEE80211_FC1_WEP 0x40 +#define IEEE80211_FC1_ORDER 0x80 + +#define IEEE80211_SEQ_FRAG_MASK 0x000f +#define IEEE80211_SEQ_FRAG_SHIFT 0 +#define IEEE80211_SEQ_SEQ_MASK 0xfff0 +#define IEEE80211_SEQ_SEQ_SHIFT 4 +#define IEEE80211_SEQ_MAX 4096 + +#define IEEE80211_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) + + +#define IEEE80211_QOS_TXOP 0x00ff + +#define IEEE80211_QOS_AMSDU 0x80 +#define IEEE80211_QOS_AMSDU_S 7 +#define IEEE80211_QOS_ACKPOLICY 0x60 +#define IEEE80211_QOS_ACKPOLICY_S 5 +#define IEEE80211_QOS_EOSP 0x10 +#define IEEE80211_QOS_EOSP_S 4 +#define IEEE80211_QOS_TID 0x0f +#define IEEE80211_MFP_TID 0xff + +#define IEEE80211_HTC0_TRQ 0x02 +#define IEEE80211_HTC2_CalPos 0x03 +#define IEEE80211_HTC2_CalSeq 0x0C +#define IEEE80211_HTC2_CSI_NONCOMP_BF 0x80 +#define IEEE80211_HTC2_CSI_COMP_BF 0xc0 + +/* Set bits 14 and 15 to 1 when duration field carries Association ID */ +#define IEEE80211_FIELD_TYPE_AID 0xC000 + +#define IEEE80211_IS_BEACON(_frame) ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \ + (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_BEACON)) +#define IEEE80211_IS_DATA(_frame) (((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) + +#define IEEE80211_IS_MFP_FRAME(_frame) ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \ + ((_frame)->i_fc[1] & IEEE80211_FC1_WEP) && \ + ((((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_DEAUTH) || \ + (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_DISASSOC) || \ + (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_ACTION))) +#define IEEE80211_IS_AUTH(_frame) ((((_frame)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) && \ + (((_frame)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_AUTH)) + +/* MCS Set */ +#define IEEE80211_RX_MCS_1_STREAM_BYTE_OFFSET 0 +#define IEEE80211_RX_MCS_2_STREAM_BYTE_OFFSET 1 +#define IEEE80211_RX_MCS_3_STREAM_BYTE_OFFSET 2 +#define IEEE80211_RX_MCS_ALL_NSTREAM_RATES 0xff +#define IEEE80211_TX_MCS_OFFSET 12 + +#define IEEE80211_TX_MCS_SET_DEFINED 0x80 +#define IEEE80211_TX_RX_MCS_SET_NOT_EQUAL 0x40 +#define IEEE80211_TX_1_SPATIAL_STREAMS 0x0 +#define IEEE80211_TX_2_SPATIAL_STREAMS 0x10 +#define IEEE80211_TX_3_SPATIAL_STREAMS 0x20 +#define IEEE80211_TX_4_SPATIAL_STREAMS 0x30 + +#define IEEE80211_TX_MCS_SET 0xf8 + +/* + * Subtype data: If bit 6 is set then the data frame contains no actual data. + */ +#define IEEE80211_FC0_SUBTYPE_NO_DATA_MASK 0x40 +#define IEEE80211_CONTAIN_DATA(_subtype) \ + (! ((_subtype) & IEEE80211_FC0_SUBTYPE_NO_DATA_MASK)) + +#define IEEE8023_MAX_LEN 0x600 /* 1536 - larger is Ethernet II */ +#define RFC1042_SNAP_ORGCODE_0 0x00 +#define RFC1042_SNAP_ORGCODE_1 0x00 +#define RFC1042_SNAP_ORGCODE_2 0x00 + +#define BTEP_SNAP_ORGCODE_0 0x00 +#define BTEP_SNAP_ORGCODE_1 0x00 +#define BTEP_SNAP_ORGCODE_2 0xf8 + +/* BT 3.0 */ +#define BTAMP_SNAP_ORGCODE_0 0x00 +#define BTAMP_SNAP_ORGCODE_1 0x19 +#define BTAMP_SNAP_ORGCODE_2 0x58 + +/* Aironet OUI Codes */ +#define AIRONET_SNAP_CODE_0 0x00 +#define AIRONET_SNAP_CODE_1 0x40 +#define AIRONET_SNAP_CODE_2 0x96 + +#define IEEE80211_LSIG_LEN 3 +#define IEEE80211_HTSIG_LEN 6 +#define IEEE80211_SB_LEN 2 + +/* + * Information element header format + */ +struct ieee80211_ie_header { + u_int8_t element_id; /* Element Id */ + u_int8_t length; /* IE Length */ +} __packed; + +/* + * Country information element. + */ +#define IEEE80211_COUNTRY_MAX_TRIPLETS (83) +struct ieee80211_ie_country { + u_int8_t country_id; + u_int8_t country_len; + u_int8_t country_str[3]; + u_int8_t country_triplet[IEEE80211_COUNTRY_MAX_TRIPLETS*3]; +} __packed; + +/* does frame have QoS sequence control data */ +#define IEEE80211_QOS_HAS_SEQ(wh) \ + (((wh)->i_fc[0] & \ + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \ + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) + +#define WME_QOSINFO_UAPSD 0x80 /* Mask for U-APSD field */ +#define WME_QOSINFO_COUNT 0x0f /* Mask for Param Set Count field */ +/* + * WME/802.11e information element. + */ +struct ieee80211_ie_wme { + u_int8_t wme_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t wme_len; /* length in bytes */ + u_int8_t wme_oui[3]; /* 0x00, 0x50, 0xf2 */ + u_int8_t wme_type; /* OUI type */ + u_int8_t wme_subtype; /* OUI subtype */ + u_int8_t wme_version; /* spec revision */ + u_int8_t wme_info; /* QoS info */ +} __packed; + +/* + * TS INFO part of the tspec element is a collection of bit flags + */ +#if _BYTE_ORDER == _BIG_ENDIAN +struct ieee80211_tsinfo_bitmap { + u_int8_t one : 1, + direction : 2, + tid : 4, + reserved1 : 1; + u_int8_t reserved2 : 2, + dot1Dtag : 3, + psb : 1, + reserved3 : 1, + zero : 1; + u_int8_t reserved5 : 7, + reserved4 : 1; +} __packed; +#else +struct ieee80211_tsinfo_bitmap { + u_int8_t reserved1 : 1, + tid : 4, + direction : 2, + one : 1; + u_int8_t zero : 1, + reserved3 : 1, + psb : 1, + dot1Dtag : 3, + reserved2 : 2; + u_int8_t reserved4 : 1, + reserved5 : 7; +} __packed; +#endif + +/* + * WME/802.11e Tspec Element + */ +struct ieee80211_wme_tspec { + u_int8_t ts_id; + u_int8_t ts_len; + u_int8_t ts_oui[3]; + u_int8_t ts_oui_type; + u_int8_t ts_oui_subtype; + u_int8_t ts_version; + u_int8_t ts_tsinfo[3]; + u_int8_t ts_nom_msdu[2]; + u_int8_t ts_max_msdu[2]; + u_int8_t ts_min_svc[4]; + u_int8_t ts_max_svc[4]; + u_int8_t ts_inactv_intv[4]; + u_int8_t ts_susp_intv[4]; + u_int8_t ts_start_svc[4]; + u_int8_t ts_min_rate[4]; + u_int8_t ts_mean_rate[4]; + u_int8_t ts_peak_rate[4]; + u_int8_t ts_max_burst[4]; + u_int8_t ts_delay[4]; + u_int8_t ts_min_phy[4]; + u_int8_t ts_surplus[2]; + u_int8_t ts_medium_time[2]; +} __packed; + +/* + * WME AC parameter field + */ +struct ieee80211_wme_acparams { + u_int8_t acp_aci_aifsn; + u_int8_t acp_logcwminmax; + u_int16_t acp_txop; +} __packed; + +#define IEEE80211_WME_PARAM_LEN 24 +#define WME_NUM_AC 4 /* 4 AC categories */ + +#define WME_PARAM_ACI 0x60 /* Mask for ACI field */ +#define WME_PARAM_ACI_S 5 /* Shift for ACI field */ +#define WME_PARAM_ACM 0x10 /* Mask for ACM bit */ +#define WME_PARAM_ACM_S 4 /* Shift for ACM bit */ +#define WME_PARAM_AIFSN 0x0f /* Mask for aifsn field */ +#define WME_PARAM_AIFSN_S 0 /* Shift for aifsn field */ +#define WME_PARAM_LOGCWMIN 0x0f /* Mask for CwMin field (in log) */ +#define WME_PARAM_LOGCWMIN_S 0 /* Shift for CwMin field */ +#define WME_PARAM_LOGCWMAX 0xf0 /* Mask for CwMax field (in log) */ +#define WME_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ + +#define WME_AC_TO_TID(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define TID_TO_WME_AC(_tid) ( \ + (((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ + (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ + (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ + WME_AC_VO) + +/* + * WME Parameter Element + */ +struct ieee80211_wme_param { + u_int8_t param_id; + u_int8_t param_len; + u_int8_t param_oui[3]; + u_int8_t param_oui_type; + u_int8_t param_oui_sybtype; + u_int8_t param_version; + u_int8_t param_qosInfo; + u_int8_t param_reserved; + struct ieee80211_wme_acparams params_acParams[WME_NUM_AC]; +} __packed; + +/* + * WME U-APSD qos info field defines + */ +#define WME_CAPINFO_UAPSD_EN 0x00000080 +#define WME_CAPINFO_UAPSD_VO 0x00000001 +#define WME_CAPINFO_UAPSD_VI 0x00000002 +#define WME_CAPINFO_UAPSD_BK 0x00000004 +#define WME_CAPINFO_UAPSD_BE 0x00000008 +#define WME_CAPINFO_UAPSD_ACFLAGS_SHIFT 0 +#define WME_CAPINFO_UAPSD_ACFLAGS_MASK 0xF +#define WME_CAPINFO_UAPSD_MAXSP_SHIFT 5 +#define WME_CAPINFO_UAPSD_MAXSP_MASK 0x3 +#define WME_CAPINFO_IE_OFFSET 8 +#define WME_UAPSD_MAXSP(_qosinfo) (((_qosinfo) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT) & WME_CAPINFO_UAPSD_MAXSP_MASK) +#define WME_UAPSD_AC_ENABLED(_ac, _qosinfo) ( (1<<(3 - (_ac))) & \ + (((_qosinfo) >> WME_CAPINFO_UAPSD_ACFLAGS_SHIFT) & WME_CAPINFO_UAPSD_ACFLAGS_MASK) ) + +/* Mask used to determined whether all queues are UAPSD-enabled */ +#define WME_CAPINFO_UAPSD_ALL (WME_CAPINFO_UAPSD_VO | \ + WME_CAPINFO_UAPSD_VI | \ + WME_CAPINFO_UAPSD_BK | \ + WME_CAPINFO_UAPSD_BE) +#define WME_CAPINFO_UAPSD_NONE 0 + +#define WME_UAPSD_AC_MAX_VAL 1 +#define WME_UAPSD_AC_INVAL WME_UAPSD_AC_MAX_VAL+1 + +/* + * Atheros Advanced Capability information element. + */ +struct ieee80211_ie_athAdvCap { + u_int8_t athAdvCap_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t athAdvCap_len; /* length in bytes */ + u_int8_t athAdvCap_oui[3]; /* 0x00, 0x03, 0x7f */ + u_int8_t athAdvCap_type; /* OUI type */ + u_int16_t athAdvCap_version; /* spec revision */ + u_int8_t athAdvCap_capability; /* Capability info */ + u_int16_t athAdvCap_defKeyIndex; +} __packed; + +/* + * Atheros Extended Capability information element. + */ +struct ieee80211_ie_ath_extcap { + u_int8_t ath_extcap_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t ath_extcap_len; /* length in bytes */ + u_int8_t ath_extcap_oui[3]; /* 0x00, 0x03, 0x7f */ + u_int8_t ath_extcap_type; /* OUI type */ + u_int8_t ath_extcap_subtype; /* OUI subtype */ + u_int8_t ath_extcap_version; /* spec revision */ + u_int32_t ath_extcap_extcap : 16, /* B0-15 extended capabilities */ + ath_extcap_weptkipaggr_rxdelim : 8, /* B16-23 num delimiters for receiving WEP/TKIP aggregates */ + ath_extcap_reserved : 8; /* B24-31 reserved */ +} __packed; + +/* + * Atheros XR information element. + */ +struct ieee80211_xr_param { + u_int8_t param_id; + u_int8_t param_len; + u_int8_t param_oui[3]; + u_int8_t param_oui_type; + u_int8_t param_oui_sybtype; + u_int8_t param_version; + u_int8_t param_Info; + u_int8_t param_base_bssid[IEEE80211_ADDR_LEN]; + u_int8_t param_xr_bssid[IEEE80211_ADDR_LEN]; + u_int16_t param_xr_beacon_interval; + u_int8_t param_base_ath_capability; + u_int8_t param_xr_ath_capability; +} __packed; + +/* + * SFA information element. + */ +struct ieee80211_ie_sfa { + u_int8_t sfa_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t sfa_len; /* length in bytes */ + u_int8_t sfa_oui[3]; /* 0x00, 0x40, 0x96 */ + u_int8_t sfa_type; /* OUI type */ + u_int8_t sfa_caps; /* Capabilities */ +} __packed; + +/* Atheros capabilities */ +#define IEEE80211_ATHC_TURBOP 0x0001 /* Turbo Prime */ +#define IEEE80211_ATHC_COMP 0x0002 /* Compression */ +#define IEEE80211_ATHC_FF 0x0004 /* Fast Frames */ +#define IEEE80211_ATHC_XR 0x0008 /* Xtended Range support */ +#define IEEE80211_ATHC_AR 0x0010 /* Advanced Radar support */ +#define IEEE80211_ATHC_BURST 0x0020 /* Bursting - not negotiated */ +#define IEEE80211_ATHC_WME 0x0040 /* CWMin tuning */ +#define IEEE80211_ATHC_BOOST 0x0080 /* Boost */ +#define IEEE80211_ATHC_TDLS 0x0100 /* TDLS */ + +/* Atheros extended capabilities */ +/* OWL device capable of WDS workaround */ +#define IEEE80211_ATHEC_OWLWDSWAR 0x0001 +#define IEEE80211_ATHEC_WEPTKIPAGGR 0x0002 +#define IEEE80211_ATHEC_EXTRADELIMWAR 0x0004 +/* + * Management Frames + */ + +/* + * *** Platform-specific code?? *** + * In Vista one must use bit fields of type (unsigned short = u_int16_t) to + * ensure data structure is of the correct size. ANSI C used to specify only + * "int" bit fields, which led to a larger structure size in Windows (32 bits). + * + * We must make sure the following construction is valid in all OS's. + */ +union ieee80211_capability { + struct { + u_int16_t ess : 1; + u_int16_t ibss : 1; + u_int16_t cf_pollable : 1; + u_int16_t cf_poll_request : 1; + u_int16_t privacy : 1; + u_int16_t short_preamble : 1; + u_int16_t pbcc : 1; + u_int16_t channel_agility : 1; + u_int16_t spectrum_management : 1; + u_int16_t qos : 1; + u_int16_t short_slot_time : 1; + u_int16_t apsd : 1; + u_int16_t reserved2 : 1; + u_int16_t dsss_ofdm : 1; + u_int16_t del_block_ack : 1; + u_int16_t immed_block_ack : 1; + }; + + u_int16_t value; +} __packed; + +struct ieee80211_beacon_frame { + u_int8_t timestamp[8]; /* the value of sender's TSFTIMER */ + u_int16_t beacon_interval; /* the number of time units between target beacon transmission times */ + union ieee80211_capability capability; +/* Value of capability for every bit +#define IEEE80211_CAPINFO_ESS 0x0001 +#define IEEE80211_CAPINFO_IBSS 0x0002 +#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 +#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 +#define IEEE80211_CAPINFO_PRIVACY 0x0010 +#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 +#define IEEE80211_CAPINFO_PBCC 0x0040 +#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 +#define IEEE80211_CAPINFO_SPECTRUM_MGMT 0x0100 +#define IEEE80211_CAPINFO_QOS 0x0200 +#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 +#define IEEE80211_CAPINFO_APSD 0x0800 +#define IEEE80211_CAPINFO_RADIOMEAS 0x1000 +#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 +bits 14-15 are reserved +*/ + struct ieee80211_ie_header info_elements; +} __packed; + +/* + * Management Action Frames + */ + +/* generic frame format */ +struct ieee80211_action { + u_int8_t ia_category; + u_int8_t ia_action; +} __packed; + +/* spectrum action frame header */ +struct ieee80211_action_measrep_header { + struct ieee80211_action action_header; + u_int8_t dialog_token; +} __packed; + +/* categories */ +#define IEEE80211_ACTION_CAT_SPECTRUM 0 /* Spectrum management */ +#define IEEE80211_ACTION_CAT_QOS 1 /* IEEE QoS */ +#define IEEE80211_ACTION_CAT_DLS 2 /* DLS */ +#define IEEE80211_ACTION_CAT_BA 3 /* BA */ +#define IEEE80211_ACTION_CAT_PUBLIC 4 /* Public Action Frame */ +#define IEEE80211_ACTION_CAT_HT 7 /* HT per IEEE802.11n-D1.06 */ +#define IEEE80211_ACTION_CAT_SA_QUERY 8 /* SA Query per IEEE802.11w, PMF */ +#define IEEE80211_ACTION_CAT_WMM_QOS 17 /* QoS from WMM specification */ +#define IEEE80211_ACTION_CAT_VHT 21 /* VHT Action */ + +/* Spectrum Management actions */ +#define IEEE80211_ACTION_MEAS_REQUEST 0 /* Measure channels */ +#define IEEE80211_ACTION_MEAS_REPORT 1 +#define IEEE80211_ACTION_TPC_REQUEST 2 /* Transmit Power control */ +#define IEEE80211_ACTION_TPC_REPORT 3 +#define IEEE80211_ACTION_CHAN_SWITCH 4 /* 802.11h Channel Switch Announcement */ + +/* HT actions */ +#define IEEE80211_ACTION_HT_TXCHWIDTH 0 /* recommended transmission channel width */ +#define IEEE80211_ACTION_HT_SMPOWERSAVE 1 /* Spatial Multiplexing (SM) Power Save */ +#define IEEE80211_ACTION_HT_CSI 4 /* CSI Frame */ +#define IEEE80211_ACTION_HT_NONCOMP_BF 5 /* Non-compressed Beamforming*/ +#define IEEE80211_ACTION_HT_COMP_BF 6 /* Compressed Beamforming*/ + +/* VHT actions */ +#define IEEE80211_ACTION_VHT_OPMODE 2 /* Operating mode notification */ + +/* Spectrum channel switch action frame after IE*/ +/* Public Actions*/ +#define IEEE80211_ACTION_TDLS_DISCRESP 14 /* TDLS Discovery Response frame */ + +/* HT - recommended transmission channel width */ +struct ieee80211_action_ht_txchwidth { + struct ieee80211_action at_header; + u_int8_t at_chwidth; +} __packed; + +#define IEEE80211_A_HT_TXCHWIDTH_20 0 +#define IEEE80211_A_HT_TXCHWIDTH_2040 1 + +/* HT - Spatial Multiplexing (SM) Power Save */ +struct ieee80211_action_ht_smpowersave { + struct ieee80211_action as_header; + u_int8_t as_control; +} __packed; + +/*HT - CSI Frame */ //for TxBF RC +#define MIMO_CONTROL_LEN 6 +struct ieee80211_action_ht_CSI { + struct ieee80211_action as_header; + u_int8_t mimo_control[MIMO_CONTROL_LEN]; +} __packed; + +/*HT - V/CV report frame*/ +struct ieee80211_action_ht_txbf_rpt { + struct ieee80211_action as_header; + u_int8_t mimo_control[MIMO_CONTROL_LEN]; +} __packed; + +/* + * 802.11ac Operating Mode Notification + */ +struct ieee80211_ie_op_mode { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int8_t rx_nss_type : 1, + rx_nss : 3, + reserved : 2, + ch_width : 2; +#else + u_int8_t ch_width : 2, + reserved : 2, + rx_nss : 3, + rx_nss_type : 1; +#endif +} __packed; + +struct ieee80211_ie_op_mode_ntfy { + u_int8_t elem_id; + u_int8_t elem_len; + struct ieee80211_ie_op_mode opmode; +} __packed; + + +/* VHT - recommended Channel width and Nss */ +struct ieee80211_action_vht_opmode { + struct ieee80211_action at_header; + struct ieee80211_ie_op_mode at_op_mode; +} __packed; + +/* values defined for 'as_control' field per 802.11n-D1.06 */ +#define IEEE80211_A_HT_SMPOWERSAVE_DISABLED 0x00 /* SM Power Save Disabled, SM packets ok */ +#define IEEE80211_A_HT_SMPOWERSAVE_ENABLED 0x01 /* SM Power Save Enabled bit */ +#define IEEE80211_A_HT_SMPOWERSAVE_MODE 0x02 /* SM Power Save Mode bit */ +#define IEEE80211_A_HT_SMPOWERSAVE_RESERVED 0xFC /* SM Power Save Reserved bits */ + +/* values defined for SM Power Save Mode bit */ +#define IEEE80211_A_HT_SMPOWERSAVE_STATIC 0x00 /* Static, SM packets not ok */ +#define IEEE80211_A_HT_SMPOWERSAVE_DYNAMIC 0x02 /* Dynamic, SM packets ok if preceded by RTS */ + +/* DLS actions */ +#define IEEE80211_ACTION_DLS_REQUEST 0 +#define IEEE80211_ACTION_DLS_RESPONSE 1 +#define IEEE80211_ACTION_DLS_TEARDOWN 2 + +struct ieee80211_dls_request { + struct ieee80211_action hdr; + u_int8_t dst_addr[IEEE80211_ADDR_LEN]; + u_int8_t src_addr[IEEE80211_ADDR_LEN]; + u_int16_t capa_info; + u_int16_t timeout; +} __packed; + +struct ieee80211_dls_response { + struct ieee80211_action hdr; + u_int16_t statuscode; + u_int8_t dst_addr[IEEE80211_ADDR_LEN]; + u_int8_t src_addr[IEEE80211_ADDR_LEN]; +} __packed; + +/* BA actions */ +#define IEEE80211_ACTION_BA_ADDBA_REQUEST 0 /* ADDBA request */ +#define IEEE80211_ACTION_BA_ADDBA_RESPONSE 1 /* ADDBA response */ +#define IEEE80211_ACTION_BA_DELBA 2 /* DELBA */ + +struct ieee80211_ba_parameterset { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int16_t buffersize : 10, /* B6-15 buffer size */ + tid : 4, /* B2-5 TID */ + bapolicy : 1, /* B1 block ack policy */ + amsdusupported : 1; /* B0 amsdu supported */ +#else + u_int16_t amsdusupported : 1, /* B0 amsdu supported */ + bapolicy : 1, /* B1 block ack policy */ + tid : 4, /* B2-5 TID */ + buffersize : 10; /* B6-15 buffer size */ +#endif +} __packed; + +#define IEEE80211_BA_POLICY_DELAYED 0 +#define IEEE80211_BA_POLICY_IMMEDIATE 1 +#define IEEE80211_BA_AMSDU_SUPPORTED 1 + +struct ieee80211_ba_seqctrl { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int16_t startseqnum : 12, /* B4-15 starting sequence number */ + fragnum : 4; /* B0-3 fragment number */ +#else + u_int16_t fragnum : 4, /* B0-3 fragment number */ + startseqnum : 12; /* B4-15 starting sequence number */ +#endif +} __packed; + +struct ieee80211_delba_parameterset { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int16_t tid : 4, /* B12-15 tid */ + initiator : 1, /* B11 initiator */ + reserved0 : 11; /* B0-10 reserved */ +#else + u_int16_t reserved0 : 11, /* B0-10 reserved */ + initiator : 1, /* B11 initiator */ + tid : 4; /* B12-15 tid */ +#endif +} __packed; + +/* BA - ADDBA request */ +struct ieee80211_action_ba_addbarequest { + struct ieee80211_action rq_header; + u_int8_t rq_dialogtoken; + struct ieee80211_ba_parameterset rq_baparamset; + u_int16_t rq_batimeout; /* in TUs */ + struct ieee80211_ba_seqctrl rq_basequencectrl; +} __packed; + +/* BA - ADDBA response */ +struct ieee80211_action_ba_addbaresponse { + struct ieee80211_action rs_header; + u_int8_t rs_dialogtoken; + u_int16_t rs_statuscode; + struct ieee80211_ba_parameterset rs_baparamset; + u_int16_t rs_batimeout; /* in TUs */ +} __packed; + +/* BA - DELBA */ +struct ieee80211_action_ba_delba { + struct ieee80211_action dl_header; + struct ieee80211_delba_parameterset dl_delbaparamset; + u_int16_t dl_reasoncode; +} __packed; + +/* MGT Notif actions */ +#define IEEE80211_WMM_QOS_ACTION_SETUP_REQ 0 +#define IEEE80211_WMM_QOS_ACTION_SETUP_RESP 1 +#define IEEE80211_WMM_QOS_ACTION_TEARDOWN 2 + +#define IEEE80211_WMM_QOS_DIALOG_TEARDOWN 0 +#define IEEE80211_WMM_QOS_DIALOG_SETUP 1 + +#define IEEE80211_WMM_QOS_TSID_DATA_TSPEC 6 +#define IEEE80211_WMM_QOS_TSID_SIG_TSPEC 7 + +struct ieee80211_action_wmm_qos { + struct ieee80211_action ts_header; + u_int8_t ts_dialogtoken; + u_int8_t ts_statuscode; + struct ieee80211_wme_tspec ts_tspecie; +} __packed; + +/* + * Control frames. + */ +struct ieee80211_frame_min { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +/* + * BAR frame format + */ +#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */ +#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */ +#define IEEE80211_BAR_CTL_NOACK 0x0001 /* no-ack policy */ +#define IEEE80211_BAR_CTL_COMBA 0x0004 /* compressed block-ack */ + +/* + * SA Query Action mgmt Frame + */ +struct ieee80211_action_sa_query { + struct ieee80211_action sa_header; + u_int16_t sa_transId; +}; + +typedef enum ieee80211_action_sa_query_type{ + IEEE80211_ACTION_SA_QUERY_REQUEST, + IEEE80211_ACTION_SA_QUERY_RESPONSE +}ieee80211_action_sa_query_type_t; + +struct ieee80211_frame_bar { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + u_int8_t i_ta[IEEE80211_ADDR_LEN]; + u_int16_t i_ctl; + u_int16_t i_seq; + /* FCS */ +} __packed; + +struct ieee80211_frame_rts { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + u_int8_t i_ta[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_cts { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_ack { + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_pspoll { + u_int8_t i_fc[2]; + u_int8_t i_aid[2]; + u_int8_t i_bssid[IEEE80211_ADDR_LEN]; + u_int8_t i_ta[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +struct ieee80211_frame_cfend { /* NB: also CF-End+CF-Ack */ + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; /* should be zero */ + u_int8_t i_ra[IEEE80211_ADDR_LEN]; + u_int8_t i_bssid[IEEE80211_ADDR_LEN]; + /* FCS */ +} __packed; + +/* + * BEACON management packets + * + * octet timestamp[8] + * octet beacon interval[2] + * octet capability information[2] + * information element + * octet elemid + * octet length + * octet information[length] + */ + +typedef u_int8_t *ieee80211_mgt_beacon_t; + +#define IEEE80211_BEACON_INTERVAL(beacon) \ + ((beacon)[8] | ((beacon)[9] << 8)) +#define IEEE80211_BEACON_CAPABILITY(beacon) \ + ((beacon)[10] | ((beacon)[11] << 8)) + +#define IEEE80211_CAPINFO_ESS 0x0001 +#define IEEE80211_CAPINFO_IBSS 0x0002 +#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 +#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 +#define IEEE80211_CAPINFO_PRIVACY 0x0010 +#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 +#define IEEE80211_CAPINFO_PBCC 0x0040 +#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 +#define IEEE80211_CAPINFO_SPECTRUM_MGMT 0x0100 +#define IEEE80211_CAPINFO_QOS 0x0200 +#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 +#define IEEE80211_CAPINFO_APSD 0x0800 +#define IEEE80211_CAPINFO_RADIOMEAS 0x1000 +#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 +/* bits 14-15 are reserved */ + +/* + * 802.11i/WPA information element (maximally sized). + */ +struct ieee80211_ie_wpa { + u_int8_t wpa_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t wpa_len; /* length in bytes */ + u_int8_t wpa_oui[3]; /* 0x00, 0x50, 0xf2 */ + u_int8_t wpa_type; /* OUI type */ + u_int16_t wpa_version; /* spec revision */ + u_int32_t wpa_mcipher[1]; /* multicast/group key cipher */ + u_int16_t wpa_uciphercnt; /* # pairwise key ciphers */ + u_int32_t wpa_uciphers[8]; /* ciphers */ + u_int16_t wpa_authselcnt; /* authentication selector cnt */ + u_int32_t wpa_authsels[8]; /* selectors */ + u_int16_t wpa_caps; /* 802.11i capabilities */ + u_int16_t wpa_pmkidcnt; /* 802.11i pmkid count */ + u_int16_t wpa_pmkids[8]; /* 802.11i pmkids */ +} __packed; + +#ifndef _BYTE_ORDER +#error "Don't know native byte order" +#endif + +#ifndef IEEE80211N_IE +/* Temporary vendor specific IE for 11n pre-standard interoperability */ +#define VENDOR_HT_OUI 0x00904c +#define VENDOR_HT_CAP_ID 51 +#define VENDOR_HT_INFO_ID 52 +#endif + +#ifdef ATH_SUPPORT_TxBF +union ieee80211_hc_txbf { + struct { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int32_t reserved : 3, + channel_estimation_cap : 2, + csi_max_rows_bfer : 2, + comp_bfer_antennas : 2, + noncomp_bfer_antennas : 2, + csi_bfer_antennas : 2, + minimal_grouping : 2, + explicit_comp_bf : 2, + explicit_noncomp_bf : 2, + explicit_csi_feedback : 2, + explicit_comp_steering : 1, + explicit_noncomp_steering : 1, + explicit_csi_txbf_capable : 1, + calibration : 2, + implicit_txbf_capable : 1, + tx_ndp_capable : 1, + rx_ndp_capable : 1, + tx_staggered_sounding : 1, + rx_staggered_sounding : 1, + implicit_rx_capable : 1; +#else + u_int32_t implicit_rx_capable : 1, + rx_staggered_sounding : 1, + tx_staggered_sounding : 1, + rx_ndp_capable : 1, + tx_ndp_capable : 1, + implicit_txbf_capable : 1, + calibration : 2, + explicit_csi_txbf_capable : 1, + explicit_noncomp_steering : 1, + explicit_comp_steering : 1, + explicit_csi_feedback : 2, + explicit_noncomp_bf : 2, + explicit_comp_bf : 2, + minimal_grouping : 2, + csi_bfer_antennas : 2, + noncomp_bfer_antennas : 2, + comp_bfer_antennas : 2, + csi_max_rows_bfer : 2, + channel_estimation_cap : 2, + reserved : 3; +#endif + }; + + u_int32_t value; +} __packed; +#endif + +struct ieee80211_ie_htcap_cmn { + u_int16_t hc_cap; /* HT capabilities */ +#if _BYTE_ORDER == _BIG_ENDIAN + u_int8_t hc_reserved : 3, /* B5-7 reserved */ + hc_mpdudensity : 3, /* B2-4 MPDU density (aka Minimum MPDU Start Spacing) */ + hc_maxampdu : 2; /* B0-1 maximum rx A-MPDU factor */ +#else + u_int8_t hc_maxampdu : 2, /* B0-1 maximum rx A-MPDU factor */ + hc_mpdudensity : 3, /* B2-4 MPDU density (aka Minimum MPDU Start Spacing) */ + hc_reserved : 3; /* B5-7 reserved */ +#endif + u_int8_t hc_mcsset[16]; /* supported MCS set */ + u_int16_t hc_extcap; /* extended HT capabilities */ +#ifdef ATH_SUPPORT_TxBF + union ieee80211_hc_txbf hc_txbf; /* txbf capabilities */ +#else + u_int32_t hc_txbf; /* txbf capabilities */ +#endif + u_int8_t hc_antenna; /* antenna capabilities */ +} __packed; + +/* + * 802.11n HT Capability IE + */ +struct ieee80211_ie_htcap { + u_int8_t hc_id; /* element ID */ + u_int8_t hc_len; /* length in bytes */ + struct ieee80211_ie_htcap_cmn hc_ie; +} __packed; + +/* + * Temporary vendor private HT Capability IE + */ +struct vendor_ie_htcap { + u_int8_t hc_id; /* element ID */ + u_int8_t hc_len; /* length in bytes */ + u_int8_t hc_oui[3]; + u_int8_t hc_ouitype; + struct ieee80211_ie_htcap_cmn hc_ie; +} __packed; + +/* HT capability flags */ +#define IEEE80211_HTCAP_C_ADVCODING 0x0001 +#define IEEE80211_HTCAP_C_CHWIDTH40 0x0002 +#define IEEE80211_HTCAP_C_SMPOWERSAVE_STATIC 0x0000 /* Capable of SM Power Save (Static) */ +#define IEEE80211_HTCAP_C_SMPOWERSAVE_DYNAMIC 0x0004 /* Capable of SM Power Save (Dynamic) */ +#define IEEE80211_HTCAP_C_SM_RESERVED 0x0008 /* Reserved */ +#define IEEE80211_HTCAP_C_SM_ENABLED 0x000c /* SM enabled, no SM Power Save */ +#define IEEE80211_HTCAP_C_GREENFIELD 0x0010 +#define IEEE80211_HTCAP_C_SHORTGI20 0x0020 +#define IEEE80211_HTCAP_C_SHORTGI40 0x0040 +#define IEEE80211_HTCAP_C_TXSTBC 0x0080 +#define IEEE80211_HTCAP_C_TXSTBC_S 7 +#define IEEE80211_HTCAP_C_RXSTBC 0x0300 /* 2 bits */ +#define IEEE80211_HTCAP_C_RXSTBC_S 8 +#define IEEE80211_HTCAP_C_DELAYEDBLKACK 0x0400 +#define IEEE80211_HTCAP_C_MAXAMSDUSIZE 0x0800 /* 1 = 8K, 0 = 3839B */ +#define IEEE80211_HTCAP_C_DSSSCCK40 0x1000 +#define IEEE80211_HTCAP_C_PSMP 0x2000 +#define IEEE80211_HTCAP_C_INTOLERANT40 0x4000 +#define IEEE80211_HTCAP_C_LSIGTXOPPROT 0x8000 + +#define IEEE80211_HTCAP_C_SM_MASK 0x000c /* Spatial Multiplexing (SM) capabitlity bitmask */ + +/* B0-1 maximum rx A-MPDU factor 2^(13+Max Rx A-MPDU Factor) */ +enum { + IEEE80211_HTCAP_MAXRXAMPDU_8192, /* 2 ^ 13 */ + IEEE80211_HTCAP_MAXRXAMPDU_16384, /* 2 ^ 14 */ + IEEE80211_HTCAP_MAXRXAMPDU_32768, /* 2 ^ 15 */ + IEEE80211_HTCAP_MAXRXAMPDU_65536, /* 2 ^ 16 */ +}; +#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 + +/* B2-4 MPDU density (usec) */ +enum { + IEEE80211_HTCAP_MPDUDENSITY_NA, /* No time restriction */ + IEEE80211_HTCAP_MPDUDENSITY_0_25, /* 1/4 usec */ + IEEE80211_HTCAP_MPDUDENSITY_0_5, /* 1/2 usec */ + IEEE80211_HTCAP_MPDUDENSITY_1, /* 1 usec */ + IEEE80211_HTCAP_MPDUDENSITY_2, /* 2 usec */ + IEEE80211_HTCAP_MPDUDENSITY_4, /* 4 usec */ + IEEE80211_HTCAP_MPDUDENSITY_8, /* 8 usec */ + IEEE80211_HTCAP_MPDUDENSITY_16, /* 16 usec */ +}; + +/* HT extended capability flags */ +#define IEEE80211_HTCAP_EXTC_PCO 0x0001 +#define IEEE80211_HTCAP_EXTC_TRANS_TIME_RSVD 0x0000 +#define IEEE80211_HTCAP_EXTC_TRANS_TIME_400 0x0002 /* 20-40 switch time */ +#define IEEE80211_HTCAP_EXTC_TRANS_TIME_1500 0x0004 /* in us */ +#define IEEE80211_HTCAP_EXTC_TRANS_TIME_5000 0x0006 +#define IEEE80211_HTCAP_EXTC_RSVD_1 0x00f8 +#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_NONE 0x0000 +#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_RSVD 0x0100 +#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_UNSOL 0x0200 +#define IEEE80211_HTCAP_EXTC_MCS_FEEDBACK_FULL 0x0300 +#define IEEE80211_HTCAP_EXTC_RSVD_2 0xfc00 +#ifdef ATH_SUPPORT_TxBF +#define IEEE80211_HTCAP_EXTC_HTC_SUPPORT 0x0400 +#endif + +struct ieee80211_ie_htinfo_cmn { + u_int8_t hi_ctrlchannel; /* control channel */ +#if _BYTE_ORDER == _BIG_ENDIAN + u_int8_t hi_serviceinterval : 3, /* B5-7 svc interval granularity */ + hi_ctrlaccess : 1, /* B4 controlled access only */ + hi_rifsmode : 1, /* B3 rifs mode */ + hi_txchwidth : 1, /* B2 recommended xmiss width set */ + hi_extchoff : 2; /* B0-1 extension channel offset */ + + +/* + + * The following 2 consecutive bytes are defined in word in 80211n spec. + + * Some processors store MSB byte into lower memory address which causes wrong + + * wrong byte sequence in beacon. Thus we break into byte definition which should + + * avoid the problem for all processors + + */ + + u_int8_t hi_reserved3 : 3, /* B5-7 reserved */ + + hi_obssnonhtpresent : 1, /* B4 OBSS non-HT STA present */ + + hi_txburstlimit : 1, /* B3 transmit burst limit */ + + hi_nongfpresent : 1, /* B2 non greenfield devices present */ + + hi_opmode : 2; /* B0-1 operating mode */ + + u_int8_t hi_reserved0 ; /* B0-7 (B8-15 in 11n) reserved */ + + + +/* The following 2 consecutive bytes are defined in word in 80211n spec. */ + + u_int8_t hi_dualctsprot : 1, /* B7 dual CTS protection */ + hi_dualbeacon : 1, /* B6 dual beacon */ + hi_reserved2 : 6; /* B0-5 reserved */ + u_int8_t hi_reserved1 : 4, /* B4-7 (B12-15 in 11n) reserved */ + hi_pcophase : 1, /* B3 (B11 in 11n) pco phase */ + hi_pcoactive : 1, /* B2 (B10 in 11n) pco active */ + hi_lsigtxopprot : 1, /* B1 (B9 in 11n) l-sig txop protection full support */ + hi_stbcbeacon : 1; /* B0 (B8 in 11n) STBC beacon */ +#else + u_int8_t hi_extchoff : 2, /* B0-1 extension channel offset */ + hi_txchwidth : 1, /* B2 recommended xmiss width set */ + hi_rifsmode : 1, /* B3 rifs mode */ + hi_ctrlaccess : 1, /* B4 controlled access only */ + hi_serviceinterval : 3; /* B5-7 svc interval granularity */ + u_int16_t hi_opmode : 2, /* B0-1 operating mode */ + hi_nongfpresent : 1, /* B2 non greenfield devices present */ + hi_txburstlimit : 1, /* B3 transmit burst limit */ + hi_obssnonhtpresent : 1, /* B4 OBSS non-HT STA present */ + hi_reserved0 : 11; /* B5-15 reserved */ + u_int16_t hi_reserved2 : 6, /* B0-5 reserved */ + hi_dualbeacon : 1, /* B6 dual beacon */ + hi_dualctsprot : 1, /* B7 dual CTS protection */ + hi_stbcbeacon : 1, /* B8 STBC beacon */ + hi_lsigtxopprot : 1, /* B9 l-sig txop protection full support */ + hi_pcoactive : 1, /* B10 pco active */ + hi_pcophase : 1, /* B11 pco phase */ + hi_reserved1 : 4; /* B12-15 reserved */ +#endif + u_int8_t hi_basicmcsset[16]; /* basic MCS set */ +} __packed; + +/* + * 802.11n HT Information IE + */ +struct ieee80211_ie_htinfo { + u_int8_t hi_id; /* element ID */ + u_int8_t hi_len; /* length in bytes */ + struct ieee80211_ie_htinfo_cmn hi_ie; +} __packed; + +/* + * Temporary vendor private HT Information IE + */ +struct vendor_ie_htinfo { + u_int8_t hi_id; /* element ID */ + u_int8_t hi_len; /* length in bytes */ + u_int8_t hi_oui[3]; + u_int8_t hi_ouitype; + struct ieee80211_ie_htinfo_cmn hi_ie; +} __packed; + +/* extension channel offset (2 bit signed number) */ +enum { + IEEE80211_HTINFO_EXTOFFSET_NA = 0, /* 0 no extension channel is present */ + IEEE80211_HTINFO_EXTOFFSET_ABOVE = 1, /* +1 extension channel above control channel */ + IEEE80211_HTINFO_EXTOFFSET_UNDEF = 2, /* -2 undefined */ + IEEE80211_HTINFO_EXTOFFSET_BELOW = 3 /* -1 extension channel below control channel*/ +}; + +/* recommended transmission width set */ +enum { + IEEE80211_HTINFO_TXWIDTH_20, + IEEE80211_HTINFO_TXWIDTH_2040 +}; + +/* operating flags */ +#define IEEE80211_HTINFO_OPMODE_PURE 0x00 /* no protection */ +#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_OPT 0x01 /* prot optional (legacy device maybe present) */ +#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_40 0x02 /* prot required (20 MHz) */ +#define IEEE80211_HTINFO_OPMODE_MIXED_PROT_ALL 0x03 /* prot required (legacy devices present) */ +#define IEEE80211_HTINFO_OPMODE_NON_GF_PRESENT 0x04 /* non-greenfield devices present */ + +#define IEEE80211_HTINFO_OPMODE_MASK 0x03 /* For protection 0x00-0x03 */ + +/* Non-greenfield STAs present */ +enum { + IEEE80211_HTINFO_NON_GF_NOT_PRESENT, /* Non-greenfield STAs not present */ + IEEE80211_HTINFO_NON_GF_PRESENT, /* Non-greenfield STAs present */ +}; + +/* Transmit Burst Limit */ +enum { + IEEE80211_HTINFO_TXBURST_UNLIMITED, /* Transmit Burst is unlimited */ + IEEE80211_HTINFO_TXBURST_LIMITED, /* Transmit Burst is limited */ +}; + +/* OBSS Non-HT STAs present */ +enum { + IEEE80211_HTINFO_OBSS_NONHT_NOT_PRESENT, /* OBSS Non-HT STAs not present */ + IEEE80211_HTINFO_OBSS_NONHT_PRESENT, /* OBSS Non-HT STAs present */ +}; + +/* misc flags */ +#define IEEE80211_HTINFO_DUALBEACON 0x0040 /* B6 dual beacon */ +#define IEEE80211_HTINFO_DUALCTSPROT 0x0080 /* B7 dual stbc protection */ +#define IEEE80211_HTINFO_STBCBEACON 0x0100 /* B8 secondary beacon */ +#define IEEE80211_HTINFO_LSIGTXOPPROT 0x0200 /* B9 lsig txop prot full support */ +#define IEEE80211_HTINFO_PCOACTIVE 0x0400 /* B10 pco active */ +#define IEEE80211_HTINFO_PCOPHASE 0x0800 /* B11 pco phase */ + +/* Secondary Channel offset for for 40MHz direct link */ +#define IEEE80211_SECONDARY_CHANNEL_ABOVE 1 +#define IEEE80211_SECONDARY_CHANNEL_BELOW 3 + +#define IEEE80211_TDLS_CHAN_SX_PROHIBIT 0x00000002 /* bit-2 TDLS Channel Switch Prohibit */ + +/* RIFS mode */ +enum { + IEEE80211_HTINFO_RIFSMODE_PROHIBITED, /* use of rifs prohibited */ + IEEE80211_HTINFO_RIFSMODE_ALLOWED, /* use of rifs permitted */ +}; + +/* + * Management information element payloads. + */ +enum { + IEEE80211_ELEMID_SSID = 0, + IEEE80211_ELEMID_RATES = 1, + IEEE80211_ELEMID_FHPARMS = 2, + IEEE80211_ELEMID_DSPARMS = 3, + IEEE80211_ELEMID_CFPARMS = 4, + IEEE80211_ELEMID_TIM = 5, + IEEE80211_ELEMID_IBSSPARMS = 6, + IEEE80211_ELEMID_COUNTRY = 7, + IEEE80211_ELEMID_REQINFO = 10, + IEEE80211_ELEMID_QBSS_LOAD = 11, + IEEE80211_ELEMID_TCLAS = 14, + IEEE80211_ELEMID_CHALLENGE = 16, + /* 17-31 reserved for challenge text extension */ + IEEE80211_ELEMID_PWRCNSTR = 32, + IEEE80211_ELEMID_PWRCAP = 33, + IEEE80211_ELEMID_TPCREQ = 34, + IEEE80211_ELEMID_TPCREP = 35, + IEEE80211_ELEMID_SUPPCHAN = 36, + IEEE80211_ELEMID_CHANSWITCHANN = 37, + IEEE80211_ELEMID_MEASREQ = 38, + IEEE80211_ELEMID_MEASREP = 39, + IEEE80211_ELEMID_QUIET = 40, + IEEE80211_ELEMID_IBSSDFS = 41, + IEEE80211_ELEMID_ERP = 42, + IEEE80211_ELEMID_TCLAS_PROCESS = 44, + IEEE80211_ELEMID_HTCAP_ANA = 45, + IEEE80211_ELEMID_RESERVED_47 = 47, + IEEE80211_ELEMID_RSN = 48, + IEEE80211_ELEMID_XRATES = 50, + IEEE80211_ELEMID_HTCAP = 51, + IEEE80211_ELEMID_HTINFO = 52, + IEEE80211_ELEMID_MOBILITY_DOMAIN = 54, + IEEE80211_ELEMID_FT = 55, + IEEE80211_ELEMID_TIMEOUT_INTERVAL = 56, + IEEE80211_ELEMID_EXTCHANSWITCHANN = 60, + IEEE80211_ELEMID_HTINFO_ANA = 61, + IEEE80211_ELEMID_SECCHANOFFSET = 62, + IEEE80211_ELEMID_WAPI = 68, /*IE for WAPI*/ + IEEE80211_ELEMID_TIME_ADVERTISEMENT = 69, + IEEE80211_ELEMID_RRM = 70, /* Radio resource measurement */ + IEEE80211_ELEMID_2040_COEXT = 72, + IEEE80211_ELEMID_2040_INTOL = 73, + IEEE80211_ELEMID_OBSS_SCAN = 74, + IEEE80211_ELEMID_MMIE = 76, /* 802.11w Management MIC IE */ + IEEE80211_ELEMID_FMS_DESCRIPTOR = 86, /* 802.11v FMS descriptor IE */ + IEEE80211_ELEMID_FMS_REQUEST = 87, /* 802.11v FMS request IE */ + IEEE80211_ELEMID_FMS_RESPONSE = 88, /* 802.11v FMS response IE */ + IEEE80211_ELEMID_BSSMAX_IDLE_PERIOD = 90, /* BSS MAX IDLE PERIOD */ + IEEE80211_ELEMID_TFS_REQUEST = 91, + IEEE80211_ELEMID_TFS_RESPONSE = 92, + IEEE80211_ELEMID_TIM_BCAST_REQUEST = 94, + IEEE80211_ELEMID_TIM_BCAST_RESPONSE = 95, + IEEE80211_ELEMID_INTERWORKING = 107, + IEEE80211_ELEMID_XCAPS = 127, + IEEE80211_ELEMID_RESERVED_133 = 133, + IEEE80211_ELEMID_TPC = 150, + IEEE80211_ELEMID_CCKM = 156, + IEEE80211_ELEMID_VHTCAP = 191, /* VHT Capabilities */ + IEEE80211_ELEMID_VHTOP = 192, /* VHT Operation */ + IEEE80211_ELEMID_EXT_BSS_LOAD = 193, /* Extended BSS Load */ + IEEE80211_ELEMID_WIDE_BAND_CHAN_SWITCH = 194, /* Wide Band Channel Switch */ + IEEE80211_ELEMID_VHT_TX_PWR_ENVLP = 195, /* VHT Transmit Power Envelope */ + IEEE80211_ELEMID_CHAN_SWITCH_WRAP = 196, /* Channel Switch Wrapper */ + IEEE80211_ELEMID_AID = 197, /* AID */ + IEEE80211_ELEMID_QUIET_CHANNEL = 198, /* Quiet Channel */ + IEEE80211_ELEMID_OP_MODE_NOTIFY = 199, /* Operating Mode Notification */ + IEEE80211_ELEMID_VENDOR = 221, /* vendor private */ +}; + +#define IEEE80211_MAX_IE_LEN 255 +#define IEEE80211_RSN_IE_LEN 22 + +#define IEEE80211_CHANSWITCHANN_BYTES 5 +#define IEEE80211_EXTCHANSWITCHANN_BYTES 6 + +//TODO -> Need to Check Redefinition Error used in only UMAC +#if 0 +struct ieee80211_tim_ie { + u_int8_t tim_ie; /* IEEE80211_ELEMID_TIM */ + u_int8_t tim_len; + u_int8_t tim_count; /* DTIM count */ + u_int8_t tim_period; /* DTIM period */ + u_int8_t tim_bitctl; /* bitmap control */ + u_int8_t tim_bitmap[1]; /* variable-length bitmap */ +} __packed; +#endif + +/* Country IE channel triplet */ +struct country_ie_triplet { + union{ + u_int8_t schan; /* starting channel */ + u_int8_t regextid; /* Regulatory Extension Identifier */ + }; + union{ + u_int8_t nchan; /* number of channels */ + u_int8_t regclass; /* Regulatory Class */ + }; + union{ + u_int8_t maxtxpwr; /* tx power */ + u_int8_t coverageclass; /* Coverage Class */ + }; +}__packed; + +struct ieee80211_country_ie { + u_int8_t ie; /* IEEE80211_ELEMID_COUNTRY */ + u_int8_t len; + u_int8_t cc[3]; /* ISO CC+(I)ndoor/(O)utdoor */ + struct country_ie_triplet triplet[1]; +} __packed; + +struct ieee80211_fh_ie { + u_int8_t ie; /* IEEE80211_ELEMID_FHPARMS */ + u_int8_t len; + u_int16_t dwell_time; // endianess?? + u_int8_t hop_set; + u_int8_t hop_pattern; + u_int8_t hop_index; +} __packed; + +struct ieee80211_ds_ie { + u_int8_t ie; /* IEEE80211_ELEMID_DSPARMS */ + u_int8_t len; + u_int8_t current_channel; +} __packed; + +struct ieee80211_erp_ie { + u_int8_t ie; /* IEEE80211_ELEMID_ERP */ + u_int8_t len; + u_int8_t value; +} __packed; + +//TODO -> Need to Check Redefinition Error used in only UMAC +#if 0 +struct ieee80211_quiet_ie { + u_int8_t ie; /* IEEE80211_ELEMID_QUIET */ + u_int8_t len; + u_int8_t tbttcount; /* quiet start */ + u_int8_t period; /* beacon intervals between quiets*/ + u_int16_t duration; /* TUs of each quiet*/ + u_int16_t offset; /* TUs of from TBTT of quiet start*/ +} __packed; +#endif + +struct ieee80211_channelswitch_ie { + u_int8_t ie; /* IEEE80211_ELEMID_CHANSWITCHANN */ + u_int8_t len; + u_int8_t switchmode; + u_int8_t newchannel; + u_int8_t tbttcount; +} __packed; + +/* channel switch action frame format definition */ +struct ieee80211_action_spectrum_channel_switch { + struct ieee80211_action csa_header; + struct ieee80211_channelswitch_ie csa_element; +}__packed; + +struct ieee80211_extendedchannelswitch_ie { + u_int8_t ie; /* IEEE80211_ELEMID_EXTCHANSWITCHANN */ + u_int8_t len; + u_int8_t switchmode; + u_int8_t newClass; + u_int8_t newchannel; + u_int8_t tbttcount; +} __packed; + +struct ieee80211_tpc_ie { + u_int8_t ie; + u_int8_t len; + u_int8_t pwrlimit; +} __packed; + +/* + * MHDRIE included in TKIP MFP protected management frames + */ +struct ieee80211_ese_mhdr_ie { + u_int8_t mhdr_id; + u_int8_t mhdr_len; + u_int8_t mhdr_oui[3]; + u_int8_t mhdr_oui_type; + u_int8_t mhdr_fc[2]; + u_int8_t mhdr_bssid[6]; +} __packed; + +/* + * SSID IE + */ +struct ieee80211_ie_ssid { + u_int8_t ssid_id; + u_int8_t ssid_len; + u_int8_t ssid[32]; +} __packed; + +/* + * Supported rates + */ +#define IEEE80211_MAX_SUPPORTED_RATES 8 + +struct ieee80211_ie_rates { + u_int8_t rate_id; /* Element Id */ + u_int8_t rate_len; /* IE Length */ + u_int8_t rate[IEEE80211_MAX_SUPPORTED_RATES]; /* IE Length */ +} __packed; + +/* + * Extended rates + */ +#define IEEE80211_MAX_EXTENDED_RATES 256 + +struct ieee80211_ie_xrates { + u_int8_t xrate_id; /* Element Id */ + u_int8_t xrate_len; /* IE Length */ + u_int8_t xrate[IEEE80211_MAX_EXTENDED_RATES]; /* IE Length */ +} __packed; + +/* + * WPS SSID list information element (maximally sized). + */ +struct ieee80211_ie_ssidl { + u_int8_t ssidl_id; /* IEEE80211_ELEMID_VENDOR */ + u_int8_t ssidl_len; /* length in bytes */ + u_int8_t ssidl_oui[3]; /* 0x00, 0x50, 0xf2 */ + u_int8_t ssidl_type; /* OUI type */ + u_int8_t ssidl_prim_cap; /* Primary capabilities */ + u_int8_t ssidl_count; /* # of secondary SSIDs */ + u_int16_t ssidl_value[248]; +} __packed; + +#if _BYTE_ORDER == _BIG_ENDIAN +struct ieee80211_sec_ssid_cap { + u_int32_t reserved0 :1, + akmlist :6, + reserved1 :4, + reeserved2 :2, + ucipher :15, + mcipher :4; +}; +#else +struct ieee80211_sec_ssid_cap { + u_int32_t mcipher :4, + ucipher :15, + reserved2 :2, + reserved1 :4, + akmlist :6, + reserved0 :1; +}; +#endif + +struct ieee80211_ie_qbssload { + u_int8_t elem_id; /* IEEE80211_ELEMID_QBSS_LOAD */ + u_int8_t length; /* length in bytes */ + u_int16_t station_count; /* number of station associated */ + u_int8_t channel_utilization; /* channel busy time in 0-255 scale */ + u_int16_t aac; /* available admission capacity */ +} __packed; + +#define SEC_SSID_HEADER_LEN 6 +#define SSIDL_IE_HEADER_LEN 6 + +struct ieee80211_sec_ssid { + u_int8_t sec_ext_cap; + struct ieee80211_sec_ssid_cap sec_cap; + u_int8_t sec_ssid_len; + u_int8_t sec_ssid[32]; +} __packed; + +/* Definitions of SSIDL IE */ +enum { + CAP_MCIPHER_ENUM_NONE = 0, + CAP_MCIPHER_ENUM_WEP40, + CAP_MCIPHER_ENUM_WEP104, + CAP_MCIPHER_ENUM_TKIP, + CAP_MCIPHER_ENUM_CCMP, + CAP_MCIPHER_ENUM_CKIP_CMIC, + CAP_MCIPHER_ENUM_CKIP, + CAP_MCIPHER_ENUM_CMIC +}; + + +#define CAP_UCIPHER_BIT_NONE 0x0001 +#define CAP_UCIPHER_BIT_WEP40 0x0002 +#define CAP_UCIPHER_BIT_WEP104 0x0004 +#define CAP_UCIPHER_BIT_TKIP 0x0008 +#define CAP_UCIPHER_BIT_CCMP 0x0010 +#define CAP_UCIPHER_BIT_CKIP_CMIC 0x0020 +#define CAP_UCIPHER_BIT_CKIP 0x0040 +#define CAP_UCIPHER_BIT_CMIC 0x0080 +#define CAP_UCIPHER_BIT_WPA2_WEP40 0x0100 +#define CAP_UCIPHER_BIT_WPA2_WEP104 0x0200 +#define CAP_UCIPHER_BIT_WPA2_TKIP 0x0400 +#define CAP_UCIPHER_BIT_WPA2_CCMP 0x0800 +#define CAP_UCIPHER_BIT_WPA2_CKIP_CMIC 0x1000 +#define CAP_UCIPHER_BIT_WPA2_CKIP 0x2000 +#define CAP_UCIPHER_BIT_WPA2_CMIC 0x4000 + +#define CAP_AKM_BIT_WPA1_1X 0x01 +#define CAP_AKM_BIT_WPA1_PSK 0x02 +#define CAP_AKM_BIT_WPA2_1X 0x04 +#define CAP_AKM_BIT_WPA2_PSK 0x08 +#define CAP_AKM_BIT_WPA1_CCKM 0x10 +#define CAP_AKM_BIT_WPA2_CCKM 0x20 + +#define IEEE80211_CHALLENGE_LEN 128 + +#define IEEE80211_SUPPCHAN_LEN 26 + +#define IEEE80211_RATE_BASIC 0x80 +#define IEEE80211_RATE_VAL 0x7f + +/* EPR information element flags */ +#define IEEE80211_ERP_NON_ERP_PRESENT 0x01 +#define IEEE80211_ERP_USE_PROTECTION 0x02 +#define IEEE80211_ERP_LONG_PREAMBLE 0x04 + +/* Atheros private advanced capabilities info */ +#define ATHEROS_CAP_TURBO_PRIME 0x01 +#define ATHEROS_CAP_COMPRESSION 0x02 +#define ATHEROS_CAP_FAST_FRAME 0x04 +/* bits 3-6 reserved */ +#define ATHEROS_CAP_BOOST 0x80 + +#define ATH_OUI 0x7f0300 /* Atheros OUI */ +#define ATH_OUI_TYPE 0x01 +#define ATH_OUI_SUBTYPE 0x01 +#define ATH_OUI_VERSION 0x00 +#define ATH_OUI_TYPE_XR 0x03 +#define ATH_OUI_VER_XR 0x01 +#define ATH_OUI_EXTCAP_TYPE 0x04 /* Atheros Extended Cap Type */ +#define ATH_OUI_EXTCAP_SUBTYPE 0x01 /* Atheros Extended Cap Sub-type */ +#define ATH_OUI_EXTCAP_VERSION 0x00 /* Atheros Extended Cap Version */ + +#define WPA_OUI 0xf25000 +#define WPA_VERSION 1 /* current supported version */ +#define CSCO_OUI 0x964000 /* Cisco OUI */ +#define AOW_OUI 0x4a0100 /* AoW OUI, workaround */ +#define AOW_OUI_TYPE 0x01 +#define AOW_OUI_VERSION 0x01 + +#define WSC_OUI 0x0050f204 + +#define WPA_CSE_NULL 0x00 +#define WPA_CSE_WEP40 0x01 +#define WPA_CSE_TKIP 0x02 +#define WPA_CSE_CCMP 0x04 +#define WPA_CSE_WEP104 0x05 + +#define WPA_ASE_NONE 0x00 +#define WPA_ASE_8021X_UNSPEC 0x01 +#define WPA_ASE_8021X_PSK 0x02 +#define WPA_ASE_FT_IEEE8021X 0x20 +#define WPA_ASE_FT_PSK 0x40 +#define WPA_ASE_SHA256_IEEE8021X 0x80 +#define WPA_ASE_SHA256_PSK 0x100 +#define WPA_ASE_WPS 0x200 + + +#define RSN_OUI 0xac0f00 +#define RSN_VERSION 1 /* current supported version */ + +#define RSN_CSE_NULL 0x00 +#define RSN_CSE_WEP40 0x01 +#define RSN_CSE_TKIP 0x02 +#define RSN_CSE_WRAP 0x03 +#define RSN_CSE_CCMP 0x04 +#define RSN_CSE_WEP104 0x05 +#define RSN_CSE_AES_CMAC 0x06 + +#define RSN_ASE_NONE 0x00 +#define RSN_ASE_8021X_UNSPEC 0x01 +#define RSN_ASE_8021X_PSK 0x02 +#define RSN_ASE_FT_IEEE8021X 0x20 +#define RSN_ASE_FT_PSK 0x40 +#define RSN_ASE_SHA256_IEEE8021X 0x80 +#define RSN_ASE_SHA256_PSK 0x100 +#define RSN_ASE_WPS 0x200 + +#define AKM_SUITE_TYPE_IEEE8021X 0x01 +#define AKM_SUITE_TYPE_PSK 0x02 +#define AKM_SUITE_TYPE_FT_IEEE8021X 0x03 +#define AKM_SUITE_TYPE_FT_PSK 0x04 +#define AKM_SUITE_TYPE_SHA256_IEEE8021X 0x05 +#define AKM_SUITE_TYPE_SHA256_PSK 0x06 + +#define RSN_CAP_PREAUTH 0x01 +#define RSN_CAP_PTKSA_REPLAYCOUNTER 0x0c +#define RSN_CAP_GTKSA_REPLAYCOUNTER 0x30 +#define RSN_CAP_MFP_REQUIRED 0x40 +#define RSN_CAP_MFP_ENABLED 0x80 + +#define CCKM_OUI 0x964000 +#define CCKM_ASE_UNSPEC 0 +#define WPA_CCKM_AKM 0x00964000 +#define RSN_CCKM_AKM 0x00964000 + +#define WME_OUI 0xf25000 +#define WME_OUI_TYPE 0x02 +#define WME_INFO_OUI_SUBTYPE 0x00 +#define WME_PARAM_OUI_SUBTYPE 0x01 +#define WME_TSPEC_OUI_SUBTYPE 0x02 + +#define WME_PARAM_OUI_VERSION 1 +#define WME_TSPEC_OUI_VERSION 1 +#define WME_VERSION 1 + +/* WME stream classes */ +#define WME_AC_BE 0 /* best effort */ +#define WME_AC_BK 1 /* background */ +#define WME_AC_VI 2 /* video */ +#define WME_AC_VO 3 /* voice */ + +/* WCN IE */ +#define WCN_OUI 0xf25000 /* Microsoft OUI */ +#define WCN_OUI_TYPE 0x04 /* WCN */ + +/* Atheros htoui for ht vender ie; use Epigram OUI for compatibility with pre11n devices */ +#define ATH_HTOUI 0x00904c + +#define SFA_OUI 0x964000 +#define SFA_OUI_TYPE 0x14 +#define SFA_IE_CAP_MFP 0x01 +#define SFA_IE_CAP_DIAG_CHANNEL 0x02 +#define SFA_IE_CAP_LOCATION_SVCS 0x04 +#define SFA_IE_CAP_EXP_BANDWIDTH 0x08 + +#define WPA_OUI_BYTES 0x00, 0x50, 0xf2 +#define RSN_OUI_BYTES 0x00, 0x0f, 0xac +#define WME_OUI_BYTES 0x00, 0x50, 0xf2 +#define ATH_OUI_BYTES 0x00, 0x03, 0x7f +#define SFA_OUI_BYTES 0x00, 0x40, 0x96 +#define CCKM_OUI_BYTES 0x00, 0x40, 0x96 +#define WPA_SEL(x) (((x)<<24)|WPA_OUI) +#define RSN_SEL(x) (((x)<<24)|RSN_OUI) +#define SFA_SEL(x) (((x)<<24)|SFA_OUI) +#define CCKM_SEL(x) (((x)<<24)|CCKM_OUI) + +#define IEEE80211_RV(v) ((v) & IEEE80211_RATE_VAL) +#define IEEE80211_N(a) (sizeof(a) / sizeof(a[0])) + +/* + * AUTH management packets + * + * octet algo[2] + * octet seq[2] + * octet status[2] + * octet chal.id + * octet chal.length + * octet chal.text[253] + */ + +typedef u_int8_t *ieee80211_mgt_auth_t; + +#define IEEE80211_AUTH_ALGORITHM(auth) \ + ((auth)[0] | ((auth)[1] << 8)) +#define IEEE80211_AUTH_TRANSACTION(auth) \ + ((auth)[2] | ((auth)[3] << 8)) +#define IEEE80211_AUTH_STATUS(auth) \ + ((auth)[4] | ((auth)[5] << 8)) + +#define IEEE80211_AUTH_ALG_OPEN 0x0000 +#define IEEE80211_AUTH_ALG_SHARED 0x0001 +#define IEEE80211_AUTH_ALG_FT 0x0002 +#define IEEE80211_AUTH_ALG_LEAP 0x0080 + +enum { + IEEE80211_AUTH_OPEN_REQUEST = 1, + IEEE80211_AUTH_OPEN_RESPONSE = 2, +}; + +enum { + IEEE80211_AUTH_SHARED_REQUEST = 1, + IEEE80211_AUTH_SHARED_CHALLENGE = 2, + IEEE80211_AUTH_SHARED_RESPONSE = 3, + IEEE80211_AUTH_SHARED_PASS = 4, +}; + +/* + * Reason codes + * + * Unlisted codes are reserved + */ + +enum { + IEEE80211_REASON_UNSPECIFIED = 1, + IEEE80211_REASON_AUTH_EXPIRE = 2, + IEEE80211_REASON_AUTH_LEAVE = 3, + IEEE80211_REASON_ASSOC_EXPIRE = 4, + IEEE80211_REASON_ASSOC_TOOMANY = 5, + IEEE80211_REASON_NOT_AUTHED = 6, + IEEE80211_REASON_NOT_ASSOCED = 7, + IEEE80211_REASON_ASSOC_LEAVE = 8, + IEEE80211_REASON_ASSOC_NOT_AUTHED = 9, + + IEEE80211_REASON_RSN_REQUIRED = 11, + IEEE80211_REASON_RSN_INCONSISTENT = 12, + IEEE80211_REASON_IE_INVALID = 13, + IEEE80211_REASON_MIC_FAILURE = 14, + + IEEE80211_REASON_QOS = 32, + IEEE80211_REASON_QOS_BANDWITDH = 33, + IEEE80211_REASON_QOS_CH_CONDITIONS = 34, + IEEE80211_REASON_QOS_TXOP = 35, + IEEE80211_REASON_QOS_LEAVE = 36, + IEEE80211_REASON_QOS_DECLINED = 37, + IEEE80211_REASON_QOS_SETUP_REQUIRED = 38, + IEEE80211_REASON_QOS_TIMEOUT = 39, + IEEE80211_REASON_QOS_CIPHER = 45, + + IEEE80211_STATUS_SUCCESS = 0, + IEEE80211_STATUS_UNSPECIFIED = 1, + IEEE80211_STATUS_CAPINFO = 10, + IEEE80211_STATUS_NOT_ASSOCED = 11, + IEEE80211_STATUS_OTHER = 12, + IEEE80211_STATUS_ALG = 13, + IEEE80211_STATUS_SEQUENCE = 14, + IEEE80211_STATUS_CHALLENGE = 15, + IEEE80211_STATUS_TIMEOUT = 16, + IEEE80211_STATUS_TOOMANY = 17, + IEEE80211_STATUS_BASIC_RATE = 18, + IEEE80211_STATUS_SP_REQUIRED = 19, + IEEE80211_STATUS_PBCC_REQUIRED = 20, + IEEE80211_STATUS_CA_REQUIRED = 21, + IEEE80211_STATUS_TOO_MANY_STATIONS = 22, + IEEE80211_STATUS_RATES = 23, + IEEE80211_STATUS_SHORTSLOT_REQUIRED = 25, + IEEE80211_STATUS_DSSSOFDM_REQUIRED = 26, + IEEE80211_STATUS_NO_HT = 27, + IEEE80211_STATUS_REJECT_TEMP = 30, + IEEE80211_STATUS_MFP_VIOLATION = 31, + IEEE80211_STATUS_REFUSED = 37, + IEEE80211_STATUS_INVALID_PARAM = 38, + + IEEE80211_STATUS_DLS_NOT_ALLOWED = 48, +}; + +/* private IEEE80211_STATUS */ +#define IEEE80211_STATUS_CANCEL -1 +#define IEEE80211_STATUS_INVALID_IE -2 +#define IEEE80211_STATUS_INVALID_CHANNEL -3 + +#define IEEE80211_WEP_KEYLEN 5 /* 40bit */ +#define IEEE80211_WEP_IVLEN 3 /* 24bit */ +#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */ +#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */ +#define IEEE80211_WEP_NKID 4 /* number of key ids */ + +/* + * 802.11i defines an extended IV for use with non-WEP ciphers. + * When the EXTIV bit is set in the key id byte an additional + * 4 bytes immediately follow the IV for TKIP. For CCMP the + * EXTIV bit is likewise set but the 8 bytes represent the + * CCMP header rather than IV+extended-IV. + */ +#define IEEE80211_WEP_EXTIV 0x20 +#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */ +#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */ + +#define IEEE80211_CCMP_HEADERLEN 8 +#define IEEE80211_CCMP_MICLEN 8 + +/* + * 802.11w defines a MMIE chunk to be attached at the end of + * any outgoing broadcast or multicast robust management frame. + * MMIE field is total 18 bytes in size. Following the diagram of MMIE + * + * <------------ 18 Bytes MMIE -----------------------> + * +--------+---------+---------+-----------+---------+ + * |Element | Length | Key id | IPN | MIC | + * | id | | | | | + * +--------+---------+---------+-----------+---------+ + * bytes 1 1 2 6 8 + * + */ +#define IEEE80211_MMIE_LEN 18 +#define IEEE80211_MMIE_ELEMENTIDLEN 1 +#define IEEE80211_MMIE_LENGTHLEN 1 +#define IEEE80211_MMIE_KEYIDLEN 2 +#define IEEE80211_MMIE_IPNLEN 6 +#define IEEE80211_MMIE_MICLEN 8 + +#define IEEE80211_CRC_LEN 4 + +#define IEEE80211_8021Q_HEADER_LEN 4 +/* + * Maximum acceptable MTU is: + * IEEE80211_MAX_LEN - WEP overhead - CRC - + * QoS overhead - RSN/WPA overhead + * Min is arbitrarily chosen > IEEE80211_MIN_LEN. The default + * mtu is Ethernet-compatible; it's set by ether_ifattach. + */ +#define IEEE80211_MTU_MAX 2290 +#define IEEE80211_MTU_MIN 32 + +/* Rather than using this default value, customer platforms can provide a custom value for this constant. + Coustomer platform will use the different define value by themself */ +#ifndef IEEE80211_MAX_MPDU_LEN +#define IEEE80211_MAX_MPDU_LEN (3840 + IEEE80211_CRC_LEN + \ + (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) +#endif +#define IEEE80211_ACK_LEN \ + (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) +#define IEEE80211_MIN_LEN \ + (sizeof(struct ieee80211_frame_min) + IEEE80211_CRC_LEN) + +/* An 802.11 data frame can be one of three types: +1. An unaggregated frame: The maximum length of an unaggregated data frame is 2324 bytes + headers. +2. A data frame that is part of an AMPDU: The maximum length of an AMPDU may be upto 65535 bytes, but data frame is limited to 2324 bytes + header. +3. An AMSDU: The maximum length of an AMSDU is eihther 3839 or 7095 bytes. +The maximum frame length supported by hardware is 4095 bytes. +A length of 3839 bytes is chosen here to support unaggregated data frames, any size AMPDUs and 3839 byte AMSDUs. +*/ +#define IEEE80211N_MAX_FRAMELEN 3839 +#define IEEE80211N_MAX_LEN (IEEE80211N_MAX_FRAMELEN + IEEE80211_CRC_LEN + \ + (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) + +#define IEEE80211_TX_CHAINMASK_MIN 1 +#define IEEE80211_TX_CHAINMASK_MAX 7 + +#define IEEE80211_RX_CHAINMASK_MIN 1 +#define IEEE80211_RX_CHAINMASK_MAX 7 + +/* + * The 802.11 spec says at most 2007 stations may be + * associated at once. For most AP's this is way more + * than is feasible so we use a default of 128. This + * number may be overridden by the driver and/or by + * user configuration. + */ +#define IEEE80211_AID_MAX 2007 +#define IEEE80211_AID_DEF 128 + +#define IEEE80211_AID(b) ((b) &~ 0xc000) + +/* + * RTS frame length parameters. The default is specified in + * the 802.11 spec. The max may be wrong for jumbo frames. + */ +#define IEEE80211_RTS_DEFAULT 512 +#define IEEE80211_RTS_MIN 0 +#define IEEE80211_RTS_MAX 2347 + +/* + * Fragmentation limits + */ +#define IEEE80211_FRAGMT_THRESHOLD_MIN 540 /* min frag threshold */ +#define IEEE80211_FRAGMT_THRESHOLD_MAX 2346 /* max frag threshold */ + +/* + * Regulatory extention identifier for country IE. + */ +#define IEEE80211_REG_EXT_ID 201 + +/* + * overlapping BSS + */ +#define IEEE80211_OBSS_SCAN_PASSIVE_DWELL_DEF 20 +#define IEEE80211_OBSS_SCAN_ACTIVE_DWELL_DEF 10 +#define IEEE80211_OBSS_SCAN_INTERVAL_DEF 300 +#define IEEE80211_OBSS_SCAN_PASSIVE_TOTAL_DEF 200 +#define IEEE80211_OBSS_SCAN_ACTIVE_TOTAL_DEF 20 +#define IEEE80211_OBSS_SCAN_THRESH_DEF 25 +#define IEEE80211_OBSS_SCAN_DELAY_DEF 5 + +/* + * overlapping BSS scan ie + */ +struct ieee80211_ie_obss_scan { + u_int8_t elem_id; + u_int8_t elem_len; + u_int16_t scan_passive_dwell; + u_int16_t scan_active_dwell; + u_int16_t scan_interval; + u_int16_t scan_passive_total; + u_int16_t scan_active_total; + u_int16_t scan_delay; + u_int16_t scan_thresh; +} __packed; + +/* + * Extended capability ie + */ +struct ieee80211_ie_ext_cap { + u_int8_t elem_id; + u_int8_t elem_len; + u_int32_t ext_capflags; + u_int32_t ext_capflags2; +} __packed; + +/* Extended capability IE flags */ +#define IEEE80211_EXTCAPIE_2040COEXTMGMT 0x00000001 +#define IEEE80211_EXTCAPIE_TFS 0x00010000 +#define IEEE80211_EXTCAPIE_FMS 0x00000800 +#define IEEE80211_EXTCAPIE_WNMSLEEPMODE 0x00020000 +#define IEEE80211_EXTCAPIE_TIMBROADCAST 0x00040000 +#define IEEE80211_EXTCAPIE_PROXYARP 0x00001000 +#define IEEE80211_EXTCAPIE_BSSTRANSITION 0x00080000 +/* Tunneled Direct Link Setup (TDLS) extended capability bits */ +#define IEEE80211_EXTCAPIE_PEER_UAPSD_BUF_STA 0x10000000 +#define IEEE80211_EXTCAPIE_TDLS_PEER_PSM 0x20000000 +#define IEEE80211_EXTCAPIE_TDLS_CHAN_SX 0x40000000 +/* 2nd Extended capability IE flags bit32-bit63*/ +#define IEEE80211_EXTCAPIE_TDLSSUPPORT 0x00000020 /* bit-37 TDLS Support */ +#define IEEE80211_EXTCAPIE_TDLSPROHIBIT 0x00000040 /* bit-38 TDLS Prohibit Support */ +#define IEEE80211_EXTCAPIE_TDLSCHANSXPROHIBIT 0x00000080 /* bit-39 TDLS Channel Switch Prohibit */ +#define IEEE80211_EXTCAPIE_TDLS_WIDE_BAND 0x20000080 /* bit-61 TDLS Wide Bandwidth support */ +#define IEEE80211_EXTCAPIE_OP_MODE_NOTIFY 0x40000000 /* bit-62 Operating Mode notification */ + +/* + * These caps are populated when we recieve beacon/probe response + * This is used to maintain local TDLS cap bit masks + */ + +#define IEEE80211_TDLS_PROHIBIT 0x00000001 /* bit-1 TDLS Prohibit Support */ + +/* + * 20/40 BSS coexistence ie + */ +struct ieee80211_ie_bss_coex { + u_int8_t elem_id; + u_int8_t elem_len; +#if _BYTE_ORDER == _BIG_ENDIAN + u_int8_t reserved1 : 1, + reserved2 : 1, + reserved3 : 1, + obss_exempt_grant : 1, + obss_exempt_req : 1, + ht20_width_req : 1, + ht40_intolerant : 1, + inf_request : 1; +#else + u_int8_t inf_request : 1, + ht40_intolerant : 1, + ht20_width_req : 1, + obss_exempt_req : 1, + obss_exempt_grant : 1, + reserved3 : 1, + reserved2 : 1, + reserved1 : 1; +#endif +} __packed; + +/* + * 20/40 BSS intolerant channel report ie + */ +struct ieee80211_ie_intolerant_report { + u_int8_t elem_id; + u_int8_t elem_len; + u_int8_t reg_class; + u_int8_t chan_list[1]; /* variable-length channel list */ +} __packed; + +/* + * 20/40 coext management action frame + */ +struct ieee80211_action_bss_coex_frame { + struct ieee80211_action ac_header; + struct ieee80211_ie_bss_coex coex; + struct ieee80211_ie_intolerant_report chan_report; +} __packed; + +typedef enum ieee80211_tie_interval_type{ + IEEE80211_TIE_INTERVAL_TYPE_RESERVED = 0, + IEEE80211_TIE_INTERVAL_TYPE_REASSOC_DEADLINE_INTERVAL = 1, + IEEE80211_TIE_INTERVAL_TYPE_KEY_LIFETIME_INTERVAL = 2, + IEEE80211_TIE_INTERVAL_TYPE_ASSOC_COMEBACK_TIME = 3, +}ieee80211_tie_interval_type_t; + +struct ieee80211_ie_timeout_interval { + u_int8_t elem_id; + u_int8_t elem_len; + u_int8_t interval_type; + u_int32_t value; +} __packed; + +//TODO -> Need to Check Redefinition Error used in only UMAC +#if 0 +/* Management MIC information element (IEEE 802.11w) */ +struct ieee80211_mmie { + u_int8_t element_id; + u_int8_t length; + u_int16_t key_id; + u_int8_t sequence_number[6]; + u_int8_t mic[8]; +} __packed; +#endif + +/* VHT capability flags */ +/* B0-B1 Maximum MPDU Length */ +#define IEEE80211_VHTCAP_MAX_MPDU_LEN_3839 0x00000000 /* A-MSDU Length 3839 octets */ +#define IEEE80211_VHTCAP_MAX_MPDU_LEN_7935 0x00000001 /* A-MSDU Length 7991 octets */ +#define IEEE80211_VHTCAP_MAX_MPDU_LEN_11454 0x00000002 /* A-MSDU Length 11454 octets */ + +/* B2-B3 Supported Channel Width */ +#define IEEE80211_VHTCAP_SUP_CHAN_WIDTH_80 0x00000000 /* Does not support 160 or 80+80 */ +#define IEEE80211_VHTCAP_SUP_CHAN_WIDTH_160 0x00000004 /* Supports 160 */ +#define IEEE80211_VHTCAP_SUP_CHAN_WIDTH_80_160 0x00000008 /* Support both 160 or 80+80 */ +#define IEEE80211_VHTCAP_SUP_CHAN_WIDTH_S 2 /* B2-B3 */ + +#define IEEE80211_VHTCAP_RX_LDPC 0x00000010 /* B4 RX LDPC */ +#define IEEE80211_VHTCAP_SHORTGI_80 0x00000020 /* B5 Short GI for 80MHz */ +#define IEEE80211_VHTCAP_SHORTGI_160 0x00000040 /* B6 Short GI for 160 and 80+80 MHz */ +#define IEEE80211_VHTCAP_TX_STBC 0x00000080 /* B7 Tx STBC */ +#define IEEE80211_VHTCAP_TX_STBC_S 7 + +#define IEEE80211_VHTCAP_RX_STBC 0x00000700 /* B8-B10 Rx STBC */ +#define IEEE80211_VHTCAP_RX_STBC_S 8 + +#define IEEE80211_VHTCAP_SU_BFORMER 0x00000800 /* B11 SU Beam former capable */ +#define IEEE80211_VHTCAP_SU_BFORMEE 0x00001000 /* B12 SU Beam formee capable */ +#define IEEE80211_VHTCAP_BF_MAX_ANT 0x0000E000 /* B13-B15 Compressed steering number of + * beacomformer Antennas supported */ +#define IEEE80211_VHTCAP_BF_MAX_ANT_S 13 + +#define IEEE80211_VHTCAP_SOUND_DIMENSIONS 0x00070000 /* B16-B18 Sounding Dimensions */ +#define IEEE80211_VHTCAP_SOUND_DIMENSIONS_S 16 + +#define IEEE80211_VHTCAP_MU_BFORMER 0x00080000 /* B19 MU Beam Former */ +#define IEEE80211_VHTCAP_MU_BFORMEE 0x00100000 /* B20 MU Beam Formee */ +#define IEEE80211_VHTCAP_TXOP_PS 0x00200000 /* B21 VHT TXOP PS */ +#define IEEE80211_VHTCAP_PLUS_HTC_VHT 0x00400000 /* B22 +HTC-VHT capable */ + +#define IEEE80211_VHTCAP_MAX_AMPDU_LEN_FACTOR 13 +#define IEEE80211_VHTCAP_MAX_AMPDU_LEN_EXP 0x03800000 /* B23-B25 maximum AMPDU Length Exponent */ +#define IEEE80211_VHTCAP_MAX_AMPDU_LEN_EXP_S 23 + +#define IEEE80211_VHTCAP_LINK_ADAPT 0x0C000000 /* B26-B27 VHT Link Adaptation capable */ +#define IEEE80211_VHTCAP_RESERVED 0xF0000000 /* B28-B31 Reserved */ + +/* + * 802.11ac VHT Capability IE + */ +struct ieee80211_ie_vhtcap { + u_int8_t elem_id; + u_int8_t elem_len; + u_int32_t vht_cap_info; + u_int16_t rx_mcs_map; /* B0-B15 Max Rx MCS for each SS */ + u_int16_t rx_high_data_rate; /* B16-B28 Max Rx data rate, + Note: B29-B31 reserved */ + u_int16_t tx_mcs_map; /* B32-B47 Max Tx MCS for each SS */ + u_int16_t tx_high_data_rate; /* B48-B60 Max Tx data rate, + Note: B61-B63 reserved */ +} __packed; + + +/* VHT Operation */ +#define IEEE80211_VHTOP_CHWIDTH_2040 0 /* 20/40 MHz Operating Channel */ +#define IEEE80211_VHTOP_CHWIDTH_80 1 /* 80 MHz Operating Channel */ +#define IEEE80211_VHTOP_CHWIDTH_160 2 /* 160 MHz Operating Channel */ +#define IEEE80211_VHTOP_CHWIDTH_80_80 3 /* 80 + 80 MHz Operating Channel */ + +/* + * 802.11ac VHT Operation IE + */ +struct ieee80211_ie_vhtop { + u_int8_t elem_id; + u_int8_t elem_len; + u_int8_t vht_op_chwidth; /* BSS Operational Channel width */ + u_int8_t vht_op_ch_freq_seg1; /* Channel Center frequency */ + u_int8_t vht_op_ch_freq_seg2; /* Channel Center frequency applicable + * for 80+80MHz mode of operation */ + u_int16_t vhtop_basic_mcs_set; /* Basic MCS set */ +} __packed; + +/* + * 802.11n Secondary Channel Offset element + */ +#define IEEE80211_SEC_CHAN_OFFSET_SCN 0 /* no secondary channel */ +#define IEEE80211_SEC_CHAN_OFFSET_SCA 1 /* secondary channel above */ +#define IEEE80211_SEC_CHAN_OFFSET_SCB 3 /* secondary channel below */ + +struct ieee80211_ie_sec_chan_offset { + u_int8_t elem_id; + u_int8_t len; + u_int8_t sec_chan_offset; +} __packed; + +/* + * 802.11ac Transmit Power Envelope element + */ +#define IEEE80211_VHT_TXPWR_IS_SUB_ELEMENT 1 /* It checks whether its sub element */ +#define IEEE80211_VHT_TXPWR_MAX_POWER_COUNT 4 /* Max TX power elements valid */ +#define IEEE80211_VHT_TXPWR_NUM_POWER_SUPPORTED 3 /* Max TX power elements supported */ +#define IEEE80211_VHT_TXPWR_LCL_MAX_PWR_UNITS_SHFT 3 /* B3-B5 Local Max transmit power units */ + +struct ieee80211_ie_vht_txpwr_env { + u_int8_t elem_id; + u_int8_t elem_len; + u_int8_t txpwr_info; /* Transmit Power Information */ + u_int8_t local_max_txpwr[4]; /* Local Max TxPower for 20,40,80,160MHz */ +} __packed; + +/* + * 802.11ac Wide Bandwidth Channel Switch Element + */ + +#define IEEE80211_VHT_EXTCH_SWITCH 1 /* For extension channel switch */ +#define CHWIDTH_VHT20 20 /* Channel width 20 */ +#define CHWIDTH_VHT40 40 /* Channel width 40 */ +#define CHWIDTH_VHT80 80 /* Channel width 80 */ +#define CHWIDTH_VHT160 160 /* Channel width 160 */ + +struct ieee80211_ie_wide_bw_switch { + u_int8_t elem_id; + u_int8_t elem_len; + u_int8_t new_ch_width; /* New channel width */ + u_int8_t new_ch_freq_seg1; /* Channel Center frequency 1 */ + u_int8_t new_ch_freq_seg2; /* Channel Center frequency 2 */ +} __packed; + +#define IEEE80211_RSSI_RX 0x00000001 +#define IEEE80211_RSSI_TX 0x00000002 +#define IEEE80211_RSSI_EXTCHAN 0x00000004 +#define IEEE80211_RSSI_BEACON 0x00000008 +#define IEEE80211_RSSI_RXDATA 0x00000010 + +#define IEEE80211_RATE_TX 0 +#define IEEE80211_RATE_RX 1 +#define IEEE80211_LASTRATE_TX 2 +#define IEEE80211_LASTRATE_RX 3 +#define IEEE80211_RATECODE_TX 4 +#define IEEE80211_RATECODE_RX 5 + +#define IEEE80211_MAX_RATE_PER_CLIENT 8 +/* Define for the P2P Wildcard SSID */ +#define IEEE80211_P2P_WILDCARD_SSID "DIRECT-" + +#define IEEE80211_P2P_WILDCARD_SSID_LEN (sizeof(IEEE80211_P2P_WILDCARD_SSID) - 1) + +#endif /* _COMMON_IEEE80211_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_defines.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_defines.h new file mode 100644 index 0000000000000..039718acb24f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ieee80211_defines.h @@ -0,0 +1,1381 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#ifndef _IEEE80211_DEFINES_H_ +#define _IEEE80211_DEFINES_H_ + +#include "ieee80211_common.h" +#ifndef EXTERNAL_USE_ONLY +#include "_ieee80211_common.h" /* IEEE80211_ADDR_LEN, iee80211_phymode */ +#endif + +/* + * Public defines for Atheros Upper MAC Layer + */ + +/** + * @brief Opaque handle of 802.11 protocal layer. + */ +struct ieee80211com; +typedef struct ieee80211com *wlan_dev_t; + +/** + * @brief Opaque handle to App IE module. +*/ +struct wlan_mlme_app_ie; +typedef struct wlan_mlme_app_ie *wlan_mlme_app_ie_t; + +/** + * @brief Opaque handle of network instance (vap) in 802.11 protocal layer. +*/ +struct ieee80211vap; +typedef struct ieee80211vap *wlan_if_t; + +struct ieee80211vapprofile; +typedef struct ieee80211vapprofile *wlan_if_info_t; + +/** + * @brief Opaque handle of a node in the wifi network. + */ +struct ieee80211_node; +typedef struct ieee80211_node *wlan_node_t; + +/** + * @brief Opaque handle of OS interface (ifp in the case of unix ). + */ +struct _os_if_t; +typedef struct _os_if_t *os_if_t; + +/** + * + * @brief Opaque handle. + */ +typedef void *os_handle_t; + +/** + * @brief Opaque handle of a channel. + */ +struct ieee80211_channel; +typedef struct ieee80211_channel *wlan_chan_t; + +/** + * @brief Opaque handle scan_entry. + */ +struct ieee80211_scan_entry; +typedef struct ieee80211_scan_entry *wlan_scan_entry_t; + +/* AoW related defines */ +#define AOW_MAX_RECEIVER_COUNT 10 + + + +#define IEEE80211_NWID_LEN 32 +#define IEEE80211_ISO_COUNTRY_LENGTH 3 /* length of 11d ISO country string */ + +typedef struct _ieee80211_ssid { + int len; + u_int8_t ssid[IEEE80211_NWID_LEN]; +} ieee80211_ssid; + +typedef struct ieee80211_tx_status { + int ts_flags; +#define IEEE80211_TX_ERROR 0x01 +#define IEEE80211_TX_XRETRY 0x02 + + int ts_retries; /* number of retries to successfully transmit this frame */ +#ifdef ATH_SUPPORT_TxBF + u_int8_t ts_txbfstatus; +#define AR_BW_Mismatch 0x1 +#define AR_Stream_Miss 0x2 +#define AR_CV_Missed 0x4 +#define AR_Dest_Miss 0x8 +#define AR_Expired 0x10 +#define AR_TxBF_Valid_HW_Status (AR_BW_Mismatch|AR_Stream_Miss|AR_CV_Missed|AR_Dest_Miss|AR_Expired) +#define TxBF_STATUS_Sounding_Complete 0x20 +#define TxBF_STATUS_Sounding_Request 0x40 +#define TxBF_Valid_SW_Status (TxBF_STATUS_Sounding_Complete | TxBF_STATUS_Sounding_Request) +#define TxBF_Valid_Status (AR_TxBF_Valid_HW_Status | TxBF_Valid_SW_Status) + u_int32_t ts_tstamp; /* tx time stamp */ +#endif +#ifdef ATH_SUPPORT_FLOWMAC_MODULE + u_int8_t ts_flowmac_flags; +#define IEEE80211_TX_FLOWMAC_DONE 0x01 +#endif + u_int32_t ts_rateKbps; +} ieee80211_xmit_status; + +#ifndef EXTERNAL_USE_ONLY +typedef struct ieee80211_rx_status { + int rs_numchains; + int rs_flags; +#define IEEE80211_RX_FCS_ERROR 0x01 +#define IEEE80211_RX_MIC_ERROR 0x02 +#define IEEE80211_RX_DECRYPT_ERROR 0x04 +/* holes in flags here between, ATH_RX_XXXX to IEEE80211_RX_XXX */ +#define IEEE80211_RX_KEYMISS 0x200 + int rs_rssi; /* RSSI (noise floor ajusted) */ + int rs_abs_rssi; /* absolute RSSI */ + int rs_datarate; /* data rate received */ + int rs_rateieee; + int rs_ratephy; + +#define IEEE80211_MAX_ANTENNA 3 /* Keep the same as ATH_MAX_ANTENNA */ + u_int8_t rs_rssictl[IEEE80211_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ + u_int8_t rs_rssiextn[IEEE80211_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ + u_int8_t rs_isvalidrssi; /* rs_rssi is valid or not */ + + enum ieee80211_phymode rs_phymode; + int rs_freq; + + union { + u_int8_t data[8]; + u_int64_t tsf; + } rs_tstamp; + + /* + * Detail channel structure of recv frame. + * It could be NULL if not available + */ + struct ieee80211_channel *rs_full_chan; + + u_int8_t rs_isaggr; + u_int8_t rs_isapsd; + int16_t rs_noisefloor; + u_int16_t rs_channel; +#ifdef ATH_SUPPORT_TxBF + u_int32_t rs_rpttstamp; /* txbf report time stamp*/ +#endif + + /* The following counts are meant to assist in stats calculation. + These variables are incremented only in specific situations, and + should not be relied upon for any purpose other than the original + stats related purpose they have been introduced for. */ + + u_int16_t rs_cryptodecapcount; /* Crypto bytes decapped/demic'ed. */ + u_int8_t rs_padspace; /* No. of padding bytes present after header + in wbuf. */ + u_int8_t rs_qosdecapcount; /* QoS/HTC bytes decapped. */ + + /* End of stats calculation related counts. */ + + uint8_t rs_lsig[IEEE80211_LSIG_LEN]; + uint8_t rs_htsig[IEEE80211_HTSIG_LEN]; + uint8_t rs_servicebytes[IEEE80211_SB_LEN]; + +} ieee80211_recv_status; +#endif /* EXTERNAL_USE_ONLY */ + +/* + * flags to be passed to ieee80211_vap_create function . + */ +#define IEEE80211_CLONE_BSSID 0x0001 /* allocate unique mac/bssid */ +#define IEEE80211_CLONE_NOBEACONS 0x0002 /* don't setup beacon timers */ +#define IEEE80211_CLONE_WDS 0x0004 /* enable WDS processing */ +#define IEEE80211_CLONE_WDSLEGACY 0x0008 /* legacy WDS operation */ +#define IEEE80211_PRIMARY_VAP 0x0010 /* primary vap */ +#define IEEE80211_P2PDEV_VAP 0x0020 /* p2pdev vap */ +#define IEEE80211_P2PGO_VAP 0x0040 /* p2p-go vap */ +#define IEEE80211_P2PCLI_VAP 0x0080 /* p2p-client vap */ +#define IEEE80211_CLONE_MACADDR 0x0100 /* create vap w/ specified mac/bssid */ +#define IEEE80211_CLONE_MATADDR 0x0200 /* create vap w/ specified MAT addr */ +#define IEEE80211_WRAP_VAP 0x0400 /* wireless repeater ap vap */ + +/* + * For the new multi-vap scan feature, there is a set of default priority tables + * for each OpMode. + * The following are the default list of the VAP Scan Priority Mapping based on OpModes. + * NOTE: the following are only used when "#if ATH_SUPPORT_MULTIPLE_SCANS" is true. + */ +/* For IBSS opmode */ +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_IBSS_BASE 0 +/* For STA opmode */ +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_STA_BASE 0 +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_STA_P2P_CLIENT 1 +/* For HostAp opmode */ +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_BASE 0 +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_P2P_GO 1 +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_AP_P2P_DEVICE 2 +/* For BTAmp opmode */ +#define DEF_VAP_SCAN_PRI_MAP_OPMODE_BTAMP_BASE 0 + +typedef enum _ieee80211_dev_vap_event { + IEEE80211_VAP_CREATED = 1, + IEEE80211_VAP_STOPPED, + IEEE80211_VAP_DELETED +} ieee80211_dev_vap_event; + +typedef struct _wlan_dev_event_handler_table { + void (*wlan_dev_vap_event) (void *event_arg, wlan_dev_t, os_if_t, ieee80211_dev_vap_event); /* callback to receive vap events*/ +#ifdef ATH_SUPPORT_SPECTRAL + void (*wlan_dev_spectral_indicate)(void*, void*, u_int32_t); +#endif +} wlan_dev_event_handler_table; + +typedef enum _ieee80211_ap_stopped_reason { + IEEE80211_AP_STOPPED_REASON_DUMMY = 0, /* Dummy placeholder. Should not use */ + IEEE80211_AP_STOPPED_REASON_CHANNEL_DFS = 1, +} ieee80211_ap_stopped_reason; + +typedef int IEEE80211_REASON_CODE; +typedef int IEEE80211_STATUS; + +/* + * scan API related structs. + */ +typedef enum _ieee80211_scan_type { + IEEE80211_SCAN_BACKGROUND, + IEEE80211_SCAN_FOREGROUND, + IEEE80211_SCAN_SPECTRAL, + IEEE80211_SCAN_REPEATER_BACKGROUND, + IEEE80211_SCAN_REPEATER_EXT_BACKGROUND, + IEEE80211_SCAN_RADIO_MEASUREMENTS, +} ieee80211_scan_type; + +/* + * Priority numbers must be sequential, starting with 0. + */ +typedef enum ieee80211_scan_priority_t { + IEEE80211_SCAN_PRIORITY_VERY_LOW = 0, + IEEE80211_SCAN_PRIORITY_LOW, + IEEE80211_SCAN_PRIORITY_MEDIUM, + IEEE80211_SCAN_PRIORITY_HIGH, + IEEE80211_SCAN_PRIORITY_VERY_HIGH, + + IEEE80211_SCAN_PRIORITY_COUNT /* number of priorities supported */ +} IEEE80211_SCAN_PRIORITY; + +typedef u_int16_t IEEE80211_SCAN_REQUESTOR; +typedef u_int32_t IEEE80211_SCAN_ID; + +#define IEEE80211_SCAN_ID_NONE 0 + +/* All P2P scans currently use medium priority */ +#define IEEE80211_P2P_DEFAULT_SCAN_PRIORITY IEEE80211_SCAN_PRIORITY_MEDIUM +#define IEEE80211_P2P_SCAN_PRIORITY_HIGH IEEE80211_SCAN_PRIORITY_HIGH + +/* Masks identifying types/ID of scans */ +#define IEEE80211_SPECIFIC_SCAN 0x00000000 +#define IEEE80211_VAP_SCAN 0x01000000 +#define IEEE80211_ALL_SCANS 0x04000000 + +/** + * host scan bit. only relevant for host/target architecture. + * do not reuse this bit definition. target uses this . + * + */ +#define IEEE80211_HOST_SCAN 0x80000000 +#define IEEE80211_SCAN_CLASS_MASK 0xFF000000 + +#define IEEE80211_SCAN_PASSIVE 0x0001 /* passively scan all the channels */ +#define IEEE80211_SCAN_ACTIVE 0x0002 /* actively scan all the channels (regdomain rules still apply) */ +#define IEEE80211_SCAN_2GHZ 0x0004 /* scan 2GHz band */ +#define IEEE80211_SCAN_5GHZ 0x0008 /* scan 5GHz band */ +#define IEEE80211_SCAN_ALLBANDS (IEEE80211_SCAN_5GHZ | IEEE80211_SCAN_2GHZ) +#define IEEE80211_SCAN_CONTINUOUS 0x0010 /* keep scanning until maxscantime expires */ +#define IEEE80211_SCAN_FORCED 0x0020 /* forced scan (OS request) - should proceed even in the presence of data traffic */ +#define IEEE80211_SCAN_NOW 0x0040 /* scan now (User request) - should proceed even in the presence of data traffic */ +#define IEEE80211_SCAN_ADD_BCAST_PROBE 0x0080 /* add wildcard ssid and broadcast probe request if there is none */ +#define IEEE80211_SCAN_EXTERNAL 0x0100 /* scan requested by OS */ +#define IEEE80211_SCAN_BURST 0x0200 /* scan multiple channels before returning to BSS channel */ +#define IEEE80211_SCAN_CHAN_EVENT 0x0400 /* scan chan event for offload architectures */ +#define IEEE80211_SCAN_FILTER_PROBE_REQ 0x0800 /* Filter probe requests- applicable only for offload architectures*/ + +#define IEEE80211_SCAN_PARAMS_MAX_SSID 10 +#define IEEE80211_SCAN_PARAMS_MAX_BSSID 10 + + +/* flag definitions passed to scan_cancel API */ + +#define IEEE80211_SCAN_CANCEL_ASYNC 0x0 /* asynchronouly wait for scan SM to complete cancel */ +#define IEEE80211_SCAN_CANCEL_WAIT 0x1 /* wait for scan SM to complete cancel */ +#define IEEE80211_SCAN_CANCEL_SYNC 0x2 /* synchronously execute cancel scan */ + +#ifndef EXTERNAL_USE_ONLY +typedef bool (*ieee80211_scan_termination_check) (void *arg); + +typedef struct _ieee80211_scan_params { + ieee80211_scan_type type; + int min_dwell_time_active; /* min time in msec on active channels */ + int max_dwell_time_active; /* max time in msec on active channels (if no response) */ + int min_dwell_time_passive; /* min time in msec on passive channels */ + int max_dwell_time_passive; /* max time in msec on passive channels (if no response) */ + int min_rest_time; /* min time in msec on the BSS channel, only valid for BG scan */ + int max_rest_time; /* max time in msec on the BSS channel, only valid for BG scan */ + int max_offchannel_time; /* max time away from BSS channel, in ms */ + int repeat_probe_time; /* time before sending second probe request */ + int idle_time; /* time in msec on bss channel before switching channel */ + int max_scan_time; /* maximum time in msec allowed for scan */ + int probe_delay; /* delay in msec before sending probe request */ + int offchan_retry_delay; /* delay in msec before retrying off-channel switch */ + int min_beacon_count; /* number of home AP beacons to receive before leaving the home channel */ + int max_offchan_retries; /* maximum number of times to retry off-channel switch */ + int beacon_timeout; /* maximum time to wait for beacons */ + int flags; /* scan flags */ + int num_channels; /* number of channels to scan */ + bool multiple_ports_active; /* driver has multiple ports active in the home channel */ + bool restricted_scan; /* Perform restricted scan */ + bool chan_list_allocated; + IEEE80211_SCAN_PRIORITY p2p_scan_priority; /* indicates the scan priority if this is a P2P-related scan */ + u_int32_t *chan_list; /* array of ieee channels (or) frequencies to scan */ + int num_ssid; /* number of desired ssids */ + ieee80211_ssid ssid_list[IEEE80211_SCAN_PARAMS_MAX_SSID]; + int num_bssid; /* number of desired bssids */ + u_int8_t bssid_list[IEEE80211_SCAN_PARAMS_MAX_BSSID][IEEE80211_ADDR_LEN]; + struct ieee80211_node *bss_node; /* BSS node */ + int ie_len; /* length of the ie data to be added to probe req */ + u_int8_t *ie_data; /* pointer to ie data */ + ieee80211_scan_termination_check check_termination_function; /* function checking for termination condition */ + void *check_termination_context; /* context passed to function above */ +} ieee80211_scan_params; + +/* Data types used to specify scan priorities */ +typedef u_int32_t IEEE80211_PRIORITY_MAPPING[IEEE80211_SCAN_PRIORITY_COUNT]; + +/************************************** + * Called before attempting to roam. Modifies the rssiAdder of a BSS + * based on the preferred status of a BSS. + * + * According to CCX spec, AP in the neighbor list is not meant for giving extra + * weightage in roaming. By doing so, roaming becomes sticky. See bug 21220. + * Change the weightage to 0. Cisco may ask in future for a user control of + * this weightage. + */ +#define PREFERRED_BSS_RANK 20 +#define NEIGHBOR_BSS_RANK 0 /* must be less than preferred BSS rank */ + +/* + * The utility of the BSS is the metric used in the selection + * of a BSS. The Utility of the BSS is reduced if we just left the BSS. + * The Utility of the BSS is not reduced if we have left the + * BSS for 8 seconds (8000ms) or more. + * 2^13 milliseconds is a close approximation to avoid expensive division + */ +#define LAST_ASSOC_TIME_DELTA_REQUIREMENT (1 << 13) // 8192 + +#define QBSS_SCALE_MAX 255 /* Qbss channel load Max value */ +#define QBSS_SCALE_DOWN_FACTOR 2 /* scale factor to reduce Qbss channel load */ +#define QBSS_HYST_ADJ 60 /* Qbss Weightage factor for the current AP */ + +/* + * Flags used to set field APState + */ +#define AP_STATE_GOOD 0x00 +#define AP_STATE_BAD 0x01 +#define AP_STATE_RETRY 0x10 +#define BAD_AP_TIMEOUT 6000 // In milli seconds +/* + * To disable BAD_AP status check on any scan entry + */ +#define BAD_AP_TIMEOUT_DISABLED 0 + +/* + * BAD_AP timeout specified in seconds + */ +#define BAD_AP_TIMEOUT_IN_SECONDS 10 + +/* + * State values used to represent our assoc_state with ap (discrete, not bitmasks) + */ +#define AP_ASSOC_STATE_NONE 0 +#define AP_ASSOC_STATE_AUTH 1 +#define AP_ASSOC_STATE_ASSOC 2 + +/* + * Entries in the scan list are considered obsolete after 75 seconds. + */ +#define IEEE80211_SCAN_ENTRY_EXPIRE_TIME 75000 + +/* + * idle time is only valid for scan type IEEE80211_SCAN_BACKGROUND. + * if idle time is set then the scanner would change channel from BSS + * channel to foreign channel only if both resttime is expired and + * the theres was not traffic for idletime msec on the bss channel. + * value of 0 for idletime would cause the channel to switch from BSS + * channel to foreign channel as soon as the resttime is expired. + * + * if maxscantime is nonzero and if the scanner can not complete the + * scan in maxscantime msec then the scanner will cancel the scan and + * post IEEE80211_SCAN_COMPLETED event with reason SCAN_TIMEDOUT. + * + */ + +/* + * chanlist can be either ieee channels (or) frequencies. + * if a value is less than 1000 implementation assumes it + * as ieee channel # otherwise implementation assumes it + * as frequency in Mhz. + */ + +typedef enum _ieee80211_scan_event_type { + IEEE80211_SCAN_STARTED, + IEEE80211_SCAN_COMPLETED, + IEEE80211_SCAN_RADIO_MEASUREMENT_START, + IEEE80211_SCAN_RADIO_MEASUREMENT_END, + IEEE80211_SCAN_RESTARTED, + IEEE80211_SCAN_HOME_CHANNEL, + IEEE80211_SCAN_FOREIGN_CHANNEL, + IEEE80211_SCAN_BSSID_MATCH, + IEEE80211_SCAN_FOREIGN_CHANNEL_GET_NF, + IEEE80211_SCAN_DEQUEUED, + IEEE80211_SCAN_PREEMPTED, + + IEEE80211_SCAN_EVENT_COUNT +} ieee80211_scan_event_type; + +typedef enum ieee80211_scan_completion_reason { + IEEE80211_REASON_NONE, + IEEE80211_REASON_COMPLETED, + IEEE80211_REASON_CANCELLED, + IEEE80211_REASON_TIMEDOUT, + IEEE80211_REASON_TERMINATION_FUNCTION, + IEEE80211_REASON_MAX_OFFCHAN_RETRIES, + IEEE80211_REASON_PREEMPTED, + IEEE80211_REASON_RUN_FAILED, + IEEE80211_REASON_INTERNAL_STOP, + + IEEE80211_REASON_COUNT +} ieee80211_scan_completion_reason; + +typedef struct _ieee80211_scan_event { + ieee80211_scan_event_type type; + ieee80211_scan_completion_reason reason; + wlan_chan_t chan; + IEEE80211_SCAN_REQUESTOR requestor; /* Requestor ID passed to the scan_start function */ + IEEE80211_SCAN_ID scan_id; /* Specific ID of the scan reporting the event */ +} ieee80211_scan_event; + +typedef enum _ieee80211_scan_request_status { + IEEE80211_SCAN_STATUS_QUEUED, + IEEE80211_SCAN_STATUS_RUNNING, + IEEE80211_SCAN_STATUS_PREEMPTED, + IEEE80211_SCAN_STATUS_COMPLETED +} ieee80211_scan_request_status; + +/* + * the sentry field of tht ieee80211_scan_event is only valid if the + * event type is IEEE80211_SCAN_BSSID_MATCH. + */ + +typedef void (*ieee80211_scan_event_handler) (wlan_if_t vaphandle, ieee80211_scan_event *event, void *arg); + +typedef struct _ieee80211_scan_info { + ieee80211_scan_type type; + IEEE80211_SCAN_REQUESTOR requestor; /* Originator ID passed to the scan_start function */ + IEEE80211_SCAN_ID scan_id; /* Specific ID of the scan reporting the event */ + IEEE80211_SCAN_PRIORITY priority; /* Requested priority level (low/medium/high) */ + ieee80211_scan_request_status scheduling_status; /* Queued/running/preempted/completed */ + int min_dwell_time_active; /* min time in msec on active channels */ + int max_dwell_time_active; /* max time in msec on active channel (if no response) */ + int min_dwell_time_passive; /* min time in msec on passive channels */ + int max_dwell_time_passive; /* max time in msec on passive channel*/ + int min_rest_time; /* min time in msec on the BSS channel, only valid for BG scan */ + int max_rest_time; /* max time in msec on the BSS channel, only valid for BG scan */ + int max_offchannel_time; /* max time away from BSS channel, in ms */ + int repeat_probe_time; /* time before sending second probe request */ + int min_beacon_count; /* number of home AP beacons to receive before leaving the home channel */ + int flags; /* scan flags */ + systime_t scan_start_time; /* system time when last scani started */ + int scanned_channels; /* number of scanned channels */ + int default_channel_list_length; /* number of channels in the default channel list */ + int channel_list_length; /* number of channels in the channel list used for the current scan */ + u_int8_t in_progress : 1, /* if the scan is in progress */ + cancelled : 1, /* if the scan is cancelled */ + preempted : 1, /* if the scan is preempted */ + restricted : 1; /* if the scan is restricted */ +} ieee80211_scan_info; + +typedef struct _ieee80211_scan_request_info { + wlan_if_t vaphandle; + IEEE80211_SCAN_REQUESTOR requestor; + IEEE80211_SCAN_PRIORITY requested_priority; + IEEE80211_SCAN_PRIORITY absolute_priority; + IEEE80211_SCAN_ID scan_id; + ieee80211_scan_request_status scheduling_status; + ieee80211_scan_params params; + systime_t request_timestamp; + u_int32_t maximum_duration; +} ieee80211_scan_request_info; + +#endif /* EXTERNAL_USE_ONLY */ + +#ifndef EXTERNAL_USE_ONLY +typedef void (*ieee80211_acs_event_handler) (void *arg, wlan_chan_t channel); +#endif /* EXTERNAL_USE_ONLY */ + +#define MAX_CHAINS 3 + +typedef struct _wlan_rssi_info { + int8_t avg_rssi; /* average rssi */ + u_int8_t valid_mask; /* bitmap of valid elements in rssi_ctrl/ext array */ + int8_t rssi_ctrl[MAX_CHAINS]; + int8_t rssi_ext[MAX_CHAINS]; +} wlan_rssi_info; + +typedef enum _wlan_rssi_type { + WLAN_RSSI_TX, + WLAN_RSSI_RX, + WLAN_RSSI_BEACON, /* rssi of the beacon, only valid for STA/IBSS vap */ + WLAN_RSSI_RX_DATA +} wlan_rssi_type; + +typedef enum _ieee80211_rate_type { + IEEE80211_RATE_TYPE_LEGACY, + IEEE80211_RATE_TYPE_MCS, +} ieee80211_rate_type; + +typedef struct _ieee80211_rate_info { + ieee80211_rate_type type; + u_int32_t rate; /* average rate in kbps */ + u_int32_t lastrate; /* last packet rate in kbps */ + u_int8_t mcs; /* mcs index . is valid if rate type is MCS20 or MCS40 */ + u_int8_t maxrate_per_client; +} ieee80211_rate_info; + +typedef enum _ieee80211_node_param_type { + IEEE80211_NODE_PARAM_TX_POWER, + IEEE80211_NODE_PARAM_ASSOCID, + IEEE80211_NODE_PARAM_INACT, /* inactivity timer value */ + IEEE80211_NODE_PARAM_AUTH_MODE, /* auth mode */ + IEEE80211_NODE_PARAM_CAP_INFO, /* auth mode */ +} ieee80211_node_param_type; + +/* + * Per/node (station) statistics available when operating as an AP. + */ +struct ieee80211_nodestats { + u_int32_t ns_rx_data; /* rx data frames */ + u_int32_t ns_rx_mgmt; /* rx management frames */ + u_int32_t ns_rx_ctrl; /* rx control frames */ + u_int32_t ns_rx_ucast; /* rx unicast frames */ + u_int32_t ns_rx_mcast; /* rx multi/broadcast frames */ + u_int64_t ns_rx_bytes; /* rx data count (bytes) */ + u_int64_t ns_rx_beacons; /* rx beacon frames */ + u_int32_t ns_rx_proberesp; /* rx probe response frames */ + + u_int32_t ns_rx_dup; /* rx discard 'cuz dup */ + u_int32_t ns_rx_noprivacy; /* rx w/ wep but privacy off */ + u_int32_t ns_rx_wepfail; /* rx wep processing failed */ + u_int32_t ns_rx_demicfail; /* rx demic failed */ + + /* We log MIC and decryption failures against Transmitter STA stats. + Though the frames may not actually be sent by STAs corresponding + to TA, the stats are still valuable for some customers as a sort + of rough indication. + Also note that the mapping from TA to STA may fail sometimes. */ + u_int32_t ns_rx_tkipmic; /* rx TKIP MIC failure */ + u_int32_t ns_rx_ccmpmic; /* rx CCMP MIC failure */ + u_int32_t ns_rx_wpimic; /* rx WAPI MIC failure */ + u_int32_t ns_rx_tkipicv; /* rx ICV check failed (TKIP) */ + u_int32_t ns_rx_decap; /* rx decapsulation failed */ + u_int32_t ns_rx_defrag; /* rx defragmentation failed */ + u_int32_t ns_rx_disassoc; /* rx disassociation */ + u_int32_t ns_rx_deauth; /* rx deauthentication */ + u_int32_t ns_rx_action; /* rx action */ + u_int32_t ns_rx_decryptcrc; /* rx decrypt failed on crc */ + u_int32_t ns_rx_unauth; /* rx on unauthorized port */ + u_int32_t ns_rx_unencrypted; /* rx unecrypted w/ privacy */ + + u_int32_t ns_tx_data; /* tx data frames */ + u_int32_t ns_tx_data_success; /* tx data frames successfully + transmitted (unicast only) */ + u_int32_t ns_tx_mgmt; /* tx management frames */ + u_int32_t ns_tx_ucast; /* tx unicast frames */ + u_int32_t ns_tx_mcast; /* tx multi/broadcast frames */ + u_int64_t ns_tx_bytes; /* tx data count (bytes) */ + u_int64_t ns_tx_bytes_success; /* tx success data count - unicast only + (bytes) */ + u_int32_t ns_tx_probereq; /* tx probe request frames */ + u_int32_t ns_tx_uapsd; /* tx on uapsd queue */ + u_int32_t ns_tx_discard; /* tx dropped by NIC */ + + u_int32_t ns_tx_novlantag; /* tx discard 'cuz no tag */ + u_int32_t ns_tx_vlanmismatch; /* tx discard 'cuz bad tag */ + + u_int32_t ns_tx_eosplost; /* uapsd EOSP retried out */ + + u_int32_t ns_ps_discard; /* ps discard 'cuz of age */ + + u_int32_t ns_uapsd_triggers; /* uapsd triggers */ + u_int32_t ns_uapsd_duptriggers; /* uapsd duplicate triggers */ + u_int32_t ns_uapsd_ignoretriggers; /* uapsd duplicate triggers */ + u_int32_t ns_uapsd_active; /* uapsd duplicate triggers */ + u_int32_t ns_uapsd_triggerenabled; /* uapsd duplicate triggers */ + + + /* MIB-related state */ + u_int32_t ns_tx_assoc; /* [re]associations */ + u_int32_t ns_tx_assoc_fail; /* [re]association failures */ + u_int32_t ns_tx_auth; /* [re]authentications */ + u_int32_t ns_tx_auth_fail; /* [re]authentication failures*/ + u_int32_t ns_tx_deauth; /* deauthentications */ + u_int32_t ns_tx_deauth_code; /* last deauth reason */ + u_int32_t ns_tx_disassoc; /* disassociations */ + u_int32_t ns_tx_disassoc_code; /* last disassociation reason */ + u_int32_t ns_psq_drops; /* power save queue drops */ +}; + +/* + * station power save mode. + */ +typedef enum ieee80211_psmode { + IEEE80211_PWRSAVE_NONE = 0, /* no power save */ + IEEE80211_PWRSAVE_LOW, + IEEE80211_PWRSAVE_NORMAL, + IEEE80211_PWRSAVE_MAXIMUM, + IEEE80211_PWRSAVE_WNM /* WNM-Sleep Mode */ +} ieee80211_pwrsave_mode; + +/* station power save pspoll handling */ +typedef enum { + IEEE80211_CONTINUE_PSPOLL_FOR_MORE_DATA, + IEEE80211_WAKEUP_FOR_MORE_DATA, +} ieee80211_pspoll_moredata_handling; + +/* + * apps power save state. + */ +typedef enum { + APPS_AWAKE = 0, + APPS_PENDING_SLEEP, + APPS_SLEEP, + APPS_FAKE_SLEEP, /* Pending blocking sleep */ + APPS_FAKING_SLEEP, /* Blocking sleep */ + APPS_UNKNOWN_PWRSAVE, +} ieee80211_apps_pwrsave_state; + +typedef enum _iee80211_mimo_powersave_mode { + IEEE80211_MIMO_POWERSAVE_NONE, /* no mimo power save */ + IEEE80211_MIMO_POWERSAVE_STATIC, /* static mimo power save */ + IEEE80211_MIMO_POWERSAVE_DYNAMIC /* dynamic mimo powersave */ +} ieee80211_mimo_powersave_mode; + +#ifdef ATH_COALESCING +typedef enum _ieee80211_coalescing_state { + IEEE80211_COALESCING_DISABLED = 0, /* Coalescing is disabled*/ + IEEE80211_COALESCING_DYNAMIC = 1, /* Dynamically move to Enabled state based on Uruns*/ + IEEE80211_COALESCING_ENABLED = 2, /* Coalescing is enabled*/ +} ieee80211_coalescing_state; + +#define IEEE80211_TX_COALESCING_THRESHOLD 5 /* Number of underrun errors to trigger coalescing */ +#endif + +typedef enum _ieee80211_cap { + IEEE80211_CAP_SHSLOT, /* CAPABILITY: short slot */ + IEEE80211_CAP_SHPREAMBLE, /* CAPABILITY: short premable */ + IEEE80211_CAP_MULTI_DOMAIN, /* CAPABILITY: multiple domain */ + IEEE80211_CAP_WMM, /* CAPABILITY: WMM */ + IEEE80211_CAP_HT, /* CAPABILITY: HT */ + IEEE80211_CAP_PERF_PWR_OFLD, /* CAPABILITY: power performance offload support */ + IEEE80211_CAP_11AC, /* CAPABILITY: 11ac support */ +} ieee80211_cap; + +typedef enum _ieee80211_device_param { + IEEE80211_DEVICE_RSSI_CTL, + IEEE80211_DEVICE_NUM_TX_CHAIN, + IEEE80211_DEVICE_NUM_RX_CHAIN, + IEEE80211_DEVICE_TX_CHAIN_MASK, + IEEE80211_DEVICE_RX_CHAIN_MASK, + IEEE80211_DEVICE_TX_CHAIN_MASK_LEGACY, + IEEE80211_DEVICE_RX_CHAIN_MASK_LEGACY, + IEEE80211_DEVICE_BMISS_LIMIT, /* # of beacon misses for HW to generate BMISS intr */ + IEEE80211_DEVICE_PROTECTION_MODE, /* protection mode*/ + IEEE80211_DEVICE_BLKDFSCHAN, /* block the use of DFS channels */ + IEEE80211_DEVICE_GREEN_AP_PS_ENABLE, + IEEE80211_DEVICE_GREEN_AP_PS_TIMEOUT, + IEEE80211_DEVICE_GREEN_AP_PS_ON_TIME, + IEEE80211_DEVICE_CWM_EXTPROTMODE, + IEEE80211_DEVICE_CWM_EXTPROTSPACING, + IEEE80211_DEVICE_CWM_ENABLE, + IEEE80211_DEVICE_CWM_EXTBUSYTHRESHOLD, + IEEE80211_DEVICE_DOTH, + IEEE80211_DEVICE_ADDBA_MODE, + IEEE80211_DEVICE_COUNTRYCODE, + IEEE80211_DEVICE_MULTI_CHANNEL, /* turn on/off off channel support */ + IEEE80211_DEVICE_MAX_AMSDU_SIZE, /* Size of AMSDU to be sent on the air */ + IEEE80211_DEVICE_P2P, /* Enable or Disable P2P */ + IEEE80211_DEVICE_OVERRIDE_SCAN_PROBERESPONSE_IE, /* Override scan Probe response IE, 0: Don't over-ride */ + IEEE80211_DEVICE_2G_CSA, + IEEE80211_DEVICE_PWRTARGET, + IEEE80211_DEVICE_OFF_CHANNEL_SUPPORT, +} ieee80211_device_param; + +typedef enum _ieee80211_param { + IEEE80211_BEACON_INTVAL, /* in TUs */ + IEEE80211_LISTEN_INTVAL, /* number of beacons */ + IEEE80211_DTIM_INTVAL, /* number of beacons */ + IEEE80211_BMISS_COUNT_RESET, /* number of beacon miss intrs before reset */ + IEEE80211_BMISS_COUNT_MAX, /* number of beacon miss intrs for bmiss notificationst */ + IEEE80211_ATIM_WINDOW, /* ATIM window */ + IEEE80211_SHORT_SLOT, /* short slot on/off */ + IEEE80211_SHORT_PREAMBLE, /* short preamble on/off */ + IEEE80211_RTS_THRESHOLD, /* rts threshold, 0 means no rts threshold */ + IEEE80211_FRAG_THRESHOLD, /* fragmentation threshold, 0 means no rts threshold */ + IEEE80211_FIXED_RATE, /* + * rate code series(0: auto rate, 32 bit value: rate + * codes for 4 rate series. each byte for one rate series) + */ + IEEE80211_MCAST_RATE, /* rate in Kbps */ + IEEE80211_TXPOWER, /* in 0.5db units */ + IEEE80211_AMPDU_DENCITY, /* AMPDU dencity*/ + IEEE80211_AMPDU_LIMIT, /* AMPDU limit*/ + IEEE80211_MAX_AMPDU, /* Max AMPDU Exp*/ + IEEE80211_VHT_MAX_AMPDU, /* VHT Max AMPDU Exp */ + IEEE80211_WPS_MODE, /* WPS mode*/ + IEEE80211_TSN_MODE, /* TSN mode*/ + IEEE80211_MULTI_DOMAIN, /* Multiple domain */ + IEEE80211_SAFE_MODE, /* Safe mode */ + IEEE80211_NOBRIDGE_MODE, /* No bridging done, all frames sent up the stack */ + IEEE80211_PERSTA_KEYTABLE_SIZE, /* IBSS-only, read-only: persta key table size */ + IEEE80211_RECEIVE_80211, /* deliver std 802.11 frames 802.11 instead of ethernet frames on the rx */ + IEEE80211_SEND_80211, /* OS sends std 802.11 frames 802.11 instead of ethernet frames on tx side */ + IEEE80211_MIN_BEACON_COUNT, /* minumum number beacons to tx/rx before vap can pause */ + IEEE80211_IDLE_TIME, /* minimun no activity time before vap can pause */ + IEEE80211_MIN_FRAMESIZE, /* smallest frame size we are allowed to receive */ + /* features. 0:feature is off. 1:feature is on. */ + IEEE80211_FEATURE_WMM, /* WMM */ + IEEE80211_FEATURE_WMM_PWRSAVE, /* WMM Power Save */ + IEEE80211_FEATURE_UAPSD, /* UAPSD setting (BE/BK/VI/VO) */ + IEEE80211_FEATURE_WDS, /* dynamic WDS feature */ + IEEE80211_FEATURE_PRIVACY, /* encryption */ + IEEE80211_FEATURE_DROP_UNENC, /* drop un encrypted frames */ + IEEE80211_FEATURE_COUNTER_MEASURES , /* turn on couter measures */ + IEEE80211_FEATURE_HIDE_SSID, /* turn on hide ssid feature */ + IEEE80211_FEATURE_APBRIDGE, /* turn on internal mcast traffic bridging for AP */ + IEEE80211_FEATURE_PUREB, /* turn on pure B mode for AP */ + IEEE80211_FEATURE_PUREG, /* turn on pure G mode for AP */ + IEEE80211_FEATURE_REGCLASS, /* add regulatory class IE in AP */ + IEEE80211_FEATURE_COUNTRY_IE, /* add country IE for vap in AP */ + IEEE80211_FEATURE_IC_COUNTRY_IE, /* add country IE for ic in AP */ + IEEE80211_FEATURE_DOTH, /* enable 802.11h */ + IEEE80211_FEATURE_PURE11N, /* enable pure 11n mode */ + IEEE80211_FEATURE_PRIVATE_RSNIE, /* enable OS shim to setup RSN IE*/ + IEEE80211_FEATURE_COPY_BEACON, /* keep a copy of beacon */ + IEEE80211_FEATURE_PSPOLL, /* enable/disable pspoll mode in power save SM */ + IEEE80211_FEATURE_CONTINUE_PSPOLL_FOR_MOREDATA, /* enable/disable option to contunue sending ps polls when there is more data */ + IEEE80211_FEATURE_AMPDU, /* Enable or Disable Aggregation */ +#ifdef ATH_COALESCING + IEEE80211_FEATURE_TX_COALESCING, /* enable tx coalescing */ +#endif + IEEE80211_FEATURE_VAP_IND, /* Repeater independant VAP */ + IEEE80211_FIXED_RETRIES, /* fixed retries 0-4 */ + IEEE80211_SHORT_GI, /* short gi on/off */ + IEEE80211_HT40_INTOLERANT, + IEEE80211_CHWIDTH, + IEEE80211_CHEXTOFFSET, + IEEE80211_DISABLE_2040COEXIST, + IEEE80211_DISABLE_HTPROTECTION, + IEEE80211_STA_QUICKKICKOUT, + IEEE80211_CHSCANINIT, + IEEE80211_FEATURE_STAFWD, /* dynamic AP Client feature */ + IEEE80211_DRIVER_CAPS, + IEEE80211_UAPSD_MAXSP, /* UAPSD service period setting (0:unlimited, 2,4,6) */ + IEEE80211_WEP_MBSSID, + IEEE80211_MGMT_RATE, /* ieee rate to be used for management*/ + IEEE80211_RESMGR_VAP_AIR_TIME_LIMIT, /* When multi-channel enabled, restrict air-time allocated to a VAP */ + IEEE80211_TDLS_MACADDR1, /* Upper 4 bytes of device's MAC address */ + IEEE80211_TDLS_MACADDR2, /* Lower 2 bytes of device's MAC address */ + IEEE80211_TDLS_ACTION, /* TDLS action requested */ + IEEE80211_AUTO_ASSOC, + IEEE80211_PROTECTION_MODE, /* per VAP protection mode*/ + IEEE80211_AUTH_INACT_TIMEOUT, /* inactivity time while waiting for 802.11x auth to complete */ + IEEE80211_INIT_INACT_TIMEOUT, /* inactivity time while waiting for 802.11 auth/assoc to complete */ + IEEE80211_RUN_INACT_TIMEOUT, /* inactivity time when fully authed*/ + IEEE80211_PROBE_INACT_TIMEOUT, /* inactivity counter value below which starts probing */ + IEEE80211_QBSS_LOAD, + IEEE80211_WNM_CAP, + IEEE80211_WNM_BSS_CAP, + IEEE80211_WNM_TFS_CAP, + IEEE80211_WNM_TIM_CAP, + IEEE80211_WNM_SLEEP_CAP, + IEEE80211_WNM_FMS_CAP, + IEEE80211_AP_REJECT_DFS_CHAN, /* AP to reject resuming on DFS Channel */ + IEEE80211_ABOLT, + IEEE80211_COMP, + IEEE80211_FF, + IEEE80211_TURBO, + IEEE80211_BURST, + IEEE80211_AR, + IEEE80211_SLEEP, + IEEE80211_EOSPDROP, + IEEE80211_MARKDFS, + IEEE80211_WDS_AUTODETECT, + IEEE80211_WEP_TKIP_HT, + IEEE80211_ATH_RADIO, + IEEE80211_IGNORE_11DBEACON, + /* Video debug feature */ + IEEE80211_VI_DBG_CFG, /* Video debug configuration - Bit0- enable dbg, Bit1 - enable stats log */ + IEEE80211_VI_DBG_NUM_STREAMS, /* Total number of receive streams */ + IEEE80211_VI_STREAM_NUM, /* the stream number whose marker parameters are being set */ + IEEE80211_VI_DBG_NUM_MARKERS, /* total number of markers used to filter pkts */ + IEEE80211_VI_MARKER_NUM, /* the marker number whose parameters (offset, size & match) are being set */ + IEEE80211_VI_MARKER_OFFSET_SIZE, /* byte offset from skb start (upper 16 bits) & size in bytes(lower 16 bits) */ + IEEE80211_VI_MARKER_MATCH, /* marker pattern match used in filtering */ + IEEE80211_VI_RXSEQ_OFFSET_SIZE, /* Rx Seq num offset skb start (upper 16 bits) & size in bytes(lower 16 bits) */ + IEEE80211_VI_RX_SEQ_RSHIFT, /* right-shift value in case field is not word aligned */ + IEEE80211_VI_RX_SEQ_MAX, /* maximum Rx Seq number (to check wrap around) */ + IEEE80211_VI_RX_SEQ_DROP, /* Indicator to the debug app that a particular seq num has been dropped */ + IEEE80211_VI_TIME_OFFSET_SIZE, /* Timestamp offset skb start (upper 16 bits) & size in bytes(lower 16 bits) */ + IEEE80211_VI_RESTART, /* If set to 1 resets all internal variables/counters & restarts debug tool*/ + IEEE80211_VI_RXDROP_STATUS, /* Total RX drops in wireless */ + IEEE80211_TRIGGER_MLME_RESP, /* Option for App to trigger mlme response */ +#ifdef ATH_SUPPORT_TxBF + IEEE80211_TXBF_AUTO_CVUPDATE, /* auto CV update enable */ + IEEE80211_TXBF_CVUPDATE_PER, /* per threshold to initial CV update*/ +#endif + IEEE80211_MAX_CLIENT_NUMBERS, + IEEE80211_SMARTNET, + IEEE80211_FEATURE_MFP_TEST, /* MFP test */ + IEEE80211_WEATHER_RADAR, /* weather radar channel skip */ + IEEE80211_WEP_KEYCACHE, /* WEP KEYCACHE is enable */ + IEEE80211_SEND_DEAUTH, /* send deauth instead of disassoc while doing interface down */ + IEEE80211_SET_TXPWRADJUST, + IEEE80211_RRM_CAP, + IEEE80211_RRM_DEBUG, + IEEE80211_RRM_STATS, + IEEE80211_RRM_SLWINDOW, + IEEE80211_FEATURE_OFF_CHANNEL_SUPPORT, + IEEE80211_FIXED_VHT_MCS, /* VHT mcs index */ + IEEE80211_FIXED_NSS, /* Spatial Streams count */ + IEEE80211_SUPPORT_LDPC, /* LDPC Support */ + IEEE80211_SUPPORT_TX_STBC, /* TX STBC enable/disable */ + IEEE80211_SUPPORT_RX_STBC, /* RX STBC enable/disable */ + IEEE80211_DEFAULT_KEYID, /* XMIT default key */ + IEEE80211_OPMODE_NOTIFY_ENABLE, /* Op mode notification enable/disable */ + IEEE80211_ENABLE_RTSCTS, /* Enable/Disable RTS-CTS */ + IEEE80211_VHT_MCSMAP, /* VHT MCS Map */ + IEEE80211_GET_ACS_STATE, /* get acs state */ + IEEE80211_GET_CAC_STATE, /* get cac state */ +} ieee80211_param; + +#define IEEE80211_PROTECTION_NONE 0 +#define IEEE80211_PROTECTION_CTSTOSELF 1 +#define IEEE80211_PROTECTION_RTS_CTS 2 + +typedef enum _ieee80211_privacy_filter { + IEEE80211_PRIVACY_FILTER_ALLWAYS, + IEEE80211_PRIVACY_FILTER_KEY_UNAVAILABLE, +} ieee80211_privacy_filter ; + +typedef enum _ieee80211_privacy_filter_packet_type { + IEEE80211_PRIVACY_FILTER_PACKET_UNICAST, + IEEE80211_PRIVACY_FILTER_PACKET_MULTICAST, + IEEE80211_PRIVACY_FILTER_PACKET_BOTH +} ieee80211_privacy_filter_packet_type ; + +typedef struct _ieee80211_privacy_excemption_filter { + u_int16_t ether_type; /* type of ethernet to apply this filter, in host byte order*/ + ieee80211_privacy_filter filter_type; + ieee80211_privacy_filter_packet_type packet_type; +} ieee80211_privacy_exemption; + +/* + * Authentication mode. + * NB: the usage of auth modes NONE, AUTO are deprecated, + * they are implemented through combinations of other auth modes + * and cipher types. The deprecated values are preserved here to + * maintain binary compatibility with applications like + * wpa_supplicant and hostapd. + */ +typedef enum _ieee80211_auth_mode { + IEEE80211_AUTH_NONE = 0, /* deprecated */ + IEEE80211_AUTH_OPEN = 1, /* open */ + IEEE80211_AUTH_SHARED = 2, /* shared-key */ + IEEE80211_AUTH_8021X = 3, /* 802.1x */ + IEEE80211_AUTH_AUTO = 4, /* deprecated */ + IEEE80211_AUTH_WPA = 5, /* WPA */ + IEEE80211_AUTH_RSNA = 6, /* WPA2/RSNA */ + IEEE80211_AUTH_CCKM = 7, /* CCK */ + IEEE80211_AUTH_WAPI = 8, /* WAPI */ +} ieee80211_auth_mode; + +#define IEEE80211_AUTH_MAX (IEEE80211_AUTH_WAPI+1) + +/* + * Cipher types. + * NB: The values are preserved here to maintain binary compatibility + * with applications like wpa_supplicant and hostapd. + */ +typedef enum _ieee80211_cipher_type { + IEEE80211_CIPHER_WEP = 0, + IEEE80211_CIPHER_TKIP = 1, + IEEE80211_CIPHER_AES_OCB = 2, + IEEE80211_CIPHER_AES_CCM = 3, + IEEE80211_CIPHER_WAPI = 4, + IEEE80211_CIPHER_CKIP = 5, + IEEE80211_CIPHER_AES_CMAC = 6, + IEEE80211_CIPHER_NONE = 7, +} ieee80211_cipher_type; + +#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) + +/* key direction */ +typedef enum _ieee80211_key_direction { + IEEE80211_KEY_DIR_TX, + IEEE80211_KEY_DIR_RX, + IEEE80211_KEY_DIR_BOTH +} ieee80211_key_direction; + +#define IEEE80211_KEYIX_NONE ((u_int16_t) -1) + +typedef struct _ieee80211_keyval { + ieee80211_cipher_type keytype; + ieee80211_key_direction keydir; + u_int persistent:1, /* persistent key */ + mfp:1; /* management frame protection */ + u_int16_t keylen; /* length of the key data fields */ + u_int8_t *macaddr; /* mac address of length IEEE80211_ADDR_LEN . all bytes are 0xff for multicast key */ + u_int64_t keyrsc; + u_int64_t keytsc; + u_int16_t txmic_offset; /* TKIP/SMS4 only: offset to tx mic key */ + u_int16_t rxmic_offset; /* TKIP/SMS4 only: offset to rx mic key */ + u_int8_t *keydata; +#ifdef ATH_SUPPORT_WAPI + u_int8_t key_used; /*index for WAPI rekey labeling*/ +#endif +} ieee80211_keyval; + +#define IEEE80211_AES_CMAC_LEN 128 +typedef enum _ieee80211_rsn_param { + IEEE80211_UCAST_CIPHER_LEN, + IEEE80211_MCAST_CIPHER_LEN, + IEEE80211_MCASTMGMT_CIPHER_LEN, + IEEE80211_KEYMGT_ALGS, + IEEE80211_RSN_CAPS +} ieee80211_rsn_param; + +#define IEEE80211_PMKID_LEN 16 + +typedef struct _ieee80211_pmkid_entry { + u_int8_t bssid[IEEE80211_ADDR_LEN]; + u_int8_t pmkid[IEEE80211_PMKID_LEN]; +} ieee80211_pmkid_entry; + +typedef enum _wlan_wme_param { + WLAN_WME_CWMIN, + WLAN_WME_CWMAX, + WLAN_WME_AIFS, + WLAN_WME_TXOPLIMIT, + WLAN_WME_ACM, /*bss only*/ + WLAN_WME_ACKPOLICY /*bss only*/ +} wlan_wme_param; + +typedef enum _ieee80211_frame_type { + IEEE80211_FRAME_TYPE_PROBEREQ, + IEEE80211_FRAME_TYPE_BEACON, + IEEE80211_FRAME_TYPE_PROBERESP, + IEEE80211_FRAME_TYPE_ASSOCREQ, + IEEE80211_FRAME_TYPE_ASSOCRESP, + IEEE80211_FRAME_TYPE_AUTH +} ieee80211_frame_type; + +#define IEEE80211_FRAME_TYPE_MAX (IEEE80211_FRAME_TYPE_AUTH+1) + +typedef enum _ieee80211_ampdu_mode { + IEEE80211_AMPDU_MODE_OFF, /* disable AMPDU */ + IEEE80211_AMPDU_MODE_ON, /* enable AMPDU */ + IEEE80211_AMPDU_MODE_WDSVAR /* enable AMPDU with 4addr WAR */ +} ieee80211_ampdu_mode; + +typedef enum _ieee80211_reset_type { + IEEE80211_RESET_TYPE_DEVICE = 0, /* device reset on error: tx timeout and etc. */ + IEEE80211_RESET_TYPE_DOT11_INTF, /* dot11 reset: only reset one network interface (vap) */ + IEEE80211_RESET_TYPE_INTERNAL, /* internal reset */ +} ieee80211_reset_type; + +typedef struct _ieee80211_reset_request { + ieee80211_reset_type type; + + u_int reset_hw:1, /* reset the actual H/W */ + /* + * The following fields are only valid for DOT11 reset, i.e., + * IEEE80211_RESET_TYPE_DOT11_INTF + */ + reset_phy:1, /* reset PHY */ + reset_mac:1, /* reset MAC */ + set_default_mib:1, /* set default MIB variables */ + no_flush:1; + u_int8_t macaddr[IEEE80211_ADDR_LEN]; + enum ieee80211_phymode phy_mode; +} ieee80211_reset_request; + +#define IEEE80211_MSG_MAX 63 +#define IEEE80211_MSG_SMARTANT 7 /* Bit 7 (0x80)for Smart Antenna debug */ +enum { + /* IEEE80211_PARAM_DBG_LVL */ + IEEE80211_MSG_TDLS = 0, /* TDLS */ + IEEE80211_MSG_ACS, /* auto channel selection */ + IEEE80211_MSG_SCAN_SM, /* scan state machine */ + IEEE80211_MSG_SCANENTRY, /* scan entry */ + IEEE80211_MSG_WDS, /* WDS handling */ + IEEE80211_MSG_ACTION, /* action management frames */ + IEEE80211_MSG_ROAM, /* sta-mode roaming */ + IEEE80211_MSG_INACT, /* inactivity handling */ + IEEE80211_MSG_DOTH = 8, /* 11.h */ + IEEE80211_MSG_IQUE, /* IQUE features */ + IEEE80211_MSG_WME, /* WME protocol */ + IEEE80211_MSG_ACL, /* ACL handling */ + IEEE80211_MSG_WPA, /* WPA/RSN protocol */ + IEEE80211_MSG_RADKEYS, /* dump 802.1x keys */ + IEEE80211_MSG_RADDUMP, /* dump 802.1x radius packets */ + IEEE80211_MSG_RADIUS, /* 802.1x radius client */ + IEEE80211_MSG_DOT1XSM = 16, /* 802.1x state machine */ + IEEE80211_MSG_DOT1X, /* 802.1x authenticator */ + IEEE80211_MSG_POWER, /* power save handling */ + IEEE80211_MSG_STATE, /* state machine */ + IEEE80211_MSG_OUTPUT, /* output handling */ + IEEE80211_MSG_SCAN, /* scanning */ + IEEE80211_MSG_AUTH, /* authentication handling */ + IEEE80211_MSG_ASSOC, /* association handling */ + IEEE80211_MSG_NODE = 24, /* node handling */ + IEEE80211_MSG_ELEMID, /* element id parsing */ + IEEE80211_MSG_XRATE, /* rate set handling */ + IEEE80211_MSG_INPUT, /* input handling */ + IEEE80211_MSG_CRYPTO, /* crypto work */ + IEEE80211_MSG_DUMPPKTS, /* IFF_LINK2 equivalant */ + IEEE80211_MSG_DEBUG, /* IFF_DEBUG equivalent */ + IEEE80211_MSG_MLME, /* MLME */ + /* IEEE80211_PARAM_DBG_LVL_HIGH */ + IEEE80211_MSG_RRM = 32, /* Radio resource measurement */ + IEEE80211_MSG_WNM, /* Wireless Network Management */ + IEEE80211_MSG_P2P_PROT, /* P2P Protocol driver */ + IEEE80211_MSG_PROXYARP, /* 11v Proxy ARP */ + IEEE80211_MSG_L2TIF, /* Hotspot 2.0 L2 TIF */ + IEEE80211_MSG_WIFIPOS, /* WifiPositioning Feature */ + IEEE80211_MSG_WRAP, /* WRAP or Wireless ProxySTA */ + IEEE80211_MSG_DFS, /* DFS debug mesg */ + + IEEE80211_MSG_NUM_CATEGORIES, /* total ieee80211 messages */ + IEEE80211_MSG_UNMASKABLE = IEEE80211_MSG_MAX, /* anything */ + IEEE80211_MSG_ANY = IEEE80211_MSG_MAX, /* anything */ +}; + +/* verbosity levels */ +#define IEEE80211_VERBOSE_OFF 100 +#define IEEE80211_VERBOSE_FORCE 1 +#define IEEE80211_VERBOSE_SERIOUS 2 +#define IEEE80211_VERBOSE_NORMAL 3 +#define IEEE80211_VERBOSE_LOUD 4 +#define IEEE80211_VERBOSE_DETAILED 5 +#define IEEE80211_VERBOSE_COMPLEX 6 +#define IEEE80211_VERBOSE_FUNCTION 7 +#define IEEE80211_VERBOSE_TRACE 8 + +#define IEEE80211_DEBUG_DEFAULT IEEE80211_MSG_DEBUG + +/* + * the lower 4 bits of the msg flags are used for extending the + * debug flags. + */ + +/* + * flag defintions for wlan_mlme_stop_bss(vap) API. + */ +#define WLAN_MLME_STOP_BSS_F_SEND_DEAUTH 0x01 +#define WLAN_MLME_STOP_BSS_F_CLEAR_ASSOC_STATE 0x02 +#define WLAN_MLME_STOP_BSS_F_FORCE_STOP_RESET 0x04 +#define WLAN_MLME_STOP_BSS_F_WAIT_RX_DONE 0x08 +#define WLAN_MLME_STOP_BSS_F_NO_RESET 0x10 +#define WLAN_MLME_STOP_BSS_F_STANDBY 0x20 + +/* + * WAPI commands to authenticator + */ +#define WAPI_WAI_REQUEST (u_int16_t)0x00F1 +#define WAPI_UNICAST_REKEY (u_int16_t)0x00F2 +#define WAPI_STA_AGING (u_int16_t)0x00F3 +#define WAPI_MULTI_REKEY (u_int16_t)0x00F4 +#define WAPI_STA_STATS (u_int16_t)0x00F5 + +/* + * IEEE80211 PHY Statistics. + */ +struct ieee80211_phy_stats { + u_int64_t ips_tx_packets; /* frames successfully transmitted */ + u_int64_t ips_tx_multicast; /* multicast/broadcast frames successfully transmitted */ + u_int64_t ips_tx_fragments; /* fragments successfully transmitted */ + u_int64_t ips_tx_xretries; /* frames that are xretried. NB: not number of retries */ + u_int64_t ips_tx_retries; /* frames transmitted after retries. NB: not number of retries */ + u_int64_t ips_tx_multiretries; /* frames transmitted after more than one retry. */ + u_int64_t ips_tx_timeout; /* frames that expire the dot11MaxTransmitMSDULifetime */ + u_int64_t ips_rx_packets; /* frames successfully received */ + u_int64_t ips_rx_multicast; /* multicast/broadcast frames successfully received */ + u_int64_t ips_rx_fragments; /* fragments successfully received */ + u_int64_t ips_rx_timeout; /* frmaes that expired the dot11MaxReceiveLifetime */ + u_int64_t ips_rx_dup; /* duplicated fragments */ + u_int64_t ips_rx_mdup; /* multiple duplicated fragments */ + u_int64_t ips_rx_promiscuous; /* frames that are received only because promiscuous filter is on */ + u_int64_t ips_rx_promiscuous_fragments; /* fragments that are received only because promiscuous filter is on */ + u_int64_t ips_tx_rts; /* RTS success count */ + u_int64_t ips_tx_shortretry; /* tx on-chip retries (short). RTSFailCnt */ + u_int64_t ips_tx_longretry; /* tx on-chip retries (long). DataFailCnt */ + u_int64_t ips_rx_crcerr; /* rx failed 'cuz of bad CRC */ + u_int64_t ips_rx_fifoerr; /* rx failed 'cuz of FIFO overrun */ + u_int64_t ips_rx_decrypterr; /* rx decryption error */ +}; + +struct ieee80211_chan_stats { + u_int32_t chan_clr_cnt; + u_int32_t cycle_cnt; + u_int32_t phy_err_cnt; +}; + +struct ieee80211_mac_stats { + u_int64_t ims_tx_packets; /* frames successfully transmitted */ + u_int64_t ims_rx_packets; /* frames successfully received */ + u_int64_t ims_tx_bytes; /* bytes successfully transmitted */ + u_int64_t ims_rx_bytes; /* bytes successfully received */ + + /* TODO: For the byte counts below, we need to handle some scenarios + such as encryption related decaps, etc */ + u_int64_t ims_tx_data_packets;/* data frames successfully transmitted */ + u_int64_t ims_rx_data_packets;/* data frames successfully received */ + u_int64_t ims_tx_data_bytes; /* data bytes successfully transmitted, + inclusive of FCS. */ + u_int64_t ims_rx_data_bytes; /* data bytes successfully received, + inclusive of FCS. */ + + u_int64_t ims_tx_datapyld_bytes; /* data payload bytes successfully + transmitted */ + u_int64_t ims_rx_datapyld_bytes; /* data payload successfully + received */ + + /* Decryption errors */ + u_int64_t ims_rx_unencrypted; /* rx w/o wep and privacy on */ + u_int64_t ims_rx_badkeyid; /* rx w/ incorrect keyid */ + u_int64_t ims_rx_decryptok; /* rx decrypt okay */ + u_int64_t ims_rx_decryptcrc; /* rx decrypt failed on crc */ + u_int64_t ims_rx_wepfail; /* rx wep processing failed */ + u_int64_t ims_rx_tkipreplay; /* rx seq# violation (TKIP) */ + u_int64_t ims_rx_tkipformat; /* rx format bad (TKIP) */ + u_int64_t ims_rx_tkipmic; /* rx MIC check failed (TKIP) */ + u_int64_t ims_rx_tkipicv; /* rx ICV check failed (TKIP) */ + u_int64_t ims_rx_ccmpreplay; /* rx seq# violation (CCMP) */ + u_int64_t ims_rx_ccmpformat; /* rx format bad (CCMP) */ + u_int64_t ims_rx_ccmpmic; /* rx MIC check failed (CCMP) */ +/*this file can be included by applications as 80211stats that has no such MACRO definition*/ +//#if ATH_SUPPORT_WAPI + u_int64_t ims_rx_wpireplay; /* rx seq# violation (WPI) */ + u_int64_t ims_rx_wpimic; /* rx MIC check failed (WPI) */ +//#endif + /* Other Tx/Rx errors */ + u_int64_t ims_tx_discard; /* tx dropped by NIC */ + u_int64_t ims_rx_discard; /* rx dropped by NIC */ + + u_int64_t ims_rx_countermeasure; /* rx TKIP countermeasure activation count */ +}; + +/* + * Summary statistics. + */ +struct ieee80211_stats { + u_int32_t is_rx_badversion; /* rx frame with bad version */ + u_int32_t is_rx_tooshort; /* rx frame too short */ + u_int32_t is_rx_wrongbss; /* rx from wrong bssid */ + u_int32_t is_rx_wrongdir; /* rx w/ wrong direction */ + u_int32_t is_rx_mcastecho; /* rx discard 'cuz mcast echo */ + u_int32_t is_rx_notassoc; /* rx discard 'cuz sta !assoc */ + u_int32_t is_rx_noprivacy; /* rx w/ wep but privacy off */ + u_int32_t is_rx_decap; /* rx decapsulation failed */ + u_int32_t is_rx_mgtdiscard; /* rx discard mgt frames */ + u_int32_t is_rx_ctl; /* rx discard ctrl frames */ + u_int32_t is_rx_beacon; /* rx beacon frames */ + u_int32_t is_rx_rstoobig; /* rx rate set truncated */ + u_int32_t is_rx_elem_missing; /* rx required element missing*/ + u_int32_t is_rx_elem_toobig; /* rx element too big */ + u_int32_t is_rx_elem_toosmall; /* rx element too small */ + u_int32_t is_rx_elem_unknown; /* rx element unknown */ + u_int32_t is_rx_badchan; /* rx frame w/ invalid chan */ + u_int32_t is_rx_chanmismatch; /* rx frame chan mismatch */ + u_int32_t is_rx_nodealloc; /* rx frame dropped */ + u_int32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */ + u_int32_t is_rx_auth_unsupported; /* rx w/ unsupported auth alg */ + u_int32_t is_rx_auth_fail; /* rx sta auth failure */ + u_int32_t is_rx_auth_countermeasures;/* rx auth discard 'cuz CM */ + u_int32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */ + u_int32_t is_rx_assoc_notauth; /* rx assoc w/o auth */ + u_int32_t is_rx_assoc_capmismatch; /* rx assoc w/ cap mismatch */ + u_int32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */ + u_int32_t is_rx_assoc_badwpaie; /* rx assoc w/ bad WPA IE */ + u_int32_t is_rx_deauth; /* rx deauthentication */ + u_int32_t is_rx_disassoc; /* rx disassociation */ + u_int32_t is_rx_action; /* rx action mgt */ + u_int32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/ + u_int32_t is_rx_nobuf; /* rx failed for lack of buf */ + u_int32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/ + u_int32_t is_rx_bad_auth; /* rx bad auth request */ + u_int32_t is_rx_unauth; /* rx on unauthorized port */ + u_int32_t is_rx_badcipher; /* rx failed 'cuz key type */ + u_int32_t is_tx_nodefkey; /* tx failed 'cuz no defkey */ + u_int32_t is_tx_noheadroom; /* tx failed 'cuz no space */ + u_int32_t is_rx_nocipherctx; /* rx failed 'cuz key !setup */ + u_int32_t is_rx_acl; /* rx discard 'cuz acl policy */ + u_int32_t is_rx_ffcnt; /* rx fast frames */ + u_int32_t is_rx_badathtnl; /* driver key alloc failed */ + u_int32_t is_rx_nowds; /* 4-addr packets received with no wds enabled */ + u_int32_t is_tx_nobuf; /* tx failed for lack of buf */ + u_int32_t is_tx_nonode; /* tx failed for no node */ + u_int32_t is_tx_unknownmgt; /* tx of unknown mgt frame */ + u_int32_t is_tx_badcipher; /* tx failed 'cuz key type */ + u_int32_t is_tx_ffokcnt; /* tx fast frames sent success */ + u_int32_t is_tx_fferrcnt; /* tx fast frames sent success */ + u_int32_t is_scan_active; /* active scans started */ + u_int32_t is_scan_passive; /* passive scans started */ + u_int32_t is_node_timeout; /* nodes timed out inactivity */ + u_int32_t is_crypto_nomem; /* no memory for crypto ctx */ + u_int32_t is_crypto_tkip; /* tkip crypto done in s/w */ + u_int32_t is_crypto_tkipenmic; /* tkip en-MIC done in s/w */ + u_int32_t is_crypto_tkipdemic; /* tkip de-MIC done in s/w */ + u_int32_t is_crypto_tkipcm; /* tkip counter measures */ + u_int32_t is_crypto_ccmp; /* ccmp crypto done in s/w */ + u_int32_t is_crypto_wep; /* wep crypto done in s/w */ + u_int32_t is_crypto_setkey_cipher; /* cipher rejected key */ + u_int32_t is_crypto_setkey_nokey; /* no key index for setkey */ + u_int32_t is_crypto_delkey; /* driver key delete failed */ + u_int32_t is_crypto_badcipher; /* unknown cipher */ + u_int32_t is_crypto_nocipher; /* cipher not available */ + u_int32_t is_crypto_attachfail; /* cipher attach failed */ + u_int32_t is_crypto_swfallback; /* cipher fallback to s/w */ + u_int32_t is_crypto_keyfail; /* driver key alloc failed */ + u_int32_t is_crypto_enmicfail; /* en-MIC failed */ + u_int32_t is_ibss_capmismatch; /* merge failed-cap mismatch */ + u_int32_t is_ibss_norate; /* merge failed-rate mismatch */ + u_int32_t is_ps_unassoc; /* ps-poll for unassoc. sta */ + u_int32_t is_ps_badaid; /* ps-poll w/ incorrect aid */ + u_int32_t is_ps_qempty; /* ps-poll w/ nothing to send */ +}; + +typedef enum _ieee80211_send_frame_type { + IEEE80211_SEND_NULL, + IEEE80211_SEND_QOSNULL, +} ieee80211_send_frame_type; + +typedef struct _ieee80211_tspec_info { + u_int8_t traffic_type; + u_int8_t direction; + u_int8_t dot1Dtag; + u_int8_t tid; + u_int8_t acc_policy_edca; + u_int8_t acc_policy_hcca; + u_int8_t aggregation; + u_int8_t psb; + u_int8_t ack_policy; + u_int16_t norminal_msdu_size; + u_int16_t max_msdu_size; + u_int32_t min_srv_interval; + u_int32_t max_srv_interval; + u_int32_t inactivity_interval; + u_int32_t suspension_interval; + u_int32_t srv_start_time; + u_int32_t min_data_rate; + u_int32_t mean_data_rate; + u_int32_t peak_data_rate; + u_int32_t max_burst_size; + u_int32_t delay_bound; + u_int32_t min_phy_rate; + u_int16_t surplus_bw; + u_int16_t medium_time; +} ieee80211_tspec_info; + +#ifndef EXTERNAL_USE_ONLY +/* + * Manual ADDBA support + */ +enum { + ADDBA_SEND = 0, + ADDBA_STATUS = 1, + DELBA_SEND = 2, + ADDBA_RESP = 3, + ADDBA_CLR_RESP = 4, + SINGLE_AMSDU = 5, +}; + +enum { + ADDBA_MODE_AUTO = 0, + ADDBA_MODE_MANUAL = 1, +}; + +struct ieee80211_addba_delba_request { + wlan_dev_t ic; + u_int8_t action; + u_int8_t tid; + u_int16_t status; + u_int16_t aid; + u_int32_t arg1; + u_int32_t arg2; +}; +#endif /* EXTERNAL_USE_ONLY */ + +#ifdef ATH_BT_COEX +typedef enum _ieee80211_bt_coex_info_type { + IEEE80211_BT_COEX_INFO_SCHEME = 0, + IEEE80211_BT_COEX_INFO_BTBUSY = 1, +} ieee80211_bt_coex_info_type; +#endif + +struct tkip_countermeasure { + u_int16_t mic_count_in_60s; + u_int32_t timestamp; +} ; + +enum _ieee80211_qos_frame_direction { + IEEE80211_RX_QOS_FRAME = 0, + IEEE80211_TX_QOS_FRAME = 1, + IEEE80211_TX_COMPLETE_QOS_FRAME = 2 +}; + +typedef struct ieee80211_vap_opmode_count { + int total_vaps; + int ibss_count; + int sta_count; + int wds_count; + int ahdemo_count; + int ap_count; + int monitor_count; + int btamp_count; + int unknown_count; +} ieee80211_vap_opmode_count; + +struct ieee80211_app_ie_t { + u_int32_t length; + u_int8_t *ie; +}; + +/* + * MAC ACL operations. + */ +enum { + IEEE80211_MACCMD_POLICY_OPEN = 0, /* set policy: no ACL's */ + IEEE80211_MACCMD_POLICY_ALLOW = 1, /* set policy: allow traffic */ + IEEE80211_MACCMD_POLICY_DENY = 2, /* set policy: deny traffic */ + IEEE80211_MACCMD_FLUSH = 3, /* flush ACL database */ + IEEE80211_MACCMD_DETACH = 4, /* detach ACL policy */ + IEEE80211_MACCMD_POLICY_RADIUS = 5, /* set policy: RADIUS managed ACLs */ +}; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/if_upperproto.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/if_upperproto.h new file mode 100644 index 0000000000000..7f178470ee6ac --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/if_upperproto.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +//#ifndef _NET_IF_ETHERSUBR_H_ +//#define _NET_IF_ETHERSUBR_H_ +#ifndef _NET_IF_UPPERPROTO_H_ +#define _NET_IF_UPPERPROTO_H_ + +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ +#define ETHER_TYPE_LEN 2 /* length of the Ethernet type field */ +#define ETHER_CRC_LEN 4 /* length of the Ethernet CRC */ +#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) +#define ETHER_MAX_LEN 1518 + +#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN) + +/* + * Structure of a 10Mb/s Ethernet header. + */ +#ifndef _NET_ETHERNET_H_ +struct ether_header { + u_int8_t ether_dhost[ETHER_ADDR_LEN]; + u_int8_t ether_shost[ETHER_ADDR_LEN]; + u_int16_t ether_type; +} __packed; +#endif +#ifndef _LINUX_IF_VLAN_H_ +struct vlan_hdr { + u_int16_t h_vlan_TCI; + u_int16_t h_vlan_encapsulated_proto; +} __packed; +#define VLAN_VID_MASK 0xfff +#endif + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif +#ifndef ETHERTYPE_AARP +#define ETHERTYPE_AARP 0x80f3 /* Appletalk AARP protocol */ +#endif +#ifndef ETHERTYPE_IPX +#define ETHERTYPE_IPX 0x8137 /* IPX over DIX protocol */ +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* ARP protocol */ +#endif +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86dd /* IPv6 */ +#endif +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 /* 802.1Q vlan protocol */ +#endif +#ifndef ETHERTYPE_VLAN +#define ETHERTYPE_VLAN 0x8100 /* VLAN TAG protocol */ +#endif +#ifndef TX_QUEUE_FOR_EAPOL_FRAME +#define TX_QUEUE_FOR_EAPOL_FRAME 0x7 /* queue eapol frame to queue 7 to avoid aggregation disorder */ +#endif + +/* + * define WAI ethertype + */ +#ifndef ETHERTYPE_WAI +#define ETHERTYPE_WAI 0x88b4 /* WAI/WAPI */ +#endif + +/* + * Structure of a 48-bit Ethernet address. + */ +#if 0 +#ifndef _NET_ETHERNET_H_ +struct ether_addr { + u_int8_t octet[ETHER_ADDR_LEN]; +} __packed; +#endif +#endif + +#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ + +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */ +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */ + +/* + * Structure of the IP frame + */ +struct ip_header { + u_int8_t version_ihl; + u_int8_t tos; + u_int16_t tot_len; + u_int16_t id; + u_int16_t frag_off; + u_int8_t ttl; + u_int8_t protocol; + u_int16_t check; + u_int32_t saddr; + u_int32_t daddr; + /*The options start here. */ +}; +#ifndef IP_PROTO_TCP +#define IP_PROTO_TCP 0x6 /* TCP protocol */ +#endif +#ifndef IP_PROTO_UDP +#define IP_PROTO_UDP 17 +#endif + +/* + * IGMP protocol structures + */ + +/* IGMP record type */ +#define IGMP_QUERY_TYPE 0x11 +#define IGMPV1_REPORT_TYPE 0x12 +#define IGMPV2_REPORT_TYPE 0x16 +#define IGMPV2_LEAVE_TYPE 0x17 +#define IGMPV3_REPORT_TYPE 0x22 + +/* Is packet type is either leave or report */ +#define IS_IGMP_REPORT_LEAVE_PACKET(type) (\ + (IGMPV1_REPORT_TYPE == type)\ + || (IGMPV2_REPORT_TYPE == type)\ + || (IGMPV2_LEAVE_TYPE == type)\ + || (IGMPV3_REPORT_TYPE == type)\ + ) +/* + * Header in on cable format + */ + +struct igmp_header +{ + u_int8_t type; + u_int8_t code; /* For newer IGMP */ + u_int16_t csum; + u_int32_t group; +}; + +/* V3 group record types [grec_type] */ +#define IGMPV3_MODE_IS_INCLUDE 1 +#define IGMPV3_MODE_IS_EXCLUDE 2 +#define IGMPV3_CHANGE_TO_INCLUDE 3 +#define IGMPV3_CHANGE_TO_EXCLUDE 4 +#define IGMPV3_ALLOW_NEW_SOURCES 5 +#define IGMPV3_BLOCK_OLD_SOURCES 6 + +/* Group record format + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Record Type | Aux Data Len | Number of Sources (N) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Multicast Address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Source Address [1] | + +- -+ + | Source Address [2] | + +- -+ + . . . + . . . + . . . + +- -+ + | Source Address [N] | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . . + . Auxiliary Data . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct igmp_v3_grec { + u_int8_t grec_type; + u_int8_t grec_auxwords; + u_int16_t grec_nsrcs; + u_int32_t grec_mca; +}; + +/* IGMPv3 report format + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type = 0x22 | Reserved | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | Number of Group Records (M) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . . + . Group Record [1] . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . . + . Group Record [2] . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | . | + . . . + | . | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . . + . Group Record [M] . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct igmp_v3_report { + u_int8_t type; + u_int8_t resv1; + u_int16_t csum; + u_int16_t resv2; + u_int16_t ngrec; +}; + +/* Calculate the group record length*/ +#define IGMPV3_GRP_REC_LEN(x) (8 + (4 * x->grec_nsrcs) + (4 * x->grec_auxwords) ) + +#endif /* _NET_IF_ETHERSUBR_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ip_prot.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ip_prot.h new file mode 100644 index 0000000000000..6b72caa046eb5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ip_prot.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _IP_PROT__H_ +#define _IP_PROT__H_ + + +#define IP_PROTOCOL_ICMP 0x01 /* Internet Control Message Protocol */ +#define IP_PROTOCOL_IGMP 0x02 /* Internet Group Management Protocol */ +#define IP_PROTOCOL_IPV4 0x04 /* IPv4 (encapsulation) */ +#define IP_PROTOCOL_TCP 0x06 /* Transmission Control Protocol */ +#define IP_PROTOCOL_UDP 0x11 /* User Datagram Protocol */ +#define IP_PROTOCOL_RDP 0x1B /* Reliable Datagram Protocol */ +#define IP_PROTOCOL_IPV6 0x29 /* IPv6 (encapsulation) */ +#define IP_PROTOCOL_IPV6_ROUTE 0x2B /* Routing Header for IPv6 */ +#define IP_PROTOCOL_IPV6_FRAG 0x2C /* Fragment Header for IPv6 */ +#define IP_PROTOCOL_RSVP 0x2E /* Resource Reservation Protocol */ +#define IP_PROTOCOL_GRE 0x2F /* Generic Routing Encapsulation */ +#define IP_PROTOCOL_MHRP 0x30 /* Mobile Host Routing Protocol */ +#define IP_PROTOCOL_BNA 0x31 /* BNA */ +#define IP_PROTOCOL_ESP 0x32 /* Encapsulating Security Payload */ +#define IP_PROTOCOL_MOBILE 0x37 /* IP Mobility (Min Encap) */ +#define IP_PROTOCOL_IPV6_ICMP 0x3A /* ICMP for IPv6 */ +#define IP_PROTOCOL_IPV6_NONXT 0x3B /* No Next Header for IPv6 */ +#define IP_PROTOCOL_IPV6_OPTS 0x3C /* Destination Options for IPv6 */ +#define IP_PROTOCOL_IPCOMP 0x6C /* IP Payload Compression Protocol */ +#define IP_PROTOCOL_L2TP 0x73 /* Layer Two Tunneling Protocol Version 3 */ +#define IP_PROTOCOL_SMP 0x79 /* Simple Message Protocol */ +#define IP_PROTOCOL_SCTP 0x84 /* Stream Control Transmission Protocol */ +#define IP_PROTOCOL_SHIM6 0x8C /* Site Multihoming by IPv6 Intermediation */ + + + +/* IPv6 ICMP types */ +#define IPV6_ICMP_TYPE_MLD 0x8F + +#endif /* _IP_PROT__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv4.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv4.h new file mode 100644 index 0000000000000..7e8ba9182b606 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv4.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _IPV4__H_ +#define _IPV4__H_ + +#if defined(ATH_TARGET) +#include /* A_UINT8 */ +#else +#include /* A_UINT8 */ +#endif + +#define IPV4_ADDR_LEN 4 /* bytes */ +struct ipv4_hdr_t { + A_UINT8 ver_hdrlen; /* version and hdr length */ + A_UINT8 tos; /* type of service */ + A_UINT8 len[2]; /* total length */ + A_UINT8 id[2]; + A_UINT8 flags_fragoff[2]; /* flags and fragment offset field */ + A_UINT8 ttl; /* time to live */ + A_UINT8 protocol; + A_UINT8 hdr_checksum[2]; + A_UINT8 src_addr[IPV4_ADDR_LEN]; + A_UINT8 dst_addr[IPV4_ADDR_LEN]; +}; + +#define IPV4_HDR_LEN (sizeof(struct ipv4_hdr_t)) +#define IPV4_HDR_OFFSET_PROTOCOL (offsetof(struct ipv4_hdr_t, protocol)) +#define IPV4_HDR_OFFSET_DST_ADDR (offsetof(struct ipv4_hdr_t, dst_addr[0])) + +#endif /* _IPV4__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv6_defs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv6_defs.h new file mode 100644 index 0000000000000..c07faac431003 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ipv6_defs.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _IPV6__H_ +#define _IPV6__H_ + +#if defined(ATH_TARGET) +#include /* A_UINT8 */ +#else +#include /* A_UINT8 */ +#include /* A_COMPILE_TIME_ASSERT */ +#endif + +/* utilities for converting between network byte order and native endianness */ +#ifndef BYTESWAP32 +#define BYTESWAP32(x) \ + ((((x) & 0x000000ff) << 24) /* byte 0 -> byte 3 */ | \ + (((x) & 0x0000ff00) << 8) /* byte 1 -> byte 2 */ | \ + (((x) & 0x00ff0000) >> 8) /* byte 2 -> byte 1 */ | \ + (((x) & 0xff000000) >> 24) /* byte 3 -> byte 0 */) +#endif /* BYTESWAP32 */ + +#ifndef BE_TO_CPU32 + #if defined(ATH_TARGET) + /* assume target is little-endian */ + #define BE_TO_CPU32(x) BYTESWAP32(x) + #else + #ifdef BIG_ENDIAN_HOST + #define BE_TO_CPU32(x) (x) + #else + #define BE_TO_CPU32(x) BYTESWAP32(x) + #endif + #endif +#endif /* BE_TO_CPU32 */ + + +/* IPv6 header definition */ + +#define IPV6_ADDR_LEN 4 /* bytes */ +struct ipv6_hdr_t { + A_UINT32 ver_tclass_flowlabel; /* version, traffic class, and flow label */ + A_UINT8 pyld_len[2]; /* payload length */ + A_UINT8 next_hdr; + A_UINT8 hop_limit; + A_UINT8 src_addr[IPV6_ADDR_LEN]; + A_UINT8 dst_addr[IPV6_ADDR_LEN]; +}; + +#define IPV6_HDR_LEN (sizeof(struct ipv6_hdr_t)) +#define IPV6_HDR_OFFSET_NEXT_HDR (offsetof(struct ipv6_hdr_t, next_hdr)) +#define IPV6_HDR_OFFSET_DST_ADDR (offsetof(struct ipv6_hdr_t, dst_addr[0])) + + +/* IPv6 header field access macros */ + +#define IPV6_HDR_VERSION_M 0xF0000000 +#define IPV6_HDR_VERSION_S 28 + +#define IPV6_HDR_TRAFFIC_CLASS_M 0x0FF00000 +#define IPV6_HDR_TRAFFIC_CLASS_S 20 + +#define IPV6_HDR_FLOW_LABEL_M 0x000FFFFF +#define IPV6_HDR_FLOW_LABEL_S 0 + +static inline A_UINT8 IPV6_VERSION(struct ipv6_hdr_t *ipv6_hdr) +{ + return + (BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) & + IPV6_HDR_VERSION_M) >> IPV6_HDR_VERSION_S; +} + +static inline A_UINT8 IPV6_TRAFFIC_CLASS(struct ipv6_hdr_t *ipv6_hdr) +{ + return + (A_UINT8)((BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) & + IPV6_HDR_TRAFFIC_CLASS_M) >> IPV6_HDR_TRAFFIC_CLASS_S); +} + +static inline A_UINT32 IPV6_FLOW_LABEL(struct ipv6_hdr_t *ipv6_hdr) +{ + return + (BE_TO_CPU32(ipv6_hdr->ver_tclass_flowlabel) & + IPV6_HDR_FLOW_LABEL_M) >> IPV6_HDR_FLOW_LABEL_S; +} + +#endif /* _IPV6__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/isoc_hw_desc.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/isoc_hw_desc.h new file mode 100644 index 0000000000000..7e4e7df2fc695 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/isoc_hw_desc.h @@ -0,0 +1,1197 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** +* @file isoc_hw_desc.h +* @brief Define the Tx BD and Rx BD structs +*/ +#ifndef _ISOC_HW_DESC__H_ +#define _ISOC_HW_DESC__H_ + +#include /* A_UINT32 */ + +#include /* adf_os_print */ +#include /* adf_os_assert */ + + +/*** + NOTE: For Pronto definition, only V1 is defined. For V2, it needs to add other fields +***/ + +/** +* @brief isoc_rx_bd_t - the format of the "RX BD" (rx buffer descriptor) +*/ + +typedef struct +{ + /* 0x00 */ +#ifdef BIG_ENDIAN_HOST + + /** (Only used by the DPU) + This routing flag indicates the WQ number to which the DPU will push the + frame after it finished processing it. */ + A_UINT32 dpu_routing_flag:8; + + /** This is DPU sig inserted by RXP. Signature on RA's DPU descriptor */ + A_UINT32 dpu_signature:3; + + /** When set Sta is authenticated. SW needs to set bit + addr2_auth_extract_enable in rxp_config2 register. Then RXP will use bit 3 + in DPU sig to say whether STA is authenticated or not. In this case only + lower 2bits of DPU Sig is valid */ + A_UINT32 sta_authenticated:1; + + /** When set address2 is not valid */ + A_UINT32 addr2_invalid:1; + + /** When set it indicates TPE has sent the Beacon frame */ + A_UINT32 beacon_sent:1; + + /** This bit filled by rxp when set indicates if the current tsf is smaller + than received tsf */ + A_UINT32 rx_tsf_later:1; + + /** These two fields are used by SW to carry the Rx Channel number and SCAN bit in RxBD*/ + A_UINT32 rx_channel:4; + /** For WMI host, this bit means band 0 - 2.4Ghz 1 - 5GHz*/ + A_UINT32 band_5ghz:1; + + A_UINT32 reserved0:1; + + /** LLC Removed + This bit is only used in Libra rsvd for Virgo1.0/Virgo2.0 + Filled by ADU when it is set LLC is removed from packet */ + A_UINT32 llc_removed:1; + + A_UINT32 uma_bypass:1; + + /** This bit is only available in Virgo2.0/libra it is reserved in Virgo1.0 + Robust Management frame. This bit indicates to DPU that the packet is a + robust management frame which requires decryption(this bit is only valid for + management unicast encrypted frames) + 1 - Needs decryption + 0 - No decryption required */ + A_UINT32 robust_mgmt:1; + + /** + This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is only valid when robust_mgmt bit is 1 */ + A_UINT32 not_unicast:1; + + /** This is the KEY ID extracted from WEP packets and is used for determine + the RX Key Index to use in the DPU Descriptror. + This field is 2bits for virgo 1.0 + And 3 bits in virgo2.0 and Libra + In virgo2.0/libra it is 3bits for the BC/MC packets */ + A_UINT32 rx_key_id:3; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + A_UINT32 dpu_no_encrypt:1; + + /** + This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit is filled by RXP and modified by ADU + This bit indicates to ADU/UMA module that the packet requires 802.11n to + 802.3 frame translation. Once ADU/UMA is done with translation they + overwrite it with 1'b0/1'b1 depending on how the translation resulted + When used by ADU + 0 - No frame translation required + 1 - Frame Translation required + When used by SW + 0 - Frame translation not done, MPDU header offset points to 802.11 header.. + 1 - Frame translation done ; hence MPDU header offset will point to a + 802.3 header */ + A_UINT32 frame_translate:1; + + /** (Only used by the DPU) + BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + A_UINT32 bd_type:2; + +#else + A_UINT32 bd_type:2; + A_UINT32 frame_translate:1; + A_UINT32 dpu_no_encrypt:1; + A_UINT32 rx_key_id:3; + A_UINT32 not_unicast:1; + A_UINT32 robust_mgmt:1; + A_UINT32 reserved1:1; + A_UINT32 llc_removed:1; + A_UINT32 reserved0:1; + /** For WMI host, this bit means band 0 - 2.4Ghz 1 - 5GHz*/ + A_UINT32 band_5ghz:1; + A_UINT32 rx_channel:4; + A_UINT32 rx_tsf_later:1; + A_UINT32 beacon_sent:1; + A_UINT32 addr2_invalid:1; + A_UINT32 sta_authenticated:1; + A_UINT32 dpu_signature:3; + A_UINT32 dpu_routing_flag:8; +#endif + + /* 0x04 */ +#ifdef BIG_ENDIAN_HOST + + /** This is used for AMSDU this is the PDU index of the PDU which is the + one before last PDU; for all non AMSDU frames, this field SHALL be 0. + Used in ADU (for AMSDU deaggregation) */ + A_UINT32 amsdu_pdu_idx:16; + +#ifdef QCA_ISOC_PRONTO + A_UINT32 adu_feedback:7; + //ToDO: Add meaning of this bit + A_UINT32 dpu_magic_packet: 1; +#else + A_UINT32 adu_feedback:8; +#endif //QCA_ISOC_PRONTO + + /** DPU feedback */ + A_UINT32 dpu_feedback:8; + +#else + A_UINT32 dpu_feedback:8; +#ifdef QCA_ISOC_PRONTO + A_UINT32 dpu_magic_packet: 1; + A_UINT32 adu_feedback:7; +#else + A_UINT32 adu_feedback:8; +#endif //QCA_ISOC_PRONTO + + A_UINT32 amsdu_pdu_idx:16; +#endif + + /* 0x08 */ +#ifdef BIG_ENDIAN_HOST + + /** In case PDUs are linked to the BD, this field indicates the index of + the first PDU linked to the BD. When PDU count is zero, this field has an + undefined value. */ + A_UINT32 head_pdu_idx:16; + + /** In case PDUs are linked to the BD, this field indicates the index of + the last PDU. When PDU count is zero, this field has an undefined value.*/ + A_UINT32 tail_pdu_idx:16; + +#else + A_UINT32 tail_pdu_idx:16; + A_UINT32 head_pdu_idx:16; +#endif + + /* 0x0c */ +#ifdef BIG_ENDIAN_HOST + + /** The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + A_UINT32 mpdu_header_length:8; + + /** The start byte number of the MPDU header. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. */ + A_UINT32 mpdu_header_offset:8; + + /** The start byte number of the MPDU data. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. Note that this offset can point all the way into the first + linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + A_UINT32 mpdu_data_offset:9; + + /** The number of PDUs linked to the BD. + This field should always indicate the correct amount. */ + A_UINT32 pdu_count:7; +#else + + A_UINT32 pdu_count:7; + A_UINT32 mpdu_data_offset:9; + A_UINT32 mpdu_header_offset:8; + A_UINT32 mpdu_header_length:8; +#endif + + /* 0x10 */ +#ifdef BIG_ENDIAN_HOST + + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length does not include FCS field. */ + A_UINT32 mpdu_length:16; + + A_UINT32 reserved3: 3; + //ToDO: Add meaning of this bit + A_UINT32 rx_dxe_priority_routing:1; + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, + this field is set to zero. */ + A_UINT32 tid:4; + + /* + * For the HW and FW, reserved4 is 6 bits long. + * However, the host SW uses two of these bits as flags to remember what + * to do with the rx frame. Hence, for the SW, reserved4 is only 4 bits. + */ + A_UINT32 sw_flag_forward:1; /* SW-only field, unused by FW+HW */ + A_UINT32 sw_flag_discard:1; /* SW-only field, unused by FW+HW */ + A_UINT32 reserved4:4; /* SW perspective: 4 bits reserved */ + //A_UINT32 reserved4:6; /* FW+HW perspecitve: 6 bits reserved */ + A_UINT32 htt_t2h_msg:1; + A_UINT32 flow_control:1; +#else + A_UINT32 flow_control:1; + A_UINT32 htt_t2h_msg:1; + //A_UINT32 reserved4:6; /* FW+HW perspecitve: 6 bits reserved */ + A_UINT32 reserved4:4; /* SW perspective: 4 bits reserved */ + A_UINT32 sw_flag_discard:1; + A_UINT32 sw_flag_forward:1; + A_UINT32 tid:4; + A_UINT32 rx_dxe_priority_routing:1; + A_UINT32 reserved3: 3; + A_UINT32 mpdu_length:16; +#endif + + /* 0x14 */ +#ifdef BIG_ENDIAN_HOST + + /** (Only used by the DPU) + The DPU descriptor index is used to calculate where in memory the DPU can + find the DPU descriptor related to this frame. The DPU calculates the + address by multiplying this index with the DPU descriptor size and adding + the DPU descriptors base address. The DPU descriptor contains information + specifying the encryption and compression type and contains references to + where encryption keys can be found. */ + A_UINT32 dpu_desc_idx:8; + + /** The result from the binary address search on the ADDR1 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + A_UINT32 addr1_index:8; + + /** The result from the binary address search on the ADDR2 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + A_UINT32 addr2_index:8; + + /** The result from the binary address search on the ADDR3 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + A_UINT32 addr3_index:8; +#else + A_UINT32 addr3_index:8; + A_UINT32 addr2_index:8; + A_UINT32 addr1_index:8; + A_UINT32 dpu_desc_idx:8; +#endif + + /* 0x18 */ +#ifdef BIG_ENDIAN_HOST + + /** Indicates Rate Index of packet received */ + A_UINT32 rate_index:9; + + /** An overview of RXP status information related to receiving the frame.*/ + A_UINT32 rxp_flags_has_fcs_en:1; + A_UINT32 rxp_flags_set_nav:1; + A_UINT32 rxp_flags_clear_nav:1; + A_UINT32 rxp_flags_rmf_keyid_vld:1; + A_UINT32 rxp_flags_addr3_index_invalid:1; + A_UINT32 rxp_flags_addr2_index_invalid:1; + A_UINT32 rxp_flags_addr1_index_invalid:1; + A_UINT32 rxp_flags_errored_rmf_frame:1; + A_UINT32 rxp_flags_ampdu_flag:1; + A_UINT32 rxp_flags_rmf_keyid:3; + A_UINT32 rxp_flags_last_mpdu:1; + A_UINT32 rxp_flags_first_mpdu:1; + A_UINT32 rxp_flags_has_phy_cmd:1; + A_UINT32 rxp_flags_has_phy_stats:1; + A_UINT32 rxp_flags_has_dlm:1; + A_UINT32 rxp_flags_byp_dlm_proc:1; + A_UINT32 rxp_flags_byp_mpdu_proc:1; + A_UINT32 rxp_flags_fail_filter:1; + A_UINT32 rxp_flags_fail_max_ptklen:1; + A_UINT32 rxp_flags_fcs_err:1; + A_UINT32 rxp_flags_err:1; + +#else + + A_UINT32 rxp_flags_err:1; + A_UINT32 rxp_flags_fcs_err:1; + A_UINT32 rxp_flags_fail_max_ptklen:1; + A_UINT32 rxp_flags_fail_filter:1; + A_UINT32 rxp_flags_byp_mpdu_proc:1; + A_UINT32 rxp_flags_byp_dlm_proc:1; + A_UINT32 rxp_flags_has_dlm:1; + A_UINT32 rxp_flags_has_phy_stats:1; + A_UINT32 rxp_flags_has_phy_cmd:1; + A_UINT32 rxp_flags_first_mpdu:1; + A_UINT32 rxp_flags_last_mpdu:1; + A_UINT32 rxp_flags_rmf_keyid:3; + A_UINT32 rxp_flags_ampdu_flag:1; + A_UINT32 rxp_flags_errored_rmf_frame:1; + A_UINT32 rxp_flags_addr1_index_invalid:1; + A_UINT32 rxp_flags_addr2_index_invalid:1; + A_UINT32 rxp_flags_addr3_index_invalid:1; + A_UINT32 rxp_flags_rmf_keyid_vld:1; + A_UINT32 rxp_flags_clear_nav:1; + A_UINT32 rxp_flags_set_nav:1; + A_UINT32 rxp_flags_has_fcs_en:1; + + A_UINT32 rate_index:9; + +#endif + /* 0x1c */ + /** The PHY can be programmed to put all the PHY STATS received from the + PHY when receiving a frame in the BD. */ +#ifdef BIG_ENDIAN_HOST + A_UINT32 rssi0:8; + A_UINT32 rssi1:8; + A_UINT32 rssi2:8; + A_UINT32 rssi3:8; +#else + A_UINT32 rssi3:8; + A_UINT32 rssi2:8; + A_UINT32 rssi1:8; + A_UINT32 rssi0:8; +#endif + + /* 0x20 */ + A_UINT32 phy_stats1; /* PHY status word 1: snr */ + + /* 0x24 */ + /** The value of the TSF[31:0] bits at the moment that the RXP start + receiving a frame from the PHY RX. */ + A_UINT32 rx_timestamp; /* Rx timestamp, microsecond based*/ + + /* 0x28~0x38 */ + /** The bits from the PMI command as received from the PHY RX. */ + A_UINT32 pmi_cmd4to23[5]; /* PMI cmd rcvd from RxP */ + + /* 0x3c */ + /** The bits from the PMI command as received from the PHY RX. */ +#ifdef QCA_ISOC__PRONTO + +#ifdef BIG_ENDIAN_HOST + /** The bits from the PMI command as received from the PHY RX. */ + A_UINT32 pmi_cmd24to25:16; + + /* 16-bit CSU Checksum value for the fragmented receive frames */ + A_UINT32 csu_checksum:16; +#else + A_UINT32 csu_checksum:16; + A_UINT32 pmi_cmd24to25:16; +#endif + +#else + /** The bits from the PMI command as received from the PHY RX. */ +#ifdef BIG_ENDIAN_HOST + A_UINT32 pmi_cmd24to25:16; + A_UINT32 pmi_cmd26to27:16; +#else + A_UINT32 pmi_cmd26to27:16; + A_UINT32 pmi_cmd24to25:16; +#endif + +#endif // QCA_ISOC__PRONTO + + /* 0x40 */ +#ifdef BIG_ENDIAN_HOST + + /** Gives commands to software upon which host will perform some commands. + Please refer to following RPE document for description of all different + values for this field. */ + A_UINT32 reorder_opcode:4; /* isoc_rx_opcode */ + + A_UINT32 reserved6:12; + + /** Filled by RPE to Indicate to the host up to which slot the host needs + to forward the packets to upper Mac layer. This field mostly used for AMDPU + packets */ + A_UINT32 reorder_fwd_idx:6; + + /** Filled by RPE which indicates to the host which one of slots in the + available 64 slots should the host Queue the packet. This field only + applied to AMPDU packets. */ + A_UINT32 reorder_slot_idx:6; + + A_UINT32 reserved7: 2; + //ToDo: Add meaning to the bits + A_UINT32 out_of_order_forward: 1; + A_UINT32 reorder_enable: 1; + +#else + + A_UINT32 reorder_enable: 1; + A_UINT32 out_of_order_forward: 1; + A_UINT32 reserved7: 2; + + A_UINT32 reorder_slot_idx:6; + A_UINT32 reorder_fwd_idx:6; + A_UINT32 reserved6:12; + A_UINT32 reorder_opcode:4; +#endif + + /* 0x44 */ +#ifdef BIG_ENDIAN_HOST + /** reserved8 from a hardware perspective. + Used by SW to propogate frame type/subtype information */ + A_UINT32 frame_type_subtype:8; + + /** Filled RPE gives the current sequence number in bitmap */ + A_UINT32 current_pkt_seqno:12; + + /** Filled by RPE which gives the sequence number of next expected packet + in bitmap */ + A_UINT32 expected_pkt_seqno:12; +#else + A_UINT32 expected_pkt_seqno:12; + A_UINT32 current_pkt_seqno:12; + A_UINT32 frame_type_subtype:8; +#endif + + /* 0x48 */ +#ifdef BIG_ENDIAN_HOST + + /** When set it is the AMSDU subframe */ + A_UINT32 amsdu:1; + + /** When set it is the First subframe of the AMSDU packet */ + A_UINT32 amsdu_first:1; + + /** When set it is the last subframe of the AMSDU packet */ + A_UINT32 amsdu_last:1; + + /** When set it indicates an Errored AMSDU packet */ + A_UINT32 amsdu_error:1; + + A_UINT32 reserved9:4; + + /** It gives the order in which the AMSDU packet is processed + Basically this is a number which increments by one for every AMSDU frame + received. Mainly for debugging purpose. */ + A_UINT32 process_order:4; + + /** It is the order of the subframe of AMSDU that is processed by ADU. + This is reset to 0 when ADU deaggregates the first subframe from a new + AMSDU and increments by 1 for every new subframe deaggregated within the + AMSDU, after it reaches 4'hf it stops incrementing. That means host should + not rely on this field as index for subframe queuing. Theoretically there + can be way more than 16 subframes in an AMSDU. This is only used for debug + purpose, SW should use LSF and FSF bits to determine first and last + subframes. */ + A_UINT32 amsdu_idx:4; + + /** Filled by ADU this is the total AMSDU size */ + A_UINT32 total_amsdu_size:16; +#else + A_UINT32 total_amsdu_size:16; + A_UINT32 amsdu_idx:4; + A_UINT32 process_order:4; + A_UINT32 reserved9:4; + A_UINT32 amsdu_error:1; + A_UINT32 amsdu_last:1; + A_UINT32 amsdu_first:1; + A_UINT32 amsdu:1; +#endif + +} isoc_rx_bd_t; + + +/** +* @brief specify whether to process or defer rx MPDUs +* @details +* The rx reorder opcode indicates which rx MPDUs should be deferred, +* due to prior MPDUs that have not yet arrived, and which shoudl be +* processed, due to having all prior MPDUs already received. +* The possibilities are: +* - There were no missing MPDUs, and a new in-order MPDU is received: +* release the new MPDU +* - A single missing MPDU is received: +* release the queued old MPDUs that were waiting on this new MPDU, +* and also release this new MPDU +* - A MPDU that is not the initial missing MPDU is received: +* store the new MPDU in the rx reordering queue until missing +* prior MPDUs have been received +* - A new MPDU shifts the block ack window, and one of the following... +* - All old MPDUs are no longer covered by the shifted block ack +* window. +* Release all old MPDUs, and store the new MPDU. +* - The missing MPDU that old MPDUs were waiting for is no longer +* covered by the shifted block ack window. Release all such +* old MPDUs, and if the new MPDU is in-order, release it too. +* - Some old MPDUs are still covered by the shifted block ack +* window, and so is a missing MPDU preceding the old MPDUs. +* Any old MPDUs that are no longer covered by the shifted block +* ack window are released, as are any old MPDUs that don't have +* any missing prior MPDU. All remaing MPDUs, including the new +* MPDU, are left queued in the rx reorder array. +* - A block ack request control message causes the block ack window +* to shift: release queued MPDUs that are no longer covered by the +* shifted block ack window. +*/ +typedef enum +{ + ISOC_RX_OPCODE_INVALID = 0, + + /* QUEUECUR_FWDBUF + * The new MPDU fills a hole (or is at the front of the block ack + * window) - release any buffered MPDUs that were waiting for this + * new MPDU (and then release this new MPDU too). + */ + ISOC_RX_OPCODE_QUEUECUR_FWDBUF = 1, + + /* FWDBUF_FWDCUR + * The new MPDU shifts the block ack window, causing all old MPDUs + * to no longer be within the shifted block ack window. + * Thus, all bufferend MPDUs are released. Since the new MPDU is at + * the front of the shifted block ack window, it too is released. + */ + ISOC_RX_OPCODE_FWDBUF_FWDCUR = 2, + + /* QUEUECUR + * The new MPDU is waiting for missing prior MPDUs. + */ + ISOC_RX_OPCODE_QUEUECUR = 3, + + /* FWDBUF_QUEUECUR + * The new MPDU results in the block ack window being shifted, + * and the new MPDU's position within the new block ack window + * potentially falls on top of an old MPDU's position within the + * old block ack window. + * The new MPDU is waiting for a missing prior MPDU that falls within + * the new position of the block ack window. + * Thus, first release all the MPDUs that are no longer covered by the + * shifted block ack window, then store the new MPDU. + * This is the same as FWDALL_QUEUECUR, except that in this case some + * of the old MPDUs still are covered by the shifted block ack window + * and have a missing MPDU that they are waiting for. + */ + ISOC_RX_OPCODE_FWDBUF_QUEUECUR = 4, + + /* FWDBUF_DROPCUR + * A block ack request control message shifts the block ack window, + * causing some of the queued MPDUs to be no longer covered by the + * shifted block ack window. + * Release these MPDUs that are no longer within the block ack window, + * and any MPDUs that are at the start of the new window, while retaining + * MPDUs within the window that are preceded by a missing MPDU. + */ + ISOC_RX_OPCODE_FWDBUF_DROPCUR = 5, + + /* FWDALL_DROPCUR + * A block ack request control message shifts the block ack window, + * causing all of the queued MPDUs to be no longer covered by the + * shifted block ack window. Release all queued MPDUs. + */ + ISOC_RX_OPCODE_FWDALL_DROPCUR = 6, + + /* FWDALL_QUEUECUR + * This is equivalent to FWDBUF_QUEUECUR, but all old MPDUs are released, + * either becaues they all are no longer covered by the shifted block ack + * window, or because the missing MPDU they were waiting for is no longer + * covered by the shifted block ack window, so though (some of) the old + * MPDUs are still covered by the shifted block ack window, they no longer + * have a missing prior MPDU within the block ack window. + */ + ISOC_RX_OPCODE_FWDALL_QUEUECUR = 7, + + ISOC_RX_OPCODE_TEARDOWN = 8, /* not used? */ + + ISOC_RX_OPCODE_DROPCUR = 9, /* not used? */ + + ISOC_RX_OPCODE_MAX +} isoc_rx_opcode; + + +/* bd_type defined */ +enum { + ISOC_BD_TYPE_GENERIC = 0, + ISOC_BD_TYPE_DEFRAG = 1, +}; + +/* dpu_feedback defined */ +enum { + ISOC_DPU_FEEDBACK_MULTI_ERROR = 0, /* DPU detected multiple errors. Should never occur. */ + ISOC_DPU_FEEDBACK_BAD_TAG, /* Tag fields in the BD and associated DPU descriptor did not match. */ + ISOC_DPU_FEEDBACK_BAD_BD, /* At least one of the following conditions applied: + * The BD type was not 0 (normal BD) in a TX packet. + * The BD type was not either 0 or 1 (normal or defrag BD) in an RX packet. + * The MPDU Length field was less than the MPDU Header Length field. + * The MPDU header was not located entirely within the BD. + * The MPDU Data Offset pointed past the end of the first PDU. + */ + ISOC_DPU_FEEDBACK_BAD_TKIP_MIC, /* The TKIP MIC of a received packet is incorrect. */ + ISOC_DPU_FEEDBACK_BAD_DECRYPT, /* Decryption of an RX fragment has failed.This error occurs only if none of the following more specific conditions applied. */ + ISOC_DPU_FEEDBACK_ENVELOPE_ONLY, /* The received protected fragment had exactly sufficient MPDU data for an empty cryptographic envelope of the selected encryption mode. */ + ISOC_DPU_FEEDBACK_ENVELOPE_PART, /* The received protected fragment had less MPDU data than required for the cryptographic envelope of the selected encryption mode. */ + ISOC_DPU_FEEDBACK_ZERO_LENGTH, /* The received fragment had no MPDU data at all. */ + ISOC_DPU_FEEDBACK_BAD_EXTIV, /* The received AES or TKIP fragment did not have the EXTIV bit set in the IV field of the cryptographic envelope. */ + ISOC_DPU_FEEDBACK_BAD_KID, /* The KID field extracted from the received fragment did not match that in the DPU descriptor (or the BD for WEP encryption modes). */ + ISOC_DPU_FEEDBACK_BAD_WEP_SEED, /* The received TKIP fragment’s computed WEP Seed did not match that in the IV. */ + ISOC_DPU_FEEDBACK_UNPROTECTED, /* The received packet was unprotected, but the associated DPU descriptor had encryption enabled. */ + ISOC_DPU_FEEDBACK_PROTECTED, /* The received packet was protected, but the associated DPU descriptor did not have an encryption mode enabled. */ + ISOC_DPU_FEEDBACK_BAD_REPLAY, /* The received packet failed replay count checking. */ + ISOC_DPU_FEEDBACK_DPU_STALL, /* The DPU stalled with a watchdog timeout and the forced packet completion event occurred. */ + ISOC_DPU_FEEDBACK_WAPI_WAI_FRAME, /* If the encryption mode is WAPI and the recived frame is WAI */ +}; + +/** +* @brief isoc_tx_bd_t - the format of the "TX BD" (tx buffer descriptor) +*/ +typedef struct +{ + /* byte offset 0x0 */ +#ifdef BIG_ENDIAN_HOST + /** + * (Only used by the DPU) This routing flag indicates the WQ number to + * which the DPU will push the frame after it finished processing it. + */ + A_UINT32 dpu_routing_flag: 8; + + /** + * DPU signature + * The DPU signature is used by the Tx MAC HW for a sanity check + * that the specified DPU index (i.e. security key ID) is valid. + */ + A_UINT32 dpu_signature: 3; + + /** Reserved */ + A_UINT32 reserved0:2; + + /** Set to '1' to terminate the current AMPDU session. Added based on the + request for WiFi Display */ + A_UINT32 terminate_ampdu:1; + + /** Bssid index to indicate ADU to use which of the 4 default MAC address + to use while 802.3 to 802.11 translation in case search in ADU UMA table + fails. The default MAC address should be appropriately programmed in the + uma_tx_default_wmacaddr_u(_1,_2,_3) and uma_tx_default_wmacaddr_l(_1,_2,_3) + registers */ + A_UINT32 uma_bssid_idx:2; + + /** Set to 1 to enable uma filling the BD when FT is not enabled. + Ignored when FT is enabled. */ + A_UINT32 uma_bd_enable:1; + + /** (Only used by the CSU) + 0: No action + 1: Host will indicate TCP/UPD header start location and provide pseudo header value in BD. + */ + A_UINT32 csu_sw_mode:1; + + /** Enable/Disable CSU on TX direction. + 0: Disable Checksum Unit (CSU) for Transmit. + 1: Enable + */ + A_UINT32 csu_tx_enable:1; + + /** Enable/Disable Transport layer Checksum in CSU + 0: Disable TCP UDP checksum generation for TX. + 1: Enable TCP UDP checksum generation for TX. + */ + A_UINT32 csu_enable_tl_checksum:1; + + /** Enable/Disable IP layer Checksum in CSU + 0: Disable IPv4/IPv6 checksum generation for TX + 1: Enable IPv4/IPv6 checksum generation for TX + */ + A_UINT32 csu_enable_ip_checksum:1; + + /** Filled by CSU to indicate whether transport layer Checksum is generated by CSU or not + 0: TCP/UDP checksum is being generated for TX. + 1: TCP/UDP checksum is NOT being generated for TX. + */ + A_UINT32 csu_tl_checksum_generated:1; + + /** Filled by CSU in error scenario + 1: No valid header found during parsing. Therefore no checksum was validated. + 0: Valid header found + */ + A_UINT32 csu_no_valid_header:1; + + /** + * Robust Management Frames + * This bit indicates to DPU that the packet is a robust management + * frame which requires encryption (this bit is only valid for + * certain management frames) + * 1 - Needs encryption + * 0 - No encrytion required + * It is only set when Privacy bit=1 AND type/subtype=Deauth, Action, + * Disassoc. Otherwise it should always be 0. + */ + A_UINT32 robust_mgmt: 1; + + /** + * This 1-bit field indicates to DPU Unicast/BC/MC packet + * 0 - Unicast packet + * 1 - Broadcast/Multicast packet + * This bit is valid only if RMF bit is set + */ + A_UINT32 not_unicast: 1; + + A_UINT32 reserved1: 1; + + /** + * This bit indicates TPE has to assert the TX complete interrupt. + * 0 - no interrupt + * 1 - generate interrupt */ + A_UINT32 tx_complete_intr: 1; + + A_UINT32 fw_tx_complete_intr: 1; + + /** + * No encryption/decryption + * 0: No action + * 1: DPU will not encrypt/decrypt the frame, and discard any encryption + * related settings in the PDU descriptor. + * (Only used by the DPU) + */ + A_UINT32 dpu_no_encrypt: 1; + + /** + * This bit indicates to ADU/UMA module that the packet requires 802.11n + * to 802.3 frame translation. When used by ADU + * 0 - No frame translation required + * 1 - Frame Translation required + */ + A_UINT32 frame_translate: 1; + + /** + * BD Type + * 00: 'Generic BD', as indicted above + * 01: De-fragmentation format + * 10-11: Reserved for future use. + */ + A_UINT32 bd_type: 2; +#else + A_UINT32 bd_type: 2; + A_UINT32 frame_translate: 1; + A_UINT32 dpu_no_encrypt: 1; + A_UINT32 fw_tx_complete_intr: 1; + A_UINT32 tx_complete_intr: 1; + A_UINT32 reserved1: 1; + A_UINT32 not_unicast: 1; + A_UINT32 robust_mgmt: 1; + + A_UINT32 csu_no_valid_header:1; + A_UINT32 csu_tl_checksum_generated:1; + A_UINT32 csu_enable_ip_checksum:1; + A_UINT32 csu_enable_tl_checksum:1; + A_UINT32 csu_tx_enable:1; + A_UINT32 csu_sw_mode:1; + A_UINT32 uma_bd_enable:1; + A_UINT32 uma_bssid_idx:2; + A_UINT32 terminate_ampdu:1; + A_UINT32 reserved0:2; + + A_UINT32 dpu_signature: 3; + A_UINT32 dpu_routing_flag: 8; +#endif + + /* byte offset 0x4 */ +#ifdef BIG_ENDIAN_HOST + A_UINT32 reserved2: 16; /* MUST BE 0 otherwise triggers BMU error*/ + A_UINT32 adu_feedback: 8; + /* DPU feedback in Tx path.*/ + A_UINT32 dpu_feedback: 8; + +#else + A_UINT32 dpu_feedback: 8; + A_UINT32 adu_feedback: 8; + A_UINT32 reserved2: 16; +#endif + + /* byte offset 0x8 */ +#ifdef BIG_ENDIAN_HOST + /** + * head PDU index + * It is initially filled by DXE then if encryption is on, + * then DPU will overwrite these fields. + * In case PDUs are linked to the BD, this field indicates + * the index of the first PDU linked to the BD. + * When PDU count is zero, this field has an undefined value. + */ + A_UINT32 head_pdu_idx: 16; + + /** + * head PDU index + * It is initially filled by DXE then if encryption is on, + * then DPU will overwrite these fields. + * In case PDUs are linked to the BD, this field indicates + * the index of the last PDU. + * When PDU count is zero, this field has an undefined value. + */ + A_UINT32 tail_pdu_idx: 16; +#else + A_UINT32 tail_pdu_idx: 16; + A_UINT32 head_pdu_idx: 16; +#endif + + /* byte offset 0xc */ +#ifdef BIG_ENDIAN_HOST + /** + * The length (in number of bytes) of the MPDU header. + * Limitation: The MPDU header offset + MPDU header length + * can never go beyond the end of the first PDU + */ + A_UINT32 mpdu_header_length: 8; + + /** + * The start byte number of the MPDU header. + * The byte numbering is done in the BE format. + * Word 0x0, bits [31:24] has byte index 0. + */ + A_UINT32 mpdu_header_offset: 8; + + /** + * The start byte number of the MPDU data. + * The byte numbering is done in the BE format. + * Word 0x0, bits [31:24] has byte index 0. + * Note that this offset can point all the way into the + * first linked PDU. + * Limitation: MPDU DATA OFFSET can not point into the + * 2nd linked PDU + */ + A_UINT32 mpdu_data_offset: 9; + + /** + * PDU count + * It is initially filled by DXE then if encryption is on, + * DPU will overwrite these fields. + * The number of PDUs linked to the BD. + * This field should always indicate the correct amount. + */ + A_UINT32 pdu_count: 7; +#else + A_UINT32 pdu_count: 7; + A_UINT32 mpdu_data_offset: 9; + A_UINT32 mpdu_header_offset: 8; + A_UINT32 mpdu_header_length: 8; +#endif + + /* byte offset 0x10 */ +#ifdef BIG_ENDIAN_HOST + /** + * This covers MPDU header length + MPDU data length. + * This does not include FCS. + * For single frame transmission, PSDU size is mpdu_length + 4. + */ + A_UINT32 mpdu_length: 16; + + A_UINT32 reserved3: 2; + + /** + * Sequence number insertion by DPU + * 00: Leave sequence number as is, as filled by host + * 01: DPU to insert non TID based sequence number + * (If not TID based, then how does DPU know what seq to fill? + * Is this the non-Qos/Mgmt sequence number?) + * 10: DPU to insert a sequence number based on TID. + * 11: Reserved + */ + A_UINT32 bd_seq_num_src:2; + + /** + * Traffic Identifier + * Indicates the traffic class the frame belongs to. + * For non QoS frames, this field is set to zero. + */ + A_UINT32 tid: 4; + + A_UINT32 reserved4: 8; +#else + A_UINT32 reserved4: 8; + A_UINT32 tid: 4; + A_UINT32 bd_seq_num_src: 2; + A_UINT32 reserved3: 2; + A_UINT32 mpdu_length: 16; +#endif + + /* byte offset 0x14 */ +#ifdef BIG_ENDIAN_HOST + /** + * (Only used by the DPU) + * The DPU descriptor index is used to calculate where in + * memory the DPU can find the DPU descriptor related to this frame. + * The DPU calculates the address by multiplying this index + * with the DPU descriptor size and adding the DPU descriptor + * array's base address. + * The DPU descriptor contains information specifying the encryption + * and compression type and contains references to where encryption + * keys can be found. + */ + A_UINT32 dpu_desc_idx: 8; + + /** + * The STAid of the RA address, a.k.a. peer ID + */ + A_UINT32 sta_index: 8; + + /** + * A field passed on to TPE which influences the ACK policy + * to be used for this frame + * 00 - ack + * 01,10,11 - No Ack + */ + A_UINT32 ack_policy: 2; + + /** + * Overwrite option for the transmit rate + * 00: Use rate programmed in the TPE STA descriptor + * 01: Use TPE BD rate 1 + * 10: Use TPE BD rate 2 + * 11: Delayed Use TPE BD rate 3 + */ + A_UINT32 bd_rate: 2; + + /** + * Which HW tx queue the frame should go into + */ + A_UINT32 queue_id: 5; + + A_UINT32 reserved5: 7; +#else + A_UINT32 reserved5: 7; + A_UINT32 queue_id: 5; + A_UINT32 bd_rate: 2; + A_UINT32 ack_policy: 2; + A_UINT32 sta_index: 8; + A_UINT32 dpu_desc_idx: 8; +#endif + + /* byte offset 0x18 */ + A_UINT32 tx_bd_signature; + + /* byte offset 0x1c */ + A_UINT32 reserved6; + + /* byte offset 0x20 */ + /* Timestamp filled by DXE. Timestamp for current transfer */ + A_UINT32 dxe_h2b_start_timestamp; + + /* byte offset 0x24 */ + /* Timestamp filled by DXE. Timestamp for previous transfer */ + A_UINT32 dxe_h2b_end_timestamp; + +#ifdef QCA_ISOC_PRONTO + + /* byte offset 0x28 */ +#ifdef BIG_ENDIAN_HOST + /** 10 bit value to indicate the start of TCP UDP frame relative to + * the first IP frame header */ + A_UINT32 csu_tcp_udp_start_offset:10; + + /** 16 bit pseudo header for TCP UDP used by CSU to generate TCP/UDP + * frame checksum */ + A_UINT32 csu_pseudo_header_checksum:16; + + A_UINT32 reserved7:6; +#else + A_UINT32 reserved7:6; + A_UINT32 csu_pseudo_header_checksum:16; + A_UINT32 csu_tcp_udp_start_offset:10; +#endif + +#endif /*QCA_ISOC_PRONTO*/ + +} isoc_tx_bd_t; + +/** +* @brief utility function to swap bytes within a series of u_int32_t words +* @details +* This function swaps bytes 0 <-> 3 and bytes 1 <-> 2 within each 4-byte +* word within a specified address range. +* The address range is assumed to be aligned to a 4-byte boundary, and +* to have a length that is a multiple of 4 bytes. +* This function can be used for endianness correction - after swapping +* the bytes within a 4-byte word, the native u_int32_t value will have +* bitfields within the u_int32_t word in the expected positions. +* For example, if a structure that is initially stored in big-endian +* format needs to be interpreted in a little-endian processor: +* +* original 32-bit word: +* bit number +* 31 24 23 16 15 8 7 0 +* |--------------+----------------+----------------+---------------| +* | C | B | A_hi | A_lo | +* |--------------+----------------+----------------+---------------| +* +* stored in +* big-endian format: +* byte contents +* +---------+ +---------+ +* 0 | C | | A_lo | +* +---------+ +---------+ +* 1 | B | byte-swapped | A_hi | +* +---------+ ================> +---------+ +* 2 | A_hi | | B | +* +---------+ +---------+ +* 3 | A_lo | | C | +* +---------+ +---------+ +* +* byte-swapped values read into a 32-bit word on a little-endian processor: +* bit number +* 31 24 23 16 15 8 7 0 +* |--------------+----------------+----------------+---------------| +* | C | B | A_hi | A_lo | +* |--------------+----------------+----------------+---------------| +*/ +static inline void + isoc_hw_bd_swap_bytes32(char *addr, int bytes) +{ + u_int32_t *p32 = (u_int32_t *) addr; + int i, num_words32; + + /* confirm that the address range has the expected alignment */ + adf_os_assert((((unsigned) addr) & 0x3) == 0); + /* confirm that the address range has the expected length quantum */ + adf_os_assert((bytes & 0x3) == 0); + + num_words32 = bytes >> 2; + for (i = 0; i < num_words32; i++, p32++) { + u_int32_t word = *p32; + *p32 = + ((word & 0x000000ff) << 24) | /* move byte 0 --> byte 3 */ + ((word & 0x0000ff00) << 8) | /* move byte 1 --> byte 2 */ + ((word & 0x00ff0000) >> 8) | /* move byte 2 --> byte 1 */ + ((word & 0xff000000) >> 24); /* move byte 3 --> byte 0 */ + } +} + +static inline void + isoc_tx_bd_dump(isoc_tx_bd_t *tx_bd) +{ + char *p; + int i; + + adf_os_print("Tx BD (%p)\n", tx_bd); + + adf_os_print("structured view:\n"); + adf_os_print(" BD type: %d\n", tx_bd->bd_type); + adf_os_print(" frame translate: %d\n", tx_bd->frame_translate); + adf_os_print(" DPU no-encrypt: %d\n", tx_bd->dpu_no_encrypt); + adf_os_print(" FW tx complete intr: %d\n", tx_bd->fw_tx_complete_intr); + adf_os_print(" tx complete intr: %d\n", tx_bd->tx_complete_intr); + adf_os_print(" not unicast: %d\n", tx_bd->not_unicast); + adf_os_print(" robust mgmt: %d\n", tx_bd->robust_mgmt); + adf_os_print(" DPU signature: %d\n", tx_bd->dpu_signature); + adf_os_print(" DPU routing flag: %d\n", tx_bd->dpu_routing_flag); + adf_os_print(" DPU feedback: %#x\n", tx_bd->dpu_feedback); + adf_os_print(" ADU feedback: %#x\n", tx_bd->adu_feedback); + adf_os_print(" tail PDU idx: %d\n", tx_bd->tail_pdu_idx); + adf_os_print(" head PDU idx: %d\n", tx_bd->head_pdu_idx); + adf_os_print(" PDU count: %d\n", tx_bd->pdu_count); + adf_os_print(" MPDU data offset: %d\n", tx_bd->mpdu_data_offset); + adf_os_print(" MPDU header offset: %d\n", tx_bd->mpdu_header_offset); + adf_os_print(" MPDU header length: %d\n", tx_bd->mpdu_header_length); + adf_os_print(" TID: %d\n", tx_bd->tid); + adf_os_print(" BD seq num src: %d\n", tx_bd->bd_seq_num_src); + adf_os_print(" MPDU length: %d\n", tx_bd->mpdu_length); + adf_os_print(" queue ID: %d\n", tx_bd->queue_id); + adf_os_print(" BD rate: %d\n", tx_bd->bd_rate); + adf_os_print(" ack policy: %d\n", tx_bd->ack_policy); + adf_os_print(" STA index: %d\n", tx_bd->sta_index); + adf_os_print(" DPU desc idx: %d\n", tx_bd->dpu_desc_idx); + adf_os_print(" Tx BD signature: %d\n", tx_bd->tx_bd_signature); + adf_os_print(" DXE start timestamp: %d\n", tx_bd->dxe_h2b_start_timestamp); + adf_os_print(" DXE end timestamp: %d\n", tx_bd->dxe_h2b_end_timestamp); + + adf_os_print("raw view:\n "); + p = (char *) tx_bd; + for (i = 0; i < sizeof(*tx_bd); i++, p++) { + adf_os_print("%#02x ", *p); + if ((i+1) % 8 == 0) { + adf_os_print("\n "); + } + } + adf_os_print("\n"); +} + +static inline void + isoc_rx_bd_dump(isoc_rx_bd_t *rx_bd) +{ + char *p; + int i; + + adf_os_print("Rx BD (%p)\n", rx_bd); + + adf_os_print("structured view:\n"); + adf_os_print(" BD type: %d\n", rx_bd->bd_type); + adf_os_print(" frame translate: %d\n", rx_bd->frame_translate); + adf_os_print(" DPU no-encrypt: %d\n", rx_bd->dpu_no_encrypt); + adf_os_print(" not unicast: %d\n", rx_bd->not_unicast); + adf_os_print(" robust mgmt: %d\n", rx_bd->robust_mgmt); + adf_os_print(" LLC removed: %d\n", rx_bd->llc_removed); + adf_os_print(" DPU signature: %d\n", rx_bd->dpu_signature); + adf_os_print(" DPU routing flag: %d\n", rx_bd->dpu_routing_flag); + adf_os_print(" addr1 index: %d\n", rx_bd->addr1_index); + adf_os_print(" addr2 index invalid: %d\n", rx_bd->addr2_invalid); + adf_os_print(" addr2 index: %d\n", rx_bd->addr2_index); + adf_os_print(" addr3 index: %d\n", rx_bd->addr3_index); + adf_os_print(" DPU feedback: %#x\n", rx_bd->dpu_feedback); + adf_os_print(" ADU feedback: %#x\n", rx_bd->adu_feedback); + adf_os_print(" tail PDU idx: %d\n", rx_bd->tail_pdu_idx); + adf_os_print(" head PDU idx: %d\n", rx_bd->head_pdu_idx); + adf_os_print(" PDU count: %d\n", rx_bd->pdu_count); + adf_os_print(" MPDU data offset: %d\n", rx_bd->mpdu_data_offset); + adf_os_print(" MPDU header offset: %d\n", rx_bd->mpdu_header_offset); + adf_os_print(" MPDU header length: %d\n", rx_bd->mpdu_header_length); + adf_os_print(" TID: %d\n", rx_bd->tid); + adf_os_print(" MPDU length: %d\n", rx_bd->mpdu_length); + adf_os_print(" DPU desc idx: %d\n", rx_bd->dpu_desc_idx); + adf_os_print(" HTT T2H Msg: %d\n", rx_bd->htt_t2h_msg); + adf_os_print(" Flow Control: %d\n", rx_bd->flow_control); + adf_os_print(" Current Pkt Sequence No: %d\n", rx_bd->current_pkt_seqno); + adf_os_print(" Expected Pkt Sequence No: %d\n", rx_bd->expected_pkt_seqno); + adf_os_print(" frame subtype: %d\n", rx_bd->frame_type_subtype); + adf_os_print(" RSSI0: %d\n", rx_bd->rssi0); + adf_os_print(" reorder opcode: %d\n", rx_bd->reorder_opcode); + adf_os_print(" reorder fwd index: %d\n", rx_bd->reorder_fwd_idx); + adf_os_print(" reorder slot index: %d\n", rx_bd->reorder_slot_idx); + adf_os_print(" AMSDU Size: %d\n", rx_bd->total_amsdu_size); + adf_os_print(" AMSDU IDX: %d\n", rx_bd->amsdu_idx); + adf_os_print(" AMSDU: %d\n", rx_bd->amsdu); + adf_os_print(" AMSDU first subfrm: %d\n", rx_bd->amsdu_first); + adf_os_print(" AMSDU last subfrm: %d\n", rx_bd->amsdu_last); + adf_os_print(" AMSDU error: %d\n", rx_bd->amsdu_error); + adf_os_print(" RX timestamp: %d\n", rx_bd->rx_timestamp); + + adf_os_print("raw view start:\n "); + p = (char *) rx_bd; + for (i = 0; i < sizeof(*rx_bd); i++, p++) { + adf_os_print("%#02x ", *p); + if ((i+1) % 8 == 0) { + adf_os_print("\n "); + } + } + adf_os_print("raw view end\n"); +} + +#endif /* _ISOC_HW_DESC__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_cfg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_cfg.h new file mode 100644 index 0000000000000..1f76c3277221f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_cfg.h @@ -0,0 +1,500 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_CFG__H_ +#define _OL_CFG__H_ + +#include /* u_int32_t */ +#include /* ol_pdev_handle */ +#include "ieee80211_common.h" /* ieee80211_qosframe_htc_addr4 */ +#include /* LLC_SNAP_HDR_LEN */ + +#if defined(CONFIG_HL_SUPPORT) +#include "wlan_tgt_def_config_hl.h" +#else +#include "wlan_tgt_def_config.h" +#endif + +/** + * @brief format of data frames delivered to/from the WLAN driver by/to the OS + */ +enum wlan_frm_fmt { + wlan_frm_fmt_unknown, + wlan_frm_fmt_raw, + wlan_frm_fmt_native_wifi, + wlan_frm_fmt_802_3, +}; + +#ifdef IPA_UC_OFFLOAD +struct wlan_ipa_uc_rsc_t { + u8 uc_offload_enabled; + u32 tx_max_buf_cnt; + u32 tx_buf_size; + u32 rx_ind_ring_size; + u32 tx_partition_base; +}; +#endif /* IPA_UC_OFFLOAD */ + +/* Config parameters for txrx_pdev */ +struct txrx_pdev_cfg_t { + u8 is_high_latency; + u8 defrag_timeout_check; + u8 rx_pn_check; + u8 pn_rx_fwd_check; + u8 host_addba; + u8 tx_free_at_download; + u8 rx_fwd_inter_bss; + u32 max_thruput_mbps; + u32 target_tx_credit; + u32 vow_config; + u32 tx_download_size; + u32 max_peer_id; + u32 max_vdev; + u32 max_nbuf_frags; + u32 throttle_period_ms; + enum wlan_frm_fmt frame_type; + u8 rx_fwd_disabled; + u8 is_packet_log_enabled; + u8 is_full_reorder_offload; +#ifdef IPA_UC_OFFLOAD + struct wlan_ipa_uc_rsc_t ipa_uc_rsc; +#endif /* IPA_UC_OFFLOAD */ +}; + +/** + * @brief Specify whether the system is high-latency or low-latency. + * @details + * Indicate whether the system is operating in high-latency (message + * based, e.g. USB) mode or low-latency (memory-mapped, e.g. PCIe) mode. + * Some chips support just one type of host / target interface. + * Other chips support both LL and HL interfaces (e.g. PCIe and USB), + * so the selection will be made based on which bus HW is present, or + * which is preferred if both are present. + * + * @param pdev - handle to the physical device + * @return 1 -> high-latency -OR- 0 -> low-latency + */ +int ol_cfg_is_high_latency(ol_pdev_handle pdev); + +/** + * @brief Specify the range of peer IDs. + * @details + * Specify the maximum peer ID. This is the maximum number of peers, + * minus one. + * This is used by the host to determine the size of arrays indexed by + * peer ID. + * + * @param pdev - handle to the physical device + * @return maximum peer ID + */ +int ol_cfg_max_peer_id(ol_pdev_handle pdev); + +/** + * @brief Specify the max number of virtual devices within a physical device. + * @details + * Specify how many virtual devices may exist within a physical device. + * + * @param pdev - handle to the physical device + * @return maximum number of virtual devices + */ +int ol_cfg_max_vdevs(ol_pdev_handle pdev); + +/** + * @brief Check whether host-side rx PN check is enabled or disabled. + * @details + * Choose whether to allocate rx PN state information and perform + * rx PN checks (if applicable, based on security type) on the host. + * If the rx PN check is specified to be done on the host, the host SW + * will determine which peers are using a security type (e.g. CCMP) that + * requires a PN check. + * + * @param pdev - handle to the physical device + * @return 1 -> host performs rx PN check -OR- 0 -> no host-side rx PN check + */ +int ol_cfg_rx_pn_check(ol_pdev_handle pdev); + + +/** + * @brief Check whether host-side rx forwarding is enabled or disabled. + * @details + * Choose whether to check whether to forward rx frames to tx on the host. + * For LL systems, this rx -> tx host-side forwarding check is typically + * enabled. + * For HL systems, the rx -> tx forwarding check is typically done on the + * target. However, even in HL systems, the host-side rx -> tx forwarding + * will typically be enabled, as a second-tier safety net in case the + * target doesn't have enough memory to store all rx -> tx forwarded frames. + * + * @param pdev - handle to the physical device + * @return 1 -> host does rx->tx forward -OR- 0 -> no host-side rx->tx forward + */ +int ol_cfg_rx_fwd_check(ol_pdev_handle pdev); + +/** + * @brief set rx fwd disable/enable. + * @details + * Choose whether to forward rx frames to tx (where applicable) within the + * WLAN driver, or to leave all forwarding up to the operating system. + * currently only intra-bss fwd is supported. + * + * @param pdev - handle to the physical device + * @param disable_rx_fwd 1 -> no rx->tx forward -> rx->tx forward + */ +void ol_set_cfg_rx_fwd_disabled(ol_pdev_handle pdev, u_int8_t disalbe_rx_fwd); + +/** + * @brief Check whether rx forwarding is enabled or disabled. + * @details + * Choose whether to forward rx frames to tx (where applicable) within the + * WLAN driver, or to leave all forwarding up to the operating system. + * + * @param pdev - handle to the physical device + * @return 1 -> no rx->tx forward -OR- 0 -> rx->tx forward (in host or target) + */ +int ol_cfg_rx_fwd_disabled(ol_pdev_handle pdev); + +/** + * @brief Check whether to perform inter-BSS or intra-BSS rx->tx forwarding. + * @details + * Check whether data received by an AP on one virtual device destined + * to a STA associated with a different virtual device within the same + * physical device should be forwarded within the driver, or whether + * forwarding should only be done within a virtual device. + * + * @param pdev - handle to the physical device + * @return + * 1 -> forward both within and between vdevs + * -OR- + * 0 -> forward only within a vdev + */ +int ol_cfg_rx_fwd_inter_bss(ol_pdev_handle pdev); + +/** + * @brief Specify data frame format used by the OS. + * @details + * Specify what type of frame (802.3 or native WiFi) the host data SW + * should expect from and provide to the OS shim. + * + * @param pdev - handle to the physical device + * @return enumerated data frame format + */ +enum wlan_frm_fmt ol_cfg_frame_type(ol_pdev_handle pdev); + +/** + * @brief Specify the peak throughput. + * @details + * Specify the peak throughput that a system is expected to support. + * The data SW uses this configuration to help choose the size for its + * tx descriptor pool and rx buffer ring. + * The data SW assumes that the peak throughput applies to either rx or tx, + * rather than having separate specs of the rx max throughput vs. the tx + * max throughput. + * + * @param pdev - handle to the physical device + * @return maximum supported throughput in Mbps (not MBps) + */ +int ol_cfg_max_thruput_mbps(ol_pdev_handle pdev); + + +/** + * @brief Specify the maximum number of fragments per tx network buffer. + * @details + * Specify the maximum number of fragments that a tx frame provided to + * the WLAN driver by the OS may contain. + * In LL systems, the host data SW uses this maximum fragment count to + * determine how many elements to allocate in the fragmentation descriptor + * it creates to specify to the tx MAC DMA where to locate the tx frame's + * data. + * This maximum fragments count is only for regular frames, not TSO frames, + * since TSO frames are sent in segments with a limited number of fragments + * per segment. + * + * @param pdev - handle to the physical device + * @return maximum number of fragments that can occur in a regular tx frame + */ +int ol_cfg_netbuf_frags_max(ol_pdev_handle pdev); + + +/** + * @brief For HL systems, specify when to free tx frames. + * @details + * In LL systems, the host's tx frame is referenced by the MAC DMA, and + * thus cannot be freed until the target indicates that it is finished + * transmitting the frame. + * In HL systems, the entire tx frame is downloaded to the target. + * Consequently, the target has its own copy of the tx frame, and the + * host can free the tx frame as soon as the download completes. + * Alternatively, the HL host can keep the frame allocated until the + * target explicitly tells the HL host it is done transmitting the frame. + * This gives the target the option of discarding its copy of the tx + * frame, and then later getting a new copy from the host. + * This function tells the host whether it should retain its copy of the + * transmit frames until the target explicitly indicates it is finished + * transmitting them, or if it should free its copy as soon as the + * tx frame is downloaded to the target. + * + * @param pdev - handle to the physical device + * @return + * 0 -> retain the tx frame until the target indicates it is done + * transmitting the frame + * -OR- + * 1 -> free the tx frame as soon as the download completes + */ +int ol_cfg_tx_free_at_download(ol_pdev_handle pdev); + + +/** + * @brief Low water mark for target tx credit. + * Tx completion handler is invoked to reap the buffers when the target tx + * credit goes below Low Water Mark. + */ +#define OL_CFG_NUM_MSDU_REAP 512 +#define ol_cfg_tx_credit_lwm(pdev) \ + ((CFG_TGT_NUM_MSDU_DESC > OL_CFG_NUM_MSDU_REAP) ? \ + (CFG_TGT_NUM_MSDU_DESC - OL_CFG_NUM_MSDU_REAP) : 0) + +/** + * @brief In a HL system, specify the target initial credit count. + * @details + * The HL host tx data SW includes a module for determining which tx frames + * to download to the target at a given time. + * To make this judgement, the HL tx download scheduler has to know + * how many buffers the HL target has available to hold tx frames. + * Due to the possibility that a single target buffer pool can be shared + * between rx and tx frames, the host may not be able to obtain a precise + * specification of the tx buffer space available in the target, but it + * uses the best estimate, as provided by this configuration function, + * to determine how best to schedule the tx frame downloads. + * + * @param pdev - handle to the physical device + * @return the number of tx buffers available in a HL target + */ +u_int16_t ol_cfg_target_tx_credit(ol_pdev_handle pdev); + + +/** + * @brief Specify the LL tx MSDU header download size. + * @details + * In LL systems, determine how many bytes from a tx frame to download, + * in order to provide the target FW's Descriptor Engine with enough of + * the packet's payload to interpret what kind of traffic this is, + * and who it is for. + * This download size specification does not include the 802.3 / 802.11 + * frame encapsulation headers; it starts with the encapsulated IP packet + * (or whatever ethertype is carried within the ethernet-ish frame). + * The LL host data SW will determine how many bytes of the MSDU header to + * download by adding this download size specification to the size of the + * frame header format specified by the ol_cfg_frame_type configuration + * function. + * + * @param pdev - handle to the physical device + * @return the number of bytes beyond the 802.3 or native WiFi header to + * download to the target for tx classification + */ +int ol_cfg_tx_download_size(ol_pdev_handle pdev); + +/** + * brief Specify where defrag timeout and duplicate detection is handled + * @details + * non-aggregate duplicate detection and timing out stale fragments + * requires additional target memory. To reach max client + * configurations (128+), non-aggregate duplicate detection and the + * logic to time out stale fragments is moved to the host. + * + * @param pdev - handle to the physical device + * @return + * 0 -> target is responsible non-aggregate duplicate detection and + * timing out stale fragments. + * + * 1 -> host is responsible non-aggregate duplicate detection and + * timing out stale fragments. + */ +int ol_cfg_rx_host_defrag_timeout_duplicate_check(ol_pdev_handle pdev); + +/** + * brief Query for the period in ms used for throttling for + * thermal mitigation + * @details + * In LL systems, transmit data throttling is used for thermal + * mitigation where data is paused and resumed during the + * throttle period i.e. the throttle period consists of an + * "on" phase when transmit is allowed and an "off" phase when + * transmit is suspended. This function returns the total + * period used for throttling. + * + * @param pdev - handle to the physical device + * @return the total throttle period in ms + */ +int ol_cfg_throttle_period_ms(ol_pdev_handle pdev); + +/** + * brief Check whether full reorder offload is + * enabled/disable by the host + * @details + * If the host does not support receive reorder (i.e. the + * target performs full receive re-ordering) this will return + * "enabled" + * + * @param pdev - handle to the physical device + * @return 1 - enable, 0 - disable + */ +int ol_cfg_is_full_reorder_offload(ol_pdev_handle pdev); + +typedef enum { + wlan_frm_tran_cap_raw = 0x01, + wlan_frm_tran_cap_native_wifi = 0x02, + wlan_frm_tran_cap_8023 = 0x04, +} wlan_target_fmt_translation_caps; + +/** + * @brief Specify the maximum header size added by SW tx encapsulation + * @details + * This function returns the maximum size of the new L2 header, not the + * difference between the new and old L2 headers. + * Thus, this function returns the maximum 802.11 header size that the + * tx SW may need to add to tx data frames. + * + * @param pdev - handle to the physical device + */ +static inline int +ol_cfg_sw_encap_hdr_max_size(ol_pdev_handle pdev) +{ + /* + * 24 byte basic 802.11 header + * + 6 byte 4th addr + * + 2 byte QoS control + * + 4 byte HT control + * + 8 byte LLC/SNAP + */ + return sizeof(struct ieee80211_qosframe_htc_addr4) + LLC_SNAP_HDR_LEN; +} + +static inline u_int8_t +ol_cfg_tx_encap(ol_pdev_handle pdev) +{ + /* tx encap done in HW */ + return 0; +} + +static inline int +ol_cfg_host_addba(ol_pdev_handle pdev) +{ + /* + * ADDBA negotiation is handled by the target FW for Peregrine + Rome. + */ + return 0; +} + +/** + * @brief If the host SW's ADDBA negotiation fails, should it be retried? + * + * @param pdev - handle to the physical device + */ +static inline int +ol_cfg_addba_retry(ol_pdev_handle pdev) +{ + return 0; /* disabled for now */ +} + +/** + * @brief How many frames to hold in a paused vdev's tx queue in LL systems + */ +static inline int +ol_tx_cfg_max_tx_queue_depth_ll(ol_pdev_handle pdev) +{ + /* + * Store up to 1500 frames for a paused vdev. + * For example, if the vdev is sending 300 Mbps of traffic, and the + * PHY is capable of 600 Mbps, then it will take 56 ms for the PHY to + * drain both the 700 frames that are queued initially, plus the next + * 700 frames that come in while the PHY is catching up. + * So in this example scenario, the PHY will remain fully utilized + * in a MCC system that has a channel-switching period of 56 ms or less. + * 700 frames calculation was correct when FW drain packet without + * any overhead. Actual situation drain overhead will slowdown drain + * speed. And channel period is less than 56 msec + * Worst scenario, 1500 frames should be stored in host. + */ + return 1500; +} + +/** + * @brief Set packet log config in HTT config based on CFG ini configuration + */ +void ol_set_cfg_packet_log_enabled(ol_pdev_handle pdev, u_int8_t val); + +/** + * @brief Get packet log config from HTT config + */ +u_int8_t ol_cfg_is_packet_log_enabled(ol_pdev_handle pdev); + +#ifdef IPA_UC_OFFLOAD +/** + * @brief IPA micro controller data path offload enable or not + * @detail + * This function returns IPA micro controller data path offload + * feature enabled or not + * + * @param pdev - handle to the physical device + */ +unsigned int ol_cfg_ipa_uc_offload_enabled(ol_pdev_handle pdev); +/** + * @brief IPA micro controller data path TX buffer size + * @detail + * This function returns IPA micro controller data path offload + * TX buffer size which should be pre-allocated by driver. + * Default buffer size is 2K + * + * @param pdev - handle to the physical device + */ +unsigned int ol_cfg_ipa_uc_tx_buf_size(ol_pdev_handle pdev); +/** + * @brief IPA micro controller data path TX buffer size + * @detail + * This function returns IPA micro controller data path offload + * TX buffer count which should be pre-allocated by driver. + * + * @param pdev - handle to the physical device + */ +unsigned int ol_cfg_ipa_uc_tx_max_buf_cnt(ol_pdev_handle pdev); +/** + * @brief IPA micro controller data path TX buffer size + * @detail + * This function returns IPA micro controller data path offload + * RX indication ring size which will notified by WLAN FW to IPA + * micro controller + * + * @param pdev - handle to the physical device + */ +unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(ol_pdev_handle pdev); +/** + * @brief IPA micro controller data path TX buffer size + * @param pdev - handle to the physical device + */ +unsigned int ol_cfg_ipa_uc_tx_partition_base(ol_pdev_handle pdev); +#endif /* IPA_UC_OFFLOAD */ +#endif /* _OL_CFG__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_addba_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_addba_api.h new file mode 100644 index 0000000000000..4cc20f00fa5c0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_addba_api.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _OL_CTRL_ADDBA_API_H_ +#define _OL_CTRL_ADDBA_API_H_ +#define ol_ctrl_addba_attach(a,b,c,d,e) 0 +#define ol_ctrl_addba_detach(a) 0 +#define ol_ctrl_addba_init(a,b,c,d,e) 0 +#define ol_ctrl_addba_cleanup(a) 0 +#define ol_ctrl_addba_request_setup(a,b,c,d,e,f) 0 +#define ol_ctrl_addba_response_setup(a,b,c,d,e,f) 0 +#define ol_ctrl_addba_request_process(a,b,c,d,e) 0 +#define ol_ctrl_addba_response_process(a,b,c,d) 0 +#define ol_ctrl_addba_clear(a) 0 +#define ol_ctrl_delba_process(a,b,c) 0 +#define ol_ctrl_addba_get_status(a,b) 0 +#define ol_ctrl_addba_set_response(a,b,c); 0 +#define ol_ctrl_addba_clear_response(a); 0 +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_api.h new file mode 100644 index 0000000000000..9ce5764091e49 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_ctrl_api.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_ctrl_api.h + * @brief Definitions used in multiple external interfaces to the control SW. + */ +#ifndef _OL_CTRL_API__H_ +#define _OL_CTRL_API__H_ + +struct ol_pdev_t; +typedef struct ol_pdev_t* ol_pdev_handle; + +struct ol_vdev_t; +typedef struct ol_vdev_t* ol_vdev_handle; + +struct ol_peer_t; +typedef struct ol_peer_t* ol_peer_handle; + +#endif /* _OL_CTRL_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_defines.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_defines.h new file mode 100644 index 0000000000000..50166964240e3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_defines.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * Offload specific Opaque Data types. + */ +#ifndef _DEV_OL_DEFINES_H +#define _DEV_OL_DEFINES_H + +/** + * @brief Opaque handle of wmi structure + */ +struct wmi_unified; +typedef struct wmi_unified *wmi_unified_t; + +typedef void* ol_scn_t; +/** + * @wmi_event_handler function prototype + */ +typedef int (*wmi_unified_event_handler) (ol_scn_t scn_handle, + u_int8_t *event_buf, + u_int32_t len); + +#endif /* _DEV_OL_DEFINES_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_fw_tx_dbg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_fw_tx_dbg.h new file mode 100644 index 0000000000000..e99ddce593995 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_fw_tx_dbg.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_fw_tx_dbg.h + * + * @details data structs used for uploading summary info about the FW's tx + */ + +#ifndef _OL_FW_TX_DBG__H_ +#define _OL_FW_TX_DBG__H_ + +/* + * Undef ATH_SUPPORT_FW_TX_DBG to remove the FW tx debug feature. + * Removing the FW tx debug feature saves a modest amount of program memory. + * The data memory allocation for the FW tx debug feature is controlled + * by the host --> target resource configuration parameters; even if + * ATH_SUPPORT_FW_TX_DBG is defined, no data memory will be allocated for + * the FW tx debug log unless the host --> target resource configuration + * specifies it. + */ +#define ATH_SUPPORT_FW_TX_DBG 1 /* enabled */ +//#undef ATH_SUPPORT_FW_TX_DBG /* disabled */ + + +#if defined(ATH_TARGET) +#include /* A_UINT32 */ +#else +#include /* A_UINT32 */ +#include /* PREPACK, POSTPACK */ +#endif + +enum ol_fw_tx_dbg_log_mode { + ol_fw_tx_dbg_log_mode_wraparound, /* overwrite old data with new */ + ol_fw_tx_dbg_log_mode_single, /* fill log once, then stop */ +}; + +/* + * tx PPDU stats upload message header + */ +struct ol_fw_tx_dbg_ppdu_msg_hdr { + /* word 0 */ + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_BYTES_WORD 0 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_BYTES_S 0 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_BYTES_M 0x000000ff + A_UINT8 mpdu_bytes_array_len; /* length of array of per-MPDU byte counts */ + + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MSDU_BYTES_WORD 0 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MSDU_BYTES_S 8 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MSDU_BYTES_M 0x0000ff00 + A_UINT8 msdu_bytes_array_len; /* length of array of per-MSDU byte counts */ + + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_MSDUS_WORD 0 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_MSDUS_S 16 + #define OL_FW_TX_DBG_PPDU_HDR_NUM_MPDU_MSDUS_M 0x00ff0000 + A_UINT8 mpdu_msdus_array_len; /* length of array of per-MPDU MSDU counts */ + + A_UINT8 reserved; + + /* word 1 */ + #define OL_FW_TX_DBG_PPDU_HDR_MICROSEC_PER_TICK_WORD 1 + #define OL_FW_TX_DBG_PPDU_HDR_MICROSEC_PER_TICK_S 0 + #define OL_FW_TX_DBG_PPDU_HDR_MICROSEC_PER_TICK_M 0xffffffff + A_UINT32 microsec_per_tick; /* conversion for timestamp entries */ +}; + +/* + * tx PPDU log element / stats upload message element + */ +struct ol_fw_tx_dbg_ppdu_base { + /* word 0 - filled in during tx enqueue */ + #define OL_FW_TX_DBG_PPDU_START_SEQ_NUM_WORD 0 + #define OL_FW_TX_DBG_PPDU_START_SEQ_NUM_S 0 + #define OL_FW_TX_DBG_PPDU_START_SEQ_NUM_M 0x0000ffff + A_UINT16 start_seq_num; + #define OL_FW_TX_DBG_PPDU_START_PN_LSBS_WORD 0 + #define OL_FW_TX_DBG_PPDU_START_PN_LSBS_S 16 + #define OL_FW_TX_DBG_PPDU_START_PN_LSBS_M 0xffff0000 + A_UINT16 start_pn_lsbs; + + /* word 1 - filled in during tx enqueue */ + #define OL_FW_TX_DBG_PPDU_NUM_BYTES_WORD 1 + #define OL_FW_TX_DBG_PPDU_NUM_BYTES_S 0 + #define OL_FW_TX_DBG_PPDU_NUM_BYTES_M 0xffffffff + A_UINT32 num_bytes; + + /* word 2 - filled in during tx enqueue */ + #define OL_FW_TX_DBG_PPDU_NUM_MSDUS_WORD 2 + #define OL_FW_TX_DBG_PPDU_NUM_MSDUS_S 0 + #define OL_FW_TX_DBG_PPDU_NUM_MSDUS_M 0x000000ff + A_UINT8 num_msdus; + #define OL_FW_TX_DBG_PPDU_NUM_MPDUS_WORD 2 + #define OL_FW_TX_DBG_PPDU_NUM_MPDUS_S 8 + #define OL_FW_TX_DBG_PPDU_NUM_MPDUS_M 0x0000ff00 + A_UINT8 num_mpdus; + A_UINT16 + #define OL_FW_TX_DBG_PPDU_EXT_TID_WORD 2 + #define OL_FW_TX_DBG_PPDU_EXT_TID_S 16 + #define OL_FW_TX_DBG_PPDU_EXT_TID_M 0x001f0000 + ext_tid : 5, + #define OL_FW_TX_DBG_PPDU_PEER_ID_WORD 2 + #define OL_FW_TX_DBG_PPDU_PEER_ID_S 21 + #define OL_FW_TX_DBG_PPDU_PEER_ID_M 0xffe00000 + peer_id : 11; + + /* word 3 - filled in during tx enqueue */ + #define OL_FW_TX_DBG_PPDU_TIME_ENQUEUE_WORD 3 + #define OL_FW_TX_DBG_PPDU_TIME_ENQUEUE_S 0 + #define OL_FW_TX_DBG_PPDU_TIME_ENQUEUE_M 0xffffffff + A_UINT32 timestamp_enqueue; + + /* word 4 - filled in during tx completion */ + #define OL_FW_TX_DBG_PPDU_TIME_COMPL_WORD 4 + #define OL_FW_TX_DBG_PPDU_TIME_COMPL_S 0 + #define OL_FW_TX_DBG_PPDU_TIME_COMPL_M 0xffffffff + A_UINT32 timestamp_completion; + + /* word 5 - filled in during tx completion */ + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD 5 + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_S 0 + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_M 0xffffffff + A_UINT32 block_ack_bitmap_lsbs; + + /* word 6 - filled in during tx completion */ + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_MSBS_WORD 6 + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_MSBS_S 0 + #define OL_FW_TX_DBG_PPDU_BLOCK_ACK_MSBS_M 0xffffffff + A_UINT32 block_ack_bitmap_msbs; + + /* word 7 - filled in during tx completion (enqueue would work too) */ + #define OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD 7 + #define OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_S 0 + #define OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_M 0xffffffff + A_UINT32 enqueued_bitmap_lsbs; + + /* word 8 - filled in during tx completion (enqueue would work too) */ + #define OL_FW_TX_DBG_PPDU_ENQUEUED_MSBS_WORD 8 + #define OL_FW_TX_DBG_PPDU_ENQUEUED_MSBS_S 0 + #define OL_FW_TX_DBG_PPDU_ENQUEUED_MSBS_M 0xffffffff + A_UINT32 enqueued_bitmap_msbs; + + /* word 9 - filled in during tx completion */ + #define OL_FW_TX_DBG_PPDU_RATE_CODE_WORD 9 + #define OL_FW_TX_DBG_PPDU_RATE_CODE_S 0 + #define OL_FW_TX_DBG_PPDU_RATE_CODE_M 0x000000ff + A_UINT8 rate_code; + #define OL_FW_TX_DBG_PPDU_RATE_FLAGS_WORD 9 + #define OL_FW_TX_DBG_PPDU_RATE_FLAGS_S 8 + #define OL_FW_TX_DBG_PPDU_RATE_FLAGS_M 0x0000ff00 + A_UINT8 rate_flags; /* includes dynamic bandwidth info */ + #define OL_FW_TX_DBG_PPDU_TRIES_WORD 9 + #define OL_FW_TX_DBG_PPDU_TRIES_S 16 + #define OL_FW_TX_DBG_PPDU_TRIES_M 0x00ff0000 + A_UINT8 tries; + #define OL_FW_TX_DBG_PPDU_COMPLETE_WORD 9 + #define OL_FW_TX_DBG_PPDU_COMPLETE_S 24 + #define OL_FW_TX_DBG_PPDU_COMPLETE_M 0xff000000 + A_UINT8 complete; +}; + + +#endif /* _OL_FW_TX_DBG__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_api.h new file mode 100644 index 0000000000000..3df24b466b39c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_api.h @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_htt_api.h + * @brief Specify the general HTT API functions called by the host data SW. + * @details + * This file declares the HTT API functions that are not specific to + * either tx nor rx. + */ +#ifndef _OL_HTT_API__H_ +#define _OL_HTT_API__H_ + +#include /* adf_os_device_t */ +#include /* adf_nbuf_t */ +#include /* A_STATUS */ +#include /* HTC_HANDLE */ +#include /* ol_pdev_handle */ +#include /* ol_txrx_pdev_handle */ +#include "htt.h" /* htt_dbg_stats_type, etc. */ + +/* TID */ +#define OL_HTT_TID_NON_QOS_UNICAST 16 +#define OL_HTT_TID_NON_QOS_MCAST_BCAST 18 + + +struct htt_pdev_t; +typedef struct htt_pdev_t *htt_pdev_handle; + +/** + * @brief Allocate and initialize a HTT instance. + * @details + * This function allocates and initializes an HTT instance. + * This involves allocating a pool of HTT tx descriptors in + * consistent memory, allocating and filling a rx ring (LL only), + * and connecting the HTC's HTT_DATA_MSG service. + * The HTC service connect call will block, so this function + * needs to be called in passive context. + * Because HTC setup has not been completed at the time this function + * is called, this function cannot send any HTC messages to the target. + * Messages to configure the target are instead sent in the + * htc_attach_target function. + * + * @param txrx_pdev - data SW's physical device handle + * (used as context pointer during HTT -> txrx calls) + * @param ctrl_pdev - control SW's physical device handle + * (used to query configuration functions) + * @param osdev - abstract OS device handle + * (used for mem allocation) + * @param desc_pool_size - number of HTT descriptors to (pre)allocate + * @return success -> HTT pdev handle; failure -> NULL + */ +htt_pdev_handle +htt_attach( + ol_txrx_pdev_handle txrx_pdev, + ol_pdev_handle ctrl_pdev, + HTC_HANDLE htc_pdev, + adf_os_device_t osdev, + int desc_pool_size); + +/** + * @brief Send HTT configuration messages to the target. + * @details + * For LL only, this function sends a rx ring configuration message to the + * target. For HL, this function is a no-op. + * + * @param htt_pdev - handle to the HTT instance being initialized + */ +A_STATUS +htt_attach_target(htt_pdev_handle htt_pdev); + +/** + * @brief modes that a virtual device can operate as + * @details + * A virtual device can operate as an AP, an IBSS, or a STA (client). + * or in monitor mode + */ +enum htt_op_mode { + htt_op_mode_unknown, + htt_op_mode_ap, + htt_op_mode_ibss, + htt_op_mode_sta, + htt_op_mode_monitor, +}; + +/* no-ops */ +#define htt_vdev_attach(htt_pdev, vdev_id, op_mode) +#define htt_vdev_detach(htt_pdev, vdev_id) +#define htt_peer_qos_update(htt_pdev, peer_id, qos_capable) +#define htt_peer_uapsdmask_update(htt_pdev, peer_id, uapsd_mask) + +/** + * @brief Deallocate a HTT instance. + * + * @param htt_pdev - handle to the HTT instance being torn down + */ +void +htt_detach(htt_pdev_handle htt_pdev); + +/** + * @brief Stop the communication between HTT and target + * @details + * For ISOC solution, this function stop the communication between HTT and target. + * For Peregrine/Rome, it's already stopped by ol_ath_disconnect_htc + * before ol_txrx_pdev_detach called in ol_ath_detach. So this function is a no-op. + * Peregrine/Rome HTT layer is on top of HTC while ISOC solution HTT layer is + * on top of DXE layer. + * + * @param htt_pdev - handle to the HTT instance being initialized + */ +void +htt_detach_target(htt_pdev_handle htt_pdev); + +/* + * @brief Tell the target side of HTT to suspend H2T processing until synced + * @param htt_pdev - the host HTT object + * @param sync_cnt - what sync count value the target HTT FW should wait for + * before resuming H2T processing + */ +A_STATUS +htt_h2t_sync_msg(htt_pdev_handle htt_pdev, u_int8_t sync_cnt); + + +int +htt_h2t_aggr_cfg_msg(htt_pdev_handle htt_pdev, + int max_subfrms_ampdu, + int max_subfrms_amsdu); + +/** + * @brief Get the FW status + * @details + * Trigger FW HTT to retrieve FW status. + * A separate HTT message will come back with the statistics we want. + * + * @param pdev - handle to the HTT instance + * @param stats_type_upload_mask - bitmask identifying which stats to upload + * @param stats_type_reset_mask - bitmask identifying which stats to reset + * @param cookie - unique value to distinguish and identify stats requests + * @return 0 - succeed to send the request to FW; otherwise, failed to do so. + */ +int +htt_h2t_dbg_stats_get( + struct htt_pdev_t *pdev, + u_int32_t stats_type_upload_mask, + u_int32_t stats_type_reset_mask, + u_int8_t cfg_stats_type, + u_int32_t cfg_val, + u_int64_t cookie); + +/** + * @brief Get the fields from HTT T2H stats upload message's stats info header + * @details + * Parse the a HTT T2H message's stats info tag-length-value header, + * to obtain the stats type, status, data lenght, and data address. + * + * @param stats_info_list - address of stats record's header + * @param[out] type - which type of FW stats are contained in the record + * @param[out] status - whether the stats are (fully) present in the record + * @param[out] length - how large the data portion of the stats record is + * @param[out] stats_data - where the data portion of the stats record is + */ +void +htt_t2h_dbg_stats_hdr_parse( + u_int8_t *stats_info_list, + enum htt_dbg_stats_type *type, + enum htt_dbg_stats_status *status, + int *length, + u_int8_t **stats_data); + +/** + * @brief Display a stats record from the HTT T2H STATS_CONF message. + * @details + * Parse the stats type and status, and invoke a type-specified printout + * to display the stats values. + * + * @param stats_data - buffer holding the stats record from the STATS_CONF msg + * @param concise - whether to do a verbose or concise printout + */ +void +htt_t2h_stats_print(u_int8_t *stats_data, int concise); + +#ifndef HTT_DEBUG_LEVEL +#if defined(DEBUG) +#define HTT_DEBUG_LEVEL 10 +#else +#define HTT_DEBUG_LEVEL 0 +#endif +#endif + +#if HTT_DEBUG_LEVEL > 5 +void htt_display(htt_pdev_handle pdev, int indent); +#else +#define htt_display(pdev, indent) +#endif + +#define HTT_DXE_RX_LOG 0 +#define htt_rx_reorder_log_print(pdev) + +#ifdef IPA_UC_OFFLOAD +/** + * @brief send IPA UC resource config message to firmware with HTT message + * @details + * send IPA UC resource config message to firmware with HTT message + * + * @param pdev - handle to the HTT instance + */ +int +htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev); + +/** + * @brief Client request resource information + * @details + * OL client will reuqest IPA UC related resource information + * Resource information will be distributted to IPA module + * All of the required resources should be pre-allocated + * + * @param pdev - handle to the HTT instance + * @param ce_sr_base_paddr - copy engine source ring base physical address + * @param ce_sr_ring_size - copy engine source ring size + * @param ce_reg_paddr - copy engine register physical address + * @param tx_comp_ring_base_paddr - tx comp ring base physical address + * @param tx_comp_ring_size - tx comp ring size + * @param tx_num_alloc_buffer - number of allocated tx buffer + * @param rx_rdy_ring_base_paddr - rx ready ring base physical address + * @param rx_rdy_ring_size - rx ready ring size + * @param rx_proc_done_idx_paddr - rx process done index physical address + */ +int +htt_ipa_uc_get_resource(htt_pdev_handle pdev, + a_uint32_t *ce_sr_base_paddr, + a_uint32_t *ce_sr_ring_size, + a_uint32_t *ce_reg_paddr, + a_uint32_t *tx_comp_ring_base_paddr, + a_uint32_t *tx_comp_ring_size, + a_uint32_t *tx_num_alloc_buffer, + a_uint32_t *rx_rdy_ring_base_paddr, + a_uint32_t *rx_rdy_ring_size, + a_uint32_t *rx_proc_done_idx_paddr); + +/** + * @brief Client set IPA UC doorbell register + * @details + * IPA UC let know doorbell register physical address + * WLAN firmware will use this physical address to notify IPA UC + * + * @param pdev - handle to the HTT instance + * @param ipa_uc_tx_doorbell_paddr - tx comp doorbell physical address + * @param ipa_uc_rx_doorbell_paddr - rx ready doorbell physical address + */ +int +htt_ipa_uc_set_doorbell_paddr(htt_pdev_handle pdev, + a_uint32_t ipa_uc_tx_doorbell_paddr, + a_uint32_t ipa_uc_rx_doorbell_paddr); + +/** + * @brief Client notify IPA UC data path active or not + * + * @param pdev - handle to the HTT instance + * @param uc_active - UC data path is active or not + * @param is_tx - UC TX is active or not + */ +int +htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev, + a_bool_t uc_active, + a_bool_t is_tx); + +/** + * @brief query uc data path stats + * + * @param pdev - handle to the HTT instance + */ +int +htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev); + +/** + * @brief Attach IPA UC data path + * + * @param pdev - handle to the HTT instance + */ +int +htt_ipa_uc_attach(struct htt_pdev_t *pdev); + +/** + * @brief detach IPA UC data path + * + * @param pdev - handle to the HTT instance + */ +void +htt_ipa_uc_detach(struct htt_pdev_t *pdev); +#endif /* IPA_UC_OFFLOAD */ + +#endif /* _OL_HTT_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h new file mode 100644 index 0000000000000..f9a325a9cc7cf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_rx_api.h @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_htt_rx_api.h + * @brief Specify the rx HTT API functions called by the host data SW. + * @details + * This file declares the HTT API functions that are specifically + * related to receive processing. + * In particular, this file specifies methods of the abstract HTT rx + * descriptor, and functions to iterate though a series of rx descriptors + * and rx MSDU buffers. + */ +#ifndef _OL_HTT_RX_API__H_ +#define _OL_HTT_RX_API__H_ + +//#include /* u_int16_t, etc. */ +#include /* u_int16_t, etc. */ +#include /* adf_nbuf_t */ +#include /* a_bool_t */ + +#include /* HTT_RX_IND_MPDU_STATUS */ +#include /* htt_pdev_handle */ + +#include /* ieee80211_rx_status */ +#include + + +/*================ constants and types used in the rx API ===================*/ + +#define HTT_RSSI_INVALID 0x7fff + + +/*================ rx indication message field access methods ===============*/ + +/** + * @brief Check if a rx indication message has a rx reorder flush command. + * @details + * Space is reserved in each rx indication message for a rx reorder flush + * command, to release specified MPDUs from the rx reorder holding array + * before processing the new MPDUs referenced by the rx indication message. + * This rx reorder flush command contains a flag to show whether the command + * is valid within a given rx indication message. + * This function checks the validity flag from the rx indication + * flush command IE within the rx indication message. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @return + * 1 - the message's rx flush command is valid and should be processed + * before processing new rx MPDUs, + * -OR- + * 0 - the message's rx flush command is invalid and should be ignored + */ +int +htt_rx_ind_flush(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg); + +/** + * @brief Return the sequence number starting the range of MPDUs to flush. + * @details + * Read the fields of the rx indication message that identify the start + * and end of the range of MPDUs to flush from the rx reorder holding array + * and send on to subsequent stages of rx processing. + * These sequence numbers are the 6 LSBs of the 12-bit 802.11 sequence + * number. These sequence numbers are masked with the block ack window size, + * rounded up to a power of two (minus one, to create a bitmask) to obtain + * the corresponding index into the rx reorder holding array. + * The series of MPDUs to flush includes the one specified by the start + * sequence number. + * The series of MPDUs to flush excludes the one specified by the end + * sequence number; the MPDUs up to but not including the end sequence number + * are to be flushed. + * These start and end seq num fields are only valid if the "flush valid" + * flag is set. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @param seq_num_start - (call-by-reference output) sequence number + * for the start of the range of MPDUs to flush + * @param seq_num_end - (call-by-reference output) sequence number + * for the end of the range of MPDUs to flush + */ +void +htt_rx_ind_flush_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + unsigned *seq_num_start, + unsigned *seq_num_end); + +/** + * @brief Check if a rx indication message has a rx reorder release command. + * @details + * Space is reserved in each rx indication message for a rx reorder release + * command, to release specified MPDUs from the rx reorder holding array + * after processing the new MPDUs referenced by the rx indication message. + * This rx reorder release command contains a flag to show whether the command + * is valid within a given rx indication message. + * This function checks the validity flag from the rx indication + * release command IE within the rx indication message. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @return + * 1 - the message's rx release command is valid and should be processed + * after processing new rx MPDUs, + * -OR- + * 0 - the message's rx release command is invalid and should be ignored + */ +int +htt_rx_ind_release(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg); + +/** + * @brief Return the sequence number starting the range of MPDUs to release. + * @details + * Read the fields of the rx indication message that identify the start + * and end of the range of MPDUs to release from the rx reorder holding + * array and send on to subsequent stages of rx processing. + * These sequence numbers are the 6 LSBs of the 12-bit 802.11 sequence + * number. These sequence numbers are masked with the block ack window size, + * rounded up to a power of two (minus one, to create a bitmask) to obtain + * the corresponding index into the rx reorder holding array. + * The series of MPDUs to release includes the one specified by the start + * sequence number. + * The series of MPDUs to release excludes the one specified by the end + * sequence number; the MPDUs up to but not including the end sequence number + * are to be released. + * These start and end seq num fields are only valid if the "release valid" + * flag is set. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @param seq_num_start - (call-by-reference output) sequence number + * for the start of the range of MPDUs to release + * @param seq_num_end - (call-by-reference output) sequence number + * for the end of the range of MPDUs to release + */ +void +htt_rx_ind_release_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + unsigned *seq_num_start, + unsigned *seq_num_end); + +/* + * For now, the host HTT -> host data rx status enum + * exactly matches the target HTT -> host HTT rx status enum; + * no translation is required. + * However, the host data SW should only use the htt_rx_status, + * so that in the future a translation from target HTT rx status + * to host HTT rx status can be added, if the need ever arises. + */ +enum htt_rx_status { + htt_rx_status_unknown = HTT_RX_IND_MPDU_STATUS_UNKNOWN, + htt_rx_status_ok = HTT_RX_IND_MPDU_STATUS_OK, + htt_rx_status_err_fcs = HTT_RX_IND_MPDU_STATUS_ERR_FCS, + htt_rx_status_err_dup = HTT_RX_IND_MPDU_STATUS_ERR_DUP, + htt_rx_status_err_replay = HTT_RX_IND_MPDU_STATUS_ERR_REPLAY, + htt_rx_status_err_inv_peer = HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER, + htt_rx_status_ctrl_mgmt_null = HTT_RX_IND_MPDU_STATUS_MGMT_CTRL, + htt_rx_status_tkip_mic_err = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR, + + htt_rx_status_err_misc = HTT_RX_IND_MPDU_STATUS_ERR_MISC +}; + +/** + * @brief Check the status MPDU range referenced by a rx indication message. + * @details + * Check the status of a range of MPDUs referenced by a rx indication message. + * This status determines whether the MPDUs should be processed or discarded. + * If the status is OK, then the MPDUs within the range should be processed + * as usual. + * Otherwise (FCS error, duplicate error, replay error, unknown sender error, + * etc.) the MPDUs within the range should be discarded. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @param mpdu_range_num - which MPDU range within the rx ind msg to check, + * starting from 0 + * @param status - (call-by-reference output) MPDU status + * @param mpdu_count - (call-by-reference output) count of MPDUs comprising + * the specified MPDU range + */ +void +htt_rx_ind_mpdu_range_info( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + int mpdu_range_num, + enum htt_rx_status *status, + int *mpdu_count); + +/** + * @brief Return the RSSI provided in a rx indication message. + * @details + * Return the RSSI from an rx indication message, converted to dBm units. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @return RSSI in dBm, or HTT_INVALID_RSSI + */ +int16_t +htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg); + + +/*==================== rx MPDU descriptor access methods ====================*/ + +/** + * @brief Return a rx MPDU's sequence number. + * @details + * This function returns the LSBs of the 802.11 sequence number for the + * provided rx MPDU descriptor. + * Depending on the system, 6-12 LSBs from the 802.11 sequence number are + * returned. (Typically, either the 8 or 12 LSBs are returned.) + * This sequence number is masked with the block ack window size, + * rounded up to a power of two (minus one, to create a bitmask) to obtain + * the corresponding index into the rx reorder holding array. + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return the LSBs of the sequence number for the MPDU + */ +extern a_uint16_t +(*htt_rx_mpdu_desc_seq_num)(htt_pdev_handle pdev, void *mpdu_desc); + +/** + * @brief Return a rx MPDU's rx reorder array index, based on sequence number. + * @details + * This function returns a sequence-number based index into the rx + * reorder array for the specified MPDU. + * In some systems, this rx reorder array is simply the LSBs of the + * sequence number, or possibly even the full sequence number. + * To support such systems, the returned index has to be masked with + * the power-of-two array size before using the value to index the + * rx reorder array. + * In other systems, this rx reorder array index is + * (sequence number) % (block ack window size) + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return the rx reorder array index the MPDU goes into + */ +/* use sequence number (or LSBs thereof) as rx reorder array index */ +#define htt_rx_mpdu_desc_reorder_idx htt_rx_mpdu_desc_seq_num + +union htt_rx_pn_t { + /* WEP: 24-bit PN */ + u_int32_t pn24; + + /* TKIP or CCMP: 48-bit PN */ + u_int64_t pn48; + + /* WAPI: 128-bit PN */ + u_int64_t pn128[2]; +}; + +/** + * @brief Find the packet number (PN) for a MPDU. + * @details + * This function only applies when the rx PN check is configured to be + * performed in the host rather than the target, and on peers using a + * security type for which a PN check applies. + * The pn_len_bits argument is used to determine which element of the + * htt_rx_pn_t union to deposit the PN value read from the MPDU descriptor + * into. + * A 24-bit PN is deposited into pn->pn24. + * A 48-bit PN is deposited into pn->pn48. + * A 128-bit PN is deposited in little-endian order into pn->pn128. + * Specifically, bits 63:0 of the PN are copied into pn->pn128[0], while + * bits 127:64 of the PN are copied into pn->pn128[1]. + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @param pn - the location to copy the packet number into + * @param pn_len_bits - the PN size, in bits + */ +extern void (*htt_rx_mpdu_desc_pn)( + htt_pdev_handle pdev, + void *mpdu_desc, + union htt_rx_pn_t *pn, + int pn_len_bits); + +/** + * @brief Return the TSF timestamp indicating when a MPDU was received. + * @details + * This function provides the timestamp indicating when the PPDU that + * the specified MPDU belongs to was received. + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return 32 LSBs of TSF time at which the MPDU's PPDU was received + */ +u_int32_t +htt_rx_mpdu_desc_tsf32( + htt_pdev_handle pdev, + void *mpdu_desc); + +/** + * @brief Return the 802.11 header of the MPDU + * @details + * This function provides a pointer to the start of the 802.11 header + * of the Rx MPDU + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return pointer to 802.11 header of the received MPDU + */ +char * +htt_rx_mpdu_wifi_hdr_retrieve( + htt_pdev_handle pdev, + void *mpdu_desc); + +/** + * @brief Return the RSSI provided in a rx descriptor. + * @details + * Return the RSSI from a rx descriptor, converted to dBm units. + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return RSSI in dBm, or HTT_INVALID_RSSI + */ +int16_t +htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc); + + +/*==================== rx MSDU descriptor access methods ====================*/ + +/** + * @brief Check if a MSDU completes a MPDU. + * @details + * When A-MSDU aggregation is used, a single MPDU will consist of + * multiple MSDUs. This function checks a MSDU's rx descriptor to + * see whether the MSDU is the final MSDU within a MPDU. + * + * @param pdev - the handle of the physical device the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - there are subsequent MSDUs within the A-MSDU / MPDU + * -OR- + * 1 - this is the last MSDU within its MPDU + */ +extern a_bool_t (*htt_rx_msdu_desc_completes_mpdu)( + htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Check if a MSDU is first msdu of MPDU. + * @details + * When A-MSDU aggregation is used, a single MPDU will consist of + * multiple MSDUs. This function checks a MSDU's rx descriptor to + * see whether the MSDU is the first MSDU within a MPDU. + * + * @param pdev - the handle of the physical device the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - this is interior MSDU in the A-MSDU / MPDU + * -OR- + * 1 - this is the first MSDU within its MPDU + */ +extern a_bool_t (*htt_rx_msdu_first_msdu_flag)( + htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Retrieve encrypt bit from a mpdu desc. + * @details + * Fw will pass all the frame to the host whether encrypted or not, and will + * indicate the encrypt flag in the desc, this function is to get the info and used + * to make a judge whether should make pn check, because non-encrypted frames + * always get the same pn number 0. + * + * @param pdev - the HTT instance the rx data was received on + * @param mpdu_desc - the abstract descriptor for the MPDU in question + * @return 0 - the frame was not encrypted + * 1 - the frame was encrypted + */ +extern a_bool_t +(*htt_rx_mpdu_is_encrypted)(htt_pdev_handle pdev, void *mpdu_desc); + +/** + * @brief Indicate whether a rx desc has a WLAN unicast vs. mcast/bcast flag. + * @details + * A flag indicating whether a MPDU was delivered over WLAN as unicast or + * multicast/broadcast may be only valid once per MPDU (LL), or within each + * rx descriptor for the MSDUs within the MPDU (HL). (In practice, it is + * unlikely that A-MSDU aggregation will be used in HL, so typically HL will + * only have one MSDU per MPDU anyway.) + * This function indicates whether the specified rx descriptor contains + * a WLAN ucast vs. mcast/bcast flag. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - The rx descriptor does not contain a WLAN ucast vs. mcast flag. + * -OR- + * 1 - The rx descriptor has a valid WLAN ucast vs. mcast flag. + */ +extern int (*htt_rx_msdu_has_wlan_mcast_flag)( + htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Indicate whether a MSDU was received as unicast or mcast/bcast + * @details + * Indicate whether the MPDU that the specified MSDU belonged to was + * delivered over the WLAN as unicast, or as multicast/broadcast. + * This query can only be performed on rx descriptors for which + * htt_rx_msdu_has_wlan_mcast_flag is true. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - The MSDU was delivered over the WLAN as unicast. + * -OR- + * 1 - The MSDU was delivered over the WLAN as broadcast or multicast. + */ +extern a_bool_t (*htt_rx_msdu_is_wlan_mcast)( + htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Indicate whether a MSDU was received as a fragmented frame + * @details + * This query can only be performed on LL system. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - The MSDU was a non-fragmented frame. + * -OR- + * 1 - The MSDU was fragmented frame. + */ +extern int (*htt_rx_msdu_is_frag)( + htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Indicate if a MSDU should be delivered to the OS shim or discarded. + * @details + * Indicate whether a MSDU should be discarded or delivered to the OS shim. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - The MSDU should be delivered to the OS + * -OR- + * non-zero - The MSDU should not be delivered to the OS. + * If the "forward" flag is set, it should be forwarded to tx. + * Else, it should be discarded. + */ +int +htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Indicate whether a MSDU should be forwarded to tx. + * @details + * Indicate whether a MSDU should be forwarded to tx, e.g. for intra-BSS + * STA-to-STA forwarding in an AP, or for multicast echo in an AP. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - The MSDU should not be forwarded + * -OR- + * non-zero - The MSDU should be forwarded. + * If the "discard" flag is set, then the original MSDU can be + * directly forwarded into the tx path. + * Else, a copy (clone?) of the rx MSDU needs to be created to + * send to the tx path. + */ +int +htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Indicate whether a MSDU's contents need to be inspected. + * @details + * Indicate whether the host data SW needs to examine the contents of the + * received MSDU, and based on the packet type infer what special handling + * to provide for the MSDU. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @return + * 0 - No inspection + special handling is required. + * -OR- + * non-zero - Inspect the MSDU contents to infer what special handling + * to apply to the MSDU. + */ +int +htt_rx_msdu_inspect(htt_pdev_handle pdev, void *msdu_desc); + +/** + * @brief Provide all action specifications for a rx MSDU + * @details + * Provide all action specifications together. This provides the same + * information in a single function call as would be provided by calling + * the functions htt_rx_msdu_discard, htt_rx_msdu_forward, and + * htt_rx_msdu_inspect. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @param[out] discard - 1: discard the MSDU, 0: deliver the MSDU to the OS + * @param[out] forward - 1: forward the rx MSDU to tx, 0: no rx->tx forward + * @param[out] inspect - 1: process according to MSDU contents, 0: no inspect + */ +void +htt_rx_msdu_actions( + htt_pdev_handle pdev, + void *msdu_desc, + int *discard, + int *forward, + int *inspect); + +/** + * @brief Get the key id sent in IV of the frame + * @details + * Provide the key index octet which is taken from IV. + * This is valid only for the first MSDU. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the abstract descriptor for the MSDU in question + * @key_id - Key id octet + * @return indication of whether key id access is successful + * A_TRUE - Success + * A_FALSE - if this is not first msdu + */ +extern a_bool_t +(*htt_rx_msdu_desc_key_id)( + htt_pdev_handle pdev, + void *mpdu_desc, + u_int8_t *key_id); + +/*====================== rx MSDU + descriptor delivery ======================*/ + +/** + * @brief Return a linked-list of network buffer holding the next rx A-MSDU. + * @details + * In some systems, the rx MSDUs are uploaded along with the rx + * indication message, while in other systems the rx MSDUs are uploaded + * out of band, via MAC DMA. + * This function provides an abstract way to obtain a linked-list of the + * next MSDUs, regardless of whether the MSDU was delivered in-band with + * the rx indication message, or out of band through MAC DMA. + * In a LL system, this function returns a linked list of the one or more + * MSDUs that together comprise an A-MSDU. + * In a HL system, this function returns a degenerate linked list consisting + * of a single MSDU (head_msdu == tail_msdu). + * This function also makes sure each MSDU's rx descriptor can be found + * through the MSDU's network buffer. + * In most systems, this is trivial - a single network buffer stores both + * the MSDU rx descriptor and the MSDU payload. + * In systems where the rx descriptor is in a separate buffer from the + * network buffer holding the MSDU payload, a pointer to the rx descriptor + * has to be stored in the network buffer. + * After this function call, the descriptor for a given MSDU can be + * obtained via the htt_rx_msdu_desc_retrieve function. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @param head_msdu - call-by-reference network buffer handle, which gets set + * in this function to point to the head MSDU of the A-MSDU + * @param tail_msdu - call-by-reference network buffer handle, which gets set + * in this function to point to the tail MSDU of the A-MSDU, or the + * same MSDU that the head_msdu points to if only a single MSDU is + * delivered at a time. + * @return indication of whether any MSDUs in the AMSDU use chaining: + * 0 - no buffer chaining + * 1 - buffers are chained + */ +extern int +(*htt_rx_amsdu_pop)( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu); + +extern int +(*htt_rx_frag_pop)( + htt_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + adf_nbuf_t *head_msdu, + adf_nbuf_t *tail_msdu); + +/** + * @brief Return a linked list of buffers holding one MSDU + * In some systems the buffers are delivered along with offload delivery + * indication message itself, while in other systems the buffers are uploaded + * out of band, via MAC DMA. + * @details + * This function provides an abstract way to obtain a linked-list of the + * buffers corresponding to an msdu, regardless of whether the MSDU was + * delivered in-band with the rx indication message, or out of band through + * MAC DMA. + * In a LL system, this function returns a linked list of one or more + * buffers corresponding to an MSDU + * In a HL system , TODO + * + * @param pdev - the HTT instance the rx data was received on + * @param offload_deliver_msg - the nebuf containing the offload deliver message + * @param head_msdu - call-by-reference network buffer handle, which gets set in this + * function to the head buffer of this MSDU + * @param tail_msdu - call-by-reference network buffer handle, which gets set in this + * function to the tail buffer of this MSDU + */ +extern int +(*htt_rx_offload_msdu_pop)( + htt_pdev_handle pdev, + adf_nbuf_t offload_deliver_msg, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf); + +/** + * @brief Return the rx descriptor for the next rx MPDU. + * @details + * The rx MSDU descriptors may be uploaded as part of the rx indication + * message, or delivered separately out of band. + * This function provides an abstract way to obtain the next MPDU descriptor, + * regardless of whether the MPDU descriptors are delivered in-band with + * the rx indication message, or out of band. + * This is used to iterate through the series of MPDU descriptors referenced + * by a rx indication message. + * The htt_rx_amsdu_pop function should be called before this function + * (or at least before using the returned rx descriptor handle), so that + * the cache location for the rx descriptor will be flushed before the + * rx descriptor gets used. + * + * @param pdev - the HTT instance the rx data was received on + * @param rx_ind_msg - the netbuf containing the rx indication message + * @return next abstract rx descriptor from the series of MPDUs referenced + * by an rx ind msg + */ +extern void * +(*htt_rx_mpdu_desc_list_next)(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg); + +/** + * @brief Retrieve a previously-stored rx descriptor from a MSDU buffer. + * @details + * The data SW will call the htt_rx_msdu_desc_link macro/function to + * link a MSDU's rx descriptor with the buffer holding the MSDU payload. + * This function retrieves the rx MSDU descriptor. + * + * @param pdev - the HTT instance the rx data was received on + * @param msdu - the buffer containing the MSDU payload + * @return the corresponding abstract rx MSDU descriptor + */ +extern void * +(*htt_rx_msdu_desc_retrieve)(htt_pdev_handle pdev, adf_nbuf_t msdu); + +/** + * @brief Free both an rx MSDU descriptor and the associated MSDU buffer. + * @details + * Usually the WLAN driver does not free rx MSDU buffers, but needs to + * do so when an invalid frame (e.g. FCS error) was deposited into the + * queue of rx buffers. + * This function frees both the rx descriptor and the rx frame. + * On some systems, the rx descriptor and rx frame are stored in the + * same buffer, and thus one free suffices for both objects. + * On other systems, the rx descriptor and rx frame are stored + * separately, so distinct frees are internally needed. + * However, in either case, the rx descriptor has been associated with + * the MSDU buffer, and can be retrieved by htt_rx_msdu_desc_retrieve. + * Hence, it is only necessary to provide the MSDU buffer; the HTT SW + * internally finds the corresponding MSDU rx descriptor. + * + * @param htt_pdev - the HTT instance the rx data was received on + * @param rx_msdu_desc - rx descriptor for the MSDU being freed + * @param msdu - rx frame buffer for the MSDU being freed + */ +void +htt_rx_desc_frame_free( + htt_pdev_handle htt_pdev, + adf_nbuf_t msdu); + +/** + * @brief Look up and free the rx descriptor for a MSDU. + * @details + * When the driver delivers rx frames to the OS, it first needs + * to free the associated rx descriptors. + * In some systems the rx descriptors are allocated in the same + * buffer as the rx frames, so this operation is a no-op. + * In other systems, the rx descriptors are stored separately + * from the rx frames, so the rx descriptor has to be freed. + * The descriptor is located from the MSDU buffer with the + * htt_rx_desc_frame_free macro/function. + * + * @param htt_pdev - the HTT instance the rx data was received on + * @param msdu - rx frame buffer for the rx MSDU descriptor being freed + */ +void +htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, adf_nbuf_t msdu); + +/** + * @brief Add new MSDU buffers for the target to fill. + * @details + * In some systems, the underlying upload mechanism (HIF) allocates new rx + * buffers itself. In other systems, the underlying upload mechanism + * (MAC DMA) needs to be provided with new rx buffers. + * This function is used as an abstract method to indicate to the underlying + * data upload mechanism when it is an appropriate time to allocate new rx + * buffers. + * If the allocation is automatically handled, a la HIF, then this function + * call is ignored. + * If the allocation has to be done explicitly, a la MAC DMA, then this + * function provides the context and timing for such replenishment + * allocations. + * + * @param pdev - the HTT instance the rx data will be received on + */ +void +htt_rx_msdu_buff_replenish(htt_pdev_handle pdev); + +/** + * @brief Links list of MSDUs into an single MPDU. Updates RX stats + * @details + * When HW MSDU splitting is turned on each MSDU in an AMSDU MPDU occupies + * a separate wbuf for delivery to the network stack. For delivery to the + * monitor mode interface they need to be restitched into an MPDU. This + * function does this. Also updates the RX status if the MPDU starts + * a new PPDU + * + * @param pdev - the HTT instance the rx data was received on + * @param head_msdu - network buffer handle, which points to the first MSDU + * in the list. This is a NULL terminated list + * @param rx_staus - pointer to the status associated with this MPDU. + * Updated only if there is a new PPDU and new status associated with it + * @param clone_not_reqd - If set the MPDU linking destroys the passed in + * list, else operates on a cloned nbuf + * @return network buffer handle to the MPDU + */ +adf_nbuf_t +htt_rx_restitch_mpdu_from_msdus( + htt_pdev_handle pdev, + adf_nbuf_t head_msdu, + struct ieee80211_rx_status *rx_status, + unsigned clone_not_reqd); + +/** + * @brief Return the sequence number of MPDUs to flush. + * @param pdev - the HTT instance the rx data was received on + * @param rx_frag_ind_msg - the netbuf containing the rx fragment indication message + * @param seq_num_start - (call-by-reference output) sequence number + * for the start of the range of MPDUs to flush + * @param seq_num_end - (call-by-reference output) sequence number + * for the end of the range of MPDUs to flush + */ +void +htt_rx_frag_ind_flush_seq_num_range( + htt_pdev_handle pdev, + adf_nbuf_t rx_frag_ind_msg, + int *seq_num_start, + int *seq_num_end); +/** + * @brief Return the HL rx desc size + * @param pdev - the HTT instance the rx data was received on + * @param msdu_desc - the hl rx desc pointer + * + */ +u_int16_t +htt_rx_msdu_rx_desc_size_hl( + htt_pdev_handle pdev, + void *msdu_desc); + +/** + * @brief populates vowext stats by processing RX desc. + * @param msdu - network buffer handle + * @param vowstats - handle to vow ext stats. + */ +void htt_rx_get_vowext_stats(adf_nbuf_t msdu,struct vow_extstats *vowstats); + +/** + * @brief parses the offload message passed by the target. + * @param pdev - pdev handle + * @param paddr - physical address of the rx buffer + * @param vdev_id - reference to vdev id to be filled + * @param peer_id - reference to the peer id to be filled + * @param tid - reference to the tid to be filled + * @param fw_desc - reference to the fw descriptor to be filled + * @param peer_id - reference to the peer id to be filled + * @param head_buf - reference to the head buffer + * @param tail_buf - reference to the tail buffer + */ +int +htt_rx_offload_paddr_msdu_pop_ll( + htt_pdev_handle pdev, + u_int32_t * msg_word, + int msdu_iter, + int *vdev_id, + int *peer_id, + int *tid, + u_int8_t *fw_desc, + adf_nbuf_t *head_buf, + adf_nbuf_t *tail_buf); +#endif /* _OL_HTT_RX_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_tx_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_tx_api.h new file mode 100644 index 0000000000000..06527bd594b35 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_htt_tx_api.h @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_htt_tx_api.h + * @brief Specify the tx HTT API functions called by the host data SW. + * @details + * This file declares the HTT API functions that are specifically + * related to transmit processing. + * In particular, the methods of the abstract HTT tx descriptor are + * specified. + */ +#ifndef _OL_HTT_TX_API__H_ +#define _OL_HTT_TX_API__H_ + +//#include /* u_int16_t, etc. */ +#include /* u_int16_t, etc. */ +#include /* adf_nbuf_t */ +#include /* wlan_frm_fmt */ + +#include /* needed by inline functions */ +#include +#include /* htt_pdev_handle */ +#include +#include + +/*================ meta-info about tx MSDUs =================================*/ + +/* + * For simplicity, use the IEEE 802.11 frame type values. + */ +enum htt_frm_type { + htt_frm_type_mgmt = 0, + htt_frm_type_ctrl = 1, + htt_frm_type_data = 2 +}; + +/* + * For simplicity, use the IEEE 802.11 frame sub-type values. + */ +enum htt_frm_subtype { + htt_frm_subtype_mgmt_assoc_req = 0, + htt_frm_subtype_mgmt_assoc_resp = 1, + htt_frm_subtype_mgmt_reassoc_req = 2, + htt_frm_subtype_mgmt_reassoc_resp = 3, + htt_frm_subtype_mgmt_probe_req = 4, + htt_frm_subtype_mgmt_probe_resp = 5, + htt_frm_subtype_mgmt_timing_adv = 6, + htt_frm_subtype_mgmt_beacon = 8, + htt_frm_subtype_mgmt_atim = 9, + htt_frm_subtype_mgmt_disassoc = 10, + htt_frm_subtype_mgmt_auth = 11, + htt_frm_subtype_mgmt_deauth = 12, + htt_frm_subtype_mgmt_action = 13, + htt_frm_subtype_mgmt_action_no_ack = 14, + + htt_frm_subtype_data_data = 0, + htt_frm_subtype_data_data_cf_ack = 1, + htt_frm_subtype_data_data_cf_poll = 2, + htt_frm_subtype_data_data_cf_ack_cf_poll = 3, + htt_frm_subtype_data_null = 4, + htt_frm_subtype_data_cf_ack = 5, + htt_frm_subtype_data_cf_poll = 6, + htt_frm_subtype_data_cf_ack_cf_poll = 7, + htt_frm_subtype_data_QoS_data = 8, + htt_frm_subtype_data_QoS_data_cf_ack = 9, + htt_frm_subtype_data_QoS_data_cf_poll = 10, + htt_frm_subtype_data_QoS_data_cf_ack_cf_poll = 11, + htt_frm_subtype_data_QoS_null = 12, + htt_frm_subtype_data_QoS_cf_poll = 14, + htt_frm_subtype_data_QoS_cf_ack_cf_poll = 15, +}; + +/** + * @brief tx MSDU meta-data that HTT may use to program the FW/HW tx descriptor + */ +struct htt_msdu_info_t { + /* the info sub-struct specifies the characteristics of the MSDU */ + struct { + u_int16_t ethertype; + #define HTT_INVALID_PEER_ID 0xffff + u_int16_t peer_id; + u_int8_t vdev_id; + u_int8_t ext_tid; + /* + * l2_hdr_type - L2 format (802.3, native WiFi 802.11, or raw 802.11) + * Based on attach-time configuration, the tx frames provided by the + * OS to the tx data SW are expected to be either 802.3 format or + * the "native WiFi" variant of 802.11 format. + * Internally, the driver may also inject tx frames into the tx + * datapath, and these frames may be either 802.3 format, or 802.11 + * "raw" format, with no further 802.11 encapsulation needed. + * The tx frames are tagged with their frame format, so the target + * FW/HW will know how to interpret the packet's encapsulation + * headers when doing tx classification, and what form of 802.11 + * header encapsulation is needed, if any. + */ + u_int8_t l2_hdr_type; /* enum htt_pkt_type */ + /* + * frame_type - is the tx frame management or data? + * Just to avoid confusion, the enum values for this frame type field + * use the 802.11 frame type values, although it is unexpected for + * control frames to be sent through the host data path. + */ + u_int8_t frame_type; /* enum htt_frm_type */ + /* + * frame subtype - this field specifies the sub-type of management + * frames + * Just to avoid confusion, the enum values for this frame subtype + * field use the 802.11 management frame subtype values. + */ + u_int8_t frame_subtype; /* enum htt_frm_subtype */ + u_int8_t is_unicast; + + /* dest_addr is not currently used. + * It could be used as an input to a Tx BD (Riva tx descriptor) + * signature computation. + u_int8_t *dest_addr; + */ + + u_int8_t l3_hdr_offset; // w.r.t. adf_nbuf_data(msdu), in bytes + + /* l4_hdr_offset is not currently used. + * It could be used to specify to a TCP/UDP checksum computation + * engine where the TCP/UDP header starts. + u_int8_t l4_hdr_offset; // w.r.t. adf_nbuf_data(msdu), in bytes + */ + } info; + /* the action sub-struct specifies how to process the MSDU */ + struct { + u_int8_t use_6mbps; /* mgmt frames: option to force 6 Mbps rate */ + u_int8_t do_encrypt; + u_int8_t do_tx_complete; + u_int8_t tx_comp_req; + + /* + * cksum_offload - Specify whether checksum offload is enabled or not + * Target FW uses this flag to turn on HW checksumming + * 0x0 - No checksum offload + * 0x1 - L3 header checksum only + * 0x2 - L4 checksum only + * 0x3 - L3 header checksum + L4 checksum + */ + adf_nbuf_tx_cksum_t cksum_offload; + } action; +}; + +static inline void +htt_msdu_info_dump(struct htt_msdu_info_t *msdu_info) +{ + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + "HTT MSDU info object (%p)\n", msdu_info); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " ethertype: %#x\n", msdu_info->info.ethertype); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " peer_id: %d\n", msdu_info->info.peer_id); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " vdev_id: %d\n", msdu_info->info.vdev_id); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " ext_tid: %d\n", msdu_info->info.ext_tid); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " l2_hdr_type: %d\n", msdu_info->info.l2_hdr_type); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " frame_type: %d\n", msdu_info->info.frame_type); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " frame_subtype: %d\n", msdu_info->info.frame_subtype); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " is_unicast: %u\n", msdu_info->info.is_unicast); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " l3_hdr_offset: %u\n", msdu_info->info.l3_hdr_offset); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " use 6 Mbps: %d\n", msdu_info->action.use_6mbps); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " do_encrypt: %d\n", msdu_info->action.do_encrypt); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " do_tx_complete: %d\n", msdu_info->action.do_tx_complete); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " is_unicast: %u\n", msdu_info->info.is_unicast); + VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW, + " is_unicast: %u\n", msdu_info->info.is_unicast); +} + + +/*================ tx completion message field access methods ===============*/ + + +/** + * @brief Look up the descriptor ID of the nth MSDU from a tx completion msg. + * @details + * A tx completion message tells the host that the target is done + * transmitting a series of MSDUs. The message uses a descriptor ID + * to identify each such MSDU. This function/macro is used to + * find the ID of one such MSDU referenced by the tx completion message. + * + * @param iterator - tx completion message context provided by HTT to the + * tx completion message handler. This abstract reference to the + * HTT tx completion message's payload allows the data SW's tx + * completion handler to not care about the format of the HTT + * tx completion message. + * @param num - (zero-based) index to specify a single MSDU within the + * series of MSDUs referenced by the tx completion message + * @return descriptor ID for the specified MSDU + */ +u_int16_t +htt_tx_compl_desc_id(void *iterator, int num); + + +/*========================= tx descriptor operations ========================*/ + + +/** + * @brief Allocate a HTT abstract tx descriptor. + * @details + * Allocate a HTT abstract tx descriptor from a pool within "consistent" + * memory, which is accessible by HIF and/or MAC DMA as well as by the + * host CPU. + * It is expected that the tx datapath will allocate HTT tx descriptors + * and link them with datapath SW tx descriptors up front as the driver + * is loaded. Thereafter, the link from datapath SW tx descriptor to + * HTT tx descriptor will be maintained until the driver is unloaded. + * + * @param htt_pdev - handle to the HTT instance making the allocation + * @param[OUT] paddr_lo - physical address of the HTT descriptor + * @return success -> descriptor handle, -OR- failure -> NULL + */ +void * +htt_tx_desc_alloc(htt_pdev_handle htt_pdev, u_int32_t *paddr_lo); + +/** + * @brief Free a HTT abstract tx descriptor. + * + * @param htt_pdev - handle to the HTT instance that made the allocation + * @param htt_tx_desc - the descriptor to free + */ +void +htt_tx_desc_free(htt_pdev_handle htt_pdev, void *htt_tx_desc); + +/** +* @brief Discard all tx frames in the process of being downloaded. +* @details +* This function dicards any tx frames queued in HTT or the layers +* under HTT. +* The download completion callback is invoked on these frames. +* +* @param htt_pdev - handle to the HTT instance +*/ +#if defined(CONFIG_HL_SUPPORT) +#define htt_tx_pending_discard(pdev) /* no-op */ +#else +void +htt_tx_pending_discard(htt_pdev_handle pdev); +#endif + +/** + * @brief Download a MSDU descriptor and (a portion of) the MSDU payload. + * @details + * This function is used within LL systems to download a tx descriptor and + * the initial portion of the tx MSDU payload, and within HL systems to + * download the tx descriptor and the entire tx MSDU payload. + * The HTT layer determines internally how much of the tx descriptor + * actually needs to be downloaded. In particular, the HTT layer does not + * download the fragmentation descriptor, and only for the LL case downloads + * the physical address of the fragmentation descriptor. + * In HL systems, the tx descriptor and the entire frame are downloaded. + * In LL systems, only the tx descriptor and the header of the frame are + * downloaded. To determine how much of the tx frame to download, this + * function assumes the tx frame is the default frame type, as specified + * by ol_cfg_frame_type. "Raw" frames need to be transmitted through the + * alternate htt_tx_send_nonstd function. + * The tx descriptor has already been attached to the adf_nbuf object during + * a preceding call to htt_tx_desc_init. + * + * @param htt_pdev - the handle of the physical device sending the tx data + * @param msdu - the frame being transmitted + * @param msdu_id - unique ID for the frame being transmitted + * @return 0 -> success, -OR- 1 -> failure + */ +int +htt_tx_send_std( + htt_pdev_handle htt_pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id); + +/** + * @brief Download a Batch Of Tx MSDUs + * @details + * Each MSDU already has the MSDU ID stored in the headroom of the + * netbuf data buffer, and has the HTT tx descriptor already attached + * as a prefix fragment to the netbuf. + * + * @param htt_pdev - the handle of the physical device sending the tx data + * @param head_msdu - the MSDU Head for Tx batch being transmitted + * @param num_msdus - The total Number of MSDU's provided for batch tx + * @return null-terminated linked-list of unaccepted frames + */ +adf_nbuf_t +htt_tx_send_batch( + htt_pdev_handle htt_pdev, + adf_nbuf_t head_msdu, + int num_msdus); + + + +/* The htt scheduler for queued packets in htt + * htt when unable to send to HTC because of lack of resource + * forms a nbuf queue which is flushed when tx completion event from + * target is recieved + */ + +void +htt_tx_sched(htt_pdev_handle pdev); + + +/** + * @brief Same as htt_tx_send_std, but can handle raw frames. + */ +int +htt_tx_send_nonstd( + htt_pdev_handle htt_pdev, + adf_nbuf_t msdu, + u_int16_t msdu_id, + enum htt_pkt_type pkt_type); + +/** + * @brief Initialize the tx descriptor. + * @details + * This function initializes the tx descriptor. + * The values for the standard tx descriptor fields are provided as + * function arguments. Non-standard descriptor fields, which don't + * have function arguments to specify their value, are set to zero. + * An exception to this initialization of non-standard fields to zero + * is the "extended TID" field, which is initialized to the "invalid" + * value (0x1f). + * + * @param pdev - the handle of the physical device sending the tx data + * @param htt_tx_desc - abstract handle to the tx descriptor + * @param htt_tx_desc_paddr_lo - physical address of the HTT tx descriptor + * @param desc_id - ID to tag the descriptor with. + * The target FW uses this ID to identify to the host which MSDUs + * the target is referring to in its tx completion / postpone / drop + * messages. + * This ID is abstract - it is only interpreted inside the host + * tx datapath SW. In practice, though, the ID is an index into an + * array of tx descriptor structs. + * This ID is used for both HL and LL systems, since in both systems + * the target may need to refer to a particular MSDU to explicitly tell + * the host when it may free the MSDU descriptor and network buffer. + * @param msdu - the MSDU that is being prepared for transmission + * @param msdu_info - tx MSDU meta-data + */ + +/* + * Provide a constant to specify the offset of the HTT portion of the + * HTT tx descriptor, to avoid having to export the descriptor defintion. + * The htt module checks internally that this exported offset is consistent + * with the private tx descriptor definition. + * + * Similarly, export a definition of the HTT tx descriptor size, and then + * check internally that this exported constant matches the private tx + * descriptor definition. + */ +#define HTT_TX_DESC_VADDR_OFFSET 8 +#define HTT_TX_DESC_SIZE 24 +static inline +void +htt_tx_desc_init( + htt_pdev_handle pdev, + void *htt_tx_desc, + u_int32_t htt_tx_desc_paddr_lo, + u_int16_t msdu_id, + adf_nbuf_t msdu, + struct htt_msdu_info_t *msdu_info) +{ + u_int32_t *word0, *word1, *word3; + u_int32_t local_word0, local_word1; + struct htt_host_tx_desc_t *htt_host_tx_desc = (struct htt_host_tx_desc_t *) + (((char *) htt_tx_desc) - HTT_TX_DESC_VADDR_OFFSET); + + word0 = (u_int32_t *) htt_tx_desc; + word1 = word0 + 1; + /* + * word2 is frag desc pointer + * word3 is peer_id + */ + word3 = word0 + 3; // Dword 3 + + /* + * HTT Tx Desc is in uncached memory. Used cached writes per word, to + * reduce unnecessary memory access. + */ + + local_word0 = 0; + HTT_H2T_MSG_TYPE_SET(local_word0, HTT_H2T_MSG_TYPE_TX_FRM); + HTT_TX_DESC_PKT_TYPE_SET(local_word0, msdu_info->info.l2_hdr_type); + HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id); + HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid); + HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0, msdu_info->action.cksum_offload); + if (pdev->cfg.is_high_latency) + HTT_TX_DESC_TX_COMP_SET(local_word0, msdu_info->action.tx_comp_req); + HTT_TX_DESC_NO_ENCRYPT_SET(local_word0, msdu_info->action.do_encrypt ? 0 : 1); + *word0 = local_word0; + + local_word1 = 0; + HTT_TX_DESC_FRM_LEN_SET(local_word1, adf_nbuf_len(msdu)); + HTT_TX_DESC_FRM_ID_SET(local_word1, msdu_id); + *word1 = local_word1; + + /* Initialize peer_id to INVALID_PEER bcoz this is NOT Reinjection path*/ + *word3 = HTT_INVALID_PEER; + + /* + * Specify that the data provided by the OS is a bytestream, + * and thus should not be byte-swapped during the HIF download + * even if the host is big-endian. + * There could be extra fragments added before the OS's fragments, + * e.g. for TSO, so it's incorrect to clear the frag 0 wordstream flag. + * Instead, clear the wordstream flag for the final fragment, which + * is certain to be (one of the) fragment(s) provided by the OS. + * Setting the flag for this final fragment suffices for specifying + * all fragments provided by the OS rather than added by the driver. + */ + adf_nbuf_set_frag_is_wordstream(msdu, adf_nbuf_get_num_frags(msdu) - 1, 0); + + /* store a link to the HTT tx descriptor within the netbuf */ + adf_nbuf_frag_push_head( + msdu, + HTT_TX_DESC_SIZE, + (char *) htt_host_tx_desc, /* virtual addr */ + htt_tx_desc_paddr_lo, 0 /* phys addr MSBs - n/a */); + + /* + * Indicate that the HTT header (and HTC header) is a meta-data + * "wordstream", i.e. series of u_int32_t, rather than a data + * bytestream. + * This allows the HIF download to byteswap the HTT + HTC headers if + * the host is big-endian, to convert to the target's little-endian + * format. + */ + adf_nbuf_set_frag_is_wordstream(msdu, 0, 1); +} + +/** + * @brief Set a flag to indicate that the MSDU in question was postponed. + * @details + * In systems in which the host retains its tx frame until the target sends + * a tx completion, the target has the option of discarding it's copy of + * the tx descriptor (and frame, for HL) and sending a "postpone" message + * to the host, to inform the host that it must eventually download the + * tx descriptor (and frame, for HL). + * Before the host downloads the postponed tx desc/frame again, it will use + * this function to set a flag in the HTT tx descriptor indicating that this + * is a re-send of a postponed frame, rather than a new frame. The target + * uses this flag to keep the correct order between re-sent and new tx frames. + * This function is relevant for LL systems. + * + * @param pdev - the handle of the physical device sending the tx data + * @param desc - abstract handle to the tx descriptor + */ +void +htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc); + +/** + * @brief Set a flag to tell the target that more tx downloads are en route. + * @details + * At times, particularly in response to a U-APSD trigger in a HL system, the + * host will download multiple tx descriptors (+ frames, in HL) in a batch. + * The host will use this function to set a "more" flag in the initial + * and interior frames of the batch, to tell the target that more tx frame + * downloads within the batch are imminent. + * + * @param pdev - the handle of the physical device sending the tx data + * @param desc - abstract handle to the tx descriptor + */ +void +htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc); + +/** + * @brief Specify the number of fragments in the fragmentation descriptor. + * @details + * Specify the number of fragments within the MSDU, i.e. the number of + * elements within the fragmentation descriptor. + * For LL, this is used to terminate the list of fragments used by the + * HW's tx MAC DMA. + * For HL, this is used to terminate the list of fragments provided to + * HTC for download. + * + * @param pdev - the handle of the physical device sending the tx data + * @param desc - abstract handle to the tx descriptor + * @param num_frags - the number of fragments comprising the MSDU + */ +static inline +void +htt_tx_desc_num_frags(htt_pdev_handle pdev, void *desc, u_int32_t num_frags) +{ + /* + * Set the element after the valid frag elems to 0x0, + * to terminate the list of fragments. + */ + *((u_int32_t *) + (((char *) desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0; +} + +/** + * @brief Specify the location and size of a fragment of a tx MSDU. + * @details + * In LL systems, the tx MAC DMA needs to know how the MSDU is constructed + * from fragments. + * In LL and HL systems, the HIF's download DMA to the target (LL: tx desc + * + header of tx payload; HL: tx desc + entire tx payload) needs to know + * where to find the fragments to download. + * The tx data SW uses this function to specify the location and size of + * each of the MSDU's fragments. + * + * @param pdev - the handle of the physical device sending the tx data + * @param desc - abstract handle to the HTT tx descriptor + * @param frag_num - which fragment is being specified (zero-based indexing) + * @param frag_phys_addr - DMA/physical address of the fragment + * @param frag_len - number of bytes within the fragment + */ +static inline +void +htt_tx_desc_frag( + htt_pdev_handle pdev, + void *desc, + int frag_num, + u_int32_t frag_phys_addr, + u_int16_t frag_len) +{ + u_int32_t *word = + (u_int32_t *) (((char *) desc) + HTT_TX_DESC_LEN + frag_num * 8); + *word = frag_phys_addr; + word++; + *word = frag_len; +} + +void htt_tx_desc_frags_table_set( + htt_pdev_handle pdev, + void *desc, + u_int32_t paddr, + int reset); + +/** + * @brief Specify the type and subtype of a tx frame. + * + * @param pdev - the handle of the physical device sending the tx data + * @param type - format of the MSDU (802.3, native WiFi, raw, or mgmt) + * @param sub_type - sub_type (relevant for raw frames) + */ +static inline +void +htt_tx_desc_type( + htt_pdev_handle pdev, + void *htt_tx_desc, + enum wlan_frm_fmt type, + u_int8_t sub_type) +{ + u_int32_t *word0; + + word0 = (u_int32_t *) htt_tx_desc; + /* clear old values */ + *word0 &= ~(HTT_TX_DESC_PKT_TYPE_M | HTT_TX_DESC_PKT_SUBTYPE_M); + /* write new values */ + HTT_TX_DESC_PKT_TYPE_SET(*word0, type); + HTT_TX_DESC_PKT_SUBTYPE_SET(*word0, sub_type); +} + +/***** TX MGMT DESC management APIs ****/ + +/* Number of mgmt descriptors in the pool */ +#define HTT_MAX_NUM_MGMT_DESCS 32 + +/** htt_tx_mgmt_desc_pool_alloc + * @description - allocates the memory for mgmt frame descriptors + * @param - htt pdev object + * @param - num of descriptors to be allocated in the pool + */ +void +htt_tx_mgmt_desc_pool_alloc(struct htt_pdev_t *pdev, A_UINT32 num_elems); + +/** htt_tx_mgmt_desc_alloc + * @description - reserves a mgmt descriptor from the pool + * @param - htt pdev object + * @param - pointer to variable to hold the allocated desc id + * @param - pointer to the mamangement from UMAC + * @return - pointer the allocated mgmt descriptor + */ +adf_nbuf_t +htt_tx_mgmt_desc_alloc(struct htt_pdev_t *pdev, A_UINT32 *desc_id, adf_nbuf_t mgmt_frm); + +/** htt_tx_mgmt_desc_free + * @description - releases the management descriptor back to the pool + * @param - htt pdev object + * @param - descriptor ID + */ +void +htt_tx_mgmt_desc_free(struct htt_pdev_t *pdev, A_UINT8 desc_id, A_UINT32 status); + +/** htt_tx_mgmt_desc_pool_free + * @description - releases all the resources allocated for mgmt desc pool + * @param - htt pdev object + */ +void +htt_tx_mgmt_desc_pool_free(struct htt_pdev_t *pdev); + + +/** + * @brief Provide a buffer to store a 802.11 header added by SW tx encap + * + * @param htt_tx_desc - which frame the 802.11 header is being added to + * @param new_l2_hdr_size - how large the buffer needs to be + */ +#define htt_tx_desc_mpdu_header(htt_tx_desc, new_l2_hdr_size) /*NULL*/ + +/** + * @brief How many tx credits would be consumed by the specified tx frame. + * + * @param msdu - the tx frame in question + * @return number of credits used for this tx frame + */ +#define htt_tx_msdu_credit(msdu) 1 /* 1 credit per buffer */ + + + +#ifdef HTT_DBG +void +htt_tx_desc_display(void *tx_desc); +#else +#define htt_tx_desc_display(tx_desc) +#endif + +static inline +void htt_tx_desc_set_peer_id(void *htt_tx_desc, u_int16_t peer_id) +{ + u_int16_t *peer_id_field_ptr; + + peer_id_field_ptr = (u_int16_t *) + (htt_tx_desc + HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES); + + *peer_id_field_ptr = peer_id; +} +static inline +void htt_tx_desc_set_chanfreq(void *htt_tx_desc, u_int16_t chanfreq) +{ + u_int16_t *chanfreq_field_ptr; + + chanfreq_field_ptr = (u_int16_t *) + (htt_tx_desc + HTT_TX_DESC_CHAN_FREQ_OFFSET_BYTES); + + *chanfreq_field_ptr = chanfreq; +} + +#endif /* _OL_HTT_TX_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_if_athvar.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_if_athvar.h new file mode 100644 index 0000000000000..279caf8b98f0c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_if_athvar.h @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Defintions for the Atheros Wireless LAN controller driver. + */ +#ifndef _DEV_OL_ATH_ATHVAR_H +#define _DEV_OL_ATH_ATHVAR_H + +#include +#include +#include +#include "adf_os_types.h" +#include "adf_os_lock.h" +#include "wmi_unified_api.h" +#include "htc_api.h" +#include "bmi_msg.h" +#include "ol_txrx_api.h" +#include "ol_txrx_ctrl_api.h" +#include "ol_txrx_osif_api.h" +#include "ol_params.h" +#include + +#ifdef CONFIG_CNSS +#include +#endif + + +#include "ol_ctrl_addba_api.h" +typedef void * hif_handle_t; + +struct ol_version { + u_int32_t host_ver; + u_int32_t target_ver; + u_int32_t wlan_ver; + u_int32_t wlan_ver_1; + u_int32_t abi_ver; +}; + +typedef enum _ATH_BIN_FILE { + ATH_OTP_FILE, + ATH_FIRMWARE_FILE, + ATH_PATCH_FILE, + ATH_BOARD_DATA_FILE, + ATH_FLASH_FILE, + ATH_SETUP_FILE, +} ATH_BIN_FILE; + +typedef enum _ol_target_status { + OL_TRGET_STATUS_CONNECTED = 0, /* target connected */ + OL_TRGET_STATUS_RESET, /* target got reset */ + OL_TRGET_STATUS_EJECT, /* target got ejected */ + OL_TRGET_STATUS_SUSPEND /*target got suspend*/ +} ol_target_status; + +enum ol_ath_tx_ecodes { + TX_IN_PKT_INCR=0, + TX_OUT_HDR_COMPL, + TX_OUT_PKT_COMPL, + PKT_ENCAP_FAIL, + TX_PKT_BAD, + RX_RCV_MSG_RX_IND, + RX_RCV_MSG_PEER_MAP, + RX_RCV_MSG_TYPE_TEST +} ; + +#ifdef HIF_SDIO +#define MAX_FILE_NAME 20 +struct ol_fw_files { + char image_file[MAX_FILE_NAME]; + char board_data[MAX_FILE_NAME]; + char otp_data[MAX_FILE_NAME]; + char utf_file[MAX_FILE_NAME]; + char utf_board_data[MAX_FILE_NAME]; + char setup_file[MAX_FILE_NAME]; + char epping_file[MAX_FILE_NAME]; +}; +#endif + +#ifndef ATH_CAP_DCS_CWIM +#define ATH_CAP_DCS_CWIM 0x1 +#define ATH_CAP_DCS_WLANIM 0x2 +#endif +/* + * structure to hold the packet error count for CE and hif layer +*/ +struct ol_ath_stats { + int hif_pipe_no_resrc_count; + int ce_ring_delta_fail_count; +}; + +#ifdef HIF_USB +/* Magic patterns for FW to report crash information (Rome USB) */ +#define FW_ASSERT_PATTERN 0x0000c600 +#define FW_REG_PATTERN 0x0000d600 +#define FW_REG_END_PATTERN 0x0000e600 +#define FW_RAMDUMP_PATTERN 0x0000f600 +#define FW_RAMDUMP_END_PATTERN 0x0000f601 +#define FW_RAMDUMP_PATTERN_MASK 0xfffffff0 + +#define FW_REG_DUMP_CNT 60 + +/* FW RAM segments (Rome USB) */ +enum { + FW_RAM_SEG_DRAM, + FW_RAM_SEG_IRAM, + FW_RAM_SEG_AXI, + FW_RAM_SEG_CNT +}; + +/* Allocate 384K memory to save each segment of ram dump */ +#define FW_RAMDUMP_SEG_SIZE 393216 + +/* structure to save RAM dump information */ +struct fw_ramdump { + A_UINT32 start_addr; + A_UINT32 length; + A_UINT8 *mem; +}; +#endif + +struct ol_softc { + /* + * handle for code that uses the osdep.h version of OS + * abstraction primitives + */ + osdev_t sc_osdev; + + /* + * handle for code that uses adf version of OS + * abstraction primitives + */ + adf_os_device_t adf_dev; + + struct ol_version version; + + /* Packet statistics */ + struct ol_ath_stats pkt_stats; + + u_int32_t target_type; /* A_TARGET_TYPE_* */ + u_int32_t target_fw_version; + u_int32_t target_version; + u_int32_t target_revision; + u_int8_t crm_version_string[64]; /* store pHalStartRsp->startRspParams.wcnssCrmVersionString */ + u_int8_t wlan_version_string[64]; /* store pHalStartRsp->startRspParams.wcnssWlanVersionString */ + ol_target_status target_status; /* target status */ + bool is_sim; /* is this a simulator */ + u_int8_t *cal_in_flash; /* calibration data is stored in flash */ + void *cal_mem; /* virtual address for the calibration data on the flash */ + + WLAN_INIT_STATUS wlan_init_status; /* status of target init */ + + /* BMI info */ + void *bmi_ol_priv; /* OS-dependent private info for BMI */ + bool bmiDone; + bool bmiUADone; + u_int8_t *pBMICmdBuf; + dma_addr_t BMICmd_pa; + OS_DMA_MEM_CONTEXT(bmicmd_dmacontext) + + u_int8_t *pBMIRspBuf; + dma_addr_t BMIRsp_pa; + u_int32_t last_rxlen; /* length of last response */ + OS_DMA_MEM_CONTEXT(bmirsp_dmacontext) + + void *MSI_magic; + dma_addr_t MSI_magic_dma; + OS_DMA_MEM_CONTEXT(MSI_dmacontext) + + /* Handles for Lower Layers : filled in at init time */ + hif_handle_t hif_hdl; +#if defined(HIF_PCI) + struct hif_pci_softc *hif_sc; +#elif defined(HIF_USB) + struct hif_usb_softc *hif_sc; +#else + struct ath_hif_sdio_softc *hif_sc; +#endif + + /* HTC handles */ + void *htc_handle; + + bool IdlePowerSave; + int ProtocolPowerSave; + A_BOOL fEnableBeaconEarlyTermination; + u_int8_t bcnEarlyTermWakeInterval; + + /* ol data path handle */ + ol_txrx_pdev_handle pdev_txrx_handle; + + /* UTF event information */ + struct { + u_int8_t *data; + u_int32_t length; + adf_os_size_t offset; + u_int8_t currentSeq; + u_int8_t expectedSeq; + } utf_event_info; + + struct ol_wow_info *scn_wowInfo; + +#ifdef PERE_IP_HDR_ALIGNMENT_WAR + bool host_80211_enable; /* Enables native-wifi mode on host */ +#endif + bool enableuartprint; /* enable uart/serial prints from target */ + bool enablefwlog; /* enable fwlog */ + /* enable FW self-recovery for Rome USB */ + bool enableFwSelfRecovery; +#ifdef HIF_USB + /* structure to save FW RAM dump (Rome USB) */ + struct fw_ramdump *ramdump[FW_RAM_SEG_CNT]; + A_UINT8 ramdump_index; + bool fw_ram_dumping; +#endif + + bool enablesinglebinary; /* Use single binary for FW */ + HAL_REG_CAPABILITIES hal_reg_capabilities; + struct ol_regdmn *ol_regdmn_handle; + u_int8_t bcn_mode; + u_int8_t arp_override; + /* + * Includes host side stack level stats + + * radio level athstats + */ + struct wlan_dbg_stats ath_stats; + int16_t chan_nf; /* noise_floor */ + u_int32_t min_tx_power; + u_int32_t max_tx_power; + u_int32_t txpowlimit2G; + u_int32_t txpowlimit5G; + u_int32_t txpower_scale; + u_int32_t chan_tx_pwr; + u_int32_t vdev_count; + u_int32_t max_bcn_ie_size; + adf_os_spinlock_t scn_lock; + + u_int8_t vow_extstats; + + u_int8_t scn_dcs; /* if dcs enabled or not*/ + wdi_event_subscribe scn_rx_peer_invalid_subscriber; + u_int8_t proxy_sta; + u_int8_t bcn_enabled; + u_int8_t dtcs; /* Dynamic Tx Chainmask Selection enabled/disabled */ + u_int32_t set_ht_vht_ies:1; /* true if vht ies are set on target */ + bool scn_cwmenable; /*CWM enable/disable state*/ + u_int8_t max_no_of_peers; +#ifdef CONFIG_CNSS + struct cnss_fw_files fw_files; +#elif defined(HIF_SDIO) + struct ol_fw_files fw_files; +#endif +#if defined(CONFIG_CNSS) || defined(HIF_SDIO) + void *ramdump_base; + unsigned long ramdump_address; + unsigned long ramdump_size; +#endif + +#ifdef WLAN_FEATURE_LPSS + bool enablelpasssupport; +#endif +#ifdef FEATURE_SECURE_FIRMWARE + bool enable_fw_hash_check; +#endif +}; + +#ifdef PERE_IP_HDR_ALIGNMENT_WAR +#define ol_scn_host_80211_enable_get(_ol_pdev_hdl) \ + ((struct ol_softc *)(_ol_pdev_hdl))->host_80211_enable +#endif + +struct bcn_buf_entry { + A_BOOL is_dma_mapped; + adf_nbuf_t bcn_buf; + TAILQ_ENTRY(bcn_buf_entry) deferred_bcn_list_elem; +}; + +struct ol_ath_vap_net80211 { + struct ol_softc *av_sc; /* back pointer to softc */ + ol_txrx_vdev_handle av_txrx_handle; /* ol data path handle */ + u_int32_t av_if_id; /* interface id */ + u_int64_t av_tsfadjust; /* Adjusted TSF, host endian */ + bool av_beacon_offload; /* Handle beacons in FW */ + adf_nbuf_t av_wbuf; /* Beacon buffer */ + A_BOOL is_dma_mapped; + os_timer_t av_timer; + bool av_ol_resmgr_wait; /* UMAC waits for target */ + /* event to bringup vap*/ + adf_os_spinlock_t avn_lock; + TAILQ_HEAD(, bcn_buf_entry) deferred_bcn_list; + os_timer_t av_target_stop_timer; + bool av_set_target_stopping; + bool av_target_stopped; +}; +#define OL_ATH_VAP_NET80211(_vap) ((struct ol_ath_vap_net80211 *)(_vap)) + +struct ol_ath_node_net80211 { + ol_txrx_peer_handle an_txrx_handle; /* ol data path handle */ +}; + +#define OL_ATH_NODE_NET80211(_ni) ((struct ol_ath_node_net80211 *)(_ni)) + +#define UAPSD_SRV_INTERVAL_DEFAULT_BK_BE_VI 300 /* Default U-APSD Service Interval in msec for BK, BE and VI */ +#define UAPSD_SRV_INTERVAL_DEFAULT_VO 20 /* Default U-APSD Service Interval in msec for VO */ +#define UAPSD_SUS_INTERVAL_DEFAULT 2000 /* Default U-APSD Suspend Interval in msec for BK, BE and VI */ +#define UAPSD_DELAY_INTERVAL_DEFAULT 3000 /* Default U-APSD Delay Interval in msec for BK, BE and VI */ +#define UAPSD_USER_PRIO_BE 0 +#define UAPSD_USER_PRIO_BK 2 +#define UAPSD_USER_PRIO_VI 5 +#define UAPSD_USER_PRIO_VO 7 + +#define SIR_MAC_DS_PARAM_SET_EID 3 +#define SIR_MAC_EDCA_PARAM_SET_EID 12 +#define SIR_MAC_CHNL_SWITCH_ANN_EID 37 +#define SIR_MAC_QUIET_EID 40 +#define SIR_MAC_ERP_INFO_EID 42 +#define SIR_MAC_QOS_CAPABILITY_EID 46 +#define SIR_MAC_HT_INFO_EID 61 + + void ol_target_failure(void *instance, A_STATUS status); + +int ol_asf_adf_attach(struct ol_softc *scn); + +int ol_ath_detach(struct ol_softc *scn, int force); +void ol_ath_utf_detach(struct ol_softc *scn); +#ifdef QVIT +void ol_ath_qvit_detach(struct ol_softc *scn); +void ol_ath_qvit_attach(struct ol_softc *scn); +#endif + +int ol_ath_resume(struct ol_softc *scn); + +int ol_ath_suspend(struct ol_softc *scn); + +int ol_ath_cwm_attach(struct ol_softc *scn); + +u_int8_t *ol_ath_vap_get_myaddr(struct ol_softc *scn, u_int8_t vdev_id); + +void ol_ath_utf_attach(struct ol_softc *scn); + +void ol_ath_vap_send_hdr_complete(void *ctx, HTC_PACKET_QUEUE *htc_pkt_list); + + +void ol_rx_indicate(void *ctx, adf_nbuf_t wbuf); + +void ol_rx_handler(void *ctx, HTC_PACKET *htc_packet); + +void ol_ath_beacon_stop(struct ol_softc *scn, + struct ol_ath_vap_net80211 *avn); + +u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offset); + +int +ol_ath_set_config_param(struct ol_softc *scn, ol_ath_param_t param, void *buff); + +int +ol_ath_get_config_param(struct ol_softc *scn, ol_ath_param_t param, void *buff); + +int +ol_hal_set_config_param(struct ol_softc *scn, ol_hal_param_t param, void *buff); + +int +ol_hal_get_config_param(struct ol_softc *scn, ol_hal_param_t param, void *buff); + +void ol_ath_host_config_update(struct ol_softc *scn); + +int ol_ath_suspend_target(struct ol_softc *scn, int disable_target_intr); +int ol_ath_resume_target(struct ol_softc *scn); + +int wmi_unified_pdev_get_tpc_config(wmi_unified_t wmi_handle, u_int32_t param); +void ol_get_wlan_dbg_stats(struct ol_softc *scn, struct wlan_dbg_stats *dbg_stats); + +int +wmi_unified_node_set_param(wmi_unified_t wmi_handle, u_int8_t *peer_addr,u_int32_t param_id, + u_int32_t param_val,u_int32_t vdev_id); + + +#ifdef BIG_ENDIAN_HOST + /* This API is used in copying in elements to WMI message, + since WMI message uses multilpes of 4 bytes, This API + converts length into multiples of 4 bytes, and performs copy + */ +#define OL_IF_MSG_COPY_CHAR_ARRAY(destp, srcp, len) do { \ + int j; \ + u_int32_t *src, *dest; \ + src = (u_int32_t *)srcp; \ + dest = (u_int32_t *)destp; \ + for(j=0; j < roundup(len, sizeof(u_int32_t))/4; j++) { \ + *(dest+j) = adf_os_le32_to_cpu(*(src+j)); \ + } \ + } while(0) + +#else + +#define OL_IF_MSG_COPY_CHAR_ARRAY(destp, srcp, len) do { \ + OS_MEMCPY(destp, srcp, len); \ + } while(0) + +#endif + +/* Keep Alive KeepAliveParam. */ +typedef struct +{ + u_int8_t keepAliveEnable;//Enable or Disable + u_int32_t keepAliveMethod;// Type of frame which need to send for keep alive purpose + u_int32_t keepAliveInterval;//Interval in Seconds + u_int8_t hostIpv4Addr[4]; //Used only when method type is Arp + u_int8_t destIpv4Addr[4];//Used only when method type is Arp + u_int8_t destMacAddr[6];//Used only when method type is Arp +} KeepAliveParam, *pKeepAliveParam; + +#endif /* _DEV_OL_ATH_ATHVAR_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_osif_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_osif_api.h new file mode 100644 index 0000000000000..2c13692de3a8a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_osif_api.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_osif_api.h + * @brief Definitions used in multiple external interfaces to the txrx SW. + */ +#ifndef _OL_OSIF_API__H_ +#define _OL_OSIF_API__H_ + +/** + * @typedef ol_osif_vdev_handle + * @brief opaque handle for OS shim virtual device object + */ +struct ol_osif_vdev_t; +typedef struct ol_osif_vdev_t* ol_osif_vdev_handle; + +#endif /* _OL_OSIF_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_params.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_params.h new file mode 100644 index 0000000000000..452cc0839be8c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_params.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * Defintions for the Atheros Wireless LAN controller driver. + */ +#ifndef _DEV_OL_PARAMS_H +#define _DEV_OL_PARAMS_H +#include "ol_txrx_stats.h" +#include "wlan_defs.h" /* for wlan statst definitions */ +/* +** Enumeration of PDEV Configuration parameter +*/ + +typedef enum _ol_ath_param_t { + OL_ATH_PARAM_TXCHAINMASK = 0, + OL_ATH_PARAM_RXCHAINMASK, + OL_ATH_PARAM_TXCHAINMASKLEGACY, + OL_ATH_PARAM_RXCHAINMASKLEGACY, + OL_ATH_PARAM_CHAINMASK_SEL, + OL_ATH_PARAM_AMPDU, + OL_ATH_PARAM_AMPDU_LIMIT, + OL_ATH_PARAM_AMPDU_SUBFRAMES, + OL_ATH_PARAM_LDPC, + OL_ATH_PARAM_NON_AGG_SW_RETRY_TH, + OL_ATH_PARAM_AGG_SW_RETRY_TH, + OL_ATH_PARAM_STA_KICKOUT_TH, + OL_ATH_PARAM_WLAN_PROF_ENABLE, + OL_ATH_PARAM_LTR_ENABLE, + OL_ATH_PARAM_LTR_AC_LATENCY_BE, + OL_ATH_PARAM_LTR_AC_LATENCY_BK, + OL_ATH_PARAM_LTR_AC_LATENCY_VI, + OL_ATH_PARAM_LTR_AC_LATENCY_VO, + OL_ATH_PARAM_LTR_AC_LATENCY_TIMEOUT, + OL_ATH_PARAM_LTR_TX_ACTIVITY_TIMEOUT, + OL_ATH_PARAM_LTR_SLEEP_OVERRIDE, + OL_ATH_PARAM_LTR_RX_OVERRIDE, + OL_ATH_PARAM_L1SS_ENABLE, + OL_ATH_PARAM_DSLEEP_ENABLE, + OL_ATH_PARAM_PCIELP_TXBUF_FLUSH, + OL_ATH_PARAM_PCIELP_TXBUF_WATERMARK, + OL_ATH_PARAM_PCIELP_TXBUF_TMO_EN, + OL_ATH_PARAM_PCIELP_TXBUF_TMO_VALUE, + OL_ATH_PARAM_BCN_BURST, + OL_ATH_PARAM_ARP_AC_OVERRIDE, + OL_ATH_PARAM_TXPOWER_LIMIT2G, + OL_ATH_PARAM_TXPOWER_LIMIT5G, + OL_ATH_PARAM_TXPOWER_SCALE, + OL_ATH_PARAM_DCS, + OL_ATH_PARAM_ANI_ENABLE, + OL_ATH_PARAM_ANI_POLL_PERIOD, + OL_ATH_PARAM_ANI_LISTEN_PERIOD, + OL_ATH_PARAM_ANI_OFDM_LEVEL, + OL_ATH_PARAM_ANI_CCK_LEVEL, + OL_ATH_PARAM_PROXYSTA, + OL_ATH_PARAM_DYN_TX_CHAINMASK, + OL_ATH_PARAM_VOW_EXT_STATS, + OL_ATH_PARAM_PWR_GATING_ENABLE, + OL_ATH_PARAM_CHATTER, +} ol_ath_param_t; + +/* +** Enumeration of PDEV Configuration parameter +*/ + +typedef enum _ol_hal_param_t { + OL_HAL_CONFIG_DMA_BEACON_RESPONSE_TIME = 0 +} ol_hal_param_t; + + +/* +** structure to hold all stats information +** for offload device interface +*/ +struct ol_stats { + int txrx_stats_level; + struct ol_txrx_stats txrx_stats; + struct wlan_dbg_stats stats; +}; +#endif /* _DEV_OL_PARAMS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_api.h new file mode 100644 index 0000000000000..59434116c97c5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_api.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_api.h + * @brief Definitions used in multiple external interfaces to the txrx SW. + */ +#ifndef _OL_TXRX_API__H_ +#define _OL_TXRX_API__H_ + +/** + * @typedef ol_txrx_pdev_handle + * @brief opaque handle for txrx physical device object + */ +struct ol_txrx_pdev_t; +typedef struct ol_txrx_pdev_t* ol_txrx_pdev_handle; + +/** + * @typedef ol_txrx_vdev_handle + * @brief opaque handle for txrx virtual device object + */ +struct ol_txrx_vdev_t; +typedef struct ol_txrx_vdev_t* ol_txrx_vdev_handle; + +/** + * @typedef ol_txrx_peer_handle + * @brief opaque handle for txrx peer object + */ +struct ol_txrx_peer_t; +typedef struct ol_txrx_peer_t* ol_txrx_peer_handle; + +/** + * @brief ADDBA negotiation status, used both during requests and confirmations + */ +enum ol_addba_status { + /* status: negotiation started or completed successfully */ + ol_addba_success, + + /* reject: aggregation is not applicable - don't try again */ + ol_addba_reject, + + /* busy: ADDBA negotiation couldn't be performed - try again later */ + ol_addba_busy, +}; + +enum ol_sec_type { + ol_sec_type_none, + ol_sec_type_wep128, + ol_sec_type_wep104, + ol_sec_type_wep40, + ol_sec_type_tkip, + ol_sec_type_tkip_nomic, + ol_sec_type_aes_ccmp, + ol_sec_type_wapi, + + /* keep this last! */ + ol_sec_type_types +}; + +/** + * @enum ol_tx_spec + * @brief indicate what non-standard transmission actions to apply + * @details + * Indicate one or more of the following: + * - The tx frame already has a complete 802.11 header. + * Thus, skip 802.3/native-WiFi to 802.11 header encapsulation and + * A-MSDU aggregation. + * - The tx frame should not be aggregated (A-MPDU or A-MSDU) + * - The tx frame is already encrypted - don't attempt encryption. + * - The tx frame is a segment of a TCP jumbo frame. + * - This tx frame should not be unmapped and freed by the txrx layer + * after transmission, but instead given to a registered tx completion + * callback. + * More than one of these specification can apply, though typically + * only a single specification is applied to a tx frame. + * A compound specification can be created, as a bit-OR of these + * specifications. + */ +enum ol_tx_spec { + ol_tx_spec_std = 0x0, /* do regular processing */ + ol_tx_spec_raw = 0x1, /* skip encap + A-MSDU aggr */ + ol_tx_spec_no_aggr = 0x2, /* skip encap + all aggr */ + ol_tx_spec_no_encrypt = 0x4, /* skip encap + encrypt */ + ol_tx_spec_tso = 0x8, /* TCP segmented */ + ol_tx_spec_nwifi_no_encrypt = 0x10, /* skip encrypt for nwifi */ + ol_tx_spec_no_free = 0x20, /* give to cb rather than free */ +}; + +#endif /* _OL_TXRX_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h new file mode 100644 index 0000000000000..f2cf10ac4f4a5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h @@ -0,0 +1,1254 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_ctrl_api.h + * @brief Define the host data API functions called by the host control SW. + */ +#ifndef _OL_TXRX_CTRL_API__H_ +#define _OL_TXRX_CTRL_API__H_ + +#include /* A_STATUS */ +#include /* adf_nbuf_t */ +#include /* adf_os_device_t */ +#include /* HTC_HANDLE */ + +#include /* ol_osif_vdev_handle */ +#include /* ol_txrx_pdev_handle, etc. */ +#include /* ol_pdev_handle, ol_vdev_handle */ + +#include /* MAX_SPATIAL_STREAM */ + +/** + * @brief modes that a virtual device can operate as + * @details + * A virtual device can operate as an AP, an IBSS, or a STA (client). + * or in monitor mode + */ +enum wlan_op_mode { + wlan_op_mode_unknown, + wlan_op_mode_ap, + wlan_op_mode_ibss, + wlan_op_mode_sta, + wlan_op_mode_monitor, +}; + +#define OL_TXQ_PAUSE_REASON_FW (1 << 0) +#define OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED (1 << 1) +#define OL_TXQ_PAUSE_REASON_TX_ABORT (1 << 2) +#define OL_TXQ_PAUSE_REASON_VDEV_STOP (1 << 3) +#define OL_TXQ_PAUSE_REASON_VDEV_SUSPEND (1 << 4) + +/** + * @brief Set up the data SW subsystem. + * @details + * As part of the WLAN device attach, the data SW subsystem has + * to be attached as a component within the WLAN device. + * This attach allocates and initializes the physical device object + * used by the data SW. + * The data SW subsystem attach needs to happen after the target has + * be started, and host / target parameter negotiation has completed, + * since the host data SW uses some of these host/target negotiated + * parameters (e.g. peer ID range) during the initializations within + * its attach function. + * However, the host data SW is not allowed to send HTC messages to the + * target within this pdev_attach function call, since the HTC setup + * has not complete at this stage of initializations. Any messaging + * to the target has to be done in the separate pdev_attach_target call + * that is invoked after HTC setup is complete. + * + * @param ctrl_pdev - control SW's physical device handle, needed as an + * argument for dynamic configuration queries + * @param htc_pdev - the HTC physical device handle. This is not needed + * by the txrx module, but needs to be passed along to the HTT module. + * @param osdev - OS handle needed as an argument for some OS primitives + * @return the data physical device object + */ +ol_txrx_pdev_handle +ol_txrx_pdev_attach( + ol_pdev_handle ctrl_pdev, + HTC_HANDLE htc_pdev, + adf_os_device_t osdev); + +/** + * @brief Do final steps of data SW setup that send messages to the target. + * @details + * The majority of the data SW setup are done by the pdev_attach function, + * but this function completes the data SW setup by sending datapath + * configuration messages to the target. + * + * @param data_pdev - the physical device being initialized + */ +A_STATUS +ol_txrx_pdev_attach_target(ol_txrx_pdev_handle data_pdev); + + +/** + * @brief Allocate and initialize the data object for a new virtual device. + * @param data_pdev - the physical device the virtual device belongs to + * @param vdev_mac_addr - the MAC address of the virtual device + * @param vdev_id - the ID used to identify the virtual device to the target + * @param op_mode - whether this virtual device is operating as an AP, + * an IBSS, or a STA + * @return + * success: handle to new data vdev object, -OR- + * failure: NULL + */ +ol_txrx_vdev_handle +ol_txrx_vdev_attach( + ol_txrx_pdev_handle data_pdev, + u_int8_t *vdev_mac_addr, + u_int8_t vdev_id, + enum wlan_op_mode op_mode); + +/** + * @brief Allocate and set up references for a data peer object. + * @details + * When an association with a peer starts, the host's control SW + * uses this function to inform the host data SW. + * The host data SW allocates its own peer object, and stores a + * reference to the control peer object within the data peer object. + * The host data SW also stores a reference to the virtual device + * that the peer is associated with. This virtual device handle is + * used when the data SW delivers rx data frames to the OS shim layer. + * The host data SW returns a handle to the new peer data object, + * so a reference within the control peer object can be set to the + * data peer object. + * + * @param data_pdev - data physical device object that will indirectly + * own the data_peer object + * @param data_vdev - data virtual device object that will directly + * own the data_peer object + * @param peer_mac_addr - MAC address of the new peer + * @return handle to new data peer object, or NULL if the attach fails + */ +ol_txrx_peer_handle +ol_txrx_peer_attach( + ol_txrx_pdev_handle data_pdev, + ol_txrx_vdev_handle data_vdev, + u_int8_t *peer_mac_addr); + +/** +* @brief Parameter type to be input to ol_txrx_peer_update +* @details +* This struct is union,to be used to specify various informations to update +* txrx peer object. +*/ +typedef union { + u_int8_t qos_capable; + u_int8_t uapsd_mask; + enum ol_sec_type sec_type; +}ol_txrx_peer_update_param_t; + +/** +* @brief Parameter type to be input to ol_txrx_peer_update +* @details +* This enum is used to specify what exact information in ol_txrx_peer_update_param_t +* is used to update the txrx peer object. +*/ +typedef enum { + ol_txrx_peer_update_qos_capable = 1, + ol_txrx_peer_update_uapsdMask, + ol_txrx_peer_update_peer_security, +} ol_txrx_peer_update_select_t; + +/** + * @brief Update the data peer object as some informaiton changed in node. + * @details + * Only a single prarameter can be changed for each call to this func. + * + * @param peer - pointer to the node's object + * @param param - new param to be upated in peer object. + * @param select - specify what's parameter needed to be update + */ +void +ol_txrx_peer_update(ol_txrx_vdev_handle data_vdev, u_int8_t *peer_mac, + ol_txrx_peer_update_param_t *param, + ol_txrx_peer_update_select_t select); + +enum { + OL_TX_WMM_AC_BE, + OL_TX_WMM_AC_BK, + OL_TX_WMM_AC_VI, + OL_TX_WMM_AC_VO, + + OL_TX_NUM_WMM_AC +}; + +/** + * @brief Parameter type to pass WMM setting to wdi_in_set_wmm_param + * @details + * The struct is used to specify informaiton to update TX WMM scheduler. + */ +struct ol_tx_ac_param_t { + u_int32_t aifs; + u_int32_t cwmin; + u_int32_t cwmax; +}; + +struct ol_tx_wmm_param_t { + struct ol_tx_ac_param_t ac[OL_TX_NUM_WMM_AC]; +}; + +/** + * @brief Set paramters of WMM scheduler per AC settings. . + * @details + * This function applies only to HL systems. + * + * @param data_pdev - the physical device being paused + * @param wmm_param - the wmm parameters + */ +#if defined(CONFIG_HL_SUPPORT) +void +ol_txrx_set_wmm_param(ol_txrx_pdev_handle data_pdev, struct ol_tx_wmm_param_t wmm_param); +#else +#define ol_txrx_set_wmm_param(data_pdev, wmm_param) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Notify tx data SW that a peer's transmissions are suspended. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * The HL host tx data SW is doing tx classification and tx download + * scheduling, and therefore also needs to actively participate in tx + * flow control. Specifically, the HL tx data SW needs to check whether a + * given peer is available to transmit to, or is paused. + * This function is used to tell the HL tx data SW when a peer is paused, + * so the host tx data SW can hold the tx frames for that SW. + * + * @param data_peer - which peer is being paused + */ +#define ol_txrx_peer_pause(data_peer) /* no-op */ + +/** + * @brief Notify tx data SW that a peer-TID is ready to transmit to. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * If a peer-TID has tx paused, then the tx datapath will end up queuing + * any tx frames that arrive from the OS shim for that peer-TID. + * In a HL system, the host tx data SW itself will classify the tx frame, + * and determine that it needs to be queued rather than downloaded to the + * target for transmission. + * Once the peer-TID is ready to accept data, the host control SW will call + * this function to notify the host data SW that the queued frames can be + * enabled for transmission, or specifically to download the tx frames + * to the target to transmit. + * The TID parameter is an extended version of the QoS TID. Values 0-15 + * indicate a regular QoS TID, and the value 16 indicates either non-QoS + * data, multicast data, or broadcast data. + * + * @param data_peer - which peer is being unpaused + * @param tid - which TID within the peer is being unpaused, or -1 as a + * wildcard to unpause all TIDs within the peer + */ +#if defined(CONFIG_HL_SUPPORT) +void +ol_txrx_peer_tid_unpause(ol_txrx_peer_handle data_peer, int tid); +#else +#define ol_txrx_peer_tid_unpause(data_peer, tid) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Tell a paused peer to release a specified number of tx frames. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * Download up to a specified maximum number of tx frames from the tx + * queues of the specified TIDs within the specified paused peer, usually + * in response to a U-APSD trigger from the peer. + * It is up to the host data SW to determine how to choose frames from the + * tx queues of the specified TIDs. However, the host data SW does need to + * provide long-term fairness across the U-APSD enabled TIDs. + * The host data SW will notify the target data FW when it is done downloading + * the batch of U-APSD triggered tx frames, so the target data FW can + * differentiate between an in-progress download versus a case when there are + * fewer tx frames available than the specified limit. + * This function is relevant primarily to HL U-APSD, where the frames are + * held in the host. + * + * @param peer - which peer sent the U-APSD trigger + * @param tid_mask - bitmask of U-APSD enabled TIDs from whose tx queues + * tx frames can be released + * @param max_frms - limit on the number of tx frames to release from the + * specified TID's queues within the specified peer + */ +#if defined(CONFIG_HL_SUPPORT) +void +ol_txrx_tx_release( + ol_txrx_peer_handle peer, + u_int32_t tid_mask, + int max_frms); +#else +#define ol_txrx_tx_release(peer, tid_mask, max_frms) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Suspend all tx data for the specified virtual device. + * @details + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + * As an example, this function could be used when a single-channel physical + * device supports multiple channels by jumping back and forth between the + * channels in a time-shared manner. As the device is switched from channel + * A to channel B, the virtual devices that operate on channel A will be + * paused. + * + * @param data_vdev - the virtual device being paused + * @param reason - the reason for which vdev queue is getting paused + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_vdev_pause(ol_txrx_vdev_handle vdev, u_int32_t reason); +#else +#define ol_txrx_vdev_pause(data_vdev, reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Drop all tx data for the specified virtual device. + * @details + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + * This function would typically be used by the ctrl SW after it parks + * a STA vdev and then resumes it, but to a new AP. In this case, though + * the same vdev can be used, any old tx frames queued inside it would be + * stale, and would need to be discarded. + * + * @param data_vdev - the virtual device being flushed + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_vdev_flush(ol_txrx_vdev_handle data_vdev); +#else +#define ol_txrx_vdev_flush(data_vdev) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Resume tx for the specified virtual device. + * @details + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + * + * @param data_vdev - the virtual device being unpaused + * @param reason - the reason for which vdev queue is getting unpaused + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_vdev_unpause(ol_txrx_vdev_handle data_vdev, u_int32_t reason); +#else +#define ol_txrx_vdev_unpause(data_vdev, reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Suspend all tx data per thermal event/timer for the + * specified physical device + * @details + * This function applies only to HL systerms, and it makes pause and + * unpause operations happen in pairs. + */ +#if defined(CONFIG_HL_SUPPORT) +void +ol_txrx_throttle_pause(ol_txrx_pdev_handle data_pdev); +#else +#define ol_txrx_throttle_pause(data_pdev) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + + +/** + * @brief Resume all tx data per thermal event/timer for the + * specified physical device + * @details + * This function applies only to HL systerms, and it makes pause and + * unpause operations happen in pairs. + */ +#if defined(CONFIG_HL_SUPPORT) +void +ol_txrx_throttle_unpause(ol_txrx_pdev_handle data_pdev); +#else +#define ol_txrx_throttle_unpause(data_pdev) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * ol_txrx_pdev_pause() - Suspend all tx data for the specified physical device. + * @data_pdev: the physical device being paused. + * @reason: pause reason. + * One can provide multiple line descriptions + * for arguments. + * + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * In some systems it is necessary to be able to temporarily + * suspend all WLAN traffic, e.g. to allow another device such as bluetooth + * to temporarily have exclusive access to shared RF chain resources. + * This function suspends tx traffic within the specified physical device. + * + * + * Return: None + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_pdev_pause(ol_txrx_pdev_handle data_pdev, u_int32_t reason); +#else +#define ol_txrx_pdev_pause(data_pdev,reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * ol_txrx_pdev_unpause() - Resume tx for the specified physical device.. + * @data_pdev: the physical device being paused. + * @reason: pause reason. + * + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * + * + * Return: None + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_pdev_unpause(ol_txrx_pdev_handle data_pdev, u_int32_t reason); +#else +#define ol_txrx_pdev_unpause(data_pdev,reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Synchronize the data-path tx with a control-path target download + * @dtails + * @param data_pdev - the data-path physical device object + * @param sync_cnt - after the host data-path SW downloads this sync request + * to the target data-path FW, the target tx data-path will hold itself + * in suspension until it is given an out-of-band sync counter value that + * is equal to or greater than this counter value + */ +void +ol_txrx_tx_sync(ol_txrx_pdev_handle data_pdev, u_int8_t sync_cnt); + +/** + * @brief Delete a peer's data object. + * @details + * When the host's control SW disassociates a peer, it calls this + * function to delete the peer's data object. + * The reference stored in the control peer object to the data peer + * object (set up by a call to ol_peer_store()) is provided. + * + * @param data_peer - the object to delete + */ +void +ol_txrx_peer_detach(ol_txrx_peer_handle data_peer); + +typedef void (*ol_txrx_vdev_delete_cb)(void *context); + +/** + * @brief Deallocate the specified data virtual device object. + * @details + * All peers associated with the virtual device need to be deleted + * (ol_txrx_peer_detach) before the virtual device itself is deleted. + * However, for the peers to be fully deleted, the peer deletion has to + * percolate through the target data FW and back up to the host data SW. + * Thus, even though the host control SW may have issued a peer_detach + * call for each of the vdev's peers, the peer objects may still be + * allocated, pending removal of all references to them by the target FW. + * In this case, though the vdev_detach function call will still return + * immediately, the vdev itself won't actually be deleted, until the + * deletions of all its peers complete. + * The caller can provide a callback function pointer to be notified when + * the vdev deletion actually happens - whether it's directly within the + * vdev_detach call, or if it's deferred until all in-progress peer + * deletions have completed. + * + * @param data_vdev - data object for the virtual device in question + * @param callback - function to call (if non-NULL) once the vdev has + * been wholly deleted + * @param callback_context - context to provide in the callback + */ +void +ol_txrx_vdev_detach( + ol_txrx_vdev_handle data_vdev, + ol_txrx_vdev_delete_cb callback, + void *callback_context); + +/** + * @brief Delete the data SW state. + * @details + * This function is used when the WLAN driver is being removed to + * remove the host data component within the driver. + * All virtual devices within the physical device need to be deleted + * (ol_txrx_vdev_detach) before the physical device itself is deleted. + * + * @param data_pdev - the data physical device object being removed + * @param force - delete the pdev (and its vdevs and peers) even if there + * are outstanding references by the target to the vdevs and peers + * within the pdev + */ +void +ol_txrx_pdev_detach(ol_txrx_pdev_handle data_pdev, int force); + +typedef void +(*ol_txrx_data_tx_cb)(void *ctxt, adf_nbuf_t tx_frm, int had_error); + +/** + * @brief Store a delivery notification callback for specific data frames. + * @details + * Through a non-std tx function, the txrx SW can be given tx data frames + * that are specially marked to not be unmapped and freed by the tx SW + * when transmission completes. Rather, these specially-marked frames + * are provided to the callback registered with this function. + * + * @param data_vdev - which vdev the callback is being registered with + * (Currently the callback is stored in the pdev rather than the vdev.) + * @param callback - the function to call when tx frames marked as "no free" + * are done being transmitted + * @param ctxt - the context argument provided to the callback function + */ +void +ol_txrx_data_tx_cb_set( + ol_txrx_vdev_handle data_vdev, + ol_txrx_data_tx_cb callback, + void *ctxt); + + +/** + * @brief Allow the control-path SW to send data frames. + * @details + * Generally, all tx data frames come from the OS shim into the txrx layer. + * However, there are rare cases such as TDLS messaging where the UMAC + * control-path SW creates tx data frames. + * This UMAC SW can call this function to provide the tx data frames to + * the txrx layer. + * The UMAC SW can request a callback for these data frames after their + * transmission completes, by using the ol_txrx_data_tx_cb_set function + * to register a tx completion callback, and by specifying + * ol_tx_spec_no_free as the tx_spec arg when giving the frames to + * ol_tx_non_std. + * The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11), + * as specified by ol_cfg_frame_type(). + * + * @param data_vdev - which vdev should transmit the tx data frames + * @param tx_spec - what non-standard handling to apply to the tx data frames + * @param msdu_list - NULL-terminated list of tx MSDUs + */ +adf_nbuf_t +ol_tx_non_std( + ol_txrx_vdev_handle data_vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list); + + +typedef void +(*ol_txrx_mgmt_tx_cb)(void *ctxt, adf_nbuf_t tx_mgmt_frm, int had_error); + +/** + * @brief Store a callback for delivery notifications for management frames. + * @details + * When the txrx SW receives notifications from the target that a tx frame + * has been delivered to its recipient, it will check if the tx frame + * is a management frame. If so, the txrx SW will check the management + * frame type specified when the frame was submitted for transmission. + * If there is a callback function registered for the type of managment + * frame in question, the txrx code will invoke the callback to inform + * the management + control SW that the mgmt frame was delivered. + * This function is used by the control SW to store a callback pointer + * for a given type of management frame. + * + * @param pdev - the data physical device object + * @param type - the type of mgmt frame the callback is used for + * @param download_cb - the callback for notification of delivery to the target + * @param ota_ack_cb - the callback for notification of delivery to the peer + * @param ctxt - context to use with the callback + */ +void +ol_txrx_mgmt_tx_cb_set( + ol_txrx_pdev_handle pdev, + u_int8_t type, + ol_txrx_mgmt_tx_cb download_cb, + ol_txrx_mgmt_tx_cb ota_ack_cb, + void *ctxt); + +/** + * @brief Transmit a management frame. + * @details + * Send the specified management frame from the specified virtual device. + * The type is used for determining whether to invoke a callback to inform + * the sender that the tx mgmt frame was delivered, and if so, which + * callback to use. + * + * @param vdev - virtual device transmitting the frame + * @param tx_mgmt_frm - management frame to transmit + * @param type - the type of managment frame (determines what callback to use) + * @param use_6mbps - specify whether management frame to transmit should use 6 Mbps + * rather than 1 Mbps min rate(for 5GHz band or P2P) + * @return + * 0 -> the frame is accepted for transmission, -OR- + * 1 -> the frame was not accepted + */ +int +ol_txrx_mgmt_send( + ol_txrx_vdev_handle vdev, + adf_nbuf_t tx_mgmt_frm, + u_int8_t type, + u_int8_t use_6mbps, + u_int16_t chanfreq); + +/** + * @brief Setup the monitor mode vap (vdev) for this pdev + * @details + * When a non-NULL vdev handle is registered as the monitor mode vdev, all + * packets received by the system are delivered to the OS stack on this + * interface in 802.11 MPDU format. Only a single monitor mode interface + * can be up at any timer. When the vdev handle is set to NULL the monitor + * mode delivery is stopped. This handle may either be a unique vdev + * object that only receives monitor mode packets OR a point to a a vdev + * object that also receives non-monitor traffic. In the second case the + * OS stack is responsible for delivering the two streams using approprate + * OS APIs + * + * @param pdev - the data physical device object + * @param vdev - the data virtual device object to deliver monitor mode + * packets on + * @return + * 0 -> the monitor mode vap was sucessfully setup + * -1 -> Unable to setup monitor mode + */ +int +ol_txrx_set_monitor_mode_vap( + ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev); + +/** + * @brief Setup the current operating channel of the device + * @details + * Mainly used when populating monitor mode status that requires the + * current operating channel + * + * @param pdev - the data physical device object + * @param chan_mhz - the channel frequency (mhz) + * packets on + * @return - void + */ +void +ol_txrx_set_curchan( + ol_txrx_pdev_handle pdev, + u_int32_t chan_mhz); + +/** + * @brief Get the number of pending transmit frames that are awaiting completion. + * @details + * Mainly used in clean up path to make sure all buffers have been free'ed + * + * @param pdev - the data physical device object + * @return - count of pending frames + */ +int +ol_txrx_get_tx_pending( + ol_txrx_pdev_handle pdev); + +/** + * @brief Discard all tx frames that are pending in txrx. + * @details + * Mainly used in clean up path to make sure all pending tx packets + * held by txrx are returned back to OS shim immediately. + * + * @param pdev - the data physical device object + * @return - void + */ +void +ol_txrx_discard_tx_pending( + ol_txrx_pdev_handle pdev); + +/** + * @brief set the safemode of the device + * @details + * This flag is used to bypass the encrypt and decrypt processes when send and + * receive packets. It works like open AUTH mode, HW will treate all packets + * as non-encrypt frames because no key installed. For rx fragmented frames, + * it bypasses all the rx defragmentaion. + * + * @param vdev - the data virtual device object + * @param val - the safemode state + * @return - void + */ +void +ol_txrx_set_safemode( + ol_txrx_vdev_handle vdev, + u_int32_t val); + +/** + * @brief set the privacy filter + * @details + * Rx related. Set the privacy filters. When rx packets, check the ether type, filter type and + * packet type to decide whether discard these packets. + * + * @param vdev - the data virtual device object + * @param filter - filters to be set + * @param num - the number of filters + * @return - void + */ +void +ol_txrx_set_privacy_filters( + ol_txrx_vdev_handle vdev, + void *filter, + u_int32_t num); + +/** + * @brief configure the drop unencrypted frame flag + * @details + * Rx related. When set this flag, all the unencrypted frames + * received over a secure connection will be discarded + * + * @param vdev - the data virtual device object + * @param val - flag + * @return - void + */ +void +ol_txrx_set_drop_unenc( + ol_txrx_vdev_handle vdev, + u_int32_t val); + +enum ol_txrx_peer_state { + ol_txrx_peer_state_invalid, + ol_txrx_peer_state_disc, /* initial state */ + ol_txrx_peer_state_conn, /* authentication in progress */ + ol_txrx_peer_state_auth, /* authentication completed successfully */ +}; + +/** + * @brief specify the peer's authentication state + * @details + * Specify the peer's authentication state (none, connected, authenticated) + * to allow the data SW to determine whether to filter out invalid data frames. + * (In the "connected" state, where security is enabled, but authentication + * has not completed, tx and rx data frames other than EAPOL or WAPI should + * be discarded.) + * This function is only relevant for systems in which the tx and rx filtering + * are done in the host rather than in the target. + * + * @param data_peer - which peer has changed its state + * @param state - the new state of the peer + */ +void +ol_txrx_peer_state_update(ol_txrx_pdev_handle pdev, u_int8_t *peer_addr, + enum ol_txrx_peer_state state); + +void +ol_txrx_peer_keyinstalled_state_update( + ol_txrx_peer_handle data_peer, + u_int8_t val); + +#define ol_tx_addba_conf(data_peer, tid, status) /* no-op */ + +/** + * @brief Find a txrx peer handle from the peer's MAC address + * @details + * The control SW typically uses the txrx peer handle to refer to the peer. + * In unusual circumstances, if it is infeasible for the control SW maintain + * the txrx peer handle but it can maintain the peer's MAC address, + * this function allows the peer handled to be retrieved, based on the peer's + * MAC address. + * In cases where there are multiple peer objects with the same MAC address, + * it is undefined which such object is returned. + * This function does not increment the peer's reference count. Thus, it is + * only suitable for use as long as the control SW has assurance that it has + * not deleted the peer object, by calling ol_txrx_peer_detach. + * + * @param pdev - the data physical device object + * @param peer_mac_addr - MAC address of the peer in question + * @return handle to the txrx peer object + */ +ol_txrx_peer_handle +ol_txrx_peer_find_by_addr(ol_txrx_pdev_handle pdev, u_int8_t *peer_mac_addr); + +/** + * @brief Find a txrx peer handle from a peer's local ID + * @details + * The control SW typically uses the txrx peer handle to refer to the peer. + * In unusual circumstances, if it is infeasible for the control SW maintain + * the txrx peer handle but it can maintain a small integer local peer ID, + * this function allows the peer handled to be retrieved, based on the local + * peer ID. + * + * @param pdev - the data physical device object + * @param local_peer_id - the ID txrx assigned locally to the peer in question + * @return handle to the txrx peer object + */ +#if QCA_SUPPORT_TXRX_LOCAL_PEER_ID +ol_txrx_peer_handle +ol_txrx_peer_find_by_local_id( + ol_txrx_pdev_handle pdev, + u_int8_t local_peer_id); +#else +#define ol_txrx_peer_find_by_local_id(pdev, local_peer_id) NULL +#endif + +typedef struct { + struct { + struct { + u_int32_t ucast; + u_int32_t mcast; + u_int32_t bcast; + } frms; + struct { + u_int32_t ucast; + u_int32_t mcast; + u_int32_t bcast; + } bytes; + } tx; + struct { + struct { + u_int32_t ucast; + u_int32_t mcast; + u_int32_t bcast; + } frms; + struct { + u_int32_t ucast; + u_int32_t mcast; + u_int32_t bcast; + } bytes; + } rx; +} ol_txrx_peer_stats_t; + +/** + * @brief Provide a snapshot of the txrx counters for the specified peer + * @details + * The txrx layer optionally maintains per-peer stats counters. + * This function provides the caller with a consistent snapshot of the + * txrx stats counters for the specified peer. + * + * @param pdev - the data physical device object + * @param peer - which peer's stats counters are requested + * @param stats - buffer for holding the stats counters snapshot + * @return success / failure status + */ +#ifdef QCA_ENABLE_OL_TXRX_PEER_STATS +A_STATUS +ol_txrx_peer_stats_copy( + ol_txrx_pdev_handle pdev, + ol_txrx_peer_handle peer, + ol_txrx_peer_stats_t *stats); +#else +#define ol_txrx_peer_stats_copy(pdev, peer, stats) A_ERROR /* failure */ +#endif /* QCA_ENABLE_OL_TXRX_PEER_STATS */ + +/* Config parameters for txrx_pdev */ +struct txrx_pdev_cfg_param_t { + u_int8_t is_full_reorder_offload; + /* IPA Micro controller data path offload enable flag */ + u_int8_t is_uc_offload_enabled; + /* IPA Micro controller data path offload TX buffer count */ + u_int32_t uc_tx_buffer_count; + /* IPA Micro controller data path offload TX buffer size */ + u_int32_t uc_tx_buffer_size; + /* IPA Micro controller data path offload RX indication ring count */ + u_int32_t uc_rx_indication_ring_count; + /* IPA Micro controller data path offload TX partition base */ + u_int32_t uc_tx_partition_base; +}; + +/** + * @brief Setup configuration parameters + * @details + * Allocation configuration context that will be used across data path + * + * @param osdev - OS handle needed as an argument for some OS primitives + * @return the control device object + */ +ol_pdev_handle ol_pdev_cfg_attach(adf_os_device_t osdev, + struct txrx_pdev_cfg_param_t cfg_param); + +#define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff +#ifdef QCA_SUPPORT_TXRX_LOCAL_PEER_ID +u_int16_t ol_txrx_local_peer_id(ol_txrx_peer_handle peer); +ol_txrx_peer_handle ol_txrx_find_peer_by_addr(ol_txrx_pdev_handle pdev, + u_int8_t *peer_addr, + u_int8_t *peer_id); +ol_txrx_peer_handle +ol_txrx_find_peer_by_addr_and_vdev(ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, + u_int8_t *peer_addr, + u_int8_t *peer_id); +#else +#define ol_txrx_local_peer_id(peer) OL_TXRX_INVALID_LOCAL_PEER_ID +#define ol_txrx_find_peer_by_addr(pdev, peer_addr, peer_id) NULL +#define ol_txrx_find_peer_by_addr_and_vdev(pdev, vdev, peer_addr, peer_id) NULL +#endif + +#define OL_TXRX_RSSI_INVALID 0xffff +/** + * @brief Provide the current RSSI average from data frames sent by a peer. + * @details + * If a peer has sent data frames, the data SW will optionally keep + * a running average of the RSSI observed for those data frames. + * This function returns that time-average RSSI if is it available, + * or OL_TXRX_RSSI_INVALID if either RSSI tracking is disabled or if + * no data frame indications with valid RSSI meta-data have been received. + * The RSSI is in approximate dBm units, and is normalized with respect + * to a 20 MHz channel. For example, if a data frame is received on a + * 40 MHz channel, wherein both the primary 20 MHz channel and the + * secondary 20 MHz channel have an RSSI of -77 dBm, the reported RSSI + * will be -77 dBm, rather than the actual -74 dBm RSSI from the + * combination of the primary + extension 20 MHz channels. + * Alternatively, the RSSI may be evaluated only on the primary 20 MHz + * channel. + * + * @param peer - which peer's RSSI is desired + * @return RSSI evaluted from frames sent by the specified peer + */ +#ifdef QCA_SUPPORT_PEER_DATA_RX_RSSI +int16_t +ol_txrx_peer_rssi(ol_txrx_peer_handle peer); +#else +#define ol_txrx_peer_rssi(peer) OL_TXRX_RSSI_INVALID +#endif /* QCA_SUPPORT_PEER_DATA_RX_RSSI */ + +#define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff +#if QCA_SUPPORT_TXRX_LOCAL_PEER_ID +u_int16_t ol_txrx_local_peer_id(ol_txrx_peer_handle peer); +#else +#define ol_txrx_local_peer_id(peer) OL_TXRX_INVALID_LOCAL_PEER_ID +#endif + +#ifdef QCA_COMPUTE_TX_DELAY +/** + * @brief updates the compute interval period for TSM stats. + * @details + * @param interval - interval for stats computation + */ +void +ol_tx_set_compute_interval( + ol_txrx_pdev_handle pdev, + u_int32_t interval); + +/** + * @brief Return the uplink (transmitted) packet count and loss count. + * @details + * This function will be called for getting uplink packet count and + * loss count for given stream (access category) a regular interval. + * This also resets the counters hence, the value returned is packets + * counted in last 5(default) second interval. These counter are + * incremented per access category in ol_tx_completion_handler() + * + * @param category - access category of interest + * @param out_packet_count - number of packets transmitted + * @param out_packet_loss_count - number of packets lost + */ +void +ol_tx_packet_count( + ol_txrx_pdev_handle pdev, + u_int16_t *out_packet_count, + u_int16_t *out_packet_loss_count, + int category); +#endif + +/** + * @brief Return the average delays for tx frames. + * @details + * Return the average of the total time tx frames spend within the driver + * and the average time tx frames take to be transmitted. + * These averages are computed over a 5 second time interval. + * These averages are computed separately for separate access categories, + * if the QCA_COMPUTE_TX_DELAY_PER_AC flag is set. + * + * @param pdev - the data physical device instance + * @param queue_delay_microsec - average time tx frms spend in the WLAN driver + * @param tx_delay_microsec - average time for frames to be transmitted + * @param category - category (TID) of interest + */ +#ifdef QCA_COMPUTE_TX_DELAY +void +ol_tx_delay( + ol_txrx_pdev_handle pdev, + u_int32_t *queue_delay_microsec, + u_int32_t *tx_delay_microsec, + int category); +#else +static inline void +ol_tx_delay( + ol_txrx_pdev_handle pdev, + u_int32_t *queue_delay_microsec, + u_int32_t *tx_delay_microsec, + int category) +{ + /* no-op version if QCA_COMPUTE_TX_DELAY is not set */ + *queue_delay_microsec = *tx_delay_microsec = 0; +} +#endif + +/* + * Bins used for reporting delay histogram: + * bin 0: 0 - 10 ms delay + * bin 1: 10 - 20 ms delay + * bin 2: 20 - 40 ms delay + * bin 3: 40 - 80 ms delay + * bin 4: 80 - 160 ms delay + * bin 5: > 160 ms delay + */ +#define QCA_TX_DELAY_HIST_REPORT_BINS 6 +/** + * @brief Provide a histogram of tx queuing delays. + * @details + * Return a histogram showing the number of tx frames of the specified + * category for each of the delay levels in the histogram bin spacings + * listed above. + * These histograms are computed over a 5 second time interval. + * These histograms are computed separately for separate access categories, + * if the QCA_COMPUTE_TX_DELAY_PER_AC flag is set. + * + * @param pdev - the data physical device instance + * @param bin_values - an array of QCA_TX_DELAY_HIST_REPORT_BINS elements + * This array gets filled in with the histogram bin counts. + * @param category - category (TID) of interest + */ +#ifdef QCA_COMPUTE_TX_DELAY +void +ol_tx_delay_hist(ol_txrx_pdev_handle pdev, u_int16_t *bin_values, + int category); +#else +static inline void +ol_tx_delay_hist(ol_txrx_pdev_handle pdev, u_int16_t *bin_values, + int category) +{ + /* no-op version if QCA_COMPUTE_TX_DELAY is not set */ + adf_os_assert(bin_values); + adf_os_mem_zero( + bin_values, QCA_TX_DELAY_HIST_REPORT_BINS * sizeof(*bin_values)); +} +#endif + +#if defined(QCA_SUPPORT_TX_THROTTLE) +/** + * @brief Set the thermal mitgation throttling level. + * @details + * This function applies only to LL systems. This function is used set the + * tx throttle level used for thermal mitigation + * + * @param pdev - the physics device being throttled + */ +void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level); +#else +static inline void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, + int level) +{ + /* no-op */ +} +#endif /* QCA_SUPPORT_TX_THROTTLE */ + +#if defined(QCA_SUPPORT_TX_THROTTLE) +/** + * @brief Configure the thermal mitgation throttling period. + * @details + * This function applies only to LL systems. This function is used set the + * period over which data will be throttled + * + * @param pdev - the physics device being throttled + */ +void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev, int period); +#else +static inline void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev, + int period) +{ + /* no-op */ +} +#endif /* QCA_SUPPORT_TX_THROTTLE */ + +void ol_vdev_rx_set_intrabss_fwd(ol_txrx_vdev_handle vdev, a_bool_t val); + +#ifdef QCA_LL_TX_FLOW_CT +/** + * @brief Query TX resource availability by OS IF + * @details + * OS IF will query TX resource status to decide back pressuring or not + * + * @param vdev - the virtual device + * @param low_watermark - low free descriptor count to pause os tx q + * @param high_watermark_offset - high free descriptor count to resume os tx q + * offset value from low watermark. + * high watermark = low watermark + high_watermark_offset + * @return boolean- true if tx data path has enough resource + false if tx data path does not have enough resource + */ +a_bool_t +ol_txrx_get_tx_resource( + ol_txrx_vdev_handle vdev, + unsigned int low_watermark, + unsigned int high_watermark_offset +); + +/** + * @brief Set MAX LL TX Pause Q depth per vdev + * @details + * Each vdev will have different TX Pause Q depth + * High bandwidth vdev may have more TX Pause Q depth + * Low bandwidth vdev will have less TX Pause Q depth not to block + * high bandwidth vdev + * + * @param vdev - the virtual device + * @param pause_q_depth - TX Pause Q depth per vdev + * @return NONE + */ +void +ol_txrx_ll_set_tx_pause_q_depth( + ol_txrx_vdev_handle vdev, + int pause_q_depth +); +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef IPA_UC_OFFLOAD +/** + * @brief Client request resource information + * @details + * OL client will reuqest IPA UC related resource information + * Resource information will be distributted to IPA module + * All of the required resources should be pre-allocated + * + * @param pdev - handle to the HTT instance + * @param ce_sr_base_paddr - copy engine source ring base physical address + * @param ce_sr_ring_size - copy engine source ring size + * @param ce_reg_paddr - copy engine register physical address + * @param tx_comp_ring_base_paddr - tx comp ring base physical address + * @param tx_comp_ring_size - tx comp ring size + * @param tx_num_alloc_buffer - number of allocated tx buffer + * @param rx_rdy_ring_base_paddr - rx ready ring base physical address + * @param rx_rdy_ring_size - rx ready ring size + * @param rx_proc_done_idx_paddr - rx process done index physical address + */ +void +ol_txrx_ipa_uc_get_resource( + ol_txrx_pdev_handle pdev, + u_int32_t *ce_sr_base_paddr, + u_int32_t *ce_sr_ring_size, + u_int32_t *ce_reg_paddr, + u_int32_t *tx_comp_ring_base_paddr, + u_int32_t *tx_comp_ring_size, + u_int32_t *tx_num_alloc_buffer, + u_int32_t *rx_rdy_ring_base_paddr, + u_int32_t *rx_rdy_ring_size, + u_int32_t *rx_proc_done_idx_paddr +); + +/** + * @brief Client set IPA UC doorbell register + * @details + * IPA UC let know doorbell register physical address + * WLAN firmware will use this physical address to notify IPA UC + * + * @param pdev - handle to the HTT instance + * @param ipa_uc_tx_doorbell_paddr - tx comp doorbell physical address + * @param ipa_uc_rx_doorbell_paddr - rx ready doorbell physical address + */ +void +ol_txrx_ipa_uc_set_doorbell_paddr( + ol_txrx_pdev_handle pdev, + u_int32_t ipa_tx_uc_doorbell_paddr, + u_int32_t ipa_rx_uc_doorbell_paddr +); + +/** + * @brief Client notify IPA UC data path active or not + * + * @param pdev - handle to the HTT instance + * @param uc_active - UC data path is active or not + * @param is_tx - UC TX is active or not + */ +void +ol_txrx_ipa_uc_set_active( + ol_txrx_pdev_handle pdev, + a_bool_t uc_active, + a_bool_t is_tx +); + +/** + * @brief Offload data path activation notificaiton + * @details + * Firmware notification handler for offload datapath activity + * + * @param pdev - handle to the HTT instance + * @param op_code - activated for tx or rx data patrh + */ +void +ol_txrx_ipa_uc_op_response( + ol_txrx_pdev_handle pdev, + u_int8_t *op_msg); + +/** + * @brief callback function registration + * @details + * OSIF layer callback function registration API + * OSIF layer will register firmware offload datapath activity + * notification callback + * + * @param pdev - handle to the HTT instance + * @param ipa_uc_op_cb_type - callback function pointer should be registered + * @param osif_dev - osif instance pointer + */ +void ol_txrx_ipa_uc_register_op_cb( + ol_txrx_pdev_handle pdev, + void (*ipa_uc_op_cb_type)(u_int8_t *op_msg, void *osif_ctxt), + void *osif_dev); + +/** + * @brief query uc data path stats + * @details + * Query uc data path stats from firmware + * + * @param pdev - handle to the HTT instance + */ +void ol_txrx_ipa_uc_get_stat(ol_txrx_pdev_handle pdev); +#else +#define ol_txrx_ipa_uc_get_resource( \ + pdev, \ + ce_sr_base_paddr, \ + ce_sr_ring_size, \ + ce_reg_paddr, \ + tx_comp_ring_base_paddr, \ + tx_comp_ring_size, \ + tx_num_alloc_buffer, \ + rx_rdy_ring_base_paddr, \ + rx_rdy_ring_size, \ + rx_proc_done_idx_paddr) /* NO-OP */ + +#define ol_txrx_ipa_uc_set_doorbell_paddr( \ + pdev, \ + ipa_tx_uc_doorbell_paddr, \ + ipa_rx_uc_doorbell_paddr) /* NO-OP */ + +#define ol_txrx_ipa_uc_set_active( \ + pdev, \ + uc_active, \ + is_tx) /* NO-OP */ + +#define ol_txrx_ipa_uc_op_response( \ + pdev, \ + op_data) /* NO-OP */ + +#define ol_txrx_ipa_uc_register_op_cb( \ + pdev, \ + ipa_uc_op_cb_type, \ + osif_dev) /* NO-OP */ + +#define ol_txrx_ipa_uc_get_stat(pdev) /* NO-OP */ +#endif /* IPA_UC_OFFLOAD */ + +#endif /* _OL_TXRX_CTRL_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_dbg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_dbg.h new file mode 100644 index 0000000000000..41c2eb346c8b6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_dbg.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_dbg.h + * @brief Functions provided for visibility and debugging. + */ +#ifndef _OL_TXRX_DBG__H_ +#define _OL_TXRX_DBG__H_ + +#include /* A_STATUS, u_int64_t */ +#include /* adf_os_mutex_t */ +#include /* htt_dbg_stats_type */ +#include /* ol_txrx_stats */ + +typedef void (*ol_txrx_stats_callback)( + void *ctxt, + enum htt_dbg_stats_type type, + u_int8_t *buf, + int bytes); + +struct ol_txrx_stats_req { + u_int32_t stats_type_upload_mask; /* which stats to upload */ + u_int32_t stats_type_reset_mask; /* which stats to reset */ + + /* stats will be printed if either print element is set */ + struct { + int verbose; /* verbose stats printout */ + int concise; /* concise stats printout (takes precedence) */ + } print; /* print uploaded stats */ + + /* stats notify callback will be invoked if fp is non-NULL */ + struct { + ol_txrx_stats_callback fp; + void *ctxt; + } callback; + + /* stats will be copied into the specified buffer if buf is non-NULL */ + struct { + u_int8_t *buf; + int byte_limit; /* don't copy more than this */ + } copy; + + /* + * If blocking is true, the caller will take the specified semaphore + * to wait for the stats to be uploaded, and the driver will release + * the semaphore when the stats are done being uploaded. + */ + struct { + int blocking; + adf_os_mutex_t *sem_ptr; + } wait; +}; + +#ifndef TXRX_DEBUG_LEVEL +#define TXRX_DEBUG_LEVEL 0 /* no debug info */ +#endif + +#ifndef ATH_PERF_PWR_OFFLOAD /*---------------------------------------------*/ + +#define ol_txrx_debug(vdev, debug_specs) 0 +#define ol_txrx_fw_stats_cfg(vdev, type, val) 0 +#define ol_txrx_fw_stats_get(vdev, req) 0 +#define ol_txrx_aggr_cfg(vdev, max_subfrms_ampdu, max_subfrms_amsdu) 0 + +#else /*---------------------------------------------------------------------*/ + + +#include /* ol_txrx_pdev_handle, etc. */ + +int ol_txrx_debug(ol_txrx_vdev_handle vdev, int debug_specs); + +void ol_txrx_fw_stats_cfg( + ol_txrx_vdev_handle vdev, + u_int8_t cfg_stats_type, + u_int32_t cfg_val); + +int ol_txrx_fw_stats_get( + ol_txrx_vdev_handle vdev, + struct ol_txrx_stats_req *req); + + +int ol_txrx_aggr_cfg(ol_txrx_vdev_handle vdev, + int max_subfrms_ampdu, + int max_subfrms_amsdu); + +enum { + TXRX_DBG_MASK_OBJS = 0x01, + TXRX_DBG_MASK_STATS = 0x02, + TXRX_DBG_MASK_PROT_ANALYZE = 0x04, + TXRX_DBG_MASK_RX_REORDER_TRACE = 0x08, + TXRX_DBG_MASK_RX_PN_TRACE = 0x10 +}; + +/*--- txrx printouts ---*/ + +/* + * Uncomment this to enable txrx printouts with dynamically adjustable + * verbosity. These printouts should not impact performance. + */ +#define TXRX_PRINT_ENABLE 1 +/* uncomment this for verbose txrx printouts (may impact performance) */ +//#define TXRX_PRINT_VERBOSE_ENABLE 1 + +void ol_txrx_print_level_set(unsigned level); + +/*--- txrx object (pdev, vdev, peer) display debug functions ---*/ + +#if TXRX_DEBUG_LEVEL > 5 +void ol_txrx_pdev_display(ol_txrx_pdev_handle pdev, int indent); +void ol_txrx_vdev_display(ol_txrx_vdev_handle vdev, int indent); +void ol_txrx_peer_display(ol_txrx_peer_handle peer, int indent); +#else +#define ol_txrx_pdev_display(pdev, indent) +#define ol_txrx_vdev_display(vdev, indent) +#define ol_txrx_peer_display(peer, indent) +#endif + +/*--- txrx stats display debug functions ---*/ + +#if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF + +void ol_txrx_stats_display(ol_txrx_pdev_handle pdev); + +int +ol_txrx_stats_publish(ol_txrx_pdev_handle pdev, struct ol_txrx_stats *buf); + +#else +#define ol_txrx_stats_display(pdev) +#define ol_txrx_stats_publish(pdev, buf) TXRX_STATS_LEVEL_OFF +#endif /* TXRX_STATS_LEVEL */ + +/*--- txrx protocol analyzer debug feature ---*/ + +/* uncomment this to enable the protocol analzyer feature */ +//#define ENABLE_TXRX_PROT_ANALYZE 1 + +#if defined(ENABLE_TXRX_PROT_ANALYZE) + +void ol_txrx_prot_ans_display(ol_txrx_pdev_handle pdev); + +#else + +#define ol_txrx_prot_ans_display(pdev) + +#endif /* ENABLE_TXRX_PROT_ANALYZE */ + +/*--- txrx sequence number trace debug feature ---*/ + +/* uncomment this to enable the rx reorder trace feature */ +//#define ENABLE_RX_REORDER_TRACE 1 + +#define ol_txrx_seq_num_trace_display(pdev) \ + ol_rx_reorder_trace_display(pdev, 0, 0) + +#if defined(ENABLE_RX_REORDER_TRACE) + +void +ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit); + +#else + +#define ol_rx_reorder_trace_display(pdev, just_once, limit) + +#endif /* ENABLE_RX_REORDER_TRACE */ + +/*--- txrx packet number trace debug feature ---*/ + +/* uncomment this to enable the rx PN trace feature */ +//#define ENABLE_RX_PN_TRACE 1 + +#define ol_txrx_pn_trace_display(pdev) ol_rx_pn_trace_display(pdev, 0) + +#if defined(ENABLE_RX_PN_TRACE) + +void +ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once); + +#else + +#define ol_rx_pn_trace_display(pdev, just_once) + +#endif /* ENABLE_RX_PN_TRACE */ + +/*--- tx queue log debug feature ---*/ +/* uncomment this to enable the tx queue log feature */ +//#define ENABLE_TX_QUEUE_LOG 1 + +#if defined(ENABLE_TX_QUEUE_LOG) && defined(CONFIG_HL_SUPPORT) + +void +ol_tx_queue_log_display(ol_txrx_pdev_handle pdev); + +#else + +#define ol_tx_queue_log_display(pdev) + +#endif /* defined(ENABLE_TX_QUEUE_LOG) && defined(CONFIG_HL_SUPPORT) */ + +#endif /* ATH_PERF_PWR_OFFLOAD */ /*----------------------------------------*/ + +#endif /* _OL_TXRX_DBG__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h new file mode 100644 index 0000000000000..9a1f164f9b3c8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_htt_api.h @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_htt_api.h + * @brief Define the host data API functions called by the host HTT SW. + */ +#ifndef _OL_TXRX_HTT_API__H_ +#define _OL_TXRX_HTT_API__H_ + +#include /* HTT_TX_COMPL_IND_STAT */ +#include /* A_STATUS */ +#include /* adf_nbuf_t */ + +#include /* ol_txrx_pdev_handle */ + + +static inline u_int16_t * +ol_tx_msdu_id_storage(adf_nbuf_t msdu) +{ + adf_os_assert(adf_nbuf_headroom(msdu) >= (sizeof(u_int16_t) * 2 - 1)); + return (u_int16_t *) (((adf_os_size_t) (adf_nbuf_head(msdu) + 1)) & ~0x1); +} + + +/** + * @brief Tx MSDU download completion for a LL system + * @details + * Release the reference to the downloaded tx descriptor. + * In the unlikely event that the reference count is zero, free + * the tx descriptor and tx frame. + * + * @param pdev - (abstract) pointer to the txrx physical device + * @param status - indication of whether the download succeeded + * @param msdu - the downloaded tx frame + * @param msdu_id - the txrx ID of the tx frame - this is used for + * locating the frame's tx descriptor + */ +void +ol_tx_download_done_ll( + void *pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id); + +/** + * @brief Tx MSDU download completion for HL system without tx completion msgs + * @details + * Free the tx descriptor and tx frame. + * Invoke the HL tx download scheduler. + * + * @param pdev - (abstract) pointer to the txrx physical device + * @param status - indication of whether the download succeeded + * @param msdu - the downloaded tx frame + * @param msdu_id - the txrx ID of the tx frame - this is used for + * locating the frame's tx descriptor + */ +void +ol_tx_download_done_hl_free( + void *pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id); + +/** + * @brief Tx MSDU download completion for HL system with tx completion msgs + * @details + * Release the reference to the downloaded tx descriptor. + * In the unlikely event that the reference count is zero, free + * the tx descriptor and tx frame. + * Optionally, invoke the HL tx download scheduler. (It is probable that + * the HL tx download scheduler would operate in response to tx completion + * messages rather than download completion events.) + * + * @param pdev - (abstract) pointer to the txrx physical device + * @param status - indication of whether the download succeeded + * @param msdu - the downloaded tx frame + * @param msdu_id - the txrx ID of the tx frame - this is used for + * locating the frame's tx descriptor + */ +void +ol_tx_download_done_hl_retain( + void *pdev, + A_STATUS status, + adf_nbuf_t msdu, + u_int16_t msdu_id); + +/* + * For now, make the host HTT -> host txrx tx completion status + * match the target HTT -> host HTT tx completion status, so no + * translation is needed. + */ +/* + * host-only statuses use a different part of the number space + * than host-target statuses + */ +#define HTT_HOST_ONLY_STATUS_CODE_START 128 +enum htt_tx_status { + /* ok - successfully sent + acked */ + htt_tx_status_ok = HTT_TX_COMPL_IND_STAT_OK, + + /* discard - not sent (congestion control) */ + htt_tx_status_discard = HTT_TX_COMPL_IND_STAT_DISCARD, + + /* no_ack - sent, but no ack */ + htt_tx_status_no_ack = HTT_TX_COMPL_IND_STAT_NO_ACK, + + /* download_fail - the host could not deliver the tx frame to the target */ + htt_tx_status_download_fail = HTT_HOST_ONLY_STATUS_CODE_START, +}; + +/** + * @brief Process a tx completion message sent by the target. + * @details + * When the target is done transmitting a tx frame (either because + * the frame was sent + acknowledged, or because the target gave up) + * it sends a tx completion message to the host. + * This notification function is used regardless of whether the + * transmission succeeded or not; the status argument indicates whether + * the transmission succeeded. + * This tx completion message indicates via the descriptor ID which + * tx frames were completed, and indicates via the status whether the + * frames were transmitted successfully. + * The host frees the completed descriptors / frames (updating stats + * in the process). + * + * @param pdev - the data physical device that sent the tx frames + * (registered with HTT as a context pointer during attach time) + * @param num_msdus - how many MSDUs are referenced by the tx completion + * message + * @param status - whether transmission was successful + * @param tx_msdu_id_iterator - abstract method of finding the IDs for the + * individual MSDUs referenced by the tx completion message, via the + * htt_tx_compl_desc_id API function + */ +void +ol_tx_completion_handler( + ol_txrx_pdev_handle pdev, + int num_msdus, + enum htt_tx_status status, + void *tx_msdu_id_iterator); + +void +ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits); + +/** + * @brief Init the total amount of target credit. + * @details + * + * @param pdev - the data physical device that sent the tx frames + * @param credit_delta - how much to increment the target's tx credit by + */ +void +ol_tx_target_credit_init(struct ol_txrx_pdev_t *pdev, int credit_delta); + +/** + * @brief Process a tx completion message for a single MSDU. + * @details + * The ol_tx_single_completion_handler function performs the same tx + * completion processing as the ol_tx_completion_handler, but for a + * single frame. + * ol_tx_completion_handler is optimized to handle batch completions + * as efficiently as possible; in contrast ol_tx_single_completion_handler + * handles single frames as simply and generally as possible. + * Thus, this ol_tx_single_completion_handler function is suitable for + * intermittent usage, such as for tx mgmt frames. + * + * @param pdev - the data physical device that sent the tx frames + * @param status - whether transmission was successful + * @param tx_msdu_id - ID of the frame which completed transmission + */ +void +ol_tx_single_completion_handler( + ol_txrx_pdev_handle pdev, + enum htt_tx_status status, + u_int16_t tx_desc_id); + +/** + * @brief Update the amount of target credit. + * @details + * When the target finishes with an old transmit frame, it can use the + * space that was occupied by the old tx frame to store a new tx frame. + * This function is used to inform the txrx layer, where the HL tx download + * scheduler resides, about such updates to the target's tx credit. + * This credit update is done explicitly, rather than having the txrx layer + * update the credit count itself inside the ol_tx_completion handler + * function. This provides HTT with the flexibility to limit the rate of + * downloads from the TXRX layer's download scheduler, by controlling how + * much credit the download scheduler gets, and also provides the flexibility + * to account for a change in the tx memory pool size within the target. + * This function is only used for HL systems; in LL systems, each tx frame + * is assumed to use exactly one credit (for its target-side tx descriptor), + * and any rate limiting is managed within the target. + * + * @param pdev - the data physical device that sent the tx frames + * @param credit_delta - how much to increment the target's tx credit by + */ +void +ol_tx_target_credit_update(struct ol_txrx_pdev_t *pdev, int credit_delta); + + +/** + * @brief Process an rx indication message sent by the target. + * @details + * The target sends a rx indication message to the host as a + * notification that there are new rx frames available for the + * host to process. + * The HTT host layer locates the rx descriptors and rx frames + * associated with the indication, and calls this function to + * invoke the rx data processing on the new frames. + * (For LL, the rx descriptors and frames are delivered directly + * to the host via MAC DMA, while for HL the rx descriptor and + * frame for individual frames are combined with the rx indication + * message.) + * All MPDUs referenced by a rx indication message belong to the + * same peer-TID. + * + * @param pdev - the data physical device that received the frames + * (registered with HTT as a context pointer during attach time) + * @param rx_ind_msg - the network buffer holding the rx indication message + * (For HL, this netbuf also holds the rx desc and rx payload, but + * the data SW is agnostic to whether the desc and payload are + * piggybacked with the rx indication message.) + * @param peer_id - which peer sent this rx data + * @param tid - what (extended) traffic type the rx data is + * @param num_mpdu_ranges - how many ranges of MPDUs does the message describe. + * Each MPDU within the range has the same rx status. + */ +void +ol_rx_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + u_int16_t peer_id, + u_int8_t tid, + int num_mpdu_ranges); + +/** + * @brief Process an rx fragment indication message sent by the target. + * @details + * The target sends a rx fragment indication message to the host as a + * notification that there are new rx fragment available for the + * host to process. + * The HTT host layer locates the rx descriptors and rx fragment + * associated with the indication, and calls this function to + * invoke the rx fragment data processing on the new fragment. + * + * @param pdev - the data physical device that received the frames + * (registered with HTT as a context pointer during attach time) + * @param rx_frag_ind_msg - the network buffer holding the rx fragment indication message + * @param peer_id - which peer sent this rx data + * @param tid - what (extended) traffic type the rx data is + */ +void ol_rx_frag_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_frag_ind_msg, + u_int16_t peer_id, + u_int8_t tid); + +/** + * @brief Process rx offload deliver indication message sent by the target. + * @details + * When the target exits offload mode, target delivers packets that it has held in its + * memory to the host using this message. + * Low latency case: + * The message contains the number of MSDUs that are being delivered by the target to the + * host. The packet itself resides in host ring along with some metadata describing the peer + * id, vdev id, tid, FW desc and length of the packet being delivered. + * Hight letency case: + * The message itself contains the payload of the MSDU being delivered by the target to the + * host. The message also contains meta data describing the packet such as peer id, vdev id, + * tid, FW desc and length of the packet being delivered. Refer to htt.h for the exact structure + * of the message. + * @param pdev - the data physical device that received the frame. + * @param msg - offload deliver indication message + * @param msdu_cnt - number of MSDUs being delivred. + */ +void +ol_rx_offload_deliver_ind_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t msg, + int msdu_cnt); + +/** + * @brief Process a peer map message sent by the target. + * @details + * Each time the target allocates a new peer ID, it will inform the + * host via the "peer map" message. This function processes that + * message. The host data SW looks for a peer object whose MAC address + * matches the MAC address specified in the peer map message, and then + * sets up a mapping between the peer ID specified in the message and + * the peer object that was found. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - ID generated by the target to refer to the peer in question + * The target may create multiple IDs for a single peer. + * @param vdev_id - Reference to the virtual device the peer is associated with + * @param peer_mac_addr - MAC address of the peer in question + * @param tx_ready - whether transmits to this peer can be done already, or + * need to wait for a call to peer_tx_ready (only applies to HL systems) + */ +void +ol_rx_peer_map_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tx_ready); + +/** + * @brief Notify the host that the target is ready to transmit to a new peer. + * @details + * Some targets can immediately accept tx frames for a new peer, as soon as + * the peer's association completes. Other target need a short setup time + * before they are ready to accept tx frames for the new peer. + * If the target needs time for setup, it will provide a peer_tx_ready + * message when it is done with the setup. This function forwards this + * notification from the target to the host's tx queue manager. + * This function only applies for HL systems, in which the host determines + * which peer a given tx frame is for, and stores the tx frames in queues. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - ID for the new peer which can now accept tx frames + */ +void +ol_txrx_peer_tx_ready_handler(ol_txrx_pdev_handle pdev, u_int16_t peer_id); + +/** + * @brief Process a peer unmap message sent by the target. + * @details + * Each time the target frees a peer ID, it will inform the host via the + * "peer unmap" message. This function processes that message. + * The host data SW uses the peer ID from the message to find the peer + * object from peer_map[peer_id], then invalidates peer_map[peer_id] + * (by setting it to NULL), and checks whether there are any remaining + * references to the peer object. If not, the function deletes the + * peer object. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - ID that is being freed. + * The target may create multiple IDs for a single peer. + */ +void +ol_rx_peer_unmap_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id); + +/** + * @brief Process a security indication message sent by the target. + * @details + * When a key is assigned to a peer, the target will inform the host + * with a security indication message. + * The host remembers the security type, and infers whether a rx PN + * check is needed. + * + * @param pdev - data physical device handle + * @param peer_id - which peer the security info is for + * @param sec_type - which type of security / key the peer is using + * @param is_unicast - whether security spec is for a unicast or multicast key + * @param michael_key - key used for TKIP MIC (if sec_type == TKIP) + * @param rx_pn - RSC used for WAPI PN replay check (if sec_type == WAPI) + */ +void +ol_rx_sec_ind_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + enum htt_sec_type sec_type, + int is_unicast, + u_int32_t *michael_key, + u_int32_t *rx_pn); + +/** + * @brief Process an ADDBA message sent by the target. + * @details + * When the target notifies the host of an ADDBA event for a specified + * peer-TID, the host will set up the rx reordering state for the peer-TID. + * Specifically, the host will create a rx reordering array whose length + * is based on the window size specified in the ADDBA. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer the ADDBA event is for + * @param tid - which traffic ID within the peer the ADDBA event is for + * @param win_sz - how many sequence numbers are in the ARQ block ack window + * set up by the ADDBA event + * @param start_seq_num - the initial value of the sequence number during the + * block ack agreement, as specified by the ADDBA request. + * @param failed - indicate whether the target's ADDBA setup succeeded: + * 0 -> success, 1 -> fail + */ +void +ol_rx_addba_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + u_int8_t win_sz, + u_int16_t start_seq_num, + u_int8_t failed); + +/** + * @brief Process a DELBA message sent by the target. + * @details + * When the target notifies the host of a DELBA event for a specified + * peer-TID, the host will clean up the rx reordering state for the peer-TID. + * Specifically, the host will remove the rx reordering array, and will + * set the reorder window size to be 1 (stop and go ARQ). + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer the ADDBA event is for + * @param tid - which traffic ID within the peer the ADDBA event is for + */ +void +ol_rx_delba_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid); + +enum htt_rx_flush_action { + htt_rx_flush_release, + htt_rx_flush_discard, +}; + +/** + * @brief Process a rx reorder flush message sent by the target. + * @details + * The target's rx reorder logic can send a flush indication to the + * host's rx reorder buffering either as a flush IE within a rx + * indication message, or as a standalone rx reorder flush message. + * This ol_rx_flush_handler function processes the standalone rx + * reorder flush message from the target. + * The flush message specifies a range of sequence numbers whose + * rx frames are flushed. + * Some sequence numbers within the specified range may not have + * rx frames; the host needs to check for each sequence number in + * the specified range whether there are rx frames held for that + * sequence number. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer's rx data is being flushed + * @param tid - which traffic ID within the peer has the rx data being flushed + * @param seq_num_start - Which sequence number within the rx reordering + * buffer the flushing should start with. + * This is the LSBs of the 802.11 sequence number. + * This sequence number is masked with the rounded-to-power-of-two + * window size to generate a reorder buffer index. + * The flush includes this initial sequence number. + * @param seq_num_end - Which sequence number within the rx reordering + * buffer the flushing should stop at. + * This is the LSBs of the 802.11 sequence number. + * This sequence number is masked with the rounded-to-power-of-two + * window size to generate a reorder buffer index. + * The flush excludes this final sequence number. + * @param action - whether to release or discard the rx frames + */ +void +ol_rx_flush_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + u_int16_t seq_num_start, + u_int16_t seq_num_end, + enum htt_rx_flush_action action); + +/** + * @brief Process a rx pn indication message + * @details + * When the peer is configured to get PN checking done in target, + * the target instead of sending reorder flush/release messages + * sends PN indication messages which contain the start and end + * sequence numbers to be flushed/released along with the sequence + * numbers of MPDUs that failed the PN check in target. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param peer_id - which peer's rx data is being flushed + * @param tid - which traffic ID within the peer + * @param seq_num_start - Which sequence number within the rx reordering + * buffer to start with. + * This is the LSBs of the 802.11 sequence number. + * This sequence number is masked with the rounded-to-power-of-two + * window size to generate a reorder buffer index. + * This is the initial sequence number. + * @param seq_num_end - Which sequence number within the rx reordering + * buffer to stop at. + * This is the LSBs of the 802.11 sequence number. + * This sequence number is masked with the rounded-to-power-of-two + * window size to generate a reorder buffer index. + * The processing stops right before this sequence number + * @param pn_ie_cnt - Indicates the number of PN information elements. + * @param pn_ie - Pointer to the array of PN information elements. Each + * PN information element contains the LSBs of the 802.11 sequence number + * of the MPDU that failed the PN checking in target. + */ +void +ol_rx_pn_ind_handler( + ol_txrx_pdev_handle pdev, + u_int16_t peer_id, + u_int8_t tid, + int seq_num_start, + int seq_num_end, + u_int8_t pn_ie_cnt, + u_int8_t *pn_ie); + +/** + * @brief Process a stats message sent by the target. + * @details + * The host can request target for stats. + * The target sends the stats to the host via a confirmation message. + * This ol_txrx_fw_stats_handler function processes the confirmation message. + * Currently, this processing consists of copying the stats from the message + * buffer into the txrx pdev object, and waking the sleeping host context + * that requested the stats. + * + * @param pdev - data physical device handle + * (registered with HTT as a context pointer during attach time) + * @param cookie - Value echoed from the cookie in the stats request + * message. This allows the host SW to find the stats request object. + * (Currently, this cookie is unused.) + * @param stats_info_list - stats confirmation message contents, containing + * a list of the stats requested from the target + */ +void +ol_txrx_fw_stats_handler( + ol_txrx_pdev_handle pdev, + u_int64_t cookie, + u_int8_t *stats_info_list); + +/** + * @brief Process a tx inspect message sent by the target. + * @details: + * TODO: update + * This tx inspect message indicates via the descriptor ID + * which tx frames are to be inspected by host. The host + * re-injects the packet back to the host for a number of + * cases. + * + * @param pdev - the data physical device that sent the tx frames + * (registered with HTT as a context pointer during attach time) + * @param num_msdus - how many MSDUs are referenced by the tx completion + * message + * @param tx_msdu_id_iterator - abstract method of finding the IDs for the + * individual MSDUs referenced by the tx completion message, via the + * htt_tx_compl_desc_id API function + */ +void +ol_tx_inspect_handler( + ol_txrx_pdev_handle pdev, + int num_msdus, + void *tx_desc_id_iterator); + +/** + * @brief Get the UAPSD mask. + * @details + * This function will return the UAPSD TID mask. + * + * @param txrx_pdev - pointer to the txrx pdev object + * @param peer_id - PeerID. + * @return uapsd mask value + */ +u_int8_t +ol_txrx_peer_uapsdmask_get(struct ol_txrx_pdev_t * txrx_pdev, + u_int16_t peer_id); + +/** + * @brief Get the Qos Capable. + * @details + * This function will return the txrx_peer qos_capable. + * + * @param txrx_pdev - pointer to the txrx pdev object + * @param peer_id - PeerID. + * @return qos_capable value + */ +u_int8_t +ol_txrx_peer_qoscapable_get(struct ol_txrx_pdev_t * txrx_pdev, + u_int16_t peer_id); + +/** + * @brief Process an rx indication message sent by the target. + * @details + * The target sends a rx indication message to the host as a + * notification that there are new rx frames available for the + * host to process. + * The HTT host layer locates the rx descriptors and rx frames + * associated with the indication, and calls this function to + * invoke the rx data processing on the new frames. + * All MPDUs referenced by a rx indication message belong to the + * same peer-TID. The frames indicated have been re-ordered by + * the target. + * + * @param pdev - the data physical device that received the frames + * (registered with HTT as a context pointer during attach time) + * @param rx_ind_msg - the network buffer holding the rx indication message + * @param peer_id - which peer sent this rx data + * @param tid - what (extended) traffic type the rx data is + * @param is_offload - is this an offload indication? + */ +void +ol_rx_in_order_indication_handler( + ol_txrx_pdev_handle pdev, + adf_nbuf_t rx_ind_msg, + u_int16_t peer_id, + u_int8_t tid, + u_int8_t is_offload ); + +#endif /* _OL_TXRX_HTT_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_osif_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_osif_api.h new file mode 100644 index 0000000000000..6808f64a782a8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_osif_api.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_osif_api.h + * @brief Define the host data API functions called by the host OS shim SW. + */ +#ifndef _OL_TXRX_OSIF_API__H_ +#define _OL_TXRX_OSIF_API__H_ + +#include /* adf_nbuf_t */ + +#include /* ol_osif_vdev_handle */ +#include /* ol_txrx_pdev_handle, etc. */ + +/** + * @typedef ol_txrx_tx_fp + * @brief top-level transmit function + */ +typedef adf_nbuf_t (*ol_txrx_tx_fp)( + ol_txrx_vdev_handle data_vdev, adf_nbuf_t msdu_list); + +/** + * @typedef ol_txrx_tx_non_std_fp + * @brief top-level transmit function for non-standard tx frames + * @details + * This function pointer provides an alternative to the ol_txrx_tx_fp + * to support non-standard transmits. In particular, this function + * supports transmission of: + * 1. "Raw" frames + * These raw frames already have an 802.11 header; the usual + * 802.11 header encapsulation by the driver does not apply. + * 2. TSO segments + * During tx completion, the txrx layer needs to reclaim the buffer + * that holds the ethernet/IP/TCP header created for the TSO segment. + * Thus, these tx frames need to be marked as TSO, to show that they + * need this special handling during tx completion. + * + * @param data_vdev - which virtual device should transmit the frame + * @param tx_spec - what non-standard operations to apply to the tx frame + * @param msdu_list - tx frame(s), in a null-terminated list + */ +typedef adf_nbuf_t (*ol_txrx_tx_non_std_fp)( + ol_txrx_vdev_handle data_vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list); + +struct txrx_rx_metainfo; + +#ifdef OSIF_NEED_RX_PEER_ID +/** + * @typedef ol_txrx_rx_fp + * @brief receive function to hand batches of data frames from txrx to OS shim + * @details this version of rx callback is for the OS shim, for example CLD, which + * depends on peer id information in data rx. + */ +typedef void (*ol_txrx_rx_fp)(void *osif_dev, u_int16_t peer_id, + adf_nbuf_t msdus); +#else + +/** + * @typedef ol_txrx_rx_fp + * @brief receive function to hand batches of data frames from txrx to OS shim + */ +typedef void (*ol_txrx_rx_fp)(void *osif_dev, adf_nbuf_t msdus); +#endif /* OSIF_NEED_RX_PEER_ID */ + +/** + * @typedef ol_txrx_tx_fc_fp + * @brief tx flow control notification function from txrx to OS shim + * @param osif_dev - the virtual device's OS shim object + * @param vdev_id - virtual device id + * @param tx_resume - tx os q should be resumed or not + */ +typedef void (*ol_txrx_tx_flow_control_fp)(void *osif_dev, + u_int8_t vdev_id, a_bool_t tx_resume); + +/** + * @typedef ol_txrx_rx_fp + * @brief receive function to hand batches of data frames from txrx to OS shim + */ + +struct ol_txrx_osif_ops { + /* tx function pointers - specified by txrx, stored by OS shim */ + struct { + ol_txrx_tx_fp std; + ol_txrx_tx_non_std_fp non_std; + ol_txrx_tx_flow_control_fp flow_control_cb; + } tx; + + /* rx function pointers - specified by OS shim, stored by txrx */ + struct { + ol_txrx_rx_fp std; + } rx; +}; + +/** + * @brief Link a vdev's data object with the matching OS shim vdev object. + * @details + * The data object for a virtual device is created by the function + * ol_txrx_vdev_attach. However, rather than fully linking the + * data vdev object with the vdev objects from the other subsystems + * that the data vdev object interacts with, the txrx_vdev_attach + * function focuses primarily on creating the data vdev object. + * After the creation of both the data vdev object and the OS shim + * vdev object, this txrx_osif_vdev_attach function is used to connect + * the two vdev objects, so the data SW can use the OS shim vdev handle + * when passing rx data received by a vdev up to the OS shim. + * + * @param txrx_vdev - the virtual device's data object + * @param osif_vdev - the virtual device's OS shim object + * @param txrx_ops - (pointers to) the functions used for tx and rx data xfer + * There are two portions of these txrx operations. + * The rx portion is filled in by OSIF SW before calling + * ol_txrx_osif_vdev_register; inside the ol_txrx_osif_vdev_register + * the txrx SW stores a copy of these rx function pointers, to use + * as it delivers rx data frames to the OSIF SW. + * The tx portion is filled in by the txrx SW inside + * ol_txrx_osif_vdev_register; when the function call returns, + * the OSIF SW stores a copy of these tx functions to use as it + * delivers tx data frames to the txrx SW. + * The rx function pointer inputs consist of the following: + * rx: the OS shim rx function to deliver rx data frames to. + * This can have different values for different virtual devices, + * e.g. so one virtual device's OS shim directly hands rx frames to + * the OS, but another virtual device's OS shim filters out P2P + * messages before sending the rx frames to the OS. + * The netbufs delivered to the osif_rx function are in the format + * specified by the OS to use for tx and rx frames (either 802.3 or + * native WiFi). + * rx_mon: the OS shim rx monitor function to deliver monitor data to + * Though in practice, it is probable that the same function will + * be used for delivering rx monitor data for all virtual devices, + * in theory each different virtual device can have a different + * OS shim function for accepting rx monitor data. + * The netbufs delivered to the osif_rx_mon function are in 802.11 + * format. Each netbuf holds a 802.11 MPDU, not an 802.11 MSDU. + * Depending on compile-time configuration, each netbuf may also + * have a monitor-mode encapsulation header such as a radiotap + * header added before the MPDU contents. + * The tx function pointer outputs consist of the following: + * tx: the tx function pointer for standard data frames + * This function pointer is set by the txrx SW to perform + * host-side transmit operations based on whether a HL or LL + * host/target interface is in use. + * tx_non_std: the tx function pointer for non-standard data frames, + * such as TSO frames, explicitly-prioritized frames, or "raw" + * frames which skip some of the tx operations, such as 802.11 + * MAC header encapsulation. + */ +void +ol_txrx_osif_vdev_register( + ol_txrx_vdev_handle txrx_vdev, + void *osif_vdev, + struct ol_txrx_osif_ops *txrx_ops); + +/** + * @brief Divide a jumbo TCP frame into smaller segments. + * @details + * For efficiency, the protocol stack above the WLAN driver may operate + * on jumbo tx frames, which are larger than the 802.11 MTU. + * The OSIF SW uses this txrx API function to divide the jumbo tx TCP frame + * into a series of segment frames. + * The segments are created as clones of the input jumbo frame. + * The txrx SW generates a new encapsulation header (ethernet + IP + TCP) + * for each of the output segment frames. The exact format of this header, + * e.g. 802.3 vs. Ethernet II, and IPv4 vs. IPv6, is chosen to match the + * header format of the input jumbo frame. + * The input jumbo frame is not modified. + * After the ol_txrx_osif_tso_segment returns, the OSIF SW needs to perform + * DMA mapping on each of the segment network buffers, and also needs to + * + * @param txrx_vdev - which virtual device will transmit the TSO segments + * @param max_seg_payload_bytes - the maximum size for the TCP payload of + * each segment frame. + * This does not include the ethernet + IP + TCP header sizes. + * @param jumbo_tcp_frame - jumbo frame which needs to be cloned+segmented + * @return + * NULL if the segmentation fails, - OR - + * a NULL-terminated list of segment network buffers + */ +adf_nbuf_t ol_txrx_osif_tso_segment( + ol_txrx_vdev_handle txrx_vdev, + int max_seg_payload_bytes, + adf_nbuf_t jumbo_tcp_frame); + +#endif /* _OL_TXRX_OSIF_API__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_stats.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_stats.h new file mode 100644 index 0000000000000..1e2b78dde248f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_txrx_stats.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @file ol_txrx_status.h + * @brief Functions provided for visibility and debugging. + * NOTE: This file is used by both kernel driver SW and userspace SW. + * Thus, do not reference use any kernel header files or defs in this file! + */ +#ifndef _OL_TXRX_STATS__H_ +#define _OL_TXRX_STATS__H_ + +#include /* u_int64_t */ + +#define TXRX_STATS_LEVEL_OFF 0 +#define TXRX_STATS_LEVEL_BASIC 1 +#define TXRX_STATS_LEVEL_FULL 2 + +#ifndef TXRX_STATS_LEVEL +#define TXRX_STATS_LEVEL TXRX_STATS_LEVEL_BASIC +#endif + +typedef struct { + u_int64_t pkts; + u_int64_t bytes; +} ol_txrx_stats_elem; + +/** + * @brief data stats published by the host txrx layer + */ +struct ol_txrx_stats { + struct { + /* MSDUs given to the txrx layer by the management stack */ + ol_txrx_stats_elem mgmt; + /* MSDUs successfully sent across the WLAN */ + ol_txrx_stats_elem delivered; + struct { + /* MSDUs that the host did not accept */ + ol_txrx_stats_elem host_reject; + /* MSDUs which could not be downloaded to the target */ + ol_txrx_stats_elem download_fail; + /* MSDUs which the target discarded (lack of mem or old age) */ + ol_txrx_stats_elem target_discard; + /* MSDUs which the target sent but couldn't get an ack for */ + ol_txrx_stats_elem no_ack; + } dropped; + } tx; + struct { + /* MSDUs given to the OS shim */ + ol_txrx_stats_elem delivered; + /* MSDUs forwarded from the rx path to the tx path */ + ol_txrx_stats_elem forwarded; + } rx; +}; + +/* + * Structure to consolidate host stats + */ +struct ieee80211req_ol_ath_host_stats { + struct ol_txrx_stats txrx_stats; + struct { + int pkt_q_fail_count; + int pkt_q_empty_count; + int send_q_empty_count; + } htc; + struct { + int pipe_no_resrc_count; + int ce_ring_delta_fail_count; + } hif; +}; + +#endif /* _OL_TXRX_STATS__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_vowext_dbg_defs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_vowext_dbg_defs.h new file mode 100644 index 0000000000000..3c8c8039a1cb2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/ol_vowext_dbg_defs.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _VOW_DEFINES__H_ +#define _VOW_DEFINES__H_ + + +#define UDP_CKSUM_OFFSET 40 /* UDP check sum offset in network buffer */ +#define RTP_HDR_OFFSET 42 /* RTP header offset in network buffer */ +#define EXT_HDR_OFFSET 54 /* Extension header offset in network buffer */ +#define UDP_PDU_RTP_EXT 0x90 /* ((2 << 6) | (1 << 4)) RTP Version 2 + X bit */ +#define IP_VER4_N_NO_EXTRA_HEADERS 0x45 +#define IPERF3_DATA_OFFSET 12 /* iperf3 data offset from EXT_HDR_OFFSET */ +#define HAL_RX_40 0x08 /* 40 Mhz */ +#define HAL_RX_GI 0x04 /* full gi */ + +struct vow_extstats { + u_int8_t rx_rssi_ctl0; /* control channel chain0 rssi */ + u_int8_t rx_rssi_ctl1; /* control channel chain1 rssi */ + u_int8_t rx_rssi_ctl2; /* control channel chain2 rssi */ + u_int8_t rx_rssi_ext0; /* extention channel chain0 rssi */ + u_int8_t rx_rssi_ext1; /* extention channel chain1 rssi */ + u_int8_t rx_rssi_ext2; /* extention channel chain2 rssi */ + u_int8_t rx_rssi_comb; /* combined RSSI value */ + u_int8_t rx_bw; /* Band width 0-20, 1-40, 2-80 */ + u_int8_t rx_sgi; /* Guard interval, 0-Long GI, 1-Short GI */ + u_int8_t rx_nss; /* Number of spatial streams */ + u_int8_t rx_mcs; /* Rate MCS value */ + u_int8_t rx_ratecode; /* Hardware rate code */ + u_int8_t rx_rs_flags; /* Recieve misc flags */ + u_int8_t rx_moreaggr; /* 0 - non aggr frame */ + u_int32_t rx_macTs; /* Time stamp */ + u_int16_t rx_seqno; /* rx sequence number*/ +}; + +/** + * @brief populates vow ext stats in given network buffer. + * @param msdu - network buffer handle + * @param pdev - handle to htt dev. + */ +void ol_ath_add_vow_extstats(htt_pdev_handle pdev, adf_nbuf_t msdu); + +#endif /* _VOW_DEFINES__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osapi_linux.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osapi_linux.h new file mode 100644 index 0000000000000..6a8517527b695 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osapi_linux.h @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +//------------------------------------------------------------------------------ +// This file contains the definitions of the basic atheros data types. +// It is used to map the data types in atheros files to a platform specific +// type. +//------------------------------------------------------------------------------ + +#ifndef _OSAPI_LINUX_H_ +#define _OSAPI_LINUX_H_ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include +#include "a_types.h" + +#ifdef __GNUC__ +#define __ATTRIB_PACK __attribute__ ((packed)) +#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) +#define __ATTRIB_NORETURN __attribute__ ((noreturn)) +#else /* Not GCC */ +#define __ATTRIB_PACK +#define __ATTRIB_PRINTF +#define __ATTRIB_NORETURN +#endif /* End __GNUC__ */ + +#define PREPACK +#define POSTPACK __ATTRIB_PACK + +/* + * Endianes macros + */ +#define A_BE2CPU8(x) ntohb(x) +#define A_BE2CPU16(x) ntohs(x) +#define A_BE2CPU32(x) ntohl(x) + +#define A_LE2CPU8(x) (x) +#define A_LE2CPU16(x) (x) +#define A_LE2CPU32(x) (x) + +#define A_CPU2BE8(x) htonb(x) +#define A_CPU2BE16(x) htons(x) +#define A_CPU2BE32(x) htonl(x) + +#define A_MEMCPY(dst, src, len) memcpy((A_UINT8 *)(dst), (src), (len)) +#define A_MEMZERO(addr, len) memset(addr, 0, len) +#define A_MEMSET(addr, value, size) memset((addr), (value), (size)) +#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) + +#ifdef AR6K_ALLOC_DEBUG +#define a_meminfo_add(p, s) __a_meminfo_add(p, s, __func__, __LINE) +#define a_mem_trace(ptr) __a_mem_trace(ptr, __func__, __LINE__) +void __a_mem_trace(void *ptr, const char *func, int lineno); +void __a_meminfo_add(void *ptr, size_t msize, const char *func, int lineno); +void a_meminfo_del(void *ptr); +void* a_mem_alloc(size_t msize, int type, const char *func, int lineno); +void a_mem_free(void *ptr); +void a_meminfo_report(int clear); +#define A_MALLOC(size) a_mem_alloc((size), GFP_KERNEL, __func__, __LINE__) +#define A_MALLOC_NOWAIT(size) a_mem_alloc((size), GFP_ATOMIC, __func__, __LINE__) +#define A_FREE(addr) a_mem_free(addr) +#define A_NETIF_RX(skb) do { a_meminfo_del(skb); netif_rx(skb); } while (0) +#define A_NETIF_RX_NI(skb) do { a_meminfo_del(skb); netif_rx_ni(skb); } while (0) +#else +#define a_meminfo_report(_c) +#define A_MALLOC(size) adf_os_mem_alloc(NULL, size) +#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) +#define a_mem_trace(ptr) +#define A_FREE(addr) adf_os_mem_free(addr) +#define A_NETIF_RX(skb) netif_rx(skb) +#define A_NETIF_RX_NI(skb) netif_rx_ni(skb) +#endif + +#define OS_DMA_MALLOC(size) kmalloc((size), GFP_ATOMIC) +#define OS_DMA_FREE(addr) kfree(addr) + +#define A_VMALLOC(size) vmalloc((size)) +#define A_VFREE(addr) vfree(addr) +#if defined(ANDROID_ENV) && defined(CONFIG_ANDROID_LOGGER) +extern unsigned int enablelogcat; +extern int android_logger_lv(void* module, int mask); +enum logidx { LOG_MAIN_IDX = 0 }; +extern int logger_write(const enum logidx idx, + const unsigned char prio, + const char __kernel * const tag, + const char __kernel * const fmt, + ...); +#define A_ANDROID_PRINTF(mask, module, tags, args...) do { \ + if (enablelogcat) \ + logger_write(LOG_MAIN_IDX, android_logger_lv(module, mask), tags, args); \ + else \ + printk(KERN_ALERT args); \ +} while (0) +#ifdef DEBUG +#define A_LOGGER_MODULE_NAME(x) #x +#define A_LOGGER(mask, mod, args...) \ + A_ANDROID_PRINTF(mask, &GET_ATH_MODULE_DEBUG_VAR_NAME(mod), "ar6k_" A_LOGGER_MODULE_NAME(mod), args); +#endif +#define A_PRINTF(args...) A_ANDROID_PRINTF(ATH_DEBUG_INFO, NULL, "ar6k_driver", args) +#else +#define A_LOGGER(mask, mod, args...) printk(args) +#define A_PRINTF(args...) printk(args) +#endif /* ANDROID */ +#define A_PRINTF_LOG(args...) printk(args) +#define A_SNPRINTF(buf, len, args...) snprintf (buf, len, args) + +/* Mutual Exclusion */ +typedef spinlock_t A_MUTEX_T; +#define A_MUTEX_INIT(mutex) spin_lock_init(mutex) +#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex) +#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex) +#define A_IS_MUTEX_VALID(mutex) TRUE /* okay to return true, since A_MUTEX_DELETE does nothing */ +#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */ + +/* Get current time in ms adding a constant offset (in ms) */ +#define A_GET_MS(offset) \ + (((jiffies / HZ) * 1000) + (offset)) + +/* + * Timer Functions + */ +#define A_MDELAY(msecs) mdelay(msecs) +#define A_MSLEEP(msecs) \ +{ \ + set_current_state(TASK_INTERRUPTIBLE); \ + schedule_timeout((HZ * (msecs)) / 1000); \ + set_current_state(TASK_RUNNING); \ +} + +typedef struct timer_list A_TIMER; + +#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \ + init_timer_deferrable(pTimer); \ + (pTimer)->function = (pFunction); \ + (pTimer)->data = (unsigned long)(pArg); \ +} while (0) + +/* + * Start a Timer that elapses after 'periodMSec' milli-seconds + * Support is provided for a one-shot timer. The 'repeatFlag' is + * ignored. + */ +#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \ + if (repeatFlag) { \ + printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \ + panic("Timer Repeat"); \ + } \ + mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \ +} while (0) + +/* + * Cancel the Timer. + */ +#define A_UNTIMEOUT(pTimer) do { \ + del_timer((pTimer)); \ +} while (0) + +#define A_DELETE_TIMER(pTimer) do { \ +} while (0) + +/* + * Wait Queue related functions + */ +typedef wait_queue_head_t A_WAITQUEUE_HEAD; +#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head) +#ifndef wait_event_interruptible_timeout +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) +#endif /* wait_event_interruptible_timeout */ + +#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \ + wait_event_interruptible_timeout(head, condition, timeout); \ +} while (0) + +#define A_WAKE_UP(head) wake_up(head) + +#ifdef DEBUG +#ifdef A_SIMOS_DEVHOST +extern unsigned int panic_on_assert; +#define A_ASSERT(expr) \ + if (!(expr)) { \ + printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \ + if (panic_on_assert) panic(#expr); \ + } +#else +#define A_ASSERT(expr) \ + if (!(expr)) { \ + printk(KERN_ALERT "Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \ + } +#endif +#else +#define A_ASSERT(expr) +#endif /* DEBUG */ + +#ifdef ANDROID_ENV +struct firmware; +int android_request_firmware(const struct firmware **firmware_p, const char *filename, + struct device *device); +void android_release_firmware(const struct firmware *firmware); +#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) android_request_firmware(_ppf, _pfile, _dev) +#define A_RELEASE_FIRMWARE(_pf) android_release_firmware(_pf) +#else +#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev) +#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf) +#endif + +/* + * Initialization of the network buffer subsystem + */ +#define A_NETBUF_INIT() + +/* + * Network buffer queue support + */ +typedef struct sk_buff_head A_NETBUF_QUEUE_T; + +#define A_NETBUF_QUEUE_INIT(q) \ + a_netbuf_queue_init(q) + +#define A_NETBUF_ENQUEUE(q, pkt) \ + a_netbuf_enqueue((q), (pkt)) +#define A_NETBUF_PREQUEUE(q, pkt) \ + a_netbuf_prequeue((q), (pkt)) +#define A_NETBUF_DEQUEUE(q) \ + (a_netbuf_dequeue(q)) +#define A_NETBUF_QUEUE_SIZE(q) \ + a_netbuf_queue_size(q) +#define A_NETBUF_QUEUE_EMPTY(q) \ + a_netbuf_queue_empty(q) + +/* + * Network buffer support + */ +#ifdef AR6K_ALLOC_DEBUG +#define A_NETBUF_ALLOC(size) \ + a_netbuf_alloc(size, __func__, __LINE__) +#define A_NETBUF_ALLOC_RAW(size) \ + a_netbuf_alloc_raw(size, __func__, __LINE__) +#define A_NETBUF_MANAGE(bufPtr) \ + a_netbuf_manage(bufPtr, __func__, __LINE__) +#define A_NETBUF_UNMANAGE(bufPtr) \ + a_netbuf_unmanage(bufPtr) +#else +#define A_NETBUF_ALLOC(size) \ + a_netbuf_alloc(size) +#define A_NETBUF_ALLOC_RAW(size) \ + a_netbuf_alloc_raw(size) +#define A_NETBUF_MANAGE(bufPtr) +#define A_NETBUF_UNMANAGE(bufPtr) +#endif /* AR6K_ALLOC_DEBUG */ +#define A_NETBUF_FREE(bufPtr) \ + a_netbuf_free(bufPtr) +#define A_NETBUF_LEN(bufPtr) \ + a_netbuf_to_len(bufPtr) +#define A_NETBUF_PUSH(bufPtr, len) \ + a_netbuf_push(bufPtr, len) +#define A_NETBUF_PUT(bufPtr, len) \ + a_netbuf_put(bufPtr, len) +#define A_NETBUF_TRIM(bufPtr,len) \ + a_netbuf_trim(bufPtr, len) +#define A_NETBUF_PULL(bufPtr, len) \ + a_netbuf_pull(bufPtr, len) +#define A_NETBUF_HEADROOM(bufPtr)\ + a_netbuf_headroom(bufPtr) +#define A_NETBUF_SETLEN(bufPtr,len) \ + a_netbuf_setlen(bufPtr, len) + +/* Add data to end of a buffer */ +#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \ + a_netbuf_put_data(bufPtr, srcPtr, len) + +/* Add data to start of the buffer */ +#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \ + a_netbuf_push_data(bufPtr, srcPtr, len) + +/* Remove data at start of the buffer */ +#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \ + a_netbuf_pull_data(bufPtr, dstPtr, len) + +/* Remove data from the end of the buffer */ +#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \ + a_netbuf_trim_data(bufPtr, dstPtr, len) + +/* View data as "size" contiguous bytes of type "t" */ +#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \ + (t )( ((struct skbuf *)(bufPtr))->data) + +/* return the beginning of the headroom for the buffer */ +#define A_NETBUF_HEAD(bufPtr) \ + ((((struct sk_buff *)(bufPtr))->head)) + +/* + * OS specific network buffer access routines + */ +#ifdef AR6K_ALLOC_DEBUG +void *a_netbuf_alloc(int size, const char *func, int lineno); +void *a_netbuf_alloc_raw(int size, const char *func, int lineno); +void a_netbuf_manage(void *bufPtr, const char *func, int lineno); +void a_netbuf_unmanage(void *bufPtr); +#else +void *a_netbuf_alloc(int size); +void *a_netbuf_alloc_raw(int size); +#endif +void a_netbuf_free(void *bufPtr); +void *a_netbuf_to_data(void *bufPtr); +A_UINT32 a_netbuf_to_len(void *bufPtr); +A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len); +A_STATUS a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); +A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len); +A_STATUS a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len); +A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len); +A_STATUS a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len); +A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len); +A_STATUS a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len); +A_STATUS a_netbuf_setlen(void *bufPtr, A_INT32 len); +A_INT32 a_netbuf_headroom(void *bufPtr); +void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); +void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); +void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); +int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q); +int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); +int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); +void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); + +/* + * Kernel v.s User space functions + */ +A_UINT32 a_copy_to_user(void *to, const void *from, A_UINT32 n); +A_UINT32 a_copy_from_user(void *to, const void *from, A_UINT32 n); + +/* In linux, WLAN Rx and Tx run in different contexts, so no need to check + * for any commands/data queued for WLAN */ +#define A_CHECK_DRV_TX() + +#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES + +#define A_CACHE_LINE_PAD 128 + +static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { + return (void *)L1_CACHE_ALIGN((unsigned long)ptr); +} + +#ifdef QCA_PARTNER_PLATFORM + +#include "ath_carr_pltfrm.h" + +#else +#define A_PCI_READ32(addr) ioread32((void __iomem *)addr) +#define A_PCI_WRITE32(addr, value) iowrite32((u32)(value), (void __iomem *)(addr)) +#endif /* QCA_PARTNER_PLATFORM */ + +typedef struct semaphore A_SEMA; +#define A_SEMA_INIT(_sem, _val) sema_init((_sem), (_val)) +static __inline__ +void A_SEMA_WAKEUP(void *osdev, A_SEMA *sem) +{ + up(sem); +} +static __inline__ +bool A_SEMA_SLEEP(void *osdev, A_SEMA *sem) +{ + return down_timeout(sem, HZ); +} + + +typedef struct ieee80211_cb wbuf_context; +#define wbuf_get_cb(skb) ((skb)->cb) + +#else /* __KERNEL__ */ + +#ifdef __GNUC__ +#define __ATTRIB_PACK __attribute__ ((packed)) +#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) +#define __ATTRIB_NORETURN __attribute__ ((noreturn)) +#ifndef INLINE +#define INLINE __inline__ +#endif +#else /* Not GCC */ +#define __ATTRIB_PACK +#define __ATTRIB_PRINTF +#define __ATTRIB_NORETURN +#ifndef INLINE +#define INLINE __inline +#endif +#endif /* End __GNUC__ */ + +#define PREPACK +#define POSTPACK __ATTRIB_PACK + +#define A_MEMCPY(dst, src, len) memcpy((dst), (src), (len)) +#define A_MEMSET(addr, value, size) memset((addr), (value), (size)) +#define A_MEMZERO(addr, len) memset((addr), 0, (len)) +#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) +#define A_MALLOC(size) malloc(size) +#define A_FREE(addr) free(addr) + + +#ifdef ANDROID +#ifndef err +#include +#define err(_s, args...) do { \ + fprintf(stderr, "%s: line %d ", __FILE__, __LINE__); \ + fprintf(stderr, args); fprintf(stderr, ": %d\n", errno); \ + exit(_s); } while (0) +#endif +#else +#include +#endif + +#endif /* __KERNEL__ */ + +#endif /* _OSAPI_LINUX_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep.h new file mode 100644 index 0000000000000..46248546c22e1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ATH_LINUX_OSDEP_H +#define _ATH_LINUX_OSDEP_H +#include "wlan_opts.h" + +#ifdef ADF_SUPPORT +#include "osdep_adf.h" +#endif /* end of ADF_SUPPORT */ + +#ifdef HOST_OFFLOAD + +void atd_proxy_arp_send(struct sk_buff *nbuf); +void atd_rx_from_wlan(struct sk_buff * nbuf); + +static inline int _copy_to_user(void *dst ,void *src, int size) +{ + memcpy(dst,src,size); + return 0; +} +static inline int _copy_from_user(void *dst ,void *src, int size) +{ + memcpy(dst,src,size); + return 0; +} + +#define _netif_carrier_on(dev) \ + do { \ + union iwreq_data w; \ + netif_carrier_on(dev); \ + memset(&w, 0, sizeof(w)); \ + w.data.flags = IEEE80211_EV_IF_RUNNING; \ + wireless_send_event(dev, \ + IWEVCUSTOM, &w, NULL); \ + } while (0) +#define _netif_carrier_off(dev) \ + do { \ + union iwreq_data w; \ + netif_carrier_off(dev); \ + memset(&w, 0, sizeof(w)); \ + w.data.flags = IEEE80211_EV_IF_NOT_RUNNING; \ + wireless_send_event(dev, \ + IWEVCUSTOM, &w, NULL); \ + } while (0) + +void +atd_event_handler(struct net_device *dev, unsigned int cmd, + union iwreq_data *wreq, char *extra); + +#define __osif_deliver_data(_osif, _skb) \ +{\ + struct net_device *dev = ((osif_dev*)(_osif))->netdev;\ + _skb->dev = dev;\ + atd_rx_from_wlan(_skb);\ +} + +#undef wireless_send_event + +#define wireless_send_event atd_event_handler + +#else + +#define __osif_deliver_data(_osif, _skb) osif_deliver_data(_osif, _skb) +#define _copy_to_user copy_to_user +#define _copy_from_user copy_from_user +#define _netif_carrier_on netif_carrier_on +#define _netif_carrier_off netif_carrier_off + +#endif + +#ifndef OS_EXPORT_SYMBOL +#define OS_EXPORT_SYMBOL(_sym) EXPORT_SYMBOL(_sym) +#endif + +#ifndef OS_WMB +#define OS_WMB() wmb() +#endif + +#endif /* end of _ATH_LINUX_OSDEP_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep_adf.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep_adf.h new file mode 100644 index 0000000000000..8739f875af838 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/osdep_adf.h @@ -0,0 +1,1245 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _ATH_LINUX_OSDEP_ADF_H +#define _ATH_LINUX_OSDEP_ADF_H + +#include "wlan_opts.h" +#include +#include +#include +#include +#include +#include +#include + + #include + #include + #include +#if defined(HIF_USB) +#include +#else + #include +#endif + #include + #include + #include + #include + #include + + + #include + #include + #include + + +#include +#include + +#include + +#include "if_upperproto.h" +#include "ah_osdep.h" + +#ifdef AR9100 +#include +#endif /* AR9100 */ + +#define INLINE __adf_os_inline + +/* UNREFERENCED_PARAMETER - provide a dummy reference */ +#define UNREFERENCED_PARAMETER(an) ((void) (an)) + +#if ATH_DEBUG +#ifndef ASSERT +#define ASSERT(expr) adf_os_assert(expr) +#endif +#else +#define ASSERT(expr) +#endif /* ATH_DEBUG */ + +#define OS_LOG_DBGPRINT(_xfmt, ...) + +#ifdef AR9100 +/* + * Howl needs DDR FIFO flush before any desc/dma data can be read. + */ +#define ATH_FLUSH_FIFO ar9100_flush_wmac +#else +#define ATH_FLUSH_FIFO() +#endif + +#define KASSERT(exp, msg) do { \ + if (unlikely(!(exp))) { \ + printk msg; \ + BUG(); \ + } \ +} while (0) + +/* + * Map Linux spin locks to OS independent names + */ +#ifdef ANDROID +static inline void spin_lock_dpc(spinlock_t *lock) +{ + adf_os_spin_lock_bh((adf_os_spinlock_t *)lock); +} +static inline void spin_unlock_dpc(spinlock_t *lock) +{ + adf_os_spin_unlock_bh((adf_os_spinlock_t *)lock); +} +#else +#define spin_lock_dpc(a) adf_os_spin_lock_bh(a) +#define spin_unlock_dpc(a) adf_os_spin_unlock_bh(a) +#endif + +#define spin_lock_destroy(a) + +#define os_tasklet_lock(a, b) adf_os_spin_lock_irq(a, b) +#define os_tasklet_unlock(a, b) adf_os_spin_unlock_irq(a, b) + +/* +** Need to define byte order based on the CPU configuration. +*/ +#ifndef _LITTLE_ENDIAN +#define _LITTLE_ENDIAN 1234 +#endif +#ifndef _BIG_ENDIAN +#define _BIG_ENDIAN 4321 +#endif +#ifdef __BIG_ENDIAN + #define _BYTE_ORDER _BIG_ENDIAN +#else + #define _BYTE_ORDER _LITTLE_ENDIAN +#endif + +/* + * Work Queue related macros + */ + +#define ATH_CREATE_WQUEUE(name) adf_os_create_workqueue(name) +#define ATH_CREATE_WORK(a,b,c) adf_os_create_work(0, a, b, c) +#define ATH_CREATE_DELAYED_WORK(a,b,c) adf_os_create_delayed_work(0, a, b, c) +#define ATH_QUEUE_WORK(a,b) adf_os_queue_work(0, a, b) +#define ATH_QUEUE_DELAYED_WORK(a,b,c) adf_os_queue_delayed_work(0, a, b, c) +#define ATH_FLUSH_WQUEUE(a) adf_os_flush_workqueue(0, a) +#define ATH_DESTROY_WQUEUE(a) adf_os_destroy_workqueue(0, a) + +/* + * Deduce if tasklets are available. If not then + * fall back to using the immediate work queue. + */ +#define tq_struct adf_os_bh_t +#define ATH_INIT_TQUEUE(a,b,c) adf_os_create_bh(0, a, b, c) +#define ATH_SCHEDULE_TQUEUE(a,b) adf_os_sched_bh(0, a) +typedef unsigned long TQUEUE_ARG; +#define mark_bh(a) + +#define ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \ + f(ctl_table *ctl, int write, void *buffer, \ + size_t *lenp, loff_t *ppos) +#define ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \ + proc_dointvec(ctl, write, buffer, lenp, ppos) +#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \ + proc_dostring(ctl, write, filp, buffer, lenp, ppos) + +/* + * Byte Order stuff + */ +#define le16toh(_x) le16_to_cpu(_x) +#define htole16(_x) cpu_to_le16(_x) +#define htobe16(_x) cpu_to_be16(_x) +#define le32toh(_x) le32_to_cpu(_x) +#define htole32(_x) cpu_to_le32(_x) +#define be16toh(_x) be16_to_cpu(_x) +#define be32toh(_x) be32_to_cpu(_x) +#define htobe32(_x) cpu_to_be32(_x) + +#define EOK (0) + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define IP_PRI_SHIFT 5 + +#ifndef IPV6_VERSION_MASK +#define IPV6_VERSION_MASK 0xF0000000 +#endif +#ifndef IPV6_PRIORITY_MASK +#define IPV6_PRIORITY_MASK 0x0FF00000 +#endif +#ifndef IPV6_FLOWLABEL_MASK +#define IPV6_FLOWLABEL_MASK 0x000FFFFF +#endif +#ifndef IPV6_VERSION_SHIFT +#define IPV6_VERSION_SHIFT 28 +#endif +#ifndef IPV6_PRIORITY_SHIFT +#define IPV6_PRIORITY_SHIFT 20 +#endif +#ifndef IPV6_FLOWLABEL_SHIFT +#define IPV6_FLOWLABEL_SHIFT 0 +#endif + +#ifndef ARPHRD_IEEE80211 +#define ARPHRD_IEEE80211 801 /* IEEE 802.11. */ +#endif + +#define MAX_TX_RX_PACKET_SIZE 2500 + +static INLINE const char * +ether_sprintf(const uint8_t mac[6]) +{ + static char buf[32]; + + __adf_os_snprint(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return buf; +} + +typedef unsigned int rwlock_state_t __attribute__((unused)); + +#define OS_ATOMIC_CMPXCHG(_Counter, _cmp, _xchg) cmpxchg((int32_t*)(_Counter), _cmp, _xchg) + +/* + * Normal Delay functions. Time specified in microseconds. + */ +#define OS_DELAY(_us) adf_os_udelay(_us) + +#define OS_SLEEP(_us) schedule_timeout_uninterruptible(usecs_to_jiffies(_us)) + +#define OS_MEMCPY(_dst, _src, _len) adf_os_mem_copy(_dst, _src, _len) +#define OS_MEMMOVE(_dst, _src, _len) adf_os_mem_move(_dst, _src, _len) +#define OS_MEMZERO(_buf, _len) adf_os_mem_zero(_buf, _len) +#define OS_MEMSET(_buf, _ch, _len) adf_os_mem_set(_buf, _ch, _len) +#define OS_MEMCMP(_mem1, _mem2, _len) adf_os_mem_cmp(_mem1, _mem2, _len) + +#define OS_SET_WDTIMEOUT(__sc, __timeo) \ +{\ + ((__sc)->sc_osdev->netdev)->watchdog_timeo = (__timeo);\ +} + +#define OS_CLR_NETDEV_FLAG(__sc, __flag)\ +{\ + ((__sc)->sc_osdev->netdev)->flags &= ~(__flag);\ +} +#define OS_NETIF_WAKE_QUEUE(__sc)\ +{\ + netif_wake_queue(((__sc)->sc_osdev->netdev));\ +} +#define OS_NETIF_STOP_QUEUE(__sc)\ +{\ + netif_stop_queue(((__sc)->sc_osdev->netdev));\ +} +#define OS_NETDEV_UPDATE_TRANS(__sc)\ +{\ + ((__sc)->sc_osdev->netdev)->trans_start = jiffies;\ +} + +/* + * Locking interface for node + */ +#ifdef ATH_USB +typedef rwlock_t usb_readwrite_lock_t; +#endif + +#define OS_RWLOCK_INIT(_rwl) rwlock_init(_rwl) +#define OS_RWLOCK_DESTROY(_nt) + +#ifdef CONFIG_SMP +/* Undo the one provided by the kernel to debug spin locks */ +#undef spin_lock +#undef spin_unlock +#undef spin_trylock + +#define spin_lock(x) \ +do { \ + spin_lock_bh(x);\ +} while (0) + +#define spin_unlock(x) \ +do { \ +if (!spin_is_locked(x)) { \ +WARN_ON(1); \ +printk(KERN_EMERG " %s:%d unlock addr=%p, %s \n", __func__, __LINE__, x, \ +!spin_is_locked(x)? "Not locked":""); \ +} \ +spin_unlock_bh(x);\ +} while (0) + +#define spin_trylock(x) spin_trylock_bh(x) + +#define OS_SUPPORT_ASYNC_Q 1 /* support for handling asyn function calls */ + +#endif // ifdef CONFIG_SMP + +#define OS_RWLOCK_READ_LOCK(rwl, lock_state) do {\ + if (irqs_disabled() || in_irq()) {\ + read_lock(rwl);\ + } else {\ + read_lock_bh(rwl);\ + }\ +} while (0) + +#define OS_RWLOCK_WRITE_LOCK(rwl, lock_state) do { \ + if (irqs_disabled() || in_irq()) {\ + write_lock(rwl);\ + } else {\ + write_lock_bh(rwl);\ + }\ +} while(0) + +#define OS_RWLOCK_READ_UNLOCK(rwl, lock_state) do {\ + if (irqs_disabled() || in_irq()) {\ + read_unlock(rwl);\ + } else {\ + read_unlock_bh(rwl);\ + }\ +} while (0) + +#define OS_RWLOCK_WRITE_UNLOCK(rwl, lock_state) do {\ + if (irqs_disabled() || in_irq()) {\ + write_unlock(rwl);\ + } else {\ + write_unlock_bh(rwl);\ + }\ +} while (0) + +#define OS_RWLOCK_READ_LOCK_BH(rwl, lock_state) do { \ + read_lock_bh(rwl); \ +} while (0) + +#define OS_RWLOCK_WRITE_LOCK_BH(rwl, lock_state) do { \ + write_lock_bh(rwl); \ +} while (0) + +#define OS_RWLOCK_READ_UNLOCK_BH(rwl, lock_state) do { \ + read_unlock_bh(rwl); \ +} while (0) + +#define OS_RWLOCK_WRITE_UNLOCK_BH(rwl, lock_state) do { \ + write_unlock_bh(rwl); \ +} while (0) + +/* Irqsave/restore version */ +#define OS_RWLOCK_READ_LOCK_IRQSAVE(rwl, lock_state, flags) do { \ + read_lock_irqsave(rwl, flags); \ +} while (0) + +#define OS_RWLOCK_WRITE_LOCK_IRQSAVE(rwl, lock_state, flags) do { \ + write_lock_irqsave(rwl, flags); \ +} while (0) + +#define OS_RWLOCK_READ_UNLOCK_IRQRESTORE(rwl, lock_state, flags) do { \ + read_unlock_irqrestore(rwl, flags); \ +} while (0) + +#define OS_RWLOCK_WRITE_UNLOCK_IRQRESTORE(rwl, lock_state, flags) do { \ + write_unlock_irqrestore(rwl, flags); \ +} while (0) + + +#ifndef OS_SUPPORT_ASYNC_Q +#define OS_SUPPORT_ASYNC_Q 0 +#endif + +/* Calculate the modulo with the following restrictions: + lowest 10 bits of div is zero. + div is at most 20 bits. + +Theory for the math. + Suppose x = A + B + Then x % r = ((A % r) + B) % r + + For our case, we let A be the top 32-bits of x which is non-zero. + Then x = (2^22 * a) + b. +*/ +static INLINE u_int32_t OS_MOD64_TBTT_OFFSET(u_int64_t num64, u_int32_t div) +{ + + u_int32_t remainder_last10bits = (u_int32_t)num64 & 0x003FF; + + /* Remove the low 10 bits. */ + div = div >> 10; + num64 = num64 >> 10; + + { + /* Get the mod of the top 32 bits */ + u_int32_t num_hi = (u_int32_t)(num64 >> 22); +#define BITS_22_MASK 0x003FFFFF +#define BITS_10_MASK 0x000003FF + u_int32_t num_lo = (u_int32_t)(num64) & BITS_22_MASK; + + u_int32_t remainder_hi = num_hi % div; + u_int32_t remainder_lo = num_lo; + + u_int32_t remainder32 = (remainder_hi << 22) + remainder_lo; + + remainder32 = remainder32 % div; + /* Put back the last 10 bits */ + remainder32 = (remainder32 << 10) + remainder_last10bits; + + return(remainder32); + } +} + +/* + * System time interface + */ + +typedef adf_os_time_t systime_t; +typedef adf_os_time_t systick_t; + +static INLINE adf_os_time_t +OS_GET_TIMESTAMP(void) +{ + return adf_os_ticks(); /* Fix double conversion from jiffies to ms */ +} + +static INLINE adf_os_time_t +OS_GET_TICKS(void) +{ + return adf_os_ticks(); +} + +#define CONVERT_SYSTEM_TIME_TO_MS(_t) adf_os_ticks_to_msecs(_t) +#define CONVERT_SYSTEM_TIME_TO_SEC(_t) (adf_os_ticks_to_msecs(_t) / 1000) +#define CONVERT_SEC_TO_SYSTEM_TIME(_t) ((_t) * HZ) +#define CONVERT_MS_TO_SYSTEM_TIME(_t) ((_t) * HZ/1000) + +struct _NIC_DEV; + +typedef struct _NIC_DEV * osdev_t; + + +typedef struct timer_list os_timer_t; +typedef void (*timer_func)(void *); + +typedef struct _os_mesg_t { + STAILQ_ENTRY(_os_mesg_t) mesg_next; + u_int16_t mesg_type; + u_int16_t mesg_len; + /* followed by mesg_len bytes */ +} os_mesg_t; + +#define OS_ASYNC_Q_MAX_MESGS 4 + +#define OS_SCHEDULE_ROUTING_MESG_TYPE 1 + +typedef void* os_task_handle_t; +typedef void (*os_tasklet_routine_t)( + void *context, + os_task_handle_t task_handle + ); + +typedef struct { + os_tasklet_routine_t routine; + atomic_t queued; + void *data; + spinlock_t lock; +} os_task_t; + +typedef struct _os_schedule_routing_mesg { + os_tasklet_routine_t routine; + void* context; +} os_schedule_routing_mesg ; + +typedef union _os_async_q_mesg { + os_schedule_routing_mesg s_mesg; +} os_async_q_mesg; + + +typedef void (*os_mesg_handler_t)( + void *ctx, + u_int16_t mesg_type, + u_int16_t mesg_len, + void *mesg + ); + +typedef struct { + osdev_t dev_handle; + int32_t num_queued; + int32_t mesg_len; + u_int8_t *mesg_queue_buf; + STAILQ_HEAD(, _os_mesg_t) mesg_head; /* queued mesg buffers */ + STAILQ_HEAD(, _os_mesg_t) mesg_free_head; /* free mesg buffers */ + spinlock_t lock; + spinlock_t ev_handler_lock; +#ifdef USE_SOFTINTR + void *_task; +#else + os_timer_t _timer; +#endif + os_mesg_handler_t handler; + void *ctx; + u_int8_t is_synchronous:1; +} os_mesg_queue_t; + +struct ath_freebuf_bin { + TAILQ_ENTRY(ath_freebuf_bin) buf_list; + unsigned char *head; + unsigned char *end; + struct sk_buff *skb; + int lifetime; +}; + +typedef TAILQ_HEAD(ath_freebufhead_s, ath_freebuf_bin) ath_freebufhead; + +struct rxbuf_recycle_ops { + void (*osdev_wbuf_collect)(void *, void *); + void * (*osdev_wbuf_recycle)(void *); +}; +/* + * Definition of OS-dependent device structure. + * It'll be opaque to the actual ATH layer. + */ +struct _NIC_DEV { + void *bdev; /* bus device handle */ + struct net_device *netdev; /* net device handle (wifi%d) */ + adf_os_bh_t intr_tq; /* tasklet */ + struct net_device_stats devstats; /* net device statisitics */ + HAL_BUS_CONTEXT bc; +#ifdef ATH_PERF_PWR_OFFLOAD + struct device *device; /* generic device */ + wait_queue_head_t event_queue; +#endif /* PERF_PWR_OFFLOAD */ +#if OS_SUPPORT_ASYNC_Q + os_mesg_queue_t async_q; /* mesgq to handle async calls */ +#endif +#ifdef ATH_BUS_PM + u_int8_t isDeviceAsleep; +#endif /* ATH_BUS_PM */ +}; + +static INLINE unsigned char * +OS_MALLOC(osdev_t pNicDev, unsigned long ulSizeInBytes, int gfp) +{ + return adf_os_mem_alloc(NULL, ulSizeInBytes); +} +#define OS_FREE(_p) adf_os_mem_free(_p) + +#define OS_MALLOC_WITH_TAG(_ppMem, _size, _tag) do { \ + *(_ppMem) = adf_os_mem_alloc(NULL, _size); \ +} while(0) + +#define OS_FREE_WITH_TAG(_pMem, _size) adf_os_mem_free(_pMem) + +static INLINE void * +OS_ALLOC_VAP(osdev_t osdev, u_int32_t len) +{ + void *netif; + + /* + * In NDIS, we just allocate memory for interface object here. + * For Linux, it may need to allocate and setup a net_device. + */ + netif = adf_os_mem_alloc(NULL, len); + if (netif != NULL) + { + adf_os_mem_zero(netif, len); + } + + return netif; +} + +static INLINE void +OS_FREE_VAP(void *netif) +{ + /* Just free the structure in NDIS. + * In Linux, it should call unregister_netdevice + * to free the memory */ + adf_os_mem_free(netif); +} + +#define bus_type_error 0 + +#define BUS_DMA_FROMDEVICE 0 +#define BUS_DMA_TODEVICE 1 + +#if bus_type_error +#error "No bus type is specified" +#endif + +typedef dma_addr_t * dma_context_t; + +#define OS_DMA_MEM_CONTEXT(context) \ + dma_addr_t context; + +#define OS_GET_DMA_MEM_CONTEXT(var, field) \ + &(var->field) + +#define OS_COPY_DMA_MEM_CONTEXT(dst, src) \ + *dst = *src + +#define OS_ZERO_DMA_MEM_CONTEXT(context) \ + *context = 0 + +#ifdef ATH_SUPPORT_SHARED_IRQ +#define ATH_LOCK_IRQ(_osdev) disable_irq(_osdev->netdev->irq) +#define ATH_UNLOCK_IRQ(_osdev) enable_irq(_osdev->netdev->irq) +#else +#define ATH_LOCK_IRQ(_osdev) +#define ATH_UNLOCK_IRQ(_osdev) +#endif + +#ifdef ATH_SUPPORT_HTC +#define OS_EXEC_INTSAFE(_osdev, _fn, _arg) do { \ + _fn(_arg); \ +} while (0) +#else /* #ifdef ATH_SUPPORT_HTC */ +#define OS_EXEC_INTSAFE(_osdev, _fn, _arg) do { \ + unsigned long flags; \ + ATH_LOCK_IRQ(_osdev); \ + local_irq_save(flags); \ + _fn(_arg); \ + local_irq_restore(flags); \ + ATH_UNLOCK_IRQ(_osdev); \ +} while (0) +#endif /* #ifdef ATH_SUPPORT_HTC */ + +/* + * Timer Interfaces. Use these macros to declare timer + * and retrieve timer argument. This is mainly for resolving + * different argument types for timer function in different OS. + */ + +#define OS_DECLARE_TIMER(_fn) void _fn(void *) + +#define OS_TIMER_FUNC(_fn) \ + void _fn(void *timer_arg) + +#define OS_GET_TIMER_ARG(_arg, _type) \ + (_arg) = (_type)(timer_arg) + + +#define OS_INIT_TIMER(_osdev, _timer, _fn, _ctx, type) adf_os_timer_init(_osdev, _timer, _fn, _ctx, type) + +#define OS_SET_TIMER(_timer, _ms) adf_os_timer_mod(_timer, _ms) + +#define OS_CANCEL_TIMER(_timer) adf_os_timer_cancel(_timer) + +#define OS_FREE_TIMER(_timer) adf_os_timer_cancel(_timer) + +static INLINE void +OS_GET_RANDOM_BYTES(void *p, u_int16_t n) +{ + get_random_bytes(p, n); +} + +typedef enum _mesgq_priority_t { + MESGQ_PRIORITY_LOW, + MESGQ_PRIORITY_NORMAL, + MESGQ_PRIORITY_HIGH +} mesgq_priority_t; + +typedef enum _mesgq_event_delivery_type { + MESGQ_ASYNCHRONOUS_EVENT_DELIVERY, + MESGQ_SYNCHRONOUS_EVENT_DELIVERY, +} mesgq_event_delivery_type; + + + + +/* + * OS_MESGQ_* API to deliver messages(events) asynchronosly. + * messages are queued up into a queue and are delivered in the context of + * timer thread. this will avoid reentrency issues across different + * module boundaries. + */ + +static INLINE void +os_mesgq_handler(void *timer_arg) +{ + os_mesg_queue_t *queue = (os_mesg_queue_t*)timer_arg; + os_mesg_t *mesg = NULL; + void *msg; + + /* + * Request access to message queue to retrieve message for processing + */ + spin_lock(&(queue->lock)); + + mesg = STAILQ_FIRST(&queue->mesg_head); + while(mesg) { + STAILQ_REMOVE_HEAD(&queue->mesg_head, mesg_next); + if (mesg->mesg_len) { + msg = (void *) (mesg+1); + } else { + msg = NULL; + } + /* + * Release access to message queue before processing message + */ + spin_unlock(&(queue->lock)); + + /* + * Ensure just one message can be processes at a time. + */ + spin_lock(&(queue->ev_handler_lock)); + queue->handler(queue->ctx,mesg->mesg_type,mesg->mesg_len, msg); + spin_unlock(&(queue->ev_handler_lock)); + + /* + * Request access to message queue to retrieve next message + */ + spin_lock(&(queue->lock)); + queue->num_queued--; + STAILQ_INSERT_TAIL(&queue->mesg_free_head,mesg, mesg_next); + mesg = STAILQ_FIRST(&queue->mesg_head); + } + + /* + * Release message queue + */ + spin_unlock(&(queue->lock)); +} + +/* + * initialize message queue. + * devhandle : os dev handle. + * queue : message queue. + * mesg_len : maximum length of message. + * max_queued : maximum number of messages that can be queued at any time. + * msg_handler : handler function which will be called + * asynchronously to deliver each message. + */ +static INLINE int OS_MESGQ_INIT(osdev_t devhandle, os_mesg_queue_t *queue, + u_int32_t mesg_len, u_int32_t max_queued, + os_mesg_handler_t msg_handler, void *context, + mesgq_priority_t priority, + mesgq_event_delivery_type mq_type) +{ + int i,len; + os_mesg_t *mesg; + + len = (mesg_len + sizeof(struct _os_mesg_t)); + queue->mesg_queue_buf = adf_os_mem_alloc(NULL, (adf_os_size_t) len*max_queued); + if (!queue->mesg_queue_buf) + return -ENOMEM; + queue->dev_handle = devhandle; + STAILQ_INIT(&queue->mesg_head); + STAILQ_INIT(&queue->mesg_free_head); + spin_lock_init(&(queue->lock)); + spin_lock_init(&(queue->ev_handler_lock)); + mesg = (os_mesg_t *)queue->mesg_queue_buf; + for (i=0;imesg_free_head,mesg,mesg_next); + mesg = (os_mesg_t *) ((u_int8_t *) mesg + len); + } + queue->mesg_len = mesg_len; + queue->ctx = context; + queue->handler = msg_handler; + queue->num_queued = 0; + if (mq_type == MESGQ_ASYNCHRONOUS_EVENT_DELIVERY) { + queue->is_synchronous=0; + } else { + queue->is_synchronous=1; + } +#ifdef USE_SOFTINTR + queue->_task = softintr_establish(IPL_SOFTNET,os_mesgq_handler,(void *)queue); +#else + OS_INIT_TIMER(devhandle,&queue->_timer, os_mesgq_handler, queue, + ADF_DEFERRABLE_TIMER); +#endif + + return 0; +} + +/* + * send a message. + * queue : message queue. + * msg : message (opaque) . the size of the message + * is equal to the mesg_length passed to the OS_MESG_INIT + * + */ +static INLINE int OS_MESGQ_SEND(os_mesg_queue_t *queue,u_int16_t type, u_int16_t len, void *msg) +{ + os_mesg_t *mesg; + + spin_lock(&(queue->lock)); + if (queue->is_synchronous ) { + queue->handler(queue->ctx,type,len, msg); + } else { + mesg = STAILQ_FIRST(&queue->mesg_free_head); + KASSERT(len <= queue->mesg_len, ("len <= queue->mesg_len")); + if (mesg) { + STAILQ_REMOVE_HEAD(&queue->mesg_free_head, mesg_next); + mesg->mesg_type = type; + mesg->mesg_len = len; + if (len) { + OS_MEMCPY((u_int8_t *)(mesg+1),msg,len); + } + STAILQ_INSERT_TAIL(&queue->mesg_head, mesg, mesg_next); + queue->num_queued++; + } else { + spin_unlock(&(queue->lock)); + printk("No more message queue buffers !!! \n"); + return -ENOMEM; + } + if (queue->num_queued == 1) { + /* schedule a task (timer) to handle the messages */ +#ifdef USE_SOFTINTR + softintr_schedule(queue->_task); +#else + OS_SET_TIMER(&queue->_timer,0); +#endif + } + } + spin_unlock(&(queue->lock)); + return 0; +} + +/* + * this is only for single threaded operating systems. + * assert for now. + */ +static INLINE int OS_MESGQ_SEND_SYNC(os_mesg_queue_t *queue,u_int16_t type, u_int16_t len, void *msg, bool flush) +{ + KASSERT(0,(" mesg queue sync send is not supported by linux")); + return 0; +} + +static INLINE int OS_MESGQ_CAN_SEND_SYNC(void) +{ + return TRUE; +} + +/* + * drain all the messages. + * queue : message queue. + */ +static INLINE void OS_MESGQ_DRAIN(os_mesg_queue_t *queue, os_mesg_handler_t msg_handler) +{ + os_mesg_t *mesg = NULL; + void *msg; + + spin_lock(&(queue->lock)); +#ifndef USE_SOFTINTR + OS_CANCEL_TIMER(&queue->_timer); +#endif + mesg = STAILQ_FIRST(&queue->mesg_head); + while(mesg) { + STAILQ_REMOVE_HEAD(&queue->mesg_head, mesg_next); + queue->num_queued--; + if (msg_handler != NULL) { + if (mesg->mesg_len) { + msg = (void *) (mesg+1); + } else { + msg = NULL; + } + msg_handler(queue->ctx, mesg->mesg_type, mesg->mesg_len, msg); + } + STAILQ_INSERT_TAIL(&queue->mesg_free_head,mesg, mesg_next); + mesg = STAILQ_FIRST(&queue->mesg_head); + }; + STAILQ_INIT(&queue->mesg_head); + spin_unlock(&(queue->lock)); +} + + +/* + * destroy the message queue. + * queue : message queue. + * reclaim all the resorces. + */ + +static INLINE void OS_MESGQ_DESTROY(os_mesg_queue_t *queue) +{ + spin_lock(&(queue->lock)); +#ifdef USE_SOFTINTR + softintr_disestablish(queue->_task); +#else + OS_CANCEL_TIMER(&queue->_timer); +#endif + queue->num_queued = 0; + STAILQ_INIT(&queue->mesg_head); + STAILQ_INIT(&queue->mesg_free_head); + adf_os_mem_free(queue->mesg_queue_buf); +#ifndef USE_SOFTINTR + OS_FREE_TIMER(&queue->_timer); +#endif + spin_unlock(&(queue->lock)); + spin_lock_destroy(&(queue->lock)); + spin_lock_destroy(&(queue->ev_handler_lock)); +} + + + +/* + * temp WAR for windows hang (dead lock). It can be removed when VAP SM is re-written (bug 65137). + */ +static INLINE int +OS_SCHEDULE_ROUTING(osdev_t pNicDev, + os_tasklet_routine_t routine, + void* context) +{ +#if OS_SUPPORT_ASYNC_Q + os_schedule_routing_mesg s_mesg ; + s_mesg.routine = routine; + s_mesg.context = context; + OS_MESGQ_SEND(&pNicDev->async_q,OS_SCHEDULE_ROUTING_MESG_TYPE, sizeof(os_schedule_routing_mesg), &s_mesg); + +#else + routine(context, NULL); +#endif + return 0; +} + +static INLINE void +OS_FREE_ROUTING(void* workItemHandle) +{ +} + +/* +** These are required for network manager support +*/ + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(ndev, pdev) +#endif + +#ifdef to_net_dev +#define ATH_GET_NETDEV_DEV(ndev) ((ndev)->dev.parent) +#else +#define ATH_GET_NETDEV_DEV(ndev) ((ndev)->class_dev.dev) +#endif + + + +/* + * Opaque S/G List Entry + */ +typedef struct scatterlist sg_t; + +#include "hwdef.h" + +#ifndef ARRAY_LENGTH +#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define MIN(a, b) adf_os_min(a, b) +#define MAX(a, b) adf_os_max(a, b) + +/* + * PCI configuration space access + */ +#ifdef ATH_PCI + +static INLINE u_int32_t +OS_PCI_READ_CONFIG(osdev_t osdev, u_int32_t offset, void *p, u_int32_t bytes) +{ + struct pci_dev *pdev = (struct pci_dev *)osdev->bdev; + + switch (bytes) { + case 1: + pci_read_config_byte(pdev, offset, p); + break; + case 2: + pci_read_config_word(pdev, offset, p); + break; + case 4: + pci_read_config_dword(pdev, offset, p); + break; + } + return bytes; +} + +static INLINE void +OS_PCI_WRITE_CONFIG(osdev_t osdev, u_int32_t offset, void *p, u_int32_t bytes) +{ + struct pci_dev *pdev = (struct pci_dev *)osdev->bdev; + + switch (bytes) { + case 1: + pci_write_config_byte(pdev, offset, *(u_int8_t *)p); + break; + case 2: + pci_write_config_word(pdev, offset, *(u_int16_t *)p); + break; + case 4: + pci_write_config_dword(pdev, offset, *(u_int32_t *)p); + break; + } +} + +#else + +static INLINE u_int32_t +OS_PCI_READ_CONFIG(osdev_t osdev, u_int32_t offset, void *p, u_int32_t bytes) +{ + OS_MEMSET(p, 0xff, bytes); + return 0; +} + +#define OS_PCI_WRITE_CONFIG(_osdev, _offset, _p, _bytes) + +#endif + +void *OS_ALLOC_VAP(osdev_t dev, u_int32_t len); +void OS_FREE_VAP(void *netif); + +// ALLOC_DMA_MAP_CONTEXT_AREA is a NULL macro and is implemented only for BSD. +#define ALLOC_DMA_MAP_CONTEXT_AREA(os_handle, p_memctx) +#define FREE_DMA_CONTEXT_POOL(os_handle, name) +#define ALLOC_DMA_CONTEXT_POOL(os_handle, name, numdesc) + +#define ATH_QOSNULL_TXDESC 64 +#define ATH_FRAG_PER_MSDU 1 +#ifndef ATH_TXBUF +#define ATH_TXBUF 512/ATH_FRAG_PER_MSDU +#endif + +/* + * minimum h/w qdepth to be sustained to maximize aggregation + */ +#define ATH_AGGR_MIN_QDEPTH 2 +#define OS_MAX_RXBUF_SIZE(_statuslen) (IEEE80211_MAX_MPDU_LEN + _statuslen) + +#define ATH_GET_RX_CONTEXT_BUF(_wbuf) \ + (ATH_RX_CONTEXT(_wbuf)->ctx_rxbuf) +#define ATH_SET_RX_CONTEXT_BUF(_wbuf, _bf) \ + (ATH_GET_RX_CONTEXT_BUF(_wbuf) = _bf) + +// This macro is used to avoid another wrapper around ath_rxbuf_alloc. +// For Mac OS, we need to OR in ATH_RXBUF_ALLOC_DONTWAIT with length. +// Not needed for other OS'. +#define ATH_ALLOCATE_RXBUFFER(_sc, _len) ath_rxbuf_alloc(_sc, _len) + +#ifndef OS_EXPORT_SYMBOL +#define OS_EXPORT_SYMBOL(_sym) EXPORT_SYMBOL(_sym) +#endif + +struct ieee80211_node; +struct ieee80211_cb { + u_int8_t vlan[8]; /* reserve for vlan tag info */ + struct ieee80211_node *ni; + u_int32_t flags; +#define N_LINK0 0x01 /* frame needs WEP encryption */ +#define N_FF 0x02 /* fast frame */ +#define N_PWR_SAV 0x04 /* bypass power save handling */ +#define N_UAPSD 0x08 /* frame flagged for u-apsd handling */ +#define N_EAPOL 0x10 /* frame flagged for EAPOL handling */ +#define N_AMSDU 0x20 /* frame flagged for AMSDU handling */ +#define N_NULL_PWR_SAV 0x40 /* null data with power save bit on */ +#define N_PROBING 0x80 /* frame flagged as a probing one */ +#define N_ERROR 0x100 /* frame flagged as a error one */ +#define N_MOREDATA 0x200 /* more data flag */ +#define N_SMPSACTM 0x400 /* This frame is SM power save Action Mgmt frame */ +#define N_QOS 0x800 /* This is a QOS frame*/ +#define N_ENCAP_DONE 0x1000 /* This frame is marked as fast-path pkts, some encapsulation work has been done by h/w */ +#define N_CLONED 0x2000 /* frame is cloned in rx path */ +#define N_ANT_TRAIN 0x8000 /* frame is smart antenna training packet */ +#define N_ANT_TRAIN_LAST 0x20000 /* Last smart antenna training packet */ +#ifdef ATH_SUPPORT_WAPI +#define N_WAI 0x40000 /* frame flagged for WAPI handling */ +#endif +#define N_FMSS 0x100000 /* frame needs FMS handling */ + + u_int8_t u_tid; /* user priority from vlan/ip tos */ + u_int8_t exemptiontype; /* exemption type of this frame (0,1,2)*/ + u_int8_t type; /* type of this frame */ + + union { + void *context; /* pointer to context area */ + }_u; + +#if defined(ATH_SUPPORT_P2P) || defined(ATH_SUPPORT_TDLS) + void *complete_handler; /* complete handler */ + void *complete_handler_arg; /* complete handler arg */ +#endif +}; +//#endif /* CONVERGED_SW */ + +#ifndef ATH_SUPPORT_HTC +/* + * For packet capture, define the same physical layer packet header + * structure as used in the wlan-ng driver + */ +typedef struct { + u_int32_t did; + u_int16_t status; + u_int16_t len; + u_int32_t data; +} p80211item_uint32_t; + +typedef struct { + u_int32_t msgcode; + u_int32_t msglen; +#define WLAN_DEVNAMELEN_MAX 16 + u_int8_t devname[WLAN_DEVNAMELEN_MAX]; + p80211item_uint32_t hosttime; + p80211item_uint32_t mactime; + p80211item_uint32_t channel; + p80211item_uint32_t rssi; + p80211item_uint32_t sq; + p80211item_uint32_t signal; + p80211item_uint32_t noise; + p80211item_uint32_t rate; + p80211item_uint32_t istx; + p80211item_uint32_t frmlen; +} wlan_ng_prism2_header; + +#endif + +#define N_FLAG_SET(_nbf, _flag) \ + (((struct ieee80211_cb *)(_nbf)->cb)->flags |= (_flag)) +#define N_FLAG_CLR(_nbf, _flag) \ + (((struct ieee80211_cb *)(_nbf)->cb)->flags &= ~(_flag)) +#define N_FLAG_GET(_nbf, _flag) \ + (((struct ieee80211_cb *)(_nbf)->cb)->flags & (_flag)) +#define N_FLAG_IS(_nbf, _flag) \ + ((((struct ieee80211_cb *)(_nbf)->cb)->flags & (_flag)) == (_flag)) +#define N_FLAG_KEEP_ONLY(_nbf, _flag) \ + (((struct ieee80211_cb *)(_nbf)->cb)->flags &= (_flag)) + +#define N_PWR_SAV_SET(nbf) N_FLAG_SET((nbf), N_PWR_SAV) +#define N_PWR_SAV_CLR(nbf) N_FLAG_CLR((nbf), N_PWR_SAV) +#define N_PWR_SAV_GET(nbf) N_FLAG_GET((nbf), N_PWR_SAV) +#define N_PWR_SAV_IS(nbf) N_FLAG_IS((nbf), N_PWR_SAV) + +#define N_NULL_PWR_SAV_SET(nbf) N_FLAG_SET((nbf), N_NULL_PWR_SAV) +#define N_NULL_PWR_SAV_CLR(nbf) N_FLAG_CLR((nbf), N_NULL_PWR_SAV) +#define N_NULL_PWR_SAV_GET(nbf) N_FLAG_GET((nbf), N_NULL_PWR_SAV) +#define N_NULL_PWR_SAV_IS(nbf) N_FLAG_IS((nbf), N_NULL_PWR_SAV) + +#define N_PROBING_SET(nbf) N_FLAG_SET((nbf), N_PROBING) +#define N_PROBING_CLR(nbf) N_FLAG_CLR((nbf), N_PROBING) +#define N_PROBING_GET(nbf) N_FLAG_GET((nbf), N_PROBING) +#define N_PROBING_IS(nbf) N_FLAG_IS((nbf), N_PROBING) + +#define N_CLONED_SET(nbf) N_FLAG_SET((nbf), N_CLONED) +#define N_CLONED_CLR(nbf) N_FLAG_CLR((nbf), N_CLONED) +#define N_CLONED_GET(nbf) N_FLAG_GET((nbf), N_CLONED) +#define N_CLONED_IS(nbf) N_FLAG_IS((nbf), N_CLONED) + +#define N_MOREDATA_SET(nbf) N_FLAG_SET((nbf), N_MOREDATA) +#define N_MOREDATA_CLR(nbf) N_FLAG_CLR((nbf), N_MOREDATA) +#define N_MOREDATA_GET(nbf) N_FLAG_GET((nbf), N_MOREDATA) +#define N_MOREDATA_IS(nbf) N_FLAG_IS((nbf), N_MOREDATA) + +#define N_SMPSACTM_SET(nbf) N_FLAG_SET((nbf), N_SMPSACTM) +#define N_SMPSACTM_CLR(nbf) N_FLAG_CLR((nbf), N_SMPSACTM) +#define N_SMPSACTM_GET(nbf) N_FLAG_GET((nbf), N_SMPSACTM) +#define N_SMPSACTM_IS(nbf) N_FLAG_IS((nbf), N_SMPSACTM) + +#define N_QOS_SET(nbf) N_FLAG_SET((nbf), N_QOS) +#define N_QOS_CLR(nbf) N_FLAG_CLR((nbf), N_QOS) +#define N_QOS_GET(nbf) N_FLAG_GET((nbf), N_QOS) +#define N_QOS_IS(nbf) N_FLAG_IS((nbf), N_QOS) + +#define N_EAPOL_SET(nbf) N_FLAG_SET((nbf), N_EAPOL) +#define N_EAPOL_IS(nbf) N_FLAG_IS((nbf), N_EAPOL) + +#define N_AMSDU_SET(nbf) N_FLAG_SET((nbf), N_AMSDU) +#define N_AMSDU_IS(nbf) N_FLAG_IS((nbf), N_AMSDU) + +#define N_FF_SET(nbf) N_FLAG_SET((nbf), N_FF) +#define N_FF_IS(nbf) N_FLAG_IS((nbf), N_FF) + +#define N_UAPSD_SET(nbf) N_FLAG_SET((nbf), N_UAPSD) +#define N_UAPSD_CLR(nbf) N_FLAG_CLR((nbf), N_UAPSD) +#define N_UAPSD_IS(nbf) N_FLAG_IS((nbf), N_UAPSD) + +#define N_ENCAP_DONE_IS(nbf) N_FLAG_IS((nbf), N_ENCAP_DONE) +#define N_ENCAP_DONE_SET(nbf) N_FLAG_SET((nbf), N_ENCAP_DONE) +#define N_ENCAP_DONE_CLR(nbf) N_FLAG_CLR((nbf), N_ENCAP_DONE) + +#define N_STATUS_SET(nbf, _status) + +#define N_STATUS_GET(nbf) \ + if(N_FLAG_IS((nbf), N_ERROR)) \ + return WB_STATUS_TX_ERROR; \ + else \ + return WB_STATUS_OK; + +#define N_CONTEXT_SET(_nbf, _context) \ + (((struct ieee80211_cb *)(_nbf)->cb)->_u.context = (_context)) +#define N_CONTEXT_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->_u.context) + +#define N_TYPE_SET(_nbf, _type) \ + (((struct ieee80211_cb *)(_nbf)->cb)->type = (_type)) +#define N_TYPE_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->type) + +#define N_NODE_SET(_nbf, _ni) \ + (((struct ieee80211_cb *)(_nbf)->cb)->ni = (_ni)) +#define N_NODE_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->ni) + +#define N_COMPLETE_HANDLER_SET(_nbf, _handler) \ + (((struct ieee80211_cb *)(_nbf)->cb)->complete_handler = (_handler)) +#define N_COMPLETE_HANDLER_ARG_SET(_nbf, _arg) \ + (((struct ieee80211_cb *)(_nbf)->cb)->complete_handler_arg = (_arg)) + +#define N_COMPLETE_HANDLER_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->complete_handler) +#define N_COMPLETE_HANDLER_ARG_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->complete_handler_arg) + +#define N_EXMTYPE_SET(_nbf, _type) \ + (((struct ieee80211_cb *)(_nbf)->cb)->exemptiontype = (_type)) +#define N_EXMTYPE_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->exemptiontype) + +#define N_TID_SET(_nbf, _tid) \ + (((struct ieee80211_cb *)(_nbf)->cb)->u_tid = (_tid)) +#define N_TID_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->u_tid) + +#define N_ANT_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->smart_antenna) +#define N_RATE_INDEX_GET(_nbf) \ + (((struct ieee80211_cb *)(_nbf)->cb)->rateIndex) +#define N_TRAIN_PKT_IS(nbf) N_FLAG_IS((nbf), N_ANT_TRAIN) +#define N_TRAIN_LASTPKT_IS(nbf) N_FLAG_IS((nbf), N_ANT_TRAIN_LAST) + +#define N_ANT_SET(_nbf, _antenna) \ + (((struct ieee80211_cb *)(_nbf)->cb)->smart_antenna = (_antenna)) +#define N_RATE_INDEX_SET(_nbf, _idx) \ + (((struct ieee80211_cb *)(_nbf)->cb)->rateIndex = (_idx)) +#define N_TRAIN_PKT_SET(nbf) N_FLAG_SET((nbf), N_ANT_TRAIN) +#define N_TRAIN_PKT_UNSET(nbf) N_FLAG_CLR((nbf), N_ANT_TRAIN) +#define N_TRAIN_LASTPKT_SET(nbf) N_FLAG_SET((nbf), N_ANT_TRAIN_LAST) + +/* + * nbufs on the power save queue are tagged with an age and + * timed out. We reuse the hardware checksum field in the + * nbuf packet header to store this data. + * XXX use private cb area + */ +#define N_AGE_SET(skb, v) (skb)->csum = (v) +#define N_AGE_GET(skb) (skb)->csum +#define N_AGE_SUB(skb, adj) (skb)->csum -= (adj) + + +#endif /* end of _ATH_LINUX_OSDEP_ADF_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog.h new file mode 100644 index 0000000000000..5619593775fc3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_ +#define _PKTLOG_ +#ifndef REMOVE_PKT_LOG + +/** + * @typedef ol_pktlog_dev_handle + * @brief opaque handle for pktlog device object + */ +struct ol_pktlog_dev_t; +typedef struct ol_pktlog_dev_t* ol_pktlog_dev_handle; +#endif /* #ifndef REMOVE_PKT_LOG */ +#endif /* _PKTLOG_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog_ac_fmt.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog_ac_fmt.h new file mode 100644 index 0000000000000..9f7551c1cb1ac --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/pktlog_ac_fmt.h @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef REMOVE_PKT_LOG +#ifndef _PKTLOG_FMT_H_ +#define _PKTLOG_FMT_H_ + +#define CUR_PKTLOG_VER 10010 /* Packet log version */ +#define PKTLOG_MAGIC_NUM 7735225 + +#ifndef MAX_TX_RATE_TBL +#define MAX_TX_RATE_TBL 72 +#endif + +#ifdef __linux__ +#define PKTLOG_PROC_DIR "ath_pktlog" +#define PKTLOG_PROC_SYSTEM "system" +#define WLANDEV_BASENAME "cld" +#endif + +#ifdef WIN32 +#pragma pack(push, pktlog_fmt, 1) +#define __ATTRIB_PACK +#elif defined(__EFI__) +#define __ATTRIB_PACK +#else +#ifndef __ATTRIB_PACK +#define __ATTRIB_PACK __attribute__ ((packed)) +#endif +#endif +#include +/* + * Each packet log entry consists of the following fixed length header + * followed by variable length log information determined by log_type + */ + +struct ath_pktlog_hdr { + u_int16_t flags; + u_int16_t missed_cnt; + u_int16_t log_type; + u_int16_t size; + u_int32_t timestamp; +}__ATTRIB_PACK; + +#define ATH_PKTLOG_HDR_FLAGS_MASK 0xffff +#define ATH_PKTLOG_HDR_FLAGS_SHIFT 0 +#define ATH_PKTLOG_HDR_FLAGS_OFFSET 0 +#define ATH_PKTLOG_HDR_MISSED_CNT_MASK 0xffff0000 +#define ATH_PKTLOG_HDR_MISSED_CNT_SHIFT 16 +#define ATH_PKTLOG_HDR_MISSED_CNT_OFFSET 0 +#define ATH_PKTLOG_HDR_LOG_TYPE_MASK 0xffff +#define ATH_PKTLOG_HDR_LOG_TYPE_SHIFT 0 +#define ATH_PKTLOG_HDR_LOG_TYPE_OFFSET 1 +#define ATH_PKTLOG_HDR_SIZE_MASK 0xffff0000 +#define ATH_PKTLOG_HDR_SIZE_SHIFT 16 +#define ATH_PKTLOG_HDR_SIZE_OFFSET 1 +#define ATH_PKTLOG_HDR_TIMESTAMP_OFFSET 2 + +enum { + PKTLOG_FLG_FRM_TYPE_LOCAL_S = 0, + PKTLOG_FLG_FRM_TYPE_REMOTE_S, + PKTLOG_FLG_FRM_TYPE_UNKNOWN_S +}; + +/**************************** + * Pktlog flag field details + * packet origin [1:0] + * 00 - Local + * 01 - Remote + * 10 - Unknown/Not applicable + * 11 - Reserved + * reserved [15:2] + * *************************/ + +#define PHFLAGS_PROTO_MASK 0x0000f000 +#define PHFLAGS_PROTO_SFT 12 +#define PHFLAGS_MACVERSION_MASK 0x0fff0000 +#define PHFLAGS_MACVERSION_SFT 16 +/* + * XXX: This need not be part of packetlog header flags - Should be + * moved to plinfo + */ + +#define PHFLAGS_INTERRUPT_CONTEXT 0x80000000 + +/* flags in pktlog header */ +#define PHFLAGS_MISCCNT_MASK 0x000F /* Indicates no. of misc log parameters + (32-bit integers) at the end of a + log entry */ + +#define PHFLAGS_MACREV_MASK 0xff0 /* MAC revision */ +#define PHFLAGS_MACREV_SFT 4 + +/* Types of protocol logging flags */ +//#define PHFLAGS_PROTO_MASK 0xf000 +//#define PHFLAGS_PROTO_SFT 12 +#define PKTLOG_PROTO_NONE 0 +#define PKTLOG_PROTO_UDP 1 +#define PKTLOG_PROTO_TCP 2 + +/* Masks for setting pktlog events filters */ +#define ATH_PKTLOG_TX 0x000000001 +#define ATH_PKTLOG_RX 0x000000002 +#define ATH_PKTLOG_RCFIND 0x000000004 +#define ATH_PKTLOG_RCUPDATE 0x000000008 +#define ATH_PKTLOG_ANI 0x000000010 +#define ATH_PKTLOG_TEXT 0x000000020 +#define ATH_PKTLOG_PHYERR 0x000000040 +#define ATH_PKTLOG_PROMISC 0x000000080 + +/* Masks for setting pktlog info filters */ +#define ATH_PKTLOG_PROTO 0x00000001 /* Decode and log protocol headers */ +#define ATH_PKTLOG_TRIGGER_SACK 0x00000002 /* Triggered stop as seeing TCP SACK packets */ +#define ATH_PKTLOG_TRIGGER_THRUPUT 0x00000004 /* Triggered stop as throughput drops below a threshold */ +#define ATH_PKTLOG_TRIGGER_PER 0x00000008 /* Triggered stop as PER goes above a threshold */ +#define ATH_PKTLOG_TRIGGER_PHYERR 0x00000010 /* Triggered stop as # of phyerrs goes above a threshold */ + +/* Types of packet log events */ +#define PKTLOG_TYPE_TX_CTRL 1 +#define PKTLOG_TYPE_TX_STAT 2 +#define PKTLOG_TYPE_TX_MSDU_ID 3 +#define PKTLOG_TYPE_TX_FRM_HDR 4 +#define PKTLOG_TYPE_RX_STAT 5 +#define PKTLOG_TYPE_RC_FIND 6 +#define PKTLOG_TYPE_RC_UPDATE 7 +#define PKTLOG_TYPE_TX_VIRT_ADDR 8 +#define PKTLOG_TYPE_MAX 9 + +/*#define PKTLOG_TYPE_TXCTL 0 +#define PKTLOG_TYPE_TXSTATUS 1 +#define PKTLOG_TYPE_RX 2 +#define PKTLOG_TYPE_RCFIND 3 +#define PKTLOG_TYPE_RCUPDATE 4 +#define PKTLOG_TYPE_ANI 5 +#define PKTLOG_TYPE_TEXT 6*/ + +#define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */ +#define PKTLOG_MAX_TXSTATUS_WORDS 32 +#define PKTLOG_MAX_PROTO_WORDS 16 +#define PKTLOG_MAX_RXDESC_WORDS 62 + +struct txctl_frm_hdr { + u_int16_t framectrl; /* frame control field from header */ + u_int16_t seqctrl; /* frame control field from header */ + u_int16_t bssid_tail; /* last two octets of bssid */ + u_int16_t sa_tail; /* last two octets of SA */ + u_int16_t da_tail; /* last two octets of DA */ + u_int16_t resvd; +}; + +/* Peregrine 11ac based */ +#define MAX_PKT_INFO_MSDU_ID 192 +/* + * msdu_id_info_t is defined for reference only + */ +typedef struct { + A_UINT32 num_msdu; + A_UINT8 bound_bmap[MAX_PKT_INFO_MSDU_ID>>3]; + /* TODO: + * Convert the id's to uint32_t + * Reduces computation in the driver code + */ + A_UINT16 id[MAX_PKT_INFO_MSDU_ID]; +}__ATTRIB_PACK msdu_id_info_t; +#define MSDU_ID_INFO_NUM_MSDU_OFFSET 0 /* char offset */ +#define MSDU_ID_INFO_BOUND_BM_OFFSET 4 +#define MSDU_ID_INFO_ID_OFFSET \ + ((MAX_PKT_INFO_MSDU_ID >> 3) + 4) + +struct ath_pktlog_txctl { + struct ath_pktlog_hdr pl_hdr; + //struct txctl_frm_hdr frm_hdr; + void *txdesc_hdr_ctl; /* frm_hdr + Tx descriptor words */ + struct { + struct txctl_frm_hdr frm_hdr; + u_int32_t txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS]; + //u_int32_t *proto_hdr; /* protocol header (variable length!) */ + //u_int32_t *misc; /* Can be used for HT specific or other misc info */ + } priv; +} __ATTRIB_PACK; + +struct ath_pktlog_tx_status { + struct ath_pktlog_hdr pl_hdr; + void *ds_status; + int32_t misc[0]; /* Can be used for HT specific or other misc info */ +}__ATTRIB_PACK; + +struct ath_pktlog_msdu_info { + struct ath_pktlog_hdr pl_hdr; + void *ath_msdu_info; + A_UINT32 num_msdu; + struct { + /* + * Provision to add more information fields + */ + struct msdu_info_t { + A_UINT32 num_msdu; + A_UINT8 bound_bmap[MAX_PKT_INFO_MSDU_ID>>3]; + } msdu_id_info; + /* + * array of num_msdu + * Static implementation will consume unwanted memory + * Need to split the pktlog_get_buf to get the buffer pointer only + */ + uint16_t msdu_len[MAX_PKT_INFO_MSDU_ID]; + } priv; + size_t priv_size; + +}__ATTRIB_PACK; + +struct ath_pktlog_rx_info { + struct ath_pktlog_hdr pl_hdr; + void *rx_desc; +}__ATTRIB_PACK; + +struct ath_pktlog_rc_find { + struct ath_pktlog_hdr pl_hdr; + void *rcFind; +}__ATTRIB_PACK; + +struct ath_pktlog_rc_update { + struct ath_pktlog_hdr pl_hdr; + void *txRateCtrl;/* rate control state proper */ +}__ATTRIB_PACK; + +#define PKTLOG_MAX_RXSTATUS_WORDS 11 + +struct ath_pktlog_ani { + u_int8_t phyStatsDisable; + u_int8_t noiseImmunLvl; + u_int8_t spurImmunLvl; + u_int8_t ofdmWeakDet; + u_int8_t cckWeakThr; + int8_t rssi; + u_int16_t firLvl; + u_int16_t listenTime; + u_int16_t resvd; + u_int32_t cycleCount; + u_int32_t ofdmPhyErrCount; + u_int32_t cckPhyErrCount; + int32_t misc[0]; /* Can be used for HT specific or other misc info */ +} __ATTRIB_PACK; + + +struct ath_pktlog_rcfind { + u_int8_t rate; + u_int8_t rateCode; + int8_t rcRssiLast; + int8_t rcRssiLastPrev; + int8_t rcRssiLastPrev2; + int8_t rssiReduce; + u_int8_t rcProbeRate; + int8_t isProbing; + int8_t primeInUse; + int8_t currentPrimeState; + u_int8_t rcRateTableSize; + u_int8_t rcRateMax; + u_int8_t ac; + int32_t misc[0]; /* Can be used for HT specific or other misc info */ +} __ATTRIB_PACK; + + +struct ath_pktlog_rcupdate { + u_int8_t txRate; + u_int8_t rateCode; + int8_t rssiAck; + u_int8_t Xretries; + u_int8_t retries; + int8_t rcRssiLast; + int8_t rcRssiLastLkup; + int8_t rcRssiLastPrev; + int8_t rcRssiLastPrev2; + u_int8_t rcProbeRate; + u_int8_t rcRateMax; + int8_t useTurboPrime; + int8_t currentBoostState; + u_int8_t rcHwMaxRetryRate; + u_int8_t ac; + u_int8_t resvd[2]; + int8_t rcRssiThres[MAX_TX_RATE_TBL]; + u_int8_t rcPer[MAX_TX_RATE_TBL]; + u_int8_t rcMaxAggrSize[MAX_TX_RATE_TBL]; + u_int8_t headFail; /* rate control and aggregation variables ( part of ATH_SUPPORT_VOWEXT ) */ + u_int8_t tailFail; /* rate control and aggregation variables ( part of ATH_SUPPORT_VOWEXT ) */ + u_int8_t aggrSize; /* rate control and aggregation variables ( part of ATH_SUPPORT_VOWEXT ) */ + u_int8_t aggrLimit;/* rate control and aggregation variables ( part of ATH_SUPPORT_VOWEXT ) */ + u_int8_t lastRate; /* rate control and aggregation variables ( part of ATH_SUPPORT_VOWEXT ) */ + int32_t misc[0]; /* Can be used for HT specific or other misc info */ + /* TBD: Add any new parameters required */ +} __ATTRIB_PACK; + +#ifdef WIN32 +#pragma pack(pop, pktlog_fmt) +#endif +#ifdef __ATTRIB_PACK +#undef __ATTRIB_PACK +#endif /* __ATTRIB_PACK */ + +/* + * The following header is included in the beginning of the file, + * followed by log entries when the log buffer is read through procfs + */ + +struct ath_pktlog_bufhdr { + u_int32_t magic_num; /* Used by post processing scripts */ + u_int32_t version; /* Set to CUR_PKTLOG_VER */ +}; + +struct ath_pktlog_buf { + struct ath_pktlog_bufhdr bufhdr; + int32_t rd_offset; + int32_t wr_offset; + char log_data[0]; +}; + +#define PKTLOG_MOV_RD_IDX(_rd_offset, _log_buf, _log_size) \ + do { \ + if((_rd_offset + sizeof(struct ath_pktlog_hdr) + \ + ((struct ath_pktlog_hdr *)((_log_buf)->log_data + \ + (_rd_offset)))->size) <= _log_size) { \ + _rd_offset = ((_rd_offset) + sizeof(struct ath_pktlog_hdr) + \ + ((struct ath_pktlog_hdr *)((_log_buf)->log_data + \ + (_rd_offset)))->size); \ + } else { \ + _rd_offset = ((struct ath_pktlog_hdr *)((_log_buf)->log_data + \ + (_rd_offset)))->size; \ + } \ + (_rd_offset) = (((_log_size) - (_rd_offset)) >= \ + sizeof(struct ath_pktlog_hdr)) ? _rd_offset:0;\ + } while(0) + +#endif /* _PKTLOG_FMT_H_ */ +#endif /* REMOVE_PKT_LOG */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/queue.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/queue.h new file mode 100644 index 0000000000000..5da9b068e9ce6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/queue.h @@ -0,0 +1,563 @@ +// +// Copyright (c) 1991, 1993 +// The Regents of the University of California. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All advertising materials mentioning features or use of this software +// must display the following acknowledgement: +// This product includes software developed by the University of +// California, Berkeley and its contributors. +// 4. Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// +// @(#)queue.h 8.5 (Berkeley) 8/20/94 +// $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $ +// + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - - - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT - - + + + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * + */ +#define QUEUE_MACRO_DEBUG 0 +#if QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#if !defined(FIELD_OFFSET) +#define FIELD_OFFSET(type, field) ((int)(int *)&(((struct type *)0)->field)) +#endif + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - FIELD_OFFSET(type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_CONCAT_ELEM(prevelm, elm, field) do { \ + prevelm->field.stqe_next = elm; \ +} while (0) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +/* + * List declarations. + */ +#define ATH_LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + + +#ifdef _KERNEL + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +static __inline void +insque(void *a, void *b) +{ + struct quehead *element = (struct quehead *)a, + *head = (struct quehead *)b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque(void *a) +{ + struct quehead *element = (struct quehead *)a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !(__GNUC__ || __INTEL_COMPILER) */ + +void insque(void *a, void *b); +void remque(void *a); + +#endif /* __GNUC__ || __INTEL_COMPILER */ + +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/rtc_soc_reg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/rtc_soc_reg.h new file mode 100644 index 0000000000000..713aeb413bfe8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/rtc_soc_reg.h @@ -0,0 +1,1966 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _RTC_SOC_REG_REG_H_ +#define _RTC_SOC_REG_REG_H_ + +#define SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define SOC_RESET_CONTROL_OFFSET 0x00000000 +#define SOC_RESET_CONTROL_SPI2_RST_MSB 30 +#define SOC_RESET_CONTROL_SPI2_RST_LSB 30 +#define SOC_RESET_CONTROL_SPI2_RST_MASK 0x40000000 +#define SOC_RESET_CONTROL_SPI2_RST_GET(x) (((x) & SOC_RESET_CONTROL_SPI2_RST_MASK) >> SOC_RESET_CONTROL_SPI2_RST_LSB) +#define SOC_RESET_CONTROL_SPI2_RST_SET(x) (((x) << SOC_RESET_CONTROL_SPI2_RST_LSB) & SOC_RESET_CONTROL_SPI2_RST_MASK) +#define SOC_RESET_CONTROL_I2S_1_RST_MSB 29 +#define SOC_RESET_CONTROL_I2S_1_RST_LSB 29 +#define SOC_RESET_CONTROL_I2S_1_RST_MASK 0x20000000 +#define SOC_RESET_CONTROL_I2S_1_RST_GET(x) (((x) & SOC_RESET_CONTROL_I2S_1_RST_MASK) >> SOC_RESET_CONTROL_I2S_1_RST_LSB) +#define SOC_RESET_CONTROL_I2S_1_RST_SET(x) (((x) << SOC_RESET_CONTROL_I2S_1_RST_LSB) & SOC_RESET_CONTROL_I2S_1_RST_MASK) +#define SOC_RESET_CONTROL_I2S_1_MBOX_RST_MSB 28 +#define SOC_RESET_CONTROL_I2S_1_MBOX_RST_LSB 28 +#define SOC_RESET_CONTROL_I2S_1_MBOX_RST_MASK 0x10000000 +#define SOC_RESET_CONTROL_I2S_1_MBOX_RST_GET(x) (((x) & SOC_RESET_CONTROL_I2S_1_MBOX_RST_MASK) >> SOC_RESET_CONTROL_I2S_1_MBOX_RST_LSB) +#define SOC_RESET_CONTROL_I2S_1_MBOX_RST_SET(x) (((x) << SOC_RESET_CONTROL_I2S_1_MBOX_RST_LSB) & SOC_RESET_CONTROL_I2S_1_MBOX_RST_MASK) +#define SOC_RESET_CONTROL_I2C_SLAVE_RST_MSB 27 +#define SOC_RESET_CONTROL_I2C_SLAVE_RST_LSB 27 +#define SOC_RESET_CONTROL_I2C_SLAVE_RST_MASK 0x08000000 +#define SOC_RESET_CONTROL_I2C_SLAVE_RST_GET(x) (((x) & SOC_RESET_CONTROL_I2C_SLAVE_RST_MASK) >> SOC_RESET_CONTROL_I2C_SLAVE_RST_LSB) +#define SOC_RESET_CONTROL_I2C_SLAVE_RST_SET(x) (((x) << SOC_RESET_CONTROL_I2C_SLAVE_RST_LSB) & SOC_RESET_CONTROL_I2C_SLAVE_RST_MASK) +#define SOC_RESET_CONTROL_USB_PHY_ARST_MSB 26 +#define SOC_RESET_CONTROL_USB_PHY_ARST_LSB 26 +#define SOC_RESET_CONTROL_USB_PHY_ARST_MASK 0x04000000 +#define SOC_RESET_CONTROL_USB_PHY_ARST_GET(x) (((x) & SOC_RESET_CONTROL_USB_PHY_ARST_MASK) >> SOC_RESET_CONTROL_USB_PHY_ARST_LSB) +#define SOC_RESET_CONTROL_USB_PHY_ARST_SET(x) (((x) << SOC_RESET_CONTROL_USB_PHY_ARST_LSB) & SOC_RESET_CONTROL_USB_PHY_ARST_MASK) +#define SOC_RESET_CONTROL_USB_PHY_RST_MSB 25 +#define SOC_RESET_CONTROL_USB_PHY_RST_LSB 25 +#define SOC_RESET_CONTROL_USB_PHY_RST_MASK 0x02000000 +#define SOC_RESET_CONTROL_USB_PHY_RST_GET(x) (((x) & SOC_RESET_CONTROL_USB_PHY_RST_MASK) >> SOC_RESET_CONTROL_USB_PHY_RST_LSB) +#define SOC_RESET_CONTROL_USB_PHY_RST_SET(x) (((x) << SOC_RESET_CONTROL_USB_PHY_RST_LSB) & SOC_RESET_CONTROL_USB_PHY_RST_MASK) +#define SOC_RESET_CONTROL_USB_RST_MSB 24 +#define SOC_RESET_CONTROL_USB_RST_LSB 24 +#define SOC_RESET_CONTROL_USB_RST_MASK 0x01000000 +#define SOC_RESET_CONTROL_USB_RST_GET(x) (((x) & SOC_RESET_CONTROL_USB_RST_MASK) >> SOC_RESET_CONTROL_USB_RST_LSB) +#define SOC_RESET_CONTROL_USB_RST_SET(x) (((x) << SOC_RESET_CONTROL_USB_RST_LSB) & SOC_RESET_CONTROL_USB_RST_MASK) +#define SOC_RESET_CONTROL_MMAC_RST_MSB 23 +#define SOC_RESET_CONTROL_MMAC_RST_LSB 23 +#define SOC_RESET_CONTROL_MMAC_RST_MASK 0x00800000 +#define SOC_RESET_CONTROL_MMAC_RST_GET(x) (((x) & SOC_RESET_CONTROL_MMAC_RST_MASK) >> SOC_RESET_CONTROL_MMAC_RST_LSB) +#define SOC_RESET_CONTROL_MMAC_RST_SET(x) (((x) << SOC_RESET_CONTROL_MMAC_RST_LSB) & SOC_RESET_CONTROL_MMAC_RST_MASK) +#define SOC_RESET_CONTROL_MDIO_RST_MSB 22 +#define SOC_RESET_CONTROL_MDIO_RST_LSB 22 +#define SOC_RESET_CONTROL_MDIO_RST_MASK 0x00400000 +#define SOC_RESET_CONTROL_MDIO_RST_GET(x) (((x) & SOC_RESET_CONTROL_MDIO_RST_MASK) >> SOC_RESET_CONTROL_MDIO_RST_LSB) +#define SOC_RESET_CONTROL_MDIO_RST_SET(x) (((x) << SOC_RESET_CONTROL_MDIO_RST_LSB) & SOC_RESET_CONTROL_MDIO_RST_MASK) +#define SOC_RESET_CONTROL_GE0_RST_MSB 21 +#define SOC_RESET_CONTROL_GE0_RST_LSB 21 +#define SOC_RESET_CONTROL_GE0_RST_MASK 0x00200000 +#define SOC_RESET_CONTROL_GE0_RST_GET(x) (((x) & SOC_RESET_CONTROL_GE0_RST_MASK) >> SOC_RESET_CONTROL_GE0_RST_LSB) +#define SOC_RESET_CONTROL_GE0_RST_SET(x) (((x) << SOC_RESET_CONTROL_GE0_RST_LSB) & SOC_RESET_CONTROL_GE0_RST_MASK) +#define SOC_RESET_CONTROL_I2S_RST_MSB 20 +#define SOC_RESET_CONTROL_I2S_RST_LSB 20 +#define SOC_RESET_CONTROL_I2S_RST_MASK 0x00100000 +#define SOC_RESET_CONTROL_I2S_RST_GET(x) (((x) & SOC_RESET_CONTROL_I2S_RST_MASK) >> SOC_RESET_CONTROL_I2S_RST_LSB) +#define SOC_RESET_CONTROL_I2S_RST_SET(x) (((x) << SOC_RESET_CONTROL_I2S_RST_LSB) & SOC_RESET_CONTROL_I2S_RST_MASK) +#define SOC_RESET_CONTROL_I2S_MBOX_RST_MSB 19 +#define SOC_RESET_CONTROL_I2S_MBOX_RST_LSB 19 +#define SOC_RESET_CONTROL_I2S_MBOX_RST_MASK 0x00080000 +#define SOC_RESET_CONTROL_I2S_MBOX_RST_GET(x) (((x) & SOC_RESET_CONTROL_I2S_MBOX_RST_MASK) >> SOC_RESET_CONTROL_I2S_MBOX_RST_LSB) +#define SOC_RESET_CONTROL_I2S_MBOX_RST_SET(x) (((x) << SOC_RESET_CONTROL_I2S_MBOX_RST_LSB) & SOC_RESET_CONTROL_I2S_MBOX_RST_MASK) +/* TODO: */ +#define SOC_RESET_CONTROL_CHECKSUM_ACC_RST_MSB 18 +#define SOC_RESET_CONTROL_CHECKSUM_ACC_RST_LSB 18 +#define SOC_RESET_CONTROL_CHECKSUM_ACC_RST_MASK 0x00040000 +#define SOC_RESET_CONTROL_CHECKSUM_ACC_RST_GET(x) (((x) & SOC_RESET_CONTROL_CHECKSUM_ACC_RST_MASK) >> SOC_RESET_CONTROL_CHECKSUM_ACC_RST_LSB) +#define SOC_RESET_CONTROL_CHECKSUM_ACC_RST_SET(x) (((x) << SOC_RESET_CONTROL_CHECKSUM_ACC_RST_LSB) & SOC_RESET_CONTROL_CHECKSUM_ACC_RST_MASK) +#define SOC_RESET_CONTROL_CE_RST_MSB 18 +#define SOC_RESET_CONTROL_CE_RST_LSB 18 +#define SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 +#define SOC_RESET_CONTROL_CE_RST_GET(x) (((x) & SOC_RESET_CONTROL_CE_RST_MASK) >> SOC_RESET_CONTROL_CE_RST_LSB) +#define SOC_RESET_CONTROL_CE_RST_SET(x) (((x) << SOC_RESET_CONTROL_CE_RST_LSB) & SOC_RESET_CONTROL_CE_RST_MASK) +#define SOC_RESET_CONTROL_UART2_RST_MSB 17 +#define SOC_RESET_CONTROL_UART2_RST_LSB 17 +#define SOC_RESET_CONTROL_UART2_RST_MASK 0x00020000 +#define SOC_RESET_CONTROL_UART2_RST_GET(x) (((x) & SOC_RESET_CONTROL_UART2_RST_MASK) >> SOC_RESET_CONTROL_UART2_RST_LSB) +#define SOC_RESET_CONTROL_UART2_RST_SET(x) (((x) << SOC_RESET_CONTROL_UART2_RST_LSB) & SOC_RESET_CONTROL_UART2_RST_MASK) +#define SOC_RESET_CONTROL_DEBUG_UART_RST_MSB 16 +#define SOC_RESET_CONTROL_DEBUG_UART_RST_LSB 16 +#define SOC_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00010000 +#define SOC_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & SOC_RESET_CONTROL_DEBUG_UART_RST_MASK) >> SOC_RESET_CONTROL_DEBUG_UART_RST_LSB) +#define SOC_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << SOC_RESET_CONTROL_DEBUG_UART_RST_LSB) & SOC_RESET_CONTROL_DEBUG_UART_RST_MASK) +#define SOC_RESET_CONTROL_CPU_INIT_RESET_MSB 11 +#define SOC_RESET_CONTROL_CPU_INIT_RESET_LSB 11 +#define SOC_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800 +#define SOC_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & SOC_RESET_CONTROL_CPU_INIT_RESET_MASK) >> SOC_RESET_CONTROL_CPU_INIT_RESET_LSB) +#define SOC_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << SOC_RESET_CONTROL_CPU_INIT_RESET_LSB) & SOC_RESET_CONTROL_CPU_INIT_RESET_MASK) +#define SOC_RESET_CONTROL_RST_OUT_MSB 9 +#define SOC_RESET_CONTROL_RST_OUT_LSB 9 +#define SOC_RESET_CONTROL_RST_OUT_MASK 0x00000200 +#define SOC_RESET_CONTROL_RST_OUT_GET(x) (((x) & SOC_RESET_CONTROL_RST_OUT_MASK) >> SOC_RESET_CONTROL_RST_OUT_LSB) +#define SOC_RESET_CONTROL_RST_OUT_SET(x) (((x) << SOC_RESET_CONTROL_RST_OUT_LSB) & SOC_RESET_CONTROL_RST_OUT_MASK) +#define SOC_RESET_CONTROL_COLD_RST_MSB 8 +#define SOC_RESET_CONTROL_COLD_RST_LSB 8 +#define SOC_RESET_CONTROL_COLD_RST_MASK 0x00000100 +#define SOC_RESET_CONTROL_COLD_RST_GET(x) (((x) & SOC_RESET_CONTROL_COLD_RST_MASK) >> SOC_RESET_CONTROL_COLD_RST_LSB) +#define SOC_RESET_CONTROL_COLD_RST_SET(x) (((x) << SOC_RESET_CONTROL_COLD_RST_LSB) & SOC_RESET_CONTROL_COLD_RST_MASK) +#define SOC_RESET_CONTROL_CPU_WARM_RST_MSB 6 +#define SOC_RESET_CONTROL_CPU_WARM_RST_LSB 6 +#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define SOC_RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & SOC_RESET_CONTROL_CPU_WARM_RST_MASK) >> SOC_RESET_CONTROL_CPU_WARM_RST_LSB) +#define SOC_RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << SOC_RESET_CONTROL_CPU_WARM_RST_LSB) & SOC_RESET_CONTROL_CPU_WARM_RST_MASK) +/* TODO: */ +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MSB 2 +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 2 +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000004 +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) (((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) (((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) +#define SOC_RESET_CONTROL_MBOX_RST_MSB 2 +#define SOC_RESET_CONTROL_MBOX_RST_LSB 2 +#define SOC_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define SOC_RESET_CONTROL_MBOX_RST_GET(x) (((x) & SOC_RESET_CONTROL_MBOX_RST_MASK) >> SOC_RESET_CONTROL_MBOX_RST_LSB) +#define SOC_RESET_CONTROL_MBOX_RST_SET(x) (((x) << SOC_RESET_CONTROL_MBOX_RST_LSB) & SOC_RESET_CONTROL_MBOX_RST_MASK) +#define SOC_RESET_CONTROL_UART_RST_MSB 1 +#define SOC_RESET_CONTROL_UART_RST_LSB 1 +#define SOC_RESET_CONTROL_UART_RST_MASK 0x00000002 +#define SOC_RESET_CONTROL_UART_RST_GET(x) (((x) & SOC_RESET_CONTROL_UART_RST_MASK) >> SOC_RESET_CONTROL_UART_RST_LSB) +#define SOC_RESET_CONTROL_UART_RST_SET(x) (((x) << SOC_RESET_CONTROL_UART_RST_LSB) & SOC_RESET_CONTROL_UART_RST_MASK) +#define SOC_RESET_CONTROL_SI0_RST_MSB 0 +#define SOC_RESET_CONTROL_SI0_RST_LSB 0 +#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define SOC_RESET_CONTROL_SI0_RST_GET(x) (((x) & SOC_RESET_CONTROL_SI0_RST_MASK) >> SOC_RESET_CONTROL_SI0_RST_LSB) +#define SOC_RESET_CONTROL_SI0_RST_SET(x) (((x) << SOC_RESET_CONTROL_SI0_RST_LSB) & SOC_RESET_CONTROL_SI0_RST_MASK) + +#define SOC_TCXO_DETECT_ADDRESS 0x00000004 +#define SOC_TCXO_DETECT_OFFSET 0x00000004 +#define SOC_TCXO_DETECT_PRESENT_MSB 0 +#define SOC_TCXO_DETECT_PRESENT_LSB 0 +#define SOC_TCXO_DETECT_PRESENT_MASK 0x00000001 +#define SOC_TCXO_DETECT_PRESENT_GET(x) (((x) & SOC_TCXO_DETECT_PRESENT_MASK) >> SOC_TCXO_DETECT_PRESENT_LSB) +#define SOC_TCXO_DETECT_PRESENT_SET(x) (((x) << SOC_TCXO_DETECT_PRESENT_LSB) & SOC_TCXO_DETECT_PRESENT_MASK) + +#define SOC_XTAL_TEST_ADDRESS 0x00000008 +#define SOC_XTAL_TEST_OFFSET 0x00000008 +#define SOC_XTAL_TEST_NOTCXODET_MSB 0 +#define SOC_XTAL_TEST_NOTCXODET_LSB 0 +#define SOC_XTAL_TEST_NOTCXODET_MASK 0x00000001 +#define SOC_XTAL_TEST_NOTCXODET_GET(x) (((x) & SOC_XTAL_TEST_NOTCXODET_MASK) >> SOC_XTAL_TEST_NOTCXODET_LSB) +#define SOC_XTAL_TEST_NOTCXODET_SET(x) (((x) << SOC_XTAL_TEST_NOTCXODET_LSB) & SOC_XTAL_TEST_NOTCXODET_MASK) + +#define SOC_CPU_CLOCK_ADDRESS 0x00000020 +#define SOC_CPU_CLOCK_OFFSET 0x00000020 +#define SOC_CPU_CLOCK_STANDARD_MSB 1 +#define SOC_CPU_CLOCK_STANDARD_LSB 0 +#define SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define SOC_CPU_CLOCK_STANDARD_GET(x) (((x) & SOC_CPU_CLOCK_STANDARD_MASK) >> SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_SET(x) (((x) << SOC_CPU_CLOCK_STANDARD_LSB) & SOC_CPU_CLOCK_STANDARD_MASK) + +#define SOC_CLOCK_CONTROL_ADDRESS 0x00000028 +#define SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define SOC_CLOCK_CONTROL_USB_CLOCK_MSB 3 +#define SOC_CLOCK_CONTROL_USB_CLOCK_LSB 3 +#define SOC_CLOCK_CONTROL_USB_CLOCK_MASK 0x00000008 +#define SOC_CLOCK_CONTROL_USB_CLOCK_GET(x) (((x) & SOC_CLOCK_CONTROL_USB_CLOCK_MASK) >> SOC_CLOCK_CONTROL_USB_CLOCK_LSB) +#define SOC_CLOCK_CONTROL_USB_CLOCK_SET(x) (((x) << SOC_CLOCK_CONTROL_USB_CLOCK_LSB) & SOC_CLOCK_CONTROL_USB_CLOCK_MASK) +#define SOC_CLOCK_CONTROL_LF_CLK32_MSB 2 +#define SOC_CLOCK_CONTROL_LF_CLK32_LSB 2 +#define SOC_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004 +#define SOC_CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & SOC_CLOCK_CONTROL_LF_CLK32_MASK) >> SOC_CLOCK_CONTROL_LF_CLK32_LSB) +#define SOC_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << SOC_CLOCK_CONTROL_LF_CLK32_LSB) & SOC_CLOCK_CONTROL_LF_CLK32_MASK) +#define SOC_CLOCK_CONTROL_SI0_CLK_MSB 0 +#define SOC_CLOCK_CONTROL_SI0_CLK_LSB 0 +#define SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define SOC_CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & SOC_CLOCK_CONTROL_SI0_CLK_MASK) >> SOC_CLOCK_CONTROL_SI0_CLK_LSB) +#define SOC_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << SOC_CLOCK_CONTROL_SI0_CLK_LSB) & SOC_CLOCK_CONTROL_SI0_CLK_MASK) + +#define SOC_WDT_CONTROL_ADDRESS 0x00000030 +#define SOC_WDT_CONTROL_OFFSET 0x00000030 +#define SOC_WDT_CONTROL_ACTION_MSB 2 +#define SOC_WDT_CONTROL_ACTION_LSB 0 +#define SOC_WDT_CONTROL_ACTION_MASK 0x00000007 +#define SOC_WDT_CONTROL_ACTION_GET(x) (((x) & SOC_WDT_CONTROL_ACTION_MASK) >> SOC_WDT_CONTROL_ACTION_LSB) +#define SOC_WDT_CONTROL_ACTION_SET(x) (((x) << SOC_WDT_CONTROL_ACTION_LSB) & SOC_WDT_CONTROL_ACTION_MASK) + +#define SOC_WDT_STATUS_ADDRESS 0x00000034 +#define SOC_WDT_STATUS_OFFSET 0x00000034 +#define SOC_WDT_STATUS_INTERRUPT_MSB 0 +#define SOC_WDT_STATUS_INTERRUPT_LSB 0 +#define SOC_WDT_STATUS_INTERRUPT_MASK 0x00000001 +#define SOC_WDT_STATUS_INTERRUPT_GET(x) (((x) & SOC_WDT_STATUS_INTERRUPT_MASK) >> SOC_WDT_STATUS_INTERRUPT_LSB) +#define SOC_WDT_STATUS_INTERRUPT_SET(x) (((x) << SOC_WDT_STATUS_INTERRUPT_LSB) & SOC_WDT_STATUS_INTERRUPT_MASK) + +#define SOC_WDT_ADDRESS 0x00000038 +#define SOC_WDT_OFFSET 0x00000038 +#define SOC_WDT_TARGET_MSB 21 +#define SOC_WDT_TARGET_LSB 0 +#define SOC_WDT_TARGET_MASK 0x003fffff +#define SOC_WDT_TARGET_GET(x) (((x) & SOC_WDT_TARGET_MASK) >> SOC_WDT_TARGET_LSB) +#define SOC_WDT_TARGET_SET(x) (((x) << SOC_WDT_TARGET_LSB) & SOC_WDT_TARGET_MASK) + +#define SOC_WDT_COUNT_ADDRESS 0x0000003c +#define SOC_WDT_COUNT_OFFSET 0x0000003c +#define SOC_WDT_COUNT_VALUE_MSB 21 +#define SOC_WDT_COUNT_VALUE_LSB 0 +#define SOC_WDT_COUNT_VALUE_MASK 0x003fffff +#define SOC_WDT_COUNT_VALUE_GET(x) (((x) & SOC_WDT_COUNT_VALUE_MASK) >> SOC_WDT_COUNT_VALUE_LSB) +#define SOC_WDT_COUNT_VALUE_SET(x) (((x) << SOC_WDT_COUNT_VALUE_LSB) & SOC_WDT_COUNT_VALUE_MASK) + +#define SOC_WDT_RESET_ADDRESS 0x00000040 +#define SOC_WDT_RESET_OFFSET 0x00000040 +#define SOC_WDT_RESET_VALUE_MSB 0 +#define SOC_WDT_RESET_VALUE_LSB 0 +#define SOC_WDT_RESET_VALUE_MASK 0x00000001 +#define SOC_WDT_RESET_VALUE_GET(x) (((x) & SOC_WDT_RESET_VALUE_MASK) >> SOC_WDT_RESET_VALUE_LSB) +#define SOC_WDT_RESET_VALUE_SET(x) (((x) << SOC_WDT_RESET_VALUE_LSB) & SOC_WDT_RESET_VALUE_MASK) + +#define SOC_INT_STATUS_ADDRESS 0x00000044 +#define SOC_INT_STATUS_OFFSET 0x00000044 +#define SOC_INT_STATUS_MAC_4_MSB 23 +#define SOC_INT_STATUS_MAC_4_LSB 23 +#define SOC_INT_STATUS_MAC_4_MASK 0x00800000 +#define SOC_INT_STATUS_MAC_4_GET(x) (((x) & SOC_INT_STATUS_MAC_4_MASK) >> SOC_INT_STATUS_MAC_4_LSB) +#define SOC_INT_STATUS_MAC_4_SET(x) (((x) << SOC_INT_STATUS_MAC_4_LSB) & SOC_INT_STATUS_MAC_4_MASK) +#define SOC_INT_STATUS_MAC_3_MSB 22 +#define SOC_INT_STATUS_MAC_3_LSB 22 +#define SOC_INT_STATUS_MAC_3_MASK 0x00400000 +#define SOC_INT_STATUS_MAC_3_GET(x) (((x) & SOC_INT_STATUS_MAC_3_MASK) >> SOC_INT_STATUS_MAC_3_LSB) +#define SOC_INT_STATUS_MAC_3_SET(x) (((x) << SOC_INT_STATUS_MAC_3_LSB) & SOC_INT_STATUS_MAC_3_MASK) +#define SOC_INT_STATUS_MAC_2_MSB 21 +#define SOC_INT_STATUS_MAC_2_LSB 21 +#define SOC_INT_STATUS_MAC_2_MASK 0x00200000 +#define SOC_INT_STATUS_MAC_2_GET(x) (((x) & SOC_INT_STATUS_MAC_2_MASK) >> SOC_INT_STATUS_MAC_2_LSB) +#define SOC_INT_STATUS_MAC_2_SET(x) (((x) << SOC_INT_STATUS_MAC_2_LSB) & SOC_INT_STATUS_MAC_2_MASK) +#define SOC_INT_STATUS_MAC_1_MSB 20 +#define SOC_INT_STATUS_MAC_1_LSB 20 +#define SOC_INT_STATUS_MAC_1_MASK 0x00100000 +#define SOC_INT_STATUS_MAC_1_GET(x) (((x) & SOC_INT_STATUS_MAC_1_MASK) >> SOC_INT_STATUS_MAC_1_LSB) +#define SOC_INT_STATUS_MAC_1_SET(x) (((x) << SOC_INT_STATUS_MAC_1_LSB) & SOC_INT_STATUS_MAC_1_MASK) +#define SOC_INT_STATUS_USBDMA_MSB 19 +#define SOC_INT_STATUS_USBDMA_LSB 19 +#define SOC_INT_STATUS_USBDMA_MASK 0x00080000 +#define SOC_INT_STATUS_USBDMA_GET(x) (((x) & SOC_INT_STATUS_USBDMA_MASK) >> SOC_INT_STATUS_USBDMA_LSB) +#define SOC_INT_STATUS_USBDMA_SET(x) (((x) << SOC_INT_STATUS_USBDMA_LSB) & SOC_INT_STATUS_USBDMA_MASK) +#define SOC_INT_STATUS_USBIP_MSB 18 +#define SOC_INT_STATUS_USBIP_LSB 18 +#define SOC_INT_STATUS_USBIP_MASK 0x00040000 +#define SOC_INT_STATUS_USBIP_GET(x) (((x) & SOC_INT_STATUS_USBIP_MASK) >> SOC_INT_STATUS_USBIP_LSB) +#define SOC_INT_STATUS_USBIP_SET(x) (((x) << SOC_INT_STATUS_USBIP_LSB) & SOC_INT_STATUS_USBIP_MASK) +#define SOC_INT_STATUS_THERM_MSB 17 +#define SOC_INT_STATUS_THERM_LSB 17 +#define SOC_INT_STATUS_THERM_MASK 0x00020000 +#define SOC_INT_STATUS_THERM_GET(x) (((x) & SOC_INT_STATUS_THERM_MASK) >> SOC_INT_STATUS_THERM_LSB) +#define SOC_INT_STATUS_THERM_SET(x) (((x) << SOC_INT_STATUS_THERM_LSB) & SOC_INT_STATUS_THERM_MASK) +#define SOC_INT_STATUS_EFUSE_OVERWRITE_MSB 16 +#define SOC_INT_STATUS_EFUSE_OVERWRITE_LSB 16 +#define SOC_INT_STATUS_EFUSE_OVERWRITE_MASK 0x00010000 +#define SOC_INT_STATUS_EFUSE_OVERWRITE_GET(x) (((x) & SOC_INT_STATUS_EFUSE_OVERWRITE_MASK) >> SOC_INT_STATUS_EFUSE_OVERWRITE_LSB) +#define SOC_INT_STATUS_EFUSE_OVERWRITE_SET(x) (((x) << SOC_INT_STATUS_EFUSE_OVERWRITE_LSB) & SOC_INT_STATUS_EFUSE_OVERWRITE_MASK) +#define SOC_INT_STATUS_RDMA_MSB 15 +#define SOC_INT_STATUS_RDMA_LSB 15 +#define SOC_INT_STATUS_RDMA_MASK 0x00008000 +#define SOC_INT_STATUS_RDMA_GET(x) (((x) & SOC_INT_STATUS_RDMA_MASK) >> SOC_INT_STATUS_RDMA_LSB) +#define SOC_INT_STATUS_RDMA_SET(x) (((x) << SOC_INT_STATUS_RDMA_LSB) & SOC_INT_STATUS_RDMA_MASK) +#define SOC_INT_STATUS_BTCOEX_MSB 14 +#define SOC_INT_STATUS_BTCOEX_LSB 14 +#define SOC_INT_STATUS_BTCOEX_MASK 0x00004000 +#define SOC_INT_STATUS_BTCOEX_GET(x) (((x) & SOC_INT_STATUS_BTCOEX_MASK) >> SOC_INT_STATUS_BTCOEX_LSB) +#define SOC_INT_STATUS_BTCOEX_SET(x) (((x) << SOC_INT_STATUS_BTCOEX_LSB) & SOC_INT_STATUS_BTCOEX_MASK) +#define SOC_INT_STATUS_RTC_POWER_MSB 13 +#define SOC_INT_STATUS_RTC_POWER_LSB 13 +#define SOC_INT_STATUS_RTC_POWER_MASK 0x00002000 +#define SOC_INT_STATUS_RTC_POWER_GET(x) (((x) & SOC_INT_STATUS_RTC_POWER_MASK) >> SOC_INT_STATUS_RTC_POWER_LSB) +#define SOC_INT_STATUS_RTC_POWER_SET(x) (((x) << SOC_INT_STATUS_RTC_POWER_LSB) & SOC_INT_STATUS_RTC_POWER_MASK) +#define SOC_INT_STATUS_MAC_MSB 12 +#define SOC_INT_STATUS_MAC_LSB 12 +#define SOC_INT_STATUS_MAC_MASK 0x00001000 +#define SOC_INT_STATUS_MAC_GET(x) (((x) & SOC_INT_STATUS_MAC_MASK) >> SOC_INT_STATUS_MAC_LSB) +#define SOC_INT_STATUS_MAC_SET(x) (((x) << SOC_INT_STATUS_MAC_LSB) & SOC_INT_STATUS_MAC_MASK) +#define SOC_INT_STATUS_MAILBOX_MSB 11 +#define SOC_INT_STATUS_MAILBOX_LSB 11 +#define SOC_INT_STATUS_MAILBOX_MASK 0x00000800 +#define SOC_INT_STATUS_MAILBOX_GET(x) (((x) & SOC_INT_STATUS_MAILBOX_MASK) >> SOC_INT_STATUS_MAILBOX_LSB) +#define SOC_INT_STATUS_MAILBOX_SET(x) (((x) << SOC_INT_STATUS_MAILBOX_LSB) & SOC_INT_STATUS_MAILBOX_MASK) +#define SOC_INT_STATUS_RTC_ALARM_MSB 10 +#define SOC_INT_STATUS_RTC_ALARM_LSB 10 +#define SOC_INT_STATUS_RTC_ALARM_MASK 0x00000400 +#define SOC_INT_STATUS_RTC_ALARM_GET(x) (((x) & SOC_INT_STATUS_RTC_ALARM_MASK) >> SOC_INT_STATUS_RTC_ALARM_LSB) +#define SOC_INT_STATUS_RTC_ALARM_SET(x) (((x) << SOC_INT_STATUS_RTC_ALARM_LSB) & SOC_INT_STATUS_RTC_ALARM_MASK) +#define SOC_INT_STATUS_HF_TIMER_MSB 9 +#define SOC_INT_STATUS_HF_TIMER_LSB 9 +#define SOC_INT_STATUS_HF_TIMER_MASK 0x00000200 +#define SOC_INT_STATUS_HF_TIMER_GET(x) (((x) & SOC_INT_STATUS_HF_TIMER_MASK) >> SOC_INT_STATUS_HF_TIMER_LSB) +#define SOC_INT_STATUS_HF_TIMER_SET(x) (((x) << SOC_INT_STATUS_HF_TIMER_LSB) & SOC_INT_STATUS_HF_TIMER_MASK) +#define SOC_INT_STATUS_LF_TIMER3_MSB 8 +#define SOC_INT_STATUS_LF_TIMER3_LSB 8 +#define SOC_INT_STATUS_LF_TIMER3_MASK 0x00000100 +#define SOC_INT_STATUS_LF_TIMER3_GET(x) (((x) & SOC_INT_STATUS_LF_TIMER3_MASK) >> SOC_INT_STATUS_LF_TIMER3_LSB) +#define SOC_INT_STATUS_LF_TIMER3_SET(x) (((x) << SOC_INT_STATUS_LF_TIMER3_LSB) & SOC_INT_STATUS_LF_TIMER3_MASK) +#define SOC_INT_STATUS_LF_TIMER2_MSB 7 +#define SOC_INT_STATUS_LF_TIMER2_LSB 7 +#define SOC_INT_STATUS_LF_TIMER2_MASK 0x00000080 +#define SOC_INT_STATUS_LF_TIMER2_GET(x) (((x) & SOC_INT_STATUS_LF_TIMER2_MASK) >> SOC_INT_STATUS_LF_TIMER2_LSB) +#define SOC_INT_STATUS_LF_TIMER2_SET(x) (((x) << SOC_INT_STATUS_LF_TIMER2_LSB) & SOC_INT_STATUS_LF_TIMER2_MASK) +#define SOC_INT_STATUS_LF_TIMER1_MSB 6 +#define SOC_INT_STATUS_LF_TIMER1_LSB 6 +#define SOC_INT_STATUS_LF_TIMER1_MASK 0x00000040 +#define SOC_INT_STATUS_LF_TIMER1_GET(x) (((x) & SOC_INT_STATUS_LF_TIMER1_MASK) >> SOC_INT_STATUS_LF_TIMER1_LSB) +#define SOC_INT_STATUS_LF_TIMER1_SET(x) (((x) << SOC_INT_STATUS_LF_TIMER1_LSB) & SOC_INT_STATUS_LF_TIMER1_MASK) +#define SOC_INT_STATUS_LF_TIMER0_MSB 5 +#define SOC_INT_STATUS_LF_TIMER0_LSB 5 +#define SOC_INT_STATUS_LF_TIMER0_MASK 0x00000020 +#define SOC_INT_STATUS_LF_TIMER0_GET(x) (((x) & SOC_INT_STATUS_LF_TIMER0_MASK) >> SOC_INT_STATUS_LF_TIMER0_LSB) +#define SOC_INT_STATUS_LF_TIMER0_SET(x) (((x) << SOC_INT_STATUS_LF_TIMER0_LSB) & SOC_INT_STATUS_LF_TIMER0_MASK) +#define SOC_INT_STATUS_SI_MSB 4 +#define SOC_INT_STATUS_SI_LSB 4 +#define SOC_INT_STATUS_SI_MASK 0x00000010 +#define SOC_INT_STATUS_SI_GET(x) (((x) & SOC_INT_STATUS_SI_MASK) >> SOC_INT_STATUS_SI_LSB) +#define SOC_INT_STATUS_SI_SET(x) (((x) << SOC_INT_STATUS_SI_LSB) & SOC_INT_STATUS_SI_MASK) +#define SOC_INT_STATUS_GPIO_MSB 3 +#define SOC_INT_STATUS_GPIO_LSB 3 +#define SOC_INT_STATUS_GPIO_MASK 0x00000008 +#define SOC_INT_STATUS_GPIO_GET(x) (((x) & SOC_INT_STATUS_GPIO_MASK) >> SOC_INT_STATUS_GPIO_LSB) +#define SOC_INT_STATUS_GPIO_SET(x) (((x) << SOC_INT_STATUS_GPIO_LSB) & SOC_INT_STATUS_GPIO_MASK) +#define SOC_INT_STATUS_DEBUG_UART_MSB 2 +#define SOC_INT_STATUS_DEBUG_UART_LSB 2 +#define SOC_INT_STATUS_DEBUG_UART_MASK 0x00000004 +#define SOC_INT_STATUS_DEBUG_UART_GET(x) (((x) & SOC_INT_STATUS_DEBUG_UART_MASK) >> SOC_INT_STATUS_DEBUG_UART_LSB) +#define SOC_INT_STATUS_DEBUG_UART_SET(x) (((x) << SOC_INT_STATUS_DEBUG_UART_LSB) & SOC_INT_STATUS_DEBUG_UART_MASK) +#define SOC_INT_STATUS_ERROR_MSB 1 +#define SOC_INT_STATUS_ERROR_LSB 1 +#define SOC_INT_STATUS_ERROR_MASK 0x00000002 +#define SOC_INT_STATUS_ERROR_GET(x) (((x) & SOC_INT_STATUS_ERROR_MASK) >> SOC_INT_STATUS_ERROR_LSB) +#define SOC_INT_STATUS_ERROR_SET(x) (((x) << SOC_INT_STATUS_ERROR_LSB) & SOC_INT_STATUS_ERROR_MASK) +#define SOC_INT_STATUS_WDT_INT_MSB 0 +#define SOC_INT_STATUS_WDT_INT_LSB 0 +#define SOC_INT_STATUS_WDT_INT_MASK 0x00000001 +#define SOC_INT_STATUS_WDT_INT_GET(x) (((x) & SOC_INT_STATUS_WDT_INT_MASK) >> SOC_INT_STATUS_WDT_INT_LSB) +#define SOC_INT_STATUS_WDT_INT_SET(x) (((x) << SOC_INT_STATUS_WDT_INT_LSB) & SOC_INT_STATUS_WDT_INT_MASK) + +#define SOC_LF_TIMER0_ADDRESS 0x00000048 +#define SOC_LF_TIMER0_OFFSET 0x00000048 +#define SOC_LF_TIMER0_TARGET_MSB 31 +#define SOC_LF_TIMER0_TARGET_LSB 0 +#define SOC_LF_TIMER0_TARGET_MASK 0xffffffff +#define SOC_LF_TIMER0_TARGET_GET(x) (((x) & SOC_LF_TIMER0_TARGET_MASK) >> SOC_LF_TIMER0_TARGET_LSB) +#define SOC_LF_TIMER0_TARGET_SET(x) (((x) << SOC_LF_TIMER0_TARGET_LSB) & SOC_LF_TIMER0_TARGET_MASK) + +#define SOC_LF_TIMER_COUNT0_ADDRESS 0x0000004c +#define SOC_LF_TIMER_COUNT0_OFFSET 0x0000004c +#define SOC_LF_TIMER_COUNT0_VALUE_MSB 31 +#define SOC_LF_TIMER_COUNT0_VALUE_LSB 0 +#define SOC_LF_TIMER_COUNT0_VALUE_MASK 0xffffffff +#define SOC_LF_TIMER_COUNT0_VALUE_GET(x) (((x) & SOC_LF_TIMER_COUNT0_VALUE_MASK) >> SOC_LF_TIMER_COUNT0_VALUE_LSB) +#define SOC_LF_TIMER_COUNT0_VALUE_SET(x) (((x) << SOC_LF_TIMER_COUNT0_VALUE_LSB) & SOC_LF_TIMER_COUNT0_VALUE_MASK) + +#define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define SOC_LF_TIMER_CONTROL0_OFFSET 0x00000050 +#define SOC_LF_TIMER_CONTROL0_ENABLE_MSB 2 +#define SOC_LF_TIMER_CONTROL0_ENABLE_LSB 2 +#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define SOC_LF_TIMER_CONTROL0_ENABLE_GET(x) (((x) & SOC_LF_TIMER_CONTROL0_ENABLE_MASK) >> SOC_LF_TIMER_CONTROL0_ENABLE_LSB) +#define SOC_LF_TIMER_CONTROL0_ENABLE_SET(x) (((x) << SOC_LF_TIMER_CONTROL0_ENABLE_LSB) & SOC_LF_TIMER_CONTROL0_ENABLE_MASK) +#define SOC_LF_TIMER_CONTROL0_AUTO_RESTART_MSB 1 +#define SOC_LF_TIMER_CONTROL0_AUTO_RESTART_LSB 1 +#define SOC_LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002 +#define SOC_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) (((x) & SOC_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> SOC_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) +#define SOC_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) (((x) << SOC_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & SOC_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) +#define SOC_LF_TIMER_CONTROL0_RESET_MSB 0 +#define SOC_LF_TIMER_CONTROL0_RESET_LSB 0 +#define SOC_LF_TIMER_CONTROL0_RESET_MASK 0x00000001 +#define SOC_LF_TIMER_CONTROL0_RESET_GET(x) (((x) & SOC_LF_TIMER_CONTROL0_RESET_MASK) >> SOC_LF_TIMER_CONTROL0_RESET_LSB) +#define SOC_LF_TIMER_CONTROL0_RESET_SET(x) (((x) << SOC_LF_TIMER_CONTROL0_RESET_LSB) & SOC_LF_TIMER_CONTROL0_RESET_MASK) + +#define SOC_LF_TIMER_STATUS0_ADDRESS 0x00000054 +#define SOC_LF_TIMER_STATUS0_OFFSET 0x00000054 +#define SOC_LF_TIMER_STATUS0_INTERRUPT_MSB 0 +#define SOC_LF_TIMER_STATUS0_INTERRUPT_LSB 0 +#define SOC_LF_TIMER_STATUS0_INTERRUPT_MASK 0x00000001 +#define SOC_LF_TIMER_STATUS0_INTERRUPT_GET(x) (((x) & SOC_LF_TIMER_STATUS0_INTERRUPT_MASK) >> SOC_LF_TIMER_STATUS0_INTERRUPT_LSB) +#define SOC_LF_TIMER_STATUS0_INTERRUPT_SET(x) (((x) << SOC_LF_TIMER_STATUS0_INTERRUPT_LSB) & SOC_LF_TIMER_STATUS0_INTERRUPT_MASK) + +#define SOC_LF_TIMER1_ADDRESS 0x00000058 +#define SOC_LF_TIMER1_OFFSET 0x00000058 +#define SOC_LF_TIMER1_TARGET_MSB 31 +#define SOC_LF_TIMER1_TARGET_LSB 0 +#define SOC_LF_TIMER1_TARGET_MASK 0xffffffff +#define SOC_LF_TIMER1_TARGET_GET(x) (((x) & SOC_LF_TIMER1_TARGET_MASK) >> SOC_LF_TIMER1_TARGET_LSB) +#define SOC_LF_TIMER1_TARGET_SET(x) (((x) << SOC_LF_TIMER1_TARGET_LSB) & SOC_LF_TIMER1_TARGET_MASK) + +#define SOC_LF_TIMER_COUNT1_ADDRESS 0x0000005c +#define SOC_LF_TIMER_COUNT1_OFFSET 0x0000005c +#define SOC_LF_TIMER_COUNT1_VALUE_MSB 31 +#define SOC_LF_TIMER_COUNT1_VALUE_LSB 0 +#define SOC_LF_TIMER_COUNT1_VALUE_MASK 0xffffffff +#define SOC_LF_TIMER_COUNT1_VALUE_GET(x) (((x) & SOC_LF_TIMER_COUNT1_VALUE_MASK) >> SOC_LF_TIMER_COUNT1_VALUE_LSB) +#define SOC_LF_TIMER_COUNT1_VALUE_SET(x) (((x) << SOC_LF_TIMER_COUNT1_VALUE_LSB) & SOC_LF_TIMER_COUNT1_VALUE_MASK) + +#define SOC_LF_TIMER_CONTROL1_ADDRESS 0x00000060 +#define SOC_LF_TIMER_CONTROL1_OFFSET 0x00000060 +#define SOC_LF_TIMER_CONTROL1_ENABLE_MSB 2 +#define SOC_LF_TIMER_CONTROL1_ENABLE_LSB 2 +#define SOC_LF_TIMER_CONTROL1_ENABLE_MASK 0x00000004 +#define SOC_LF_TIMER_CONTROL1_ENABLE_GET(x) (((x) & SOC_LF_TIMER_CONTROL1_ENABLE_MASK) >> SOC_LF_TIMER_CONTROL1_ENABLE_LSB) +#define SOC_LF_TIMER_CONTROL1_ENABLE_SET(x) (((x) << SOC_LF_TIMER_CONTROL1_ENABLE_LSB) & SOC_LF_TIMER_CONTROL1_ENABLE_MASK) +#define SOC_LF_TIMER_CONTROL1_AUTO_RESTART_MSB 1 +#define SOC_LF_TIMER_CONTROL1_AUTO_RESTART_LSB 1 +#define SOC_LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002 +#define SOC_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) (((x) & SOC_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> SOC_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) +#define SOC_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) (((x) << SOC_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & SOC_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) +#define SOC_LF_TIMER_CONTROL1_RESET_MSB 0 +#define SOC_LF_TIMER_CONTROL1_RESET_LSB 0 +#define SOC_LF_TIMER_CONTROL1_RESET_MASK 0x00000001 +#define SOC_LF_TIMER_CONTROL1_RESET_GET(x) (((x) & SOC_LF_TIMER_CONTROL1_RESET_MASK) >> SOC_LF_TIMER_CONTROL1_RESET_LSB) +#define SOC_LF_TIMER_CONTROL1_RESET_SET(x) (((x) << SOC_LF_TIMER_CONTROL1_RESET_LSB) & SOC_LF_TIMER_CONTROL1_RESET_MASK) + +#define SOC_LF_TIMER_STATUS1_ADDRESS 0x00000064 +#define SOC_LF_TIMER_STATUS1_OFFSET 0x00000064 +#define SOC_LF_TIMER_STATUS1_INTERRUPT_MSB 0 +#define SOC_LF_TIMER_STATUS1_INTERRUPT_LSB 0 +#define SOC_LF_TIMER_STATUS1_INTERRUPT_MASK 0x00000001 +#define SOC_LF_TIMER_STATUS1_INTERRUPT_GET(x) (((x) & SOC_LF_TIMER_STATUS1_INTERRUPT_MASK) >> SOC_LF_TIMER_STATUS1_INTERRUPT_LSB) +#define SOC_LF_TIMER_STATUS1_INTERRUPT_SET(x) (((x) << SOC_LF_TIMER_STATUS1_INTERRUPT_LSB) & SOC_LF_TIMER_STATUS1_INTERRUPT_MASK) + +#define SOC_LF_TIMER2_ADDRESS 0x00000068 +#define SOC_LF_TIMER2_OFFSET 0x00000068 +#define SOC_LF_TIMER2_TARGET_MSB 31 +#define SOC_LF_TIMER2_TARGET_LSB 0 +#define SOC_LF_TIMER2_TARGET_MASK 0xffffffff +#define SOC_LF_TIMER2_TARGET_GET(x) (((x) & SOC_LF_TIMER2_TARGET_MASK) >> SOC_LF_TIMER2_TARGET_LSB) +#define SOC_LF_TIMER2_TARGET_SET(x) (((x) << SOC_LF_TIMER2_TARGET_LSB) & SOC_LF_TIMER2_TARGET_MASK) + +#define SOC_LF_TIMER_COUNT2_ADDRESS 0x0000006c +#define SOC_LF_TIMER_COUNT2_OFFSET 0x0000006c +#define SOC_LF_TIMER_COUNT2_VALUE_MSB 31 +#define SOC_LF_TIMER_COUNT2_VALUE_LSB 0 +#define SOC_LF_TIMER_COUNT2_VALUE_MASK 0xffffffff +#define SOC_LF_TIMER_COUNT2_VALUE_GET(x) (((x) & SOC_LF_TIMER_COUNT2_VALUE_MASK) >> SOC_LF_TIMER_COUNT2_VALUE_LSB) +#define SOC_LF_TIMER_COUNT2_VALUE_SET(x) (((x) << SOC_LF_TIMER_COUNT2_VALUE_LSB) & SOC_LF_TIMER_COUNT2_VALUE_MASK) + +#define SOC_LF_TIMER_CONTROL2_ADDRESS 0x00000070 +#define SOC_LF_TIMER_CONTROL2_OFFSET 0x00000070 +#define SOC_LF_TIMER_CONTROL2_ENABLE_MSB 2 +#define SOC_LF_TIMER_CONTROL2_ENABLE_LSB 2 +#define SOC_LF_TIMER_CONTROL2_ENABLE_MASK 0x00000004 +#define SOC_LF_TIMER_CONTROL2_ENABLE_GET(x) (((x) & SOC_LF_TIMER_CONTROL2_ENABLE_MASK) >> SOC_LF_TIMER_CONTROL2_ENABLE_LSB) +#define SOC_LF_TIMER_CONTROL2_ENABLE_SET(x) (((x) << SOC_LF_TIMER_CONTROL2_ENABLE_LSB) & SOC_LF_TIMER_CONTROL2_ENABLE_MASK) +#define SOC_LF_TIMER_CONTROL2_AUTO_RESTART_MSB 1 +#define SOC_LF_TIMER_CONTROL2_AUTO_RESTART_LSB 1 +#define SOC_LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002 +#define SOC_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) (((x) & SOC_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> SOC_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) +#define SOC_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) (((x) << SOC_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & SOC_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) +#define SOC_LF_TIMER_CONTROL2_RESET_MSB 0 +#define SOC_LF_TIMER_CONTROL2_RESET_LSB 0 +#define SOC_LF_TIMER_CONTROL2_RESET_MASK 0x00000001 +#define SOC_LF_TIMER_CONTROL2_RESET_GET(x) (((x) & SOC_LF_TIMER_CONTROL2_RESET_MASK) >> SOC_LF_TIMER_CONTROL2_RESET_LSB) +#define SOC_LF_TIMER_CONTROL2_RESET_SET(x) (((x) << SOC_LF_TIMER_CONTROL2_RESET_LSB) & SOC_LF_TIMER_CONTROL2_RESET_MASK) + +#define SOC_LF_TIMER_STATUS2_ADDRESS 0x00000074 +#define SOC_LF_TIMER_STATUS2_OFFSET 0x00000074 +#define SOC_LF_TIMER_STATUS2_INTERRUPT_MSB 0 +#define SOC_LF_TIMER_STATUS2_INTERRUPT_LSB 0 +#define SOC_LF_TIMER_STATUS2_INTERRUPT_MASK 0x00000001 +#define SOC_LF_TIMER_STATUS2_INTERRUPT_GET(x) (((x) & SOC_LF_TIMER_STATUS2_INTERRUPT_MASK) >> SOC_LF_TIMER_STATUS2_INTERRUPT_LSB) +#define SOC_LF_TIMER_STATUS2_INTERRUPT_SET(x) (((x) << SOC_LF_TIMER_STATUS2_INTERRUPT_LSB) & SOC_LF_TIMER_STATUS2_INTERRUPT_MASK) + +#define SOC_LF_TIMER3_ADDRESS 0x00000078 +#define SOC_LF_TIMER3_OFFSET 0x00000078 +#define SOC_LF_TIMER3_TARGET_MSB 31 +#define SOC_LF_TIMER3_TARGET_LSB 0 +#define SOC_LF_TIMER3_TARGET_MASK 0xffffffff +#define SOC_LF_TIMER3_TARGET_GET(x) (((x) & SOC_LF_TIMER3_TARGET_MASK) >> SOC_LF_TIMER3_TARGET_LSB) +#define SOC_LF_TIMER3_TARGET_SET(x) (((x) << SOC_LF_TIMER3_TARGET_LSB) & SOC_LF_TIMER3_TARGET_MASK) + +#define SOC_LF_TIMER_COUNT3_ADDRESS 0x0000007c +#define SOC_LF_TIMER_COUNT3_OFFSET 0x0000007c +#define SOC_LF_TIMER_COUNT3_VALUE_MSB 31 +#define SOC_LF_TIMER_COUNT3_VALUE_LSB 0 +#define SOC_LF_TIMER_COUNT3_VALUE_MASK 0xffffffff +#define SOC_LF_TIMER_COUNT3_VALUE_GET(x) (((x) & SOC_LF_TIMER_COUNT3_VALUE_MASK) >> SOC_LF_TIMER_COUNT3_VALUE_LSB) +#define SOC_LF_TIMER_COUNT3_VALUE_SET(x) (((x) << SOC_LF_TIMER_COUNT3_VALUE_LSB) & SOC_LF_TIMER_COUNT3_VALUE_MASK) + +#define SOC_LF_TIMER_CONTROL3_ADDRESS 0x00000080 +#define SOC_LF_TIMER_CONTROL3_OFFSET 0x00000080 +#define SOC_LF_TIMER_CONTROL3_ENABLE_MSB 2 +#define SOC_LF_TIMER_CONTROL3_ENABLE_LSB 2 +#define SOC_LF_TIMER_CONTROL3_ENABLE_MASK 0x00000004 +#define SOC_LF_TIMER_CONTROL3_ENABLE_GET(x) (((x) & SOC_LF_TIMER_CONTROL3_ENABLE_MASK) >> SOC_LF_TIMER_CONTROL3_ENABLE_LSB) +#define SOC_LF_TIMER_CONTROL3_ENABLE_SET(x) (((x) << SOC_LF_TIMER_CONTROL3_ENABLE_LSB) & SOC_LF_TIMER_CONTROL3_ENABLE_MASK) +#define SOC_LF_TIMER_CONTROL3_AUTO_RESTART_MSB 1 +#define SOC_LF_TIMER_CONTROL3_AUTO_RESTART_LSB 1 +#define SOC_LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002 +#define SOC_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) (((x) & SOC_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> SOC_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) +#define SOC_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) (((x) << SOC_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & SOC_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) +#define SOC_LF_TIMER_CONTROL3_RESET_MSB 0 +#define SOC_LF_TIMER_CONTROL3_RESET_LSB 0 +#define SOC_LF_TIMER_CONTROL3_RESET_MASK 0x00000001 +#define SOC_LF_TIMER_CONTROL3_RESET_GET(x) (((x) & SOC_LF_TIMER_CONTROL3_RESET_MASK) >> SOC_LF_TIMER_CONTROL3_RESET_LSB) +#define SOC_LF_TIMER_CONTROL3_RESET_SET(x) (((x) << SOC_LF_TIMER_CONTROL3_RESET_LSB) & SOC_LF_TIMER_CONTROL3_RESET_MASK) + +#define SOC_LF_TIMER_STATUS3_ADDRESS 0x00000084 +#define SOC_LF_TIMER_STATUS3_OFFSET 0x00000084 +#define SOC_LF_TIMER_STATUS3_INTERRUPT_MSB 0 +#define SOC_LF_TIMER_STATUS3_INTERRUPT_LSB 0 +#define SOC_LF_TIMER_STATUS3_INTERRUPT_MASK 0x00000001 +#define SOC_LF_TIMER_STATUS3_INTERRUPT_GET(x) (((x) & SOC_LF_TIMER_STATUS3_INTERRUPT_MASK) >> SOC_LF_TIMER_STATUS3_INTERRUPT_LSB) +#define SOC_LF_TIMER_STATUS3_INTERRUPT_SET(x) (((x) << SOC_LF_TIMER_STATUS3_INTERRUPT_LSB) & SOC_LF_TIMER_STATUS3_INTERRUPT_MASK) + +#define SOC_HF_TIMER_ADDRESS 0x00000088 +#define SOC_HF_TIMER_OFFSET 0x00000088 +#define SOC_HF_TIMER_TARGET_MSB 31 +#define SOC_HF_TIMER_TARGET_LSB 12 +#define SOC_HF_TIMER_TARGET_MASK 0xfffff000 +#define SOC_HF_TIMER_TARGET_GET(x) (((x) & SOC_HF_TIMER_TARGET_MASK) >> SOC_HF_TIMER_TARGET_LSB) +#define SOC_HF_TIMER_TARGET_SET(x) (((x) << SOC_HF_TIMER_TARGET_LSB) & SOC_HF_TIMER_TARGET_MASK) + +#define SOC_HF_TIMER_COUNT_ADDRESS 0x0000008c +#define SOC_HF_TIMER_COUNT_OFFSET 0x0000008c +#define SOC_HF_TIMER_COUNT_VALUE_MSB 31 +#define SOC_HF_TIMER_COUNT_VALUE_LSB 12 +#define SOC_HF_TIMER_COUNT_VALUE_MASK 0xfffff000 +#define SOC_HF_TIMER_COUNT_VALUE_GET(x) (((x) & SOC_HF_TIMER_COUNT_VALUE_MASK) >> SOC_HF_TIMER_COUNT_VALUE_LSB) +#define SOC_HF_TIMER_COUNT_VALUE_SET(x) (((x) << SOC_HF_TIMER_COUNT_VALUE_LSB) & SOC_HF_TIMER_COUNT_VALUE_MASK) + +#define SOC_HF_LF_COUNT_ADDRESS 0x00000090 +#define SOC_HF_LF_COUNT_OFFSET 0x00000090 +#define SOC_HF_LF_COUNT_VALUE_MSB 31 +#define SOC_HF_LF_COUNT_VALUE_LSB 0 +#define SOC_HF_LF_COUNT_VALUE_MASK 0xffffffff +#define SOC_HF_LF_COUNT_VALUE_GET(x) (((x) & SOC_HF_LF_COUNT_VALUE_MASK) >> SOC_HF_LF_COUNT_VALUE_LSB) +#define SOC_HF_LF_COUNT_VALUE_SET(x) (((x) << SOC_HF_LF_COUNT_VALUE_LSB) & SOC_HF_LF_COUNT_VALUE_MASK) + +#define SOC_HF_TIMER_CONTROL_ADDRESS 0x00000094 +#define SOC_HF_TIMER_CONTROL_OFFSET 0x00000094 +#define SOC_HF_TIMER_CONTROL_ENABLE_MSB 3 +#define SOC_HF_TIMER_CONTROL_ENABLE_LSB 3 +#define SOC_HF_TIMER_CONTROL_ENABLE_MASK 0x00000008 +#define SOC_HF_TIMER_CONTROL_ENABLE_GET(x) (((x) & SOC_HF_TIMER_CONTROL_ENABLE_MASK) >> SOC_HF_TIMER_CONTROL_ENABLE_LSB) +#define SOC_HF_TIMER_CONTROL_ENABLE_SET(x) (((x) << SOC_HF_TIMER_CONTROL_ENABLE_LSB) & SOC_HF_TIMER_CONTROL_ENABLE_MASK) +#define SOC_HF_TIMER_CONTROL_ON_MSB 2 +#define SOC_HF_TIMER_CONTROL_ON_LSB 2 +#define SOC_HF_TIMER_CONTROL_ON_MASK 0x00000004 +#define SOC_HF_TIMER_CONTROL_ON_GET(x) (((x) & SOC_HF_TIMER_CONTROL_ON_MASK) >> SOC_HF_TIMER_CONTROL_ON_LSB) +#define SOC_HF_TIMER_CONTROL_ON_SET(x) (((x) << SOC_HF_TIMER_CONTROL_ON_LSB) & SOC_HF_TIMER_CONTROL_ON_MASK) +#define SOC_HF_TIMER_CONTROL_AUTO_RESTART_MSB 1 +#define SOC_HF_TIMER_CONTROL_AUTO_RESTART_LSB 1 +#define SOC_HF_TIMER_CONTROL_AUTO_RESTART_MASK 0x00000002 +#define SOC_HF_TIMER_CONTROL_AUTO_RESTART_GET(x) (((x) & SOC_HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> SOC_HF_TIMER_CONTROL_AUTO_RESTART_LSB) +#define SOC_HF_TIMER_CONTROL_AUTO_RESTART_SET(x) (((x) << SOC_HF_TIMER_CONTROL_AUTO_RESTART_LSB) & SOC_HF_TIMER_CONTROL_AUTO_RESTART_MASK) +#define SOC_HF_TIMER_CONTROL_RESET_MSB 0 +#define SOC_HF_TIMER_CONTROL_RESET_LSB 0 +#define SOC_HF_TIMER_CONTROL_RESET_MASK 0x00000001 +#define SOC_HF_TIMER_CONTROL_RESET_GET(x) (((x) & SOC_HF_TIMER_CONTROL_RESET_MASK) >> SOC_HF_TIMER_CONTROL_RESET_LSB) +#define SOC_HF_TIMER_CONTROL_RESET_SET(x) (((x) << SOC_HF_TIMER_CONTROL_RESET_LSB) & SOC_HF_TIMER_CONTROL_RESET_MASK) + +#define SOC_HF_TIMER_STATUS_ADDRESS 0x00000098 +#define SOC_HF_TIMER_STATUS_OFFSET 0x00000098 +#define SOC_HF_TIMER_STATUS_INTERRUPT_MSB 0 +#define SOC_HF_TIMER_STATUS_INTERRUPT_LSB 0 +#define SOC_HF_TIMER_STATUS_INTERRUPT_MASK 0x00000001 +#define SOC_HF_TIMER_STATUS_INTERRUPT_GET(x) (((x) & SOC_HF_TIMER_STATUS_INTERRUPT_MASK) >> SOC_HF_TIMER_STATUS_INTERRUPT_LSB) +#define SOC_HF_TIMER_STATUS_INTERRUPT_SET(x) (((x) << SOC_HF_TIMER_STATUS_INTERRUPT_LSB) & SOC_HF_TIMER_STATUS_INTERRUPT_MASK) + +#define SOC_RTC_CONTROL_ADDRESS 0x0000009c +#define SOC_RTC_CONTROL_OFFSET 0x0000009c +#define SOC_RTC_CONTROL_ENABLE_MSB 2 +#define SOC_RTC_CONTROL_ENABLE_LSB 2 +#define SOC_RTC_CONTROL_ENABLE_MASK 0x00000004 +#define SOC_RTC_CONTROL_ENABLE_GET(x) (((x) & SOC_RTC_CONTROL_ENABLE_MASK) >> SOC_RTC_CONTROL_ENABLE_LSB) +#define SOC_RTC_CONTROL_ENABLE_SET(x) (((x) << SOC_RTC_CONTROL_ENABLE_LSB) & SOC_RTC_CONTROL_ENABLE_MASK) +#define SOC_RTC_CONTROL_LOAD_RTC_MSB 1 +#define SOC_RTC_CONTROL_LOAD_RTC_LSB 1 +#define SOC_RTC_CONTROL_LOAD_RTC_MASK 0x00000002 +#define SOC_RTC_CONTROL_LOAD_RTC_GET(x) (((x) & SOC_RTC_CONTROL_LOAD_RTC_MASK) >> SOC_RTC_CONTROL_LOAD_RTC_LSB) +#define SOC_RTC_CONTROL_LOAD_RTC_SET(x) (((x) << SOC_RTC_CONTROL_LOAD_RTC_LSB) & SOC_RTC_CONTROL_LOAD_RTC_MASK) +#define SOC_RTC_CONTROL_LOAD_ALARM_MSB 0 +#define SOC_RTC_CONTROL_LOAD_ALARM_LSB 0 +#define SOC_RTC_CONTROL_LOAD_ALARM_MASK 0x00000001 +#define SOC_RTC_CONTROL_LOAD_ALARM_GET(x) (((x) & SOC_RTC_CONTROL_LOAD_ALARM_MASK) >> SOC_RTC_CONTROL_LOAD_ALARM_LSB) +#define SOC_RTC_CONTROL_LOAD_ALARM_SET(x) (((x) << SOC_RTC_CONTROL_LOAD_ALARM_LSB) & SOC_RTC_CONTROL_LOAD_ALARM_MASK) + +#define SOC_RTC_TIME_ADDRESS 0x000000a0 +#define SOC_RTC_TIME_OFFSET 0x000000a0 +#define SOC_RTC_TIME_WEEK_DAY_MSB 26 +#define SOC_RTC_TIME_WEEK_DAY_LSB 24 +#define SOC_RTC_TIME_WEEK_DAY_MASK 0x07000000 +#define SOC_RTC_TIME_WEEK_DAY_GET(x) (((x) & SOC_RTC_TIME_WEEK_DAY_MASK) >> SOC_RTC_TIME_WEEK_DAY_LSB) +#define SOC_RTC_TIME_WEEK_DAY_SET(x) (((x) << SOC_RTC_TIME_WEEK_DAY_LSB) & SOC_RTC_TIME_WEEK_DAY_MASK) +#define SOC_RTC_TIME_HOUR_MSB 21 +#define SOC_RTC_TIME_HOUR_LSB 16 +#define SOC_RTC_TIME_HOUR_MASK 0x003f0000 +#define SOC_RTC_TIME_HOUR_GET(x) (((x) & SOC_RTC_TIME_HOUR_MASK) >> SOC_RTC_TIME_HOUR_LSB) +#define SOC_RTC_TIME_HOUR_SET(x) (((x) << SOC_RTC_TIME_HOUR_LSB) & SOC_RTC_TIME_HOUR_MASK) +#define SOC_RTC_TIME_MINUTE_MSB 14 +#define SOC_RTC_TIME_MINUTE_LSB 8 +#define SOC_RTC_TIME_MINUTE_MASK 0x00007f00 +#define SOC_RTC_TIME_MINUTE_GET(x) (((x) & SOC_RTC_TIME_MINUTE_MASK) >> SOC_RTC_TIME_MINUTE_LSB) +#define SOC_RTC_TIME_MINUTE_SET(x) (((x) << SOC_RTC_TIME_MINUTE_LSB) & SOC_RTC_TIME_MINUTE_MASK) +#define SOC_RTC_TIME_SECOND_MSB 6 +#define SOC_RTC_TIME_SECOND_LSB 0 +#define SOC_RTC_TIME_SECOND_MASK 0x0000007f +#define SOC_RTC_TIME_SECOND_GET(x) (((x) & SOC_RTC_TIME_SECOND_MASK) >> SOC_RTC_TIME_SECOND_LSB) +#define SOC_RTC_TIME_SECOND_SET(x) (((x) << SOC_RTC_TIME_SECOND_LSB) & SOC_RTC_TIME_SECOND_MASK) + +#define SOC_RTC_DATE_ADDRESS 0x000000a4 +#define SOC_RTC_DATE_OFFSET 0x000000a4 +#define SOC_RTC_DATE_YEAR_MSB 23 +#define SOC_RTC_DATE_YEAR_LSB 16 +#define SOC_RTC_DATE_YEAR_MASK 0x00ff0000 +#define SOC_RTC_DATE_YEAR_GET(x) (((x) & SOC_RTC_DATE_YEAR_MASK) >> SOC_RTC_DATE_YEAR_LSB) +#define SOC_RTC_DATE_YEAR_SET(x) (((x) << SOC_RTC_DATE_YEAR_LSB) & SOC_RTC_DATE_YEAR_MASK) +#define SOC_RTC_DATE_MONTH_MSB 12 +#define SOC_RTC_DATE_MONTH_LSB 8 +#define SOC_RTC_DATE_MONTH_MASK 0x00001f00 +#define SOC_RTC_DATE_MONTH_GET(x) (((x) & SOC_RTC_DATE_MONTH_MASK) >> SOC_RTC_DATE_MONTH_LSB) +#define SOC_RTC_DATE_MONTH_SET(x) (((x) << SOC_RTC_DATE_MONTH_LSB) & SOC_RTC_DATE_MONTH_MASK) +#define SOC_RTC_DATE_MONTH_DAY_MSB 5 +#define SOC_RTC_DATE_MONTH_DAY_LSB 0 +#define SOC_RTC_DATE_MONTH_DAY_MASK 0x0000003f +#define SOC_RTC_DATE_MONTH_DAY_GET(x) (((x) & SOC_RTC_DATE_MONTH_DAY_MASK) >> SOC_RTC_DATE_MONTH_DAY_LSB) +#define SOC_RTC_DATE_MONTH_DAY_SET(x) (((x) << SOC_RTC_DATE_MONTH_DAY_LSB) & SOC_RTC_DATE_MONTH_DAY_MASK) + +#define SOC_RTC_SET_TIME_ADDRESS 0x000000a8 +#define SOC_RTC_SET_TIME_OFFSET 0x000000a8 +#define SOC_RTC_SET_TIME_WEEK_DAY_MSB 26 +#define SOC_RTC_SET_TIME_WEEK_DAY_LSB 24 +#define SOC_RTC_SET_TIME_WEEK_DAY_MASK 0x07000000 +#define SOC_RTC_SET_TIME_WEEK_DAY_GET(x) (((x) & SOC_RTC_SET_TIME_WEEK_DAY_MASK) >> SOC_RTC_SET_TIME_WEEK_DAY_LSB) +#define SOC_RTC_SET_TIME_WEEK_DAY_SET(x) (((x) << SOC_RTC_SET_TIME_WEEK_DAY_LSB) & SOC_RTC_SET_TIME_WEEK_DAY_MASK) +#define SOC_RTC_SET_TIME_HOUR_MSB 21 +#define SOC_RTC_SET_TIME_HOUR_LSB 16 +#define SOC_RTC_SET_TIME_HOUR_MASK 0x003f0000 +#define SOC_RTC_SET_TIME_HOUR_GET(x) (((x) & SOC_RTC_SET_TIME_HOUR_MASK) >> SOC_RTC_SET_TIME_HOUR_LSB) +#define SOC_RTC_SET_TIME_HOUR_SET(x) (((x) << SOC_RTC_SET_TIME_HOUR_LSB) & SOC_RTC_SET_TIME_HOUR_MASK) +#define SOC_RTC_SET_TIME_MINUTE_MSB 14 +#define SOC_RTC_SET_TIME_MINUTE_LSB 8 +#define SOC_RTC_SET_TIME_MINUTE_MASK 0x00007f00 +#define SOC_RTC_SET_TIME_MINUTE_GET(x) (((x) & SOC_RTC_SET_TIME_MINUTE_MASK) >> SOC_RTC_SET_TIME_MINUTE_LSB) +#define SOC_RTC_SET_TIME_MINUTE_SET(x) (((x) << SOC_RTC_SET_TIME_MINUTE_LSB) & SOC_RTC_SET_TIME_MINUTE_MASK) +#define SOC_RTC_SET_TIME_SECOND_MSB 6 +#define SOC_RTC_SET_TIME_SECOND_LSB 0 +#define SOC_RTC_SET_TIME_SECOND_MASK 0x0000007f +#define SOC_RTC_SET_TIME_SECOND_GET(x) (((x) & SOC_RTC_SET_TIME_SECOND_MASK) >> SOC_RTC_SET_TIME_SECOND_LSB) +#define SOC_RTC_SET_TIME_SECOND_SET(x) (((x) << SOC_RTC_SET_TIME_SECOND_LSB) & SOC_RTC_SET_TIME_SECOND_MASK) + +#define SOC_RTC_SET_DATE_ADDRESS 0x000000ac +#define SOC_RTC_SET_DATE_OFFSET 0x000000ac +#define SOC_RTC_SET_DATE_YEAR_MSB 23 +#define SOC_RTC_SET_DATE_YEAR_LSB 16 +#define SOC_RTC_SET_DATE_YEAR_MASK 0x00ff0000 +#define SOC_RTC_SET_DATE_YEAR_GET(x) (((x) & SOC_RTC_SET_DATE_YEAR_MASK) >> SOC_RTC_SET_DATE_YEAR_LSB) +#define SOC_RTC_SET_DATE_YEAR_SET(x) (((x) << SOC_RTC_SET_DATE_YEAR_LSB) & SOC_RTC_SET_DATE_YEAR_MASK) +#define SOC_RTC_SET_DATE_MONTH_MSB 12 +#define SOC_RTC_SET_DATE_MONTH_LSB 8 +#define SOC_RTC_SET_DATE_MONTH_MASK 0x00001f00 +#define SOC_RTC_SET_DATE_MONTH_GET(x) (((x) & SOC_RTC_SET_DATE_MONTH_MASK) >> SOC_RTC_SET_DATE_MONTH_LSB) +#define SOC_RTC_SET_DATE_MONTH_SET(x) (((x) << SOC_RTC_SET_DATE_MONTH_LSB) & SOC_RTC_SET_DATE_MONTH_MASK) +#define SOC_RTC_SET_DATE_MONTH_DAY_MSB 5 +#define SOC_RTC_SET_DATE_MONTH_DAY_LSB 0 +#define SOC_RTC_SET_DATE_MONTH_DAY_MASK 0x0000003f +#define SOC_RTC_SET_DATE_MONTH_DAY_GET(x) (((x) & SOC_RTC_SET_DATE_MONTH_DAY_MASK) >> SOC_RTC_SET_DATE_MONTH_DAY_LSB) +#define SOC_RTC_SET_DATE_MONTH_DAY_SET(x) (((x) << SOC_RTC_SET_DATE_MONTH_DAY_LSB) & SOC_RTC_SET_DATE_MONTH_DAY_MASK) + +#define SOC_RTC_SET_ALARM_ADDRESS 0x000000b0 +#define SOC_RTC_SET_ALARM_OFFSET 0x000000b0 +#define SOC_RTC_SET_ALARM_HOUR_MSB 21 +#define SOC_RTC_SET_ALARM_HOUR_LSB 16 +#define SOC_RTC_SET_ALARM_HOUR_MASK 0x003f0000 +#define SOC_RTC_SET_ALARM_HOUR_GET(x) (((x) & SOC_RTC_SET_ALARM_HOUR_MASK) >> SOC_RTC_SET_ALARM_HOUR_LSB) +#define SOC_RTC_SET_ALARM_HOUR_SET(x) (((x) << SOC_RTC_SET_ALARM_HOUR_LSB) & SOC_RTC_SET_ALARM_HOUR_MASK) +#define SOC_RTC_SET_ALARM_MINUTE_MSB 14 +#define SOC_RTC_SET_ALARM_MINUTE_LSB 8 +#define SOC_RTC_SET_ALARM_MINUTE_MASK 0x00007f00 +#define SOC_RTC_SET_ALARM_MINUTE_GET(x) (((x) & SOC_RTC_SET_ALARM_MINUTE_MASK) >> SOC_RTC_SET_ALARM_MINUTE_LSB) +#define SOC_RTC_SET_ALARM_MINUTE_SET(x) (((x) << SOC_RTC_SET_ALARM_MINUTE_LSB) & SOC_RTC_SET_ALARM_MINUTE_MASK) +#define SOC_RTC_SET_ALARM_SECOND_MSB 6 +#define SOC_RTC_SET_ALARM_SECOND_LSB 0 +#define SOC_RTC_SET_ALARM_SECOND_MASK 0x0000007f +#define SOC_RTC_SET_ALARM_SECOND_GET(x) (((x) & SOC_RTC_SET_ALARM_SECOND_MASK) >> SOC_RTC_SET_ALARM_SECOND_LSB) +#define SOC_RTC_SET_ALARM_SECOND_SET(x) (((x) << SOC_RTC_SET_ALARM_SECOND_LSB) & SOC_RTC_SET_ALARM_SECOND_MASK) + +#define SOC_RTC_CONFIG_ADDRESS 0x000000b4 +#define SOC_RTC_CONFIG_OFFSET 0x000000b4 +#define SOC_RTC_CONFIG_BCD_MSB 2 +#define SOC_RTC_CONFIG_BCD_LSB 2 +#define SOC_RTC_CONFIG_BCD_MASK 0x00000004 +#define SOC_RTC_CONFIG_BCD_GET(x) (((x) & SOC_RTC_CONFIG_BCD_MASK) >> SOC_RTC_CONFIG_BCD_LSB) +#define SOC_RTC_CONFIG_BCD_SET(x) (((x) << SOC_RTC_CONFIG_BCD_LSB) & SOC_RTC_CONFIG_BCD_MASK) +#define SOC_RTC_CONFIG_TWELVE_HOUR_MSB 1 +#define SOC_RTC_CONFIG_TWELVE_HOUR_LSB 1 +#define SOC_RTC_CONFIG_TWELVE_HOUR_MASK 0x00000002 +#define SOC_RTC_CONFIG_TWELVE_HOUR_GET(x) (((x) & SOC_RTC_CONFIG_TWELVE_HOUR_MASK) >> SOC_RTC_CONFIG_TWELVE_HOUR_LSB) +#define SOC_RTC_CONFIG_TWELVE_HOUR_SET(x) (((x) << SOC_RTC_CONFIG_TWELVE_HOUR_LSB) & SOC_RTC_CONFIG_TWELVE_HOUR_MASK) +#define SOC_RTC_CONFIG_DSE_MSB 0 +#define SOC_RTC_CONFIG_DSE_LSB 0 +#define SOC_RTC_CONFIG_DSE_MASK 0x00000001 +#define SOC_RTC_CONFIG_DSE_GET(x) (((x) & SOC_RTC_CONFIG_DSE_MASK) >> SOC_RTC_CONFIG_DSE_LSB) +#define SOC_RTC_CONFIG_DSE_SET(x) (((x) << SOC_RTC_CONFIG_DSE_LSB) & SOC_RTC_CONFIG_DSE_MASK) + +#define SOC_RTC_ALARM_STATUS_ADDRESS 0x000000b8 +#define SOC_RTC_ALARM_STATUS_OFFSET 0x000000b8 +#define SOC_RTC_ALARM_STATUS_ENABLE_MSB 1 +#define SOC_RTC_ALARM_STATUS_ENABLE_LSB 1 +#define SOC_RTC_ALARM_STATUS_ENABLE_MASK 0x00000002 +#define SOC_RTC_ALARM_STATUS_ENABLE_GET(x) (((x) & SOC_RTC_ALARM_STATUS_ENABLE_MASK) >> SOC_RTC_ALARM_STATUS_ENABLE_LSB) +#define SOC_RTC_ALARM_STATUS_ENABLE_SET(x) (((x) << SOC_RTC_ALARM_STATUS_ENABLE_LSB) & SOC_RTC_ALARM_STATUS_ENABLE_MASK) +#define SOC_RTC_ALARM_STATUS_INTERRUPT_MSB 0 +#define SOC_RTC_ALARM_STATUS_INTERRUPT_LSB 0 +#define SOC_RTC_ALARM_STATUS_INTERRUPT_MASK 0x00000001 +#define SOC_RTC_ALARM_STATUS_INTERRUPT_GET(x) (((x) & SOC_RTC_ALARM_STATUS_INTERRUPT_MASK) >> SOC_RTC_ALARM_STATUS_INTERRUPT_LSB) +#define SOC_RTC_ALARM_STATUS_INTERRUPT_SET(x) (((x) << SOC_RTC_ALARM_STATUS_INTERRUPT_LSB) & SOC_RTC_ALARM_STATUS_INTERRUPT_MASK) + +#define SOC_UART_WAKEUP_ADDRESS 0x000000bc +#define SOC_UART_WAKEUP_OFFSET 0x000000bc +#define SOC_UART_WAKEUP_ENABLE_MSB 0 +#define SOC_UART_WAKEUP_ENABLE_LSB 0 +#define SOC_UART_WAKEUP_ENABLE_MASK 0x00000001 +#define SOC_UART_WAKEUP_ENABLE_GET(x) (((x) & SOC_UART_WAKEUP_ENABLE_MASK) >> SOC_UART_WAKEUP_ENABLE_LSB) +#define SOC_UART_WAKEUP_ENABLE_SET(x) (((x) << SOC_UART_WAKEUP_ENABLE_LSB) & SOC_UART_WAKEUP_ENABLE_MASK) + +#define SOC_RESET_CAUSE_ADDRESS 0x000000c0 +#define SOC_RESET_CAUSE_OFFSET 0x000000c0 +#define SOC_RESET_CAUSE_LAST_MSB 2 +#define SOC_RESET_CAUSE_LAST_LSB 0 +#define SOC_RESET_CAUSE_LAST_MASK 0x00000007 +#define SOC_RESET_CAUSE_LAST_GET(x) (((x) & SOC_RESET_CAUSE_LAST_MASK) >> SOC_RESET_CAUSE_LAST_LSB) +#define SOC_RESET_CAUSE_LAST_SET(x) (((x) << SOC_RESET_CAUSE_LAST_LSB) & SOC_RESET_CAUSE_LAST_MASK) + +#define SOC_SYSTEM_SLEEP_ADDRESS 0x000000c4 +#define SOC_SYSTEM_SLEEP_OFFSET 0x000000c4 +#define SOC_SYSTEM_SLEEP_MCI_MSB 5 +#define SOC_SYSTEM_SLEEP_MCI_LSB 5 +#define SOC_SYSTEM_SLEEP_MCI_MASK 0x00000020 +#define SOC_SYSTEM_SLEEP_MCI_GET(x) (((x) & SOC_SYSTEM_SLEEP_MCI_MASK) >> SOC_SYSTEM_SLEEP_MCI_LSB) +#define SOC_SYSTEM_SLEEP_MCI_SET(x) (((x) << SOC_SYSTEM_SLEEP_MCI_LSB) & SOC_SYSTEM_SLEEP_MCI_MASK) +#define SOC_SYSTEM_SLEEP_HOST_IF_MSB 4 +#define SOC_SYSTEM_SLEEP_HOST_IF_LSB 4 +#define SOC_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010 +#define SOC_SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & SOC_SYSTEM_SLEEP_HOST_IF_MASK) >> SOC_SYSTEM_SLEEP_HOST_IF_LSB) +#define SOC_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << SOC_SYSTEM_SLEEP_HOST_IF_LSB) & SOC_SYSTEM_SLEEP_HOST_IF_MASK) +#define SOC_SYSTEM_SLEEP_MBOX_MSB 3 +#define SOC_SYSTEM_SLEEP_MBOX_LSB 3 +#define SOC_SYSTEM_SLEEP_MBOX_MASK 0x00000008 +#define SOC_SYSTEM_SLEEP_MBOX_GET(x) (((x) & SOC_SYSTEM_SLEEP_MBOX_MASK) >> SOC_SYSTEM_SLEEP_MBOX_LSB) +#define SOC_SYSTEM_SLEEP_MBOX_SET(x) (((x) << SOC_SYSTEM_SLEEP_MBOX_LSB) & SOC_SYSTEM_SLEEP_MBOX_MASK) +#define SOC_SYSTEM_SLEEP_MAC_IF_MSB 2 +#define SOC_SYSTEM_SLEEP_MAC_IF_LSB 2 +#define SOC_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004 +#define SOC_SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & SOC_SYSTEM_SLEEP_MAC_IF_MASK) >> SOC_SYSTEM_SLEEP_MAC_IF_LSB) +#define SOC_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << SOC_SYSTEM_SLEEP_MAC_IF_LSB) & SOC_SYSTEM_SLEEP_MAC_IF_MASK) +#define SOC_SYSTEM_SLEEP_LIGHT_MSB 1 +#define SOC_SYSTEM_SLEEP_LIGHT_LSB 1 +#define SOC_SYSTEM_SLEEP_LIGHT_MASK 0x00000002 +#define SOC_SYSTEM_SLEEP_LIGHT_GET(x) (((x) & SOC_SYSTEM_SLEEP_LIGHT_MASK) >> SOC_SYSTEM_SLEEP_LIGHT_LSB) +#define SOC_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << SOC_SYSTEM_SLEEP_LIGHT_LSB) & SOC_SYSTEM_SLEEP_LIGHT_MASK) +#define SOC_SYSTEM_SLEEP_DISABLE_MSB 0 +#define SOC_SYSTEM_SLEEP_DISABLE_LSB 0 +#define SOC_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define SOC_SYSTEM_SLEEP_DISABLE_GET(x) (((x) & SOC_SYSTEM_SLEEP_DISABLE_MASK) >> SOC_SYSTEM_SLEEP_DISABLE_LSB) +#define SOC_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << SOC_SYSTEM_SLEEP_DISABLE_LSB) & SOC_SYSTEM_SLEEP_DISABLE_MASK) + +#define SOC_SDIO_WRAPPER_ADDRESS 0x000000c8 +#define SOC_SDIO_WRAPPER_OFFSET 0x000000c8 +#define SOC_SDIO_WRAPPER_SLEEP_MSB 3 +#define SOC_SDIO_WRAPPER_SLEEP_LSB 3 +#define SOC_SDIO_WRAPPER_SLEEP_MASK 0x00000008 +#define SOC_SDIO_WRAPPER_SLEEP_GET(x) (((x) & SOC_SDIO_WRAPPER_SLEEP_MASK) >> SOC_SDIO_WRAPPER_SLEEP_LSB) +#define SOC_SDIO_WRAPPER_SLEEP_SET(x) (((x) << SOC_SDIO_WRAPPER_SLEEP_LSB) & SOC_SDIO_WRAPPER_SLEEP_MASK) +#define SOC_SDIO_WRAPPER_WAKEUP_MSB 2 +#define SOC_SDIO_WRAPPER_WAKEUP_LSB 2 +#define SOC_SDIO_WRAPPER_WAKEUP_MASK 0x00000004 +#define SOC_SDIO_WRAPPER_WAKEUP_GET(x) (((x) & SOC_SDIO_WRAPPER_WAKEUP_MASK) >> SOC_SDIO_WRAPPER_WAKEUP_LSB) +#define SOC_SDIO_WRAPPER_WAKEUP_SET(x) (((x) << SOC_SDIO_WRAPPER_WAKEUP_LSB) & SOC_SDIO_WRAPPER_WAKEUP_MASK) +#define SOC_SDIO_WRAPPER_SOC_ON_MSB 1 +#define SOC_SDIO_WRAPPER_SOC_ON_LSB 1 +#define SOC_SDIO_WRAPPER_SOC_ON_MASK 0x00000002 +#define SOC_SDIO_WRAPPER_SOC_ON_GET(x) (((x) & SOC_SDIO_WRAPPER_SOC_ON_MASK) >> SOC_SDIO_WRAPPER_SOC_ON_LSB) +#define SOC_SDIO_WRAPPER_SOC_ON_SET(x) (((x) << SOC_SDIO_WRAPPER_SOC_ON_LSB) & SOC_SDIO_WRAPPER_SOC_ON_MASK) +#define SOC_SDIO_WRAPPER_ON_MSB 0 +#define SOC_SDIO_WRAPPER_ON_LSB 0 +#define SOC_SDIO_WRAPPER_ON_MASK 0x00000001 +#define SOC_SDIO_WRAPPER_ON_GET(x) (((x) & SOC_SDIO_WRAPPER_ON_MASK) >> SOC_SDIO_WRAPPER_ON_LSB) +#define SOC_SDIO_WRAPPER_ON_SET(x) (((x) << SOC_SDIO_WRAPPER_ON_LSB) & SOC_SDIO_WRAPPER_ON_MASK) + +#define SOC_INT_SLEEP_MASK_ADDRESS 0x000000cc +#define SOC_INT_SLEEP_MASK_OFFSET 0x000000cc +#define SOC_INT_SLEEP_MASK_BITMAP_MSB 31 +#define SOC_INT_SLEEP_MASK_BITMAP_LSB 0 +#define SOC_INT_SLEEP_MASK_BITMAP_MASK 0xffffffff +#define SOC_INT_SLEEP_MASK_BITMAP_GET(x) (((x) & SOC_INT_SLEEP_MASK_BITMAP_MASK) >> SOC_INT_SLEEP_MASK_BITMAP_LSB) +#define SOC_INT_SLEEP_MASK_BITMAP_SET(x) (((x) << SOC_INT_SLEEP_MASK_BITMAP_LSB) & SOC_INT_SLEEP_MASK_BITMAP_MASK) + +#define SOC_LPO_CAL_TIME_ADDRESS 0x000000d4 +#define SOC_LPO_CAL_TIME_OFFSET 0x000000d4 +#define SOC_LPO_CAL_TIME_LENGTH_MSB 13 +#define SOC_LPO_CAL_TIME_LENGTH_LSB 0 +#define SOC_LPO_CAL_TIME_LENGTH_MASK 0x00003fff +#define SOC_LPO_CAL_TIME_LENGTH_GET(x) (((x) & SOC_LPO_CAL_TIME_LENGTH_MASK) >> SOC_LPO_CAL_TIME_LENGTH_LSB) +#define SOC_LPO_CAL_TIME_LENGTH_SET(x) (((x) << SOC_LPO_CAL_TIME_LENGTH_LSB) & SOC_LPO_CAL_TIME_LENGTH_MASK) + +#define SOC_LPO_INIT_DIVIDEND_INT_ADDRESS 0x000000d8 +#define SOC_LPO_INIT_DIVIDEND_INT_OFFSET 0x000000d8 +#define SOC_LPO_INIT_DIVIDEND_INT_VALUE_MSB 23 +#define SOC_LPO_INIT_DIVIDEND_INT_VALUE_LSB 0 +#define SOC_LPO_INIT_DIVIDEND_INT_VALUE_MASK 0x00ffffff +#define SOC_LPO_INIT_DIVIDEND_INT_VALUE_GET(x) (((x) & SOC_LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> SOC_LPO_INIT_DIVIDEND_INT_VALUE_LSB) +#define SOC_LPO_INIT_DIVIDEND_INT_VALUE_SET(x) (((x) << SOC_LPO_INIT_DIVIDEND_INT_VALUE_LSB) & SOC_LPO_INIT_DIVIDEND_INT_VALUE_MASK) + +#define SOC_LPO_INIT_DIVIDEND_FRACTION_ADDRESS 0x000000dc +#define SOC_LPO_INIT_DIVIDEND_FRACTION_OFFSET 0x000000dc +#define SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10 +#define SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0 +#define SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff +#define SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) (((x) & SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) +#define SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) (((x) << SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & SOC_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) + +#define SOC_LPO_CAL_ADDRESS 0x000000e0 +#define SOC_LPO_CAL_OFFSET 0x000000e0 +#define SOC_LPO_CAL_ENABLE_MSB 20 +#define SOC_LPO_CAL_ENABLE_LSB 20 +#define SOC_LPO_CAL_ENABLE_MASK 0x00100000 +#define SOC_LPO_CAL_ENABLE_GET(x) (((x) & SOC_LPO_CAL_ENABLE_MASK) >> SOC_LPO_CAL_ENABLE_LSB) +#define SOC_LPO_CAL_ENABLE_SET(x) (((x) << SOC_LPO_CAL_ENABLE_LSB) & SOC_LPO_CAL_ENABLE_MASK) +#define SOC_LPO_CAL_COUNT_MSB 19 +#define SOC_LPO_CAL_COUNT_LSB 0 +#define SOC_LPO_CAL_COUNT_MASK 0x000fffff +#define SOC_LPO_CAL_COUNT_GET(x) (((x) & SOC_LPO_CAL_COUNT_MASK) >> SOC_LPO_CAL_COUNT_LSB) +#define SOC_LPO_CAL_COUNT_SET(x) (((x) << SOC_LPO_CAL_COUNT_LSB) & SOC_LPO_CAL_COUNT_MASK) + +#define SOC_LPO_CAL_TEST_CONTROL_ADDRESS 0x000000e4 +#define SOC_LPO_CAL_TEST_CONTROL_OFFSET 0x000000e4 +#define SOC_LPO_CAL_TEST_CONTROL_ENABLE_MSB 16 +#define SOC_LPO_CAL_TEST_CONTROL_ENABLE_LSB 16 +#define SOC_LPO_CAL_TEST_CONTROL_ENABLE_MASK 0x00010000 +#define SOC_LPO_CAL_TEST_CONTROL_ENABLE_GET(x) (((x) & SOC_LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> SOC_LPO_CAL_TEST_CONTROL_ENABLE_LSB) +#define SOC_LPO_CAL_TEST_CONTROL_ENABLE_SET(x) (((x) << SOC_LPO_CAL_TEST_CONTROL_ENABLE_LSB) & SOC_LPO_CAL_TEST_CONTROL_ENABLE_MASK) +#define SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 15 +#define SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0 +#define SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000ffff +#define SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) (((x) & SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) +#define SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) (((x) << SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & SOC_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) + +#define SOC_LPO_CAL_TEST_STATUS_ADDRESS 0x000000e8 +#define SOC_LPO_CAL_TEST_STATUS_OFFSET 0x000000e8 +#define SOC_LPO_CAL_TEST_STATUS_READY_MSB 16 +#define SOC_LPO_CAL_TEST_STATUS_READY_LSB 16 +#define SOC_LPO_CAL_TEST_STATUS_READY_MASK 0x00010000 +#define SOC_LPO_CAL_TEST_STATUS_READY_GET(x) (((x) & SOC_LPO_CAL_TEST_STATUS_READY_MASK) >> SOC_LPO_CAL_TEST_STATUS_READY_LSB) +#define SOC_LPO_CAL_TEST_STATUS_READY_SET(x) (((x) << SOC_LPO_CAL_TEST_STATUS_READY_LSB) & SOC_LPO_CAL_TEST_STATUS_READY_MASK) +#define SOC_LPO_CAL_TEST_STATUS_COUNT_MSB 15 +#define SOC_LPO_CAL_TEST_STATUS_COUNT_LSB 0 +#define SOC_LPO_CAL_TEST_STATUS_COUNT_MASK 0x0000ffff +#define SOC_LPO_CAL_TEST_STATUS_COUNT_GET(x) (((x) & SOC_LPO_CAL_TEST_STATUS_COUNT_MASK) >> SOC_LPO_CAL_TEST_STATUS_COUNT_LSB) +#define SOC_LPO_CAL_TEST_STATUS_COUNT_SET(x) (((x) << SOC_LPO_CAL_TEST_STATUS_COUNT_LSB) & SOC_LPO_CAL_TEST_STATUS_COUNT_MASK) + +#define LEGACY_SOC_CHIP_ID_ADDRESS 0x000000ec +#define LEGACY_SOC_CHIP_ID_OFFSET 0x000000ec +#define LEGACY_SOC_CHIP_ID_DEVICE_ID_MSB 31 +#define LEGACY_SOC_CHIP_ID_DEVICE_ID_LSB 16 +#define LEGACY_SOC_CHIP_ID_DEVICE_ID_MASK 0xffff0000 +#define LEGACY_SOC_CHIP_ID_DEVICE_ID_GET(x) (((x) & LEGACY_SOC_CHIP_ID_DEVICE_ID_MASK) >> LEGACY_SOC_CHIP_ID_DEVICE_ID_LSB) +#define LEGACY_SOC_CHIP_ID_DEVICE_ID_SET(x) (((x) << LEGACY_SOC_CHIP_ID_DEVICE_ID_LSB) & LEGACY_SOC_CHIP_ID_DEVICE_ID_MASK) +#define LEGACY_SOC_CHIP_ID_CONFIG_ID_MSB 15 +#define LEGACY_SOC_CHIP_ID_CONFIG_ID_LSB 4 +#define LEGACY_SOC_CHIP_ID_CONFIG_ID_MASK 0x0000fff0 +#define LEGACY_SOC_CHIP_ID_CONFIG_ID_GET(x) (((x) & LEGACY_SOC_CHIP_ID_CONFIG_ID_MASK) >> LEGACY_SOC_CHIP_ID_CONFIG_ID_LSB) +#define LEGACY_SOC_CHIP_ID_CONFIG_ID_SET(x) (((x) << LEGACY_SOC_CHIP_ID_CONFIG_ID_LSB) & LEGACY_SOC_CHIP_ID_CONFIG_ID_MASK) +#define LEGACY_SOC_CHIP_ID_VERSION_ID_MSB 3 +#define LEGACY_SOC_CHIP_ID_VERSION_ID_LSB 0 +#define LEGACY_SOC_CHIP_ID_VERSION_ID_MASK 0x0000000f +#define LEGACY_SOC_CHIP_ID_VERSION_ID_GET(x) (((x) & LEGACY_SOC_CHIP_ID_VERSION_ID_MASK) >> LEGACY_SOC_CHIP_ID_VERSION_ID_LSB) +#define LEGACY_SOC_CHIP_ID_VERSION_ID_SET(x) (((x) << LEGACY_SOC_CHIP_ID_VERSION_ID_LSB) & LEGACY_SOC_CHIP_ID_VERSION_ID_MASK) + +#define SOC_CHIP_ID_ADDRESS 0x000000f0 +#define SOC_CHIP_ID_OFFSET 0x000000f0 +#define SOC_CHIP_ID_DEVICE_ID_MSB 31 +#define SOC_CHIP_ID_DEVICE_ID_LSB 16 +#define SOC_CHIP_ID_DEVICE_ID_MASK 0xffff0000 +#define SOC_CHIP_ID_DEVICE_ID_GET(x) (((x) & SOC_CHIP_ID_DEVICE_ID_MASK) >> SOC_CHIP_ID_DEVICE_ID_LSB) +#define SOC_CHIP_ID_DEVICE_ID_SET(x) (((x) << SOC_CHIP_ID_DEVICE_ID_LSB) & SOC_CHIP_ID_DEVICE_ID_MASK) +#define SOC_CHIP_ID_CONFIG_ID_MSB 15 +#define SOC_CHIP_ID_CONFIG_ID_LSB 4 +#define SOC_CHIP_ID_CONFIG_ID_MASK 0x0000fff0 +#define SOC_CHIP_ID_CONFIG_ID_GET(x) (((x) & SOC_CHIP_ID_CONFIG_ID_MASK) >> SOC_CHIP_ID_CONFIG_ID_LSB) +#define SOC_CHIP_ID_CONFIG_ID_SET(x) (((x) << SOC_CHIP_ID_CONFIG_ID_LSB) & SOC_CHIP_ID_CONFIG_ID_MASK) +#define SOC_CHIP_ID_VERSION_ID_MSB 3 +#define SOC_CHIP_ID_VERSION_ID_LSB 0 +#define SOC_CHIP_ID_VERSION_ID_MASK 0x0000000f +#define SOC_CHIP_ID_VERSION_ID_GET(x) (((x) & SOC_CHIP_ID_VERSION_ID_MASK) >> SOC_CHIP_ID_VERSION_ID_LSB) +#define SOC_CHIP_ID_VERSION_ID_SET(x) (((x) << SOC_CHIP_ID_VERSION_ID_LSB) & SOC_CHIP_ID_VERSION_ID_MASK) + +#define SOC_POWER_REG_ADDRESS 0x0000010c +#define SOC_POWER_REG_OFFSET 0x0000010c +#define SOC_POWER_REG_DISCON_MODE_EN_MSB 16 +#define SOC_POWER_REG_DISCON_MODE_EN_LSB 16 +#define SOC_POWER_REG_DISCON_MODE_EN_MASK 0x00010000 +#define SOC_POWER_REG_DISCON_MODE_EN_GET(x) (((x) & SOC_POWER_REG_DISCON_MODE_EN_MASK) >> SOC_POWER_REG_DISCON_MODE_EN_LSB) +#define SOC_POWER_REG_DISCON_MODE_EN_SET(x) (((x) << SOC_POWER_REG_DISCON_MODE_EN_LSB) & SOC_POWER_REG_DISCON_MODE_EN_MASK) +#define SOC_POWER_REG_DEEP_SLEEP_EN_MSB 15 +#define SOC_POWER_REG_DEEP_SLEEP_EN_LSB 15 +#define SOC_POWER_REG_DEEP_SLEEP_EN_MASK 0x00008000 +#define SOC_POWER_REG_DEEP_SLEEP_EN_GET(x) (((x) & SOC_POWER_REG_DEEP_SLEEP_EN_MASK) >> SOC_POWER_REG_DEEP_SLEEP_EN_LSB) +#define SOC_POWER_REG_DEEP_SLEEP_EN_SET(x) (((x) << SOC_POWER_REG_DEEP_SLEEP_EN_LSB) & SOC_POWER_REG_DEEP_SLEEP_EN_MASK) +#define SOC_POWER_REG_DEBUG_EN_MSB 14 +#define SOC_POWER_REG_DEBUG_EN_LSB 14 +#define SOC_POWER_REG_DEBUG_EN_MASK 0x00004000 +#define SOC_POWER_REG_DEBUG_EN_GET(x) (((x) & SOC_POWER_REG_DEBUG_EN_MASK) >> SOC_POWER_REG_DEBUG_EN_LSB) +#define SOC_POWER_REG_DEBUG_EN_SET(x) (((x) << SOC_POWER_REG_DEBUG_EN_LSB) & SOC_POWER_REG_DEBUG_EN_MASK) +#define SOC_POWER_REG_WLAN_BB_PWD_EN_MSB 13 +#define SOC_POWER_REG_WLAN_BB_PWD_EN_LSB 13 +#define SOC_POWER_REG_WLAN_BB_PWD_EN_MASK 0x00002000 +#define SOC_POWER_REG_WLAN_BB_PWD_EN_GET(x) (((x) & SOC_POWER_REG_WLAN_BB_PWD_EN_MASK) >> SOC_POWER_REG_WLAN_BB_PWD_EN_LSB) +#define SOC_POWER_REG_WLAN_BB_PWD_EN_SET(x) (((x) << SOC_POWER_REG_WLAN_BB_PWD_EN_LSB) & SOC_POWER_REG_WLAN_BB_PWD_EN_MASK) +#define SOC_POWER_REG_WLAN_MAC_PWD_EN_MSB 12 +#define SOC_POWER_REG_WLAN_MAC_PWD_EN_LSB 12 +#define SOC_POWER_REG_WLAN_MAC_PWD_EN_MASK 0x00001000 +#define SOC_POWER_REG_WLAN_MAC_PWD_EN_GET(x) (((x) & SOC_POWER_REG_WLAN_MAC_PWD_EN_MASK) >> SOC_POWER_REG_WLAN_MAC_PWD_EN_LSB) +#define SOC_POWER_REG_WLAN_MAC_PWD_EN_SET(x) (((x) << SOC_POWER_REG_WLAN_MAC_PWD_EN_LSB) & SOC_POWER_REG_WLAN_MAC_PWD_EN_MASK) +#define SOC_POWER_REG_CPU_INT_ENABLE_MSB 7 +#define SOC_POWER_REG_CPU_INT_ENABLE_LSB 7 +#define SOC_POWER_REG_CPU_INT_ENABLE_MASK 0x00000080 +#define SOC_POWER_REG_CPU_INT_ENABLE_GET(x) (((x) & SOC_POWER_REG_CPU_INT_ENABLE_MASK) >> SOC_POWER_REG_CPU_INT_ENABLE_LSB) +#define SOC_POWER_REG_CPU_INT_ENABLE_SET(x) (((x) << SOC_POWER_REG_CPU_INT_ENABLE_LSB) & SOC_POWER_REG_CPU_INT_ENABLE_MASK) +#define SOC_POWER_REG_WLAN_ISO_DIS_MSB 6 +#define SOC_POWER_REG_WLAN_ISO_DIS_LSB 6 +#define SOC_POWER_REG_WLAN_ISO_DIS_MASK 0x00000040 +#define SOC_POWER_REG_WLAN_ISO_DIS_GET(x) (((x) & SOC_POWER_REG_WLAN_ISO_DIS_MASK) >> SOC_POWER_REG_WLAN_ISO_DIS_LSB) +#define SOC_POWER_REG_WLAN_ISO_DIS_SET(x) (((x) << SOC_POWER_REG_WLAN_ISO_DIS_LSB) & SOC_POWER_REG_WLAN_ISO_DIS_MASK) +#define SOC_POWER_REG_WLAN_ISO_CNTL_MSB 5 +#define SOC_POWER_REG_WLAN_ISO_CNTL_LSB 5 +#define SOC_POWER_REG_WLAN_ISO_CNTL_MASK 0x00000020 +#define SOC_POWER_REG_WLAN_ISO_CNTL_GET(x) (((x) & SOC_POWER_REG_WLAN_ISO_CNTL_MASK) >> SOC_POWER_REG_WLAN_ISO_CNTL_LSB) +#define SOC_POWER_REG_WLAN_ISO_CNTL_SET(x) (((x) << SOC_POWER_REG_WLAN_ISO_CNTL_LSB) & SOC_POWER_REG_WLAN_ISO_CNTL_MASK) +#define SOC_POWER_REG_RADIO_PWD_EN_MSB 4 +#define SOC_POWER_REG_RADIO_PWD_EN_LSB 4 +#define SOC_POWER_REG_RADIO_PWD_EN_MASK 0x00000010 +#define SOC_POWER_REG_RADIO_PWD_EN_GET(x) (((x) & SOC_POWER_REG_RADIO_PWD_EN_MASK) >> SOC_POWER_REG_RADIO_PWD_EN_LSB) +#define SOC_POWER_REG_RADIO_PWD_EN_SET(x) (((x) << SOC_POWER_REG_RADIO_PWD_EN_LSB) & SOC_POWER_REG_RADIO_PWD_EN_MASK) +#define SOC_POWER_REG_SOC_ISO_EN_MSB 3 +#define SOC_POWER_REG_SOC_ISO_EN_LSB 3 +#define SOC_POWER_REG_SOC_ISO_EN_MASK 0x00000008 +#define SOC_POWER_REG_SOC_ISO_EN_GET(x) (((x) & SOC_POWER_REG_SOC_ISO_EN_MASK) >> SOC_POWER_REG_SOC_ISO_EN_LSB) +#define SOC_POWER_REG_SOC_ISO_EN_SET(x) (((x) << SOC_POWER_REG_SOC_ISO_EN_LSB) & SOC_POWER_REG_SOC_ISO_EN_MASK) +#define SOC_POWER_REG_WLAN_ISO_EN_MSB 2 +#define SOC_POWER_REG_WLAN_ISO_EN_LSB 2 +#define SOC_POWER_REG_WLAN_ISO_EN_MASK 0x00000004 +#define SOC_POWER_REG_WLAN_ISO_EN_GET(x) (((x) & SOC_POWER_REG_WLAN_ISO_EN_MASK) >> SOC_POWER_REG_WLAN_ISO_EN_LSB) +#define SOC_POWER_REG_WLAN_ISO_EN_SET(x) (((x) << SOC_POWER_REG_WLAN_ISO_EN_LSB) & SOC_POWER_REG_WLAN_ISO_EN_MASK) +#define SOC_POWER_REG_WLAN_PWD_EN_MSB 1 +#define SOC_POWER_REG_WLAN_PWD_EN_LSB 1 +#define SOC_POWER_REG_WLAN_PWD_EN_MASK 0x00000002 +#define SOC_POWER_REG_WLAN_PWD_EN_GET(x) (((x) & SOC_POWER_REG_WLAN_PWD_EN_MASK) >> SOC_POWER_REG_WLAN_PWD_EN_LSB) +#define SOC_POWER_REG_WLAN_PWD_EN_SET(x) (((x) << SOC_POWER_REG_WLAN_PWD_EN_LSB) & SOC_POWER_REG_WLAN_PWD_EN_MASK) +#define SOC_POWER_REG_POWER_EN_MSB 0 +#define SOC_POWER_REG_POWER_EN_LSB 0 +#define SOC_POWER_REG_POWER_EN_MASK 0x00000001 +#define SOC_POWER_REG_POWER_EN_GET(x) (((x) & SOC_POWER_REG_POWER_EN_MASK) >> SOC_POWER_REG_POWER_EN_LSB) +#define SOC_POWER_REG_POWER_EN_SET(x) (((x) << SOC_POWER_REG_POWER_EN_LSB) & SOC_POWER_REG_POWER_EN_MASK) + +#define SOC_CORE_CLK_CTRL_ADDRESS 0x00000110 +#define SOC_CORE_CLK_CTRL_OFFSET 0x00000110 +#define SOC_CORE_CLK_CTRL_DIV_MSB 2 +#define SOC_CORE_CLK_CTRL_DIV_LSB 0 +#define SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define SOC_CORE_CLK_CTRL_DIV_GET(x) (((x) & SOC_CORE_CLK_CTRL_DIV_MASK) >> SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_SET(x) (((x) << SOC_CORE_CLK_CTRL_DIV_LSB) & SOC_CORE_CLK_CTRL_DIV_MASK) + +#define SOC_GPIO_WAKEUP_CONTROL_ADDRESS 0x00000114 +#define SOC_GPIO_WAKEUP_CONTROL_OFFSET 0x00000114 +#define SOC_GPIO_WAKEUP_CONTROL_ENABLE_MSB 0 +#define SOC_GPIO_WAKEUP_CONTROL_ENABLE_LSB 0 +#define SOC_GPIO_WAKEUP_CONTROL_ENABLE_MASK 0x00000001 +#define SOC_GPIO_WAKEUP_CONTROL_ENABLE_GET(x) (((x) & SOC_GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> SOC_GPIO_WAKEUP_CONTROL_ENABLE_LSB) +#define SOC_GPIO_WAKEUP_CONTROL_ENABLE_SET(x) (((x) << SOC_GPIO_WAKEUP_CONTROL_ENABLE_LSB) & SOC_GPIO_WAKEUP_CONTROL_ENABLE_MASK) + +#define SLEEP_RETENTION_ADDRESS 0x00000214 +#define SLEEP_RETENTION_OFFSET 0x00000214 +#define SLEEP_RETENTION_GREEN_SAVE_MSB 10 +#define SLEEP_RETENTION_GREEN_SAVE_LSB 10 +#define SLEEP_RETENTION_GREEN_SAVE_MASK 0x00000400 +#define SLEEP_RETENTION_GREEN_SAVE_GET(x) (((x) & SLEEP_RETENTION_GREEN_SAVE_MASK) >> SLEEP_RETENTION_GREEN_SAVE_LSB) +#define SLEEP_RETENTION_GREEN_SAVE_SET(x) (((x) << SLEEP_RETENTION_GREEN_SAVE_LSB) & SLEEP_RETENTION_GREEN_SAVE_MASK) +#define SLEEP_RETENTION_TIME_MSB 9 +#define SLEEP_RETENTION_TIME_LSB 2 +#define SLEEP_RETENTION_TIME_MASK 0x000003fc +#define SLEEP_RETENTION_TIME_GET(x) (((x) & SLEEP_RETENTION_TIME_MASK) >> SLEEP_RETENTION_TIME_LSB) +#define SLEEP_RETENTION_TIME_SET(x) (((x) << SLEEP_RETENTION_TIME_LSB) & SLEEP_RETENTION_TIME_MASK) +#define SLEEP_RETENTION_MODE_MSB 1 +#define SLEEP_RETENTION_MODE_LSB 1 +#define SLEEP_RETENTION_MODE_MASK 0x00000002 +#define SLEEP_RETENTION_MODE_GET(x) (((x) & SLEEP_RETENTION_MODE_MASK) >> SLEEP_RETENTION_MODE_LSB) +#define SLEEP_RETENTION_MODE_SET(x) (((x) << SLEEP_RETENTION_MODE_LSB) & SLEEP_RETENTION_MODE_MASK) +#define SLEEP_RETENTION_ENABLE_MSB 0 +#define SLEEP_RETENTION_ENABLE_LSB 0 +#define SLEEP_RETENTION_ENABLE_MASK 0x00000001 +#define SLEEP_RETENTION_ENABLE_GET(x) (((x) & SLEEP_RETENTION_ENABLE_MASK) >> SLEEP_RETENTION_ENABLE_LSB) +#define SLEEP_RETENTION_ENABLE_SET(x) (((x) << SLEEP_RETENTION_ENABLE_LSB) & SLEEP_RETENTION_ENABLE_MASK) + +#define LP_PERF_COUNTER_ADDRESS 0x00000284 +#define LP_PERF_COUNTER_OFFSET 0x00000284 +#define LP_PERF_COUNTER_EN_MSB 0 +#define LP_PERF_COUNTER_EN_LSB 0 +#define LP_PERF_COUNTER_EN_MASK 0x00000001 +#define LP_PERF_COUNTER_EN_GET(x) (((x) & LP_PERF_COUNTER_EN_MASK) >> LP_PERF_COUNTER_EN_LSB) +#define LP_PERF_COUNTER_EN_SET(x) (((x) << LP_PERF_COUNTER_EN_LSB) & LP_PERF_COUNTER_EN_MASK) + +#define LP_PERF_LIGHT_SLEEP_ADDRESS 0x00000288 +#define LP_PERF_LIGHT_SLEEP_OFFSET 0x00000288 +#define LP_PERF_LIGHT_SLEEP_CNT_MSB 31 +#define LP_PERF_LIGHT_SLEEP_CNT_LSB 0 +#define LP_PERF_LIGHT_SLEEP_CNT_MASK 0xffffffff +#define LP_PERF_LIGHT_SLEEP_CNT_GET(x) (((x) & LP_PERF_LIGHT_SLEEP_CNT_MASK) >> LP_PERF_LIGHT_SLEEP_CNT_LSB) +#define LP_PERF_LIGHT_SLEEP_CNT_SET(x) (((x) << LP_PERF_LIGHT_SLEEP_CNT_LSB) & LP_PERF_LIGHT_SLEEP_CNT_MASK) + +#define LP_PERF_DEEP_SLEEP_ADDRESS 0x0000028c +#define LP_PERF_DEEP_SLEEP_OFFSET 0x0000028c +#define LP_PERF_DEEP_SLEEP_CNT_MSB 31 +#define LP_PERF_DEEP_SLEEP_CNT_LSB 0 +#define LP_PERF_DEEP_SLEEP_CNT_MASK 0xffffffff +#define LP_PERF_DEEP_SLEEP_CNT_GET(x) (((x) & LP_PERF_DEEP_SLEEP_CNT_MASK) >> LP_PERF_DEEP_SLEEP_CNT_LSB) +#define LP_PERF_DEEP_SLEEP_CNT_SET(x) (((x) << LP_PERF_DEEP_SLEEP_CNT_LSB) & LP_PERF_DEEP_SLEEP_CNT_MASK) + +#define LP_PERF_ON_ADDRESS 0x00000290 +#define LP_PERF_ON_OFFSET 0x00000290 +#define LP_PERF_ON_CNT_MSB 31 +#define LP_PERF_ON_CNT_LSB 0 +#define LP_PERF_ON_CNT_MASK 0xffffffff +#define LP_PERF_ON_CNT_GET(x) (((x) & LP_PERF_ON_CNT_MASK) >> LP_PERF_ON_CNT_LSB) +#define LP_PERF_ON_CNT_SET(x) (((x) << LP_PERF_ON_CNT_LSB) & LP_PERF_ON_CNT_MASK) + +#define CHIP_MODE_ADDRESS 0x000002a8 +#define CHIP_MODE_OFFSET 0x000002a8 +#define CHIP_MODE_BIT_MSB 1 +#define CHIP_MODE_BIT_LSB 0 +#define CHIP_MODE_BIT_MASK 0x00000003 +#define CHIP_MODE_BIT_GET(x) (((x) & CHIP_MODE_BIT_MASK) >> CHIP_MODE_BIT_LSB) +#define CHIP_MODE_BIT_SET(x) (((x) << CHIP_MODE_BIT_LSB) & CHIP_MODE_BIT_MASK) + +#define CLK_REQ_FALL_EDGE_ADDRESS 0x000002ac +#define CLK_REQ_FALL_EDGE_OFFSET 0x000002ac +#define CLK_REQ_FALL_EDGE_EN_MSB 31 +#define CLK_REQ_FALL_EDGE_EN_LSB 31 +#define CLK_REQ_FALL_EDGE_EN_MASK 0x80000000 +#define CLK_REQ_FALL_EDGE_EN_GET(x) (((x) & CLK_REQ_FALL_EDGE_EN_MASK) >> CLK_REQ_FALL_EDGE_EN_LSB) +#define CLK_REQ_FALL_EDGE_EN_SET(x) (((x) << CLK_REQ_FALL_EDGE_EN_LSB) & CLK_REQ_FALL_EDGE_EN_MASK) +#define CLK_REQ_FALL_EDGE_DELAY_MSB 7 +#define CLK_REQ_FALL_EDGE_DELAY_LSB 0 +#define CLK_REQ_FALL_EDGE_DELAY_MASK 0x000000ff +#define CLK_REQ_FALL_EDGE_DELAY_GET(x) (((x) & CLK_REQ_FALL_EDGE_DELAY_MASK) >> CLK_REQ_FALL_EDGE_DELAY_LSB) +#define CLK_REQ_FALL_EDGE_DELAY_SET(x) (((x) << CLK_REQ_FALL_EDGE_DELAY_LSB) & CLK_REQ_FALL_EDGE_DELAY_MASK) + +#define OTP_ADDRESS 0x000002b0 +#define OTP_OFFSET 0x000002b0 +#define OTP_LDO25_EN_MSB 1 +#define OTP_LDO25_EN_LSB 1 +#define OTP_LDO25_EN_MASK 0x00000002 +#define OTP_LDO25_EN_GET(x) (((x) & OTP_LDO25_EN_MASK) >> OTP_LDO25_EN_LSB) +#define OTP_LDO25_EN_SET(x) (((x) << OTP_LDO25_EN_LSB) & OTP_LDO25_EN_MASK) +#define OTP_VDD12_EN_MSB 0 +#define OTP_VDD12_EN_LSB 0 +#define OTP_VDD12_EN_MASK 0x00000001 +#define OTP_VDD12_EN_GET(x) (((x) & OTP_VDD12_EN_MASK) >> OTP_VDD12_EN_LSB) +#define OTP_VDD12_EN_SET(x) (((x) << OTP_VDD12_EN_LSB) & OTP_VDD12_EN_MASK) + +#define OTP_STATUS_ADDRESS 0x000002b4 +#define OTP_STATUS_OFFSET 0x000002b4 +#define OTP_STATUS_LDO25_EN_READY_MSB 1 +#define OTP_STATUS_LDO25_EN_READY_LSB 1 +#define OTP_STATUS_LDO25_EN_READY_MASK 0x00000002 +#define OTP_STATUS_LDO25_EN_READY_GET(x) (((x) & OTP_STATUS_LDO25_EN_READY_MASK) >> OTP_STATUS_LDO25_EN_READY_LSB) +#define OTP_STATUS_LDO25_EN_READY_SET(x) (((x) << OTP_STATUS_LDO25_EN_READY_LSB) & OTP_STATUS_LDO25_EN_READY_MASK) +#define OTP_STATUS_VDD12_EN_READY_MSB 0 +#define OTP_STATUS_VDD12_EN_READY_LSB 0 +#define OTP_STATUS_VDD12_EN_READY_MASK 0x00000001 +#define OTP_STATUS_VDD12_EN_READY_GET(x) (((x) & OTP_STATUS_VDD12_EN_READY_MASK) >> OTP_STATUS_VDD12_EN_READY_LSB) +#define OTP_STATUS_VDD12_EN_READY_SET(x) (((x) << OTP_STATUS_VDD12_EN_READY_LSB) & OTP_STATUS_VDD12_EN_READY_MASK) + +#define PMU_ADDRESS 0x000002b8 +#define PMU_OFFSET 0x000002b8 +#define PMU_REG_WAKEUP_TIME_SEL_MSB 1 +#define PMU_REG_WAKEUP_TIME_SEL_LSB 0 +#define PMU_REG_WAKEUP_TIME_SEL_MASK 0x00000003 +#define PMU_REG_WAKEUP_TIME_SEL_GET(x) (((x) & PMU_REG_WAKEUP_TIME_SEL_MASK) >> PMU_REG_WAKEUP_TIME_SEL_LSB) +#define PMU_REG_WAKEUP_TIME_SEL_SET(x) (((x) << PMU_REG_WAKEUP_TIME_SEL_LSB) & PMU_REG_WAKEUP_TIME_SEL_MASK) + +#define PMU_CONFIG_ADDRESS 0x000002bc +#define PMU_CONFIG_OFFSET 0x000002bc +#define PMU_CONFIG_VALUE_MSB 4 +#define PMU_CONFIG_VALUE_LSB 0 +#define PMU_CONFIG_VALUE_MASK 0x0000001f +#define PMU_CONFIG_VALUE_GET(x) (((x) & PMU_CONFIG_VALUE_MASK) >> PMU_CONFIG_VALUE_LSB) +#define PMU_CONFIG_VALUE_SET(x) (((x) << PMU_CONFIG_VALUE_LSB) & PMU_CONFIG_VALUE_MASK) + +#define PMU_PAREG_ADDRESS 0x000002c0 +#define PMU_PAREG_OFFSET 0x000002c0 +#define PMU_PAREG_LVL_CTR_MSB 2 +#define PMU_PAREG_LVL_CTR_LSB 0 +#define PMU_PAREG_LVL_CTR_MASK 0x00000007 +#define PMU_PAREG_LVL_CTR_GET(x) (((x) & PMU_PAREG_LVL_CTR_MASK) >> PMU_PAREG_LVL_CTR_LSB) +#define PMU_PAREG_LVL_CTR_SET(x) (((x) << PMU_PAREG_LVL_CTR_LSB) & PMU_PAREG_LVL_CTR_MASK) + +#define PMU_BYPASS_ADDRESS 0x000002c4 +#define PMU_BYPASS_OFFSET 0x000002c4 +#define PMU_BYPASS_SWREG_MSB 2 +#define PMU_BYPASS_SWREG_LSB 2 +#define PMU_BYPASS_SWREG_MASK 0x00000004 +#define PMU_BYPASS_SWREG_GET(x) (((x) & PMU_BYPASS_SWREG_MASK) >> PMU_BYPASS_SWREG_LSB) +#define PMU_BYPASS_SWREG_SET(x) (((x) << PMU_BYPASS_SWREG_LSB) & PMU_BYPASS_SWREG_MASK) +#define PMU_BYPASS_DREG_MSB 1 +#define PMU_BYPASS_DREG_LSB 1 +#define PMU_BYPASS_DREG_MASK 0x00000002 +#define PMU_BYPASS_DREG_GET(x) (((x) & PMU_BYPASS_DREG_MASK) >> PMU_BYPASS_DREG_LSB) +#define PMU_BYPASS_DREG_SET(x) (((x) << PMU_BYPASS_DREG_LSB) & PMU_BYPASS_DREG_MASK) +#define PMU_BYPASS_PAREG_MSB 0 +#define PMU_BYPASS_PAREG_LSB 0 +#define PMU_BYPASS_PAREG_MASK 0x00000001 +#define PMU_BYPASS_PAREG_GET(x) (((x) & PMU_BYPASS_PAREG_MASK) >> PMU_BYPASS_PAREG_LSB) +#define PMU_BYPASS_PAREG_SET(x) (((x) << PMU_BYPASS_PAREG_LSB) & PMU_BYPASS_PAREG_MASK) + +#define THERM_CTRL1_ADDRESS 0x000002dc +#define THERM_CTRL1_OFFSET 0x000002dc +#define THERM_CTRL1_BYPASS_MSB 16 +#define THERM_CTRL1_BYPASS_LSB 16 +#define THERM_CTRL1_BYPASS_MASK 0x00010000 +#define THERM_CTRL1_BYPASS_GET(x) (((x) & THERM_CTRL1_BYPASS_MASK) >> THERM_CTRL1_BYPASS_LSB) +#define THERM_CTRL1_BYPASS_SET(x) (((x) << THERM_CTRL1_BYPASS_LSB) & THERM_CTRL1_BYPASS_MASK) +#define THERM_CTRL1_WIDTH_ARBITOR_MSB 15 +#define THERM_CTRL1_WIDTH_ARBITOR_LSB 12 +#define THERM_CTRL1_WIDTH_ARBITOR_MASK 0x0000f000 +#define THERM_CTRL1_WIDTH_ARBITOR_GET(x) (((x) & THERM_CTRL1_WIDTH_ARBITOR_MASK) >> THERM_CTRL1_WIDTH_ARBITOR_LSB) +#define THERM_CTRL1_WIDTH_ARBITOR_SET(x) (((x) << THERM_CTRL1_WIDTH_ARBITOR_LSB) & THERM_CTRL1_WIDTH_ARBITOR_MASK) +#define THERM_CTRL1_WIDTH_MSB 11 +#define THERM_CTRL1_WIDTH_LSB 5 +#define THERM_CTRL1_WIDTH_MASK 0x00000fe0 +#define THERM_CTRL1_WIDTH_GET(x) (((x) & THERM_CTRL1_WIDTH_MASK) >> THERM_CTRL1_WIDTH_LSB) +#define THERM_CTRL1_WIDTH_SET(x) (((x) << THERM_CTRL1_WIDTH_LSB) & THERM_CTRL1_WIDTH_MASK) +#define THERM_CTRL1_TYPE_MSB 4 +#define THERM_CTRL1_TYPE_LSB 3 +#define THERM_CTRL1_TYPE_MASK 0x00000018 +#define THERM_CTRL1_TYPE_GET(x) (((x) & THERM_CTRL1_TYPE_MASK) >> THERM_CTRL1_TYPE_LSB) +#define THERM_CTRL1_TYPE_SET(x) (((x) << THERM_CTRL1_TYPE_LSB) & THERM_CTRL1_TYPE_MASK) +#define THERM_CTRL1_MEASURE_MSB 2 +#define THERM_CTRL1_MEASURE_LSB 2 +#define THERM_CTRL1_MEASURE_MASK 0x00000004 +#define THERM_CTRL1_MEASURE_GET(x) (((x) & THERM_CTRL1_MEASURE_MASK) >> THERM_CTRL1_MEASURE_LSB) +#define THERM_CTRL1_MEASURE_SET(x) (((x) << THERM_CTRL1_MEASURE_LSB) & THERM_CTRL1_MEASURE_MASK) +#define THERM_CTRL1_INT_EN_MSB 1 +#define THERM_CTRL1_INT_EN_LSB 1 +#define THERM_CTRL1_INT_EN_MASK 0x00000002 +#define THERM_CTRL1_INT_EN_GET(x) (((x) & THERM_CTRL1_INT_EN_MASK) >> THERM_CTRL1_INT_EN_LSB) +#define THERM_CTRL1_INT_EN_SET(x) (((x) << THERM_CTRL1_INT_EN_LSB) & THERM_CTRL1_INT_EN_MASK) +#define THERM_CTRL1_INT_STATUS_MSB 0 +#define THERM_CTRL1_INT_STATUS_LSB 0 +#define THERM_CTRL1_INT_STATUS_MASK 0x00000001 +#define THERM_CTRL1_INT_STATUS_GET(x) (((x) & THERM_CTRL1_INT_STATUS_MASK) >> THERM_CTRL1_INT_STATUS_LSB) +#define THERM_CTRL1_INT_STATUS_SET(x) (((x) << THERM_CTRL1_INT_STATUS_LSB) & THERM_CTRL1_INT_STATUS_MASK) + +#define THERM_CTRL2_ADDRESS 0x000002e0 +#define THERM_CTRL2_OFFSET 0x000002e0 +#define THERM_CTRL2_ADC_OFF_MSB 25 +#define THERM_CTRL2_ADC_OFF_LSB 25 +#define THERM_CTRL2_ADC_OFF_MASK 0x02000000 +#define THERM_CTRL2_ADC_OFF_GET(x) (((x) & THERM_CTRL2_ADC_OFF_MASK) >> THERM_CTRL2_ADC_OFF_LSB) +#define THERM_CTRL2_ADC_OFF_SET(x) (((x) << THERM_CTRL2_ADC_OFF_LSB) & THERM_CTRL2_ADC_OFF_MASK) +#define THERM_CTRL2_ADC_ON_MSB 24 +#define THERM_CTRL2_ADC_ON_LSB 24 +#define THERM_CTRL2_ADC_ON_MASK 0x01000000 +#define THERM_CTRL2_ADC_ON_GET(x) (((x) & THERM_CTRL2_ADC_ON_MASK) >> THERM_CTRL2_ADC_ON_LSB) +#define THERM_CTRL2_ADC_ON_SET(x) (((x) << THERM_CTRL2_ADC_ON_LSB) & THERM_CTRL2_ADC_ON_MASK) +#define THERM_CTRL2_SAMPLE_MSB 23 +#define THERM_CTRL2_SAMPLE_LSB 16 +#define THERM_CTRL2_SAMPLE_MASK 0x00ff0000 +#define THERM_CTRL2_SAMPLE_GET(x) (((x) & THERM_CTRL2_SAMPLE_MASK) >> THERM_CTRL2_SAMPLE_LSB) +#define THERM_CTRL2_SAMPLE_SET(x) (((x) << THERM_CTRL2_SAMPLE_LSB) & THERM_CTRL2_SAMPLE_MASK) +#define THERM_CTRL2_HIGH_MSB 15 +#define THERM_CTRL2_HIGH_LSB 8 +#define THERM_CTRL2_HIGH_MASK 0x0000ff00 +#define THERM_CTRL2_HIGH_GET(x) (((x) & THERM_CTRL2_HIGH_MASK) >> THERM_CTRL2_HIGH_LSB) +#define THERM_CTRL2_HIGH_SET(x) (((x) << THERM_CTRL2_HIGH_LSB) & THERM_CTRL2_HIGH_MASK) +#define THERM_CTRL2_LOW_MSB 7 +#define THERM_CTRL2_LOW_LSB 0 +#define THERM_CTRL2_LOW_MASK 0x000000ff +#define THERM_CTRL2_LOW_GET(x) (((x) & THERM_CTRL2_LOW_MASK) >> THERM_CTRL2_LOW_LSB) +#define THERM_CTRL2_LOW_SET(x) (((x) << THERM_CTRL2_LOW_LSB) & THERM_CTRL2_LOW_MASK) + +#define THERM_CTRL3_ADDRESS 0x000002e4 +#define THERM_CTRL3_OFFSET 0x000002e4 +#define THERM_CTRL3_ADC_GAIN_MSB 16 +#define THERM_CTRL3_ADC_GAIN_LSB 8 +#define THERM_CTRL3_ADC_GAIN_MASK 0x0001ff00 +#define THERM_CTRL3_ADC_GAIN_GET(x) (((x) & THERM_CTRL3_ADC_GAIN_MASK) >> THERM_CTRL3_ADC_GAIN_LSB) +#define THERM_CTRL3_ADC_GAIN_SET(x) (((x) << THERM_CTRL3_ADC_GAIN_LSB) & THERM_CTRL3_ADC_GAIN_MASK) +#define THERM_CTRL3_ADC_OFFSET_MSB 7 +#define THERM_CTRL3_ADC_OFFSET_LSB 0 +#define THERM_CTRL3_ADC_OFFSET_MASK 0x000000ff +#define THERM_CTRL3_ADC_OFFSET_GET(x) (((x) & THERM_CTRL3_ADC_OFFSET_MASK) >> THERM_CTRL3_ADC_OFFSET_LSB) +#define THERM_CTRL3_ADC_OFFSET_SET(x) (((x) << THERM_CTRL3_ADC_OFFSET_LSB) & THERM_CTRL3_ADC_OFFSET_MASK) + +#define LISTEN_MODE1_ADDRESS 0x000002e8 +#define LISTEN_MODE1_OFFSET 0x000002e8 +#define LISTEN_MODE1_TIMER_CLEAR_MSB 19 +#define LISTEN_MODE1_TIMER_CLEAR_LSB 19 +#define LISTEN_MODE1_TIMER_CLEAR_MASK 0x00080000 +#define LISTEN_MODE1_TIMER_CLEAR_GET(x) (((x) & LISTEN_MODE1_TIMER_CLEAR_MASK) >> LISTEN_MODE1_TIMER_CLEAR_LSB) +#define LISTEN_MODE1_TIMER_CLEAR_SET(x) (((x) << LISTEN_MODE1_TIMER_CLEAR_LSB) & LISTEN_MODE1_TIMER_CLEAR_MASK) +#define LISTEN_MODE1_TIMER_THRESH_WAKE_MSB 18 +#define LISTEN_MODE1_TIMER_THRESH_WAKE_LSB 3 +#define LISTEN_MODE1_TIMER_THRESH_WAKE_MASK 0x0007fff8 +#define LISTEN_MODE1_TIMER_THRESH_WAKE_GET(x) (((x) & LISTEN_MODE1_TIMER_THRESH_WAKE_MASK) >> LISTEN_MODE1_TIMER_THRESH_WAKE_LSB) +#define LISTEN_MODE1_TIMER_THRESH_WAKE_SET(x) (((x) << LISTEN_MODE1_TIMER_THRESH_WAKE_LSB) & LISTEN_MODE1_TIMER_THRESH_WAKE_MASK) +#define LISTEN_MODE1_TIMER_OVERFLOW_WAKE_MSB 2 +#define LISTEN_MODE1_TIMER_OVERFLOW_WAKE_LSB 2 +#define LISTEN_MODE1_TIMER_OVERFLOW_WAKE_MASK 0x00000004 +#define LISTEN_MODE1_TIMER_OVERFLOW_WAKE_GET(x) (((x) & LISTEN_MODE1_TIMER_OVERFLOW_WAKE_MASK) >> LISTEN_MODE1_TIMER_OVERFLOW_WAKE_LSB) +#define LISTEN_MODE1_TIMER_OVERFLOW_WAKE_SET(x) (((x) << LISTEN_MODE1_TIMER_OVERFLOW_WAKE_LSB) & LISTEN_MODE1_TIMER_OVERFLOW_WAKE_MASK) +#define LISTEN_MODE1_CLOCK_GATE_MSB 1 +#define LISTEN_MODE1_CLOCK_GATE_LSB 1 +#define LISTEN_MODE1_CLOCK_GATE_MASK 0x00000002 +#define LISTEN_MODE1_CLOCK_GATE_GET(x) (((x) & LISTEN_MODE1_CLOCK_GATE_MASK) >> LISTEN_MODE1_CLOCK_GATE_LSB) +#define LISTEN_MODE1_CLOCK_GATE_SET(x) (((x) << LISTEN_MODE1_CLOCK_GATE_LSB) & LISTEN_MODE1_CLOCK_GATE_MASK) +#define LISTEN_MODE1_ENABLE_MSB 0 +#define LISTEN_MODE1_ENABLE_LSB 0 +#define LISTEN_MODE1_ENABLE_MASK 0x00000001 +#define LISTEN_MODE1_ENABLE_GET(x) (((x) & LISTEN_MODE1_ENABLE_MASK) >> LISTEN_MODE1_ENABLE_LSB) +#define LISTEN_MODE1_ENABLE_SET(x) (((x) << LISTEN_MODE1_ENABLE_LSB) & LISTEN_MODE1_ENABLE_MASK) + +#define LISTEN_MODE2_ADDRESS 0x000002ec +#define LISTEN_MODE2_OFFSET 0x000002ec +#define LISTEN_MODE2_TIMER_TRIGGER_WAKE_MSB 15 +#define LISTEN_MODE2_TIMER_TRIGGER_WAKE_LSB 0 +#define LISTEN_MODE2_TIMER_TRIGGER_WAKE_MASK 0x0000ffff +#define LISTEN_MODE2_TIMER_TRIGGER_WAKE_GET(x) (((x) & LISTEN_MODE2_TIMER_TRIGGER_WAKE_MASK) >> LISTEN_MODE2_TIMER_TRIGGER_WAKE_LSB) +#define LISTEN_MODE2_TIMER_TRIGGER_WAKE_SET(x) (((x) << LISTEN_MODE2_TIMER_TRIGGER_WAKE_LSB) & LISTEN_MODE2_TIMER_TRIGGER_WAKE_MASK) + +#define AUDIO_PLL_CONFIG_ADDRESS 0x000002f0 +#define AUDIO_PLL_CONFIG_OFFSET 0x000002f0 +#define AUDIO_PLL_CONFIG_UPDATING_MSB 31 +#define AUDIO_PLL_CONFIG_UPDATING_LSB 31 +#define AUDIO_PLL_CONFIG_UPDATING_MASK 0x80000000 +#define AUDIO_PLL_CONFIG_UPDATING_GET(x) (((x) & AUDIO_PLL_CONFIG_UPDATING_MASK) >> AUDIO_PLL_CONFIG_UPDATING_LSB) +#define AUDIO_PLL_CONFIG_UPDATING_SET(x) (((x) << AUDIO_PLL_CONFIG_UPDATING_LSB) & AUDIO_PLL_CONFIG_UPDATING_MASK) +#define AUDIO_PLL_CONFIG_EXT_DIV_MSB 14 +#define AUDIO_PLL_CONFIG_EXT_DIV_LSB 12 +#define AUDIO_PLL_CONFIG_EXT_DIV_MASK 0x00007000 +#define AUDIO_PLL_CONFIG_EXT_DIV_GET(x) (((x) & AUDIO_PLL_CONFIG_EXT_DIV_MASK) >> AUDIO_PLL_CONFIG_EXT_DIV_LSB) +#define AUDIO_PLL_CONFIG_EXT_DIV_SET(x) (((x) << AUDIO_PLL_CONFIG_EXT_DIV_LSB) & AUDIO_PLL_CONFIG_EXT_DIV_MASK) +#define AUDIO_PLL_CONFIG_POSTPLLDIV_MSB 9 +#define AUDIO_PLL_CONFIG_POSTPLLDIV_LSB 7 +#define AUDIO_PLL_CONFIG_POSTPLLDIV_MASK 0x00000380 +#define AUDIO_PLL_CONFIG_POSTPLLDIV_GET(x) (((x) & AUDIO_PLL_CONFIG_POSTPLLDIV_MASK) >> AUDIO_PLL_CONFIG_POSTPLLDIV_LSB) +#define AUDIO_PLL_CONFIG_POSTPLLDIV_SET(x) (((x) << AUDIO_PLL_CONFIG_POSTPLLDIV_LSB) & AUDIO_PLL_CONFIG_POSTPLLDIV_MASK) +#define AUDIO_PLL_CONFIG_PLLPWD_MSB 5 +#define AUDIO_PLL_CONFIG_PLLPWD_LSB 5 +#define AUDIO_PLL_CONFIG_PLLPWD_MASK 0x00000020 +#define AUDIO_PLL_CONFIG_PLLPWD_GET(x) (((x) & AUDIO_PLL_CONFIG_PLLPWD_MASK) >> AUDIO_PLL_CONFIG_PLLPWD_LSB) +#define AUDIO_PLL_CONFIG_PLLPWD_SET(x) (((x) << AUDIO_PLL_CONFIG_PLLPWD_LSB) & AUDIO_PLL_CONFIG_PLLPWD_MASK) +#define AUDIO_PLL_CONFIG_BYPASS_MSB 4 +#define AUDIO_PLL_CONFIG_BYPASS_LSB 4 +#define AUDIO_PLL_CONFIG_BYPASS_MASK 0x00000010 +#define AUDIO_PLL_CONFIG_BYPASS_GET(x) (((x) & AUDIO_PLL_CONFIG_BYPASS_MASK) >> AUDIO_PLL_CONFIG_BYPASS_LSB) +#define AUDIO_PLL_CONFIG_BYPASS_SET(x) (((x) << AUDIO_PLL_CONFIG_BYPASS_LSB) & AUDIO_PLL_CONFIG_BYPASS_MASK) +#define AUDIO_PLL_CONFIG_REFDIV_MSB 3 +#define AUDIO_PLL_CONFIG_REFDIV_LSB 0 +#define AUDIO_PLL_CONFIG_REFDIV_MASK 0x0000000f +#define AUDIO_PLL_CONFIG_REFDIV_GET(x) (((x) & AUDIO_PLL_CONFIG_REFDIV_MASK) >> AUDIO_PLL_CONFIG_REFDIV_LSB) +#define AUDIO_PLL_CONFIG_REFDIV_SET(x) (((x) << AUDIO_PLL_CONFIG_REFDIV_LSB) & AUDIO_PLL_CONFIG_REFDIV_MASK) + +#define AUDIO_PLL_MODULATION_ADDRESS 0x000002f4 +#define AUDIO_PLL_MODULATION_OFFSET 0x000002f4 +#define AUDIO_PLL_MODULATION_TGT_DIV_FRAC_MSB 28 +#define AUDIO_PLL_MODULATION_TGT_DIV_FRAC_LSB 11 +#define AUDIO_PLL_MODULATION_TGT_DIV_FRAC_MASK 0x1ffff800 +#define AUDIO_PLL_MODULATION_TGT_DIV_FRAC_GET(x) (((x) & AUDIO_PLL_MODULATION_TGT_DIV_FRAC_MASK) >> AUDIO_PLL_MODULATION_TGT_DIV_FRAC_LSB) +#define AUDIO_PLL_MODULATION_TGT_DIV_FRAC_SET(x) (((x) << AUDIO_PLL_MODULATION_TGT_DIV_FRAC_LSB) & AUDIO_PLL_MODULATION_TGT_DIV_FRAC_MASK) +#define AUDIO_PLL_MODULATION_TGT_DIV_INT_MSB 6 +#define AUDIO_PLL_MODULATION_TGT_DIV_INT_LSB 1 +#define AUDIO_PLL_MODULATION_TGT_DIV_INT_MASK 0x0000007e +#define AUDIO_PLL_MODULATION_TGT_DIV_INT_GET(x) (((x) & AUDIO_PLL_MODULATION_TGT_DIV_INT_MASK) >> AUDIO_PLL_MODULATION_TGT_DIV_INT_LSB) +#define AUDIO_PLL_MODULATION_TGT_DIV_INT_SET(x) (((x) << AUDIO_PLL_MODULATION_TGT_DIV_INT_LSB) & AUDIO_PLL_MODULATION_TGT_DIV_INT_MASK) +#define AUDIO_PLL_MODULATION_START_MSB 0 +#define AUDIO_PLL_MODULATION_START_LSB 0 +#define AUDIO_PLL_MODULATION_START_MASK 0x00000001 +#define AUDIO_PLL_MODULATION_START_GET(x) (((x) & AUDIO_PLL_MODULATION_START_MASK) >> AUDIO_PLL_MODULATION_START_LSB) +#define AUDIO_PLL_MODULATION_START_SET(x) (((x) << AUDIO_PLL_MODULATION_START_LSB) & AUDIO_PLL_MODULATION_START_MASK) + +#define AUDIO_PLL_MOD_STEP_ADDRESS 0x000002f8 +#define AUDIO_PLL_MOD_STEP_OFFSET 0x000002f8 +#define AUDIO_PLL_MOD_STEP_FRAC_MSB 31 +#define AUDIO_PLL_MOD_STEP_FRAC_LSB 14 +#define AUDIO_PLL_MOD_STEP_FRAC_MASK 0xffffc000 +#define AUDIO_PLL_MOD_STEP_FRAC_GET(x) (((x) & AUDIO_PLL_MOD_STEP_FRAC_MASK) >> AUDIO_PLL_MOD_STEP_FRAC_LSB) +#define AUDIO_PLL_MOD_STEP_FRAC_SET(x) (((x) << AUDIO_PLL_MOD_STEP_FRAC_LSB) & AUDIO_PLL_MOD_STEP_FRAC_MASK) +#define AUDIO_PLL_MOD_STEP_INT_MSB 13 +#define AUDIO_PLL_MOD_STEP_INT_LSB 4 +#define AUDIO_PLL_MOD_STEP_INT_MASK 0x00003ff0 +#define AUDIO_PLL_MOD_STEP_INT_GET(x) (((x) & AUDIO_PLL_MOD_STEP_INT_MASK) >> AUDIO_PLL_MOD_STEP_INT_LSB) +#define AUDIO_PLL_MOD_STEP_INT_SET(x) (((x) << AUDIO_PLL_MOD_STEP_INT_LSB) & AUDIO_PLL_MOD_STEP_INT_MASK) +#define AUDIO_PLL_MOD_STEP_UPDATE_CNT_MSB 3 +#define AUDIO_PLL_MOD_STEP_UPDATE_CNT_LSB 0 +#define AUDIO_PLL_MOD_STEP_UPDATE_CNT_MASK 0x0000000f +#define AUDIO_PLL_MOD_STEP_UPDATE_CNT_GET(x) (((x) & AUDIO_PLL_MOD_STEP_UPDATE_CNT_MASK) >> AUDIO_PLL_MOD_STEP_UPDATE_CNT_LSB) +#define AUDIO_PLL_MOD_STEP_UPDATE_CNT_SET(x) (((x) << AUDIO_PLL_MOD_STEP_UPDATE_CNT_LSB) & AUDIO_PLL_MOD_STEP_UPDATE_CNT_MASK) + +#define CURRENT_AUDIO_PLL_MODULATION_ADDRESS 0x000002fc +#define CURRENT_AUDIO_PLL_MODULATION_OFFSET 0x000002fc +#define CURRENT_AUDIO_PLL_MODULATION_FRAC_MSB 27 +#define CURRENT_AUDIO_PLL_MODULATION_FRAC_LSB 10 +#define CURRENT_AUDIO_PLL_MODULATION_FRAC_MASK 0x0ffffc00 +#define CURRENT_AUDIO_PLL_MODULATION_FRAC_GET(x) (((x) & CURRENT_AUDIO_PLL_MODULATION_FRAC_MASK) >> CURRENT_AUDIO_PLL_MODULATION_FRAC_LSB) +#define CURRENT_AUDIO_PLL_MODULATION_FRAC_SET(x) (((x) << CURRENT_AUDIO_PLL_MODULATION_FRAC_LSB) & CURRENT_AUDIO_PLL_MODULATION_FRAC_MASK) +#define CURRENT_AUDIO_PLL_MODULATION_INT_MSB 6 +#define CURRENT_AUDIO_PLL_MODULATION_INT_LSB 1 +#define CURRENT_AUDIO_PLL_MODULATION_INT_MASK 0x0000007e +#define CURRENT_AUDIO_PLL_MODULATION_INT_GET(x) (((x) & CURRENT_AUDIO_PLL_MODULATION_INT_MASK) >> CURRENT_AUDIO_PLL_MODULATION_INT_LSB) +#define CURRENT_AUDIO_PLL_MODULATION_INT_SET(x) (((x) << CURRENT_AUDIO_PLL_MODULATION_INT_LSB) & CURRENT_AUDIO_PLL_MODULATION_INT_MASK) + +#define ETH_PLL_CONFIG_ADDRESS 0x00000300 +#define ETH_PLL_CONFIG_OFFSET 0x00000300 +#define ETH_PLL_CONFIG_GE0_MASTER_MSB 30 +#define ETH_PLL_CONFIG_GE0_MASTER_LSB 30 +#define ETH_PLL_CONFIG_GE0_MASTER_MASK 0x40000000 +#define ETH_PLL_CONFIG_GE0_MASTER_GET(x) (((x) & ETH_PLL_CONFIG_GE0_MASTER_MASK) >> ETH_PLL_CONFIG_GE0_MASTER_LSB) +#define ETH_PLL_CONFIG_GE0_MASTER_SET(x) (((x) << ETH_PLL_CONFIG_GE0_MASTER_LSB) & ETH_PLL_CONFIG_GE0_MASTER_MASK) +#define ETH_PLL_CONFIG_GE0_MSB 29 +#define ETH_PLL_CONFIG_GE0_LSB 29 +#define ETH_PLL_CONFIG_GE0_MASK 0x20000000 +#define ETH_PLL_CONFIG_GE0_GET(x) (((x) & ETH_PLL_CONFIG_GE0_MASK) >> ETH_PLL_CONFIG_GE0_LSB) +#define ETH_PLL_CONFIG_GE0_SET(x) (((x) << ETH_PLL_CONFIG_GE0_LSB) & ETH_PLL_CONFIG_GE0_MASK) +#define ETH_PLL_CONFIG_RANGE_MSB 28 +#define ETH_PLL_CONFIG_RANGE_LSB 28 +#define ETH_PLL_CONFIG_RANGE_MASK 0x10000000 +#define ETH_PLL_CONFIG_RANGE_GET(x) (((x) & ETH_PLL_CONFIG_RANGE_MASK) >> ETH_PLL_CONFIG_RANGE_LSB) +#define ETH_PLL_CONFIG_RANGE_SET(x) (((x) << ETH_PLL_CONFIG_RANGE_LSB) & ETH_PLL_CONFIG_RANGE_MASK) +#define ETH_PLL_CONFIG_FRAC_MSB 27 +#define ETH_PLL_CONFIG_FRAC_LSB 18 +#define ETH_PLL_CONFIG_FRAC_MASK 0x0ffc0000 +#define ETH_PLL_CONFIG_FRAC_GET(x) (((x) & ETH_PLL_CONFIG_FRAC_MASK) >> ETH_PLL_CONFIG_FRAC_LSB) +#define ETH_PLL_CONFIG_FRAC_SET(x) (((x) << ETH_PLL_CONFIG_FRAC_LSB) & ETH_PLL_CONFIG_FRAC_MASK) +#define ETH_PLL_CONFIG_INT_MSB 17 +#define ETH_PLL_CONFIG_INT_LSB 12 +#define ETH_PLL_CONFIG_INT_MASK 0x0003f000 +#define ETH_PLL_CONFIG_INT_GET(x) (((x) & ETH_PLL_CONFIG_INT_MASK) >> ETH_PLL_CONFIG_INT_LSB) +#define ETH_PLL_CONFIG_INT_SET(x) (((x) << ETH_PLL_CONFIG_INT_LSB) & ETH_PLL_CONFIG_INT_MASK) +#define ETH_PLL_CONFIG_OUTDIV_MSB 9 +#define ETH_PLL_CONFIG_OUTDIV_LSB 7 +#define ETH_PLL_CONFIG_OUTDIV_MASK 0x00000380 +#define ETH_PLL_CONFIG_OUTDIV_GET(x) (((x) & ETH_PLL_CONFIG_OUTDIV_MASK) >> ETH_PLL_CONFIG_OUTDIV_LSB) +#define ETH_PLL_CONFIG_OUTDIV_SET(x) (((x) << ETH_PLL_CONFIG_OUTDIV_LSB) & ETH_PLL_CONFIG_OUTDIV_MASK) +#define ETH_PLL_CONFIG_PLLPWD_MSB 6 +#define ETH_PLL_CONFIG_PLLPWD_LSB 6 +#define ETH_PLL_CONFIG_PLLPWD_MASK 0x00000040 +#define ETH_PLL_CONFIG_PLLPWD_GET(x) (((x) & ETH_PLL_CONFIG_PLLPWD_MASK) >> ETH_PLL_CONFIG_PLLPWD_LSB) +#define ETH_PLL_CONFIG_PLLPWD_SET(x) (((x) << ETH_PLL_CONFIG_PLLPWD_LSB) & ETH_PLL_CONFIG_PLLPWD_MASK) +#define ETH_PLL_CONFIG_BYPASS_MSB 5 +#define ETH_PLL_CONFIG_BYPASS_LSB 5 +#define ETH_PLL_CONFIG_BYPASS_MASK 0x00000020 +#define ETH_PLL_CONFIG_BYPASS_GET(x) (((x) & ETH_PLL_CONFIG_BYPASS_MASK) >> ETH_PLL_CONFIG_BYPASS_LSB) +#define ETH_PLL_CONFIG_BYPASS_SET(x) (((x) << ETH_PLL_CONFIG_BYPASS_LSB) & ETH_PLL_CONFIG_BYPASS_MASK) +#define ETH_PLL_CONFIG_REFDIV_MSB 4 +#define ETH_PLL_CONFIG_REFDIV_LSB 0 +#define ETH_PLL_CONFIG_REFDIV_MASK 0x0000001f +#define ETH_PLL_CONFIG_REFDIV_GET(x) (((x) & ETH_PLL_CONFIG_REFDIV_MASK) >> ETH_PLL_CONFIG_REFDIV_LSB) +#define ETH_PLL_CONFIG_REFDIV_SET(x) (((x) << ETH_PLL_CONFIG_REFDIV_LSB) & ETH_PLL_CONFIG_REFDIV_MASK) + +#define CPU_PLL_CONFIG_ADDRESS 0x00000304 +#define CPU_PLL_CONFIG_OFFSET 0x00000304 +#define CPU_PLL_CONFIG_RANGE_MSB 28 +#define CPU_PLL_CONFIG_RANGE_LSB 28 +#define CPU_PLL_CONFIG_RANGE_MASK 0x10000000 +#define CPU_PLL_CONFIG_RANGE_GET(x) (((x) & CPU_PLL_CONFIG_RANGE_MASK) >> CPU_PLL_CONFIG_RANGE_LSB) +#define CPU_PLL_CONFIG_RANGE_SET(x) (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK) +#define CPU_PLL_CONFIG_FRAC_MSB 25 +#define CPU_PLL_CONFIG_FRAC_LSB 20 +#define CPU_PLL_CONFIG_FRAC_MASK 0x03f00000 +#define CPU_PLL_CONFIG_FRAC_GET(x) (((x) & CPU_PLL_CONFIG_FRAC_MASK) >> CPU_PLL_CONFIG_FRAC_LSB) +#define CPU_PLL_CONFIG_FRAC_SET(x) (((x) << CPU_PLL_CONFIG_FRAC_LSB) & CPU_PLL_CONFIG_FRAC_MASK) +#define CPU_PLL_CONFIG_INT_MSB 17 +#define CPU_PLL_CONFIG_INT_LSB 12 +#define CPU_PLL_CONFIG_INT_MASK 0x0003f000 +#define CPU_PLL_CONFIG_INT_GET(x) (((x) & CPU_PLL_CONFIG_INT_MASK) >> CPU_PLL_CONFIG_INT_LSB) +#define CPU_PLL_CONFIG_INT_SET(x) (((x) << CPU_PLL_CONFIG_INT_LSB) & CPU_PLL_CONFIG_INT_MASK) +#define CPU_PLL_CONFIG_OUTDIV_MSB 9 +#define CPU_PLL_CONFIG_OUTDIV_LSB 7 +#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00000380 +#define CPU_PLL_CONFIG_OUTDIV_GET(x) (((x) & CPU_PLL_CONFIG_OUTDIV_MASK) >> CPU_PLL_CONFIG_OUTDIV_LSB) +#define CPU_PLL_CONFIG_OUTDIV_SET(x) (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK) +#define CPU_PLL_CONFIG_PLLPWD_MSB 6 +#define CPU_PLL_CONFIG_PLLPWD_LSB 6 +#define CPU_PLL_CONFIG_PLLPWD_MASK 0x00000040 +#define CPU_PLL_CONFIG_PLLPWD_GET(x) (((x) & CPU_PLL_CONFIG_PLLPWD_MASK) >> CPU_PLL_CONFIG_PLLPWD_LSB) +#define CPU_PLL_CONFIG_PLLPWD_SET(x) (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK) +#define CPU_PLL_CONFIG_REFDIV_MSB 4 +#define CPU_PLL_CONFIG_REFDIV_LSB 0 +#define CPU_PLL_CONFIG_REFDIV_MASK 0x0000001f +#define CPU_PLL_CONFIG_REFDIV_GET(x) (((x) & CPU_PLL_CONFIG_REFDIV_MASK) >> CPU_PLL_CONFIG_REFDIV_LSB) +#define CPU_PLL_CONFIG_REFDIV_SET(x) (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK) + +#define BB_PLL_CONFIG_ADDRESS 0x00000308 +#define BB_PLL_CONFIG_OFFSET 0x00000308 +#define BB_PLL_CONFIG_FRAC_MSB 17 +#define BB_PLL_CONFIG_FRAC_LSB 0 +#define BB_PLL_CONFIG_FRAC_MASK 0x0003ffff +#define BB_PLL_CONFIG_FRAC_GET(x) (((x) & BB_PLL_CONFIG_FRAC_MASK) >> BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_SET(x) (((x) << BB_PLL_CONFIG_FRAC_LSB) & BB_PLL_CONFIG_FRAC_MASK) + +#define ETH_XMII_ADDRESS 0x0000030c +#define ETH_XMII_OFFSET 0x0000030c +#define ETH_XMII_TX_INVERT_MSB 31 +#define ETH_XMII_TX_INVERT_LSB 31 +#define ETH_XMII_TX_INVERT_MASK 0x80000000 +#define ETH_XMII_TX_INVERT_GET(x) (((x) & ETH_XMII_TX_INVERT_MASK) >> ETH_XMII_TX_INVERT_LSB) +#define ETH_XMII_TX_INVERT_SET(x) (((x) << ETH_XMII_TX_INVERT_LSB) & ETH_XMII_TX_INVERT_MASK) +#define ETH_XMII_GIGE_QUAD_MSB 30 +#define ETH_XMII_GIGE_QUAD_LSB 30 +#define ETH_XMII_GIGE_QUAD_MASK 0x40000000 +#define ETH_XMII_GIGE_QUAD_GET(x) (((x) & ETH_XMII_GIGE_QUAD_MASK) >> ETH_XMII_GIGE_QUAD_LSB) +#define ETH_XMII_GIGE_QUAD_SET(x) (((x) << ETH_XMII_GIGE_QUAD_LSB) & ETH_XMII_GIGE_QUAD_MASK) +#define ETH_XMII_RX_DELAY_MSB 29 +#define ETH_XMII_RX_DELAY_LSB 28 +#define ETH_XMII_RX_DELAY_MASK 0x30000000 +#define ETH_XMII_RX_DELAY_GET(x) (((x) & ETH_XMII_RX_DELAY_MASK) >> ETH_XMII_RX_DELAY_LSB) +#define ETH_XMII_RX_DELAY_SET(x) (((x) << ETH_XMII_RX_DELAY_LSB) & ETH_XMII_RX_DELAY_MASK) +#define ETH_XMII_TX_DELAY_MSB 27 +#define ETH_XMII_TX_DELAY_LSB 26 +#define ETH_XMII_TX_DELAY_MASK 0x0c000000 +#define ETH_XMII_TX_DELAY_GET(x) (((x) & ETH_XMII_TX_DELAY_MASK) >> ETH_XMII_TX_DELAY_LSB) +#define ETH_XMII_TX_DELAY_SET(x) (((x) << ETH_XMII_TX_DELAY_LSB) & ETH_XMII_TX_DELAY_MASK) +#define ETH_XMII_GIGE_MSB 25 +#define ETH_XMII_GIGE_LSB 25 +#define ETH_XMII_GIGE_MASK 0x02000000 +#define ETH_XMII_GIGE_GET(x) (((x) & ETH_XMII_GIGE_MASK) >> ETH_XMII_GIGE_LSB) +#define ETH_XMII_GIGE_SET(x) (((x) << ETH_XMII_GIGE_LSB) & ETH_XMII_GIGE_MASK) +#define ETH_XMII_OFFSET_PHASE_MSB 24 +#define ETH_XMII_OFFSET_PHASE_LSB 24 +#define ETH_XMII_OFFSET_PHASE_MASK 0x01000000 +#define ETH_XMII_OFFSET_PHASE_GET(x) (((x) & ETH_XMII_OFFSET_PHASE_MASK) >> ETH_XMII_OFFSET_PHASE_LSB) +#define ETH_XMII_OFFSET_PHASE_SET(x) (((x) << ETH_XMII_OFFSET_PHASE_LSB) & ETH_XMII_OFFSET_PHASE_MASK) +#define ETH_XMII_OFFSET_COUNT_MSB 23 +#define ETH_XMII_OFFSET_COUNT_LSB 16 +#define ETH_XMII_OFFSET_COUNT_MASK 0x00ff0000 +#define ETH_XMII_OFFSET_COUNT_GET(x) (((x) & ETH_XMII_OFFSET_COUNT_MASK) >> ETH_XMII_OFFSET_COUNT_LSB) +#define ETH_XMII_OFFSET_COUNT_SET(x) (((x) << ETH_XMII_OFFSET_COUNT_LSB) & ETH_XMII_OFFSET_COUNT_MASK) +#define ETH_XMII_PHASE1_COUNT_MSB 15 +#define ETH_XMII_PHASE1_COUNT_LSB 8 +#define ETH_XMII_PHASE1_COUNT_MASK 0x0000ff00 +#define ETH_XMII_PHASE1_COUNT_GET(x) (((x) & ETH_XMII_PHASE1_COUNT_MASK) >> ETH_XMII_PHASE1_COUNT_LSB) +#define ETH_XMII_PHASE1_COUNT_SET(x) (((x) << ETH_XMII_PHASE1_COUNT_LSB) & ETH_XMII_PHASE1_COUNT_MASK) +#define ETH_XMII_PHASE0_COUNT_MSB 7 +#define ETH_XMII_PHASE0_COUNT_LSB 0 +#define ETH_XMII_PHASE0_COUNT_MASK 0x000000ff +#define ETH_XMII_PHASE0_COUNT_GET(x) (((x) & ETH_XMII_PHASE0_COUNT_MASK) >> ETH_XMII_PHASE0_COUNT_LSB) +#define ETH_XMII_PHASE0_COUNT_SET(x) (((x) << ETH_XMII_PHASE0_COUNT_LSB) & ETH_XMII_PHASE0_COUNT_MASK) + +#define USB_PHY_CONFIG_ADDRESS 0x00000310 +#define USB_PHY_CONFIG_OFFSET 0x00000310 +#define USB_PHY_CONFIG_REFCLK_SEL_MSB 7 +#define USB_PHY_CONFIG_REFCLK_SEL_LSB 4 +#define USB_PHY_CONFIG_REFCLK_SEL_MASK 0x000000f0 +#define USB_PHY_CONFIG_REFCLK_SEL_GET(x) (((x) & USB_PHY_CONFIG_REFCLK_SEL_MASK) >> USB_PHY_CONFIG_REFCLK_SEL_LSB) +#define USB_PHY_CONFIG_REFCLK_SEL_SET(x) (((x) << USB_PHY_CONFIG_REFCLK_SEL_LSB) & USB_PHY_CONFIG_REFCLK_SEL_MASK) +#define USB_PHY_CONFIG_REFDIV_MSB 3 +#define USB_PHY_CONFIG_REFDIV_LSB 3 +#define USB_PHY_CONFIG_REFDIV_MASK 0x00000008 +#define USB_PHY_CONFIG_REFDIV_GET(x) (((x) & USB_PHY_CONFIG_REFDIV_MASK) >> USB_PHY_CONFIG_REFDIV_LSB) +#define USB_PHY_CONFIG_REFDIV_SET(x) (((x) << USB_PHY_CONFIG_REFDIV_LSB) & USB_PHY_CONFIG_REFDIV_MASK) +#define USB_PHY_CONFIG_TESTMODE_MSB 2 +#define USB_PHY_CONFIG_TESTMODE_LSB 2 +#define USB_PHY_CONFIG_TESTMODE_MASK 0x00000004 +#define USB_PHY_CONFIG_TESTMODE_GET(x) (((x) & USB_PHY_CONFIG_TESTMODE_MASK) >> USB_PHY_CONFIG_TESTMODE_LSB) +#define USB_PHY_CONFIG_TESTMODE_SET(x) (((x) << USB_PHY_CONFIG_TESTMODE_LSB) & USB_PHY_CONFIG_TESTMODE_MASK) +#define USB_PHY_CONFIG_PLL_PWD_MSB 1 +#define USB_PHY_CONFIG_PLL_PWD_LSB 1 +#define USB_PHY_CONFIG_PLL_PWD_MASK 0x00000002 +#define USB_PHY_CONFIG_PLL_PWD_GET(x) (((x) & USB_PHY_CONFIG_PLL_PWD_MASK) >> USB_PHY_CONFIG_PLL_PWD_LSB) +#define USB_PHY_CONFIG_PLL_PWD_SET(x) (((x) << USB_PHY_CONFIG_PLL_PWD_LSB) & USB_PHY_CONFIG_PLL_PWD_MASK) +#define USB_PHY_CONFIG_HOSTMODE_MSB 0 +#define USB_PHY_CONFIG_HOSTMODE_LSB 0 +#define USB_PHY_CONFIG_HOSTMODE_MASK 0x00000001 +#define USB_PHY_CONFIG_HOSTMODE_GET(x) (((x) & USB_PHY_CONFIG_HOSTMODE_MASK) >> USB_PHY_CONFIG_HOSTMODE_LSB) +#define USB_PHY_CONFIG_HOSTMODE_SET(x) (((x) << USB_PHY_CONFIG_HOSTMODE_LSB) & USB_PHY_CONFIG_HOSTMODE_MASK) + +#define USBCORE_CLK60M_ADDRESS 0x00000314 +#define USBCORE_CLK60M_OFFSET 0x00000314 +#define USBCORE_CLK60M_SEL_MSB 0 +#define USBCORE_CLK60M_SEL_LSB 0 +#define USBCORE_CLK60M_SEL_MASK 0x00000001 +#define USBCORE_CLK60M_SEL_GET(x) (((x) & USBCORE_CLK60M_SEL_MASK) >> USBCORE_CLK60M_SEL_LSB) +#define USBCORE_CLK60M_SEL_SET(x) (((x) << USBCORE_CLK60M_SEL_LSB) & USBCORE_CLK60M_SEL_MASK) + +#define USBPHY_UTMI_CLK_ADDRESS 0x00000318 +#define USBPHY_UTMI_CLK_OFFSET 0x00000318 +#define USBPHY_UTMI_CLK_EN_MSB 0 +#define USBPHY_UTMI_CLK_EN_LSB 0 +#define USBPHY_UTMI_CLK_EN_MASK 0x00000001 +#define USBPHY_UTMI_CLK_EN_GET(x) (((x) & USBPHY_UTMI_CLK_EN_MASK) >> USBPHY_UTMI_CLK_EN_LSB) +#define USBPHY_UTMI_CLK_EN_SET(x) (((x) << USBPHY_UTMI_CLK_EN_LSB) & USBPHY_UTMI_CLK_EN_MASK) + +#define USB_TXVALID_DLY_CONFIG_ADDRESS 0x0000031c +#define USB_TXVALID_DLY_CONFIG_OFFSET 0x0000031c +#define USB_TXVALID_DLY_CONFIG_UTMI16_MSB 7 +#define USB_TXVALID_DLY_CONFIG_UTMI16_LSB 4 +#define USB_TXVALID_DLY_CONFIG_UTMI16_MASK 0x000000f0 +#define USB_TXVALID_DLY_CONFIG_UTMI16_GET(x) (((x) & USB_TXVALID_DLY_CONFIG_UTMI16_MASK) >> USB_TXVALID_DLY_CONFIG_UTMI16_LSB) +#define USB_TXVALID_DLY_CONFIG_UTMI16_SET(x) (((x) << USB_TXVALID_DLY_CONFIG_UTMI16_LSB) & USB_TXVALID_DLY_CONFIG_UTMI16_MASK) +#define USB_TXVALID_DLY_CONFIG_UTMI8_MSB 3 +#define USB_TXVALID_DLY_CONFIG_UTMI8_LSB 0 +#define USB_TXVALID_DLY_CONFIG_UTMI8_MASK 0x0000000f +#define USB_TXVALID_DLY_CONFIG_UTMI8_GET(x) (((x) & USB_TXVALID_DLY_CONFIG_UTMI8_MASK) >> USB_TXVALID_DLY_CONFIG_UTMI8_LSB) +#define USB_TXVALID_DLY_CONFIG_UTMI8_SET(x) (((x) << USB_TXVALID_DLY_CONFIG_UTMI8_LSB) & USB_TXVALID_DLY_CONFIG_UTMI8_MASK) + +#define SECOND_HOST_INFT_ADDRESS 0x00000320 +#define SECOND_HOST_INFT_OFFSET 0x00000320 +#define SECOND_HOST_INFT_SDIO_MODE_MSB 0 +#define SECOND_HOST_INFT_SDIO_MODE_LSB 0 +#define SECOND_HOST_INFT_SDIO_MODE_MASK 0x00000001 +#define SECOND_HOST_INFT_SDIO_MODE_GET(x) (((x) & SECOND_HOST_INFT_SDIO_MODE_MASK) >> SECOND_HOST_INFT_SDIO_MODE_LSB) +#define SECOND_HOST_INFT_SDIO_MODE_SET(x) (((x) << SECOND_HOST_INFT_SDIO_MODE_LSB) & SECOND_HOST_INFT_SDIO_MODE_MASK) + +#define SDIO_HOST_ADDRESS 0x00000324 +#define SDIO_HOST_OFFSET 0x00000324 +#define SDIO_HOST_RESET_MSB 0 +#define SDIO_HOST_RESET_LSB 0 +#define SDIO_HOST_RESET_MASK 0x00000001 +#define SDIO_HOST_RESET_GET(x) (((x) & SDIO_HOST_RESET_MASK) >> SDIO_HOST_RESET_LSB) +#define SDIO_HOST_RESET_SET(x) (((x) << SDIO_HOST_RESET_LSB) & SDIO_HOST_RESET_MASK) + +#define ENTERPRISE_CONFIG_ADDRESS 0x00000328 +#define ENTERPRISE_CONFIG_OFFSET 0x00000328 +#define ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_MSB 12 +#define ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_LSB 12 +#define ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_MASK 0x00001000 +#define ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_GET(x) (((x) & ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_MASK) >> ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_LSB) +#define ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_SET(x) (((x) << ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_LSB) & ENTERPRISE_CONFIG_TPC_LOWER_PERFORMANCE_MASK) +#define ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_MSB 11 +#define ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_LSB 11 +#define ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_MASK 0x00000800 +#define ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_GET(x) (((x) & ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_MASK) >> ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_LSB) +#define ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_SET(x) (((x) << ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_LSB) & ENTERPRISE_CONFIG_SWCOM_IDLE_MODE_MASK) +#define ENTERPRISE_CONFIG_STBC_DISABLE_MSB 10 +#define ENTERPRISE_CONFIG_STBC_DISABLE_LSB 10 +#define ENTERPRISE_CONFIG_STBC_DISABLE_MASK 0x00000400 +#define ENTERPRISE_CONFIG_STBC_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_STBC_DISABLE_MASK) >> ENTERPRISE_CONFIG_STBC_DISABLE_LSB) +#define ENTERPRISE_CONFIG_STBC_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_STBC_DISABLE_LSB) & ENTERPRISE_CONFIG_STBC_DISABLE_MASK) +#define ENTERPRISE_CONFIG_LDPC_DISABLE_MSB 9 +#define ENTERPRISE_CONFIG_LDPC_DISABLE_LSB 9 +#define ENTERPRISE_CONFIG_LDPC_DISABLE_MASK 0x00000200 +#define ENTERPRISE_CONFIG_LDPC_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_LDPC_DISABLE_MASK) >> ENTERPRISE_CONFIG_LDPC_DISABLE_LSB) +#define ENTERPRISE_CONFIG_LDPC_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_LDPC_DISABLE_LSB) & ENTERPRISE_CONFIG_LDPC_DISABLE_MASK) +#define ENTERPRISE_CONFIG_GREEN_TX_DISABLE_MSB 8 +#define ENTERPRISE_CONFIG_GREEN_TX_DISABLE_LSB 8 +#define ENTERPRISE_CONFIG_GREEN_TX_DISABLE_MASK 0x00000100 +#define ENTERPRISE_CONFIG_GREEN_TX_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_GREEN_TX_DISABLE_MASK) >> ENTERPRISE_CONFIG_GREEN_TX_DISABLE_LSB) +#define ENTERPRISE_CONFIG_GREEN_TX_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_GREEN_TX_DISABLE_LSB) & ENTERPRISE_CONFIG_GREEN_TX_DISABLE_MASK) +#define ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_MSB 7 +#define ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_LSB 7 +#define ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_MASK 0x00000080 +#define ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_MASK) >> ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_LSB) +#define ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_LSB) & ENTERPRISE_CONFIG_DUAL_BAND_DISABLE_MASK) +#define ENTERPRISE_CONFIG_CHAIN1_DISABLE_MSB 6 +#define ENTERPRISE_CONFIG_CHAIN1_DISABLE_LSB 6 +#define ENTERPRISE_CONFIG_CHAIN1_DISABLE_MASK 0x00000040 +#define ENTERPRISE_CONFIG_CHAIN1_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_CHAIN1_DISABLE_MASK) >> ENTERPRISE_CONFIG_CHAIN1_DISABLE_LSB) +#define ENTERPRISE_CONFIG_CHAIN1_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_CHAIN1_DISABLE_LSB) & ENTERPRISE_CONFIG_CHAIN1_DISABLE_MASK) +#define ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_MSB 5 +#define ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_LSB 5 +#define ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_MASK 0x00000020 +#define ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_MASK) >> ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_LSB) +#define ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_LSB) & ENTERPRISE_CONFIG_CH_5MHZ_DISABLE_MASK) +#define ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_MSB 4 +#define ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_LSB 4 +#define ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_MASK 0x00000010 +#define ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_MASK) >> ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_LSB) +#define ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_LSB) & ENTERPRISE_CONFIG_CH_10MHZ_DISABLE_MASK) +#define ENTERPRISE_CONFIG_TXBF_DISABLE_MSB 3 +#define ENTERPRISE_CONFIG_TXBF_DISABLE_LSB 3 +#define ENTERPRISE_CONFIG_TXBF_DISABLE_MASK 0x00000008 +#define ENTERPRISE_CONFIG_TXBF_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_TXBF_DISABLE_MASK) >> ENTERPRISE_CONFIG_TXBF_DISABLE_LSB) +#define ENTERPRISE_CONFIG_TXBF_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_TXBF_DISABLE_LSB) & ENTERPRISE_CONFIG_TXBF_DISABLE_MASK) +#define ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_MSB 2 +#define ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_LSB 2 +#define ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_MASK 0x00000004 +#define ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_MASK) >> ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_LSB) +#define ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_LSB) & ENTERPRISE_CONFIG_MIN_PKT_SIZE_DISABLE_MASK) +#define ENTERPRISE_CONFIG_LOOPBACK_DISABLE_MSB 1 +#define ENTERPRISE_CONFIG_LOOPBACK_DISABLE_LSB 1 +#define ENTERPRISE_CONFIG_LOOPBACK_DISABLE_MASK 0x00000002 +#define ENTERPRISE_CONFIG_LOOPBACK_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_LOOPBACK_DISABLE_MASK) >> ENTERPRISE_CONFIG_LOOPBACK_DISABLE_LSB) +#define ENTERPRISE_CONFIG_LOOPBACK_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_LOOPBACK_DISABLE_LSB) & ENTERPRISE_CONFIG_LOOPBACK_DISABLE_MASK) +#define ENTERPRISE_CONFIG_LOCATION_DISABLE_MSB 0 +#define ENTERPRISE_CONFIG_LOCATION_DISABLE_LSB 0 +#define ENTERPRISE_CONFIG_LOCATION_DISABLE_MASK 0x00000001 +#define ENTERPRISE_CONFIG_LOCATION_DISABLE_GET(x) (((x) & ENTERPRISE_CONFIG_LOCATION_DISABLE_MASK) >> ENTERPRISE_CONFIG_LOCATION_DISABLE_LSB) +#define ENTERPRISE_CONFIG_LOCATION_DISABLE_SET(x) (((x) << ENTERPRISE_CONFIG_LOCATION_DISABLE_LSB) & ENTERPRISE_CONFIG_LOCATION_DISABLE_MASK) + +#define RTC_DEBUG_BUS_ADDRESS 0x0000032c +#define RTC_DEBUG_BUS_OFFSET 0x0000032c +#define RTC_DEBUG_BUS_SEL_MSB 0 +#define RTC_DEBUG_BUS_SEL_LSB 0 +#define RTC_DEBUG_BUS_SEL_MASK 0x00000001 +#define RTC_DEBUG_BUS_SEL_GET(x) (((x) & RTC_DEBUG_BUS_SEL_MASK) >> RTC_DEBUG_BUS_SEL_LSB) +#define RTC_DEBUG_BUS_SEL_SET(x) (((x) << RTC_DEBUG_BUS_SEL_LSB) & RTC_DEBUG_BUS_SEL_MASK) + +#define RTC_EXT_CLK_BUF_ADDRESS 0x00000330 +#define RTC_EXT_CLK_BUF_OFFSET 0x00000330 +#define RTC_EXT_CLK_BUF_EN_MSB 0 +#define RTC_EXT_CLK_BUF_EN_LSB 0 +#define RTC_EXT_CLK_BUF_EN_MASK 0x00000001 +#define RTC_EXT_CLK_BUF_EN_GET(x) (((x) & RTC_EXT_CLK_BUF_EN_MASK) >> RTC_EXT_CLK_BUF_EN_LSB) +#define RTC_EXT_CLK_BUF_EN_SET(x) (((x) << RTC_EXT_CLK_BUF_EN_LSB) & RTC_EXT_CLK_BUF_EN_MASK) + +#define WLAN_AHB_BRIDGE_TIMEOUT_ADDRESS 0x00000334 +#define WLAN_AHB_BRIDGE_TIMEOUT_OFFSET 0x00000334 +#define WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_MSB 13 +#define WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_LSB 0 +#define WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_MASK 0x00003fff +#define WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_GET(x) (((x) & WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_MASK) >> WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_LSB) +#define WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_SET(x) (((x) << WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_LSB) & WLAN_AHB_BRIDGE_TIMEOUT_CONFIG_MASK) + +#define WLAN_AHB_CONFIG_ADDRESS 0x00000338 +#define WLAN_AHB_CONFIG_OFFSET 0x00000338 +#define WLAN_AHB_CONFIG_MAX_BURST_16_MSB 2 +#define WLAN_AHB_CONFIG_MAX_BURST_16_LSB 2 +#define WLAN_AHB_CONFIG_MAX_BURST_16_MASK 0x00000004 +#define WLAN_AHB_CONFIG_MAX_BURST_16_GET(x) (((x) & WLAN_AHB_CONFIG_MAX_BURST_16_MASK) >> WLAN_AHB_CONFIG_MAX_BURST_16_LSB) +#define WLAN_AHB_CONFIG_MAX_BURST_16_SET(x) (((x) << WLAN_AHB_CONFIG_MAX_BURST_16_LSB) & WLAN_AHB_CONFIG_MAX_BURST_16_MASK) +#define WLAN_AHB_CONFIG_MAX_BURST_8_MSB 1 +#define WLAN_AHB_CONFIG_MAX_BURST_8_LSB 1 +#define WLAN_AHB_CONFIG_MAX_BURST_8_MASK 0x00000002 +#define WLAN_AHB_CONFIG_MAX_BURST_8_GET(x) (((x) & WLAN_AHB_CONFIG_MAX_BURST_8_MASK) >> WLAN_AHB_CONFIG_MAX_BURST_8_LSB) +#define WLAN_AHB_CONFIG_MAX_BURST_8_SET(x) (((x) << WLAN_AHB_CONFIG_MAX_BURST_8_LSB) & WLAN_AHB_CONFIG_MAX_BURST_8_MASK) +#define WLAN_AHB_CONFIG_MAX_BURST_4_MSB 0 +#define WLAN_AHB_CONFIG_MAX_BURST_4_LSB 0 +#define WLAN_AHB_CONFIG_MAX_BURST_4_MASK 0x00000001 +#define WLAN_AHB_CONFIG_MAX_BURST_4_GET(x) (((x) & WLAN_AHB_CONFIG_MAX_BURST_4_MASK) >> WLAN_AHB_CONFIG_MAX_BURST_4_LSB) +#define WLAN_AHB_CONFIG_MAX_BURST_4_SET(x) (((x) << WLAN_AHB_CONFIG_MAX_BURST_4_LSB) & WLAN_AHB_CONFIG_MAX_BURST_4_MASK) + +#define RTC_AXI_AHB_BRIDGE_ADDRESS 0x0000033c +#define RTC_AXI_AHB_BRIDGE_OFFSET 0x0000033c +#define RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_MSB 3 +#define RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_LSB 3 +#define RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_MASK 0x00000008 +#define RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_GET(x) (((x) & RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_MASK) >> RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_LSB) +#define RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_SET(x) (((x) << RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_LSB) & RTC_AXI_AHB_BRIDGE_BURST_WR_ALIGN_EN_MASK) +#define RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_MSB 2 +#define RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_LSB 2 +#define RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_MASK 0x00000004 +#define RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_GET(x) (((x) & RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_MASK) >> RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_LSB) +#define RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_SET(x) (((x) << RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_LSB) & RTC_AXI_AHB_BRIDGE_BURST_RD_ALIGN_EN_MASK) +#define RTC_AXI_AHB_BRIDGE_MAX_BEATS_MSB 1 +#define RTC_AXI_AHB_BRIDGE_MAX_BEATS_LSB 0 +#define RTC_AXI_AHB_BRIDGE_MAX_BEATS_MASK 0x00000003 +#define RTC_AXI_AHB_BRIDGE_MAX_BEATS_GET(x) (((x) & RTC_AXI_AHB_BRIDGE_MAX_BEATS_MASK) >> RTC_AXI_AHB_BRIDGE_MAX_BEATS_LSB) +#define RTC_AXI_AHB_BRIDGE_MAX_BEATS_SET(x) (((x) << RTC_AXI_AHB_BRIDGE_MAX_BEATS_LSB) & RTC_AXI_AHB_BRIDGE_MAX_BEATS_MASK) + +#define WLAN2BT_CPUCOM_INT_STS_ADDRESS 0x00000400 +#define WLAN2BT_CPUCOM_INT_STS_OFFSET 0x00000400 +#define WLAN2BT_CPUCOM_INT_STS_REG_MSB 31 +#define WLAN2BT_CPUCOM_INT_STS_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_STS_REG_MASK 0xffffffff +#define WLAN2BT_CPUCOM_INT_STS_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_STS_REG_MASK) >> WLAN2BT_CPUCOM_INT_STS_REG_LSB) +#define WLAN2BT_CPUCOM_INT_STS_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_STS_REG_LSB) & WLAN2BT_CPUCOM_INT_STS_REG_MASK) + +#define WLAN2BT_CPUCOM_INT_MASK_N_ADDRESS 0x00000404 +#define WLAN2BT_CPUCOM_INT_MASK_N_OFFSET 0x00000404 +#define WLAN2BT_CPUCOM_INT_MASK_N_REG_MSB 31 +#define WLAN2BT_CPUCOM_INT_MASK_N_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_MASK_N_REG_MASK 0xffffffff +#define WLAN2BT_CPUCOM_INT_MASK_N_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_MASK_N_REG_MASK) >> WLAN2BT_CPUCOM_INT_MASK_N_REG_LSB) +#define WLAN2BT_CPUCOM_INT_MASK_N_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_MASK_N_REG_LSB) & WLAN2BT_CPUCOM_INT_MASK_N_REG_MASK) + +#define WLAN2BT_CPUCOM_INT_EOI_ADDRESS 0x00000408 +#define WLAN2BT_CPUCOM_INT_EOI_OFFSET 0x00000408 +#define WLAN2BT_CPUCOM_INT_EOI_REG_MSB 31 +#define WLAN2BT_CPUCOM_INT_EOI_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_EOI_REG_MASK 0xffffffff +#define WLAN2BT_CPUCOM_INT_EOI_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_EOI_REG_MASK) >> WLAN2BT_CPUCOM_INT_EOI_REG_LSB) +#define WLAN2BT_CPUCOM_INT_EOI_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_EOI_REG_LSB) & WLAN2BT_CPUCOM_INT_EOI_REG_MASK) + +#define WLAN2BT_CPUCOM_INT_ACK_STS_ADDRESS 0x0000040c +#define WLAN2BT_CPUCOM_INT_ACK_STS_OFFSET 0x0000040c +#define WLAN2BT_CPUCOM_INT_ACK_STS_REG_MSB 31 +#define WLAN2BT_CPUCOM_INT_ACK_STS_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_ACK_STS_REG_MASK 0xffffffff +#define WLAN2BT_CPUCOM_INT_ACK_STS_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_ACK_STS_REG_MASK) >> WLAN2BT_CPUCOM_INT_ACK_STS_REG_LSB) +#define WLAN2BT_CPUCOM_INT_ACK_STS_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_ACK_STS_REG_LSB) & WLAN2BT_CPUCOM_INT_ACK_STS_REG_MASK) + +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_ADDRESS 0x00000410 +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_OFFSET 0x00000410 +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_MSB 31 +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_MASK 0xffffffff +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_MASK) >> WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_LSB) +#define WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_LSB) & WLAN2BT_CPUCOM_INT_ACK_MASK_N_REG_MASK) + +#define WLAN_CPUCOM_CRD_CNT0_ADDRESS 0x00000414 +#define WLAN_CPUCOM_CRD_CNT0_OFFSET 0x00000414 +#define WLAN_CPUCOM_CRD_CNT0_REG_MSB 15 +#define WLAN_CPUCOM_CRD_CNT0_REG_LSB 0 +#define WLAN_CPUCOM_CRD_CNT0_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_CNT0_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_CNT0_REG_MASK) >> WLAN_CPUCOM_CRD_CNT0_REG_LSB) +#define WLAN_CPUCOM_CRD_CNT0_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_CNT0_REG_LSB) & WLAN_CPUCOM_CRD_CNT0_REG_MASK) + +#define WLAN_CPUCOM_CRD_INC0_ADDRESS 0x00000418 +#define WLAN_CPUCOM_CRD_INC0_OFFSET 0x00000418 +#define WLAN_CPUCOM_CRD_INC0_REG_MSB 15 +#define WLAN_CPUCOM_CRD_INC0_REG_LSB 0 +#define WLAN_CPUCOM_CRD_INC0_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_INC0_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_INC0_REG_MASK) >> WLAN_CPUCOM_CRD_INC0_REG_LSB) +#define WLAN_CPUCOM_CRD_INC0_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_INC0_REG_LSB) & WLAN_CPUCOM_CRD_INC0_REG_MASK) + +#define WLAN_CPUCOM_CRD_DEC0_ADDRESS 0x0000041c +#define WLAN_CPUCOM_CRD_DEC0_OFFSET 0x0000041c +#define WLAN_CPUCOM_CRD_DEC0_REG_MSB 15 +#define WLAN_CPUCOM_CRD_DEC0_REG_LSB 0 +#define WLAN_CPUCOM_CRD_DEC0_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_DEC0_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_DEC0_REG_MASK) >> WLAN_CPUCOM_CRD_DEC0_REG_LSB) +#define WLAN_CPUCOM_CRD_DEC0_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_DEC0_REG_LSB) & WLAN_CPUCOM_CRD_DEC0_REG_MASK) + +#define WLAN_CPUCOM_CRD_CNT1_ADDRESS 0x00000420 +#define WLAN_CPUCOM_CRD_CNT1_OFFSET 0x00000420 +#define WLAN_CPUCOM_CRD_CNT1_REG_MSB 15 +#define WLAN_CPUCOM_CRD_CNT1_REG_LSB 0 +#define WLAN_CPUCOM_CRD_CNT1_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_CNT1_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_CNT1_REG_MASK) >> WLAN_CPUCOM_CRD_CNT1_REG_LSB) +#define WLAN_CPUCOM_CRD_CNT1_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_CNT1_REG_LSB) & WLAN_CPUCOM_CRD_CNT1_REG_MASK) + +#define WLAN_CPUCOM_CRD_INC1_ADDRESS 0x00000424 +#define WLAN_CPUCOM_CRD_INC1_OFFSET 0x00000424 +#define WLAN_CPUCOM_CRD_INC1_REG_MSB 15 +#define WLAN_CPUCOM_CRD_INC1_REG_LSB 0 +#define WLAN_CPUCOM_CRD_INC1_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_INC1_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_INC1_REG_MASK) >> WLAN_CPUCOM_CRD_INC1_REG_LSB) +#define WLAN_CPUCOM_CRD_INC1_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_INC1_REG_LSB) & WLAN_CPUCOM_CRD_INC1_REG_MASK) + +#define WLAN_CPUCOM_CRD_DEC1_ADDRESS 0x00000428 +#define WLAN_CPUCOM_CRD_DEC1_OFFSET 0x00000428 +#define WLAN_CPUCOM_CRD_DEC1_REG_MSB 15 +#define WLAN_CPUCOM_CRD_DEC1_REG_LSB 0 +#define WLAN_CPUCOM_CRD_DEC1_REG_MASK 0x0000ffff +#define WLAN_CPUCOM_CRD_DEC1_REG_GET(x) (((x) & WLAN_CPUCOM_CRD_DEC1_REG_MASK) >> WLAN_CPUCOM_CRD_DEC1_REG_LSB) +#define WLAN_CPUCOM_CRD_DEC1_REG_SET(x) (((x) << WLAN_CPUCOM_CRD_DEC1_REG_LSB) & WLAN_CPUCOM_CRD_DEC1_REG_MASK) + +#define WLAN_CPUCOM_SCRATCH0_ADDRESS 0x0000042c +#define WLAN_CPUCOM_SCRATCH0_OFFSET 0x0000042c +#define WLAN_CPUCOM_SCRATCH0_REG_MSB 31 +#define WLAN_CPUCOM_SCRATCH0_REG_LSB 0 +#define WLAN_CPUCOM_SCRATCH0_REG_MASK 0xffffffff +#define WLAN_CPUCOM_SCRATCH0_REG_GET(x) (((x) & WLAN_CPUCOM_SCRATCH0_REG_MASK) >> WLAN_CPUCOM_SCRATCH0_REG_LSB) +#define WLAN_CPUCOM_SCRATCH0_REG_SET(x) (((x) << WLAN_CPUCOM_SCRATCH0_REG_LSB) & WLAN_CPUCOM_SCRATCH0_REG_MASK) + +#define WLAN_CPUCOM_SCRATCH1_ADDRESS 0x00000430 +#define WLAN_CPUCOM_SCRATCH1_OFFSET 0x00000430 +#define WLAN_CPUCOM_SCRATCH1_REG_MSB 31 +#define WLAN_CPUCOM_SCRATCH1_REG_LSB 0 +#define WLAN_CPUCOM_SCRATCH1_REG_MASK 0xffffffff +#define WLAN_CPUCOM_SCRATCH1_REG_GET(x) (((x) & WLAN_CPUCOM_SCRATCH1_REG_MASK) >> WLAN_CPUCOM_SCRATCH1_REG_LSB) +#define WLAN_CPUCOM_SCRATCH1_REG_SET(x) (((x) << WLAN_CPUCOM_SCRATCH1_REG_LSB) & WLAN_CPUCOM_SCRATCH1_REG_MASK) + +#define WLAN_CPUCOM_SCRATCH2_ADDRESS 0x00000434 +#define WLAN_CPUCOM_SCRATCH2_OFFSET 0x00000434 +#define WLAN_CPUCOM_SCRATCH2_REG_MSB 31 +#define WLAN_CPUCOM_SCRATCH2_REG_LSB 0 +#define WLAN_CPUCOM_SCRATCH2_REG_MASK 0xffffffff +#define WLAN_CPUCOM_SCRATCH2_REG_GET(x) (((x) & WLAN_CPUCOM_SCRATCH2_REG_MASK) >> WLAN_CPUCOM_SCRATCH2_REG_LSB) +#define WLAN_CPUCOM_SCRATCH2_REG_SET(x) (((x) << WLAN_CPUCOM_SCRATCH2_REG_LSB) & WLAN_CPUCOM_SCRATCH2_REG_MASK) + +#define WLAN_CPUCOM_SCRATCH3_ADDRESS 0x00000438 +#define WLAN_CPUCOM_SCRATCH3_OFFSET 0x00000438 +#define WLAN_CPUCOM_SCRATCH3_REG_MSB 31 +#define WLAN_CPUCOM_SCRATCH3_REG_LSB 0 +#define WLAN_CPUCOM_SCRATCH3_REG_MASK 0xffffffff +#define WLAN_CPUCOM_SCRATCH3_REG_GET(x) (((x) & WLAN_CPUCOM_SCRATCH3_REG_MASK) >> WLAN_CPUCOM_SCRATCH3_REG_LSB) +#define WLAN_CPUCOM_SCRATCH3_REG_SET(x) (((x) << WLAN_CPUCOM_SCRATCH3_REG_LSB) & WLAN_CPUCOM_SCRATCH3_REG_MASK) + +#define WLAN_CPUCOM_DBG_ADDRESS 0x0000043c +#define WLAN_CPUCOM_DBG_OFFSET 0x0000043c +#define WLAN_CPUCOM_DBG_RESERVE_MSB 7 +#define WLAN_CPUCOM_DBG_RESERVE_LSB 4 +#define WLAN_CPUCOM_DBG_RESERVE_MASK 0x000000f0 +#define WLAN_CPUCOM_DBG_RESERVE_GET(x) (((x) & WLAN_CPUCOM_DBG_RESERVE_MASK) >> WLAN_CPUCOM_DBG_RESERVE_LSB) +#define WLAN_CPUCOM_DBG_RESERVE_SET(x) (((x) << WLAN_CPUCOM_DBG_RESERVE_LSB) & WLAN_CPUCOM_DBG_RESERVE_MASK) +#define WLAN_CPUCOM_DBG_CRD1_DEC_ERR_MSB 3 +#define WLAN_CPUCOM_DBG_CRD1_DEC_ERR_LSB 3 +#define WLAN_CPUCOM_DBG_CRD1_DEC_ERR_MASK 0x00000008 +#define WLAN_CPUCOM_DBG_CRD1_DEC_ERR_GET(x) (((x) & WLAN_CPUCOM_DBG_CRD1_DEC_ERR_MASK) >> WLAN_CPUCOM_DBG_CRD1_DEC_ERR_LSB) +#define WLAN_CPUCOM_DBG_CRD1_DEC_ERR_SET(x) (((x) << WLAN_CPUCOM_DBG_CRD1_DEC_ERR_LSB) & WLAN_CPUCOM_DBG_CRD1_DEC_ERR_MASK) +#define WLAN_CPUCOM_DBG_CRD1_INC_ERR_MSB 2 +#define WLAN_CPUCOM_DBG_CRD1_INC_ERR_LSB 2 +#define WLAN_CPUCOM_DBG_CRD1_INC_ERR_MASK 0x00000004 +#define WLAN_CPUCOM_DBG_CRD1_INC_ERR_GET(x) (((x) & WLAN_CPUCOM_DBG_CRD1_INC_ERR_MASK) >> WLAN_CPUCOM_DBG_CRD1_INC_ERR_LSB) +#define WLAN_CPUCOM_DBG_CRD1_INC_ERR_SET(x) (((x) << WLAN_CPUCOM_DBG_CRD1_INC_ERR_LSB) & WLAN_CPUCOM_DBG_CRD1_INC_ERR_MASK) +#define WLAN_CPUCOM_DBG_CRD0_DEC_ERR_MSB 1 +#define WLAN_CPUCOM_DBG_CRD0_DEC_ERR_LSB 1 +#define WLAN_CPUCOM_DBG_CRD0_DEC_ERR_MASK 0x00000002 +#define WLAN_CPUCOM_DBG_CRD0_DEC_ERR_GET(x) (((x) & WLAN_CPUCOM_DBG_CRD0_DEC_ERR_MASK) >> WLAN_CPUCOM_DBG_CRD0_DEC_ERR_LSB) +#define WLAN_CPUCOM_DBG_CRD0_DEC_ERR_SET(x) (((x) << WLAN_CPUCOM_DBG_CRD0_DEC_ERR_LSB) & WLAN_CPUCOM_DBG_CRD0_DEC_ERR_MASK) +#define WLAN_CPUCOM_DBG_CRD0_INC_ERR_MSB 0 +#define WLAN_CPUCOM_DBG_CRD0_INC_ERR_LSB 0 +#define WLAN_CPUCOM_DBG_CRD0_INC_ERR_MASK 0x00000001 +#define WLAN_CPUCOM_DBG_CRD0_INC_ERR_GET(x) (((x) & WLAN_CPUCOM_DBG_CRD0_INC_ERR_MASK) >> WLAN_CPUCOM_DBG_CRD0_INC_ERR_LSB) +#define WLAN_CPUCOM_DBG_CRD0_INC_ERR_SET(x) (((x) << WLAN_CPUCOM_DBG_CRD0_INC_ERR_LSB) & WLAN_CPUCOM_DBG_CRD0_INC_ERR_MASK) + +#define WLAN2BT_CPUCOM_INT_ACK_EN_ADDRESS 0x00000440 +#define WLAN2BT_CPUCOM_INT_ACK_EN_OFFSET 0x00000440 +#define WLAN2BT_CPUCOM_INT_ACK_EN_REG_MSB 0 +#define WLAN2BT_CPUCOM_INT_ACK_EN_REG_LSB 0 +#define WLAN2BT_CPUCOM_INT_ACK_EN_REG_MASK 0x00000001 +#define WLAN2BT_CPUCOM_INT_ACK_EN_REG_GET(x) (((x) & WLAN2BT_CPUCOM_INT_ACK_EN_REG_MASK) >> WLAN2BT_CPUCOM_INT_ACK_EN_REG_LSB) +#define WLAN2BT_CPUCOM_INT_ACK_EN_REG_SET(x) (((x) << WLAN2BT_CPUCOM_INT_ACK_EN_REG_LSB) & WLAN2BT_CPUCOM_INT_ACK_EN_REG_MASK) + +#define BT2WLAN_CPUCOM_INT_EN_ADDRESS 0x00000444 +#define BT2WLAN_CPUCOM_INT_EN_OFFSET 0x00000444 +#define BT2WLAN_CPUCOM_INT_EN_REG_MSB 0 +#define BT2WLAN_CPUCOM_INT_EN_REG_LSB 0 +#define BT2WLAN_CPUCOM_INT_EN_REG_MASK 0x00000001 +#define BT2WLAN_CPUCOM_INT_EN_REG_GET(x) (((x) & BT2WLAN_CPUCOM_INT_EN_REG_MASK) >> BT2WLAN_CPUCOM_INT_EN_REG_LSB) +#define BT2WLAN_CPUCOM_INT_EN_REG_SET(x) (((x) << BT2WLAN_CPUCOM_INT_EN_REG_LSB) & BT2WLAN_CPUCOM_INT_EN_REG_MASK) + +#ifndef __ASSEMBLER__ +typedef struct rtc_soc_reg_reg_s { + volatile unsigned int soc_reset_control; + volatile unsigned int soc_tcxo_detect; + volatile unsigned int soc_xtal_test; + unsigned char pad0[20]; /* pad to 0x20 */ + volatile unsigned int soc_cpu_clock; + unsigned char pad1[4]; /* pad to 0x28 */ + volatile unsigned int soc_clock_control; + unsigned char pad2[4]; /* pad to 0x30 */ + volatile unsigned int soc_wdt_control; + volatile unsigned int soc_wdt_status; + volatile unsigned int soc_wdt; + volatile unsigned int soc_wdt_count; + volatile unsigned int soc_wdt_reset; + volatile unsigned int soc_int_status; + volatile unsigned int soc_lf_timer0; + volatile unsigned int soc_lf_timer_count0; + volatile unsigned int soc_lf_timer_control0; + volatile unsigned int soc_lf_timer_status0; + volatile unsigned int soc_lf_timer1; + volatile unsigned int soc_lf_timer_count1; + volatile unsigned int soc_lf_timer_control1; + volatile unsigned int soc_lf_timer_status1; + volatile unsigned int soc_lf_timer2; + volatile unsigned int soc_lf_timer_count2; + volatile unsigned int soc_lf_timer_control2; + volatile unsigned int soc_lf_timer_status2; + volatile unsigned int soc_lf_timer3; + volatile unsigned int soc_lf_timer_count3; + volatile unsigned int soc_lf_timer_control3; + volatile unsigned int soc_lf_timer_status3; + volatile unsigned int soc_hf_timer; + volatile unsigned int soc_hf_timer_count; + volatile unsigned int soc_hf_lf_count; + volatile unsigned int soc_hf_timer_control; + volatile unsigned int soc_hf_timer_status; + volatile unsigned int soc_rtc_control; + volatile unsigned int soc_rtc_time; + volatile unsigned int soc_rtc_date; + volatile unsigned int soc_rtc_set_time; + volatile unsigned int soc_rtc_set_date; + volatile unsigned int soc_rtc_set_alarm; + volatile unsigned int soc_rtc_config; + volatile unsigned int soc_rtc_alarm_status; + volatile unsigned int soc_uart_wakeup; + volatile unsigned int soc_reset_cause; + volatile unsigned int soc_system_sleep; + volatile unsigned int soc_sdio_wrapper; + volatile unsigned int soc_int_sleep_mask; + unsigned char pad3[4]; /* pad to 0xd4 */ + volatile unsigned int soc_lpo_cal_time; + volatile unsigned int soc_lpo_init_dividend_int; + volatile unsigned int soc_lpo_init_dividend_fraction; + volatile unsigned int soc_lpo_cal; + volatile unsigned int soc_lpo_cal_test_control; + volatile unsigned int soc_lpo_cal_test_status; + volatile unsigned int legacy_soc_chip_id; + volatile unsigned int soc_chip_id; + unsigned char pad4[24]; /* pad to 0x10c */ + volatile unsigned int soc_power_reg; + volatile unsigned int soc_core_clk_ctrl; + volatile unsigned int soc_gpio_wakeup_control; + unsigned char pad5[252]; /* pad to 0x214 */ + volatile unsigned int sleep_retention; + unsigned char pad6[108]; /* pad to 0x284 */ + volatile unsigned int lp_perf_counter; + volatile unsigned int lp_perf_light_sleep; + volatile unsigned int lp_perf_deep_sleep; + volatile unsigned int lp_perf_on; + unsigned char pad7[20]; /* pad to 0x2a8 */ + volatile unsigned int chip_mode; + volatile unsigned int clk_req_fall_edge; + volatile unsigned int otp; + volatile unsigned int otp_status; + volatile unsigned int pmu; + volatile unsigned int pmu_config; + volatile unsigned int pmu_pareg; + volatile unsigned int pmu_bypass; + unsigned char pad8[20]; /* pad to 0x2dc */ + volatile unsigned int therm_ctrl1; + volatile unsigned int therm_ctrl2; + volatile unsigned int therm_ctrl3; + volatile unsigned int listen_mode1; + volatile unsigned int listen_mode2; + volatile unsigned int audio_pll_config; + volatile unsigned int audio_pll_modulation; + volatile unsigned int audio_pll_mod_step; + volatile unsigned int current_audio_pll_modulation; + volatile unsigned int eth_pll_config; + volatile unsigned int cpu_pll_config; + volatile unsigned int bb_pll_config; + volatile unsigned int eth_xmii; + volatile unsigned int usb_phy_config; + volatile unsigned int usbcore_clk60m; + volatile unsigned int usbphy_utmi_clk; + volatile unsigned int usb_txvalid_dly_config; + volatile unsigned int second_host_inft; + volatile unsigned int sdio_host; + volatile unsigned int enterprise_config; + volatile unsigned int rtc_debug_bus; + volatile unsigned int rtc_ext_clk_buf; + volatile unsigned int wlan_ahb_bridge_timeout; + volatile unsigned int wlan_ahb_config; + volatile unsigned int rtc_axi_ahb_bridge; + unsigned char pad9[192]; /* pad to 0x400 */ + volatile unsigned int wlan2bt_cpucom_int_sts; + volatile unsigned int wlan2bt_cpucom_int_mask_n; + volatile unsigned int wlan2bt_cpucom_int_eoi; + volatile unsigned int wlan2bt_cpucom_int_ack_sts; + volatile unsigned int wlan2bt_cpucom_int_ack_mask_n; + volatile unsigned int wlan_cpucom_crd_cnt0; + volatile unsigned int wlan_cpucom_crd_inc0[1]; + volatile unsigned int wlan_cpucom_crd_dec0[1]; + volatile unsigned int wlan_cpucom_crd_cnt1; + volatile unsigned int wlan_cpucom_crd_inc1[1]; + volatile unsigned int wlan_cpucom_crd_dec1[1]; + volatile unsigned int wlan_cpucom_scratch0; + volatile unsigned int wlan_cpucom_scratch1; + volatile unsigned int wlan_cpucom_scratch2; + volatile unsigned int wlan_cpucom_scratch3; + volatile unsigned int wlan_cpucom_dbg; + volatile unsigned int wlan2bt_cpucom_int_ack_en; + volatile unsigned int bt2wlan_cpucom_int_en; +} rtc_soc_reg_reg_t; +#endif /* __ASSEMBLER__ */ + +#endif /* _RTC_SOC_REG_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/sys/queue.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/sys/queue.h new file mode 100644 index 0000000000000..a1b620721cea3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/sys/queue.h @@ -0,0 +1,576 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $ + */ + +#if !defined(__NetBSD__) +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - - - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT - - + + + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * + */ +#define QUEUE_MACRO_DEBUG 0 +#if QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + char * lastfile; + int lastline; + char * prevfile; + int prevline; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRASHIT(x) do {(x) = (void *)NULL;} while (0) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRASHIT(x) do {(x) = (void *)0;} while (0) +#endif /* QUEUE_MACRO_DEBUG */ + +#ifdef ATHR_RNWF +/* NDIS contains a defn for SLIST_ENTRY and SINGLE_LIST_ENTRY */ +#endif + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SING_LIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ +} while (0) + + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if (STAILQ_NEXT(elm, field)) { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + } \ +} while (0) + + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +/* + * List declarations. + */ +#define ATH_LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#ifndef LIST_HEAD +#define LIST_HEAD ATH_LIST_HEAD +#endif + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define HEADNAME +#define COPY_HEADNAME(head) + +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + HEADNAME \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + COPY_HEADNAME(head); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT((elm)->field.tqe_next); \ + TRASHIT((elm)->field.tqe_prev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + } \ +} while (0) + +#ifdef _KERNEL + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +static __inline void +insque(void *a, void *b) +{ + struct quehead *element = (struct quehead *)a, + *head = (struct quehead *)b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque(void *a) +{ + struct quehead *element = (struct quehead *)a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !(__GNUC__ || __INTEL_COMPILER) */ + +void insque(void *a, void *b); +void remque(void *a); + +#endif /* __GNUC__ || __INTEL_COMPILER */ + +#endif /* _KERNEL */ + +#endif /* !_SYS_QUEUE_H_ */ +#else /* !__NetBSD__ */ +#include_next +#endif /* __NetBSD__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targaddrs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targaddrs.h new file mode 100644 index 0000000000000..0cec68fb137ee --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targaddrs.h @@ -0,0 +1,686 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __TARGADDRS_H__ +#define __TARGADDRS_H__ + +#if defined(ATH_TARGET) +#include "soc_addrs.h" +#endif + +#if !defined(ATH_TARGET) +#include "athstartpack.h" +#endif + +/* + * SOC option bits, to enable/disable various features. + * By default, all option bits are 0. + * AR6004: These bits can be set in LOCAL_SCRATCH register 0. + * AR9888: These bits can be set in soc_core register SCRATCH_0. + */ +#define SOC_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */ +#define SOC_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */ +#define SOC_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */ +#define SOC_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */ +#define SOC_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */ +#define SOC_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */ +#define SOC_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */ +#define SOC_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */ + +/* + * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the + * host_interest structure. It must match the address of the _host_interest + * symbol (see linker script). + * + * Host Interest is shared between Host and Target in order to coordinate + * between the two, and is intended to remain constant (with additions only + * at the end) across software releases. + * + * All addresses are available here so that it's possible to + * write a single binary that works with all Target Types. + * May be used in assembler code as well as C. + */ +#define AR6002_HOST_INTEREST_ADDRESS 0x00500400 +#define AR6003_HOST_INTEREST_ADDRESS 0x00540600 +#define AR6004_HOST_INTEREST_ADDRESS 0x00400800 +#define AR9888_HOST_INTEREST_ADDRESS 0x00400800 +#define AR900B_HOST_INTEREST_ADDRESS 0x00400800 +#define AR6320_HOST_INTEREST_ADDRESS 0x00400800 +#define AR6004_SOC_RESET_ADDRESS 0X00004000 +#define AR6004_SOC_RESET_CPU_INIT_RESET_MASK 0X00000800 +#if defined(AR6006_MEMORY_NEW_ARCH) +#define AR6006_HOST_INTEREST_ADDRESS 0x00428800 +#else +#define AR6006_HOST_INTEREST_ADDRESS 0x00400800 +#endif +#define AR6006_SOC_RESET_ADDRESS 0X00004000 +#define AR6006_SOC_RESET_CPU_INIT_RESET_MASK 0X00000800 + + + +#define HOST_INTEREST_MAX_SIZE 0x200 + +#if !defined(__ASSEMBLER__) +struct register_dump_s; +struct dbglog_hdr_s; + +/* + * These are items that the Host may need to access + * via BMI or via the Diagnostic Window. The position + * of items in this structure must remain constant + * across firmware revisions! + * + * Types for each item must be fixed size across + * target and host platforms. + * + * More items may be added at the end. + */ +PREPACK64 struct host_interest_s { + /* + * Pointer to application-defined area, if any. + * Set by Target application during startup. + */ + A_UINT32 hi_app_host_interest; /* 0x00 */ + + /* Pointer to register dump area, valid after Target crash. */ + A_UINT32 hi_failure_state; /* 0x04 */ + + /* Pointer to debug logging header */ + A_UINT32 hi_dbglog_hdr; /* 0x08 */ + + /* Save SW ROM version */ + A_UINT32 hi_sw_rom_version; /* 0x0c */ + + /* + * General-purpose flag bits, similar to SOC_OPTION_* flags. + * Can be used by application rather than by OS. + */ + A_UINT32 hi_option_flag; /* 0x10 */ + + /* + * Boolean that determines whether or not to + * display messages on the serial port. + */ + A_UINT32 hi_serial_enable; /* 0x14 */ + + /* Start address of DataSet index, if any */ + A_UINT32 hi_dset_list_head; /* 0x18 */ + + /* Override Target application start address */ + A_UINT32 hi_app_start; /* 0x1c */ + + /* Clock and voltage tuning */ + A_UINT32 hi_skip_clock_init; /* 0x20 */ + A_UINT32 hi_core_clock_setting; /* 0x24 */ + A_UINT32 hi_cpu_clock_setting; /* 0x28 */ + A_UINT32 hi_system_sleep_setting; /* 0x2c */ + A_UINT32 hi_xtal_control_setting; /* 0x30 */ + A_UINT32 hi_pll_ctrl_setting_24ghz; /* 0x34 */ + A_UINT32 hi_pll_ctrl_setting_5ghz; /* 0x38 */ + A_UINT32 hi_ref_voltage_trim_setting; /* 0x3c */ + A_UINT32 hi_clock_info; /* 0x40 */ + + /* Host uses BE CPU or not */ + A_UINT32 hi_be; /* 0x44 */ + + A_UINT32 hi_stack; /* normal stack */ /* 0x48 */ + A_UINT32 hi_err_stack; /* error stack */ /* 0x4c */ + A_UINT32 hi_desired_cpu_speed_hz; /* 0x50 */ + + /* Pointer to Board Data */ + A_UINT32 hi_board_data; /* 0x54 */ + + /* + * Indication of Board Data state: + * 0: board data is not yet initialized. + * 1: board data is initialized; unknown size + * >1: number of bytes of initialized board data (varies with board type) + */ + A_UINT32 hi_board_data_initialized; /* 0x58 */ + + A_UINT32 hi_dset_RAM_index_table; /* 0x5c */ + + A_UINT32 hi_desired_baud_rate; /* 0x60 */ + A_UINT32 hi_dbglog_config; /* 0x64 */ + A_UINT32 hi_end_RAM_reserve_sz; /* 0x68 */ + A_UINT32 hi_mbox_io_block_sz; /* 0x6c */ + + A_UINT32 hi_num_bpatch_streams; /* 0x70 -- unused */ + A_UINT32 hi_mbox_isr_yield_limit; /* 0x74 */ + + A_UINT32 hi_refclk_hz; /* 0x78 */ + A_UINT32 hi_ext_clk_detected; /* 0x7c */ + A_UINT32 hi_dbg_uart_txpin; /* 0x80 */ + A_UINT32 hi_dbg_uart_rxpin; /* 0x84 */ + A_UINT32 hi_hci_uart_baud; /* 0x88 */ + A_UINT32 hi_hci_uart_pin_assignments; /* 0x8C */ + /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */ + A_UINT32 hi_hci_uart_baud_scale_val; /* 0x90 */ + A_UINT32 hi_hci_uart_baud_step_val; /* 0x94 */ + + A_UINT32 hi_allocram_start; /* 0x98 */ + A_UINT32 hi_allocram_sz; /* 0x9c */ + A_UINT32 hi_hci_bridge_flags; /* 0xa0 */ + A_UINT32 hi_hci_uart_support_pins; /* 0xa4 */ + /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */ + A_UINT32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */ + /* 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high + * [31:16]: wakeup timeout in ms + */ + /* Pointer to extended board Data */ + A_UINT32 hi_board_ext_data; /* 0xac */ + A_UINT32 hi_board_ext_data_config; /* 0xb0 */ + /* + * Bit [0] : valid + * Bit[31:16: size + */ + /* + * hi_reset_flag is used to do some stuff when target reset. + * such as restore app_start after warm reset or + * preserve host Interest area, or preserve ROM data, literals etc. + */ + A_UINT32 hi_reset_flag; /* 0xb4 */ + /* indicate hi_reset_flag is valid */ + A_UINT32 hi_reset_flag_valid; /* 0xb8 */ + A_UINT32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */ + /* 0xbc - [31:0]: idle timeout in ms + */ + /* ACS flags */ + A_UINT32 hi_acs_flags; /* 0xc0 */ + A_UINT32 hi_console_flags; /* 0xc4 */ + A_UINT32 hi_nvram_state; /* 0xc8 */ + A_UINT32 hi_option_flag2; /* 0xcc */ + + /* If non-zero, override values sent to Host in WMI_READY event. */ + A_UINT32 hi_sw_version_override; /* 0xd0 */ + A_UINT32 hi_abi_version_override; /* 0xd4 */ + + /* Percentage of high priority RX traffic to total expected RX traffic - + * applicable only to ar6004 */ + A_UINT32 hi_hp_rx_traffic_ratio; /* 0xd8 */ + + /* test applications flags */ + A_UINT32 hi_test_apps_related ; /* 0xdc */ + /* location of test script */ + A_UINT32 hi_ota_testscript; /* 0xe0 */ + /* location of CAL data */ + A_UINT32 hi_cal_data; /* 0xe4 */ + + /* Number of packet log buffers */ + A_UINT32 hi_pktlog_num_buffers; /* 0xe8 */ + + /* wow extension configuration */ + A_UINT32 hi_wow_ext_config; /* 0xec */ + A_UINT32 hi_pwr_save_flags; /* 0xf0 */ + + /* Spatial Multiplexing Power Save (SMPS) options */ + A_UINT32 hi_smps_options; /* 0xf4 */ + + /* Interconnect-specific state */ + A_UINT32 hi_interconnect_state; /* 0xf8 */ + + /* Coex configuration flags */ + A_UINT32 hi_coex_config; /* 0xfc */ + + /* Early allocation support */ + A_UINT32 hi_early_alloc; /* 0x100 */ + + /* FW swap field */ + /* Bits of this 32bit word will be used to pass specific swap + instruction to FW */ + /* Bit 0 -- AP Nart descriptor no swap. When this bit is set + FW will not swap TX descriptor. Meaning packets are formed + on the target processor.*/ + /* Bit 1 -- TBD */ + + A_UINT32 hi_fw_swap; /* 0x104 */ + + /* global arenas pointer address, used by host driver debug */ + A_UINT32 hi_dynamic_mem_arenas_addr; /* 0x108 */ + + /* allocated bytes of DRAM use by allocated */ + A_UINT32 hi_dynamic_mem_allocated; /* 0x10C */ + + /* remaining bytes of DRAM */ + A_UINT32 hi_dynamic_mem_remaining; /* 0x110 */ + + /* memory track count, configured by host */ + A_UINT32 hi_dynamic_mem_track_max; /* 0x114 */ + + /* minidump buffer */ + A_UINT32 hi_minidump; /* 0x118 */ + + /* bdata's sig and key addr */ + A_UINT32 hi_bd_sig_key; /* 0x11c */ + +} POSTPACK64; + +/* bitmap for hi_test_apps_related */ +#define HI_TEST_APPS_TESTSCRIPT_LOADED 0x00000001 +#define HI_TEST_APPS_CAL_DATA_AVAIL 0x00000002 + +/* Bits defined in hi_option_flag */ +#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */ +#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */ +#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */ +#define HI_OPTION_MAC_ADDR_METHOD 0x08 /* MAC addr method 0-locally administred 1-globally unique addrs */ +#define HI_OPTION_FW_BRIDGE 0x10 /* Firmware Bridging */ +#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */ +#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */ +#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */ +#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */ +#define HI_OPTION_NUM_DEV_LSB 0x200 +#define HI_OPTION_NUM_DEV_MSB 0x800 +#define HI_OPTION_DEV_MODE_LSB 0x1000 +#define HI_OPTION_DEV_MODE_MSB 0x8000000 +#define HI_OPTION_NO_LFT_STBL 0x10000000 /* Disable LowFreq Timer Stabilization */ +#define HI_OPTION_SKIP_REG_SCAN 0x20000000 /* Skip regulatory scan */ +#define HI_OPTION_INIT_REG_SCAN 0x40000000 /* Do regulatory scan during init before + * sending WMI ready event to host */ +#define HI_OPTION_SKIP_MEMMAP 0x80000000 /* REV6: Do not adjust memory map */ + +#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3 + +/* 2 bits of hi_option_flag are used to represent 3 modes */ +#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */ +#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */ +#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */ +#define HI_OPTION_FW_MODE_BT30AMP 0x3 /* BT30 AMP Mode */ + +/* 2 bits of hi_option flag are usedto represent 4 submodes */ +#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */ +#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */ +#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */ +#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */ + +/* Num dev Mask */ +#define HI_OPTION_NUM_DEV_MASK 0x7 +#define HI_OPTION_NUM_DEV_SHIFT 0x9 + +/* firmware bridging */ +#define HI_OPTION_FW_BRIDGE_SHIFT 0x04 + +/* Fw Mode/SubMode Mask +|-------------------------------------------------------------------------------| +| SUB | SUB | SUB | SUB | | | | | +| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0] | +| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2) | +|-------------------------------------------------------------------------------| +*/ +#define HI_OPTION_FW_MODE_BITS 0x2 +#define HI_OPTION_FW_MODE_MASK 0x3 +#define HI_OPTION_FW_MODE_SHIFT 0xC +#define HI_OPTION_ALL_FW_MODE_MASK 0xFF + +#define HI_OPTION_FW_SUBMODE_BITS 0x2 +#define HI_OPTION_FW_SUBMODE_MASK 0x3 +#define HI_OPTION_FW_SUBMODE_SHIFT 0x14 +#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 +#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 + + +/* hi_option_flag2 options */ +#define HI_OPTION_OFFLOAD_AMSDU 0x01 +#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ +#define HI_OPTION_ENABLE_RFKILL 0x04 /* RFKill Enable Feature*/ +#define HI_OPTION_RADIO_RETENTION_DISABLE 0x08 /* Disable radio retention */ +#define HI_OPTION_EARLY_CFG_DONE 0x10 /* Early configuration is complete */ + +#define HI_OPTION_RF_KILL_SHIFT 0x2 +#define HI_OPTION_RF_KILL_MASK 0x1 + +/* AR9888 1.0 only. Enable/disable CDC max perf support from host */ +#define HI_OPTION_DISABLE_CDC_MAX_PERF_WAR 0x20 +#define CDC_MAX_PERF_WAR_ENABLED() \ + (!(HOST_INTEREST->hi_option_flag2 & HI_OPTION_DISABLE_CDC_MAX_PERF_WAR)) + +#define HI_OPTION_USE_EXT_LDO 0x40 /* use LDO27 for 1.1V instead of PMU */ +#define HI_OPTION_DBUART_SUPPORT 0x80 /* Enable uart debug support */ +#define HT_OPTION_GPIO_WAKEUP_SUPPORT 0x200 /* GPIO wake up support */ + +#define GPIO_WAKEUP_ENABLED() \ + (HOST_INTEREST->hi_option_flag2 & HT_OPTION_GPIO_WAKEUP_SUPPORT) + +/* hi_reset_flag */ +#define HI_RESET_FLAG_PRESERVE_APP_START 0x01 /* preserve App Start address */ +#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST 0x02 /* preserve host interest */ +#define HI_RESET_FLAG_PRESERVE_ROMDATA 0x04 /* preserve ROM data */ +#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE 0x08 +#define HI_RESET_FLAG_PRESERVE_BOOT_INFO 0x10 +#define HI_RESET_FLAG_WARM_RESET 0x20 + +/* define hi_fw_swap bits */ +#define HI_DESC_IN_FW_BIT 0x01 + +#define HI_RESET_FLAG_IS_VALID 0x12345678 /* indicate the reset flag is valid */ + +#define ON_RESET_FLAGS_VALID() \ + (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID) + +#define RESET_FLAGS_VALIDATE() \ + (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID) + +#define RESET_FLAGS_INVALIDATE() \ + (HOST_INTEREST->hi_reset_flag_valid = 0) + +#define ON_RESET_PRESERVE_APP_START() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START) + +#define ON_RESET_PRESERVE_NVRAM_STATE() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE) + +#define ON_RESET_PRESERVE_HOST_INTEREST() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST) + +#define ON_RESET_PRESERVE_ROMDATA() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA) + +#define ON_RESET_PRESERVE_BOOT_INFO() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO) + +#define ON_RESET_WARM_RESET() \ + (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_WARM_RESET) + +/* host CPU endianness */ +#define HOST_ON_BE_CPU() \ + (HOST_INTEREST->hi_be) + +/* AP nart no swap descriptor flag. Decsriptors are created on the target processor. */ +#define DESC_IN_FW() \ + (HOST_INTEREST->hi_fw_swap & HI_DESC_IN_FW_BIT) + +#define HI_ACS_FLAGS_ENABLED (1 << 0) /* ACS is enabled */ +#define HI_ACS_FLAGS_USE_WWAN (1 << 1) /* Use physical WWAN device */ +#define HI_ACS_FLAGS_TEST_VAP (1 << 2) /* Use test VAP */ + +/* CONSOLE FLAGS + * + * Bit Range Meaning + * --------- -------------------------------- + * 2..0 UART ID (0 = Default) + * 3 Baud Select (0 = 9600, 1 = 115200) + * 30..4 Reserved + * 31 Enable Console + * + * */ + +#define HI_CONSOLE_FLAGS_ENABLE (1 << 31) +#define HI_CONSOLE_FLAGS_UART_MASK (0x7) +#define HI_CONSOLE_FLAGS_UART_SHIFT 0 +#define HI_CONSOLE_FLAGS_BAUD_SELECT (1 << 3) + +/* SM power save options */ +#define HI_SMPS_ALLOW_MASK (0x00000001) +#define HI_SMPS_MODE_MASK (0x00000002) +#define HI_SMPS_MODE_STATIC (0x00000000) +#define HI_SMPS_MODE_DYNAMIC (0x00000002) +#define HI_SMPS_DISABLE_AUTO_MODE (0x00000004) +#define HI_SMPS_DATA_THRESH_MASK (0x000007f8) +#define HI_SMPS_DATA_THRESH_SHIFT (3) +#define HI_SMPS_RSSI_THRESH_MASK (0x0007f800) +#define HI_SMPS_RSSI_THRESH_SHIFT (11) +#define HI_SMPS_LOWPWR_CM_MASK (0x00380000) +#define HI_SMPS_LOWPWR_CM_SHIFT (15) +#define HI_SMPS_HIPWR_CM_MASK (0x03c00000) +#define HI_SMPS_HIPWR_CM_SHIFT (19) + +#define HOST_INTEREST_SMPS_GET_MODE() (HOST_INTEREST->hi_smps_options & HI_SMPS_MODE_MASK) +#define HOST_INTEREST_SMPS_GET_DATA_THRESH() ((HOST_INTEREST->hi_smps_options & HI_SMPS_DATA_THRESH_MASK) >> HI_SMPS_DATA_THRESH_SHIFT) +#define HOST_INTEREST_SMPS_SET_DATA_THRESH(x) (((x) << HI_SMPS_DATA_THRESH_SHIFT) & HI_SMPS_DATA_THRESH_MASK) +#define HOST_INTEREST_SMPS_GET_RSSI_THRESH() ((HOST_INTEREST->hi_smps_options & HI_SMPS_RSSI_THRESH_MASK) >> HI_SMPS_RSSI_THRESH_SHIFT) +#define HOST_INTEREST_SMPS_SET_RSSI_THRESH(x) (((x) << HI_SMPS_RSSI_THRESH_SHIFT) & HI_SMPS_RSSI_THRESH_MASK) +#define HOST_INTEREST_SMPS_SET_LOWPWR_CM() ((HOST_INTEREST->hi_smps_options & HI_SMPS_LOWPWR_CM_MASK) >> HI_SMPS_LOWPWR_CM_SHIFT) +#define HOST_INTEREST_SMPS_SET_HIPWR_CM() ((HOST_INTEREST->hi_smps_options << HI_SMPS_HIPWR_CM_MASK) & HI_SMPS_HIPWR_CM_SHIFT) +#define HOST_INTEREST_SMPS_IS_AUTO_MODE_DISABLED() (HOST_INTEREST->hi_smps_options & HI_SMPS_DISABLE_AUTO_MODE) + + +/* WOW Extension configuration + * + * Bit Range Meaning + * --------- -------------------------------- + * 8..0 Size of each WOW pattern (max 511) + * 15..9 Number of patterns per list (max 127) + * 17..16 Number of lists (max 4) + * 30..18 Reserved + * 31 Enabled + * + * set values (except enable) to zeros for default settings + * + * */ + +#define HI_WOW_EXT_ENABLED_MASK (1 << 31) +#define HI_WOW_EXT_NUM_LIST_SHIFT 16 +#define HI_WOW_EXT_NUM_LIST_MASK (0x3 << HI_WOW_EXT_NUM_LIST_SHIFT) +#define HI_WOW_EXT_NUM_PATTERNS_SHIFT 9 +#define HI_WOW_EXT_NUM_PATTERNS_MASK (0x7F << HI_WOW_EXT_NUM_PATTERNS_SHIFT) +#define HI_WOW_EXT_PATTERN_SIZE_SHIFT 0 +#define HI_WOW_EXT_PATTERN_SIZE_MASK (0x1FF << HI_WOW_EXT_PATTERN_SIZE_SHIFT) + +#define HI_WOW_EXT_MAKE_CONFIG(num_lists,count,size) \ + ((((num_lists) << HI_WOW_EXT_NUM_LIST_SHIFT) & HI_WOW_EXT_NUM_LIST_MASK) | \ + (((count) << HI_WOW_EXT_NUM_PATTERNS_SHIFT) & HI_WOW_EXT_NUM_PATTERNS_MASK) | \ + (((size) << HI_WOW_EXT_PATTERN_SIZE_SHIFT) & HI_WOW_EXT_PATTERN_SIZE_MASK)) + +#define HI_WOW_EXT_GET_NUM_LISTS(config) \ + (((config) & HI_WOW_EXT_NUM_LIST_MASK) >> HI_WOW_EXT_NUM_LIST_SHIFT) +#define HI_WOW_EXT_GET_NUM_PATTERNS(config) \ + (((config) & HI_WOW_EXT_NUM_PATTERNS_MASK) >> HI_WOW_EXT_NUM_PATTERNS_SHIFT) +#define HI_WOW_EXT_GET_PATTERN_SIZE(config) \ + (((config) & HI_WOW_EXT_PATTERN_SIZE_MASK) >> HI_WOW_EXT_PATTERN_SIZE_SHIFT) + +/* + * Early allocation configuration + * Support RAM bank configuration before BMI done and this eases the memory + * allocation at very early stage + * Bit Range Meaning + * --------- ---------------------------------- + * [0:3] number of bank assigned to be IRAM + * [4:15] reserved + * [16:31] magic number + * + * Note: + * 1. target firmware would check magic number and if it's a match, firmware + * would consider the bits[0:15] are valid and base on that to calculate + * the end of DRAM. Early allocation would be located at that area and + * may be reclaimed when necesary + * 2. if no magic number is found, early allocation would happen at "_end" + * symbol of ROM which is located before the app-data and might NOT be + * re-claimable. If this is adopted, link script should keep this in + * mind to avoid data corruption. + */ +#define HI_EARLY_ALLOC_MAGIC 0x6d8a +#define HI_EARLY_ALLOC_MAGIC_MASK 0xffff0000 +#define HI_EARLY_ALLOC_MAGIC_SHIFT 16 +#define HI_EARLY_ALLOC_IRAM_BANKS_MASK 0x0000000f +#define HI_EARLY_ALLOC_IRAM_BANKS_SHIFT 0 + +#define HI_EARLY_ALLOC_VALID() \ + ((((HOST_INTEREST->hi_early_alloc) & HI_EARLY_ALLOC_MAGIC_MASK) >> HI_EARLY_ALLOC_MAGIC_SHIFT) \ + == (HI_EARLY_ALLOC_MAGIC)) +#define HI_EARLY_ALLOC_GET_IRAM_BANKS() \ + (((HOST_INTEREST->hi_early_alloc) & HI_EARLY_ALLOC_IRAM_BANKS_MASK) >> HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) + +/* + * Intended for use by Host software, this macro returns the Target RAM + * address of any item in the host_interest structure. + * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data); + */ +#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item))) + +#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item))) + +#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item))) + +#define AR6006_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR6006_HOST_INTEREST_ADDRESS))->item))) + +#define AR9888_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR9888_HOST_INTEREST_ADDRESS))->item))) + +#define AR6320_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR6320_HOST_INTEREST_ADDRESS))->item))) + +#define AR900B_HOST_INTEREST_ITEM_ADDRESS(item) \ + (A_UINT32)((size_t)&((((struct host_interest_s *)(AR900B_HOST_INTEREST_ADDRESS))->item))) + +#define HOST_INTEREST_DBGLOG_IS_ENABLED() \ + (!((volatile A_UINT32)HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG)) + +#define HOST_INTEREST_PKTLOG_IS_ENABLED() \ + (((volatile A_UINT32)HOST_INTEREST->hi_pktlog_num_buffers)) + +#define HOST_INTEREST_PROFILE_IS_ENABLED() \ + ((volatile A_UINT32)HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE) + +#define LF_TIMER_STABILIZATION_IS_ENABLED() \ + (!((volatile A_UINT32)HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL)) + +#define IS_AMSDU_OFFLAOD_ENABLED() \ + (((volatile A_UINT32)HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU)) + +#define HOST_INTEREST_DFS_IS_ENABLED() \ + (((volatile A_UINT32)HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT)) + +#define HOST_INTEREST_EARLY_CFG_DONE() \ + (((volatile A_UINT32)HOST_INTEREST->hi_option_flag2 & HI_OPTION_EARLY_CFG_DONE)) + +/*power save flag bit definitions*/ +#define HI_PWR_SAVE_LPL_ENABLED 0x1 +/*b1-b3 reserved*/ +/*b4-b5 : dev0 LPL type : 0 - none + 1- Reduce Pwr Search + 2- Reduce Pwr Listen*/ +/*b6-b7 : dev1 LPL type and so on for Max 8 devices*/ +#define HI_PWR_SAVE_LPL_DEV0_LSB 4 +#define HI_PWR_SAVE_LPL_DEV_MASK 0x3 +/*power save related utility macros*/ +#define HI_LPL_ENABLED() \ + ((HOST_INTEREST->hi_pwr_save_flags & HI_PWR_SAVE_LPL_ENABLED)) +#define HI_DEV_LPL_TYPE_GET(_devix) \ + (HOST_INTEREST->hi_pwr_save_flags & \ + ((HI_PWR_SAVE_LPL_DEV_MASK) << \ + (HI_PWR_SAVE_LPL_DEV0_LSB + \ + (_devix)*2))) + +#define HOST_INTEREST_SMPS_IS_ALLOWED() \ + ((HOST_INTEREST->hi_smps_options & HI_SMPS_ALLOW_MASK)) + +/* Convert a Target virtual address into a Target physical address */ +#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff) +#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff) +#define AR6004_VTOP(vaddr) (vaddr) +#define AR6006_VTOP(vaddr) (vaddr) +#define AR9888_VTOP(vaddr) (vaddr) +#define AR6320_VTOP(vaddr) (vaddr) +#define AR900B_VTOP(vaddr) (vaddr) +#define TARG_VTOP(TargetType, vaddr) \ + (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR6006) ? AR6006_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR9888) ? AR9888_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR6320) ? AR6320_VTOP(vaddr) : \ + (((TargetType) == TARGET_TYPE_AR900B) ? AR900B_VTOP(vaddr) : \ + 0))))))) + +#define HOST_INTEREST_ITEM_ADDRESS(TargetType, item) \ + (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR6004) ? AR6004_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR6006) ? AR6006_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR9888) ? AR9888_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR6320) ? AR6320_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR6320V2) ? AR6320_HOST_INTEREST_ITEM_ADDRESS(item) : \ + (((TargetType) == TARGET_TYPE_AR900B) ? AR900B_HOST_INTEREST_ITEM_ADDRESS(item) : \ + 0)))))))) + +#define AR6002_BOARD_DATA_SZ 768 +#define AR6002_BOARD_EXT_DATA_SZ 0 +#define AR6003_BOARD_DATA_SZ 1024 +/* Reserve 1024 bytes for extended board data */ +#if defined(AR6002_REV43) +#define AR6003_BOARD_EXT_DATA_SZ 1024 +#else +#define AR6003_BOARD_EXT_DATA_SZ 768 +#endif +#define AR6004_BOARD_DATA_SZ 7168 +#define AR6004_BOARD_EXT_DATA_SZ 0 +#define AR9888_BOARD_DATA_SZ 7168 +#define AR9888_BOARD_EXT_DATA_SZ 0 +#define AR6320_BOARD_DATA_SZ 8192 +#define AR6320_BOARD_EXT_DATA_SZ 0 +#define AR900B_BOARD_DATA_SZ 7168 +#define AR900B_BOARD_EXT_DATA_SZ 0 + +#define AR6003_REV3_APP_START_OVERRIDE 0x946100 +#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000 +#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330 +#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74 +#define AR6003_REV3_RAM_RESERVE_SIZE 4096 + +#define AR6004_REV1_BOARD_DATA_ADDRESS 0x423900 +#define AR6004_REV1_RAM_RESERVE_SIZE 19456 +#define AR6004_REV1_DATASET_PATCH_ADDRESS 0x425294 + +#define AR6004_REV2_BOARD_DATA_ADDRESS 0x426400 +#define AR6004_REV2_RAM_RESERVE_SIZE 7168 +#define AR6004_REV2_DATASET_PATCH_ADDRESS 0x435294 + +#define AR6004_REV5_BOARD_DATA_ADDRESS 0x436400 +#define AR6004_REV5_RAM_RESERVE_SIZE 7168 +#define AR6004_REV5_DATASET_PATCH_ADDRESS 0x437860 + +/* Reserve 4K for OTA test script */ +#define AR6004_REV1_RAM_RESERVE_SIZE_FOR_TEST_SCRIPT 4096 +#define AR6004_REV1_TEST_SCRIPT_ADDRESS 0x422900 + +/* # of A_UINT32 entries in targregs, used by DIAG_FETCH_TARG_REGS */ +#define AR6003_FETCH_TARG_REGS_COUNT 64 +#define AR6004_FETCH_TARG_REGS_COUNT 64 +#define AR9888_FETCH_TARG_REGS_COUNT 64 +#define AR6320_FETCH_TARG_REGS_COUNT 64 +#define AR900B_FETCH_TARG_REGS_COUNT 64 + +#endif /* !__ASSEMBLER__ */ + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + +#endif /* __TARGADDRS_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targcfg.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targcfg.h new file mode 100644 index 0000000000000..f33a6e6dd593e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/targcfg.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __TARGCFG_H__ +#define __TARGCFG_H__ + +#if defined(ATH_TARGET) +#include /* A_UINT32 */ +#else +#include /* A_UINT32 */ +#endif + +typedef struct _targcfg_t { + A_UINT32 num_vdev; + A_UINT32 num_peers; + A_UINT32 num_peer_ast; + A_UINT32 num_peer_keys; + A_UINT32 num_peer_tid; + A_UINT32 num_mcast_keys; + A_UINT32 num_tx; + A_UINT32 num_rx; + A_UINT32 num_mgmt_tx; + A_UINT32 num_mgmt_rx; + A_UINT32 tx_chain_mask; + A_UINT32 rx_chain_mask; + A_UINT32 override; /* Override target with the values supplied above */ +} targcfg_t; + +#endif /* __TARGCFG_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/testmode.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/testmode.h new file mode 100644 index 0000000000000..705884bc12078 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/testmode.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _TESTMODE_H_ +#define _TESTMODE_H_ + +#define AR6K_TM_DATA_MAX_LEN 5000 + +enum ar6k_testmode_attr { + __AR6K_TM_ATTR_INVALID = 0, + AR6K_TM_ATTR_CMD = 1, + AR6K_TM_ATTR_DATA = 2, + AR6K_TM_ATTR_STREAM_ID = 3, + + /* keep last */ + __AR6K_TM_ATTR_AFTER_LAST, + AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1 +}; + +enum ar6k_testmode_cmd { + AR6K_TM_CMD_TCMD = 0, + AR6K_TM_CMD_WMI_CMD = 0xF000, +}; + +enum ar6k_tcmd_ep { + TCMD_EP_TCMD, + TCMD_EP_WMI, +}; + +struct ar6k_testmode_cmd_data { + void *data; + int len; +}; +#endif /* #ifndef _TESTMODE_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wal_rx_desc.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wal_rx_desc.h new file mode 100644 index 0000000000000..d35120c7da691 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wal_rx_desc.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WAL_RX_DESC__H_ +#define _WAL_RX_DESC__H_ + + +#if defined(ATH_TARGET) +#include /* A_UINT8 */ +#else +#include /* A_UINT8 */ +#endif + +/* + * As this header is used by host also, + * and host will access target registers by target reg tbl, + * so disable direct-reference here for host. + * + */ +#if !defined(ATH_PERF_PWR_OFFLOAD) +/* HW rx descriptor definitions */ +#include +#include +#include +#include +#include +#include +#include +#include +/* + * This struct defines the basic descriptor information, which is + * written by the 11ac HW MAC into the WAL's rx status descriptor + * ring. + */ +struct hw_rx_desc_base { + struct rx_attention attention; + struct rx_frag_info frag_info; + struct rx_mpdu_start mpdu_start; + struct rx_msdu_start msdu_start; + struct rx_msdu_end msdu_end; + struct rx_mpdu_end mpdu_end; + struct rx_ppdu_start ppdu_start; + struct rx_ppdu_end ppdu_end; +}; +#endif + +/* + * This struct defines the basic MSDU rx descriptor created by FW. + */ +struct fw_rx_desc_base { + union { + struct { + A_UINT8 discard : 1, + forward : 1, + any_err : 1, + dup_err : 1, + reserved : 1, + inspect : 1, + extension: 2; + }bits; + A_UINT8 val; + }u; +}; + +#define FW_RX_DESC_DISCARD_M 0x1 +#define FW_RX_DESC_DISCARD_S 0 +#define FW_RX_DESC_FORWARD_M 0x2 +#define FW_RX_DESC_FORWARD_S 1 +#define FW_RX_DESC_MIC_ERR_M 0x4 +#define FW_RX_DESC_MIC_ERR_S 2 +#define FW_RX_DESC_DUP_ERR_M 0x8 +#define FW_RX_DESC_DUP_ERR_S 3 +#define FW_RX_DESC_INSPECT_M 0x20 +#define FW_RX_DESC_INSPECT_S 5 +#define FW_RX_DESC_EXT_M 0xc0 +#define FW_RX_DESC_EXT_S 6 + +#define FW_RX_DESC_CNT_2_BYTES(_fw_desc_cnt) (_fw_desc_cnt) + +enum { + FW_RX_DESC_EXT_NONE = 0, + FW_RX_DESC_EXT_LRO_ONLY, + FW_RX_DESC_EXT_LRO_AND_OTHER, + FW_RX_DESC_EXT_OTHER +}; + +#define FW_RX_DESC_DISCARD_GET(_var) \ + (((_var) & FW_RX_DESC_DISCARD_M) >> FW_RX_DESC_DISCARD_S) +#define FW_RX_DESC_DISCARD_SET(_var, _val) \ + ((_var) |= ((_val) << FW_RX_DESC_DISCARD_S)) + +#define FW_RX_DESC_FORWARD_GET(_var) \ + (((_var) & FW_RX_DESC_FORWARD_M) >> FW_RX_DESC_FORWARD_S) +#define FW_RX_DESC_FORWARD_SET(_var, _val) \ + ((_var) |= ((_val) << FW_RX_DESC_FORWARD_S)) + +#define FW_RX_DESC_INSPECT_GET(_var) \ + (((_var) & FW_RX_DESC_INSPECT_M) >> FW_RX_DESC_INSPECT_S) +#define FW_RX_DESC_INSPECT_SET(_var, _val) \ + ((_var) |= ((_val) << FW_RX_DESC_INSPECT_S)) + +#define FW_RX_DESC_EXT_GET(_var) \ + (((_var) & FW_RX_DESC_EXT_M) >> FW_RX_DESC_EXT_S) +#define FW_RX_DESC_EXT_SET(_var, _val) \ + ((_var) |= ((_val) << FW_RX_DESC_EXT_S)) + + +#endif /* _WAL_RX_DESC__H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event.h new file mode 100644 index 0000000000000..70ab930dd4dd9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WDI_EVENT_H_ +#define _WDI_EVENT_H_ + +#include "athdefs.h" +#include "adf_nbuf.h" +#define WDI_EVENT_BASE 0x100 /* Event starting number */ + +enum WDI_EVENT { + WDI_EVENT_TX_STATUS = WDI_EVENT_BASE, + WDI_EVENT_RX_DESC, + WDI_EVENT_RX_DESC_REMOTE, + WDI_EVENT_RATE_FIND, + WDI_EVENT_RATE_UPDATE, + WDI_EVENT_RX_PEER_INVALID, + /* End of new event items */ + + WDI_EVENT_LAST +}; + +struct wdi_event_rx_peer_invalid_msg { + adf_nbuf_t msdu; + struct ieee80211_frame *wh; + u_int8_t vdev_id; +}; + +#define WDI_NUM_EVENTS (WDI_EVENT_LAST - WDI_EVENT_BASE) + +#define WDI_EVENT_NOTIFY_BASE 0x200 +enum WDI_EVENT_NOTIFY { + WDI_EVENT_SUB_DEALLOCATE = WDI_EVENT_NOTIFY_BASE, + /* End of new notification types */ + + WDI_EVENT_NOTIFY_LAST +}; + +/* Opaque event callback */ +typedef void (*wdi_event_cb)(void *pdev, enum WDI_EVENT event, void *data); + +/* Opaque event notify */ +typedef void (*wdi_event_notify)(enum WDI_EVENT_NOTIFY notify, + enum WDI_EVENT event); + +/** + * @typedef wdi_event_subscribe + * @brief Used by consumers to subscribe to WDI event notifications. + * @details + * The event_subscribe struct includes pointers to other event_subscribe + * objects. These pointers are simply to simplify the management of + * lists of event subscribers. These pointers are set during the + * event_sub() function, and shall not be modified except by the + * WDI event management SW, until after the object's event subscription + * is canceled by calling event_unsub(). + */ + +typedef struct wdi_event_subscribe_t { + wdi_event_cb callback; /* subscriber event callback structure head*/ + void *context; /* subscriber object that processes the event callback */ + struct { + /* private - the event subscriber SW shall not use this struct */ + struct wdi_event_subscribe_t *next; + struct wdi_event_subscribe_t *prev; + } priv; +} wdi_event_subscribe; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event_api.h new file mode 100644 index 0000000000000..4ed3a424ea8a4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_event_api.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WDI_EVENT_API_H_ +#define _WDI_EVENT_API_H_ + +#include "wdi_event.h" + +struct ol_txrx_pdev_t; + +/** + * @brief Subscribe to a specified WDI event. + * @details + * This function adds the provided wdi_event_subscribe object to a list of + * subscribers for the specified WDI event. + * When the event in question happens, each subscriber for the event will + * have their callback function invoked. + * The order in which callback functions from multiple subscribers are + * invoked is unspecified. + * + * @param pdev - the event physical device, that maintains the event lists + * @param event_cb_sub - the callback and context for the event subscriber + * @param event - which event's notifications are being subscribed to + * @return error code, or A_OK for success + */ +A_STATUS wdi_event_sub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event); + +/** + * @brief Unsubscribe from a specified WDI event. + * @details + * This function removes the provided event subscription object from the + * list of subscribers for its event. + * This function shall only be called if there was a successful prior call + * to event_sub() on the same wdi_event_subscribe object. + * + * @param pdev - the event physical device with the list of event subscribers + * @param event_cb_sub - the event subscription object + * @param event - which event is being unsubscribed + * @return error code, or A_OK for success + */ +A_STATUS wdi_event_unsub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event); + +#ifdef WDI_EVENT_ENABLE + +void wdi_event_handler(enum WDI_EVENT event, + struct ol_txrx_pdev_t *txrx_pdev, + void *data); +A_STATUS wdi_event_attach(struct ol_txrx_pdev_t *txrx_pdev); +A_STATUS wdi_event_detach(struct ol_txrx_pdev_t *txrx_pdev); + +#endif /* WDI_EVENT_ENABLE */ + +#endif /* _WDI_EVENT_API_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_in.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_in.h new file mode 100644 index 0000000000000..c81497d4c396c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_in.h @@ -0,0 +1,1261 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY */ +/** + * @addtogroup WDIAPI + *@{ + */ +/** + * @file wdi_in.h + * @brief Datapath functions called by SW outside the WDI boundary + */ +#ifndef _WDI_IN__H_ +#define _WDI_IN__H_ + +#include + +#ifdef WDI_API_AS_FUNCS + +#include /* A_STATUS */ +#include /* adf_nbuf_t */ +#include /* adf_os_device_t */ +#include /* HTC_HANDLE */ + +#include /* MAX_SPATIAL_STREAM */ + +/** + * @brief Set up the data SW subsystem. + * @details + * As part of the WLAN device attach, the data SW subsystem has + * to be attached as a component within the WLAN device. + * This attach allocates and initializes the physical device object + * used by the data SW. + * The data SW subsystem attach needs to happen after the target has + * be started, and host / target parameter negotiation has completed, + * since the host data SW uses some of these host/target negotiated + * parameters (e.g. peer ID range) during the initializations within + * its attach function. + * However, the host data SW is not allowed to send HTC messages to the + * target within this pdev_attach function call, since the HTC setup + * has not complete at this stage of initializations. Any messaging + * to the target has to be done in the separate pdev_attach_target call + * that is invoked after HTC setup is complete. + * + * @param ctrl_pdev - control SW's physical device handle, needed as an + * argument for dynamic configuration queries + * @param htc_pdev - the HTC physical device handle. This is not needed + * by the txrx module, but needs to be passed along to the HTT module. + * @param osdev - OS handle needed as an argument for some OS primitives + * @return the data physical device object + */ +ol_txrx_pdev_handle +wdi_in_pdev_attach( + ol_pdev_handle ctrl_pdev, + HTC_HANDLE htc_pdev, + adf_os_device_t osdev); + +/** + * @brief Do final steps of data SW setup that send messages to the target. + * @details + * The majority of the data SW setup are done by the pdev_attach function, + * but this function completes the data SW setup by sending datapath + * configuration messages to the target. + * + * @param data_pdev - the physical device being initialized + */ +A_STATUS +wdi_in_pdev_attach_target(ol_txrx_pdev_handle data_pdev); + +/** + * @brief Wrapper for rate-control context initialization + * @details + * Enables the switch that controls the allocation of the + * rate-control contexts on the host. + * + * @param pdev - the physical device being initialized + * @param enable - 1: enabled 0: disabled + */ +void wdi_in_enable_host_ratectrl(ol_txrx_pdev_handle pdev, u_int32_t enable); + +/** + * @brief modes that a virtual device can operate as + * @details + * A virtual device can operate as an AP, an IBSS, or a STA (client). + * or in monitor mode + */ +enum wlan_op_mode { + wlan_op_mode_unknown, + wlan_op_mode_ap, + wlan_op_mode_ibss, + wlan_op_mode_sta, + wlan_op_mode_monitor, +}; + +/** + * @brief Allocate and initialize the data object for a new virtual device. + * @param data_pdev - the physical device the virtual device belongs to + * @param vdev_mac_addr - the MAC address of the virtual device + * @param vdev_id - the ID used to identify the virtual device to the target + * @param op_mode - whether this virtual device is operating as an AP, + * an IBSS, or a STA + * @return + * success: handle to new data vdev object, -OR- + * failure: NULL + */ +ol_txrx_vdev_handle +wdi_in_vdev_attach( + ol_txrx_pdev_handle data_pdev, + u_int8_t *vdev_mac_addr, + u_int8_t vdev_id, + enum wlan_op_mode op_mode); + +/** + * @brief Allocate and set up references for a data peer object. + * @details + * When an association with a peer starts, the host's control SW + * uses this function to inform the host data SW. + * The host data SW allocates its own peer object, and stores a + * reference to the control peer object within the data peer object. + * The host data SW also stores a reference to the virtual device + * that the peer is associated with. This virtual device handle is + * used when the data SW delivers rx data frames to the OS shim layer. + * The host data SW returns a handle to the new peer data object, + * so a reference within the control peer object can be set to the + * data peer object. + * + * @param data_pdev - data physical device object that will indirectly + * own the data_peer object + * @param data_vdev - data virtual device object that will directly + * own the data_peer object + * @param peer_mac_addr - MAC address of the new peer + * @return handle to new data peer object, or NULL if the attach fails + */ +ol_txrx_peer_handle +wdi_in_peer_attach( + ol_txrx_pdev_handle data_pdev, + ol_txrx_vdev_handle data_vdev, + u_int8_t *peer_mac_addr); + +/** + * @brief Template for passing ieee80211_node members to rate-control + * @details + * This structure is used in order to maintain the isolation between umac and + * ol while initializing the peer-level rate-control context with peer-specific + * parameters. + */ +struct peer_ratectrl_params_t { + u_int8_t ni_streams; + u_int8_t is_auth_wpa; + u_int8_t is_auth_wpa2; + u_int8_t is_auth_8021x; + u_int32_t ni_flags; + u_int32_t ni_chwidth; + u_int16_t ni_htcap; + u_int32_t ni_vhtcap; + u_int16_t ni_phymode; + u_int16_t ni_rx_vhtrates; + u_int8_t ht_rates[MAX_SPATIAL_STREAM * 8]; +}; + +/** +* @brief Parameter type to be input to wdi_in_peer_update +* @details +* This struct is union,to be used to specify various informations to update +* txrx peer object. +*/ +typedef union { + struct peer_ratectrl_params_t * ratectrl; + u_int8_t qos_capable; + u_int8_t uapsd_mask; + enum ol_sec_type sec_type; +}ol_txrx_peer_update_param_t; + +/** +* @brief Parameter type to be input to wdi_in_peer_update +* @details +* This enum is used to specify what exact information in ol_txrx_peer_update_param_t +* is used to update the txrx peer object. +*/ +typedef enum { + ol_txrx_peer_update_rate_ctrl = 0x1, + ol_txrx_peer_update_qos_capable, + ol_txrx_peer_update_uapsdMask, + ol_txrx_peer_update_peer_security, +} ol_txrx_peer_update_select_t; + +/** + * @brief Update the data peer object as some informaiton changed in node. + * @details + * Only a single prarameter can be changed for each call to this func. + * For the host-based implementation of rate-control (select == + * ol_txrx_peer_update_rate_ctrl), it updates the peer/node-related parameters + * within rate-control context of the peer at association. + * + * @param peer - pointer to the node's object + * @param param - new param to be upated in peer object. + * @param select - specify what's parameter needed to be update + * @return none + */ +void +wdi_in_peer_update(ol_txrx_vdev_handle data_vdev, u_int8_t *peer_mac, + ol_txrx_peer_update_param_t *param, + ol_txrx_peer_update_select_t select); + +/** + * @brief Notify tx data SW that a peer's transmissions are suspended. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * The HL host tx data SW is doing tx classification and tx download + * scheduling, and therefore also needs to actively participate in tx + * flow control. Specifically, the HL tx data SW needs to check whether a + * given peer is available to transmit to, or is paused. + * This function is used to tell the HL tx data SW when a peer is paused, + * so the host tx data SW can hold the tx frames for that SW. + * + * @param data_peer - which peer is being paused + */ +#if defined(CONFIG_HL_SUPPORT) && defined(QCA_SUPPORT_INTEGRATED_SOC) +void +wdi_in_peer_pause(ol_txrx_peer_handle data_peer); +#else +#define wdi_in_peer_pause(data_peer) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Notify tx data SW that a peer-TID is ready to transmit to. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * If a peer-TID has tx paused, then the tx datapath will end up queuing + * any tx frames that arrive from the OS shim for that peer-TID. + * In a HL system, the host tx data SW itself will classify the tx frame, + * and determine that it needs to be queued rather than downloaded to the + * target for transmission. + * Once the peer-TID is ready to accept data, the host control SW will call + * this function to notify the host data SW that the queued frames can be + * enabled for transmission, or specifically to download the tx frames + * to the target to transmit. + * The TID parameter is an extended version of the QoS TID. Values 0-15 + * indicate a regular QoS TID, and the value 16 indicates either non-QoS + * data, multicast data, or broadcast data. + * + * @param data_peer - which peer is being unpaused + * @param tid - which TID within the peer is being unpaused, or -1 as a + * wildcard to unpause all TIDs within the peer + */ +#if defined(CONFIG_HL_SUPPORT) +void +wdi_in_peer_tid_unpause(ol_txrx_peer_handle data_peer, int tid); +#else +#define wdi_in_peer_tid_unpause(data_peer, tid) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Tell a paused peer to release a specified number of tx frames. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * Download up to a specified maximum number of tx frames from the tx + * queues of the specified TIDs within the specified paused peer, usually + * in response to a U-APSD trigger from the peer. + * It is up to the host data SW to determine how to choose frames from the + * tx queues of the specified TIDs. However, the host data SW does need to + * provide long-term fairness across the U-APSD enabled TIDs. + * The host data SW will notify the target data FW when it is done downloading + * the batch of U-APSD triggered tx frames, so the target data FW can + * differentiate between an in-progress download versus a case when there are + * fewer tx frames available than the specified limit. + * This function is relevant primarily to HL U-APSD, where the frames are + * held in the host. + * + * @param peer - which peer sent the U-APSD trigger + * @param tid_mask - bitmask of U-APSD enabled TIDs from whose tx queues + * tx frames can be released + * @param max_frms - limit on the number of tx frames to release from the + * specified TID's queues within the specified peer + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +wdi_in_tx_release( + ol_txrx_peer_handle peer, + u_int32_t tid_mask, + int max_frms); +#else +#define wdi_in_tx_release(peer, tid_mask, max_frms) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Suspend all tx data for the specified virtual device. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * As an example, this function could be used when a single-channel physical + * device supports multiple channels by jumping back and forth between the + * channels in a time-shared manner. As the device is switched from channel + * A to channel B, the virtual devices that operate on channel A will be + * paused. + * + * @param data_vdev - the virtual device being paused + * @param reason - the reason for which vdev queue is getting paused + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +wdi_in_vdev_pause(ol_txrx_vdev_handle data_vdev, u_int32_t reason); +#else +#define wdi_in_vdev_pause(data_vdev, reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Resume tx for the specified virtual device. + * @details + * This function applies only to HL systems - in LL systems, tx flow control + * is handled entirely within the target FW. + * + * @param data_vdev - the virtual device being unpaused + * @param reason - the reason for which vdev queue is getting unpaused + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +wdi_in_vdev_unpause(ol_txrx_vdev_handle data_vdev, u_int32_t reason); +#else +#define wdi_in_vdev_unpause(data_vdev, reason) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** + * @brief Suspend all tx data for the specified physical device. + * @details + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * In some systems it is necessary to be able to temporarily + * suspend all WLAN traffic, e.g. to allow another device such as bluetooth + * to temporarily have exclusive access to shared RF chain resources. + * This function suspends tx traffic within the specified physical device. + * + * @param data_pdev - the physical device being paused + * @param reason - pause reason + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +wdi_in_pdev_pause(ol_txrx_pdev_handle data_pdev, u_int32_t reason); +#else +#define wdi_in_pdev_pause(data_pdev, reason) /* no-op */ +#endif + +/** + * @brief Resume tx for the specified physical device. + * @details + * This function applies to HL systems - + * in LL systems, applies when txrx_vdev_pause_all is enabled. + * + * @param data_pdev - the physical device being unpaused + * @param reason - pause reason + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +wdi_in_pdev_unpause(ol_txrx_pdev_handle data_pdev, u_int32_t reason); +#else +#define wdi_in_pdev_unpause(data_pdev, reason) /* no-op */ +#endif + +/** + * @brief Synchronize the data-path tx with a control-path target download + * @dtails + * @param data_pdev - the data-path physical device object + * @param sync_cnt - after the host data-path SW downloads this sync request + * to the target data-path FW, the target tx data-path will hold itself + * in suspension until it is given an out-of-band sync counter value that + * is equal to or greater than this counter value + */ +void +wdi_in_tx_sync(ol_txrx_pdev_handle data_pdev, u_int8_t sync_cnt); + +/** + * @brief Delete a peer's data object. + * @details + * When the host's control SW disassociates a peer, it calls this + * function to delete the peer's data object. + * The reference stored in the control peer object to the data peer + * object (set up by a call to ol_peer_store()) is provided. + * + * @param data_peer - the object to delete + */ +void +wdi_in_peer_detach(ol_txrx_peer_handle data_peer); + +typedef void (*ol_txrx_vdev_delete_cb)(void *context); + +/** + * @brief Deallocate the specified data virtual device object. + * @details + * All peers associated with the virtual device need to be deleted + * (wdi_in_peer_detach) before the virtual device itself is deleted. + * However, for the peers to be fully deleted, the peer deletion has to + * percolate through the target data FW and back up to the host data SW. + * Thus, even though the host control SW may have issued a peer_detach + * call for each of the vdev's peers, the peer objects may still be + * allocated, pending removal of all references to them by the target FW. + * In this case, though the vdev_detach function call will still return + * immediately, the vdev itself won't actually be deleted, until the + * deletions of all its peers complete. + * The caller can provide a callback function pointer to be notified when + * the vdev deletion actually happens - whether it's directly within the + * vdev_detach call, or if it's deferred until all in-progress peer + * deletions have completed. + * + * @param data_vdev - data object for the virtual device in question + * @param callback - function to call (if non-NULL) once the vdev has + * been wholly deleted + * @param callback_context - context to provide in the callback + */ +void +wdi_in_vdev_detach( + ol_txrx_vdev_handle data_vdev, + ol_txrx_vdev_delete_cb callback, + void *callback_context); + +/** + * @brief Delete the data SW state. + * @details + * This function is used when the WLAN driver is being removed to + * remove the host data component within the driver. + * All virtual devices within the physical device need to be deleted + * (wdi_in_vdev_detach) before the physical device itself is deleted. + * + * @param data_pdev - the data physical device object being removed + * @param force - delete the pdev (and its vdevs and peers) even if there + * are outstanding references by the target to the vdevs and peers + * within the pdev + */ +void +wdi_in_pdev_detach(ol_txrx_pdev_handle data_pdev, int force); + +typedef void +(*ol_txrx_data_tx_cb)(void *ctxt, adf_nbuf_t tx_frm, int had_error); + +/** + * @brief Store a delivery notification callback for specific data frames. + * @details + * Through a non-std tx function, the txrx SW can be given tx data frames + * that are specially marked to not be unmapped and freed by the tx SW + * when transmission completes. Rather, these specially-marked frames + * are provided to the callback registered with this function. + * + * @param data_vdev - which vdev the callback is being registered with + * (Currently the callback is stored in the pdev rather than the vdev.) + * @param callback - the function to call when tx frames marked as "no free" + * are done being transmitted + * @param ctxt - the context argument provided to the callback function + */ +void +wdi_in_data_tx_cb_set( + ol_txrx_vdev_handle data_vdev, + ol_txrx_data_tx_cb callback, + void *ctxt); + +/** + * @brief Allow the control-path SW to send data frames. + * @details + * Generally, all tx data frames come from the OS shim into the txrx layer. + * However, there are rare cases such as TDLS messaging where the UMAC + * control-path SW creates tx data frames. + * This UMAC SW can call this function to provide the tx data frames to + * the txrx layer. + * The UMAC SW can request a callback for these data frames after their + * transmission completes, by using the wdi_in_data_tx_cb_set function + * to register a tx completion callback, and by specifying + * ol_tx_spec_no_free as the tx_spec arg when giving the frames to + * ol_tx_non_std. + * The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11), + * as specified by ol_cfg_frame_type(). + * + * @param data_vdev - which vdev should transmit the tx data frames + * @param tx_spec - what non-standard handling to apply to the tx data frames + * @param msdu_list - NULL-terminated list of tx MSDUs + */ +adf_nbuf_t +ol_tx_non_std( + ol_txrx_vdev_handle data_vdev, + enum ol_tx_spec tx_spec, + adf_nbuf_t msdu_list); + +typedef void +(*ol_txrx_mgmt_tx_cb)(void *ctxt, adf_nbuf_t tx_mgmt_frm, int had_error); + +/** + * @brief Store a callback for delivery notifications for managements frames. + * @details + * When the txrx SW receives notifications from the target that a tx frame + * has been delivered to its recipient, it will check if the tx frame + * is a management frame. If so, the txrx SW will check the management + * frame type specified when the frame was submitted for transmission. + * If there is a callback function registered for the type of managment + * frame in question, the txrx code will invoke the callback to inform + * the management + control SW that the mgmt frame was delivered. + * This function is used by the control SW to store a callback pointer + * for a given type of management frame. + * + * @param pdev - the data physical device object + * @param type - the type of mgmt frame the callback is used for + * @param download_cb - the callback for delivery notification to target + * @param ota_ack_cb - the callback for delivery notification to peer + * @param ctxt - context to use with the callback + */ +void +wdi_in_mgmt_tx_cb_set( + ol_txrx_pdev_handle pdev, + u_int8_t type, + ol_txrx_mgmt_tx_cb download_cb, + ol_txrx_mgmt_tx_cb ota_ack_cb + void *ctxt); + +/** + * @brief Transmit a management frame. + * @details + * Send the specified management frame from the specified virtual device. + * The type is used for determining whether to invoke a callback to inform + * the sender that the tx mgmt frame was delivered, and if so, which + * callback to use. + * + * @param vdev - virtual device transmitting the frame + * @param tx_mgmt_frm - management frame to transmit + * @param type - the type of managment frame (determines what callback to use) + * @param use_6mbps - specify whether management frame to transmit should use 6 Mbps + * rather than 1 Mbps min rate(for 5GHz band or P2P) + * @return + * 0 -> the frame is accepted for transmission, -OR- + * 1 -> the frame was not accepted + */ +int +wdi_in_mgmt_send( + ol_txrx_vdev_handle vdev, + adf_nbuf_t tx_mgmt_frm, + u_int8_t type, + u_int8_t use_6mbps, + u_int16_t chanfreq); + +/** + * @brief Setup the monitor mode vap (vdev) for this pdev + * @details + * When a non-NULL vdev handle is registered as the monitor mode vdev, all + * packets received by the system are delivered to the OS stack on this + * interface in 802.11 MPDU format. Only a single monitor mode interface + * can be up at any timer. When the vdev handle is set to NULL the monitor + * mode delivery is stopped. This handle may either be a unique vdev + * object that only receives monitor mode packets OR a point to a a vdev + * object that also receives non-monitor traffic. In the second case the + * OS stack is responsible for delivering the two streams using approprate + * OS APIs + * + * @param pdev - the data physical device object + * @param vdev - the data virtual device object to deliver monitor mode + * packets on + * @return + * 0 -> the monitor mode vap was sucessfully setup + * -1 -> Unable to setup monitor mode + */ +int +wdi_in_set_monitor_mode_vap( + ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev); + +/** + * @brief Setup the current operating channel of the device + * @details + * Mainly used when populating monitor mode status that requires the + * current operating channel + * + * @param pdev - the data physical device object + * @param chan_mhz - the channel frequency (mhz) + * packets on + * @return - void + */ +void +wdi_in_set_curchan( + ol_txrx_pdev_handle pdev, + u_int32_t chan_mhz); + +/** + * @brief Get the number of pending transmit frames that are awaiting completion. + * @details + * Mainly used in clean up path to make sure all buffers have been free'ed + * + * @param pdev - the data physical device object + * @return - count of pending frames + */ +int +wdi_in_get_tx_pending( + ol_txrx_pdev_handle pdev); + +/** + * @brief Discard all tx frames that are pending in txrx. + * @details + * Mainly used in clean up path to make sure all pending tx packets + * held by txrx are returned back to OS shim immediately. + * + * @param pdev - the data physical device object + * @return - void + */ +void +wdi_in_discard_tx_pending( + ol_txrx_pdev_handle pdev); + +/** + * @brief set the safemode of the device + * @details + * This flag is used to bypass the encrypt and decrypt processes when send and + * receive packets. It works like open AUTH mode, HW will treate all packets + * as non-encrypt frames because no key installed. For rx fragmented frames, + * it bypasses all the rx defragmentaion. + * + * @param vdev - the data virtual device object + * @param val - the safemode state + * @return - void + */ +void +wdi_in_set_safemode( + ol_txrx_vdev_handle vdev, + u_int32_t val); + +/** + * @brief set the privacy filter + * @details + * Rx related. Set the privacy filters. When rx packets, check the ether type, filter type and + * packet type to decide whether discard these packets. + * + * @param vdev - the data virtual device object + * @param filter - filters to be set + * @param num - the number of filters + * @return - void + */ +void +wdi_in_set_privacy_filters( + ol_txrx_vdev_handle vdev, + void *filter, + u_int32_t num); + +/** + * @brief configure the drop unencrypted frame flag + * @details + * Rx related. When set this flag, all the unencrypted frames + * received over a secure connection will be discarded + * + * @param vdev - the data virtual device object + * @param val - flag + * @return - void + */ +void +wdi_in_set_drop_unenc( + ol_txrx_vdev_handle vdev, + u_int32_t val); + +enum ol_txrx_peer_state { + ol_txrx_peer_state_disc, /* initial state */ + ol_txrx_peer_state_conn, /* authentication in progress */ + ol_txrx_peer_state_auth, /* authentication completed successfully */ +}; + +/** + * @brief specify the peer's authentication state + * @details + * Specify the peer's authentication state (none, connected, authenticated) + * to allow the data SW to determine whether to filter out invalid data frames. + * (In the "connected" state, where security is enabled, but authentication + * has not completed, tx and rx data frames other than EAPOL or WAPI should + * be discarded.) + * This function is only relevant for systems in which the tx and rx filtering + * are done in the host rather than in the target. + * + * @param data_peer - which peer has changed its state + * @param state - the new state of the peer + */ +void +wdi_in_peer_state_update(ol_txrx_pdev_handle pdev, u_int8_t *peer_mac, + ol_txrx_peer_handle data_peer, + enum ol_txrx_peer_state state); + +void +wdi_in_peer_keyinstalled_state_update( + ol_txrx_peer_handle data_peer, + u_int8_t val); + +#define ol_tx_addba_conf(data_peer, tid, status) /* no-op */ + +/** + * @typedef ol_txrx_tx_fp + * @brief top-level transmit function + */ +typedef adf_nbuf_t (*ol_txrx_tx_fp)( + ol_txrx_vdev_handle data_vdev, adf_nbuf_t msdu_list); + +/** + * @enum ol_txrx_osif_tx_spec + * @brief indicate what non-standard transmission actions to apply + * @details + * Indicate one or more of the following: + * - The tx frame already has a complete 802.11 header. + * Thus, skip 802.3/native-WiFi to 802.11 header encapsulation and + * A-MSDU aggregation. + * - The tx frame should not be aggregated (A-MPDU or A-MSDU) + * - The tx frame is already encrypted - don't attempt encryption. + * - The tx frame is a segment of a TCP jumbo frame. + * More than one of these specification can apply, though typically + * only a single specification is applied to a tx frame. + * A compound specification can be created, as a bit-OR of these + * specifications. + */ +enum ol_txrx_osif_tx_spec { + ol_txrx_osif_tx_spec_std = 0x0, /* do regular processing */ + ol_txrx_osif_tx_spec_raw = 0x1, /* skip encap + A-MSDU aggr */ + ol_txrx_osif_tx_spec_no_aggr = 0x2, /* skip encap + all aggr */ + ol_txrx_osif_tx_spec_no_encrypt = 0x4, /* skip encap + encrypt */ + ol_txrx_osif_tx_spec_tso = 0x8, /* TCP segmented */ + ol_txrx_osif_tx_spect_nwifi_no_encrypt = 0x10, /* skip encrypt for nwifi */ +}; + +/** + * @typedef ol_txrx_tx_non_std_fp + * @brief top-level transmit function for non-standard tx frames + * @details + * This function pointer provides an alternative to the ol_txrx_tx_fp + * to support non-standard transmits. In particular, this function + * supports transmission of: + * 1. "Raw" frames + * These raw frames already have an 802.11 header; the usual + * 802.11 header encapsulation by the driver does not apply. + * 2. TSO segments + * During tx completion, the txrx layer needs to reclaim the buffer + * that holds the ethernet/IP/TCP header created for the TSO segment. + * Thus, these tx frames need to be marked as TSO, to show that they + * need this special handling during tx completion. + * + * @param data_vdev - which virtual device should transmit the frame + * @param tx_spec - what non-standard operations to apply to the tx frame + * @param msdu_list - tx frame(s), in a null-terminated list + */ +typedef adf_nbuf_t (*ol_txrx_tx_non_std_fp)( + ol_txrx_vdev_handle data_vdev, + enum ol_txrx_osif_tx_spec tx_spec, + adf_nbuf_t msdu_list); + +/** + * @typedef ol_txrx_rx_fp + * @brief receive function to hand batches of data frames from txrx to OS shim + */ +typedef void (*ol_txrx_rx_fp)(ol_osif_vdev_handle vdev, adf_nbuf_t msdus); + +/** + * @typedef ol_txrx_rx_mon_fp + * @brief OSIF monitor mode receive function for single MPDU (802.11 format) + */ +typedef void (*ol_txrx_rx_mon_fp)( + ol_osif_vdev_handle vdev, + adf_nbuf_t mpdu, + void *rx_status); + +struct ol_txrx_osif_ops { + /* tx function pointers - specified by txrx, stored by OS shim */ + struct { + ol_txrx_tx_fp std; + ol_txrx_tx_non_std_fp non_std; + } tx; + + /* rx function pointers - specified by OS shim, stored by txrx */ + struct { + ol_txrx_rx_fp std; + ol_txrx_rx_mon_fp mon; + } rx; +}; + +/** + * @brief Link a vdev's data object with the matching OS shim vdev object. + * @details + * The data object for a virtual device is created by the function + * ol_txrx_vdev_attach. However, rather than fully linking the + * data vdev object with the vdev objects from the other subsystems + * that the data vdev object interacts with, the txrx_vdev_attach + * function focuses primarily on creating the data vdev object. + * After the creation of both the data vdev object and the OS shim + * vdev object, this txrx_osif_vdev_attach function is used to connect + * the two vdev objects, so the data SW can use the OS shim vdev handle + * when passing rx data received by a vdev up to the OS shim. + * + * @param txrx_vdev - the virtual device's data object + * @param osif_vdev - the virtual device's OS shim object + * @param txrx_ops - (pointers to) the functions used for tx and rx data xfer + * There are two portions of these txrx operations. + * The rx portion is filled in by OSIF SW before calling + * wdi_in_osif_vdev_register; inside the wdi_in_osif_vdev_register + * the txrx SW stores a copy of these rx function pointers, to use + * as it delivers rx data frames to the OSIF SW. + * The tx portion is filled in by the txrx SW inside + * wdi_in_osif_vdev_register; when the function call returns, + * the OSIF SW stores a copy of these tx functions to use as it + * delivers tx data frames to the txrx SW. + * The rx function pointer inputs consist of the following: + * rx: the OS shim rx function to deliver rx data frames to. + * This can have different values for different virtual devices, + * e.g. so one virtual device's OS shim directly hands rx frames to + * the OS, but another virtual device's OS shim filters out P2P + * messages before sending the rx frames to the OS. + * The netbufs delivered to the osif_rx function are in the format + * specified by the OS to use for tx and rx frames (either 802.3 or + * native WiFi). + * rx_mon: the OS shim rx monitor function to deliver monitor data to + * Though in practice, it is probable that the same function will + * be used for delivering rx monitor data for all virtual devices, + * in theory each different virtual device can have a different + * OS shim function for accepting rx monitor data. + * The netbufs delivered to the osif_rx_mon function are in 802.11 + * format. Each netbuf holds a 802.11 MPDU, not an 802.11 MSDU. + * Depending on compile-time configuration, each netbuf may also + * have a monitor-mode encapsulation header such as a radiotap + * header added before the MPDU contents. + * The tx function pointer outputs consist of the following: + * tx: the tx function pointer for standard data frames + * This function pointer is set by the txrx SW to perform + * host-side transmit operations based on whether a HL or LL + * host/target interface is in use. + * tx_non_std: the tx function pointer for non-standard data frames, + * such as TSO frames, explicitly-prioritized frames, or "raw" + * frames which skip some of the tx operations, such as 802.11 + * MAC header encapsulation. + */ +void +wdi_in_osif_vdev_register( + ol_txrx_vdev_handle txrx_vdev, + void *osif_vdev, + struct ol_txrx_osif_ops *txrx_ops); + +/** + * @brief Divide a jumbo TCP frame into smaller segments. + * @details + * For efficiency, the protocol stack above the WLAN driver may operate + * on jumbo tx frames, which are larger than the 802.11 MTU. + * The OSIF SW uses this txrx API function to divide the jumbo tx TCP frame + * into a series of segment frames. + * The segments are created as clones of the input jumbo frame. + * The txrx SW generates a new encapsulation header (ethernet + IP + TCP) + * for each of the output segment frames. The exact format of this header, + * e.g. 802.3 vs. Ethernet II, and IPv4 vs. IPv6, is chosen to match the + * header format of the input jumbo frame. + * The input jumbo frame is not modified. + * After the wdi_in_osif_tso_segment returns, the OSIF SW needs to perform + * DMA mapping on each of the segment network buffers, and also needs to + * + * @param txrx_vdev - which virtual device will transmit the TSO segments + * @param max_seg_payload_bytes - the maximum size for the TCP payload of + * each segment frame. + * This does not include the ethernet + IP + TCP header sizes. + * @param jumbo_tcp_frame - jumbo frame which needs to be cloned+segmented + * @return + * NULL if the segmentation fails, - OR - + * a NULL-terminated list of segment network buffers + */ +adf_nbuf_t wdi_in_osif_tso_segment( + ol_txrx_vdev_handle txrx_vdev, + int max_seg_payload_bytes, + adf_nbuf_t jumbo_tcp_frame); + +#define WDI_EVENT_BASE 0x100 /* Event starting number */ + +enum WDI_EVENT { + WDI_EVENT_TX_STATUS = WDI_EVENT_BASE, + WDI_EVENT_RX_DESC, + WDI_EVENT_RX_DESC_REMOTE, + WDI_EVENT_RATE_FIND, + WDI_EVENT_RATE_UPDATE, + WDI_EVENT_RX_PEER_INVALID, + /* End of new event items */ + + WDI_EVENT_LAST +}; + +struct wdi_event_rx_peer_invalid_msg { + adf_nbuf_t msdu; + struct ieee80211_frame *wh; + u_int8_t vdev_id; +}; + +#define WDI_NUM_EVENTS WDI_EVENT_LAST - WDI_EVENT_BASE + +#define WDI_EVENT_NOTIFY_BASE 0x200 +enum WDI_EVENT_NOTIFY { + WDI_EVENT_SUB_DEALLOCATE = WDI_EVENT_NOTIFY_BASE, + /* End of new notification types */ + + WDI_EVENT_NOTIFY_LAST +}; + +/* Opaque event callback */ +typedef void (*wdi_event_cb)(void *pdev, enum WDI_EVENT event, void *data); + +/* Opaque event notify */ +typedef void (*wdi_event_notify)(enum WDI_EVENT_NOTIFY notify, + enum WDI_EVENT event); +/** + * @typedef wdi_event_subscribe + * @brief Used by consumers to subscribe to WDI event notifications. + * @details + * The event_subscribe struct includes pointers to other event_subscribe + * objects. These pointers are simply to simplify the management of + * lists of event subscribers. These pointers are set during the + * event_sub() function, and shall not be modified except by the + * WDI event management SW, until after the object's event subscription + * is canceled by calling event_unsub(). + */ + +typedef struct wdi_event_subscribe_t { + wdi_event_cb callback; /* subscriber event callback structure head*/ + void *context; /* subscriber object that processes the event callback */ + struct { + /* private - the event subscriber SW shall not use this struct */ + struct wdi_event_subscribe_t *next; + struct wdi_event_subscribe_t *prev; + } priv; +} wdi_event_subscribe; + +struct wdi_event_pdev_t; +typedef struct wdi_event_pdev_t *wdi_event_pdev_handle; + +/** + * @brief Subscribe to a specified WDI event. + * @details + * This function adds the provided wdi_event_subscribe object to a list of + * subscribers for the specified WDI event. + * When the event in question happens, each subscriber for the event will + * have their callback function invoked. + * The order in which callback functions from multiple subscribers are + * invoked is unspecified. + * + * @param pdev - the event physical device, that maintains the event lists + * @param event_cb_sub - the callback and context for the event subscriber + * @param event - which event's notifications are being subscribed to + * @return error code, or A_OK for success + */ +A_STATUS wdi_in_event_sub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event); + +/** + * @brief Unsubscribe from a specified WDI event. + * @details + * This function removes the provided event subscription object from the + * list of subscribers for its event. + * This function shall only be called if there was a successful prior call + * to event_sub() on the same wdi_event_subscribe object. + * + * @param pdev - the event physical device with the list of event subscribers + * @param event_cb_sub - the event subscription object + * @param event - which event is being unsubscribed + * @return error code, or A_OK for success + */ +A_STATUS wdi_in_event_unsub( + struct ol_txrx_pdev_t *txrx_pdev, + wdi_event_subscribe *event_cb_sub, + enum WDI_EVENT event); + +#include /* adf_os_mutex_t */ +#include /* htt_dbg_stats_type */ +#include /* ol_txrx_stats */ + +typedef void (*ol_txrx_stats_callback)( + void *ctxt, + enum htt_dbg_stats_type type, + u_int8_t *buf, + int bytes); + +struct ol_txrx_stats_req { + u_int32_t stats_type_upload_mask; /* which stats to upload */ + u_int32_t stats_type_reset_mask; /* which stats to reset */ + + /* stats will be printed if either print element is set */ + struct { + int verbose; /* verbose stats printout */ + int concise; /* concise stats printout (takes precedence) */ + } print; /* print uploaded stats */ + + /* stats notify callback will be invoked if fp is non-NULL */ + struct { + ol_txrx_stats_callback fp; + void *ctxt; + } callback; + + /* stats will be copied into the specified buffer if buf is non-NULL */ + struct { + u_int8_t *buf; + int byte_limit; /* don't copy more than this */ + } copy; + + /* + * If blocking is true, the caller will take the specified semaphore + * to wait for the stats to be uploaded, and the driver will release + * the semaphore when the stats are done being uploaded. + */ + struct { + int blocking; + adf_os_mutex_t *sem_ptr; + } wait; +}; + +#ifdef ATH_PERF_PWR_OFFLOAD /*---------------------------------------------*/ + +#define wdi_in_debug(vdev, debug_specs) 0 +#define wdi_in_fw_stats_cfg(vdev, type, val) 0 +#define wdi_in_fw_stats_get(vdev, req) 0 +#define wdi_in_aggr_cfg(vdev, max_subfrms_ampdu, max_subfrms_amsdu) 0 + +#else /*---------------------------------------------------------------------*/ + +int wdi_in_debug(ol_txrx_vdev_handle vdev, int debug_specs); + +void wdi_in_fw_stats_cfg( + ol_txrx_vdev_handle vdev, + u_int8_t cfg_stats_type, + u_int32_t cfg_val); + +int wdi_in_fw_stats_get( + ol_txrx_vdev_handle vdev, + struct ol_txrx_stats_req *req); + +int wdi_in_aggr_cfg(ol_txrx_vdev_handle vdev, + int max_subfrms_ampdu, + int max_subfrms_amsdu); + +enum { + TXRX_DBG_MASK_OBJS = 0x01, + TXRX_DBG_MASK_STATS = 0x02, + TXRX_DBG_MASK_PROT_ANALYZE = 0x04, + TXRX_DBG_MASK_RX_REORDER_TRACE = 0x08, + TXRX_DBG_MASK_RX_PN_TRACE = 0x10 +}; + +/*--- txrx printouts ---*/ + +/* + * Uncomment this to enable txrx printouts with dynamically adjustable + * verbosity. These printouts should not impact performance. + */ +#define TXRX_PRINT_ENABLE 1 +/* uncomment this for verbose txrx printouts (may impact performance) */ +//#define TXRX_PRINT_VERBOSE_ENABLE 1 + +void wdi_in_print_level_set(unsigned level); + +/*--- txrx object (pdev, vdev, peer) display debug functions ---*/ + +#ifndef TXRX_DEBUG_LEVEL +#define TXRX_DEBUG_LEVEL 0 /* no debug info */ +#endif + +#if TXRX_DEBUG_LEVEL > 5 +void wdi_in_pdev_display(ol_txrx_pdev_handle pdev, int indent); +void wdi_in_vdev_display(ol_txrx_vdev_handle vdev, int indent); +void wdi_in_peer_display(ol_txrx_peer_handle peer, int indent); +#else +#define wdi_in_pdev_display(pdev, indent) +#define wdi_in_vdev_display(vdev, indent) +#define wdi_in_peer_display(peer, indent) +#endif + +/*--- txrx stats display debug functions ---*/ + +#if TXRX_STATS_LEVEL != TXRX_STATS_LEVEL_OFF + +void wdi_in_stats_display(ol_txrx_pdev_handle pdev); + +int +wdi_in_stats_publish(ol_txrx_pdev_handle pdev, struct ol_txrx_stats *buf); + +#else +#define wdi_in_stats_display(pdev) +#define wdi_in_stats_publish(pdev, buf) TXRX_STATS_LEVEL_OFF +#endif /* TXRX_STATS_LEVEL */ + +/*--- txrx protocol analyzer debug feature ---*/ + +/* uncomment this to enable the protocol analzyer feature */ +//#define ENABLE_TXRX_PROT_ANALYZE 1 + +#if defined(ENABLE_TXRX_PROT_ANALYZE) + +void wdi_in_prot_ans_display(ol_txrx_pdev_handle pdev); + +#else + +#define wdi_in_prot_ans_display(pdev) + +#endif /* ENABLE_TXRX_PROT_ANALYZE */ + +/*--- txrx sequence number trace debug feature ---*/ + +/* uncomment this to enable the rx reorder trace feature */ +//#define ENABLE_RX_REORDER_TRACE 1 + +#define wdi_in_seq_num_trace_display(pdev) \ + ol_rx_reorder_trace_display(pdev, 0, 0) + +#if defined(ENABLE_RX_REORDER_TRACE) + +void +ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit); + +#else + +#define ol_rx_reorder_trace_display(pdev, just_once, limit) + +#endif /* ENABLE_RX_REORDER_TRACE */ + +/*--- txrx packet number trace debug feature ---*/ + +/* uncomment this to enable the rx PN trace feature */ +//#define ENABLE_RX_PN_TRACE 1 + +#define wdi_in_pn_trace_display(pdev) ol_rx_pn_trace_display(pdev, 0) + +#if defined(ENABLE_RX_PN_TRACE) + +void +ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once); + +#else + +#define ol_rx_pn_trace_display(pdev, just_once) + +#endif /* ENABLE_RX_PN_TRACE */ + +/*--- tx queue log debug feature ---*/ +/* uncomment this to enable the tx queue log feature */ +//#define ENABLE_TX_QUEUE_LOG 1 + +#if defined(ENABLE_TX_QUEUE_LOG) && defined(CONFIG_HL_SUPPORT) + +void +ol_tx_queue_log_display(ol_txrx_pdev_handle pdev); + +#else + +#define ol_tx_queue_log_display(pdev) + +#endif /* defined(ENABLE_TX_QUEUE_LOG) && defined(CONFIG_HL_SUPPORT) */ + +#endif /* ATH_PERF_PWR_OFFLOAD */ /*----------------------------------------*/ + +#else +/* WDI_API_AS_MACROS */ + +#include + +#define wdi_in_pdev_cfg_attach ol_pdev_cfg_attach +#define wdi_in_pdev_attach ol_txrx_pdev_attach +#define wdi_in_pdev_attach_target ol_txrx_pdev_attach_target +#define wdi_in_enable_host_ratectrl ol_txrx_enable_host_ratectrl +#define wdi_in_vdev_attach ol_txrx_vdev_attach +#define wdi_in_peer_attach ol_txrx_peer_attach +#define wdi_in_peer_update ol_txrx_peer_update +#define wdi_in_peer_pause ol_txrx_peer_pause +#define wdi_in_peer_tid_unpause ol_txrx_peer_tid_unpause +#define wdi_in_tx_release ol_txrx_tx_release +#define wdi_in_vdev_pause ol_txrx_vdev_pause +#define wdi_in_vdev_unpause ol_txrx_vdev_unpause +#define wdi_in_pdev_pause ol_txrx_pdev_pause +#define wdi_in_pdev_unpause ol_txrx_pdev_unpause +#define wdi_in_tx_sync ol_txrx_tx_sync +#define wdi_in_peer_detach ol_txrx_peer_detach +#define wdi_in_vdev_detach ol_txrx_vdev_detach +#define wdi_in_pdev_detach ol_txrx_pdev_detach +#define wdi_in_data_tx_cb_set ol_txrx_data_tx_cb_set +#define wdi_in_mgmt_tx_cb_set ol_txrx_mgmt_tx_cb_set +#define wdi_in_mgmt_send ol_txrx_mgmt_send +#define wdi_in_set_monitor_mode_vap ol_txrx_set_monitor_mode_vap +#define wdi_in_set_curchan ol_txrx_set_curchan +#define wdi_in_get_tx_pending ol_txrx_get_tx_pending +#define wdi_in_discard_tx_pending ol_txrx_discard_tx_pending +#define wdi_in_set_safemode ol_txrx_set_safemode +#define wdi_in_set_privacy_filters ol_txrx_set_privacy_filters +#define wdi_in_set_drop_unenc ol_txrx_set_drop_unenc +#define wdi_in_peer_state_update ol_txrx_peer_state_update +#define wdi_in_peer_keyinstalled_state_update ol_txrx_peer_keyinstalled_state_update +#define wdi_in_vdev_rx_fwd_disabled ol_vdev_rx_set_intrabss_fwd +#ifdef QCA_LL_TX_FLOW_CT +#define wdi_in_get_tx_resource ol_txrx_get_tx_resource +#define wdi_in_ll_set_tx_pause_q_depth ol_txrx_ll_set_tx_pause_q_depth +#endif /* QCA_LL_TX_FLOW_CT */ +#define wdi_in_set_wmm_param ol_txrx_set_wmm_param + +#include + +#define wdi_in_debug ol_txrx_debug +#define wdi_in_fw_stats_cfg ol_txrx_fw_stats_cfg +#define wdi_in_fw_stats_get ol_txrx_fw_stats_get +#define wdi_in_aggr_cfg ol_txrx_aggr_cfg +#define wdi_in_debug ol_txrx_debug +#define wdi_in_fw_stats_cfg ol_txrx_fw_stats_cfg +#define wdi_in_fw_stats_get ol_txrx_fw_stats_get +#define wdi_in_aggr_cfg ol_txrx_aggr_cfg +#define wdi_in_aggr_cfg ol_txrx_aggr_cfg +#define wdi_in_print_level_set ol_txrx_print_level_set +#define wdi_in_pdev_display ol_txrx_pdev_display +#define wdi_in_vdev_display ol_txrx_vdev_display +#define wdi_in_peer_display ol_txrx_peer_display +#define wdi_in_pdev_display ol_txrx_pdev_display +#define wdi_in_vdev_display ol_txrx_vdev_display +#define wdi_in_peer_display ol_txrx_peer_display +#define wdi_in_stats_display ol_txrx_stats_display +#define wdi_in_stats_publish ol_txrx_stats_publish +#define wdi_in_stats_display ol_txrx_stats_display +#define wdi_in_stats_publish ol_txrx_stats_publish +#define wdi_in_prot_ans_display ol_txrx_prot_ans_display +#define wdi_in_prot_ans_display ol_txrx_prot_ans_display +#define wdi_in_seq_num_trace_display ol_txrx_seq_num_trace_display +#define wdi_in_pn_trace_display ol_txrx_pn_trace_display + +#ifdef IPA_UC_OFFLOAD +#define wdi_in_ipa_uc_get_resource ol_txrx_ipa_uc_get_resource +#define wdi_in_ipa_uc_set_doorbell_paddr ol_txrx_ipa_uc_set_doorbell_paddr +#define wdi_in_ipa_uc_set_active ol_txrx_ipa_uc_set_active +#define wdi_in_ipa_uc_register_op_cb ol_txrx_ipa_uc_register_op_cb +#endif /* IPA_UC_OFFLOAD */ + +#include + +#define wdi_in_osif_vdev_register ol_txrx_osif_vdev_register +#define wdi_in_osif_tso_segment ol_txrx_osif_tso_segment +#include + +#define wdi_in_event_sub wdi_event_sub +#define wdi_in_event_unsub wdi_event_unsub +#define wdi_in_set_cfg_rx_fwd_disabled ol_set_cfg_rx_fwd_disabled +#define wdi_in_set_cfg_pakcet_log_enabled ol_set_cfg_packet_log_enabled + +#endif /* WDI_API_AS_FUNCS / MACROS */ + +#endif /* _WDI_IN__H_ */ + +/**@}*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_out.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_out.h new file mode 100644 index 0000000000000..dcfccd273fd18 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_out.h @@ -0,0 +1,561 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY */ +/** + * @addtogroup WDIAPI + *@{ + */ +/** + * @file wdi_out.h + * @brief Functions outside the WDI boundary called by datapath functions + */ +#ifndef _WDI_OUT__H_ +#define _WDI_OUT__H_ + +#include + +#ifdef WDI_API_AS_FUNCS + +#include /* u_int32_t */ +#include /* ieee80211_qosframe_htc_addr4 */ +#include /* LLC_SNAP_HDR_LEN */ + +#if defined(CONFIG_HL_SUPPORT) +#include "wlan_tgt_def_config_hl.h" +#else +#include "wlan_tgt_def_config.h" +#endif + +/** + * @brief Specify whether the system is high-latency or low-latency. + * @details + * Indicate whether the system is operating in high-latency (message + * based, e.g. USB) mode or low-latency (memory-mapped, e.g. PCIe) mode. + * Some chips support just one type of host / target interface. + * Other chips support both LL and HL interfaces (e.g. PCIe and USB), + * so the selection will be made based on which bus HW is present, or + * which is preferred if both are present. + * + * @param pdev - handle to the physical device + * @return 1 -> high-latency -OR- 0 -> low-latency + */ +int wdi_out_cfg_is_high_latency(ol_pdev_handle pdev); + +/** + * @brief Specify the range of peer IDs. + * @details + * Specify the maximum peer ID. This is the maximum number of peers, + * minus one. + * This is used by the host to determine the size of arrays indexed by + * peer ID. + * + * @param pdev - handle to the physical device + * @return maximum peer ID + */ +int wdi_out_cfg_max_peer_id(ol_pdev_handle pdev); + +/** + * @brief Specify the max number of virtual devices within a physical device. + * @details + * Specify how many virtual devices may exist within a physical device. + * + * @param pdev - handle to the physical device + * @return maximum number of virtual devices + */ +int wdi_out_cfg_max_vdevs(ol_pdev_handle pdev); + +/** + * @brief Check whether host-side rx PN check is enabled or disabled. + * @details + * Choose whether to allocate rx PN state information and perform + * rx PN checks (if applicable, based on security type) on the host. + * If the rx PN check is specified to be done on the host, the host SW + * will determine which peers are using a security type (e.g. CCMP) that + * requires a PN check. + * + * @param pdev - handle to the physical device + * @return 1 -> host performs rx PN check -OR- 0 -> no host-side rx PN check + */ +int wdi_out_cfg_rx_pn_check(ol_pdev_handle pdev); + +/** + * @brief Check whether host-side rx forwarding is enabled or disabled. + * @details + * Choose whether to check whether to forward rx frames to tx on the host. + * For LL systems, this rx -> tx host-side forwarding check is typically + * enabled. + * For HL systems, the rx -> tx forwarding check is typically done on the + * target. However, even in HL systems, the host-side rx -> tx forwarding + * will typically be enabled, as a second-tier safety net in case the + * target doesn't have enough memory to store all rx -> tx forwarded frames. + * + * @param pdev - handle to the physical device + * @return 1 -> host does rx->tx forward -OR- 0 -> no host-side rx->tx forward + */ +int wdi_out_cfg_rx_fwd_check(ol_pdev_handle pdev); + +/** + * @brief Check whether to perform inter-BSS or intra-BSS rx->tx forwarding. + * @details + * Check whether data received by an AP on one virtual device destined + * to a STA associated with a different virtual device within the same + * physical device should be forwarded within the driver, or whether + * forwarding should only be done within a virtual device. + * + * @param pdev - handle to the physical device + * @return + * 1 -> forward both within and between vdevs + * -OR- + * 0 -> forward only within a vdev + */ +int wdi_out_cfg_rx_fwd_inter_bss(ol_pdev_handle pdev); + +/** + * @brief format of data frames delivered to/from the WLAN driver by/to the OS + */ +enum wlan_frm_fmt { + wlan_frm_fmt_unknown, + wlan_frm_fmt_raw, + wlan_frm_fmt_native_wifi, + wlan_frm_fmt_802_3, +}; + +/** + * @brief Specify data frame format used by the OS. + * @details + * Specify what type of frame (802.3 or native WiFi) the host data SW + * should expect from and provide to the OS shim. + * + * @param pdev - handle to the physical device + * @return enumerated data frame format + */ +enum wlan_frm_fmt wdi_out_cfg_frame_type(ol_pdev_handle pdev); + +/** + * @brief Specify the peak throughput. + * @details + * Specify the peak throughput that a system is expected to support. + * The data SW uses this configuration to help choose the size for its + * tx descriptor pool and rx buffer ring. + * The data SW assumes that the peak throughput applies to either rx or tx, + * rather than having separate specs of the rx max throughput vs. the tx + * max throughput. + * + * @param pdev - handle to the physical device + * @return maximum supported throughput in Mbps (not MBps) + */ +int wdi_out_cfg_max_thruput_mbps(ol_pdev_handle pdev); + +/** + * @brief Specify the maximum number of fragments per tx network buffer. + * @details + * Specify the maximum number of fragments that a tx frame provided to + * the WLAN driver by the OS may contain. + * In LL systems, the host data SW uses this maximum fragment count to + * determine how many elements to allocate in the fragmentation descriptor + * it creates to specify to the tx MAC DMA where to locate the tx frame's + * data. + * This maximum fragments count is only for regular frames, not TSO frames, + * since TSO frames are sent in segments with a limited number of fragments + * per segment. + * + * @param pdev - handle to the physical device + * @return maximum number of fragments that can occur in a regular tx frame + */ +int wdi_out_cfg_netbuf_frags_max(ol_pdev_handle pdev); + +/** + * @brief For HL systems, specify when to free tx frames. + * @details + * In LL systems, the host's tx frame is referenced by the MAC DMA, and + * thus cannot be freed until the target indicates that it is finished + * transmitting the frame. + * In HL systems, the entire tx frame is downloaded to the target. + * Consequently, the target has its own copy of the tx frame, and the + * host can free the tx frame as soon as the download completes. + * Alternatively, the HL host can keep the frame allocated until the + * target explicitly tells the HL host it is done transmitting the frame. + * This gives the target the option of discarding its copy of the tx + * frame, and then later getting a new copy from the host. + * This function tells the host whether it should retain its copy of the + * transmit frames until the target explicitly indicates it is finished + * transmitting them, or if it should free its copy as soon as the + * tx frame is downloaded to the target. + * + * @param pdev - handle to the physical device + * @return + * 0 -> retain the tx frame until the target indicates it is done + * transmitting the frame + * -OR- + * 1 -> free the tx frame as soon as the download completes + */ +int wdi_out_cfg_tx_free_at_download(ol_pdev_handle pdev); + +/** + * @brief Low water mark for target tx credit. + * Tx completion handler is invoked to reap the buffers when the target tx + * credit goes below Low Water Mark. + */ +#define OL_CFG_NUM_MSDU_REAP 512 +#define wdi_out_cfg_tx_credit_lwm(pdev) \ + ((CFG_TGT_NUM_MSDU_DESC > OL_CFG_NUM_MSDU_REAP) ? \ + (CFG_TGT_NUM_MSDU_DESC - OL_CFG_NUM_MSDU_REAP) : 0) + +/** + * @brief In a HL system, specify the target initial credit count. + * @details + * The HL host tx data SW includes a module for determining which tx frames + * to download to the target at a given time. + * To make this judgement, the HL tx download scheduler has to know + * how many buffers the HL target has available to hold tx frames. + * Due to the possibility that a single target buffer pool can be shared + * between rx and tx frames, the host may not be able to obtain a precise + * specification of the tx buffer space available in the target, but it + * uses the best estimate, as provided by this configuration function, + * to determine how best to schedule the tx frame downloads. + * + * @param pdev - handle to the physical device + * @return the number of tx buffers available in a HL target + */ +int wdi_out_cfg_target_tx_credit(ol_pdev_handle pdev); + +/** + * @brief Specify the LL tx MSDU header download size. + * @details + * In LL systems, determine how many bytes from a tx frame to download, + * in order to provide the target FW's Descriptor Engine with enough of + * the packet's payload to interpret what kind of traffic this is, + * and who it is for. + * This download size specification does not include the 802.3 / 802.11 + * frame encapsulation headers; it starts with the encapsulated IP packet + * (or whatever ethertype is carried within the ethernet-ish frame). + * The LL host data SW will determine how many bytes of the MSDU header to + * download by adding this download size specification to the size of the + * frame header format specified by the wdi_out_cfg_frame_type configuration + * function. + * + * @param pdev - handle to the physical device + * @return the number of bytes beyond the 802.3 or native WiFi header to + * download to the target for tx classification + */ +int wdi_out_cfg_tx_download_size(ol_pdev_handle pdev); + +/** + * brief Specify where defrag timeout and duplicate detection is handled + * @details + * non-aggregate duplicate detection and timing out stale fragments + * requires additional target memory. To reach max client + * configurations (128+), non-aggregate duplicate detection and the + * logic to time out stale fragments is moved to the host. + * + * @param pdev - handle to the physical device + * @return + * 0 -> target is responsible non-aggregate duplicate detection and + * timing out stale fragments. + * + * 1 -> host is responsible non-aggregate duplicate detection and + * timing out stale fragments. + */ +int wdi_out_cfg_rx_host_defrag_timeout_duplicate_check(ol_pdev_handle pdev); + +typedef enum { + wlan_frm_tran_cap_raw = 0x01, + wlan_frm_tran_cap_native_wifi = 0x02, + wlan_frm_tran_cap_8023 = 0x04, +} wlan_target_fmt_translation_caps; + +/** + * @brief Specify the maximum header size added by SW tx encapsulation + * @details + * This function returns the maximum size of the new L2 header, not the + * difference between the new and old L2 headers. + * Thus, this function returns the maximum 802.11 header size that the + * tx SW may need to add to tx data frames. + * + * @param pdev - handle to the physical device + */ +static inline int +wdi_out_cfg_sw_encap_hdr_max_size(ol_pdev_handle pdev) +{ + /* + * 24 byte basic 802.11 header + * + 6 byte 4th addr + * + 2 byte QoS control + * + 4 byte HT control + * + 8 byte LLC/SNAP + */ + return sizeof(struct ieee80211_qosframe_htc_addr4) + LLC_SNAP_HDR_LEN; +} + +static inline u_int8_t +wdi_out_cfg_tx_encap(ol_pdev_handle pdev) +{ + /* tx encap done in HW */ + return 0; +} + +static inline int +wdi_out_cfg_host_addba(ol_pdev_handle pdev) +{ + /* + * ADDBA negotiation is handled by the target FW for Peregrine + Rome. + */ + return 0; +} + +/** + * @brief If the host SW's ADDBA negotiation fails, should it be retried? + * + * @param pdev - handle to the physical device + */ +static inline int +wdi_out_cfg_addba_retry(ol_pdev_handle pdev) +{ + return 0; /* disabled for now */ +} + +/** + * @brief How many frames to hold in a paused vdev's tx queue in LL systems + */ +static inline int +wdi_out_tx_cfg_max_tx_queue_depth_ll(ol_pdev_handle pdev) +{ + /* + * Store up to 700 frames for a paused vdev. + * For example, if the vdev is sending 300 Mbps of traffic, and the + * PHY is capable of 600 Mbps, then it will take 56 ms for the PHY to + * drain both the 700 frames that are queued initially, plus the next + * 700 frames that come in while the PHY is catching up. + * So in this example scenario, the PHY will remain fully utilized + * in a MCC system that has a channel-switching period of 56 ms or less. + */ + return 700; +} + +//#include /* u_int8_t */ +#include /* u_int8_t */ +#include /* adf_nbuf_t */ + +enum ol_rx_err_type { + OL_RX_ERR_DEFRAG_MIC, + OL_RX_ERR_PN, + OL_RX_ERR_UNKNOWN_PEER, + OL_RX_ERR_MALFORMED, + OL_RX_ERR_TKIP_MIC, + OL_RX_ERR_DECRYPT, + OL_RX_ERR_MPDU_LENGTH, + OL_RX_ERR_ENCRYPT_REQUIRED, + OL_RX_ERR_DUP, + OL_RX_ERR_UNKNOWN, + OL_RX_ERR_FCS, + OL_RX_ERR_PRIVACY, + OL_RX_ERR_NONE_FRAG, + OL_RX_ERR_NONE = 0xFF +}; + +#ifdef SUPPORT_HOST_STATISTICS +/** * @brief Update tx statistics + * @details + * Update tx statistics after tx complete. + * + * @param pdev - ol_pdev_handle instance + * @param vdev_id - ID of the virtual device that tx frame + * @param had_error - whether there is error when tx + */ +void wdi_out_tx_statistics(ol_pdev_handle pdev, + u_int16_t vdev_id, + int had_error); +#else +#define wdi_out_tx_statistics(pdev, vdev_id, had_error) +#endif + +/** * @brief Count on received packets for invalid peer case + * + * @param pdev - txrx pdev handle + * @param wh - received frame + * @param err_type - what kind of error occurred + */ +void wdi_out_rx_err_inv_peer_statistics(ol_pdev_handle pdev, + struct ieee80211_frame *wh, + enum ol_rx_err_type err_type); + +/** + * @brief Count on received packets, both success and failed + * + * @param pdev - ol_pdev_handle handle + * @param vdev_id - ID of the virtual device received the erroneous rx frame + * @param err_type - what kind of error occurred + * @param sec_type - The cipher type the peer is using + * @param is_mcast - whether this is one multi cast frame + */ +void wdi_out_rx_err_statistics(ol_pdev_handle pdev, + u_int8_t vdev_id, + enum ol_rx_err_type err_type, + enum ol_sec_type sec_type, + int is_mcast); + +/** + * @brief Provide notification of failure during host rx processing + * @details + * Indicate an error during host rx data processing, including what + * kind of error happened, when it happened, which peer and TID the + * erroneous rx frame is from, and what the erroneous rx frame itself + * is. + * + * @param pdev - handle to the ctrl SW's physical device object + * @param vdev_id - ID of the virtual device received the erroneous rx frame + * @param peer_mac_addr - MAC address of the peer that sent the erroneous + * rx frame + * @param tid - which TID within the peer sent the erroneous rx frame + * @param tsf32 - the timstamp in TSF units of the erroneous rx frame, or + * one of the fragments that when reassembled, constitute the rx frame + * @param err_type - what kind of error occurred + * @param rx_frame - the rx frame that had an error + * @pn - Packet sequence number + * @key_id - Key index octet received in IV of the frame + */ +void +wdi_out_rx_err( + ol_pdev_handle pdev, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tid, + u_int32_t tsf32, + enum ol_rx_err_type err_type, + adf_nbuf_t rx_frame, + u_int64_t *pn, + u_int8_t key_id); + +enum ol_rx_notify_type { + OL_RX_NOTIFY_IPV4_IGMP, +}; + +/** + * @brief Provide notification of reception of data of special interest. + * @details + * Indicate when "special" data has been received. The nature of the + * data that results in it being considered special is specified in the + * notify_type argument. + * This function is currently used by the data-path SW to notify the + * control path SW when the following types of rx data are received: + * + IPv4 IGMP frames + * The control SW can use these to learn about multicast group + * membership, if it so chooses. + * + * @param pdev - handle to the ctrl SW's physical device object + * @param vdev_id - ID of the virtual device received the special data + * @param peer_mac_addr - MAC address of the peer that sent the special data + * @param tid - which TID within the peer sent the special data + * @param tsf32 - the timstamp in TSF units of the special data + * @param notify_type - what kind of special data was received + * @param rx_frame - the rx frame containing the special data + */ +void +wdi_out_rx_notify( + ol_pdev_handle pdev, + u_int8_t vdev_id, + u_int8_t *peer_mac_addr, + int tid, + u_int32_t tsf32, + enum ol_rx_notify_type notify_type, + adf_nbuf_t rx_frame); + +/** + * @brief Indicate when a paused STA has tx data available. + * @details + * Indicate to the control SW when a paused peer that previously + * has all its peer-TID queues empty gets a MSDU to transmit. + * Conversely, indicate when a paused peer that had data in one or more of + * its peer-TID queues has all queued data removed (e.g. due to a U-APSD + * triggered transmission), but is still paused. + * It is up to the control SW to determine whether the peer is paused due to + * being in power-save sleep, or some other reason, and thus whether it is + * necessary to set the TIM in beacons to notify a sleeping STA that it has + * data. + * The data SW will also issue this wdi_out_tx_paused_peer_data call when an + * unpaused peer that currently has tx data in one or more of its + * peer-TID queues becomes paused. + * The data SW will not issue this wdi_out_tx_paused_peer_data call when a + * peer with data in one or more of its peer-TID queues becomes unpaused. + * + * @param peer - the paused peer + * @param has_tx_data - + * 1 -> a paused peer that previously had no tx data now does, -OR- + * 0 -> a paused peer that previously had tx data now doesnt + */ +void +wdi_out_tx_paused_peer_data(ol_peer_handle peer, int has_tx_data); + + +#define wdi_out_ctrl_addba_req(pdev, peer_mac_addr, tid) ol_addba_req_reject +#define wdi_out_ctrl_rx_addba_complete(pdev, peer_mac_addr, tid, failed) /* no-op */ + + +#else +/* WDI_API_AS_MACROS */ + +#include + +#define wdi_out_cfg_is_high_latency ol_cfg_is_high_latency +#define wdi_out_cfg_max_peer_id ol_cfg_max_peer_id +#define wdi_out_cfg_max_vdevs ol_cfg_max_vdevs +#define wdi_out_cfg_rx_pn_check ol_cfg_rx_pn_check +#define wdi_out_cfg_rx_fwd_check ol_cfg_rx_fwd_check +#define wdi_out_cfg_rx_fwd_inter_bss ol_cfg_rx_fwd_inter_bss +#define wdi_out_cfg_frame_type ol_cfg_frame_type +#define wdi_out_cfg_max_thruput_mbps ol_cfg_max_thruput_mbps +#define wdi_out_cfg_netbuf_frags_max ol_cfg_netbuf_frags_max +#define wdi_out_cfg_tx_free_at_download ol_cfg_tx_free_at_download +#define wdi_out_cfg_tx_credit_lwm ol_cfg_tx_credit_lwm +#define wdi_out_cfg_target_tx_credit ol_cfg_target_tx_credit +#define wdi_out_cfg_tx_download_size ol_cfg_tx_download_size +#define wdi_out_cfg_rx_host_defrag_timeout_duplicate_check ol_cfg_rx_host_defrag_timeout_duplicate_check +#define wdi_out_cfg_sw_encap_hdr_max_size ol_cfg_sw_encap_hdr_max_size +#define wdi_out_cfg_tx_encap ol_cfg_tx_encap +#define wdi_out_cfg_host_addba ol_cfg_host_addba +#define wdi_out_cfg_addba_retry ol_cfg_addba_retry +#define wdi_out_tx_cfg_max_tx_queue_depth_ll ol_tx_cfg_max_tx_queue_depth_ll + +#include + +#define wdi_out_tx_statistics ol_tx_statistics +#define wdi_out_tx_statistics ol_tx_statistics +#define wdi_out_rx_err_inv_peer_statistics ol_rx_err_inv_peer_statistics +#define wdi_out_rx_err_statistics ol_rx_err_statistics +#define wdi_out_rx_err ol_rx_err +#define wdi_out_rx_notify ol_rx_notify +#define wdi_out_tx_paused_peer_data ol_tx_paused_peer_data +#define wdi_out_ctrl_addba_req ol_ctrl_addba_req +#define wdi_out_ctrl_rx_addba_complete ol_ctrl_rx_addba_complete +#define wdi_out_cfg_rx_fwd_disabled ol_cfg_rx_fwd_disabled + +#endif /* WDI_API_AS_FUNCS / MACROS */ + +#endif /* _WDI_OUT__H_ */ + +/**@}*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_types.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_types.h new file mode 100644 index 0000000000000..e6e500769a6cb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wdi_types.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY */ +/** + * @addtogroup WDIAPI + *@{ + */ +/** + * @file wdi_types.h + * @brief Data type definitions used within the WDI API + * @details + * The data type definitions shown below are purely for documentation + * reference. + * The actual data type definitions are obtained by including the individual + * API header files that define them. + */ +#ifndef _WDI_TYPES__H_ +#define _WDI_TYPES__H_ + +#ifdef WDI_TYPES_DIRECT_DEFS + +struct ol_pdev_t; +typedef struct ol_pdev_t* ol_pdev_handle; + +struct ol_vdev_t; +typedef struct ol_vdev_t* ol_vdev_handle; + +struct ol_peer_t; +typedef struct ol_peer_t* ol_peer_handle; + +/** + * @typedef ol_osif_vdev_handle + * @brief opaque handle for OS shim virtual device object + */ +struct ol_osif_vdev_t; +typedef struct ol_osif_vdev_t* ol_osif_vdev_handle; + +/** + * @typedef ol_txrx_pdev_handle + * @brief opaque handle for txrx physical device object + */ +struct ol_txrx_pdev_t; +typedef struct ol_txrx_pdev_t* ol_txrx_pdev_handle; + +/** + * @typedef ol_txrx_vdev_handle + * @brief opaque handle for txrx virtual device object + */ +struct ol_txrx_vdev_t; +typedef struct ol_txrx_vdev_t* ol_txrx_vdev_handle; + +/** + * @typedef ol_txrx_peer_handle + * @brief opaque handle for txrx peer object + */ +struct ol_txrx_peer_t; +typedef struct ol_txrx_peer_t* ol_txrx_peer_handle; + +/** + * @brief ADDBA negotiation status, used both during requests and confirmations + */ +enum ol_addba_status { + /* status: negotiation started or completed successfully */ + ol_addba_success, + + /* reject: aggregation is not applicable - don't try again */ + ol_addba_reject, + + /* busy: ADDBA negotiation couldn't be performed - try again later */ + ol_addba_busy, +}; + +enum ol_sec_type { + ol_sec_type_none, + ol_sec_type_wep128, + ol_sec_type_wep104, + ol_sec_type_wep40, + ol_sec_type_tkip, + ol_sec_type_tkip_nomic, + ol_sec_type_aes_ccmp, + ol_sec_type_wapi, + + /* keep this last! */ + ol_sec_type_types +}; + +#else + +/* obtain data type defs from individual API header files */ + +#include +#include +#include + +#endif /* WDI_TYPES_DIRECT_DEFS */ + +#endif /* _WDI_TYPES__H_ */ + +/**@}*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_defs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_defs.h new file mode 100644 index 0000000000000..ce2a1665644b5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_defs.h @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2004-2010, 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010, 2013 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __WLANDEFS_H__ +#define __WLANDEFS_H__ + +#include /* A_COMPILE_TIME_ASSERT */ +#include + +/* + * This file contains WLAN definitions that may be used across both + * Host and Target software. + */ +/* + * MAX_SPATIAL_STREAM should be defined in a fwconfig_xxx.h file, + * but for now provide a default value here in case it's not defined + * in the fwconfig_xxx.h file. + */ +#ifndef MAX_SPATIAL_STREAM +#define MAX_SPATIAL_STREAM 3 +#endif + +/* + * MAX_SPATIAL_STREAM_ANY - + * what is the largest number of spatial streams that any target supports + */ +#define MAX_SPATIAL_STREAM_ANY 4 + +#ifndef CONFIG_160MHZ_SUPPORT +#define CONFIG_160MHZ_SUPPORT 0 /* default: 160 MHz channels not supported */ +#endif + +typedef enum { + MODE_11A = 0, /* 11a Mode */ + MODE_11G = 1, /* 11b/g Mode */ + MODE_11B = 2, /* 11b Mode */ + MODE_11GONLY = 3, /* 11g only Mode */ + MODE_11NA_HT20 = 4, /* 11a HT20 mode */ + MODE_11NG_HT20 = 5, /* 11g HT20 mode */ + MODE_11NA_HT40 = 6, /* 11a HT40 mode */ + MODE_11NG_HT40 = 7, /* 11g HT40 mode */ + MODE_11AC_VHT20 = 8, + MODE_11AC_VHT40 = 9, + MODE_11AC_VHT80 = 10, + MODE_11AC_VHT20_2G = 11, + MODE_11AC_VHT40_2G = 12, + MODE_11AC_VHT80_2G = 13, +#if CONFIG_160MHZ_SUPPORT + MODE_11AC_VHT80_80 = 14, + MODE_11AC_VHT160 = 15, +#endif + + MODE_UNKNOWN, + MODE_UNKNOWN_NO_160MHZ_SUPPORT = 14, + MODE_UNKNOWN_160MHZ_SUPPORT = 16, + + MODE_MAX = MODE_UNKNOWN, + MODE_MAX_NO_160_MHZ_SUPPORT = MODE_UNKNOWN_NO_160MHZ_SUPPORT, + MODE_MAX_160_MHZ_SUPPORT = MODE_UNKNOWN_160MHZ_SUPPORT, + +} WLAN_PHY_MODE; + +#if CONFIG_160MHZ_SUPPORT == 0 +A_COMPILE_TIME_ASSERT( + mode_unknown_value_consistency_Check, + MODE_UNKNOWN == MODE_UNKNOWN_NO_160MHZ_SUPPORT); +#else +A_COMPILE_TIME_ASSERT( + mode_unknown_value_consistency_Check, + MODE_UNKNOWN == MODE_UNKNOWN_160MHZ_SUPPORT); +#endif + +typedef enum { + VHT_MODE_NONE = 0, /* NON VHT Mode, e.g., HT, DSSS, CCK */ + VHT_MODE_20M = 1, + VHT_MODE_40M = 2, + VHT_MODE_80M = 3, + VHT_MODE_160M = 4 +} VHT_OPER_MODE; + +typedef enum { + WLAN_11A_CAPABILITY = 1, + WLAN_11G_CAPABILITY = 2, + WLAN_11AG_CAPABILITY = 3, +}WLAN_CAPABILITY; + +#if defined(CONFIG_AR900B_SUPPORT) || defined(AR900B) +#define A_RATEMASK A_UINT64 +#else +#define A_RATEMASK A_UINT32 +#endif + +#define A_RATEMASK_NUM_OCTET (sizeof (A_RATEMASK)) +#define A_RATEMASK_NUM_BITS ((sizeof (A_RATEMASK)) << 3) + + +#if CONFIG_160MHZ_SUPPORT +#define IS_MODE_VHT(mode) (((mode) == MODE_11AC_VHT20) || \ + ((mode) == MODE_11AC_VHT40) || \ + ((mode) == MODE_11AC_VHT80) || \ + ((mode) == MODE_11AC_VHT80_80) || \ + ((mode) == MODE_11AC_VHT160)) +#else +#define IS_MODE_VHT(mode) (((mode) == MODE_11AC_VHT20) || \ + ((mode) == MODE_11AC_VHT40) || \ + ((mode) == MODE_11AC_VHT80)) +#endif + +#define IS_MODE_VHT_2G(mode) (((mode) == MODE_11AC_VHT20_2G) || \ + ((mode) == MODE_11AC_VHT40_2G) || \ + ((mode) == MODE_11AC_VHT80_2G)) + + +#define IS_MODE_11A(mode) (((mode) == MODE_11A) || \ + ((mode) == MODE_11NA_HT20) || \ + ((mode) == MODE_11NA_HT40) || \ + (IS_MODE_VHT(mode))) + +#define IS_MODE_11B(mode) ((mode) == MODE_11B) +#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \ + ((mode) == MODE_11GONLY) || \ + ((mode) == MODE_11NG_HT20) || \ + ((mode) == MODE_11NG_HT40) || \ + (IS_MODE_VHT_2G(mode))) +#define IS_MODE_11GN(mode) (((mode) == MODE_11NG_HT20) || \ + ((mode) == MODE_11NG_HT40)) +#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY) + + +enum { + REGDMN_MODE_11A = 0x00000001, /* 11a channels */ + REGDMN_MODE_TURBO = 0x00000002, /* 11a turbo-only channels */ + REGDMN_MODE_11B = 0x00000004, /* 11b channels */ + REGDMN_MODE_PUREG = 0x00000008, /* 11g channels (OFDM only) */ + REGDMN_MODE_11G = 0x00000008, /* XXX historical */ + REGDMN_MODE_108G = 0x00000020, /* 11g+Turbo channels */ + REGDMN_MODE_108A = 0x00000040, /* 11a+Turbo channels */ + REGDMN_MODE_XR = 0x00000100, /* XR channels */ + REGDMN_MODE_11A_HALF_RATE = 0x00000200, /* 11A half rate channels */ + REGDMN_MODE_11A_QUARTER_RATE = 0x00000400, /* 11A quarter rate channels */ + REGDMN_MODE_11NG_HT20 = 0x00000800, /* 11N-G HT20 channels */ + REGDMN_MODE_11NA_HT20 = 0x00001000, /* 11N-A HT20 channels */ + REGDMN_MODE_11NG_HT40PLUS = 0x00002000, /* 11N-G HT40 + channels */ + REGDMN_MODE_11NG_HT40MINUS = 0x00004000, /* 11N-G HT40 - channels */ + REGDMN_MODE_11NA_HT40PLUS = 0x00008000, /* 11N-A HT40 + channels */ + REGDMN_MODE_11NA_HT40MINUS = 0x00010000, /* 11N-A HT40 - channels */ + REGDMN_MODE_11AC_VHT20 = 0x00020000, /* 5Ghz, VHT20 */ + REGDMN_MODE_11AC_VHT40PLUS = 0x00040000, /* 5Ghz, VHT40 + channels */ + REGDMN_MODE_11AC_VHT40MINUS = 0x00080000, /* 5Ghz VHT40 - channels */ + REGDMN_MODE_11AC_VHT80 = 0x000100000, /* 5Ghz, VHT80 channels */ + REGDMN_MODE_11AC_VHT20_2G = 0x000200000, /* 2Ghz, VHT20 */ + REGDMN_MODE_11AC_VHT40_2G = 0x000400000, /* 2Ghz, VHT40 */ + REGDMN_MODE_11AC_VHT80_2G = 0x000800000, /* 2Ghz, VHT80 */ + REGDMN_MODE_11AC_VHT160 = 0x001000000, /* 5Ghz, VHT160 */ +}; + +#define REGDMN_MODE_ALL (0xFFFFFFFF) /* REGDMN_MODE_ALL is defined out of the enum + * to prevent the ARM compile "warning #66: + * enumeration value is out of int range" + * Anyway, this is a BIT-OR of all possible values. + */ + +#define REGDMN_CAP1_CHAN_HALF_RATE 0x00000001 +#define REGDMN_CAP1_CHAN_QUARTER_RATE 0x00000002 +#define REGDMN_CAP1_CHAN_HAL49GHZ 0x00000004 + + +/* regulatory capabilities */ +#define REGDMN_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U2 0x0100 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMI_TLVTAG_STRUC_HAL_REG_CAPABILITIES */ + A_UINT32 eeprom_rd; //regdomain value specified in EEPROM + A_UINT32 eeprom_rd_ext; //regdomain + A_UINT32 regcap1; // CAP1 capabilities bit map. + A_UINT32 regcap2; // REGDMN EEPROM CAP. + A_UINT32 wireless_modes; // REGDMN MODE + A_UINT32 low_2ghz_chan; + A_UINT32 high_2ghz_chan; + A_UINT32 low_5ghz_chan; + A_UINT32 high_5ghz_chan; +} HAL_REG_CAPABILITIES; + +typedef enum { + WHAL_REG_EXT_FCC_MIDBAND = 0, + WHAL_REG_EXT_JAPAN_MIDBAND = 1, + WHAL_REG_EXT_FCC_DFS_HT40 = 2, + WHAL_REG_EXT_JAPAN_NONDFS_HT40 = 3, + WHAL_REG_EXT_JAPAN_DFS_HT40 = 4, + WHAL_REG_EXT_FCC_CH_144 = 5, +} WHAL_REG_EXT_BITMAP; + +/* + * Used to update rate-control logic with the status of the tx-completion. + * In host-based implementation of the rate-control feature, this struture is used to + * create the payload for HTT message/s from target to host. + */ + +typedef struct { + A_UINT8 rateCode; + A_UINT8 flags; +}RATE_CODE; + +typedef struct { + RATE_CODE ptx_rc; /* rate code, bw, chain mask sgi */ + A_UINT8 reserved[2]; + A_UINT32 flags; /* Encodes information such as excessive + retransmission, aggregate, some info + from .11 frame control, + STBC, LDPC, (SGI and Tx Chain Mask + are encoded in ptx_rc->flags field), + AMPDU truncation (BT/time based etc.), + RTS/CTS attempt */ + A_UINT32 num_enqued; /* # of MPDUs (for non-AMPDU 1) for this rate */ + A_UINT32 num_retries; /* Total # of transmission attempt for this rate */ + A_UINT32 num_failed; /* # of failed MPDUs in A-MPDU, 0 otherwise */ + A_UINT32 ack_rssi; /* ACK RSSI: b'7..b'0 avg RSSI across all chain */ + A_UINT32 time_stamp ; /* ACK timestamp (helps determine age) */ + A_UINT32 is_probe; /* Valid if probing. Else, 0 */ + A_UINT32 ba_win_size; /* b'7..b0, block Ack Window size, b'31..b8 Resvd */ + A_UINT32 failed_ba_bmap_0_31; /* failed BA bitmap 0..31 */ + A_UINT32 failed_ba_bmap_32_63; /* failed BA bitmap 32..63 */ + A_UINT32 bmap_tried_0_31; /* enqued bitmap 0..31 */ + A_UINT32 bmap_tried_32_63; /* enqued bitmap 32..63 */ +} RC_TX_DONE_PARAMS; + + +#define RC_SET_TX_DONE_INFO(_dst, _rc, _f, _nq, _nr, _nf, _rssi, _ts) \ + do { \ + (_dst).ptx_rc.rateCode = (_rc).rateCode; \ + (_dst).ptx_rc.flags = (_rc).flags; \ + (_dst).flags = (_f); \ + (_dst).num_enqued = (_nq); \ + (_dst).num_retries = (_nr); \ + (_dst).num_failed = (_nf); \ + (_dst).ack_rssi = (_rssi); \ + (_dst).time_stamp = (_ts); \ + } while (0) + +#define RC_SET_TXBF_DONE_INFO(_dst, _f) \ + do { \ + (_dst).flags |= (_f); \ + } while (0) + +/* NOTE: NUM_DYN_BW and NUM_SCHED_ENTRIES cannot be changed without breaking WMI Compatibility */ +#define NUM_SCHED_ENTRIES 2 +#define NUM_DYN_BW_MAX 4 + +/* Some products only use 20/40/80; some use 20/40/80/160 */ +#ifndef NUM_DYN_BW +#define NUM_DYN_BW 3 /* default: support up through 80 MHz */ +#endif + +#define NUM_DYN_BW_MASK 0x3 + +#define PROD_SCHED_BW_ENTRIES (NUM_SCHED_ENTRIES * NUM_DYN_BW) +typedef A_UINT8 A_RATE; + +#if NUM_DYN_BW > 4 +// Extend rate table module first +#error "Extend rate table module first" +#endif + +#define MAX_IBSS_PEERS 32 + +#if defined(CONFIG_AR900B_SUPPORT) || defined(AR900B) +typedef struct{ + A_UINT32 psdu_len [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT16 flags[NUM_SCHED_ENTRIES][NUM_DYN_BW]; + A_RATE rix[NUM_SCHED_ENTRIES][NUM_DYN_BW]; + A_UINT8 tpc[NUM_SCHED_ENTRIES][NUM_DYN_BW]; + A_UINT32 antmask[NUM_SCHED_ENTRIES]; + A_UINT8 num_mpdus [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT16 txbf_cv_len; + A_UINT32 txbf_cv_ptr; + A_UINT16 txbf_flags; + A_UINT16 txbf_cv_size; + A_UINT8 txbf_nc_idx; + A_UINT8 tries[NUM_SCHED_ENTRIES]; + A_UINT8 bw_mask[NUM_SCHED_ENTRIES]; + A_UINT8 max_bw[NUM_SCHED_ENTRIES]; + A_UINT8 num_sched_entries; + A_UINT8 paprd_mask; + A_UINT8 rts_rix; + A_UINT8 sh_pream; + A_UINT8 min_spacing_1_4_us; + A_UINT8 fixed_delims; + A_UINT8 bw_in_service; + A_RATE probe_rix; + A_UINT8 num_valid_rates; + A_UINT8 rtscts_tpc; +} RC_TX_RATE_SCHEDULE; + +#else +typedef struct{ + A_UINT32 psdu_len [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT16 flags [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_RATE rix [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT8 tpc [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT8 num_mpdus [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_UINT32 antmask [NUM_SCHED_ENTRIES]; + A_UINT32 txbf_cv_ptr; + A_UINT16 txbf_cv_len; + A_UINT8 tries [NUM_SCHED_ENTRIES]; + A_UINT8 num_valid_rates; + A_UINT8 paprd_mask; + A_UINT8 rts_rix; + A_UINT8 sh_pream; + A_UINT8 min_spacing_1_4_us; + A_UINT8 fixed_delims; + A_UINT8 bw_in_service; + A_RATE probe_rix; +} RC_TX_RATE_SCHEDULE; +#endif + +typedef struct{ + A_UINT16 flags [NUM_DYN_BW * NUM_SCHED_ENTRIES]; + A_RATE rix [NUM_DYN_BW * NUM_SCHED_ENTRIES]; +#ifdef DYN_TPC_ENABLE + A_UINT8 tpc [NUM_DYN_BW * NUM_SCHED_ENTRIES]; +#endif +#ifdef SECTORED_ANTENNA + A_UINT32 antmask [NUM_SCHED_ENTRIES]; +#endif + A_UINT8 tries [NUM_SCHED_ENTRIES]; + A_UINT8 num_valid_rates; + A_UINT8 rts_rix; + A_UINT8 sh_pream; + A_UINT8 bw_in_service; + A_RATE probe_rix; + A_UINT8 dd_profile; +} RC_TX_RATE_INFO; + +/* + * Temporarily continue to provide the WHAL_RC_INIT_RC_MASKS def in wlan_defs.h + * for older targets. + * The WHAL_RX_INIT_RC_MASKS macro def needs to be moved into ratectrl_11ac.h + * for all targets, but until this is complete, the WHAL_RC_INIT_RC_MASKS def + * will be maintained here in its old location. + */ +#if CONFIG_160MHZ_SUPPORT == 0 +#define WHAL_RC_INIT_RC_MASKS(_rm) do { \ + _rm[WHAL_RC_MASK_IDX_NON_HT] = A_RATEMASK_OFDM_CCK; \ + _rm[WHAL_RC_MASK_IDX_HT_20] = A_RATEMASK_HT_20; \ + _rm[WHAL_RC_MASK_IDX_HT_40] = A_RATEMASK_HT_40; \ + _rm[WHAL_RC_MASK_IDX_VHT_20] = A_RATEMASK_VHT_20; \ + _rm[WHAL_RC_MASK_IDX_VHT_40] = A_RATEMASK_VHT_40; \ + _rm[WHAL_RC_MASK_IDX_VHT_80] = A_RATEMASK_VHT_80; \ + } while (0) +#endif + +/** + * strucutre describing host memory chunk. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wlan_host_memory_chunk */ + /** id of the request that is passed up in service ready */ + A_UINT32 req_id; + /** the physical address the memory chunk */ + A_UINT32 ptr; + /** size of the chunk */ + A_UINT32 size; +} wlan_host_memory_chunk; + +#define NUM_UNITS_IS_NUM_VDEVS 0x1 +#define NUM_UNITS_IS_NUM_PEERS 0x2 + +/** + * structure used by FW for requesting host memory + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMI_TLVTAG_STRUC_wlan_host_mem_req */ + + /** ID of the request */ + A_UINT32 req_id; + /** size of the of each unit */ + A_UINT32 unit_size; + /** + * flags to indicate that + * the number units is dependent + * on number of resources(num vdevs num peers .. etc) + */ + A_UINT32 num_unit_info; + /* + * actual number of units to allocate . if flags in the num_unit_info + * indicate that number of units is tied to number of a particular + * resource to allocate then num_units filed is set to 0 and host + * will derive the number units from number of the resources it is + * requesting. + */ + A_UINT32 num_units; +} wlan_host_mem_req; + +typedef enum { + IGNORE_DTIM = 0x01, + NORMAL_DTIM = 0x02, + STICK_DTIM = 0x03, + AUTO_DTIM = 0x04, +} BEACON_DTIM_POLICY; + +/* During test it is observed that 6 * 400 = 2400 can + * be alloced in addition to CFG_TGT_NUM_MSDU_DESC. + * If there is any change memory requirement, this number + * needs to be revisited. */ +#define TOTAL_VOW_ALLOCABLE 2400 +#define VOW_DESC_GRAB_MAX 800 + +#define VOW_GET_NUM_VI_STA(vow_config) (((vow_config) & 0xffff0000) >> 16) +#define VOW_GET_DESC_PER_VI_STA(vow_config) ((vow_config) & 0x0000ffff) + +/***TODO!!! Get these values dynamically in WMI_READY event and use it to calculate the mem req*/ +/* size in bytes required for msdu descriptor. If it changes, this should be updated. LARGE_AP + * case is not considered. LARGE_AP is disabled when VoW is enabled.*/ +#define MSDU_DESC_SIZE 20 + +/* size in bytes required to support a peer in target. + * This obtained by considering Two tids per peer. + * peer structure = 168 bytes + * tid = 96 bytes (per sta 2 means we need 192 bytes) + * peer_cb = 16 * 2 + * key = 52 * 2 + * AST = 12 * 2 + * rate, reorder.. = 384 + * smart antenna = 50 + */ +#define MEMORY_REQ_FOR_PEER 800 +/* + * NB: it is important to keep all the fields in the structure dword long + * so that it is easy to handle the statistics in BE host. + */ + +struct wlan_dbg_tx_stats { + /* Num HTT cookies queued to dispatch list */ + A_INT32 comp_queued; + /* Num HTT cookies dispatched */ + A_INT32 comp_delivered; + /* Num MSDU queued to WAL */ + A_INT32 msdu_enqued; + /* Num MPDU queue to WAL */ + A_INT32 mpdu_enqued; + /* Num MSDUs dropped by WMM limit */ + A_INT32 wmm_drop; + /* Num Local frames queued */ + A_INT32 local_enqued; + /* Num Local frames done */ + A_INT32 local_freed; + /* Num queued to HW */ + A_INT32 hw_queued; + /* Num PPDU reaped from HW */ + A_INT32 hw_reaped; + /* Num underruns */ + A_INT32 underrun; +#if defined(AR900B) + /* HW Paused. */ + A_UINT32 hw_paused; +#endif + /* Num PPDUs cleaned up in TX abort */ + A_INT32 tx_abort; + /* Num MPDUs requed by SW */ + A_INT32 mpdus_requed; + /* excessive retries */ + A_UINT32 tx_ko; +#if defined(AR900B) + A_UINT32 tx_xretry; +#endif + /* data hw rate code */ + A_UINT32 data_rc; + /* Scheduler self triggers */ + A_UINT32 self_triggers; + /* frames dropped due to excessive sw retries */ + A_UINT32 sw_retry_failure; + /* illegal rate phy errors */ + A_UINT32 illgl_rate_phy_err; + /* wal pdev continous xretry */ + A_UINT32 pdev_cont_xretry; + /* wal pdev continous xretry */ + A_UINT32 pdev_tx_timeout; + /* wal pdev resets */ + A_UINT32 pdev_resets; + /* frames dropped due to non-availability of stateless TIDs */ + A_UINT32 stateless_tid_alloc_failure; + /* PhY/BB underrun */ + A_UINT32 phy_underrun; + /* MPDU is more than txop limit */ + A_UINT32 txop_ovf; +#if defined(AR900B) + /* Number of Sequences posted */ + A_UINT32 seq_posted; + /* Number of Sequences failed queueing */ + A_UINT32 seq_failed_queueing; + /* Number of Sequences completed */ + A_UINT32 seq_completed; + /* Number of Sequences restarted */ + A_UINT32 seq_restarted; + /* Number of MU Sequences posted */ + A_UINT32 mu_seq_posted; + /* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT (Reset,channel change) */ + A_INT32 mpdus_sw_flush; + /* Num MPDUs filtered by HW, all filter condition (TTL expired) */ + A_INT32 mpdus_hw_filter; + /* Num MPDUs truncated by PDG (TXOP, TBTT, PPDU_duration based on rate, dyn_bw) */ + A_INT32 mpdus_truncated; + /* Num MPDUs that was tried but didn't receive ACK or BA */ + A_INT32 mpdus_ack_failed; + /* Num MPDUs that was dropped du to expiry. */ + A_INT32 mpdus_expired; + /* Num mc drops */ + //A_UINT32 mc_drop; +#endif +}; + +struct wlan_dbg_rx_stats { + /* Cnts any change in ring routing mid-ppdu */ + A_INT32 mid_ppdu_route_change; + /* Total number of statuses processed */ + A_INT32 status_rcvd; + /* Extra frags on rings 0-3 */ + A_INT32 r0_frags; + A_INT32 r1_frags; + A_INT32 r2_frags; + A_INT32 r3_frags; + /* MSDUs / MPDUs delivered to HTT */ + A_INT32 htt_msdus; + A_INT32 htt_mpdus; + /* MSDUs / MPDUs delivered to local stack */ + A_INT32 loc_msdus; + A_INT32 loc_mpdus; + /* AMSDUs that have more MSDUs than the status ring size */ + A_INT32 oversize_amsdu; + /* Number of PHY errors */ + A_INT32 phy_errs; + /* Number of PHY errors drops */ + A_INT32 phy_err_drop; + /* Number of mpdu errors - FCS, MIC, ENC etc. */ + A_INT32 mpdu_errs; +#if defined(AR900B) + /* Number of rx overflow errors. */ + A_INT32 rx_ovfl_errs; +#endif +}; + + +struct wlan_dbg_mem_stats { + A_UINT32 iram_free_size; + A_UINT32 dram_free_size; +}; + +struct wlan_dbg_peer_stats { + + A_INT32 dummy; /* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */ +}; + +typedef struct { + A_UINT32 mcs[10]; + A_UINT32 sgi[10]; + A_UINT32 nss[4]; + A_UINT32 nsts; + A_UINT32 stbc[10]; + A_UINT32 bw[3]; + A_UINT32 pream[6]; + A_UINT32 ldpc; + A_UINT32 txbf; + A_UINT32 mgmt_rssi; + A_UINT32 data_rssi; + A_UINT32 rssi_chain0; + A_UINT32 rssi_chain1; + A_UINT32 rssi_chain2; +/* + * TEMPORARY: leave rssi_chain3 in place for AR900B builds until code using + * rssi_chain3 has been converted to use wlan_dbg_rx_rate_info_v2_t. + * At that time, this rssi_chain3 field will be deleted. + */ +#if defined(AR900B) + A_UINT32 rssi_chain3; +#endif +} wlan_dbg_rx_rate_info_t ; + +typedef struct { + A_UINT32 mcs[10]; + A_UINT32 sgi[10]; +/* + * TEMPORARY: leave nss conditionally defined, until all code that + * requires nss[4] is converted to use wlan_dbg_tx_rate_info_v2_t. + * At that time, this nss array will be made length = 3 unconditionally. + */ +#if defined(CONFIG_AR900B_SUPPORT) || defined(AR900B) + A_UINT32 nss[4]; +#else + A_UINT32 nss[3]; +#endif + A_UINT32 stbc[10]; + A_UINT32 bw[3]; + A_UINT32 pream[4]; + A_UINT32 ldpc; + A_UINT32 rts_cnt; + A_UINT32 ack_rssi; +} wlan_dbg_tx_rate_info_t ; + +#define WLAN_MAX_MCS 10 + +typedef struct { + A_UINT32 mcs[WLAN_MAX_MCS]; + A_UINT32 sgi[WLAN_MAX_MCS]; + A_UINT32 nss[MAX_SPATIAL_STREAM_ANY]; + A_UINT32 nsts; + A_UINT32 stbc[WLAN_MAX_MCS]; + A_UINT32 bw[NUM_DYN_BW_MAX]; + A_UINT32 pream[6]; + A_UINT32 ldpc; + A_UINT32 txbf; + A_UINT32 mgmt_rssi; + A_UINT32 data_rssi; + A_UINT32 rssi_chain0; + A_UINT32 rssi_chain1; + A_UINT32 rssi_chain2; + A_UINT32 rssi_chain3; + A_UINT32 reserved[8]; +} wlan_dbg_rx_rate_info_v2_t ; + +typedef struct { + A_UINT32 mcs[WLAN_MAX_MCS]; + A_UINT32 sgi[WLAN_MAX_MCS]; + A_UINT32 nss[MAX_SPATIAL_STREAM_ANY]; + A_UINT32 stbc[WLAN_MAX_MCS]; + A_UINT32 bw[NUM_DYN_BW_MAX]; + A_UINT32 pream[4]; + A_UINT32 ldpc; + A_UINT32 rts_cnt; + A_UINT32 ack_rssi; + A_UINT32 reserved[8]; +} wlan_dbg_tx_rate_info_v2_t ; + +#define WHAL_DBG_PHY_ERR_MAXCNT 18 +#define WHAL_DBG_SIFS_STATUS_MAXCNT 8 +#define WHAL_DBG_SIFS_ERR_MAXCNT 8 +#define WHAL_DBG_CMD_RESULT_MAXCNT 10 +#define WHAL_DBG_CMD_STALL_ERR_MAXCNT 4 +#define WHAL_DBG_FLUSH_REASON_MAXCNT 40 + +typedef enum { + WIFI_URRN_STATS_FIRST_PKT, + WIFI_URRN_STATS_BETWEEN_MPDU, + WIFI_URRN_STATS_WITHIN_MPDU, + WHAL_MAX_URRN_STATS +} wifi_urrn_type_t; + +typedef struct wlan_dbg_txbf_snd_stats { + A_UINT32 cbf_20[4]; + A_UINT32 cbf_40[4]; + A_UINT32 cbf_80[4]; + A_UINT32 sounding[9]; +}wlan_dbg_txbf_snd_stats_t; + +typedef struct wlan_dbg_wifi2_error_stats { + A_UINT32 urrn_stats[WHAL_MAX_URRN_STATS]; + A_UINT32 flush_errs[WHAL_DBG_FLUSH_REASON_MAXCNT]; + A_UINT32 schd_stall_errs[WHAL_DBG_CMD_STALL_ERR_MAXCNT]; + A_UINT32 schd_cmd_result[WHAL_DBG_CMD_RESULT_MAXCNT]; + A_UINT32 sifs_status[WHAL_DBG_SIFS_STATUS_MAXCNT]; + A_UINT8 phy_errs[WHAL_DBG_PHY_ERR_MAXCNT]; + A_UINT32 rx_rate_inval; +}wlan_dbg_wifi2_error_stats_t; + +typedef struct wlan_dbg_wifi2_error2_stats { + A_UINT32 schd_errs[WHAL_DBG_CMD_STALL_ERR_MAXCNT]; + A_UINT32 sifs_errs[WHAL_DBG_SIFS_ERR_MAXCNT]; +}wlan_dbg_wifi2_error2_stats_t; + +#define WLAN_DBG_STATS_SIZE_TXBF_VHT 10 +#define WLAN_DBG_STATS_SIZE_TXBF_HT 8 +#define WLAN_DBG_STATS_SIZE_TXBF_OFDM 8 +#define WLAN_DBG_STATS_SIZE_TXBF_CCK 7 + +typedef struct wlan_dbg_txbf_data_stats { + A_UINT32 tx_txbf_vht[WLAN_DBG_STATS_SIZE_TXBF_VHT]; + A_UINT32 rx_txbf_vht[WLAN_DBG_STATS_SIZE_TXBF_VHT]; + A_UINT32 tx_txbf_ht[WLAN_DBG_STATS_SIZE_TXBF_HT]; + A_UINT32 tx_txbf_ofdm[WLAN_DBG_STATS_SIZE_TXBF_OFDM]; + A_UINT32 tx_txbf_cck[WLAN_DBG_STATS_SIZE_TXBF_CCK]; +} wlan_dbg_txbf_data_stats_t; + +struct wlan_dbg_tx_mu_stats { + A_UINT32 mu_sch_nusers_2; + A_UINT32 mu_sch_nusers_3; + A_UINT32 mu_mpdus_queued_usr[4]; + A_UINT32 mu_mpdus_tried_usr[4]; + A_UINT32 mu_mpdus_failed_usr[4]; + A_UINT32 mu_mpdus_requeued_usr[4]; + A_UINT32 mu_err_no_ba_usr[4]; + A_UINT32 mu_mpdu_underrun_usr[4]; + A_UINT32 mu_ampdu_underrun_usr[4]; +}; + +struct wlan_dbg_tx_selfgen_stats { + A_UINT32 su_ndpa; + A_UINT32 su_ndp; + A_UINT32 mu_ndpa; + A_UINT32 mu_ndp; + A_UINT32 mu_brpoll_1; + A_UINT32 mu_brpoll_2; + A_UINT32 mu_bar_1; + A_UINT32 mu_bar_2; + A_UINT32 cts_burst; + A_UINT32 su_ndp_err; + A_UINT32 mu_ndp_err; + A_UINT32 mu_brp1_err; + A_UINT32 mu_brp2_err; +}; + +typedef struct wlan_dbg_sifs_resp_stats { + A_UINT32 ps_poll_trigger; /* num ps-poll trigger frames */ + A_UINT32 uapsd_trigger; /* num uapsd trigger frames */ + A_UINT32 qb_data_trigger[2]; /* num data trigger frames; idx 0: explicit and idx 1: implicit */ + A_UINT32 qb_bar_trigger[2]; /* num bar trigger frames; idx 0: explicit and idx 1: implicit */ + A_UINT32 sifs_resp_data; /* num ppdus transmitted at SIFS interval */ + A_UINT32 sifs_resp_err; /* num ppdus failed to meet SIFS resp timing */ +} wlan_dgb_sifs_resp_stats_t; + + + +/** wlan_dbg_wifi2_error_stats_t is not grouped with the + * following structure as it is allocated differently and only + * belongs to whal + */ +typedef struct wlan_dbg_stats_wifi2 { + wlan_dbg_txbf_snd_stats_t txbf_snd_info; + wlan_dbg_txbf_data_stats_t txbf_data_info; + struct wlan_dbg_tx_selfgen_stats tx_selfgen; + struct wlan_dbg_tx_mu_stats tx_mu; + wlan_dgb_sifs_resp_stats_t sifs_resp_info; +} wlan_dbg_wifi2_stats_t; + +typedef struct { + wlan_dbg_rx_rate_info_t rx_phy_info; + wlan_dbg_tx_rate_info_t tx_rate_info; +} wlan_dbg_rate_info_t; + +typedef struct { + wlan_dbg_rx_rate_info_v2_t rx_phy_info; + wlan_dbg_tx_rate_info_v2_t tx_rate_info; +} wlan_dbg_rate_info_v2_t; + +struct wlan_dbg_stats { + struct wlan_dbg_tx_stats tx; + struct wlan_dbg_rx_stats rx; +#if defined(AR900B) + struct wlan_dbg_mem_stats mem; +#endif + struct wlan_dbg_peer_stats peer; +}; + +#define DBG_STATS_MAX_HWQ_NUM 10 +#define DBG_STATS_MAX_TID_NUM 20 +#define DBG_STATS_MAX_CONG_NUM 16 +struct wlan_dbg_txq_stats { + A_UINT16 num_pkts_queued[DBG_STATS_MAX_HWQ_NUM]; + A_UINT16 tid_hw_qdepth[DBG_STATS_MAX_TID_NUM];//WAL_MAX_TID is 20 + A_UINT16 tid_sw_qdepth[DBG_STATS_MAX_TID_NUM];//WAL_MAX_TID is 20 +}; + +struct wlan_dbg_tidq_stats{ + A_UINT32 wlan_dbg_tid_txq_status; + struct wlan_dbg_txq_stats txq_st; +}; + +#endif /* __WLANDEFS_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_module_ids.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_module_ids.h new file mode 100644 index 0000000000000..8596a8c8afc32 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_module_ids.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _WLAN_MODULE_IDS_H_ +#define _WLAN_MODULE_IDS_H_ + +/* Wlan module ids , global across all the modules */ +typedef enum { + WLAN_MODULE_ID_MIN = 0, + WLAN_MODULE_INF = WLAN_MODULE_ID_MIN, + WLAN_MODULE_WMI, + WLAN_MODULE_STA_PWRSAVE, + WLAN_MODULE_WHAL, + WLAN_MODULE_COEX, + WLAN_MODULE_ROAM, + WLAN_MODULE_RESMGR_CHAN_MANAGER, + WLAN_MODULE_RESMGR, + WLAN_MODULE_VDEV_MGR, + WLAN_MODULE_SCAN, + WLAN_MODULE_RATECTRL, + WLAN_MODULE_AP_PWRSAVE, + WLAN_MODULE_BLOCKACK, + WLAN_MODULE_MGMT_TXRX, + WLAN_MODULE_DATA_TXRX, + WLAN_MODULE_HTT, + WLAN_MODULE_HOST, + WLAN_MODULE_BEACON, + WLAN_MODULE_OFFLOAD, + WLAN_MODULE_WAL, + WAL_MODULE_DE, + WLAN_MODULE_PCIELP, + WLAN_MODULE_RTT, + WLAN_MODULE_RESOURCE, + WLAN_MODULE_DCS, + WLAN_MODULE_CACHEMGR, + WLAN_MODULE_ANI, + WLAN_MODULE_P2P, + WLAN_MODULE_CSA, + WLAN_MODULE_NLO, + WLAN_MODULE_CHATTER, + WLAN_MODULE_WOW, + WLAN_MODULE_WAL_VDEV, + WLAN_MODULE_WAL_PDEV, + WLAN_MODULE_TEST, + WLAN_MODULE_STA_SMPS, + WLAN_MODULE_SWBMISS, + WLAN_MODULE_WMMAC, + WLAN_MODULE_TDLS, + WLAN_MODULE_HB, + WLAN_MODULE_TXBF, + WLAN_MODULE_BATCH_SCAN, + WLAN_MODULE_THERMAL_MGR, + WLAN_MODULE_PHYERR_DFS, + WLAN_MODULE_RMC, + WLAN_MODULE_STATS, + WLAN_MODULE_NAN, + WLAN_MODULE_IBSS_PWRSAVE, + WLAN_MODULE_HIF_UART, + WLAN_MODULE_LPI, + WLAN_MODULE_EXTSCAN, + WLAN_MODULE_UNIT_TEST, + WLAN_MODULE_MLME, + WLAN_MODULE_SUPPL, + WLAN_MODULE_ERE, + WLAN_MODULE_OCB, + WLAN_MODULE_ID_MAX, + WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX, +} WLAN_MODULE_ID; + + +#endif /* _WLAN_MODULE_IDS_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_opts.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_opts.h new file mode 100644 index 0000000000000..4fed4cdb7d670 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_opts.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_OPTS_H_ +#define _WLAN_OPTS_H_ + +/* ATH_DEBUG - + * Control whether debug features (printouts, assertions) are compiled + * into the driver. + */ +#ifndef ATH_DEBUG +#define ATH_DEBUG 1 /* default: include debug code */ +#endif + +#if ATH_DEBUG +#define DEBUG_VAR_DECL_INIT(_var,_type,_value) _type (_var)=_value +#else +#define DEBUG_VAR_DECL_INIT(_var,_type,_value) +#endif + +/* ATH_SUPPORT_WIRESHARK - + * Control whether code that adds a radiotap packet header for consumption + * by wireshark are compiled into the driver. + */ +#ifndef ATH_SUPPORT_WIRESHARK +#define ATH_SUPPORT_WIRESHARK 1 /* default: include radiotap/wireshark code */ +#endif + +#ifndef ATH_SUPPORT_ATHVAP_INFO +#define ATH_SUPPORT_ATHVAP_INFO 1 +#endif + +/* ATH_SUPPORT_IBSS - + * Control whether Adhoc support is compiled into the driver. + */ +#ifndef ATH_SUPPORT_IBSS +#define ATH_SUPPORT_IBSS 1 /* default: include radiotap/wireshark code */ +#endif + +/* ATH_SLOW_ANT_DIV - + * Control whether Slow Antenna Diversity support is compiled into the driver. + */ +#ifndef ATH_SLOW_ANT_DIV +#define ATH_SLOW_ANT_DIV 0 /* default: do not include Slow Antenna Diversity code */ +#endif + +#ifndef ATH_SUPPORT_CWM +#define ATH_SUPPORT_CWM 1 /* on unless explicitly disabled */ +#endif + +#ifndef ATH_SUPPORT_MULTIPLE_SCANS +#define ATH_SUPPORT_MULTIPLE_SCANS 0 /* default: do not include suport for multiple simultaneous scans, including Scan Scheduler code */ +#endif + +#ifndef ATH_BUILD_VISTA_ONLY +#define ATH_BUILD_VISTA_ONLY 0 /* default: build VISTA and WIN7 as the same binary */ +#endif + +#ifndef IEEE80211_DEBUG_REFCNT_SE +#define IEEE80211_DEBUG_REFCNT_SE 0 /*default: do not include scan_entry reference count debug info */ +#endif + +#ifndef ATH_OSPREY_UAPSDDEFERRED +#define ATH_OSPREY_UAPSDDEFERRED 0 /* default: handle Osprey UAPSD in ISR */ +#endif + +#ifndef ATH_SUPPORT_STATS_APONLY +#define ATH_SUPPORT_STATS_APONLY 0 /*default: update all stats*/ +#endif + +#ifndef ATH_RESET_SERIAL +#define ATH_RESET_SERIAL 0 /*default: do not run ath_reset always in passive_level */ +#endif + +#ifndef ATH_LOW_PRIORITY_CALIBRATE +#define ATH_LOW_PRIORITY_CALIBRATE 0 /*default: do not run ath_calibrate in workitem. */ +#endif + +#endif /* _WLAN_OPTS_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config.h new file mode 100644 index 0000000000000..04ecf436d09ee --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_TGT_DEF_CONFIG_H__ +#define __WLAN_TGT_DEF_CONFIG_H__ + +/* + * set of default target config , that can be over written by platform + */ + +/* + * default limit of 8 VAPs per device. + */ +/* Rome PRD support 3 vdevs */ +#define CFG_TGT_NUM_VDEV 3 + +/* + * We would need 1 AST entry per peer. Scale it by a factor of 2 to minimize hash collisions. + * TODO: This scaling factor would be taken care inside the WAL in the future. + */ +#define CFG_TGT_NUM_PEER_AST 2 + +/* # of WDS entries to support. + */ +#define CFG_TGT_WDS_ENTRIES 32 + +/* MAC DMA burst size. 0: 128B - default, 1: 256B, 2: 64B + */ +#define CFG_TGT_DEFAULT_DMA_BURST_SIZE 0 + +/* Fixed delimiters to be inserted after every MPDU + */ +#define CFG_TGT_DEFAULT_MAC_AGGR_DELIM 0 + +/* + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_AST_SKID_LIMIT 16 + +/* + * total number of peers per device. + */ +#define CFG_TGT_NUM_PEERS 14 + +/* + * In offload mode target supports features like WOW, chatter and other + * protocol offloads. In order to support them some functionalities like + * reorder buffering, PN checking need to be done in target. This determines + * maximum number of peers suported by target in offload mode + */ + +/* + * The current firmware implementation requires the number of offload peers + * should be (number of vdevs + 1). + + * The reason for this is the firmware clubbed the self peer and offload peer + * in the same pool. So if the firmware wanted to support n vdevs then the + * number of offload peer must be n+1 of which n buffers will be used for + * self peer and the remaining 1 is used for offload peer to support chatter + * mode for single STA. + + * Technically the macro should be 1 however the current firmware requires n+1. + + * TODO: This MACRO need to be modified in the future, if the firmware modified + * to allocate buffers for self peer and offload peer independently. + */ + +#define CFG_TGT_NUM_OFFLOAD_PEERS (CFG_TGT_NUM_VDEV+1) + +/* + * Number of reorder buffers used in offload mode + */ +#define CFG_TGT_NUM_OFFLOAD_REORDER_BUFFS 4 + +/* + * keys per peer node + */ +#define CFG_TGT_NUM_PEER_KEYS 2 +/* + * total number of data TX and RX TIDs + */ +#define CFG_TGT_NUM_TIDS (2 * (CFG_TGT_NUM_PEERS + CFG_TGT_NUM_VDEV + 2)) +/* + * set this to 0x7 (Peregrine = 3 chains). + * need to be set dynamically based on the HW capability. + */ +#define CFG_TGT_DEFAULT_TX_CHAIN_MASK 0x7 +/* + * set this to 0x7 (Peregrine = 3 chains). + * need to be set dynamically based on the HW capability. + */ +#define CFG_TGT_DEFAULT_RX_CHAIN_MASK 0x7 +/* 100 ms for video, best-effort, and background */ +#define CFG_TGT_RX_TIMEOUT_LO_PRI 100 +/* 40 ms for voice*/ +#define CFG_TGT_RX_TIMEOUT_HI_PRI 40 + +/* AR9888 unified is default in ethernet mode */ +#define CFG_TGT_RX_DECAP_MODE (0x2) +/* Decap to native Wifi header */ +#define CFG_TGT_RX_DECAP_MODE_NWIFI (0x1) + +/* maximum number of pending scan requests */ +#define CFG_TGT_DEFAULT_SCAN_MAX_REQS 0x4 + +/* maximum number of VDEV that could use BMISS offload */ +#define CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV 0x2 + +/* maximum number of VDEV offload Roaming to support */ +#define CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV 0x2 + +/* maximum number of AP profiles pushed to offload Roaming */ +#define CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES 0x8 + +/* maximum number of VDEV offload GTK to support */ +#define CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV 0x2 + +/* default: mcast->ucast disabled if ATH_SUPPORT_MCAST2UCAST not defined */ +#ifndef ATH_SUPPORT_MCAST2UCAST +#define CFG_TGT_DEFAULT_NUM_MCAST_GROUPS 0 +#define CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS 0 +#define CFG_TGT_DEFAULT_MCAST2UCAST_MODE 0 /* disabled */ +#else +/* (for testing) small multicast group membership table enabled */ +#define CFG_TGT_DEFAULT_NUM_MCAST_GROUPS 4 +#define CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS 16 +#define CFG_TGT_DEFAULT_MCAST2UCAST_MODE 2 +#endif + +#define CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES 5 +/* + * Specify how much memory the target should allocate for a debug log of + * tx PPDU meta-information (how large the PPDU was, when it was sent, + * whether it was successful, etc.) + * The size of the log records is configurable, from a minimum of 28 bytes + * to a maximum of about 300 bytes. A typical configuration would result + * in each log record being about 124 bytes. + * Thus, 1KB of log space can hold about 30 small records, 3 large records, + * or about 8 typical-sized records. + */ +#define CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE 1024 /* bytes */ + +/* target based fragment timeout and MPDU duplicate detection */ +#define CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 0 + +/* Default VoW configuration + */ +#define CFG_TGT_DEFAULT_VOW_CONFIG 0 + +/* + * total number of descriptors to use in the target + */ +#define CFG_TGT_NUM_MSDU_DESC (1024 + 32) + +/* + * Maximum number of frag table entries + */ +#define CFG_TGT_MAX_FRAG_TABLE_ENTRIES 10 + +/* + * Maximum number of VDEV that beacon tx offload will support + */ +#define CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV 2 + +/* + * number of vdevs that can support tdls + */ +#define CFG_TGT_NUM_TDLS_VDEVS 1 + +/* + * number of peers that each Tdls vdev can track + */ +#define CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES 32 + +/* + * number of TDLS concurrent sleep STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS 1 + +/* + * number of TDLS concurrent buffer STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS 1 + +/* + * ht enable highest MCS by default + */ +#define CFG_TGT_DEFAULT_GTX_HT_MASK 0x8080 +/* + * vht enable highest MCS by default + */ +#define CFG_TGT_DEFAULT_GTX_VHT_MASK 0x80200 +/* + * resv for furture use, bit 30 is used for fix tpc, bit0-3 for Power save balance + */ +#define CFG_TGT_DEFAULT_GTX_USR_CFG 0xa +/* + * threshold to enable GTX + */ +#define CFG_TGT_DEFAULT_GTX_PER_THRESHOLD 3 +/* + * margin to move back when per > margin + threshold + */ +#define CFG_TGT_DEFAULT_GTX_PER_MARGIN 2 +/* + * step for every move + */ +#define CFG_TGT_DEFAULT_GTX_TPC_STEP 1 +/* + * lowest TPC + */ +#define CFG_TGT_DEFAULT_GTX_TPC_MIN 0 +/* + * enable all BW 20/40/80/160 + */ +#define CFG_TGT_DEFAULT_GTX_BW_MASK 0xf + +#endif /*__WLAN_TGT_DEF_CONFIG_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h new file mode 100644 index 0000000000000..c9757bc3ea0bb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef __WLAN_TGT_DEF_CONFIG_H__ +#define __WLAN_TGT_DEF_CONFIG_H__ + +/* + * TODO: please help to consider if we need a seperate config file from LL case. + */ + +/* + * set of default target config , that can be over written by platform + */ + +#ifdef QCA_SUPPORT_INTEGRATED_SOC +#define CFG_TGT_NUM_VDEV 3 /*STA, P2P device, P2P GO/Cli*/ +#else +/* + * default limit of VAPs per device. + */ +#define CFG_TGT_NUM_VDEV 3 +#endif +/* + * We would need 1 AST entry per peer. Scale it by a factor of 2 to minimize + * hash collisions. + * TODO: This scaling factor would be taken care inside the WAL in the future. + */ +#define CFG_TGT_NUM_PEER_AST 2 + +/* # of WDS entries to support. + */ +#define CFG_TGT_WDS_ENTRIES 2 + +/* MAC DMA burst size. 0: 128B - default, 1: 256B, 2: 64B + */ +#define CFG_TGT_DEFAULT_DMA_BURST_SIZE 0 + +/* Fixed delimiters to be inserted after every MPDU + */ +#define CFG_TGT_DEFAULT_MAC_AGGR_DELIM 0 + +/* + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_AST_SKID_LIMIT 6 +/* + * total number of peers per device. + * currently set to 8 to bring up IP3.9 for memory size problem + */ +#define CFG_TGT_NUM_PEERS 8 +/* + * max number of peers per device. + */ +#define CFG_TGT_NUM_PEERS_MAX 8 +/* + * In offload mode target supports features like WOW, chatter and other + * protocol offloads. In order to support them some functionalities like + * reorder buffering, PN checking need to be done in target. This determines + * maximum number of peers suported by target in offload mode + */ +#define CFG_TGT_NUM_OFFLOAD_PEERS 0 +/* + * Number of reorder buffers used in offload mode + */ +#define CFG_TGT_NUM_OFFLOAD_REORDER_BUFFS 0 +/* + * keys per peer node + */ +#define CFG_TGT_NUM_PEER_KEYS 2 +/* + * total number of TX/RX data TIDs + */ +#define CFG_TGT_NUM_TIDS (2 * (CFG_TGT_NUM_PEERS + CFG_TGT_NUM_VDEV)) +/* + * max number of Tx TIDS + */ +#define CFG_TGT_NUM_TIDS_MAX (2 * (CFG_TGT_NUM_PEERS_MAX + CFG_TGT_NUM_VDEV)) +/* + * number of multicast keys. + */ +#define CFG_TGT_NUM_MCAST_KEYS 8 +/* + * A value of 3 would probably suffice - one for the control stack, one for + * the data stack, and one for debugging. + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_NUM_PDEV_HANDLERS 8 +/* + * A value of 3 would probably suffice - one for the control stack, one for + * the data stack, and one for debugging. + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_NUM_VDEV_HANDLERS 4 +/* + * set this to 8: + * one for WAL interals (connection pause) + * one for the control stack, + * one for the data stack + * and one for debugging + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_NUM_HANDLERS 14 +/* + * set this to 3: one for the control stack, one for + * the data stack, and one for debugging. + * This value may need to be fine tuned, but a constant value will + * probably always be appropriate; it is probably not necessary to + * determine this value dynamically. + */ +#define CFG_TGT_NUM_PEER_HANDLERS 32 +/* + * set this to 0x7 (Peregrine = 3 chains). + * need to be set dynamically based on the HW capability. + * this is rome + */ +#define CFG_TGT_DEFAULT_TX_CHAIN_MASK 0x3 +/* + * set this to 0x7 (Peregrine = 3 chains). + * need to be set dynamically based on the HW capability. + * this is rome + */ +#define CFG_TGT_DEFAULT_RX_CHAIN_MASK 0x3 +/* 100 ms for video, best-effort, and background */ +#define CFG_TGT_RX_TIMEOUT_LO_PRI 100 +/* 40 ms for voice*/ +#define CFG_TGT_RX_TIMEOUT_HI_PRI 40 + +/* AR9888 unified is default in ethernet mode */ +#define CFG_TGT_RX_DECAP_MODE (0x2) +/* Decap to native Wifi header */ +#define CFG_TGT_RX_DECAP_MODE_NWIFI (0x1) + +/* maximum number of pending scan requests */ +#define CFG_TGT_DEFAULT_SCAN_MAX_REQS 0x4 + +/* maximum number of scan event handlers */ +#define CFG_TGT_DEFAULT_SCAN_MAX_HANDLERS 0x4 + +/* maximum number of VDEV that could use BMISS offload */ +#define CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV 0x2 + +/* maximum number of VDEV offload Roaming to support */ +#define CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV 0x2 + +/* maximum number of AP profiles pushed to offload Roaming */ +#define CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES 0x8 + +/* maximum number of VDEV offload GTK to support */ +#define CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV 0x2 +/* default: mcast->ucast disabled */ +#if 1 +#define CFG_TGT_DEFAULT_NUM_MCAST_GROUPS 0 +#define CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS 0 +#define CFG_TGT_DEFAULT_MCAST2UCAST_MODE 0 /* disabled */ +#else +/* (for testing) small multicast group membership table enabled */ +#define CFG_TGT_DEFAULT_NUM_MCAST_GROUPS 4 +#define CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS 16 +#define CFG_TGT_DEFAULT_MCAST2UCAST_MODE 1 +#endif + +/* + * Specify how much memory the target should allocate for a debug log of + * tx PPDU meta-information (how large the PPDU was, when it was sent, + * whether it was successful, etc.) + * The size of the log records is configurable, from a minimum of 28 bytes + * to a maximum of about 300 bytes. A typical configuration would result + * in each log record being about 124 bytes. + * Thus, 1KB of log space can hold about 30 small records, 3 large records, + * or about 8 typical-sized records. + */ +#define CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE 1024 /* bytes */ + +/* target based fragment timeout and MPDU duplicate detection */ +#define CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 0 +/* Default VoW configuration + */ +#define CFG_TGT_DEFAULT_VOW_CONFIG 0 + +/* + * total number of descriptors to use in the target + */ +#ifndef HIF_SDIO +#define CFG_TGT_NUM_MSDU_DESC (32) +#else +#define CFG_TGT_NUM_MSDU_DESC (16) +#endif +/* + * Maximum number of frag table entries + */ +#define CFG_TGT_MAX_FRAG_TABLE_ENTRIES 2 + +/* + * number of vdevs that can support tdls + */ +#define CFG_TGT_NUM_TDLS_VDEVS 1 + +/* + * number of peers that each Tdls vdev can track + */ +#define CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES 32 +/* + * number of TDLS concurrent sleep STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS 1 + +/* + * number of TDLS concurrent buffer STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS 1 + +#define CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES 5 +/* + * Maximum number of VDEV that beacon tx offload will support + */ +#define CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV 1 + +/* + * ht enable highest MCS by default + */ +#define CFG_TGT_DEFAULT_GTX_HT_MASK 0x8080 +/* + * vht enable highest MCS by default + */ +#define CFG_TGT_DEFAULT_GTX_VHT_MASK 0x80200 +/* + * resv for furture use, bit 30 is used for fix tpc, bit0-3 for Power save + * balance + */ +#define CFG_TGT_DEFAULT_GTX_USR_CFG 0xa +/* + * threshold to enable GTX + */ +#define CFG_TGT_DEFAULT_GTX_PER_THRESHOLD 3 +/* + * margin to move back when per > margin + threshold + */ +#define CFG_TGT_DEFAULT_GTX_PER_MARGIN 2 +/* + * step for every move + */ +#define CFG_TGT_DEFAULT_GTX_TPC_STEP 1 +/* + * lowest TPC + */ +#define CFG_TGT_DEFAULT_GTX_TPC_MIN 0 +/* + * enable all BW 20/40/80/160 + */ +#define CFG_TGT_DEFAULT_GTX_BW_MASK 0xf + +#endif /*__WLAN_TGT_DEF_CONFIG_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_api.h new file mode 100644 index 0000000000000..ea84460cc083b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_api.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wma.c + \brief Implementation of WMA + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- ----------------------------------------- + 12/03/2013 Ganesh Implementation of wma function for initialization + Kondabattini + ==========================================================================*/ +#ifndef WMA_API_H +#define WMA_API_H + +#include "osdep.h" +#include "vos_mq.h" +#include "aniGlobal.h" +#include "a_types.h" +#include "wmi_unified.h" +#include "wlan_hdd_tgt_cfg.h" +#ifdef NOT_YET +#include "htc_api.h" +#endif +#include "limGlobal.h" + +typedef v_VOID_t* WMA_HANDLE; + +typedef enum { + /* Set ampdu size */ + GEN_VDEV_PARAM_AMPDU = 0x1, + /* Set amsdu size */ + GEN_VDEV_PARAM_AMSDU, + GEN_PARAM_DUMP_AGC_START, + GEN_PARAM_DUMP_AGC, + GEN_PARAM_DUMP_CHANINFO_START, + GEN_PARAM_DUMP_CHANINFO, + GEN_PARAM_DUMP_WATCHDOG, + GEN_PARAM_CRASH_INJECT, +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + GEN_PARAM_DUMP_PCIE_ACCESS_LOG +#endif +} GEN_PARAM; + +#define VDEV_CMD 1 +#define PDEV_CMD 2 +#define GEN_CMD 3 +#define DBG_CMD 4 +#define PPS_CMD 5 +#define QPOWER_CMD 6 +#define GTX_CMD 7 + +VOS_STATUS wma_pre_start(v_VOID_t *vos_context); + +VOS_STATUS wma_mc_process_msg( v_VOID_t *vos_context, vos_msg_t *msg ); + +VOS_STATUS wma_start(v_VOID_t *vos_context); + +VOS_STATUS wma_stop(v_VOID_t *vos_context, tANI_U8 reason); + +VOS_STATUS wma_close(v_VOID_t *vos_context); + +VOS_STATUS wma_wmi_service_close(v_VOID_t *vos_context); + +v_VOID_t wma_rx_ready_event(WMA_HANDLE handle, v_VOID_t *ev); + +v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, + v_VOID_t *ev); + +v_VOID_t wma_setneedshutdown(v_VOID_t *vos_context); + +v_BOOL_t wma_needshutdown(v_VOID_t *vos_context); + +VOS_STATUS wma_wait_for_ready_event(WMA_HANDLE handle); + +tANI_U8 wma_map_channel(tANI_U8 mapChannel); + +int wma_cli_get_command(void *wmapvosContext, int vdev_id, + int param_id, int vpdev); +eHalStatus wma_set_htconfig(tANI_U8 vdev_id, tANI_U16 ht_capab, int value); +eHalStatus WMA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + tAniBool sendRegHint); + +VOS_STATUS WMA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx, tANI_U8 *pVersion, + tANI_U32 versionBufferSize); +int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr); +void wma_target_suspend_acknowledge(void *context); +int wma_resume_target(WMA_HANDLE handle); +int wma_disable_wow_in_fw(WMA_HANDLE handle); +int wma_is_wow_mode_selected(WMA_HANDLE handle); +int wma_enable_wow_in_fw(WMA_HANDLE handle); +bool wma_check_scan_in_progress(WMA_HANDLE handle); +#ifdef FEATURE_WLAN_D0WOW +int wma_get_client_count(WMA_HANDLE handle); +#endif +int wma_set_peer_param(void *wma_ctx, u_int8_t *peer_addr, u_int32_t param_id, + u_int32_t param_value, u_int32_t vdev_id); +#ifdef NOT_YET +VOS_STATUS wma_update_channel_list(WMA_HANDLE handle, void *scan_chan_info); +#endif + +u_int8_t *wma_get_vdev_address_by_vdev_id(u_int8_t vdev_id); + +void *wma_get_beacon_buffer_by_vdev_id(u_int8_t vdev_id, + u_int32_t *buffer_size); + +int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev); +tANI_U8 wma_getFwWlanFeatCaps(tANI_U8 featEnumValue); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_dfs_interface.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_dfs_interface.h new file mode 100644 index 0000000000000..b6e4fd296617d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wma_dfs_interface.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "ath_dfs_structs.h" +#include "_ieee80211_common.h" + +#define IEEE80211_CHAN_MAX 255 + +/* channel attributes */ + +/* Turbo channel */ +#define IEEE80211_CHAN_TURBO 0x00000010 +/* CCK channel */ +#define IEEE80211_CHAN_CCK 0x00000020 +/* OFDM channel */ +#define IEEE80211_CHAN_OFDM 0x00000040 +/* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_2GHZ 0x00000080 +/* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_5GHZ 0x00000100 +/* Only passive scan allowed */ +#define IEEE80211_CHAN_PASSIVE 0x00000200 +/* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_DYN 0x00000400 +/* GFSK channel (FHSS PHY) */ +#define IEEE80211_CHAN_GFSK 0x00000800 +/* Radar found on channel */ +#define IEEE80211_CHAN_RADAR 0x00001000 +/* 11a static turbo channel only */ +#define IEEE80211_CHAN_STURBO 0x00002000 +/* Half rate channel */ +#define IEEE80211_CHAN_HALF 0x00004000 +/* Quarter rate channel */ +#define IEEE80211_CHAN_QUARTER 0x00008000 +/* HT 20 channel */ +#define IEEE80211_CHAN_HT20 0x00010000 +/* HT 40 with extension channel above */ +#define IEEE80211_CHAN_HT40PLUS 0x00020000 +/* HT 40 with extension channel below */ +#define IEEE80211_CHAN_HT40MINUS 0x00040000 +/* HT 40 Intolerant */ +#define IEEE80211_CHAN_HT40INTOL 0x00080000 +/* VHT 20 channel */ +#define IEEE80211_CHAN_VHT20 0x00100000 +/* VHT 40 with extension channel above */ +#define IEEE80211_CHAN_VHT40PLUS 0x00200000 +/* VHT 40 with extension channel below */ +#define IEEE80211_CHAN_VHT40MINUS 0x00400000 +/* VHT 80 channel */ +#define IEEE80211_CHAN_VHT80 0x00800000 + +/* token for ``any channel'' */ +#define IEEE80211_CHAN_ANY (-1) +#define IEEE80211_CHAN_ANYC \ + ((struct ieee80211_channel *) IEEE80211_CHAN_ANY) + + +#define IEEE80211_IS_CHAN_11N_HT40MINUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) != 0) +#define IEEE80211_IS_CHAN_11N_HT40PLUS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) != 0) +#define IEEE80211_CHAN_11AC_VHT80 \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT80) + + +#define IEEE80211_IS_CHAN_11AC_VHT80(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80) == \ + IEEE80211_CHAN_11AC_VHT80) +#define CHANNEL_108G \ + (IEEE80211_CHAN_2GHZ|IEEE80211_CHAN_OFDM|IEEE80211_CHAN_TURBO) + +/* + * Software use: channel interference + * used for as AR as well as RADAR + * interference detection +*/ +#define CHANNEL_INTERFERENCE 0x01 +/* In case of VHT160, we can have 8 20Mhz channels */ +#define IEE80211_MAX_20M_SUB_CH 8 + +struct ieee80211_channel +{ + u_int32_t ic_freq; /* setting in Mhz */ + u_int32_t ic_flags; /* see below */ + u_int8_t ic_flagext; /* see below */ + u_int8_t ic_ieee; /* IEEE channel number */ + + /* maximum regulatory tx power in dBm */ + int8_t ic_maxregpower; + + int8_t ic_maxpower; /* maximum tx power in dBm */ + int8_t ic_minpower; /* minimum tx power in dBm */ + u_int8_t ic_regClassId; /* regClassId of this channel */ + u_int8_t ic_antennamax; /* antenna gain max from regulatory */ + u_int32_t ic_vhtop_ch_freq_seg1; /* Channel Center frequency */ + + /* Channel Center frequency applicable*/ + u_int32_t ic_vhtop_ch_freq_seg2; +}; + +struct ieee80211_channel_list +{ + int cl_nchans; + struct ieee80211_channel *cl_channels[IEE80211_MAX_20M_SUB_CH]; +}; + +struct ieee80211_dfs_state +{ + int nol_event[IEEE80211_CHAN_MAX]; + os_timer_t nol_timer; /* NOL list processing */ + os_timer_t cac_timer; /* CAC timer */ + int cureps; /* current events/second */ + const struct ieee80211_channel *lastchan; /* chan w/ last radar event */ + struct ieee80211_channel *newchan; /* chan selected next */ + /* overridden cac timeout */ + int cac_timeout_override; + u_int8_t enable:1, + cac_timer_running:1, + ignore_dfs:1, + ignore_cac:1; +}; + +typedef struct ieee80211com +{ + void (*ic_start_csa)(struct ieee80211com *ic,u_int8_t ieeeChan); + void (*ic_get_ext_chan_info)(struct ieee80211com *ic, + struct ieee80211_channel_list *chan); + enum ieee80211_opmode ic_opmode; /* operation mode */ + struct ieee80211_channel *(*ic_find_channel)(struct ieee80211com *ic, + int freq, u_int32_t flags); + u_int64_t (*ic_get_TSF64)(struct ieee80211com *ic); + unsigned int (*ic_ieee2mhz)(u_int chan, u_int flags); + struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX+1]; + /* Number of Channels according to the Regulatory domain channels */ + int ic_nchans; + struct ieee80211_channel *ic_curchan; /* current channel */ + u_int8_t ic_isdfsregdomain; /* operating in DFS domain ? */ + int (*ic_get_dfsdomain)(struct ieee80211com *); + u_int16_t (*ic_dfs_usenol)(struct ieee80211com *ic); + u_int16_t (*ic_dfs_isdfsregdomain)(struct ieee80211com *ic); + int (*ic_dfs_attached)(struct ieee80211com *ic); + void *ic_dfs; + struct ieee80211_dfs_state ic_dfs_state; + int (*ic_dfs_attach)(struct ieee80211com *ic, + void *pCap, void *radar_info); + int (*ic_dfs_detach)(struct ieee80211com *ic); + int (*ic_dfs_enable)(struct ieee80211com *ic, int *is_fastclk, void *); + int (*ic_dfs_disable)(struct ieee80211com *ic); + int (*ic_get_ext_busy)(struct ieee80211com *ic); + int (*ic_get_mib_cycle_counts_pct)(struct ieee80211com *ic, + u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt); + int (*ic_dfs_get_thresholds)(struct ieee80211com *ic,void *pe); + + int (*ic_dfs_debug)(struct ieee80211com *ic, int type, void *data); + /* + * Update the channel list with the current set of DFS + * NOL entries. + * + * + 'cmd' indicates what to do; for now it should just + * be DFS_NOL_CLIST_CMD_UPDATE which will update all + * channels, given the _entire_ NOL. (Rather than + * the earlier behaviour with clist_update, which + * was to either add or remove a set of channel + * entries.) + */ + void (*ic_dfs_clist_update)(struct ieee80211com *ic, int cmd, + struct dfs_nol_chan_entry *, int nentries); + void (*ic_dfs_notify_radar)(struct ieee80211com *ic, + struct ieee80211_channel *chan); + void (*ic_dfs_unmark_radar)(struct ieee80211com *ic, + struct ieee80211_channel *chan); + int (*ic_dfs_control)(struct ieee80211com *ic, + u_int id, void *indata, u_int32_t insize, + void *outdata, u_int32_t *outsize); + HAL_DFS_DOMAIN current_dfs_regdomain; + u_int8_t vdev_id; + u_int8_t last_radar_found_chan; + int32_t dfs_pri_multiplier; +} IEEE80211COM, *PIEEE80211COM; + +/* + * Convert channel to frequency value. + */ +static INLINE u_int +ieee80211_chan2freq(struct ieee80211com *ic, + const struct ieee80211_channel *c) +{ + if (c == NULL) + { + return 0; + } + return (c == IEEE80211_CHAN_ANYC ? IEEE80211_CHAN_ANY : c->ic_freq); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi.h new file mode 100644 index 0000000000000..2a7d095fcc84d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2004-2010 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// Copyright (c) 2004-2010, 2013 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +/* + * This file contains the definitions of the WMI protocol specified in the + * Wireless Module Interface (WMI). It includes definitions of all the + * commands and events. Commands are messages from the host to the WM. + * Events and Replies are messages from the WM to the host. + * + * Ownership of correctness in regards to commands + * belongs to the host driver and the WMI is not required to validate + * parameters for value, proper range, or any other checking. + * + */ + +#ifndef _WMI_H_ +#define _WMI_H_ + +#include "wlan_defs.h" +#include "wmix.h" +#include "wmi_unified.h" +#include "wmi_tlv_helper.h" +#include "wmi_tlv_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HTC_PROTOCOL_VERSION 0x0002 + +#define WMI_PROTOCOL_VERSION 0x0002 + +#define WMI_MODE_MAX 8 +#define WMI_MAX_RATE_MASK 6 + + +PREPACK struct host_app_area_s { + A_UINT32 wmi_protocol_ver; +} POSTPACK; + + +#undef MS +#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) +#undef SM +#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) +#undef WO +#define WO(_f) ((_f##_OFFSET) >> 2) + +#undef GET_FIELD +#define GET_FIELD(_addr, _f) MS(*((A_UINT32 *)(_addr) + WO(_f)), _f) +#undef SET_FIELD +#define SET_FIELD(_addr, _f, _val) \ + (*((A_UINT32 *)(_addr) + WO(_f)) = \ + (*((A_UINT32 *)(_addr) + WO(_f)) & ~_f##_MASK) | SM(_val, _f)) + +#define WMI_GET_FIELD(_msg_buf, _msg_type, _f) \ + GET_FIELD(_msg_buf, _msg_type ## _ ## _f) + +#define WMI_SET_FIELD(_msg_buf, _msg_type, _f, _val) \ + SET_FIELD(_msg_buf, _msg_type ## _ ## _f, _val) + +#define WMI_EP_APASS 0x0 +#define WMI_EP_LPASS 0x1 + +/* + * Control Path + */ +typedef PREPACK struct { + A_UINT32 commandId : 24, + reserved : 2, /* used for WMI endpoint ID */ + plt_priv : 6; /* platform private */ +} POSTPACK WMI_CMD_HDR; /* used for commands and events */ + +#define WMI_CMD_HDR_COMMANDID_LSB 0 +#define WMI_CMD_HDR_COMMANDID_MASK 0x00ffffff +#define WMI_CMD_HDR_COMMANDID_OFFSET 0x00000000 +#define WMI_CMD_HDR_WMI_ENDPOINTID_MASK 0x03000000 +#define WMI_CMD_HDR_WMI_ENDPOINTID_OFFSET 24 +#define WMI_CMD_HDR_PLT_PRIV_LSB 24 +#define WMI_CMD_HDR_PLT_PRIV_MASK 0xff000000 +#define WMI_CMD_HDR_PLT_PRIV_OFFSET 0x00000000 + +/* + * List of Commnands + */ +typedef enum { + WMI_EXTENSION_CMDID, //used in wmi_svc.c /* Non-wireless extensions */ + WMI_IGNORE_CMDID, //used in wlan_wmi.c +} WMI_COMMAND_ID; + + +typedef enum { + NONE_CRYPT = 0x01, + WEP_CRYPT = 0x02, + TKIP_CRYPT = 0x04, + AES_CRYPT = 0x08, +#ifdef WAPI_ENABLE + WAPI_CRYPT = 0x10, +#endif /*WAPI_ENABLE*/ +} CRYPTO_TYPE; + +#define WMI_MAX_SSID_LEN 32 + +/* + * WMI_SET_PMK_CMDID + */ +#define WMI_PMK_LEN 32 + + +/* + * WMI_ADD_CIPHER_KEY_CMDID + */ +typedef enum { + PAIRWISE_USAGE = 0x00, + GROUP_USAGE = 0x01, + TX_USAGE = 0x02, /* default Tx Key - Static WEP only */ +} KEY_USAGE; + + +/* + * List of Events (target to host) + */ +typedef enum { + WMI_EXTENSION_EVENTID, //wmi_profhook.c and umac_wmi_events.c +} WMI_EVENT_ID; + +typedef enum { + WMI_11A_CAPABILITY = 1, + WMI_11G_CAPABILITY = 2, + WMI_11AG_CAPABILITY = 3, + WMI_11NA_CAPABILITY = 4, + WMI_11NG_CAPABILITY = 5, + WMI_11NAG_CAPABILITY = 6, + WMI_11AC_CAPABILITY = 7, + // END CAPABILITY + WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY), +} WMI_PHY_CAPABILITY; + + +/* Deprectated, need clean up */ +#define WMI_MAX_RX_META_SZ (12) + +typedef PREPACK struct { + A_INT8 rssi; + A_UINT8 info; /* usage of 'info' field(8-bit): + * b1:b0 - WMI_MSG_TYPE + * b4:b3:b2 - UP(tid) + * b5 - Used in AP mode. More-data in tx dir, PS in rx. + * b7:b6 - Dot3 header(0), + * Dot11 Header(1), + * ACL data(2) + */ + + A_UINT16 info2; /* usage of 'info2' field(16-bit): + * b11:b0 - seq_no + * b12 - A-MSDU? + * b15:b13 - META_DATA_VERSION 0 - 7 + */ + A_UINT16 info3; /* b3:b2:b1:b0 - device id + * b4 - Used in AP mode. uAPSD trigger in rx, EOSP in tx + * b7:b5 - unused? + * b15:b8 - pad before data start(irrespective of meta version) + */ +} POSTPACK WMI_DATA_HDR; + +#ifdef __cplusplus +} +#endif + +#endif /* _WMI_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_services.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_services.h new file mode 100644 index 0000000000000..bc39cd02552ff --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_services.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * This file defines WMI services bitmap and the set of WMI services . + * defines macrso to set/clear/get different service bits from the bitmap. + * the service bitmap is sent up to the host via WMI_READY command. + * + */ + +#ifndef _WMI_SERVICES_H_ +#define _WMI_SERVICES_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +typedef enum { + WMI_SERVICE_BEACON_OFFLOAD=0, /* beacon offload */ + WMI_SERVICE_SCAN_OFFLOAD, /* scan offload */ + WMI_SERVICE_ROAM_SCAN_OFFLOAD, /* roam scan offload */ + WMI_SERVICE_BCN_MISS_OFFLOAD, /* beacon miss offload */ + WMI_SERVICE_STA_PWRSAVE, /* fake sleep + basic power save */ + WMI_SERVICE_STA_ADVANCED_PWRSAVE, /* uapsd, pspoll, force sleep */ + WMI_SERVICE_AP_UAPSD, /* uapsd on AP */ + WMI_SERVICE_AP_DFS, /* DFS on AP */ + WMI_SERVICE_11AC, /* supports 11ac */ + WMI_SERVICE_BLOCKACK, /* Supports triggering ADDBA/DELBA from host*/ + WMI_SERVICE_PHYERR, /* PHY error */ + WMI_SERVICE_BCN_FILTER, /* Beacon filter support */ + WMI_SERVICE_RTT, /* RTT (round trip time) support */ + WMI_SERVICE_WOW, /* WOW Support */ + WMI_SERVICE_RATECTRL_CACHE, /* Rate-control caching */ + WMI_SERVICE_IRAM_TIDS, /* TIDs in IRAM */ + WMI_SERVICE_ARPNS_OFFLOAD, /* ARP NS Offload support for STA vdev */ + WMI_SERVICE_NLO, /* Network list offload service */ + WMI_SERVICE_GTK_OFFLOAD, /* GTK offload */ + WMI_SERVICE_SCAN_SCH, /* Scan Scheduler Service */ + WMI_SERVICE_CSA_OFFLOAD, /* CSA offload service */ + WMI_SERVICE_CHATTER, /* Chatter service */ + WMI_SERVICE_COEX_FREQAVOID, /* FW report freq range to avoid */ + WMI_SERVICE_PACKET_POWER_SAVE, /* packet power save service */ + WMI_SERVICE_FORCE_FW_HANG, /* Service to test the firmware recovery mechanism */ + WMI_SERVICE_GPIO, /* GPIO service */ + WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, /* Modulated DTIM support */ + WMI_STA_UAPSD_BASIC_AUTO_TRIG, /* Basic version of station UAPSD AC Trigger Generation Method with + * variable tigger periods (service, delay, and suspend intervals) */ + WMI_STA_UAPSD_VAR_AUTO_TRIG, /* Station UAPSD AC Trigger Generation Method with variable + * trigger periods (service, delay, and suspend intervals) */ + WMI_SERVICE_STA_KEEP_ALIVE, /* Serivce to support the STA KEEP ALIVE mechanism */ + WMI_SERVICE_TX_ENCAP, /* Packet type for TX encapsulation */ + WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, /* detect out-of-sync sleeping stations */ + WMI_SERVICE_EARLY_RX, /* adaptive early-rx feature */ + WMI_SERVICE_STA_SMPS, /* STA MIMO-PS */ + WMI_SERVICE_FWTEST, /* Firmware test service */ + WMI_SERVICE_STA_WMMAC, /* STA WMMAC */ + WMI_SERVICE_TDLS, /* TDLS support */ + WMI_SERVICE_BURST, /* SIFS spaced burst support */ + WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE, /* Dynamic beaocn interval change for SAP/P2p GO in MCC scenario */ + WMI_SERVICE_ADAPTIVE_OCS, /* Service to support adaptive off-channel scheduler */ + WMI_SERVICE_BA_SSN_SUPPORT, /* target will provide Sequence number for the peer/tid combo */ + WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE, + WMI_SERVICE_WLAN_HB, /* wlan HB service */ + WMI_SERVICE_LTE_ANT_SHARE_SUPPORT, /* support LTE/WLAN antenna sharing */ + WMI_SERVICE_BATCH_SCAN, /*Service to support batch scan*/ + WMI_SERVICE_QPOWER, /* QPower service */ + WMI_SERVICE_PLMREQ, + WMI_SERVICE_THERMAL_MGMT, + WMI_SERVICE_RMC, /* RMC support */ + WMI_SERVICE_MHF_OFFLOAD, /* multi-hop forwarding offload */ + WMI_SERVICE_COEX_SAR, /* target support SAR tx limit from WMI_PDEV_PARAM_TXPOWER_LIMITxG */ + WMI_SERVICE_BCN_TXRATE_OVERRIDE, /* Will support the bcn/prb rsp rate override */ + WMI_SERVICE_NAN, /* Neighbor Awareness Network */ + WMI_SERVICE_L1SS_STAT, /* L1SS statistics counter report */ + WMI_SERVICE_ESTIMATE_LINKSPEED, /* Linkspeed Estimation per peer */ + WMI_SERVICE_OBSS_SCAN, /* Service to support OBSS scan */ + WMI_SERVICE_TDLS_OFFCHAN, /* TDLS off channel support */ + WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, /* TDLS UAPSD Buffer STA support */ + WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, /* TDLS UAPSD Sleep STA support */ + WMI_SERVICE_IBSS_PWRSAVE, /* IBSS power save support */ + WMI_SERVICE_LPASS, /*Service to support LPASS*/ + WMI_SERVICE_EXTSCAN, /* Extended Scans */ + WMI_SERVICE_D0WOW, /* D0-WOW Support */ + WMI_SERVICE_HSOFFLOAD, /* Hotspot offload feature Support */ + WMI_SERVICE_ROAM_HO_OFFLOAD, /* roam handover offload */ + WMI_SERVICE_RX_FULL_REORDER, /* target-based Rx full reorder */ + WMI_SERVICE_DHCP_OFFLOAD, /* DHCP offload support */ + WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, /* STA RX DATA offload to IPA support */ + WMI_SERVICE_MDNS_OFFLOAD, /* mDNS responder offload support */ + WMI_SERVICE_SAP_AUTH_OFFLOAD, /* softap auth offload */ + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT, /* Dual Band Simultaneous support */ + WMI_SERVICE_OCB, /* OCB mode support */ + WMI_SERVICE_AP_ARPNS_OFFLOAD, /* arp offload support for ap mode vdev */ + WMI_MAX_SERVICE=128 /* max service */ +} WMI_SERVICE; + +#define WMI_SERVICE_BM_SIZE ((WMI_MAX_SERVICE + sizeof(A_UINT32)- 1)/sizeof(A_UINT32)) + +#define WMI_SERVICE_ROAM_OFFLOAD WMI_SERVICE_ROAM_SCAN_OFFLOAD /* depreciated the name WMI_SERVICE_ROAM_OFFLOAD, but here to help compiling with old host driver */ + +/* + * turn on the WMI service bit corresponding to the WMI service. + */ +#define WMI_SERVICE_ENABLE(pwmi_svc_bmap,svc_id) \ + ( (pwmi_svc_bmap)[(svc_id)/(sizeof(A_UINT32))] |= \ + (1 << ((svc_id)%(sizeof(A_UINT32)))) ) + +#define WMI_SERVICE_DISABLE(pwmi_svc_bmap,svc_id) \ + ( (pwmi_svc_bmap)[(svc_id)/(sizeof(A_UINT32))] &= \ + ( ~(1 << ((svc_id)%(sizeof(A_UINT32)))) ) ) + +#define WMI_SERVICE_IS_ENABLED(pwmi_svc_bmap,svc_id) \ + ( ((pwmi_svc_bmap)[(svc_id)/(sizeof(A_UINT32))] & \ + (1 << ((svc_id)%(sizeof(A_UINT32)))) ) != 0) + +#ifdef __cplusplus +} +#endif + +#endif /*_WMI_SERVICES_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_defs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_defs.h new file mode 100644 index 0000000000000..15d29c391a48b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_defs.h @@ -0,0 +1,2812 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WMI_TLV_DEFS_H_ +#define _WMI_TLV_DEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define WMITLV_FIELD_BUF_IS_ALLOCATED(elem_name) \ + is_allocated_##elem_name + +#define WMITLV_FIELD_NUM_OF(elem_name) \ + num_##elem_name + +/* Define the structure typedef for the TLV parameters of each cmd/event */ +#define WMITLV_TYPEDEF_STRUCT_PARAMS_TLVS(wmi_cmd_event_id) \ + wmi_cmd_event_id##_param_tlvs + +/* + * The following macro WMITLV_OP_* are created by the macro WMITLV_ELEM(). + */ +/* macro to define the TLV name in the correct order. When (op==TAG_ORDER) */ +#define WMITLV_OP_TAG_ORDER_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + wmi_cmd_event_id##_tlv_order_##elem_name, + +/* macro to define the TLV name with the TLV Tag value. When (op==TAG_ID) */ +#define WMITLV_OP_TAG_ID_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + wmi_cmd_event_id##_tlv_tag_##elem_name = elem_tlv_tag, + +/* macro to define the TLV name with the TLV structure size. May not be accurate when variable length. When (op==TAG_SIZEOF) */ +#define WMITLV_OP_TAG_SIZEOF_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + wmi_cmd_event_id##_sizeof_##elem_name = sizeof(elem_struc_type), + +/* macro to define the TLV name with value indicating whether the TLV is variable length. When (op==TAG_VAR_SIZED) */ +#define WMITLV_OP_TAG_VAR_SIZED_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + wmi_cmd_event_id##_var_sized_##elem_name = var_len, + +/* macro to define the TLV name with value indicating the fixed array size. When (op==TAG_ARR_SIZE) */ +#define WMITLV_OP_TAG_ARR_SIZE_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + wmi_cmd_event_id##_arr_size_##elem_name = arr_size, + +/* + * macro to define afew fields associated to a TLV. For example, a structure pointer with the TLV name. + * This macro is expand from WMITLV_ELEM(op) when (op==STRUCT_FIELD). + * NOTE: If this macro is changed, then "mirror" structure wmitlv_cmd_param_info + * should be updated too. + */ +#define WMITLV_OP_STRUCT_FIELD_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + elem_struc_type *elem_name; \ + A_UINT32 WMITLV_FIELD_NUM_OF(elem_name); \ + A_UINT32 WMITLV_FIELD_BUF_IS_ALLOCATED(elem_name); + +/* + * A "mirror" structure that contains the fields that is created by the + * macro WMITLV_OP_STRUCT_FIELD_macro. + * NOTE: you should modify this structure and WMITLV_OP_STRUCT_FIELD_macro + * so that they both has the same kind of fields. + */ +typedef struct { + void *tlv_ptr; /* Pointer to the TLV Buffer. But the "real" one will have the right type instead of void. */ + A_UINT32 num_elements; /* Number of elements. For non-array, this is one. For array, this is the number of elements. */ + A_UINT32 buf_is_allocated;/* Boolean flag to indicate that a new buffer is allocated for this TLV. */ +} wmitlv_cmd_param_info; + +/* + * NOTE TRICKY MACRO: + * WMITLV_ELEM is re-defined to a "op" specific macro. + * Eg. WMITLV_OP_TAG_ORDER_macro is created for the op_type=TAG_ORDER. + */ +#define WMITLV_ELEM(wmi_cmd_event_id, op_type, param_ptr, param_len, elem_tlv_tag, elem_struc_type, elem_name, var_len) \ + WMITLV_OP_##op_type##_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, WMITLV_ARR_SIZE_INVALID) +/* + * WMITLV_FXAR (FiX ARray) is similar to WMITLV_ELEM except it has an extra parameter for the fixed number of elements. + * It is re-defined to a "op" specific macro. + * Eg. WMITLV_OP_TAG_ORDER_macro is created for the op_type=TAG_ORDER. + */ +#define WMITLV_FXAR(wmi_cmd_event_id, op_type, param_ptr, param_len, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + WMITLV_OP_##op_type##_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) + +#define WMITLV_TABLE(id,op,buf,len) WMITLV_TABLE_##id(id,op,buf,len) + +/* + * This macro will create various enumerations and structures to describe the TLVs for + * the given Command/Event ID. + * + * For example, the following is for WMI_SERVICE_READY_EVENTID: + * #define WMITLV_TABLE_WMI_SERVICE_READY_EVENTID(id,op,buf,len) \ + * WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_service_ready_event_fixed_param, wmi_service_ready_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + * WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_HAL_REG_CAPABILITIES, HAL_REG_CAPABILITIES, hal_reg_capabilities, WMITLV_SIZE_FIX) \ + * WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, wmi_service_bitmap, WMITLV_SIZE_FIX, WMI_SERVICE_BM_SIZE) \ + * WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wlan_host_mem_req, mem_reqs, WMITLV_SIZE_VAR) + * WMITLV_CREATE_PARAM_STRUC(WMI_SERVICE_READY_EVENTID); + * This macro will create the following text: + * + * typedef enum { + * WMI_SERVICE_READY_EVENTID_tlv_order_wmi_service_ready_event_fixed_param, + * WMI_SERVICE_READY_EVENTID_tlv_order_hal_reg_capabilities, + * WMI_SERVICE_READY_EVENTID_tlv_order_wmi_service_bitmap, + * WMI_SERVICE_READY_EVENTID_tlv_order_mem_reqs, + * WMI_TLV_HLPR_NUM_TLVS_FOR_WMI_SERVICE_READY_EVENTID + * } WMI_SERVICE_READY_EVENTID_TAG_ID_enum_type; + * //NOTE: WMI_TLV_HLPR_NUM_TLVS_FOR_WMI_SERVICE_READY_EVENTID is the number of TLVs. + * + * typedef enum { + * WMI_SERVICE_READY_EVENTID_tlv_tag_wmi_service_ready_event_fixed_param = WMITLV_TAG_STRUC_wmi_service_ready_event_fixed_param, + * WMI_SERVICE_READY_EVENTID_tlv_tag_hal_reg_capabilities = WMITLV_TAG_STRUC_HAL_REG_CAPABILITIES, + * WMI_SERVICE_READY_EVENTID_tlv_tag_wmi_service_bitmap = WMITLV_TAG_ARRAY_UINT32, + * WMI_SERVICE_READY_EVENTID_tlv_tag_mem_reqs = WMITLV_TAG_ARRAY_STRUC, + * } WMI_SERVICE_READY_EVENTID_TAG_ORDER_enum_type; + * + * typedef enum { + * WMI_SERVICE_READY_EVENTID_sizeof_wmi_service_ready_event_fixed_param = sizeof(wmi_service_ready_event_fixed_param), + * WMI_SERVICE_READY_EVENTID_sizeof_hal_reg_capabilities = sizeof(HAL_REG_CAPABILITIES), + * WMI_SERVICE_READY_EVENTID_sizeof_wmi_service_bitmap = sizeof(A_UINT32), + * WMI_SERVICE_READY_EVENTID_sizeof_mem_reqs = sizeof(wlan_host_mem_req), + * } WMI_SERVICE_READY_EVENTID_TAG_SIZEOF_enum_type; + * + * typedef enum { + * WMI_SERVICE_READY_EVENTID_var_sized_wmi_service_ready_event_fixed_param = WMITLV_SIZE_FIX, + * WMI_SERVICE_READY_EVENTID_var_sized_hal_reg_capabilities = WMITLV_SIZE_FIX, + * WMI_SERVICE_READY_EVENTID_var_sized_wmi_service_bitmap = WMITLV_SIZE_VAR, + * WMI_SERVICE_READY_EVENTID_var_sized_mem_reqs = WMITLV_SIZE_VAR, + * } WMI_SERVICE_READY_EVENTID_TAG_VAR_SIZED_enum_type; + * + * typedef enum { + * WMI_SERVICE_READY_EVENTID_arr_size_wmi_service_ready_event_fixed_param = WMITLV_ARR_SIZE_INVALID, + * WMI_SERVICE_READY_EVENTID_arr_size_hal_reg_capabilities = WMITLV_ARR_SIZE_INVALID, + * WMI_SERVICE_READY_EVENTID_arr_size_wmi_service_bitmap = WMI_SERVICE_BM_SIZE, + * WMI_SERVICE_READY_EVENTID_arr_size_mem_reqs = WMITLV_ARR_SIZE_INVALID, + * } WMI_SERVICE_READY_EVENTID_TAG_ARR_SIZE_enum_type; + * + * typedef struct { + * wmi_service_ready_event_fixed_param *fixed_param; + * A_UINT32 num_fixed_param; + * A_UINT32 is_allocated_fixed_param; + * HAL_REG_CAPABILITIES *hal_reg_capabilities; + * A_UINT32 num_hal_reg_capabilities; + * A_UINT32 is_allocated_hal_reg_capabilities; + * A_UINT32 *wmi_service_bitmap; + * A_UINT32 num_wmi_service_bitmap; + * A_UINT32 is_allocated_wmi_service_bitmap; + * wlan_host_mem_req *mem_reqs; + * A_UINT32 num_mem_reqs; + * A_UINT32 is_allocated_mem_reqs; + * + * } WMI_SERVICE_READY_EVENTID_param_tlvs; + * + */ + +#define WMITLV_CREATE_PARAM_STRUC(wmi_cmd_event_id) \ + typedef enum { \ + WMITLV_TABLE(wmi_cmd_event_id, TAG_ORDER, NULL, 0) \ + WMI_TLV_HLPR_NUM_TLVS_FOR_##wmi_cmd_event_id \ + } wmi_cmd_event_id##_TAG_ORDER_enum_type; \ + \ + typedef struct { \ + WMITLV_TABLE(wmi_cmd_event_id, STRUCT_FIELD, NULL, 0) \ + } WMITLV_TYPEDEF_STRUCT_PARAMS_TLVS(wmi_cmd_event_id); \ + +/** Enum list of TLV Tags for each parameter structure type. */ +typedef enum { + /* 0 to 15 is reserved */ + WMITLV_TAG_LAST_RESERVED = 15, + WMITLV_TAG_FIRST_ARRAY_ENUM, /* First entry of ARRAY type tags */ + WMITLV_TAG_ARRAY_UINT32 = WMITLV_TAG_FIRST_ARRAY_ENUM, + WMITLV_TAG_ARRAY_BYTE, + WMITLV_TAG_ARRAY_STRUC, + WMITLV_TAG_ARRAY_FIXED_STRUC, + WMITLV_TAG_LAST_ARRAY_ENUM = 31, /* Last entry of ARRAY type tags */ + WMITLV_TAG_STRUC_wmi_service_ready_event_fixed_param, + WMITLV_TAG_STRUC_HAL_REG_CAPABILITIES, + WMITLV_TAG_STRUC_wlan_host_mem_req, + WMITLV_TAG_STRUC_wmi_ready_event_fixed_param, + WMITLV_TAG_STRUC_wmi_scan_event_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_tpc_config_event_fixed_param, + WMITLV_TAG_STRUC_wmi_chan_info_event_fixed_param, + WMITLV_TAG_STRUC_wmi_comb_phyerr_rx_hdr, + WMITLV_TAG_STRUC_wmi_vdev_start_response_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_stopped_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_install_key_complete_event_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_sta_kickout_event_fixed_param, + WMITLV_TAG_STRUC_wmi_mgmt_rx_hdr, + WMITLV_TAG_STRUC_wmi_tbtt_offset_event_fixed_param, + WMITLV_TAG_STRUC_wmi_tx_delba_complete_event_fixed_param, + WMITLV_TAG_STRUC_wmi_tx_addba_complete_event_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_event_fixed_param, + WMITLV_TAG_STRUC_WOW_EVENT_INFO_fixed_param, + WMITLV_TAG_STRUC_WOW_EVENT_INFO_SECTION_BITMAP, + WMITLV_TAG_STRUC_wmi_rtt_event_header, + WMITLV_TAG_STRUC_wmi_rtt_error_report_event_fixed_param, + WMITLV_TAG_STRUC_wmi_rtt_meas_event_fixed_param, + WMITLV_TAG_STRUC_wmi_echo_event_fixed_param, + WMITLV_TAG_STRUC_wmi_ftm_intg_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_event_fixed_param, + WMITLV_TAG_STRUC_wmi_gpio_input_event_fixed_param, + WMITLV_TAG_STRUC_wmi_csa_event_fixed_param, + WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, + WMITLV_TAG_STRUC_wmi_igtk_info, + WMITLV_TAG_STRUC_wmi_dcs_interference_event_fixed_param, + WMITLV_TAG_STRUC_ath_dcs_cw_int, + WMITLV_TAG_STRUC_ath_dcs_wlan_int_stat, + WMITLV_TAG_STRUC_wmi_wlan_profile_ctx_t, + WMITLV_TAG_STRUC_wmi_wlan_profile_t, + WMITLV_TAG_STRUC_wmi_pdev_qvit_event_fixed_param, + WMITLV_TAG_STRUC_wmi_host_swba_event_fixed_param, + WMITLV_TAG_STRUC_wmi_tim_info, + WMITLV_TAG_STRUC_wmi_p2p_noa_info, + WMITLV_TAG_STRUC_wmi_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_avoid_freq_ranges_event_fixed_param, + WMITLV_TAG_STRUC_wmi_avoid_freq_range_desc, + WMITLV_TAG_STRUC_wmi_gtk_rekey_fail_event_fixed_param, + WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_resource_config, + WMITLV_TAG_STRUC_wlan_host_memory_chunk, + WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wmm_params, + WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, + WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, + WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vht_rate_set, + WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_bcn_prb_info, + WMITLV_TAG_STRUC_wmi_peer_tid_addba_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_tid_delba_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_dtim_ps_method_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, + WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, + WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, + WMITLV_TAG_STRUC_wmi_ftm_intg_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, + WMITLV_TAG_STRUC_wmi_p2p_set_vendor_ie_data_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_rate_retry_sched_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_rtt_measreq_head, + WMITLV_TAG_STRUC_wmi_rtt_measreq_body, + WMITLV_TAG_STRUC_wmi_rtt_tsf_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, + WMITLV_TAG_STRUC_nlo_configured_parameters, + WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_csa_offload_chanswitch_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_chatter_set_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_echo_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_set_keepalive_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_bcn_tx_hdr, + WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mgmt_tx_hdr, + WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_addba_setresponse_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_send_singleamsdu_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_dscp_tid_map_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, + WMITLV_TAG_STRUC_wmi_ap_profile, + WMITLV_TAG_STRUC_wmi_scan_sch_priority_table_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, + WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T, + WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T, + WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD, + WMITLV_TAG_STRUC_WMI_scan_update_request_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_chatter_pkt_coalescing_filter, + WMITLV_TAG_STRUC_wmi_chatter_coalescing_add_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_chatter_coalescing_delete_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_chatter_coalescing_query_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_txbf_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_nlo_event, + WMITLV_TAG_STRUC_wmi_chatter_query_reply_event_fixed_param, + WMITLV_TAG_STRUC_wmi_upload_h_hdr, + WMITLV_TAG_STRUC_wmi_capture_h_event_hdr, + WMITLV_TAG_STRUC_WMI_VDEV_WNM_SLEEPMODE_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_tdls_peer_event_fixed_param, + WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, + WMITLV_TAG_STRUC_wmi_vdev_mcc_set_tbtt_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_mcc_bcn_intvl_change_event_fixed_param, + WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ba_req_ssn_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ba_rsp_ssn_event_fixed_param, + WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ba_req_ssn_cmd_sub_struct_param, + WMITLV_TAG_STRUC_wmi_ba_req_ssn_event_sub_struct_param, + WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mcc_sched_traffic_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mcc_sched_sta_traffic_stats, + WMITLV_TAG_STRUC_wmi_offload_bcn_tx_status_event_fixed_param, + WMITLV_TAG_STRUC_wmi_p2p_noa_event_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_hb_ind_event_fixed_param, + WMITLV_TAG_STRUC_wmi_tx_pause_event_fixed_param, + WMITLV_TAG_STRUC_wmi_rfkill_event_fixed_param, + WMITLV_TAG_STRUC_wmi_dfs_radar_event_fixed_param, + WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_batch_scan_result_scan_list, + WMITLV_TAG_STRUC_wmi_batch_scan_result_network_info, + WMITLV_TAG_STRUC_wmi_batch_scan_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_batch_scan_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_batch_scan_trigger_result_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_batch_scan_enabled_event_fixed_param, + WMITLV_TAG_STRUC_wmi_batch_scan_result_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_thermal_mgmt_event_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_info_event_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_info, + WMITLV_TAG_STRUC_wmi_peer_tx_fail_cnt_thr_event_fixed_param, + WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_rmc_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mhf_offload_set_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mhf_offload_plumb_routing_table_cmd_fixed_param, + WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_nan_cmd_param, + WMITLV_TAG_STRUC_wmi_nan_event_hdr, + WMITLV_TAG_STRUC_wmi_pdev_l1ss_track_event_fixed_param, + WMITLV_TAG_STRUC_wmi_diag_data_container_event_fixed_param, + WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, + WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_estimated_linkspeed_event_fixed_param, + WMITLV_TAG_STRUC_wmi_aggr_state_trig_event_fixed_param, + WMITLV_TAG_STRUC_wmi_mhf_offload_routing_table_entry, + WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_stats_ext_event_fixed_param, + WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_offload_prb_rsp_tx_status_event_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_led_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_host_auto_shutdown_event_fixed_param, + WMITLV_TAG_STRUC_wmi_update_whal_mib_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, + WMITLV_TAG_STRUC_WOW_IOAC_PKT_PATTERN_T, + WMITLV_TAG_STRUC_WOW_IOAC_TMR_PATTERN_T, + WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_KEEPALIVE_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_KEEPALIVE_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_IOAC_KEEPALIVE_T, + WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_iface_link_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_radio_link_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_channel_stats, + WMITLV_TAG_STRUC_wmi_radio_link_stats, + WMITLV_TAG_STRUC_wmi_rate_stats, + WMITLV_TAG_STRUC_wmi_peer_link_stats, + WMITLV_TAG_STRUC_wmi_wmm_ac_stats, + WMITLV_TAG_STRUC_wmi_iface_link_stats, + WMITLV_TAG_STRUC_wmi_lpi_mgmt_snooping_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_lpi_start_scan_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_lpi_stop_scan_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_lpi_result_event_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_state_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_wlan_change_bssid_param_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_get_wlan_change_results_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_set_capabilities_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_wlan_descriptor_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_rssi_info_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_wlan_change_result_bssid_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_cache_capabilities_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_wlan_change_monitor_capabilities_event_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_hotlist_monitor_capabilities_event_fixed_param, + WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_d0_wow_disable_ack_event_fixed_param, + WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, + WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, + WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, + WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, + WMITLV_TAG_STRUC_wmi_roam_synch_event_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, + WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_lpi_status_event_fixed_param, + WMITLV_TAG_STRUC_wmi_lpi_handoff_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_rate_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_rate_ht_info, + WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_temperature_event_fixed_param, + WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_tpc_chainmask_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ric_tspec, + WMITLV_TAG_STRUC_wmi_tpc_chainmask_config, + WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_key_material, + WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mdns_offload_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mdns_set_fqdn_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mdns_set_resp_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mdns_get_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_mdns_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_resume_event_fixed_param, + WMITLV_TAG_STRUC_wmi_pdev_set_antenna_diversity_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sap_ofl_enable_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_sap_ofl_add_sta_event_fixed_param, + WMITLV_TAG_STRUC_wmi_sap_ofl_del_sta_event_fixed_param, + WMITLV_TAG_STRUC_wmi_apfind_cmd_param, + WMITLV_TAG_STRUC_wmi_apfind_event_hdr, + WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param, //DEPRECATED + WMITLV_TAG_STRUC_wmi_ocb_set_sched_event_fixed_param, // DEPRECATED + WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_set_config_resp_event_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_resp_event_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request, + WMITLV_TAG_STRUC_wmi_dcc_get_stats_resp_event_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_update_ndl_resp_event_fixed_param, + WMITLV_TAG_STRUC_wmi_dcc_stats_event_fixed_param, + WMITLV_TAG_STRUC_wmi_ocb_channel, + WMITLV_TAG_STRUC_wmi_ocb_schedule_element, + WMITLV_TAG_STRUC_wmi_dcc_ndl_stats_per_channel, + WMITLV_TAG_STRUC_wmi_dcc_ndl_chan, + WMITLV_TAG_STRUC_wmi_qos_parameter, + WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config, + WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param, + WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, + WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_passpoint_event_hdr, + WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_tsf_report_event_fixed_param, + WMITLV_TAG_STRUC_wmi_get_fw_mem_dump_fixed_param, + WMITLV_TAG_STRUC_wmi_update_fw_mem_dump_fixed_param, + WMITLV_TAG_STRUC_wmi_fw_mem_dump_params, + WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, + WMITLV_TAG_STRUC_wmi_debug_mesg_flush_complete_fixed_param, + WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, + WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, + WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, + WMITLV_TAG_STRUC_wmi_rssi_breach_event_fixed_param, + WMITLV_TAG_STRUC_WOW_EVENT_INITIAL_WAKEUP_fixed_param, + WMITLV_TAG_STRUC_wmi_soc_set_pcl_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_cmd_fixed_param, + WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_response_event_fixed_param, + WMITLV_TAG_STRUC_wmi_soc_hw_mode_transition_event_fixed_param, +} WMITLV_TAG_ID; + +/* + * IMPORTANT: Please add _ALL_ WMI Commands Here. + * Otherwise, these WMI TLV Functions will be process them. + */ +#define WMITLV_ALL_CMD_LIST(OP) \ + OP(WMI_INIT_CMDID) \ + OP(WMI_PEER_CREATE_CMDID) \ + OP(WMI_PEER_DELETE_CMDID) \ + OP(WMI_PEER_FLUSH_TIDS_CMDID) \ + OP(WMI_PEER_SET_PARAM_CMDID) \ + OP(WMI_STA_POWERSAVE_MODE_CMDID) \ + OP(WMI_STA_POWERSAVE_PARAM_CMDID) \ + OP(WMI_STA_DTIM_PS_METHOD_CMDID) \ + OP(WMI_PDEV_SET_REGDOMAIN_CMDID) \ + OP(WMI_PEER_TID_ADDBA_CMDID) \ + OP(WMI_PEER_TID_DELBA_CMDID) \ + OP(WMI_PDEV_FTM_INTG_CMDID) \ + OP(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID) \ + OP(WMI_WOW_ENABLE_CMDID) \ + OP(WMI_RMV_BCN_FILTER_CMDID) \ + OP(WMI_ROAM_SCAN_MODE) \ + OP(WMI_ROAM_SCAN_RSSI_THRESHOLD) \ + OP(WMI_ROAM_SCAN_PERIOD) \ + OP(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD) \ + OP(WMI_START_SCAN_CMDID) \ + OP(WMI_VDEV_PLMREQ_START_CMDID) \ + OP(WMI_VDEV_PLMREQ_STOP_CMDID) \ + OP(WMI_PDEV_SET_CHANNEL_CMDID) \ + OP(WMI_PDEV_SET_WMM_PARAMS_CMDID) \ + OP(WMI_VDEV_START_REQUEST_CMDID) \ + OP(WMI_VDEV_RESTART_REQUEST_CMDID) \ + OP(WMI_P2P_GO_SET_BEACON_IE) \ + OP(WMI_GTK_OFFLOAD_CMDID) \ + OP(WMI_SCAN_CHAN_LIST_CMDID) \ + OP(WMI_STA_UAPSD_AUTO_TRIG_CMDID) \ + OP(WMI_PRB_TMPL_CMDID) \ + OP(WMI_BCN_TMPL_CMDID) \ + OP(WMI_VDEV_INSTALL_KEY_CMDID) \ + OP(WMI_PEER_ASSOC_CMDID) \ + OP(WMI_ADD_BCN_FILTER_CMDID) \ + OP(WMI_STA_KEEPALIVE_CMDID) \ + OP(WMI_SET_ARP_NS_OFFLOAD_CMDID) \ + OP(WMI_P2P_SET_VENDOR_IE_DATA_CMDID) \ + OP(WMI_AP_PS_PEER_PARAM_CMDID) \ + OP(WMI_WLAN_PROFILE_TRIGGER_CMDID) \ + OP(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID) \ + OP(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID) \ + OP(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID) \ + OP(WMI_WOW_DEL_WAKE_PATTERN_CMDID) \ + OP(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID) \ + OP(WMI_RTT_MEASREQ_CMDID) \ + OP(WMI_RTT_TSF_CMDID) \ + OP(WMI_OEM_REQ_CMDID) \ + OP(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID) \ + OP(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID) \ + OP(WMI_REQUEST_STATS_CMDID) \ + OP(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID) \ + OP(WMI_CSA_OFFLOAD_ENABLE_CMDID) \ + OP(WMI_CSA_OFFLOAD_CHANSWITCH_CMDID) \ + OP(WMI_CHATTER_SET_MODE_CMDID) \ + OP(WMI_ECHO_CMDID) \ + OP(WMI_PDEV_UTF_CMDID) \ + OP(WMI_PDEV_QVIT_CMDID) \ + OP(WMI_VDEV_SET_KEEPALIVE_CMDID) \ + OP(WMI_VDEV_GET_KEEPALIVE_CMDID) \ + OP(WMI_FORCE_FW_HANG_CMDID) \ + OP(WMI_GPIO_CONFIG_CMDID) \ + OP(WMI_GPIO_OUTPUT_CMDID) \ + OP(WMI_PEER_ADD_WDS_ENTRY_CMDID) \ + OP(WMI_PEER_REMOVE_WDS_ENTRY_CMDID) \ + OP(WMI_BCN_TX_CMDID) \ + OP(WMI_PDEV_SEND_BCN_CMDID) \ + OP(WMI_MGMT_TX_CMDID) \ + OP(WMI_ADDBA_CLEAR_RESP_CMDID) \ + OP(WMI_ADDBA_SEND_CMDID) \ + OP(WMI_DELBA_SEND_CMDID) \ + OP(WMI_ADDBA_SET_RESP_CMDID) \ + OP(WMI_SEND_SINGLEAMSDU_CMDID) \ + OP(WMI_PDEV_PKTLOG_ENABLE_CMDID) \ + OP(WMI_PDEV_PKTLOG_DISABLE_CMDID) \ + OP(WMI_PDEV_SET_HT_CAP_IE_CMDID) \ + OP(WMI_PDEV_SET_VHT_CAP_IE_CMDID) \ + OP(WMI_PDEV_SET_DSCP_TID_MAP_CMDID) \ + OP(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID) \ + OP(WMI_PDEV_GET_TPC_CONFIG_CMDID) \ + OP(WMI_PDEV_SET_BASE_MACADDR_CMDID) \ + OP(WMI_PEER_MCAST_GROUP_CMDID) \ + OP(WMI_ROAM_AP_PROFILE) \ + OP(WMI_SCAN_SCH_PRIO_TBL_CMDID) \ + OP(WMI_PDEV_DFS_ENABLE_CMDID) \ + OP(WMI_PDEV_DFS_DISABLE_CMDID) \ + OP(WMI_WOW_ADD_WAKE_PATTERN_CMDID) \ + OP(WMI_PDEV_SUSPEND_CMDID) \ + OP(WMI_PDEV_RESUME_CMDID) \ + OP(WMI_STOP_SCAN_CMDID) \ + OP(WMI_PDEV_SET_PARAM_CMDID) \ + OP(WMI_PDEV_SET_QUIET_MODE_CMDID) \ + OP(WMI_VDEV_CREATE_CMDID) \ + OP(WMI_VDEV_DELETE_CMDID) \ + OP(WMI_VDEV_UP_CMDID) \ + OP(WMI_VDEV_STOP_CMDID) \ + OP(WMI_VDEV_DOWN_CMDID) \ + OP(WMI_VDEV_SET_PARAM_CMDID) \ + OP(WMI_SCAN_UPDATE_REQUEST_CMDID) \ + OP(WMI_CHATTER_ADD_COALESCING_FILTER_CMDID) \ + OP(WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID) \ + OP(WMI_CHATTER_COALESCING_QUERY_CMDID) \ + OP(WMI_TXBF_CMDID) \ + OP(WMI_DBGLOG_CFG_CMDID) \ + OP(WMI_VDEV_WNM_SLEEPMODE_CMDID) \ + OP(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID) \ + OP(WMI_VDEV_WMM_ADDTS_CMDID) \ + OP(WMI_VDEV_WMM_DELTS_CMDID) \ + OP(WMI_VDEV_SET_WMM_PARAMS_CMDID) \ + OP(WMI_VDEV_SET_GTX_PARAMS_CMDID) \ + OP(WMI_TDLS_SET_STATE_CMDID) \ + OP(WMI_TDLS_PEER_UPDATE_CMDID) \ + OP(WMI_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID) \ + OP(WMI_ROAM_CHAN_LIST) \ + OP(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID)\ + OP(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID) \ + OP(WMI_RESMGR_SET_CHAN_LATENCY_CMDID) \ + OP(WMI_BA_REQ_SSN_CMDID) \ + OP(WMI_STA_SMPS_FORCE_MODE_CMDID) \ + OP(WMI_SET_MCASTBCAST_FILTER_CMDID) \ + OP(WMI_P2P_SET_OPPPS_PARAM_CMDID) \ + OP(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID) \ + OP(WMI_STA_SMPS_PARAM_CMDID) \ + OP(WMI_MCC_SCHED_TRAFFIC_STATS_CMDID) \ + OP(WMI_HB_SET_ENABLE_CMDID) \ + OP(WMI_HB_SET_TCP_PARAMS_CMDID) \ + OP(WMI_HB_SET_TCP_PKT_FILTER_CMDID) \ + OP(WMI_HB_SET_UDP_PARAMS_CMDID) \ + OP(WMI_HB_SET_UDP_PKT_FILTER_CMDID) \ + OP(WMI_PEER_INFO_REQ_CMDID) \ + OP(WMI_RMC_SET_MODE_CMDID) \ + OP(WMI_RMC_SET_ACTION_PERIOD_CMDID) \ + OP(WMI_RMC_CONFIG_CMDID) \ + OP(WMI_MHF_OFFLOAD_SET_MODE_CMDID) \ + OP(WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID) \ + OP(WMI_DFS_PHYERR_FILTER_ENA_CMDID) \ + OP(WMI_DFS_PHYERR_FILTER_DIS_CMDID) \ + OP(WMI_BATCH_SCAN_ENABLE_CMDID) \ + OP(WMI_BATCH_SCAN_DISABLE_CMDID) \ + OP(WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID) \ + OP(WMI_THERMAL_MGMT_CMDID) \ + OP(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID) \ + OP(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID) \ + OP(WMI_NAN_CMDID) \ + OP(WMI_MODEM_POWER_STATE_CMDID) \ + OP(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID) \ + OP(WMI_ROAM_SCAN_CMD)\ + OP(WMI_REQUEST_STATS_EXT_CMDID) \ + OP(WMI_OBSS_SCAN_ENABLE_CMDID) \ + OP(WMI_OBSS_SCAN_DISABLE_CMDID)\ + OP(WMI_PDEV_SET_LED_CONFIG_CMDID)\ + OP(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID) \ + OP(WMI_TPC_CHAINMASK_CONFIG_CMDID) \ + OP(WMI_CHAN_AVOID_UPDATE_CMDID) \ + OP(WMI_WOW_IOAC_ADD_KEEPALIVE_CMDID) \ + OP(WMI_WOW_IOAC_DEL_KEEPALIVE_CMDID) \ + OP(WMI_WOW_IOAC_ADD_WAKE_PATTERN_CMDID) \ + OP(WMI_WOW_IOAC_DEL_WAKE_PATTERN_CMDID) \ + OP(WMI_REQUEST_LINK_STATS_CMDID) \ + OP(WMI_START_LINK_STATS_CMDID) \ + OP(WMI_CLEAR_LINK_STATS_CMDID) \ + OP(WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID) \ + OP(WMI_LPI_START_SCAN_CMDID) \ + OP(WMI_LPI_STOP_SCAN_CMDID) \ + OP(WMI_EXTSCAN_START_CMDID) \ + OP(WMI_EXTSCAN_STOP_CMDID) \ + OP(WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID) \ + OP(WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID) \ + OP(WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID) \ + OP(WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID) \ + OP(WMI_EXTSCAN_SET_CAPABILITIES_CMDID) \ + OP(WMI_EXTSCAN_GET_CAPABILITIES_CMDID) \ + OP(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID) \ + OP(WMI_D0_WOW_ENABLE_DISABLE_CMDID) \ + OP(WMI_UNIT_TEST_CMDID) \ + OP(WMI_ROAM_SYNCH_COMPLETE) \ + OP(WMI_EXTWOW_ENABLE_CMDID) \ + OP(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID) \ + OP(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID) \ + OP(WMI_ROAM_SET_RIC_REQUEST_CMDID) \ + OP(WMI_PDEV_GET_TEMPERATURE_CMDID) \ + OP(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID) \ + OP(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID)\ + OP(WMI_SCAN_PROB_REQ_OUI_CMDID) \ + OP(WMI_TDLS_SET_OFFCHAN_MODE_CMDID)\ + OP(WMI_PDEV_SET_LED_FLASHING_CMDID) \ + OP(WMI_ROAM_INVOKE_CMDID) \ + OP(WMI_MDNS_OFFLOAD_ENABLE_CMDID) \ + OP(WMI_MDNS_SET_FQDN_CMDID) \ + OP(WMI_MDNS_SET_RESPONSE_CMDID) \ + OP(WMI_MDNS_GET_STATS_CMDID) \ + OP(WMI_SET_ANTENNA_DIVERSITY_CMDID) \ + OP(WMI_SAP_OFL_ENABLE_CMDID) \ + OP(WMI_APFIND_CMDID) \ + OP(WMI_OCB_SET_SCHED_CMDID) \ + OP(WMI_OCB_SET_CONFIG_CMDID) \ + OP(WMI_OCB_SET_UTC_TIME_CMDID) \ + OP(WMI_OCB_START_TIMING_ADVERT_CMDID) \ + OP(WMI_OCB_STOP_TIMING_ADVERT_CMDID) \ + OP(WMI_OCB_GET_TSF_TIMER_CMDID) \ + OP(WMI_DCC_GET_STATS_CMDID) \ + OP(WMI_DCC_CLEAR_STATS_CMDID) \ + OP(WMI_DCC_UPDATE_NDL_CMDID) \ + OP(WMI_ROAM_FILTER_CMDID) \ + OP(WMI_PASSPOINT_LIST_CONFIG_CMDID) \ + OP(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID) \ + OP(WMI_GET_FW_MEM_DUMP_CMDID) \ + OP(WMI_DEBUG_MESG_FLUSH_CMDID) \ + OP(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID) \ + OP(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID) \ + OP(WMI_VDEV_SET_IE_CMDID) \ + OP(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID) \ + OP(WMI_SOC_SET_PCL_CMDID) \ + OP(WMI_SOC_SET_HW_MODE_CMDID) + +/* + * IMPORTANT: Please add _ALL_ WMI Events Here. + * Otherwise, these WMI TLV Functions will be process them. + */ +#define WMITLV_ALL_EVT_LIST(OP) \ + OP(WMI_SERVICE_READY_EVENTID) \ + OP(WMI_READY_EVENTID) \ + OP(WMI_SCAN_EVENTID) \ + OP(WMI_PDEV_TPC_CONFIG_EVENTID) \ + OP(WMI_CHAN_INFO_EVENTID) \ + OP(WMI_PHYERR_EVENTID) \ + OP(WMI_VDEV_START_RESP_EVENTID) \ + OP(WMI_VDEV_STOPPED_EVENTID) \ + OP(WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID) \ + OP(WMI_PEER_STA_KICKOUT_EVENTID) \ + OP(WMI_MGMT_RX_EVENTID) \ + OP(WMI_TBTTOFFSET_UPDATE_EVENTID) \ + OP(WMI_TX_DELBA_COMPLETE_EVENTID) \ + OP(WMI_TX_ADDBA_COMPLETE_EVENTID) \ + OP(WMI_ROAM_EVENTID) \ + OP(WMI_WOW_WAKEUP_HOST_EVENTID) \ + OP(WMI_RTT_ERROR_REPORT_EVENTID) \ + OP(WMI_OEM_MEASUREMENT_REPORT_EVENTID) \ + OP(WMI_OEM_ERROR_REPORT_EVENTID) \ + OP(WMI_OEM_CAPABILITY_EVENTID) \ + OP(WMI_ECHO_EVENTID) \ + OP(WMI_PDEV_FTM_INTG_EVENTID) \ + OP(WMI_VDEV_GET_KEEPALIVE_EVENTID) \ + OP(WMI_GPIO_INPUT_EVENTID) \ + OP(WMI_CSA_HANDLING_EVENTID) \ + OP(WMI_DEBUG_MESG_EVENTID) \ + OP(WMI_GTK_OFFLOAD_STATUS_EVENTID) \ + OP(WMI_DCS_INTERFERENCE_EVENTID) \ + OP(WMI_WLAN_PROFILE_DATA_EVENTID) \ + OP(WMI_PDEV_UTF_EVENTID) \ + OP(WMI_DEBUG_PRINT_EVENTID) \ + OP(WMI_RTT_MEASUREMENT_REPORT_EVENTID) \ + OP(WMI_HOST_SWBA_EVENTID) \ + OP(WMI_UPDATE_STATS_EVENTID) \ + OP(WMI_PDEV_QVIT_EVENTID) \ + OP(WMI_WLAN_FREQ_AVOID_EVENTID) \ + OP(WMI_GTK_REKEY_FAIL_EVENTID) \ + OP(WMI_NLO_MATCH_EVENTID) \ + OP(WMI_NLO_SCAN_COMPLETE_EVENTID) \ + OP(WMI_APFIND_EVENTID) \ + OP(WMI_CHATTER_PC_QUERY_EVENTID) \ + OP(WMI_UPLOADH_EVENTID) \ + OP(WMI_CAPTUREH_EVENTID) \ + OP(WMI_TDLS_PEER_EVENTID) \ + OP(WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID) \ + OP(WMI_BA_RSP_SSN_EVENTID) \ + OP(WMI_OFFLOAD_BCN_TX_STATUS_EVENTID) \ + OP(WMI_P2P_NOA_EVENTID) \ + OP(WMI_TX_PAUSE_EVENTID) \ + OP(WMI_RFKILL_STATE_CHANGE_EVENTID) \ + OP(WMI_PEER_INFO_EVENTID) \ + OP(WMI_PEER_TX_FAIL_CNT_THR_EVENTID) \ + OP(WMI_DFS_RADAR_EVENTID) \ + OP(WMI_BATCH_SCAN_ENABLED_EVENTID) \ + OP(WMI_BATCH_SCAN_RESULT_EVENTID) \ + OP(WMI_THERMAL_MGMT_EVENTID) \ + OP(WMI_NAN_EVENTID) \ + OP(WMI_PDEV_L1SS_TRACK_EVENTID) \ + OP(WMI_DIAG_DATA_CONTAINER_EVENTID) \ + OP(WMI_PEER_ESTIMATED_LINKSPEED_EVENTID) \ + OP(WMI_AGGR_STATE_TRIG_EVENTID)\ + OP(WMI_STATS_EXT_EVENTID) \ + OP(WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID) \ + OP(WMI_HOST_AUTO_SHUTDOWN_EVENTID) \ + OP(WMI_UPDATE_WHAL_MIB_STATS_EVENTID) \ + OP(WMI_IFACE_LINK_STATS_EVENTID) \ + OP(WMI_PEER_LINK_STATS_EVENTID) \ + OP(WMI_RADIO_LINK_STATS_EVENTID) \ + OP(WMI_LPI_RESULT_EVENTID) \ + OP(WMI_PEER_STATE_EVENTID) \ + OP(WMI_EXTSCAN_START_STOP_EVENTID) \ + OP(WMI_EXTSCAN_OPERATION_EVENTID) \ + OP(WMI_EXTSCAN_TABLE_USAGE_EVENTID) \ + OP(WMI_EXTSCAN_CACHED_RESULTS_EVENTID) \ + OP(WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID) \ + OP(WMI_EXTSCAN_HOTLIST_MATCH_EVENTID) \ + OP(WMI_EXTSCAN_CAPABILITIES_EVENTID) \ + OP(WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID) \ + OP(WMI_D0_WOW_DISABLE_ACK_EVENTID) \ + OP(WMI_ROAM_SYNCH_EVENTID) \ + OP(WMI_LPI_STATUS_EVENTID) \ + OP(WMI_LPI_HANDOFF_EVENTID) \ + OP(WMI_UPDATE_VDEV_RATE_STATS_EVENTID) \ + OP(WMI_PDEV_TEMPERATURE_EVENTID) \ + OP(WMI_DIAG_EVENTID) \ + OP(WMI_MDNS_STATS_EVENTID) \ + OP(WMI_PDEV_RESUME_EVENTID) \ + OP(WMI_SAP_OFL_ADD_STA_EVENTID) \ + OP(WMI_SAP_OFL_DEL_STA_EVENTID) \ + OP(WMI_OCB_SET_SCHED_EVENTID) \ + OP(WMI_OCB_SET_CONFIG_RESP_EVENTID) \ + OP(WMI_OCB_GET_TSF_TIMER_RESP_EVENTID) \ + OP(WMI_DCC_GET_STATS_RESP_EVENTID) \ + OP(WMI_DCC_UPDATE_NDL_RESP_EVENTID) \ + OP(WMI_DCC_STATS_EVENTID) \ + OP(WMI_PASSPOINT_MATCH_EVENTID) \ + OP(WMI_VDEV_TSF_REPORT_EVENTID) \ + OP(WMI_UPDATE_FW_MEM_DUMP_EVENTID) \ + OP(WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID) \ + OP(WMI_RSSI_BREACH_EVENTID)\ + OP(WMI_WOW_INITIAL_WAKEUP_EVENTID) \ + OP(WMI_SOC_SET_HW_MODE_RESP_EVENTID) \ + OP(WMI_SOC_HW_MODE_TRANSITION_EVENTID) + +/* TLV definitions of WMI commands */ + +/* Init Cmd */ +#define WMITLV_TABLE_WMI_INIT_CMDID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, wmi_init_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_resource_config, wmi_resource_config, resource_config, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wlan_host_memory_chunk, host_mem_chunks, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_INIT_CMDID); + +/* Peer create Cmd */ +#define WMITLV_TABLE_WMI_PEER_CREATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, wmi_peer_create_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_CREATE_CMDID); + +/* Peer delete Cmd */ +#define WMITLV_TABLE_WMI_PEER_DELETE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, wmi_peer_delete_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_DELETE_CMDID); + +/* Peer flush Cmd*/ +#define WMITLV_TABLE_WMI_PEER_FLUSH_TIDS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, wmi_peer_flush_tids_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_FLUSH_TIDS_CMDID); + +/* Peer Set Param Cmd */ +#define WMITLV_TABLE_WMI_PEER_SET_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, wmi_peer_set_param_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_SET_PARAM_CMDID); + +/* STA Powersave Mode Cmd */ +#define WMITLV_TABLE_WMI_STA_POWERSAVE_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, wmi_sta_powersave_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_POWERSAVE_MODE_CMDID); + +/* STA Powersave Param Cmd */ +#define WMITLV_TABLE_WMI_STA_POWERSAVE_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, wmi_sta_powersave_param_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_POWERSAVE_PARAM_CMDID); + +/* STA DTIM PS METHOD Cmd */ +#define WMITLV_TABLE_WMI_STA_DTIM_PS_METHOD_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_dtim_ps_method_cmd_fixed_param, wmi_sta_dtim_ps_method_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_DTIM_PS_METHOD_CMDID); + +/* Pdev Set Reg Domain Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_REGDOMAIN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, wmi_pdev_set_regdomain_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_REGDOMAIN_CMDID); + + +/* Peer TID ADD BA Cmd */ +#define WMITLV_TABLE_WMI_PEER_TID_ADDBA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_tid_addba_cmd_fixed_param, wmi_peer_tid_addba_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_TID_ADDBA_CMDID); + +/* Peer TID DEL BA Cmd */ +#define WMITLV_TABLE_WMI_PEER_TID_DELBA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_tid_delba_cmd_fixed_param, wmi_peer_tid_delba_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_TID_DELBA_CMDID); +/* Peer Req Add BA Ssn for staId/tid pair Cmd */ +#define WMITLV_TABLE_WMI_BA_REQ_SSN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ba_req_ssn_cmd_fixed_param, wmi_ba_req_ssn_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len,WMITLV_TAG_ARRAY_STRUC, wmi_ba_req_ssn, ba_req_ssn_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_BA_REQ_SSN_CMDID); + +/* PDEV FTM integration Cmd */ +#define WMITLV_TABLE_WMI_PDEV_FTM_INTG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ftm_intg_cmd_fixed_param, wmi_ftm_intg_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_FTM_INTG_CMDID); + +/* WOW Wakeup from sleep Cmd */ +#define WMITLV_TABLE_WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); + +/* WOW Enable Cmd */ +#define WMITLV_TABLE_WMI_WOW_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, wmi_wow_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_ENABLE_CMDID); + +/* Remove Bcn Filter Cmd */ +#define WMITLV_TABLE_WMI_RMV_BCN_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param, wmi_rmv_bcn_filter_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_RMV_BCN_FILTER_CMDID); + +/** Service bit WMI_SERVICE_ROAM_OFFLOAD for Roaming feature */ +/* Roam scan mode Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SCAN_MODE(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, wmi_roam_scan_mode_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, wmi_start_scan_cmd_fixed_param, scan_params, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_offload_tlv_param, offload_param, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_11i_offload_tlv_param, offload_11i_param, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_11r_offload_tlv_param, offload_11r_param, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_ese_offload_tlv_param, offload_ese_param, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SCAN_MODE); + +/* Roam scan Rssi Threshold Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SCAN_RSSI_THRESHOLD(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, wmi_roam_scan_rssi_threshold_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_roam_scan_extended_threshold_param, extended_param, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SCAN_RSSI_THRESHOLD); + +/* Roam Scan Period Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SCAN_PERIOD(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, wmi_roam_scan_period_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SCAN_PERIOD); + +/* Roam scan change Rssi Threshold Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, wmi_roam_scan_rssi_change_threshold_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); +/* Roam Scan Channel list Cmd */ +#define WMITLV_TABLE_WMI_ROAM_CHAN_LIST(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, wmi_roam_chan_list_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_CHAN_LIST); + +/* Roam scan mode Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SCAN_CMD(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, wmi_roam_scan_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SCAN_CMD); + + +#define WMITLV_TABLE_WMI_VDEV_PLMREQ_START_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, wmi_vdev_plmreq_start_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_PLMREQ_START_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_PLMREQ_STOP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, wmi_vdev_plmreq_stop_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_PLMREQ_STOP_CMDID); + +/* Start scan Cmd */ +#define WMITLV_TABLE_WMI_START_SCAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, wmi_start_scan_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_ssid, ssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_START_SCAN_CMDID); + +/* Start ExtScan Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_START_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, wmi_extscan_start_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_ssid, ssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_bucket, bucket_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_bucket_channel, channel_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_START_CMDID); + +/* Stop ExtScan Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_STOP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, wmi_extscan_stop_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_STOP_CMDID); + +/* Start ExtScan BSSID Monitoring Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_change_bssid_param, wlan_change_descriptor_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID); + +/* Start Hot List Monitoring Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_hotlist_entry, hotlist, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID); + +/* Get ExtScan BSSID/RSSI list Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, wmi_extscan_get_cached_results_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID); + +/* Get ExtScan BSSID monitor results Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_get_wlan_change_results_cmd_fixed_param, wmi_extscan_get_wlan_change_results_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID); + +/* Set ExtScan Capabilities Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_SET_CAPABILITIES_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_set_capabilities_cmd_fixed_param, wmi_extscan_set_capabilities_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_cache_capabilities, extscan_cache_capabilities, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_change_monitor_capabilities, wlan_change_capabilities, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_hotlist_monitor_capabilities, hotlist_capabilities, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_SET_CAPABILITIES_CMDID); + +/* Get ExtScan Capabilities Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_GET_CAPABILITIES_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, wmi_extscan_get_capabilities_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_GET_CAPABILITIES_CMDID); + +/* Start SSID Hot List Monitoring Cmd */ +#define WMITLV_TABLE_WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_hotlist_ssid_entry, hotlist_ssid, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID); + +/* P2P set vendor ID data Cmd */ +#define WMITLV_TABLE_WMI_P2P_SET_VENDOR_IE_DATA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_set_vendor_ie_data_cmd_fixed_param, wmi_p2p_set_vendor_ie_data_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_P2P_SET_VENDOR_IE_DATA_CMDID); +/* P2P set OppPS parameters Cmd */ +#define WMITLV_TABLE_WMI_P2P_SET_OPPPS_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, wmi_p2p_set_oppps_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_P2P_SET_OPPPS_PARAM_CMDID); + +/* Pdev set channel Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_CHANNEL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_channel, wmi_channel, chan, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_CHANNEL_CMDID); + +/* Echo Cmd */ +#define WMITLV_TABLE_WMI_ECHO_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_echo_cmd_fixed_param, wmi_echo_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_ECHO_CMDID); + +/* Pdev set wmm params */ +#define WMITLV_TABLE_WMI_PDEV_SET_WMM_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param, wmi_pdev_set_wmm_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wmm_params, wmi_wmm_params, wmm_params_ac_be, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wmm_params, wmi_wmm_params, wmm_params_ac_bk, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wmm_params, wmi_wmm_params, wmm_params_ac_vi, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wmm_params, wmi_wmm_params, wmm_params_ac_vo, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_WMM_PARAMS_CMDID); + +/* Vdev start request Cmd */ +#define WMITLV_TABLE_WMI_VDEV_START_REQUEST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, wmi_vdev_start_request_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_channel, wmi_channel, chan, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_p2p_noa_descriptor, noa_descriptors, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_START_REQUEST_CMDID); + +/* Vdev restart request cmd */ +#define WMITLV_TABLE_WMI_VDEV_RESTART_REQUEST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, wmi_vdev_start_request_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_channel, wmi_channel, chan, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_p2p_noa_descriptor, noa_descriptors, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_RESTART_REQUEST_CMDID); + +/* P2P Go set beacon IE cmd */ +#define WMITLV_TABLE_WMI_P2P_GO_SET_BEACON_IE(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, wmi_p2p_go_set_beacon_ie_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_P2P_GO_SET_BEACON_IE); + +/* GTK offload Cmd */ +#define WMITLV_TABLE_WMI_GTK_OFFLOAD_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, WMI_GTK_OFFLOAD_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_GTK_OFFLOAD_CMDID); + +/* Scan channel list Cmd */ +#define WMITLV_TABLE_WMI_SCAN_CHAN_LIST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, wmi_scan_chan_list_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_channel, chan_info, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_CHAN_LIST_CMDID); + +/* STA UAPSD Auto trigger Cmd */ +#define WMITLV_TABLE_WMI_STA_UAPSD_AUTO_TRIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, wmi_sta_uapsd_auto_trig_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_sta_uapsd_auto_trig_param, ac_param, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_UAPSD_AUTO_TRIG_CMDID); + +/* Probe template Cmd */ +#define WMITLV_TABLE_WMI_PRB_TMPL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, wmi_prb_tmpl_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bcn_prb_info, wmi_bcn_prb_info, bcn_prb_info, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_PRB_TMPL_CMDID); + +/* Beacon template Cmd */ +#define WMITLV_TABLE_WMI_BCN_TMPL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, wmi_bcn_tmpl_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bcn_prb_info, wmi_bcn_prb_info, bcn_prb_info, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_BCN_TMPL_CMDID); + +/* VDEV install key complete Cmd */ +#define WMITLV_TABLE_WMI_VDEV_INSTALL_KEY_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, wmi_vdev_install_key_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, key_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_INSTALL_KEY_CMDID); +/* VDEV WNM SLEEP MODE Cmd */ +#define WMITLV_TABLE_WMI_VDEV_WNM_SLEEPMODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_VDEV_WNM_SLEEPMODE_CMD_fixed_param, WMI_VDEV_WNM_SLEEPMODE_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_WNM_SLEEPMODE_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID); + +/* Peer Assoc Cmd */ +#define WMITLV_TABLE_WMI_PEER_ASSOC_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, wmi_peer_assoc_complete_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, peer_legacy_rates, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, peer_ht_rates, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vht_rate_set, wmi_vht_rate_set, peer_vht_rates, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ASSOC_CMDID); + +/* Peer Set Rate Report Condition Cmd */ +#define WMITLV_TABLE_WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_set_rate_report_condition_fixed_param, wmi_peer_set_rate_report_condition_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); + + +/* Add Beacon filter Cmd */ +#define WMITLV_TABLE_WMI_ADD_BCN_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param, wmi_add_bcn_filter_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, ie_map, WMITLV_SIZE_FIX, BCN_FLT_MAX_ELEMS_IE_LIST) + +WMITLV_CREATE_PARAM_STRUC(WMI_ADD_BCN_FILTER_CMDID); + +/* Sta keepalive cmd */ +#define WMITLV_TABLE_WMI_STA_KEEPALIVE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, WMI_STA_KEEPALIVE_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, WMI_STA_KEEPALVE_ARP_RESPONSE, arp_resp, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_KEEPALIVE_CMDID); + +/* ARP NS offload Cmd */ +#define WMITLV_TABLE_WMI_SET_ARP_NS_OFFLOAD_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_NS_OFFLOAD_TUPLE, ns_tuples, WMITLV_SIZE_FIX, WMI_MAX_NS_OFFLOADS) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_ARP_OFFLOAD_TUPLE, arp_tuples, WMITLV_SIZE_FIX, WMI_MAX_ARP_OFFLOADS) + +WMITLV_CREATE_PARAM_STRUC(WMI_SET_ARP_NS_OFFLOAD_CMDID); + +/* AP PS peer param Cmd */ +#define WMITLV_TABLE_WMI_AP_PS_PEER_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, wmi_ap_ps_peer_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_AP_PS_PEER_PARAM_CMDID); + +/* Profile Trigger Cmd */ +#define WMITLV_TABLE_WMI_WLAN_PROFILE_TRIGGER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param, wmi_wlan_profile_trigger_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_PROFILE_TRIGGER_CMDID); + +/* WLAN Profile set hist interval Cmd */ +#define WMITLV_TABLE_WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, wmi_wlan_profile_set_hist_intvl_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); + +/* WLAN Profile get profile data Cmd */ +#define WMITLV_TABLE_WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param, wmi_wlan_profile_get_prof_data_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); + +/* WLAN Profile enable profile ID Cmd */ +#define WMITLV_TABLE_WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param, wmi_wlan_profile_enable_profile_id_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); + +/* WOW Delete Wake Pattern Cmd */ +#define WMITLV_TABLE_WMI_WOW_DEL_WAKE_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, WMI_WOW_DEL_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_DEL_WAKE_PATTERN_CMDID); + +/* Wow enable/disable wake up Cmd */ +#define WMITLV_TABLE_WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); + +/* RTT measurement request Cmd */ +#define WMITLV_TABLE_WMI_RTT_MEASREQ_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_RTT_MEASREQ_CMDID); + +/* RTT TSF Cmd */ +#define WMITLV_TABLE_WMI_RTT_TSF_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_RTT_TSF_CMDID); + +/*RTT OEM req Cmd */ +#define WMITLV_TABLE_WMI_OEM_REQ_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_OEM_REQ_CMDID); + +/* Spectral scan configure Cmd */ +#define WMITLV_TABLE_WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param, wmi_vdev_spectral_configure_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); + +/* Spectral scan enable Cmd */ +#define WMITLV_TABLE_WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param, wmi_vdev_spectral_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); + +/* Request stats Cmd */ +#define WMITLV_TABLE_WMI_REQUEST_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, wmi_request_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_REQUEST_STATS_CMDID); + + +/* Request for memory dump stats Cmd */ +#define WMITLV_TABLE_WMI_GET_FW_MEM_DUMP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_get_fw_mem_dump_fixed_param, wmi_get_fw_mem_dump_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_fw_mem_dump, fw_mem_dump_params, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_GET_FW_MEM_DUMP_CMDID); + +/* flush debug messages */ +#define WMITLV_TABLE_WMI_DEBUG_MESG_FLUSH_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param, wmi_debug_mesg_flush_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_DEBUG_MESG_FLUSH_CMDID); + + + +/* Set config params */ +#define WMITLV_TABLE_WMI_START_LINK_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, wmi_start_link_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_START_LINK_STATS_CMDID); + +/* Request to clear link stats */ +#define WMITLV_TABLE_WMI_CLEAR_LINK_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, wmi_clear_link_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_CLEAR_LINK_STATS_CMDID); + +/* Request Link stats Cmd */ +#define WMITLV_TABLE_WMI_REQUEST_LINK_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, wmi_request_link_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_REQUEST_LINK_STATS_CMDID); + +/* Network list offload config Cmd */ +#define WMITLV_TABLE_WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, wmi_nlo_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, nlo_configured_parameters, nlo_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); + +/* Passpoint list offload config Cmd */ +#define WMITLV_TABLE_WMI_PASSPOINT_LIST_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_passpoint_config_cmd_fixed_param, wmi_passpoint_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PASSPOINT_LIST_CONFIG_CMDID); + +/* CSA offload enable Cmd */ +#define WMITLV_TABLE_WMI_CSA_OFFLOAD_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, wmi_csa_offload_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_CSA_OFFLOAD_ENABLE_CMDID); + +/* CSA offload channel switch Cmd */ +#define WMITLV_TABLE_WMI_CSA_OFFLOAD_CHANSWITCH_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_csa_offload_chanswitch_cmd_fixed_param, wmi_csa_offload_chanswitch_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_channel, wmi_channel, chan, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_CSA_OFFLOAD_CHANSWITCH_CMDID); + +/* Chatter set mode Cmd */ +#define WMITLV_TABLE_WMI_CHATTER_SET_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chatter_set_mode_cmd_fixed_param, wmi_chatter_set_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_CHATTER_SET_MODE_CMDID); + + +/* PDEV UTF Cmd */ +#define WMITLV_TABLE_WMI_PDEV_UTF_CMDID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_UTF_CMDID); + +/* PDEV QVIT Cmd */ +#define WMITLV_TABLE_WMI_PDEV_QVIT_CMDID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_QVIT_CMDID); + +/* Vdev Set keep alive Cmd */ +#define WMITLV_TABLE_WMI_VDEV_SET_KEEPALIVE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_set_keepalive_cmd_fixed_param, wmi_vdev_set_keepalive_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_KEEPALIVE_CMDID); + +/* Vdev Get keep alive Cmd */ +#define WMITLV_TABLE_WMI_VDEV_GET_KEEPALIVE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_cmd_fixed_param, wmi_vdev_get_keepalive_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_GET_KEEPALIVE_CMDID); +/*FWTEST Set TBTT mode Cmd*/ +#define WMITLV_TABLE_WMI_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_mcc_set_tbtt_mode_cmd_fixed_param, wmi_vdev_mcc_set_tbtt_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID); + +/* FWTEST set NoA parameters Cmd */ +#define WMITLV_TABLE_WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, wmi_p2p_set_noa_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_p2p_noa_descriptor, noa_descriptor, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); + +/* Unit test FW */ +#define WMITLV_TABLE_WMI_UNIT_TEST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, wmi_unit_test_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, args, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_UNIT_TEST_CMDID); + +/* Force Fw Hang Cmd */ +#define WMITLV_TABLE_WMI_FORCE_FW_HANG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, WMI_FORCE_FW_HANG_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_FORCE_FW_HANG_CMDID); +/* Set Mcast address Cmd */ +#define WMITLV_TABLE_WMI_SET_MCASTBCAST_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SET_MCASTBCAST_FILTER_CMDID); + +/* GPIO config Cmd */ +#define WMITLV_TABLE_WMI_GPIO_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param, wmi_gpio_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_GPIO_CONFIG_CMDID); + +/* GPIO output Cmd */ +#define WMITLV_TABLE_WMI_GPIO_OUTPUT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param, wmi_gpio_output_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_GPIO_OUTPUT_CMDID); + +/* Peer add WDA entry Cmd */ +#define WMITLV_TABLE_WMI_PEER_ADD_WDS_ENTRY_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, wmi_peer_add_wds_entry_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ADD_WDS_ENTRY_CMDID); + +/*Peer remove WDS entry Cmd */ +#define WMITLV_TABLE_WMI_PEER_REMOVE_WDS_ENTRY_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, wmi_peer_remove_wds_entry_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_REMOVE_WDS_ENTRY_CMDID); + +/* Beacon tx Cmd */ +#define WMITLV_TABLE_WMI_BCN_TX_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bcn_tx_hdr, wmi_bcn_tx_hdr, hdr, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_BCN_TX_CMDID); + +/* PDEV send Beacon Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SEND_BCN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, wmi_bcn_send_from_host_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SEND_BCN_CMDID); + +/* Management tx Cmd */ +#define WMITLV_TABLE_WMI_MGMT_TX_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mgmt_tx_hdr, wmi_mgmt_tx_hdr, hdr, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_MGMT_TX_CMDID); + +/* ADD clear response Cmd */ +#define WMITLV_TABLE_WMI_ADDBA_CLEAR_RESP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param, wmi_addba_clear_resp_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ADDBA_CLEAR_RESP_CMDID); + +/* ADD BA send Cmd */ +#define WMITLV_TABLE_WMI_ADDBA_SEND_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param, wmi_addba_send_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ADDBA_SEND_CMDID); + +/* DEL BA send Cmd */ +#define WMITLV_TABLE_WMI_DELBA_SEND_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param, wmi_delba_send_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_DELBA_SEND_CMDID); + +/* ADD BA set response Cmd */ +#define WMITLV_TABLE_WMI_ADDBA_SET_RESP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_addba_setresponse_cmd_fixed_param, wmi_addba_setresponse_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ADDBA_SET_RESP_CMDID); + +/* Send single AMSDU Cmd */ +#define WMITLV_TABLE_WMI_SEND_SINGLEAMSDU_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_send_singleamsdu_cmd_fixed_param, wmi_send_singleamsdu_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_SEND_SINGLEAMSDU_CMDID); + +/* PDev Packet Log enable Cmd */ +#define WMITLV_TABLE_WMI_PDEV_PKTLOG_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, wmi_pdev_pktlog_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_PKTLOG_ENABLE_CMDID); + +/* PDev Packet Log disable Cmd */ +#define WMITLV_TABLE_WMI_PDEV_PKTLOG_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, wmi_pdev_pktlog_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_PKTLOG_DISABLE_CMDID); + +/* PDev set HT Cap IE Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_HT_CAP_IE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param, wmi_pdev_set_ht_ie_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_HT_CAP_IE_CMDID); + +/* PDev set VHT Cap IE Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_VHT_CAP_IE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param, wmi_pdev_set_vht_ie_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_VHT_CAP_IE_CMDID); + +/* PDev Set DSCP to TID map Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_DSCP_TID_MAP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_dscp_tid_map_cmd_fixed_param, wmi_pdev_set_dscp_tid_map_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_DSCP_TID_MAP_CMDID); + +/* PDev Green AP PS enable Cmd */ +#define WMITLV_TABLE_WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, wmi_pdev_green_ap_ps_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID); + +/* PDEV Get TPC Config Cmd */ +#define WMITLV_TABLE_WMI_PDEV_GET_TPC_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param, wmi_pdev_get_tpc_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_GET_TPC_CONFIG_CMDID); + +/* PDEV Set Base Mac Address Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_BASE_MACADDR_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, wmi_pdev_set_base_macaddr_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_BASE_MACADDR_CMDID); + +/* Peer multicast group Cmd */ +#define WMITLV_TABLE_WMI_PEER_MCAST_GROUP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param, wmi_peer_mcast_group_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_MCAST_GROUP_CMDID); + +/* Roam AP profile Cmd */ +#define WMITLV_TABLE_WMI_ROAM_AP_PROFILE(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, wmi_roam_ap_profile_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ap_profile, wmi_ap_profile, ap_profile, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_AP_PROFILE); + +/* Roam sync complete Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SYNCH_COMPLETE(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, wmi_roam_synch_complete_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SYNCH_COMPLETE); + +#define WMITLV_TABLE_WMI_ROAM_SET_RIC_REQUEST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, wmi_ric_request_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ric_tspec, ric_tspec_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SET_RIC_REQUEST_CMDID); + +/* Scan scheduler priority Table Cmd */ +#define WMITLV_TABLE_WMI_SCAN_SCH_PRIO_TBL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_scan_sch_priority_table_cmd_fixed_param, wmi_scan_sch_priority_table_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, mapping_table, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_SCH_PRIO_TBL_CMDID); + +/* PDEV DFS enable Cmd */ +#define WMITLV_TABLE_WMI_PDEV_DFS_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param, wmi_pdev_dfs_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_DFS_ENABLE_CMDID); + +/* PDEV DFS disable Cmd */ +#define WMITLV_TABLE_WMI_PDEV_DFS_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param, wmi_pdev_dfs_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_DFS_DISABLE_CMDID); + +/* DFS phyerr parse/filter offload enable Cmd */ +#define WMITLV_TABLE_WMI_DFS_PHYERR_FILTER_ENA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, wmi_dfs_phyerr_filter_ena_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_DFS_PHYERR_FILTER_ENA_CMDID); + +/* DFS phyerr parse/filter offload disable Cmd */ +#define WMITLV_TABLE_WMI_DFS_PHYERR_FILTER_DIS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, wmi_dfs_phyerr_filter_dis_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_DFS_PHYERR_FILTER_DIS_CMDID); + +/* WOW Add Wake Pattern Cmd */ +#define WMITLV_TABLE_WMI_WOW_ADD_WAKE_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, WMI_WOW_ADD_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_BITMAP_PATTERN_T, pattern_info_bitmap, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_IPV4_SYNC_PATTERN_T, pattern_info_ipv4, WMITLV_SIZE_VAR)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_IPV6_SYNC_PATTERN_T, pattern_info_ipv6, WMITLV_SIZE_VAR)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_MAGIC_PATTERN_CMD, pattern_info_magic_pattern, WMITLV_SIZE_VAR)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, pattern_info_timeout, WMITLV_SIZE_VAR) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, ra_ratelimit_interval, WMITLV_SIZE_FIX, 1) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_ADD_WAKE_PATTERN_CMDID); + +/* IOAC add keep alive cmd. */ +#define WMITLV_TABLE_WMI_WOW_IOAC_ADD_KEEPALIVE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_KEEPALIVE_CMD_fixed_param, WMI_WOW_IOAC_ADD_KEEPALIVE_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_WOW_IOAC_KEEPALIVE_T, keepalive_set, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_IOAC_ADD_KEEPALIVE_CMDID); + +/* IOAC del keep alive cmd. */ +#define WMITLV_TABLE_WMI_WOW_IOAC_DEL_KEEPALIVE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_KEEPALIVE_CMD_fixed_param, WMI_WOW_IOAC_DEL_KEEPALIVE_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_IOAC_DEL_KEEPALIVE_CMDID); + +/* WOW IOAC Add Wake Pattern Cmd */ +#define WMITLV_TABLE_WMI_WOW_IOAC_ADD_WAKE_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_PATTERN_CMD_fixed_param, WMI_WOW_IOAC_ADD_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_IOAC_PKT_PATTERN_T, pattern_info_pkt, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_IOAC_TMR_PATTERN_T, pattern_info_tmr, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_IOAC_ADD_WAKE_PATTERN_CMDID); + +/* WOW IOAC Delete Wake Pattern Cmd */ +#define WMITLV_TABLE_WMI_WOW_IOAC_DEL_WAKE_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_PATTERN_CMD_fixed_param, WMI_WOW_IOAC_DEL_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_IOAC_DEL_WAKE_PATTERN_CMDID); + +/* extwow enable Cmd */ +#define WMITLV_TABLE_WMI_EXTWOW_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, wmi_extwow_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTWOW_ENABLE_CMDID); + +/* extwow set wakeup params cmd for app type1 */ +#define WMITLV_TABLE_WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, wmi_extwow_set_app_type1_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); + +/* extwow set wakeup params cmd for app type2 */ +#define WMITLV_TABLE_WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, wmi_extwow_set_app_type2_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); + +/* Stop scan Cmd */ +#define WMITLV_TABLE_WMI_STOP_SCAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, wmi_stop_scan_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STOP_SCAN_CMDID); + +#define WMITLV_TABLE_WMI_PDEV_SET_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, wmi_pdev_set_param_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_PARAM_CMDID); + +/* PDev set quiet Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_QUIET_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param, wmi_pdev_set_quiet_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_QUIET_MODE_CMDID); + +/* Vdev create Cmd */ +#define WMITLV_TABLE_WMI_VDEV_CREATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, wmi_vdev_create_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_CREATE_CMDID); + +/* Vdev delete Cmd */ +#define WMITLV_TABLE_WMI_VDEV_DELETE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, wmi_vdev_delete_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_DELETE_CMDID); + +/* Vdev up Cmd */ +#define WMITLV_TABLE_WMI_VDEV_UP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, wmi_vdev_up_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_UP_CMDID); + +/* Vdev stop cmd */ +#define WMITLV_TABLE_WMI_VDEV_STOP_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, wmi_vdev_stop_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_STOP_CMDID); + +/* Vdev down Cmd */ +#define WMITLV_TABLE_WMI_VDEV_DOWN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, wmi_vdev_down_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_DOWN_CMDID); + +/* Vdev set param Cmd */ +#define WMITLV_TABLE_WMI_VDEV_SET_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, wmi_vdev_set_param_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_PARAM_CMDID); + +/* Pdev suspend Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SUSPEND_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, wmi_pdev_suspend_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SUSPEND_CMDID); + +/* Pdev Resume Cmd */ +#define WMITLV_TABLE_WMI_PDEV_RESUME_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, wmi_pdev_resume_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_RESUME_CMDID); + +#define WMITLV_TABLE_WMI_SCAN_UPDATE_REQUEST_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_scan_update_request_cmd_fixed_param, wmi_scan_update_request_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_UPDATE_REQUEST_CMDID); + +#define WMITLV_TABLE_WMI_SCAN_PROB_REQ_OUI_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, wmi_scan_prob_req_oui_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_PROB_REQ_OUI_CMDID); + +#define WMITLV_TABLE_WMI_CHATTER_ADD_COALESCING_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len,WMITLV_TAG_STRUC_wmi_chatter_coalescing_add_filter_cmd_fixed_param, wmi_chatter_coalescing_add_filter_cmd_fixed_param, fixed_param,WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, chatter_pkt_coalescing_filter, coalescing_filter, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_CHATTER_ADD_COALESCING_FILTER_CMDID); + +#define WMITLV_TABLE_WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chatter_coalescing_delete_filter_cmd_fixed_param,wmi_chatter_coalescing_delete_filter_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + +WMITLV_CREATE_PARAM_STRUC(WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID); + +#define WMITLV_TABLE_WMI_CHATTER_COALESCING_QUERY_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chatter_coalescing_query_cmd_fixed_param, wmi_chatter_coalescing_query_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + +WMITLV_CREATE_PARAM_STRUC(WMI_CHATTER_COALESCING_QUERY_CMDID); + +#define WMITLV_TABLE_WMI_TXBF_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len,WMITLV_TAG_STRUC_wmi_txbf_cmd_fixed_param, wmi_txbf_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + +WMITLV_CREATE_PARAM_STRUC(WMI_TXBF_CMDID); + +#define WMITLV_TABLE_WMI_DBGLOG_CFG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, wmi_debug_log_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_FXAR(id,op,buf,len,WMITLV_TAG_ARRAY_UINT32, A_UINT32, module_id_bitmap, WMITLV_SIZE_FIX, MAX_MODULE_ID_BITMAP_WORDS) \ + +WMITLV_CREATE_PARAM_STRUC(WMI_DBGLOG_CFG_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_WMM_ADDTS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, wmi_vdev_wmm_addts_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_WMM_ADDTS_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_WMM_DELTS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, wmi_vdev_wmm_delts_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_WMM_DELTS_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_SET_WMM_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, wmi_vdev_set_wmm_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_WMM_PARAMS_CMDID); + +#define WMITLV_TABLE_WMI_VDEV_SET_GTX_PARAMS_CMDID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, wmi_vdev_set_gtx_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_GTX_PARAMS_CMDID); + +/* TDLS Enable/Disable Cmd */ +#define WMITLV_TABLE_WMI_TDLS_SET_STATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, \ + wmi_tdls_set_state_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_SET_STATE_CMDID); + +/* TDLS Peer Update Cmd */ +#define WMITLV_TABLE_WMI_TDLS_PEER_UPDATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, wmi_tdls_peer_update_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, wmi_tdls_peer_capabilities, peer_caps, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_channel, peer_chan_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_PEER_UPDATE_CMDID); + +/* Enable/Disable TDLS Offchannel Cmd */ +#define WMITLV_TABLE_WMI_TDLS_SET_OFFCHAN_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, \ + wmi_tdls_set_offchan_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_SET_OFFCHAN_MODE_CMDID); + +/* Resmgr Enable/Disable Adaptive OCS CMD */ +#define WMITLV_TABLE_WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, \ + wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); + +/* Resmgr Set Channel Time Quota CMD */ +#define WMITLV_TABLE_WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, \ + wmi_resmgr_set_chan_time_quota_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); + +/* Resmgr Set Channel Latency CMD */ +#define WMITLV_TABLE_WMI_RESMGR_SET_CHAN_LATENCY_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, \ + wmi_resmgr_set_chan_latency_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_RESMGR_SET_CHAN_LATENCY_CMDID); + +/* STA SMPS Force Mode CMD */ +#define WMITLV_TABLE_WMI_STA_SMPS_FORCE_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, \ + wmi_sta_smps_force_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_SMPS_FORCE_MODE_CMDID); + +/* wlan hb enable/disable CMD */ +#define WMITLV_TABLE_WMI_HB_SET_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, \ + wmi_hb_set_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_HB_SET_ENABLE_CMDID); + +/* wlan hb set tcp params CMD */ +#define WMITLV_TABLE_WMI_HB_SET_TCP_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, \ + wmi_hb_set_tcp_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_HB_SET_TCP_PARAMS_CMDID); + +/* wlan hb set tcp pkt filter CMD */ +#define WMITLV_TABLE_WMI_HB_SET_TCP_PKT_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, \ + wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_HB_SET_TCP_PKT_FILTER_CMDID); + +/* wlan set udp params CMD */ +#define WMITLV_TABLE_WMI_HB_SET_UDP_PARAMS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, \ + wmi_hb_set_udp_params_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_HB_SET_UDP_PARAMS_CMDID); + +/* wlan hb set udp pkt filter CMD */ +#define WMITLV_TABLE_WMI_HB_SET_UDP_PKT_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, \ + wmi_hb_set_udp_pkt_filter_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_HB_SET_UDP_PKT_FILTER_CMDID); + +/* STA SMPS Param CMD */ +#define WMITLV_TABLE_WMI_STA_SMPS_PARAM_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, \ + wmi_sta_smps_param_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_STA_SMPS_PARAM_CMDID); + +/* MCC Adaptive Scheduler Traffic Stats */ +#define WMITLV_TABLE_WMI_MCC_SCHED_TRAFFIC_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mcc_sched_traffic_stats_cmd_fixed_param, wmi_mcc_sched_traffic_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_ARRAY_STRUC, wmi_mcc_sched_sta_traffic_stats, mcc_sched_sta_traffic_stats_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_MCC_SCHED_TRAFFIC_STATS_CMDID); + +#define WMITLV_TABLE_WMI_BATCH_SCAN_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_batch_scan_enable_cmd_fixed_param, wmi_batch_scan_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_BATCH_SCAN_ENABLE_CMDID); + +#define WMITLV_TABLE_WMI_PEER_INFO_REQ_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param, \ + wmi_peer_info_req_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_INFO_REQ_CMDID); + +#define WMITLV_TABLE_WMI_RMC_SET_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param, \ + wmi_rmc_set_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_RMC_SET_MODE_CMDID); + +#define WMITLV_TABLE_WMI_RMC_SET_ACTION_PERIOD_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param, \ + wmi_rmc_set_action_period_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_RMC_SET_ACTION_PERIOD_CMDID); + +#define WMITLV_TABLE_WMI_RMC_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rmc_config_cmd_fixed_param, \ + wmi_rmc_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_RMC_CONFIG_CMDID); + +#define WMITLV_TABLE_WMI_MHF_OFFLOAD_SET_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mhf_offload_set_mode_cmd_fixed_param, \ + wmi_mhf_offload_set_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_MHF_OFFLOAD_SET_MODE_CMDID); + +#define WMITLV_TABLE_WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mhf_offload_plumb_routing_table_cmd_fixed_param, \ + wmi_mhf_offload_plumb_routing_table_cmd, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_mhf_offload_routing_table_entry, \ + routing_tbl_entries, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID) + +#define WMITLV_TABLE_WMI_BATCH_SCAN_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_batch_scan_disable_cmd_fixed_param, wmi_batch_scan_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_BATCH_SCAN_DISABLE_CMDID); + +#define WMITLV_TABLE_WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_batch_scan_trigger_result_cmd_fixed_param, wmi_batch_scan_trigger_result_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID); + +/* LPI mgmt snooping config Cmd */ +#define WMITLV_TABLE_WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_mgmt_snooping_config_cmd_fixed_param, wmi_lpi_mgmt_snooping_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID); + +/* LPI start scan Cmd */ +#define WMITLV_TABLE_WMI_LPI_START_SCAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_start_scan_cmd_fixed_param, wmi_lpi_start_scan_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_ssid, ssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_data, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_START_SCAN_CMDID); + +/* LPI stop scan Cmd */ +#define WMITLV_TABLE_WMI_LPI_STOP_SCAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_stop_scan_cmd_fixed_param, wmi_lpi_stop_scan_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_STOP_SCAN_CMDID); + +#define WMITLV_TABLE_WMI_LPI_RESULT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_result_event_fixed_param, wmi_lpi_result_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_RESULT_EVENTID); + +/* LPI Status Event */ +#define WMITLV_TABLE_WMI_LPI_STATUS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_status_event_fixed_param, wmi_lpi_status_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_STATUS_EVENTID); + +/* LPI Handoff Event */ +#define WMITLV_TABLE_WMI_LPI_HANDOFF_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_lpi_handoff_event_fixed_param, wmi_lpi_handoff_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_LPI_HANDOFF_EVENTID); + +/* Thermal Manager Params*/ +#define WMITLV_TABLE_WMI_THERMAL_MGMT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, wmi_thermal_mgmt_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_THERMAL_MGMT_CMDID); + +#define WMITLV_TABLE_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, pattern, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID); + +#define WMITLV_TABLE_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID); + +/* NaN Request */ +#define WMITLV_TABLE_WMI_NAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nan_cmd_param, wmi_nan_cmd_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_NAN_CMDID); + +/* Modem power state cmd */ +#define WMITLV_TABLE_WMI_MODEM_POWER_STATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, wmi_modem_power_state_cmd_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_MODEM_POWER_STATE_CMDID); + +/* get estimated link speed cmd */ +#define WMITLV_TABLE_WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, wmi_peer_get_estimated_linkspeed_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID); + +/* ext stats Request */ +#define WMITLV_TABLE_WMI_REQUEST_STATS_EXT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, wmi_req_stats_ext_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_REQUEST_STATS_EXT_CMDID); + +/* 2.4Ghz HT40 OBSS scan enable */ +#define WMITLV_TABLE_WMI_OBSS_SCAN_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param, wmi_obss_scan_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, channels, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_field, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OBSS_SCAN_ENABLE_CMDID); + +/* 2.4Ghz HT40 OBSS scan disable */ +#define WMITLV_TABLE_WMI_OBSS_SCAN_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, wmi_obss_scan_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OBSS_SCAN_DISABLE_CMDID); + +/* Pdev Set LED Config Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_LED_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_set_led_config_cmd_fixed_param, wmi_pdev_set_led_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_LED_CONFIG_CMDID); + +/* host auto shut down config cmd */ +#define WMITLV_TABLE_WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, wmi_host_auto_shutdown_cfg_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); + +/* tpc chainmask config cmd */ +#define WMITLV_TABLE_WMI_TPC_CHAINMASK_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tpc_chainmask_config_cmd_fixed_param, wmi_tpc_chainmask_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_tpc_chainmask_config, config_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_TPC_CHAINMASK_CONFIG_CMDID); + +/* Ch avoidance update cmd */ +#define WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, wmi_chan_avoid_update_cmd_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_CHAN_AVOID_UPDATE_CMDID); + +/* D0-WOW Enable Disable Cmd */ +#define WMITLV_TABLE_WMI_D0_WOW_ENABLE_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, wmi_d0_wow_enable_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_D0_WOW_ENABLE_DISABLE_CMDID); + +/* Pdev get chip temperature Cmd */ +#define WMITLV_TABLE_WMI_PDEV_GET_TEMPERATURE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param, wmi_pdev_get_temperature_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_GET_TEMPERATURE_CMDID); + +/* Set antenna diversity Cmd */ +#define WMITLV_TABLE_WMI_SET_ANTENNA_DIVERSITY_CMDID(id,op,buf,len) \ +WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_pdev_set_antenna_diversity_cmd_fixed_param, wmi_pdev_set_antenna_diversity_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SET_ANTENNA_DIVERSITY_CMDID); + +/* Set rssi monitoring config Cmd */ +#define WMITLV_TABLE_WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID(id,op,buf,len) \ +WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_fixed_param, wmi_rssi_breach_monitor_config_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); + +/* DHCP server offload param Cmd */ +#define WMITLV_TABLE_WMI_SET_DHCP_SERVER_OFFLOAD_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param, wmi_set_dhcp_server_offload_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); + +/* IPA Offload Enable Disable Cmd */ +#define WMITLV_TABLE_WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUCT_wmi_ipa_offload_enable_disable_cmd_fixed_param, wmi_ipa_offload_enable_disable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID); + +/* Set LED flashing parameter Cmd */ +#define WMITLV_TABLE_WMI_PDEV_SET_LED_FLASHING_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param, wmi_set_led_flashing_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_SET_LED_FLASHING_CMDID); + +/* mDNS responder offload param Cmd */ +#define WMITLV_TABLE_WMI_MDNS_OFFLOAD_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mdns_offload_cmd_fixed_param, wmi_mdns_offload_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_OFFLOAD_ENABLE_CMDID); + +#define WMITLV_TABLE_WMI_MDNS_SET_FQDN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mdns_set_fqdn_cmd_fixed_param, wmi_mdns_set_fqdn_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, fqdn_data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_SET_FQDN_CMDID); + +#define WMITLV_TABLE_WMI_MDNS_SET_RESPONSE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mdns_set_resp_cmd_fixed_param, wmi_mdns_set_resp_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, resp_data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_SET_RESPONSE_CMDID); + +#define WMITLV_TABLE_WMI_MDNS_GET_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mdns_get_stats_cmd_fixed_param, wmi_mdns_get_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_GET_STATS_CMDID); + +/* roam invoke Cmd */ +#define WMITLV_TABLE_WMI_ROAM_INVOKE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, wmi_roam_invoke_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_INVOKE_CMDID); + +/* SAP Authentication offload param Cmd */ +#define WMITLV_TABLE_WMI_SAP_OFL_ENABLE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sap_ofl_enable_cmd_fixed_param, wmi_sap_ofl_enable_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, psk, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_ENABLE_CMDID); + +/* APFIND Request */ +#define WMITLV_TABLE_WMI_APFIND_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_apfind_cmd_param, wmi_apfind_cmd_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_APFIND_CMDID); + +/* Set OCB schedule cmd, DEPRECATED */ +#define WMITLV_TABLE_WMI_OCB_SET_SCHED_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param, wmi_ocb_set_sched_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_SCHED_CMDID); + +/* Set OCB configuration cmd */ +#define WMITLV_TABLE_WMI_OCB_SET_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param, wmi_ocb_set_config_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_channel, chan_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ocb_channel, ocb_chan_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_qos_parameter, qos_parameter_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_chan, chan_cfg, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_active_state_config, ndl_active_state_config_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_ocb_schedule_element, schedule_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_CONFIG_CMDID); + +/* Set UTC time cmd */ +#define WMITLV_TABLE_WMI_OCB_SET_UTC_TIME_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param, wmi_ocb_set_utc_time_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_UTC_TIME_CMDID); + +/* Start timing advertisement cmd */ +#define WMITLV_TABLE_WMI_OCB_START_TIMING_ADVERT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param, wmi_ocb_start_timing_advert_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_START_TIMING_ADVERT_CMDID); + +/* Stop timing advertisement cmd */ +#define WMITLV_TABLE_WMI_OCB_STOP_TIMING_ADVERT_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param, wmi_ocb_stop_timing_advert_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_STOP_TIMING_ADVERT_CMDID); + +/* Get TSF timer cmd */ +#define WMITLV_TABLE_WMI_OCB_GET_TSF_TIMER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param, wmi_ocb_get_tsf_timer_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_GET_TSF_TIMER_CMDID); + +/* Get DCC stats cmd */ +#define WMITLV_TABLE_WMI_DCC_GET_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param, wmi_dcc_get_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_channel_stats_request, channel_stats_request, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_GET_STATS_CMDID); + +/* Clear DCC stats cmd */ +#define WMITLV_TABLE_WMI_DCC_CLEAR_STATS_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param, wmi_dcc_clear_stats_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_CLEAR_STATS_CMDID); + +/* Update DCC NDL cmd */ +#define WMITLV_TABLE_WMI_DCC_UPDATE_NDL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param, wmi_dcc_update_ndl_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_chan, chan_ndl_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_active_state_config, ndl_active_state_config_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_UPDATE_NDL_CMDID); + +/* Roam filter cmd */ +#define WMITLV_TABLE_WMI_ROAM_FILTER_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_filter_fixed_param, wmi_roam_filter_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_black_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_ssid, ssid_white_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, bssid_preferred_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, bssid_preferred_factor, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_FILTER_CMDID); + +/* TSF timestamp action cmd */ +#define WMITLV_TABLE_WMI_VDEV_TSF_TSTAMP_ACTION_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param, wmi_vdev_tsf_tstamp_action_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID); + +/* LFR subnet change config Cmd */ +#define WMITLV_TABLE_WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param, wmi_roam_subnet_change_config_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_FIXED_STRUC, wmi_mac_addr, skip_subnet_change_detection_bssid_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); + +/* Set the SOC Preferred Channel List (PCL) Cmd */ +#define WMITLV_TABLE_WMI_SOC_SET_PCL_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_soc_set_pcl_cmd_fixed_param, wmi_soc_set_pcl_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, channel_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SOC_SET_PCL_CMDID); + +/* Set the SOC Hardware Mode Cmd */ +#define WMITLV_TABLE_WMI_SOC_SET_HW_MODE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_cmd_fixed_param, wmi_soc_set_hw_mode_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SOC_SET_HW_MODE_CMDID); + +/************************** TLV definitions of WMI events *******************************/ + +/* Service Ready event */ +#define WMITLV_TABLE_WMI_SERVICE_READY_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_service_ready_event_fixed_param, wmi_service_ready_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_HAL_REG_CAPABILITIES, HAL_REG_CAPABILITIES, hal_reg_capabilities, WMITLV_SIZE_FIX) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, wmi_service_bitmap, WMITLV_SIZE_FIX, WMI_SERVICE_BM_SIZE) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wlan_host_mem_req, mem_reqs, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, wlan_dbs_hw_mode_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SERVICE_READY_EVENTID); + +/* Ready event */ +#define WMITLV_TABLE_WMI_READY_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ready_event_fixed_param, wmi_ready_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_READY_EVENTID); + +/* Scan Event */ +#define WMITLV_TABLE_WMI_SCAN_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_scan_event_fixed_param, wmi_scan_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SCAN_EVENTID); + +/* ExtScan Start/Stop Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_START_STOP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param, wmi_extscan_start_stop_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_START_STOP_EVENTID); + +/* ExtScan Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_OPERATION_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param, wmi_extscan_operation_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, bucket_id, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_OPERATION_EVENTID); + +/* ExtScan Table Usage Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_TABLE_USAGE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param, wmi_extscan_table_usage_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_TABLE_USAGE_EVENTID); + +/* ExtScan Result Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_CACHED_RESULTS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param, wmi_extscan_cached_results_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_descriptor, bssid_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_rssi_info, rssi_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ie_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_CACHED_RESULTS_EVENTID); + +/* ExtScan Monitor RSSI List Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param, wmi_extscan_wlan_change_results_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_change_result_bssid, bssid_signal_descriptor_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, rssi_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID); + +/* ExtScan Hot List Match Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_HOTLIST_MATCH_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param, wmi_extscan_hotlist_match_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_descriptor, hotlist_match, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_HOTLIST_MATCH_EVENTID); + +/* ExtScan Hot List Match Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_CAPABILITIES_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param, wmi_extscan_capabilities_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_cache_capabilities, extscan_cache_capabilities, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_change_monitor_capabilities, wlan_change_capabilities, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_hotlist_monitor_capabilities, hotlist_capabilities, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_CAPABILITIES_EVENTID); + +/* ExtScan Hot List Match Event */ +#define WMITLV_TABLE_WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_extscan_hotlist_ssid_match_event_fixed_param, wmi_extscan_hotlist_ssid_match_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_extscan_wlan_descriptor, hotlist_ssid_match, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID); + +/* Update_whal_mib_stats Event */ +#define WMITLV_TABLE_WMI_UPDATE_WHAL_MIB_STATS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_update_whal_mib_stats_event_fixed_param, wmi_update_whal_mib_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_WHAL_MIB_STATS_EVENTID); + +/* PDEV TPC Config Event */ +#define WMITLV_TABLE_WMI_PDEV_TPC_CONFIG_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_tpc_config_event_fixed_param, wmi_pdev_tpc_config_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, ratesArray, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_TPC_CONFIG_EVENTID); + +/* Channel Info Event */ +#define WMITLV_TABLE_WMI_CHAN_INFO_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chan_info_event_fixed_param, wmi_chan_info_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_CHAN_INFO_EVENTID); + +/* Phy Error Event */ +#define WMITLV_TABLE_WMI_PHYERR_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_comb_phyerr_rx_hdr, wmi_comb_phyerr_rx_hdr, hdr, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PHYERR_EVENTID); + +/* TX Pause/Unpause event */ +#define WMITLV_TABLE_WMI_TX_PAUSE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tx_pause_event_fixed_param, wmi_tx_pause_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_TX_PAUSE_EVENTID); + +/* VDEV Start response Event */ +#define WMITLV_TABLE_WMI_VDEV_START_RESP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_start_response_event_fixed_param, wmi_vdev_start_response_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_START_RESP_EVENTID); + +/* VDEV Stopped Event */ +#define WMITLV_TABLE_WMI_VDEV_STOPPED_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_stopped_event_fixed_param, wmi_vdev_stopped_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_STOPPED_EVENTID); + +/* VDEV Install Key Complete Event */ +#define WMITLV_TABLE_WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_install_key_complete_event_fixed_param, wmi_vdev_install_key_complete_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID); + +/* Peer STA Kickout Event */ +#define WMITLV_TABLE_WMI_PEER_STA_KICKOUT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_sta_kickout_event_fixed_param, wmi_peer_sta_kickout_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_STA_KICKOUT_EVENTID); + +/* Management Rx Event */ +#define WMITLV_TABLE_WMI_MGMT_RX_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mgmt_rx_hdr, wmi_mgmt_rx_hdr, hdr, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_MGMT_RX_EVENTID); + +/* TBTT offset Event */ +#define WMITLV_TABLE_WMI_TBTTOFFSET_UPDATE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tbtt_offset_event_fixed_param, wmi_tbtt_offset_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_FXAR(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, tbttoffset_list, WMITLV_SIZE_FIX, WMI_MAX_AP_VDEV) +WMITLV_CREATE_PARAM_STRUC(WMI_TBTTOFFSET_UPDATE_EVENTID); + +/* TX DELBA Complete Event */ +#define WMITLV_TABLE_WMI_TX_DELBA_COMPLETE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tx_delba_complete_event_fixed_param, wmi_tx_delba_complete_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_TX_DELBA_COMPLETE_EVENTID); + +/* Tx ADDBA Complete Event */ +#define WMITLV_TABLE_WMI_TX_ADDBA_COMPLETE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tx_addba_complete_event_fixed_param, wmi_tx_addba_complete_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_TX_ADDBA_COMPLETE_EVENTID); + +/* ADD BA Req ssn Event */ +#define WMITLV_TABLE_WMI_BA_RSP_SSN_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ba_rsp_ssn_event_fixed_param, wmi_ba_rsp_ssn_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_ARRAY_STRUC, wmi_ba_event_ssn, ba_event_ssn_list, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_BA_RSP_SSN_EVENTID); + +/* Aggregation Request event */ +#define WMITLV_TABLE_WMI_AGGR_STATE_TRIG_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_aggr_state_trig_event_fixed_param, wmi_aggr_state_trig_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_AGGR_STATE_TRIG_EVENTID); + +/* Roam Event */ +#define WMITLV_TABLE_WMI_ROAM_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_event_fixed_param, wmi_roam_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_EVENTID); + +/* Roam Synch Event */ +#define WMITLV_TABLE_WMI_ROAM_SYNCH_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_roam_synch_event_fixed_param, wmi_roam_synch_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bcn_probe_rsp_frame, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, reassoc_rsp_frame, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_channel, wmi_channel, chan, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_key_material, key, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, status, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_ROAM_SYNCH_EVENTID); + +/* WOW Wakeup Host Event */ +/* NOTE: Make sure wow_bitmap_info can be zero or one elements only */ +#define WMITLV_TABLE_WMI_WOW_WAKEUP_HOST_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WOW_EVENT_INFO_fixed_param, WOW_EVENT_INFO_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WOW_EVENT_INFO_SECTION_BITMAP, wow_bitmap_info, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, wow_packet_buffer, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_hb_ind_event_fixed_param, hb_indevt, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, wow_gtkigtk, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_WAKEUP_HOST_EVENTID); + +#define WMITLV_TABLE_WMI_WOW_INITIAL_WAKEUP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WOW_EVENT_INITIAL_WAKEUP_fixed_param, WOW_INITIAL_WAKEUP_EVENT_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_WOW_INITIAL_WAKEUP_EVENTID); + +/* RTT error report Event */ +#define WMITLV_TABLE_WMI_RTT_ERROR_REPORT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_RTT_ERROR_REPORT_EVENTID); + +/* Echo Event */ +#define WMITLV_TABLE_WMI_ECHO_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_echo_event_fixed_param, wmi_echo_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_ECHO_EVENTID); + +/* FTM Integration Event */ +#define WMITLV_TABLE_WMI_PDEV_FTM_INTG_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ftm_intg_event_fixed_param, wmi_ftm_intg_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_FTM_INTG_EVENTID); + +/* VDEV get Keepalive Event */ +#define WMITLV_TABLE_WMI_VDEV_GET_KEEPALIVE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_event_fixed_param, wmi_vdev_get_keepalive_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_GET_KEEPALIVE_EVENTID); + +/* GPIO Input Event */ +#define WMITLV_TABLE_WMI_GPIO_INPUT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_gpio_input_event_fixed_param, wmi_gpio_input_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_GPIO_INPUT_EVENTID); + +/* CSA Handling Event */ +#define WMITLV_TABLE_WMI_CSA_HANDLING_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_csa_event_fixed_param, wmi_csa_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_CSA_HANDLING_EVENTID); + +/* Rfkill state change Event */ +#define WMITLV_TABLE_WMI_RFKILL_STATE_CHANGE_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rfkill_event_fixed_param, wmi_rfkill_mode_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_RFKILL_STATE_CHANGE_EVENTID); + +/* Debug Message Event */ +#define WMITLV_TABLE_WMI_DEBUG_MESG_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DEBUG_MESG_EVENTID); + +#define WMITLV_TABLE_WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_debug_mesg_flush_complete_fixed_param, wmi_debug_mesg_flush_complete_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID); + +#define WMITLV_TABLE_WMI_RSSI_BREACH_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_rssi_breach_event_fixed_param, wmi_rssi_breach_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_RSSI_BREACH_EVENTID); + +/* Diagnostics Event */ +#define WMITLV_TABLE_WMI_DIAG_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DIAG_EVENTID); + +/* IGTK Offload Event */ +#define WMITLV_TABLE_WMI_GTK_OFFLOAD_STATUS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_GTK_OFFLOAD_STATUS_EVENTID); + +/* DCA interferance Event */ +#define WMITLV_TABLE_WMI_DCS_INTERFERENCE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcs_interference_event_fixed_param, wmi_dcs_interference_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, ath_dcs_cw_int, cw_int, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wlan_dcs_im_tgt_stats_t, wlan_stat, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DCS_INTERFERENCE_EVENTID); + +/* Profile data Event */ +#define WMITLV_TABLE_WMI_WLAN_PROFILE_DATA_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_wlan_profile_ctx_t, wmi_wlan_profile_ctx_t, profile_ctx, WMITLV_SIZE_FIX)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wlan_profile_t, profile_data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_PROFILE_DATA_EVENTID); + +/* PDEV UTF Event */ +#define WMITLV_TABLE_WMI_PDEV_UTF_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_UTF_EVENTID); + +/* Debug print Event */ +#define WMITLV_TABLE_WMI_DEBUG_PRINT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DEBUG_PRINT_EVENTID); + +/* RTT measurement report Event */ +#define WMITLV_TABLE_WMI_RTT_MEASUREMENT_REPORT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_RTT_MEASUREMENT_REPORT_EVENTID); + +/*oem measurement report Event*/ +#define WMITLV_TABLE_WMI_OEM_MEASUREMENT_REPORT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OEM_MEASUREMENT_REPORT_EVENTID); + +/*oem error report event*/ +#define WMITLV_TABLE_WMI_OEM_ERROR_REPORT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OEM_ERROR_REPORT_EVENTID); + +/*oem capability report event*/ +#define WMITLV_TABLE_WMI_OEM_CAPABILITY_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_OEM_CAPABILITY_EVENTID); + +/* HOST SWBA Event */ +#define WMITLV_TABLE_WMI_HOST_SWBA_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_host_swba_event_fixed_param, wmi_host_swba_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_tim_info, tim_info, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_p2p_noa_info, p2p_noa_info, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_HOST_SWBA_EVENTID); + + +/* Update stats Event */ +#define WMITLV_TABLE_WMI_UPDATE_STATS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_stats_event_fixed_param, wmi_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_STATS_EVENTID); + +/* For vdev based ht/vht info upload*/ +#define WMITLV_TABLE_WMI_UPDATE_VDEV_RATE_STATS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_rate_stats_event_fixed_param, wmi_vdev_rate_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_vdev_rate_ht_info, ht_info, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_VDEV_RATE_STATS_EVENTID); + + +/* Update memory dump complete Event */ +#define WMITLV_TABLE_WMI_UPDATE_FW_MEM_DUMP_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_update_fw_mem_dump_fixed_param, wmi_update_fw_mem_dump_fixed_param, fixed_param, WMITLV_SIZE_FIX) + +WMITLV_CREATE_PARAM_STRUC(WMI_UPDATE_FW_MEM_DUMP_EVENTID); + +/* Update iface link stats Event */ +#define WMITLV_TABLE_WMI_IFACE_LINK_STATS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_iface_link_stats_event_fixed_param, wmi_iface_link_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_iface_link_stats, iface_link_stats, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_wmm_ac_stats, ac, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_IFACE_LINK_STATS_EVENTID); + +/* Update Peer link stats Event */ +#define WMITLV_TABLE_WMI_PEER_LINK_STATS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_stats_event_fixed_param, wmi_peer_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_link_stats, peer_stats, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_rate_stats, peer_rate_stats, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_LINK_STATS_EVENTID); + +/* Update radio stats Event */ +#define WMITLV_TABLE_WMI_RADIO_LINK_STATS_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_radio_link_stats_event_fixed_param, wmi_radio_link_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_radio_link_stats, radio_stats, WMITLV_SIZE_VAR)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_channel_stats, channel_stats, WMITLV_SIZE_VAR) + +WMITLV_CREATE_PARAM_STRUC(WMI_RADIO_LINK_STATS_EVENTID); + +/* PDEV QVIT Event */ +#define WMITLV_TABLE_WMI_PDEV_QVIT_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_QVIT_EVENTID); + +/* WLAN Frequency avoid Event */ +#define WMITLV_TABLE_WMI_WLAN_FREQ_AVOID_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_avoid_freq_ranges_event_fixed_param, wmi_avoid_freq_ranges_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_avoid_freq_range_desc, avd_freq_range, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_WLAN_FREQ_AVOID_EVENTID); + +/* GTK rekey fail Event */ +#define WMITLV_TABLE_WMI_GTK_REKEY_FAIL_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_gtk_rekey_fail_event_fixed_param, wmi_gtk_rekey_fail_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_GTK_REKEY_FAIL_EVENTID); + +/* NLO match event */ +#define WMITLV_TABLE_WMI_NLO_MATCH_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nlo_event, wmi_nlo_event, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_NLO_MATCH_EVENTID); + +/* NLO scan complete event */ +#define WMITLV_TABLE_WMI_NLO_SCAN_COMPLETE_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nlo_event, wmi_nlo_event, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_NLO_SCAN_COMPLETE_EVENTID); + +/* APFIND event */ +#define WMITLV_TABLE_WMI_APFIND_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_apfind_event_hdr, wmi_apfind_event_hdr, hdr, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_APFIND_EVENTID); + +/* WMI_PASSPOINT_MATCH_EVENTID */ +#define WMITLV_TABLE_WMI_PASSPOINT_MATCH_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_passpoint_event_hdr, wmi_passpoint_event_hdr, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_PASSPOINT_MATCH_EVENTID); + +/* Chatter query reply event */ +#define WMITLV_TABLE_WMI_CHATTER_PC_QUERY_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_chatter_query_reply_event_fixed_param, wmi_chatter_query_reply_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_CHATTER_PC_QUERY_EVENTID); + +/* Upload H_CV info event */ +#define WMITLV_TABLE_WMI_UPLOADH_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_upload_h_hdr, wmi_upload_h_hdr, hdr, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_UPLOADH_EVENTID); + +/* Capture H info event */ +#define WMITLV_TABLE_WMI_CAPTUREH_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_capture_h_event_hdr, wmi_capture_h_event_hdr, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_CAPTUREH_EVENTID); + +/* TDLS Peer Update event */ +#define WMITLV_TABLE_WMI_TDLS_PEER_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_event_fixed_param, wmi_tdls_peer_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_PEER_EVENTID); + +/* VDEV MCC Beacon Interval Change Request Event */ +#define WMITLV_TABLE_WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_mcc_bcn_intvl_change_event_fixed_param, wmi_vdev_mcc_bcn_intvl_change_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID); + +#define WMITLV_TABLE_WMI_BATCH_SCAN_ENABLED_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_batch_scan_enabled_event_fixed_param, wmi_batch_scan_enabled_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_BATCH_SCAN_ENABLED_EVENTID); + +#define WMITLV_TABLE_WMI_BATCH_SCAN_RESULT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_batch_scan_result_event_fixed_param, wmi_batch_scan_result_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len,WMITLV_TAG_ARRAY_STRUC, wmi_batch_scan_result_scan_list, scan_list, WMITLV_SIZE_VAR) \ + WMITLV_ELEM(id,op,buf,len,WMITLV_TAG_ARRAY_STRUC, wmi_batch_scan_result_network_info, network_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_BATCH_SCAN_RESULT_EVENTID); + +#define WMITLV_TABLE_WMI_OFFLOAD_BCN_TX_STATUS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_offload_bcn_tx_status_event_fixed_param, wmi_offload_bcn_tx_status_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OFFLOAD_BCN_TX_STATUS_EVENTID); + +/* NOA Event */ +#define WMITLV_TABLE_WMI_P2P_NOA_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_noa_event_fixed_param, wmi_p2p_noa_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_p2p_noa_info, wmi_p2p_noa_info, p2p_noa_info, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_P2P_NOA_EVENTID); + +#define WMITLV_TABLE_WMI_PEER_INFO_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_info_event_fixed_param, wmi_peer_info_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_peer_info, peer_info, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_PEER_INFO_EVENTID); + +#define WMITLV_TABLE_WMI_PEER_TX_FAIL_CNT_THR_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_tx_fail_cnt_thr_event_fixed_param, wmi_peer_tx_fail_cnt_thr_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_PEER_TX_FAIL_CNT_THR_EVENTID); + +/* DFS radar Event */ +#define WMITLV_TABLE_WMI_DFS_RADAR_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dfs_radar_event_fixed_param, wmi_dfs_radar_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_DFS_RADAR_EVENTID); + +/* Thermal Event */ +#define WMITLV_TABLE_WMI_THERMAL_MGMT_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_thermal_mgmt_event_fixed_param, wmi_thermal_mgmt_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) + WMITLV_CREATE_PARAM_STRUC(WMI_THERMAL_MGMT_EVENTID); + +/* NAN Response/Indication Event */ +#define WMITLV_TABLE_WMI_NAN_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nan_event_hdr, wmi_nan_event_hdr, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_NAN_EVENTID); + +/* L1SS track Event */ +#define WMITLV_TABLE_WMI_PDEV_L1SS_TRACK_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_l1ss_track_event_fixed_param, wmi_pdev_l1ss_track_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_L1SS_TRACK_EVENTID); + +#define WMITLV_TABLE_WMI_DIAG_DATA_CONTAINER_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_diag_data_container_event_fixed_param, wmi_diag_data_container_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DIAG_DATA_CONTAINER_EVENTID); + +/* Estimated Link Speed Indication*/ +#define WMITLV_TABLE_WMI_PEER_ESTIMATED_LINKSPEED_EVENTID(id,op,buf,len)\ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_estimated_linkspeed_event_fixed_param, wmi_peer_estimated_linkspeed_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_ESTIMATED_LINKSPEED_EVENTID); + +#define WMITLV_TABLE_WMI_STATS_EXT_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_stats_ext_event_fixed_param, wmi_stats_ext_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_STATS_EXT_EVENTID); + +#define WMITLV_TABLE_WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_offload_prb_rsp_tx_status_event_fixed_param, wmi_offload_prb_rsp_tx_status_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID); + +/* host auto shut down event */ +#define WMITLV_TABLE_WMI_HOST_AUTO_SHUTDOWN_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_host_auto_shutdown_event_fixed_param, wmi_host_auto_shutdown_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_HOST_AUTO_SHUTDOWN_EVENTID); + +/* peer state Event */ +#define WMITLV_TABLE_WMI_PEER_STATE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_peer_state_event_fixed_param, wmi_peer_state_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PEER_STATE_EVENTID); + +/* D0-WOW Disable Ack event */ +#define WMITLV_TABLE_WMI_D0_WOW_DISABLE_ACK_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_d0_wow_disable_ack_event_fixed_param, wmi_d0_wow_disable_ack_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_D0_WOW_DISABLE_ACK_EVENTID); + +/* Pdev get chip temperature event */ +#define WMITLV_TABLE_WMI_PDEV_TEMPERATURE_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_temperature_event_fixed_param, wmi_pdev_temperature_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_TEMPERATURE_EVENTID); + +/* mDNS offload stats event */ +#define WMITLV_TABLE_WMI_MDNS_STATS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_mdns_stats_event_fixed_param, wmi_mdns_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_MDNS_STATS_EVENTID); + +/* pdev resume event */ +#define WMITLV_TABLE_WMI_PDEV_RESUME_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_pdev_resume_event_fixed_param, wmi_pdev_resume_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_RESUME_EVENTID); + +/* SAP Authentication offload event */ +#define WMITLV_TABLE_WMI_SAP_OFL_ADD_STA_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sap_ofl_add_sta_event_fixed_param, wmi_sap_ofl_add_sta_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_ADD_STA_EVENTID); + +#define WMITLV_TABLE_WMI_SAP_OFL_DEL_STA_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sap_ofl_del_sta_event_fixed_param, wmi_sap_ofl_del_sta_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_DEL_STA_EVENTID); + +/* Set OCB schedule cmd, DEPRECATED */ +#define WMITLV_TABLE_WMI_OCB_SET_SCHED_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_ocb_set_sched_event_fixed_param, wmi_ocb_set_sched_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_SCHED_EVENTID); + +/* Set OCB configuration response event */ +#define WMITLV_TABLE_WMI_OCB_SET_CONFIG_RESP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_set_config_resp_event_fixed_param, wmi_ocb_set_config_resp_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_CONFIG_RESP_EVENTID); + +/* Get TSF timer response event */ +#define WMITLV_TABLE_WMI_OCB_GET_TSF_TIMER_RESP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_resp_event_fixed_param, wmi_ocb_get_tsf_timer_resp_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_OCB_GET_TSF_TIMER_RESP_EVENTID); + +/* Get DCC stats response event */ +#define WMITLV_TABLE_WMI_DCC_GET_STATS_RESP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_get_stats_resp_event_fixed_param, wmi_dcc_get_stats_resp_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_stats_per_channel, stats_per_channel_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_GET_STATS_RESP_EVENTID); + +/* Update DCC NDL response event */ +#define WMITLV_TABLE_WMI_DCC_UPDATE_NDL_RESP_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_update_ndl_resp_event_fixed_param, wmi_dcc_update_ndl_resp_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_UPDATE_NDL_RESP_EVENTID); + +/* DCC stats event */ +#define WMITLV_TABLE_WMI_DCC_STATS_EVENTID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dcc_stats_event_fixed_param, wmi_dcc_stats_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_dcc_ndl_stats_per_channel, stats_per_channel_list, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_DCC_STATS_EVENTID); + +/* Read TSF timer response event */ +#define WMITLV_TABLE_WMI_VDEV_TSF_REPORT_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_tsf_report_event_fixed_param, wmi_vdev_tsf_report_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_TSF_REPORT_EVENTID); + +/* Vdev capabilities IE to be transmitted in mgmt frames */ +#define WMITLV_TABLE_WMI_VDEV_SET_IE_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param, wmi_vdev_set_ie_cmd_fixed_param, vdev_ie, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, bufp, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_VDEV_SET_IE_CMDID); + +/* SOC Set Hardware Mode Response event */ +#define WMITLV_TABLE_WMI_SOC_SET_HW_MODE_RESP_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_response_event_fixed_param, wmi_soc_set_hw_mode_response_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_soc_set_hw_mode_response_vdev_mac_entry, wmi_soc_set_hw_mode_response_vdev_mac_mapping, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SOC_SET_HW_MODE_RESP_EVENTID); + +/* SOC Hardware Mode Transition event */ +#define WMITLV_TABLE_WMI_SOC_HW_MODE_TRANSITION_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_soc_hw_mode_transition_event_fixed_param, wmi_soc_hw_mode_transition_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_soc_set_hw_mode_response_vdev_mac_entry, wmi_soc_set_hw_mode_response_vdev_mac_mapping, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_SOC_HW_MODE_TRANSITION_EVENTID); +#ifdef __cplusplus +} +#endif + +#endif /*_WMI_TLV_DEFS_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_helper.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_helper.h new file mode 100644 index 0000000000000..8064913f0eb9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_tlv_helper.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WMI_TLV_HELPER_H_ +#define _WMI_TLV_HELPER_H_ + +/* + * Every command or event parameter structure will need a TLV definition. + * The macro WMITLV_TABLE is used to help build this TLV definition. Inside this macro define, the + * individual TLV's are specified. The parameters for WMITLV_ELEM are: + * (1) the list of parameters that are passed unchanged from the WMITLV_TABLE. Currently, they are id,op,buf,len + * (2) The TLV Tag. You should create a new tag for each cmd/event in WMITLV_TAG_ID. The name of the + * tag is . There are special tags, + * e.g. WMI_TLVTAG_ARRAY_UINT32 and WMI_TLVTAG_ARRAY_STRUC. WMI_TLVTAG_ARRAY_UINT32 is for a + * variable size array of UINT32 elements. WMI_TLVTAG_ARRAY_STRUC is for a varialbe size array + * of structures. + * (3) type of the TLV. For WMI_TLVTAG_ARRAY_* tag, then it is the type of each element. + * (4) Name of this TLV. It must be unique in this TLV TABLE. + * (5) Either WMITLV_SIZE_FIX or WMITLV_SIZE_VAR to indicate if this TLV is variable size. + * + * Note: It is important that the last TLV_ELEM does not have the "\" character. +*/ + +/* Size of the TLV Header which is the Tag and Length fields */ +#define WMI_TLV_HDR_SIZE (1 * sizeof(A_UINT32)) + +/** TLV Helper macro to get the TLV Header given the pointer + * to the TLV buffer. */ +#define WMITLV_GET_HDR(tlv_buf) (((A_UINT32 *)(tlv_buf))[0]) + +/** TLV Helper macro to set the TLV Header given the pointer + * to the TLV buffer. */ +#define WMITLV_SET_HDR(tlv_buf, tag, len) (((A_UINT32 *)(tlv_buf))[0]) = ((tag << 16) | (len & 0x0000FFFF)) + +/** TLV Helper macro to get the TLV Tag given the TLV header. */ +#define WMITLV_GET_TLVTAG(tlv_header) ((A_UINT32)((tlv_header)>>16)) + +/** TLV Helper macro to get the TLV Buffer Length (minus TLV + * header size) given the TLV header. */ +#define WMITLV_GET_TLVLEN(tlv_header) ((A_UINT32)((tlv_header) & 0x0000FFFF)) + +/** TLV Helper macro to get the TLV length from TLV structure size by removing TLV header size */ +#define WMITLV_GET_STRUCT_TLVLEN(tlv_struct) ((A_UINT32)(sizeof(tlv_struct)-WMI_TLV_HDR_SIZE)) + +/* Indicates whether the TLV is fixed size or variable length */ +#define WMITLV_SIZE_FIX 0 +#define WMITLV_SIZE_VAR 1 + +typedef struct { + A_UINT32 tag_order; + A_UINT32 tag_id; + A_UINT32 tag_struct_size; + A_UINT32 tag_varied_size; + A_UINT32 tag_array_size; + A_UINT32 cmd_num_tlv; +} wmitlv_attributes_struc; + + +/* Template structure definition for a variable size array of UINT32 */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMI_TLVTAG_ARRAY_UINT32 */ + A_UINT32 uint32_array[1]; /* variable length Array of UINT32 */ +} wmitlv_array_uint32; + +/* Template structure definition for a variable size array of unknown structure */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMI_TLVTAG_ARRAY_STRUC */ + A_UINT32 struc_array[1]; /* variable length Array of structures */ +} wmitlv_array_struc; + +/* + * Used to fill in the "arr_size" parameter when it is not specified and hence, invalid. Can be used to + * indicate if the original TLV definition specify this fixed array size. + */ +#define WMITLV_ARR_SIZE_INVALID 0x1FE + +#define WMITLV_GET_TAG_NUM_TLV_ATTRIB(wmi_cmd_event_id) \ + WMI_TLV_HLPR_NUM_TLVS_FOR_##wmi_cmd_event_id + + +void +wmitlv_set_static_param_tlv_buf(void *param_tlv_buf, A_UINT32 max_tlvs_accomodated); + +void +wmitlv_free_allocated_command_tlvs( + A_UINT32 cmd_id, + void **wmi_cmd_struct_ptr); + +void +wmitlv_free_allocated_event_tlvs( + A_UINT32 event_id, + void **wmi_cmd_struct_ptr); + +int +wmitlv_check_command_tlv_params( + void *os_ctx, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id); + +int +wmitlv_check_event_tlv_params( + void *os_ctx, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id); + +int +wmitlv_check_and_pad_command_tlvs( + void *os_ctx, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id, void **wmi_cmd_struct_ptr); + +int +wmitlv_check_and_pad_event_tlvs( + void *os_ctx, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id, void **wmi_cmd_struct_ptr); + +/** This structure is the element for the Version WhiteList + * table. */ +typedef struct { + A_UINT32 major; + A_UINT32 minor; + A_UINT32 namespace_0; + A_UINT32 namespace_1; + A_UINT32 namespace_2; + A_UINT32 namespace_3; +} wmi_whitelist_version_info; + +struct _wmi_abi_version; /* Forward declaration to make the ARM compiler happy */ + +int +wmi_cmp_and_set_abi_version(int num_whitelist, wmi_whitelist_version_info *version_whitelist_table, + struct _wmi_abi_version *my_vers, + struct _wmi_abi_version *opp_vers, + struct _wmi_abi_version *out_vers); + +int +wmi_versions_are_compatible(struct _wmi_abi_version *vers1, struct _wmi_abi_version *vers2); + +#endif /*_WMI_TLV_HELPER_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified.h new file mode 100644 index 0000000000000..4819fa5e9b9aa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified.h @@ -0,0 +1,11022 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * @addtogroup WMIAPI + *@{ + */ + +/** @file + * This file specifies the WMI interface for the Software Architecture. + * + * It includes definitions of all the commands and events. Commands are messages + * from the host to the target. Events and Replies are messages from the target + * to the host. + * + * Ownership of correctness in regards to WMI commands + * belongs to the host driver and the target is not required to validate + * parameters for value, proper range, or any other checking. + * + * Guidelines for extending this interface are below. + * + * 1. Add new WMI commands ONLY within the specified range - 0x9000 - 0x9fff + * 2. Use ONLY A_UINT32 type for defining member variables within WMI command/event + * structures. Do not use A_UINT8, A_UINT16, A_BOOL or enum types within these structures. + * 3. DO NOT define bit fields within structures. Implement bit fields using masks + * if necessary. Do not use the programming language's bit field definition. + * 4. Define macros for encode/decode of A_UINT8, A_UINT16 fields within the A_UINT32 + * variables. Use these macros for set/get of these fields. Try to use this to + * optimize the structure without bloating it with A_UINT32 variables for every lower + * sized field. + * 5. Do not use PACK/UNPACK attributes for the structures as each member variable is + * already 4-byte aligned by virtue of being a A_UINT32 type. + * 6. Comment each parameter part of the WMI command/event structure by using the + * 2 stars at the begining of C comment instead of one star to enable HTML document + * generation using Doxygen. + * + */ + +#ifndef _WMI_UNIFIED_H_ +#define _WMI_UNIFIED_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define ATH_MAC_LEN 6 /**< length of MAC in bytes */ +#define WMI_EVENT_STATUS_SUCCESS 0 /* Success return status to host */ +#define WMI_EVENT_STATUS_FAILURE 1 /* Failure return status to host */ + +#define MAX_TX_RATE_VALUES 10 /*Max Tx Rates*/ +#define MAX_RSSI_VALUES 10 /*Max Rssi values*/ + +/* The WLAN_MAX_AC macro cannot be changed without breaking + WMI compatibility. */ +//The maximum value of access category +#define WLAN_MAX_AC 4 + +/* + * These don't necessarily belong here; but as the MS/SM macros require + * ar6000_internal.h to be included, it may not be defined as yet. + */ +#define WMI_F_MS(_v, _f) \ + ( ((_v) & (_f)) >> (_f##_S) ) + +/* + * This breaks the "good macro practice" of only referencing each + * macro field once (to avoid things like field++ from causing issues.) + */ +#define WMI_F_RMW(_var, _v, _f) \ + do { \ + (_var) &= ~(_f); \ + (_var) |= ( ((_v) << (_f##_S)) & (_f)); \ + } while (0) + +#define WMI_GET_BITS(_val,_index,_num_bits) \ + (((_val) >> (_index)) & ((1 << (_num_bits)) - 1)) + +#define WMI_SET_BITS(_var,_index,_num_bits,_val) do { \ + (_var) &= ~(((1 << (_num_bits)) - 1) << (_index)); \ + (_var) |= (((_val) & ((1 << (_num_bits)) - 1)) << (_index)); \ + } while(0) + +/** + * A packed array is an array where each entry in the array is less than + * or equal to 16 bits, and the entries are stuffed into an A_UINT32 array. + * For example, if each entry in the array is 11 bits, then you can stuff + * an array of 4 11-bit values into an array of 2 A_UINT32 values. + * The first 2 11-bit values will be stored in the first A_UINT32, + * and the last 2 11-bit values will be stored in the second A_UINT32. + */ +#define WMI_PACKED_ARR_SIZE(num_entries,bits_per_entry) \ + (((num_entries) / (32 / (bits_per_entry))) + \ + (((num_entries) % (32 / (bits_per_entry))) ? 1 : 0)) + +static INLINE A_UINT32 wmi_packed_arr_get_bits(A_UINT32 *arr, + A_UINT32 entry_index, A_UINT32 bits_per_entry) +{ + A_UINT32 entries_per_uint = (32 / bits_per_entry); + A_UINT32 uint_index = (entry_index / entries_per_uint); + A_UINT32 num_entries_in_prev_uints = (uint_index * entries_per_uint); + A_UINT32 index_in_uint = (entry_index - num_entries_in_prev_uints); + A_UINT32 start_bit_in_uint = (index_in_uint * bits_per_entry); + return ((arr[uint_index] >> start_bit_in_uint) & + (( 1 << bits_per_entry) - 1)); +} + +static INLINE void wmi_packed_arr_set_bits(A_UINT32 *arr, A_UINT32 entry_index, + A_UINT32 bits_per_entry, A_UINT32 val) +{ + A_UINT32 entries_per_uint = (32 / bits_per_entry); + A_UINT32 uint_index = (entry_index / entries_per_uint); + A_UINT32 num_entries_in_prev_uints = (uint_index * entries_per_uint); + A_UINT32 index_in_uint = (entry_index - num_entries_in_prev_uints); + A_UINT32 start_bit_in_uint = (index_in_uint * bits_per_entry); + + arr[uint_index] &= ~(((1 << bits_per_entry) - 1) << start_bit_in_uint); + arr[uint_index] |= + ((val & ((1 << bits_per_entry) - 1)) << start_bit_in_uint); +} + +/** 2 word representation of MAC addr */ +typedef struct { + /** upper 4 bytes of MAC address */ + A_UINT32 mac_addr31to0; + /** lower 2 bytes of MAC address */ + A_UINT32 mac_addr47to32; +} wmi_mac_addr; + +/** macro to convert MAC address from WMI word format to char array */ +#define WMI_MAC_ADDR_TO_CHAR_ARRAY(pwmi_mac_addr,c_macaddr) do { \ + (c_macaddr)[0] = ((pwmi_mac_addr)->mac_addr31to0) & 0xff; \ + (c_macaddr)[1] = ( ((pwmi_mac_addr)->mac_addr31to0) >> 8) & 0xff; \ + (c_macaddr)[2] = ( ((pwmi_mac_addr)->mac_addr31to0) >> 16) & 0xff; \ + (c_macaddr)[3] = ( ((pwmi_mac_addr)->mac_addr31to0) >> 24) & 0xff; \ + (c_macaddr)[4] = ((pwmi_mac_addr)->mac_addr47to32) & 0xff; \ + (c_macaddr)[5] = ( ((pwmi_mac_addr)->mac_addr47to32) >> 8) & 0xff; \ + } while(0) + +/** macro to convert MAC address from char array to WMI word format */ +#define WMI_CHAR_ARRAY_TO_MAC_ADDR(c_macaddr,pwmi_mac_addr) do { \ + (pwmi_mac_addr)->mac_addr31to0 = \ + ( (c_macaddr)[0] | ((c_macaddr)[1] << 8) \ + | ((c_macaddr)[2] << 16) | ((c_macaddr)[3] << 24) ); \ + (pwmi_mac_addr)->mac_addr47to32 = \ + ( (c_macaddr)[4] | ((c_macaddr)[5] << 8)); \ + } while(0) + + +/* + * wmi command groups. + */ +typedef enum { + /* 0 to 2 are reserved */ + WMI_GRP_START=0x3, + WMI_GRP_SCAN=WMI_GRP_START, + WMI_GRP_PDEV, + WMI_GRP_VDEV, + WMI_GRP_PEER, + WMI_GRP_MGMT, + WMI_GRP_BA_NEG, + WMI_GRP_STA_PS, + WMI_GRP_DFS, + WMI_GRP_ROAM, + WMI_GRP_OFL_SCAN, + WMI_GRP_P2P, + WMI_GRP_AP_PS, + WMI_GRP_RATE_CTRL, + WMI_GRP_PROFILE, + WMI_GRP_SUSPEND, + WMI_GRP_BCN_FILTER, + WMI_GRP_WOW, + WMI_GRP_RTT, + WMI_GRP_SPECTRAL, + WMI_GRP_STATS, + WMI_GRP_ARP_NS_OFL, + WMI_GRP_NLO_OFL, + WMI_GRP_GTK_OFL, + WMI_GRP_CSA_OFL, + WMI_GRP_CHATTER, + WMI_GRP_TID_ADDBA, + WMI_GRP_MISC, + WMI_GRP_GPIO, + WMI_GRP_FWTEST, + WMI_GRP_TDLS, + WMI_GRP_RESMGR, + WMI_GRP_STA_SMPS, + WMI_GRP_WLAN_HB, + WMI_GRP_RMC, + WMI_GRP_MHF_OFL, + WMI_GRP_LOCATION_SCAN, + WMI_GRP_OEM, + WMI_GRP_NAN, + WMI_GRP_COEX, + WMI_GRP_OBSS_OFL, + WMI_GRP_LPI, + WMI_GRP_EXTSCAN, + WMI_GRP_DHCP_OFL, + WMI_GRP_IPA, + WMI_GRP_MDNS_OFL, + WMI_GRP_SAP_OFL, + WMI_GRP_OCB, + WMI_GRP_SOC, +} WMI_GRP_ID; + +#define WMI_CMD_GRP_START_ID(grp_id) (((grp_id) << 12) | 0x1) +#define WMI_EVT_GRP_START_ID(grp_id) (((grp_id) << 12) | 0x1) + +/** + * Command IDs and commange events + */ +typedef enum { + /** initialize the wlan sub system */ + WMI_INIT_CMDID=0x1, + + /* Scan specific commands */ + + /** start scan request to FW */ + WMI_START_SCAN_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_SCAN) , + /** stop scan request to FW */ + WMI_STOP_SCAN_CMDID, + /** full list of channels as defined by the regulatory that will be used by scanner */ + WMI_SCAN_CHAN_LIST_CMDID, + /** overwrite default priority table in scan scheduler */ + WMI_SCAN_SCH_PRIO_TBL_CMDID, + /** This command to adjust the priority and min.max_rest_time + * of an on ongoing scan request. + */ + WMI_SCAN_UPDATE_REQUEST_CMDID, + + /** set OUI to be used in probe request if enabled */ + WMI_SCAN_PROB_REQ_OUI_CMDID, + + /* PDEV(physical device) specific commands */ + /** set regulatorty ctl id used by FW to determine the exact ctl power limits */ + WMI_PDEV_SET_REGDOMAIN_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_PDEV), + /** set channel. mainly used for supporting monitor mode */ + WMI_PDEV_SET_CHANNEL_CMDID, + /** set pdev specific parameters */ + WMI_PDEV_SET_PARAM_CMDID, + /** enable packet log */ + WMI_PDEV_PKTLOG_ENABLE_CMDID, + /** disable packet log*/ + WMI_PDEV_PKTLOG_DISABLE_CMDID, + /** set wmm parameters */ + WMI_PDEV_SET_WMM_PARAMS_CMDID, + /** set HT cap ie that needs to be carried probe requests HT/VHT channels */ + WMI_PDEV_SET_HT_CAP_IE_CMDID, + /** set VHT cap ie that needs to be carried on probe requests on VHT channels */ + WMI_PDEV_SET_VHT_CAP_IE_CMDID, + + /** Command to send the DSCP-to-TID map to the target */ + WMI_PDEV_SET_DSCP_TID_MAP_CMDID, + /** set quiet ie parameters. primarily used in AP mode */ + WMI_PDEV_SET_QUIET_MODE_CMDID, + /** Enable/Disable Green AP Power Save */ + WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, + /** get TPC config for the current operating channel */ + WMI_PDEV_GET_TPC_CONFIG_CMDID, + + /** set the base MAC address for the physical device before a VDEV is created. + * For firmware that doesn't support this feature and this command, the pdev + * MAC address will not be changed. */ + WMI_PDEV_SET_BASE_MACADDR_CMDID, + + /* eeprom content dump , the same to bdboard data */ + WMI_PDEV_DUMP_CMDID, + /* set LED configuration */ + WMI_PDEV_SET_LED_CONFIG_CMDID, + /* Get Current temprature of chip in Celcius degree*/ + WMI_PDEV_GET_TEMPERATURE_CMDID, + /* Set LED flashing behavior */ + WMI_PDEV_SET_LED_FLASHING_CMDID, + + /* VDEV(virtual device) specific commands */ + /** vdev create */ + WMI_VDEV_CREATE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_VDEV), + /** vdev delete */ + WMI_VDEV_DELETE_CMDID, + /** vdev start request */ + WMI_VDEV_START_REQUEST_CMDID, + /** vdev restart request (RX only, NO TX, used for CAC period)*/ + WMI_VDEV_RESTART_REQUEST_CMDID, + /** vdev up request */ + WMI_VDEV_UP_CMDID, + /** vdev stop request */ + WMI_VDEV_STOP_CMDID, + /** vdev down request */ + WMI_VDEV_DOWN_CMDID, + /* set a vdev param */ + WMI_VDEV_SET_PARAM_CMDID, + /* set a key (used for setting per peer unicast and per vdev multicast) */ + WMI_VDEV_INSTALL_KEY_CMDID, + + /* wnm sleep mode command */ + WMI_VDEV_WNM_SLEEPMODE_CMDID, + WMI_VDEV_WMM_ADDTS_CMDID, + WMI_VDEV_WMM_DELTS_CMDID, + WMI_VDEV_SET_WMM_PARAMS_CMDID, + WMI_VDEV_SET_GTX_PARAMS_CMDID, + WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, + + WMI_VDEV_PLMREQ_START_CMDID, + WMI_VDEV_PLMREQ_STOP_CMDID, + /* TSF timestamp action for specified vdev */ + WMI_VDEV_TSF_TSTAMP_ACTION_CMDID, + /** set the capabilties IE, e.g. for extended caps in probe requests, + * assoc req etc for frames FW locally generates */ + WMI_VDEV_SET_IE_CMDID, + + /* peer specific commands */ + + /** create a peer */ + WMI_PEER_CREATE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_PEER), + /** delete a peer */ + WMI_PEER_DELETE_CMDID, + /** flush specific tid queues of a peer */ + WMI_PEER_FLUSH_TIDS_CMDID, + /** set a parameter of a peer */ + WMI_PEER_SET_PARAM_CMDID, + /** set peer to associated state. will cary all parameters determined during assocication time */ + WMI_PEER_ASSOC_CMDID, + /**add a wds (4 address ) entry. used only for testing WDS feature on AP products */ + WMI_PEER_ADD_WDS_ENTRY_CMDID, + /**remove wds (4 address ) entry. used only for testing WDS feature on AP products */ + WMI_PEER_REMOVE_WDS_ENTRY_CMDID, + /** set up mcast group infor for multicast to unicast conversion */ + WMI_PEER_MCAST_GROUP_CMDID, + /** request peer info from FW. FW shall respond with PEER_INFO_EVENTID */ + WMI_PEER_INFO_REQ_CMDID, + + /** request the estimated link speed for the peer. FW shall respond with + * WMI_PEER_ESTIMATED_LINKSPEED_EVENTID. + */ + WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, + /** Set the conditions to report peer justified rate to driver + * The justified rate means the the user-rate is justified by PER. + */ + WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID, + + /* beacon/management specific commands */ + + /** transmit beacon by reference . used for transmitting beacon on low latency interface like pcie */ + WMI_BCN_TX_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_MGMT), + /** transmit beacon by value */ + WMI_PDEV_SEND_BCN_CMDID, + /** set the beacon template. used in beacon offload mode to setup the + * the common beacon template with the FW to be used by FW to generate beacons */ + WMI_BCN_TMPL_CMDID, + /** set beacon filter with FW */ + WMI_BCN_FILTER_RX_CMDID, + /* enable/disable filtering of probe requests in the firmware */ + WMI_PRB_REQ_FILTER_RX_CMDID, + /** transmit management frame by value. will be deprecated */ + WMI_MGMT_TX_CMDID, + /** set the probe response template. used in beacon offload mode to setup the + * the common probe response template with the FW to be used by FW to generate + * probe responses */ + WMI_PRB_TMPL_CMDID, + + /** commands to directly control ba negotiation directly from host. only used in test mode */ + + /** turn off FW Auto addba mode and let host control addba */ + WMI_ADDBA_CLEAR_RESP_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_BA_NEG), + /** send add ba request */ + WMI_ADDBA_SEND_CMDID, + WMI_ADDBA_STATUS_CMDID, + /** send del ba */ + WMI_DELBA_SEND_CMDID, + /** set add ba response will be used by FW to generate addba response*/ + WMI_ADDBA_SET_RESP_CMDID, + /** send single VHT MPDU with AMSDU */ + WMI_SEND_SINGLEAMSDU_CMDID, + + /** Station power save specific config */ + /** enable/disable station powersave */ + WMI_STA_POWERSAVE_MODE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_STA_PS), + /** set station power save specific parameter */ + WMI_STA_POWERSAVE_PARAM_CMDID, + /** set station mimo powersave mode */ + WMI_STA_MIMO_PS_MODE_CMDID, + + + /** DFS-specific commands */ + /** enable DFS (radar detection)*/ + WMI_PDEV_DFS_ENABLE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_DFS), + /** disable DFS (radar detection)*/ + WMI_PDEV_DFS_DISABLE_CMDID, + /** enable DFS phyerr/parse filter offload */ + WMI_DFS_PHYERR_FILTER_ENA_CMDID, + /** enable DFS phyerr/parse filter offload */ + WMI_DFS_PHYERR_FILTER_DIS_CMDID, + + /* Roaming specific commands */ + /** set roam scan mode */ + WMI_ROAM_SCAN_MODE=WMI_CMD_GRP_START_ID(WMI_GRP_ROAM), + /** set roam scan rssi threshold below which roam scan is enabled */ + WMI_ROAM_SCAN_RSSI_THRESHOLD, + /** set roam scan period for periodic roam scan mode */ + WMI_ROAM_SCAN_PERIOD, + /** set roam scan trigger rssi change threshold */ + WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, + /** set roam AP profile */ + WMI_ROAM_AP_PROFILE, + /** set channel list for roam scans */ + WMI_ROAM_CHAN_LIST, + /** Stop scan command */ + WMI_ROAM_SCAN_CMD, + /** roaming sme offload sync complete */ + WMI_ROAM_SYNCH_COMPLETE, + /** set ric request element for 11r roaming */ + WMI_ROAM_SET_RIC_REQUEST_CMDID, + /** Invoke roaming forcefully */ + WMI_ROAM_INVOKE_CMDID, + /** roaming filter cmd to allow further filtering of roaming candidate */ + WMI_ROAM_FILTER_CMDID, + /** set gateway ip, mac and retries for subnet change detection */ + WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID, + + /** offload scan specific commands */ + /** set offload scan AP profile */ + WMI_OFL_SCAN_ADD_AP_PROFILE=WMI_CMD_GRP_START_ID(WMI_GRP_OFL_SCAN), + /** remove offload scan AP profile */ + WMI_OFL_SCAN_REMOVE_AP_PROFILE, + /** set offload scan period */ + WMI_OFL_SCAN_PERIOD, + + /* P2P specific commands */ + /**set P2P device info. FW will used by FW to create P2P IE to be carried in probe response + * generated during p2p listen and for p2p discoverability */ + WMI_P2P_DEV_SET_DEVICE_INFO=WMI_CMD_GRP_START_ID(WMI_GRP_P2P), + /** enable/disable p2p discoverability on STA/AP VDEVs */ + WMI_P2P_DEV_SET_DISCOVERABILITY, + /** set p2p ie to be carried in beacons generated by FW for GO */ + WMI_P2P_GO_SET_BEACON_IE, + /** set p2p ie to be carried in probe response frames generated by FW for GO */ + WMI_P2P_GO_SET_PROBE_RESP_IE, + /** set the vendor specific p2p ie data. FW will use this to parse the P2P NoA + * attribute in the beacons/probe responses received. + */ + WMI_P2P_SET_VENDOR_IE_DATA_CMDID, + /** set the configure of p2p find offload */ + WMI_P2P_DISC_OFFLOAD_CONFIG_CMDID, + /** set the vendor specific p2p ie data for p2p find offload using */ + WMI_P2P_DISC_OFFLOAD_APPIE_CMDID, + /** set the BSSID/device name pattern of p2p find offload */ + WMI_P2P_DISC_OFFLOAD_PATTERN_CMDID, + /** set OppPS related parameters **/ + WMI_P2P_SET_OPPPS_PARAM_CMDID, + + /** AP power save specific config */ + /** set AP power save specific param */ + WMI_AP_PS_PEER_PARAM_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_AP_PS), + /** set AP UAPSD coex pecific param */ + WMI_AP_PS_PEER_UAPSD_COEX_CMDID, + + + /** Rate-control specific commands */ + WMI_PEER_RATE_RETRY_SCHED_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_RATE_CTRL), + + /** WLAN Profiling commands. */ + WMI_WLAN_PROFILE_TRIGGER_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_PROFILE), + WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, + WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, + WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, + WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, + + /** Suspend resume command Ids */ + WMI_PDEV_SUSPEND_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_SUSPEND), + WMI_PDEV_RESUME_CMDID, + + /* Beacon filter commands */ + /** add a beacon filter */ + WMI_ADD_BCN_FILTER_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_BCN_FILTER), + /** remove a beacon filter */ + WMI_RMV_BCN_FILTER_CMDID, + + /* WOW Specific WMI commands*/ + /** add pattern for awake */ + WMI_WOW_ADD_WAKE_PATTERN_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_WOW), + /** deleta a wake pattern */ + WMI_WOW_DEL_WAKE_PATTERN_CMDID, + /** enable/deisable wake event */ + WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, + /** enable WOW */ + WMI_WOW_ENABLE_CMDID, + /** host woke up from sleep event to FW. Generated in response to WOW Hardware event */ + WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, + /* IOAC add keep alive cmd. */ + WMI_WOW_IOAC_ADD_KEEPALIVE_CMDID, + /* IOAC del keep alive cmd. */ + WMI_WOW_IOAC_DEL_KEEPALIVE_CMDID, + /* IOAC add pattern for awake */ + WMI_WOW_IOAC_ADD_WAKE_PATTERN_CMDID, + /* IOAC deleta a wake pattern */ + WMI_WOW_IOAC_DEL_WAKE_PATTERN_CMDID, + /* D0-WOW enable or disable cmd */ + WMI_D0_WOW_ENABLE_DISABLE_CMDID, + /* enable extend WoW */ + WMI_EXTWOW_ENABLE_CMDID, + /* Extend WoW command to configure app type1 parameter */ + WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, + /* Extend WoW command to configure app type2 parameter */ + WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, + + /* RTT measurement related cmd */ + /** reques to make an RTT measurement */ + WMI_RTT_MEASREQ_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_RTT), + /** reques to report a tsf measurement */ + WMI_RTT_TSF_CMDID, + + /** spectral scan command */ + /** configure spectral scan */ + WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_SPECTRAL), + /** enable/disable spectral scan and trigger */ + WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, + + /* F/W stats */ + /** one time request for stats */ + WMI_REQUEST_STATS_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_STATS), + /** Push MCC Adaptive Scheduler Stats to Firmware */ + WMI_MCC_SCHED_TRAFFIC_STATS_CMDID, + /** one time request for txrx stats */ + WMI_REQUEST_STATS_EXT_CMDID, + + /* Link Layer stats */ + /** Request for link layer stats */ + WMI_REQUEST_LINK_STATS_CMDID, + /** Request for setting params to link layer stats */ + WMI_START_LINK_STATS_CMDID, + /** Request to clear stats*/ + WMI_CLEAR_LINK_STATS_CMDID, + + /** Request for getting the Firmware Memory Dump */ + WMI_GET_FW_MEM_DUMP_CMDID, + + /** Request to flush of the buffered debug messages */ + WMI_DEBUG_MESG_FLUSH_CMDID, + + /** ARP OFFLOAD REQUEST*/ + WMI_SET_ARP_NS_OFFLOAD_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_ARP_NS_OFL), + + /** Proactive ARP Response Add Pattern Command*/ + WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, + + /** Proactive ARP Response Del Pattern Command*/ + WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, + + /** NS offload confid*/ + WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_NLO_OFL), + + /** APFIND Config */ + WMI_APFIND_CMDID, + + /** Passpoint list config */ + WMI_PASSPOINT_LIST_CONFIG_CMDID, + + /* GTK offload Specific WMI commands*/ + WMI_GTK_OFFLOAD_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_GTK_OFL), + + /* CSA offload Specific WMI commands*/ + /** csa offload enable */ + WMI_CSA_OFFLOAD_ENABLE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_CSA_OFL), + /** chan switch command */ + WMI_CSA_OFFLOAD_CHANSWITCH_CMDID, + + /* Chatter commands*/ + /* Change chatter mode of operation */ + WMI_CHATTER_SET_MODE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_CHATTER), + /** chatter add coalescing filter command */ + WMI_CHATTER_ADD_COALESCING_FILTER_CMDID, + /** chatter delete coalescing filter command */ + WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID, + /** chatter coalecing query command */ + WMI_CHATTER_COALESCING_QUERY_CMDID, + + /**addba specific commands */ + /** start the aggregation on this TID */ + WMI_PEER_TID_ADDBA_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_TID_ADDBA), + /** stop the aggregation on this TID */ + WMI_PEER_TID_DELBA_CMDID, + + /** set station mimo powersave method */ + WMI_STA_DTIM_PS_METHOD_CMDID, + /** Configure the Station UAPSD AC Auto Trigger Parameters */ + WMI_STA_UAPSD_AUTO_TRIG_CMDID, + /** Configure the Keep Alive Parameters */ + WMI_STA_KEEPALIVE_CMDID, + + /* Request ssn from target for a sta/tid pair */ + WMI_BA_REQ_SSN_CMDID, + /* misc command group */ + /** echo command mainly used for testing */ + WMI_ECHO_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_MISC), + + /* !!IMPORTANT!! + * If you need to add a new WMI command to the WMI_GRP_MISC sub-group, + * please make sure you add it BEHIND WMI_PDEV_UTF_CMDID, + * as we MUST have a fixed value here to maintain compatibility between + * UTF and the ART2 driver + */ + /** UTF WMI commands */ + WMI_PDEV_UTF_CMDID, + + /** set debug log config */ + WMI_DBGLOG_CFG_CMDID, + /* QVIT specific command id */ + WMI_PDEV_QVIT_CMDID, + /* Factory Testing Mode request command + * used for integrated chipsets */ + WMI_PDEV_FTM_INTG_CMDID, + /* set and get keepalive parameters command */ + WMI_VDEV_SET_KEEPALIVE_CMDID, + WMI_VDEV_GET_KEEPALIVE_CMDID, + /* For fw recovery test command */ + WMI_FORCE_FW_HANG_CMDID, + /* Set Mcast/Bdcast filter */ + WMI_SET_MCASTBCAST_FILTER_CMDID, + /** set thermal management params **/ + WMI_THERMAL_MGMT_CMDID, + /** set host auto shutdown params **/ + WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, + /** set tpc chainmask config command */ + WMI_TPC_CHAINMASK_CONFIG_CMDID, + /** set Antenna diversity command */ + WMI_SET_ANTENNA_DIVERSITY_CMDID, + /** Set OCB Sched Request, deprecated */ + WMI_OCB_SET_SCHED_CMDID, + /** Set rssi monitoring config command */ + WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID, + /* GPIO Configuration */ + WMI_GPIO_CONFIG_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_GPIO), + WMI_GPIO_OUTPUT_CMDID, + + /* Txbf configuration command */ + WMI_TXBF_CMDID, + + /* FWTEST Commands */ + WMI_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_FWTEST), + /** set NoA descs **/ + WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, + /* UNIT Tests */ + WMI_UNIT_TEST_CMDID, + + /** TDLS Configuration */ + /** enable/disable TDLS */ + WMI_TDLS_SET_STATE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_TDLS), + /** set tdls peer state */ + WMI_TDLS_PEER_UPDATE_CMDID, + /** TDLS Offchannel control */ + WMI_TDLS_SET_OFFCHAN_MODE_CMDID, + + /** Resmgr Configuration */ + /** Adaptive OCS is enabled by default in the FW. This command is used to + * disable FW based adaptive OCS. + */ + WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_RESMGR), + /** set the requested channel time quota for the home channels */ + WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, + /** set the requested latency for the home channels */ + WMI_RESMGR_SET_CHAN_LATENCY_CMDID, + + /** STA SMPS Configuration */ + /** force SMPS mode */ + WMI_STA_SMPS_FORCE_MODE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_STA_SMPS), + /** set SMPS parameters */ + WMI_STA_SMPS_PARAM_CMDID, + + /* Wlan HB commands*/ + /* enalbe/disable wlan HB */ + WMI_HB_SET_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_WLAN_HB), + /* set tcp parameters for wlan HB */ + WMI_HB_SET_TCP_PARAMS_CMDID, + /* set tcp pkt filter for wlan HB */ + WMI_HB_SET_TCP_PKT_FILTER_CMDID, + /* set udp parameters for wlan HB */ + WMI_HB_SET_UDP_PARAMS_CMDID, + /* set udp pkt filter for wlan HB */ + WMI_HB_SET_UDP_PKT_FILTER_CMDID, + + /** Wlan RMC commands*/ + /** enable/disable RMC */ + WMI_RMC_SET_MODE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_RMC), + /** configure action frame period */ + WMI_RMC_SET_ACTION_PERIOD_CMDID, + /** For debug/future enhancement purposes only, + * configures/finetunes RMC algorithms */ + WMI_RMC_CONFIG_CMDID, + + /** WLAN MHF offload commands */ + /** enable/disable MHF offload */ + WMI_MHF_OFFLOAD_SET_MODE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_MHF_OFL), + /** Plumb routing table for MHF offload */ + WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID, + + /*location scan commands*/ + /*start batch scan*/ + WMI_BATCH_SCAN_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_LOCATION_SCAN), + /*stop batch scan*/ + WMI_BATCH_SCAN_DISABLE_CMDID, + /*get batch scan result*/ + WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID, + /* OEM related cmd */ + WMI_OEM_REQ_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_OEM), + + /** Nan Request */ + WMI_NAN_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_NAN), + + /** Modem power state command */ + WMI_MODEM_POWER_STATE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_COEX), + WMI_CHAN_AVOID_UPDATE_CMDID, + + /** + * OBSS scan offload enable/disable commands + * OBSS scan enable CMD will send to FW after VDEV UP, if these conditions are true: + * 1. WMI_SERVICE_OBSS_SCAN is reported by FW in service ready, + * 2. STA connect to a 2.4Ghz ht20/ht40 AP, + * 3. AP enable 20/40 coexistence (OBSS_IE-74 can be found in beacon or association response) + * If OBSS parameters from beacon changed, also use enable CMD to update parameters. + * OBSS scan disable CMD will send to FW if have enabled when tearing down connection. + */ + WMI_OBSS_SCAN_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_OBSS_OFL), + WMI_OBSS_SCAN_DISABLE_CMDID, + + /**LPI commands*/ + /**LPI mgmt snooping config command*/ + WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_LPI), + /**LPI scan start command*/ + WMI_LPI_START_SCAN_CMDID, + /**LPI scan stop command*/ + WMI_LPI_STOP_SCAN_CMDID, + + /** ExtScan commands */ + WMI_EXTSCAN_START_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_EXTSCAN), + WMI_EXTSCAN_STOP_CMDID, + WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID, + WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID, + WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID, + WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID, + WMI_EXTSCAN_SET_CAPABILITIES_CMDID, + WMI_EXTSCAN_GET_CAPABILITIES_CMDID, + WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID, + + /** DHCP server offload commands */ + WMI_SET_DHCP_SERVER_OFFLOAD_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_DHCP_OFL), + + /** IPA Offload features related commands */ + WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_IPA), + + /** mDNS responder offload commands */ + WMI_MDNS_OFFLOAD_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_MDNS_OFL), + WMI_MDNS_SET_FQDN_CMDID, + WMI_MDNS_SET_RESPONSE_CMDID, + WMI_MDNS_GET_STATS_CMDID, + + /* enable/disable AP Authentication offload */ + WMI_SAP_OFL_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_SAP_OFL), + + /** Out-of-context-of-BSS (OCB) commands */ + WMI_OCB_SET_CONFIG_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_OCB), + WMI_OCB_SET_UTC_TIME_CMDID, + WMI_OCB_START_TIMING_ADVERT_CMDID, + WMI_OCB_STOP_TIMING_ADVERT_CMDID, + WMI_OCB_GET_TSF_TIMER_CMDID, + WMI_DCC_GET_STATS_CMDID, + WMI_DCC_CLEAR_STATS_CMDID, + WMI_DCC_UPDATE_NDL_CMDID, + /* System-On-Chip commands */ + WMI_SOC_SET_PCL_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_SOC), + WMI_SOC_SET_HW_MODE_CMDID, + +} WMI_CMD_ID; + +typedef enum { + /** WMI service is ready; after this event WMI messages can be sent/received */ + WMI_SERVICE_READY_EVENTID=0x1, + /** WMI is ready; after this event the wlan subsystem is initialized and can process commands. */ + WMI_READY_EVENTID, + + /** Scan specific events */ + WMI_SCAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SCAN) , + + /* PDEV specific events */ + /** TPC config for the current operating channel */ + WMI_PDEV_TPC_CONFIG_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PDEV) , + /** Channel stats event */ + WMI_CHAN_INFO_EVENTID, + + /** PHY Error specific WMI event */ + WMI_PHYERR_EVENTID, + + /** eeprom dump event */ + WMI_PDEV_DUMP_EVENTID, + + /** traffic pause event */ + WMI_TX_PAUSE_EVENTID, + + /** DFS radar event */ + WMI_DFS_RADAR_EVENTID, + + /** track L1SS entry and residency event */ + WMI_PDEV_L1SS_TRACK_EVENTID, + + /** Report current temprature of the chip in Celcius degree */ + WMI_PDEV_TEMPERATURE_EVENTID, + + /* VDEV specific events */ + /** VDEV started event in response to VDEV_START request */ + WMI_VDEV_START_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_VDEV), + /** vdev stopped event , generated in response to VDEV_STOP request */ + WMI_VDEV_STOPPED_EVENTID, + /* Indicate the set key (used for setting per + * peer unicast and per vdev multicast) + * operation has completed */ + WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID, + /* NOTE: WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID would be deprecated. Please + don't use this for any new implementations */ + /* Firmware requests dynamic change to a specific beacon interval for a specific vdev ID in MCC scenario. + This request is valid only for vdevs operating in soft AP or P2P GO mode */ + WMI_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, + + /* Return the TSF timestamp of specified vdev */ + WMI_VDEV_TSF_REPORT_EVENTID, + + /* peer specific events */ + /** FW reauet to kick out the station for reasons like inactivity,lack of response ..etc */ + WMI_PEER_STA_KICKOUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PEER), + + /** Peer Info Event with data_rate, rssi, tx_fail_cnt etc */ + WMI_PEER_INFO_EVENTID, + + /** Event indicating that TX fail count reaching threshold */ + WMI_PEER_TX_FAIL_CNT_THR_EVENTID, + /** Return the estimate link speed for the Peer specified in the + * WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID command. + */ + WMI_PEER_ESTIMATED_LINKSPEED_EVENTID, + /* Return the peer state + * WMI_PEER_SET_PARAM_CMDID, WMI_PEER_AUTHORIZE + */ + WMI_PEER_STATE_EVENTID, + + /* beacon/mgmt specific events */ + /** RX management frame. the entire frame is carried along with the event. */ + WMI_MGMT_RX_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MGMT), + /** software beacon alert event to Host requesting host to Queue a beacon for transmission + use only in host beacon mode */ + WMI_HOST_SWBA_EVENTID, + /** beacon tbtt offset event indicating the tsf offset of the tbtt from the theritical value. + tbtt offset is normally 0 and will be non zero if there are multiple VDEVs operating in + staggered beacon transmission mode */ + WMI_TBTTOFFSET_UPDATE_EVENTID, + + /** event after the first beacon is transmitted following + a change in the template.*/ + WMI_OFFLOAD_BCN_TX_STATUS_EVENTID, + /** event after the first probe response is transmitted following + a change in the template.*/ + WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID, + + /*ADDBA Related WMI Events*/ + /** Indication the completion of the prior + WMI_PEER_TID_DELBA_CMDID(initiator) */ + WMI_TX_DELBA_COMPLETE_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_BA_NEG), + /** Indication the completion of the prior + *WMI_PEER_TID_ADDBA_CMDID(initiator) */ + WMI_TX_ADDBA_COMPLETE_EVENTID, + + /* Seq num returned from hw for a sta/tid pair */ + WMI_BA_RSP_SSN_EVENTID, + + /* Aggregation state requested by BTC */ + WMI_AGGR_STATE_TRIG_EVENTID, + + /** Roam event to trigger roaming on host */ + WMI_ROAM_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_ROAM), + + /** matching AP found from list of profiles */ + WMI_PROFILE_MATCH, + /** roam synch event */ + WMI_ROAM_SYNCH_EVENTID, + + /** P2P disc found */ + WMI_P2P_DISC_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_P2P), + + /*send noa info to host when noa is changed for beacon tx offload enable*/ + WMI_P2P_NOA_EVENTID, + + /* send pdev resume event to host after pdev resume. */ + WMI_PDEV_RESUME_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SUSPEND), + + /** WOW wake up host event.generated in response to WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID. + will cary wake reason */ + WMI_WOW_WAKEUP_HOST_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_WOW), + WMI_D0_WOW_DISABLE_ACK_EVENTID, + WMI_WOW_INITIAL_WAKEUP_EVENTID, + + /*RTT related event ID*/ + /** RTT measurement report */ + WMI_RTT_MEASUREMENT_REPORT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_RTT), + /** TSF measurement report */ + WMI_TSF_MEASUREMENT_REPORT_EVENTID, + /** RTT error report */ + WMI_RTT_ERROR_REPORT_EVENTID, + /*STATS specific events*/ + /** txrx stats event requested by host */ + WMI_STATS_EXT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_STATS), + /** FW iface link stats Event */ + WMI_IFACE_LINK_STATS_EVENTID, + /** FW iface peer link stats Event */ + WMI_PEER_LINK_STATS_EVENTID, + /** FW Update radio stats Event */ + WMI_RADIO_LINK_STATS_EVENTID, + + /** Firmware memory dump Complete event*/ + WMI_UPDATE_FW_MEM_DUMP_EVENTID, + + /*NLO specific events*/ + /** NLO match event after the first match */ + WMI_NLO_MATCH_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_NLO_OFL), + + /** NLO scan complete event */ + WMI_NLO_SCAN_COMPLETE_EVENTID, + + /** APFIND specific events */ + WMI_APFIND_EVENTID, + + /** passpoint network match event */ + WMI_PASSPOINT_MATCH_EVENTID, + + /** GTK offload stautus event requested by host */ + WMI_GTK_OFFLOAD_STATUS_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GTK_OFL), + + /** GTK offload failed to rekey event */ + WMI_GTK_REKEY_FAIL_EVENTID, + /* CSA IE received event */ + WMI_CSA_HANDLING_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_CSA_OFL), + + /*chatter query reply event*/ + WMI_CHATTER_PC_QUERY_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_CHATTER), + + /** echo event in response to echo command */ + WMI_ECHO_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MISC), + + /* !!IMPORTANT!! + * If you need to add a new WMI event ID to the WMI_GRP_MISC sub-group, + * please make sure you add it BEHIND WMI_PDEV_UTF_EVENTID, + * as we MUST have a fixed value here to maintain compatibility between + * UTF and the ART2 driver + */ + /** UTF specific WMI event */ + WMI_PDEV_UTF_EVENTID, + + /** event carries buffered debug messages */ + WMI_DEBUG_MESG_EVENTID, + /** FW stats(periodic or on shot) */ + WMI_UPDATE_STATS_EVENTID, + /** debug print message used for tracing FW code while debugging */ + WMI_DEBUG_PRINT_EVENTID, + /** DCS wlan or non-wlan interference event + */ + WMI_DCS_INTERFERENCE_EVENTID, + /** VI spoecific event */ + WMI_PDEV_QVIT_EVENTID, + /** FW code profile data in response to profile request */ + WMI_WLAN_PROFILE_DATA_EVENTID, + /* Factory Testing Mode request event + * used for integrated chipsets */ + WMI_PDEV_FTM_INTG_EVENTID, + /* avoid list of frequencies . + */ + WMI_WLAN_FREQ_AVOID_EVENTID, + /* Indicate the keepalive parameters */ + WMI_VDEV_GET_KEEPALIVE_EVENTID, + /* Thermal Management event */ + WMI_THERMAL_MGMT_EVENTID, + + /* Container for QXDM/DIAG events */ + WMI_DIAG_DATA_CONTAINER_EVENTID, + + /* host auto shutdown event */ + WMI_HOST_AUTO_SHUTDOWN_EVENTID, + + /*update mib counters together with WMI_UPDATE_STATS_EVENTID*/ + WMI_UPDATE_WHAL_MIB_STATS_EVENTID, + + /*update ht/vht info based on vdev (rx and tx NSS and preamble)*/ + WMI_UPDATE_VDEV_RATE_STATS_EVENTID, + + WMI_DIAG_EVENTID, + + /** Set OCB Sched Response, deprecated */ + WMI_OCB_SET_SCHED_EVENTID, + + /** event to indicate the flush of the buffered debug messages is complete*/ + WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID, + + /** event to report mix/max RSSI breach events */ + WMI_RSSI_BREACH_EVENTID, + + /* GPIO Event */ + WMI_GPIO_INPUT_EVENTID=WMI_EVT_GRP_START_ID(WMI_GRP_GPIO), + /** upload H_CV info WMI event + * to indicate uploaded H_CV info to host + */ + WMI_UPLOADH_EVENTID, + + /** capture H info WMI event + * to indicate captured H info to host + */ + WMI_CAPTUREH_EVENTID, + /* hw RFkill */ + WMI_RFKILL_STATE_CHANGE_EVENTID, + + /* TDLS Event */ + WMI_TDLS_PEER_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_TDLS), + + /*location scan event*/ + /*report the firmware's capability of batch scan*/ + WMI_BATCH_SCAN_ENABLED_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_LOCATION_SCAN), + /*batch scan result*/ + WMI_BATCH_SCAN_RESULT_EVENTID, + /* OEM Event */ + WMI_OEM_CAPABILITY_EVENTID=WMI_EVT_GRP_START_ID(WMI_GRP_OEM), + WMI_OEM_MEASUREMENT_REPORT_EVENTID, + WMI_OEM_ERROR_REPORT_EVENTID, + + /* NAN Event */ + WMI_NAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_NAN), + + /* LPI Event */ + WMI_LPI_RESULT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_LPI), + WMI_LPI_STATUS_EVENTID, + WMI_LPI_HANDOFF_EVENTID, + + /* ExtScan events */ + WMI_EXTSCAN_START_STOP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_EXTSCAN), + WMI_EXTSCAN_OPERATION_EVENTID, + WMI_EXTSCAN_TABLE_USAGE_EVENTID, + WMI_EXTSCAN_CACHED_RESULTS_EVENTID, + WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID, + WMI_EXTSCAN_HOTLIST_MATCH_EVENTID, + WMI_EXTSCAN_CAPABILITIES_EVENTID, + WMI_EXTSCAN_HOTLIST_SSID_MATCH_EVENTID, + + /* mDNS offload events */ + WMI_MDNS_STATS_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MDNS_OFL), + + /* SAP Authentication offload events */ + WMI_SAP_OFL_ADD_STA_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SAP_OFL), + WMI_SAP_OFL_DEL_STA_EVENTID, + + + /** Out-of-context-of-bss (OCB) events */ + WMI_OCB_SET_CONFIG_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_OCB), + WMI_OCB_GET_TSF_TIMER_RESP_EVENTID, + WMI_DCC_GET_STATS_RESP_EVENTID, + WMI_DCC_UPDATE_NDL_RESP_EVENTID, + WMI_DCC_STATS_EVENTID, + + /* System-On-Chip events */ + WMI_SOC_SET_HW_MODE_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SOC), + WMI_SOC_HW_MODE_TRANSITION_EVENTID, +} WMI_EVT_ID; + +/* defines for OEM message sub-types */ +#define WMI_OEM_CAPABILITY_REQ 0x01 +#define WMI_OEM_CAPABILITY_RSP 0x02 +#define WMI_OEM_MEASUREMENT_REQ 0x03 +#define WMI_OEM_MEASUREMENT_RSP 0x04 +#define WMI_OEM_ERROR_REPORT_RSP 0x05 +#define WMI_OEM_NAN_MEAS_REQ 0x06 +#define WMI_OEM_NAN_MEAS_RSP 0x07 +#define WMI_OEM_NAN_PEER_INFO 0x08 +#define WMI_OEM_CONFIGURE_LCR 0x09 +#define WMI_OEM_CONFIGURE_LCI 0x0A + + +/* below message subtype is internal to CLD. Target should + * never use internal response type + */ +#define WMI_OEM_INTERNAL_RSP 0xdeadbeef + +#define WMI_CHAN_LIST_TAG 0x1 +#define WMI_SSID_LIST_TAG 0x2 +#define WMI_BSSID_LIST_TAG 0x3 +#define WMI_IE_TAG 0x4 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_channel */ + /** primary 20 MHz channel frequency in mhz */ + A_UINT32 mhz; + /** Center frequency 1 in MHz*/ + A_UINT32 band_center_freq1; + /** Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode*/ + A_UINT32 band_center_freq2; + /** channel info described below */ + A_UINT32 info; + /** contains min power, max power, reg power and reg class id. */ + A_UINT32 reg_info_1; + /** contains antennamax */ + A_UINT32 reg_info_2; +} wmi_channel; + +typedef enum{ +WMI_CHANNEL_CHANGE_CAUSE_NONE = 0, +WMI_CHANNEL_CHANGE_CAUSE_CSA, +}wmi_channel_change_cause; + +/** channel info consists of 6 bits of channel mode */ + +#define WMI_SET_CHANNEL_MODE(pwmi_channel,val) do { \ + (pwmi_channel)->info &= 0xffffffc0; \ + (pwmi_channel)->info |= (val); \ + } while(0) + +#define WMI_GET_CHANNEL_MODE(pwmi_channel) ((pwmi_channel)->info & 0x0000003f ) + +#define WMI_CHAN_FLAG_HT40_PLUS 6 +#define WMI_CHAN_FLAG_PASSIVE 7 +#define WMI_CHAN_ADHOC_ALLOWED 8 +#define WMI_CHAN_AP_DISABLED 9 +#define WMI_CHAN_FLAG_DFS 10 +#define WMI_CHAN_FLAG_ALLOW_HT 11 /* HT is allowed on this channel */ +#define WMI_CHAN_FLAG_ALLOW_VHT 12 /* VHT is allowed on this channel */ +#define WMI_CHANNEL_CHANGE_CAUSE_CSA 13 /*Indicate reason for channel switch */ +#define WMI_CHAN_FLAG_HALF_RATE 14 /* Indicates half rate channel */ +#define WMI_CHAN_FLAG_QUARTER_RATE 15 /* Indicates quarter rate channel */ + +#define WMI_SET_CHANNEL_FLAG(pwmi_channel,flag) do { \ + (pwmi_channel)->info |= (1 << flag); \ + } while(0) + +#define WMI_GET_CHANNEL_FLAG(pwmi_channel,flag) \ + (((pwmi_channel)->info & (1 << flag)) >> flag) + +#define WMI_SET_CHANNEL_MIN_POWER(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_1 &= 0xffffff00; \ + (pwmi_channel)->reg_info_1 |= (val&0xff); \ + } while(0) +#define WMI_GET_CHANNEL_MIN_POWER(pwmi_channel) ((pwmi_channel)->reg_info_1 & 0xff ) + +#define WMI_SET_CHANNEL_MAX_POWER(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_1 &= 0xffff00ff; \ + (pwmi_channel)->reg_info_1 |= ((val&0xff) << 8); \ + } while(0) +#define WMI_GET_CHANNEL_MAX_POWER(pwmi_channel) ( (((pwmi_channel)->reg_info_1) >> 8) & 0xff ) + +#define WMI_SET_CHANNEL_REG_POWER(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_1 &= 0xff00ffff; \ + (pwmi_channel)->reg_info_1 |= ((val&0xff) << 16); \ + } while(0) +#define WMI_GET_CHANNEL_REG_POWER(pwmi_channel) ( (((pwmi_channel)->reg_info_1) >> 16) & 0xff ) +#define WMI_SET_CHANNEL_REG_CLASSID(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_1 &= 0x00ffffff; \ + (pwmi_channel)->reg_info_1 |= ((val&0xff) << 24); \ + } while(0) +#define WMI_GET_CHANNEL_REG_CLASSID(pwmi_channel) ( (((pwmi_channel)->reg_info_1) >> 24) & 0xff ) + +#define WMI_SET_CHANNEL_ANTENNA_MAX(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_2 &= 0xffffff00; \ + (pwmi_channel)->reg_info_2 |= (val&0xff); \ + } while(0) +#define WMI_GET_CHANNEL_ANTENNA_MAX(pwmi_channel) ((pwmi_channel)->reg_info_2 & 0xff ) + +/* max tx power is in 1 dBm units */ +#define WMI_SET_CHANNEL_MAX_TX_POWER(pwmi_channel,val) do { \ + (pwmi_channel)->reg_info_2 &= 0xffff00ff; \ + (pwmi_channel)->reg_info_2 |= ((val&0xff)<<8); \ + } while(0) +#define WMI_GET_CHANNEL_MAX_TX_POWER(pwmi_channel) ( (((pwmi_channel)->reg_info_2)>>8) & 0xff ) + + +/** HT Capabilities*/ +#define WMI_HT_CAP_ENABLED 0x0001 /* HT Enabled/ disabled */ +#define WMI_HT_CAP_HT20_SGI 0x0002 /* Short Guard Interval with HT20 */ +#define WMI_HT_CAP_DYNAMIC_SMPS 0x0004 /* Dynamic MIMO powersave */ +#define WMI_HT_CAP_TX_STBC 0x0008 /* B3 TX STBC */ +#define WMI_HT_CAP_TX_STBC_MASK_SHIFT 3 +#define WMI_HT_CAP_RX_STBC 0x0030 /* B4-B5 RX STBC */ +#define WMI_HT_CAP_RX_STBC_MASK_SHIFT 4 +#define WMI_HT_CAP_LDPC 0x0040 /* LDPC supported */ +#define WMI_HT_CAP_L_SIG_TXOP_PROT 0x0080 /* L-SIG TXOP Protection */ +#define WMI_HT_CAP_MPDU_DENSITY 0x0700 /* MPDU Density */ +#define WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 8 +#define WMI_HT_CAP_HT40_SGI 0x0800 + +/* These macros should be used when we wish to advertise STBC support for + * only 1SS or 2SS or 3SS. */ +#define WMI_HT_CAP_RX_STBC_1SS 0x0010 /* B4-B5 RX STBC */ +#define WMI_HT_CAP_RX_STBC_2SS 0x0020 /* B4-B5 RX STBC */ +#define WMI_HT_CAP_RX_STBC_3SS 0x0030 /* B4-B5 RX STBC */ + + +#define WMI_HT_CAP_DEFAULT_ALL (WMI_HT_CAP_ENABLED | \ + WMI_HT_CAP_HT20_SGI | \ + WMI_HT_CAP_HT40_SGI | \ + WMI_HT_CAP_TX_STBC | \ + WMI_HT_CAP_RX_STBC | \ + WMI_HT_CAP_LDPC) + +/* WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information + field. The fields not defined here are not supported, or reserved. + Do not change these masks and if you have to add new one follow the + bitmask as specified by 802.11ac draft. +*/ + +#define WMI_VHT_CAP_MAX_MPDU_LEN_MASK 0x00000003 +#define WMI_VHT_CAP_RX_LDPC 0x00000010 +#define WMI_VHT_CAP_SGI_80MHZ 0x00000020 +#define WMI_VHT_CAP_TX_STBC 0x00000080 +#define WMI_VHT_CAP_RX_STBC_MASK 0x00000300 +#define WMI_VHT_CAP_RX_STBC_MASK_SHIFT 8 +#define WMI_VHT_CAP_SU_BFORMER 0x00000800 +#define WMI_VHT_CAP_SU_BFORMEE 0x00001000 +#define WMI_VHT_CAP_MAX_CS_ANT_MASK 0x0000E000 +#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT 13 +#define WMI_VHT_CAP_MAX_SND_DIM_MASK 0x00070000 +#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT 16 +#define WMI_VHT_CAP_MU_BFORMER 0x00080000 +#define WMI_VHT_CAP_MU_BFORMEE 0x00100000 +#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP 0x03800000 +#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIT 23 +#define WMI_VHT_CAP_RX_FIXED_ANT 0x10000000 +#define WMI_VHT_CAP_TX_FIXED_ANT 0x20000000 + +#define WMI_VHT_CAP_MAX_MPDU_LEN_11454 0x00000002 + +/* These macros should be used when we wish to advertise STBC support for + * only 1SS or 2SS or 3SS. */ +#define WMI_VHT_CAP_RX_STBC_1SS 0x00000100 +#define WMI_VHT_CAP_RX_STBC_2SS 0x00000200 +#define WMI_vHT_CAP_RX_STBC_3SS 0x00000300 + +#define WMI_VHT_CAP_DEFAULT_ALL (WMI_VHT_CAP_MAX_MPDU_LEN_11454 | \ + WMI_VHT_CAP_SGI_80MHZ | \ + WMI_VHT_CAP_TX_STBC | \ + WMI_VHT_CAP_RX_STBC_MASK | \ + WMI_VHT_CAP_RX_LDPC | \ + WMI_VHT_CAP_MAX_AMPDU_LEN_EXP | \ + WMI_VHT_CAP_RX_FIXED_ANT | \ + WMI_VHT_CAP_TX_FIXED_ANT) + +/* Interested readers refer to Rx/Tx MCS Map definition as defined in + 802.11ac +*/ +#define WMI_VHT_MAX_MCS_4_SS_MASK(r,ss) ((3 & (r)) << (((ss) - 1) << 1)) +#define WMI_VHT_MAX_SUPP_RATE_MASK 0x1fff0000 +#define WMI_VHT_MAX_SUPP_RATE_MASK_SHIFT 16 + +/* WMI_SYS_CAPS_* refer to the capabilities that system support +*/ +#define WMI_SYS_CAP_ENABLE 0x00000001 +#define WMI_SYS_CAP_TXPOWER 0x00000002 + +/* + * WMI Dual Band Simultaneous (DBS) hardware mode list bit-mask definitions. + * Bits 5:0 are reserved + */ +#define WMI_DBS_HW_MODE_MAC0_TX_STREAMS_BITPOS (28) +#define WMI_DBS_HW_MODE_MAC0_RX_STREAMS_BITPOS (24) +#define WMI_DBS_HW_MODE_MAC1_TX_STREAMS_BITPOS (20) +#define WMI_DBS_HW_MODE_MAC1_RX_STREAMS_BITPOS (16) +#define WMI_DBS_HW_MODE_MAC0_BANDWIDTH_BITPOS (12) +#define WMI_DBS_HW_MODE_MAC1_BANDWIDTH_BITPOS (8) +#define WMI_DBS_HW_MODE_DBS_MODE_BITPOS (7) +#define WMI_DBS_HW_MODE_AGILE_DFS_MODE_BITPOS (6) + +#define WMI_DBS_HW_MODE_MAC0_TX_STREAMS_MASK (0xf << WMI_DBS_HW_MODE_MAC0_TX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC0_RX_STREAMS_MASK (0xf << WMI_DBS_HW_MODE_MAC0_RX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_TX_STREAMS_MASK (0xf << WMI_DBS_HW_MODE_MAC1_TX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_RX_STREAMS_MASK (0xf << WMI_DBS_HW_MODE_MAC1_RX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC0_BANDWIDTH_MASK (0xf << WMI_DBS_HW_MODE_MAC0_BANDWIDTH_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_BANDWIDTH_MASK (0xf << WMI_DBS_HW_MODE_MAC1_BANDWIDTH_BITPOS) +#define WMI_DBS_HW_MODE_DBS_MODE_MASK (0x1 << WMI_DBS_HW_MODE_DBS_MODE_BITPOS) +#define WMI_DBS_HW_MODE_AGILE_DFS_MODE_MASK (0x1 << WMI_DBS_HW_MODE_AGILE_DFS_MODE_BITPOS) + +#define WMI_DBS_HW_MODE_MAC0_TX_STREAMS_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_MAC0_TX_STREAMS_BITPOS) & WMI_DBS_HW_MODE_MAC0_TX_STREAMS_MASK)) +#define WMI_DBS_HW_MODE_MAC0_RX_STREAMS_SET(hw_mode, value) \ + (hw_mode != ((value << WMI_DBS_HW_MODE_MAC0_RX_STREAMS_BITPOS) & WMI_DBS_HW_MODE_MAC0_RX_STREAMS_MASK)) +#define WMI_DBS_HW_MODE_MAC1_TX_STREAMS_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_MAC1_TX_STREAMS_BITPOS) & WMI_DBS_HW_MODE_MAC1_TX_STREAMS_MASK)) +#define WMI_DBS_HW_MODE_MAC1_RX_STREAMS_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_MAC1_RX_STREAMS_BITPOS) & WMI_DBS_HW_MODE_MAC1_RX_STREAMS_MASK)) +#define WMI_DBS_HW_MODE_MAC0_BANDWIDTH_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_MAC0_BANDWIDTH_BITPOS) & WMI_DBS_HW_MODE_MAC0_BANDWIDTH_MASK)) +#define WMI_DBS_HW_MODE_MAC1_BANDWIDTH_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_MAC1_BANDWIDTH_BITPOS) & WMI_DBS_HW_MODE_MAC1_BANDWIDTH_MASK)) +#define WMI_DBS_HW_MODE_DBS_MODE_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_DBS_MODE_BITPOS) & WMI_DBS_HW_MODE_DBS_MODE_MASK)) +#define WMI_DBS_HW_MODE_AGILE_DFS_SET(hw_mode, value) \ + (hw_mode |= ((value << WMI_DBS_HW_MODE_AGILE_DFS_MODE_BITPOS) & WMI_DBS_HW_MODE_AGILE_DFS_MODE_MASK)) + +#define WMI_DBS_HW_MODE_MAC0_TX_STREAMS_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC0_TX_STREAMS_MASK) >> WMI_DBS_HW_MODE_MAC0_TX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC0_RX_STREAMS_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC0_RX_STREAMS_MASK) >> WMI_DBS_HW_MODE_MAC0_RX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_TX_STREAMS_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC1_TX_STREAMS_MASK) >> WMI_DBS_HW_MODE_MAC1_TX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_RX_STREAMS_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC1_RX_STREAMS_MASK) >> WMI_DBS_HW_MODE_MAC1_RX_STREAMS_BITPOS) +#define WMI_DBS_HW_MODE_MAC0_BANDWIDTH_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC0_BANDWIDTH_MASK) >> WMI_DBS_HW_MODE_MAC0_BANDWIDTH_BITPOS) +#define WMI_DBS_HW_MODE_MAC1_BANDWIDTH_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_MAC1_BANDWIDTH_MASK) >> WMI_DBS_HW_MODE_MAC1_BANDWIDTH_BITPOS) +#define WMI_DBS_HW_MODE_DBS_MODE_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_DBS_MODE_MASK) >> WMI_DBS_HW_MODE_DBS_MODE_BITPOS) +#define WMI_DBS_HW_MODE_AGILE_DFS_GET(hw_mode) \ + ((hw_mode & WMI_DBS_HW_MODE_AGILE_DFS_MODE_MASK) >> WMI_DBS_HW_MODE_AGILE_DFS_MODE_BITPOS) + +/** NOTE: This structure cannot be extended in the future without breaking WMI compatibility */ +typedef struct _wmi_abi_version { + A_UINT32 abi_version_0; /** WMI Major and Minor versions */ + A_UINT32 abi_version_1; /** WMI change revision */ + A_UINT32 abi_version_ns_0; /** ABI version namespace first four dwords */ + A_UINT32 abi_version_ns_1; /** ABI version namespace second four dwords */ + A_UINT32 abi_version_ns_2; /** ABI version namespace third four dwords */ + A_UINT32 abi_version_ns_3; /** ABI version namespace fourth four dwords */ +} wmi_abi_version; + +/* +* maximum number of memroy requests allowed from FW. +*/ +#define WMI_MAX_MEM_REQS 16 + +/* !!NOTE!!: + * This HW_BD_INFO_SIZE cannot be changed without breaking compatibility. + * Please don't change it. + */ +#define HW_BD_INFO_SIZE 5 + +/** + * The following struct holds optional payload for + * wmi_service_ready_event_fixed_param,e.g., 11ac pass some of the + * device capability to the host. +*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_SERVICE_READY_EVENT */ + A_UINT32 fw_build_vers; /* firmware build number */ + wmi_abi_version fw_abi_vers; + A_UINT32 phy_capability; /* WMI_PHY_CAPABILITY */ + A_UINT32 max_frag_entry; /* Maximum number of frag table entries that SW will populate less 1 */ + A_UINT32 num_rf_chains; + /* The following field is only valid for service type WMI_SERVICE_11AC */ + A_UINT32 ht_cap_info; /* WMI HT Capability */ + A_UINT32 vht_cap_info; /* VHT capability info field of 802.11ac */ + A_UINT32 vht_supp_mcs; /* VHT Supported MCS Set field Rx/Tx same */ + A_UINT32 hw_min_tx_power; + A_UINT32 hw_max_tx_power; + A_UINT32 sys_cap_info; + A_UINT32 min_pkt_size_enable; /* Enterprise mode short pkt enable */ + /** Max beacon and Probe Response IE offload size (includes + * optional P2P IEs) */ + A_UINT32 max_bcn_ie_size; + /* + * request to host to allocate a chuck of memory and pss it down to FW via WM_INIT. + * FW uses this as FW extesnsion memory for saving its data structures. Only valid + * for low latency interfaces like PCIE where FW can access this memory directly (or) + * by DMA. + */ + A_UINT32 num_mem_reqs; + /* Max No. scan channels target can support + * If FW is too old and doesn't indicate this number, host side value will default to + * 0, and host will take the original compatible value (62) for future scan channel + * setup. + */ + A_UINT32 max_num_scan_channels; + + /* Hardware board specific ID. Values defined in enum WMI_HWBOARD_ID. + * Default 0 means tha hw_bd_info[] is invalid(legacy board). + */ + A_UINT32 hw_bd_id; + A_UINT32 hw_bd_info[HW_BD_INFO_SIZE]; /* Board specific information. Invalid if hw_hd_id is zero. */ + + /* + * Number of MACs supported, i.e. a DBS-capable device will return 2 + */ + A_UINT32 max_supported_macs; + + /* + * FW sub-feature capabilities to be used in concurrence with wmi_service_bitmap + */ + A_UINT32 wmi_fw_sub_feat_caps; //values from enum WMI_FW_SUB_FEAT_CAPS + + /* + * Number of Dual Band Simultaneous (DBS) hardware modes + */ + A_UINT32 num_dbs_hw_modes; + + /* The TLVs for hal_reg_capabilities, wmi_service_bitmap and mem_reqs[] will follow this TLV. + * HAL_REG_CAPABILITIES hal_reg_capabilities; + * A_UINT32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; + * wlan_host_mem_req mem_reqs[]; + * wlan_dbs_hw_mode_list[]; + */ +} wmi_service_ready_event_fixed_param; + +typedef enum { + WMI_FW_STA_RTT_INITR = 0x00000001, + WMI_FW_STA_RTT_RESPR = 0x00000002, + WMI_FW_P2P_CLI_RTT_INITR = 0x00000004, + WMI_FW_P2P_CLI_RTT_RESPR = 0x00000008, + WMI_FW_P2P_GO_RTT_INITR = 0x00000010, + WMI_FW_P2P_GO_RTT_RESPR = 0x00000020, + WMI_FW_AP_RTT_INITR = 0x00000040, + WMI_FW_AP_RTT_RESPR = 0x00000080, + WMI_FW_NAN_RTT_INITR = 0x00000100, + WMI_FW_NAN_RTT_RESPR = 0x00000200, + /* + * New fw sub feature capabilites before + * WMI_FW_MAX_SUB_FEAT_CAP + */ + WMI_FW_MAX_SUB_FEAT_CAP = 0x80000000, +} WMI_FW_SUB_FEAT_CAPS; + +typedef enum { + WMI_HWBD_NONE = 0, /* No hw board information is given */ + WMI_HWBD_QCA6174 = 1, /* Rome(AR6320) */ + WMI_HWBD_QCA2582 = 2, /* Killer 1525*/ +} WMI_HWBD_ID; + +#define ATH_BD_DATA_REV_MASK 0x000000FF +#define ATH_BD_DATA_REV_SHIFT 0 + +#define ATH_BD_DATA_PROJ_ID_MASK 0x0000FF00 +#define ATH_BD_DATA_PROJ_ID_SHIFT 8 + +#define ATH_BD_DATA_CUST_ID_MASK 0x00FF0000 +#define ATH_BD_DATA_CUST_ID_SHIFT 16 + +#define ATH_BD_DATA_REF_DESIGN_ID_MASK 0xFF000000 +#define ATH_BD_DATA_REF_DESIGN_ID_SHIFT 24 + +#define SET_BD_DATA_REV(bd_data_ver, value) \ + ((bd_data_ver) &= ~ATH_BD_DATA_REV_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_REV_SHIFT)) + +#define GET_BD_DATA_REV(bd_data_ver) \ + (((bd_data_ver) & ATH_BD_DATA_REV_MASK) >> ATH_BD_DATA_REV_SHIFT) + +#define SET_BD_DATA_PROJ_ID(bd_data_ver, value) \ + ((bd_data_ver) &= ~ATH_BD_DATA_PROJ_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_PROJ_ID_SHIFT)) + +#define GET_BD_DATA_PROJ_ID(bd_data_ver) \ + (((bd_data_ver) & ATH_BD_DATA_PROJ_ID_MASK) >> ATH_BD_DATA_PROJ_ID_SHIFT) + +#define SET_BD_DATA_CUST_ID(bd_data_ver, value) \ + ((bd_data_ver) &= ~ATH_BD_DATA_CUST_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_CUST_ID_SHIFT)) + +#define GET_BD_DATA_CUST_ID(bd_data_ver) \ + (((bd_data_ver) & ATH_BD_DATA_CUST_ID_MASK) >> ATH_BD_DATA_CUST_ID_SHIFT) + +#define SET_BD_DATA_REF_DESIGN_ID(bd_data_ver, value) \ + ((bd_data_ver) &= ~ATH_BD_DATA_REF_DESIGN_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_REF_DESIGN_ID_SHIFT)) + +#define GET_BD_DATA_REF_DESIGN_ID(bd_data_ver) \ + (((bd_data_ver) & ATH_BD_DATA_REF_DESIGN_ID_MASK) >> ATH_BD_DATA_REF_DESIGN_ID_SHIFT) + +#ifdef ROME_LTE_COEX_FREQ_AVOID +typedef struct { + A_UINT32 start_freq; //start frequency, not channel center freq + A_UINT32 end_freq;//end frequency +}avoid_freq_range_desc; + +typedef struct { + //bad channel range count, multi range is allowed, 0 means all channel clear + A_UINT32 num_freq_ranges; + //multi range with num_freq_ranges, LTE advance multi carrier, CDMA,etc + avoid_freq_range_desc avd_freq_range[0]; +}wmi_wlan_avoid_freq_ranges_event; +#endif + +/** status consists of upper 16 bits fo A_STATUS status and lower 16 bits of module ID that retuned status */ +#define WLAN_INIT_STATUS_SUCCESS 0x0 +#define WLAN_INIT_STATUS_GEN_FAILED 0x1 +#define WLAN_GET_INIT_STATUS_REASON(status) ((status) & 0xffff) +#define WLAN_GET_INIT_STATUS_MODULE_ID(status) (((status) >> 16) & 0xffff) + +typedef A_UINT32 WLAN_INIT_STATUS; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ready_event_fixed_param */ + wmi_abi_version fw_abi_vers; + wmi_mac_addr mac_addr; + A_UINT32 status; +} wmi_ready_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resource_config */ +/** + * @brief num_vdev - number of virtual devices (VAPs) to support + */ + A_UINT32 num_vdevs; +/** + * @brief num_peers - number of peer nodes to support + */ + A_UINT32 num_peers; +/* + * @brief In offload mode target supports features like WOW, chatter and other + * protocol offloads. In order to support them some functionalities like + * reorder buffering, PN checking need to be done in target. This determines + * maximum number of peers suported by target in offload mode + */ + A_UINT32 num_offload_peers; +/* @brief Number of reorder buffers available for doing target based reorder + * Rx reorder buffering + */ + A_UINT32 num_offload_reorder_buffs; +/** + * @brief num_peer_keys - number of keys per peer + */ + A_UINT32 num_peer_keys; +/** + * @brief num_peer_tids - number of TIDs to provide storage for per peer. + */ + A_UINT32 num_tids; +/** + * @brief ast_skid_limit - max skid for resolving hash collisions + * @details + * The address search table is sparse, so that if two MAC addresses + * result in the same hash value, the second of these conflicting + * entries can slide to the next index in the address search table, + * and use it, if it is unoccupied. This ast_skid_limit parameter + * specifies the upper bound on how many subsequent indices to search + * over to find an unoccupied space. + */ + A_UINT32 ast_skid_limit; +/** + * @brief tx_chain_mask - the nominal chain mask for transmit + * @details + * The chain mask may be modified dynamically, e.g. to operate AP tx with + * a reduced number of chains if no clients are associated. + * This configuration parameter specifies the nominal chain-mask that + * should be used when not operating with a reduced set of tx chains. + */ + A_UINT32 tx_chain_mask; +/** + * @brief rx_chain_mask - the nominal chain mask for receive + * @details + * The chain mask may be modified dynamically, e.g. for a client to use + * a reduced number of chains for receive if the traffic to the client + * is low enough that it doesn't require downlink MIMO or antenna + * diversity. + * This configuration parameter specifies the nominal chain-mask that + * should be used when not operating with a reduced set of rx chains. + */ + A_UINT32 rx_chain_mask; +/** + * @brief rx_timeout_pri - what rx reorder timeout (ms) to use for the AC + * @details + * Each WMM access class (voice, video, best-effort, background) will + * have its own timeout value to dictate how long to wait for missing + * rx MPDUs to arrive before flushing subsequent MPDUs that have already + * been received. + * This parameter specifies the timeout in milliseconds for each class . + * NOTE: the number of class (defined as 4) cannot be + * changed in the future without breaking WMI compatibility. + */ + A_UINT32 rx_timeout_pri[4]; +/** + * @brief rx_decap mode - what mode the rx should decap packets to + * @details + * MAC can decap to RAW (no decap), native wifi or Ethernet types + * THis setting also determines the default TX behavior, however TX + * behavior can be modified on a per VAP basis during VAP init + */ + A_UINT32 rx_decap_mode; + /** + * @brief scan_max_pending_req - what is the maximum scan requests than can be queued + */ + A_UINT32 scan_max_pending_req; + + /** + * @brief maximum VDEV that could use BMISS offload + */ + A_UINT32 bmiss_offload_max_vdev; + + /** + * @brief maximum VDEV that could use offload roaming + */ + A_UINT32 roam_offload_max_vdev; + + /** + * @brief maximum AP profiles that would push to offload roaming + */ + A_UINT32 roam_offload_max_ap_profiles; + +/** + * @brief num_mcast_groups - how many groups to use for mcast->ucast conversion + * @details + * The target's WAL maintains a table to hold information regarding which + * peers belong to a given multicast group, so that if multicast->unicast + * conversion is enabled, the target can convert multicast tx frames to a + * series of unicast tx frames, to each peer within the multicast group. + * This num_mcast_groups configuration parameter tells the target how + * many multicast groups to provide storage for within its multicast + * group membership table. + */ + A_UINT32 num_mcast_groups; + +/** + * @brief num_mcast_table_elems - size to alloc for the mcast membership table + * @details + * This num_mcast_table_elems configuration parameter tells the target + * how many peer elements it needs to provide storage for in its + * multicast group membership table. + * These multicast group membership table elements are shared by the + * multicast groups stored within the table. + */ + A_UINT32 num_mcast_table_elems; + +/** + * @brief mcast2ucast_mode - whether/how to do multicast->unicast conversion + * @details + * This configuration parameter specifies whether the target should + * perform multicast --> unicast conversion on transmit, and if so, + * what to do if it finds no entries in its multicast group membership + * table for the multicast IP address in the tx frame. + * Configuration value: + * 0 -> Do not perform multicast to unicast conversion. + * 1 -> Convert multicast frames to unicast, if the IP multicast address + * from the tx frame is found in the multicast group membership + * table. If the IP multicast address is not found, drop the frame. + * 2 -> Convert multicast frames to unicast, if the IP multicast address + * from the tx frame is found in the multicast group membership + * table. If the IP multicast address is not found, transmit the + * frame as multicast. + */ + A_UINT32 mcast2ucast_mode; + + + /** + * @brief tx_dbg_log_size - how much memory to allocate for a tx PPDU dbg log + * @details + * This parameter controls how much memory the target will allocate to + * store a log of tx PPDU meta-information (how large the PPDU was, + * when it was sent, whether it was successful, etc.) + */ + A_UINT32 tx_dbg_log_size; + + /** + * @brief num_wds_entries - how many AST entries to be allocated for WDS + */ + A_UINT32 num_wds_entries; + + /** + * @brief dma_burst_size - MAC DMA burst size, e.g., on Peregrine on PCI + * this limit can be 0 -default, 1 256B + */ + A_UINT32 dma_burst_size; + + /** + * @brief mac_aggr_delim - Fixed delimiters to be inserted after every MPDU + * to account for interface latency to avoid underrun. + */ + A_UINT32 mac_aggr_delim; + /** + * @brief rx_skip_defrag_timeout_dup_detection_check + * @details + * determine whether target is responsible for detecting duplicate + * non-aggregate MPDU and timing out stale fragments. + * + * A-MPDU reordering is always performed on the target. + * + * 0: target responsible for frag timeout and dup checking + * 1: host responsible for frag timeout and dup checking + */ + A_UINT32 rx_skip_defrag_timeout_dup_detection_check; + + /** + * @brief vow_config - Configuration for VoW : No of Video Nodes to be supported + * and Max no of descriptors for each Video link (node). + */ + A_UINT32 vow_config; + + /** + * @brief maximum VDEV that could use GTK offload + */ + A_UINT32 gtk_offload_max_vdev; + + /** + * @brief num_msdu_desc - Number of msdu descriptors target should use + */ + A_UINT32 num_msdu_desc; /* Number of msdu desc */ + /** + * @brief max_frag_entry - Max. number of Tx fragments per MSDU + * @details + * This parameter controls the max number of Tx fragments per MSDU. + * This is sent by the target as part of the WMI_SERVICE_READY event + * and is overriden by the OS shim as required. + */ + A_UINT32 max_frag_entries; + + /** + * @brief num_tdls_vdevs - Max. number of vdevs that can support TDLS + * @brief num_msdu_desc - Number of vdev that can support beacon offload + */ + + A_UINT32 num_tdls_vdevs; /* number of vdevs allowed to do tdls */ + + /** + * @brief num_tdls_conn_table_entries - Number of peers tracked by tdls vdev + * @details + * Each TDLS enabled vdev can track outgoing transmits/rssi/rates to/of + * peers in a connection tracking table for possible TDLS link creation + * or deletion. This controls the number of tracked peers per vdev. + */ + A_UINT32 num_tdls_conn_table_entries; /* number of peers to track per TDLS vdev */ + A_UINT32 beacon_tx_offload_max_vdev; + A_UINT32 num_multicast_filter_entries; + A_UINT32 num_wow_filters; /*host can configure the number of wow filters*/ + + /** + * @brief num_keep_alive_pattern - Num of keep alive patterns configured + * from host. + */ + A_UINT32 num_keep_alive_pattern; + /** + * @brief keep_alive_pattern_size - keep alive pattern size. + */ + A_UINT32 keep_alive_pattern_size; + + /** + * @brief max_tdls_concurrent_sleep_sta - Number of tdls sleep sta supported + * @details + * Each TDLS STA can become a sleep STA independently. This parameter + * mentions how many such sleep STAs can be supported concurrently. + */ + A_UINT32 max_tdls_concurrent_sleep_sta; + + /** + * @brief max_tdls_concurrent_buffer_sta - Number of tdls buffer sta supported + * @details + * Each TDLS STA can become a buffer STA independently. This parameter + * mentions how many such buffer STAs can be supported concurrently. + */ + A_UINT32 max_tdls_concurrent_buffer_sta; + + /** + * @brief wmi_send_separate - host configures fw to send the wmi separately + */ + A_UINT32 wmi_send_separate; + + /** + * @brief num_ocb_vdevs - Number of vdevs used for OCB support + */ + A_UINT32 num_ocb_vdevs; + + /** + * @brief num_ocb_channels - The supported number of simultaneous OCB channels + */ + A_UINT32 num_ocb_channels; + + /** + * @brief num_ocb_schedules - The supported number of OCB schedule segments + */ + A_UINT32 num_ocb_schedules; +} wmi_resource_config; + + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param */ + + /** The following indicate the WMI versions to be supported by + * the host driver. Note that the host driver decide to + * "downgrade" its WMI version support and this may not be the + * native version of the host driver. */ + wmi_abi_version host_abi_vers; + + A_UINT32 num_host_mem_chunks; /** size of array host_mem_chunks[] */ + /* The TLVs for resource_config and host_mem_chunks[] will follow. + * wmi_resource_config resource_config; + * wlan_host_memory_chunk host_mem_chunks[]; + */ + +} wmi_init_cmd_fixed_param; + +/** + * TLV for channel list + */ +typedef struct { + /** WMI_CHAN_LIST_TAG */ + A_UINT32 tag; + /** # of channels to scan */ + A_UINT32 num_chan; + /** channels in Mhz */ + A_UINT32 channel_list[1]; +} wmi_chan_list; + +/** + * TLV for bssid list + */ +typedef struct { + /** WMI_BSSID_LIST_TAG */ + A_UINT32 tag; + /** number of bssids */ + A_UINT32 num_bssid; + /** bssid list */ + wmi_mac_addr bssid_list[1]; +} wmi_bssid_list; + +/** + * TLV for ie data. + */ +typedef struct { + /** WMI_IE_TAG */ + A_UINT32 tag; + /** number of bytes in ie data */ + A_UINT32 ie_len; + /** ie data array (ie_len adjusted to number of words (ie_len + 4)/4 ) */ + A_UINT32 ie_data[1]; +} wmi_ie_data; + + +typedef struct { + /** Len of the SSID */ + A_UINT32 ssid_len; + /** SSID */ + A_UINT32 ssid[8]; +} wmi_ssid; + +typedef struct { + /** WMI_SSID_LIST_TAG */ + A_UINT32 tag; + A_UINT32 num_ssids; + wmi_ssid ssids[1]; +} wmi_ssid_list; + +/* prefix used by scan requestor ids on the host */ +#define WMI_HOST_SCAN_REQUESTOR_ID_PREFIX 0xA000 +/* prefix used by scan request ids generated on the host */ +/* host cycles through the lower 12 bits to generate ids */ +#define WMI_HOST_SCAN_REQ_ID_PREFIX 0xA000 + +#define WLAN_SCAN_PARAMS_MAX_SSID 16 +#define WLAN_SCAN_PARAMS_MAX_BSSID 4 +#define WLAN_SCAN_PARAMS_MAX_IE_LEN 512 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param */ + /** Scan ID */ + A_UINT32 scan_id; + /** Scan requestor ID */ + A_UINT32 scan_req_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** Scan Priority, input to scan scheduler */ + A_UINT32 scan_priority; + /** Scan events subscription */ + A_UINT32 notify_scan_events; + /** dwell time in msec on active channels */ + A_UINT32 dwell_time_active; + /** dwell time in msec on passive channels */ + A_UINT32 dwell_time_passive; + /** min time in msec on the BSS channel,only valid if atleast one VDEV is active*/ + A_UINT32 min_rest_time; + /** max rest time in msec on the BSS channel,only valid if at least one VDEV is active*/ + /** the scanner will rest on the bss channel at least min_rest_time. after min_rest_time the scanner + * will start checking for tx/rx activity on all VDEVs. if there is no activity the scanner will + * switch to off channel. if there is activity the scanner will let the radio on the bss channel + * until max_rest_time expires.at max_rest_time scanner will switch to off channel + * irrespective of activity. activity is determined by the idle_time parameter. + */ + A_UINT32 max_rest_time; + /** time before sending next set of probe requests. + * The scanner keeps repeating probe requests transmission with period specified by repeat_probe_time. + * The number of probe requests specified depends on the ssid_list and bssid_list + */ + A_UINT32 repeat_probe_time; + /** time in msec between 2 consequetive probe requests with in a set. */ + A_UINT32 probe_spacing_time; + /** data inactivity time in msec on bss channel that will be used by scanner for measuring the inactivity */ + A_UINT32 idle_time; + /** maximum time in msec allowed for scan */ + A_UINT32 max_scan_time; + /** delay in msec before sending first probe request after switching to a channel */ + A_UINT32 probe_delay; + /** Scan control flags */ + A_UINT32 scan_ctrl_flags; + /** Burst duration time in msec*/ + A_UINT32 burst_duration; + + /** # if channels to scan. In the TLV channel_list[] */ + A_UINT32 num_chan; + /** number of bssids. In the TLV bssid_list[] */ + A_UINT32 num_bssid; + /** number of ssid. In the TLV ssid_list[] */ + A_UINT32 num_ssids; + /** number of bytes in ie data. In the TLV ie_data[]. Max len is defined by WLAN_SCAN_PARAMS_MAX_IE_LEN */ + A_UINT32 ie_len; + /** Max number of probes to be sent */ + A_UINT32 n_probes; + + + /** + * TLV (tag length value ) parameters follow the scan_cmd + * structure. The TLV's are: + * A_UINT32 channel_list[]; + * wmi_ssid ssid_list[]; + * wmi_mac_addr bssid_list[]; + * A_UINT8 ie_data[]; + */ +} wmi_start_scan_cmd_fixed_param; + +/** + * scan control flags. + */ + +/** passively scan all channels including active channels */ +#define WMI_SCAN_FLAG_PASSIVE 0x1 +/** add wild card ssid probe request even though ssid_list is specified. */ +#define WMI_SCAN_ADD_BCAST_PROBE_REQ 0x2 +/** add cck rates to rates/xrate ie for the generated probe request */ +#define WMI_SCAN_ADD_CCK_RATES 0x4 +/** add ofdm rates to rates/xrate ie for the generated probe request */ +#define WMI_SCAN_ADD_OFDM_RATES 0x8 +/** To enable indication of Chan load and Noise floor to host */ +#define WMI_SCAN_CHAN_STAT_EVENT 0x10 +/** Filter Probe request frames */ +#define WMI_SCAN_FILTER_PROBE_REQ 0x20 +/**When set, not to scan DFS channels*/ +#define WMI_SCAN_BYPASS_DFS_CHN 0x40 +/**When set, certain errors are ignored and scan continues. +* Different FW scan engine may use its own logic to decide what errors to ignore*/ +#define WMI_SCAN_CONTINUE_ON_ERROR 0x80 +/** Enable promiscous mode for ese */ +#define WMI_SCAN_FILTER_PROMISCOUS 0x100 +/** allow to send probe req on DFS channel */ +#define WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS 0x200 +/** add TPC content in probe req frame */ +#define WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ 0x400 +/** add DS content in probe req frame */ +#define WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ 0x800 +/** use random mac address for TA for probe request frame and add + * oui specified by WMI_SCAN_PROB_REQ_OUI_CMDID to the probe req frame. + * if oui is not set by WMI_SCAN_PROB_REQ_OUI_CMDID then the flag is ignored*/ +#define WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ 0x1000 + +/** WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */ +#define WMI_SCAN_CLASS_MASK 0xFF000000 + +/* +* Masks identifying types/ID of scans +* Scan_Stop macros should be the same value as below defined in UMAC +* #define IEEE80211_SPECIFIC_SCAN 0x00000000 +* #define IEEE80211_VAP_SCAN 0x01000000 +* #define IEEE80211_ALL_SCANS 0x04000000 +*/ +#define WMI_SCAN_STOP_ONE 0x00000000 +#define WMI_SCN_STOP_VAP_ALL 0x01000000 +#define WMI_SCAN_STOP_ALL 0x04000000 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param */ + /** requestor requesting cancel */ + A_UINT32 requestor; + /** Scan ID */ + A_UINT32 scan_id; + /** + * Req Type + * req_type should be WMI_SCAN_STOP_ONE, WMI_SCN_STOP_VAP_ALL or WMI_SCAN_STOP_ALL + * WMI_SCAN_STOP_ONE indicates to stop a specific scan with scan_id + * WMI_SCN_STOP_VAP_ALL indicates to stop all scan requests on a specific vDev with vdev_id + * WMI_SCAN_STOP_ALL indicates to stop all scan requests in both Scheduler's queue and Scan Engine + */ + A_UINT32 req_type; + /** + * vDev ID + * used when req_type equals to WMI_SCN_STOP_VAP_ALL, it indexed the vDev on which to stop the scan + */ + A_UINT32 vdev_id; +} wmi_stop_scan_cmd_fixed_param; + +#define MAX_NUM_CHAN_PER_WMI_CMD 58 // each WMI cmd can hold 58 channel entries at most +#define APPEND_TO_EXISTING_CHAN_LIST 1 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param */ + A_UINT32 num_scan_chans; /** no of elements in chan_info[] */ + A_UINT32 flags; /* Flags used to control the behavior of channel list update on target side */ + /** Followed by the variable length TLV chan_info: + * wmi_channel chan_info[] */ +} wmi_scan_chan_list_cmd_fixed_param; + +/* + * Priority numbers must be sequential, starting with 0. + */ + /* NOTE: WLAN SCAN_PRIORITY_COUNT can't be changed without breaking the compatibility */ +typedef enum { + WMI_SCAN_PRIORITY_VERY_LOW = 0, + WMI_SCAN_PRIORITY_LOW, + WMI_SCAN_PRIORITY_MEDIUM, + WMI_SCAN_PRIORITY_HIGH, + WMI_SCAN_PRIORITY_VERY_HIGH, + + WMI_SCAN_PRIORITY_COUNT /* number of priorities supported */ +} wmi_scan_priority; + +/* Five Levels for Requested Priority */ +/* VERY_LOW LOW MEDIUM HIGH VERY_HIGH */ +typedef A_UINT32 WLAN_PRIORITY_MAPPING[WMI_SCAN_PRIORITY_COUNT]; + +/** +* to keep align with UMAC implementation, we pass only vdev_type but not vdev_subtype when we overwrite an entry for a specific vdev_subtype +* ex. if we need overwrite P2P Client prority entry, we will overwrite the whole table for WLAN_M_STA +* we will generate the new WLAN_M_STA table with modified P2P Client Entry but keep STA entry intact +*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_scan_sch_priority_table_cmd_fixed_param */ + /** + * used as an index to find the proper table for a specific vdev type in default_scan_priority_mapping_table + * vdev_type should be one of enum in WLAN_OPMODE which inculdes WLAN_M_IBSS, WLAN_M_STA, WLAN_M_AP and WLAN_M_MONITOR currently + */ + A_UINT32 vdev_type; + /** + * number of rows in mapping_table for a specific vdev + * for WLAN_M_STA type, there are 3 entries in the table (refer to default_scan_priority_mapping_table definition) + */ + A_UINT32 number_rows; + /** mapping_table for a specific vdev follows this TLV + * WLAN_PRIORITY_MAPPING mapping_table[]; */ +}wmi_scan_sch_priority_table_cmd_fixed_param; + +/** update flags */ +#define WMI_SCAN_UPDATE_SCAN_PRIORITY 0x1 +#define WMI_SCAN_UPDATE_SCAN_MIN_REST_TIME 0x2 +#define WMI_SCAN_UPDATE_SCAN_MAX_REST_TIME 0x4 + +typedef struct { + A_UINT32 tlv_header; + /** requestor requesting update scan request */ + A_UINT32 requestor; + /** Scan ID of the scan request that need to be update */ + A_UINT32 scan_id; + /** update flags, indicating which of the following fields are valid and need to be updated*/ + A_UINT32 scan_update_flags; + /** scan priority. Only valid if WMI_SCAN_UPDATE_SCAN_PRIORITY flag is set in scan_update_flag */ + A_UINT32 scan_priority; + /** min rest time. Only valid if WMI_SCAN_UPDATE_MIN_REST_TIME flag is set in scan_update_flag */ + A_UINT32 min_rest_time; + /** min rest time. Only valid if WMI_SCAN_UPDATE_MAX_REST_TIME flag is set in scan_update_flag */ + A_UINT32 max_rest_time; +} wmi_scan_update_request_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + /** oui to be used in probe request frame when random mac addresss is + * requested part of scan parameters. this is applied to both FW internal scans and + * host initated scans. host can request for random mac address with + * WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ flag. */ + A_UINT32 prob_req_oui; +} wmi_scan_prob_req_oui_cmd_fixed_param; + +enum wmi_scan_event_type { + WMI_SCAN_EVENT_STARTED=0x1, + WMI_SCAN_EVENT_COMPLETED=0x2, + WMI_SCAN_EVENT_BSS_CHANNEL=0x4, + WMI_SCAN_EVENT_FOREIGN_CHANNEL = 0x8, + WMI_SCAN_EVENT_DEQUEUED=0x10, /* scan request got dequeued */ + WMI_SCAN_EVENT_PREEMPTED=0x20, /* preempted by other high priority scan */ + WMI_SCAN_EVENT_START_FAILED=0x40, /* scan start failed */ + WMI_SCAN_EVENT_RESTARTED=0x80, /*scan restarted*/ + WMI_SCAN_EVENT_MAX=0x8000 +}; + +enum wmi_scan_completion_reason { + /** scan related events */ + WMI_SCAN_REASON_NONE = 0xFF, + WMI_SCAN_REASON_COMPLETED = 0, + WMI_SCAN_REASON_CANCELLED = 1, + WMI_SCAN_REASON_PREEMPTED = 2, + WMI_SCAN_REASON_TIMEDOUT = 3, + WMI_SCAN_REASON_INTERNAL_FAILURE = 4, /* This reason indication failures when performaing scan */ + WMI_SCAN_REASON_MAX, +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_scan_event_fixed_param */ + /** scan event (wmi_scan_event_type) */ + A_UINT32 event; + /** status of the scan completion event */ + A_UINT32 reason; + /** channel freq , only valid for FOREIGN channel event*/ + A_UINT32 channel_freq; + /**id of the requestor whose scan is in progress */ + A_UINT32 requestor; + /**id of the scan that is in progress */ + A_UINT32 scan_id; + /**id of VDEV that requested the scan */ + A_UINT32 vdev_id; +} wmi_scan_event_fixed_param; + +/* WMI Diag event */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag is WMITLV_TAG_STRUC_wmi_diag_event_fixed_param */ + A_UINT32 time_stamp; /* Reference timestamp. diag frame contains diff value */ + A_UINT32 count; /* Number of diag frames added to current event */ + A_UINT32 dropped; + /* followed by WMITLV_TAG_ARRAY_BYTE */ +} wmi_diag_event_fixed_param; + +/* +* If FW has multiple active channels due to MCC(multi channel concurrency), +* then these stats are combined stats for all the active channels. +*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_update_whal_mib_stats_event_fixed_param */ + /** ack count, it is an incremental number, not accumulated number */ + A_UINT32 ackRcvBad; + /** bad rts count, it is an incremental number, not accumulated number */ + A_UINT32 rtsBad; + /** good rts, it is an incremental number, not accumulated number */ + A_UINT32 rtsGood; + /** fcs count, it is an incremental number, not accumulated number */ + A_UINT32 fcsBad; + /** beacon count, it is an incremental number, not accumulated number */ + A_UINT32 noBeacons; +} wmi_update_whal_mib_stats_event_fixed_param; + +/* + * This defines how much headroom is kept in the + * receive frame between the descriptor and the + * payload, in order for the WMI PHY error and + * management handler to insert header contents. + * + * This is in bytes. + */ +#define WMI_MGMT_RX_HDR_HEADROOM sizeof(wmi_comb_phyerr_rx_hdr) + WMI_TLV_HDR_SIZE + sizeof(wmi_single_phyerr_rx_hdr) + +/** This event will be used for sending scan results + * as well as rx mgmt frames to the host. The rx buffer + * will be sent as part of this WMI event. It would be a + * good idea to pass all the fields in the RX status + * descriptor up to the host. + */ + /* ATH_MAX_ANTENNA value (4) can't be changed without breaking the compatibility */ +#define ATH_MAX_ANTENNA 4 /* To support beelinear, which is up to 4 chains */ + +/** flag indicating that the the mgmt frame (probe req/beacon) is received in the context of extscan performed by FW */ +#define WMI_MGMT_RX_HDR_EXTSCAN 0x01 + +/** flag indicating that the the mgmt frame (probe req/beacon) is received in the context of matched network by FW ENLO */ +#define WMI_MGMT_RX_HDR_ENLO 0x02 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mgmt_rx_hdr */ + /** channel on which this frame is received. */ + A_UINT32 channel; + /** snr information used to cal rssi */ + A_UINT32 snr; + /** Rate kbps */ + A_UINT32 rate; + /** rx phy mode WLAN_PHY_MODE */ + A_UINT32 phy_mode; + /** length of the frame */ + A_UINT32 buf_len; + /** rx status */ + A_UINT32 status; + /** RSSI of PRI 20MHz for each chain. */ + A_UINT32 rssi_ctl[ATH_MAX_ANTENNA]; + /** information about the management frame e.g. can give a scan source for a scan result mgmt frame */ + A_UINT32 flags; + /** combined RSSI, i.e. the sum of the snr + noise floor (dBm units) */ + A_INT32 rssi; + /** delta between local TSF(TSF timestamp when frame was RXd) + * and remote TSF(TSF timestamp in the IE for mgmt frame - + * beacon,proberesp for e.g). If remote TSF is not available, + * delta set to 0. + * Although tsf_delta is stored as A_UINT32, it can be negative, + * and thus would need to be sign-extended if added to a value + * larger than 32 bits. + */ + A_UINT32 tsf_delta; + + /* This TLV is followed by array of bytes: + * // management frame buffer + * A_UINT8 bufp[]; + */ +} wmi_mgmt_rx_hdr; + +/* WMI PHY Error RX */ + +typedef struct { + /** TSF timestamp */ + A_UINT32 tsf_timestamp; + + /** + * Current freq1, freq2 + * + * [7:0]: freq1[lo] + * [15:8] : freq1[hi] + * [23:16]: freq2[lo] + * [31:24]: freq2[hi] + */ + A_UINT32 freq_info_1; + + /** + * Combined RSSI over all chains and channel width for this PHY error + * + * [7:0]: RSSI combined + * [15:8]: Channel width (MHz) + * [23:16]: PHY error code + * [24:16]: reserved (future use) + */ + A_UINT32 freq_info_2; + + /** + * RSSI on chain 0 through 3 + * + * This is formatted the same as the PPDU_START RX descriptor + * field: + * + * [7:0]: pri20 + * [15:8]: sec20 + * [23:16]: sec40 + * [31:24]: sec80 + */ + A_UINT32 rssi_chain0; + A_UINT32 rssi_chain1; + A_UINT32 rssi_chain2; + A_UINT32 rssi_chain3; + + /** + * Last calibrated NF value for chain 0 through 3 + * + * nf_list_1: + * + * + [15:0] - chain 0 + * + [31:16] - chain 1 + * + * nf_list_2: + * + * + [15:0] - chain 2 + * + [31:16] - chain 3 + */ + A_UINT32 nf_list_1; + A_UINT32 nf_list_2; + + /** Length of the frame */ + A_UINT32 buf_len; +} wmi_single_phyerr_rx_hdr; + +#define WMI_UNIFIED_FREQINFO_1_LO 0x000000ff +#define WMI_UNIFIED_FREQINFO_1_LO_S 0 +#define WMI_UNIFIED_FREQINFO_1_HI 0x0000ff00 +#define WMI_UNIFIED_FREQINFO_1_HI_S 8 +#define WMI_UNIFIED_FREQINFO_2_LO 0x00ff0000 +#define WMI_UNIFIED_FREQINFO_2_LO_S 16 +#define WMI_UNIFIED_FREQINFO_2_HI 0xff000000 +#define WMI_UNIFIED_FREQINFO_2_HI_S 24 + +/* + * Please keep in mind that these _SET macros break macro side effect + * assumptions; don't be clever with them. + */ +#define WMI_UNIFIED_FREQ_INFO_GET(hdr, f) \ + ( WMI_F_MS( (hdr)->freq_info_1, \ + WMI_UNIFIED_FREQINFO_##f##_LO ) \ + | (WMI_F_MS( (hdr)->freq_info_1, \ + WMI_UNIFIED_FREQINFO_##f##_HI ) << 8) ) + +#define WMI_UNIFIED_FREQ_INFO_SET(hdr, f, v) \ + do { \ + WMI_F_RMW((hdr)->freq_info_1, (v) & 0xff, \ + WMI_UNIFIED_FREQINFO_##f##_LO); \ + WMI_F_RMW((hdr)->freq_info_1, ((v) >> 8) & 0xff, \ + WMI_UNIFIED_FREQINFO_##f##_HI); \ + } while (0) + +#define WMI_UNIFIED_FREQINFO_2_RSSI_COMB 0x000000ff +#define WMI_UNIFIED_FREQINFO_2_RSSI_COMB_S 0 +#define WMI_UNIFIED_FREQINFO_2_CHWIDTH 0x0000ff00 +#define WMI_UNIFIED_FREQINFO_2_CHWIDTH_S 8 +#define WMI_UNIFIED_FREQINFO_2_PHYERRCODE 0x00ff0000 +#define WMI_UNIFIED_FREQINFO_2_PHYERRCODE_S 16 + +#define WMI_UNIFIED_RSSI_COMB_GET(hdr) \ + ( (int8_t) (WMI_F_MS((hdr)->freq_info_2, \ + WMI_UNIFIED_FREQINFO_2_RSSI_COMB))) + +#define WMI_UNIFIED_RSSI_COMB_SET(hdr, v) \ + WMI_F_RMW((hdr)->freq_info_2, (v) & 0xff, \ + WMI_UNIFIED_FREQINFO_2_RSSI_COMB); + +#define WMI_UNIFIED_CHWIDTH_GET(hdr) \ + WMI_F_MS((hdr)->freq_info_2, WMI_UNIFIED_FREQINFO_2_CHWIDTH) + +#define WMI_UNIFIED_CHWIDTH_SET(hdr, v) \ + WMI_F_RMW((hdr)->freq_info_2, (v) & 0xff, \ + WMI_UNIFIED_FREQINFO_2_CHWIDTH); + +#define WMI_UNIFIED_PHYERRCODE_GET(hdr) \ + WMI_F_MS((hdr)->freq_info_2, WMI_UNIFIED_FREQINFO_2_PHYERRCODE) + +#define WMI_UNIFIED_PHYERRCODE_SET(hdr, v) \ + WMI_F_RMW((hdr)->freq_info_2, (v) & 0xff, \ + WMI_UNIFIED_FREQINFO_2_PHYERRCODE); + +#define WMI_UNIFIED_CHAIN_0 0x0000ffff +#define WMI_UNIFIED_CHAIN_0_S 0 +#define WMI_UNIFIED_CHAIN_1 0xffff0000 +#define WMI_UNIFIED_CHAIN_1_S 16 +#define WMI_UNIFIED_CHAIN_2 0x0000ffff +#define WMI_UNIFIED_CHAIN_2_S 0 +#define WMI_UNIFIED_CHAIN_3 0xffff0000 +#define WMI_UNIFIED_CHAIN_3_S 16 + +#define WMI_UNIFIED_CHAIN_0_FIELD nf_list_1 +#define WMI_UNIFIED_CHAIN_1_FIELD nf_list_1 +#define WMI_UNIFIED_CHAIN_2_FIELD nf_list_2 +#define WMI_UNIFIED_CHAIN_3_FIELD nf_list_2 + +#define WMI_UNIFIED_NF_CHAIN_GET(hdr, c) \ + ((int16_t) (WMI_F_MS((hdr)->WMI_UNIFIED_CHAIN_##c##_FIELD, \ + WMI_UNIFIED_CHAIN_##c))) + +#define WMI_UNIFIED_NF_CHAIN_SET(hdr, c, nf) \ + WMI_F_RMW((hdr)->WMI_UNIFIED_CHAIN_##c##_FIELD, (nf) & 0xffff, \ + WMI_UNIFIED_CHAIN_##c); + +/* + * For now, this matches what the underlying hardware is doing. + * Update ar6000ProcRxDesc() to use these macros when populating + * the rx descriptor and then we can just copy the field over + * to the WMI PHY notification without worrying about breaking + * things. + */ +#define WMI_UNIFIED_RSSI_CHAN_PRI20 0x000000ff +#define WMI_UNIFIED_RSSI_CHAN_PRI20_S 0 +#define WMI_UNIFIED_RSSI_CHAN_SEC20 0x0000ff00 +#define WMI_UNIFIED_RSSI_CHAN_SEC20_S 8 +#define WMI_UNIFIED_RSSI_CHAN_SEC40 0x00ff0000 +#define WMI_UNIFIED_RSSI_CHAN_SEC40_S 16 +#define WMI_UNIFIED_RSSI_CHAN_SEC80 0xff000000 +#define WMI_UNIFIED_RSSI_CHAN_SEC80_S 24 + +#define WMI_UNIFIED_RSSI_CHAN_SET(hdr, c, ch, rssi) \ + WMI_F_RMW((hdr)->rssi_chain##c, (rssi) & 0xff, \ + WMI_UNIFIED_RSSI_CHAN_##ch); + +#define WMI_UNIFIED_RSSI_CHAN_GET(hdr, c, ch) \ + ((int8_t) (WMI_F_MS((hdr)->rssi_chain##c, \ + WMI_UNIFIED_RSSI_CHAN_##ch))) + +typedef struct { + /** Phy error event header */ + wmi_single_phyerr_rx_hdr hdr; + /** frame buffer */ + A_UINT8 bufp[1]; +}wmi_single_phyerr_rx_event; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_comb_phyerr_rx_hdr */ + /** Phy error phy error count */ + A_UINT32 num_phyerr_events; + A_UINT32 tsf_l32; + A_UINT32 tsf_u32; + A_UINT32 buf_len; + /* This TLV is followed by array of bytes: + * // frame buffer - contains multiple payloads in the order: + * // header - payload, header - payload... + * (The header is of type: wmi_single_phyerr_rx_hdr) + * A_UINT8 bufp[]; + */ +} wmi_comb_phyerr_rx_hdr; + +/* WMI MGMT TX */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mgmt_tx_hdr */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** xmit rate */ + A_UINT32 tx_rate; + /** xmit power */ + A_UINT32 tx_power; + /** Buffer length in bytes */ + A_UINT32 buf_len; + /* This TLV is followed by array of bytes: + * // management frame buffer + * A_UINT8 bufp[]; + */ +} wmi_mgmt_tx_hdr; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_echo_event_fixed_param */ + A_UINT32 value; +} wmi_echo_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_echo_cmd_fixed_param */ + A_UINT32 value; +}wmi_echo_cmd_fixed_param; + + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param */ + + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + /** reg domain code */ + A_UINT32 reg_domain; + A_UINT32 reg_domain_2G; + A_UINT32 reg_domain_5G; + A_UINT32 conformance_test_limit_2G; + A_UINT32 conformance_test_limit_5G; +} wmi_pdev_set_regdomain_cmd_fixed_param; + +typedef struct { + /** TRUE for scan start and flase for scan end */ + A_UINT32 scan_start; +} wmi_pdev_scan_cmd; + +/*Command to set/unset chip in quiet mode*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_quiet_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 period; /*period in TUs*/ + A_UINT32 duration; /*duration in TUs*/ + A_UINT32 next_start; /*offset in TUs*/ + A_UINT32 enabled; /*enable/disable*/ +} wmi_pdev_set_quiet_cmd_fixed_param; + +/* + * Command to enable/disable Green AP Power Save. + * This helps conserve power during AP operation. When the AP has no + * stations associated with it, the host can enable Green AP Power Save + * to request the firmware to shut down all but one transmit and receive + * chains. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 enable; /*1:enable, 0:disable*/ +} wmi_pdev_green_ap_ps_enable_cmd_fixed_param; + + +#define MAX_HT_IE_LEN 32 +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 ie_len; /*length of the ht ie in the TLV ie_data[] */ + /** The TLV for the HT IE follows: + * A_UINT32 ie_data[]; + */ +} wmi_pdev_set_ht_ie_cmd_fixed_param; + +#define MAX_VHT_IE_LEN 32 +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 ie_len; /*length of the vht ie in the TLV ie_data[] */ + /** The TLV for the VHT IE follows: + * A_UINT32 ie_data[]; + */ +} wmi_pdev_set_vht_ie_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + wmi_mac_addr base_macaddr; +} wmi_pdev_set_base_macaddr_cmd_fixed_param; + +/* + * For now, the spectral configuration is global rather than + * per-vdev. The vdev is a placeholder and will be ignored + * by the firmware. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_spectral_configure_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 spectral_scan_count; + A_UINT32 spectral_scan_period; + A_UINT32 spectral_scan_priority; + A_UINT32 spectral_scan_fft_size; + A_UINT32 spectral_scan_gc_ena; + A_UINT32 spectral_scan_restart_ena; + A_UINT32 spectral_scan_noise_floor_ref; + A_UINT32 spectral_scan_init_delay; + A_UINT32 spectral_scan_nb_tone_thr; + A_UINT32 spectral_scan_str_bin_thr; + A_UINT32 spectral_scan_wb_rpt_mode; + A_UINT32 spectral_scan_rssi_rpt_mode; + A_UINT32 spectral_scan_rssi_thr; + A_UINT32 spectral_scan_pwr_format; + A_UINT32 spectral_scan_rpt_mode; + A_UINT32 spectral_scan_bin_scale; + A_UINT32 spectral_scan_dBm_adj; + A_UINT32 spectral_scan_chn_mask; +} wmi_vdev_spectral_configure_cmd_fixed_param; + +/* + * Enabling, disabling and triggering the spectral scan + * is a per-vdev operation. That is, it will set channel + * flags per vdev rather than globally; so concurrent scan/run + * and multiple STA (eg p2p, tdls, multi-band STA) is possible. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_spectral_enable_cmd_fixed_param */ + A_UINT32 vdev_id; + /* 0 - ignore; 1 - trigger, 2 - clear trigger */ + A_UINT32 trigger_cmd; + /* 0 - ignore; 1 - enable, 2 - disable */ + A_UINT32 enable_cmd; +} wmi_vdev_spectral_enable_cmd_fixed_param; + +typedef enum { +WMI_CSA_IE_PRESENT = 0x00000001, +WMI_XCSA_IE_PRESENT = 0x00000002, +WMI_WBW_IE_PRESENT = 0x00000004, +WMI_CSWARP_IE_PRESENT = 0x00000008, +}WMI_CSA_EVENT_IES_PRESENT_FLAG; + +/* wmi CSA receive event from beacon frame */ +typedef struct{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_csa_event_fixed_param */ + A_UINT32 i_fc_dur; +// Bit 0-15: FC +// Bit 16-31: DUR + wmi_mac_addr i_addr1; + wmi_mac_addr i_addr2; + /* NOTE: size of array of csa_ie[], xcsa_ie[], and wb_ie[] cannot be + * changed in the future without breaking WMI compatibility */ + A_UINT32 csa_ie[2]; + A_UINT32 xcsa_ie[2]; + A_UINT32 wb_ie[2]; + A_UINT32 cswarp_ie; + A_UINT32 ies_present_flag; //WMI_CSA_EVENT_IES_PRESENT_FLAG +}wmi_csa_event_fixed_param; + +typedef enum { + /** TX chain mask */ + WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1, + /** RX chian mask */ + WMI_PDEV_PARAM_RX_CHAIN_MASK, + /** TX power limit for 2G Radio */ + WMI_PDEV_PARAM_TXPOWER_LIMIT2G, + /** TX power limit for 5G Radio */ + WMI_PDEV_PARAM_TXPOWER_LIMIT5G, + /** TX power scale */ + WMI_PDEV_PARAM_TXPOWER_SCALE, + /** Beacon generation mode . 0: host, 1: target */ + WMI_PDEV_PARAM_BEACON_GEN_MODE, + /** Beacon generation mode . 0: staggered 1: bursted */ + WMI_PDEV_PARAM_BEACON_TX_MODE, + /** Resource manager off chan mode . + * 0: turn off off chan mode. 1: turn on offchan mode + */ + WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, + /** Protection mode 0: no protection 1:use CTS-to-self 2: use RTS/CTS */ + WMI_PDEV_PARAM_PROTECTION_MODE, + /** Dynamic bandwidth 0: disable 1: enable */ + WMI_PDEV_PARAM_DYNAMIC_BW, + /** Non aggregrate/ 11g sw retry threshold.0-disable */ + WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, + /** aggregrate sw retry threshold. 0-disable*/ + WMI_PDEV_PARAM_AGG_SW_RETRY_TH, + /** Station kickout threshold (non of consecutive failures).0-disable */ + WMI_PDEV_PARAM_STA_KICKOUT_TH, + /** Aggerate size scaling configuration per AC */ + WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, + /** LTR enable */ + WMI_PDEV_PARAM_LTR_ENABLE, + /** LTR latency for BE, in us */ + WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, + /** LTR latency for BK, in us */ + WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, + /** LTR latency for VI, in us */ + WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, + /** LTR latency for VO, in us */ + WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, + /** LTR AC latency timeout, in ms */ + WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, + /** LTR platform latency override, in us */ + WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, + /** LTR-M override, in us */ + WMI_PDEV_PARAM_LTR_RX_OVERRIDE, + /** Tx activity timeout for LTR, in us */ + WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, + /** L1SS state machine enable */ + WMI_PDEV_PARAM_L1SS_ENABLE, + /** Deep sleep state machine enable */ + WMI_PDEV_PARAM_DSLEEP_ENABLE, + /** RX buffering flush enable */ + WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, + /** RX buffering matermark */ + WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, + /** RX buffering timeout enable */ + WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, + /** RX buffering timeout value */ + WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, + /** pdev level stats update period in ms */ + WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, + /** vdev level stats update period in ms */ + WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, + /** peer level stats update period in ms */ + WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, + /** beacon filter status update period */ + WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, + /** QOS Mgmt frame protection MFP/PMF 0: disable, 1: enable */ + WMI_PDEV_PARAM_PMF_QOS, + /** Access category on which ARP frames are sent */ + WMI_PDEV_PARAM_ARP_AC_OVERRIDE, + /** DCS configuration */ + WMI_PDEV_PARAM_DCS, + /** Enable/Disable ANI on target */ + WMI_PDEV_PARAM_ANI_ENABLE, + /** configure the ANI polling period */ + WMI_PDEV_PARAM_ANI_POLL_PERIOD, + /** configure the ANI listening period */ + WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, + /** configure OFDM immunity level */ + WMI_PDEV_PARAM_ANI_OFDM_LEVEL, + /** configure CCK immunity level */ + WMI_PDEV_PARAM_ANI_CCK_LEVEL, + /** Enable/Disable CDD for 1x1 STAs in rate control module */ + WMI_PDEV_PARAM_DYNTXCHAIN, + /** Enable/Disable proxy STA */ + WMI_PDEV_PARAM_PROXY_STA, + /** Enable/Disable low power state when all VDEVs are inactive/idle. */ + WMI_PDEV_PARAM_IDLE_PS_CONFIG, + /** Enable/Disable power gating sleep */ + WMI_PDEV_PARAM_POWER_GATING_SLEEP, + /** Enable/Disable Rfkill */ + WMI_PDEV_PARAM_RFKILL_ENABLE, + /** Set Bursting DUR */ + WMI_PDEV_PARAM_BURST_DUR, + /** Set Bursting ENABLE */ + WMI_PDEV_PARAM_BURST_ENABLE, + /** HW rfkill config */ + WMI_PDEV_PARAM_HW_RFKILL_CONFIG, + /** Enable radio low power features */ + WMI_PDEV_PARAM_LOW_POWER_RF_ENABLE, + /** L1SS entry and residency time track */ + WMI_PDEV_PARAM_L1SS_TRACK, + /** set hyst at runtime, requirement from SS */ + WMI_PDEV_PARAM_HYST_EN, + /** Enable/ Disable POWER COLLAPSE */ + WMI_PDEV_PARAM_POWER_COLLAPSE_ENABLE, + /** configure LED system state */ + WMI_PDEV_PARAM_LED_SYS_STATE, + /** Enable/Disable LED */ + WMI_PDEV_PARAM_LED_ENABLE, + /** set DIRECT AUDIO time latency */ + WMI_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, + /** set DIRECT AUDIO Feature ENABLE */ + WMI_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, + /** pdev level whal mib stats update enable */ + WMI_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, + /** ht/vht info based on vdev */ + WMI_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, + /** Set CTS channel BW for dynamic BW adjustment feature */ + WMI_PDEV_PARAM_CTS_CBW, + /** Set GPIO pin info used by WNTS */ + WMI_PDEV_PARAM_WNTS_CONFIG, + /** Enable/Disable hardware adaptive early rx feature */ + WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_ENABLE, + /** The minimum early rx duration, to ensure early rx duration is non-zero */ + WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_MIN_SLEEP_SLOP, + /** Increasing/decreasing step used by hardware */ + WMI_PDEV_PARAM_ADAPTIVE_EARLY_RX_INC_DEC_STEP, + /** The fixed early rx duration when adaptive early rx is disabled */ + WMI_PDEV_PARAM_EARLY_RX_FIX_SLEEP_SLOP, + /** Enable/Disable bmiss based adaptive beacon timeout feature */ + WMI_PDEV_PARAM_BMISS_BASED_ADAPTIVE_BTO_ENABLE, + /** The minimum beacon timeout duration, to ensure beacon timeout duration is non-zero */ + WMI_PDEV_PARAM_BMISS_BTO_MIN_BCN_TIMEOUT, + /** Increasing/decreasing step used by hardware */ + WMI_PDEV_PARAM_BMISS_BTO_INC_DEC_STEP, + /** The fixed beacon timeout duration when bmiss based adaptive beacon timeout is disabled */ + WMI_PDEV_PARAM_BTO_FIX_BCN_TIMEOUT, + /** Enable/Disable Congestion Estimator based adaptive beacon timeout feature */ + WMI_PDEV_PARAM_CE_BASED_ADAPTIVE_BTO_ENABLE, + /** combo value of ce_id, ce_threshold, ce_time, refer to WMI_CE_BTO_CE_ID_MASK */ + WMI_PDEV_PARAM_CE_BTO_COMBO_CE_VALUE, +} WMI_PDEV_PARAM; + +typedef enum { + /** Set the loglevel */ + WMI_DBGLOG_LOG_LEVEL = 0x1, + /** Enable VAP level debug */ + WMI_DBGLOG_VAP_ENABLE, + /** Disable VAP level debug */ + WMI_DBGLOG_VAP_DISABLE, + /** Enable MODULE level debug */ + WMI_DBGLOG_MODULE_ENABLE, + /** Disable MODULE level debug */ + WMI_DBGLOG_MODULE_DISABLE, + /** Enable MODULE level debug */ + WMI_DBGLOG_MOD_LOG_LEVEL, + /** set type of the debug output */ + WMI_DBGLOG_TYPE, + /** Enable Disable debug */ + WMI_DBGLOG_REPORT_ENABLE +} WMI_DBG_PARAM; + +/* param_value for param_id WMI_PDEV_PARAM_CTS_CBW */ +typedef enum { + WMI_CTS_CBW_INVALID = 0, + WMI_CTS_CBW_20, + WMI_CTS_CBW_40, + WMI_CTS_CBW_80, + WMI_CTS_CBW_80_80, + WMI_CTS_CBW_160, +} WMI_CTS_CBW; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + /** parameter id */ + A_UINT32 param_id; + /** parametr value */ + A_UINT32 param_value; +} wmi_pdev_set_param_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_get_tpc_config_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + /** parameter */ + A_UINT32 param; +} wmi_pdev_get_tpc_config_cmd_fixed_param; + +#define WMI_FAST_DIVERSITY_BIT_OFFSET 0 +#define WMI_SLOW_DIVERSITY_BIT_OFFSET 1 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_antenna_diversity_cmd_fixed_param */ + A_UINT32 mac_id; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + /** parameter */ + A_UINT32 value; /** bit0 is for enable/disable FAST diversity, and bit1 is for enable/disable SLOW diversity, 0->disable, 1->enable */ +} wmi_pdev_set_antenna_diversity_cmd_fixed_param; + +#define WMI_MAX_RSSI_THRESHOLD_SUPPORTED 3 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rssi_breach_monitor_config_cmd_fixed_param */ + A_UINT32 vdev_id; /* vdev_id, where RSSI monitoring will take place */ + A_UINT32 request_id; /* host will configure request_id and firmware echo this id in RSSI_BREACH_EVENT */ + A_UINT32 enabled_bitmap; /* bit [0-2] = low_rssi_breach_enabled[0-2] enabled, bit [3-5] = hi_rssi_breach_enabled[0-2] */ + A_UINT32 low_rssi_breach_threshold[WMI_MAX_RSSI_THRESHOLD_SUPPORTED]; /* unit dBm. host driver to make sure [0] > [1] > [2] */ + A_UINT32 hi_rssi_breach_threshold[WMI_MAX_RSSI_THRESHOLD_SUPPORTED]; /* unit dBm. host driver to make sure [0] < [1] < [2] */ + A_UINT32 lo_rssi_reenable_hysteresis; /* unit dBm. once low rssi[] breached, same event bitmap will be generated only after signal gets better than this level. This value is adopted for all low_rssi_breach_threshold[3] */ + A_UINT32 hi_rssi_reenable_histeresis;/* unit dBm. once hi rssi[] breached, same event bitmap will be generated only after signal gets worse than this level. This value is adopted for all hi_rssi_breach_threshold[3] */ + A_UINT32 min_report_interval; /* After last event is generated, we wait until this interval to generate next event */ + A_UINT32 max_num_report; /* this is to suppress number of event to be generated */ +} wmi_rssi_breach_monitor_config_fixed_param; + +typedef struct { + /** parameter */ + A_UINT32 param; +} wmi_pdev_dump_cmd; + +typedef enum { + PAUSE_TYPE_CHOP = 0x1, /** for MCC (switch channel), only vdev_map is valid */ + PAUSE_TYPE_PS = 0x2, /** for peer station sleep in sap mode, only peer_id is valid */ + PAUSE_TYPE_UAPSD = 0x3, /** for uapsd, only peer_id and tid_map are valid. */ + PAUSE_TYPE_P2P_CLIENT_NOA = 0x4, /** only vdev_map is valid, actually only one vdev id is set at one time */ + PAUSE_TYPE_P2P_GO_PS = 0x5, /** only vdev_map is valid, actually only one vdev id is set at one time */ + PAUSE_TYPE_STA_ADD_BA = 0x6, /** only peer_id and tid_map are valid, actually only one tid is set at one time */ + PAUSE_TYPE_AP_PS = 0x7, /** for pausing AP vdev when all the connected clients are in PS. only vdev_map is valid */ + PAUSE_TYPE_IBSS_PS = 0x8, /** for pausing IBSS vdev when all the peers are in PS. only vdev_map is valid */ + PAUSE_TYPE_HOST = 0x15,/** host is requesting vdev pause */ +} wmi_tx_pause_type; + +typedef enum { + ACTION_PAUSE = 0x0, + ACTION_UNPAUSE = 0x1, +} wmi_tx_pause_action; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 pause_type; + A_UINT32 action; + A_UINT32 vdev_map; + A_UINT32 peer_id; + A_UINT32 tid_map; +} wmi_tx_pause_event_fixed_param; + +#define WMI_TPC_RATE_MAX 160 +/* WMI_TPC_TX_NUM_CHAIN macro can't be changed without breaking the WMI compatibility */ +#define WMI_TPC_TX_NUM_CHAIN 4 + +typedef enum { + WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD = 0x1, + WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC = 0x2, + WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF = 0x4, +} WMI_TPC_CONFIG_EVENT_FLAG; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_tpc_config_event_fixed_param */ + A_UINT32 regDomain; + A_UINT32 chanFreq; + A_UINT32 phyMode; + A_UINT32 twiceAntennaReduction; + A_UINT32 twiceMaxRDPower; + A_INT32 twiceAntennaGain; + A_UINT32 powerLimit; + A_UINT32 rateMax; + A_UINT32 numTxChain; + A_UINT32 ctl; + A_UINT32 flags; + /* WMI_TPC_TX_NUM_CHAIN macro can't be changed without breaking the WMI compatibility */ + A_INT8 maxRegAllowedPower[WMI_TPC_TX_NUM_CHAIN]; + A_INT8 maxRegAllowedPowerAGCDD[WMI_TPC_TX_NUM_CHAIN][WMI_TPC_TX_NUM_CHAIN]; + A_INT8 maxRegAllowedPowerAGSTBC[WMI_TPC_TX_NUM_CHAIN][WMI_TPC_TX_NUM_CHAIN]; + A_INT8 maxRegAllowedPowerAGTXBF[WMI_TPC_TX_NUM_CHAIN][WMI_TPC_TX_NUM_CHAIN]; + /* This TLV is followed by a byte array: + * A_UINT8 ratesArray[]; + */ +} wmi_pdev_tpc_config_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_l1ss_track_event_fixed_param */ + A_UINT32 periodCnt; + A_UINT32 L1Cnt; + A_UINT32 L11Cnt; + A_UINT32 L12Cnt; + A_UINT32 L1Entry; + A_UINT32 L11Entry; + A_UINT32 L12Entry; +} wmi_pdev_l1ss_track_event_fixed_param; + +typedef struct { + A_UINT32 len; + A_UINT32 msgref; + A_UINT32 segmentInfo; +} wmi_pdev_seg_hdr_info; + + +/* + * Transmit power scale factor. + * + */ +typedef enum { + WMI_TP_SCALE_MAX = 0, /* no scaling (default) */ + WMI_TP_SCALE_50 = 1, /* 50% of max (-3 dBm) */ + WMI_TP_SCALE_25 = 2, /* 25% of max (-6 dBm) */ + WMI_TP_SCALE_12 = 3, /* 12% of max (-9 dBm) */ + WMI_TP_SCALE_MIN = 4, /* min, but still on */ + WMI_TP_SCALE_SIZE = 5, /* max num of enum */ +} WMI_TP_SCALE; + +#define WMI_MAX_DEBUG_MESG (sizeof(A_UINT32) * 32) + +typedef struct { + /** message buffer, NULL terminated */ + char bufp[WMI_MAX_DEBUG_MESG]; +} wmi_debug_mesg_event; + +enum { + /** IBSS station */ + VDEV_TYPE_IBSS = 0, + /** infra STA */ + VDEV_TYPE_STA = 1, + /** infra AP */ + VDEV_TYPE_AP = 2, + /** Monitor */ + VDEV_TYPE_MONITOR =3, + /** OCB */ + VDEV_TYPE_OCB = 6, +}; + +enum { + /** P2P device */ + VDEV_SUBTYPE_P2PDEV=0, + /** P2P client */ + VDEV_SUBTYPE_P2PCLI, + /** P2P GO */ + VDEV_SUBTYPE_P2PGO, + /** BT3.0 HS */ + VDEV_SUBTYPE_BT, +}; + +typedef struct { + /** idnore power , only use flags , mode and freq */ + wmi_channel chan; +} wmi_pdev_set_channel_cmd; + +typedef enum { + WMI_PKTLOG_EVENT_RX = 0x1, + WMI_PKTLOG_EVENT_TX = 0x2, + WMI_PKTLOG_EVENT_RCF = 0x4, /* Rate Control Find */ + WMI_PKTLOG_EVENT_RCU = 0x8, /* Rate Control Update */ + /* 0x10 used by deprecated DBG_PRINT */ + WMI_PKTLOG_EVENT_SMART_ANTENNA = 0x20, /* To support Smart Antenna */ +} WMI_PKTLOG_EVENT; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + WMI_PKTLOG_EVENT evlist; +} wmi_pdev_pktlog_enable_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param */ + A_UINT32 reserved0; +} wmi_pdev_pktlog_disable_cmd_fixed_param; + +/** Customize the DSCP (bit) to TID (0-7) mapping for QOS. + * NOTE: This constant cannot be changed without breaking + * WMI Compatibility. */ + +#define WMI_DSCP_MAP_MAX (64) + /* + * @brief dscp_tid_map_cmdid - command to send the dscp to tid map to the target + * @details + * Create an API for sending the custom DSCP-to-TID map to the target + * If this is a request from the user space or from above the UMAC + * then the best place to implement this is in the umac_if_offload of the OL path. + * Provide a place holder for this API in the ieee80211com (ic). + * + * This API will be a function pointer in the ieee80211com (ic). Any user space calls for manually setting the DSCP-to-TID mapping + * in the target should be directed to the function pointer in the ic. + * + * Implementation details of the API to send the map to the target are as described- + * + * 1. The function will have 2 arguments- struct ieee80211com, DSCP-to-TID map. + * DSCP-to-TID map is a one dimensional u_int32_t array of length 64 to accomodate + * 64 TID values for 2^6 (64) DSCP ids. + * Example: + * A_UINT32 dscp_tid_map[WMI_DSCP_MAP_MAX] = { + * 0, 0, 0, 0, 0, 0, 0, 0, + * 1, 1, 1, 1, 1, 1, 1, 1, + * 2, 2, 2, 2, 2, 2, 2, 2, + * 3, 3, 3, 3, 3, 3, 3, 3, + * 4, 4, 4, 4, 4, 4, 4, 4, + * 5, 5, 5, 5, 5, 5, 5, 5, + * 6, 6, 6, 6, 6, 6, 6, 6, + * 7, 7, 7, 7, 7, 7, 7, 7, + * }; + * + * 2. Request for the WMI buffer of size equal to the size of the DSCP-to-TID map. + * + * 3. Copy the DSCP-to-TID map into the WMI buffer. + * + * 4. Invoke the wmi_unified_cmd_send to send the cmd buffer to the target with the + * WMI_PDEV_SET_DSCP_TID_MAP_CMDID. Arguments to the wmi send cmd API + * (wmi_unified_send_cmd) are wmi handle, cmd buffer, length of the cmd buffer and + * the WMI_PDEV_SET_DSCP_TID_MAP_CMDID id. + * + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_dscp_tid_map_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + /* map indicating DSCP to TID conversion */ + A_UINT32 dscp_to_tid_map[WMI_DSCP_MAP_MAX]; +} wmi_pdev_set_dscp_tid_map_cmd_fixed_param; + +/** Fixed rate (rate-code) for broadcast/ multicast data frames */ +/* @brief bcast_mcast_data_rate - set the rates for the bcast/ mcast frames + * @details + * Create an API for setting the custom rate for the MCAST and BCAST frames + * in the target. If this is a request from the user space or from above the UMAC + * then the best place to implement this is in the umac_if_offload of the OL path. + * Provide a place holder for this API in the ieee80211com (ic). + * + * Implementation details of the API to set custom rates for MCAST and BCAST in + * the target are as described- + * + * 1. The function will have 3 arguments- + * vap structure, + * MCAST/ BCAST identifier code, + * 8 bit rate code + * + * The rate-code is a 1-byte field in which:for given rate, nss and preamble + * b'7-b-6 indicate the preamble (0 OFDM, 1 CCK, 2, HT, 3 VHT) + * b'5-b'4 indicate the NSS (0 - 1x1, 1 - 2x2, 2 - 3x3) + * b'3-b'0 indicate the rate, which is indicated as follows: + * OFDM : 0: OFDM 48 Mbps + * 1: OFDM 24 Mbps + * 2: OFDM 12 Mbps + * 3: OFDM 6 Mbps + * 4: OFDM 54 Mbps + * 5: OFDM 36 Mbps + * 6: OFDM 18 Mbps + * 7: OFDM 9 Mbps + * CCK (pream == 1) + * 0: CCK 11 Mbps Long + * 1: CCK 5.5 Mbps Long + * 2: CCK 2 Mbps Long + * 3: CCK 1 Mbps Long + * 4: CCK 11 Mbps Short + * 5: CCK 5.5 Mbps Short + * 6: CCK 2 Mbps Short + * HT/VHT (pream == 2/3) + * 0..7: MCS0..MCS7 (HT) + * 0..9: MCS0..MCS9 (VHT) + * + * 2. Invoke the wmi_unified_vdev_set_param_send to send the rate value + * to the target. + * Arguments to the API are- + * wmi handle, + * VAP interface id (av_if_id) defined in ol_ath_vap_net80211, + * WMI_VDEV_PARAM_BCAST_DATA_RATE/ WMI_VDEV_PARAM_MCAST_DATA_RATE, + * rate value. + */ +typedef enum { + WMI_SET_MCAST_RATE, + WMI_SET_BCAST_RATE +} MCAST_BCAST_RATE_ID; + +typedef struct { + MCAST_BCAST_RATE_ID rate_id; + A_UINT32 rate; +} mcast_bcast_rate; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wmm_params */ + A_UINT32 cwmin; + A_UINT32 cwmax; + A_UINT32 aifs; + A_UINT32 txoplimit; + A_UINT32 acm; + A_UINT32 no_ack; +} wmi_wmm_params; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_set_wmm_params_cmd_fixed_param */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 dg_type; + + /* The TLVs for the 4 AC follows: + * wmi_wmm_params wmm_params_ac_be; + * wmi_wmm_params wmm_params_ac_bk; + * wmi_wmm_params wmm_params_ac_vi; + * wmi_wmm_params wmm_params_ac_vo; + */ +} wmi_pdev_set_wmm_params_cmd_fixed_param; + +typedef enum { + WMI_REQUEST_PEER_STAT = 0x01, + WMI_REQUEST_AP_STAT = 0x02, + WMI_REQUEST_PDEV_STAT = 0x04, + WMI_REQUEST_VDEV_STAT = 0x08, + WMI_REQUEST_BCNFLT_STAT = 0x10, + WMI_REQUEST_VDEV_RATE_STAT = 0x20, +} wmi_stats_id; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param */ + wmi_stats_id stats_id; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; +} wmi_request_stats_cmd_fixed_param; + +/* stats type bitmap */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + + +/* wifi clear statistics bitmap */ +#define WIFI_STATS_RADIO 0x00000001 /** all radio statistics */ +#define WIFI_STATS_RADIO_CCA 0x00000002 /** cca_busy_time (within radio statistics) */ +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 /** all channel statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_SCAN 0x00000008 /** all scan statistics (within radio statistics) */ +#define WIFI_STATS_IFACE 0x00000010 /** all interface statistics */ +#define WIFI_STATS_IFACE_TXRATE 0x00000020 /** all tx rate statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_AC 0x00000040 /** all ac statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 /** all contention (min, max, avg) statistics (within ac statisctics) */ +#define WMI_STATS_IFACE_ALL_PEER 0x00000100 /** All peer stats on this interface */ +#define WMI_STATS_IFACE_PER_PEER 0x00000200 /** Clear particular peer stats depending on the peer_mac */ + +/** Default value for stats if the stats collection has not started */ +#define WMI_STATS_VALUE_INVALID 0xffffffff + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param*/ + A_UINT32 reserved0; /** placeholder for future */ +} wmi_debug_mesg_flush_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_debug_mesg_flush_complete_fixed_param*/ + A_UINT32 reserved0; /** placeholder for future */ +} wmi_debug_mesg_flush_complete_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rssi_breach_fixed_param */ + /* vdev_id, where RSSI breach event occurred */ + A_UINT32 vdev_id; + /* request id */ + A_UINT32 request_id; + /* bitmap[0-2] is corresponding to low_rssi[0-2]. bitmap[3-5] is corresponding to hi_rssi[0-2]*/ + A_UINT32 event_bitmap; + /* rssi at the time of RSSI breach. Unit dBm */ + A_UINT32 rssi; + /* bssid of the monitored AP's */ + wmi_mac_addr bssid; +} wmi_rssi_breach_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_fw_mem_dump */ + /** unique id identifying the segment */ + A_UINT32 seg_id; + /** Start address of the segment to be read */ + A_UINT32 seg_start_addr_lo; + A_UINT32 seg_start_addr_hi; + /** Length of the segment to be read */ + A_UINT32 seg_length; + /** Host bufeer address to which the segment will be read and dumped */ + A_UINT32 dest_addr_lo; + A_UINT32 dest_addr_hi; +} wmi_fw_mem_dump; + +/* Command to get firmware memory dump*/ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_get_fw_mem_dump_fixed_param */ + /** unique id identifying the request */ + A_UINT32 request_id; + /** number of memory dump segments */ + A_UINT32 num_fw_mem_dump_segs; +/** + * This TLV is followed by another TLV + * wmi_fw_mem_dump fw_mem_dump[]; + */ +} wmi_get_fw_mem_dump_fixed_param; + +/** Event to indicate the completion of fw mem dump */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_update_fw_mem_dump_fixed_param */ + /** unique id identifying the request, given in the request stats command */ + A_UINT32 request_id; + /*In case of Firmware memory dump */ + A_UINT32 fw_mem_dump_complete; +} wmi_update_fw_mem_dump_fixed_param; + +typedef enum { + WMI_ROAMING_IDLE = 0, + WMI_ROAMING_ACTIVE = 1, +} wmi_roam_state; + +/* access categories */ +typedef enum { + WMI_AC_VO = 0, + WMI_AC_VI = 1, + WMI_AC_BE = 2, + WMI_AC_BK = 3, + WMI_AC_MAX = 4, +} wmi_traffic_ac; + +typedef enum { + WMI_STA_STATS = 0, + WMI_SOFTAP_STATS = 1, + WMI_IBSS_STATS = 2, + WMI_P2P_CLIENT_STATS = 3, + WMI_P2P_GO_STATS = 4, + WMI_NAN_STATS = 5, + WMI_MESH_STATS = 6, +} wmi_link_iface_type; + +/* channel operating width */ +typedef enum { + WMI_CHAN_WIDTH_20 = 0, + WMI_CHAN_WIDTH_40 = 1, + WMI_CHAN_WIDTH_80 = 2, + WMI_CHAN_WIDTH_160 = 3, + WMI_CHAN_WIDTH_80P80 = 4, + WMI_CHAN_WIDTH_5 = 5, + WMI_CHAN_WIDTH_10 = 6, +} wmi_channel_width; + +/* wifi peer type */ +typedef enum { + WMI_PEER_STA, + WMI_PEER_AP, + WMI_PEER_P2P_GO, + WMI_PEER_P2P_CLIENT, + WMI_PEER_NAN, + WMI_PEER_TDLS, + WMI_PEER_OCB, + WMI_PEER_INVALID, +} wmi_peer_type; + +/*Clear stats*/ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** stop_stats_collection_req = 1 will imply stop the statistics collection */ + A_UINT32 stop_stats_collection_req; + /** identifies what stats to be cleared */ + A_UINT32 stats_clear_req_mask; + /** identifies which peer stats to be cleared. Valid only while clearing PER_REER */ + wmi_mac_addr peer_macaddr; +} wmi_clear_link_stats_cmd_fixed_param; + +/* Link Stats configuration params. Trigger the link layer statistics collection*/ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param */ + /** threshold to classify the pkts as short or long */ + A_UINT32 mpdu_size_threshold; + /** set for field debug mode. Driver should collect all statistics regardless of performance impact.*/ + A_UINT32 aggressive_statistics_gathering; +} wmi_start_link_stats_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param */ + /** Type of stats required. This is a bitmask WMI_LINK_STATS_RADIO, WMI_LINK_STATS_IFACE */ + A_UINT32 stats_type; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** unique id identifying the request, generated by the caller */ + A_UINT32 request_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; +} wmi_request_link_stats_cmd_fixed_param; + +/* channel statistics */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_channel_stats */ + /** Channel width (20, 40, 80, 80+80, 160) enum wmi_channel_width*/ + A_UINT32 channel_width; + /** Primary 20 MHz channel */ + A_UINT32 center_freq; + /** center frequency (MHz) first segment */ + A_UINT32 center_freq0; + /** center frequency (MHz) second segment */ + A_UINT32 center_freq1; + /** msecs the radio is awake (32 bits number accruing over time) */ + A_UINT32 radio_awake_time; + /** msecs the CCA register is busy (32 bits number accruing over time) */ + A_UINT32 cca_busy_time; +} wmi_channel_stats; + +/* radio statistics */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_radio_link_stats */ + /** Wifi radio (if multiple radio supported) */ + A_UINT32 radio_id; + /** msecs the radio is awake (32 bits number accruing over time) */ + A_UINT32 on_time; + /** msecs the radio is transmitting (32 bits number accruing over time) */ + A_UINT32 tx_time; + /** msecs the radio is in active receive (32 bits number accruing over time) */ + A_UINT32 rx_time; + /** msecs the radio is awake due to all scan (32 bits number accruing over time) */ + A_UINT32 on_time_scan; + /** msecs the radio is awake due to NAN (32 bits number accruing over time) */ + A_UINT32 on_time_nbd; + /** msecs the radio is awake due to G?scan (32 bits number accruing over time) */ + A_UINT32 on_time_gscan; + /** msecs the radio is awake due to roam?scan (32 bits number accruing over time) */ + A_UINT32 on_time_roam_scan; + /** msecs the radio is awake due to PNO scan (32 bits number accruing over time) */ + A_UINT32 on_time_pno_scan; + /** msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits number accruing over time) */ + A_UINT32 on_time_hs20; + /** number of channels */ + A_UINT32 num_channels; +} wmi_radio_link_stats; + +/** Radio statistics (once started) do not stop or get reset unless wifi_clear_link_stats is invoked */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stats_event_fixed_param */ + /** unique id identifying the request, given in the request stats command */ + A_UINT32 request_id; + /** Number of radios*/ + A_UINT32 num_radio; + /** more_data will be set depending on the number of radios */ + A_UINT32 more_radio_events; +/* + * This TLV is followed by another TLV of array of bytes + * size of(struct wmi_radio_link_stats); + * + * This TLV is followed by another TLV of array of bytes + * num_channels * size of(struct wmi_channel_stats) + */ + +} wmi_radio_link_stats_event_fixed_param; + +/* per rate statistics */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rate_stats */ + /** rate information + * The rate-code is a 1-byte field in which:for given rate, nss and preamble + * b'7-b-6 indicate the preamble (0 OFDM, 1 CCK, 2, HT, 3 VHT) + * b'5-b'4 indicate the NSS (0 - 1x1, 1 - 2x2, 2 - 3x3) + * b'3-b'0 indicate the rate, which is indicated as follows: + * OFDM : 0: OFDM 48 Mbps + * 1: OFDM 24 Mbps + * 2: OFDM 12 Mbps + * 3: OFDM 6 Mbps + * 4: OFDM 54 Mbps + * 5: OFDM 36 Mbps + * 6: OFDM 18 Mbps + * 7: OFDM 9 Mbps + * CCK (pream == 1) + * 0: CCK 11 Mbps Long + * 1: CCK 5.5 Mbps Long + * 2: CCK 2 Mbps Long + * 3: CCK 1 Mbps Long + * 4: CCK 11 Mbps Short + * 5: CCK 5.5 Mbps Short + * 6: CCK 2 Mbps Short + * HT/VHT (pream == 2/3) + * 0..7: MCS0..MCS7 (HT) + * 0..9: MCS0..MCS9 (VHT) + */ + A_UINT32 rate; + /** units of 100 Kbps */ + A_UINT32 bitrate; + /** number of successfully transmitted data pkts (ACK rcvd) */ + A_UINT32 tx_mpdu; + /** number of received data pkts */ + A_UINT32 rx_mpdu; + /** number of data packet losses (no ACK) */ + A_UINT32 mpdu_lost; + /** total number of data pkt retries */ + A_UINT32 retries; + /** number of short data pkt retries */ + A_UINT32 retries_short; + /** number of long data pkt retries */ + A_UINT32 retries_long; +} wmi_rate_stats; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_link_stats */ + /** peer type (AP, TDLS, GO etc.) enum wmi_peer_type*/ + A_UINT32 peer_type; + /** mac address */ + wmi_mac_addr peer_mac_address; + /** peer wmi_CAPABILITY_XXX */ + A_UINT32 capabilities; + /** number of rates */ + A_UINT32 num_rates; +} wmi_peer_link_stats; + +/** PEER statistics (once started) reset and start afresh after each connection */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_stats_event_fixed_param */ + /** unique id identifying the request, given in the request stats command */ + A_UINT32 request_id; + /** number of peers accomidated in this particular event */ + A_UINT32 num_peers; + /** Indicates the fragment number */ + A_UINT32 peer_event_number; + /** Indicates if there are more peers which will be sent as seperate peer_stats event */ + A_UINT32 more_data; + +/** + * This TLV is followed by another TLV + * num_peers * size of(struct wmi_peer_stats) + * num_rates * size of(struct wmi_rate_stats). num_rates is the sum of the rates of all the peers. + */ +} wmi_peer_stats_event_fixed_param; + +/* per access category statistics */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wmm_ac_stats */ + /** access category (VI, VO, BE, BK) enum wmi_traffic_ac*/ + A_UINT32 ac_type; + /** number of successfully transmitted unicast data pkts (ACK rcvd) */ + A_UINT32 tx_mpdu; + /** number of received unicast mpdus */ + A_UINT32 rx_mpdu; + /** number of succesfully transmitted multicast data packets */ + /** STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ + A_UINT32 tx_mcast; + /** number of received multicast data packets */ + A_UINT32 rx_mcast; + /** number of received unicast a-mpdus */ + A_UINT32 rx_ampdu; + /** number of transmitted unicast a-mpdus */ + A_UINT32 tx_ampdu; + /** number of data pkt losses (no ACK) */ + A_UINT32 mpdu_lost; + /** total number of data pkt retries */ + A_UINT32 retries; + /** number of short data pkt retries */ + A_UINT32 retries_short; + /** number of long data pkt retries */ + A_UINT32 retries_long; + /** data pkt min contention time (usecs) */ + A_UINT32 contention_time_min; + /** data pkt max contention time (usecs) */ + A_UINT32 contention_time_max; + /** data pkt avg contention time (usecs) */ + A_UINT32 contention_time_avg; + /** num of data pkts used for contention statistics */ + A_UINT32 contention_num_samples; +} wmi_wmm_ac_stats; + +/* interface statistics */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_iface_link_stats */ + /** access point beacon received count from connected AP */ + A_UINT32 beacon_rx; + /** access point mgmt frames received count from connected AP (including Beacon) */ + A_UINT32 mgmt_rx; + /** action frames received count */ + A_UINT32 mgmt_action_rx; + /** action frames transmit count */ + A_UINT32 mgmt_action_tx; + /** access Point Beacon and Management frames RSSI (averaged) */ + A_UINT32 rssi_mgmt; + /** access Point Data Frames RSSI (averaged) from connected AP */ + A_UINT32 rssi_data; + /** access Point ACK RSSI (averaged) from connected AP */ + A_UINT32 rssi_ack; + /** number of peers */ + A_UINT32 num_peers; + /** Indicates how many peer_stats events will be sent depending on the num_peers. */ + A_UINT32 num_peer_events; + /** number of ac */ + A_UINT32 num_ac; + /** Roaming Stat */ + A_UINT32 roam_state; + /** Average Beacon spread offset is the averaged time delay between TBTT and beacon TSF */ + /** Upper 32 bits of averaged 64 bit beacon spread offset */ + A_UINT32 avg_bcn_spread_offset_high; + /** Lower 32 bits of averaged 64 bit beacon spread offset */ + A_UINT32 avg_bcn_spread_offset_low; + /** Takes value of 1 if AP leaks packets after sending an ACK for PM=1 otherwise 0 */ + A_UINT32 is_leaky_ap; + /** Average number of frames received from AP after receiving the ACK for a frame with PM=1 */ + A_UINT32 avg_rx_frms_leaked; + /** Rx leak watch window currently in force to minimize data loss because of leaky AP. Rx leak window is the + time driver waits before shutting down the radio or switching the channel and after receiving an ACK for + a data frame with PM bit set) */ + A_UINT32 rx_leak_window; +} wmi_iface_link_stats; + +/** Interface statistics (once started) reset and start afresh after each connection */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_iface_link_stats_event_fixed_param */ + /** unique id identifying the request, given in the request stats command */ + A_UINT32 request_id; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +/* + * This TLV is followed by another TLV + * wmi_iface_link_stats iface_link_stats; + * num_ac * size of(struct wmi_wmm_ac_stats) + */ +} wmi_iface_link_stats_event_fixed_param; + +/** Suspend option */ +enum { + WMI_PDEV_SUSPEND, /* suspend */ + WMI_PDEV_SUSPEND_AND_DISABLE_INTR, /* suspend and disable all interrupts */ +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param */ + /* suspend option sent to target */ + A_UINT32 reserved0; /** placeholder for pdev_id of future multiple MAC products. Init. to 0. */ + A_UINT32 suspend_opt; +} wmi_pdev_suspend_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param */ + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_pdev_resume_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_rate_stats_event_fixed_param, */ + A_UINT32 num_vdev_stats; /* number of vdevs */ +}wmi_vdev_rate_stats_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len, tag equals WMITLV_TAG_STRUC_wmi_vdev_rate_ht_info*/ + A_UINT32 vdevid; /* Id of the wlan vdev*/ + A_UINT32 tx_nss; /* Bit 28 of tx_rate_kbps has this info - based on last data packet transmitted*/ + A_UINT32 rx_nss; /* Bit 24 of rx_rate_kbps - same as above*/ + A_UINT32 tx_preamble; /* Bits 30-29 from tx_rate_kbps */ + A_UINT32 rx_preamble; /* Bits 26-25 from rx_rate_kbps */ +} wmi_vdev_rate_ht_info; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stats_event_fixed_param */ + wmi_stats_id stats_id; + /** number of pdev stats event structures (wmi_pdev_stats) 0 or 1 */ + A_UINT32 num_pdev_stats; + /** number of vdev stats event structures (wmi_vdev_stats) 0 or max vdevs */ + A_UINT32 num_vdev_stats; + /** number of peer stats event structures (wmi_peer_stats) 0 or max peers */ + A_UINT32 num_peer_stats; + A_UINT32 num_bcnflt_stats; + /** number of chan stats event structures (wmi_chan_stats) 0 to MAX MCC CHANS */ + A_UINT32 num_chan_stats; + /* This TLV is followed by another TLV of array of bytes + * A_UINT8 data[]; + * This data array contains + * num_pdev_stats * size of(struct wmi_pdev_stats) + * num_vdev_stats * size of(struct wmi_vdev_stats) + * num_peer_stats * size of(struct wmi_peer_stats) + * num_bcnflt_stats * size_of() + * num_chan_stats * size of(struct wmi_chan_stats) + * + */ +} wmi_stats_event_fixed_param; + +/** + * PDEV statistics + * @todo + * add all PDEV stats here + */ +typedef struct { + /** Channel noise floor */ + A_INT32 chan_nf; + /** TX frame count */ + A_UINT32 tx_frame_count; + /** RX frame count */ + A_UINT32 rx_frame_count; + /** rx clear count */ + A_UINT32 rx_clear_count; + /** cycle count */ + A_UINT32 cycle_count; + /** Phy error count */ + A_UINT32 phy_err_count; + /** Channel Tx Power */ + A_UINT32 chan_tx_pwr; + /** WAL dbg stats */ + struct wlan_dbg_stats pdev_stats; + +} wmi_pdev_stats; + +/** + * VDEV statistics + * @todo + * add all VDEV stats here + */ + +typedef struct { + A_INT32 bcn_snr; + A_INT32 dat_snr; +} wmi_snr_info; + +typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + wmi_snr_info vdev_snr; + A_UINT32 tx_frm_cnt[WLAN_MAX_AC];/* Total number of packets(per AC) that were successfully transmitted(with and without retries, including multi-cast, broadcast) */ + A_UINT32 rx_frm_cnt;/* Total number of packets that were successfully received (after appropriate filter rules including multi-cast, broadcast)*/ + A_UINT32 multiple_retry_cnt[WLAN_MAX_AC];/*The number of MSDU packets and MMPDU frames per AC + that the 802.11 station successfully transmitted after more than one retransmission attempt*/ + A_UINT32 fail_cnt[WLAN_MAX_AC]; /*Total number packets(per AC) failed to transmit */ + A_UINT32 rts_fail_cnt;/*Total number of RTS/CTS sequence failures for transmission of a packet*/ + A_UINT32 rts_succ_cnt;/*Total number of RTS/CTS sequence success for transmission of a packet*/ + A_UINT32 rx_err_cnt;/*The receive error count. HAL will provide the RxP FCS error global */ + A_UINT32 rx_discard_cnt;/* The sum of the receive error count and dropped-receive-buffer error count. (FCS error)*/ + A_UINT32 ack_fail_cnt;/*Total number packets failed transmit because of no ACK from the remote entity*/ + A_UINT32 tx_rate_history[MAX_TX_RATE_VALUES];/*History of last ten transmit rate, in units of 500 kbit/sec*/ + A_UINT32 bcn_rssi_history[MAX_RSSI_VALUES];/*History of last ten Beacon rssi of the connected Bss*/ +} wmi_vdev_stats; + +/** + * peer statistics. + * + * @todo + * add more stats + * + */ +typedef struct { + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** rssi */ + A_UINT32 peer_rssi; + /** last tx data rate used for peer */ + A_UINT32 peer_tx_rate; + /** last rx data rate used for peer */ + A_UINT32 peer_rx_rate; +} wmi_peer_stats; + +typedef struct { + /** Primary channel freq of the channel for which stats are sent */ + A_UINT32 chan_mhz; + /** Time spent on the channel */ + A_UINT32 sampling_period_us; + /** Aggregate duration over a sampling period for which channel activity was observed */ + A_UINT32 rx_clear_count; + /** Accumalation of the TX PPDU duration over a sampling period */ + A_UINT32 tx_duration_us; + /** Accumalation of the RX PPDU duration over a sampling period */ + A_UINT32 rx_duration_us; +} wmi_chan_stats; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** VDEV type (AP,STA,IBSS,MONITOR) */ + A_UINT32 vdev_type; + /** VDEV subtype (P2PDEV, P2PCLI, P2PGO, BT3.0)*/ + A_UINT32 vdev_subtype; + /** VDEV MAC address */ + wmi_mac_addr vdev_macaddr; +} wmi_vdev_create_cmd_fixed_param; + +/* wmi_p2p_noa_descriptor structure can't be modified without breaking the compatibility for WMI_HOST_SWBA_EVENTID */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor */ + A_UINT32 type_count; /** 255: continuous schedule, 0: reserved */ + A_UINT32 duration ; /** Absent period duration in micro seconds */ + A_UINT32 interval; /** Absent period interval in micro seconds */ + A_UINT32 start_time; /** 32 bit tsf time when in starts */ +} wmi_p2p_noa_descriptor; + +/** values for vdev_type */ +#define WMI_VDEV_TYPE_AP 0x1 +#define WMI_VDEV_TYPE_STA 0x2 +#define WMI_VDEV_TYPE_IBSS 0x3 +#define WMI_VDEV_TYPE_MONITOR 0x4 + +/** VDEV type is for social wifi interface.This VDEV is Currently mainly needed +* by FW to execute the NAN specific WMI commands and also implement NAN specific +* operations like Network discovery, service provisioning and service +* subscription ..etc. If FW needs NAN VDEV then Host should issue VDEV create +* WMI command to create this VDEV once during initialization and host is not +* expected to use any VDEV specific WMI commands on this VDEV. +**/ +#define WMI_VDEV_TYPE_NAN 0x5 + +#define WMI_VDEV_TYPE_OCB 0x6 + +/** values for vdev_subtype */ +#define WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE 0x1 +#define WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT 0x2 +#define WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO 0x3 + +/** values for vdev_start_request flags */ +/** Indicates that AP VDEV uses hidden ssid. only valid for + * AP/GO */ +#define WMI_UNIFIED_VDEV_START_HIDDEN_SSID (1<<0) +/** Indicates if robust management frame/management frame + * protection is enabled. For GO/AP vdevs, it indicates that + * it may support station/client associations with RMF enabled. + * For STA/client vdevs, it indicates that sta will + * associate with AP with RMF enabled. */ +#define WMI_UNIFIED_VDEV_START_PMF_ENABLED (1<<1) + +/* + * Host is sending bcn_tx_rate to override the beacon tx rates. + */ +#define WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT (1<<2) + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** requestor id identifying the caller module */ + A_UINT32 requestor_id; + /** beacon interval from received beacon */ + A_UINT32 beacon_interval; + /** DTIM Period from the received beacon */ + A_UINT32 dtim_period; + /** Flags */ + A_UINT32 flags; + /** ssid field. Only valid for AP/GO/IBSS/BTAmp VDEV type. */ + wmi_ssid ssid; + /** beacon/probe reponse xmit rate. Applicable for SoftAP. */ + /** This field will be invalid and ignored unless the */ + /** flags field has the WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT bit. */ + /** When valid, this field contains the fixed tx rate for the beacon */ + /** and probe response frames send by the GO or SoftAP */ + A_UINT32 bcn_tx_rate; + /** beacon/probe reponse xmit power. Applicable for SoftAP. */ + A_UINT32 bcn_txPower; + /** number of p2p NOA descriptor(s) from scan entry */ + A_UINT32 num_noa_descriptors; + /** Disable H/W ack. This used by WMI_VDEV_RESTART_REQUEST_CMDID. + During CAC, Our HW shouldn't ack ditected frames */ + A_UINT32 disable_hw_ack; + /** This field will be invalid unless the Dual Band Simultaneous (DBS) feature is enabled. */ + /** The DBS policy manager indicates the preferred number of transmit streams. */ + A_UINT32 preferred_tx_streams; + /** This field will be invalid unless the Dual Band Simultaneous (DBS) feature is enabled. */ + /** the DBS policy manager indicates the preferred number of receive streams. */ + A_UINT32 preferred_rx_streams; + + /* The TLVs follows this structure: + * wmi_channel chan; //WMI channel + * wmi_p2p_noa_descriptor noa_descriptors[]; //actual p2p NOA descriptor from scan entry + */ +} wmi_vdev_start_request_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_delete_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_up_cmdid_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** aid (assoc id) received in association response for STA VDEV */ + A_UINT32 vdev_assoc_id; + /** bssid of the BSS the VDEV is joining */ + wmi_mac_addr vdev_bssid; +} wmi_vdev_up_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_stop_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_down_cmd_fixed_param; + +typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_standby_response_cmd; + +typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_resume_response_cmd; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** parameter id */ + A_UINT32 param_id; + /** parameter value */ + A_UINT32 param_value; +} wmi_vdev_set_param_cmd_fixed_param; + +typedef struct { + A_UINT32 key_seq_counter_l; + A_UINT32 key_seq_counter_h; +} wmi_key_seq_counter; + +#define WMI_CIPHER_NONE 0x0 /* clear key */ +#define WMI_CIPHER_WEP 0x1 +#define WMI_CIPHER_TKIP 0x2 +#define WMI_CIPHER_AES_OCB 0x3 +#define WMI_CIPHER_AES_CCM 0x4 +#define WMI_CIPHER_WAPI 0x5 +#define WMI_CIPHER_CKIP 0x6 +#define WMI_CIPHER_AES_CMAC 0x7 +#define WMI_CIPHER_ANY 0x8 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** MAC address used for installing */ + wmi_mac_addr peer_macaddr; + /** key index */ + A_UINT32 key_ix; + /** key flags */ + A_UINT32 key_flags; + /** key cipher, defined above */ + A_UINT32 key_cipher; + /** key rsc counter */ + wmi_key_seq_counter key_rsc_counter; + /** global key rsc counter */ + wmi_key_seq_counter key_global_rsc_counter; + /** global key tsc counter */ + wmi_key_seq_counter key_tsc_counter; + /** WAPI key rsc counter */ + A_UINT8 wpi_key_rsc_counter[16]; + /** WAPI key tsc counter */ + A_UINT8 wpi_key_tsc_counter[16]; + /** key length */ + A_UINT32 key_len; + /** key tx mic length */ + A_UINT32 key_txmic_len; + /** key rx mic length */ + A_UINT32 key_rxmic_len; + /* + * Following this struct are this TLV. + * // actual key data + * A_UINT8 key_data[]; // contains key followed by tx mic followed by rx mic + */ +} wmi_vdev_install_key_cmd_fixed_param; + +/** Preamble types to be used with VDEV fixed rate configuration */ +typedef enum { + WMI_RATE_PREAMBLE_OFDM, + WMI_RATE_PREAMBLE_CCK, + WMI_RATE_PREAMBLE_HT, + WMI_RATE_PREAMBLE_VHT, +} WMI_RATE_PREAMBLE; + +/** Value to disable fixed rate setting */ +#define WMI_FIXED_RATE_NONE (0xff) + +/** the definition of different VDEV parameters */ +typedef enum { + /** RTS Threshold */ + WMI_VDEV_PARAM_RTS_THRESHOLD = 0x1, + /** Fragmentation threshold */ + WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, + /** beacon interval in TUs */ + WMI_VDEV_PARAM_BEACON_INTERVAL, + /** Listen interval in TUs */ + WMI_VDEV_PARAM_LISTEN_INTERVAL, + /** muticast rate in Mbps */ + WMI_VDEV_PARAM_MULTICAST_RATE, + /** management frame rate in Mbps */ + WMI_VDEV_PARAM_MGMT_TX_RATE, + /** slot time (long vs short) */ + WMI_VDEV_PARAM_SLOT_TIME, + /** preamble (long vs short) */ + WMI_VDEV_PARAM_PREAMBLE, + /** SWBA time (time before tbtt in msec) */ + WMI_VDEV_PARAM_SWBA_TIME, + /** time period for updating VDEV stats */ + WMI_VDEV_STATS_UPDATE_PERIOD, + /** age out time in msec for frames queued for station in power save*/ + WMI_VDEV_PWRSAVE_AGEOUT_TIME, + /** Host SWBA interval (time in msec before tbtt for SWBA event generation) */ + WMI_VDEV_HOST_SWBA_INTERVAL, + /** DTIM period (specified in units of num beacon intervals) */ + WMI_VDEV_PARAM_DTIM_PERIOD, + /** scheduler air time limit for this VDEV. used by off chan scheduler */ + WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, + /** enable/dsiable WDS for this VDEV */ + WMI_VDEV_PARAM_WDS, + /** ATIM Window */ + WMI_VDEV_PARAM_ATIM_WINDOW, + /** BMISS max */ + WMI_VDEV_PARAM_BMISS_COUNT_MAX, + /** BMISS first time */ + WMI_VDEV_PARAM_BMISS_FIRST_BCNT, + /** BMISS final time */ + WMI_VDEV_PARAM_BMISS_FINAL_BCNT, + /** WMM enables/disabled */ + WMI_VDEV_PARAM_FEATURE_WMM, + /** Channel width */ + WMI_VDEV_PARAM_CHWIDTH, + /** Channel Offset */ + WMI_VDEV_PARAM_CHEXTOFFSET, + /** Disable HT Protection */ + WMI_VDEV_PARAM_DISABLE_HTPROTECTION, + /** Quick STA Kickout */ + WMI_VDEV_PARAM_STA_QUICKKICKOUT, + /** Rate to be used with Management frames */ + WMI_VDEV_PARAM_MGMT_RATE, + /** Protection Mode */ + WMI_VDEV_PARAM_PROTECTION_MODE, + /** Fixed rate setting */ + WMI_VDEV_PARAM_FIXED_RATE, + /** Short GI Enable/Disable */ + WMI_VDEV_PARAM_SGI, + /** Enable LDPC */ + WMI_VDEV_PARAM_LDPC, + /** Enable Tx STBC */ + WMI_VDEV_PARAM_TX_STBC, + /** Enable Rx STBC */ + WMI_VDEV_PARAM_RX_STBC, + /** Intra BSS forwarding */ + WMI_VDEV_PARAM_INTRA_BSS_FWD, + /** Setting Default xmit key for Vdev */ + WMI_VDEV_PARAM_DEF_KEYID, + /** NSS width */ + WMI_VDEV_PARAM_NSS, + /** Set the custom rate for the broadcast data frames */ + WMI_VDEV_PARAM_BCAST_DATA_RATE, + /** Set the custom rate (rate-code) for multicast data frames */ + WMI_VDEV_PARAM_MCAST_DATA_RATE, + /** Tx multicast packet indicate Enable/Disable */ + WMI_VDEV_PARAM_MCAST_INDICATE, + /** Tx DHCP packet indicate Enable/Disable */ + WMI_VDEV_PARAM_DHCP_INDICATE, + /** Enable host inspection of Tx unicast packet to unknown destination */ + WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, + + /* The minimum amount of time AP begins to consider STA inactive */ + WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, + + /* An associated STA is considered inactive when there is no recent TX/RX + * activity and no downlink frames are buffered for it. Once a STA exceeds + * the maximum idle inactive time, the AP will send an 802.11 data-null as + * a keep alive to verify the STA is still associated. If the STA does ACK + * the data-null, or if the data-null is buffered and the STA does not + * retrieve it, the STA will be considered unresponsive (see + * WMI_VDEV_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS). */ + WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, + + /* An associated STA is considered unresponsive if there is no recent + * TX/RX activity and downlink frames are buffered for it. Once a STA + * exceeds the maximum unresponsive time, the AP will send a + * WMI_STA_KICKOUT event to the host so the STA can be deleted. */ + WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, + + /* Enable NAWDS : MCAST INSPECT Enable, NAWDS Flag set */ + WMI_VDEV_PARAM_AP_ENABLE_NAWDS, + /** Enable/Disable RTS-CTS */ + WMI_VDEV_PARAM_ENABLE_RTSCTS, + /* Enable TXBFee/er */ + WMI_VDEV_PARAM_TXBF, + + /**Set packet power save */ + WMI_VDEV_PARAM_PACKET_POWERSAVE, + + /**Drops un-encrypted packets if any received in an encryted connection + * otherwise forwards to host + */ + WMI_VDEV_PARAM_DROP_UNENCRY, + + /* + * Set TX encap type. + * + * enum wmi_pkt_type is to be used as the parameter + * specifying the encap type. + */ + WMI_VDEV_PARAM_TX_ENCAP_TYPE, + + /* + * Try to detect stations that woke-up and exited power save but did not + * successfully transmit data-null with PM=0 to AP. When this happens, + * STA and AP power save state are out-of-sync. Use buffered but + * undelivered MSDU to the STA as a hint that the STA is really awake + * and expecting normal ASAP delivery, rather than retrieving BU with + * PS-Poll, U-APSD trigger, etc. + * + * 0 disables out-of-sync detection. Maximum time is 255 seconds. + */ + WMI_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, + + /* Enable/Disable early rx dynamic adjust feature. + * Early-rx dynamic adjust is a advance power save feature. + * Early-rx is a wakeup duration before exact TBTT,which is deemed necessary to provide a cushion for various + * timing discrepancies in the system. + * In current code branch, the duration is set to a very conservative fix value to make sure the drift impact is minimum. + * The fix early-tx will result in the unnessary power consume, so a dynamic early-rx adjust algorithm can be designed + * properly to minimum the power consume.*/ + WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, + + /* set target bmiss number per sample cycle if bmiss adjust was chosen. + * In this adjust policy,early-rx is adjusted by comparing the current bmiss rate to target bmiss rate + * which can be set by user through WMI command. + */ + WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, + + /* set sample cycle(in the unit of beacon interval) if bmiss adjust was chosen */ + WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, + + /* set slop_step */ + WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP, + + /* set init slop */ + WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP, + + /* pause adjust enable/disable */ + WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, + + + /* Set channel pwr limit value of the vdev the minimal value of all + * vdevs operating on this channel will be set as channel tx power + * limit, which is used to configure ratearray + */ + WMI_VDEV_PARAM_TX_PWRLIMIT, + + /* set the count of snr value for calculation in snr monitor */ + WMI_VDEV_PARAM_SNR_NUM_FOR_CAL, + + /** Roaming offload */ + WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, + + /** Enable Leader request RX functionality for RMC */ + WMI_VDEV_PARAM_ENABLE_RMC, + + /* IBSS does not have deauth/disassoc, vdev has to detect peer gone event + * by himself. If the beacon lost time exceed this threshold, the peer is + * thought to be gone. */ + WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, + + /** max rate in kpbs, transmit rate can't go beyond it */ + WMI_VDEV_PARAM_MAX_RATE, + + /* enable/disable drift sample. 0: disable; 1: clk_drift; 2: ap_drift; 3 both clk and ap drift*/ + WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, + /* set Tx failure count threshold for the vdev */ + WMI_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, + + /* set ebt resync timeout value, in the unit of TU */ + WMI_VDEV_PARAM_EBT_RESYNC_TIMEOUT, + + /* Enable Aggregation State Trigger Event */ + WMI_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, + + /* This parameter indicates whether IBSS station can enter into power save + * mode by sending Null frame (with PM=1). When not allowed, IBSS station has to stay + * awake all the time and should never set PM=1 in its transmitted frames. + * This parameter is meaningful/valid only when WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH + * is non-zero. */ + WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, + + /* This parameter indicates if this station can enter into power collapse + * for the remaining beacon interval after the ATIM window. + * This parameter is meaningful/valid only when WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED + * is set to TRUE. */ + WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, + + /* This parameter indicates whether IBSS station exit power save mode and + * enter power active state (by sending Null frame with PM=0 in the immediate ATIM Window) + * whenever there is a TX/RX activity. */ + WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, + + /* If Awake on TX/RX activity is enabled, this parameter indicates + * the data inactivity time in number of beacon intervals after which + * IBSS station reenters power save by sending Null frame with PM=1. */ + WMI_VDEV_PARAM_INACTIVITY_CNT, + + /* Inactivity time in msec after which TX Service Period (SP) is + * terminated by sending a Qos Null frame with EOSP. + * If value is 0, TX SP is terminated with the last buffered packet itself + * instead of waiting for the inactivity timeout. */ + WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, + + /** DTIM policy */ + WMI_VDEV_PARAM_DTIM_POLICY, + + /* When IBSS network is initialized, PS-supporting device + * does not enter protocol sleep state during first + * WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS seconds. */ + WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, + + /* Enable/Disable 1 RX chain usage during the ATIM window */ + WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, + + /* RX Leak window is the time driver waits before shutting down + * the radio or switching the channel and after receiving an ACK + * for a data frame with PM bit set) */ + WMI_VDEV_PARAM_RX_LEAK_WINDOW, + + /** Averaging factor(16 bit value) is used in the calculations to + * perform averaging of different link level statistics like average + * beacon spread or average number of frames leaked */ + WMI_VDEV_PARAM_STATS_AVG_FACTOR, + + /** disconnect threshold, once the consecutive error for specific peer + * exceed this threhold, FW will send kickout event to host */ + WMI_VDEV_PARAM_DISCONNECT_TH, + +} WMI_VDEV_PARAM; + +/* Length of ATIM Window in TU */ +#define WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH WMI_VDEV_PARAM_ATIM_WINDOW + +enum wmi_pkt_type { + WMI_PKT_TYPE_RAW = 0, + WMI_PKT_TYPE_NATIVE_WIFI = 1, + WMI_PKT_TYPE_ETHERNET = 2, +}; + +typedef struct { + A_UINT8 sutxbfee : 1, + mutxbfee : 1, + sutxbfer : 1, + mutxbfer : 1, +#if defined(AR900B) + txb_sts_cap : 3, + implicit_bf:1; +#else + reserved : 4; +#endif +} wmi_vdev_txbf_en; + +/** Upto 8 bits are available for Roaming module to be sent along with +WMI_VDEV_PARAM_ROAM_FW_OFFLOAD WMI_VDEV_PARAM **/ +/* Enable Roaming FW offload LFR1.5/LFR2.0 implementation */ +#define WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG 0x1 +/* Enable Roaming module in FW to do scan based on Final BMISS */ +#define WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG 0x2 + + /** slot time long */ + #define WMI_VDEV_SLOT_TIME_LONG 0x1 + /** slot time short */ + #define WMI_VDEV_SLOT_TIME_SHORT 0x2 + /** preablbe long */ + #define WMI_VDEV_PREAMBLE_LONG 0x1 + /** preablbe short */ + #define WMI_VDEV_PREAMBLE_SHORT 0x2 + +/** the definition of different START/RESTART Event response */ +typedef enum { + /* Event respose of START CMD */ + WMI_VDEV_START_RESP_EVENT = 0, + /* Event respose of RESTART CMD */ + WMI_VDEV_RESTART_RESP_EVENT, +} WMI_START_EVENT_PARAM; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_start_response_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** requestor id that requested the VDEV start request */ + A_UINT32 requestor_id; + /* Respose of Event type START/RESTART */ + WMI_START_EVENT_PARAM resp_type; + /** status of the response */ + A_UINT32 status; + /** Vdev chain mask */ + A_UINT32 chain_mask; + /** Vdev mimo power save mode */ + A_UINT32 smps_mode; + /** mac_id field contains the MAC identifier that the VDEV is bound to. The valid range is 0 to (num_macs-1). */ + A_UINT32 mac_id; + /** Configured Transmit Streams **/ + A_UINT32 cfgd_tx_streams; + /** Configured Receive Streams **/ + A_UINT32 cfgd_rx_streams; +} wmi_vdev_start_response_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_stopped_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_stopped_event_fixed_param; + +/** common structure used for simple events (stopped, resume_req, standby response) */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag would be equivalent to actual event */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_vdev_simple_event_fixed_param; + + +/** VDEV start response status codes */ +#define WMI_VDEV_START_RESPONSE_STATUS_SUCCESS 0x0 /** VDEV succesfully started */ +#define WMI_VDEV_START_RESPONSE_INVALID_VDEVID 0x1 /** requested VDEV not found */ +#define WMI_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 /** unsupported VDEV combination */ + +/** Beacon processing related command and event structures */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_bcn_tx_hdr */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** xmit rate */ + A_UINT32 tx_rate; + /** xmit power */ + A_UINT32 txPower; + /** beacon buffer length in bytes */ + A_UINT32 buf_len; + /* This TLV is followed by array of bytes: + * // beacon frame buffer + * A_UINT8 bufp[]; + */ +} wmi_bcn_tx_hdr; + +/* Beacon filter */ +#define WMI_BCN_FILTER_ALL 0 /* Filter all beacons */ +#define WMI_BCN_FILTER_NONE 1 /* Pass all beacons */ +#define WMI_BCN_FILTER_RSSI 2 /* Pass Beacons RSSI >= RSSI threshold */ +#define WMI_BCN_FILTER_BSSID 3 /* Pass Beacons with matching BSSID */ +#define WMI_BCN_FILTER_SSID 4 /* Pass Beacons with matching SSID */ + +typedef struct { + /** Filter ID */ + A_UINT32 bcn_filter_id; + /** Filter type - wmi_bcn_filter */ + A_UINT32 bcn_filter; + /** Buffer len */ + A_UINT32 bcn_filter_len; + /** Filter info (threshold, BSSID, RSSI) */ + A_UINT8 *bcn_filter_buf; +} wmi_bcn_filter_rx_cmd; + +/** Capabilities and IEs to be passed to firmware */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_bcn_prb_info */ + /** Capabilities */ + A_UINT32 caps; + /** ERP info */ + A_UINT32 erp; + /** Advanced capabilities */ + /** HT capabilities */ + /** HT Info */ + /** ibss_dfs */ + /** wpa Info */ + /** rsn Info */ + /** rrm info */ + /** ath_ext */ + /** app IE */ +} wmi_bcn_prb_info; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** TIM IE offset from the beginning of the template. */ + A_UINT32 tim_ie_offset; + /** beacon buffer length. data is in TLV data[] */ + A_UINT32 buf_len; + /* + * The TLVs follows: + * wmi_bcn_prb_info bcn_prb_info; //beacon probe capabilities and IEs + * A_UINT8 data[]; //Variable length data + */ +} wmi_bcn_tmpl_cmd_fixed_param; + + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** beacon buffer length. data is in TLV data[] */ + A_UINT32 buf_len; + /* + * The TLVs follows: + * wmi_bcn_prb_info bcn_prb_info; //beacon probe capabilities and IEs + * A_UINT8 data[]; //Variable length data + */ + } wmi_prb_tmpl_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_offload_bcn_tx_status_event_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** bcn tx status, values defined in enum WMI_FRAME_TX_STATUS */ + A_UINT32 tx_status; +} wmi_offload_bcn_tx_status_event_fixed_param; + + enum wmi_sta_ps_mode { + /** enable power save for the given STA VDEV */ + WMI_STA_PS_MODE_DISABLED = 0, + /** disable power save for a given STA VDEV */ + WMI_STA_PS_MODE_ENABLED = 1, + }; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + + /** Power save mode + * + * (see enum wmi_sta_ps_mode) + */ + A_UINT32 sta_ps_mode; + } wmi_sta_powersave_mode_cmd_fixed_param; + + enum wmi_csa_offload_en{ + WMI_CSA_OFFLOAD_DISABLE = 0, + WMI_CSA_OFFLOAD_ENABLE = 1, + }; + + typedef struct{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 csa_offload_enable; + } wmi_csa_offload_enable_cmd_fixed_param; + + typedef struct{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_csa_offload_chanswitch_cmd_fixed_param */ + A_UINT32 vdev_id; + /* + * The TLVs follows: + * wmi_channel chan; + */ + } wmi_csa_offload_chanswitch_cmd_fixed_param; + /** + * This parameter controls the policy for retrieving frames from AP while the + * STA is in sleep state. + * + * Only takes affect if the sta_ps_mode is enabled + */ + enum wmi_sta_ps_param_rx_wake_policy { + /* Wake up when ever there is an RX activity on the VDEV. In this mode + * the Power save SM(state machine) will come out of sleep by either + * sending null frame (or) a data frame (with PS==0) in response to TIM + * bit set in the received beacon frame from AP. + */ + WMI_STA_PS_RX_WAKE_POLICY_WAKE = 0, + + /* Here the power save state machine will not wakeup in response to TIM + * bit, instead it will send a PSPOLL (or) UASPD trigger based on UAPSD + * configuration setup by WMISET_PS_SET_UAPSD WMI command. When all + * access categories are delivery-enabled, the station will send a UAPSD + * trigger frame, otherwise it will send a PS-Poll. + */ + WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD = 1, + }; + + /** Number of tx frames/beacon that cause the power save SM to wake up. + * + * Value 1 causes the SM to wake up for every TX. Value 0 has a special + * meaning, It will cause the SM to never wake up. This is useful if you want + * to keep the system to sleep all the time for some kind of test mode . host + * can change this parameter any time. It will affect at the next tx frame. + */ + enum wmi_sta_ps_param_tx_wake_threshold { + WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER = 0, + WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS = 1, + + /* Values greater than one indicate that many TX attempts per beacon + * interval before the STA will wake up + */ + }; + + /** + * The maximum number of PS-Poll frames the FW will send in response to + * traffic advertised in TIM before waking up (by sending a null frame with PS + * = 0). Value 0 has a special meaning: there is no maximum count and the FW + * will send as many PS-Poll as are necessary to retrieve buffered BU. This + * parameter is used when the RX wake policy is + * WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD and ignored when the RX wake + * policy is WMI_STA_PS_RX_WAKE_POLICY_WAKE. + */ + enum wmi_sta_ps_param_pspoll_count { + WMI_STA_PS_PSPOLL_COUNT_NO_MAX = 0, + /* Values greater than 0 indicate the maximum numer of PS-Poll frames FW + * will send before waking up. + */ + }; + + /* + * This will include the delivery and trigger enabled state for every AC. + * This is the negotiated state with AP. The host MLME needs to set this based + * on AP capability and the state Set in the association request by the + * station MLME.Lower 8 bits of the value specify the UAPSD configuration. + */ + #define WMI_UAPSD_AC_TYPE_DELI 0 + #define WMI_UAPSD_AC_TYPE_TRIG 1 + + #define WMI_UAPSD_AC_BIT_MASK(ac,type) (type == WMI_UAPSD_AC_TYPE_DELI)?(1<<(ac<<1)):(1<<((ac<<1)+1)) + + enum wmi_sta_ps_param_uapsd { + WMI_STA_PS_UAPSD_AC0_DELIVERY_EN = (1 << 0), + WMI_STA_PS_UAPSD_AC0_TRIGGER_EN = (1 << 1), + WMI_STA_PS_UAPSD_AC1_DELIVERY_EN = (1 << 2), + WMI_STA_PS_UAPSD_AC1_TRIGGER_EN = (1 << 3), + WMI_STA_PS_UAPSD_AC2_DELIVERY_EN = (1 << 4), + WMI_STA_PS_UAPSD_AC2_TRIGGER_EN = (1 << 5), + WMI_STA_PS_UAPSD_AC3_DELIVERY_EN = (1 << 6), + WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7), + }; + + enum wmi_sta_powersave_param { + /** + * Controls how frames are retrievd from AP while STA is sleeping + * + * (see enum wmi_sta_ps_param_rx_wake_policy) + */ + WMI_STA_PS_PARAM_RX_WAKE_POLICY = 0, + + /** + * The STA will go active after this many TX + * + * (see enum wmi_sta_ps_param_tx_wake_threshold) + */ + WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD = 1, + + /** + * Number of PS-Poll to send before STA wakes up + * + * (see enum wmi_sta_ps_param_pspoll_count) + * + */ + WMI_STA_PS_PARAM_PSPOLL_COUNT = 2, + + /** + * TX/RX inactivity time in msec before going to sleep. + * + * The power save SM will monitor tx/rx activity on the VDEV, if no + * activity for the specified msec of the parameter the Power save SM will + * go to sleep. + */ + WMI_STA_PS_PARAM_INACTIVITY_TIME = 3, + + /** + * Set uapsd configuration. + * + * (see enum wmi_sta_ps_param_uapsd) + */ + WMI_STA_PS_PARAM_UAPSD = 4, + /** + * Number of PS-Poll to send before STA wakes up in QPower Mode + */ + WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT = 5, + + /** + * Enable QPower + */ + WMI_STA_PS_ENABLE_QPOWER = 6, + + /** + * Number of TX frames before the entering the Active state + */ + WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE = 7, + + /** + * QPower SPEC PSPOLL interval + */ + WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL = 8, + + /** + * Max SPEC PSPOLL to be sent when the PSPOLL response has + * no-data bit set + */ + WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL = 9, + }; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** station power save parameter (see enum wmi_sta_powersave_param) */ + A_UINT32 param; + A_UINT32 value; + } wmi_sta_powersave_param_cmd_fixed_param; + + /** No MIMO power save */ + #define WMI_STA_MIMO_PS_MODE_DISABLE + /** mimo powersave mode static*/ + #define WMI_STA_MIMO_PS_MODE_STATIC + /** mimo powersave mode dynamic */ + #define WMI_STA_MIMO_PS_MODE_DYNAMI + + typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** mimo powersave mode as defined above */ + A_UINT32 mimo_pwrsave_mode; + } wmi_sta_mimo_ps_mode_cmd; + + + /** U-APSD configuration of peer station from (re)assoc request and TSPECs */ + enum wmi_ap_ps_param_uapsd { + WMI_AP_PS_UAPSD_AC0_DELIVERY_EN = (1 << 0), + WMI_AP_PS_UAPSD_AC0_TRIGGER_EN = (1 << 1), + WMI_AP_PS_UAPSD_AC1_DELIVERY_EN = (1 << 2), + WMI_AP_PS_UAPSD_AC1_TRIGGER_EN = (1 << 3), + WMI_AP_PS_UAPSD_AC2_DELIVERY_EN = (1 << 4), + WMI_AP_PS_UAPSD_AC2_TRIGGER_EN = (1 << 5), + WMI_AP_PS_UAPSD_AC3_DELIVERY_EN = (1 << 6), + WMI_AP_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7), + }; + + /** U-APSD maximum service period of peer station */ + enum wmi_ap_ps_peer_param_max_sp { + WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED = 0, + WMI_AP_PS_PEER_PARAM_MAX_SP_2 = 1, + WMI_AP_PS_PEER_PARAM_MAX_SP_4 = 2, + WMI_AP_PS_PEER_PARAM_MAX_SP_6 = 3, + + /* keep last! */ + MAX_WMI_AP_PS_PEER_PARAM_MAX_SP, + }; + + /** + * AP power save parameter + * Set a power save specific parameter for a peer station + */ + enum wmi_ap_ps_peer_param { + /** Set uapsd configuration for a given peer. + * + * This will include the delivery and trigger enabled state for every AC. + * The host MLME needs to set this based on AP capability and stations + * request Set in the association request received from the station. + * + * Lower 8 bits of the value specify the UAPSD configuration. + * + * (see enum wmi_ap_ps_param_uapsd) + * The default value is 0. + */ + WMI_AP_PS_PEER_PARAM_UAPSD = 0, + + /** + * Set the service period for a UAPSD capable station + * + * The service period from wme ie in the (re)assoc request frame. + * + * (see enum wmi_ap_ps_peer_param_max_sp) + */ + WMI_AP_PS_PEER_PARAM_MAX_SP = 1, + + /** Time in seconds for aging out buffered frames for STA in power save */ + WMI_AP_PS_PEER_PARAM_AGEOUT_TIME = 2, + }; + + typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** AP powersave param (see enum wmi_ap_ps_peer_param) */ + A_UINT32 param; + /** AP powersave param value */ + A_UINT32 value; + } wmi_ap_ps_peer_cmd_fixed_param; + + /** Configure peer station 11v U-APSD coexistance + * + * Two parameters from uaspd coexistence ie info (as specified in 11v) are + * sent down to FW along with this command. + * + * The semantics of these fields are described in the following text extracted + * from 802.11v. + * + * --- If the non-AP STA specified a non-zero TSF 0 Offset value in the + * U-APSD Coexistence element, the AP should not transmit frames to the + * non-AP STA outside of the U-APSD Coexistence Service Period, which + * begins when the AP receives the U-APSD trigger frame and ends after + * the transmission period specified by the result of the following + * calculation: + * + * End of transmission period = T + (Interval . ((T . TSF 0 Offset) mod Interval)) + * + * Where T is the time the U-APSD trigger frame was received at the AP + * Interval is the UAPSD Coexistence element Duration/Interval field + * value (see 7.3.2.91) or upon the successful transmission of a frame + * with EOSP bit set to 1, whichever is earlier. + * + * + * --- If the non-AP STA specified a zero TSF 0 Offset value in the U-APSD + * Coexistence element, the AP should not transmit frames to the non-AP + * STA outside of the U-APSD Coexistence Service Period, which begins + * when the AP receives a U-APSD trigger frame and ends after the + * transmission period specified by the result of the following + * calculation: End of transmission period = T + Duration + */ + typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Enable U-APSD coexistence support for this peer + * + * 0 -> disabled (default) + * 1 -> enabled + */ + A_UINT32 enabled; + /** Duration/Interval as defined by 11v U-ASPD coexistance */ + A_UINT32 duration_interval; + /** Upper 32 bits of 64-bit TSF offset */ + A_UINT32 tsf_offset_high; + /** Lower 32 bits of 64-bit TSF offset */ + A_UINT32 tsf_offset_low; + } wmi_ap_powersave_peer_uapsd_coex_cmd; + + /* 128 clients = 4 words */ + /* WMI_TIM_BITMAP_ARRAY_SIZE can't be modified without breaking the compatibility */ + #define WMI_TIM_BITMAP_ARRAY_SIZE 4 + + typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tim_info */ + /** TIM bitmap len (in bytes)*/ + A_UINT32 tim_len; + /** TIM Partial Virtual Bitmap */ + A_UINT32 tim_mcast; + A_UINT32 tim_bitmap[WMI_TIM_BITMAP_ARRAY_SIZE]; + A_UINT32 tim_changed; + A_UINT32 tim_num_ps_pending; + } wmi_tim_info; + + typedef struct { + /** Flag to enable quiet period IE support */ + A_UINT32 is_enabled; + /** Quiet start */ + A_UINT32 tbttcount; + /** Beacon intervals between quiets*/ + A_UINT32 period; + /** TUs of each quiet*/ + A_UINT32 duration; + /** TUs of from TBTT of quiet start*/ + A_UINT32 offset; + } wmi_quiet_info; + +/* WMI_P2P_MAX_NOA_DESCRIPTORS can't be modified without breaking the compatibility */ +#define WMI_P2P_MAX_NOA_DESCRIPTORS 4 /* Maximum number of NOA Descriptors supported */ + + typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_noa_info */ + /** Bit 0: Flag to indicate an update in NOA schedule + * Bits 7-1: Reserved + * Bits 15-8: Index (identifies the instance of NOA sub element) + * Bit 16: Opp PS state of the AP + * Bits 23-17: Ctwindow in TUs + * Bits 31-24: Number of NOA descriptors + */ + A_UINT32 noa_attributes; + wmi_p2p_noa_descriptor noa_descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS]; + }wmi_p2p_noa_info; + +#define WMI_UNIFIED_NOA_ATTR_MODIFIED 0x1 +#define WMI_UNIFIED_NOA_ATTR_MODIFIED_S 0 + +#define WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(hdr) \ + WMI_F_MS((hdr)->noa_attributes, WMI_UNIFIED_NOA_ATTR_MODIFIED) + +#define WMI_UNIFIED_NOA_ATTR_MODIFIED_SET(hdr) \ + WMI_F_RMW((hdr)->noa_attributes, 0x1, \ + WMI_UNIFIED_NOA_ATTR_MODIFIED); + +#define WMI_UNIFIED_NOA_ATTR_INDEX 0xff00 +#define WMI_UNIFIED_NOA_ATTR_INDEX_S 8 + +#define WMI_UNIFIED_NOA_ATTR_INDEX_GET(hdr) \ + WMI_F_MS((hdr)->noa_attributes, WMI_UNIFIED_NOA_ATTR_INDEX) + +#define WMI_UNIFIED_NOA_ATTR_INDEX_SET(hdr, v) \ + WMI_F_RMW((hdr)->noa_attributes, (v) & 0xff, \ + WMI_UNIFIED_NOA_ATTR_INDEX); + +#define WMI_UNIFIED_NOA_ATTR_OPP_PS 0x10000 +#define WMI_UNIFIED_NOA_ATTR_OPP_PS_S 16 + +#define WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(hdr) \ + WMI_F_MS((hdr)->noa_attributes, WMI_UNIFIED_NOA_ATTR_OPP_PS) + +#define WMI_UNIFIED_NOA_ATTR_OPP_PS_SET(hdr) \ + WMI_F_RMW((hdr)->noa_attributes, 0x1, \ + WMI_UNIFIED_NOA_ATTR_OPP_PS); + +#define WMI_UNIFIED_NOA_ATTR_CTWIN 0xfe0000 +#define WMI_UNIFIED_NOA_ATTR_CTWIN_S 17 + +#define WMI_UNIFIED_NOA_ATTR_CTWIN_GET(hdr) \ + WMI_F_MS((hdr)->noa_attributes, WMI_UNIFIED_NOA_ATTR_CTWIN) + +#define WMI_UNIFIED_NOA_ATTR_CTWIN_SET(hdr, v) \ + WMI_F_RMW((hdr)->noa_attributes, (v) & 0x7f, \ + WMI_UNIFIED_NOA_ATTR_CTWIN); + +#define WMI_UNIFIED_NOA_ATTR_NUM_DESC 0xff000000 +#define WMI_UNIFIED_NOA_ATTR_NUM_DESC_S 24 + +#define WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(hdr) \ + WMI_F_MS((hdr)->noa_attributes, WMI_UNIFIED_NOA_ATTR_NUM_DESC) + +#define WMI_UNIFIED_NOA_ATTR_NUM_DESC_SET(hdr, v) \ + WMI_F_RMW((hdr)->noa_attributes, (v) & 0xff, \ + WMI_UNIFIED_NOA_ATTR_NUM_DESC); + + typedef struct { + /** TIM info */ + wmi_tim_info tim_info; + /** P2P NOA info */ + wmi_p2p_noa_info p2p_noa_info; + /* TBD: More info elements to be added later */ + } wmi_bcn_info; + + typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_host_swba_event_fixed_param */ + /** bitmap identifying the VDEVs, generated by the caller */ + A_UINT32 vdev_map; + /* This TLV is followed by tim_info and p2p_noa_info for each vdev in vdevmap : + * wmi_tim_info tim_info[]; + * wmi_p2p_noa_info p2p_noa_info[]; + * + */ + } wmi_host_swba_event_fixed_param; + + #define WMI_MAX_AP_VDEV 16 + + + typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tbtt_offset_event_fixed_param */ + /** bimtap of VDEVs that has tbtt offset updated */ + A_UINT32 vdev_map; + /* The TLVs for tbttoffset_list will follow this TLV. + * tbtt offset list in the order of the LSB to MSB in the vdev_map bitmap + * A_UINT32 tbttoffset_list[WMI_MAX_AP_VDEV]; + */ + } wmi_tbtt_offset_event_fixed_param; + + + /* Peer Specific commands and events */ + +typedef struct { + A_UINT32 percentage; /* in unit of 12.5% */ + A_UINT32 min_delta; /* in unit of Mbps */ +} rate_delta_t; + +#define PEER_RATE_REPORT_COND_FLAG_DELTA 0x01 +#define PEER_RATE_REPORT_COND_FLAG_THRESHOLD 0x02 +#define MAX_NUM_OF_RATE_THRESH 4 + +typedef struct { + A_UINT32 val_cond_flags; /* PEER_RATE_REPORT_COND_FLAG_DELTA, PEER_RATE_REPORT_COND_FLAG_THRESHOLD + Any of these two conditions or both of them can be set. */ + rate_delta_t rate_delta; + A_UINT32 rate_threshold[MAX_NUM_OF_RATE_THRESH]; /* In unit of Mbps. There are at most 4 thresholds. + If the threshold count is less than 4, set zero to + the one following the last threshold */ +} report_cond_per_phy_t; + + +enum peer_rate_report_cond_phy_type { + PEER_RATE_REPORT_COND_11B = 0, + PEER_RATE_REPORT_COND_11A_G, + PEER_RATE_REPORT_COND_11N, + PEER_RATE_REPORT_COND_11AC, + PEER_RATE_REPORT_COND_MAX_NUM +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_rate_report_condtion_fixed_param */ + A_UINT32 enable_rate_report; /* 1= enable, 0=disable */ + A_UINT32 report_backoff_time; /* in unit of msecond */ + A_UINT32 report_timer_period; /* in unit of msecond */ + /* In the following field, the array index means the phy type, + * please see enum peer_rate_report_cond_phy_type for detail */ + report_cond_per_phy_t cond_per_phy[PEER_RATE_REPORT_COND_MAX_NUM]; +} wmi_peer_set_rate_report_condition_fixed_param; + + /* Peer Type: + * NB: This can be left DEFAULT for the normal case, and f/w will determine BSS type based + * on address and vdev opmode. This is largely here to allow host to indicate that + * peer is explicitly a TDLS peer + */ + enum wmi_peer_type { + WMI_PEER_TYPE_DEFAULT = 0, /* Generic/Non-BSS/Self Peer */ + WMI_PEER_TYPE_BSS = 1, /* Peer is BSS Peer entry */ + WMI_PEER_TYPE_TDLS = 2, /* Peer is a TDLS Peer */ + WMI_PEER_TYPE_OCB = 3, /* Peer is a OCB Peer */ + WMI_PEER_TYPE_HOST_MAX = 127, /* Host <-> Target Peer type + * is assigned up to 127 */ + /* Reserved from 128 - 255 for + * target internal use.*/ + WMI_PEER_TYPE_ROAMOFFLOAD_TEMP = 128, /* Temporarily created during offload roam */ + }; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** peer type: see enum values above */ + A_UINT32 peer_type; + } wmi_peer_create_cmd_fixed_param; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + } wmi_peer_delete_cmd_fixed_param; + + typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** tid bitmap identifying the tids to flush */ + A_UINT32 peer_tid_bitmap; + } wmi_peer_flush_tids_cmd_fixed_param; + + typedef struct { + /** rate mode . 0: disable fixed rate (auto rate) + * 1: legacy (non 11n) rate specified as ieee rate 2*Mbps + * 2: ht20 11n rate specified as mcs index + * 3: ht40 11n rate specified as mcs index + */ + A_UINT32 rate_mode; + /** 4 rate values for 4 rate series. series 0 is stored in byte 0 (LSB) + * and series 3 is stored at byte 3 (MSB) */ + A_UINT32 rate_series; + /** 4 retry counts for 4 rate series. retry count for rate 0 is stored in byte 0 (LSB) + * and retry count for rate 3 is stored at byte 3 (MSB) */ + A_UINT32 rate_retries; + } wmi_fixed_rate; + + typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** fixed rate */ + wmi_fixed_rate peer_fixed_rate; + } wmi_peer_fixed_rate_cmd; + + #define WMI_MGMT_TID 17 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_addba_clear_resp_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; +} wmi_addba_clear_resp_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_addba_send_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Buffer/Window size*/ + A_UINT32 buffersize; +} wmi_addba_send_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_delba_send_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Is Initiator */ + A_UINT32 initiator; + /** Reason code */ + A_UINT32 reasoncode; +} wmi_delba_send_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_addba_setresponse_cmd_fixed_param */ + /** unique id identifying the vdev, generated by the caller */ + A_UINT32 vdev_id; + /** peer mac address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** status code */ + A_UINT32 statuscode; +} wmi_addba_setresponse_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_send_singleamsdu_cmd_fixed_param */ + /** unique id identifying the vdev, generated by the caller */ + A_UINT32 vdev_id; + /** peer mac address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; +} wmi_send_singleamsdu_cmd_fixed_param; + +/* Type of Station DTIM Power Save method */ +enum { + /* For NORMAL DTIM, the parameter is the number of beacon intervals and + * also the same value as the listen interval. For this method, the + * station will wake up based on the listen interval. If this + * listen interval is not equal to DTIM, then the station may + * miss certain DTIM beacons. If this value is 1, then the + * station will wake up for every beacon. + */ + WMI_STA_DTIM_PS_NORMAL_DTIM = 0x01, + /* For MODULATED_DTIM, parameter is a multiple of DTIM beacons to skip. + * When this value is 1, then the station will wake at every DTIM beacon. + * If this value is >1, then the station will skip certain DTIM beacons. + * This value is the multiple of DTIM intervals that the station will + * wake up to receive the DTIM beacons. + */ + WMI_STA_DTIM_PS_MODULATED_DTIM = 0x02, +}; + +/* Parameter structure for the WMI_STA_DTIM_PS_METHOD_CMDID */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sta_dtim_ps_method_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** Station DTIM Power Save method as defined above */ + A_UINT32 dtim_pwrsave_method; + /** DTIM PS value. Contents depends on the method */ + A_UINT32 value; + /** Modulated DTIM value */ + A_UINT32 MaxLIModulatedDTIM; +} wmi_sta_dtim_ps_method_cmd_fixed_param; + + /* + * For Station UAPSD Auto Trigger feature, the Firmware monitors the + * uAPSD uplink and downlink traffic for each uAPSD enabled WMM ACs. + * If there is no uplink/download for the specified service interval (field service_interval), + * firmware will auto generate a QOS-NULL trigger for that WMM-AP with the TID value + * specified in the UP (field user_priority). + * Firmware also monitors the responses for these QOS-NULL triggers. + * If the peer does not have any delivery frames, it will respond with + * QOS-NULL (EOSP=1). This feature of only using service interval is assumed to be mandatory for all + * firmware implementation. For this basic implementation, the suspend_interval and delay_interval + * are unused and should be set to 0. + * When service_interval is 0, then the firmware will not send any trigger frames. This is for + * certain host-based implementations that don't want this firmware offload. + * Note that the per-AC intervals are required for some usage scenarios. This is why the intervals + * are given in the array of ac_param[]. For example, Voice service interval may defaults to 20 ms + * and rest of the AC default to 300 ms. + * + * The service bit, WMI_STA_UAPSD_VAR_AUTO_TRIG, will indicate that the more advanced feature + * of variable auto trigger is supported. The suspend_interval and delay_interval is used in + * the more advanced monitoring method. + * If the PEER does not have any delivery enabled data frames (non QOS-NULL) for the + * suspend interval (field suspend_interval), firmware will change its auto trigger interval + * to delay interval (field delay_interval). This way, when there is no traffic, the station + * will save more power by waking up less and sending less trigger frames. + * The (service_interval < suspend_interval) and (service_interval < delay_interval). + * If this variable auto trigger is not required, then the suspend_interval and delay_interval + * should be 0. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param */ + /** WMM Access category from 0 to 3 */ + A_UINT32 wmm_ac; + /** User priority to use in trigger frames. It is the TID + * value. This field needs to be specified and may not be + * equivalent to AC since some implementation may use the TSPEC + * to enable UAPSD and negotiate a particular user priority. */ + A_UINT32 user_priority; + /** service interval in ms */ + A_UINT32 service_interval; + /** Suspend interval in ms */ + A_UINT32 suspend_interval; + /** delay interval in ms */ + A_UINT32 delay_interval; +} wmi_sta_uapsd_auto_trig_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer mac address */ + wmi_mac_addr peer_macaddr; + /** Number of AC to specify */ + A_UINT32 num_ac; + /* + * Following this struc is the TLV: + * wmi_sta_uapsd_auto_trig_param ac_param[]; //Variable number of AC parameters (defined by field num_ac) + */ + +} wmi_sta_uapsd_auto_trig_cmd_fixed_param; + +/** mimo powersave state */ +#define WMI_PEER_MIMO_PS_STATE 0x1 +/** enable/disable AMPDU . initial value (enabled) */ +#define WMI_PEER_AMPDU 0x2 +/** authorize/unauthorize peer. initial value is unauthorized (0) */ +#define WMI_PEER_AUTHORIZE 0x3 +/** peer channel bandwidth */ +#define WMI_PEER_CHWIDTH 0x4 +/** peer NSS */ +#define WMI_PEER_NSS 0x5 +/** USE 4 ADDR */ +#define WMI_PEER_USE_4ADDR 0x6 +/* set group membership status */ +#define WMI_PEER_MEMBERSHIP 0x7 +#define WMI_PEER_USERPOS 0x8 +/* + * A critical high-level protocol is being used with this peer. Target + * should take appropriate measures (if possible) to ensure more + * reliable link with minimal latency. This *may* include modifying the + * station power save policy, enabling more RX chains, increased + * priority of channel scheduling, etc. + * + * NOTE: This parameter should only be considered a hint as specific + * behavior will depend on many factors including current network load + * and vdev/peer configuration. + * + * For STA VDEV this peer corresponds to the AP's BSS peer. + * For AP VDEV this peer corresponds to the remote peer STA. + */ +#define WMI_PEER_CRIT_PROTO_HINT_ENABLED 0x9 +/* set Tx failure count threshold for the peer - Currently unused */ +#define WMI_PEER_TX_FAIL_CNT_THR 0xA +/* Enable H/W retry and Enable H/W Send CTS2S before Data */ +#define WMI_PEER_SET_HW_RETRY_CTS2S 0xB + +/* Set peer advertised IBSS atim window length */ +#define WMI_PEER_IBSS_ATIM_WINDOW_LENGTH 0xC + +/** peer phy mode */ +#define WMI_PEER_PHYMODE 0xD + +/** mimo ps values for the parameter WMI_PEER_MIMO_PS_STATE */ +#define WMI_PEER_MIMO_PS_NONE 0x0 +#define WMI_PEER_MIMO_PS_STATIC 0x1 +#define WMI_PEER_MIMO_PS_DYNAMIC 0x2 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** parameter id */ + A_UINT32 param_id; + /** parametr value */ + A_UINT32 param_value; +} wmi_peer_set_param_cmd_fixed_param; + +#define MAX_SUPPORTED_RATES 128 + +typedef struct { + /** total number of rates */ + A_UINT32 num_rates; + /** + * rates (each 8bit value) packed into a 32 bit word. + * the rates are filled from least significant byte to most + * significant byte. + */ + A_UINT32 rates[(MAX_SUPPORTED_RATES/4)+1]; +} wmi_rate_set; + +/* NOTE: It would bea good idea to represent the Tx MCS + * info in one word and Rx in another word. This is split + * into multiple words for convenience + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vht_rate_set */ + A_UINT32 rx_max_rate; /* Max Rx data rate */ + A_UINT32 rx_mcs_set; /* Negotiated RX VHT rates */ + A_UINT32 tx_max_rate; /* Max Tx data rate */ + A_UINT32 tx_mcs_set; /* Negotiated TX VHT rates */ +}wmi_vht_rate_set; + +/* + * IMPORTANT: Make sure the bit definitions here are consistent + * with the ni_flags definitions in wlan_peer.h + */ +#define WMI_PEER_AUTH 0x00000001 /* Authorized for data */ +#define WMI_PEER_QOS 0x00000002 /* QoS enabled */ +#define WMI_PEER_NEED_PTK_4_WAY 0x00000004 /* Needs PTK 4 way handshake for authorization */ +#define WMI_PEER_NEED_GTK_2_WAY 0x00000010 /* Needs GTK 2 way handshake after 4-way handshake */ +#define WMI_PEER_APSD 0x00000800 /* U-APSD power save enabled */ +#define WMI_PEER_HT 0x00001000 /* HT enabled */ +#define WMI_PEER_40MHZ 0x00002000 /* 40MHz enabld */ +#define WMI_PEER_STBC 0x00008000 /* STBC Enabled */ +#define WMI_PEER_LDPC 0x00010000 /* LDPC ENabled */ +#define WMI_PEER_DYN_MIMOPS 0x00020000 /* Dynamic MIMO PS Enabled */ +#define WMI_PEER_STATIC_MIMOPS 0x00040000 /* Static MIMO PS enabled */ +#define WMI_PEER_SPATIAL_MUX 0x00200000 /* SM Enabled */ +#define WMI_PEER_VHT 0x02000000 /* VHT Enabled */ +#define WMI_PEER_80MHZ 0x04000000 /* 80MHz enabld */ +#define WMI_PEER_PMF 0x08000000 /* Robust Management Frame Protection enabled */ +/** CAUTION TODO: Place holder for WLAN_PEER_F_PS_PRESEND_REQUIRED = 0x10000000. Need to be clean up */ +#define WMI_PEER_IS_P2P_CAPABLE 0x20000000 /* P2P capable peer */ +#define WMI_PEER_160MHZ 0x40000000 /* 160 MHz enabled */ +#define WMI_PEER_SAFEMODE_EN 0x80000000 /* Fips Mode Enabled */ + +/** + * Peer rate capabilities. + * + * This is of interest to the ratecontrol + * module which resides in the firmware. The bit definitions are + * consistent with that defined in if_athrate.c. + * + * @todo + * Move this to a common header file later so there is no need to + * duplicate the definitions or maintain consistency. + */ +#define WMI_RC_DS_FLAG 0x01 /* Dual stream flag */ +#define WMI_RC_CW40_FLAG 0x02 /* CW 40 */ +#define WMI_RC_SGI_FLAG 0x04 /* Short Guard Interval */ +#define WMI_RC_HT_FLAG 0x08 /* HT */ +#define WMI_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */ +#define WMI_RC_TX_STBC_FLAG 0x20 /* TX STBC */ +#define WMI_RC_TX_STBC_FLAG_S 5 /* TX STBC */ +#define WMI_RC_RX_STBC_FLAG 0xC0 /* RX STBC ,2 bits */ +#define WMI_RC_RX_STBC_FLAG_S 6 /* RX STBC ,2 bits */ +#define WMI_RC_WEP_TKIP_FLAG 0x100 /* WEP/TKIP encryption */ +#define WMI_RC_TS_FLAG 0x200 /* Three stream flag */ +#define WMI_RC_UAPSD_FLAG 0x400 /* UAPSD Rate Control */ + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param */ + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** VDEV id */ + A_UINT32 vdev_id; + /** assoc = 1 reassoc = 0 */ + A_UINT32 peer_new_assoc; + /** peer associd (16 bits) */ + A_UINT32 peer_associd; + /** peer station flags: see definition above */ + A_UINT32 peer_flags; + /** negotiated capabilities (lower 16 bits)*/ + A_UINT32 peer_caps; + /** Listen interval */ + A_UINT32 peer_listen_intval; + /** HT capabilties of the peer */ + A_UINT32 peer_ht_caps; + /** maximum rx A-MPDU length */ + A_UINT32 peer_max_mpdu; + /** mpdu density of the peer in usec(0 to 16) */ + A_UINT32 peer_mpdu_density; + /** peer rate capabilties see flags above */ + A_UINT32 peer_rate_caps; + /** num spatial streams */ + A_UINT32 peer_nss; + /** VHT capabilties of the peer */ + A_UINT32 peer_vht_caps; + /** phy mode */ + A_UINT32 peer_phymode; + /** HT Operation Element of the peer. Five bytes packed in 2 + * INT32 array and filled from lsb to msb. + * Note that the size of array peer_ht_info[] cannotbe changed + * without breaking WMI Compatibility. */ + A_UINT32 peer_ht_info[2]; + /** total number of negotiated legacy rate set. Also the sizeof + * peer_legacy_rates[] */ + A_UINT32 num_peer_legacy_rates; + /** total number of negotiated ht rate set. Also the sizeof + * peer_ht_rates[] */ + A_UINT32 num_peer_ht_rates; + /* Following this struc are the TLV's: + * A_UINT8 peer_legacy_rates[]; + * A_UINT8 peer_ht_rates[]; + * wmi_vht_rate_set peer_vht_rates; //VHT capabilties of the peer + */ +} wmi_peer_assoc_complete_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param */ + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** wds MAC addr */ + wmi_mac_addr wds_macaddr; +} wmi_peer_add_wds_entry_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param */ + /** wds MAC addr */ + wmi_mac_addr wds_macaddr; +} wmi_peer_remove_wds_entry_cmd_fixed_param; + + +typedef struct { + /** peer MAC address */ + wmi_mac_addr peer_macaddr; +} wmi_peer_q_empty_callback_event; + + + +/** + * Channel info WMI event + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chan_info_event_fixed_param */ + /** Error code */ + A_UINT32 err_code; + /** Channel freq */ + A_UINT32 freq; + /** Read flags */ + A_UINT32 cmd_flags; + /** Noise Floor value */ + A_UINT32 noise_floor; + /** rx clear count */ + A_UINT32 rx_clear_count; + /** cycle count */ + A_UINT32 cycle_count; +} wmi_chan_info_event_fixed_param; + +/** + * Non wlan interference event + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_ath_dcs_cw_int */ + A_UINT32 channel; /* either number or freq in mhz*/ +} ath_dcs_cw_int; + +/** + * wlan_dcs_im_tgt_stats + * + */ +typedef struct _wlan_dcs_im_tgt_stats { + /** current running TSF from the TSF-1 */ + A_UINT32 reg_tsf32; + + /** Known last frame rssi, in case of multiple stations, if + * and at different ranges, this would not gaurantee that + * this is the least rssi. + */ + A_UINT32 last_ack_rssi; + + /** Sum of all the failed durations in the last one second interval. + */ + A_UINT32 tx_waste_time; + /** count how many times the hal_rxerr_phy is marked, in this + * time period + */ + A_UINT32 rx_time; + A_UINT32 phyerr_cnt; + + /** + * WLAN IM stats from target to host + * + * Below statistics are sent from target to host periodically. + * These are collected at target as long as target is running + * and target chip is not in sleep. + * + */ + + /** listen time from ANI */ + A_INT32 listen_time; + + /** tx frame count, MAC_PCU_TX_FRAME_CNT_ADDRESS */ + A_UINT32 reg_tx_frame_cnt; + + /** rx frame count, MAC_PCU_RX_FRAME_CNT_ADDRESS */ + A_UINT32 reg_rx_frame_cnt; + + /** rx clear count, MAC_PCU_RX_CLEAR_CNT_ADDRESS */ + A_UINT32 reg_rxclr_cnt; + + /** total cycle counts MAC_PCU_CYCLE_CNT_ADDRESS */ + A_UINT32 reg_cycle_cnt; /* delta cycle count */ + + /** extenstion channel rx clear count */ + A_UINT32 reg_rxclr_ext_cnt; + + /** OFDM phy error counts, MAC_PCU_PHY_ERR_CNT_1_ADDRESS */ + A_UINT32 reg_ofdm_phyerr_cnt; + + /** CCK phy error count, MAC_PCU_PHY_ERR_CNT_2_ADDRESS */ + A_UINT32 reg_cck_phyerr_cnt; /* CCK err count since last reset, read from register */ + +} wlan_dcs_im_tgt_stats_t; + +/** + * wmi_dcs_interference_event_t + * + * Right now this is event and stats together. Partly this is + * because cw interference is handled in target now. This + * can be done at host itself, if we can carry the NF alone + * as a stats event. In future this would be done and this + * event would carry only stats. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_dcs_interference_event_fixed_param */ + /** + * Type of the event present, either the cw interference event, or the wlan_im stats + */ + A_UINT32 interference_type; /* type of interference, wlan or cw */ + /* + * Following this struct are these TLVs. Note that they are both array of structures + * but can have at most one element. Which TLV is empty or has one element depends + * on the field interference_type. This is to emulate an union with cw_int and wlan_stat + * elements (not arrays). union { ath_dcs_cw_int cw_int; wlan_dcs_im_tgt_stats_t wlan_stat; } int_event; + * + * //cw_interference event + * ath_dcs_cw_int cw_int[]; this element + * // wlan im interfernce stats + * wlan_dcs_im_tgt_stats_t wlan_stat[]; + */ +} wmi_dcs_interference_event_fixed_param; + +enum wmi_peer_mcast_group_action { + wmi_peer_mcast_group_action_add = 0, + wmi_peer_mcast_group_action_del = 1 +}; +#define WMI_PEER_MCAST_GROUP_FLAG_ACTION_M 0x1 +#define WMI_PEER_MCAST_GROUP_FLAG_ACTION_S 0 +#define WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_M 0x2 +#define WMI_PEER_MCAST_GROUP_FLAG_WILDCARD_S 1 +/* multicast group membership commands */ +/* TODO: Converting this will be tricky since it uses an union. + Also, the mac_addr is not aligned. We will convert to the wmi_mac_addr */ +typedef struct{ + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_mcast_group_cmd_fixed_param */ + A_UINT32 flags; + wmi_mac_addr ucast_mac_addr; + A_UINT8 mcast_ip_addr[16]; /* in network byte order */ +} wmi_peer_mcast_group_cmd_fixed_param; + + +/** Offload Scan and Roaming related commands */ +/** The FW performs 2 different kinds of offload scans independent + * of host. One is Roam scan which is primarily performed on a + * station VDEV after association to look for a better AP that + * the station VDEV can roam to. The second scan is connect scan + * which is mainly performed when the station is not associated + * and to look for a matching AP profile from a list of + * configured profiles. */ + +/** + * WMI_ROAM_SCAN_MODE: Set Roam Scan mode + * the roam scan mode is one of the periodic, rssi change, both, none. + * None : Disable Roam scan. No Roam scan at all. + * Periodic : Scan periodically with a configurable period. + * Rssi change : Scan when ever rssi to current AP changes by the threshold value + * set by WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD command. + * Both : Both of the above (scan when either period expires or rss to current AP changes by X amount) + * + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param */ + A_UINT32 roam_scan_mode; + A_UINT32 vdev_id; +} wmi_roam_scan_mode_fixed_param; + +#define WMI_ROAM_SCAN_MODE_NONE 0x0 +#define WMI_ROAM_SCAN_MODE_PERIODIC 0x1 +#define WMI_ROAM_SCAN_MODE_RSSI_CHANGE 0x2 +#define WMI_ROAM_SCAN_MODE_BOTH 0x3 +/* Note: WMI_ROAM_SCAN_MODE_ROAMOFFLOAD is one bit not conflict with LFR2.0 SCAN_MODE. */ +#define WMI_ROAM_SCAN_MODE_ROAMOFFLOAD 0x4 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 command_arg; +} wmi_roam_scan_cmd_fixed_param; + +#define WMI_ROAM_SCAN_STOP_CMD 0x1 + +/** + * WMI_ROAM_SCAN_RSSI_THRESHOLD : set scan rssi thresold + * scan rssi threshold is the rssi threshold below which the FW will start running Roam scans. + * Applicable when WMI_ROAM_SCAN_MODE is not set to none. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** roam scan rssi threshold */ + A_UINT32 roam_scan_rssi_thresh; + /** When using Hw generated beacon RSSI interrupts */ + A_UINT32 roam_rssi_thresh_diff; + /** 5G scan max count */ + A_UINT32 hirssi_scan_max_count; + /** 5G scan rssi change threshold value */ + A_UINT32 hirssi_scan_delta; + /** 5G scan upper bound */ + A_UINT32 hirssi_upper_bound; +} wmi_roam_scan_rssi_threshold_fixed_param; + +#define WMI_ROAM_5G_BOOST_PENALIZE_ALGO_FIXED 0x0 +#define WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR 0x1 +#define WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LOG 0x2 +#define WMI_ROAM_5G_BOOST_PENALIZE_ALGO_EXP 0x3 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param */ + A_UINT32 boost_threshold_5g; /** RSSI threshold above which 5GHz RSSI is favored */ + A_UINT32 penalty_threshold_5g; /** RSSI threshold below which 5GHz RSSI is penalized */ + A_UINT32 boost_algorithm_5g; /** 0 == fixed, 1 == linear, 2 == logarithm ..etc */ + A_UINT32 boost_factor_5g; /** factor by which 5GHz RSSI is boosted */ + A_UINT32 penalty_algorithm_5g; /** 0 == fixed, 1 == linear, 2 == logarithm ..etc */ + A_UINT32 penalty_factor_5g; /** factor by which 5GHz RSSI is penalized */ + A_UINT32 max_boost_5g; /** maximum boost that can be applied to a 5GHz RSSI */ + A_UINT32 max_penalty_5g; /** maximum penality that can be applied to a 5GHz RSSI */ + A_UINT32 good_rssi_threshold; /** RSSI below which roam is kicked in by background scan, although rssi is still good */ +} wmi_roam_scan_extended_threshold_param; + +/** + * WMI_ROAM_SCAN_PERIOD: period for roam scan. + * Applicable when the scan mode is Periodic or both. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** roam scan period value */ + A_UINT32 roam_scan_period; + /** Aging for Roam scans */ + A_UINT32 roam_scan_age; +} wmi_roam_scan_period_fixed_param; + +/** + * WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD : rssi delta to trigger the roam scan. + * Rssi change threshold used when mode is Rssi change (or) Both. + * The FW will run the roam scan when ever the rssi changes (up or down) by the value set by this parameter. + * Note scan is triggered based on the rssi threshold condition set by WMI_ROAM_SCAN_RSSI_THRESHOLD + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** roam scan rssi change threshold value */ + A_UINT32 roam_scan_rssi_change_thresh; + /** When using Hw generated beacon RSSI interrupts */ + A_UINT32 bcn_rssi_weight; + /** Minimum delay between two 5G scans */ + A_UINT32 hirssi_delay_btw_scans; +} wmi_roam_scan_rssi_change_threshold_fixed_param; + +#define WMI_ROAM_SCAN_CHAN_LIST_TYPE_NONE 0x1 +#define WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC 0x2 +#define WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC 0x3 +/** + * TLV for roaming channel list + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** WMI_CHAN_LIST_TAG */ + A_UINT32 chan_list_type; + /** # if channels to scan */ + A_UINT32 num_chan; +/** + * TLV (tag length value ) parameters follow the wmi_roam_chan_list + * structure. The TLV's are: + * A_UINT32 channel_list[]; + **/ +} wmi_roam_chan_list_fixed_param; + +/** Authentication modes */ +enum { + WMI_AUTH_NONE , /* no upper level auth */ + WMI_AUTH_OPEN , /* open */ + WMI_AUTH_SHARED , /* shared-key */ + WMI_AUTH_8021X , /* 802.1x */ + WMI_AUTH_AUTO , /* Auto */ + WMI_AUTH_WPA , /* WPA */ + WMI_AUTH_RSNA , /* WPA2/RSNA */ + WMI_AUTH_CCKM , /* CCK */ + WMI_AUTH_WAPI ,/* WAPI */ + WMI_AUTH_AUTO_PSK, + WMI_AUTH_WPA_PSK, + WMI_AUTH_RSNA_PSK, + WMI_AUTH_WAPI_PSK, + WMI_AUTH_FT_RSNA, /* 11r FT */ + WMI_AUTH_FT_RSNA_PSK, + WMI_AUTH_RSNA_PSK_SHA256, + WMI_AUTH_RSNA_8021X_SHA256, +}; + +typedef struct { + /** authentication mode (defined above) */ + A_UINT32 rsn_authmode; + /** unicast cipher set */ + A_UINT32 rsn_ucastcipherset; + /** mcast/group cipher set */ + A_UINT32 rsn_mcastcipherset; + /** mcast/group management frames cipher set */ + A_UINT32 rsn_mcastmgmtcipherset; +} wmi_rsn_params; + +/** looking for a wps enabled AP */ +#define WMI_AP_PROFILE_FLAG_WPS 0x1 +/** looking for a secure AP */ +#define WMI_AP_PROFILE_FLAG_CRYPTO 0x2 +/** looking for a PMF enabled AP */ +#define WMI_AP_PROFILE_FLAG_PMF 0x4 + +/** To match an open AP, the rs_authmode should be set to WMI_AUTH_NONE + * and WMI_AP_PROFILE_FLAG_CRYPTO should be clear. + * To match a WEP enabled AP, the rs_authmode should be set to WMI_AUTH_NONE + * and WMI_AP_PROFILE_FLAG_CRYPTO should be set . + */ + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ap_profile */ + /** flags as defined above */ + A_UINT32 flags; + /** + * rssi thresold value: the value of the the candidate AP should + * higher by this threshold than the rssi of the currrently associated AP. + */ + A_UINT32 rssi_threshold; + /** + * ssid vlaue to be matched. + */ + wmi_ssid ssid; + + /** + * security params to be matched. + */ + /** authentication mode (defined above) */ + A_UINT32 rsn_authmode; + /** unicast cipher set */ + A_UINT32 rsn_ucastcipherset; + /** mcast/group cipher set */ + A_UINT32 rsn_mcastcipherset; + /** mcast/group management frames cipher set */ + A_UINT32 rsn_mcastmgmtcipherset; +} wmi_ap_profile; + +/** Beacon filter wmi command info */ + +#define BCN_FLT_MAX_SUPPORTED_IES 256 +#define BCN_FLT_MAX_ELEMS_IE_LIST BCN_FLT_MAX_SUPPORTED_IES/32 + +typedef struct bss_bcn_stats { + A_UINT32 vdev_id; + A_UINT32 bss_bcnsdropped; + A_UINT32 bss_bcnsdelivered; +}wmi_bss_bcn_stats_t; + +typedef struct bcn_filter_stats { + A_UINT32 bcns_dropped; + A_UINT32 bcns_delivered; + A_UINT32 activefilters; + wmi_bss_bcn_stats_t bss_stats; +}wmi_bcnfilter_stats_t; + +typedef struct wmi_add_bcn_filter_cmd { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_add_bcn_filter_cmd_fixed_param */ + A_UINT32 vdev_id; + /* + * Following this structure is the TLV: + * A_UINT32 ie_map[BCN_FLT_MAX_ELEMS_IE_LIST]; + */ +} wmi_add_bcn_filter_cmd_fixed_param; + +typedef struct wmi_rmv_bcn_filter_cmd { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_rmv_bcn_filter_cmd_fixed_param */ + A_UINT32 vdev_id; +}wmi_rmv_bcn_filter_cmd_fixed_param; + +#define WMI_BCN_SEND_DTIM_ZERO 1 +#define WMI_BCN_SEND_DTIM_BITCTL_SET 2 +typedef struct wmi_bcn_send_from_host { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 data_len; + A_UINT32 frag_ptr; /* Physical address of the frame */ + A_UINT32 frame_ctrl; /* farme ctrl to setup PPDU desc */ + A_UINT32 dtim_flag; /* to control CABQ traffic */ +}wmi_bcn_send_from_host_cmd_fixed_param; + +/* cmd to support bcn snd for all vaps at once */ +typedef struct wmi_pdev_send_bcn { + A_UINT32 num_vdevs; + wmi_bcn_send_from_host_cmd_fixed_param bcn_cmd[1]; +} wmi_pdev_send_bcn_cmd_t; + + /* + * WMI_ROAM_AP_PROFILE: AP profile of connected AP for roaming. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param */ + /** id of AP criteria */ + A_UINT32 id; + + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + + /* + * Following this structure is the TLV: + * wmi_ap_profile ap_profile; //AP profile info + */ +} wmi_roam_ap_profile_fixed_param; + +/** + * WMI_OFL_SCAN_ADD_AP_PROFILE: add an AP profile. + */ +typedef struct { + /** id of AP criteria */ + A_UINT32 id; + + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + + /** AP profile info */ + wmi_ap_profile ap_profile; + +} wmi_ofl_scan_add_ap_profile; + +/** + * WMI_OFL_SCAN_REMOVE_AP_CRITERIA: remove an ap profile. + */ +typedef struct { + /** id of AP criteria */ + A_UINT32 id; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_ofl_scan_remove_ap_profile; + +/** + * WMI_OFL_SCAN_PERIOD: period in msec for offload scan. + * 0 will disable ofload scan and a very low value will perform a continous + * scan. + */ +typedef struct { + /** offload scan period value, used for scans used when not connected */ + A_UINT32 ofl_scan_period; +} wmi_ofl_scan_period; + +/* Do not modify XXX_BYTES or XXX_LEN below as it is fixed by standard */ +#define ROAM_OFFLOAD_PMK_BYTES (32) +#define ROAM_OFFLOAD_PSK_MSK_BYTES (32) +#define ROAM_OFFLOAD_KRK_BYTES (16) +#define ROAM_OFFLOAD_BTK_BYTES (32) +#define ROAM_OFFLOAD_R0KH_ID_MAX_LEN (48) +#define ROAM_OFFLOAD_NUM_MCS_SET (16) + +/* This TLV will be filled only in case roam offload + * for wpa2-psk/okc/ese/11r is enabled */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_offload_fixed_param */ + A_UINT32 rssi_cat_gap; /* gap for every category bucket */ + A_UINT32 prefer_5g; /* prefer select 5G candidate */ + A_UINT32 select_5g_margin; + A_UINT32 reassoc_failure_timeout; /* reassoc failure timeout */ + A_UINT32 capability; + A_UINT32 ht_caps_info; + A_UINT32 ampdu_param; + A_UINT32 ht_ext_cap; + A_UINT32 ht_txbf; + A_UINT32 asel_cap; + A_UINT32 qos_enabled; + A_UINT32 qos_caps; + A_UINT32 wmm_caps; + A_UINT32 mcsset[ROAM_OFFLOAD_NUM_MCS_SET>>2]; /* since this 4 byte aligned, + * we don't declare it as + * tlv array */ +} wmi_roam_offload_tlv_param; + +/* flags for 11i offload */ +#define WMI_ROAM_OFFLOAD_FLAG_OKC_ENABLED 0 /* okc is enabled */ +/* from bit 1 to bit 31 are reserved */ + +#define WMI_SET_ROAM_OFFLOAD_OKC_ENABLED(flag) do { \ + (flag) |= (1 << WMI_ROAM_OFFLOAD_FLAG_OKC_ENABLED); \ + } while(0) + +#define WMI_SET_ROAM_OFFLOAD_OKC_DISABLED(flag) do { \ + (flag) &= ~(1 << WMI_ROAM_OFFLOAD_FLAG_OKC_ENABLED); \ + } while(0) + +#define WMI_GET_ROAM_OFFLOAD_OKC_ENABLED(flag) \ + ((flag) & (1 << WMI_ROAM_OFFLOAD_FLAG_OKC_ENABLED)) + +/* This TLV will be filled only in case of wpa-psk/wpa2-psk */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_11i_offload_fixed_param */ + A_UINT32 flags; /** flags. see WMI_ROAM_OFFLOAD_FLAG_ above */ + A_UINT32 pmk[ROAM_OFFLOAD_PMK_BYTES>>2]; /* pmk offload. As this 4 byte aligned, we don't declare it as tlv array */ + A_UINT32 pmk_len; /**the length of pmk. in normal case it should be 32, but for LEAP, is should be 16*/ +} wmi_roam_11i_offload_tlv_param; + +/* This TLV will be filled only in case of 11R*/ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_11r_offload_fixed_param */ + A_UINT32 mdie_present; + A_UINT32 mdid; + A_UINT32 r0kh_id[ROAM_OFFLOAD_R0KH_ID_MAX_LEN>>2]; + A_UINT32 r0kh_id_len; + A_UINT32 psk_msk[ROAM_OFFLOAD_PSK_MSK_BYTES>>2]; /* psk/msk offload. As this 4 byte aligned, we don't declare it as tlv array */ + A_UINT32 psk_msk_len; /**length of psk_msk*/ +} wmi_roam_11r_offload_tlv_param; + +/* This TLV will be filled only in case of ESE */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_ese_offload_fixed_param */ + A_UINT32 krk[ROAM_OFFLOAD_KRK_BYTES>>2]; /* KRK offload. As this 4 byte aligned, we don't declare it as tlv array */ + A_UINT32 btk[ROAM_OFFLOAD_BTK_BYTES>>2]; /* BTK offload. As this 4 byte aligned, we don't declare it as tlv array */ +} wmi_roam_ese_offload_tlv_param; + + +/** WMI_ROAM_EVENT: roam event triggering the host roam logic. + * generated when ever a better AP is found in the recent roam scan (or) + * when beacon miss is detected (or) when a DEAUTH/DISASSOC is received + * from the current AP. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** reason for roam event */ + A_UINT32 reason; + /** associated AP's rssi calculated by FW when reason code is WMI_ROAM_REASON_LOW_RSSI*/ + A_UINT32 rssi; + +} wmi_roam_event_fixed_param; + +#define WMI_ROAM_REASON_BETTER_AP 0x1 /** found a better AP */ +#define WMI_ROAM_REASON_BMISS 0x2 /** beacon miss detected */ +#define WMI_ROAM_REASON_DEAUTH 0x2 /** deauth/disassoc received */ +#define WMI_ROAM_REASON_LOW_RSSI 0x3 /** connected AP's low rssi condition detected */ +#define WMI_ROAM_REASON_SUITABLE_AP 0x4 /** found another AP that matches + SSID and Security profile in + WMI_ROAM_AP_PROFILE, found during scan + triggered upon FINAL_BMISS **/ +#define WMI_ROAM_REASON_HO_FAILED 0x5 /** LFR3.0 roaming failed, indicate the disconnection to host */ + +/**whenever RIC request information change, host driver should pass all ric related information to firmware (now only support tsepc) +* Once, 11r roaming happens, firmware can generate RIC request in reassoc request based on these informations +*/ +typedef struct +{ + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ric_request_fixed_param */ + A_UINT32 vdev_id; /**unique id identifying the VDEV, generated by the caller*/ + A_UINT32 num_ric_request; /**number of ric request ie send to firmware.(max value is 2 now)*/ + A_UINT32 is_add_ric; /**support add ric or delete ric*/ +}wmi_ric_request_fixed_param; + +/**tspec element: refer to 8.4.2.32 of 802.11 2012 spec +* these elements are used to construct tspec field in RIC request, which allow station to require specific TS when 11r roaming +*/ +typedef struct{ + A_UINT32 tlv_header; + A_UINT32 ts_info; /** bits value of TS Info field.*/ + A_UINT32 nominal_msdu_size; /**Nominal MSDU Size field*/ + A_UINT32 maximum_msdu_size; /**The Maximum MSDU Size field*/ + A_UINT32 min_service_interval; /**The Minimum Service Interval field*/ + A_UINT32 max_service_interval; /**The Maximum Service Interval field*/ + A_UINT32 inactivity_interval; /**The Inactivity Interval field*/ + A_UINT32 suspension_interval; /**The Suspension Interval field*/ + A_UINT32 svc_start_time; /**The Service Start Time field*/ + A_UINT32 min_data_rate; /**The Minimum Data Rate field*/ + A_UINT32 mean_data_rate; /**The Mean Data Rate field*/ + A_UINT32 peak_data_rate; /**The Peak Data Rate field*/ + A_UINT32 max_burst_size; /**The Burst Size field*/ + A_UINT32 delay_bound; /**The Delay Bound field*/ + A_UINT32 min_phy_rate; /**The Minimum PHY Rate field*/ + A_UINT32 surplus_bw_allowance; /**The Surplus Bandwidth Allowance field*/ + A_UINT32 medium_time; /**The Medium Time field,in units of 32 us/s.*/ +} wmi_ric_tspec; + +/* flags for roam_invoke_cmd */ +/* add this channel into roam cache channel list after this command is finished */ +#define WMI_ROAM_INVOKE_FLAG_ADD_CH_TO_CACHE 0 +/* from bit 1 to bit 31 are reserved */ + +#define WMI_SET_ROAM_INVOKE_ADD_CH_TO_CACHE(flag) do { \ + (flag) |= (1 << WMI_SET_ROAM_INVOKE_ADD_CH_TO_CACHE); \ + } while(0) + +#define WMI_CLEAR_ROAM_INVOKE_ADD_CH_TO_CACHE(flag) do { \ + (flag) &= ~(1 << WMI_SET_ROAM_INVOKE_ADD_CH_TO_CACHE); \ + } while(0) + +#define WMI_GET_ROAM_INVOKE_ADD_CH_TO_CACHE(flag) \ + ((flag) & (1 << WMI_SET_ROAM_INVOKE_ADD_CH_TO_CACHE)) + + +#define WMI_ROAM_INVOKE_SCAN_MODE_FIXED_CH 0 /* scan given channel only */ +#define WMI_ROAM_INVOKE_SCAN_MODE_CACHE_LIST 1 /* scan cached channel list */ +#define WMI_ROAM_INVOKE_SCAN_MODE_FULL_CH 2 /* scan full channel */ + +#define WMI_ROAM_INVOKE_AP_SEL_FIXED_BSSID 0 /* roam to given BSSID only */ +#define WMI_ROAM_INVOKE_AP_SEL_ANY_BSSID 1 /* roam to any BSSID */ + +/** WMI_ROAM_INVOKE_CMD: command to invoke roaming forcefully + * + * if is zero and is not given, roaming is not executed. + * if is zero and = 0 + * = 0 + * = 0 + * |= WMI_ROAM_INVOKE_FLAG_ADD_CH_TO_CACHE + * = do not fill (there will be no actual roaming because of ap_sel_mode is zero, but no BSSID is given) + * = channel list to be added + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_invoke_fixed_param */ + A_UINT32 vdev_id; /** Unique id identifying the VDEV on which roaming is invoked */ + A_UINT32 flags; /** flags. see WMI_ROAM_INVOKE_FLAG_ above */ + A_UINT32 roam_scan_mode; /** see WMI_ROAM_INVOKE_SCAN_ above */ + A_UINT32 roam_ap_sel_mode; /** see WMI_ROAM_INVOKE_AP_SEL_ above */ + A_UINT32 roam_delay; /** 0 = immediate roam, 1-2^32 = roam after this delay (msec) */ + A_UINT32 num_chan; /** # if channels to scan. In the TLV channel_list[] */ + A_UINT32 num_bssid; /** number of bssids. In the TLV bssid_list[] */ + /** + * TLV (tag length value ) parameters follows roam_invoke_req + * The TLV's are: + * A_UINT32 channel_list[]; + * wmi_mac_addr bssid_list[]; + */ +} wmi_roam_invoke_cmd_fixed_param; + +/* Definition for op_bitmap */ +enum { + ROAM_FILTER_OP_BITMAP_BLACK_LIST = 0x1, + ROAM_FILTER_OP_BITMAP_WHITE_LIST = 0x2, + ROAM_FILTER_OP_BITMAP_PREFER_BSSID = 0x4, +}; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_filter_list_fixed_param */ + A_UINT32 vdev_id; /** Unique id identifying the VDEV on which roaming filter is adopted */ + A_UINT32 flags; /** flags for filter */ + A_UINT32 op_bitmap; /** 32 bit bitmap to be set on. bit0 = first param, bit 1 = second param...etc. Can be or'ed */ + A_UINT32 num_bssid_black_list; /* number of blacklist in the TLV variable bssid_black_list */ + A_UINT32 num_ssid_white_list; /* number of whitelist in the TLV variable ssid_white_list */ + A_UINT32 num_bssid_preferred_list; /* only for lfr 3.0. number of preferred list & factor in the TLV */ + /** + * TLV (tag length value ) parameters follows roam_filter_list_cmd + * The TLV's are: + * wmi_mac_addr bssid_black_list[]; + * wmi_ssid ssid_white_list[]; + * wmi_mac_addr bssid_preferred_list[]; + * A_UINT32 bssid_preferred_factor[]; + */ +} wmi_roam_filter_fixed_param; + +typedef struct { + A_UINT8 address[4]; /* IPV4 address in Network Byte Order */ +} WMI_IPV4_ADDR; + +typedef struct _WMI_IPV6_ADDR { + A_UINT8 address[16]; /* IPV6 in Network Byte Order */ +} WMI_IPV6_ADDR; + +/* flags for subnet change detection */ +#define WMI_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED 0 +#define WMI_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED 1 +/* bit 2 to bit 31 are reserved */ + +/* set IPv4 enabled/disabled flag and get the flag */ +#define WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(flag) do { \ + (flag) |= (1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED); \ +} while (0) + +#define WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_DISABLED(flag) do { \ + (flag) &= ~(1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED); \ +} while (0) + +#define WMI_GET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(flag) \ + ((flag) & (1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED) + +/* set IPv6 enabled flag, disabled and get the flag */ +#define WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(flag) do { \ + (flag) |= (1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED); \ +} while (0) + +#define WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_DISABLED(flag) do { \ + (flag) &= ~(1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED); \ +} while (0) + +#define WMI_GET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(flag) do { \ + ((flag) & (1 << WMI_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED); \ +} while (0) + +/** + * WMI_ROAM_SUBNET_CHANGE_CONFIG : Pass the gateway IP and MAC addresses + * to FW. FW uses these parameters for subnet change detection. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals +WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** IPv4/IPv6 enabled/disabled */ + /** This flag sets the WMI_SET_ROAM_SUBNET_CHANGE_FLAG_xxx_ENABLED/ +DISABLED */ + A_UINT32 flag; + /** Gateway MAC address */ + wmi_mac_addr inet_gw_mac_addr; + /** IP addresses */ + WMI_IPV4_ADDR inet_gw_ip_v4_addr; + WMI_IPV6_ADDR inet_gw_ip_v6_addr; + /** Number of software retries for ARP/Neighbor solicitation request */ + A_UINT32 max_retries; + /** timeout in milliseconds for each ARP request*/ + A_UINT32 timeout; + /** number of skipped aps **/ + A_UINT32 num_skip_subnet_change_detection_bssid_list; +/** + * TLV (tag length value ) parameters follows roam_subnet_change_config_cmd + * structure. The TLV's are: + * wmi_mac_addr skip_subnet_change_detection_bssid_list []; + **/ +} wmi_roam_subnet_change_config_fixed_param; + +/** WMI_PROFILE_MATCH_EVENT: offload scan + * generated when ever atleast one of the matching profiles is found + * in recent NLO scan. no data is carried with the event. + */ + +/** P2P specific commands */ + +/** + * WMI_P2P_DEV_SET_DEVICE_INFO : p2p device info, which will be used by + * FW to generate P2P IE tobe carried in probe response frames. + * FW will respond to probe requests while in listen state. + */ +typedef struct { + /* number of secondary device types,supported */ + A_UINT32 num_secondary_dev_types; + /** + * followed by 8 bytes of primary device id and + * num_secondary_dev_types * 8 bytes of secondary device + * id. + */ +} wmi_p2p_dev_set_device_info; + +/** WMI_P2P_DEV_SET_DISCOVERABILITY: enable/disable discoverability + * state. if enabled, an active STA/AP will respond to P2P probe requests on + * the operating channel of the VDEV. + */ + +typedef struct { + /* 1:enable disoverability, 0:disable discoverability */ + A_UINT32 enable_discoverability; +} wmi_p2p_set_discoverability; + +/** WMI_P2P_GO_SET_BEACON_IE: P2P IE to be added to + * beacons generated by FW. used in FW beacon mode. + * the FW will add this IE to beacon in addition to the beacon + * template set by WMI_BCN_TMPL_CMDID command. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* ie length */ + A_UINT32 ie_buf_len; + /* Following this structure is the TLV byte stream of ie data of length ie_buf_len: + * A_UINT8 ie_data[]; // length in byte given by field num_data. + */ + +} wmi_p2p_go_set_beacon_ie_fixed_param; + +/** WMI_P2P_GO_PROBE_RESP_IE: P2P IE to be added to + * probe response generated by FW. used in FW beacon mode. + * the FW will add this IE to probe response in addition to the probe response + * template set by WMI_PRB_TMPL_CMDID command. + */ +typedef struct { + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* ie length */ + A_UINT32 ie_buf_len; + /*followed by byte stream of ie data of length ie_buf_len */ +} wmi_p2p_go_set_probe_resp_ie; + +/** WMI_P2P_SET_VENDOR_IE_DATA_CMDID: Vendor specific P2P IE data, which will + * be used by the FW to parse the P2P NoA attribute in beacons, probe resposes + * and action frames received by the P2P Client. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_set_vendor_ie_data_cmd_fixed_param */ + /** OS specific P2P IE OUI (3 bytes) + OUI type (1 byte) */ + A_UINT32 p2p_ie_oui_type; + /** OS specific NoA Attribute ID */ + A_UINT32 p2p_noa_attribute; +} wmi_p2p_set_vendor_ie_data_cmd_fixed_param; + +/*----P2P disc offload definition ----*/ + +typedef struct { + A_UINT32 pattern_type; + /** + * TLV (tag length value ) paramerters follow the pattern structure. + * TLV can contain bssid list, ssid list and + * ie. the TLV tags are defined above; + */ +}wmi_p2p_disc_offload_pattern_cmd; + +typedef struct { + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* mgmt type of the ie*/ + A_UINT32 mgmt_type; + /* ie length */ + A_UINT32 ie_buf_len; + /*followed by byte stream of ie data of length ie_buf_len */ +}wmi_p2p_disc_offload_appie_cmd; + +typedef struct { + /* enable/disable p2p find offload*/ + A_UINT32 enable; + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* p2p find type */ + A_UINT32 disc_type; + /* p2p find perodic */ + A_UINT32 perodic; + /* p2p find listen channel */ + A_UINT32 listen_channel; + /* p2p find full channel number */ + A_UINT32 num_scan_chans; + /** + * TLV (tag length value ) paramerters follow the pattern structure. + * TLV contain channel list + */ +}wmi_p2p_disc_offload_config_cmd; + +/*----P2P OppPS definition ----*/ +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param */ + A_UINT32 tlv_header; + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* OppPS attributes */ + /** Bit 0: Indicate enable/disable of OppPS + * Bits 7-1: Ctwindow in TUs + * Bits 31-8: Reserved + */ + A_UINT32 oppps_attr; +} wmi_p2p_set_oppps_cmd_fixed_param; + +#define WMI_UNIFIED_OPPPS_ATTR_ENALBED 0x1 +#define WMI_UNIFIED_OPPPS_ATTR_ENALBED_S 0 + +#define WMI_UNIFIED_OPPPS_ATTR_IS_ENABLED(hdr) \ + WMI_F_MS((hdr)->oppps_attr, WMI_UNIFIED_OPPPS_ATTR_ENALBED) + +#define WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(hdr) \ + WMI_F_RMW((hdr)->oppps_attr, 0x1, \ + WMI_UNIFIED_OPPPS_ATTR_ENALBED); + +#define WMI_UNIFIED_OPPPS_ATTR_CTWIN 0xfe +#define WMI_UNIFIED_OPPPS_ATTR_CTWIN_S 1 + +#define WMI_UNIFIED_OPPPS_ATTR_CTWIN_GET(hdr) \ + WMI_F_MS((hdr)->oppps_attr, WMI_UNIFIED_OPPPS_ATTR_CTWIN) + +#define WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(hdr, v) \ + WMI_F_RMW((hdr)->oppps_attr, (v) & 0x7f, \ + WMI_UNIFIED_OPPPS_ATTR_CTWIN); + +typedef struct { + A_UINT32 time32; //upper 32 bits of time stamp + A_UINT32 time0; //lower 32 bits of time stamp +} A_TIME64; + +typedef enum wmi_peer_sta_kickout_reason { + WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED = 0, /* default value to preserve legacy behavior */ + WMI_PEER_STA_KICKOUT_REASON_XRETRY = 1, + WMI_PEER_STA_KICKOUT_REASON_INACTIVITY = 2, + WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT = 3, + WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT = 4, /* TDLS peer has disappeared. All tx is failing */ +} PEER_KICKOUT_REASON; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_sta_kickout_event_fixed_param */ + /** peer mac address */ + wmi_mac_addr peer_macaddr; + /** Reason code, defined as above */ + A_UINT32 reason; +} wmi_peer_sta_kickout_event_fixed_param; + +#define WMI_WLAN_PROFILE_MAX_HIST 3 +#define WMI_WLAN_PROFILE_MAX_BIN_CNT 32 + +typedef struct _wmi_wlan_profile_t { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_t */ + A_UINT32 id; + A_UINT32 cnt; + A_UINT32 tot; + A_UINT32 min; + A_UINT32 max; + A_UINT32 hist_intvl; + A_UINT32 hist[WMI_WLAN_PROFILE_MAX_HIST]; +} wmi_wlan_profile_t; + +typedef struct _wmi_wlan_profile_ctx_t { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_ctx_t */ + A_UINT32 tot; /* time in us */ + A_UINT32 tx_msdu_cnt; + A_UINT32 tx_mpdu_cnt; + A_UINT32 tx_ppdu_cnt; + A_UINT32 rx_msdu_cnt; + A_UINT32 rx_mpdu_cnt; + A_UINT32 bin_count; +} wmi_wlan_profile_ctx_t; + + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param */ + A_UINT32 enable; +} wmi_wlan_profile_trigger_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param */ + A_UINT32 value; +} wmi_wlan_profile_get_prof_data_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param */ + A_UINT32 profile_id; + A_UINT32 value; +} wmi_wlan_profile_set_hist_intvl_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param */ + A_UINT32 profile_id; + A_UINT32 enable; +} wmi_wlan_profile_enable_profile_id_cmd_fixed_param; + +/*Wifi header is upto 26, LLC is 8, with 14 byte duplicate in 802.3 header, that's 26+8-14=20. +146-128=18. So this means it is converted to non-QoS header. Riva FW take care of the QOS/non-QOS +when comparing wifi header.*/ +/* NOTE: WOW_DEFAULT_BITMAP_PATTERN_SIZE(_DWORD) and WOW_DEFAULT_BITMASK_SIZE(_DWORD) can't be changed without breaking the compatibility */ +#define WOW_DEFAULT_BITMAP_PATTERN_SIZE 146 +#define WOW_DEFAULT_BITMAP_PATTERN_SIZE_DWORD 37 //Convert WOW_DEFAULT_EVT_BUF_SIZE into Int32 size +#define WOW_DEFAULT_BITMASK_SIZE 146 +#define WOW_DEFAULT_BITMASK_SIZE_DWORD 37 +#define WOW_MAX_BITMAP_FILTERS 32 +#define WOW_DEFAULT_MAGIG_PATTERN_MATCH_CNT 16 +#define WOW_EXTEND_PATTERN_MATCH_CNT 16 +#define WOW_SHORT_PATTERN_MATCH_CNT 8 +#define WOW_DEFAULT_EVT_BUF_SIZE 148 /* Maximum 148 bytes of the data is copied starting from header incase if the match is found. + The 148 comes from (128 - 14 ) payload size + 8bytes LLC + 26bytes MAC header*/ +#define WOW_DEFAULT_IOAC_PATTERN_SIZE 6 +#define WOW_DEFAULT_IOAC_PATTERN_SIZE_DWORD 2 +#define WOW_DEFAULT_IOAC_RANDOM_SIZE 6 +#define WOW_DEFAULT_IOAC_RANDOM_SIZE_DWORD 2 +#define WOW_DEFAULT_IOAC_KEEP_ALIVE_PKT_SIZE 120 +#define WOW_DEFAULT_IOAC_KEEP_ALIVE_PKT_SIZE_DWORD 30 + +typedef enum pattern_type_e { + WOW_PATTERN_MIN = 0, + WOW_BITMAP_PATTERN = WOW_PATTERN_MIN, + WOW_IPV4_SYNC_PATTERN, + WOW_IPV6_SYNC_PATTERN, + WOW_WILD_CARD_PATTERN, + WOW_TIMER_PATTERN, + WOW_MAGIC_PATTERN, + WOW_IPV6_RA_PATTERN, + WOW_IOAC_PKT_PATTERN, + WOW_IOAC_TMR_PATTERN, + WOW_PATTERN_MAX +}WOW_PATTERN_TYPE; + +typedef enum event_type_e { + WOW_BMISS_EVENT = 0, + WOW_BETTER_AP_EVENT, + WOW_DEAUTH_RECVD_EVENT, + WOW_MAGIC_PKT_RECVD_EVENT, + WOW_GTK_ERR_EVENT, + WOW_FOURWAY_HSHAKE_EVENT, + WOW_EAPOL_RECVD_EVENT, + WOW_NLO_DETECTED_EVENT, + WOW_DISASSOC_RECVD_EVENT, + WOW_PATTERN_MATCH_EVENT, + WOW_CSA_IE_EVENT, + WOW_PROBE_REQ_WPS_IE_EVENT, + WOW_AUTH_REQ_EVENT, + WOW_ASSOC_REQ_EVENT, + WOW_HTT_EVENT, + WOW_RA_MATCH_EVENT, + WOW_HOST_AUTO_SHUTDOWN_EVENT, + WOW_IOAC_MAGIC_EVENT, + WOW_IOAC_SHORT_EVENT, + WOW_IOAC_EXTEND_EVENT, + WOW_IOAC_TIMER_EVENT, + WOW_DFS_PHYERR_RADAR_EVENT, + WOW_BEACON_EVENT, + WOW_CLIENT_KICKOUT_EVENT, + WOW_NAN_EVENT, + WOW_EXTSCAN_EVENT, +} WOW_WAKE_EVENT_TYPE; + +typedef enum wake_reason_e { + WOW_REASON_UNSPECIFIED =-1, + WOW_REASON_NLOD = 0, + WOW_REASON_AP_ASSOC_LOST, + WOW_REASON_LOW_RSSI, + WOW_REASON_DEAUTH_RECVD, + WOW_REASON_DISASSOC_RECVD, + WOW_REASON_GTK_HS_ERR, + WOW_REASON_EAP_REQ, + WOW_REASON_FOURWAY_HS_RECV, + WOW_REASON_TIMER_INTR_RECV, + WOW_REASON_PATTERN_MATCH_FOUND, + WOW_REASON_RECV_MAGIC_PATTERN, + WOW_REASON_P2P_DISC, + WOW_REASON_WLAN_HB, + WOW_REASON_CSA_EVENT, + WOW_REASON_PROBE_REQ_WPS_IE_RECV, + WOW_REASON_AUTH_REQ_RECV, + WOW_REASON_ASSOC_REQ_RECV, + WOW_REASON_HTT_EVENT, + WOW_REASON_RA_MATCH, + WOW_REASON_HOST_AUTO_SHUTDOWN, + WOW_REASON_IOAC_MAGIC_EVENT, + WOW_REASON_IOAC_SHORT_EVENT, + WOW_REASON_IOAC_EXTEND_EVENT, + WOW_REASON_IOAC_TIMER_EVENT, + WOW_REASON_ROAM_HO, + WOW_REASON_DFS_PHYERR_RADADR_EVENT, + WOW_REASON_BEACON_RECV, + WOW_REASON_CLIENT_KICKOUT_EVENT, + WOW_REASON_NAN_EVENT, + WOW_REASON_EXTSCAN, + WOW_REASON_RSSI_BREACH_EVENT, + WOW_REASON_DEBUG_TEST = 0xFF, +} WOW_WAKE_REASON_TYPE; + +typedef enum { + WOW_IFACE_PAUSE_ENABLED, + WOW_IFACE_PAUSE_DISABLED +} WOW_IFACE_STATUS; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param */ + A_UINT32 enable; + A_UINT32 pause_iface_config; +} wmi_wow_enable_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param */ + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_wow_hostwakeup_from_sleep_cmd_fixed_param; + +typedef struct bitmap_pattern_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T */ + A_UINT32 patternbuf[WOW_DEFAULT_BITMAP_PATTERN_SIZE_DWORD]; + A_UINT32 bitmaskbuf[WOW_DEFAULT_BITMASK_SIZE_DWORD]; + A_UINT32 pattern_offset; + A_UINT32 pattern_len; + A_UINT32 bitmask_len; + A_UINT32 pattern_id; /* must be less than max_bitmap_filters */ +}WOW_BITMAP_PATTERN_T; + +typedef struct ipv4_sync_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T */ + A_UINT32 ipv4_src_addr; + A_UINT32 ipv4_dst_addr; + A_UINT32 tcp_src_prt; + A_UINT32 tcp_dst_prt; +}WOW_IPV4_SYNC_PATTERN_T; + +typedef struct ipv6_sync_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T */ + A_UINT32 ipv6_src_addr[4]; + A_UINT32 ipv6_dst_addr[4]; + A_UINT32 tcp_src_prt; + A_UINT32 tcp_dst_prt; +}WOW_IPV6_SYNC_PATTERN_T; + +typedef struct WOW_MAGIC_PATTERN_CMD +{ + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD */ + wmi_mac_addr macaddr; +}WOW_MAGIC_PATTERN_CMD; + +typedef enum wow_ioac_pattern_type { + WOW_IOAC_MAGIC_PATTERN = 1, + WOW_IOAC_SHORT_PATTERN, + WOW_IOAC_EXTEND_PATTERN, +} WOW_IOAC_PATTERN_TYPE; + +typedef struct ioac_pkt_pattern_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_IOAC_PKT_PATTERN_T */ + A_UINT32 pattern_type; + A_UINT32 pattern[WOW_DEFAULT_IOAC_PATTERN_SIZE_DWORD]; + A_UINT32 random[WOW_DEFAULT_IOAC_RANDOM_SIZE_DWORD]; + A_UINT32 pattern_len; + A_UINT32 random_len; +} WOW_IOAC_PKT_PATTERN_T; + +typedef struct ioac_tmr_pattern_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_IOAC_TMR_PATTERN_T */ + A_UINT32 wake_in_s; + A_UINT32 vdev_id; +} WOW_IOAC_TMR_PATTERN_T; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_KEEPALIVE_CMD_fixed_param */ + A_UINT32 nID; +} WMI_WOW_IOAC_ADD_KEEPALIVE_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_KEEPALIVE_CMD_fixed_param */ + A_UINT32 nID; +} WMI_WOW_IOAC_DEL_KEEPALIVE_CMD_fixed_param; + +typedef struct ioac_keepalive_s { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_IOAC_KEEPALIVE_T */ + A_UINT32 keepalive_pkt_buf[WOW_DEFAULT_IOAC_KEEP_ALIVE_PKT_SIZE_DWORD]; + A_UINT32 keepalive_pkt_len; + A_UINT32 period_in_ms; + A_UINT32 vdev_id; +} WMI_WOW_IOAC_KEEPALIVE_T; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_IOAC_ADD_PATTERN_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 pattern_type; +/* + * Following this struct are these TLVs. Note that they are all array of structures + * but can have at most one element. Which TLV is empty or has one element depends + * on the field pattern_type. This is to emulate an union. + * WOW_IOAC_PKT_PATTERN_T pattern_info_pkt[]; + * WOW_IOAC_TMR_PATTERN_T pattern_info_tmr[]; + */ +} WMI_WOW_IOAC_ADD_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_IOAC_DEL_PATTERN_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 pattern_type; +} WMI_WOW_IOAC_DEL_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 pattern_id; + A_UINT32 pattern_type; + /* + * Following this struct are these TLVs. Note that they are all array of structures + * but can have at most one element. Which TLV is empty or has one element depends + * on the field pattern_type. This is to emulate an union. + * WOW_BITMAP_PATTERN_T pattern_info_bitmap[]; + * WOW_IPV4_SYNC_PATTERN_T pattern_info_ipv4[]; + * WOW_IPV6_SYNC_PATTERN_T pattern_info_ipv6[]; + * WOW_MAGIC_PATTERN_CMD pattern_info_magic_pattern[]; + * A_UINT32 pattern_info_timeout[]; + * A_UINT32 ra_ratelimit_interval; + */ +}WMI_WOW_ADD_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 pattern_id; + A_UINT32 pattern_type; +}WMI_WOW_DEL_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 is_add; + A_UINT32 event_bitmap; +}WMI_WOW_ADD_DEL_EVT_CMD_fixed_param; + +typedef struct wow_event_info_s { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_EVENT_INFO_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 flag; /*This is current reserved.*/ + A_INT32 wake_reason; + A_UINT32 data_len; +}WOW_EVENT_INFO_fixed_param; + +typedef struct wow_initial_wakeup_event_s { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WOW_INITIAL_WAKEUP_EVENT_fixed_param */ + A_UINT32 vdev_id; +} WOW_INITIAL_WAKEUP_EVENT_fixed_param; + +typedef enum { + WOW_EVENT_INFO_TYPE_PACKET = 0x0001, + WOW_EVENT_INFO_TYPE_BITMAP, + WOW_EVENT_INFO_TYPE_GTKIGTK, +}WOW_EVENT_INFO_TYPE; + +typedef struct wow_event_info_section_s { + A_UINT32 data_type; + A_UINT32 data_len; +}WOW_EVENT_INFO_SECTION; + +typedef struct wow_event_info_section_packet_s { + A_UINT8 packet[WOW_DEFAULT_EVT_BUF_SIZE]; +}WOW_EVENT_INFO_SECTION_PACKET; + +typedef struct wow_event_info_section_bitmap_s { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WOW_EVENT_INFO_SECTION_BITMAP */ + A_UINT32 flag; /*This is current reserved.*/ + A_UINT32 value; /*This could be the pattern id for bitmap pattern.*/ + A_UINT32 org_len; /*The length of the orginal packet.*/ +}WOW_EVENT_INFO_SECTION_BITMAP; + +/** + * This command is sent from WLAN host driver to firmware to + * enable or disable D0-WOW. D0-WOW means APSS suspend with + * PCIe link and DDR being active. + * + * + * Entering D0-WOW Mode (based on kernel suspend request): + * host->target: WMI_DO_WOW_ENABLE_DISABLE_CMDID (enable = 1) + * target: Take action (e.g. dbglog suspend) + * target->host: HTC_ACK (HTC_MSG_SEND_SUSPEND_COMPLETE message) + * + * Exiting D0-WOW mode (based on kernel resume OR target->host message received) + * host->target: WMI_DO_WOW_ENABLE_DISABLE_CMDID (enable = 0) + * target: Take action (e.g. dbglog resume) + * target->host: WMI_D0_WOW_DISABLE_ACK_EVENTID + * + * This command is applicable only on the PCIE LL systems + * Host can enter either D0-WOW or WOW mode, but NOT both at same time + * Decision to enter D0-WOW or WOW is based on active interfaces + * + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param */ + A_UINT32 enable; /* 1 = enable, 0 = disable */ +} wmi_d0_wow_enable_disable_cmd_fixed_param; + +typedef enum extend_wow_type_e { + EXTWOW_TYPE_APP_TYPE1, /* extend wow type: only enable wakeup for app type1 */ + EXTWOW_TYPE_APP_TYPE2, /* extend wow type: only enable wakeup for app type2 */ + EXTWOW_TYPE_APP_TYPE1_2, /* extend wow type: enable wakeup for app type1&2 */ +} EXTWOW_TYPE; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals wmi_extwow_enable_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 type; + A_UINT32 wakeup_pin_num; +} wmi_extwow_enable_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals wmi_extwow_set_app_type1_params_cmd_fixed_param */ + A_UINT32 vdev_id; + wmi_mac_addr wakee_mac; + A_UINT8 ident[8]; + A_UINT8 passwd[16]; + A_UINT32 ident_len; + A_UINT32 passwd_len; +} wmi_extwow_set_app_type1_params_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals wmi_extwow_set_app_type2_params_cmd_fixed_param */ + A_UINT32 vdev_id; + + A_UINT8 rc4_key[16]; + A_UINT32 rc4_key_len; + + /** ip header parameter */ + A_UINT32 ip_id; /* NC id */ + A_UINT32 ip_device_ip; /* NC IP address */ + A_UINT32 ip_server_ip; /* Push server IP address */ + + /** tcp header parameter */ + A_UINT16 tcp_src_port; /* NC TCP port */ + A_UINT16 tcp_dst_port; /* Push server TCP port */ + A_UINT32 tcp_seq; + A_UINT32 tcp_ack_seq; + + A_UINT32 keepalive_init; /* Initial ping interval */ + A_UINT32 keepalive_min; /* Minimum ping interval */ + A_UINT32 keepalive_max; /* Maximum ping interval */ + A_UINT32 keepalive_inc; /* Increment of ping interval */ + + wmi_mac_addr gateway_mac; + A_UINT32 tcp_tx_timeout_val; + A_UINT32 tcp_rx_timeout_val; +} wmi_extwow_set_app_type2_params_cmd_fixed_param; + + + +#define WMI_RXERR_CRC 0x01 /* CRC error on frame */ +#define WMI_RXERR_DECRYPT 0x08 /* non-Michael decrypt error */ +#define WMI_RXERR_MIC 0x10 /* Michael MIC decrypt error */ +#define WMI_RXERR_KEY_CACHE_MISS 0x20 /* No/incorrect key matter in h/w */ + +typedef enum { + PKT_PWR_SAVE_PAID_MATCH = 0x0001, + PKT_PWR_SAVE_GID_MATCH = 0x0002, + PKT_PWR_SAVE_EARLY_TIM_CLEAR = 0x0004, + PKT_PWR_SAVE_EARLY_DTIM_CLEAR = 0x0008, + PKT_PWR_SAVE_EOF_PAD_DELIM = 0x0010, + PKT_PWR_SAVE_MACADDR_MISMATCH = 0x0020, + PKT_PWR_SAVE_DELIM_CRC_FAIL = 0x0040, + PKT_PWR_SAVE_GID_NSTS_ZERO = 0x0080, + PKT_PWR_SAVE_RSSI_CHECK = 0x0100, + PKT_PWR_SAVE_5G_EBT = 0x0200, + WMI_PKT_PWR_SAVE_MAX = 0x0400, +} WMI_PKT_PWR_SAVE_TYPE; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ftm_intg_cmd_fixed_param */ + A_UINT32 num_data; /** length in byte of data[]. */ + /* This structure is used to send Factory Test Mode [FTM] command + * from host to firmware for integrated chips which are binary blobs. + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field num_data. + */ +}wmi_ftm_intg_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ftm_intg_event_fixed_param */ + A_UINT32 num_data; /** length in byte of data[]. */ + /* This structure is used to receive Factory Test Mode [FTM] event + * from firmware to host for integrated chips which are binary blobs. + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field num_data. + */ +}wmi_ftm_intg_event_fixed_param; + +#define WMI_MAX_NS_OFFLOADS 2 +#define WMI_MAX_ARP_OFFLOADS 2 + +#define WMI_ARPOFF_FLAGS_VALID (1 << 0) /* the tuple entry is valid */ +#define WMI_ARPOFF_FLAGS_MAC_VALID (1 << 1) /* the target mac address is valid */ +#define WMI_ARPOFF_FLAGS_REMOTE_IP_VALID (1 << 2) /* remote IP field is valid */ + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE */ + A_UINT32 flags; /* flags */ + A_UINT8 target_ipaddr[4]; /* IPV4 addresses of the local node*/ + A_UINT8 remote_ipaddr[4]; /* source address of the remote node requesting the ARP (qualifier) */ + wmi_mac_addr target_mac; /* mac address for this tuple, if not valid, the local MAC is used */ +} WMI_ARP_OFFLOAD_TUPLE; + +#define WMI_NSOFF_FLAGS_VALID (1 << 0) /* the tuple entry is valid */ +#define WMI_NSOFF_FLAGS_MAC_VALID (1 << 1) /* the target mac address is valid */ +#define WMI_NSOFF_FLAGS_REMOTE_IP_VALID (1 << 2) /* remote IP field is valid */ + +#define WMI_NSOFF_MAX_TARGET_IPS 2 + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE */ + A_UINT32 flags; /* flags */ + /* NOTE: This size of array target_ipaddr[] cannot be changed without breaking WMI compatibility. */ + WMI_IPV6_ADDR target_ipaddr[WMI_NSOFF_MAX_TARGET_IPS]; /* IPV6 target addresses of the local node */ + WMI_IPV6_ADDR solicitation_ipaddr; /* multi-cast source IP addresses for receiving solicitations */ + WMI_IPV6_ADDR remote_ipaddr; /* address of remote node requesting the solicitation (qualifier) */ + wmi_mac_addr target_mac; /* mac address for this tuple, if not valid, the local MAC is used */ +} WMI_NS_OFFLOAD_TUPLE; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param */ + A_UINT32 flags; + A_UINT32 vdev_id; + /* Following this structure are the TLVs: + * WMI_NS_OFFLOAD_TUPLE ns_tuples[WMI_MAX_NS_OFFLOADS]; + * WMI_ARP_OFFLOAD_TUPLE arp_tuples[WMI_MAX_ARP_OFFLOADS]; + */ +} WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 pattern_id; + A_UINT32 timeout; + A_UINT32 length; + /* Following this would be the pattern + A_UINT8 pattern[] of length specifed by length + field in the structure. */ +} WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 pattern_id; +} WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_tid_addba_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Initiator (1) or Responder (0) for this aggregation */ + A_UINT32 initiator; + /** size of the negotiated window */ + A_UINT32 window_size; + /** starting sequence number (only valid for initiator) */ + A_UINT32 ssn; + /** timeout field represents the time to wait for Block Ack in + * initiator case and the time to wait for BAR in responder + * case. 0 represents no timeout. */ + A_UINT32 timeout; + /* BA policy: immediate ACK (0) or delayed ACK (1) */ + A_UINT32 policy; +} wmi_peer_tid_addba_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_peer_tid_delba_cmd */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Initiator (1) or Responder (0) for this aggregation */ + A_UINT32 initiator; +} wmi_peer_tid_delba_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tx_addba_complete_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Event status */ + A_UINT32 status; +} wmi_tx_addba_complete_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tx_delba_complete_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** Tid number */ + A_UINT32 tid; + /** Event status */ + A_UINT32 status; +} wmi_tx_delba_complete_event_fixed_param; +/* + * Structure to request sequence numbers for a given + * peer station on different TIDs. The TIDs are + * indicated in the tidBitMap, tid 0 would + * be represented by LSB bit 0. tid 1 would be + * represented by LSB bit 1 etc. + * The target will retrieve the current sequence + * numbers for the peer on all the TIDs requested + * and send back a response in a WMI event. + */ +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals + WMITLV_TAG_STRUC_wmi_ba_req_ssn_cmd_sub_struct_param */ + wmi_mac_addr peer_macaddr; + A_UINT32 tidBitmap; +} wmi_ba_req_ssn; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals + WMITLV_TAG_STRUC_wmi_ba_req_ssn_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** Number of requested SSN In the TLV wmi_ba_req_ssn[] */ + A_UINT32 num_ba_req_ssn; +/* Following this struc are the TLV's: + * wmi_ba_req_ssn ba_req_ssn_list; All peer and tidBitMap for which the ssn is requested + */ +} wmi_ba_req_ssn_cmd_fixed_param; + +/* + * Max transmit categories + * + * Note: In future if we need to increase WMI_MAX_TC definition + * It would break the compatibility for WMI_BA_RSP_SSN_EVENTID. + */ +#define WMI_MAX_TC 8 + +/* + * Structure to send response sequence numbers + * for a give peer and tidmap. + */ +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals + WMITLV_TAG_STRUC_wmi_ba_req_ssn_event_sub_struct_param */ + wmi_mac_addr peer_macaddr; + /* A boolean to indicate if ssn is present */ + A_UINT32 ssn_present_for_tid[WMI_MAX_TC]; + /* The ssn from target, valid only if + * ssn_present_for_tid[tidn] equals 1 + */ + A_UINT32 ssn_for_tid[WMI_MAX_TC]; +} wmi_ba_event_ssn; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals + WMITLV_TAG_STRUC_wmi_ba_rsp_ssn_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** Event status, success or failure of the overall operation */ + A_UINT32 status; + /** Number of requested SSN In the TLV wmi_ba_req_ssn[] */ + A_UINT32 num_ba_event_ssn; +/* Following this struc are the TLV's: + * wmi_ba_event_ssn ba_event_ssn_list; All peer and tidBitMap for which the ssn is requested + */ +} wmi_ba_rsp_ssn_event_fixed_param; + + +enum wmi_aggr_state_req_type { + WMI_DISABLE_AGGREGATION, + WMI_ENABLE_AGGREGATION +}; + +/* + * This event is generated by the COEX module + * when esco call is begins the coex module in fw genrated this event to host to + * disable the RX aggregation and after completion of the esco call fw will indicate to + * enable back the Rx aggregation . +*/ + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_aggr_state_trig_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** req_type contains values from enum + * wmi_aggr_state_req_type; 0 (disable) 1(enable) */ + A_UINT32 req_type; +}wmi_aggr_state_trig_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_install_key_complete_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** MAC address used for installing */ + wmi_mac_addr peer_macaddr; + /** key index */ + A_UINT32 key_ix; + /** key flags */ + A_UINT32 key_flags; + /** Event status */ + A_UINT32 status; +} wmi_vdev_install_key_complete_event_fixed_param; + +typedef enum _WMI_NLO_AUTH_ALGORITHM { + WMI_NLO_AUTH_ALGO_80211_OPEN = 1, + WMI_NLO_AUTH_ALGO_80211_SHARED_KEY = 2, + WMI_NLO_AUTH_ALGO_WPA = 3, + WMI_NLO_AUTH_ALGO_WPA_PSK = 4, + WMI_NLO_AUTH_ALGO_WPA_NONE = 5, + WMI_NLO_AUTH_ALGO_RSNA = 6, + WMI_NLO_AUTH_ALGO_RSNA_PSK = 7, +} WMI_NLO_AUTH_ALGORITHM; + +typedef enum _WMI_NLO_CIPHER_ALGORITHM { + WMI_NLO_CIPHER_ALGO_NONE = 0x00, + WMI_NLO_CIPHER_ALGO_WEP40 = 0x01, + WMI_NLO_CIPHER_ALGO_TKIP = 0x02, + WMI_NLO_CIPHER_ALGO_CCMP = 0x04, + WMI_NLO_CIPHER_ALGO_WEP104 = 0x05, + WMI_NLO_CIPHER_ALGO_BIP = 0x06, + WMI_NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, + WMI_NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, + WMI_NLO_CIPHER_ALGO_WEP = 0x101, +} WMI_NLO_CIPHER_ALGORITHM; + +/* SSID broadcast type passed in NLO params */ +typedef enum _WMI_NLO_SSID_BcastNwType +{ + WMI_NLO_BCAST_UNKNOWN = 0, + WMI_NLO_BCAST_NORMAL = 1, + WMI_NLO_BCAST_HIDDEN = 2, +} WMI_NLO_SSID_BcastNwType; + +#define WMI_NLO_MAX_SSIDS 16 +#define WMI_NLO_MAX_CHAN 48 + +#define WMI_NLO_CONFIG_STOP (0x1 << 0) +#define WMI_NLO_CONFIG_START (0x1 << 1) +#define WMI_NLO_CONFIG_RESET (0x1 << 2) +#define WMI_NLO_CONFIG_SLOW_SCAN (0x1 << 4) +#define WMI_NLO_CONFIG_FAST_SCAN (0x1 << 5) +#define WMI_NLO_CONFIG_SSID_HIDE_EN (0x1 << 6) +/* This bit is used to indicate if EPNO or supplicant PNO is enabled. Only one of them can be enabled at a given time */ +#define WMI_NLO_CONFIG_ENLO (0x1 << 7) + +/* Whether directed scan needs to be performed (for hidden SSIDs) */ +#define WMI_ENLO_FLAG_DIRECTED_SCAN 1 +/* Whether PNO event shall be triggered if the network is found on A band */ +#define WMI_ENLO_FLAG_A_BAND 2 +/* Whether PNO event shall be triggered if the network is found on G band */ +#define WMI_ENLO_FLAG_G_BAND 4 +/* Whether strict matching is required (i.e. firmware shall not match on the entire SSID) */ +#define WMI_ENLO_FLAG_STRICT_MATCH 8 + +/* Code for matching the beacon AUTH IE - additional codes TBD */ +/* open */ +#define WMI_ENLO_AUTH_CODE_OPEN 1 +/* WPA_PSK or WPA2PSK */ +#define WMI_ENLO_AUTH_CODE_PSK 2 +/* any EAPOL */ +#define WMI_ENLO_AUTH_CODE_EAPOL 4 + +/* NOTE: wmi_nlo_ssid_param structure can't be changed without breaking the compatibility */ +typedef struct wmi_nlo_ssid_param +{ + A_UINT32 valid; + wmi_ssid ssid; +} wmi_nlo_ssid_param; + +/* NOTE: wmi_nlo_enc_param structure can't be changed without breaking the compatibility */ +typedef struct wmi_nlo_enc_param +{ + A_UINT32 valid; + A_UINT32 enc_type; +} wmi_nlo_enc_param; + +/* NOTE: wmi_nlo_auth_param structure can't be changed without breaking the compatibility */ +typedef struct wmi_nlo_auth_param +{ + A_UINT32 valid; + A_UINT32 auth_type; +} wmi_nlo_auth_param; + +/* NOTE: wmi_nlo_bcast_nw_param structure can't be changed without breaking the compatibility */ +typedef struct wmi_nlo_bcast_nw_param +{ + A_UINT32 valid; + /* If WMI_NLO_CONFIG_EPNO is not set. Supplicant PNO is enabled. The value should be true/false + Otherwise EPNO is enabled. bcast_nw_type would be used as a bit flag contains WMI_ENLO_FLAG_XXX */ + A_UINT32 bcast_nw_type; +} wmi_nlo_bcast_nw_param; + +/* NOTE: wmi_nlo_rssi_param structure can't be changed without breaking the compatibility */ +typedef struct wmi_nlo_rssi_param +{ + A_UINT32 valid; + A_INT32 rssi; +} wmi_nlo_rssi_param; + +typedef struct nlo_configured_parameters { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_nlo_configured_parameters */ + wmi_nlo_ssid_param ssid; + wmi_nlo_enc_param enc_type; + wmi_nlo_auth_param auth_type; + wmi_nlo_rssi_param rssi_cond; + wmi_nlo_bcast_nw_param bcast_nw_type; /* indicates if the SSID is hidden or not */ +} nlo_configured_parameters; + +typedef struct wmi_nlo_config { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param */ + A_UINT32 flags; + A_UINT32 vdev_id; + A_UINT32 fast_scan_max_cycles; + A_UINT32 active_dwell_time; + A_UINT32 passive_dwell_time; /* PDT in msecs */ + A_UINT32 probe_bundle_size; + A_UINT32 rest_time; /* ART = IRT */ + A_UINT32 max_rest_time; /* Max value that can be reached after SBM */ + A_UINT32 scan_backoff_multiplier; /* SBM */ + A_UINT32 fast_scan_period; /* SCBM */ + A_UINT32 slow_scan_period; /* specific to windows */ + A_UINT32 no_of_ssids; + A_UINT32 num_of_channels; + A_UINT32 delay_start_time; /* NLO scan start delay time in milliseconds */ + /* The TLVs will follow. + * nlo_configured_parameters nlo_list[]; + * A_UINT32 channel_list[]; + */ + +} wmi_nlo_config_cmd_fixed_param; + +typedef struct wmi_nlo_event +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nlo_event */ + A_UINT32 vdev_id; +}wmi_nlo_event; + + +/* WMI_PASSPOINT_CONFIG_SET + * Sets a list for passpoint networks for PNO purposes; + * it should be matched against any passpoint networks found + * during regular PNO scan. + */ +#define WMI_PASSPOINT_CONFIG_SET (0x1 << 0) +/* WMI_PASSPOINT_CONFIG_RESET + * Reset passpoint network list - + * no Passpoint networks should be matched after this. + */ +#define WMI_PASSPOINT_CONFIG_RESET (0x1 << 1) + +#define PASSPOINT_REALM_LEN 256 +#define PASSPOINT_ROAMING_CONSORTIUM_ID_LEN 5 +#define PASSPOINT_ROAMING_CONSORTIUM_ID_NUM 16 +#define PASSPOINT_PLMN_ID_LEN 3 +#define PASSPOINT_PLMN_ID_ALLOC_LEN /* round up to A_UINT32 boundary */ \ + (((PASSPOINT_PLMN_ID_LEN + 3) >> 2) << 2) + +/* + * Confirm PASSPOINT_REALM_LEN is a multiple of 4, so the + * A_UINT8 realm[PASSPOINT_REALM_LEN] + * array will end on a 4-byte boundary. + * (This 4-byte alignment simplifies endianness-correction byte swapping.) + */ +A_COMPILE_TIME_ASSERT( + check_passpoint_realm_size, + (PASSPOINT_REALM_LEN % sizeof(A_UINT32)) == 0); + +/* + * Confirm the product of PASSPOINT_ROAMING_CONSORTIUM_ID_NUM and + * PASSPOINT_ROAMING_CONSORTIUM_ID_LEN is a multiple of 4, so the + * roaming_consortium_ids array below will end on a 4-byte boundary. + * (This 4-byte alignment simplifies endianness-correction byte swapping.) + */ +A_COMPILE_TIME_ASSERT( + check_passpoint_roaming_consortium_ids_size, + ((PASSPOINT_ROAMING_CONSORTIUM_ID_NUM*PASSPOINT_ROAMING_CONSORTIUM_ID_LEN) % sizeof(A_UINT32)) == 0); + +/* wildcard ID to allow an action (reset) to apply to all networks */ +#define WMI_PASSPOINT_NETWORK_ID_WILDCARD 0xFFFFFFFF +typedef struct wmi_passpoint_config { + A_UINT32 tlv_header; /* TLV tag and len; tag equals wmi_passpoint_config_cmd_fixed_param */ + /* (network) id + * identifier of the matched network, report this in event + * This id can be a wildcard (WMI_PASSPOINT_NETWORK_ID_WILDCARD) + * that indicates the action should be applied to all networks. + * Currently, the only action that is applied to all networks is "reset". + * If a non-wildcard ID is specified, that particular network is configured. + * If a wildcard ID is specified, all networks are reset. + */ + A_UINT32 id; + A_UINT32 req_id; + A_UINT8 realm[PASSPOINT_REALM_LEN]; /*null terminated UTF8 encoded realm, 0 if unspecified*/ + A_UINT8 roaming_consortium_ids[PASSPOINT_ROAMING_CONSORTIUM_ID_NUM][PASSPOINT_ROAMING_CONSORTIUM_ID_LEN]; /*roaming consortium ids to match, 0s if unspecified*/ + /*This would be bytes-stream as same as defition of realm id in 802.11 standard*/ + A_UINT8 plmn[PASSPOINT_PLMN_ID_ALLOC_LEN]; /*PLMN id mcc/mnc combination as per rules, 0s if unspecified */ +} wmi_passpoint_config_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals wmi_passpoint_event_hdr */ + A_UINT32 id; /* identifier of the matched network */ + A_UINT32 vdev_id; + A_UINT32 timestamp; /* time since boot (in microsecond) when the result was retrieved*/ + wmi_ssid ssid; + wmi_mac_addr bssid; /* bssid of the network */ + A_UINT32 channel_mhz; /* channel frequency in MHz */ + A_UINT32 rssi; /* rssi value */ + A_UINT32 rtt; /* timestamp in nanoseconds*/ + A_UINT32 rtt_sd; /* standard deviation in rtt */ + A_UINT32 beacon_period; /* beacon advertised in the beacon */ + A_UINT32 capability; /* capabilities advertised in the beacon */ + A_UINT32 ie_length; /* size of the ie_data blob */ + A_UINT32 anqp_length; /* length of ANQP blob */ +/* Following this structure is the byte stream of ie data of length ie_buf_len: + * A_UINT8 ie_data[]; // length in byte given by field ie_length, blob of ie data in beacon + * A_UINT8 anqp_ie[]; // length in byte given by field anqp_len, blob of anqp data of IE + * Implicitly, combing ie_data and anqp_ie into a single bufp, and the bytes stream of each ie should be same as BEACON/Action-frm by 802.11 spec. + */ +} wmi_passpoint_event_hdr; + + +#define GTK_OFFLOAD_OPCODE_MASK 0xFF000000 +/** Enable GTK offload, and provided parameters KEK,KCK and replay counter values */ +#define GTK_OFFLOAD_ENABLE_OPCODE 0x01000000 +/** Disable GTK offload */ +#define GTK_OFFLOAD_DISABLE_OPCODE 0x02000000 +/** Read GTK offload parameters, generates WMI_GTK_OFFLOAD_STATUS_EVENT */ +#define GTK_OFFLOAD_REQUEST_STATUS_OPCODE 0x04000000 +enum wmi_chatter_mode { + /* Chatter enter/exit happens + * automatically based on preset + * params + */ + WMI_CHATTER_MODE_AUTO, + /* Chatter enter is triggered + * manually by the user + */ + WMI_CHATTER_MODE_MANUAL_ENTER, + /* Chatter exit is triggered + * manually by the user + */ + WMI_CHATTER_MODE_MANUAL_EXIT, + /* Placeholder max value, always last*/ + WMI_CHATTER_MODE_MAX +}; + +enum wmi_chatter_query_type { + /*query coalescing filter match counter*/ + WMI_CHATTER_QUERY_FILTER_MATCH_CNT, + WMI_CHATTER_QUERY_MAX +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_set_mode_cmd_fixed_param */ + A_UINT32 chatter_mode; +} wmi_chatter_set_mode_cmd_fixed_param; + +/** maximum number of filter supported*/ +#define CHATTER_MAX_COALESCING_RULES 11 +/** maximum number of field tests per filter*/ +#define CHATTER_MAX_FIELD_TEST 5 +/** maximum field length in number of DWORDS*/ +#define CHATTER_MAX_TEST_FIELD_LEN32 2 + +/** field test kinds*/ +#define CHATTER_COALESCING_TEST_EQUAL 1 +#define CHATTER_COALESCING_TEST_MASKED_EQUAL 2 +#define CHATTER_COALESCING_TEST_NOT_EQUAL 3 + +/** packet type*/ +#define CHATTER_COALESCING_PKT_TYPE_UNICAST (1 << 0) +#define CHATTER_COALESCING_PKT_TYPE_MULTICAST (1 << 1) +#define CHATTER_COALESCING_PKT_TYPE_BROADCAST (1 << 2) + +/** coalescing field test*/ +typedef struct _chatter_pkt_coalescing_hdr_test { + /** offset from start of mac header, for windows native wifi host driver + * should assume standard 802.11 frame format without QoS info and address4 + * FW would account for any non-stand fields for final offset value. + */ + A_UINT32 offset; + A_UINT32 length; /* length of test field*/ + A_UINT32 test; /*equal, not equal or masked equal*/ + A_UINT32 mask[CHATTER_MAX_TEST_FIELD_LEN32]; /*mask byte stream*/ + A_UINT32 value[CHATTER_MAX_TEST_FIELD_LEN32]; /*value byte stream*/ +} chatter_pkt_coalescing_hdr_test; + +/** packet coalescing filter*/ +typedef struct _chatter_pkt_coalescing_filter { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_pkt_coalescing_filter */ + A_UINT32 filter_id; /*unique id assigned by OS*/ + A_UINT32 max_coalescing_delay; /*max miliseconds 1st pkt can be hold*/ + A_UINT32 pkt_type; /*unicast/multicast/broadcast*/ + A_UINT32 num_of_test_field; /*number of field test in table*/ + chatter_pkt_coalescing_hdr_test test_fields[CHATTER_MAX_FIELD_TEST]; /*field test tbl*/ +} chatter_pkt_coalescing_filter; + +/** packet coalescing filter add command*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_coalescing_add_filter_cmd_fixed_param */ + A_UINT32 num_of_filters; + /* Following this tlv, there comes an array of structure of type chatter_pkt_coalescing_filter + chatter_pkt_coalescing_filter rx_filter[1];*/ +} wmi_chatter_coalescing_add_filter_cmd_fixed_param; +/** packet coalescing filter delete command*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_coalescing_delete_filter_cmd_fixed_param */ + A_UINT32 filter_id; /*filter id which will be deleted*/ +} wmi_chatter_coalescing_delete_filter_cmd_fixed_param; +/** packet coalescing query command*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_coalescing_query_cmd_fixed_param */ + A_UINT32 type; /*type of query*/ +} wmi_chatter_coalescing_query_cmd_fixed_param; +/** chatter query reply event*/ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_chatter_query_reply_event_fixed_param */ + A_UINT32 type; /*query type*/ + A_UINT32 filter_match_cnt; /*coalescing filter match counter*/ +} wmi_chatter_query_reply_event_fixed_param; + +/* NOTE: This constants GTK_OFFLOAD_KEK_BYTES, GTK_OFFLOAD_KCK_BYTES, and GTK_REPLAY_COUNTER_BYTES + * cannot be changed without breaking WMI compatibility. */ +#define GTK_OFFLOAD_KEK_BYTES 16 +#define GTK_OFFLOAD_KCK_BYTES 16 +/* NOTE: GTK_REPLAY_COUNTER_BYTES, WMI_MAX_KEY_LEN, IGTK_PN_SIZE cannot be changed in the future without breaking WMI compatibility */ +#define GTK_REPLAY_COUNTER_BYTES 8 +#define WMI_MAX_KEY_LEN 32 +#define IGTK_PN_SIZE 6 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param */ + A_UINT32 vdev_id; /** unique id identifying the VDEV */ + A_UINT32 flags; /* status flags */ + A_UINT32 refresh_cnt; /* number of successful GTK refresh exchanges since last SET operation */ + A_UINT8 replay_counter[GTK_REPLAY_COUNTER_BYTES]; /* current replay counter */ + A_UINT8 igtk_keyIndex; /* Use if IGTK_OFFLOAD is defined */ + A_UINT8 igtk_keyLength; /* Use if IGTK_OFFLOAD is defined */ + A_UINT8 igtk_keyRSC[IGTK_PN_SIZE]; /* key replay sequence counter */ /* Use if IGTK_OFFLOAD is defined */ + A_UINT8 igtk_key[WMI_MAX_KEY_LEN]; /* Use if IGTK_OFFLOAD is defined */ +} WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param */ + A_UINT32 vdev_id; /** unique id identifying the VDEV */ + A_UINT32 flags; /* control flags, GTK offload command use high byte */ + /* The size of following 3 arrays cannot be changed without breaking WMI compatibility. */ + A_UINT8 KEK[GTK_OFFLOAD_KEK_BYTES]; /* key encryption key */ + A_UINT8 KCK[GTK_OFFLOAD_KCK_BYTES]; /* key confirmation key */ + A_UINT8 replay_counter[GTK_REPLAY_COUNTER_BYTES]; /* replay counter for re-key */ +}WMI_GTK_OFFLOAD_CMD_fixed_param; + +typedef enum { + WMI_STA_KEEPALIVE_METHOD_NULL_FRAME = 1, /* 802.11 NULL frame */ + WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE = 2, /* ARP response */ + WMI_STA_KEEPALIVE_METHOD_ETHERNET_LOOPBACK = 3, /*ETHERNET LOOPBACK*/ + WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST = 4, /* gratuitous ARP req*/ +} WMI_STA_KEEPALIVE_METHOD; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE */ + WMI_IPV4_ADDR sender_prot_addr; /* Sender protocol address */ + WMI_IPV4_ADDR target_prot_addr; /* Target protocol address */ + wmi_mac_addr dest_mac_addr; /* destination MAC address */ +} WMI_STA_KEEPALVE_ARP_RESPONSE; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 enable; /* 1 - Enable, 0 - disable */ + A_UINT32 method; /* keep alive method */ + A_UINT32 interval; /* time interval in seconds */ + /* + * NOTE: following this structure is the TLV for ARP Resonse: + * WMI_STA_KEEPALVE_ARP_RESPONSE arp_resp; // ARP response + */ +} WMI_STA_KEEPALIVE_CMD_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 action; +} WMI_VDEV_WNM_SLEEPMODE_CMD_fixed_param; +typedef WMI_VDEV_WNM_SLEEPMODE_CMD_fixed_param WMI_STA_WNMSLEEP_CMD; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_set_keepalive_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 keepaliveInterval; /* seconds */ + A_UINT32 keepaliveMethod; +} wmi_vdev_set_keepalive_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_cmd_fixed_param */ + A_UINT32 vdev_id; +} wmi_vdev_get_keepalive_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_get_keepalive_event_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 keepaliveInterval; /* seconds */ + A_UINT32 keepaliveMethod; /* seconds */ +} wmi_vdev_get_keepalive_event_fixed_param; + +#define IPSEC_NATKEEPALIVE_FILTER_DISABLE 0 +#define IPSEC_NATKEEPALIVE_FILTER_ENABLE 1 + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 action; +} WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param; + +typedef WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 mcc_tbttmode; + wmi_mac_addr mcc_bssid; +} wmi_vdev_mcc_set_tbtt_mode_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; /* home vdev id */ + A_UINT32 meas_token; /* from measure request frame */ + A_UINT32 dialog_token; + A_UINT32 number_bursts; /* zero keep sending until cancel, bigger than 0 means times e.g. 1,2 */ + A_UINT32 burst_interval; /* unit in mill seconds, interval between consecutive burst*/ + A_UINT32 burst_cycle; /* times cycle through within one burst */ + A_UINT32 tx_power; /* for path frame */ + A_UINT32 off_duration; /* uint in mill seconds, channel off duraiton for path loss frame sending */ + wmi_mac_addr dest_mac; /* multicast DA, for path loss frame */ + A_UINT32 num_chans; +} wmi_vdev_plmreq_start_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 meas_token; /* same value from req*/ +} wmi_vdev_plmreq_stop_cmd_fixed_param; + +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param */ + A_UINT32 tlv_header; + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* enable/disable NoA */ + A_UINT32 enable; + /** number of NoA desc. In the TLV noa_descriptor[] */ + A_UINT32 num_noa; + /** + * TLV (tag length value ) paramerters follow the pattern structure. + * TLV contain NoA desc with num of num_noa + */ +} wmi_p2p_set_noa_cmd_fixed_param; + +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param */ + A_UINT32 tlv_header; + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* Identify the wlan module */ + A_UINT32 module_id; + /* Num of test arguments passed */ + A_UINT32 num_args; +/** + * TLV (tag length value ) parameters follow the wmi_roam_chan_list + * structure. The TLV's are: + * A_UINT32 args[]; + **/ +} wmi_unit_test_cmd_fixed_param; + +/** Roaming offload SYNCH_COMPLETE from host when host finished sync logic + * after it received WMI_ROAM_SYNCH_EVENTID. + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; +} wmi_roam_synch_complete_fixed_param; + + +typedef enum { + RECOVERY_SIM_ASSERT = 0x01, + RECOVERY_SIM_NO_DETECT = 0x02, + RECOVERY_SIM_CTR_EP_FULL = 0x03, + RECOVERY_SIM_EMPTY_POINT = 0x04, + RECOVERY_SIM_STACK_OV = 0x05, + RECOVERY_SIM_INFINITE_LOOP = 0x06, + RECOVERY_SIM_PCIE_LINKDOWN = 0x07, + RECOVERY_SIM_SELF_RECOVERY = 0x08, +} RECOVERY_SIM_TYPE; + +/* WMI_FORCE_FW_HANG_CMDID */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param */ + A_UINT32 type; /*0:unused 1: ASSERT, 2: not respond detect command,3: simulate ep-full(),4:...*/ + A_UINT32 delay_time_ms; /*0xffffffff means the simulate will delay for random time (0 ~0xffffffff ms)*/ +}WMI_FORCE_FW_HANG_CMD_fixed_param; +#define WMI_MCAST_FILTER_SET 1 +#define WMI_MCAST_FILTER_DELETE 2 +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 index; + A_UINT32 action; + wmi_mac_addr mcastbdcastaddr; +} WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param; + +/* GPIO Command and Event data structures */ + +/* WMI_GPIO_CONFIG_CMDID */ +enum { + WMI_GPIO_PULL_NONE, + WMI_GPIO_PULL_UP, + WMI_GPIO_PULL_DOWN, +}; + +enum { + WMI_GPIO_INTTYPE_DISABLE, + WMI_GPIO_INTTYPE_RISING_EDGE, + WMI_GPIO_INTTYPE_FALLING_EDGE, + WMI_GPIO_INTTYPE_BOTH_EDGE, + WMI_GPIO_INTTYPE_LEVEL_LOW, + WMI_GPIO_INTTYPE_LEVEL_HIGH +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_gpio_config_cmd_fixed_param */ + A_UINT32 gpio_num; /* GPIO number to be setup */ + A_UINT32 input; /* 0 - Output/ 1 - Input */ + A_UINT32 pull_type; /* Pull type defined above */ + A_UINT32 intr_mode; /* Interrupt mode defined above (Input) */ +} wmi_gpio_config_cmd_fixed_param; + +/* WMI_GPIO_OUTPUT_CMDID */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_gpio_output_cmd_fixed_param */ + A_UINT32 gpio_num; /* GPIO number to be setup */ + A_UINT32 set; /* Set the GPIO pin*/ +} wmi_gpio_output_cmd_fixed_param; + +/* WMI_GPIO_INPUT_EVENTID */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_gpio_input_event_fixed_param */ + A_UINT32 gpio_num; /* GPIO number which changed state */ +} wmi_gpio_input_event_fixed_param; + +/* WMI_P2P_DISC_EVENTID */ +enum { + P2P_DISC_SEARCH_PROB_REQ_HIT = 0, /* prob req hit the p2p find pattern */ + P2P_DISC_SEARCH_PROB_RESP_HIT, /* prob resp hit the p2p find pattern */ +}; + +enum { + P2P_DISC_MODE_SEARCH = 0, /* do search when p2p find offload*/ + P2P_DISC_MODE_LISTEN, /* do listen when p2p find offload*/ + P2P_DISC_MODE_AUTO, /* do listen and search when p2p find offload*/ +}; + +enum { + P2P_DISC_PATTERN_TYPE_BSSID = 0, /* BSSID pattern */ + P2P_DISC_PATTERN_TYPE_DEV_NAME, /* device name pattern */ +}; + +typedef struct { + A_UINT32 vdev_id; + A_UINT32 reason; /* P2P DISC wake up reason*/ +} wmi_p2p_disc_event; + +typedef WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param WOW_EVENT_INFO_SECTION_GTKIGTK; + +typedef enum { + WMI_FAKE_TXBFER_SEND_NDPA, + WMI_FAKE_TXBFER_SEND_MU, + WMI_FAKE_TXBFER_NDPA_FBTYPE, + WMI_FAKE_TXBFER_NDPA_NCIDX, + WMI_FAKE_TXBFER_NDPA_POLL, + WMI_FAKE_TXBFER_NDPA_BW, + WMI_FAKE_TXBFER_NDPA_PREAMBLE, + WMI_FAKE_TXBFER_NDPA_RATE, + WMI_FAKE_TXBFER_NDP_BW, + WMI_FAKE_TXBFER_NDP_NSS, + WMI_TXBFEE_ENABLE_UPLOAD_H, + WMI_TXBFEE_ENABLE_CAPTURE_H, + WMI_TXBFEE_SET_CBF_TBL, + WMI_TXBFEE_CBF_TBL_LSIG, + WMI_TXBFEE_CBF_TBL_SIGA1, + WMI_TXBFEE_CBF_TBL_SIGA2, + WMI_TXBFEE_CBF_TBL_SIGB, + WMI_TXBFEE_CBF_TBL_PAD, + WMI_TXBFEE_CBF_TBL_DUR, + WMI_TXBFEE_SU_NCIDX, + WMI_TXBFEE_CBIDX, + WMI_TXBFEE_NGIDX, +} WMI_TXBF_PARAM_ID; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_txbf_cmd_fixed_param */ + /** parameter id */ + A_UINT32 param_id; + /** parameter value */ + A_UINT32 param_value; +} wmi_txbf_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_upload_h_hdr */ + A_UINT32 h_length; + A_UINT32 cv_length; + /* This TLV is followed by array of bytes: + * // h_cv info buffer + * A_UINT8 bufp[]; + */ +} wmi_upload_h_hdr; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_capture_h_event_hdr */ + A_UINT32 svd_num; + A_UINT32 tone_num; + A_UINT32 reserved; +} wmi_capture_h_event_hdr; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_avoid_freq_range_desc */ + A_UINT32 start_freq; //start frequency, not channel center freq + A_UINT32 end_freq; //end frequency +} wmi_avoid_freq_range_desc; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_avoid_freq_ranges_event_fixed_param */ + //bad channel range count, multi range is allowed, 0 means all channel clear + A_UINT32 num_freq_ranges; + + /* The TLVs will follow. + * multi range with num_freq_ranges, LTE advance multi carrier, CDMA,etc + * wmi_avoid_freq_range_desc avd_freq_range[]; // message buffer, NULL terminated + */ +} wmi_avoid_freq_ranges_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_gtk_rekey_fail_event_fixed_param */ + /** Reserved for future use */ + A_UINT32 reserved0; + A_UINT32 vdev_id; +} wmi_gtk_rekey_fail_event_fixed_param; + +enum wmm_ac_downgrade_policy { + WMM_AC_DOWNGRADE_DEPRIO, + WMM_AC_DOWNGRADE_DROP, + WMM_AC_DOWNGRADE_INVALID, +}; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 cwmin; + A_UINT32 cwmax; + A_UINT32 aifs; + A_UINT32 txoplimit; + A_UINT32 acm; + A_UINT32 no_ack; +} wmi_wmm_vparams; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + wmi_wmm_vparams wmm_params[4]; /* 0 be, 1 bk, 2 vi, 3 vo */ +} wmi_vdev_set_wmm_params_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 gtxRTMask[2]; /* for HT and VHT rate masks */ + A_UINT32 userGtxMask; /* host request for GTX mask */ + A_UINT32 gtxPERThreshold; /* default: 10% */ + A_UINT32 gtxPERMargin; /* default: 2% */ + A_UINT32 gtxTPCstep; /* default: 1 */ + A_UINT32 gtxTPCMin; /* default: 5 */ + A_UINT32 gtxBWMask; /* 20/40/80/160 Mhz */ +} wmi_vdev_set_gtx_params_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 ac; + A_UINT32 medium_time_us; /* per second unit, the Admitted time granted, unit in micro seconds */ + A_UINT32 downgrade_type; +} wmi_vdev_wmm_addts_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 ac; +} wmi_vdev_wmm_delts_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_dfs_enable_cmd_fixed_param */ + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_pdev_dfs_enable_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_dfs_disable_cmd_fixed_param */ + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_pdev_dfs_disable_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param + */ + A_UINT32 tlv_header; + + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_dfs_phyerr_filter_ena_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param + */ + A_UINT32 tlv_header; + /** Reserved for future use */ + A_UINT32 reserved0; +} wmi_dfs_phyerr_filter_dis_cmd_fixed_param; + +/** TDLS COMMANDS */ + +/* WMI_TDLS_SET_STATE_CMDID */ +/* TDLS State */ +enum wmi_tdls_state { + /** TDLS disable */ + WMI_TDLS_DISABLE, + /** TDLS enabled - no firmware connection tracking/notifications */ + WMI_TDLS_ENABLE_PASSIVE, + /** TDLS enabled - with firmware connection tracking/notifications */ + WMI_TDLS_ENABLE_ACTIVE, +}; + +/* TDLS Options */ +#define WMI_TDLS_OFFCHAN_EN (1 << 0) /** TDLS Off Channel support */ +#define WMI_TDLS_BUFFER_STA_EN (1 << 1) /** TDLS Buffer STA support */ +#define WMI_TDLS_SLEEP_STA_EN (1 << 2) /** TDLS Sleep STA support (not currently supported) */ + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** Enable/Disable TDLS (wmi_tdls_state) */ + A_UINT32 state; + /** Duration (in ms) over which to calculate tx threshold and rate values */ + A_UINT32 notification_interval_ms; + /** number of packets OVER which notify/suggest TDLS Discovery: + * if current tx pps counter / notification interval >= threshold + * then a notification will be sent to host to advise TDLS Discovery */ + A_UINT32 tx_discovery_threshold; + /** number of packets UNDER which notify/suggest TDLS Teardown: + * if current tx pps counter / notification interval < threshold + * then a notification will be sent to host to advise TDLS Tear down */ + A_UINT32 tx_teardown_threshold; + /** Absolute RSSI value under which notify/suggest TDLS Teardown */ + A_INT32 rssi_teardown_threshold; + /** Peer RSSI < (AP RSSI + delta) will trigger a teardown */ + A_INT32 rssi_delta; + /** TDLS Option Control + * Off-Channel, Buffer STA, (later)Sleep STA support */ + A_UINT32 tdls_options; + /* Buffering time in number of beacon intervals */ + A_UINT32 tdls_peer_traffic_ind_window; + /* Wait time for PTR frame */ + A_UINT32 tdls_peer_traffic_response_timeout_ms; + /* Self PUAPSD mask */ + A_UINT32 tdls_puapsd_mask; + /* Inactivity timeout */ + A_UINT32 tdls_puapsd_inactivity_time_ms; + /* Max of rx frame during SP */ + A_UINT32 tdls_puapsd_rx_frame_threshold; +} wmi_tdls_set_state_cmd_fixed_param; + +/* WMI_TDLS_PEER_UPDATE_CMDID */ + +enum wmi_tdls_peer_state { + /** tx peer TDLS link setup now starting, traffic to DA should be + * paused (except TDLS frames) until state is moved to CONNECTED (or + * TEARDOWN on setup failure) */ + WMI_TDLS_PEER_STATE_PEERING, + /** tx peer TDLS link established, running (all traffic to DA unpaused) */ + WMI_TDLS_PEER_STATE_CONNECTED, + /** tx peer TDLS link tear down started (link paused, any frames + * queued for DA will be requeued back through the AP)*/ + WMI_TDLS_PEER_STATE_TEARDOWN, +}; + +/* NB: These defines are fixed, and cannot be changed without breaking WMI compatibility */ +#define WMI_TDLS_MAX_SUPP_OPER_CLASSES 32 +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities */ + A_UINT32 tlv_header; + /* Peer's QoS Info - for U-APSD */ + /* AC FLAGS - accessed through macros below */ + /* Ack, SP, More Data Ack - accessed through macros below */ + A_UINT32 peer_qos; + /*TDLS Peer's U-APSD Buffer STA Support*/ + A_UINT32 buff_sta_support; + /*TDLS off channel related params */ + A_UINT32 off_chan_support; + A_UINT32 peer_curr_operclass; + A_UINT32 self_curr_operclass; + /* Number of channels available for off channel operation */ + A_UINT32 peer_chan_len; + A_UINT32 peer_operclass_len; + A_UINT8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES]; + /* Is peer initiator or responder of TDLS setup request */ + A_UINT32 is_peer_responder; + /* Preferred off channel number as configured by user */ + A_UINT32 pref_offchan_num; + /* Preferred off channel bandwidth as configured by user */ + A_UINT32 pref_offchan_bw; + + /** Followed by the variable length TLV peer_chan_list: + * wmi_channel peer_chan_list[]. + * Array size would be peer_chan_len. + * This array is intersected channels which is supported by both peer + * and DUT. freq1 in chan_info shall be same as mhz, freq2 shall be 0. + * FW shall compute BW for an offchan based on peer's ht/vht cap + * received in peer_assoc cmd during change STA operation + */ +} wmi_tdls_peer_capabilities; + +#define WMI_TDLS_QOS_VO_FLAG 0 +#define WMI_TDLS_QOS_VI_FLAG 1 +#define WMI_TDLS_QOS_BK_FLAG 2 +#define WMI_TDLS_QOS_BE_FLAG 3 +#define WMI_TDLS_QOS_ACK_FLAG 4 +#define WMI_TDLS_QOS_SP_FLAG 5 +#define WMI_TDLS_QOS_MOREDATA_FLAG 7 + +#define WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps,flag) do { \ + (ppeer_caps)->peer_qos |= (1 << flag); \ + } while(0) +#define WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps,flag) \ + (((ppeer_caps)->peer_qos & (1 << flag)) >> flag) + +#define WMI_SET_TDLS_PEER_VO_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) +#define WMI_GET_TDLS_PEER_VO_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) +#define WMI_SET_TDLS_PEER_VI_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) +#define WMI_GET_TDLS_PEER_VI_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) +#define WMI_SET_TDLS_PEER_BK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) +#define WMI_GET_TDLS_PEER_BK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) +#define WMI_SET_TDLS_PEER_BE_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) +#define WMI_GET_TDLS_PEER_BE_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) +#define WMI_SET_TDLS_PEER_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) +#define WMI_GET_TDLS_PEER_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) +/* SP has 2 bits */ +#define WMI_SET_TDLS_PEER_SP_UAPSD(ppeer_caps,val) do { \ + (ppeer_caps)->peer_qos |= (((val)&0x3) << WMI_TDLS_QOS_SP_FLAG); \ + } while(0) +#define WMI_GET_TDLS_PEER_SP_UAPSD(ppeer_caps) \ + (((ppeer_caps)->peer_qos & (0x3 << WMI_TDLS_QOS_SP_FLAG)) >> WMI_TDLS_QOS_SP_FLAG) + +#define WMI_SET_TDLS_PEER_MORE_DATA_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) +#define WMI_GET_TDLS_PEER_MORE_DATA_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) + + +#define WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd,flag) do { \ + (pset_cmd)->tdls_puapsd_mask |= (1 << flag); \ + } while(0) +#define WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd,flag) \ + (((pset_cmd)->tdls_puapsd_mask & (1 << flag)) >> flag) + +#define WMI_SET_TDLS_SELF_VO_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VO_FLAG) +#define WMI_GET_TDLS_SELF_VO_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VO_FLAG) +#define WMI_SET_TDLS_SELF_VI_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VI_FLAG) +#define WMI_GET_TDLS_SELF_VI_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VI_FLAG) +#define WMI_SET_TDLS_SELF_BK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BK_FLAG) +#define WMI_GET_TDLS_SELF__BK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BK_FLAG) +#define WMI_SET_TDLS_SELF_BE_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BE_FLAG) +#define WMI_GET_TDLS_SELF_BE_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BE_FLAG) +#define WMI_SET_TDLS_SELF_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_ACK_FLAG) +#define WMI_GET_TDLS_SELF_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_ACK_FLAG) +/* SP has 2 bits */ +#define WMI_SET_TDLS_SELF_SP_UAPSD(pset_cmd,val) do { \ + (pset_cmd)->tdls_puapsd_mask |= (((val)&0x3) << WMI_TDLS_QOS_SP_FLAG); \ + } while(0) +#define WMI_GET_TDLS_SELF_SP_UAPSD(pset_cmd) \ + (((pset_cmd)->tdls_puapsd_mask & (0x3 << WMI_TDLS_QOS_SP_FLAG)) >> WMI_TDLS_QOS_SP_FLAG) + +#define WMI_SET_TDLS_SELF_MORE_DATA_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_MOREDATA_FLAG) +#define WMI_GET_TDLS_SELF_MORE_DATA_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_MOREDATA_FLAG) + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** new TDLS state for peer (wmi_tdls_peer_state) */ + A_UINT32 peer_state; + /* The TLV for wmi_tdls_peer_capabilities will follow. + * wmi_tdls_peer_capabilities peer_caps; + */ + /** Followed by the variable length TLV chan_info: + * wmi_channel chan_info[] */ +} wmi_tdls_peer_update_cmd_fixed_param; + +/* WMI_TDLS_SET_OFFCHAN_MODE_CMDID */ + + +/* bitmap 20, 40, 80 or 160 MHz wide channel */ +#define WMI_TDLS_OFFCHAN_20MHZ 0x1 /* 20 MHz wide channel */ +#define WMI_TDLS_OFFCHAN_40MHZ 0x2 /* 40 MHz wide channel */ +#define WMI_TDLS_OFFCHAN_80MHZ 0x4 /* 80 MHz wide channel */ +#define WMI_TDLS_OFFCHAN_160MHZ 0x8 /* 160 MHz wide channel */ + + +enum wmi_tdls_offchan_mode { + WMI_TDLS_ENABLE_OFFCHANNEL, + WMI_TDLS_DISABLE_OFFCHANNEL +}; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** Enable/Disable TDLS offchannel */ + A_UINT32 offchan_mode; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /* Is peer initiator or responder of TDLS setup request */ + A_UINT32 is_peer_responder; + /* off channel number*/ + A_UINT32 offchan_num; + /* off channel bandwidth bitmap, e.g. WMI_OFFCHAN_20MHZ */ + A_UINT32 offchan_bw_bitmap; + /* operating class for offchan */ + A_UINT32 offchan_oper_class; +} wmi_tdls_set_offchan_mode_cmd_fixed_param; + +/** TDLS EVENTS */ +enum wmi_tdls_peer_notification { + /** tdls discovery recommended for peer (based + * on tx bytes per second > tx_discover threshold) */ + WMI_TDLS_SHOULD_DISCOVER, + /** tdls link tear down recommended for peer + * due to tx bytes per second below tx_teardown_threshold + * NB: this notification sent once */ + WMI_TDLS_SHOULD_TEARDOWN, + /** tx peer TDLS link tear down complete */ + WMI_TDLS_PEER_DISCONNECTED, +}; + +enum wmi_tdls_peer_reason { + /** tdls teardown recommended due to low transmits */ + WMI_TDLS_TEARDOWN_REASON_TX, + /** tdls link tear down recommended due to poor RSSI */ + WMI_TDLS_TEARDOWN_REASON_RSSI, + /** tdls link tear down recommended due to offchannel scan */ + WMI_TDLS_TEARDOWN_REASON_SCAN, + /** tdls peer disconnected due to peer deletion */ + WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE, + /** tdls peer disconnected due to PTR timeout */ + WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT, + /** tdls peer disconnected due wrong PTR format */ + WMI_TDLS_TEARDOWN_REASON_BAD_PTR, + /** tdls peer not responding */ + WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE, +}; + +/* WMI_TDLS_PEER_EVENTID */ +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_peer_event_fixed_param */ + A_UINT32 tlv_header; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** TDLS peer status (wmi_tdls_peer_notification)*/ + A_UINT32 peer_status; + /** TDLS peer reason (wmi_tdls_peer_reason) */ + A_UINT32 peer_reason; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; +} wmi_tdls_peer_event_fixed_param; + +/* NOTE: wmi_vdev_mcc_bcn_intvl_change_event_fixed_param would be deprecated. Please + don't use this for any new implementations */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_mcc_bcn_intvl_change_event_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* New beacon interval to be used for the specified VDEV suggested by firmware */ + A_UINT32 new_bcn_intvl; +} wmi_vdev_mcc_bcn_intvl_change_event_fixed_param; + +/* WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID */ +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param */ + A_UINT32 tlv_header; + /** 1: enable fw based adaptive ocs, + * 0: disable fw based adaptive ocs + */ + A_UINT32 enable; + /** This field contains the MAC identifier in order to lookup the appropriate OCS instance. */ + /** The valid range is 0 to (num_macs-1). */ + A_UINT32 mac_id; +} wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param; + +/* WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID */ +typedef struct { + /* Frequency of the channel for which the quota is set */ + A_UINT32 chan_mhz; + /* Requested channel time quota expressed as percentage */ + A_UINT32 channel_time_quota; +} wmi_resmgr_chan_time_quota; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param */ + A_UINT32 tlv_header; + /** number of channel time quota command structures + * (wmi_resmgr_chan_time_quota) 1 or 2 + */ + A_UINT32 num_chans; +/* This TLV is followed by another TLV of array of bytes + * A_UINT8 data[]; + * This data array contains + * num_chans * size of(struct wmi_resmgr_chan_time_quota) + */ +} wmi_resmgr_set_chan_time_quota_cmd_fixed_param; + +/* WMI_RESMGR_SET_CHAN_LATENCY_CMDID */ +typedef struct { + /* Frequency of the channel for which the latency is set */ + A_UINT32 chan_mhz; + /* Requested channel latency in milliseconds */ + A_UINT32 latency; +} wmi_resmgr_chan_latency; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param */ + A_UINT32 tlv_header; + /** number of channel latency command structures + * (wmi_resmgr_chan_latency) 1 or 2 + */ + A_UINT32 num_chans; +/* This TLV is followed by another TLV of array of bytes + * A_UINT8 data[]; + * This data array contains + * num_chans * size of(struct wmi_resmgr_chan_latency) + */ +} wmi_resmgr_set_chan_latency_cmd_fixed_param; + +/* WMI_STA_SMPS_FORCE_MODE_CMDID */ + +/** STA SMPS Forced Mode */ +typedef enum { + WMI_SMPS_FORCED_MODE_NONE = 0, + WMI_SMPS_FORCED_MODE_DISABLED, + WMI_SMPS_FORCED_MODE_STATIC, + WMI_SMPS_FORCED_MODE_DYNAMIC +} wmi_sta_smps_forced_mode; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param */ + A_UINT32 tlv_header; + /** Unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** The mode of SMPS that is to be forced in the FW. */ + A_UINT32 forced_mode; +} wmi_sta_smps_force_mode_cmd_fixed_param; + +/** wlan HB commands */ +#define WMI_WLAN_HB_ITEM_UDP 0x1 +#define WMI_WLAN_HB_ITEM_TCP 0x2 +#define WMI_WLAN_HB_MAX_FILTER_SIZE 32 /* should be equal to WLAN_HB_MAX_FILTER_SIZE, must be a multiple of 4 bytes */ + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 enable; + A_UINT32 item; + A_UINT32 session; +} wmi_hb_set_enable_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 srv_ip; + A_UINT32 dev_ip; + A_UINT32 seq; + A_UINT32 src_port; + A_UINT32 dst_port; + A_UINT32 interval; + A_UINT32 timeout; + A_UINT32 session; +wmi_mac_addr gateway_mac; +} wmi_hb_set_tcp_params_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 length; + A_UINT32 offset; + A_UINT32 session; + A_UINT8 filter[WMI_WLAN_HB_MAX_FILTER_SIZE]; +} wmi_hb_set_tcp_pkt_filter_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 srv_ip; + A_UINT32 dev_ip; + A_UINT32 src_port; + A_UINT32 dst_port; + A_UINT32 interval; + A_UINT32 timeout; + A_UINT32 session; + wmi_mac_addr gateway_mac; +} wmi_hb_set_udp_params_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + A_UINT32 length; + A_UINT32 offset; + A_UINT32 session; + A_UINT8 filter[WMI_WLAN_HB_MAX_FILTER_SIZE]; +} wmi_hb_set_udp_pkt_filter_cmd_fixed_param; + +/** wlan HB events */ +typedef enum { + WMI_WLAN_HB_REASON_UNKNOWN = 0, + WMI_WLAN_HB_REASON_TCP_TIMEOUT = 1, + WMI_WLAN_HB_REASON_UDP_TIMEOUT = 2, +} WMI_HB_WAKEUP_REASON; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_hb_ind_event_fixed_param */ + A_UINT32 vdev_id; /* unique id identifying the VDEV */ + A_UINT32 session; /* Session ID from driver */ + A_UINT32 reason; /* wakeup reason */ +} wmi_hb_ind_event_fixed_param; + +/** WMI_STA_SMPS_PARAM_CMDID */ +typedef enum { + /** RSSI threshold to enter Dynamic SMPS mode from inactive mode */ + WMI_STA_SMPS_PARAM_UPPER_RSSI_THRESH = 0, + /** RSSI threshold to enter Stalled-D-SMPS mode from D-SMPS mode or + * to enter D-SMPS mode from Stalled-D-SMPS mode */ + WMI_STA_SMPS_PARAM_STALL_RSSI_THRESH = 1, + /** RSSI threshold to disable SMPS modes */ + WMI_STA_SMPS_PARAM_LOWER_RSSI_THRESH = 2, + /** Upper threshold for beacon-RSSI. Used to reduce RX chainmask. */ + WMI_STA_SMPS_PARAM_UPPER_BRSSI_THRESH = 3, + /** Lower threshold for beacon-RSSI. Used to increase RX chainmask. */ + WMI_STA_SMPS_PARAM_LOWER_BRSSI_THRESH = 4, + /** Enable/Disable DTIM 1chRx feature */ + WMI_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE = 5 +} wmi_sta_smps_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param */ + A_UINT32 tlv_header; + /** Unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** SMPS parameter (see wmi_sta_smps_param) */ + A_UINT32 param; + /** Value of SMPS parameter */ + A_UINT32 value; +} wmi_sta_smps_param_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_mcc_sched_sta_traffic_stats */ + A_UINT32 tlv_header; + /* TX stats */ + A_UINT32 txBytesPushed; + A_UINT32 txPacketsPushed; + /* RX stats */ + A_UINT32 rxBytesRcvd; + A_UINT32 rxPacketsRcvd; + A_UINT32 rxTimeTotal; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; +} wmi_mcc_sched_sta_traffic_stats; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_mcc_sched_traffic_stats_cmd_fixed_param */ + A_UINT32 tlv_header; + /** Duration over which the host stats were collected */ + A_UINT32 duration; + /** Number of stations filled in following stats array */ + A_UINT32 num_sta; + /* Following this struct are the TLVs: + * wmi_mcc_sched_sta_traffic_stats mcc_sched_sta_traffic_stats_list; + */ +} wmi_mcc_sched_traffic_stats_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_batch_scan_enable_cmd_fixed_param */ + /* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /*Batch scan enable command parameters*/ + A_UINT32 scanInterval; + A_UINT32 numScan2Batch; + A_UINT32 bestNetworks; + A_UINT32 rfBand; + A_UINT32 rtt; +} wmi_batch_scan_enable_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_batch_scan_enabled_event_fixed_param */ + A_UINT32 supportedMscan; +} wmi_batch_scan_enabled_event_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_batch_scan_disable_cmd_fixed_param */ +/* unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + A_UINT32 param; +} wmi_batch_scan_disable_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_batch_scan_trigger_result_cmd_fixed_param */ + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + A_UINT32 param; +} wmi_batch_scan_trigger_result_cmd_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; + wmi_mac_addr bssid; /* BSSID */ + wmi_ssid ssid; /* SSID */ + A_UINT32 ch; /* Channel */ + A_UINT32 rssi; /* RSSI or Level */ + /* Timestamp when Network was found. Used to calculate age based on timestamp in GET_RSP msg header */ + A_UINT32 timestamp; +} wmi_batch_scan_result_network_info; + +typedef struct +{ + A_UINT32 tlv_header; + A_UINT32 scanId; /* Scan List ID. */ + /* No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg */ + A_UINT32 numNetworksInScanList; + A_UINT32 netWorkStartIndex; /* indicate the start index of network info*/ +} wmi_batch_scan_result_scan_list; + +#define LPI_IE_BITMAP_BSSID 0x00000001 // if this bit is set, bssid of the scan response frame is sent as the first IE in the data buffer sent to LOWI LP. +#define LPI_IE_BITMAP_IS_PROBE 0x00000002 // send true or false based on scan response frame being a Probe Rsp or not +#define LPI_IE_BITMAP_SSID 0x00000004 // send ssid from received scan response frame +#define LPI_IE_BITMAP_RSSI 0x00000008 // send RSSI value reported by HW for the received scan response after adjusting with noise floor +#define LPI_IE_BITMAP_CHAN 0x00000010 // send channel number from the received scan response +#define LPI_IE_BITMAP_AP_TX_PWR 0x00000020 // send Tx power from TPC IE of scan rsp +#define LPI_IE_BITMAP_TX_RATE 0x00000040 // send rate of the received frame as reported by HW. +#define LPI_IE_BITMAP_80211_MC_SUPPORT 0x00000080 // send true or false based on the received scan rsp was from a 11mc supported AP or not. +#define LPI_IE_BITMAP_TSF_TIMER_VALUE 0x00000100 // send timestamp reported in the received scan rsp frame. +#define LPI_IE_BITMAP_AGE_OF_MEASUREMENT 0x00000200 // (current system time - received time) = duration of time scan rsp frame data is kept in the buffer before sending to LOWI LP. +/* + * TEMPORARY alias of incorrect old name the correct name. + * This alias will be removed once all references to the old name have been fixed. + */ +#define LPI_IE_BITMAP_AGE_OF_MESAUREMENT LPI_IE_BITMAP_AGE_OF_MEASUREMENT +#define LPI_IE_BITMAP_CONN_STATUS 0x00000400 // If an infra STA is active and connected to an AP, true value is sent else false. +#define LPI_IE_BITMAP_MSAP_IE 0x00000800 // info on the vendor specific proprietary IE MSAP +#define LPI_IE_BITMAP_SEC_STATUS 0x00001000 // we indicate true or false based on if the AP has WPA or RSN security enabled +#define LPI_IE_BITMAP_DEVICE_TYPE 0x00002000 // info about the beacons coming from an AP or P2P or NAN device. +#define LPI_IE_BITMAP_CHAN_IS_PASSIVE 0x00004000 // info on whether the scan rsp was received from a passive channel +#define LPI_IE_BITMAP_DWELL_TIME 0x00008000 // send the scan dwell time of the channel on which the current scan rsp frame was received. +#define LPI_IE_BITMAP_BAND_CENTER_FREQ1 0x00010000 // the center frequencies in case AP is supporting wider channels than 20 MHz +#define LPI_IE_BITMAP_BAND_CENTER_FREQ2 0x00020000 // same as above +#define LPI_IE_BITMAP_PHY_MODE 0x00040000 // PHY mode indicates a, b, ,g, ac and other combinations +#define LPI_IE_BITMAP_SCAN_MODULE_ID 0x00080000 // scan module id indicates the scan client who originated the scan +#define LPI_IE_BITMAP_SCAN_ID 0x00100000 // extscan inserts the scan cycle count for this value; other scan clients can insert the scan id of the scan, if needed. +#define LPI_IE_BITMAP_FLAGS 0x00200000 // reserved as a bitmap to indicate more scan information; one such use being to indicate if the on-going scan is interrupted or not +#define LPI_IE_BITMAP_CACHING_REQD 0x00400000 // extscan will use this field to indicate if this frame info needs to be cached in LOWI LP or not +#define LPI_IE_BITMAP_ALL 0xFFFFFFFF + +typedef struct { + A_UINT32 tlv_header; + /**A_BOOL indicates LPI mgmt snooping enable/disable*/ + A_UINT32 enable; + /**LPI snooping mode*/ + A_UINT32 snooping_mode; + /** LPI interested IEs in snooping context */ + A_UINT32 ie_bitmap; +} wmi_lpi_mgmt_snooping_config_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param */ + /** Scan ID */ + A_UINT32 scan_id; + /** Scan requestor ID */ + A_UINT32 scan_req_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** LPI interested IEs in scan context */ + A_UINT32 ie_bitmap; + /** Scan Priority, input to scan scheduler */ + A_UINT32 scan_priority; + /** dwell time in msec on active channels */ + A_UINT32 dwell_time_active; + /** dwell time in msec on passive channels */ + A_UINT32 dwell_time_passive; + /** min time in msec on the BSS channel,only valid if atleast one VDEV is active*/ + A_UINT32 min_rest_time; + /** max rest time in msec on the BSS channel,only valid if at least one VDEV is active*/ + /** the scanner will rest on the bss channel at least min_rest_time. after min_rest_time the scanner + * will start checking for tx/rx activity on all VDEVs. if there is no activity the scanner will + * switch to off channel. if there is activity the scanner will let the radio on the bss channel + * until max_rest_time expires.at max_rest_time scanner will switch to off channel + * irrespective of activity. activity is determined by the idle_time parameter. + */ + A_UINT32 max_rest_time; + /** time before sending next set of probe requests. + * The scanner keeps repeating probe requests transmission with period specified by repeat_probe_time. + * The number of probe requests specified depends on the ssid_list and bssid_list + */ + A_UINT32 repeat_probe_time; + /** time in msec between 2 consequetive probe requests with in a set. */ + A_UINT32 probe_spacing_time; + /** data inactivity time in msec on bss channel that will be used by scanner for measuring the inactivity */ + A_UINT32 idle_time; + /** maximum time in msec allowed for scan */ + A_UINT32 max_scan_time; + /** delay in msec before sending first probe request after switching to a channel */ + A_UINT32 probe_delay; + /** Scan control flags */ + A_UINT32 scan_ctrl_flags; + /** Burst duration time in msec*/ + A_UINT32 burst_duration; + + /** # if channels to scan. In the TLV channel_list[] */ + A_UINT32 num_chan; + /** number of bssids. In the TLV bssid_list[] */ + A_UINT32 num_bssid; + /** number of ssid. In the TLV ssid_list[] */ + A_UINT32 num_ssids; + /** number of bytes in ie data. In the TLV ie_data[] */ + A_UINT32 ie_len; + +/** + * TLV (tag length value ) parameters follow the scan_cmd + * structure. The TLV's are: + * A_UINT32 channel_list[]; + * wmi_ssid ssid_list[]; + * wmi_mac_addr bssid_list[]; + * A_UINT8 ie_data[]; + */ +} wmi_lpi_start_scan_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param */ + /** Scan requestor ID */ + A_UINT32 scan_req_id; + /** Scan ID */ + A_UINT32 scan_id; + /** + * Req Type + * req_type should be WMI_SCAN_STOP_ONE, WMI_SCN_STOP_VAP_ALL or WMI_SCAN_STOP_ALL + * WMI_SCAN_STOP_ONE indicates to stop a specific scan with scan_id + * WMI_SCN_STOP_VAP_ALL indicates to stop all scan requests on a specific vDev with vdev_id + * WMI_SCAN_STOP_ALL indicates to stop all scan requests in both Scheduler's queue and Scan Engine + */ + A_UINT32 req_type; + /** + * vDev ID + * used when req_type equals to WMI_SCN_STOP_VAP_ALL, it indexed the vDev on which to stop the scan + */ + A_UINT32 vdev_id; +} wmi_lpi_stop_scan_cmd_fixed_param; + +typedef enum { + WMI_LPI_DEVICE_TYPE_AP = 1, + WMI_LPI_DEVICE_TYPE_P2P = 2, + WMI_LPI_DEVICE_TYPE_NAN = 3, +}wmi_lpi_device_type; + +typedef struct +{ + A_UINT32 tlv_header; + /** Scan requestor ID */ + A_UINT32 scan_req_id; + A_UINT32 ie_bitmap; + A_UINT32 data_len; +} wmi_lpi_result_event_fixed_param; + +typedef enum { + /** User scan Request completed */ + WMI_LPI_STATUS_SCAN_REQ_COMPLED = 0, + /** User Request was never serviced */ + WMI_LPI_STATUS_DROPPED_REQ = 1, + /** Illegal channel Req */ + WMI_LPI_STATUS_ILLEGAL_CHAN_REQ = 2, + /** Illegal Operation Req */ + WMI_LPI_STATUS_ILLEGAL_OPER_REQ = 3, + /** Request Aborted */ + WMI_LPI_STATUS_REQ_ABORTED = 4, + /** Request Timed Out */ + WMI_LPI_STATUS_REQ_TIME_OUT = 5, + /** Medium Bussy, already there + * is a scan is going on */ + WMI_LPI_STATUS_MEDIUM_BUSY = 6, +}wmi_lpi_staus; + +typedef struct +{ + A_UINT32 tlv_header; + wmi_lpi_staus status; + /** Scan requestor ID */ + A_UINT32 scan_req_id; +} wmi_lpi_status_event_fixed_param; + + +typedef struct +{ + A_UINT32 tlv_header; + wmi_mac_addr bssid; + wmi_ssid ssid; + A_UINT32 freq; + A_UINT32 rssi; + A_UINT32 vdev_id; +} wmi_lpi_handoff_event_fixed_param; + +typedef struct +{ + A_UINT32 tlv_header; + A_UINT32 timestamp; /*timestamp of batch scan event*/ + A_UINT32 numScanLists; /*number of scan in this event*/ + A_UINT32 isLastResult; /*is this event a last event of the whole batch scan*/ +} wmi_batch_scan_result_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_p2p_noa_event_fixed_param */ + A_UINT32 vdev_id; + /* This TLV is followed by p2p_noa_info for vdev : + * wmi_p2p_noa_info p2p_noa_info; + */ +} wmi_p2p_noa_event_fixed_param; + +#define WMI_RFKILL_CFG_RADIO_LEVEL_OFFSET 6 +#define WMI_RFKILL_CFG_RADIO_LEVEL_MASK 0x1 + +#define WMI_RFKILL_CFG_GPIO_PIN_NUM_OFFSET 0 +#define WMI_RFKILL_CFG_GPIO_PIN_NUM_MASK 0x3f + +#define WMI_RFKILL_CFG_PIN_AS_GPIO_OFFSET 7 +#define WMI_RFKILL_CFG_PIN_AS_GPIO_MASK 0xf + +typedef struct { + /** TLV tag and len; tag equals + * */ + A_UINT32 tlv_header; + /** gpip pin number */ + A_UINT32 gpio_pin_num; + /** gpio interupt type */ + A_UINT32 int_type; + /** RF radio status */ + A_UINT32 radio_state; +} wmi_rfkill_mode_param; + +typedef enum { + WMI_SET_LED_SYS_POWEROFF, + WMI_SET_LED_SYS_S3_SUSPEND, + WMI_SET_LED_SYS_S4_S5, + WMI_SET_LED_SYS_DRIVER_DISABLE, + WMI_SET_LED_SYS_WAKEUP, + WMI_SET_LED_SYS_ALWAYS_ON, //just for test! + WMI_SET_LED_SYS_POWERON, +} wmi_led_sys_state_param; + +typedef enum { + WMI_CONFIG_LED_TO_VDD = 0, + WMI_CONFIG_LED_TO_GND = 1, +} wmi_config_led_connect_type; + +typedef enum { + WMI_CONFIG_LED_NOT_WITH_BT = 0, + WMI_CONFIG_LED_WITH_BT = 1, +} wmi_config_led_with_bt_flag; + +typedef enum { + WMI_CONFIG_LED_DISABLE = 0, + WMI_CONFIG_LED_ENABLE = 1, +} wmi_config_led_enable_flag; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param */ + A_UINT32 tlv_header; + /* Set GPIO pin */ + A_UINT32 led_gpio_pin; + /* Set connect type defined in wmi_config_led_connect_type */ + A_UINT32 connect_type; + /* Set flag defined in wmi_config_led_with_bt_flag*/ + A_UINT32 with_bt; + /* Set LED enablement defined in wmi_config_led_enable_flag */ + A_UINT32 led_enable; +} wmi_pdev_set_led_config_cmd_fixed_param; + +#define WMI_WNTS_CFG_GPIO_PIN_NUM_OFFSET 0 +#define WMI_WNTS_CFG_GPIO_PIN_NUM_MASK 0xff + +/** WMI_PEER_INFO_REQ_CMDID + * Request FW to provide peer info */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_peer_info_req_cmd_fixed_param */ + A_UINT32 tlv_header; + /** In order to get the peer info for a single peer, host shall + * issue the peer_mac_address of that peer. For getting the + * info all peers, the host shall issue 0xFFFFFFFF as the mac + * address. The firmware will return the peer info for all the + * peers on the specified vdev_id */ + wmi_mac_addr peer_mac_address; + /** vdev id */ + A_UINT32 vdev_id; +} wmi_peer_info_req_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_peer_info */ + A_UINT32 tlv_header; + /** mac addr of the peer */ + wmi_mac_addr peer_mac_address; + /** data_rate of the peer */ + A_UINT32 data_rate; + /** rssi of the peer */ + A_UINT32 rssi; + /** tx fail count */ + A_UINT32 tx_fail_cnt; +} wmi_peer_info; + +/** FW response with the peer info */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_peer_info_event_fixed_param */ + A_UINT32 tlv_header; + /** number of peers in peer_info */ + A_UINT32 num_peers; + /* This TLV is followed by another TLV of array of structs + * wmi_peer_info peer_info[]; + */ +} wmi_peer_info_event_fixed_param; + +/** FW response when tx failure count has reached threshold + * for a peer */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_peer_tx_fail_cnt_thr_event_fixed_param */ + A_UINT32 tlv_header; + /** vdev id*/ + A_UINT32 vdev_id; + /** mac address */ + wmi_mac_addr peer_mac_address; + /** tx failure count- will eventually be removed and not used * */ + A_UINT32 tx_fail_cnt; + /** seq number of the nth tx_fail_event */ + A_UINT32 seq_no; +} wmi_peer_tx_fail_cnt_thr_event_fixed_param; + +enum wmi_rmc_mode { + /** Disable RMC */ + WMI_RMC_MODE_DISABLED = 0, + /** Enable RMC */ + WMI_RMC_MODE_ENABLED = 1, +}; + +/** Enable RMC transmitter functionality. Upon + * receiving this, the FW shall mutlicast frames with + * reliablity. This is a vendor + * proprietary feature. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_rmc_set_mode_cmd_fixed_param */ + A_UINT32 tlv_header; + /** vdev id*/ + A_UINT32 vdev_id; + /** enable_rmc contains values from enum wmi_rmc_mode; + * Default value: 0 (disabled) */ + A_UINT32 enable_rmc; +} wmi_rmc_set_mode_cmd_fixed_param; + +/** Configure transmission periodicity of action frames in a + * RMC network for the multicast transmitter */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_rmc_set_action_period_cmd_fixed_param */ + A_UINT32 tlv_header; + /** vdev id */ + A_UINT32 vdev_id; + /** time period in milliseconds. Default: 300 ms. + An action frame indicating the current leader is transmitted by the + RMC transmitter once every 'periodity_msec' */ + A_UINT32 periodicity_msec; +} wmi_rmc_set_action_period_cmd_fixed_param; + +/** Optimise Leader selection process in RMC functionality. For + * Enhancement/Debug purposes only */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_rmc_config_cmd_fixed_param */ + A_UINT32 tlv_header; + /** vdev id */ + A_UINT32 vdev_id; + /** flags :: + * 0x0001 - Enable beacon averaging + * 0x0002 - Force leader selection + * 0x0004 - Enable Timer based leader switch + * 0x0008 - Use qos/NULL based for multicast reliability */ + A_UINT32 flags; + /** control leader change timeperiod (in seconds) */ + A_UINT32 peridocity_leader_switch; + /** control activity timeout value for data rx (in seconds) */ + A_UINT32 data_activity_timeout; + /** mac address of leader */ + wmi_mac_addr forced_leader_mac_addr; +} wmi_rmc_config_cmd_fixed_param; + +/** MHF is generally implemented in + * the kernel. To decrease system power consumption, the + * driver can enable offloading this to the chipset. In + * order for the offload, the firmware needs the routing table. + * The host shall plumb the routing table into FW. The firmware + * shall perform an IP address lookup and forward the packet to + * the next hop using next hop's mac address. This is a vendor + * proprietary feature. */ +enum wmi_mhf_ofl_mode { + /** Disable MHF offload */ + WMI_MHF_OFL_MODE_DISABLED = 0, + /** Enable MHF offload */ + WMI_MHF_OFL_MODE_ENABLED = 1, +}; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_mhf_offload_set_mode_cmd_fixed_param */ + A_UINT32 tlv_header; + /** vdev id*/ + A_UINT32 vdev_id; + /** enable_mhf_ofl contains values from enum + * wmi_mhf_ofl_mode; Default value: 0 (disabled) */ + A_UINT32 enable_mhf_ofl; +} wmi_mhf_offload_set_mode_cmd_fixed_param; + +enum wmi_mhf_ofl_table_action { + /** Create MHF offload table in FW */ + WMI_MHF_OFL_TBL_CREATE = 0, + /** Append to existing MHF offload table */ + WMI_MHF_OFL_TBL_APPEND = 1, + /** Flush entire MHF offload table in FW */ + WMI_MHF_OFL_TBL_FLUSH = 2, +}; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_mhf_offload_plumb_routing_table_cmd_fixed_param */ + A_UINT32 tlv_header; + /** vdev id*/ + A_UINT32 vdev_id; + /** action corresponds to values from enum + * wmi_mhf_ofl_table_action */ + A_UINT32 action; + /** number of entries in the table */ + A_UINT32 num_entries; +/** Followed by the variable length TLV + * wmi_mhf_offload_routing_table_entry entries[] */ +}wmi_mhf_offload_plumb_routing_table_cmd; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_mhf_offload_routing_table_entry */ + A_UINT32 tlv_header; + /** Destination node's IP address */ + WMI_IPV4_ADDR dest_ipv4_addr; + /** Next hop node's MAC address */ + wmi_mac_addr next_hop_mac_addr; +}wmi_mhf_offload_routing_table_entry; + +typedef struct { + /** tlv tag and len, tag equals + * WMITLV_TAG_STRUC_wmi_dfs_radar_event */ + A_UINT32 tlv_header; + + /** full 64 tsf timestamp get from MAC tsf timer indicates + * the time that the radar event uploading to host, split + * it to high 32 bit and lower 32 bit in fulltsf_high and + * full_tsf_low + */ + A_UINT32 upload_fullts_low; + A_UINT32 upload_fullts_high; + + /** timestamp indicates the time when DFS pulse is detected + * equal to ppdu_end_ts - radar_pusle_summary_ts_offset + */ + A_UINT32 pulse_detect_ts; + + /** the duaration of the pulse in us */ + A_UINT32 pulse_duration; + + /** the center frequency of the radar pulse detected, KHz */ + A_UINT32 pulse_center_freq; + + /** bandwidth of current DFS channel, MHz */ + A_UINT32 ch_bandwidth; + + /** center channel frequency1 of current DFS channel, MHz */ + A_UINT16 ch_center_freq1; + + /** center channel frequency2 of current DFS channel, MHz, + * reserved for 160 BW mode + */ + A_UINT16 ch_center_freq2; + + /** flag to indicate if this pulse is chirp */ + A_UINT8 pulse_is_chirp; + + /** RSSI recorded in the ppdu */ + A_UINT8 rssi; + + /** extened RSSI info */ + A_UINT8 rssi_ext; + + /** For 4-byte aligment padding */ + A_UINT8 reserved; + +} wmi_dfs_radar_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param */ + + /*Thermal thresholds*/ + A_UINT32 lower_thresh_degreeC; /* in degree C*/ + A_UINT32 upper_thresh_degreeC; /* in degree C*/ + + /*Enable/Disable Thermal Monitoring for Mitigation*/ + A_UINT32 enable; +} wmi_thermal_mgmt_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_thermal_mgmt_event_fixed_param */ + + A_UINT32 temperature_degreeC;/* temperature in degree C*/ +} wmi_thermal_mgmt_event_fixed_param; + +/** + * This command is sent from WLAN host driver to firmware to + * request firmware to configure auto shutdown timer in fw + * 0 - Disable <1-19600>-Enabled and timer value is seconds (86400 seconds = 1 day maximum> + */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_param */ + A_UINT32 timer_value; /** timer value; 0=disable */ +} wmi_host_auto_shutdown_cfg_cmd_fixed_param; + +enum wmi_host_auto_shutdown_reason { + WMI_HOST_AUTO_SHUTDOWN_REASON_UNKNOWN = 0, + WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY = 1, + WMI_HOST_AUTO_SHUTDOWN_REASON_MAX, +}; + +/* WMI_HOST_AUTO_SHUTDOWN_EVENTID */ +typedef struct{ + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_host_auto_shutdown_event_fixed_param */ + A_UINT32 shutdown_reason; /* value: wmi_host_auto_shutdown_reason */ +} wmi_host_auto_shutdown_event_fixed_param; + + +/** New WMI command to support TPC CHAINMASK ADJUSTMENT ACCORDING TO a set of conditions specified in the command. + * fw will save c tpc offset/chainmask along with conditions and adjust tpc/chainmask when condition meet. + * This command is only used by some customer for verification test. It is not for end-user. + * + * array of wmi_tpc_chainmask_config structures are passed with the command to specify multiple conditions. + * + * The set of conditions include bt status, stbc status, band, phy_mode, 1stream/2streams, channel, rate. when all these conditions meet, + * the output(tpc_offset,chainmask) will be applied on per packet basis. ack_offset is applied based on channel condtion only. When multiple + * conditions has the same channel ,then the first ack_offset will be applied. It is better for host driver to make sure the + * pair is unique. + * + * the conditions (bt status, stbc status, band, phy_mode, 1steam/2streams, tpc_offset, ack_offset, chainmask) are combinedi into a single word + * called basic_config_info by bitmap + * to save memory. And channel & rate info will be tracked by 'channel' field and 'rate0', 'rate1' field because of its large combination. + * + * 'rate bit' or 'channel bit' field of basic_config_info indicate validity of the channel and rate fields.if rate bit is 0 then the rate field + * is ignored. + * disable will remove preious conditions from FW. + * conditions from the later command will over write conditions stored from a previous command. + * + */ + +#define WMI_TPC_CHAINMASK_CONFIG_BT_ON_OFF 0 /** dont' care the bt status */ +#define WMI_TPC_CHAINMASK_CONFIG_BT_ON 1 /** apply only when bt on */ +#define WMI_TPC_CHAINMASK_CONFIG_BT_OFF 2 /** apply only when bt off */ +#define WMI_TPC_CHAINMASK_CONFIG_BT_RESV1 3 /** reserved */ + +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_DONT_CARE 0 /** don't care the chainmask */ +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_CHAIN0 1 /** force to use Chain0 to send */ +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_CHAIN1 2 /** force to use Chain1 to send */ +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_CHAIN0_CHAIN1 3 /** force to use Chain0 & Chain1 to send */ + +#define WMI_TPC_CHAINMASK_CONFIG_STBC_ON_OFF 0 /** don't care about stbc */ +#define WMI_TPC_CHAINMASK_CONFIG_STBC_ON 1 /** apply only when stbc on */ +#define WMI_TPC_CHAINMASK_CONFIG_STBC_OFF 2 /** apply only when stbc off */ +#define WMI_TPC_CHAINMASK_CONFIG_STBC_RESV1 3 /** reserved */ + +#define WMI_TPC_CHAINMASK_CONFIG_BAND_2G 0 /** 2G */ +#define WMI_TPC_CHAINMASK_CONFIG_BAND_5G 1 /** 5G */ + +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11B_2G 0 /** 11b 2G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11G_2G 1 /** 11g 2G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_2G 2 /** 11n 2G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_11AC_2G 3 /** 11n + 11ac 2G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11A_5G 4 /** 11a 5G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_5G 5 /** 11n 5G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11AC_5G 6 /** 11ac 5G */ +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_11AC_5G 7 /** 11n + 11ac 5G */ + +#define WMI_TPC_CHAINMASK_CONFIG_STREAM_1 0 /** 1 stream */ +#define WMI_TPC_CHAINMASK_CONFIG_STREAM_2 1 /** 2 streams */ + +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_OFF 0 /** channel field is ignored */ +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_ON 1 /** channel field needs to be checked */ + +#define WMI_TPC_CHAINMASK_CONFIG_RATE_OFF 0 /** rate field is ignored */ +#define WMI_TPC_CHAINMASK_CONFIG_RATE_ON 1 /** rate field needs to be checked */ + +/** Bit map definition for basic_config_info starts */ +#define WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET_S 0 +#define WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET (0x1f << WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET_S) +#define WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET) +#define WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET_SET(x,z) WMI_F_RMW(x,(z) & 0x1f,WMI_TPC_CHAINMASK_CONFIG_TPC_OFFSET) + +#define WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET_S 5 +#define WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET (0x1f << WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET_S) +#define WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET) +#define WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET_SET(x,z) WMI_F_RMW(x, (z) & 0x1f, WMI_TPC_CHAINMASK_CONFIG_ACK_OFFSET) + +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_S 10 +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK (0x3 << WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_S) +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_CHAINMASK) +#define WMI_TPC_CHAINMASK_CONFIG_CHAINMASK_SET(x,z) WMI_F_RMW(x, (z)&0x3, WMI_TPC_CHAINMASK_CONFIG_CHAINMASK) + +#define WMI_TPC_CHAINMASK_CONFIG_BT_S 12 +#define WMI_TPC_CHAINMASK_CONFIG_BT (0x3 << WMI_TPC_CHAINMASK_CONFIG_BT_S) +#define WMI_TPC_CHAINMASK_CONFIG_BT_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_BT) +#define WMI_TPC_CHAINMASK_CONFIG_BT_SET(x,z) WMI_F_RMW(x, (z)&0x3, WMI_TPC_CHAINMASK_CONFIG_BT) + +#define WMI_TPC_CHAINMASK_CONFIG_STBC_S 14 +#define WMI_TPC_CHAINMASK_CONFIG_STBC (0x3 << WMI_TPC_CHAINMASK_CONFIG_STBC_S) +#define WMI_TPC_CHAINMASK_CONFIG_STBC_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_STBC) +#define WMI_TPC_CHAINMASK_CONFIG_STBC_SET(x,z) WMI_F_RMW(x, (z)& 0x3, WMI_TPC_CHAINMASK_CONFIG_STBC) + +#define WMI_TPC_CHAINMASK_CONFIG_BAND_S 16 +#define WMI_TPC_CHAINMASK_CONFIG_BAND (0x1 << WMI_TPC_CHAINMASK_CONFIG_BAND_S) +#define WMI_TPC_CHAINMASK_CONFIG_BAND_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_BAND) +#define WMI_TPC_CHAINMASK_CONFIG_BAND_SET(x,z) WMI_F_RMW(x, (z) &0x1, WMI_TPC_CHAINMASK_CONFIG_BAND) + +#define WMI_TPC_CHAINMASK_CONFIG_STREAM_S 17 +#define WMI_TPC_CHAINMASK_CONFIG_STREAM (0x1 << WMI_TPC_CHAINMASK_CONFIG_STREAM_S) +#define WMI_TPC_CHAINMASK_CONFIG_STREAM_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_STREAM) +#define WMI_TPC_CHAINMASK_CONFIG_STREAM_SET(x,z) WMI_F_RMW(x, (z)&0x1, WMI_TPC_CHAINMASK_CONFIG_STREAM) + +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_S 18 +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE (0x7 << WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_S) +#define WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_PHY_MODE) +#define WMI_TPC_CHAINAMSK_CONFIG_PHY_MODE_SET(x,z) WMI_F_RMW(x, (z)&0x7, WMI_TPC_CHAINMASK_CONFIG_PHY_MODE) + +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_S 21 +/* + * The deprecated old name (WMI_TPC_CHAINMASK_CONFIG_CHANNEL_EXIST) + * is temporarily maintained as an alias for the correct name + * (WMI_TPC_CHAINMASK_CONFIG_CHANNEL) + */ +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_EXIST WMI_TPC_CHAINMASK_CONFIG_CHANNEL +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL (0x1 << WMI_TPC_CHAINMASK_CONFIG_CHANNEL_S) +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_GET(x) WMI_F_MS(x,WMI_TPC_CHAINMASK_CONFIG_CHANNEL) +#define WMI_TPC_CHAINMASK_CONFIG_CHANNEL_SET(x,z) WMI_F_RMW(x, (z)&0x1, WMI_TPC_CHAINMASK_CONFIG_CHANNEL) + +#define WMI_TPC_CHAINMASK_CONFIG_RATE_S 22 +/* + * The deprecated old name (WMI_TPC_CHAINMASK_CONFIG_RATE_EXIST) + * is temporarily maintained as an alias for the correct name + * (WMI_TPC_CHAINMASK_CONFIG_RATE) + */ +#define WMI_TPC_CHAINMASK_CONFIG_RATE_EXIST WMI_TPC_CHAINMASK_CONFIG_RATE +#define WMI_TPC_CHAINMASK_CONFIG_RATE (0x1 << WMI_TPC_CHAINMASK_CONFIG_RATE_S) +#define WMI_TPC_CHAINMASK_CONFIG_RATE_GET(x) WMI_F_MS(x, WMI_TPC_CHAINMASK_CONFIG_RATE) +#define WMI_TPC_CHAINMASK_CONFIG_RATE_SET(x,z) WMI_F_RMW(x, (z)&0x1, WMI_TPC_CHAINMASK_CONFIG_RATE) + +/** Bit map definition for basic_config_info ends */ + +typedef struct{ + A_UINT32 tlv_header; + /** Basic condition defined as bit map above, bitmap is chosen to save memory. + * Bit0 ~ Bit4: tpc offset which will be adjusted if condtion matches, the unit is 0.5dB. bit4 indicates signed + * Bit5 ~ Bit9: ack offset which will be adjusted if condtion matches, the unit is 0.5dB. bit9 indicates signed + * Bit10 ~ Bit11: chainmask b'00: don't care, b'01: force to use chain0, b'10: force to use chain1, b'11: force to use chain0&chain1 + * Bit12 ~ Bit13: bt condition b'00: don't care, b'01: apply only when bt on, b'10: apply only when bt off, b'11: reserved + * Bit14 ~ Bit15: stbc condition b'00: don't care, b'01: apply only when stbc on, b'10: apply only when stbc off, b'11: reserved + * Bit16 : band condition b'0: 2G, b'1: 5G + * Bit17 : stream condition: b'0: 1 stream, b'1: 2 streams + * Bit18 ~ Bit20: phy mode condition: b'000: 11b 2g, b'001: 11g 2g, b'010: 11n 2g, b'011: 11n+11ac 2g, b'100: 11a, b'101: 11n 5g, b'110: 11ac 5g, b'111: 11n+11ac 5g + * Bit21 : channel bit, if this bit is 0, then the following channel field is ignored + * Bit22 : rate bit, if this bit is 0, then the following rate0&rate1 is ignored. + * Bit23 ~ Bit31: reserved + */ + A_UINT32 basic_config_info; + + /** channel mapping bit rule: The lower bit corresponds with smaller channel. + * it depends on Bit14 of basic_config_info + * Total 24 channels for 5G + * 36 40 44 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 149 153 157 161 165 + * Total 14 channels for 2G + * 1 ~ 14 + */ + A_UINT32 channel; + + /** rate mapping bit rule: The lower bit corresponds with lower rate. + * it depends on Bit16 ~ Bit18 of basic_config_info, "phy mode condition" + * Legacy rates , 11b, 11g, 11A + * 11n one stream ( ht20, ht40 ) 8+8 + * 11n two streams ( ht20, ht40 ) 8+8 + * 11ac one stream ( vht20, vht40, vht80 ) 10+10+10 + * 11ac two streams (vht20, vht40, vht80 ) 10+10+10 + */ + A_UINT32 rate0; + /** For example, for 11b, when rate0 equals 0x3, it means if actual_rate in [ "1Mbps", "2Mbps"] connection, the rate condition is true. + * For example, for 11g/11a, when rate0 equals 0xf0,it means "54Mbps", "48Mbps", "36Mbps", "24Mb's" is selected, while "18Mbps", "12Mbps", "9Mbps", "6Mbps" is not selected + */ + + /** only used for "11n+11ac" combined phy_mode, (WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_11AC_2G , WMI_TPC_CHAINMASK_CONFIG_PHY_MODE_11N_11AC_5G) in this case, 11n rates begins on rate0, while 11ac rates begins on rate1 + */ + A_UINT32 rate1; +} wmi_tpc_chainmask_config; + +#define WMI_TPC_CHAINMASK_CONFIG_DISABLE 0 /** control the off for the tpc & chainmask*/ +#define WMI_TPC_CHAINMASK_CONFIG_ENABLE 1 /** control the on for the tpc & chainmask*/ + +typedef struct{ + A_UINT32 tlv_header; + A_UINT32 enable; /** enable to set tpc & chainmask when condtions meet, 0: disabled, 1: enabled. */ + A_UINT32 num_tpc_chainmask_configs; + /** following this structure is num_tpc_chainmask_configs number of wmi_tpc_chainmask_config */ +} wmi_tpc_chainmask_config_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nan_cmd_param */ + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from application/service to firmware where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_nan_cmd_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nan_event_hdr */ + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from firmware to application/service where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_nan_event_hdr; + +typedef struct { + A_UINT32 tlv_header; + A_UINT32 num_data; + /* followed by WMITLV_TAG_ARRAY_BYTE */ +} wmi_diag_data_container_event_fixed_param; + +enum { + WMI_PDEV_PARAM_TXPOWER_REASON_NONE = 0, + WMI_PDEV_PARAM_TXPOWER_REASON_SAR, + WMI_PDEV_PARAM_TXPOWER_REASON_MAX +}; + +#define PDEV_PARAM_TXPOWER_VALUE_MASK 0x000000FF +#define PDEV_PARAM_TXPOWER_VALUE_SHIFT 0 + +#define PDEV_PARAM_TXPOWER_REASON_MASK 0x0000FF00 +#define PDEV_PARAM_TXPOWER_REASON_SHIFT 8 + +#define SET_PDEV_PARAM_TXPOWER_VALUE(txpower_param, value) \ + ((txpower_param) &= ~PDEV_PARAM_TXPOWER_VALUE_MASK, (txpower_param) |= ((value) << PDEV_PARAM_TXPOWER_VALUE_SHIFT)) + +#define SET_PDEV_PARAM_TXPOWER_REASON(txpower_param, value) \ + ((txpower_param) &= ~PDEV_PARAM_TXPOWER_REASON_MASK, (txpower_param) |= ((value) << PDEV_PARAM_TXPOWER_REASON_SHIFT)) + +#define GET_PDEV_PARAM_TXPOWER_VALUE(txpower_param) \ + (((txpower_param) & PDEV_PARAM_TXPOWER_VALUE_MASK) >> PDEV_PARAM_TXPOWER_VALUE_SHIFT) + +#define GET_PDEV_PARAM_TXPOWER_REASON(txpower_param) \ + (((txpower_param) & PDEV_PARAM_TXPOWER_REASON_MASK) >> PDEV_PARAM_TXPOWER_REASON_SHIFT) + +/** + * This command is sent from WLAN host driver to firmware to + * notify the current modem power state. Host would receive a + * message from modem when modem is powered on. Host driver + * would then send this command to firmware. Firmware would then + * power on WCI-2 (UART) interface for LTE/MWS Coex. + * + * This command is only applicable for APQ platform which has + * modem on the platform. If firmware doesn't support MWS Coex, + * this command can be dropped by firmware. + * + * This is a requirement from modem team that WCN can't toggle + * UART before modem is powered on. + */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param */ + A_UINT32 tlv_header; + + /** Modem power state parameter */ + A_UINT32 modem_power_state; +} wmi_modem_power_state_cmd_param; + +enum { + WMI_MODEM_STATE_OFF = 0, + WMI_MODEM_STATE_ON +}; + +#define WMI_ROAM_AUTH_STATUS_CONNECTED 0x1 /** connected, but not authenticated */ +#define WMI_ROAM_AUTH_STATUS_AUTHENTICATED 0x2 /** connected and authenticated */ + +/** WMI_ROAM_SYNCH_EVENT: roam synch event triggering the host propagation logic + generated whenever firmware roamed to new AP silently and + (a) If the host is awake, FW sends the event to the host immediately . + (b) If host is in sleep then either + (1) FW waits until host sends WMI_PDEV_RESUME_CMDID or WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID + command to FW (part of host wake up sequence from low power mode) before sending the event host. + (2) data/mgmt frame is received from roamed AP, which needs to return to host +*/ + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_key_material */ + A_UINT32 tlv_header; + + A_UINT8 kck[GTK_OFFLOAD_KCK_BYTES]; /* EAPOL-Key Key Confirmation Key (KCK) */ + A_UINT8 kek[GTK_OFFLOAD_KEK_BYTES]; /* EAPOL-Key Key Encryption Key (KEK) */ + A_UINT8 replay_counter[GTK_REPLAY_COUNTER_BYTES]; +} wmi_key_material; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_roam_synch_event_fixed_param */ + /** Unique id identifying the VDEV on which roaming is done by firmware */ + A_UINT32 vdev_id; + /** auth_status: connected or authorized */ + A_UINT32 auth_status; + /** roam_reason: the reason of roam. see the WMI_ROAM_REASON_ XXX */ + A_UINT32 roam_reason; + /** associated AP's rssi calculated by FW when reason code is WMI_ROAM_REASON_LOW_RSSI. not valid if roam_reason is BMISS */ + A_UINT32 rssi; + /** MAC address of roamed AP */ + wmi_mac_addr bssid; /* BSSID */ + /** whether the frame is beacon or probe rsp */ + A_UINT32 is_beacon; + /** the length of beacon/probe rsp */ + A_UINT32 bcn_probe_rsp_len; + /** the length of reassoc rsp */ + A_UINT32 reassoc_rsp_len; + /** + * TLV (tag length value ) parameters follows roam_synch_event + * The TLV's are: + * A_UINT8 bcn_probe_rsp_frame[]; length identified by bcn_probe_rsp_len + * A_UINT8 reassoc_rsp_frame[]; length identified by reassoc_rsp_len + * wmi_channel chan; + * wmi_key_material key; + * A_UINT32 status; subnet changed status + **/ +} wmi_roam_synch_event_fixed_param; + +#define WMI_PEER_ESTIMATED_LINKSPEED_INVALID 0xFFFFFFFF + +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_ wmi_peer_get_estimated_linkspeed_cmd_fixed_param */ + A_UINT32 tlv_header; + /** MAC address of the peer for which the estimated link speed is required. */ + wmi_mac_addr peer_macaddr; +} wmi_peer_get_estimated_linkspeed_cmd_fixed_param; + +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_ wmi_peer_estimated_linkspeed_event_fixed_param */ + A_UINT32 tlv_header; + /** MAC address of the peer for which the estimated link speed is required. + */ + wmi_mac_addr peer_macaddr; + /* Estimated link speed in kbps. + * When est_linkspeed_kbps is not valid, the value is set to WMI_PEER_ESTIMATED_LINKSPEED_INVALID. + */ + A_UINT32 est_linkspeed_kbps; +} wmi_peer_estimated_linkspeed_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals */ + /* vdev ID */ + A_UINT32 vdev_id; + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from application/service to firmware where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_req_stats_ext_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_stats1_event_fix_param */ + A_UINT32 vdev_id; /** vdev ID */ + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from firmware to application/service where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_stats_ext_event_fixed_param; + +typedef struct { + /* TLV tag and len; tag equals WMITLV_TAG_STRUC_ wmi_peer_state_event_fixed_param */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; /* vdev ID */ + /* MAC address of the peer for which the estimated link speed is required.*/ + wmi_mac_addr peer_macaddr; + A_UINT32 state; /* peer state */ +} wmi_peer_state_event_fixed_param; + +enum { + WMI_2G4_HT40_OBSS_SCAN_PASSIVE = 0, /** scan_type: passive */ + WMI_2G4_HT40_OBSS_SCAN_ACTIVE, /** scan_type: active */ +}; + +typedef struct { + /** + * TLV tag and len; + * tag equals WMITLV_TAG_STRUC_wmi_obss_scan_enalbe_cmd_fixed_param + */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; + /** + * active or passive. if active all the channels are actively scanned. + * if passive then all the channels are passively scanned + */ + A_UINT32 scan_type; + /** + * FW can perform multiple scans with in a OBSS scan interval. + * For each scan, + * if the scan is passive then obss_scan_passive_dwell is minimum dwell to be used for each channel , + * if the scan is active then obss_scan_active_dwell is minimum dwell to be used for each channel . + * The unit for these 2 parameters is TUs. + */ + A_UINT32 obss_scan_passive_dwell; + A_UINT32 obss_scan_active_dwell; + /** + * OBSS scan interval . FW needs to perform one or more OBSS scans within this interval and fulfill the + * both min and total per channel dwell time requirement + */ + A_UINT32 bss_channel_width_trigger_scan_interval; + /** + * FW can perform multiple scans with in a OBSS scan interval. + * For each scan, + * the total per channel dwell time across all scans with in OBSS scan interval should be + * atleast obss_scan_passive_total_per channel for passive scas and obss_scan_active_total_per channel + * for active scans and , + * The unit for these 2 parameters is TUs. + */ + A_UINT32 obss_scan_passive_total_per_channel; + A_UINT32 obss_scan_active_total_per_channel; + A_UINT32 bss_width_channel_transition_delay_factor; /** parameter to check exemption from scan */ + A_UINT32 obss_scan_activity_threshold; /** parameter to check exemption from scan */ + /** following two parameters used by FW to fill IEs when sending 20/40 coexistence action frame to AP */ + A_UINT32 forty_mhz_intolerant; /** STA 40M bandwidth intolerant capability */ + A_UINT32 current_operating_class; /** STA current operating class */ + /** length of 2.4GHz channel list to scan at, channel list in tlv->channels[] */ + A_UINT32 channel_len; + /** length of optional ie data to append to probe reqest when active scan, ie data in tlv->ie_field[] */ + A_UINT32 ie_len; +} wmi_obss_scan_enable_cmd_fixed_param; + +typedef struct { + /** + * TLV tag and len; + * tag equals WMITLV_TAG_STRUC_wmi_obss_scan_disalbe_cmd_fixed_param + */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; +} wmi_obss_scan_disable_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_offload_prb_rsp_tx_status_event_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** prb rsp tx status, values defined in enum WMI_FRAME_TX_STATUS */ + A_UINT32 tx_status; +}wmi_offload_prb_rsp_tx_status_event_fixed_param; + +typedef enum { + WMI_FRAME_TX_OK, /* frame tx ok */ + WMI_FRAME_TX_XRETRY, /* excessivley retried */ + WMI_FRAME_TX_DROP, /* frame dropped by FW due to resources */ + WMI_FRAME_TX_FILTERED, /* frame filtered by hardware */ +} WMI_FRAME_TX_STATUS; + +/** + * This command is sent from WLAN host driver to firmware to + * request firmware to send the latest channel avoidance range + * to host. + * + * This command is only applicable for APQ platform which has + * modem on the platform. If firmware doesn't support MWS Coex, + * this command can be dropped by firmware. + * + * Host would send this command to firmware to request a channel + * avoidance information update. + */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param */ + A_UINT32 tlv_header; +} wmi_chan_avoid_update_cmd_param; + +/* ExtScan operation mode */ +typedef enum { + WMI_EXTSCAN_MODE_NONE = 0x0000, + WMI_EXTSCAN_MODE_START = 0x0001, // ExtScan/TableMonitoring operation started + WMI_EXTSCAN_MODE_STOP = 0x0002, // ExtScan/TableMonitoring operation stopped + WMI_EXTSCAN_MODE_IGNORED = 0x0003, // ExtScan command ignored due to error +} wmi_extscan_operation_mode; + +/* Channel Mask */ +typedef enum { + WMI_CHANNEL_BAND_UNSPECIFIED = 0x0000, + WMI_CHANNEL_BAND_24 = 0x0001, // 2.4 channel + WMI_CHANNEL_BAND_5_NON_DFS = 0x0002, // 5G Channels (No DFS channels) + WMI_CHANNEL_BAND_DFS = 0x0004, // DFS channels +} wmi_channel_band_mask; + +typedef enum { + WMI_EXTSCAN_CYCLE_STARTED_EVENT = 0x0001, + WMI_EXTSCAN_CYCLE_COMPLETED_EVENT = 0x0002, + WMI_EXTSCAN_BUCKET_STARTED_EVENT = 0x0004, + WMI_EXTSCAN_BUCKET_COMPLETED_EVENT = 0x0008, + WMI_EXTSCAN_BUCKET_FAILED_EVENT = 0x0010, + WMI_EXTSCAN_BUCKET_OVERRUN_EVENT = 0x0020, + + WMI_EXTSCAN_EVENT_MAX = 0x8000 +} wmi_extscan_event_type; + +#define WMI_EXTSCAN_CYCLE_EVENTS_MASK (WMI_EXTSCAN_CYCLE_STARTED_EVENT | \ + WMI_EXTSCAN_CYCLE_COMPLETED_EVENT) + +#define WMI_EXTSCAN_BUCKET_EVENTS_MASK (WMI_EXTSCAN_BUCKET_STARTED_EVENT | \ + WMI_EXTSCAN_BUCKET_COMPLETED_EVENT | \ + WMI_EXTSCAN_BUCKET_FAILED_EVENT | \ + WMI_EXTSCAN_BUCKET_OVERRUN_EVENT) + +typedef enum { + WMI_EXTSCAN_NO_FORWARDING = 0x0000, + WMI_EXTSCAN_FORWARD_FRAME_TO_HOST = 0x0001 +} wmi_extscan_forwarding_flags; + +typedef enum { + WMI_EXTSCAN_USE_MSD = 0x0001, // Use Motion Sensor Detection */ + WMI_EXTSCAN_EXTENDED_BATCHING_EN = 0x0002, // Extscan LPASS extended batching feature is supported and enabled +} wmi_extscan_configuration_flags; + +typedef enum { + WMI_EXTSCAN_BUCKET_CACHE_RESULTS = 0x0001, // Cache the results of bucket whose configuration flags has this bit set +} wmi_extscan_bucket_configuration_flags; + +typedef enum { + WMI_EXTSCAN_STATUS_OK = 0, + WMI_EXTSCAN_STATUS_ERROR = 0x80000000, + WMI_EXTSCAN_STATUS_INVALID_PARAMETERS, + WMI_EXTSCAN_STATUS_INTERNAL_ERROR +} wmi_extscan_start_stop_status; + +typedef struct { + /** Request ID - to identify command. Cannot be 0 */ + A_UINT32 request_id; + /** Requestor ID - client requesting ExtScan */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; +} wmi_extscan_command_id; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /** channel number */ + A_UINT32 channel; + + /** dwell time in msec - use defaults if 0 */ + A_UINT32 min_dwell_time; + A_UINT32 max_dwell_time; + /** passive/active channel and other flags */ + A_UINT32 control_flags; // 0 => active, 1 => passive scan; ignored for DFS +} wmi_extscan_bucket_channel; + +/* Scan Bucket specification */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /** Bucket ID - 0-based */ + A_UINT32 bucket_id; + /** ExtScan events subscription - events to be reported to client (see wmi_extscan_event_type) */ + A_UINT32 notify_extscan_events; + /** Options to forward scan results - see wmi_extscan_forwarding_flags */ + A_UINT32 forwarding_flags; + /** ExtScan configuration flags - wmi_extscan__bucket_configuration_flags */ + A_UINT32 configuration_flags; + /** DEPRECATED member: multiplier to be applied to the periodic scan's base period */ + A_UINT32 base_period_multiplier; + /** dwell time in msec on active channels - use defaults if 0 */ + A_UINT32 min_dwell_time_active; + A_UINT32 max_dwell_time_active; + /** dwell time in msec on passive channels - use defaults if 0 */ + A_UINT32 min_dwell_time_passive; + A_UINT32 max_dwell_time_passive; + /** see wmi_channel_band_mask; when equal to WMI_CHANNEL_UNSPECIFIED, use channel list */ + A_UINT32 channel_band; + /** number of channels (if channel_band is WMI_CHANNEL_UNSPECIFIED) */ + A_UINT32 num_channels; + /** scan period upon start or restart of the bucket - periodicity of the bucket to begin with */ + A_UINT32 min_period; + /** period above which exponent is not applied anymore */ + A_UINT32 max_period; + /** back off value to be applied to bucket's periodicity after exp_max_step_count scan cycles + * new_bucket_period = last_bucket_period + last_exponent_period * exp_backoff + */ + A_UINT32 exp_backoff; + /** number of scans performed at a given periodicity after which exponential back off value is + * applied to current periodicity to obtain a newer one + */ + A_UINT32 exp_max_step_count; +/** Followed by the variable length TLV chan_list: + * wmi_extscan_bucket_channel chan_list[] */ +} wmi_extscan_bucket; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param */ + /** Request ID - to identify command. Cannot be 0 */ + A_UINT32 request_id; + /** Requestor ID - client requesting ExtScan */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; + /** Base period (milliseconds) used by scan buckets to define periodicity of the scans */ + A_UINT32 base_period; + /** Maximum number of iterations to run - one iteration is the scanning of the least frequent bucket */ + A_UINT32 max_iterations; + /** Options to forward scan results - see wmi_extscan_forwarding_flags */ + A_UINT32 forwarding_flags; + /** ExtScan configuration flags - wmi_extscan_configuration_flags */ + A_UINT32 configuration_flags; + /** ExtScan events subscription - bitmask indicating which events should be send to client (see wmi_extscan_event_type) */ + A_UINT32 notify_extscan_events; + /** Scan Priority, input to scan scheduler */ + A_UINT32 scan_priority; + /** Maximum number of BSSIDs to cache on each scan cycle */ + A_UINT32 max_bssids_per_scan_cycle; + /** Minimum RSSI value to report */ + A_UINT32 min_rssi; + /** Maximum table usage in percentage */ + A_UINT32 max_table_usage; + /** default dwell time in msec on active channels */ + A_UINT32 min_dwell_time_active; + A_UINT32 max_dwell_time_active; + /** default dwell time in msec on passive channels */ + A_UINT32 min_dwell_time_passive; + A_UINT32 max_dwell_time_passive; + /** min time in msec on the BSS channel,only valid if atleast one VDEV is active*/ + A_UINT32 min_rest_time; + /** max rest time in msec on the BSS channel,only valid if at least one VDEV is active*/ + /** the scanner will rest on the bss channel at least min_rest_time. after min_rest_time the scanner + * will start checking for tx/rx activity on all VDEVs. if there is no activity the scanner will + * switch to off channel. if there is activity the scanner will let the radio on the bss channel + * until max_rest_time expires.at max_rest_time scanner will switch to off channel + * irrespective of activity. activity is determined by the idle_time parameter. + */ + A_UINT32 max_rest_time; + /** time before sending next set of probe requests. + * The scanner keeps repeating probe requests transmission with period specified by repeat_probe_time. + * The number of probe requests specified depends on the ssid_list and bssid_list + */ + /** Max number of probes to be sent */ + A_UINT32 n_probes; + /** time in msec between 2 sets of probe requests. */ + A_UINT32 repeat_probe_time; + /** time in msec between 2 consequetive probe requests with in a set. */ + A_UINT32 probe_spacing_time; + /** data inactivity time in msec on bss channel that will be used by scanner for measuring the inactivity */ + A_UINT32 idle_time; + /** maximum time in msec allowed for scan */ + A_UINT32 max_scan_time; + /** delay in msec before sending first probe request after switching to a channel */ + A_UINT32 probe_delay; + /** Scan control flags */ + A_UINT32 scan_ctrl_flags; + /** Burst duration time in msec*/ + A_UINT32 burst_duration; + + /** number of bssids in the TLV bssid_list[] */ + A_UINT32 num_bssid; + /** number of ssid in the TLV ssid_list[] */ + A_UINT32 num_ssids; + /** number of bytes in TLV ie_data[] */ + A_UINT32 ie_len; + /** number of buckets in the TLV bucket_list[] */ + A_UINT32 num_buckets; + /** in number of scans, send notifications to host after these many scans */ + A_UINT32 report_threshold_num_scans; + /** number of channels in channel_list[] determined by the + sum of wmi_extscan_bucket.num_channels in array */ + +/** + * TLV (tag length value ) parameters follow the extscan_cmd + * structure. The TLV's are: + * wmi_ssid ssid_list[]; + * wmi_mac_addr bssid_list[]; + * A_UINT8 ie_data[]; + * wmi_extscan_bucket bucket_list[]; + * wmi_extscan_bucket_channel channel_list[]; + */ +} wmi_extscan_start_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param */ + /** Request ID - to match running command. 0 matches any request */ + A_UINT32 request_id; + /** Requestor ID - client requesting stop */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; +} wmi_extscan_stop_cmd_fixed_param; + +enum wmi_extscan_get_cached_results_flags { + WMI_EXTSCAN_GET_CACHED_RESULTS_FLAG_NONE = 0x0000, + WMI_EXTSCAN_GET_CACHED_RESULTS_FLAG_FLUSH_TABLE = 0x0001 +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param */ + /** request ID - used to correlate command with events */ + A_UINT32 request_id; + /** Requestor ID - client that requested results */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; + /** maximum number of results to be returned */ + A_UINT32 max_results; + /** flush BSSID list - wmi_extscan_get_cached_results_flags */ + A_UINT32 control_flags; // enum wmi_extscan_get_cached_results_flags +} wmi_extscan_get_cached_results_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_get_wlan_change_results_cmd_fixed_param */ + /** request ID - used to correlate command with events */ + A_UINT32 request_id; + /** Requestor ID - client that requested results */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; +} wmi_extscan_get_wlan_change_results_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**bssid */ + wmi_mac_addr bssid; + /**channel number */ + A_UINT32 channel; + /**upper RSSI limit */ + A_UINT32 upper_rssi_limit; + /**lower RSSI limit */ + A_UINT32 lower_rssi_limit; +} wmi_extscan_wlan_change_bssid_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param */ + /** Request ID - to identify command. Cannot be 0 */ + A_UINT32 request_id; + /** Requestor ID - client requesting wlan change monitoring */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** operation mode: start/stop */ + A_UINT32 mode; // wmi_extscan_operation_mode + /** number of rssi samples to store */ + A_UINT32 max_rssi_samples; + /** number of samples to use to calculate RSSI average */ + A_UINT32 rssi_averaging_samples; + /** number of scans to confirm loss of contact with RSSI */ + A_UINT32 lost_ap_scan_count; + /** number of out-of-range BSSIDs necessary to send event */ + A_UINT32 max_out_of_range_count; + /** total number of bssid signal descriptors (in all pages) */ + A_UINT32 total_entries; + /** index of the first bssid entry found in the TLV wlan_change_descriptor_list*/ + A_UINT32 first_entry_index; + /** number of bssid signal descriptors in this page */ + A_UINT32 num_entries_in_page; + /* Following this structure is the TLV: + * wmi_extscan_wlan_change_bssid_param wlan_change_descriptor_list[]; // number of elements given by field num_page_entries. + */ +} wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**bssid */ + wmi_mac_addr bssid; + /**RSSI min threshold for reporting */ + A_UINT32 min_rssi; + /**Deprecated entry - channel number */ + A_UINT32 channel; + /** RSSI max threshold for reporting */ + A_UINT32 max_rssi; +} wmi_extscan_hotlist_entry; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param */ + /** Request ID - to identify command. Cannot be 0 */ + A_UINT32 request_id; + /** Requestor ID - client requesting hotlist monitoring */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** operation mode: start/stop */ + A_UINT32 mode; // wmi_extscan_operation_mode + /**total number of bssids (in all pages) */ + A_UINT32 total_entries; + /**index of the first bssid entry found in the TLV wmi_extscan_hotlist_entry*/ + A_UINT32 first_entry_index; + /**number of bssids in this page */ + A_UINT32 num_entries_in_page; + /** number of consecutive scans to confirm loss of contact with AP */ + A_UINT32 lost_ap_scan_count; + /* Following this structure is the TLV: + * wmi_extscan_hotlist_entry hotlist[]; // number of elements given by field num_page_entries. + */ +} wmi_extscan_configure_hotlist_monitor_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**ssid */ + wmi_ssid ssid; + /**band */ + A_UINT32 band; + /**RSSI threshold for reporting */ + A_UINT32 min_rssi; + A_UINT32 max_rssi; +} wmi_extscan_hotlist_ssid_entry; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param */ + /** Request ID - to identify command. Cannot be 0 */ + A_UINT32 request_id; + /** Requestor ID - client requesting hotlist ssid monitoring */ + A_UINT32 requestor_id; + /** VDEV id(interface) that is requesting scan */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** operation mode: start/stop */ + A_UINT32 mode; // wmi_extscan_operation_mode + /**total number of ssids (in all pages) */ + A_UINT32 total_entries; + /**index of the first ssid entry found in the TLV wmi_extscan_hotlist_ssid_entry*/ + A_UINT32 first_entry_index; + /**number of ssids in this page */ + A_UINT32 num_entries_in_page; + /** number of consecutive scans to confirm loss of an ssid **/ + A_UINT32 lost_ap_scan_count; + /* Following this structure is the TLV: + * wmi_extscan_hotlist_ssid_entry hotlist_ssid[]; // number of elements given by field num_page_entries. + */ +} wmi_extscan_configure_hotlist_ssid_monitor_cmd_fixed_param; + + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** size in bytes of scan cache entry */ + A_UINT32 scan_cache_entry_size; + /** maximum number of scan cache entries */ + A_UINT32 max_scan_cache_entries; + /** maximum number of buckets per extscan request */ + A_UINT32 max_buckets; + /** maximum number of BSSIDs that will be stored in each scan (best n/w as per RSSI) */ + A_UINT32 max_bssid_per_scan; + /** table usage level at which indication must be sent to host */ + A_UINT32 max_table_usage_threshold; +} wmi_extscan_cache_capabilities; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** size in bytes of wlan change entry */ + A_UINT32 wlan_change_entry_size; + /** maximum number of entries in wlan change table */ + A_UINT32 max_wlan_change_entries; + /** number of RSSI samples used for averaging RSSI */ + A_UINT32 max_rssi_averaging_samples; + /** number of BSSID/RSSI entries (BSSID pointer, RSSI, timestamp) that device can hold */ + A_UINT32 max_rssi_history_entries; +} wmi_extscan_wlan_change_monitor_capabilities; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /** size in bytes of hotlist entry */ + A_UINT32 wlan_hotlist_entry_size; + /** maximum number of entries in wlan change table */ + A_UINT32 max_hotlist_entries; +} wmi_extscan_hotlist_monitor_capabilities; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_set_capabilities_cmd_fixed_param */ + /** Request ID - matches request ID used to start hot list monitoring */ + A_UINT32 request_id; + /** Requestor ID - client requesting stop */ + A_UINT32 requestor_id; + /** number of extscan caches */ + A_UINT32 num_extscan_cache_tables; + /** number of wlan change lists */ + A_UINT32 num_wlan_change_monitor_tables; + /** number of hotlists */ + A_UINT32 num_hotlist_monitor_tables; + /** if one sided rtt data collection is supported */ + A_UINT32 rtt_one_sided_supported; + /** if 11v data collection is supported */ + A_UINT32 rtt_11v_supported; + /** if 11mc data collection is supported */ + A_UINT32 rtt_ftm_supported; + /** number of extscan cache capabilities (one per table) */ + A_UINT32 num_extscan_cache_capabilities; + /** number of wlan change capabilities (one per table) */ + A_UINT32 num_extscan_wlan_change_capabilities; + /** number of extscan hotlist capabilities (one per table) */ + A_UINT32 num_extscan_hotlist_capabilities; + /* Following this structure is the TLV: + * wmi_extscan_cache_capabilities extscan_cache_capabilities; // number of capabilities given by num_extscan_caches + * wmi_extscan_wlan_change_monitor_capabilities wlan_change_capabilities; // number of capabilities given by num_wlan_change_monitor_tables + * wmi_extscan_hotlist_monitor_capabilities hotlist_capabilities; // number of capabilities given by num_hotlist_monitor_tables + */ +} wmi_extscan_set_capabilities_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param */ + /** Request ID - matches request ID used to start hot list monitoring */ + A_UINT32 request_id; + /** Requestor ID - client requesting capabilities */ + A_UINT32 requestor_id; +} wmi_extscan_get_capabilities_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param */ + /** Request ID of the operation that was started/stopped */ + A_UINT32 request_id; + /** Requestor ID of the operation that was started/stopped */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the operation that was started/stopped */ + A_UINT32 vdev_id; + /** extscan WMI command */ + A_UINT32 command; + /** operation mode: start/stop */ + A_UINT32 mode; // wmi_extscan_operation_mode + /**success/failure */ + A_UINT32 status; // enum wmi_extscan_start_stop_status + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; +} wmi_extscan_start_stop_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param */ + /** Request ID of the extscan operation that is currently running */ + A_UINT32 request_id; + /** Requestor ID of the extscan operation that is currently running */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the extscan operation that is currently running */ + A_UINT32 vdev_id; + /** scan event (wmi_scan_event_type) */ + A_UINT32 event; // wmi_extscan_event_type + /** table ID - to allow support for multiple simultaneous requests */ + A_UINT32 table_id; + /**number of buckets */ + A_UINT32 num_buckets; + /* Following this structure is the TLV: + * A_UINT32 bucket_id[]; // number of elements given by field num_buckets. + */ +} wmi_extscan_operation_event_fixed_param; + +/* Types of extscan tables */ +typedef enum { + EXTSCAN_TABLE_NONE = 0, + EXTSCAN_TABLE_BSSID = 1, + EXTSCAN_TABLE_RSSI = 2, +} wmi_extscan_table_type; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param */ + /** Request ID of the extscan operation that is currently running */ + A_UINT32 request_id; + /** Requestor ID of the extscan operation that is currently running */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the extscan operation that is currently running */ + A_UINT32 vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /**see wmi_extscan_table_type for table reporting usage */ + A_UINT32 table_type; + /**number of entries in use */ + A_UINT32 entries_in_use; + /**maximum number of entries in table */ + A_UINT32 maximum_entries; +} wmi_extscan_table_usage_event_fixed_param; + +typedef enum { + WMI_SCAN_STATUS_INTERRUPTED = 1 /* Indicates scan got interrupted i.e. aborted or pre-empted for a long time (> 1sec) + this can be used to discard scan results */ +} wmi_scan_status_flags; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**RSSI */ + A_UINT32 rssi; + /**time stamp in milliseconds */ + A_UINT32 tstamp; + /** Extscan cycle during which this entry was scanned */ + A_UINT32 scan_cycle_id; + /** flag to indicate if the given result was obtained as part of interrupted (aborted/large time gap preempted) scan */ + A_UINT32 flags; +} wmi_extscan_rssi_info; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**bssid */ + wmi_mac_addr bssid; + /**ssid */ + wmi_ssid ssid; + /**channel number */ + A_UINT32 channel; + /* capabilities */ + A_UINT32 capabilities; + /* beacon interval in TUs */ + A_UINT32 beacon_interval; + /**time stamp in milliseconds - time last seen */ + A_UINT32 tstamp; + /**flags - _tExtScanEntryFlags */ + A_UINT32 flags; + /**RTT in ns */ + A_UINT32 rtt; + /**rtt standard deviation */ + A_UINT32 rtt_sd; + /* rssi information */ + A_UINT32 number_rssi_samples; + /** IE length */ + A_UINT32 ie_length; // length of IE data +} wmi_extscan_wlan_descriptor; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param */ + /** Request ID of the WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID */ + A_UINT32 request_id; + /** Requestor ID of the WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID */ + A_UINT32 vdev_id; + /** Request ID of the extscan operation that is currently running */ + A_UINT32 extscan_request_id; + /** Requestor ID of the extscan operation that is currently running */ + A_UINT32 extscan_requestor_id; + /** VDEV id(interface) of the extscan operation that is currently running */ + A_UINT32 extscan_vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /**current time stamp in seconds. Used to provide a baseline for the relative timestamps returned for each block and entry */ + A_UINT32 current_tstamp; + /**total number of bssids (in all pages) */ + A_UINT32 total_entries; + /**index of the first bssid entry found in the TLV wmi_extscan_wlan_descriptor*/ + A_UINT32 first_entry_index; + /**number of bssids in this page */ + A_UINT32 num_entries_in_page; + /* Followed by the variable length TLVs + * wmi_extscan_wlan_descriptor bssid_list[] + * wmi_extscan_rssi_info rssi_list[] + * A_UINT8 ie_list[] + */ +} wmi_extscan_cached_results_event_fixed_param; + +typedef enum { + EXTSCAN_WLAN_CHANGE_FLAG_NONE = 0x00, + EXTSCAN_WLAN_CHANGE_FLAG_OUT_OF_RANGE = 0x01, + EXTSCAN_WLAN_CHANGE_FLAG_AP_LOST = 0x02, +} wmi_extscan_wlan_change_flags; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_ARRAY_STRUC */ + /**bssid */ + wmi_mac_addr bssid; + /**time stamp in milliseconds */ + A_UINT32 tstamp; + /**upper RSSI limit */ + A_UINT32 upper_rssi_limit; + /**lower RSSI limit */ + A_UINT32 lower_rssi_limit; + /** channel */ + A_UINT32 channel; /* in MHz */ + /**current RSSI average */ + A_UINT32 rssi_average; + /**flags - wmi_extscan_wlan_change_flags */ + A_UINT32 flags; + /**legnth of RSSI history to follow (number of values) */ + A_UINT32 num_rssi_samples; +} wmi_extscan_wlan_change_result_bssid; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param */ + /** Request ID of the WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID command that requested the results */ + A_UINT32 request_id; + /** Requestor ID of the WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID command that requested the results */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID command that requested the results */ + A_UINT32 vdev_id; + /** Request ID of the WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID command that configured the table */ + A_UINT32 config_request_id; + /** Requestor ID of the WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID command that configured the table */ + A_UINT32 config_requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID command that configured the table */ + A_UINT32 config_vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /**number of entries with RSSI out of range or BSSID not detected */ + A_UINT32 change_count; + /**total number of bssid signal descriptors (in all pages) */ + A_UINT32 total_entries; + /**index of the first bssid signal descriptor entry found in the TLV wmi_extscan_wlan_descriptor*/ + A_UINT32 first_entry_index; + /**number of bssids signal descriptors in this page */ + A_UINT32 num_entries_in_page; + /* Following this structure is the TLV: + * wmi_extscan_wlan_change_result_bssid bssid_signal_descriptor_list[]; // number of descriptors given by field num_entries_in_page. + * Following this structure is the list of RSSI values (each is an A_UINT8): + * A_UINT8 rssi_list[]; // last N RSSI values. + */ +} wmi_extscan_wlan_change_results_event_fixed_param; + +enum _tExtScanEntryFlags +{ + WMI_HOTLIST_FLAG_NONE = 0x00, + WMI_HOTLIST_FLAG_PRESENCE = 0x01, + WMI_HOTLIST_FLAG_DUPLICATE_SSID = 0x80, +}; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param */ + /** Request ID of the WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID that configured the table */ + A_UINT32 config_request_id; + /** Requestor ID of the WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID that configured the table */ + A_UINT32 config_requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID that configured the table */ + A_UINT32 config_vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /**total number of bssids (in all pages) */ + A_UINT32 total_entries; + /**index of the first bssid entry found in the TLV wmi_extscan_wlan_descriptor*/ + A_UINT32 first_entry_index; + /**number of bssids in this page */ + A_UINT32 num_entries_in_page; + /* Following this structure is the TLV: + * wmi_extscan_wlan_descriptor hotlist_match[]; // number of descriptors given by field num_entries_in_page. + */ +} wmi_extscan_hotlist_match_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param */ + /** Request ID of the WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID that configured the table */ + A_UINT32 config_request_id; + /** Requestor ID of the WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID that configured the table */ + A_UINT32 config_requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID that configured the table */ + A_UINT32 config_vdev_id; + /** table ID - to allow support for multiple simultaneous tables */ + A_UINT32 table_id; + /**total number of ssids (in all pages) */ + A_UINT32 total_entries; + /**index of the first ssid entry found in the TLV wmi_extscan_wlan_descriptor*/ + A_UINT32 first_entry_index; + /**number of ssids in this page */ + A_UINT32 num_entries_in_page; + /* Following this structure is the TLV: + * wmi_extscan_wlan_descriptor hotlist_match[]; // number of descriptors given by field num_entries_in_page. + */ +} wmi_extscan_hotlist_ssid_match_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param */ + /** Request ID of the WMI_EXTSCAN_GET_CAPABILITIES_CMDID */ + A_UINT32 request_id; + /** Requestor ID of the WMI_EXTSCAN_GET_CAPABILITIES_CMDID */ + A_UINT32 requestor_id; + /** VDEV id(interface) of the WMI_EXTSCAN_GET_CAPABILITIES_CMDID */ + A_UINT32 vdev_id; + /** number of extscan caches */ + A_UINT32 num_extscan_cache_tables; + /** number of wlan change lists */ + A_UINT32 num_wlan_change_monitor_tables; + /** number of hotlists */ + A_UINT32 num_hotlist_monitor_tables; + /** if one sided rtt data collection is supported */ + A_UINT32 rtt_one_sided_supported; + /** if 11v data collection is supported */ + A_UINT32 rtt_11v_supported; + /** if 11mc data collection is supported */ + A_UINT32 rtt_ftm_supported; + /** number of extscan cache capabilities (one per table) */ + A_UINT32 num_extscan_cache_capabilities; + /** number of wlan change capabilities (one per table) */ + A_UINT32 num_extscan_wlan_change_capabilities; + /** number of extscan hotlist capabilities (one per table) */ + A_UINT32 num_extscan_hotlist_capabilities; + /* max number of roaming ssid whitelist firmware can support */ + A_UINT32 num_roam_ssid_whitelist; + /* max number of blacklist bssid firmware can support */ + A_UINT32 num_roam_bssid_blacklist; + /* max number of preferred list firmware can support */ + A_UINT32 num_roam_bssid_preferred_list; + /* max number of hotlist ssids firmware can support */ + A_UINT32 num_extscan_hotlist_ssid; + /* max number of epno networks firmware can support */ + A_UINT32 num_epno_networks; + + /* Following this structure are the TLVs describing the capabilities of of the various types of lists. The FW theoretically + * supports multiple lists of each type. + * + * wmi_extscan_cache_capabilities extscan_cache_capabilities[] // capabilities of extscan cache (BSSID/RSSI lists) + * wmi_extscan_wlan_change_monitor_capabilities wlan_change_capabilities[] // capabilities of wlan_change_monitor_tables + * wmi_extscan_hotlist_monitor_capabilities hotlist_capabilities[] // capabilities of hotlist_monitor_tables + */ +} wmi_extscan_capabilities_event_fixed_param; + +/* WMI_D0_WOW_DISABLE_ACK_EVENTID */ +typedef struct{ + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_d0_wow_disable_ack_event_fixed_param */ + A_UINT32 reserved0; /* for future need */ +} wmi_d0_wow_disable_ack_event_fixed_param; + +/** WMI_PDEV_RESUME_EVENTID : generated in response to WMI_PDEV_RESUME_CMDID */ +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_resume_event_fixed_param */ + A_UINT32 rsvd; /* for future need */ +} wmi_pdev_resume_event_fixed_param; + + +/** value representing all modules */ +#define WMI_DEBUG_LOG_MODULE_ALL 0xffff + +/* param definitions */ + +/** + * Log level for a given module. Value contains both module id and log level. + * here is the bitmap definition for value. + * module Id : 16 + * Flags : reserved + * Level : 8 + * if odule Id is WMI_DEBUG_LOG_MODULE_ALL then log level is applied to all modules (global). + * WMI_DEBUG_LOG_MIDULE_ALL will overwrites per module level setting. + */ +#define WMI_DEBUG_LOG_PARAM_LOG_LEVEL 0x1 + +#define WMI_DBGLOG_SET_LOG_LEVEL(val,lvl) do { \ + (val) |= (lvl & 0xff); \ + } while(0) + +#define WMI_DBGLOG_GET_LOG_LEVEL(val) ((val) & 0xff) + +#define WMI_DBGLOG_SET_MODULE_ID(val,mid) do { \ + (val) |= ((mid & 0xffff) << 16); \ + } while(0) + +#define WMI_DBGLOG_GET_MODULE_ID(val) (( (val) >> 16) & 0xffff) + +/** + * Enable the debug log for a given vdev. Value is vdev id + */ +#define WMI_DEBUG_LOG_PARAM_VDEV_ENABLE 0x2 + + +/** + * Disable the debug log for a given vdev. Value is vdev id + * All the log level for a given VDEV is disabled except the ERROR log messages + */ + +#define WMI_DEBUG_LOG_PARAM_VDEV_DISABLE 0x3 + +/** + * set vdev enable bitmap. value is the vden enable bitmap + */ +#define WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP 0x4 + +/** + * set a given log level to all the modules specified in the module bitmap. + * and set the log levle for all other modules to DBGLOG_ERR. + * value: log levelt to be set. + * module_id_bitmap : identifies the modules for which the log level should be set and + * modules for which the log level should be reset to DBGLOG_ERR. + */ +#define WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP 0x5 + +#define NUM_MODULES_PER_ENTRY ((sizeof(A_UINT32)) << 3) + +#define WMI_MODULE_ENABLE(pmid_bitmap,mod_id) \ + ( (pmid_bitmap)[(mod_id)/NUM_MODULES_PER_ENTRY] |= \ + (1 << ((mod_id)%NUM_MODULES_PER_ENTRY)) ) + +#define WMI_MODULE_DISABLE(pmid_bitmap,mod_id) \ + ( (pmid_bitmap)[(mod_id)/NUM_MODULES_PER_ENTRY] &= \ + ( ~(1 << ((mod_id)%NUM_MODULES_PER_ENTRY)) ) ) + +#define WMI_MODULE_IS_ENABLED(pmid_bitmap,mod_id) \ + ( ((pmid_bitmap)[(mod_id)/NUM_MODULES_PER_ENTRY ] & \ + (1 << ((mod_id)%NUM_MODULES_PER_ENTRY)) ) != 0) + +#define MAX_MODULE_ID_BITMAP_WORDS 16 /* 16*32=512 module ids. should be more than sufficient */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param */ + A_UINT32 dbg_log_param; /** param types are defined above */ + A_UINT32 value; + /* The below array will follow this tlv ->fixed length module_id_bitmap[] + A_UINT32 module_id_bitmap[MAX_MODULE_ID_BITMAP_WORDS]; + */ +} wmi_debug_log_config_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_get_temperature_cmd_fixed_param */ + A_UINT32 param; /* Reserved for future use */ +} wmi_pdev_get_temperature_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_pdev_temperature_event_fixed_param */ + A_INT32 value; /* temprature value in Celcius degree */ +} wmi_pdev_temperature_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_set_dhcp_server_offload_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 enable; + A_UINT32 srv_ipv4; /* server IP */ + A_UINT32 start_lsb; /* starting address assigned to client */ + A_UINT32 num_client; /* number of clients we support */ +} wmi_set_dhcp_server_offload_cmd_fixed_param; + +typedef enum { + AP_RX_DATA_OFFLOAD = 0x00, + STA_RX_DATA_OFFLOAD = 0x01, +} wmi_ipa_offload_types; + +/** + * This command is sent from WLAN host driver to firmware for + * enabling/disabling IPA data-path offload features. + * + * + * Enabling data path offload to IPA(based on host INI configuration), example: + * when STA interface comes up, + * host->target: WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMD, + * (enable = 1, vdev_id = STA vdev id, offload_type = STA_RX_DATA_OFFLOAD) + * + * Disabling data path offload to IPA, example: + * host->target: WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMD, + * (enable = 0, vdev_id = STA vdev id, offload_type = STA_RX_DATA_OFFLOAD) + * + * + * This command is applicable only on the PCIE LL systems + * + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_ipa_offload_enable_disable_cmd_fixed_param */ + A_UINT32 offload_type; /* wmi_ipa_offload_types enum values */ + A_UINT32 vdev_id; + A_UINT32 enable; /* 1 == enable, 0 == disable */ +} wmi_ipa_offload_enable_disable_cmd_fixed_param; + +typedef enum { + WMI_LED_FLASHING_PATTERN_NOT_CONNECTED = 0, + WMI_LED_FLASHING_PATTERN_CONNECTED = 1, + WMI_LED_FLASHING_PATTERN_RESERVED = 2, +} wmi_set_led_flashing_type; + +/** +The state of the LED GPIO control is determined by two 32 bit values(X_0 and X_1) to produce a 64 bit value. +Each 32 bit value consists of 4 bytes, where each byte defines the number of 50ms intervals that the GPIO will +remain at a predetermined state. The 64 bit value provides 8 unique GPIO timing intervals. The pattern starts +with the MSB of X_0 and continues to the LSB of X_1. After executing the timer interval of the LSB of X_1, the +pattern returns to the MSB of X_0 and repeats. The GPIO state for each timing interval alternates from Low to +High and the first interval of the pattern represents the time when the GPIO is Low. When a timing interval of +Zero is reached, it is skipped and moves on to the next interval. +*/ +typedef struct{ + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param */ + A_UINT32 pattern_id; /* pattern identifier */ + A_UINT32 led_x0; /* led flashing parameter0 */ + A_UINT32 led_x1; /* led flashing parameter1 */ + A_UINT32 gpio_num; /* GPIO number */ +} wmi_set_led_flashing_cmd_fixed_param; + +/** + * The purpose of the multicast Domain Name System (mDNS) is to resolve host names to IP addresses + * within small networks that do not include a local name server. + * It utilizes essentially the same programming interfaces, packet formats and operating semantics + * as the unicast DNS, and the advantage is zero configuration service while no need for central or + * global server. + * Based on mDNS, the DNS-SD (Service Discovery) allows clients to discover a named list of services + * by type in a specified domain using standard DNS queries. + * Here, we provide the ability to advertise the available services by responding to mDNS queries. + */ +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mdns_offload_cmd_fixed_param */ + A_UINT32 vdev_id; + A_UINT32 enable; +} wmi_mdns_offload_cmd_fixed_param; + +#define WMI_MAX_MDNS_FQDN_LEN 64 +#define WMI_MAX_MDNS_RESP_LEN 512 +#define WMI_MDNS_FQDN_TYPE_GENERAL 0 +#define WMI_MDNS_FQDN_TYPE_UNIQUE 1 + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mdns_set_fqdn_cmd_fixed_param */ + A_UINT32 vdev_id; + /** type of fqdn, general or unique */ + A_UINT32 type; + /** length of fqdn */ + A_UINT32 fqdn_len; + /* Following this structure is the TLV byte stream of fqdn data of length fqdn_len + * A_UINT8 fqdn_data[]; // fully-qualified domain name to check if match with the received queries + */ +} wmi_mdns_set_fqdn_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mdns_set_resp_cmd_fixed_param */ + A_UINT32 vdev_id; + /** Answer Resource Record count */ + A_UINT32 AR_count; + /** length of response */ + A_UINT32 resp_len; + /* Following this structure is the TLV byte stream of resp data of length resp_len + * A_UINT8 resp_data[]; // responses consisits of Resource Records + */ +} wmi_mdns_set_resp_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mdns_get_stats_cmd_fixed_param */ + A_UINT32 vdev_id; +} wmi_mdns_get_stats_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_mdns_stats_event_fixed_param */ + A_UINT32 vdev_id; + /** curTimestamp in milliseconds */ + A_UINT32 curTimestamp; + /** last received Query in milliseconds */ + A_UINT32 lastQueryTimestamp; + /** last sent Response in milliseconds */ + A_UINT32 lastResponseTimestamp; + /** stats of received queries */ + A_UINT32 totalQueries; + /** stats of macth queries */ + A_UINT32 totalMatches; + /** stats of responses */ + A_UINT32 totalResponses; + /** indicate the current status of mDNS offload */ + A_UINT32 status; +} wmi_mdns_stats_event_fixed_param; + +/** + * The purpose of the SoftAP authenticator offload is to offload the association and 4-way handshake process + * down to the firmware. When this feature is enabled, firmware can process the association/disassociation + * request and create/remove connection even host is suspended. + * 3 major components are offloaded: + * 1. ap-mlme. Firmware will process auth/deauth, association/disassociation request and send out response. + * 2. 4-way handshake. Firmware will send out m1/m3 and receive m2/m4. + * 3. key installation. Firmware will generate PMK from the psk info which is sent from the host and install PMK/GTK. + * Current implementation only supports WPA2 CCMP. + */ + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sap_ofl_enable_cmd_fixed_param */ + /** VDEV id(interface) of the WMI_SAP_OFL_ENABLE_CMDID */ + A_UINT32 vdev_id; + /** enable/disable sap auth offload */ + A_UINT32 enable; + /** sap ssid */ + wmi_ssid ap_ssid; + /** authentication mode (defined above) */ + A_UINT32 rsn_authmode; + /** unicast cipher set */ + A_UINT32 rsn_ucastcipherset; + /** mcast/group cipher set */ + A_UINT32 rsn_mcastcipherset; + /** mcast/group management frames cipher set */ + A_UINT32 rsn_mcastmgmtcipherset; + /** sap channel */ + A_UINT32 channel; + /** length of psk */ + A_UINT32 psk_len; + /* Following this structure is the TLV byte stream of wpa passphrase data of length psk_len + * A_UINT8 psk[]; + */ +} wmi_sap_ofl_enable_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sap_ofl_add_sta_event_fixed_param */ + /** VDEV id(interface) of the WMI_SAP_OFL_ADD_STA_EVENTID */ + A_UINT32 vdev_id; + /** aid (association id) of this station */ + A_UINT32 assoc_id; + /** peer station's mac addr */ + wmi_mac_addr peer_macaddr; + /** length of association request frame */ + A_UINT32 data_len; + /* Following this structure is the TLV byte stream of a whole association request frame of length data_len + * A_UINT8 bufp[]; + */ +} wmi_sap_ofl_add_sta_event_fixed_param; + +typedef enum { + SAP_OFL_DEL_STA_FLAG_NONE = 0x00, + SAP_OFL_DEL_STA_FLAG_RECONNECT = 0x01, +} wmi_sap_ofl_del_sta_flags; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_sap_ofl_del_sta_event_fixed_param */ + /** VDEV id(interface) of the WMI_SAP_OFL_DEL_STA_EVENTID */ + A_UINT32 vdev_id; + /** aid (association id) of this station */ + A_UINT32 assoc_id; + /** peer station's mac addr */ + wmi_mac_addr peer_macaddr; + /** disassociation reason */ + A_UINT32 reason; + /** flags - wmi_sap_ofl_del_sta_flags */ + A_UINT32 flags; +} wmi_sap_ofl_del_sta_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_apfind_cmd_param */ + A_UINT32 data_len; /** length in byte of data[]. */ + /** This structure is used to send REQ binary blobs + * from application/service to firmware where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_apfind_cmd_param; + +typedef enum apfind_event_type_e { + APFIND_MATCH_EVENT = 0, + APFIND_WAKEUP_EVENT, +} APFIND_EVENT_TYPE; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_apfind_event_hdr */ + A_UINT32 event_type; /** APFIND_EVENT_TYPE */ + A_UINT32 data_len; /** length in byte of data[]. */ + /** This structure is used to send event binary blobs + * from firmware to application/service and Host drv. + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_apfind_event_hdr; + + +/** + * OCB DCC types and structures. + */ + +/** + * DCC types as described in ETSI TS 102 687 + * Type Format stepSize referenceValue numBits + * ------------------------------------------------------------------------- + * ndlType_acPrio INTEGER (0...7) 1 number 3 + * ndlType_controlLoop INTEGER (0...7) 1 0 3 + * ndlType_arrivalRate INTEGER (0..8191) 0.01 /s 0 13 + * ndlType_channelLoad INTEGER (0..1000) 0.1 % 0 % 10 + * ndlType_channelUse INTEGER (0..8000) 0.0125 % 0 % 13 + * ndlType_datarate INTEGER (0..7) Table 8 3 + * ndlType_distance INTEGER (0..4095) 1 m 0 12 + * ndlType_numberElements INTEGER (0..63) number 6 + * ndlType_packetDuration INTEGER (0..2047) TSYM 0 11 + * ndlType_packetInterval INTEGER (0..1023) 10 ms 0 10 + * ndlType_pathloss INTEGER (0..31) 0.1 1.0 5 + * ndlType_rxPower INTEGER (0..127) -0.5 dB -40 dBm 7 + * ndlType_snr INTEGER (0..127) 0.5 dB -10 dB 7 + * ndlType_timing INTEGER (0..4095) 10 ms 0 12 + * ndlType_txPower INTEGER (0..127) 0.5 dB -20 dBm 7 + * ndlType_ratio INTEGER (0..100) 1 % 0 % 7 + * ndlType_exponent INTEGER (0..100) 0.1 0 7 + * ndlType_queueStatus Enumeration Table A.2 1 + * ndlType_dccMechanism Bitset Table A.2 6 + * + * NOTE: All of following size macros (SIZE_NDLTYPE_ACPRIO through SIZE_BYTE) + * cannot be changed without breaking WMI compatibility. + * + * NOTE: For each of the types, one additional bit is allocated. This + * leftmost bit is used to indicate that the value is invalid. */ +#define SIZE_NDLTYPE_ACPRIO (1 + 3 ) +#define SIZE_NDLTYPE_CONTROLLOOP (1 + 3 ) +#define SIZE_NDLTYPE_ARRIVALRATE (1 + 13) +#define SIZE_NDLTYPE_CHANNELLOAD (1 + 10) +#define SIZE_NDLTYPE_CHANNELUSE (1 + 13) +#define SIZE_NDLTYPE_DATARATE (1 + 3 ) +#define SIZE_NDLTYPE_DISTANCE (1 + 12) +#define SIZE_NDLTYPE_NUMBERELEMENTS (1 + 6 ) +#define SIZE_NDLTYPE_PACKETDURATION (1 + 11) +#define SIZE_NDLTYPE_PACKETINTERVAL (1 + 10) +#define SIZE_NDLTYPE_PATHLOSS (1 + 5 ) +#define SIZE_NDLTYPE_RXPOWER (1 + 7 ) +#define SIZE_NDLTYPE_SNR (1 + 7 ) +#define SIZE_NDLTYPE_TIMING (1 + 12) +#define SIZE_NDLTYPE_TXPOWER (1 + 7 ) +#define SIZE_NDLTYPE_RATIO (1 + 7 ) +#define SIZE_NDLTYPE_EXPONENT (1 + 7 ) +#define SIZE_NDLTYPE_QUEUESTATUS (1 + 1 ) +#define SIZE_NDLTYPE_DCCMECHANISM (1 + 6 ) +#define SIZE_BYTE (8) + +#define INVALID_ACPRIO ((1 << SIZE_NDLTYPE_ACPRIO) - 1) +#define INVALID_CONTROLLOOP ((1 << SIZE_NDLTYPE_CONTROLLOOP) - 1) +#define INVALID_ARRIVALRATE ((1 << SIZE_NDLTYPE_ARRIVALRATE) - 1) +#define INVALID_CHANNELLOAD ((1 << SIZE_NDLTYPE_CHANNELLOAD) - 1) +#define INVALID_CHANNELUSE ((1 << SIZE_NDLTYPE_CHANNELUSE) - 1) +#define INVALID_DATARATE ((1 << SIZE_NDLTYPE_DATARATE) - 1) +#define INVALID_DISTANCE ((1 << SIZE_NDLTYPE_DISTANCE) - 1) +#define INVALID_NUMBERELEMENTS ((1 << SIZE_NDLTYPE_NUMBERELEMENTS) - 1) +#define INVALID_PACKETDURATION ((1 << SIZE_NDLTYPE_PACKETDURATION) - 1) +#define INVALID_PACKETINTERVAL ((1 << SIZE_NDLTYPE_PACKETINTERVAL) - 1) +#define INVALID_PATHLOSS ((1 << SIZE_NDLTYPE_PATHLOSS) - 1) +#define INVALID_RXPOWER ((1 << SIZE_NDLTYPE_RXPOWER) - 1) +#define INVALID_SNR ((1 << SIZE_NDLTYPE_SNR) - 1) +#define INVALID_TIMING ((1 << SIZE_NDLTYPE_TIMING) - 1) +#define INVALID_TXPOWER ((1 << SIZE_NDLTYPE_TXPOWER) - 1) +#define INVALID_RATIO ((1 << SIZE_NDLTYPE_RATIO) - 1) +#define INVALID_EXPONENT ((1 << SIZE_NDLTYPE_EXPONENT) - 1) +#define INVALID_QUEUESTATS ((1 << SIZE_NDLTYPE_QUEUESTATUS) - 1) +#define INVALID_DCCMECHANISM ((1 << SIZE_NDLTYPE_DCCMECHANISM) - 1) + +/** The MCS_COUNT macro cannot be modified without breaking + * WMI compatibility. */ +#define MCS_COUNT (8) + +/** Flags for ndlType_dccMechanism. */ +typedef enum { + DCC_MECHANISM_TPC = 1, + DCC_MECHANISM_TRC = 2, + DCC_MECHANISM_TDC = 4, + DCC_MECHANISM_DSC = 8, + DCC_MECHANISM_TAC = 16, + DCC_MECHANISM_RESERVED = 32, + DCC_MECHANISM_ALL = 0x3f, +} wmi_dcc_ndl_type_dcc_mechanism; + +/** Values for ndlType_queueStatus. */ +typedef enum { + DCC_QUEUE_CLOSED = 0, + DCC_QUEUE_OPEN = 1, +} wmi_dcc_ndl_type_queue_status; + +/** For ndlType_acPrio, use the values in wmi_traffic_ac. */ + +/** Values for ndlType_datarate */ +typedef enum { + DCC_DATARATE_3_MBPS = 0, + DCC_DATARATE_4_5_MBPS = 1, + DCC_DATARATE_6_MBPS = 2, + DCC_DATARATE_9_MBPS = 3, + DCC_DATARATE_12_MBPS = 4, + DCC_DATARATE_18_MBPS = 5, + DCC_DATARATE_24_MBPS = 6, + DCC_DATARATE_27_MBPS = 7, +} wmi_dcc_ndl_type_datarate; + +/** Data structure for active state configuration. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_ndl_active_state_config */ + A_UINT32 tlv_header; + /** + * NDL_asStateId, ndlType_numberElements, 1+6 bits. + * NDL_asChanLoad, ndlType_channelLoad, 1+10 bits. + */ + A_UINT32 state_info; + /** + * NDL_asDcc(AC_BK), ndlType_dccMechanism, 1+6 bits. + * NDL_asDcc(AC_BE), ndlType_dccMechanism, 1+6 bits. + * NDL_asDcc(AC_VI), ndlType_dccMechanism, 1+6 bits. + * NDL_asDcc(AC_VO), ndlType_dccMechanism, 1+6 bits. + */ + A_UINT32 as_dcc[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_DCCMECHANISM)]; + + /** + * NDL_asTxPower(AC_BK), ndlType_txPower, 1+7 bits. + * NDL_asTxPower(AC_BE), ndlType_txPower, 1+7 bits. + * NDL_asTxPower(AC_VI), ndlType_txPower, 1+7 bits. + * NDL_asTxPower(AC_VO), ndlType_txPower, 1+7 bits. + */ + A_UINT32 as_tx_power_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_TXPOWER)]; + /** + * NDL_asPacketInterval(AC_BK), ndlType_packetInterval, 1+10 bits. + * NDL_asPacketInterval(AC_BE), ndlType_packetInterval, 1+10 bits. + * NDL_asPacketInterval(AC_VI), ndlType_packetInterval, 1+10 bits. + * NDL_asPacketInterval(AC_VO), ndlType_packetInterval, 1+10 bits. + */ + A_UINT32 as_packet_interval_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_PACKETINTERVAL)]; + /** + * NDL_asDatarate(AC_BK), ndlType_datarate, 1+3 bits. + * NDL_asDatarate(AC_BE), ndlType_datarate, 1+3 bits. + * NDL_asDatarate(AC_VI), ndlType_datarate, 1+3 bits. + * NDL_asDatarate(AC_VO), ndlType_datarate, 1+3 bits. + */ + A_UINT32 as_datarate_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_DATARATE)]; + /** + * NDL_asCarrierSense(AC_BK), ndlType_rxPower, 1+7 bits. + * NDL_asCarrierSense(AC_BE), ndlType_rxPower, 1+7 bits. + * NDL_asCarrierSense(AC_VI), ndlType_rxPower, 1+7 bits. + * NDL_asCarrierSense(AC_VO), ndlType_rxPower, 1+7 bits. + */ + A_UINT32 as_carrier_sense_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_RXPOWER)]; +} wmi_dcc_ndl_active_state_config; + +#define WMI_NDL_AS_STATE_ID_GET(ptr) WMI_GET_BITS((ptr)->state_info, 0, 7) +#define WMI_NDL_AS_STATE_ID_SET(ptr,val) WMI_SET_BITS((ptr)->state_info, 0, 7, val) +#define WMI_NDL_AS_CHAN_LOAD_GET(ptr) WMI_GET_BITS((ptr)->state_info, 7, 11) +#define WMI_NDL_AS_CHAN_LOAD_SET(ptr,val) WMI_SET_BITS((ptr)->state_info, 7, 11, val) +#define WMI_NDL_AS_DCC_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->as_dcc, acprio, SIZE_NDLTYPE_DCCMECHANISM) +#define WMI_NDL_AS_DCC_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->as_dcc, acprio, SIZE_NDLTYPE_DCCMECHANISM, val) +#define WMI_NDL_AS_TX_POWER_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->as_tx_power_ac, acprio, SIZE_NDLTYPE_TXPOWER) +#define WMI_NDL_AS_TX_POWER_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->as_tx_power_ac, acprio, SIZE_NDLTYPE_TXPOWER, val) +#define WMI_NDL_AS_PACKET_INTERVAL_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->as_packet_interval_ac, acprio, SIZE_NDLTYPE_PACKETINTERVAL) +#define WMI_NDL_AS_PACKET_INTERVAL_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->as_packet_interval_ac, acprio, SIZE_NDLTYPE_PACKETINTERVAL, val) +#define WMI_NDL_AS_DATARATE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->as_datarate_ac, acprio, SIZE_NDLTYPE_DATARATE) +#define WMI_NDL_AS_DATARATE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->as_datarate_ac, acprio, SIZE_NDLTYPE_DATARATE, val) +#define WMI_NDL_AS_CARRIER_SENSE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->as_carrier_sense_ac, acprio, SIZE_NDLTYPE_RXPOWER) +#define WMI_NDL_AS_CARRIER_SENSE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->as_carrier_sense_ac, acprio, SIZE_NDLTYPE_RXPOWER, val) + +/** Data structure for EDCA/QOS parameters. */ +typedef struct +{ + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_qos_parameter */ + A_UINT32 tlv_header; + /** Arbitration Inter-Frame Spacing. Range: 2-15 */ + A_UINT32 aifsn; + /** Contention Window minimum. Range: 1 - 10 */ + A_UINT32 cwmin; + /** Contention Window maximum. Range: 1 - 10 */ + A_UINT32 cwmax; +} wmi_qos_parameter; + +/** Data structure for information specific to a channel. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_channel */ + A_UINT32 tlv_header; + A_UINT32 bandwidth; /* MHz units */ + wmi_mac_addr mac_address; +} wmi_ocb_channel; + +/** Data structure for an element of the schedule array. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_schedule_element */ + A_UINT32 tlv_header; + A_UINT32 channel_freq; /* MHz units */ + A_UINT32 total_duration; /* ms units */ + A_UINT32 guard_interval; /* ms units */ +} wmi_ocb_schedule_element; + +/** Data structure for OCB configuration. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_set_config_cmd_fixed_param */ + A_UINT32 tlv_header; + /** VDEV id(interface) that is being configured */ + A_UINT32 vdev_id; + A_UINT32 channel_count; + A_UINT32 schedule_size; + A_UINT32 flags; + + /** This is followed by a TLV array of wmi_channel. */ + /** This is followed by a TLV array of wmi_ocb_channel. */ + /** This is followed by a TLV array of wmi_qos_parameter. */ + /** This is followed by a TLV array of wmi_dcc_ndl_chan. */ + /** This is followed by a TLV array of wmi_dcc_ndl_active_state_config. */ + /** This is followed by a TLV array of wmi_ocb_schedule_element. */ +} wmi_ocb_set_config_cmd_fixed_param; + +#define EXPIRY_TIME_IN_TSF_TIMESTAMP_OFFSET 0 +#define EXPIRY_TIME_IN_TSF_TIMESTAMP_MASK 1 + +#define WMI_OCB_EXPIRY_TIME_IN_TSF(ptr) \ + (((ptr)->flags & EXPIRY_TIME_IN_TSF_TIMESTAMP_MASK) >> EXPIRY_TIME_IN_TSF_TIMESTAMP_OFFSET) + +/** Data structure for the response to the WMI_OCB_SET_CONFIG_CMDID command. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_set_config_resp_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 status; +} wmi_ocb_set_config_resp_event_fixed_param; + +/* SIZE_UTC_TIME and SIZE_UTC_TIME_ERROR cannot be modified without breaking + WMI compatibility. */ +#define SIZE_UTC_TIME (10) // The size of the utc time in bytes. +#define SIZE_UTC_TIME_ERROR (5) // The size of the utc time error in bytes. + +/** Data structure to set the UTC time. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_set_utc_time_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /** 10 bytes of the utc time. */ + A_UINT32 utc_time[WMI_PACKED_ARR_SIZE(SIZE_UTC_TIME,SIZE_BYTE)]; + /** 5 bytes of the time error. */ + A_UINT32 time_error[WMI_PACKED_ARR_SIZE(SIZE_UTC_TIME_ERROR,SIZE_BYTE)]; +} wmi_ocb_set_utc_time_cmd_fixed_param; + +#define WMI_UTC_TIME_GET(ptr,byte_index) wmi_packed_arr_get_bits((ptr)->utc_time, byte_index, SIZE_BYTE) +#define WMI_UTC_TIME_SET(ptr,byte_index,val) wmi_packed_arr_set_bits((ptr)->utc_time, byte_index, SIZE_BYTE, val) +#define WMI_TIME_ERROR_GET(ptr,byte_index) wmi_packed_arr_get_bits((ptr)->time_error, byte_index, SIZE_BYTE) +#define WMI_TIME_ERROR_SET(ptr,byte_index,val) wmi_packed_arr_set_bits((ptr)->time_error, byte_index, SIZE_BYTE, val) + +/** Data structure start the timing advertisement. The template for the + * timing advertisement frame follows this structure in the WMI command. + */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_start_timing_advert_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /** Number of times the TA is sent every 5 seconds. */ + A_UINT32 repeat_rate; + /** The frequency on which to transmit. */ + A_UINT32 channel_freq; /* MHz units */ + /** The offset into the template of the timestamp. */ + A_UINT32 timestamp_offset; + /** The offset into the template of the time value. */ + A_UINT32 time_value_offset; + /** The length of the timing advertisement template. The + * template is in the TLV data. */ + A_UINT32 timing_advert_template_length; + + /** This is followed by a binary array containing the TA template. */ +} wmi_ocb_start_timing_advert_cmd_fixed_param; + +/** Data structure to stop the timing advertisement. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_stop_timing_advert_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 channel_freq; /* MHz units */ +} wmi_ocb_stop_timing_advert_cmd_fixed_param; + +/** Data structure for the request for WMI_OCB_GET_TSF_TIMER_CMDID. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 reserved; +} wmi_ocb_get_tsf_timer_cmd_fixed_param; + +/** Data structure for the response to WMI_OCB_GET_TSF_TIMER_CMDID. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_get_tsf_timer_resp_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 tsf_timer_high; + A_UINT32 tsf_timer_low; +} wmi_ocb_get_tsf_timer_resp_event_fixed_param; + +/** Data structure for DCC stats configuration per channel. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_ndl_stats_per_channel */ + A_UINT32 tlv_header; + + /** The channel for which this applies, 16 bits. */ + /** The dcc_stats_bitmap, 8 bits. */ + A_UINT32 chan_info; + + /** Demodulation model parameters. */ + /** + * NDL_snrBackoff(MCS0), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS1), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS2), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS3), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS4), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS5), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS6), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS7), ndlType_snr, 1+7 bits. + */ + A_UINT32 snr_backoff_mcs[WMI_PACKED_ARR_SIZE(MCS_COUNT,SIZE_NDLTYPE_SNR)]; + + /** Communication ranges. */ + /** + * tx_power, ndlType_txPower, 1+7 bits. + * datarate, ndlType_datarate, 1+3 bits. + */ + A_UINT32 tx_power_datarate; + /** + * NDL_carrierSenseRange, ndlType_distance, 1+12 bits. + * NDL_estCommRange, ndlType_distance, 1+12 bits. + */ + A_UINT32 carrier_sense_est_comm_range; + + /** Channel load measures. */ + /** + * dccSensitivity, ndlType_rxPower, 1+7 bits. + * carrierSense, ndlType_rxPower, 1+7 bits. + * NDL_channelLoad, ndlType_channelLoad, 1+10 bits. + */ + A_UINT32 dcc_stats; + /** + * NDL_packetArrivalRate, ndlType_arrivalRate, 1+13 bits. + * NDL_packetAvgDuration, ndlType_packetDuration, 1+11 bits. + */ + A_UINT32 packet_stats; + /** + * NDL_channelBusyTime, ndlType_channelLoad, 1+10 bits. + */ + A_UINT32 channel_busy_time; + + /** Transmit packet statistics. */ + /** + * NDL_txPacketArrivalRate(AC_BK), ndlType_arrivalRate, 1+13 bits. + * NDL_txPacketArrivalRate(AC_BE), ndlType_arrivalRate, 1+13 bits. + * NDL_txPacketArrivalRate(AC_VI), ndlType_arrivalRate, 1+13 bits. + * NDL_txPacketArrivalRate(AC_VO), ndlType_arrivalRate, 1+13 bits. + */ + A_UINT32 tx_packet_arrival_rate_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_ARRIVALRATE)]; + /** + * NDL_txPacketAvgDuration(AC_BK), ndlType_packetDuration, 1+11 bits. + * NDL_txPacketAvgDuration(AC_BE), ndlType_packetDuration, 1+11 bits. + * NDL_txPacketAvgDuration(AC_VI), ndlType_packetDuration, 1+11 bits. + * NDL_txPacketAvgDuration(AC_VO), ndlType_packetDuration, 1+11 bits. + */ + A_UINT32 tx_packet_avg_duration_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_PACKETDURATION)]; + /** + * NDL_txChannelUse(AC_BK), ndlType_channelUse, 1+13 bits. + * NDL_txChannelUse(AC_BE), ndlType_channelUse, 1+13 bits. + * NDL_txChannelUse(AC_VI), ndlType_channelUse, 1+13 bits. + * NDL_txChannelUse(AC_VO), ndlType_channelUse, 1+13 bits. + */ + A_UINT32 tx_channel_use_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_CHANNELUSE)]; + /** + * NDL_txSignalAvgPower(AC_BK), ndlType_txPower, 1+7 bits. + * NDL_txSignalAvgPower(AC_BE), ndlType_txPower, 1+7 bits. + * NDL_txSignalAvgPower(AC_VI), ndlType_txPower, 1+7 bits. + * NDL_txSignalAvgPower(AC_VO), ndlType_txPower, 1+7 bits. + */ + A_UINT32 tx_signal_avg_power_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_TXPOWER)]; +} wmi_dcc_ndl_stats_per_channel; + +#define WMI_NDL_STATS_SNR_BACKOFF_GET(ptr,mcs) wmi_packed_arr_get_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR) +#define WMI_NDL_STATS_SNR_BACKOFF_SET(ptr,mcs,val) wmi_packed_arr_set_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR, val) + +#define WMI_NDL_STATS_CHAN_FREQ_GET(ptr) WMI_GET_BITS((ptr)->chan_info, 0, 16) +#define WMI_NDL_STATS_CHAN_FREQ_SET(ptr,val) WMI_SET_BITS((ptr)->chan_info, 0, 16, val) +#define WMI_NDL_STATS_DCC_STATS_BITMAP_GET(ptr) WMI_GET_BITS((ptr)->chan_info, 16, 8) +#define WMI_NDL_STATS_DCC_STATS_BITMAP_SET(ptr,val) WMI_SET_BITS((ptr)->chan_info, 16, 8, val) + +#define WMI_NDL_STATS_SNR_BACKOFF_GET(ptr,mcs) wmi_packed_arr_get_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR) +#define WMI_NDL_STATS_SNR_BACKOFF_SET(ptr,mcs,val) wmi_packed_arr_set_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR, val) + +#define WMI_TX_POWER_GET(ptr) WMI_GET_BITS((ptr)->tx_power_datarate, 0, 8) +#define WMI_TX_POWER_SET(ptr,val) WMI_SET_BITS((ptr)->tx_power_datarate, 0, 8, val) +#define WMI_TX_DATARATE_GET(ptr) WMI_GET_BITS((ptr)->tx_power_datarate, 0, 4) +#define WMI_TX_DATARATE_SET(ptr,val) WMI_SET_BITS((ptr)->tx_power_datarate, 0, 4, val) +#define WMI_NDL_CARRIER_SENSE_RANGE_GET(ptr) WMI_GET_BITS((ptr)->carrier_sense_est_comm_range, 0, 13) +#define WMI_NDL_CARRIER_SENSE_RANGE_SET(ptr,val) WMI_SET_BITS((ptr)->carrier_sense_est_comm_range, 0, 13, val) +#define WMI_NDL_EST_COMM_RANGE_GET(ptr) WMI_GET_BITS((ptr)->carrier_sense_est_comm_range, 13, 13) +#define WMI_NDL_EST_COMM_RANGE_SET(ptr,val) WMI_SET_BITS((ptr)->carrier_sense_est_comm_range, 13, 13, val) + +#define WMI_DCC_SENSITIVITY_GET(ptr) WMI_GET_BITS((ptr)->dcc_stats, 0, 8) +#define WMI_DCC_SENSITIVITY_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_stats, 0, 8, val) +#define WMI_CARRIER_SENSE_GET(ptr) WMI_GET_BITS((ptr)->dcc_stats, 8, 8) +#define WMI_CARRIER_SENSE_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_stats, 8, 8, val) +#define WMI_NDL_CHANNEL_LOAD_GET(ptr) WMI_GET_BITS((ptr)->dcc_stats, 16, 11) +#define WMI_NDL_CHANNEL_LOAD_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_stats, 16, 11, val) +#define WMI_NDL_PACKET_ARRIVAL_RATE_GET(ptr) WMI_GET_BITS((ptr)->packet_stats, 0, 14) +#define WMI_NDL_PACKET_ARRIVAL_RATE_SET(ptr,val) WMI_SET_BITS((ptr)->packet_stats, 0, 14, val) +#define WMI_NDL_PACKET_AVG_DURATION_GET(ptr) WMI_GET_BITS((ptr)->packet_stats, 14, 12) +#define WMI_NDL_PACKET_AVG_DURATION_SET(ptr,val) WMI_SET_BITS((ptr)->packet_stats, 14, 12, val) +#define WMI_NDL_CHANNEL_BUSY_TIME_GET(ptr) WMI_GET_BITS((ptr)->channel_busy_time, 0, 11) +#define WMI_NDL_CHANNEL_BUSY_TIME_SET(ptr,val) WMI_SET_BITS((ptr)->channel_busy_time, 0, 11, val) + +#define WMI_NDL_TX_PACKET_ARRIVAL_RATE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tx_packet_arrival_rate_ac, acprio, SIZE_NDLTYPE_ARRIVALRATE) +#define WMI_NDL_TX_PACKET_ARRIVAL_RATE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tx_packet_arrival_rate_ac, acprio, SIZE_NDLTYPE_ARRIVALRATE, val) +#define WMI_NDL_TX_PACKET_AVG_DURATION_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tx_packet_avg_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION) +#define WMI_NDL_TX_PACKET_AVG_DURATION_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tx_packet_avg_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION, val) +#define WMI_NDL_TX_CHANNEL_USE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tx_channel_use_ac, acprio, SIZE_NDLTYPE_CHANNELUSE) +#define WMI_NDL_TX_CHANNEL_USE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tx_channel_use_ac, acprio, SIZE_NDLTYPE_CHANNELUSE, val) +#define WMI_NDL_TX_SIGNAL_AVG_POWER_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tx_signal_avg_power_ac, acprio, SIZE_NDLTYPE_TXPOWER) +#define WMI_NDL_TX_SIGNAL_AVG_POWER_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tx_signal_avg_power_ac, acprio, SIZE_NDLTYPE_TXPOWER, val) + +/** Bitmap for DCC stats. */ +typedef enum { + DCC_STATS_DEMODULATION_MODEL = 1, + DCC_STATS_COMMUNICATION_RANGES = 2, + DCC_STATS_CHANNEL_LOAD_MEASURES = 4, + DCC_STATS_TRANSMIT_PACKET_STATS = 8, + DCC_STATS_TRANSMIT_MODEL_PARAMETER = 16, + DCC_STATS_ALL = 0xff, +} wmi_dcc_stats_bitmap; + +/** Data structure for getting the DCC stats. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_get_stats_cmd_fixed_param */ + A_UINT32 tlv_header; + + /* VDEV identifier */ + A_UINT32 vdev_id; + + /** The number of channels for which stats are being requested. */ + A_UINT32 num_channels; + + /** This is followed by a TLV array of wmi_dcc_channel_stats_request. */ +} wmi_dcc_get_stats_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_channel_stats_request */ + A_UINT32 tlv_header; + + /** The channel for which this applies. */ + A_UINT32 chan_freq; /* MHz units */ + + /** The DCC stats being requested. */ + A_UINT32 dcc_stats_bitmap; +} wmi_dcc_channel_stats_request; + +/** Data structure for the response with the DCC stats. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_get_stats_resp_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /** Number of channels in the response. */ + A_UINT32 num_channels; + /** This is followed by a TLV array of wmi_dcc_ndl_stats_per_channel. */ +} wmi_dcc_get_stats_resp_event_fixed_param; + +/** Data structure for clearing the DCC stats. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_clear_stats_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 dcc_stats_bitmap; +} wmi_dcc_clear_stats_cmd_fixed_param; + +/** Data structure for the pushed DCC stats */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_stats_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /** The number of channels in the response. */ + A_UINT32 num_channels; + + /** This is followed by a TLV array of wmi_dcc_ndl_stats_per_channel. */ +} wmi_dcc_stats_event_fixed_param; + +/** Data structure for updating NDL per channel. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_ndl_chan */ + A_UINT32 tlv_header; + + /** + * Channel frequency, 16 bits + * NDL_numActiveState, ndlType_numberElements, 1+6 bits + */ + A_UINT32 chan_info; + + /** + * NDL_minDccSampling, 10 bits. + * Maximum time interval between subsequent checks of the DCC rules. + */ + A_UINT32 ndl_min_dcc_sampling; + + /** + * dcc_enable, 1 bit. + * dcc_stats_enable, 1 bit. + * dcc_stats_interval, 16 bits. + */ + A_UINT32 dcc_flags; + + /** General DCC configuration. */ + /** + * NDL_timeUp, ndlType_timing, 1+12 bits. + * NDL_timeDown, ndlType_timing, 1+12 bits. + */ + A_UINT32 general_config; + + /** Transmit power thresholds. */ + /** + * NDL_minTxPower, ndlType_txPower, 1+7 bits. + * NDL_maxTxPower, ndlType_txPower, 1+7 bits. + */ + A_UINT32 min_max_tx_power; /* see "ETSI TS 102 687" table above for units */ + /** + * NDL_defTxPower(AC_BK), ndlType_txPower, 1+7 bits. + * NDL_defTxPower(AC_BE), ndlType_txPower, 1+7 bits. + * NDL_defTxPower(AC_VI), ndlType_txPower, 1+7 bits. + * NDL_defTxPower(AC_VO), ndlType_txPower, 1+7 bits. + */ + /* see "ETSI TS 102 687" table above for units */ + A_UINT32 def_tx_power_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_TXPOWER)]; + + /** Packet timing thresholds. */ + /** + * NDL_maxPacketDuration(AC_BK), ndlType_packetDuration, 1+11 bits. + * NDL_maxPacketDuration(AC_BE), ndlType_packetDuration, 1+11 bits. + * NDL_maxPacketDuration(AC_VI), ndlType_packetDuration, 1+11 bits. + * NDL_maxPacketDuration(AC_VO), ndlType_packetDuration, 1+11 bits. + */ + A_UINT32 max_packet_duration_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_PACKETDURATION)]; + /** + * NDL_minPacketInterval, ndlType_packetInterval, 1+10 bits. + * NDL_maxPacketInterval, ndlType_packetInterval, 1+10 bits. + */ + A_UINT32 min_max_packet_interval; + /** + * NDL_defPacketInterval(AC_BK), ndlType_packetInterval, 1+10 bits. + * NDL_defPacketInterval(AC_BE), ndlType_packetInterval, 1+10 bits. + * NDL_defPacketInterval(AC_VI), ndlType_packetInterval, 1+10 bits. + * NDL_defPacketInterval(AC_VO), ndlType_packetInterval, 1+10 bits. + */ + A_UINT32 def_packet_interval_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_PACKETINTERVAL)]; + + /** Packet datarate thresholds. */ + /** + * NDL_minDatarate, ndlType_datarate, 1+3 bits. + * NDL_maxDatarate, ndlType_datarate, 1+3 bits. + */ + A_UINT32 min_max_datarate; + /** + * NDL_defDatarate(AC_BK), ndlType_datarate, 1+3 bits. + * NDL_defDatarate(AC_BE), ndlType_datarate, 1+3 bits. + * NDL_defDatarate(AC_VI), ndlType_datarate, 1+3 bits. + * NDL_defDatarate(AC_VO), ndlType_datarate, 1+3 bits. + */ + A_UINT32 def_datarate_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC,SIZE_NDLTYPE_DATARATE)]; + + /** Receive signal thresholds. */ + /** + * NDL_minCarrierSense, ndlType_rxPower, 1+7 bits. + * NDL_maxCarrierSense, ndlType_rxPower, 1+7 bits. + * NDL_defCarrierSense, ndlType_rxPower, 1+7 bits. + */ + A_UINT32 min_max_def_carrier_sense; + + /** Receive model parameter. */ + /** + * NDL_defDccSensitivity, ndlType_rxPower, 1+7 bits. + * NDL_maxCsRange, ndlType_distance, 1+12 bits. + * NDL_refPathLoss, ndlType_pathloss, 1+5 bits. + */ + A_UINT32 receive_model_parameter; + + /** + * NDL_minSNR, ndlType_snr, 1+7 bits. + */ + A_UINT32 receive_model_parameter_2; + + /** Demodulation model parameters. */ + /** + * NDL_snrBackoff(MCS0), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS1), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS2), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS3), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS4), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS5), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS6), ndlType_snr, 1+7 bits. + * NDL_snrBackoff(MCS7), ndlType_snr, 1+7 bits. + */ + A_UINT32 snr_backoff_mcs[WMI_PACKED_ARR_SIZE(MCS_COUNT,SIZE_NDLTYPE_SNR)]; + + /** Transmit model parameters. */ + /** + * NDL_tmPacketArrivalRate(AC_BK), ndlType_arrivalRate, 1+13 bits. + * NDL_tmPacketArrivalRate(AC_BE), ndlType_arrivalRate, 1+13 bits. + * NDL_tmPacketArrivalRate(AC_VI), ndlType_arrivalRate, 1+13 bits. + * NDL_tmPacketArrivalRate(AC_VO), ndlType_arrivalRate, 1+13 bits. + */ + A_UINT32 tm_packet_arrival_rate_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_ARRIVALRATE)]; + /** + * NDL_tmPacketAvgDuration(AC_BK), ndlType_packetDuration, 1+11 bits. + * NDL_tmPacketAvgDuration(AC_BE), ndlType_packetDuration, 1+11 bits. + * NDL_tmPacketAvgDuration(AC_VI), ndlType_packetDuration, 1+11 bits. + * NDL_tmPacketAvgDuration(AC_VO), ndlType_packetDuration, 1+11 bits. + */ + A_UINT32 tm_packet_avg_duration_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_PACKETDURATION)]; + /** + * NDL_tmSignalAvgPower(AC_BK), ndlType_txPower, 1+7 bits. + * NDL_tmSignalAvgPower(AC_BE), ndlType_txPower, 1+7 bits. + * NDL_tmSignalAvgPower(AC_VI), ndlType_txPower, 1+7 bits. + * NDL_tmSignalAvgPower(AC_VO), ndlType_txPower, 1+7 bits. + */ + A_UINT32 tm_signal_avg_power_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_TXPOWER)]; + /** + * NDL_tmMaxChannelUse, ndlType_channelUse, 1+13 bits. + */ + A_UINT32 tm_max_channel_use; + /** + * NDL_tmChannelUse(AC_BK), ndlType_channelUse, 1+13 bits. + * NDL_tmChannelUse(AC_BE), ndlType_channelUse, 1+13 bits. + * NDL_tmChannelUse(AC_VI), ndlType_channelUse, 1+13 bits. + * NDL_tmChannelUse(AC_VO), ndlType_channelUse, 1+13 bits. + */ + A_UINT32 tm_channel_use_ac[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_CHANNELUSE)]; + + /** Channel load thresholds. */ + /** + * NDL_minChannelLoad, ndlType_channelLoad, 1+10 bits. + * NDL_maxChannelLoad, ndlType_channelLoad, 1+10 bits. + */ + A_UINT32 min_max_channel_load; + + /** Transmit queue parameters. */ + /** + * NDL_numQueue, ndlType_acPrio, 1+3 bits. + * NDL_refQueueStatus(AC_BK), ndlType_queueStatus, 1+1 bit. + * NDL_refQueueStatus(AC_BE), ndlType_queueStatus, 1+1 bit. + * NDL_refQueueStatus(AC_VI), ndlType_queueStatus, 1+1 bit. + * NDL_refQueueStatus(AC_VO), ndlType_queueStatus, 1+1 bit. + */ + A_UINT32 transmit_queue_parameters; + + /** + * NDL_refQueueLen(AC_BK), ndlType_numberElements, 1+6 bits. + * NDL_refQueueLen(AC_BE), ndlType_numberElements, 1+6 bits. + * NDL_refQueueLen(AC_VI), ndlType_numberElements, 1+6 bits. + * NDL_refQueueLen(AC_VO), ndlType_numberElements, 1+6 bits. + */ + A_UINT32 numberElements[WMI_PACKED_ARR_SIZE(WLAN_MAX_AC, SIZE_NDLTYPE_NUMBERELEMENTS)]; + +} wmi_dcc_ndl_chan; + +#define WMI_CHAN_FREQ_GET(ptr) WMI_GET_BITS((ptr)->chan_info, 0, 16) +#define WMI_CHAN_FREQ_SET(ptr,val) WMI_SET_BITS((ptr)->chan_info, 0, 16, val) +#define WMI_NDL_NUM_ACTIVE_STATE_GET(ptr) WMI_GET_BITS((ptr)->chan_info, 16, 7) +#define WMI_NDL_NUM_ACTIVE_STATE_SET(ptr,val) WMI_SET_BITS((ptr)->chan_info, 16, 7, val) + +#define WMI_NDL_MIN_DCC_SAMPLING_GET(ptr) WMI_GET_BITS((ptr)->ndl_min_dcc_sampling, 0, 10) +#define WMI_NDL_MIN_DCC_SAMPLING_SET(ptr,val) WMI_SET_BITS((ptr)->ndl_min_dcc_sampling, 0, 10, val) +#define WMI_NDL_MEASURE_INTERVAL_GET(ptr) WMI_GET_BITS((ptr)->ndl_min_dcc_sampling, 10, 16) +#define WMI_NDL_MEASURE_INTERVAL_SET(ptr,val) WMI_SET_BITS((ptr)->ndl_min_dcc_sampling, 10, 16, val) + +#define WMI_NDL_DCC_ENABLE_GET(ptr) WMI_GET_BITS((ptr)->dcc_flags, 0, 1) +#define WMI_NDL_DCC_ENABLE_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_flags, 0, 1, val) +#define WMI_NDL_DCC_STATS_ENABLE_GET(ptr) WMI_GET_BITS((ptr)->dcc_flags, 1, 1) +#define WMI_NDL_DCC_STATS_ENABLE_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_flags, 1, 1, val) +#define WMI_NDL_DCC_STATS_INTERVAL_GET(ptr) WMI_GET_BITS((ptr)->dcc_flags, 2, 16) +#define WMI_NDL_DCC_STATS_INTERVAL_SET(ptr,val) WMI_SET_BITS((ptr)->dcc_flags, 2, 16, val) + +#define WMI_NDL_TIME_UP_GET(ptr) WMI_GET_BITS((ptr)->general_config, 0, 13) +#define WMI_NDL_TIME_UP_SET(ptr,val) WMI_SET_BITS((ptr)->general_config, 0, 13, val) +#define WMI_NDL_TIME_DOWN_GET(ptr) WMI_GET_BITS((ptr)->general_config, 13, 13) +#define WMI_NDL_TIME_DOWN_SET(ptr,val) WMI_SET_BITS((ptr)->general_config, 13, 13, val) + +#define WMI_NDL_MIN_TX_POWER_GET(ptr) WMI_GET_BITS((ptr)->min_max_tx_power, 0, 8) +#define WMI_NDL_MIN_TX_POWER_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_tx_power, 0, 8, val) +#define WMI_NDL_MAX_TX_POWER_GET(ptr) WMI_GET_BITS((ptr)->min_max_tx_power, 8, 8) +#define WMI_NDL_MAX_TX_POWER_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_tx_power, 8, 8, val) + +#define WMI_NDL_DEF_TX_POWER_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->def_tx_power_ac, acprio, SIZE_NDLTYPE_TXPOWER) +#define WMI_NDL_DEF_TX_POWER_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->def_tx_power_ac, acprio, SIZE_NDLTYPE_TXPOWER, val) + +#define WMI_NDL_MAX_PACKET_DURATION_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->max_packet_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION) +#define WMI_NDL_MAX_PACKET_DURATION_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->max_packet_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION, val) +#define WMI_NDL_MIN_PACKET_INTERVAL_GET(ptr) WMI_GET_BITS((ptr)->min_max_packet_interval, 0, 11) +#define WMI_NDL_MIN_PACKET_INTERVAL_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_packet_interval, 0, 11, val) +#define WMI_NDL_MAX_PACKET_INTERVAL_GET(ptr) WMI_GET_BITS((ptr)->min_max_packet_interval, 11, 11) +#define WMI_NDL_MAX_PACKET_INTERVAL_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_packet_interval, 11, 11, val) +#define WMI_NDL_DEF_PACKET_INTERVAL_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->def_packet_interval_ac, acprio, SIZE_NDLTYPE_PACKETINTERVAL) +#define WMI_NDL_DEF_PACKET_INTERVAL_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->def_packet_interval_ac, acprio, SIZE_NDLTYPE_PACKETINTERVAL, val) + +#define WMI_NDL_MIN_DATARATE_GET(ptr) WMI_GET_BITS((ptr)->min_max_datarate, 0, 4) +#define WMI_NDL_MIN_DATARATE_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_datarate, 0, 4, val) +#define WMI_NDL_MAX_DATARATE_GET(ptr) WMI_GET_BITS((ptr)->min_max_datarate, 4, 4) +#define WMI_NDL_MAX_DATARATE_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_datarate, 4, 4, val) +#define WMI_NDL_DEF_DATARATE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->def_datarate_ac, acprio, SIZE_NDLTYPE_DATARATE) +#define WMI_NDL_DEF_DATARATE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->def_datarate_ac, acprio, SIZE_NDLTYPE_DATARATE, val) + +#define WMI_NDL_MIN_CARRIER_SENSE_GET(ptr) WMI_GET_BITS((ptr)->min_max_def_carrier_sense, 0, 8) +#define WMI_NDL_MIN_CARRIER_SENSE_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_def_carrier_sense, 0, 8, val) +#define WMI_NDL_MAX_CARRIER_SENSE_GET(ptr) WMI_GET_BITS((ptr)->min_max_def_carrier_sense, 8, 8) +#define WMI_NDL_MAX_CARRIER_SENSE_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_def_carrier_sense, 8, 8, val) +#define WMI_NDL_DEF_CARRIER_SENSE_GET(ptr) WMI_GET_BITS((ptr)->min_max_def_carrier_sense, 16, 8) +#define WMI_NDL_DEF_CARRIER_SENSE_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_def_carrier_sense, 16, 8, val) + +#define WMI_NDL_DEF_DCC_SENSITIVITY_GET(ptr) WMI_GET_BITS((ptr)->receive_model_parameter, 0, 8) +#define WMI_NDL_DEF_DCC_SENSITIVITY_SET(ptr,val) WMI_SET_BITS((ptr)->receive_model_parameter, 0, 8, val) +#define WMI_NDL_MAX_CS_RANGE_GET(ptr) WMI_GET_BITS((ptr)->receive_model_parameter, 8, 13) +#define WMI_NDL_MAX_CS_RANGE_SET(ptr,val) WMI_SET_BITS((ptr)->receive_model_parameter, 8, 13, val) +#define WMI_NDL_REF_PATH_LOSS_GET(ptr) WMI_GET_BITS((ptr)->receive_model_parameter, 21, 6) +#define WMI_NDL_REF_PATH_LOSS_SET(ptr,val) WMI_SET_BITS((ptr)->receive_model_parameter, 21, 6, val) + +#define WMI_NDL_MIN_SNR_GET(ptr) WMI_GET_BITS((ptr)->receive_model_parameter_2, 0, 8) +#define WMI_NDL_MIN_SNR_SET(ptr,val) WMI_SET_BITS((ptr)->receive_model_parameter_2, 0, 8, val) + +#define WMI_NDL_SNR_BACKOFF_GET(ptr,mcs) wmi_packed_arr_get_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR) +#define WMI_NDL_SNR_BACKOFF_SET(ptr,mcs,val) wmi_packed_arr_set_bits((ptr)->snr_backoff_mcs, mcs, SIZE_NDLTYPE_SNR, val) + +#define WMI_NDL_TM_PACKET_ARRIVAL_RATE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tm_packet_arrival_rate_ac, acprio, SIZE_NDLTYPE_ARRIVALRATE) +#define WMI_NDL_TM_PACKET_ARRIVAL_RATE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tm_packet_arrival_rate_ac, acprio, SIZE_NDLTYPE_ARRIVALRATE, val) +#define WMI_NDL_TM_PACKET_AVG_DURATION_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tm_packet_avg_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION) +#define WMI_NDL_TM_PACKET_AVG_DURATION_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tm_packet_avg_duration_ac, acprio, SIZE_NDLTYPE_PACKETDURATION, val) +#define WMI_NDL_TM_SIGNAL_AVG_POWER_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tm_signal_avg_power_ac, acprio, SIZE_NDLTYPE_TXPOWER) +#define WMI_NDL_TM_SIGNAL_AVG_POWER_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tm_signal_avg_power_ac, acprio, SIZE_NDLTYPE_TXPOWER, val) +#define WMI_NDL_TM_MAX_CHANNEL_USE_GET(ptr) WMI_GET_BITS((ptr)->tm_max_channel_use, 0, 14) +#define WMI_NDL_TM_MAX_CHANNEL_USE_SET(ptr,val) WMI_SET_BITS((ptr)->tm_max_channel_use, 0, 14, val) +#define WMI_NDL_TM_CHANNEL_USE_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->tm_channel_use_ac, acprio, SIZE_NDLTYPE_CHANNELUSE) +#define WMI_NDL_TM_CHANNEL_USE_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->tm_channel_use_ac, acprio, SIZE_NDLTYPE_CHANNELUSE, val) + +#define WMI_NDL_MIN_CHANNEL_LOAD_GET(ptr) WMI_GET_BITS((ptr)->min_max_channel_load, 0, 11) +#define WMI_NDL_MIN_CHANNEL_LOAD_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_channel_load, 0, 11, val) +#define WMI_NDL_MAX_CHANNEL_LOAD_GET(ptr) WMI_GET_BITS((ptr)->min_max_channel_load, 11, 11) +#define WMI_NDL_MAX_CHANNEL_LOAD_SET(ptr,val) WMI_SET_BITS((ptr)->min_max_channel_load, 11, 11, val) + +#define WMI_NDL_NUM_QUEUE_GET(ptr) WMI_GET_BITS((ptr)->transmit_queue_parameters, 0, 4) +#define WMI_NDL_NUM_QUEUE_SET(ptr,val) WMI_SET_BITS((ptr)->transmit_queue_parameters, 0, 4, val) +#define WMI_NDL_REF_QUEUE_STATUS_GET(ptr,acprio) WMI_GET_BITS((ptr)->transmit_queue_parameters, (4 + (acprio * 2)), 2) +#define WMI_NDL_REF_QUEUE_STATUS_SET(ptr,acprio,val) WMI_SET_BITS((ptr)->transmit_queue_parameters, (4 + (acprio * 2)), 2, val) +#define WMI_NDL_REF_QUEUE_LEN_GET(ptr,acprio) wmi_packed_arr_get_bits((ptr)->numberElements, acprio, SIZE_NDLTYPE_NUMBERELEMENTS) +#define WMI_NDL_REF_QUEUE_LEN_SET(ptr,acprio,val) wmi_packed_arr_set_bits((ptr)->numberElements, acprio, SIZE_NDLTYPE_NUMBERELEMENTS, val) + +/** Data structure for updating the NDL. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_update_ndl_cmd_fixed_param */ + A_UINT32 tlv_header; + + /* VDEV identifier */ + A_UINT32 vdev_id; + + /** The number of channels in the request. */ + A_UINT32 num_channel; + + /** This is followed by a TLV array of wmi_dcc_ndl_chan. */ + /** This is followed by a TLV array of wmi_dcc_ndl_active_state_config. */ +} wmi_dcc_update_ndl_cmd_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_dcc_update_ndl_resp_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + A_UINT32 status; +} wmi_dcc_update_ndl_resp_event_fixed_param; + +/* Actions for TSF timestamp */ +typedef enum { + TSF_TSTAMP_CAPTURE_REQ = 1, + TSF_TSTAMP_CAPTURE_RESET = 2, + TSF_TSTAMP_READ_VALUE = 3, +} wmi_tsf_tstamp_action; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /* action type, refer to wmi_tsf_tstamp_action */ + A_UINT32 tsf_action; +} wmi_vdev_tsf_tstamp_action_cmd_fixed_param; + +typedef struct { + /* TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_vdev_tsf_report_event_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /* low 32bit of tsf */ + A_UINT32 tsf_low; + /* high 32 bit of tsf */ + A_UINT32 tsf_high; +} wmi_vdev_tsf_report_event_fixed_param; + +typedef struct { + /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param */ + A_UINT32 tlv_header; + /** unique id identifying the VDEV, generated by the caller */ + A_UINT32 vdev_id; + /** unique id to identify the ie_data as defined by ieee 802.11 spec */ + A_UINT32 ie_id; /** ie_len corresponds to num of bytes in ie_data[] */ + A_UINT32 ie_len; + /** + * Following this structure is the TLV byte stream of ie data of length ie_buf_len: + * A_UINT8 ie_data[]; */ +} wmi_vdev_set_ie_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_soc_set_pcl_cmd_fixed_param */ + /** Set Preferred Channel List **/ + + /** # of channels to scan */ + A_UINT32 num_chan; +/** + * TLV (tag length value ) parameters follow the wmi_soc_set_pcl_cmd + * structure. The TLV's are: + * A_UINT32 channel_list[]; + **/ +} wmi_soc_set_pcl_cmd_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_cmd_fixed_param */ + /** Set Hardware Mode **/ + + /* Hardware Mode Index */ + A_UINT32 hw_mode_index; +} wmi_soc_set_hw_mode_cmd_fixed_param; + +/** Data structure for information specific to a VDEV to MAC mapping. */ +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_response_vdev_mac_entry */ + A_UINT32 tlv_header; + A_UINT32 vdev_id; /* VDEV ID */ + A_UINT32 mac_id; /* MAC ID */ +} wmi_soc_set_hw_mode_response_vdev_mac_entry; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_response_event_fixed_param */ + /** Set Hardware Mode Response Event **/ + + /* Status of set_hw_mode command */ + /* + * Values for Status: + * 0 - OK; command successful + * 1 - EINVAL; Requested invalid hw_mode + * 2 - ECANCELED; HW mode change canceled + * 3 - ENOTSUP; HW mode not supported + * 4 - EHARDWARE; HW mode change prevented by hardware + * 5 - EPENDING; HW mode change is pending + * 6 - ECOEX; HW mode change conflict with Coex + */ + A_UINT32 status; + /* Configured Hardware Mode */ + A_UINT32 cfgd_hw_mode_index; + /* Number of Vdev to Mac entries */ + A_UINT32 num_vdev_mac_entries; + +/** + * TLV (tag length value ) parameters follow the soc_set_hw_mode_response_event + * structure. The TLV's are: + * A_UINT32 wmi_soc_set_hw_mode_response_vdev_mac_entry[]; + */ +} wmi_soc_set_hw_mode_response_event_fixed_param; + +typedef struct { + A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_soc_hw_mode_transition_event_fixed_param */ + /** Hardware Mode Transition Event **/ + + /* Original or old Hardware mode */ + A_UINT32 old_hw_mode_index; + /* New Hardware Mode */ + A_UINT32 new_hw_mode_index; + /* Number of Vdev to Mac entries */ + A_UINT32 num_vdev_mac_entries; + +/** + * TLV (tag length value ) parameters follow the soc_set_hw_mode_response_event + * structure. The TLV's are: + * A_UINT32 wmi_soc_set_hw_mode_response_vdev_mac_entry[]; + */ +} wmi_soc_hw_mode_transition_event_fixed_param; + + +/* ADD NEW DEFS HERE */ + +/***************************************************************************** + * The following structures are deprecated. DO NOT USE THEM! + */ + +/** Max number of channels in the schedule. */ +#define OCB_CHANNEL_MAX (5) + +/* NOTE: Make sure these data structures are identical to those 9235 +* defined in sirApi.h */ + +typedef struct +{ + /** Arbitration Inter-Frame Spacing. Range: 2-15 */ + A_UINT32 aifsn; + /** Contention Window minimum. Range: 1 - 10 */ + A_UINT32 cwmin; + /** Contention Window maximum. Range: 1 - 10 */ + A_UINT32 cwmax; +} wmi_qos_params_t; + +typedef struct +{ + /** Channel frequency in MHz */ + A_UINT32 chan_freq; + /** Channel duration in ms */ + A_UINT32 duration; + /** Start guard interval in ms */ + A_UINT32 start_guard_interval; + /** End guard interval in ms */ + A_UINT32 end_guard_interval; + /** Transmit power in dBm, range 0 - 23 */ + A_UINT32 tx_power; + /** Transmit datarate in Mbps */ + A_UINT32 tx_rate; + /** QoS parameters for each AC */ + wmi_qos_params_t qos_params[WLAN_MAX_AC]; + /** 1 to enable RX stats for this channel, 0 otherwise */ + A_UINT32 rx_stats; +} wmi_ocb_channel_t; + +typedef struct { + /** TLV tag and len; tag equals + * WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param */ + A_UINT32 tlv_header; + /* VDEV identifier */ + A_UINT32 vdev_id; + /** Number of valid channels in the channels array */ + A_UINT32 num_channels; + /** The array of channels */ + wmi_ocb_channel_t channels[OCB_CHANNEL_MAX]; + /** 1 to allow off-channel tx, 0 otherwise */ + A_UINT32 off_channel_tx; // Not supported +} wmi_ocb_set_sched_cmd_fixed_param; + +typedef struct { + /** Return status. 0 for success, non-zero otherwise */ + A_UINT32 status; +} wmi_ocb_set_sched_event_fixed_param; + +/***************************************************************************** + * END DEPRECATED + */ + +/* ADD NEW DEFS ABOVE THIS DEPRECATED SECTION */ + +#ifdef __cplusplus +} +#endif + +#endif /*_WMI_UNIFIED_H_*/ + +/**@}*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h new file mode 100644 index 0000000000000..62797d90a575e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +/* + * This file contains the API definitions for the Unified Wireless Module Interface (WMI). + */ + +#ifndef _WMI_UNIFIED_API_H_ +#define _WMI_UNIFIED_API_H_ + +#include +#include "a_types.h" +#include "ol_defines.h" +#include "wmi.h" +#include "htc_api.h" + +typedef adf_nbuf_t wmi_buf_t; +#define wmi_buf_free(_buf) adf_nbuf_free(_buf) +#define wmi_buf_data(_buf) adf_nbuf_data(_buf) + +/** + * attach for unified WMI + * + * @param scn_handle : handle to SCN. + * @return opaque handle. + */ +void * +wmi_unified_attach(void *scn_handle, void (*func) (void*)); +/** + * detach for unified WMI + * + * @param wmi_handle : handle to WMI. + * @return void. + */ +void +wmi_unified_detach(struct wmi_unified* wmi_handle); + +/** + * generic function to allocate WMI buffer + * + * @param wmi_handle : handle to WMI. + * @param len : length of the buffer + * @return wmi_buf_t. + */ +wmi_buf_t +wmi_buf_alloc(wmi_unified_t wmi_handle, u_int16_t len); + + +/** + * generic function to send unified WMI command + * + * @param wmi_handle : handle to WMI. + * @param buf : wmi command buffer + * @param buflen : wmi command buffer length + * @return 0 on success and -ve on failure. + */ +int +wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int buflen, WMI_CMD_ID cmd_id); + +/** + * WMI event handler register function + * + * @param wmi_handle : handle to WMI. + * @param event_id : WMI event ID + * @param handler_func : Event handler call back function + * @return 0 on success and -ve on failure. + */ +int +wmi_unified_register_event_handler(wmi_unified_t wmi_handle, WMI_EVT_ID event_id, + wmi_unified_event_handler handler_func); + +/** + * WMI event handler unregister function + * + * @param wmi_handle : handle to WMI. + * @param event_id : WMI event ID + * @return 0 on success and -ve on failure. + */ +int +wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle, WMI_EVT_ID event_id); + + +/** + * request wmi to connet its htc service. + * @param wmi_handle : handle to WMI. + * @return void + */ +int +wmi_unified_connect_htc_service(struct wmi_unified * wmi_handle, void *htc_handle); + +/* + * WMI API to verify the host has enough credits to suspend +*/ + +int +wmi_is_suspend_ready(wmi_unified_t wmi_handle); + +/** + WMI API to get updated host_credits +*/ + +int +wmi_get_host_credits(wmi_unified_t wmi_handle); + +/** + WMI API to get WMI Pending Commands in the HTC queue +*/ + +int +wmi_get_pending_cmds(wmi_unified_t wmi_handle); + +/** + WMI API to set target suspend state +*/ + +void +wmi_set_target_suspend(wmi_unified_t wmi_handle, A_BOOL val); + +/** + WMI API to set D0WOW flag +*/ +#ifdef FEATURE_WLAN_D0WOW +void +wmi_set_d0wow_flag(wmi_unified_t wmi_handle, A_BOOL flag); +#endif +/** + WMA Callback to get the Tx complete for WOW_ENABLE +*/ +typedef void (*wma_wow_tx_complete_cbk)(void *scn_handle); +#endif /* _WMI_UNIFIED_API_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version.h new file mode 100644 index 0000000000000..c1ab37ffb72a1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * IMPORTANT NOTE: For all change to WMI Interface, the ABI version number _must_ be updated. + */ +/** Major version number is incremented when there are significant changes to WMI Interface that break compatibility. */ +#define __WMI_VER_MAJOR_ 1 +/** Minor version number is incremented when there are changes + * (however minor) to WMI Interface that break + * compatibility. */ +#define __WMI_VER_MINOR_ 0 +/** WMI revision number has to be incremented when there is a + * change that may or may not break compatibility. */ +#define __WMI_REVISION_ 127 + +/** The Version Namespace should not be normally changed. Only + * host and firmware of the same WMI namespace will work + * together. + * For example, "QCA_ML" converts to 0x4C, 0x4D5F414351. + * where 'Q'=0x51, 'C'=0x43, 'A'=0x41, '_'=0x5F. 'M'=4D, 'L'=4C + */ +#define __NAMESPACE_0_ 0x5F414351 +#define __NAMESPACE_1_ 0x00004C4D +#define __NAMESPACE_2_ 0x00000000 +#define __NAMESPACE_3_ 0x00000000 + +/* Format of the version number. */ +#define WMI_VER_MAJOR_BIT_OFFSET 24 +#define WMI_VER_MINOR_BIT_OFFSET 0 + +#define WMI_VER_MAJOR_BIT_MASK 0xFF000000 +#define WMI_VER_MINOR_BIT_MASK 0x00FFFFFF + +/* Macros to extract the sw_version components. + */ +#define WMI_VER_GET_MAJOR(x) (((x) & WMI_VER_MAJOR_BIT_MASK)>>WMI_VER_MAJOR_BIT_OFFSET) +#define WMI_VER_GET_MINOR(x) (((x) & WMI_VER_MINOR_BIT_MASK)>>WMI_VER_MINOR_BIT_OFFSET) + +#define WMI_VER_GET_VERSION_0(major, minor) ( (( major << WMI_VER_MAJOR_BIT_OFFSET ) & WMI_VER_MAJOR_BIT_MASK) + (( minor << WMI_VER_MINOR_BIT_OFFSET ) & WMI_VER_MINOR_BIT_MASK) ) +/* + * The version has the following format: + * Bits 24-31: Major version + * Bits 0-23: Minor version + * Bits 0-31: Build number + * E.g. Build 1.1.7 would be represented as 0x01000001 for Major/Minor & 0x00000007 for buildnum. + * + * DO NOT split the following macro into multiple lines as this may confuse the build scripts. + */ +/* ABI Version. Reflects the version of binary interface exposed by Target firmware. */ +#define WMI_ABI_VERSION_0 WMI_VER_GET_VERSION_0(__WMI_VER_MAJOR_, __WMI_VER_MINOR_) +#define WMI_ABI_VERSION_1 __WMI_REVISION_ +#define WMI_ABI_VERSION_NS_0 __NAMESPACE_0_ +#define WMI_ABI_VERSION_NS_1 __NAMESPACE_1_ +#define WMI_ABI_VERSION_NS_2 __NAMESPACE_2_ +#define WMI_ABI_VERSION_NS_3 __NAMESPACE_3_ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version_whitelist.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version_whitelist.c new file mode 100644 index 0000000000000..266b7620445f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_version_whitelist.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * Every Product Line or chipset or team can have its own Whitelist table. + * The following is a list of versions that the present software can support + * even though its versions are incompatible. Any entry here means that the + * indicated version does not break WMI compatibility even though it has + * a minor version change. + */ +wmi_whitelist_version_info version_whitelist[] = +{ + {0, 0, 0x5F414351, 0x00004C4D, 0, 0}, //Placeholder: Major=0, Minor=0, Namespace="QCA_ML" (Dummy entry) +}; diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmix.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmix.h new file mode 100644 index 0000000000000..9a64f53b98fee --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmix.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. +// $ATH_LICENSE_HOSTSDK0_C$ +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +/* + * This file contains extensions of the WMI protocol specified in the + * Wireless Module Interface (WMI). It includes definitions of all + * extended commands and events. Extensions include useful commands + * that are not directly related to wireless activities. They may + * be hardware-specific, and they might not be supported on all + * implementations. + * + * Extended WMIX commands are encapsulated in a WMI message with + * cmd=WMI_EXTENSION_CMD. + */ + +#ifndef _WMIX_H_ +#define _WMIX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Extended WMI commands are those that are needed during wireless + * operation, but which are not really wireless commands. This allows, + * for instance, platform-specific commands. Extended WMI commands are + * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID. + * Extended WMI events are similarly embedded in a WMI event message with + * WMI_EVENT_ID=WMI_EXTENSION_EVENTID. + */ +typedef struct { + A_UINT32 commandId; +} POSTPACK WMIX_CMD_HDR; + +typedef enum { + WMIX_DSETOPEN_REPLY_CMDID = 0x2001, + WMIX_DSETDATA_REPLY_CMDID, + WMIX_HB_CHALLENGE_RESP_CMDID, + WMIX_DBGLOG_CFG_MODULE_CMDID, + WMIX_PROF_CFG_CMDID, /* 0x200a */ + WMIX_PROF_ADDR_SET_CMDID, + WMIX_PROF_START_CMDID, + WMIX_PROF_STOP_CMDID, + WMIX_PROF_COUNT_GET_CMDID, +} WMIX_COMMAND_ID; + +typedef enum { + WMIX_DSETOPENREQ_EVENTID = 0x3001, + WMIX_DSETCLOSE_EVENTID, + WMIX_DSETDATAREQ_EVENTID, + WMIX_HB_CHALLENGE_RESP_EVENTID, + WMIX_DBGLOG_EVENTID, + WMIX_PROF_COUNT_EVENTID, + WMIX_PKTLOG_EVENTID, +} WMIX_EVENT_ID; + +/* + * =============DataSet support================= + */ + +/* + * WMIX_DSETOPENREQ_EVENTID + * DataSet Open Request Event + */ +typedef struct { + A_UINT32 dset_id; + A_UINT32 targ_dset_handle; /* echo'ed, not used by Host, */ + A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ + A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ +} POSTPACK WMIX_DSETOPENREQ_EVENT; + +/* + * WMIX_DSETCLOSE_EVENTID + * DataSet Close Event + */ +typedef struct { + A_UINT32 access_cookie; +} POSTPACK WMIX_DSETCLOSE_EVENT; + +/* + * WMIX_DSETDATAREQ_EVENTID + * DataSet Data Request Event + */ +typedef struct { + A_UINT32 access_cookie; + A_UINT32 offset; + A_UINT32 length; + A_UINT32 targ_buf; /* echo'ed, not used by Host, */ + A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ + A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ +} WMIX_DSETDATAREQ_EVENT; + +typedef struct { + A_UINT32 status; + A_UINT32 targ_dset_handle; + A_UINT32 targ_reply_fn; + A_UINT32 targ_reply_arg; + A_UINT32 access_cookie; + A_UINT32 size; + A_UINT32 version; +} WMIX_DSETOPEN_REPLY_CMD; + +typedef struct { + A_UINT32 status; + A_UINT32 targ_buf; + A_UINT32 targ_reply_fn; + A_UINT32 targ_reply_arg; + A_UINT32 length; + A_UINT8 buf[1]; +} WMIX_DSETDATA_REPLY_CMD; + +/* + * =============Error Detection support================= + */ + +/* + * WMIX_HB_CHALLENGE_RESP_CMDID + * Heartbeat Challenge Response command + */ +typedef struct { + A_UINT32 cookie; + A_UINT32 source; +} WMIX_HB_CHALLENGE_RESP_CMD; + +/* + * WMIX_HB_CHALLENGE_RESP_EVENTID + * Heartbeat Challenge Response Event + */ +#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD + +/* + * =============Target Profiling support================= + */ + +typedef struct { + A_UINT32 period; /* Time (in 30.5us ticks) between samples */ + A_UINT32 nbins; +} WMIX_PROF_CFG_CMD; + +typedef struct { + A_UINT32 addr; +} WMIX_PROF_ADDR_SET_CMD; + +/* + * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request + * using a WMIX_PROF_COUNT_EVENT with + * addr set to the next address + * count set to the corresponding count + */ +typedef struct { + A_UINT32 addr; + A_UINT32 count; +} WMIX_PROF_COUNT_EVENT; + + +#ifdef __cplusplus +} +#endif + +#endif /* _WMIX_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/ath_dfs_structs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/ath_dfs_structs.h new file mode 100644 index 0000000000000..425d0d5f53ecc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/ath_dfs_structs.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + ath_dfs_structs.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + + +#ifndef _DFS__STRUCTS_H_ +#define _DFS__STRUCTS_H_ +#include + +#ifdef ANDROID +#include +#endif + +/* + * For the dfs_nol_clist_update() method - this is the + * update command. + */ +enum { + DFS_NOL_CLIST_CMD_NONE = 0x0, + DFS_NOL_CLIST_CMD_UPDATE = 0x1, +}; + +struct ath_dfs_caps { + u_int32_t + ath_dfs_ext_chan_ok:1, /* Can radar be detected on the extension chan? */ + ath_dfs_combined_rssi_ok:1, /* Can use combined radar RSSI? */ + /* the following flag is used to indicate if radar detection scheme */ + /* should use enhanced chirping detection algorithm. This flag also */ + /* determines if certain radar data should be discarded to minimize */ + /* false detection of radar. */ + ath_dfs_use_enhancement:1, + ath_strong_signal_diversiry:1, + ath_chip_is_bb_tlv:1; + + /* + * goes with ath_strong_signal_diversiry: + * If we have fast diversity capability, read off + * Strong Signal fast diversity count set in the ini + * file, and store so we can restore the value when + * radar is disabled + */ + u_int32_t ath_fastdiv_val; +}; + +/* + * These are defined in the HAL for now, and must be migrated outside + * of there in order to be used by the new partial offload data path. + */ + +struct dfs_pulse { + u_int32_t rp_numpulses; /* Num of pulses in radar burst */ + u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */ + u_int32_t rp_pulsefreq; /* Frequency of pulses in burst */ + u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */ + u_int32_t rp_patterntype; /* fixed or variable pattern type*/ + u_int32_t rp_pulsevar; /* Time variation of pulse duration for + matched filter (single-sided) in usecs */ + u_int32_t rp_threshold; /* Threshold for MF output to indicateC + radar match */ + u_int32_t rp_mindur; /* Min pulse duration to be considered for + this pulse type */ + u_int32_t rp_maxdur; /* Max pusle duration to be considered for + this pulse type */ + u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */ + u_int32_t rp_meanoffset; /* Offset for timing adjustment */ + int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */ + /* lower than in non TURBO mode. This will be used to offset that diff.*/ + u_int32_t rp_ignore_pri_window; + u_int32_t rp_pulseid; /* Unique ID for identifying filter */ +}; + +struct dfs_staggered_pulse { + u_int32_t rp_numpulses; /* Num of pulses in radar burst */ + u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */ + u_int32_t rp_min_pulsefreq; /* Frequency of pulses in burst */ + u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */ + u_int32_t rp_patterntype; /* fixed or variable pattern type*/ + u_int32_t rp_pulsevar; /* Time variation of pulse duration for + matched filter (single-sided) in usecs */ + u_int32_t rp_threshold; /* Thershold for MF output to indicateC + radar match */ + u_int32_t rp_mindur; /* Min pulse duration to be considered for + this pulse type */ + u_int32_t rp_maxdur; /* Max pusle duration to be considered for + this pulse type */ + u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */ + u_int32_t rp_meanoffset; /* Offset for timing adjustment */ + int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */ + /* lower than in non TURBO mode. This will be used to offset that diff.*/ + u_int32_t rp_pulseid; /* Unique ID for identifying filter */ +}; + +struct dfs_bin5pulse { + u_int32_t b5_threshold; /* Number of bin5 pulses to indicate detection */ + u_int32_t b5_mindur; /* Min duration for a bin5 pulse */ + u_int32_t b5_maxdur; /* Max duration for a bin5 pulse */ + u_int32_t b5_timewindow; /* Window over which to count bin5 pulses */ + u_int32_t b5_rssithresh; /* Min rssi to be considered a pulse */ + u_int32_t b5_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dB */ +}; + +/* + * DFS NOL representation. + * + * This is used to represent the DFS NOL information between the + * NOL code in lmac/dfs/dfs_nol.c and any driver layer wishing + * to use it. + */ +struct dfs_nol_chan_entry { + u_int32_t nol_chfreq; /* Centre frequency, MHz */ + u_int32_t nol_chwidth; /* Width, MHz */ + unsigned long nol_start_ticks; /* start ticks, OS specific */ + u_int32_t nol_timeout_ms; /* timeout, mS */ +}; + +//HAL_PHYERR_PARAM; + +/* + * This represents the general case of the radar PHY configuration, + * across all chips. + * + * It's then up to each chip layer to translate to/from this + * (eg to HAL_PHYERR_PARAM for the HAL case.) + */ + +#define ATH_DFS_PHYERR_PARAM_NOVAL 0xFFFF +#define ATH_DFS_PHYERR_PARAM_ENABLE 0x8000 + +struct ath_dfs_phyerr_param { + int32_t pe_firpwr; /* FIR pwr out threshold */ + int32_t pe_rrssi; /* Radar rssi thresh */ + int32_t pe_height; /* Pulse height thresh */ + int32_t pe_prssi; /* Pulse rssi thresh */ + int32_t pe_inband; /* Inband thresh */ + + /* The following params are only for AR5413 and later */ + /* + * Relative power threshold in 0.5dB steps + */ + u_int32_t pe_relpwr; + + /* + * Pulse Relative step threshold in 0.5dB steps + */ + u_int32_t pe_relstep; + + /* + * Max length of radar sign in 0.8us units + */ + u_int32_t pe_maxlen; + + /* + * Use the average in-band power measured over 128 cycles + */ + bool pe_usefir128; + + /* + * Enable to block radar check if pkt detect is done via OFDM + * weak signal detect or pkt is detected immediately after tx + * to rx transition + */ + bool pe_blockradar; + + /* + * Enable to use the max rssi instead of the last rssi during + * fine gain changes for radar detection + */ + bool pe_enmaxrssi; +}; + +static inline void ath_dfs_phyerr_param_copy(struct ath_dfs_phyerr_param *dst, + struct ath_dfs_phyerr_param *src) +{ + adf_os_mem_copy(dst, src, sizeof(*dst)); +} + +static inline void ath_dfs_phyerr_init_noval(struct ath_dfs_phyerr_param *pe) +{ + pe->pe_firpwr = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_rrssi = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_height = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_prssi = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_inband = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_relpwr = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_relstep = ATH_DFS_PHYERR_PARAM_NOVAL; + pe->pe_maxlen = ATH_DFS_PHYERR_PARAM_NOVAL; + + /* XXX what about usefir128, blockradar, enmaxrssi? */ +} + +struct ath_dfs_radar_tab_info { + u_int32_t dfsdomain; + int numradars; + struct dfs_pulse *dfs_radars; + int numb5radars; + struct dfs_bin5pulse *b5pulses; + struct ath_dfs_phyerr_param dfs_defaultparams; + int dfs_pri_multiplier; +}; +#endif /* _DFS__STRUCTS_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs.h new file mode 100644 index 0000000000000..6907add11ee95 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs.h @@ -0,0 +1,792 @@ +/* + * Copyright (c) 2005-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#ifndef _DFS_H_ +#define _DFS_H_ + +/* +*TO DO DFS- Need to include this file later on +*#include "ath_internal.h" +*/ +/*DFS New Include Start*/ + +#include /* ADF_NBUF_EXEMPT_NO_EXEMPTION, etc. */ +#include /* adf_nbuf_t, etc. */ +#include /* adf_os_assert */ +#include /* adf_os_spinlock */ +#include /* TAILQ */ +#include +#include +#include +#include +/*DFS Utility Include END*/ + +/* From wlan_modules/include/ */ +#include "ath_dfs_structs.h" +/*DFS - Newly added File to interface cld UMAC and dfs data structures*/ +#include +/* +*TO DO DFS- Need to include this file later on +#include "ah.h" +*/ +//#include "ah_desc.h" +#include "dfs_ioctl.h" +#include "dfs_ioctl_private.h" +#include "dfs_interface.h" +#include "_ieee80211_common.h" +#include "vos_api.h" + +#define ATH_SUPPORT_DFS 1 +#define CHANNEL_TURBO 0x00010 +#define DFS_PRINTK(_fmt, ...) printk((_fmt), __VA_ARGS__) +#define DFS_DPRINTK(dfs, _m, _fmt, ...) do { \ + if (((dfs) == NULL) || \ + ((dfs) != NULL && \ + ((_m) & (dfs)->dfs_debug_mask))) { \ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, _fmt, __VA_ARGS__);\ + } \ +} while (0) + +#define DFS_MIN(a,b) ((a)<(b)?(a):(b)) +#define DFS_MAX(a,b) ((a)>(b)?(a):(b)) +#define DFS_DIFF(a,b) (DFS_MAX(a,b) - DFS_MIN(a,b)) +/* + * Maximum number of radar events to be processed in a single iteration. + * Allows soft watchdog to run. + */ +#define MAX_EVENTS 100 + +#define DFS_STATUS_SUCCESS 0 +#define DFS_STATUS_FAIL 1 + +/* + * Constants to use for chirping detection. + * + * All are unconverted as HW reports them. + * + * XXX Are these constants with or without fast clock 5GHz operation? + * XXX Peregrine reports pulses in microseconds, not hardware clocks! + */ +#define MIN_BIN5_DUR 63 /* 50 * 1.25*/ +#define MIN_BIN5_DUR_MICROSEC 50 +#define MAYBE_BIN5_DUR 35 /* 28 * 1.25*/ +#define MAYBE_BIN5_DUR_MICROSEC 28 +//#define MAX_BIN5_DUR 131 /* 105 * 1.25*/ +#define MAX_BIN5_DUR 145 /* use 145 for osprey */ //conversion is already done using dfs->dur_multiplier// +#define MAX_BIN5_DUR_MICROSEC 105 + +#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a,b)) <= margin) +#define DFS_MAX_STAGGERED_BURSTS 3 + +/* All filter thresholds in the radar filter tables are effective at a 50% channel loading */ +#define DFS_CHAN_LOADING_THRESH 50 +#define DFS_EXT_CHAN_LOADING_THRESH 30 +#define DFS_DEFAULT_PRI_MARGIN 6 +#define DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN 4 +#define ATH_DFSQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_radarqlock)) +#define ATH_DFSQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_radarqlock)) +#define ATH_DFSQ_LOCK_INIT(_dfs) adf_os_spinlock_init(&(_dfs)->dfs_radarqlock) + +#define ATH_ARQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_arqlock)) +#define ATH_ARQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_arqlock)) +#define ATH_ARQ_LOCK_INIT(_dfs) adf_os_spinlock_init(&(_dfs)->dfs_arqlock) + +#define ATH_DFSEVENTQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_eventqlock)) +#define ATH_DFSEVENTQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_eventqlock)) +#define ATH_DFSEVENTQ_LOCK_INIT(_dfs) adf_os_spinlock_init((&(_dfs)->dfs_eventqlock)); + + + + + +#define DFS_TSMASK 0xFFFFFFFF /* Mask for time stamp from descriptor */ +#define DFS_TSSHIFT 32 /* Shift for time stamp from descriptor */ +#define DFS_TSF_WRAP 0xFFFFFFFFFFFFFFFFULL /* 64 bit TSF wrap value */ +#define DFS_64BIT_TSFMASK 0x0000000000007FFFULL /* TS mask for 64 bit value */ + + +#define DFS_AR_RADAR_RSSI_THR 5 /* in dB */ +#define DFS_AR_RADAR_RESET_INT 1 /* in secs */ +#define DFS_AR_RADAR_MAX_HISTORY 500 +#define DFS_AR_REGION_WIDTH 128 +#define DFS_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */ +#define DFS_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */ +#define DFS_AR_MAX_NUM_ACK_REGIONS 9 +#define DFS_AR_ACK_DETECT_PAR_THRESH 20 +#define DFS_AR_PKT_COUNT_THRESH 20 + +#define DFS_MAX_DL_SIZE 64 +#define DFS_MAX_DL_MASK 0x3F + +#define DFS_NOL_TIME DFS_NOL_TIMEOUT_US + /* 30 minutes in usecs */ + +#define DFS_WAIT_TIME 60*1000000 /* 1 minute in usecs */ + +#define DFS_DISABLE_TIME 3*60*1000000 /* 3 minutes in usecs */ + +#define DFS_MAX_B5_SIZE 128 +#define DFS_MAX_B5_MASK 0x0000007F /* 128 */ + +#define DFS_MAX_RADAR_OVERLAP 16 /* Max number of overlapping filters */ + +#define DFS_MAX_EVENTS 1024 /* Max number of dfs events which can be q'd */ + +#define DFS_RADAR_EN 0x80000000 /* Radar detect is capable */ +#define DFS_AR_EN 0x40000000 /* AR detect is capable */ +#define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */ + +#define DFS_BIN_MAX_PULSES 60 /* max num of pulses in a burst */ +#define DFS_BIN5_PRI_LOWER_LIMIT 990 /* us */ + +/* to cover the single pusle burst case, change from 2010 us to 2010000 us */ + +/* + * this is reverted back to 2010 as larger value causes false + * bin5 detect (EV76432, EV76320) + */ +#define DFS_BIN5_PRI_HIGHER_LIMIT 2010 /* us */ + +#define DFS_BIN5_WIDTH_MARGIN 4 /* us */ +#define DFS_BIN5_RSSI_MARGIN 5 /* dBm */ +/*Following threshold is not specified but should be okay statistically*/ +#define DFS_BIN5_BRI_LOWER_LIMIT 300000 /* us */ +#define DFS_BIN5_BRI_UPPER_LIMIT 12000000 /* us */ + +#define DFS_MAX_PULSE_BUFFER_SIZE 1024 /* Max number of pulses kept in buffer */ +#define DFS_MAX_PULSE_BUFFER_MASK 0x3ff + +#define DFS_FAST_CLOCK_MULTIPLIER (800/11) +#define DFS_NO_FAST_CLOCK_MULTIPLIER (80) + +typedef adf_os_spinlock_t dfsq_lock_t; + +#ifdef WIN32 +#pragma pack(push, dfs_pulseparams, 1) +#endif +struct dfs_pulseparams { + u_int64_t p_time; /* time for start of pulse in usecs*/ + u_int8_t p_dur; /* Duration of pulse in usecs*/ + u_int8_t p_rssi; /* Duration of pulse in usecs*/ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_pulseparams) +#endif + +#ifdef WIN32 +#pragma pack(push, dfs_pulseline, 1) +#endif +struct dfs_pulseline { + /* pl_elems - array of pulses in delay line */ + struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE]; + u_int32_t pl_firstelem; /* Index of the first element */ + u_int32_t pl_lastelem; /* Index of the last element */ + u_int32_t pl_numelems; /* Number of elements in the delay line */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_pulseline) +#endif + +#ifdef WIN32 +#pragma pack(push, dfs_event, 1) +#endif + +#define DFS_EVENT_CHECKCHIRP 0x01 /* Whether to check the chirp flag */ +#define DFS_EVENT_HW_CHIRP 0x02 /* hardware chirp */ +#define DFS_EVENT_SW_CHIRP 0x04 /* software chirp */ + +/* + * Use this only if the event has CHECKCHIRP set. + */ +#define DFS_EVENT_ISCHIRP(e) \ + ((e)->re_flags & (DFS_EVENT_HW_CHIRP | DFS_EVENT_SW_CHIRP)) + +/* + * Check if the given event is to be rejected as not possibly + * a chirp. This means: + * (a) it's a hardware or software checked chirp, and + * (b) the HW/SW chirp bits are both 0. + */ +#define DFS_EVENT_NOTCHIRP(e) \ + (((e)->re_flags & (DFS_EVENT_CHECKCHIRP)) && \ + (! DFS_EVENT_ISCHIRP((e)))) + +struct dfs_event { + u_int64_t re_full_ts; /* 64-bit full timestamp from interrupt time */ + u_int32_t re_ts; /* Original 15 bit recv timestamp */ + u_int8_t re_rssi; /* rssi of radar event */ + u_int8_t re_dur; /* duration of radar pulse */ + u_int8_t re_chanindex; /* Channel of event */ + u_int8_t re_flags; /* Event flags */ + u_int32_t re_freq; /* Centre frequency of event, KHz */ + u_int32_t re_freq_lo; /* Lower bounds of frequency, KHz */ + u_int32_t re_freq_hi; /* Upper bounds of frequency, KHz */ + int sidx; /* Pulse Index as in radar summary report */ + STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_event) +#endif + +#define DFS_AR_MAX_ACK_RADAR_DUR 511 +#define DFS_AR_MAX_NUM_PEAKS 3 +#define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */ +#define DFS_AR_ARQ_SEQSIZE 2049 /* Sequence counter wrap for AR */ + +#define DFS_RADARQ_SIZE 512 /* 1K radar events for buffer size */ +#define DFS_RADARQ_SEQSIZE 513 /* Sequence counter wrap for radar */ +#define DFS_NUM_RADAR_STATES 64 /* Number of radar channels we keep state for */ +#define DFS_MAX_NUM_RADAR_FILTERS 10 /* Max number radar filters for each type */ +#define DFS_MAX_RADAR_TYPES 32 /* Number of different radar types */ + +struct dfs_ar_state { + u_int32_t ar_prevwidth; + u_int32_t ar_phyerrcount[DFS_AR_MAX_ACK_RADAR_DUR]; + u_int32_t ar_acksum; + u_int32_t ar_packetthreshold; /* Thresh to determine traffic load */ + u_int32_t ar_parthreshold; /* Thresh to determine peak */ + u_int32_t ar_radarrssi; /* Rssi threshold for AR event */ + u_int16_t ar_prevtimestamp; + u_int16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS]; +}; + +#ifdef WIN32 +#pragma pack(push, dfs_delayelem, 1) +#endif +struct dfs_delayelem { + u_int32_t de_time; /* Current "filter" time for start of pulse in usecs*/ + u_int8_t de_dur; /* Duration of pulse in usecs*/ + u_int8_t de_rssi; /* rssi of pulse in dB*/ + u_int64_t de_ts; /* time stamp for this delay element */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_delayelem) +#endif + +/* NB: The first element in the circular buffer is the oldest element */ + +#ifdef WIN32 +#pragma pack(push, dfs_delayline, 1) +#endif +struct dfs_delayline { + struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; /* Array of pulses in delay line */ + u_int64_t dl_last_ts; /* Last timestamp the delay line was used (in usecs) */ + u_int32_t dl_firstelem; /* Index of the first element */ + u_int32_t dl_lastelem; /* Index of the last element */ + u_int32_t dl_numelems; /* Number of elements in the delay line */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_delayline) +#endif + +#ifdef WIN32 +#pragma pack(push, dfs_filter, 1) +#endif +struct dfs_filter { + struct dfs_delayline rf_dl; /* Delay line of pulses for this filter */ + u_int32_t rf_numpulses; /* Number of pulses in the filter */ + u_int32_t rf_minpri; /* min pri to be considered for this filter*/ + u_int32_t rf_maxpri; /* max pri to be considered for this filter*/ + u_int32_t rf_threshold; /* match filter output threshold for radar detect */ + u_int32_t rf_filterlen; /* Length (in usecs) of the filter */ + u_int32_t rf_patterntype; /* fixed or variable pattern type */ + u_int32_t rf_fixed_pri_radar_pulse; /* indicates if it is a fixed pri pulse */ + u_int32_t rf_mindur; /* Min duration for this radar filter */ + u_int32_t rf_maxdur; /* Max duration for this radar filter */ + u_int32_t rf_ignore_pri_window; + u_int32_t rf_pulseid; /* Unique ID corresponding to the original filter ID */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_filter) +#endif + +struct dfs_filtertype { + struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS]; + u_int32_t ft_filterdur; /* Duration of pulse which specifies filter type*/ + u_int32_t ft_numfilters; /* Num filters of this type */ + u_int64_t ft_last_ts; /* Last timestamp this filtertype was used + * (in usecs) */ + u_int32_t ft_mindur; /* min pulse duration to be considered + * for this filter type */ + u_int32_t ft_maxdur; /* max pulse duration to be considered + * for this filter type */ + u_int32_t ft_rssithresh; /* min rssi to be considered + * for this filter type */ + u_int32_t ft_numpulses; /* Num pulses in each filter of this type */ + u_int32_t ft_patterntype; /* fixed or variable pattern type */ + u_int32_t ft_minpri; /* min pri to be considered for this type */ + u_int32_t ft_rssimargin; /* rssi threshold margin. In Turbo Mode HW + * reports rssi 3dB lower than in non TURBO + * mode. This will offset that diff. */ +}; + +struct dfs_state { + struct ieee80211_channel rs_chan; /* Channel info */ + u_int8_t rs_chanindex; /* Channel index in radar structure */ + u_int32_t rs_numradarevents; /* Number of radar events */ + + struct ath_dfs_phyerr_param rs_param; +}; + +#define DFS_NOL_TIMEOUT_S (30*60) /* 30 minutes in seconds */ +//#define DFS_NOL_TIMEOUT_S (5*60) /* 5 minutes in seconds - debugging */ +#define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000) +#define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000) + +#ifdef WIN32 +#pragma pack(push, dfs_nolelem, 1) +#endif +struct dfs_nolelem { + u_int32_t nol_freq; /* centre frequency */ + u_int32_t nol_chwidth; /* event width (MHz) */ + unsigned long nol_start_ticks; /* NOL start time in OS ticks */ + u_int32_t nol_timeout_ms; /* NOL timeout value in msec */ + os_timer_t nol_timer; /* per element NOL timer */ + struct dfs_nolelem *nol_next; /* next element pointer */ +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_nolelem) +#endif + +/* Pass structure to DFS NOL timer */ +struct dfs_nol_timer_arg { + struct ath_dfs *dfs; + u_int16_t delfreq; + u_int16_t delchwidth; +}; + +#ifdef WIN32 +#pragma pack(push, dfs_info, 1) +#endif +struct dfs_info { + int rn_use_nol; /* Use the NOL when radar found (default: TRUE) */ + u_int32_t rn_numradars; /* Number of different types of radars */ + u_int64_t rn_lastfull_ts; /* Last 64 bit timstamp from recv interrupt */ + u_int16_t rn_last_ts; /* last 15 bit ts from recv descriptor */ + u_int32_t rn_last_unique_ts; /* last unique 32 bit ts from recv descriptor */ + + u_int64_t rn_ts_prefix; /* Prefix to prepend to 15 bit recv ts */ + u_int32_t rn_numbin5radars; /* Number of bin5 radar pulses to search for */ + u_int32_t rn_fastdivGCval; /* Value of fast diversity gc limit from init file */ + int32_t rn_minrssithresh; /* Min rssi for all radar types */ + u_int32_t rn_maxpulsedur; /* Max pulse width in TSF ticks */ + + u_int8_t dfs_ext_chan_busy; + u_int64_t ext_chan_busy_ts; + + u_int64_t dfs_bin5_chirp_ts; + u_int8_t dfs_last_bin5_dur; +} adf_os_packed; +#ifdef WIN32 +#pragma pack(pop, dfs_info) +#endif + +struct dfs_bin5elem { + u_int64_t be_ts; /* Timestamp for the bin5 element */ + u_int32_t be_rssi; /* Rssi for the bin5 element */ + u_int32_t be_dur; /* Duration of bin5 element */ +}; + +struct dfs_bin5radars { + struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE]; /* List of bin5 elems that fall + * within the time window */ + u_int32_t br_firstelem; /* Index of the first element */ + u_int32_t br_lastelem; /* Index of the last element */ + u_int32_t br_numelems; /* Number of elements in the delay line */ + struct dfs_bin5pulse br_pulse; /* Original info about bin5 pulse */ +}; + +struct dfs_stats { + u_int32_t num_radar_detects; /* total num. of radar detects */ + u_int32_t total_phy_errors; + u_int32_t owl_phy_errors; + u_int32_t pri_phy_errors; + u_int32_t ext_phy_errors; + u_int32_t dc_phy_errors; + u_int32_t early_ext_phy_errors; + u_int32_t bwinfo_errors; + u_int32_t datalen_discards; + u_int32_t rssi_discards; + u_int64_t last_reset_tstamp; +}; + +/* + * This is for debuggin DFS as console log interferes with (helps) + * radar detection +*/ + +#define DFS_EVENT_LOG_SIZE 256 +struct dfs_event_log { + u_int64_t ts; /* 64-bit full timestamp from interrupt time */ + u_int32_t diff_ts; /* diff timestamp */ + u_int8_t rssi; /* rssi of radar event */ + u_int8_t dur; /* duration of radar pulse */ +}; + + +#define ATH_DFS_RESET_TIME_S 7 +#define ATH_DFS_WAIT (60 + ATH_DFS_RESET_TIME_S) /* 60 seconds */ +#define ATH_DFS_WAIT_MS ((ATH_DFS_WAIT) * 1000) /*in MS*/ + +#define ATH_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes*/ +#define ATH_DFS_WEATHER_CHANNEL_WAIT_S (ATH_DFS_WEATHER_CHANNEL_WAIT_MIN * 60) +#define ATH_DFS_WEATHER_CHANNEL_WAIT_MS ((ATH_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS*/ + +#define ATH_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */ +#define ATH_DFS_WAIT_POLL_PERIOD_MS ((ATH_DFS_WAIT_POLL_PERIOD) * 1000) /*in MS*/ +#define ATH_DFS_TEST_RETURN_PERIOD 2 /* 2 seconds */ +#define ATH_DFS_TEST_RETURN_PERIOD_MS ((ATH_DFS_TEST_RETURN_PERIOD) * 1000)/* n MS*/ +#define IS_CHANNEL_WEATHER_RADAR(chan) ((chan->ic_freq >= 5600) && (chan->ic_freq <= 5650)) + +#define DFS_DEBUG_TIMEOUT_S 30 // debug timeout is 30 seconds +#define DFS_DEBUG_TIMEOUT_MS (DFS_DEBUG_TIMEOUT_S * 1000) + + +#define RSSI_POSSIBLY_FALSE 50 +#define SEARCH_FFT_REPORT_PEAK_MAG_THRSH 40 + + + +#if 0 +struct ath_dfs_caps { + u_int32_t + ath_dfs_ext_chan_ok:1, /* Can radar be detected on the extension chan? */ + ath_dfs_combined_rssi_ok:1, /* Can use combined radar RSSI? */ + /* the following flag is used to indicate if radar detection scheme */ + /* should use enhanced chirping detection algorithm. This flag also */ + /* determines if certain radar data should be discarded to minimize */ + /* false detection of radar. */ + ath_dfs_use_enhancement:1, + ath_strong_signal_diversiry:1; + + /* + * goes with ath_strong_signal_diversiry: + * If we have fast diversity capability, read off + * Strong Signal fast diversity count set in the ini + * file, and store so we can restore the value when + * radar is disabled + */ + u_int32_t ath_fastdiv_val; +}; + +struct ath_dfs_radar_tab_info { + u_int32_t dfsdomain; + int numradars; + struct dfs_pulse *dfs_radars; + int numb5radars; + struct dfs_bin5pulse *b5pulses; + HAL_PHYERR_PARAM dfs_defaultparams; +}; +#endif +struct ath_dfs { + uint32_t dfs_debug_mask; /* current debug bitmask */ + int16_t dfs_curchan_radindex; /* cur. channel radar index */ + int16_t dfs_extchan_radindex; /* extension channel radar index */ + u_int32_t dfsdomain; /* cur. DFS domain */ + u_int32_t dfs_proc_phyerr; /* Flags for Phy Errs to process */ + struct ieee80211com *ic; + STAILQ_HEAD(,dfs_event) dfs_eventq; /* Q of free dfs event objects */ + dfsq_lock_t dfs_eventqlock; /* Lock for free dfs event list */ + STAILQ_HEAD(,dfs_event) dfs_radarq; /* Q of radar events */ + dfsq_lock_t dfs_radarqlock; /* Lock for dfs q */ + STAILQ_HEAD(,dfs_event) dfs_arq; /* Q of AR events */ + dfsq_lock_t dfs_arqlock; /* Lock for AR q */ + + struct dfs_ar_state dfs_ar_state; /* AR state */ + + /* dfs_radar - Per-Channel Radar detector state */ + struct dfs_state dfs_radar[DFS_NUM_RADAR_STATES]; + + /* dfs_radarf - One filter for each radar pulse type */ + struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES]; + + struct dfs_info dfs_rinfo; /* State vars for radar processing */ + struct dfs_bin5radars *dfs_b5radars;/* array of bin5 radar events */ + int8_t **dfs_radartable; /* map of radar durs to filter types */ +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */ + int dfs_nol_count; /* How many items? */ +#endif + + struct ath_dfs_phyerr_param dfs_defaultparams; /* Default phy params per radar state */ + struct dfs_stats ath_dfs_stats; /* DFS related stats */ + struct dfs_pulseline *pulses; /* pulse history */ + struct dfs_event *events; /* Events structure */ + + u_int32_t + ath_radar_tasksched:1, /* radar task is scheduled */ + ath_dfswait:1, /* waiting on channel for radar detect */ + ath_dfstest:1; /* Test timer in progress */ + struct ath_dfs_caps dfs_caps; + u_int8_t ath_dfstest_ieeechan; /* IEEE chan num to return to after + * a dfs mute test */ +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + u_int32_t ath_dfs_cac_time; /* CAC period */ + u_int32_t ath_dfstesttime; /* Time to stay off chan during dfs test */ + os_timer_t ath_dfswaittimer; /* dfs wait timer */ + os_timer_t ath_dfstesttimer; /* dfs mute test timer */ + os_timer_t ath_dfs_debug_timer; /* dfs debug timer */ + u_int8_t dfs_bangradar; +#endif + os_timer_t ath_dfs_task_timer; /* dfs wait timer */ + int dur_multiplier; + + u_int16_t ath_dfs_isdfsregdomain; /* true when we are DFS domain */ + int ath_dfs_false_rssi_thres; + int ath_dfs_peak_mag; + + struct dfs_event_log radar_log[DFS_EVENT_LOG_SIZE]; + int dfs_event_log_count; + int dfs_event_log_on; + int dfs_phyerr_count; /* same as number of PHY radar interrupts */ + int dfs_phyerr_reject_count; /* when TLV is supported, # of radar events ignored after TLV is parsed */ + int dfs_phyerr_queued_count; /* number of radar events queued for matching the filters */ + int dfs_phyerr_freq_min; + int dfs_phyerr_freq_max; + int dfs_phyerr_w53_counter; + int dfs_pri_multiplier; /* allow pulse if they are within multiple of PRI for the radar type */ + int ath_dfs_nol_timeout; + int dfs_pri_multiplier_ini; /* dfs pri configuration from ini */ + /* + * Flag to indicate if DFS test mode is enabled and + * channel switch is disabled. + */ + int8_t disable_dfs_ch_switch; +}; + +/* This should match the table from if_ath.c */ +enum { + ATH_DEBUG_DFS = 0x00000100, /* Minimal DFS debug */ + ATH_DEBUG_DFS1 = 0x00000200, /* Normal DFS debug */ + ATH_DEBUG_DFS2 = 0x00000400, /* Maximal DFS debug */ + ATH_DEBUG_DFS3 = 0x00000800, /* matched filterID display */ + + ATH_DEBUG_DFS_PHYERR = 0x00001000, /* phy error parsing */ + ATH_DEBUG_DFS_NOL = 0x00002000, /* NOL related entries */ + ATH_DEBUG_DFS_PHYERR_SUM = 0x00004000, /* PHY error summary */ + ATH_DEBUG_DFS_PHYERR_PKT = 0x00008000, /* PHY error payload */ + + ATH_DEBUG_DFS_BIN5 = 0x00010000, /* bin5 checks */ + ATH_DEBUG_DFS_BIN5_FFT = 0x00020000, /* bin5 FFT check */ + ATH_DEBUG_DFS_BIN5_PULSE = 0x00040000, /* bin5 pulse check */ +}; + +#define IS_CHAN_HT40(_c) IEEE80211_IS_CHAN_11N_HT40(_c) +#define IS_CHAN_HT40_PLUS(_c) IEEE80211_IS_CHAN_11N_HT40PLUS(_c) +#define IS_CHAN_HT40_MINUS(_c) IEEE80211_IS_CHAN_11N_HT40MINUS(_c) + +/* + * chirp notes! + * + * Pre-Sowl chips don't do FFT reports, so chirp pulses simply show up + * as long duration pulses. + * + * The bin5 checking code would simply look for a chirp pulse of the correct + * duration (within MIN_BIN5_DUR and MAX_BIN5_DUR) and add it to the "chirp" + * pattern. + * + * For Sowl and later, an FFT was done on longer duration frames. If those + * frames looked like a chirp, their duration was adjusted to fall within + * the chirp duration limits. If the pulse failed the chirp test (it had + * no FFT data or the FFT didn't meet the chirping requirements) then the + * pulse duration was adjusted to be greater than MAX_BIN5_DUR, so it + * would always fail chirp detection. + * + * This is pretty horrible. + * + * The eventual goal for chirp handling is thus: + * + * + In case someone ever wants to do chirp detection with this code on + * chips that don't support chirp detection, you can still do it based + * on pulse duration. That's your problem to solve. + * + * + For chips that do hardware chirp detection or FFT, the "do_check_chirp" + * bit should be set. + * + * + Then, either is_hw_chirp or is_sw_chirp is set, indicating that + * the hardware or software post-processing of the chirp event found + * that indeed it was a chirp. + * + * + Finally, the bin5 code should just check whether the chirp bits are + * set and behave appropriately, falling back onto the duration checks + * if someone wishes to use this on older hardware (or with disabled + * FFTs, for whatever reason.) + */ +/* + * XXX TODO: + * + * + add duration in uS and raw duration, so the PHY error parsing + * code is responsible for doing the duration calculation; + * + add ts in raw and corrected, so the PHY error parsing + * code is responsible for doing the offsetting, not the radar + * event code. + */ +struct dfs_phy_err { + u_int64_t fulltsf; /* 64-bit TSF as read from MAC */ + + uint32_t is_pri:1, /* detected on primary channel */ + is_ext:1, /* detected on extension channel */ + is_dc:1, /* detected at DC */ + is_early:1, /* early detect */ + do_check_chirp:1, /* whether to check hw_chirp/sw_chirp */ + is_hw_chirp:1, /* hardware-detected chirp */ + is_sw_chirp:1; /* software detected chirp */ + + u_int32_t rs_tstamp; /* 32 bit TSF from RX descriptor (event) */ + u_int32_t freq; /* Centre frequency of event - KHz */ + u_int32_t freq_lo; /* Lower bounds of frequency - KHz */ + u_int32_t freq_hi; /* Upper bounds of frequency - KHz */ + + u_int8_t rssi; /* pulse RSSI */ + u_int8_t dur; /* pulse duration, raw (not uS) */ + int sidx; /* Pulse Index as in radar summary report */ +}; + +/* Attach, detach, handle ioctl prototypes */ + +int dfs_get_thresholds(struct ieee80211com *ic, + struct ath_dfs_phyerr_param *param); +int dfs_set_thresholds(struct ieee80211com *ic, + const u_int32_t threshtype, const u_int32_t value); + +/* PHY error and radar event handling */ +int dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan); + +/* Non occupancy (NOL) handling prototypes */ +void dfs_nol_addchan(struct ath_dfs *dfs, struct ieee80211_channel *chan, u_int32_t dfs_nol_timeout); +void dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int *nchan); +void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan); +void dfs_nol_update(struct ath_dfs *dfs); +void dfs_nol_timer_cleanup(struct ath_dfs *dfs); + +/* FCC Bin5 detection prototypes */ +int dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re, + struct dfs_bin5radars *br); +int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br, + struct dfs_event *re, u_int64_t thists); +int dfs_bin5_check(struct ath_dfs *dfs); +int dfs_check_chirping(struct ath_dfs *dfs, void *buf, + u_int16_t datalen, int is_ctl, + int is_ext, int *slope, int *is_dc); +u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts, u_int8_t old_dur); +u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts, u_int8_t old_dur); +int dfs_get_random_bin5_dur(struct ath_dfs *dfs, u_int64_t tstamp); + +/* Debug prototypes */ +void dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl); +void dfs_print_nol(struct ath_dfs *dfs); +void dfs_print_filters(struct ath_dfs *dfs); +void dfs_print_activity(struct ath_dfs *dfs); +OS_TIMER_FUNC(dfs_debug_timeout); +void dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf); + +/* Misc prototypes */ +u_int32_t dfs_round(int32_t val); +struct dfs_state* dfs_getchanstate(struct ath_dfs *dfs, u_int8_t *index, int ext_ch_flag); + +/* Reset and init data structures */ + +int dfs_init_radar_filters( struct ieee80211com *ic, struct ath_dfs_radar_tab_info *radar_info); +void dfs_reset_alldelaylines(struct ath_dfs *dfs); +void dfs_reset_delayline(struct dfs_delayline *dl); +void dfs_reset_filter_delaylines(struct dfs_filtertype *dft); +void dfs_reset_radarq(struct ath_dfs *dfs); + +/* Detection algorithm prototypes */ +void dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf, + struct dfs_event *re, u_int32_t deltaT, u_int64_t this_ts); + +int dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf, + u_int32_t dur, int ext_chan_flag); +int dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf, + u_int32_t deltaT, u_int32_t dur, int ext_chan_flag); + +int dfs_bin_pri_check(struct ath_dfs *dfs, struct dfs_filter *rf, + struct dfs_delayline *dl, u_int32_t score, + u_int32_t refpri, u_int32_t refdur, int ext_chan_flag, int fundamentalpri); +int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf, + u_int32_t deltaT, u_int32_t width); +/* False detection reduction */ +int dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect, + int is_fixed_pattern); +int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf, + int is_extchan_detect); + +/* AR related prototypes */ + +/* Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * void dfs_process_ar_event(struct ath_dfs *dfs, struct ieee80211_channel *chan); + */ +/* Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * void ath_ar_disable(struct ath_dfs *dfs); + */ +/* Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * void ath_ar_enable(struct ath_dfs *dfs); + */ +void dfs_reset_ar(struct ath_dfs *dfs); +/* Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * void dfs_reset_arq(struct ath_dfs *dfs); + */ + + +struct ieee80211_channel *ieee80211_get_extchan(struct ieee80211com *ic); + +#endif /* _DFS_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs_interface.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs_interface.h new file mode 100644 index 0000000000000..ec15b9cbe166b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/dfs_interface.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_interface.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#ifndef _DFS__INTERFACE_H_ +#define _DFS__INTERFACE_H_ + +/* + * These are the only functions exported to the upper (device) layer. + */ + +/* + * EXPORT_SYMBOL(dfs_attach); + * EXPORT_SYMBOL(dfs_detach); + * EXPORT_SYMBOL(dfs_radar_enable); + * EXPORT_SYMBOL(dfs_process_phyerr); + * EXPORT_SYMBOL(dfs_control); + * EXPORT_SYMBOL(dfs_clear_stats); + * EXPORT_SYMBOL(dfs_usenol); + * EXPORT_SYMBOL(dfs_isdfsregdomain); + */ + +/* + * These are exported but not currently defined here; these should be + * evaluated. + * + * EXPORT_SYMBOL(dfs_process_ar_event); -- legacy adaptive radio processing + * EXPORT_SYMBOL(ath_ar_disable); + * EXPORT_SYMBOL(ath_ar_enable); + * EXPORT_SYMBOL(dfs_get_thresholds); + * EXPORT_SYMBOL(dfs_init_radar_filters); + * EXPORT_SYMBOL(dfs_getchanstate); + */ + + +u_int16_t dfs_isdfsregdomain(struct ieee80211com *ic); +int dfs_attach(struct ieee80211com *ic); +void dfs_detach(struct ieee80211com *ic); +int dfs_radar_enable(struct ieee80211com *ic, + struct ath_dfs_radar_tab_info *ri); +int dfs_radar_disable(struct ieee80211com *ic); +extern void dfs_process_phyerr(struct ieee80211com *ic, void *buf, u_int16_t datalen, u_int8_t rssi, + u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf); +int dfs_control(struct ieee80211com *ic, u_int id, void *indata, u_int32_t insize, + void *outdata, u_int32_t *outsize); +void dfs_clear_stats(struct ieee80211com *ic); +#if 0 +/* The following are for FCC Bin 1-4 pulses */ +struct dfs_pulse dfs_fcc_radars[] = { + // FCC TYPE 1 + // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + + // FCC TYPE 6 + // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + + // FCC TYPE 2 + {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, + + // FCC TYPE 3 + {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, + + // FCC TYPE 4 + {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, +}; + +struct dfs_pulse dfs_mkk4_radars[] = { + /* following two filters are specific to Japan/MKK4 */ +// {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us +// {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us +// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us + {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us + {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us + {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us + + /* following filters are common to both FCC and JAPAN */ + + // FCC TYPE 1 + // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + + // FCC TYPE 6 + // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + + // FCC TYPE 2 + {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, + + // FCC TYPE 3 + {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, + + // FCC TYPE 4 + {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, +}; + +struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { + {4, 28, 105, 12, 22, 5}, +}; + +struct dfs_bin5pulse dfs_jpn_bin5pulses[] = { + {5, 28, 105, 12, 22, 5}, +}; +struct dfs_pulse dfs_etsi_radars[] = { + + /* TYPE staggered pulse */ + /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ + {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/ + /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ + {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */ + + /* constant PRF based */ + /* 0.8-5us, 200 300 PRF, 10 pulses */ + {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */ + {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */ + {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */ + {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */ +// {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, + + /* 0.8-15us, 200-1600 PRF, 15 pulses */ + {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */ + + /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ + {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */ + + /* 20-30us, 2000-4000 PRF, 20 pulses*/ + {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */ +}; +#endif +#endif /* _DFS__INTERFACE_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/radar_filters.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/radar_filters.h new file mode 100644 index 0000000000000..4ab74188b656b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/inc/radar_filters.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + radar_filters.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + + + + +struct dfs_pulse dfs_fcc_radars[] = { + // FCC TYPE 1 + // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + + // FCC TYPE 6 + // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + + // FCC TYPE 2 + {23, 5, 4347, 6666, 0, 18, 8, 0, 7, 22, 0, 3, 0, 2}, + + // FCC TYPE 3 + {18, 10, 2000, 5000, 0, 23, 6, 6, 13, 22, 0, 3, 0, 5}, + + // FCC TYPE 4 + {16, 15, 2000, 5000, 0, 25, 5, 11, 23, 22, 0, 3, 0, 11}, +}; + +struct dfs_pulse dfs_mkk4_radars[] = { + /* following two filters are specific to Japan/MKK4 */ +// {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us +// {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us +// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us + {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us + {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us + {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us + + /* following filters are common to both FCC and JAPAN */ + + // FCC TYPE 1 + // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066 + {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0}, + {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, + + // FCC TYPE 6 + // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us + {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1}, + + // FCC TYPE 2 + {23, 5, 4347, 6666, 0, 18, 8, 0, 7, 22, 0, 3, 0, 2}, + + // FCC TYPE 3 + {18, 10, 2000, 5000, 0, 23, 6, 6, 13, 22, 0, 3, 0, 5}, + + // FCC TYPE 4 + {16, 15, 2000, 5000, 0, 25, 5, 11, 23, 22, 0, 3, 0, 11}, +}; + +struct dfs_bin5pulse dfs_fcc_bin5pulses[] = { + {4, 28, 105, 12, 22, 5}, +}; + +struct dfs_bin5pulse dfs_jpn_bin5pulses[] = { + {5, 28, 105, 12, 22, 5}, +}; +struct dfs_pulse dfs_etsi_radars[] = { + + /* TYPE staggered pulse */ + /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ + {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/ + /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ + {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */ + + /* constant PRF based */ + /* 0.8-5us, 200 300 PRF, 10 pulses */ + {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */ + {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */ + {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */ + {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */ +// {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, + + /* 0.8-15us, 200-1600 PRF, 15 pulses */ + {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */ + + /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ + {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */ + + /* 20-30us, 2000-4000 PRF, 20 pulses*/ + {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */ +}; diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/sources b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/sources new file mode 100644 index 0000000000000..d27e9b807daf9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/sources @@ -0,0 +1,62 @@ +# +# sources file for DFS module +# +LMAC=.. +TOP=$(LMAC)\.. +INC=$(TOP)\include +HAL=$(TOP)\hal +ATH=$(LMAC)\ath_dev + +!IFDEF BUILD_UMAC +MP=$(TOP)\os\win_nwf +INC_MP=$(MP)\include +IF_ATH=$(TOP)\umac\if_lmac +!ELSE +MP=$(TOP)\winvista +INC_MP=$(INC)\winvista +IF_ATH=$(TOP)\if_ath_net80211 +!ENDIF + +!include $(INC_MP)\sources.inc + +TARGETNAME=ath_dfs +TARGETPATH=$(TOP)\lib +TARGETTYPE=LIBRARY + +!IFDEF BUILD_HTC +# Put htc include dirs at the head of the list. +# This ensures that the htc/adf header files will preempt any +# header files of the same names from the regular adf directories. +INCLUDES= $(INCLUDES) \ + $(TOP)\htc\inc; \ + $(TOP)\htc\adf\include; \ + $(TOP)\htc\adf\winvista\nbuf; \ + $(TOP)\htc\adf\winvista\include; +!ENDIF + +INCLUDES= $(INCLUDES) \ + $(TOP); \ + $(ATH); \ + $(ATH_DFS); \ + $(TOP)\ath\winvista; \ + $(TOP)\ath\winvista; \ + $(HAL); \ + $(HAL)\winvista; \ + $(IF_ATH); \ + $(INC); \ + $(INC_MP); \ + $(SDXROOT)\net\inc; \ + $(DDK_INC_PATH) + +SOURCES=$(SOURCES) \ + dfs_staggered.c \ + dfs_bindetects.c \ + dfs_misc.c \ + dfs_debug.c \ + dfs_process_radarevent.c \ + dfs_process_phyerr.c \ + dfs_nol.c \ + dfs_ar.c \ + dfs_fcc_bin5.c \ + dfs_init.c \ + dfs.c diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs.c new file mode 100644 index 0000000000000..bf81edff21ae0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs.c @@ -0,0 +1,985 @@ +/* + * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include + +#ifndef ATH_SUPPORT_DFS +#define ATH_SUPPORT_DFS 1 +#include "sys/queue.h" + +//#include "if_athioctl.h" +//#include "if_athvar.h" +#include "dfs_ioctl.h" +#include "dfs.h" + +int domainoverride=DFS_UNINIT_DOMAIN; + +/* + ** channel switch announcement (CSA) + ** usenol=1 (default) make CSA and switch to a new channel on radar detect + ** usenol=0, make CSA with next channel same as current on radar detect + ** usenol=2, no CSA and stay on the same channel on radar detect + **/ + +int usenol=1; +u_int32_t dfs_debug_level=ATH_DEBUG_DFS; + +#if 0 /* the code to call this is curently commented-out below */ +/* + * Mark a channel as having interference detected upon it. + * + * This adds the interference marker to both the primary and + * extension channel. + * + * XXX TODO: make the NOL and channel interference logic a bit smarter + * so only the channel with the radar event is marked, rather than + * both the primary and extension. + */ +static void +dfs_channel_mark_radar(struct ath_dfs *dfs, struct ieee80211_channel *chan) +{ + struct ieee80211_channel_list chan_info; + int i; + + //chan->ic_flagext |= CHANNEL_INTERFERENCE; + + /* + * If radar is detected in 40MHz mode, add both the primary and the + * extension channels to the NOL. chan is the channel data we return + * to the ath_dev layer which passes it on to the 80211 layer. + * As we want the AP to change channels and send out a CSA, + * we always pass back the primary channel data to the ath_dev layer. + */ + if ((dfs->dfs_rinfo.rn_use_nol == 1) && + (dfs->ic->ic_opmode == IEEE80211_M_HOSTAP || + dfs->ic->ic_opmode == IEEE80211_M_IBSS)) { + chan_info.cl_nchans= 0; + dfs->ic->ic_get_ext_chan_info (dfs->ic, &chan_info); + + for (i = 0; i < chan_info.cl_nchans; i++) + { + if (chan_info.cl_channels[i] == NULL) { + DFS_PRINTK("%s: NULL channel\n", __func__); + } else { + chan_info.cl_channels[i]->ic_flagext |= CHANNEL_INTERFERENCE; + dfs_nol_addchan(dfs, chan_info.cl_channels[i], dfs->ath_dfs_nol_timeout); + } + } + + + /* + * Update the umac/driver channels with the new NOL information. + */ + dfs_nol_update(dfs); + } +} +#endif /* #if 0 */ + +static OS_TIMER_FUNC(dfs_task) +{ + struct ieee80211com *ic; + struct ath_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(ic, struct ieee80211com *); + dfs = (struct ath_dfs *)ic->ic_dfs; + /* + * XXX no locking?! + */ + if (dfs_process_radarevent(dfs, ic->ic_curchan)) { +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + + /* + * This marks the channel (and the extension channel, if HT40) as + * having seen a radar event. It marks CHAN_INTERFERENCE and + * will add it to the local NOL implementation. + * + * This is only done for 'usenol=1', as the other two modes + * don't do radar notification or CAC/CSA/NOL; it just notes + * there was a radar. + */ + + if (dfs->dfs_rinfo.rn_use_nol == 1) { + //dfs_channel_mark_radar(dfs, ic->ic_curchan); + } +#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ + + /* + * This calls into the umac DFS code, which sets the umac related + * radar flags and begins the channel change machinery. + * + * XXX TODO: the umac NOL code isn't used, but IEEE80211_CHAN_RADAR + * still gets set. Since the umac NOL code isn't used, that flag + * is never cleared. This needs to be fixed. See EV 105776. + */ + if (dfs->dfs_rinfo.rn_use_nol == 1) { + ic->ic_dfs_notify_radar(ic, ic->ic_curchan); + } else if (dfs->dfs_rinfo.rn_use_nol == 0) { + /* + * For the test mode, don't do a CSA here; but setup the + * test timer so we get a CSA _back_ to the original channel. + */ + OS_CANCEL_TIMER(&dfs->ath_dfstesttimer); + dfs->ath_dfstest = 1; + dfs->ath_dfstest_ieeechan = ic->ic_curchan->ic_ieee; + dfs->ath_dfstesttime = 1; /* 1ms */ + OS_SET_TIMER(&dfs->ath_dfstesttimer, dfs->ath_dfstesttime); + } + } + dfs->ath_radar_tasksched = 0; +} + +static +OS_TIMER_FUNC(dfs_testtimer_task) +{ + struct ieee80211com *ic; + struct ath_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(ic, struct ieee80211com *); + dfs = (struct ath_dfs *)ic->ic_dfs; + + /* XXX no locking? */ + dfs->ath_dfstest = 0; + + /* + * Flip the channel back to the original channel. + * Make sure this is done properly with a CSA. + */ + DFS_PRINTK("%s: go back to channel %d\n", + __func__, + dfs->ath_dfstest_ieeechan); + + /* + * XXX The mere existence of this method indirection + * to a umac function means this code belongs in + * the driver, _not_ here. Please fix this! + */ + ic->ic_start_csa(ic, dfs->ath_dfstest_ieeechan); +} + + +static int dfs_get_debug_info(struct ieee80211com *ic, int type, void *data) +{ + struct ath_dfs *dfs=(struct ath_dfs *)ic->ic_dfs; + if (data) { + *(u_int32_t *)data = dfs->dfs_proc_phyerr; + } + return (int)dfs->dfs_proc_phyerr; +} + + +int +dfs_attach(struct ieee80211com *ic) +{ + int i, n; + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + struct ath_dfs_radar_tab_info radar_info; +#define N(a) (sizeof(a)/sizeof(a[0])) + + if (dfs != NULL) { + /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: ic_dfs was not NULL\n", + __func__); + */ + return 1; + } + + dfs = (struct ath_dfs *)OS_MALLOC(NULL, sizeof(struct ath_dfs), GFP_ATOMIC); + + + if (dfs == NULL) { + /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: ath_dfs allocation failed\n", __func__);*/ + return 1; + } + + OS_MEMZERO(dfs, sizeof (struct ath_dfs)); + + ic->ic_dfs = (void *)dfs; + + dfs->ic = ic; + + ic->ic_dfs_debug = dfs_get_debug_info; +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + dfs->dfs_nol = NULL; +#endif + + /* + * Zero out radar_info. It's possible that the attach function won't + * fetch an initial regulatory configuration; you really do want to + * ensure that the contents indicates there aren't any filters. + */ + OS_MEMZERO(&radar_info, sizeof(radar_info)); + ic->ic_dfs_attach(ic, &dfs->dfs_caps, &radar_info); + dfs_clear_stats(ic); + dfs->dfs_event_log_on = 0; + OS_INIT_TIMER(NULL, &(dfs->ath_dfs_task_timer), dfs_task, (void *) (ic), + ADF_DEFERRABLE_TIMER); +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + OS_INIT_TIMER(NULL, &(dfs->ath_dfstesttimer), dfs_testtimer_task, + (void *) ic, ADF_DEFERRABLE_TIMER); + dfs->ath_dfs_cac_time = ATH_DFS_WAIT_MS; + dfs->ath_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD_MS; +#endif + ATH_DFSQ_LOCK_INIT(dfs); + STAILQ_INIT(&dfs->dfs_radarq); + ATH_ARQ_LOCK_INIT(dfs); + STAILQ_INIT(&dfs->dfs_arq); + STAILQ_INIT(&(dfs->dfs_eventq)); + ATH_DFSEVENTQ_LOCK_INIT(dfs); + dfs->events = (struct dfs_event *)OS_MALLOC(NULL, + sizeof(struct dfs_event)*DFS_MAX_EVENTS, + GFP_ATOMIC); + if (dfs->events == NULL) { + OS_FREE(dfs); + ic->ic_dfs = NULL; + DFS_PRINTK("%s: events allocation failed\n", __func__); + return 1; + } + for (i = 0; i < DFS_MAX_EVENTS; i++) { + STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i], re_list); + } + + dfs->pulses = (struct dfs_pulseline *)OS_MALLOC(NULL, sizeof(struct dfs_pulseline), GFP_ATOMIC); + if (dfs->pulses == NULL) { + OS_FREE(dfs->events); + dfs->events = NULL; + OS_FREE(dfs); + ic->ic_dfs = NULL; + DFS_PRINTK("%s: pulse buffer allocation failed\n", __func__); + return 1; + } + + dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK; + + /* Allocate memory for radar filters */ + for (n=0; ndfs_radarf[n] = (struct dfs_filtertype *)OS_MALLOC(NULL, sizeof(struct dfs_filtertype),GFP_ATOMIC); + if (dfs->dfs_radarf[n] == NULL) { + DFS_PRINTK("%s: cannot allocate memory for radar filter types\n", + __func__); + goto bad1; + } + OS_MEMZERO(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype)); + } + /* Allocate memory for radar table */ + dfs->dfs_radartable = (int8_t **)OS_MALLOC(NULL, 256*sizeof(int8_t *), GFP_ATOMIC); + if (dfs->dfs_radartable == NULL) { + DFS_PRINTK("%s: cannot allocate memory for radar table\n", + __func__); + goto bad1; + } + for (n=0; n<256; n++) { + dfs->dfs_radartable[n] = OS_MALLOC(NULL, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t), + GFP_ATOMIC); + if (dfs->dfs_radartable[n] == NULL) { + DFS_PRINTK("%s: cannot allocate memory for radar table entry\n", + __func__); + goto bad2; + } + } + + if (usenol == 0) + DFS_PRINTK("%s: NOL disabled\n", __func__); + else if (usenol == 2) + DFS_PRINTK("%s: NOL disabled; no CSA\n", __func__); + + dfs->dfs_rinfo.rn_use_nol = usenol; + + /* Init the cached extension channel busy for false alarm reduction */ + dfs->dfs_rinfo.ext_chan_busy_ts = ic->ic_get_TSF64(ic); + dfs->dfs_rinfo.dfs_ext_chan_busy = 0; + /* Init the Bin5 chirping related data */ + dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts; + dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR; + dfs->dfs_b5radars = NULL; + + /* + * If dfs_init_radar_filters() fails, we can abort here and + * reconfigure when the first valid channel + radar config + * is available. + */ + if ( dfs_init_radar_filters( ic, &radar_info) ) { + DFS_PRINTK(" %s: Radar Filter Intialization Failed \n", + __func__); + return 1; + } + + dfs->ath_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE; + dfs->ath_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH; + dfs->dfs_phyerr_freq_min = 0x7fffffff; + dfs->dfs_phyerr_freq_max = 0; + dfs->dfs_phyerr_queued_count = 0; + dfs->dfs_phyerr_w53_counter = 0; + dfs->dfs_pri_multiplier = 2; + + dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S; + return 0; + +bad2: + OS_FREE(dfs->dfs_radartable); + dfs->dfs_radartable = NULL; +bad1: + for (n=0; ndfs_radarf[n] != NULL) { + OS_FREE(dfs->dfs_radarf[n]); + dfs->dfs_radarf[n] = NULL; + } + } + if (dfs->pulses) { + OS_FREE(dfs->pulses); + dfs->pulses = NULL; + } + if (dfs->events) { + OS_FREE(dfs->events); + dfs->events = NULL; + } + + if (ic->ic_dfs) { + OS_FREE(ic->ic_dfs); + ic->ic_dfs = NULL; + } + return 1; +#undef N +} + +void +dfs_detach(struct ieee80211com *ic) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + int n, empty; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n", __func__); + return; + } + + /* Bug 29099 make sure all outstanding timers are cancelled*/ + + if (dfs->ath_radar_tasksched) { + OS_CANCEL_TIMER(&dfs->ath_dfs_task_timer); + dfs->ath_radar_tasksched = 0; + } + + if (dfs->ath_dfstest) { + OS_CANCEL_TIMER(&dfs->ath_dfstesttimer); + dfs->ath_dfstest = 0; + } + +#if 0 +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + if (dfs->ic_dfswait) { + OS_CANCEL_TIMER(&dfs->ic_dfswaittimer); + dfs->ath_dfswait = 0; + } + + OS_CANCEL_TIMER(&dfs->sc_dfs_war_timer); + if (dfs->dfs_nol != NULL) { + struct dfs_nolelem *nol, *next; + nol = dfs->dfs_nol; + /* Bug 29099 - each NOL element has its own timer, cancel it and + free the element*/ + while (nol != NULL) { + OS_CANCEL_TIMER(&nol->nol_timer); + next = nol->nol_next; + OS_FREE(nol); + nol = next; + } + dfs->dfs_nol = NULL; + } +#endif +#endif + /* Return radar events to free q*/ + dfs_reset_radarq(dfs); + dfs_reset_alldelaylines(dfs); + + /* Free up pulse log*/ + if (dfs->pulses != NULL) { + OS_FREE(dfs->pulses); + dfs->pulses = NULL; + } + + for (n=0; ndfs_radarf[n] != NULL) { + OS_FREE(dfs->dfs_radarf[n]); + dfs->dfs_radarf[n] = NULL; + } + } + + + if (dfs->dfs_radartable != NULL) { + for (n=0; n<256; n++) { + if (dfs->dfs_radartable[n] != NULL) { + OS_FREE(dfs->dfs_radartable[n]); + dfs->dfs_radartable[n] = NULL; + } + } + OS_FREE(dfs->dfs_radartable); + dfs->dfs_radartable = NULL; +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + dfs->ath_dfs_isdfsregdomain = 0; +#endif + } + + if (dfs->dfs_b5radars != NULL) { + OS_FREE(dfs->dfs_b5radars); + dfs->dfs_b5radars=NULL; + } + +/* Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * dfs_reset_ar(dfs); + */ + ATH_ARQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_arq)); + ATH_ARQ_UNLOCK(dfs); + if (!empty) { +/* + * Commenting out since all the ar functions are obsolete and + * the function definition has been removed as part of dfs_ar.c + * + * dfs_reset_arq(dfs); + */ + } + if (dfs->events != NULL) { + OS_FREE(dfs->events); + dfs->events = NULL; + } + dfs_nol_timer_cleanup(dfs); + OS_FREE(dfs); + + /* XXX? */ + ic->ic_dfs = NULL; +} +/* + * This is called each time a channel change occurs, to (potentially) enable + * the radar code. + */ +int dfs_radar_disable(struct ieee80211com *ic) +{ + struct ath_dfs *dfs=(struct ath_dfs *)ic->ic_dfs; +#ifdef ATH_ENABLE_AR + dfs->dfs_proc_phyerr &= ~DFS_AR_EN; +#endif + dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; + return 0; +} +/* + * This is called each time a channel change occurs, to (potentially) enable + * the radar code. + */ +int dfs_radar_enable(struct ieee80211com *ic, + struct ath_dfs_radar_tab_info *radar_info) +{ + int is_ext_ch; + int is_fastclk = 0; + int radar_filters_init_status = 0; + //u_int32_t rfilt; + struct ath_dfs *dfs; + struct dfs_state *rs_pri, *rs_ext; + struct ieee80211_channel *chan=ic->ic_curchan, *ext_ch = NULL; + is_ext_ch=IEEE80211_IS_CHAN_11N_HT40(ic->ic_curchan); + dfs=(struct ath_dfs *)ic->ic_dfs; + rs_pri = NULL; + rs_ext = NULL; +#if 0 + int i; +#endif + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: ic_dfs is NULL\n", + __func__); + + return -EIO; + } + ic->ic_dfs_disable(ic); + + /* + * Setting country code might change the DFS domain + * so initialize the DFS Radar filters + */ + radar_filters_init_status = dfs_init_radar_filters(ic, radar_info); + + /* + * dfs_init_radar_filters() returns 1 on failure and + * 0 on success. + */ + if ( DFS_STATUS_FAIL == radar_filters_init_status ) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: DFS Radar Filters Initialization Failed", + __func__, __LINE__); + return -EIO; + } + + if ((ic->ic_opmode == IEEE80211_M_HOSTAP || ic->ic_opmode == IEEE80211_M_IBSS)) { + + if (IEEE80211_IS_CHAN_DFS(chan)) { + + u_int8_t index_pri, index_ext; +#ifdef ATH_ENABLE_AR + dfs->dfs_proc_phyerr |= DFS_AR_EN; +#endif + dfs->dfs_proc_phyerr |= DFS_RADAR_EN; + + + + if (is_ext_ch) { + ext_ch = ieee80211_get_extchan(ic); + } + dfs_reset_alldelaylines(dfs); + + rs_pri = dfs_getchanstate(dfs, &index_pri, 0); + if (ext_ch) { + rs_ext = dfs_getchanstate(dfs, &index_ext, 1); + } + if (rs_pri != NULL && ((ext_ch==NULL)||(rs_ext != NULL))) { + struct ath_dfs_phyerr_param pe; + + OS_MEMSET(&pe, '\0', sizeof(pe)); + + if (index_pri != dfs->dfs_curchan_radindex) + dfs_reset_alldelaylines(dfs); + + dfs->dfs_curchan_radindex = (int16_t) index_pri; + dfs->dfs_pri_multiplier_ini = radar_info->dfs_pri_multiplier; + + if (rs_ext) + dfs->dfs_extchan_radindex = (int16_t) index_ext; + + ath_dfs_phyerr_param_copy(&pe, + &rs_pri->rs_param); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, + "%s: firpwr=%d, rssi=%d, height=%d, " + "prssi=%d, inband=%d, relpwr=%d, " + "relstep=%d, maxlen=%d\n", + __func__, + pe.pe_firpwr, + pe.pe_rrssi, + pe.pe_height, + pe.pe_prssi, + pe.pe_inband, + pe.pe_relpwr, + pe.pe_relstep, + pe.pe_maxlen + ); + + ic->ic_dfs_enable(ic, &is_fastclk, &pe); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "Enabled radar detection on channel %d\n", + chan->ic_freq); + dfs->dur_multiplier = + is_fastclk ? DFS_FAST_CLOCK_MULTIPLIER : DFS_NO_FAST_CLOCK_MULTIPLIER; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, + "%s: duration multiplier is %d\n", __func__, dfs->dur_multiplier); + } else + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: No more radar states left\n", + __func__); + } + } + + return DFS_STATUS_SUCCESS; +} + +int +dfs_control(struct ieee80211com *ic, u_int id, + void *indata, u_int32_t insize, + void *outdata, u_int32_t *outsize) +{ + int error = 0; + struct ath_dfs_phyerr_param peout; + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + struct dfs_ioctl_params *dfsparams; + u_int32_t val=0; +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + struct dfsreq_nolinfo *nol; + u_int32_t *data = NULL; +#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ + int i; + + if (dfs == NULL) { + error = -EINVAL; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s DFS is null\n", __func__); + goto bad; + } + + + switch (id) { + case DFS_SET_THRESH: + if (insize < sizeof(struct dfs_ioctl_params) || !indata) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: insize=%d, expected=%zu bytes, indata=%p\n", + __func__, insize, sizeof(struct dfs_ioctl_params), + indata); + error = -EINVAL; + break; + } + dfsparams = (struct dfs_ioctl_params *) indata; + if (!dfs_set_thresholds(ic, DFS_PARAM_FIRPWR, dfsparams->dfs_firpwr)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_RRSSI, dfsparams->dfs_rrssi)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_HEIGHT, dfsparams->dfs_height)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_PRSSI, dfsparams->dfs_prssi)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_INBAND, dfsparams->dfs_inband)) + error = -EINVAL; + /* 5413 speicfic */ + if (!dfs_set_thresholds(ic, DFS_PARAM_RELPWR, dfsparams->dfs_relpwr)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_RELSTEP, dfsparams->dfs_relstep)) + error = -EINVAL; + if (!dfs_set_thresholds(ic, DFS_PARAM_MAXLEN, dfsparams->dfs_maxlen)) + error = -EINVAL; + break; + case DFS_GET_THRESH: + if (!outdata || !outsize || *outsize ath_dfs_stats.num_radar_detects; + break; + case DFS_DISABLE_DETECT: + dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; + dfs->ic->ic_dfs_state.ignore_dfs = 1; + DFS_PRINTK("%s enable detects, ignore_dfs %d\n", + __func__, + dfs->ic->ic_dfs_state.ignore_dfs); + break; + case DFS_ENABLE_DETECT: + dfs->dfs_proc_phyerr |= DFS_RADAR_EN; + dfs->ic->ic_dfs_state.ignore_dfs = 0; + DFS_PRINTK("%s enable detects, ignore_dfs %d\n", + __func__, + dfs->ic->ic_dfs_state.ignore_dfs); + break; + case DFS_DISABLE_FFT: + //UMACDFS: TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, false); + DFS_PRINTK("%s TODO disable FFT val=0x%x \n", __func__, val); + break; + case DFS_ENABLE_FFT: + //UMACDFS TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, true); + DFS_PRINTK("%s TODO enable FFT val=0x%x \n", __func__, val); + break; + case DFS_SET_DEBUG_LEVEL: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + dfs->dfs_debug_mask= *(u_int32_t *)indata; + DFS_PRINTK("%s debug level now = 0x%x \n", + __func__, + dfs->dfs_debug_mask); + if (dfs->dfs_debug_mask & ATH_DEBUG_DFS3) { + /* Enable debug Radar Event */ + dfs->dfs_event_log_on = 1; + } else { + dfs->dfs_event_log_on = 0; + } + break; + case DFS_SET_FALSE_RSSI_THRES: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + dfs->ath_dfs_false_rssi_thres= *(u_int32_t *)indata; + DFS_PRINTK("%s false RSSI threshold now = 0x%x \n", + __func__, + dfs->ath_dfs_false_rssi_thres); + break; + case DFS_SET_PEAK_MAG: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + dfs->ath_dfs_peak_mag= *(u_int32_t *)indata; + DFS_PRINTK("%s peak_mag now = 0x%x \n", + __func__, + dfs->ath_dfs_peak_mag); + break; + case DFS_IGNORE_CAC: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + if (*(u_int32_t *)indata) { + dfs->ic->ic_dfs_state.ignore_cac= 1; + } else { + dfs->ic->ic_dfs_state.ignore_cac= 0; + } + DFS_PRINTK("%s ignore cac = 0x%x \n", + __func__, + dfs->ic->ic_dfs_state.ignore_cac); + break; + case DFS_SET_NOL_TIMEOUT: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + if (*(int *)indata) { + dfs->ath_dfs_nol_timeout= *(int *)indata; + } else { + dfs->ath_dfs_nol_timeout= DFS_NOL_TIMEOUT_S; + } + DFS_PRINTK("%s nol timeout = %d sec \n", + __func__, + dfs->ath_dfs_nol_timeout); + break; +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + case DFS_MUTE_TIME: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + data = (u_int32_t *) indata; + dfs->ath_dfstesttime = *data; + dfs->ath_dfstesttime *= (1000); //convert sec into ms + break; + case DFS_GET_USENOL: + if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) { + error = -EINVAL; + break; + } + *outsize = sizeof(u_int32_t); + *((u_int32_t *)outdata) = dfs->dfs_rinfo.rn_use_nol; + + + + for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); i++) { + //DFS_DPRINTK(sc, ATH_DEBUG_DFS,"ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur); + + } + dfs->dfs_event_log_count = 0; + dfs->dfs_phyerr_count = 0; + dfs->dfs_phyerr_reject_count = 0; + dfs->dfs_phyerr_queued_count = 0; + dfs->dfs_phyerr_freq_min = 0x7fffffff; + dfs->dfs_phyerr_freq_max = 0; + break; + case DFS_SET_USENOL: + if (insize < sizeof(u_int32_t) || !indata) { + error = -EINVAL; + break; + } + dfs->dfs_rinfo.rn_use_nol = *(u_int32_t *)indata; + /* iwpriv markdfs in linux can do the same thing... */ + break; + case DFS_GET_NOL: + if (!outdata || !outsize || *outsize < sizeof(struct dfsreq_nolinfo)) { + error = -EINVAL; + break; + } + *outsize = sizeof(struct dfsreq_nolinfo); + nol = (struct dfsreq_nolinfo *)outdata; + dfs_get_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, &nol->ic_nchans); + dfs_print_nol(dfs); + break; + case DFS_SET_NOL: + if (insize < sizeof(struct dfsreq_nolinfo) || !indata) { + error = -EINVAL; + break; + } + nol = (struct dfsreq_nolinfo *) indata; + dfs_set_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, nol->ic_nchans); + break; + + case DFS_SHOW_NOL: + dfs_print_nol(dfs); + break; + case DFS_BANGRADAR: + #if 0 //MERGE_TBD + if(sc->sc_nostabeacons) + { + printk("No radar detection Enabled \n"); + break; + } +#endif + dfs->dfs_bangradar = 1; + dfs->ath_radar_tasksched = 1; + OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0); + break; +#endif /* ATH_DFS_RADAR_DETECTION_ONLY */ + default: + error = -EINVAL; + } +bad: + return error; +} +int +dfs_set_thresholds(struct ieee80211com *ic, const u_int32_t threshtype, + const u_int32_t value) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + int16_t chanindex; + struct dfs_state *rs; + struct ath_dfs_phyerr_param pe; + int is_fastclk = 0; /* XXX throw-away */ + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n", + __func__); + return 0; + } + + chanindex = dfs->dfs_curchan_radindex; + if ((chanindex <0) || (chanindex >= DFS_NUM_RADAR_STATES)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n", + __func__, + chanindex, + DFS_NUM_RADAR_STATES); + return 0; + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: threshtype=%d, value=%d\n", __func__, threshtype, value); + + ath_dfs_phyerr_init_noval(&pe); + + rs = &(dfs->dfs_radar[chanindex]); + switch (threshtype) { + case DFS_PARAM_FIRPWR: + rs->rs_param.pe_firpwr = (int32_t) value; + pe.pe_firpwr = value; + break; + case DFS_PARAM_RRSSI: + rs->rs_param.pe_rrssi = value; + pe.pe_rrssi = value; + break; + case DFS_PARAM_HEIGHT: + rs->rs_param.pe_height = value; + pe.pe_height = value; + break; + case DFS_PARAM_PRSSI: + rs->rs_param.pe_prssi = value; + pe.pe_prssi = value; + break; + case DFS_PARAM_INBAND: + rs->rs_param.pe_inband = value; + pe.pe_inband = value; + break; + /* 5413 specific */ + case DFS_PARAM_RELPWR: + rs->rs_param.pe_relpwr = value; + pe.pe_relpwr = value; + break; + case DFS_PARAM_RELSTEP: + rs->rs_param.pe_relstep = value; + pe.pe_relstep = value; + break; + case DFS_PARAM_MAXLEN: + rs->rs_param.pe_maxlen = value; + pe.pe_maxlen = value; + break; + default: + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: unknown threshtype (%d)\n", + __func__, + threshtype); + break; + } + + /* + * The driver layer dfs_enable routine is tasked with translating + * values from the global format to the per-device (HAL, offload) + * format. + */ + ic->ic_dfs_enable(ic, &is_fastclk, &pe); + return 1; +} + +int +dfs_get_thresholds(struct ieee80211com *ic, struct ath_dfs_phyerr_param *param) +{ + //UMACDFS : TODO:ath_hal_getdfsthresh(sc->sc_ah, param); + + OS_MEMZERO(param, sizeof(*param)); + + (void) ic->ic_dfs_get_thresholds(ic, param); + + return 1; +} + +u_int16_t dfs_usenol(struct ieee80211com *ic) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + return dfs ? (u_int16_t) dfs->dfs_rinfo.rn_use_nol : 0; +} + +u_int16_t dfs_isdfsregdomain(struct ieee80211com *ic) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + return dfs ? dfs->dfsdomain : 0; +} + +#endif /* ATH_UPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_bindetects.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_bindetects.c new file mode 100644 index 0000000000000..1c1b903e6e857 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_bindetects.c @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_bindetects.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +/*TO DO DFS removing +#include +*/ +#ifdef ATH_SUPPORT_DFS + +int +dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf, u_int32_t dur, int ext_chan_flag) +{ + struct dfs_pulseline *pl = dfs->pulses; + int i, n, refpri, primargin, numpulses=0; + u_int64_t start_ts, end_ts, event_ts, prev_event_ts, next_event_ts, window_start, window_end; + u_int32_t index, next_index, deltadur; + + /* For fixed pattern types, rf->rf_patterntype=1*/ + primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1)); + + refpri = (rf->rf_minpri + rf->rf_maxpri)/2; + index = pl->pl_lastelem; + end_ts = pl->pl_elems[index].p_time; + start_ts = end_ts - (refpri*rf->rf_numpulses); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, + "lastelem ts=%llu start_ts=%llu, end_ts=%llu\n", + (unsigned long long) pl->pl_elems[index].p_time, + (unsigned long long) start_ts, + (unsigned long long) end_ts); + + /* find the index of first element in our window of interest */ + for(i=0;ipl_numelems;i++) { + index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK; + if(pl->pl_elems[index].p_time >= start_ts ) + continue; + else { + index = (index) & DFS_MAX_PULSE_BUFFER_MASK; + break; + } + } + for (n=0;n<=rf->rf_numpulses; n++) { + window_start = (start_ts + (refpri*n))-(primargin+n); + window_end = window_start + 2*(primargin+n); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "window_start %u window_end %u \n", + (u_int32_t)window_start, (u_int32_t)window_end); + for(i=0;ipl_numelems;i++) { + prev_event_ts = pl->pl_elems[index].p_time; + index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK; + event_ts = pl->pl_elems[index].p_time; + next_index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK; + next_event_ts = pl->pl_elems[next_index].p_time; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "ts %u \n", (u_int32_t)event_ts); + if( (event_ts <= window_end) && (event_ts >= window_start)){ + deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur); + if( (pl->pl_elems[index].p_dur == 1) || + ((dur != 1) && (deltadur <= 2))) { + numpulses++; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "numpulses %u \n", numpulses); + break; + } + } + else if( event_ts > window_end) { + index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK; + break; + } + else if( event_ts == prev_event_ts) { + if( ((next_event_ts - event_ts) > refpri) || + ((next_event_ts - event_ts) == 0)) { + deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur); + if( (pl->pl_elems[index].p_dur == 1) || + ((pl->pl_elems[index].p_dur != 1) && (deltadur <= 2))) { + numpulses++; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "zero PRI: numpulses %u \n", numpulses); + break; + } + } + } + } + } + if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n", __func__, rf->rf_pulseid, numpulses, rf->rf_threshold); + return 1; + } + else + return 0; +} + +void +dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf, struct dfs_event *re, + u_int32_t deltaT, u_int64_t this_ts) +{ + u_int32_t index,n, window; + struct dfs_delayline *dl; + + dl = &rf->rf_dl; + /* Circular buffer of size 2^n */ + index = (dl->dl_lastelem + 1) & DFS_MAX_DL_MASK; + //if ((dl->dl_numelems+1) == DFS_MAX_DL_SIZE) + if ((dl->dl_numelems) == DFS_MAX_DL_SIZE) + dl->dl_firstelem = (dl->dl_firstelem + 1) & DFS_MAX_DL_MASK; + else + dl->dl_numelems++; + dl->dl_lastelem = index; + dl->dl_elems[index].de_time = deltaT; + dl->dl_elems[index].de_ts = this_ts; + window = deltaT; + dl->dl_elems[index].de_dur = re->re_dur; + dl->dl_elems[index].de_rssi = re->re_rssi; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "%s: adding: filter id %d, dur=%d, rssi=%d, ts=%llu\n", + __func__, + rf->rf_pulseid, + re->re_dur, + re->re_rssi, + (unsigned long long int) this_ts); + + for (n=0;ndl_numelems-1; n++) { + index = (index-1) & DFS_MAX_DL_MASK; + /* + * calculate window based on full time stamp instead of deltaT + * deltaT (de_time) may result in incorrect window value + */ + window = (u_int32_t) (this_ts - dl->dl_elems[index].de_ts); + + if (window > rf->rf_filterlen) { + dl->dl_firstelem = (index+1) & DFS_MAX_DL_MASK; + dl->dl_numelems = n+1; + } + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "dl firstElem = %d lastElem = %d\n",dl->dl_firstelem, + dl->dl_lastelem); +} + + +int +dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf, u_int32_t deltaT, + u_int32_t width, int ext_chan_flag) +{ + u_int32_t refpri, refdur, searchpri, deltapri,deltapri_2,deltapri_3, averagerefpri; + u_int32_t n, i, primargin, durmargin, highscore, highscoreindex; + int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0; + struct dfs_delayline *dl; + u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff; + int numpulses=0; + int lowprichk=3, pri_match=0; + + dl = &rf->rf_dl; + if( dl->dl_numelems < (rf->rf_threshold-1)) { + return 0; + } + if( deltaT > rf->rf_filterlen) + return 0; + + primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1)); + + + if(rf->rf_maxdur < 10) { + durmargin = 4; + } + else { + durmargin = 6; + } + + if( rf->rf_patterntype == 1 ){ + found = dfs_bin_fixedpattern_check(dfs, rf, width, ext_chan_flag); + if(found) { + dl->dl_numelems = 0; + } + return found; + } + + OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE); + /* find out the lowest pri */ + for (n=0;ndl_numelems; n++) { + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refpri = dl->dl_elems[delayindex].de_time; + if( refpri == 0) + continue; + else if(refpri < lowpri) { + lowpri = dl->dl_elems[delayindex].de_time; + lowpriindex = n; + } + } + /* find out the each delay element's pri score */ + for (n=0;ndl_numelems; n++) { + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refpri = dl->dl_elems[delayindex].de_time; + if( refpri == 0) + continue; + if (refpri < rf->rf_maxpri) { // use only valid PRI range for high score + for (i=0;idl_numelems; i++) { + dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; + searchpri = dl->dl_elems[dindex].de_time; + deltapri = DFS_DIFF(searchpri, refpri); + deltapri_2 = DFS_DIFF(searchpri, 2*refpri); + deltapri_3 = DFS_DIFF(searchpri, 3*refpri); + if (rf->rf_ignore_pri_window==2) { + pri_match = ((deltapri < primargin) || (deltapri_2 < primargin) || (deltapri_3 < primargin)); + } else { + pri_match = (deltapri < primargin); + } + + if (pri_match) + score[n]++; + } + } else { + score[n] = 0; + } + if( score[n] > rf->rf_threshold) { + /* we got the most possible candidate, + * no need to continue further */ + break; + } + } + /* find out the high scorer */ + highscore = 0; + highscoreindex = 0; + for (n=0;ndl_numelems; n++) { + if( score[n] > highscore) { + highscore = score[n]; + highscoreindex = n; + } + else if( score[n] == highscore ) { + /*more than one pri has highscore take the least pri */ + delayindex = (dl->dl_firstelem + highscoreindex) & DFS_MAX_DL_MASK; + dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + if( dl->dl_elems[dindex].de_time <= + dl->dl_elems[delayindex].de_time ) { + highscoreindex = n; + } + } + } + /* find the average pri of pulses around the pri of highscore or + * the pulses around the lowest pri */ + if (rf->rf_ignore_pri_window > 0) { + lowprichk = (rf->rf_threshold >> 1)+1; + } else { + lowprichk = 3; + } + + if( highscore < lowprichk) { + scoreindex = lowpriindex; + } + else { + scoreindex = highscoreindex; + } + /* We got the possible pri, save its parameters as reference */ + delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK; + refdur = dl->dl_elems[delayindex].de_dur; + refpri = dl->dl_elems[delayindex].de_time; + averagerefpri = 0; + + if (rf->rf_fixed_pri_radar_pulse) { + refpri = (rf->rf_minpri + rf->rf_maxpri)/2; + } + + numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri, + refdur, ext_chan_flag, refpri); + if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) { + found = 1; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refdur=%d refpri=%d primargin=%d\n", ext_chan_flag, rf->rf_pulseid, numpulses,rf->rf_threshold, refdur, refpri, primargin); + dfs_print_delayline(dfs, &rf->rf_dl); + dfs_print_filter(dfs, rf); + } + return found; +} + +int +dfs_bin_pri_check(struct ath_dfs *dfs, struct dfs_filter *rf, + struct dfs_delayline *dl, u_int32_t score, u_int32_t refpri, + u_int32_t refdur, int ext_chan_flag, int fundamentalpri) +{ + u_int32_t searchpri, searchdur, searchrssi, deltapri = 0,deltapri1 = 0, deltapri2 = 0, deltadur, averagerefpri=0,MatchCount = 0; + u_int32_t delta_ts_variance, delta_time_stamps, prev_good_timestamp=0; + int delayindex, dindex; + u_int32_t i, j=0, primargin, durmargin, highscore=score, highscoreindex=0; + int numpulses=1; //first pulse in the burst is most likely being filtered out based on maxfilterlen + int priscorechk=1,numpulsetochk=2,primatch=0; + + //Use the adjusted PRI margin to reduce false alarms + /* For non fixed pattern types, rf->rf_patterntype=0*/ + primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1)); + + if ( (refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri) ) { + numpulses = 0; + return numpulses; + } + + + if(rf->rf_maxdur < 10) { + durmargin = 4; + } else { + durmargin = 6; + } + + if ((!rf->rf_fixed_pri_radar_pulse)) { + if (rf->rf_ignore_pri_window==1) { + priscorechk = (rf->rf_threshold >> 1); + } else { + priscorechk = 1; + } + + MatchCount = 0; + if( score > priscorechk) { + for (i=0;idl_numelems; i++) { + dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; + searchpri = dl->dl_elems[dindex].de_time; + deltapri = DFS_DIFF(searchpri, refpri); + if( deltapri < primargin) { + averagerefpri += searchpri; + MatchCount++; + } + } + if (rf->rf_patterntype != 2) { + if (MatchCount > 0) + refpri = (averagerefpri/MatchCount); //average + } else { + refpri = (averagerefpri/score); + } + } + } + /* Note: Following primultiple calculation should be done once per filter + * during initialization stage (dfs_attach) and stored in its array + * atleast for fixed frequency types like FCC Bin1 to save some CPU cycles. + * multiplication, devide operators in the following code are left as it is + * for readability hoping the complier will use left/right shifts wherever possible + */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "refpri = %d high score = %d index = %d numpulses = %d\n", + refpri, highscore, highscoreindex, numpulses); + /* Count the other delay elements that have pri and dur with in the + * acceptable range from the reference one */ + for (i=0; idl_numelems; i++) { + delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; + searchpri = dl->dl_elems[delayindex].de_time; + if( searchpri == 0) { + /* This events PRI is zero, take it as a + * valid pulse but decrement next event's PRI by refpri + */ + dindex = (delayindex+1)& DFS_MAX_DL_MASK; + dl->dl_elems[dindex].de_time -= refpri; + searchpri = refpri; + } + searchdur = dl->dl_elems[delayindex].de_dur; + searchrssi = dl->dl_elems[delayindex].de_rssi; + deltadur = DFS_DIFF(searchdur, refdur); + deltapri = DFS_DIFF(searchpri, refpri); + + //deltapri3 = DFS_DIFF(searchpri, 3 * refpri); + primatch=0; + + if ((rf->rf_ignore_pri_window>0) && (rf->rf_patterntype!=2)) { + for (j=0;jrf_numpulses;j++){ + deltapri1 = DFS_DIFF(searchpri, (j+1)*refpri); + if (deltapri1 < (2*primargin)) { + primatch = 1; + break; + } + } + } else { + if (( deltapri1 < primargin) || ( deltapri2 < primargin)) { + primatch = 1; + } + } + + if ( primatch && ( deltadur < durmargin) ) { + if ( (numpulses == 1) ) { + numpulses++; + } else { + delta_time_stamps = dl->dl_elems[delayindex].de_ts - prev_good_timestamp; + if ((rf->rf_ignore_pri_window>0)) { + numpulsetochk = rf->rf_numpulses; + + if ((rf->rf_patterntype==2) && (fundamentalprirf_ignore_pri_window>0) { + break; + } + } + } + } + prev_good_timestamp = dl->dl_elems[delayindex].de_ts; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d\n", + rf->rf_minpri, rf->rf_maxpri, searchpri, i, numpulses, deltapri, j); + } + + } + return numpulses; +} +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_debug.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_debug.c new file mode 100644 index 0000000000000..2590f6eec10d0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_debug.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_debug.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifdef ATH_SUPPORT_DFS + +void +dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl) +{ + int i=0,index; + struct dfs_delayelem *de; + + index = dl->dl_lastelem; + for (i=0; idl_numelems; i++) { + de = &dl->dl_elems[index]; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "Elem %d: ts = %u (0x%x) dur=%u\n",i, + de->de_time, de->de_time, de->de_dur); + index = (index - 1)& DFS_MAX_DL_MASK; + } +} +void +dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf) +{ + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "filterID[%d] rf_numpulses=%u; rf->rf_minpri=%u; " + "rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; " + "rf->rf_mindur=%u; rf->rf_maxdur=%u\n", + rf->rf_pulseid, + rf->rf_numpulses, + rf->rf_minpri, + rf->rf_maxpri, + rf->rf_threshold, + rf->rf_filterlen, + rf->rf_mindur, + rf->rf_maxdur); +} + +void +dfs_print_filters(struct ath_dfs *dfs) +{ + struct dfs_filtertype *ft = NULL; + struct dfs_filter *rf; + int i,j; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__); + return; + } + for (i=0; idfs_radarf[i] != NULL) { + ft = dfs->dfs_radarf[i]; + if((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) || (!ft->ft_numfilters)) + continue; + DFS_PRINTK("===========ft->ft_numfilters=%u===========\n", ft->ft_numfilters); + for (j=0; jft_numfilters; j++) { + rf = &(ft->ft_filters[j]); + DFS_PRINTK("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",j, rf->rf_pulseid, + rf->rf_numpulses, rf->rf_minpri, rf->rf_maxpri, rf->rf_threshold, rf->rf_filterlen, rf->rf_mindur, rf->rf_maxdur); + } + } + } +} + +void dfs_print_activity(struct ath_dfs *dfs) +{ + int chan_busy=0, ext_chan_busy=0; + u_int32_t rxclear=0, rxframe=0, txframe=0, cycles=0; + + cycles = dfs->ic->ic_get_mib_cycle_counts_pct(dfs->ic, &rxclear, &rxframe, &txframe); + chan_busy = cycles; + + ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS,"cycles=%d rxclear=%d rxframe=%d" + " txframe=%d extchanbusy=%d\n", cycles, rxclear, + rxframe, txframe, ext_chan_busy); + return; +} + +/* + * XXX migrate this to use ath_dfs as the arg, not ieee80211com! + */ +#ifndef ATH_DFS_RADAR_DETECTION_ONLY +OS_TIMER_FUNC(dfs_debug_timeout) +{ + struct ieee80211com *ic; + struct ath_dfs* dfs; + + OS_GET_TIMER_ARG(ic, struct ieee80211com *); + + dfs = (struct ath_dfs *)ic->ic_dfs; + + dfs_print_activity(dfs); + + OS_SET_TIMER(&dfs->ath_dfs_debug_timer, DFS_DEBUG_TIMEOUT_MS); +} +#endif + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c new file mode 100644 index 0000000000000..e41e49f0200df --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c @@ -0,0 +1,828 @@ +/* + * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_fcc_bin5.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifdef ATH_SUPPORT_DFS + +/* + * Reject the pulse if: + * + It's outside the RSSI threshold; + * + It's outside the pulse duration; + * + It's been verified by HW/SW chirp checking + * and neither of those found a chirp. + */ +int +dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re, + struct dfs_bin5radars *br) +{ + int b5_rssithresh = br->br_pulse.b5_rssithresh; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_PULSE, + "%s: re_dur=%d, rssi=%d, check_chirp=%d, " + "hw_chirp=%d, sw_chirp=%d\n", + __func__, + (int) re->re_dur, + (int) re->re_rssi, + !! (re->re_flags & DFS_EVENT_CHECKCHIRP), + !! (re->re_flags & DFS_EVENT_HW_CHIRP), + !! (re->re_flags & DFS_EVENT_SW_CHIRP)); + + /* + * If the sw/hw chirp detection says to fail the pulse, + * do so. + */ + if (DFS_EVENT_NOTCHIRP(re)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "%s: rejecting chirp: ts=%llu, dur=%d, rssi=%d " + "checkchirp=%d, hwchirp=%d, swchirp=%d\n", + __func__, + (unsigned long long) re->re_full_ts, + (int) re->re_dur, + (int) re->re_rssi, + !! (re->re_flags & DFS_EVENT_CHECKCHIRP), + !! (re->re_flags & DFS_EVENT_HW_CHIRP), + !! (re->re_flags & DFS_EVENT_SW_CHIRP)); + return (0); + } + + /* Adjust the filter threshold for rssi in non TURBO mode */ + if( ! (dfs->ic->ic_curchan->ic_flags & CHANNEL_TURBO)) + b5_rssithresh += br->br_pulse.b5_rssimargin; + + /* + * Check if the pulse is within duration and rssi + * thresholds. + */ + if ((re->re_dur >= br->br_pulse.b5_mindur) && + (re->re_dur <= br->br_pulse.b5_maxdur) && + (re->re_rssi >= b5_rssithresh)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "%s: dur=%d, rssi=%d - adding!\n", + __func__, (int) re->re_dur, (int) re->re_rssi); + return (1); + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "%s: too low to be Bin5 pulse tsf=%llu, dur=%d, rssi=%d\n", + __func__, + (unsigned long long) re->re_full_ts, + (int) re->re_dur, + (int) re->re_rssi); + + return (0); +} + + +int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br, + struct dfs_event *re, u_int64_t thists) +{ + u_int32_t index,stop; + u_int64_t tsDelta; + + /* Check if this pulse is a valid pulse in terms of repetition, + * if not, return without adding it to the queue. + * PRI : Pulse Repitetion Interval + * BRI : Burst Repitetion Interval */ + if( br->br_numelems != 0){ + index = br->br_lastelem; + tsDelta = thists - br->br_elems[index].be_ts; + if( (tsDelta < DFS_BIN5_PRI_LOWER_LIMIT) || + ( (tsDelta > DFS_BIN5_PRI_HIGHER_LIMIT) && + (tsDelta < DFS_BIN5_BRI_LOWER_LIMIT))) { + return 0; + } + } + /* Circular buffer of size 2^n */ + index = (br->br_lastelem +1) & DFS_MAX_B5_MASK; + br->br_lastelem = index; + if (br->br_numelems == DFS_MAX_B5_SIZE) + br->br_firstelem = (br->br_firstelem+1)&DFS_MAX_B5_MASK; + else + br->br_numelems++; + br->br_elems[index].be_ts = thists; + br->br_elems[index].be_rssi = re->re_rssi; + br->br_elems[index].be_dur = re->re_dur; /* please note that this is in u-sec */ + stop = 0; + index = br->br_firstelem; + while ((!stop) && (br->br_numelems-1) > 0) { + if ((thists - br->br_elems[index].be_ts) > + ((u_int64_t) br->br_pulse.b5_timewindow)) { + br->br_numelems--; + br->br_firstelem = (br->br_firstelem +1) & DFS_MAX_B5_MASK; + index = br->br_firstelem; + } else + stop = 1; + } + return 1; +} + +/* + * If the dfs structure is NULL (which should be illegal if everyting is working + * properly, then signify that a bin5 radar was found + */ + +int +dfs_bin5_check(struct ath_dfs *dfs) +{ + struct dfs_bin5radars *br; + int index[DFS_MAX_B5_SIZE]; + u_int32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0, rssi_diff = 0, width_diff = 0, bursts= 0; + u_int32_t total_diff=0, average_diff=0, total_width=0, average_width=0, numevents=0; + u_int64_t pri; + + + if (dfs == NULL) { + DFS_PRINTK("%s: ic_dfs is NULL\n", __func__); + return 1; + } + for (n=0;ndfs_rinfo.rn_numbin5radars; n++) { + br = &(dfs->dfs_b5radars[n]); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "Num elems = %d\n", br->br_numelems); + + /* find a valid bin 5 pulse and use it as reference */ + for(i1=0;i1 < br->br_numelems; i1++) { + this = ((br->br_firstelem +i1) & DFS_MAX_B5_MASK); + if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) && + (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) { + break; + } + } + + prev = this; + for(i = i1 + 1; i < br->br_numelems; i++){ + this = ((br->br_firstelem +i) & DFS_MAX_B5_MASK); + + /* first make sure it is a bin 5 pulse by checking the duration */ + if ((br->br_elems[this].be_dur < MIN_BIN5_DUR_MICROSEC) || (br->br_elems[this].be_dur > MAX_BIN5_DUR_MICROSEC)) { + continue; + } + + /* Rule 1: 1000 <= PRI <= 2000 + some margin */ + if( br->br_elems[this].be_ts >= br->br_elems[prev].be_ts ) { + pri = br->br_elems[this].be_ts - br->br_elems[prev].be_ts; + } + else {//roll over case + //pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts; + pri = br->br_elems[this].be_ts; + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + " pri=%llu this.ts=%llu this.dur=%d this.rssi=%d prev.ts=%llu\n", + (unsigned long long)pri, + (unsigned long long)br->br_elems[this].be_ts, + (int) br->br_elems[this].be_dur, + (int) br->br_elems[this].be_rssi, + (unsigned long long)br->br_elems[prev].be_ts); + if(( (pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) { //pri: pulse repitition interval in us + /* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */ + if( br->br_elems[this].be_dur >= br->br_elems[prev].be_dur) { + width_diff = br->br_elems[this].be_dur - br->br_elems[prev].be_dur; + } + else { + width_diff = br->br_elems[prev].be_dur - br->br_elems[this].be_dur; + } + if( width_diff <= DFS_BIN5_WIDTH_MARGIN ) { + /* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */ + if( br->br_elems[this].be_rssi >= br->br_elems[prev].be_rssi) { + rssi_diff = br->br_elems[this].be_rssi - br->br_elems[prev].be_rssi; + } + else { + rssi_diff = br->br_elems[prev].be_rssi - br->br_elems[this].be_rssi; + } + if( rssi_diff <= DFS_BIN5_RSSI_MARGIN ) { + bursts++; + /* Save the indexes of this pair for later width variance check */ + if( numevents >= 2 ) { + /* make sure the event is not duplicated, + * possible in a 3 pulse burst */ + if( index[numevents-1] != prev) { + index[numevents++] = prev; + } + } + else { + index[numevents++] = prev; } + index[numevents++] = this; + } else { + DFS_DPRINTK(dfs, + ATH_DEBUG_DFS_BIN5, + "%s %d Bin5 rssi_diff=%d\n", + __func__, __LINE__, rssi_diff); + } + } else { + DFS_DPRINTK(dfs, + ATH_DEBUG_DFS_BIN5, + "%s %d Bin5 width_diff=%d\n", + __func__, __LINE__, + width_diff); + } + } else if ((pri >= DFS_BIN5_BRI_LOWER_LIMIT) && + (pri <= DFS_BIN5_BRI_UPPER_LIMIT)) { + // check pulse width to make sure it is in range of bin 5 + //if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) && (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) { + bursts++; + //} + } else{ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "%s %d Bin5 PRI check fail pri=%llu\n", + __func__, __LINE__, (unsigned long long)pri); + } + prev = this; + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u\n", bursts, numevents); + if ( bursts >= br->br_pulse.b5_threshold) { + if( (br->br_elems[br->br_lastelem].be_ts - br->br_elems[br->br_firstelem].be_ts) < 3000000 ) { + return 0; + } + else { + /* + * don't do this check since not all the cases have this kind of burst width variation. + * + for (i=0; ibr_elems[index[i]].be_dur; + } + average_width = total_width/bursts; + for (i=0; ibr_elems[index[i]].be_dur, average_width); + } + average_diff = total_diff/bursts; + if( average_diff > DFS_BIN5_WIDTH_MARGIN ) { + return 1; + } else { + + DFS_DPRINTK(ic, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff); + + } + */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff); + DFS_PRINTK("bin 5 radar detected, bursts=%d\n", bursts); + return 1; + } + } + } + + return 0; +} + + +/* Return TRUE if chirping pulse, FALSE if not. + Decision is made based on processing the FFT data included with the PHY error. + Calculate the slope using the maximum bin index reported in the FFT data. + Calculate slope between FFT packet 0 and packet n-1. Also calculate slope between + packet 1 and packet n. + If a pulse is chirping, a slope of 5 and greater is seen. + Non-chirping pulses have slopes of 0, 1, 2 or 3. +*/ + +/* + * Chirp detection for Sowl/Howl. + */ +static int +dfs_check_chirping_sowl(struct ath_dfs *dfs, void *buf, + u_int16_t datalen, int is_ctl, int is_ext, int *slope, int *is_dc) +{ +#define FFT_LEN 70 +#define FFT_LOWER_BIN_MAX_INDEX_BYTE 66 +#define FFT_UPPER_BIN_MAX_INDEX_BYTE 69 +#define MIN_CHIRPING_SLOPE 4 + int is_chirp=0; + int p, num_fft_packets=0; + int ctl_slope=0, ext_slope=0; + int ctl_high0, ctl_low0, ctl_slope0=0, ext_high0, ext_low0, ext_slope0=0; + int ctl_high1, ctl_low1, ctl_slope1=0, ext_high1, ext_low1, ext_slope1=0; + u_int8_t *fft_data_ptr; + + *slope = 0; + *is_dc = 0; + + num_fft_packets = datalen / FFT_LEN; + fft_data_ptr = ((u_int8_t*)buf); + + /* DEBUG - Print relevant portions of the FFT data*/ + for (p=0; p < num_fft_packets; p++) { + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "fft_data_ptr=0x%p\t", fft_data_ptr); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "[66]=%d [69]=%d\n", + *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2, + *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2); + + fft_data_ptr += FFT_LEN; + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "datalen=%d num_fft_packets=%d\n", datalen, num_fft_packets); + + /* There is not enough FFT data to figure out whether the pulse is chirping or not*/ + if (num_fft_packets < 4) { + return 0; + } + + fft_data_ptr = ((u_int8_t*)buf); + + if (is_ctl) { + + fft_data_ptr = ((u_int8_t*)buf); + ctl_low0 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; + fft_data_ptr += FFT_LEN; + ctl_low1 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; + + // last packet with first packet + fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 1)); + ctl_high1 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; + + // second last packet with 0th packet + fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 2)); + ctl_high0 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2; + + ctl_slope0 = ctl_high0 - ctl_low0; + if (ctl_slope0 < 0) ctl_slope0 *= (-1); + + ctl_slope1 = ctl_high1 - ctl_low1; + if (ctl_slope1 < 0) ctl_slope1 *= (-1); + + ctl_slope = ((ctl_slope0 > ctl_slope1) ? ctl_slope0: ctl_slope1); + *slope = ctl_slope; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "ctl_slope0=%d ctl_slope1=%d ctl_slope=%d\n", + ctl_slope0, ctl_slope1, ctl_slope); + + } else if (is_ext) { + + fft_data_ptr = ((u_int8_t*)buf); + ext_low0 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; + + fft_data_ptr += FFT_LEN; + ext_low1 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; + + fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 1)); + ext_high1 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; + fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 2)); + ext_high0 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2; + + ext_slope0 = ext_high0 - ext_low0; + if (ext_slope0 < 0) ext_slope0 *= (-1); + + ext_slope1 = ext_high1 - ext_low1; + if (ext_slope1 < 0) ext_slope1 *= (-1); + + ext_slope = ((ext_slope0 > ext_slope1) ? ext_slope0: ext_slope1); + *slope = ext_slope; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_BIN5, + "ext_slope0=%d ext_slope1=%d ext_slope=%d\n", + ext_slope0, ext_slope1, ext_slope); + } else + return 0; + + if ((ctl_slope >= MIN_CHIRPING_SLOPE) || (ext_slope >= MIN_CHIRPING_SLOPE)) { + is_chirp = 1; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5 | ATH_DEBUG_DFS_BIN5_FFT | + ATH_DEBUG_DFS_PHYERR_SUM, + "is_chirp=%d is_dc=%d\n", is_chirp, *is_dc); + } + return is_chirp; + +#undef FFT_LEN +#undef FFT_LOWER_BIN_MAX_INDEX_BYTE +#undef FFT_UPPER_BIN_MAX_INDEX_BYTE +#undef MIN_CHIRPING_SLOPE +} + +/* + * Merlin (and Osprey, etc) chirp radar chirp detection. + */ +static int +dfs_check_chirping_merlin(struct ath_dfs *dfs, void *buf, u_int16_t datalen, + int is_ctl, int is_ext, int *slope, int *is_dc) +{ +#define ABS_DIFF(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x) +#define ABS(_x) ((int)_x > 0 ? (int)_x : - (int)_x) + +#define DELTA_STEP 1 /* This should be between 1 and 3. Default is 1. */ +#define NUM_DIFFS 3 /* Number of Diffs to compute. valid range is 2-4 */ +#define MAX_DIFF 2 /* Threshold for difference of delta peaks */ +#define BIN_COUNT_MAX 6 /* Max. number of strong bins for narrow band */ + + +/* + * Dynamic 20/40 mode FFT packet format related definition + */ + +#define NUM_FFT_BYTES_HT40 70 +#define NUM_BIN_BYTES_HT40 64 +#define NUM_SUBCHAN_BINS_HT40 64 +#define LOWER_INDEX_BYTE_HT40 66 +#define UPPER_INDEX_BYTE_HT40 69 +#define LOWER_WEIGHT_BYTE_HT40 64 +#define UPPER_WEIGHT_BYTE_HT40 67 +#define LOWER_MAG_BYTE_HT40 65 +#define UPPER_MAG_BYTE_HT40 68 + +/* + * Static 20 mode FFT packet format related definition + */ + +#define NUM_FFT_BYTES_HT20 31 +#define NUM_BIN_BYTES_HT20 28 +#define NUM_SUBCHAN_BINS_HT20 56 +#define LOWER_INDEX_BYTE_HT20 30 +#define UPPER_INDEX_BYTE_HT20 30 +#define LOWER_WEIGHT_BYTE_HT20 28 +#define UPPER_WEIGHT_BYTE_HT20 28 +#define LOWER_MAG_BYTE_HT20 29 +#define UPPER_MAG_BYTE_HT20 29 + + int num_fft_packets; /* number of FFT packets reported to software */ + int num_fft_bytes; + int num_bin_bytes; + int num_subchan_bins; + int lower_index_byte; + int upper_index_byte; + int lower_weight_byte; + int upper_weight_byte; + int lower_mag_byte; + int upper_mag_byte; + + int max_index_lower [DELTA_STEP + NUM_DIFFS]; + int max_index_upper [DELTA_STEP + NUM_DIFFS]; + int max_mag_lower [DELTA_STEP + NUM_DIFFS]; + int max_mag_upper [DELTA_STEP + NUM_DIFFS]; + int bin_wt_lower [DELTA_STEP + NUM_DIFFS]; + int bin_wt_upper [DELTA_STEP + NUM_DIFFS]; + int max_mag_sel [DELTA_STEP + NUM_DIFFS]; + int max_mag [DELTA_STEP + NUM_DIFFS]; + int max_index [DELTA_STEP + NUM_DIFFS]; + + + + int max_d[] = {10, 19, 28}; + int min_d[] = {1, 2, 3}; + + u_int8_t *ptr; /* pointer to FFT data */ + int i; + int fft_start; + int chirp_found; + int delta_peak[NUM_DIFFS]; + int j; + int bin_count; + int bw_mask; + int delta_diff; + int same_sign; + int temp; + + if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { + num_fft_bytes = NUM_FFT_BYTES_HT40; + num_bin_bytes = NUM_BIN_BYTES_HT40; + num_subchan_bins = NUM_SUBCHAN_BINS_HT40; + lower_index_byte = LOWER_INDEX_BYTE_HT40; + upper_index_byte = UPPER_INDEX_BYTE_HT40; + lower_weight_byte = LOWER_WEIGHT_BYTE_HT40; + upper_weight_byte = UPPER_WEIGHT_BYTE_HT40; + lower_mag_byte = LOWER_MAG_BYTE_HT40; + upper_mag_byte = UPPER_MAG_BYTE_HT40; + + /* if we are in HT40MINUS then swap primary and extension */ + if (IS_CHAN_HT40_MINUS(dfs->ic->ic_curchan)) { + temp = is_ctl; + is_ctl = is_ext; + is_ext = temp; + } + + } else { + num_fft_bytes = NUM_FFT_BYTES_HT20; + num_bin_bytes = NUM_BIN_BYTES_HT20; + num_subchan_bins = NUM_SUBCHAN_BINS_HT20; + lower_index_byte = LOWER_INDEX_BYTE_HT20; + upper_index_byte = UPPER_INDEX_BYTE_HT20; + lower_weight_byte = LOWER_WEIGHT_BYTE_HT20; + upper_weight_byte = UPPER_WEIGHT_BYTE_HT20; + lower_mag_byte = LOWER_MAG_BYTE_HT20; + upper_mag_byte = UPPER_MAG_BYTE_HT20; + } + + ptr = (u_int8_t*)buf; + /* + * sanity check for FFT buffer + */ + + if ((ptr == NULL) || (datalen == 0)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "%s: FFT buffer pointer is null or size is 0\n", __func__); + return 0; + } + + num_fft_packets = (datalen - 3) / num_fft_bytes; + if (num_fft_packets < (NUM_DIFFS + DELTA_STEP)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "datalen = %d, num_fft_packets = %d, too few packets... (exiting)\n", datalen, num_fft_packets); + return 0; + } + + if ((((datalen - 3) % num_fft_bytes) == 2) && (datalen > num_fft_bytes)) { + // FIXME !!! + ptr += 2; + datalen -= 2; + } + + for (i = 0; i < (NUM_DIFFS + DELTA_STEP); i++) { + fft_start = i * num_fft_bytes; + bin_wt_lower[i] = ptr[fft_start + lower_weight_byte] & 0x3f; + bin_wt_upper[i] = ptr[fft_start + upper_weight_byte] & 0x3f; + + max_index_lower[i] = ptr[fft_start + lower_index_byte] >> 2; + max_index_upper[i] = (ptr[fft_start + upper_index_byte] >> 2) + num_subchan_bins; + + if (!IS_CHAN_HT40(dfs->ic->ic_curchan)) { + /* + * for HT20 mode indices are 6 bit signed number + */ + max_index_lower[i] ^= 0x20; + max_index_upper[i] = 0; + } + /* + * Reconstruct the maximum magnitude for each sub-channel. Also select + * and flag the max overall magnitude between the two sub-channels. + */ + + max_mag_lower[i] = ((ptr[fft_start + lower_index_byte] & 0x03) << 8) + + ptr[fft_start + lower_mag_byte]; + max_mag_upper[i] = ((ptr[fft_start + upper_index_byte] & 0x03) << 8) + + ptr[fft_start + upper_mag_byte]; + bw_mask = ((bin_wt_lower[i] == 0) ? 0 : is_ctl) + + (((bin_wt_upper[i] == 0) ? 0 : is_ext) << 1); + + /* + * Limit the max bin based on channel bandwidth + * If the upper sub-channel max index is stuck at '1', the signal is dominated + * by residual DC (or carrier leak) and should be ignored. + */ + + if (bw_mask == 1) { + max_mag_sel[i] = 0; + max_mag[i] = max_mag_lower[i]; + max_index[i] = max_index_lower[i]; + } else if(bw_mask == 2) { + max_mag_sel[i] = 1; + max_mag[i] = max_mag_upper[i]; + max_index[i] = max_index_upper[i]; + } else if(max_index_upper[i] == num_subchan_bins) { + max_mag_sel[i] = 0; /* Ignore DC bin. */ + max_mag[i] = max_mag_lower[i]; + max_index[i] = max_index_lower[i]; + } else { + if (max_mag_upper[i] > max_mag_lower[i]) { + max_mag_sel[i] = 1; + max_mag[i] = max_mag_upper[i]; + max_index[i] = max_index_upper[i]; + } else { + max_mag_sel[i] = 0; + max_mag[i] = max_mag_lower[i]; + max_index[i] = max_index_lower[i]; + } + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "i=%d, max_index[i]=%d, max_index_lower[i]=%d, " + "max_index_upper[i]=%d\n", + i, max_index[i], max_index_lower[i], max_index_upper[i]); + } + + + + chirp_found = 1; + delta_diff = 0; + same_sign = 1; + + /* + delta_diff computation -- look for movement in peak. + make sure that the chirp direction (i.e. sign) is always the same, + i.e. sign of the two peaks should be same. + */ + for (i = 0; i < NUM_DIFFS; i++) { + delta_peak[i] = max_index[i + DELTA_STEP] - max_index[i]; + if (i > 0) { + delta_diff = delta_peak[i] - delta_peak[i-1]; + same_sign = !((delta_peak[i] & 0x80) ^ (delta_peak[i-1] & 0x80)); + } + chirp_found &= (ABS(delta_peak[i]) >= min_d[DELTA_STEP - 1]) && + (ABS(delta_peak[i]) <= max_d[DELTA_STEP - 1]) && + same_sign && + (ABS(delta_diff) <= MAX_DIFF); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "i=%d, delta_peak[i]=%d, delta_diff=%d\n", + i, delta_peak[i], delta_diff); + } + + + if (chirp_found) + { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "%s: CHIRPING_BEFORE_STRONGBIN_YES\n", __func__); + } else { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "%s: CHIRPING_BEFORE_STRONGBIN_NO\n", __func__); + } + + /* + Work around for potential hardware data corruption bug. Check for + wide band signal by counting strong bins indicated by bitmap flags. + This check is done if chirp_found is true. We do this as a final check + to weed out corrupt FFTs bytes. This looks expensive but in most cases it + will exit early. + */ + + for (i = 0; (i < (NUM_DIFFS + DELTA_STEP)) && (chirp_found == 1); i++) { + bin_count = 0; + /* point to the start of the 1st byte of the selected sub-channel. */ + fft_start = (i * num_fft_bytes) + (max_mag_sel[i] ? (num_subchan_bins >> 1) : 0); + for (j = 0; j < (num_subchan_bins >> 1); j++) + { + /* + * If either bin is flagged "strong", accumulate the bin_count. + * It's not accurate, but good enough... + */ + bin_count += (ptr[fft_start + j] & 0x88) ? 1 : 0; + } + chirp_found &= (bin_count > BIN_COUNT_MAX) ? 0 : 1; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, + "i=%d, computed bin_count=%d\n", i, bin_count); + } + + if (chirp_found) + { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM, + "%s: CHIRPING_YES\n", __func__); + } else { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM, + "%s: CHIRPING_NO\n", __func__); + } + return chirp_found; + +#undef ABS_DIFF +#undef ABS +#undef DELTA_STEP +#undef NUM_DIFFS +#undef MAX_DIFF +#undef BIN_COUNT_MAX + +#undef NUM_FFT_BYTES_HT40 +#undef NUM_BIN_BYTES_HT40 +#undef NUM_SUBCHAN_BINS_HT40 +#undef LOWER_INDEX_BYTE_HT40 +#undef UPPER_INDEX_BYTE_HT40 +#undef LOWER_WEIGHT_BYTE_HT40 +#undef UPPER_WEIGHT_BYTE_HT40 +#undef LOWER_MAG_BYTE_HT40 +#undef UPPER_MAG_BYTE_HT40 + +#undef NUM_FFT_BYTES_HT40 +#undef NUM_BIN_BYTES_HT40 +#undef NUM_SUBCHAN_BINS_HT40 +#undef LOWER_INDEX_BYTE_HT40 +#undef UPPER_INDEX_BYTE_HT40 +#undef LOWER_WEIGHT_BYTE_HT40 +#undef UPPER_WEIGHT_BYTE_HT40 +#undef LOWER_MAG_BYTE_HT40 +#undef UPPER_MAG_BYTE_HT40 +} + +int +dfs_check_chirping(struct ath_dfs *dfs, void *buf, + u_int16_t datalen, int is_ctl, int is_ext, int *slope, int *is_dc) +{ + + if (dfs->dfs_caps.ath_dfs_use_enhancement) + return dfs_check_chirping_merlin(dfs, buf, datalen, is_ctl, + is_ext, slope, is_dc); + else + return dfs_check_chirping_sowl(dfs, buf, datalen, is_ctl, + is_ext, slope, is_dc); +} + +u_int8_t +dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts, + u_int8_t old_dur) +{ + + /* + * Pulses may get split into 2 during chirping, this print is only + * to show that it happened, we do not handle this condition if we + * cannot detect the chirping. + */ + /* + * SPLIT pulses will have a time stamp difference of < 50 + */ + if (diff_ts < 50) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, + "%s SPLIT pulse diffTs=%u dur=%d (old_dur=%d)\n", + __func__, diff_ts, + dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur); + } + /* + * Check if this is the 2nd or 3rd pulse in the same burst, + * PRI will be between 1000 and 2000 us + */ + if (((diff_ts >= DFS_BIN5_PRI_LOWER_LIMIT) && + (diff_ts <= DFS_BIN5_PRI_HIGHER_LIMIT))) { + /* + * This pulse belongs to the same burst as the pulse before, + * so return the same random duration for it + */ + DFS_DPRINTK(dfs,ATH_DEBUG_DFS_BIN5, + "%s this pulse belongs to the same burst as before, give " + "it same dur=%d (old_dur=%d)\n", + __func__, dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur); + + return (dfs->dfs_rinfo.dfs_last_bin5_dur); + } + /* + * This pulse does not belong to this burst, return unchanged + * duration. + */ + return old_dur; +} + +/* + * Chirping pulses may get cut off at DC and report lower durations. + * + * This function will compute a suitable random duration for each pulse. + * Duration must be between 50 and 100 us, but remember that in + * ath_process_phyerr() which calls this function, we are dealing with the + * HW reported duration (unconverted). dfs_process_radarevent() will + * actually convert the duration into the correct value. + * + * XXX This function doesn't take into account whether the hardware + * is operating in 5GHz fast clock mode or not. + * + * XXX And this function doesn't take into account whether the hardware + * is peregrine or not. Grr. + */ +int +dfs_get_random_bin5_dur(struct ath_dfs *dfs, u_int64_t tstamp) +{ + u_int8_t new_dur=MIN_BIN5_DUR; + int range; + + get_random_bytes(&new_dur, sizeof(u_int8_t)); + + range = (MAX_BIN5_DUR - MIN_BIN5_DUR + 1); + + new_dur %= range; + + new_dur += MIN_BIN5_DUR; + + return new_dur; +} + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_init.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_init.c new file mode 100644 index 0000000000000..be4262fbc4aae --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_init.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_init.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifdef ATH_SUPPORT_DFS + +extern int domainoverride; + +/* + * Clear all delay lines for all filter types + * + * This may be called before any radar pulses are configured + * (eg on a non-DFS channel, with radar PHY errors still showing up.) + * In that case, just drop out early. + */ +void dfs_reset_alldelaylines(struct ath_dfs *dfs) +{ + struct dfs_filtertype *ft = NULL; + struct dfs_filter *rf; + struct dfs_delayline *dl; + struct dfs_pulseline *pl; + int i,j; + + if (dfs == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: sc_dfs is NULL", __func__, __LINE__); + return; + } + pl = dfs->pulses; + + if (pl == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: pl==NULL, dfs=%p", __func__, __LINE__, dfs); + return; + } + + if (dfs->dfs_b5radars == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: pl==NULL, b5radars=%p", __func__, __LINE__, dfs->dfs_b5radars); + return; + } + + /* reset the pulse log */ + pl->pl_firstelem = pl->pl_numelems = 0; + pl->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK; + + for (i=0; idfs_radarf[i] != NULL) { + ft = dfs->dfs_radarf[i]; + if (NULL != ft) { + for (j = 0; j < ft->ft_numfilters; j++) { + rf = &(ft->ft_filters[j]); + dl = &(rf->rf_dl); + if (dl != NULL) { + OS_MEMZERO(dl, sizeof(struct dfs_delayline)); + dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK; + } + } + } + } + } + for (i = 0; i < dfs->dfs_rinfo.rn_numbin5radars; i++) { + OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), sizeof(struct dfs_bin5elem)*DFS_MAX_B5_SIZE); + dfs->dfs_b5radars[i].br_firstelem = 0; + dfs->dfs_b5radars[i].br_numelems = 0; + dfs->dfs_b5radars[i].br_lastelem = (0xFFFFFFFF)&DFS_MAX_B5_MASK; + } +} +/* + * Clear only a single delay line + */ + +void dfs_reset_delayline(struct dfs_delayline *dl) +{ + OS_MEMZERO(&(dl->dl_elems[0]), sizeof(dl->dl_elems)); + dl->dl_lastelem = (0xFFFFFFFF)&DFS_MAX_DL_MASK; +} + +void dfs_reset_filter_delaylines(struct dfs_filtertype *dft) +{ + int i; + struct dfs_filter *df; + for (i=0; i< DFS_MAX_NUM_RADAR_FILTERS; i++) { + df = &dft->ft_filters[i]; + dfs_reset_delayline(&(df->rf_dl)); + } +} + +void +dfs_reset_radarq(struct ath_dfs *dfs) +{ + struct dfs_event *event; + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL", __func__); + return; + } + ATH_DFSQ_LOCK(dfs); + ATH_DFSEVENTQ_LOCK(dfs); + while (!STAILQ_EMPTY(&(dfs->dfs_radarq))) { + event = STAILQ_FIRST(&(dfs->dfs_radarq)); + STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list); + OS_MEMZERO(event, sizeof(struct dfs_event)); + STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list); + } + ATH_DFSEVENTQ_UNLOCK(dfs); + ATH_DFSQ_UNLOCK(dfs); +} + + +/* This function Initialize the radar filter tables + * if the ath dfs domain is uninitalized or + * ath dfs domain is different from hal dfs domain + */ +int dfs_init_radar_filters(struct ieee80211com *ic, + struct ath_dfs_radar_tab_info *radar_info) +{ + u_int32_t T, Tmax; + int numpulses,p,n, i; + int numradars = 0, numb5radars = 0; + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + struct dfs_filtertype *ft = NULL; + struct dfs_filter *rf=NULL; + struct dfs_pulse *dfs_radars; + struct dfs_bin5pulse *b5pulses=NULL; + int32_t min_rssithresh=DFS_MAX_RSSI_VALUE; + u_int32_t max_pulsedur=0; + + if (dfs == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: dfs is NULL", __func__, __LINE__); + return DFS_STATUS_FAIL; + } + /* clear up the dfs domain flag first */ +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + dfs->ath_dfs_isdfsregdomain = 0; +#endif + + /* + * If radar_info is NULL or dfsdomain is NULL, treat + * the rest of the radar configuration as suspect. + */ + if (radar_info == NULL || radar_info->dfsdomain == 0) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: Unknown dfs domain %d ", + __func__, __LINE__, dfs->dfsdomain); + /* Disable radar detection since we don't have a radar domain */ + dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN; + /* Returning success though we are not completing init. A failure + * will fail dfs_attach also. + */ + return DFS_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s[%d]:dfsdomain=%d, numradars=%d, numb5radars=%d", + __func__, __LINE__, radar_info->dfsdomain, + radar_info->numradars, radar_info->numb5radars); + dfs->dfsdomain = radar_info->dfsdomain; + dfs_radars = radar_info->dfs_radars; + numradars = radar_info->numradars; + b5pulses = radar_info->b5pulses; + numb5radars = radar_info->numb5radars; + + /* XXX this should be an explicit copy of some sort! */ + dfs->dfs_defaultparams = radar_info->dfs_defaultparams; + +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + dfs->ath_dfs_isdfsregdomain = 1; +#endif + + dfs->dfs_rinfo.rn_numradars = 0; + /* Clear filter type table */ + for (n = 0; n < 256; n++) { + for (i=0;idfs_radartable[n])[i] = -1; + } + /* Now, initialize the radar filters */ + for (p=0; pdfs_rinfo.rn_numradars; n++) { + if ((dfs_radars[p].rp_pulsedur == dfs->dfs_radarf[n]->ft_filterdur) && + (dfs_radars[p].rp_numpulses == dfs->dfs_radarf[n]->ft_numpulses) && + (dfs_radars[p].rp_mindur == dfs->dfs_radarf[n]->ft_mindur) && + (dfs_radars[p].rp_maxdur == dfs->dfs_radarf[n]->ft_maxdur)) { + ft = dfs->dfs_radarf[n]; + break; + } + } + if (ft == NULL) { + /* No filter of the appropriate dur was found */ + if ((dfs->dfs_rinfo.rn_numradars+1) >DFS_MAX_RADAR_TYPES) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types", + __func__); + goto bad4; + } + ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars]; + ft->ft_numfilters = 0; + ft->ft_numpulses = dfs_radars[p].rp_numpulses; + ft->ft_patterntype = dfs_radars[p].rp_patterntype; + ft->ft_mindur = dfs_radars[p].rp_mindur; + ft->ft_maxdur = dfs_radars[p].rp_maxdur; + ft->ft_filterdur = dfs_radars[p].rp_pulsedur; + ft->ft_rssithresh = dfs_radars[p].rp_rssithresh; + ft->ft_rssimargin = dfs_radars[p].rp_rssimargin; + ft->ft_minpri = 1000000; + + if (ft->ft_rssithresh < min_rssithresh) + min_rssithresh = ft->ft_rssithresh; + if (ft->ft_maxdur > max_pulsedur) + max_pulsedur = ft->ft_maxdur; + for (i=ft->ft_mindur; i<=ft->ft_maxdur; i++) { + u_int32_t stop=0,tableindex=0; + while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) { + if ((dfs->dfs_radartable[i])[tableindex] == -1) + stop = 1; + else + tableindex++; + } + if (stop) { + (dfs->dfs_radartable[i])[tableindex] = + (int8_t) (dfs->dfs_rinfo.rn_numradars); + } else { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: Too many overlapping radar filters", + __func__); + goto bad4; + } + } + dfs->dfs_rinfo.rn_numradars++; + } + rf = &(ft->ft_filters[ft->ft_numfilters++]); + dfs_reset_delayline(&rf->rf_dl); + numpulses = dfs_radars[p].rp_numpulses; + + rf->rf_numpulses = numpulses; + rf->rf_patterntype = dfs_radars[p].rp_patterntype; + rf->rf_pulseid = dfs_radars[p].rp_pulseid; + rf->rf_mindur = dfs_radars[p].rp_mindur; + rf->rf_maxdur = dfs_radars[p].rp_maxdur; + rf->rf_numpulses = dfs_radars[p].rp_numpulses; + rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window; + T = (100000000/dfs_radars[p].rp_max_pulsefreq) - + 100*(dfs_radars[p].rp_meanoffset); + rf->rf_minpri = + dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar))); + Tmax = (100000000/dfs_radars[p].rp_pulsefreq) - + 100*(dfs_radars[p].rp_meanoffset); + rf->rf_maxpri = + dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar))); + + if( rf->rf_minpri < ft->ft_minpri ) + ft->ft_minpri = rf->rf_minpri; + + rf->rf_fixed_pri_radar_pulse = ( dfs_radars[p].rp_max_pulsefreq == dfs_radars[p].rp_pulsefreq ) ? 1 : 0; + rf->rf_threshold = dfs_radars[p].rp_threshold; + rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d", + __func__,__LINE__,dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq, + dfs_radars[p].rp_pulsevar, rf->rf_threshold); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d",__func__,__LINE__, + rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid); + + } + +#ifdef DFS_DEBUG + dfs_print_filters(ic); +#endif + dfs->dfs_rinfo.rn_numbin5radars = numb5radars; + if (dfs->dfs_b5radars != NULL) + OS_FREE(dfs->dfs_b5radars); + + dfs->dfs_b5radars = (struct dfs_bin5radars *)OS_MALLOC(NULL, + numb5radars * sizeof(struct dfs_bin5radars), GFP_KERNEL); + if (dfs->dfs_b5radars == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: cannot allocate memory for bin5 radars", + __func__); + goto bad4; + } + for (n=0; ndfs_b5radars[n].br_pulse = b5pulses[n]; + dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= 1000000; + if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < min_rssithresh) + min_rssithresh = dfs->dfs_b5radars[n].br_pulse.b5_rssithresh; + if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur) + max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur; + } + dfs_reset_alldelaylines(dfs); + dfs_reset_radarq(dfs); + dfs->dfs_curchan_radindex = -1; + dfs->dfs_extchan_radindex = -1; + dfs->dfs_rinfo.rn_minrssithresh = min_rssithresh; + /* Convert durations to TSF ticks */ + dfs->dfs_rinfo.rn_maxpulsedur = dfs_round((int32_t)((max_pulsedur*100/80)*100)); + /* relax the max pulse duration a little bit due to inaccuracy caused by chirping. */ + dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur +20; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s[%d]: DFS min filter rssiThresh = %d", + __func__, __LINE__, min_rssithresh); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s[%d]:DFS max pulse dur = %d ticks", + __func__ ,__LINE__, dfs->dfs_rinfo.rn_maxpulsedur); + return DFS_STATUS_SUCCESS; + + bad4: + return DFS_STATUS_FAIL; +} + +void +dfs_clear_stats(struct ieee80211com *ic) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + if (dfs == NULL) + return; + OS_MEMZERO(&dfs->ath_dfs_stats, sizeof (struct dfs_stats)); + dfs->ath_dfs_stats.last_reset_tstamp = ic->ic_get_TSF64(ic); +} + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl.h new file mode 100644 index 0000000000000..d6f6b225578ee --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2010-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_ioctl.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +/* + * ioctl defines + */ + +#ifndef _DFS_IOCTL_H_ +#define _DFS_IOCTL_H_ + +#define DFS_MUTE_TIME 1 +#define DFS_SET_THRESH 2 +#define DFS_GET_THRESH 3 +#define DFS_GET_USENOL 4 +#define DFS_SET_USENOL 5 +#define DFS_RADARDETECTS 6 +#define DFS_BANGRADAR 7 +#define DFS_SHOW_NOL 8 +#define DFS_DISABLE_DETECT 9 +#define DFS_ENABLE_DETECT 10 +#define DFS_DISABLE_FFT 11 +#define DFS_ENABLE_FFT 12 +#define DFS_SET_DEBUG_LEVEL 13 +#define DFS_GET_NOL 14 +#define DFS_SET_NOL 15 + +#define DFS_SET_FALSE_RSSI_THRES 16 +#define DFS_SET_PEAK_MAG 17 +#define DFS_IGNORE_CAC 18 +#define DFS_SET_NOL_TIMEOUT 19 +#define DFS_LAST_IOCTL 20 +#ifndef IEEE80211_CHAN_MAX +#define IEEE80211_CHAN_MAX 255 +#endif + +struct dfsreq_nolelem { + u_int16_t nol_freq; /* NOL channel frequency */ + u_int16_t nol_chwidth; + unsigned long nol_start_ticks; /* OS ticks when the NOL timer started */ + u_int32_t nol_timeout_ms; /* Nol timeout value in msec */ +}; + +struct dfsreq_nolinfo { + u_int32_t ic_nchans; + struct dfsreq_nolelem dfs_nol[IEEE80211_CHAN_MAX]; +}; + +/* + * ioctl parameter types + */ + +#define DFS_PARAM_FIRPWR 1 +#define DFS_PARAM_RRSSI 2 +#define DFS_PARAM_HEIGHT 3 +#define DFS_PARAM_PRSSI 4 +#define DFS_PARAM_INBAND 5 +//5413 specific parameters +#define DFS_PARAM_RELPWR 7 +#define DFS_PARAM_RELSTEP 8 +#define DFS_PARAM_MAXLEN 9 + +struct dfs_ioctl_params { + int32_t dfs_firpwr; /* FIR pwr out threshold */ + int32_t dfs_rrssi; /* Radar rssi thresh */ + int32_t dfs_height; /* Pulse height thresh */ + int32_t dfs_prssi; /* Pulse rssi thresh */ + int32_t dfs_inband; /* Inband thresh */ + int32_t dfs_relpwr; /* pulse relative pwr thresh */ + int32_t dfs_relstep; /* pulse relative step thresh */ + int32_t dfs_maxlen; /* pulse max duration */ +}; + +/* + * XXX keep these in sync with ath_dfs_phyerr_param! + */ +#define DFS_IOCTL_PARAM_NOVAL 65535 +#define DFS_IOCTL_PARAM_ENABLE 0x8000 + +#endif /* _DFS_IOCTL_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl_private.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl_private.h new file mode 100644 index 0000000000000..02397973e949b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_ioctl_private.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2010-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_ioctl_private.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +/* + * ioctl defines + */ + +#ifndef _DFS_IOCTL_PRIVATE_H_ +#define _DFS_IOCTL_PRIVATE_H_ + +/* + * Assert that the NOVAL values match. + */ +#if (ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL) +#error "ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL" +#endif + +/* + * Assert that the ENABLE values match. + */ +#if (ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE) +#error "ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE" +#endif + +/* + * These two methods are used by the lmac glue to copy between + * the DFS and HAL PHY configuration. + * + * I'm "cheating" here and assuming that the ENABLE and NOVAL + * values match - see the above macros. + */ +static inline void +ath_dfs_ioctlparam_to_dfsparam(const struct dfs_ioctl_params *src, + struct ath_dfs_phyerr_param *dst) +{ + + dst->pe_firpwr = src->dfs_firpwr; + dst->pe_rrssi = src->dfs_rrssi; + dst->pe_height = src->dfs_height; + dst->pe_prssi = src->dfs_prssi; + dst->pe_inband = src->dfs_inband; + dst->pe_relpwr = src->dfs_relpwr; + dst->pe_relstep = src->dfs_relstep; + dst->pe_maxlen = src->dfs_maxlen; +} + +static inline void +ath_dfs_dfsparam_to_ioctlparam(struct ath_dfs_phyerr_param *src, + struct dfs_ioctl_params *dst) +{ + + dst->dfs_firpwr = src->pe_firpwr; + dst->dfs_rrssi = src->pe_rrssi; + dst->dfs_height = src->pe_height; + dst->dfs_prssi = src->pe_prssi; + dst->dfs_inband = src->pe_inband; + dst->dfs_relpwr = src->pe_relpwr; + dst->dfs_relstep = src->pe_relstep; + dst->dfs_maxlen = src->pe_maxlen; +} + +#endif /* _DFS_IOCTL_PRIVATE_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_misc.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_misc.c new file mode 100644 index 0000000000000..a8f8e2b3b5956 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_misc.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_misc.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifndef UNINET +/* TO DO DFS +#include +*/ +#endif +#ifdef ATH_SUPPORT_DFS + +static int adjust_pri_per_chan_busy(int ext_chan_busy, int pri_margin) +{ + int adjust_pri=0; + + if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) { + + adjust_pri = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * (pri_margin); + adjust_pri /= 100; + + } + return adjust_pri; +} + +static int adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh) +{ + int adjust_thresh=0; + + if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) { + + adjust_thresh = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * thresh; + adjust_thresh /= 100; + + } + return adjust_thresh; +} +/* For the extension channel, if legacy traffic is present, we see a lot of false alarms, +so make the PRI margin narrower depending on the busy % for the extension channel.*/ + +int +dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect, + int is_fixed_pattern) +{ + + int adjust_pri=0, ext_chan_busy=0; + int pri_margin; + + if (is_fixed_pattern) + pri_margin = DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN; + else + pri_margin = DFS_DEFAULT_PRI_MARGIN; + + if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { + ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); + if(ext_chan_busy >= 0) { + dfs->dfs_rinfo.ext_chan_busy_ts = dfs->ic->ic_get_TSF64(dfs->ic); + dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy; + } else { + // Check to see if the cached value of ext_chan_busy can be used + ext_chan_busy = 0; + if (dfs->dfs_rinfo.dfs_ext_chan_busy) { + if (dfs->dfs_rinfo.rn_lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) { + ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + " PRI Use cached copy of ext_chan_busy extchanbusy=%d \n", ext_chan_busy); + } + } + } + adjust_pri = adjust_pri_per_chan_busy(ext_chan_busy, pri_margin); + + pri_margin -= adjust_pri; + } + return pri_margin; +} + +/* For the extension channel, if legacy traffic is present, we see a lot of false alarms, +so make the thresholds higher depending on the busy % for the extension channel.*/ + +int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf, + int is_extchan_detect) +{ + int ext_chan_busy=0; + int thresh, adjust_thresh=0; + + thresh = rf->rf_threshold; + + if (IS_CHAN_HT40(dfs->ic->ic_curchan)) { + ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic); + if(ext_chan_busy >= 0) { + dfs->dfs_rinfo.ext_chan_busy_ts = dfs->ic->ic_get_TSF64(dfs->ic); + dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy; + } else { + // Check to see if the cached value of ext_chan_busy can be used + ext_chan_busy = 0; + if (dfs->dfs_rinfo.dfs_ext_chan_busy) { + if (dfs->dfs_rinfo.rn_lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) { + ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + " THRESH Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n", + ext_chan_busy, + (unsigned long long)dfs->dfs_rinfo.rn_lastfull_ts, + (unsigned long long)dfs->dfs_rinfo.ext_chan_busy_ts); + } + } + } + + adjust_thresh = adjust_thresh_per_chan_busy(ext_chan_busy, thresh); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + " filterID=%d extchanbusy=%d adjust_thresh=%d\n", + rf->rf_pulseid, ext_chan_busy, adjust_thresh); + + thresh += adjust_thresh; + } + return thresh; +} + + +u_int32_t dfs_round(int32_t val) +{ + u_int32_t ival,rem; + + if (val < 0) + return 0; + ival = val/100; + rem = val-(ival*100); + if (rem <50) + return ival; + else + return(ival+1); +} + +struct ieee80211_channel * +ieee80211_get_extchan(struct ieee80211com *ic) +{ + int chan_offset = 0; + if (IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(ic->ic_curchan)) { + chan_offset = 20; + } else if (IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(ic->ic_curchan)) { + chan_offset = -20; + } else { + return NULL; + } + return(ic->ic_find_channel(ic, ic->ic_curchan->ic_freq + chan_offset, IEEE80211_CHAN_11NA_HT20)); +} + +/* + * Finds the radar state entry that matches the current channel + */ +struct dfs_state * +dfs_getchanstate(struct ath_dfs *dfs, u_int8_t *index, int ext_chan_flag) +{ + struct dfs_state *rs=NULL; + int i; + struct ieee80211_channel *cmp_ch; + + if (dfs == NULL) { + printk("%s[%d]: sc_dfs is NULL\n",__func__,__LINE__); + // DFS_DPRINTK(dfs, ATH_DEBUG_DFS,"%s: sc_dfs is NULL\n",__func__); + return NULL; + } + + if (ext_chan_flag) { + cmp_ch = ieee80211_get_extchan(dfs->ic); + if (cmp_ch) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "Extension channel freq = %u flags=0x%x\n", cmp_ch->ic_freq, cmp_ch->ic_flagext); + } else { + return NULL; + } + + } else { + cmp_ch = dfs->ic->ic_curchan; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "Primary channel freq = %u flags=0x%x\n", cmp_ch->ic_freq, cmp_ch->ic_flagext); + } + for (i=0;idfs_radar[i].rs_chan.ic_freq== cmp_ch->ic_freq) && + (dfs->dfs_radar[i].rs_chan.ic_flags == cmp_ch->ic_flags)) { + if (index != NULL) + *index = (u_int8_t) i; + return &(dfs->dfs_radar[i]); + } + } + /* No existing channel found, look for first free channel state entry */ + for (i=0; idfs_radar[i].rs_chan.ic_freq == 0) { + rs = &(dfs->dfs_radar[i]); + /* Found one, set channel info and default thresholds */ + rs->rs_chan = *cmp_ch; + + /* Copy the parameters from the default set */ + ath_dfs_phyerr_param_copy(&rs->rs_param, + &dfs->dfs_defaultparams); + + if (index != NULL) + *index = (u_int8_t) i; + return (rs); + } + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: No more radar states left.\n", __func__); + return(NULL); +} + + + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_nol.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_nol.c new file mode 100644 index 0000000000000..d907cecf02f9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_nol.c @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_nol.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifndef UNINET +/*TO DO DFS +#include +*/ +#endif +#if defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY) +#include "dfs_ioctl.h" +#include "dfs_ioctl_private.h" +#include "adf_os_time.h" /* adf_os_time_t, adf_os_time_after */ + +static void +dfs_nol_delete(struct ath_dfs *dfs, u_int16_t delfreq, u_int16_t delchwidth); + +static +OS_TIMER_FUNC(dfs_remove_from_nol) +{ + struct dfs_nol_timer_arg *nol_arg; + struct ath_dfs *dfs; + struct ieee80211com *ic; + u_int16_t delfreq; + u_int16_t delchwidth; + + OS_GET_TIMER_ARG(nol_arg, struct dfs_nol_timer_arg *); + + dfs = nol_arg->dfs; + ic = dfs->ic; + delfreq = nol_arg->delfreq; + delchwidth = nol_arg->delchwidth; + + /* Only operate in HOSTAP/IBSS */ + if (ic->ic_opmode != IEEE80211_M_HOSTAP && + ic->ic_opmode != IEEE80211_M_IBSS) + goto done; + + /* Delete the given NOL entry */ + dfs_nol_delete(dfs, delfreq, delchwidth); + + /* Update the wireless stack with the new NOL */ + dfs_nol_update(dfs); + +done: + OS_FREE(nol_arg); + return; +} + +void +dfs_print_nol(struct ath_dfs *dfs) +{ + struct dfs_nolelem *nol; + uint32_t diff_ms, remaining_sec; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", __func__); + return; + } + nol = dfs->dfs_nol; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: NOL", __func__); + while (nol != NULL) { + diff_ms = adf_os_ticks_to_msecs(adf_os_ticks() - nol->nol_start_ticks); + diff_ms = (nol->nol_timeout_ms - diff_ms); + remaining_sec = diff_ms / 1000; /* convert to seconds */ + nol = nol->nol_next; + } +} + + +void +dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, + int *nchan) +{ + struct dfs_nolelem *nol; + + *nchan = 0; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", __func__); + return; + } + + nol = dfs->dfs_nol; + while (nol != NULL) { + dfs_nol[*nchan].nol_freq = nol->nol_freq; + dfs_nol[*nchan].nol_chwidth = nol->nol_chwidth; + dfs_nol[*nchan].nol_start_ticks = nol->nol_start_ticks; + dfs_nol[*nchan].nol_timeout_ms = nol->nol_timeout_ms; + ++(*nchan); + nol = nol->nol_next; + } +} + + +void +dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan) +{ +#define TIME_IN_MS 1000 + u_int32_t nol_time_left_ms; + struct ieee80211_channel chan; + int i; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", __func__); + return; + } + + for (i = 0; i < nchan; i++) + { + nol_time_left_ms = adf_os_ticks_to_msecs(adf_os_ticks() - dfs_nol[i].nol_start_ticks); + if (nol_time_left_ms < dfs_nol[i].nol_timeout_ms) { + chan.ic_freq = dfs_nol[i].nol_freq; + chan.ic_flags= 0; + chan.ic_flagext = 0; + nol_time_left_ms = (dfs_nol[i].nol_timeout_ms - nol_time_left_ms); + dfs_nol_addchan(dfs, &chan, (nol_time_left_ms / TIME_IN_MS)); + } + } +#undef TIME_IN_MS + dfs_nol_update(dfs); +} + + +void +dfs_nol_addchan(struct ath_dfs *dfs, struct ieee80211_channel *chan, + u_int32_t dfs_nol_timeout) +{ +#define TIME_IN_MS 1000 +#define TIME_IN_US (TIME_IN_MS * 1000) + struct dfs_nolelem *nol, *elem, *prev; + struct dfs_nol_timer_arg *dfs_nol_arg; + /* XXX for now, assume all events are 20MHz wide */ + int ch_width = 20; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL", __func__); + return; + } + nol = dfs->dfs_nol; + prev = dfs->dfs_nol; + elem = NULL; + while (nol != NULL) { + if ((nol->nol_freq == chan->ic_freq) && + (nol->nol_chwidth == ch_width)) { + nol->nol_start_ticks = adf_os_ticks(); + nol->nol_timeout_ms = dfs_nol_timeout*TIME_IN_MS; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, + "%s: Update OS Ticks for NOL %d MHz / %d MHz", + __func__, nol->nol_freq, nol->nol_chwidth); + OS_CANCEL_TIMER(&nol->nol_timer); + OS_SET_TIMER(&nol->nol_timer, dfs_nol_timeout*TIME_IN_MS); + return; + } + prev = nol; + nol = nol->nol_next; + } + /* Add a new element to the NOL*/ + elem = (struct dfs_nolelem *)OS_MALLOC(NULL, sizeof(struct dfs_nolelem),GFP_ATOMIC); + if (elem == NULL) { + goto bad; + } + dfs_nol_arg = (struct dfs_nol_timer_arg *)OS_MALLOC(NULL, + sizeof(struct dfs_nol_timer_arg), GFP_ATOMIC); + if (dfs_nol_arg == NULL) { + OS_FREE(elem); + goto bad; + } + elem->nol_freq = chan->ic_freq; + elem->nol_chwidth = ch_width; + elem->nol_start_ticks = adf_os_ticks(); + elem->nol_timeout_ms = dfs_nol_timeout*TIME_IN_MS; + elem->nol_next = NULL; + if (prev) { + prev->nol_next = elem; + } else { + /* This is the first element in the NOL */ + dfs->dfs_nol = elem; + } + dfs_nol_arg->dfs = dfs; + dfs_nol_arg->delfreq = elem->nol_freq; + dfs_nol_arg->delchwidth = elem->nol_chwidth; + + OS_INIT_TIMER(NULL, &elem->nol_timer, dfs_remove_from_nol, + dfs_nol_arg, ADF_DEFERRABLE_TIMER); + OS_SET_TIMER(&elem->nol_timer, dfs_nol_timeout*TIME_IN_MS); + + /* Update the NOL counter */ + dfs->dfs_nol_count++; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, + "%s: new NOL channel %d MHz / %d MHz", + __func__, + elem->nol_freq, + elem->nol_chwidth); + return; + +bad: + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL | ATH_DEBUG_DFS, + "%s: failed to allocate memory for nol entry", __func__); + +#undef TIME_IN_MS +#undef TIME_IN_US +} + +/* + * Delete the given frequency/chwidth from the NOL. + */ +static void +dfs_nol_delete(struct ath_dfs *dfs, u_int16_t delfreq, u_int16_t delchwidth) +{ + struct dfs_nolelem *nol,**prev_next; + + if (dfs == NULL) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL", __func__); + return; + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, + "%s: remove channel=%d/%d MHz from NOL", + __func__, + delfreq, delchwidth); + prev_next = &(dfs->dfs_nol); + nol = dfs->dfs_nol; + while (nol != NULL) { + if (nol->nol_freq == delfreq && nol->nol_chwidth == delchwidth) { + *prev_next = nol->nol_next; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, + "%s removing channel %d/%dMHz from NOL tstamp=%d", + __func__, nol->nol_freq, nol->nol_chwidth, + (adf_os_ticks_to_msecs(adf_os_ticks()) / 1000)); + OS_CANCEL_TIMER(&nol->nol_timer); + OS_FREE(nol); + nol = NULL; + nol = *prev_next; + + /* Update the NOL counter */ + dfs->dfs_nol_count--; + + /* Be paranoid! */ + if (dfs->dfs_nol_count < 0) { + DFS_PRINTK("%s: dfs_nol_count < 0; eek!", __func__); + dfs->dfs_nol_count = 0; + } + + } else { + prev_next = &(nol->nol_next); + nol = nol->nol_next; + } + } +} + +/* + * Notify the driver/umac that it should update the channel radar/NOL + * flags based on the current NOL list. + */ +void +dfs_nol_update(struct ath_dfs *dfs) +{ + struct ieee80211com *ic = dfs->ic; + struct dfs_nol_chan_entry *dfs_nol; + struct dfs_nolelem *nol; + int nlen; + + /* + * Allocate enough entries to store the NOL. + * + * At least on Linux (don't ask why), if you allocate a 0 entry + * array, the returned pointer is 0x10. Make sure you're + * aware of this when you start debugging. + */ + dfs_nol = (struct dfs_nol_chan_entry *)OS_MALLOC(NULL, + sizeof(struct dfs_nol_chan_entry) * dfs->dfs_nol_count, + GFP_ATOMIC); + + if (dfs_nol == NULL) { + /* + * XXX TODO: if this fails, just schedule a task to retry + * updating the NOL at a later stage. That way the NOL + * update _DOES_ happen - hopefully the failure was just + * temporary. + */ + DFS_PRINTK("%s: failed to allocate NOL update memory!", + __func__); + return; + } + + + /* populate the nol array */ + nlen = 0; + + nol = dfs->dfs_nol; + while (nol != NULL && nlen < dfs->dfs_nol_count) { + dfs_nol[nlen].nol_chfreq = nol->nol_freq; + dfs_nol[nlen].nol_chwidth = nol->nol_chwidth; + dfs_nol[nlen].nol_start_ticks = nol->nol_start_ticks; + dfs_nol[nlen].nol_timeout_ms = nol->nol_timeout_ms; + nlen++; + nol = nol->nol_next; + } + + /* Be suitably paranoid for now */ + if (nlen != dfs->dfs_nol_count) + DFS_PRINTK("%s: nlen (%d) != dfs->dfs_nol_count (%d)!", + __func__, nlen, dfs->dfs_nol_count); + + /* + * Call the driver layer to have it recalculate the NOL flags for + * each driver/umac channel. + * + * If the list is empty, pass NULL instead of dfs_nol. + * + * The operating system may have some special representation for + * "malloc a 0 byte memory region" - for example, + * Linux 2.6.38-13 (ubuntu) returns 0x10 rather than a valid + * allocation (and is likely not NULL so the pointer doesn't + * match NULL checks in any later code. + */ + ic->ic_dfs_clist_update(ic, DFS_NOL_CLIST_CMD_UPDATE, + (nlen > 0) ? dfs_nol : NULL, nlen); + + /* + * .. and we're done. + */ + OS_FREE(dfs_nol); +} + +void dfs_nol_timer_cleanup(struct ath_dfs *dfs) +{ + struct dfs_nolelem *nol = dfs->dfs_nol, *prev; + + /* First Cancel timer */ + while (nol) { + OS_CANCEL_TIMER(&nol->nol_timer); + nol = nol->nol_next; + } + /* Free NOL elem, don't mix this while loop with above loop */ + nol = dfs->dfs_nol; + while (nol) { + prev = nol; + nol = nol->nol_next; + OS_FREE(prev); + } + return; +} +#endif /* defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY) */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr.h new file mode 100644 index 0000000000000..bc43f8e85300a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_phyerr.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + +#ifndef __DFS_PHYERR_H__ +#define __DFS_PHYERR_H__ + +extern int dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, + u_int16_t datalen, u_int8_t rssi, u_int8_t ext_rssi, + u_int32_t rs_tstamp, u_int64_t fulltsf, struct dfs_phy_err *e); + +#endif /* __DFS_PHYERR_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c new file mode 100644 index 0000000000000..27238522b852d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_phyerr_tlv.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +/* TO DO DFS +#include +*/ +/* TO DO DFS +#include +*/ +#include "dfs_phyerr.h" +#include "dfs_phyerr_tlv.h" + +/* + * Parsed radar status + */ +struct rx_radar_status { + uint32_t raw_tsf; + uint32_t tsf_offset; + int rssi; + int pulse_duration; + int is_chirp:1; + int delta_peak; + int delta_diff; + int sidx; + int freq_offset; /* in KHz */ +}; + + +struct rx_search_fft_report { + uint32_t total_gain_db; + uint32_t base_pwr_db; + int fft_chn_idx; + int peak_sidx; + int relpwr_db; + int avgpwr_db; + int peak_mag; + int num_str_bins_ib; +}; + + +/* + * XXX until "fastclk" is stored in the DFS configuration.. + */ +#define PERE_IS_OVERSAMPLING(_dfs) (1) + +/* + * XXX there _has_ to be a better way of doing this! + * -adrian + */ +static int32_t +sign_extend_32(uint32_t v, int nb) +{ + uint32_t m = 1U << (nb - 1); + + /* Chop off high bits, just in case */ + v &= v & ((1U << nb) - 1); + + /* Extend */ + return (v ^ m) - m; +} + +/* + * Calculate the frequency offset from the given signed bin index + * from the radar summary report. + * + * This takes the oversampling mode into account. + * + * For oversampling, each bin has resolution 44MHz/128. + * For non-oversampling, each bin has resolution 40MHz/128. + * + * It returns kHz - ie, 1000th's of MHz. + */ +static int +calc_freq_offset(int sindex, int is_oversampling) +{ + + if (is_oversampling) + return (sindex * (44000 / 128)); + else + return (sindex * (40000 / 128)); +} + +static void +radar_summary_print(struct ath_dfs *dfs, struct rx_radar_status *rsu) +{ + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " pulsedur=%d", rsu->pulse_duration); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " rssi=%d", rsu->rssi); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " ischirp=%d", rsu->is_chirp); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " sidx=%d", rsu->sidx); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " raw tsf=%d", rsu->raw_tsf); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " tsf_offset=%d", rsu->tsf_offset); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " cooked tsf=%d", rsu->raw_tsf - rsu->tsf_offset); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + " frequency offset=%d.%d MHz (oversampling=%d)", + (int) (rsu->freq_offset / 1000), + (int) abs(rsu->freq_offset % 1000), + PERE_IS_OVERSAMPLING(dfs)); +} + +/* + * Parse the radar summary frame. + * + * The frame contents _minus_ the TLV are passed in. + */ +static void +radar_summary_parse(struct ath_dfs *dfs, const char *buf, size_t len, + struct rx_radar_status *rsu) +{ + uint32_t rs[2]; + int freq_centre, freq; + + /* Drop out if we have < 2 DWORDs available */ + if (len < sizeof(rs)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | + ATH_DEBUG_DFS_PHYERR_SUM, + "%s: len (%zu) < expected (%zu)!", + __func__, + len, + sizeof(rs)); + } + + /* + * Since the TLVs may be unaligned for some reason + * we take a private copy into aligned memory. + * This enables us to use the HAL-like accessor macros + * into the DWORDs to access sub-DWORD fields. + */ + OS_MEMCPY(rs, buf, sizeof(rs)); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: two 32 bit values are: %08x %08x", __func__, rs[0], rs[1]); +// DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s (p=%p):", __func__, buf); + + /* Populate the fields from the summary report */ + rsu->tsf_offset = + MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_TSF_OFFSET); + rsu->pulse_duration = + MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_DUR); + rsu->is_chirp = + MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_IS_CHIRP); + rsu->sidx = sign_extend_32( + MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_SIDX), + 10); + rsu->freq_offset = + calc_freq_offset(rsu->sidx, PERE_IS_OVERSAMPLING(dfs)); + + /* These are only relevant if the pulse is a chirp */ + rsu->delta_peak = sign_extend_32( + MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_PEAK), + 6); + rsu->delta_diff = + MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_DIFF); + + /* WAR for FCC Type 4*/ + /* + * HW is giving longer pulse duration (in case of VHT80, with traffic) + * which fails to detect FCC type4 radar pulses. Added a work around to + * fix the pulse duration and duration delta. + * + * IF VHT80 + * && (primary_channel==30MHz || primary_channel== -30MHz) + * && -4 <= pulse_index <= 4 + * && !chirp + * && pulse duration > 20 us + * THEN + * Set pulse duration to 20 us + */ + + freq = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan); + freq_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; + + if ((IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan) && + (abs(freq - freq_centre) == 30) && + !rsu->is_chirp && + abs(rsu->sidx) <= 4 && + rsu->pulse_duration > 20)){ + rsu->pulse_duration = 20; + } + +} + +static void +radar_fft_search_report_parse(struct ath_dfs *dfs, const char *buf, size_t len, + struct rx_search_fft_report *rsfr) +{ + uint32_t rs[2]; + + /* Drop out if we have < 2 DWORDs available */ + if (len < sizeof(rs)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | + ATH_DEBUG_DFS_PHYERR_SUM, + "%s: len (%zu) < expected (%zu)!", + __func__, + len, + sizeof(rs)); + } + + /* + * Since the TLVs may be unaligned for some reason + * we take a private copy into aligned memory. + * This enables us to use the HAL-like accessor macros + * into the DWORDs to access sub-DWORD fields. + */ + OS_MEMCPY(rs, buf, sizeof(rs)); + rsfr->total_gain_db = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_TOTAL_GAIN_DB); + rsfr->base_pwr_db = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_BASE_PWR_DB); + rsfr->fft_chn_idx = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_FFT_CHN_IDX); + rsfr->peak_sidx = sign_extend_32(MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_PEAK_SIDX), 12); + rsfr->relpwr_db = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_RELPWR_DB); + rsfr->avgpwr_db = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_AVGPWR_DB); + rsfr->peak_mag = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_PEAK_MAG); + rsfr->num_str_bins_ib = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_NUM_STR_BINS_IB); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: two 32 bit values are: %08x %08x", __func__, rs[0], rs[1]); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->total_gain_db = %d", __func__, rsfr->total_gain_db); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->base_pwr_db = %d", __func__, rsfr->base_pwr_db); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->fft_chn_idx = %d", __func__, rsfr->fft_chn_idx); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->peak_sidx = %d", __func__, rsfr->peak_sidx); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->relpwr_db = %d", __func__, rsfr->relpwr_db); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->avgpwr_db = %d", __func__, rsfr->avgpwr_db); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->peak_mag = %d", __func__, rsfr->peak_mag); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->num_str_bins_ib = %d", __func__, rsfr->num_str_bins_ib); +} + +/* + * Parse a Peregrine BB TLV frame. + * + * This routine parses each TLV, prints out what's going on and + * calls an appropriate sub-function. + * + * Since the TLV format doesn't _specify_ all TLV components are + * DWORD aligned, we must treat them as not and access the fields + * appropriately. + */ +static int +tlv_parse_frame(struct ath_dfs *dfs, struct rx_radar_status *rs, + struct rx_search_fft_report *rsfr, const char *buf, size_t len, u_int8_t rssi) +{ + int i = 0; + uint32_t tlv_hdr[1]; + bool first_tlv = true; + bool false_detect = false; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s: total length = %zu bytes", __func__, len); + while ((i < len ) && (false_detect == false)) { + /* Ensure we at least have four bytes */ + if ((len - i) < sizeof(tlv_hdr)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | + ATH_DEBUG_DFS_PHYERR_SUM, + "%s: ran out of bytes, len=%zu, i=%d", + __func__, len, i); + return (0); + } + + /* + * Copy the offset into the header, + * so the DWORD style access macros + * can be used. + */ + OS_MEMCPY(&tlv_hdr, buf + i, sizeof(tlv_hdr)); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s: HDR: TLV SIG=0x%x, TAG=0x%x, LEN=%d bytes", + __func__, + MS(tlv_hdr[TLV_REG], TLV_SIG), + MS(tlv_hdr[TLV_REG], TLV_TAG), + MS(tlv_hdr[TLV_REG], TLV_LEN)); + + /* + * Sanity check the length field is available in + * the remaining frame. Drop out if this isn't + * the case - we can't trust the rest of the TLV + * entries. + */ + if (MS(tlv_hdr[TLV_REG], TLV_LEN) + i >= len) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s: TLV oversize: TLV LEN=%d, available=%zu, " + "i=%d", + __func__, + MS(tlv_hdr[TLV_REG], TLV_LEN), + len, + i); + break; + } + + /* Skip the TLV header - one DWORD */ + i += sizeof(tlv_hdr); + + /* Handle the payload */ + /* XXX TODO! */ + switch (MS(tlv_hdr[TLV_REG], TLV_SIG)) { + case TAG_ID_RADAR_PULSE_SUMMARY: /* Radar pulse summary */ + /* XXX TODO verify return value */ + /* XXX TODO validate only seeing one of these */ + radar_summary_parse(dfs, buf + i, + MS(tlv_hdr[TLV_REG], TLV_LEN), rs); + break; + case TAG_ID_SEARCH_FFT_REPORT: + radar_fft_search_report_parse(dfs, buf + i, + MS(tlv_hdr[TLV_REG], TLV_LEN), rsfr); + /* + we examine search FFT report and make the following assumption + as per algorithms group's input: + (1) There may be multiple TLV + (2) We make false detection decison solely based on the first TLV + (3) If the first TLV is a serch FFT report then we check the peak_mag value. + When RSSI is equal to dfs->ath_dfs_false_rssI_thres (default 50) + and peak_mag is less than 2 * dfs->ath_dfs_peak_mag (default 40) + we treat it as false detect. + Please note that 50 is not a true RSSI estimate, but value indicated + by HW for RF saturation event. + */ + + if ((first_tlv == true) && + (rssi == dfs->ath_dfs_false_rssi_thres) && + (rsfr->peak_mag < (2 * dfs->ath_dfs_peak_mag))) { + false_detect = true; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: setting false_detect to TRUE", __func__); + } + + break; + default: + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s: unknown entry, SIG=0x%02x", + __func__, + MS(tlv_hdr[TLV_REG], TLV_SIG)); + } + + /* Skip the payload */ + i += MS(tlv_hdr[TLV_REG], TLV_LEN); + first_tlv = false; + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: done", __func__); + + return (false_detect? 0 : 1); +} + +/* + * Calculate the channel centre in MHz. + */ +static int +tlv_calc_freq_info(struct ath_dfs *dfs, struct rx_radar_status *rs) +{ + uint32_t chan_centre; + uint32_t chan_width; + int chan_offset; + + /* + * For now, just handle up to VHT80 correctly. + */ + if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) { + DFS_PRINTK("%s: dfs->ic=%p, that or curchan is null?", + __func__, dfs->ic); + return (0); + /* + * For now, the only 11ac channel with freq1/freq2 setup is + * VHT80. + * + * XXX should have a flag macro to check this! + */ + } else if (IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan)) { + /* 11AC, so cfreq1/cfreq2 are setup */ + + /* + * XXX if it's 80+80 this won't work - need to use seg + * appropriately! + */ + + chan_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1; + } else { + /* HT20/HT40 */ + + /* + * XXX this is hard-coded - it should be 5 or 10 for + * half/quarter appropriately. + */ + chan_width = 20; + + /* Grab default channel centre */ + chan_centre = ieee80211_chan2freq(dfs->ic, + dfs->ic->ic_curchan); + + /* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D */ + if (IEEE80211_IS_CHAN_11N_HT40PLUS(dfs->ic->ic_curchan) || + dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40PLUS) + chan_offset = chan_width; + else if (IEEE80211_IS_CHAN_11N_HT40MINUS(dfs->ic->ic_curchan) || + dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40MINUS) + chan_offset = -chan_width; + else + chan_offset = 0; + + /* Calculate new _real_ channel centre */ + chan_centre += (chan_offset / 2); + } + + /* + * XXX half/quarter rate support! + */ + + /* Return ev_chan_centre in MHz */ + return (chan_centre); +} + +/* + * Calculate the centre frequency and low/high range for a radar pulse event. + * + * XXX TODO: Handle half/quarter rates correctly! + * XXX TODO: handle VHT160 correctly! + * XXX TODO: handle VHT80+80 correctly! + */ +static int +tlv_calc_event_freq_pulse(struct ath_dfs *dfs, struct rx_radar_status *rs, + uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi) +{ + int chan_width; + int chan_centre; + + /* Fetch the channel centre frequency in MHz */ + chan_centre = tlv_calc_freq_info(dfs, rs); + + /* Convert to KHz */ + chan_centre *= 1000; + + /* + * XXX hard-code event width to be 2 * bin size for now; + * XXX this needs to take into account the core clock speed + * XXX for half/quarter rate mode. + */ + if (PERE_IS_OVERSAMPLING(dfs)) + chan_width = (44000 * 2 / 128); + else + chan_width = (40000 * 2 / 128); + + /* XXX adjust chan_width for half/quarter rate! */ + + /* + * Now we can do the math to figure out the correct channel range. + */ + (*freq_centre) = (uint32_t) (chan_centre + rs->freq_offset); + (*freq_lo) = (uint32_t) ((chan_centre + rs->freq_offset) + - chan_width); + (*freq_hi) = (uint32_t) ((chan_centre + rs->freq_offset) + + chan_width); + + return (1); +} + +/* + * The chirp bandwidth in KHz is defined as: + * + * totalBW(KHz) = delta_peak(mean) + * * [ (bin resolution in KHz) / (radar_fft_long_period in uS) ] + * * pulse_duration (us) + * + * The bin resolution depends upon oversampling. + * + * For now, we treat the radar_fft_long_period as a hard-coded 8uS. + */ +static int +tlv_calc_event_freq_chirp(struct ath_dfs *dfs, struct rx_radar_status *rs, + uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi) +{ + int32_t bin_resolution; /* KHz * 100 */ + int32_t radar_fft_long_period = 8; /* microseconds */ + int32_t delta_peak; + int32_t pulse_duration; + int32_t total_bw; + int32_t chan_centre; + int32_t freq_1, freq_2; + + /* + * KHz isn't enough resolution here! + * So treat it as deci-hertz (10Hz) and convert back to KHz + * later. + */ + if (PERE_IS_OVERSAMPLING(dfs)) + bin_resolution = (44000 * 100) / 128; + else + bin_resolution = (40000 * 100) / 128; + + delta_peak = rs->delta_peak; + pulse_duration = rs->pulse_duration; + + total_bw = delta_peak * (bin_resolution / radar_fft_long_period) * + pulse_duration; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | ATH_DEBUG_DFS_PHYERR_SUM, + "%s: delta_peak=%d, pulse_duration=%d, bin_resolution=%d.%dKHz, " + "radar_fft_long_period=%d, total_bw=%d.%ldKHz", + __func__, + delta_peak, + pulse_duration, + bin_resolution / 1000, + bin_resolution % 1000, + radar_fft_long_period, + total_bw / 100, + abs(total_bw % 100)); + + total_bw /= 100; /* back to KHz */ + + /* Grab the channel centre frequency in MHz */ + chan_centre = tlv_calc_freq_info(dfs, rs); + + /* Early abort! */ + if (chan_centre == 0) { + (*freq_centre) = 0; + return (0); + } + + /* Convert to KHz */ + chan_centre *= 1000; + + /* + * sidx is the starting frequency; total_bw is a signed value and + * for negative chirps (ie, moving down in frequency rather than up) + * the end frequency may be less than the start frequency. + */ + if (total_bw > 0) { + freq_1 = chan_centre + rs->freq_offset; + freq_2 = chan_centre + rs->freq_offset + total_bw; + } else { + freq_1 = chan_centre + rs->freq_offset + total_bw; + freq_2 = chan_centre + rs->freq_offset; + } + + (*freq_lo) = (uint32_t)(freq_1); + (*freq_hi) = (uint32_t)(freq_2); + (*freq_centre) = (uint32_t) (freq_1 + (abs(total_bw) / 2)); + + return (1); +} + +/* + * Calculate the centre and band edge frequencies of the given radar + * event. + */ +static int +tlv_calc_event_freq(struct ath_dfs *dfs, struct rx_radar_status *rs, + uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi) +{ + if (rs->is_chirp) + return tlv_calc_event_freq_chirp(dfs, rs, freq_centre, + freq_lo, freq_hi); + else + return tlv_calc_event_freq_pulse(dfs, rs, freq_centre, + freq_lo, freq_hi); +} + +/* + * This is the public facing function which parses the PHY error + * and populates the dfs_phy_err struct. + */ +int +dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, u_int16_t datalen, + u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf, + struct dfs_phy_err *e) +{ + struct rx_radar_status rs; + struct rx_search_fft_report rsfr; + static int invalid_phyerr_count = 0; + + OS_MEMZERO(&rs, sizeof(rs)); + + /* + * Add the ppdu_start/ppdu_end fields given to us by the upper + * layers. The firmware gives us a summary set of parameters rather + * than the whole PPDU_START/PPDU_END descriptor contenst. + */ + rs.rssi = rssi; + rs.raw_tsf = rs_tstamp; + /* + * Try parsing the TLV set. + */ + if (! tlv_parse_frame(dfs, &rs, &rsfr, buf, datalen, rssi)){ + invalid_phyerr_count++; + /* + * Print only at every 2 power times + * to avoid flushing of the kernel + * logs, since the frequency of + * invalid phyerrors is very high + * in noisy environments. + */ + if ( !(invalid_phyerr_count & 0xFF) ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, + "%s[%d]:DFS-tlv parse failed invalid phyerror count = %d", + __func__,__LINE__, invalid_phyerr_count); + } + return (0); + } + /* For debugging, print what we have parsed */ + radar_summary_print(dfs, &rs); + + /* Populate dfs_phy_err from rs */ + OS_MEMSET(e, 0, sizeof(*e)); + e->rssi = rs.rssi; + e->dur = rs.pulse_duration; + e->sidx = rs.sidx; + e->is_pri = 1; /* XXX always PRI for now */ + e->is_ext = 0; + e->is_dc = 0; + e->is_early = 0; + /* + * XXX TODO: add a "chirp detection enabled" capability or config + * bit somewhere, in case for some reason the hardware chirp + * detection AND FFTs are disabled. + */ + /* For now, assume this hardware always does chirp detection */ + e->do_check_chirp = 1; + e->is_hw_chirp = !! (rs.is_chirp); + e->is_sw_chirp = 0; /* We don't yet do software chirp checking */ + + e->fulltsf = fulltsf; + e->rs_tstamp = rs.raw_tsf - rs.tsf_offset; + + /* XXX error check */ + (void) tlv_calc_event_freq(dfs, &rs, &e->freq, &e->freq_lo, + &e->freq_hi); + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, + "%s: fbin=%d, freq=%d.%d MHz, raw tsf=%u, offset=%d, " + "cooked tsf=%u, rssi=%d, dur=%d, is_chirp=%d, fulltsf=%llu, " + "freq=%d.%d MHz, freq_lo=%d.%dMHz, freq_hi=%d.%d MHz", + __func__, + rs.sidx, + (int) (rs.freq_offset / 1000), + (int) abs(rs.freq_offset % 1000), + rs.raw_tsf, + rs.tsf_offset, + e->rs_tstamp, + rs.rssi, + rs.pulse_duration, + (int) rs.is_chirp, + (unsigned long long) fulltsf, + (int) e->freq / 1000, + (int) abs(e->freq) % 1000, + (int) e->freq_lo / 1000, + (int) abs(e->freq_lo) % 1000, + (int) e->freq_hi / 1000, + (int) abs(e->freq_hi) % 1000); + + return (1); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h new file mode 100644 index 0000000000000..ca90fa5cc3953 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_phyerr_tlv.h + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ +#ifndef __DFS_PHYERR_PEREGRINE_H__ +#define __DFS_PHYERR_PEREGRINE_H__ + +/* + * Register manipulation macros that expect bit field defines + * to follow the convention that an _S suffix is appended for + * a shift count, while the field mask has no suffix. + */ +#define SM(_v, _f) (((_v) << _f##_S) & _f) +#define MS(_v, _f) (((_v) & _f) >> _f##_S) + +/* + * The TLV dword is at the beginning of each TLV section. + */ +#define TLV_REG 0x00 + +#define TLV_LEN 0x0000FFFF +#define TLV_LEN_S 0 + +#define TLV_SIG 0x00FF0000 +#define TLV_SIG_S 16 + +#define TLV_TAG 0xFF000000 +#define TLV_TAG_S 24 + +#define TAG_ID_SEARCH_FFT_REPORT 0xFB +#define TAG_ID_RADAR_PULSE_SUMMARY 0xF8 +/* + * Radar pulse summary + * + * + TYPE=0xF8 (Radar pulse summary reprot) + * + SIG=0xBB (baseband PHY generated TLV components) + */ + +#define RADAR_REPORT_PULSE_REG_1 0x00 + +#define RADAR_REPORT_PULSE_IS_CHIRP 0x80000000 +#define RADAR_REPORT_PULSE_IS_CHIRP_S 31 + +#define RADAR_REPORT_PULSE_IS_MAX_WIDTH 0x40000000 +#define RADAR_REPORT_PULSE_IS_MAX_WIDTH_S 30 + +#define RADAR_REPORT_AGC_TOTAL_GAIN 0x3FF00000 +#define RADAR_REPORT_AGC_TOTAL_GAIN_S 20 + +#define RADAR_REPORT_PULSE_DELTA_DIFF 0x000F0000 +#define RADAR_REPORT_PULSE_DELTA_DIFF_S 16 + +#define RADAR_REPORT_PULSE_DELTA_PEAK 0x0000FC00 +#define RADAR_REPORT_PULSE_DELTA_PEAK_S 10 + +#define RADAR_REPORT_PULSE_SIDX 0x000003FF +#define RADAR_REPORT_PULSE_SIDX_S 0x0 + +#define RADAR_REPORT_PULSE_REG_2 0x01 + +#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID 0x80000000 +#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID_S 31 + +#define RADAR_REPORT_PULSE_AGC_MB_GAIN 0x7F000000 +#define RADAR_REPORT_PULSE_AGC_MB_GAIN_S 24 + +#define RADAR_REPORT_PULSE_SUBCHAN_MASK 0x00FF0000 +#define RADAR_REPORT_PULSE_SUBCHAN_MASK_S 16 + +#define RADAR_REPORT_PULSE_TSF_OFFSET 0x0000FF00 +#define RADAR_REPORT_PULSE_TSF_OFFSET_S 8 + +#define RADAR_REPORT_PULSE_DUR 0x000000FF +#define RADAR_REPORT_PULSE_DUR_S 0 + +#define SEARCH_FFT_REPORT_REG_1 0x00 + + +#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB 0xFF800000 +#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB_S 23 + +#define SEARCH_FFT_REPORT_BASE_PWR_DB 0x007FC000 +#define SEARCH_FFT_REPORT_BASE_PWR_DB_S 14 + +#define SEARCH_FFT_REPORT_FFT_CHN_IDX 0x00003000 +#define SEARCH_FFT_REPORT_FFT_CHN_IDX_S 12 + +#define SEARCH_FFT_REPORT_PEAK_SIDX 0x00000FFF +#define SEARCH_FFT_REPORT_PEAK_SIDX_S 0 + +#define SEARCH_FFT_REPORT_REG_2 0x01 + +#define SEARCH_FFT_REPORT_RELPWR_DB 0xFC000000 +#define SEARCH_FFT_REPORT_RELPWR_DB_S 26 + +#define SEARCH_FFT_REPORT_AVGPWR_DB 0x03FC0000 +#define SEARCH_FFT_REPORT_AVGPWR_DB_S 18 + +#define SEARCH_FFT_REPORT_PEAK_MAG 0x0003FF00 +#define SEARCH_FFT_REPORT_PEAK_MAG_S 8 + +#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB 0x000000FF +#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB_S 0 + + + +/* + * Although this code is now not parsing the whole frame (descriptor + * and all), the relevant fields are still useful information + * for anyone who is working on the PHY error part of DFS pattern + * matching. + * + * However, to understand _where_ these descriptors start, you + * should do some digging into the peregrine descriptor format. + * The 30 second version: each RX ring has a bitmap listing which + * descriptors are to be included, and then a set of offsets + * into the RX buffer for where each descriptor will be written. + * It's not like the 802.11n generation hardware which has + * a fixed descriptor format. + */ + +/* + * RX_PPDU_START + */ +#define RX_PPDU_START_LEN (10*4) + +#define RX_PPDU_START_REG_4 0x0004 +#define RX_PPDU_START_RSSI_COMB 0x000000FF +#define RX_PPDU_START_RSSI_COMB_S 0 + +/* + * RX_PPDU_END + */ +#define RX_PPDU_END_LEN (21*4) + +#define RX_PPDU_END_REG_16 16 +#define RX_PPDU_END_TSF_TIMESTAMP 0xFFFFFFFF +#define RX_PPDU_END_TSF_TIMESTAMP_S 0 + +#define RX_PPDU_END_REG_18 18 +#define RX_PPDU_END_PHY_ERR_CODE 0x0000FF00 +#define RX_PPDU_END_PHY_ERR_CODE_S 8 +#define RX_PPDU_END_PHY_ERR 0x00010000 +#define RX_PPDU_END_PHY_ERR_S 16 + +/* + * The RSSI values can have "special meanings". + * + * If rssi=50, it means that the peak detector triggered. + */ +#define RSSI_PEAK_DETECTOR_SAT 50 + +/* + * + * If rssi=25, it means that the ADC was saturated, but that only is + * valid when there is one ADC gain change. For short pulses this + * is true - you won't have time to do a gain change before the pulse + * goes away. But for longer pulses, ADC gain changes can occur, so + * you'll get a more accurate RSSI figure. + * + * For short pulses (and the definition of "short" still isn't clear + * at the time of writing) there isn't any real time to do a gain change + * (or two, or three..) in order to get an accurate estimation of signal + * sizing. Thus, RSSI will not be very accurate for short duration pulses. + * All you can really say for certain is that yes, there's a pulse that + * met the requirements of the pulse detector. + * + * For more information, see the 802.11ac Microarchitecture guide. + * (TODO: add a twiki reference.) + */ + +#endif /* __DFS_PHYERR_PEREGRINE_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_phyerr.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_phyerr.c new file mode 100644 index 0000000000000..8656502de32fa --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_phyerr.c @@ -0,0 +1,894 @@ +/* + * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_process_phyerr.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +#include "dfs_phyerr.h" /* For chip-specific phyerr function declarations */ +/* TO DO DFS +#include +*/ +#ifndef UNINET +/* TO DO DFS +#include +*/ +#endif +#ifdef ATH_SUPPORT_DFS + +/* + * Return the frequency width for the current operating channel. + * + * This isn't the channel width - it's how wide the reported event + * may be. For HT20 this is 20MHz. For HT40 on Howl and later it'll + * still be 20MHz - the hardware returns either pri or ext channel. + */ +static inline int +dfs_get_event_freqwidth(struct ath_dfs *dfs) +{ + + /* Handle edge cases during startup/transition, shouldn't happen! */ + if (dfs == NULL) + return (0); + if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) + return (0); + + /* + * XXX For now, assume 20MHz wide - but this is incorrect when + * operating in half/quarter mode! + */ + return (20); +} + +/* + * Return the centre frequency for the current operating channel and + * event. + * + * This is for post-Owl 11n chips which report pri/extension channel + * events. + */ +static inline uint16_t +dfs_get_event_freqcentre(struct ath_dfs *dfs, int is_pri, int is_ext, int is_dc) +{ + struct ieee80211com *ic; + int chan_offset = 0, chan_width; + + /* Handle edge cases during startup/transition, shouldn't happen! */ + if (dfs == NULL) + return (0); + if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) + return (0); + + ic = dfs->ic; + + /* + * + * For wide channels, DC and ext frequencies need a bit of hand-holding + * based on whether it's an upper or lower channel. + */ + chan_width = dfs_get_event_freqwidth(dfs); + + if (IEEE80211_IS_CHAN_11N_HT40PLUS(ic->ic_curchan)) + chan_offset = chan_width; + else if (IEEE80211_IS_CHAN_11N_HT40MINUS(ic->ic_curchan)) + chan_offset = -chan_width; + else + chan_offset = 0; + + /* + * Check for DC events first - the sowl code may just set all + * the bits together.. + */ + if (is_dc) { + /* + * XXX TODO: Should DC events be considered 40MHz wide here? + */ + return (ieee80211_chan2freq(ic, ic->ic_curchan) + + (chan_offset / 2)); + } + + /* + * For non-wide channels, the centre frequency is just ic_freq. + * The centre frequency for pri events is still ic_freq. + */ + if (is_pri) { + return (ieee80211_chan2freq(ic, ic->ic_curchan)); + } + + if (is_ext) { + return (ieee80211_chan2freq(ic, ic->ic_curchan) + chan_width); + } + + /* XXX shouldn't get here */ + return (ieee80211_chan2freq(ic, ic->ic_curchan)); +} + +/* + * Process an Owl-style phy error. + * + * Return 1 on success or 0 on failure. + */ +int +dfs_process_phyerr_owl(struct ath_dfs *dfs, void *buf, u_int16_t datalen, + u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf, + struct dfs_phy_err *e) +{ + const char *cbuf = (const char *) buf; + u_int8_t dur; + int event_width; + + /* XXX this shouldn't be kept count here */ + dfs->ath_dfs_stats.owl_phy_errors++; + + /* + * HW cannot detect extension channel radar so it only passes us + * primary channel radar data + */ + if (datalen == 0) + dur = 0; + else + dur = ((u_int8_t *) cbuf)[0]; + + /* + * This is a spurious event; toss. + */ + if (rssi == 0 && dur == 0) + dfs->ath_dfs_stats.datalen_discards++; + return (0); + + /* + * Fill out dfs_phy_err with the information we have + * at hand. + */ + OS_MEMSET(e, 0, sizeof(*e)); + e->rssi = rssi; + e->dur = dur; + e->is_pri = 1; + e->is_ext = 0; + e->is_dc = 0; + e->is_early = 1; + e->fulltsf = fulltsf; + e->rs_tstamp = rs_tstamp; + + /* + * Owl only ever reports events on the primary channel; + * it doesn't even see events on the secondary channel. + */ + event_width = dfs_get_event_freqwidth(dfs); + e->freq = dfs_get_event_freqcentre(dfs, 1, 0, 0) * 1000; + e->freq_lo = e->freq - (event_width / 2) * 1000; + e->freq_hi = e->freq + (event_width / 2) * 1000; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, + "%s: rssi=%u dur=%u, freq=%d MHz, freq_lo=%d MHz, " + "freq_hi=%d MHz\n", + __func__, + rssi, + dur, + e->freq / 1000, + e->freq_lo / 1000, + e->freq_hi / 1000); + + return (1); +} + +/* + * Process a Sowl/Howl style phy error. + */ +int +dfs_process_phyerr_sowl(struct ath_dfs *dfs, void *buf, u_int16_t datalen, + u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf, + struct dfs_phy_err *e) +{ +#define EXT_CH_RADAR_FOUND 0x02 +#define PRI_CH_RADAR_FOUND 0x01 +#define EXT_CH_RADAR_EARLY_FOUND 0x04 + const char *cbuf = (const char *) buf; + u_int8_t dur = 0; + u_int8_t pulse_bw_info, pulse_length_ext, pulse_length_pri; + int pri_found = 0, ext_found = 0; + int early_ext = 0; + int event_width; + + /* + * If radar can be detected on the extension channel, datalen zero + * pulses are bogus, discard them. + */ + if (!datalen) { + dfs->ath_dfs_stats.datalen_discards++; + return (0); + } + + /* Ensure that we have at least three bytes of payload */ + if (datalen < 3) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: short error frame (%d bytes)\n", + __func__, datalen); + dfs->ath_dfs_stats.datalen_discards++; + return (0); + } + + /* + * Fetch the payload directly - the compiler will happily generate + * byte-read instructions with a const char * cbuf pointer. + */ + pulse_length_pri = cbuf[datalen - 3]; + pulse_length_ext = cbuf[datalen - 2]; + pulse_bw_info = cbuf[datalen - 1]; + + /* + * Only the last 3 bits of the BW info are relevant, they indicate + * which channel the radar was detected in. + */ + pulse_bw_info &= 0x07; + + /* + * If pulse on DC, both primary and extension flags will be set + */ + if (((pulse_bw_info & EXT_CH_RADAR_FOUND) && + (pulse_bw_info & PRI_CH_RADAR_FOUND))) { + /* + * Conducted testing, when pulse is on DC, both + * pri and ext durations are reported to be same. + * + * Radiated testing, when pulse is on DC, different + * pri and ext durations are reported, so take the + * larger of the two + */ + if (pulse_length_ext >= pulse_length_pri) { + dur = pulse_length_ext; + ext_found = 1; + } else { + dur = pulse_length_pri; + pri_found = 1; + } + dfs->ath_dfs_stats.dc_phy_errors++; + } else { + if (pulse_bw_info & EXT_CH_RADAR_FOUND) { + dur = pulse_length_ext; + pri_found = 0; + ext_found = 1; + dfs->ath_dfs_stats.ext_phy_errors++; + } + if (pulse_bw_info & PRI_CH_RADAR_FOUND) { + dur = pulse_length_pri; + pri_found = 1; + ext_found = 0; + dfs->ath_dfs_stats.pri_phy_errors++; + } + if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) { + dur = pulse_length_ext; + pri_found = 0; + ext_found = 1; + early_ext = 1; + dfs->ath_dfs_stats.early_ext_phy_errors++; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "EARLY ext channel dur=%u rssi=%u datalen=%d\n", + dur, rssi, datalen); + } + if (! pulse_bw_info) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "ERROR channel dur=%u rssi=%u pulse_bw_info=0x%x " + "datalen MOD 4 = %d\n", + dur, rssi, pulse_bw_info, + (datalen & 0x3)); + /* + * Bogus bandwidth info received in descriptor, + * so ignore this PHY error + */ + dfs->ath_dfs_stats.bwinfo_errors++; + return (0); + } + } + + /* + * Always use combined RSSI reported, unless RSSI reported on + * extension is stronger + */ + if ((ext_rssi > rssi) && (ext_rssi < 128)) { + rssi = ext_rssi; + } + + /* + * Fill out the rssi/duration fields from above. + */ + OS_MEMSET(e, 0, sizeof(*e)); + e->rssi = rssi; + e->dur = dur; + e->is_pri = pri_found; + e->is_ext = ext_found; + e->is_dc = !! (((pulse_bw_info & EXT_CH_RADAR_FOUND) && + (pulse_bw_info & PRI_CH_RADAR_FOUND))); + e->is_early = early_ext; + e->fulltsf = fulltsf; + e->rs_tstamp = rs_tstamp; + + /* + * Sowl and later can report pri/ext events. + */ + event_width = dfs_get_event_freqwidth(dfs); + e->freq = + dfs_get_event_freqcentre(dfs, e->is_pri, e->is_ext, e->is_dc) + * 1000; + e->freq_lo = e->freq - (event_width / 2) * 1000; + e->freq_hi = e->freq + (event_width / 2) * 1000; + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM, + "%s: pulse_bw_info=0x%x pulse_length_ext=%u pulse_length_pri=%u " + "rssi=%u ext_rssi=%u, freq=%d MHz, freq_lo=%d MHz, " + "freq_hi=%d MHz\n", + __func__, + pulse_bw_info, + pulse_length_ext, + pulse_length_pri, + rssi, + ext_rssi, + e->freq / 1000, + e->freq_lo / 1000, + e->freq_hi / 1000); + + return (1); +} + +/* + * Process a Merlin/Osprey style phy error. + */ +int +dfs_process_phyerr_merlin(struct ath_dfs *dfs, void *buf, + u_int16_t datalen, u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, + u_int64_t fulltsf, struct dfs_phy_err *e) +{ + const char *cbuf = (const char *) buf; + u_int8_t pulse_bw_info = 0; + + /* + * Process using the sowl code + */ + if (! dfs_process_phyerr_sowl(dfs, buf, datalen, rssi, ext_rssi, + rs_tstamp, fulltsf, e)) { + return (0); + } + + /* + * For osprey (and Merlin) bw_info has implication for selecting + * RSSI value. So re-fetch the bw_info field so the RSSI values + * can be appropriately overridden. + */ + pulse_bw_info = cbuf[datalen - 1]; + + switch (pulse_bw_info & 0x03) { + case 0x00: + /* No radar in ctrl or ext channel */ + rssi = 0; + break; + case 0x01: + /* radar in ctrl channel */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "RAW RSSI: rssi=%u ext_rssi=%u\n", + rssi, ext_rssi); + if (ext_rssi >= (rssi + 3)) { + /* + * cannot use ctrl channel RSSI if + * extension channel is stronger + */ + rssi = 0; + } + break; + case 0x02: + /* radar in extension channel */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "RAW RSSI: rssi=%u ext_rssi=%u\n", + rssi, ext_rssi); + if (rssi >= (ext_rssi + 12)) { + /* + * cannot use extension channel RSSI if control channel + * is stronger + */ + rssi = 0; + } else { + rssi = ext_rssi; + } + break; + case 0x03: + /* when both are present use stronger one */ + if (rssi < ext_rssi) { + rssi = ext_rssi; + } + break; + } + + /* + * Override the rssi decision made by the sowl code. + * The rest of the fields (duration, timestamp, etc) + * are left untouched. + */ + e->rssi = rssi; + + return(1); +} + +static void +dump_phyerr_contents(const char *d, int len) +{ +#ifdef CONFIG_ENABLE_DUMP_PHYERR_CONTENTS + int i, n, bufsize = 64; + + /* + * This is statically sized for a 4-digit address + 16 * 2 digit + * data string. + * + * It's done so the printk() passed to the kernel is an entire + * line, so the kernel logging code will atomically print it. + * Otherwise we'll end up with interleaved lines with output + * from other kernel threads. + */ + char buf[64]; + + /* Initial conditions */ + buf[0] = '\n'; + n = 0; + + for (i = 0; i < len; i++) { + if (i % 16 == 0) { + n += snprintf(buf + n, bufsize - n, + "%04x: ", i); + } + n += snprintf(buf + n, bufsize - n, "%02x ", d[i] & 0xff); + if (i % 16 == 15) { + n = 0; + buf[0] = '\0'; + } + } + + /* + * Print the final line if we didn't print it above. + */ + if (n != 0) + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s: %s\n", __func__, buf); +#endif /* def CONFIG_ENABLE_DUMP_PHYERR_CONTENTS */ +} + +void +dfs_process_phyerr(struct ieee80211com *ic, void *buf, u_int16_t datalen, + u_int8_t r_rssi, u_int8_t r_ext_rssi, u_int32_t r_rs_tstamp, + u_int64_t r_fulltsf) +{ + struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; + struct ieee80211_channel *chan=ic->ic_curchan; + struct dfs_event *event; + struct dfs_phy_err e; + int empty; + + if (dfs == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: sc_dfs is NULL\n", __func__); + return; + } + + dfs->dfs_phyerr_count++; + dump_phyerr_contents(buf, datalen); + /* + * XXX The combined_rssi_ok support has been removed. + * This was only clear for Owl. + * + * XXX TODO: re-add this; it requires passing in the ctl/ext + * RSSI set from the RX status descriptor. + * + * XXX TODO TODO: this may be done for us from the legacy + * phy error path in ath_dev; please review that code. + */ + + /* + * At this time we have a radar pulse that we need to examine and + * queue. But if dfs_process_radarevent already detected radar and set + * CHANNEL_INTERFERENCE flag then do not queue any more radar data. + * When we are in a new channel this flag will be clear and we will + * start queueing data for new channel. (EV74162) + */ + if (dfs->dfs_debug_mask & ATH_DEBUG_DFS_PHYERR_PKT) + dump_phyerr_contents(buf, datalen); + + if (chan == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: chan is NULL\n", __func__); + return; + } + + if (IEEE80211_IS_CHAN_RADAR(chan)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: Radar already found in the channel, " + " do not queue radar data\n", + __func__); + return; + } + + dfs->ath_dfs_stats.total_phy_errors++; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "%s[%d] phyerr %d len %d\n", + __func__, __LINE__, + dfs->ath_dfs_stats.total_phy_errors, datalen); + + /* + * hardware stores this as 8 bit signed value. + * we will cap it at 0 if it is a negative number + */ + if (r_rssi & 0x80) + r_rssi = 0; + + if (r_ext_rssi & 0x80) + r_ext_rssi = 0; + + OS_MEMSET(&e, 0, sizeof(e)); + + /* + * This is a bit evil - instead of just passing in + * the chip version, the existing code uses a set + * of HAL capability bits to determine what is + * possible. + * + * The way I'm decoding it is thus: + * + * + DFS enhancement? Merlin or later + * + DFS extension channel? Sowl or later. (Howl?) + * + otherwise, Owl (and legacy.) + */ + if (dfs->dfs_caps.ath_chip_is_bb_tlv) { + if (dfs_process_phyerr_bb_tlv(dfs, buf, datalen, r_rssi, + r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0) { + dfs->dfs_phyerr_reject_count++; + return; + } else { + if (dfs->dfs_phyerr_freq_min > e.freq) + dfs->dfs_phyerr_freq_min = e. freq; + + if (dfs->dfs_phyerr_freq_max < e.freq) + dfs->dfs_phyerr_freq_max = e. freq; + } + } else if (dfs->dfs_caps.ath_dfs_use_enhancement) { + if (dfs_process_phyerr_merlin(dfs, buf, datalen, r_rssi, + r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){ + return; + } + } else if (dfs->dfs_caps.ath_dfs_ext_chan_ok) { + if (dfs_process_phyerr_sowl(dfs, buf, datalen, r_rssi, + r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){ + return; + } + } else { + if (dfs_process_phyerr_owl(dfs, buf, datalen, r_rssi, + r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){ + return; + } + } + + /* + * If the hardware supports radar reporting on the extension channel + * it will supply FFT data for longer radar pulses. + * + * TLV chips don't go through this software check - the hardware + * check should be enough. If we want to do software checking + * later on then someone will have to craft an FFT parser + * suitable for the TLV FFT data format. + */ + if ((! dfs->dfs_caps.ath_chip_is_bb_tlv) && + dfs->dfs_caps.ath_dfs_ext_chan_ok) { + /* + * HW has a known issue with chirping pulses injected at or + * around DC in 40MHz mode. Such pulses are reported with + * much lower durations and SW then discards them because + * they do not fit the minimum bin5 pulse duration. + * + * To work around this issue, if a pulse is within a 10us + * range of the bin5 min duration, check if the pulse is + * chirping. If the pulse is chirping, bump up the duration + * to the minimum bin5 duration. + * + * This makes sure that a valid chirping pulse will not be + * discarded because of incorrect low duration. + * + * TBD - Is it possible to calculate the 'real' duration of + * the pulse using the slope of the FFT data? + * + * TBD - Use FFT data to differentiate between radar pulses + * and false PHY errors. + * This will let us reduce the number of false alarms seen. + * + * BIN 5 chirping pulses are only for FCC or Japan MMK4 domain + */ + if (((dfs->dfsdomain == DFS_FCC_DOMAIN) || + (dfs->dfsdomain == DFS_MKK4_DOMAIN)) && + (e.dur >= MAYBE_BIN5_DUR) && (e.dur < MAX_BIN5_DUR)) { + int add_dur; + int slope = 0, dc_found = 0; + + /* + * Set the event chirping flags; as we're doing + * an actual chirp check. + */ + e.do_check_chirp = 1; + e.is_hw_chirp = 0; + e.is_sw_chirp = 0; + + /* + * dfs_check_chirping() expects is_pri and is_ext + * to be '1' for true and '0' for false for now, + * as the function itself uses these values in + * constructing things rather than testing them + * for 'true' or 'false'. + */ + add_dur = dfs_check_chirping(dfs, buf, datalen, + (e.is_pri ? 1 : 0), + (e.is_ext ? 1 : 0), + &slope, &dc_found); + if (add_dur) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "old dur %d slope =%d\n", e.dur, slope); + e.is_sw_chirp = 1; + // bump up to a random bin5 pulse duration + if (e.dur < MIN_BIN5_DUR) { + e.dur = dfs_get_random_bin5_dur(dfs, + e.fulltsf); + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "new dur %d\n", e.dur); + } else { + /* set the duration so that it is rejected */ + e.is_sw_chirp = 0; + e.dur = MAX_BIN5_DUR + 100; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "is_chirping = %d dur=%d \n", + add_dur, e.dur); + } + } else { + /* + * We have a pulse that is either bigger than + * MAX_BIN5_DUR or * less than MAYBE_BIN5_DUR + */ + if ((dfs->dfsdomain == DFS_FCC_DOMAIN) || + (dfs->dfsdomain == DFS_MKK4_DOMAIN)) { + /* + * XXX Would this result in very large pulses + * wrapping around to become short pulses? + */ + if (e.dur >= MAX_BIN5_DUR) { + /* + * set the duration so that it is + * rejected + */ + e.dur = MAX_BIN5_DUR + 50; + } + } + } + } + + /* + * Add the parsed, checked and filtered entry to the radar pulse + * event list. This is then checked by dfs_radar_processevent(). + * + * XXX TODO: some filtering is still done below this point - fix + * XXX this! + */ + ATH_DFSEVENTQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_eventq)); + ATH_DFSEVENTQ_UNLOCK(dfs); + if (empty) { + return; + } + + /* + * If the channel is a turbo G channel, then the event is + * for the adaptive radio (AR) pattern matching rather than + * radar detection. + */ + if ((chan->ic_flags & CHANNEL_108G) == CHANNEL_108G) { + if (!(dfs->dfs_proc_phyerr & DFS_AR_EN)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "%s: DFS_AR_EN not enabled\n", + __func__); + return; + } + ATH_DFSEVENTQ_LOCK(dfs); + event = STAILQ_FIRST(&(dfs->dfs_eventq)); + if (event == NULL) { + ATH_DFSEVENTQ_UNLOCK(dfs); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: no more events space left\n", + __func__); + return; + } + STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list); + ATH_DFSEVENTQ_UNLOCK(dfs); + event->re_rssi = e.rssi; + event->re_dur = e.dur; + event->re_full_ts = e.fulltsf; + event->re_ts = (e.rs_tstamp) & DFS_TSMASK; + event->re_chanindex = dfs->dfs_curchan_radindex; + event->re_flags = 0; + event->sidx = e.sidx; + + /* + * Handle chirp flags. + */ + if (e.do_check_chirp) { + event->re_flags |= DFS_EVENT_CHECKCHIRP; + if (e.is_hw_chirp) + event->re_flags |= DFS_EVENT_HW_CHIRP; + if (e.is_sw_chirp) + event->re_flags |= DFS_EVENT_SW_CHIRP; + } + + ATH_ARQ_LOCK(dfs); + STAILQ_INSERT_TAIL(&(dfs->dfs_arq), event, re_list); + ATH_ARQ_UNLOCK(dfs); + } else { + if (IEEE80211_IS_CHAN_DFS(chan)) { + if (!(dfs->dfs_proc_phyerr & DFS_RADAR_EN)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, + "%s: DFS_RADAR_EN not enabled\n", + __func__); + return; + } + /* + * rssi is not accurate for short pulses, so do + * not filter based on that for short duration pulses + * + * XXX do this filtering above? + */ + if (dfs->dfs_caps.ath_dfs_ext_chan_ok) { + if ((e.rssi < dfs->dfs_rinfo.rn_minrssithresh && + (e.dur > 4)) || + e.dur > (dfs->dfs_rinfo.rn_maxpulsedur) ) { + dfs->ath_dfs_stats.rssi_discards++; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "Extension channel pulse is " + "discarded: dur=%d, " + "maxpulsedur=%d, rssi=%d, " + "minrssi=%d\n", + e.dur, + dfs->dfs_rinfo.rn_maxpulsedur, + e.rssi, + dfs->dfs_rinfo.rn_minrssithresh); + return; + } + } else { + if (e.rssi < dfs->dfs_rinfo.rn_minrssithresh || + e.dur > dfs->dfs_rinfo.rn_maxpulsedur) { + /* XXX TODO add a debug statement? */ + dfs->ath_dfs_stats.rssi_discards++; + return; + } + } + + /* + * Add the event to the list, if there's space. + */ + ATH_DFSEVENTQ_LOCK(dfs); + event = STAILQ_FIRST(&(dfs->dfs_eventq)); + if (event == NULL) { + ATH_DFSEVENTQ_UNLOCK(dfs); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, + "%s: no more events space left\n", + __func__); + return; + } + STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list); + ATH_DFSEVENTQ_UNLOCK(dfs); + + dfs->dfs_phyerr_queued_count++; + dfs->dfs_phyerr_w53_counter++; + + event->re_dur = e.dur; + event->re_full_ts = e.fulltsf; + event->re_ts = (e.rs_tstamp) & DFS_TSMASK; + event->re_rssi = e.rssi; + event->sidx = e.sidx; + + /* + * Handle chirp flags. + */ + if (e.do_check_chirp) { + event->re_flags |= DFS_EVENT_CHECKCHIRP; + if (e.is_hw_chirp) + event->re_flags |= DFS_EVENT_HW_CHIRP; + if (e.is_sw_chirp) + event->re_flags |= DFS_EVENT_SW_CHIRP; + } + + /* + * Correctly set which channel is being reported on + */ + if (e.is_pri) { + event->re_chanindex = dfs->dfs_curchan_radindex; + } else { + if (dfs->dfs_extchan_radindex == -1) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s - phyerr on ext channel\n", __func__); + } + event->re_chanindex = dfs->dfs_extchan_radindex; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, + "%s New extension channel event is added " + "to queue\n",__func__); + } + ATH_DFSQ_LOCK(dfs); + STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list); + ATH_DFSQ_UNLOCK(dfs); + } + } + + /* + * Schedule the radar/AR task as appropriate. + * + * XXX isn't a lock needed for ath_radar_tasksched? + */ + +/* +* Commenting out the dfs_process_ar_event() since the function is never +* called at run time as dfs_arq will be empty and the function +* dfs_process_ar_event is obsolete and function definition is removed +* as part of dfs_ar.c file +* +* if (!STAILQ_EMPTY(&dfs->dfs_arq)) +* // XXX shouldn't this be a task/timer too? +* dfs_process_ar_event(dfs, ic->ic_curchan); +*/ + + if (!STAILQ_EMPTY(&dfs->dfs_radarq) && !dfs->ath_radar_tasksched) { + dfs->ath_radar_tasksched = 1; + OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0); + } +#undef EXT_CH_RADAR_FOUND +#undef PRI_CH_RADAR_FOUND +#undef EXT_CH_RADAR_EARLY_FOUND +} +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_radarevent.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_radarevent.c new file mode 100644 index 0000000000000..1bb758d461a9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_process_radarevent.c @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_radarevent.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifdef ATH_SUPPORT_DFS + +#define FREQ_5500_MHZ 5500 +#define FREQ_5500_MHZ 5500 + +#define DFS_MAX_FREQ_SPREAD 1375 * 1 + +static char debug_dup[33]; +static int debug_dup_cnt; + +/* + * Convert the hardware provided duration to TSF ticks (usecs) + * taking the clock (fast or normal) into account. + * + * Legacy (pre-11n, Owl, Sowl, Howl) operate 5GHz using a 40MHz + * clock. Later 11n chips (Merlin, Osprey, etc) operate 5GHz using + * a 44MHz clock, so the reported pulse durations are different. + * + * Peregrine reports the pulse duration in microseconds regardless + * of the operating mode. (XXX TODO: verify this, obviously.) + */ +static inline u_int8_t +dfs_process_pulse_dur(struct ath_dfs *dfs, u_int8_t re_dur) +{ + /* + * Short pulses are sometimes returned as having a duration of 0, + * so round those up to 1. + * + * XXX This holds true for BB TLV chips too, right? + */ + if (re_dur == 0) + return 1; + + /* + * For BB TLV chips, the hardware always returns microsecond + * pulse durations. + */ + if (dfs->dfs_caps.ath_chip_is_bb_tlv) + return re_dur; + + /* + * This is for 11n and legacy chips, which may or may not + * use the 5GHz fast clock mode. + */ + /* Convert 0.8us durations to TSF ticks (usecs) */ + return (u_int8_t)dfs_round((int32_t)((dfs->dur_multiplier)*re_dur)); +} + +/* + * Process a radar event. + * + * If a radar event is found, return 1. Otherwise, return 0. + * + * There is currently no way to specify that a radar event has occured on + * a specific channel, so the current methodology is to mark both the pri + * and ext channels as being unavailable. This should be fixed for 802.11ac + * or we'll quickly run out of valid channels to use. + */ +int +dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan) +{ +//commenting for now to validate radar indication msg to SAP +//#if 0 + struct dfs_event re,*event; + struct dfs_state *rs=NULL; + struct dfs_filtertype *ft; + struct dfs_filter *rf; + int found, retval = 0, p, empty; + int events_processed = 0; + u_int32_t tabledepth, index; + u_int64_t deltafull_ts = 0, this_ts, deltaT; + struct ieee80211_channel *thischan; + struct dfs_pulseline *pl; + static u_int32_t test_ts = 0; + static u_int32_t diff_ts = 0; + int ext_chan_event_flag = 0; +#if 0 + int pri_multiplier = 2; +#endif + int i; + + if (dfs == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s[%d]: dfs is NULL", __func__, __LINE__); + return 0; + } + pl = dfs->pulses; + if ( !(IEEE80211_IS_CHAN_DFS(dfs->ic->ic_curchan))) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: radar event on non-DFS chan", + __func__); + dfs_reset_radarq(dfs); + dfs_reset_alldelaylines(dfs); + return 0; + } +#ifndef ATH_DFS_RADAR_DETECTION_ONLY + /* TEST : Simulate radar bang, make sure we add the channel to NOL (bug 29968) */ + if (dfs->dfs_bangradar) { + /* bangradar will always simulate radar found on the primary channel */ + rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex]; + dfs->dfs_bangradar = 0; /* reset */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: bangradar", __func__); + retval = 1; + goto dfsfound; + } +#endif + + /* + The HW may miss some pulses especially with high channel loading. + This is true for Japan W53 where channel loaoding is 50%. Also + for ETSI where channel loading is 30% this can be an issue too. + To take care of missing pulses, we introduce pri_margin multiplie. + This is normally 2 but can be higher for W53. + */ + + if ((dfs->dfsdomain == DFS_MKK4_DOMAIN) && + (dfs->dfs_caps.ath_chip_is_bb_tlv) && + (chan->ic_freq < FREQ_5500_MHZ)) { + + dfs->dfs_pri_multiplier = dfs->dfs_pri_multiplier_ini; + + /* do not process W53 pulses, + unless we have a minimum number of them + */ + if (dfs->dfs_phyerr_w53_counter >= 5) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: w53_counter=%d, freq_max=%d, " + "freq_min=%d, pri_multiplier=%d", + __func__, + dfs->dfs_phyerr_w53_counter, + dfs->dfs_phyerr_freq_max, + dfs->dfs_phyerr_freq_min, + dfs->dfs_pri_multiplier); + dfs->dfs_phyerr_freq_min = 0x7fffffff; + dfs->dfs_phyerr_freq_max = 0; + } else { + return 0; + } + } + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "%s: pri_multiplier=%d", + __func__, + dfs->dfs_pri_multiplier); + + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + + while ((!empty) && (!retval) && (events_processed < MAX_EVENTS)) { + ATH_DFSQ_LOCK(dfs); + event = STAILQ_FIRST(&(dfs->dfs_radarq)); + if (event != NULL) + STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list); + ATH_DFSQ_UNLOCK(dfs); + + if (event == NULL) { + empty = 1; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "%s[%d]: event is NULL ",__func__,__LINE__); + break; + } + events_processed++; + re = *event; + + OS_MEMZERO(event, sizeof(struct dfs_event)); + ATH_DFSEVENTQ_LOCK(dfs); + STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list); + ATH_DFSEVENTQ_UNLOCK(dfs); + + found = 0; + if (re.re_chanindex < DFS_NUM_RADAR_STATES) + rs = &dfs->dfs_radar[re.re_chanindex]; + else { + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + continue; + } + if (rs->rs_chan.ic_flagext & CHANNEL_INTERFERENCE) { + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + continue; + } + + if (dfs->dfs_rinfo.rn_lastfull_ts == 0) { + /* + * Either not started, or 64-bit rollover exactly to zero + * Just prepend zeros to the 15-bit ts + */ + dfs->dfs_rinfo.rn_ts_prefix = 0; + } else { + /* WAR 23031- patch duplicate ts on very short pulses */ + /* This pacth has two problems in linux environment. + * 1)The time stamp created and hence PRI depends entirely on the latency. + * If the latency is high, it possibly can split two consecutive + * pulses in the same burst so far away (the same amount of latency) + * that make them look like they are from differenct bursts. It is + * observed to happen too often. It sure makes the detection fail. + * 2)Even if the latency is not that bad, it simply shifts the duplicate + * timestamps to a new duplicate timestamp based on how they are processed. + * This is not worse but not good either. + * + * Take this pulse as a good one and create a probable PRI later + */ + if (re.re_dur == 0 && re.re_ts == dfs->dfs_rinfo.rn_last_unique_ts) { + debug_dup[debug_dup_cnt++] = '1'; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, " %s deltaT is 0 ", __func__); + } else { + dfs->dfs_rinfo.rn_last_unique_ts = re.re_ts; + debug_dup[debug_dup_cnt++] = '0'; + } + if (debug_dup_cnt >= 32){ + debug_dup_cnt = 0; + } + + + if (re.re_ts <= dfs->dfs_rinfo.rn_last_ts) { + dfs->dfs_rinfo.rn_ts_prefix += + (((u_int64_t) 1) << DFS_TSSHIFT); + /* Now, see if it's been more than 1 wrap */ + deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts; + if (deltafull_ts > + ((u_int64_t)((DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts))) + deltafull_ts -= (DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts; + deltafull_ts = deltafull_ts >> DFS_TSSHIFT; + if (deltafull_ts > 1) { + dfs->dfs_rinfo.rn_ts_prefix += + ((deltafull_ts - 1) << DFS_TSSHIFT); + } + } else { + deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts; + if (deltafull_ts > (u_int64_t) DFS_TSMASK) { + deltafull_ts = deltafull_ts >> DFS_TSSHIFT; + dfs->dfs_rinfo.rn_ts_prefix += + ((deltafull_ts - 1) << DFS_TSSHIFT); + } + } + } + /* + * At this stage rn_ts_prefix has either been blanked or + * calculated, so it's safe to use. + */ + this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((u_int64_t) re.re_ts); + dfs->dfs_rinfo.rn_lastfull_ts = re.re_full_ts; + dfs->dfs_rinfo.rn_last_ts = re.re_ts; + + /* + * The hardware returns the duration in a variety of formats, + * so it's converted from the hardware format to TSF (usec) + * values here. + * + * XXX TODO: this should really be done when the PHY error + * is processed, rather than way out here.. + */ + re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur); + + /* + * Calculate the start of the radar pulse. + * + * The TSF is stamped by the MAC upon reception of the + * event, which is (typically?) at the end of the event. + * But the pattern matching code expects the event timestamps + * to be at the start of the event. So to fake it, we + * subtract the pulse duration from the given TSF. + * + * This is done after the 64-bit timestamp has been calculated + * so long pulses correctly under-wrap the counter. Ie, if + * this was done on the 32 (or 15!) bit TSF when the TSF + * value is closed to 0, it will underflow to 0xfffffXX, which + * would mess up the logical "OR" operation done above. + * + * This isn't valid for Peregrine as the hardware gives us + * the actual TSF offset of the radar event, not just the MAC + * TSF of the completed receive. + * + * XXX TODO: ensure that the TLV PHY error processing + * code will correctly calculate the TSF to be the start + * of the radar pulse. + * + * XXX TODO TODO: modify the TLV parsing code to subtract + * the duration from the TSF, based on the current fast clock + * value. + */ + if ((! dfs->dfs_caps.ath_chip_is_bb_tlv) && re.re_dur != 1) { + this_ts -= re.re_dur; + } + + /* Save the pulse parameters in the pulse buffer(pulse line) */ + index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK; + if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE) + pl->pl_firstelem = (pl->pl_firstelem+1) & DFS_MAX_PULSE_BUFFER_MASK; + else + pl->pl_numelems++; + pl->pl_lastelem = index; + pl->pl_elems[index].p_time = this_ts; + pl->pl_elems[index].p_dur = re.re_dur; + pl->pl_elems[index].p_rssi = re.re_rssi; + diff_ts = (u_int32_t)this_ts - test_ts; + test_ts = (u_int32_t)this_ts; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,"ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu",(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time); + if (dfs->dfs_event_log_on) { + i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE; + dfs->radar_log[i].ts = this_ts; + dfs->radar_log[i].diff_ts = diff_ts; + dfs->radar_log[i].rssi = re.re_rssi; + dfs->radar_log[i].dur = re.re_dur; + dfs->dfs_event_log_count++; + } + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx",__func__,__LINE__,(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time); + + + + /* If diff_ts is very small, we might be getting false pulse detects + * due to heavy interference. We might be getting spectral splatter + * from adjacent channel. In order to prevent false alarms we + * clear the delay-lines. This might impact positive detections under + * harsh environments, but helps with false detects. */ + + if (diff_ts < 100) { + dfs_reset_alldelaylines(dfs); + dfs_reset_radarq(dfs); + } + + found = 0; + + /* + * Use this fix only when device is not in test mode, as + * it drops some valid phyerrors. + * In FCC or JAPAN domain,if the follwing signature matches + * its likely that this is a false radar pulse pattern + * so process the next pulse in the queue. + */ + if ((dfs->disable_dfs_ch_switch == VOS_FALSE) && + (DFS_FCC_DOMAIN == dfs->dfsdomain || + DFS_MKK4_DOMAIN == dfs->dfsdomain) && + (re.re_dur >= 11 && re.re_dur <= 20) && + (diff_ts > 500 || diff_ts <= 305) && + (re.sidx == -4)) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "\n%s: Rejecting on Peak Index = %d,re.re_dur = %d,diff_ts = %d\n", + __func__,re.sidx, re.re_dur, diff_ts); + + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + continue; + } + + /* BIN5 pulses are FCC and Japan specific */ + + if ((dfs->dfsdomain == DFS_FCC_DOMAIN) || (dfs->dfsdomain == DFS_MKK4_DOMAIN)) { + for (p=0; (p < dfs->dfs_rinfo.rn_numbin5radars) && (!found); p++) { + struct dfs_bin5radars *br; + + br = &(dfs->dfs_b5radars[p]); + if (dfs_bin5_check_pulse(dfs, &re, br)) { + // This is a valid Bin5 pulse, check if it belongs to a burst + re.re_dur = dfs_retain_bin5_burst_pattern(dfs, diff_ts, re.re_dur); + // Remember our computed duration for the next pulse in the burst (if needed) + dfs->dfs_rinfo.dfs_bin5_chirp_ts = this_ts; + dfs->dfs_rinfo.dfs_last_bin5_dur = re.re_dur; + + if( dfs_bin5_addpulse(dfs, br, &re, this_ts) ) { + found |= dfs_bin5_check(dfs); + } + } else{ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_PULSE, + "%s not a BIN5 pulse (dur=%d)", + __func__, re.re_dur); + } + } + } + + if (found) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Found bin5 radar", __func__); + retval |= found; + goto dfsfound; + } + + tabledepth = 0; + rf = NULL; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1," *** chan freq (%d): ts %llu dur %u rssi %u", + rs->rs_chan.ic_freq, (unsigned long long)this_ts, re.re_dur, re.re_rssi); + + while ((tabledepth < DFS_MAX_RADAR_OVERLAP) && + ((dfs->dfs_radartable[re.re_dur])[tabledepth] != -1) && + (!retval)) { + ft = dfs->dfs_radarf[((dfs->dfs_radartable[re.re_dur])[tabledepth])]; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," ** RD (%d): ts %x dur %u rssi %u", + rs->rs_chan.ic_freq, + re.re_ts, re.re_dur, re.re_rssi); + + if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"%s : Rejecting on rssi rssi=%u thresh=%u", __func__, re.re_rssi, ft->ft_rssithresh); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: Rejecting on rssi rssi=%u thresh=%u",__func__,__LINE__,re.re_rssi, ft->ft_rssithresh); + tabledepth++; + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + continue; + } + deltaT = this_ts - ft->ft_last_ts; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)",(unsigned long long)deltaT, (unsigned long long)this_ts, (unsigned long long)ft->ft_last_ts); + if ((deltaT < ft->ft_minpri) && (deltaT !=0)){ + /* This check is for the whole filter type. Individual filters + will check this again. This is first line of filtering.*/ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: Rejecting on pri pri=%lld minpri=%u", __func__, (unsigned long long)deltaT, ft->ft_minpri); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:Rejecting on pri pri=%lld minpri=%u",__func__,__LINE__,(unsigned long long)deltaT,ft->ft_minpri); + tabledepth++; + continue; + } + for (p=0, found = 0; (pft_numfilters) && (!found); p++) { + rf = &(ft->ft_filters[p]); + if ((re.re_dur >= rf->rf_mindur) && (re.re_dur <= rf->rf_maxdur)) { + /* The above check is probably not necessary */ + deltaT = (this_ts < rf->rf_dl.dl_last_ts) ? + (int64_t) ((DFS_TSF_WRAP - rf->rf_dl.dl_last_ts) + this_ts + 1) : + this_ts - rf->rf_dl.dl_last_ts; + + if ((deltaT < rf->rf_minpri) && (deltaT != 0)) { + /* Second line of PRI filtering. */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u", + rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:filterID= %d::Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); + continue; + } + + if (rf->rf_ignore_pri_window > 0) { + if (deltaT < rf->rf_minpri) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", + rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); + /* But update the last time stamp */ + rf->rf_dl.dl_last_ts = this_ts; + continue; + } + } else { + + /* + The HW may miss some pulses especially with high channel loading. + This is true for Japan W53 where channel loaoding is 50%. Also + for ETSI where channel loading is 30% this can be an issue too. + To take care of missing pulses, we introduce pri_margin multiplie. + This is normally 2 but can be higher for W53. + */ + + if ( (deltaT > (dfs->dfs_pri_multiplier * rf->rf_maxpri) ) || (deltaT < rf->rf_minpri) ) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u", + rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); +VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri); + /* But update the last time stamp */ + rf->rf_dl.dl_last_ts = this_ts; + continue; + } + } + dfs_add_pulse(dfs, rf, &re, deltaT, this_ts); + + + /* If this is an extension channel event, flag it for false alarm reduction */ + if (re.re_chanindex == dfs->dfs_extchan_radindex) { + ext_chan_event_flag = 1; + } + if (rf->rf_patterntype == 2) { + found = dfs_staggered_check(dfs, rf, (u_int32_t) deltaT, re.re_dur); + } else { + found = dfs_bin_check(dfs, rf, (u_int32_t) deltaT, re.re_dur, ext_chan_event_flag); + } + if (dfs->dfs_debug_mask & ATH_DEBUG_DFS2) { + dfs_print_delayline(dfs, &rf->rf_dl); + } + rf->rf_dl.dl_last_ts = this_ts; + } + } + ft->ft_last_ts = this_ts; + retval |= found; + if (found) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, + "Found on channel minDur = %d, filterId = %d",ft->ft_mindur, + rf != NULL ? rf->rf_pulseid : -1); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s[%d]:### Found on channel minDur = %d, filterId = %d ###", + __func__,__LINE__,ft->ft_mindur, + rf != NULL ? rf->rf_pulseid : -1); + } + tabledepth++; + } + ATH_DFSQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); + ATH_DFSQ_UNLOCK(dfs); + } +dfsfound: + if (retval) { + /* Collect stats */ + dfs->ath_dfs_stats.num_radar_detects++; + thischan = &rs->rs_chan; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "%s[%d]: ### RADAR FOUND ON CHANNEL %d (%d MHz) ###",__func__,__LINE__,thischan->ic_ieee, +thischan->ic_freq); + DFS_PRINTK("Radar found on channel %d (%d MHz)", + thischan->ic_ieee, + thischan->ic_freq); + +#if 0 //UMACDFS : TODO + /* Disable radar for now */ + rfilt = ath_hal_getrxfilter(ah); + rfilt &= ~HAL_RX_FILTER_PHYRADAR; + ath_hal_setrxfilter(ah, rfilt); +#endif + dfs_reset_radarq(dfs); + dfs_reset_alldelaylines(dfs); + /* XXX Should we really enable again? Maybe not... */ +/* No reason to re-enable so far - Ajay*/ +#if 0 + pe.pe_firpwr = rs->rs_firpwr; + pe.pe_rrssi = rs->rs_radarrssi; + pe.pe_height = rs->rs_height; + pe.pe_prssi = rs->rs_pulserssi; + pe.pe_inband = rs->rs_inband; + /* 5413 specific */ + pe.pe_relpwr = rs->rs_relpwr; + pe.pe_relstep = rs->rs_relstep; + pe.pe_maxlen = rs->rs_maxlen; + + ath_hal_enabledfs(ah, &pe); + rfilt |= HAL_RX_FILTER_PHYRADAR; + ath_hal_setrxfilter(ah, rfilt); +#endif + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "Primary channel freq = %u flags=0x%x", + chan->ic_freq, chan->ic_flagext); + if ((dfs->ic->ic_curchan->ic_freq!= thischan->ic_freq)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "Ext channel freq = %u flags=0x%x", + thischan->ic_freq, thischan->ic_flagext); + } + dfs->dfs_phyerr_freq_min = 0x7fffffff; + dfs->dfs_phyerr_freq_max = 0; + dfs->dfs_phyerr_w53_counter = 0; + } + //VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "IN FUNC %s[%d]: retval = %d ",__func__,__LINE__,retval); + return retval; +//#endif +// return 1; +} + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_staggered.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_staggered.c new file mode 100644 index 0000000000000..23d27c4a1b0b0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/DFS/src/dfs_staggered.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + dfs_staggered.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + +#include "dfs.h" +/* TO DO DFS +#include +*/ +#ifdef ATH_SUPPORT_DFS + +static int is_pri_multiple(u_int32_t sample_pri, u_int32_t refpri) +{ +#define MAX_ALLOWED_MISSED 3 + int i; + + if (sample_pri < refpri || (!refpri)) + return 0; + + for (i=1; i<= MAX_ALLOWED_MISSED; i++) { + if((sample_pri%(i*refpri) <= 5)) { + //printk("sample_pri=%d is a multiple of refpri=%d\n", sample_pri, refpri); + return 1; + } + } + return 0; +#undef MAX_ALLOWED_MISSED +} + +static int is_unique_pri(u_int32_t highestpri , u_int32_t midpri, + u_int32_t lowestpri , u_int32_t refpri ) +{ +#define DFS_STAGGERED_PRI_MARGIN_MIN 20 +#define DFS_STAGGERED_PRI_MARGIN_MAX 400 + if ((DFS_DIFF(lowestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && + (DFS_DIFF(midpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) && + (DFS_DIFF(highestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN)) { + return 1; + } else { + if ((is_pri_multiple(refpri, highestpri)) || (is_pri_multiple(refpri, lowestpri)) || + (is_pri_multiple(refpri, midpri))) + return 0; + } + return 0; +#undef DFS_STAGGERED_PRI_MARGIN_MIN +#undef DFS_STAGGERED_PRI_MARGIN_MAX +} + + +int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf, + u_int32_t deltaT, u_int32_t width) +{ + u_int32_t refpri, refdur, searchpri=0, deltapri;//, averagerefpri; + u_int32_t n, i, primargin, durmargin; + int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0; + struct dfs_delayline *dl; + u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff; +#if 0 + int numpulses=0; +#endif + int higherthan, lowerthan, numscores; + int numpulseshigh=0, numpulsesmid=0, numpulsestemp=0; + u_int32_t lowestscore=0, lowestscoreindex=0, lowestpri=0; + u_int32_t midscore=0, midscoreindex=0, midpri=0; + u_int32_t highestscore=0, highestscoreindex=0, highestpri=0; + + dl = &rf->rf_dl; + if( dl->dl_numelems < (rf->rf_threshold-1)) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "numelems %d < threshold for filter %d\n", + dl->dl_numelems, rf->rf_pulseid); + return 0; + } + if( deltaT > rf->rf_filterlen) { + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "numelems %d < threshold for filter %d\n", + dl->dl_numelems, rf->rf_pulseid); + return 0; + } + primargin = 6; + if(rf->rf_maxdur < 10) { + durmargin = 4; + } + else { + durmargin = 6; + } + + OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE); + /* find out the lowest pri */ + for (n=0;ndl_numelems; n++) { + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refpri = dl->dl_elems[delayindex].de_time; + if( refpri == 0) + continue; + else if(refpri < lowpri) { + lowpri = dl->dl_elems[delayindex].de_time; + lowpriindex = n; + } + } + /* find out the each delay element's pri score */ + for (n=0;ndl_numelems; n++) { + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refpri = dl->dl_elems[delayindex].de_time; + if( refpri == 0) { + continue; + } + + if ( (refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri) ) { + score[n] = 0; + continue; + } + + for (i=0;idl_numelems; i++) { + dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK; + searchpri = dl->dl_elems[dindex].de_time; + deltapri = DFS_DIFF(searchpri, refpri); + if( deltapri < primargin) + score[n]++; + } + } + for (n=0;ndl_numelems; n++) { + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refdur = dl->dl_elems[delayindex].de_time; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "score[%d]=%d pri=%d\n", n, score[n], refdur); + } + + /* find out the 2 or 3 highest scorers */ + scoreindex = 0; + highestscore=0; + highestscoreindex=0; + highestpri=0; numscores=0; lowestscore=0; + + for (n=0;ndl_numelems; n++) { + higherthan=0; + lowerthan=0; + delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK; + refpri = dl->dl_elems[delayindex].de_time; + + if ((score[n] >= highestscore) && + (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { + lowestscore = midscore; + lowestpri = midpri; + lowestscoreindex = midscoreindex; + midscore = highestscore; + midpri = highestpri; + midscoreindex = highestscoreindex; + highestscore = score[n]; + highestpri = refpri; + highestscoreindex = n; + } else { + if ((score[n] >= midscore) && + (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { + lowestscore = midscore; + lowestpri = midpri; + lowestscoreindex = midscoreindex; + midscore = score[n]; + midpri = refpri; + midscoreindex = n; + } else if ((score[n] >= lowestscore) && + (is_unique_pri(highestpri, midpri, lowestpri, refpri))) { + lowestscore = score[n]; + lowestpri = refpri; + lowestscoreindex = n; + } + } + + } + + if (midscore == 0) { + // This means we have only 1 pulse type. It can not be staggered! + return 0; + } + + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "FINAL highestscore=%d highestscoreindex=%d highestpri=%d\n", + highestscore, highestscoreindex, highestpri); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "FINAL lowestscore=%d lowestscoreindex=%d lowpri=%d\n", + lowestscore, lowestscoreindex, lowestpri); + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "FINAL midscore=%d midscoreindex=%d midpri=%d\n", + midscore, midscoreindex, midpri); + + + delayindex = (dl->dl_firstelem + highestscoreindex) & DFS_MAX_DL_MASK; + refdur = dl->dl_elems[delayindex].de_dur; + refpri = dl->dl_elems[delayindex].de_time; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "highscoreindex=%d refdur=%d refpri=%d\n", + highestscoreindex, refdur, refpri); + + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri); + numpulseshigh = numpulsestemp; + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri + midpri); + if (numpulsestemp > numpulseshigh) { + numpulseshigh = numpulsestemp; + } + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri + midpri + lowestpri); + if (numpulsestemp > numpulseshigh) { + numpulseshigh = numpulsestemp; + } + + + delayindex = (dl->dl_firstelem + midscoreindex) & DFS_MAX_DL_MASK; + refdur = dl->dl_elems[delayindex].de_dur; + refpri = dl->dl_elems[delayindex].de_time; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, + "midscoreindex=%d refdur=%d refpri=%d\n", + midscoreindex, refdur, refpri); + + //numpulsesmid = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, 1); + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, midpri); + numpulsesmid = numpulsestemp; + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, highestpri + midpri); + if (numpulsestemp > numpulsesmid) { + numpulsesmid = numpulsestemp; + } + numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, highestpri + midpri + lowestpri); + if (numpulsestemp > numpulsesmid) { + numpulsesmid = numpulsestemp; + } + + + /*delayindex = (dl->dl_firstelem + lowestscoreindex) & DFS_MAX_DL_MASK; + refdur = dl->dl_elems[delayindex].de_dur; + refpri = dl->dl_elems[delayindex].de_time; + DFS_DPRINTK(ic, ATH_DEBUG_DFS1, "lowestscoreindex=%d refdur=%d refpri=%d\n", lowestscoreindex, refdur, refpri); + + numpulseslow = dfs_bin_pri_check(dfs, rf, dl, lowestscore, refpri, refdur,0, 1); + */ + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, + "numpulseshigh=%d, numpulsesmid=%d\n", + numpulseshigh, numpulsesmid); +// printf("numpulseshigh=%d, numpulsesmid=%d, numpulseslow %d\n",numpulseshigh, numpulsesmid, numpulseslow); + + if ( (numpulseshigh >= rf->rf_threshold) && (numpulsesmid >= rf->rf_threshold) ) { + /*if (numpulses >= rf->rf_threshold) {*/ + found = 1; + DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "MATCH filter=%u numpulseshigh=%u numpulsesmid= %u thresh=%u\n", rf->rf_pulseid, numpulseshigh, numpulsesmid, rf->rf_threshold); + } + return found; + } + +#endif /* ATH_SUPPORT_DFS */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320def.h new file mode 100644 index 0000000000000..e581735fd450b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320def.h @@ -0,0 +1,695 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320DEF_H_ +#define _AR6320DEF_H_ + +/* Base Addresses */ +#define AR6320_RTC_SOC_BASE_ADDRESS 0x00000000 +#define AR6320_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320_CE0_BASE_ADDRESS 0x00034400 +#define AR6320_CE1_BASE_ADDRESS 0x00034800 +#define AR6320_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320_CE3_BASE_ADDRESS 0x00035000 +#define AR6320_CE4_BASE_ADDRESS 0x00035400 +#define AR6320_CE5_BASE_ADDRESS 0x00035800 +#define AR6320_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320_CE7_BASE_ADDRESS 0x00036000 +#define AR6320_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320_SCRATCH_3_ADDRESS 0x0028 +#define AR6320_TARG_DRAM_START 0x00400000 +#define AR6320_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320_SI_CONFIG_I2C_LSB 16 +#define AR6320_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320_SI_CONFIG_OFFSET 0x00000000 +#define AR6320_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320_SI_CS_OFFSET 0x00000004 +#define AR6320_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320_SI_CS_START_LSB 8 +#define AR6320_SI_CS_START_MASK 0x00000100 +#define AR6320_SI_CS_RX_CNT_LSB 4 +#define AR6320_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320_SI_CS_TX_CNT_LSB 0 +#define AR6320_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320_CE_COUNT 8 +#define AR6320_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320_HOST_IS_ADDRESS 0x0030 +#define AR6320_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320_HOST_IE_ADDRESS 0x002c +#define AR6320_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_SR_BA_ADDRESS 0x0000 +#define AR6320_SR_SIZE_ADDRESS 0x0004 +#define AR6320_CE_CTRL1_ADDRESS 0x0010 +#define AR6320_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320_DR_BA_ADDRESS 0x0008 +#define AR6320_DR_SIZE_ADDRESS 0x000c +#define AR6320_MISC_IE_ADDRESS 0x0034 +#define AR6320_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320_SRC_WATERMARK_LOW_LSB 16 +#define AR6320_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320_DST_WATERMARK_LOW_LSB 16 +#define AR6320_DST_WATERMARK_HIGH_LSB 0 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320_RTC_STATE_ADDRESS 0x0000 +#define AR6320_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320_RTC_STATE_V_MASK 0x00000007 +#define AR6320_RTC_STATE_V_LSB 0 +#define AR6320_RTC_STATE_V_ON 3 +#define AR6320_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320_FW_IND_EVENT_PENDING 1 +#define AR6320_FW_IND_INITIALIZED 2 +#define AR6320_FW_IND_HELPER 4 +#define AR6320_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320_CPU_INTR_ADDRESS 0x0010 +#define AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320_CORE_CTRL_ADDRESS 0x0000 +#define AR6320_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320_SOC_CHIP_ID_REVISION_LSB 8 +#define AR6320_SOC_POWER_REG_OFFSET 0x0000010c + +/* Copy Engine Debug */ +#define AR6320_WLAN_DEBUG_INPUT_SEL_OFFSET 0x0000010c +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MSB 3 +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_LSB 0 +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MASK 0x0000000f +#define AR6320_WLAN_DEBUG_CONTROL_OFFSET 0x00000108 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_MSB 0 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_LSB 0 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_MASK 0x00000001 +#define AR6320_WLAN_DEBUG_OUT_OFFSET 0x00000110 +#define AR6320_WLAN_DEBUG_OUT_DATA_MSB 19 +#define AR6320_WLAN_DEBUG_OUT_DATA_LSB 0 +#define AR6320_WLAN_DEBUG_OUT_DATA_MASK 0x000fffff +#define AR6320_AMBA_DEBUG_BUS_OFFSET 0x0000011c +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB 13 +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB 8 +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK 0x00003f00 +#define AR6320_AMBA_DEBUG_BUS_SEL_MSB 4 +#define AR6320_AMBA_DEBUG_BUS_SEL_LSB 0 +#define AR6320_AMBA_DEBUG_BUS_SEL_MASK 0x0000001f +#define AR6320_CE_WRAPPER_DEBUG_OFFSET 0x0008 +#define AR6320_CE_WRAPPER_DEBUG_SEL_MSB 5 +#define AR6320_CE_WRAPPER_DEBUG_SEL_LSB 0 +#define AR6320_CE_WRAPPER_DEBUG_SEL_MASK 0x0000003f +#define AR6320_CE_DEBUG_OFFSET 0x0054 +#define AR6320_CE_DEBUG_SEL_MSB 5 +#define AR6320_CE_DEBUG_SEL_LSB 0 +#define AR6320_CE_DEBUG_SEL_MASK 0x0000003f +/* End */ + +/* PLL start */ +#define AR6320_EFUSE_OFFSET 0x0000032c +#define AR6320_EFUSE_XTAL_SEL_MSB 10 +#define AR6320_EFUSE_XTAL_SEL_LSB 8 +#define AR6320_EFUSE_XTAL_SEL_MASK 0x00000700 +#define AR6320_BB_PLL_CONFIG_OFFSET 0x000002f4 +#define AR6320_BB_PLL_CONFIG_OUTDIV_MSB 20 +#define AR6320_BB_PLL_CONFIG_OUTDIV_LSB 18 +#define AR6320_BB_PLL_CONFIG_OUTDIV_MASK 0x001c0000 +#define AR6320_BB_PLL_CONFIG_FRAC_MSB 17 +#define AR6320_BB_PLL_CONFIG_FRAC_LSB 0 +#define AR6320_BB_PLL_CONFIG_FRAC_MASK 0x0003ffff +#define AR6320_WLAN_PLL_SETTLE_TIME_MSB 10 +#define AR6320_WLAN_PLL_SETTLE_TIME_LSB 0 +#define AR6320_WLAN_PLL_SETTLE_TIME_MASK 0x000007ff +#define AR6320_WLAN_PLL_SETTLE_OFFSET 0x0018 +#define AR6320_WLAN_PLL_SETTLE_SW_MASK 0x000007ff +#define AR6320_WLAN_PLL_SETTLE_RSTMASK 0xffffffff +#define AR6320_WLAN_PLL_SETTLE_RESET 0x00000400 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_MSB 18 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_LSB 18 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_MSB 16 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_LSB 16 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_RESET 0x1 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_MSB 15 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_LSB 14 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_MASK 0x0000c000 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_RESET 0x0 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_MSB 13 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_LSB 10 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_MASK 0x00003c00 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_RESET 0x0 +#define AR6320_WLAN_PLL_CONTROL_DIV_MSB 9 +#define AR6320_WLAN_PLL_CONTROL_DIV_LSB 0 +#define AR6320_WLAN_PLL_CONTROL_DIV_MASK 0x000003ff +#define AR6320_WLAN_PLL_CONTROL_DIV_RESET 0x11 +#define AR6320_WLAN_PLL_CONTROL_OFFSET 0x0014 +#define AR6320_WLAN_PLL_CONTROL_SW_MASK 0x001fffff +#define AR6320_WLAN_PLL_CONTROL_RSTMASK 0xffffffff +#define AR6320_WLAN_PLL_CONTROL_RESET 0x00010011 +#define AR6320_SOC_CORE_CLK_CTRL_OFFSET 0x00000114 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_MSB 2 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_LSB 0 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MSB 5 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_LSB 5 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MASK 0x00000020 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_RESET 0x0 +#define AR6320_RTC_SYNC_STATUS_OFFSET 0x0244 +#define AR6320_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MSB 1 +#define AR6320_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +/* PLL end */ + +#define AR6320_PCIE_INTR_CE_MASK(n) (AR6320_PCIE_INTR_CE0_MASK << (n)) +#define AR6320_DRAM_BASE_ADDRESS AR6320_TARG_DRAM_START +#define AR6320_FW_INDICATOR_ADDRESS (AR6320_SOC_CORE_BASE_ADDRESS + AR6320_SCRATCH_3_ADDRESS) +#define AR6320_SYSTEM_SLEEP_OFFSET AR6320_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320_WLAN_RESET_CONTROL_OFFSET AR6320_SOC_RESET_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_OFFSET AR6320_SOC_CLOCK_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_SI0_CLK_MASK AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320_RESET_CONTROL_SI0_RST_MASK AR6320_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320_GPIO_BASE_ADDRESS AR6320_WLAN_GPIO_BASE_ADDRESS +#define AR6320_GPIO_PIN0_OFFSET AR6320_WLAN_GPIO_PIN0_ADDRESS +#define AR6320_GPIO_PIN1_OFFSET AR6320_WLAN_GPIO_PIN1_ADDRESS +#define AR6320_GPIO_PIN0_CONFIG_MASK AR6320_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320_GPIO_PIN1_CONFIG_MASK AR6320_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320_SI_BASE_ADDRESS 0x00050000 +#define AR6320_CPU_CLOCK_OFFSET AR6320_SOC_CPU_CLOCK_OFFSET +#define AR6320_LPO_CAL_OFFSET AR6320_SOC_LPO_CAL_OFFSET +#define AR6320_GPIO_PIN10_OFFSET AR6320_WLAN_GPIO_PIN10_ADDRESS +#define AR6320_GPIO_PIN11_OFFSET AR6320_WLAN_GPIO_PIN11_ADDRESS +#define AR6320_GPIO_PIN12_OFFSET AR6320_WLAN_GPIO_PIN12_ADDRESS +#define AR6320_GPIO_PIN13_OFFSET AR6320_WLAN_GPIO_PIN13_ADDRESS +#define AR6320_CPU_CLOCK_STANDARD_LSB AR6320_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320_CPU_CLOCK_STANDARD_MASK AR6320_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320_LPO_CAL_ENABLE_LSB AR6320_SOC_LPO_CAL_ENABLE_LSB +#define AR6320_LPO_CAL_ENABLE_MASK AR6320_SOC_LPO_CAL_ENABLE_MASK +#define AR6320_ANALOG_INTF_BASE_ADDRESS AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320_COUNT_DEC_ADDRESS 0x0840 +#define AR6320_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320_WINDOW_WRITE_ADDR_ADDRESS 0x0878 + +struct targetdef_s ar6320_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + .d_WLAN_DEBUG_INPUT_SEL_OFFSET = AR6320_WLAN_DEBUG_INPUT_SEL_OFFSET, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MSB = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_LSB = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_LSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MASK = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MASK, + .d_WLAN_DEBUG_CONTROL_OFFSET = AR6320_WLAN_DEBUG_CONTROL_OFFSET, + .d_WLAN_DEBUG_CONTROL_ENABLE_MSB = AR6320_WLAN_DEBUG_CONTROL_ENABLE_MSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_LSB = AR6320_WLAN_DEBUG_CONTROL_ENABLE_LSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_MASK = AR6320_WLAN_DEBUG_CONTROL_ENABLE_MASK, + .d_WLAN_DEBUG_OUT_OFFSET = AR6320_WLAN_DEBUG_OUT_OFFSET, + .d_WLAN_DEBUG_OUT_DATA_MSB = AR6320_WLAN_DEBUG_OUT_DATA_MSB, + .d_WLAN_DEBUG_OUT_DATA_LSB = AR6320_WLAN_DEBUG_OUT_DATA_LSB, + .d_WLAN_DEBUG_OUT_DATA_MASK = AR6320_WLAN_DEBUG_OUT_DATA_MASK, + .d_AMBA_DEBUG_BUS_OFFSET = AR6320_AMBA_DEBUG_BUS_OFFSET, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK, + .d_AMBA_DEBUG_BUS_SEL_MSB = AR6320_AMBA_DEBUG_BUS_SEL_MSB, + .d_AMBA_DEBUG_BUS_SEL_LSB = AR6320_AMBA_DEBUG_BUS_SEL_LSB, + .d_AMBA_DEBUG_BUS_SEL_MASK = AR6320_AMBA_DEBUG_BUS_SEL_MASK, + .d_CE_WRAPPER_DEBUG_OFFSET = AR6320_CE_WRAPPER_DEBUG_OFFSET, + .d_CE_WRAPPER_DEBUG_SEL_MSB = AR6320_CE_WRAPPER_DEBUG_SEL_MSB, + .d_CE_WRAPPER_DEBUG_SEL_LSB = AR6320_CE_WRAPPER_DEBUG_SEL_LSB, + .d_CE_WRAPPER_DEBUG_SEL_MASK = AR6320_CE_WRAPPER_DEBUG_SEL_MASK, + .d_CE_DEBUG_OFFSET = AR6320_CE_DEBUG_OFFSET, + .d_CE_DEBUG_SEL_MSB = AR6320_CE_DEBUG_SEL_MSB, + .d_CE_DEBUG_SEL_LSB = AR6320_CE_DEBUG_SEL_LSB, + .d_CE_DEBUG_SEL_MASK = AR6320_CE_DEBUG_SEL_MASK, + /* PLL start */ + .d_EFUSE_OFFSET = AR6320_EFUSE_OFFSET, + .d_EFUSE_XTAL_SEL_MSB = AR6320_EFUSE_XTAL_SEL_MSB, + .d_EFUSE_XTAL_SEL_LSB = AR6320_EFUSE_XTAL_SEL_LSB, + .d_EFUSE_XTAL_SEL_MASK = AR6320_EFUSE_XTAL_SEL_MASK, + .d_BB_PLL_CONFIG_OFFSET = AR6320_BB_PLL_CONFIG_OFFSET, + .d_BB_PLL_CONFIG_OUTDIV_MSB = AR6320_BB_PLL_CONFIG_OUTDIV_MSB, + .d_BB_PLL_CONFIG_OUTDIV_LSB = AR6320_BB_PLL_CONFIG_OUTDIV_LSB, + .d_BB_PLL_CONFIG_OUTDIV_MASK = AR6320_BB_PLL_CONFIG_OUTDIV_MASK, + .d_BB_PLL_CONFIG_FRAC_MSB = AR6320_BB_PLL_CONFIG_FRAC_MSB, + .d_BB_PLL_CONFIG_FRAC_LSB = AR6320_BB_PLL_CONFIG_FRAC_LSB, + .d_BB_PLL_CONFIG_FRAC_MASK = AR6320_BB_PLL_CONFIG_FRAC_MASK, + .d_WLAN_PLL_SETTLE_TIME_MSB = AR6320_WLAN_PLL_SETTLE_TIME_MSB, + .d_WLAN_PLL_SETTLE_TIME_LSB = AR6320_WLAN_PLL_SETTLE_TIME_LSB, + .d_WLAN_PLL_SETTLE_TIME_MASK = AR6320_WLAN_PLL_SETTLE_TIME_MASK, + .d_WLAN_PLL_SETTLE_OFFSET = AR6320_WLAN_PLL_SETTLE_OFFSET, + .d_WLAN_PLL_SETTLE_SW_MASK = AR6320_WLAN_PLL_SETTLE_SW_MASK, + .d_WLAN_PLL_SETTLE_RSTMASK = AR6320_WLAN_PLL_SETTLE_RSTMASK, + .d_WLAN_PLL_SETTLE_RESET = AR6320_WLAN_PLL_SETTLE_RESET, + .d_WLAN_PLL_CONTROL_NOPWD_MSB = AR6320_WLAN_PLL_CONTROL_NOPWD_MSB, + .d_WLAN_PLL_CONTROL_NOPWD_LSB = AR6320_WLAN_PLL_CONTROL_NOPWD_LSB, + .d_WLAN_PLL_CONTROL_NOPWD_MASK = AR6320_WLAN_PLL_CONTROL_NOPWD_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_MSB = AR6320_WLAN_PLL_CONTROL_BYPASS_MSB, + .d_WLAN_PLL_CONTROL_BYPASS_LSB = AR6320_WLAN_PLL_CONTROL_BYPASS_LSB, + .d_WLAN_PLL_CONTROL_BYPASS_MASK = AR6320_WLAN_PLL_CONTROL_BYPASS_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_RESET = AR6320_WLAN_PLL_CONTROL_BYPASS_RESET, + .d_WLAN_PLL_CONTROL_CLK_SEL_MSB = AR6320_WLAN_PLL_CONTROL_CLK_SEL_MSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_LSB = AR6320_WLAN_PLL_CONTROL_CLK_SEL_LSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_MASK = AR6320_WLAN_PLL_CONTROL_CLK_SEL_MASK, + .d_WLAN_PLL_CONTROL_CLK_SEL_RESET = AR6320_WLAN_PLL_CONTROL_CLK_SEL_RESET, + .d_WLAN_PLL_CONTROL_REFDIV_MSB = AR6320_WLAN_PLL_CONTROL_REFDIV_MSB, + .d_WLAN_PLL_CONTROL_REFDIV_LSB = AR6320_WLAN_PLL_CONTROL_REFDIV_LSB, + .d_WLAN_PLL_CONTROL_REFDIV_MASK = AR6320_WLAN_PLL_CONTROL_REFDIV_MASK, + .d_WLAN_PLL_CONTROL_REFDIV_RESET = AR6320_WLAN_PLL_CONTROL_REFDIV_RESET, + .d_WLAN_PLL_CONTROL_DIV_MSB = AR6320_WLAN_PLL_CONTROL_DIV_MSB, + .d_WLAN_PLL_CONTROL_DIV_LSB = AR6320_WLAN_PLL_CONTROL_DIV_LSB, + .d_WLAN_PLL_CONTROL_DIV_MASK = AR6320_WLAN_PLL_CONTROL_DIV_MASK, + .d_WLAN_PLL_CONTROL_DIV_RESET = AR6320_WLAN_PLL_CONTROL_DIV_RESET, + .d_WLAN_PLL_CONTROL_OFFSET = AR6320_WLAN_PLL_CONTROL_OFFSET, + .d_WLAN_PLL_CONTROL_SW_MASK = AR6320_WLAN_PLL_CONTROL_SW_MASK, + .d_WLAN_PLL_CONTROL_RSTMASK = AR6320_WLAN_PLL_CONTROL_RSTMASK, + .d_WLAN_PLL_CONTROL_RESET = AR6320_WLAN_PLL_CONTROL_RESET, + .d_SOC_CORE_CLK_CTRL_OFFSET = AR6320_SOC_CORE_CLK_CTRL_OFFSET, + .d_SOC_CORE_CLK_CTRL_DIV_MSB = AR6320_SOC_CORE_CLK_CTRL_DIV_MSB, + .d_SOC_CORE_CLK_CTRL_DIV_LSB = AR6320_SOC_CORE_CLK_CTRL_DIV_LSB, + .d_SOC_CORE_CLK_CTRL_DIV_MASK = AR6320_SOC_CORE_CLK_CTRL_DIV_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MSB = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_LSB = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_LSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MASK = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_RESET = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_RESET, + .d_RTC_SYNC_STATUS_OFFSET = AR6320_RTC_SYNC_STATUS_OFFSET, + .d_SOC_CPU_CLOCK_OFFSET = AR6320_SOC_CPU_CLOCK_OFFSET, + .d_SOC_CPU_CLOCK_STANDARD_MSB = AR6320_SOC_CPU_CLOCK_STANDARD_MSB, + .d_SOC_CPU_CLOCK_STANDARD_LSB = AR6320_SOC_CPU_CLOCK_STANDARD_LSB, + .d_SOC_CPU_CLOCK_STANDARD_MASK = AR6320_SOC_CPU_CLOCK_STANDARD_MASK, + /* PLL end */ + .d_SOC_POWER_REG_OFFSET = AR6320_SOC_POWER_REG_OFFSET, + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320_FW_IND_INITIALIZED, + .d_FW_IND_HELPER = AR6320_FW_IND_HELPER, + .d_RTC_STATE_V_ON = AR6320_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320v2def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320v2def.h new file mode 100644 index 0000000000000..d84434b7bf0de --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar6320v2def.h @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320V2DEF_H_ +#define _AR6320V2DEF_H_ + +/* Base Addresses */ +#define AR6320V2_RTC_SOC_BASE_ADDRESS 0x00000800 +#define AR6320V2_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320V2_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320V2_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320V2_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320V2_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320V2_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320V2_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320V2_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320V2_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320V2_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320V2_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320V2_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320V2_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320V2_CE0_BASE_ADDRESS 0x00034400 +#define AR6320V2_CE1_BASE_ADDRESS 0x00034800 +#define AR6320V2_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320V2_CE3_BASE_ADDRESS 0x00035000 +#define AR6320V2_CE4_BASE_ADDRESS 0x00035400 +#define AR6320V2_CE5_BASE_ADDRESS 0x00035800 +#define AR6320V2_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320V2_CE7_BASE_ADDRESS 0x00036000 +#define AR6320V2_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320V2_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320V2_SCRATCH_3_ADDRESS 0x0028 +#define AR6320V2_TARG_DRAM_START 0x00400000 +#define AR6320V2_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320V2_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320V2_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320V2_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320V2_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320V2_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320V2_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320V2_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320V2_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320V2_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320V2_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320V2_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320V2_SI_CONFIG_I2C_LSB 16 +#define AR6320V2_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320V2_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320V2_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320V2_SI_CONFIG_OFFSET 0x00000000 +#define AR6320V2_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320V2_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320V2_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320V2_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320V2_SI_CS_OFFSET 0x00000004 +#define AR6320V2_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320V2_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320V2_SI_CS_START_LSB 8 +#define AR6320V2_SI_CS_START_MASK 0x00000100 +#define AR6320V2_SI_CS_RX_CNT_LSB 4 +#define AR6320V2_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320V2_SI_CS_TX_CNT_LSB 0 +#define AR6320V2_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320V2_CE_COUNT 8 +#define AR6320V2_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320V2_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff + +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320V2_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320V2_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320V2_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320V2_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320V2_HOST_IS_ADDRESS 0x0030 +#define AR6320V2_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320V2_HOST_IE_ADDRESS 0x002c +#define AR6320V2_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_SR_BA_ADDRESS 0x0000 +#define AR6320V2_SR_SIZE_ADDRESS 0x0004 +#define AR6320V2_CE_CTRL1_ADDRESS 0x0010 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320V2_DR_BA_ADDRESS 0x0008 +#define AR6320V2_DR_SIZE_ADDRESS 0x000c +#define AR6320V2_MISC_IE_ADDRESS 0x0034 +#define AR6320V2_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320V2_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320V2_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320V2_SRC_WATERMARK_LOW_LSB 16 +#define AR6320V2_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320V2_DST_WATERMARK_LOW_LSB 16 +#define AR6320V2_DST_WATERMARK_HIGH_LSB 0 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320V2_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320V2_RTC_STATE_ADDRESS 0x0000 +#define AR6320V2_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320V2_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320V2_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320V2_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320V2_RTC_STATE_V_MASK 0x00000007 +#define AR6320V2_RTC_STATE_V_LSB 0 +#define AR6320V2_RTC_STATE_V_ON 3 +#define AR6320V2_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320V2_FW_IND_EVENT_PENDING 1 +#define AR6320V2_FW_IND_INITIALIZED 2 +#define AR6320V2_FW_IND_HELPER 4 +#define AR6320V2_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320V2_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320V2_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320V2_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320V2_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320V2_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320V2_CPU_INTR_ADDRESS 0x0010 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320V2_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320V2_CORE_CTRL_ADDRESS 0x0000 +#define AR6320V2_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320V2_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320V2_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320V2_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320V2_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320V2_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320V2_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320V2_SOC_CHIP_ID_REVISION_LSB 8 +#define AR6320V2_SOC_POWER_REG_OFFSET 0x0000010c + +/* Copy Engine Debug */ +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_OFFSET 0x0000010c +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MSB 3 +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_LSB 0 +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MASK 0x0000000f +#define AR6320V2_WLAN_DEBUG_CONTROL_OFFSET 0x00000108 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MSB 0 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_LSB 0 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MASK 0x00000001 +#define AR6320V2_WLAN_DEBUG_OUT_OFFSET 0x00000110 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_MSB 19 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_LSB 0 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_MASK 0x000fffff +#define AR6320V2_AMBA_DEBUG_BUS_OFFSET 0x0000011c +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB 13 +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB 8 +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK 0x00003f00 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_MSB 4 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_LSB 0 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_MASK 0x0000001f +#define AR6320V2_CE_WRAPPER_DEBUG_OFFSET 0x0008 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_MSB 5 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_LSB 0 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_MASK 0x0000003f +#define AR6320V2_CE_DEBUG_OFFSET 0x0054 +#define AR6320V2_CE_DEBUG_SEL_MSB 5 +#define AR6320V2_CE_DEBUG_SEL_LSB 0 +#define AR6320V2_CE_DEBUG_SEL_MASK 0x0000003f +/* End */ + +/* PLL start */ +#define AR6320V2_EFUSE_OFFSET 0x0000032c +#define AR6320V2_EFUSE_XTAL_SEL_MSB 10 +#define AR6320V2_EFUSE_XTAL_SEL_LSB 8 +#define AR6320V2_EFUSE_XTAL_SEL_MASK 0x00000700 +#define AR6320V2_BB_PLL_CONFIG_OFFSET 0x000002f4 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_MSB 20 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_LSB 18 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_MASK 0x001c0000 +#define AR6320V2_BB_PLL_CONFIG_FRAC_MSB 17 +#define AR6320V2_BB_PLL_CONFIG_FRAC_LSB 0 +#define AR6320V2_BB_PLL_CONFIG_FRAC_MASK 0x0003ffff +#define AR6320V2_WLAN_PLL_SETTLE_TIME_MSB 10 +#define AR6320V2_WLAN_PLL_SETTLE_TIME_LSB 0 +#define AR6320V2_WLAN_PLL_SETTLE_TIME_MASK 0x000007ff +#define AR6320V2_WLAN_PLL_SETTLE_OFFSET 0x0018 +#define AR6320V2_WLAN_PLL_SETTLE_SW_MASK 0x000007ff +#define AR6320V2_WLAN_PLL_SETTLE_RSTMASK 0xffffffff +#define AR6320V2_WLAN_PLL_SETTLE_RESET 0x00000400 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_MSB 18 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_LSB 18 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_MSB 16 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_LSB 16 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_RESET 0x1 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MSB 15 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_LSB 14 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MASK 0x0000c000 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_RESET 0x0 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_MSB 13 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_LSB 10 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_MASK 0x00003c00 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_RESET 0x0 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_MSB 9 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_LSB 0 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_MASK 0x000003ff +#define AR6320V2_WLAN_PLL_CONTROL_DIV_RESET 0x11 +#define AR6320V2_WLAN_PLL_CONTROL_OFFSET 0x0014 +#define AR6320V2_WLAN_PLL_CONTROL_SW_MASK 0x001fffff +#define AR6320V2_WLAN_PLL_CONTROL_RSTMASK 0xffffffff +#define AR6320V2_WLAN_PLL_CONTROL_RESET 0x00010011 +#define AR6320V2_SOC_CORE_CLK_CTRL_OFFSET 0x00000114 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_MSB 2 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_LSB 0 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MSB 5 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_LSB 5 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MASK 0x00000020 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_RESET 0x0 +#define AR6320V2_RTC_SYNC_STATUS_OFFSET 0x0244 +#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MSB 1 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +/* PLL end */ + +#define AR6320V2_PCIE_INTR_CE_MASK(n) (AR6320V2_PCIE_INTR_CE0_MASK << (n)) +#define AR6320V2_DRAM_BASE_ADDRESS AR6320V2_TARG_DRAM_START +#define AR6320V2_FW_INDICATOR_ADDRESS (AR6320V2_SOC_CORE_BASE_ADDRESS + AR6320V2_SCRATCH_3_ADDRESS) +#define AR6320V2_SYSTEM_SLEEP_OFFSET AR6320V2_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320V2_WLAN_RESET_CONTROL_OFFSET AR6320V2_SOC_RESET_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_OFFSET AR6320V2_SOC_CLOCK_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320V2_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320V2_RESET_CONTROL_SI0_RST_MASK AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320V2_GPIO_BASE_ADDRESS AR6320V2_WLAN_GPIO_BASE_ADDRESS +#define AR6320V2_GPIO_PIN0_OFFSET AR6320V2_WLAN_GPIO_PIN0_ADDRESS +#define AR6320V2_GPIO_PIN1_OFFSET AR6320V2_WLAN_GPIO_PIN1_ADDRESS +#define AR6320V2_GPIO_PIN0_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320V2_GPIO_PIN1_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320V2_SI_BASE_ADDRESS 0x00050000 +#define AR6320V2_CPU_CLOCK_OFFSET AR6320V2_SOC_CPU_CLOCK_OFFSET +#define AR6320V2_LPO_CAL_OFFSET AR6320V2_SOC_LPO_CAL_OFFSET +#define AR6320V2_GPIO_PIN10_OFFSET AR6320V2_WLAN_GPIO_PIN10_ADDRESS +#define AR6320V2_GPIO_PIN11_OFFSET AR6320V2_WLAN_GPIO_PIN11_ADDRESS +#define AR6320V2_GPIO_PIN12_OFFSET AR6320V2_WLAN_GPIO_PIN12_ADDRESS +#define AR6320V2_GPIO_PIN13_OFFSET AR6320V2_WLAN_GPIO_PIN13_ADDRESS +#define AR6320V2_CPU_CLOCK_STANDARD_LSB AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320V2_CPU_CLOCK_STANDARD_MASK AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320V2_LPO_CAL_ENABLE_LSB AR6320V2_SOC_LPO_CAL_ENABLE_LSB +#define AR6320V2_LPO_CAL_ENABLE_MASK AR6320V2_SOC_LPO_CAL_ENABLE_MASK +#define AR6320V2_ANALOG_INTF_BASE_ADDRESS AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320V2_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320V2_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320V2_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320V2_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320V2_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320V2_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320V2_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320V2_COUNT_DEC_ADDRESS 0x0840 +#define AR6320V2_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320V2_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320V2_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320V2_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320V2_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320V2_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320V2_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320V2_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320V2_WINDOW_WRITE_ADDR_ADDRESS 0x0878 + +struct targetdef_s ar6320v2_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320V2_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320V2_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320V2_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320V2_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320V2_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320V2_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320V2_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320V2_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320V2_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320V2_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320V2_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320V2_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320V2_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320V2_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320V2_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320V2_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320V2_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320V2_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320V2_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320V2_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320V2_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320V2_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320V2_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320V2_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320V2_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320V2_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320V2_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320V2_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320V2_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320V2_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320V2_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320V2_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320V2_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320V2_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320V2_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320V2_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320V2_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320V2_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320V2_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320V2_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320V2_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320V2_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320V2_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320V2_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320V2_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320V2_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320V2_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320V2_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320V2_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320V2_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320V2_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320V2_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320V2_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320V2_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320V2_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320V2_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320V2_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320V2_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320V2_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320V2_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320V2_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320V2_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320V2_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320V2_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320V2_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320V2_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320V2_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320V2_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320V2_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320V2_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320V2_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320V2_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320V2_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320V2_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320V2_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320V2_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320V2_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320V2_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320V2_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320V2_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320V2_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320V2_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320V2_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320V2_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320V2_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320V2_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320V2_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320V2_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320V2_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320V2_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + .d_WLAN_DEBUG_INPUT_SEL_OFFSET = AR6320V2_WLAN_DEBUG_INPUT_SEL_OFFSET, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MSB = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_LSB = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_LSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MASK = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MASK, + .d_WLAN_DEBUG_CONTROL_OFFSET = AR6320V2_WLAN_DEBUG_CONTROL_OFFSET, + .d_WLAN_DEBUG_CONTROL_ENABLE_MSB = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_LSB = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_LSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_MASK = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MASK, + .d_WLAN_DEBUG_OUT_OFFSET = AR6320V2_WLAN_DEBUG_OUT_OFFSET, + .d_WLAN_DEBUG_OUT_DATA_MSB = AR6320V2_WLAN_DEBUG_OUT_DATA_MSB, + .d_WLAN_DEBUG_OUT_DATA_LSB = AR6320V2_WLAN_DEBUG_OUT_DATA_LSB, + .d_WLAN_DEBUG_OUT_DATA_MASK = AR6320V2_WLAN_DEBUG_OUT_DATA_MASK, + .d_AMBA_DEBUG_BUS_OFFSET = AR6320V2_AMBA_DEBUG_BUS_OFFSET, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK, + .d_AMBA_DEBUG_BUS_SEL_MSB = AR6320V2_AMBA_DEBUG_BUS_SEL_MSB, + .d_AMBA_DEBUG_BUS_SEL_LSB = AR6320V2_AMBA_DEBUG_BUS_SEL_LSB, + .d_AMBA_DEBUG_BUS_SEL_MASK = AR6320V2_AMBA_DEBUG_BUS_SEL_MASK, + .d_CE_WRAPPER_DEBUG_OFFSET = AR6320V2_CE_WRAPPER_DEBUG_OFFSET, + .d_CE_WRAPPER_DEBUG_SEL_MSB = AR6320V2_CE_WRAPPER_DEBUG_SEL_MSB, + .d_CE_WRAPPER_DEBUG_SEL_LSB = AR6320V2_CE_WRAPPER_DEBUG_SEL_LSB, + .d_CE_WRAPPER_DEBUG_SEL_MASK = AR6320V2_CE_WRAPPER_DEBUG_SEL_MASK, + .d_CE_DEBUG_OFFSET = AR6320V2_CE_DEBUG_OFFSET, + .d_CE_DEBUG_SEL_MSB = AR6320V2_CE_DEBUG_SEL_MSB, + .d_CE_DEBUG_SEL_LSB = AR6320V2_CE_DEBUG_SEL_LSB, + .d_CE_DEBUG_SEL_MASK = AR6320V2_CE_DEBUG_SEL_MASK, + /* PLL start */ + .d_EFUSE_OFFSET = AR6320V2_EFUSE_OFFSET, + .d_EFUSE_XTAL_SEL_MSB = AR6320V2_EFUSE_XTAL_SEL_MSB, + .d_EFUSE_XTAL_SEL_LSB = AR6320V2_EFUSE_XTAL_SEL_LSB, + .d_EFUSE_XTAL_SEL_MASK = AR6320V2_EFUSE_XTAL_SEL_MASK, + .d_BB_PLL_CONFIG_OFFSET = AR6320V2_BB_PLL_CONFIG_OFFSET, + .d_BB_PLL_CONFIG_OUTDIV_MSB = AR6320V2_BB_PLL_CONFIG_OUTDIV_MSB, + .d_BB_PLL_CONFIG_OUTDIV_LSB = AR6320V2_BB_PLL_CONFIG_OUTDIV_LSB, + .d_BB_PLL_CONFIG_OUTDIV_MASK = AR6320V2_BB_PLL_CONFIG_OUTDIV_MASK, + .d_BB_PLL_CONFIG_FRAC_MSB = AR6320V2_BB_PLL_CONFIG_FRAC_MSB, + .d_BB_PLL_CONFIG_FRAC_LSB = AR6320V2_BB_PLL_CONFIG_FRAC_LSB, + .d_BB_PLL_CONFIG_FRAC_MASK = AR6320V2_BB_PLL_CONFIG_FRAC_MASK, + .d_WLAN_PLL_SETTLE_TIME_MSB = AR6320V2_WLAN_PLL_SETTLE_TIME_MSB, + .d_WLAN_PLL_SETTLE_TIME_LSB = AR6320V2_WLAN_PLL_SETTLE_TIME_LSB, + .d_WLAN_PLL_SETTLE_TIME_MASK = AR6320V2_WLAN_PLL_SETTLE_TIME_MASK, + .d_WLAN_PLL_SETTLE_OFFSET = AR6320V2_WLAN_PLL_SETTLE_OFFSET, + .d_WLAN_PLL_SETTLE_SW_MASK = AR6320V2_WLAN_PLL_SETTLE_SW_MASK, + .d_WLAN_PLL_SETTLE_RSTMASK = AR6320V2_WLAN_PLL_SETTLE_RSTMASK, + .d_WLAN_PLL_SETTLE_RESET = AR6320V2_WLAN_PLL_SETTLE_RESET, + .d_WLAN_PLL_CONTROL_NOPWD_MSB = AR6320V2_WLAN_PLL_CONTROL_NOPWD_MSB, + .d_WLAN_PLL_CONTROL_NOPWD_LSB = AR6320V2_WLAN_PLL_CONTROL_NOPWD_LSB, + .d_WLAN_PLL_CONTROL_NOPWD_MASK = AR6320V2_WLAN_PLL_CONTROL_NOPWD_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_MSB = AR6320V2_WLAN_PLL_CONTROL_BYPASS_MSB, + .d_WLAN_PLL_CONTROL_BYPASS_LSB = AR6320V2_WLAN_PLL_CONTROL_BYPASS_LSB, + .d_WLAN_PLL_CONTROL_BYPASS_MASK = AR6320V2_WLAN_PLL_CONTROL_BYPASS_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_RESET = AR6320V2_WLAN_PLL_CONTROL_BYPASS_RESET, + .d_WLAN_PLL_CONTROL_CLK_SEL_MSB = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_LSB = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_LSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_MASK = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MASK, + .d_WLAN_PLL_CONTROL_CLK_SEL_RESET = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_RESET, + .d_WLAN_PLL_CONTROL_REFDIV_MSB = AR6320V2_WLAN_PLL_CONTROL_REFDIV_MSB, + .d_WLAN_PLL_CONTROL_REFDIV_LSB = AR6320V2_WLAN_PLL_CONTROL_REFDIV_LSB, + .d_WLAN_PLL_CONTROL_REFDIV_MASK = AR6320V2_WLAN_PLL_CONTROL_REFDIV_MASK, + .d_WLAN_PLL_CONTROL_REFDIV_RESET = AR6320V2_WLAN_PLL_CONTROL_REFDIV_RESET, + .d_WLAN_PLL_CONTROL_DIV_MSB = AR6320V2_WLAN_PLL_CONTROL_DIV_MSB, + .d_WLAN_PLL_CONTROL_DIV_LSB = AR6320V2_WLAN_PLL_CONTROL_DIV_LSB, + .d_WLAN_PLL_CONTROL_DIV_MASK = AR6320V2_WLAN_PLL_CONTROL_DIV_MASK, + .d_WLAN_PLL_CONTROL_DIV_RESET = AR6320V2_WLAN_PLL_CONTROL_DIV_RESET, + .d_WLAN_PLL_CONTROL_OFFSET = AR6320V2_WLAN_PLL_CONTROL_OFFSET, + .d_WLAN_PLL_CONTROL_SW_MASK = AR6320V2_WLAN_PLL_CONTROL_SW_MASK, + .d_WLAN_PLL_CONTROL_RSTMASK = AR6320V2_WLAN_PLL_CONTROL_RSTMASK, + .d_WLAN_PLL_CONTROL_RESET = AR6320V2_WLAN_PLL_CONTROL_RESET, + .d_SOC_CORE_CLK_CTRL_OFFSET = AR6320V2_SOC_CORE_CLK_CTRL_OFFSET, + .d_SOC_CORE_CLK_CTRL_DIV_MSB = AR6320V2_SOC_CORE_CLK_CTRL_DIV_MSB, + .d_SOC_CORE_CLK_CTRL_DIV_LSB = AR6320V2_SOC_CORE_CLK_CTRL_DIV_LSB, + .d_SOC_CORE_CLK_CTRL_DIV_MASK = AR6320V2_SOC_CORE_CLK_CTRL_DIV_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MSB = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_LSB = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_LSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MASK = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_RESET = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_RESET, + .d_RTC_SYNC_STATUS_OFFSET = AR6320V2_RTC_SYNC_STATUS_OFFSET, + .d_SOC_CPU_CLOCK_OFFSET = AR6320V2_SOC_CPU_CLOCK_OFFSET, + .d_SOC_CPU_CLOCK_STANDARD_MSB = AR6320V2_SOC_CPU_CLOCK_STANDARD_MSB, + .d_SOC_CPU_CLOCK_STANDARD_LSB = AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB, + .d_SOC_CPU_CLOCK_STANDARD_MASK = AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK, + /* PLL end */ + .d_SOC_POWER_REG_OFFSET = AR6320V2_SOC_POWER_REG_OFFSET, + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320V2_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320V2_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320V2_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320V2_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320V2_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320V2_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320V2_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320V2_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320v2_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320V2_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320V2_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320V2_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320V2_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320V2_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320V2_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320V2_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320V2_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320V2_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320V2_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320V2_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320V2_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320V2_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320V2_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320V2_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320V2_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320V2_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320V2_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320V2_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320V2_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320V2_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320V2_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320V2_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320V2_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320V2_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320V2_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320V2_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320V2_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320V2_FW_IND_INITIALIZED, + .d_FW_IND_HELPER = AR6320V2_FW_IND_HELPER, + .d_RTC_STATE_V_ON = AR6320V2_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320V2_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar9888def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar9888def.h new file mode 100644 index 0000000000000..b26b1b74f5285 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/ar9888def.h @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR9888DEF_H_ +#define AR9888__AR9888DEF_H_ + +/* Base Addresses */ +#define AR9888_RTC_SOC_BASE_ADDRESS 0x00004000 +#define AR9888_RTC_WMAC_BASE_ADDRESS 0x00005000 +#define AR9888_MAC_COEX_BASE_ADDRESS 0x00006000 +#define AR9888_BT_COEX_BASE_ADDRESS 0x00007000 +#define AR9888_SOC_PCIE_BASE_ADDRESS 0x00008000 +#define AR9888_SOC_CORE_BASE_ADDRESS 0x00009000 +#define AR9888_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 +#define AR9888_WLAN_MAC_BASE_ADDRESS 0x00020000 +#define AR9888_EFUSE_BASE_ADDRESS 0x00030000 +#define AR9888_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR9888_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR9888_CE_WRAPPER_BASE_ADDRESS 0x00057000 +#define AR9888_CE0_BASE_ADDRESS 0x00057400 +#define AR9888_CE1_BASE_ADDRESS 0x00057800 +#define AR9888_CE2_BASE_ADDRESS 0x00057c00 +#define AR9888_CE3_BASE_ADDRESS 0x00058000 +#define AR9888_CE4_BASE_ADDRESS 0x00058400 +#define AR9888_CE5_BASE_ADDRESS 0x00058800 +#define AR9888_CE6_BASE_ADDRESS 0x00058c00 +#define AR9888_CE7_BASE_ADDRESS 0x00059000 +#define AR9888_DBI_BASE_ADDRESS 0x00060000 +#define AR9888_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 + +#define AR9888_SCRATCH_3_ADDRESS 0x0030 +#define AR9888_TARG_DRAM_START 0x00400000 +#define AR9888_SOC_SYSTEM_SLEEP_OFFSET 0x000000c4 +#define AR9888_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR9888_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR9888_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_GPIO_PIN0_ADDRESS 0x00000028 +#define AR9888_WLAN_GPIO_PIN1_ADDRESS 0x0000002c +#define AR9888_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR9888_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR9888_WLAN_GPIO_PIN10_ADDRESS 0x00000050 +#define AR9888_WLAN_GPIO_PIN11_ADDRESS 0x00000054 +#define AR9888_WLAN_GPIO_PIN12_ADDRESS 0x00000058 +#define AR9888_WLAN_GPIO_PIN13_ADDRESS 0x0000005c +#define AR9888_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR9888_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR9888_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR9888_SOC_LPO_CAL_ENABLE_MASK 0x00100000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 + +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR9888_SI_CONFIG_I2C_LSB 16 +#define AR9888_SI_CONFIG_I2C_MASK 0x00010000 +#define AR9888_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR9888_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR9888_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR9888_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR9888_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR9888_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR9888_SI_CONFIG_DIVIDER_LSB 0 +#define AR9888_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR9888_SI_CONFIG_OFFSET 0x00000000 +#define AR9888_SI_TX_DATA0_OFFSET 0x00000008 +#define AR9888_SI_TX_DATA1_OFFSET 0x0000000c +#define AR9888_SI_RX_DATA0_OFFSET 0x00000010 +#define AR9888_SI_RX_DATA1_OFFSET 0x00000014 +#define AR9888_SI_CS_OFFSET 0x00000004 +#define AR9888_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR9888_SI_CS_DONE_INT_MASK 0x00000200 +#define AR9888_SI_CS_START_LSB 8 +#define AR9888_SI_CS_START_MASK 0x00000100 +#define AR9888_SI_CS_RX_CNT_LSB 4 +#define AR9888_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR9888_SI_CS_TX_CNT_LSB 0 +#define AR9888_SI_CS_TX_CNT_MASK 0x0000000f +#define AR9888_CE_COUNT 8 +#define AR9888_SR_WR_INDEX_ADDRESS 0x003c +#define AR9888_DST_WATERMARK_ADDRESS 0x0050 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR9888_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR9888_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR9888_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR9888_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR9888_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR9888_DST_WR_INDEX_ADDRESS 0x0040 +#define AR9888_SRC_WATERMARK_ADDRESS 0x004c +#define AR9888_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_CURRENT_SRRI_ADDRESS 0x0044 +#define AR9888_CURRENT_DRRI_ADDRESS 0x0048 +#define AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR9888_HOST_IS_ADDRESS 0x0030 +#define AR9888_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR9888_HOST_IE_ADDRESS 0x002c +#define AR9888_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_SR_BA_ADDRESS 0x0000 +#define AR9888_SR_SIZE_ADDRESS 0x0004 +#define AR9888_CE_CTRL1_ADDRESS 0x0010 +#define AR9888_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR9888_DR_BA_ADDRESS 0x0008 +#define AR9888_DR_SIZE_ADDRESS 0x000c +#define AR9888_MISC_IE_ADDRESS 0x0034 +#define AR9888_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR9888_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR9888_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR9888_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR9888_SRC_WATERMARK_LOW_LSB 16 +#define AR9888_SRC_WATERMARK_HIGH_LSB 0 +#define AR9888_DST_WATERMARK_LOW_LSB 16 +#define AR9888_DST_WATERMARK_HIGH_LSB 0 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR9888_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 2 +#define AR9888_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR9888_RTC_STATE_ADDRESS 0x0000 +#define AR9888_RTC_STATE_COLD_RESET_MASK 0x00000400 +#define AR9888_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR9888_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR9888_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR9888_RTC_STATE_V_MASK 0x00000007 +#define AR9888_RTC_STATE_V_LSB 0 +#define AR9888_RTC_STATE_V_ON 3 +#define AR9888_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR9888_FW_IND_EVENT_PENDING 1 +#define AR9888_FW_IND_INITIALIZED 2 +#define AR9888_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR9888_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR9888_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR9888_PCIE_INTR_CE0_MASK 0x00000800 +#define AR9888_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR9888_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR9888_CPU_INTR_ADDRESS 0x0010 +#define AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR9888_SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 +#define AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR9888_CORE_CTRL_ADDRESS 0x0000 +#define AR9888_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR9888_LOCAL_SCRATCH_OFFSET 0x18 +#define AR9888_CLOCK_GPIO_OFFSET 0xffffffff +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 + +#define AR9888_PCIE_INTR_CE_MASK(n) (AR9888_PCIE_INTR_CE0_MASK << (n)) +#define AR9888_FW_EVENT_PENDING_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_DRAM_BASE_ADDRESS AR9888_TARG_DRAM_START +#define AR9888_FW_INDICATOR_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_RESET_CONTROL_OFFSET AR9888_SOC_RESET_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_OFFSET AR9888_SOC_CLOCK_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_SI0_CLK_MASK AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR9888_RESET_CONTROL_MBOX_RST_MASK MISSING +#define AR9888_RESET_CONTROL_SI0_RST_MASK AR9888_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR9888_GPIO_BASE_ADDRESS AR9888_WLAN_GPIO_BASE_ADDRESS +#define AR9888_GPIO_PIN0_OFFSET AR9888_WLAN_GPIO_PIN0_ADDRESS +#define AR9888_GPIO_PIN1_OFFSET AR9888_WLAN_GPIO_PIN1_ADDRESS +#define AR9888_GPIO_PIN0_CONFIG_MASK AR9888_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR9888_GPIO_PIN1_CONFIG_MASK AR9888_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR9888_SI_BASE_ADDRESS AR9888_WLAN_SI_BASE_ADDRESS +#define AR9888_SCRATCH_BASE_ADDRESS AR9888_SOC_CORE_BASE_ADDRESS +#define AR9888_CPU_CLOCK_OFFSET AR9888_SOC_CPU_CLOCK_OFFSET +#define AR9888_LPO_CAL_OFFSET AR9888_SOC_LPO_CAL_OFFSET +#define AR9888_GPIO_PIN10_OFFSET AR9888_WLAN_GPIO_PIN10_ADDRESS +#define AR9888_GPIO_PIN11_OFFSET AR9888_WLAN_GPIO_PIN11_ADDRESS +#define AR9888_GPIO_PIN12_OFFSET AR9888_WLAN_GPIO_PIN12_ADDRESS +#define AR9888_GPIO_PIN13_OFFSET AR9888_WLAN_GPIO_PIN13_ADDRESS +#define AR9888_CPU_CLOCK_STANDARD_LSB AR9888_SOC_CPU_CLOCK_STANDARD_LSB +#define AR9888_CPU_CLOCK_STANDARD_MASK AR9888_SOC_CPU_CLOCK_STANDARD_MASK +#define AR9888_LPO_CAL_ENABLE_LSB AR9888_SOC_LPO_CAL_ENABLE_LSB +#define AR9888_LPO_CAL_ENABLE_MASK AR9888_SOC_LPO_CAL_ENABLE_MASK +#define AR9888_ANALOG_INTF_BASE_ADDRESS AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR9888_MBOX_BASE_ADDRESS MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_HOST_INT_STATUS_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define AR9888_COUNT_DEC_ADDRESS MISSING +#define AR9888_HOST_INT_STATUS_CPU_MASK MISSING +#define AR9888_HOST_INT_STATUS_CPU_LSB MISSING +#define AR9888_HOST_INT_STATUS_ERROR_MASK MISSING +#define AR9888_HOST_INT_STATUS_ERROR_LSB MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_MASK MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_LSB MISSING +#define AR9888_RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define AR9888_WINDOW_DATA_ADDRESS MISSING +#define AR9888_WINDOW_READ_ADDR_ADDRESS MISSING +#define AR9888_WINDOW_WRITE_ADDR_ADDRESS MISSING + +struct targetdef_s ar9888_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR9888_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR9888_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR9888_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR9888_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR9888_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR9888_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR9888_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR9888_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR9888_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR9888_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR9888_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR9888_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR9888_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR9888_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR9888_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR9888_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR9888_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR9888_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR9888_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR9888_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR9888_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR9888_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR9888_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR9888_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR9888_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR9888_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR9888_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR9888_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR9888_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR9888_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR9888_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR9888_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR9888_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR9888_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR9888_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR9888_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR9888_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR9888_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR9888_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR9888_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR9888_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR9888_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR9888_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR9888_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR9888_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR9888_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR9888_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR9888_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR9888_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR9888_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR9888_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR9888_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR9888_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR9888_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR9888_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR9888_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR9888_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR9888_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR9888_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR9888_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR9888_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR9888_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR9888_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR9888_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR9888_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR9888_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR9888_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR9888_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR9888_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR9888_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR9888_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR9888_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR9888_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR9888_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR9888_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR9888_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR9888_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR9888_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR9888_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR9888_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR9888_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR9888_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR9888_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR9888_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR9888_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR9888_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR9888_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR9888_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR9888_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR9888_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR9888_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR9888_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR9888_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR9888_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR9888_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR9888_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR9888_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR9888_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR9888_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR9888_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR9888_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR9888_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR9888_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR9888_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR9888_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR9888_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR9888_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR9888_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR9888_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR9888_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + + .d_PCIE_INTR_CAUSE_ADDRESS = AR9888_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR9888_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR9888_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR9888_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, +}; + +struct hostdef_s ar9888_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR9888_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR9888_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR9888_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR9888_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR9888_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR9888_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR9888_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR9888_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR9888_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR9888_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR9888_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR9888_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR9888_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR9888_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR9888_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR9888_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR9888_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR9888_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR9888_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR9888_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR9888_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR9888_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR9888_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR9888_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR9888_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR9888_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR9888_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR9888_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR9888_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR9888_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR9888_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR9888_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR9888_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR9888_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR9888_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR9888_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR9888_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/cepci.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/cepci.h new file mode 100644 index 0000000000000..f5ba19bde895d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/cepci.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __CEPCI_H__ +#define __CEPCI_H__ + +/* + * Support for Copy Engine over PCI. + * Structures shared between Host software and Target firmware. + */ + + +/* + * Total number of PCIe MSI interrupts requested for all interrupt sources. + * PCIe standard forces this to be a power of 2. + * Some Host OS's limit MSI requests that can be granted to 8 + * so for now we abide by this limit and avoid requesting more + * than that. + */ +#define MSI_NUM_REQUEST_LOG2 3 +#define MSI_NUM_REQUEST (1<hi_interconnect_state points + * here (and all members are 32-bit quantities in order to + * facilitate Host access). In particular, Host software is + * required to initialize pipe_cfg_addr and svc_to_pipe_map. + */ +struct pcie_state_s { + A_UINT32 pipe_cfg_addr; /* Pipe configuration Target address */ + /* NB: CE_pipe_config[CE_COUNT] */ + + A_UINT32 svc_to_pipe_map; /* Service to pipe map Target address */ + /* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */ + + A_UINT32 MSI_requested; /* number of MSI interrupts requested */ + A_UINT32 MSI_granted; /* number of MSI interrupts granted */ + A_UINT32 MSI_addr; /* Message Signalled Interrupt address */ + A_UINT32 MSI_data; /* Base data */ + A_UINT32 MSI_fw_intr_data; /* Data for firmware interrupt; + MSI data for other interrupts are + in various SoC registers */ + + A_UINT32 power_mgmt_method; /* PCIE_PWR_METHOD_* */ + A_UINT32 config_flags; /* PCIE_CONFIG_FLAG_* */ +}; + +/* + * PCIE_CONFIG_FLAG definitions + */ +#define PCIE_CONFIG_FLAG_ENABLE_L1 0x0000001 +#define PCIE_CONFIG_FLAG_CLK_SWITCH_WAIT 0x0000002 +#define PCIE_CONFIG_FLAG_AXI_CLK_GATE 0x0000004 + +#define PIPE_TO_CE_MAP_CNT 32 /* simple implementation constant */ + +/* + * Configuration information for a Copy Engine pipe. + * Passed from Host to Target during startup (one per CE). + */ +struct CE_pipe_config { + A_UINT32 pipenum; + A_UINT32 pipedir; + A_UINT32 nentries; + A_UINT32 nbytes_max; + A_UINT32 flags; + A_UINT32 reserved; +}; + +#endif /* __CEPCI_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine.c new file mode 100644 index 0000000000000..c73a8537c52c8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine.c @@ -0,0 +1,1678 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include +#include "a_types.h" +#include +#include "osapi_linux.h" +#include "hif_msg_based.h" +#include "if_pci.h" +#include "copy_engine_api.h" +#include "copy_engine_internal.h" +#include "adf_os_lock.h" +#include "hif_pci.h" +#include "regtable.h" +#include +#include "epping_main.h" + +#define CE_POLL_TIMEOUT 10 /* ms */ + +static int war1_allow_sleep; +extern int hif_pci_war1; + +/* + * Support for Copy Engine hardware, which is mainly used for + * communication between Host and Target over a PCIe interconnect. + */ + +/* + * A single CopyEngine (CE) comprises two "rings": + * a source ring + * a destination ring + * + * Each ring consists of a number of descriptors which specify + * an address, length, and meta-data. + * + * Typically, one side of the PCIe interconnect (Host or Target) + * controls one ring and the other side controls the other ring. + * The source side chooses when to initiate a transfer and it + * chooses what to send (buffer address, length). The destination + * side keeps a supply of "anonymous receive buffers" available and + * it handles incoming data as it arrives (when the destination + * recieves an interrupt). + * + * The sender may send a simple buffer (address/length) or it may + * send a small list of buffers. When a small list is sent, hardware + * "gathers" these and they end up in a single destination buffer + * with a single interrupt. + * + * There are several "contexts" managed by this layer -- more, it + * may seem -- than should be needed. These are provided mainly for + * maximum flexibility and especially to facilitate a simpler HIF + * implementation. There are per-CopyEngine recv, send, and watermark + * contexts. These are supplied by the caller when a recv, send, + * or watermark handler is established and they are echoed back to + * the caller when the respective callbacks are invoked. There is + * also a per-transfer context supplied by the caller when a buffer + * (or sendlist) is sent and when a buffer is enqueued for recv. + * These per-transfer contexts are echoed back to the caller when + * the buffer is sent/received. + */ + +/* + * Guts of CE_send, used by both CE_send and CE_sendlist_send. + * The caller takes responsibility for any needed locking. + */ +int +CE_completed_send_next_nolock(struct CE_state *CE_state, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *sw_idx, + unsigned int *hw_idx); + +void WAR_CE_SRC_RING_WRITE_IDX_SET(struct hif_pci_softc *sc, + void __iomem *targid, + u32 ctrl_addr, + unsigned int write_index) +{ + if (hif_pci_war1) { + void __iomem *indicator_addr; + + indicator_addr = targid + ctrl_addr + DST_WATERMARK_ADDRESS; + + if (!war1_allow_sleep && ctrl_addr == CE_BASE_ADDRESS(CDC_WAR_DATA_CE)) { + A_PCI_WRITE32(indicator_addr, + (CDC_WAR_MAGIC_STR | write_index)); + } else { + unsigned long irq_flags; + local_irq_save(irq_flags); + A_PCI_WRITE32(indicator_addr, 1); + + /* + * PCIE write waits for ACK in IPQ8K, there is no + * need to read back value. + */ + (void)A_PCI_READ32(indicator_addr); + (void)A_PCI_READ32(indicator_addr); /* conservative */ + + CE_SRC_RING_WRITE_IDX_SET(targid, + ctrl_addr, + write_index); + + A_PCI_WRITE32(indicator_addr, 0); + local_irq_restore(irq_flags); + } + } else + CE_SRC_RING_WRITE_IDX_SET(targid, ctrl_addr, write_index); +} + +int +CE_send_nolock(struct CE_handle *copyeng, + void *per_transfer_context, + CE_addr_t buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags) +{ + int status; + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct CE_ring_state *src_ring = CE_state->src_ring; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int sw_index = src_ring->sw_index; + unsigned int write_index = src_ring->write_index; + + A_TARGET_ACCESS_BEGIN_RET(targid); + if (unlikely(CE_RING_DELTA(nentries_mask, write_index, sw_index-1) <= 0)) { + OL_ATH_CE_PKT_ERROR_COUNT_INCR(sc,CE_RING_DELTA_FAIL); + status = A_ERROR; + A_TARGET_ACCESS_END_RET(targid); + return status; + } + { + struct CE_src_desc *src_ring_base = (struct CE_src_desc *)src_ring->base_addr_owner_space; + struct CE_src_desc *shadow_base = (struct CE_src_desc *)src_ring->shadow_base; + struct CE_src_desc *src_desc = CE_SRC_RING_TO_DESC(src_ring_base, write_index); + struct CE_src_desc *shadow_src_desc = CE_SRC_RING_TO_DESC(shadow_base, write_index); + + /* Update source descriptor */ + shadow_src_desc->src_ptr = buffer; + shadow_src_desc->meta_data = transfer_id; + + /* + * Set the swap bit if: + * typical sends on this CE are swapped (host is big-endian) and + * this send doesn't disable the swapping (data is not bytestream) + */ + shadow_src_desc->byte_swap = + (((CE_state->attr_flags & CE_ATTR_BYTE_SWAP_DATA) != 0) & + ((flags & CE_SEND_FLAG_SWAP_DISABLE) == 0)); + shadow_src_desc->gather = ((flags & CE_SEND_FLAG_GATHER) != 0); + shadow_src_desc->nbytes = nbytes; + + *src_desc = *shadow_src_desc; + + src_ring->per_transfer_context[write_index] = per_transfer_context; + + /* Update Source Ring Write Index */ + write_index = CE_RING_IDX_INCR(nentries_mask, write_index); + + /* WORKAROUND */ + if (!shadow_src_desc->gather) { + WAR_CE_SRC_RING_WRITE_IDX_SET(sc, targid, ctrl_addr, write_index); + } + + src_ring->write_index = write_index; + status = A_OK; + } + A_TARGET_ACCESS_END_RET(targid); + + return status; +} + +int +CE_send(struct CE_handle *copyeng, + void *per_transfer_context, + CE_addr_t buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + int status; + + + adf_os_spin_lock_bh(&sc->target_lock); + status = CE_send_nolock(copyeng, per_transfer_context, buffer, nbytes, transfer_id, flags); + adf_os_spin_unlock_bh(&sc->target_lock); + + return status; +} + +unsigned int +CE_sendlist_sizeof(void) +{ + return sizeof(struct CE_sendlist); +} + +void +CE_sendlist_init(struct CE_sendlist *sendlist) +{ + struct CE_sendlist_s *sl = (struct CE_sendlist_s *)sendlist; + sl->num_items=0; +} + +int +CE_sendlist_buf_add(struct CE_sendlist *sendlist, + CE_addr_t buffer, + unsigned int nbytes, + u_int32_t flags) +{ + struct CE_sendlist_s *sl = (struct CE_sendlist_s *)sendlist; + unsigned int num_items = sl->num_items; + struct CE_sendlist_item *item; + + if (num_items >= CE_SENDLIST_ITEMS_MAX) { + A_ASSERT(num_items < CE_SENDLIST_ITEMS_MAX); + return A_NO_RESOURCE; + } + + item = &sl->item[num_items]; + item->send_type = CE_SIMPLE_BUFFER_TYPE; + item->data = buffer; + item->u.nbytes = nbytes; + item->flags = flags; + sl->num_items = num_items+1; + return A_OK; +} + +int +CE_sendlist_send(struct CE_handle *copyeng, + void *per_transfer_context, + struct CE_sendlist *sendlist, + unsigned int transfer_id) +{ + int status = -ENOMEM; + struct CE_sendlist_s *sl = (struct CE_sendlist_s *)sendlist; + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct CE_ring_state *src_ring = CE_state->src_ring; + struct hif_pci_softc *sc = CE_state->sc; + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int num_items = sl->num_items; + unsigned int sw_index ; + unsigned int write_index ; + + A_ASSERT((num_items > 0) && (num_items < src_ring->nentries)); + + adf_os_spin_lock_bh(&sc->target_lock); + sw_index = src_ring->sw_index; + write_index = src_ring->write_index; + + if (CE_RING_DELTA(nentries_mask, write_index, sw_index-1) >= num_items) { + struct CE_sendlist_item *item; + int i; + + /* handle all but the last item uniformly */ + for (i = 0; i < num_items-1; i++) { + item = &sl->item[i]; + /* TBDXXX: Support extensible sendlist_types? */ + A_ASSERT(item->send_type == CE_SIMPLE_BUFFER_TYPE); + status = CE_send_nolock(copyeng, CE_SENDLIST_ITEM_CTXT, + (CE_addr_t)item->data, item->u.nbytes, + transfer_id, + item->flags | CE_SEND_FLAG_GATHER); + A_ASSERT(status == A_OK); + } + /* provide valid context pointer for final item */ + item = &sl->item[i]; + /* TBDXXX: Support extensible sendlist_types? */ + A_ASSERT(item->send_type == CE_SIMPLE_BUFFER_TYPE); + status = CE_send_nolock(copyeng, per_transfer_context, + (CE_addr_t)item->data, item->u.nbytes, + transfer_id, item->flags); + A_ASSERT(status == A_OK); + } else { + /* + * Probably not worth the additional complexity to support + * partial sends with continuation or notification. We expect + * to use large rings and small sendlists. If we can't handle + * the entire request at once, punt it back to the caller. + */ + } + adf_os_spin_unlock_bh(&sc->target_lock); + + return status; +} + +int +CE_recv_buf_enqueue(struct CE_handle *copyeng, + void *per_recv_context, + CE_addr_t buffer) +{ + int status; + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct CE_ring_state *dest_ring = CE_state->dest_ring; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + unsigned int nentries_mask = dest_ring->nentries_mask; + unsigned int write_index ; + unsigned int sw_index; + int val = 0; + + adf_os_spin_lock_bh(&sc->target_lock); + write_index = dest_ring->write_index; + sw_index = dest_ring->sw_index; + + A_TARGET_ACCESS_BEGIN_RET_EXT(targid, val); + if (val == -1) { + adf_os_spin_unlock_bh(&sc->target_lock); + return val; + } + + if (CE_RING_DELTA(nentries_mask, write_index, sw_index-1) > 0) { + struct CE_dest_desc *dest_ring_base = (struct CE_dest_desc *)dest_ring->base_addr_owner_space; + struct CE_dest_desc *dest_desc = CE_DEST_RING_TO_DESC(dest_ring_base, write_index); + + /* Update destination descriptor */ + dest_desc->dest_ptr = buffer; + dest_desc->info.nbytes = 0; /* NB: Enable CE_completed_recv_next_nolock to + protect against race between DRRI update and + desc update */ + + dest_ring->per_transfer_context[write_index] = per_recv_context; + + /* Update Destination Ring Write Index */ + write_index = CE_RING_IDX_INCR(nentries_mask, write_index); + CE_DEST_RING_WRITE_IDX_SET(targid, ctrl_addr, write_index); + dest_ring->write_index = write_index; + status = A_OK; + } else { + status = A_ERROR; + } + A_TARGET_ACCESS_END_RET_EXT(targid, val); + if (val == -1) { + adf_os_spin_unlock_bh(&sc->target_lock); + return val; + } + + adf_os_spin_unlock_bh(&sc->target_lock); + + return status; +} + +void +CE_send_watermarks_set(struct CE_handle *copyeng, + unsigned int low_alert_nentries, + unsigned int high_alert_nentries) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + + adf_os_spin_lock(&sc->target_lock); + CE_SRC_RING_LOWMARK_SET(targid, ctrl_addr, low_alert_nentries); + CE_SRC_RING_HIGHMARK_SET(targid, ctrl_addr, high_alert_nentries); + adf_os_spin_unlock(&sc->target_lock); +} + +void +CE_recv_watermarks_set(struct CE_handle *copyeng, + unsigned int low_alert_nentries, + unsigned int high_alert_nentries) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + + adf_os_spin_lock(&sc->target_lock); + CE_DEST_RING_LOWMARK_SET(targid, ctrl_addr, low_alert_nentries); + CE_DEST_RING_HIGHMARK_SET(targid, ctrl_addr, high_alert_nentries); + adf_os_spin_unlock(&sc->target_lock); +} + +unsigned int +CE_send_entries_avail(struct CE_handle *copyeng) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct CE_ring_state *src_ring = CE_state->src_ring; + struct hif_pci_softc *sc = CE_state->sc; + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int sw_index; + unsigned int write_index; + + adf_os_spin_lock(&sc->target_lock); + sw_index = src_ring->sw_index; + write_index = src_ring->write_index; + adf_os_spin_unlock(&sc->target_lock); + + return CE_RING_DELTA(nentries_mask, write_index, sw_index-1); +} + +unsigned int +CE_recv_entries_avail(struct CE_handle *copyeng) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct CE_ring_state *dest_ring = CE_state->dest_ring; + struct hif_pci_softc *sc = CE_state->sc; + unsigned int nentries_mask = dest_ring->nentries_mask; + unsigned int sw_index; + unsigned int write_index; + + adf_os_spin_lock(&sc->target_lock); + sw_index = dest_ring->sw_index; + write_index = dest_ring->write_index; + adf_os_spin_unlock(&sc->target_lock); + + return CE_RING_DELTA(nentries_mask, write_index, sw_index-1); +} + +/* + * Guts of CE_send_entries_done. + * The caller takes responsibility for any necessary locking. + */ +unsigned int +CE_send_entries_done_nolock(struct hif_pci_softc *sc, struct CE_state *CE_state) +{ + struct CE_ring_state *src_ring = CE_state->src_ring; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + A_target_id_t targid = TARGID(sc); + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int sw_index; + unsigned int read_index; + + sw_index = src_ring->sw_index; + read_index = CE_SRC_RING_READ_IDX_GET(targid, ctrl_addr); + + return CE_RING_DELTA(nentries_mask, sw_index, read_index); +} + +unsigned int +CE_send_entries_done(struct CE_handle *copyeng) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + unsigned int nentries; + + adf_os_spin_lock(&sc->target_lock); + nentries = CE_send_entries_done_nolock(sc, CE_state); + adf_os_spin_unlock(&sc->target_lock); + + return nentries; +} + +/* + * Guts of CE_recv_entries_done. + * The caller takes responsibility for any necessary locking. + */ +unsigned int +CE_recv_entries_done_nolock(struct hif_pci_softc *sc, struct CE_state *CE_state) +{ + struct CE_ring_state *dest_ring = CE_state->dest_ring; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + A_target_id_t targid = TARGID(sc); + unsigned int nentries_mask = dest_ring->nentries_mask; + unsigned int sw_index; + unsigned int read_index; + + sw_index = dest_ring->sw_index; + read_index = CE_DEST_RING_READ_IDX_GET(targid, ctrl_addr); + + return CE_RING_DELTA(nentries_mask, sw_index, read_index); +} + +unsigned int +CE_recv_entries_done(struct CE_handle *copyeng) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + unsigned int nentries; + + adf_os_spin_lock(&sc->target_lock); + nentries = CE_recv_entries_done_nolock(sc, CE_state); + adf_os_spin_unlock(&sc->target_lock); + + return nentries; +} + +/* Debug support */ +void *ce_debug_cmplrn_context; /* completed recv next context */ +void *ce_debug_cnclsn_context; /* cancel send next context */ +void *ce_debug_rvkrn_context; /* revoke receive next context */ +void *ce_debug_cmplsn_context; /* completed send next context */ + + +/* + * Guts of CE_completed_recv_next. + * The caller takes responsibility for any necessary locking. + */ +int +CE_completed_recv_next_nolock(struct CE_state *CE_state, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *flagsp) +{ + int status; + struct CE_ring_state *dest_ring = CE_state->dest_ring; + unsigned int nentries_mask = dest_ring->nentries_mask; + unsigned int sw_index = dest_ring->sw_index; + + struct CE_dest_desc *dest_ring_base = (struct CE_dest_desc *)dest_ring->base_addr_owner_space; + struct CE_dest_desc *dest_desc = CE_DEST_RING_TO_DESC(dest_ring_base, sw_index); + int nbytes; + struct dest_desc_info dest_desc_info; + + /* + * By copying the dest_desc_info element to local memory, we could + * avoid extra memory read from non-cachable memory. + */ + dest_desc_info = dest_desc->info; + nbytes = dest_desc_info.nbytes; + if (nbytes == 0) { + /* + * This closes a relatively unusual race where the Host + * sees the updated DRRI before the update to the + * corresponding descriptor has completed. We treat this + * as a descriptor that is not yet done. + */ + status = A_ERROR; + goto done; + } + + dest_desc->info.nbytes = 0; + + /* Return data from completed destination descriptor */ + *bufferp = (CE_addr_t)(dest_desc->dest_ptr); + *nbytesp = nbytes; + *transfer_idp = dest_desc_info.meta_data; + *flagsp = (dest_desc_info.byte_swap) ? CE_RECV_FLAG_SWAPPED : 0; + + if (per_CE_contextp) { + *per_CE_contextp = CE_state->recv_context; + } + + ce_debug_cmplrn_context = dest_ring->per_transfer_context[sw_index]; + if (per_transfer_contextp) { + *per_transfer_contextp = ce_debug_cmplrn_context; + } + dest_ring->per_transfer_context[sw_index] = 0; /* sanity */ + + /* Update sw_index */ + sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); + dest_ring->sw_index = sw_index; + status = A_OK; + +done: + return status; +} + +int +CE_completed_recv_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *flagsp) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + int status; + + + adf_os_spin_lock_bh(&sc->target_lock); + status = CE_completed_recv_next_nolock(CE_state, per_CE_contextp, per_transfer_contextp, + bufferp, nbytesp, transfer_idp, flagsp); + adf_os_spin_unlock_bh(&sc->target_lock); + + return status; +} + +/* NB: Modeled after CE_completed_recv_next_nolock */ +A_STATUS +CE_revoke_recv_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp) +{ + struct CE_state *CE_state; + struct CE_ring_state *dest_ring; + unsigned int nentries_mask; + unsigned int sw_index; + unsigned int write_index; + A_STATUS status; + struct hif_pci_softc *sc; + + CE_state = (struct CE_state *)copyeng; + dest_ring = CE_state->dest_ring; + if (!dest_ring) { + return A_ERROR; + } + + sc = CE_state->sc; + adf_os_spin_lock(&sc->target_lock); + nentries_mask = dest_ring->nentries_mask; + sw_index = dest_ring->sw_index; + write_index = dest_ring->write_index; + if (write_index != sw_index) { + struct CE_dest_desc *dest_ring_base = (struct CE_dest_desc *)dest_ring->base_addr_owner_space; + struct CE_dest_desc *dest_desc = CE_DEST_RING_TO_DESC(dest_ring_base, sw_index); + + /* Return data from completed destination descriptor */ + *bufferp = (CE_addr_t)(dest_desc->dest_ptr); + + if (per_CE_contextp) { + *per_CE_contextp = CE_state->recv_context; + } + + ce_debug_rvkrn_context = dest_ring->per_transfer_context[sw_index]; + if (per_transfer_contextp) { + *per_transfer_contextp = ce_debug_rvkrn_context; + } + dest_ring->per_transfer_context[sw_index] = 0; /* sanity */ + + /* Update sw_index */ + sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); + dest_ring->sw_index = sw_index; + status = A_OK; + } else { + status = A_ERROR; + } + adf_os_spin_unlock(&sc->target_lock); + + return status; +} + +/* + * Guts of CE_completed_send_next. + * The caller takes responsibility for any necessary locking. + */ +int +CE_completed_send_next_nolock(struct CE_state *CE_state, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *sw_idx, + unsigned int *hw_idx) +{ + int status = A_ERROR; + struct CE_ring_state *src_ring = CE_state->src_ring; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int sw_index = src_ring->sw_index; + unsigned int read_index; + + + if (src_ring->hw_index == sw_index) { + /* + * The SW completion index has caught up with the cached + * version of the HW completion index. + * Update the cached HW completion index to see whether + * the SW has really caught up to the HW, or if the cached + * value of the HW index has become stale. + */ + A_TARGET_ACCESS_BEGIN_RET(targid); + src_ring->hw_index = CE_SRC_RING_READ_IDX_GET(targid, ctrl_addr); + A_TARGET_ACCESS_END_RET(targid); + } + read_index = src_ring->hw_index; + + if (sw_idx) + *sw_idx = sw_index; + + if (hw_idx) + *hw_idx = read_index; + + if ((read_index != sw_index) && (read_index != 0xffffffff)) { + struct CE_src_desc *shadow_base = (struct CE_src_desc *)src_ring->shadow_base; + struct CE_src_desc *shadow_src_desc = CE_SRC_RING_TO_DESC(shadow_base, sw_index); + + /* Return data from completed source descriptor */ + *bufferp = (CE_addr_t)(shadow_src_desc->src_ptr); + *nbytesp = shadow_src_desc->nbytes; + *transfer_idp = shadow_src_desc->meta_data; + + if (per_CE_contextp) { + *per_CE_contextp = CE_state->send_context; + } + + ce_debug_cmplsn_context = src_ring->per_transfer_context[sw_index]; + if (per_transfer_contextp) { + *per_transfer_contextp = ce_debug_cmplsn_context; + } + src_ring->per_transfer_context[sw_index] = 0; /* sanity */ + + /* Update sw_index */ + sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); + src_ring->sw_index = sw_index; + status = A_OK; + } + + return status; +} + +/* NB: Modeled after CE_completed_send_next */ +A_STATUS +CE_cancel_send_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp) +{ + struct CE_state *CE_state; + struct CE_ring_state *src_ring; + unsigned int nentries_mask; + unsigned int sw_index; + unsigned int write_index; + A_STATUS status; + struct hif_pci_softc *sc; + + CE_state = (struct CE_state *)copyeng; + src_ring = CE_state->src_ring; + if (!src_ring) { + return A_ERROR; + } + + sc = CE_state->sc; + adf_os_spin_lock(&sc->target_lock); + nentries_mask = src_ring->nentries_mask; + sw_index = src_ring->sw_index; + write_index = src_ring->write_index; + + if (write_index != sw_index) { + struct CE_src_desc *src_ring_base = (struct CE_src_desc *)src_ring->base_addr_owner_space; + struct CE_src_desc *src_desc = CE_SRC_RING_TO_DESC(src_ring_base, sw_index); + + /* Return data from completed source descriptor */ + *bufferp = (CE_addr_t)(src_desc->src_ptr); + *nbytesp = src_desc->nbytes; + *transfer_idp = src_desc->meta_data; + + if (per_CE_contextp) { + *per_CE_contextp = CE_state->send_context; + } + + ce_debug_cnclsn_context = src_ring->per_transfer_context[sw_index]; + if (per_transfer_contextp) { + *per_transfer_contextp = ce_debug_cnclsn_context; + } + src_ring->per_transfer_context[sw_index] = 0; /* sanity */ + + /* Update sw_index */ + sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); + src_ring->sw_index = sw_index; + status = A_OK; + } else { + status = A_ERROR; + } + adf_os_spin_unlock(&sc->target_lock); + + return status; +} + +/* Shift bits to convert IS_*_RING_*_WATERMARK_MASK to CE_WM_FLAG_*_* */ +#define CE_WM_SHFT 1 + + +int +CE_completed_send_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *sw_idx, + unsigned int *hw_idx) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + int status; + + + adf_os_spin_lock_bh(&sc->target_lock); + status = CE_completed_send_next_nolock(CE_state, per_CE_contextp, per_transfer_contextp, + bufferp, nbytesp, transfer_idp, + sw_idx, hw_idx); + adf_os_spin_unlock_bh(&sc->target_lock); + + return status; +} + + +#ifdef ATH_11AC_TXCOMPACT +/* CE engine descriptor reap + Similar to CE_per_engine_service , Only difference is CE_per_engine_service + does recieve and reaping of completed descriptor , + This function only handles reaping of Tx complete descriptor. + The Function is called from threshold reap poll routine HIFSendCompleteCheck + So should not countain recieve functionality within it . + */ + +void +CE_per_engine_servicereap(struct hif_pci_softc *sc, unsigned int CE_id) +{ + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + A_target_id_t targid = TARGID(sc); + void *CE_context; + void *transfer_context; + CE_addr_t buf; + unsigned int nbytes; + unsigned int id; + unsigned int sw_idx, hw_idx; + + A_TARGET_ACCESS_BEGIN(targid); + + /* Since this function is called from both user context and + * tasklet context the spinlock has to lock the bottom halves. + * This fix assumes that ATH_11AC_TXCOMPACT flag is always + * enabled in TX polling mode. If this is not the case, more + * bottom halve spin lock changes are needed. Due to data path + * performance concern, after internal discussion we've decided + * to make minimum change, i.e., only address the issue occurred + * in this function. The possible negative effect of this minimum + * change is that, in the future, if some other function will also + * be opened to let the user context to use, those cases need to be + * addressed by change spin_lock to spin_lock_bh also. */ + + adf_os_spin_lock_bh(&sc->target_lock); + + if (CE_state->send_cb) { + { + /* Pop completed send buffers and call the registered send callback for each */ + while (CE_completed_send_next_nolock(CE_state, &CE_context, &transfer_context, + &buf, &nbytes, &id, &sw_idx, &hw_idx) == A_OK) + { + if(CE_id != CE_HTT_H2T_MSG){ + adf_os_spin_unlock_bh(&sc->target_lock); + CE_state->send_cb((struct CE_handle *)CE_state, CE_context, transfer_context, buf, nbytes, id, + sw_idx, hw_idx); + adf_os_spin_lock_bh(&sc->target_lock); + }else{ + struct HIF_CE_pipe_info *pipe_info = (struct HIF_CE_pipe_info *)CE_context; + + adf_os_spin_lock_bh(&pipe_info->completion_freeq_lock); + pipe_info->num_sends_allowed++; + adf_os_spin_unlock_bh(&pipe_info->completion_freeq_lock); + } + } + } + } + + adf_os_spin_unlock_bh(&sc->target_lock); + A_TARGET_ACCESS_END(targid); +} + +#endif /*ATH_11AC_TXCOMPACT*/ + +/* + * Number of times to check for any pending tx/rx completion on + * a copy engine, this count should be big enough. Once we hit + * this threashold we'll not check for any Tx/Rx comlpetion in same + * interrupt handling. Note that this threashold is only used for + * Rx interrupt processing, this can be used tor Tx as well if we + * suspect any infinite loop in checking for pending Tx completion. + */ +#define CE_TXRX_COMP_CHECK_THRESHOLD 20 + +/* + * Guts of interrupt handler for per-engine interrupts on a particular CE. + * + * Invokes registered callbacks for recv_complete, + * send_complete, and watermarks. + */ +void +CE_per_engine_service(struct hif_pci_softc *sc, unsigned int CE_id) +{ + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + A_target_id_t targid = TARGID(sc); + void *CE_context; + void *transfer_context; + CE_addr_t buf; + unsigned int nbytes; + unsigned int id; + unsigned int flags; + u_int32_t CE_int_status; + unsigned int more_comp_cnt = 0; + unsigned int more_snd_comp_cnt = 0; + unsigned int sw_idx, hw_idx; + + A_TARGET_ACCESS_BEGIN(targid); + + adf_os_spin_lock(&sc->target_lock); + + /* Clear force_break flag and re-initialize receive_count to 0 */ + sc->receive_count = 0; + sc->force_break = 0; +more_completions: + if (CE_state->recv_cb) { + + /* Pop completed recv buffers and call the registered recv callback for each */ + while (CE_completed_recv_next_nolock(CE_state, &CE_context, &transfer_context, + &buf, &nbytes, &id, &flags) == A_OK) + { + adf_os_spin_unlock(&sc->target_lock); + CE_state->recv_cb((struct CE_handle *)CE_state, CE_context, transfer_context, + buf, nbytes, id, flags); + + /* + * EV #112693 - [Peregrine][ES1][WB342][Win8x86][Performance] BSoD_0x133 occurred in VHT80 UDP_DL + * Break out DPC by force if number of loops in HIF_PCI_CE_recv_data reaches MAX_NUM_OF_RECEIVES to avoid spending too long time in DPC for each interrupt handling. + * Schedule another DPC to avoid data loss if we had taken force-break action before + * Apply to Windows OS only currently, Linux/MAC os can expand to their platform if necessary + */ + + /* Break the receive processes by force if force_break set up */ + if (adf_os_unlikely(sc->force_break)) + { + adf_os_atomic_set(&CE_state->rx_pending, 1); + CE_ENGINE_INT_STATUS_CLEAR(targid, ctrl_addr, HOST_IS_COPY_COMPLETE_MASK); + A_TARGET_ACCESS_END(targid); + return; + } + adf_os_spin_lock(&sc->target_lock); + } + } + + /* + * Attention: We may experience potential infinite loop for below While Loop during Sending Stress test + * Resolve the same way as Receive Case (Refer to EV #112693) + */ + + if (CE_state->send_cb) { + /* Pop completed send buffers and call the registered send callback for each */ + +#ifdef ATH_11AC_TXCOMPACT + while (CE_completed_send_next_nolock(CE_state, &CE_context, &transfer_context, + &buf, &nbytes, &id, &sw_idx, &hw_idx) == A_OK){ + + if(CE_id != CE_HTT_H2T_MSG || + WLAN_IS_EPPING_ENABLED(vos_get_conparam())){ + adf_os_spin_unlock(&sc->target_lock); + CE_state->send_cb((struct CE_handle *)CE_state, CE_context, transfer_context, buf, nbytes, id, + sw_idx, hw_idx); + adf_os_spin_lock(&sc->target_lock); + }else{ + struct HIF_CE_pipe_info *pipe_info = (struct HIF_CE_pipe_info *)CE_context; + + adf_os_spin_lock(&pipe_info->completion_freeq_lock); + pipe_info->num_sends_allowed++; + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + } + } +#else /*ATH_11AC_TXCOMPACT*/ + while (CE_completed_send_next_nolock(CE_state, &CE_context, &transfer_context, + &buf, &nbytes, &id, &sw_idx, &hw_idx) == A_OK){ + adf_os_spin_unlock(&sc->target_lock); + CE_state->send_cb((struct CE_handle *)CE_state, CE_context, transfer_context, buf, nbytes, id, + sw_idx, hw_idx); + adf_os_spin_lock(&sc->target_lock); + } +#endif /*ATH_11AC_TXCOMPACT*/ + } + +more_watermarks: + if (CE_state->misc_cbs) { + CE_int_status = CE_ENGINE_INT_STATUS_GET(targid, ctrl_addr); + if (CE_int_status & CE_WATERMARK_MASK) { + if (CE_state->watermark_cb) { + + adf_os_spin_unlock(&sc->target_lock); + /* Convert HW IS bits to software flags */ + flags = (CE_int_status & CE_WATERMARK_MASK) >> CE_WM_SHFT; + + CE_state->watermark_cb((struct CE_handle *)CE_state, CE_state->wm_context, flags); + adf_os_spin_lock(&sc->target_lock); + } + } + } + + /* + * Clear the misc interrupts (watermark) that were handled above, + * and that will be checked again below. + * Clear and check for copy-complete interrupts again, just in case + * more copy completions happened while the misc interrupts were being + * handled. + */ + CE_ENGINE_INT_STATUS_CLEAR(targid, ctrl_addr, CE_WATERMARK_MASK | HOST_IS_COPY_COMPLETE_MASK); + + /* + * Now that per-engine interrupts are cleared, verify that + * no recv interrupts arrive while processing send interrupts, + * and no recv or send interrupts happened while processing + * misc interrupts.Go back and check again.Keep checking until + * we find no more events to process. + */ + if (CE_state->recv_cb && CE_recv_entries_done_nolock(sc, CE_state)) { + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()) || + more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { + goto more_completions; + } else { + adf_os_print("%s:Potential infinite loop detected during Rx processing" + "nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x\n", + __func__, CE_state->dest_ring->nentries_mask, + CE_state->dest_ring->sw_index, + CE_DEST_RING_READ_IDX_GET(targid, CE_state->ctrl_addr)); + } + } + + if (CE_state->send_cb && CE_send_entries_done_nolock(sc, CE_state)) { + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()) || + more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { + goto more_completions; + } else { + adf_os_print("%s:Potential infinite loop detected during send completion" + "nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x\n", + __func__, CE_state->src_ring->nentries_mask, + CE_state->src_ring->sw_index, + CE_SRC_RING_READ_IDX_GET(targid, CE_state->ctrl_addr)); + } + } + + + if (CE_state->misc_cbs) { + CE_int_status = CE_ENGINE_INT_STATUS_GET(targid, ctrl_addr); + if (CE_int_status & CE_WATERMARK_MASK) { + if (CE_state->watermark_cb) { + goto more_watermarks; + } + } + } + + adf_os_spin_unlock(&sc->target_lock); + adf_os_atomic_set(&CE_state->rx_pending, 0); + A_TARGET_ACCESS_END(targid); +} + +static void +CE_poll_timeout(void *arg) +{ + struct CE_state *CE_state = (struct CE_state *) arg; + if (CE_state->timer_inited) { + CE_per_engine_service(CE_state->sc, CE_state->id); + adf_os_timer_mod(&CE_state->poll_timer, CE_POLL_TIMEOUT); + } +} + + +/* + * Handler for per-engine interrupts on ALL active CEs. + * This is used in cases where the system is sharing a + * single interrput for all CEs + */ + +void +CE_per_engine_service_any(int irq, void *arg) +{ + struct hif_pci_softc *sc = arg; + A_target_id_t targid = TARGID(sc); + int CE_id; + A_UINT32 intr_summary; + + A_TARGET_ACCESS_BEGIN(targid); + if (!adf_os_atomic_read(&sc->tasklet_from_intr)) { + for (CE_id=0; CE_id < sc->ce_count; CE_id++) { + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + if (adf_os_atomic_read(&CE_state->rx_pending)) { + adf_os_atomic_set(&CE_state->rx_pending, 0); + CE_per_engine_service(sc, CE_id); + } + } + + A_TARGET_ACCESS_END(targid); + return; + } + + intr_summary = CE_INTERRUPT_SUMMARY(targid); + + for (CE_id=0; intr_summary && (CE_id < sc->ce_count); CE_id++) { + if (intr_summary & (1<ctrl_addr; + struct hif_pci_softc *sc = CE_state->sc; + A_target_id_t targid = TARGID(sc); + CE_state->disable_copy_compl_intr = disable_copy_compl_intr; + + A_TARGET_ACCESS_BEGIN(targid); + if ((!disable_copy_compl_intr) && + (CE_state->send_cb || CE_state->recv_cb)) + { + CE_COPY_COMPLETE_INTR_ENABLE(targid, ctrl_addr); + } else { + CE_COPY_COMPLETE_INTR_DISABLE(targid, ctrl_addr); + } + + if (CE_state->watermark_cb) { + CE_WATERMARK_INTR_ENABLE(targid, ctrl_addr); + } else { + CE_WATERMARK_INTR_DISABLE(targid, ctrl_addr); + } + A_TARGET_ACCESS_END(targid); + +} + +/*Iterate the CE_state list and disable the compl interrupt if it has been registered already.*/ +void CE_disable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc) +{ + A_target_id_t targid = TARGID(sc); + int CE_id; + + A_TARGET_ACCESS_BEGIN(targid); + for (CE_id=0; CE_id < sc->ce_count; CE_id++) { + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + + /* if the interrupt is currently enabled, disable it */ + if (!CE_state->disable_copy_compl_intr && (CE_state->send_cb || CE_state->recv_cb)) { + CE_COPY_COMPLETE_INTR_DISABLE(targid, ctrl_addr); + } + + if (CE_state->watermark_cb) { + CE_WATERMARK_INTR_DISABLE(targid, ctrl_addr); + } + } + A_TARGET_ACCESS_END(targid); +} + +void CE_enable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc) +{ + A_target_id_t targid = TARGID(sc); + int CE_id; + + A_TARGET_ACCESS_BEGIN(targid); + for (CE_id=0; CE_id < sc->ce_count; CE_id++) { + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + u_int32_t ctrl_addr = CE_state->ctrl_addr; + + /* + * If the CE is supposed to have copy complete interrupts enabled + * (i.e. there a callback registered, and the "disable" flag is not set), + * then re-enable the interrupt. + */ + if (!CE_state->disable_copy_compl_intr && (CE_state->send_cb || CE_state->recv_cb)) { + CE_COPY_COMPLETE_INTR_ENABLE(targid, ctrl_addr); + } + + if (CE_state->watermark_cb) { + CE_WATERMARK_INTR_ENABLE(targid, ctrl_addr); + } + } + A_TARGET_ACCESS_END(targid); +} + +void +CE_disable_any_copy_compl_intr(struct hif_pci_softc *sc) +{ + adf_os_spin_lock(&sc->target_lock); + CE_disable_any_copy_compl_intr_nolock(sc); + adf_os_spin_unlock(&sc->target_lock); +} + +/*Re-enable the copy compl interrupt if it has not been disabled before.*/ +void +CE_enable_any_copy_compl_intr(struct hif_pci_softc *sc) +{ + adf_os_spin_lock(&sc->target_lock); + CE_enable_any_copy_compl_intr_nolock(sc); + adf_os_spin_unlock(&sc->target_lock); +} + +void +CE_send_cb_register(struct CE_handle *copyeng, + CE_send_cb fn_ptr, + void *CE_send_context, + int disable_interrupts) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + + adf_os_spin_lock(&sc->target_lock); + CE_state->send_cb = fn_ptr; + CE_state->send_context = CE_send_context; + CE_per_engine_handler_adjust(CE_state, disable_interrupts); + adf_os_spin_unlock(&sc->target_lock); +} + +void +CE_recv_cb_register(struct CE_handle *copyeng, + CE_recv_cb fn_ptr, + void *CE_recv_context, + int disable_interrupts) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + + adf_os_spin_lock(&sc->target_lock); + CE_state->recv_cb = fn_ptr; + CE_state->recv_context = CE_recv_context; + CE_per_engine_handler_adjust(CE_state, disable_interrupts); + adf_os_spin_unlock(&sc->target_lock); +} + +void +CE_watermark_cb_register(struct CE_handle *copyeng, + CE_watermark_cb fn_ptr, + void *CE_wm_context) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + struct hif_pci_softc *sc = CE_state->sc; + + adf_os_spin_lock(&sc->target_lock); + CE_state->watermark_cb = fn_ptr; + CE_state->wm_context = CE_wm_context; + CE_per_engine_handler_adjust(CE_state, 0); + if (fn_ptr) { + CE_state->misc_cbs = 1; + } + adf_os_spin_unlock(&sc->target_lock); +} + +static unsigned int +roundup_pwr2(unsigned int n) +{ + int i; + unsigned int test_pwr2; + + if (!(n & (n-1))) { + return n; /* already a power of 2 */ + } + + test_pwr2 = 4; + for (i=0; i<29; i++) { + if (test_pwr2 > n) { + return test_pwr2; + } + test_pwr2 = test_pwr2 << 1; + } + + A_ASSERT(0); /* n too large */ + return 0; +} + +bool CE_get_rx_pending(struct hif_pci_softc *sc) +{ + int CE_id; + + for (CE_id=0; CE_id < sc->ce_count; CE_id++) { + struct CE_state *CE_state = sc->CE_id_to_state[CE_id]; + if (adf_os_atomic_read(&CE_state->rx_pending)) + return true; + } + + return false; +} +/* + * Initialize a Copy Engine based on caller-supplied attributes. + * This may be called once to initialize both source and destination + * rings or it may be called twice for separate source and destination + * initialization. It may be that only one side or the other is + * initialized by software/firmware. + */ +struct CE_handle * +CE_init(struct hif_pci_softc *sc, + unsigned int CE_id, + struct CE_attr *attr) +{ + struct CE_state *CE_state; + u_int32_t ctrl_addr; + A_target_id_t targid; + unsigned int nentries; + adf_os_dma_addr_t base_addr; + struct ol_softc *scn = sc->ol_sc; + bool malloc_CE_state = false; + bool malloc_src_ring = false; + + A_ASSERT(CE_id < sc->ce_count); + ctrl_addr = CE_BASE_ADDRESS(CE_id); + adf_os_spin_lock(&sc->target_lock); + CE_state = sc->CE_id_to_state[CE_id]; + + + if (!CE_state) { + adf_os_spin_unlock(&sc->target_lock); + CE_state = (struct CE_state *)A_MALLOC(sizeof(*CE_state)); + if (!CE_state) { + dev_err(&sc->pdev->dev, "ath ERROR: CE_state has no mem\n"); + return NULL; + } else + malloc_CE_state = true; + A_MEMZERO(CE_state, sizeof(*CE_state)); + adf_os_spin_lock(&sc->target_lock); + if (!sc->CE_id_to_state[CE_id]) { /* re-check under lock */ + sc->CE_id_to_state[CE_id] = CE_state; + + CE_state->sc = sc; + CE_state->id = CE_id; + CE_state->ctrl_addr = ctrl_addr; + CE_state->state = CE_RUNNING; + CE_state->attr_flags = attr->flags; /* Save attribute flags */ + } else { + /* + * We released target_lock in order to allocate CE state, + * but someone else beat us to it. Continue, using that + * CE_state (and free the one we allocated). + */ + A_FREE(CE_state); + malloc_CE_state = false; + CE_state = sc->CE_id_to_state[CE_id]; + } + } + adf_os_spin_unlock(&sc->target_lock); + + adf_os_atomic_init(&CE_state->rx_pending); + if (attr == NULL) { + /* Already initialized; caller wants the handle */ + return (struct CE_handle *)CE_state; + } + + targid = TARGID(sc); + + if (CE_state->src_sz_max) { + A_ASSERT(CE_state->src_sz_max == attr->src_sz_max); + } else { + CE_state->src_sz_max = attr->src_sz_max; + } + + /* source ring setup */ + nentries = attr->src_nentries; + if (nentries) { + struct CE_ring_state *src_ring; + unsigned CE_nbytes; + char *ptr; + + nentries = roundup_pwr2(nentries); + if (CE_state->src_ring) { + A_ASSERT(CE_state->src_ring->nentries == nentries); + } else { + CE_nbytes = sizeof(struct CE_ring_state) + + (nentries * sizeof(void *)); /* per-send context */ + ptr = A_MALLOC(CE_nbytes); + if (!ptr) { + /* cannot allocate src ring. If the CE_state is allocated + * locally free CE_State and return error. */ + dev_err(&sc->pdev->dev, "ath ERROR: src ring has no mem\n"); + if (malloc_CE_state) { + /* allocated CE_state locally */ + adf_os_spin_lock(&sc->target_lock); + sc->CE_id_to_state[CE_id]= NULL; + adf_os_spin_unlock(&sc->target_lock); + A_FREE(CE_state); + malloc_CE_state = false; + } + return NULL; + } else { + /* we can allocate src ring. + * Mark that the src ring is allocated locally */ + malloc_src_ring = true; + } + A_MEMZERO(ptr, CE_nbytes); + + src_ring = CE_state->src_ring = (struct CE_ring_state *)ptr; + ptr += sizeof(struct CE_ring_state); + src_ring->nentries = nentries; + src_ring->nentries_mask = nentries-1; + A_TARGET_ACCESS_BEGIN_RET_PTR(targid); + src_ring->hw_index = + src_ring->sw_index = CE_SRC_RING_READ_IDX_GET(targid, ctrl_addr); + src_ring->write_index = CE_SRC_RING_WRITE_IDX_GET(targid, ctrl_addr); + A_TARGET_ACCESS_END_RET_PTR(targid); + src_ring->low_water_mark_nentries = 0; + src_ring->high_water_mark_nentries = nentries; + src_ring->per_transfer_context = (void **)ptr; + + /* Legacy platforms that do not support cache coherent DMA are unsupported */ + src_ring->base_addr_owner_space_unaligned = + pci_alloc_consistent(scn->sc_osdev->bdev, + (nentries * sizeof(struct CE_src_desc) + CE_DESC_RING_ALIGN), + &base_addr); + if (src_ring->base_addr_owner_space_unaligned == NULL) { + dev_err(&sc->pdev->dev, "ath ERROR: src ring has no DMA mem\n"); + goto error_no_dma_mem; + } + src_ring->base_addr_CE_space_unaligned = base_addr; + + + if (src_ring->base_addr_CE_space_unaligned & (CE_DESC_RING_ALIGN-1)) { + + src_ring->base_addr_CE_space = (src_ring->base_addr_CE_space_unaligned + + CE_DESC_RING_ALIGN-1) & ~(CE_DESC_RING_ALIGN-1); + + src_ring->base_addr_owner_space = (void *)(((size_t)src_ring->base_addr_owner_space_unaligned + + CE_DESC_RING_ALIGN-1) & ~(CE_DESC_RING_ALIGN-1)); + } else { + src_ring->base_addr_CE_space = src_ring->base_addr_CE_space_unaligned; + src_ring->base_addr_owner_space = src_ring->base_addr_owner_space_unaligned; + } + /* + * Also allocate a shadow src ring in regular mem to use for + * faster access. + */ + src_ring->shadow_base_unaligned = A_MALLOC( + nentries * sizeof(struct CE_src_desc) + CE_DESC_RING_ALIGN); + if (src_ring->shadow_base_unaligned == NULL) { + dev_err(&sc->pdev->dev, "ath ERROR: src ring has no shadow_base mem\n"); + goto error_no_dma_mem; + } + src_ring->shadow_base = (struct CE_src_desc *) + (((size_t) src_ring->shadow_base_unaligned + + CE_DESC_RING_ALIGN-1) & ~(CE_DESC_RING_ALIGN-1)); + + A_TARGET_ACCESS_BEGIN_RET_PTR(targid); + CE_SRC_RING_BASE_ADDR_SET(targid, ctrl_addr, src_ring->base_addr_CE_space); + CE_SRC_RING_SZ_SET(targid, ctrl_addr, nentries); + CE_SRC_RING_DMAX_SET(targid, ctrl_addr, attr->src_sz_max); +#ifdef BIG_ENDIAN_HOST + /* Enable source ring byte swap for big endian host */ + CE_SRC_RING_BYTE_SWAP_SET(targid, ctrl_addr, 1); +#endif + CE_SRC_RING_LOWMARK_SET(targid, ctrl_addr, 0); + CE_SRC_RING_HIGHMARK_SET(targid, ctrl_addr, nentries); + A_TARGET_ACCESS_END_RET_PTR(targid); + } + } + + /* destination ring setup */ + nentries = attr->dest_nentries; + if (nentries) { + struct CE_ring_state *dest_ring; + unsigned CE_nbytes; + char *ptr; + + nentries = roundup_pwr2(nentries); + if (CE_state->dest_ring) { + A_ASSERT(CE_state->dest_ring->nentries == nentries); + } else { + CE_nbytes = sizeof(struct CE_ring_state) + + (nentries * sizeof(void *)); /* per-recv context */ + ptr = A_MALLOC(CE_nbytes); + if (!ptr) { + /* cannot allocate dst ring. If the CE_state or src ring is allocated + * locally free CE_State and src ring and return error. */ + dev_err(&sc->pdev->dev, "ath ERROR: dest ring has no mem\n"); + if (malloc_src_ring) { + A_FREE(CE_state->src_ring); + CE_state->src_ring= NULL; + malloc_src_ring = false; + } + if (malloc_CE_state) { + /* allocated CE_state locally */ + adf_os_spin_lock(&sc->target_lock); + sc->CE_id_to_state[CE_id]= NULL; + adf_os_spin_unlock(&sc->target_lock); + A_FREE(CE_state); + malloc_CE_state = false; + } + return NULL; + } + A_MEMZERO(ptr, CE_nbytes); + + dest_ring = CE_state->dest_ring = (struct CE_ring_state *)ptr; + ptr += sizeof(struct CE_ring_state); + dest_ring->nentries = nentries; + dest_ring->nentries_mask = nentries-1; + A_TARGET_ACCESS_BEGIN_RET_PTR(targid); + dest_ring->sw_index = CE_DEST_RING_READ_IDX_GET(targid, ctrl_addr); + dest_ring->write_index = CE_DEST_RING_WRITE_IDX_GET(targid, ctrl_addr); + A_TARGET_ACCESS_END_RET_PTR(targid); + dest_ring->low_water_mark_nentries = 0; + dest_ring->high_water_mark_nentries = nentries; + dest_ring->per_transfer_context = (void **)ptr; + + /* Legacy platforms that do not support cache coherent DMA are unsupported */ + dest_ring->base_addr_owner_space_unaligned = + pci_alloc_consistent(scn->sc_osdev->bdev, + (nentries * sizeof(struct CE_dest_desc) + CE_DESC_RING_ALIGN), + &base_addr); + if (dest_ring->base_addr_owner_space_unaligned == NULL) { + dev_err(&sc->pdev->dev, "ath ERROR: dest ring has no DMA mem\n"); + goto error_no_dma_mem; + } + dest_ring->base_addr_CE_space_unaligned = base_addr; + + /* Correctly initialize memory to 0 to prevent garbage data + * crashing system when download firmware + */ + A_MEMZERO(dest_ring->base_addr_owner_space_unaligned, nentries * sizeof(struct CE_dest_desc) + CE_DESC_RING_ALIGN); + + if (dest_ring->base_addr_CE_space_unaligned & (CE_DESC_RING_ALIGN-1)) { + + dest_ring->base_addr_CE_space = (dest_ring->base_addr_CE_space_unaligned + + CE_DESC_RING_ALIGN-1) & ~(CE_DESC_RING_ALIGN-1); + + dest_ring->base_addr_owner_space = (void *)(((size_t)dest_ring->base_addr_owner_space_unaligned + + CE_DESC_RING_ALIGN-1) & ~(CE_DESC_RING_ALIGN-1)); + } else { + dest_ring->base_addr_CE_space = dest_ring->base_addr_CE_space_unaligned; + dest_ring->base_addr_owner_space = dest_ring->base_addr_owner_space_unaligned; + } + + A_TARGET_ACCESS_BEGIN_RET_PTR(targid); + CE_DEST_RING_BASE_ADDR_SET(targid, ctrl_addr, dest_ring->base_addr_CE_space); + CE_DEST_RING_SZ_SET(targid, ctrl_addr, nentries); +#ifdef BIG_ENDIAN_HOST + /* Enable Destination ring byte swap for big endian host */ + CE_DEST_RING_BYTE_SWAP_SET(targid, ctrl_addr, 1); +#endif + CE_DEST_RING_LOWMARK_SET(targid, ctrl_addr, 0); + CE_DEST_RING_HIGHMARK_SET(targid, ctrl_addr, nentries); + A_TARGET_ACCESS_END_RET_PTR(targid); + + /* epping */ + /* poll timer */ + if ((CE_state->attr_flags & CE_ATTR_ENABLE_POLL)) { + adf_os_timer_init(scn->adf_dev, &CE_state->poll_timer, + CE_poll_timeout, CE_state, ADF_DEFERRABLE_TIMER); + CE_state->timer_inited = true; + adf_os_timer_mod(&CE_state->poll_timer, CE_POLL_TIMEOUT); + } + } + } + + /* Enable CE error interrupts */ + A_TARGET_ACCESS_BEGIN_RET_PTR(targid); + CE_ERROR_INTR_ENABLE(targid, ctrl_addr); + A_TARGET_ACCESS_END_RET_PTR(targid); + + return (struct CE_handle *)CE_state; + +error_no_dma_mem: + CE_fini((struct CE_handle *)CE_state); + return NULL; +} + +void +CE_fini(struct CE_handle *copyeng) +{ + struct CE_state *CE_state = (struct CE_state *)copyeng; + unsigned int CE_id = CE_state->id; + struct hif_pci_softc *sc = CE_state->sc; + struct ol_softc *scn = sc->ol_sc; + + CE_state->state = CE_UNUSED; + CE_state->sc->CE_id_to_state[CE_id] = NULL; + if (CE_state->src_ring) { + if (CE_state->src_ring->shadow_base_unaligned) + A_FREE(CE_state->src_ring->shadow_base_unaligned); + if (CE_state->src_ring->base_addr_owner_space_unaligned) + pci_free_consistent(scn->sc_osdev->bdev, + (CE_state->src_ring->nentries * sizeof(struct CE_src_desc) + CE_DESC_RING_ALIGN), + CE_state->src_ring->base_addr_owner_space_unaligned, CE_state->src_ring->base_addr_CE_space); + A_FREE(CE_state->src_ring); + } + if (CE_state->dest_ring) { + if (CE_state->dest_ring->base_addr_owner_space_unaligned) + pci_free_consistent(scn->sc_osdev->bdev, + (CE_state->dest_ring->nentries * sizeof(struct CE_dest_desc) + CE_DESC_RING_ALIGN), + CE_state->dest_ring->base_addr_owner_space_unaligned, CE_state->dest_ring->base_addr_CE_space); + A_FREE(CE_state->dest_ring); + + /* epping */ + if (CE_state->timer_inited) { + CE_state->timer_inited = false; + adf_os_timer_free(&CE_state->poll_timer); + } + } + A_FREE(CE_state); +} + +#ifdef IPA_UC_OFFLOAD +/* + * Copy engine should release resource to micro controller + * Micro controller needs + - Copy engine source descriptor base address + - Copy engine source descriptor size + - PCI BAR address to access copy engine regiser + */ +void CE_ipaGetResource(struct CE_handle *ce, + a_uint32_t *ce_sr_base_paddr, + a_uint32_t *ce_sr_ring_size, + a_uint32_t *ce_reg_paddr) +{ + struct CE_state *CE_state = (struct CE_state *)ce; + a_uint32_t ring_loop; + struct CE_src_desc *ce_desc; + a_uint32_t bar_value; + struct hif_pci_softc *sc = CE_state->sc; + + if (CE_RUNNING != CE_state->state) + { + *ce_sr_base_paddr = 0; + *ce_sr_ring_size = 0; + return; + } + + /* Update default value for descriptor */ + for (ring_loop = 0; ring_loop < CE_state->src_ring->nentries; ring_loop++) + { + ce_desc = (struct CE_src_desc *) + ((char *)CE_state->src_ring->base_addr_owner_space + + ring_loop * (sizeof(struct CE_src_desc))); + /* Source pointer and ID, + * should be updated by uc dynamically + * ce_desc->src_ptr = buffer; + * ce_desc->meta_data = transfer_id; */ + /* No Byte SWAP */ + ce_desc->byte_swap = 0; + /* DL size + * pdev->download_len = + * sizeof(struct htt_host_tx_desc_t) + + * HTT_TX_HDR_SIZE_OUTER_HDR_MAX + + * HTT_TX_HDR_SIZE_802_1Q + + * HTT_TX_HDR_SIZE_LLC_SNAP + + * ol_cfg_tx_download_size(pdev->ctrl_pdev); */ + ce_desc->nbytes = 60; + /* Single fragment No gather */ + ce_desc->gather = 0; + } + + /* Get BAR address */ + hif_read_bar(CE_state->sc, &bar_value); + + *ce_sr_base_paddr = (a_uint32_t)CE_state->src_ring->base_addr_CE_space; + *ce_sr_ring_size = (a_uint32_t)CE_state->src_ring->nentries; + *ce_reg_paddr = bar_value + CE_BASE_ADDRESS(CE_state->id) + SR_WR_INDEX_ADDRESS; + return; +} +#endif /* IPA_UC_OFFLOAD */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_api.h new file mode 100644 index 0000000000000..bc865fd92495a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_api.h @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __COPY_ENGINE_API_H__ +#define __COPY_ENGINE_API_H__ + +#if defined(CONFIG_COPY_ENGINE_SUPPORT) + +/* TBDXXX: Use int return values for consistency with Target */ + +/* TBDXXX: Perhaps merge Host/Target-->common */ + +/* + * Copy Engine support: low-level Target-side Copy Engine API. + * This is a hardware access layer used by code that understands + * how to use copy engines. + */ + +/* + * A "struct CE_handle *" serves as an opaque pointer-sized + * handle to a specific copy engine. + */ +struct CE_handle; + +/* + * "Send Completion" callback type for Send Completion Notification. + * + * If a Send Completion callback is registered and one or more sends + * have completed, the callback is invoked. + * + * per_CE_send_context is a context supplied by the calling layer + * (via CE_send_cb_register). It is associated with a copy engine. + * + * per_transfer_send_context is context supplied by the calling layer + * (via the "send" call). It may be different for each invocation + * of send. + * + * The buffer parameter is the first byte sent of the first buffer + * sent (if more than one buffer). + * + * nbytes is the number of bytes of that buffer that were sent. + * + * transfer_id matches the value used when the buffer or + * buf_list was sent. + * + * Implementation note: Pops 1 completed send buffer from Source ring + */ +typedef void (* CE_send_cb)(struct CE_handle *copyeng, + void *per_CE_send_context, + void *per_transfer_send_context, + CE_addr_t buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int sw_index, + unsigned int hw_index); + +/* + * "Buffer Received" callback type for Buffer Received Notification. + * + * Implementation note: Pops 1 completed recv buffer from Dest ring + */ +typedef void (* CE_recv_cb)(struct CE_handle *copyeng, + void *per_CE_recv_context, + void *per_transfer_recv_context, + CE_addr_t buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags); + +/* + * Copy Engine Watermark callback type. + * + * Allows upper layers to be notified when watermarks are reached: + * space is available and/or running short in a source ring + * buffers are exhausted and/or abundant in a destination ring + * + * The flags parameter indicates which condition triggered this + * callback. See CE_WM_FLAG_*. + * + * Watermark APIs are provided to allow upper layers "batch" + * descriptor processing and to allow upper layers to + * throttle/unthrottle. + */ +typedef void (* CE_watermark_cb)(struct CE_handle *copyeng, + void *per_CE_wm_context, + unsigned int flags); + +#define CE_WM_FLAG_SEND_HIGH 1 +#define CE_WM_FLAG_SEND_LOW 2 +#define CE_WM_FLAG_RECV_HIGH 4 +#define CE_WM_FLAG_RECV_LOW 8 + +/* A list of buffers to be gathered and sent */ +struct CE_sendlist; + +/* Copy Engine settable attributes */ +struct CE_attr; + +/*==================Send======================================================*/ + + /* CE_send flags */ +/* disable ring's byte swap, even if the default policy is to swap */ +#define CE_SEND_FLAG_SWAP_DISABLE 1 + +/* + * Queue a source buffer to be sent to an anonymous destination buffer. + * copyeng - which copy engine to use + * buffer - address of buffer + * nbytes - number of bytes to send + * transfer_id - arbitrary ID; reflected to destination + * flags - CE_SEND_FLAG_* values + * Returns 0 on success; otherwise an error status. + * + * Note: If no flags are specified, use CE's default data swap mode. + * + * Implementation note: pushes 1 buffer to Source ring + */ +int CE_send(struct CE_handle *copyeng, + void *per_transfer_send_context, + CE_addr_t buffer, + unsigned int nbytes, + unsigned int transfer_id, /* 14 bits */ + unsigned int flags); + + +/* + * Register a Send Callback function. + * This function is called as soon as the contents of a Send + * have reached the destination, unless disable_interrupts is + * requested. In this case, the callback is invoked when the + * send status is polled, shortly after the send completes. + */ +void CE_send_cb_register(struct CE_handle *copyeng, + CE_send_cb fn_ptr, + void *per_CE_send_context, + int disable_interrupts); + +/* + * Return the size of a SendList. This allows the caller to allocate + * a SendList while the SendList structure remains opaque. + */ +unsigned int CE_sendlist_sizeof(void); + +/* Initialize a sendlist */ +void CE_sendlist_init(struct CE_sendlist *sendlist); + +/* Append a simple buffer (address/length) to a sendlist. */ +int CE_sendlist_buf_add(struct CE_sendlist *sendlist, + CE_addr_t buffer, + unsigned int nbytes, + u_int32_t flags /* OR-ed with internal flags */); + +/* + * Queue a "sendlist" of buffers to be sent using gather to a single + * anonymous destination buffer + * copyeng - which copy engine to use + * sendlist - list of simple buffers to send using gather + * transfer_id - arbitrary ID; reflected to destination + * Returns 0 on success; otherwise an error status. + * + * Implemenation note: Pushes multiple buffers with Gather to Source ring. + */ +int CE_sendlist_send(struct CE_handle *copyeng, + void *per_transfer_send_context, + struct CE_sendlist *sendlist, + unsigned int transfer_id); /* 14 bits */ + +/*==================Recv======================================================*/ + +/* + * Make a buffer available to receive. The buffer must be at least of a + * minimal size appropriate for this copy engine (src_sz_max attribute). + * copyeng - which copy engine to use + * per_transfer_recv_context - context passed back to caller's recv_cb + * buffer - address of buffer in CE space + * Returns 0 on success; otherwise an error status. + * + * Implemenation note: Pushes a buffer to Dest ring. + */ +int CE_recv_buf_enqueue(struct CE_handle *copyeng, + void *per_transfer_recv_context, + CE_addr_t buffer); + +/* + * Register a Receive Callback function. + * This function is called as soon as data is received + * from the source. + */ +void CE_recv_cb_register(struct CE_handle *copyeng, + CE_recv_cb fn_ptr, + void *per_CE_recv_context, + int disable_interrupts); + +/*==================CE Watermark==============================================*/ + +/* + * Register a Watermark Callback function. + * This function is called as soon as a watermark level + * is crossed. A Watermark Callback function is free to + * handle received data "en masse"; but then some coordination + * is required with a registered Receive Callback function. + * [Suggestion: Either handle Receives in a Receive Callback + * or en masse in a Watermark Callback; but not both.] + */ +void CE_watermark_cb_register(struct CE_handle *copyeng, + CE_watermark_cb fn_ptr, + void *per_CE_wm_context); + +/* + * Set low/high watermarks for the send/source side of a copy engine. + * + * Typically, the destination side CPU manages watermarks for + * the receive side and the source side CPU manages watermarks + * for the send side. + * + * A low watermark of 0 is never hit (so the watermark function + * will never be called for a Low Watermark condition). + * + * A high watermark equal to nentries is never hit (so the + * watermark function will never be called for a High Watermark + * condition). + */ +void CE_send_watermarks_set(struct CE_handle *copyeng, + unsigned int low_alert_nentries, + unsigned int high_alert_nentries); + +/* Set low/high watermarks for the receive/destination side of a copy engine. */ +void CE_recv_watermarks_set(struct CE_handle *copyeng, + unsigned int low_alert_nentries, + unsigned int high_alert_nentries); + +/* + * Return the number of entries that can be queued + * to a ring at an instant in time. + * + * For source ring, does not imply that destination-side + * buffers are available; merely indicates descriptor space + * in the source ring. + * + * For destination ring, does not imply that previously + * received buffers have been processed; merely indicates + * descriptor space in destination ring. + * + * Mainly for use with CE Watermark callback. + */ +unsigned int CE_send_entries_avail(struct CE_handle *copyeng); +unsigned int CE_recv_entries_avail(struct CE_handle *copyeng); + +/* + * Return the number of entries in the ring that are ready + * to be processed by software. + * + * For source ring, the number of descriptors that have + * been completed and can now be overwritten with new send + * descriptors. + * + * For destination ring, the number of descriptors that + * are available to be processed (newly received buffers). + */ +unsigned int CE_send_entries_done(struct CE_handle *copyeng); +unsigned int CE_recv_entries_done(struct CE_handle *copyeng); + + /* recv flags */ +/* Data is byte-swapped */ +#define CE_RECV_FLAG_SWAPPED 1 + +/* + * Supply data for the next completed unprocessed receive descriptor. + * + * For use + * with CE Watermark callback, + * in a recv_cb function when processing buf_lists + * in a recv_cb function in order to mitigate recv_cb's. + * + * Implemenation note: Pops buffer from Dest ring. + */ +int CE_completed_recv_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *flagsp); + +/* + * Supply data for the next completed unprocessed send descriptor. + * + * For use + * with CE Watermark callback + * in a send_cb function in order to mitigate send_cb's. + * + * Implementation note: Pops 1 completed send buffer from Source ring + */ +int CE_completed_send_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *sw_idx, + unsigned int *hw_idx); + + +/*==================CE Engine Initialization==================================*/ + +/* Initialize an instance of a CE */ +struct CE_handle *CE_init(struct hif_pci_softc *sc, + unsigned int CE_id, + struct CE_attr *attr); + + +/*==================CE Engine Shutdown========================================*/ +/* + * Support clean shutdown by allowing the caller to revoke + * receive buffers. Target DMA must be stopped before using + * this API. + */ +A_STATUS +CE_revoke_recv_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp); + +/* + * Support clean shutdown by allowing the caller to cancel + * pending sends. Target DMA must be stopped before using + * this API. + */ +A_STATUS +CE_cancel_send_next(struct CE_handle *copyeng, + void **per_CE_contextp, + void **per_transfer_contextp, + CE_addr_t *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp); + +void CE_fini(struct CE_handle *copyeng); + +/*==================CE Interrupt Handlers=====================================*/ +void CE_per_engine_service_any(int irq, void *arg); +void CE_per_engine_service(struct hif_pci_softc *sc, unsigned int CE_id); +void CE_per_engine_servicereap(struct hif_pci_softc *sc, unsigned int CE_id); + +/*===================CE cmpl interrupt Enable/Disable ============================*/ +void CE_disable_any_copy_compl_intr(struct hif_pci_softc *sc); +void CE_enable_any_copy_compl_intr(struct hif_pci_softc *sc); +void CE_disable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc); +void CE_enable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc); + +/* API to check if any of the copy engine pipes has pending frames for prcoessing */ +bool CE_get_rx_pending(struct hif_pci_softc *sc); + +/* CE_attr.flags values */ +#define CE_ATTR_NO_SNOOP 0x01 /* Use NonSnooping PCIe accesses? */ +#define CE_ATTR_BYTE_SWAP_DATA 0x02 /* Byte swap data words */ +#define CE_ATTR_SWIZZLE_DESCRIPTORS 0x04 /* Swizzle descriptors? */ +#define CE_ATTR_DISABLE_INTR 0x08 /* no interrupt on copy completion */ +#define CE_ATTR_ENABLE_POLL 0x10 /* poll for residue descriptors */ + +/* Attributes of an instance of a Copy Engine */ +struct CE_attr { + unsigned int flags; /* CE_ATTR_* values */ + + unsigned int priority; /* TBD */ + + unsigned int src_nentries; /* #entries in source ring - + Must be a power of 2 */ + + unsigned int src_sz_max; /* Max source send size for this CE. + This is also the minimum size of + a destination buffer. */ + + unsigned int dest_nentries; /* #entries in destination ring - + Must be a power of 2 */ + + void *reserved; /* Future use */ +}; + +/* + * When using sendlist_send to transfer multiple buffer fragments, the + * transfer context of each fragment, except last one, will be filled + * with CE_SENDLIST_ITEM_CTXT. CE_completed_send will return success for + * each fragment done with send and the transfer context would be + * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the + * status of a send completion. + */ +#define CE_SENDLIST_ITEM_CTXT ((void *)0xcecebeef) + +/* + * This is an opaque type that is at least large enough to hold + * a sendlist. A sendlist can only be accessed through CE APIs, + * but this allows a sendlist to be allocated on the run-time + * stack. TBDXXX: un-opaque would be simpler... + */ +struct CE_sendlist { + unsigned int word[62]; +}; + +#define ATH_ISR_NOSCHED 0x0000 /* Do not schedule bottom half/DPC */ +#define ATH_ISR_SCHED 0x0001 /* Schedule the bottom half for execution */ +#define ATH_ISR_NOTMINE 0x0002 /* This was not my interrupt - for shared IRQ's */ + +#ifdef IPA_UC_OFFLOAD +/* + * Copy engine should release resource to micro controller + * Micro controller needs + - Copy engine source descriptor base address + - Copy engine source descriptor size + - PCI BAR address to access copy engine regiser + */ +void CE_ipaGetResource(struct CE_handle *ce, + a_uint32_t *ce_sr_base_paddr, + a_uint32_t *ce_sr_ring_size, + a_uint32_t *ce_reg_paddr); +#endif /* IPA_UC_OFFLOAD */ + +#endif /* CONFIG_COPY_ENGINE_SUPPORT */ +#endif /* __COPY_ENGINE_API_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h new file mode 100644 index 0000000000000..27df748ea7f12 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include /* A_TARGET_WRITE */ + +/* Copy Engine operational state */ +enum CE_op_state { + CE_UNUSED, + CE_PAUSED, + CE_RUNNING, +}; + +enum ol_ath_hif_ce_ecodes { + CE_RING_DELTA_FAIL=0 +}; + +struct CE_src_desc; + +/* Copy Engine Ring internal state */ +struct CE_ring_state { + + /* Number of entries in this ring; must be power of 2 */ + unsigned int nentries; + unsigned int nentries_mask; + + /* + * For dest ring, this is the next index to be processed + * by software after it was/is received into. + * + * For src ring, this is the last descriptor that was sent + * and completion processed by software. + * + * Regardless of src or dest ring, this is an invariant + * (modulo ring size): + * write index >= read index >= sw_index + */ + unsigned int sw_index; + unsigned int write_index; /* cached copy */ + /* + * For src ring, this is the next index not yet processed by HW. + * This is a cached copy of the real HW index (read index), used + * for avoiding reading the HW index register more often than + * necessary. + * This extends the invariant: + * write index >= read index >= hw_index >= sw_index + * + * For dest ring, this is currently unused. + */ + unsigned int hw_index; /* cached copy */ + + /* Start of DMA-coherent area reserved for descriptors */ + void *base_addr_owner_space_unaligned; /* Host address space */ + CE_addr_t base_addr_CE_space_unaligned; /* CE address space */ + + /* + * Actual start of descriptors. + * Aligned to descriptor-size boundary. + * Points into reserved DMA-coherent area, above. + */ + void *base_addr_owner_space; /* Host address space */ + CE_addr_t base_addr_CE_space; /* CE address space */ + /* + * Start of shadow copy of descriptors, within regular memory. + * Aligned to descriptor-size boundary. + */ + char *shadow_base_unaligned; + struct CE_src_desc *shadow_base; + + unsigned int low_water_mark_nentries; + unsigned int high_water_mark_nentries; + void **per_transfer_context; + OS_DMA_MEM_CONTEXT(ce_dmacontext) // OS Specific DMA context +}; + +/* Copy Engine internal state */ +struct CE_state { + struct hif_pci_softc *sc; /* back pointer to device's sc */ + unsigned int id; + unsigned int attr_flags; /* CE_ATTR_* */ + u_int32_t ctrl_addr; /* relative to BAR */ + enum CE_op_state state; + + CE_send_cb send_cb; + void *send_context; + + CE_recv_cb recv_cb; + void *recv_context; + + /* misc_cbs - are any callbacks besides send and recv enabled? */ + u_int8_t misc_cbs; + + CE_watermark_cb watermark_cb; + void *wm_context; + + /*Record the state of the copy compl interrupt*/ + int disable_copy_compl_intr; + + unsigned int src_sz_max; + struct CE_ring_state *src_ring; + struct CE_ring_state *dest_ring; + atomic_t rx_pending; + + /* epping */ + bool timer_inited; + adf_os_timer_t poll_timer; +}; + +/* Descriptor rings must be aligned to this boundary */ +#define CE_DESC_RING_ALIGN 8 + +struct CE_src_desc { + CE_addr_t src_ptr; +#if _BYTE_ORDER == _BIG_ENDIAN + u_int32_t meta_data:14, + byte_swap:1, + gather:1, + nbytes:16; +#else + + u_int32_t nbytes:16, + gather:1, + byte_swap:1, + meta_data:14; +#endif +}; + +struct dest_desc_info { +#if _BYTE_ORDER == _BIG_ENDIAN + u_int32_t meta_data:14, + byte_swap:1, + gather:1, + nbytes:16; +#else + u_int32_t nbytes:16, + gather:1, + byte_swap:1, + meta_data:14; +#endif +}; + +struct CE_dest_desc { + CE_addr_t dest_ptr; + struct dest_desc_info info; +}; + +#define CE_SENDLIST_ITEMS_MAX 12 + +enum CE_sendlist_type_e { + CE_SIMPLE_BUFFER_TYPE, + /* TBDXXX: CE_RX_DESC_LIST, */ +}; + +/* + * There's a public "CE_sendlist" and a private "CE_sendlist_s". + * The former is an opaque structure with sufficient space + * to hold the latter. The latter is the actual structure + * definition and it is only used internally. The opaque version + * of the structure allows callers to allocate an instance on the + * run-time stack without knowing any of the details of the + * structure layout. + */ +struct CE_sendlist_s { + unsigned int num_items; + struct CE_sendlist_item { + enum CE_sendlist_type_e send_type; + dma_addr_t data; /* e.g. buffer or desc list */ + union { + unsigned int nbytes; /* simple buffer */ + unsigned int ndesc; /* Rx descriptor list */ + } u; + /* flags: externally-specified flags; OR-ed with internal flags */ + u_int32_t flags; + } item[CE_SENDLIST_ITEMS_MAX]; +}; + + +/* which ring of a CE? */ +#define CE_RING_SRC 0 +#define CE_RING_DEST 1 + +#define CDC_WAR_MAGIC_STR 0xceef0000 +#define CDC_WAR_DATA_CE 4 + +/* Additional internal-only CE_send flags */ +#define CE_SEND_FLAG_GATHER 0x00010000 /* Use Gather */ + +#define CE_SRC_RING_WRITE_IDX_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+SR_WR_INDEX_ADDRESS, (n)) + +#define CE_SRC_RING_WRITE_IDX_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+SR_WR_INDEX_ADDRESS) + +#define CE_SRC_RING_READ_IDX_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+CURRENT_SRRI_ADDRESS) + +#define CE_SRC_RING_BASE_ADDR_SET(targid, CE_ctrl_addr, addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+SR_BA_ADDRESS, (addr)) + +#define CE_SRC_RING_SZ_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+SR_SIZE_ADDRESS, (n)) + +#define CE_SRC_RING_DMAX_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS) & ~CE_CTRL1_DMAX_LENGTH_MASK) | \ + CE_CTRL1_DMAX_LENGTH_SET(n)) +#define CE_SRC_RING_BYTE_SWAP_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS) & ~CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK ) | \ + CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(n)) + +#define CE_DEST_RING_BYTE_SWAP_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+CE_CTRL1_ADDRESS) & ~CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK ) | \ + CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(n)) + +#define CE_DEST_RING_WRITE_IDX_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+DST_WR_INDEX_ADDRESS, (n)) + +#define CE_DEST_RING_WRITE_IDX_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+DST_WR_INDEX_ADDRESS) + +#define CE_DEST_RING_READ_IDX_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+CURRENT_DRRI_ADDRESS) + +#define CE_DEST_RING_BASE_ADDR_SET(targid, CE_ctrl_addr, addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+DR_BA_ADDRESS, (addr)) + +#define CE_DEST_RING_SZ_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+DR_SIZE_ADDRESS, (n)) + +#define CE_SRC_RING_HIGHMARK_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+SRC_WATERMARK_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+SRC_WATERMARK_ADDRESS) & ~SRC_WATERMARK_HIGH_MASK) | \ + SRC_WATERMARK_HIGH_SET(n)) + +#define CE_SRC_RING_LOWMARK_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+SRC_WATERMARK_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+SRC_WATERMARK_ADDRESS) & ~SRC_WATERMARK_LOW_MASK) | \ + SRC_WATERMARK_LOW_SET(n)) + +#define CE_DEST_RING_HIGHMARK_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+DST_WATERMARK_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+DST_WATERMARK_ADDRESS) & ~DST_WATERMARK_HIGH_MASK) | \ + DST_WATERMARK_HIGH_SET(n)) + +#define CE_DEST_RING_LOWMARK_SET(targid, CE_ctrl_addr, n) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+DST_WATERMARK_ADDRESS, \ + (A_TARGET_READ((targid), (CE_ctrl_addr)+DST_WATERMARK_ADDRESS) & ~DST_WATERMARK_LOW_MASK) | \ + DST_WATERMARK_LOW_SET(n)) + +#define CE_COPY_COMPLETE_INTR_ENABLE(targid, CE_ctrl_addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS, \ + A_TARGET_READ((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS) | HOST_IE_COPY_COMPLETE_MASK) + +#define CE_COPY_COMPLETE_INTR_DISABLE(targid, CE_ctrl_addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS, \ + A_TARGET_READ((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS) & ~HOST_IE_COPY_COMPLETE_MASK) + +#define CE_BASE_ADDRESS(CE_id) \ + CE0_BASE_ADDRESS + ((CE1_BASE_ADDRESS-CE0_BASE_ADDRESS)*(CE_id)) + +#define CE_WATERMARK_INTR_ENABLE(targid, CE_ctrl_addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS, \ + A_TARGET_READ((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS) | CE_WATERMARK_MASK) + +#define CE_WATERMARK_INTR_DISABLE(targid, CE_ctrl_addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS, \ + A_TARGET_READ((targid), (CE_ctrl_addr)+HOST_IE_ADDRESS) & ~CE_WATERMARK_MASK) + +#define CE_ERROR_INTR_ENABLE(targid, CE_ctrl_addr) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+MISC_IE_ADDRESS, \ + A_TARGET_READ((targid), (CE_ctrl_addr)+MISC_IE_ADDRESS) | CE_ERROR_MASK) + +#define CE_MISC_INT_STATUS_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+MISC_IS_ADDRESS) + +#define CE_ENGINE_INT_STATUS_GET(targid, CE_ctrl_addr) \ + A_TARGET_READ((targid), (CE_ctrl_addr)+HOST_IS_ADDRESS) + +#define CE_ENGINE_INT_STATUS_CLEAR(targid, CE_ctrl_addr, mask) \ + A_TARGET_WRITE((targid), (CE_ctrl_addr)+HOST_IS_ADDRESS, (mask)) + +#define CE_WATERMARK_MASK (HOST_IS_SRC_RING_LOW_WATERMARK_MASK | \ + HOST_IS_SRC_RING_HIGH_WATERMARK_MASK | \ + HOST_IS_DST_RING_LOW_WATERMARK_MASK | \ + HOST_IS_DST_RING_HIGH_WATERMARK_MASK) + +#define CE_ERROR_MASK (MISC_IS_AXI_ERR_MASK | \ + MISC_IS_DST_ADDR_ERR_MASK | \ + MISC_IS_SRC_LEN_ERR_MASK | \ + MISC_IS_DST_MAX_LEN_VIO_MASK | \ + MISC_IS_DST_RING_OVERFLOW_MASK | \ + MISC_IS_SRC_RING_OVERFLOW_MASK) + +#define CE_SRC_RING_TO_DESC(baddr, idx) &(((struct CE_src_desc *)baddr)[idx]) +#define CE_DEST_RING_TO_DESC(baddr, idx) &(((struct CE_dest_desc *)baddr)[idx]) + +/* Ring arithmetic (modulus number of entries in ring, which is a pwr of 2). */ +#define CE_RING_DELTA(nentries_mask, fromidx, toidx) \ + (((int)(toidx)-(int)(fromidx)) & (nentries_mask)) + +#define CE_RING_IDX_INCR(nentries_mask, idx) \ + (((idx) + 1) & (nentries_mask)) + +#define CE_INTERRUPT_SUMMARY(targid) \ + CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( \ + A_TARGET_READ((targid), CE_WRAPPER_BASE_ADDRESS+CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)) + +/*Macro to increment CE packet errors*/ +#define OL_ATH_CE_PKT_ERROR_COUNT_INCR(_sc,_ce_ecode);\ +{\ + if(_ce_ecode==CE_RING_DELTA_FAIL)(_sc->ol_sc->pkt_stats.ce_ring_delta_fail_count)+=1;\ +} + + +/* Given a Copy Engine's ID, determine the interrupt number for that copy engine's interrupts. */ +#define CE_ID_TO_INUM(id) (A_INUM_CE0_COPY_COMP_BASE + (id)) +#define CE_INUM_TO_ID(inum) ((inum) - A_INUM_CE0_COPY_COMP_BASE) diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c new file mode 100644 index 0000000000000..ef4e0f53e220f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -0,0 +1,2993 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Implementation of the Host-side Host InterFace (HIF) API + * for a Host/Target interconnect using Copy Engines over PCIe. + */ + +//#include +#include +#include "a_types.h" +#include "athdefs.h" +#include "osapi_linux.h" +#include "targcfg.h" +#include "adf_os_lock.h" +#include /* adf_os_atomic_read */ + +#include +#include +#include +#include + +#include "hif_msg_based.h" + +#include "if_pci.h" +#include "copy_engine_api.h" +#include "regtable.h" + +#define ATH_MODULE_NAME hif +#include +#include "hif_pci.h" +#include "vos_trace.h" +#include "vos_api.h" +#if defined(CONFIG_CNSS) +#include +#endif +#include +#include "epping_main.h" + +/* use credit flow control over HTC */ +unsigned int htc_credit_flow = 1; +int hif_pci_war1 = 0; +static DEFINE_SPINLOCK(pciwar_lock); + + +OSDRV_CALLBACKS HIF_osDrvcallback; + +#define HIF_PCI_DEBUG ATH_DEBUG_MAKE_MODULE_MASK(0) +#ifdef IPA_UC_OFFLOAD +#define HIF_PCI_IPA_UC_ASSIGNED_CE 5 +#endif /* IPA_UC_OFFLOAD */ + +#if defined(DEBUG) +static ATH_DEBUG_MASK_DESCRIPTION g_HIFDebugDescription[] = { + {HIF_PCI_DEBUG,"hif_pci"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, + "hif", + "PCIe Host Interface", + ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO, /*or with HIF_PCI_DEBUG if verbose HIF debug is required*/ + ATH_DEBUG_DESCRIPTION_COUNT(g_HIFDebugDescription), + g_HIFDebugDescription); +#endif + + +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +spinlock_t pcie_access_log_lock; +unsigned int pcie_access_log_seqnum = 0; +HIF_ACCESS_LOG pcie_access_log[PCIE_ACCESS_LOG_NUM]; +static void HIFTargetDumpAccessLog(void); +#endif + +/* Forward references */ +static int hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info); + +/* + * Host software's Copy Engine configuration. + * This table is derived from the CE_PCI TABLE, above. + */ +#ifdef BIG_ENDIAN_HOST +#define CE_ATTR_FLAGS CE_ATTR_BYTE_SWAP_DATA +#else +#define CE_ATTR_FLAGS 0 +#endif + +#define AGC_DUMP 1 +#define CHANINFO_DUMP 2 +#define BB_WATCHDOG_DUMP 3 +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +#define PCIE_ACCESS_DUMP 4 +#endif +/* + * Fix EV118783, poll to check whether a BMI response comes + * other than waiting for the interruption which may be lost. + */ +//#define BMI_RSP_POLLING +#define BMI_RSP_TO_MILLISEC 1000 + +static struct CE_attr host_CE_config_wlan[] = +{ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */ + /* could be moved to share CE3 */ + { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL, },/* target->host HTT + HTC control */ + { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL, },/* target->host WMI */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL, },/* host->target WMI */ + { /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0, CE_HTT_H2T_MSG_SRC_NENTRIES , 256, 0, NULL, }, /* host->target HTT */ +#ifndef IPA_UC_OFFLOAD + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */ +#else + { /* CE5 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0, 1024, 512, 0, NULL, }, /* ipa_uc->target HTC control */ +#endif /* IPA_UC_OFFLOAD */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */ + { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */ +}; + +static struct CE_attr *host_CE_config = host_CE_config_wlan; + +/* + * Target firmware's Copy Engine configuration. + * This table is derived from the CE_PCI TABLE, above. + * It is passed to the Target at startup for use by firmware. + */ +static struct CE_pipe_config target_CE_config_wlan[] = { + { /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTC control and raw streams */ + { /* CE1 */ 1, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0, }, /* target->host HTT + HTC control */ + { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0, }, /* target->host WMI */ + { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* host->target WMI */ + { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTT */ + /* NB: 50% of src nentries, since tx has 2 frags */ +#ifndef IPA_UC_OFFLOAD + { /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* unused */ +#else + { /* CE5 */ 5, PIPEDIR_OUT, 1024, 64, CE_ATTR_FLAGS, 0, }, /* ipa_uc->target HTC control */ +#endif /* IPA_UC_OFFLOAD */ + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0, },/* Reserved for target autonomous HIF_memcpy */ + /* CE7 used only by Host */ +}; + +static struct CE_pipe_config *target_CE_config = target_CE_config_wlan; +static int target_CE_config_sz = sizeof(target_CE_config_wlan); + +/* + * CE config for endpoint-ping test + * EP-ping is used to verify HTC/HIF basic functionality and could be used to + * measure interface performance. Here comes some notes. + * 1. In theory, each CE could be used to test. However, due to the limitation + * of target memory EP-ping only focus on CE 1/2/3/4 which are used for + * WMI/HTT services + * 2. The EP-ping CE config does not share the same CE config with WLAN + * application since the max_size and entries requirement for EP-ping + * is different. + */ +#define EPPING_CE_FLAGS_POLL CE_ATTR_DISABLE_INTR|CE_ATTR_ENABLE_POLL|CE_ATTR_FLAGS +static struct CE_attr host_CE_config_wlan_epping_poll[] = +{ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */ + { /* CE1 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */ + { /* CE2 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */ + { /* CE4 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* EP-ping heartbeat */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */ + { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */ +}; + +static struct CE_attr host_CE_config_wlan_epping_irq[] = +{ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */ + { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */ + { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */ + { /* CE4 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* EP-ping heartbeat */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */ + { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */ +}; +/* + * EP-ping firmware's CE configuration + */ +static struct CE_pipe_config target_CE_config_wlan_epping[] = { + { /* CE0 */ 0, PIPEDIR_OUT, 16, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTC control and raw streams */ + { /* CE1 */ 1, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* target->host EP-ping */ + { /* CE2 */ 2, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* target->host EP-ping */ + { /* CE3 */ 3, PIPEDIR_OUT, 128, 2048, CE_ATTR_FLAGS, 0, }, /* host->target EP-ping */ + { /* CE4 */ 4, PIPEDIR_OUT, 128, 2048, CE_ATTR_FLAGS, 0, }, /* host->target EP-ping */ + { /* CE5 */ 5, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* EP-ping heartbeat */ + { /* CE6 */ 6, PIPEDIR_INOUT, 0, 0, CE_ATTR_FLAGS, 0, }, /* unused */ + /* CE7 used only by Host */ +}; + +int hif_completion_thread(struct HIF_CE_state *hif_state); +static int hif_post_recv_buffers(HIF_DEVICE *hif_device); + +void +WAR_PCI_WRITE32(char *addr, u32 offset, u32 value) +{ + if (hif_pci_war1) { + unsigned long irq_flags; + + spin_lock_irqsave(&pciwar_lock, irq_flags); + + (void)ioread32((void __iomem *)(addr+offset+4)); /* 3rd read prior to write */ + (void)ioread32((void __iomem *)(addr+offset+4)); /* 2nd read prior to write */ + (void)ioread32((void __iomem *)(addr+offset+4)); /* 1st read prior to write */ + iowrite32((u32)(value), (void __iomem *)(addr+offset)); + + spin_unlock_irqrestore(&pciwar_lock, irq_flags); + } else { + iowrite32((u32)(value), (void __iomem *)(addr+offset)); + } +} + +int HIFInit(OSDRV_CALLBACKS *callbacks) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + A_MEMZERO(&HIF_osDrvcallback,sizeof(HIF_osDrvcallback)); + + A_REGISTER_MODULE_DEBUG_INFO(hif); + + HIF_osDrvcallback.deviceInsertedHandler = callbacks->deviceInsertedHandler; + HIF_osDrvcallback.deviceRemovedHandler = callbacks->deviceRemovedHandler; + HIF_osDrvcallback.deviceSuspendHandler = callbacks->deviceSuspendHandler; + HIF_osDrvcallback.deviceResumeHandler = callbacks->deviceResumeHandler; + HIF_osDrvcallback.deviceWakeupHandler = callbacks->deviceWakeupHandler; + HIF_osDrvcallback.context = callbacks->context; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + return EOK; +} + +int +HIFAttachHTC(HIF_DEVICE *hif_device, HTC_CALLBACKS *callbacks) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + ASSERT(0); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return EOK; +} + +void +HIFDetachHTC(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + A_MEMZERO(&hif_state->msg_callbacks_pending, sizeof(hif_state->msg_callbacks_pending)); + A_MEMZERO(&hif_state->msg_callbacks_current, sizeof(hif_state->msg_callbacks_current)); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + +/* Send the first nbytes bytes of the buffer */ +A_STATUS +HIFSend_head(HIF_DEVICE *hif_device, + a_uint8_t pipe, unsigned int transfer_id, unsigned int nbytes, adf_nbuf_t nbuf) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct HIF_CE_pipe_info *pipe_info = &(hif_state->pipe_info[pipe]); + struct CE_handle *ce_hdl = pipe_info->ce_hdl; + int bytes = nbytes, nfrags = 0; + struct CE_sendlist sendlist; + int status; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + A_ASSERT(nbytes <= adf_nbuf_len(nbuf)); + + /* + * The common case involves sending multiple fragments within a + * single download (the tx descriptor and the tx frame header). + * So, optimize for the case of multiple fragments by not even + * checking whether it's necessary to use a sendlist. + * The overhead of using a sendlist for a single buffer download + * is not a big deal, since it happens rarely (for WMI messages). + */ + CE_sendlist_init(&sendlist); + do { + a_uint32_t frag_paddr; + int frag_bytes; + + frag_paddr = adf_nbuf_get_frag_paddr_lo(nbuf, nfrags); + frag_bytes = adf_nbuf_get_frag_len(nbuf, nfrags); + status = CE_sendlist_buf_add( + &sendlist, frag_paddr, + frag_bytes > bytes ? bytes : frag_bytes, + adf_nbuf_get_frag_is_wordstream(nbuf, nfrags) ? + 0 : CE_SEND_FLAG_SWAP_DISABLE); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: error, frag_num %d larger than the given limit\n", + __func__, nfrags)); + return status; + } + bytes -= frag_bytes; + nfrags++; + } while (bytes > 0); + + /* Make sure we have resources to handle this request */ + adf_os_spin_lock_bh(&pipe_info->completion_freeq_lock); + if (pipe_info->num_sends_allowed < nfrags) { + adf_os_spin_unlock_bh(&pipe_info->completion_freeq_lock); + OL_ATH_HIF_PKT_ERROR_COUNT_INCR(hif_state, HIF_PIPE_NO_RESOURCE); + return A_NO_RESOURCE; + } + pipe_info->num_sends_allowed -= nfrags; + adf_os_spin_unlock_bh(&pipe_info->completion_freeq_lock); + + if(adf_os_unlikely(ce_hdl == NULL)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: error CE handle is null\n", __func__)); + return A_ERROR; + } + + status = CE_sendlist_send(ce_hdl, nbuf, &sendlist, transfer_id); + A_ASSERT(status == A_OK); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return status; +} + +/* Send the entire buffer */ +A_STATUS +HIFSend(HIF_DEVICE *hif_device, a_uint8_t pipe, adf_nbuf_t hdr_buf, adf_nbuf_t netbuf) +{ + return HIFSend_head(hif_device, pipe, 0, adf_nbuf_len(netbuf), netbuf); +} + +void +HIFSendCompleteCheck(HIF_DEVICE *hif_device, a_uint8_t pipe, int force) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + if (! force) { + int resources; + /* + * Decide whether to actually poll for completions, or just + * wait for a later chance. + * If there seem to be plenty of resources left, then just wait, + * since checking involves reading a CE register, which is a + * relatively expensive operation. + */ + resources = HIFGetFreeQueueNumber(hif_device, pipe); + /* + * If at least 50% of the total resources are still available, + * don't bother checking again yet. + */ + if (resources > (host_CE_config[pipe].src_nentries >> 1)) { + return; + } + } +#ifdef ATH_11AC_TXCOMPACT + CE_per_engine_servicereap(hif_state->sc, pipe); +#else + CE_per_engine_service(hif_state->sc, pipe); +#endif +} + +a_uint16_t +HIFGetFreeQueueNumber(HIF_DEVICE *hif_device, a_uint8_t pipe) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct HIF_CE_pipe_info *pipe_info = &(hif_state->pipe_info[pipe]); + a_uint16_t rv; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + adf_os_spin_lock_bh(&pipe_info->completion_freeq_lock); + rv = pipe_info->num_sends_allowed; + adf_os_spin_unlock_bh(&pipe_info->completion_freeq_lock); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + return rv; +} + +/* Called by lower (CE) layer when a send to Target completes. */ +void +HIF_PCI_CE_send_done(struct CE_handle *copyeng, void *ce_context, void *transfer_context, + CE_addr_t CE_data, unsigned int nbytes, unsigned int transfer_id, + unsigned int sw_index, unsigned int hw_index) +{ + struct HIF_CE_pipe_info *pipe_info = (struct HIF_CE_pipe_info *)ce_context; + struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state; + struct HIF_CE_completion_state *compl_state; + struct HIF_CE_completion_state *compl_queue_head, *compl_queue_tail; /* local queue */ + unsigned int sw_idx = sw_index, hw_idx = hw_index; + + compl_queue_head = compl_queue_tail = NULL; + do { + /* + * For the send completion of an item in sendlist, just increment + * num_sends_allowed. The upper layer callback will be triggered + * when last fragment is done with send. + */ + if (transfer_context == CE_SENDLIST_ITEM_CTXT) { + adf_os_spin_lock(&pipe_info->completion_freeq_lock); + pipe_info->num_sends_allowed++; /* NB: meaningful only for Sends */ + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + continue; + } + + adf_os_spin_lock(&pipe_info->completion_freeq_lock); + compl_state = pipe_info->completion_freeq_head; + if (!compl_state) { + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Out of free buf in hif send completion list, potential hw_index corruption" + "pipe_num:%d num_send_allowed:%d pipe_info:0x%p sw_index:%d hw_index:%d nbytes:%d\n", + pipe_info->pipe_num, pipe_info->num_sends_allowed, + pipe_info, sw_idx, hw_idx, nbytes)); + ASSERT(0); + break; + } + pipe_info->completion_freeq_head = compl_state->next; + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + + compl_state->next = NULL; + compl_state->send_or_recv = HIF_CE_COMPLETE_SEND; + compl_state->copyeng = copyeng; + compl_state->ce_context = ce_context; + compl_state->transfer_context = transfer_context; + compl_state->data = CE_data; + compl_state->nbytes = nbytes; + compl_state->transfer_id = transfer_id; + compl_state->flags = 0; + + /* Enqueue at end of local queue */ + if (compl_queue_tail) { + compl_queue_tail->next = compl_state; + } else { + compl_queue_head = compl_state; + } + compl_queue_tail = compl_state; + } while (CE_completed_send_next(copyeng, &ce_context, &transfer_context, + &CE_data, &nbytes, &transfer_id, + &sw_idx, &hw_idx) == EOK); + + if (compl_queue_head == NULL) { + /* + * If only some of the items within a sendlist have completed, + * don't invoke completion processing until the entire sendlist + * has been sent. + */ + return; + } + + adf_os_spin_lock(&hif_state->completion_pendingq_lock); + + /* Enqueue the local completion queue on the per-device completion queue */ + if (hif_state->completion_pendingq_head) { + hif_state->completion_pendingq_tail->next = compl_queue_head; + hif_state->completion_pendingq_tail = compl_queue_tail; + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + } else { + hif_state->completion_pendingq_head = compl_queue_head; + hif_state->completion_pendingq_tail = compl_queue_tail; + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + + /* Alert the send completion service thread */ + hif_completion_thread(hif_state); + } +} + + +/* Called by lower (CE) layer when data is received from the Target. */ +void +HIF_PCI_CE_recv_data(struct CE_handle *copyeng, void *ce_context, void *transfer_context, + CE_addr_t CE_data, unsigned int nbytes, unsigned int transfer_id, unsigned int flags) +{ + struct HIF_CE_pipe_info *pipe_info = (struct HIF_CE_pipe_info *)ce_context; + struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state; + struct hif_pci_softc *sc = hif_state->sc; + struct ol_softc *scn = sc->ol_sc; + struct HIF_CE_completion_state *compl_state; + struct HIF_CE_completion_state *compl_queue_head, *compl_queue_tail; /* local queue */ + + compl_queue_head = compl_queue_tail = NULL; + do { + adf_os_spin_lock(&pipe_info->completion_freeq_lock); + compl_state = pipe_info->completion_freeq_head; + ASSERT(compl_state != NULL); + pipe_info->completion_freeq_head = compl_state->next; + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + + compl_state->next = NULL; + compl_state->send_or_recv = HIF_CE_COMPLETE_RECV; + compl_state->copyeng = copyeng; + compl_state->ce_context = ce_context; + compl_state->transfer_context = transfer_context; + compl_state->data = CE_data; + compl_state->nbytes = nbytes; + compl_state->transfer_id = transfer_id; + compl_state->flags = flags; + + /* Enqueue at end of local queue */ + if (compl_queue_tail) { + compl_queue_tail->next = compl_state; + } else { + compl_queue_head = compl_state; + } + compl_queue_tail = compl_state; + + adf_nbuf_unmap_single(scn->adf_dev, (adf_nbuf_t)transfer_context, ADF_OS_DMA_FROM_DEVICE); + + /* + * EV #112693 - [Peregrine][ES1][WB342][Win8x86][Performance] BSoD_0x133 occurred in VHT80 UDP_DL + * Break out DPC by force if number of loops in HIF_PCI_CE_recv_data reaches MAX_NUM_OF_RECEIVES to avoid spending too long time in DPC for each interrupt handling. + * Schedule another DPC to avoid data loss if we had taken force-break action before + * Apply to Windows OS only currently, Linux/MAC os can expand to their platform if necessary + */ + + /* Set up force_break flag if num of receices reaches MAX_NUM_OF_RECEIVES */ + sc->receive_count++; + if (adf_os_unlikely(hif_max_num_receives_reached(sc->receive_count))) + { + sc->force_break = 1; + break; + } + } while (CE_completed_recv_next(copyeng, &ce_context, &transfer_context, + &CE_data, &nbytes, &transfer_id, &flags) == EOK); + + adf_os_spin_lock(&hif_state->completion_pendingq_lock); + + /* Enqueue the local completion queue on the per-device completion queue */ + if (hif_state->completion_pendingq_head) { + hif_state->completion_pendingq_tail->next = compl_queue_head; + hif_state->completion_pendingq_tail = compl_queue_tail; + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + } else { + hif_state->completion_pendingq_head = compl_queue_head; + hif_state->completion_pendingq_tail = compl_queue_tail; + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + + /* Alert the recv completion service thread */ + hif_completion_thread(hif_state); + } +} + +/* TBDXXX: Set CE High Watermark; invoke txResourceAvailHandler in response */ + + +void +HIFPostInit(HIF_DEVICE *hif_device, void *unused, MSG_BASED_HIF_CALLBACKS *callbacks) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + spin_lock_init(&pcie_access_log_lock); +#endif + /* Save callbacks for later installation */ + A_MEMCPY(&hif_state->msg_callbacks_pending, callbacks, sizeof(hif_state->msg_callbacks_pending)); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + +static void hif_pci_free_complete_state(struct HIF_CE_pipe_info *pipe_info) +{ + struct HIF_CE_completion_state_list *tmp_list; + + while (pipe_info->completion_space_list) { + tmp_list = pipe_info->completion_space_list; + pipe_info->completion_space_list = tmp_list->next; + vos_mem_free(tmp_list); + } +} +int +hif_completion_thread_startup(struct HIF_CE_state *hif_state) +{ + struct CE_handle *ce_diag = hif_state->ce_diag; + struct hif_pci_softc *sc = hif_state->sc; + A_target_id_t targid = hif_state->targid; + int pipe_num; + + //daemonize("hif_compl_thread"); + + adf_os_spinlock_init(&hif_state->completion_pendingq_lock); + hif_state->completion_pendingq_head = hif_state->completion_pendingq_tail = NULL; + + A_TARGET_ACCESS_LIKELY(targid); + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct CE_attr attr; + struct HIF_CE_pipe_info *pipe_info; + int completions_needed; + + pipe_info = &hif_state->pipe_info[pipe_num]; + if (pipe_info->ce_hdl == ce_diag) { + continue; /* Handle Diagnostic CE specially */ + } + attr = host_CE_config[pipe_num]; + completions_needed = 0; + if (attr.src_nentries) { /* pipe used to send to target */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("pipe_num:%d pipe_info:0x%p\n", + pipe_num, pipe_info)); + CE_send_cb_register(pipe_info->ce_hdl, HIF_PCI_CE_send_done, pipe_info, attr.flags & CE_ATTR_DISABLE_INTR); + completions_needed += attr.src_nentries; + pipe_info->num_sends_allowed = attr.src_nentries-1; + } + if (attr.dest_nentries) { /* pipe used to receive from target */ + CE_recv_cb_register(pipe_info->ce_hdl, HIF_PCI_CE_recv_data, pipe_info, attr.flags & CE_ATTR_DISABLE_INTR); + completions_needed += attr.dest_nentries; + } + + pipe_info->completion_freeq_head = pipe_info->completion_freeq_tail = NULL; + if (completions_needed > 0) { + struct HIF_CE_completion_state *compl_state; + struct HIF_CE_completion_state_list *tmp_list; + int i; + int idx; + int num_list; + int allocated_node; + int num_in_batch; + size_t len; + + allocated_node = 0; + num_list = (completions_needed + HIF_CE_COMPLETE_STATE_NUM -1); + num_list /= HIF_CE_COMPLETE_STATE_NUM; + + for (idx = 0; idx < num_list; idx++) { + if (completions_needed - allocated_node >= + HIF_CE_COMPLETE_STATE_NUM) + num_in_batch = HIF_CE_COMPLETE_STATE_NUM; + else + num_in_batch = completions_needed - allocated_node; + if (num_in_batch <= 0) + break; + len = num_in_batch * + sizeof(struct HIF_CE_completion_state) + + sizeof(struct HIF_CE_completion_state_list); + /* Allocate structures to track pending send/recv completions */ + tmp_list = + (struct HIF_CE_completion_state_list *)vos_mem_malloc(len); + if (!tmp_list) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("ath ERROR: compl_state has no mem\n")); + hif_pci_free_complete_state(pipe_info); + return -1; + } + compl_state = (struct HIF_CE_completion_state *) + ((uint8_t *)tmp_list + + sizeof(struct HIF_CE_completion_state_list)); + for (i = 0; i < num_in_batch; i++) { + compl_state->send_or_recv = HIF_CE_COMPLETE_FREE; + compl_state->next = NULL; + if (pipe_info->completion_freeq_head) + pipe_info->completion_freeq_tail->next = compl_state; + else + pipe_info->completion_freeq_head = compl_state; + pipe_info->completion_freeq_tail = compl_state; + compl_state++; + allocated_node++; + } + if (pipe_info->completion_space_list == NULL) { + pipe_info->completion_space_list = tmp_list; + tmp_list->next = NULL; + } else { + tmp_list->next = pipe_info->completion_space_list; + pipe_info->completion_space_list = tmp_list; + } + } + adf_os_spinlock_init(&pipe_info->completion_freeq_lock); + } + + } + A_TARGET_ACCESS_UNLIKELY(targid); + return 0; +} + +void +hif_completion_thread_shutdown(struct HIF_CE_state *hif_state) +{ + struct HIF_CE_completion_state *compl_state; + struct HIF_CE_pipe_info *pipe_info; + struct hif_pci_softc *sc = hif_state->sc; + int pipe_num; + + /* + * Drop pending completions. These have already been + * reported by the CE layer to us but we have not yet + * passed them upstack. + */ + while ((compl_state = hif_state->completion_pendingq_head) != NULL) { + adf_nbuf_t netbuf; + + netbuf = (adf_nbuf_t)compl_state->transfer_context; + adf_nbuf_free(netbuf); + + hif_state->completion_pendingq_head = compl_state->next; + + /* + * NB: Don't bother to place compl_state on pipe's free queue, + * because we'll free underlying memory for the free queues + * in a moment anyway. + */ + } + + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + pipe_info = &hif_state->pipe_info[pipe_num]; + hif_pci_free_complete_state(pipe_info); + adf_os_spinlock_destroy(&pipe_info->completion_freeq_lock); + } + + //hif_state->compl_thread = NULL; + //complete_and_exit(&hif_state->compl_thread_done, 0); +} + +/* + * This thread provides a context in which send/recv completions + * are handled. + * + * Note: HIF installs callback functions with the CE layer. + * Those functions are called directly (e.g. in interrupt context). + * Upper layers (e.g. HTC) have installed callbacks with HIF which + * expect to be called in a thread context. This is where that + * conversion occurs. + * + * TBDXXX: Currently we use just one thread for all pipes. + * This might be sufficient or we might need multiple threads. + */ +int +//hif_completion_thread(void *hif_dev) +hif_completion_thread(struct HIF_CE_state *hif_state) +{ + MSG_BASED_HIF_CALLBACKS *msg_callbacks = &hif_state->msg_callbacks_current; + struct HIF_CE_completion_state *compl_state; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + /* Allow only one instance of the thread to execute at a time to + * prevent out of order processing of messages - this is bad for higher + * layer code + */ + if (!adf_os_atomic_dec_and_test(&hif_state->hif_thread_idle)) { + /* We were not the lucky one */ + adf_os_atomic_inc(&hif_state->hif_thread_idle); + return 0; + } + + /* Make sure that HTC registered call backs with the HIF are valid */ + if (!msg_callbacks->fwEventHandler + || !msg_callbacks->txCompletionHandler + || !msg_callbacks->rxCompletionHandler) { + return 0; + } + + while (atomic_read(&hif_state->fw_event_pending) > 0) { + /* + * Clear pending state before handling, in case there's + * another while we process the first. + */ + atomic_set(&hif_state->fw_event_pending, 0); + msg_callbacks->fwEventHandler(msg_callbacks->Context, A_ERROR); + } + + if (hif_state->sc->ol_sc->target_status == OL_TRGET_STATUS_RESET) + return 0; + + for (;;) { + struct HIF_CE_pipe_info *pipe_info; + int send_done = 0; + + adf_os_spin_lock(&hif_state->completion_pendingq_lock); + + if (!hif_state->completion_pendingq_head) { + /* We are atomically sure that there is no pending work */ + adf_os_atomic_inc(&hif_state->hif_thread_idle); + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + break; /* All pending completions are handled */ + } + + /* Dequeue the first unprocessed but completed transfer */ + compl_state = hif_state->completion_pendingq_head; + hif_state->completion_pendingq_head = compl_state->next; + adf_os_spin_unlock(&hif_state->completion_pendingq_lock); + + pipe_info = (struct HIF_CE_pipe_info *)compl_state->ce_context; + if (compl_state->send_or_recv == HIF_CE_COMPLETE_SEND) { + msg_callbacks->txCompletionHandler(msg_callbacks->Context, compl_state->transfer_context, compl_state->transfer_id); + send_done = 1; + } else { /* compl_state->send_or_recv == HIF_CE_COMPLETE_RECV */ + adf_nbuf_t netbuf; + unsigned int nbytes; + + atomic_inc(&pipe_info->recv_bufs_needed); + hif_post_recv_buffers((HIF_DEVICE *)hif_state); + + netbuf = (adf_nbuf_t)compl_state->transfer_context; + nbytes = compl_state->nbytes; + /* + To see the following debug output, enable the HIF_PCI_DEBUG flag in + the debug module declaration in this source file + */ + AR_DEBUG_PRINTF(HIF_PCI_DEBUG,("HIF_PCI_CE_recv_data netbuf=%p nbytes=%d\n", netbuf, nbytes)); + if (nbytes <= pipe_info->buf_sz) { + adf_nbuf_set_pktlen(netbuf, nbytes); + msg_callbacks->rxCompletionHandler(msg_callbacks->Context, + netbuf, pipe_info->pipe_num); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Rx message netbuf:%p nbytes:%d\n", + netbuf, nbytes)); + adf_nbuf_free(netbuf); + } + } + + /* Recycle completion state back to the pipe it came from. */ + compl_state->next = NULL; + compl_state->send_or_recv = HIF_CE_COMPLETE_FREE; + adf_os_spin_lock(&pipe_info->completion_freeq_lock); + if (pipe_info->completion_freeq_head) { + pipe_info->completion_freeq_tail->next = compl_state; + } else { + pipe_info->completion_freeq_head = compl_state; + } + pipe_info->completion_freeq_tail = compl_state; + pipe_info->num_sends_allowed += send_done; + adf_os_spin_unlock(&pipe_info->completion_freeq_lock); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return 0; +} + +/* + * Install pending msg callbacks. + * + * TBDXXX: This hack is needed because upper layers install msg callbacks + * for use with HTC before BMI is done; yet this HIF implementation + * needs to continue to use BMI msg callbacks. Really, upper layers + * should not register HTC callbacks until AFTER BMI phase. + */ +static void +hif_msg_callbacks_install(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + A_MEMCPY(&hif_state->msg_callbacks_current, + &hif_state->msg_callbacks_pending, sizeof(hif_state->msg_callbacks_pending)); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + +int +HIFConfigureDevice(HIF_DEVICE *hif_device, HIF_DEVICE_CONFIG_OPCODE opcode, + void *config, u_int32_t configLen) +{ + int status = EOK; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + switch (opcode) { + case HIF_DEVICE_GET_OS_DEVICE: + { + HIF_DEVICE_OS_DEVICE_INFO *info = (HIF_DEVICE_OS_DEVICE_INFO *)config; + + info->pOSDevice = (void *)sc->dev; + } + break; + + case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: + /* provide fake block sizes for mailboxes to satisfy upper layer software */ + ((u_int32_t *)config)[0] = 16; + ((u_int32_t *)config)[1] = 16; + ((u_int32_t *)config)[2] = 16; + ((u_int32_t *)config)[3] = 16; + break; + + case HIF_BMI_DONE: + { + printk("%s: BMI_DONE\n", __FUNCTION__); /* TBDXXX */ + break; + } + + default: + status = !EOK; + break; + + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return status; +} + +void +HIFClaimDevice(HIF_DEVICE *hif_device, void *claimedContext) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + hif_state->claimedContext = claimedContext; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + +void +HIFReleaseDevice(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + hif_state->claimedContext = NULL; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + +void +HIFGetDefaultPipe(HIF_DEVICE *hif_device, a_uint8_t *ULPipe, a_uint8_t *DLPipe) +{ + int ul_is_polled, dl_is_polled; + + (void)HIFMapServiceToPipe( + hif_device, HTC_CTRL_RSVD_SVC, + ULPipe, DLPipe, + &ul_is_polled, &dl_is_polled); +} + +/* TBDXXX - temporary mapping while we have too few CE's */ +int +HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, a_uint8_t *ULPipe, a_uint8_t *DLPipe, int *ul_is_polled, int *dl_is_polled) +{ + int status = EOK; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + *dl_is_polled = 0; /* polling for received messages not supported */ + switch (ServiceId) { + case HTT_DATA_MSG_SVC: + /* + * Host->target HTT gets its own pipe, so it can be polled + * while other pipes are interrupt driven. + */ + *ULPipe = 4; + /* + * Use the same target->host pipe for HTC ctrl, HTC raw streams, + * and HTT. + */ + *DLPipe = 1; + break; + + case HTC_CTRL_RSVD_SVC: + case HTC_RAW_STREAMS_SVC: + /* + * Note: HTC_RAW_STREAMS_SVC is currently unused, and + * HTC_CTRL_RSVD_SVC could share the same pipe as the + * WMI services. So, if another CE is needed, change + * this to *ULPipe = 3, which frees up CE 0. + */ + //*ULPipe = 3; + *ULPipe = 0; + *DLPipe = 1; + break; + + case WMI_DATA_BK_SVC: + /* + * To avoid some confusions, better to introduce new EP-ping + * service instead of using existed services. Until the main + * framework support this, keep this design. + */ + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + *ULPipe = 4; + *DLPipe = 1; + break; + } + case WMI_DATA_BE_SVC: + case WMI_DATA_VI_SVC: + case WMI_DATA_VO_SVC: + + case WMI_CONTROL_SVC: + *ULPipe = 3; + *DLPipe = 2; + break; + +#ifdef IPA_UC_OFFLOAD + case WDI_IPA_TX_SVC: + *ULPipe = 5; + break; +#endif /* IPA_UC_OFFLOAD */ + + /* pipe 5 unused */ + /* pipe 6 reserved */ + /* pipe 7 reserved */ + + default: + status = !EOK; + break; + } + *ul_is_polled = (host_CE_config[*ULPipe].flags & CE_ATTR_DISABLE_INTR) != 0; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return status; +} + +void HIFDumpTargetMemory(HIF_DEVICE *hif_device, void *ramdump_base, + u_int32_t address, u_int32_t size) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + A_target_id_t targid; + u_int32_t loc = address; + u_int32_t val = 0; + u_int32_t j = 0; + u8 *temp = ramdump_base; + + hif_state = (struct HIF_CE_state *)hif_device; + sc = hif_state->sc; + targid = hif_state->targid; + + A_TARGET_ACCESS_BEGIN(targid); + while (j < size) { + val = A_PCI_READ32(sc->mem + loc + j); + OS_MEMCPY(temp, &val, 4); + j += 4; + temp += 4; + } + A_TARGET_ACCESS_END(targid); +} + +/* + * TBDXXX: Should be a function call specific to each Target-type. + * This convoluted macro converts from Target CPU Virtual Address Space to CE Address Space. + * As part of this process, we conservatively fetch the current PCIE_BAR. MOST of the time, + * this should match the upper bits of PCI space for this device; but that's not guaranteed. + */ +#define TARG_CPU_SPACE_TO_CE_SPACE(pci_addr, addr) \ + (((A_PCI_READ32((pci_addr)+(SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \ + | 0x100000 | ((addr) & 0xfffff)) + +/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ +#define DIAG_ACCESS_CE_TIMEOUT_MS 10 + +/* + * Diagnostic read/write access is provided for startup/config/debug usage. + * Caller must guarantee proper alignment, when applicable, and single user + * at any moment. + */ + +A_STATUS +HIFDiagReadMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + struct ol_softc *scn; + A_target_id_t targid; + A_STATUS status = EOK; + CE_addr_t buf; + unsigned int completed_nbytes, orig_nbytes, remaining_bytes; + unsigned int id; + unsigned int flags; + struct CE_handle *ce_diag; + CE_addr_t CE_data; /* Host buffer address in CE space */ + adf_os_dma_addr_t CE_data_base = 0; + void *data_buf = NULL; + int i; + hif_state = (struct HIF_CE_state *)hif_device; + sc = hif_state->sc; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" %s\n",__FUNCTION__)); + + + /* This code cannot handle reads to non-memory space. Redirect to the + * register read fn but preserve the multi word read capability of this fn + */ + if (address < DRAM_BASE_ADDRESS) { + + if ((address & 0x3) || ((uintptr_t)data & 0x3)) { + return (-EIO); + } + + while ((nbytes >= 4) && + (A_OK == (status = HIFDiagReadAccess(hif_device, address, + (A_UINT32*)data)))) { + + nbytes -= sizeof(A_UINT32); + address+= sizeof(A_UINT32); + data += sizeof(A_UINT32); + + } + + return status; + } + + + scn = sc->ol_sc; + targid = hif_state->targid; + ce_diag = hif_state->ce_diag; + + A_TARGET_ACCESS_LIKELY(targid); + + /* + * Allocate a temporary bounce buffer to hold caller's data + * to be DMA'ed from Target. This guarantees + * 1) 4-byte alignment + * 2) Buffer in DMA-able space + */ + orig_nbytes = nbytes; + data_buf = (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev, + orig_nbytes, + &CE_data_base); + if (!data_buf) { + status = A_NO_MEMORY; + goto done; + } + adf_os_mem_set(data_buf, 0, orig_nbytes); + pci_dma_sync_single_for_device(scn->sc_osdev->bdev, CE_data_base, orig_nbytes, PCI_DMA_FROMDEVICE); + + remaining_bytes = orig_nbytes; + CE_data = CE_data_base; + while (remaining_bytes) { + nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT); + { + status = CE_recv_buf_enqueue(ce_diag, NULL, CE_data); + if (status != A_OK) { + goto done; + } + } + + { /* Request CE to send from Target(!) address to Host buffer */ + /* + * The address supplied by the caller is in the + * Target CPU virtual address space. + * + * In order to use this address with the diagnostic CE, + * convert it from + * Target CPU virtual address space + * to + * CE address space + */ + A_TARGET_ACCESS_BEGIN_RET(targid); + address = TARG_CPU_SPACE_TO_CE_SPACE(sc->mem, address); + A_TARGET_ACCESS_END_RET(targid); + + status = CE_send(ce_diag, NULL, (CE_addr_t)address, nbytes, 0, 0); + if (status != EOK) { + goto done; + } + } + + i=0; + while (CE_completed_send_next(ce_diag, NULL, NULL, &buf, + &completed_nbytes, &id, + NULL, NULL) != A_OK) { + A_MDELAY(1); + if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { + status = A_EBUSY; + goto done; + } + } + if (nbytes != completed_nbytes) { + status = A_ERROR; + goto done; + } + if (buf != (CE_addr_t)address) { + status = A_ERROR; + goto done; + } + + i=0; + while (CE_completed_recv_next(ce_diag, NULL, NULL, &buf, &completed_nbytes, &id, &flags) != A_OK) { + A_MDELAY(1); + if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { + status = A_EBUSY; + goto done; + } + } + if (nbytes != completed_nbytes) { + status = A_ERROR; + goto done; + } + if (buf != CE_data) { + status = A_ERROR; + goto done; + } + + remaining_bytes -= nbytes; + address += nbytes; + CE_data += nbytes; + } + +done: + A_TARGET_ACCESS_UNLIKELY(targid); + + if (status == A_OK) { + /* Copy data from allocated DMA buf to caller's buf */ + A_MEMCPY(data, data_buf, orig_nbytes); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s failure (0x%x)\n", __FUNCTION__, address)); + } + + if (data_buf) { + pci_free_consistent(scn->sc_osdev->bdev, orig_nbytes, + data_buf, CE_data_base); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return status; +} + +/* Read 4-byte aligned data from Target memory or register */ +A_STATUS +HIFDiagReadAccess(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT32 *data) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + + hif_state = (struct HIF_CE_state *)hif_device; + sc = hif_state->sc; + + if (address >= DRAM_BASE_ADDRESS) { /* Assume range doesn't cross this boundary */ + return HIFDiagReadMem(hif_device, address, (A_UINT8 *)data, sizeof(A_UINT32)); + } else { + A_target_id_t targid; + + targid = hif_state->targid; + + A_TARGET_ACCESS_BEGIN_RET(targid); + *data = A_TARGET_READ(targid, address); + A_TARGET_ACCESS_END_RET(targid); + + return A_OK; + } +} + +A_STATUS +HIFDiagWriteMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + struct ol_softc *scn; + A_target_id_t targid; + A_STATUS status = A_OK; + CE_addr_t buf; + unsigned int completed_nbytes, orig_nbytes, remaining_bytes; + unsigned int id; + unsigned int flags; + struct CE_handle *ce_diag; + void *data_buf = NULL; + CE_addr_t CE_data; /* Host buffer address in CE space */ + adf_os_dma_addr_t CE_data_base = 0; + int i; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" %s\n",__FUNCTION__)); + + hif_state = (struct HIF_CE_state *)hif_device; + sc = hif_state->sc; + scn = sc->ol_sc; + targid = hif_state->targid; + ce_diag = hif_state->ce_diag; + + A_TARGET_ACCESS_LIKELY(targid); + + /* + * Allocate a temporary bounce buffer to hold caller's data + * to be DMA'ed to Target. This guarantees + * 1) 4-byte alignment + * 2) Buffer in DMA-able space + */ + orig_nbytes = nbytes; + data_buf = (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev, + orig_nbytes, + &CE_data_base); + if (!data_buf) { + status = A_NO_MEMORY; + goto done; + } + + /* Copy caller's data to allocated DMA buf */ + A_MEMCPY(data_buf, data, orig_nbytes); + pci_dma_sync_single_for_device(scn->sc_osdev->bdev, CE_data_base, orig_nbytes, PCI_DMA_TODEVICE); + + /* + * The address supplied by the caller is in the + * Target CPU virtual address space. + * + * In order to use this address with the diagnostic CE, + * convert it from + * Target CPU virtual address space + * to + * CE address space + */ + A_TARGET_ACCESS_BEGIN_RET(targid); + address = TARG_CPU_SPACE_TO_CE_SPACE(sc->mem, address); + A_TARGET_ACCESS_END_RET(targid); + + remaining_bytes = orig_nbytes; + CE_data = CE_data_base; + while (remaining_bytes) { + nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT); + + { /* Set up to receive directly into Target(!) address */ + status = CE_recv_buf_enqueue(ce_diag, NULL, address); + if (status != A_OK) { + goto done; + } + } + + { + /* + * Request CE to send caller-supplied data that + * was copied to bounce buffer to Target(!) address. + */ + status = CE_send(ce_diag, NULL, (CE_addr_t)CE_data, nbytes, 0, 0); + if (status != A_OK) { + goto done; + } + } + + i=0; + while (CE_completed_send_next(ce_diag, NULL, NULL, &buf, + &completed_nbytes, &id, + NULL, NULL) != A_OK) { + A_MDELAY(1); + if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { + status = A_EBUSY; + goto done; + } + } + + if (nbytes != completed_nbytes) { + status = A_ERROR; + goto done; + } + + if (buf != CE_data) { + status = A_ERROR; + goto done; + } + + i=0; + while (CE_completed_recv_next(ce_diag, NULL, NULL, &buf, &completed_nbytes, &id, &flags) != A_OK) { + A_MDELAY(1); + if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { + status = A_EBUSY; + goto done; + } + } + + if (nbytes != completed_nbytes) { + status = A_ERROR; + goto done; + } + + if (buf != address) { + status = A_ERROR; + goto done; + } + + remaining_bytes -= nbytes; + address += nbytes; + CE_data += nbytes; + } + +done: + A_TARGET_ACCESS_UNLIKELY(targid); + + if (data_buf) { + pci_free_consistent(scn->sc_osdev->bdev, orig_nbytes, + data_buf, CE_data_base); + } + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s failure (0x%x)\n", __FUNCTION__, address)); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return status; +} + +/* Write 4B data to Target memory or register */ +A_STATUS +HIFDiagWriteAccess(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT32 data) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + + hif_state = (struct HIF_CE_state *)hif_device; + sc = hif_state->sc; + if (address >= DRAM_BASE_ADDRESS) { /* Assume range doesn't cross this boundary */ + A_UINT32 data_buf = data; + + return HIFDiagWriteMem(hif_device, address, (A_UINT8 *)&data_buf, sizeof(A_UINT32)); + } else { + struct HIF_CE_state *hif_state; + A_target_id_t targid; + + hif_state = (struct HIF_CE_state *)hif_device; + targid = hif_state->targid; + + A_TARGET_ACCESS_BEGIN_RET(targid); + A_TARGET_WRITE(targid, address, data); + A_TARGET_ACCESS_END_RET(targid); + + return A_OK; + } +} + +/** + * hif_dump_pipe_debug_count() - Log error count + * @hif_device: HIF device pointer. + * + * Output the pipe error counts of each pipe to log file + * + * Return: N/A + */ +void hif_dump_pipe_debug_count(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + int pipe_num; + + if (hif_device == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s hif_device is NULL", __func__)); + return; + } + hif_state = (struct HIF_CE_state *)hif_device; + if (hif_state == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s hif_state is NULL", __func__)); + return; + } + sc = hif_state->sc; + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct HIF_CE_pipe_info *pipe_info; + + pipe_info = &hif_state->pipe_info[pipe_num]; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s pipe_id = %d, recv_bufs_needed = %d, nbuf_alloc_err_count = %u, nbuf_dma_err_count = %u, nbuf_ce_enqueue_err_count = %u", + __func__, pipe_info->pipe_num, + atomic_read(&pipe_info->recv_bufs_needed), + pipe_info->nbuf_alloc_err_count, + pipe_info->nbuf_dma_err_count, + pipe_info->nbuf_ce_enqueue_err_count)); + } +} + +static int +hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info) +{ + struct CE_handle *ce_hdl; + adf_os_size_t buf_sz; + struct HIF_CE_state *hif_state = pipe_info->HIF_CE_state; + struct hif_pci_softc *sc = hif_state->sc; + struct ol_softc *scn = sc->ol_sc; + a_status_t ret; + uint32_t bufs_posted = 0; + + buf_sz = pipe_info->buf_sz; + if (buf_sz == 0) { + /* Unused Copy Engine */ + return 0; + } + + ce_hdl = pipe_info->ce_hdl; + + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + while (atomic_read(&pipe_info->recv_bufs_needed) > 0) { + CE_addr_t CE_data; /* CE space buffer address*/ + adf_nbuf_t nbuf; + int status; + + atomic_dec(&pipe_info->recv_bufs_needed); + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + + nbuf = adf_nbuf_alloc(scn->adf_dev, buf_sz, 0, 4, FALSE); + if (!nbuf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s buf alloc error [%d] needed %d\n", + __func__, pipe_info->pipe_num, + atomic_read(&pipe_info->recv_bufs_needed))); + atomic_inc(&pipe_info->recv_bufs_needed); + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + pipe_info->nbuf_alloc_err_count++; + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + return 1; + } + + /* + * adf_nbuf_peek_header(nbuf, &data, &unused); + * CE_data = dma_map_single(dev, data, buf_sz, DMA_FROM_DEVICE); + */ + ret = adf_nbuf_map_single(scn->adf_dev, nbuf, ADF_OS_DMA_FROM_DEVICE); + + if (unlikely(ret != A_STATUS_OK)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s mapping error\n", __func__)); + adf_nbuf_free(nbuf); + atomic_inc(&pipe_info->recv_bufs_needed); + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + pipe_info->nbuf_dma_err_count++; + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + return 1; + } + + CE_data = adf_nbuf_get_frag_paddr_lo(nbuf, 0); + + pci_dma_sync_single_for_device(scn->sc_osdev->bdev, CE_data, + buf_sz, PCI_DMA_FROMDEVICE); + status = CE_recv_buf_enqueue(ce_hdl, (void *)nbuf, CE_data); + A_ASSERT(status == EOK); + if (status != EOK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s CE_recv_buf_enqueue error [%d] needed %d\n", + __func__, pipe_info->pipe_num, + atomic_read(&pipe_info->recv_bufs_needed))); + atomic_inc(&pipe_info->recv_bufs_needed); + adf_nbuf_free(nbuf); + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + pipe_info->nbuf_ce_enqueue_err_count++; + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + return 1; + } + + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + bufs_posted++; + } + pipe_info->nbuf_alloc_err_count = + (pipe_info->nbuf_alloc_err_count > bufs_posted)? + pipe_info->nbuf_alloc_err_count - bufs_posted : 0; + pipe_info->nbuf_dma_err_count = + (pipe_info->nbuf_dma_err_count > bufs_posted)? + pipe_info->nbuf_dma_err_count - bufs_posted : 0; + pipe_info->nbuf_ce_enqueue_err_count = + (pipe_info->nbuf_ce_enqueue_err_count > bufs_posted)? + pipe_info->nbuf_ce_enqueue_err_count - bufs_posted : 0; + + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + + return 0; +} + +/* + * Try to post all desired receive buffers for all pipes. + * Returns 0 if all desired buffers are posted, + * non-zero if were were unable to completely + * replenish receive buffers. + */ +static int +hif_post_recv_buffers(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + A_target_id_t targid = hif_state->targid; + int pipe_num, rv=0; + + A_TARGET_ACCESS_LIKELY(targid); + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct HIF_CE_pipe_info *pipe_info; + + pipe_info = &hif_state->pipe_info[pipe_num]; + if (hif_post_recv_buffers_for_pipe(pipe_info)) { + rv = 1; + goto done; + } + } + +done: + A_TARGET_ACCESS_UNLIKELY(targid); + + return rv; +} + +void HIFDump(HIF_DEVICE *hif_device, u_int8_t cmd_id, bool start) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + + switch (cmd_id) { + case AGC_DUMP: + if (start) + priv_start_agc(sc); + else + priv_dump_agc(sc); + break; + + case CHANINFO_DUMP: + if (start) + priv_start_cap_chaninfo(sc); + else + priv_dump_chaninfo(sc); + break; + + case BB_WATCHDOG_DUMP: + priv_dump_bbwatchdog(sc); + break; + +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + case PCIE_ACCESS_DUMP: + HIFTargetDumpAccessLog(); + break; +#endif + default: + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Invalid htc dump command\n")); + break; + } +} + +A_STATUS +HIFStart(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + if (hif_completion_thread_startup(hif_state)) + return A_ERROR; + + hif_msg_callbacks_install(hif_device); + + /* Post buffers once to start things off. */ + (void)hif_post_recv_buffers(hif_device); + + hif_state->started = TRUE; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return A_OK; +} + +void +HIFGrowBuffers(hif_handle_t hif_hdl) +{ + struct hif_pci_softc *sc = hif_hdl; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *) sc->hif_device; + struct HIF_CE_pipe_info *pipe_info; + struct CE_attr *attr; + int pipe_num; + + for (pipe_num = 0; pipe_num < sc->ce_count; pipe_num++) { + pipe_info = &hif_state->pipe_info[pipe_num]; + attr = &host_CE_config[pipe_num]; + if (attr->dest_nentries > 0) { + adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock); + atomic_set(&pipe_info->recv_bufs_needed, attr->dest_nentries-1 - initBufferCount(attr->dest_nentries -1)); + adf_os_spin_unlock_bh(&pipe_info->recv_bufs_needed_lock); + if (hif_post_recv_buffers_for_pipe(pipe_info)) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s failed to grow\n",__FUNCTION__)); + break; + } + } + } +} + +void +hif_recv_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info) +{ + struct ol_softc *scn; + struct CE_handle *ce_hdl; + u_int32_t buf_sz; + struct HIF_CE_state *hif_state; + struct hif_pci_softc *sc; + adf_nbuf_t netbuf; + CE_addr_t CE_data; + void *per_CE_context; + + buf_sz = pipe_info->buf_sz; + if (buf_sz == 0) { + /* Unused Copy Engine */ + return; + } + + hif_state = pipe_info->HIF_CE_state; + if (!hif_state->started) { + return; + } + + sc = hif_state->sc; + scn = sc->ol_sc; + ce_hdl = pipe_info->ce_hdl; + + if (scn->adf_dev == NULL) { + return; + } + while (CE_revoke_recv_next(ce_hdl, &per_CE_context, (void **)&netbuf, &CE_data) == A_OK) + { + adf_nbuf_unmap_single(scn->adf_dev, netbuf, ADF_OS_DMA_FROM_DEVICE); + adf_nbuf_free(netbuf); + } +} + +void +hif_send_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info) +{ + struct CE_handle *ce_hdl; + struct HIF_CE_state *hif_state; + adf_nbuf_t netbuf; + void *per_CE_context; + CE_addr_t CE_data; + unsigned int nbytes; + unsigned int id; + u_int32_t buf_sz; + + buf_sz = pipe_info->buf_sz; + if (buf_sz == 0) { + /* Unused Copy Engine */ + return; + } + + hif_state = pipe_info->HIF_CE_state; + if (!hif_state->started) { + return; + } + + ce_hdl = pipe_info->ce_hdl; + + while (CE_cancel_send_next(ce_hdl, &per_CE_context, (void **)&netbuf, &CE_data, &nbytes, &id) == A_OK) + { + if (netbuf != CE_SENDLIST_ITEM_CTXT) + { + /* + * Packets enqueued by htt_h2t_ver_req_msg() and + * htt_h2t_rx_ring_cfg_msg_ll() have already been freed in + * htt_htc_misc_pkt_pool_free() in WLANTL_Close(), so do not + * free them here again by checking whether it's the EndPoint + * which they are queued in. + */ + if (id == hif_state->sc->htc_endpoint) { + return; + } + /* Indicate the completion to higer layer to free the buffer */ + hif_state->msg_callbacks_current.txCompletionHandler( + hif_state->msg_callbacks_current.Context, netbuf, id); + } + } +} + +/* + * Cleanup residual buffers for device shutdown: + * buffers that were enqueued for receive + * buffers that were to be sent + * Note: Buffers that had completed but which were + * not yet processed are on a completion queue. They + * are handled when the completion thread shuts down. + */ +void +hif_buffer_cleanup(struct HIF_CE_state *hif_state) +{ + struct hif_pci_softc *sc = hif_state->sc; + int pipe_num; + + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct HIF_CE_pipe_info *pipe_info; + + pipe_info = &hif_state->pipe_info[pipe_num]; + hif_recv_buffer_cleanup_on_pipe(pipe_info); + hif_send_buffer_cleanup_on_pipe(pipe_info); + } +} + +void +HIFFlushSurpriseRemove(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + hif_buffer_cleanup(hif_state); +} + +void +HIFStop(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + int pipe_num; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + if (!hif_state->started && !sc->hif_init_done) { + return; /* already stopped or stopping */ + } + + sc->hif_init_done = FALSE; + + if (hif_state->started) { + /* sync shutdown */ + hif_completion_thread_shutdown(hif_state); + hif_completion_thread(hif_state); + } else { + hif_completion_thread_shutdown(hif_state); + } + + /* + * At this point, asynchronous threads are stopped, + * The Target should not DMA nor interrupt, Host code may + * not initiate anything more. So we just need to clean + * up Host-side state. + */ + +#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) + athdiag_procfs_remove(); +#endif + + hif_buffer_cleanup(hif_state); + + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct HIF_CE_pipe_info *pipe_info; + + pipe_info = &hif_state->pipe_info[pipe_num]; + if (pipe_info->ce_hdl) { + CE_fini(pipe_info->ce_hdl); + pipe_info->ce_hdl = NULL; + pipe_info->buf_sz = 0; + } + } + + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_free(&hif_state->sleep_timer); + + hif_state->started = FALSE; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); +} + + +int +hifWaitForPendingRecv(HIF_DEVICE *device) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" %s\n",__FUNCTION__)); + /* Nothing needed -- CE layer will notify via recv completion */ + + return EOK; +} + +void +HIFShutDownDevice(HIF_DEVICE *hif_device) +{ + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+%s\n",__FUNCTION__)); + + if (hif_device) { + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + + HIFStop(hif_device); + A_FREE(hif_state); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-%s\n",__FUNCTION__)); +} + +/* Track a BMI transaction that is in progress */ +#ifndef BIT +#define BIT(n) (1 << (n)) +#endif + +typedef enum { + BMI_REQ_SEND_DONE = BIT(0), /* the bmi request is done(tx completion) */ + BMI_RESP_RECV_DONE = BIT(1), /* the bmi respond is received */ +} BMI_TRANSACTION_FLAGS; + +struct BMI_transaction { + struct HIF_CE_state *hif_state; + adf_os_mutex_t bmi_transaction_sem; + A_UINT8 *bmi_request_host; /* Request BMI message in Host address space */ + CE_addr_t bmi_request_CE; /* Request BMI message in CE address space */ + u_int32_t bmi_request_length; /* Length of BMI request */ + A_UINT8 *bmi_response_host; /* Response BMI message in Host address space */ + CE_addr_t bmi_response_CE; /* Response BMI message in CE address space */ + unsigned int bmi_response_length;/* Length of received response */ + unsigned int bmi_timeout_ms; + A_UINT32 bmi_transaction_flags; /* flags for the transcation in bmi stage */ +}; + +/* + * send/recv completion functions for BMI. + * NB: The "net_buf" parameter is actually just a straight buffer, not an sk_buff. + */ +static void +HIF_BMI_send_done(struct CE_handle *copyeng, void *ce_context, void *transfer_context, + CE_addr_t data, unsigned int nbytes, unsigned int transfer_id, + unsigned int sw_index, unsigned int hw_index) +{ + struct BMI_transaction *transaction = (struct BMI_transaction *)transfer_context; + struct hif_pci_softc *sc = transaction->hif_state->sc; + +#ifdef BMI_RSP_POLLING + /* + * Fix EV118783, Release a semaphore after sending + * no matter whether a response is been expecting now. + */ + adf_os_mutex_release(sc->ol_sc->adf_dev, &transaction->bmi_transaction_sem); +#else + /* + * If a response is anticipated, we'll complete the + * transaction if the response has been received. + * If no response is anticipated, complete the + * transaction now. + */ + transaction->bmi_transaction_flags |= BMI_REQ_SEND_DONE; + + /* resp is't needed or has already been received, never assume resp comes later then this */ + if (!transaction->bmi_response_CE || + (transaction->bmi_transaction_flags & BMI_RESP_RECV_DONE)) { + adf_os_mutex_release(sc->ol_sc->adf_dev, &transaction->bmi_transaction_sem); + } +#endif +} + +#ifndef BMI_RSP_POLLING +static void +HIF_BMI_recv_data(struct CE_handle *copyeng, void *ce_context, void *transfer_context, + CE_addr_t data, unsigned int nbytes, unsigned int transfer_id, unsigned int flags) +{ + struct BMI_transaction *transaction = (struct BMI_transaction *)transfer_context; + struct hif_pci_softc *sc = transaction->hif_state->sc; + + transaction->bmi_response_length = nbytes; + transaction->bmi_transaction_flags |= BMI_RESP_RECV_DONE; + + /* when both send/recv are done, the sem can be released */ + if (transaction->bmi_transaction_flags & BMI_REQ_SEND_DONE) { + adf_os_mutex_release(sc->ol_sc->adf_dev, &transaction->bmi_transaction_sem); + } +} +#endif + +int +HIFExchangeBMIMsg(HIF_DEVICE *hif_device, + A_UINT8 *bmi_request, + u_int32_t request_length, + A_UINT8 *bmi_response, + u_int32_t *bmi_response_lengthp, + u_int32_t TimeoutMS) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + struct ol_softc *scn = sc->ol_sc; + struct HIF_CE_pipe_info *send_pipe_info = &(hif_state->pipe_info[BMI_CE_NUM_TO_TARG]); + struct CE_handle *ce_send = send_pipe_info->ce_hdl; + CE_addr_t CE_request, CE_response = 0; + A_target_id_t targid = hif_state->targid; + struct BMI_transaction *transaction = NULL; + int status = EOK; + struct HIF_CE_pipe_info *recv_pipe_info = &(hif_state->pipe_info[BMI_CE_NUM_TO_HOST]); + struct CE_handle *ce_recv = recv_pipe_info->ce_hdl; + +#ifdef BMI_RSP_POLLING + CE_addr_t buf; + unsigned int completed_nbytes, id, flags; + int i; +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" %s\n",__FUNCTION__)); + + transaction = (struct BMI_transaction *)A_MALLOC(sizeof(*transaction)); + if (unlikely(!transaction)) { + return -ENOMEM; + } + + A_TARGET_ACCESS_LIKELY(targid); + + /* Initialize bmi_transaction_sem to block */ + adf_os_init_mutex(&transaction->bmi_transaction_sem); + adf_os_mutex_acquire(scn->adf_dev, &transaction->bmi_transaction_sem); + + transaction->hif_state = hif_state; + transaction->bmi_request_host = bmi_request; + transaction->bmi_request_length = request_length; + transaction->bmi_response_length = 0; + transaction->bmi_timeout_ms = TimeoutMS; + transaction->bmi_transaction_flags = 0; + + /* + * CE_request = dma_map_single(dev, (void *)bmi_request, request_length, DMA_TO_DEVICE); + */ + CE_request = scn->BMICmd_pa; + transaction->bmi_request_CE = CE_request; + + if (bmi_response) { + + /* + * CE_response = dma_map_single(dev, bmi_response, BMI_DATASZ_MAX, DMA_FROM_DEVICE); + */ + CE_response = scn->BMIRsp_pa; + transaction->bmi_response_host = bmi_response; + transaction->bmi_response_CE = CE_response; + /* dma_cache_sync(dev, bmi_response, BMI_DATASZ_MAX, DMA_FROM_DEVICE); */ + pci_dma_sync_single_for_device(scn->sc_osdev->bdev, CE_response, BMI_DATASZ_MAX, PCI_DMA_FROMDEVICE); + CE_recv_buf_enqueue(ce_recv, transaction, transaction->bmi_response_CE); + /* NB: see HIF_BMI_recv_done */ + } else { + transaction->bmi_response_host = NULL; + transaction->bmi_response_CE = 0; + } + + /* dma_cache_sync(dev, bmi_request, request_length, DMA_TO_DEVICE); */ + pci_dma_sync_single_for_device(scn->sc_osdev->bdev, CE_request, request_length, PCI_DMA_TODEVICE); + + status = CE_send(ce_send, transaction, CE_request, request_length, -1, 0); + ASSERT(status == EOK); + /* NB: see HIF_BMI_send_done */ + + /* TBDXXX: handle timeout */ + + /* Wait for BMI request/response transaction to complete */ + /* Always just wait for BMI request here if BMI_RSP_POLLING is defined */ + while (adf_os_mutex_acquire(scn->adf_dev, &transaction->bmi_transaction_sem)) { + /*need some break out condition(time out?)*/ + } + + if (bmi_response) { +#ifdef BMI_RSP_POLLING + /* Fix EV118783, do not wait a semaphore for the BMI response + * since the relative interruption may be lost. + * poll the BMI response instead. + */ + i = 0; + while (CE_completed_recv_next(ce_recv, NULL, NULL, &buf, &completed_nbytes, &id, &flags) != A_OK) { + if (i++ > BMI_RSP_TO_MILLISEC) { + printk("%s:error, can't get bmi response\n", __func__); + status = A_EBUSY; + break; + } + OS_DELAY(1000); + } + + if ((status == EOK) && bmi_response_lengthp) { + *bmi_response_lengthp = completed_nbytes; + } +#else + if ((status == EOK) && bmi_response_lengthp) { + *bmi_response_lengthp = transaction->bmi_response_length; + } +#endif + + } + + /* dma_unmap_single(dev, transaction->bmi_request_CE, request_length, DMA_TO_DEVICE); */ + //bus_unmap_single(scn->sc_osdev, transaction->bmi_request_CE, request_length, BUS_DMA_TODEVICE); + + if (status != EOK) { + CE_addr_t unused_buffer; + unsigned int unused_nbytes; + unsigned int unused_id; + + CE_cancel_send_next(ce_send, NULL, NULL, &unused_buffer, &unused_nbytes, &unused_id); + } + + A_TARGET_ACCESS_UNLIKELY(targid); + A_FREE(transaction); + return status; +} + + +/* CE_PCI TABLE */ +/* + * NOTE: the table below is out of date, though still a useful reference. + * Refer to target_service_to_CE_map and HIFMapServiceToPipe for the actual + * mapping of HTC services to HIF pipes. + */ +/* + * This authoritative table defines Copy Engine configuration and the mapping + * of services/endpoints to CEs. A subset of this information is passed to + * the Target during startup as a prerequisite to entering BMI phase. + * See: + * target_service_to_CE_map - Target-side mapping + * HIFMapServiceToPipe - Host-side mapping + * target_CE_config - Target-side configuration + * host_CE_config - Host-side configuration +============================================================================= +Purpose | Service / Endpoint | CE | Dire | Xfer | Xfer + | | | ctio | Size | Frequency + | | | n | | +============================================================================= +tx | HTT_DATA (downlink) | CE 0 | h->t | medium - | very frequent +descriptor | | | | O(100B) | and regular +download | | | | | +----------------------------------------------------------------------------- +rx | HTT_DATA (uplink) | CE 1 | t->h | small - | frequent and +indication | | | | O(10B) | regular +upload | | | | | +----------------------------------------------------------------------------- +MSDU | DATA_BK (uplink) | CE 2 | t->h | large - | rare +upload | | | | O(1000B) | (frequent +e.g. noise | | | | | during IP1.0 +packets | | | | | testing) +----------------------------------------------------------------------------- +MSDU | DATA_BK (downlink) | CE 3 | h->t | large - | very rare +download | | | | O(1000B) | (frequent +e.g. | | | | | during IP1.0 +misdirecte | | | | | testing) +d EAPOL | | | | | +packets | | | | | +----------------------------------------------------------------------------- +n/a | DATA_BE, DATA_VI | CE 2 | t->h | | never(?) + | DATA_VO (uplink) | | | | +----------------------------------------------------------------------------- +n/a | DATA_BE, DATA_VI | CE 3 | h->t | | never(?) + | DATA_VO (downlink) | | | | +----------------------------------------------------------------------------- +WMI events | WMI_CONTROL (uplink) | CE 4 | t->h | medium - | infrequent + | | | | O(100B) | +----------------------------------------------------------------------------- +WMI | WMI_CONTROL | CE 5 | h->t | medium - | infrequent +messages | (downlink) | | | O(100B) | + | | | | | +----------------------------------------------------------------------------- +n/a | HTC_CTRL_RSVD, | CE 1 | t->h | | never(?) + | HTC_RAW_STREAMS | | | | + | (uplink) | | | | +----------------------------------------------------------------------------- +n/a | HTC_CTRL_RSVD, | CE 0 | h->t | | never(?) + | HTC_RAW_STREAMS | | | | + | (downlink) | | | | +----------------------------------------------------------------------------- +diag | none (raw CE) | CE 7 | t<>h | 4 | Diag Window + | | | | | infrequent +============================================================================= + */ + +/* + * Map from service/endpoint to Copy Engine. + * This table is derived from the CE_PCI TABLE, above. + * It is passed to the Target at startup for use by firmware. + */ +static struct service_to_pipe target_service_to_CE_map_wlan[] = { + { + WMI_DATA_VO_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 3, + }, + { + WMI_DATA_VO_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 2, + }, + { + WMI_DATA_BK_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 3, + }, + { + WMI_DATA_BK_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 2, + }, + { + WMI_DATA_BE_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 3, + }, + { + WMI_DATA_BE_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 2, + }, + { + WMI_DATA_VI_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 3, + }, + { + WMI_DATA_VI_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 2, + }, + { + WMI_CONTROL_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 3, + }, + { + WMI_CONTROL_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 2, + }, + { + HTC_CTRL_RSVD_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 0, /* could be moved to 3 (share with WMI) */ + }, + { + HTC_CTRL_RSVD_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 1, + }, + { + HTC_RAW_STREAMS_SVC, /* not currently used */ + PIPEDIR_OUT, /* out = UL = host -> target */ + 0, + }, + { + HTC_RAW_STREAMS_SVC, /* not currently used */ + PIPEDIR_IN, /* in = DL = target -> host */ + 1, + }, + { + HTT_DATA_MSG_SVC, + PIPEDIR_OUT, /* out = UL = host -> target */ + 4, + }, + { + HTT_DATA_MSG_SVC, + PIPEDIR_IN, /* in = DL = target -> host */ + 1, + }, +#ifdef IPA_UC_OFFLOAD + { + WDI_IPA_TX_SVC, + PIPEDIR_OUT, /* in = DL = target -> host */ + 5, + }, +#endif /* IPA_UC_OFFLOAD */ + /* (Additions here) */ + + { /* Must be last */ + 0, + 0, + 0, + }, +}; + +static struct service_to_pipe *target_service_to_CE_map = target_service_to_CE_map_wlan; +static int target_service_to_CE_map_sz = sizeof(target_service_to_CE_map_wlan); + +static struct service_to_pipe target_service_to_CE_map_wlan_epping[] = { + { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */ + { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */ + { WMI_DATA_BK_SVC, PIPEDIR_OUT, 4, }, /* out = UL = host -> target */ + { WMI_DATA_BK_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */ + { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */ + { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */ + { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */ + { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */ + { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */ + { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */ + { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, /* out = UL = host -> target */ + { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */ + { HTC_RAW_STREAMS_SVC, PIPEDIR_OUT, 0, }, /* out = UL = host -> target */ + { HTC_RAW_STREAMS_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */ + { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, /* out = UL = host -> target */ + { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */ + { 0, 0, 0, }, /* Must be last */ +}; + +/* + * Send an interrupt to the device to wake up the Target CPU + * so it has an opportunity to notice any changed state. + */ +void +HIF_wake_target_cpu(struct hif_pci_softc *sc) +{ + A_STATUS rv; + A_UINT32 core_ctrl; + + rv = HIFDiagReadAccess(sc->hif_device, SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS, &core_ctrl); + ASSERT(rv == A_OK); + + core_ctrl |= CORE_CTRL_CPU_INTR_MASK; /* A_INUM_FIRMWARE interrupt to Target CPU */ + + rv = HIFDiagWriteAccess(sc->hif_device, SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS, core_ctrl); + ASSERT(rv == A_OK); +} + +#define HIF_MIN_SLEEP_INACTIVITY_TIME_MS 50 +#define HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS 60 +static void +HIF_sleep_entry(void *arg) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)arg; + A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(hif_state->targid); + struct hif_pci_softc *sc = hif_state->sc; + u_int32_t idle_ms; + + if (sc->recovery) + return; + + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); + if (hif_state->verified_awake == FALSE) { + idle_ms = adf_os_ticks_to_msecs(adf_os_ticks() + - hif_state->sleep_ticks); + if (idle_ms >= HIF_MIN_SLEEP_INACTIVITY_TIME_MS) { + if (!adf_os_atomic_read(&sc->pci_link_suspended)) { + A_PCI_WRITE32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + hif_state->fake_sleep = FALSE; + } + } else { + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_start(&hif_state->sleep_timer, + HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); + } + } else { + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_start(&hif_state->sleep_timer, + HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); + } + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); +} + +void +HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(hif_state->targid); + struct hif_pci_softc *sc = hif_state->sc; + + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); + /* + * If the deferred sleep timer is running cancel it + * and put the soc into sleep. + */ + if (hif_state->fake_sleep == TRUE) { + adf_os_timer_cancel(&hif_state->sleep_timer); + if (hif_state->verified_awake == FALSE) { + A_PCI_WRITE32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + } + hif_state->fake_sleep = FALSE; + } + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); +} + +/* + * Called from PCI layer whenever a new PCI device is probed. + * Initializes per-device HIF state and notifies the main + * driver that a new HIF device is present. + */ +int +HIF_PCIDeviceProbed(hif_handle_t hif_hdl) +{ + struct HIF_CE_state *hif_state; + struct HIF_CE_pipe_info *pipe_info; + int pipe_num; + A_STATUS rv; + struct hif_pci_softc *sc = hif_hdl; + struct ol_softc *scn = sc->ol_sc; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); + + /* if epping is enabled we need to use the epping configuration. */ + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + if (WLAN_IS_EPPING_IRQ(vos_get_conparam())) + host_CE_config = host_CE_config_wlan_epping_irq; + else + host_CE_config = host_CE_config_wlan_epping_poll; + target_CE_config = target_CE_config_wlan_epping; + target_CE_config_sz = sizeof(target_CE_config_wlan_epping); + target_service_to_CE_map = target_service_to_CE_map_wlan_epping; + target_service_to_CE_map_sz = sizeof(target_service_to_CE_map_wlan_epping); + } + + hif_state = (struct HIF_CE_state *)A_MALLOC(sizeof(*hif_state)); + if (!hif_state) { + return -ENOMEM; + } + + A_MEMZERO(hif_state, sizeof(*hif_state)); + + sc->hif_device = (HIF_DEVICE *)hif_state; + hif_state->sc = sc; + + adf_os_spinlock_init(&hif_state->keep_awake_lock); + + adf_os_spinlock_init(&hif_state->suspend_lock); + + adf_os_atomic_init(&hif_state->hif_thread_idle); + adf_os_atomic_inc(&hif_state->hif_thread_idle); + + hif_state->keep_awake_count = 0; + + hif_state->fake_sleep = FALSE; + hif_state->sleep_ticks = 0; + adf_os_timer_init(NULL, &hif_state->sleep_timer, + HIF_sleep_entry, (void *)hif_state, + ADF_NON_DEFERRABLE_TIMER); + + hif_state->fw_indicator_address = FW_INDICATOR_ADDRESS; + hif_state->targid = A_TARGET_ID(sc->hif_device); +#if CONFIG_ATH_PCIE_MAX_PERF || CONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD + /* Force AWAKE forever/till the driver is loaded */ + if (HIFTargetSleepStateAdjust(hif_state->targid, FALSE, TRUE) < 0) + return -EACCES; +#endif + + A_TARGET_ACCESS_LIKELY(hif_state->targid); /* During CE initializtion */ + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + struct CE_attr *attr; + + pipe_info = &hif_state->pipe_info[pipe_num]; + pipe_info->pipe_num = pipe_num; + pipe_info->HIF_CE_state = hif_state; + attr = &host_CE_config[pipe_num]; + pipe_info->ce_hdl = CE_init(sc, pipe_num, attr); + ASSERT(pipe_info->ce_hdl != NULL); + + if (pipe_num == sc->ce_count-1) { + /* Reserve the ultimate CE for Diagnostic Window support */ + hif_state->ce_diag = hif_state->pipe_info[sc->ce_count-1].ce_hdl; + continue; + } + + pipe_info->buf_sz = (adf_os_size_t)(attr->src_sz_max); + adf_os_spinlock_init(&pipe_info->recv_bufs_needed_lock); + if (attr->dest_nentries > 0) { + atomic_set(&pipe_info->recv_bufs_needed, initBufferCount(attr->dest_nentries-1)); + } else { + atomic_set(&pipe_info->recv_bufs_needed, 0); + } + } + +#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) + if (athdiag_procfs_init(sc) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("athdiag_procfs_init failed\n")); + return A_ERROR; + } +#endif + + /* + * Initially, establish CE completion handlers for use with BMI. + * These are overwritten with generic handlers after we exit BMI phase. + */ + pipe_info = &hif_state->pipe_info[BMI_CE_NUM_TO_TARG]; + CE_send_cb_register(pipe_info->ce_hdl, HIF_BMI_send_done, pipe_info, 0); +#ifndef BMI_RSP_POLLING + pipe_info = &hif_state->pipe_info[BMI_CE_NUM_TO_HOST]; + CE_recv_cb_register(pipe_info->ce_hdl, HIF_BMI_recv_data, pipe_info, 0); +#endif + + { /* Download to Target the CE Configuration and the service-to-CE map */ + A_UINT32 interconnect_targ_addr = host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_interconnect_state)); + A_UINT32 pcie_state_targ_addr = 0; + A_UINT32 pipe_cfg_targ_addr = 0; + A_UINT32 svc_to_pipe_map = 0; + A_UINT32 pcie_config_flags = 0; + + /* Supply Target-side CE configuration */ + rv = HIFDiagReadAccess(sc->hif_device, interconnect_targ_addr, &pcie_state_targ_addr); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get pcie state addr (%d)\n", rv)); + goto done; + } + if (pcie_state_targ_addr == 0) { + rv = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed pcie state addr is 0\n")); + goto done; + } + + rv = HIFDiagReadAccess(sc->hif_device, + pcie_state_targ_addr+offsetof(struct pcie_state_s, pipe_cfg_addr), + &pipe_cfg_targ_addr); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get pipe cfg addr (%d)\n", rv)); + goto done; + } + if (pipe_cfg_targ_addr == 0) { + rv = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed pipe cfg addr is 0\n")); + goto done; + } + + rv = HIFDiagWriteMem(sc->hif_device, pipe_cfg_targ_addr, (A_UINT8 *)target_CE_config, target_CE_config_sz); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed write pipe cfg (%d)\n", rv)); + goto done; + } + + rv = HIFDiagReadAccess(sc->hif_device, + pcie_state_targ_addr+offsetof(struct pcie_state_s, svc_to_pipe_map), + &svc_to_pipe_map); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get svc/pipe map (%d)\n", rv)); + goto done; + } + if (svc_to_pipe_map == 0) { + rv = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed svc_to_pipe map is 0\n")); + goto done; + } + + rv = HIFDiagWriteMem(sc->hif_device, + svc_to_pipe_map, + (A_UINT8 *)target_service_to_CE_map, + target_service_to_CE_map_sz); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed write svc/pipe map (%d)\n", rv)); + goto done; + } + + rv = HIFDiagReadAccess(sc->hif_device, + pcie_state_targ_addr+offsetof(struct pcie_state_s, config_flags), + &pcie_config_flags); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get pcie config_flags (%d)\n", rv)); + goto done; + } + +#if (CONFIG_PCIE_ENABLE_L1_CLOCK_GATE) + pcie_config_flags |= PCIE_CONFIG_FLAG_ENABLE_L1; +#else + pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; +#endif /* CONFIG_PCIE_ENABLE_L1_CLOCK_GATE */ + pcie_config_flags |= PCIE_CONFIG_FLAG_CLK_SWITCH_WAIT; +#if (CONFIG_PCIE_ENABLE_AXI_CLK_GATE) + pcie_config_flags |= PCIE_CONFIG_FLAG_AXI_CLK_GATE; +#endif + rv = HIFDiagWriteMem(sc->hif_device, + pcie_state_targ_addr+offsetof(struct pcie_state_s, config_flags), + (A_UINT8 *)&pcie_config_flags, + sizeof(pcie_config_flags)); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed write pcie config_flags (%d)\n", rv)); + goto done; + } + } + + { /* configure early allocation */ + A_UINT32 ealloc_value; + A_UINT32 ealloc_targ_addr = host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_early_alloc)); + + rv = HIFDiagReadAccess(sc->hif_device, ealloc_targ_addr, &ealloc_value); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get early alloc val (%d)\n", rv)); + goto done; + } + + /* 1 bank is switched to IRAM, except ROME 1.0 */ + ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) & HI_EARLY_ALLOC_MAGIC_MASK); + { + A_UINT8 banks_switched = 1; + A_UINT32 chip_id; + rv = HIFDiagReadAccess(sc->hif_device, CHIP_ID_ADDRESS | RTC_SOC_BASE_ADDRESS, &chip_id); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get chip id val (%d)\n", rv)); + goto done; + } + if (CHIP_ID_VERSION_GET(chip_id) == 0xD) { + scn->target_revision = CHIP_ID_REVISION_GET(chip_id); + switch(CHIP_ID_REVISION_GET(chip_id)) { + case 0x2: /* ROME 1.3 */ + /* 2 banks are switched to IRAM */ + banks_switched = 2; + break; + case 0x4: /* ROME 2.1 */ + case 0x5: /* ROME 2.2 */ + banks_switched = 6; + break; + case 0x8: /* ROME 3.0 */ + case 0x9: /* ROME 3.1 */ + case 0xA: /* ROME 3.2 */ + banks_switched = 9; + break; + case 0x0: /* ROME 1.0 */ + case 0x1: /* ROME 1.1 */ + default: + /* 3 banks are switched to IRAM */ + banks_switched = 3; + break; + } + + } + ealloc_value |= ((banks_switched << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & HI_EARLY_ALLOC_IRAM_BANKS_MASK); + } + rv = HIFDiagWriteAccess(sc->hif_device, ealloc_targ_addr, ealloc_value); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed set early alloc val (%d)\n", rv)); + goto done; + } + } + + { /* Tell Target to proceed with initialization */ + A_UINT32 flag2_value; + A_UINT32 flag2_targ_addr = host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_option_flag2)); + + rv = HIFDiagReadAccess(sc->hif_device, flag2_targ_addr, &flag2_value); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get option val (%d)\n", rv)); + goto done; + } + + flag2_value |= HI_OPTION_EARLY_CFG_DONE; + rv = HIFDiagWriteAccess(sc->hif_device, flag2_targ_addr, flag2_value); + if (rv != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed set option val (%d)\n", rv)); + goto done; + } + + HIF_wake_target_cpu(sc); + } + +done: + A_TARGET_ACCESS_UNLIKELY(hif_state->targid); + + if (rv == A_OK) { + } else { + /* Failure, so clean up */ + for (pipe_num=0; pipe_num < sc->ce_count; pipe_num++) { + pipe_info = &hif_state->pipe_info[pipe_num]; + if (pipe_info->ce_hdl) { + CE_fini(pipe_info->ce_hdl); + pipe_info->ce_hdl = NULL; + pipe_info->buf_sz = 0; + } + } + + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_free(&hif_state->sleep_timer); + + A_FREE(hif_state); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__)); + + return (rv != A_OK); +} + +/* + * The "ID" returned here is an opaque cookie used for + * A_TARGET_READ and A_TARGET_WRITE -- low-overhead APIs + * appropriate for PCIe. + */ +A_target_id_t +HIFGetTargetId(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + + return(TARGID(sc)); +} + +extern void HIFdebug(void); + +/* + * For now, we use simple on-demand sleep/wake. + * Some possible improvements: + * -Use the Host-destined A_INUM_PCIE_AWAKE interrupt rather than spin/delay + * (or perhaps spin/delay for a short while, then convert to sleep/interrupt) + * Careful, though, these functions may be used by interrupt handlers ("atomic") + * -Don't use host_reg_table for this code; instead use values directly + * -Use a separate timer to track activity and allow Target to sleep only + * if it hasn't done anything for a while; may even want to delay some + * processing for a short while in order to "batch" (e.g.) transmit + * requests with completion processing into "windows of up time". Costs + * some performance, but improves power utilization. + * -On some platforms, it might be possible to eliminate explicit + * sleep/wakeup. Instead, take a chance that each access works OK. If not, + * recover from the failure by forcing the Target awake. + * -Change keep_awake_count to an atomic_t in order to avoid spin lock + * overhead in some cases. Perhaps this makes more sense when + * CONFIG_ATH_PCIE_ACCESS_LIKELY is used and less sense when LIKELY is + * disabled. + * -It is possible to compile this code out and simply force the Target + * to remain awake. That would yield optimal performance at the cost of + * increased power. See CONFIG_ATH_PCIE_MAX_PERF. + * + * Note: parameter wait_for_it has meaning only when waking (when sleep_ok==0). + */ +int +HIFTargetSleepStateAdjust(A_target_id_t targid, + A_BOOL sleep_ok, + A_BOOL wait_for_it) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)TARGID_TO_HIF(targid); + A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(targid); + static int max_delay; + struct hif_pci_softc *sc = hif_state->sc; + + + if (sc->recovery) + return -EACCES; + + if (sleep_ok) { + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); + hif_state->keep_awake_count--; + if (hif_state->keep_awake_count == 0) { + /* Allow sleep */ + hif_state->verified_awake = FALSE; + hif_state->sleep_ticks = adf_os_ticks(); + } + if (hif_state->fake_sleep == FALSE) { + /* Set the Fake Sleep */ + hif_state->fake_sleep = TRUE; + + /* Start the Sleep Timer */ + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_start(&hif_state->sleep_timer, + HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); + } + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); + } else { + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); + + if (hif_state->fake_sleep) { + hif_state->verified_awake = TRUE; + } else { + if (hif_state->keep_awake_count == 0) { + /* Force AWAKE */ + A_PCI_WRITE32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + } + } + hif_state->keep_awake_count++; + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); + + if (wait_for_it && !hif_state->verified_awake) { +#define PCIE_WAKE_TIMEOUT 8000 /* 8Ms */ + int tot_delay = 0; + int curr_delay = 5; + + for (;;) { + if (hif_pci_targ_is_awake(sc, pci_addr)) { + hif_state->verified_awake = TRUE; + break; + } else if (!hif_pci_targ_is_present(targid, pci_addr)) { + break; + } + + //ASSERT(tot_delay <= PCIE_WAKE_TIMEOUT); + if (tot_delay > PCIE_WAKE_TIMEOUT) + { + u_int16_t val; + u_int32_t bar; + + printk("%s: keep_awake_count = %d\n", __func__, + hif_state->keep_awake_count); + + pci_read_config_word(sc->pdev, PCI_VENDOR_ID, &val); + printk("%s: PCI Vendor ID = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &val); + printk("%s: PCI Device ID = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_COMMAND, &val); + printk("%s: PCI Command = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_STATUS, &val); + printk("%s: PCI Status = 0x%04x\n", __func__, val); + + pci_read_config_dword(sc->pdev, PCI_BASE_ADDRESS_0, &bar); + printk("%s: PCI BAR 0 = 0x%08x\n", __func__, bar); + + printk("%s: PCIE_SOC_WAKE_ADDRESS = 0x%08x," \ + " RTC_STATE_ADDRESS = 0x%08x\n", __func__, + A_PCI_READ32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS), + A_PCI_READ32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS)); + + printk("%s:error, can't wakeup target\n", __func__); + sc->recovery = true; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); +#ifdef CONFIG_CNSS + cnss_wlan_pci_link_down(); +#endif + return -EACCES; + } + + OS_DELAY(curr_delay); + tot_delay += curr_delay; + + if (curr_delay < 50) { + curr_delay += 5; + } + } + + /* + * NB: If Target has to come out of Deep Sleep, + * this may take a few Msecs. Typically, though + * this delay should be <30us. + */ + if (tot_delay > max_delay) { + max_delay = tot_delay; + } + } + } + return EOK; +} + +void +HIFSetTargetSleep(HIF_DEVICE *hif_device, A_BOOL sleep_ok, A_BOOL wait_for_it) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + HIFTargetSleepStateAdjust(hif_state->targid, sleep_ok, wait_for_it); +} + +A_BOOL +HIFTargetForcedAwake(A_target_id_t targid) +{ + A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(targid); + A_BOOL awake; + A_BOOL pcie_forced_awake; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)TARGID_TO_HIF(targid); + struct hif_pci_softc *sc = hif_state->sc; + + awake = hif_pci_targ_is_awake(sc, pci_addr); + + pcie_forced_awake = + !!(A_PCI_READ32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS) & PCIE_SOC_WAKE_V_MASK); + + return (awake && pcie_forced_awake); +} + +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +A_UINT32 +HIFTargetReadChecked(A_target_id_t targid, A_UINT32 offset) +{ + A_UINT32 value; + void *addr; + + if (!A_TARGET_ACCESS_OK(targid)) { + HIFdebug(); + } + + addr = TARGID_TO_PCI_ADDR(targid)+offset; + value = A_PCI_READ32(addr); + + { + unsigned long irq_flags; + int idx = pcie_access_log_seqnum % PCIE_ACCESS_LOG_NUM; + + spin_lock_irqsave(&pcie_access_log_lock, irq_flags); + pcie_access_log[idx].seqnum = pcie_access_log_seqnum; + pcie_access_log[idx].is_write = FALSE; + pcie_access_log[idx].addr = addr; + pcie_access_log[idx].value = value; + pcie_access_log_seqnum++; + spin_unlock_irqrestore(&pcie_access_log_lock, irq_flags); + } + + return value; +} + +void +HIFTargetWriteChecked(A_target_id_t targid, A_UINT32 offset, A_UINT32 value) +{ + void *addr; + + if (!A_TARGET_ACCESS_OK(targid)) { + HIFdebug(); + } + + addr = TARGID_TO_PCI_ADDR(targid)+(offset); + A_PCI_WRITE32(addr, value); + + { + unsigned long irq_flags; + int idx = pcie_access_log_seqnum % PCIE_ACCESS_LOG_NUM; + + spin_lock_irqsave(&pcie_access_log_lock, irq_flags); + pcie_access_log[idx].seqnum = pcie_access_log_seqnum; + pcie_access_log[idx].is_write = TRUE; + pcie_access_log[idx].addr = addr; + pcie_access_log[idx].value = value; + pcie_access_log_seqnum++; + spin_unlock_irqrestore(&pcie_access_log_lock, irq_flags); + } +} + +void +HIFdebug(void) +{ + /* BUG_ON(1); */ +// BREAK(); +} + +void +HIFTargetDumpAccessLog(void) +{ + int idx, len, start_idx, cur_idx; + unsigned long irq_flags; + + spin_lock_irqsave(&pcie_access_log_lock, irq_flags); + if (pcie_access_log_seqnum > PCIE_ACCESS_LOG_NUM) + { + len = PCIE_ACCESS_LOG_NUM; + start_idx = pcie_access_log_seqnum % PCIE_ACCESS_LOG_NUM; + } + else + { + len = pcie_access_log_seqnum; + start_idx = 0; + } + + for(idx = 0; idx < len; idx++) + { + cur_idx = (start_idx + idx) % PCIE_ACCESS_LOG_NUM; + printk("idx:%d\t sn:%u wr:%d addr:%p val:%u.\n", + idx, + pcie_access_log[cur_idx].seqnum, + pcie_access_log[cur_idx].is_write, + pcie_access_log[cur_idx].addr, + pcie_access_log[cur_idx].value); + } + + pcie_access_log_seqnum = 0; + spin_unlock_irqrestore(&pcie_access_log_lock, irq_flags); +} +#endif + +/* + * Convert an opaque HIF device handle into the corresponding + * opaque (void *) operating system device handle. + */ +#if ! defined(A_SIMOS_DEVHOST) +void * +HIFDeviceToOsDevice(HIF_DEVICE *hif_device) +{ + return ((struct HIF_CE_state *) hif_device)->sc->dev; +} +#endif + +/* + * Typically called from either the PCI infrastructure when + * a firmware interrupt is pending OR from the the shared PCI + * interrupt handler when a firmware-generated interrupt + * to the Host might be pending. + */ +irqreturn_t +HIF_fw_interrupt_handler(int irq, void *arg) +{ + struct hif_pci_softc *sc = arg; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; + A_UINT32 fw_indicator_address, fw_indicator; + + A_TARGET_ACCESS_BEGIN_RET(targid); + + fw_indicator_address = hif_state->fw_indicator_address; + /* For sudden unplug this will return ~0 */ + fw_indicator = A_TARGET_READ(targid, fw_indicator_address); + + if ((fw_indicator != ~0) && (fw_indicator & FW_IND_EVENT_PENDING)) { + /* ACK: clear Target-side pending event */ + A_TARGET_WRITE(targid, fw_indicator_address, fw_indicator & ~FW_IND_EVENT_PENDING); + A_TARGET_ACCESS_END_RET(targid); + + if (hif_state->started) { + /* Alert the Host-side service thread */ + atomic_set(&hif_state->fw_event_pending, 1); + hif_completion_thread(hif_state); + } else { + /* + * Probable Target failure before we're prepared + * to handle it. Generally unexpected. + */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ath ERROR: Early firmware event indicated\n")); + } + } else { + A_TARGET_ACCESS_END_RET(targid); + } + + return ATH_ISR_SCHED; +} + +void *hif_get_targetdef(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + + return sc->targetdef; +} + +void HIFsuspendwow(HIF_DEVICE *hif_device) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct hif_pci_softc *sc = hif_state->sc; + adf_os_atomic_set(&sc->wow_done, 1); +} + +#ifdef IPA_UC_OFFLOAD +void HIFIpaGetCEResource(HIF_DEVICE *hif_device, + A_UINT32 *ce_sr_base_paddr, + A_UINT32 *ce_sr_ring_size, + A_UINT32 *ce_reg_paddr) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device; + struct HIF_CE_pipe_info *pipe_info = + &(hif_state->pipe_info[HIF_PCI_IPA_UC_ASSIGNED_CE]); + struct CE_handle *ce_hdl = pipe_info->ce_hdl; + + CE_ipaGetResource(ce_hdl, ce_sr_base_paddr, ce_sr_ring_size, ce_reg_paddr); + return; +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.h new file mode 100644 index 0000000000000..7db34945813da --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * NB: Inappropriate references to "HTC" are used in this (and other) + * HIF implementations. HTC is typically the calling layer, but it + * theoretically could be some alternative. + */ + +/* + * This holds all state needed to process a pending send/recv interrupt. + * The information is saved here as soon as the interrupt occurs (thus + * allowing the underlying CE to re-use the ring descriptor). The + * information here is eventually processed by a completion processing + * thread. + */ + +#include /* adf_os_atomic_read */ +#include "vos_lock.h" +struct HIF_CE_completion_state { + struct HIF_CE_completion_state *next; + int send_or_recv; + struct CE_handle *copyeng; + void *ce_context; + void *transfer_context; + CE_addr_t data; + unsigned int nbytes; + unsigned int transfer_id; + unsigned int flags; +}; + +/* compl_state.send_or_recv */ +#define HIF_CE_COMPLETE_FREE 0 +#define HIF_CE_COMPLETE_SEND 1 +#define HIF_CE_COMPLETE_RECV 2 + +enum ol_ath_hif_pkt_ecodes { + HIF_PIPE_NO_RESOURCE=0 +}; + +struct HIF_CE_state ; + +#define HIF_CE_COMPLETE_STATE_NUM 18 /* 56 * 18 + 4/8 = 1012/1016 bytes */ +struct HIF_CE_completion_state_list { + struct HIF_CE_completion_state_list *next; +}; +/* Per-pipe state. */ +struct HIF_CE_pipe_info { + /* Handle of underlying Copy Engine */ + struct CE_handle *ce_hdl; + + /* Our pipe number; facilitiates use of pipe_info ptrs. */ + A_UINT8 pipe_num; + + /* Convenience back pointer to HIF_CE_state. */ + struct HIF_CE_state *HIF_CE_state; + + /* Instantaneous number of receive buffers that should be posted */ + atomic_t recv_bufs_needed; + adf_os_size_t buf_sz; + adf_os_spinlock_t recv_bufs_needed_lock; + + adf_os_spinlock_t completion_freeq_lock; + /* Limit the number of outstanding send requests. */ + int num_sends_allowed; + struct HIF_CE_completion_state_list *completion_space_list; + struct HIF_CE_completion_state *completion_freeq_head; + struct HIF_CE_completion_state *completion_freeq_tail; + /* adding three counts for debugging ring buffer errors */ + uint32_t nbuf_alloc_err_count; + uint32_t nbuf_dma_err_count; + uint32_t nbuf_ce_enqueue_err_count; +} ; + +struct HIF_CE_state { + struct hif_pci_softc *sc; + A_BOOL started; + + adf_os_spinlock_t keep_awake_lock; + adf_os_spinlock_t suspend_lock; + unsigned int keep_awake_count; + A_BOOL verified_awake; + A_BOOL fake_sleep; + adf_os_timer_t sleep_timer; + unsigned long sleep_ticks; + + //struct task_struct *pci_dev_inserted_thread; + //struct completion pci_dev_inserted_thread_done; + + //wait_queue_head_t replenish_recv_buf_waitq; + //atomic_t replenish_recv_buf_flag; + //struct task_struct *replenish_thread; + //struct completion post_recv_bufs_thread_done; + + adf_os_spinlock_t completion_pendingq_lock; + /* Queue of send/recv completions that need to be processed */ + struct HIF_CE_completion_state *completion_pendingq_head; + struct HIF_CE_completion_state *completion_pendingq_tail; + atomic_t fw_event_pending; + adf_os_atomic_t hif_thread_idle; + + //wait_queue_head_t service_waitq; + //struct task_struct *compl_thread; + //struct completion compl_thread_done; + + /* Per-pipe state. */ + struct HIF_CE_pipe_info pipe_info[CE_COUNT_MAX]; + + MSG_BASED_HIF_CALLBACKS msg_callbacks_pending; /* to be activated after BMI_DONE */ + MSG_BASED_HIF_CALLBACKS msg_callbacks_current; /* current msg callbacks in use */ + + void *claimedContext; + + /* Target address used to signal a pending firmware event */ + u_int32_t fw_indicator_address; + + /* Copy Engine used for Diagnostic Accesses */ + struct CE_handle *ce_diag; + + /* For use with A_TARGET_ API */ + A_target_id_t targid; +}; + +void priv_start_agc(struct hif_pci_softc *sc); +void priv_dump_agc(struct hif_pci_softc *sc); +void priv_start_cap_chaninfo(struct hif_pci_softc *sc); +void priv_dump_chaninfo(struct hif_pci_softc *sc); +void priv_dump_bbwatchdog(struct hif_pci_softc *sc); +void hif_dump_pipe_debug_count(HIF_DEVICE *hif_device); + +#define CE_HTT_T2H_MSG 1 +#define CE_HTT_H2T_MSG 4 diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c new file mode 100644 index 0000000000000..d29462f7ccb61 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -0,0 +1,2260 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include +#include +#include +#include +#include +#include "if_pci.h" +#include "hif_msg_based.h" +#include "hif_pci.h" +#include "copy_engine_api.h" +#include "copy_engine_internal.h" +#include "bmi_msg.h" /* TARGET_TYPE_ */ +#include "regtable.h" +#include "ol_fw.h" +#include +#include "vos_api.h" +#include "vos_sched.h" +#include "wma_api.h" +#include "adf_os_atomic.h" +#include "wlan_hdd_power.h" +#include "wlan_hdd_main.h" +#ifdef CONFIG_CNSS +#include +#endif +#include "epping_main.h" + +#ifdef WLAN_BTAMP_FEATURE +#include "wlan_btc_svc.h" +#include "wlan_nlink_common.h" +#endif + +#ifndef REMOVE_PKT_LOG +#include "ol_txrx_types.h" +#include "pktlog_ac_api.h" +#include "pktlog_ac.h" +#endif + +#define AR9888_DEVICE_ID (0x003c) +#define AR6320_DEVICE_ID (0x003e) +#define AR6320_FW_1_1 (0x11) +#define AR6320_FW_1_3 (0x13) +#define AR6320_FW_2_0 (0x20) +#define AR6320_FW_3_0 (0x30) +#define AR6320_FW_3_2 (0x32) + +#ifdef CONFIG_SLUB_DEBUG_ON +#define MAX_NUM_OF_RECEIVES 400 /* Maximum number of Rx buf to process before* + break out in SLUB debug builds */ +#else +#define MAX_NUM_OF_RECEIVES 1000 /* Maximum number of Rx buf to process before break out */ +#endif + +#define PCIE_WAKE_TIMEOUT 1000 /* Maximum ms timeout for host to wake up target */ +#define RAMDUMP_EVENT_TIMEOUT 2500 + +unsigned int msienable = 0; +module_param(msienable, int, 0644); + +int hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl); +void hif_nointrs(struct hif_pci_softc *sc); + +static struct pci_device_id hif_pci_id_table[] = { + { 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID }, + { 0 } +}; + +#ifndef REMOVE_PKT_LOG +struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs = NULL; +#endif + +/* Setting SOC_GLOBAL_RESET during driver unload causes intermittent PCIe data bus error + * As workaround for this issue - changing the reset sequence to use TargetCPU warm reset + * instead of SOC_GLOBAL_RESET + */ +#define CPU_WARM_RESET_WAR + +/* + * Top-level interrupt handler for all PCI interrupts from a Target. + * When a block of MSI interrupts is allocated, this top-level handler + * is not used; instead, we directly call the correct sub-handler. + */ +static irqreturn_t +hif_pci_interrupt_handler(int irq, void *arg) +{ + struct hif_pci_softc *sc = (struct hif_pci_softc *) arg; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + volatile int tmp; + A_UINT16 val; + A_UINT32 bar0; + + if (sc->hif_init_done == TRUE) { + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + } + + if (LEGACY_INTERRUPTS(sc)) { + + if (sc->hif_init_done == TRUE) { + if (Q_TARGET_ACCESS_BEGIN(hif_state->targid) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + return IRQ_HANDLED; + } + } + + /* Clear Legacy PCI line interrupts */ + /* IMPORTANT: INTR_CLR regiser has to be set after INTR_ENABLE is set to 0, */ + /* otherwise interrupt can not be really cleared */ + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), 0); + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_CLR_ADDRESS), PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ + tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + + if (tmp == 0xdeadbeef) { + printk(KERN_ERR "BUG(%s): SoC returns 0xdeadbeef!!\n", __func__); + + pci_read_config_word(sc->pdev, PCI_VENDOR_ID, &val); + printk(KERN_ERR "%s: PCI Vendor ID = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &val); + printk(KERN_ERR "%s: PCI Device ID = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_COMMAND, &val); + printk(KERN_ERR "%s: PCI Command = 0x%04x\n", __func__, val); + + pci_read_config_word(sc->pdev, PCI_STATUS, &val); + printk(KERN_ERR "%s: PCI Status = 0x%04x\n", __func__, val); + + pci_read_config_dword(sc->pdev, PCI_BASE_ADDRESS_0, &bar0); + printk(KERN_ERR "%s: PCI BAR0 = 0x%08x\n", __func__, bar0); + + printk(KERN_ERR "%s: RTC_STATE_ADDRESS = 0x%08x, " + "PCIE_SOC_WAKE_ADDRESS = 0x%08x\n", __func__, + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS), + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS)); + + pr_err("%s: 0x80008 = 0x%08x, 0x8000c = 0x%08x, " + "0x80010 = 0x%08x,\n0x80014 = 0x%08x, 0x80018 = 0x%08x, " + "0x8001c = 0x%08x\n", __func__, + A_PCI_READ32(sc->mem + 0x80008), + A_PCI_READ32(sc->mem + 0x8000c), + A_PCI_READ32(sc->mem + 0x80010), + A_PCI_READ32(sc->mem + 0x80014), + A_PCI_READ32(sc->mem + 0x80018), + A_PCI_READ32(sc->mem + 0x8001c)); + + VOS_BUG(0); + } + + if (sc->hif_init_done == TRUE) { + if (Q_TARGET_ACCESS_END(hif_state->targid) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + return IRQ_HANDLED; + } + } + } + /* TBDXXX: Add support for WMAC */ + + sc->irq_event = irq; + adf_os_atomic_set(&sc->tasklet_from_intr, 1); + tasklet_schedule(&sc->intr_tq); + + if (sc->hif_init_done == TRUE) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + } + return IRQ_HANDLED; +} + +static irqreturn_t +hif_pci_msi_fw_handler(int irq, void *arg) +{ + struct hif_pci_softc *sc = (struct hif_pci_softc *) arg; + + (irqreturn_t)HIF_fw_interrupt_handler(sc->irq_event, sc); + + return IRQ_HANDLED; +} + +bool +hif_pci_targ_is_awake(struct hif_pci_softc *sc, void *__iomem *mem) +{ + A_UINT32 val; + + if(sc->recovery) + return false; + + val = A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS + RTC_STATE_ADDRESS); + return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON); +} + +bool hif_pci_targ_is_present(A_target_id_t targetid, void *__iomem *mem) +{ + return 1; /* FIX THIS */ +} + +bool hif_max_num_receives_reached(unsigned int count) +{ + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + return (count > 120); + else + return (count > MAX_NUM_OF_RECEIVES); +} + +int hif_init_adf_ctx(void *ol_sc) +{ + v_CONTEXT_t pVosContext = NULL; + adf_os_device_t adf_ctx; + struct ol_softc *sc = (struct ol_softc *)ol_sc; + struct hif_pci_softc *hif_sc = sc->hif_sc; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(pVosContext == NULL) { + return -EFAULT; + } + adf_ctx = vos_mem_malloc(sizeof(*adf_ctx)); + if (!adf_ctx) { + return -ENOMEM; + } + vos_mem_zero(adf_ctx, sizeof(*adf_ctx)); + adf_ctx->drv = &hif_sc->aps_osdev; + adf_ctx->drv_hdl = hif_sc->aps_osdev.bdev; + adf_ctx->dev = hif_sc->aps_osdev.device; + sc->adf_dev = adf_ctx; + ((VosContextType*)(pVosContext))->adf_ctx = adf_ctx; + return 0; +} + +void hif_deinit_adf_ctx(void *ol_sc) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + + if (sc == NULL) + return; + if (sc->adf_dev) { + v_CONTEXT_t pVosContext = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + vos_mem_free(sc->adf_dev); + sc->adf_dev = NULL; + if (pVosContext) + ((VosContextType*)(pVosContext))->adf_ctx = NULL; + } +} + +#define A_PCIE_LOCAL_REG_READ(mem, addr) \ + A_PCI_READ32((char *)(mem) + PCIE_LOCAL_BASE_ADDRESS + (A_UINT32)(addr)) + +#define A_PCIE_LOCAL_REG_WRITE(mem, addr, val) \ + A_PCI_WRITE32(((char *)(mem) + PCIE_LOCAL_BASE_ADDRESS + (A_UINT32)(addr)), (val)) + +#define ATH_PCI_RESET_WAIT_MAX 10 /* Ms */ +static void +hif_pci_device_reset(struct hif_pci_softc *sc) +{ + void __iomem *mem = sc->mem; + int i; + u_int32_t val; + + if (!sc->hostdef) + return; + + /* NB: Don't check resetok here. This form of reset is integral to correct operation. */ + + if (!SOC_GLOBAL_RESET_ADDRESS) { + return; + } + + if (!mem) { + return; + } + + printk("Reset Device \n"); + + /* + * NB: If we try to write SOC_GLOBAL_RESET_ADDRESS without first + * writing WAKE_V, the Target may scribble over Host memory! + */ + A_PCIE_LOCAL_REG_WRITE(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + for (i=0; imem; + int i; + u_int32_t val; + u_int32_t fw_indicator; + + /* NB: Don't check resetok here. This form of reset is integral to correct operation. */ + + if (!mem) { + return; + } + + printk("Target Warm Reset\n"); + + /* + * NB: If we try to write SOC_GLOBAL_RESET_ADDRESS without first + * writing WAKE_V, the Target may scribble over Host memory! + */ + A_PCIE_LOCAL_REG_WRITE(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + for (i=0; ihif_device; + A_target_id_t targid = hif_state->targid; + void __iomem *mem = sc->mem; + u_int32_t val; + + A_TARGET_ACCESS_BEGIN_RET(targid); + val = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS); + A_TARGET_ACCESS_END_RET(targid); + + printk("%s: FW_INDICATOR register is 0x%x\n", __func__, val); + + if (val & FW_IND_HELPER) + return 0; + + return 1; +} + +int hif_pci_check_soc_status(struct hif_pci_softc *sc) +{ + u_int16_t device_id; + u_int32_t val; + u_int16_t timeout_count = 0; + + /* Check device ID from PCIe configuration space for link status */ + pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &device_id); + if(device_id != sc->devid) { + printk(KERN_ERR "PCIe link is down!\n"); + return -EACCES; + } + + /* Check PCIe local register for bar/memory access */ + val = A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS); + printk("RTC_STATE_ADDRESS is %08x\n", val); + + /* Try to wake up taget if it sleeps */ + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + printk("PCIE_SOC_WAKE_ADDRESS is %08x\n", + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS)); + + /* Check if taget can be woken up */ + while(!hif_pci_targ_is_awake(sc, sc->mem)) { + if(timeout_count >= PCIE_WAKE_TIMEOUT) { + printk(KERN_ERR "Target cannot be woken up! " + "RTC_STATE_ADDRESS is %08x, PCIE_SOC_WAKE_ADDRESS is %08x\n", + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS), A_PCI_READ32(sc->mem + + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS)); + return -EACCES; + } + + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + + A_MDELAY(100); + timeout_count += 100; + } + + /* Check Power register for SoC internal bus issues */ + val = A_PCI_READ32(sc->mem + RTC_SOC_BASE_ADDRESS + SOC_POWER_REG_OFFSET); + printk("Power register is %08x\n", val); + + return EOK; +} + +void dump_CE_debug_register(struct hif_pci_softc *sc) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; + void __iomem *mem = sc->mem; + u_int32_t val, i, j; + u_int32_t wrapper_idx[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + u_int32_t ce_base; + + A_TARGET_ACCESS_BEGIN(targid); + + /* DEBUG_INPUT_SEL_SRC = 0x6 */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET); + val &= ~WLAN_DEBUG_INPUT_SEL_SRC_MASK; + val |= WLAN_DEBUG_INPUT_SEL_SRC_SET(0x6); + A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET, val); + + /* DEBUG_CONTROL_ENABLE = 0x1 */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET); + val &= ~WLAN_DEBUG_CONTROL_ENABLE_MASK; + val |= WLAN_DEBUG_CONTROL_ENABLE_SET(0x1); + A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET, val); + + printk("Debug: inputsel: %x dbgctrl: %x\n", + A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET), + A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET)); + + printk("Debug CE: \n"); + /* Loop CE debug output */ + /* AMBA_DEBUG_BUS_SEL = 0xc */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET); + val &= ~AMBA_DEBUG_BUS_SEL_MASK; + val |= AMBA_DEBUG_BUS_SEL_SET(0xc); + A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val); + + for (i = 0; i < sizeof(wrapper_idx)/sizeof(A_UINT32); i++) { + /* For (i=1,2,3,4,8,9) write CE_WRAPPER_DEBUG_SEL = i */ + val = A_PCI_READ32(mem + CE_WRAPPER_BASE_ADDRESS + + CE_WRAPPER_DEBUG_OFFSET); + val &= ~CE_WRAPPER_DEBUG_SEL_MASK; + val |= CE_WRAPPER_DEBUG_SEL_SET(wrapper_idx[i]); + A_PCI_WRITE32(mem + CE_WRAPPER_BASE_ADDRESS + + CE_WRAPPER_DEBUG_OFFSET, val); + + printk("ce wrapper: %d amdbg: %x cewdbg: %x\n", wrapper_idx[i], + A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET), + A_PCI_READ32(mem + CE_WRAPPER_BASE_ADDRESS + + CE_WRAPPER_DEBUG_OFFSET)); + + if (wrapper_idx[i] <= 7) { + for (j = 0; j <= 5; j++) { + ce_base = CE_BASE_ADDRESS(wrapper_idx[i]); + /* For (j=0~5) write CE_DEBUG_SEL = j */ + val = A_PCI_READ32(mem + ce_base + CE_DEBUG_OFFSET); + val &= ~CE_DEBUG_SEL_MASK; + val |= CE_DEBUG_SEL_SET(j); + A_PCI_WRITE32(mem + ce_base + CE_DEBUG_OFFSET, val); + + /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + + WLAN_DEBUG_OUT_OFFSET); + val = WLAN_DEBUG_OUT_DATA_GET(val); + + printk(" module%d: cedbg: %x out: %x\n", j, + A_PCI_READ32(mem + ce_base + CE_DEBUG_OFFSET), val); + } + } else { + /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET); + val = WLAN_DEBUG_OUT_DATA_GET(val); + + printk(" out: %x\n", val); + } + } + + printk("Debug PCIe: \n"); + /* Loop PCIe debug output */ + /* Write AMBA_DEBUG_BUS_SEL = 0x1c */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET); + val &= ~AMBA_DEBUG_BUS_SEL_MASK; + val |= AMBA_DEBUG_BUS_SEL_SET(0x1c); + A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val); + + for (i = 0; i <= 8; i++) { + /* For (i=1~8) write AMBA_DEBUG_BUS_PCIE_DEBUG_SEL = i */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET); + val &= ~AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK; + val |= AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_SET(i); + A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val); + + /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */ + val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET); + val = WLAN_DEBUG_OUT_DATA_GET(val); + + printk("amdbg: %x out: %x %x\n", + A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET), val, + A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET)); + } + + A_TARGET_ACCESS_END(targid); +} + +/* + * Handler for a per-engine interrupt on a PARTICULAR CE. + * This is used in cases where each CE has a private + * MSI interrupt. + */ +static irqreturn_t +CE_per_engine_handler(int irq, void *arg) +{ + struct hif_pci_softc *sc = (struct hif_pci_softc *) arg; + int CE_id = irq - MSI_ASSIGN_CE_INITIAL; + + /* + * NOTE: We are able to derive CE_id from irq because we + * use a one-to-one mapping for CE's 0..5. + * CE's 6 & 7 do not use interrupts at all. + * + * This mapping must be kept in sync with the mapping + * used by firmware. + */ + + CE_per_engine_service(sc, CE_id); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_SLUB_DEBUG_ON + +/* worker thread to schedule wlan_tasklet in SLUB debug build */ +static void reschedule_tasklet_work_handler(struct work_struct *recovery) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct ol_softc *scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + struct hif_pci_softc *sc; + + if (NULL == scn){ + printk(KERN_ERR "%s: tasklet scn is null\n", __func__); + return; + } + + sc = scn->hif_sc; + + if (sc->hif_init_done == FALSE) { + printk(KERN_ERR "%s: wlan driver is unloaded\n", __func__); + return; + } + + tasklet_schedule(&sc->intr_tq); + return; +} + +static DECLARE_WORK(reschedule_tasklet_work, reschedule_tasklet_work_handler); + +#endif + + +static void +wlan_tasklet(unsigned long data) +{ + struct hif_pci_softc *sc = (struct hif_pci_softc *) data; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + volatile int tmp; + + if (sc->hif_init_done == FALSE) { + goto irq_handled; + } + + if (adf_os_atomic_read(&sc->wow_done)) + goto irq_handled; + + adf_os_atomic_set(&sc->ce_suspend, 0); + + (irqreturn_t)HIF_fw_interrupt_handler(sc->irq_event, sc); + if (sc->ol_sc->target_status == OL_TRGET_STATUS_RESET) + goto irq_handled; + + CE_per_engine_service_any(sc->irq_event, sc); + adf_os_atomic_set(&sc->tasklet_from_intr, 0); + if (CE_get_rx_pending(sc)) { + /* + * There are frames pending, schedule tasklet to process them. + * Enable the interrupt only when there is no pending frames in + * any of the Copy Engine pipes. + */ + adf_os_atomic_set(&sc->ce_suspend, 1); +#ifdef CONFIG_SLUB_DEBUG_ON + schedule_work(&reschedule_tasklet_work); +#else + tasklet_schedule(&sc->intr_tq); +#endif + return; + } +irq_handled: + if (LEGACY_INTERRUPTS(sc) && (sc->ol_sc->target_status != + OL_TRGET_STATUS_RESET) && + (!adf_os_atomic_read(&sc->pci_link_suspended))) { + + if (sc->hif_init_done == TRUE) + A_TARGET_ACCESS_BEGIN(hif_state->targid); + + /* Enable Legacy PCI line interrupts */ + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), + PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ + tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + + if (sc->hif_init_done == TRUE) + A_TARGET_ACCESS_END(hif_state->targid); + } + adf_os_atomic_set(&sc->ce_suspend, 1); +} + +#define ATH_PCI_PROBE_RETRY_MAX 3 + +int +hif_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + void __iomem *mem; + int ret = 0; + u_int32_t hif_type, target_type; + struct hif_pci_softc *sc; + struct ol_softc *ol_sc; + int probe_again = 0; + u_int16_t device_id; + u_int16_t revision_id; + u_int32_t lcr_val; + + printk(KERN_INFO "%s:, con_mode= 0x%x\n", __func__, vos_get_conparam()); + +again: + ret = 0; + +#define BAR_NUM 0 + /* + * Without any knowledge of the Host, the Target + * may have been reset or power cycled and its + * Config Space may no longer reflect the PCI + * address space that was assigned earlier + * by the PCI infrastructure. Refresh it now. + */ + /*WAR for EV#117307, if PCI link is down, return from probe() */ + pci_read_config_word(pdev,PCI_DEVICE_ID,&device_id); + printk("PCI device id is %04x :%04x\n",device_id,id->device); + if(device_id != id->device) { + printk(KERN_ERR "ath: PCI link is down.\n"); + /* pci link is down, so returing with error code */ + return -EIO; + } + + /* FIXME: temp. commenting out assign_resource + * call for dev_attach to work on 2.6.38 kernel + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && !defined(__LINUX_ARM_ARCH__) + if (pci_assign_resource(pdev, BAR_NUM)) { + printk(KERN_ERR "ath: cannot assign PCI space\n"); + return -EIO; + } +#endif + + if (pci_enable_device(pdev)) { + printk(KERN_ERR "ath: cannot enable PCI device\n"); + return -EIO; + } + +#define BAR_NUM 0 + /* Request MMIO resources */ + ret = pci_request_region(pdev, BAR_NUM, "ath"); + if (ret) { + dev_err(&pdev->dev, "ath: PCI MMIO reservation error\n"); + ret = -EIO; + goto err_region; + } +#ifdef CONFIG_ARM_LPAE + /* if CONFIG_ARM_LPAE is enabled, we have to set 64 bits mask + * for 32 bits device also. */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 64-bit pci DMA\n"); + goto err_dma; + } + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 64-bit consistent DMA\n"); + goto err_dma; + } +#else + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 32-bit pci DMA\n"); + goto err_dma; + } + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + printk(KERN_ERR "%s: Cannot enable 32-bit consistent DMA!\n", + __func__); + goto err_dma; + } +#endif + +#ifdef DISABLE_L1SS_STATES + pci_read_config_dword(pdev, 0x188, &lcr_val); + pci_write_config_dword(pdev, 0x188, (lcr_val & ~0x0000000f)); +#endif + + /* Set bus master bit in PCI_COMMAND to enable DMA */ + pci_set_master(pdev); + + /* Temporary FIX: disable ASPM on peregrine. Will be removed after the OTP is programmed */ + pci_read_config_dword(pdev, 0x80, &lcr_val); + pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); + + /* Arrange for access to Target SoC registers. */ + mem = pci_iomap(pdev, BAR_NUM, 0); + if (!mem) { + printk(KERN_ERR "ath: PCI iomap error\n") ; + ret = -EIO; + goto err_iomap; + } + + /* Disable asynchronous suspend */ + device_disable_async_suspend(&pdev->dev); + + sc = A_MALLOC(sizeof(*sc)); + if (!sc) { + ret = -ENOMEM; + goto err_alloc; + } + + OS_MEMZERO(sc, sizeof(*sc)); + sc->mem = mem; + sc->pdev = pdev; + sc->dev = &pdev->dev; + + sc->aps_osdev.bdev = pdev; + sc->aps_osdev.device = &pdev->dev; + sc->aps_osdev.bc.bc_handle = (void *)mem; + sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_PCI; + sc->devid = id->device; + + adf_os_spinlock_init(&sc->target_lock); + + sc->cacheline_sz = dma_get_cache_alignment(); + + pci_read_config_word(pdev, 0x08, &revision_id); + + switch (id->device) { + case AR9888_DEVICE_ID: + hif_type = HIF_TYPE_AR9888; + target_type = TARGET_TYPE_AR9888; + break; + + case AR6320_DEVICE_ID: + switch(revision_id) { + case AR6320_FW_1_1: + case AR6320_FW_1_3: + hif_type = HIF_TYPE_AR6320; + target_type = TARGET_TYPE_AR6320; + break; + + case AR6320_FW_2_0: + case AR6320_FW_3_0: + case AR6320_FW_3_2: + hif_type = HIF_TYPE_AR6320V2; + target_type = TARGET_TYPE_AR6320V2; + break; + + default: + printk(KERN_ERR "unsupported revision id %x\n", id->device); + ret = -ENODEV; + goto err_tgtstate; + } + break; + + default: + printk(KERN_ERR "unsupported device id\n"); + ret = -ENODEV; + goto err_tgtstate; + } + /* + * Attach Target register table. This is needed early on -- + * even before BMI -- since PCI and HIF initialization (and BMI init) + * directly access Target registers (e.g. CE registers). + */ + + hif_register_tbl_attach(sc, hif_type); + target_register_tbl_attach(sc, target_type); + { + A_UINT32 fw_indicator; +#if PCIE_BAR0_READY_CHECKING + int wait_limit = 200; +#endif + int targ_awake_limit = 500; + + /* + * Verify that the Target was started cleanly. + * + * The case where this is most likely is with an AUX-powered + * Target and a Host in WoW mode. If the Host crashes, + * loses power, or is restarted (without unloading the driver) + * then the Target is left (aux) powered and running. On a + * subsequent driver load, the Target is in an unexpected state. + * We try to catch that here in order to reset the Target and + * retry the probe. + */ + A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + while (!hif_pci_targ_is_awake(sc, mem)) { + if (0 == targ_awake_limit) { + printk(KERN_ERR "%s: target awake timeout\n", __func__); + ret = -EAGAIN; + goto err_tgtstate; + } + A_MDELAY(1); + targ_awake_limit--; + } + +#if PCIE_BAR0_READY_CHECKING + /* Synchronization point: wait the BAR0 is configured */ + while (wait_limit-- && + !(A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_RDY_STATUS_ADDRESS) \ + & PCIE_SOC_RDY_STATUS_BAR_MASK)) { + A_MDELAY(10); + } + if (wait_limit < 0) { + /* AR6320v1 doesn't support checking of BAR0 configuration, + takes one sec to wait BAR0 ready */ + printk(KERN_INFO "AR6320v1 waits two sec for BAR0 ready.\n"); + } +#endif + + fw_indicator = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS); + A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + + if (fw_indicator & FW_IND_INITIALIZED) { + probe_again++; + printk(KERN_ERR "ath: Target is in an unknown state. Resetting (attempt %d).\n", probe_again); + /* hif_pci_device_reset, below, will reset the target */ + ret = -EIO; + goto err_tgtstate; + } + } + + ol_sc = A_MALLOC(sizeof(*ol_sc)); + if (!ol_sc) + goto err_attach; + OS_MEMZERO(ol_sc, sizeof(*ol_sc)); + ol_sc->sc_osdev = &sc->aps_osdev; + ol_sc->hif_sc = (void *)sc; + sc->ol_sc = ol_sc; + ol_sc->target_type = target_type; + if (hif_pci_configure(sc, &ol_sc->hif_hdl)) + goto err_config; + + ol_sc->enableuartprint = 0; + ol_sc->enablefwlog = 0; +#ifdef QCA_SINGLE_BINARY_SUPPORT + ol_sc->enablesinglebinary = TRUE; +#else + ol_sc->enablesinglebinary = FALSE; +#endif + ol_sc->max_no_of_peers = 1; + +#ifdef CONFIG_CNSS + /* Get RAM dump memory address and size */ + ol_sc->ramdump_base = cnss_get_virt_ramdump_mem(&ol_sc->ramdump_size); + + if (ol_sc->ramdump_base == NULL || !ol_sc->ramdump_size) { + pr_info("%s: Failed to get RAM dump memory address or size!\n", + __func__); + } +#endif + + adf_os_atomic_init(&sc->tasklet_from_intr); + adf_os_atomic_init(&sc->wow_done); + adf_os_atomic_init(&sc->ce_suspend); + adf_os_atomic_init(&sc->pci_link_suspended); + init_waitqueue_head(&ol_sc->sc_osdev->event_queue); + + ret = hif_init_adf_ctx(ol_sc); + if (ret == 0) + ret = hdd_wlan_startup(&pdev->dev, ol_sc); + + if (ret) { + hif_disable_isr(ol_sc); + HIFShutDownDevice(ol_sc->hif_hdl); + goto err_config; + } + + /* Re-enable ASPM after firmware/OTP download is complete */ + pci_write_config_dword(pdev, 0x80, lcr_val); + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + /* + * pktlog initialization + */ + ol_pl_sethandle(&ol_sc->pdev_txrx_handle->pl_dev, ol_sc); + + if (pktlogmod_init(ol_sc)) + printk(KERN_ERR "%s: pktlogmod_init failed\n", __func__); + } +#endif + +#ifdef WLAN_BTAMP_FEATURE + /* Send WLAN UP indication to Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0); +#endif + + return 0; + +err_config: + hif_deinit_adf_ctx(ol_sc); + A_FREE(ol_sc); +err_attach: + ret = -EIO; +err_tgtstate: + pci_set_drvdata(pdev, NULL); + hif_pci_device_reset(sc); + A_FREE(sc); +err_alloc: + /* call HIF PCI free here */ + printk("%s: HIF PCI Free needs to happen here \n", __func__); + pci_iounmap(pdev, mem); +err_iomap: + pci_clear_master(pdev); +err_dma: + pci_release_region(pdev, BAR_NUM); +err_region: + pci_disable_device(pdev); + + if (probe_again && (probe_again <= ATH_PCI_PROBE_RETRY_MAX)) { + int delay_time; + + /* + * We can get here after a Host crash or power fail when + * the Target has aux power. We just did a device_reset, + * so we need to delay a short while before we try to + * reinitialize. Typically only one retry with the smallest + * delay is needed. Target should never need more than a 100Ms + * delay; that would not conform to the PCIe std. + */ + + printk(KERN_INFO "pci reprobe.\n"); + delay_time = max(100, 10 * (probe_again * probe_again)); /* 10, 40, 90, 100, 100, ... */ + A_MDELAY(delay_time); + goto again; + } + return ret; +} + +/* This function will be called when SSR frame work wants to + * power up WLAN host driver when SSR happens. Most of this + * function is duplicated from hif_pci_probe(). + */ +#if defined(CONFIG_CNSS) +int hif_pci_reinit(struct pci_dev *pdev, const struct pci_device_id *id) +{ + void __iomem *mem; + struct hif_pci_softc *sc; + struct ol_softc *ol_sc; + int probe_again = 0; + int ret = 0; + u_int16_t device_id; + u_int32_t hif_type; + u_int32_t target_type; + u_int32_t lcr_val; + u_int16_t revision_id; + +again: + ret = 0; + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + printk("Load/unload in progress, ignore SSR reinit\n"); + return 0; + } + +#define BAR_NUM 0 + /* + * Without any knowledge of the Host, the Target + * may have been reset or power cycled and its + * Config Space may no longer reflect the PCI + * address space that was assigned earlier + * by the PCI infrastructure. Refresh it now. + */ + /* If PCI link is down, return from reinit() */ + pci_read_config_word(pdev,PCI_DEVICE_ID,&device_id); + printk("PCI device id is %04x :%04x\n", device_id, id->device); + if (device_id != id->device) { + printk(KERN_ERR "%s: PCI link is down!\n", __func__); + /* PCI link is down, so return with error code. */ + return -EIO; + } + + /* FIXME: Commenting out assign_resource + * call for dev_attach to work on 2.6.38 kernel + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && !defined(__LINUX_ARM_ARCH__) + if (pci_assign_resource(pdev, BAR_NUM)) { + printk(KERN_ERR "%s: Cannot assign PCI space!\n", __func__); + return -EIO; + } +#endif + + if (pci_enable_device(pdev)) { + printk(KERN_ERR "%s: Cannot enable PCI device!\n", __func__); + return -EIO; + } + + /* Request MMIO resources */ + ret = pci_request_region(pdev, BAR_NUM, "ath"); + if (ret) { + dev_err(&pdev->dev, "%s: PCI MMIO reservation error!\n", __func__); + ret = -EIO; + goto err_region; + } + +#ifdef CONFIG_ARM_LPAE + /* if CONFIG_ARM_LPAE is enabled, we have to set 64 bits mask + * for 32 bits device also. */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 64-bit pci DMA\n"); + goto err_dma; + } + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 64-bit consistent DMA\n"); + goto err_dma; + } +#else + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + printk(KERN_ERR "ath: Cannot enable 32-bit pci DMA\n"); + goto err_dma; + } + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + printk(KERN_ERR "%s: Cannot enable 32-bit consistent DMA!\n", + __func__); + goto err_dma; + } +#endif + +#ifdef DISABLE_L1SS_STATES + pci_read_config_dword(pdev, 0x188, &lcr_val); + pci_write_config_dword(pdev, 0x188, (lcr_val & ~0x0000000f)); +#endif + + /* Set bus master bit in PCI_COMMAND to enable DMA */ + pci_set_master(pdev); + + /* Temporary FIX: disable ASPM. Will be removed after + the OTP is programmed. */ + pci_read_config_dword(pdev, 0x80, &lcr_val); + pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); + + /* Arrange for access to Target SoC registers */ + mem = pci_iomap(pdev, BAR_NUM, 0); + if (!mem) { + printk(KERN_ERR "%s: PCI iomap error!\n", __func__) ; + ret = -EIO; + goto err_iomap; + } + + /* Disable asynchronous suspend */ + device_disable_async_suspend(&pdev->dev); + + sc = A_MALLOC(sizeof(*sc)); + if (!sc) { + ret = -ENOMEM; + goto err_alloc; + } + + OS_MEMZERO(sc, sizeof(*sc)); + sc->mem = mem; + sc->pdev = pdev; + sc->dev = &pdev->dev; + sc->aps_osdev.bdev = pdev; + sc->aps_osdev.device = &pdev->dev; + sc->aps_osdev.bc.bc_handle = (void *)mem; + sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_PCI; + sc->devid = id->device; + + adf_os_spinlock_init(&sc->target_lock); + + sc->cacheline_sz = dma_get_cache_alignment(); + pci_read_config_word(pdev, 0x08, &revision_id); + + switch (id->device) { + case AR9888_DEVICE_ID: + hif_type = HIF_TYPE_AR9888; + target_type = TARGET_TYPE_AR9888; + break; + + case AR6320_DEVICE_ID: + switch(revision_id) { + case AR6320_FW_1_1: + case AR6320_FW_1_3: + hif_type = HIF_TYPE_AR6320; + target_type = TARGET_TYPE_AR6320; + break; + + case AR6320_FW_2_0: + case AR6320_FW_3_0: + case AR6320_FW_3_2: + hif_type = HIF_TYPE_AR6320V2; + target_type = TARGET_TYPE_AR6320V2; + break; + + default: + printk(KERN_ERR "unsupported revision id %x\n", id->device); + ret = -ENODEV; + goto err_tgtstate; + } + break; + + default: + printk(KERN_ERR "%s: Unsupported device ID!\n", __func__); + ret = -ENODEV; + goto err_tgtstate; + } + + /* + * Attach Target register table. This is needed early on -- + * even before BMI -- since PCI and HIF initialization (and BMI init) + * directly access Target registers (e.g. CE registers). + */ + + hif_register_tbl_attach(sc, hif_type); + target_register_tbl_attach(sc, target_type); + { + A_UINT32 fw_indicator; +#if PCIE_BAR0_READY_CHECKING + int wait_limit = 200; +#endif + + /* + * Verify that the Target was started cleanly. + * + * The case where this is most likely is with an AUX-powered + * Target and a Host in WoW mode. If the Host crashes, + * loses power, or is restarted (without unloading the driver) + * then the Target is left (aux) powered and running. On a + * subsequent driver load, the Target is in an unexpected state. + * We try to catch that here in order to reset the Target and + * retry the probe. + */ + A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_V_MASK); + while (!hif_pci_targ_is_awake(sc, mem)) { + ; + } + +#if PCIE_BAR0_READY_CHECKING + /* Synchronization point: wait the BAR0 is configured. */ + while (wait_limit-- && + !(A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_RDY_STATUS_ADDRESS) & PCIE_SOC_RDY_STATUS_BAR_MASK)) { + A_MDELAY(10); + } + if (wait_limit < 0) { + /* AR6320v1 doesn't support checking of BAR0 configuration, + takes one sec to wait BAR0 ready. */ + printk(KERN_INFO "AR6320v1 waits two sec for BAR0 ready.\n"); + } +#endif + + fw_indicator = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS); + A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_RESET); + + if (fw_indicator & FW_IND_INITIALIZED) { + probe_again++; + printk(KERN_ERR "%s: Target is in an unknown state. " + "Resetting (attempt %d).\n", __func__, probe_again); + /* hif_pci_device_reset, below will reset the target. */ + ret = -EIO; + goto err_tgtstate; + } + } + + ol_sc = A_MALLOC(sizeof(*ol_sc)); + if (!ol_sc) + goto err_attach; + + OS_MEMZERO(ol_sc, sizeof(*ol_sc)); + ol_sc->sc_osdev = &sc->aps_osdev; + ol_sc->hif_sc = (void *)sc; + sc->ol_sc = ol_sc; + ol_sc->target_type = target_type; + + if (hif_pci_configure(sc, &ol_sc->hif_hdl)) + goto err_config; + + ol_sc->enableuartprint = 0; + ol_sc->enablefwlog = 0; +#ifdef QCA_SINGLE_BINARY_SUPPORT + ol_sc->enablesinglebinary = TRUE; +#else + ol_sc->enablesinglebinary = FALSE; +#endif + ol_sc->max_no_of_peers = 1; + +#ifdef CONFIG_CNSS + /* Get RAM dump memory address and size */ + ol_sc->ramdump_base = cnss_get_virt_ramdump_mem(&ol_sc->ramdump_size); + + if (ol_sc->ramdump_base == NULL || !ol_sc->ramdump_size) { + pr_info("%s: Failed to get RAM dump memory address or size!\n", + __func__); + } +#endif + + adf_os_atomic_init(&sc->tasklet_from_intr); + adf_os_atomic_init(&sc->wow_done); + adf_os_atomic_init(&sc->ce_suspend); + adf_os_atomic_init(&sc->pci_link_suspended); + + init_waitqueue_head(&ol_sc->sc_osdev->event_queue); + + ret = hif_init_adf_ctx(ol_sc); + if (ret == 0) { + if (VOS_STATUS_SUCCESS == hdd_wlan_re_init(ol_sc)) + ret = 0; + } + + /* Re-enable ASPM after firmware/OTP download is complete */ + pci_write_config_dword(pdev, 0x80, lcr_val); + + if (ret) { + hif_disable_isr(ol_sc); + HIFShutDownDevice(ol_sc->hif_hdl); + goto err_config; + } + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + /* + * pktlog initialization + */ + ol_pl_sethandle(&ol_sc->pdev_txrx_handle->pl_dev, ol_sc); + + if (pktlogmod_init(ol_sc)) + printk(KERN_ERR "%s: pktlogmod_init failed!\n", __func__); + } +#endif + +#ifdef WLAN_BTAMP_FEATURE + /* Send WLAN UP indication to Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0); +#endif + + printk("%s: WLAN host driver reinitiation completed!\n", __func__); + return 0; + +err_config: + hif_deinit_adf_ctx(ol_sc); + A_FREE(ol_sc); +err_attach: + ret = -EIO; +err_tgtstate: + pci_set_drvdata(pdev, NULL); + hif_pci_device_reset(sc); + A_FREE(sc); +err_alloc: + /* Call HIF PCI free here */ + printk("%s: HIF PCI free needs to happen here.\n", __func__); + pci_iounmap(pdev, mem); +err_iomap: + pci_clear_master(pdev); +err_dma: + pci_release_region(pdev, BAR_NUM); +err_region: + pci_disable_device(pdev); + + if (probe_again && (probe_again <= ATH_PCI_PROBE_RETRY_MAX)) { + int delay_time; + + /* + * We can get here after a Host crash or power fail when + * the Target has aux power. We just did a device_reset, + * so we need to delay a short while before we try to + * reinitialize. Typically only one retry with the smallest + * delay is needed. Target should never need more than a 100Ms + * delay; that would not conform to the PCIe std. + */ + + printk(KERN_INFO "%s: PCI rereinit\n", __func__); + /* 10, 40, 90, 100, 100, ... */ + delay_time = max(100, 10 * (probe_again * probe_again)); + A_MDELAY(delay_time); + goto again; + } + + return ret; +} +#endif + +void hif_pci_notify_handler(struct pci_dev *pdev, int state) +{ + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + int ret = 0; + ret = hdd_wlan_notify_modem_power_state(state); + if (ret < 0) + printk(KERN_ERR "%s: Fail to send notify\n", __func__); + } +} + +void +hif_nointrs(struct hif_pci_softc *sc) +{ + int i; + + if (sc->num_msi_intrs > 0) { + /* MSI interrupt(s) */ + for (i = 0; i < sc->num_msi_intrs; i++) { + free_irq(sc->pdev->irq + i, sc); + } + sc->num_msi_intrs = 0; + } else { + /* Legacy PCI line interrupt */ + free_irq(sc->pdev->irq, sc); + } +} + +int +hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl) +{ + int ret = 0; + int num_msi_desired; + u_int32_t val; + + BUG_ON(pci_get_drvdata(sc->pdev) != NULL); + pci_set_drvdata(sc->pdev, sc); + + tasklet_init(&sc->intr_tq, wlan_tasklet, (unsigned long)sc); + + /* + * Interrupt Management is divided into these scenarios : + * A) We wish to use MSI and Multiple MSI is supported and we + * are able to obtain the number of MSI interrupts desired + * (best performance) + * B) We wish to use MSI and Single MSI is supported and we are + * able to obtain a single MSI interrupt + * C) We don't want to use MSI or MSI is not supported and we + * are able to obtain a legacy interrupt + * D) Failure + */ +#if defined(FORCE_LEGACY_PCI_INTERRUPTS) + num_msi_desired = 0; /* Use legacy PCI line interrupts rather than MSI */ +#else + num_msi_desired = MSI_NUM_REQUEST; /* Multiple MSI */ + if (!msienable) { + num_msi_desired = 0; + } +#endif + + printk("\n %s : num_desired MSI set to %d\n", __func__, num_msi_desired); + + if (num_msi_desired > 1) { + int i; + int rv; + + rv = pci_enable_msi_block(sc->pdev, MSI_NUM_REQUEST); + + if (rv == 0) { /* successfully allocated all MSI interrupts */ + /* + * TBDXXX: This path not yet tested, + * since Linux x86 does not currently + * support "Multiple MSIs". + */ + sc->num_msi_intrs = MSI_NUM_REQUEST; + ret = request_irq(sc->pdev->irq+MSI_ASSIGN_FW, hif_pci_msi_fw_handler, + IRQF_SHARED, "wlan_pci", sc); + if(ret) { + dev_err(&sc->pdev->dev, "request_irq failed\n"); + goto err_intr; + } + for (i=MSI_ASSIGN_CE_INITIAL; i<=MSI_ASSIGN_CE_MAX; i++) { + ret = request_irq(sc->pdev->irq+i, CE_per_engine_handler, IRQF_SHARED, + "wlan_pci", sc); + if(ret) { + dev_err(&sc->pdev->dev, "request_irq failed\n"); + goto err_intr; + } + } + } else { + if (rv < 0) { + /* Can't get any MSI -- try for legacy line interrupts */ + num_msi_desired = 0; + } else { + /* Can't get enough MSI interrupts -- try for just 1 */ + printk("\n %s : Can't allocate requested number of MSI, just use 1\n", __func__); + num_msi_desired = 1; + } + } + } + + if (num_msi_desired == 1) { + /* + * We are here because either the platform only supports + * single MSI OR because we couldn't get all the MSI interrupts + * that we wanted so we fall back to a single MSI. + */ + if (pci_enable_msi(sc->pdev) < 0) { + printk(KERN_ERR "ath: single MSI interrupt allocation failed\n"); + /* Try for legacy PCI line interrupts */ + num_msi_desired = 0; + } else { + /* Use a single Host-side MSI interrupt handler for all interrupts */ + num_msi_desired = 1; + } + } + + if ( num_msi_desired <= 1) { + /* We are here because we want to multiplex a single host interrupt among all + * Target interrupt sources + */ + ret = request_irq(sc->pdev->irq, hif_pci_interrupt_handler, IRQF_SHARED, + "wlan_pci", sc); + if(ret) { + dev_err(&sc->pdev->dev, "request_irq failed\n"); + goto err_intr; + } + + } +#if CONFIG_PCIE_64BIT_MSI + { + struct ol_ath_softc_net80211 *scn = sc->scn; + u_int8_t MSI_flag; + u_int32_t reg; + +#define OL_ATH_PCI_MSI_POS 0x50 +#define MSI_MAGIC_RDY_MASK 0x00000001 +#define MSI_MAGIC_EN_MASK 0x80000000 + + pci_read_config_byte(sc->pdev, OL_ATH_PCI_MSI_POS + PCI_MSI_FLAGS, &MSI_flag); + if (MSI_flag & PCI_MSI_FLAGS_ENABLE) { + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + while (!ath_pci_targ_is_awake(sc->mem)) { + ; + } + scn->MSI_magic = OS_MALLOC_CONSISTENT(scn->sc_osdev, 4, &scn->MSI_magic_dma, \ + OS_GET_DMA_MEM_CONTEXT(scn, MSI_dmacontext), 0); + A_PCI_WRITE32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADR_ADDRESS, + scn->MSI_magic_dma); + reg = A_PCI_READ32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADDRESS); + A_PCI_WRITE32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADDRESS, reg | MSI_MAGIC_RDY_MASK); + + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + } + } +#endif + + if(num_msi_desired == 0) { + printk("\n Using PCI Legacy Interrupt\n"); + + /* Make sure to wake the Target before enabling Legacy Interrupt */ + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_V_MASK); + while (!hif_pci_targ_is_awake(sc, sc->mem)) { + ; + } + /* Use Legacy PCI Interrupts */ + /* + * A potential race occurs here: The CORE_BASE write depends on + * target correctly decoding AXI address but host won't know + * when target writes BAR to CORE_CTRL. This write might get lost + * if target has NOT written BAR. For now, fix the race by repeating + * the write in below synchronization checking. + */ + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | + PCIE_INTR_ENABLE_ADDRESS), + PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_RESET); + } + + sc->num_msi_intrs = num_msi_desired; + sc->ce_count = CE_COUNT; + + { /* Synchronization point: Wait for Target to finish initialization before we proceed. */ + int wait_limit = 1000; /* 10 sec */ + + /* Make sure to wake Target before accessing Target memory */ + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + while (!hif_pci_targ_is_awake(sc, sc->mem)) { + ; + } + while (wait_limit-- && !(A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) & FW_IND_INITIALIZED)) { + if (num_msi_desired == 0) { + /* Fix potential race by repeating CORE_BASE writes */ + A_PCI_WRITE32(sc->mem + (SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), + PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + } + A_MDELAY(10); + } + + if (wait_limit < 0) { + printk(KERN_ERR "ath: %s: TARGET STALLED: .\n", __FUNCTION__); + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + ret = -EIO; + goto err_stalled; + } + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + } + + if (HIF_PCIDeviceProbed(sc)) { + printk(KERN_ERR "ath: %s: Target probe failed.\n", __FUNCTION__); + ret = -EIO; + goto err_stalled; + } + + *hif_hdl = sc->hif_device; + + /* + * Flag to avoid potential unallocated memory access from MSI + * interrupt handler which could get scheduled as soon as MSI + * is enabled, i.e to take care of the race due to the order + * in where MSI is enabled before the memory, that will be + * in interrupt handlers, is allocated. + */ + sc->hif_init_done = TRUE; + return 0; + +err_stalled: + /* Read Target CPU Intr Cause for debug */ + val = A_PCI_READ32(sc->mem + (SOC_CORE_BASE_ADDRESS | CPU_INTR_ADDRESS)); + printk("ERROR: Target Stalled : Target CPU Intr Cause 0x%x \n", val); + hif_nointrs(sc); +err_intr: + if (num_msi_desired) { + pci_disable_msi(sc->pdev); + } + pci_set_drvdata(sc->pdev, NULL); + + return ret; +} + +void +hif_pci_remove(struct pci_dev *pdev) +{ + struct hif_pci_softc *sc = pci_get_drvdata(pdev); + struct ol_softc *scn; + void __iomem *mem; + + /* Attach did not succeed, all resources have been + * freed in error handler + */ + if (!sc) + return; + + scn = sc->ol_sc; + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + pktlogmod_exit(scn); +#endif + + __hdd_wlan_exit(); + + mem = (void __iomem *)sc->mem; + + pci_disable_msi(pdev); + + hif_dump_pipe_debug_count(sc->hif_device); + + hif_deinit_adf_ctx(scn); + A_FREE(scn); + A_FREE(sc->hif_device); + A_FREE(sc); + pci_set_drvdata(pdev, NULL); + pci_iounmap(pdev, mem); + pci_release_region(pdev, BAR_NUM); + pci_clear_master(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "pci_remove\n"); +} + +/* This function will be called when SSR framework wants to + * shutdown WLAN host driver when SSR happens. Most of this + * function is duplicated from hif_pci_remove(). + */ +#if defined(CONFIG_CNSS) +void hif_pci_shutdown(struct pci_dev *pdev) +{ + void __iomem *mem; + struct hif_pci_softc *sc; + struct ol_softc *scn; + + sc = pci_get_drvdata(pdev); + /* Attach did not succeed, all resources have been + * freed in error handler. + */ + if (!sc) + return; + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + printk("Load/unload in progress, ignore SSR shutdown\n"); + return; + } + /* this is for cases, where shutdown invoked from CNSS */ + vos_set_logp_in_progress(VOS_MODULE_ID_HIF, TRUE); + + scn = sc->ol_sc; + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + pktlogmod_exit(scn); +#endif + + if (!vos_is_ssr_ready(__func__)) + printk("Host driver is not ready for SSR, attempting anyway\n"); + + hif_dump_pipe_debug_count(sc->hif_device); + + if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + hdd_wlan_shutdown(); + + mem = (void __iomem *)sc->mem; + + pci_disable_msi(pdev); + + hif_deinit_adf_ctx(scn); + A_FREE(scn); + A_FREE(sc->hif_device); + A_FREE(sc); + pci_set_drvdata(pdev, NULL); + pci_iounmap(pdev, mem); + pci_release_region(pdev, BAR_NUM); + pci_clear_master(pdev); + pci_disable_device(pdev); + + printk("%s: WLAN host driver shutting down completed!\n", __func__); +} + +void hif_pci_crash_shutdown(struct pci_dev *pdev) +{ +#ifdef TARGET_RAMDUMP_AFTER_KERNEL_PANIC + struct hif_pci_softc *sc; + struct ol_softc *scn; + struct HIF_CE_state *hif_state; + + sc = pci_get_drvdata(pdev); + if (!sc) + return; + + hif_state = (struct HIF_CE_state *)sc->hif_device; + if (!hif_state) + return; + + scn = sc->ol_sc; + if (!scn) + return; + + if (OL_TRGET_STATUS_RESET == scn->target_status) { + printk("%s: Target is already asserted, ignore!\n", __func__); + return; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + pr_info("%s: Load/unload is in progress, ignore!\n", __func__); + return; + } + + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + +#ifdef DEBUG + if (hif_pci_check_soc_status(scn->hif_sc) + || dump_CE_register(scn)) { + goto out; + } + + dump_CE_debug_register(scn->hif_sc); +#endif + + if (ol_copy_ramdump(scn)) { + goto out; + } + + printk("%s: RAM dump collecting completed!\n", __func__); + +out: + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + return; +#else + printk("%s: Collecting target RAM dump after kernel panic is disabled!\n", + __func__); + return; +#endif +} +#endif + +#define OL_ATH_PCI_PM_CONTROL 0x44 + +static int +__hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct hif_pci_softc *sc = pci_get_drvdata(pdev); + void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + ol_txrx_pdev_handle txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos); + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; + u32 tx_drain_wait_cnt = 0; + u32 val; + u32 ce_drain_wait_cnt = 0; + v_VOID_t * temp_module; + u32 tmp; + int ret = -1; + + if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) + return ret; + + if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0) + goto out; + + A_PCI_WRITE32(sc->mem + FW_INDICATOR_ADDRESS, (state.event << 16)); + + if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) + goto out; + + if (!txrx_pdev) { + printk("%s: txrx_pdev is NULL\n", __func__); + goto out; + } + /* Wait for pending tx completion */ + while (ol_txrx_get_tx_pending(txrx_pdev)) { + msleep(OL_ATH_TX_DRAIN_WAIT_DELAY); + if (++tx_drain_wait_cnt > OL_ATH_TX_DRAIN_WAIT_CNT) { + printk("%s: tx frames are pending\n", __func__); + goto out; + } + } + + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + goto out; + } + + if (wma_check_scan_in_progress(temp_module)) { + printk("%s: Scan in progress. Aborting suspend\n", __func__); + goto out; + } + + printk("%s: wow mode %d event %d\n", __func__, + wma_is_wow_mode_selected(temp_module), state.event); + + if (wma_is_wow_mode_selected(temp_module)) { + if(wma_enable_wow_in_fw(temp_module)) + goto out; + } else if (state.event == PM_EVENT_FREEZE || state.event == PM_EVENT_SUSPEND) { + if (wma_suspend_target(temp_module, 0)) + goto out; + } + + while (!adf_os_atomic_read(&sc->ce_suspend)) { + if (++ce_drain_wait_cnt > HIF_CE_DRAIN_WAIT_CNT) { + printk("%s: CE still not done with access: \n", __func__); + adf_os_atomic_set(&sc->wow_done, 0); + + if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0) + goto out; + val = A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) >> 16; + if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) + goto out; + + if (!wma_is_wow_mode_selected(temp_module) && + (val == PM_EVENT_HIBERNATE || val == PM_EVENT_SUSPEND)) { + wma_resume_target(temp_module); + goto out; + } + else { + wma_disable_wow_in_fw(temp_module); + goto out; + } + } + printk("%s: Waiting for CE to finish access: \n", __func__); + msleep(10); + } + +#ifdef FEATURE_WLAN_D0WOW + if (wma_get_client_count(temp_module)) { + if (enable_irq_wake(pdev->irq)) { + pr_err("%s: Fail to enable wake IRQ!\n", __func__); + ret = -1; + goto out; + } + + pr_info("%s: Suspend completes (D0WOW)\n", __func__); + ret = 0; + goto out; + } +#endif + + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + + /*Disable PCIe interrupts*/ + if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + goto out; + } + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), 0); + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_CLR_ADDRESS), + PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ + tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + if (tmp == 0xffffffff) { + printk(KERN_ERR "%s: PCIe pcie link is down\n", __func__); + VOS_ASSERT(0); + } + + if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + goto out; + } + + /* Stop the HIF Sleep Timer */ + HIFCancelDeferredTargetSleep(sc->hif_device); + + adf_os_atomic_set(&sc->pci_link_suspended, 1); + + adf_os_spin_unlock_irqrestore( &hif_state->suspend_lock); + +#ifdef CONFIG_CNSS + /* Keep PCIe bus driver's shadow memory intact */ + cnss_pcie_shadow_control(pdev, FALSE); +#endif + + pci_read_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, &val); + if ((val & 0x000000ff) != 0x3) { + pci_save_state(pdev); + pci_disable_device(pdev); + pci_write_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, (val & 0xffffff00) | 0x03); + } + + printk("%s: Suspend completes\n", __func__); + ret = 0; + +out: + return ret; +} + +static int hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int ret; + + vos_ssr_protect(__func__); + + ret = __hif_pci_suspend(pdev, state); + + vos_ssr_unprotect(__func__); + + return ret; +} + +static int +__hif_pci_resume(struct pci_dev *pdev) +{ + struct hif_pci_softc *sc = pci_get_drvdata(pdev); + void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; + u32 val; + int err = 0; + v_VOID_t * temp_module; + u32 tmp; + + if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) + return err; + + adf_os_atomic_set(&sc->pci_link_suspended, 0); + + /* Enable Legacy PCI line interrupts */ + if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0) + goto out; + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), + PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); + /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ + tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + if (tmp == 0xffffffff) { + printk(KERN_ERR "%s: PCIe link is down\n", __func__); + VOS_ASSERT(0); + } + if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) + goto out; + + + err = pci_enable_device(pdev); + if (err) + { + printk("\n%s %d : pci_enable_device returned failure %d\n", + __func__, __LINE__, err); + goto out; + } + + pci_read_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, &val); + if ((val & 0x000000ff) != 0) { + pci_restore_state(pdev); + pci_write_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, val & 0xffffff00); + + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state + * + */ + pci_read_config_dword(pdev, 0x40, &val); + + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + } + + printk("\n%s: Rome PS: %d", __func__, val); + +#ifdef CONFIG_CNSS + /* Keep PCIe bus driver's shadow memory intact */ + cnss_pcie_shadow_control(pdev, TRUE); +#endif + +#ifdef DISABLE_L1SS_STATES + pci_read_config_dword(pdev, 0x188, &val); + pci_write_config_dword(pdev, 0x188, (val & ~0x0000000f)); +#endif + + if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0) + goto out; + val = A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) >> 16; + if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) + goto out; + + /* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + goto out; + } + + printk("%s: wow mode %d val %d\n", __func__, + wma_is_wow_mode_selected(temp_module), val); + + adf_os_atomic_set(&sc->wow_done, 0); + + if (!wma_is_wow_mode_selected(temp_module) && + (val == PM_EVENT_HIBERNATE || val == PM_EVENT_SUSPEND)) + err = wma_resume_target(temp_module); + else + err = wma_disable_wow_in_fw(temp_module); + +#ifdef FEATURE_WLAN_D0WOW + if (wma_get_client_count(temp_module)) { + if (disable_irq_wake(pdev->irq)) { + pr_err("%s: Fail to disable wake IRQ!\n", __func__); + err = -1; + goto out; + } + } +#endif + +out: + printk("%s: Resume completes %d\n", __func__, err); + + if (err) + return (-1); + + return (0); +} + +static int +hif_pci_resume(struct pci_dev *pdev) +{ + int ret; + + vos_ssr_protect(__func__); + + ret = __hif_pci_resume(pdev); + + vos_ssr_unprotect(__func__); + + return ret; +} + +/* routine to modify the initial buffer count to be allocated on an os + * platform basis. Platform owner will need to modify this as needed + */ +adf_os_size_t initBufferCount(adf_os_size_t maxSize) +{ + return maxSize; +} + +#ifdef CONFIG_CNSS +struct cnss_wlan_driver cnss_wlan_drv_id = { + .name = "hif_pci", + .id_table = hif_pci_id_table, + .probe = hif_pci_probe, + .remove = hif_pci_remove, + .reinit = hif_pci_reinit, + .shutdown = hif_pci_shutdown, + .crash_shutdown = hif_pci_crash_shutdown, + .modem_status = hif_pci_notify_handler, +#ifdef ATH_BUS_PM + .suspend = hif_pci_suspend, + .resume = hif_pci_resume, +#endif +}; +#else +MODULE_DEVICE_TABLE(pci, hif_pci_id_table); +struct pci_driver hif_pci_drv_id = { + .name = "hif_pci", + .id_table = hif_pci_id_table, + .probe = hif_pci_probe, + .remove = hif_pci_remove, +#ifdef ATH_BUS_PM + .suspend = hif_pci_suspend, + .resume = hif_pci_resume, +#endif +}; +#endif + +int hif_register_driver(void) +{ +#ifdef CONFIG_CNSS + return cnss_wlan_register_driver(&cnss_wlan_drv_id); +#else + return pci_register_driver(&hif_pci_drv_id); +#endif +} + +void hif_unregister_driver(void) +{ +#ifdef CONFIG_CNSS + cnss_wlan_unregister_driver(&cnss_wlan_drv_id); +#else + pci_unregister_driver(&hif_pci_drv_id); +#endif +} + +/* Function to set the TXRX handle in the ol_sc context */ +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + sc->pdev_txrx_handle = txrx_handle; +} + +void hif_disable_isr(void *ol_sc) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + struct hif_pci_softc *hif_sc = sc->hif_sc; + struct ol_softc *scn; + + scn = hif_sc->ol_sc; + hif_nointrs(hif_sc); +#if CONFIG_PCIE_64BIT_MSI + OS_FREE_CONSISTENT(scn->sc_osdev, 4, scn->MSI_magic, scn->MSI_magic_dma, + OS_GET_DMA_MEM_CONTEXT(scn, MSI_dmacontext)); + scn->MSI_magic = NULL; + scn->MSI_magic_dma = 0; +#endif + /* Cancel the pending tasklet */ + tasklet_kill(&hif_sc->intr_tq); +} + +/* Function to reset SoC */ +void hif_reset_soc(void *ol_sc) +{ + struct ol_softc *scn = (struct ol_softc *)ol_sc; + struct hif_pci_softc *sc = scn->hif_sc; + +#if defined(CPU_WARM_RESET_WAR) + /* Currently CPU warm reset sequence is tested only for AR9888_REV2 + * Need to enable for AR9888_REV1 once CPU warm reset sequence is + * verified for AR9888_REV1 + */ + if (scn->target_version == AR9888_REV2_VERSION) { + hif_pci_device_warm_reset(sc); + } + else { + hif_pci_device_reset(sc); + } +#else + hif_pci_device_reset(sc); +#endif +} + +void hif_disable_aspm(void) +{ + u_int32_t lcr_val = 0; + void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct ol_softc *scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + struct hif_pci_softc *sc; + + if (NULL == scn) + { + printk(KERN_ERR "%s: Could not disable ASPM scn is null\n", __func__); + return; + } + + sc = scn->hif_sc; + + /* Disable ASPM when pkt log is enabled */ + pci_read_config_dword(sc->pdev, 0x80, &lcr_val); + pci_write_config_dword(sc->pdev, 0x80, (lcr_val & 0xffffff00)); +} + +void hif_pci_save_htc_htt_config_endpoint(int htc_endpoint) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct ol_softc *scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + + if (!scn || !scn->hif_sc) { + printk(KERN_ERR "%s: error: scn or scn->hif_sc is NULL!\n", __func__); + return; + } + + scn->hif_sc->htc_endpoint = htc_endpoint; +} + +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) +{ + *version = ((struct ol_softc *)ol_sc)->target_version; + *revision = ((struct ol_softc *)ol_sc)->target_revision; +} + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} + +#ifdef IPA_UC_OFFLOAD +/* Micro controller needs PCI BAR address to access CE register */ +void hif_read_bar(struct hif_pci_softc *sc, u32 *bar_value) +{ + pci_read_config_dword(sc->pdev, 0x10, bar_value); + *bar_value = pci_resource_start(sc->pdev, 0); +} +#endif /* IPA_UC_OFFLOAD */ + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +void wlan_hif_pci_suspend(void) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct ol_softc *scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + pm_message_t state; + + if (!scn || !scn->hif_sc) { + printk(KERN_ERR "%s: error: scn or scn->hif_sc is NULL!\n", __func__); + return; + } + state.event = PM_EVENT_SUSPEND; + hif_pci_suspend(scn->hif_sc->pdev, state); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h new file mode 100644 index 0000000000000..66980697fb32c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#ifndef __ATH_PCI_H__ +#define __ATH_PCI_H__ + +#include +#include +#include + +#define CONFIG_COPY_ENGINE_SUPPORT /* TBDXXX: here for now */ +#define ATH_DBG_DEFAULT 0 +#include +#include +#include +#include "osapi_linux.h" +#include "hif.h" +#include "cepci.h" + +/* Maximum number of Copy Engine's supported */ +#define CE_COUNT_MAX 8 +#define CE_HTT_H2T_MSG_SRC_NENTRIES 2048 + +struct CE_state; +struct ol_softc; + +/* An address (e.g. of a buffer) in Copy Engine space. */ +typedef ath_dma_addr_t CE_addr_t; + +struct hif_pci_softc { + void __iomem *mem; /* PCI address. */ + /* For efficiency, should be first in struct */ + + struct device *dev; + struct pci_dev *pdev; + struct _NIC_DEV aps_osdev; + struct ol_softc *ol_sc; + int num_msi_intrs; /* number of MSI interrupts granted */ + /* 0 --> using legacy PCI line interrupts */ + struct tasklet_struct intr_tq; /* tasklet */ + + int irq; + int irq_event; + int cacheline_sz; + /* + * Guard changes to Target HW state and to software + * structures that track hardware state. + */ + adf_os_spinlock_t target_lock; + + unsigned int ce_count; /* Number of Copy Engines supported */ + struct CE_state *CE_id_to_state[CE_COUNT_MAX]; /* Map CE id to CE_state */ + HIF_DEVICE *hif_device; + + bool force_break; /* Flag to indicate whether to break out the DPC context */ + unsigned int receive_count; /* count Num Of Receive Buffers handled for one interrupt DPC routine */ + u16 devid; + struct targetdef_s *targetdef; + struct hostdef_s *hostdef; + atomic_t tasklet_from_intr; + atomic_t wow_done; + atomic_t ce_suspend; + atomic_t pci_link_suspended; + bool hif_init_done; + bool recovery; + int htc_endpoint; +}; +#define TARGID(sc) ((A_target_id_t)(&(sc)->mem)) +#define TARGID_TO_HIF(targid) (((struct hif_pci_softc *)((char *)(targid) - (char *)&(((struct hif_pci_softc *)0)->mem)))->hif_device) + +int athdiag_procfs_init(void *scn); +void athdiag_procfs_remove(void); + +bool hif_pci_targ_is_awake(struct hif_pci_softc *sc, void *__iomem *mem); + +bool hif_pci_targ_is_present(A_target_id_t targetid, void *__iomem *mem); + +bool hif_max_num_receives_reached(unsigned int count); + +int HIF_PCIDeviceProbed(hif_handle_t hif_hdl); +irqreturn_t HIF_fw_interrupt_handler(int irq, void *arg); + +/* routine to modify the initial buffer count to be allocated on an os + * platform basis. Platform owner will need to modify this as needed + */ +adf_os_size_t initBufferCount(adf_os_size_t maxSize); + +/* Function to disable ASPM */ +void hif_disable_aspm(void); + +void hif_pci_save_htc_htt_config_endpoint(int htc_endpoint); + +#ifndef REMOVE_PKT_LOG +extern int pktlogmod_init(void *context); +extern void pktlogmod_exit(void *context); +#endif + +int hif_pci_check_fw_reg(struct hif_pci_softc *sc); +int hif_pci_check_soc_status(struct hif_pci_softc *sc); +void dump_CE_debug_register(struct hif_pci_softc *sc); + +/*These functions are exposed to HDD*/ +int hif_register_driver(void); +void hif_unregister_driver(void); +int hif_init_adf_ctx(void *ol_sc); +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); +void hif_disable_isr(void *ol_sc); +void hif_reset_soc(void *ol_sc); +void hif_deinit_adf_ctx(void *ol_sc); +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +void hif_set_fw_info(void *ol_sc, u32 target_fw_version); + +#ifdef IPA_UC_OFFLOAD +/* + * Micro controller needs PCI BAR address to access CE register + * If Micro controller data path enabled, control path will + * try to get PCI BAR address and will send to IPA driver + */ +void hif_read_bar(struct hif_pci_softc *sc, u32 *bar_value); +#endif /* IPA_UC_OFFLOAD */ + +/* + * A firmware interrupt to the Host is indicated by the + * low bit of SCRATCH_3_ADDRESS being set. + */ +#define FW_EVENT_PENDING_REG_ADDRESS SCRATCH_3_ADDRESS + +/* + * Typically, MSI Interrupts are used with PCIe. To force use of legacy + * "ABCD" PCI line interrupts rather than MSI, define FORCE_LEGACY_PCI_INTERRUPTS. + * Even when NOT forced, the driver may attempt to use legacy PCI interrupts + * MSI allocation fails + */ +#define LEGACY_INTERRUPTS(sc) ((sc)->num_msi_intrs == 0) + +/* + * There may be some pending tx frames during platform suspend. + * Suspend operation should be delayed until those tx frames are + * transfered from the host to target. This macro specifies how + * long suspend thread has to sleep before checking pending tx + * frame count. + */ +#define OL_ATH_TX_DRAIN_WAIT_DELAY 50 /* ms */ + +#define HIF_CE_DRAIN_WAIT_DELAY 10 /* ms */ +/* + * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending + * tx frame completion before suspend. Refer: hif_pci_suspend() + */ +#define OL_ATH_TX_DRAIN_WAIT_CNT 10 + +#define HIF_CE_DRAIN_WAIT_CNT 20 +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +void wlan_hif_pci_suspend(void); +#endif +#endif /* __ATH_PCI_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/mp_dev.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/mp_dev.c new file mode 100644 index 0000000000000..314003c28ba08 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/mp_dev.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "if_pci.h" + +/*chaninfo*/ +#define CHANINFOMEM_S2_READ_MASK 0x00000008 +#define CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK 0x00000001 +#define CHANINFO_CTRL_CHANINFOMEM_BW_MASK 0x00000030 +#define MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK 0x00000007 + +/*agc*/ +#define GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK 0x00040000 +#define GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK 0x00080000 +#define GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK 0x00100000 +#define GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK 0x00200000 +#define AGC_HISTORY_DUMP_MASK GAINS_MIN_OFFSETS_CF_AGC_HIST_ENABLE_MASK| \ + GAINS_MIN_OFFSETS_CF_AGC_HIST_GC_MASK| \ + GAINS_MIN_OFFSETS_CF_AGC_HIST_VOTING_MASK| \ + GAINS_MIN_OFFSETS_CF_AGC_HIST_PHY_ERR_MASK + +#define BB_chaninfo_ctrl 0x1a370 +#define BB_multichain_enable 0x1a2a0 +#define BB_chn_tables_intf_addr 0x19894 +#define BB_chn1_tables_intf_addr 0x1a894 +#define BB_chn_tables_intf_data 0x19898 +#define BB_chn1_tables_intf_data 0x1a898 +#define BB_gains_min_offsets 0x19e08 +#define BB_chaninfo_tab_b0 0x03200 +#define BB_chaninfo_tab_b1 0x03300 +#define BB_watchdog_status 0x1a7c0 +#define BB_watchdog_ctrl_1 0x1a7c4 +#define BB_watchdog_ctrl_2 0x1a7c8 +#define BB_watchdog_status_B 0x1a7e0 + +struct priv_ctrl_ctx { + u_int32_t chaninfo_ctrl_orig; + u_int32_t gain_min_offsets_orig; + u_int32_t anyreg_start; + u_int32_t anyreg_len; +}; + +static struct priv_ctrl_ctx g_Priv_Dump_Ctx; + +static INLINE void set_target_reg_bits(struct hif_pci_softc* hif, u_int32_t reg, u_int32_t bitmask, u_int32_t val) +{ + u_int32_t value = A_PCI_READ32(hif->mem + (reg)); + u_int32_t shift = 0; + value &= ~(bitmask); + while (!((bitmask >> shift) & 0x01)) { + shift++; + } + value |= (((val)<mem + (reg), value); +} + +static INLINE u_int32_t get_target_reg_bits(struct hif_pci_softc* hif, u_int32_t reg, u_int32_t bitmask) +{ + u_int32_t value = A_PCI_READ32(hif->mem + (reg)); + u_int32_t shift = 0; + while (!((bitmask >> shift) & 0x01)) { + shift++; + } + return (value>>shift)&bitmask; +} + +void priv_start_cap_chaninfo(struct hif_pci_softc* hif_sc) +{ + set_target_reg_bits(hif_sc, BB_chaninfo_ctrl, CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK, 1); +} + +void priv_start_agc(struct hif_pci_softc* hif_sc) +{ + g_Priv_Dump_Ctx.gain_min_offsets_orig = A_PCI_READ32(hif_sc->mem + BB_gains_min_offsets); + set_target_reg_bits(hif_sc, BB_gains_min_offsets, AGC_HISTORY_DUMP_MASK, 0x0f); +} + +void priv_stop_agc(struct hif_pci_softc* hif_sc) +{ + set_target_reg_bits(hif_sc, BB_gains_min_offsets, AGC_HISTORY_DUMP_MASK, 0); +} + +void priv_dump_chaninfo(struct hif_pci_softc* hif_sc) +{ + u_int32_t bw, val; + u_int32_t len, i, tmp; + u_int32_t chain_mask; + u_int32_t chain0, chain1; + + chain_mask = get_target_reg_bits(hif_sc, BB_multichain_enable, MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK); + chain0 = chain_mask & 1; + chain1 = chain_mask & 2; + + printk("\nChannel info dump:\n"); + bw = get_target_reg_bits(hif_sc, BB_chaninfo_ctrl, CHANINFO_CTRL_CHANINFOMEM_BW_MASK); + + if (bw == 0) { + len = 53; + } else if (bw == 1) { + len = 57; + } else if (bw == 2) { + len = 59*2-1; + } else { + len = 60*2+61*2; + } + + /* + * each tone is 16 bit valid, write to 32bit buffer each. + * bw==0(legacy20): 53 tones. + * bw==1(ht/vht20): 57 tones. + * bw==2(ht/vht40): 59+58 tones. + * bw==3(vht80): 60*2+61*2 tones. + */ + + if (chain0) { + A_PCI_WRITE32(hif_sc->mem+BB_chn_tables_intf_addr, 0x80003200); + } + if (chain1) { + A_PCI_WRITE32(hif_sc->mem+BB_chn1_tables_intf_addr, 0x80003200); + } + + set_target_reg_bits(hif_sc, BB_chaninfo_ctrl, CHANINFOMEM_S2_READ_MASK, 0); + + if (chain0) { + if (bw < 2) { + len = (bw == 0) ? 53 : 57; + for (i=0; imem+BB_chn_tables_intf_data) & 0x0000ffff; + printk("0x%x\t",val); + if (i%4 == 0) + printk("\n"); + } + } else { + len = (bw == 2) ? 59 : 60; + for (i=0; imem+BB_chn_tables_intf_data); + printk("0x%x\t", ((tmp>>16) & 0x0000ffff)); + printk("0x%x\t", (tmp & 0x0000ffff)); + if (i%2 == 0) + printk("\n"); + } + if (bw > 2) { + //bw == 3 for vht80 + A_PCI_WRITE32(hif_sc->mem+BB_chn_tables_intf_addr, 0x80003300); + len = 61; + for (i=0; imem+BB_chn_tables_intf_data); + printk("0x%x\t", ((tmp>>16) & 0x0000ffff)); + printk("0x%x\t", (tmp & 0x0000ffff)); + if (i%2 == 0) + printk("\n"); + } + } + } + } + if (chain1) { + if (bw < 2) { + len = (bw == 0) ? 53 : 57; + for (i=0; imem+BB_chn1_tables_intf_data) & 0x0000ffff; + printk("0x%x\t",val); + if (i%4 == 0) + printk("\n"); + } + } else { + len = (bw == 2) ? 59 : 60; + for (i=0; imem+BB_chn1_tables_intf_data); + printk("0x%x\n", (tmp>>16) & 0x0000ffff); + printk("0x%x\n", tmp & 0x0000ffff); + if (i%2 == 0) + printk("\n"); + } + if (bw > 2) { + //bw == 3 for vht80 + A_PCI_WRITE32(hif_sc->mem+BB_chn1_tables_intf_addr, 0x80003300); + len = 61; + for (i=0; imem+BB_chn1_tables_intf_data); + printk("0x%x\t", ((tmp>>16) & 0x0000ffff)); + printk("0x%x\t", (tmp & 0x0000ffff)); + if (i%2 == 0) + printk("\n"); + } + } + } + } + printk("\nChannel info dump complete\n"); +} + +void priv_dump_agc(struct hif_pci_softc* hif_sc) +{ + int i, len = 30; //check this value for Rome and Peregrine + u_int32_t chain0, chain1, chain_mask, val; + + chain_mask = get_target_reg_bits(hif_sc, BB_multichain_enable, MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK); + chain0 = chain_mask & 1; + chain1 = chain_mask & 2; + + len = len<<1; //each agc item is 64bit, total*2 + priv_stop_agc(hif_sc); + + set_target_reg_bits(hif_sc, BB_chaninfo_ctrl, CHANINFOMEM_S2_READ_MASK, 0); + + printk("AGC history buffer dump:\n"); + if (chain0) { + for (i = 0; i < len; i++) { + val = A_PCI_READ32(hif_sc->mem + BB_chaninfo_tab_b0 + i*4); + printk("0x%x\t", val); + if (i%4 == 0) + printk("\n"); + } + } + if (chain1) { + for (i = 0; i < len; i++) { + val = A_PCI_READ32(hif_sc->mem + BB_chaninfo_tab_b1 + i*4); + printk("0x%x\t", val); + if (i%4 == 0) + printk("\n"); + } + } + printk("\nAGC history buffer dump complete\n"); + //restore original value + A_PCI_WRITE32(hif_sc->mem + BB_gains_min_offsets, g_Priv_Dump_Ctx.gain_min_offsets_orig); + return; +} + +void priv_dump_bbwatchdog(struct hif_pci_softc* hif_sc) +{ + u_int32_t val; + + printk("BB watchdog dump\n"); + val = A_PCI_READ32(hif_sc->mem + BB_watchdog_status); + printk("0x%x\t",val); + val = A_PCI_READ32(hif_sc->mem + BB_watchdog_ctrl_1); + printk("0x%x\t",val); + val = A_PCI_READ32(hif_sc->mem + BB_watchdog_ctrl_2); + printk("0x%x\t",val); + val = A_PCI_READ32(hif_sc->mem + BB_watchdog_status_B); + printk("0x%x\n",val); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.c new file mode 100644 index 0000000000000..14cb319a4384f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "bmi_msg.h" +#include "targaddrs.h" +#include "cepci.h" +#include "regtable.h" +#include "ar9888def.h" +#include "ar6320def.h" +#include "ar6320v2def.h" + +void target_register_tbl_attach(struct hif_pci_softc *sc, u32 target_type) +{ + switch (target_type) { + case TARGET_TYPE_AR9888: + sc->targetdef = &ar9888_targetdef; + break; + case TARGET_TYPE_AR6320: + sc->targetdef = &ar6320_targetdef; + break; + case TARGET_TYPE_AR6320V2: + sc->targetdef = &ar6320v2_targetdef; + break; + default: + break; + } +} + +void hif_register_tbl_attach(struct hif_pci_softc *sc, u32 hif_type) +{ + switch (hif_type) { + case HIF_TYPE_AR9888: + sc->hostdef = &ar9888_hostdef; + break; + case HIF_TYPE_AR6320: + sc->hostdef = &ar6320_hostdef; + break; + case HIF_TYPE_AR6320V2: + sc->hostdef = &ar6320v2_hostdef; + break; + default: + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.h new file mode 100644 index 0000000000000..8964aeebf3adb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/regtable.h @@ -0,0 +1,841 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _REGTABLE_H_ +#define _REGTABLE_H_ +#include "if_pci.h" + +#define MISSING 0 + +typedef struct targetdef_s { + u_int32_t d_RTC_SOC_BASE_ADDRESS; + u_int32_t d_RTC_WMAC_BASE_ADDRESS; + u_int32_t d_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_LSB; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_MASK; + u_int32_t d_CLOCK_CONTROL_OFFSET; + u_int32_t d_CLOCK_CONTROL_SI0_CLK_MASK; + u_int32_t d_RESET_CONTROL_OFFSET; + u_int32_t d_RESET_CONTROL_MBOX_RST_MASK; + u_int32_t d_RESET_CONTROL_SI0_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_OFFSET; + u_int32_t d_WLAN_RESET_CONTROL_COLD_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_WARM_RST_MASK; + u_int32_t d_GPIO_BASE_ADDRESS; + u_int32_t d_GPIO_PIN0_OFFSET; + u_int32_t d_GPIO_PIN1_OFFSET; + u_int32_t d_GPIO_PIN0_CONFIG_MASK; + u_int32_t d_GPIO_PIN1_CONFIG_MASK; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_LSB; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_MASK; + u_int32_t d_SI_CONFIG_I2C_LSB; + u_int32_t d_SI_CONFIG_I2C_MASK; + u_int32_t d_SI_CONFIG_POS_SAMPLE_LSB; + u_int32_t d_SI_CONFIG_POS_SAMPLE_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_MASK; + u_int32_t d_SI_CONFIG_DIVIDER_LSB; + u_int32_t d_SI_CONFIG_DIVIDER_MASK; + u_int32_t d_SI_BASE_ADDRESS; + u_int32_t d_SI_CONFIG_OFFSET; + u_int32_t d_SI_TX_DATA0_OFFSET; + u_int32_t d_SI_TX_DATA1_OFFSET; + u_int32_t d_SI_RX_DATA0_OFFSET; + u_int32_t d_SI_RX_DATA1_OFFSET; + u_int32_t d_SI_CS_OFFSET; + u_int32_t d_SI_CS_DONE_ERR_MASK; + u_int32_t d_SI_CS_DONE_INT_MASK; + u_int32_t d_SI_CS_START_LSB; + u_int32_t d_SI_CS_START_MASK; + u_int32_t d_SI_CS_RX_CNT_LSB; + u_int32_t d_SI_CS_RX_CNT_MASK; + u_int32_t d_SI_CS_TX_CNT_LSB; + u_int32_t d_SI_CS_TX_CNT_MASK; + u_int32_t d_BOARD_DATA_SZ; + u_int32_t d_BOARD_EXT_DATA_SZ; + u_int32_t d_MBOX_BASE_ADDRESS; + u_int32_t d_LOCAL_SCRATCH_OFFSET; + u_int32_t d_CPU_CLOCK_OFFSET; + u_int32_t d_LPO_CAL_OFFSET; + u_int32_t d_GPIO_PIN10_OFFSET; + u_int32_t d_GPIO_PIN11_OFFSET; + u_int32_t d_GPIO_PIN12_OFFSET; + u_int32_t d_GPIO_PIN13_OFFSET; + u_int32_t d_CLOCK_GPIO_OFFSET; + u_int32_t d_CPU_CLOCK_STANDARD_LSB; + u_int32_t d_CPU_CLOCK_STANDARD_MASK; + u_int32_t d_LPO_CAL_ENABLE_LSB; + u_int32_t d_LPO_CAL_ENABLE_MASK; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK; + u_int32_t d_ANALOG_INTF_BASE_ADDRESS; + u_int32_t d_WLAN_MAC_BASE_ADDRESS; + u_int32_t d_CE0_BASE_ADDRESS; + u_int32_t d_CE1_BASE_ADDRESS; + u_int32_t d_FW_INDICATOR_ADDRESS; + u_int32_t d_DRAM_BASE_ADDRESS; + u_int32_t d_SOC_CORE_BASE_ADDRESS; + u_int32_t d_CORE_CTRL_ADDRESS; + u_int32_t d_CE_COUNT; + u_int32_t d_MSI_NUM_REQUEST; + u_int32_t d_MSI_ASSIGN_FW; + u_int32_t d_MSI_ASSIGN_CE_INITIAL; + u_int32_t d_PCIE_INTR_ENABLE_ADDRESS; + u_int32_t d_PCIE_INTR_CLR_ADDRESS; + u_int32_t d_PCIE_INTR_FIRMWARE_MASK; + u_int32_t d_PCIE_INTR_CE_MASK_ALL; + u_int32_t d_CORE_CTRL_CPU_INTR_MASK; + u_int32_t d_SR_WR_INDEX_ADDRESS; + u_int32_t d_DST_WATERMARK_ADDRESS; + + /* htt_rx.c */ + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_LSB; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_MASK; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_MASK; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_LSB; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_LSB; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_MASK; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_LSB; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_MASK; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_LSB; + u_int32_t d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_MASK; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_LSB; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_MASK; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_LSB; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_MASK; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_LSB; + u_int32_t d_RX_ATTENTION_0_MORE_DATA_MASK; + u_int32_t d_RX_ATTENTION_0_MSDU_DONE_MASK; + u_int32_t d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK; + /* end */ + /* copy_engine.c */ + u_int32_t d_DST_WR_INDEX_ADDRESS; + u_int32_t d_SRC_WATERMARK_ADDRESS; + u_int32_t d_SRC_WATERMARK_LOW_MASK; + u_int32_t d_SRC_WATERMARK_HIGH_MASK; + u_int32_t d_DST_WATERMARK_LOW_MASK; + u_int32_t d_DST_WATERMARK_HIGH_MASK; + u_int32_t d_CURRENT_SRRI_ADDRESS; + u_int32_t d_CURRENT_DRRI_ADDRESS; + u_int32_t d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_ADDRESS; + u_int32_t d_HOST_IS_COPY_COMPLETE_MASK; + u_int32_t d_CE_WRAPPER_BASE_ADDRESS; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS; + u_int32_t d_HOST_IE_ADDRESS; + u_int32_t d_HOST_IE_COPY_COMPLETE_MASK; + u_int32_t d_SR_BA_ADDRESS; + u_int32_t d_SR_SIZE_ADDRESS; + u_int32_t d_CE_CTRL1_ADDRESS; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_MASK; + u_int32_t d_DR_BA_ADDRESS; + u_int32_t d_DR_SIZE_ADDRESS; + u_int32_t d_MISC_IE_ADDRESS; + u_int32_t d_MISC_IS_AXI_ERR_MASK; + u_int32_t d_MISC_IS_DST_ADDR_ERR_MASK; + u_int32_t d_MISC_IS_SRC_LEN_ERR_MASK; + u_int32_t d_MISC_IS_DST_MAX_LEN_VIO_MASK; + u_int32_t d_MISC_IS_DST_RING_OVERFLOW_MASK; + u_int32_t d_MISC_IS_SRC_RING_OVERFLOW_MASK; + u_int32_t d_SRC_WATERMARK_LOW_LSB; + u_int32_t d_SRC_WATERMARK_HIGH_LSB; + u_int32_t d_DST_WATERMARK_LOW_LSB; + u_int32_t d_DST_WATERMARK_HIGH_LSB; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_LSB; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_OFFSET; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_LSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MASK; + u_int32_t d_WLAN_DEBUG_CONTROL_OFFSET; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MSB; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_LSB; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MASK; + u_int32_t d_WLAN_DEBUG_OUT_OFFSET; + u_int32_t d_WLAN_DEBUG_OUT_DATA_MSB; + u_int32_t d_WLAN_DEBUG_OUT_DATA_LSB; + u_int32_t d_WLAN_DEBUG_OUT_DATA_MASK; + u_int32_t d_AMBA_DEBUG_BUS_OFFSET; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK; + u_int32_t d_AMBA_DEBUG_BUS_SEL_MSB; + u_int32_t d_AMBA_DEBUG_BUS_SEL_LSB; + u_int32_t d_AMBA_DEBUG_BUS_SEL_MASK; + u_int32_t d_CE_WRAPPER_DEBUG_OFFSET; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_MSB; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_LSB; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_MASK; + u_int32_t d_CE_DEBUG_OFFSET; + u_int32_t d_CE_DEBUG_SEL_MSB; + u_int32_t d_CE_DEBUG_SEL_LSB; + u_int32_t d_CE_DEBUG_SEL_MASK; + /* end */ + /* PLL start */ + u_int32_t d_EFUSE_OFFSET; + u_int32_t d_EFUSE_XTAL_SEL_MSB; + u_int32_t d_EFUSE_XTAL_SEL_LSB; + u_int32_t d_EFUSE_XTAL_SEL_MASK; + u_int32_t d_BB_PLL_CONFIG_OFFSET; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_MSB; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_LSB; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_MASK; + u_int32_t d_BB_PLL_CONFIG_FRAC_MSB; + u_int32_t d_BB_PLL_CONFIG_FRAC_LSB; + u_int32_t d_BB_PLL_CONFIG_FRAC_MASK; + u_int32_t d_WLAN_PLL_SETTLE_TIME_MSB; + u_int32_t d_WLAN_PLL_SETTLE_TIME_LSB; + u_int32_t d_WLAN_PLL_SETTLE_TIME_MASK; + u_int32_t d_WLAN_PLL_SETTLE_OFFSET; + u_int32_t d_WLAN_PLL_SETTLE_SW_MASK; + u_int32_t d_WLAN_PLL_SETTLE_RSTMASK; + u_int32_t d_WLAN_PLL_SETTLE_RESET; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MSB; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_LSB; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MASK; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MSB; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_LSB; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MASK; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_RESET; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MSB; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_LSB; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MASK; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_RESET; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MSB; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_LSB; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MASK; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_RESET; + u_int32_t d_WLAN_PLL_CONTROL_DIV_MSB; + u_int32_t d_WLAN_PLL_CONTROL_DIV_LSB; + u_int32_t d_WLAN_PLL_CONTROL_DIV_MASK; + u_int32_t d_WLAN_PLL_CONTROL_DIV_RESET; + u_int32_t d_WLAN_PLL_CONTROL_OFFSET; + u_int32_t d_WLAN_PLL_CONTROL_SW_MASK; + u_int32_t d_WLAN_PLL_CONTROL_RSTMASK; + u_int32_t d_WLAN_PLL_CONTROL_RESET; + u_int32_t d_SOC_CORE_CLK_CTRL_OFFSET; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MSB; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_LSB; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MASK; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MSB; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_LSB; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MASK; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_RESET; + u_int32_t d_RTC_SYNC_STATUS_OFFSET; + u_int32_t d_SOC_CPU_CLOCK_OFFSET; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_MSB; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_LSB; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_MASK; + /* PLL end */ + u_int32_t d_SOC_POWER_REG_OFFSET; + u_int32_t d_PCIE_INTR_CAUSE_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB; + u_int32_t d_SOC_RESET_CONTROL_CE_RST_MASK; + u_int32_t d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK; + u_int32_t d_CPU_INTR_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK; + /* chip id start */ + u_int32_t d_SOC_CHIP_ID_ADDRESS; + u_int32_t d_SOC_CHIP_ID_VERSION_MASK; + u_int32_t d_SOC_CHIP_ID_VERSION_LSB; + u_int32_t d_SOC_CHIP_ID_REVISION_MASK; + u_int32_t d_SOC_CHIP_ID_REVISION_LSB; + /* chip id end */ +} TARGET_REGISTER_TABLE; + +#define RTC_SOC_BASE_ADDRESS (sc->targetdef->d_RTC_SOC_BASE_ADDRESS) +#define RTC_WMAC_BASE_ADDRESS (sc->targetdef->d_RTC_WMAC_BASE_ADDRESS) +#define SYSTEM_SLEEP_OFFSET (sc->targetdef->d_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_OFFSET (sc->targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB) +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define CLOCK_CONTROL_OFFSET (sc->targetdef->d_CLOCK_CONTROL_OFFSET) +#define CLOCK_CONTROL_SI0_CLK_MASK (sc->targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK) +#define RESET_CONTROL_OFFSET (sc->targetdef->d_RESET_CONTROL_OFFSET) +#define RESET_CONTROL_MBOX_RST_MASK (sc->targetdef->d_RESET_CONTROL_MBOX_RST_MASK) +#define RESET_CONTROL_SI0_RST_MASK (sc->targetdef->d_RESET_CONTROL_SI0_RST_MASK) +#define WLAN_RESET_CONTROL_OFFSET (sc->targetdef->d_WLAN_RESET_CONTROL_OFFSET) +#define WLAN_RESET_CONTROL_COLD_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_WARM_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK) +#define GPIO_BASE_ADDRESS (sc->targetdef->d_GPIO_BASE_ADDRESS) +#define GPIO_PIN0_OFFSET (sc->targetdef->d_GPIO_PIN0_OFFSET) +#define GPIO_PIN1_OFFSET (sc->targetdef->d_GPIO_PIN1_OFFSET) +#define GPIO_PIN0_CONFIG_MASK (sc->targetdef->d_GPIO_PIN0_CONFIG_MASK) +#define GPIO_PIN1_CONFIG_MASK (sc->targetdef->d_GPIO_PIN1_CONFIG_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_LSB (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB) +#define SI_CONFIG_BIDIR_OD_DATA_MASK (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_LSB (sc->targetdef->d_SI_CONFIG_I2C_LSB) +#define SI_CONFIG_I2C_MASK (sc->targetdef->d_SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_LSB (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_LSB) +#define SI_CONFIG_POS_SAMPLE_MASK (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB) +#define SI_CONFIG_INACTIVE_CLK_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB) +#define SI_CONFIG_INACTIVE_DATA_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_LSB (sc->targetdef->d_SI_CONFIG_DIVIDER_LSB) +#define SI_CONFIG_DIVIDER_MASK (sc->targetdef->d_SI_CONFIG_DIVIDER_MASK) +#define SI_BASE_ADDRESS (sc->targetdef->d_SI_BASE_ADDRESS) +#define SI_CONFIG_OFFSET (sc->targetdef->d_SI_CONFIG_OFFSET) +#define SI_TX_DATA0_OFFSET (sc->targetdef->d_SI_TX_DATA0_OFFSET) +#define SI_TX_DATA1_OFFSET (sc->targetdef->d_SI_TX_DATA1_OFFSET) +#define SI_RX_DATA0_OFFSET (sc->targetdef->d_SI_RX_DATA0_OFFSET) +#define SI_RX_DATA1_OFFSET (sc->targetdef->d_SI_RX_DATA1_OFFSET) +#define SI_CS_OFFSET (sc->targetdef->d_SI_CS_OFFSET) +#define SI_CS_DONE_ERR_MASK (sc->targetdef->d_SI_CS_DONE_ERR_MASK) +#define SI_CS_DONE_INT_MASK (sc->targetdef->d_SI_CS_DONE_INT_MASK) +#define SI_CS_START_LSB (sc->targetdef->d_SI_CS_START_LSB) +#define SI_CS_START_MASK (sc->targetdef->d_SI_CS_START_MASK) +#define SI_CS_RX_CNT_LSB (sc->targetdef->d_SI_CS_RX_CNT_LSB) +#define SI_CS_RX_CNT_MASK (sc->targetdef->d_SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_LSB (sc->targetdef->d_SI_CS_TX_CNT_LSB) +#define SI_CS_TX_CNT_MASK (sc->targetdef->d_SI_CS_TX_CNT_MASK) +#define EEPROM_SZ (sc->targetdef->d_BOARD_DATA_SZ) +#define EEPROM_EXT_SZ (sc->targetdef->d_BOARD_EXT_DATA_SZ) +#define MBOX_BASE_ADDRESS (sc->targetdef->d_MBOX_BASE_ADDRESS) +#define LOCAL_SCRATCH_OFFSET (sc->targetdef->d_LOCAL_SCRATCH_OFFSET) +#define CPU_CLOCK_OFFSET (sc->targetdef->d_CPU_CLOCK_OFFSET) +#define LPO_CAL_OFFSET (sc->targetdef->d_LPO_CAL_OFFSET) +#define GPIO_PIN10_OFFSET (sc->targetdef->d_GPIO_PIN10_OFFSET) +#define GPIO_PIN11_OFFSET (sc->targetdef->d_GPIO_PIN11_OFFSET) +#define GPIO_PIN12_OFFSET (sc->targetdef->d_GPIO_PIN12_OFFSET) +#define GPIO_PIN13_OFFSET (sc->targetdef->d_GPIO_PIN13_OFFSET) +#define CLOCK_GPIO_OFFSET (sc->targetdef->d_CLOCK_GPIO_OFFSET) +#define CPU_CLOCK_STANDARD_LSB (sc->targetdef->d_CPU_CLOCK_STANDARD_LSB) +#define CPU_CLOCK_STANDARD_MASK (sc->targetdef->d_CPU_CLOCK_STANDARD_MASK) +#define LPO_CAL_ENABLE_LSB (sc->targetdef->d_LPO_CAL_ENABLE_LSB) +#define LPO_CAL_ENABLE_MASK (sc->targetdef->d_LPO_CAL_ENABLE_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB) +#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +#define ANALOG_INTF_BASE_ADDRESS (sc->targetdef->d_ANALOG_INTF_BASE_ADDRESS) +#define WLAN_MAC_BASE_ADDRESS (sc->targetdef->d_WLAN_MAC_BASE_ADDRESS) +#define CE0_BASE_ADDRESS (sc->targetdef->d_CE0_BASE_ADDRESS) +#define CE1_BASE_ADDRESS (sc->targetdef->d_CE1_BASE_ADDRESS) +#define FW_INDICATOR_ADDRESS (sc->targetdef->d_FW_INDICATOR_ADDRESS) +#define DRAM_BASE_ADDRESS (sc->targetdef->d_DRAM_BASE_ADDRESS) +#define SOC_CORE_BASE_ADDRESS (sc->targetdef->d_SOC_CORE_BASE_ADDRESS) +#define CORE_CTRL_ADDRESS (sc->targetdef->d_CORE_CTRL_ADDRESS) +#define CE_COUNT (sc->targetdef->d_CE_COUNT) +#define PCIE_INTR_ENABLE_ADDRESS (sc->targetdef->d_PCIE_INTR_ENABLE_ADDRESS) +#define PCIE_INTR_CLR_ADDRESS (sc->targetdef->d_PCIE_INTR_CLR_ADDRESS) +#define PCIE_INTR_FIRMWARE_MASK (sc->targetdef->d_PCIE_INTR_FIRMWARE_MASK) +#define PCIE_INTR_CE_MASK_ALL (sc->targetdef->d_PCIE_INTR_CE_MASK_ALL) +#define CORE_CTRL_CPU_INTR_MASK (sc->targetdef->d_CORE_CTRL_CPU_INTR_MASK) +#define PCIE_INTR_CAUSE_ADDRESS (sc->targetdef->d_PCIE_INTR_CAUSE_ADDRESS) +#define SOC_RESET_CONTROL_ADDRESS (sc->targetdef->d_SOC_RESET_CONTROL_ADDRESS) +#define SOC_RESET_CONTROL_CE_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CE_RST_MASK) +#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK) +#define CPU_INTR_ADDRESS (sc->targetdef->d_CPU_INTR_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ADDRESS (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB (sc->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK (sc->targetdef ->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) (((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) (((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +/* hif_pci.c */ +#define CHIP_ID_ADDRESS (sc->targetdef->d_SOC_CHIP_ID_ADDRESS) +#define SOC_CHIP_ID_REVISION_MASK (sc->targetdef->d_SOC_CHIP_ID_REVISION_MASK) +#define SOC_CHIP_ID_REVISION_LSB (sc->targetdef->d_SOC_CHIP_ID_REVISION_LSB) +#define SOC_CHIP_ID_VERSION_MASK (sc->targetdef->d_SOC_CHIP_ID_VERSION_MASK) +#define SOC_CHIP_ID_VERSION_LSB (sc->targetdef->d_SOC_CHIP_ID_VERSION_LSB) +#define CHIP_ID_REVISION_GET(x) (((x) & SOC_CHIP_ID_REVISION_MASK) >> SOC_CHIP_ID_REVISION_LSB) +#define CHIP_ID_VERSION_GET(x) (((x) & SOC_CHIP_ID_VERSION_MASK) >> SOC_CHIP_ID_VERSION_LSB) +/* hif_pci.c end */ + +/* misc */ +#define SR_WR_INDEX_ADDRESS (sc->targetdef->d_SR_WR_INDEX_ADDRESS) +#define DST_WATERMARK_ADDRESS (sc->targetdef->d_DST_WATERMARK_ADDRESS) +#define SOC_POWER_REG_OFFSET (sc->targetdef->d_SOC_POWER_REG_OFFSET) +/* end */ + +/* htt_rx.c */ +#define RX_MSDU_END_4_FIRST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_MASK) +#define RX_MSDU_END_4_FIRST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_LSB) +#define RX_MPDU_START_0_SEQ_NUM_MASK (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_MASK) +#define RX_MPDU_START_0_SEQ_NUM_LSB (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_LSB) +#define RX_MPDU_START_2_PN_47_32_LSB (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_LSB) +#define RX_MPDU_START_2_PN_47_32_MASK (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_MASK (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_LSB (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_LSB) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB) +#define RX_MSDU_END_4_LAST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_MASK) +#define RX_MSDU_END_4_LAST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_LSB) +#define RX_ATTENTION_0_MCAST_BCAST_MASK (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_MASK) +#define RX_ATTENTION_0_MCAST_BCAST_LSB (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_LSB) +#define RX_ATTENTION_0_FRAGMENT_MASK (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_MASK) +#define RX_ATTENTION_0_FRAGMENT_LSB (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_LSB) +#define RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK (pdev->targetdef->d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB) +#define RX_MSDU_START_0_MSDU_LENGTH_MASK (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_MASK) +#define RX_MSDU_START_0_MSDU_LENGTH_LSB (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_LSB) +#define RX_MSDU_START_2_DECAP_FORMAT_OFFSET (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET) +#define RX_MSDU_START_2_DECAP_FORMAT_MASK (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_MASK) +#define RX_MSDU_START_2_DECAP_FORMAT_LSB (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_LSB) +#define RX_MPDU_START_0_ENCRYPTED_MASK (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_MASK) +#define RX_MPDU_START_0_ENCRYPTED_LSB (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_LSB) +#define RX_ATTENTION_0_MORE_DATA_MASK (pdev->targetdef->d_RX_ATTENTION_0_MORE_DATA_MASK) +#define RX_ATTENTION_0_MSDU_DONE_MASK (pdev->targetdef->d_RX_ATTENTION_0_MSDU_DONE_MASK) +#define RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK (pdev->targetdef->d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK) +/* end */ + +/* copy_engine.c */ +#define DST_WR_INDEX_ADDRESS (sc->targetdef->d_DST_WR_INDEX_ADDRESS) +#define SRC_WATERMARK_ADDRESS (sc->targetdef->d_SRC_WATERMARK_ADDRESS) +#define SRC_WATERMARK_LOW_MASK (sc->targetdef->d_SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_MASK (sc->targetdef->d_SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_MASK (sc->targetdef->d_DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_MASK (sc->targetdef->d_DST_WATERMARK_HIGH_MASK) +#define CURRENT_SRRI_ADDRESS (sc->targetdef->d_CURRENT_SRRI_ADDRESS) +#define CURRENT_DRRI_ADDRESS (sc->targetdef->d_CURRENT_DRRI_ADDRESS) +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK) +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_LOW_WATERMARK_MASK) +#define HOST_IS_ADDRESS (sc->targetdef->d_HOST_IS_ADDRESS) +#define HOST_IS_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IS_COPY_COMPLETE_MASK) +#define CE_WRAPPER_BASE_ADDRESS (sc->targetdef->d_CE_WRAPPER_BASE_ADDRESS) +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS) +#define HOST_IE_ADDRESS (sc->targetdef->d_HOST_IE_ADDRESS) +#define HOST_IE_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IE_COPY_COMPLETE_MASK) +#define SR_BA_ADDRESS (sc->targetdef->d_SR_BA_ADDRESS) +#define SR_SIZE_ADDRESS (sc->targetdef->d_SR_SIZE_ADDRESS) +#define CE_CTRL1_ADDRESS (sc->targetdef->d_CE_CTRL1_ADDRESS) +#define CE_CTRL1_DMAX_LENGTH_MASK (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_MASK) +#define DR_BA_ADDRESS (sc->targetdef->d_DR_BA_ADDRESS) +#define DR_SIZE_ADDRESS (sc->targetdef->d_DR_SIZE_ADDRESS) +#define MISC_IE_ADDRESS (sc->targetdef->d_MISC_IE_ADDRESS) +#define MISC_IS_AXI_ERR_MASK (sc->targetdef->d_MISC_IS_AXI_ERR_MASK) +#define MISC_IS_DST_ADDR_ERR_MASK (sc->targetdef->d_MISC_IS_DST_ADDR_ERR_MASK) +#define MISC_IS_SRC_LEN_ERR_MASK (sc->targetdef->d_MISC_IS_SRC_LEN_ERR_MASK) +#define MISC_IS_DST_MAX_LEN_VIO_MASK (sc->targetdef->d_MISC_IS_DST_MAX_LEN_VIO_MASK) +#define MISC_IS_DST_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_DST_RING_OVERFLOW_MASK) +#define MISC_IS_SRC_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_SRC_RING_OVERFLOW_MASK) +#define SRC_WATERMARK_LOW_LSB (sc->targetdef->d_SRC_WATERMARK_LOW_LSB) +#define SRC_WATERMARK_HIGH_LSB (sc->targetdef->d_SRC_WATERMARK_HIGH_LSB) +#define DST_WATERMARK_LOW_LSB (sc->targetdef->d_DST_WATERMARK_LOW_LSB) +#define DST_WATERMARK_HIGH_LSB (sc->targetdef->d_DST_WATERMARK_HIGH_LSB) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_LSB (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_LSB) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) +#define WLAN_DEBUG_INPUT_SEL_OFFSET (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_OFFSET) +#define WLAN_DEBUG_INPUT_SEL_SRC_MSB (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_LSB (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_LSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_MASK (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MASK) +#define WLAN_DEBUG_CONTROL_OFFSET (sc->targetdef->d_WLAN_DEBUG_CONTROL_OFFSET) +#define WLAN_DEBUG_CONTROL_ENABLE_MSB (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MSB) +#define WLAN_DEBUG_CONTROL_ENABLE_LSB (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_LSB) +#define WLAN_DEBUG_CONTROL_ENABLE_MASK (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MASK) +#define WLAN_DEBUG_OUT_OFFSET (sc->targetdef->d_WLAN_DEBUG_OUT_OFFSET) +#define WLAN_DEBUG_OUT_DATA_MSB (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_MSB) +#define WLAN_DEBUG_OUT_DATA_LSB (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_LSB) +#define WLAN_DEBUG_OUT_DATA_MASK (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_MASK) +#define AMBA_DEBUG_BUS_OFFSET (sc->targetdef->d_AMBA_DEBUG_BUS_OFFSET) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) +#define AMBA_DEBUG_BUS_SEL_MSB (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_MSB) +#define AMBA_DEBUG_BUS_SEL_LSB (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_LSB) +#define AMBA_DEBUG_BUS_SEL_MASK (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_MASK) +#define CE_WRAPPER_DEBUG_OFFSET (sc->targetdef->d_CE_WRAPPER_DEBUG_OFFSET) +#define CE_WRAPPER_DEBUG_SEL_MSB (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_MSB) +#define CE_WRAPPER_DEBUG_SEL_LSB (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_LSB) +#define CE_WRAPPER_DEBUG_SEL_MASK (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_MASK) +#define CE_DEBUG_OFFSET (sc->targetdef->d_CE_DEBUG_OFFSET) +#define CE_DEBUG_SEL_MSB (sc->targetdef->d_CE_DEBUG_SEL_MSB) +#define CE_DEBUG_SEL_LSB (sc->targetdef->d_CE_DEBUG_SEL_LSB) +#define CE_DEBUG_SEL_MASK (sc->targetdef->d_CE_DEBUG_SEL_MASK) +/* end */ +/* PLL start */ +#define EFUSE_OFFSET (sc->targetdef->d_EFUSE_OFFSET) +#define EFUSE_XTAL_SEL_MSB (sc->targetdef->d_EFUSE_XTAL_SEL_MSB) +#define EFUSE_XTAL_SEL_LSB (sc->targetdef->d_EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_MASK (sc->targetdef->d_EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OFFSET (sc->targetdef->d_BB_PLL_CONFIG_OFFSET) +#define BB_PLL_CONFIG_OUTDIV_MSB (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_MSB) +#define BB_PLL_CONFIG_OUTDIV_LSB (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_MASK (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_MSB (sc->targetdef->d_BB_PLL_CONFIG_FRAC_MSB) +#define BB_PLL_CONFIG_FRAC_LSB (sc->targetdef->d_BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_MASK (sc->targetdef->d_BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_MSB (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_MSB) +#define WLAN_PLL_SETTLE_TIME_LSB (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_MASK (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_SETTLE_OFFSET (sc->targetdef->d_WLAN_PLL_SETTLE_OFFSET) +#define WLAN_PLL_SETTLE_SW_MASK (sc->targetdef->d_WLAN_PLL_SETTLE_SW_MASK) +#define WLAN_PLL_SETTLE_RSTMASK (sc->targetdef->d_WLAN_PLL_SETTLE_RSTMASK) +#define WLAN_PLL_SETTLE_RESET (sc->targetdef->d_WLAN_PLL_SETTLE_RESET) +#define WLAN_PLL_CONTROL_NOPWD_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MSB) +#define WLAN_PLL_CONTROL_NOPWD_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MSB) +#define WLAN_PLL_CONTROL_BYPASS_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_BYPASS_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_RESET) +#define WLAN_PLL_CONTROL_CLK_SEL_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MSB) +#define WLAN_PLL_CONTROL_CLK_SEL_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_RESET) +#define WLAN_PLL_CONTROL_REFDIV_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MSB) +#define WLAN_PLL_CONTROL_REFDIV_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_REFDIV_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_RESET) +#define WLAN_PLL_CONTROL_DIV_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_MSB) +#define WLAN_PLL_CONTROL_DIV_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_MASK) +#define WLAN_PLL_CONTROL_DIV_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_RESET) +#define WLAN_PLL_CONTROL_OFFSET (sc->targetdef->d_WLAN_PLL_CONTROL_OFFSET) +#define WLAN_PLL_CONTROL_SW_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_SW_MASK) +#define WLAN_PLL_CONTROL_RSTMASK (sc->targetdef->d_WLAN_PLL_CONTROL_RSTMASK) +#define WLAN_PLL_CONTROL_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_RESET) +#define SOC_CORE_CLK_CTRL_OFFSET (sc->targetdef->d_SOC_CORE_CLK_CTRL_OFFSET) +#define SOC_CORE_CLK_CTRL_DIV_MSB (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MSB) +#define SOC_CORE_CLK_CTRL_DIV_LSB (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_MASK (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_MSB (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_LSB (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_MASK (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_RESET (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_RESET) +#define RTC_SYNC_STATUS_OFFSET (sc->targetdef->d_RTC_SYNC_STATUS_OFFSET) +#define SOC_CPU_CLOCK_OFFSET (sc->targetdef->d_SOC_CPU_CLOCK_OFFSET) +#define SOC_CPU_CLOCK_STANDARD_MSB (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_MSB) +#define SOC_CPU_CLOCK_STANDARD_LSB (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_MASK (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ + +/* SET macros */ +#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK) +#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK) +#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK) +#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK) +#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +/* copy_engine.c */ +#define SRC_WATERMARK_LOW_SET(x) (((x) << SRC_WATERMARK_LOW_LSB) & SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_SET(x) (((x) << SRC_WATERMARK_HIGH_LSB) & SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_SET(x) (((x) << DST_WATERMARK_LOW_LSB) & DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_SET(x) (((x) << DST_WATERMARK_HIGH_LSB) & DST_WATERMARK_HIGH_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) (((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_SET(x) (((x) << CE_CTRL1_DMAX_LENGTH_LSB) & CE_CTRL1_DMAX_LENGTH_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +#define WLAN_DEBUG_INPUT_SEL_SRC_GET(x) (((x) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) >> WLAN_DEBUG_INPUT_SEL_SRC_LSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_SET(x) (((x) << WLAN_DEBUG_INPUT_SEL_SRC_LSB) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) +#define WLAN_DEBUG_CONTROL_ENABLE_GET(x) (((x) & WLAN_DEBUG_CONTROL_ENABLE_MASK) >> WLAN_DEBUG_CONTROL_ENABLE_LSB) +#define WLAN_DEBUG_CONTROL_ENABLE_SET(x) (((x) << WLAN_DEBUG_CONTROL_ENABLE_LSB) & WLAN_DEBUG_CONTROL_ENABLE_MASK) +#define WLAN_DEBUG_OUT_DATA_GET(x) (((x) & WLAN_DEBUG_OUT_DATA_MASK) >> WLAN_DEBUG_OUT_DATA_LSB) +#define WLAN_DEBUG_OUT_DATA_SET(x) (((x) << WLAN_DEBUG_OUT_DATA_LSB) & WLAN_DEBUG_OUT_DATA_MASK) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_GET(x) (((x) & AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) >> AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_SET(x) (((x) << AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) & AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) +#define AMBA_DEBUG_BUS_SEL_GET(x) (((x) & AMBA_DEBUG_BUS_SEL_MASK) >> AMBA_DEBUG_BUS_SEL_LSB) +#define AMBA_DEBUG_BUS_SEL_SET(x) (((x) << AMBA_DEBUG_BUS_SEL_LSB) & AMBA_DEBUG_BUS_SEL_MASK) +#define CE_WRAPPER_DEBUG_SEL_GET(x) (((x) & CE_WRAPPER_DEBUG_SEL_MASK) >> CE_WRAPPER_DEBUG_SEL_LSB) +#define CE_WRAPPER_DEBUG_SEL_SET(x) (((x) << CE_WRAPPER_DEBUG_SEL_LSB) & CE_WRAPPER_DEBUG_SEL_MASK) +#define CE_DEBUG_SEL_GET(x) (((x) & CE_DEBUG_SEL_MASK) >> CE_DEBUG_SEL_LSB) +#define CE_DEBUG_SEL_SET(x) (((x) << CE_DEBUG_SEL_LSB) & CE_DEBUG_SEL_MASK) +/* end */ +/* PLL start */ +#define EFUSE_XTAL_SEL_GET(x) (((x) & EFUSE_XTAL_SEL_MASK) >> EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_SET(x) (((x) << EFUSE_XTAL_SEL_LSB) & EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OUTDIV_GET(x) (((x) & BB_PLL_CONFIG_OUTDIV_MASK) >> BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_SET(x) (((x) << BB_PLL_CONFIG_OUTDIV_LSB) & BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_GET(x) (((x) & BB_PLL_CONFIG_FRAC_MASK) >> BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_SET(x) (((x) << BB_PLL_CONFIG_FRAC_LSB) & BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_GET(x) (((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_SET(x) (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_CONTROL_NOPWD_GET(x) (((x) & WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_SET(x) (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_GET(x) (((x) & WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_SET(x) (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_GET(x) (((x) & WLAN_PLL_CONTROL_CLK_SEL_MASK) >> WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_SET(x) (((x) << WLAN_PLL_CONTROL_CLK_SEL_LSB) & WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_REFDIV_GET(x) (((x) & WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_SET(x) (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_DIV_GET(x) (((x) & WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_SET(x) (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK) +#define SOC_CORE_CLK_CTRL_DIV_GET(x) (((x) & SOC_CORE_CLK_CTRL_DIV_MASK) >> SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_SET(x) (((x) << SOC_CORE_CLK_CTRL_DIV_LSB) & SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_GET(x) (((x) & RTC_SYNC_STATUS_PLL_CHANGING_MASK) >> RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_SET(x) (((x) << RTC_SYNC_STATUS_PLL_CHANGING_LSB) & RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define SOC_CPU_CLOCK_STANDARD_GET(x) (((x) & SOC_CPU_CLOCK_STANDARD_MASK) >> SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_SET(x) (((x) << SOC_CPU_CLOCK_STANDARD_LSB) & SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ + +typedef struct hostdef_s { + A_UINT32 d_INT_STATUS_ENABLE_ERROR_LSB; + A_UINT32 d_INT_STATUS_ENABLE_ERROR_MASK; + A_UINT32 d_INT_STATUS_ENABLE_CPU_LSB; + A_UINT32 d_INT_STATUS_ENABLE_CPU_MASK; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_LSB; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_MASK; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_LSB; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_INT_STATUS_ENABLE_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_HOST_INT_STATUS_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_MASK; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_LSB; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_LSB; + A_UINT32 d_COUNT_DEC_ADDRESS; + A_UINT32 d_HOST_INT_STATUS_CPU_MASK; + A_UINT32 d_HOST_INT_STATUS_CPU_LSB; + A_UINT32 d_HOST_INT_STATUS_ERROR_MASK; + A_UINT32 d_HOST_INT_STATUS_ERROR_LSB; + A_UINT32 d_HOST_INT_STATUS_COUNTER_MASK; + A_UINT32 d_HOST_INT_STATUS_COUNTER_LSB; + A_UINT32 d_RX_LOOKAHEAD_VALID_ADDRESS; + A_UINT32 d_WINDOW_DATA_ADDRESS; + A_UINT32 d_WINDOW_READ_ADDR_ADDRESS; + A_UINT32 d_WINDOW_WRITE_ADDR_ADDRESS; + A_UINT32 d_SOC_GLOBAL_RESET_ADDRESS; + A_UINT32 d_RTC_STATE_ADDRESS; + A_UINT32 d_RTC_STATE_COLD_RESET_MASK; + A_UINT32 d_PCIE_LOCAL_BASE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_RESET; + A_UINT32 d_PCIE_SOC_WAKE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_V_MASK; + A_UINT32 d_RTC_STATE_V_MASK; + A_UINT32 d_RTC_STATE_V_LSB; + A_UINT32 d_FW_IND_EVENT_PENDING; + A_UINT32 d_FW_IND_INITIALIZED; + A_UINT32 d_FW_IND_HELPER; + A_UINT32 d_RTC_STATE_V_ON; +#if defined(SDIO_3_0) + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_MASK; + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_LSB; +#endif + A_UINT32 d_PCIE_SOC_RDY_STATUS_ADDRESS; + A_UINT32 d_PCIE_SOC_RDY_STATUS_BAR_MASK; + A_UINT32 d_SOC_PCIE_BASE_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADR_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADDRESS; +} HOST_REGISTER_TABLE; + +#define INT_STATUS_ENABLE_ERROR_LSB (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_LSB) +#define INT_STATUS_ENABLE_ERROR_MASK (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_LSB (sc->hostdef->d_INT_STATUS_ENABLE_CPU_LSB) +#define INT_STATUS_ENABLE_CPU_MASK (sc->hostdef->d_INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_LSB (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB) +#define INT_STATUS_ENABLE_COUNTER_MASK (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_LSB (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB) +#define INT_STATUS_ENABLE_MBOX_DATA_MASK (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB) +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define INT_STATUS_ENABLE_ADDRESS (sc->hostdef->d_INT_STATUS_ENABLE_ADDRESS) +#define CPU_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB) +#define CPU_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK) +#define HOST_INT_STATUS_ADDRESS (sc->hostdef->d_HOST_INT_STATUS_ADDRESS) +#define CPU_INT_STATUS_ADDRESS (sc->hostdef->d_CPU_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_ADDRESS (sc->hostdef->d_ERROR_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_WAKEUP_MASK (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK) +#define ERROR_INT_STATUS_WAKEUP_LSB (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK) +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK) +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define COUNT_DEC_ADDRESS (sc->hostdef->d_COUNT_DEC_ADDRESS) +#define HOST_INT_STATUS_CPU_MASK (sc->hostdef->d_HOST_INT_STATUS_CPU_MASK) +#define HOST_INT_STATUS_CPU_LSB (sc->hostdef->d_HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_MASK (sc->hostdef->d_HOST_INT_STATUS_ERROR_MASK) +#define HOST_INT_STATUS_ERROR_LSB (sc->hostdef->d_HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_MASK (sc->hostdef->d_HOST_INT_STATUS_COUNTER_MASK) +#define HOST_INT_STATUS_COUNTER_LSB (sc->hostdef->d_HOST_INT_STATUS_COUNTER_LSB) +#define RX_LOOKAHEAD_VALID_ADDRESS (sc->hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS) +#define WINDOW_DATA_ADDRESS (sc->hostdef->d_WINDOW_DATA_ADDRESS) +#define WINDOW_READ_ADDR_ADDRESS (sc->hostdef->d_WINDOW_READ_ADDR_ADDRESS) +#define WINDOW_WRITE_ADDR_ADDRESS (sc->hostdef->d_WINDOW_WRITE_ADDR_ADDRESS) +#define SOC_GLOBAL_RESET_ADDRESS (sc->hostdef->d_SOC_GLOBAL_RESET_ADDRESS) +#define RTC_STATE_ADDRESS (sc->hostdef->d_RTC_STATE_ADDRESS) +#define RTC_STATE_COLD_RESET_MASK (sc->hostdef->d_RTC_STATE_COLD_RESET_MASK) +#define PCIE_LOCAL_BASE_ADDRESS (sc->hostdef->d_PCIE_LOCAL_BASE_ADDRESS) +#define PCIE_SOC_WAKE_RESET (sc->hostdef->d_PCIE_SOC_WAKE_RESET) +#define PCIE_SOC_WAKE_ADDRESS (sc->hostdef->d_PCIE_SOC_WAKE_ADDRESS) +#define PCIE_SOC_WAKE_V_MASK (sc->hostdef->d_PCIE_SOC_WAKE_V_MASK) +#define RTC_STATE_V_MASK (sc->hostdef->d_RTC_STATE_V_MASK) +#define RTC_STATE_V_LSB (sc->hostdef->d_RTC_STATE_V_LSB) +#define FW_IND_EVENT_PENDING (sc->hostdef->d_FW_IND_EVENT_PENDING) +#define FW_IND_INITIALIZED (sc->hostdef->d_FW_IND_INITIALIZED) +#define FW_IND_HELPER (sc->hostdef->d_FW_IND_HELPER) +#define RTC_STATE_V_ON (sc->hostdef->d_RTC_STATE_V_ON) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_MASK (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_MASK) +#define HOST_INT_STATUS_MBOX_DATA_LSB (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#if !defined(SOC_PCIE_BASE_ADDRESS) +#define SOC_PCIE_BASE_ADDRESS 0 +#endif + +#if !defined(PCIE_SOC_RDY_STATUS_ADDRESS) +#define PCIE_SOC_RDY_STATUS_ADDRESS 0 +#define PCIE_SOC_RDY_STATUS_BAR_MASK 0 +#endif + +#if !defined(MSI_MAGIC_ADR_ADDRESS) +#define MSI_MAGIC_ADR_ADDRESS 0 +#define MSI_MAGIC_ADDRESS 0 +#endif + + +/* SET/GET macros */ +#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) +#define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#define INVALID_REG_LOC_DUMMY_DATA 0xAA + + +#define AR6320_CORE_CLK_DIV_ADDR 0x403fa8 +#define AR6320_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320_CPU_SPEED_ADDR 0x403fa4 +#define AR6320V2_CORE_CLK_DIV_ADDR 0x403fd8 +#define AR6320V2_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320V2_CPU_SPEED_ADDR 0x403fd4 +#define AR6320V3_CORE_CLK_DIV_ADDR 0x404028 +#define AR6320V3_CPU_PLL_INIT_DONE_ADDR 0x404020 +#define AR6320V3_CPU_SPEED_ADDR 0x404024 + +typedef enum { + SOC_REFCLK_UNKNOWN = -1, /* Unsupported ref clock -- use PLL Bypass */ + SOC_REFCLK_48_MHZ = 0, + SOC_REFCLK_19_2_MHZ = 1, + SOC_REFCLK_24_MHZ = 2, + SOC_REFCLK_26_MHZ = 3, + SOC_REFCLK_37_4_MHZ = 4, + SOC_REFCLK_38_4_MHZ = 5, + SOC_REFCLK_40_MHZ = 6, + SOC_REFCLK_52_MHZ = 7, +} A_refclk_speed_t; + +#define A_REFCLK_UNKNOWN SOC_REFCLK_UNKNOWN +#define A_REFCLK_48_MHZ SOC_REFCLK_48_MHZ +#define A_REFCLK_19_2_MHZ SOC_REFCLK_19_2_MHZ +#define A_REFCLK_24_MHZ SOC_REFCLK_24_MHZ +#define A_REFCLK_26_MHZ SOC_REFCLK_26_MHZ +#define A_REFCLK_37_4_MHZ SOC_REFCLK_37_4_MHZ +#define A_REFCLK_38_4_MHZ SOC_REFCLK_38_4_MHZ +#define A_REFCLK_40_MHZ SOC_REFCLK_40_MHZ +#define A_REFCLK_52_MHZ SOC_REFCLK_52_MHZ + +#define TARGET_CPU_FREQ 176000000 + +struct wlan_pll_s { + u_int32_t refdiv; + u_int32_t div; + u_int32_t rnfrac; + u_int32_t outdiv; +}; + +struct cmnos_clock_s { + A_refclk_speed_t refclk_speed; + u_int32_t refclk_hz; + u_int32_t pll_settling_time; /* 50us */ + struct wlan_pll_s wlan_pll; +}; + +typedef struct TGT_REG_SECTION { + u_int32_t start_addr; + u_int32_t end_addr; +} tgt_reg_section; + +typedef struct TGT_REG_TABLE { + tgt_reg_section *section; + u_int32_t section_size; +} tgt_reg_table; + +void target_register_tbl_attach(struct hif_pci_softc *sc, u32 target_type); +void hif_register_tbl_attach(struct hif_pci_softc *sc, u32 hif_type); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320def.h new file mode 100644 index 0000000000000..13518d9aac07f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320def.h @@ -0,0 +1,690 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320DEF_H_ +#define _AR6320DEF_H_ + +/* Base Addresses */ +#define AR6320_RTC_SOC_BASE_ADDRESS 0x00000000 +#define AR6320_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320_CE0_BASE_ADDRESS 0x00034400 +#define AR6320_CE1_BASE_ADDRESS 0x00034800 +#define AR6320_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320_CE3_BASE_ADDRESS 0x00035000 +#define AR6320_CE4_BASE_ADDRESS 0x00035400 +#define AR6320_CE5_BASE_ADDRESS 0x00035800 +#define AR6320_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320_CE7_BASE_ADDRESS 0x00036000 +#define AR6320_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320_SCRATCH_3_ADDRESS 0x0028 +#define AR6320_TARG_DRAM_START 0x00400000 +#define AR6320_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320_SI_CONFIG_I2C_LSB 16 +#define AR6320_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320_SI_CONFIG_OFFSET 0x00000000 +#define AR6320_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320_SI_CS_OFFSET 0x00000004 +#define AR6320_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320_SI_CS_START_LSB 8 +#define AR6320_SI_CS_START_MASK 0x00000100 +#define AR6320_SI_CS_RX_CNT_LSB 4 +#define AR6320_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320_SI_CS_TX_CNT_LSB 0 +#define AR6320_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320_CE_COUNT 8 +#define AR6320_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320_HOST_IS_ADDRESS 0x0030 +#define AR6320_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320_HOST_IE_ADDRESS 0x002c +#define AR6320_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_SR_BA_ADDRESS 0x0000 +#define AR6320_SR_SIZE_ADDRESS 0x0004 +#define AR6320_CE_CTRL1_ADDRESS 0x0010 +#define AR6320_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320_DR_BA_ADDRESS 0x0008 +#define AR6320_DR_SIZE_ADDRESS 0x000c +#define AR6320_MISC_IE_ADDRESS 0x0034 +#define AR6320_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320_SRC_WATERMARK_LOW_LSB 16 +#define AR6320_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320_DST_WATERMARK_LOW_LSB 16 +#define AR6320_DST_WATERMARK_HIGH_LSB 0 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320_RTC_STATE_ADDRESS 0x0000 +#define AR6320_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320_RTC_STATE_V_MASK 0x00000007 +#define AR6320_RTC_STATE_V_LSB 0 +#define AR6320_RTC_STATE_V_ON 3 +#define AR6320_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320_FW_IND_EVENT_PENDING 1 +#define AR6320_FW_IND_INITIALIZED 2 +#define AR6320_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320_CPU_INTR_ADDRESS 0x0010 +#define AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320_CORE_CTRL_ADDRESS 0x0000 +#define AR6320_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320_SOC_CHIP_ID_REVISION_LSB 8 +#define AR6320_SOC_POWER_REG_OFFSET 0x0000010c + +/* Copy Engine Debug */ +#define AR6320_WLAN_DEBUG_INPUT_SEL_OFFSET 0x0000010c +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MSB 3 +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_LSB 0 +#define AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MASK 0x0000000f +#define AR6320_WLAN_DEBUG_CONTROL_OFFSET 0x00000108 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_MSB 0 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_LSB 0 +#define AR6320_WLAN_DEBUG_CONTROL_ENABLE_MASK 0x00000001 +#define AR6320_WLAN_DEBUG_OUT_OFFSET 0x00000110 +#define AR6320_WLAN_DEBUG_OUT_DATA_MSB 19 +#define AR6320_WLAN_DEBUG_OUT_DATA_LSB 0 +#define AR6320_WLAN_DEBUG_OUT_DATA_MASK 0x000fffff +#define AR6320_AMBA_DEBUG_BUS_OFFSET 0x0000011c +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB 13 +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB 8 +#define AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK 0x00003f00 +#define AR6320_AMBA_DEBUG_BUS_SEL_MSB 4 +#define AR6320_AMBA_DEBUG_BUS_SEL_LSB 0 +#define AR6320_AMBA_DEBUG_BUS_SEL_MASK 0x0000001f +#define AR6320_CE_WRAPPER_DEBUG_OFFSET 0x0008 +#define AR6320_CE_WRAPPER_DEBUG_SEL_MSB 5 +#define AR6320_CE_WRAPPER_DEBUG_SEL_LSB 0 +#define AR6320_CE_WRAPPER_DEBUG_SEL_MASK 0x0000003f +#define AR6320_CE_DEBUG_OFFSET 0x0054 +#define AR6320_CE_DEBUG_SEL_MSB 5 +#define AR6320_CE_DEBUG_SEL_LSB 0 +#define AR6320_CE_DEBUG_SEL_MASK 0x0000003f +/* End */ + +/* PLL start */ +#define AR6320_EFUSE_OFFSET 0x0000032c +#define AR6320_EFUSE_XTAL_SEL_MSB 10 +#define AR6320_EFUSE_XTAL_SEL_LSB 8 +#define AR6320_EFUSE_XTAL_SEL_MASK 0x00000700 +#define AR6320_BB_PLL_CONFIG_OFFSET 0x000002f4 +#define AR6320_BB_PLL_CONFIG_OUTDIV_MSB 20 +#define AR6320_BB_PLL_CONFIG_OUTDIV_LSB 18 +#define AR6320_BB_PLL_CONFIG_OUTDIV_MASK 0x001c0000 +#define AR6320_BB_PLL_CONFIG_FRAC_MSB 17 +#define AR6320_BB_PLL_CONFIG_FRAC_LSB 0 +#define AR6320_BB_PLL_CONFIG_FRAC_MASK 0x0003ffff +#define AR6320_WLAN_PLL_SETTLE_TIME_MSB 10 +#define AR6320_WLAN_PLL_SETTLE_TIME_LSB 0 +#define AR6320_WLAN_PLL_SETTLE_TIME_MASK 0x000007ff +#define AR6320_WLAN_PLL_SETTLE_OFFSET 0x0018 +#define AR6320_WLAN_PLL_SETTLE_SW_MASK 0x000007ff +#define AR6320_WLAN_PLL_SETTLE_RSTMASK 0xffffffff +#define AR6320_WLAN_PLL_SETTLE_RESET 0x00000400 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_MSB 18 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_LSB 18 +#define AR6320_WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_MSB 16 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_LSB 16 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000 +#define AR6320_WLAN_PLL_CONTROL_BYPASS_RESET 0x1 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_MSB 15 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_LSB 14 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_MASK 0x0000c000 +#define AR6320_WLAN_PLL_CONTROL_CLK_SEL_RESET 0x0 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_MSB 13 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_LSB 10 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_MASK 0x00003c00 +#define AR6320_WLAN_PLL_CONTROL_REFDIV_RESET 0x0 +#define AR6320_WLAN_PLL_CONTROL_DIV_MSB 9 +#define AR6320_WLAN_PLL_CONTROL_DIV_LSB 0 +#define AR6320_WLAN_PLL_CONTROL_DIV_MASK 0x000003ff +#define AR6320_WLAN_PLL_CONTROL_DIV_RESET 0x11 +#define AR6320_WLAN_PLL_CONTROL_OFFSET 0x0014 +#define AR6320_WLAN_PLL_CONTROL_SW_MASK 0x001fffff +#define AR6320_WLAN_PLL_CONTROL_RSTMASK 0xffffffff +#define AR6320_WLAN_PLL_CONTROL_RESET 0x00010011 +#define AR6320_SOC_CORE_CLK_CTRL_OFFSET 0x00000114 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_MSB 2 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_LSB 0 +#define AR6320_SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MSB 5 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_LSB 5 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MASK 0x00000020 +#define AR6320_RTC_SYNC_STATUS_PLL_CHANGING_RESET 0x0 +#define AR6320_RTC_SYNC_STATUS_OFFSET 0x0244 +#define AR6320_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MSB 1 +#define AR6320_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +/* PLL end */ + +#define AR6320_PCIE_INTR_CE_MASK(n) (AR6320_PCIE_INTR_CE0_MASK << (n)) +#define AR6320_DRAM_BASE_ADDRESS AR6320_TARG_DRAM_START +#define AR6320_FW_INDICATOR_ADDRESS (AR6320_SOC_CORE_BASE_ADDRESS + AR6320_SCRATCH_3_ADDRESS) +#define AR6320_SYSTEM_SLEEP_OFFSET AR6320_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320_WLAN_RESET_CONTROL_OFFSET AR6320_SOC_RESET_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_OFFSET AR6320_SOC_CLOCK_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_SI0_CLK_MASK AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320_RESET_CONTROL_SI0_RST_MASK AR6320_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320_GPIO_BASE_ADDRESS AR6320_WLAN_GPIO_BASE_ADDRESS +#define AR6320_GPIO_PIN0_OFFSET AR6320_WLAN_GPIO_PIN0_ADDRESS +#define AR6320_GPIO_PIN1_OFFSET AR6320_WLAN_GPIO_PIN1_ADDRESS +#define AR6320_GPIO_PIN0_CONFIG_MASK AR6320_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320_GPIO_PIN1_CONFIG_MASK AR6320_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320_SI_BASE_ADDRESS 0x00050000 +#define AR6320_CPU_CLOCK_OFFSET AR6320_SOC_CPU_CLOCK_OFFSET +#define AR6320_LPO_CAL_OFFSET AR6320_SOC_LPO_CAL_OFFSET +#define AR6320_GPIO_PIN10_OFFSET AR6320_WLAN_GPIO_PIN10_ADDRESS +#define AR6320_GPIO_PIN11_OFFSET AR6320_WLAN_GPIO_PIN11_ADDRESS +#define AR6320_GPIO_PIN12_OFFSET AR6320_WLAN_GPIO_PIN12_ADDRESS +#define AR6320_GPIO_PIN13_OFFSET AR6320_WLAN_GPIO_PIN13_ADDRESS +#define AR6320_CPU_CLOCK_STANDARD_LSB AR6320_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320_CPU_CLOCK_STANDARD_MASK AR6320_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320_LPO_CAL_ENABLE_LSB AR6320_SOC_LPO_CAL_ENABLE_LSB +#define AR6320_LPO_CAL_ENABLE_MASK AR6320_SOC_LPO_CAL_ENABLE_MASK +#define AR6320_ANALOG_INTF_BASE_ADDRESS AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320_COUNT_DEC_ADDRESS 0x0840 +#define AR6320_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320_WINDOW_WRITE_ADDR_ADDRESS 0x0878 + +struct targetdef_s ar6320_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320_CE_COUNT, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + .d_WLAN_DEBUG_INPUT_SEL_OFFSET = AR6320_WLAN_DEBUG_INPUT_SEL_OFFSET, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MSB = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_LSB = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_LSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MASK = AR6320_WLAN_DEBUG_INPUT_SEL_SRC_MASK, + .d_WLAN_DEBUG_CONTROL_OFFSET = AR6320_WLAN_DEBUG_CONTROL_OFFSET, + .d_WLAN_DEBUG_CONTROL_ENABLE_MSB = AR6320_WLAN_DEBUG_CONTROL_ENABLE_MSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_LSB = AR6320_WLAN_DEBUG_CONTROL_ENABLE_LSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_MASK = AR6320_WLAN_DEBUG_CONTROL_ENABLE_MASK, + .d_WLAN_DEBUG_OUT_OFFSET = AR6320_WLAN_DEBUG_OUT_OFFSET, + .d_WLAN_DEBUG_OUT_DATA_MSB = AR6320_WLAN_DEBUG_OUT_DATA_MSB, + .d_WLAN_DEBUG_OUT_DATA_LSB = AR6320_WLAN_DEBUG_OUT_DATA_LSB, + .d_WLAN_DEBUG_OUT_DATA_MASK = AR6320_WLAN_DEBUG_OUT_DATA_MASK, + .d_AMBA_DEBUG_BUS_OFFSET = AR6320_AMBA_DEBUG_BUS_OFFSET, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK = AR6320_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK, + .d_AMBA_DEBUG_BUS_SEL_MSB = AR6320_AMBA_DEBUG_BUS_SEL_MSB, + .d_AMBA_DEBUG_BUS_SEL_LSB = AR6320_AMBA_DEBUG_BUS_SEL_LSB, + .d_AMBA_DEBUG_BUS_SEL_MASK = AR6320_AMBA_DEBUG_BUS_SEL_MASK, + .d_CE_WRAPPER_DEBUG_OFFSET = AR6320_CE_WRAPPER_DEBUG_OFFSET, + .d_CE_WRAPPER_DEBUG_SEL_MSB = AR6320_CE_WRAPPER_DEBUG_SEL_MSB, + .d_CE_WRAPPER_DEBUG_SEL_LSB = AR6320_CE_WRAPPER_DEBUG_SEL_LSB, + .d_CE_WRAPPER_DEBUG_SEL_MASK = AR6320_CE_WRAPPER_DEBUG_SEL_MASK, + .d_CE_DEBUG_OFFSET = AR6320_CE_DEBUG_OFFSET, + .d_CE_DEBUG_SEL_MSB = AR6320_CE_DEBUG_SEL_MSB, + .d_CE_DEBUG_SEL_LSB = AR6320_CE_DEBUG_SEL_LSB, + .d_CE_DEBUG_SEL_MASK = AR6320_CE_DEBUG_SEL_MASK, + /* PLL start */ + .d_EFUSE_OFFSET = AR6320_EFUSE_OFFSET, + .d_EFUSE_XTAL_SEL_MSB = AR6320_EFUSE_XTAL_SEL_MSB, + .d_EFUSE_XTAL_SEL_LSB = AR6320_EFUSE_XTAL_SEL_LSB, + .d_EFUSE_XTAL_SEL_MASK = AR6320_EFUSE_XTAL_SEL_MASK, + .d_BB_PLL_CONFIG_OFFSET = AR6320_BB_PLL_CONFIG_OFFSET, + .d_BB_PLL_CONFIG_OUTDIV_MSB = AR6320_BB_PLL_CONFIG_OUTDIV_MSB, + .d_BB_PLL_CONFIG_OUTDIV_LSB = AR6320_BB_PLL_CONFIG_OUTDIV_LSB, + .d_BB_PLL_CONFIG_OUTDIV_MASK = AR6320_BB_PLL_CONFIG_OUTDIV_MASK, + .d_BB_PLL_CONFIG_FRAC_MSB = AR6320_BB_PLL_CONFIG_FRAC_MSB, + .d_BB_PLL_CONFIG_FRAC_LSB = AR6320_BB_PLL_CONFIG_FRAC_LSB, + .d_BB_PLL_CONFIG_FRAC_MASK = AR6320_BB_PLL_CONFIG_FRAC_MASK, + .d_WLAN_PLL_SETTLE_TIME_MSB = AR6320_WLAN_PLL_SETTLE_TIME_MSB, + .d_WLAN_PLL_SETTLE_TIME_LSB = AR6320_WLAN_PLL_SETTLE_TIME_LSB, + .d_WLAN_PLL_SETTLE_TIME_MASK = AR6320_WLAN_PLL_SETTLE_TIME_MASK, + .d_WLAN_PLL_SETTLE_OFFSET = AR6320_WLAN_PLL_SETTLE_OFFSET, + .d_WLAN_PLL_SETTLE_SW_MASK = AR6320_WLAN_PLL_SETTLE_SW_MASK, + .d_WLAN_PLL_SETTLE_RSTMASK = AR6320_WLAN_PLL_SETTLE_RSTMASK, + .d_WLAN_PLL_SETTLE_RESET = AR6320_WLAN_PLL_SETTLE_RESET, + .d_WLAN_PLL_CONTROL_NOPWD_MSB = AR6320_WLAN_PLL_CONTROL_NOPWD_MSB, + .d_WLAN_PLL_CONTROL_NOPWD_LSB = AR6320_WLAN_PLL_CONTROL_NOPWD_LSB, + .d_WLAN_PLL_CONTROL_NOPWD_MASK = AR6320_WLAN_PLL_CONTROL_NOPWD_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_MSB = AR6320_WLAN_PLL_CONTROL_BYPASS_MSB, + .d_WLAN_PLL_CONTROL_BYPASS_LSB = AR6320_WLAN_PLL_CONTROL_BYPASS_LSB, + .d_WLAN_PLL_CONTROL_BYPASS_MASK = AR6320_WLAN_PLL_CONTROL_BYPASS_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_RESET = AR6320_WLAN_PLL_CONTROL_BYPASS_RESET, + .d_WLAN_PLL_CONTROL_CLK_SEL_MSB = AR6320_WLAN_PLL_CONTROL_CLK_SEL_MSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_LSB = AR6320_WLAN_PLL_CONTROL_CLK_SEL_LSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_MASK = AR6320_WLAN_PLL_CONTROL_CLK_SEL_MASK, + .d_WLAN_PLL_CONTROL_CLK_SEL_RESET = AR6320_WLAN_PLL_CONTROL_CLK_SEL_RESET, + .d_WLAN_PLL_CONTROL_REFDIV_MSB = AR6320_WLAN_PLL_CONTROL_REFDIV_MSB, + .d_WLAN_PLL_CONTROL_REFDIV_LSB = AR6320_WLAN_PLL_CONTROL_REFDIV_LSB, + .d_WLAN_PLL_CONTROL_REFDIV_MASK = AR6320_WLAN_PLL_CONTROL_REFDIV_MASK, + .d_WLAN_PLL_CONTROL_REFDIV_RESET = AR6320_WLAN_PLL_CONTROL_REFDIV_RESET, + .d_WLAN_PLL_CONTROL_DIV_MSB = AR6320_WLAN_PLL_CONTROL_DIV_MSB, + .d_WLAN_PLL_CONTROL_DIV_LSB = AR6320_WLAN_PLL_CONTROL_DIV_LSB, + .d_WLAN_PLL_CONTROL_DIV_MASK = AR6320_WLAN_PLL_CONTROL_DIV_MASK, + .d_WLAN_PLL_CONTROL_DIV_RESET = AR6320_WLAN_PLL_CONTROL_DIV_RESET, + .d_WLAN_PLL_CONTROL_OFFSET = AR6320_WLAN_PLL_CONTROL_OFFSET, + .d_WLAN_PLL_CONTROL_SW_MASK = AR6320_WLAN_PLL_CONTROL_SW_MASK, + .d_WLAN_PLL_CONTROL_RSTMASK = AR6320_WLAN_PLL_CONTROL_RSTMASK, + .d_WLAN_PLL_CONTROL_RESET = AR6320_WLAN_PLL_CONTROL_RESET, + .d_SOC_CORE_CLK_CTRL_OFFSET = AR6320_SOC_CORE_CLK_CTRL_OFFSET, + .d_SOC_CORE_CLK_CTRL_DIV_MSB = AR6320_SOC_CORE_CLK_CTRL_DIV_MSB, + .d_SOC_CORE_CLK_CTRL_DIV_LSB = AR6320_SOC_CORE_CLK_CTRL_DIV_LSB, + .d_SOC_CORE_CLK_CTRL_DIV_MASK = AR6320_SOC_CORE_CLK_CTRL_DIV_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MSB = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_LSB = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_LSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MASK = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_RESET = AR6320_RTC_SYNC_STATUS_PLL_CHANGING_RESET, + .d_RTC_SYNC_STATUS_OFFSET = AR6320_RTC_SYNC_STATUS_OFFSET, + .d_SOC_CPU_CLOCK_OFFSET = AR6320_SOC_CPU_CLOCK_OFFSET, + .d_SOC_CPU_CLOCK_STANDARD_MSB = AR6320_SOC_CPU_CLOCK_STANDARD_MSB, + .d_SOC_CPU_CLOCK_STANDARD_LSB = AR6320_SOC_CPU_CLOCK_STANDARD_LSB, + .d_SOC_CPU_CLOCK_STANDARD_MASK = AR6320_SOC_CPU_CLOCK_STANDARD_MASK, + /* PLL end */ + .d_SOC_POWER_REG_OFFSET = AR6320_SOC_POWER_REG_OFFSET, + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR6320_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320v2def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320v2def.h new file mode 100644 index 0000000000000..b9c1d2fadfd2b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar6320v2def.h @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320V2DEF_H_ +#define _AR6320V2DEF_H_ + +/* Base Addresses */ +#define AR6320V2_RTC_SOC_BASE_ADDRESS 0x00000800 +#define AR6320V2_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320V2_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320V2_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320V2_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320V2_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320V2_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320V2_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320V2_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320V2_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320V2_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320V2_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320V2_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320V2_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320V2_CE0_BASE_ADDRESS 0x00034400 +#define AR6320V2_CE1_BASE_ADDRESS 0x00034800 +#define AR6320V2_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320V2_CE3_BASE_ADDRESS 0x00035000 +#define AR6320V2_CE4_BASE_ADDRESS 0x00035400 +#define AR6320V2_CE5_BASE_ADDRESS 0x00035800 +#define AR6320V2_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320V2_CE7_BASE_ADDRESS 0x00036000 +#define AR6320V2_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320V2_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320V2_SCRATCH_3_ADDRESS 0x0028 +#define AR6320V2_TARG_DRAM_START 0x00400000 +#define AR6320V2_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320V2_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320V2_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320V2_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320V2_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320V2_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320V2_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320V2_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320V2_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320V2_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320V2_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320V2_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320V2_SI_CONFIG_I2C_LSB 16 +#define AR6320V2_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320V2_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320V2_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320V2_SI_CONFIG_OFFSET 0x00000000 +#define AR6320V2_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320V2_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320V2_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320V2_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320V2_SI_CS_OFFSET 0x00000004 +#define AR6320V2_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320V2_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320V2_SI_CS_START_LSB 8 +#define AR6320V2_SI_CS_START_MASK 0x00000100 +#define AR6320V2_SI_CS_RX_CNT_LSB 4 +#define AR6320V2_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320V2_SI_CS_TX_CNT_LSB 0 +#define AR6320V2_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320V2_CE_COUNT 8 +#define AR6320V2_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320V2_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff + +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320V2_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320V2_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320V2_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320V2_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320V2_HOST_IS_ADDRESS 0x0030 +#define AR6320V2_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320V2_HOST_IE_ADDRESS 0x002c +#define AR6320V2_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_SR_BA_ADDRESS 0x0000 +#define AR6320V2_SR_SIZE_ADDRESS 0x0004 +#define AR6320V2_CE_CTRL1_ADDRESS 0x0010 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320V2_DR_BA_ADDRESS 0x0008 +#define AR6320V2_DR_SIZE_ADDRESS 0x000c +#define AR6320V2_MISC_IE_ADDRESS 0x0034 +#define AR6320V2_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320V2_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320V2_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320V2_SRC_WATERMARK_LOW_LSB 16 +#define AR6320V2_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320V2_DST_WATERMARK_LOW_LSB 16 +#define AR6320V2_DST_WATERMARK_HIGH_LSB 0 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320V2_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320V2_RTC_STATE_ADDRESS 0x0000 +#define AR6320V2_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320V2_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320V2_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320V2_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320V2_RTC_STATE_V_MASK 0x00000007 +#define AR6320V2_RTC_STATE_V_LSB 0 +#define AR6320V2_RTC_STATE_V_ON 3 +#define AR6320V2_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320V2_FW_IND_EVENT_PENDING 1 +#define AR6320V2_FW_IND_INITIALIZED 2 +#define AR6320V2_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320V2_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320V2_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320V2_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320V2_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320V2_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320V2_CPU_INTR_ADDRESS 0x0010 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320V2_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320V2_CORE_CTRL_ADDRESS 0x0000 +#define AR6320V2_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320V2_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320V2_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320V2_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320V2_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320V2_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320V2_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320V2_SOC_CHIP_ID_REVISION_LSB 8 +#define AR6320V2_SOC_POWER_REG_OFFSET 0x0000010c + +/* Copy Engine Debug */ +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_OFFSET 0x0000010c +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MSB 3 +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_LSB 0 +#define AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MASK 0x0000000f +#define AR6320V2_WLAN_DEBUG_CONTROL_OFFSET 0x00000108 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MSB 0 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_LSB 0 +#define AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MASK 0x00000001 +#define AR6320V2_WLAN_DEBUG_OUT_OFFSET 0x00000110 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_MSB 19 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_LSB 0 +#define AR6320V2_WLAN_DEBUG_OUT_DATA_MASK 0x000fffff +#define AR6320V2_AMBA_DEBUG_BUS_OFFSET 0x0000011c +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB 13 +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB 8 +#define AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK 0x00003f00 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_MSB 4 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_LSB 0 +#define AR6320V2_AMBA_DEBUG_BUS_SEL_MASK 0x0000001f +#define AR6320V2_CE_WRAPPER_DEBUG_OFFSET 0x0008 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_MSB 5 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_LSB 0 +#define AR6320V2_CE_WRAPPER_DEBUG_SEL_MASK 0x0000003f +#define AR6320V2_CE_DEBUG_OFFSET 0x0054 +#define AR6320V2_CE_DEBUG_SEL_MSB 5 +#define AR6320V2_CE_DEBUG_SEL_LSB 0 +#define AR6320V2_CE_DEBUG_SEL_MASK 0x0000003f +/* End */ + +/* PLL start */ +#define AR6320V2_EFUSE_OFFSET 0x0000032c +#define AR6320V2_EFUSE_XTAL_SEL_MSB 10 +#define AR6320V2_EFUSE_XTAL_SEL_LSB 8 +#define AR6320V2_EFUSE_XTAL_SEL_MASK 0x00000700 +#define AR6320V2_BB_PLL_CONFIG_OFFSET 0x000002f4 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_MSB 20 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_LSB 18 +#define AR6320V2_BB_PLL_CONFIG_OUTDIV_MASK 0x001c0000 +#define AR6320V2_BB_PLL_CONFIG_FRAC_MSB 17 +#define AR6320V2_BB_PLL_CONFIG_FRAC_LSB 0 +#define AR6320V2_BB_PLL_CONFIG_FRAC_MASK 0x0003ffff +#define AR6320V2_WLAN_PLL_SETTLE_TIME_MSB 10 +#define AR6320V2_WLAN_PLL_SETTLE_TIME_LSB 0 +#define AR6320V2_WLAN_PLL_SETTLE_TIME_MASK 0x000007ff +#define AR6320V2_WLAN_PLL_SETTLE_OFFSET 0x0018 +#define AR6320V2_WLAN_PLL_SETTLE_SW_MASK 0x000007ff +#define AR6320V2_WLAN_PLL_SETTLE_RSTMASK 0xffffffff +#define AR6320V2_WLAN_PLL_SETTLE_RESET 0x00000400 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_MSB 18 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_LSB 18 +#define AR6320V2_WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_MSB 16 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_LSB 16 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000 +#define AR6320V2_WLAN_PLL_CONTROL_BYPASS_RESET 0x1 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MSB 15 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_LSB 14 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MASK 0x0000c000 +#define AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_RESET 0x0 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_MSB 13 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_LSB 10 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_MASK 0x00003c00 +#define AR6320V2_WLAN_PLL_CONTROL_REFDIV_RESET 0x0 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_MSB 9 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_LSB 0 +#define AR6320V2_WLAN_PLL_CONTROL_DIV_MASK 0x000003ff +#define AR6320V2_WLAN_PLL_CONTROL_DIV_RESET 0x11 +#define AR6320V2_WLAN_PLL_CONTROL_OFFSET 0x0014 +#define AR6320V2_WLAN_PLL_CONTROL_SW_MASK 0x001fffff +#define AR6320V2_WLAN_PLL_CONTROL_RSTMASK 0xffffffff +#define AR6320V2_WLAN_PLL_CONTROL_RESET 0x00010011 +#define AR6320V2_SOC_CORE_CLK_CTRL_OFFSET 0x00000114 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_MSB 2 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_LSB 0 +#define AR6320V2_SOC_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MSB 5 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_LSB 5 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MASK 0x00000020 +#define AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_RESET 0x0 +#define AR6320V2_RTC_SYNC_STATUS_OFFSET 0x0244 +#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MSB 1 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +/* PLL end */ + +#define AR6320V2_PCIE_INTR_CE_MASK(n) (AR6320V2_PCIE_INTR_CE0_MASK << (n)) +#define AR6320V2_DRAM_BASE_ADDRESS AR6320V2_TARG_DRAM_START +#define AR6320V2_FW_INDICATOR_ADDRESS (AR6320V2_SOC_CORE_BASE_ADDRESS + AR6320V2_SCRATCH_3_ADDRESS) +#define AR6320V2_SYSTEM_SLEEP_OFFSET AR6320V2_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320V2_WLAN_RESET_CONTROL_OFFSET AR6320V2_SOC_RESET_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_OFFSET AR6320V2_SOC_CLOCK_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320V2_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320V2_RESET_CONTROL_SI0_RST_MASK AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320V2_GPIO_BASE_ADDRESS AR6320V2_WLAN_GPIO_BASE_ADDRESS +#define AR6320V2_GPIO_PIN0_OFFSET AR6320V2_WLAN_GPIO_PIN0_ADDRESS +#define AR6320V2_GPIO_PIN1_OFFSET AR6320V2_WLAN_GPIO_PIN1_ADDRESS +#define AR6320V2_GPIO_PIN0_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320V2_GPIO_PIN1_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320V2_SI_BASE_ADDRESS 0x00050000 +#define AR6320V2_CPU_CLOCK_OFFSET AR6320V2_SOC_CPU_CLOCK_OFFSET +#define AR6320V2_LPO_CAL_OFFSET AR6320V2_SOC_LPO_CAL_OFFSET +#define AR6320V2_GPIO_PIN10_OFFSET AR6320V2_WLAN_GPIO_PIN10_ADDRESS +#define AR6320V2_GPIO_PIN11_OFFSET AR6320V2_WLAN_GPIO_PIN11_ADDRESS +#define AR6320V2_GPIO_PIN12_OFFSET AR6320V2_WLAN_GPIO_PIN12_ADDRESS +#define AR6320V2_GPIO_PIN13_OFFSET AR6320V2_WLAN_GPIO_PIN13_ADDRESS +#define AR6320V2_CPU_CLOCK_STANDARD_LSB AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320V2_CPU_CLOCK_STANDARD_MASK AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320V2_LPO_CAL_ENABLE_LSB AR6320V2_SOC_LPO_CAL_ENABLE_LSB +#define AR6320V2_LPO_CAL_ENABLE_MASK AR6320V2_SOC_LPO_CAL_ENABLE_MASK +#define AR6320V2_ANALOG_INTF_BASE_ADDRESS AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320V2_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320V2_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320V2_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320V2_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320V2_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320V2_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320V2_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320V2_COUNT_DEC_ADDRESS 0x0840 +#define AR6320V2_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320V2_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320V2_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320V2_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320V2_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320V2_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320V2_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320V2_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320V2_WINDOW_WRITE_ADDR_ADDRESS 0x0878 + +struct targetdef_s ar6320v2_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320V2_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320V2_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320V2_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320V2_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320V2_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320V2_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320V2_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320V2_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320V2_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320V2_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320V2_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320V2_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320V2_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320V2_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320V2_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320V2_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320V2_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320V2_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320V2_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320V2_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320V2_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320V2_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320V2_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320V2_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320V2_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320V2_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320V2_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320V2_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320V2_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320V2_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320V2_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320V2_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320V2_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320V2_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320V2_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320V2_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320V2_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320V2_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320V2_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320V2_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320V2_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320V2_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320V2_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320V2_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320V2_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320V2_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320V2_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320V2_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320V2_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320V2_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320V2_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320V2_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320V2_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320V2_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320V2_CE_COUNT, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320V2_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320V2_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320V2_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320V2_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320V2_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320V2_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320V2_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320V2_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320V2_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320V2_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320V2_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320V2_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320V2_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320V2_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320V2_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320V2_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320V2_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320V2_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320V2_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320V2_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320V2_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320V2_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320V2_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320V2_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320V2_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320V2_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320V2_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320V2_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320V2_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320V2_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320V2_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320V2_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320V2_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320V2_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320V2_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + .d_WLAN_DEBUG_INPUT_SEL_OFFSET = AR6320V2_WLAN_DEBUG_INPUT_SEL_OFFSET, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MSB = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_LSB = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_LSB, + .d_WLAN_DEBUG_INPUT_SEL_SRC_MASK = AR6320V2_WLAN_DEBUG_INPUT_SEL_SRC_MASK, + .d_WLAN_DEBUG_CONTROL_OFFSET = AR6320V2_WLAN_DEBUG_CONTROL_OFFSET, + .d_WLAN_DEBUG_CONTROL_ENABLE_MSB = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_LSB = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_LSB, + .d_WLAN_DEBUG_CONTROL_ENABLE_MASK = AR6320V2_WLAN_DEBUG_CONTROL_ENABLE_MASK, + .d_WLAN_DEBUG_OUT_OFFSET = AR6320V2_WLAN_DEBUG_OUT_OFFSET, + .d_WLAN_DEBUG_OUT_DATA_MSB = AR6320V2_WLAN_DEBUG_OUT_DATA_MSB, + .d_WLAN_DEBUG_OUT_DATA_LSB = AR6320V2_WLAN_DEBUG_OUT_DATA_LSB, + .d_WLAN_DEBUG_OUT_DATA_MASK = AR6320V2_WLAN_DEBUG_OUT_DATA_MASK, + .d_AMBA_DEBUG_BUS_OFFSET = AR6320V2_AMBA_DEBUG_BUS_OFFSET, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB, + .d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK = AR6320V2_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK, + .d_AMBA_DEBUG_BUS_SEL_MSB = AR6320V2_AMBA_DEBUG_BUS_SEL_MSB, + .d_AMBA_DEBUG_BUS_SEL_LSB = AR6320V2_AMBA_DEBUG_BUS_SEL_LSB, + .d_AMBA_DEBUG_BUS_SEL_MASK = AR6320V2_AMBA_DEBUG_BUS_SEL_MASK, + .d_CE_WRAPPER_DEBUG_OFFSET = AR6320V2_CE_WRAPPER_DEBUG_OFFSET, + .d_CE_WRAPPER_DEBUG_SEL_MSB = AR6320V2_CE_WRAPPER_DEBUG_SEL_MSB, + .d_CE_WRAPPER_DEBUG_SEL_LSB = AR6320V2_CE_WRAPPER_DEBUG_SEL_LSB, + .d_CE_WRAPPER_DEBUG_SEL_MASK = AR6320V2_CE_WRAPPER_DEBUG_SEL_MASK, + .d_CE_DEBUG_OFFSET = AR6320V2_CE_DEBUG_OFFSET, + .d_CE_DEBUG_SEL_MSB = AR6320V2_CE_DEBUG_SEL_MSB, + .d_CE_DEBUG_SEL_LSB = AR6320V2_CE_DEBUG_SEL_LSB, + .d_CE_DEBUG_SEL_MASK = AR6320V2_CE_DEBUG_SEL_MASK, + /* PLL start */ + .d_EFUSE_OFFSET = AR6320V2_EFUSE_OFFSET, + .d_EFUSE_XTAL_SEL_MSB = AR6320V2_EFUSE_XTAL_SEL_MSB, + .d_EFUSE_XTAL_SEL_LSB = AR6320V2_EFUSE_XTAL_SEL_LSB, + .d_EFUSE_XTAL_SEL_MASK = AR6320V2_EFUSE_XTAL_SEL_MASK, + .d_BB_PLL_CONFIG_OFFSET = AR6320V2_BB_PLL_CONFIG_OFFSET, + .d_BB_PLL_CONFIG_OUTDIV_MSB = AR6320V2_BB_PLL_CONFIG_OUTDIV_MSB, + .d_BB_PLL_CONFIG_OUTDIV_LSB = AR6320V2_BB_PLL_CONFIG_OUTDIV_LSB, + .d_BB_PLL_CONFIG_OUTDIV_MASK = AR6320V2_BB_PLL_CONFIG_OUTDIV_MASK, + .d_BB_PLL_CONFIG_FRAC_MSB = AR6320V2_BB_PLL_CONFIG_FRAC_MSB, + .d_BB_PLL_CONFIG_FRAC_LSB = AR6320V2_BB_PLL_CONFIG_FRAC_LSB, + .d_BB_PLL_CONFIG_FRAC_MASK = AR6320V2_BB_PLL_CONFIG_FRAC_MASK, + .d_WLAN_PLL_SETTLE_TIME_MSB = AR6320V2_WLAN_PLL_SETTLE_TIME_MSB, + .d_WLAN_PLL_SETTLE_TIME_LSB = AR6320V2_WLAN_PLL_SETTLE_TIME_LSB, + .d_WLAN_PLL_SETTLE_TIME_MASK = AR6320V2_WLAN_PLL_SETTLE_TIME_MASK, + .d_WLAN_PLL_SETTLE_OFFSET = AR6320V2_WLAN_PLL_SETTLE_OFFSET, + .d_WLAN_PLL_SETTLE_SW_MASK = AR6320V2_WLAN_PLL_SETTLE_SW_MASK, + .d_WLAN_PLL_SETTLE_RSTMASK = AR6320V2_WLAN_PLL_SETTLE_RSTMASK, + .d_WLAN_PLL_SETTLE_RESET = AR6320V2_WLAN_PLL_SETTLE_RESET, + .d_WLAN_PLL_CONTROL_NOPWD_MSB = AR6320V2_WLAN_PLL_CONTROL_NOPWD_MSB, + .d_WLAN_PLL_CONTROL_NOPWD_LSB = AR6320V2_WLAN_PLL_CONTROL_NOPWD_LSB, + .d_WLAN_PLL_CONTROL_NOPWD_MASK = AR6320V2_WLAN_PLL_CONTROL_NOPWD_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_MSB = AR6320V2_WLAN_PLL_CONTROL_BYPASS_MSB, + .d_WLAN_PLL_CONTROL_BYPASS_LSB = AR6320V2_WLAN_PLL_CONTROL_BYPASS_LSB, + .d_WLAN_PLL_CONTROL_BYPASS_MASK = AR6320V2_WLAN_PLL_CONTROL_BYPASS_MASK, + .d_WLAN_PLL_CONTROL_BYPASS_RESET = AR6320V2_WLAN_PLL_CONTROL_BYPASS_RESET, + .d_WLAN_PLL_CONTROL_CLK_SEL_MSB = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_LSB = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_LSB, + .d_WLAN_PLL_CONTROL_CLK_SEL_MASK = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_MASK, + .d_WLAN_PLL_CONTROL_CLK_SEL_RESET = AR6320V2_WLAN_PLL_CONTROL_CLK_SEL_RESET, + .d_WLAN_PLL_CONTROL_REFDIV_MSB = AR6320V2_WLAN_PLL_CONTROL_REFDIV_MSB, + .d_WLAN_PLL_CONTROL_REFDIV_LSB = AR6320V2_WLAN_PLL_CONTROL_REFDIV_LSB, + .d_WLAN_PLL_CONTROL_REFDIV_MASK = AR6320V2_WLAN_PLL_CONTROL_REFDIV_MASK, + .d_WLAN_PLL_CONTROL_REFDIV_RESET = AR6320V2_WLAN_PLL_CONTROL_REFDIV_RESET, + .d_WLAN_PLL_CONTROL_DIV_MSB = AR6320V2_WLAN_PLL_CONTROL_DIV_MSB, + .d_WLAN_PLL_CONTROL_DIV_LSB = AR6320V2_WLAN_PLL_CONTROL_DIV_LSB, + .d_WLAN_PLL_CONTROL_DIV_MASK = AR6320V2_WLAN_PLL_CONTROL_DIV_MASK, + .d_WLAN_PLL_CONTROL_DIV_RESET = AR6320V2_WLAN_PLL_CONTROL_DIV_RESET, + .d_WLAN_PLL_CONTROL_OFFSET = AR6320V2_WLAN_PLL_CONTROL_OFFSET, + .d_WLAN_PLL_CONTROL_SW_MASK = AR6320V2_WLAN_PLL_CONTROL_SW_MASK, + .d_WLAN_PLL_CONTROL_RSTMASK = AR6320V2_WLAN_PLL_CONTROL_RSTMASK, + .d_WLAN_PLL_CONTROL_RESET = AR6320V2_WLAN_PLL_CONTROL_RESET, + .d_SOC_CORE_CLK_CTRL_OFFSET = AR6320V2_SOC_CORE_CLK_CTRL_OFFSET, + .d_SOC_CORE_CLK_CTRL_DIV_MSB = AR6320V2_SOC_CORE_CLK_CTRL_DIV_MSB, + .d_SOC_CORE_CLK_CTRL_DIV_LSB = AR6320V2_SOC_CORE_CLK_CTRL_DIV_LSB, + .d_SOC_CORE_CLK_CTRL_DIV_MASK = AR6320V2_SOC_CORE_CLK_CTRL_DIV_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MSB = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_LSB = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_LSB, + .d_RTC_SYNC_STATUS_PLL_CHANGING_MASK = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_MASK, + .d_RTC_SYNC_STATUS_PLL_CHANGING_RESET = AR6320V2_RTC_SYNC_STATUS_PLL_CHANGING_RESET, + .d_RTC_SYNC_STATUS_OFFSET = AR6320V2_RTC_SYNC_STATUS_OFFSET, + .d_SOC_CPU_CLOCK_OFFSET = AR6320V2_SOC_CPU_CLOCK_OFFSET, + .d_SOC_CPU_CLOCK_STANDARD_MSB = AR6320V2_SOC_CPU_CLOCK_STANDARD_MSB, + .d_SOC_CPU_CLOCK_STANDARD_LSB = AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB, + .d_SOC_CPU_CLOCK_STANDARD_MASK = AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK, + /* PLL end */ + .d_SOC_POWER_REG_OFFSET = AR6320V2_SOC_POWER_REG_OFFSET, + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320V2_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320V2_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320V2_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320V2_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320V2_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320V2_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320V2_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320V2_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320v2_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320V2_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320V2_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320V2_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320V2_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320V2_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320V2_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320V2_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320V2_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320V2_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320V2_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320V2_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320V2_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320V2_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320V2_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320V2_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320V2_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320V2_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320V2_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320V2_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320V2_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320V2_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320V2_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320V2_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320V2_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320V2_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320V2_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320V2_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320V2_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320V2_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR6320V2_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320V2_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar9888def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar9888def.h new file mode 100644 index 0000000000000..3bf2ec2e308cd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/ar9888def.h @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR9888DEF_H_ +#define AR9888__AR9888DEF_H_ + +/* Base Addresses */ +#define AR9888_RTC_SOC_BASE_ADDRESS 0x00004000 +#define AR9888_RTC_WMAC_BASE_ADDRESS 0x00005000 +#define AR9888_MAC_COEX_BASE_ADDRESS 0x00006000 +#define AR9888_BT_COEX_BASE_ADDRESS 0x00007000 +#define AR9888_SOC_PCIE_BASE_ADDRESS 0x00008000 +#define AR9888_SOC_CORE_BASE_ADDRESS 0x00009000 +#define AR9888_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 +#define AR9888_WLAN_MAC_BASE_ADDRESS 0x00020000 +#define AR9888_EFUSE_BASE_ADDRESS 0x00030000 +#define AR9888_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR9888_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR9888_CE_WRAPPER_BASE_ADDRESS 0x00057000 +#define AR9888_CE0_BASE_ADDRESS 0x00057400 +#define AR9888_CE1_BASE_ADDRESS 0x00057800 +#define AR9888_CE2_BASE_ADDRESS 0x00057c00 +#define AR9888_CE3_BASE_ADDRESS 0x00058000 +#define AR9888_CE4_BASE_ADDRESS 0x00058400 +#define AR9888_CE5_BASE_ADDRESS 0x00058800 +#define AR9888_CE6_BASE_ADDRESS 0x00058c00 +#define AR9888_CE7_BASE_ADDRESS 0x00059000 +#define AR9888_DBI_BASE_ADDRESS 0x00060000 +#define AR9888_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 + +#define AR9888_SCRATCH_3_ADDRESS 0x0030 +#define AR9888_TARG_DRAM_START 0x00400000 +#define AR9888_SOC_SYSTEM_SLEEP_OFFSET 0x000000c4 +#define AR9888_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR9888_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR9888_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_GPIO_PIN0_ADDRESS 0x00000028 +#define AR9888_WLAN_GPIO_PIN1_ADDRESS 0x0000002c +#define AR9888_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR9888_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR9888_WLAN_GPIO_PIN10_ADDRESS 0x00000050 +#define AR9888_WLAN_GPIO_PIN11_ADDRESS 0x00000054 +#define AR9888_WLAN_GPIO_PIN12_ADDRESS 0x00000058 +#define AR9888_WLAN_GPIO_PIN13_ADDRESS 0x0000005c +#define AR9888_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR9888_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR9888_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR9888_SOC_LPO_CAL_ENABLE_MASK 0x00100000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 + +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR9888_SI_CONFIG_I2C_LSB 16 +#define AR9888_SI_CONFIG_I2C_MASK 0x00010000 +#define AR9888_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR9888_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR9888_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR9888_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR9888_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR9888_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR9888_SI_CONFIG_DIVIDER_LSB 0 +#define AR9888_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR9888_SI_CONFIG_OFFSET 0x00000000 +#define AR9888_SI_TX_DATA0_OFFSET 0x00000008 +#define AR9888_SI_TX_DATA1_OFFSET 0x0000000c +#define AR9888_SI_RX_DATA0_OFFSET 0x00000010 +#define AR9888_SI_RX_DATA1_OFFSET 0x00000014 +#define AR9888_SI_CS_OFFSET 0x00000004 +#define AR9888_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR9888_SI_CS_DONE_INT_MASK 0x00000200 +#define AR9888_SI_CS_START_LSB 8 +#define AR9888_SI_CS_START_MASK 0x00000100 +#define AR9888_SI_CS_RX_CNT_LSB 4 +#define AR9888_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR9888_SI_CS_TX_CNT_LSB 0 +#define AR9888_SI_CS_TX_CNT_MASK 0x0000000f +#define AR9888_CE_COUNT 8 +#define AR9888_SR_WR_INDEX_ADDRESS 0x003c +#define AR9888_DST_WATERMARK_ADDRESS 0x0050 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR9888_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR9888_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR9888_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR9888_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR9888_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR9888_DST_WR_INDEX_ADDRESS 0x0040 +#define AR9888_SRC_WATERMARK_ADDRESS 0x004c +#define AR9888_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_CURRENT_SRRI_ADDRESS 0x0044 +#define AR9888_CURRENT_DRRI_ADDRESS 0x0048 +#define AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR9888_HOST_IS_ADDRESS 0x0030 +#define AR9888_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR9888_HOST_IE_ADDRESS 0x002c +#define AR9888_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_SR_BA_ADDRESS 0x0000 +#define AR9888_SR_SIZE_ADDRESS 0x0004 +#define AR9888_CE_CTRL1_ADDRESS 0x0010 +#define AR9888_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR9888_DR_BA_ADDRESS 0x0008 +#define AR9888_DR_SIZE_ADDRESS 0x000c +#define AR9888_MISC_IE_ADDRESS 0x0034 +#define AR9888_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR9888_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR9888_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR9888_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR9888_SRC_WATERMARK_LOW_LSB 16 +#define AR9888_SRC_WATERMARK_HIGH_LSB 0 +#define AR9888_DST_WATERMARK_LOW_LSB 16 +#define AR9888_DST_WATERMARK_HIGH_LSB 0 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR9888_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 2 +#define AR9888_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR9888_RTC_STATE_ADDRESS 0x0000 +#define AR9888_RTC_STATE_COLD_RESET_MASK 0x00000400 +#define AR9888_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR9888_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR9888_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR9888_RTC_STATE_V_MASK 0x00000007 +#define AR9888_RTC_STATE_V_LSB 0 +#define AR9888_RTC_STATE_V_ON 3 +#define AR9888_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR9888_FW_IND_EVENT_PENDING 1 +#define AR9888_FW_IND_INITIALIZED 2 +#define AR9888_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR9888_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR9888_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR9888_PCIE_INTR_CE0_MASK 0x00000800 +#define AR9888_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR9888_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR9888_CPU_INTR_ADDRESS 0x0010 +#define AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR9888_SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 +#define AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR9888_CORE_CTRL_ADDRESS 0x0000 +#define AR9888_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR9888_LOCAL_SCRATCH_OFFSET 0x18 +#define AR9888_CLOCK_GPIO_OFFSET 0xffffffff +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 + +#define AR9888_PCIE_INTR_CE_MASK(n) (AR9888_PCIE_INTR_CE0_MASK << (n)) +#define AR9888_FW_EVENT_PENDING_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_DRAM_BASE_ADDRESS AR9888_TARG_DRAM_START +#define AR9888_FW_INDICATOR_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_RESET_CONTROL_OFFSET AR9888_SOC_RESET_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_OFFSET AR9888_SOC_CLOCK_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_SI0_CLK_MASK AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR9888_RESET_CONTROL_MBOX_RST_MASK MISSING +#define AR9888_RESET_CONTROL_SI0_RST_MASK AR9888_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR9888_GPIO_BASE_ADDRESS AR9888_WLAN_GPIO_BASE_ADDRESS +#define AR9888_GPIO_PIN0_OFFSET AR9888_WLAN_GPIO_PIN0_ADDRESS +#define AR9888_GPIO_PIN1_OFFSET AR9888_WLAN_GPIO_PIN1_ADDRESS +#define AR9888_GPIO_PIN0_CONFIG_MASK AR9888_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR9888_GPIO_PIN1_CONFIG_MASK AR9888_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR9888_SI_BASE_ADDRESS AR9888_WLAN_SI_BASE_ADDRESS +#define AR9888_SCRATCH_BASE_ADDRESS AR9888_SOC_CORE_BASE_ADDRESS +#define AR9888_CPU_CLOCK_OFFSET AR9888_SOC_CPU_CLOCK_OFFSET +#define AR9888_LPO_CAL_OFFSET AR9888_SOC_LPO_CAL_OFFSET +#define AR9888_GPIO_PIN10_OFFSET AR9888_WLAN_GPIO_PIN10_ADDRESS +#define AR9888_GPIO_PIN11_OFFSET AR9888_WLAN_GPIO_PIN11_ADDRESS +#define AR9888_GPIO_PIN12_OFFSET AR9888_WLAN_GPIO_PIN12_ADDRESS +#define AR9888_GPIO_PIN13_OFFSET AR9888_WLAN_GPIO_PIN13_ADDRESS +#define AR9888_CPU_CLOCK_STANDARD_LSB AR9888_SOC_CPU_CLOCK_STANDARD_LSB +#define AR9888_CPU_CLOCK_STANDARD_MASK AR9888_SOC_CPU_CLOCK_STANDARD_MASK +#define AR9888_LPO_CAL_ENABLE_LSB AR9888_SOC_LPO_CAL_ENABLE_LSB +#define AR9888_LPO_CAL_ENABLE_MASK AR9888_SOC_LPO_CAL_ENABLE_MASK +#define AR9888_ANALOG_INTF_BASE_ADDRESS AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR9888_MBOX_BASE_ADDRESS MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_HOST_INT_STATUS_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define AR9888_COUNT_DEC_ADDRESS MISSING +#define AR9888_HOST_INT_STATUS_CPU_MASK MISSING +#define AR9888_HOST_INT_STATUS_CPU_LSB MISSING +#define AR9888_HOST_INT_STATUS_ERROR_MASK MISSING +#define AR9888_HOST_INT_STATUS_ERROR_LSB MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_MASK MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_LSB MISSING +#define AR9888_RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define AR9888_WINDOW_DATA_ADDRESS MISSING +#define AR9888_WINDOW_READ_ADDR_ADDRESS MISSING +#define AR9888_WINDOW_WRITE_ADDR_ADDRESS MISSING + +struct targetdef_s ar9888_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR9888_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR9888_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR9888_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR9888_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR9888_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR9888_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR9888_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR9888_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR9888_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR9888_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR9888_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR9888_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR9888_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR9888_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR9888_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR9888_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR9888_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR9888_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR9888_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR9888_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR9888_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR9888_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR9888_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR9888_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR9888_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR9888_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR9888_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR9888_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR9888_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR9888_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR9888_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR9888_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR9888_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR9888_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR9888_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR9888_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR9888_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR9888_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR9888_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR9888_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR9888_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR9888_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR9888_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR9888_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR9888_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR9888_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR9888_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR9888_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR9888_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR9888_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR9888_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR9888_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR9888_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR9888_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR9888_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR9888_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR9888_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR9888_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR9888_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR9888_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR9888_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR9888_CE_COUNT, + .d_PCIE_INTR_ENABLE_ADDRESS = AR9888_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR9888_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR9888_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR9888_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR9888_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR9888_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR9888_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR9888_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR9888_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR9888_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR9888_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR9888_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR9888_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR9888_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR9888_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR9888_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR9888_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR9888_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR9888_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR9888_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR9888_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR9888_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR9888_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR9888_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR9888_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR9888_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR9888_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR9888_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR9888_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR9888_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR9888_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR9888_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR9888_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR9888_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR9888_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR9888_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR9888_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR9888_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR9888_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR9888_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR9888_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR9888_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR9888_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR9888_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR9888_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR9888_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR9888_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR9888_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + + .d_PCIE_INTR_CAUSE_ADDRESS = AR9888_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR9888_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR9888_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR9888_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, +}; + +struct hostdef_s ar9888_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR9888_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR9888_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR9888_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR9888_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR9888_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR9888_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR9888_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR9888_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR9888_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR9888_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR9888_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR9888_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR9888_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR9888_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR9888_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR9888_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR9888_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR9888_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR9888_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR9888_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR9888_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR9888_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR9888_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR9888_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR9888_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR9888_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR9888_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR9888_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR9888_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR9888_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR9888_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR9888_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR9888_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR9888_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR9888_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR9888_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR9888_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb.c new file mode 100644 index 0000000000000..50448ce7bc8f3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb.c @@ -0,0 +1,1159 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adf_net_types.h" +#include +#include "a_types.h" +#include "athdefs.h" +#include "a_osapi.h" +#include +#include "hif_usb_internal.h" +#include +#include +#include +#include +#define ATH_MODULE_NAME hif +#include + +#define USB_HIF_USE_SINGLE_PIPE_FOR_DATA +#define USB_HIF_TARGET_CREDIT_SIZE 1664 +#ifdef DEBUG +static ATH_DEBUG_MASK_DESCRIPTION g_HIFDebugDescription[] = { + {USB_HIF_DEBUG_CTRL_TRANS, "Control Transfers"}, + {USB_HIF_DEBUG_BULK_IN, "BULK In Transfers"}, + {USB_HIF_DEBUG_BULK_OUT, "BULK Out Transfers"}, + {USB_HIF_DEBUG_DUMP_DATA, "Dump data"}, + {USB_HIF_DEBUG_ENUM, "Enumeration"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, + "hif", + "USB Host Interface", + ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO | + USB_HIF_DEBUG_ENUM, + ATH_DEBUG_DESCRIPTION_COUNT + (g_HIFDebugDescription), + g_HIFDebugDescription); + +#endif + +/* use credit flow control over HTC */ +unsigned int htc_credit_flow; +module_param(htc_credit_flow, uint, 0644); + +/* not enabling bundle recv/send by default */ +unsigned int htc_bundle_recv; +module_param(htc_bundle_recv, uint, 0644); + +unsigned int htc_bundle_send; +module_param(htc_bundle_send, uint, 0644); + +#ifdef USB_ISOC_SUPPORT +unsigned int hif_usb_isoch_vo = 1; +#else +unsigned int hif_usb_isoch_vo; +#endif +module_param(hif_usb_isoch_vo, uint, 0644); +unsigned int hif_usb_disable_rxdata2 = 1; +module_param(hif_usb_disable_rxdata2, uint, 0644); + +unsigned int hif_usbaudioclass; +module_param(hif_usbaudioclass, uint, 0644); + +static void usb_hif_destroy(HIF_DEVICE_USB *device); +static HIF_DEVICE_USB *usb_hif_create(struct usb_interface *interface); + +OSDRV_CALLBACKS osDrvcallback; + +int notifyDeviceInsertedHandler(void *hHIF) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + osDrvcallback.deviceInsertedHandler(osDrvcallback.context, hHIF); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + complete_and_exit(NULL, 0); + return 0; +} + +int notifyDeviceSurprisedRemovedHandler(void *context) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) context; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + osDrvcallback.deviceRemovedHandler(device->claimed_context, device); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + complete_and_exit(NULL, 0); + return 0; +} + +int HIF_USBDeviceInserted(struct usb_interface *interface, hif_handle_t hif_hdl) +{ + HIF_DEVICE_USB *device = NULL; + int retval = -1; + struct hif_usb_softc *sc = hif_hdl; + struct usb_device *udev = interface_to_usbdev(interface); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BCDDevice : %x\n", + udev->descriptor.bcdDevice)); + + do { + + device = usb_hif_create(interface); + if (NULL == device) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("device is NULL\n")); + break; + } + device->sc = sc; + sc->hif_device = (HIF_DEVICE *) device; + retval = 0; + + } while (FALSE); + + if ((device != NULL) && (retval < 0)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("abnormal condition\n")); + usb_hif_destroy(device); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + return retval; +} + +void HIF_USBDeviceDetached(struct usb_interface *interface, + a_uint8_t surprise_removed) +{ + HIF_DEVICE_USB *device; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + do { + + device = (HIF_DEVICE_USB *) usb_get_intfdata(interface); + if (NULL == device) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("device is NULL\n")); + break; + } + + device->surpriseRemoved = surprise_removed; + /* inform upper layer if it is still interested */ + if (surprise_removed + && (osDrvcallback.deviceRemovedHandler != NULL) + && (device->claimed_context != NULL)) { + osDrvcallback.deviceRemovedHandler(device-> + claimed_context, + device); + } + + usb_hif_destroy(device); + athdiag_procfs_remove(); + } while (FALSE); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + +} + +static void usb_hif_usb_transmit_complete(struct urb *urb) +{ + HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context; + adf_nbuf_t buf; + HIF_USB_PIPE *pipe = urb_context->pipe; + struct HIFSendContext *pSendContext; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("+%s: pipe: %d, stat:%d, len:%d\n", __func__, + pipe->logical_pipe_num, urb->status, + urb->actual_length)); + + /* this urb is not pending anymore */ + usb_hif_remove_pending_transfer(urb_context); + + if (urb->status != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: pipe: %d, failed:%d\n", + __func__, + pipe->logical_pipe_num, + urb->status)); + } + + a_mem_trace(urb_context->buf); + buf = urb_context->buf; + pSendContext = urb_context->pSendContext; + + if (pSendContext->bNewAlloc) { + adf_os_mem_free((void *)pSendContext); + } else { + adf_nbuf_pull_head(buf, pSendContext->head_data_len); + } + + urb_context->buf = NULL; + usb_hif_cleanup_transmit_urb(urb_context); + +#if 0 + if (pipe->urbcnt >= pipe->urb_cnt_thresh) + /* TBD */ +#endif + + /* note: queue implements a lock */ + skb_queue_tail(&pipe->io_comp_queue, buf); + schedule_work(&pipe->io_complete_work); + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, ("-%s\n", __func__)); +} + +static void usb_hif_usb_transmit_bundle_complete(struct urb *urb) +{ + HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context; + HIF_USB_PIPE *pipe = urb_context->pipe; + adf_nbuf_t tmp_buf; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("+%s: pipe: %d, stat:%d, len:%d\n", __func__, + pipe->logical_pipe_num, urb->status, + urb->actual_length)); + + /* this urb is not pending anymore */ + usb_hif_remove_pending_transfer(urb_context); + + if (urb->status != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: pipe: %d, failed:%d\n", + __func__, + pipe->logical_pipe_num, + urb->status)); + } + + a_mem_trace(urb_context->buf); + + usb_hif_cleanup_transmit_urb(urb_context); + +#if 0 + if (pipe->urbcnt >= pipe->urb_cnt_thresh) + /* TBD */ +#endif + + while ((tmp_buf = skb_dequeue(&urb_context->comp_queue))) + skb_queue_tail(&pipe->io_comp_queue, tmp_buf); + schedule_work(&pipe->io_complete_work); + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, ("-%s\n", __func__)); +} + +A_STATUS HIFSendMultiple(HIF_DEVICE *hifDevice, a_uint8_t PipeID, + adf_nbuf_t *msg_bundle, int num_msgs) +{ + A_STATUS status = A_OK; + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + HIF_USB_PIPE *pipe = &device->pipes[PipeID]; + HIF_URB_CONTEXT *urb_context; + struct urb *urb; + adf_nbuf_t stream_buf = NULL, nbuf; + int usb_status; + int i; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("+%s pipe : %d\n", __func__, PipeID)); + + do { + A_UINT8 *stream_netdata, *netdata, *stream_netdata_start; + A_UINT32 stream_netlen, netlen; + + urb_context = usb_hif_alloc_urb_from_pipe(pipe); + if (NULL == urb_context) { + /* TODO : note, it is possible to run out of urbs if 2 + * endpoints map to the same pipe ID + */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s pipe:%d no urbs left. URB Cnt :%d\n", + __func__, PipeID, pipe->urb_cnt)); + status = A_NO_RESOURCE; + break; + } + + urb = urb_context->urb; + stream_buf = urb_context->buf; + + adf_nbuf_peek_header(stream_buf, &stream_netdata, + &stream_netlen); + stream_netlen = 0; + stream_netdata_start = stream_netdata; + + for (i = 0; i < num_msgs; i++) { + nbuf = msg_bundle[i]; + adf_nbuf_peek_header(nbuf, &netdata, &netlen); + + adf_os_mem_copy(stream_netdata, netdata, netlen); + + /* add additional dummy padding + * target credit size + */ + stream_netdata += USB_HIF_TARGET_CREDIT_SIZE; + stream_netlen += USB_HIF_TARGET_CREDIT_SIZE; + + /* note: queue implements a lock */ + skb_queue_tail(&urb_context->comp_queue, nbuf); + } + + usb_fill_bulk_urb(urb, + device->udev, + pipe->usb_pipe_handle, + stream_netdata_start, + (stream_netlen % pipe->max_packet_size) == 0 ? + (stream_netlen + 1) : stream_netlen, + usb_hif_usb_transmit_bundle_complete, + urb_context); + + if ((stream_netlen % pipe->max_packet_size) == 0) { + /* hit a max packet boundary on this pipe */ + /* urb->transfer_flags |= URB_ZERO_PACKET; */ + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, ( + "athusb bulk send submit:%d, 0x%X (ep:0x%2.2X), %d bytes\n", + pipe->logical_pipe_num, pipe->usb_pipe_handle, + pipe->ep_address, stream_netlen)); + + usb_hif_enqueue_pending_transfer(pipe, urb_context); + + usb_status = usb_submit_urb(urb, GFP_ATOMIC); + if (usb_status) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb : usb bulk transmit failed\n")); + usb_hif_remove_pending_transfer(urb_context); + usb_hif_cleanup_transmit_urb(urb_context); + status = A_ECOMM; + break; + } + } while (FALSE); + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("-%s pipe : %d\n", __func__, PipeID)); + + return status; +} + +static A_STATUS HIFSend_internal(HIF_DEVICE *hifDevice, a_uint8_t PipeID, + adf_nbuf_t hdr_buf, adf_nbuf_t buf, unsigned int nbytes) +{ + A_STATUS status = A_OK; + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + HIF_USB_PIPE *pipe = &device->pipes[PipeID]; + HIF_URB_CONTEXT *urb_context; + A_UINT8 *data; + A_UINT32 len; + struct urb *urb; + int usb_status; + int i; + struct HIFSendContext *pSendContext; + int frag_count = 0, head_data_len, tmp_frag_count = 0; + unsigned char *pData; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, ("+%s pipe : %d, buf:0x%p\n", + __func__, PipeID, buf)); + + a_mem_trace(buf); + + frag_count = adf_nbuf_get_num_frags(buf); + if (frag_count > 1) { /* means have extra fragment buf in skb */ + /* header data length should be total sending length substract + * internal data length of netbuf + * | HIFSendContext | fragments except internal buffer | + * netbuf->data + */ + head_data_len = sizeof(struct HIFSendContext); + while (tmp_frag_count < (frag_count - 1)) { + head_data_len = + head_data_len + adf_nbuf_get_frag_len(buf, + tmp_frag_count); + tmp_frag_count = tmp_frag_count + 1; + } + } else { + /* + * | HIFSendContext | netbuf->data + */ + head_data_len = sizeof(struct HIFSendContext); + } + + /* Check whether head room is enough to save extra head data */ + if (head_data_len <= adf_nbuf_headroom(buf)) { + pSendContext = (struct HIFSendContext *)adf_nbuf_push_head(buf, + head_data_len); + pSendContext->bNewAlloc = FALSE; + } else { + pSendContext = adf_os_mem_alloc(NULL, + sizeof + (struct + HIFSendContext) + + + head_data_len + + + nbytes); + pSendContext->bNewAlloc = TRUE; + } + pSendContext->netbuf = buf; + pSendContext->pDev = hifDevice; + pSendContext->transferID = PipeID; + pSendContext->head_data_len = head_data_len; + /* + * Copy data to head part of netbuf or head of allocated buffer. + * if buffer is new allocated, the last buffer should be copied also. + * It assume last fragment is internal buffer of netbuf + * sometime total length of fragments larger than nbytes + */ + pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext); + for (i = 0; i < (pSendContext->bNewAlloc ? frag_count : frag_count - 1); + i++) { + int frag_len = adf_nbuf_get_frag_len(buf, i); + unsigned char *frag_addr = adf_nbuf_get_frag_vaddr(buf, i); + memcpy(pData, frag_addr, frag_len); + pData += frag_len; + } + /* Reset pData pointer and send out */ + pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext); + + do { + urb_context = usb_hif_alloc_urb_from_pipe(pipe); + if (NULL == urb_context) { + /* TODO : note, it is possible to run out of urbs if 2 + * endpoints map to the same pipe ID + */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s pipe:%d no urbs left. URB Cnt : %d\n", + __func__, PipeID, pipe->urb_cnt)); + status = A_NO_RESOURCE; + break; + } + urb_context->pSendContext = pSendContext; + urb = urb_context->urb; + urb_context->buf = buf; + data = pData; + len = nbytes; + + usb_fill_bulk_urb(urb, + device->udev, + pipe->usb_pipe_handle, + data, + (len % pipe->max_packet_size) == + 0 ? (len + 1) : len, + usb_hif_usb_transmit_complete, urb_context); + + if ((len % pipe->max_packet_size) == 0) { + /* hit a max packet boundary on this pipe */ + /* urb->transfer_flags |= URB_ZERO_PACKET; */ + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, ( + "athusb bulk send submit:%d, 0x%X (ep:0x%2.2X), %d bytes\n", + pipe->logical_pipe_num, pipe->usb_pipe_handle, + pipe->ep_address, nbytes)); + + usb_hif_enqueue_pending_transfer(pipe, urb_context); + usb_status = usb_submit_urb(urb, GFP_ATOMIC); + if (usb_status) { + if (pSendContext->bNewAlloc) + adf_os_mem_free(pSendContext); + else + adf_nbuf_pull_head(buf, head_data_len); + urb_context->buf = NULL; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb : usb bulk transmit failed %d\n", + usb_status)); + usb_hif_remove_pending_transfer(urb_context); + usb_hif_cleanup_transmit_urb(urb_context); + status = A_ECOMM; + break; + } + + } while (FALSE); + + if (A_FAILED(status) && (status != A_NO_RESOURCE)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb send failed %d\n", status)); + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("-%s pipe : %d\n", __func__, PipeID)); + + return status; +} + +/* Send the entire buffer */ +A_STATUS HIFSend(HIF_DEVICE *hif_device, a_uint8_t pipe, adf_nbuf_t hdr_buf, + adf_nbuf_t netbuf) +{ + return HIFSend_head(hif_device, pipe, 0, adf_nbuf_len(netbuf), netbuf); +} + +A_STATUS +HIFSend_head(HIF_DEVICE *hif_device, + a_uint8_t pipe, unsigned int transfer_id, unsigned int nbytes, + adf_nbuf_t nbuf) +{ + A_STATUS status = EOK; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + status = HIFSend_internal(hif_device, pipe, NULL, nbuf, nbytes); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + + return status; +} + +a_uint16_t HIFGetFreeQueueNumber(HIF_DEVICE *hifDevice, a_uint8_t PipeID) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + return device->pipes[PipeID].urb_cnt; +} + +a_uint16_t HIFGetMaxQueueNumber(HIF_DEVICE *hifDevice, a_uint8_t PipeID) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + return device->pipes[PipeID].urb_alloc; +} + +void HIFPostInit(HIF_DEVICE *hifDevice, void *unused, + MSG_BASED_HIF_CALLBACKS *callbacks) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + + A_MEMCPY(&device->htcCallbacks.Context, callbacks, + sizeof(MSG_BASED_HIF_CALLBACKS)); +} + +void HIFDetachHTC(HIF_DEVICE *hifDevice) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + + usb_hif_flush_all(device); + + A_MEMZERO(&device->htcCallbacks, sizeof(MSG_BASED_HIF_CALLBACKS)); +} + +static void usb_hif_destroy(HIF_DEVICE_USB *device) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + usb_hif_flush_all(device); + + usb_hif_cleanup_pipe_resources(device); + + usb_set_intfdata(device->interface, NULL); + + if (device->diag_cmd_buffer != NULL) + adf_os_mem_free(device->diag_cmd_buffer); + + if (device->diag_resp_buffer != NULL) + adf_os_mem_free(device->diag_resp_buffer); + + adf_os_mem_free(device); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +static HIF_DEVICE_USB *usb_hif_create(struct usb_interface *interface) +{ + HIF_DEVICE_USB *device = NULL; + struct usb_device *dev = interface_to_usbdev(interface); + A_STATUS status = A_OK; + int i; + HIF_USB_PIPE *pipe; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + do { + + device = adf_os_mem_alloc(NULL, sizeof(*device)); + if (NULL == device) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("device is NULL\n")); + break; + } + + adf_os_mem_zero(device, sizeof(*device)); + usb_set_intfdata(interface, device); + spin_lock_init(&(device->cs_lock)); + spin_lock_init(&(device->rx_lock)); + spin_lock_init(&(device->tx_lock)); + device->udev = dev; + device->interface = interface; + + for (i = 0; i < HIF_USB_PIPE_MAX; i++) { + pipe = &device->pipes[i]; + INIT_WORK(&pipe->io_complete_work, + usb_hif_io_comp_work); + skb_queue_head_init(&pipe->io_comp_queue); + } + + device->diag_cmd_buffer = adf_os_mem_alloc(NULL, + USB_CTRL_MAX_DIAG_CMD_SIZE); + if (NULL == device->diag_cmd_buffer) { + status = A_NO_MEMORY; + break; + } + device->diag_resp_buffer = adf_os_mem_alloc(NULL, + USB_CTRL_MAX_DIAG_RESP_SIZE); + if (NULL == device->diag_resp_buffer) { + status = A_NO_MEMORY; + break; + } + + status = usb_hif_setup_pipe_resources(device); + + } while (FALSE); + + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("abnormal condition\n")); + usb_hif_destroy(device); + device = NULL; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + return device; +} + +A_STATUS HIFStart(HIF_DEVICE *hifDevice) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + int i; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + usb_hif_start_recv_pipes(device); + + /* set the TX resource avail threshold for each TX pipe */ + for (i = HIF_TX_CTRL_PIPE; i <= HIF_TX_DATA_HP_PIPE; i++) { + device->pipes[i].urb_cnt_thresh = + device->pipes[i].urb_alloc / 2; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + return A_OK; +} + +void HIFStop(HIF_DEVICE *hifDevice) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hifDevice; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + usb_hif_flush_all(device); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void HIFGetDefaultPipe(HIF_DEVICE *hifDevice, a_uint8_t *ULPipe, + a_uint8_t *DLPipe) +{ + *ULPipe = HIF_TX_CTRL_PIPE; + *DLPipe = HIF_RX_CTRL_PIPE; +} + +#if defined(USB_MULTI_IN_TEST) || defined(USB_ISOC_TEST) +int +HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, + a_uint8_t *ULPipe, a_uint8_t *DLPipe, int *ul_is_polled, + int *dl_is_polled) +{ + A_STATUS status = A_OK; + + switch (ServiceId) { + case HTC_CTRL_RSVD_SVC: + case WMI_CONTROL_SVC: + case HTC_RAW_STREAMS_SVC: + *ULPipe = HIF_TX_CTRL_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + case WMI_DATA_BE_SVC: + *ULPipe = HIF_TX_DATA_LP_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + case WMI_DATA_BK_SVC: + *ULPipe = HIF_TX_DATA_MP_PIPE; + *DLPipe = HIF_RX_DATA2_PIPE; + break; + case WMI_DATA_VI_SVC: + *ULPipe = HIF_TX_DATA_HP_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + case WMI_DATA_VO_SVC: + *ULPipe = HIF_TX_DATA_LP_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + default: + status = A_ENOTSUP; + break; + } + + return status; +} +#else +int +HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, + a_uint8_t *ULPipe, a_uint8_t *DLPipe, int *ul_is_polled, + int *dl_is_polled) +{ + A_STATUS status = A_OK; + + switch (ServiceId) { + case HTC_CTRL_RSVD_SVC: + case WMI_CONTROL_SVC: + *ULPipe = HIF_TX_CTRL_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + case WMI_DATA_BE_SVC: + case WMI_DATA_BK_SVC: + *ULPipe = HIF_TX_DATA_LP_PIPE; + if (hif_usb_disable_rxdata2) + *DLPipe = HIF_RX_DATA_PIPE; + else + *DLPipe = HIF_RX_DATA2_PIPE; + break; + case WMI_DATA_VI_SVC: +#ifdef USB_HIF_USE_SINGLE_PIPE_FOR_DATA + *ULPipe = HIF_TX_DATA_LP_PIPE; +#else + *ULPipe = HIF_TX_DATA_MP_PIPE; +#endif + if (hif_usb_disable_rxdata2) + *DLPipe = HIF_RX_DATA_PIPE; + else + *DLPipe = HIF_RX_DATA2_PIPE; + break; + case WMI_DATA_VO_SVC: +#ifdef USB_HIF_USE_SINGLE_PIPE_FOR_DATA + *ULPipe = HIF_TX_DATA_LP_PIPE; +#else + *ULPipe = HIF_TX_DATA_HP_PIPE; +#endif + if (hif_usb_disable_rxdata2) + *DLPipe = HIF_RX_DATA_PIPE; + else + *DLPipe = HIF_RX_DATA2_PIPE; +#ifdef USB_HIF_TEST_INTERRUPT_IN + *DLPipe = HIF_RX_INT_PIPE; +#endif + break; + case HTC_RAW_STREAMS_SVC: + *ULPipe = HIF_TX_CTRL_PIPE; + *DLPipe = HIF_RX_DATA_PIPE; + break; + case HTT_DATA_MSG_SVC: + *ULPipe = HIF_TX_DATA_LP_PIPE; + if (hif_usb_disable_rxdata2) + *DLPipe = HIF_RX_DATA_PIPE; + else + *DLPipe = HIF_RX_DATA2_PIPE; + break; +#ifdef QCA_TX_HTT2_SUPPORT + case HTT_DATA2_MSG_SVC: + *ULPipe = HIF_TX_DATA_HP_PIPE; + if (hif_usb_disable_rxdata2) + *DLPipe = HIF_RX_DATA_PIPE; + else + *DLPipe = HIF_RX_DATA2_PIPE; + break; +#endif /* QCA_TX_HTT2_SUPPORT */ + default: + status = A_ENOTSUP; + break; + } + + return status; +} +#endif + +static A_STATUS HIFCtrlMsgExchange(HIF_DEVICE_USB *macp, + A_UINT8 SendReqVal, + A_UINT8 *pSendMessage, + A_UINT32 Length, + A_UINT8 ResponseReqVal, + A_UINT8 *pResponseMessage, + A_UINT32 *pResponseLength) +{ + A_STATUS status; + + do { + + /* send command */ + status = usb_hif_submit_ctrl_out(macp, SendReqVal, 0, 0, + pSendMessage, Length); + + if (A_FAILED(status)) + break; + + if (NULL == pResponseMessage) { + /* no expected response */ + break; + } + + /* get response */ + status = usb_hif_submit_ctrl_in(macp, ResponseReqVal, 0, 0, + pResponseMessage, + *pResponseLength); + + if (A_FAILED(status)) + break; + + } while (FALSE); + + return status; +} + +A_STATUS HIFExchangeBMIMsg(HIF_DEVICE *device, + A_UINT8 *pSendMessage, + A_UINT32 Length, + A_UINT8 *pResponseMessage, + A_UINT32 *pResponseLength, A_UINT32 TimeoutMS) +{ + HIF_DEVICE_USB *macp = (HIF_DEVICE_USB *) device; + + return HIFCtrlMsgExchange(macp, + USB_CONTROL_REQ_SEND_BMI_CMD, + pSendMessage, + Length, + USB_CONTROL_REQ_RECV_BMI_RESP, + pResponseMessage, pResponseLength); +} + +A_STATUS HIFConfigureDevice(HIF_DEVICE *hif, HIF_DEVICE_CONFIG_OPCODE opcode, + void *config, A_UINT32 configLen) +{ + A_STATUS status = A_OK; + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif; + + switch (opcode) { + + case HIF_DEVICE_GET_OS_DEVICE: + { + HIF_DEVICE_OS_DEVICE_INFO *info = config; + info->pOSDevice = &device->udev->dev; + } + break; + case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: + /* provide fake block sizes for mailboxes to satisfy upper layer + * software + */ + ((A_UINT32 *) config)[0] = 16; + ((A_UINT32 *) config)[1] = 16; + ((A_UINT32 *) config)[2] = 16; + ((A_UINT32 *) config)[3] = 16; + break; + default: + status = A_ENOTSUP; + break; + + } + + return status; +} + +A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device) +{ + return A_OK; +} + +A_STATUS HIFDiagReadAccess(HIF_DEVICE *hifDevice, A_UINT32 address, + A_UINT32 *data) +{ + HIF_DEVICE_USB *macp = (HIF_DEVICE_USB *) hifDevice; + A_STATUS status; + USB_CTRL_DIAG_CMD_READ *cmd; + A_UINT32 respLength; + + cmd = (USB_CTRL_DIAG_CMD_READ *) macp->diag_cmd_buffer; + + A_MEMZERO(cmd, sizeof(*cmd)); + cmd->Cmd = USB_CTRL_DIAG_CC_READ; + cmd->Address = address; + respLength = sizeof(USB_CTRL_DIAG_RESP_READ); + + status = HIFCtrlMsgExchange(macp, + USB_CONTROL_REQ_DIAG_CMD, + (A_UINT8 *) cmd, + sizeof(*cmd), + USB_CONTROL_REQ_DIAG_RESP, + macp->diag_resp_buffer, &respLength); + + if (A_SUCCESS(status)) { + USB_CTRL_DIAG_RESP_READ *pResp = + (USB_CTRL_DIAG_RESP_READ *) macp->diag_resp_buffer; + *data = pResp->ReadValue; + } + + return status; +} + +A_STATUS HIFDiagWriteAccess(HIF_DEVICE *hifDevice, A_UINT32 address, + A_UINT32 data) +{ + HIF_DEVICE_USB *macp = (HIF_DEVICE_USB *) hifDevice; + USB_CTRL_DIAG_CMD_WRITE *cmd; + + cmd = (USB_CTRL_DIAG_CMD_WRITE *) macp->diag_cmd_buffer; + + A_MEMZERO(cmd, sizeof(*cmd)); + cmd->Cmd = USB_CTRL_DIAG_CC_WRITE; + cmd->Address = address; + cmd->Value = data; + + return HIFCtrlMsgExchange(macp, + USB_CONTROL_REQ_DIAG_CMD, + (A_UINT8 *) cmd, + sizeof(*cmd), 0, NULL, 0); +} + +void HIFShutDownDevice(HIF_DEVICE *hif) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + if (NULL == hif) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("full shutdown\n")); + /* this is a full driver shutdown */ + } else { + /* perform any actions to shutdown specific device */ + usb_hif_flush_all(device); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void HIFReleaseDevice(HIF_DEVICE *hif) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + device->claimed_context = NULL; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void HIFClaimDevice(HIF_DEVICE *hif, void *claimedContext) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif; + device->claimed_context = claimedContext; +} + +A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HIFInit\n")); + + A_MEMZERO(&osDrvcallback, sizeof(osDrvcallback)); + + A_REGISTER_MODULE_DEBUG_INFO(hif); + + osDrvcallback.deviceInsertedHandler = callbacks->deviceInsertedHandler; + osDrvcallback.deviceRemovedHandler = callbacks->deviceRemovedHandler; + osDrvcallback.deviceSuspendHandler = callbacks->deviceSuspendHandler; + osDrvcallback.deviceResumeHandler = callbacks->deviceResumeHandler; + osDrvcallback.deviceWakeupHandler = callbacks->deviceWakeupHandler; + osDrvcallback.context = callbacks->context; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HIFInit\n")); + return A_OK; +} + +#ifdef ATH_BUS_PM +void HIFDeviceSuspend(HIF_DEVICE *dev) +{ + HIF_DEVICE_USB *macp = (HIF_DEVICE_USB *) dev; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + if (osDrvcallback.deviceSuspendHandler) + osDrvcallback.deviceSuspendHandler(macp->claimed_context); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void HIFDeviceResume(HIF_DEVICE *dev) +{ + HIF_DEVICE_USB *macp = (HIF_DEVICE_USB *) dev; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + if (osDrvcallback.deviceResumeHandler) + osDrvcallback.deviceResumeHandler(macp->claimed_context); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} +#endif + +void HIFDumpInfo(HIF_DEVICE *hif) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif; + HIF_USB_PIPE *pipe = NULL; + struct usb_host_interface *iface_desc = NULL; + struct usb_endpoint_descriptor *ep_desc; + A_UINT8 i = 0; + for (i = 0; i < HIF_USB_PIPE_MAX; i++) { + pipe = &device->pipes[i]; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "PipeIndex : %d URB Cnt : %d PipeHandle : %x\n", + i, pipe->urb_cnt, + pipe->usb_pipe_handle)); + if (usb_pipeisoc(pipe->usb_pipe_handle)) + pr_info("Pipe Type ISOC\n"); + else if (usb_pipebulk(pipe->usb_pipe_handle)) + pr_info("Pipe Type BULK\n"); + else if (usb_pipeint(pipe->usb_pipe_handle)) + pr_info("Pipe Type INT\n"); + else if (usb_pipecontrol(pipe->usb_pipe_handle)) + pr_info("Pipe Type control\n"); + } + + for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { + ep_desc = &iface_desc->endpoint[i].desc; + if (ep_desc) { + pr_info( + "ep_desc : %p Index : %d: DescType : %d Addr : %d Maxp : %d Atrrib : %d\n", + ep_desc, i, + ep_desc->bDescriptorType, + ep_desc->bEndpointAddress, ep_desc->wMaxPacketSize, + ep_desc->bmAttributes); + if ((ep_desc) + && (usb_endpoint_type(ep_desc) == + USB_ENDPOINT_XFER_ISOC)) { + pr_info("ISOC EP Detected\n"); + } + } + } + +} + +void HIFDump(HIF_DEVICE *hif_device, u_int8_t cmd_id, bool start) +{ +/* TO DO... */ +} + +void HIFFlushSurpriseRemove(HIF_DEVICE *hif_device) +{ +/* TO DO... */ +} + +A_STATUS +HIFDiagReadMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, + int nbytes) +{ + A_STATUS status = EOK; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + if ((address & 0x3) || ((uintptr_t)data & 0x3)) { + return (-EIO); + } + + while ((nbytes >= 4) && + (A_OK == (status = HIFDiagReadAccess(hif_device, address, + (A_UINT32*)data)))) { + + nbytes -= sizeof(A_UINT32); + address += sizeof(A_UINT32); + data += sizeof(A_UINT32); + + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + return status; +} + +A_STATUS +HIFDiagWriteMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes) +{ + A_STATUS status = EOK; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + if ((address & 0x3) || ((uintptr_t)data & 0x3)) { + return (-EIO); + } + + while ((nbytes >= 4) && + (A_OK == (status = HIFDiagWriteAccess(hif_device, address, + *((A_UINT32*)data))))) { + + nbytes -= sizeof(A_UINT32); + address += sizeof(A_UINT32); + data += sizeof(A_UINT32); + + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + return status; +} + +void *hif_get_targetdef(HIF_DEVICE *hif_device) +{ + HIF_DEVICE_USB *device = (HIF_DEVICE_USB *) hif_device; + struct hif_usb_softc *sc = device->sc; + + return sc->targetdef; +} + +void HIFSendCompleteCheck(HIF_DEVICE *hif_device, a_uint8_t pipe, int force) +{ +} + +void HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) +{ +} + +/* diagnostic command defnitions */ +#define USB_CTRL_DIAG_CC_READ 0 +#define USB_CTRL_DIAG_CC_WRITE 1 +#define USB_CTRL_DIAG_CC_WARM_RESET 2 +A_STATUS HIFDiagWriteWARMRESET(struct usb_interface *interface, + A_UINT32 address, A_UINT32 data) +{ + HIF_DEVICE_USB *hHIF_DEV; + A_STATUS status = EOK; + USB_CTRL_DIAG_CMD_WRITE *cmd; + + hHIF_DEV = (HIF_DEVICE_USB *) usb_get_intfdata(interface); + cmd = (USB_CTRL_DIAG_CMD_WRITE *) hHIF_DEV->diag_cmd_buffer; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + A_MEMZERO(cmd, sizeof(USB_CTRL_DIAG_CMD_WRITE)); + cmd->Cmd = USB_CTRL_DIAG_CC_WARM_RESET; + cmd->Address = address; + cmd->Value = data; + + status = HIFCtrlMsgExchange(hHIF_DEV, + USB_CONTROL_REQ_DIAG_CMD, + (A_UINT8 *) cmd, + sizeof(USB_CTRL_DIAG_CMD_WRITE), + 0, NULL, 0); + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("-%s HIFCtrlMsgExchange fail\n", + __func__)); + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + return status; +} +void HIFsuspendwow(HIF_DEVICE *hif_device) +{ + printk(KERN_INFO "HIFsuspendwow TODO\n"); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb_internal.h new file mode 100644 index 0000000000000..e59c013457046 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/hif_usb_internal.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#ifndef _HIF_USB_INTERNAL_H +#define _HIF_USB_INTERNAL_H + +#include +#include + +#include "a_types.h" +#include "athdefs.h" +#include "a_osapi.h" +#include "hif_msg_based.h" +#include "a_usb_defs.h" +#include +#include + +#define TX_URB_COUNT 32 +#define RX_URB_COUNT 32 + +#define HIF_USB_RX_BUFFER_SIZE 2048 +#define HIF_USB_RX_BUNDLE_BUFFER_SIZE 16896 +#define HIF_USB_TX_BUNDLE_BUFFER_SIZE 16384 + +/* USB Endpoint definition */ +typedef enum { + HIF_TX_CTRL_PIPE = 0, + HIF_TX_DATA_LP_PIPE, + HIF_TX_DATA_MP_PIPE, + HIF_TX_DATA_HP_PIPE, + HIF_RX_CTRL_PIPE, + HIF_RX_DATA_PIPE, + HIF_RX_DATA2_PIPE, + HIF_RX_INT_PIPE, + HIF_USB_PIPE_MAX +} HIF_USB_PIPE_ID; + +#define HIF_USB_PIPE_INVALID HIF_USB_PIPE_MAX + +/* debug masks */ +#define USB_HIF_DEBUG_CTRL_TRANS ATH_DEBUG_MAKE_MODULE_MASK(0) +#define USB_HIF_DEBUG_BULK_IN ATH_DEBUG_MAKE_MODULE_MASK(1) +#define USB_HIF_DEBUG_BULK_OUT ATH_DEBUG_MAKE_MODULE_MASK(2) +#define USB_HIF_DEBUG_ENUM ATH_DEBUG_MAKE_MODULE_MASK(3) +#define USB_HIF_DEBUG_DUMP_DATA ATH_DEBUG_MAKE_MODULE_MASK(4) +#define USB_HIF_SUSPEND ATH_DEBUG_MAKE_MODULE_MASK(5) +#define USB_HIF_ISOC_SUPPORT ATH_DEBUG_MAKE_MODULE_MASK(6) +struct _HIF_DEVICE_USB; +struct _HIF_USB_PIPE; + +/* + * Data structure to record required sending context data + */ +struct HIFSendContext { + A_BOOL bNewAlloc; + HIF_DEVICE *pDev; + adf_nbuf_t netbuf; + unsigned int transferID; + unsigned int head_data_len; +}; + +typedef struct _HIF_URB_CONTEXT { + DL_LIST link; + struct _HIF_USB_PIPE *pipe; + adf_nbuf_t buf; + struct urb *urb; + struct sk_buff_head comp_queue; + struct HIFSendContext *pSendContext; +} HIF_URB_CONTEXT; + +#define HIF_USB_PIPE_FLAG_TX (1 << 0) + +typedef struct _HIF_USB_PIPE { + DL_LIST urb_list_head; + DL_LIST urb_pending_list; + A_INT32 urb_alloc; + A_INT32 urb_cnt; + A_INT32 urb_cnt_thresh; + unsigned int usb_pipe_handle; + A_UINT32 flags; + A_UINT8 ep_address; + A_UINT8 logical_pipe_num; + struct _HIF_DEVICE_USB *device; + A_UINT16 max_packet_size; + struct work_struct io_complete_work; + struct sk_buff_head io_comp_queue; + struct usb_endpoint_descriptor *ep_desc; +} HIF_USB_PIPE; + +typedef struct _HIF_DEVICE_USB { + spinlock_t cs_lock; + spinlock_t tx_lock; + spinlock_t rx_lock; + MSG_BASED_HIF_CALLBACKS htcCallbacks; + struct usb_device *udev; + struct usb_interface *interface; + HIF_USB_PIPE pipes[HIF_USB_PIPE_MAX]; + a_uint8_t surpriseRemoved; + a_uint8_t *diag_cmd_buffer; + a_uint8_t *diag_resp_buffer; + void *claimed_context; + struct hif_usb_softc *sc; +} HIF_DEVICE_USB; +extern unsigned int hif_usb_disable_rxdata2; +extern unsigned int htc_bundle_recv; +extern unsigned int htc_bundle_send; + +extern A_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *macp, + a_uint8_t req, + a_uint16_t value, + a_uint16_t index, + void *data, a_uint32_t size); + +extern A_STATUS usb_hif_submit_ctrl_out(HIF_DEVICE_USB *macp, + a_uint8_t req, + a_uint16_t value, + a_uint16_t index, + void *data, a_uint32_t size); + +extern int HIF_USBDeviceInserted(struct usb_interface *interface, + hif_handle_t hif_hdl); +extern void HIF_USBDeviceDetached(struct usb_interface *interface, + a_uint8_t surprise_removed); +#ifdef ATH_BUS_PM +extern void HIFDeviceSuspend(HIF_DEVICE *dev); +extern void HIFDeviceResume(HIF_DEVICE *dev); +#endif +extern A_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device); +extern void usb_hif_cleanup_pipe_resources(HIF_DEVICE_USB *device); +extern void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device); +extern void usb_hif_flush_all(HIF_DEVICE_USB *device); +extern void usb_hif_cleanup_transmit_urb(HIF_URB_CONTEXT *urb_context); +extern void usb_hif_enqueue_pending_transfer(HIF_USB_PIPE *pipe, + HIF_URB_CONTEXT *urb_context); +extern void usb_hif_remove_pending_transfer(HIF_URB_CONTEXT *urb_context); +extern HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(HIF_USB_PIPE *pipe); +extern void usb_hif_io_comp_work(struct work_struct *work); +/* Support for USB Suspend / Resume */ +extern void usb_hif_suspend(struct usb_interface *interface); +extern void usb_hif_resume(struct usb_interface *interface); +A_STATUS HIFDiagWriteWARMRESET(struct usb_interface *interface, + A_UINT32 address, A_UINT32 data); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.c new file mode 100644 index 0000000000000..6cc6c25db1427 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#include +#include +#include +#include +#include +#include "if_usb.h" +#include "hif_usb_internal.h" +#include "bmi_msg.h" /* TARGET_TYPE_ */ +#include "regtable.h" +#include "ol_fw.h" +#include +#include "vos_api.h" +#include "wma_api.h" +#include "wlan_hdd_main.h" +#include "epping_main.h" + +#ifdef WLAN_BTAMP_FEATURE +#include "wlan_btc_svc.h" +#include "wlan_nlink_common.h" +#endif + +#ifndef REMOVE_PKT_LOG +#include "ol_txrx_types.h" +#include "pktlog_ac_api.h" +#include "pktlog_ac.h" +#endif +#define VENDOR_ATHR 0x0CF3 +#define AR9888_DEVICE_ID (0x003c) +#define AR6320_DEVICE_ID (0x9378) +#define DELAY_FOR_TARGET_READY 200 /* 200ms */ +#define DELAY_INT_FOR_HDD_REMOVE 200 /* 200ms */ +#define HIFDiagWriteCOLDRESET(hifdevice) HIFDiagWriteAccess(sc->hif_device, \ + (ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB | \ + ROME_USB_RTC_SOC_BASE_ADDRESS), \ + SOC_RESET_CONTROL_COLD_RST_SET(1)) + +unsigned int msienable; +module_param(msienable, int, 0644); +#define HIF_USB_UNLOAD_TIMEOUT (2*HZ) +enum hif_usb_drv_unload_state { + HIF_USB_UNLOAD_STATE_NULL = 0, + HIF_USB_UNLOAD_STATE_DRV_DEREG, + HIF_USB_UNLOAD_STATE_TARGET_RESET, + HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED, +}; + +static int hif_usb_unload_dev_num = -1; +static wait_queue_head_t hif_usb_unload_event_wq; +static atomic_t hif_usb_unload_state; +struct hif_usb_softc *usb_sc = NULL; +static int hif_usb_resume(struct usb_interface *interface); + +static int +hif_usb_configure(struct hif_usb_softc *sc, hif_handle_t *hif_hdl, + struct usb_interface *interface) +{ + int ret = 0; + struct usb_device *dev = interface_to_usbdev(interface); + + if (HIF_USBDeviceInserted(interface, sc)) { + pr_err("ath: %s: Target probe failed.\n", __func__); + ret = -EIO; + goto err_stalled; + } + + if (athdiag_procfs_init(sc) != 0) { + pr_err("athdiag_procfs_init failed\n"); + return A_ERROR; + } + hif_usb_unload_dev_num = dev->devnum; + *hif_hdl = sc->hif_device; + return 0; + +err_stalled: + + return ret; +} + +static void hif_nointrs(struct hif_usb_softc *sc) +{ +} + +static int hif_usb_reboot(struct notifier_block *nb, unsigned long val, + void *v) +{ + struct hif_usb_softc *sc; + sc = container_of(nb, struct hif_usb_softc, reboot_notifier); + /* do cold reset */ + HIFDiagWriteCOLDRESET(sc->hif_device); + return NOTIFY_DONE; +} + +static int +hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) +{ + int ret = 0; + struct hif_usb_softc *sc; + struct ol_softc *ol_sc; + struct usb_device *pdev = interface_to_usbdev(interface); + int vendor_id, product_id; + + pr_info("hif_usb_probe\n"); + usb_get_dev(pdev); + vendor_id = le16_to_cpu(pdev->descriptor.idVendor); + product_id = le16_to_cpu(pdev->descriptor.idProduct); + + ret = 0; + + sc = A_MALLOC(sizeof(*sc)); + if (!sc) { + ret = -ENOMEM; + goto err_alloc; + } + + OS_MEMZERO(sc, sizeof(*sc)); + sc->pdev = (void *)pdev; + sc->dev = &pdev->dev; + + sc->aps_osdev.bdev = pdev; + sc->aps_osdev.device = &pdev->dev; + sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_AHB; + sc->devid = id->idProduct; + + adf_os_spinlock_init(&sc->target_lock); + + ol_sc = A_MALLOC(sizeof(*ol_sc)); + if (!ol_sc) + goto err_attach; + OS_MEMZERO(ol_sc, sizeof(*ol_sc)); + ol_sc->sc_osdev = &sc->aps_osdev; + ol_sc->hif_sc = (void *)sc; + sc->ol_sc = ol_sc; + + if ((usb_control_msg(pdev, usb_sndctrlpipe(pdev, 0), + USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0, + HZ)) < 0) { + pr_info("%s[%d]\n\r", __func__, __LINE__); + } + usb_set_interface(pdev, 0, 0); + + if (hif_usb_configure(sc, &ol_sc->hif_hdl, interface)) + goto err_config; + + ol_sc->enableuartprint = 1; + ol_sc->enablefwlog = 0; + ol_sc->enablesinglebinary = FALSE; + ol_sc->max_no_of_peers = 1; + + init_waitqueue_head(&ol_sc->sc_osdev->event_queue); + + ret = hdd_wlan_startup(&pdev->dev, ol_sc); + if (ret) { + hif_nointrs(sc); + if (sc->hif_device != NULL) { + ((HIF_DEVICE_USB *)(sc->hif_device))->sc = NULL; + } + athdiag_procfs_remove(); + goto err_config; + } + sc->hdd_removed = 0; + sc->hdd_removed_processing = 0; + sc->hdd_removed_wait_cnt = 0; + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + /* + * pktlog initialization + */ + ol_pl_sethandle(&ol_sc->pdev_txrx_handle->pl_dev, ol_sc); + + if (pktlogmod_init(ol_sc)) + pr_err("%s: pktlogmod_init failed\n", __func__); + } +#endif + +#ifdef WLAN_BTAMP_FEATURE + /* Send WLAN UP indication to Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0); +#endif + + sc->interface = interface; + sc->reboot_notifier.notifier_call = hif_usb_reboot; + register_reboot_notifier(&sc->reboot_notifier); + + usb_sc = sc; + return 0; + +err_config: + A_FREE(ol_sc); +err_attach: + ret = -EIO; + usb_sc = NULL; + A_FREE(sc); +err_alloc: + usb_put_dev(pdev); + + return ret; +} + +static void hif_usb_remove(struct usb_interface *interface) +{ + HIF_DEVICE_USB *device = usb_get_intfdata(interface); + struct hif_usb_softc *sc = device->sc; + struct ol_softc *scn; + + /* Attach did not succeed, all resources have been + * freed in error handler + */ + if (!sc) + return; + /* wait __hdd_wlan_exit until finished and no more than 4 seconds*/ + while(usb_sc->hdd_removed_processing == 1 && + usb_sc->hdd_removed_wait_cnt < 20) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(DELAY_INT_FOR_HDD_REMOVE)); + set_current_state(TASK_RUNNING); + usb_sc->hdd_removed_wait_cnt ++; + } + /* do cold reset */ + HIFDiagWriteCOLDRESET(sc->hif_device); + /* wait for target jump to boot code and finish the initialization */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(DELAY_FOR_TARGET_READY)); + set_current_state(TASK_RUNNING); + if (usb_sc->local_state.event != 0) { + hif_usb_resume(usb_sc->interface); + usb_sc->local_state.event = 0; + } + unregister_reboot_notifier(&sc->reboot_notifier); + usb_put_dev(interface_to_usbdev(interface)); + if (atomic_read(&hif_usb_unload_state) == + HIF_USB_UNLOAD_STATE_DRV_DEREG) + atomic_set(&hif_usb_unload_state, + HIF_USB_UNLOAD_STATE_TARGET_RESET); + scn = sc->ol_sc; + + if (usb_sc->hdd_removed == 0) { + usb_sc->hdd_removed_processing = 1; +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + pktlogmod_exit(scn); +#endif + __hdd_wlan_exit(); + usb_sc->hdd_removed_processing = 0; + usb_sc->hdd_removed = 1; + } + hif_nointrs(sc); + HIF_USBDeviceDetached(interface, 1); + A_FREE(scn); + A_FREE(sc); + usb_sc = NULL; + pr_info("hif_usb_remove!!!!!!\n"); +} + +#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND +void hdd_suspend_wlan(void (*callback) (void *callbackContext), + void *callbackContext); +#endif + +static int hif_usb_suspend(struct usb_interface *interface, pm_message_t state) +{ + HIF_DEVICE_USB *device = usb_get_intfdata(interface); + struct hif_usb_softc *sc = device->sc; + void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + v_VOID_t * temp_module; + + if (vos == NULL) + return 0; + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + return (-1); + } + + if (wma_check_scan_in_progress(temp_module)) { + printk("%s: Scan in progress. Aborting suspend\n", __func__); + return (-1); + } + sc->local_state = state; + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + if (wma_is_wow_mode_selected(temp_module)) { + if (wma_enable_wow_in_fw(temp_module)) { + pr_warn("%s[%d]: fail\n", __func__, __LINE__); + return -1; + } + } else if ((PM_EVENT_FREEZE & state.event) == PM_EVENT_FREEZE || + (PM_EVENT_SUSPEND & state.event) == PM_EVENT_SUSPEND || + (PM_EVENT_HIBERNATE & state.event) == PM_EVENT_HIBERNATE) { + if (wma_suspend_target + (vos_get_context(VOS_MODULE_ID_WDA, vos), 0)) { + pr_warn("%s[%d]: fail\n", __func__, __LINE__); + return -1; + } + } + usb_hif_flush_all(device); + return 0; +} + +#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND +void hdd_resume_wlan(void); +#endif + +static int hif_usb_resume(struct usb_interface *interface) +{ + HIF_DEVICE_USB *device = usb_get_intfdata(interface); + struct hif_usb_softc *sc = device->sc; + void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + v_VOID_t * temp_module; + + if (vos == NULL) + return 0; + /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */ + temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos); + if (!temp_module) { + printk("%s: WDA module is NULL\n", __func__); + return (-1); + } + + if (wma_check_scan_in_progress(temp_module)) { + printk("%s: Scan in progress. Aborting suspend\n", __func__); + return (-1); + } + sc->local_state.event = 0; + usb_hif_start_recv_pipes(device); + +#ifdef USB_HIF_TEST_INTERRUPT_IN + usb_hif_post_recv_transfers(&device->pipes[HIF_RX_INT_PIPE], + HIF_USB_RX_BUFFER_SIZE); +#endif + /* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */ + if (!wma_is_wow_mode_selected(temp_module)) { + wma_resume_target(temp_module); + } else if (wma_disable_wow_in_fw(temp_module)) { + return (-1); + } + + return 0; +} + +static int hif_usb_reset_resume(struct usb_interface *intf) +{ + HIF_DEVICE_USB *device = usb_get_intfdata(intf); + struct hif_usb_softc *sc = device->sc; + + HIFDiagWriteCOLDRESET(sc->hif_device); + + return 0; +} + +static struct usb_device_id hif_usb_id_table[] = { + {USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ATHR, 0x9378, 0xFF, 0xFF, 0xFF)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, hif_usb_id_table); +struct usb_driver hif_usb_drv_id = { + + .name = "hif_usb", + .id_table = hif_usb_id_table, + .probe = hif_usb_probe, + .disconnect = hif_usb_remove, +#ifdef ATH_BUS_PM + .suspend = hif_usb_suspend, + .resume = hif_usb_resume, + .reset_resume = hif_usb_reset_resume, +#endif + .supports_autosuspend = true, +}; + +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + struct hif_usb_softc *hif_sc = (struct hif_usb_softc *)sc->hif_sc; + adf_dev->drv = &hif_sc->aps_osdev; + adf_dev->drv_hdl = hif_sc->aps_osdev.bdev; + adf_dev->dev = hif_sc->aps_osdev.device; + sc->adf_dev = adf_dev; +} + +void hif_deinit_adf_ctx(void *ol_sc) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + sc->adf_dev = NULL; +} + +static int hif_usb_dev_notify(struct notifier_block *nb, + unsigned long action, void *dev) +{ + struct usb_device *udev; + int ret = NOTIFY_DONE; + + if (action != USB_DEVICE_REMOVE) + goto done; + + udev = (struct usb_device *) dev; + if (hif_usb_unload_dev_num != udev->devnum) + goto done; + + if (atomic_read(&hif_usb_unload_state) == + HIF_USB_UNLOAD_STATE_TARGET_RESET) { + atomic_set(&hif_usb_unload_state, + HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED); + wake_up(&hif_usb_unload_event_wq); + } + +done: + return ret; +} + +static struct notifier_block hif_usb_dev_nb = { + .notifier_call = hif_usb_dev_notify, +}; +static int is_usb_driver_register = 0; +int hif_register_driver(void) +{ + is_usb_driver_register = 1; + init_waitqueue_head(&hif_usb_unload_event_wq); + atomic_set(&hif_usb_unload_state, HIF_USB_UNLOAD_STATE_NULL); + usb_register_notify(&hif_usb_dev_nb); + return usb_register(&hif_usb_drv_id); +} + +void hif_unregister_driver(void) +{ + if (is_usb_driver_register) { + long timeleft = 0; + if (usb_sc != NULL) { + /* wait __hdd_wlan_exit until finished and no more than + * 4 seconds + */ + while(usb_sc->hdd_removed_processing == 1 && + usb_sc->hdd_removed_wait_cnt < 20) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies( + DELAY_INT_FOR_HDD_REMOVE)); + set_current_state(TASK_RUNNING); + usb_sc->hdd_removed_wait_cnt ++; + } + if (usb_sc->local_state.event != 0) { + hif_usb_resume(usb_sc->interface); + usb_sc->local_state.event = 0; + } + + if (usb_sc->hdd_removed == 0) { + usb_sc->hdd_removed_processing = 1; +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + pktlogmod_exit(usb_sc->ol_sc); +#endif + __hdd_wlan_exit(); + usb_sc->hdd_removed_processing = 0; + usb_sc->hdd_removed = 1; + } + } + is_usb_driver_register = 0; + atomic_set(&hif_usb_unload_state, + HIF_USB_UNLOAD_STATE_DRV_DEREG); + usb_deregister(&hif_usb_drv_id); + if (atomic_read(&hif_usb_unload_state) != + HIF_USB_UNLOAD_STATE_TARGET_RESET) + goto finish; + timeleft = wait_event_interruptible_timeout( + hif_usb_unload_event_wq, + atomic_read(&hif_usb_unload_state) == + HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED, + HIF_USB_UNLOAD_TIMEOUT); + if (timeleft <= 0) + pr_err("Fail to wait from DRV_DEREG to DISCONNECT," + "timeleft = %ld \n\r", + timeleft); +finish: + usb_unregister_notify(&hif_usb_dev_nb); + } +} + +/* Function to set the TXRX handle in the ol_sc context */ +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + sc->pdev_txrx_handle = txrx_handle; +} + +void hif_disable_isr(void *ol_sc) +{ + /* TODO */ +} + +/* Function to reset SoC */ +void hif_reset_soc(void *ol_sc) +{ + /* TODO */ +} + +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) +{ + u_int32_t hif_type, target_type; + A_STATUS rv; + A_INT32 ret = 0; + A_UINT32 chip_id; + struct hif_usb_softc *sc; + + sc = ((struct ol_softc *)ol_sc)->hif_sc; + if (sc->hostdef == NULL && sc->targetdef == NULL) { + switch (((struct ol_softc *)ol_sc)->target_type) + { + case TARGET_TYPE_AR6320: + switch(((struct ol_softc *)ol_sc)->target_version) { + case AR6320_REV1_VERSION: + case AR6320_REV1_1_VERSION: + case AR6320_REV1_3_VERSION: + hif_type = HIF_TYPE_AR6320; + target_type = TARGET_TYPE_AR6320; + break; + case AR6320_REV2_1_VERSION: + case AR6320_REV3_VERSION: + case AR6320_REV3_2_VERSION: + hif_type = HIF_TYPE_AR6320V2; + target_type = TARGET_TYPE_AR6320V2; + break; + default: + ret = -1; + break; + } + break; + default: + ret = -1; + break; + } + + if (!ret) { + /* assign target register table if we find corresponding type */ + hif_register_tbl_attach(sc, hif_type); + target_register_tbl_attach(sc, target_type); + /* read the chip revision*/ + rv = HIFDiagReadAccess(sc->hif_device, (CHIP_ID_ADDRESS | RTC_SOC_BASE_ADDRESS), &chip_id); + if (rv != A_OK) { + pr_err("ath: HIF_PCIDeviceProbed get chip id val (%d)\n", rv); + } + ((struct ol_softc *)ol_sc)->target_revision = CHIP_ID_REVISION_GET(chip_id); + } + } + + /* we need to get chip revision here */ + *version = ((struct ol_softc *)ol_sc)->target_version; + /* Chip version should be supported, set to 0 for now */ + *revision = ((struct ol_softc *)ol_sc)->target_revision; +} + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.h new file mode 100644 index 0000000000000..cfdf4e76c8f2c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/if_usb.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#ifndef __ATH_USB_H__ +#define __ATH_USB_H__ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +#include +#else +#include +#endif +#include +#include + +/* + * There may be some pending tx frames during platform suspend. + * Suspend operation should be delayed until those tx frames are + * transfered from the host to target. This macro specifies how + * long suspend thread has to sleep before checking pending tx + * frame count. + */ +#define OL_ATH_TX_DRAIN_WAIT_DELAY 50 /* ms */ +/* + * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending + * tx frame completion before suspend. Refer: hif_pci_suspend() + */ +#define OL_ATH_TX_DRAIN_WAIT_CNT 10 + +#define CONFIG_COPY_ENGINE_SUPPORT /* TBDXXX: here for now */ +#define ATH_DBG_DEFAULT 0 +#include +#include +#include +#include "osapi_linux.h" +#include "hif.h" + +struct hif_usb_softc { + /* For efficiency, should be first in struct */ + struct device *dev; + struct usb_dev *pdev; + struct _NIC_DEV aps_osdev; + struct ol_softc *ol_sc; + /* + * Guard changes to Target HW state and to software + * structures that track hardware state. + */ + adf_os_spinlock_t target_lock; + + HIF_DEVICE *hif_device; + + u16 devid; + struct targetdef_s *targetdef; + struct hostdef_s *hostdef; + struct usb_interface *interface; + struct notifier_block reboot_notifier; /* default mode before reboot */ + pm_message_t local_state; + int hdd_removed; + int hdd_removed_processing; + int hdd_removed_wait_cnt; + u8 *fw_data; + u32 fw_data_len; +}; +#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) +int athdiag_procfs_init(void *scn); +void athdiag_procfs_remove(void); +#else +static inline int athdiag_procfs_init(void *scn) { return 0; } +static inline void athdiag_procfs_remove(void) { return; } +#endif + +#ifndef REMOVE_PKT_LOG +extern int pktlogmod_init(void *context); +extern void pktlogmod_exit(void *context); +#endif + +/*These functions are exposed to HDD*/ +int hif_register_driver(void); +void hif_unregister_driver(void); +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); +void hif_disable_isr(void *ol_sc); +void hif_reset_soc(void *ol_sc); +void hif_deinit_adf_ctx(void *ol_sc); + +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +void hif_set_fw_info(void *ol_sc, u32 target_fw_version); +#endif /* __ATH_USB_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.c new file mode 100644 index 0000000000000..2f2d5b0d0fef0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "bmi_msg.h" +#include "targaddrs.h" +#include "regtable.h" +#include "ar9888def.h" +#include "ar6320def.h" +#include "ar6320v2def.h" + +void target_register_tbl_attach(struct hif_usb_softc *sc, u32 target_type) +{ + switch (target_type) { + case TARGET_TYPE_AR9888: + sc->targetdef = &ar9888_targetdef; + break; + case TARGET_TYPE_AR6320: + sc->targetdef = &ar6320_targetdef; + break; + case TARGET_TYPE_AR6320V2: + sc->targetdef = &ar6320v2_targetdef; + break; + default: + break; + } +} + +void hif_register_tbl_attach(struct hif_usb_softc *sc, u32 hif_type) +{ + switch (hif_type) { + case HIF_TYPE_AR9888: + sc->hostdef = &ar9888_hostdef; + break; + case HIF_TYPE_AR6320: + sc->hostdef = &ar6320_hostdef; + break; + case HIF_TYPE_AR6320V2: + sc->hostdef = &ar6320v2_hostdef; + break; + default: + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.h new file mode 100644 index 0000000000000..74ce65165fa36 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/regtable.h @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#ifndef _REGTABLE_H_ +#define _REGTABLE_H_ +#include "if_usb.h" + +#define MISSING 0 + +typedef struct targetdef_s { + u_int32_t d_RTC_SOC_BASE_ADDRESS; + u_int32_t d_RTC_WMAC_BASE_ADDRESS; + u_int32_t d_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_LSB; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_MASK; + u_int32_t d_CLOCK_CONTROL_OFFSET; + u_int32_t d_CLOCK_CONTROL_SI0_CLK_MASK; + u_int32_t d_RESET_CONTROL_OFFSET; + u_int32_t d_RESET_CONTROL_MBOX_RST_MASK; + u_int32_t d_RESET_CONTROL_SI0_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_OFFSET; + u_int32_t d_WLAN_RESET_CONTROL_COLD_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_WARM_RST_MASK; + u_int32_t d_GPIO_BASE_ADDRESS; + u_int32_t d_GPIO_PIN0_OFFSET; + u_int32_t d_GPIO_PIN1_OFFSET; + u_int32_t d_GPIO_PIN0_CONFIG_MASK; + u_int32_t d_GPIO_PIN1_CONFIG_MASK; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_LSB; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_MASK; + u_int32_t d_SI_CONFIG_I2C_LSB; + u_int32_t d_SI_CONFIG_I2C_MASK; + u_int32_t d_SI_CONFIG_POS_SAMPLE_LSB; + u_int32_t d_SI_CONFIG_POS_SAMPLE_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_MASK; + u_int32_t d_SI_CONFIG_DIVIDER_LSB; + u_int32_t d_SI_CONFIG_DIVIDER_MASK; + u_int32_t d_SI_BASE_ADDRESS; + u_int32_t d_SI_CONFIG_OFFSET; + u_int32_t d_SI_TX_DATA0_OFFSET; + u_int32_t d_SI_TX_DATA1_OFFSET; + u_int32_t d_SI_RX_DATA0_OFFSET; + u_int32_t d_SI_RX_DATA1_OFFSET; + u_int32_t d_SI_CS_OFFSET; + u_int32_t d_SI_CS_DONE_ERR_MASK; + u_int32_t d_SI_CS_DONE_INT_MASK; + u_int32_t d_SI_CS_START_LSB; + u_int32_t d_SI_CS_START_MASK; + u_int32_t d_SI_CS_RX_CNT_LSB; + u_int32_t d_SI_CS_RX_CNT_MASK; + u_int32_t d_SI_CS_TX_CNT_LSB; + u_int32_t d_SI_CS_TX_CNT_MASK; + u_int32_t d_BOARD_DATA_SZ; + u_int32_t d_BOARD_EXT_DATA_SZ; + u_int32_t d_MBOX_BASE_ADDRESS; + u_int32_t d_LOCAL_SCRATCH_OFFSET; + u_int32_t d_CPU_CLOCK_OFFSET; + u_int32_t d_LPO_CAL_OFFSET; + u_int32_t d_GPIO_PIN10_OFFSET; + u_int32_t d_GPIO_PIN11_OFFSET; + u_int32_t d_GPIO_PIN12_OFFSET; + u_int32_t d_GPIO_PIN13_OFFSET; + u_int32_t d_CLOCK_GPIO_OFFSET; + u_int32_t d_CPU_CLOCK_STANDARD_LSB; + u_int32_t d_CPU_CLOCK_STANDARD_MASK; + u_int32_t d_LPO_CAL_ENABLE_LSB; + u_int32_t d_LPO_CAL_ENABLE_MASK; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK; + u_int32_t d_ANALOG_INTF_BASE_ADDRESS; + u_int32_t d_WLAN_MAC_BASE_ADDRESS; + u_int32_t d_CE0_BASE_ADDRESS; + u_int32_t d_CE1_BASE_ADDRESS; + u_int32_t d_FW_INDICATOR_ADDRESS; + u_int32_t d_DRAM_BASE_ADDRESS; + u_int32_t d_SOC_CORE_BASE_ADDRESS; + u_int32_t d_CORE_CTRL_ADDRESS; + u_int32_t d_CE_COUNT; + u_int32_t d_MSI_NUM_REQUEST; + u_int32_t d_MSI_ASSIGN_FW; + u_int32_t d_MSI_ASSIGN_CE_INITIAL; + u_int32_t d_PCIE_INTR_ENABLE_ADDRESS; + u_int32_t d_PCIE_INTR_CLR_ADDRESS; + u_int32_t d_PCIE_INTR_FIRMWARE_MASK; + u_int32_t d_PCIE_INTR_CE_MASK_ALL; + u_int32_t d_CORE_CTRL_CPU_INTR_MASK; + u_int32_t d_SR_WR_INDEX_ADDRESS; + u_int32_t d_DST_WATERMARK_ADDRESS; + + /* htt_rx.c */ + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_LSB; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_MASK; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_MASK; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_LSB; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_LSB; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_MASK; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_LSB; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_MASK; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_LSB; + u_int32_t d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_MASK; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_LSB; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_MASK; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_LSB; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_MASK; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_LSB; + u_int32_t d_RX_ATTENTION_0_MORE_DATA_MASK; + u_int32_t d_RX_ATTENTION_0_MSDU_DONE_MASK; + u_int32_t d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK; + /* end */ + /* copy_engine.c */ + u_int32_t d_DST_WR_INDEX_ADDRESS; + u_int32_t d_SRC_WATERMARK_ADDRESS; + u_int32_t d_SRC_WATERMARK_LOW_MASK; + u_int32_t d_SRC_WATERMARK_HIGH_MASK; + u_int32_t d_DST_WATERMARK_LOW_MASK; + u_int32_t d_DST_WATERMARK_HIGH_MASK; + u_int32_t d_CURRENT_SRRI_ADDRESS; + u_int32_t d_CURRENT_DRRI_ADDRESS; + u_int32_t d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_ADDRESS; + u_int32_t d_HOST_IS_COPY_COMPLETE_MASK; + u_int32_t d_CE_WRAPPER_BASE_ADDRESS; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS; + u_int32_t d_HOST_IE_ADDRESS; + u_int32_t d_HOST_IE_COPY_COMPLETE_MASK; + u_int32_t d_SR_BA_ADDRESS; + u_int32_t d_SR_SIZE_ADDRESS; + u_int32_t d_CE_CTRL1_ADDRESS; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_MASK; + u_int32_t d_DR_BA_ADDRESS; + u_int32_t d_DR_SIZE_ADDRESS; + u_int32_t d_MISC_IE_ADDRESS; + u_int32_t d_MISC_IS_AXI_ERR_MASK; + u_int32_t d_MISC_IS_DST_ADDR_ERR_MASK; + u_int32_t d_MISC_IS_SRC_LEN_ERR_MASK; + u_int32_t d_MISC_IS_DST_MAX_LEN_VIO_MASK; + u_int32_t d_MISC_IS_DST_RING_OVERFLOW_MASK; + u_int32_t d_MISC_IS_SRC_RING_OVERFLOW_MASK; + u_int32_t d_SRC_WATERMARK_LOW_LSB; + u_int32_t d_SRC_WATERMARK_HIGH_LSB; + u_int32_t d_DST_WATERMARK_LOW_LSB; + u_int32_t d_DST_WATERMARK_HIGH_LSB; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_LSB; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_OFFSET; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_LSB; + u_int32_t d_WLAN_DEBUG_INPUT_SEL_SRC_MASK; + u_int32_t d_WLAN_DEBUG_CONTROL_OFFSET; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MSB; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_LSB; + u_int32_t d_WLAN_DEBUG_CONTROL_ENABLE_MASK; + u_int32_t d_WLAN_DEBUG_OUT_OFFSET; + u_int32_t d_WLAN_DEBUG_OUT_DATA_MSB; + u_int32_t d_WLAN_DEBUG_OUT_DATA_LSB; + u_int32_t d_WLAN_DEBUG_OUT_DATA_MASK; + u_int32_t d_AMBA_DEBUG_BUS_OFFSET; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB; + u_int32_t d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK; + u_int32_t d_AMBA_DEBUG_BUS_SEL_MSB; + u_int32_t d_AMBA_DEBUG_BUS_SEL_LSB; + u_int32_t d_AMBA_DEBUG_BUS_SEL_MASK; + u_int32_t d_CE_WRAPPER_DEBUG_OFFSET; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_MSB; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_LSB; + u_int32_t d_CE_WRAPPER_DEBUG_SEL_MASK; + u_int32_t d_CE_DEBUG_OFFSET; + u_int32_t d_CE_DEBUG_SEL_MSB; + u_int32_t d_CE_DEBUG_SEL_LSB; + u_int32_t d_CE_DEBUG_SEL_MASK; + /* end */ + /* PLL start */ + u_int32_t d_EFUSE_OFFSET; + u_int32_t d_EFUSE_XTAL_SEL_MSB; + u_int32_t d_EFUSE_XTAL_SEL_LSB; + u_int32_t d_EFUSE_XTAL_SEL_MASK; + u_int32_t d_BB_PLL_CONFIG_OFFSET; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_MSB; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_LSB; + u_int32_t d_BB_PLL_CONFIG_OUTDIV_MASK; + u_int32_t d_BB_PLL_CONFIG_FRAC_MSB; + u_int32_t d_BB_PLL_CONFIG_FRAC_LSB; + u_int32_t d_BB_PLL_CONFIG_FRAC_MASK; + u_int32_t d_WLAN_PLL_SETTLE_TIME_MSB; + u_int32_t d_WLAN_PLL_SETTLE_TIME_LSB; + u_int32_t d_WLAN_PLL_SETTLE_TIME_MASK; + u_int32_t d_WLAN_PLL_SETTLE_OFFSET; + u_int32_t d_WLAN_PLL_SETTLE_SW_MASK; + u_int32_t d_WLAN_PLL_SETTLE_RSTMASK; + u_int32_t d_WLAN_PLL_SETTLE_RESET; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MSB; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_LSB; + u_int32_t d_WLAN_PLL_CONTROL_NOPWD_MASK; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MSB; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_LSB; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_MASK; + u_int32_t d_WLAN_PLL_CONTROL_BYPASS_RESET; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MSB; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_LSB; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_MASK; + u_int32_t d_WLAN_PLL_CONTROL_CLK_SEL_RESET; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MSB; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_LSB; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_MASK; + u_int32_t d_WLAN_PLL_CONTROL_REFDIV_RESET; + u_int32_t d_WLAN_PLL_CONTROL_DIV_MSB; + u_int32_t d_WLAN_PLL_CONTROL_DIV_LSB; + u_int32_t d_WLAN_PLL_CONTROL_DIV_MASK; + u_int32_t d_WLAN_PLL_CONTROL_DIV_RESET; + u_int32_t d_WLAN_PLL_CONTROL_OFFSET; + u_int32_t d_WLAN_PLL_CONTROL_SW_MASK; + u_int32_t d_WLAN_PLL_CONTROL_RSTMASK; + u_int32_t d_WLAN_PLL_CONTROL_RESET; + u_int32_t d_SOC_CORE_CLK_CTRL_OFFSET; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MSB; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_LSB; + u_int32_t d_SOC_CORE_CLK_CTRL_DIV_MASK; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MSB; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_LSB; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_MASK; + u_int32_t d_RTC_SYNC_STATUS_PLL_CHANGING_RESET; + u_int32_t d_RTC_SYNC_STATUS_OFFSET; + u_int32_t d_SOC_CPU_CLOCK_OFFSET; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_MSB; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_LSB; + u_int32_t d_SOC_CPU_CLOCK_STANDARD_MASK; + /* PLL end */ + u_int32_t d_SOC_POWER_REG_OFFSET; + u_int32_t d_PCIE_INTR_CAUSE_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB; + u_int32_t d_SOC_RESET_CONTROL_CE_RST_MASK; + u_int32_t d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK; + u_int32_t d_CPU_INTR_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK; + /* chip id start */ + u_int32_t d_SOC_CHIP_ID_ADDRESS; + u_int32_t d_SOC_CHIP_ID_VERSION_MASK; + u_int32_t d_SOC_CHIP_ID_VERSION_LSB; + u_int32_t d_SOC_CHIP_ID_REVISION_MASK; + u_int32_t d_SOC_CHIP_ID_REVISION_LSB; + /* chip id end */ +} TARGET_REGISTER_TABLE; + +#define RTC_SOC_BASE_ADDRESS (sc->targetdef->d_RTC_SOC_BASE_ADDRESS) +#define RTC_WMAC_BASE_ADDRESS (sc->targetdef->d_RTC_WMAC_BASE_ADDRESS) +#define SYSTEM_SLEEP_OFFSET (sc->targetdef->d_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_OFFSET (sc->targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB) +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define CLOCK_CONTROL_OFFSET (sc->targetdef->d_CLOCK_CONTROL_OFFSET) +#define CLOCK_CONTROL_SI0_CLK_MASK (sc->targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK) +#define RESET_CONTROL_OFFSET (sc->targetdef->d_RESET_CONTROL_OFFSET) +#define RESET_CONTROL_MBOX_RST_MASK (sc->targetdef->d_RESET_CONTROL_MBOX_RST_MASK) +#define RESET_CONTROL_SI0_RST_MASK (sc->targetdef->d_RESET_CONTROL_SI0_RST_MASK) +#define WLAN_RESET_CONTROL_OFFSET (sc->targetdef->d_WLAN_RESET_CONTROL_OFFSET) +#define WLAN_RESET_CONTROL_COLD_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_WARM_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK) +#define GPIO_BASE_ADDRESS (sc->targetdef->d_GPIO_BASE_ADDRESS) +#define GPIO_PIN0_OFFSET (sc->targetdef->d_GPIO_PIN0_OFFSET) +#define GPIO_PIN1_OFFSET (sc->targetdef->d_GPIO_PIN1_OFFSET) +#define GPIO_PIN0_CONFIG_MASK (sc->targetdef->d_GPIO_PIN0_CONFIG_MASK) +#define GPIO_PIN1_CONFIG_MASK (sc->targetdef->d_GPIO_PIN1_CONFIG_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_LSB (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB) +#define SI_CONFIG_BIDIR_OD_DATA_MASK (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_LSB (sc->targetdef->d_SI_CONFIG_I2C_LSB) +#define SI_CONFIG_I2C_MASK (sc->targetdef->d_SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_LSB (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_LSB) +#define SI_CONFIG_POS_SAMPLE_MASK (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB) +#define SI_CONFIG_INACTIVE_CLK_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB) +#define SI_CONFIG_INACTIVE_DATA_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_LSB (sc->targetdef->d_SI_CONFIG_DIVIDER_LSB) +#define SI_CONFIG_DIVIDER_MASK (sc->targetdef->d_SI_CONFIG_DIVIDER_MASK) +#define SI_BASE_ADDRESS (sc->targetdef->d_SI_BASE_ADDRESS) +#define SI_CONFIG_OFFSET (sc->targetdef->d_SI_CONFIG_OFFSET) +#define SI_TX_DATA0_OFFSET (sc->targetdef->d_SI_TX_DATA0_OFFSET) +#define SI_TX_DATA1_OFFSET (sc->targetdef->d_SI_TX_DATA1_OFFSET) +#define SI_RX_DATA0_OFFSET (sc->targetdef->d_SI_RX_DATA0_OFFSET) +#define SI_RX_DATA1_OFFSET (sc->targetdef->d_SI_RX_DATA1_OFFSET) +#define SI_CS_OFFSET (sc->targetdef->d_SI_CS_OFFSET) +#define SI_CS_DONE_ERR_MASK (sc->targetdef->d_SI_CS_DONE_ERR_MASK) +#define SI_CS_DONE_INT_MASK (sc->targetdef->d_SI_CS_DONE_INT_MASK) +#define SI_CS_START_LSB (sc->targetdef->d_SI_CS_START_LSB) +#define SI_CS_START_MASK (sc->targetdef->d_SI_CS_START_MASK) +#define SI_CS_RX_CNT_LSB (sc->targetdef->d_SI_CS_RX_CNT_LSB) +#define SI_CS_RX_CNT_MASK (sc->targetdef->d_SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_LSB (sc->targetdef->d_SI_CS_TX_CNT_LSB) +#define SI_CS_TX_CNT_MASK (sc->targetdef->d_SI_CS_TX_CNT_MASK) +#define EEPROM_SZ (sc->targetdef->d_BOARD_DATA_SZ) +#define EEPROM_EXT_SZ (sc->targetdef->d_BOARD_EXT_DATA_SZ) +#define MBOX_BASE_ADDRESS (sc->targetdef->d_MBOX_BASE_ADDRESS) +#define LOCAL_SCRATCH_OFFSET (sc->targetdef->d_LOCAL_SCRATCH_OFFSET) +#define CPU_CLOCK_OFFSET (sc->targetdef->d_CPU_CLOCK_OFFSET) +#define LPO_CAL_OFFSET (sc->targetdef->d_LPO_CAL_OFFSET) +#define GPIO_PIN10_OFFSET (sc->targetdef->d_GPIO_PIN10_OFFSET) +#define GPIO_PIN11_OFFSET (sc->targetdef->d_GPIO_PIN11_OFFSET) +#define GPIO_PIN12_OFFSET (sc->targetdef->d_GPIO_PIN12_OFFSET) +#define GPIO_PIN13_OFFSET (sc->targetdef->d_GPIO_PIN13_OFFSET) +#define CLOCK_GPIO_OFFSET (sc->targetdef->d_CLOCK_GPIO_OFFSET) +#define CPU_CLOCK_STANDARD_LSB (sc->targetdef->d_CPU_CLOCK_STANDARD_LSB) +#define CPU_CLOCK_STANDARD_MASK (sc->targetdef->d_CPU_CLOCK_STANDARD_MASK) +#define LPO_CAL_ENABLE_LSB (sc->targetdef->d_LPO_CAL_ENABLE_LSB) +#define LPO_CAL_ENABLE_MASK (sc->targetdef->d_LPO_CAL_ENABLE_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB) +#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +#define ANALOG_INTF_BASE_ADDRESS (sc->targetdef->d_ANALOG_INTF_BASE_ADDRESS) +#define WLAN_MAC_BASE_ADDRESS (sc->targetdef->d_WLAN_MAC_BASE_ADDRESS) +#define CE0_BASE_ADDRESS (sc->targetdef->d_CE0_BASE_ADDRESS) +#define CE1_BASE_ADDRESS (sc->targetdef->d_CE1_BASE_ADDRESS) +#define FW_INDICATOR_ADDRESS (sc->targetdef->d_FW_INDICATOR_ADDRESS) +#define DRAM_BASE_ADDRESS (sc->targetdef->d_DRAM_BASE_ADDRESS) +#define SOC_CORE_BASE_ADDRESS (sc->targetdef->d_SOC_CORE_BASE_ADDRESS) +#define CORE_CTRL_ADDRESS (sc->targetdef->d_CORE_CTRL_ADDRESS) +#define CE_COUNT (sc->targetdef->d_CE_COUNT) +#define PCIE_INTR_ENABLE_ADDRESS (sc->targetdef->d_PCIE_INTR_ENABLE_ADDRESS) +#define PCIE_INTR_CLR_ADDRESS (sc->targetdef->d_PCIE_INTR_CLR_ADDRESS) +#define PCIE_INTR_FIRMWARE_MASK (sc->targetdef->d_PCIE_INTR_FIRMWARE_MASK) +#define PCIE_INTR_CE_MASK_ALL (sc->targetdef->d_PCIE_INTR_CE_MASK_ALL) +#define CORE_CTRL_CPU_INTR_MASK (sc->targetdef->d_CORE_CTRL_CPU_INTR_MASK) +#define PCIE_INTR_CAUSE_ADDRESS (sc->targetdef->d_PCIE_INTR_CAUSE_ADDRESS) +#define SOC_RESET_CONTROL_ADDRESS (sc->targetdef->d_SOC_RESET_CONTROL_ADDRESS) +#define SOC_RESET_CONTROL_CE_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CE_RST_MASK) +#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK) +#define CPU_INTR_ADDRESS (sc->targetdef->d_CPU_INTR_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ADDRESS (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB (sc->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK (sc->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) (((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) (((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +/* hif_pci.c */ +#define CHIP_ID_ADDRESS (sc->targetdef->d_SOC_CHIP_ID_ADDRESS) +#define SOC_CHIP_ID_REVISION_MASK (sc->targetdef->d_SOC_CHIP_ID_REVISION_MASK) +#define SOC_CHIP_ID_REVISION_LSB (sc->targetdef->d_SOC_CHIP_ID_REVISION_LSB) +#define SOC_CHIP_ID_VERSION_MASK (sc->targetdef->d_SOC_CHIP_ID_VERSION_MASK) +#define SOC_CHIP_ID_VERSION_LSB (sc->targetdef->d_SOC_CHIP_ID_VERSION_LSB) +#define CHIP_ID_REVISION_GET(x) (((x) & SOC_CHIP_ID_REVISION_MASK) >> SOC_CHIP_ID_REVISION_LSB) +#define CHIP_ID_VERSION_GET(x) (((x) & SOC_CHIP_ID_VERSION_MASK) >> SOC_CHIP_ID_VERSION_LSB) +/* hif_pci.c end */ + +/* misc */ +#define SR_WR_INDEX_ADDRESS (sc->targetdef->d_SR_WR_INDEX_ADDRESS) +#define DST_WATERMARK_ADDRESS (sc->targetdef->d_DST_WATERMARK_ADDRESS) +#define SOC_POWER_REG_OFFSET (sc->targetdef->d_SOC_POWER_REG_OFFSET) +/* end */ + +/* htt_rx.c */ +#define RX_MSDU_END_4_FIRST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_MASK) +#define RX_MSDU_END_4_FIRST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_LSB) +#define RX_MPDU_START_0_SEQ_NUM_MASK (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_MASK) +#define RX_MPDU_START_0_SEQ_NUM_LSB (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_LSB) +#define RX_MPDU_START_2_PN_47_32_LSB (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_LSB) +#define RX_MPDU_START_2_PN_47_32_MASK (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_MASK (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_LSB (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_LSB) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB) +#define RX_MSDU_END_4_LAST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_MASK) +#define RX_MSDU_END_4_LAST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_LSB) +#define RX_ATTENTION_0_MCAST_BCAST_MASK (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_MASK) +#define RX_ATTENTION_0_MCAST_BCAST_LSB (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_LSB) +#define RX_ATTENTION_0_FRAGMENT_MASK (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_MASK) +#define RX_ATTENTION_0_FRAGMENT_LSB (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_LSB) +#define RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK (pdev->targetdef->d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB) +#define RX_MSDU_START_0_MSDU_LENGTH_MASK (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_MASK) +#define RX_MSDU_START_0_MSDU_LENGTH_LSB (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_LSB) +#define RX_MSDU_START_2_DECAP_FORMAT_OFFSET (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET) +#define RX_MSDU_START_2_DECAP_FORMAT_MASK (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_MASK) +#define RX_MSDU_START_2_DECAP_FORMAT_LSB (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_LSB) +#define RX_MPDU_START_0_ENCRYPTED_MASK (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_MASK) +#define RX_MPDU_START_0_ENCRYPTED_LSB (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_LSB) +#define RX_ATTENTION_0_MORE_DATA_MASK (pdev->targetdef->d_RX_ATTENTION_0_MORE_DATA_MASK) +#define RX_ATTENTION_0_MSDU_DONE_MASK (pdev->targetdef->d_RX_ATTENTION_0_MSDU_DONE_MASK) +#define RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK (pdev->targetdef->d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK) +/* end */ + +/* copy_engine.c */ +#define DST_WR_INDEX_ADDRESS (sc->targetdef->d_DST_WR_INDEX_ADDRESS) +#define SRC_WATERMARK_ADDRESS (sc->targetdef->d_SRC_WATERMARK_ADDRESS) +#define SRC_WATERMARK_LOW_MASK (sc->targetdef->d_SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_MASK (sc->targetdef->d_SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_MASK (sc->targetdef->d_DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_MASK (sc->targetdef->d_DST_WATERMARK_HIGH_MASK) +#define CURRENT_SRRI_ADDRESS (sc->targetdef->d_CURRENT_SRRI_ADDRESS) +#define CURRENT_DRRI_ADDRESS (sc->targetdef->d_CURRENT_DRRI_ADDRESS) +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK) +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_LOW_WATERMARK_MASK) +#define HOST_IS_ADDRESS (sc->targetdef->d_HOST_IS_ADDRESS) +#define HOST_IS_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IS_COPY_COMPLETE_MASK) +#define CE_WRAPPER_BASE_ADDRESS (sc->targetdef->d_CE_WRAPPER_BASE_ADDRESS) +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS) +#define HOST_IE_ADDRESS (sc->targetdef->d_HOST_IE_ADDRESS) +#define HOST_IE_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IE_COPY_COMPLETE_MASK) +#define SR_BA_ADDRESS (sc->targetdef->d_SR_BA_ADDRESS) +#define SR_SIZE_ADDRESS (sc->targetdef->d_SR_SIZE_ADDRESS) +#define CE_CTRL1_ADDRESS (sc->targetdef->d_CE_CTRL1_ADDRESS) +#define CE_CTRL1_DMAX_LENGTH_MASK (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_MASK) +#define DR_BA_ADDRESS (sc->targetdef->d_DR_BA_ADDRESS) +#define DR_SIZE_ADDRESS (sc->targetdef->d_DR_SIZE_ADDRESS) +#define MISC_IE_ADDRESS (sc->targetdef->d_MISC_IE_ADDRESS) +#define MISC_IS_AXI_ERR_MASK (sc->targetdef->d_MISC_IS_AXI_ERR_MASK) +#define MISC_IS_DST_ADDR_ERR_MASK (sc->targetdef->d_MISC_IS_DST_ADDR_ERR_MASK) +#define MISC_IS_SRC_LEN_ERR_MASK (sc->targetdef->d_MISC_IS_SRC_LEN_ERR_MASK) +#define MISC_IS_DST_MAX_LEN_VIO_MASK (sc->targetdef->d_MISC_IS_DST_MAX_LEN_VIO_MASK) +#define MISC_IS_DST_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_DST_RING_OVERFLOW_MASK) +#define MISC_IS_SRC_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_SRC_RING_OVERFLOW_MASK) +#define SRC_WATERMARK_LOW_LSB (sc->targetdef->d_SRC_WATERMARK_LOW_LSB) +#define SRC_WATERMARK_HIGH_LSB (sc->targetdef->d_SRC_WATERMARK_HIGH_LSB) +#define DST_WATERMARK_LOW_LSB (sc->targetdef->d_DST_WATERMARK_LOW_LSB) +#define DST_WATERMARK_HIGH_LSB (sc->targetdef->d_DST_WATERMARK_HIGH_LSB) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_LSB (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_LSB) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) +#define WLAN_DEBUG_INPUT_SEL_OFFSET (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_OFFSET) +#define WLAN_DEBUG_INPUT_SEL_SRC_MSB (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_LSB (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_LSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_MASK (sc->targetdef->d_WLAN_DEBUG_INPUT_SEL_SRC_MASK) +#define WLAN_DEBUG_CONTROL_OFFSET (sc->targetdef->d_WLAN_DEBUG_CONTROL_OFFSET) +#define WLAN_DEBUG_CONTROL_ENABLE_MSB (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MSB) +#define WLAN_DEBUG_CONTROL_ENABLE_LSB (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_LSB) +#define WLAN_DEBUG_CONTROL_ENABLE_MASK (sc->targetdef->d_WLAN_DEBUG_CONTROL_ENABLE_MASK) +#define WLAN_DEBUG_OUT_OFFSET (sc->targetdef->d_WLAN_DEBUG_OUT_OFFSET) +#define WLAN_DEBUG_OUT_DATA_MSB (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_MSB) +#define WLAN_DEBUG_OUT_DATA_LSB (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_LSB) +#define WLAN_DEBUG_OUT_DATA_MASK (sc->targetdef->d_WLAN_DEBUG_OUT_DATA_MASK) +#define AMBA_DEBUG_BUS_OFFSET (sc->targetdef->d_AMBA_DEBUG_BUS_OFFSET) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK (sc->targetdef->d_AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) +#define AMBA_DEBUG_BUS_SEL_MSB (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_MSB) +#define AMBA_DEBUG_BUS_SEL_LSB (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_LSB) +#define AMBA_DEBUG_BUS_SEL_MASK (sc->targetdef->d_AMBA_DEBUG_BUS_SEL_MASK) +#define CE_WRAPPER_DEBUG_OFFSET (sc->targetdef->d_CE_WRAPPER_DEBUG_OFFSET) +#define CE_WRAPPER_DEBUG_SEL_MSB (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_MSB) +#define CE_WRAPPER_DEBUG_SEL_LSB (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_LSB) +#define CE_WRAPPER_DEBUG_SEL_MASK (sc->targetdef->d_CE_WRAPPER_DEBUG_SEL_MASK) +#define CE_DEBUG_OFFSET (sc->targetdef->d_CE_DEBUG_OFFSET) +#define CE_DEBUG_SEL_MSB (sc->targetdef->d_CE_DEBUG_SEL_MSB) +#define CE_DEBUG_SEL_LSB (sc->targetdef->d_CE_DEBUG_SEL_LSB) +#define CE_DEBUG_SEL_MASK (sc->targetdef->d_CE_DEBUG_SEL_MASK) +/* end */ +/* PLL start */ +#define EFUSE_OFFSET (sc->targetdef->d_EFUSE_OFFSET) +#define EFUSE_XTAL_SEL_MSB (sc->targetdef->d_EFUSE_XTAL_SEL_MSB) +#define EFUSE_XTAL_SEL_LSB (sc->targetdef->d_EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_MASK (sc->targetdef->d_EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OFFSET (sc->targetdef->d_BB_PLL_CONFIG_OFFSET) +#define BB_PLL_CONFIG_OUTDIV_MSB (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_MSB) +#define BB_PLL_CONFIG_OUTDIV_LSB (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_MASK (sc->targetdef->d_BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_MSB (sc->targetdef->d_BB_PLL_CONFIG_FRAC_MSB) +#define BB_PLL_CONFIG_FRAC_LSB (sc->targetdef->d_BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_MASK (sc->targetdef->d_BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_MSB (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_MSB) +#define WLAN_PLL_SETTLE_TIME_LSB (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_MASK (sc->targetdef->d_WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_SETTLE_OFFSET (sc->targetdef->d_WLAN_PLL_SETTLE_OFFSET) +#define WLAN_PLL_SETTLE_SW_MASK (sc->targetdef->d_WLAN_PLL_SETTLE_SW_MASK) +#define WLAN_PLL_SETTLE_RSTMASK (sc->targetdef->d_WLAN_PLL_SETTLE_RSTMASK) +#define WLAN_PLL_SETTLE_RESET (sc->targetdef->d_WLAN_PLL_SETTLE_RESET) +#define WLAN_PLL_CONTROL_NOPWD_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MSB) +#define WLAN_PLL_CONTROL_NOPWD_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MSB) +#define WLAN_PLL_CONTROL_BYPASS_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_BYPASS_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_BYPASS_RESET) +#define WLAN_PLL_CONTROL_CLK_SEL_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MSB) +#define WLAN_PLL_CONTROL_CLK_SEL_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_CLK_SEL_RESET) +#define WLAN_PLL_CONTROL_REFDIV_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MSB) +#define WLAN_PLL_CONTROL_REFDIV_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_REFDIV_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_REFDIV_RESET) +#define WLAN_PLL_CONTROL_DIV_MSB (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_MSB) +#define WLAN_PLL_CONTROL_DIV_LSB (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_MASK) +#define WLAN_PLL_CONTROL_DIV_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_DIV_RESET) +#define WLAN_PLL_CONTROL_OFFSET (sc->targetdef->d_WLAN_PLL_CONTROL_OFFSET) +#define WLAN_PLL_CONTROL_SW_MASK (sc->targetdef->d_WLAN_PLL_CONTROL_SW_MASK) +#define WLAN_PLL_CONTROL_RSTMASK (sc->targetdef->d_WLAN_PLL_CONTROL_RSTMASK) +#define WLAN_PLL_CONTROL_RESET (sc->targetdef->d_WLAN_PLL_CONTROL_RESET) +#define SOC_CORE_CLK_CTRL_OFFSET (sc->targetdef->d_SOC_CORE_CLK_CTRL_OFFSET) +#define SOC_CORE_CLK_CTRL_DIV_MSB (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MSB) +#define SOC_CORE_CLK_CTRL_DIV_LSB (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_MASK (sc->targetdef->d_SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_MSB (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_LSB (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_MASK (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_RESET (sc->targetdef->d_RTC_SYNC_STATUS_PLL_CHANGING_RESET) +#define RTC_SYNC_STATUS_OFFSET (sc->targetdef->d_RTC_SYNC_STATUS_OFFSET) +#define SOC_CPU_CLOCK_OFFSET (sc->targetdef->d_SOC_CPU_CLOCK_OFFSET) +#define SOC_CPU_CLOCK_STANDARD_MSB (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_MSB) +#define SOC_CPU_CLOCK_STANDARD_LSB (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_MASK (sc->targetdef->d_SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ + +/* SET macros */ +#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK) +#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK) +#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK) +#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK) +#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +/* copy_engine.c */ +#define SRC_WATERMARK_LOW_SET(x) (((x) << SRC_WATERMARK_LOW_LSB) & SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_SET(x) (((x) << SRC_WATERMARK_HIGH_LSB) & SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_SET(x) (((x) << DST_WATERMARK_LOW_LSB) & DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_SET(x) (((x) << DST_WATERMARK_HIGH_LSB) & DST_WATERMARK_HIGH_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) (((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_SET(x) (((x) << CE_CTRL1_DMAX_LENGTH_LSB) & CE_CTRL1_DMAX_LENGTH_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +#define WLAN_DEBUG_INPUT_SEL_SRC_GET(x) (((x) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) >> WLAN_DEBUG_INPUT_SEL_SRC_LSB) +#define WLAN_DEBUG_INPUT_SEL_SRC_SET(x) (((x) << WLAN_DEBUG_INPUT_SEL_SRC_LSB) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) +#define WLAN_DEBUG_CONTROL_ENABLE_GET(x) (((x) & WLAN_DEBUG_CONTROL_ENABLE_MASK) >> WLAN_DEBUG_CONTROL_ENABLE_LSB) +#define WLAN_DEBUG_CONTROL_ENABLE_SET(x) (((x) << WLAN_DEBUG_CONTROL_ENABLE_LSB) & WLAN_DEBUG_CONTROL_ENABLE_MASK) +#define WLAN_DEBUG_OUT_DATA_GET(x) (((x) & WLAN_DEBUG_OUT_DATA_MASK) >> WLAN_DEBUG_OUT_DATA_LSB) +#define WLAN_DEBUG_OUT_DATA_SET(x) (((x) << WLAN_DEBUG_OUT_DATA_LSB) & WLAN_DEBUG_OUT_DATA_MASK) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_GET(x) (((x) & AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) >> AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) +#define AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_SET(x) (((x) << AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_LSB) & AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK) +#define AMBA_DEBUG_BUS_SEL_GET(x) (((x) & AMBA_DEBUG_BUS_SEL_MASK) >> AMBA_DEBUG_BUS_SEL_LSB) +#define AMBA_DEBUG_BUS_SEL_SET(x) (((x) << AMBA_DEBUG_BUS_SEL_LSB) & AMBA_DEBUG_BUS_SEL_MASK) +#define CE_WRAPPER_DEBUG_SEL_GET(x) (((x) & CE_WRAPPER_DEBUG_SEL_MASK) >> CE_WRAPPER_DEBUG_SEL_LSB) +#define CE_WRAPPER_DEBUG_SEL_SET(x) (((x) << CE_WRAPPER_DEBUG_SEL_LSB) & CE_WRAPPER_DEBUG_SEL_MASK) +#define CE_DEBUG_SEL_GET(x) (((x) & CE_DEBUG_SEL_MASK) >> CE_DEBUG_SEL_LSB) +#define CE_DEBUG_SEL_SET(x) (((x) << CE_DEBUG_SEL_LSB) & CE_DEBUG_SEL_MASK) +/* end */ +/* PLL start */ +#define EFUSE_XTAL_SEL_GET(x) (((x) & EFUSE_XTAL_SEL_MASK) >> EFUSE_XTAL_SEL_LSB) +#define EFUSE_XTAL_SEL_SET(x) (((x) << EFUSE_XTAL_SEL_LSB) & EFUSE_XTAL_SEL_MASK) +#define BB_PLL_CONFIG_OUTDIV_GET(x) (((x) & BB_PLL_CONFIG_OUTDIV_MASK) >> BB_PLL_CONFIG_OUTDIV_LSB) +#define BB_PLL_CONFIG_OUTDIV_SET(x) (((x) << BB_PLL_CONFIG_OUTDIV_LSB) & BB_PLL_CONFIG_OUTDIV_MASK) +#define BB_PLL_CONFIG_FRAC_GET(x) (((x) & BB_PLL_CONFIG_FRAC_MASK) >> BB_PLL_CONFIG_FRAC_LSB) +#define BB_PLL_CONFIG_FRAC_SET(x) (((x) << BB_PLL_CONFIG_FRAC_LSB) & BB_PLL_CONFIG_FRAC_MASK) +#define WLAN_PLL_SETTLE_TIME_GET(x) (((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_SET(x) (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK) +#define WLAN_PLL_CONTROL_NOPWD_GET(x) (((x) & WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_SET(x) (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_BYPASS_GET(x) (((x) & WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_SET(x) (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_CLK_SEL_GET(x) (((x) & WLAN_PLL_CONTROL_CLK_SEL_MASK) >> WLAN_PLL_CONTROL_CLK_SEL_LSB) +#define WLAN_PLL_CONTROL_CLK_SEL_SET(x) (((x) << WLAN_PLL_CONTROL_CLK_SEL_LSB) & WLAN_PLL_CONTROL_CLK_SEL_MASK) +#define WLAN_PLL_CONTROL_REFDIV_GET(x) (((x) & WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_SET(x) (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_DIV_GET(x) (((x) & WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_SET(x) (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK) +#define SOC_CORE_CLK_CTRL_DIV_GET(x) (((x) & SOC_CORE_CLK_CTRL_DIV_MASK) >> SOC_CORE_CLK_CTRL_DIV_LSB) +#define SOC_CORE_CLK_CTRL_DIV_SET(x) (((x) << SOC_CORE_CLK_CTRL_DIV_LSB) & SOC_CORE_CLK_CTRL_DIV_MASK) +#define RTC_SYNC_STATUS_PLL_CHANGING_GET(x) (((x) & RTC_SYNC_STATUS_PLL_CHANGING_MASK) >> RTC_SYNC_STATUS_PLL_CHANGING_LSB) +#define RTC_SYNC_STATUS_PLL_CHANGING_SET(x) (((x) << RTC_SYNC_STATUS_PLL_CHANGING_LSB) & RTC_SYNC_STATUS_PLL_CHANGING_MASK) +#define SOC_CPU_CLOCK_STANDARD_GET(x) (((x) & SOC_CPU_CLOCK_STANDARD_MASK) >> SOC_CPU_CLOCK_STANDARD_LSB) +#define SOC_CPU_CLOCK_STANDARD_SET(x) (((x) << SOC_CPU_CLOCK_STANDARD_LSB) & SOC_CPU_CLOCK_STANDARD_MASK) +/* PLL end */ + +typedef struct hostdef_s { + A_UINT32 d_INT_STATUS_ENABLE_ERROR_LSB; + A_UINT32 d_INT_STATUS_ENABLE_ERROR_MASK; + A_UINT32 d_INT_STATUS_ENABLE_CPU_LSB; + A_UINT32 d_INT_STATUS_ENABLE_CPU_MASK; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_LSB; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_MASK; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_LSB; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_INT_STATUS_ENABLE_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_HOST_INT_STATUS_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_MASK; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_LSB; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_LSB; + A_UINT32 d_COUNT_DEC_ADDRESS; + A_UINT32 d_HOST_INT_STATUS_CPU_MASK; + A_UINT32 d_HOST_INT_STATUS_CPU_LSB; + A_UINT32 d_HOST_INT_STATUS_ERROR_MASK; + A_UINT32 d_HOST_INT_STATUS_ERROR_LSB; + A_UINT32 d_HOST_INT_STATUS_COUNTER_MASK; + A_UINT32 d_HOST_INT_STATUS_COUNTER_LSB; + A_UINT32 d_RX_LOOKAHEAD_VALID_ADDRESS; + A_UINT32 d_WINDOW_DATA_ADDRESS; + A_UINT32 d_WINDOW_READ_ADDR_ADDRESS; + A_UINT32 d_WINDOW_WRITE_ADDR_ADDRESS; + A_UINT32 d_SOC_GLOBAL_RESET_ADDRESS; + A_UINT32 d_RTC_STATE_ADDRESS; + A_UINT32 d_RTC_STATE_COLD_RESET_MASK; + A_UINT32 d_PCIE_LOCAL_BASE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_RESET; + A_UINT32 d_PCIE_SOC_WAKE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_V_MASK; + A_UINT32 d_RTC_STATE_V_MASK; + A_UINT32 d_RTC_STATE_V_LSB; + A_UINT32 d_FW_IND_EVENT_PENDING; + A_UINT32 d_FW_IND_INITIALIZED; + A_UINT32 d_RTC_STATE_V_ON; +#if defined(SDIO_3_0) + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_MASK; + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_LSB; +#endif + A_UINT32 d_PCIE_SOC_RDY_STATUS_ADDRESS; + A_UINT32 d_PCIE_SOC_RDY_STATUS_BAR_MASK; + A_UINT32 d_SOC_PCIE_BASE_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADR_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADDRESS; +} HOST_REGISTER_TABLE; + +#define INT_STATUS_ENABLE_ERROR_LSB (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_LSB) +#define INT_STATUS_ENABLE_ERROR_MASK (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_LSB (sc->hostdef->d_INT_STATUS_ENABLE_CPU_LSB) +#define INT_STATUS_ENABLE_CPU_MASK (sc->hostdef->d_INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_LSB (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB) +#define INT_STATUS_ENABLE_COUNTER_MASK (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_LSB (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB) +#define INT_STATUS_ENABLE_MBOX_DATA_MASK (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB) +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define INT_STATUS_ENABLE_ADDRESS (sc->hostdef->d_INT_STATUS_ENABLE_ADDRESS) +#define CPU_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB) +#define CPU_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK) +#define HOST_INT_STATUS_ADDRESS (sc->hostdef->d_HOST_INT_STATUS_ADDRESS) +#define CPU_INT_STATUS_ADDRESS (sc->hostdef->d_CPU_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_ADDRESS (sc->hostdef->d_ERROR_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_WAKEUP_MASK (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK) +#define ERROR_INT_STATUS_WAKEUP_LSB (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK) +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK) +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define COUNT_DEC_ADDRESS (sc->hostdef->d_COUNT_DEC_ADDRESS) +#define HOST_INT_STATUS_CPU_MASK (sc->hostdef->d_HOST_INT_STATUS_CPU_MASK) +#define HOST_INT_STATUS_CPU_LSB (sc->hostdef->d_HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_MASK (sc->hostdef->d_HOST_INT_STATUS_ERROR_MASK) +#define HOST_INT_STATUS_ERROR_LSB (sc->hostdef->d_HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_MASK (sc->hostdef->d_HOST_INT_STATUS_COUNTER_MASK) +#define HOST_INT_STATUS_COUNTER_LSB (sc->hostdef->d_HOST_INT_STATUS_COUNTER_LSB) +#define RX_LOOKAHEAD_VALID_ADDRESS (sc->hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS) +#define WINDOW_DATA_ADDRESS (sc->hostdef->d_WINDOW_DATA_ADDRESS) +#define WINDOW_READ_ADDR_ADDRESS (sc->hostdef->d_WINDOW_READ_ADDR_ADDRESS) +#define WINDOW_WRITE_ADDR_ADDRESS (sc->hostdef->d_WINDOW_WRITE_ADDR_ADDRESS) +#define SOC_GLOBAL_RESET_ADDRESS (sc->hostdef->d_SOC_GLOBAL_RESET_ADDRESS) +#define RTC_STATE_ADDRESS (sc->hostdef->d_RTC_STATE_ADDRESS) +#define RTC_STATE_COLD_RESET_MASK (sc->hostdef->d_RTC_STATE_COLD_RESET_MASK) +#define PCIE_LOCAL_BASE_ADDRESS (sc->hostdef->d_PCIE_LOCAL_BASE_ADDRESS) +#define PCIE_SOC_WAKE_RESET (sc->hostdef->d_PCIE_SOC_WAKE_RESET) +#define PCIE_SOC_WAKE_ADDRESS (sc->hostdef->d_PCIE_SOC_WAKE_ADDRESS) +#define PCIE_SOC_WAKE_V_MASK (sc->hostdef->d_PCIE_SOC_WAKE_V_MASK) +#define RTC_STATE_V_MASK (sc->hostdef->d_RTC_STATE_V_MASK) +#define RTC_STATE_V_LSB (sc->hostdef->d_RTC_STATE_V_LSB) +#define FW_IND_EVENT_PENDING (sc->hostdef->d_FW_IND_EVENT_PENDING) +#define FW_IND_INITIALIZED (sc->hostdef->d_FW_IND_INITIALIZED) +#define RTC_STATE_V_ON (sc->hostdef->d_RTC_STATE_V_ON) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_MASK (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_MASK) +#define HOST_INT_STATUS_MBOX_DATA_LSB (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#if !defined(SOC_PCIE_BASE_ADDRESS) +#define SOC_PCIE_BASE_ADDRESS 0 +#endif + +#if !defined(PCIE_SOC_RDY_STATUS_ADDRESS) +#define PCIE_SOC_RDY_STATUS_ADDRESS 0 +#define PCIE_SOC_RDY_STATUS_BAR_MASK 0 +#endif + +#if !defined(MSI_MAGIC_ADR_ADDRESS) +#define MSI_MAGIC_ADR_ADDRESS 0 +#define MSI_MAGIC_ADDRESS 0 +#endif + +/* SET/GET macros */ +#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) +#define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#define INVALID_REG_LOC_DUMMY_DATA 0xAA + + + +#define ROME_USB_RTC_SOC_BASE_ADDRESS 0x00000800 +#define ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB 0x0 +#define SOC_RESET_CONTROL_COLD_RST_LSB 8 +#define SOC_RESET_CONTROL_COLD_RST_MASK 0x00000100 +#define SOC_RESET_CONTROL_COLD_RST_SET(x) \ + (((x) << SOC_RESET_CONTROL_COLD_RST_LSB) & \ + SOC_RESET_CONTROL_COLD_RST_MASK) + + +#define AR6320_CORE_CLK_DIV_ADDR 0x403fa8 +#define AR6320_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320_CPU_SPEED_ADDR 0x403fa4 +#define AR6320V2_CORE_CLK_DIV_ADDR 0x403fd8 +#define AR6320V2_CPU_PLL_INIT_DONE_ADDR 0x403fd0 +#define AR6320V2_CPU_SPEED_ADDR 0x403fd4 +#define AR6320V3_CORE_CLK_DIV_ADDR 0x404028 +#define AR6320V3_CPU_PLL_INIT_DONE_ADDR 0x404020 +#define AR6320V3_CPU_SPEED_ADDR 0x404024 + +typedef enum { + SOC_REFCLK_UNKNOWN = -1, /* Unsupported ref clock -- use PLL Bypass */ + SOC_REFCLK_48_MHZ = 0, + SOC_REFCLK_19_2_MHZ = 1, + SOC_REFCLK_24_MHZ = 2, + SOC_REFCLK_26_MHZ = 3, + SOC_REFCLK_37_4_MHZ = 4, + SOC_REFCLK_38_4_MHZ = 5, + SOC_REFCLK_40_MHZ = 6, + SOC_REFCLK_52_MHZ = 7, +} A_refclk_speed_t; + +#define A_REFCLK_UNKNOWN SOC_REFCLK_UNKNOWN +#define A_REFCLK_48_MHZ SOC_REFCLK_48_MHZ +#define A_REFCLK_19_2_MHZ SOC_REFCLK_19_2_MHZ +#define A_REFCLK_24_MHZ SOC_REFCLK_24_MHZ +#define A_REFCLK_26_MHZ SOC_REFCLK_26_MHZ +#define A_REFCLK_37_4_MHZ SOC_REFCLK_37_4_MHZ +#define A_REFCLK_38_4_MHZ SOC_REFCLK_38_4_MHZ +#define A_REFCLK_40_MHZ SOC_REFCLK_40_MHZ +#define A_REFCLK_52_MHZ SOC_REFCLK_52_MHZ + +#define TARGET_CPU_FREQ 176000000 + +struct wlan_pll_s { + u_int32_t refdiv; + u_int32_t div; + u_int32_t rnfrac; + u_int32_t outdiv; +}; + +struct cmnos_clock_s { + A_refclk_speed_t refclk_speed; + u_int32_t refclk_hz; + u_int32_t pll_settling_time; /* 50us */ + struct wlan_pll_s wlan_pll; +}; + +typedef struct TGT_REG_SECTION { + u_int32_t start_addr; + u_int32_t end_addr; +} tgt_reg_section; + +typedef struct TGT_REG_TABLE { + tgt_reg_section *section; + u_int32_t section_size; +} tgt_reg_table; +void target_register_tbl_attach(struct hif_usb_softc *sc, u32 target_type); +void hif_register_tbl_attach(struct hif_usb_softc *sc, u32 hif_type); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/usbdrv.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/usbdrv.c new file mode 100644 index 0000000000000..453739ddddd66 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/USB/usbdrv.c @@ -0,0 +1,1038 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#include +#include +#include +#include + +#include "hif_usb_internal.h" +#include +#include "a_types.h" +#include "athdefs.h" +#include "a_osapi.h" +#define ATH_MODULE_NAME hif +#include "a_debug.h" +#include "a_usb_defs.h" +#include "htc.h" +#include "htc_packet.h" +#include "qwlan_version.h" +#include "if_usb.h" +#include "vos_api.h" + +#define IS_BULK_EP(attr) (((attr) & 3) == 0x02) +#define IS_INT_EP(attr) (((attr) & 3) == 0x03) +#define IS_ISOC_EP(attr) (((attr) & 3) == 0x01) +#define IS_DIR_IN(addr) ((addr) & 0x80) + +static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe, + int buffer_length); +static void usb_hif_post_recv_bundle_transfers(HIF_USB_PIPE *recv_pipe, + int buffer_length); +static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context); +static void usb_hif_free_urb_to_pipe(HIF_USB_PIPE *pipe, + HIF_URB_CONTEXT *urb_context) +{ + unsigned long flags; + + spin_lock_irqsave(&pipe->device->cs_lock, flags); + pipe->urb_cnt++; + DL_ListAdd(&pipe->urb_list_head, &urb_context->link); + spin_unlock_irqrestore(&pipe->device->cs_lock, flags); +} + +HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(HIF_USB_PIPE *pipe) +{ + HIF_URB_CONTEXT *urb_context = NULL; + DL_LIST *item; + unsigned long flags; + + spin_lock_irqsave(&pipe->device->cs_lock, flags); + item = DL_ListRemoveItemFromHead(&pipe->urb_list_head); + if (item != NULL) { + urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link); + pipe->urb_cnt--; + } + spin_unlock_irqrestore(&pipe->device->cs_lock, flags); + + return urb_context; +} + +static HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer(HIF_USB_PIPE *pipe) +{ + HIF_URB_CONTEXT *urb_context = NULL; + DL_LIST *item; + unsigned long flags; + + spin_lock_irqsave(&pipe->device->cs_lock, flags); + item = DL_ListRemoveItemFromHead(&pipe->urb_pending_list); + if (item != NULL) + urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link); + spin_unlock_irqrestore(&pipe->device->cs_lock, flags); + + return urb_context; +} + +void usb_hif_enqueue_pending_transfer(HIF_USB_PIPE *pipe, + HIF_URB_CONTEXT *urb_context) +{ + unsigned long flags; + + spin_lock_irqsave(&pipe->device->cs_lock, flags); + DL_ListInsertTail(&pipe->urb_pending_list, &urb_context->link); + spin_unlock_irqrestore(&pipe->device->cs_lock, flags); +} + +void usb_hif_remove_pending_transfer(HIF_URB_CONTEXT *urb_context) +{ + unsigned long flags; + + spin_lock_irqsave(&urb_context->pipe->device->cs_lock, flags); + DL_ListRemove(&urb_context->link); + spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock, flags); +} + +static A_STATUS usb_hif_alloc_pipe_resources(HIF_USB_PIPE *pipe, int urb_cnt) +{ + A_STATUS status = A_OK; + int i; + HIF_URB_CONTEXT *urb_context; + + DL_LIST_INIT(&pipe->urb_list_head); + DL_LIST_INIT(&pipe->urb_pending_list); + + for (i = 0; i < urb_cnt; i++) { + urb_context = adf_os_mem_alloc(NULL, sizeof(*urb_context)); + if (NULL == urb_context) { + status = A_NO_MEMORY; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("urb_context is null\n")); + break; + } + adf_os_mem_zero(urb_context, sizeof(HIF_URB_CONTEXT)); + urb_context->pipe = pipe; + urb_context->urb = usb_alloc_urb(0, GFP_KERNEL); + + if (NULL == urb_context->urb) { + status = A_NO_MEMORY; + adf_os_mem_free(urb_context); + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("urb_context->urb is null\n")); + break; + } + + /* note we are only allocate the urb contexts here, the actual + * URB is + * allocated from the kernel as needed to do a transaction + */ + pipe->urb_alloc++; + + if (htc_bundle_send) { + /* In tx bundle mode, only pre-allocate bundle buffers + * for data + * pipes + */ + if (pipe->logical_pipe_num >= HIF_TX_DATA_LP_PIPE && + pipe->logical_pipe_num <= HIF_TX_DATA_HP_PIPE) { + urb_context->buf = adf_nbuf_alloc(NULL, + HIF_USB_TX_BUNDLE_BUFFER_SIZE, + 0, 4, FALSE); + if (NULL == urb_context->buf) { + status = A_NO_MEMORY; + usb_free_urb(urb_context->urb); + urb_context->urb = NULL; + adf_os_mem_free(urb_context); + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb: alloc send bundle buffer %d-byte failed\n", + HIF_USB_TX_BUNDLE_BUFFER_SIZE)); + break; + } + } + skb_queue_head_init(&urb_context->comp_queue); + } + + usb_hif_free_urb_to_pipe(pipe, urb_context); + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( + "athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d\n", + pipe->logical_pipe_num, + pipe->usb_pipe_handle, + pipe->urb_alloc)); + return status; +} + +static void usb_hif_free_pipe_resources(HIF_USB_PIPE *pipe) +{ + HIF_URB_CONTEXT *urb_context; + adf_nbuf_t nbuf; + + if (NULL == pipe->device) { + /* nothing allocated for this pipe */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("pipe->device is null\n")); + return; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ( + "athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d\n", + pipe->logical_pipe_num, + pipe->usb_pipe_handle, pipe->urb_alloc, + pipe->urb_cnt)); + + if (pipe->urb_alloc != pipe->urb_cnt) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d\n", + pipe->logical_pipe_num, + pipe->usb_pipe_handle, pipe->urb_alloc, + pipe->urb_cnt)); + } + + while (TRUE) { + urb_context = usb_hif_alloc_urb_from_pipe(pipe); + if (NULL == urb_context) + break; + + if (urb_context->buf) { + adf_nbuf_free(urb_context->buf); + urb_context->buf = NULL; + } + + if (htc_bundle_send) { + while ((nbuf = + skb_dequeue(&urb_context->comp_queue)) != + NULL) { + adf_nbuf_free(nbuf); + } + } + + usb_free_urb(urb_context->urb); + urb_context->urb = NULL; + adf_os_mem_free(urb_context); + } + +} + +static A_UINT8 usb_hif_get_logical_pipe_num(HIF_DEVICE_USB *device, + A_UINT8 ep_address, int *urb_count) +{ + A_UINT8 pipe_num = HIF_USB_PIPE_INVALID; + + switch (ep_address) { + case USB_EP_ADDR_APP_CTRL_IN: + pipe_num = HIF_RX_CTRL_PIPE; + *urb_count = RX_URB_COUNT; + break; + case USB_EP_ADDR_APP_DATA_IN: + pipe_num = HIF_RX_DATA_PIPE; + *urb_count = RX_URB_COUNT; + break; + case USB_EP_ADDR_APP_INT_IN: + pipe_num = HIF_RX_INT_PIPE; + *urb_count = RX_URB_COUNT; + break; + case USB_EP_ADDR_APP_DATA2_IN: + pipe_num = HIF_RX_DATA2_PIPE; + *urb_count = RX_URB_COUNT; + break; + case USB_EP_ADDR_APP_CTRL_OUT: + pipe_num = HIF_TX_CTRL_PIPE; + *urb_count = TX_URB_COUNT; + break; + case USB_EP_ADDR_APP_DATA_LP_OUT: + pipe_num = HIF_TX_DATA_LP_PIPE; + *urb_count = TX_URB_COUNT; + break; + case USB_EP_ADDR_APP_DATA_MP_OUT: + pipe_num = HIF_TX_DATA_MP_PIPE; + *urb_count = TX_URB_COUNT; + break; + case USB_EP_ADDR_APP_DATA_HP_OUT: + pipe_num = HIF_TX_DATA_HP_PIPE; + *urb_count = TX_URB_COUNT; + break; + default: + /* note: there may be endpoints not currently used */ + break; + } + + return pipe_num; +} + +A_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device) +{ + struct usb_interface *interface = device->interface; + struct usb_host_interface *iface_desc = interface->cur_altsetting; + struct usb_endpoint_descriptor *endpoint; + int i; + int urbcount; + A_STATUS status = A_OK; + HIF_USB_PIPE *pipe; + A_UINT8 pipe_num; + + /* walk decriptors and setup pipes */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (IS_BULK_EP(endpoint->bmAttributes)) { + AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( + "%s Bulk Ep:0x%2.2X " "maxpktsz:%d\n", + IS_DIR_IN(endpoint->bEndpointAddress) ? + "RX" : "TX", + endpoint->bEndpointAddress, + le16_to_cpu + (endpoint->wMaxPacketSize))); + } else if (IS_INT_EP(endpoint->bmAttributes)) { + AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( + "%s Int Ep:0x%2.2X maxpktsz:%d interval:%d\n", + IS_DIR_IN(endpoint->bEndpointAddress) ? + "RX" : "TX", + endpoint->bEndpointAddress, + le16_to_cpu(endpoint->wMaxPacketSize), + endpoint->bInterval)); + } else if (IS_ISOC_EP(endpoint->bmAttributes)) { + /* TODO for ISO */ + AR_DEBUG_PRINTF(USB_HIF_DEBUG_ENUM, ( + "%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d\n", + IS_DIR_IN(endpoint->bEndpointAddress) ? + "RX" : "TX", + endpoint->bEndpointAddress, + le16_to_cpu(endpoint->wMaxPacketSize), + endpoint->bInterval)); + } + urbcount = 0; + + pipe_num = usb_hif_get_logical_pipe_num(device, + endpoint-> + bEndpointAddress, + &urbcount); + if (HIF_USB_PIPE_INVALID == pipe_num) + continue; + + pipe = &device->pipes[pipe_num]; + if (pipe->device != NULL) { + /* hmmm..pipe was already setup */ + continue; + } + + pipe->device = device; + pipe->logical_pipe_num = pipe_num; + pipe->ep_address = endpoint->bEndpointAddress; + pipe->max_packet_size = le16_to_cpu(endpoint->wMaxPacketSize); + + if (IS_BULK_EP(endpoint->bmAttributes)) { + if (IS_DIR_IN(pipe->ep_address)) { + pipe->usb_pipe_handle = + usb_rcvbulkpipe(device->udev, + pipe->ep_address); + } else { + pipe->usb_pipe_handle = + usb_sndbulkpipe(device->udev, + pipe->ep_address); + } + } else if (IS_INT_EP(endpoint->bmAttributes)) { + if (IS_DIR_IN(pipe->ep_address)) { + pipe->usb_pipe_handle = + usb_rcvintpipe(device->udev, + pipe->ep_address); + } else { + pipe->usb_pipe_handle = + usb_sndintpipe(device->udev, + pipe->ep_address); + } + } else if (IS_ISOC_EP(endpoint->bmAttributes)) { + /* TODO for ISO */ + if (IS_DIR_IN(pipe->ep_address)) { + pipe->usb_pipe_handle = + usb_rcvisocpipe(device->udev, + pipe->ep_address); + } else { + pipe->usb_pipe_handle = + usb_sndisocpipe(device->udev, + pipe->ep_address); + } + } + pipe->ep_desc = endpoint; + + if (!IS_DIR_IN(pipe->ep_address)) + pipe->flags |= HIF_USB_PIPE_FLAG_TX; + + status = usb_hif_alloc_pipe_resources(pipe, urbcount); + if (A_FAILED(status)) + break; + + } + + return status; +} + +void usb_hif_cleanup_pipe_resources(HIF_DEVICE_USB *device) +{ + int i; + + for (i = 0; i < HIF_USB_PIPE_MAX; i++) + usb_hif_free_pipe_resources(&device->pipes[i]); +} + +static void usb_hif_flush_pending_transfers(HIF_USB_PIPE *pipe) +{ + HIF_URB_CONTEXT *urb_context; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s pipe : %d\n", __func__, + pipe->logical_pipe_num)); + + while (1) { + urb_context = usb_hif_dequeue_pending_transfer(pipe); + if (NULL == urb_context) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("urb_context is NULL\n")); + break; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" pending urb ctxt: 0x%p\n", + urb_context)); + if (urb_context->urb != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + (" killing urb: 0x%p\n", + urb_context->urb)); + /* killing the URB will cause the completion routines to + * run + */ + usb_kill_urb(urb_context->urb); + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void usb_hif_flush_all(HIF_DEVICE_USB *device) +{ + int i; + HIF_USB_PIPE *pipe; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + for (i = 0; i < HIF_USB_PIPE_MAX; i++) { + if (device->pipes[i].device != NULL) { + usb_hif_flush_pending_transfers(&device->pipes[i]); + pipe = &device->pipes[i]; + flush_work(&pipe->io_complete_work); + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + if (urb_context->buf != NULL) { + adf_nbuf_free(urb_context->buf); + urb_context->buf = NULL; + } + + usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); +} + +void usb_hif_cleanup_transmit_urb(HIF_URB_CONTEXT *urb_context) +{ + usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); +} + +static void usb_hif_usb_recv_complete(struct urb *urb) +{ + HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context; + A_STATUS status = A_OK; + adf_nbuf_t buf = NULL; + HIF_USB_PIPE *pipe = urb_context->pipe; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ( + "+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p\n", + __func__, + pipe->logical_pipe_num, + urb->status, urb->actual_length, + urb)); + + /* this urb is not pending anymore */ + usb_hif_remove_pending_transfer(urb_context); + + do { + + if (urb->status != 0) { + status = A_ECOMM; + switch (urb->status) { +#ifdef RX_SG_SUPPORT + case -EOVERFLOW: + urb->actual_length = HIF_USB_RX_BUFFER_SIZE; + status = A_OK; + break; +#endif + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* NOTE: no need to spew these errors when + * device is removed + * or urb is killed due to driver shutdown + */ + status = A_ECANCELED; + break; + default: + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s recv pipe: %d (ep:0x%2.2X), failed:%d\n", + __func__, + pipe->logical_pipe_num, + pipe->ep_address, + urb->status)); + break; + } + break; + } + + if (urb->actual_length == 0) + break; + + buf = urb_context->buf; + /* we are going to pass it up */ + urb_context->buf = NULL; + adf_nbuf_put_tail(buf, urb->actual_length); + if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { + A_UINT8 *data; + A_UINT32 len; + adf_nbuf_peek_header(buf, &data, &len); + DebugDumpBytes(data, len, "hif recv data"); + } + + /* note: queue implements a lock */ + skb_queue_tail(&pipe->io_comp_queue, buf); + schedule_work(&pipe->io_complete_work); + + } while (FALSE); + + usb_hif_cleanup_recv_urb(urb_context); + + if (A_SUCCESS(status)) { + if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { + /* our free urbs are piling up, post more transfers */ + usb_hif_post_recv_transfers(pipe, + HIF_USB_RX_BUFFER_SIZE); + } + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ("-%s\n", __func__)); +} + +static void usb_hif_usb_recv_bundle_complete(struct urb *urb) +{ + HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context; + A_STATUS status = A_OK; + adf_nbuf_t buf = NULL; + HIF_USB_PIPE *pipe = urb_context->pipe; + A_UINT8 *netdata, *netdata_new; + A_UINT32 netlen, netlen_new; + HTC_FRAME_HDR *HtcHdr; + A_UINT16 payloadLen; + adf_nbuf_t new_skb = NULL; + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ( + "+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p\n", + __func__, + pipe->logical_pipe_num, + urb->status, urb->actual_length, + urb)); + + /* this urb is not pending anymore */ + usb_hif_remove_pending_transfer(urb_context); + + do { + + if (urb->status != 0) { + status = A_ECOMM; + switch (urb->status) { + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* NOTE: no need to spew these errors when + * device is removed + * or urb is killed due to driver shutdown + */ + status = A_ECANCELED; + break; + default: + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s recv pipe: %d (ep:0x%2.2X), failed:%d\n", + __func__, + pipe->logical_pipe_num, + pipe->ep_address, + urb->status)); + break; + } + break; + } + + if (urb->actual_length == 0) + break; + + buf = urb_context->buf; + + if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) { + A_UINT8 *data; + A_UINT32 len; + adf_nbuf_peek_header(buf, &data, &len); + DebugDumpBytes(data, len, "hif recv data"); + } + + adf_nbuf_peek_header(buf, &netdata, &netlen); + netlen = urb->actual_length; + + do { +#if defined(AR6004_1_0_ALIGN_WAR) + A_UINT8 extra_pad; + A_UINT16 act_frame_len; +#endif + A_UINT16 frame_len; + + /* Hack into HTC header for bundle processing */ + HtcHdr = (HTC_FRAME_HDR *) netdata; + if (HtcHdr->EndpointID >= ENDPOINT_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb: Rx: invalid EndpointID=%d\n", + HtcHdr->EndpointID)); + break; + } + + payloadLen = HtcHdr->PayloadLen; + payloadLen = A_LE2CPU16(payloadLen); + +#if defined(AR6004_1_0_ALIGN_WAR) + act_frame_len = (HTC_HDR_LENGTH + payloadLen); + + if (HtcHdr->EndpointID == 0 || + HtcHdr->EndpointID == 1) { + /* assumption: target won't pad on HTC endpoint + * 0 & 1. + */ + extra_pad = 0; + } else { + extra_pad = + A_GET_UINT8_FIELD((A_UINT8 *) HtcHdr, + HTC_FRAME_HDR, + ControlBytes[1]); + } +#endif + + if (payloadLen > HIF_USB_RX_BUFFER_SIZE) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb: payloadLen too long %u\n", + payloadLen)); + break; + } +#if defined(AR6004_1_0_ALIGN_WAR) + frame_len = (act_frame_len + extra_pad); +#else + frame_len = (HTC_HDR_LENGTH + payloadLen); +#endif + + if (netlen >= frame_len) { + /* allocate a new skb and copy */ +#if defined(AR6004_1_0_ALIGN_WAR) + new_skb = + adf_nbuf_alloc(NULL, act_frame_len, 0, 4, + FALSE); + if (new_skb == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb: allocate skb (len=%u) failed\n", + act_frame_len)); + break; + } + + adf_nbuf_peek_header(new_skb, &netdata_new, + &netlen_new); + adf_os_mem_copy(netdata_new, netdata, + act_frame_len); + adf_nbuf_put_tail(new_skb, act_frame_len); +#else + new_skb = + adf_nbuf_alloc(NULL, frame_len, 0, 4, + FALSE); + if (new_skb == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb: allocate skb (len=%u) failed\n", + frame_len)); + break; + } + + adf_nbuf_peek_header(new_skb, &netdata_new, + &netlen_new); + adf_os_mem_copy(netdata_new, netdata, + frame_len); + adf_nbuf_put_tail(new_skb, frame_len); +#endif + skb_queue_tail(&pipe->io_comp_queue, new_skb); + new_skb = NULL; + + netdata += frame_len; + netlen -= frame_len; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "athusb: subframe length %d not fitted into bundle packet length %d\n" + , netlen, frame_len)); + break; + } + + } while (netlen); + + schedule_work(&pipe->io_complete_work); + + } while (FALSE); + + if (urb_context->buf == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb: buffer in urb_context is NULL\n")); + } + + /* reset urb_context->buf ==> seems not necessary */ + usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context); + + if (A_SUCCESS(status)) { + if (pipe->urb_cnt >= pipe->urb_cnt_thresh) { + /* our free urbs are piling up, post more transfers */ + usb_hif_post_recv_bundle_transfers(pipe, 0 + /* pass zero for not allocating urb-buffer again */ + ); + } + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ("-%s\n", __func__)); +} + +/* post recv urbs for a given pipe */ +static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe, + int buffer_length) +{ + HIF_URB_CONTEXT *urb_context; + a_uint8_t *data; + a_uint32_t len; + struct urb *urb; + int usb_status; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + while (1) { + + urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); + if (NULL == urb_context) + break; + + urb_context->buf = + adf_nbuf_alloc(NULL, buffer_length, 0, 4, FALSE); + if (NULL == urb_context->buf) { + usb_hif_cleanup_recv_urb(urb_context); + break; + } + + adf_nbuf_peek_header(urb_context->buf, &data, &len); + + urb = urb_context->urb; + + usb_fill_bulk_urb(urb, + recv_pipe->device->udev, + recv_pipe->usb_pipe_handle, + data, + buffer_length, + usb_hif_usb_recv_complete, urb_context); + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ( + "athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p\n", + recv_pipe->logical_pipe_num, + recv_pipe->usb_pipe_handle, + recv_pipe->ep_address, buffer_length, + urb_context->buf)); + + usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); + + usb_status = usb_submit_urb(urb, GFP_ATOMIC); + + if (usb_status) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb : usb bulk recv failed %d\n", + usb_status)); + usb_hif_remove_pending_transfer(urb_context); + usb_hif_cleanup_recv_urb(urb_context); + break; + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + +} + +/* post recv urbs for a given pipe */ +static void usb_hif_post_recv_bundle_transfers(HIF_USB_PIPE *recv_pipe, + int buffer_length) +{ + HIF_URB_CONTEXT *urb_context; + a_uint8_t *data; + a_uint32_t len; + struct urb *urb; + int usb_status; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + + while (1) { + + urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe); + if (NULL == urb_context) + break; + + if (buffer_length) { + urb_context->buf = + adf_nbuf_alloc(NULL, buffer_length, 0, 4, FALSE); + if (NULL == urb_context->buf) { + usb_hif_cleanup_recv_urb(urb_context); + break; + } + } + + adf_nbuf_peek_header(urb_context->buf, &data, &len); + + urb = urb_context->urb; + usb_fill_bulk_urb(urb, + recv_pipe->device->udev, + recv_pipe->usb_pipe_handle, + data, + HIF_USB_RX_BUNDLE_BUFFER_SIZE, + usb_hif_usb_recv_bundle_complete, + urb_context); + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, ( + "athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p\n", + recv_pipe->logical_pipe_num, + recv_pipe->usb_pipe_handle, + recv_pipe->ep_address, buffer_length, + urb_context->buf)); + + usb_hif_enqueue_pending_transfer(recv_pipe, urb_context); + + usb_status = usb_submit_urb(urb, GFP_ATOMIC); + + if (usb_status) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("athusb : usb bulk recv failed %d\n", + usb_status)); + usb_hif_remove_pending_transfer(urb_context); + usb_hif_free_urb_to_pipe(urb_context->pipe, + urb_context); + break; + } + + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + +} + +void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device) +{ + device->pipes[HIF_RX_DATA_PIPE].urb_cnt_thresh = + device->pipes[HIF_RX_DATA_PIPE].urb_alloc / 2; + + if (!htc_bundle_recv) { + usb_hif_post_recv_transfers(&device->pipes[HIF_RX_DATA_PIPE], + HIF_USB_RX_BUFFER_SIZE); + } else { + usb_hif_post_recv_bundle_transfers(&device->pipes + [HIF_RX_DATA_PIPE], + HIF_USB_RX_BUNDLE_BUFFER_SIZE); + } + + if (!hif_usb_disable_rxdata2) { + device->pipes[HIF_RX_DATA2_PIPE].urb_cnt_thresh = + device->pipes[HIF_RX_DATA2_PIPE].urb_alloc / 2; + usb_hif_post_recv_transfers(&device->pipes[HIF_RX_DATA2_PIPE], + HIF_USB_RX_BUFFER_SIZE); + } +#ifdef USB_HIF_TEST_INTERRUPT_IN + device->pipes[HIF_RX_INT_PIPE].urb_cnt_thresh = + device->pipes[HIF_RX_INT_PIPE].urb_alloc / 2; + usb_hif_post_recv_transfers(&device->pipes[HIF_RX_INT_PIPE], + HIF_USB_RX_BUFFER_SIZE); +#endif +} + +A_STATUS usb_hif_submit_ctrl_out(HIF_DEVICE_USB *device, + a_uint8_t req, + a_uint16_t value, + a_uint16_t index, void *data, a_uint32_t size) +{ + a_int32_t result = 0; + A_STATUS ret = A_OK; + a_uint8_t *buf = NULL; + + do { + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (NULL == buf) { + ret = A_NO_MEMORY; + break; + } + memcpy(buf, (a_uint8_t *) data, size); + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_CTRL_TRANS, ( + "ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d\n", + req, value, index, size)); + + result = usb_control_msg(device->udev, + usb_sndctrlpipe(device->udev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 2 * HZ); + + if (result < 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ( + "%s failed,result = %d\n", + __func__, result)); + ret = A_ERROR; + } + + } while (FALSE); + + if (buf != NULL) + kfree(buf); + + return ret; +} + +A_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *device, + a_uint8_t req, + a_uint16_t value, + a_uint16_t index, void *data, a_uint32_t size) +{ + a_int32_t result = 0; + A_STATUS ret = A_OK; + a_uint8_t *buf = NULL; + + do { + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (NULL == buf) { + ret = A_NO_MEMORY; + break; + } + } + + AR_DEBUG_PRINTF(USB_HIF_DEBUG_CTRL_TRANS, ( + "ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d\n", + req, value, index, size)); + + result = usb_control_msg(device->udev, + usb_rcvctrlpipe(device->udev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 2 * HZ); + + if (result < 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s failed,result = %d\n", + __func__, result)); + ret = A_ERROR; + break; + } + + memcpy((a_uint8_t *) data, buf, size); + + } while (FALSE); + + if (buf != NULL) + kfree(buf); + + return ret; +} + +#define IS_FW_CRASH_DUMP(x) ((x == FW_ASSERT_PATTERN) || \ + (x == FW_REG_PATTERN) || \ + ((x & FW_RAMDUMP_PATTERN_MASK) == FW_RAMDUMP_PATTERN))?1:0 + +void usb_hif_io_comp_work(struct work_struct *work) +{ + HIF_USB_PIPE *pipe = container_of(work, HIF_USB_PIPE, io_complete_work); + adf_nbuf_t buf; + HIF_DEVICE_USB *device; + HTC_FRAME_HDR *HtcHdr; + struct hif_usb_softc *sc; + A_UINT8 *data; + A_UINT32 len; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); + device = pipe->device; + sc = device->sc; + + while ((buf = skb_dequeue(&pipe->io_comp_queue))) { + a_mem_trace(buf); + if (pipe->flags & HIF_USB_PIPE_FLAG_TX) { + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("+athusb xmit callback " "buf:0x%p\n", + buf)); + HtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(buf, 0); + +#ifdef ATH_11AC_TXCOMPACT +#error ATH_11AC_TXCOMPACT only support for High Latency mode +#else + device->htcCallbacks.txCompletionHandler(device-> + htcCallbacks. + Context, buf, + HtcHdr-> + EndpointID); +#endif + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_OUT, + ("-athusb xmit callback\n")); + } else { + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, + ("+athusb recv callback buf:" "0x%p\n", + buf)); + adf_nbuf_peek_header(buf, &data, &len); + + if (IS_FW_CRASH_DUMP(*((A_UINT32 *) data))) { + sc->fw_data = data; + sc->fw_data_len = len; + device->htcCallbacks.fwEventHandler( + device->htcCallbacks.Context, A_USB_ERROR); + dev_kfree_skb(buf); + } else { + device->htcCallbacks.rxCompletionHandler( + device->htcCallbacks.Context, buf, + pipe->logical_pipe_num); + AR_DEBUG_PRINTF(USB_HIF_DEBUG_BULK_IN, + ("-athusb recv callback\n")); + } + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n", __func__)); + +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c new file mode 100644 index 0000000000000..bad2474dc7da6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) +#include /* Specifically, a module */ +#include /* We're doing kernel work */ +#include /* We're doing kernel work */ +#include /* Necessary because we use the proc fs */ +#include /* for copy_from_user */ +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +#include "vos_api.h" + +#define PROCFS_NAME "athdiagpfs" +#define PROCFS_DIR "cld" + +/** + * This structure hold information about the /proc file + * + */ +static struct proc_dir_entry *proc_file, *proc_dir; + +static void *get_hif_hdl_from_file(struct file *file) +{ +#if defined(HIF_PCI) + struct hif_pci_softc *scn; +#elif defined(HIF_USB) + struct hif_usb_softc *scn; +#elif defined(HIF_SDIO) + struct ath_hif_sdio_softc *scn; +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#if defined(HIF_PCI) + scn = (struct hif_pci_softc *)PDE_DATA(file_inode(file)); +#elif defined(HIF_USB) + scn = (struct hif_usb_softc *)PDE_DATA(file_inode(file)); +#elif defined(HIF_SDIO) + scn = (struct ath_hif_sdio_softc *)PDE_DATA(file_inode(file)); +#endif +#else +#if defined(HIF_PCI) + scn = (struct hif_pci_softc *)(PDE(file->f_path.dentry->d_inode)->data); +#elif defined(HIF_USB) + scn = (struct hif_usb_softc *)(PDE(file->f_path.dentry->d_inode)->data); +#elif defined(HIF_SDIO) + scn = (struct ath_hif_sdio_softc *)(PDE(file->f_path.dentry->d_inode)->data); +#endif +#endif + return (void*)scn->ol_sc->hif_hdl; +} + +static ssize_t ath_procfs_diag_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + hif_handle_t hif_hdl; + int rv; + A_UINT8 *read_buffer = NULL; + + read_buffer = (A_UINT8 *)vos_mem_malloc(count); + if (NULL == read_buffer) { + pr_debug("%s: vos_mem_alloc failed\n", __func__); + return -EINVAL; + } + + hif_hdl = get_hif_hdl_from_file(file); + pr_debug("rd buff 0x%p cnt %zu offset 0x%x buf 0x%p\n", + read_buffer,count, + (int)*pos, buf); + + if ((count == 4) && ((((A_UINT32)(*pos)) & 3) == 0)) { + /* reading a word? */ + rv = HIFDiagReadAccess(hif_hdl, (A_UINT32)(*pos), + (A_UINT32 *)read_buffer); + } else { + rv = HIFDiagReadMem(hif_hdl, (A_UINT32)(*pos), + (A_UINT8 *)read_buffer, count); + } + + if(copy_to_user(buf, read_buffer, count)) { + vos_mem_free(read_buffer); + return -EFAULT; + } else + vos_mem_free(read_buffer); + + if (rv == 0) { + return count; + } else { + return -EIO; + } +} + +static ssize_t ath_procfs_diag_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + hif_handle_t hif_hdl; + int rv; + A_UINT8 *write_buffer = NULL; + + write_buffer = (A_UINT8 *)vos_mem_malloc(count); + if (NULL == write_buffer) { + pr_debug("%s: vos_mem_alloc failed\n", __func__); + return -EINVAL; + } + if(copy_from_user(write_buffer, buf, count)) { + vos_mem_free(write_buffer); + return -EFAULT; + } + + hif_hdl = get_hif_hdl_from_file(file); + pr_debug("wr buff 0x%p buf 0x%p cnt %zu offset 0x%x value 0x%x\n", + write_buffer, buf, count, + (int)*pos, *((A_UINT32 *)write_buffer)); + + if ((count == 4) && ((((A_UINT32)(*pos)) & 3) == 0)) { + /* reading a word? */ + A_UINT32 value = *((A_UINT32 *)write_buffer); + rv = HIFDiagWriteAccess(hif_hdl, + (A_UINT32)(*pos), value); + } else { + rv = HIFDiagWriteMem(hif_hdl, (A_UINT32)(*pos), + (A_UINT8 *)write_buffer, count); + } + + vos_mem_free(write_buffer); + if (rv == 0) { + return count; + } else { + return -EIO; + } +} + +static const struct file_operations athdiag_fops = { + .read = ath_procfs_diag_read, + .write = ath_procfs_diag_write, +}; + +/** + *This function is called when the module is loaded + * + */ +int athdiag_procfs_init(void *scn) +{ + proc_dir = proc_mkdir(PROCFS_DIR, NULL); + if (proc_dir == NULL) { + remove_proc_entry(PROCFS_DIR, NULL); + pr_debug("Error: Could not initialize /proc/%s\n", + PROCFS_DIR); + return -ENOMEM; + } + + proc_file = proc_create_data(PROCFS_NAME, + S_IRUSR | S_IWUSR, proc_dir, + &athdiag_fops, (void *)scn); + if (proc_file == NULL) { + remove_proc_entry(PROCFS_NAME, proc_dir); + pr_debug("Error: Could not initialize /proc/%s\n", + PROCFS_NAME); + return -ENOMEM; + } + + pr_debug("/proc/%s/%s created\n", PROCFS_DIR, PROCFS_NAME); + return 0; /* everything is ok */ +} + +/** + *This function is called when the module is unloaded + * + */ +void athdiag_procfs_remove(void) +{ + remove_proc_entry(PROCFS_NAME, proc_dir); + pr_debug("/proc/%s/%s removed\n", PROCFS_DIR, PROCFS_NAME); + remove_proc_entry(PROCFS_DIR, NULL); + pr_debug("/proc/%s removed\n", PROCFS_DIR); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_bmi_reg_access.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_bmi_reg_access.c new file mode 100644 index 0000000000000..8880fcf028035 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_bmi_reg_access.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + *Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "athdefs.h" +#include "a_types.h" +#include "a_osapi.h" +#define ATH_MODULE_NAME bmi +#include "a_debug.h" +#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) +#include "hif.h" +#include "bmi.h" +#include "htc_api.h" +#include "if_ath_sdio.h" +#include "regtable.h" + +#define BMI_COMMUNICATION_TIMEOUT 100000 + +static A_BOOL pendingEventsFuncCheck = FALSE; +static A_UINT32 commandCredits = 0; +static A_UINT32 *pBMICmdCredits = &commandCredits; + +/* BMI Access routines */ +static A_STATUS +bmiBufferSend(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length) +{ + A_STATUS status; + A_UINT32 timeout; + A_UINT32 address; + A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; + + HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, + &mboxAddress[0], sizeof(mboxAddress)); + + *pBMICmdCredits = 0; + timeout = BMI_COMMUNICATION_TIMEOUT; + + while(timeout-- && !(*pBMICmdCredits)) { + /* Read the counter register to get the command credits */ + address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; + /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause + * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to + * make all HIF accesses 4-byte aligned */ + status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4, + HIF_RD_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n")); + return A_ERROR; + } + /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ + (*pBMICmdCredits) &= 0xFF; + } + + if (*pBMICmdCredits) { + address = mboxAddress[ENDPOINT1]; + status = HIFReadWrite(device, address, buffer, length, + HIF_WR_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n")); + return A_ERROR; + } + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n")); + return A_ERROR; + } + + return status; +} + +static A_STATUS +bmiBufferReceive(HIF_DEVICE *device, + A_UCHAR *buffer, + A_UINT32 length, + A_BOOL want_timeout) +{ + A_STATUS status; + A_UINT32 address; + A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; + HIF_PENDING_EVENTS_INFO hifPendingEvents; + static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL; + + if (!pendingEventsFuncCheck) { + /* see if the HIF layer implements an alternative function to get pending events + * do this only once! */ + HIFConfigureDevice(device, + HIF_DEVICE_GET_PENDING_EVENTS_FUNC, + &getPendingEventsFunc, + sizeof(getPendingEventsFunc)); + pendingEventsFuncCheck = TRUE; + } + + HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, + &mboxAddress[0], sizeof(mboxAddress)); + + /* + * During normal bootup, small reads may be required. + * Rather than issue an HIF Read and then wait as the Target + * adds successive bytes to the FIFO, we wait here until + * we know that response data is available. + * + * This allows us to cleanly timeout on an unexpected + * Target failure rather than risk problems at the HIF level. In + * particular, this avoids SDIO timeouts and possibly garbage + * data on some host controllers. And on an interconnect + * such as Compact Flash (as well as some SDIO masters) which + * does not provide any indication on data timeout, it avoids + * a potential hang or garbage response. + * + * Synchronization is more difficult for reads larger than the + * size of the MBOX FIFO (128B), because the Target is unable + * to push the 129th byte of data until AFTER the Host posts an + * HIF Read and removes some FIFO data. So for large reads the + * Host proceeds to post an HIF Read BEFORE all the data is + * actually available to read. Fortunately, large BMI reads do + * not occur in practice -- they're supported for debug/development. + * + * So Host/Target BMI synchronization is divided into these cases: + * CASE 1: length < 4 + * Should not happen + * + * CASE 2: 4 <= length <= 128 + * Wait for first 4 bytes to be in FIFO + * If CONSERVATIVE_BMI_READ is enabled, also wait for + * a BMI command credit, which indicates that the ENTIRE + * response is available in the the FIFO + * + * CASE 3: length > 128 + * Wait for the first 4 bytes to be in FIFO + * + * For most uses, a small timeout should be sufficient and we will + * usually see a response quickly; but there may be some unusual + * (debug) cases of BMI_EXECUTE where we want an larger timeout. + * For now, we use an unbounded busy loop while waiting for + * BMI_EXECUTE. + * + * If BMI_EXECUTE ever needs to support longer-latency execution, + * especially in production, this code needs to be enhanced to sleep + * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently + * a function of Host processor speed. + */ + if (length >= 4) { /* NB: Currently, always true */ + /* + * NB: word_available is declared static for esoteric reasons + * having to do with protection on some OSes. + */ + static A_UINT32 word_available; + A_UINT32 timeout; + + word_available = 0; + timeout = BMI_COMMUNICATION_TIMEOUT; + while((!want_timeout || timeout--) && !word_available) { + + if (getPendingEventsFunc != NULL) { + status = getPendingEventsFunc(device, + &hifPendingEvents, + NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n")); + break; + } + + if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) { + word_available = 1; + } + continue; + } +#if defined(SDIO_3_0) + status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, (A_UINT8 *)&word_available, sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read HOST_INT_STATUS_ADDRESS register\n")); + return A_ERROR; + } + +#else + status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *)&word_available, sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n")); + return A_ERROR; + } +#endif + /* We did a 4-byte read to the same register; all we really want is one bit */ +#if defined(SDIO_3_0) + word_available = (HOST_INT_STATUS_MBOX_DATA_GET(word_available) & ( 1 << ENDPOINT1)); +#else + word_available &= (1 << ENDPOINT1); +#endif + + } + + if (!word_available) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n")); + return A_ERROR; + } + } + +#define CONSERVATIVE_BMI_READ 0 +#if CONSERVATIVE_BMI_READ + /* + * This is an extra-conservative CREDIT check. It guarantees + * that ALL data is available in the FIFO before we start to + * read from the interconnect. + * + * This credit check is useless when firmware chooses to + * allow multiple outstanding BMI Command Credits, since the next + * credit will already be present. To restrict the Target to one + * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT. + * + * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set) + * we cannot wait for the next credit because the Target's FIFO + * will not hold the entire response. So we need the Host to + * start to empty the FIFO sooner. (And again, large reads are + * not used in practice; they are for debug/development only.) + * + * For a more conservative Host implementation (which would be + * safer for a Compact Flash interconnect): + * Set CONSERVATIVE_BMI_READ (above) to 1 + * Set HI_OPTION_BMI_CRED_LIMIT and + * reduce BMI_DATASZ_MAX to 32 or 64 + */ + if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */ + A_UINT32 timeout; + + *pBMICmdCredits = 0; + timeout = BMI_COMMUNICATION_TIMEOUT; + while((!want_timeout || timeout--) && !(*pBMICmdCredits) { + /* Read the counter register to get the command credits */ + address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; + /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing, + * we can read this counter multiple times using a non-incrementing address mode. + * The rationale here is to make all HIF accesses a multiple of 4 bytes */ + status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, sizeof(*pBMICmdCredits), + HIF_RD_SYNC_BYTE_FIX, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n")); + return A_ERROR; + } + /* we did a 4-byte read to the same count register so mask off upper bytes */ + (*pBMICmdCredits) &= 0xFF; + } + + if (!(*pBMICmdCredits)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n")); + return A_ERROR; + } + } +#endif + + address = mboxAddress[ENDPOINT1]; + status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n")); + return A_ERROR; + } + + return A_OK; +} + + +A_STATUS HIFRegBasedGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) +{ + A_STATUS status; + A_UINT32 cid; + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device)); + cid = BMI_GET_TARGET_INFO; + + status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); + return A_ERROR; + } + + status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, + sizeof(targ_info->target_ver), TRUE); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); + return A_ERROR; + } + + if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { + /* Determine how many bytes are in the Target's targ_info */ + status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count, + sizeof(targ_info->target_info_byte_count), TRUE); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); + return A_ERROR; + } + + /* + * The Target's targ_info doesn't match the Host's targ_info. + * We need to do some backwards compatibility work to make this OK. + */ + A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); + + /* Read the remainder of the targ_info */ + status = bmiBufferReceive(device, + ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), + sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", + targ_info->target_info_byte_count)); + return A_ERROR; + } + } else { + /* + * Target must be an AR6001 whose firmware does not + * support BMI_GET_TARGET_INFO. Construct the data + * that it would have sent. + */ + targ_info->target_info_byte_count=sizeof(*targ_info); + targ_info->target_type=TARGET_TYPE_AR6001; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", + targ_info->target_ver, targ_info->target_type)); + + return A_OK; +} + +A_STATUS HIFExchangeBMIMsg(HIF_DEVICE *device, + A_UINT8 *pSendMessage, + A_UINT32 Length, + A_UINT8 *pResponseMessage, + A_UINT32 *pResponseLength, + A_UINT32 TimeoutMS) +{ + A_STATUS status = A_OK; + + if (device == NULL ) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Null device argument\n")); + return A_EINVAL; + } + + do { + + status = bmiBufferSend(device, pSendMessage, Length); + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI : Unable to Send Message to device \n")); + break; + } + + if (pResponseMessage != NULL) { + status = bmiBufferReceive(device, pResponseMessage, *pResponseLength, TimeoutMS ? TRUE : FALSE); + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI : Unable to read response from device \n")); + break; + } + } + + } while (FALSE); + + return status; +} + +/* TODO .. the following APIs are a relic of the old register based interface */ + +A_STATUS +BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) +{ + return bmiBufferSend(device, buffer, length); +} + +A_STATUS +BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) +{ + return bmiBufferReceive(device, buffer, length, want_timeout); +} +#ifdef BRINGUP_DEBUG +#define SDIO_SCRATCH_1_ADDRESS 0x864 +/*Functions used for debugging*/ +A_STATUS bmiWriteScratchRegister (HIF_DEVICE *device, u_int32_t buffer) +{ + A_STATUS status = A_OK; + + + status = HIFReadWrite(device, SDIO_SCRATCH_1_ADDRESS, (A_UINT8 *)&buffer, 4, HIF_WR_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Unable to write to 0x%x\n",__func__, SDIO_SCRATCH_1_ADDRESS)); + return A_ERROR; + } + else + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wrote 0x%x to 0x%x\n", __func__, buffer, SDIO_SCRATCH_1_ADDRESS)); + + return status; +} + + +A_STATUS bmiReadScratchRegister (HIF_DEVICE *device) +{ + A_STATUS status = A_OK; + u_int32_t buffer = 0; + + + status = HIFReadWrite(device, SDIO_SCRATCH_1_ADDRESS, (A_UINT8 *)&buffer, 4, HIF_RD_SYNC_BYTE_INC, NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Unable to read from 0x%x\n", __func__, SDIO_SCRATCH_1_ADDRESS)); + return A_ERROR; + } + else + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: read 0x%x from 0x%x\n", __func__, buffer, SDIO_SCRATCH_1_ADDRESS)); + + return status; +} +#endif + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_diag_reg_access.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_diag_reg_access.c new file mode 100644 index 0000000000000..d3c69a1aba65e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_diag_reg_access.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WIN_MOBILE7 +#include +#endif + +#include "athdefs.h" +#include "a_types.h" +#include "a_osapi.h" +#define ATH_MODULE_NAME hif +#include "a_debug.h" + +#include "targaddrs.h" +#include "hif.h" +#include "if_ath_sdio.h" +#include "regtable.h" + +#define CPU_DBG_SEL_ADDRESS 0x00000483 +#define CPU_DBG_ADDRESS 0x00000484 + +/* set the window address register (using 4-byte register access ). + * This mitigates host interconnect issues with non-4byte aligned bus requests, some + * interconnects use bus adapters that impose strict limitations. + * Since diag window access is not intended for performance critical operations, the 4byte mode should + * be satisfactory even though it generates 4X the bus activity. */ +static A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) +{ + A_STATUS status; + static A_UINT32 address; + + address = Address; + +/*AR6320 use new window register access procedure,not need confuse operation as below*/ +#if 0 + for (i = 1; i <= 3; i++) { + /* fill the buffer with the address byte value we want to hit 4 times*/ + addrValue[0] = ((A_UINT8 *)&Address)[i]; + addrValue[1] = addrValue[0]; + addrValue[2] = addrValue[0]; + addrValue[3] = addrValue[0]; + + /* hit each byte of the register address with a 4-byte write operation to the same address, + * this is a harmless operation */ + status = HIFReadWrite(hifDevice, + RegisterAddr+i, + addrValue, + 4, + HIF_WR_SYNC_BYTE_FIX, + NULL); + if (status != A_OK) { + break; + } + } + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", + Address, RegisterAddr)); + return status; + } +#endif +/*AR6320,just write the 4-byte address to window register*/ + status = HIFReadWrite(hifDevice, + RegisterAddr, + (A_UCHAR *)(&address), + 4, + HIF_WR_SYNC_BYTE_INC, + NULL); + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", + Address, RegisterAddr)); + return status; + } + + return A_OK; +} + + +/* + * Read from the AR6000 through its diagnostic window. + * No cooperation from the Target is required for this. + */ +A_STATUS +HIFDiagReadAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 *data) +{ + A_STATUS status; + static A_UINT32 readvalue; + + if(address&0x03) + { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("[%s]addr is not 4 bytes align.addr[0x%08x]\n",__func__, address)); + return A_BAD_ADDRESS; + } + + /* set window register to start read cycle */ + status = ar6000_SetAddressWindowRegister(hifDevice, + WINDOW_READ_ADDR_ADDRESS, + address); + + if (status != A_OK) { + return status; + } + + /* read the data */ + status = HIFReadWrite(hifDevice, + WINDOW_DATA_ADDRESS, + (A_UCHAR *)&readvalue, + sizeof(A_UINT32), + HIF_RD_SYNC_BYTE_INC, + NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n")); + return status; + } + + *data = readvalue; + return status; +} + + +/* + * Write to the AR6000 through its diagnostic window. + * No cooperation from the Target is required for this. + */ +A_STATUS HIFDiagWriteAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 data) +{ + A_STATUS status; + static A_UINT32 writeValue; + + if(address&0x03) + { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("[%s]addr is not 4 bytes align.addr[0x%08x]\n",__func__, address)); + return A_BAD_ADDRESS; + } + + writeValue = data; + + /* set write data */ + status = HIFReadWrite(hifDevice, + WINDOW_DATA_ADDRESS, + (A_UCHAR *)&writeValue, + sizeof(A_UINT32), + HIF_WR_SYNC_BYTE_INC, + NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", data)); + return status; + } + + /* set window register, which starts the write cycle */ + return ar6000_SetAddressWindowRegister(hifDevice, + WINDOW_WRITE_ADDR_ADDRESS, + address); +} + +/* + * Write a block data to the AR6000 through its diagnostic window. + * This function may take some time. + * No cooperation from the Target is required for this. + */ +A_STATUS +HIFDiagWriteMem(HIF_DEVICE *hif_device, A_UINT32 address, A_UINT8 *data, int nbytes) +{ + A_STATUS status; + A_INT32 i; + A_UINT32 tmp_data; + + if((address&0x03) || (nbytes&0x03)) + { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("[%s]addr or length is not 4 bytes align.addr[0x%08x] len[0x%08x]\n",__func__, address, nbytes)); + return A_BAD_ADDRESS; + } + + for(i=0;i>8 & 0xff; + data[i+2] = tmp_data>>16 & 0xff; + data[i+3] = tmp_data>>24 & 0xff; + } + + return A_OK; +} + +/* TODO .. the following APIs are only available on register-based HIFs where the CPU_DBG_SEL_ADDRESS + * register is available */ + +A_STATUS +ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval) +{ + A_STATUS status; + A_UCHAR vals[4]; + A_UCHAR register_selection[4]; + + register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff); + status = HIFReadWrite(hifDevice, + CPU_DBG_SEL_ADDRESS, + register_selection, + 4, + HIF_WR_SYNC_BYTE_FIX, + NULL); + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel)); + return status; + } + + status = HIFReadWrite(hifDevice, + CPU_DBG_ADDRESS, + (A_UCHAR *)vals, + sizeof(vals), + HIF_RD_SYNC_BYTE_INC, + NULL); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n")); + return status; + } + + *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24; + + return status; +} + +void +ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs) +{ + int i; + A_UINT32 val; + + for (i=0; i +#endif +#include "hif_trace.h" + +#ifndef HIF_SDIO_COMMON_H_ +#define HIF_SDIO_COMMON_H_ + +#ifndef INLINE +#ifdef __GNUC__ +#define INLINE __inline__ +#else +#define INLINE __inline +#endif +#endif + /* SDIO manufacturer ID and Codes */ +#define MANUFACTURER_ID_AR6002_BASE 0x200 +#define MANUFACTURER_ID_AR6003_BASE 0x300 +#define MANUFACTURER_ID_AR6004_BASE 0x400 +#define MANUFACTURER_ID_AR6320_BASE 0x500 /* AR6320_TBDXXX */ +#define MANUFACTURER_ID_QCA9377_BASE 0x700 /* QCA9377 */ +#define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00 +#define MANUFACTURER_ID_AR6K_REV_MASK 0x00FF +#define FUNCTION_CLASS 0x0 +#define MANUFACTURER_CODE 0x271 /* Atheros */ + + /* Mailbox address in SDIO address space */ +#if defined(SDIO_3_0) +#define HIF_MBOX_BASE_ADDR 0x1000 +#define HIF_MBOX_DUMMY_WIDTH 0x800 +#else +#define HIF_MBOX_BASE_ADDR 0x800 +#define HIF_MBOX_DUMMY_WIDTH 0 +#endif + +#define HIF_MBOX_WIDTH 0x800 + +#define HIF_MBOX_START_ADDR(mbox) \ + ( HIF_MBOX_BASE_ADDR + mbox * (HIF_MBOX_WIDTH + HIF_MBOX_DUMMY_WIDTH) ) + +#define HIF_MBOX_END_ADDR(mbox) \ + (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1) + + /* extended MBOX address for larger MBOX writes to MBOX 0*/ +#if defined(SDIO_3_0) +#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x5000 +#else +#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800 +#endif +#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024) +#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024) + + /* version 1 of the chip has only a 12K extended mbox range */ +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024) + +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6004 0x2800 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6004 (18*1024) + + +#if defined(SDIO_3_0) +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x5000 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (36*1024) +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320_ROME_2_0 (56*1024) +#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (36*1024) +#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 (2*1024) +#else +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x2800 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (24*1024) +#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (24*1024) +#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 0 +#endif + + + /* GMBOX addresses */ +#define HIF_GMBOX_BASE_ADDR 0x7000 +#define HIF_GMBOX_WIDTH 0x4000 + + /* for SDIO we recommend a 128-byte block size */ +#define HIF_DEFAULT_IO_BLOCK_SIZE 128 + + /* set extended MBOX window information for SDIO interconnects */ +static INLINE void SetExtendedMboxWindowInfo(A_UINT16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo) +{ + switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) { + case MANUFACTURER_ID_AR6002_BASE : + /* MBOX 0 has an extended range */ + + /**** FIXME .. AR6004 currently masquerades as an AR6002 device + * and thus it's actual extended window size will be incorrectly + * set. Temporarily force the location and size to match AR6004 ****/ + //pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR; + //pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002; + + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1; + + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1; + + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6004; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6004; + + break; + case MANUFACTURER_ID_AR6003_BASE : + /* MBOX 0 has an extended range */ + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1; + pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR; + pInfo->GMboxSize = HIF_GMBOX_WIDTH; + break; + case MANUFACTURER_ID_AR6004_BASE : + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6004; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6004; + pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR; + pInfo->GMboxSize = HIF_GMBOX_WIDTH; + break; + case MANUFACTURER_ID_AR6320_BASE :{ + A_UINT16 ManuRevID = Manfid & MANUFACTURER_ID_AR6K_REV_MASK; + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320; + if (ManuRevID < 4){ + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6320; + } else { + /* from rome 2.0(0x504), the width has been extended to 56K */ +#if defined(SDIO_3_0) + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6320_ROME_2_0; +#else + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6320; +#endif + } +#if defined(SDIO_3_0) + pInfo->MboxProp[1].ExtendedAddress = pInfo->MboxProp[0].ExtendedAddress + + pInfo->MboxProp[0].ExtendedSize + HIF_MBOX_DUMMY_SPACE_SIZE_AR6320; + pInfo->MboxProp[1].ExtendedSize = HIF_MBOX1_EXTENDED_WIDTH_AR6320; +#endif + pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR; + pInfo->GMboxSize = HIF_GMBOX_WIDTH; + break; + } + case MANUFACTURER_ID_QCA9377_BASE : + pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320; + pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6320_ROME_2_0; + pInfo->MboxProp[1].ExtendedAddress = pInfo->MboxProp[0].ExtendedAddress + + pInfo->MboxProp[0].ExtendedSize + HIF_MBOX_DUMMY_SPACE_SIZE_AR6320; + pInfo->MboxProp[1].ExtendedSize = HIF_MBOX1_EXTENDED_WIDTH_AR6320; + pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR; + pInfo->GMboxSize = HIF_GMBOX_WIDTH; + break; + default: + A_ASSERT(FALSE); + break; + } +} + +/* + In SDIO 2.0, asynchronous interrupt is not in SPEC requirement, but AR6003 support it, so the register + is placed in vendor specific field 0xF0(bit0) + In SDIO 3.0, the register is defined in SPEC, and its address is 0x16(bit1) +*/ + +#define CCCR_SDIO_IRQ_MODE_REG_AR6003 0xF0 /* interrupt mode register of AR6003*/ +#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003 (1 << 0) /* mode to enable special 4-bit interrupt assertion without clock*/ + +#define CCCR_SDIO_IRQ_MODE_REG_AR6320 0x16 /* interrupt mode register of AR6320*/ +#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320 (1 << 1) /* mode to enable special 4-bit interrupt assertion without clock*/ + + +#define CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS 0xF0 +#define CCCR_SDIO_ASYNC_INT_DELAY_LSB 0x06 +#define CCCR_SDIO_ASYNC_INT_DELAY_MASK 0xC0 + +#endif /*HIF_SDIO_COMMON_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_trace.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_trace.h new file mode 100644 index 0000000000000..59af5a840780b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/common/hif_trace.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//============================================================================== +// HIF specific declarations and prototypes +// +// Author(s): ="Atheros" +//============================================================================== +#ifndef _HIF_TRACE_H_ +#define _HIF_TRACE_H_ + +#include "vos_trace.h" +#ifdef ENTER +#undef ENTER +#endif +#define ENTER(fmt,...) VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO, "Enter: %s "fmt, __FUNCTION__,## __VA_ARGS__) + +#ifdef EXIT +#undef EXIT +#endif +#define EXIT(fmt,...) VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO, "Exit: %s "fmt, __FUNCTION__,## __VA_ARGS__) + +#endif //_HIF_TRACE_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320def.h new file mode 100644 index 0000000000000..4f9da9982265d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320def.h @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320DEF_H_ +#define _AR6320DEF_H_ + +/* Base Addresses */ +#define AR6320_RTC_SOC_BASE_ADDRESS 0x00000000 +#define AR6320_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320_CE0_BASE_ADDRESS 0x00034400 +#define AR6320_CE1_BASE_ADDRESS 0x00034800 +#define AR6320_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320_CE3_BASE_ADDRESS 0x00035000 +#define AR6320_CE4_BASE_ADDRESS 0x00035400 +#define AR6320_CE5_BASE_ADDRESS 0x00035800 +#define AR6320_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320_CE7_BASE_ADDRESS 0x00036000 +#define AR6320_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320_SCRATCH_3_ADDRESS 0x0028 +#define AR6320_TARG_DRAM_START 0x00400000 +#define AR6320_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320_SI_CONFIG_I2C_LSB 16 +#define AR6320_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320_SI_CONFIG_OFFSET 0x00000000 +#define AR6320_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320_SI_CS_OFFSET 0x00000004 +#define AR6320_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320_SI_CS_START_LSB 8 +#define AR6320_SI_CS_START_MASK 0x00000100 +#define AR6320_SI_CS_RX_CNT_LSB 4 +#define AR6320_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320_SI_CS_TX_CNT_LSB 0 +#define AR6320_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320_CE_COUNT 8 +#define AR6320_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320_HOST_IS_ADDRESS 0x0030 +#define AR6320_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320_HOST_IE_ADDRESS 0x002c +#define AR6320_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320_SR_BA_ADDRESS 0x0000 +#define AR6320_SR_SIZE_ADDRESS 0x0004 +#define AR6320_CE_CTRL1_ADDRESS 0x0010 +#define AR6320_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320_DR_BA_ADDRESS 0x0008 +#define AR6320_DR_SIZE_ADDRESS 0x000c +#define AR6320_MISC_IE_ADDRESS 0x0034 +#define AR6320_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320_SRC_WATERMARK_LOW_LSB 16 +#define AR6320_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320_DST_WATERMARK_LOW_LSB 16 +#define AR6320_DST_WATERMARK_HIGH_LSB 0 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320_RTC_STATE_ADDRESS 0x0000 +#define AR6320_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320_RTC_STATE_V_MASK 0x00000007 +#define AR6320_RTC_STATE_V_LSB 0 +#define AR6320_RTC_STATE_V_ON 3 +#define AR6320_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320_FW_IND_EVENT_PENDING 1 +#define AR6320_FW_IND_INITIALIZED 2 +#define AR6320_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320_CPU_INTR_ADDRESS 0x0010 +#define AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320_CORE_CTRL_ADDRESS 0x0000 +#define AR6320_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320_SOC_CHIP_ID_REVISION_LSB 8 + +#define AR6320_PCIE_INTR_CE_MASK(n) (AR6320_PCIE_INTR_CE0_MASK << (n)) +#define AR6320_DRAM_BASE_ADDRESS AR6320_TARG_DRAM_START +#define AR6320_FW_INDICATOR_ADDRESS (AR6320_SOC_CORE_BASE_ADDRESS + AR6320_SCRATCH_3_ADDRESS) +#define AR6320_SYSTEM_SLEEP_OFFSET AR6320_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320_WLAN_RESET_CONTROL_OFFSET AR6320_SOC_RESET_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_OFFSET AR6320_SOC_CLOCK_CONTROL_OFFSET +#define AR6320_CLOCK_CONTROL_SI0_CLK_MASK AR6320_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320_RESET_CONTROL_SI0_RST_MASK AR6320_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320_GPIO_BASE_ADDRESS AR6320_WLAN_GPIO_BASE_ADDRESS +#define AR6320_GPIO_PIN0_OFFSET AR6320_WLAN_GPIO_PIN0_ADDRESS +#define AR6320_GPIO_PIN1_OFFSET AR6320_WLAN_GPIO_PIN1_ADDRESS +#define AR6320_GPIO_PIN0_CONFIG_MASK AR6320_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320_GPIO_PIN1_CONFIG_MASK AR6320_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320_SI_BASE_ADDRESS 0x00050000 +#define AR6320_CPU_CLOCK_OFFSET AR6320_SOC_CPU_CLOCK_OFFSET +#define AR6320_LPO_CAL_OFFSET AR6320_SOC_LPO_CAL_OFFSET +#define AR6320_GPIO_PIN10_OFFSET AR6320_WLAN_GPIO_PIN10_ADDRESS +#define AR6320_GPIO_PIN11_OFFSET AR6320_WLAN_GPIO_PIN11_ADDRESS +#define AR6320_GPIO_PIN12_OFFSET AR6320_WLAN_GPIO_PIN12_ADDRESS +#define AR6320_GPIO_PIN13_OFFSET AR6320_WLAN_GPIO_PIN13_ADDRESS +#define AR6320_CPU_CLOCK_STANDARD_LSB AR6320_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320_CPU_CLOCK_STANDARD_MASK AR6320_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320_LPO_CAL_ENABLE_LSB AR6320_SOC_LPO_CAL_ENABLE_LSB +#define AR6320_LPO_CAL_ENABLE_MASK AR6320_SOC_LPO_CAL_ENABLE_MASK +#define AR6320_ANALOG_INTF_BASE_ADDRESS AR6320_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320_COUNT_DEC_ADDRESS 0x0840 +#define AR6320_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320_WINDOW_WRITE_ADDR_ADDRESS 0x0878 +#define AR6320_HOST_INT_STATUS_MBOX_DATA_MASK 0x0f +#define AR6320_HOST_INT_STATUS_MBOX_DATA_LSB 0 + +struct targetdef_s ar6320_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR6320_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR6320_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR6320_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif +#ifdef HIF_PCI + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +#endif +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320v2def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320v2def.h new file mode 100644 index 0000000000000..3db4d3758a5ac --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar6320v2def.h @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR6320V2DEF_H_ +#define _AR6320V2DEF_H_ + +/* Base Addresses */ +#define AR6320V2_RTC_SOC_BASE_ADDRESS 0x00000800 +#define AR6320V2_RTC_WMAC_BASE_ADDRESS 0x00001000 +#define AR6320V2_MAC_COEX_BASE_ADDRESS 0x0000f000 +#define AR6320V2_BT_COEX_BASE_ADDRESS 0x00002000 +#define AR6320V2_SOC_PCIE_BASE_ADDRESS 0x00038000 +#define AR6320V2_SOC_CORE_BASE_ADDRESS 0x0003a000 +#define AR6320V2_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR6320V2_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR6320V2_WLAN_GPIO_BASE_ADDRESS 0x00005000 +#define AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000 +#define AR6320V2_WLAN_MAC_BASE_ADDRESS 0x00010000 +#define AR6320V2_EFUSE_BASE_ADDRESS 0x00024000 +#define AR6320V2_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR6320V2_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR6320V2_CE_WRAPPER_BASE_ADDRESS 0x00034000 +#define AR6320V2_CE0_BASE_ADDRESS 0x00034400 +#define AR6320V2_CE1_BASE_ADDRESS 0x00034800 +#define AR6320V2_CE2_BASE_ADDRESS 0x00034c00 +#define AR6320V2_CE3_BASE_ADDRESS 0x00035000 +#define AR6320V2_CE4_BASE_ADDRESS 0x00035400 +#define AR6320V2_CE5_BASE_ADDRESS 0x00035800 +#define AR6320V2_CE6_BASE_ADDRESS 0x00035c00 +#define AR6320V2_CE7_BASE_ADDRESS 0x00036000 +#define AR6320V2_DBI_BASE_ADDRESS 0x0003c000 +#define AR6320V2_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800 + +#define AR6320V2_SCRATCH_3_ADDRESS 0x0028 +#define AR6320V2_TARG_DRAM_START 0x00400000 +#define AR6320V2_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0 +#define AR6320V2_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR6320V2_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000 +#define AR6320V2_WLAN_GPIO_PIN0_ADDRESS 0x00000068 +#define AR6320V2_WLAN_GPIO_PIN1_ADDRESS 0x0000006c +#define AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR6320V2_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR6320V2_WLAN_GPIO_PIN10_ADDRESS 0x00000090 +#define AR6320V2_WLAN_GPIO_PIN11_ADDRESS 0x00000094 +#define AR6320V2_WLAN_GPIO_PIN12_ADDRESS 0x00000098 +#define AR6320V2_WLAN_GPIO_PIN13_ADDRESS 0x0000009c +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR6320V2_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR6320V2_SOC_LPO_CAL_ENABLE_MASK 0x00100000 + +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR6320V2_SI_CONFIG_I2C_LSB 16 +#define AR6320V2_SI_CONFIG_I2C_MASK 0x00010000 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR6320V2_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR6320V2_SI_CONFIG_DIVIDER_LSB 0 +#define AR6320V2_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR6320V2_SI_CONFIG_OFFSET 0x00000000 +#define AR6320V2_SI_TX_DATA0_OFFSET 0x00000008 +#define AR6320V2_SI_TX_DATA1_OFFSET 0x0000000c +#define AR6320V2_SI_RX_DATA0_OFFSET 0x00000010 +#define AR6320V2_SI_RX_DATA1_OFFSET 0x00000014 +#define AR6320V2_SI_CS_OFFSET 0x00000004 +#define AR6320V2_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR6320V2_SI_CS_DONE_INT_MASK 0x00000200 +#define AR6320V2_SI_CS_START_LSB 8 +#define AR6320V2_SI_CS_START_MASK 0x00000100 +#define AR6320V2_SI_CS_RX_CNT_LSB 4 +#define AR6320V2_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR6320V2_SI_CS_TX_CNT_LSB 0 +#define AR6320V2_SI_CS_TX_CNT_MASK 0x0000000f +#define AR6320V2_CE_COUNT 8 +#define AR6320V2_SR_WR_INDEX_ADDRESS 0x003c +#define AR6320V2_DST_WATERMARK_ADDRESS 0x0050 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR6320V2_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff + +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR6320V2_DST_WR_INDEX_ADDRESS 0x0040 +#define AR6320V2_SRC_WATERMARK_ADDRESS 0x004c +#define AR6320V2_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR6320V2_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR6320V2_CURRENT_SRRI_ADDRESS 0x0044 +#define AR6320V2_CURRENT_DRRI_ADDRESS 0x0048 +#define AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR6320V2_HOST_IS_ADDRESS 0x0030 +#define AR6320V2_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR6320V2_HOST_IE_ADDRESS 0x002c +#define AR6320V2_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR6320V2_SR_BA_ADDRESS 0x0000 +#define AR6320V2_SR_SIZE_ADDRESS 0x0004 +#define AR6320V2_CE_CTRL1_ADDRESS 0x0010 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR6320V2_DR_BA_ADDRESS 0x0008 +#define AR6320V2_DR_SIZE_ADDRESS 0x000c +#define AR6320V2_MISC_IE_ADDRESS 0x0034 +#define AR6320V2_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR6320V2_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR6320V2_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR6320V2_SRC_WATERMARK_LOW_LSB 16 +#define AR6320V2_SRC_WATERMARK_HIGH_LSB 0 +#define AR6320V2_DST_WATERMARK_LOW_LSB 16 +#define AR6320V2_DST_WATERMARK_HIGH_LSB 0 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020 +#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5 +#define AR6320V2_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR6320V2_RTC_STATE_ADDRESS 0x0000 +#define AR6320V2_RTC_STATE_COLD_RESET_MASK 0x00002000 +#define AR6320V2_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR6320V2_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR6320V2_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR6320V2_RTC_STATE_V_MASK 0x00000007 +#define AR6320V2_RTC_STATE_V_LSB 0 +#define AR6320V2_RTC_STATE_V_ON 3 +#define AR6320V2_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR6320V2_FW_IND_EVENT_PENDING 1 +#define AR6320V2_FW_IND_INITIALIZED 2 +#define AR6320V2_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR6320V2_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR6320V2_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR6320V2_PCIE_INTR_CE0_MASK 0x00000800 +#define AR6320V2_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR6320V2_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR6320V2_CPU_INTR_ADDRESS 0x0010 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR6320V2_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001 +#define AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR6320V2_CORE_CTRL_ADDRESS 0x0000 +#define AR6320V2_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR6320V2_LOCAL_SCRATCH_OFFSET 0x000000c0 +#define AR6320V2_CLOCK_GPIO_OFFSET 0xffffffff +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 +#define AR6320V2_SOC_CHIP_ID_ADDRESS 0x000000f0 +#define AR6320V2_SOC_CHIP_ID_VERSION_MASK 0xfffc0000 +#define AR6320V2_SOC_CHIP_ID_VERSION_LSB 18 +#define AR6320V2_SOC_CHIP_ID_REVISION_MASK 0x00000f00 +#define AR6320V2_SOC_CHIP_ID_REVISION_LSB 8 + +#define AR6320V2_PCIE_INTR_CE_MASK(n) (AR6320V2_PCIE_INTR_CE0_MASK << (n)) +#define AR6320V2_DRAM_BASE_ADDRESS AR6320V2_TARG_DRAM_START +#define AR6320V2_FW_INDICATOR_ADDRESS (AR6320V2_SOC_CORE_BASE_ADDRESS + AR6320V2_SCRATCH_3_ADDRESS) +#define AR6320V2_SYSTEM_SLEEP_OFFSET AR6320V2_SOC_SYSTEM_SLEEP_OFFSET +#define AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET 0x002c +#define AR6320V2_WLAN_RESET_CONTROL_OFFSET AR6320V2_SOC_RESET_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_OFFSET AR6320V2_SOC_CLOCK_CONTROL_OFFSET +#define AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR6320V2_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define AR6320V2_RESET_CONTROL_SI0_RST_MASK AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR6320V2_GPIO_BASE_ADDRESS AR6320V2_WLAN_GPIO_BASE_ADDRESS +#define AR6320V2_GPIO_PIN0_OFFSET AR6320V2_WLAN_GPIO_PIN0_ADDRESS +#define AR6320V2_GPIO_PIN1_OFFSET AR6320V2_WLAN_GPIO_PIN1_ADDRESS +#define AR6320V2_GPIO_PIN0_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR6320V2_GPIO_PIN1_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR6320V2_SI_BASE_ADDRESS 0x00050000 +#define AR6320V2_CPU_CLOCK_OFFSET AR6320V2_SOC_CPU_CLOCK_OFFSET +#define AR6320V2_LPO_CAL_OFFSET AR6320V2_SOC_LPO_CAL_OFFSET +#define AR6320V2_GPIO_PIN10_OFFSET AR6320V2_WLAN_GPIO_PIN10_ADDRESS +#define AR6320V2_GPIO_PIN11_OFFSET AR6320V2_WLAN_GPIO_PIN11_ADDRESS +#define AR6320V2_GPIO_PIN12_OFFSET AR6320V2_WLAN_GPIO_PIN12_ADDRESS +#define AR6320V2_GPIO_PIN13_OFFSET AR6320V2_WLAN_GPIO_PIN13_ADDRESS +#define AR6320V2_CPU_CLOCK_STANDARD_LSB AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB +#define AR6320V2_CPU_CLOCK_STANDARD_MASK AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK +#define AR6320V2_LPO_CAL_ENABLE_LSB AR6320V2_SOC_LPO_CAL_ENABLE_LSB +#define AR6320V2_LPO_CAL_ENABLE_MASK AR6320V2_SOC_LPO_CAL_ENABLE_MASK +#define AR6320V2_ANALOG_INTF_BASE_ADDRESS AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR6320V2_MBOX_BASE_ADDRESS 0x00008000 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_LSB 7 +#define AR6320V2_INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define AR6320V2_INT_STATUS_ENABLE_CPU_LSB 6 +#define AR6320V2_INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB 4 +#define AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16 +#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24 +#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000 +#define AR6320V2_INT_STATUS_ENABLE_ADDRESS 0x0828 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB 8 +#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00 +#define AR6320V2_HOST_INT_STATUS_ADDRESS 0x0800 +#define AR6320V2_CPU_INT_STATUS_ADDRESS 0x0801 +#define AR6320V2_ERROR_INT_STATUS_ADDRESS 0x0802 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000 +#define AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB 18 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000 +#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000 +#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16 +#define AR6320V2_COUNT_DEC_ADDRESS 0x0840 +#define AR6320V2_HOST_INT_STATUS_CPU_MASK 0x00000040 +#define AR6320V2_HOST_INT_STATUS_CPU_LSB 6 +#define AR6320V2_HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define AR6320V2_HOST_INT_STATUS_ERROR_LSB 7 +#define AR6320V2_HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define AR6320V2_HOST_INT_STATUS_COUNTER_LSB 4 +#define AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS 0x0805 +#define AR6320V2_WINDOW_DATA_ADDRESS 0x0874 +#define AR6320V2_WINDOW_READ_ADDR_ADDRESS 0x087c +#define AR6320V2_WINDOW_WRITE_ADDR_ADDRESS 0x0878 +#define AR6320V2_HOST_INT_STATUS_MBOX_DATA_MASK 0x0f +#define AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB 0 + +struct targetdef_s ar6320v2_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR6320V2_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR6320V2_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR6320V2_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR6320V2_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR6320V2_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR6320V2_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR6320V2_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR6320V2_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR6320V2_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR6320V2_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR6320V2_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR6320V2_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR6320V2_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR6320V2_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320V2_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320V2_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR6320V2_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR6320V2_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR6320V2_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR6320V2_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR6320V2_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR6320V2_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR6320V2_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR6320V2_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR6320V2_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR6320V2_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR6320V2_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR6320V2_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR6320V2_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR6320V2_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR6320V2_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR6320V2_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR6320V2_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR6320V2_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR6320V2_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR6320V2_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR6320V2_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR6320V2_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR6320V2_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR6320V2_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR6320V2_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR6320V2_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR6320V2_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR6320V2_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR6320V2_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR6320V2_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR6320V2_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR6320V2_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR6320V2_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR6320V2_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR6320V2_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR6320V2_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR6320V2_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR6320V2_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR6320V2_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR6320V2_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR6320V2_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR6320V2_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR6320V2_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR6320V2_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR6320V2_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR6320V2_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320V2_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320V2_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR6320V2_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR6320V2_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR6320V2_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR6320V2_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR6320V2_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR6320V2_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR6320V2_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR6320V2_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR6320V2_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR6320V2_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR6320V2_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR6320V2_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR6320V2_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR6320V2_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR6320V2_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR6320V2_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR6320V2_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR6320V2_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR6320V2_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR6320V2_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320V2_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320V2_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR6320V2_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR6320V2_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR6320V2_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR6320V2_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + + .d_PCIE_INTR_CAUSE_ADDRESS = AR6320V2_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR6320V2_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR6320V2_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, + /* chip id start */ + .d_SOC_CHIP_ID_ADDRESS = AR6320V2_SOC_CHIP_ID_ADDRESS, + .d_SOC_CHIP_ID_VERSION_MASK = AR6320V2_SOC_CHIP_ID_VERSION_MASK, + .d_SOC_CHIP_ID_VERSION_LSB = AR6320V2_SOC_CHIP_ID_VERSION_LSB, + .d_SOC_CHIP_ID_REVISION_MASK = AR6320V2_SOC_CHIP_ID_REVISION_MASK, + .d_SOC_CHIP_ID_REVISION_LSB = AR6320V2_SOC_CHIP_ID_REVISION_LSB, + /* chip id end */ +}; + +struct hostdef_s ar6320v2_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320V2_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320V2_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR6320V2_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR6320V2_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR6320V2_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR6320V2_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR6320V2_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR6320V2_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR6320V2_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR6320V2_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR6320V2_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR6320V2_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR6320V2_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR6320V2_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR6320V2_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR6320V2_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR6320V2_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320V2_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR6320V2_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR6320V2_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR6320V2_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR6320V2_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR6320V2_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR6320V2_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR6320V2_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR6320V2_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR6320V2_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR6320V2_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR6320V2_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR6320V2_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320V2_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif +#ifdef HIF_PCI + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +#endif +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar9888def.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar9888def.h new file mode 100644 index 0000000000000..7c0095bddbc8b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/ar9888def.h @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _AR9888DEF_H_ +#define AR9888__AR9888DEF_H_ + +/* Base Addresses */ +#define AR9888_RTC_SOC_BASE_ADDRESS 0x00004000 +#define AR9888_RTC_WMAC_BASE_ADDRESS 0x00005000 +#define AR9888_MAC_COEX_BASE_ADDRESS 0x00006000 +#define AR9888_BT_COEX_BASE_ADDRESS 0x00007000 +#define AR9888_SOC_PCIE_BASE_ADDRESS 0x00008000 +#define AR9888_SOC_CORE_BASE_ADDRESS 0x00009000 +#define AR9888_WLAN_UART_BASE_ADDRESS 0x0000c000 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 +#define AR9888_WLAN_MAC_BASE_ADDRESS 0x00020000 +#define AR9888_EFUSE_BASE_ADDRESS 0x00030000 +#define AR9888_FPGA_REG_BASE_ADDRESS 0x00039000 +#define AR9888_WLAN_UART2_BASE_ADDRESS 0x00054c00 +#define AR9888_CE_WRAPPER_BASE_ADDRESS 0x00057000 +#define AR9888_CE0_BASE_ADDRESS 0x00057400 +#define AR9888_CE1_BASE_ADDRESS 0x00057800 +#define AR9888_CE2_BASE_ADDRESS 0x00057c00 +#define AR9888_CE3_BASE_ADDRESS 0x00058000 +#define AR9888_CE4_BASE_ADDRESS 0x00058400 +#define AR9888_CE5_BASE_ADDRESS 0x00058800 +#define AR9888_CE6_BASE_ADDRESS 0x00058c00 +#define AR9888_CE7_BASE_ADDRESS 0x00059000 +#define AR9888_DBI_BASE_ADDRESS 0x00060000 +#define AR9888_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 + +#define AR9888_SCRATCH_3_ADDRESS 0x0030 +#define AR9888_TARG_DRAM_START 0x00400000 +#define AR9888_SOC_SYSTEM_SLEEP_OFFSET 0x000000c4 +#define AR9888_SOC_RESET_CONTROL_OFFSET 0x00000000 +#define AR9888_SOC_CLOCK_CONTROL_OFFSET 0x00000028 +#define AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define AR9888_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define AR9888_WLAN_GPIO_BASE_ADDRESS 0x00014000 +#define AR9888_WLAN_GPIO_PIN0_ADDRESS 0x00000028 +#define AR9888_WLAN_GPIO_PIN1_ADDRESS 0x0000002c +#define AR9888_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800 +#define AR9888_WLAN_SI_BASE_ADDRESS 0x00010000 +#define AR9888_SOC_CPU_CLOCK_OFFSET 0x00000020 +#define AR9888_SOC_LPO_CAL_OFFSET 0x000000e0 +#define AR9888_WLAN_GPIO_PIN10_ADDRESS 0x00000050 +#define AR9888_WLAN_GPIO_PIN11_ADDRESS 0x00000054 +#define AR9888_WLAN_GPIO_PIN12_ADDRESS 0x00000058 +#define AR9888_WLAN_GPIO_PIN13_ADDRESS 0x0000005c +#define AR9888_SOC_CPU_CLOCK_STANDARD_LSB 0 +#define AR9888_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define AR9888_SOC_LPO_CAL_ENABLE_LSB 20 +#define AR9888_SOC_LPO_CAL_ENABLE_MASK 0x00100000 +#define AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 + +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 +#define AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define AR9888_SI_CONFIG_I2C_LSB 16 +#define AR9888_SI_CONFIG_I2C_MASK 0x00010000 +#define AR9888_SI_CONFIG_POS_SAMPLE_LSB 7 +#define AR9888_SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define AR9888_SI_CONFIG_INACTIVE_CLK_LSB 4 +#define AR9888_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define AR9888_SI_CONFIG_INACTIVE_DATA_LSB 5 +#define AR9888_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define AR9888_SI_CONFIG_DIVIDER_LSB 0 +#define AR9888_SI_CONFIG_DIVIDER_MASK 0x0000000f +#define AR9888_SI_CONFIG_OFFSET 0x00000000 +#define AR9888_SI_TX_DATA0_OFFSET 0x00000008 +#define AR9888_SI_TX_DATA1_OFFSET 0x0000000c +#define AR9888_SI_RX_DATA0_OFFSET 0x00000010 +#define AR9888_SI_RX_DATA1_OFFSET 0x00000014 +#define AR9888_SI_CS_OFFSET 0x00000004 +#define AR9888_SI_CS_DONE_ERR_MASK 0x00000400 +#define AR9888_SI_CS_DONE_INT_MASK 0x00000200 +#define AR9888_SI_CS_START_LSB 8 +#define AR9888_SI_CS_START_MASK 0x00000100 +#define AR9888_SI_CS_RX_CNT_LSB 4 +#define AR9888_SI_CS_RX_CNT_MASK 0x000000f0 +#define AR9888_SI_CS_TX_CNT_LSB 0 +#define AR9888_SI_CS_TX_CNT_MASK 0x0000000f +#define AR9888_CE_COUNT 8 +#define AR9888_SR_WR_INDEX_ADDRESS 0x003c +#define AR9888_DST_WATERMARK_ADDRESS 0x0050 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB 14 +#define AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_LSB 16 +#define AR9888_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000 +#define AR9888_RX_MPDU_START_2_PN_47_32_LSB 0 +#define AR9888_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK 0x000000ff +#define AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB 0 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16 +#define AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_LSB 15 +#define AR9888_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB 2 +#define AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004 +#define AR9888_RX_ATTENTION_0_FRAGMENT_LSB 13 +#define AR9888_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16 +#define AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB 0 +#define AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB 8 +#define AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_LSB 13 +#define AR9888_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000 +#define AR9888_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400 +#define AR9888_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000 +#define AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000 +#define AR9888_DST_WR_INDEX_ADDRESS 0x0040 +#define AR9888_SRC_WATERMARK_ADDRESS 0x004c +#define AR9888_SRC_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_SRC_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_DST_WATERMARK_LOW_MASK 0xffff0000 +#define AR9888_DST_WATERMARK_HIGH_MASK 0x0000ffff +#define AR9888_CURRENT_SRRI_ADDRESS 0x0044 +#define AR9888_CURRENT_DRRI_ADDRESS 0x0048 +#define AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002 +#define AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004 +#define AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008 +#define AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010 +#define AR9888_HOST_IS_ADDRESS 0x0030 +#define AR9888_HOST_IS_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 +#define AR9888_HOST_IE_ADDRESS 0x002c +#define AR9888_HOST_IE_COPY_COMPLETE_MASK 0x00000001 +#define AR9888_SR_BA_ADDRESS 0x0000 +#define AR9888_SR_SIZE_ADDRESS 0x0004 +#define AR9888_CE_CTRL1_ADDRESS 0x0010 +#define AR9888_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff +#define AR9888_DR_BA_ADDRESS 0x0008 +#define AR9888_DR_SIZE_ADDRESS 0x000c +#define AR9888_MISC_IE_ADDRESS 0x0034 +#define AR9888_MISC_IS_AXI_ERR_MASK 0x00000400 +#define AR9888_MISC_IS_DST_ADDR_ERR_MASK 0x00000200 +#define AR9888_MISC_IS_SRC_LEN_ERR_MASK 0x00000100 +#define AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080 +#define AR9888_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040 +#define AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020 +#define AR9888_SRC_WATERMARK_LOW_LSB 16 +#define AR9888_SRC_WATERMARK_HIGH_LSB 0 +#define AR9888_DST_WATERMARK_LOW_LSB 16 +#define AR9888_DST_WATERMARK_HIGH_LSB 0 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00 +#define AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8 +#define AR9888_CE_CTRL1_DMAX_LENGTH_LSB 0 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000 +#define AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16 +#define AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 2 +#define AR9888_SOC_GLOBAL_RESET_ADDRESS 0x0008 +#define AR9888_RTC_STATE_ADDRESS 0x0000 +#define AR9888_RTC_STATE_COLD_RESET_MASK 0x00000400 +#define AR9888_PCIE_SOC_WAKE_RESET 0x00000000 +#define AR9888_PCIE_SOC_WAKE_ADDRESS 0x0004 +#define AR9888_PCIE_SOC_WAKE_V_MASK 0x00000001 +#define AR9888_RTC_STATE_V_MASK 0x00000007 +#define AR9888_RTC_STATE_V_LSB 0 +#define AR9888_RTC_STATE_V_ON 3 +#define AR9888_PCIE_LOCAL_BASE_ADDRESS 0x80000 +#define AR9888_FW_IND_EVENT_PENDING 1 +#define AR9888_FW_IND_INITIALIZED 2 +#define AR9888_PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define AR9888_PCIE_INTR_CLR_ADDRESS 0x0014 +#define AR9888_PCIE_INTR_FIRMWARE_MASK 0x00000400 +#define AR9888_PCIE_INTR_CE0_MASK 0x00000800 +#define AR9888_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */ +#define AR9888_PCIE_INTR_CAUSE_ADDRESS 0x000c +#define AR9888_CPU_INTR_ADDRESS 0x0010 +#define AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define AR9888_SOC_RESET_CONTROL_ADDRESS 0x00000000 +#define AR9888_SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 +#define AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define AR9888_CORE_CTRL_ADDRESS 0x0000 +#define AR9888_CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define AR9888_LOCAL_SCRATCH_OFFSET 0x18 +#define AR9888_CLOCK_GPIO_OFFSET 0xffffffff +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0 +#define AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0 + +#define AR9888_PCIE_INTR_CE_MASK(n) (AR9888_PCIE_INTR_CE0_MASK << (n)) +#define AR9888_FW_EVENT_PENDING_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_DRAM_BASE_ADDRESS AR9888_TARG_DRAM_START +#define AR9888_FW_INDICATOR_ADDRESS (AR9888_SOC_CORE_BASE_ADDRESS + AR9888_SCRATCH_3_ADDRESS) +#define AR9888_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_SYSTEM_SLEEP_OFFSET AR9888_SOC_SYSTEM_SLEEP_OFFSET +#define AR9888_WLAN_RESET_CONTROL_OFFSET AR9888_SOC_RESET_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_OFFSET AR9888_SOC_CLOCK_CONTROL_OFFSET +#define AR9888_CLOCK_CONTROL_SI0_CLK_MASK AR9888_SOC_CLOCK_CONTROL_SI0_CLK_MASK +#define AR9888_RESET_CONTROL_MBOX_RST_MASK MISSING +#define AR9888_RESET_CONTROL_SI0_RST_MASK AR9888_SOC_RESET_CONTROL_SI0_RST_MASK +#define AR9888_GPIO_BASE_ADDRESS AR9888_WLAN_GPIO_BASE_ADDRESS +#define AR9888_GPIO_PIN0_OFFSET AR9888_WLAN_GPIO_PIN0_ADDRESS +#define AR9888_GPIO_PIN1_OFFSET AR9888_WLAN_GPIO_PIN1_ADDRESS +#define AR9888_GPIO_PIN0_CONFIG_MASK AR9888_WLAN_GPIO_PIN0_CONFIG_MASK +#define AR9888_GPIO_PIN1_CONFIG_MASK AR9888_WLAN_GPIO_PIN1_CONFIG_MASK +#define AR9888_SI_BASE_ADDRESS AR9888_WLAN_SI_BASE_ADDRESS +#define AR9888_SCRATCH_BASE_ADDRESS AR9888_SOC_CORE_BASE_ADDRESS +#define AR9888_CPU_CLOCK_OFFSET AR9888_SOC_CPU_CLOCK_OFFSET +#define AR9888_LPO_CAL_OFFSET AR9888_SOC_LPO_CAL_OFFSET +#define AR9888_GPIO_PIN10_OFFSET AR9888_WLAN_GPIO_PIN10_ADDRESS +#define AR9888_GPIO_PIN11_OFFSET AR9888_WLAN_GPIO_PIN11_ADDRESS +#define AR9888_GPIO_PIN12_OFFSET AR9888_WLAN_GPIO_PIN12_ADDRESS +#define AR9888_GPIO_PIN13_OFFSET AR9888_WLAN_GPIO_PIN13_ADDRESS +#define AR9888_CPU_CLOCK_STANDARD_LSB AR9888_SOC_CPU_CLOCK_STANDARD_LSB +#define AR9888_CPU_CLOCK_STANDARD_MASK AR9888_SOC_CPU_CLOCK_STANDARD_MASK +#define AR9888_LPO_CAL_ENABLE_LSB AR9888_SOC_LPO_CAL_ENABLE_LSB +#define AR9888_LPO_CAL_ENABLE_MASK AR9888_SOC_LPO_CAL_ENABLE_MASK +#define AR9888_ANALOG_INTF_BASE_ADDRESS AR9888_WLAN_ANALOG_INTF_BASE_ADDRESS +#define AR9888_MBOX_BASE_ADDRESS MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_ERROR_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_CPU_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_COUNTER_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB MISSING +#define AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB MISSING +#define AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_INT_STATUS_ENABLE_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB MISSING +#define AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK MISSING +#define AR9888_HOST_INT_STATUS_ADDRESS MISSING +#define AR9888_CPU_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_ADDRESS MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_MASK MISSING +#define AR9888_ERROR_INT_STATUS_WAKEUP_LSB MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK MISSING +#define AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB MISSING +#define AR9888_COUNT_DEC_ADDRESS MISSING +#define AR9888_HOST_INT_STATUS_CPU_MASK MISSING +#define AR9888_HOST_INT_STATUS_CPU_LSB MISSING +#define AR9888_HOST_INT_STATUS_ERROR_MASK MISSING +#define AR9888_HOST_INT_STATUS_ERROR_LSB MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_MASK MISSING +#define AR9888_HOST_INT_STATUS_COUNTER_LSB MISSING +#define AR9888_RX_LOOKAHEAD_VALID_ADDRESS MISSING +#define AR9888_WINDOW_DATA_ADDRESS MISSING +#define AR9888_WINDOW_READ_ADDR_ADDRESS MISSING +#define AR9888_WINDOW_WRITE_ADDR_ADDRESS MISSING +#define AR9888_HOST_INT_STATUS_MBOX_DATA_MASK 0x0f +#define AR9888_HOST_INT_STATUS_MBOX_DATA_LSB 0 + +struct targetdef_s ar9888_targetdef = { + .d_RTC_SOC_BASE_ADDRESS = AR9888_RTC_SOC_BASE_ADDRESS, + .d_RTC_WMAC_BASE_ADDRESS = AR9888_RTC_WMAC_BASE_ADDRESS, + .d_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_OFFSET = AR9888_WLAN_SYSTEM_SLEEP_OFFSET, + .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_LSB, + .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR9888_WLAN_SYSTEM_SLEEP_DISABLE_MASK, + .d_CLOCK_CONTROL_OFFSET = AR9888_CLOCK_CONTROL_OFFSET, + .d_CLOCK_CONTROL_SI0_CLK_MASK = AR9888_CLOCK_CONTROL_SI0_CLK_MASK, + .d_RESET_CONTROL_OFFSET = AR9888_SOC_RESET_CONTROL_OFFSET, + .d_RESET_CONTROL_MBOX_RST_MASK = AR9888_RESET_CONTROL_MBOX_RST_MASK, + .d_RESET_CONTROL_SI0_RST_MASK = AR9888_RESET_CONTROL_SI0_RST_MASK, + .d_WLAN_RESET_CONTROL_OFFSET = AR9888_WLAN_RESET_CONTROL_OFFSET, + .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR9888_WLAN_RESET_CONTROL_COLD_RST_MASK, + .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR9888_WLAN_RESET_CONTROL_WARM_RST_MASK, + .d_GPIO_BASE_ADDRESS = AR9888_GPIO_BASE_ADDRESS, + .d_GPIO_PIN0_OFFSET = AR9888_GPIO_PIN0_OFFSET, + .d_GPIO_PIN1_OFFSET = AR9888_GPIO_PIN1_OFFSET, + .d_GPIO_PIN0_CONFIG_MASK = AR9888_GPIO_PIN0_CONFIG_MASK, + .d_GPIO_PIN1_CONFIG_MASK = AR9888_GPIO_PIN1_CONFIG_MASK, + .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR9888_SI_CONFIG_BIDIR_OD_DATA_LSB, + .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR9888_SI_CONFIG_BIDIR_OD_DATA_MASK, + .d_SI_CONFIG_I2C_LSB = AR9888_SI_CONFIG_I2C_LSB, + .d_SI_CONFIG_I2C_MASK = AR9888_SI_CONFIG_I2C_MASK, + .d_SI_CONFIG_POS_SAMPLE_LSB = AR9888_SI_CONFIG_POS_SAMPLE_LSB, + .d_SI_CONFIG_POS_SAMPLE_MASK = AR9888_SI_CONFIG_POS_SAMPLE_MASK, + .d_SI_CONFIG_INACTIVE_CLK_LSB = AR9888_SI_CONFIG_INACTIVE_CLK_LSB, + .d_SI_CONFIG_INACTIVE_CLK_MASK = AR9888_SI_CONFIG_INACTIVE_CLK_MASK, + .d_SI_CONFIG_INACTIVE_DATA_LSB = AR9888_SI_CONFIG_INACTIVE_DATA_LSB, + .d_SI_CONFIG_INACTIVE_DATA_MASK = AR9888_SI_CONFIG_INACTIVE_DATA_MASK, + .d_SI_CONFIG_DIVIDER_LSB = AR9888_SI_CONFIG_DIVIDER_LSB, + .d_SI_CONFIG_DIVIDER_MASK = AR9888_SI_CONFIG_DIVIDER_MASK, + .d_SI_BASE_ADDRESS = AR9888_SI_BASE_ADDRESS, + .d_SI_CONFIG_OFFSET = AR9888_SI_CONFIG_OFFSET, + .d_SI_TX_DATA0_OFFSET = AR9888_SI_TX_DATA0_OFFSET, + .d_SI_TX_DATA1_OFFSET = AR9888_SI_TX_DATA1_OFFSET, + .d_SI_RX_DATA0_OFFSET = AR9888_SI_RX_DATA0_OFFSET, + .d_SI_RX_DATA1_OFFSET = AR9888_SI_RX_DATA1_OFFSET, + .d_SI_CS_OFFSET = AR9888_SI_CS_OFFSET, + .d_SI_CS_DONE_ERR_MASK = AR9888_SI_CS_DONE_ERR_MASK, + .d_SI_CS_DONE_INT_MASK = AR9888_SI_CS_DONE_INT_MASK, + .d_SI_CS_START_LSB = AR9888_SI_CS_START_LSB, + .d_SI_CS_START_MASK = AR9888_SI_CS_START_MASK, + .d_SI_CS_RX_CNT_LSB = AR9888_SI_CS_RX_CNT_LSB, + .d_SI_CS_RX_CNT_MASK = AR9888_SI_CS_RX_CNT_MASK, + .d_SI_CS_TX_CNT_LSB = AR9888_SI_CS_TX_CNT_LSB, + .d_SI_CS_TX_CNT_MASK = AR9888_SI_CS_TX_CNT_MASK, + .d_BOARD_DATA_SZ = AR9888_BOARD_DATA_SZ, + .d_BOARD_EXT_DATA_SZ = AR9888_BOARD_EXT_DATA_SZ, + .d_MBOX_BASE_ADDRESS = AR9888_MBOX_BASE_ADDRESS, + .d_LOCAL_SCRATCH_OFFSET = AR9888_LOCAL_SCRATCH_OFFSET, + .d_CPU_CLOCK_OFFSET = AR9888_CPU_CLOCK_OFFSET, + .d_LPO_CAL_OFFSET = AR9888_LPO_CAL_OFFSET, + .d_GPIO_PIN10_OFFSET = AR9888_GPIO_PIN10_OFFSET, + .d_GPIO_PIN11_OFFSET = AR9888_GPIO_PIN11_OFFSET, + .d_GPIO_PIN12_OFFSET = AR9888_GPIO_PIN12_OFFSET, + .d_GPIO_PIN13_OFFSET = AR9888_GPIO_PIN13_OFFSET, + .d_CLOCK_GPIO_OFFSET = AR9888_CLOCK_GPIO_OFFSET, + .d_CPU_CLOCK_STANDARD_LSB = AR9888_CPU_CLOCK_STANDARD_LSB, + .d_CPU_CLOCK_STANDARD_MASK = AR9888_CPU_CLOCK_STANDARD_MASK, + .d_LPO_CAL_ENABLE_LSB = AR9888_LPO_CAL_ENABLE_LSB, + .d_LPO_CAL_ENABLE_MASK = AR9888_LPO_CAL_ENABLE_MASK, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_LSB, + .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR9888_CLOCK_GPIO_BT_CLK_OUT_EN_MASK, + .d_ANALOG_INTF_BASE_ADDRESS = AR9888_ANALOG_INTF_BASE_ADDRESS, + .d_WLAN_MAC_BASE_ADDRESS = AR9888_WLAN_MAC_BASE_ADDRESS, + .d_CE0_BASE_ADDRESS = AR9888_CE0_BASE_ADDRESS, + .d_CE1_BASE_ADDRESS = AR9888_CE1_BASE_ADDRESS, + .d_FW_INDICATOR_ADDRESS = AR9888_FW_INDICATOR_ADDRESS, + .d_DRAM_BASE_ADDRESS = AR9888_DRAM_BASE_ADDRESS, + .d_SOC_CORE_BASE_ADDRESS = AR9888_SOC_CORE_BASE_ADDRESS, + .d_CORE_CTRL_ADDRESS = AR9888_CORE_CTRL_ADDRESS, + .d_CE_COUNT = AR9888_CE_COUNT, + .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST, + .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW, + .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL, + .d_PCIE_INTR_ENABLE_ADDRESS = AR9888_PCIE_INTR_ENABLE_ADDRESS, + .d_PCIE_INTR_CLR_ADDRESS = AR9888_PCIE_INTR_CLR_ADDRESS, + .d_PCIE_INTR_FIRMWARE_MASK = AR9888_PCIE_INTR_FIRMWARE_MASK, + .d_PCIE_INTR_CE_MASK_ALL = AR9888_PCIE_INTR_CE_MASK_ALL, + .d_CORE_CTRL_CPU_INTR_MASK = AR9888_CORE_CTRL_CPU_INTR_MASK, + .d_SR_WR_INDEX_ADDRESS = AR9888_SR_WR_INDEX_ADDRESS, + .d_DST_WATERMARK_ADDRESS = AR9888_DST_WATERMARK_ADDRESS, + /* htt_rx.c */ + .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR9888_RX_MSDU_END_4_FIRST_MSDU_MASK, + .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR9888_RX_MSDU_END_4_FIRST_MSDU_LSB, + .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR9888_RX_MPDU_START_0_SEQ_NUM_MASK, + .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR9888_RX_MPDU_START_0_SEQ_NUM_LSB, + .d_RX_MPDU_START_2_PN_47_32_LSB = AR9888_RX_MPDU_START_2_PN_47_32_LSB, + .d_RX_MPDU_START_2_PN_47_32_MASK = AR9888_RX_MPDU_START_2_PN_47_32_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK, + .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR9888_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB, + .d_RX_MSDU_END_1_KEY_ID_OCT_MASK = AR9888_RX_MSDU_END_1_KEY_ID_OCT_MASK, + .d_RX_MSDU_END_1_KEY_ID_OCT_LSB = AR9888_RX_MSDU_END_1_KEY_ID_OCT_LSB, + .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR9888_RX_MSDU_END_4_LAST_MSDU_MASK, + .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR9888_RX_MSDU_END_4_LAST_MSDU_LSB, + .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR9888_RX_ATTENTION_0_MCAST_BCAST_MASK, + .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR9888_RX_ATTENTION_0_MCAST_BCAST_LSB, + .d_RX_ATTENTION_0_FRAGMENT_MASK = AR9888_RX_ATTENTION_0_FRAGMENT_MASK, + .d_RX_ATTENTION_0_FRAGMENT_LSB = AR9888_RX_ATTENTION_0_FRAGMENT_LSB, + .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR9888_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK, + .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR9888_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB, + .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR9888_RX_MSDU_START_0_MSDU_LENGTH_MASK, + .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR9888_RX_MSDU_START_0_MSDU_LENGTH_LSB, + .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR9888_RX_MSDU_START_2_DECAP_FORMAT_OFFSET, + .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR9888_RX_MSDU_START_2_DECAP_FORMAT_MASK, + .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR9888_RX_MSDU_START_2_DECAP_FORMAT_LSB, + .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR9888_RX_MPDU_START_0_ENCRYPTED_MASK, + .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR9888_RX_MPDU_START_0_ENCRYPTED_LSB, + .d_RX_ATTENTION_0_MORE_DATA_MASK = AR9888_RX_ATTENTION_0_MORE_DATA_MASK, + .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR9888_RX_ATTENTION_0_MSDU_DONE_MASK, + .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR9888_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK, + /* copy_engine.c */ + .d_DST_WR_INDEX_ADDRESS = AR9888_DST_WR_INDEX_ADDRESS, + .d_SRC_WATERMARK_ADDRESS = AR9888_SRC_WATERMARK_ADDRESS, + .d_SRC_WATERMARK_LOW_MASK = AR9888_SRC_WATERMARK_LOW_MASK, + .d_SRC_WATERMARK_HIGH_MASK = AR9888_SRC_WATERMARK_HIGH_MASK, + .d_DST_WATERMARK_LOW_MASK = AR9888_DST_WATERMARK_LOW_MASK, + .d_DST_WATERMARK_HIGH_MASK = AR9888_DST_WATERMARK_HIGH_MASK, + .d_CURRENT_SRRI_ADDRESS = AR9888_CURRENT_SRRI_ADDRESS, + .d_CURRENT_DRRI_ADDRESS = AR9888_CURRENT_DRRI_ADDRESS, + .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_SRC_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_HIGH_WATERMARK_MASK, + .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR9888_HOST_IS_DST_RING_LOW_WATERMARK_MASK, + .d_HOST_IS_ADDRESS = AR9888_HOST_IS_ADDRESS, + .d_HOST_IS_COPY_COMPLETE_MASK = AR9888_HOST_IS_COPY_COMPLETE_MASK, + .d_CE_WRAPPER_BASE_ADDRESS = AR9888_CE_WRAPPER_BASE_ADDRESS, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS, + .d_HOST_IE_ADDRESS = AR9888_HOST_IE_ADDRESS, + .d_HOST_IE_COPY_COMPLETE_MASK = AR9888_HOST_IE_COPY_COMPLETE_MASK, + .d_SR_BA_ADDRESS = AR9888_SR_BA_ADDRESS, + .d_SR_SIZE_ADDRESS = AR9888_SR_SIZE_ADDRESS, + .d_CE_CTRL1_ADDRESS = AR9888_CE_CTRL1_ADDRESS, + .d_CE_CTRL1_DMAX_LENGTH_MASK = AR9888_CE_CTRL1_DMAX_LENGTH_MASK, + .d_DR_BA_ADDRESS = AR9888_DR_BA_ADDRESS, + .d_DR_SIZE_ADDRESS = AR9888_DR_SIZE_ADDRESS, + .d_MISC_IE_ADDRESS = AR9888_MISC_IE_ADDRESS, + .d_MISC_IS_AXI_ERR_MASK = AR9888_MISC_IS_AXI_ERR_MASK, + .d_MISC_IS_DST_ADDR_ERR_MASK = AR9888_MISC_IS_DST_ADDR_ERR_MASK, + .d_MISC_IS_SRC_LEN_ERR_MASK = AR9888_MISC_IS_SRC_LEN_ERR_MASK, + .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR9888_MISC_IS_DST_MAX_LEN_VIO_MASK, + .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR9888_MISC_IS_DST_RING_OVERFLOW_MASK, + .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR9888_MISC_IS_SRC_RING_OVERFLOW_MASK, + .d_SRC_WATERMARK_LOW_LSB = AR9888_SRC_WATERMARK_LOW_LSB, + .d_SRC_WATERMARK_HIGH_LSB = AR9888_SRC_WATERMARK_HIGH_LSB, + .d_DST_WATERMARK_LOW_LSB = AR9888_DST_WATERMARK_LOW_LSB, + .d_DST_WATERMARK_HIGH_LSB = AR9888_DST_WATERMARK_HIGH_LSB, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK, + .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR9888_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB, + .d_CE_CTRL1_DMAX_LENGTH_LSB = AR9888_CE_CTRL1_DMAX_LENGTH_LSB, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK, + .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB, + .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR9888_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB, + + .d_PCIE_INTR_CAUSE_ADDRESS = AR9888_PCIE_INTR_CAUSE_ADDRESS, + .d_SOC_RESET_CONTROL_ADDRESS = AR9888_SOC_RESET_CONTROL_ADDRESS, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK, + .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR9888_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB, + .d_SOC_RESET_CONTROL_CE_RST_MASK = AR9888_SOC_RESET_CONTROL_CE_RST_MASK, + .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR9888_SOC_RESET_CONTROL_CPU_WARM_RST_MASK, + .d_CPU_INTR_ADDRESS = AR9888_CPU_INTR_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR9888_SOC_LF_TIMER_CONTROL0_ADDRESS, + .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR9888_SOC_LF_TIMER_CONTROL0_ENABLE_MASK, +}; + +struct hostdef_s ar9888_hostdef = { + .d_INT_STATUS_ENABLE_ERROR_LSB = AR9888_INT_STATUS_ENABLE_ERROR_LSB, + .d_INT_STATUS_ENABLE_ERROR_MASK = AR9888_INT_STATUS_ENABLE_ERROR_MASK, + .d_INT_STATUS_ENABLE_CPU_LSB = AR9888_INT_STATUS_ENABLE_CPU_LSB, + .d_INT_STATUS_ENABLE_CPU_MASK = AR9888_INT_STATUS_ENABLE_CPU_MASK, + .d_INT_STATUS_ENABLE_COUNTER_LSB = AR9888_INT_STATUS_ENABLE_COUNTER_LSB, + .d_INT_STATUS_ENABLE_COUNTER_MASK = AR9888_INT_STATUS_ENABLE_COUNTER_MASK, + .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR9888_INT_STATUS_ENABLE_MBOX_DATA_LSB, + .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR9888_INT_STATUS_ENABLE_MBOX_DATA_MASK, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB, + .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR9888_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK, + .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_LSB, + .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR9888_COUNTER_INT_STATUS_ENABLE_BIT_MASK, + .d_INT_STATUS_ENABLE_ADDRESS = AR9888_INT_STATUS_ENABLE_ADDRESS, + .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR9888_CPU_INT_STATUS_ENABLE_BIT_LSB, + .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR9888_CPU_INT_STATUS_ENABLE_BIT_MASK, + .d_HOST_INT_STATUS_ADDRESS = AR9888_HOST_INT_STATUS_ADDRESS, + .d_CPU_INT_STATUS_ADDRESS = AR9888_CPU_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_ADDRESS = AR9888_ERROR_INT_STATUS_ADDRESS, + .d_ERROR_INT_STATUS_WAKEUP_MASK = AR9888_ERROR_INT_STATUS_WAKEUP_MASK, + .d_ERROR_INT_STATUS_WAKEUP_LSB = AR9888_ERROR_INT_STATUS_WAKEUP_LSB, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_MASK, + .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR9888_ERROR_INT_STATUS_RX_UNDERFLOW_LSB, + .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_MASK, + .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR9888_ERROR_INT_STATUS_TX_OVERFLOW_LSB, + .d_COUNT_DEC_ADDRESS = AR9888_COUNT_DEC_ADDRESS, + .d_HOST_INT_STATUS_CPU_MASK = AR9888_HOST_INT_STATUS_CPU_MASK, + .d_HOST_INT_STATUS_CPU_LSB = AR9888_HOST_INT_STATUS_CPU_LSB, + .d_HOST_INT_STATUS_ERROR_MASK = AR9888_HOST_INT_STATUS_ERROR_MASK, + .d_HOST_INT_STATUS_ERROR_LSB = AR9888_HOST_INT_STATUS_ERROR_LSB, + .d_HOST_INT_STATUS_COUNTER_MASK = AR9888_HOST_INT_STATUS_COUNTER_MASK, + .d_HOST_INT_STATUS_COUNTER_LSB = AR9888_HOST_INT_STATUS_COUNTER_LSB, + .d_RX_LOOKAHEAD_VALID_ADDRESS = AR9888_RX_LOOKAHEAD_VALID_ADDRESS, + .d_WINDOW_DATA_ADDRESS = AR9888_WINDOW_DATA_ADDRESS, + .d_WINDOW_READ_ADDR_ADDRESS = AR9888_WINDOW_READ_ADDR_ADDRESS, + .d_WINDOW_WRITE_ADDR_ADDRESS = AR9888_WINDOW_WRITE_ADDR_ADDRESS, + .d_SOC_GLOBAL_RESET_ADDRESS = AR9888_SOC_GLOBAL_RESET_ADDRESS, + .d_RTC_STATE_ADDRESS = AR9888_RTC_STATE_ADDRESS, + .d_RTC_STATE_COLD_RESET_MASK = AR9888_RTC_STATE_COLD_RESET_MASK, + .d_PCIE_LOCAL_BASE_ADDRESS = AR9888_PCIE_LOCAL_BASE_ADDRESS, + .d_PCIE_SOC_WAKE_RESET = AR9888_PCIE_SOC_WAKE_RESET, + .d_PCIE_SOC_WAKE_ADDRESS = AR9888_PCIE_SOC_WAKE_ADDRESS, + .d_PCIE_SOC_WAKE_V_MASK = AR9888_PCIE_SOC_WAKE_V_MASK, + .d_RTC_STATE_V_MASK = AR9888_RTC_STATE_V_MASK, + .d_RTC_STATE_V_LSB = AR9888_RTC_STATE_V_LSB, + .d_FW_IND_EVENT_PENDING = AR9888_FW_IND_EVENT_PENDING, + .d_FW_IND_INITIALIZED = AR9888_FW_IND_INITIALIZED, + .d_RTC_STATE_V_ON = AR9888_RTC_STATE_V_ON, +#if defined(SDIO_3_0) + .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR9888_HOST_INT_STATUS_MBOX_DATA_MASK, + .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR9888_HOST_INT_STATUS_MBOX_DATA_LSB, +#endif +#ifdef HIF_PCI + .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS, + .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK, + .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS, + .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS, + .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS, +#endif +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/cepci.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/cepci.h new file mode 100644 index 0000000000000..f5ba19bde895d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/cepci.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __CEPCI_H__ +#define __CEPCI_H__ + +/* + * Support for Copy Engine over PCI. + * Structures shared between Host software and Target firmware. + */ + + +/* + * Total number of PCIe MSI interrupts requested for all interrupt sources. + * PCIe standard forces this to be a power of 2. + * Some Host OS's limit MSI requests that can be granted to 8 + * so for now we abide by this limit and avoid requesting more + * than that. + */ +#define MSI_NUM_REQUEST_LOG2 3 +#define MSI_NUM_REQUEST (1<hi_interconnect_state points + * here (and all members are 32-bit quantities in order to + * facilitate Host access). In particular, Host software is + * required to initialize pipe_cfg_addr and svc_to_pipe_map. + */ +struct pcie_state_s { + A_UINT32 pipe_cfg_addr; /* Pipe configuration Target address */ + /* NB: CE_pipe_config[CE_COUNT] */ + + A_UINT32 svc_to_pipe_map; /* Service to pipe map Target address */ + /* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */ + + A_UINT32 MSI_requested; /* number of MSI interrupts requested */ + A_UINT32 MSI_granted; /* number of MSI interrupts granted */ + A_UINT32 MSI_addr; /* Message Signalled Interrupt address */ + A_UINT32 MSI_data; /* Base data */ + A_UINT32 MSI_fw_intr_data; /* Data for firmware interrupt; + MSI data for other interrupts are + in various SoC registers */ + + A_UINT32 power_mgmt_method; /* PCIE_PWR_METHOD_* */ + A_UINT32 config_flags; /* PCIE_CONFIG_FLAG_* */ +}; + +/* + * PCIE_CONFIG_FLAG definitions + */ +#define PCIE_CONFIG_FLAG_ENABLE_L1 0x0000001 +#define PCIE_CONFIG_FLAG_CLK_SWITCH_WAIT 0x0000002 +#define PCIE_CONFIG_FLAG_AXI_CLK_GATE 0x0000004 + +#define PIPE_TO_CE_MAP_CNT 32 /* simple implementation constant */ + +/* + * Configuration information for a Copy Engine pipe. + * Passed from Host to Target during startup (one per CE). + */ +struct CE_pipe_config { + A_UINT32 pipenum; + A_UINT32 pipedir; + A_UINT32 nentries; + A_UINT32 nbytes_max; + A_UINT32 flags; + A_UINT32 reserved; +}; + +#endif /* __CEPCI_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio.c new file mode 100644 index 0000000000000..f20e7742eff3a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adf_net_types.h" +#include "a_types.h" +#include "athdefs.h" +#include "a_osapi.h" +#include +#include +#include +#include "hif_sdio_dev.h" +#include "if_ath_sdio.h" +#include "regtable.h" + +#define ATH_MODULE_NAME hif_sdio + +unsigned int htc_credit_flow = 1; + +A_STATUS HIFStart(HIF_DEVICE *hif_device) +{ + HIF_SDIO_DEVICE *htc_sdio_device = HIFDevFromHIF(hif_device); + ENTER(); + HIFDevEnableInterrupts(htc_sdio_device); + EXIT(); + return A_OK; +} + +void +HIFFlushSurpriseRemove(HIF_DEVICE *hif_device) +{ + +} + +void HIFStop(HIF_DEVICE *hif_device) +{ + HIF_SDIO_DEVICE *htc_sdio_device = HIFDevFromHIF(hif_device); + ENTER(); + if (htc_sdio_device != NULL) { + HIFDevDisableInterrupts(htc_sdio_device); + HIFDevDestroy(htc_sdio_device); + } + EXIT(); +} + +A_STATUS HIFSend_head(HIF_DEVICE *hif_device, a_uint8_t pipe, + unsigned int transferID, unsigned int nbytes, adf_nbuf_t buf) +{ + HIF_SDIO_DEVICE *htc_sdio_device = HIFDevFromHIF(hif_device); + return HIFDevSendBuffer(htc_sdio_device, transferID, pipe, nbytes, buf); + +} + +int HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, + a_uint8_t *ULPipe, a_uint8_t *DLPipe, int *ul_is_polled, + int *dl_is_polled) +{ + HIF_SDIO_DEVICE *htc_sdio_device = HIFDevFromHIF(hif_device); + + return HIFDevMapServiceToPipe(htc_sdio_device, ServiceId, ULPipe, DLPipe); +} + +void HIFGetDefaultPipe(HIF_DEVICE *hif_device, a_uint8_t *ULPipe, + a_uint8_t *DLPipe) +{ + HIFMapServiceToPipe(hif_device, + HTC_CTRL_RSVD_SVC, + ULPipe, + DLPipe, + NULL, + NULL); +} + +void HIFPostInit(HIF_DEVICE *hif_device, void *target, + MSG_BASED_HIF_CALLBACKS *callbacks) +{ + HIF_SDIO_DEVICE *htc_sdio_device = HIFDevFromHIF(hif_device); + if (htc_sdio_device == NULL) { + htc_sdio_device = HIFDevCreate(hif_device, callbacks, target); + } + + if (htc_sdio_device) + HIFDevSetup(htc_sdio_device); + + return; +} + + +/*SDIO uses credit based flow control at the HTC layer so transmit resource checks are +bypassed. This API is relevant to USB where there may be a limited number of USB request +blocks (URBs) in the HIF*/ +a_uint16_t HIFGetFreeQueueNumber(HIF_DEVICE *hif_device, a_uint8_t pipe) +{ + a_uint16_t rv; + rv = 1; + return rv; +} + +void HIFSendCompleteCheck(HIF_DEVICE *hif_device, a_uint8_t pipe, int force) +{ + +} + +void *hif_get_targetdef(HIF_DEVICE *hif_device) +{ + return (void*)sc->targetdef; +} + +void HIFDump(HIF_DEVICE *hif_device, u_int8_t cmd_id, bool start) { + ENTER("Dummy Function"); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c new file mode 100644 index 0000000000000..b0b34e67a7202 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#define ATH_MODULE_NAME hif +#include "a_debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hif_sdio_internal.h" +#include "if_ath_sdio.h" +#include "regtable.h" + +/* under HL SDIO, with Interface Memory support, we have the following + * reasons to support 2 mboxs: a) we need place different buffers in different + * mempool, for example, data using Interface Memory, desc and other using + * DRAM, they need different SDIO mbox channels; b) currently, tx mempool in + * LL case is seperated from main mempool, the structure (descs at the beginning + * of every pool buffer) is different, because they only need store tx desc from host. + * To align with LL case, we also need 2 mbox support just as PCIe LL cases. + */ + +#define INVALID_MAILBOX_NUMBER 0xFF +A_UINT8 HIFDevMapPipeToMailBox(HIF_SDIO_DEVICE *pDev, A_UINT8 pipeid) +{ + // TODO: temp version, should not hardcoded here, will be updated after HIF design + if (2 == pipeid || 3 == pipeid) + return 1; + else if (0 == pipeid || 1 == pipeid) + return 0; + else { + printk("%s:--------------------pipeid=%d,should not happen\n",__func__,pipeid); + adf_os_assert(0); + return INVALID_MAILBOX_NUMBER; + } +} + +A_UINT8 HIFDevMapMailBoxToPipe(HIF_SDIO_DEVICE *pDev, A_UINT8 mboxIndex, + A_BOOL upload) +{ + // TODO: temp version, should not hardcoded here, will be updated after HIF design + if (mboxIndex == 0) { + return upload ? 1 : 0; + } else if (mboxIndex == 1) { + return upload ? 3 : 2; + } else { + printk("%s:--------------------mboxIndex=%d,upload=%d,should not happen\n",__func__,mboxIndex,upload); + adf_os_assert(0); + return 0xff; + } +} + +A_STATUS HIFDevMapServiceToPipe(HIF_SDIO_DEVICE *pDev, A_UINT16 ServiceId, + A_UINT8 *ULPipe, A_UINT8 *DLPipe) +{ + A_STATUS status = EOK; + switch (ServiceId) { + case HTT_DATA_MSG_SVC: + *ULPipe = 3; + *DLPipe = 2; + break; + + case HTC_CTRL_RSVD_SVC: + case HTC_RAW_STREAMS_SVC: + *ULPipe = 1; + *DLPipe = 0; + break; + + case WMI_DATA_BE_SVC: + case WMI_DATA_BK_SVC: + case WMI_DATA_VI_SVC: + case WMI_DATA_VO_SVC: + *ULPipe = 1; + *DLPipe = 0; + break; + + case WMI_CONTROL_SVC: + *ULPipe = 1; + *DLPipe = 0; + break; + + default: + status = !EOK; + break; + } + return status; +} + +HTC_PACKET *HIFDevAllocRxBuffer(HIF_SDIO_DEVICE *pDev) +{ + HTC_PACKET *pPacket; + adf_nbuf_t netbuf; + A_UINT32 bufsize = 0, headsize = 0; + + bufsize = HIF_SDIO_RX_BUFFER_SIZE + HIF_SDIO_RX_DATA_OFFSET; + headsize = sizeof(HTC_PACKET); + netbuf = adf_nbuf_alloc(NULL, bufsize + headsize, 0, 4, FALSE); + if (netbuf == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("(%s)Allocate netbuf failed\n", __FUNCTION__)); + return NULL; + } + pPacket = (HTC_PACKET *) adf_nbuf_data(netbuf); + adf_nbuf_reserve(netbuf, headsize); + + SET_HTC_PACKET_INFO_RX_REFILL(pPacket, + pDev, + adf_nbuf_data(netbuf), + bufsize, + ENDPOINT_0); + SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf); + return pPacket; +} + +HIF_SDIO_DEVICE* HIFDevCreate(HIF_DEVICE *hif_device, + MSG_BASED_HIF_CALLBACKS *callbacks, + void *target) +{ + + A_STATUS status; + HIF_SDIO_DEVICE *pDev; + + pDev = A_MALLOC(sizeof(HIF_SDIO_DEVICE)); + if (!pDev) { + A_ASSERT(FALSE); + return NULL; + } + + A_MEMZERO(pDev, sizeof(HIF_SDIO_DEVICE)); + A_MUTEX_INIT(&pDev->Lock); + A_MUTEX_INIT(&pDev->TxLock); + A_MUTEX_INIT(&pDev->RxLock); + + pDev->HIFDevice = hif_device; + pDev->pTarget = target; + status = HIFConfigureDevice(hif_device, + HIF_DEVICE_SET_HTC_CONTEXT, + (void*) pDev, + sizeof(pDev)); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("(%s)HIF_DEVICE_SET_HTC_CONTEXT failed!!!\n", __FUNCTION__)); + } + + A_MEMCPY(&pDev->hif_callbacks, callbacks, sizeof(*callbacks)); + + return pDev; +} + +void HIFDevDestroy(HIF_SDIO_DEVICE *pDev) +{ + A_STATUS status; + + status = HIFConfigureDevice(pDev->HIFDevice, + HIF_DEVICE_SET_HTC_CONTEXT, + (void*) NULL, + 0); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("(%s)HIF_DEVICE_SET_HTC_CONTEXT failed!!!\n", __FUNCTION__)); + } + A_FREE(pDev); +} + +HIF_SDIO_DEVICE *HIFDevFromHIF(HIF_DEVICE *hif_device) +{ + HIF_SDIO_DEVICE *pDev = NULL; + A_STATUS status; + status = HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_HTC_CONTEXT, + (void**) &pDev, + sizeof(HIF_SDIO_DEVICE)); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("(%s)HTC_SDIO_CONTEXT is NULL!!!\n", __FUNCTION__)); + } + return pDev; +} + +A_STATUS HIFDevDisableInterrupts(HIF_SDIO_DEVICE *pDev) +{ + MBOX_IRQ_ENABLE_REGISTERS regs; + A_STATUS status = A_OK; + ENTER(); + + LOCK_HIF_DEV(pDev); + /* Disable all interrupts */ + pDev->IrqEnableRegisters.int_status_enable = 0; + pDev->IrqEnableRegisters.cpu_int_status_enable = 0; + pDev->IrqEnableRegisters.error_status_enable = 0; + pDev->IrqEnableRegisters.counter_int_status_enable = 0; + /* copy into our temp area */ + A_MEMCPY(®s, + &pDev->IrqEnableRegisters, + sizeof(pDev->IrqEnableRegisters)); + + UNLOCK_HIF_DEV(pDev); + + /* always synchronous */ + status = HIFReadWrite(pDev->HIFDevice, + INT_STATUS_ENABLE_ADDRESS, + (A_UCHAR *)®s, + sizeof(MBOX_IRQ_ENABLE_REGISTERS), + HIF_WR_SYNC_BYTE_INC, + NULL); + + if (status != A_OK) { + /* Can't write it for some reason */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to update interrupt control registers err: %d", status)); + } + + EXIT("status :%d",status); + return status; +} + +A_STATUS HIFDevEnableInterrupts(HIF_SDIO_DEVICE *pDev) +{ + A_STATUS status; + MBOX_IRQ_ENABLE_REGISTERS regs; + ENTER(); + + + /* for good measure, make sure interrupt are disabled before unmasking at the HIF + * layer. + * The rationale here is that between device insertion (where we clear the interrupts the first time) + * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. + * The AR6K interrupt enables reset back to an "enabled" state when this happens. + * */ + HIFDevDisableInterrupts(pDev); + + /* Unmask the host controller interrupts */ + HIFUnMaskInterrupt(pDev->HIFDevice); + + LOCK_HIF_DEV(pDev); + + /* Enable all the interrupts except for the internal AR6000 CPU interrupt */ + pDev->IrqEnableRegisters.int_status_enable = + INT_STATUS_ENABLE_ERROR_SET(0x01) | INT_STATUS_ENABLE_CPU_SET(0x01) + | INT_STATUS_ENABLE_COUNTER_SET(0x01); + + pDev->IrqEnableRegisters.int_status_enable |= + INT_STATUS_ENABLE_MBOX_DATA_SET(0x01) | INT_STATUS_ENABLE_MBOX_DATA_SET(0x02); // enable 2 mboxs INT + + /* Set up the CPU Interrupt Status Register, enable CPU sourced interrupt #0, #1 + * #0 is used for report assertion from target + * #1 is used for inform host that credit arrived + * */ + pDev->IrqEnableRegisters.cpu_int_status_enable = 0x03; + + /* Set up the Error Interrupt Status Register */ + pDev->IrqEnableRegisters.error_status_enable = + (ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) + | ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01)) >> 16; + + /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */ + pDev->IrqEnableRegisters.counter_int_status_enable = + (COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK)) >> 24; + + /* copy into our temp area */ + A_MEMCPY(®s, + &pDev->IrqEnableRegisters, + sizeof(MBOX_IRQ_ENABLE_REGISTERS)); + + UNLOCK_HIF_DEV(pDev); + + + /* always synchronous */ + status = HIFReadWrite(pDev->HIFDevice, + INT_STATUS_ENABLE_ADDRESS, + (A_UCHAR *)®s, + sizeof(MBOX_IRQ_ENABLE_REGISTERS), + HIF_WR_SYNC_BYTE_INC, + NULL); + + if (status != A_OK) { + /* Can't write it for some reason */ + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("Failed to update interrupt control registers err: %d\n", status)); + + } + EXIT(); + return status; +} + +A_STATUS HIFDevSetup(HIF_SDIO_DEVICE *pDev) +{ + A_STATUS status; + A_UINT32 blocksizes[MAILBOX_COUNT]; + HTC_CALLBACKS htcCallbacks; + HIF_DEVICE *hif_device = pDev->HIFDevice; + + ENTER(); + + status = HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_MBOX_ADDR, + &pDev->MailBoxInfo, + sizeof(pDev->MailBoxInfo)); + + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("(%s)HIF_DEVICE_GET_MBOX_ADDR failed!!!\n", __FUNCTION__)); + A_ASSERT(FALSE); + } + + status = HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_MBOX_BLOCK_SIZE, + blocksizes, + sizeof(blocksizes)); + if (status != A_OK) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("(%s)HIF_DEVICE_GET_MBOX_BLOCK_SIZE failed!!!\n", __FUNCTION__)); + A_ASSERT(FALSE); + } + + pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; + pDev->BlockMask = pDev->BlockSize - 1; + A_ASSERT((pDev->BlockSize & pDev->BlockMask) == 0); + + /* assume we can process HIF interrupt events asynchronously */ + pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; + + /* see if the HIF layer overrides this assumption */ + HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_IRQ_PROC_MODE, + &pDev->HifIRQProcessingMode, + sizeof(pDev->HifIRQProcessingMode)); + + switch (pDev->HifIRQProcessingMode) { + case HIF_DEVICE_IRQ_SYNC_ONLY: + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("HIF Interrupt processing is SYNC ONLY\n")); + /* see if HIF layer wants HTC to yield */ + HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_IRQ_YIELD_PARAMS, + &pDev->HifIRQYieldParams, + sizeof(pDev->HifIRQYieldParams)); + + if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) { + AR_DEBUG_PRINTF( ATH_DEBUG_WARN, + ("HIF requests that DSR yield per %d RECV packets \n", pDev->HifIRQYieldParams.RecvPacketYieldCount)); + pDev->DSRCanYield = TRUE; + } + break; + case HIF_DEVICE_IRQ_ASYNC_SYNC: + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + ("HIF Interrupt processing is ASYNC and SYNC\n")); + break; + default: + A_ASSERT(FALSE); + break; + } + + pDev->HifMaskUmaskRecvEvent = NULL; + + /* see if the HIF layer implements the mask/unmask recv events function */ + HIFConfigureDevice(hif_device, + HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, + &pDev->HifMaskUmaskRecvEvent, + sizeof(pDev->HifMaskUmaskRecvEvent)); + + status = HIFDevDisableInterrupts(pDev); + + A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); + /* the device layer handles these */ + htcCallbacks.rwCompletionHandler = HIFDevRWCompletionHandler; + htcCallbacks.dsrHandler = HIFDevDsrHandler; + htcCallbacks.context = pDev; + status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); + + EXIT(); + return status; +} + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.h new file mode 100644 index 0000000000000..2600607f0c3cf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_dev.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HIF_SDIO_DEV_H_ +#define HIF_SDIO_DEV_H_ + +#include "adf_net_types.h" +#include "a_types.h" +#include "athdefs.h" +#include "a_osapi.h" +#include "hif_msg_based.h" +#include "athstartpack.h" + +typedef struct TAG_HIF_SDIO_DEVICE HIF_SDIO_DEVICE; + +HIF_SDIO_DEVICE* HIFDevFromHIF(HIF_DEVICE *hif_device); + +HIF_SDIO_DEVICE* HIFDevCreate(HIF_DEVICE *hif_device, + MSG_BASED_HIF_CALLBACKS *callbacks, + void *target); + +void HIFDevDestroy(HIF_SDIO_DEVICE *htc_sdio_device); + +A_STATUS HIFDevSetup(HIF_SDIO_DEVICE *htc_sdio_device); + +A_STATUS HIFDevEnableInterrupts(HIF_SDIO_DEVICE *htc_sdio_device); + +A_STATUS HIFDevDisableInterrupts(HIF_SDIO_DEVICE *htc_sdio_device); + +A_STATUS HIFDevSendBuffer(HIF_SDIO_DEVICE *htc_sdio_device, unsigned int transferID, a_uint8_t pipe, + unsigned int nbytes, adf_nbuf_t buf); + +A_STATUS HIFDevMapServiceToPipe(HIF_SDIO_DEVICE *pDev, A_UINT16 ServiceId, + A_UINT8 *ULPipe, A_UINT8 *DLPipe); + +#endif /* HIF_SDIO_DEV_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h new file mode 100644 index 0000000000000..3696974e5da48 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_internal.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HIF_SDIO_INTERNAL_H_ +#define HIF_SDIO_INTERNAL_H_ + +#include "a_debug.h" +#include "hif_sdio_dev.h" +#include "htc_packet.h" +#include "htc_api.h" + + +#define HIF_SDIO_RX_BUFFER_SIZE 1664 +#define HIF_SDIO_RX_DATA_OFFSET 64 + +/* TODO: print output level and mask control */ +#define ATH_DEBUG_IRQ ATH_DEBUG_MAKE_MODULE_MASK(4) +#define ATH_DEBUG_XMIT ATH_DEBUG_MAKE_MODULE_MASK(5) +#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(6) + +#define ATH_DEBUG_MAX_MASK 32 + +#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \ + INT_STATUS_ENABLE_CPU_MASK | \ + INT_STATUS_ENABLE_COUNTER_MASK) + +/* HTC operational parameters */ +#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ +#define HTC_TARGET_DEBUG_INTR_MASK 0x01 +#define HTC_TARGET_CREDIT_INTR_MASK 0xF0 + +#define MAILBOX_COUNT 4 +#define MAILBOX_FOR_BLOCK_SIZE 1 +#define MAILBOX_USED_COUNT 2 +#if defined(SDIO_3_0) +#define MAILBOX_LOOKAHEAD_SIZE_IN_WORD 2 +#else +#define MAILBOX_LOOKAHEAD_SIZE_IN_WORD 1 +#endif +#define AR6K_TARGET_DEBUG_INTR_MASK 0x01 + +typedef PREPACK struct _MBOX_IRQ_PROC_REGISTERS { + A_UINT8 host_int_status; + A_UINT8 cpu_int_status; + A_UINT8 error_int_status; + A_UINT8 counter_int_status; + A_UINT8 mbox_frame; + A_UINT8 rx_lookahead_valid; + A_UINT8 host_int_status2; + A_UINT8 gmbox_rx_avail; + A_UINT32 rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD * MAILBOX_COUNT]; + A_UINT32 int_status_enable; +}POSTPACK MBOX_IRQ_PROC_REGISTERS; + +typedef PREPACK struct _MBOX_IRQ_ENABLE_REGISTERS { + A_UINT8 int_status_enable; + A_UINT8 cpu_int_status_enable; + A_UINT8 error_status_enable; + A_UINT8 counter_int_status_enable; +}POSTPACK MBOX_IRQ_ENABLE_REGISTERS; + +#define TOTAL_CREDIT_COUNTER_CNT 4 + +typedef PREPACK struct _MBOX_COUNTER_REGISTERS { + A_UINT32 counter[TOTAL_CREDIT_COUNTER_CNT]; +}POSTPACK MBOX_COUNTER_REGISTERS; + +#define SDIO_NUM_DATA_RX_BUFFERS 64 +#define SDIO_DATA_RX_SIZE 1664 + +struct TAG_HIF_SDIO_DEVICE { + HIF_DEVICE *HIFDevice; + A_MUTEX_T Lock; + A_MUTEX_T TxLock; + A_MUTEX_T RxLock; + MBOX_IRQ_PROC_REGISTERS IrqProcRegisters; + MBOX_IRQ_ENABLE_REGISTERS IrqEnableRegisters; + MBOX_COUNTER_REGISTERS MailBoxCounterRegisters; + MSG_BASED_HIF_CALLBACKS hif_callbacks; + HIF_DEVICE_MBOX_INFO MailBoxInfo; + A_UINT32 BlockSize; + A_UINT32 BlockMask; + HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; + HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams; + A_BOOL DSRCanYield; + HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; + int CurrentDSRRecvCount; + int RecheckIRQStatusCnt; + A_UINT32 RecvStateFlags; + void *pTarget; +}; + +#define LOCK_HIF_DEV(device) A_MUTEX_LOCK(&(device)->Lock); +#define UNLOCK_HIF_DEV(device) A_MUTEX_UNLOCK(&(device)->Lock); +#define LOCK_HIF_DEV_RX(t) A_MUTEX_LOCK(&(t)->RxLock); +#define UNLOCK_HIF_DEV_RX(t) A_MUTEX_UNLOCK(&(t)->RxLock); +#define LOCK_HIF_DEV_TX(t) A_MUTEX_LOCK(&(t)->TxLock); +#define UNLOCK_HIF_DEV_TX(t) A_MUTEX_UNLOCK(&(t)->TxLock); + +#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) +#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) +#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) + +#define HTC_RECV_WAIT_BUFFERS (1 << 0) +#define HTC_OP_STATE_STOPPING (1 << 0) + +#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0) +#define HTC_RX_PKT_REFRESH_HDR (1 << 1) +#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2) +#define HTC_RX_PKT_NO_RECYCLE (1 << 3) + +#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY) + +/* hif_sdio_dev.c */ +HTC_PACKET *HIFDevAllocRxBuffer(HIF_SDIO_DEVICE *pDev); + +A_UINT8 HIFDevMapPipeToMailBox(HIF_SDIO_DEVICE *pDev, A_UINT8 pipeid); +A_UINT8 HIFDevMapMailBoxToPipe(HIF_SDIO_DEVICE *pDev, A_UINT8 mboxIndex, + A_BOOL upload); + +/* hif_sdio_recv.c */ +A_STATUS HIFDevRWCompletionHandler(void *context, A_STATUS status); +A_STATUS HIFDevDsrHandler(void *context); + +#endif /* HIF_SDIO_INTERNAL_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c new file mode 100644 index 0000000000000..9e17113e8281c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_recv.c @@ -0,0 +1,1221 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#define ATH_MODULE_NAME hif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hif_sdio_internal.h" +#include "../../HTC/htc_internal.h" +#include "regtable.h" +#include "if_ath_sdio.h" + + +static void HIFDevDumpRegisters(HIF_SDIO_DEVICE *pDev, + MBOX_IRQ_PROC_REGISTERS *pIrqProcRegs, + MBOX_IRQ_ENABLE_REGISTERS *pIrqEnableRegs, + MBOX_COUNTER_REGISTERS *pMailBoxCounterRegisters) +{ + + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("RegTable->")); + + if (pIrqProcRegs != NULL) { + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("HostIntStatus: 0x%x ",pIrqProcRegs->host_int_status)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("CPUIntStatus: 0x%x ",pIrqProcRegs->cpu_int_status)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("ErrorIntStatus: 0x%x ",pIrqProcRegs->error_int_status)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("CounterIntStatus: 0x%x ",pIrqProcRegs->counter_int_status)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, + ("MboxFrame: 0x%x ",pIrqProcRegs->mbox_frame)); + + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\nRegTable->")); + + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("RxLKAValid: 0x%x ",pIrqProcRegs->rx_lookahead_valid)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("RxLKA0: 0x%x",pIrqProcRegs->rx_lookahead[0])); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("RxLKA1: 0x%x ",pIrqProcRegs->rx_lookahead[1])); + + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("RxLKA2: 0x%x ",pIrqProcRegs->rx_lookahead[2])); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("RxLKA3: 0x%x",pIrqProcRegs->rx_lookahead[3])); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\nRegTable->")); + + if (pDev->MailBoxInfo.GMboxAddress != 0) { + /* if the target supports GMBOX hardware, dump some additional state */ + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("GMBOX-HostIntStatus2: 0x%x ",pIrqProcRegs->host_int_status2)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("GMBOX-RX-Avail: 0x%x ",pIrqProcRegs->gmbox_rx_avail)); + } + } + + if (pIrqEnableRegs != NULL) { + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable)); + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable)); + } + + if (pMailBoxCounterRegisters != NULL){ + int i; + for (i = 0; i < 4; i ++){ + AR_DEBUG_PRINTF( ATH_DEBUG_ANY, + ("Counter[%d]: 0x%x\n", i, pMailBoxCounterRegisters->counter[i])); + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n")); +} + +static A_STATUS HIFDevAllocAndPrepareRxPackets(HIF_SDIO_DEVICE *pDev, + A_UINT32 LookAheads[], int Messages, HTC_PACKET_QUEUE *pQueue) +{ + A_STATUS status = A_OK; + HTC_PACKET *pPacket; + HTC_FRAME_HDR *pHdr; + int i, j; + int numMessages; + int fullLength; + A_BOOL noRecycle; + + /* lock RX while we assemble the packet buffers */ + LOCK_HIF_DEV_RX(pDev); + + for (i = 0; i < Messages; i++) { + + pHdr = (HTC_FRAME_HDR *) &LookAheads[i]; + if (pHdr->EndpointID >= ENDPOINT_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID)); + /* invalid endpoint */ + status = A_EPROTO; + break; + } + + if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("Payload length %d exceeds max HTC : %d !\n", pHdr->PayloadLen, (A_UINT32)HTC_MAX_PAYLOAD_LENGTH)); + status = A_EPROTO; + break; + } + + if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) { + /* HTC header only indicates 1 message to fetch */ + numMessages = 1; + } else { + /* HTC header indicates that every packet to follow has the same padded length so that it can + * be optimally fetched as a full bundle */ + numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) + >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT; + /* the count doesn't include the starter frame, just a count of frames to follow */ + numMessages++; + //A_ASSERT(numMessages <= target->MaxMsgPerBundle); + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, + ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages)); + } + + fullLength = + DEV_CALC_RECV_PADDED_LEN(pDev,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR)); + + /* get packet buffers for each message, if there was a bundle detected in the header, + * use pHdr as a template to fetch all packets in the bundle */ + for (j = 0; j < numMessages; j++) { + + /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup, + * they must be explicitly returned */ + noRecycle = FALSE; + pPacket = HIFDevAllocRxBuffer(pDev); + + if (pPacket == NULL) { + /* this is not an error, we simply need to mark that we are waiting for buffers.*/ + pDev->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS; + //pDev->EpWaitingForBuffers = pEndpoint->Id; + status = A_NO_RESOURCE; + break; + } + + //AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id); + /* clear flags */ + pPacket->PktInfo.AsRx.HTCRxFlags = 0; + pPacket->PktInfo.AsRx.IndicationFlags = 0; + pPacket->Status = A_OK; + + if (noRecycle) { + /* flag that these packets cannot be recycled, they have to be returned to the + * user */ + pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE; + } + /* add packet to queue (also incase we need to cleanup down below) */ + HTC_PACKET_ENQUEUE(pQueue, pPacket); + + /* + if (HTC_STOPPING(target)) { + status = A_ECANCELED; + break; + } + */ + + /* make sure this message can fit in the endpoint buffer */ + if ((A_UINT32) fullLength > pPacket->BufferLength) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n", pHdr->PayloadLen, fullLength, pPacket->BufferLength)); + status = A_EPROTO; + break; + } + + if (j > 0) { + /* for messages fetched in a bundle the expected lookahead is unknown since we + * are only using the lookahead of the first packet as a template of what to + * expect for lengths */ + /* flag that once we get the real HTC header we need to refesh the information */ + pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR; + /* set it to something invalid */ + pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF; + } else { + pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */ + } + /* set the amount of data to fetch */ + pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; + pPacket->Endpoint = pHdr->EndpointID; + pPacket->Completion = NULL; + } + + if (A_FAILED(status)) { + if (A_NO_RESOURCE == status) { + /* this is actually okay */ + status = A_OK; + } + break; + } + + } + + UNLOCK_HIF_DEV_RX(pDev); + + if (A_FAILED(status)) { + while (!HTC_QUEUE_EMPTY(pQueue)) { + pPacket = HTC_PACKET_DEQUEUE(pQueue); + } + } + return status; +} + +static INLINE A_STATUS HIFDevRecvPacket(HIF_SDIO_DEVICE *pDev, + HTC_PACKET *pPacket, + A_UINT32 RecvLength, + A_UINT8 mboxIndex) +{ + A_UINT32 paddedLength; + A_STATUS status; + A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; + + /* adjust the length to be a multiple of block size if appropriate */ + paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength); + + if (paddedLength > pPacket->BufferLength) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", paddedLength,RecvLength,pPacket->BufferLength)); + if (pPacket->Completion != NULL) { + COMPLETE_HTC_PACKET(pPacket, A_EINVAL); + return A_OK; + } + return A_EINVAL; + } + + /* mailbox index is saved in Endpoint member */ + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, + ("HIFDevRecvPacket (0x%lX : hdr:0x%X) Len:%d, Padded Length: %d Mbox:0x%X\n", + (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr, + RecvLength, + paddedLength, + pDev->MailBoxInfo.MboxAddresses[mboxIndex])); + status = HIFReadWrite(pDev->HIFDevice, + pDev->MailBoxInfo.MboxAddresses[mboxIndex], + pPacket->pBuffer, + paddedLength, + (sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX), + sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, ("EP%d, Seq:%d\n", + ((HTC_FRAME_HDR*)pPacket->pBuffer)->EndpointID, + ((HTC_FRAME_HDR*)pPacket->pBuffer)->ControlBytes1)); + if (status != A_OK) { + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, + ("HIFDevRecvPacket (0x%lX : hdr:0x%X) Failed\n", (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr)); + } + if (sync) { + pPacket->Status = status; + if (status == A_OK) { + HTC_FRAME_HDR *pHdr = (HTC_FRAME_HDR *) pPacket->pBuffer; + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, + ("HIFDevRecvPacket " + "EP:%d,PayloadLen:%d,Flag:%d,CB:0x%02X,0x%02X\n", + pHdr->EndpointID, + pHdr->PayloadLen, + pHdr->Flags, + pHdr->ControlBytes0, + pHdr->ControlBytes1)); + } + } + + return status; +} + +static INLINE A_STATUS HIFDevProcessTrailer(HIF_SDIO_DEVICE *pDev, + A_UINT8 *pBuffer, int Length, A_UINT32 *pNextLookAheads, + int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint) +{ + HTC_RECORD_HDR *pRecord; + A_UINT8 *pRecordBuf; + HTC_LOOKAHEAD_REPORT *pLookAhead; + A_UINT8 *pOrigBuffer; + int origLength; + A_STATUS status; + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, + ("+HTCProcessTrailer (length:%d) \n", Length)); + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer"); + } + + pOrigBuffer = pBuffer; + origLength = Length; + status = A_OK; + + while (Length > 0) { + + if (Length < sizeof(HTC_RECORD_HDR)) { + status = A_EPROTO; + break; + } + /* these are byte aligned structs */ + pRecord = (HTC_RECORD_HDR *) pBuffer; + Length -= sizeof(HTC_RECORD_HDR); + pBuffer += sizeof(HTC_RECORD_HDR); + + if (pRecord->Length > Length) { + /* no room left in buffer for record */ + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", pRecord->Length, pRecord->RecordID, Length)); + status = A_EPROTO; + break; + } + /* start of record follows the header */ + pRecordBuf = pBuffer; + + switch (pRecord->RecordID) { + case HTC_RECORD_CREDITS: + /* Process in HTC, ignore here*/ + break; + case HTC_RECORD_LOOKAHEAD: + AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT)); + pLookAhead = (HTC_LOOKAHEAD_REPORT *) pRecordBuf; + if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) + && (pNextLookAheads != NULL)) { + + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, + (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) %d %d\n", + pLookAhead->PreValid, pLookAhead->PostValid, + FromEndpoint, + pLookAhead->LookAhead0 + )); + /* look ahead bytes are valid, copy them over */ + ((A_UINT8 *) (&pNextLookAheads[0]))[0] = pLookAhead->LookAhead0; + ((A_UINT8 *) (&pNextLookAheads[0]))[1] = pLookAhead->LookAhead1; + ((A_UINT8 *) (&pNextLookAheads[0]))[2] = pLookAhead->LookAhead2; + ((A_UINT8 *) (&pNextLookAheads[0]))[3] = pLookAhead->LookAhead3; + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + DebugDumpBytes((A_UINT8 *) pNextLookAheads, + 4, + "Next Look Ahead"); + } + /* just one normal lookahead */ + if (pNumLookAheads != NULL) { + *pNumLookAheads = 1; + } + } + break; + case HTC_RECORD_LOOKAHEAD_BUNDLE: + AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)); + if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) + && (pNextLookAheads != NULL)) { + HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt; + int i; + + pBundledLookAheadRpt = + (HTC_BUNDLED_LOOKAHEAD_REPORT *) pRecordBuf; + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + DebugDumpBytes(pRecordBuf, + pRecord->Length, + "Bundle LookAhead"); + } + + if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) + > HTC_MAX_MSG_PER_BUNDLE) { + /* this should never happen, the target restricts the number + * of messages per bundle configured by the host */ + A_ASSERT(FALSE); + status = A_EPROTO; + break; + } + for (i = 0; i< (int) (pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) { + ((A_UINT8 *) (&pNextLookAheads[i]))[0] = + pBundledLookAheadRpt->LookAhead0; + ((A_UINT8 *) (&pNextLookAheads[i]))[1] = + pBundledLookAheadRpt->LookAhead1; + ((A_UINT8 *) (&pNextLookAheads[i]))[2] = + pBundledLookAheadRpt->LookAhead2; + ((A_UINT8 *) (&pNextLookAheads[i]))[3] = + pBundledLookAheadRpt->LookAhead3; + pBundledLookAheadRpt++; + } + + *pNumLookAheads = i; + } + break; + default: + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + (" HIF unhandled record: id:%d length:%d \n", pRecord->RecordID, pRecord->Length)); + break; + } + + if (A_FAILED(status)) { + break; + } + + /* advance buffer past this record for next time around */ + pBuffer += pRecord->Length; + Length -= pRecord->Length; + } + + if (A_FAILED(status)) { + DebugDumpBytes(pOrigBuffer, origLength, "BAD Recv Trailer"); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n")); + return status; + +} + + +/* process a received message (i.e. strip off header, process any trailer data) + * note : locks must be released when this function is called */ +static A_STATUS HIFDevProcessRecvHeader(HIF_SDIO_DEVICE *pDev, + HTC_PACKET *pPacket, A_UINT32 *pNextLookAheads, int *pNumLookAheads) +{ + A_UINT8 temp; + A_UINT8 *pBuf; + A_STATUS status = A_OK; + A_UINT16 payloadLen; + A_UINT32 lookAhead, ActualLength; + + pBuf = pPacket->pBuffer; + ActualLength = pPacket->ActualLength; + + if (pNumLookAheads != NULL) { + *pNumLookAheads = 0; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n")); + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT"); + } + + do { + /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to + * retrieve 16 bit fields */ + payloadLen = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, PAYLOADLEN); + + ((A_UINT8 *) &lookAhead)[0] = pBuf[0]; + ((A_UINT8 *) &lookAhead)[1] = pBuf[1]; + ((A_UINT8 *) &lookAhead)[2] = pBuf[2]; + ((A_UINT8 *) &lookAhead)[3] = pBuf[3]; + + if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) { + /* refresh expected hdr, since this was unknown at the time we grabbed the packets + * as part of a bundle */ + pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead; + /* refresh actual length since we now have the real header */ + pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH; + + /* validate the actual header that was refreshed */ + if (pPacket->ActualLength > pPacket->BufferLength) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n", payloadLen, lookAhead)); + /* limit this to max buffer just to print out some of the buffer */ + pPacket->ActualLength = + min(pPacket->ActualLength, pPacket->BufferLength); + status = A_EPROTO; + break; + } + + if (pPacket->Endpoint + != HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, ENDPOINTID)) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n", HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, ENDPOINTID), pPacket->Endpoint)); + status = A_EPROTO; + break; + } + } + + if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) { + /* somehow the lookahead that gave us the full read length did not + * reflect the actual header in the pending message */ + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("HIFDevProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X), 0x%08X != 0x%08X\n", + (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags, + lookAhead, pPacket->PktInfo.AsRx.ExpectedHdr)); +#ifdef ATH_DEBUG_MODULE + DebugDumpBytes((A_UINT8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead"); + DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header"); +#ifdef HTC_CAPTURE_LAST_FRAME + DebugDumpBytes((A_UINT8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header"); + if (target->LastTrailerLength != 0) { + DebugDumpBytes(target->LastTrailer, + target->LastTrailerLength, + "Last trailer"); + } +#endif +#endif + status = A_EPROTO; + break; + } + + /* get flags */ + temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, FLAGS); + + if (temp & HTC_FLAGS_RECV_TRAILER) { + /* this packet has a trailer */ + + /* extract the trailer length in control byte 0 */ + temp = HTC_GET_FIELD(pBuf, HTC_FRAME_HDR, CONTROLBYTES0); + + if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { + AR_DEBUG_PRINTF( ATH_DEBUG_ERR, + ("HIFDevProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", payloadLen, temp)); + status = A_EPROTO; + break; + } + + if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) { + /* this packet was fetched as part of an HTC bundle, the embedded lookahead is + * not valid since the next packet may have already been fetched as part of the + * bundle */ + pNextLookAheads = NULL; + pNumLookAheads = NULL; + } + + /* process trailer data that follows HDR + application payload */ + status = HIFDevProcessTrailer(pDev, + (pBuf + HTC_HDR_LENGTH + payloadLen - temp), + temp, + pNextLookAheads, + pNumLookAheads, + pPacket->Endpoint); + + if (A_FAILED(status)) { + break; + } + } + }while (FALSE); + + if (A_FAILED(status)) { + /* dump the whole packet */ + DebugDumpBytes(pBuf, + pPacket->ActualLength, + "BAD HTC Recv PKT"); + } else { + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + if (pPacket->ActualLength > 0) { + AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg"); + } + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HIFDevProcessRecvHeader \n")); + return status; +} + +static A_STATUS HIFDevIssueRecvPacketBundle(HIF_SDIO_DEVICE *pDev, + HTC_PACKET_QUEUE *pRecvPktQueue, + HTC_PACKET_QUEUE *pSyncCompletionQueue, + A_UINT8 MailBoxIndex, + int *pNumPacketsFetched, + A_BOOL PartialBundle) +{ A_STATUS status = A_OK; + int i, totalLength = 0; + unsigned char *pBundleBuffer = NULL; + HTC_PACKET *pPacket, *pPacketRxBundle; + HTC_TARGET *target = NULL; + A_UINT32 paddedLength; + + int bundleSpaceRemaining = 0; + target = (HTC_TARGET *)pDev->pTarget; + + if((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - HTC_MAX_MSG_PER_BUNDLE) > 0){ + PartialBundle = TRUE; + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("%s, partial bundle detected num: %d, %d \n", + __FUNCTION__, HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), HTC_MAX_MSG_PER_BUNDLE)); + } + + bundleSpaceRemaining = HTC_MAX_MSG_PER_BUNDLE * target->TargetCreditSize; + pPacketRxBundle = AllocateHTCBundlePacket(target); + pBundleBuffer = pPacketRxBundle->pBuffer; + + for(i = 0; !HTC_QUEUE_EMPTY(pRecvPktQueue) && i < HTC_MAX_MSG_PER_BUNDLE; i++){ + pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue); + A_ASSERT(pPacket != NULL); + paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength); + + if((bundleSpaceRemaining - paddedLength) < 0){ + /* exceeds what we can transfer, put the packet back */ + HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue, pPacket); + break; + } + bundleSpaceRemaining -= paddedLength; + + if(PartialBundle || HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) > 0){ + pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD; + } + pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE; + + HTC_PACKET_ENQUEUE(pSyncCompletionQueue, pPacket); + + totalLength += paddedLength; + } +#if DEBUG_BUNDLE + adf_os_print("Recv bundle count %d, length %d.\n", + HTC_PACKET_QUEUE_DEPTH(pSyncCompletionQueue), totalLength); +#endif + + status = HIFReadWrite(pDev->HIFDevice, + pDev->MailBoxInfo.MboxAddresses[(int)MailBoxIndex], + pBundleBuffer, + totalLength, + HIF_RD_SYNC_BLOCK_FIX, + NULL); + + if(status != A_OK){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s, HIFSend Failed status:%d \n",__FUNCTION__, status)); + }else{ + unsigned char *pBuffer = pBundleBuffer; + *pNumPacketsFetched = i; + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pSyncCompletionQueue, pPacket){ + paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, pPacket->ActualLength); + A_MEMCPY(pPacket->pBuffer, pBuffer, paddedLength); + pBuffer += paddedLength; + }HTC_PACKET_QUEUE_ITERATE_END; + } + /* free bundle space under Sync mode */ + FreeHTCBundlePacket(target, pPacketRxBundle); + return status; +} +A_STATUS HIFDevRecvMessagePendingHandler(HIF_SDIO_DEVICE *pDev, + A_UINT8 MailBoxIndex, + A_UINT32 MsgLookAheads[], + int NumLookAheads, + A_BOOL *pAsyncProc, + int *pNumPktsFetched) +{ + A_STATUS status = A_OK; + HTC_PACKET *pPacket; + A_BOOL asyncProc = FALSE; + A_UINT32 lookAheads[HTC_MAX_MSG_PER_BUNDLE]; + int pktsFetched; + HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue; + A_BOOL partialBundle; + HTC_ENDPOINT_ID id; + int totalFetched = 0; + + AR_DEBUG_PRINTF( ATH_DEBUG_RECV, + ("+HTCRecvMessagePendingHandler NumLookAheads: %d \n", NumLookAheads)); + + if (pNumPktsFetched != NULL) { + *pNumPktsFetched = 0; + } + + if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev)) { + /* We use async mode to get the packets if the device layer supports it. + * The device layer interfaces with HIF in which HIF may have restrictions on + * how interrupts are processed */ + asyncProc = TRUE; + } + + if (pAsyncProc != NULL) { + /* indicate to caller how we decided to process this */ + *pAsyncProc = asyncProc; + } + if (NumLookAheads > HTC_MAX_MSG_PER_BUNDLE) { + A_ASSERT(FALSE); + return A_EPROTO; + } + A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads); + while (TRUE) { + + /* reset packets queues */ + INIT_HTC_PACKET_QUEUE(&recvPktQueue); + INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue); + if (NumLookAheads > HTC_MAX_MSG_PER_BUNDLE) { + status = A_EPROTO; + A_ASSERT(FALSE); + break; + } + + /* first lookahead sets the expected endpoint IDs for all packets in a bundle */ + id = ((HTC_FRAME_HDR *) &lookAheads[0])->EndpointID; + + if (id >= ENDPOINT_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("MsgPend, Invalid Endpoint in look-ahead: %d \n",id)); + status = A_EPROTO; + break; + } + /* try to allocate as many HTC RX packets indicated by the lookaheads + * these packets are stored in the recvPkt queue */ + status = HIFDevAllocAndPrepareRxPackets(pDev, + lookAheads, + NumLookAheads, + &recvPktQueue); + if (A_FAILED(status)) { + break; + } + totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue); + + /* we've got packet buffers for all we can currently fetch, + * this count is not valid anymore */ + NumLookAheads = 0; + partialBundle = FALSE; + + /* now go fetch the list of HTC packets */ + while (!HTC_QUEUE_EMPTY(&recvPktQueue)) { + + pktsFetched = 0; + if ((HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) { + /* there are enough packets to attempt a bundle transfer and recv bundling is allowed */ + status = HIFDevIssueRecvPacketBundle(pDev, + &recvPktQueue, + asyncProc ? NULL : &syncCompletedPktsQueue, + MailBoxIndex, + &pktsFetched, + partialBundle); + if (A_FAILED(status)) { + break; + } + + if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) { + /* we couldn't fetch all packets at one time, this creates a broken + * bundle */ + partialBundle = TRUE; + } + } + + /* see if the previous operation fetched any packets using bundling */ + if (0 == pktsFetched) { + /* dequeue one packet */ + pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue); + A_ASSERT(pPacket != NULL); + pPacket->Completion = NULL; + + if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) { + /* lookaheads in all packets except the last one in the bundle must be ignored */ + pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD; + } +#ifdef DEBUG_BUNDLE + //adf_os_print("Recv single packet, length %d.\n", pPacket->ActualLength); +#endif + + /* go fetch the packet */ + status = HIFDevRecvPacket(pDev, pPacket, pPacket->ActualLength, MailBoxIndex); + if (A_FAILED(status)) { + break; + } + /* sent synchronously, queue this packet for synchronous completion */ + HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue, pPacket); + } + } + + /* synchronous handling */ + if (pDev->DSRCanYield) { + /* for the SYNC case, increment count that tracks when the DSR should yield */ + pDev->CurrentDSRRecvCount++; + } + + /* in the sync case, all packet buffers are now filled, + * we can process each packet, check lookaheads and then repeat */ + + /* unload sync completion queue */ + while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) { + A_UINT8 pipeid; + adf_nbuf_t netbuf; + + pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue); + A_ASSERT(pPacket != NULL); + + NumLookAheads = 0; + status = HIFDevProcessRecvHeader(pDev, pPacket, lookAheads, + &NumLookAheads); + if (A_FAILED(status)) { + break; + } + + netbuf = (adf_nbuf_t) pPacket->pNetBufContext; + /* set data length */ + adf_nbuf_put_tail(netbuf, pPacket->ActualLength); + + if (pDev->hif_callbacks.rxCompletionHandler) { + pipeid = HIFDevMapMailBoxToPipe(pDev, MailBoxIndex, TRUE); + pDev->hif_callbacks.rxCompletionHandler(pDev->hif_callbacks.Context, + netbuf, + pipeid); + } + } + if (A_FAILED(status)) { + break; + } + + if (NumLookAheads == 0) { + /* no more look aheads */ + break; + } + /* check whether other OS contexts have queued any WMI command/data for WLAN. + * This check is needed only if WLAN Tx and Rx happens in same thread context */ + A_CHECK_DRV_TX(); + } + if (pNumPktsFetched != NULL) { + *pNumPktsFetched = totalFetched; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvMessagePendingHandler \n")); + return status; +} + +static A_STATUS HIFDevServiceCPUInterrupt(HIF_SDIO_DEVICE *pDev) +{ + A_STATUS status; + A_UINT8 cpu_int_status; + A_UINT8 regBuffer[4]; + + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n")); + cpu_int_status = pDev->IrqProcRegisters.cpu_int_status + & pDev->IrqEnableRegisters.cpu_int_status_enable; + A_ASSERT(cpu_int_status); + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", cpu_int_status)); + + /* Clear the interrupt */ + pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */ + + /* set up the register transfer buffer to hit the register 4 times , this is done + * to make the access 4-byte aligned to mitigate issues with host bus interconnects that + * restrict bus transfer lengths to be a multiple of 4-bytes */ + + /* set W1C value to clear the interrupt, this hits the register first */ + regBuffer[0] = cpu_int_status; + /* the remaining 4 values are set to zero which have no-effect */ + regBuffer[1] = 0; + regBuffer[2] = 0; + regBuffer[3] = 0; + + status = HIFReadWrite(pDev->HIFDevice, + CPU_INT_STATUS_ADDRESS, + regBuffer, + 4, + HIF_WR_SYNC_BYTE_FIX, + NULL); + + A_ASSERT(status == A_OK); + + /* The Interrupt sent to the Host is generated via bit0 of CPU INT register*/ + if (cpu_int_status & 0x1){ + if (pDev && pDev->hif_callbacks.fwEventHandler) + /* It calls into HTC which propagates this to ol_target_failure() */ + pDev->hif_callbacks.fwEventHandler(pDev->hif_callbacks.Context, + A_ERROR); + } + else + AR_DEBUG_PRINTF( ATH_DEBUG_ERROR, + ("%s: Unable to call fwEventHandler, invalid input arguments\n",__func__)); + + return status; +} + +static A_STATUS HIFDevServiceErrorInterrupt(HIF_SDIO_DEVICE *pDev) +{ + A_STATUS status; + A_UINT8 error_int_status; + A_UINT8 regBuffer[4]; + + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n")); + error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F; + A_ASSERT(error_int_status); + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n", error_int_status)); + + if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) { + /* Wakeup */ + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n")); + } + + if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) { + /* Rx Underflow */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n")); + } + + if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) { + /* Tx Overflow */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n")); + } + + /* Clear the interrupt */ + pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */ + + /* set up the register transfer buffer to hit the register 4 times , this is done + * to make the access 4-byte aligned to mitigate issues with host bus interconnects that + * restrict bus transfer lengths to be a multiple of 4-bytes */ + + /* set W1C value to clear the interrupt, this hits the register first */ + regBuffer[0] = error_int_status; + /* the remaining 4 values are set to zero which have no-effect */ + regBuffer[1] = 0; + regBuffer[2] = 0; + regBuffer[3] = 0; + + status = HIFReadWrite(pDev->HIFDevice, + ERROR_INT_STATUS_ADDRESS, + regBuffer, + 4, + HIF_WR_SYNC_BYTE_FIX, + NULL); + + A_ASSERT(status == A_OK); + return status; +} + +static A_STATUS HIFDevServiceDebugInterrupt(HIF_SDIO_DEVICE *pDev) +{ + A_UINT32 dummy; + A_STATUS status; + + /* Send a target failure event to the application */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); + + /* clear the interrupt , the debug error interrupt is + * counter 0 */ + /* read counter to clear interrupt */ + status = HIFReadWrite(pDev->HIFDevice, + COUNT_DEC_ADDRESS, + (A_UINT8 *) &dummy, + 4, + HIF_RD_SYNC_BYTE_INC, + NULL); + + A_ASSERT(status == A_OK); + return status; +} + +static A_STATUS HIFDevServiceCounterInterrupt(HIF_SDIO_DEVICE *pDev) +{ + A_UINT8 counter_int_status; + + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n")); + + counter_int_status = pDev->IrqProcRegisters.counter_int_status + & pDev->IrqEnableRegisters.counter_int_status_enable; + + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", counter_int_status)); + + /* Check if the debug interrupt is pending + * NOTE: other modules like GMBOX may use the counter interrupt for + * credit flow control on other counters, we only need to check for the debug assertion + * counter interrupt */ + if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { + return HIFDevServiceDebugInterrupt(pDev); + } + + return A_OK; +} + +/* process pending interrupts synchronously */ +static A_STATUS HIFDevProcessPendingIRQs(HIF_SDIO_DEVICE *pDev, A_BOOL *pDone, + A_BOOL *pASyncProcessing) +{ + A_STATUS status = A_OK; + A_UINT8 host_int_status = 0; + A_UINT32 lookAhead[MAILBOX_USED_COUNT]; + int i; + + A_MEMZERO(&lookAhead, sizeof(lookAhead)); + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, + ("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev)); + + /*** NOTE: the HIF implementation guarantees that the context of this call allows + * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that + * can block or switch thread/task ontexts. + * This is a fully schedulable context. + * */ + do { + + if (pDev->IrqEnableRegisters.int_status_enable == 0) { + /* interrupt enables have been cleared, do not try to process any pending interrupts that + * may result in more bus transactions. The target may be unresponsive at this + * point. */ + break; + } + status = HIFReadWrite(pDev->HIFDevice, + HOST_INT_STATUS_ADDRESS, + (A_UINT8 *) &pDev->IrqProcRegisters, + sizeof(pDev->IrqProcRegisters), + HIF_RD_SYNC_BYTE_INC, + NULL); + + if (A_FAILED(status)) { + break; + } + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) { + HIFDevDumpRegisters(pDev, + &pDev->IrqProcRegisters, + &pDev->IrqEnableRegisters, + &pDev->MailBoxCounterRegisters); + } + + /* Update only those registers that are enabled */ + host_int_status = pDev->IrqProcRegisters.host_int_status + & pDev->IrqEnableRegisters.int_status_enable; + + /* only look at mailbox status if the HIF layer did not provide this function, + * on some HIF interfaces reading the RX lookahead is not valid to do */ + for (i = 0; i < MAILBOX_USED_COUNT; i++) { + lookAhead[i] = 0; + if (host_int_status & (1 << i)) { + /* mask out pending mailbox value, we use "lookAhead" as the real flag for + * mailbox processing below */ + host_int_status &= ~(1 << i); + if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << i)) { + /* mailbox has a message and the look ahead is valid */ + lookAhead[i] = pDev->IrqProcRegisters.rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD*i]; + } + } + } /*end of for loop*/ + } while (FALSE); + + do { + A_BOOL bLookAheadValid = FALSE; + /* did the interrupt status fetches succeed? */ + if (A_FAILED(status)) { + break; + } + + for (i = 0; i < MAILBOX_USED_COUNT; i++) { + if (lookAhead[i] != 0) { + bLookAheadValid = TRUE; + break; + } + } + + if ((0 == host_int_status) && !bLookAheadValid) { + /* nothing to process, the caller can use this to break out of a loop */ + *pDone = TRUE; + break; + } + + if (bLookAheadValid) { + for (i = 0; i < MAILBOX_USED_COUNT; i++) { + int fetched = 0; + if (lookAhead[i] == 0) { + continue; + } + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, + ("Pending mailbox[%d] message, LookAhead: 0x%X\n", i, lookAhead[i])); + /* Mailbox Interrupt, the HTC layer may issue async requests to empty the + * mailbox... + * When emptying the recv mailbox we use the async handler above called from the + * completion routine of the callers read request. This can improve performance + * by reducing context switching when we rapidly pull packets */ + status = HIFDevRecvMessagePendingHandler(pDev, + i, + &lookAhead[i], + 1, + pASyncProcessing, + &fetched); + if (A_FAILED(status)) { + break; + } + + if (!fetched) { + /* HTC could not pull any messages out due to lack of resources */ + /* force DSR handler to ack the interrupt */ + *pASyncProcessing = FALSE; + pDev->RecheckIRQStatusCnt = 0; + } + } + } + + /* now handle the rest of them */ + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n", host_int_status)); + + if (HOST_INT_STATUS_CPU_GET(host_int_status)) { + /* CPU Interrupt */ + status = HIFDevServiceCPUInterrupt(pDev); + if (A_FAILED(status)) { + break; + } + } + + if (HOST_INT_STATUS_ERROR_GET(host_int_status)) { + /* Error Interrupt */ + status = HIFDevServiceErrorInterrupt(pDev); + if (A_FAILED(status)) { + break; + } + } + + if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) { + /* Counter Interrupt */ + status = HIFDevServiceCounterInterrupt(pDev); + if (A_FAILED(status)) { + break; + } + } + + } while (FALSE); + + /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake + * the target, if upper layers determine that we are in a low-throughput mode, we can + * rely on taking another interrupt rather than re-checking the status registers which can + * re-wake the target. + * + * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot + * be used due to possible side-effects. For example, SPI requires the host to drain all + * messages from the mailbox before exiting the ISR routine. */ + if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0)) { + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, + ("Bypassing IRQ Status re-check, forcing done \n")); + *pDone = TRUE; + } + + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + ("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n", *pDone, *pASyncProcessing, status)); + + return status; +} + +#define DEV_CHECK_RECV_YIELD(pDev) \ + ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount) + +/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/ +A_STATUS HIFDevDsrHandler(void *context) +{ + HIF_SDIO_DEVICE *pDev = (HIF_SDIO_DEVICE *) context; + A_STATUS status = A_OK; + A_BOOL done = FALSE; + A_BOOL asyncProc = FALSE; + + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, + ("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); + + /* reset the recv counter that tracks when we need to yield from the DSR */ + pDev->CurrentDSRRecvCount = 0; + /* reset counter used to flag a re-scan of IRQ status registers on the target */ + pDev->RecheckIRQStatusCnt = 0; + + while (!done) { + status = HIFDevProcessPendingIRQs(pDev, &done, &asyncProc); + if (A_FAILED(status)) { + break; + } + + if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { + /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */ + asyncProc = FALSE; + /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers. + * this has a nice side effect of blocking us until all async read requests are completed. + * This behavior is required on some HIF implementations that do not allow ASYNC + * processing in interrupt handlers (like Windows CE) */ + + if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) { + /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop + * checking for more messages and return */ + break; + } + } + + if (asyncProc) { + /* the function performed some async I/O for performance, we + need to exit the ISR immediately, the check below will prevent the interrupt from being + Ack'd while we handle it asynchronously */ + break; + } + + } + + if (A_SUCCESS(status) && !asyncProc) { + /* Ack the interrupt only if : + * 1. we did not get any errors in processing interrupts + * 2. there are no outstanding async processing requests */ + if (pDev->DSRCanYield) { + /* if the DSR can yield do not ACK the interrupt, there could be more pending messages. + * The HIF layer must ACK the interrupt on behalf of HTC */ + AR_DEBUG_PRINTF( ATH_DEBUG_IRQ, + (" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, + (" Acking interrupt from DevDsrHandler \n")); + HIFAckInterrupt(pDev->HIFDevice); + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevDsrHandler \n")); + return status; +} + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_send.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_send.c new file mode 100644 index 0000000000000..24b27ee7c1927 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/hif_sdio_send.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hif_sdio_internal.h" + +/* + * Data structure to record required sending context data + */ +struct HIFSendContext +{ + A_BOOL bNewAlloc; + HIF_SDIO_DEVICE *pDev; + adf_nbuf_t netbuf; + unsigned int transferID; + unsigned int head_data_len; +}; + +/* + * Completion routine for ALL HIF layer async I/O + */ +A_STATUS HIFDevRWCompletionHandler(void *context, A_STATUS status) +{ + struct HIFSendContext *pSendContext = (struct HIFSendContext *)context; + unsigned int transferID = pSendContext->transferID; + HIF_SDIO_DEVICE *pDev = pSendContext->pDev; + adf_nbuf_t buf = pSendContext->netbuf; + + if (pSendContext->bNewAlloc){ + adf_os_mem_free((void*)pSendContext); + } else { + adf_nbuf_pull_head(buf, pSendContext->head_data_len); + } + if (pDev->hif_callbacks.txCompletionHandler) { + pDev->hif_callbacks.txCompletionHandler(pDev->hif_callbacks.Context, + buf, + transferID); + } + return A_OK; +} + +A_STATUS HIFDevSendBuffer(HIF_SDIO_DEVICE *pDev, unsigned int transferID, a_uint8_t pipe, + unsigned int nbytes, adf_nbuf_t buf) +{ + A_STATUS status; + A_UINT32 paddedLength; + int frag_count = 0, i, head_data_len; + struct HIFSendContext *pSendContext; + unsigned char *pData; + A_UINT32 request = HIF_WR_ASYNC_BLOCK_INC; + A_UINT8 mboxIndex = HIFDevMapPipeToMailBox(pDev, pipe); + + paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, nbytes); +#ifdef ENABLE_MBOX_DUMMY_SPACE_FEATURE + A_ASSERT(paddedLength - nbytes < HIF_DUMMY_SPACE_MASK + 1); + /* + * two most significant bytes to save dummy data count + * data written into the dummy space will not put into the final mbox FIFO + * + */ + request |= ((paddedLength - nbytes) << 16); +#endif + + frag_count = adf_nbuf_get_num_frags(buf); + + if (frag_count > 1){ + /* header data length should be total sending length substract internal data length of netbuf */ + /* + * | HIFSendContext | fragments except internal buffer | netbuf->data + */ + head_data_len = sizeof(struct HIFSendContext) + + (nbytes - adf_nbuf_get_frag_len(buf, frag_count - 1)); + } else { + /* + * | HIFSendContext | netbuf->data + */ + head_data_len = sizeof(struct HIFSendContext); + } + + /* Check whether head room is enough to save extra head data */ + if ((head_data_len <= adf_nbuf_headroom(buf)) && + (adf_nbuf_tailroom(buf) >= (paddedLength - nbytes))){ + pSendContext = (struct HIFSendContext*)adf_nbuf_push_head(buf, head_data_len); + pSendContext->bNewAlloc = FALSE; + } else { + pSendContext = (struct HIFSendContext*)adf_os_mem_alloc(NULL, + sizeof(struct HIFSendContext) + paddedLength); + pSendContext->bNewAlloc = TRUE; + } + + pSendContext->netbuf = buf; + pSendContext->pDev = pDev; + pSendContext->transferID = transferID; + pSendContext->head_data_len = head_data_len; + /* + * Copy data to head part of netbuf or head of allocated buffer. + * if buffer is new allocated, the last buffer should be copied also. + * It assume last fragment is internal buffer of netbuf + * sometime total length of fragments larger than nbytes + */ + pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext); + for (i = 0; i < (pSendContext->bNewAlloc ? frag_count : frag_count - 1); i ++){ + int frag_len = adf_nbuf_get_frag_len(buf, i); + unsigned char *frag_addr = adf_nbuf_get_frag_vaddr(buf, i); + if (frag_len > nbytes){ + frag_len = nbytes; + } + memcpy(pData, frag_addr, frag_len); + pData += frag_len; + nbytes -= frag_len; + if (nbytes <= 0) { + break; + } + } + + /* Reset pData pointer and send out */ + pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext); + status = HIFReadWrite(pDev->HIFDevice, + pDev->MailBoxInfo.MboxProp[mboxIndex].ExtendedAddress, + (char*) pData, + paddedLength, + request, + (void*)pSendContext); + + if (status == A_PENDING){ + /* + * it will return A_PENDING in native HIF implementation, + * which should be treated as successful result here. + */ + status = A_OK; + } + /* release buffer or move back data pointer when failed */ + if (status != A_OK){ + if (pSendContext->bNewAlloc){ + adf_os_mem_free(pSendContext); + } else { + adf_nbuf_pull_head(buf, head_data_len); + } + } + + return status; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c new file mode 100644 index 0000000000000..bbd1ac4c22738 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bmi_msg.h" /* TARGET_TYPE_ */ +#include "if_ath_sdio.h" +#include "vos_api.h" + +#ifndef REMOVE_PKT_LOG +#include "ol_txrx_types.h" +#include "pktlog_ac_api.h" +#include "pktlog_ac.h" +#endif +#include "epping_main.h" + +#ifndef ATH_BUS_PM +#ifdef CONFIG_PM +#define ATH_BUS_PM +#endif /* CONFIG_PM */ +#endif /* ATH_BUS_PM */ + +#ifndef REMOVE_PKT_LOG +struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs = NULL; +#endif + +typedef void * hif_handle_t; +typedef void * hif_softc_t; + +extern int hdd_wlan_startup(struct device *dev, void *hif_sc); +extern void __hdd_wlan_exit(void); + +struct ath_hif_sdio_softc *sc = NULL; + +static A_STATUS +ath_hif_sdio_probe(void *context, void *hif_handle) +{ + int ret = 0; + struct ol_softc *ol_sc; + HIF_DEVICE_OS_DEVICE_INFO os_dev_info; + struct sdio_func *func = NULL; + const struct sdio_device_id *id; + u_int32_t target_type; + ENTER(); + + sc = (struct ath_hif_sdio_softc *) A_MALLOC(sizeof(*sc)); + if (!sc) { + ret = -ENOMEM; + goto err_alloc; + } + A_MEMZERO(sc,sizeof(*sc)); + + + sc->hif_handle = hif_handle; + HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, &os_dev_info, sizeof(os_dev_info)); + + sc->aps_osdev.device = os_dev_info.pOSDevice; + sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_SDIO; + spin_lock_init(&sc->target_lock); + + { + /* + * Attach Target register table. This is needed early on -- + * even before BMI -- since PCI and HIF initialization (and BMI init) + * directly access Target registers (e.g. CE registers). + * + * TBDXXX: targetdef should not be global -- should be stored + * in per-device struct so that we can support multiple + * different Target types with a single Host driver. + * The whole notion of an "hif type" -- (not as in the hif + * module, but generic "Host Interface Type") is bizarre. + * At first, one one expect it to be things like SDIO, USB, PCI. + * But instead, it's an actual platform type. Inexplicably, the + * values used for HIF platform types are *different* from the + * values used for Target Types. + */ + +#if defined(CONFIG_AR9888_SUPPORT) + hif_register_tbl_attach(HIF_TYPE_AR9888); + target_register_tbl_attach(TARGET_TYPE_AR9888); + target_type = TARGET_TYPE_AR9888; +#elif defined(CONFIG_AR6320_SUPPORT) + id = ((HIF_DEVICE*)hif_handle)->id; + if (id->device == MANUFACTURER_ID_QCA9377_BASE) { + hif_register_tbl_attach(HIF_TYPE_AR6320V2); + target_register_tbl_attach(TARGET_TYPE_AR6320V2); + } else { + hif_register_tbl_attach(HIF_TYPE_AR6320); + target_register_tbl_attach(TARGET_TYPE_AR6320); + } + target_type = TARGET_TYPE_AR6320; + +#endif + } + func = ((HIF_DEVICE*)hif_handle)->func; + + ol_sc = A_MALLOC(sizeof(*ol_sc)); + if (!ol_sc){ + ret = -ENOMEM; + goto err_attach; + } + OS_MEMZERO(ol_sc, sizeof(*ol_sc)); + ol_sc->sc_osdev = &sc->aps_osdev; + ol_sc->hif_sc = (void *)sc; + sc->ol_sc = ol_sc; + ol_sc->target_type = target_type; + ol_sc->enableuartprint = 1; + ol_sc->enablefwlog = 0; + ol_sc->enablesinglebinary = FALSE; + ol_sc->max_no_of_peers = 1; + + ol_sc->hif_hdl = hif_handle; + + ol_sc->ramdump_base = ioremap(RAMDUMP_ADDR, RAMDUMP_SIZE); + ol_sc->ramdump_size = RAMDUMP_SIZE; + if (ol_sc->ramdump_base == NULL) { + ol_sc->ramdump_base = 0; + ol_sc->ramdump_size = 0; + } + init_waitqueue_head(&ol_sc->sc_osdev->event_queue); + + if (athdiag_procfs_init(sc) != 0) { + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR, + "%s athdiag_procfs_init failed",__func__); + ret = A_ERROR; + goto err_attach1; + } + + ret = hdd_wlan_startup(&(func->dev), ol_sc); + if ( ret ) { + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_FATAL," hdd_wlan_startup failed"); + goto err_attach2; + }else{ + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO," hdd_wlan_startup success!"); + } + + /* epping is minimum ethernet driver and the + * epping fw does not support pktlog, etc. + * After hdd_wladriver is epping directly return. */ + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) + goto end; + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE) { + /* + * pktlog initialization + */ + ol_pl_sethandle(&ol_sc->pdev_txrx_handle->pl_dev, ol_sc); + + if (pktlogmod_init(ol_sc)) + printk(KERN_ERR "%s: pktlogmod_init failed\n", __func__); + } +#endif +end: + return 0; + +err_attach2: + athdiag_procfs_remove(); +err_attach1: + A_FREE(ol_sc); +err_attach: + A_FREE(sc); + sc = NULL; +err_alloc: + return ret; +} + +int +ol_ath_sdio_configure(hif_softc_t hif_sc, struct net_device *dev, hif_handle_t *hif_hdl) +{ + struct ath_hif_sdio_softc *sc = (struct ath_hif_sdio_softc *) hif_sc; + int ret = 0; + + sc->aps_osdev.netdev = dev; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(dev); +#endif + + *hif_hdl = sc->hif_handle; + + return ret; +} + +static A_STATUS +ath_hif_sdio_remove(void *context, void *hif_handle) +{ + ENTER(); + + if (!sc) { + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR, + "Global SDIO context is NULL"); + return A_ERROR; + } + + athdiag_procfs_remove(); + + iounmap(sc->ol_sc->ramdump_base); + +#ifndef REMOVE_PKT_LOG + if (vos_get_conparam() != VOS_FTM_MODE && + !WLAN_IS_EPPING_ENABLED(vos_get_conparam())){ + if (sc && sc->ol_sc) + pktlogmod_exit(sc->ol_sc); + } +#endif + + //cleaning up the upper layers + __hdd_wlan_exit(); + + if (sc && sc->ol_sc){ + A_FREE(sc->ol_sc); + sc->ol_sc = NULL; + } + if (sc) { + A_FREE(sc); + sc = NULL; + } + + EXIT(); + return 0; +} + +static A_STATUS +ath_hif_sdio_suspend(void *context) +{ + printk(KERN_INFO "ol_ath_sdio_suspend TODO\n"); + return 0; +} + +static A_STATUS +ath_hif_sdio_resume(void *context) +{ + printk(KERN_INFO "ol_ath_sdio_resume ODO\n"); + return 0; +} + +static A_STATUS +ath_hif_sdio_power_change(void *context, A_UINT32 config) +{ + printk(KERN_INFO "ol_ath_sdio_power change TODO\n"); + return 0; +} + +/* + * Module glue. + */ +#include +static char *version = "HIF (Atheros/multi-bss)"; +static char *dev_info = "ath_hif_sdio"; + +static int init_ath_hif_sdio(void) +{ + static int probed = 0; + A_STATUS status; + OSDRV_CALLBACKS osdrvCallbacks; + ENTER(); + + A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks)); + osdrvCallbacks.deviceInsertedHandler = ath_hif_sdio_probe; + osdrvCallbacks.deviceRemovedHandler = ath_hif_sdio_remove; +#ifdef CONFIG_PM + osdrvCallbacks.deviceSuspendHandler = ath_hif_sdio_suspend; + osdrvCallbacks.deviceResumeHandler = ath_hif_sdio_resume; + osdrvCallbacks.devicePowerChangeHandler = ath_hif_sdio_power_change; +#endif + + if (probed) { + return -ENODEV; + } + probed++; + + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO,"%s %d",__func__,__LINE__); + status = HIFInit(&osdrvCallbacks); + if(status != A_OK){ + VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_FATAL, "%s HIFInit failed!",__func__); + return -ENODEV; + } + + printk(KERN_INFO "%s: %s\n", dev_info, version); + + return 0; +} + +int hif_register_driver(void) +{ + int status = 0; + ENTER(); + status = init_ath_hif_sdio(); + EXIT("status = %d", status); + return status; + +} + +void hif_unregister_driver(void) +{ + ENTER(); + HIFShutDownDevice(NULL); + EXIT(); + return ; +} + +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc) +{ + struct ol_softc *ol_sc_local = (struct ol_softc *)ol_sc; + struct ath_hif_sdio_softc *hif_sc = ol_sc_local->hif_sc; + ENTER(); + adf_dev->drv = &hif_sc->aps_osdev; + adf_dev->dev = hif_sc->aps_osdev.device; + ol_sc_local->adf_dev = adf_dev; + EXIT(); +} + +void hif_deinit_adf_ctx(void *ol_sc) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + sc->adf_dev = NULL; +} + +/* Function to set the TXRX handle in the ol_sc context */ +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) +{ + struct ol_softc *sc = (struct ol_softc *)ol_sc; + ENTER(); + sc->pdev_txrx_handle = txrx_handle; +} + +void hif_disable_isr(void *ol_sc) +{ + ENTER("- dummy function!"); +} + +void +HIFSetTargetSleep(HIF_DEVICE *hif_device, A_BOOL sleep_ok, A_BOOL wait_for_it) +{ + ENTER("- dummy function!"); +} + +void +HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) +{ + ENTER("- dummy function!"); + +} + +/* Function to reset SoC */ +void hif_reset_soc(void *ol_sc) +{ + ENTER("- dummy function!"); +} + +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) +{ + *version = ((struct ol_softc *)ol_sc)->target_version; + /* Chip revision should be supported, set to 0 for now */ + *revision = 0; +} + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h new file mode 100644 index 0000000000000..8de7217ad844a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __IF_ATH_SDIO_H__ +#define __IF_ATH_SDIO_H__ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#include +#else +#include +#endif +#include +#include +#include +#include +#include "a_osapi.h" +#include "hif_internal.h" +#include "hif_trace.h" + +#define AR6320_HEADERS_DEF + +#define ATH_DBG_DEFAULT 0 + +#define RAMDUMP_ADDR 0x8F000000 +#define RAMDUMP_SIZE 0x700000 + +struct ath_hif_sdio_softc { + struct device *dev; + struct _NIC_DEV aps_osdev; + struct ol_softc *ol_sc; + struct tasklet_struct intr_tq; /* tasklet */ + + int irq; + /* + * Guard changes to Target HW state and to software + * structures that track hardware state. + */ + spinlock_t target_lock; + void *hif_handle; + struct targetdef_s *targetdef; + struct hostdef_s *hostdef; +}; + +#if defined(CONFIG_ATH_PROCFS_DIAG_SUPPORT) +int athdiag_procfs_init(void *scn); +void athdiag_procfs_remove(void); +#else +static inline int athdiag_procfs_init(void *scn) { return 0; } +static inline void athdiag_procfs_remove(void) { return; } +#endif + +#ifndef REMOVE_PKT_LOG +extern int pktlogmod_init(void *context); +extern void pktlogmod_exit(void *context); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#define DMA_MAPPING_ERROR(dev, addr) dma_mapping_error((addr)) +#else +#define DMA_MAPPING_ERROR(dev, addr) dma_mapping_error((dev), (addr)) +#endif + +int ath_sdio_probe(void *context, void *hif_handle); +void ath_sdio_remove(void *context, void *hif_handle); +int ath_sdio_suspend(void *context); +int ath_sdio_resume(void *context); + +/*These functions are exposed to HDD*/ +int hif_register_driver(void); +void hif_unregister_driver(void); +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); +void hif_deinit_adf_ctx(void *ol_sc); +void hif_disable_isr(void *ol_sc); +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); +void hif_reset_soc(void *ol_sc); + + +void hif_register_tbl_attach(u32 hif_type); +void target_register_tbl_attach(u32 target_type); + +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +void hif_set_fw_info(void *ol_sc, u32 target_fw_version); + +#endif /* __IF_ATH_SDIO_H__*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h new file mode 100644 index 0000000000000..64328d3728d0b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _HIF_INTERNAL_H_ +#define _HIF_INTERNAL_H_ + +#include "athdefs.h" +#include "a_types.h" +#include "a_osapi.h" +#include "hif.h" +#include "hif_sdio_common.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#include +#define HIF_LINUX_MMC_SCATTER_SUPPORT +#endif + +#define BUS_REQUEST_MAX_NUM 64 + +#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000 +#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20 +#define FLAGS_CARD_ENAB 0x02 +#define FLAGS_CARD_IRQ_UNMSK 0x04 + +#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE +#define HIF_MBOX0_BLOCK_SIZE 1 +#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE +#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE +#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE + +struct _HIF_SCATTER_REQ_PRIV; + +typedef struct bus_request { + struct bus_request *next; /* link list of available requests */ + struct bus_request *inusenext; /* link list of in use requests */ + struct semaphore sem_req; + A_UINT32 address; /* request data */ + A_UCHAR *buffer; + A_UINT32 length; + A_UINT32 request; + void *context; + A_STATUS status; + struct _HIF_SCATTER_REQ_PRIV *pScatterReq; /* this request is a scatter request */ +} BUS_REQUEST; + +struct hif_device { + struct sdio_func *func; + spinlock_t asynclock; + struct task_struct* async_task; /* task to handle async commands */ + struct semaphore sem_async; /* wake up for async task */ + int async_shutdown; /* stop the async task */ + struct completion async_completion; /* thread completion */ + BUS_REQUEST *asyncreq; /* request for async tasklet */ + BUS_REQUEST *taskreq; /* async tasklet data */ + spinlock_t lock; + BUS_REQUEST *s_busRequestFreeQueue; /* free list */ + BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */ + void *claimedContext; + HTC_CALLBACKS htcCallbacks; + A_UINT8 *dma_buffer; + DL_LIST ScatterReqHead; /* scatter request list head */ + A_BOOL scatter_enabled; /* scatter enabled flag */ + A_BOOL is_suspend; + A_BOOL is_disabled; + atomic_t irqHandling; + HIF_DEVICE_POWER_CHANGE_TYPE powerConfig; + HIF_DEVICE_STATE DeviceState; + const struct sdio_device_id *id; + struct mmc_host *host; + void *htcContext; +}; + +#define HIF_DMA_BUFFER_SIZE (32 * 1024) +#define CMD53_FIXED_ADDRESS 1 +#define CMD53_INCR_ADDRESS 2 + +BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device); +void hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest); +void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest); +void HIFDumpCCCR(HIF_DEVICE *hif_device); + +#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT + +#define MAX_SCATTER_REQUESTS 4 +#define MAX_SCATTER_ENTRIES_PER_REQ 16 +#define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024 + +typedef struct _HIF_SCATTER_REQ_PRIV { + HIF_SCATTER_REQ *pHifScatterReq; /* HIF scatter request with allocated entries */ + HIF_DEVICE *device; /* this device */ + BUS_REQUEST *busrequest; /* request associated with request */ + /* scatter list for linux */ + struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ]; +} HIF_SCATTER_REQ_PRIV; + +#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) + +A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo); +void CleanupHIFScatterResources(HIF_DEVICE *device); +A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest); + +#else // HIF_LINUX_MMC_SCATTER_SUPPORT + +static inline A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +{ + return A_ENOTSUP; +} + +static inline A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +{ + return A_ENOTSUP; +} + +#define CleanupHIFScatterResources(d) { } + +#endif // HIF_LINUX_MMC_SCATTER_SUPPORT + +#endif // _HIF_INTERNAL_H_ + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c new file mode 100644 index 0000000000000..60e8d0796d55f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c @@ -0,0 +1,2213 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "if_ath_sdio.h" +#include "regtable.h" + +/* by default setup a bounce buffer for the data packets, if the underlying host controller driver + does not use DMA you may be able to skip this step and save the memory allocation and transfer time */ +#define HIF_USE_DMA_BOUNCE_BUFFER 1 +#define ATH_MODULE_NAME hif +#include "a_debug.h" + +#if HIF_USE_DMA_BOUNCE_BUFFER +/* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the + * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack). + * virt_addr_valid check fails on stack memory. + */ +#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer))) +#else +#define BUFFER_NEEDS_BOUNCE(buffer) (FALSE) +#endif + +#define MAX_HIF_DEVICES 2 + +unsigned int mmcbusmode = 0; +module_param(mmcbusmode, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mmcbusmode, "Set MMC driver Bus Mode: 1-SDR12, 2-SDR25, 3-SDR50, 4-DDR50, 5-SDR104"); +EXPORT_SYMBOL(mmcbusmode); + +unsigned int mmcbuswidth = 0; +module_param(mmcbuswidth, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mmcbuswidth, "Set MMC driver Bus Width: 1-1Bit, 4-4Bit, 8-8Bit"); +EXPORT_SYMBOL(mmcbuswidth); + +unsigned int mmcclock = 0; +module_param(mmcclock, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mmcclock, "Set MMC driver Clock value"); +EXPORT_SYMBOL(mmcclock); + +unsigned int brokenirq = 0; +module_param(brokenirq, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(brokenirq, "Set as 1 to use polling method instead of interrupt mode"); + +unsigned int forcesleepmode = 0; +module_param(forcesleepmode, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(forcesleepmode, "Set sleep mode: 0-host capbility, 1-force WOW, 2-force DeepSleep, 3-force CutPower"); + +unsigned int asyncintdelay = 0; +module_param(asyncintdelay, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(asyncintdelay, "Delay clock count for aysnc interrupt, 0 is default, vaild values are 1 and 2"); + +unsigned int forcecard = 0; +module_param(forcecard, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(forcecard, "Ignore card capabilities information to switch bus mode"); + +unsigned int debugcccr = 1; +module_param(debugcccr, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(debugcccr, "Output this cccr values"); + +unsigned int writecccr1 = 0; +module_param(writecccr1, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +unsigned int writecccr1value = 0; +module_param(writecccr1value, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +unsigned int writecccr2 = 0; +module_param(writecccr2, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +unsigned int writecccr2value = 0; +module_param(writecccr2value, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +unsigned int writecccr3 = 0; +module_param(writecccr3, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +unsigned int writecccr3value = 0; +module_param(writecccr3value, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +unsigned int writecccr4 = 0; +module_param(writecccr4, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +unsigned int writecccr4value = 0; +module_param(writecccr4value, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +unsigned int modstrength = 0; +module_param(modstrength, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(modstrength, "Adjust internal driver strength"); + +/* ATHENV */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) +#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) +#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) +static int hifDeviceSuspend(struct device *dev); +static int hifDeviceResume(struct device *dev); +#endif /* CONFIG_PM */ +static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id); +static void hifDeviceRemoved(struct sdio_func *func); +static HIF_DEVICE *addHifDevice(struct sdio_func *func); +static HIF_DEVICE *getHifDevice(struct sdio_func *func); +static void delHifDevice(HIF_DEVICE * device); +static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); +static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); + + +int reset_sdio_on_unload = 0; +module_param(reset_sdio_on_unload, int, 0644); + +A_UINT32 nohifscattersupport = 1; + + +/* ------ Static Variables ------ */ +static const struct sdio_device_id ar6k_id_table[] = { +#ifdef AR6002_HEADERS_DEF + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, +#endif +#ifdef AR6003_HEADERS_DEF + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, +#endif +#ifdef AR6004_HEADERS_DEF + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1)) }, +#endif +#ifdef AR6320_HEADERS_DEF + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x1)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x2)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x3)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x4)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x5)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x6)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x7)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x8)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x9)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xA)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xB)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xC)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xD)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xE)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xF)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x1)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x2)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x3)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x4)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x5)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x6)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x7)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x8)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x9)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xA)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xB)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xC)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xD)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xE)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xF)) }, + /* TODO: just for compatible with old image which ManufacturerID is 0, should delete later */ + { SDIO_DEVICE(MANUFACTURER_CODE, (0 | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (0 | 0x1)) }, +#endif + { /* null */ }, +}; +MODULE_DEVICE_TABLE(sdio, ar6k_id_table); + +static struct sdio_driver ar6k_driver = { + .name = "ar6k_wlan", + .id_table = ar6k_id_table, + .probe = hifDeviceInserted, + .remove = hifDeviceRemoved, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) +/* New suspend/resume based on linux-2.6.32 + * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch + * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static struct dev_pm_ops ar6k_device_pm_ops = { +#else +static struct pm_ops ar6k_device_pm_ops = { +#endif + .suspend = hifDeviceSuspend, + .resume = hifDeviceResume, +}; +#endif /* CONFIG_PM */ + +/* make sure we only unregister when registered. */ +static int registered = 0; + +OSDRV_CALLBACKS osdrvCallbacks; +extern A_UINT32 onebitmode; +extern A_UINT32 busspeedlow; +extern A_UINT32 debughif; + +static HIF_DEVICE *hif_devices[MAX_HIF_DEVICES]; + +static void ResetAllCards(void); +static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); +static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func); + +#ifdef DEBUG + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, + "hif", + "(Linux MMC) Host Interconnect Framework", + ATH_DEBUG_MASK_DEFAULTS, + 0, + NULL); + +#endif + + +/* ------ Functions ------ */ +A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) +{ + int status; + AR_DEBUG_ASSERT(callbacks != NULL); + + A_REGISTER_MODULE_DEBUG_INFO(hif); + + ENTER(); + /* store the callback handlers */ + osdrvCallbacks = *callbacks; + + /* Register with bus driver core */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n")); + registered = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) + if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) { + ar6k_driver.drv.pm = &ar6k_device_pm_ops; + } +#endif /* CONFIG_PM */ + status = sdio_register_driver(&ar6k_driver); + AR_DEBUG_ASSERT(status==0); + + if (status != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("%s sdio_register_driver failed!",__func__)); + return A_ERROR; + } + else + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("%s sdio_register_driver successful",__func__)); + + return A_OK; +} + +static A_STATUS +__HIFReadWrite(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + A_UINT32 request, + void *context) +{ + A_UINT8 opcode; + A_STATUS status = A_OK; + int ret; + A_UINT8 *tbuffer; + A_BOOL bounced = FALSE; + + AR_DEBUG_ASSERT(device != NULL); + AR_DEBUG_ASSERT(device->func != NULL); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("__HIFReadWrite, addr:0X%06X, len:%08d, %s, %s\n", + address, + length, + request & HIF_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? "Async" : "Sync ")); + + do { + if (request & HIF_EXTENDED_IO) { + //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n")); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Invalid command type: 0x%08x\n", request)); + status = A_EINVAL; + break; + } + + if (request & HIF_BLOCK_BASIS) { + /* round to whole block length size */ + length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("AR6000: Block mode (BlockLen: %d)\n", + length)); + } else if (request & HIF_BYTE_BASIS) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("AR6000: Byte mode (BlockLen: %d)\n", + length)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Invalid data mode: 0x%08x\n", request)); + status = A_EINVAL; + break; + } + +#if 0 + /* useful for checking register accesses */ + if (length & 0x3) { + A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n", + request & HIF_WRITE ? "write":"read", address, length); + } +#endif + + if (request & HIF_WRITE) { + HIF_DEVICE_MBOX_INFO MailBoxInfo; + unsigned int mboxLength = 0; + HIFConfigureDevice(device, + HIF_DEVICE_GET_MBOX_ADDR, + &MailBoxInfo, + sizeof(MailBoxInfo)); + if (address >= 0x800 && address < 0xC00) { + /* Host control register and CIS Window */ + mboxLength = 0; + } else if (address == MailBoxInfo.MboxAddresses[0] + || address == MailBoxInfo.MboxAddresses[1] + || address == MailBoxInfo.MboxAddresses[2] + || address == MailBoxInfo.MboxAddresses[3]) { + mboxLength = HIF_MBOX_WIDTH; + } else if (address == MailBoxInfo.MboxProp[0].ExtendedAddress) { + mboxLength = MailBoxInfo.MboxProp[0].ExtendedSize; + } else if (address == MailBoxInfo.MboxProp[1].ExtendedAddress) { + mboxLength = MailBoxInfo.MboxProp[1].ExtendedSize; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("Invalid written address: 0x%08x\n", address)); + break; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("address:%08X, Length:0x%08X, Dummy:0x%04X, Final:0x%08X\n", address, length, (request & HIF_DUMMY_SPACE_MASK) >> 16, mboxLength == 0 ? address : address + (mboxLength - length))); + if (mboxLength != 0) { + if (length > mboxLength) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("HIFReadWrite: written length(0x%08X) " + "larger than mbox length(0x%08x)\n", length, mboxLength)); + break; + } + address += (mboxLength - length); +#ifdef ENABLE_MBOX_DUMMY_SPACE_FEATURE + /* + * plus dummy byte count + */ + address += ((request & HIF_DUMMY_SPACE_MASK) >> 16); +#endif + } + } + + if (request & HIF_FIXED_ADDRESS) { + opcode = CMD53_FIXED_ADDRESS; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address)); + } else if (request & HIF_INCREMENTAL_ADDRESS) { + opcode = CMD53_INCR_ADDRESS; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Invalid address mode: 0x%08x\n", request)); + status = A_EINVAL; + break; + } + + if (request & HIF_WRITE) { +#if HIF_USE_DMA_BOUNCE_BUFFER + if (BUFFER_NEEDS_BOUNCE(buffer)) { + AR_DEBUG_ASSERT(device->dma_buffer != NULL); + tbuffer = device->dma_buffer; + /* copy the write data to the dma buffer */ + AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); + memcpy(tbuffer, buffer, length); + bounced = TRUE; + } else { + tbuffer = buffer; + } +#else + tbuffer = buffer; +#endif + if (opcode == CMD53_FIXED_ADDRESS) { + ret = sdio_writesb(device->func, address, tbuffer, length); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n", + ret, address, length, *(int *)tbuffer)); + } else { + ret = sdio_memcpy_toio(device->func, address, tbuffer, length); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n", + ret, address, length, *(int *)tbuffer)); + } + } else if (request & HIF_READ) { +#if HIF_USE_DMA_BOUNCE_BUFFER + if (BUFFER_NEEDS_BOUNCE(buffer)) { + AR_DEBUG_ASSERT(device->dma_buffer != NULL); + AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); + tbuffer = device->dma_buffer; + bounced = TRUE; + } else { + tbuffer = buffer; + } +#else + tbuffer = buffer; +#endif + if (opcode == CMD53_FIXED_ADDRESS) { + ret = sdio_readsb(device->func, tbuffer, address, length); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n", + ret, address, length, *(int *)tbuffer)); + } else { + ret = sdio_memcpy_fromio(device->func, tbuffer, address, length); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n", + ret, address, length, *(int *)tbuffer)); + } +#if HIF_USE_DMA_BOUNCE_BUFFER + if (bounced) { + /* copy the read data from the dma buffer */ + memcpy(buffer, tbuffer, length); + } +#endif + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Invalid direction: 0x%08x\n", request)); + status = A_EINVAL; + break; + } + + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret)); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("__HIFReadWrite, addr:0X%06X, len:%08d, %s, %s\n", + address, + length, + request & HIF_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? "Async" : "Sync ")); + status = A_ERROR; + } + } while (FALSE); + + return status; +} + +void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) +{ + unsigned long flags; + BUS_REQUEST *async; + BUS_REQUEST *active; + + spin_lock_irqsave(&device->asynclock, flags); + active = device->asyncreq; + if (active == NULL) { + device->asyncreq = busrequest; + device->asyncreq->inusenext = NULL; + } else { + for (async = device->asyncreq; + async != NULL; + async = async->inusenext) { + active = async; + } + active->inusenext = busrequest; + busrequest->inusenext = NULL; + } + spin_unlock_irqrestore(&device->asynclock, flags); +} + + +/* queue a read/write request */ +A_STATUS +HIFReadWrite(HIF_DEVICE *device, + A_UINT32 address, + A_UCHAR *buffer, + A_UINT32 length, + A_UINT32 request, + void *context) +{ + A_STATUS status = A_OK; + BUS_REQUEST *busrequest; + + + AR_DEBUG_ASSERT(device != NULL); + AR_DEBUG_ASSERT(device->func != NULL); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("AR6000: device 0x%p addr 0x%X buffer 0x%p len %d req 0x%X context 0x%p", + device, address, buffer, length, request, context)); + + /*sdio r/w action is not needed when suspend with cut power,so just return*/ + if((device->is_suspend == TRUE)&&(device->powerConfig == HIF_DEVICE_POWER_CUT)){ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("skip io when suspending\n")); + return A_OK; + } + do { + if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){ + /* serialize all requests through the async thread */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", + (request & HIF_ASYNCHRONOUS)?"Async":"Synch")); + busrequest = hifAllocateBusRequest(device); + if (busrequest == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n", + request & HIF_READ ? "READ":"WRITE", address, length)); + return A_ERROR; + } + busrequest->address = address; + busrequest->buffer = buffer; + busrequest->length = length; + busrequest->request = request; + busrequest->context = context; + + AddToAsyncList(device, busrequest); + + if (request & HIF_SYNCHRONOUS) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest)); + + /* wait for completion */ + up(&device->sem_async); + if (down_interruptible(&busrequest->sem_req) != 0) { + /* interrupted, exit */ + return A_ERROR; + } else { + A_STATUS status = busrequest->status; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n", + (unsigned long)busrequest, busrequest->status)); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request)); + hifFreeBusRequest(device, busrequest); + return status; + } + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest)); + up(&device->sem_async); + return A_PENDING; + } + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request)); + status = A_EINVAL; + break; + } + } while(0); + + return status; +} +/* thread to serialize all requests, both sync and async */ +static int async_task(void *param) + { + HIF_DEVICE *device; + BUS_REQUEST *request; + A_STATUS status; + unsigned long flags; + + device = (HIF_DEVICE *)param; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n")); + set_current_state(TASK_INTERRUPTIBLE); + while(!device->async_shutdown) { + /* wait for work */ + if (down_interruptible(&device->sem_async) != 0) { + /* interrupted, exit */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n")); + break; + } + if (device->async_shutdown) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n")); + break; + } + /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */ + sdio_claim_host(device->func); + spin_lock_irqsave(&device->asynclock, flags); + /* pull the request to work on */ + while (device->asyncreq != NULL) { + request = device->asyncreq; + if (request->inusenext != NULL) { + device->asyncreq = request->inusenext; + } else { + device->asyncreq = NULL; + } + spin_unlock_irqrestore(&device->asynclock, flags); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request)); + + if (request->pScatterReq != NULL) { + A_ASSERT(device->scatter_enabled); + /* this is a queued scatter request, pass the request to scatter routine which + * executes it synchronously, note, no need to free the request since scatter requests + * are maintained on a separate list */ + status = DoHifReadWriteScatter(device,request); + } else { + /* call HIFReadWrite in sync mode to do the work */ + status = __HIFReadWrite(device, request->address, request->buffer, + request->length, request->request & ~HIF_SYNCHRONOUS, NULL); + if (request->request & HIF_ASYNCHRONOUS) { + void *context = request->context; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request)); + hifFreeBusRequest(device, request); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request)); + device->htcCallbacks.rwCompletionHandler(context, status); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request)); + request->status = status; + up(&request->sem_req); + } + } + spin_lock_irqsave(&device->asynclock, flags); + } + spin_unlock_irqrestore(&device->asynclock, flags); + sdio_release_host(device->func); + } + + complete_and_exit(&device->async_completion, 0); + return 0; +} + +static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg, A_UINT32 flags, A_UINT32 *resp) +{ + struct mmc_command cmd; + A_INT32 err; + struct mmc_host *host; + struct sdio_func *func; + + func = device->func; + host = func->card->host; + + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = opcode; + cmd.arg = arg; + cmd.flags = flags; + err = mmc_wait_for_cmd(host, &cmd, 3); + + if ((!err) && (resp)) { + *resp = cmd.resp[0]; + } + + return err; +} +A_STATUS ReinitSDIO(HIF_DEVICE *device) +{ + A_INT32 err = 0; + struct mmc_host *host; + struct mmc_card *card; + struct sdio_func *func; + A_UINT8 cmd52_resp; + A_UINT32 clock; + + func = device->func; + card = func->card; + host = card->host; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n")); + sdio_claim_host(func); + + do { + /* 2.6.32 kernel does part of the SDIO initalization upon resume */ + A_BOOL lt_2_6_32 = (LINUX_VERSION_CODEocr_avail) - 1; + /* emulate the mmc_power_up(...) */ + host->ios.vdd = bit; + host->ios.chip_select = MMC_CS_DONTCARE; + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.power_mode = MMC_POWER_UP; + host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; + host->ops->set_ios(host, &host->ios); + /* + * This delay should be sufficient to allow the power supply + * to reach the minimum voltage. + */ + msleep(2); + + host->ios.clock = host->f_min; + host->ios.power_mode = MMC_POWER_ON; + host->ops->set_ios(host, &host->ios); + + /* + * This delay must be at least 74 clock sizes, or 1 ms, or the + * time required to reach a stable voltage. + */ + msleep(2); + + /* Issue CMD0. Goto idle state */ + host->ios.chip_select = MMC_CS_HIGH; + host->ops->set_ios(host, &host->ios); + msleep(1); + err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL); + host->ios.chip_select = MMC_CS_DONTCARE; + host->ops->set_ios(host, &host->ios); + msleep(1); + host->use_spi_crc = 0; + + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err)); + break; + } + + if (!host->ocr) { + /* Issue CMD5, arg = 0 */ + err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); + break; + } + host->ocr = resp; + } + + /* Issue CMD5, arg = ocr. Wait till card is ready */ + for (i=0;i<100;i++) { + err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); + break; + } + if (resp & MMC_CARD_BUSY) { + break; + } + msleep(10); + } + + if ((i == 100) || (err)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err)); + break; + } + + /* Issue CMD3, get RCA */ + err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err)); + break; + } + rca = resp >> 16; + host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; + host->ops->set_ios(host, &host->ios); + + /* Issue CMD7, select card */ + err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err)); + break; + } + } + + /* Enable high speed */ + if (card->host->caps & MMC_CAP_SD_HIGHSPEED) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n")); + err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err)); + card->state &= ~MMC_STATE_HIGHSPEED; + /* no need to break */ + } else { + err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS)); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err)); + break; + } + mmc_card_set_highspeed(card); + host->ios.timing = MMC_TIMING_SD_HS; + host->ops->set_ios(host, &host->ios); + } + } + + /* Set clock */ + if (mmc_card_highspeed(card)) { + clock = 50000000; + } else { + clock = card->cis.max_dtr; + } + + if (clock > host->f_max) { + clock = host->f_max; + } + /* + * In fpga mode the clk should be set to 12500000, or will result in scan channel setting timeout error. + * So in fpga mode, please set module parameter mmcclock to 12500000. + */ + if(mmcclock > 0) + clock = mmcclock; + host->ios.clock = clock; + host->ops->set_ios(host, &host->ios); + + + if (card->host->caps & MMC_CAP_4_BIT_DATA) { + /* CMD52: Set bus width & disable card detect resistor */ + err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT); + if (err) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err)); + break; + } + host->ios.bus_width = MMC_BUS_WIDTH_4; + host->ops->set_ios(host, &host->ios); + } + } while (0); + + sdio_release_host(func); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n")); + + return (err) ? A_ERROR : A_OK; +} + +#ifdef CONFIG_PM +/* + * Setup IRQ mode for deep sleep and WoW + * Switch back to 1 bits mode when we suspend for WoW in order to + * detect SDIO irq without clock. + * Re-enable async 4-bit irq mode for some host controllers after resume + */ +static int SdioEnable4bits(HIF_DEVICE *device, int enable) +{ + int ret = 0; + struct sdio_func *func = device->func; + struct mmc_card *card = func->card; + struct mmc_host *host = card->host; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + unsigned char ctrl = 0; + unsigned int width; +#ifdef SDIO_BUS_WIDTH_8BIT + unsigned char wide_mask = (SDIO_BUS_WIDTH_4BIT|SDIO_BUS_WIDTH_8BIT); +#else + unsigned char wide_mask = (SDIO_BUS_WIDTH_4BIT); +#endif +#endif + + if (!(host->caps & (MMC_CAP_4_BIT_DATA))) + return 0; + + if (card->cccr.low_speed && !card->cccr.wide_bus) + return 0; + + sdio_claim_host(func); + do { + int setAsyncIRQ = 0; + __u16 manufacturer_id = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; + /* 2.6.34 will setup 1bits automatically. No need to setup */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + ret = Func0_CMD52ReadByte(card, SDIO_CCCR_IF, &ctrl); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Fail to read CCCR_IF : %d \n", __func__, ret)); + break; + } + if (enable) { + width = MMC_BUS_WIDTH_4; + ctrl &= ~(SDIO_BUS_WIDTH_1BIT|wide_mask); + ctrl |= SDIO_BUS_WIDTH_4BIT; + } else { + width = MMC_BUS_WIDTH_1; + ctrl &= ~(wide_mask); + } + + ret = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, ctrl); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Fail to write CCCR_IF : %d \n", __func__, ret)); + break; + } + host->ios.bus_width = width; + host->ops->set_ios(host, &host->ios); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) */ + + /* Re-enable 4-bit ASYNC interrupt on AR6003x after system resume for some host controller */ + if (manufacturer_id == MANUFACTURER_ID_AR6003_BASE) { + setAsyncIRQ = 1; + ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6003, + enable ? SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003 : 0); + } else if (manufacturer_id == MANUFACTURER_ID_AR6320_BASE || manufacturer_id == MANUFACTURER_ID_QCA9377_BASE) { + unsigned char data = 0; + setAsyncIRQ = 1; + ret = Func0_CMD52ReadByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6320, &data); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to read interrupt extension register %d \n",ret)); + sdio_release_host(func); + return ret; + } + if (enable) + data |= SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320; + else + data &= ~SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320; + ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6320, data); + } + if (setAsyncIRQ){ + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to setup 4-bit ASYNC IRQ mode into %d err %d \n", enable, ret)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("AR6000: Setup 4-bit ASYNC IRQ mode into %d successfully\n", enable)); + } + } + } while (0); + sdio_release_host(func); + return ret; +} + +#endif /* CONFIG_PM */ +A_STATUS +PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) +{ + A_STATUS status = A_OK; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) + struct sdio_func *func = device->func; + int old_reset_val; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config)); + switch (config) { + case HIF_DEVICE_POWER_DOWN: + /* Disable 4bits in order to let SDIO bus detect DAT1 as interrupt source */ + SdioEnable4bits(device, 0); + break; + case HIF_DEVICE_POWER_CUT: + old_reset_val = reset_sdio_on_unload; + reset_sdio_on_unload = 1; + status = hifDisableFunc(device, func); + reset_sdio_on_unload = old_reset_val; + if (!device->is_suspend) { + device->powerConfig = config; + mmc_detect_change(device->host, HZ/3); + } + break; + case HIF_DEVICE_POWER_UP: + if (device->powerConfig == HIF_DEVICE_POWER_CUT) { + if (device->is_suspend) { + status = ReinitSDIO(device); + /* set powerConfig before EnableFunc to passthrough sdio r/w action when resuming from cut power */ + device->powerConfig = config; + if (status == A_OK) { + status = hifEnableFunc(device, func); + } + } else { + /* device->func is bad pointer at this time */ + mmc_detect_change(device->host, 0); + return A_PENDING; /* Don't change powerConfig status */ + } + } else if (device->powerConfig == HIF_DEVICE_POWER_DOWN) { + int ret = SdioEnable4bits(device, 1); + status = (ret==0) ? A_OK : A_ERROR; + } + break; + } + device->powerConfig = config; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n")); +#endif + return status; +} + +A_STATUS +HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, + void *config, A_UINT32 configLen) +{ + A_UINT32 count; + A_STATUS status = A_OK; + + switch(opcode) { + case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: + ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; + ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; + ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; + ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; + break; + + case HIF_DEVICE_GET_MBOX_ADDR: + for (count = 0; count < 4; count ++) { + ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count); + } + + if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) { + SetExtendedMboxWindowInfo((A_UINT16)device->func->device, + (HIF_DEVICE_MBOX_INFO *)config); + } + + break; + case HIF_DEVICE_GET_PENDING_EVENTS_FUNC: + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: configuration opcode %d is not used for Linux SDIO stack \n", opcode)); + status = A_ERROR; + break; + case HIF_DEVICE_GET_IRQ_PROC_MODE: + *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY; + break; + case HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC: + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: configuration opcode %d is not used for Linux SDIO stack \n", opcode)); + status = A_ERROR; + break; + case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT: + if (!device->scatter_enabled) { + return A_ENOTSUP; + } + status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config); + if (A_FAILED(status)) { + device->scatter_enabled = FALSE; + } + break; + case HIF_DEVICE_GET_OS_DEVICE: + /* pass back a pointer to the SDIO function's "dev" struct */ + ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev; + break; + case HIF_DEVICE_POWER_STATE_CHANGE: + status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config); + break; + case HIF_DEVICE_GET_IRQ_YIELD_PARAMS: + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: configuration opcode %d is only used for RTOS systems, not Linux systems\n", opcode)); + status = A_ERROR; + break; + case HIF_DEVICE_SET_HTC_CONTEXT: + device->htcContext = config; + break; + case HIF_DEVICE_GET_HTC_CONTEXT: + if (config == NULL){ + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Argument of HIF_DEVICE_GET_HTC_CONTEXT is NULL\n")); + return A_ERROR; + } + *(void**)config = device->htcContext; + break; + case HIF_BMI_DONE: + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("%s: BMI_DONE\n", __FUNCTION__)); /* TBDXXX */ + break; + } + default: + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: Unsupported configuration opcode: %d\n", opcode)); + status = A_ERROR; + } + + return status; +} + +void +HIFShutDownDevice(HIF_DEVICE *device) +{ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n")); + if (device != NULL) { + AR_DEBUG_ASSERT(device->powerConfig==HIF_DEVICE_POWER_CUT || device->func != NULL); + } else { + int i; + /* since we are unloading the driver anyways, reset all cards in case the SDIO card + * is externally powered and we are unloading the SDIO stack. This avoids the problem when + * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already + * enumerated */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n")); + ResetAllCards(); + + /* Unregister with bus driver core */ + if (registered) { + registered = 0; + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Unregistering with the bus driver\n")); + sdio_unregister_driver(&ar6k_driver); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Unregistered!")); + } + + for (i=0; ifunc == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("AR6000: Remove pending hif_device %p\n", hif_devices[i])); + delHifDevice(hif_devices[i]); + hif_devices[i] = NULL; + } + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n")); +} + +static void +hifIRQHandler(struct sdio_func *func) +{ + A_STATUS status; + HIF_DEVICE *device; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); + + device = getHifDevice(func); + atomic_set(&device->irqHandling, 1); + /* release the host during ints so we can pick it back up when we process cmds */ + sdio_release_host(device->func); + status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); + sdio_claim_host(device->func); + atomic_set(&device->irqHandling, 0); + AR_DEBUG_ASSERT(status == A_OK || status == A_ECANCELED); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n")); +} + +/* handle HTC startup via thread*/ +static int startup_task(void *param) +{ + HIF_DEVICE *device; + + device = (HIF_DEVICE *)param; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); + /* start up inform DRV layer */ + if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); + } + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) +static int enable_task(void *param) +{ + HIF_DEVICE *device; + device = (HIF_DEVICE *)param; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n")); + + /* start up inform DRV layer */ + if (device && + device->claimedContext && + osdrvCallbacks.devicePowerChangeHandler && + osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != A_OK) + { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); + } + + return 0; +} +#endif +static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) +{ + int i; + int ret; + HIF_DEVICE * device = NULL; + int count; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", + func->num, func->vendor, id->device, func->max_blksize, func->cur_blksize)); + /* + dma_mask should not be NULL, otherwise dma_map_single will crash. + TODO: check why dma_mask is NULL here + */ + if (func->dev.dma_mask == NULL){ + static u64 dma_mask = 0xFFFFFFFF; + func->dev.dma_mask = &dma_mask; + } + for (i=0; ipowerConfig == HIF_DEVICE_POWER_CUT && + hifdevice->host == func->card->host) { + hifdevice->func = func; + hifdevice->powerConfig = HIF_DEVICE_POWER_UP; + sdio_set_drvdata(func, hifdevice); + device = getHifDevice(func); + + if (device->is_suspend) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("AR6000: hifDeviceInserted, Resume from suspend, need to ReinitSDIO.\n")); + ret = ReinitSDIO(device); + } + break; + } + } + + if (device==NULL) { + addHifDevice(func); + device = getHifDevice(func); + + for (i=0; iid = id; + device->host = func->card->host; + device->is_disabled = TRUE; +/* +TODO: MMC SDIO3.0 Setting should also be modified in ReInit() function when Power Manage work. +*/ + { + A_UINT32 clock, clock_set = 12500000; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + unsigned int bus_speed = 0, timing = 0; + unsigned char speed = 0; +#endif + sdio_claim_host(func); + if (writecccr1) { + A_UINT32 err = Func0_CMD52WriteByte(func->card, + writecccr1, + writecccr1value); + if (err) { + printk("Write CCCR 0x%02X to 0x%02X failed: %d\n", + (unsigned int) writecccr1, + (unsigned int) writecccr1value, + (unsigned int) err); + } else { + printk("Write CCCR 0x%02X to 0x%02X OK\n", + (unsigned int) writecccr1, + (unsigned int) writecccr1value); + } + } + if (writecccr2) { + A_UINT32 err = Func0_CMD52WriteByte(func->card, + writecccr2, + writecccr2value); + if (err) { + printk("Write CCCR 0x%02X to 0x%02X failed: %d\n", + (unsigned int) writecccr2, + (unsigned int) writecccr2value, + (unsigned int) err); + } else { + printk("Write CCCR 0x%02X to 0x%02X OK\n", + (unsigned int) writecccr2, + (unsigned int) writecccr2value); + } + } + if (writecccr3) { + A_UINT32 err = Func0_CMD52WriteByte(func->card, + writecccr3, + writecccr3value); + if (err) { + printk("Write CCCR 0x%02X to 0x%02X failed: %d\n", + (unsigned int) writecccr3, + (unsigned int) writecccr3value, + (unsigned int) err); + } else { + printk("Write CCCR 0x%02X to 0x%02X OK\n", + (unsigned int) writecccr3, + (unsigned int) writecccr3value); + } + } + if (writecccr4) { + A_UINT32 err = Func0_CMD52WriteByte(func->card, + writecccr4, + writecccr4value); + if (err) { + printk("Write CCCR 0x%02X to 0x%02X failed: %d\n", + (unsigned int) writecccr4, + (unsigned int) writecccr4value, + (unsigned int) err); + } else { + printk("Write CCCR 0x%02X to 0x%02X OK\n", + (unsigned int) writecccr4, + (unsigned int) writecccr4value); + } + } + // Set MMC Clock + if (mmcclock > 0){ + clock_set = mmcclock; + } + if (mmc_card_highspeed(func->card)){ + clock = 50000000; + } else { + clock = func->card->cis.max_dtr; + } + if (clock > device->host->f_max){ + clock = device->host->f_max; + } + + printk(KERN_ERR "%s: Dumping clocks (%d,%d)\n", __func__, func->card->cis.max_dtr, device->host->f_max); + +/* +// We don't need to set the clock explicitly on 8064/ADP platforms. +// The clock chosen by the MMC stack will take affect. + + printk(KERN_ERR "Decrease host clock from %d to %d(%d,%d)\n", + clock, clock_set, func->card->cis.max_dtr, device->host->f_max); + device->host->ios.clock = clock_set; + device->host->ops->set_ios(device->host, &device->host->ios); +*/ + /* only when mmcclock module parameter is specified, + * set the clock explicitly + */ + if (mmcclock > 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Decrease host clock from %d to %d(%d,%d)\n", + clock, clock_set, func->card->cis.max_dtr, device->host->f_max)); + device->host->ios.clock = clock_set; + device->host->ops->set_ios(device->host, &device->host->ios); + } + +// Set SDIO3.0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + // Set MMC Bus Width: 1-1Bit, 4-4Bit, 8-8Bit + if (mmcbuswidth > 0){ + if (mmcbuswidth == 1){ + ret = Func0_CMD52WriteByte(func->card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE|SDIO_BUS_WIDTH_1BIT); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: CMD52 to set bus width failed: %d \n", __func__, ret)); + return ret; + } + device->host->ios.bus_width = MMC_BUS_WIDTH_1; + device->host->ops->set_ios(device->host, &device->host->ios); + } else if (mmcbuswidth == 4 && (device->host->caps & MMC_CAP_4_BIT_DATA)){ + ret = Func0_CMD52WriteByte(func->card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE|SDIO_BUS_WIDTH_4BIT); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: CMD52 to set bus width failed: %d \n", __func__, ret)); + return ret; + } + device->host->ios.bus_width = MMC_BUS_WIDTH_4; + device->host->ops->set_ios(device->host, &device->host->ios); + } +#ifdef SDIO_BUS_WIDTH_8BIT + else if (mmcbuswidth == 8 && (device->host->caps & MMC_CAP_8_BIT_DATA)){ + ret = Func0_CMD52WriteByte(func->card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE|SDIO_BUS_WIDTH_8BIT); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: CMD52 to set bus width failed: %d \n", __func__, ret)); + return ret; + } + device->host->ios.bus_width = MMC_BUS_WIDTH_8; + device->host->ops->set_ios(device->host, &device->host->ios); + } +#endif /* SDIO_BUS_WIDTH_8BIT */ + else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: MMC bus width %d is not supported. \n", __func__, mmcbuswidth)); + return ret = -1; + } + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus width to %dBit. \n", __func__, mmcbuswidth)); + } + if (debugcccr) { + HIFDumpCCCR(device); + } + // Set MMC Bus Mode: 1-SDR12, 2-SDR25, 3-SDR50, 4-DDR50, 5-SDR104 + if (mmcbusmode > 0) { + printk("host caps:0x%08X, card_sd3_bus_mode:0x%08X\n", (unsigned int)func->card->host->caps, (unsigned int)func->card->sw_caps.sd3_bus_mode); + if (mmcbusmode == 5 && (func->card->host->caps & MMC_CAP_UHS_SDR104) && + ((func->card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104) || forcecard)) { + bus_speed = SDIO_SPEED_SDR104; + timing = MMC_TIMING_UHS_SDR104; + func->card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus mode to SDR104. \n", __func__)); + } else if (mmcbusmode == 4 && (func->card->host->caps & MMC_CAP_UHS_DDR50) && + ((func->card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50) || forcecard)) { + bus_speed = SDIO_SPEED_DDR50; + timing = MMC_TIMING_UHS_DDR50; + func->card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus mode to DDR50. \n", __func__)); + } else if (mmcbusmode == 3 && (func->card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50)) && + ((func->card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) || forcecard)) { + bus_speed = SDIO_SPEED_SDR50; + timing = MMC_TIMING_UHS_SDR50; + func->card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus mode to SDR50. \n", __func__)); + } else if (mmcbusmode == 2 && (func->card->host->caps & + (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && + ((func->card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25) || forcecard)) { + bus_speed = SDIO_SPEED_SDR25; + timing = MMC_TIMING_UHS_SDR25; + func->card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus mode to SDR25. \n", __func__)); + } else if (mmcbusmode == 1 && (func->card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | + MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR12)) && + ((func->card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR12) || forcecard)) { + bus_speed = SDIO_SPEED_SDR12; + timing = MMC_TIMING_UHS_SDR12; + func->card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("%s: Set MMC bus mode to SDR12. \n", __func__)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: MMC bus mode %d not supported. \n", __func__, mmcbusmode)); + return ret = -1; + } + + ret = Func0_CMD52ReadByte(func->card, SDIO_CCCR_SPEED, &speed); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: CMD52 to get CCCR SPEED failed: %d, cap_uhs: %lu, sd3_bus_mode: %x \n", __func__, ret, (long unsigned int)(func->card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR12)), func->card->sw_caps.sd3_bus_mode)); + return ret; + } + + speed &= ~SDIO_SPEED_BSS_MASK; + speed |= bus_speed; + ret = Func0_CMD52WriteByte(func->card, SDIO_CCCR_SPEED, speed); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: CMD52 to set CCCR SPPED failed: %d \n", __func__, ret)); + return ret; + } + + if (bus_speed) { + device->host->ios.timing = timing; + device->host->ops->set_ios(device->host, &device->host->ios); + // mmc_set_clock(func->card->host, func->card->sw_caps.uhs_max_dtr); + } + } + +#endif //#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + + sdio_release_host(func); + } + + spin_lock_init(&device->lock); + + spin_lock_init(&device->asynclock); + + DL_LIST_INIT(&device->ScatterReqHead); + + if (!nohifscattersupport) { + /* try to allow scatter operation on all instances, + * unless globally overridden */ + device->scatter_enabled = TRUE; + } + else + device->scatter_enabled = FALSE; + + /* Initialize the bus requests to be used later */ + A_MEMZERO(device->busRequest, sizeof(device->busRequest)); + for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { + sema_init(&device->busRequest[count].sem_req, 0); + hifFreeBusRequest(device, &device->busRequest[count]); + } + sema_init(&device->sem_async, 0); + } + + ret = hifEnableFunc(device, func); + return (ret == A_OK || ret == A_PENDING) ? 0 : -1; +} + + +void +HIFAckInterrupt(HIF_DEVICE *device) +{ + AR_DEBUG_ASSERT(device != NULL); + + /* Acknowledge our function IRQ */ +} + +void +HIFUnMaskInterrupt(HIF_DEVICE *device) +{ + int ret;; + + AR_DEBUG_ASSERT(device != NULL); + AR_DEBUG_ASSERT(device->func != NULL); + + ENTER(); + /* + * On HP Elitebook 8460P, interrupt mode is not stable in high throughput, + * so polling method should be used instead of interrupt mode + */ + if (brokenirq){ + printk(KERN_ERR"AR6000:Using broken IRQ mode\n"); + /* disable IRQ support even the capability exists */ + device->func->card->host->caps &= ~MMC_CAP_SDIO_IRQ; + } + /* Register the IRQ Handler */ + sdio_claim_host(device->func); + ret = sdio_claim_irq(device->func, hifIRQHandler); + sdio_release_host(device->func); + AR_DEBUG_ASSERT(ret == 0); + EXIT(); +} + +void HIFMaskInterrupt(HIF_DEVICE *device) +{ + int ret; + AR_DEBUG_ASSERT(device != NULL); + AR_DEBUG_ASSERT(device->func != NULL); + + ENTER(); + + /* Mask our function IRQ */ + sdio_claim_host(device->func); + while (atomic_read(&device->irqHandling)) { + sdio_release_host(device->func); + schedule_timeout_interruptible(HZ/10); + sdio_claim_host(device->func); + } + ret = sdio_release_irq(device->func); + sdio_release_host(device->func); + if (ret) { + if (ret == -ETIMEDOUT) { + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: Timeout to mask interrupt. Card removed?\n")); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Unable to mask interrupt %d\n", ret)); + AR_DEBUG_ASSERT(ret == 0); + } + } + EXIT(); +} + +BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device) +{ + BUS_REQUEST *busrequest; + unsigned long flag; + + /* Acquire lock */ + spin_lock_irqsave(&device->lock, flag); + + /* Remove first in list */ + if((busrequest = device->s_busRequestFreeQueue) != NULL) + { + device->s_busRequestFreeQueue = busrequest->next; + } + /* Release lock */ + spin_unlock_irqrestore(&device->lock, flag); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest)); + return busrequest; +} + +void +hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) +{ + unsigned long flag; + + AR_DEBUG_ASSERT(busrequest != NULL); + //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest)); + /* Acquire lock */ + spin_lock_irqsave(&device->lock, flag); + + + /* Insert first in list */ + busrequest->next = device->s_busRequestFreeQueue; + busrequest->inusenext = NULL; + device->s_busRequestFreeQueue = busrequest; + + /* Release lock */ + spin_unlock_irqrestore(&device->lock, flag); +} + +static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) +{ + int ret; + A_STATUS status = A_OK; + + ENTER(); + device = getHifDevice(func); + if (!IS_ERR(device->async_task)) { + init_completion(&device->async_completion); + device->async_shutdown = 1; + up(&device->sem_async); + wait_for_completion(&device->async_completion); + device->async_task = NULL; + sema_init(&device->sem_async, 0); + } + /* Disable the card */ + sdio_claim_host(device->func); + ret = sdio_disable_func(device->func); + if (ret) { + status = A_ERROR; + } + + if (reset_sdio_on_unload && status == A_OK) { + /* reset the SDIO interface. This is useful in automated testing where the card + * does not need to be removed at the end of the test. It is expected that the user will + * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */ + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n")); + + /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access + * to undefined registers in the range of: 0xF0-0xFF */ + + ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)); + if (ret) { + status = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret)); + } + } + + sdio_release_host(device->func); + + if (status == A_OK) { + device->is_disabled = TRUE; + } + CleanupHIFScatterResources(device); + + EXIT(); + return status; +} + +static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) +{ + struct task_struct* pTask; + const char *taskName = NULL; + int (*taskFunc)(void *) = NULL; + int ret = A_OK; + + ENTER("sdio_func 0x%p", func); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n")); + device = getHifDevice(func); + + if (device->is_disabled) { + int setAsyncIRQ = 0; + __u16 manufacturer_id = device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK; + /* enable the SDIO function */ + sdio_claim_host(func); + /* enable 4-bit ASYNC interrupt on AR6003x or later devices */ + if (manufacturer_id == MANUFACTURER_ID_AR6003_BASE) { + setAsyncIRQ = 1; + ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6003, + SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003); + } else if (manufacturer_id == MANUFACTURER_ID_AR6320_BASE || + manufacturer_id == MANUFACTURER_ID_QCA9377_BASE) { + unsigned char data = 0; + setAsyncIRQ = 1; + ret = Func0_CMD52ReadByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6320, &data); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to read interrupt extension register %d \n",ret)); + sdio_release_host(func); + return A_ERROR; + } + data |= SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320; + ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG_AR6320, data); + } + if (setAsyncIRQ){ + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret)); + sdio_release_host(func); + return A_ERROR; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n")); + } + + /* set CCCR 0xF0[7:6] to increase async interrupt delay clock to fix interrupt missing issue on dell 8460p */ + if (asyncintdelay != 0){ + unsigned char data = 0; + ret = Func0_CMD52ReadByte(func->card, CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, &data); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to read CCCR %d, result is %d \n", + CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, ret)); + sdio_release_host(func); + return A_ERROR; + } + data = (data & ~CCCR_SDIO_ASYNC_INT_DELAY_MASK) | + ((asyncintdelay << CCCR_SDIO_ASYNC_INT_DELAY_LSB) & CCCR_SDIO_ASYNC_INT_DELAY_MASK); + ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, data); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to write CCCR %d, result is %d \n", + CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS, ret)); + sdio_release_host(func); + return A_ERROR; + } + printk(KERN_ERR"AR6000: Set async interrupt delay clock as %d.\n", asyncintdelay); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + /* give us some time to enable, in ms */ + func->enable_timeout = 100; +#endif + ret = sdio_enable_func(func); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", + __FUNCTION__, ret)); + sdio_release_host(func); + return A_ERROR; + } + ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); + + if (modstrength){ + unsigned int address = WINDOW_DATA_ADDRESS; + unsigned int value = 0x0FFF; + ret = sdio_memcpy_toio(device->func, address, &value, 4); + if (ret) { + printk("memcpy_toio 0x%x 0x%x error:%d\n", address, value, ret); + } else { + printk("memcpy_toio, 0x%x 0x%x OK\n", address, value); + address = WINDOW_WRITE_ADDR_ADDRESS; + value = 0x50F8; + ret = sdio_memcpy_toio(device->func, address, &value, 4); + if (ret) { + printk("memcpy_toio 0x%x 0x%x error:%d\n", address, value, ret); + } else { + printk("memcpy_toio, 0x%x 0x%x OK\n", address, value); + } + } + }; + sdio_release_host(func); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", + __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); + return A_ERROR; + } + device->is_disabled = FALSE; + /* create async I/O thread */ + if (!device->async_task) { + device->async_shutdown = 0; + device->async_task = kthread_create(async_task, + (void *)device, + "AR6K Async"); + if (IS_ERR(device->async_task)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); + return A_ERROR; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); + wake_up_process(device->async_task ); + } + } + + if (!device->claimedContext) { + taskFunc = startup_task; + taskName = "AR6K startup"; + ret = A_OK; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) + } else { + taskFunc = enable_task; + taskName = "AR6K enable"; + ret = A_PENDING; +#endif /* CONFIG_PM */ + } + /* create resume thread */ + pTask = kthread_create(taskFunc, (void *)device, taskName); + if (IS_ERR(pTask)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__)); + return A_ERROR; + } + wake_up_process(pTask); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n")); + + /* task will call the enable func, indicate pending */ + EXIT(); + return ret; +} +#if 0 +//ToDO - This is a part of suspend/resume functionality +static int hifStopAllVap(struct ol_ath_softc_net80211 *scn) +{ + struct ieee80211com *ic; + struct ieee80211vap *vap; + struct ieee80211vap *vapnext; + osif_dev *osifp; + struct net_device *netdev; + A_STATUS status = A_OK; + + ic = &scn->sc_ic; + vap = TAILQ_FIRST(&ic->ic_vaps); + while (vap != NULL) { + vapnext = TAILQ_NEXT(vap, iv_next); + osifp = (osif_dev *)vap->iv_ifp; + if(osifp->is_up == 0){ + vap = vapnext; + continue; + } + + /* force target to sleep */ + wlan_pwrsave_force_sleep(vap,TRUE); + + netdev = osifp->netdev; + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: %s()stopping interface %s\n", __FUNCTION__, netdev->name)); + status = osif_vap_stop(netdev); + if(status){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s()stop interface %s failed\n", __FUNCTION__, netdev->name)); + } + vap = vapnext; + } + + return A_OK; +} + +static int hifRestartAllVap(struct ol_ath_softc_net80211 *scn) +{ + struct ieee80211com *ic; + struct ieee80211vap *vap; + struct ieee80211vap *vapnext; + osif_dev *osifp; + struct net_device *netdev; + + ic = &scn->sc_ic;; + vap = TAILQ_FIRST(&ic->ic_vaps); + while (vap != NULL) { + vapnext = TAILQ_NEXT(vap, iv_next); + osifp = (osif_dev *)vap->iv_ifp; + netdev = osifp->netdev; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: %s()restarting interface %s\n", __FUNCTION__, netdev->name)); + netdev->flags |= IFF_RUNNING; /* we are ready to go */ + osifp->is_vap_pending = 1; + osif_vap_init(netdev, 0); + + /* restore power save state */ + wlan_pwrsave_force_sleep(vap,FALSE); + + vap = vapnext; + } + + return A_OK; +} +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM) +static int hifDeviceSuspend(struct device *dev) +{ + struct sdio_func *func=dev_to_sdio_func(dev); + A_STATUS status = A_OK; + int ret = A_OK; +#if defined(MMC_PM_KEEP_POWER) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + mmc_pm_flag_t pm_flag = 0; + HIF_DEVICE_POWER_CHANGE_TYPE config; + struct mmc_host *host = NULL; +#endif + + HIF_DEVICE *device = getHifDevice(func); + +#if defined(MMC_PM_KEEP_POWER) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + if (device && device->func) { + host = device->func->card->host; + } +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); + if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { + device->is_suspend = TRUE; /* set true first for PowerStateChangeNotify(..) */ + status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); + +#if defined(MMC_PM_KEEP_POWER) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + switch(forcesleepmode){ + case 0://depend on sdio host pm capbility + pm_flag = sdio_get_host_pm_caps(func); + break; + case 1://force WOW + pm_flag |= MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; + break; + case 2://force DeepSleep + pm_flag &= ~MMC_PM_WAKE_SDIO_IRQ; + pm_flag |= MMC_PM_KEEP_POWER; + break; + case 3://force CutPower + pm_flag &= ~(MMC_PM_WAKE_SDIO_IRQ | MMC_PM_WAKE_SDIO_IRQ); + break; + } + if(!(pm_flag & MMC_PM_KEEP_POWER)){ + /* cut power support */ + /*setting powerConfig before HIFConfigureDevice to skip sdio r/w action when suspending with cut power*/ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: cut power enter\n")); + config = HIF_DEVICE_POWER_CUT; + device->powerConfig = config; + if ((device->claimedContext != NULL)&&osdrvCallbacks.deviceRemovedHandler) { + status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); + } + ret = HIFConfigureDevice(device, + HIF_DEVICE_POWER_STATE_CHANGE, + &config, + sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); + if(ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: HIFConfigureDevice failed: %d\n",ret)); + return ret; + } + + HIFMaskInterrupt(device); + device->DeviceState = HIF_DEVICE_STATE_CUTPOWER; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: cut power success\n")); + return ret; + } else { + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: set sdio pm flags MMC_PM_KEEP_POWER failed: %d\n",ret)); + return ret; + } + + /* TODO:WOW support */ + if (pm_flag & MMC_PM_WAKE_SDIO_IRQ){ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: wow enter\n")); + config = HIF_DEVICE_POWER_DOWN; + ret = HIFConfigureDevice(device, + HIF_DEVICE_POWER_STATE_CHANGE, + &config, + sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); + + if(ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: HIFConfigureDevice failed: %d\n",ret)); + return ret; + } + ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + if (ret){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: set sdio pm flags MMC_PM_WAKE_SDIO_IRQ failed: %d\n",ret)); + return ret; + } + HIFMaskInterrupt(device); + device->DeviceState = HIF_DEVICE_STATE_WOW; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: wow success\n")); + return ret; + } + else{ + /* deep sleep support */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: deep sleep enter\n")); +// hifStopAllVap((struct ol_ath_softc_net80211 *)device->claimedContext); + + /* + * Wait for some async clean handler finished. + * These clean handlers are part of vdev disconnect flow. + * As these handlers are async,sleep wait is not a good method, some block kernel method may be a good choice. + * But before adding finishe callback function to these handler, sleep wait is a simple method. + */ + msleep(100); + HIFMaskInterrupt(device); + device->DeviceState = HIF_DEVICE_STATE_DEEPSLEEP; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: deep sleep success\n")); + return ret; + } + } +#endif + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); + + switch (status) { + case A_OK: +#if defined(MMC_PM_KEEP_POWER) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + if (host) { + host->pm_flags &= ~(MMC_PM_KEEP_POWER|MMC_PM_WAKE_SDIO_IRQ); + } +#endif + return 0; + case A_EBUSY: +#if defined(MMC_PM_KEEP_POWER) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + if (host) { + /* Some controller need to WAKE_SDIO_IRQ in order to wake up by DAT1 */ + host->pm_flags |= (MMC_PM_KEEP_POWER|MMC_PM_WAKE_SDIO_IRQ); + host->pm_flags &= host->pm_caps; + } + return 0; +#else + return -EBUSY; /* Hack for kernel to support deep sleep and wow */ +#endif + default: + device->is_suspend = FALSE; + return -1; + } +} + +static int hifDeviceResume(struct device *dev) +{ + struct sdio_func *func=dev_to_sdio_func(dev); + A_STATUS status = A_OK; + HIF_DEVICE_POWER_CHANGE_TYPE config; + HIF_DEVICE *device; + + device = getHifDevice(func); + + if(device->DeviceState == HIF_DEVICE_STATE_CUTPOWER){ + config = HIF_DEVICE_POWER_UP; + status = HIFConfigureDevice(device, + HIF_DEVICE_POWER_STATE_CHANGE, + &config, + sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); + if(status){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: HIFConfigureDevice failed\n")); + return status; + } + } + else if(device->DeviceState == HIF_DEVICE_STATE_DEEPSLEEP){ + HIFUnMaskInterrupt(device); +// hifRestartAllVap((struct ol_ath_softc_net80211 *)device->claimedContext); + } + else if(device->DeviceState == HIF_DEVICE_STATE_WOW){ + /*TODO:WOW support*/ + HIFUnMaskInterrupt(device); + } + + /* + * deviceResumeHandler do nothing now. + * If some operation should be added to this handler in power cut resume flow, + * do make sure those operation is not + * depent on what startup_task has done,or the resume flow will block. + */ + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); + if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { + status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); + device->is_suspend = FALSE; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); + device->DeviceState = HIF_DEVICE_STATE_ON; + + return A_SUCCESS(status) ? 0 : status; +} +#endif /* CONFIG_PM */ + +static void hifDeviceRemoved(struct sdio_func *func) +{ + A_STATUS status = A_OK; + HIF_DEVICE *device; + AR_DEBUG_ASSERT(func != NULL); + + ENTER(); + + device = getHifDevice(func); + + if (device->powerConfig == HIF_DEVICE_POWER_CUT) { + device->func = NULL; /* func will be free by mmc stack */ + return; /* Just return for cut-off mode */ + } else { + int i; + for (i=0; iclaimedContext != NULL) { + status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); + } + + HIFMaskInterrupt(device); + + if (device->is_disabled) { + device->is_disabled = FALSE; + } else { + status = hifDisableFunc(device, func); + } + + delHifDevice(device); + if (status != A_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: Unable to disable sdio func. Card removed?\n")); + } + + EXIT(); +} + +/* + * This should be moved to AR6K HTC layer. + */ +A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device) +{ + A_INT32 cnt = 10; + A_UINT8 host_int_status; + A_STATUS status = A_OK; + + do { + while (atomic_read(&device->irqHandling)) { + /* wait until irq handler finished all the jobs */ + schedule_timeout_interruptible(HZ / 10); + } + /* check if there is any pending irq due to force done */ + host_int_status = 0; + status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, + (A_UINT8 *)&host_int_status, sizeof(host_int_status), + HIF_RD_SYNC_BYTE_INC, NULL); + host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0; + if (host_int_status) { + /* wait until irq handler finishs its job */ + schedule_timeout_interruptible(1); + } + } while (host_int_status && --cnt > 0); + + if (host_int_status && cnt == 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__)); + } + + return A_OK; +} + + +static HIF_DEVICE * +addHifDevice(struct sdio_func *func) +{ + HIF_DEVICE *hifdevice = NULL; + int ret = 0; + ENTER(); + AR_DEBUG_ASSERT(func != NULL); + hifdevice = (HIF_DEVICE *)A_MALLOC(sizeof(HIF_DEVICE)); + AR_DEBUG_ASSERT(hifdevice != NULL); + A_MEMZERO(hifdevice, sizeof(*hifdevice)); +#if HIF_USE_DMA_BOUNCE_BUFFER + hifdevice->dma_buffer = A_MALLOC(HIF_DMA_BUFFER_SIZE); + AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL); +#endif + hifdevice->func = func; + hifdevice->powerConfig = HIF_DEVICE_POWER_UP; + hifdevice->DeviceState = HIF_DEVICE_STATE_ON; + ret = sdio_set_drvdata(func, hifdevice); + + EXIT("status %d", ret); + return hifdevice; +} + +static HIF_DEVICE * +getHifDevice(struct sdio_func *func) +{ + AR_DEBUG_ASSERT(func != NULL); + return (HIF_DEVICE *)sdio_get_drvdata(func); +} + +static void +delHifDevice(HIF_DEVICE * device) +{ + AR_DEBUG_ASSERT(device!= NULL); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device)); + if (device->dma_buffer != NULL) { + A_FREE(device->dma_buffer); + } + A_FREE(device); +} + +static void ResetAllCards(void) +{ +} + +void HIFClaimDevice(HIF_DEVICE *device, void *context) +{ + device->claimedContext = context; +} + +void HIFReleaseDevice(HIF_DEVICE *device) +{ + device->claimedContext = NULL; +} + +A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) +{ + if (device->htcCallbacks.context != NULL) { + /* already in use! */ + return A_ERROR; + } + device->htcCallbacks = *callbacks; + return A_OK; +} + +void HIFDetachHTC(HIF_DEVICE *device) +{ + A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks)); +} + +#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \ + (arg) = (((rw) & 1) << 31) | \ + (((func) & 0x7) << 28) | \ + (((raw) & 1) << 27) | \ + (1 << 26) | \ + (((address) & 0x1FFFF) << 9) | \ + (1 << 8) | \ + ((writedata) & 0xFF) + +#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \ + SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00) +#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \ + SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value) + +static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte) +{ + struct mmc_command ioCmd; + unsigned long arg; + int status = 0; + + memset(&ioCmd,0,sizeof(ioCmd)); + SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte); + ioCmd.opcode = SD_IO_RW_DIRECT; + ioCmd.arg = arg; + ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + status = mmc_wait_for_cmd(card->host, &ioCmd, 0); + + if (status) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: %s mmc_wait_for_cmd returned %d\n",__func__, status)); + + return status; +} + +static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte) +{ + struct mmc_command ioCmd; + unsigned long arg; + A_INT32 err; + + memset(&ioCmd,0,sizeof(ioCmd)); + SDIO_SET_CMD52_READ_ARG(arg,0,address); + ioCmd.opcode = SD_IO_RW_DIRECT; + ioCmd.arg = arg; + ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &ioCmd, 0); + + if ((!err) && (byte)) { + *byte = ioCmd.resp[0] & 0xFF; + } + + if (err) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s mmc_wait_for_cmd returned %d\n",__func__, err)); + + return err; +} + +void HIFDumpCCCR(HIF_DEVICE *hif_device) +{ + int i; + A_UINT8 cccr_val; + A_UINT32 err; + + if (!hif_device || !hif_device->func|| !hif_device->func->card) { + printk("HIFDumpCCCR incorrect input arguments\n"); + return; + } + + printk("HIFDumpCCCR "); + for (i = 0; i <= 0x16; i ++) { + err = Func0_CMD52ReadByte(hif_device->func->card, i, &cccr_val); + if (err) { + printk("Reading CCCR 0x%02X failed: %d\n", (unsigned int)i, (unsigned int)err); + } else { + printk("%X(%X) ", (unsigned int)i, (unsigned int)cccr_val); + } + } +/* + printk("\nHIFDumpCCCR "); + for (i = 0xF0; i <= 0xFF; i ++) { + err = Func0_CMD52ReadByte(hif_device->func->card, i, &cccr_val); + if (err) { + printk("Reading CCCR 0x%02X failed: %d\n", (unsigned int)i, (unsigned int)err); + } else { + printk("0x%02X(%02X)", (unsigned int)i, (unsigned int)cccr_val); + } + } +*/ + printk("\n"); +} + +void HIFsuspendwow(HIF_DEVICE *hif_device) +{ + printk(KERN_INFO "HIFsuspendwow TODO\n"); +} + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif_scatter.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif_scatter.c new file mode 100644 index 0000000000000..52c628256ce39 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif_scatter.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include "hif_internal.h" +#include +#define ATH_MODULE_NAME hif +#include "a_debug.h" + +#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT + +#define _CMD53_ARG_READ 0 +#define _CMD53_ARG_WRITE 1 +#define _CMD53_ARG_BLOCK_BASIS 1 +#define _CMD53_ARG_FIXED_ADDRESS 0 +#define _CMD53_ARG_INCR_ADDRESS 1 + +#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \ + (arg) = (((rw) & 1) << 31) | \ + (((func) & 0x7) << 28) | \ + (((mode) & 1) << 27) | \ + (((opcode) & 1) << 26) | \ + (((address) & 0x1FFFF) << 9) | \ + ((bytes_blocks) & 0x1FF) + +static void FreeScatterReq(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) +{ + unsigned long flag; + + spin_lock_irqsave(&device->lock, flag); + + DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink); + + spin_unlock_irqrestore(&device->lock, flag); + +} + +static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) +{ + DL_LIST *pItem; + unsigned long flag; + + spin_lock_irqsave(&device->lock, flag); + + pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead); + + spin_unlock_irqrestore(&device->lock, flag); + + if (pItem != NULL) { + return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink); + } + + return NULL; +} + + /* called by async task to perform the operation synchronously using direct MMC APIs */ +A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +{ + int i; + A_UINT8 rw; + A_UINT8 opcode; + struct mmc_request mmcreq; + struct mmc_command cmd; + struct mmc_data data; + HIF_SCATTER_REQ_PRIV *pReqPriv; + HIF_SCATTER_REQ *pReq; + A_STATUS status = A_OK; + struct scatterlist *pSg; + + ENTER(); + + pReqPriv = busrequest->pScatterReq; + + A_ASSERT(pReqPriv != NULL); + + pReq = pReqPriv->pHifScatterReq; + + memset(&mmcreq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + + data.blksz = HIF_MBOX_BLOCK_SIZE; + data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE; + + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n", + (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks, + pReq->TotalLength,pReq->ValidScatterEntries)); + + if (pReq->Request & HIF_WRITE) { + rw = _CMD53_ARG_WRITE; + data.flags = MMC_DATA_WRITE; + } else { + rw = _CMD53_ARG_READ; + data.flags = MMC_DATA_READ; + } + + if (pReq->Request & HIF_FIXED_ADDRESS) { + opcode = _CMD53_ARG_FIXED_ADDRESS; + } else { + opcode = _CMD53_ARG_INCR_ADDRESS; + } + + /* fill SG entries */ + pSg = pReqPriv->sgentries; + sg_init_table(pSg, pReq->ValidScatterEntries); + + /* assemble SG list */ + for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) { + /* setup each sg entry */ + if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) { + /* note some scatter engines can handle unaligned buffers, print this + * as informational only */ + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, + ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n", + pReq->Request & HIF_WRITE ? "WRITE":"READ", + (unsigned long)pReq->ScatterList[i].pBuffer)); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, (" %d: Addr:0x%lX, Len:%d \n", + i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length)); + + sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length); + } + /* set scatter-gather table for request */ + data.sg = pReqPriv->sgentries; + data.sg_len = pReq->ValidScatterEntries; + /* set command argument */ + SDIO_SET_CMD53_ARG(cmd.arg, + rw, + device->func->num, + _CMD53_ARG_BLOCK_BASIS, + opcode, + pReq->Address, + data.blocks); + + cmd.opcode = SD_IO_RW_EXTENDED; + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; + + mmcreq.cmd = &cmd; + mmcreq.data = &data; + + mmc_set_data_timeout(&data, device->func->card); + /* synchronous call to process request */ + mmc_wait_for_req(device->func->card->host, &mmcreq); + + if (cmd.error) { + status = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error)); + } + + if (data.error) { + status = A_ERROR; + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error)); + } + + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n", + (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks)); + } + + /* set completion status, fail or success */ + pReq->CompletionStatus = status; + + if (pReq->Request & HIF_ASYNCHRONOUS) { + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status)); + /* complete the request */ + A_ASSERT(pReq->CompletionRoutine != NULL); + pReq->CompletionRoutine(pReq); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status)); + /* signal wait */ + up(&busrequest->sem_req); + } + EXIT(); + + return status; +} + + /* callback to issue a read-write scatter request */ +static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) +{ + A_STATUS status = A_EINVAL; + A_UINT32 request = pReq->Request; + HIF_SCATTER_REQ_PRIV *pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; + + do { + + A_ASSERT(pReqPriv != NULL); + + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n", + pReq->TotalLength, pReq->ValidScatterEntries)); + + if (!(request & HIF_EXTENDED_IO)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("HIF-SCATTER: Invalid command type: 0x%08x\n", request)); + break; + } + + if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request)); + break; + } + + if (!(request & HIF_BLOCK_BASIS)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request)); + break; + } + + if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength)); + break; + } + + if (pReq->TotalLength == 0) { + A_ASSERT(FALSE); + break; + } + + /* add bus request to the async list for the async I/O thread to process */ + AddToAsyncList(device, pReqPriv->busrequest); + + if (request & HIF_SYNCHRONOUS) { + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest)); + /* signal thread and wait */ + up(&device->sem_async); + if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n")); + /* interrupted, exit */ + status = A_ERROR; + break; + } else { + status = pReq->CompletionStatus; + } + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest)); + /* wake thread, it will process and then take care of the async callback */ + up(&device->sem_async); + status = A_OK; + } + + } while (FALSE); + + if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) { + pReq->CompletionStatus = status; + pReq->CompletionRoutine(pReq); + status = A_OK; + } + + return status; +} + + /* setup of HIF scatter resources */ +A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +{ + A_STATUS status = A_ERROR; + int i; + HIF_SCATTER_REQ_PRIV *pReqPriv; + BUS_REQUEST *busrequest; + + do { + /* check if host supports scatter requests and it meets our requirements */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + if (device->func->card->host->max_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", + device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ)); + status = A_ENOTSUP; + break; + } +#else + if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", + device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); + status = A_ENOTSUP; + break; + } +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n", + MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); + + for (i = 0; i < MAX_SCATTER_REQUESTS; i++) { + /* allocate the private request blob */ + pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV)); + if (NULL == pReqPriv) { + break; + } + A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV)); + /* save the device instance*/ + pReqPriv->device = device; + /* allocate the scatter request */ + pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + + (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); + + if (NULL == pReqPriv->pHifScatterReq) { + A_FREE(pReqPriv); + break; + } + /* just zero the main part of the scatter request */ + A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ)); + /* back pointer to the private struct */ + pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv; + /* allocate a bus request for this scatter request */ + busrequest = hifAllocateBusRequest(device); + if (NULL == busrequest) { + A_FREE(pReqPriv->pHifScatterReq); + A_FREE(pReqPriv); + break; + } + /* assign the scatter request to this bus request */ + busrequest->pScatterReq = pReqPriv; + /* point back to the request */ + pReqPriv->busrequest = busrequest; + /* add it to the scatter pool */ + FreeScatterReq(device,pReqPriv->pHifScatterReq); + } + + if (i != MAX_SCATTER_REQUESTS) { + status = A_NO_MEMORY; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n")); + break; + } + + /* set scatter function pointers */ + pInfo->pAllocateReqFunc = AllocScatterReq; + pInfo->pFreeReqFunc = FreeScatterReq; + pInfo->pReadWriteScatterFunc = HifReadWriteScatter; + pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ; + pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE; + + status = A_OK; + + } while (FALSE); + + if (A_FAILED(status)) { + CleanupHIFScatterResources(device); + } + + return status; +} + + /* clean up scatter support */ +void CleanupHIFScatterResources(HIF_DEVICE *device) +{ + HIF_SCATTER_REQ_PRIV *pReqPriv; + HIF_SCATTER_REQ *pReq; + + /* empty the free list */ + + while (1) { + + pReq = AllocScatterReq(device); + + if (NULL == pReq) { + break; + } + + pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; + A_ASSERT(pReqPriv != NULL); + + if (pReqPriv->busrequest != NULL) { + pReqPriv->busrequest->pScatterReq = NULL; + /* free bus request */ + hifFreeBusRequest(device, pReqPriv->busrequest); + pReqPriv->busrequest = NULL; + } + + if (pReqPriv->pHifScatterReq != NULL) { + A_FREE(pReqPriv->pHifScatterReq); + pReqPriv->pHifScatterReq = NULL; + } + + A_FREE(pReqPriv); + } +} + +#endif // HIF_LINUX_MMC_SCATTER_SUPPORT diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.c new file mode 100644 index 0000000000000..34a3f333e9aea --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "bmi_msg.h" +#include "cepci.h" + +#define MISSING 0 +#include "regtable.h" +#include "targaddrs.h" +#include "if_ath_sdio.h" +#include "ar9888def.h" +#include "ar6320def.h" +#include "ar6320v2def.h" + + + +void target_register_tbl_attach(u32 target_type) +{ + ENTER("target_type %d", target_type); + + switch (target_type) { + case TARGET_TYPE_AR9888: + sc->targetdef = &ar9888_targetdef; + break; + case TARGET_TYPE_AR6320: + sc->targetdef = &ar6320_targetdef; + break; + case TARGET_TYPE_AR6320V2: + sc->targetdef = &ar6320v2_targetdef; + break; + default: + break; + } +} + +void hif_register_tbl_attach(u32 hif_type) +{ + ENTER("hif_type %d", hif_type); + + if (NULL == sc) { + VOS_TRACE( VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR, "%s: sc is NULL", + __func__); + return; +} + + switch (hif_type) { + case HIF_TYPE_AR9888: + sc->hostdef = &ar9888_hostdef; + break; + case HIF_TYPE_AR6320: + sc->hostdef = &ar6320_hostdef; + break; + case HIF_TYPE_AR6320V2: + sc->hostdef = &ar6320v2_hostdef; + break; + default: + break; + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.h new file mode 100644 index 0000000000000..3b3ff03b49e3b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/sdio/regtable.h @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#ifndef _REGTABLE_H_ +#define _REGTABLE_H_ +//#include "if_usb.h" + +#define MISSING 0 +extern struct ath_hif_sdio_softc *sc; + +typedef struct targetdef_s { + u_int32_t d_RTC_SOC_BASE_ADDRESS; + u_int32_t d_RTC_WMAC_BASE_ADDRESS; + u_int32_t d_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_OFFSET; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_LSB; + u_int32_t d_WLAN_SYSTEM_SLEEP_DISABLE_MASK; + u_int32_t d_CLOCK_CONTROL_OFFSET; + u_int32_t d_CLOCK_CONTROL_SI0_CLK_MASK; + u_int32_t d_RESET_CONTROL_OFFSET; + u_int32_t d_RESET_CONTROL_MBOX_RST_MASK; + u_int32_t d_RESET_CONTROL_SI0_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_OFFSET; + u_int32_t d_WLAN_RESET_CONTROL_COLD_RST_MASK; + u_int32_t d_WLAN_RESET_CONTROL_WARM_RST_MASK; + u_int32_t d_GPIO_BASE_ADDRESS; + u_int32_t d_GPIO_PIN0_OFFSET; + u_int32_t d_GPIO_PIN1_OFFSET; + u_int32_t d_GPIO_PIN0_CONFIG_MASK; + u_int32_t d_GPIO_PIN1_CONFIG_MASK; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_LSB; + u_int32_t d_SI_CONFIG_BIDIR_OD_DATA_MASK; + u_int32_t d_SI_CONFIG_I2C_LSB; + u_int32_t d_SI_CONFIG_I2C_MASK; + u_int32_t d_SI_CONFIG_POS_SAMPLE_LSB; + u_int32_t d_SI_CONFIG_POS_SAMPLE_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_CLK_MASK; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_LSB; + u_int32_t d_SI_CONFIG_INACTIVE_DATA_MASK; + u_int32_t d_SI_CONFIG_DIVIDER_LSB; + u_int32_t d_SI_CONFIG_DIVIDER_MASK; + u_int32_t d_SI_BASE_ADDRESS; + u_int32_t d_SI_CONFIG_OFFSET; + u_int32_t d_SI_TX_DATA0_OFFSET; + u_int32_t d_SI_TX_DATA1_OFFSET; + u_int32_t d_SI_RX_DATA0_OFFSET; + u_int32_t d_SI_RX_DATA1_OFFSET; + u_int32_t d_SI_CS_OFFSET; + u_int32_t d_SI_CS_DONE_ERR_MASK; + u_int32_t d_SI_CS_DONE_INT_MASK; + u_int32_t d_SI_CS_START_LSB; + u_int32_t d_SI_CS_START_MASK; + u_int32_t d_SI_CS_RX_CNT_LSB; + u_int32_t d_SI_CS_RX_CNT_MASK; + u_int32_t d_SI_CS_TX_CNT_LSB; + u_int32_t d_SI_CS_TX_CNT_MASK; + u_int32_t d_BOARD_DATA_SZ; + u_int32_t d_BOARD_EXT_DATA_SZ; + u_int32_t d_MBOX_BASE_ADDRESS; + u_int32_t d_LOCAL_SCRATCH_OFFSET; + u_int32_t d_CPU_CLOCK_OFFSET; + u_int32_t d_LPO_CAL_OFFSET; + u_int32_t d_GPIO_PIN10_OFFSET; + u_int32_t d_GPIO_PIN11_OFFSET; + u_int32_t d_GPIO_PIN12_OFFSET; + u_int32_t d_GPIO_PIN13_OFFSET; + u_int32_t d_CLOCK_GPIO_OFFSET; + u_int32_t d_CPU_CLOCK_STANDARD_LSB; + u_int32_t d_CPU_CLOCK_STANDARD_MASK; + u_int32_t d_LPO_CAL_ENABLE_LSB; + u_int32_t d_LPO_CAL_ENABLE_MASK; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB; + u_int32_t d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK; + u_int32_t d_ANALOG_INTF_BASE_ADDRESS; + u_int32_t d_WLAN_MAC_BASE_ADDRESS; + u_int32_t d_CE0_BASE_ADDRESS; + u_int32_t d_CE1_BASE_ADDRESS; + u_int32_t d_FW_INDICATOR_ADDRESS; + u_int32_t d_DRAM_BASE_ADDRESS; + u_int32_t d_SOC_CORE_BASE_ADDRESS; + u_int32_t d_CORE_CTRL_ADDRESS; + u_int32_t d_CE_COUNT; + u_int32_t d_MSI_NUM_REQUEST; + u_int32_t d_MSI_ASSIGN_FW; + u_int32_t d_MSI_ASSIGN_CE_INITIAL; + u_int32_t d_PCIE_INTR_ENABLE_ADDRESS; + u_int32_t d_PCIE_INTR_CLR_ADDRESS; + u_int32_t d_PCIE_INTR_FIRMWARE_MASK; + u_int32_t d_PCIE_INTR_CE_MASK_ALL; + u_int32_t d_CORE_CTRL_CPU_INTR_MASK; + u_int32_t d_SR_WR_INDEX_ADDRESS; + u_int32_t d_DST_WATERMARK_ADDRESS; + + /* htt_rx.c */ + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_FIRST_MSDU_LSB; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_MASK; + u_int32_t d_RX_MPDU_START_0_SEQ_NUM_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_LSB; + u_int32_t d_RX_MPDU_START_2_PN_47_32_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK; + u_int32_t d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_MASK; + u_int32_t d_RX_MSDU_END_1_KEY_ID_OCT_LSB; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_MASK; + u_int32_t d_RX_MSDU_END_4_LAST_MSDU_LSB; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_MASK; + u_int32_t d_RX_ATTENTION_0_MCAST_BCAST_LSB; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_MASK; + u_int32_t d_RX_ATTENTION_0_FRAGMENT_LSB; + u_int32_t d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK; + u_int32_t d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_MASK; + u_int32_t d_RX_MSDU_START_0_MSDU_LENGTH_LSB; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_MASK; + u_int32_t d_RX_MSDU_START_2_DECAP_FORMAT_LSB; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_MASK; + u_int32_t d_RX_MPDU_START_0_ENCRYPTED_LSB; + u_int32_t d_RX_ATTENTION_0_MORE_DATA_MASK; + u_int32_t d_RX_ATTENTION_0_MSDU_DONE_MASK; + u_int32_t d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK; + /* end */ + /* copy_engine.c */ + u_int32_t d_DST_WR_INDEX_ADDRESS; + u_int32_t d_SRC_WATERMARK_ADDRESS; + u_int32_t d_SRC_WATERMARK_LOW_MASK; + u_int32_t d_SRC_WATERMARK_HIGH_MASK; + u_int32_t d_DST_WATERMARK_LOW_MASK; + u_int32_t d_DST_WATERMARK_HIGH_MASK; + u_int32_t d_CURRENT_SRRI_ADDRESS; + u_int32_t d_CURRENT_DRRI_ADDRESS; + u_int32_t d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK; + u_int32_t d_HOST_IS_DST_RING_LOW_WATERMARK_MASK; + u_int32_t d_HOST_IS_ADDRESS; + u_int32_t d_HOST_IS_COPY_COMPLETE_MASK; + u_int32_t d_CE_WRAPPER_BASE_ADDRESS; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS; + u_int32_t d_HOST_IE_ADDRESS; + u_int32_t d_HOST_IE_COPY_COMPLETE_MASK; + u_int32_t d_SR_BA_ADDRESS; + u_int32_t d_SR_SIZE_ADDRESS; + u_int32_t d_CE_CTRL1_ADDRESS; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_MASK; + u_int32_t d_DR_BA_ADDRESS; + u_int32_t d_DR_SIZE_ADDRESS; + u_int32_t d_MISC_IE_ADDRESS; + u_int32_t d_MISC_IS_AXI_ERR_MASK; + u_int32_t d_MISC_IS_DST_ADDR_ERR_MASK; + u_int32_t d_MISC_IS_SRC_LEN_ERR_MASK; + u_int32_t d_MISC_IS_DST_MAX_LEN_VIO_MASK; + u_int32_t d_MISC_IS_DST_RING_OVERFLOW_MASK; + u_int32_t d_MISC_IS_SRC_RING_OVERFLOW_MASK; + u_int32_t d_SRC_WATERMARK_LOW_LSB; + u_int32_t d_SRC_WATERMARK_HIGH_LSB; + u_int32_t d_DST_WATERMARK_LOW_LSB; + u_int32_t d_DST_WATERMARK_HIGH_LSB; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK; + u_int32_t d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB; + u_int32_t d_CE_CTRL1_DMAX_LENGTH_LSB; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK; + u_int32_t d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB; + u_int32_t d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB; + /* end */ + u_int32_t d_PCIE_INTR_CAUSE_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_ADDRESS; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK; + u_int32_t d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB; + u_int32_t d_SOC_RESET_CONTROL_CE_RST_MASK; + u_int32_t d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK; + u_int32_t d_CPU_INTR_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ADDRESS; + u_int32_t d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK; + /* chip id start */ + u_int32_t d_SOC_CHIP_ID_ADDRESS; + u_int32_t d_SOC_CHIP_ID_VERSION_MASK; + u_int32_t d_SOC_CHIP_ID_VERSION_LSB; + u_int32_t d_SOC_CHIP_ID_REVISION_MASK; + u_int32_t d_SOC_CHIP_ID_REVISION_LSB; + /* chip id end */ +} TARGET_REGISTER_TABLE; + +#define RTC_SOC_BASE_ADDRESS (sc->targetdef->d_RTC_SOC_BASE_ADDRESS) +#define RTC_WMAC_BASE_ADDRESS (sc->targetdef->d_RTC_WMAC_BASE_ADDRESS) +#define SYSTEM_SLEEP_OFFSET (sc->targetdef->d_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_OFFSET (sc->targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET) +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB) +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK (sc->targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define CLOCK_CONTROL_OFFSET (sc->targetdef->d_CLOCK_CONTROL_OFFSET) +#define CLOCK_CONTROL_SI0_CLK_MASK (sc->targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK) +#define RESET_CONTROL_OFFSET (sc->targetdef->d_RESET_CONTROL_OFFSET) +#define RESET_CONTROL_MBOX_RST_MASK (sc->targetdef->d_RESET_CONTROL_MBOX_RST_MASK) +#define RESET_CONTROL_SI0_RST_MASK (sc->targetdef->d_RESET_CONTROL_SI0_RST_MASK) +#define WLAN_RESET_CONTROL_OFFSET (sc->targetdef->d_WLAN_RESET_CONTROL_OFFSET) +#define WLAN_RESET_CONTROL_COLD_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_WARM_RST_MASK (sc->targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK) +#define GPIO_BASE_ADDRESS (sc->targetdef->d_GPIO_BASE_ADDRESS) +#define GPIO_PIN0_OFFSET (sc->targetdef->d_GPIO_PIN0_OFFSET) +#define GPIO_PIN1_OFFSET (sc->targetdef->d_GPIO_PIN1_OFFSET) +#define GPIO_PIN0_CONFIG_MASK (sc->targetdef->d_GPIO_PIN0_CONFIG_MASK) +#define GPIO_PIN1_CONFIG_MASK (sc->targetdef->d_GPIO_PIN1_CONFIG_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_LSB (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB) +#define SI_CONFIG_BIDIR_OD_DATA_MASK (sc->targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_LSB (sc->targetdef->d_SI_CONFIG_I2C_LSB) +#define SI_CONFIG_I2C_MASK (sc->targetdef->d_SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_LSB (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_LSB) +#define SI_CONFIG_POS_SAMPLE_MASK (sc->targetdef->d_SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB) +#define SI_CONFIG_INACTIVE_CLK_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_LSB (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB) +#define SI_CONFIG_INACTIVE_DATA_MASK (sc->targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_LSB (sc->targetdef->d_SI_CONFIG_DIVIDER_LSB) +#define SI_CONFIG_DIVIDER_MASK (sc->targetdef->d_SI_CONFIG_DIVIDER_MASK) +#define SI_BASE_ADDRESS (sc->targetdef->d_SI_BASE_ADDRESS) +#define SI_CONFIG_OFFSET (sc->targetdef->d_SI_CONFIG_OFFSET) +#define SI_TX_DATA0_OFFSET (sc->targetdef->d_SI_TX_DATA0_OFFSET) +#define SI_TX_DATA1_OFFSET (sc->targetdef->d_SI_TX_DATA1_OFFSET) +#define SI_RX_DATA0_OFFSET (sc->targetdef->d_SI_RX_DATA0_OFFSET) +#define SI_RX_DATA1_OFFSET (sc->targetdef->d_SI_RX_DATA1_OFFSET) +#define SI_CS_OFFSET (sc->targetdef->d_SI_CS_OFFSET) +#define SI_CS_DONE_ERR_MASK (sc->targetdef->d_SI_CS_DONE_ERR_MASK) +#define SI_CS_DONE_INT_MASK (sc->targetdef->d_SI_CS_DONE_INT_MASK) +#define SI_CS_START_LSB (sc->targetdef->d_SI_CS_START_LSB) +#define SI_CS_START_MASK (sc->targetdef->d_SI_CS_START_MASK) +#define SI_CS_RX_CNT_LSB (sc->targetdef->d_SI_CS_RX_CNT_LSB) +#define SI_CS_RX_CNT_MASK (sc->targetdef->d_SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_LSB (sc->targetdef->d_SI_CS_TX_CNT_LSB) +#define SI_CS_TX_CNT_MASK (sc->targetdef->d_SI_CS_TX_CNT_MASK) +#define EEPROM_SZ (sc->targetdef->d_BOARD_DATA_SZ) +#define EEPROM_EXT_SZ (sc->targetdef->d_BOARD_EXT_DATA_SZ) +#define MBOX_BASE_ADDRESS (sc->targetdef->d_MBOX_BASE_ADDRESS) +#define LOCAL_SCRATCH_OFFSET (sc->targetdef->d_LOCAL_SCRATCH_OFFSET) +#define CPU_CLOCK_OFFSET (sc->targetdef->d_CPU_CLOCK_OFFSET) +#define LPO_CAL_OFFSET (sc->targetdef->d_LPO_CAL_OFFSET) +#define GPIO_PIN10_OFFSET (sc->targetdef->d_GPIO_PIN10_OFFSET) +#define GPIO_PIN11_OFFSET (sc->targetdef->d_GPIO_PIN11_OFFSET) +#define GPIO_PIN12_OFFSET (sc->targetdef->d_GPIO_PIN12_OFFSET) +#define GPIO_PIN13_OFFSET (sc->targetdef->d_GPIO_PIN13_OFFSET) +#define CLOCK_GPIO_OFFSET (sc->targetdef->d_CLOCK_GPIO_OFFSET) +#define CPU_CLOCK_STANDARD_LSB (sc->targetdef->d_CPU_CLOCK_STANDARD_LSB) +#define CPU_CLOCK_STANDARD_MASK (sc->targetdef->d_CPU_CLOCK_STANDARD_MASK) +#define LPO_CAL_ENABLE_LSB (sc->targetdef->d_LPO_CAL_ENABLE_LSB) +#define LPO_CAL_ENABLE_MASK (sc->targetdef->d_LPO_CAL_ENABLE_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB) +#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK (sc->targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +#define ANALOG_INTF_BASE_ADDRESS (sc->targetdef->d_ANALOG_INTF_BASE_ADDRESS) +#define WLAN_MAC_BASE_ADDRESS (sc->targetdef->d_WLAN_MAC_BASE_ADDRESS) +#define CE0_BASE_ADDRESS (sc->targetdef->d_CE0_BASE_ADDRESS) +#define CE1_BASE_ADDRESS (sc->targetdef->d_CE1_BASE_ADDRESS) +#define FW_INDICATOR_ADDRESS (sc->targetdef->d_FW_INDICATOR_ADDRESS) +#define DRAM_BASE_ADDRESS (sc->targetdef->d_DRAM_BASE_ADDRESS) +#define SOC_CORE_BASE_ADDRESS (sc->targetdef->d_SOC_CORE_BASE_ADDRESS) +#define CORE_CTRL_ADDRESS (sc->targetdef->d_CORE_CTRL_ADDRESS) +#define CE_COUNT (sc->targetdef->d_CE_COUNT) +#define PCIE_INTR_ENABLE_ADDRESS (sc->targetdef->d_PCIE_INTR_ENABLE_ADDRESS) +#define PCIE_INTR_CLR_ADDRESS (sc->targetdef->d_PCIE_INTR_CLR_ADDRESS) +#define PCIE_INTR_FIRMWARE_MASK (sc->targetdef->d_PCIE_INTR_FIRMWARE_MASK) +#define PCIE_INTR_CE_MASK_ALL (sc->targetdef->d_PCIE_INTR_CE_MASK_ALL) +#define CORE_CTRL_CPU_INTR_MASK (sc->targetdef->d_CORE_CTRL_CPU_INTR_MASK) +#define PCIE_INTR_CAUSE_ADDRESS (sc->targetdef->d_PCIE_INTR_CAUSE_ADDRESS) +#define SOC_RESET_CONTROL_ADDRESS (sc->targetdef->d_SOC_RESET_CONTROL_ADDRESS) +#define SOC_RESET_CONTROL_CE_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CE_RST_MASK) +#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK (sc->targetdef->d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK) +#define CPU_INTR_ADDRESS (sc->targetdef->d_CPU_INTR_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ADDRESS (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ADDRESS) +#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK (sc->targetdef->d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB (sc->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK (sc->targetdef->d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_GET(x) (((x) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) >> SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) +#define SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_SET(x) (((x) << SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB) & SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK) + +/* hif_pci.c */ +#define CHIP_ID_ADDRESS (sc->targetdef->d_SOC_CHIP_ID_ADDRESS) +#define SOC_CHIP_ID_REVISION_MASK (sc->targetdef->d_SOC_CHIP_ID_REVISION_MASK) +#define SOC_CHIP_ID_REVISION_LSB (sc->targetdef->d_SOC_CHIP_ID_REVISION_LSB) +#define SOC_CHIP_ID_VERSION_MASK (sc->targetdef->d_SOC_CHIP_ID_VERSION_MASK) +#define SOC_CHIP_ID_VERSION_LSB (sc->targetdef->d_SOC_CHIP_ID_VERSION_LSB) +#define CHIP_ID_REVISION_GET(x) (((x) & SOC_CHIP_ID_REVISION_MASK) >> SOC_CHIP_ID_REVISION_LSB) +#define CHIP_ID_VERSION_GET(x) (((x) & SOC_CHIP_ID_VERSION_MASK) >> SOC_CHIP_ID_VERSION_LSB) +/* hif_pci.c end */ + +/* misc */ +#define SR_WR_INDEX_ADDRESS (sc->targetdef->d_SR_WR_INDEX_ADDRESS) +#define DST_WATERMARK_ADDRESS (sc->targetdef->d_DST_WATERMARK_ADDRESS) +/* end */ + +/* htt_rx.c */ +#define RX_MSDU_END_4_FIRST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_MASK) +#define RX_MSDU_END_4_FIRST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_FIRST_MSDU_LSB) +#define RX_MPDU_START_0_SEQ_NUM_MASK (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_MASK) +#define RX_MPDU_START_0_SEQ_NUM_LSB (pdev->targetdef->d_RX_MPDU_START_0_SEQ_NUM_LSB) +#define RX_MPDU_START_2_PN_47_32_LSB (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_LSB) +#define RX_MPDU_START_2_PN_47_32_MASK (pdev->targetdef->d_RX_MPDU_START_2_PN_47_32_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_MASK (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_MASK) +#define RX_MSDU_END_1_KEY_ID_OCT_LSB (pdev->targetdef->d_RX_MSDU_END_1_KEY_ID_OCT_LSB) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK) +#define RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB (pdev->targetdef->d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB) +#define RX_MSDU_END_4_LAST_MSDU_MASK (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_MASK) +#define RX_MSDU_END_4_LAST_MSDU_LSB (pdev->targetdef->d_RX_MSDU_END_4_LAST_MSDU_LSB) +#define RX_ATTENTION_0_MCAST_BCAST_MASK (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_MASK) +#define RX_ATTENTION_0_MCAST_BCAST_LSB (pdev->targetdef->d_RX_ATTENTION_0_MCAST_BCAST_LSB) +#define RX_ATTENTION_0_FRAGMENT_MASK (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_MASK) +#define RX_ATTENTION_0_FRAGMENT_LSB (pdev->targetdef->d_RX_ATTENTION_0_FRAGMENT_LSB) +#define RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK (pdev->targetdef->d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK) +#define RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB (pdev->targetdef->d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB) +#define RX_MSDU_START_0_MSDU_LENGTH_MASK (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_MASK) +#define RX_MSDU_START_0_MSDU_LENGTH_LSB (pdev->targetdef->d_RX_MSDU_START_0_MSDU_LENGTH_LSB) +#define RX_MSDU_START_2_DECAP_FORMAT_OFFSET (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET) +#define RX_MSDU_START_2_DECAP_FORMAT_MASK (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_MASK) +#define RX_MSDU_START_2_DECAP_FORMAT_LSB (pdev->targetdef->d_RX_MSDU_START_2_DECAP_FORMAT_LSB) +#define RX_MPDU_START_0_ENCRYPTED_MASK (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_MASK) +#define RX_MPDU_START_0_ENCRYPTED_LSB (pdev->targetdef->d_RX_MPDU_START_0_ENCRYPTED_LSB) +#define RX_ATTENTION_0_MORE_DATA_MASK (pdev->targetdef->d_RX_ATTENTION_0_MORE_DATA_MASK) +#define RX_ATTENTION_0_MSDU_DONE_MASK (pdev->targetdef->d_RX_ATTENTION_0_MSDU_DONE_MASK) +#define RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK (pdev->targetdef->d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK) +/* end */ + +/* copy_engine.c */ +#define DST_WR_INDEX_ADDRESS (sc->targetdef->d_DST_WR_INDEX_ADDRESS) +#define SRC_WATERMARK_ADDRESS (sc->targetdef->d_SRC_WATERMARK_ADDRESS) +#define SRC_WATERMARK_LOW_MASK (sc->targetdef->d_SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_MASK (sc->targetdef->d_SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_MASK (sc->targetdef->d_DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_MASK (sc->targetdef->d_DST_WATERMARK_HIGH_MASK) +#define CURRENT_SRRI_ADDRESS (sc->targetdef->d_CURRENT_SRRI_ADDRESS) +#define CURRENT_DRRI_ADDRESS (sc->targetdef->d_CURRENT_DRRI_ADDRESS) +#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK) +#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK) +#define HOST_IS_DST_RING_LOW_WATERMARK_MASK (sc->targetdef->d_HOST_IS_DST_RING_LOW_WATERMARK_MASK) +#define HOST_IS_ADDRESS (sc->targetdef->d_HOST_IS_ADDRESS) +#define HOST_IS_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IS_COPY_COMPLETE_MASK) +#define CE_WRAPPER_BASE_ADDRESS (sc->targetdef->d_CE_WRAPPER_BASE_ADDRESS) +#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS) +#define HOST_IE_ADDRESS (sc->targetdef->d_HOST_IE_ADDRESS) +#define HOST_IE_COPY_COMPLETE_MASK (sc->targetdef->d_HOST_IE_COPY_COMPLETE_MASK) +#define SR_BA_ADDRESS (sc->targetdef->d_SR_BA_ADDRESS) +#define SR_SIZE_ADDRESS (sc->targetdef->d_SR_SIZE_ADDRESS) +#define CE_CTRL1_ADDRESS (sc->targetdef->d_CE_CTRL1_ADDRESS) +#define CE_CTRL1_DMAX_LENGTH_MASK (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_MASK) +#define DR_BA_ADDRESS (sc->targetdef->d_DR_BA_ADDRESS) +#define DR_SIZE_ADDRESS (sc->targetdef->d_DR_SIZE_ADDRESS) +#define MISC_IE_ADDRESS (sc->targetdef->d_MISC_IE_ADDRESS) +#define MISC_IS_AXI_ERR_MASK (sc->targetdef->d_MISC_IS_AXI_ERR_MASK) +#define MISC_IS_DST_ADDR_ERR_MASK (sc->targetdef->d_MISC_IS_DST_ADDR_ERR_MASK) +#define MISC_IS_SRC_LEN_ERR_MASK (sc->targetdef->d_MISC_IS_SRC_LEN_ERR_MASK) +#define MISC_IS_DST_MAX_LEN_VIO_MASK (sc->targetdef->d_MISC_IS_DST_MAX_LEN_VIO_MASK) +#define MISC_IS_DST_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_DST_RING_OVERFLOW_MASK) +#define MISC_IS_SRC_RING_OVERFLOW_MASK (sc->targetdef->d_MISC_IS_SRC_RING_OVERFLOW_MASK) +#define SRC_WATERMARK_LOW_LSB (sc->targetdef->d_SRC_WATERMARK_LOW_LSB) +#define SRC_WATERMARK_HIGH_LSB (sc->targetdef->d_SRC_WATERMARK_HIGH_LSB) +#define DST_WATERMARK_LOW_LSB (sc->targetdef->d_DST_WATERMARK_LOW_LSB) +#define DST_WATERMARK_HIGH_LSB (sc->targetdef->d_DST_WATERMARK_HIGH_LSB) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB (sc->targetdef->d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_LSB (sc->targetdef->d_CE_CTRL1_DMAX_LENGTH_LSB) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB (sc->targetdef->d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) +/* end */ + +/* SET macros */ +#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK) +#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK) +#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK) +#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK) +#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK) +#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) +/* copy_engine.c */ +#define SRC_WATERMARK_LOW_SET(x) (((x) << SRC_WATERMARK_LOW_LSB) & SRC_WATERMARK_LOW_MASK) +#define SRC_WATERMARK_HIGH_SET(x) (((x) << SRC_WATERMARK_HIGH_LSB) & SRC_WATERMARK_HIGH_MASK) +#define DST_WATERMARK_LOW_SET(x) (((x) << DST_WATERMARK_LOW_LSB) & DST_WATERMARK_LOW_MASK) +#define DST_WATERMARK_HIGH_SET(x) (((x) << DST_WATERMARK_HIGH_LSB) & DST_WATERMARK_HIGH_MASK) +#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) (((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) +#define CE_CTRL1_DMAX_LENGTH_SET(x) (((x) << CE_CTRL1_DMAX_LENGTH_LSB) & CE_CTRL1_DMAX_LENGTH_MASK) +#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) +#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(x) (((x) << CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) & CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) +/* end */ + +typedef struct hostdef_s { + A_UINT32 d_INT_STATUS_ENABLE_ERROR_LSB; + A_UINT32 d_INT_STATUS_ENABLE_ERROR_MASK; + A_UINT32 d_INT_STATUS_ENABLE_CPU_LSB; + A_UINT32 d_INT_STATUS_ENABLE_CPU_MASK; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_LSB; + A_UINT32 d_INT_STATUS_ENABLE_COUNTER_MASK; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_LSB; + A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB; + A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_INT_STATUS_ENABLE_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_LSB; + A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_MASK; + A_UINT32 d_HOST_INT_STATUS_ADDRESS; + A_UINT32 d_CPU_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_ADDRESS; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_MASK; + A_UINT32 d_ERROR_INT_STATUS_WAKEUP_LSB; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_MASK; + A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_LSB; + A_UINT32 d_COUNT_DEC_ADDRESS; + A_UINT32 d_HOST_INT_STATUS_CPU_MASK; + A_UINT32 d_HOST_INT_STATUS_CPU_LSB; + A_UINT32 d_HOST_INT_STATUS_ERROR_MASK; + A_UINT32 d_HOST_INT_STATUS_ERROR_LSB; + A_UINT32 d_HOST_INT_STATUS_COUNTER_MASK; + A_UINT32 d_HOST_INT_STATUS_COUNTER_LSB; + A_UINT32 d_RX_LOOKAHEAD_VALID_ADDRESS; + A_UINT32 d_WINDOW_DATA_ADDRESS; + A_UINT32 d_WINDOW_READ_ADDR_ADDRESS; + A_UINT32 d_WINDOW_WRITE_ADDR_ADDRESS; + A_UINT32 d_SOC_GLOBAL_RESET_ADDRESS; + A_UINT32 d_RTC_STATE_ADDRESS; + A_UINT32 d_RTC_STATE_COLD_RESET_MASK; + A_UINT32 d_PCIE_LOCAL_BASE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_RESET; + A_UINT32 d_PCIE_SOC_WAKE_ADDRESS; + A_UINT32 d_PCIE_SOC_WAKE_V_MASK; + A_UINT32 d_RTC_STATE_V_MASK; + A_UINT32 d_RTC_STATE_V_LSB; + A_UINT32 d_FW_IND_EVENT_PENDING; + A_UINT32 d_FW_IND_INITIALIZED; + A_UINT32 d_RTC_STATE_V_ON; +#if defined(SDIO_3_0) + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_MASK; + A_UINT32 d_HOST_INT_STATUS_MBOX_DATA_LSB; +#endif + A_UINT32 d_PCIE_SOC_RDY_STATUS_ADDRESS; + A_UINT32 d_PCIE_SOC_RDY_STATUS_BAR_MASK; + A_UINT32 d_SOC_PCIE_BASE_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADR_ADDRESS; + A_UINT32 d_MSI_MAGIC_ADDRESS; +} HOST_REGISTER_TABLE; + +#define INT_STATUS_ENABLE_ERROR_LSB (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_LSB) +#define INT_STATUS_ENABLE_ERROR_MASK (sc->hostdef->d_INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_LSB (sc->hostdef->d_INT_STATUS_ENABLE_CPU_LSB) +#define INT_STATUS_ENABLE_CPU_MASK (sc->hostdef->d_INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_LSB (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB) +#define INT_STATUS_ENABLE_COUNTER_MASK (sc->hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_LSB (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB) +#define INT_STATUS_ENABLE_MBOX_DATA_MASK (sc->hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB) +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define INT_STATUS_ENABLE_ADDRESS (sc->hostdef->d_INT_STATUS_ENABLE_ADDRESS) +#define CPU_INT_STATUS_ENABLE_BIT_LSB (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB) +#define CPU_INT_STATUS_ENABLE_BIT_MASK (sc->hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK) +#define HOST_INT_STATUS_ADDRESS (sc->hostdef->d_HOST_INT_STATUS_ADDRESS) +#define CPU_INT_STATUS_ADDRESS (sc->hostdef->d_CPU_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_ADDRESS (sc->hostdef->d_ERROR_INT_STATUS_ADDRESS) +#define ERROR_INT_STATUS_WAKEUP_MASK (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK) +#define ERROR_INT_STATUS_WAKEUP_LSB (sc->hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK) +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK) +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB (sc->hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define COUNT_DEC_ADDRESS (sc->hostdef->d_COUNT_DEC_ADDRESS) +#define HOST_INT_STATUS_CPU_MASK (sc->hostdef->d_HOST_INT_STATUS_CPU_MASK) +#define HOST_INT_STATUS_CPU_LSB (sc->hostdef->d_HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_MASK (sc->hostdef->d_HOST_INT_STATUS_ERROR_MASK) +#define HOST_INT_STATUS_ERROR_LSB (sc->hostdef->d_HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_MASK (sc->hostdef->d_HOST_INT_STATUS_COUNTER_MASK) +#define HOST_INT_STATUS_COUNTER_LSB (sc->hostdef->d_HOST_INT_STATUS_COUNTER_LSB) +#define RX_LOOKAHEAD_VALID_ADDRESS (sc->hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS) +#define WINDOW_DATA_ADDRESS (sc->hostdef->d_WINDOW_DATA_ADDRESS) +#define WINDOW_READ_ADDR_ADDRESS (sc->hostdef->d_WINDOW_READ_ADDR_ADDRESS) +#define WINDOW_WRITE_ADDR_ADDRESS (sc->hostdef->d_WINDOW_WRITE_ADDR_ADDRESS) +#define SOC_GLOBAL_RESET_ADDRESS (sc->hostdef->d_SOC_GLOBAL_RESET_ADDRESS) +#define RTC_STATE_ADDRESS (sc->hostdef->d_RTC_STATE_ADDRESS) +#define RTC_STATE_COLD_RESET_MASK (sc->hostdef->d_RTC_STATE_COLD_RESET_MASK) +#define PCIE_LOCAL_BASE_ADDRESS (sc->hostdef->d_PCIE_LOCAL_BASE_ADDRESS) +#define PCIE_SOC_WAKE_RESET (sc->hostdef->d_PCIE_SOC_WAKE_RESET) +#define PCIE_SOC_WAKE_ADDRESS (sc->hostdef->d_PCIE_SOC_WAKE_ADDRESS) +#define PCIE_SOC_WAKE_V_MASK (sc->hostdef->d_PCIE_SOC_WAKE_V_MASK) +#define RTC_STATE_V_MASK (sc->hostdef->d_RTC_STATE_V_MASK) +#define RTC_STATE_V_LSB (sc->hostdef->d_RTC_STATE_V_LSB) +#define FW_IND_EVENT_PENDING (sc->hostdef->d_FW_IND_EVENT_PENDING) +#define FW_IND_INITIALIZED (sc->hostdef->d_FW_IND_INITIALIZED) +#define RTC_STATE_V_ON (sc->hostdef->d_RTC_STATE_V_ON) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_MASK (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_MASK) +#define HOST_INT_STATUS_MBOX_DATA_LSB (sc->hostdef->d_HOST_INT_STATUS_MBOX_DATA_LSB) +#endif + +#if !defined(SOC_PCIE_BASE_ADDRESS) +#define SOC_PCIE_BASE_ADDRESS 0 +#endif + +#if !defined(PCIE_SOC_RDY_STATUS_ADDRESS) +#define PCIE_SOC_RDY_STATUS_ADDRESS 0 +#define PCIE_SOC_RDY_STATUS_BAR_MASK 0 +#endif + +#if !defined(MSI_MAGIC_ADR_ADDRESS) +#define MSI_MAGIC_ADR_ADDRESS 0 +#define MSI_MAGIC_ADDRESS 0 +#endif + +/* SET/GET macros */ +#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) +#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) +#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) +#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) +#define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB) +#if defined(SDIO_3_0) +#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB) +#endif +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc.c new file mode 100644 index 0000000000000..1c74c6c3f2e26 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc.c @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2013, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include "ol_if_athvar.h" +#include "htc_debug.h" +#include "htc_internal.h" +#include /* adf_nbuf_t */ +#include /* adf_os_print */ +#include /* HIFFlushSurpriseRemove */ +#include +#include "epping_main.h" + +#ifdef DEBUG +static ATH_DEBUG_MASK_DESCRIPTION g_HTCDebugDescription[] = { + { ATH_DEBUG_SEND , "Send"}, + { ATH_DEBUG_RECV , "Recv"}, + { ATH_DEBUG_SYNC , "Sync"}, + { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"}, + { ATH_DEBUG_SETUP, "Setup"}, +}; + + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, + "htc", + "Host Target Communications", + ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO | ATH_DEBUG_SETUP, + ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription), + g_HTCDebugDescription); + +#endif + +extern unsigned int htc_credit_flow; + +static void ResetEndpointStates(HTC_TARGET *target); + +static void DestroyHTCTxCtrlPacket(HTC_PACKET *pPacket) +{ + adf_nbuf_t netbuf; + netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("free ctrl netbuf :0x%p \n", netbuf)); + if (netbuf != NULL) { + adf_nbuf_free(netbuf); + } + + A_FREE(pPacket); +} + + +static HTC_PACKET *BuildHTCTxCtrlPacket(adf_os_device_t osdev) +{ + HTC_PACKET *pPacket = NULL; + adf_nbuf_t netbuf; + + do { + pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); + if (NULL == pPacket) { + break; + } + A_MEMZERO(pPacket,sizeof(HTC_PACKET)); + netbuf = adf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, TRUE); + if (NULL == netbuf) { + A_FREE(pPacket); + pPacket = NULL; + adf_os_print("%s: nbuf alloc failed\n",__func__); + break; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("alloc ctrl netbuf :0x%p \n", netbuf)); + SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf); + } while (FALSE); + + return pPacket; +} + +void HTCFreeControlTxPacket(HTC_TARGET *target, HTC_PACKET *pPacket) +{ + +#ifdef TODO_FIXME + LOCK_HTC(target); + HTC_PACKET_ENQUEUE(&target->ControlBufferTXFreeList,pPacket); + UNLOCK_HTC(target); + /* TODO_FIXME netbufs cannot be RESET! */ +#else + DestroyHTCTxCtrlPacket(pPacket); +#endif + +} + +HTC_PACKET *HTCAllocControlTxPacket(HTC_TARGET *target) +{ +#ifdef TODO_FIXME + HTC_PACKET *pPacket; + + LOCK_HTC(target); + pPacket = HTC_PACKET_DEQUEUE(&target->ControlBufferTXFreeList); + UNLOCK_HTC(target); + + return pPacket; +#else + return BuildHTCTxCtrlPacket(target->osdev); +#endif +} + +/* Set the target failure handling callback */ +void HTCSetTargetFailureCallback(HTC_HANDLE HTCHandle, HTC_TARGET_FAILURE Callback) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + target->HTCInitInfo.TargetFailure = Callback; +} + +void HTCDump(HTC_HANDLE HTCHandle, u_int8_t CmdId, bool start) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HIFDump(target->hif_dev, CmdId, start); +} + +/* cleanup the HTC instance */ +static void HTCCleanup(HTC_TARGET *target) +{ + HTC_PACKET *pPacket; + //adf_nbuf_t netbuf; + + if (target->hif_dev != NULL) { + HIFDetachHTC(target->hif_dev); + target->hif_dev = NULL; + } + + while (TRUE) { + pPacket = AllocateHTCPacketContainer(target); + if (NULL == pPacket) { + break; + } + A_FREE(pPacket); + } + + pPacket = target->pBundleFreeList; + while (pPacket) { + HTC_PACKET *pPacketTmp = (HTC_PACKET *)pPacket->ListLink.pNext; + A_FREE(pPacket); + pPacket = pPacketTmp; + } +#ifdef TODO_FIXME + while (TRUE) { + pPacket = HTCAllocControlTxPacket(target); + if (NULL == pPacket) { + break; + } + netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + if (netbuf != NULL) { + adf_nbuf_free(netbuf); + } + + A_FREE(pPacket); + } +#endif + + adf_os_spinlock_destroy(&target->HTCLock); + adf_os_spinlock_destroy(&target->HTCRxLock); + adf_os_spinlock_destroy(&target->HTCTxLock); + adf_os_spinlock_destroy(&target->HTCCreditLock); + + /* free our instance */ + A_FREE(target); +} + +/* registered target arrival callback from the HIF layer */ +HTC_HANDLE HTCCreate(void *ol_sc, HTC_INIT_INFO *pInfo, adf_os_device_t osdev) +{ + hif_handle_t hHIF = ((struct ol_softc *)ol_sc)->hif_hdl; + MSG_BASED_HIF_CALLBACKS htcCallbacks; + HTC_ENDPOINT *pEndpoint=NULL; + HTC_TARGET *target = NULL; + int i; + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("+HTCCreate .. HIF :%p \n",hHIF)); + + A_REGISTER_MODULE_DEBUG_INFO(htc); + + if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n")); + return NULL; + } + + A_MEMZERO(target, sizeof(HTC_TARGET)); + + adf_os_spinlock_init(&target->HTCLock); + adf_os_spinlock_init(&target->HTCRxLock); + adf_os_spinlock_init(&target->HTCTxLock); + adf_os_spinlock_init(&target->HTCCreditLock); + + do { + A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); + target->host_handle = pInfo->pContext; + target->osdev = osdev; + + ResetEndpointStates(target); + + INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList); + + for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) { + HTC_PACKET *pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); + if (pPacket != NULL) { + A_MEMZERO(pPacket,sizeof(HTC_PACKET)); + FreeHTCPacketContainer(target,pPacket); + } + } + +#ifdef TODO_FIXME + for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) { + pPacket = BuildHTCTxCtrlPacket(); + if (NULL == pPacket) { + break; + } + HTCFreeControlTxPacket(target,pPacket); + } +#endif + + /* setup HIF layer callbacks */ + A_MEMZERO(&htcCallbacks, sizeof(MSG_BASED_HIF_CALLBACKS)); + htcCallbacks.Context = target; + htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler; + htcCallbacks.txCompletionHandler = HTCTxCompletionHandler; + htcCallbacks.txResourceAvailHandler = HTCTxResourceAvailHandler; + htcCallbacks.fwEventHandler = HTCFwEventHandler; + target->hif_dev = hHIF; + + /* Get HIF default pipe for HTC message exchange */ + pEndpoint = &target->EndPoint[ENDPOINT_0]; + + HIFPostInit(hHIF, target, &htcCallbacks); + HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID); + + } while (FALSE); + + HTCRecvInit(target); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("-HTCCreate (0x%p) \n", target)); + + return (HTC_HANDLE)target; +} + +void HTCDestroy(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%p \n",target)); + HTCCleanup(target); + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n")); +} + +/* get the low level HIF device for the caller , the caller may wish to do low level + * HIF requests */ +void *HTCGetHifDevice(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + return target->hif_dev; +} + +void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket) +{ + HTC_TARGET *target = (HTC_TARGET *)Context; + AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+-HTCControlTxComplete 0x%p (l:%d) \n",pPacket,pPacket->ActualLength)); + HTCFreeControlTxPacket(target,pPacket); +} + +/* TODO, this is just a temporary max packet size */ +#define MAX_MESSAGE_SIZE 1536 + +A_STATUS HTCSetupTargetBufferAssignments(HTC_TARGET *target) +{ + HTC_SERVICE_TX_CREDIT_ALLOCATION *pEntry; + A_STATUS status; + int credits; + int creditsPerMaxMsg; +#ifdef HIF_USB + unsigned int hif_usbaudioclass=0; +#else + unsigned int hif_usbaudioclass=0; +#endif + + creditsPerMaxMsg = MAX_MESSAGE_SIZE / target->TargetCreditSize; + if (MAX_MESSAGE_SIZE % target->TargetCreditSize) { + creditsPerMaxMsg++; + } + + /* TODO, this should be configured by the caller! */ + + credits = target->TotalTransmitCredits; + pEntry = &target->ServiceTxAllocTable[0]; +#if defined(HIF_USB) + target->avail_tx_credits = target->TotalTransmitCredits - 1 ; +#endif +#if !(defined(HIF_PCI) || defined(HIF_SIM) || defined(CONFIG_HL_SUPPORT) || (defined(HIF_USB))) + status = A_NO_RESOURCE; +#endif + +#if defined(HIF_PCI) || defined(HIF_SIM) || (defined(CONFIG_HL_SUPPORT) && !defined(AR6004_HW))/* TODO: maybe change to HIF_SDIO later */ + /* TODO: maybe check ROME service for USB service */ + /* + * for PCIE allocate all credists/HTC buffers to WMI. + * no buffers are used/required for data. data always + * remains on host. + */ + hif_usbaudioclass = 0; /* to keep compiler happy */ + /* for PCIE allocate all credits to wmi for now */ + status = A_OK; + pEntry++; + pEntry->ServiceID = WMI_CONTROL_SVC; + pEntry->CreditAllocation = credits; + + if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) { + /* endpoint ping is a testing tool directly on top of HTC in + * both target and host sides. + * In target side, the endppint ping fw has no wlan stack and the + * FW mboxping app directly sits on HTC and it simply drops + * or loops back TX packets. For rx perf, FW mboxping app + * generates packets and passes packets to HTC to send to host. + * There is no WMI mesage exchanges between host and target + * in endpoint ping case. + * In host side, the endpoint ping driver is a Ethernet driver + * and it directly sits on HTC. Only HIF, HTC, VOSS, ADF are + * used by the endpoint ping driver. There is no wifi stack + * at all in host side also. For tx perf use case, + * the user space mboxping app sends the raw packets to endpoint + * ping driver and it directly forwards to HTC for transmission + * to stress the bus. For the rx perf, HTC passes the received + * packets to endpoint ping driver and it is passed to the user + * space through the Ethernet interface. + * For credit allocation, in SDIO bus case, only BE service is + * used for tx/rx perf testing so that all credits are given + * to BE service. In PCIe and USB bus case, endpoint ping uses both + * BE and BK services to stress the bus so that the total credits + * are equally distributed to BE and BK services. + */ +#if !defined(HIF_USB) + pEntry++; + pEntry->ServiceID = WMI_DATA_BE_SVC; + pEntry->CreditAllocation = credits; +#endif + #if defined(HIF_PCI) || defined(HIF_USB) + pEntry->ServiceID = WMI_DATA_BE_SVC; + pEntry->CreditAllocation = (credits >> 1); + + pEntry++; + pEntry->ServiceID = WMI_DATA_BK_SVC; + pEntry->CreditAllocation = (credits >> 1); + #endif + } + +#else + do { + + if(hif_usbaudioclass) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HTCSetupTargetBufferAssignments For USB Audio Class- Total:%d\n",credits)); + pEntry++; + pEntry++; + //Setup VO Service To have Max Credits + pEntry->ServiceID = WMI_DATA_VO_SVC; + pEntry->CreditAllocation = (credits -6); + if (pEntry->CreditAllocation == 0) { + pEntry->CreditAllocation++; + } + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + pEntry++; + pEntry->ServiceID = WMI_CONTROL_SVC; + pEntry->CreditAllocation = creditsPerMaxMsg; + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + /* + * HTT_DATA_MSG_SVG is unidirectional from target -> host, + * so no target buffers are needed. + */ + /* leftovers go to best effort */ + pEntry++; + pEntry++; + pEntry->ServiceID = WMI_DATA_BE_SVC; + pEntry->CreditAllocation = (A_UINT8)credits; + status = A_OK; + break; + } + + pEntry++; + pEntry->ServiceID = WMI_DATA_VI_SVC; + pEntry->CreditAllocation = credits / 4; + if (pEntry->CreditAllocation == 0) { + pEntry->CreditAllocation++; + } + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + pEntry++; + pEntry->ServiceID = WMI_DATA_VO_SVC; + pEntry->CreditAllocation = credits / 4; + if (pEntry->CreditAllocation == 0) { + pEntry->CreditAllocation++; + } + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + pEntry++; + pEntry->ServiceID = WMI_CONTROL_SVC; + pEntry->CreditAllocation = creditsPerMaxMsg; + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + /* + * HTT_DATA_MSG_SVG is unidirectional from target -> host, + * so no target buffers are needed. + */ + pEntry++; + pEntry->ServiceID = WMI_DATA_BK_SVC; + pEntry->CreditAllocation = creditsPerMaxMsg; + credits -= (int)pEntry->CreditAllocation; + if (credits <= 0) { + break; + } + /* leftovers go to best effort */ + pEntry++; + pEntry->ServiceID = WMI_DATA_BE_SVC; + pEntry->CreditAllocation = (A_UINT8)credits; + status = A_OK; + + } while (FALSE); + +#endif + + if (A_SUCCESS(status)) { + int i; + for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) { + if (target->ServiceTxAllocTable[i].ServiceID != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_INIT,("HTC Service Index : %d TX : 0x%2.2X : alloc:%d \n", + i, + target->ServiceTxAllocTable[i].ServiceID, + target->ServiceTxAllocTable[i].CreditAllocation)); + } + } + } + + return status; +} + +A_UINT8 HTCGetCreditAllocation(HTC_TARGET *target, A_UINT16 ServiceID) +{ + A_UINT8 allocation = 0; + int i; + + for (i = 0; i < HTC_MAX_SERVICE_ALLOC_ENTRIES; i++) { + if (target->ServiceTxAllocTable[i].ServiceID == ServiceID) { + allocation = target->ServiceTxAllocTable[i].CreditAllocation; + } + } + + if (0 == allocation) { + AR_DEBUG_PRINTF(ATH_DEBUG_INIT,("HTC Service TX : 0x%2.2X : allocation is zero! \n",ServiceID)); + } + + return allocation; +} + + +A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) +{ + A_STATUS status = A_OK; + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_READY_EX_MSG *pReadyMsg; + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP resp; + HTC_READY_MSG *rdy_msg; + A_UINT16 htc_rdy_msg_id; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%p) \n", HTCHandle)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n")); + + do { + + status = HIFStart(target->hif_dev); + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIFStart failed\n")); + break; + } + + status = HTCWaitRecvCtrlMessage(target); + + if (A_FAILED(status)) { + break; + } + + if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg Len:%d! \n",target->CtrlResponseLength)); + status = A_ECOMM; + break; + } + + pReadyMsg = (HTC_READY_EX_MSG *)target->CtrlResponseBuffer; + + rdy_msg = &pReadyMsg->Version2_0_Info; + htc_rdy_msg_id = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID); + if (htc_rdy_msg_id != HTC_MSG_READY_ID) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Invalid HTC Ready Msg : 0x%X ! \n",htc_rdy_msg_id)); + status = A_ECOMM; + break; + } + + target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT); + target->TargetCreditSize = (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE); + target->MaxMsgsPerHTCBundle = (A_UINT8)pReadyMsg->MaxMsgsPerHTCBundle; + /* for old fw this value is set to 0. But the minimum value should be 1, + * i.e., no bundling */ + if (target->MaxMsgsPerHTCBundle < 1) + target->MaxMsgsPerHTCBundle = 1; + + AR_DEBUG_PRINTF(ATH_DEBUG_INIT, + ("Target Ready! : transmit resources : %d size:%d, MaxMsgsPerHTCBundle = %d\n", + target->TotalTransmitCredits, target->TargetCreditSize, target->MaxMsgsPerHTCBundle)); + + if ((0 == target->TotalTransmitCredits) || (0 == target->TargetCreditSize)) { + status = A_ECOMM; + break; + } + /* done processing */ + target->CtrlResponseProcessing = FALSE; + + HTCSetupTargetBufferAssignments(target); + + /* setup our pseudo HTC control endpoint connection */ + A_MEMZERO(&connect,sizeof(connect)); + A_MEMZERO(&resp,sizeof(resp)); + connect.EpCallbacks.pContext = target; + connect.EpCallbacks.EpTxComplete = HTCControlTxComplete; + connect.EpCallbacks.EpRecv = HTCControlRxComplete; + connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS; + connect.ServiceID = HTC_CTRL_RSVD_SVC; + + /* connect fake service */ + status = HTCConnectService((HTC_HANDLE)target, + &connect, + &resp); + + } while (FALSE); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit (%d)\n",status)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n")); + return status; +} + +/* start HTC, this is called after all services are connected */ +static A_STATUS HTCConfigTargetHIFPipe(HTC_TARGET *target) +{ + + return A_OK; +} + +static void ResetEndpointStates(HTC_TARGET *target) +{ + HTC_ENDPOINT *pEndpoint; + int i; + + for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + pEndpoint->ServiceID = 0; + pEndpoint->MaxMsgLength = 0; + pEndpoint->MaxTxQueueDepth = 0; + pEndpoint->Id = i; + INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue); + INIT_HTC_PACKET_QUEUE(&pEndpoint->TxLookupQueue); + INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBufferHoldQueue); + pEndpoint->target = target; + //pEndpoint->TxCreditFlowEnabled = (A_BOOL)htc_credit_flow; + pEndpoint->TxCreditFlowEnabled = (A_BOOL)1; + adf_os_atomic_init(&pEndpoint->TxProcessCount); + } +} + +A_STATUS HTCStart(HTC_HANDLE HTCHandle) +{ + adf_nbuf_t netbuf; + A_STATUS status = A_OK; + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_SETUP_COMPLETE_EX_MSG *pSetupComp; + HTC_PACKET *pSendPacket; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); + + do { + + HTCConfigTargetHIFPipe(target); + + /* allocate a buffer to send */ + pSendPacket = HTCAllocControlTxPacket(target); + if (NULL == pSendPacket) { + AR_DEBUG_ASSERT(FALSE); + adf_os_print("%s: allocControlTxPacket failed\n",__func__); + status = A_NO_MEMORY; + break; + } + + netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket); + /* assemble setup complete message */ + adf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG)); + pSetupComp = (HTC_SETUP_COMPLETE_EX_MSG *) adf_nbuf_data(netbuf); + A_MEMZERO(pSetupComp,sizeof(HTC_SETUP_COMPLETE_EX_MSG)); + + HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG, + MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID); + + if (!htc_credit_flow) { + AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC will not use TX credit flow control\n")); + pSetupComp->SetupFlags |= HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC using TX credit flow control\n")); + } + +#ifdef HIF_SDIO +#if ENABLE_BUNDLE_RX + if (HTC_ENABLE_BUNDLE(target)) + pSetupComp->SetupFlags |= + HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV; +#endif /* ENABLE_BUNDLE_RX */ +#endif /* HIF_SDIO */ + + SET_HTC_PACKET_INFO_TX(pSendPacket, + NULL, + (A_UINT8 *)pSetupComp, + sizeof(HTC_SETUP_COMPLETE_EX_MSG), + ENDPOINT_0, + HTC_SERVICE_TX_PACKET_TAG); + + status = HTCSendPkt((HTC_HANDLE)target,pSendPacket); + if (A_FAILED(status)) { + break; + } + + } while (FALSE); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); + return status; +} + +/*flush all queued buffers for surpriseremove case*/ +void HTCFlushSurpriseRemove(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + int i; + HTC_ENDPOINT *pEndpoint; +#ifdef RX_SG_SUPPORT + adf_nbuf_t netbuf; + adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCFlushSurpriseRemove \n")); + + /* cleanup endpoints */ + for (i = 0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + HTCFlushRxHoldQueue(target,pEndpoint); + HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); + } + + HIFFlushSurpriseRemove(target->hif_dev); + +#ifdef RX_SG_SUPPORT + LOCK_HTC_RX(target); + while ((netbuf = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { + adf_nbuf_free(netbuf); + } + RESET_RX_SG_CONFIG(target); + UNLOCK_HTC_RX(target); +#endif + + ResetEndpointStates(target); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCFlushSurpriseRemove \n")); +} + +/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ +void HTCStop(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + int i; + HTC_ENDPOINT *pEndpoint; +#ifdef RX_SG_SUPPORT + adf_nbuf_t netbuf; + adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); + + /* cleanup endpoints */ + for (i = 0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + HTCFlushRxHoldQueue(target,pEndpoint); + HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); + if(pEndpoint->ul_is_polled){ + adf_os_timer_cancel(&pEndpoint->ul_poll_timer); + adf_os_timer_free(&pEndpoint->ul_poll_timer); + } + } + + /* Note: HTCFlushEndpointTX for all endpoints should be called before + * HIFStop - otherwise HTCTxCompletionHandler called from + * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer, + * might queue the packet again to HIF Layer - which could cause tx + * buffer leak + */ + + HIFStop(target->hif_dev); + +#ifdef RX_SG_SUPPORT + LOCK_HTC_RX(target); + while ((netbuf = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { + adf_nbuf_free(netbuf); + } + RESET_RX_SG_CONFIG(target); + UNLOCK_HTC_RX(target); +#endif + + ResetEndpointStates(target); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); +} + + + +void HTCDumpCreditStates(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + int i; + + for (i = 0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + if (0 == pEndpoint->ServiceID) { + continue; + } + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n", + pEndpoint->Id, pEndpoint->ServiceID)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEndpoint->TxCredits)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEndpoint->TxCreditSize)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEndpoint->TxCreditsPerMaxMsg)); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n", HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue))); + AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); + } +} + + +A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint, + HTC_ENDPOINT_STAT_ACTION Action, + HTC_ENDPOINT_STATS *pStats) +{ +#ifdef HTC_EP_STAT_PROFILING + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + A_BOOL clearStats = FALSE; + A_BOOL sample = FALSE; + + switch (Action) { + case HTC_EP_STAT_SAMPLE : + sample = TRUE; + break; + case HTC_EP_STAT_SAMPLE_AND_CLEAR : + sample = TRUE; + clearStats = TRUE; + break; + case HTC_EP_STAT_CLEAR : + clearStats = TRUE; + break; + default: + break; + } + + A_ASSERT(Endpoint < ENDPOINT_MAX); + + /* lock out TX and RX while we sample and/or clear */ + LOCK_HTC_TX(target); + LOCK_HTC_RX(target); + + if (sample) { + A_ASSERT(pStats != NULL); + /* return the stats to the caller */ + A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); + } + + if (clearStats) { + /* reset stats */ + A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); + } + + UNLOCK_HTC_RX(target); + UNLOCK_HTC_TX(target); + + return TRUE; +#else + return FALSE; +#endif +} + +void *htc_get_targetdef(HTC_HANDLE htc_handle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); + + return hif_get_targetdef(target->hif_dev); +} + +void HTCSetTargetToSleep(void *context) +{ +#ifdef HIF_PCI +#if CONFIG_ATH_PCIE_MAX_PERF == 0 +#if CONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD + struct ol_softc *sc = (struct ol_softc *)context; + + HIFSetTargetSleep(sc->hif_hdl, true, false); +#endif +#endif +#endif +} + +void HTCCancelDeferredTargetSleep(void *context) +{ +#ifdef HIF_PCI +#if CONFIG_ATH_PCIE_MAX_PERF == 0 + struct ol_softc *sc = (struct ol_softc *)context; + HIFCancelDeferredTargetSleep(sc->hif_hdl); +#endif +#endif +} + +#ifdef IPA_UC_OFFLOAD +void HTCIpaGetCEResource(HTC_HANDLE htc_handle, + a_uint32_t *ce_sr_base_paddr, + a_uint32_t *ce_sr_ring_size, + a_uint32_t *ce_reg_paddr) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); + + if (target->hif_dev != NULL) { + HIFIpaGetCEResource(target->hif_dev, + ce_sr_base_paddr, + ce_sr_ring_size, + ce_reg_paddr); + } +} +#endif /* IPA_UC_OFFLOAD */ + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_debug.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_debug.h new file mode 100644 index 0000000000000..d41fcee13ba1e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_debug.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef HTC_DEBUG_H_ +#define HTC_DEBUG_H_ + +#define ATH_MODULE_NAME htc +#include "a_debug.h" + +/* ------- Debug related stuff ------- */ + +#define ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0) +#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1) +#define ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2) +#define ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3) +#define ATH_DEBUG_SETUP ATH_DEBUG_MAKE_MODULE_MASK(4) + + +#endif /*HTC_DEBUG_H_*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_internal.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_internal.h new file mode 100644 index 0000000000000..493c06a5bc0fc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_internal.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _HTC_INTERNAL_H_ +#define _HTC_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +//#include +#include +#include + +#endif +#include +#include "a_types.h" +#include "osapi_linux.h" +#include +#include +#include +#include +#include +#include "hif_msg_based.h" +#include +#include "htc_api.h" +#include "htc_packet.h" + +/* HTC operational parameters */ +#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ +#define HTC_TARGET_DEBUG_INTR_MASK 0x01 +#define HTC_TARGET_CREDIT_INTR_MASK 0xF0 +#define HTC_MIN_MSG_PER_BUNDLE 2 +#if defined(HIF_USB) +#define HTC_MAX_MSG_PER_BUNDLE 9 +#else +#define HTC_MAX_MSG_PER_BUNDLE 16 +#endif +/* + * HTC_MAX_TX_BUNDLE_SEND_LIMIT - + * This value is in units of tx frame fragments. + * It needs to be at least as large as the maximum number of tx frames in a + * HTC download bundle times the average number of fragments in each such frame + * (In certain operating systems, such as Linux, we expect to only have + * a single fragment per frame anyway.) + */ +#define HTC_MAX_TX_BUNDLE_SEND_LIMIT 255 + +#define HTC_PACKET_CONTAINER_ALLOCATION 32 +#define NUM_CONTROL_TX_BUFFERS 2 +#define HTC_CONTROL_BUFFER_SIZE (HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH) +#define HTC_CONTROL_BUFFER_ALIGN 32 +#define HTC_TARGET_RESPONSE_POLL_MS 10 +#if !defined(A_SIMOS_DEVHOST) +#define HTC_TARGET_MAX_RESPONSE_POLL 200 /* actual HW */ +#else +#define HTC_TARGET_MAX_RESPONSE_POLL 600 /* host + target simulation */ +#endif + +#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL + +#define HTC_CREDIT_HISTORY_MAX 1024 + +typedef enum { + HTC_REQUEST_CREDIT, + HTC_PROCESS_CREDIT_REPORT, + HTC_SUSPEND_ACK, + HTC_SUSPEND_NACK, +} htc_credit_exchange_type; + +typedef struct { + htc_credit_exchange_type type; + A_UINT64 time; + A_UINT32 tx_credit; + A_UINT32 htc_tx_queue_depth; +} HTC_CREDIT_HISTORY; + +typedef struct _HTC_ENDPOINT { + HTC_ENDPOINT_ID Id; + HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to + non-zero value means this endpoint is in use */ + HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */ + HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */ + int MaxTxQueueDepth; /* max depth of the TX queue before we need to + call driver's full handler */ + int MaxMsgLength; /* max length of endpoint message */ + a_uint8_t UL_PipeID; + a_uint8_t DL_PipeID; + int ul_is_polled; /* Need to call HIF to get tx completion callbacks? */ + adf_os_timer_t ul_poll_timer; + int ul_poll_timer_active; + int ul_outstanding_cnt; + int dl_is_polled; /* Need to call HIF to fetch rx? (Not currently supported.) */ + #if 0 /* not currently supported */ + adf_os_timer_t dl_poll_timer; + #endif + + HTC_PACKET_QUEUE TxLookupQueue; /* lookup queue to match netbufs to htc packets */ + HTC_PACKET_QUEUE RxBufferHoldQueue; /* temporary hold queue for back compatibility */ + A_UINT8 SeqNo; /* TX seq no (helpful) for debugging */ + adf_os_atomic_t TxProcessCount; /* serialization */ + struct _HTC_TARGET *target; + int TxCredits; /* TX credits available on this endpoint */ + int TxCreditSize; /* size in bytes of each credit (set by HTC) */ + int TxCreditsPerMaxMsg; /* credits required per max message (precalculated) */ +#ifdef HTC_EP_STAT_PROFILING + HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ +#endif + A_BOOL TxCreditFlowEnabled; +} HTC_ENDPOINT; + +#ifdef HTC_EP_STAT_PROFILING +#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count); +#else +#define INC_HTC_EP_STAT(p,stat,count) +#endif + +typedef struct { + A_UINT16 ServiceID; + A_UINT8 CreditAllocation; +} HTC_SERVICE_TX_CREDIT_ALLOCATION; + +#define HTC_MAX_SERVICE_ALLOC_ENTRIES 8 + +/* Error codes for HTC layer packet stats*/ +enum ol_ath_htc_pkt_ecodes { + GET_HTC_PKT_Q_FAIL=0, /* error- get packet at head of HTC_PACKET_Q */ + HTC_PKT_Q_EMPTY, + HTC_SEND_Q_EMPTY +}; +/* our HTC target state */ +typedef struct _HTC_TARGET { + HIF_DEVICE *hif_dev; + HTC_ENDPOINT EndPoint[ENDPOINT_MAX]; + adf_os_spinlock_t HTCLock; + adf_os_spinlock_t HTCRxLock; + adf_os_spinlock_t HTCTxLock; + adf_os_spinlock_t HTCCreditLock; + A_UINT32 HTCStateFlags; + void *host_handle; + HTC_INIT_INFO HTCInitInfo; + HTC_PACKET *pHTCPacketStructPool; /* pool of HTC packets */ + HTC_PACKET_QUEUE ControlBufferTXFreeList; + A_UINT8 CtrlResponseBuffer[HTC_MAX_CONTROL_MESSAGE_LENGTH]; + int CtrlResponseLength; + adf_os_mutex_t CtrlResponseValid; + A_BOOL CtrlResponseProcessing; + int TotalTransmitCredits; +#if defined(HIF_USB) + int avail_tx_credits; +#endif + HTC_SERVICE_TX_CREDIT_ALLOCATION ServiceTxAllocTable[HTC_MAX_SERVICE_ALLOC_ENTRIES]; + int TargetCreditSize; +#ifdef RX_SG_SUPPORT + adf_nbuf_queue_t RxSgQueue; + A_BOOL IsRxSgInprogress; + A_UINT32 CurRxSgTotalLen; /* current total length */ + A_UINT32 ExpRxSgTotalLen; /* expected total length */ +#endif + adf_os_device_t osdev; + struct ol_ath_htc_stats htc_pkt_stats; + HTC_PACKET *pBundleFreeList; + A_UINT32 CE_send_cnt; + A_UINT32 TX_comp_cnt; + A_UINT8 MaxMsgsPerHTCBundle; +} HTC_TARGET; + +#define HTC_ENABLE_BUNDLE(target) (target->MaxMsgsPerHTCBundle > 1) +#ifdef RX_SG_SUPPORT +#define RESET_RX_SG_CONFIG(_target) \ + _target->ExpRxSgTotalLen = 0; \ + _target->CurRxSgTotalLen = 0; \ + _target->IsRxSgInprogress = FALSE; +#endif + +#define HTC_STATE_STOPPING (1 << 0) +#define HTC_STOPPING(t) ((t)->HTCStateFlags & HTC_STATE_STOPPING) +#define LOCK_HTC(t) adf_os_spin_lock_bh(&(t)->HTCLock); +#define UNLOCK_HTC(t) adf_os_spin_unlock_bh(&(t)->HTCLock); +#define LOCK_HTC_RX(t) adf_os_spin_lock_bh(&(t)->HTCRxLock); +#define UNLOCK_HTC_RX(t) adf_os_spin_unlock_bh(&(t)->HTCRxLock); +#define LOCK_HTC_TX(t) adf_os_spin_lock_bh(&(t)->HTCTxLock); +#define UNLOCK_HTC_TX(t) adf_os_spin_unlock_bh(&(t)->HTCTxLock); +#define LOCK_HTC_CREDIT(t) adf_os_spin_lock_bh(&(t)->HTCCreditLock); +#define UNLOCK_HTC_CREDIT(t) adf_os_spin_unlock_bh(&(t)->HTCCreditLock); + +#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd)) + +#define IS_TX_CREDIT_FLOW_ENABLED(ep) ((ep)->TxCreditFlowEnabled) + +#define HTC_POLL_CLEANUP_PERIOD_MS 10 /* milliseconds */ + + +/* Macro to Increment the HTC_PACKET_ERRORS for Tx.*/ +#define OL_ATH_HTC_PKT_ERROR_COUNT_INCR(_target,_ecode)\ + do {\ + if(_ecode==GET_HTC_PKT_Q_FAIL)(_target->htc_pkt_stats.htc_get_pkt_q_fail_count)+=1;\ + if(_ecode==HTC_PKT_Q_EMPTY)(_target->htc_pkt_stats.htc_pkt_q_empty_count)+=1;\ + if(_ecode==HTC_SEND_Q_EMPTY)(_target->htc_pkt_stats.htc_send_q_empty_count)+=1;\ + } while(0); +/* internal HTC functions */ + +A_STATUS HTCRxCompletionHandler( + void *Context, adf_nbuf_t netbuf, a_uint8_t pipeID); +A_STATUS HTCTxCompletionHandler( + void *Context, adf_nbuf_t netbuf, unsigned int transferID); + +HTC_PACKET *AllocateHTCBundlePacket(HTC_TARGET *target); +void FreeHTCBundlePacket(HTC_TARGET *target, HTC_PACKET *pPacket); + +HTC_PACKET *AllocateHTCPacketContainer(HTC_TARGET *target); +void FreeHTCPacketContainer(HTC_TARGET *target, HTC_PACKET *pPacket); +void HTCFlushRxHoldQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint); +void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag); +void HTCRecvInit(HTC_TARGET *target); +A_STATUS HTCWaitRecvCtrlMessage(HTC_TARGET *target); +void HTCFreeControlTxPacket(HTC_TARGET *target, HTC_PACKET *pPacket); +HTC_PACKET *HTCAllocControlTxPacket(HTC_TARGET *target); +A_UINT8 HTCGetCreditAllocation(HTC_TARGET *target, A_UINT16 ServiceID); +void HTCTxResourceAvailHandler(void *context, A_UINT8 pipeID); +void HTCControlRxComplete(void *Context, HTC_PACKET *pPacket); +void HTCProcessCreditRpt(HTC_TARGET *target, + HTC_CREDIT_REPORT *pRpt, + int NumEntries, + HTC_ENDPOINT_ID FromEndpoint); +void HTCFwEventHandler(void *context, A_STATUS status); +void HTCSendCompleteCheckCleanup(void *context); + +void htc_credit_record(htc_credit_exchange_type type, A_UINT32 tx_credit, + A_UINT32 htc_tx_queue_depth); + +static inline void HTCSendCompletePollTimerStop(HTC_ENDPOINT *pEndpoint) +{ + LOCK_HTC_TX(pEndpoint->target); + if (pEndpoint->ul_poll_timer_active) { + //adf_os_timer_cancel(&pEndpoint->ul_poll_timer); + pEndpoint->ul_poll_timer_active = 0; + } + UNLOCK_HTC_TX(pEndpoint->target); +} + +static inline void HTCSendCompletePollTimerStart(HTC_ENDPOINT *pEndpoint) +{ + LOCK_HTC_TX(pEndpoint->target); + if (pEndpoint->ul_outstanding_cnt && ! pEndpoint->ul_poll_timer_active) { + /* + adf_os_timer_start( + &pEndpoint->ul_poll_timer, HTC_POLL_CLEANUP_PERIOD_MS); + */ + pEndpoint->ul_poll_timer_active = 1; + } + UNLOCK_HTC_TX(pEndpoint->target); +} + + +static inline void +HTCSendCompleteCheck(HTC_ENDPOINT *pEndpoint, int force) +{ + /* + * Stop the polling-cleanup timer that will result in a later call to + * this function. It may get started again below, if there are still + * outsending sends. + */ + HTCSendCompletePollTimerStop(pEndpoint); + /* + * Check whether HIF has any prior sends that have finished, + * have not had the post-processing done. + */ + HIFSendCompleteCheck( + pEndpoint->target->hif_dev, pEndpoint->UL_PipeID, force); + /* + * If there are still outstanding sends after polling, start a timer + * to check again a little later. + */ + HTCSendCompletePollTimerStart(pEndpoint); +} + + +#ifdef __cplusplus +} +#endif + +#ifndef DEBUG_BUNDLE +#define DEBUG_BUNDLE 0 +#endif + +#ifdef HIF_SDIO +#ifndef ENABLE_BUNDLE_TX +#define ENABLE_BUNDLE_TX 1 +#endif + +#ifndef ENABLE_BUNDLE_RX +#define ENABLE_BUNDLE_RX 1 +#endif +#endif /* HIF_SDIO */ +#endif /* !_HTC_HOST_INTERNAL_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_recv.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_recv.c new file mode 100644 index 0000000000000..8e346c474b60d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_recv.c @@ -0,0 +1,703 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "htc_debug.h" +#include "htc_internal.h" +#include "vos_api.h" +#include /* adf_nbuf_t */ +#include +#include "epping_main.h" + +#ifdef DEBUG +void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription) +{ + A_CHAR stream[60]; + A_CHAR byteOffsetStr[10]; + A_UINT32 i; + A_UINT16 offset, count, byteOffset; + + A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription); + + count = 0; + offset = 0; + byteOffset = 0; + for(i = 0; i < length; i++) { + A_SNPRINTF(stream + offset, (sizeof(stream) - offset), + "%02X ", buffer[i]); + count ++; + offset += 3; + + if(count == 16) { + count = 0; + offset = 0; + A_SNPRINTF(byteOffsetStr, sizeof(byteOffset), "%4.4X",byteOffset); + A_PRINTF("[%s]: %s\n", byteOffsetStr, stream); + A_MEMZERO(stream, 60); + byteOffset += 16; + } + } + + if(offset != 0) { + A_SNPRINTF(byteOffsetStr, sizeof(byteOffset), "%4.4X",byteOffset); + A_PRINTF("[%s]: %s\n", byteOffsetStr, stream); + } + + A_PRINTF("<------------------------------------------------->\n"); +} +#else +void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription) +{} +#endif + +static A_STATUS HTCProcessTrailer(HTC_TARGET *target, + A_UINT8 *pBuffer, + int Length, + HTC_ENDPOINT_ID FromEndpoint); + +static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pQueueToIndicate) +{ + + do { + + if (HTC_QUEUE_EMPTY(pQueueToIndicate)) { + /* nothing to indicate */ + break; + } + + if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n", + pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate))); + /* a recv multiple handler is being used, pass the queue to the handler */ + pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext, + pQueueToIndicate); + INIT_HTC_PACKET_QUEUE(pQueueToIndicate); + } else { + HTC_PACKET *pPacket; + /* using legacy EpRecv */ + while (!HTC_QUEUE_EMPTY(pQueueToIndicate)) { + pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); + if (pEndpoint->EpCallBacks.EpRecv == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC ep %d has NULL recv callback on packet %p\n", + pEndpoint->Id, pPacket)); + continue; + } + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTC calling ep %d recv callback on packet %p\n", + pEndpoint->Id, pPacket)); + pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket); + } + } + + } while (FALSE); + +} + +static void RecvPacketCompletion(HTC_TARGET *target,HTC_ENDPOINT *pEndpoint, HTC_PACKET *pPacket) +{ + HTC_PACKET_QUEUE container; + INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); + /* do completion */ + DoRecvCompletion(pEndpoint,&container); +} + + +void HTCControlRxComplete(void *Context, HTC_PACKET *pPacket) +{ + /* TODO, can't really receive HTC control messages yet.... */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid call to HTCControlRxComplete\n")); +} + +void HTCUnblockRecv(HTC_HANDLE HTCHandle) +{ + /* TODO find the Need in new model*/ +} + + +void HTCEnableRecv(HTC_HANDLE HTCHandle) +{ + + /* TODO find the Need in new model*/ +} + +void HTCDisableRecv(HTC_HANDLE HTCHandle) +{ + + /* TODO find the Need in new model*/ +} + +int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; + return HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBufferHoldQueue); +} + +HTC_PACKET *AllocateHTCPacketContainer(HTC_TARGET *target) +{ + HTC_PACKET *pPacket; + + LOCK_HTC_RX(target); + + if (NULL == target->pHTCPacketStructPool) { + UNLOCK_HTC_RX(target); + return NULL; + } + + pPacket = target->pHTCPacketStructPool; + target->pHTCPacketStructPool = (HTC_PACKET *)pPacket->ListLink.pNext; + + UNLOCK_HTC_RX(target); + + pPacket->ListLink.pNext = NULL; + return pPacket; +} + +void FreeHTCPacketContainer(HTC_TARGET *target, HTC_PACKET *pPacket) +{ + LOCK_HTC_RX(target); + + if (NULL == target->pHTCPacketStructPool) { + target->pHTCPacketStructPool = pPacket; + pPacket->ListLink.pNext = NULL; + } else { + pPacket->ListLink.pNext = (DL_LIST *)target->pHTCPacketStructPool; + target->pHTCPacketStructPool = pPacket; + } + + UNLOCK_HTC_RX(target); +} + +#ifdef RX_SG_SUPPORT +adf_nbuf_t RxSgToSingleNetbuf(HTC_TARGET *target) +{ + adf_nbuf_t skb; + a_uint8_t *anbdata; + a_uint8_t *anbdata_new; + a_uint32_t anblen; + adf_nbuf_t new_skb = NULL; + a_uint32_t sg_queue_len; + adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; + + sg_queue_len = adf_nbuf_queue_len(rx_sg_queue); + + if (sg_queue_len <= 1) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("RxSgToSingleNetbuf: invalid sg queue len %u\n")); + goto _failed; + } + + new_skb = adf_nbuf_alloc(target->ExpRxSgTotalLen, 0, 4, FALSE); + if (new_skb == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("RxSgToSingleNetbuf: can't allocate %u size netbuf\n", + target->ExpRxSgTotalLen)); + goto _failed; + } + + adf_nbuf_peek_header(new_skb, &anbdata_new, &anblen); + + skb = adf_nbuf_queue_remove(rx_sg_queue); + do { + adf_nbuf_peek_header(skb, &anbdata, &anblen); + adf_os_mem_copy(anbdata_new, anbdata, adf_nbuf_len(skb)); + adf_nbuf_put_tail(new_skb, adf_nbuf_len(skb)); + anbdata_new += adf_nbuf_len(skb); + adf_nbuf_free(skb); + skb = adf_nbuf_queue_remove(rx_sg_queue); + } while(skb != NULL); + + RESET_RX_SG_CONFIG(target); + return new_skb; + +_failed: + + while ((skb = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { + adf_nbuf_free(skb); + } + + RESET_RX_SG_CONFIG(target); + return NULL; +} +#endif + +static void HTCsuspendwow(HTC_TARGET *target) +{ + HIFsuspendwow(target->hif_dev); + return; +} + +A_STATUS HTCRxCompletionHandler( + void *Context, adf_nbuf_t netbuf, a_uint8_t pipeID) +{ + A_STATUS status = A_OK; + HTC_FRAME_HDR *HtcHdr; + HTC_TARGET *target = (HTC_TARGET *)Context; + a_uint8_t *netdata; + a_uint32_t netlen; + HTC_ENDPOINT *pEndpoint; + HTC_PACKET *pPacket; + A_UINT16 payloadLen; + a_uint32_t trailerlen = 0; + A_UINT8 htc_ep_id; + +#ifdef RX_SG_SUPPORT + LOCK_HTC_RX(target); + if (target->IsRxSgInprogress) { + target->CurRxSgTotalLen += adf_nbuf_len(netbuf); + adf_nbuf_queue_add(&target->RxSgQueue, netbuf); + if (target->CurRxSgTotalLen == target->ExpRxSgTotalLen) { + netbuf = RxSgToSingleNetbuf(target); + if (netbuf == NULL) { + UNLOCK_HTC_RX(target); + goto _out; + } + } + else { + netbuf = NULL; + UNLOCK_HTC_RX(target); + goto _out; + } + } + UNLOCK_HTC_RX(target); +#endif + + netdata = adf_nbuf_data(netbuf); + netlen = adf_nbuf_len(netbuf); + + HtcHdr = (HTC_FRAME_HDR *)netdata; + + do { + + htc_ep_id = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, ENDPOINTID); + + if (htc_ep_id >= ENDPOINT_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx: invalid EndpointID=%d\n",htc_ep_id)); + DebugDumpBytes((A_UINT8 *)HtcHdr,sizeof(HTC_FRAME_HDR),"BAD HTC Header"); + status = A_ERROR; + VOS_BUG(0); + break; + } + + pEndpoint = &target->EndPoint[htc_ep_id]; + + /* + * If this endpoint that received a message from the target has + * a to-target HIF pipe whose send completions are polled rather + * than interrupt-driven, this is a good point to ask HIF to check + * whether it has any completed sends to handle. + */ + if (pEndpoint->ul_is_polled) { + HTCSendCompleteCheck(pEndpoint, 1); + } + + payloadLen = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, PAYLOADLEN); + + if (netlen < (payloadLen + HTC_HDR_LENGTH)) { +#ifdef RX_SG_SUPPORT + LOCK_HTC_RX(target); + target->IsRxSgInprogress = TRUE; + adf_nbuf_queue_init(&target->RxSgQueue); + adf_nbuf_queue_add(&target->RxSgQueue, netbuf); + target->ExpRxSgTotalLen = (payloadLen + HTC_HDR_LENGTH); + target->CurRxSgTotalLen += netlen; + UNLOCK_HTC_RX(target); + netbuf = NULL; + break; +#else + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx: insufficient length, got:%d expected =%zu\n", + netlen, payloadLen + HTC_HDR_LENGTH)); + DebugDumpBytes((A_UINT8 *)HtcHdr,sizeof(HTC_FRAME_HDR),"BAD RX packet length"); + status = A_ERROR; + VOS_BUG(0); + break; +#endif + } + +#ifdef HTC_EP_STAT_PROFILING + LOCK_HTC_RX(target); + INC_HTC_EP_STAT(pEndpoint,RxReceived,1); + UNLOCK_HTC_RX(target); +#endif + + //if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { + { + A_UINT8 temp; + /* get flags to check for trailer */ + temp = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, FLAGS); + if (temp & HTC_FLAGS_RECV_TRAILER) { + /* extract the trailer length */ + temp = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, CONTROLBYTES0); + if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("HTCRxCompletionHandler, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", + payloadLen, temp)); + status = A_EPROTO; + break; + } + + trailerlen = temp; + /* process trailer data that follows HDR + application payload */ + status = HTCProcessTrailer(target, + ((A_UINT8 *)HtcHdr + HTC_HDR_LENGTH + payloadLen - temp), + temp, htc_ep_id); + if (A_FAILED(status)) { + break; + } + + } + } + + if (((int)payloadLen - (int)trailerlen) <= 0) { + /* zero length packet with trailer data, just drop these */ + break; + } + + + if (htc_ep_id == ENDPOINT_0) { + A_UINT16 message_id; + HTC_UNKNOWN_MSG *htc_msg; + int wow_nack = 0; + + /* remove HTC header */ + adf_nbuf_pull_head(netbuf, HTC_HDR_LENGTH); + netdata = adf_nbuf_data(netbuf); + netlen = adf_nbuf_len(netbuf); + + htc_msg = (HTC_UNKNOWN_MSG*)netdata; + message_id = HTC_GET_FIELD(htc_msg, HTC_UNKNOWN_MSG, MESSAGEID); + + switch (message_id) { + default: + /* handle HTC control message */ + if (target->CtrlResponseProcessing) { + /* this is a fatal error, target should not be sending unsolicited messages + * on the endpoint 0 */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx Ctrl still processing\n")); + status = A_ERROR; + break; + } + + LOCK_HTC_RX(target); + target->CtrlResponseLength = min((int)netlen,HTC_MAX_CONTROL_MESSAGE_LENGTH); + A_MEMCPY(target->CtrlResponseBuffer,netdata,target->CtrlResponseLength); + UNLOCK_HTC_RX(target); + + adf_os_mutex_release(target->osdev, &target->CtrlResponseValid); + break; + case HTC_MSG_SEND_SUSPEND_COMPLETE: + wow_nack = 0; + LOCK_HTC_CREDIT(target); + htc_credit_record(HTC_SUSPEND_ACK, pEndpoint->TxCredits, + HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); + UNLOCK_HTC_CREDIT(target); + target->HTCInitInfo.TargetSendSuspendComplete((void *)&wow_nack); + HTCsuspendwow(target); + break; + case HTC_MSG_NACK_SUSPEND: + wow_nack = 1; + LOCK_HTC_CREDIT(target); + htc_credit_record(HTC_SUSPEND_NACK, pEndpoint->TxCredits, + HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); + UNLOCK_HTC_CREDIT(target); + target->HTCInitInfo.TargetSendSuspendComplete((void *)&wow_nack); + break; + } + + adf_nbuf_free(netbuf); + netbuf = NULL; + break; + } + + /* the current message based HIF architecture allocates net bufs for recv packets + * since this layer bridges that HIF to upper layers , which expects HTC packets, + * we form the packets here + * TODO_FIXME */ + pPacket = AllocateHTCPacketContainer(target); + if (NULL == pPacket) { + status = A_NO_RESOURCE; + break; + } + pPacket->Status = A_OK; + pPacket->Endpoint = htc_ep_id; + pPacket->pPktContext = netbuf; + pPacket->pBuffer = adf_nbuf_data(netbuf) + HTC_HDR_LENGTH; + pPacket->ActualLength = netlen - HTC_HEADER_LEN - trailerlen; + + adf_nbuf_pull_head(netbuf, HTC_HEADER_LEN); + adf_nbuf_set_pktlen(netbuf, pPacket->ActualLength); + + RecvPacketCompletion(target,pEndpoint,pPacket); + /* recover the packet container */ + FreeHTCPacketContainer(target,pPacket); + netbuf = NULL; + + } while(FALSE); + +#ifdef RX_SG_SUPPORT +_out: +#endif + + if (netbuf != NULL) { + adf_nbuf_free(netbuf); + } + + return status; + +} + +A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + HTC_PACKET *pFirstPacket; + A_STATUS status = A_OK; + HTC_PACKET *pPacket; + + pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); + + if (NULL == pFirstPacket) { + A_ASSERT(FALSE); + return A_EINVAL; + } + + AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX); + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, + ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n", + pFirstPacket->Endpoint, + HTC_PACKET_QUEUE_DEPTH(pPktQueue), + pFirstPacket->BufferLength)); + + pEndpoint = &target->EndPoint[pFirstPacket->Endpoint]; + + LOCK_HTC_RX(target); + + do { + + if (HTC_STOPPING(target)) { + status = A_ERROR; + break; + } + + /* store receive packets */ + HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBufferHoldQueue,pPktQueue); + + } while (FALSE); + + UNLOCK_HTC_RX(target); + + if (A_FAILED(status)) { + /* walk through queue and mark each one canceled */ + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) { + pPacket->Status = A_ECANCELED; + } HTC_PACKET_QUEUE_ITERATE_END; + + DoRecvCompletion(pEndpoint,pPktQueue); + } + + return status; +} + + +A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +{ + HTC_PACKET_QUEUE queue; + INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); + return HTCAddReceivePktMultiple(HTCHandle, &queue); +} + +void HTCFlushRxHoldQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint) +{ + HTC_PACKET *pPacket; + HTC_PACKET_QUEUE container; + + LOCK_HTC_RX(target); + + while (1) { + pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBufferHoldQueue); + if (NULL == pPacket) { + break; + } + UNLOCK_HTC_RX(target); + pPacket->Status = A_ECANCELED; + pPacket->ActualLength = 0; + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:%p, length:%d, ep:%d \n", + pPacket, pPacket->BufferLength, pPacket->Endpoint)); + INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); + /* give the packet back */ + DoRecvCompletion(pEndpoint,&container); + LOCK_HTC_RX(target); + } + + UNLOCK_HTC_RX(target); +} + +void HTCRecvInit(HTC_TARGET *target) +{ + /* Initialize CtrlResponseValid to block */ + adf_os_init_mutex(&target->CtrlResponseValid); + adf_os_mutex_acquire(target->osdev, &target->CtrlResponseValid); +} + + + /* polling routine to wait for a control packet to be received */ +A_STATUS HTCWaitRecvCtrlMessage(HTC_TARGET *target) +{ +// int count = HTC_TARGET_MAX_RESPONSE_POLL; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HTCWaitCtrlMessageRecv\n")); + + /* Wait for BMI request/response transaction to complete */ + while (adf_os_mutex_acquire(target->osdev, &target->CtrlResponseValid)) { + } + + LOCK_HTC_RX(target); + /* caller will clear this flag */ + target->CtrlResponseProcessing = TRUE; + + UNLOCK_HTC_RX(target); + +#if 0 + while (count > 0) { + + LOCK_HTC_RX(target); + + if (target->CtrlResponseValid) { + target->CtrlResponseValid = FALSE; + /* caller will clear this flag */ + target->CtrlResponseProcessing = TRUE; + UNLOCK_HTC_RX(target); + break; + } + + UNLOCK_HTC_RX(target); + + count--; + A_MSLEEP(HTC_TARGET_RESPONSE_POLL_MS); + } + + if (count <= 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("-HTCWaitCtrlMessageRecv: Timeout!\n")); + return A_ECOMM; + } +#endif + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HTCWaitCtrlMessageRecv success\n")); + return A_OK; +} + +static A_STATUS HTCProcessTrailer(HTC_TARGET *target, + A_UINT8 *pBuffer, + int Length, + HTC_ENDPOINT_ID FromEndpoint) +{ + HTC_RECORD_HDR *pRecord; + A_UINT8 htc_rec_id; + A_UINT8 htc_rec_len; + A_UINT8 *pRecordBuf; + A_UINT8 *pOrigBuffer; + int origLength; + A_STATUS status; + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length)); + + if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { + AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer"); + } + + pOrigBuffer = pBuffer; + origLength = Length; + status = A_OK; + + while (Length > 0) { + + if (Length < sizeof(HTC_RECORD_HDR)) { + status = A_EPROTO; + break; + } + /* these are byte aligned structs */ + pRecord = (HTC_RECORD_HDR *)pBuffer; + Length -= sizeof(HTC_RECORD_HDR); + pBuffer += sizeof(HTC_RECORD_HDR); + + htc_rec_len = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, LENGTH); + htc_rec_id = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, RECORDID); + + if (htc_rec_len > Length) { + /* no room left in buffer for record */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", + htc_rec_len, htc_rec_id, Length)); + status = A_EPROTO; + break; + } + /* start of record follows the header */ + pRecordBuf = pBuffer; + + switch (htc_rec_id) { + case HTC_RECORD_CREDITS: + AR_DEBUG_ASSERT(htc_rec_len >= sizeof(HTC_CREDIT_REPORT)); + HTCProcessCreditRpt(target, + (HTC_CREDIT_REPORT *)pRecordBuf, + htc_rec_len / (sizeof(HTC_CREDIT_REPORT)), + FromEndpoint); + break; + +#ifdef HIF_SDIO + case HTC_RECORD_LOOKAHEAD: + /* Process in HIF layer */ + break; + + case HTC_RECORD_LOOKAHEAD_BUNDLE: + /* Process in HIF layer */ + break; +#endif /* HIF_SDIO */ + + default: + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" HTC unhandled record: id:%d length:%d \n", + htc_rec_id, htc_rec_len)); + break; + } + + if (A_FAILED(status)) { + break; + } + + /* advance buffer past this record for next time around */ + pBuffer += htc_rec_len; + Length -= htc_rec_len; + } + + if (A_FAILED(status)) { + DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer"); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n")); + return status; + +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_send.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_send.c new file mode 100644 index 0000000000000..309fa0d219517 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_send.c @@ -0,0 +1,1715 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include "htc_debug.h" +#include "htc_internal.h" +#include /* adf_nbuf_t */ +#include /* adf_os_mem_alloc */ +#include +#include "epping_main.h" + +//#define USB_HIF_SINGLE_PIPE_DATA_SCHED +//#ifdef USB_HIF_SINGLE_PIPE_DATA_SCHED +#define DATA_EP_SIZE 4 +//#endif +#define HTC_DATA_RESOURCE_THRS 256 +#define HTC_DATA_MINDESC_PERPACKET 2 + +typedef enum _HTC_SEND_QUEUE_RESULT { + HTC_SEND_QUEUE_OK = 0, /* packet was queued */ + HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */ +} HTC_SEND_QUEUE_RESULT; + +#ifndef DEBUG_CREDIT +#define DEBUG_CREDIT 0 +#endif + +#if DEBUG_CREDIT +/* bit mask to enable debug certain endpoint */ +static unsigned ep_debug_mask = (1 << ENDPOINT_0) | (1 << ENDPOINT_1) | (1 << ENDPOINT_2); +#endif + +/* HTC Control Path Credit History */ +A_UINT32 g_htc_credit_history_idx = 0; +HTC_CREDIT_HISTORY htc_credit_history_buffer[HTC_CREDIT_HISTORY_MAX]; + +void htc_credit_record(htc_credit_exchange_type type, A_UINT32 tx_credit, + A_UINT32 htc_tx_queue_depth) +{ + if (HTC_CREDIT_HISTORY_MAX <= g_htc_credit_history_idx) + g_htc_credit_history_idx = 0; + + htc_credit_history_buffer[g_htc_credit_history_idx].type = type; + htc_credit_history_buffer[g_htc_credit_history_idx].time = + adf_get_boottime(); + htc_credit_history_buffer[g_htc_credit_history_idx].tx_credit = tx_credit; + htc_credit_history_buffer[g_htc_credit_history_idx].htc_tx_queue_depth = + htc_tx_queue_depth; + g_htc_credit_history_idx++; +} + +void HTC_dump_counter_info(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("\n%s: CE_send_cnt = %d, TX_comp_cnt = %d\n", + __func__, target->CE_send_cnt, target->TX_comp_cnt)); +} + +void HTCGetControlEndpointTxHostCredits(HTC_HANDLE HTCHandle, int *credits) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + int i; + + if (!credits || !target) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: invalid args", __func__)); + return; + } + + *credits = 0; + LOCK_HTC_TX(target); + for (i = 0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + if (pEndpoint->ServiceID == WMI_CONTROL_SVC) { + *credits = pEndpoint->TxCredits; + break; + } + } + UNLOCK_HTC_TX(target); +} + +static INLINE void RestoreTxPacket(HTC_TARGET *target, HTC_PACKET *pPacket) +{ + if (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) { + adf_nbuf_t netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + adf_nbuf_unmap(target->osdev, netbuf, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_pull_head(netbuf, sizeof(HTC_FRAME_HDR)); + pPacket->PktInfo.AsTx.Flags &= ~HTC_TX_PACKET_FLAG_FIXUP_NETBUF; + } + +} + +static void DoSendCompletion(HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pQueueToIndicate) +{ + do { + + if (HTC_QUEUE_EMPTY(pQueueToIndicate)) { + /* nothing to indicate */ + break; + } + + if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n", + pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate))); + /* a multiple send complete handler is being used, pass the queue to the handler */ + pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext, + pQueueToIndicate); + /* all packets are now owned by the callback, reset queue to be safe */ + INIT_HTC_PACKET_QUEUE(pQueueToIndicate); + } else { + HTC_PACKET *pPacket; + /* using legacy EpTxComplete */ + do { + pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet %p \n", \ + pEndpoint->Id, pPacket)); + pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket); + } while (!HTC_QUEUE_EMPTY(pQueueToIndicate)); + } + + } while (FALSE); + +} + +static void SendPacketCompletion(HTC_TARGET *target, HTC_PACKET *pPacket) +{ + HTC_ENDPOINT *pEndpoint = &target->EndPoint[pPacket->Endpoint]; + HTC_PACKET_QUEUE container; + + RestoreTxPacket(target, pPacket); + INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); + + /* do completion */ + DoSendCompletion(pEndpoint,&container); +} + +void +HTCSendCompleteCheckCleanup(void *context) +{ + HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *) context; + HTCSendCompleteCheck(pEndpoint, 1); +} + + +HTC_PACKET *AllocateHTCBundlePacket(HTC_TARGET *target) +{ + HTC_PACKET *pPacket; + HTC_PACKET_QUEUE *pQueueSave; + adf_nbuf_t netbuf; + LOCK_HTC_TX(target); + if (NULL == target->pBundleFreeList) { + UNLOCK_HTC_TX(target); + netbuf = adf_nbuf_alloc(NULL, + target->MaxMsgsPerHTCBundle * target->TargetCreditSize, + 0, + 4, + FALSE); + AR_DEBUG_ASSERT(netbuf); + if (!netbuf) + { + return NULL; + } + pPacket = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET)); + AR_DEBUG_ASSERT(pPacket); + if (!pPacket) + { + adf_nbuf_free(netbuf); + return NULL; + } + pQueueSave = adf_os_mem_alloc(NULL, sizeof(HTC_PACKET_QUEUE)); + AR_DEBUG_ASSERT(pQueueSave); + if (!pQueueSave) + { + adf_nbuf_free(netbuf); + adf_os_mem_free(pPacket); + return NULL; + } + INIT_HTC_PACKET_QUEUE(pQueueSave); + pPacket->pContext = pQueueSave; + SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf); + pPacket->pBuffer = adf_nbuf_data(netbuf); + pPacket->BufferLength = adf_nbuf_len(netbuf); + + //store the original head room so that we can restore this when we "free" the packet + //free packet puts the packet back on the free list + pPacket->netbufOrigHeadRoom = adf_nbuf_headroom(netbuf); + return pPacket; + } + + //already done malloc - restore from free list + pPacket = target->pBundleFreeList; + AR_DEBUG_ASSERT(pPacket); + if (!pPacket) + { + UNLOCK_HTC_TX(target); + return NULL; + } + target->pBundleFreeList = (HTC_PACKET *)pPacket->ListLink.pNext; + UNLOCK_HTC_TX(target); + pPacket->ListLink.pNext = NULL; + + return pPacket; +} + +void FreeHTCBundlePacket(HTC_TARGET *target, HTC_PACKET *pPacket) +{ + A_UINT32 curentHeadRoom; + adf_nbuf_t netbuf; + HTC_PACKET_QUEUE *pQueueSave; + + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + AR_DEBUG_ASSERT(netbuf); + if (!netbuf) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("\n%s: Invalid netbuf in HTC " + "Packet\n", __func__)); + return; + } + + // HIF adds data to the headroom section of the nbuf, restore the original + // size. If this is not done, headroom keeps shrinking with every HIF send + // and eventually HIF ends up doing another malloc big enough to store the + // data + its header + + curentHeadRoom = adf_nbuf_headroom(netbuf); + adf_nbuf_pull_head(netbuf, pPacket->netbufOrigHeadRoom - curentHeadRoom); + adf_nbuf_trim_tail(netbuf, adf_nbuf_len(netbuf)); + + //restore the pBuffer pointer. HIF changes this + pPacket->pBuffer = adf_nbuf_data(netbuf); + pPacket->BufferLength = adf_nbuf_len(netbuf); + + //restore queue + pQueueSave = (HTC_PACKET_QUEUE*)pPacket->pContext; + AR_DEBUG_ASSERT(pQueueSave); + + INIT_HTC_PACKET_QUEUE(pQueueSave); + + LOCK_HTC_TX(target); + if (target->pBundleFreeList == NULL) { + target->pBundleFreeList = pPacket; + pPacket->ListLink.pNext = NULL; + } else { + pPacket->ListLink.pNext = (DL_LIST *)target->pBundleFreeList; + target->pBundleFreeList = pPacket; + } + UNLOCK_HTC_TX(target); +} + +#if defined(HIF_USB) || defined(HIF_SDIO) +#ifdef ENABLE_BUNDLE_TX +static A_STATUS HTCSendBundledNetbuf(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + unsigned char *pBundleBuffer, + HTC_PACKET *pPacketTx) +{ + adf_os_size_t data_len; + A_STATUS status; + adf_nbuf_t bundleBuf; + bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx); + data_len = pBundleBuffer - adf_nbuf_data(bundleBuf); + adf_nbuf_put_tail(bundleBuf, data_len); + SET_HTC_PACKET_INFO_TX(pPacketTx, + target, + pBundleBuffer, + data_len, + pEndpoint->Id, + HTC_TX_PACKET_TAG_BUNDLED); + LOCK_HTC_TX(target); + HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue, pPacketTx); + UNLOCK_HTC_TX(target); +#if DEBUG_BUNDLE + adf_os_print(" Send bundle EP%d buffer size:0x%x, total:0x%x, count:%d.\n", + pEndpoint->Id, + pEndpoint->TxCreditSize, + data_len, + data_len / pEndpoint->TxCreditSize); +#endif + status = HIFSend_head(target->hif_dev, + pEndpoint->UL_PipeID, + pEndpoint->Id, + data_len, + bundleBuf); + if (status != A_OK){ + adf_os_print("%s:HIFSend_head failed(len=%d).\n", __FUNCTION__, data_len); + } + return status; +} + +static void HTCIssuePacketsBundle(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pPktQueue) +{ + int i, frag_count, nbytes; + adf_nbuf_t netbuf, bundleBuf; + unsigned char *pBundleBuffer = NULL; + HTC_PACKET *pPacket = NULL, *pPacketTx = NULL; + HTC_FRAME_HDR *pHtcHdr; + int creditPad, creditRemainder,transferLength, bundlesSpaceRemaining = 0; + HTC_PACKET_QUEUE *pQueueSave = NULL; + + bundlesSpaceRemaining = target->MaxMsgsPerHTCBundle * pEndpoint->TxCreditSize; + pPacketTx = AllocateHTCBundlePacket(target); + if (!pPacketTx) + { + //good time to panic + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AllocateHTCBundlePacket failed \n")); + AR_DEBUG_ASSERT(FALSE); + return; + } + bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx); + pBundleBuffer = adf_nbuf_data(bundleBuf); + pQueueSave = (HTC_PACKET_QUEUE*)pPacketTx->pContext; + while (1) { + pPacket = HTC_PACKET_DEQUEUE(pPktQueue); + if (pPacket == NULL){ + break; + } + creditPad = 0; + transferLength = pPacket->ActualLength + HTC_HDR_LENGTH; + creditRemainder = transferLength % pEndpoint->TxCreditSize; + if(creditRemainder != 0){ + if(transferLength < pEndpoint->TxCreditSize){ + creditPad = pEndpoint->TxCreditSize - transferLength; + } else { + creditPad = creditRemainder; + } + transferLength += creditPad; + } + + if (bundlesSpaceRemaining < transferLength){ + /* send out previous buffer */ + HTCSendBundledNetbuf(target, pEndpoint, pBundleBuffer, pPacketTx); + if (HTC_PACKET_QUEUE_DEPTH(pPktQueue) < HTC_MIN_MSG_PER_BUNDLE){ + return; + } + bundlesSpaceRemaining = target->MaxMsgsPerHTCBundle * pEndpoint->TxCreditSize; + pPacketTx = AllocateHTCBundlePacket(target); + if (!pPacketTx) + { + //good time to panic + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AllocateHTCBundlePacket failed \n")); + AR_DEBUG_ASSERT(FALSE); + return; + } + bundleBuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacketTx); + pBundleBuffer = adf_nbuf_data(bundleBuf); + pQueueSave = (HTC_PACKET_QUEUE*)pPacketTx->pContext; + } + + bundlesSpaceRemaining -= transferLength; + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0); + HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) | + SM(pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE, HTC_FRAME_HDR_FLAGS) | + SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID)); + HTC_WRITE32((A_UINT32 *)pHtcHdr + 1, + SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1) | + SM(creditPad, HTC_FRAME_HDR_RESERVED)); + pHtcHdr->reserved = creditPad; + frag_count = adf_nbuf_get_num_frags(netbuf); + nbytes = pPacket->ActualLength + HTC_HDR_LENGTH; + for (i = 0; i < frag_count && nbytes > 0; i ++){ + int frag_len = adf_nbuf_get_frag_len(netbuf, i); + unsigned char *frag_addr = adf_nbuf_get_frag_vaddr(netbuf, i); + if (frag_len > nbytes){ + frag_len = nbytes; + } + A_MEMCPY(pBundleBuffer, frag_addr, frag_len); + nbytes -= frag_len; + pBundleBuffer += frag_len; + } + HTC_PACKET_ENQUEUE(pQueueSave, pPacket); + pBundleBuffer += creditPad; + } + if (pBundleBuffer != adf_nbuf_data(bundleBuf)){ + /* send out remaining buffer */ + HTCSendBundledNetbuf(target, pEndpoint, pBundleBuffer, pPacketTx); + } else { + FreeHTCBundlePacket(target, pPacketTx); + } +} +#endif /* ENABLE_BUNDLE_TX */ +#endif + +static A_STATUS HTCIssuePackets(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pPktQueue) +{ + A_STATUS status = A_OK; + adf_nbuf_t netbuf; + HTC_PACKET *pPacket = NULL; + u_int16_t payloadLen; + HTC_FRAME_HDR *pHtcHdr; + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCIssuePackets: Queue: %p, Pkts %d \n", + pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue))); + while (TRUE) { +#if defined(HIF_USB) || defined(HIF_SDIO) +#ifdef ENABLE_BUNDLE_TX + if(IS_TX_CREDIT_FLOW_ENABLED(pEndpoint) && + HTC_ENABLE_BUNDLE(target) && + HTC_PACKET_QUEUE_DEPTH(pPktQueue) >= HTC_MIN_MSG_PER_BUNDLE){ + HTCIssuePacketsBundle(target, pEndpoint, pPktQueue); + } +#endif +#endif + /* if not bundling or there was a packet that could not be placed in a bundle, + * and send it by normal way + */ + pPacket = HTC_PACKET_DEQUEUE(pPktQueue); + if(NULL == pPacket){ + /* local queue is fully drained */ + break; + } + + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + AR_DEBUG_ASSERT(netbuf); + /* Non-credit enabled endpoints have been mapped and setup by now, + * so no need to revisit the HTC headers + */ + if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { + + payloadLen = pPacket->ActualLength; + /* setup HTC frame header */ + + pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0); + AR_DEBUG_ASSERT(pHtcHdr); + + + HTC_WRITE32(pHtcHdr, SM(payloadLen, HTC_FRAME_HDR_PAYLOADLEN) | + SM(pPacket->PktInfo.AsTx.SendFlags, HTC_FRAME_HDR_FLAGS) | + SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID)); + HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, + SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1)); + + /* + * Now that the HTC frame header has been added, the netbuf can be + * mapped. This only applies to non-data frames, since data frames + * were already mapped as they entered into the driver. + * Check the "FIXUP_NETBUF" flag to see whether this is a data netbuf + * that is already mapped, or a non-data netbuf that needs to be + * mapped. + */ + if (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) { + adf_nbuf_map( + target->osdev, + GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket), + ADF_OS_DMA_TO_DEVICE); + } + } + LOCK_HTC_TX(target); + /* store in look up queue to match completions */ +#ifdef ATH_11AC_TXCOMPACT + if (HTT_DATA_MSG_SVC != pEndpoint->ServiceID) +#endif /* ATH_11AC_TXCOMPACT */ + { + HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue,pPacket); + } + INC_HTC_EP_STAT(pEndpoint,TxIssued,1); + pEndpoint->ul_outstanding_cnt++; + UNLOCK_HTC_TX(target); + + status = HIFSend_head(target->hif_dev, + pEndpoint->UL_PipeID, pEndpoint->Id, + HTC_HDR_LENGTH + pPacket->ActualLength, + netbuf); +#if DEBUG_BUNDLE + adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n", + pEndpoint->Id, + pEndpoint->TxCreditSize, + HTC_HDR_LENGTH + pPacket->ActualLength); +#endif + + target->CE_send_cnt++; + + if (adf_os_unlikely(A_FAILED(status))) { + if (status != A_NO_RESOURCE) { + /* TODO : if more than 1 endpoint maps to the same PipeID it is possible + * to run out of resources in the HIF layer. Don't emit the error */ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HIFSend Failed status:%d \n",status)); + } + LOCK_HTC_TX(target); + target->CE_send_cnt--; + pEndpoint->ul_outstanding_cnt--; + HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue,pPacket); + /* reclaim credits */ +#if defined(HIF_USB) + if (pEndpoint->Id >= ENDPOINT_2 && pEndpoint->Id <= ENDPOINT_5) + target->avail_tx_credits += pPacket->PktInfo.AsTx.CreditsUsed; + else + pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed; +#else + pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed; +#endif + /* put it back into the callers queue */ + HTC_PACKET_ENQUEUE_TO_HEAD(pPktQueue,pPacket); + UNLOCK_HTC_TX(target); + break; + } + + } + if (adf_os_unlikely(A_FAILED(status))) { +#if defined(HIF_USB) + if (pEndpoint->Id >= ENDPOINT_2 && pEndpoint->Id <= ENDPOINT_5) + target->avail_tx_credits += pPacket->PktInfo.AsTx.CreditsUsed; + else + pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed; +#endif + while (!HTC_QUEUE_EMPTY(pPktQueue)) { + if (status != A_NO_RESOURCE) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCIssuePackets, failed pkt:0x%p status:%d \n",pPacket,status)); + } + pPacket = HTC_PACKET_DEQUEUE(pPktQueue); + if (pPacket) { + pPacket->Status = status; + SendPacketCompletion(target,pPacket); + } + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCIssuePackets \n")); + + return status; +} + + /* get HTC send packets from the TX queue on an endpoint, based on available credits */ +void GetHTCSendPacketsCreditBased(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pQueue) +{ + int creditsRequired; + int remainder; + A_UINT8 sendFlags; + HTC_PACKET *pPacket; + unsigned int transferLength; + + /****** NOTE : the TX lock is held when this function is called *****************/ + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPacketsCreditBased \n")); + + /* loop until we can grab as many packets out of the queue as we can */ + while (TRUE) { + + sendFlags = 0; + /* get packet at head, but don't remove it */ + pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue); + if (pPacket == NULL) { + break; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:%p , Queue Depth: %d\n", + pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue))); + + transferLength = pPacket->ActualLength + HTC_HDR_LENGTH; + + if (transferLength <= pEndpoint->TxCreditSize) { + creditsRequired = 1; + } else { + /* figure out how many credits this message requires */ + creditsRequired = transferLength / pEndpoint->TxCreditSize; + remainder = transferLength % pEndpoint->TxCreditSize; + + if (remainder) { + creditsRequired++; + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Credits Required:%d Got:%d\n", + creditsRequired, pEndpoint->TxCredits)); + + if (pEndpoint->Id == ENDPOINT_0) { + /* endpoint 0 is special, it always has a credit and does not require credit based + * flow control */ + creditsRequired = 0; +#if defined(HIF_USB) + } else if (pEndpoint->Id >= ENDPOINT_2 && pEndpoint->Id <= ENDPOINT_5) { + if (target->avail_tx_credits < creditsRequired) + break; + + target->avail_tx_credits -= creditsRequired; + + if (target->avail_tx_credits < 9) { + /* tell the target we need credits ASAP! */ + sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; + INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n")); + } +#endif + } else { + + if (pEndpoint->TxCredits < creditsRequired) { +#if DEBUG_CREDIT + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" EP%d, No Credit now. %d < %d\n", + pEndpoint->Id, pEndpoint->TxCredits, creditsRequired)); +#endif + break; + } + + pEndpoint->TxCredits -= creditsRequired; + INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired); + + /* check if we need credits back from the target */ + if (pEndpoint->TxCredits <= pEndpoint->TxCreditsPerMaxMsg) { + /* tell the target we need credits ASAP! */ + sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; + + if (pEndpoint->ServiceID == WMI_CONTROL_SVC) { + LOCK_HTC_CREDIT(target); + htc_credit_record(HTC_REQUEST_CREDIT, pEndpoint->TxCredits, + HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); + UNLOCK_HTC_CREDIT(target); + } + + INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1); +#if DEBUG_CREDIT + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" EP%d Needs Credits\n", pEndpoint->Id)); +#endif + } + } + + /* now we can fully dequeue */ + pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); + if (pPacket) { + /* save the number of credits this packet consumed */ + pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired; + /* save send flags */ + pPacket->PktInfo.AsTx.SendFlags = sendFlags; + + /* queue this packet into the caller's queue */ + HTC_PACKET_ENQUEUE(pQueue,pPacket); + } + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPacketsCreditBased \n")); + +} + +void GetHTCSendPackets(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pQueue, + int Resources) +{ + + HTC_PACKET *pPacket; + + /****** NOTE : the TX lock is held when this function is called *****************/ + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets %d resources\n",Resources)); + + /* loop until we can grab as many packets out of the queue as we can */ + while (Resources > 0) { + int num_frags; + + pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); + if (pPacket == NULL) { + break; + } + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got packet:%p , New Queue Depth: %d\n", + pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue))); + /* For non-credit path the sequence number is already embedded + * in the constructed HTC header + */ +#if 0 + pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo; + pEndpoint->SeqNo++; +#endif + pPacket->PktInfo.AsTx.SendFlags = 0; + pPacket->PktInfo.AsTx.CreditsUsed = 0; + /* queue this packet into the caller's queue */ + HTC_PACKET_ENQUEUE(pQueue,pPacket); + + /* + * FIX THIS: + * For now, avoid calling adf_nbuf_get_num_frags before calling + * adf_nbuf_map, because the MacOS version of adf_nbuf_t doesn't + * support adf_nbuf_get_num_frags until after adf_nbuf_map has + * been done. + * Assume that the non-data netbufs, i.e. the WMI message netbufs, + * consist of a single fragment. + */ + num_frags = + (pPacket->PktInfo.AsTx.Flags & HTC_TX_PACKET_FLAG_FIXUP_NETBUF) ? + 1 /* WMI messages are in a single-fragment network buffer */ : + adf_nbuf_get_num_frags(GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)); + Resources -= num_frags; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n")); + +} + +static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, + HTC_ENDPOINT *pEndpoint, + HTC_PACKET_QUEUE *pCallersSendQueue) +{ + HTC_PACKET_QUEUE sendQueue; /* temp queue to hold packets at various stages */ + HTC_PACKET *pPacket; + int tx_resources; + int overflow; + HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK; + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:%p Depth:%d)\n", + pCallersSendQueue, + (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue))); + + /* init the local send queue */ + INIT_HTC_PACKET_QUEUE(&sendQueue); + + do { + + if (NULL == pCallersSendQueue) { + /* caller didn't provide a queue, just wants us to check queues and send */ + break; + } + + if (HTC_QUEUE_EMPTY(pCallersSendQueue)) { + /* empty queue */ + OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,HTC_PKT_Q_EMPTY); + result = HTC_SEND_QUEUE_DROP; + break; + } + + if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) { + /* we've already overflowed */ + overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue); + } else { + /* figure out how much we will overflow by */ + overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); + overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue); + /* figure out how much we will overflow the TX queue by */ + overflow -= pEndpoint->MaxTxQueueDepth; + } + + /* if overflow is negative or zero, we are okay */ + if (overflow > 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n", + pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth)); + } + if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) { + /* all packets will fit or caller did not provide send full indication handler + * -- just move all of them to the local sendQueue object */ + HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue); + } else { + int i; + int goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow; + + A_ASSERT(goodPkts >= 0); + /* we have overflowed, and a callback is provided */ + /* dequeue all non-overflow packets into the sendqueue */ + for (i = 0; i < goodPkts; i++) { + /* pop off caller's queue*/ + pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue); + A_ASSERT(pPacket != NULL); + /* insert into local queue */ + HTC_PACKET_ENQUEUE(&sendQueue,pPacket); + } + + /* the caller's queue has all the packets that won't fit*/ + /* walk through the caller's queue and indicate each one to the send full handler */ + ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, HTC_PACKET, ListLink) { + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: %p \n", + pPacket)); + /* + * Remove headroom reserved for HTC_FRAME_HDR before giving + * the packet back to the user via the EpSendFull callback. + */ + RestoreTxPacket(target, pPacket); + + if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, + pPacket) == HTC_SEND_FULL_DROP) { + /* callback wants the packet dropped */ + INC_HTC_EP_STAT(pEndpoint, TxDropped, 1); + /* leave this one in the caller's queue for cleanup */ + } else { + /* callback wants to keep this packet, remove from caller's queue */ + HTC_PACKET_REMOVE(pCallersSendQueue, pPacket); + /* put it in the send queue */ + /* add HTC_FRAME_HDR space reservation again */ + adf_nbuf_push_head( + GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket), + sizeof(HTC_FRAME_HDR)); + + HTC_PACKET_ENQUEUE(&sendQueue,pPacket); + } + + } ITERATE_END; + + if (HTC_QUEUE_EMPTY(&sendQueue)) { + /* no packets made it in, caller will cleanup */ + OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,HTC_SEND_Q_EMPTY); + result = HTC_SEND_QUEUE_DROP; + break; + } + } + + } while (FALSE); + + if (result != HTC_SEND_QUEUE_OK) { + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); + return result; + } + + if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { + tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID); + } else { + tx_resources = 0; + } + + LOCK_HTC_TX(target); + + if (!HTC_QUEUE_EMPTY(&sendQueue)) { + /* transfer packets to tail */ + HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue); + A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue)); + INIT_HTC_PACKET_QUEUE(&sendQueue); + } + + /* increment tx processing count on entry */ + adf_os_atomic_inc(&pEndpoint->TxProcessCount); + if (adf_os_atomic_read(&pEndpoint->TxProcessCount) > 1) { + /* another thread or task is draining the TX queues on this endpoint + * that thread will reset the tx processing count when the queue is drained */ + adf_os_atomic_dec(&pEndpoint->TxProcessCount); + UNLOCK_HTC_TX(target); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n")); + return HTC_SEND_QUEUE_OK; + } + + /***** beyond this point only 1 thread may enter ******/ + + /* now drain the endpoint TX queue for transmission as long as we have enough + * transmit resources */ + while (TRUE) { + + if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) { + break; + } + + if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { +#if DEBUG_CREDIT + int cred = pEndpoint->TxCredits; +#endif + /* credit based mechanism provides flow control based on target transmit resource availability, we + * assume that the HIF layer will always have bus resources greater than target transmit resources */ + GetHTCSendPacketsCreditBased(target,pEndpoint,&sendQueue); +#if DEBUG_CREDIT + if (ep_debug_mask & (1 << pEndpoint->Id)){ + if (cred - pEndpoint->TxCredits > 0){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Decrease EP%d %d - %d = %d credits.\n", + pEndpoint->Id, cred, cred - pEndpoint->TxCredits, pEndpoint->TxCredits)); + } + } +#endif + } else { + /* get all the packets for this endpoint that we can for this pass */ + GetHTCSendPackets(target,pEndpoint,&sendQueue,tx_resources); + } + + if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) { + /* didn't get any packets due to a lack of resources or TX queue was drained */ + break; + } + + UNLOCK_HTC_TX(target); + + /* send what we can */ + HTCIssuePackets(target,pEndpoint,&sendQueue); + + if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { + tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID); + } + + LOCK_HTC_TX(target); + + } + + /* done with this endpoint, we can clear the count */ + adf_os_atomic_init(&pEndpoint->TxProcessCount); + UNLOCK_HTC_TX(target); + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); + + return HTC_SEND_QUEUE_OK; +} + +#ifdef USB_HIF_SINGLE_PIPE_DATA_SCHED +static A_UINT16 HTCSendPktsSchedCheck(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID id) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + HTC_ENDPOINT_ID eid; + HTC_PACKET_QUEUE *pTxQueue; + A_UINT16 resources; + A_UINT16 acQueueStatus[DATA_EP_SIZE] = {0, 0, 0, 0}; + + if (id < ENDPOINT_2 || id > ENDPOINT_5) { + return 1; + } + + for (eid = ENDPOINT_2; eid <= ENDPOINT_5; eid++) { + pEndpoint = &target->EndPoint[eid]; + pTxQueue = &pEndpoint->TxQueue; + + if (HTC_QUEUE_EMPTY(pTxQueue)) { + acQueueStatus[eid - 2] = 1; + } + } + + switch (id) + { + case ENDPOINT_2: //BE + return (acQueueStatus[0] && acQueueStatus[2] && acQueueStatus[3]); + case ENDPOINT_3: //BK + return (acQueueStatus[0] && acQueueStatus[1] && acQueueStatus[2] && acQueueStatus[3]); + case ENDPOINT_4: //VI + return (acQueueStatus[2] && acQueueStatus[3]); + case ENDPOINT_5: //VO + return (acQueueStatus[3]); + default: + return 0; + } + +} + +static A_STATUS HTCSendPktsSchedQueue(HTC_TARGET *target, HTC_PACKET_QUEUE *pPktQueue, HTC_ENDPOINT_ID eid) +{ + HTC_ENDPOINT *pEndpoint; + HTC_PACKET_QUEUE *pTxQueue; + HTC_PACKET *pPacket; + int goodPkts; + + pEndpoint = &target->EndPoint[eid]; + pTxQueue = &pEndpoint->TxQueue; + + LOCK_HTC_TX(target); + + goodPkts = pEndpoint->MaxTxQueueDepth - HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); + + if (goodPkts > 0){ + while (!HTC_QUEUE_EMPTY(pPktQueue)) { + pPacket = HTC_PACKET_DEQUEUE(pPktQueue); + HTC_PACKET_ENQUEUE(pTxQueue, pPacket); + goodPkts--; + + if (goodPkts <= 0) { + break; + } + } + } + + if (HTC_PACKET_QUEUE_DEPTH(pPktQueue)) { + ITERATE_OVER_LIST_ALLOW_REMOVE(&pPktQueue->QueueHead, pPacket, HTC_PACKET, ListLink) { + + if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, + pPacket) == HTC_SEND_FULL_DROP) { + INC_HTC_EP_STAT(pEndpoint, TxDropped, 1); + } else { + HTC_PACKET_REMOVE(pPktQueue, pPacket); + HTC_PACKET_ENQUEUE(pTxQueue,pPacket); + } + } ITERATE_END; + } + + UNLOCK_HTC_TX(target); + + return A_OK; +} + +#endif + +A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + HTC_PACKET *pPacket; + adf_nbuf_t netbuf; + HTC_FRAME_HDR *pHtcHdr; + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: %p, Pkts %d \n", + pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue))); + + /* get packet at head to figure out which endpoint these packets will go into */ + pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); + if (NULL == pPacket) { + OL_ATH_HTC_PKT_ERROR_COUNT_INCR(target,GET_HTC_PKT_Q_FAIL); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n")); + return A_EINVAL; + } + + AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); + pEndpoint = &target->EndPoint[pPacket->Endpoint]; + +#ifdef HTC_EP_STAT_PROFILING + LOCK_HTC_TX(target); + INC_HTC_EP_STAT(pEndpoint,TxPosted,HTC_PACKET_QUEUE_DEPTH(pPktQueue)); + UNLOCK_HTC_TX(target); +#endif + + /* provide room in each packet's netbuf for the HTC frame header */ + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) { + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + AR_DEBUG_ASSERT(netbuf); + + adf_nbuf_push_head(netbuf, sizeof(HTC_FRAME_HDR)); + /* setup HTC frame header */ + pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0); + AR_DEBUG_ASSERT(pHtcHdr); + HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) | + SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID)); + + LOCK_HTC_TX(target); + + pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo; + pEndpoint->SeqNo++; + + HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, + SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1)); + + UNLOCK_HTC_TX(target); + /* + * Now that the HTC frame header has been added, the netbuf can be + * mapped. This only applies to non-data frames, since data frames + * were already mapped as they entered into the driver. + */ + adf_nbuf_map( + target->osdev, + GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket), + ADF_OS_DMA_TO_DEVICE); + + pPacket->PktInfo.AsTx.Flags |= HTC_TX_PACKET_FLAG_FIXUP_NETBUF; + } HTC_PACKET_QUEUE_ITERATE_END; + +#ifdef USB_HIF_SINGLE_PIPE_DATA_SCHED + if (!HTCSendPktsSchedCheck(HTCHandle, pEndpoint->Id)) { + HTCSendPktsSchedQueue(HTCHandle, pPktQueue, pEndpoint->Id); + } else { + HTCTrySend(target,pEndpoint,pPktQueue); + } +#else + HTCTrySend(target,pEndpoint,pPktQueue); +#endif + + /* do completion on any packets that couldn't get in */ + if (!HTC_QUEUE_EMPTY(pPktQueue)) { + + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) { + /* remove the headroom reserved for HTC_FRAME_HDR */ + RestoreTxPacket(target, pPacket); + + if (HTC_STOPPING(target)) { + pPacket->Status = A_ECANCELED; + } else { + pPacket->Status = A_NO_RESOURCE; + } + } HTC_PACKET_QUEUE_ITERATE_END; + + DoSendCompletion(pEndpoint,pPktQueue); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n")); + + return A_OK; +} + +/* HTC API - HTCSendPkt */ +A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +{ + HTC_PACKET_QUEUE queue; + + if (HTCHandle == NULL || pPacket == NULL) { + return A_ERROR; + } + a_mem_trace(GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, + ("+-HTCSendPkt: Enter endPointId: %d, buffer: %p, length: %d \n", + pPacket->Endpoint, pPacket->pBuffer, pPacket->ActualLength)); + INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); + return HTCSendPktsMultiple(HTCHandle, &queue); +} + +#ifdef ATH_11AC_TXCOMPACT + +A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, adf_nbuf_t netbuf, int Epid, int ActualLength) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + HTC_FRAME_HDR *pHtcHdr; + A_STATUS status = A_OK; + int tx_resources; + + pEndpoint = &target->EndPoint[Epid]; + + tx_resources = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID); + + if(tx_resources < HTC_DATA_RESOURCE_THRS){ + if (pEndpoint->ul_is_polled){ + HIFSendCompleteCheck( + pEndpoint->target->hif_dev, pEndpoint->UL_PipeID, 1); + tx_resources = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID); + } + if(tx_resources < HTC_DATA_MINDESC_PERPACKET){ + return A_ERROR; + } + } + + pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0); + AR_DEBUG_ASSERT(pHtcHdr); + + HTC_WRITE32(pHtcHdr, SM(ActualLength, HTC_FRAME_HDR_PAYLOADLEN) | + SM(Epid, HTC_FRAME_HDR_ENDPOINTID)); + /* + * If the HIF pipe for the data endpoint is polled rather than + * interrupt-driven, this is a good point to check whether any + * data previously sent through the HIF pipe have finished being + * sent. + * Since this may result in callbacks to HTCTxCompletionHandler, + * which can take the HTC tx lock, make the HIFSendCompleteCheck + * call before acquiring the HTC tx lock. + * Call HIFSendCompleteCheck directly, rather than calling + * HTCSendCompleteCheck, and call the PollTimerStart separately + * after calling HIFSend_head, so the timer will be started to + * check for completion of the new outstanding download (in the + * unexpected event that other polling calls don't catch it). + */ + + LOCK_HTC_TX(target); + + HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, SM(pEndpoint->SeqNo, HTC_FRAME_HDR_CONTROLBYTES1)); + + pEndpoint->SeqNo++; + + status = HIFSend_head(target->hif_dev, + pEndpoint->UL_PipeID, + pEndpoint->Id, + ActualLength, + netbuf); + + + UNLOCK_HTC_TX(target); + return status ; +} +#else /*ATH_11AC_TXCOMPACT*/ + +A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket, + A_UINT8 more_data) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint; + HTC_FRAME_HDR *pHtcHdr; + HTC_PACKET_QUEUE sendQueue; + adf_nbuf_t netbuf; + int tx_resources; + A_STATUS status = A_OK; + if (pPacket){ + AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); + pEndpoint = &target->EndPoint[pPacket->Endpoint]; + + /* add HTC_FRAME_HDR in the initial fragment */ + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + pHtcHdr = (HTC_FRAME_HDR *) adf_nbuf_get_frag_vaddr(netbuf, 0); + AR_DEBUG_ASSERT(pHtcHdr); + + HTC_WRITE32(pHtcHdr, SM(pPacket->ActualLength, HTC_FRAME_HDR_PAYLOADLEN) | + SM(pPacket->PktInfo.AsTx.SendFlags, HTC_FRAME_HDR_FLAGS) | + SM(pPacket->Endpoint, HTC_FRAME_HDR_ENDPOINTID)); + /* + * If the HIF pipe for the data endpoint is polled rather than + * interrupt-driven, this is a good point to check whether any + * data previously sent through the HIF pipe have finished being + * sent. + * Since this may result in callbacks to HTCTxCompletionHandler, + * which can take the HTC tx lock, make the HIFSendCompleteCheck + * call before acquiring the HTC tx lock. + * Call HIFSendCompleteCheck directly, rather than calling + * HTCSendCompleteCheck, and call the PollTimerStart separately + * after calling HIFSend_head, so the timer will be started to + * check for completion of the new outstanding download (in the + * unexpected event that other polling calls don't catch it). + */ + if (pEndpoint->ul_is_polled) { + HTCSendCompletePollTimerStop(pEndpoint); + HIFSendCompleteCheck( + pEndpoint->target->hif_dev, pEndpoint->UL_PipeID, 0); + } + + LOCK_HTC_TX(target); + + pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo; + pEndpoint->SeqNo++; + + + HTC_WRITE32(((A_UINT32 *)pHtcHdr) + 1, SM(pPacket->PktInfo.AsTx.SeqNo, HTC_FRAME_HDR_CONTROLBYTES1)); + + /* append new packet to pEndpoint->TxQueue */ + HTC_PACKET_ENQUEUE(&pEndpoint->TxQueue, pPacket); +#ifdef ENABLE_BUNDLE_TX + if (HTC_ENABLE_BUNDLE(target) && (more_data)) { + UNLOCK_HTC_TX(target); + return A_OK; + } +#endif + } else { + LOCK_HTC_TX(target); + pEndpoint = &target->EndPoint[1]; + } + + /* increment tx processing count on entry */ + adf_os_atomic_inc(&pEndpoint->TxProcessCount); + if (adf_os_atomic_read(&pEndpoint->TxProcessCount) > 1) { + /* + * Another thread or task is draining the TX queues on this endpoint. + * That thread will reset the tx processing count when the queue is + * drained. + */ + adf_os_atomic_dec(&pEndpoint->TxProcessCount); + UNLOCK_HTC_TX(target); + return A_OK; + } + + /***** beyond this point only 1 thread may enter ******/ + + INIT_HTC_PACKET_QUEUE(&sendQueue); + if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { +#if DEBUG_CREDIT + int cred = pEndpoint->TxCredits; +#endif + GetHTCSendPacketsCreditBased(target, pEndpoint, &sendQueue); +#if DEBUG_CREDIT + if (ep_debug_mask & (1 << pEndpoint->Id)){ + if (cred - pEndpoint->TxCredits > 0){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Decrease EP%d %d - %d = %d credits.\n", + pEndpoint->Id, cred, cred - pEndpoint->TxCredits, pEndpoint->TxCredits)); + } + } +#endif + UNLOCK_HTC_TX(target); + } +#ifdef ENABLE_BUNDLE_TX + else if (HTC_ENABLE_BUNDLE(target)) { + /* Dequeue max packets from endpoint tx queue */ + GetHTCSendPackets(target, pEndpoint, &sendQueue, + HTC_MAX_TX_BUNDLE_SEND_LIMIT); + UNLOCK_HTC_TX(target); + } +#endif + else { + /* + * Now drain the endpoint TX queue for transmission as long as we have + * enough transmit resources + */ + tx_resources = HIFGetFreeQueueNumber(target->hif_dev,pEndpoint->UL_PipeID); + GetHTCSendPackets(target, pEndpoint, &sendQueue, tx_resources); + UNLOCK_HTC_TX(target); + } + /* send what we can */ + while (TRUE) { +#if defined(HIF_USB) || defined(HIF_SDIO) +#ifdef ENABLE_BUNDLE_TX + if (HTC_ENABLE_BUNDLE(target) && + HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_MSG_PER_BUNDLE) { + HTCIssuePacketsBundle(target, pEndpoint, &sendQueue); + } +#endif +#endif + pPacket = HTC_PACKET_DEQUEUE(&sendQueue); + if (pPacket == NULL){ + break; + } + netbuf = GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket); + + LOCK_HTC_TX(target); + /* store in look up queue to match completions */ + HTC_PACKET_ENQUEUE(&pEndpoint->TxLookupQueue,pPacket); + INC_HTC_EP_STAT(pEndpoint,TxIssued,1); + pEndpoint->ul_outstanding_cnt++; + UNLOCK_HTC_TX(target); + + status = HIFSend_head(target->hif_dev, + pEndpoint->UL_PipeID, + pEndpoint->Id, + HTC_HDR_LENGTH + pPacket->ActualLength, + netbuf); +#if DEBUG_BUNDLE + adf_os_print(" Send single EP%d buffer size:0x%x, total:0x%x.\n", + pEndpoint->Id, + pEndpoint->TxCreditSize, + HTC_HDR_LENGTH + pPacket->ActualLength); +#endif + + if (adf_os_unlikely(A_FAILED(status))) { + LOCK_HTC_TX(target); + pEndpoint->ul_outstanding_cnt--; + /* remove this packet from the tx completion queue */ + HTC_PACKET_REMOVE(&pEndpoint->TxLookupQueue,pPacket); + + /* + * Don't bother reclaiming credits - HTC flow control + * is not applicable to tx data. + * In LL systems, there is no download flow control, + * since there's virtually no download delay. + * In HL systems, the txrx SW explicitly performs the + * tx flow control. + */ + //pEndpoint->TxCredits += pPacket->PktInfo.AsTx.CreditsUsed; + + /* put this frame back at the front of the sendQueue */ + HTC_PACKET_ENQUEUE_TO_HEAD(&sendQueue, pPacket); + + /* put the sendQueue back at the front of pEndpoint->TxQueue */ + HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxQueue, &sendQueue); + UNLOCK_HTC_TX(target); + break; /* still need to reset TxProcessCount */ + } + } + /* done with this endpoint, we can clear the count */ + adf_os_atomic_init(&pEndpoint->TxProcessCount); + + if (pEndpoint->ul_is_polled) { + /* + * Start a cleanup timer to poll for download completion. + * The download completion should be noticed promptly from + * other polling calls, but the timer provides a safety net + * in case other polling calls don't occur as expected. + */ + HTCSendCompletePollTimerStart(pEndpoint); + } + + return status; +} +#endif /*ATH_11AC_TXCOMPACT*/ + +/* + * In the adapted HIF layer, adf_nbuf_t are passed between HIF and HTC, since upper layers expects + * HTC_PACKET containers we use the completed netbuf and lookup its corresponding HTC packet buffer + * from a lookup list. + * This is extra overhead that can be fixed by re-aligning HIF interfaces with HTC. + * + */ +static HTC_PACKET *HTCLookupTxPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, adf_nbuf_t netbuf) +{ + HTC_PACKET *pPacket = NULL; + HTC_PACKET *pFoundPacket = NULL; + HTC_PACKET_QUEUE lookupQueue; + + INIT_HTC_PACKET_QUEUE(&lookupQueue); + LOCK_HTC_TX(target); + + /* mark that HIF has indicated the send complete for another packet */ + pEndpoint->ul_outstanding_cnt--; + + /* Dequeue first packet directly because of in-order completion */ + pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxLookupQueue); + if (adf_os_unlikely(!pPacket)) { + UNLOCK_HTC_TX(target); + return NULL; + } + if (netbuf == (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)) { + UNLOCK_HTC_TX(target); + return pPacket; + } else { + HTC_PACKET_ENQUEUE(&lookupQueue, pPacket); + } + + /* + * Move TX lookup queue to temp queue because most of packets that are not index 0 + * are not top 10 packets. + */ + HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&lookupQueue, &pEndpoint->TxLookupQueue); + UNLOCK_HTC_TX(target); + + ITERATE_OVER_LIST_ALLOW_REMOVE(&lookupQueue.QueueHead,pPacket,HTC_PACKET,ListLink) { + + if (NULL == pPacket){ + pFoundPacket = pPacket; + break; + } + /* check for removal */ + if (netbuf == (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pPacket)) { + /* found it */ + HTC_PACKET_REMOVE(&lookupQueue, pPacket); + pFoundPacket = pPacket; + break; + } + + } ITERATE_END; + + LOCK_HTC_TX(target); + HTC_PACKET_QUEUE_TRANSFER_TO_HEAD(&pEndpoint->TxLookupQueue, &lookupQueue); + UNLOCK_HTC_TX(target); + + return pFoundPacket; +} + + +A_STATUS HTCTxCompletionHandler(void *Context, + adf_nbuf_t netbuf, + unsigned int EpID) +{ + HTC_TARGET *target = (HTC_TARGET *)Context; + HTC_ENDPOINT *pEndpoint; + HTC_PACKET *pPacket; +#ifdef USB_HIF_SINGLE_PIPE_DATA_SCHED + HTC_ENDPOINT_ID eid[DATA_EP_SIZE] = {ENDPOINT_5, ENDPOINT_4, ENDPOINT_2, ENDPOINT_3}; + int epidIdx; + A_UINT16 resourcesThresh[DATA_EP_SIZE]; //urb resources + A_UINT16 resources; + A_UINT16 resourcesMax; +#endif + + pEndpoint = &target->EndPoint[EpID]; + target->TX_comp_cnt++; + + do { + pPacket = HTCLookupTxPacket(target, pEndpoint, netbuf); + if (NULL == pPacket) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC TX lookup failed!\n")); + /* may have already been flushed and freed */ + netbuf = NULL; + break; + } + a_mem_trace(netbuf); + if (pPacket->PktInfo.AsTx.Tag == HTC_TX_PACKET_TAG_BUNDLED){ + HTC_PACKET *pPacketTemp; + HTC_PACKET_QUEUE *pQueueSave = (HTC_PACKET_QUEUE *)pPacket->pContext; + HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQueueSave, pPacketTemp){ + pPacket->Status = A_OK; + SendPacketCompletion(target,pPacketTemp); + }HTC_PACKET_QUEUE_ITERATE_END; + FreeHTCBundlePacket(target, pPacket); + return A_OK; + } + /* will be giving this buffer back to upper layers */ + netbuf = NULL; + pPacket->Status = A_OK; + SendPacketCompletion(target,pPacket); + + } while (FALSE); + + if (!IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { +#ifdef USB_HIF_SINGLE_PIPE_DATA_SCHED + if ((HTC_ENDPOINT_ID)EpID >= ENDPOINT_2 && + (HTC_ENDPOINT_ID)EpID <= ENDPOINT_5) { + + resourcesMax = HIFGetMaxQueueNumber(target->hif_dev, pEndpoint->UL_PipeID); + + resourcesThresh[0] = 0; //VO + resourcesThresh[1] = (resourcesMax * 2) / 32; //VI + resourcesThresh[2] = (resourcesMax * 3) / 32; //BE + resourcesThresh[3] = (resourcesMax * 4) / 32; //BK + + resources = HIFGetFreeQueueNumber(target->hif_dev, pEndpoint->UL_PipeID); + + for (epidIdx = 0; epidIdx < DATA_EP_SIZE; epidIdx++) { + + pEndpoint = &target->EndPoint[eid[epidIdx]]; + + if (!HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) { + continue; + } + + if (resources >= resourcesThresh[epidIdx]) { + break; + } + } + + if (epidIdx == DATA_EP_SIZE) { + #if 0 + if (resources) { + for (epidIdx = 0; epidIdx < DATA_EP_SIZE; epidIdx++) { + + pEndpoint = &target->EndPoint[eid[epidIdx]]; + + if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) { + break; + } + } + } else + #endif + return A_OK; + } + } +#endif + + /* note: when using TX credit flow, the re-checking of queues happens + * when credits flow back from the target. + * in the non-TX credit case, we recheck after the packet completes */ + HTCTrySend(target,pEndpoint,NULL); + } + + return A_OK; +} + + /* callback when TX resources become available */ +void HTCTxResourceAvailHandler(void *context, A_UINT8 pipeID) +{ + int i; + HTC_TARGET *target = (HTC_TARGET *)context; + HTC_ENDPOINT *pEndpoint = NULL; + + for (i = 0; i < ENDPOINT_MAX; i++) { + pEndpoint = &target->EndPoint[i]; + if (pEndpoint->ServiceID != 0) { + if (pEndpoint->UL_PipeID == pipeID) { + break; + } + } + } + + if (i >= ENDPOINT_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid pipe indicated for TX resource avail : %d!\n",pipeID)); + return; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HIF indicated more resources for pipe:%d \n",pipeID)); + + HTCTrySend(target,pEndpoint,NULL); +} + +/* flush endpoint TX queue */ +void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag) +{ + HTC_PACKET *pPacket; + + LOCK_HTC_TX(target); + while(HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)){ + pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); + + if (pPacket) { + /* let the sender know the packet was not delivered */ + pPacket->Status = A_ECANCELED; + SendPacketCompletion(target, pPacket); + } + } + UNLOCK_HTC_TX(target); +} + +/* HTC API to flush an endpoint's TX queue*/ +void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; + + if (pEndpoint->ServiceID == 0) { + AR_DEBUG_ASSERT(FALSE); + /* not in use.. */ + return; + } + + HTCFlushEndpointTX(target,pEndpoint,Tag); +} + +/* HTC API to indicate activity to the credit distribution function */ +void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint, + A_BOOL Active) +{ + /* TODO */ +} + +A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle, + HTC_ENDPOINT_ID Endpoint) +{ + return TRUE; +} + +/* process credit reports and call distribution function */ +void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) +{ + int i; + HTC_ENDPOINT *pEndpoint; + int totalCredits = 0; + A_UINT8 rpt_credits, rpt_ep_id; + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries)); + + /* lock out TX while we update credits */ + LOCK_HTC_TX(target); + + + for (i = 0; i < NumEntries; i++, pRpt++) { + + rpt_ep_id = HTC_GET_FIELD(pRpt, HTC_CREDIT_REPORT, ENDPOINTID); + + if (rpt_ep_id >= ENDPOINT_MAX) { + AR_DEBUG_ASSERT(FALSE); + break; + } + + rpt_credits = HTC_GET_FIELD(pRpt, HTC_CREDIT_REPORT, CREDITS); + + pEndpoint = &target->EndPoint[rpt_ep_id]; +#if DEBUG_CREDIT + if (ep_debug_mask & (1 << pEndpoint->Id)){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Increase EP%d %d + %d = %d credits\n", + rpt_ep_id, pEndpoint->TxCredits, rpt_credits, pEndpoint->TxCredits + rpt_credits)); + } +#endif + +#ifdef HTC_EP_STAT_PROFILING + + INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1); + INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, rpt_credits); + + if (FromEndpoint == rpt_ep_id) { + /* this credit report arrived on the same endpoint indicating it arrived in an RX + * packet */ + INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, rpt_credits); + INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1); + } else if (FromEndpoint == ENDPOINT_0) { + /* this credit arrived on endpoint 0 as a NULL message */ + INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, rpt_credits); + INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1); + } else { + /* arrived on another endpoint */ + INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, rpt_credits); + INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1); + } + +#endif +#if defined(HIF_USB) + if (pEndpoint->Id >= ENDPOINT_2 && pEndpoint->Id <= ENDPOINT_5) { + HTC_ENDPOINT_ID eid[DATA_EP_SIZE] = {ENDPOINT_5, ENDPOINT_4, ENDPOINT_2, ENDPOINT_3}; + int epid_idx; + + target->avail_tx_credits += rpt_credits; + + for (epid_idx = 0; epid_idx < DATA_EP_SIZE; epid_idx++) { + pEndpoint = &target->EndPoint[eid[epid_idx]]; + if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) { + break; + } + + } + UNLOCK_HTC_TX(target); + HTCTrySend(target,pEndpoint,NULL); + LOCK_HTC_TX(target); + } else { + pEndpoint->TxCredits += rpt_credits; + + if (pEndpoint->TxCredits && HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) { + UNLOCK_HTC_TX(target); + HTCTrySend(target,pEndpoint,NULL); + LOCK_HTC_TX(target); + } + } +#else + pEndpoint->TxCredits += rpt_credits; + + if (pEndpoint->ServiceID == WMI_CONTROL_SVC) { + LOCK_HTC_CREDIT(target); + htc_credit_record(HTC_PROCESS_CREDIT_REPORT, pEndpoint->TxCredits, + HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); + UNLOCK_HTC_CREDIT(target); + } + + if (pEndpoint->TxCredits && HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)) { + UNLOCK_HTC_TX(target); +#ifdef ATH_11AC_TXCOMPACT + HTCTrySend(target,pEndpoint,NULL); +#else + if (pEndpoint->ServiceID == HTT_DATA_MSG_SVC){ + HTCSendDataPkt(target, NULL, 0); + } else { + HTCTrySend(target,pEndpoint,NULL); + } +#endif + LOCK_HTC_TX(target); + } +#endif + totalCredits += rpt_credits; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits)); + + UNLOCK_HTC_TX(target); + + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n")); +} + +/* function to fetch stats from htc layer*/ +struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE HTCHandle) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + + return(&(target->htc_pkt_stats)); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_services.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_services.c new file mode 100644 index 0000000000000..948ef5c811e72 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HTC/htc_services.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "htc_debug.h" +#include "htc_internal.h" +#include /* adf_nbuf_t */ +#if defined(HIF_PCI) +#include "if_pci.h" +#endif + +extern unsigned int htc_credit_flow; + +#ifndef DEBUG_CREDIT +#define DEBUG_CREDIT 0 +#endif + +A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, + HTC_SERVICE_CONNECT_REQ *pConnectReq, + HTC_SERVICE_CONNECT_RESP *pConnectResp) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + A_STATUS status = A_OK; + HTC_PACKET *pSendPacket = NULL; + HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; + HTC_CONNECT_SERVICE_MSG *pConnectMsg; + HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; + HTC_ENDPOINT *pEndpoint; + unsigned int maxMsgSize = 0; + adf_nbuf_t netbuf; + A_UINT8 txAlloc; + int length; + A_BOOL disableCreditFlowCtrl = FALSE; + A_UINT16 conn_flags; + A_UINT16 rsp_msg_id, rsp_msg_serv_id, rsp_msg_max_msg_size; + A_UINT8 rsp_msg_status, rsp_msg_end_id, rsp_msg_serv_meta_len; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:%p SvcID:0x%X \n", + target, pConnectReq->ServiceID)); + + do { + + AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0); + + if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) { + /* special case for pseudo control service */ + assignedEndpoint = ENDPOINT_0; + maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; + txAlloc = 0; + + } else { + + txAlloc = HTCGetCreditAllocation(target,pConnectReq->ServiceID); + if (!txAlloc) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Service %d does not allocate target credits!\n", + pConnectReq->ServiceID)); + } + + /* allocate a packet to send to the target */ + pSendPacket = HTCAllocControlTxPacket(target); + + if (NULL == pSendPacket) { + AR_DEBUG_ASSERT(FALSE); + status = A_NO_MEMORY; + break; + } + + netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket); + length = sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectReq->MetaDataLength; + + /* assemble connect service message */ + adf_nbuf_put_tail(netbuf, length); + pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)adf_nbuf_data(netbuf); + + if (NULL == pConnectMsg) { + AR_DEBUG_ASSERT(0); + status = A_EFAULT; + break; + } + + A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG)); + + conn_flags = (pConnectReq->ConnectionFlags & ~HTC_SET_RECV_ALLOC_MASK) | + HTC_CONNECT_FLAGS_SET_RECV_ALLOCATION(txAlloc); + HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, MESSAGEID, + HTC_MSG_CONNECT_SERVICE_ID); + HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, SERVICE_ID, + pConnectReq->ServiceID); + HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, + CONNECTIONFLAGS, conn_flags); + + if (pConnectReq->ConnectionFlags & HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL) { + disableCreditFlowCtrl = TRUE; + } +#if defined(HIF_USB) + if (!htc_credit_flow) { + disableCreditFlowCtrl = TRUE; + } +#else + /* Only enable credit for WMI service */ + if (!htc_credit_flow && pConnectReq->ServiceID != WMI_CONTROL_SVC) { + disableCreditFlowCtrl = TRUE; + } +#endif + /* check caller if it wants to transfer meta data */ + if ((pConnectReq->pMetaData != NULL) && + (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { + /* copy meta data into message buffer (after header ) */ + A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), + pConnectReq->pMetaData, + pConnectReq->MetaDataLength); + + HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, + SERVICEMETALENGTH, pConnectReq->MetaDataLength); + } + + SET_HTC_PACKET_INFO_TX(pSendPacket, + NULL, + (A_UINT8 *)pConnectMsg, + length, + ENDPOINT_0, + HTC_SERVICE_TX_PACKET_TAG); + + + status = HTCSendPkt((HTC_HANDLE)target,pSendPacket); + /* we don't own it anymore */ + pSendPacket = NULL; + if (A_FAILED(status)) { + break; + } + + /* wait for response */ + status = HTCWaitRecvCtrlMessage(target); + if (A_FAILED(status)) { + break; + } + /* we controlled the buffer creation so it has to be properly aligned */ + pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)target->CtrlResponseBuffer; + + rsp_msg_id = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, MESSAGEID); + rsp_msg_serv_id = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEID); + rsp_msg_status = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, STATUS); + rsp_msg_end_id = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, ENDPOINTID); + rsp_msg_max_msg_size = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, MAXMSGSIZE); + rsp_msg_serv_meta_len = HTC_GET_FIELD(pResponseMsg, + HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEMETALENGTH); + + + if ((rsp_msg_id != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || + (target->CtrlResponseLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { + /* this message is not valid */ + AR_DEBUG_ASSERT(FALSE); + status = A_EPROTO; + break; + } + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + ("HTCConnectService, service 0x%X connect response from target status:%d, assigned ep: %d\n", + rsp_msg_serv_id, rsp_msg_status, rsp_msg_end_id)); + + pConnectResp->ConnectRespCode = rsp_msg_status; + + /* check response status */ + if (rsp_msg_status != HTC_SERVICE_SUCCESS) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + (" Target failed service 0x%X connect request (status:%d)\n", + rsp_msg_serv_id, rsp_msg_status)); + status = A_EPROTO; +#ifdef QCA_TX_HTT2_SUPPORT + /* Keep work and not to block the control message. */ + target->CtrlResponseProcessing = FALSE; +#endif /* QCA_TX_HTT2_SUPPORT */ + break; + } + + assignedEndpoint = (HTC_ENDPOINT_ID)rsp_msg_end_id; + maxMsgSize = rsp_msg_max_msg_size; + + if ((pConnectResp->pMetaData != NULL) && + (rsp_msg_serv_meta_len > 0) && + (rsp_msg_serv_meta_len <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { + /* caller supplied a buffer and the target responded with data */ + int copyLength = min((int)pConnectResp->BufferLength, (int)rsp_msg_serv_meta_len); + /* copy the meta data */ + A_MEMCPY(pConnectResp->pMetaData, + ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), + copyLength); + pConnectResp->ActualLength = copyLength; + } + /* done processing response buffer */ + target->CtrlResponseProcessing = FALSE; + } + + /* the rest of these are parameter checks so set the error status */ + status = A_EPROTO; + + if (assignedEndpoint >= ENDPOINT_MAX) { + AR_DEBUG_ASSERT(FALSE); + break; + } + + if (0 == maxMsgSize) { + AR_DEBUG_ASSERT(FALSE); + break; + } + + pEndpoint = &target->EndPoint[assignedEndpoint]; + pEndpoint->Id = assignedEndpoint; + if (pEndpoint->ServiceID != 0) { + /* endpoint already in use! */ + AR_DEBUG_ASSERT(FALSE); + break; + } + + /* return assigned endpoint to caller */ + pConnectResp->Endpoint = assignedEndpoint; + pConnectResp->MaxMsgLength = maxMsgSize; + + /* setup the endpoint */ + pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */ + pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth; + pEndpoint->MaxMsgLength = maxMsgSize; + pEndpoint->TxCredits = txAlloc; + pEndpoint->TxCreditSize = target->TargetCreditSize; + pEndpoint->TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize; + if (maxMsgSize % target->TargetCreditSize) { + pEndpoint->TxCreditsPerMaxMsg++; + } +#if DEBUG_CREDIT + adf_os_print(" Endpoint%d initial credit:%d, size:%d.\n", + pEndpoint->Id, pEndpoint->TxCredits, pEndpoint->TxCreditSize); +#endif + + /* copy all the callbacks */ + pEndpoint->EpCallBacks = pConnectReq->EpCallbacks; + + status = HIFMapServiceToPipe(target->hif_dev, + pEndpoint->ServiceID, + &pEndpoint->UL_PipeID, + &pEndpoint->DL_PipeID, + &pEndpoint->ul_is_polled, + &pEndpoint->dl_is_polled); + if (A_FAILED(status)) { + break; + } + + adf_os_assert(!pEndpoint->dl_is_polled); /* not currently supported */ + + if (pEndpoint->ul_is_polled) { + adf_os_timer_init( + target->osdev, + &pEndpoint->ul_poll_timer, + HTCSendCompleteCheckCleanup, + pEndpoint, ADF_DEFERRABLE_TIMER); + } + + AR_DEBUG_PRINTF(ATH_DEBUG_SETUP, ("HTC Service:0x%4.4X, ULpipe:%d DLpipe:%d id:%d Ready\n", + pEndpoint->ServiceID,pEndpoint->UL_PipeID,pEndpoint->DL_PipeID,pEndpoint->Id)); + + if (disableCreditFlowCtrl && pEndpoint->TxCreditFlowEnabled) { + pEndpoint->TxCreditFlowEnabled = FALSE; + AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HTC Service:0x%4.4X ep:%d TX flow control disabled\n", + pEndpoint->ServiceID, assignedEndpoint)); + } + + } while (FALSE); + + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n")); + + return status; +} + + +void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, + void *pCreditDistContext, + HTC_CREDIT_DIST_CALLBACK CreditDistFunc, + HTC_CREDIT_INIT_CALLBACK CreditInitFunc, + HTC_SERVICE_ID ServicePriorityOrder[], + int ListLength) +{ + /* NOT Supported, this transport does not use a credit based flow control mechanism */ + +} + + +void HTCFwEventHandler(void *context, A_STATUS status) +{ + HTC_TARGET *target = (HTC_TARGET *)context; + HTC_INIT_INFO *initInfo = &target->HTCInitInfo; + + /* check if target failure handler exists and pass error code to it. */ + if (target->HTCInitInfo.TargetFailure != NULL) { + initInfo->TargetFailure(initInfo->pContext, status); + } +} + +/* Disable ASPM : disable PCIe low power */ +void htc_disable_aspm(void) +{ +#if defined(HIF_PCI) + hif_disable_aspm(); +#endif +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.c new file mode 100644 index 0000000000000..39bbe313aadb5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.c @@ -0,0 +1,680 @@ +/* + * Copyright (c) 2011,2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting + * Copyright (c) 2005-2006 Atheros Communications, Inc. + * Copyright (c) 2010, Atheros Communications Inc. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. The materials contained herein are unmodified and are used + * unmodified. + * 2. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following NO + * ''WARRANTY'' disclaimer below (''Disclaimer''), without + * modification. + * 3. Redistributions in binary form must reproduce at minimum a + * disclaimer similar to the Disclaimer below and any redistribution + * must be conditioned upon including a substantially similar + * Disclaimer requirement for further binary redistribution. + * 4. Neither the names of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote + * product derived from this software without specific prior written + * permission. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE + * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +#include +#include "wma.h" +#include "regdomain.h" +#include "regdomain_common.h" + +#define N(a) (sizeof(a)/sizeof(a[0])) + +static regdm_supp_op_classes regdm_curr_supp_opp_classes = {0}; + +/* Global Operating Classes */ +regdm_op_class_map_t global_op_class[] = { + {81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {82, 25, BW20, {14}}, + {83, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {84, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {115, 20, BW20, {36, 40, 44, 48}}, + {116, 40, BW40_LOW_PRIMARY, {36, 44}}, + {117, 40, BW40_HIGH_PRIMARY, {40, 48}}, + {118, 20, BW20, {52, 56, 60, 64}}, + {119, 40, BW40_LOW_PRIMARY, {52, 60}}, + {120, 40, BW40_HIGH_PRIMARY, {56, 64}}, + {121, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {122, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132}}, + {123, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136}}, + {125, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {126, 40, BW40_LOW_PRIMARY, {149, 157}}, + {127, 40, BW40_HIGH_PRIMARY, {153, 161}}, + {0, 0, 0, {0}}, +}; + +/* Operating Classes in US */ +regdm_op_class_map_t us_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {5, 20, BW20, {149, 153, 157, 161, 165}}, + {12, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, + {22, 40, BW40_LOW_PRIMARY, {36, 44}}, + {23, 40, BW40_LOW_PRIMARY, {52, 60}}, + {24, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132}}, + {26, 40, BW40_LOW_PRIMARY, {149, 157}}, + {27, 40, BW40_HIGH_PRIMARY, {40, 48}}, + {28, 40, BW40_HIGH_PRIMARY, {56, 64}}, + {29, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136}}, + {31, 40, BW40_HIGH_PRIMARY, {153, 161}}, + {32, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7}}, + {33, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11}}, + {0, 0, 0, {0}}, +}; + +/* Operating Classes in Europe */ +regdm_op_class_map_t euro_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {5, 40, BW40_LOW_PRIMARY, {36, 44}}, + {6, 40, BW40_LOW_PRIMARY, {52, 60}}, + {7, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132}}, + {8, 40, BW40_HIGH_PRIMARY, {40, 48}}, + {9, 40, BW40_HIGH_PRIMARY, {56, 64}}, + {10, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136}}, + {11, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {12, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {17, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {0, 0, 0, {0}}, +}; + +/* Operating Classes in Japan */ +regdm_op_class_map_t japan_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {31, 25, BW20, {14}}, + {32, 20, BW20, {52, 56, 60, 64}}, + {34, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {36, 40, BW40_LOW_PRIMARY, {36, 44}}, + {37, 40, BW40_LOW_PRIMARY, {52, 60}}, + {39, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132}}, + {41, 40, BW40_HIGH_PRIMARY, {40, 48}}, + {42, 40, BW40_HIGH_PRIMARY, {56, 64}}, + {44, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136}}, + {0, 0, 0, {0}}, +}; + +/* + * By default, the regdomain tables reference the common tables + * from regdomain_common.h. These default tables can be replaced + * by calls to populate_regdomain_tables functions. + */ +HAL_REG_DMN_TABLES ol_regdmn_Rdt = { + ahCmnRegDomainPairs, /* regDomainPairs */ + ahCmnAllCountries, /* allCountries */ + ahCmnRegDomains, /* allRegDomains */ + N(ahCmnRegDomainPairs), /* regDomainPairsCt */ + N(ahCmnAllCountries), /* allCountriesCt */ + N(ahCmnRegDomains), /* allRegDomainCt */ +}; + +static u_int16_t get_eeprom_rd(u_int16_t rd) +{ + return rd & ~WORLDWIDE_ROAMING_FLAG; +} + +/* + * Return whether or not the regulatory domain/country in EEPROM + * is acceptable. + */ +static bool regdmn_is_eeprom_valid(u_int16_t rd) +{ + int32_t i; + + if (rd & COUNTRY_ERD_FLAG) { + u_int16_t cc = rd & ~COUNTRY_ERD_FLAG; + for (i = 0; i < ol_regdmn_Rdt.allCountriesCt; i++) + if (ol_regdmn_Rdt.allCountries[i].countryCode == cc) + return true; + } else { + for (i = 0; i < ol_regdmn_Rdt.regDomainPairsCt; i++) + if (ol_regdmn_Rdt.regDomainPairs[i].regDmnEnum == rd) + return true; + } + /* TODO: Bring it under debug level */ + adf_os_print("%s: invalid regulatory domain/country code 0x%x\n", + __func__, rd); + return false; +} + +/* + * Find the pointer to the country element in the country table + * corresponding to the country code + */ +static const COUNTRY_CODE_TO_ENUM_RD *find_country(u_int16_t country_code) +{ + int32_t i; + + for (i = 0; i < ol_regdmn_Rdt.allCountriesCt; i++) { + if (ol_regdmn_Rdt.allCountries[i].countryCode == country_code) + return &ol_regdmn_Rdt.allCountries[i]; + } + return NULL; /* Not found */ +} + +int32_t regdmn_find_ctry_by_name(u_int8_t *alpha2) +{ + int32_t i; + + for (i = 0; i < ol_regdmn_Rdt.allCountriesCt; i++) { + if (ol_regdmn_Rdt.allCountries[i].isoName[0] == alpha2[0] && + ol_regdmn_Rdt.allCountries[i].isoName[1] == alpha2[1]) + return ol_regdmn_Rdt.allCountries[i].countryCode; + } + return CTRY_DEFAULT; /* Not found */ +} + +static u_int16_t regdmn_get_default_country(u_int16_t rd) +{ + int32_t i; + + if (rd & COUNTRY_ERD_FLAG) { + const COUNTRY_CODE_TO_ENUM_RD *country = NULL; + u_int16_t cc = rd & ~COUNTRY_ERD_FLAG; + + country = find_country(cc); + if (country) + return cc; + } + + /* + * Check reg domains that have only one country + */ + for (i = 0; i < ol_regdmn_Rdt.regDomainPairsCt; i++) { + if (ol_regdmn_Rdt.regDomainPairs[i].regDmnEnum == rd) { + if (ol_regdmn_Rdt.regDomainPairs[i].singleCC != 0) + return ol_regdmn_Rdt.regDomainPairs[i].singleCC; + else + i = ol_regdmn_Rdt.regDomainPairsCt; + } + } + return CTRY_DEFAULT; +} + +static const REG_DMN_PAIR_MAPPING *get_regdmn_pair(u_int16_t reg_dmn) +{ + int32_t i; + + for (i = 0; i < ol_regdmn_Rdt.regDomainPairsCt; i++) { + if (ol_regdmn_Rdt.regDomainPairs[i].regDmnEnum == reg_dmn) + return &ol_regdmn_Rdt.regDomainPairs[i]; + } + return NULL; +} + +static const REG_DOMAIN *get_regdmn(u_int16_t reg_dmn) +{ + int32_t i; + + for (i = 0; i < ol_regdmn_Rdt.regDomainsCt; i++) { + if (ol_regdmn_Rdt.regDomains[i].regDmnEnum == reg_dmn) + return &ol_regdmn_Rdt.regDomains[i]; + } + return NULL; +} + +static const COUNTRY_CODE_TO_ENUM_RD *get_country_from_rd(u_int16_t regdmn) +{ + int32_t i; + + for (i = 0; i < ol_regdmn_Rdt.allCountriesCt; i++) { + if (ol_regdmn_Rdt.allCountries[i].regDmnEnum == regdmn) + return &ol_regdmn_Rdt.allCountries[i]; + } + return NULL; /* Not found */ +} + +/* + * Some users have reported their EEPROM programmed with + * 0x8000 set, this is not a supported regulatory domain + * but since we have more than one user with it we need + * a solution for them. We default to 0x64 + */ +static void regd_sanitize(struct regulatory *reg) +{ + if (reg->reg_domain != COUNTRY_ERD_FLAG) + return; + reg->reg_domain = 0x64; +} + +/* + * Returns country string for the given regulatory domain. + */ +int32_t regdmn_get_country_alpha2(struct regulatory *reg) +{ + u_int16_t country_code; + u_int16_t regdmn, rd; + const COUNTRY_CODE_TO_ENUM_RD *country = NULL; + + regd_sanitize(reg); + rd = reg->reg_domain; + + if (!regdmn_is_eeprom_valid(rd)) + return -EINVAL; + + regdmn = get_eeprom_rd(rd); + + country_code = regdmn_get_default_country(regdmn); + if (country_code == CTRY_DEFAULT && regdmn == CTRY_DEFAULT) { + /* Set to CTRY_UNITED_STATES for testing */ + country_code = CTRY_UNITED_STATES; + } + + if (country_code != CTRY_DEFAULT) { + country = find_country(country_code); + if (!country) { + /* TODO: Bring it under debug level */ + adf_os_print(KERN_ERR "Not a valid country code\n"); + return -EINVAL; + } + regdmn = country->regDmnEnum; + } + + reg->regpair = get_regdmn_pair(regdmn); + if (!reg->regpair) { + /* TODO: Bring it under debug level */ + adf_os_print(KERN_ERR "No regpair is found, can not proceeed\n"); + return -EINVAL; + } + reg->country_code = country_code; + + if (!country) + country = get_country_from_rd(regdmn); + + if (country) { + reg->alpha2[0] = country->isoName[0]; + reg->alpha2[1] = country->isoName[1]; + } else { + reg->alpha2[0] = '0'; + reg->alpha2[1] = '0'; + } + + return 0; +} + +/* + * Returns regulatory domain for given country string + */ +int32_t regdmn_get_regdmn_for_country(u_int8_t *alpha2) +{ + u_int8_t i; + + for (i = 0; i < ol_regdmn_Rdt.allCountriesCt; i++) { + if ((ol_regdmn_Rdt.allCountries[i].isoName[0] == alpha2[0]) && + (ol_regdmn_Rdt.allCountries[i].isoName[1] == alpha2[1])) + return ol_regdmn_Rdt.allCountries[i].regDmnEnum; + } + return -1; +} + +/* + * Test to see if the bitmask array is all zeros + */ +static bool +isChanBitMaskZero(const u_int64_t *bitmask) +{ + int i; + + for (i = 0; i < BMLEN; i++) { + if (bitmask[i] != 0) + return false; + } + return true; +} + +/* + * Return the mask of available modes based on the hardware + * capabilities and the specified country code and reg domain. + */ +u_int32_t regdmn_getwmodesnreg(u_int32_t modesAvail, + const COUNTRY_CODE_TO_ENUM_RD *country, + const REG_DOMAIN *rd5GHz) +{ + + /* Check country regulations for allowed modes */ + if ((modesAvail & (REGDMN_MODE_11A_TURBO|REGDMN_MODE_TURBO)) && + (!country->allow11aTurbo)) + modesAvail &= ~(REGDMN_MODE_11A_TURBO | REGDMN_MODE_TURBO); + + if ((modesAvail & REGDMN_MODE_11G_TURBO) && + (!country->allow11gTurbo)) + modesAvail &= ~REGDMN_MODE_11G_TURBO; + + if ((modesAvail & REGDMN_MODE_11G) && + (!country->allow11g)) + modesAvail &= ~REGDMN_MODE_11G; + + if ((modesAvail & REGDMN_MODE_11A) && + (isChanBitMaskZero(rd5GHz->chan11a))) + modesAvail &= ~REGDMN_MODE_11A; + + if ((modesAvail & REGDMN_MODE_11NG_HT20) && + (!country->allow11ng20)) + modesAvail &= ~REGDMN_MODE_11NG_HT20; + + if ((modesAvail & REGDMN_MODE_11NA_HT20) && + (!country->allow11na20)) + modesAvail &= ~REGDMN_MODE_11NA_HT20; + + if ((modesAvail & REGDMN_MODE_11NG_HT40PLUS) && + (!country->allow11ng40)) + modesAvail &= ~REGDMN_MODE_11NG_HT40PLUS; + + if ((modesAvail & REGDMN_MODE_11NG_HT40MINUS) && + (!country->allow11ng40)) + modesAvail &= ~REGDMN_MODE_11NG_HT40MINUS; + + if ((modesAvail & REGDMN_MODE_11NA_HT40PLUS) && + (!country->allow11na40)) + modesAvail &= ~REGDMN_MODE_11NA_HT40PLUS; + + if ((modesAvail & REGDMN_MODE_11NA_HT40MINUS) && + (!country->allow11na40)) + modesAvail &= ~REGDMN_MODE_11NA_HT40MINUS; + + if ((modesAvail & REGDMN_MODE_11AC_VHT20) && + (!country->allow11na20)) + modesAvail &= ~REGDMN_MODE_11AC_VHT20; + + if ((modesAvail & REGDMN_MODE_11AC_VHT40PLUS) && + (!country->allow11na40)) + modesAvail &= ~REGDMN_MODE_11AC_VHT40PLUS; + + if ((modesAvail & REGDMN_MODE_11AC_VHT40MINUS) && + (!country->allow11na40)) + modesAvail &= ~REGDMN_MODE_11AC_VHT40MINUS; + + if ((modesAvail & REGDMN_MODE_11AC_VHT80) && + (!country->allow11na80)) + modesAvail &= ~REGDMN_MODE_11AC_VHT80; + + if ((modesAvail & REGDMN_MODE_11AC_VHT20_2G) && + (!country->allow11ng20)) + modesAvail &= ~REGDMN_MODE_11AC_VHT20_2G; + + return modesAvail; +} + +void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail, + u_int32_t modeSelect) +{ + const REG_DOMAIN *regdomain2G = NULL; + const REG_DOMAIN *regdomain5G = NULL; + int8_t ctl_2g, ctl_5g, ctl; + const REG_DOMAIN *rd = NULL; + const struct cmode *cm; + const COUNTRY_CODE_TO_ENUM_RD *country; + const REG_DMN_PAIR_MAPPING *regpair; + + regpair = reg->regpair; + regdomain2G = get_regdmn(regpair->regDmn2GHz); + if (!regdomain2G) { + adf_os_print(KERN_ERR "Failed to get regdmn 2G"); + return; + } + + regdomain5G = get_regdmn(regpair->regDmn5GHz); + if (!regdomain5G) { + adf_os_print(KERN_ERR "Failed to get regdmn 5G"); + return; + } + + /* find first nible of CTL */ + ctl_2g = regdomain2G->conformance_test_limit; + ctl_5g = regdomain5G->conformance_test_limit; + + /* find second nible of CTL */ + country = find_country(reg->country_code); + if (country != NULL) + modesAvail = regdmn_getwmodesnreg(modesAvail, country, regdomain5G); + + for (cm = modes; cm < &modes[N(modes)]; cm++) { + + if ((cm->mode & modeSelect) == 0) + continue; + + if ((cm->mode & modesAvail) == 0) + continue; + + switch (cm->mode) { + case REGDMN_MODE_TURBO: + rd = regdomain5G; + ctl = rd->conformance_test_limit | CTL_TURBO; + break; + case REGDMN_MODE_11A: + case REGDMN_MODE_11NA_HT20: + case REGDMN_MODE_11NA_HT40PLUS: + case REGDMN_MODE_11NA_HT40MINUS: + case REGDMN_MODE_11AC_VHT20: + case REGDMN_MODE_11AC_VHT40PLUS: + case REGDMN_MODE_11AC_VHT40MINUS: + case REGDMN_MODE_11AC_VHT80: + rd = regdomain5G; + ctl = rd->conformance_test_limit; + break; + case REGDMN_MODE_11B: + rd = regdomain2G; + ctl = rd->conformance_test_limit | CTL_11B; + break; + case REGDMN_MODE_11G: + case REGDMN_MODE_11NG_HT20: + case REGDMN_MODE_11NG_HT40PLUS: + case REGDMN_MODE_11NG_HT40MINUS: + case REGDMN_MODE_11AC_VHT20_2G: + case REGDMN_MODE_11AC_VHT40_2G: + case REGDMN_MODE_11AC_VHT80_2G: + rd = regdomain2G; + ctl = rd->conformance_test_limit | CTL_11G; + break; + case REGDMN_MODE_11G_TURBO: + rd = regdomain2G; + ctl = rd->conformance_test_limit | CTL_108G; + break; + case REGDMN_MODE_11A_TURBO: + rd = regdomain5G; + ctl = rd->conformance_test_limit | CTL_108G; + break; + default: + adf_os_print(KERN_ERR "%s: Unkonwn HAL mode 0x%x\n", + __func__, cm->mode); + continue; + } + + if (rd == regdomain2G) + ctl_2g = ctl; + + if (rd == regdomain5G) + ctl_5g = ctl; + } + wma_send_regdomain_info(reg->reg_domain, regpair->regDmn2GHz, + regpair->regDmn5GHz, ctl_2g, ctl_5g); +} + +void regdmn_set_regval(struct regulatory *reg) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + u_int32_t modeSelect = 0xFFFFFFFF; + + if (!wma) { + WMA_LOGE("%s: Unable to get WMA handle", __func__); + return; + } + + wma_get_modeselect(wma, &modeSelect); + + regdmn_get_ctl_info(reg, wma->reg_cap.wireless_modes, modeSelect); + return; +} + +/* get the ctl from regdomain */ +u_int8_t regdmn_get_ctl_for_regdmn(u_int32_t reg_dmn) +{ + u_int8_t i; + u_int8_t default_regdmn_ctl = FCC; + + if (reg_dmn == CTRY_DEFAULT) + { + return default_regdmn_ctl; + } + else + { + for (i = 0; i < ol_regdmn_Rdt.regDomainsCt; i++) + { + if (ol_regdmn_Rdt.regDomains[i].regDmnEnum == reg_dmn) + return ol_regdmn_Rdt.regDomains[i].conformance_test_limit; + } + } + return -1; +} + +/* + * Get the 5G reg domain value for reg doamin + */ +u_int16_t get_regdmn_5g(u_int32_t reg_dmn) +{ + u_int16_t i; + + for (i = 0; i < ol_regdmn_Rdt.regDomainPairsCt; i++) + { + if (ol_regdmn_Rdt.regDomainPairs[i].regDmnEnum == reg_dmn) + { + return ol_regdmn_Rdt.regDomainPairs[i].regDmn5GHz; + } + } + adf_os_print("%s: invalid regulatory domain/country code 0x%x\n", + __func__, reg_dmn); + return 0; +} + +/* + * Get operating class for a given channel + */ +u_int16_t regdm_get_opclass_from_channel(u_int8_t *country, u_int8_t channel, + u_int8_t offset) +{ + regdm_op_class_map_t *class = NULL; + u_int16_t i = 0; + + if (0 == adf_os_mem_cmp(country,"US", 2)) { + class = us_op_class; + } else if (0 == adf_os_mem_cmp(country,"EU", 2)) { + class = euro_op_class; + } else if (0 == adf_os_mem_cmp(country,"JP", 2)) { + class = japan_op_class; + } else { + class = global_op_class; + } + + while (class->op_class) { + if ((offset == class->offset) || (offset == BWALL)) { + for (i = 0; + (i < MAX_CHANNELS_PER_OPERATING_CLASS && + class->channels[i]); + i++) { + if (channel == class->channels[i]) + return class->op_class; + } + } + class++; + } + return 0; +} + +/* + * Set current operating classes per country, regdomain + */ +u_int16_t regdm_set_curr_opclasses(u_int8_t num_classes, u_int8_t *class) +{ + u_int8_t i; + + if (SIR_MAC_MAX_SUPP_OPER_CLASSES < num_classes) { + adf_os_print(KERN_ERR "%s: Invalid numClasses (%d)\n", + __func__, num_classes); + return -1; + } + + for (i = 0 ; i < num_classes; i++) { + regdm_curr_supp_opp_classes.classes[i] = class[i]; + } + regdm_curr_supp_opp_classes.num_classes = num_classes; + + return 0; +} + +/* + * Get current operating classes + */ +u_int16_t regdm_get_curr_opclasses(u_int8_t *num_classes, u_int8_t *class) +{ + u_int8_t i; + + if (!num_classes || !class) { + adf_os_print(KERN_ERR "%s: Either num_classes or class is null\n", + __func__); + return -1; + } + + for (i = 0 ; i < regdm_curr_supp_opp_classes.num_classes; i++) { + class[i] = regdm_curr_supp_opp_classes.classes[i]; + } + + *num_classes = regdm_curr_supp_opp_classes.num_classes; + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.h new file mode 100644 index 0000000000000..d9f671d21c028 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain.h @@ -0,0 +1,1095 @@ +/* + * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting + * Copyright (c) 2005-2006 Atheros Communications, Inc. + * Copyright (c) 2010, Atheros Communications Inc. + * + * Redistribution and use in source and binary forms are permitted + * provided that the following conditions are met: + * 1. The materials contained herein are unmodified and are used + * unmodified. + * 2. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following NO + * ''WARRANTY'' disclaimer below (''Disclaimer''), without + * modification. + * 3. Redistributions in binary form must reproduce at minimum a + * disclaimer similar to the Disclaimer below and any redistribution + * must be conditioned upon including a substantially similar + * Disclaimer requirement for further binary redistribution. + * 4. Neither the names of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote + * product derived from this software without specific prior written + * permission. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE + * FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + * + * This module contains the regulatory domain private structure definitions . + * + */ + +#ifndef REGULATORY_H +#define REGULATORY_H + +enum { + CTRY_DEBUG = 0x1ff, /* debug country code */ + CTRY_DEFAULT = 0 /* default country code */ +}; + +#define BMLEN 2 /* Use 2 64 bit uint for channel bitmask */ + +/* + * The following table is the master list for all different freqeuncy + * bands with the complete matrix of all possible flags and settings + * for each band if it is used in ANY reg domain. + */ + +#define DEF_REGDMN FCC3_FCCA +#define DEF_DMN_5 FCC1 +#define DEF_DMN_2 FCCA +#define COUNTRY_ERD_FLAG 0x8000 +#define WORLDWIDE_ROAMING_FLAG 0x4000 +#define SUPER_DOMAIN_MASK 0x0fff +#define COUNTRY_CODE_MASK 0x3fff +#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT) + +/* + * The following describe the bit masks for different passive scan + * capability/requirements per regdomain. + */ +#define NO_PSCAN 0x0ULL +#define PSCAN_FCC 0x0000000000000001ULL +#define PSCAN_FCC_T 0x0000000000000002ULL +#define PSCAN_ETSI 0x0000000000000004ULL +#define PSCAN_MKK1 0x0000000000000008ULL +#define PSCAN_MKK2 0x0000000000000010ULL +#define PSCAN_MKKA 0x0000000000000020ULL +#define PSCAN_MKKA_G 0x0000000000000040ULL +#define PSCAN_ETSIA 0x0000000000000080ULL +#define PSCAN_ETSIB 0x0000000000000100ULL +#define PSCAN_ETSIC 0x0000000000000200ULL +#define PSCAN_WWR 0x0000000000000400ULL +#define PSCAN_MKKA1 0x0000000000000800ULL +#define PSCAN_MKKA1_G 0x0000000000001000ULL +#define PSCAN_MKKA2 0x0000000000002000ULL +#define PSCAN_MKKA2_G 0x0000000000004000ULL +#define PSCAN_MKK3 0x0000000000008000ULL +#define PSCAN_EXT_CHAN 0x0000000000010000ULL +#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL +#define IS_ECM_CHAN 0x8000000000000000ULL + + +/* define in ah_eeprom.h */ +#define SD_NO_CTL 0xf0 +#define NO_CTL 0xff +#define CTL_MODE_M 0x0f +#define CTL_11A 0 +#define CTL_11B 1 +#define CTL_11G 2 +#define CTL_TURBO 3 +#define CTL_108G 4 +#define CTL_2GHT20 5 +#define CTL_5GHT20 6 +#define CTL_2GHT40 7 +#define CTL_5GHT40 8 +#define CTL_5GVHT80 9 + +#ifndef ATH_NO_5G_SUPPORT + #define REGDMN_MODE_11A_TURBO REGDMN_MODE_108A + #define CHAN_11A_BMZERO BMZERO, + #define CHAN_11A_BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l) \ + BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l), +#else + /* remove 11a channel info if 11a is not supported */ + #define CHAN_11A_BMZERO + #define CHAN_11A_BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l) +#endif +#ifndef ATH_REMOVE_2G_TURBO_RD_TABLE + #define REGDMN_MODE_11G_TURBO REGDMN_MODE_108G + #define CHAN_TURBO_G_BMZERO BMZERO, + #define CHAN_TURBO_G_BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l) \ + BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l), +#else + /* remove turbo-g channel info if turbo-g is not supported */ + #define CHAN_TURBO_G(a, b) + #define CHAN_TURBO_G_BMZERO + #define CHAN_TURBO_G_BM(_a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l) +#endif + +#define BMLEN 2 /* Use 2 64 bit uint for channel bitmask + NB: Must agree with macro below (BM) */ +#define BMZERO {(u_int64_t) 0, (u_int64_t) 0} /* BMLEN zeros */ + +#ifndef SUPPRESS_SHIFT_WARNING +#define SUPPRESS_SHIFT_WARNING +#endif + +/* Suppress MS warning "C4293: 'operator' : shift count negative or too big, + * undefined behavior" + * This is safe below because the the operand is properly range-checked, but + * the compiler can't reason that out before it spits the warning. + * Using suppress, so the warning can still be enabled globally to catch other + * incorrect uses. + */ +#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \ + SUPPRESS_SHIFT_WARNING \ + {((((_fa >= 0) && (_fa < 64)) ? (((u_int64_t) 1) << _fa) : (u_int64_t) 0) | \ + (((_fb >= 0) && (_fb < 64)) ? (((u_int64_t) 1) << _fb) : (u_int64_t) 0) | \ + (((_fc >= 0) && (_fc < 64)) ? (((u_int64_t) 1) << _fc) : (u_int64_t) 0) | \ + (((_fd >= 0) && (_fd < 64)) ? (((u_int64_t) 1) << _fd) : (u_int64_t) 0) | \ + (((_fe >= 0) && (_fe < 64)) ? (((u_int64_t) 1) << _fe) : (u_int64_t) 0) | \ + (((_ff >= 0) && (_ff < 64)) ? (((u_int64_t) 1) << _ff) : (u_int64_t) 0) | \ + (((_fg >= 0) && (_fg < 64)) ? (((u_int64_t) 1) << _fg) : (u_int64_t) 0) | \ + (((_fh >= 0) && (_fh < 64)) ? (((u_int64_t) 1) << _fh) : (u_int64_t) 0) | \ + (((_fi >= 0) && (_fi < 64)) ? (((u_int64_t) 1) << _fi) : (u_int64_t) 0) | \ + (((_fj >= 0) && (_fj < 64)) ? (((u_int64_t) 1) << _fj) : (u_int64_t) 0) | \ + (((_fk >= 0) && (_fk < 64)) ? (((u_int64_t) 1) << _fk) : (u_int64_t) 0) | \ + (((_fl >= 0) && (_fl < 64)) ? (((u_int64_t) 1) << _fl) : (u_int64_t) 0) ) \ + ,(((((_fa > 63) && (_fa < 128)) ? (((u_int64_t) 1) << (_fa - 64)) : (u_int64_t) 0) | \ + (((_fb > 63) && (_fb < 128)) ? (((u_int64_t) 1) << (_fb - 64)) : (u_int64_t) 0) | \ + (((_fc > 63) && (_fc < 128)) ? (((u_int64_t) 1) << (_fc - 64)) : (u_int64_t) 0) | \ + (((_fd > 63) && (_fd < 128)) ? (((u_int64_t) 1) << (_fd - 64)) : (u_int64_t) 0) | \ + (((_fe > 63) && (_fe < 128)) ? (((u_int64_t) 1) << (_fe - 64)) : (u_int64_t) 0) | \ + (((_ff > 63) && (_ff < 128)) ? (((u_int64_t) 1) << (_ff - 64)) : (u_int64_t) 0) | \ + (((_fg > 63) && (_fg < 128)) ? (((u_int64_t) 1) << (_fg - 64)) : (u_int64_t) 0) | \ + (((_fh > 63) && (_fh < 128)) ? (((u_int64_t) 1) << (_fh - 64)) : (u_int64_t) 0) | \ + (((_fi > 63) && (_fi < 128)) ? (((u_int64_t) 1) << (_fi - 64)) : (u_int64_t) 0) | \ + (((_fj > 63) && (_fj < 128)) ? (((u_int64_t) 1) << (_fj - 64)) : (u_int64_t) 0) | \ + (((_fk > 63) && (_fk < 128)) ? (((u_int64_t) 1) << (_fk - 64)) : (u_int64_t) 0) | \ + (((_fl > 63) && (_fl < 128)) ? (((u_int64_t) 1) << (_fl - 64)) : (u_int64_t) 0)))} + +/* + * THE following table is the mapping of regdomain pairs specified by + * an 8 bit regdomain value to the individual unitary reg domains + */ + +typedef struct reg_dmn_pair_mapping { + u_int16_t regDmnEnum; /* 16 bit reg domain pair */ + u_int16_t regDmn5GHz; /* 5GHz reg domain */ + u_int16_t regDmn2GHz; /* 2GHz reg domain */ + u_int32_t flags5GHz; /* Requirements flags (AdHoc + disallow, noise floor cal needed, + etc) */ + u_int32_t flags2GHz; /* Requirements flags (AdHoc + disallow, noise floor cal needed, + etc) */ + u_int64_t pscanMask; /* Passive Scan flags which + can override unitary domain + passive scan flags. This + value is used as a mask on + the unitary flags*/ + u_int16_t singleCC; /* Country code of single country if + a one-on-one mapping exists */ +} REG_DMN_PAIR_MAPPING; + +typedef struct { + u_int16_t countryCode; + u_int16_t regDmnEnum; + const char* isoName; + const char* name; + u_int16_t + allow11g : 1, + allow11aTurbo : 1, + allow11gTurbo : 1, + allow11ng20 : 1, /* HT-20 allowed in 2GHz? */ + allow11ng40 : 1, /* HT-40 allowed in 2GHz? */ + allow11na20 : 1, /* HT-20 allowed in 5GHz? */ + allow11na40 : 1, /* HT-40 VHT-40 allowed in 5GHz? */ + allow11na80 : 1; /* VHT-80 allowed in 5GHz */ + u_int16_t outdoorChanStart; +} COUNTRY_CODE_TO_ENUM_RD; + +typedef struct RegDmnFreqBand { + u_int16_t lowChannel; /* Low channel center in MHz */ + u_int16_t highChannel; /* High Channel center in MHz */ + u_int8_t powerDfs; /* Max power (dBm) for channel + range when using DFS */ + u_int8_t antennaMax; /* Max allowed antenna gain */ + u_int8_t channelBW; /* Bandwidth of the channel */ + u_int8_t channelSep; /* Channel separation within + the band */ + u_int64_t useDfs; /* Use DFS in the RegDomain + if corresponding bit is set */ + u_int64_t usePassScan; /* Use Passive Scan in the RegDomain + if corresponding bit is set */ + u_int8_t regClassId; /* Regulatory class id */ +} REG_DMN_FREQ_BAND; + +typedef struct reg_domain { + u_int16_t regDmnEnum; /* value from EnumRd table */ + u_int8_t conformance_test_limit; + u_int64_t dfsMask; /* DFS bitmask for 5Ghz tables */ + u_int64_t pscan; /* Bitmask for passive scan */ + u_int32_t flags; /* Requirement flags (AdHoc disallow, noise + floor cal needed, etc) */ + u_int64_t chan11a[BMLEN];/* 128 bit bitmask for channel/band selection */ + u_int64_t chan11a_turbo[BMLEN];/* 128 bit bitmask for channel/band select */ + u_int64_t chan11a_dyn_turbo[BMLEN]; /* 128 bit mask for chan/band select */ + + u_int64_t chan11b[BMLEN];/* 128 bit bitmask for channel/band selection */ + u_int64_t chan11g[BMLEN];/* 128 bit bitmask for channel/band selection */ + u_int64_t chan11g_turbo[BMLEN]; +} REG_DOMAIN; + +struct cmode { + u_int32_t mode; + u_int32_t flags; +}; + +#define YES true +#define NO false + +/* mapping of old skus to new skus for Japan */ +typedef struct { + u_int16_t domain; + u_int16_t newdomain_pre53; /* pre eeprom version 5.3 */ + u_int16_t newdomain_post53; /* post eeprom version 5.3 */ +} JAPAN_SKUMAP; + +/* mapping of countrycode to new skus for Japan */ +typedef struct { + u_int16_t ccode; + u_int16_t newdomain_pre53; /* pre eeprom version 5.3 */ + u_int16_t newdomain_post53; /* post eeprom version 5.3 */ +} JAPAN_COUNTRYMAP; + +/* check rd flags in eeprom for japan */ +typedef struct { + u_int16_t freqbandbit; + u_int32_t eepromflagtocheck; +} JAPAN_BANDCHECK; + +/* Common mode power table for 5Ghz */ +typedef struct { + u_int16_t lchan; + u_int16_t hchan; + u_int8_t pwrlvl; +} COMMON_MODE_POWER; + +typedef enum +{ + COUNTRY_CODE_SET_BY_CORE, + COUNTRY_CODE_SET_BY_DRIVER, + COUNTRY_CODE_SET_BY_USER +} COUNTRY_CODE_SOURCE; + +struct regulatory { + u_int32_t reg_domain; + u_int32_t eeprom_rd_ext; + u_int16_t country_code; + u_int8_t alpha2[3]; + const void *regpair; + COUNTRY_CODE_SOURCE cc_src; +}; +/* Multi-Device RegDomain Support */ +typedef struct ath_hal_reg_dmn_tables { + /* regDomainPairs: Map of 8-bit regdomain values to unitary reg domain */ + const REG_DMN_PAIR_MAPPING *regDomainPairs; + /* allCountries: Master list of freq. bands (flags, settings) */ + const COUNTRY_CODE_TO_ENUM_RD *allCountries; + /* regDomains: Array of supported reg domains */ + const REG_DOMAIN *regDomains; + + u_int16_t regDomainPairsCt; /* Num reg domain pair entries */ + u_int16_t allCountriesCt; /* Num country entries */ + u_int16_t regDomainsCt; /* Num reg domain entries */ +} HAL_REG_DMN_TABLES; + +/* + * Country/Region Codes from MS WINNLS.H + * Numbering from ISO 3166 + */ +/** @brief country code definitions + * - country definition: CTRY_DEBUG + * - country string: DB + * - country ID: 0 + * - country definition: CTRY_DEFAULT + * - country string: NA + * - country ID: 0 + * - country definition: CTRY_ALBANIA + * - country string: AL + * - country ID: 8 + * - country definition: CTRY_ALGERIA + * - country string: DZ + * - country ID: 12 + * - country definition: CTRY_ARGENTINA + * - country string: AR + * - country ID: 32 + * - country definition: CTRY_ARMENIA + * - country string: AM + * - country ID: 51 + * - country definition: CTRY_AUSTRALIA + * - country string: AU + * - country ID: 36 + * - country definition: CTRY_AUSTRALIA2 + * - country string: AU2 + * - country ID: 5000 + * - country definition: CTRY_AUSTRIA + * - country string: AT + * - country ID: 40 + * - country definition: CTRY_AZERBAIJAN + * - country string: AZ + * - country ID: 31 + * - country definition: CTRY_BAHAMAS + * - country string: BS + * - country ID: 44 + * - country definition: CTRY_BAHRAIN + * - country string: BH + * - country ID: 48 + * - country definition: CTRY_BELARUS + * - country string: BY + * - country ID: 112 + * - country definition: CTRY_BELGIUM + * - country string: BE + * - country ID: 56 + * - country definition: CTRY_BELIZE + * - country string: BZ + * - country ID: 84 + * - country definition: CTRY_BERMUDA + * - country string: BM + * - country ID: 60 + * - country definition: CTRY_BOLIVIA + * - country string: BO + * - country ID: 68 + * - country definition: CTRY_BOSNIA_HERZEGOWINA + * - country string: 70 + * - country ID: BA + * - country definition: CTRY_BRAZIL + * - country string: BR + * - country ID: 76 + * - country definition: CTRY_BRUNEI_DARUSSALAM + * - country string: BN + * - country ID: 96 + * - country definition: CTRY_BULGARIA + * - country string: BG + * - country ID: 100 + * - country definition: CTRY_CANADA + * - country string: CA + * - country ID: 124 + * - country definition: CTRY_CANADA2 + * - country string: CA2 + * - country ID: 5001 + * - country definition: CTRY_CHILE + * - country string: CL + * - country ID: 152 + * - country definition: CTRY_CHINA + * - country string: CN + * - country ID: 152 + * - country definition: CTRY_COLOMBIA + * - country string: CO + * - country ID: 170 + * - country definition: CTRY_COSTA_RICA + * - country string: CR + * - country ID: 191 + * - country definition: CTRY_CROATIA + * - country string: HR + * - country ID: 191 + * - country definition: CTRY_CYPRUS + * - country string: CY + * - country ID: 196 + * - country definition: CTRY_CZECH + * - country string: CZ + * - country ID: 203 + * - country definition: CTRY_DENMARK + * - country string: DK + * - country ID: 208 + * - country definition: CTRY_DOMINICAN_REPUBLIC + * - country string: DO + * - country ID: 214 + * - country definition: CTRY_ECUADOR + * - country string: EC + * - country ID: 218 + * - country definition: CTRY_EGYPT + * - country string: EG + * - country ID: 818 + * - country definition: CTRY_EL_SALVADOR + * - country string: SV + * - country ID: 222 + * - country definition: CTRY_ESTONIA + * - country string: EE + * - country ID: 233 + * - country definition: CTRY_FAEROE_ISLANDS + * - country string: FO + * - country ID: 234 + * - country definition: CTRY_FINLAND + * - country string: FI + * - country ID: 246 + * - country definition: CTRY_FRANCE + * - country string: FR + * - country ID: 250 + * - country definition: CTRY_FRANCE2 + * - country string: F2 + * - country ID: 255 + * - country definition: CTRY_GEORGIA + * - country string: GE + * - country ID: 268 + * - country definition: CTRY_GERMANY + * - country string: DE + * - country ID: 276 + * - country definition: CTRY_GREECE + * - country string: GR + * - country ID: 300 + * - country definition: CTRY_GUATEMALA + * - country string: GT + * - country ID: 320 + * - country definition: CTRY_HONDURAS + * - country string: HN + * - country ID: 340 + * - country definition: CTRY_HONG_KONG + * - country string: HK + * - country ID: 344 + * - country definition: CTRY_HUNGARY + * - country string: HU + * - country ID: 348 + * - country definition: CTRY_ICELAND + * - country string: IS + * - country ID: 352 + * - country definition: CTRY_INDIA + * - country string: IN + * - country ID: 356 + * - country definition: CTRY_INDONESIA + * - country string: ID + * - country ID: 360 + * - country definition: CTRY_IRAN + * - country string: IR + * - country ID: 364 + * - country definition: CTRY_IRAQ + * - country string: IQ + * - country ID: 368 + * - country definition: CTRY_IRELAND + * - country string: IE + * - country ID: 372 + * - country definition: CTRY_ISRAEL + * - country string: IL + * - country ID: 376 + * - country definition: CTRY_ITALY + * - country string: IT + * - country ID: 380 + * - country definition: CTRY_JAMAICA + * - country string: JM + * - country ID: 388 + * - country definition: CTRY_JAPAN + * - country string: JP + * - country ID: 392 + * - country definition: CTRY_JAPAN1 + * - country string: JP1 + * - country ID: 393 + * - country definition: CTRY_JAPAN2 + * - country string: JP2 + * - country ID: 394 + * - country definition: CTRY_JAPAN3 + * - country string: JP3 + * - country ID: 395 + * - country definition: CTRY_JAPAN4 + * - country string: JP4 + * - country ID: 396 + * - country definition: CTRY_JAPAN5 + * - country string: JP5 + * - country ID: 397 + * - country definition: CTRY_JAPAN6 + * - country string: JP6 + * - country ID: 399 + * - country definition: CTRY_JAPAN7 + * - country string: JP7 + * - country ID: 4007 + * - country definition: CTRY_JAPAN8 + * - country string: JP8 + * - country ID: 4008 + * - country definition: CTRY_JAPAN9 + * - country string: JP9 + * - country ID: 4009 + * - country definition: CTRY_JAPAN10 + * - country string: JP10 + * - country ID: 4010 + * - country definition: CTRY_JAPAN11 + * - country string: JP11 + * - country ID: 4011 + * - country definition: CTRY_JAPAN12 + * - country string: JP12 + * - country ID: 4012 + * - country definition: CTRY_JAPAN13 + * - country string: JP13 + * - country ID: 4013 + * - country definition: CTRY_JAPAN14 + * - country string: JP14 + * - country ID: 4014 + * - country definition: CTRY_JAPAN15 + * - country string: JP15 + * - country ID: 4015 + * - country definition: CTRY_JAPAN16 + * - country string: JP16 + * - country ID: 4016 + * - country definition: CTRY_JAPAN17 + * - country string: JP17 + * - country ID: 4017 + * - country definition: CTRY_JAPAN18 + * - country string: JP18 + * - country ID: 4018 + * - country definition: CTRY_JAPAN19 + * - country string: JP19 + * - country ID: 4019 + * - country definition: CTRY_JAPAN20 + * - country string: JP20 + * - country ID: 4020 + * - country definition: CTRY_JAPAN21 + * - country string: JP21 + * - country ID: 4021 + * - country definition: CTRY_JAPAN22 + * - country string: JP22 + * - country ID: 4022 + * - country definition: CTRY_JAPAN23 + * - country string: JP23 + * - country ID: 4023 + * - country definition: CTRY_JAPAN24 + * - country string: JP24 + * - country ID: 4024 + * - country definition: CTRY_JAPAN25 + * - country string: JP25 + * - country ID: 4025 + * - country definition: CTRY_JAPAN26 + * - country string: JP26 + * - country ID: 4026 + * - country definition: CTRY_JAPAN27 + * - country string: JP27 + * - country ID: 4027 + * - country definition: CTRY_JAPAN28 + * - country string: JP28 + * - country ID: 4028 + * - country definition: CTRY_JAPAN29 + * - country string: JP29 + * - country ID: 4029 + * - country definition: CTRY_JAPAN30 + * - country string: JP30 + * - country ID: 4030 + * - country definition: CTRY_JAPAN31 + * - country string: JP31 + * - country ID: 4031 + * - country definition: CTRY_JAPAN32 + * - country string: JP32 + * - country ID: 4032 + * - country definition: CTRY_JAPAN33 + * - country string: JP33 + * - country ID: 4033 + * - country definition: CTRY_JAPAN34 + * - country string: JP34 + * - country ID: 4034 + * - country definition: CTRY_JAPAN35 + * - country string: JP35 + * - country ID: 4035 + * - country definition: CTRY_JAPAN36 + * - country string: JP36 + * - country ID: 4036 + * - country definition: CTRY_JAPAN37 + * - country string: JP37 + * - country ID: 4037 + * - country definition: CTRY_JAPAN38 + * - country string: JP38 + * - country ID: 4038 + * - country definition: CTRY_JAPAN39 + * - country string: JP39 + * - country ID: 4039 + * - country definition: CTRY_JAPAN40 + * - country string: JP40 + * - country ID: 4040 + * - country definition: CTRY_JAPAN41 + * - country string: JP41 + * - country ID: 4041 + * - country definition: CTRY_JAPAN42 + * - country string: JP42 + * - country ID: 4042 + * - country definition: CTRY_JAPAN43 + * - country string: JP43 + * - country ID: 4043 + * - country definition: CTRY_JAPAN44 + * - country string: JP44 + * - country ID: 4044 + * - country definition: CTRY_JAPAN45 + * - country string: JP45 + * - country ID: 4045 + * - country definition: CTRY_JAPAN46 + * - country string: JP46 + * - country ID: 4046 + * - country definition: CTRY_JAPAN47 + * - country string: JP47 + * - country ID: 4047 + * - country definition: CTRY_JAPAN48 + * - country string: JP48 + * - country ID: 4048 + * - country definition: CTRY_JAPAN49 + * - country string: JP49 + * - country ID: 4049 + * - country definition: CTRY_JAPAN50 + * - country string: JP50 + * - country ID: 4050 + * - country definition: CTRY_JAPAN51 + * - country string: JP51 + * - country ID: 4051 + * - country definition: CTRY_JAPAN52 + * - country string: JP52 + * - country ID: 4052 + * - country definition: CTRY_JAPAN53 + * - country string: JP53 + * - country ID: 4053 + * - country definition: CTRY_JAPAN54 + * - country string: JP54 + * - country ID: 4054 + * - country definition: CTRY_JAPAN55 + * - country string: JP55 + * - country ID: 4055 + * - country definition: CTRY_JAPAN56 + * - country string: JP56 + * - country ID: 4056 + * - country definition: CTRY_JORDAN + * - country string: JO + * - country ID: 400 + * - country definition: CTRY_KAZAKHSTAN + * - country string: KZ + * - country ID: 398 + * - country definition: CTRY_KENYA + * - country string: KE + * - country ID: 404 + * - country definition: CTRY_KOREA_NORTH + * - country string: KP + * - country ID: 408 + * - country definition: CTRY_KOREA_ROC + * - country string: KR + * - country ID: 410 + * - country definition: CTRY_KOREA_ROC2 + * - country string: KR2 + * - country ID: 411 + * - country definition: CTRY_KOREA_ROC3 + * - country string: KR3 + * - country ID: 412 + * - country definition: CTRY_KUWAIT + * - country string: KW + * - country ID: 414 + * - country definition: CTRY_LATVIA + * - country string: LV + * - country ID: 428 + * - country definition: CTRY_LEBANON + * - country string: LB + * - country ID: 422 + * - country definition: CTRY_LIBYA + * - country string: LY + * - country ID: 434 + * - country definition: CTRY_LIECHTENSTEIN + * - country string: LI + * - country ID: 438 + * - country definition: CTRY_LITHUANIA + * - country string: LT + * - country ID: 440 + * - country definition: CTRY_LUXEMBOURG + * - country string: LU + * - country ID: 442 + * - country definition: CTRY_MACAU + * - country string: MO + * - country ID: 446 + * - country definition: CTRY_MACEDONIA + * - country string: MK + * - country ID: 807 + * - country definition: CTRY_MALAYSIA + * - country string: MY + * - country ID: 458 + * - country definition: CTRY_MALTA + * - country string: MT + * - country ID: 470 + * - country definition: CTRY_MAURITIUS + * - country string: MU + * - country ID: 480 + * - country definition: CTRY_MEXICO + * - country string: MX + * - country ID: 484 + * - country definition: CTRY_MONACO + * - country string: MC + * - country ID: 492 + * - country definition: CTRY_MOROCCO + * - country string: MA + * - country ID: 504 + * - country definition: CTRY_NETHERLANDS + * - country string: NL + * - country ID: 528 + * - country definition: CTRY_NEW_ZEALAND + * - country string: NZ + * - country ID: 554 + * - country definition: CTRY_NICARAGUA + * - country string: NI + * - country ID: 558 + * - country definition: CTRY_NORWAY + * - country string: NO + * - country ID: 578 + * - country definition: CTRY_OMAN + * - country string: OM + * - country ID: 512 + * - country definition: CTRY_PAKISTAN + * - country string: PK + * - country ID: 586 + * - country definition: CTRY_PANAMA + * - country string: PA + * - country ID: 591 + * - country definition: CTRY_PARAGUAY + * - country string: PY + * - country ID: 600 + * - country definition: CTRY_PERU + * - country string: PE + * - country ID: 604 + * - country definition: CTRY_PHILIPPINES + * - country string: PH + * - country ID: 608 + * - country definition: CTRY_POLAND + * - country string: PL + * - country ID: 616 + * - country definition: CTRY_PORTUGAL + * - country string: PT + * - country ID: 620 + * - country definition: CTRY_PUERTO_RICO + * - country string: PR + * - country ID: 630 + * - country definition: CTRY_QATAR + * - country string: QA + * - country ID: 634 + * - country definition: CTRY_ROMANIA + * - country string: RO + * - country ID: 642 + * - country definition: CTRY_RUSSIA + * - country string: RU + * - country ID: 643 + * - country definition: CTRY_SAUDI_ARABIA + * - country string: SA + * - country ID: 682 + * - country definition: CTRY_SERBIA + * - country string: RS + * - country ID: 688 + * - country definition: CTRY_MONTENEGRO + * - country string: ME + * - country ID: 499 + * - country definition: CTRY_SINGAPORE + * - country string: SG + * - country ID: 702 + * - country definition: CTRY_SLOVAKIA + * - country string: SK + * - country ID: 703 + * - country definition: CTRY_SLOVENIA + * - country string: SI + * - country ID: 705 + * - country definition: CTRY_SOUTH_AFRICA + * - country string: ZA + * - country ID: 710 + * - country definition: CTRY_SPAIN + * - country string: ES + * - country ID: 724 + * - country definition: CTRY_SRI_LANKA + * - country string: LK + * - country ID: 144 + * - country definition: CTRY_SWEDEN + * - country string: SE + * - country ID: 752 + * - country definition: CTRY_SWITZERLAND + * - country string: CH + * - country ID: 756 + * - country definition: CTRY_SYRIA + * - country string: SY + * - country ID: 760 + * - country definition: CTRY_TAIWAN + * - country string: TW + * - country ID: 158 + * - country definition: CTRY_TANZANIA + * - country string: TZ + * - country ID: 834 + * - country definition: CTRY_THAILAND + * - country string: TH + * - country ID: 764 + * - country definition: CTRY_TRINIDAD_Y_TOBAGO + * - country string: TT + * - country ID: 780 + * - country definition: CTRY_TUNISIA + * - country string: TN + * - country ID: 788 + * - country definition: CTRY_TURKEY + * - country string: TR + * - country ID: 792 + * - country definition: CTRY_UAE + * - country string: AE + * - country ID: 784 + * - country definition: CTRY_UKRAINE + * - country string: UA + * - country ID: 804 + * - country definition: CTRY_UNITED_KINGDOM + * - country string: GB + * - country ID: 826 + * - country definition: CTRY_UNITED_STATES + * - country string: US + * - country ID: 840 + * - country definition: CTRY_UNITED_STATES_FCC49 + * - country string: US + * - country ID: 842 + * - country definition: CTRY_URUGUAY + * - country string: UY + * - country ID: 858 + * - country definition: CTRY_UZBEKISTAN + * - country string: UZ + * - country ID: 860 + * - country definition: CTRY_VENEZUELA + * - country string: VE + * - country ID: 862 + * - country definition: CTRY_VIET_NAM + * - country string: VN + * - country ID: 704 + * - country definition: CTRY_YEMEN + * - country string: YE + * - country ID: 887 + * - country definition: CTRY_ZIMBABWE + * - country string: ZW + * - country ID: 716 + */ +enum CountryCode { + CTRY_ALBANIA = 8, /* Albania */ + CTRY_ALGERIA = 12, /* Algeria */ + CTRY_ARGENTINA = 32, /* Argentina */ + CTRY_ARMENIA = 51, /* Armenia */ + CTRY_AUSTRALIA = 36, /* Australia */ + CTRY_AUSTRIA = 40, /* Austria */ + CTRY_AZERBAIJAN = 31, /* Azerbaijan */ + CTRY_BAHAMAS = 44, /* Bahamas */ + CTRY_BAHRAIN = 48, /* Bahrain */ + CTRY_BANGLADESH = 50, /* Bangladesh */ + CTRY_BARBADOS = 52, /* Barbados */ + CTRY_BELARUS = 112, /* Belarus */ + CTRY_BELGIUM = 56, /* Belgium */ + CTRY_BELIZE = 84, /* Belize */ + CTRY_BERMUDA = 60, /* Berumuda */ + CTRY_BOLIVIA = 68, /* Bolivia */ + CTRY_BOSNIA_HERZ = 70, /* Bosnia and Herzegowina */ + CTRY_BRAZIL = 76, /* Brazil */ + CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ + CTRY_BULGARIA = 100, /* Bulgaria */ + CTRY_CAMBODIA = 116, /* Cambodia */ + CTRY_CANADA = 124, /* Canada */ + CTRY_CHILE = 152, /* Chile */ + CTRY_CHINA = 156, /* People's Republic of China */ + CTRY_COLOMBIA = 170, /* Colombia */ + CTRY_COSTA_RICA = 188, /* Costa Rica */ + CTRY_CROATIA = 191, /* Croatia */ + CTRY_CYPRUS = 196, + CTRY_CZECH = 203, /* Czech Republic */ + CTRY_DENMARK = 208, /* Denmark */ + CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ + CTRY_ECUADOR = 218, /* Ecuador */ + CTRY_EGYPT = 818, /* Egypt */ + CTRY_EL_SALVADOR = 222, /* El Salvador */ + CTRY_ESTONIA = 233, /* Estonia */ + CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ + CTRY_FINLAND = 246, /* Finland */ + CTRY_FRANCE = 250, /* France */ + CTRY_GEORGIA = 268, /* Georgia */ + CTRY_GERMANY = 276, /* Germany */ + CTRY_GREECE = 300, /* Greece */ + CTRY_GREENLAND = 304, /* Greenland */ + CTRY_GRENADA = 308, /* Grenada */ + CTRY_GUAM = 316, /* Guam */ + CTRY_GUATEMALA = 320, /* Guatemala */ + CTRY_HAITI = 332, /* Haiti */ + CTRY_HONDURAS = 340, /* Honduras */ + CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ + CTRY_HUNGARY = 348, /* Hungary */ + CTRY_ICELAND = 352, /* Iceland */ + CTRY_INDIA = 356, /* India */ + CTRY_INDONESIA = 360, /* Indonesia */ + CTRY_IRAN = 364, /* Iran */ + CTRY_IRAQ = 368, /* Iraq */ + CTRY_IRELAND = 372, /* Ireland */ + CTRY_ISRAEL = 376, /* Israel */ + CTRY_ITALY = 380, /* Italy */ + CTRY_JAMAICA = 388, /* Jamaica */ + CTRY_JAPAN = 392, /* Japan */ + CTRY_JORDAN = 400, /* Jordan */ + CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ + CTRY_KENYA = 404, /* Kenya */ + CTRY_KOREA_NORTH = 408, /* North Korea */ + CTRY_KOREA_ROC = 410, /* South Korea */ + CTRY_KOREA_ROC3 = 412, /* South Korea */ + CTRY_KUWAIT = 414, /* Kuwait */ + CTRY_LATVIA = 428, /* Latvia */ + CTRY_LEBANON = 422, /* Lebanon */ + CTRY_LIBYA = 434, /* Libya */ + CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ + CTRY_LITHUANIA = 440, /* Lithuania */ + CTRY_LUXEMBOURG = 442, /* Luxembourg */ + CTRY_MACAU = 446, /* Macau SAR */ + CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */ + CTRY_MALAYSIA = 458, /* Malaysia */ + CTRY_MALDIVES = 462, /* Maldives */ + CTRY_MALTA = 470, /* Malta */ + CTRY_MAURITIUS = 480, /* Mauritius */ + CTRY_MEXICO = 484, /* Mexico */ + CTRY_MONACO = 492, /* Principality of Monaco */ + CTRY_MOROCCO = 504, /* Morocco */ + CTRY_NEPAL = 524, /* Nepal */ + CTRY_NETHERLANDS = 528, /* Netherlands */ + CTRY_NETHERLANDS_ANTILLES = 530, /* Netherlands-Antilles */ + CTRY_ARUBA = 533, /* Aruba */ + CTRY_NEW_ZEALAND = 554, /* New Zealand */ + CTRY_NICARAGUA = 558, /* Nicaragua */ + CTRY_NORWAY = 578, /* Norway */ + CTRY_OMAN = 512, /* Oman */ + CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ + CTRY_PANAMA = 591, /* Panama */ + CTRY_PAPUA_NEW_GUINEA = 598, /* Papua New Guinea */ + CTRY_PARAGUAY = 600, /* Paraguay */ + CTRY_PERU = 604, /* Peru */ + CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ + CTRY_POLAND = 616, /* Poland */ + CTRY_PORTUGAL = 620, /* Portugal */ + CTRY_PUERTO_RICO = 630, /* Puerto Rico */ + CTRY_QATAR = 634, /* Qatar */ + CTRY_ROMANIA = 642, /* Romania */ + CTRY_RUSSIA = 643, /* Russia */ + CTRY_RWANDA = 646, /* Rwanda */ + CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ + CTRY_SERBIA = 688, /* Republic of Serbia */ + CTRY_MONTENEGRO = 499, /* Montenegro */ + CTRY_SINGAPORE = 702, /* Singapore */ + CTRY_SLOVAKIA = 703, /* Slovak Republic */ + CTRY_SLOVENIA = 705, /* Slovenia */ + CTRY_SOUTH_AFRICA = 710, /* South Africa */ + CTRY_SPAIN = 724, /* Spain */ + CTRY_SRI_LANKA = 144, /* Sri Lanka */ + CTRY_SWEDEN = 752, /* Sweden */ + CTRY_SWITZERLAND = 756, /* Switzerland */ + CTRY_SYRIA = 760, /* Syria */ + CTRY_TAIWAN = 158, /* Taiwan */ + CTRY_TANZANIA = 834, /* Tanzania */ + CTRY_THAILAND = 764, /* Thailand */ + CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ + CTRY_TUNISIA = 788, /* Tunisia */ + CTRY_TURKEY = 792, /* Turkey */ + CTRY_UAE = 784, /* U.A.E. */ + CTRY_UGANDA = 800, /* Uganda */ + CTRY_UKRAINE = 804, /* Ukraine */ + CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ + CTRY_UNITED_STATES = 840, /* United States */ + CTRY_UNITED_STATES2 = 841, /* United States for AP */ + CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/ + CTRY_URUGUAY = 858, /* Uruguay */ + CTRY_UZBEKISTAN = 860, /* Uzbekistan */ + CTRY_VENEZUELA = 862, /* Venezuela */ + CTRY_VIET_NAM = 704, /* Viet Nam */ + CTRY_YEMEN = 887, /* Yemen */ + CTRY_ZIMBABWE = 716, /* Zimbabwe */ + + /* + ** Japan special codes. Boy, do they have a lot + */ + + CTRY_JAPAN1 = 393, /* Japan (JP1) */ + CTRY_JAPAN2 = 394, /* Japan (JP0) */ + CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ + CTRY_JAPAN4 = 396, /* Japan (JE1) */ + CTRY_JAPAN5 = 397, /* Japan (JE2) */ + CTRY_JAPAN6 = 4006, /* Japan (JP6) */ + CTRY_JAPAN7 = 4007, /* Japan (J7) */ + CTRY_JAPAN8 = 4008, /* Japan (J8) */ + CTRY_JAPAN9 = 4009, /* Japan (J9) */ + CTRY_JAPAN10 = 4010, /* Japan (J10) */ + CTRY_JAPAN11 = 4011, /* Japan (J11) */ + CTRY_JAPAN12 = 4012, /* Japan (J12) */ + CTRY_JAPAN13 = 4013, /* Japan (J13) */ + CTRY_JAPAN14 = 4014, /* Japan (J14) */ + CTRY_JAPAN15 = 4015, /* Japan (J15) */ + CTRY_JAPAN16 = 4016, /* Japan (J16) */ + CTRY_JAPAN17 = 4017, /* Japan (J17) */ + CTRY_JAPAN18 = 4018, /* Japan (J18) */ + CTRY_JAPAN19 = 4019, /* Japan (J19) */ + CTRY_JAPAN20 = 4020, /* Japan (J20) */ + CTRY_JAPAN21 = 4021, /* Japan (J21) */ + CTRY_JAPAN22 = 4022, /* Japan (J22) */ + CTRY_JAPAN23 = 4023, /* Japan (J23) */ + CTRY_JAPAN24 = 4024, /* Japan (J24) */ + CTRY_JAPAN25 = 4025, /* Japan (J25) */ + CTRY_JAPAN26 = 4026, /* Japan (J26) */ + CTRY_JAPAN27 = 4027, /* Japan (J27) */ + CTRY_JAPAN28 = 4028, /* Japan (J28) */ + CTRY_JAPAN29 = 4029, /* Japan (J29) */ + CTRY_JAPAN30 = 4030, /* Japan (J30) */ + CTRY_JAPAN31 = 4031, /* Japan (J31) */ + CTRY_JAPAN32 = 4032, /* Japan (J32) */ + CTRY_JAPAN33 = 4033, /* Japan (J33) */ + CTRY_JAPAN34 = 4034, /* Japan (J34) */ + CTRY_JAPAN35 = 4035, /* Japan (J35) */ + CTRY_JAPAN36 = 4036, /* Japan (J36) */ + CTRY_JAPAN37 = 4037, /* Japan (J37) */ + CTRY_JAPAN38 = 4038, /* Japan (J38) */ + CTRY_JAPAN39 = 4039, /* Japan (J39) */ + CTRY_JAPAN40 = 4040, /* Japan (J40) */ + CTRY_JAPAN41 = 4041, /* Japan (J41) */ + CTRY_JAPAN42 = 4042, /* Japan (J42) */ + CTRY_JAPAN43 = 4043, /* Japan (J43) */ + CTRY_JAPAN44 = 4044, /* Japan (J44) */ + CTRY_JAPAN45 = 4045, /* Japan (J45) */ + CTRY_JAPAN46 = 4046, /* Japan (J46) */ + CTRY_JAPAN47 = 4047, /* Japan (J47) */ + CTRY_JAPAN48 = 4048, /* Japan (J48) */ + CTRY_JAPAN49 = 4049, /* Japan (J49) */ + CTRY_JAPAN50 = 4050, /* Japan (J50) */ + CTRY_JAPAN51 = 4051, /* Japan (J51) */ + CTRY_JAPAN52 = 4052, /* Japan (J52) */ + CTRY_JAPAN53 = 4053, /* Japan (J53) */ + CTRY_JAPAN54 = 4054, /* Japan (J54) */ + CTRY_JAPAN55 = 4055, /* Japan (J55) */ + CTRY_JAPAN56 = 4056, /* Japan (J56) */ + CTRY_JAPAN57 = 4057, /* Japan (J57) */ + CTRY_JAPAN58 = 4058, /* Japan (J58) */ + CTRY_JAPAN59 = 4059, /* Japan (J59) */ + + /* + ** "Special" codes for multiply defined countries, with the exception + ** of Japan and US. + */ + + CTRY_AUSTRALIA2 = 5000, /* Australia for AP only */ + CTRY_CANADA2 = 5001, /* Canada for AP only */ + CTRY_BELGIUM2 = 5002 /* Belgium/Cisco implementation */ +}; +int32_t regdmn_get_country_alpha2(struct regulatory *reg); +void regdmn_set_regval(struct regulatory *reg); +int32_t regdmn_find_ctry_by_name(u_int8_t *alpha2); +#endif /* REGULATORY_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain_common.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain_common.h new file mode 100644 index 0000000000000..913799ff3dad4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/regdomain_common.h @@ -0,0 +1,1864 @@ +/* + * Copyright (c) 2011 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* +* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting +* Copyright (c) 2005-2011 Atheros Communications, Inc. +* All rights reserved. +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $FreeBSD: release/9.0.0/sys/dev/ath/ath_hal/ah_regdomain/ah_rd_regenum.h 224226 2011-07-20 12:46:58Z adrian $ +*/ + /* + * This module contains the common regulatory domain database tables: + * + * - reg domain enum constants + * - reg domain enum to reg domain pair mappings + * - country to regdomain mappings + * - channel tag enums and the frequency-to-frequency band mappings + * for all the modes + * + * "The country table and respective Regulatory Domain channel and power + * settings are based on available knowledge as of software release. The + * underlying global regulatory and spectrum rules change on a regular basis, + * therefore, no warranty is given that the channel and power information + * herein is complete, accurate or up to date. Developers are responsible + * for regulatory compliance of end-products developed using the enclosed + * data per all applicable national requirements. Furthermore, data in this + * table does not guarantee that spectrum is available and that regulatory + * approval is possible in every case. Knowldegable regulatory compliance + * or government contacts should be consulted by the manufacturer to ensure + * that the most current and accurate settings are used in each end-product. + * This table was designed so that developers are able to update the country + * table mappings as well as the Regulatory Domain definitions in order to + * incorporate the most current channel and power settings in the end-product." + * + */ + +/* Enumerated Regulatory Domain Information 8 bit values indicate that + * the regdomain is really a pair of unitary regdomains. 12 bit values + * are the real unitary regdomains and are the only ones which have the + * frequency bitmasks and flags set. + */ + +#include "_ieee80211_common.h" +#include +#include "wlan_defs.h" + +#define MAX_CHANNELS_PER_OPERATING_CLASS 15 + +enum EnumRd { + /* + * The following regulatory domain definitions are + * found in the EEPROM. Each regulatory domain + * can operate in either a 5GHz or 2.4GHz wireless mode or + * both 5GHz and 2.4GHz wireless modes. + * In general, the value holds no special + * meaning and is used to decode into either specific + * 2.4GHz or 5GHz wireless mode for that particular + * regulatory domain. + */ + NO_ENUMRD = 0x00, + NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */ + NULL1_ETSIB = 0x07, /* Israel */ + NULL1_ETSIC = 0x08, + FCC1_FCCA = 0x10, /* USA */ + FCC1_WORLD = 0x11, /* Hong Kong */ + FCC4_FCCA = 0x12, /* USA - Public Safety */ + FCC5_FCCA = 0x13, /* US with no DFS (UNII-1 + UNII-3 Only)*/ + FCC6_FCCA = 0x14, /* Canada for AP only*/ + + FCC2_FCCA = 0x20, /* Canada */ + FCC2_WORLD = 0x21, /* Australia & HK */ + FCC2_ETSIC = 0x22, + FCC6_WORLD = 0x23, /* Australia for AP only*/ + FRANCE_RES = 0x31, /* Legacy France for OEM */ + FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */ + FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */ + FCC3_ETSIC = 0x3F, /* New Zealand, DFS enabled */ + + ETSI1_WORLD = 0x37, + ETSI3_ETSIA = 0x32, /* France (optional) */ + ETSI2_WORLD = 0x35, /* Hungary & others */ + ETSI3_WORLD = 0x36, /* France & others */ + ETSI4_WORLD = 0x30, + ETSI4_ETSIC = 0x38, + ETSI5_WORLD = 0x39, + ETSI6_WORLD = 0x34, /* Bulgaria */ + ETSI8_WORLD = 0x3D, /* Russia */ + ETSI9_WORLD = 0x3E, /* Ukraine */ + ETSI_RESERVED = 0x33, /* Reserved (Do not used) */ + + MKK1_MKKA = 0x40, /* Japan (JP1) */ + MKK1_MKKB = 0x41, /* Japan (JP0) */ + APL4_WORLD = 0x42, /* Singapore and Morocco */ + MKK2_MKKA = 0x43, /* Japan with 4.9G channels */ + APL_RESERVED = 0x44, /* Reserved (Do not used) */ + APL2_WORLD = 0x45, /* Korea */ + APL2_APLC = 0x46, + APL3_WORLD = 0x47, + MKK1_FCCA = 0x48, /* Japan (JP1-1) */ + APL2_APLD = 0x49, /* Korea with 2.3G channels */ + MKK1_MKKA1 = 0x4A, /* Japan (JE1) */ + MKK1_MKKA2 = 0x4B, /* Japan (JE2) */ + MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */ + APL2_FCCA = 0x4D, /* Mobile customer */ + APL11_FCCA = 0x4F, /* Specific AP Customer 5GHz, For APs Only */ + + APL3_FCCA = 0x50, + APL12_WORLD = 0x51, + APL1_WORLD = 0x52, /* Latin America */ + APL1_FCCA = 0x53, + APL1_APLA = 0x54, + APL1_ETSIC = 0x55, + APL2_ETSIC = 0x56, /* Venezuela */ + APL5_WORLD = 0x58, /* Chile */ + APL13_WORLD = 0x5A, /* Algeria */ + APL6_WORLD = 0x5B, /* Singapore */ + APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */ + APL8_WORLD = 0x5D, /* Malaysia 5GHz */ + APL9_WORLD = 0x5E, /* Korea 5GHz, Before 11/2007. Now used only by APs */ + APL10_WORLD = 0x5F, /* Korea 5GHz, After 11/2007. For STAs only */ + + /* + * World mode SKUs + */ + WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */ + WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */ + WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */ + WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */ + WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */ + WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */ + + WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */ + WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */ + EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */ + + WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */ + WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */ + WORB_WORLD = 0x6B, /* WorldB (WOB SKU) */ + WORC_WORLD = 0x6C, /* WorldC (WOC SKU) */ + + MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */ + MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */ + MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */ + + MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */ + MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */ + MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */ + + MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */ + MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */ + MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */ + + MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */ + MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */ + MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */ + + MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */ + MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */ + MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */ + + MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */ + MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */ + MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */ + + MKK14_MKKA1 = 0x92, /* Japan UNI-1 even + UNI-1 odd + 4.9GHz + MKKA1 */ + MKK15_MKKA1 = 0x93, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + 4.9GHz + MKKA1 */ + + MKK10_FCCA = 0xD0, /* Japan UNI-1 even + UNI-2 + 4.9GHz + FCCA */ + MKK10_MKKA1 = 0xD1, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA1 */ + MKK10_MKKC = 0xD2, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKC */ + MKK10_MKKA2 = 0xD3, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA2 */ + + MKK11_MKKA = 0xD4, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA */ + MKK11_FCCA = 0xD5, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + FCCA */ + MKK11_MKKA1 = 0xD6, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA1 */ + MKK11_MKKC = 0xD7, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKC */ + MKK11_MKKA2 = 0xD8, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA2 */ + + MKK12_MKKA = 0xD9, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA */ + MKK12_FCCA = 0xDA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + FCCA */ + MKK12_MKKA1 = 0xDB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA1 */ + MKK12_MKKC = 0xDC, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKC */ + MKK12_MKKA2 = 0xDD, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA2 */ + + MKK13_MKKB = 0xDE, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB + All passive + no adhoc */ + + /* Following definitions are used only by s/w to map old + * Japan SKUs. + */ + MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */ + MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */ + MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */ + MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */ + MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */ + MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */ + MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */ + MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */ + MKK6_MKKA1 = 0xF8, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA1 */ + MKK6_FCCA = 0xF9, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + FCCA */ + MKK7_MKKA1 = 0xFA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA1 */ + MKK7_FCCA = 0xFB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + FCCA */ + MKK9_FCCA = 0xFC, /* Japan UNI-1 even + 4.9GHz + FCCA */ + MKK9_MKKA1 = 0xFD, /* Japan UNI-1 even + 4.9GHz + MKKA1 */ + MKK9_MKKC = 0xFE, /* Japan UNI-1 even + 4.9GHz + MKKC */ + MKK9_MKKA2 = 0xFF, /* Japan UNI-1 even + 4.9GHz + MKKA2 */ + + /* + * Regulator domains ending in a number (e.g. APL1, + * MK1, ETSI4, etc) apply to 5GHz channel and power + * information. Regulator domains ending in a letter + * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and + * power information. + */ + APL1 = 0x0150, /* LAT & Asia */ + APL2 = 0x0250, /* LAT & Asia */ + APL3 = 0x0350, /* Taiwan */ + APL4 = 0x0450, /* Jordan */ + APL5 = 0x0550, /* Chile */ + APL6 = 0x0650, /* Singapore */ + APL7 = 0x0750, /* Taiwan, disable ch52 */ + APL8 = 0x0850, /* Malaysia */ + APL9 = 0x0950, /* Korea. Before 11/2007. Now used only by APs */ + APL10 = 0x1050, /* Korea. After 11/2007. For STAs only */ + APL11 = 0x1150, /* Specific AP Customer 5GHz, For APs Only */ + APL12 = 0x1160, /* Kenya */ + + ETSI1 = 0x0130, /* Europe & others */ + ETSI2 = 0x0230, /* Europe & others */ + ETSI3 = 0x0330, /* Europe & others */ + ETSI4 = 0x0430, /* Europe & others */ + ETSI5 = 0x0530, /* Europe & others */ + ETSI6 = 0x0630, /* Europe & others */ + ETSI8 = 0x0830, /* Russia */ + ETSI9 = 0x0930, /* Ukraine */ + ETSIA = 0x0A30, /* France */ + ETSIB = 0x0B30, /* Israel */ + ETSIC = 0x0C30, /* Latin America */ + + FCC1 = 0x0110, /* US & others */ + FCC2 = 0x0120, /* Canada, Australia & New Zealand */ + FCC3 = 0x0160, /* US w/new middle band & DFS */ + FCC4 = 0x0165, /* US Public Safety */ + FCC5 = 0x0510, + FCC6 = 0x0610, /* Canada & Australia */ + FCCA = 0x0A10, + + APLD = 0x0D50, /* South Korea */ + + MKK1 = 0x0140, /* Japan (UNI-1 odd)*/ + MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */ + MKK3 = 0x0340, /* Japan (UNI-1 even) */ + MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */ + MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */ + MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */ + MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */ + MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */ + MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */ + MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + MKK11 = 0x1140, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + MKK12 = 0x1240, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + MKK13 = 0x0C40, /* Same as MKK8 but all passive and no adhoc 11a */ + MKK14 = 0x1440, /* Japan UNI-1 even + UNI-1 odd + 4.9GHz */ + MKK15 = 0x1540, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + 4.9GHz */ + MKKA = 0x0A40, /* Japan */ + MKKC = 0x0A50, + + NULL1 = 0x0198, + WORLD = 0x0199, + DEBUG_REG_DMN = 0x01ff, +}; + +enum { /* conformance test limits */ + FCC = 0x10, + MKK = 0x40, + ETSI = 0x30, +}; +/* + * The following are flags for different requirements per reg domain. + * These requirements are either inhereted from the reg domain pair or + * from the unitary reg domain if the reg domain pair flags value is + * 0 + */ + +enum { + NO_REQ = 0x00000000, + DISALLOW_ADHOC_11A = 0x00000001, + DISALLOW_ADHOC_11A_TURB = 0x00000002, + NEED_NFC = 0x00000004, + + ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */ + ADHOC_NO_11A = 0x00000010, + + PUBLIC_SAFETY_DOMAIN = 0x00000020, /* public safety domain */ + LIMIT_FRAME_4MS = 0x00000040, /* 4msec limit on the frame length */ + + NO_HOSTAP = 0x00000080, /* No HOSTAP mode opereation */ + + REQ_MASK = 0x000000FF, /* Requirements bit mask */ +}; + +static const REG_DMN_PAIR_MAPPING ahCmnRegDomainPairs[] = { + {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC3_ETSIC, FCC3, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI8_WORLD, ETSI8, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI9_WORLD, ETSI9, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + + {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_FCCA, APL2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL7_FCCA, APL7, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL10_WORLD, APL10, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN }, + {MKK1_MKKB, MKK1, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 }, + {MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 }, + {MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 }, + {MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 }, + {MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 }, + + /* MKK2 */ + {MKK2_MKKA, MKK2, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 }, + + /* MKK3 */ + {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, CTRY_JAPAN25 }, + {MKK3_MKKB, MKK3, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 }, + {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26 }, + {MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 }, + {MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 }, + {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN27 }, + + /* MKK4 */ + {MKK4_MKKA, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN36 }, + {MKK4_MKKB, MKK4, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 }, + {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28 }, + {MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 }, + {MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 }, + {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN29 }, + + /* MKK5 */ +/* {MKK5_MKKA, MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN56 },*/ + {MKK5_MKKB, MKK5, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 }, + {MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 }, + {MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 }, +/* {MKK5_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN57 },*/ + + /* MKK6 */ + {MKK6_MKKB, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16 }, + {MKK6_MKKA1,MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30 }, + {MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 }, + {MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 }, + {MKK6_FCCA, MKK6, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN31 }, + + /* MKK7 */ + {MKK7_MKKB, MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN19 }, + {MKK7_MKKA1,MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32 }, + {MKK7_MKKA2, MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN20 }, + {MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 }, + {MKK7_FCCA, MKK7, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33 }, + + /* MKK8 */ + {MKK8_MKKB, MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN22 }, + {MKK8_MKKA2,MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 }, + {MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 }, + + {MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN34 }, + {MKK9_FCCA, MKK9, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN37 }, + {MKK9_MKKA1, MKK9, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38 }, + {MKK9_MKKA2, MKK9, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40 }, + {MKK9_MKKC, MKK9, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN39 }, + + {MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN35 }, + {MKK10_FCCA, MKK10, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 , CTRY_JAPAN41 }, + {MKK10_MKKA1, MKK10, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42 }, + {MKK10_MKKA2, MKK10, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44 }, + {MKK10_MKKC, MKK10, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN43 }, + + {MKK11_MKKA, MKK11, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN45 }, + {MKK11_FCCA, MKK11, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN46 }, + {MKK11_MKKA1, MKK11, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47 }, + {MKK11_MKKA2, MKK11, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49 }, + {MKK11_MKKC, MKK11, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN48 }, + + {MKK12_MKKA, MKK12, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50 }, + {MKK12_FCCA, MKK12, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51 }, + {MKK12_MKKA1, MKK12, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN52 }, + {MKK12_MKKA2, MKK12, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN54 }, + {MKK12_MKKC, MKK12, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53 }, + + {MKK13_MKKB, MKK13, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN57 }, + + {MKK14_MKKA1, MKK14, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58 }, + {MKK15_MKKA1, MKK15, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59 }, + + /* These are super domains */ + {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WORB_WORLD, WORB_WORLD, WORB_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WORC_WORLD, WORC_WORLD, WORC_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, +}; + +static const COUNTRY_CODE_TO_ENUM_RD ahCmnAllCountries[] = { + {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_ARGENTINA, FCC3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_ARUBA, ETSI1_WORLD, "AW", "ARUBA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_AUSTRALIA, FCC3_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BAHAMAS, FCC3_WORLD, "BS", "BAHAMAS", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_BANGLADESH, NULL1_WORLD, "BD", "BANGLADESH", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_BARBADOS, FCC2_WORLD, "BB", "BARBADOS", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BELGIUM2, ETSI4_WORLD, "BE", "BELGIUM2", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BERMUDA, FCC3_FCCA, "BM", "BERMUDA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLIVIA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA AND HERZEGOVINA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BRUNEI_DARUSSALAM, APL6_WORLD, "BN", "BRUNEI DARUSSALAM", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_BULGARIA, ETSI1_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CAMBODIA, ETSI1_WORLD, "KH", "CAMBODIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CANADA, FCC3_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_CROATIA, ETSI1_WORLD, "HR", "CROATIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_CZECH, ETSI1_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_GREENLAND, ETSI1_WORLD, "GL", "GREENLAND", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_GRENADA, FCC3_FCCA, "GD", "GRENADA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_GUAM, FCC1_FCCA, "GU", "GUAM", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_HAITI, ETSI1_WORLD, "HT", "HAITI", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_HONDURAS, FCC3_WORLD, "HN", "HONDURAS", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_HONG_KONG, FCC3_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_INDONESIA, APL2_WORLD, "ID", "INDONESIA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ISRAEL, ETSI3_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_JAMAICA, FCC3_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES, YES, NO, NO, 7000 }, + {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, +/* {CTRY_JAPAN55, MKK5_MKKA, "JP", "JAPAN55", YES, NO, NO, YES, YES, YES, YES, NO, 7000 },*/ +/* {CTRY_JAPAN56, MKK5_FCCA, "JP", "JAPAN56", YES, NO, NO, YES, YES, YES, YES, NO, 7000 },*/ + {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_KENYA, APL1_WORLD, "KE", "KENYA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO, YES, NO, YES, NO, NO, 7000 }, + {CTRY_KOREA_ROC, APL10_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO, YES, YES, YES, YES, YES, 7000 }, + {CTRY_KOREA_ROC3, APL9_WORLD, "KR", "KOREA REPUBLIC3", YES, NO, NO, YES, NO, YES, NO, NO, 7000 }, + {CTRY_KUWAIT, ETSI3_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_LEBANON, APL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU SAR", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MACEDONIA, ETSI1_WORLD, "MK", "MACEDONIA, FYRO", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MALAYSIA, FCC1_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MAURITIUS, ETSI1_WORLD, "MU", "MAURITIUS", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MEXICO, FCC1_WORLD, "MX", "MEXICO", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MOROCCO, APL4_WORLD, "MA", "MOROCCO", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN", "NETHERLANDS ANTILLES", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NEW_ZEALAND, FCC3_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NICARAGUA, FCC3_FCCA, "NI", "NICARAGUA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_OMAN, FCC3_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PAKISTAN, APL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PARAGUAY, FCC3_WORLD, "PY", "PARAGUAY", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PERU, FCC3_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PHILIPPINES, FCC3_WORLD, "PH", "PHILIPPINES", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_QATAR, APL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_ROMANIA, ETSI1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_RUSSIA, ETSI8_WORLD, "RU", "RUSSIA", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_RWANDA, APL1_WORLD, "RW", "RWANDA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SAUDI_ARABIA, FCC2_WORLD, "SA", "SAUDI ARABIA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_SERBIA, ETSI1_WORLD, "RS", "REPUBLIC OF SERBIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_MONTENEGRO, ETSI1_WORLD, "ME", "MONTENEGRO", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SINGAPORE, FCC3_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAKIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIAN ARAB REPUBLIC", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_TAIWAN, APL7_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_TANZANIA, APL1_WORLD, "TZ", "TANZANIA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_THAILAND, FCC3_WORLD, "TH", "THAILAND", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT", "TRINIDAD AND TOBAGO", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES, YES, NO, NO, 7000 }, + {CTRY_UGANDA, APL10_WORLD, "UG", "UGANDA", YES, NO, NO, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UKRAINE, ETSI9_WORLD, "UA", "UKRAINE", YES, NO, NO, YES, YES, YES, YES, NO, 7000 }, + {CTRY_UGANDA, APL10_WORLD, "UG", "UGANDA", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UAE, ETSI1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES, YES, YES, YES, YES, YES, YES, 5825 }, + {CTRY_UNITED_STATES2, FCC6_FCCA, "US", "UNITED STATES2", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_URUGUAY, FCC3_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_VENEZUELA, FCC1_WORLD, "VE", "VENEZUELA", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_VIET_NAM, ETSI3_WORLD, "VN", "VIET NAM", YES, NO, YES, YES, YES, YES, YES, YES, 7000 }, + {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES, NO, NO, NO, 7000 }, + {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES, YES, NO, NO, NO, 7000 } +}; + + +/* Bit masks for DFS per regdomain */ + +enum { + NO_DFS = 0x0000000000000000ULL, + DFS_FCC3 = 0x0000000000000001ULL, + DFS_ETSI = 0x0000000000000002ULL, + DFS_MKK4 = 0x0000000000000004ULL, +}; + + +/* The table of frequency bands is indexed by a bitmask. The ordering + * must be consistent with the enum below. When adding a new + * frequency band, be sure to match the location in the enum with the + * comments + */ + +/* + * 5GHz 11A channel tags + */ +enum { + F1_4912_4947, + F1_4915_4925, + F2_4915_4925, + F1_4935_4945, + F2_4935_4945, + F1_4920_4980, + F2_4920_4980, + F1_4942_4987, + F1_4945_4985, + F1_4950_4980, + F1_5032_5057, + F1_5035_5040, + F2_5035_5040, + F1_5035_5045, + F1_5040_5040, + F1_5040_5080, + F2_5040_5080, + F1_5055_5055, + F2_5055_5055, + + F1_5120_5240, + + F1_5170_5230, + F2_5170_5230, + + F1_5180_5240, + F2_5180_5240, + F3_5180_5240, + F4_5180_5240, + F5_5180_5240, + F6_5180_5240, + F7_5180_5240, + F8_5180_5240, + F9_5180_5240, + F10_5180_5240, + + F1_5240_5280, + + F1_5260_5280, + + F1_5260_5320, + F2_5260_5320, + F3_5260_5320, + F4_5260_5320, + F5_5260_5320, + F6_5260_5320, + F7_5260_5320, + + F1_5260_5700, + + F1_5280_5320, + F2_5280_5320, + F1_5500_5560, + + F1_5500_5580, + F2_5500_5580, + + F1_5500_5620, + + F1_5500_5660, + + F1_5500_5720, + F2_5500_5700, + F3_5500_5700, + F4_5500_5700, + F5_5500_5700, + F6_5500_5700, + + F1_5660_5700, + F2_5660_5720, + F3_5660_5720, + + F1_5745_5765, + + F1_5745_5805, + F2_5745_5805, + F3_5745_5805, + F4_5745_5805, + + F1_5745_5825, + F2_5745_5825, + F3_5745_5825, + F4_5745_5825, + F5_5745_5825, + F6_5745_5825, + F7_5745_5825, + F8_5745_5825, + F9_5745_5825, + + F1_5845_5865, + + W1_4920_4980, + W1_5040_5080, + W1_5170_5230, + W1_5180_5240, + W1_5260_5320, + W1_5745_5825, + W1_5500_5700, + A_DEMO_ALL_CHANNELS +}; + +static const REG_DMN_FREQ_BAND regDmn5GhzFreq[] = { + { 4915, 4925, 20, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4915_4925 */ + { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F2_4915_4925 */ + { 4935, 4945, 20, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4935_4945 */ + { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F2_4935_4945 */ + { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 }, /* F1_4920_4980 */ + { 4920, 4980, 20, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 }, /* F2_4920_4980 */ + { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4942_4987 */ + { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4945_4985 */ + { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4950_4980 */ + { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5035_5040 */ + { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F2_5035_5040 */ + { 5040, 5040, 20, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5040_5040 */ + { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 }, /* F1_5040_5080 */ + { 5040, 5080, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 6 }, /* F2_5040_5080 */ + { 5055, 5055, 20, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5055_5055 */ + { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F2_5055_5055 */ + + { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5120_5240 */ + + { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F1_5170_5230 */ + { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F2_5170_5230 */ + + { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 1 }, /* F1_5180_5240 */ + { 5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1 }, /* F2_5180_5240 */ + { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 1 }, /* F3_5180_5240 */ + { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 1 }, /* F4_5180_5240 */ + { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 1 }, /* F5_5180_5240 */ + { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 }, /* F6_5180_5240 */ + { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0 }, /* F7_5180_5240 */ + { 5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 1 }, /* F8_5180_5240 */ + { 5180, 5240, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0 }, /* F9_5180_5240 */ + { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 1 }, /* F10_5180_5240 */ + + { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5240_5280 */ + + { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 2 }, /* F1_5260_5280 */ + + { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 2 }, /* F1_5260_5320 */ + + { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 }, + /* F2_5260_5320 */ + + { 5260, 5320, 24, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 2 },/* F3_5260_5320 */ + { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F4_5260_5320 */ + { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F5_5260_5320 */ + { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 2 }, /* F6_5260_5320 */ + { 5260, 5320, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 }, + /* F7_5260_5320 */ + + { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 }, /* F1_5260_5700 */ + + { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F1_5280_5320 */ + + { 5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 4}, /* F1_5500_5580 */ + { 5500, 5580, 30, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 4}, /* F2_5500_5580 */ + + { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 3 }, /* F1_5500_5620 */ + + { 5500, 5660, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5500_5660 */ + + { 5500, 5720, 24, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 }, /* F1_5500_5720 */ + { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 3 }, /* F2_5500_5700 */ + { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 3 }, /* F3_5500_5700 */ + { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },/* F4_5500_5700 */ + { 5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F5_5500_5700 */ + { 5500, 5700, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },/* F6_5500_5700 */ + + { 5660, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 4}, /* F1_5660_5700 */ + { 5660, 5700, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 4}, /* F2_5660_5700 */ + { 5660, 5700, 30, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 4}, /* F3_5660_5700 */ + + { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 3 }, /* F1_5745_5805 */ + { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 }, /* F2_5745_5805 */ + { 5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0 }, /* F3_5745_5805 */ + { 5745, 5805, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F4_5745_5805 */ + + { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 5 }, /* F1_5745_5825 */ + { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 5 }, /* F2_5745_5825 */ + { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F3_5745_5825 */ + { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F4_5745_5825 */ + { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 5 }, /* F5_5745_5825 */ + { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 5 }, /* F6_5745_5825 */ + { 5745, 5825, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0 }, /* F7_5745_5825 */ + { 5745, 5825, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0 }, /* F8_5745_5825 */ + + /* + * Below are the world roaming channels + * All WWR domains have no power limit, instead use the card's CTL + * or max power settings. + */ + { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_4920_4980 */ + { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5040_5080 */ + { 5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5170_5230 */ + { 5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5180_5240 */ + { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5260_5320 */ + { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5745_5825 */ + { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5500_5700 */ + { 4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* A_DEMO_ALL_CHANNELS */ +}; + +/* + * 2GHz 11b channel tags + */ +enum { + F1_2312_2372, + F2_2312_2372, + + F1_2412_2472, + F2_2412_2472, + F3_2412_2472, + F4_2412_2472, + + F1_2412_2462, + F2_2412_2462, + + F1_2432_2442, + + F1_2457_2472, + + F1_2467_2472, + + F1_2484_2484, + F2_2484_2484, + + F1_2512_2732, + + W1_2312_2372, + W1_2412_2412, + W1_2417_2432, + W1_2437_2442, + W1_2447_2457, + W1_2462_2462, + W1_2467_2467, + W2_2467_2467, + W1_2472_2472, + W2_2472_2472, + W1_2484_2484, + W2_2484_2484, +}; + +static const REG_DMN_FREQ_BAND regDmn2GhzFreq[] = { + { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2312_2372 */ + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F2_2312_2372 */ + + { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 30},/* F2_2412_2472 */ + { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 4}, /* F3_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, /* F4_2412_2472 */ + + { 2412, 2462, 30, 6, 20, 5, NO_DFS, NO_PSCAN, 12}, /* F1_2412_2462 */ + { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 30}, /* F2_2412_2462 */ + + { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 4}, /* F1_2432_2442 */ + + { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2457_2472 */ + + { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 30}, /* F1_2467_2472 */ + + { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2484_2484 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 31}, /* F2_2484_2484 */ + + { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2512_2732 */ + + /* + * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers + */ + + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2312_2372 */ + { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2412_2412 */ + { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2417_2432 */ + { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2437_2442 */ + { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2447_2457 */ + { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2462_2462 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2467_2467 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2467_2467 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2472_2472 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2472_2472 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2484_2484 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2484_2484 */ +}; + +/* + * 2GHz 11g channel tags + */ + +enum { + G1_2312_2372, + G2_2312_2372, + + G1_2412_2472, + G2_2412_2472, + G3_2412_2472, + G4_2412_2472, + + G1_2412_2462, + G2_2412_2462, + + G1_2432_2442, + + G1_2457_2472, + + G1_2512_2732, + + G1_2467_2472, + G2_2467_2472, + + G1_2484_2484, + + WG1_2312_2372, + WG1_2412_2462, + WG1_2412_2472, + WG2_2412_2472, + G_DEMO_ALMOST_ALL_CHANNELS, + G_DEMO_ALL_CHANNELS, +}; + +static const REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = { + { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2312_2372 */ + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G2_2312_2372 */ + + { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G | PSCAN_MKKA2 | PSCAN_MKKA | PSCAN_EXT_CHAN, 30}, /* G2_2412_2472 */ + { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 4}, /* G3_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G | PSCAN_MKKA2 | PSCAN_MKKA | PSCAN_EXT_CHAN, 0}, /* G4_2412_2472 */ + + { 2412, 2462, 30, 6, 20, 5, NO_DFS, NO_PSCAN, 12}, /* G1_2412_2462 */ + { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 30}, /* G2_2412_2462 */ + + { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 4}, /* G1_2432_2442 */ + + { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2457_2472 */ + + { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2512_2732 */ + + { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 30 }, /* G1_2467_2472 */ + { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G | PSCAN_MKKA2, 0 }, /* G2_2467_2472 */ + + { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2484_2484 */ + /* + * WWR open up the power to 20dBm + */ + + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2312_2372 */ + { 2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2412_2462 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN | PSCAN_EXT_CHAN, 0}, /* WG1_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* WG2_2412_2472 */ + { 2312, 2532, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G_DEMO_ALMOST_ALL_CHANNELS */ + { 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G_DEMO_ALL_CHANNELS */ +}; + +/* regulatory capabilities */ +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U2 0x0100 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200 +#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400 + +static const JAPAN_BANDCHECK j_bandcheck[] = { + {F1_5170_5230, REGDMN_EEPROM_EEREGCAP_EN_KK_U1_ODD}, + {F4_5180_5240, REGDMN_EEPROM_EEREGCAP_EN_KK_U1_EVEN}, + {F2_5260_5320, REGDMN_EEPROM_EEREGCAP_EN_KK_U2}, + {F4_5500_5700, REGDMN_EEPROM_EEREGCAP_EN_KK_MIDBAND} +}; + +static const COMMON_MODE_POWER common_mode_pwrtbl[] = { + { 4900, 5000, 17 }, + { 5000, 5100, 17 }, + { 5150, 5250, 17 }, /* ETSI & MKK */ + { 5250, 5350, 18 }, /* ETSI */ + { 5470, 5725, 20 }, /* ETSI */ + { 5725, 5825, 20 }, /* Singapore */ + { 5825, 5850, 23 } /* Korea */ +}; + +/* + * 5GHz Turbo (dynamic & static) tags + */ + +enum { + T1_5130_5650, + T1_5150_5670, + + T1_5200_5200, + T2_5200_5200, + T3_5200_5200, + T4_5200_5200, + T5_5200_5200, + T6_5200_5200, + T7_5200_5200, + T8_5200_5200, + + T1_5200_5280, + T2_5200_5280, + T3_5200_5280, + T4_5200_5280, + T5_5200_5280, + T6_5200_5280, + + T1_5200_5240, + T1_5210_5210, + T2_5210_5210, + T3_5210_5210, + T4_5210_5210, + T5_5210_5210, + T6_5210_5210, + T7_5210_5210, + T8_5210_5210, + T9_5210_5210, + T10_5210_5210, + T1_5240_5240, + + T1_5210_5250, + T1_5210_5290, + T2_5210_5290, + T3_5210_5290, + + T1_5280_5280, + T2_5280_5280, + T1_5290_5290, + T2_5290_5290, + T3_5290_5290, + T1_5250_5290, + T2_5250_5290, + T3_5250_5290, + T4_5250_5290, + + T1_5540_5660, + T2_5540_5660, + T3_5540_5660, + T1_5760_5800, + T2_5760_5800, + T3_5760_5800, + T4_5760_5800, + T5_5760_5800, + T6_5760_5800, + T7_5760_5800, + + T1_5765_5805, + T2_5765_5805, + T3_5765_5805, + T4_5765_5805, + T5_5765_5805, + T6_5765_5805, + T7_5765_5805, + T8_5765_5805, + T9_5765_5805, + + WT1_5210_5250, + WT1_5290_5290, + WT1_5540_5660, + WT1_5760_5800, +}; + +/* + * 2GHz Dynamic turbo tags + */ +#ifndef ATH_REMOVE_2G_TURBO_RD_TABLE +enum { + T1_2312_2372, + T1_2437_2437, + T2_2437_2437, + T3_2437_2437, + T1_2512_2732 +}; + +static const REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = { + { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2312_2372 */ + { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2437_2437 */ + { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_2437_2437 */ + { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0}, /* T3_2437_2437 */ + { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2512_2732 */ +}; +#endif /* ATH_REMOVE_2G_TURBO_RD_TABLE */ + +static const REG_DOMAIN ahCmnRegDomains[] = { + + {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ, + CHAN_11A_BM(A_DEMO_ALL_CHANNELS, F6_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(T1_5130_5650, T1_5150_5670, F6_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, + -1, -1, -1, -1, -1, -1, -1, -1) + BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, + -1, -1, -1, -1, -1, -1, -1, -1), + BM(G_DEMO_ALMOST_ALL_CHANNELS, + G1_2484_2484, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL3, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ, + BM(F1_5280_5320, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F5_5180_5240, F9_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC , NO_REQ, + BM(F9_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL7, FCC, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI , NO_REQ, + BM(F2_5280_5320, F2_5500_5580, F3_5660_5720, F7_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL8, ETSI, NO_DFS, NO_PSCAN, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL9, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F9_5180_5240, F2_5260_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL10, ETSI, DFS_ETSI, PSCAN_ETSI , DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F9_5180_5240, F2_5260_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL11, ETSI, DFS_ETSI, PSCAN_ETSI , DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F9_5180_5240, F2_5260_5320, F5_5500_5700, F7_5745_5825, F1_5845_5865, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {APL12, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F5_5180_5240, F1_5500_5560, F1_5745_5765, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F2_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {ETSI8, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, F1_5660_5700, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO + }, + + {ETSI9, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, F1_5500_5660, F8_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO + }, + + {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, + BM(F2_5180_5240, F3_5260_5320, F1_5500_5720, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + /* + + Bug Fix: EV 98583 Public Safety channel + Exclude the following channel in FCC Public safety domain + Uni-1: 5180, 5200, 5220, 5240 + Uni-2: 5260, 5280, 5300, 5320 + Uni-3: 5745, 5765, 5785, 5805, 5825 + */ + {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, + BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ, + BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F2_5660_5720, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1), + BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {MKK1, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_5170_5230, F10_5180_5240, F7_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + {MKK2, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F2_4915_4925, F2_4935_4945, F1_4920_4980, F1_5035_5040, F2_5055_5055, F1_5040_5080, F1_5170_5230, F10_5180_5240, -1, -1, -1, -1), + BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 even */ + {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 even + UNI-2 */ + {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 even + UNI-2 + mid-band */ + {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, F6_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + even */ + {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + UNI-1 even + UNI-2 */ + {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */ + {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, F2_5260_5320, F6_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 even + 4.9 GHZ */ + {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4912_4947, F1_5032_5057, F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5035_5045, F1_5055_5055, F2_5040_5080, F4_5180_5240, -1, -1, -1), + BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 even + UNI-2 + 4.9 GHZ */ + {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4912_4947, F1_5032_5057, F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5035_5045, F1_5055_5055, F2_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz */ + {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4912_4947, F1_5032_5057, F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5035_5045, F1_5055_5055, F2_5040_5080, F4_5180_5240, F2_5260_5320, F6_5500_5700, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz */ + {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5040_5040, F1_5055_5055, F2_5040_5080, F2_5170_5230, F4_5180_5240, F2_5260_5320, F6_5500_5700, -1, -1), + BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */ + {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F7_5180_5240, F2_5260_5320, F6_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + UNI-1 even + 4.9GHz */ + {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5040_5040, F2_5040_5080, F1_5055_5055, F2_5170_5230, F4_5180_5240, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /* UNI-1 odd + UNI-1 even + UNI-2 + 4.9GHz */ + {MKK15, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F2_4920_4980, F1_5040_5040, F2_5040_5080, F1_5055_5055, F2_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, + + /*=== 2 GHz ===*/ + + /* Defined here to use when 2G channels are authorised for country K2 */ + {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F2_2312_2372, F4_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2312_2372,G4_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BMZERO + }, + + {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {MKKA, MKK, NO_DFS, PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, + -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(F4_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G4_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, + -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + W1_5500_5700, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, + -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + W1_5500_5700, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + W1_5500_5700, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, W1_2417_2432, + W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), + BM(WG2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + W1_5500_5700, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + W1_5500_5700, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, + -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, + -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, + -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, + -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, + -1, -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {WORC_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + CHAN_11A_BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, W1_5745_5825, + -1, -1, -1, -1, -1, -1, -1, -1) + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, + W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + CHAN_TURBO_G_BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1) + }, + + {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, + CHAN_11A_BMZERO + CHAN_11A_BMZERO + CHAN_11A_BMZERO + BMZERO, + BMZERO, + CHAN_TURBO_G_BMZERO + }, +}; + +static const struct cmode modes[] = { + { REGDMN_MODE_TURBO, IEEE80211_CHAN_ST}, /* TURBO means 11a Static Turbo */ + { REGDMN_MODE_11A, IEEE80211_CHAN_A}, + { REGDMN_MODE_11B, IEEE80211_CHAN_B}, + { REGDMN_MODE_11G, IEEE80211_CHAN_PUREG}, + { REGDMN_MODE_11G_TURBO, IEEE80211_CHAN_108G}, + { REGDMN_MODE_11A_TURBO, IEEE80211_CHAN_108A}, + { REGDMN_MODE_11NG_HT20, IEEE80211_CHAN_11NG_HT20}, + { REGDMN_MODE_11NG_HT40PLUS, IEEE80211_CHAN_11NG_HT40PLUS}, + { REGDMN_MODE_11NG_HT40MINUS, IEEE80211_CHAN_11NG_HT40MINUS}, + { REGDMN_MODE_11NA_HT20, IEEE80211_CHAN_11NA_HT20}, + { REGDMN_MODE_11NA_HT40PLUS, IEEE80211_CHAN_11NA_HT40PLUS}, + { REGDMN_MODE_11NA_HT40MINUS, IEEE80211_CHAN_11NA_HT40MINUS}, + { REGDMN_MODE_11AC_VHT20, IEEE80211_CHAN_11AC_VHT20}, + { REGDMN_MODE_11AC_VHT40PLUS, IEEE80211_CHAN_11AC_VHT40PLUS}, + { REGDMN_MODE_11AC_VHT40MINUS, IEEE80211_CHAN_11AC_VHT40MINUS}, + { REGDMN_MODE_11AC_VHT80, IEEE80211_CHAN_11AC_VHT80}, + { REGDMN_MODE_11AC_VHT20_2G, IEEE80211_CHAN_11AC_VHT20_2G}, + { REGDMN_MODE_11AC_VHT40_2G, IEEE80211_CHAN_11AC_VHT40_2G}, + { REGDMN_MODE_11AC_VHT80_2G, IEEE80211_CHAN_11AC_VHT80_2G}, +}; + +typedef enum offset +{ + BW20 = 0, + BW40_LOW_PRIMARY = 1, + BW40_HIGH_PRIMARY = 3, + BWALL +} offset_t; + +typedef struct _regdm_op_class_map +{ + u_int8_t op_class; + u_int8_t ch_spacing; + offset_t offset; + u_int8_t channels[MAX_CHANNELS_PER_OPERATING_CLASS]; +} regdm_op_class_map_t; + +typedef struct _regdm_supp_op_classes { + u_int8_t num_classes; + u_int8_t classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +} regdm_supp_op_classes; + +u_int16_t regdm_get_opclass_from_channel(u_int8_t *country, u_int8_t channel, + u_int8_t offset); +u_int16_t regdm_set_curr_opclasses(u_int8_t num_classes, u_int8_t *class); +u_int16_t regdm_get_curr_opclasses(u_int8_t *num_classes, u_int8_t *class); + diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_nv.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_nv.c new file mode 100644 index 0000000000000..d273e218ef692 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_nv.c @@ -0,0 +1,5375 @@ +/* + * Copyright (c) "2012,2014" The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file wlan_nv.c + + \brief Contains collection of table default values to use in + case a table is not found in NV + + $Id$ + + ========================================================================== */ + +#ifndef WLAN_NV_C +#define WLAN_NV_C + +#include "palTypes.h" +#include "wlan_nv.h" + +const sHalNv nvDefaults = +{ + { + 0, // tANI_U16 productId; + 1, // tANI_U8 productBands; + 2, // tANI_U8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: WCN3660 + 1, // tANI_U8 numOfTxChains; + 1, // tANI_U8 numOfRxChains; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { "\0" }, + 0, // tANI_U8 couplerType; + WLAN_NV_VERSION, // tANI_U8 nvVersion; + }, //fields + + { + // NV_TABLE_RATE_POWER_SETTINGS + { + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + //2.4G + { + //802.11b Rates + {1900}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + //11A 20MHz Rates + {1700}, // HAL_PHY_RATE_11A_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_48_MBPS, + {1550}, // HAL_PHY_RATE_11A_54_MBPS, + + //DUP 11A 40MHz Rates + {1700}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + //MCS Index #0-7(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + //MCS Index #8-15(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATURE_11AC + //11AC rates + //11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + //11ac 20MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + + //11ac 40MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + //11ac 80MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_2_4_GHZ + // 5G Low + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DUP 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11AC rates + ///11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11ac 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + //11ac 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_LOW_GHZ + // 5G Mid + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_111AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // // RF_SUBBAND_5_MID_GHZ + // 5G High + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_HIGH_GHZ, + // 4.9G + + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500,, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_4_9_GHZ + }, + + // NV_TABLE_REGULATORY_DOMAINS + { + // typedef struct + // { + // tANI_BOOLEAN enabled; + // tPowerdBm pwrLimit; + // }sRegulatoryChannel; + + // typedef struct + // { + // sRegulatoryChannel channels[NUM_RF_CHANNELS]; + // uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + // uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + // }sRegulatoryDomains; + + //sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; + + + { // REG_DOMAIN_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_FCC end + + { // REG_DOMAIN_ETSI start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_ETSI end + + { // REG_DOMAIN_JAPAN start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_13, + {NV_CHANNEL_ENABLE, 18}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_JAPAN end + + { // REG_DOMAIN_WORLD start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_WORLD end + + { // REG_DOMAIN_N_AMER_EXC_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_N_AMER_EXC_FCC end + + { // REG_DOMAIN_APAC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_APAC end + + { // REG_DOMAIN_KOREA start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_KOREA end + + { // REG_DOMAIN_HI_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_HI_5GHZ end + + { // REG_DOMAIN_NO_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + } // REG_DOMAIN_NO_5GHZ end + }, + + // NV_TABLE_DEFAULT_COUNTRY + { + // typedef struct + // { + // tANI_U8 regDomain; //from eRegDomainId + // tANI_U8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; // string identifier + // }sDefaultCountry; + + 0, // regDomain + { 'U', 'S', 'I' } // countryCode + }, + + //NV_TABLE_TPC_POWER_TABLE + { + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 60 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 65 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 78 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 82 , //35 + 83 , //36 + 83 , //37 + 84 , //38 + 85 , //39 + 86 , //40 + 86 , //41 + 87 , //42 + 88 , //43 + 89 , //44 + 89 , //45 + 90 , //46 + 91 , //47 + 91 , //48 + 92 , //49 + 92 , //50 + 93 , //51 + 93 , //52 + 94 , //53 + 94 , //54 + 95 , //55 + 95 , //56 + 95 , //57 + 96 , //58 + 96 , //59 + 97 , //60 + 97 , //61 + 98 , //62 + 98 , //63 + 98 , //64 + 99 , //65 + 99 , //66 + 99 , //67 + 100, //68 + 100, //69 + 100, //70 + 101, //71 + 101, //72 + 102, //73 + 102, //74 + 102, //75 + 102, //76 + 103, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_1 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 56 , //9 + 57 , //10 + 59 , //11 + 60 , //12 + 61 , //13 + 62 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 67 , //18 + 68 , //19 + 69 , //20 + 70 , //21 + 71 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 75 , //27 + 76 , //28 + 77 , //29 + 78 , //30 + 79 , //31 + 79 , //32 + 80 , //33 + 81 , //34 + 82 , //35 + 82 , //36 + 83 , //37 + 84 , //38 + 85 , //39 + 85 , //40 + 86 , //41 + 87 , //42 + 88 , //43 + 88 , //44 + 89 , //45 + 89 , //46 + 90 , //47 + 91 , //48 + 91 , //49 + 92 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 95 , //56 + 95 , //57 + 96 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 98 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 101, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_2 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 55 , //9 + 57 , //10 + 58 , //11 + 60 , //12 + 61 , //13 + 62 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 67 , //18 + 68 , //19 + 69 , //20 + 70 , //21 + 71 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 75 , //27 + 76 , //28 + 77 , //29 + 78 , //30 + 78 , //31 + 79 , //32 + 80 , //33 + 81 , //34 + 82 , //35 + 82 , //36 + 83 , //37 + 84 , //38 + 84 , //39 + 85 , //40 + 86 , //41 + 87 , //42 + 87 , //43 + 88 , //44 + 89 , //45 + 89 , //46 + 90 , //47 + 90 , //48 + 91 , //49 + 91 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 94 , //56 + 95 , //57 + 95 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 97 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 100, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 103, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 107, + } + }, //RF_CHAN_3 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 78 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 82 , //35 + 83 , //36 + 84 , //37 + 84 , //38 + 85 , //39 + 86 , //40 + 87 , //41 + 87 , //42 + 88 , //43 + 88 , //44 + 89 , //45 + 90 , //46 + 90 , //47 + 91 , //48 + 91 , //49 + 92 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 95 , //56 + 95 , //57 + 95 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 98 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 100, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 103, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_4 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 54 , //8 + 56 , //9 + 57 , //10 + 59 , //11 + 60 , //12 + 62 , //13 + 63 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 69 , //20 + 71 , //21 + 72 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 83 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 89 , //43 + 89 , //44 + 90 , //45 + 91 , //46 + 91 , //47 + 92 , //48 + 92 , //49 + 93 , //50 + 93 , //51 + 94 , //52 + 94 , //53 + 95 , //54 + 95 , //55 + 96 , //56 + 96 , //57 + 96 , //58 + 97 , //59 + 97 , //60 + 98 , //61 + 98 , //62 + 98 , //63 + 99 , //64 + 99 , //65 + 100, //66 + 100, //67 + 100, //68 + 101, //69 + 101, //70 + 101, //71 + 102, //72 + 102, //73 + 102, //74 + 103, //75 + 103, //76 + 103, //77 + 103, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_5 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 83 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 89 , //43 + 89 , //44 + 90 , //45 + 91 , //46 + 91 , //47 + 92 , //48 + 92 , //49 + 93 , //50 + 93 , //51 + 94 , //52 + 94 , //53 + 95 , //54 + 95 , //55 + 96 , //56 + 96 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 98 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 101, //70 + 102, //71 + 102, //72 + 102, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_6 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 84 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 88 , //43 + 89 , //44 + 90 , //45 + 90 , //46 + 91 , //47 + 91 , //48 + 92 , //49 + 92 , //50 + 93 , //51 + 93 , //52 + 94 , //53 + 94 , //54 + 95 , //55 + 95 , //56 + 96 , //57 + 96 , //58 + 97 , //59 + 97 , //60 + 97 , //61 + 98 , //62 + 98 , //63 + 99 , //64 + 99 , //65 + 99 , //66 + 100, //67 + 100, //68 + 100, //69 + 101, //70 + 101, //71 + 101, //72 + 102, //73 + 102, //74 + 102, //75 + 103, //76 + 103, //77 + 103, //78 + 103, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_7 + { + { + 0 , //0 + 40 , //1 + 42 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 81 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 89 , //42 + 89 , //43 + 90 , //44 + 91 , //45 + 91 , //46 + 92 , //47 + 92 , //48 + 93 , //49 + 93 , //50 + 94 , //51 + 94 , //52 + 95 , //53 + 95 , //54 + 96 , //55 + 96 , //56 + 97 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 99 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 102, //70 + 102, //71 + 102, //72 + 103, //73 + 103, //74 + 103, //75 + 104, //76 + 104, //77 + 104, //78 + 104, //79 + 105, //80 + 105, //81 + 105, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 106, //88 + 106, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_8 + { + { + 0 , //0 + 41 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 58 , //9 + 59 , //10 + 60 , //11 + 62 , //12 + 63 , //13 + 64 , //14 + 66 , //15 + 67 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 78 , //27 + 79 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 83 , //33 + 83 , //34 + 84 , //35 + 85 , //36 + 86 , //37 + 87 , //38 + 87 , //39 + 88 , //40 + 89 , //41 + 89 , //42 + 90 , //43 + 91 , //44 + 91 , //45 + 92 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 95 , //53 + 96 , //54 + 96 , //55 + 97 , //56 + 97 , //57 + 98 , //58 + 98 , //59 + 98 , //60 + 99 , //61 + 99 , //62 + 100, //63 + 100, //64 + 100, //65 + 101, //66 + 101, //67 + 101, //68 + 102, //69 + 102, //70 + 103, //71 + 103, //72 + 103, //73 + 104, //74 + 104, //75 + 104, //76 + 104, //77 + 105, //78 + 105, //79 + 105, //80 + 105, //81 + 105, //82 + 105, //83 + 106, //84 + 106, //85 + 106, //86 + 106, //87 + 106, //88 + 106, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 107, //99 + 107, //100 + 107, //101 + 107, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_9 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 47 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 53 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 62 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 67 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 83 , //33 + 84 , //34 + 85 , //35 + 85 , //36 + 86 , //37 + 87 , //38 + 88 , //39 + 89 , //40 + 89 , //41 + 90 , //42 + 90 , //43 + 91 , //44 + 92 , //45 + 92 , //46 + 93 , //47 + 94 , //48 + 94 , //49 + 95 , //50 + 95 , //51 + 96 , //52 + 96 , //53 + 96 , //54 + 97 , //55 + 97 , //56 + 98 , //57 + 98 , //58 + 99 , //59 + 99 , //60 + 99 , //61 + 100, //62 + 100, //63 + 101, //64 + 101, //65 + 102, //66 + 102, //67 + 102, //68 + 103, //69 + 103, //70 + 103, //71 + 104, //72 + 104, //73 + 104, //74 + 105, //75 + 105, //76 + 105, //77 + 105, //78 + 105, //79 + 106, //80 + 106, //81 + 106, //82 + 106, //83 + 106, //84 + 106, //85 + 106, //86 + 106, //87 + 106, //88 + 107, //89 + 107, //90 + 107, //91 + 107, //92 + 107, //93 + 107, //94 + 107, //95 + 107, //96 + 107, //97 + 107, //98 + 107, //99 + 107, //100 + 107, //101 + 107, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_10 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 47 , //3 + 49 , //4 + 51 , //5 + 52 , //6 + 54 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 82 , //33 + 83 , //34 + 84 , //35 + 85 , //36 + 86 , //37 + 86 , //38 + 87 , //39 + 88 , //40 + 89 , //41 + 90 , //42 + 90 , //43 + 91 , //44 + 91 , //45 + 92 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 96 , //53 + 96 , //54 + 97 , //55 + 97 , //56 + 97 , //57 + 98 , //58 + 98 , //59 + 99 , //60 + 99 , //61 + 100, //62 + 100, //63 + 100, //64 + 101, //65 + 101, //66 + 101, //67 + 102, //68 + 102, //69 + 102, //70 + 103, //71 + 103, //72 + 103, //73 + 103, //74 + 103, //75 + 103, //76 + 104, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + } + }, //RF_CHAN_11 + { + { + 0 , //0 + 41 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 57 , //9 + 59 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 80 , //31 + 81 , //32 + 82 , //33 + 83 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 88 , //42 + 89 , //43 + 90 , //44 + 90 , //45 + 91 , //46 + 92 , //47 + 92 , //48 + 93 , //49 + 93 , //50 + 94 , //51 + 94 , //52 + 95 , //53 + 95 , //54 + 96 , //55 + 96 , //56 + 96 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 99 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 101, //70 + 102, //71 + 102, //72 + 102, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 104, //90 + 104, //91 + 104, //92 + 104, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + 105, + } + }, //RF_CHAN_12 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 58 , //9 + 59 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 80 , //31 + 81 , //32 + 82 , //33 + 83 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 89 , //42 + 89 , //43 + 90 , //44 + 91 , //45 + 91 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 95 , //53 + 96 , //54 + 96 , //55 + 97 , //56 + 97 , //57 + 97 , //58 + 98 , //59 + 98 , //60 + 99 , //61 + 99 , //62 + 100, //63 + 100, //64 + 100, //65 + 101, //66 + 101, //67 + 101, //68 + 102, //69 + 102, //70 + 102, //71 + 103, //72 + 103, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + 105, + } + }, //RF_CHAN_13 + { + { + 0, //0 + 40, //1 + 43, //2 + 45, //3 + 47, //4 + 49, //5 + 50, //6 + 52, //7 + 54, //8 + 56, //9 + 57, //10 + 58, //11 + 59, //12 + 60, //13 + 62, //14 + 63, //15 + 64, //16 + 65, //17 + 66, //18 + 67, //19 + 68, //20 + 69, //21 + 70, //22 + 71, //23 + 72, //24 + 73, //25 + 74, //26 + 74, //27 + 75, //28 + 76, //29 + 77, //30 + 78, //31 + 78, //32 + 79, //33 + 80, //34 + 81, //35 + 82, //36 + 83, //37 + 83, //38 + 84, //39 + 85, //40 + 85, //41 + 86, //42 + 87, //43 + 87, //44 + 88, //45 + 89, //46 + 89, //47 + 90, //48 + 90, //49 + 91, //50 + 91, //51 + 92, //52 + 92, //53 + 93, //54 + 93, //55 + 94, //56 + 94, //57 + 95, //58 + 95, //59 + 96, //60 + 96, //61 + 96, //62 + 97, //63 + 97, //64 + 97, //65 + 98, //66 + 98, //67 + 98, //68 + 98, //69 + 99, //70 + 99, //71 + 99, //72 + 99, //73 + 99, //74 + 99, //75 + 99, //76 + 99, //77 + 99, //78 + 99, //79 + 100, //80 + 100, //81 + 100, //82 + 100, //83 + 100, //84 + 100, //85 + 100, //86 + 100, //87 + 100, //88 + 100, //89 + 100, //90 + 100, //91 + 100, //92 + 100, //93 + 100, //94 + 100, //95 + 100, //96 + 100, //97 + 100, //98 + 100, //99 + 100, //100 + 100, //101 + 100, //102 + 100, //103 + 100, //104 + 100, //105 + 100, //106 + 100, //107 + 100, //108 + 100, //109 + 100, //110 + 100, //111 + 100, //112 + 100, //113 + 100, //114 + 100, //115 + 100, //116 + 100, //117 + 100, //118 + 100, //119 + 100, //120 + 100, //121 + 100, //122 + 100, //123 + 100, //124 + 100, //125 + 100, //126 + 100, //127 + 100, + } + }, //RF_CHAN_14 + }, + + //NV_TABLE_TPC_PDADC_OFFSETS + { + 98, // RF_CHAN_1 + 101, // RF_CHAN_2 + 101, // RF_CHAN_3 + 100, // RF_CHAN_4 + 98, // RF_CHAN_5 + 97, // RF_CHAN_6 + 94, // RF_CHAN_7 + 94, // RF_CHAN_8 + 92, // RF_CHAN_9 + 90, // RF_CHAN_10 + 94, // RF_CHAN_11 + 95, // RF_CHAN_12 + 97, // RF_CHAN_13 + 104, // RF_CHAN_14 + 100, // RF_CHAN_240 + 100, // RF_CHAN_244 + 100, // RF_CHAN_248 + 100, // RF_CHAN_252 + 100, // RF_CHAN_208 + 100, // RF_CHAN_212 + 100, // RF_CHAN_216 + 100, // RF_CHAN_36 + 100, // RF_CHAN_40 + 100, // RF_CHAN_44 + 100, // RF_CHAN_48 + 100, // RF_CHAN_52 + 100, // RF_CHAN_56 + 100, // RF_CHAN_60 + 100, // RF_CHAN_64 + 100, // RF_CHAN_100 + 100, // RF_CHAN_104 + 100, // RF_CHAN_108 + 100, // RF_CHAN_112 + 100, // RF_CHAN_116 + 100, // RF_CHAN_120 + 100, // RF_CHAN_124 + 100, // RF_CHAN_128 + 100, // RF_CHAN_132 + 100, // RF_CHAN_136 + 100, // RF_CHAN_140 + 100, // RF_CHAN_149 + 100, // RF_CHAN_153 + 100, // RF_CHAN_157 + 100, // RF_CHAN_161 + 100, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 100, // RF_CHAN_BOND_3 + 100, // RF_CHAN_BOND_4 + 100, // RF_CHAN_BOND_5 + 100, // RF_CHAN_BOND_6 + 100, // RF_CHAN_BOND_7 + 100, // RF_CHAN_BOND_8 + 100, // RF_CHAN_BOND_9 + 100, // RF_CHAN_BOND_10 + 100, // RF_CHAN_BOND_11 + 100, // RF_CHAN_BOND_242 + 100, // RF_CHAN_BOND_246 + 100, // RF_CHAN_BOND_250 + 100, // RF_CHAN_BOND_210 + 100, // RF_CHAN_BOND_214 + 100, // RF_CHAN_BOND_38 + 100, // RF_CHAN_BOND_42 + 100, // RF_CHAN_BOND_46 + 100, // RF_CHAN_BOND_50 + 100, // RF_CHAN_BOND_54 + 100, // RF_CHAN_BOND_58 + 100, // RF_CHAN_BOND_62 + 100, // RF_CHAN_BOND_102 + 100, // RF_CHAN_BOND_106 + 100, // RF_CHAN_BOND_110 + 100, // RF_CHAN_BOND_114 + 100, // RF_CHAN_BOND_118 + 100, // RF_CHAN_BOND_122 + 100, // RF_CHAN_BOND_126 + 100, // RF_CHAN_BOND_130 + 100, // RF_CHAN_BOND_134 + 100, // RF_CHAN_BOND_138 + 100, // RF_CHAN_BOND_151 + 100, // RF_CHAN_BOND_155 + 100, // RF_CHAN_BOND_159 + 100, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_VIRTUAL_RATE + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + { + // 2.4G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Low RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Middle RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G High RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 4.9G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + } + }, + +#if 0 //FIXME_PRIMA + //NV_TABLE_CAL_MEMORY + { + 0x7FFF, // tANI_U16 process_monitor; + 0x00, // tANI_U8 hdet_cal_code; + 0x00, // tANI_U8 rxfe_gm_2; + + 0x00, // tANI_U8 tx_bbf_rtune; + 0x00, // tANI_U8 pa_rtune_reg; + 0x00, // tANI_U8 rt_code; + 0x00, // tANI_U8 bias_rtune; + + 0x00, // tANI_U8 bb_bw1; + 0x00, // tANI_U8 bb_bw2; + { 0x00, 0x00 }, // tANI_U8 reserved[2]; + + 0x00, // tANI_U8 bb_bw3; + 0x00, // tANI_U8 bb_bw4; + 0x00, // tANI_U8 bb_bw5; + 0x00, // tANI_U8 bb_bw6; + + 0x7FFF, // tANI_U16 rcMeasured; + 0x00, // tANI_U8 tx_bbf_ct; + 0x00, // tANI_U8 tx_bbf_ctr; + + 0x00, // tANI_U8 csh_maxgain_reg; + 0x00, // tANI_U8 csh_0db_reg; + 0x00, // tANI_U8 csh_m3db_reg; + 0x00, // tANI_U8 csh_m6db_reg; + + 0x00, // tANI_U8 cff_0db_reg; + 0x00, // tANI_U8 cff_m3db_reg; + 0x00, // tANI_U8 cff_m6db_reg; + 0x00, // tANI_U8 rxfe_gpio_ctl_1; + + 0x00, // tANI_U8 mix_bal_cnt_2; + 0x00, // tANI_S8 rxfe_lna_highgain_bias_ctl_delta; + 0x00, // tANI_U8 rxfe_lna_load_ctune; + 0x00, // tANI_U8 rxfe_lna_ngm_rtune; + + 0x00, // tANI_U8 rx_im2_i_cfg0; + 0x00, // tANI_U8 rx_im2_i_cfg1; + 0x00, // tANI_U8 rx_im2_q_cfg0; + 0x00, // tANI_U8 rx_im2_q_cfg1; + + 0x00, // tANI_U8 pll_vfc_reg3_b0; + 0x00, // tANI_U8 pll_vfc_reg3_b1; + 0x00, // tANI_U8 pll_vfc_reg3_b2; + 0x00, // tANI_U8 pll_vfc_reg3_b3; + + 0x7FFF, // tANI_U16 tempStart; + 0x7FFF, // tANI_U16 tempFinish; + + { //txLoCorrections + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // tTxLoCorrections txLoValues; + + { //sTxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sTxIQChannel txIqValues; + + { //sRxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sRxIQChannel rxIqValues; + + { // tTpcConfig clpcData[MAX_TPC_CHANNELS] + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_1 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_2 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_3 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_4 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_5 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_6 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_7 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_8 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_9 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_10 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_11 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_12 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_13 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + } // RF_CHAN_14 + }, // tTpcConfig clpcData[MAX_TPC_CHANNELS]; + + { + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_1: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_2: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_3: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_4: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_5: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_6: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_7: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_8: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_9: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_10: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_11: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_12: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_13: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } } // RF_CHAN_14: pdadc_offset, reserved[2] + } // tTpcParams clpcParams[MAX_TPC_CHANNELS]; + + }, //NV_TABLE_CAL_MEMORY +#endif + //NV_TABLE_FW_CONFIG + { + 0, //skuID + 0, //tpcMode2G + 0, //tpcMode5G + 0, //reserved1 + + 0, //xPA2G + 0, //xPA5G; + 0, //paPolarityTx; + 0, //paPolarityRx; + + 0, //xLNA2G; + 0, //xLNA5G; + 0, //xCoupler2G; + 0, //xCoupler5G; + + 0, //xPdet2G; + 0, //xPdet5G; + 0, //enableDPD2G; + 1, //enableDPD5G; + + 1, //pdadcSelect2G; + 1, //pdadcSelect5GLow; + 1, //pdadcSelect5GMid; + 1, //pdadcSelect5GHigh; + + 0, //reserved2 + 0, //reserved3 + 0, //reserved4 + }, + + + //NV_TABLE_RSSI_CHANNEL_OFFSETS + { + //PHY_RX_CHAIN_0 + { + //bRssiOffset + {300}, // apply to all channles + + //gnRssiOffset + {300} // apply to all channles + }, + //rsvd + { + //bRssiOffset + {0}, // apply to all channles + + //gnRssiOffset + {0} // apply to all channles + } + }, + + //NV_TABLE_HW_CAL_VALUES + { + 0x0, //validBmap + { + 1400, //psSlpTimeOvrHd2G; + 1400, //psSlpTimeOvrHd5G; + + 1600, //psSlpTimeOvrHdxLNA5G; + 0, //nv_TxBBFSel9MHz + 0, //hwParam1 + 0, //hwParam2 + + 0x1B, //custom_tcxo_reg8 + 0xFF, //custom_tcxo_reg9 + + 0, //hwParam3; + 0, //hwParam4; + 0, //hwParam5; + 0, //hwParam6; + 0, //hwParam7; + 0, //hwParam8; + 0, //hwParam9; + 0, //hwParam10; + 0, //hwParam11; + } + }, + + + //NV_TABLE_ANTENNA_PATH_LOSS + { + 280, // RF_CHAN_1 + 270, // RF_CHAN_2 + 270, // RF_CHAN_3 + 270, // RF_CHAN_4 + 270, // RF_CHAN_5 + 270, // RF_CHAN_6 + 280, // RF_CHAN_7 + 280, // RF_CHAN_8 + 290, // RF_CHAN_9 + 300, // RF_CHAN_10 + 300, // RF_CHAN_11 + 310, // RF_CHAN_12 + 310, // RF_CHAN_13 + 310, // RF_CHAN_14 + 280, // RF_CHAN_240 + 280, // RF_CHAN_244 + 280, // RF_CHAN_248 + 280, // RF_CHAN_252 + 280, // RF_CHAN_208 + 280, // RF_CHAN_212 + 280, // RF_CHAN_216 + 280, // RF_CHAN_36 + 280, // RF_CHAN_40 + 280, // RF_CHAN_44 + 280, // RF_CHAN_48 + 280, // RF_CHAN_52 + 280, // RF_CHAN_56 + 280, // RF_CHAN_60 + 280, // RF_CHAN_64 + 280, // RF_CHAN_100 + 280, // RF_CHAN_104 + 280, // RF_CHAN_108 + 280, // RF_CHAN_112 + 280, // RF_CHAN_116 + 280, // RF_CHAN_120 + 280, // RF_CHAN_124 + 280, // RF_CHAN_128 + 280, // RF_CHAN_132 + 280, // RF_CHAN_136 + 280, // RF_CHAN_140 + 280, // RF_CHAN_149 + 280, // RF_CHAN_153 + 280, // RF_CHAN_157 + 280, // RF_CHAN_161 + 280, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 280, // RF_CHAN_BOND_3 + 280, // RF_CHAN_BOND_4 + 280, // RF_CHAN_BOND_5 + 280, // RF_CHAN_BOND_6 + 280, // RF_CHAN_BOND_7 + 280, // RF_CHAN_BOND_8 + 280, // RF_CHAN_BOND_9 + 280, // RF_CHAN_BOND_10 + 280, // RF_CHAN_BOND_11 + 280, // RF_CHAN_BOND_242 + 280, // RF_CHAN_BOND_246 + 280, // RF_CHAN_BOND_250 + 280, // RF_CHAN_BOND_210 + 280, // RF_CHAN_BOND_214 + 280, // RF_CHAN_BOND_38 + 280, // RF_CHAN_BOND_42 + 280, // RF_CHAN_BOND_46 + 280, // RF_CHAN_BOND_50 + 280, // RF_CHAN_BOND_54 + 280, // RF_CHAN_BOND_58 + 280, // RF_CHAN_BOND_62 + 280, // RF_CHAN_BOND_102 + 280, // RF_CHAN_BOND_106 + 280, // RF_CHAN_BOND_110 + 280, // RF_CHAN_BOND_114 + 280, // RF_CHAN_BOND_118 + 280, // RF_CHAN_BOND_122 + 280, // RF_CHAN_BOND_126 + 280, // RF_CHAN_BOND_130 + 280, // RF_CHAN_BOND_134 + 280, // RF_CHAN_BOND_138 + 280, // RF_CHAN_BOND_151 + 280, // RF_CHAN_BOND_155 + 280, // RF_CHAN_BOND_159 + 280, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_PACKET_TYPE_POWER_LIMITS + { + { 2150 }, // applied to all channels, MODE_802_11B + { 1850 }, // applied to all channels,MODE_802_11AG + { 1750 } // applied to all channels,MODE_802_11N + }, + + //NV_TABLE_OFDM_CMD_PWR_OFFSET + { + 0, 0 + }, + + //NV_TABLE_TX_BB_FILTER_MODE + { + 0 + } + + } // tables +}; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_qct_wma_legacy.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_qct_wma_legacy.c new file mode 100644 index 0000000000000..06dc646b07846 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wlan_qct_wma_legacy.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wlan_qct_WMA_legacy.c + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Adaptation + Layer for the legacy functionalities that were part of the old HAL. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/* Standard include files */ +/* Application Specific include files */ +#include "limApi.h" +#include "pmmApi.h" +#include "cfgApi.h" + +/* Locally used Defines */ + +#define HAL_MMH_MB_MSG_TYPE_MASK 0xFF00 +// ------------------------------------------------------------- +/** + * WMAPostCtrlMsg + * + * FUNCTION: + * Posts WMA messages to MC thread + * + * LOGIC: + * + * ASSUMPTIONS:pl + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg pointer with message + * @return Success or Failure + */ + +tSirRetStatus +wmaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WMA, (vos_msg_t *) pMsg)) + return eSIR_FAILURE; + else + return eSIR_SUCCESS; +} // halPostMsg() + +/** + * WMAPostCfgMsg + * + * FUNCTION: + * Posts MNT messages to gSirMntMsgQ + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg A pointer to the msg + * @return Success or Failure + */ + +tSirRetStatus +wmaPostCfgMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tSirRetStatus rc = eSIR_SUCCESS; + + do + { + // For Windows based MAC, instead of posting message to different + // queues we will call the handler routines directly + + cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr); + rc = eSIR_SUCCESS; + } while (0); + + return rc; +} // halMntPostMsg() + +// ------------------------------------------------------------- +/** + * uMacPostCtrlMsg + * + * FUNCTION: + * Forwards the completely received message to the respective + * modules for further processing. + * + * LOGIC: + * + * ASSUMPTIONS: + * Freeing up of the message buffer is left to the destination module. + * + * NOTE: + * This function has been moved to the API file because for MAC running + * on Windows host, the host module will call this routine directly to + * send any mailbox messages. Making this function an API makes sure that + * outside world (any module outside MMH) only calls APIs to use MMH + * services and not an internal function. + * + * @param pMb A pointer to the maibox message + * @return NONE + */ + +tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pSirGlobal; + + + tSirMbMsg* pMbLocal; + msg.type = pMb->type; + msg.bodyval = 0; +//TODO:FIXME +// WMA_LOGD("msgType %d, msgLen %d\n" ,pMb->type, pMb->msgLen); + + // copy the message from host buffer to firmware buffer + // this will make sure that firmware allocates, uses and frees + // it's own buffers for mailbox message instead of working on + // host buffer + + // second parameter, 'wait option', to palAllocateMemory is ignored on Windows + if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMbLocal, pMb->msgLen)) + { +//TODO:FIXME +// WMA_LOGE("Buffer Allocation failed!\n"); + return eSIR_FAILURE; + } + + palCopyMemory(pMac, (void *)pMbLocal, (void *)pMb, pMb->msgLen); + msg.bodyptr = pMbLocal; + + switch (msg.type & HAL_MMH_MB_MSG_TYPE_MASK) + { + case WMA_MSG_TYPES_BEGIN: // Posts a message to the HAL MsgQ + wmaPostCtrlMsg(pMac, &msg); + break; + + case SIR_LIM_MSG_TYPES_BEGIN: // Posts a message to the LIM MsgQ + limPostMsgApi(pMac, &msg); + break; + + case SIR_CFG_MSG_TYPES_BEGIN: // Posts a message to the CFG MsgQ + wmaPostCfgMsg(pMac, &msg); + break; + + case SIR_PMM_MSG_TYPES_BEGIN: // Posts a message to the PMM MsgQ + pmmPostMessage(pMac, &msg); + break; + + case SIR_PTT_MSG_TYPES_BEGIN: + break; + + + default: +//TODO:FIXME +//WMA_LOGD("Unknown message type = 0x%X\n", msg.type); + + // Release the memory. + if (palFreeMemory( pMac->hHdd, (void*)(msg.bodyptr)) + != eHAL_STATUS_SUCCESS) + { +//TODO:FIXME +// WMA_LOGE("Buffer Allocation failed!\n"); + return eSIR_FAILURE; + } + break; + } + + return eSIR_SUCCESS; + +} // uMacPostCtrlMsg() + +//TODO: FIXME +#if 0 +/* --------------------------------------------------------- + * FUNCTION: WMAGetGlobalSystemRole() + * + * Get the global HAL system role. + * --------------------------------------------------------- + */ +tBssSystemRole WMAGetGlobalSystemRole(tpAniSirGlobal pMac) +{ + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WMA, NULL); + t_wma_handle *wmaContext = + vos_get_context(VOS_MODULE_ID_WMA, pVosContext); + if(NULL == wmaContext) + { + VOS_TRACE( VOS_MODULE_ID_WMA, VOS_TRACE_LEVEL_ERROR, + "%s:WMA context is NULL", __func__); + VOS_ASSERT(0); + return eSYSTEM_UNKNOWN_ROLE; + } +#ifdef FEATURE_WLAN_INTEGRATED_SOC + WMA_LOGD(" returning %d role\n",wmaContext->wmaGlobalSystemRole); +#endif /* #ifdef FEATURE_WLAN_INTEGRATED_SOC */ + return wmaContext->wmaGlobalSystemRole; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c new file mode 100644 index 0000000000000..d91b953a3e9ff --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c @@ -0,0 +1,27417 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wma.c + \brief Implementation of WMA + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- ----------------------------------------- + 12/03/2013 Ganesh Implementation of WMA APIs. + Kondabattini + 27/03/2013 Ganesh Rx Management Support added + Babu + ==========================================================================*/ + +/* ################ Header files ################ */ +#include "wma.h" +#include "wma_api.h" +#include "vos_api.h" +#include "wmi_unified_api.h" +#include "wlan_qct_sys.h" +#include "wniApi.h" +#include "aniGlobal.h" +#include "wmi_unified.h" +#include "wniCfgAp.h" +#include "wlan_hal_cfg.h" +#include "cfgApi.h" +#include "ol_txrx_ctrl_api.h" +#if defined(CONFIG_HL_SUPPORT) +#include "wlan_tgt_def_config_hl.h" +#else +#include "wlan_tgt_def_config.h" +#endif + +#if defined(QCA_IBSS_SUPPORT) +#include "wlan_hdd_assoc.h" +#endif + +#include "adf_nbuf.h" +#include "adf_os_types.h" +#include "ol_txrx_api.h" +#include "vos_memory.h" +#include "ol_txrx_types.h" +#include "ol_txrx_peer_find.h" + +#include "wlan_qct_wda.h" +#include "wlan_qct_wda_msg.h" +#include "limApi.h" +#include "limSessionUtils.h" + +#include "wdi_out.h" +#include "wdi_in.h" + +#include "vos_utils.h" +#include "tl_shim.h" +#if defined(QCA_WIFI_FTM) +#include "testmode.h" +#endif + +#if !defined(REMOVE_PKT_LOG) +#include "pktlog_ac.h" +#endif + +#include "dbglog_host.h" +/* FIXME: Inclusion of .c looks odd but this is how it is in internal codebase */ +#include "wmi_version_whitelist.c" +#include "csrApi.h" +#include "ol_fw.h" + +#include "dfs.h" +#include "radar_filters.h" +/* ################### defines ################### */ +/* + * TODO: Following constant should be shared by firwmare in + * wmi_unified.h. This will be done once wmi_unified.h is updated. + */ +#define WMI_PEER_STATE_AUTHORIZED 0x2 + +#define WMA_2_4_GHZ_MAX_FREQ 3000 +#define WOW_CSA_EVENT_OFFSET 12 + +#define WMA_DEFAULT_SCAN_REQUESTER_ID 1 +#define WMI_SCAN_FINISH_EVENTS (WMI_SCAN_EVENT_START_FAILED |\ + WMI_SCAN_EVENT_COMPLETED |\ + WMI_SCAN_EVENT_DEQUEUED) +/* default value */ +#define DEFAULT_INFRA_STA_KEEP_ALIVE_PERIOD 20 +/* pdev vdev and peer stats*/ +#define FW_PDEV_STATS_SET 0x1 +#define FW_VDEV_STATS_SET 0x2 +#define FW_PEER_STATS_SET 0x4 +#define FW_STATS_SET 0x7 +/*AR9888/AR6320 noise floor approx value + * similar to the mentioned the TLSHIM + */ +#define WMA_TGT_NOISE_FLOOR_DBM (-96) + +/* + * Make sure that link monitor and keep alive + * default values should be in sync with CFG. + */ +#define WMA_LINK_MONITOR_DEFAULT_TIME_SECS 10 +#define WMA_KEEP_ALIVE_DEFAULT_TIME_SECS 5 + +#define AGC_DUMP 1 +#define CHAN_DUMP 2 +#define WD_DUMP 3 +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG +#define PCIE_DUMP 4 +#endif + +/* conformance test limits */ +#define FCC 0x10 +#define MKK 0x40 +#define ETSI 0x30 + +/* Maximum Buffer length allowed for DFS phyerrors */ +#define DFS_MAX_BUF_LENGHT 4096 + +#define WMI_DEFAULT_NOISE_FLOOR_DBM (-96) + +#define WMI_MCC_MIN_CHANNEL_QUOTA 20 +#define WMI_MCC_MAX_CHANNEL_QUOTA 80 +#define WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY 30 + +/* The maximum number of patterns that can be transmitted by the firmware + * and maximum patterns size. + */ +#define WMA_MAXNUM_PERIODIC_TX_PTRNS 6 + +#define WMI_MAX_HOST_CREDITS 2 +#define WMI_WOW_REQUIRED_CREDITS 1 + +#ifdef FEATURE_WLAN_D0WOW +#define DISABLE_PCIE_POWER_COLLAPSE 1 +#define ENABLE_PCIE_POWER_COLLAPSE 0 +#endif + +#define MAX_HT_MCS_IDX 8 +#define MAX_VHT_MCS_IDX 10 +#define INVALID_MCS_IDX 255 + +#define LINK_STATUS_LEGACY 0 +#define LINK_STATUS_VHT 0x1 +#define LINK_STATUS_MIMO 0x2 +#define LINK_SUPPORT_VHT 0x4 +#define LINK_SUPPORT_MIMO 0x8 + +#define LINK_RATE_VHT 0x3 +/* Data rate 100KBPS based on IE Index */ +struct index_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_rate[4]; +}; + +#ifdef WLAN_FEATURE_11AC +struct index_vht_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_VHT80_rate[2]; + v_U16_t supported_VHT40_rate[2]; + v_U16_t supported_VHT20_rate[2]; +}; +#endif + +/* MCS Based rate table */ +/* HT MCS parameters with Nss = 1 */ +static struct index_data_rate_type supported_mcs_rate_nss1[] = +{ + /* MCS L20 L40 S20 S40 */ + {0, {65, 135, 72, 150}}, + {1, {130, 270, 144, 300}}, + {2, {195, 405, 217, 450}}, + {3, {260, 540, 289, 600}}, + {4, {390, 810, 433, 900}}, + {5, {520, 1080, 578, 1200}}, + {6, {585, 1215, 650, 1350}}, + {7, {650, 1350, 722, 1500}} +}; +/* HT MCS parameters with Nss = 2 */ +static struct index_data_rate_type supported_mcs_rate_nss2[] = +{ + /* MCS L20 L40 S20 S40 */ + {0, {130, 270, 144, 300}}, + {1, {260, 540, 289, 600}}, + {2, {390, 810, 433, 900}}, + {3, {520, 1080, 578, 1200}}, + {4, {780, 1620, 867, 1800}}, + {5, {1040, 2160, 1156, 2400}}, + {6, {1170, 2430, 1300, 2700}}, + {7, {1300, 2700, 1444, 3000}} +}; + +#ifdef WLAN_FEATURE_11AC +/* MCS Based VHT rate table */ +/* MCS parameters with Nss = 1*/ +static struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = +{ + /* MCS L80 S80 L40 S40 L20 S40*/ + {0, {293, 325}, {135, 150}, {65, 72}}, + {1, {585, 650}, {270, 300}, {130, 144}}, + {2, {878, 975}, {405, 450}, {195, 217}}, + {3, {1170, 1300}, {540, 600}, {260, 289}}, + {4, {1755, 1950}, {810, 900}, {390, 433}}, + {5, {2340, 2600}, {1080, 1200}, {520, 578}}, + {6, {2633, 2925}, {1215, 1350}, {585, 650}}, + {7, {2925, 3250}, {1350, 1500}, {650, 722}}, + {8, {3510, 3900}, {1620, 1800}, {780, 867}}, + {9, {3900, 4333}, {1800, 2000}, {780, 867}} +}; + +/*MCS parameters with Nss = 2*/ +static struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = +{ + /* MCS L80 S80 L40 S40 L20 S40*/ + {0, {585, 650}, {270, 300}, {130, 144}}, + {1, {1170, 1300}, {540, 600}, {260, 289}}, + {2, {1755, 1950}, {810, 900}, {390, 433}}, + {3, {2340, 2600}, {1080, 1200}, {520, 578}}, + {4, {3510, 3900}, {1620, 1800}, {780, 867}}, + {5, {4680, 5200}, {2160, 2400}, {1040, 1156}}, + {6, {5265, 5850}, {2430, 2700}, {1170, 1300}}, + {7, {5850, 6500}, {2700, 3000}, {1300, 1444}}, + {8, {7020, 7800}, {3240, 3600}, {1560, 1733}}, + {9, {7800, 8667}, {3600, 4000}, {1560, 1733}} +}; +#endif + +static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type, + void *body_ptr, u_int32_t body_val); + +#ifdef QCA_IBSS_SUPPORT +static void wma_data_tx_ack_comp_hdlr(void *wma_context, + adf_nbuf_t netbuf, + int32_t status); +#endif +static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, + tpDelStaSelfParams pdel_sta_self_req_param, + u_int8_t generateRsp); +static struct wma_target_req * +wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev_id, + u_int32_t msg_type, u_int8_t type, void *params, + u_int32_t timeout); +static int32_t wmi_unified_vdev_stop_send(wmi_unified_t wmi, u_int8_t vdev_id); +static void wma_remove_vdev_req(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t type); + +static tANI_U32 gFwWlanFeatCaps; + +static eHalStatus wma_set_ppsconfig(tANI_U8 vdev_id, tANI_U16 pps_param, + int value); +static eHalStatus wma_set_mimops(tp_wma_handle wma_handle, + tANI_U8 vdev_id, int value); +#ifdef FEATURE_WLAN_TDLS +static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams); +static int wma_update_tdls_peer_state(WMA_HANDLE handle, + tTdlsPeerStateParams *peerStateParams); +static int wma_set_tdls_offchan_mode(WMA_HANDLE wma_handle, + tTdlsChanSwitchParams *pChanSwitchParams); +#endif + +static eHalStatus wma_set_smps_params(tp_wma_handle wma_handle, + tANI_U8 vdev_id, int value); +#if defined(QCA_WIFI_FTM) +void wma_utf_attach(tp_wma_handle wma_handle); +void wma_utf_detach(tp_wma_handle wma_handle); +static VOS_STATUS +wma_process_ftm_command(tp_wma_handle wma_handle, + struct ar6k_testmode_cmd_data *msg_buffer); +#endif + +static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, u8 peer_addr[6], + u_int32_t peer_type, u_int8_t vdev_id, + v_BOOL_t roam_synch_in_progress); +static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, + tpAddStaSelfParams self_sta_req, + u_int8_t generateRsp); +static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info); + +/*DFS Attach*/ +struct ieee80211com* wma_dfs_attach(struct ieee80211com *ic); +static void wma_dfs_detach(struct ieee80211com *ic); +static void wma_set_bss_rate_flags(struct wma_txrx_node *iface, + tpAddBssParams add_bss); +/*Configure DFS with radar tables and regulatory domain*/ +void wma_dfs_configure(struct ieee80211com *ic); + +/*Configure the current channel with the DFS*/ +struct ieee80211_channel * +wma_dfs_configure_channel(struct ieee80211com *dfs_ic, + wmi_channel *chan, + WLAN_PHY_MODE chanmode, + struct wma_vdev_start_req *req); + +/* VDEV UP */ +static int +wmi_unified_vdev_up_send(wmi_unified_t wmi, + u_int8_t vdev_id, u_int16_t aid, + u_int8_t bssid[IEEE80211_ADDR_LEN]); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +void wma_process_roam_synch_complete(WMA_HANDLE handle, + tSirSmeRoamOffloadSynchCnf *synchcnf); +void wma_process_roam_synch_fail(WMA_HANDLE handle, + tSirRoamOffloadSynchFail *synchfail); +#endif +/* Configure the regulatory domain for DFS radar filter initialization*/ +void wma_set_dfs_regdomain(tp_wma_handle wma); + +static VOS_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle, + t_thermal_cmd_params thermal_info); + +#ifdef FEATURE_WLAN_CH_AVOID +VOS_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle, + tSirChAvoidUpdateReq *ch_avoid_update_req); +#endif /* FEATURE_WLAN_CH_AVOID */ + +static void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info); + +static void wma_beacon_miss_handler(tp_wma_handle wma, u_int32_t vdev_id); +static void wma_set_suspend_dtim(tp_wma_handle wma); +static void wma_set_resume_dtim(tp_wma_handle wma); +static int wma_roam_event_callback(WMA_HANDLE handle, u_int8_t *event_buf, + u_int32_t len); +static VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle, + tAbortScanParams *abort_scan_req); + +static void wma_set_sap_keepalive(tp_wma_handle wma, u_int8_t vdev_id); + +static void *wma_find_vdev_by_addr(tp_wma_handle wma, u_int8_t *addr, + u_int8_t *vdev_id) +{ + u_int8_t i; + + for (i = 0; i < wma->max_bssid; i++) { + if (vos_is_macaddr_equal( + (v_MACADDR_t *) wma->interfaces[i].addr, + (v_MACADDR_t *) addr) == VOS_TRUE) { + *vdev_id = i; + return wma->interfaces[i].handle; + } + } + return NULL; +} + +/* + * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": + * 0 for no restriction + * 1 for 1/4 us - Our lower layer calculations limit our precision to 1 msec + * 2 for 1/2 us - Our lower layer calculations limit our precision to 1 msec + * 3 for 1 us + * 4 for 2 us + * 5 for 4 us + * 6 for 8 us + * 7 for 16 us + */ +static const u_int8_t wma_mpdu_spacing[] = {0, 1, 1, 1, 2, 4, 8, 16}; + +static inline uint8_t wma_parse_mpdudensity(u_int8_t mpdudensity) +{ + if (mpdudensity < sizeof(wma_mpdu_spacing)) + return wma_mpdu_spacing[mpdudensity]; + else + return 0; +} + +/* Function : wma_find_vdev_by_id + * Description : Returns vdev handle for given vdev id. + * Args : @wma - wma handle, @vdev_id - vdev ID + * Returns : Returns vdev handle if given vdev id is valid. + * Otherwise returns NULL. + */ +static inline void *wma_find_vdev_by_id(tp_wma_handle wma, u_int8_t vdev_id) +{ + if (vdev_id > wma->max_bssid) + return NULL; + + return wma->interfaces[vdev_id].handle; +} + +/* Function : wma_get_vdev_count + * Discription : Returns number of active vdev. + * Args : @wma - wma handle + * Returns : Returns valid vdev count. + */ +static inline u_int8_t wma_get_vdev_count(tp_wma_handle wma) +{ + u_int8_t vdev_count = 0, i; + + for (i = 0; i < wma->max_bssid; i++) { + if (wma->interfaces[i].handle) + vdev_count++; + } + return vdev_count; +} + +/* Function : wma_is_vdev_in_ap_mode + * Description : Helper function to know whether given vdev id + * is in AP mode or not. + * Args : @wma - wma handle, @ vdev_id - vdev ID. + * Returns : True - if given vdev id is in AP mode. + * False - if given vdev id is not in AP mode. + */ +static bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, u_int8_t vdev_id) +{ + struct wma_txrx_node *intf = wma->interfaces; + + if (vdev_id > wma->max_bssid) { + WMA_LOGP("%s: Invalid vdev_id %hu", __func__, vdev_id); + VOS_ASSERT(0); + return false; + } + + if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) && + ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) || + (intf[vdev_id].sub_type == 0))) + return true; + + return false; +} + +#ifdef QCA_IBSS_SUPPORT +/* Function : wma_is_vdev_in_ibss_mode + s_vdev_in_ibss_mode* Description : Helper function to know whether given vdev id + * is in IBSS mode or not. + * Args : @wma - wma handle, @ vdev_id - vdev ID. + * Retruns : True - if given vdev id is in IBSS mode. + * False - if given vdev id is not in IBSS mode. + */ +static bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, u_int8_t vdev_id) +{ + struct wma_txrx_node *intf = wma->interfaces; + + if (vdev_id > wma->max_bssid) { + WMA_LOGP("%s: Invalid vdev_id %hu", __func__, vdev_id); + VOS_ASSERT(0); + return false; + } + + if (intf[vdev_id].type == WMI_VDEV_TYPE_IBSS) + return true; + + return false; +} +#endif + +/* + * Function : wma_find_bssid_by_vdev_id + * Description : Get the BSS ID corresponding to the vdev ID + * Args : @wma - wma handle, @vdev_id - vdev ID + * Returns : Returns pointer to bssid on success, + * otherwise returns NULL. + */ +static inline u_int8_t *wma_find_bssid_by_vdev_id(tp_wma_handle wma, + u_int8_t vdev_id) +{ + if (vdev_id >= wma->max_bssid) + return NULL; + + return wma->interfaces[vdev_id].bssid; +} + +/* + * Function : wma_find_vdev_by_bssid + * Description : Get the VDEV ID corresponding from BSS ID + * Args : @wma - wma handle, @vdev_id - vdev ID + * Returns : Returns pointer to bssid on success, + * otherwise returns NULL. + */ +static void *wma_find_vdev_by_bssid(tp_wma_handle wma, u_int8_t *bssid, + u_int8_t *vdev_id) +{ + int i; + + for (i = 0; i < wma->max_bssid; i++) { + if (vos_is_macaddr_equal( + (v_MACADDR_t *)wma->interfaces[i].bssid, + (v_MACADDR_t *)bssid) == VOS_TRUE) { + *vdev_id = i; + return wma->interfaces[i].handle; + } + } + + return NULL; +} + +#ifdef BIG_ENDIAN_HOST + +/* ############# function definitions ############ */ + +/* function : wma_swap_bytes + * Description : + * Args : + * Retruns : + */ +v_VOID_t wma_swap_bytes(v_VOID_t *pv, v_SIZE_t n) +{ + v_SINT_t no_words; + v_SINT_t i; + v_U32_t *word_ptr; + + no_words = n/sizeof(v_U32_t); + word_ptr = (v_U32_t *)pv; + for (i=0; i= 7) { + if (rate_flags & eHAL_TX_RATE_SGI) + rateFlag |= 0x1; + } + + curRate = + supported_vht_mcs_rate[curIdx].supported_VHT80_rate[rateFlag]; + if (curRate == maxRate) { + found = true; + break; + } + } + } + + if ((found == false) && + ((rate_flags & eHAL_TX_RATE_VHT80) || + (rate_flags & eHAL_TX_RATE_VHT40))) { + for (curIdx = 0; curIdx < MAX_VHT_MCS_IDX; curIdx++) { + rateFlag = 0; + if (curIdx >= 7) { + if (rate_flags & eHAL_TX_RATE_SGI) + rateFlag |= 0x1; + } + + curRate = + supported_vht_mcs_rate[curIdx].supported_VHT40_rate[rateFlag]; + if (curRate == maxRate) { + found = true; + *mcsRateFlag &= ~eHAL_TX_RATE_VHT80; + break; + } + } + } + + if ((found == false) && + ((rate_flags & eHAL_TX_RATE_VHT80) || + (rate_flags & eHAL_TX_RATE_VHT40) || + (rate_flags & eHAL_TX_RATE_VHT20))) { + for (curIdx = 0; curIdx < MAX_VHT_MCS_IDX; curIdx++) { + rateFlag = 0; + if (curIdx >= 7) { + if (rate_flags & eHAL_TX_RATE_SGI) + rateFlag |= 0x1; + } + + curRate = + supported_vht_mcs_rate[curIdx].supported_VHT20_rate[rateFlag]; + if (curRate == maxRate) { + found = true; + *mcsRateFlag &= ~(eHAL_TX_RATE_VHT80|eHAL_TX_RATE_VHT40); + break; + } + } + } + } +#endif + if ((found == false) && + (rate_flags & + (eHAL_TX_RATE_HT40|eHAL_TX_RATE_HT20))) { + if (rate_flags & eHAL_TX_RATE_HT40) { + rateFlag = 0x1; + + for (curIdx = 0; curIdx < MAX_HT_MCS_IDX; curIdx++) { + if (curIdx == 7) { + if (rate_flags & eHAL_TX_RATE_SGI) + rateFlag |= 0x2; + } + + curRate = supported_mcs_rate[curIdx].supported_rate[rateFlag]; + if (curRate == maxRate) { + found = true; + *mcsRateFlag = eHAL_TX_RATE_HT40; + break; + } + } + } + + if (found == false) { + rateFlag = 0; + for (curIdx = 0; curIdx < MAX_HT_MCS_IDX; curIdx++) { + if (curIdx == 7) { + if (rate_flags & eHAL_TX_RATE_SGI) + rateFlag |= 0x2; + } + + curRate = supported_mcs_rate[curIdx].supported_rate[rateFlag]; + if (curRate == maxRate) { + found = true; + *mcsRateFlag = eHAL_TX_RATE_HT20; + break; + } + } + } + } + + /*SGI rates are used by firmware only for MCS >= 7*/ + if (found && (curIdx >= 7)) + *mcsRateFlag |= eHAL_TX_RATE_SGI; + + return (found ? curIdx : INVALID_MCS_IDX); +} + +static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma, + u_int8_t vdev_id, + u_int8_t type) +{ + struct wma_target_req *req_msg = NULL, *tmp; + bool found = false; + + adf_os_spin_lock_bh(&wma->vdev_respq_lock); + list_for_each_entry_safe(req_msg, tmp, + &wma->vdev_resp_queue, node) { + if (req_msg->vdev_id != vdev_id) + continue; + if (req_msg->type != type) + continue; + + found = true; + list_del(&req_msg->node); + break; + } + adf_os_spin_unlock_bh(&wma->vdev_respq_lock); + if (!found) { + WMA_LOGP("%s: target request not found for vdev_id %d type %d", + __func__, vdev_id, type); + return NULL; + } + WMA_LOGD("%s: target request found for vdev id: %d type %d msg %d", + __func__, vdev_id, type, req_msg->msg_type); + return req_msg; +} + +tSmpsModeValue host_map_smps_mode (A_UINT32 fw_smps_mode) +{ + tSmpsModeValue smps_mode = SMPS_MODE_DISABLED; + switch (fw_smps_mode) { + case WMI_SMPS_FORCED_MODE_STATIC: + smps_mode = STATIC_SMPS_MODE; + break; + case WMI_SMPS_FORCED_MODE_DYNAMIC: + smps_mode = DYNAMIC_SMPS_MODE; + break; + default: + smps_mode = SMPS_MODE_DISABLED; + } + + return smps_mode; +} + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +/* function : wma_post_auto_shutdown_msg + * Description : function to post auto shutdown event to sme + */ +static int wma_post_auto_shutdown_msg(void) +{ + tSirAutoShutdownEvtParams *auto_sh_evt; + VOS_STATUS vos_status; + vos_msg_t sme_msg = {0} ; + + auto_sh_evt = (tSirAutoShutdownEvtParams *) + vos_mem_malloc(sizeof(tSirAutoShutdownEvtParams)); + if (!auto_sh_evt) { + WMA_LOGE("%s: No Mem", __func__); + return -ENOMEM; + } + + auto_sh_evt->shutdown_reason = + WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY; + sme_msg.type = eWNI_SME_AUTO_SHUTDOWN_IND; + sme_msg.bodyptr = auto_sh_evt; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if ( !VOS_IS_STATUS_SUCCESS(vos_status) ) { + WMA_LOGE("Fail to post eWNI_SME_AUTO_SHUTDOWN_IND msg to SME"); + vos_mem_free(auto_sh_evt); + return -EINVAL; + } + + return 0; +} + +/* function : wma_auto_shutdown_event_handler + * Description : function to process auto shutdown timer trigger + */ +static int wma_auto_shutdown_event_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + wmi_host_auto_shutdown_event_fixed_param *wmi_auto_sh_evt; + WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *param_buf = + (WMI_HOST_AUTO_SHUTDOWN_EVENTID_param_tlvs *) + event; + + if (!param_buf || !param_buf->fixed_param) { + WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__, + __LINE__); + return -EINVAL; + } + + + wmi_auto_sh_evt = param_buf->fixed_param; + + if (wmi_auto_sh_evt->shutdown_reason + != WMI_HOST_AUTO_SHUTDOWN_REASON_TIMER_EXPIRY) { + WMA_LOGE("%s:%d: Invalid Auto shutdown timer evt", __func__, + __LINE__); + return -EINVAL; + } + + WMA_LOGD("%s:%d: Auto Shutdown Evt: %d", __func__, __LINE__, + wmi_auto_sh_evt->shutdown_reason); + return(wma_post_auto_shutdown_msg()); +} + +/* function : wma_set_auto_shutdown_timer_req + * Description : function sets auto shutdown timer in firmware + * Args : wma handle, auto shutdown timer value + * Returns : status of wmi cmd + */ +static VOS_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle, + tSirAutoShutdownCmdParams *auto_sh_cmd) +{ + int status = 0; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd; + int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param); + + if (auto_sh_cmd == NULL) { + WMA_LOGE("%s : Invalid Autoshutdown cfg cmd", __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d", + __func__, auto_sh_cmd->timer_val); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + wmi_auto_sh_cmd = (wmi_host_auto_shutdown_cfg_cmd_fixed_param *)buf_ptr; + wmi_auto_sh_cmd->timer_value = auto_sh_cmd->timer_val; + + WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_host_auto_shutdown_cfg_cmd_fixed_param)); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); + if (status != EOK) { + WMA_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d", + __func__, status); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} +#endif + +static void wma_vdev_start_rsp(tp_wma_handle wma, + tpAddBssParams add_bss, + wmi_vdev_start_response_event_fixed_param *resp_event) +{ + struct beacon_info *bcn; + +#ifdef QCA_IBSS_SUPPORT + WMA_LOGD("%s: vdev start response received for %s mode", __func__, + add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS ? "IBSS" : "non-IBSS"); +#endif + + if (resp_event->status) { + add_bss->status = VOS_STATUS_E_FAILURE; + goto send_fail_resp; + } + + if ((add_bss->operMode == BSS_OPERATIONAL_MODE_AP) +#ifdef QCA_IBSS_SUPPORT + || (add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS) +#endif + ) { + wma->interfaces[resp_event->vdev_id].beacon = + vos_mem_malloc(sizeof(struct beacon_info)); + + bcn = wma->interfaces[resp_event->vdev_id].beacon; + if (!bcn) { + WMA_LOGE("%s: Failed alloc memory for beacon struct", + __func__); + add_bss->status = VOS_STATUS_E_FAILURE; + goto send_fail_resp; + } + vos_mem_zero(bcn, sizeof(*bcn)); + bcn->buf = adf_nbuf_alloc(NULL, WMA_BCN_BUF_MAX_SIZE, 0, + sizeof(u_int32_t), 0); + if (!bcn->buf) { + WMA_LOGE("%s: No memory allocated for beacon buffer", + __func__); + vos_mem_free(bcn); + add_bss->status = VOS_STATUS_E_FAILURE; + goto send_fail_resp; + } + bcn->seq_no = MIN_SW_SEQ; + adf_os_spinlock_init(&bcn->lock); + adf_os_atomic_set(&wma->interfaces[resp_event->vdev_id].bss_status, + WMA_BSS_STATUS_STARTED); + WMA_LOGD("%s: AP mode (type %d subtype %d) BSS is started", __func__, + wma->interfaces[resp_event->vdev_id].type, + wma->interfaces[resp_event->vdev_id].sub_type); + + WMA_LOGD("%s: Allocated beacon struct %p, template memory %p", + __func__, bcn, bcn->buf); + } + add_bss->status = VOS_STATUS_SUCCESS; + add_bss->bssIdx = resp_event->vdev_id; + add_bss->chainMask = resp_event->chain_mask; + add_bss->smpsMode = host_map_smps_mode(resp_event->smps_mode); +send_fail_resp: + WMA_LOGD("%s: Sending add bss rsp to umac(vdev %d status %d)", + __func__, resp_event->vdev_id, add_bss->status); + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); +} + +static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf; + wmi_vdev_start_response_event_fixed_param *resp_event; + u_int8_t *buf; + vos_msg_t vos_msg = {0}; + + WMA_LOGI("%s: Enter", __func__); + param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info; + if (!param_buf) { + WMA_LOGE("Invalid start response event buffer"); + return -EINVAL; + } + + resp_event = param_buf->fixed_param; + buf = vos_mem_malloc(sizeof(wmi_vdev_start_response_event_fixed_param)); + if (!buf) { + WMA_LOGE("%s: Failed alloc memory for buf", __func__); + return -EINVAL; + } + vos_mem_zero(buf, sizeof(wmi_vdev_start_response_event_fixed_param)); + vos_mem_copy(buf, (u_int8_t *)resp_event, + sizeof(wmi_vdev_start_response_event_fixed_param)); + + vos_msg.type = WDA_VDEV_START_RSP_IND; + vos_msg.bodyptr = buf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGP("%s: Failed to post WDA_VDEV_START_RSP_IND msg", __func__); + vos_mem_free(buf); + return -1; + } + WMA_LOGD("WDA_VDEV_START_RSP_IND posted"); + return 0; +} + +static int wma_vdev_start_rsp_ind(tp_wma_handle wma, u_int8_t *buf) +{ + struct wma_target_req *req_msg; + struct wma_txrx_node *iface; + wmi_vdev_start_response_event_fixed_param *resp_event; + + resp_event = (wmi_vdev_start_response_event_fixed_param *)buf; + + if (!resp_event) { + WMA_LOGE("Invalid start response event buffer"); + return -EINVAL; + } + + if ((resp_event->vdev_id <= wma->max_bssid) && + (adf_os_atomic_read( + &wma->interfaces[resp_event->vdev_id].vdev_restart_params.hidden_ssid_restart_in_progress)) && + ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) && + (wma->interfaces[resp_event->vdev_id].sub_type == 0))) { + WMA_LOGE( + "%s: vdev restart event recevied for hidden ssid set using IOCTL", + __func__); + + if (wmi_unified_vdev_up_send(wma->wmi_handle, resp_event->vdev_id, 0, + wma->interfaces[resp_event->vdev_id].bssid) < 0) { + WMA_LOGE("%s : failed to send vdev up", __func__); + return -EEXIST; + } + adf_os_atomic_set( + &wma->interfaces[resp_event->vdev_id].vdev_restart_params.hidden_ssid_restart_in_progress, 0); + wma->interfaces[resp_event->vdev_id].vdev_up = TRUE; + } + + req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_START); + + if (!req_msg) { + WMA_LOGE("%s: Failed to lookup request message for vdev %d", + __func__, resp_event->vdev_id); + return -EINVAL; + } + + vos_timer_stop(&req_msg->event_timeout); + + iface = &wma->interfaces[resp_event->vdev_id]; + if (req_msg->msg_type == WDA_CHNL_SWITCH_REQ) { + tpSwitchChannelParams params = + (tpSwitchChannelParams) req_msg->user_data; + if(!params) { + WMA_LOGE("%s: channel switch params is NULL for vdev %d", + __func__, resp_event->vdev_id); + return -EINVAL; + } + + WMA_LOGD("%s: Send channel switch resp vdev %d status %d", + __func__, resp_event->vdev_id, resp_event->status); + params->chainMask = resp_event->chain_mask; + params->smpsMode = host_map_smps_mode(resp_event->smps_mode); + params->status = resp_event->status; + if (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT && + (iface->type == WMI_VDEV_TYPE_STA)) { + if (wmi_unified_vdev_up_send(wma->wmi_handle, + resp_event->vdev_id, iface->aid, + iface->bssid)) { + WMA_LOGE("%s:vdev_up failed vdev_id %d", + __func__, resp_event->vdev_id); + wma->interfaces[resp_event->vdev_id].vdev_up = + FALSE; + } else { + wma->interfaces[resp_event->vdev_id].vdev_up = + TRUE; + } + } + + wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + } else if (req_msg->msg_type == WDA_ADD_BSS_REQ) { + tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data; + vos_mem_copy(iface->bssid, bssParams->bssId, ETH_ALEN); + wma_vdev_start_rsp(wma, bssParams, resp_event); + } + + + if ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) && + wma->interfaces[resp_event->vdev_id].vdev_up) + wma_set_sap_keepalive(wma, resp_event->vdev_id); + + vos_timer_destroy(&req_msg->event_timeout); + adf_os_mem_free(req_msg); + + return 0; +} + +/* function : wma_unified_debug_print_event_handler + * Description : + * Args : + * Returns : + */ +static int wma_unified_debug_print_event_handler(void *handle, u_int8_t *datap, + u_int32_t len) +{ + WMI_DEBUG_PRINT_EVENTID_param_tlvs *param_buf; + u_int8_t *data; + u_int32_t datalen; + + param_buf = (WMI_DEBUG_PRINT_EVENTID_param_tlvs *)datap; + if (!param_buf) { + WMA_LOGE("Get NULL point message from FW"); + return -ENOMEM; + } + data = param_buf->data; + datalen = param_buf->num_data; + +#ifdef BIG_ENDIAN_HOST + { + char dbgbuf[500] = {0}; + memcpy(dbgbuf, data, datalen); + SWAPME(dbgbuf, datalen); + WMA_LOGD("FIRMWARE:%s", dbgbuf); + return 0; + } +#else + WMA_LOGD("FIRMWARE:%s", data); + return 0; +#endif +} + +static int +wmi_unified_vdev_set_param_send(wmi_unified_t wmi_handle, u_int32_t if_id, + u_int32_t param_id, u_int32_t param_value) +{ + int ret; + wmi_vdev_set_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_vdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_set_param_cmd_fixed_param)); + cmd->vdev_id = if_id; + cmd->param_id = param_id; + cmd->param_value = param_value; + WMA_LOGD("Setting vdev %d param = %x, value = %u", + if_id, param_id, param_value); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_VDEV_SET_PARAM_CMDID); + if (ret < 0) { + WMA_LOGE("Failed to send set param command ret = %d", ret); + wmi_buf_free(buf); + } + return ret; +} + +VOS_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle, + A_INT32 first_bcnt, + A_UINT32 final_bcnt, + u_int32_t vdev_id) +{ + int status = 0; + + WMA_LOGI("%s: first_bcnt=%d, final_bcnt=%d", __func__, + first_bcnt, final_bcnt); + + status = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_BMISS_FIRST_BCNT, + first_bcnt); + if (status != EOK) { + WMA_LOGE("wmi_unified_vdev_set_param_send" + "WMI_VDEV_PARAM_BMISS_FIRST_BCNT returned Error %d",status); + return VOS_STATUS_E_FAILURE; + } + + status = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_BMISS_FINAL_BCNT, + final_bcnt); + if (status != EOK) { + WMA_LOGE("wmi_unified_vdev_set_param_send" + "WMI_VDEV_PARAM_BMISS_FINAL_BCNT returned Error %d",status); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static v_VOID_t wma_set_default_tgt_config(tp_wma_handle wma_handle) +{ + struct ol_softc *scn; + u_int8_t no_of_peers_supported; + wmi_resource_config tgt_cfg = { + 0, /* Filling zero for TLV Tag and Length fields */ + CFG_TGT_NUM_VDEV, + CFG_TGT_NUM_PEERS + CFG_TGT_NUM_VDEV + 2, + CFG_TGT_NUM_OFFLOAD_PEERS, + CFG_TGT_NUM_OFFLOAD_REORDER_BUFFS, + CFG_TGT_NUM_PEER_KEYS, + CFG_TGT_NUM_TIDS, + CFG_TGT_AST_SKID_LIMIT, + CFG_TGT_DEFAULT_TX_CHAIN_MASK, + CFG_TGT_DEFAULT_RX_CHAIN_MASK, + { CFG_TGT_RX_TIMEOUT_LO_PRI, CFG_TGT_RX_TIMEOUT_LO_PRI, CFG_TGT_RX_TIMEOUT_LO_PRI, CFG_TGT_RX_TIMEOUT_HI_PRI }, + CFG_TGT_RX_DECAP_MODE, + CFG_TGT_DEFAULT_SCAN_MAX_REQS, + CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV, + CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV, + CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES, + CFG_TGT_DEFAULT_NUM_MCAST_GROUPS, + CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS, + CFG_TGT_DEFAULT_MCAST2UCAST_MODE, + CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE, + CFG_TGT_WDS_ENTRIES, + CFG_TGT_DEFAULT_DMA_BURST_SIZE, + CFG_TGT_DEFAULT_MAC_AGGR_DELIM, + CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK, + CFG_TGT_DEFAULT_VOW_CONFIG, + CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV, + CFG_TGT_NUM_MSDU_DESC, + CFG_TGT_MAX_FRAG_TABLE_ENTRIES, + CFG_TGT_NUM_TDLS_VDEVS, + CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES, + CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV, + CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES, + 0, + 0, + 0, + CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS, + CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS, + }; + + /* Update the max number of peers */ + scn = vos_get_context(VOS_MODULE_ID_HIF, wma_handle->vos_context); + if (!scn) { + WMA_LOGE("%s: vos_context is NULL", __func__); + return; + } + no_of_peers_supported = ol_get_number_of_peers_supported(scn); + tgt_cfg.num_peers = no_of_peers_supported + CFG_TGT_NUM_VDEV + 2; + tgt_cfg.num_tids = (2 * (no_of_peers_supported + CFG_TGT_NUM_VDEV + 2)); + + WMITLV_SET_HDR(&tgt_cfg.tlv_header,WMITLV_TAG_STRUC_wmi_resource_config, + WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); + /* reduce the peer/vdev if CFG_TGT_NUM_MSDU_DESC exceeds 1000 */ +#ifdef PERE_IP_HDR_ALIGNMENT_WAR + if (scn->host_80211_enable) { + /* + * To make the IP header begins at dword aligned address, + * we make the decapsulation mode as Native Wifi. + */ + tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_NWIFI; + } +#endif + wma_handle->wlan_resource_config = tgt_cfg; +} + +static int32_t wmi_unified_peer_delete_send(wmi_unified_t wmi, + u_int8_t peer_addr[IEEE80211_ADDR_LEN], + u_int8_t vdev_id) +{ + wmi_peer_delete_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_peer_delete_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_delete_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_delete_cmd_fixed_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + cmd->vdev_id = vdev_id; + + if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_DELETE_CMDID)) { + WMA_LOGP("%s: Failed to send peer delete command", __func__); + adf_nbuf_free(buf); + return -EIO; + } + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); + return 0; +} + +static int32_t wmi_unified_peer_flush_tids_send(wmi_unified_t wmi, + u_int8_t peer_addr + [IEEE80211_ADDR_LEN], + u_int32_t peer_tid_bitmap, + u_int8_t vdev_id) +{ + wmi_peer_flush_tids_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_peer_flush_tids_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_flush_tids_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_flush_tids_cmd_fixed_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + cmd->peer_tid_bitmap = peer_tid_bitmap; + cmd->vdev_id = vdev_id; + + if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_FLUSH_TIDS_CMDID)) { + WMA_LOGP("%s: Failed to send flush tid command", __func__); + adf_nbuf_free(buf); + return -EIO; + } + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); + return 0; +} + +static void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, + u_int8_t vdev_id, ol_txrx_peer_handle peer, + v_BOOL_t roam_synch_in_progress) +{ +#define PEER_ALL_TID_BITMASK 0xffffffff + u_int32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK; + u_int8_t *peer_addr = bssid; + if (!wma->interfaces[vdev_id].peer_count) + { + WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d", + __func__, bssid, vdev_id, wma->interfaces[vdev_id].peer_count); + return; + } + if (peer) + ol_txrx_peer_detach(peer); + + wma->interfaces[vdev_id].peer_count--; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (roam_synch_in_progress) { + WMA_LOGD("%s:LFR3:Removed peer with addr %pM vdevid %d peer_cnt %d", + __func__, bssid, vdev_id, wma->interfaces[vdev_id].peer_count); + return; + } else { + WMA_LOGE("%s: Removed peer with addr %pM vdevid %d peer_count %d", + __func__, bssid, vdev_id, wma->interfaces[vdev_id].peer_count); + } +#endif + /* Flush all TIDs except MGMT TID for this peer in Target */ + peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); + wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid, + peer_tid_bitmap, vdev_id); + +#if defined(QCA_IBSS_SUPPORT) + if ((peer) && (wma_is_vdev_in_ibss_mode(wma, vdev_id))) { + WMA_LOGD("%s: bssid %pM peer->mac_addr %pM", __func__, + bssid, peer->mac_addr.raw); + peer_addr = peer->mac_addr.raw; + } +#endif + + wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr, vdev_id); +#undef PEER_ALL_TID_BITMASK +} + +static int wma_peer_sta_kickout_event_handler(void *handle, u8 *event, u32 len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL; + wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL; + u_int8_t vdev_id, peer_id, macaddr[IEEE80211_ADDR_LEN]; + ol_txrx_peer_handle peer; + ol_txrx_pdev_handle pdev; + tpDeleteStaContext del_sta_ctx; + tpSirIbssPeerInactivityInd p_inactivity; + + WMA_LOGD("%s: Enter", __func__); + param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event; + kickout_event = param_buf->fixed_param; + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (!pdev) { + WMA_LOGE("%s: pdev is NULL", __func__); + return -EINVAL; + } + WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr); + peer = ol_txrx_find_peer_by_addr(pdev, macaddr, &peer_id); + if (!peer) { + WMA_LOGE("PEER [%pM] not found", macaddr); + return -EINVAL; + } + + if (tl_shim_get_vdevid(peer, &vdev_id) != VOS_STATUS_SUCCESS) { + WMA_LOGE("Not able to find BSSID for peer [%pM]", macaddr); + return -EINVAL; + } + + WMA_LOGA("%s: PEER:[%pM], ADDR:[%pN], INTERFACE:%d, peer_id:%d, reason:%d", + __func__, macaddr, + wma->interfaces[vdev_id].addr, vdev_id, + peer_id, kickout_event->reason); + + switch (kickout_event->reason) { + case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT: + p_inactivity = (tpSirIbssPeerInactivityInd) + vos_mem_malloc(sizeof(tSirIbssPeerInactivityInd)); + if (!p_inactivity) { + WMA_LOGE("VOS MEM Alloc Failed for tSirIbssPeerInactivity"); + return -EINVAL; + } + + p_inactivity->staIdx = peer_id; + vos_mem_copy(p_inactivity->peerAddr, macaddr, IEEE80211_ADDR_LEN); + wma_send_msg(wma, WDA_IBSS_PEER_INACTIVITY_IND, (void *)p_inactivity, 0); + goto exit_handler; + break; + +#ifdef FEATURE_WLAN_TDLS + case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT: + del_sta_ctx = + (tpDeleteStaContext)vos_mem_malloc(sizeof(tDeleteStaContext)); + if (!del_sta_ctx) { + WMA_LOGE("%s: mem alloc failed for tDeleteStaContext for TDLS peer: %pM", + __func__, macaddr); + return -EINVAL; + } + + del_sta_ctx->is_tdls = true; + del_sta_ctx->vdev_id = vdev_id; + del_sta_ctx->staId = peer_id; + vos_mem_copy(del_sta_ctx->addr2, macaddr, IEEE80211_ADDR_LEN); + vos_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].bssid, + IEEE80211_ADDR_LEN); + del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE; + wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx, + 0); + goto exit_handler; + break; +#endif /* FEATURE_WLAN_TDLS */ + + case WMI_PEER_STA_KICKOUT_REASON_XRETRY: + if(wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA && + (wma->interfaces[vdev_id].sub_type == 0 || + wma->interfaces[vdev_id].sub_type == + WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) && + vos_mem_compare(wma->interfaces[vdev_id].bssid, + macaddr, ETH_ALEN)) { + /* + * KICKOUT event is for current station-AP connection. + * Treat it like final beacon miss. Station may not have + * missed beacons but not able to transmit frames to AP + * for a long time. Must disconnect to get out of + * this sticky situation. + * In future implementation, roaming module will also + * handle this event and perform a scan. + */ + WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_XRETRY event for STA", + __func__); + wma_beacon_miss_handler(wma, vdev_id); + goto exit_handler; + } + break; + + case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED: + /* + * Default legacy value used by original firmware implementation. + */ + if(wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA && + (wma->interfaces[vdev_id].sub_type == 0 || + wma->interfaces[vdev_id].sub_type == + WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) && + vos_mem_compare(wma->interfaces[vdev_id].bssid, + macaddr, ETH_ALEN)) { + /* + * KICKOUT event is for current station-AP connection. + * Treat it like final beacon miss. Station may not have + * missed beacons but not able to transmit frames to AP + * for a long time. Must disconnect to get out of + * this sticky situation. + * In future implementation, roaming module will also + * handle this event and perform a scan. + */ + WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED event for STA", + __func__); + wma_beacon_miss_handler(wma, vdev_id); + goto exit_handler; + } + break; + + case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY: + /* This could be for STA or SAP role */ + default: + break; + } + + /* + * default action is to send delete station context indication to LIM + */ + del_sta_ctx = (tpDeleteStaContext)vos_mem_malloc(sizeof(tDeleteStaContext)); + if (!del_sta_ctx) { + WMA_LOGE("VOS MEM Alloc Failed for tDeleteStaContext"); + return -EINVAL; + } + + del_sta_ctx->is_tdls = false; + del_sta_ctx->vdev_id = vdev_id; + del_sta_ctx->staId = peer_id; + vos_mem_copy(del_sta_ctx->addr2, macaddr, IEEE80211_ADDR_LEN); + vos_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].addr, + IEEE80211_ADDR_LEN); + del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE; + wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx, 0); + +exit_handler: + WMA_LOGD("%s: Exit", __func__); + return 0; +} + +static int wmi_unified_vdev_down_send(wmi_unified_t wmi, u_int8_t vdev_id) +{ + wmi_vdev_down_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s : wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) { + WMA_LOGP("%s: Failed to send vdev down", __func__); + adf_nbuf_free(buf); + return -EIO; + } + WMA_LOGE("%s: vdev_id %d", __func__, vdev_id); + return 0; +} + +#ifdef QCA_IBSS_SUPPORT +static void wma_delete_all_ibss_peers(tp_wma_handle wma, A_UINT32 vdev_id) +{ + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + + if (!wma || vdev_id > wma->max_bssid) + return; + + vdev = wma->interfaces[vdev_id].handle; + if (!vdev) + return; + + /* remove all IBSS remote peers first */ + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + if (peer != TAILQ_FIRST(&vdev->peer_list)) { + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); + adf_os_atomic_init(&peer->ref_cnt); + adf_os_atomic_inc(&peer->ref_cnt); + wma_remove_peer(wma, wma->interfaces[vdev_id].bssid, + vdev_id, peer, VOS_FALSE); + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + } + } + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); + + /* remove IBSS bss peer last */ + peer = TAILQ_FIRST(&vdev->peer_list); + wma_remove_peer(wma, wma->interfaces[vdev_id].bssid, vdev_id, peer, + VOS_FALSE); +} +#endif //#ifdef QCA_IBSS_SUPPORT + +static void wma_delete_all_ap_remote_peers(tp_wma_handle wma, A_UINT32 vdev_id) +{ + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer, temp; + + if (!wma || vdev_id > wma->max_bssid) + return; + + vdev = wma->interfaces[vdev_id].handle; + if (!vdev) + return; + + WMA_LOGE("%s: vdev_id - %d", __func__, vdev_id); + /* remove all remote peers of SAP */ + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + + temp = NULL; + TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list, peer_list_t, peer_list_elem) { + if (temp) { + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); + if (adf_os_atomic_read(&temp->delete_in_progress) == 0){ + wma_remove_peer(wma, temp->mac_addr.raw, + vdev_id, temp, VOS_FALSE); + } + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + } + /* self peer is deleted by caller */ + if (peer == TAILQ_FIRST(&vdev->peer_list)){ + WMA_LOGE("%s: self peer removed by caller ", __func__); + break; + } else + temp = peer; + } + + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); +} + +#ifdef QCA_IBSS_SUPPORT +static void wma_recreate_ibss_vdev_and_bss_peer(tp_wma_handle wma, u_int8_t vdev_id) +{ + ol_txrx_vdev_handle vdev; + tDelStaSelfParams del_sta_param; + tAddStaSelfParams add_sta_self_param; + VOS_STATUS status; + + if (!wma) { + WMA_LOGE("%s: Null wma handle", __func__); + return; + } + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("%s: Can't find vdev with id %d", __func__, vdev_id); + return; + } + + vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr), + (v_MACADDR_t *)&(vdev->mac_addr)); + add_sta_self_param.sessionId = vdev_id; + add_sta_self_param.type = WMI_VDEV_TYPE_IBSS; + add_sta_self_param.subType = 0; + add_sta_self_param.status = 0; + + /* delete old ibss vdev */ + del_sta_param.sessionId = vdev_id; + vos_mem_copy((void *)del_sta_param.selfMacAddr, + (void *)&(vdev->mac_addr), + VOS_MAC_ADDR_SIZE); + wma_vdev_detach(wma, &del_sta_param, 0); + + /* create new vdev for ibss */ + vdev = wma_vdev_attach(wma, &add_sta_self_param, 0); + if (!vdev) { + WMA_LOGE("%s: Failed to create vdev", __func__); + return; + } + + WLANTL_RegisterVdev(wma->vos_context, vdev); + /* Register with TxRx Module for Data Ack Complete Cb */ + wdi_in_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma); + WMA_LOGA("new IBSS vdev created with mac %pM", add_sta_self_param.selfMacAddr); + + /* create ibss bss peer */ + status = wma_create_peer(wma, vdev->pdev, vdev, vdev->mac_addr.raw, + WMI_PEER_TYPE_DEFAULT, vdev_id, VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) + WMA_LOGE("%s: Failed to create IBSS bss peer", __func__); + else + WMA_LOGA("IBSS BSS peer created with mac %pM", vdev->mac_addr.raw); +} +#endif //#ifdef QCA_IBSS_SUPPORT + +static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, + u32 len) +{ + WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf; + wmi_vdev_stopped_event_fixed_param *event; + u_int8_t *buf; + vos_msg_t vos_msg = {0}; + + WMA_LOGI("%s: Enter", __func__); + param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info; + if (!param_buf) { + WMA_LOGE("Invalid event buffer"); + return -EINVAL; + } + event = param_buf->fixed_param; + buf = vos_mem_malloc(sizeof(wmi_vdev_stopped_event_fixed_param)); + if (!buf) { + WMA_LOGE("%s: Failed alloc memory for buf", __func__); + return -EINVAL; + } + vos_mem_zero(buf, sizeof(wmi_vdev_stopped_event_fixed_param)); + vos_mem_copy(buf, (u_int8_t *)event, + sizeof(wmi_vdev_stopped_event_fixed_param)); + + vos_msg.type = WDA_VDEV_STOP_IND; + vos_msg.bodyptr = buf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGP("%s: Failed to post WDA_VDEV_STOP_IND msg", __func__); + vos_mem_free(buf); + return -1; + } + WMA_LOGD("WDA_VDEV_STOP_IND posted"); + return 0; +} + +void wma_hidden_ssid_vdev_restart_on_vdev_stop(tp_wma_handle wma_handle, u_int8_t sessionId) +{ + wmi_vdev_start_request_cmd_fixed_param *cmd; + wmi_buf_t buf; + wmi_channel *chan; + int32_t len; + u_int8_t *buf_ptr; + struct wma_txrx_node *intr = wma_handle->interfaces; + int32_t ret=0; + + len = sizeof(*cmd) + sizeof(wmi_channel) + + WMI_TLV_HDR_SIZE; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + adf_os_atomic_set(&intr[sessionId].vdev_restart_params.hidden_ssid_restart_in_progress,0); + return; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; + chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_start_request_cmd_fixed_param)); + + WMITLV_SET_HDR(&chan->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + + cmd->vdev_id = sessionId; + cmd->ssid.ssid_len = intr[sessionId].vdev_restart_params.ssid.ssid_len; + vos_mem_copy(cmd->ssid.ssid, + intr[sessionId].vdev_restart_params.ssid.ssid, + cmd->ssid.ssid_len); + cmd->flags = intr[sessionId].vdev_restart_params.flags; + if (intr[sessionId].vdev_restart_params.ssidHidden) + cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; + else + cmd->flags &= (0xFFFFFFFE); + cmd->requestor_id = intr[sessionId].vdev_restart_params.requestor_id; + cmd->disable_hw_ack = intr[sessionId].vdev_restart_params.disable_hw_ack; + + chan->mhz = intr[sessionId].vdev_restart_params.chan.mhz; + chan->band_center_freq1 = intr[sessionId].vdev_restart_params.chan.band_center_freq1; + chan->band_center_freq2 = intr[sessionId].vdev_restart_params.chan.band_center_freq2; + chan->info = intr[sessionId].vdev_restart_params.chan.info; + chan->reg_info_1 = intr[sessionId].vdev_restart_params.chan.reg_info_1; + chan->reg_info_2 = intr[sessionId].vdev_restart_params.chan.reg_info_2; + + cmd->num_noa_descriptors = 0; + buf_ptr = (u_int8_t *)(((u_int8_t *) cmd) + sizeof(*cmd) + + sizeof(wmi_channel)); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + cmd->num_noa_descriptors * + sizeof(wmi_p2p_noa_descriptor)); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle,buf,len, + WMI_VDEV_RESTART_REQUEST_CMDID); + if (ret < 0) { + WMA_LOGE("%s: Failed to send vdev restart command", __func__); + adf_os_atomic_set(&intr[sessionId].vdev_restart_params.hidden_ssid_restart_in_progress,0); + adf_nbuf_free(buf); + } +} + +static int wma_vdev_stop_ind(tp_wma_handle wma, u_int8_t *buf) +{ + wmi_vdev_stopped_event_fixed_param *resp_event; + struct wma_target_req *req_msg; + ol_txrx_peer_handle peer; + ol_txrx_pdev_handle pdev; + u_int8_t peer_id; + struct wma_txrx_node *iface; + int32_t status = 0; + + WMA_LOGI("%s: Enter", __func__); + if (!buf) { + WMA_LOGE("Invalid event buffer"); + return -EINVAL; + } + + resp_event = (wmi_vdev_stopped_event_fixed_param *)buf; + + if ((resp_event->vdev_id <= wma->max_bssid) && + (adf_os_atomic_read(&wma->interfaces[resp_event->vdev_id].vdev_restart_params.hidden_ssid_restart_in_progress)) && + ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) && + (wma->interfaces[resp_event->vdev_id].sub_type == 0))) { + WMA_LOGE("%s: vdev stop event recevied for hidden ssid set using IOCTL ", __func__); + wma_hidden_ssid_vdev_restart_on_vdev_stop(wma, resp_event->vdev_id); + } + + req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_STOP); + if (!req_msg) { + WMA_LOGP("%s: Failed to lookup vdev request for vdev id %d", + __func__, resp_event->vdev_id); + return -EINVAL; + } + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (!pdev) { + WMA_LOGE("%s: pdev is NULL", __func__); + status = -EINVAL; + vos_timer_stop(&req_msg->event_timeout); + goto free_req_msg; + } + + vos_timer_stop(&req_msg->event_timeout); + if (req_msg->msg_type == WDA_DELETE_BSS_REQ) { + tpDeleteBssParams params = + (tpDeleteBssParams)req_msg->user_data; + struct beacon_info *bcn; + if (resp_event->vdev_id > wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d", __func__, + resp_event->vdev_id); + status = -EINVAL; + goto free_req_msg; + } + + iface = &wma->interfaces[resp_event->vdev_id]; + if (iface->handle == NULL) { + WMA_LOGE("%s vdev id %d is already deleted", + __func__, resp_event->vdev_id); + status = -EINVAL; + goto free_req_msg; + } + +#ifdef QCA_IBSS_SUPPORT + if ( wma_is_vdev_in_ibss_mode(wma, resp_event->vdev_id)) + wma_delete_all_ibss_peers(wma, resp_event->vdev_id); + else +#endif + { + if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) + { + wma_delete_all_ap_remote_peers(wma, resp_event->vdev_id); + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, + &peer_id); + if (!peer) + WMA_LOGD("%s Failed to find peer %pM", + __func__, params->bssid); + wma_remove_peer(wma, params->bssid, resp_event->vdev_id, + peer, VOS_FALSE); + } + + if (wmi_unified_vdev_down_send(wma->wmi_handle, resp_event->vdev_id) < 0) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + resp_event->vdev_id); + } else { + wma->interfaces[resp_event->vdev_id].vdev_up = FALSE; + } + ol_txrx_vdev_flush(iface->handle); + WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", + __func__, resp_event->vdev_id); + wdi_in_vdev_unpause(iface->handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); + WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", + __func__, iface->type, iface->sub_type); + bcn = wma->interfaces[resp_event->vdev_id].beacon; + + if (bcn) { + WMA_LOGD("%s: Freeing beacon struct %p, " + "template memory %p", __func__, + bcn, bcn->buf); + if (bcn->dma_mapped) + adf_nbuf_unmap_single(pdev->osdev, bcn->buf, + ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(bcn->buf); + vos_mem_free(bcn); + wma->interfaces[resp_event->vdev_id].beacon = NULL; + } + +#ifdef QCA_IBSS_SUPPORT + /* recreate ibss vdev and bss peer for scan purpose */ + if (wma_is_vdev_in_ibss_mode(wma, resp_event->vdev_id)) + wma_recreate_ibss_vdev_and_bss_peer(wma, resp_event->vdev_id); +#endif + /* Timeout status means its WMA generated DEL BSS REQ when ADD + BSS REQ was timed out to stop the VDEV in this case no need to + send response to UMAC */ + if (params->status == eHAL_STATUS_FW_MSG_TIMEDOUT){ + vos_mem_free(params); + WMA_LOGE("%s: DEL BSS from ADD BSS timeout do not send " + "resp to UMAC (vdev id %x)", + __func__, resp_event->vdev_id); + } else { + params->status = VOS_STATUS_SUCCESS; + wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0); + } + + if (iface->del_staself_req) { + WMA_LOGA("scheduling defered deletion (vdev id %x)", + resp_event->vdev_id); + wma_vdev_detach(wma, iface->del_staself_req, 1); + } + } +free_req_msg: + vos_timer_destroy(&req_msg->event_timeout); + adf_os_mem_free(req_msg); + return status; +} + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +static void wma_send_status_of_ext_wow(tp_wma_handle wma, boolean status) +{ + tSirReadyToExtWoWInd *ready_to_extwow; + VOS_STATUS vstatus; + vos_msg_t vos_msg; + u_int8_t len; + + WMA_LOGD("Posting ready to suspend indication to umac"); + + len = sizeof(tSirReadyToExtWoWInd); + ready_to_extwow = (tSirReadyToExtWoWInd *) vos_mem_malloc(len); + + if (NULL == ready_to_extwow) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return; + } + + ready_to_extwow->mesgType = eWNI_SME_READY_TO_EXTWOW_IND; + ready_to_extwow->mesgLen = len; + ready_to_extwow->status= status; + + vos_msg.type = eWNI_SME_READY_TO_EXTWOW_IND; + vos_msg.bodyptr = (void *) ready_to_extwow; + vos_msg.bodyval = 0; + + vstatus = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg); + if (vstatus != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to post ready to suspend"); + vos_mem_free(ready_to_extwow); + } +} + +static int wma_enable_ext_wow(tp_wma_handle wma, + tpSirExtWoWParams params) +{ + wmi_extwow_enable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int ret; + + len = sizeof(wmi_extwow_enable_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_extwow_enable_cmd_fixed_param *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extwow_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extwow_enable_cmd_fixed_param)); + + cmd->vdev_id = params->vdev_id; + cmd->type = params->type; + cmd->wakeup_pin_num = params->wakeup_pin_num; + + WMA_LOGD("%s: vdev_id %d type %d Wakeup_pin_num %x", + __func__, cmd->vdev_id, + cmd->type, cmd->wakeup_pin_num); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_EXTWOW_ENABLE_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to set EXTWOW Enable", __func__); + wmi_buf_free(buf); + wma_send_status_of_ext_wow(wma, FALSE); + return VOS_STATUS_E_FAILURE; + } + + wma_send_status_of_ext_wow(wma, TRUE); + return VOS_STATUS_SUCCESS; + +} + +static int wma_set_app_type1_params_in_fw(tp_wma_handle wma, + tpSirAppType1Params appType1Params) +{ + wmi_extwow_set_app_type1_params_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int ret; + + len = sizeof(wmi_extwow_set_app_type1_params_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_extwow_set_app_type1_params_cmd_fixed_param *) + wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extwow_set_app_type1_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extwow_set_app_type1_params_cmd_fixed_param)); + + cmd->vdev_id = appType1Params->vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(appType1Params->wakee_mac_addr, + &cmd->wakee_mac); + vos_mem_copy(cmd->ident, appType1Params->identification_id, 8); + cmd->ident_len = appType1Params->id_length; + vos_mem_copy(cmd->passwd, appType1Params->password, 16); + cmd->passwd_len = appType1Params->pass_length; + + WMA_LOGD("%s: vdev_id %d wakee_mac_addr %pM " + "identification_id %.8s id_length %u " + "password %.16s pass_length %u", + __func__, cmd->vdev_id, appType1Params->wakee_mac_addr, + cmd->ident, cmd->ident_len, + cmd->passwd, cmd->passwd_len); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to set APP TYPE1 PARAMS", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static int wma_set_app_type2_params_in_fw(tp_wma_handle wma, + tpSirAppType2Params appType2Params) +{ + wmi_extwow_set_app_type2_params_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int ret; + + len = sizeof(wmi_extwow_set_app_type2_params_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_extwow_set_app_type2_params_cmd_fixed_param *) + wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extwow_set_app_type2_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extwow_set_app_type2_params_cmd_fixed_param)); + + cmd->vdev_id = appType2Params->vdev_id; + + vos_mem_copy(cmd->rc4_key, appType2Params->rc4_key, 16); + cmd->rc4_key_len = appType2Params->rc4_key_len; + + cmd->ip_id = appType2Params->ip_id; + cmd->ip_device_ip = appType2Params->ip_device_ip; + cmd->ip_server_ip = appType2Params->ip_server_ip; + + cmd->tcp_src_port = appType2Params->tcp_src_port; + cmd->tcp_dst_port = appType2Params->tcp_dst_port; + cmd->tcp_seq = appType2Params->tcp_seq; + cmd->tcp_ack_seq = appType2Params->tcp_ack_seq; + + cmd->keepalive_init = appType2Params->keepalive_init; + cmd->keepalive_min = appType2Params->keepalive_min; + cmd->keepalive_max = appType2Params->keepalive_max; + cmd->keepalive_inc = appType2Params->keepalive_inc; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(appType2Params->gateway_mac, + &cmd->gateway_mac); + cmd->tcp_tx_timeout_val = appType2Params->tcp_tx_timeout_val; + cmd->tcp_rx_timeout_val = appType2Params->tcp_rx_timeout_val; + + WMA_LOGD("%s: vdev_id %d gateway_mac %pM " + "rc4_key %.16s rc4_key_len %u " + "ip_id %x ip_device_ip %x ip_server_ip %x " + "tcp_src_port %u tcp_dst_port %u tcp_seq %u " + "tcp_ack_seq %u keepalive_init %u keepalive_min %u " + "keepalive_max %u keepalive_inc %u " + "tcp_tx_timeout_val %u tcp_rx_timeout_val %u", + __func__, cmd->vdev_id, appType2Params->gateway_mac, + cmd->rc4_key, cmd->rc4_key_len, + cmd->ip_id, cmd->ip_device_ip, cmd->ip_server_ip, + cmd->tcp_src_port, cmd->tcp_dst_port, cmd->tcp_seq, + cmd->tcp_ack_seq, cmd->keepalive_init, cmd->keepalive_min, + cmd->keepalive_max, cmd->keepalive_inc, + cmd->tcp_tx_timeout_val, cmd->tcp_rx_timeout_val); + + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to set APP TYPE2 PARAMS", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; + +} +#endif +static void wma_update_pdev_stats(tp_wma_handle wma, + wmi_pdev_stats *pdev_stats) +{ + tAniGetPEStatsRsp *stats_rsp_params; + tANI_U32 temp_mask; + tANI_U8 *stats_buf; + tCsrGlobalClassAStatsInfo *classa_stats = NULL; + struct wma_txrx_node *node; + u_int8_t i; + + for (i = 0; i < wma->max_bssid; i++) { + node = &wma->interfaces[i]; + stats_rsp_params = node->stats_rsp; + if (stats_rsp_params) { + node->fw_stats_set |= FW_PDEV_STATS_SET; + WMA_LOGD("<---FW PDEV STATS received for vdevId:%d", + i); + stats_buf = (tANI_U8 *) (stats_rsp_params + 1); + temp_mask = stats_rsp_params->statsMask; + if (temp_mask & (1 << eCsrSummaryStats)) + stats_buf += sizeof(tCsrSummaryStatsInfo); + + if (temp_mask & (1 << eCsrGlobalClassAStats)) { + classa_stats = + (tCsrGlobalClassAStatsInfo *) stats_buf; + classa_stats->max_pwr = pdev_stats->chan_tx_pwr; + } + } + } +} + +static void wma_update_vdev_stats(tp_wma_handle wma, + wmi_vdev_stats *vdev_stats) +{ + tAniGetPEStatsRsp *stats_rsp_params; + tCsrSummaryStatsInfo *summary_stats = NULL; + tANI_U8 *stats_buf; + struct wma_txrx_node *node; + tANI_U8 i; + v_S7_t rssi = 0; + tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)wma->pGetRssiReq; + + node = &wma->interfaces[vdev_stats->vdev_id]; + stats_rsp_params = node->stats_rsp; + if (stats_rsp_params) { + stats_buf = (tANI_U8 *) (stats_rsp_params + 1); + node->fw_stats_set |= FW_VDEV_STATS_SET; + WMA_LOGD("<---FW VDEV STATS received for vdevId:%d", + vdev_stats->vdev_id); + if (stats_rsp_params->statsMask & + (1 << eCsrSummaryStats)) { + summary_stats = (tCsrSummaryStatsInfo *) stats_buf; + for (i=0 ; i < 4 ; i++) { + summary_stats->tx_frm_cnt[i] = + vdev_stats->tx_frm_cnt[i]; + summary_stats->fail_cnt[i] = + vdev_stats->fail_cnt[i]; + summary_stats->multiple_retry_cnt[i] = + vdev_stats->multiple_retry_cnt[i]; + } + + summary_stats->rx_frm_cnt = vdev_stats->rx_frm_cnt; + summary_stats->rx_error_cnt = vdev_stats->rx_err_cnt; + summary_stats->rx_discard_cnt = + vdev_stats->rx_discard_cnt; + summary_stats->ack_fail_cnt = vdev_stats->ack_fail_cnt; + summary_stats->rts_succ_cnt = vdev_stats->rts_succ_cnt; + summary_stats->rts_fail_cnt = vdev_stats->rts_fail_cnt; + } + } + + if (pGetRssiReq && + pGetRssiReq->sessionId == vdev_stats->vdev_id) { + if ((vdev_stats->vdev_snr.bcn_snr == WMA_TGT_INVALID_SNR) && + (vdev_stats->vdev_snr.dat_snr == WMA_TGT_INVALID_SNR)) { + /* + * Firmware sends invalid snr till it sees + * Beacon/Data after connection since after + * vdev up fw resets the snr to invalid. + * In this duartion Host will return the last know + * rssi during connection. + */ + rssi = wma->first_rssi; + } else { + if (vdev_stats->vdev_snr.bcn_snr != WMA_TGT_INVALID_SNR) { + rssi = vdev_stats->vdev_snr.bcn_snr; + } else if (vdev_stats->vdev_snr.dat_snr != WMA_TGT_INVALID_SNR) { + rssi = vdev_stats->vdev_snr.dat_snr; + } + + /* + * Get the absolute rssi value from the current rssi value + * the sinr value is hardcoded into 0 in the core stack + */ + rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM; + } + + WMA_LOGD("vdev id %d beancon snr %d data snr %d", + vdev_stats->vdev_id, + vdev_stats->vdev_snr.bcn_snr, + vdev_stats->vdev_snr.dat_snr); + WMA_LOGD("Average Rssi = %d, vdev id= %d", rssi, + pGetRssiReq->sessionId); + + /* update the average rssi value to UMAC layer */ + if (NULL != pGetRssiReq->rssiCallback) { + ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(rssi,pGetRssiReq->staId, + pGetRssiReq->pDevContext); + } + + adf_os_mem_free(pGetRssiReq); + wma->pGetRssiReq = NULL; + } +} + +static void wma_post_stats(tp_wma_handle wma, struct wma_txrx_node *node) +{ + tAniGetPEStatsRsp *stats_rsp_params; + + stats_rsp_params = node->stats_rsp; + /* send response to UMAC*/ + wma_send_msg(wma, WDA_GET_STATISTICS_RSP, (void *)stats_rsp_params, 0) ; + node->stats_rsp = NULL; + node->fw_stats_set = 0; +} + +static void wma_update_peer_stats(tp_wma_handle wma, wmi_peer_stats *peer_stats) +{ + tAniGetPEStatsRsp *stats_rsp_params; + tCsrGlobalClassAStatsInfo *classa_stats = NULL; + struct wma_txrx_node *node; + tANI_U8 *stats_buf, vdev_id, macaddr[IEEE80211_ADDR_LEN], mcsRateFlags; + tANI_U32 temp_mask; + + WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr, &macaddr[0]); + if (!wma_find_vdev_by_bssid(wma, macaddr, &vdev_id)) + return; + + node = &wma->interfaces[vdev_id]; + if (node->stats_rsp) { + node->fw_stats_set |= FW_PEER_STATS_SET; + WMA_LOGD("<-- FW PEER STATS received for vdevId:%d", vdev_id); + stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp; + stats_buf = (tANI_U8 *) (stats_rsp_params + 1); + temp_mask = stats_rsp_params->statsMask; + if (temp_mask & (1 << eCsrSummaryStats)) + stats_buf += sizeof(tCsrSummaryStatsInfo); + + if (temp_mask & (1 << eCsrGlobalClassAStats)) { + classa_stats = (tCsrGlobalClassAStatsInfo *) stats_buf; + WMA_LOGD("peer tx rate:%d", peer_stats->peer_tx_rate); + /*The linkspeed returned by fw is in kbps so convert + *it in to units of 500kbps which is expected by UMAC*/ + if (peer_stats->peer_tx_rate) { + classa_stats->tx_rate = + peer_stats->peer_tx_rate/500; + } + + classa_stats->tx_rate_flags = node->rate_flags; + if (!(node->rate_flags & eHAL_TX_RATE_LEGACY)) { + classa_stats->mcs_index = + wma_get_mcs_idx((peer_stats->peer_tx_rate/100), + node->rate_flags, + node->nss, + &mcsRateFlags); + /* rx_frag_cnt and promiscuous_rx_frag_cnt + * parameter is currently not used. lets use the + * same parameter to hold the nss value and mcs + * rate flags */ + classa_stats->rx_frag_cnt = node->nss; + classa_stats->promiscuous_rx_frag_cnt = mcsRateFlags; + WMA_LOGD("Computed mcs_idx:%d mcs_rate_flags:%d", + classa_stats->mcs_index, + mcsRateFlags); + } + /* FW returns tx power in intervals of 0.5 dBm + Convert it back to intervals of 1 dBm */ + classa_stats->max_pwr = + roundup(classa_stats->max_pwr, 2) >> 1; + WMA_LOGD("peer tx rate flags:%d nss:%d max_txpwr:%d", + node->rate_flags, node->nss, + classa_stats->max_pwr); + } + + if (node->fw_stats_set & FW_STATS_SET) { + WMA_LOGD("<--STATS RSP VDEV_ID:%d", vdev_id); + wma_post_stats(wma, node); + } + } +} + +static void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus, + u_int8_t link_status) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + vos_msg_t sme_msg = {0} ; + + pGetLinkStatus->linkStatus = link_status; + sme_msg.type = eWNI_SME_LINK_STATUS_IND; + sme_msg.bodyptr = pGetLinkStatus; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGE("%s: Fail to post link status ind msg", __func__); + vos_mem_free(pGetLinkStatus); + } +} + +static int wma_link_status_rsp(tp_wma_handle wma, u_int8_t *buf) +{ + wmi_vdev_rate_stats_event_fixed_param *event; + wmi_vdev_rate_ht_info *ht_info; + struct wma_txrx_node *intr = wma->interfaces; + u_int8_t link_status = LINK_STATUS_LEGACY; + int i; + + event = (wmi_vdev_rate_stats_event_fixed_param *)buf; + ht_info = (wmi_vdev_rate_ht_info *)(buf + sizeof(*event)); + + WMA_LOGD("num_vdev_stats: %d", event->num_vdev_stats); + for (i = 0; (i < event->num_vdev_stats) && ht_info; i++) { + WMA_LOGD( + "%s vdevId:%d tx_nss:%d rx_nss:%d tx_preamble:%d rx_preamble:%d", + __func__, + ht_info->vdevid, + ht_info->tx_nss, + ht_info->rx_nss, + ht_info->tx_preamble, + ht_info->rx_preamble); + if (ht_info->vdevid < wma->max_bssid && + intr[ht_info->vdevid].plink_status_req) { + if (ht_info->tx_nss || ht_info->rx_nss) + link_status = LINK_STATUS_MIMO; + + if ((ht_info->tx_preamble == LINK_RATE_VHT) || + (ht_info->rx_preamble == LINK_RATE_VHT)) + link_status |= LINK_STATUS_VHT; + + if (intr[ht_info->vdevid].nss == 2) + link_status |= LINK_SUPPORT_MIMO; + + if (intr[ht_info->vdevid].rate_flags & + (eHAL_TX_RATE_VHT20 | eHAL_TX_RATE_VHT40 | + eHAL_TX_RATE_VHT80)) + link_status |= LINK_SUPPORT_VHT; + + wma_post_link_status(intr[ht_info->vdevid].plink_status_req, + link_status); + intr[ht_info->vdevid].plink_status_req = NULL; + link_status = LINK_STATUS_LEGACY; + } + + ht_info++; + } + + return 0; +} + +static int wma_link_status_event_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_UPDATE_VDEV_RATE_STATS_EVENTID_param_tlvs *param_buf; + wmi_vdev_rate_stats_event_fixed_param *event; + vos_msg_t vos_msg = {0}; + u_int32_t buf_size; + u_int8_t *buf; + + param_buf = + (WMI_UPDATE_VDEV_RATE_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_buf) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + + event = param_buf->fixed_param; + buf_size = sizeof(wmi_vdev_rate_stats_event_fixed_param) + + sizeof(wmi_vdev_rate_ht_info) * event->num_vdev_stats; + buf = vos_mem_malloc(buf_size); + if (!buf) { + WMA_LOGE("%s: Failed alloc memory for buf", __func__); + return -ENOMEM; + } + + vos_mem_zero(buf, buf_size); + vos_mem_copy(buf, param_buf->fixed_param, + sizeof(wmi_vdev_rate_stats_event_fixed_param)); + vos_mem_copy((buf + sizeof(wmi_vdev_rate_stats_event_fixed_param)), + param_buf->ht_info, + sizeof(wmi_vdev_rate_ht_info) * event->num_vdev_stats); + + vos_msg.type = WDA_GET_LINK_STATUS_RSP_IND; + vos_msg.bodyptr = buf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGP("%s: Failed to post WDA_GET_LINK_STATUS_RSP_IND msg", + __func__); + vos_mem_free(buf); + return -1; + } + WMA_LOGD("posted WDA_GET_LINK_STATUS_RSP_IND"); + + return 0; +} + +static int wma_stats_event_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; + wmi_stats_event_fixed_param *event; + vos_msg_t vos_msg = {0}; + u_int32_t buf_size; + u_int8_t *buf; + + param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_buf) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + buf_size = sizeof(*event) + + (event->num_pdev_stats * sizeof(wmi_pdev_stats)) + + (event->num_vdev_stats * sizeof(wmi_vdev_stats)) + + (event->num_peer_stats * sizeof(wmi_peer_stats)); + buf = vos_mem_malloc(buf_size); + if (!buf) { + WMA_LOGE("%s: Failed alloc memory for buf", __func__); + return -ENOMEM; + } + vos_mem_zero(buf, buf_size); + vos_mem_copy(buf, event, sizeof(*event)); + vos_mem_copy(buf + sizeof(*event), (u_int8_t *)param_buf->data, + (buf_size - sizeof(*event))); + vos_msg.type = WDA_FW_STATS_IND; + vos_msg.bodyptr = buf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGP("%s: Failed to post WDA_FW_STATS_IND msg", __func__); + vos_mem_free(buf); + return -1; + } + WMA_LOGD("WDA_FW_STATS_IND posted"); + return 0; +} + +static VOS_STATUS wma_send_link_speed(u_int32_t link_speed) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + vos_msg_t sme_msg = {0} ; + tSirLinkSpeedInfo *ls_ind = + (tSirLinkSpeedInfo *) vos_mem_malloc(sizeof(tSirLinkSpeedInfo)); + if (!ls_ind) { + WMA_LOGE("%s: Memory allocation failed.", __func__); + vos_status = VOS_STATUS_E_NOMEM; + } + else + { + ls_ind->estLinkSpeed = link_speed; + sme_msg.type = eWNI_SME_LINK_SPEED_IND; + sme_msg.bodyptr = ls_ind; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status) ) { + WMA_LOGE("%s: Fail to post linkspeed ind msg", __func__); + vos_mem_free(ls_ind); + } + } + return vos_status; +} + +static int wma_link_speed_event_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *param_buf; + wmi_peer_estimated_linkspeed_event_fixed_param *event; + VOS_STATUS vos_status; + + param_buf = (WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *)cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid linkspeed event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + vos_status = wma_send_link_speed(event->est_linkspeed_kbps); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + return -EINVAL; + } + return 0; +} + +static void wma_fw_stats_ind(tp_wma_handle wma, u_int8_t *buf) +{ + wmi_stats_event_fixed_param *event = (wmi_stats_event_fixed_param *)buf; + wmi_pdev_stats *pdev_stats; + wmi_vdev_stats *vdev_stats; + wmi_peer_stats *peer_stats; + u_int8_t i, *temp; + + WMA_LOGI("%s: Enter", __func__); + + temp = buf + sizeof(*event); + WMA_LOGD("%s: num_stats: pdev: %u vdev: %u peer %u", + __func__, event->num_pdev_stats, event->num_vdev_stats, + event->num_peer_stats); + if (event->num_pdev_stats > 0) { + for (i = 0; i < event->num_pdev_stats; i++) { + pdev_stats = (wmi_pdev_stats*)temp; + wma_update_pdev_stats(wma, pdev_stats); + temp += sizeof(wmi_pdev_stats); + } + } + + if (event->num_vdev_stats > 0) { + for (i = 0; i < event->num_vdev_stats; i++) { + vdev_stats = (wmi_vdev_stats *)temp; + wma_update_vdev_stats(wma, vdev_stats); + temp += sizeof(wmi_vdev_stats); + } + } + + if (event->num_peer_stats > 0) { + for (i = 0; i < event->num_peer_stats; i++) { + peer_stats = (wmi_peer_stats *)temp; + wma_update_peer_stats(wma, peer_stats); + temp += sizeof(wmi_peer_stats); + } + } + + WMA_LOGI("%s: Exit", __func__); +} + +#ifdef FEATURE_WLAN_EXTSCAN +static int wma_extscan_start_stop_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *param_buf; + wmi_extscan_start_stop_event_fixed_param *event; + tSirExtScanStartRspParams *extscan_ind; + u_int16_t event_type; + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid extscan event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + extscan_ind = vos_mem_malloc(sizeof(*extscan_ind)); + if (!extscan_ind) { + WMA_LOGE("%s: extscan memory allocation failed", __func__); + return -EINVAL; + } + switch (event->command) { + case WMI_EXTSCAN_START_CMDID: + event_type = eSIR_EXTSCAN_START_RSP; + extscan_ind->status = event->status; + extscan_ind->requestId = event->request_id; + break; + case WMI_EXTSCAN_STOP_CMDID: + event_type = eSIR_EXTSCAN_STOP_RSP; + extscan_ind->status = event->status; + extscan_ind->requestId = event->request_id; + break; + case WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID: + extscan_ind->status = event->status; + extscan_ind->requestId = event->request_id; + if (event->mode == WMI_EXTSCAN_MODE_STOP) { + event_type = + eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP; + } else { + event_type = + eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP; + } + break; + case WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID: + extscan_ind->status = event->status; + extscan_ind->requestId = event->request_id; + if (event->mode == WMI_EXTSCAN_MODE_STOP) { + event_type = + eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP; + } else { + event_type = + eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP; + } + break; + case WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID: + extscan_ind->status = event->status; + extscan_ind->requestId = event->request_id; + event_type = eSIR_EXTSCAN_CACHED_RESULTS_RSP; + break; + default: + WMA_LOGE("%s: Unknown event(%d) from target", + __func__, event->status); + vos_mem_free(extscan_ind); + return -EINVAL; + } + pMac->sme.pExtScanIndCb(pMac->hHdd, + event_type, extscan_ind); + WMA_LOGD("%s: sending event to umac for requestid %x" + "with status %d", __func__, + extscan_ind->requestId, extscan_ind->status); + vos_mem_free(extscan_ind); + return 0; +} + +static int wma_extscan_operations_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *param_buf; + wmi_extscan_operation_event_fixed_param *oprn_event; + tSirExtScanOnScanEventIndParams *oprn_ind; + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid scan operation event", __func__); + return -EINVAL; + } + oprn_event = param_buf->fixed_param; + oprn_ind = vos_mem_malloc(sizeof(*oprn_ind)); + if (!oprn_ind) { + WMA_LOGE("%s: extscan memory allocation failed", + __func__); + vos_mem_free(oprn_ind); + return -EINVAL; + } + + oprn_ind->requestId = oprn_event->request_id; + + switch (oprn_event->event) { + case WMI_EXTSCAN_BUCKET_COMPLETED_EVENT: + oprn_ind->scanEventType = WIFI_SCAN_COMPLETE; + oprn_ind->status = 0; + break; + case WMI_EXTSCAN_CYCLE_STARTED_EVENT: + vos_wake_lock_acquire(&wma->extscan_wake_lock); + WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_STARTED_EVENT", + __func__); + goto exit_handler; + case WMI_EXTSCAN_CYCLE_COMPLETED_EVENT: + vos_wake_lock_release(&wma->extscan_wake_lock); + WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_COMPLETED_EVENT", + __func__); + goto exit_handler; + default: + WMA_LOGE("%s: Unknown event(%d) from target", + __func__, oprn_event->event); + vos_mem_free(oprn_ind); + return -EINVAL; + } + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND, + oprn_ind); +exit_handler: + WMA_LOGD("%s: sending scan progress event to hdd", + __func__); + vos_mem_free(oprn_ind); + return 0; +} + +static int wma_extscan_table_usage_event_handler (void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *param_buf; + wmi_extscan_table_usage_event_fixed_param *event; + tSirExtScanResultsAvailableIndParams *tbl_usg_ind; + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid table usage event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + tbl_usg_ind = vos_mem_malloc(sizeof(*tbl_usg_ind)); + if (!tbl_usg_ind) { + WMA_LOGE("%s: table usage allocation failed", + __func__); + return -EINVAL; + } + tbl_usg_ind->requestId = event->request_id; + tbl_usg_ind->numResultsAvailable = event->maximum_entries; + + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND, + tbl_usg_ind); + WMA_LOGD("%s: sending scan_res available event to hdd", + __func__); + vos_mem_free(tbl_usg_ind); + return 0; +} + +static int wma_extscan_capabilities_event_handler (void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *param_buf; + wmi_extscan_capabilities_event_fixed_param *event; + wmi_extscan_cache_capabilities *src_cache; + wmi_extscan_hotlist_monitor_capabilities *src_hotlist; + wmi_extscan_wlan_change_monitor_capabilities *src_change; + + tSirExtScanCapabilitiesEvent *dest_capab; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid capabilities event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + src_cache = param_buf->extscan_cache_capabilities; + src_hotlist = param_buf->hotlist_capabilities; + src_change = param_buf->wlan_change_capabilities; + + if (!src_cache || !src_hotlist || !src_change) { + WMA_LOGE("%s: Invalid capabilities list", __func__); + return -EINVAL; + } + dest_capab = vos_mem_malloc(sizeof(*dest_capab)); + if (!dest_capab) { + WMA_LOGE("%s: Allocation failed for capabilities buffer", + __func__); + return -EINVAL; + } + dest_capab->requestId = event->request_id; + dest_capab->scanBuckets = src_cache->max_buckets; + dest_capab->scanCacheSize = src_cache->scan_cache_entry_size; + dest_capab->maxApPerScan = src_cache->max_bssid_per_scan; + dest_capab->maxScanReportingThreshold = + src_cache->max_table_usage_threshold; + + dest_capab->maxHotlistAPs = src_hotlist->max_hotlist_entries; + dest_capab->maxRssiSampleSize = + src_change->max_rssi_averaging_samples; + dest_capab->maxBsidHistoryEntries = + src_change->max_rssi_history_entries; + dest_capab->maxSignificantWifiChangeAPs = + src_change->max_wlan_change_entries; + dest_capab->status = 0; + + WMA_LOGD("%s: Capabilities: scanBuckets: %d," + "maxHotlistAPs: %d,scanCacheSize: %d", + __func__, dest_capab->scanBuckets, + dest_capab->maxHotlistAPs, + dest_capab->scanCacheSize); + + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_GET_CAPABILITIES_IND, + dest_capab); + WMA_LOGD("%s: sending capabilities event to hdd", __func__); + vos_mem_free(dest_capab); + return 0; +} + +static int wma_extscan_hotlist_match_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *param_buf; + wmi_extscan_hotlist_match_event_fixed_param *event; + tSirWifiScanResultEvent *dest_hotlist; + tSirWifiScanResult *dest_ap; + wmi_extscan_wlan_descriptor *src_hotlist; + int numap; + int j; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid hotlist match event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + src_hotlist = param_buf->hotlist_match; + numap = event->total_entries; + + if (!src_hotlist || !numap) { + WMA_LOGE("%s: Hotlist AP's list invalid", __func__); + return -EINVAL; + } + dest_hotlist = vos_mem_malloc(sizeof(*dest_hotlist) + + sizeof(*dest_ap) * numap); + if (!dest_hotlist) { + WMA_LOGE("%s: Allocation failed for hotlist buffer", + __func__); + return -EINVAL; + } + dest_ap = &dest_hotlist->ap[0]; + dest_hotlist->numOfAps = event->total_entries; + dest_hotlist->requestId = event->config_request_id; + WMA_LOGD("%s: Hotlist match: requestId: 0x%x," + "numOfAps: %d", __func__, + dest_hotlist->requestId, dest_hotlist->numOfAps); + + for (j = 0; j < numap; j++) { + dest_ap->channel = src_hotlist->channel; + dest_ap->ts = src_hotlist->tstamp; + dest_ap->rtt = src_hotlist->rtt; + dest_ap->rtt_sd = src_hotlist->rtt_sd; + dest_ap->beaconPeriod = src_hotlist->beacon_interval; + dest_ap->capability = src_hotlist->capabilities; + dest_ap->ieLength = src_hotlist-> ie_length; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid, + dest_ap->bssid); + vos_mem_copy(dest_ap->ssid, src_hotlist->ssid.ssid, + src_hotlist->ssid.ssid_len); + dest_ap->ssid[src_hotlist->ssid.ssid_len] = '\0'; + dest_ap++; + src_hotlist++; + } + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_HOTLIST_MATCH_IND, + dest_hotlist); + WMA_LOGD("%s: sending hotlist match event to hdd", __func__); + vos_mem_free(dest_hotlist); + return 0; +} + +static int wma_extscan_cached_results_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf; + wmi_extscan_cached_results_event_fixed_param *event; + tSirWifiScanResultEvent *dest_cachelist; + tSirWifiScanResult *dest_ap; + wmi_extscan_wlan_descriptor *src_hotlist; + wmi_extscan_rssi_info *src_rssi; + int numap; + int j; + int moredata; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid cached results event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + src_hotlist = param_buf->bssid_list; + src_rssi = param_buf->rssi_list; + if (!src_hotlist || !src_rssi) { + WMA_LOGE("%s: Cached_results AP's list invalid", + __func__); + return -EINVAL; + } + if (event->first_entry_index + + event->num_entries_in_page < event->total_entries) { + moredata = 1; + } else { + moredata = 0; + } + numap = event->num_entries_in_page; + if (!src_hotlist || !numap) { + WMA_LOGE("%s: cached results AP's list invalid", __func__); + return -EINVAL; + } + dest_cachelist = vos_mem_malloc(sizeof(*dest_cachelist) + + sizeof(*dest_ap) * numap); + if (!dest_cachelist) { + WMA_LOGE("%s: Allocation failed for cached" + "results event", __func__); + return -EINVAL; + } + dest_ap = &dest_cachelist->ap[0]; + dest_cachelist->requestId = event->request_id; + dest_cachelist->numOfAps = event->num_entries_in_page; + dest_cachelist->moreData = moredata; + + for (j = 0; j < numap; j++) { + dest_ap->channel = src_hotlist->channel; + dest_ap->ts = src_hotlist->tstamp * WMA_SEC_TO_USEC; + dest_ap->rtt = src_hotlist->rtt; + dest_ap->rtt_sd = src_hotlist->rtt_sd; + dest_ap->beaconPeriod = src_hotlist->beacon_interval; + dest_ap->capability = src_hotlist->capabilities; + dest_ap->ieLength = src_hotlist-> ie_length; + dest_ap->rssi = src_rssi->rssi; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid, dest_ap->bssid); + + vos_mem_copy(dest_ap->ssid, src_hotlist->ssid.ssid, + src_hotlist->ssid.ssid_len); + dest_ap->ssid[src_hotlist->ssid.ssid_len] = '\0'; + dest_ap++; + src_hotlist++; + src_rssi++; + } + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_CACHED_RESULTS_IND, + dest_cachelist); + WMA_LOGD("%s: sending cached results event", __func__); + vos_mem_free(dest_cachelist); + return 0; +} + +static int wma_extscan_change_results_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *param_buf; + wmi_extscan_wlan_change_results_event_fixed_param *event; + tSirWifiSignificantChangeEvent *dest_chglist; + tSirWifiSignificantChange *dest_ap; + wmi_extscan_wlan_change_result_bssid *src_chglist; + + int numap; + int i, k; + u_int8_t *src_rssi; + int count = 0; + int moredata; + int rssi_num = 0; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( + VOS_MODULE_ID_PE, wma->vos_context); + if (!pMac) { + WMA_LOGE("%s: Invalid pMac", __func__); + return -EINVAL; + } + if (!pMac->sme.pExtScanIndCb) { + WMA_LOGE("%s: Callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *) + cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid change monitor event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + src_chglist = param_buf->bssid_signal_descriptor_list; + src_rssi = param_buf->rssi_list; + numap = event->num_entries_in_page; + + if (!src_chglist || !numap) { + WMA_LOGE("%s: changed monitor results AP's" + "list invalid", __func__); + return -EINVAL; + } + for (i = 0; i < numap; i++) { + rssi_num += src_chglist->num_rssi_samples; + } + if (event->first_entry_index + + event->num_entries_in_page < event->total_entries) { + moredata = 1; + } else { + moredata = 0; + } + dest_chglist = vos_mem_malloc(sizeof(*dest_chglist) + + sizeof(*dest_ap) * numap + + sizeof(tANI_S32) * rssi_num); + if (!dest_chglist) { + WMA_LOGE("%s: Allocation failed for change monitor", + __func__); + return -EINVAL; + } + dest_ap = &dest_chglist->ap[0]; + for (i = 0; i < numap; i++) { + dest_ap->channel = src_chglist->channel; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_chglist->bssid, + dest_ap->bssid); + dest_ap->numOfRssi = + src_chglist->num_rssi_samples; + if (dest_ap->numOfRssi) { + for (k = 0; k < dest_ap->numOfRssi; k++) { + dest_ap->rssi[k] = WMA_TGT_NOISE_FLOOR_DBM + + src_rssi[count++]; + } + } + dest_ap += dest_ap->numOfRssi * sizeof(tANI_S32); + src_chglist++; + } + dest_chglist->requestId = event->request_id; + dest_chglist->moreData = moredata; + dest_chglist->numResults = event->total_entries; + + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND, + dest_chglist); + WMA_LOGD("%s: sending change monitor results", __func__); + vos_mem_free(dest_chglist); + return 0; +} +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +static int wma_unified_link_iface_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_iface_link_stats_event_fixed_param *fixed_param; + wmi_iface_link_stats *link_stats; + wmi_wmm_ac_stats *ac_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_link_stats, *t_ac_stats; + u_int32_t next_res_offset, next_ac_offset, count; + u_int32_t roaming_offset , roaming_size; + size_t link_stats_size, ac_stats_size, iface_info_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Iface Stats event to HDD", __func__); + param_tlvs = (WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + + /* + * cmd_param_info contains + * wmi_iface_link_stats_event_fixed_param fixed_param; + * wmi_iface_link_stats iface_link_stats; + * iface_link_stats->num_ac * size of(struct wmi_wmm_ac_stats) + */ + fixed_param = param_tlvs->fixed_param; + link_stats = param_tlvs->iface_link_stats; + ac_stats = param_tlvs->ac; + + if (!fixed_param || !link_stats || !ac_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__); + return -EINVAL; + } + + link_stats_size = sizeof(tSirWifiIfaceStat); + iface_info_size = sizeof(tSirWifiInterfaceInfo); + ac_stats_size = sizeof(tSirWifiWmmAcStat); + link_stats_results_size = sizeof(*link_stats_results) + + link_stats_size; + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (!link_stats_results) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Interface stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u vdev_id %u", + fixed_param->request_id,fixed_param->vdev_id); + + WMA_LOGD("Iface Stats:"); + WMA_LOGD("beacon_rx %u mgmt_rx %u mgmt_action_rx %u mgmt_action_tx %u " + "rssi_mgmt %u rssi_data %u rssi_ack %u num_peers %u " + "num_peer_events %u num_ac %u roam_state %u", + link_stats->beacon_rx, link_stats->mgmt_rx, + link_stats->mgmt_action_rx, link_stats->mgmt_action_tx, + link_stats->rssi_mgmt, link_stats->rssi_data, + link_stats->rssi_ack, link_stats->num_peers, + link_stats->num_peer_events, link_stats->num_ac, + link_stats->roam_state); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_IFACE; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = fixed_param->vdev_id; + link_stats_results->num_peers = link_stats->num_peers; + link_stats_results->peer_event_number = 0; + link_stats_results->moreResultToFollow = 0; + + results = (u_int8_t *)link_stats_results->results; + t_link_stats = (u_int8_t *)link_stats; + t_ac_stats = (u_int8_t *)ac_stats; + + /* Copy roaming state */ + roaming_offset = offsetof(tSirWifiInterfaceInfo, roaming); + roaming_size = member_size(tSirWifiInterfaceInfo, roaming); + + vos_mem_copy(results + roaming_offset, &link_stats->roam_state, + roaming_size); + + vos_mem_copy(results + iface_info_size, + t_link_stats + WMI_TLV_HDR_SIZE, + link_stats_size - iface_info_size - WIFI_AC_MAX * ac_stats_size); + + next_res_offset = link_stats_size - WIFI_AC_MAX * ac_stats_size; + next_ac_offset = WMI_TLV_HDR_SIZE; + + WMA_LOGD("AC Stats:"); + for (count = 0; count < link_stats->num_ac; count++) { + WMA_LOGD("ac_type %u tx_mpdu %u rx_mpdu %u tx_mcast %u " + "rx_mcast %u rx_ampdu %u tx_ampdu %u mpdu_lost %u " + "retries %u retries_short %u retries_long %u " + "contention_time_min %u contention_time_max %u " + "contention_time_avg %u contention_num_samples %u", + ac_stats->ac_type, ac_stats->tx_mpdu, ac_stats->rx_mpdu, + ac_stats->tx_mcast, ac_stats->rx_mcast, + ac_stats->rx_ampdu,ac_stats->tx_ampdu, + ac_stats->mpdu_lost, ac_stats->retries, + ac_stats->retries_short, ac_stats->retries_long, + ac_stats->contention_time_min, + ac_stats->contention_time_max, + ac_stats->contention_time_avg, + ac_stats->contention_num_samples); + ac_stats++; + + vos_mem_copy(results + next_res_offset, + t_ac_stats + next_ac_offset, + ac_stats_size); + next_res_offset += ac_stats_size; + next_ac_offset += sizeof(*ac_stats); + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Iface Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +static int wma_unified_link_peer_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_PEER_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_peer_stats_event_fixed_param *fixed_param; + wmi_peer_link_stats *peer_stats, *temp_peer_stats; + wmi_rate_stats *rate_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_peer_stats, *t_rate_stats; + u_int32_t count, num_rates=0; + u_int32_t next_res_offset, next_peer_offset, next_rate_offset; + size_t peer_info_size, peer_stats_size, rate_stats_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Peer Stats event to HDD", __func__); + param_tlvs = (WMI_PEER_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + /* + * cmd_param_info contains + * wmi_peer_stats_event_fixed_param fixed_param; + * num_peers * size of(struct wmi_peer_link_stats) + * num_rates * size of(struct wmi_rate_stats) + * num_rates is the sum of the rates of all the peers. + */ + fixed_param = param_tlvs->fixed_param; + peer_stats = param_tlvs->peer_stats; + rate_stats = param_tlvs->peer_rate_stats; + + if (!fixed_param || !peer_stats || !rate_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Peer Stats", __func__); + return -EINVAL; + } + + /* + * num_rates - sum of the rates of all the peers + */ + temp_peer_stats = (wmi_peer_link_stats*)peer_stats; + for (count = 0; count < fixed_param->num_peers; count++) { + num_rates += temp_peer_stats->num_rates; + temp_peer_stats++; + } + + peer_stats_size = sizeof(tSirWifiPeerStat); + peer_info_size = sizeof(tSirWifiPeerInfo); + rate_stats_size = sizeof(tSirWifiRateStat); + link_stats_results_size = sizeof(*link_stats_results) + peer_stats_size + + (fixed_param->num_peers * peer_info_size) + + (num_rates * rate_stats_size); + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (NULL == link_stats_results ) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Peer stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u num_peers %u peer_event_number %u more_data %u", + fixed_param->request_id, fixed_param->num_peers, + fixed_param->peer_event_number, fixed_param->more_data); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_ALL_PEER; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = 0; + link_stats_results->num_peers = fixed_param->num_peers; + link_stats_results->peer_event_number = fixed_param->peer_event_number; + link_stats_results->moreResultToFollow = fixed_param->more_data; + + vos_mem_copy(link_stats_results->results, + &fixed_param->num_peers, peer_stats_size); + + results = (u_int8_t *)link_stats_results->results; + t_peer_stats = (u_int8_t *)peer_stats; + t_rate_stats = (u_int8_t *)rate_stats; + next_res_offset = peer_stats_size; + next_peer_offset = WMI_TLV_HDR_SIZE; + next_rate_offset = WMI_TLV_HDR_SIZE; + for (count = 0; count < fixed_param->num_peers; count++) { + WMA_LOGD("Peer Info:"); + WMA_LOGD("peer_type %u capabilities %u num_rates %u", + peer_stats->peer_type, peer_stats->capabilities, + peer_stats->num_rates); + + vos_mem_copy(results + next_res_offset, + t_peer_stats + next_peer_offset, + peer_info_size); + next_res_offset += peer_info_size; + + /* Copy rate stats associated with this peer */ + for (count = 0; count < peer_stats->num_rates; count++) { + WMA_LOGD("Rate Stats Info:"); + WMA_LOGD("rate %u bitrate %u tx_mpdu %u rx_mpdu %u " + "mpdu_lost %u retries %u retries_short %u " + "retries_long %u", rate_stats->rate, + rate_stats->bitrate, rate_stats->tx_mpdu, + rate_stats->rx_mpdu, rate_stats->mpdu_lost, + rate_stats->retries, rate_stats->retries_short, + rate_stats->retries_long); + rate_stats++; + + vos_mem_copy(results + next_res_offset, + t_rate_stats + next_rate_offset, + rate_stats_size); + next_res_offset += rate_stats_size; + next_rate_offset += sizeof(*rate_stats); + } + next_peer_offset += sizeof(*peer_stats); + peer_stats++; + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Peer Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +static int wma_unified_link_radio_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_radio_link_stats_event_fixed_param *fixed_param; + wmi_radio_link_stats *radio_stats; + wmi_channel_stats *channel_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_radio_stats, *t_channel_stats; + u_int32_t next_res_offset, next_chan_offset, count; + size_t radio_stats_size, chan_stats_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Radio Stats event to HDD", __func__); + param_tlvs = (WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + + /* + * cmd_param_info contains + * wmi_radio_link_stats_event_fixed_param fixed_param; + * size of(struct wmi_radio_link_stats); + * num_channels * size of(struct wmi_channel_stats) + */ + fixed_param = param_tlvs->fixed_param; + radio_stats = param_tlvs->radio_stats; + channel_stats = param_tlvs->channel_stats; + + if (!fixed_param || !radio_stats || !channel_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Radio Stats", __func__); + return -EINVAL; + } + + radio_stats_size = sizeof(tSirWifiRadioStat); + chan_stats_size = sizeof(tSirWifiChannelStats); + link_stats_results_size = sizeof(*link_stats_results) + + radio_stats_size + + (radio_stats->num_channels * chan_stats_size); + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (NULL == link_stats_results ) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Radio stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u num_radio %u more_radio_events %u", + fixed_param->request_id, fixed_param->num_radio, + fixed_param->more_radio_events); + + WMA_LOGD("Radio Info"); + WMA_LOGD("radio_id %u on_time %u tx_time %u rx_time %u on_time_scan %u " + "on_time_nbd %u on_time_gscan %u on_time_roam_scan %u " + "on_time_pno_scan %u on_time_hs20 %u num_channels %u", + radio_stats->radio_id, radio_stats->on_time, + radio_stats->tx_time, radio_stats->rx_time, + radio_stats->on_time_scan, radio_stats->on_time_nbd, + radio_stats->on_time_gscan, + radio_stats->on_time_roam_scan, + radio_stats->on_time_pno_scan, + radio_stats->on_time_hs20, + radio_stats->num_channels); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_RADIO; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = 0; + link_stats_results->num_radio = fixed_param->num_radio; + link_stats_results->peer_event_number = 0; + link_stats_results->moreResultToFollow = fixed_param->more_radio_events; + + results = (u_int8_t *)link_stats_results->results; + t_radio_stats = (u_int8_t *)radio_stats; + t_channel_stats = (u_int8_t *)channel_stats; + + vos_mem_copy(results, t_radio_stats + WMI_TLV_HDR_SIZE, + radio_stats_size); + + next_res_offset = radio_stats_size; + next_chan_offset = WMI_TLV_HDR_SIZE; + WMA_LOGD("Channel Stats Info"); + for (count = 0; count < radio_stats->num_channels; count++) { + WMA_LOGD("channel_width %u center_freq %u center_freq0 %u " + "center_freq1 %u radio_awake_time %u cca_busy_time %u", + channel_stats->channel_width, channel_stats->center_freq, + channel_stats->center_freq0, channel_stats->center_freq1, + channel_stats->radio_awake_time, + channel_stats->cca_busy_time); + channel_stats++; + + vos_mem_copy(results + next_res_offset, + t_channel_stats + next_chan_offset, + chan_stats_size); + next_res_offset += chan_stats_size; + next_chan_offset += sizeof(*channel_stats); + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Radio Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +u_int8_t *wma_add_p2p_ie(u_int8_t *frm) +{ + u_int8_t wfa_oui[3] = WMA_P2P_WFA_OUI; + struct p2p_ie *p2p_ie=(struct p2p_ie *) frm; + + p2p_ie->p2p_id = WMA_P2P_IE_ID; + p2p_ie->p2p_oui[0] = wfa_oui[0]; + p2p_ie->p2p_oui[1] = wfa_oui[1]; + p2p_ie->p2p_oui[2] = wfa_oui[2]; + p2p_ie->p2p_oui_type = WMA_P2P_WFA_VER; + p2p_ie->p2p_len = 4; + return (frm + sizeof(struct p2p_ie)); +} + +static void wma_update_beacon_noa_ie( + struct beacon_info *bcn, + u_int16_t new_noa_sub_ie_len) +{ + struct p2p_ie *p2p_ie; + u_int8_t *buf; + + /* if there is nothing to add, just return */ + if (new_noa_sub_ie_len == 0) { + if (bcn->noa_sub_ie_len && bcn->noa_ie) { + WMA_LOGD("%s: NoA is present in previous beacon, " + "but not present in swba event, " + "So Reset the NoA", + __func__); + /* TODO: Assuming p2p noa ie is last ie in the beacon */ + vos_mem_zero(bcn->noa_ie, (bcn->noa_sub_ie_len + + sizeof(struct p2p_ie)) ); + bcn->len -= (bcn->noa_sub_ie_len + + sizeof(struct p2p_ie)); + bcn->noa_ie = NULL; + bcn->noa_sub_ie_len = 0; + } + WMA_LOGD("%s: No need to update NoA", __func__); + return; + } + + if (bcn->noa_sub_ie_len && bcn->noa_ie) { + /* NoA present in previous beacon, update it */ + WMA_LOGD("%s: NoA present in previous beacon, " + "update the NoA IE, bcn->len %u" + "bcn->noa_sub_ie_len %u", + __func__, bcn->len, bcn->noa_sub_ie_len); + bcn->len -= (bcn->noa_sub_ie_len + sizeof(struct p2p_ie)) ; + vos_mem_zero(bcn->noa_ie, + (bcn->noa_sub_ie_len + sizeof(struct p2p_ie))); + } else { /* NoA is not present in previous beacon */ + WMA_LOGD("%s: NoA not present in previous beacon, add it" + "bcn->len %u", __func__, bcn->len); + buf = adf_nbuf_data(bcn->buf); + bcn->noa_ie = buf + bcn->len; + } + + bcn->noa_sub_ie_len = new_noa_sub_ie_len; + wma_add_p2p_ie(bcn->noa_ie); + p2p_ie = (struct p2p_ie *) bcn->noa_ie; + p2p_ie->p2p_len += new_noa_sub_ie_len; + vos_mem_copy((bcn->noa_ie + sizeof(struct p2p_ie)), bcn->noa_sub_ie, + new_noa_sub_ie_len); + + bcn->len += (new_noa_sub_ie_len + sizeof(struct p2p_ie)); + WMA_LOGI("%s: Updated beacon length with NoA Ie is %u", + __func__, bcn->len); +} + +static void wma_p2p_create_sub_ie_noa( + u_int8_t *buf, + struct p2p_sub_element_noa *noa, + u_int16_t *new_noa_sub_ie_len) +{ + u_int8_t tmp_octet = 0; + int i; + u_int8_t *buf_start = buf; + + *buf++ = WMA_P2P_SUB_ELEMENT_NOA; /* sub-element id */ + ASSERT(noa->num_descriptors <= WMA_MAX_NOA_DESCRIPTORS); + + /* + * Length = (2 octets for Index and CTWin/Opp PS) and + * (13 octets for each NOA Descriptors) + */ + P2PIE_PUT_LE16(buf, WMA_NOA_IE_SIZE(noa->num_descriptors)); + buf += 2; + + *buf++ = noa->index; /* Instance Index */ + + tmp_octet = noa->ctwindow & WMA_P2P_NOA_IE_CTWIN_MASK; + if (noa->oppPS) { + tmp_octet |= WMA_P2P_NOA_IE_OPP_PS_SET; + } + *buf++ = tmp_octet; /* Opp Ps and CTWin capabilities */ + + for (i = 0; i < noa->num_descriptors; i++) { + ASSERT(noa->noa_descriptors[i].type_count != 0); + + *buf++ = noa->noa_descriptors[i].type_count; + + P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].duration); + buf += 4; + P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].interval); + buf += 4; + P2PIE_PUT_LE32(buf, noa->noa_descriptors[i].start_time); + buf += 4; + } + *new_noa_sub_ie_len = (buf - buf_start); +} + +static void wma_update_noa(struct beacon_info *beacon, + struct p2p_sub_element_noa *noa_ie) +{ + u_int16_t new_noa_sub_ie_len; + + /* Call this function by holding the spinlock on beacon->lock */ + + if (noa_ie) { + if ((noa_ie->ctwindow == 0) && (noa_ie->oppPS == 0) && + (noa_ie->num_descriptors == 0)) { + /* NoA is not present */ + WMA_LOGD("%s: NoA is not present", __func__); + new_noa_sub_ie_len = 0; + } + else { + /* Create the binary blob containing NOA sub-IE */ + WMA_LOGD("%s: Create NOA sub ie", __func__); + wma_p2p_create_sub_ie_noa(&beacon->noa_sub_ie[0], + noa_ie, &new_noa_sub_ie_len); + } + } + else { + WMA_LOGD("%s: No need to add NOA", __func__); + new_noa_sub_ie_len = 0; /* no NOA IE sub-attributes */ + } + + wma_update_beacon_noa_ie(beacon, new_noa_sub_ie_len); +} + +static void wma_update_probe_resp_noa(tp_wma_handle wma_handle, + struct p2p_sub_element_noa *noa_ie) +{ + tSirP2PNoaAttr *noa_attr = (tSirP2PNoaAttr *) vos_mem_malloc(sizeof(tSirP2PNoaAttr)); + WMA_LOGD("Received update NoA event"); + if (!noa_attr) { + WMA_LOGE("Failed to allocate memory for tSirP2PNoaAttr"); + return; + } + + vos_mem_zero(noa_attr, sizeof(tSirP2PNoaAttr)); + + noa_attr->index = noa_ie->index; + noa_attr->oppPsFlag = noa_ie->oppPS; + noa_attr->ctWin = noa_ie->ctwindow; + if (!noa_ie->num_descriptors) { + WMA_LOGD("Zero NoA descriptors"); + } + else { + WMA_LOGD("%d NoA descriptors", noa_ie->num_descriptors); + noa_attr->uNoa1IntervalCnt = + noa_ie->noa_descriptors[0].type_count; + noa_attr->uNoa1Duration = + noa_ie->noa_descriptors[0].duration; + noa_attr->uNoa1Interval = + noa_ie->noa_descriptors[0].interval; + noa_attr->uNoa1StartTime = + noa_ie->noa_descriptors[0].start_time; + if (noa_ie->num_descriptors > 1) { + noa_attr->uNoa2IntervalCnt = + noa_ie->noa_descriptors[1].type_count; + noa_attr->uNoa2Duration = + noa_ie->noa_descriptors[1].duration; + noa_attr->uNoa2Interval = + noa_ie->noa_descriptors[1].interval; + noa_attr->uNoa2StartTime = + noa_ie->noa_descriptors[1].start_time; + } + } + WMA_LOGI("Sending SIR_HAL_P2P_NOA_ATTR_IND to LIM"); + wma_send_msg(wma_handle, SIR_HAL_P2P_NOA_ATTR_IND, (void *)noa_attr , + 0); +} + +static void wma_send_bcn_buf_ll(tp_wma_handle wma, + ol_txrx_pdev_handle pdev, + u_int8_t vdev_id, + WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf) +{ + wmi_bcn_send_from_host_cmd_fixed_param *cmd; + struct ieee80211_frame *wh; + struct beacon_info *bcn; + wmi_tim_info *tim_info = param_buf->tim_info; + u_int8_t *bcn_payload; + wmi_buf_t wmi_buf; + a_status_t ret; + struct beacon_tim_ie *tim_ie; + wmi_p2p_noa_info *p2p_noa_info = param_buf->p2p_noa_info; + struct p2p_sub_element_noa noa_ie; + u_int8_t i; + int status; + + bcn = wma->interfaces[vdev_id].beacon; + if (!bcn->buf) { + WMA_LOGE("%s: Invalid beacon buffer", __func__); + return; + } + + wmi_buf = wmi_buf_alloc(wma->wmi_handle, sizeof(*cmd)); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return; + } + + adf_os_spin_lock_bh(&bcn->lock); + + bcn_payload = adf_nbuf_data(bcn->buf); + + tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]); + + if(tim_info->tim_changed) { + if(tim_info->tim_num_ps_pending) + vos_mem_copy(&tim_ie->tim_bitmap, tim_info->tim_bitmap, + WMA_TIM_SUPPORTED_PVB_LENGTH); + else + vos_mem_zero(&tim_ie->tim_bitmap, + WMA_TIM_SUPPORTED_PVB_LENGTH); + /* + * Currently we support fixed number of + * peers as limited by HAL_NUM_STA. + * tim offset is always 0 + */ + tim_ie->tim_bitctl = 0; + } + + /* Update DTIM Count */ + if (tim_ie->dtim_count == 0) + tim_ie->dtim_count = tim_ie->dtim_period - 1; + else + tim_ie->dtim_count--; + + /* + * DTIM count needs to be backedup so that + * when umac updates the beacon template + * current dtim count can be updated properly + */ + bcn->dtim_count = tim_ie->dtim_count; + + /* update state for buffered multicast frames on DTIM */ + if (tim_info->tim_mcast && (tim_ie->dtim_count == 0 || + tim_ie->dtim_period == 1)) + tim_ie->tim_bitctl |= 1; + else + tim_ie->tim_bitctl &= ~1; + + /* To avoid sw generated frame sequence the same as H/W generated frame, + * the value lower than min_sw_seq is reserved for HW generated frame */ + if ((bcn->seq_no & IEEE80211_SEQ_MASK) < MIN_SW_SEQ) + bcn->seq_no = MIN_SW_SEQ; + + wh = (struct ieee80211_frame *) bcn_payload; + *(u_int16_t *)&wh->i_seq[0] = htole16(bcn->seq_no + << IEEE80211_SEQ_SEQ_SHIFT); + bcn->seq_no++; + + if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { + vos_mem_zero(&noa_ie, sizeof(noa_ie)); + + noa_ie.index = (u_int8_t)WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); + noa_ie.oppPS = (u_int8_t)WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); + noa_ie.ctwindow = (u_int8_t)WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); + noa_ie.num_descriptors = (u_int8_t)WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET( + p2p_noa_info); + WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, " + "num_descriptors = %u", __func__, noa_ie.index, + noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors); + for(i = 0; i < noa_ie.num_descriptors; i++) { + noa_ie.noa_descriptors[i].type_count = + (u_int8_t)p2p_noa_info->noa_descriptors[i].type_count; + noa_ie.noa_descriptors[i].duration = + p2p_noa_info->noa_descriptors[i].duration; + noa_ie.noa_descriptors[i].interval = + p2p_noa_info->noa_descriptors[i].interval; + noa_ie.noa_descriptors[i].start_time = + p2p_noa_info->noa_descriptors[i].start_time; + WMA_LOGI("%s: NoA descriptor[%d] type_count %u, " + "duration %u, interval %u, start_time = %u", + __func__, i, + noa_ie.noa_descriptors[i].type_count, + noa_ie.noa_descriptors[i].duration, + noa_ie.noa_descriptors[i].interval, + noa_ie.noa_descriptors[i].start_time); + } + wma_update_noa(bcn, &noa_ie); + + /* Send a msg to LIM to update the NoA IE in probe response + * frames transmitted by the host */ + wma_update_probe_resp_noa(wma, &noa_ie); + } + + if (bcn->dma_mapped) { + adf_nbuf_unmap_single(pdev->osdev, bcn->buf, + ADF_OS_DMA_TO_DEVICE); + bcn->dma_mapped = 0; + } + ret = adf_nbuf_map_single(pdev->osdev, bcn->buf, + ADF_OS_DMA_TO_DEVICE); + if (ret != A_STATUS_OK) { + adf_nbuf_free(wmi_buf); + WMA_LOGE("%s: failed map beacon buf to DMA region", + __func__); + adf_os_spin_unlock_bh(&bcn->lock); + return; + } + + bcn->dma_mapped = 1; + cmd = (wmi_bcn_send_from_host_cmd_fixed_param *) wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_bcn_send_from_host_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->data_len = bcn->len; + cmd->frame_ctrl = *((A_UINT16 *)wh->i_fc); + cmd->frag_ptr = adf_nbuf_get_frag_paddr_lo(bcn->buf, 0); + + /* Notify Firmware of DTM and mcast/bcast traffic */ + if (tim_ie->dtim_count == 0) { + cmd->dtim_flag |= WMI_BCN_SEND_DTIM_ZERO; + /* deliver mcast/bcast traffic in next DTIM beacon */ + if (tim_ie->tim_bitctl & 0x01) + cmd->dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET; + } + + status = wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, sizeof(*cmd), + WMI_PDEV_SEND_BCN_CMDID); + + if (status != EOK) { + WMA_LOGE("Failed to send WMI_PDEV_SEND_BCN_CMDID command"); + wmi_buf_free(wmi_buf); + } + adf_os_spin_unlock_bh(&bcn->lock); +} + +static int wma_beacon_swba_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf; + wmi_host_swba_event_fixed_param *swba_event; + u_int32_t vdev_map; + ol_txrx_pdev_handle pdev; + u_int8_t vdev_id = 0; + + param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("Invalid swba event buffer"); + return -EINVAL; + } + swba_event = param_buf->fixed_param; + vdev_map = swba_event->vdev_map; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (!pdev) { + WMA_LOGE("%s: pdev is NULL", __func__); + return -EINVAL; + } + + for ( ; vdev_map; vdev_id++, vdev_map >>= 1) { + if (!(vdev_map & 0x1)) + continue; + if (!wdi_out_cfg_is_high_latency(pdev->ctrl_pdev)) + wma_send_bcn_buf_ll(wma, pdev, vdev_id, param_buf); + break; + } + return 0; +} + +static int wma_csa_offload_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_CSA_HANDLING_EVENTID_param_tlvs *param_buf; + wmi_csa_event_fixed_param *csa_event; + u_int8_t bssid[IEEE80211_ADDR_LEN]; + u_int8_t vdev_id = 0; + u_int8_t cur_chan = 0; + struct ieee80211_channelswitch_ie *csa_ie; + tpCSAOffloadParams csa_offload_event; + struct ieee80211_extendedchannelswitch_ie *xcsa_ie; + struct ieee80211_ie_wide_bw_switch *wb_ie; + struct wma_txrx_node *intr = wma->interfaces; + + param_buf = (WMI_CSA_HANDLING_EVENTID_param_tlvs *) event; + + WMA_LOGD("%s: Enter", __func__); + if (!param_buf) { + WMA_LOGE("Invalid csa event buffer"); + return -EINVAL; + } + csa_event = param_buf->fixed_param; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&csa_event->i_addr2, &bssid[0]); + + if (wma_find_vdev_by_bssid(wma, bssid, &vdev_id) == NULL) { + WMA_LOGE("Invalid bssid received %s:%d", __func__, __LINE__); + return -EINVAL; + } + + csa_offload_event = vos_mem_malloc(sizeof(*csa_offload_event)); + if (!csa_offload_event) { + WMA_LOGE("VOS MEM Alloc Failed for csa_offload_event"); + return -EINVAL; + } + + vos_mem_zero(csa_offload_event, sizeof(*csa_offload_event)); + vos_mem_copy(csa_offload_event->bssId, &bssid, ETH_ALEN); + + if (csa_event->ies_present_flag & WMI_CSA_IE_PRESENT) { + csa_ie = (struct ieee80211_channelswitch_ie *)(&csa_event->csa_ie[0]); + csa_offload_event->channel = csa_ie->newchannel; + csa_offload_event->switchmode = csa_ie->switchmode; + } else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) { + xcsa_ie = (struct ieee80211_extendedchannelswitch_ie*)(&csa_event->xcsa_ie[0]); + csa_offload_event->channel = xcsa_ie->newchannel; + csa_offload_event->switchmode = xcsa_ie->switchmode; + } else { + WMA_LOGE("CSA Event error: No CSA IE present"); + vos_mem_free(csa_offload_event); + return -EINVAL; + } + + if (csa_event->ies_present_flag & WMI_WBW_IE_PRESENT) { + wb_ie = (struct ieee80211_ie_wide_bw_switch*)(&csa_event->wb_ie[0]); + csa_offload_event->new_ch_width = wb_ie->new_ch_width; + csa_offload_event->new_ch_freq_seg1 = wb_ie->new_ch_freq_seg1; + csa_offload_event->new_ch_freq_seg2 = wb_ie->new_ch_freq_seg2; + } + + csa_offload_event->ies_present_flag = csa_event->ies_present_flag; + + WMA_LOGD("CSA: New Channel = %d BSSID:%pM", + csa_offload_event->channel, + csa_offload_event->bssId); + + cur_chan = vos_freq_to_chan(intr[vdev_id].mhz); + /* + * basic sanity check: requested channel should not be 0 + * and equal to home channel + */ + if( (0 == csa_offload_event->channel) || + (cur_chan == csa_offload_event->channel) ) { + WMA_LOGE("CSA Event with channel %d. Ignore !!", + csa_offload_event->channel); + vos_mem_free(csa_offload_event); + return -EINVAL; + } + wma->interfaces[vdev_id].is_channel_switch = VOS_TRUE; + wma_send_msg(wma, WDA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0); + return 0; +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +static int wma_gtk_offload_status_event(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *status; + WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *param_buf; + tpSirGtkOffloadGetInfoRspParams resp; + vos_msg_t vos_msg; + u_int8_t *bssid; + + WMA_LOGD("%s Enter", __func__); + + param_buf = (WMI_GTK_OFFLOAD_STATUS_EVENTID_param_tlvs *)event; + if (!param_buf) { + WMA_LOGE("param_buf is NULL"); + return -EINVAL; + } + + status = (WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param *)param_buf->fixed_param; + + if (len < sizeof(WMI_GTK_OFFLOAD_STATUS_EVENT_fixed_param)) { + WMA_LOGE("Invalid length for GTK status"); + return -EINVAL; + } + bssid = wma_find_bssid_by_vdev_id(wma, status->vdev_id); + if (!bssid) { + WMA_LOGE("invalid bssid for vdev id %d", status->vdev_id); + return -ENOENT; + } + + resp = vos_mem_malloc(sizeof(*resp)); + if (!resp) { + WMA_LOGE("%s: Failed to alloc response", __func__); + return -ENOMEM; + } + vos_mem_zero(resp, sizeof(*resp)); + resp->mesgType = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP; + resp->mesgLen = sizeof(*resp); + resp->ulStatus = VOS_STATUS_SUCCESS; + resp->ulTotalRekeyCount = status->refresh_cnt; + /* TODO: Is the total rekey count and GTK rekey count same? */ + resp->ulGTKRekeyCount = status->refresh_cnt; + + vos_mem_copy(&resp->ullKeyReplayCounter, &status->replay_counter, + GTK_REPLAY_COUNTER_BYTES); + + vos_mem_copy(resp->bssId, bssid, ETH_ALEN); + +#ifdef IGTK_OFFLOAD + /* TODO: Is the refresh count same for GTK and IGTK? */ + resp->ulIGTKRekeyCount = status->refresh_cnt; +#endif + + vos_msg.type = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP; + vos_msg.bodyptr = (void *)resp; + vos_msg.bodyval = 0; + + if (vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vos_msg) + != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to post GTK response to SME"); + vos_mem_free(resp); + return -EINVAL; + } + + WMA_LOGD("GTK: got target status with replay counter " + "%02x%02x%02x%02x%02x%02x%02x%02x. vdev %d " + "Refresh GTK %d times exchanges since last set operation", + status->replay_counter[0], + status->replay_counter[1], + status->replay_counter[2], + status->replay_counter[3], + status->replay_counter[4], + status->replay_counter[5], + status->replay_counter[6], + status->replay_counter[7], + status->vdev_id, status->refresh_cnt); + + WMA_LOGD("%s Exit", __func__); + + return 0; +} +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT +static int wma_oem_capability_event_callback(void *handle, + u_int8_t *datap, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_OEM_CAPABILITY_EVENTID_param_tlvs *param_buf; + u_int8_t *data; + u_int32_t datalen; + u_int32_t *msg_subtype; + tStartOemDataRsp *pStartOemDataRsp; + + param_buf = (WMI_OEM_CAPABILITY_EVENTID_param_tlvs *)datap; + if (!param_buf) { + WMA_LOGE("%s: Received NULL buf ptr from FW", __func__); + return -ENOMEM; + } + + data = param_buf->data; + datalen = param_buf->num_data; + + if (!data) { + WMA_LOGE("%s: Received NULL data from FW", __func__); + return -EINVAL; + } + + /* wma puts 4 bytes prefix for msg subtype, so length + * of data received from target should be 4 bytes less + * then max allowed + */ + if (datalen > (OEM_DATA_RSP_SIZE - 4)) { + WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)", + __func__, datalen, (OEM_DATA_RSP_SIZE - 4)); + return -EINVAL; + } + + pStartOemDataRsp = vos_mem_malloc(sizeof(*pStartOemDataRsp)); + if (!pStartOemDataRsp) { + WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__); + return -ENOMEM; + } + + vos_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp)); + msg_subtype = (u_int32_t *)(&pStartOemDataRsp->oemDataRsp[0]); + *msg_subtype = WMI_OEM_CAPABILITY_RSP; + vos_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen); + + WMA_LOGI("%s: Sending WDA_START_OEM_DATA_RSP, data len (%d)", + __func__, datalen); + + wma_send_msg(wma, WDA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0); + return 0; +} + +static int wma_oem_measurement_report_event_callback(void *handle, + u_int8_t *datap, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_OEM_MEASUREMENT_REPORT_EVENTID_param_tlvs *param_buf; + u_int8_t *data; + u_int32_t datalen; + u_int32_t *msg_subtype; + tStartOemDataRsp *pStartOemDataRsp; + + param_buf = (WMI_OEM_MEASUREMENT_REPORT_EVENTID_param_tlvs *)datap; + if (!param_buf) { + WMA_LOGE("%s: Received NULL buf ptr from FW", __func__); + return -ENOMEM; + } + + data = param_buf->data; + datalen = param_buf->num_data; + + if (!data) { + WMA_LOGE("%s: Received NULL data from FW", __func__); + return -EINVAL; + } + + /* wma puts 4 bytes prefix for msg subtype, so length + * of data received from target should be 4 bytes less + * then max allowed + */ + if (datalen > (OEM_DATA_RSP_SIZE - 4)) { + WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)", + __func__, datalen, (OEM_DATA_RSP_SIZE - 4)); + return -EINVAL; + } + + pStartOemDataRsp = vos_mem_malloc(sizeof(*pStartOemDataRsp)); + if (!pStartOemDataRsp) { + WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__); + return -ENOMEM; + } + + vos_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp)); + msg_subtype = (u_int32_t *)(&pStartOemDataRsp->oemDataRsp[0]); + *msg_subtype = WMI_OEM_MEASUREMENT_RSP; + vos_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen); + + WMA_LOGI("%s: Sending WDA_START_OEM_DATA_RSP, data len (%d)", + __func__, datalen); + + wma_send_msg(wma, WDA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0); + return 0; +} + +static int wma_oem_error_report_event_callback(void *handle, + u_int8_t *datap, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_OEM_ERROR_REPORT_EVENTID_param_tlvs *param_buf; + u_int8_t *data; + u_int32_t datalen; + u_int32_t *msg_subtype; + tStartOemDataRsp *pStartOemDataRsp; + + param_buf = (WMI_OEM_ERROR_REPORT_EVENTID_param_tlvs *)datap; + if (!param_buf) { + WMA_LOGE("%s: Received NULL buf ptr from FW", __func__); + return -ENOMEM; + } + + data = param_buf->data; + datalen = param_buf->num_data; + + if (!data) { + WMA_LOGE("%s: Received NULL data from FW", __func__); + return -EINVAL; + } + + /* wma puts 4 bytes prefix for msg subtype, so length + * of data received from target should be 4 bytes less + * then max allowed + */ + if (datalen > (OEM_DATA_RSP_SIZE - 4)) { + WMA_LOGE("%s: Received data len (%d) exceeds max value (%d)", + __func__, datalen, (OEM_DATA_RSP_SIZE - 4)); + return -EINVAL; + } + + pStartOemDataRsp = vos_mem_malloc(sizeof(*pStartOemDataRsp)); + if (!pStartOemDataRsp) { + WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__); + return -ENOMEM; + } + + vos_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp)); + msg_subtype = (u_int32_t *)(&pStartOemDataRsp->oemDataRsp[0]); + *msg_subtype = WMI_OEM_ERROR_REPORT_RSP; + vos_mem_copy(&pStartOemDataRsp->oemDataRsp[4], data, datalen); + + WMA_LOGI("%s: Sending WDA_START_OEM_DATA_RSP, data len (%d)", + __func__, datalen); + + wma_send_msg(wma, WDA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0); + return 0; +} +#endif /* FEATURE_OEM_DATA_SUPPORT */ + +static int wma_p2p_noa_event_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_P2P_NOA_EVENTID_param_tlvs *param_buf; + wmi_p2p_noa_event_fixed_param *p2p_noa_event; + u_int8_t vdev_id, i; + wmi_p2p_noa_info *p2p_noa_info; + struct p2p_sub_element_noa noa_ie; + u_int8_t *buf_ptr; + u_int32_t descriptors; + + param_buf = (WMI_P2P_NOA_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("Invalid P2P NoA event buffer"); + return -EINVAL; + } + + p2p_noa_event = param_buf->fixed_param; + buf_ptr = (u_int8_t *) p2p_noa_event; + buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param); + p2p_noa_info = (wmi_p2p_noa_info *) (buf_ptr); + vdev_id = p2p_noa_event->vdev_id; + + if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) { + + vos_mem_zero(&noa_ie, sizeof(noa_ie)); + noa_ie.index = (u_int8_t)WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info); + noa_ie.oppPS = (u_int8_t)WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info); + noa_ie.ctwindow = (u_int8_t)WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info); + descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info); + noa_ie.num_descriptors = (u_int8_t)descriptors; + + WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, " + "num_descriptors = %u", __func__, noa_ie.index, + noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors); + for(i = 0; i < noa_ie.num_descriptors; i++) { + noa_ie.noa_descriptors[i].type_count = + (u_int8_t)p2p_noa_info->noa_descriptors[i].type_count; + noa_ie.noa_descriptors[i].duration = + p2p_noa_info->noa_descriptors[i].duration; + noa_ie.noa_descriptors[i].interval = + p2p_noa_info->noa_descriptors[i].interval; + noa_ie.noa_descriptors[i].start_time = + p2p_noa_info->noa_descriptors[i].start_time; + WMA_LOGI("%s: NoA descriptor[%d] type_count %u, " + "duration %u, interval %u, start_time = %u", + __func__, i, + noa_ie.noa_descriptors[i].type_count, + noa_ie.noa_descriptors[i].duration, + noa_ie.noa_descriptors[i].interval, + noa_ie.noa_descriptors[i].start_time); + } + + /* Send a msg to LIM to update the NoA IE in probe response + * frames transmitted by the host */ + wma_update_probe_resp_noa(wma, &noa_ie); + } + + return 0; +} + +#ifdef FEATURE_WLAN_TDLS +static int wma_tdls_event_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf = NULL; + wmi_tdls_peer_event_fixed_param *peer_event = NULL; + tSirTdlsEventNotify *tdls_event; + + if (!event) { + WMA_LOGE("%s: event param null", __func__); + return -1; + } + + param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("%s: received null buf from target", __func__); + return -1; + } + + peer_event = param_buf->fixed_param; + if (!peer_event) { + WMA_LOGE("%s: received null event data from target", __func__); + return -1; + } + + tdls_event = (tSirTdlsEventNotify *) + vos_mem_malloc(sizeof(*tdls_event)); + if (!tdls_event) { + WMA_LOGE("%s: failed to allocate memory for tdls_event", __func__); + return -1; + } + + tdls_event->sessionId = peer_event->vdev_id; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_event->peer_macaddr, tdls_event->peerMac); + + switch(peer_event->peer_status) { + case WMI_TDLS_SHOULD_DISCOVER: + tdls_event->messageType = WDA_TDLS_SHOULD_DISCOVER; + break; + case WMI_TDLS_SHOULD_TEARDOWN: + tdls_event->messageType = WDA_TDLS_SHOULD_TEARDOWN; + break; + case WMI_TDLS_PEER_DISCONNECTED: + tdls_event->messageType = WDA_TDLS_PEER_DISCONNECTED; + break; + default: + WMA_LOGE("%s: Discarding unknown tdls event(%d) from target", + __func__, peer_event->peer_status); + return -1; + } + + switch (peer_event->peer_reason) { + case WMI_TDLS_TEARDOWN_REASON_TX: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_TX; + break; + case WMI_TDLS_TEARDOWN_REASON_RSSI: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_RSSI; + break; + case WMI_TDLS_TEARDOWN_REASON_SCAN: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_SCAN; + break; + case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE: + tdls_event->peer_reason = eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE; + break; + case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT; + break; + case WMI_TDLS_TEARDOWN_REASON_BAD_PTR: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_BAD_PTR; + break; + case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE: + tdls_event->peer_reason = eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE; + break; + default: + WMA_LOGE("%s: unknown reason(%d) in tdls event(%d) from target", + __func__, peer_event->peer_reason, peer_event->peer_status); + return -1; + } + + WMA_LOGD("%s: sending msg to umac, messageType: 0x%x, " + "for peer: %pM, reason: %d, smesessionId: %d", + __func__, tdls_event->messageType, tdls_event->peerMac, + tdls_event->peer_reason, tdls_event->sessionId); + + wma_send_msg(wma, tdls_event->messageType, (void *)tdls_event, 0); + return 0; +} +#endif /* FEATURE_WLAN_TDLS */ + +/* + * WMI Handler for WMI_PHYERR_EVENTID event from firmware. + * This handler is currently handling only DFS phy errors. + * This handler will be invoked only when the DFS phyerror + * filtering offload is disabled. + * Return- 1:Success, 0:Failure + */ +static int wma_unified_phyerr_rx_event_handler(void * handle, + u_int8_t *data, u_int32_t datalen) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_PHYERR_EVENTID_param_tlvs *param_tlvs; + wmi_comb_phyerr_rx_hdr *pe_hdr; + u_int8_t *bufp; + wmi_single_phyerr_rx_event *ev; + struct ieee80211com *ic = wma->dfs_ic; + adf_os_size_t n; + A_UINT64 tsf64 = 0; + int phy_err_code = 0; + int error = 0; + param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *)data; + + if (!param_tlvs) + { + WMA_LOGE("%s: Received NULL data from FW", __func__); + return 0; + } + + pe_hdr = param_tlvs->hdr; + if (pe_hdr == NULL) + { + WMA_LOGE("%s: Received Data PE Header is NULL", __func__); + return 0; + } + + /* Ensure it's at least the size of the header */ + if (datalen < sizeof(*pe_hdr)) + { + WMA_LOGE("%s: Expected minimum size %zu, received %d", + __func__, sizeof(*pe_hdr), datalen); + return 0; + } + if (pe_hdr->buf_len > DFS_MAX_BUF_LENGHT) + { + WMA_LOGE("%s: Received Invalid Phyerror event buffer length = %d" + "Maximum allowed buf length = %d", + __func__, pe_hdr->buf_len, DFS_MAX_BUF_LENGHT); + + return 0; + } + + /* + * Reconstruct the 64 bit event TSF. This isn't from the MAC, it's + * at the time the event was sent to us, the TSF value will be + * in the future. + */ + tsf64 = pe_hdr->tsf_l32; + tsf64 |= (((uint64_t) pe_hdr->tsf_u32) << 32); + + /* + * Loop over the bufp, extracting out phyerrors + * wmi_unified_comb_phyerr_rx_event.bufp is a char pointer, + * which isn't correct here - what we have received here + * is an array of TLV-style PHY errors. + */ + n = 0;/* Start just after the header */ + bufp = param_tlvs->bufp; + while (n < pe_hdr->buf_len) + { + /* ensure there's at least space for the header */ + if ((pe_hdr->buf_len - n) < sizeof(ev->hdr)) + { + WMA_LOGE("%s: Not enough space.(datalen=%d, n=%zu, hdr=%zu bytes", + __func__,pe_hdr->buf_len,n,sizeof(ev->hdr)); + error = 1; + break; + } + /* + * Obtain a pointer to the beginning of the current event. + * data[0] is the beginning of the WMI payload. + */ + ev = (wmi_single_phyerr_rx_event *) &bufp[n]; + + /* + * Sanity check the buffer length of the event against + * what we currently have. + * Since buf_len is 32 bits, we check if it overflows + * a large 32 bit value. It's not 0x7fffffff because + * we increase n by (buf_len + sizeof(hdr)), which would + * in itself cause n to overflow. + * If "int" is 64 bits then this becomes a moot point. + */ + if (ev->hdr.buf_len > 0x7f000000) + { + WMA_LOGE("%s:buf_len is garbage (0x%x)",__func__, + ev->hdr.buf_len); + error = 1; + break; + } + if (n + ev->hdr.buf_len > pe_hdr->buf_len) + { + WMA_LOGE("%s: buf_len exceeds available space n=%zu," + "buf_len=%d, datalen=%d", + __func__,n,ev->hdr.buf_len,pe_hdr->buf_len); + error = 1; + break; + } + phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr); + + /* + * If the phyerror category matches, + * pass radar events to the dfs pattern matching code. + * Don't pass radar events with no buffer payload. + */ + if (phy_err_code == 0x5 || phy_err_code == 0x24) + { + if (ev->hdr.buf_len > 0) + { + /* Calling in to the DFS module to process the phyerr */ + dfs_process_phyerr(ic, &ev->bufp[0], ev->hdr.buf_len, + WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr) & 0xff, + /* Extension RSSI */ + WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr) & 0xff, + ev->hdr.tsf_timestamp, + tsf64); + } + } + + /* + * Advance the buffer pointer to the next PHY error. + * buflen is the length of this payload, so we need to + * advance past the current header _AND_ the payload. + */ + n += sizeof(*ev) + ev->hdr.buf_len; + + }/*end while()*/ + if (error) + { + return (0); + } + else + { + return (1); + } +} + +#ifdef WLAN_FEATURE_NAN +/* function : wma_nan_rsp_event_handler + * Descriptin : Function is used to handle nan response + * Args : wma_handle, event buffer and its length + * Returns : SUCCESS or FAILURE + */ +static int wma_nan_rsp_event_handler(void *handle, u_int8_t *event_buf, + u_int32_t len) +{ + WMI_NAN_EVENTID_param_tlvs *param_buf; + tSirNanEvent *nan_rsp_event; + wmi_nan_event_hdr *nan_rsp_event_hdr; + VOS_STATUS status; + vos_msg_t vos_msg; + u_int8_t *buf_ptr; + u_int32_t alloc_len; + + /* + * This is how received event_buf looks like + * + * <-------------------- event_buf -----------------------------------> + * + * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data --------> + * + * +-----------+---------+-----------------------+--------------------+ + * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data | + * +-----------+---------+-----------------------+--------------------+ + */ + + WMA_LOGD("%s: Posting NaN response event to SME", __func__); + param_buf = (WMI_NAN_EVENTID_param_tlvs *)event_buf; + if (!param_buf) { + WMA_LOGE("%s: Invalid nan response event buf", __func__); + return -EINVAL; + } + nan_rsp_event_hdr = param_buf->fixed_param; + buf_ptr = (u_int8_t *)nan_rsp_event_hdr; + alloc_len = sizeof(tSirNanEvent); + alloc_len += nan_rsp_event_hdr->data_len; + nan_rsp_event = (tSirNanEvent *) vos_mem_malloc(alloc_len); + if (NULL == nan_rsp_event) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return -ENOMEM; + } + + nan_rsp_event->event_data_len = nan_rsp_event_hdr->data_len; + vos_mem_copy(nan_rsp_event->event_data, buf_ptr + + sizeof(wmi_nan_event_hdr) + WMI_TLV_HDR_SIZE, + nan_rsp_event->event_data_len); + vos_msg.type = eWNI_SME_NAN_EVENT; + vos_msg.bodyptr = (void *)nan_rsp_event; + vos_msg.bodyval = 0; + + status = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to post NaN response event to SME", __func__); + vos_mem_free(nan_rsp_event); + return -1; + } + WMA_LOGD("%s: NaN response event Posted to SME", __func__); + return 0; +} +#endif + +/* + * WMI handler for WMI_DFS_RADAR_EVENTID + * This handler is registered for handling + * filtered DFS Phyerror. This handler is + * will be invoked only when DFS Phyerr + * filtering offload is enabled. + * Return- 1:Success, 0:Failure + */ +static int wma_unified_dfs_radar_rx_event_handler(void *handle, + u_int8_t *data, u_int32_t datalen) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + struct ieee80211com *ic; + struct ath_dfs *dfs; + struct dfs_event *event; + struct ieee80211_channel *chan; + int empty; + int do_check_chirp = 0; + int is_hw_chirp = 0; + int is_sw_chirp = 0; + int is_pri = 0; + + WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlvs; + wmi_dfs_radar_event_fixed_param *radar_event; + + ic = wma->dfs_ic; + if (NULL == ic) { + WMA_LOGE("%s: dfs_ic is NULL ", __func__); + return 0; + } + + dfs = (struct ath_dfs *)ic->ic_dfs; + chan = ic->ic_curchan; + param_tlvs = (WMI_DFS_RADAR_EVENTID_param_tlvs *) data; + + if (NULL == dfs) { + WMA_LOGE("%s: dfs is NULL ", __func__); + return 0; + } + /* + * This parameter holds the number + * of phyerror interrupts to the host + * after the phyerrors have passed through + * false detect filters in the firmware. + */ + dfs->dfs_phyerr_count++; + + if (!param_tlvs) { + WMA_LOGE("%s: Received NULL data from FW", __func__); + return 0; + } + + radar_event = param_tlvs->fixed_param; + + if (NV_CHANNEL_DFS != vos_nv_getChannelEnabledState(chan->ic_ieee)) { + WMA_LOGE("%s: Invalid DFS Phyerror event. Channel=%d is Non-DFS", + __func__, chan->ic_ieee); + return 0; + } + dfs->ath_dfs_stats.total_phy_errors++; + + if (dfs->dfs_caps.ath_chip_is_bb_tlv) { + do_check_chirp = 1; + is_pri = 1; + is_hw_chirp = radar_event->pulse_is_chirp; + + if ((u_int32_t)dfs->dfs_phyerr_freq_min > + radar_event->pulse_center_freq) { + dfs->dfs_phyerr_freq_min = + (int)radar_event->pulse_center_freq; + } + + if (dfs->dfs_phyerr_freq_max < + (int)radar_event->pulse_center_freq) { + dfs->dfs_phyerr_freq_max = + (int)radar_event->pulse_center_freq; + } + } + + /* + * Now, add the parsed, checked and filtered + * radar phyerror event radar pulse event list. + * This event will then be processed by + * dfs_radar_processevent() to see if the pattern + * of pulses in radar pulse list match any radar + * singnature in the current regulatory domain. + */ + + ATH_DFSEVENTQ_LOCK(dfs); + empty = STAILQ_EMPTY(&(dfs->dfs_eventq)); + ATH_DFSEVENTQ_UNLOCK(dfs); + if (empty) { + return 0; + } + /* + * Add the event to the list, if there's space. + */ + ATH_DFSEVENTQ_LOCK(dfs); + event = STAILQ_FIRST(&(dfs->dfs_eventq)); + if (event == NULL) { + ATH_DFSEVENTQ_UNLOCK(dfs); + WMA_LOGE("%s: No more space left for queuing DFS Phyerror events", + __func__); + return 0; + } + STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list); + ATH_DFSEVENTQ_UNLOCK(dfs); + dfs->dfs_phyerr_queued_count++; + dfs->dfs_phyerr_w53_counter++; + event->re_dur = (u_int8_t)radar_event->pulse_duration; + event->re_rssi = radar_event->rssi; + event->re_ts = radar_event->pulse_detect_ts & DFS_TSMASK; + event->re_full_ts = (((uint64_t)radar_event->upload_fullts_high) << 32) + | radar_event->upload_fullts_low; + + /* + * Handle chirp flags. + */ + if (do_check_chirp) { + event->re_flags |= DFS_EVENT_CHECKCHIRP; + if (is_hw_chirp) { + event->re_flags |= DFS_EVENT_HW_CHIRP; + } + if (is_sw_chirp) { + event->re_flags |= DFS_EVENT_SW_CHIRP; + } + } + /* + * Correctly set which channel is being reported on + */ + if (is_pri) { + event->re_chanindex = (u_int8_t)dfs->dfs_curchan_radindex; + } else { + if (dfs->dfs_extchan_radindex == -1) { + WMA_LOGI("%s phyerr on ext channel", __func__); + } + event->re_chanindex = (u_int8_t)dfs->dfs_extchan_radindex; + WMA_LOGI("%s:New extension channel event is added to queue", + __func__); + } + + ATH_DFSQ_LOCK(dfs); + + STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list); + + empty = STAILQ_EMPTY(&dfs->dfs_radarq); + + ATH_DFSQ_UNLOCK(dfs); + + if (!empty && !dfs->ath_radar_tasksched) { + dfs->ath_radar_tasksched = 1; + OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0); + } + + return 1; + +} + +/* + * Register appropriate dfs phyerror event handler + * based on phyerror filtering offload is enabled + * or disabled. + */ +static void +wma_register_dfs_event_handler(tp_wma_handle wma_handle) +{ + if (NULL == wma_handle) { + WMA_LOGE("%s:wma_handle is NULL", __func__); + return; + } + + if (VOS_FALSE == wma_handle->dfs_phyerr_filter_offload) { + /* + * Register the wma_unified_phyerr_rx_event_handler + * for filtering offload disabled case to handle + * the DFS phyerrors. + */ + WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini", + __func__); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PHYERR_EVENTID, wma_unified_phyerr_rx_event_handler); + WMA_LOGD("%s: WMI_PHYERR_EVENTID event handler registered", + __func__); + } else { + WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini", + __func__); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_DFS_RADAR_EVENTID, + wma_unified_dfs_radar_rx_event_handler); + WMA_LOGD("%s:WMI_DFS_RADAR_EVENTID event handler registered", + __func__); + } + + return; +} + +static int wma_peer_state_change_event_handler(void *handle, + u_int8_t *event_buff, + u_int32_t len) +{ + WMI_PEER_STATE_EVENTID_param_tlvs *param_buf; + wmi_peer_state_event_fixed_param *event; + ol_txrx_vdev_handle vdev; + tp_wma_handle wma_handle = (tp_wma_handle)handle; + + param_buf = (WMI_PEER_STATE_EVENTID_param_tlvs *)event_buff; + if (!param_buf) { + WMA_LOGE("%s: Received NULL buf ptr from FW", __func__); + return -ENOMEM; + } + + event = param_buf->fixed_param; + vdev = wma_find_vdev_by_id( wma_handle, event->vdev_id); + if (NULL == vdev) { + WMA_LOGP("%s: Couldn't find vdev for vdev_id: %d", + __func__, event->vdev_id); + return -EINVAL; + } + + if (vdev->opmode == wlan_op_mode_sta + && event->state == WMI_PEER_STATE_AUTHORIZED) { + /* + * set event so that WLANTL_ChangeSTAState + * can procced and unpause tx queue + */ + tl_shim_set_peer_authorized_event(wma_handle->vos_context, + event->vdev_id); + } + + return 0; +} + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* + * Register all the Link Layer Stats related event + * handler + */ +static void +wma_register_ll_stats_event_handler(tp_wma_handle wma_handle) +{ + if (NULL == wma_handle) { + WMA_LOGE("%s: wma_handle is NULL", __func__); + return; + } + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_IFACE_LINK_STATS_EVENTID, + wma_unified_link_iface_stats_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_LINK_STATS_EVENTID, + wma_unified_link_peer_stats_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_RADIO_LINK_STATS_EVENTID, + wma_unified_link_radio_stats_event_handler); + + return; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL; + wmi_roam_synch_event_fixed_param *synch_event = NULL; + u_int8_t *bcn_probersp_ptr = NULL; + u_int8_t *reassoc_rsp_ptr = NULL; + tp_wma_handle wma = (tp_wma_handle)handle; + wmi_channel *chan = NULL; + wmi_key_material *key = NULL; + int size=0; + tSirRoamOffloadSynchInd *pRoamOffloadSynchInd; + + WMA_LOGD("LFR3:%s", __func__); + if (!event) { + WMA_LOGE("%s: event param null", __func__); + return -EINVAL; + } + + param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("%s: received null buf from target", __func__); + return -EINVAL; + } + + synch_event = param_buf->fixed_param; + if (!synch_event) { + WMA_LOGE("%s: received null event data from target", __func__); + return -EINVAL; + } + + if(wma->interfaces[synch_event->vdev_id].roam_synch_in_progress == + VOS_TRUE) { + WMA_LOGE("%s: Ignoring RSI since one is already in progress", + __func__); + return -EINVAL; + } + adf_os_spin_lock_bh(&wma->roam_synch_lock); + wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = VOS_TRUE; + adf_os_spin_unlock_bh(&wma->roam_synch_lock); + len = sizeof(tSirRoamOffloadSynchInd) + + synch_event->bcn_probe_rsp_len + + synch_event->reassoc_rsp_len; + pRoamOffloadSynchInd = (tSirRoamOffloadSynchInd *)vos_mem_malloc(len); + if (!pRoamOffloadSynchInd) { + WMA_LOGE("%s: failed to allocate memory for roam_synch_event", __func__); + return -ENOMEM; + } + /* abort existing scan if any */ + if (wma->interfaces[synch_event->vdev_id].scan_info.scan_id != 0) { + tAbortScanParams abortScan; + WMA_LOGD("LFR3: Aborting Scan with scan_id=%d\n", + wma->interfaces[synch_event->vdev_id].scan_info.scan_id); + abortScan.SessionId = synch_event->vdev_id; + wma_stop_scan(wma, &abortScan); + } + pRoamOffloadSynchInd->messageType = eWNI_SME_ROAM_OFFLOAD_SYNCH_IND; + pRoamOffloadSynchInd->length = size; + pRoamOffloadSynchInd->roamedVdevId = synch_event->vdev_id; + pRoamOffloadSynchInd->authStatus = synch_event->auth_status; + pRoamOffloadSynchInd->roamReason = synch_event->roam_reason; + pRoamOffloadSynchInd->rssi = synch_event->rssi; + pRoamOffloadSynchInd->isBeacon = synch_event->is_beacon; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid, pRoamOffloadSynchInd->bssId); + pRoamOffloadSynchInd->beaconProbeRespOffset = sizeof(tSirRoamOffloadSynchInd); + bcn_probersp_ptr = (tANI_U8 *)pRoamOffloadSynchInd + + pRoamOffloadSynchInd->beaconProbeRespOffset; + pRoamOffloadSynchInd->beaconProbeRespLength = synch_event->bcn_probe_rsp_len; + vos_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame, + pRoamOffloadSynchInd->beaconProbeRespLength); + pRoamOffloadSynchInd->reassocRespOffset = sizeof(tSirRoamOffloadSynchInd) + + pRoamOffloadSynchInd->beaconProbeRespLength; + pRoamOffloadSynchInd->reassocRespLength = synch_event->reassoc_rsp_len; + reassoc_rsp_ptr = (tANI_U8 *)pRoamOffloadSynchInd + + pRoamOffloadSynchInd->reassocRespOffset; + vos_mem_copy(reassoc_rsp_ptr, + param_buf->reassoc_rsp_frame, + pRoamOffloadSynchInd->reassocRespLength); + chan = (wmi_channel *) param_buf->chan; + pRoamOffloadSynchInd->chan_freq = chan->mhz; + key = (wmi_key_material *) param_buf->key; + if (key != NULL) + { + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + key->replay_counter, + SIR_REPLAY_CTR_LEN); + vos_mem_copy(pRoamOffloadSynchInd->kck, key->kck, + SIR_KCK_KEY_LEN); + vos_mem_copy(pRoamOffloadSynchInd->kek, key->kek, + SIR_KEK_KEY_LEN); + vos_mem_copy(pRoamOffloadSynchInd->replay_ctr, key->replay_counter, + SIR_REPLAY_CTR_LEN); + } + wma_send_msg(wma, WDA_ROAM_OFFLOAD_SYNCH_IND, + (void *) pRoamOffloadSynchInd, 0); + return 0; +} +#endif +/* + * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or + * WMI_DFS_PHYERR_FILTER_DIS_CMDID command + * to firmware based on phyerr filtering + * offload status. + */ +static int +wma_unified_dfs_phyerr_filter_offload_enable(tp_wma_handle wma_handle) +{ + wmi_dfs_phyerr_filter_ena_cmd_fixed_param* enable_phyerr_offload_cmd; + wmi_dfs_phyerr_filter_dis_cmd_fixed_param* disable_phyerr_offload_cmd; + wmi_buf_t buf; + u_int16_t len; + int ret; + + if (NULL == wma_handle) { + WMA_LOGE("%s:wma_handle is NULL", __func__); + return 0; + } + + if (VOS_FALSE == wma_handle->dfs_phyerr_filter_offload) { + WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini", + __func__); + len = sizeof(*disable_phyerr_offload_cmd); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return 0; + } + disable_phyerr_offload_cmd = + (wmi_dfs_phyerr_filter_dis_cmd_fixed_param *) + wmi_buf_data(buf); + + WMITLV_SET_HDR(&disable_phyerr_offload_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_dis_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_dfs_phyerr_filter_dis_cmd_fixed_param)); + + /* + * Send WMI_DFS_PHYERR_FILTER_DIS_CMDID + * to the firmware to disable the phyerror + * filtering offload. + */ + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_DFS_PHYERR_FILTER_DIS_CMDID); + if (ret < 0) { + WMA_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_DIS_CMDID ret=%d", + __func__, ret); + wmi_buf_free(buf); + return 0; + } + WMA_LOGD("%s: WMI_DFS_PHYERR_FILTER_DIS_CMDID Send Success", + __func__); + } else { + WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini", + __func__); + + len = sizeof(*enable_phyerr_offload_cmd); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return 0; + } + + enable_phyerr_offload_cmd = + (wmi_dfs_phyerr_filter_ena_cmd_fixed_param *) + wmi_buf_data(buf); + + WMITLV_SET_HDR(&enable_phyerr_offload_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_dfs_phyerr_filter_ena_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_dfs_phyerr_filter_ena_cmd_fixed_param)); + + /* + * Send a WMI_DFS_PHYERR_FILTER_ENA_CMDID + * to the firmware to enable the phyerror + * filtering offload. + */ + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_DFS_PHYERR_FILTER_ENA_CMDID); + + if (ret < 0) { + WMA_LOGE("%s: Failed to send WMI_DFS_PHYERR_FILTER_ENA_CMDID ret=%d", + __func__, ret); + wmi_buf_free(buf); + return 0; + } + WMA_LOGD("%s: WMI_DFS_PHYERR_FILTER_ENA_CMDID Send Success", + __func__); + } + + return 1; +} + +/* + * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware. + * This event is generated by FW when the beacon transmission is offloaded + * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID + * The FW generates this event when the first successful beacon transmission + * after template update + * Return- 1:Success, 0:Failure + */ +static int wma_unified_bcntx_status_event_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf; + wmi_offload_bcn_tx_status_event_fixed_param *resp_event; + tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind; + + param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info; + if (!param_buf) { + WMA_LOGE("Invalid bcn tx response event buffer"); + return -EINVAL; + } + + resp_event = param_buf->fixed_param; + + /* Check for valid handle to ensure session is not deleted in any race */ + if (!wma->interfaces[resp_event->vdev_id].handle) { + WMA_LOGE("%s: The session does not exist", __func__); + return -EINVAL; + } + + /* Beacon Tx Indication supports only AP mode. Ignore in other modes */ + if ((wma->interfaces[resp_event->vdev_id].type != WMI_VDEV_TYPE_AP) || + (wma->interfaces[resp_event->vdev_id].sub_type != 0)) { + WMA_LOGI("%s: Beacon Tx Indication does not support type %d and sub_type %d", + __func__, wma->interfaces[resp_event->vdev_id].type, + wma->interfaces[resp_event->vdev_id].sub_type); + return 0; + } + + beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *) + vos_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd)); + if (!beacon_tx_complete_ind) { + WMA_LOGE("%s: Failed to alloc beacon_tx_complete_ind", __func__); + return -ENOMEM; + } + + beacon_tx_complete_ind->messageType = WDA_DFS_BEACON_TX_SUCCESS_IND; + beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd); + beacon_tx_complete_ind->bssIdx = resp_event->vdev_id; + + wma_send_msg(wma, WDA_DFS_BEACON_TX_SUCCESS_IND, (void *)beacon_tx_complete_ind, 0); + return 0; +} + +static int wma_vdev_install_key_complete_event_handler(void *handle, u_int8_t *event, u_int32_t len) +{ + WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf = NULL; + wmi_vdev_install_key_complete_event_fixed_param *key_fp = NULL; + + if (!event) { + WMA_LOGE("%s: event param null", __func__); + return -1; + } + + param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("%s: received null buf from target", __func__); + return -1; + } + + key_fp = param_buf->fixed_param; + if (!key_fp) { + WMA_LOGE("%s: received null event data from target", __func__); + return -1; + } + /* + * Do nothing for now. Completion of set key is already indicated to lim + */ + WMA_LOGI("%s: WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID", __func__); + return 0; +} + +#ifdef WLAN_FEATURE_STATS_EXT +static int wma_stats_ext_event_handler(void *handle, u_int8_t *event_buf, + u_int32_t len) +{ + WMI_STATS_EXT_EVENTID_param_tlvs *param_buf; + tSirStatsExtEvent *stats_ext_event; + wmi_stats_ext_event_fixed_param *stats_ext_info; + VOS_STATUS status; + vos_msg_t vos_msg; + u_int8_t *buf_ptr; + u_int32_t alloc_len; + + WMA_LOGD("%s: Posting stats ext event to SME", __func__); + + param_buf = (WMI_STATS_EXT_EVENTID_param_tlvs *)event_buf; + if (!param_buf) { + WMA_LOGE("%s: Invalid stats ext event buf", __func__); + return -EINVAL; + } + + stats_ext_info = param_buf->fixed_param; + buf_ptr = (u_int8_t *)stats_ext_info; + + alloc_len = sizeof(tSirStatsExtEvent); + alloc_len += stats_ext_info->data_len; + + stats_ext_event = (tSirStatsExtEvent *) vos_mem_malloc(alloc_len); + if (NULL == stats_ext_event) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return -ENOMEM; + } + + buf_ptr += sizeof(wmi_stats_ext_event_fixed_param) + WMI_TLV_HDR_SIZE ; + + stats_ext_event->vdev_id = stats_ext_info->vdev_id; + stats_ext_event->event_data_len = stats_ext_info->data_len; + vos_mem_copy(stats_ext_event->event_data, + buf_ptr, + stats_ext_event->event_data_len); + + vos_msg.type = eWNI_SME_STATS_EXT_EVENT; + vos_msg.bodyptr = (void *)stats_ext_event; + vos_msg.bodyval = 0; + + status = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to post stats ext event to SME", __func__); + vos_mem_free(stats_ext_event); + return -1; + } + + WMA_LOGD("%s: stats ext event Posted to SME", __func__); + return 0; +} +#endif + +static void +wma_register_extscan_event_handler(tp_wma_handle wma_handle) +{ + if (!wma_handle) { + WMA_LOGE("%s: extscan wma_handle is NULL", __func__); + return; + } + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_START_STOP_EVENTID, + wma_extscan_start_stop_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_CAPABILITIES_EVENTID, + wma_extscan_capabilities_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_HOTLIST_MATCH_EVENTID, + wma_extscan_hotlist_match_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID, + wma_extscan_change_results_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_OPERATION_EVENTID, + wma_extscan_operations_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_TABLE_USAGE_EVENTID, + wma_extscan_table_usage_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_EXTSCAN_CACHED_RESULTS_EVENTID, + wma_extscan_cached_results_event_handler); + return; +} + +void wma_wow_tx_complete(void *wma) +{ + tp_wma_handle wma_handle = (tp_wma_handle)wma; + WMA_LOGD("WOW_TX_COMPLETE DONE"); + vos_event_set(&wma_handle->wow_tx_complete); +} + +/* + * Allocate and init wmi adaptation layer. + */ +VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, + wda_tgt_cfg_cb tgt_cfg_cb, + wda_dfs_radar_indication_cb radar_ind_cb, + tMacOpenParameters *mac_params) +{ + tp_wma_handle wma_handle; + HTC_HANDLE htc_handle; + adf_os_device_t adf_dev; + v_VOID_t *wmi_handle; + VOS_STATUS vos_status; + struct ol_softc *scn; + struct txrx_pdev_cfg_param_t olCfg = {0}; + + WMA_LOGD("%s: Enter", __func__); + + adf_dev = vos_get_context(VOS_MODULE_ID_ADF, vos_context); + htc_handle = vos_get_context(VOS_MODULE_ID_HTC, vos_context); + + if (!htc_handle) { + WMA_LOGP("%s: Invalid HTC handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* Alloc memory for WMA Context */ + vos_status = vos_alloc_context(vos_context, VOS_MODULE_ID_WDA, + (v_VOID_t **) &wma_handle, + sizeof (t_wma_handle)); + + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: Memory allocation failed for wma_handle", + __func__); + return vos_status; + } + + vos_mem_zero(wma_handle, sizeof (t_wma_handle)); + + if (vos_get_conparam() != VOS_FTM_MODE) { +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_init(&wma_handle->pno_wake_lock, "wlan_pno_wl"); +#endif +#ifdef FEATURE_WLAN_EXTSCAN + vos_wake_lock_init(&wma_handle->extscan_wake_lock, + "wlan_extscan_wl"); +#endif + vos_wake_lock_init(&wma_handle->wow_wake_lock, "wlan_wow_wl"); + } + + /* attach the wmi */ + wmi_handle = wmi_unified_attach(wma_handle, wma_wow_tx_complete); + if (!wmi_handle) { + WMA_LOGP("%s: failed to attach WMI", __func__); + vos_status = VOS_STATUS_E_NOMEM; + goto err_wma_handle; + } + + WMA_LOGA("WMA --> wmi_unified_attach - success"); + + /* Save the WMI & HTC handle */ + wma_handle->wmi_handle = wmi_handle; + wma_handle->htc_handle = htc_handle; + wma_handle->vos_context = vos_context; + wma_handle->adf_dev = adf_dev; + + /* initialize default target config */ + wma_set_default_tgt_config(wma_handle); + +#ifdef IPA_UC_OFFLOAD + olCfg.is_uc_offload_enabled = mac_params->ucOffloadEnabled; + olCfg.uc_tx_buffer_count = mac_params->ucTxBufCount; + olCfg.uc_tx_buffer_size = mac_params->ucTxBufSize; + olCfg.uc_rx_indication_ring_count = mac_params->ucRxIndRingCount; + olCfg.uc_tx_partition_base = mac_params->ucTxPartitionBase; +#endif /* IPA_UC_OFFLOAD*/ + /* Allocate cfg handle */ + + /* RX Full reorder should enable for PCIe, ROME3.X project only now + * MDM should enable later, schedule TBD + * HL also sdould be enabled, schedule TBD */ +#ifdef WLAN_FEATURE_RX_FULL_REORDER_OL + olCfg.is_full_reorder_offload = mac_params->reorderOffload; +#else + olCfg.is_full_reorder_offload = 0; +#endif + ((pVosContextType) vos_context)->cfg_ctx = + ol_pdev_cfg_attach(((pVosContextType) vos_context)->adf_ctx, olCfg); + if (!(((pVosContextType) vos_context)->cfg_ctx)) { + WMA_LOGP("%s: failed to init cfg handle", __func__); + vos_status = VOS_STATUS_E_NOMEM; + goto err_wmi_handle; + } + + /* adjust the cfg_ctx default value based on setting */ + wdi_in_set_cfg_rx_fwd_disabled((ol_pdev_handle)((pVosContextType)vos_context)->cfg_ctx, + (u_int8_t)mac_params->apDisableIntraBssFwd); + + /* adjust the packet log enable default value based on CFG INI setting */ + wdi_in_set_cfg_pakcet_log_enabled((ol_pdev_handle) + ((pVosContextType)vos_context)->cfg_ctx, (u_int8_t)vos_is_packet_log_enabled()); + + + /* Allocate dfs_ic and initialize DFS */ + wma_handle->dfs_ic = wma_dfs_attach(wma_handle->dfs_ic); + if(wma_handle->dfs_ic == NULL) { + WMA_LOGE("%s: Memory allocation failed for dfs_ic", __func__); + goto err_wmi_handle; + } + +#if defined(QCA_WIFI_FTM) + if (vos_get_conparam() == VOS_FTM_MODE) + wma_utf_attach(wma_handle); +#endif + + /*TODO: Recheck below parameters */ + scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + + if (NULL == scn) { + WMA_LOGE("%s: Failed to get scn",__func__); + vos_status = VOS_STATUS_E_NOMEM; + goto err_scn_context; + } + + mac_params->maxStation = ol_get_number_of_peers_supported(scn); + + mac_params->maxBssId = WMA_MAX_SUPPORTED_BSS; + mac_params->frameTransRequired = 0; + + wma_handle->wlan_resource_config.num_wow_filters = mac_params->maxWoWFilters; + wma_handle->wlan_resource_config.num_keep_alive_pattern = WMA_MAXNUM_PERIODIC_TX_PTRNS; + + /* The current firmware implementation requires the number of offload peers + * should be (number of vdevs + 1). + */ + wma_handle->wlan_resource_config.num_offload_peers = + mac_params->apMaxOffloadPeers + 1; + + wma_handle->wlan_resource_config.num_offload_reorder_buffs = + mac_params->apMaxOffloadReorderBuffs + 1; + + wma_handle->ol_ini_info = mac_params->olIniInfo; + wma_handle->max_station = mac_params->maxStation; + wma_handle->max_bssid = mac_params->maxBssId; + wma_handle->frame_xln_reqd = mac_params->frameTransRequired; + wma_handle->driver_type = mac_params->driverType; + wma_handle->ssdp = mac_params->ssdp; +#ifdef FEATURE_WLAN_RA_FILTERING + wma_handle->IsRArateLimitEnabled = mac_params->IsRArateLimitEnabled; + wma_handle->RArateLimitInterval = mac_params->RArateLimitInterval; +#endif + /* + * Indicates if DFS Phyerr filtering offload + * is Enabled/Disabed from ini + */ + wma_handle->dfs_phyerr_filter_offload = + mac_params->dfsPhyerrFilterOffload; + wma_handle->dfs_pri_multiplier = + mac_params->dfsRadarPriMultiplier; + wma_handle->interfaces = vos_mem_malloc(sizeof(struct wma_txrx_node) * + wma_handle->max_bssid); + if (!wma_handle->interfaces) { + WMA_LOGP("%s: failed to allocate interface table", __func__); + vos_status = VOS_STATUS_E_NOMEM; + goto err_scn_context; + } + vos_mem_zero(wma_handle->interfaces, sizeof(struct wma_txrx_node) * + wma_handle->max_bssid); + /* Register the debug print event handler */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_DEBUG_PRINT_EVENTID, + wma_unified_debug_print_event_handler); + + wma_handle->tgt_cfg_update_cb = tgt_cfg_cb; + wma_handle->dfs_radar_indication_cb = radar_ind_cb; + + vos_status = vos_event_init(&wma_handle->wma_ready_event); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: wma_ready_event initialization failed", __func__); + goto err_event_init; + } + vos_status = vos_event_init(&wma_handle->target_suspend); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: target suspend event initialization failed", + __func__); + goto err_event_init; + } + + vos_status = vos_event_init(&wma_handle->wow_tx_complete); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: wow_tx_complete event initialization failed", + __func__); + goto err_event_init; + } + + /* Init Tx Frame Complete event */ + vos_status = vos_event_init(&wma_handle->tx_frm_download_comp_event); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: failed to init tx_frm_download_comp_event", + __func__); + goto err_event_init; + } + + /* Init tx queue empty check event */ + vos_status = vos_event_init(&wma_handle->tx_queue_empty_event); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: failed to init tx_queue_empty_event", + __func__); + goto err_event_init; + } + + vos_status = vos_event_init(&wma_handle->wma_resume_event); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: wma_resume_event initialization failed", __func__); + goto err_event_init; + } + + vos_status = vos_event_init(&wma_handle->recovery_event); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: recovery event initialization failed", __func__); + goto err_event_init; + } + + INIT_LIST_HEAD(&wma_handle->vdev_resp_queue); + adf_os_spinlock_init(&wma_handle->vdev_respq_lock); + adf_os_spinlock_init(&wma_handle->vdev_detach_lock); + adf_os_spinlock_init(&wma_handle->roam_preauth_lock); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + adf_os_spinlock_init(&wma_handle->roam_synch_lock); +#endif + adf_os_atomic_init(&wma_handle->is_wow_bus_suspended); + + /* Register vdev start response event handler */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_VDEV_START_RESP_EVENTID, + wma_vdev_start_resp_handler); + + /* Register vdev stop response event handler */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_VDEV_STOPPED_EVENTID, + wma_vdev_stop_resp_handler); + + /* register for STA kickout function */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_STA_KICKOUT_EVENTID, + wma_peer_sta_kickout_event_handler); + + /* register for stats response event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_UPDATE_STATS_EVENTID, + wma_stats_event_handler); + /* register for linkspeed response event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_ESTIMATED_LINKSPEED_EVENTID, + wma_link_speed_event_handler); + +#ifdef FEATURE_OEM_DATA_SUPPORT + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_OEM_CAPABILITY_EVENTID, + wma_oem_capability_event_callback); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_OEM_MEASUREMENT_REPORT_EVENTID, + wma_oem_measurement_report_event_callback); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_OEM_ERROR_REPORT_EVENTID, + wma_oem_error_report_event_callback); +#endif + /* + * Register appropriate DFS phyerr event handler for + * Phyerror events. Handlers differ for phyerr filtering + * offload enable and disable cases. + */ + wma_register_dfs_event_handler(wma_handle); + + /* Register peer change event handler */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_STATE_EVENTID, + wma_peer_state_change_event_handler); + + + /* Register beacon tx complete event id. The event is required + * for sending channel switch announcement frames + */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_OFFLOAD_BCN_TX_STATUS_EVENTID, + wma_unified_bcntx_status_event_handler); + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_UPDATE_VDEV_RATE_STATS_EVENTID, + wma_link_status_event_handler); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + /* Register event handler for processing Link Layer Stats + * response from the FW + */ + wma_register_ll_stats_event_handler(wma_handle); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + /* Firmware debug log */ + vos_status = dbglog_init(wma_handle->wmi_handle); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: Firmware Dbglog initialization failed", __func__); + goto err_dbglog_init; + } + + /* + * Update Powersave mode + * 1 - Legacy Powersave + Deepsleep Disabled + * 2 - QPower + Deepsleep Disabled + * 3 - Legacy Powersave + Deepsleep Enabled + * 4 - QPower + Deepsleep Enabled + */ + wma_handle->powersave_mode = mac_params->powersaveOffloadEnabled; + wma_handle->staMaxLIModDtim = mac_params->staMaxLIModDtim; + wma_handle->staModDtim = mac_params->staModDtim; + wma_handle->staDynamicDtim = mac_params->staDynamicDtim; + + /* + * Value of mac_params->wowEnable can be, + * 0 - Disable both magic pattern match and pattern byte match. + * 1 - Enable magic pattern match on all interfaces. + * 2 - Enable pattern byte match on all interfaces. + * 3 - Enable both magic patter and pattern byte match on + * all interfaces. + */ + wma_handle->wow.magic_ptrn_enable = + (mac_params->wowEnable & 0x01) ? TRUE : FALSE; + wma_handle->ptrn_match_enable_all_vdev = + (mac_params->wowEnable & 0x02) ? TRUE : FALSE; + +#ifdef FEATURE_WLAN_TDLS + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_TDLS_PEER_EVENTID, + wma_tdls_event_handler); +#endif /* FEATURE_WLAN_TDLS */ + + /* register for install key completion event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID, + wma_vdev_install_key_complete_event_handler); +#ifdef WLAN_FEATURE_NAN + /* register for nan response event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_NAN_EVENTID, + wma_nan_rsp_event_handler); +#endif + +#ifdef WLAN_FEATURE_STATS_EXT + /* register for extended stats event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_STATS_EXT_EVENTID, + wma_stats_ext_event_handler); +#endif +#ifdef FEATURE_WLAN_EXTSCAN + wma_register_extscan_event_handler(wma_handle); +#endif + + WMA_LOGD("%s: Exit", __func__); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_ROAM_SYNCH_EVENTID, + wma_roam_synch_event_handler); +#endif /* WLAN_FEATURE_ROAM_OFFLOAD */ + return VOS_STATUS_SUCCESS; + +err_dbglog_init: + adf_os_spinlock_destroy(&wma_handle->vdev_respq_lock); + adf_os_spinlock_destroy(&wma_handle->vdev_detach_lock); + adf_os_spinlock_destroy(&wma_handle->roam_preauth_lock); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + adf_os_spinlock_destroy(&wma_handle->roam_synch_lock); +#endif +err_event_init: + wmi_unified_unregister_event_handler(wma_handle->wmi_handle, + WMI_DEBUG_PRINT_EVENTID); + vos_mem_free(wma_handle->interfaces); +err_scn_context: + wma_dfs_detach(wma_handle->dfs_ic); +#if defined(QCA_WIFI_FTM) + wma_utf_detach(wma_handle); +#endif +err_wmi_handle: + adf_os_mem_free(((pVosContextType) vos_context)->cfg_ctx); + OS_FREE(wmi_handle); + +err_wma_handle: + + if (vos_get_conparam() != VOS_FTM_MODE) { +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_destroy(&wma_handle->pno_wake_lock); +#endif +#ifdef FEATURE_WLAN_EXTSCAN + vos_wake_lock_destroy(&wma_handle->extscan_wake_lock); +#endif + vos_wake_lock_destroy(&wma_handle->wow_wake_lock); + } + vos_free_context(vos_context, VOS_MODULE_ID_WDA, wma_handle); + + WMA_LOGD("%s: Exit", __func__); + + return vos_status; +} + +/* function : wma_pre_start + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_pre_start(v_VOID_t *vos_ctx) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + A_STATUS status = A_OK; + tp_wma_handle wma_handle; + vos_msg_t wma_msg = {0} ; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + /* Validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGP("%s: invalid argument", __func__); + vos_status = VOS_STATUS_E_INVAL; + goto end; + } + /* Open endpoint for ctrl path - WMI <--> HTC */ + status = wmi_unified_connect_htc_service( + wma_handle->wmi_handle, + wma_handle->htc_handle); + if (A_OK != status) { + WMA_LOGP("%s: wmi_unified_connect_htc_service", __func__); + vos_status = VOS_STATUS_E_FAULT; + goto end; + } + + WMA_LOGA("WMA --> wmi_unified_connect_htc_service - success"); + + /* Trigger the CFG DOWNLOAD */ + wma_msg.type = WNI_CFG_DNLD_REQ ; + wma_msg.bodyptr = NULL; + wma_msg.bodyval = 0; + + vos_status = vos_mq_post_message( VOS_MQ_ID_WDA, &wma_msg ); + if (VOS_STATUS_SUCCESS !=vos_status) { + WMA_LOGP("%s: Failed to post WNI_CFG_DNLD_REQ msg", __func__); + VOS_ASSERT(0); + vos_status = VOS_STATUS_E_FAILURE; + } +end: + WMA_LOGD("%s: Exit", __func__); + return vos_status; +} + +/* function : wma_send_msg + * Description : + * Args : + * Returns : + */ +static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type, + void *body_ptr, u_int32_t body_val) +{ + tSirMsgQ msg = {0} ; + tANI_U32 status = VOS_STATUS_SUCCESS ; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + msg.type = msg_type; + msg.bodyval = body_val; + msg.bodyptr = body_ptr; + status = limPostMsgApi(pMac, &msg); + if (VOS_STATUS_SUCCESS != status) { + if(NULL != body_ptr) + vos_mem_free(body_ptr); + VOS_ASSERT(0) ; + } + return ; +} + +/* function : wma_get_txrx_vdev_type + * Description : + * Args : + * Returns : + */ +enum wlan_op_mode wma_get_txrx_vdev_type(u_int32_t type) +{ + enum wlan_op_mode vdev_type = wlan_op_mode_unknown; + switch (type) { + case WMI_VDEV_TYPE_AP: + vdev_type = wlan_op_mode_ap; + break; + case WMI_VDEV_TYPE_STA: + vdev_type = wlan_op_mode_sta; + break; +#ifdef QCA_IBSS_SUPPORT + case WMI_VDEV_TYPE_IBSS: + vdev_type = wlan_op_mode_ibss; + break; +#endif + case WMI_VDEV_TYPE_MONITOR: + default: + WMA_LOGE("Invalid vdev type %u", type); + vdev_type = wlan_op_mode_unknown; + } + + return vdev_type; +} + +/* function : wma_unified_vdev_create_send + * Description : + * Args : + * Returns : + */ +int wma_unified_vdev_create_send(wmi_unified_t wmi_handle, u_int8_t if_id, + u_int32_t type, u_int32_t subtype, + u_int8_t macaddr[IEEE80211_ADDR_LEN]) +{ + wmi_vdev_create_cmd_fixed_param* cmd; + wmi_buf_t buf; + int len = sizeof(*cmd); + int ret; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGP("%s:wmi_buf_alloc failed", __FUNCTION__); + return ENOMEM; + } + cmd = (wmi_vdev_create_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_create_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_create_cmd_fixed_param)); + cmd->vdev_id = if_id; + cmd->vdev_type = type; + cmd->vdev_subtype = subtype; + WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->vdev_macaddr); + WMA_LOGE("%s: ID = %d VAP Addr = %02x:%02x:%02x:%02x:%02x:%02x", + __func__, if_id, + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_CREATE_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send WMI_VDEV_CREATE_CMDID"); + wmi_buf_free(buf); + } + return ret; +} + +/* function : wma_unified_vdev_delete_send + * Description : + * Args : + * Returns : + */ +static int wma_unified_vdev_delete_send(wmi_unified_t wmi_handle, u_int8_t if_id) +{ + wmi_vdev_delete_cmd_fixed_param* cmd; + wmi_buf_t buf; + int ret; + + buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGP("%s:wmi_buf_alloc failed", __FUNCTION__); + return ENOMEM; + } + + cmd = (wmi_vdev_delete_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_delete_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_delete_cmd_fixed_param)); + cmd->vdev_id = if_id; + ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(wmi_vdev_delete_cmd_fixed_param), + WMI_VDEV_DELETE_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send WMI_VDEV_DELETE_CMDID"); + wmi_buf_free(buf); + } + return ret; +} + +void wma_vdev_detach_callback(void *ctx) +{ + tp_wma_handle wma; + struct wma_txrx_node *iface = (struct wma_txrx_node *)ctx; + tpDelStaSelfParams param; + struct wma_target_req *req_msg; + + wma = vos_get_context(VOS_MODULE_ID_WDA, + vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + + if (!wma || !iface->del_staself_req) { + WMA_LOGP("%s: wma %p iface %p", __func__, wma, + iface->del_staself_req); + return; + } + param = (tpDelStaSelfParams) iface->del_staself_req; + WMA_LOGD("%s: sending WDA_DEL_STA_SELF_RSP for vdev %d", + __func__, param->sessionId); + + req_msg = wma_find_vdev_req(wma, param->sessionId, + WMA_TARGET_REQ_TYPE_VDEV_DEL); + if (req_msg) { + WMA_LOGD("%s: Found vdev request for vdev id %d", + __func__, param->sessionId); + vos_timer_stop(&req_msg->event_timeout); + vos_timer_destroy(&req_msg->event_timeout); + adf_os_mem_free(req_msg); + } + if(iface->addBssStaContext) + adf_os_mem_free(iface->addBssStaContext); + +#if defined WLAN_FEATURE_VOWIFI_11R + if (iface->staKeyParams) + adf_os_mem_free(iface->staKeyParams); +#endif + vos_mem_zero(iface, sizeof(*iface)); + param->status = VOS_STATUS_SUCCESS; + + wma_send_msg(wma, WDA_DEL_STA_SELF_RSP, (void *)param, 0); +} + +/* function : wma_vdev_detach + * Description : + * Args : + * Returns : + */ +static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, + tpDelStaSelfParams pdel_sta_self_req_param, + u_int8_t generateRsp) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + ol_txrx_peer_handle peer; + ol_txrx_pdev_handle pdev; + u_int8_t peer_id; + u_int8_t vdev_id = pdel_sta_self_req_param->sessionId; + struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; + struct wma_target_req *msg; + + if ((iface->type == WMI_VDEV_TYPE_AP) && + (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) { + + WMA_LOGA("P2P Device: removing self peer %pM", + pdel_sta_self_req_param->selfMacAddr); + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, + wma_handle->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev",__func__); + return VOS_STATUS_E_FAULT; + } + + peer = ol_txrx_find_peer_by_addr(pdev, + pdel_sta_self_req_param->selfMacAddr, + &peer_id); + if (!peer) { + WMA_LOGE("%s Failed to find peer %pM", __func__, + pdel_sta_self_req_param->selfMacAddr); + } + wma_remove_peer(wma_handle, + pdel_sta_self_req_param->selfMacAddr, + vdev_id, peer, VOS_FALSE); + } + if (adf_os_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) { + WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion", + vdev_id); + iface->del_staself_req = pdel_sta_self_req_param; + return status; + } + + adf_os_spin_lock_bh(&wma_handle->vdev_detach_lock); + if(!iface->handle) { + WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed", + vdev_id); + adf_os_spin_unlock_bh(&wma_handle->vdev_detach_lock); + vos_mem_free(pdel_sta_self_req_param); + pdel_sta_self_req_param = NULL; + return status; + } + + /* Unregister vdev from TL shim before vdev delete + * Will protect from invalid vdev access */ + WLANTL_UnRegisterVdev(wma_handle->vos_context, vdev_id); + + /* remove the interface from ath_dev */ + if (wma_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id)) { + WMA_LOGE("Unable to remove an interface for ath_dev."); + status = VOS_STATUS_E_FAILURE; + adf_os_spin_unlock_bh(&wma_handle->vdev_detach_lock); + goto out; + } + + + WMA_LOGA("vdev_id:%hu vdev_hdl:%p", vdev_id, iface->handle); + if (!generateRsp) { + WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id); + ol_txrx_vdev_detach(iface->handle, NULL, NULL); + adf_os_spin_unlock_bh(&wma_handle->vdev_detach_lock); + goto out; + } + + iface->del_staself_req = pdel_sta_self_req_param; + msg = wma_fill_vdev_req(wma_handle, vdev_id, WDA_DEL_STA_SELF_REQ, + WMA_TARGET_REQ_TYPE_VDEV_DEL, iface, 2000); + if (!msg) { + WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d", + __func__, vdev_id); + status = VOS_STATUS_E_NOMEM; + adf_os_spin_unlock_bh(&wma_handle->vdev_detach_lock); + goto out; + } + WMA_LOGE("Call txrx detach with callback for vdev %d", vdev_id); + ol_txrx_vdev_detach(iface->handle, NULL, NULL); + wma_vdev_detach_callback(iface); + adf_os_spin_unlock_bh(&wma_handle->vdev_detach_lock); + return status; +out: + if(iface->addBssStaContext) + adf_os_mem_free(iface->addBssStaContext); +#if defined WLAN_FEATURE_VOWIFI_11R + if (iface->staKeyParams) + adf_os_mem_free(iface->staKeyParams); +#endif + vos_mem_zero(iface, sizeof(*iface)); + pdel_sta_self_req_param->status = status; + if (generateRsp) + wma_send_msg(wma_handle, WDA_DEL_STA_SELF_RSP, (void *)pdel_sta_self_req_param, 0); + + return status; +} + +static int wmi_unified_peer_create_send(wmi_unified_t wmi, + const u_int8_t *peer_addr, u_int32_t peer_type, + u_int32_t vdev_id) +{ + wmi_peer_create_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_peer_create_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_create_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_create_cmd_fixed_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + cmd->peer_type = peer_type; + cmd->vdev_id = vdev_id; + + if (wmi_unified_cmd_send(wmi, buf, len, WMI_PEER_CREATE_CMDID)) { + WMA_LOGP("%s: failed to send WMI_PEER_CREATE_CMDID", __func__); + adf_nbuf_free(buf); + return -EIO; + } + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); + return 0; +} + +static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, u8 peer_addr[6], + u_int32_t peer_type, u_int8_t vdev_id, + v_BOOL_t roam_synch_in_progress) +{ + ol_txrx_peer_handle peer; + + if (++wma->interfaces[vdev_id].peer_count > wma->wlan_resource_config.num_peers) { + WMA_LOGP("%s, the peer count exceeds the limit %d", + __func__, wma->interfaces[vdev_id].peer_count - 1); + goto err; + } + peer = ol_txrx_peer_attach(pdev, vdev, peer_addr); + if (!peer) { + WMA_LOGE("%s : Unable to attach peer %pM", __func__, peer_addr); + goto err; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (roam_synch_in_progress) { + + WMA_LOGD("%s: Created peer with peer_addr %pM vdev_id %d," + "peer_count - %d",__func__, peer_addr, vdev_id, + wma->interfaces[vdev_id].peer_count); + return VOS_STATUS_SUCCESS; + } +#endif + if (wmi_unified_peer_create_send(wma->wmi_handle, peer_addr, + peer_type, vdev_id) < 0) { + WMA_LOGP("%s : Unable to create peer in Target", __func__); + ol_txrx_peer_detach(peer); + goto err; + } + WMA_LOGE("%s: Created peer with peer_addr %pM vdev_id %d, peer_count - %d", + __func__, peer_addr, vdev_id, wma->interfaces[vdev_id].peer_count); + +#ifdef QCA_IBSS_SUPPORT + /* for each remote ibss peer, clear its keys */ + if (wma_is_vdev_in_ibss_mode(wma, vdev_id) + && !vos_mem_compare(peer_addr, vdev->mac_addr.raw, ETH_ALEN)) { + + tSetStaKeyParams key_info; + WMA_LOGD("%s: remote ibss peer %pM key clearing\n", __func__, + peer_addr); + vos_mem_set(&key_info, sizeof(key_info), 0); + key_info.smesessionId= vdev_id; + vos_mem_copy(key_info.peerMacAddr, peer_addr, ETH_ALEN); + key_info.sendRsp = FALSE; + + wma_set_stakey(wma, &key_info); + } +#endif + + return VOS_STATUS_SUCCESS; +err: + wma->interfaces[vdev_id].peer_count--; + return VOS_STATUS_E_FAILURE; +} + +static void wma_set_sta_keep_alive(tp_wma_handle wma, u_int8_t vdev_id, + v_U32_t method, v_U32_t timeperiod, + u_int8_t *hostv4addr, u_int8_t *destv4addr, + u_int8_t *destmac) +{ + wmi_buf_t buf; + WMI_STA_KEEPALIVE_CMD_fixed_param *cmd; + WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp; + u_int8_t *buf_ptr; + int len; + + WMA_LOGD("%s: Enter", __func__); + len = sizeof(*cmd) + sizeof(*arp_rsp); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("wmi_buf_alloc failed"); + return; + } + + cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf); + buf_ptr = (u_int8_t *)cmd; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_STA_KEEPALIVE_CMD_fixed_param)); + cmd->interval = timeperiod; + cmd->enable = (timeperiod)? 1:0; + cmd->vdev_id = vdev_id; + WMA_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", vdev_id, + timeperiod, method); + arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *)(buf_ptr + sizeof(*cmd)); + WMITLV_SET_HDR(&arp_rsp->tlv_header, + WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE, + WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE)); + + if (method == SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP) { + cmd->method = WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE; + vos_mem_copy(&arp_rsp->sender_prot_addr, hostv4addr, + SIR_IPV4_ADDR_LEN); + vos_mem_copy(&arp_rsp->target_prot_addr, destv4addr, + SIR_IPV4_ADDR_LEN); + WMI_CHAR_ARRAY_TO_MAC_ADDR(destmac,&arp_rsp->dest_mac_addr); + } else { + cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; + } + + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_STA_KEEPALIVE_CMDID)) { + WMA_LOGE("Failed to set KeepAlive"); + adf_nbuf_free(buf); + } + + WMA_LOGD("%s: Exit", __func__); + return; +} + +static inline void wma_get_link_probe_timeout(struct sAniSirGlobal *mac, + tANI_U32 sub_type, + tANI_U32 *max_inactive_time, + tANI_U32 *max_unresponsive_time) +{ + tANI_U32 keep_alive; + tANI_U16 lm_id, ka_id; + + switch (sub_type) { + case WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO: + lm_id = WNI_CFG_GO_LINK_MONITOR_TIMEOUT; + ka_id = WNI_CFG_GO_KEEP_ALIVE_TIMEOUT; + break; + default: + /*For softAp the subtype value will be zero*/ + lm_id = WNI_CFG_AP_LINK_MONITOR_TIMEOUT; + ka_id = WNI_CFG_AP_KEEP_ALIVE_TIMEOUT; + } + + if(wlan_cfgGetInt(mac, lm_id, max_inactive_time) != eSIR_SUCCESS) { + WMA_LOGE("Failed to read link monitor for subtype %d", sub_type); + *max_inactive_time = WMA_LINK_MONITOR_DEFAULT_TIME_SECS; + } + + if(wlan_cfgGetInt(mac, ka_id, &keep_alive) != eSIR_SUCCESS) { + WMA_LOGE("Failed to read keep alive for subtype %d", sub_type); + keep_alive = WMA_KEEP_ALIVE_DEFAULT_TIME_SECS; + } + *max_unresponsive_time = *max_inactive_time + keep_alive; +} + +static void wma_set_sap_keepalive(tp_wma_handle wma, u_int8_t vdev_id) +{ + tANI_U32 min_inactive_time, max_inactive_time, max_unresponsive_time; + struct sAniSirGlobal *mac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + if (NULL == mac) { + WMA_LOGE("%s: Failed to get mac", __func__); + return; + } + + wma_get_link_probe_timeout(mac, wma->interfaces[vdev_id].sub_type, + &max_inactive_time, &max_unresponsive_time); + + min_inactive_time = max_inactive_time / 2; + + if (wmi_unified_vdev_set_param_send(wma->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, + min_inactive_time)) + WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME"); + + if (wmi_unified_vdev_set_param_send(wma->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, + max_inactive_time)) + WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME"); + + if (wmi_unified_vdev_set_param_send(wma->wmi_handle, + vdev_id, + WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, + max_unresponsive_time)) + WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME"); + + WMA_LOGD("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u" + " max_unresponsive_time: %u", __func__, vdev_id, + min_inactive_time, max_inactive_time, max_unresponsive_time); +} + +static VOS_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(tANI_U32 mcc_adaptive_scheduler) +{ + int ret = -1; + wmi_buf_t buf = 0; + wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *cmd = NULL; + tp_wma_handle wma = NULL; + void *vos_context = NULL; + u_int16_t len = sizeof(wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param); + + vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + + if (NULL == wma) { + WMA_LOGE("%s : Failed to get wma", __func__); + return VOS_STATUS_E_FAULT; + } + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + cmd = (wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param)); + cmd->enable = mcc_adaptive_scheduler; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); + if (ret) { + WMA_LOGP("%s: Failed to send enable/disable MCC" + " adaptive scheduler command", __func__); + adf_nbuf_free(buf); + } + return VOS_STATUS_SUCCESS; +} + +/** + * Currently used to set time latency for an MCC vdev/adapter using operating + * channel of it and channel number. The info is provided run time using + * iwpriv command: iwpriv setMccLatency . + */ +static VOS_STATUS wma_set_mcc_channel_time_latency + ( + tp_wma_handle wma, + tANI_U32 mcc_channel, + tANI_U32 mcc_channel_time_latency + ) +{ + int ret = -1; + wmi_buf_t buf = 0; + wmi_resmgr_set_chan_latency_cmd_fixed_param *cmdTL = NULL; + u_int16_t len = 0; + u_int8_t *buf_ptr = NULL; + tANI_U32 cfg_val = 0; + wmi_resmgr_chan_latency chan_latency; + struct sAniSirGlobal *pMac = NULL; + /* Note: we only support MCC time latency for a single channel */ + u_int32_t num_channels = 1; + u_int32_t channel1 = mcc_channel; + u_int32_t chan1_freq = vos_chan_to_freq( channel1 ); + u_int32_t latency_chan1 = mcc_channel_time_latency; + + if (!wma) { + WMA_LOGE("%s:NULL wma ptr. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pMac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + if (!pMac) { + WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* First step is to confirm if MCC is active */ + if (!limIsInMCC(pMac)) { + WMA_LOGE("%s: MCC is not active. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + /* Confirm MCC adaptive scheduler feature is disabled */ + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, + &cfg_val) == eSIR_SUCCESS) { + if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) { + WMA_LOGD("%s: Can't set channel latency while MCC " + "ADAPTIVE SCHED is enabled. Exit", __func__); + return VOS_STATUS_SUCCESS; + } + } else { + WMA_LOGE("%s: Failed to get value for MCC_ADAPTIVE_SCHED, " + "Exit w/o setting latency", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + /* If 0ms latency is provided, then FW will set to a default. + * Otherwise, latency must be at least 30ms. + */ + if ((latency_chan1 > 0) && + (latency_chan1 < WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY)) { + WMA_LOGE("%s: Invalid time latency for Channel #1 = %dms " + "Minimum is 30ms (or 0 to use default value by " + "firmware)", __func__, latency_chan1); + return VOS_STATUS_E_INVAL; + } + + /* Set WMI CMD for channel time latency here */ + len = sizeof(wmi_resmgr_set_chan_latency_cmd_fixed_param) + + WMI_TLV_HDR_SIZE + /*Place holder for chan_time_latency array*/ + num_channels * sizeof(wmi_resmgr_chan_latency); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmdTL = (wmi_resmgr_set_chan_latency_cmd_fixed_param *) + wmi_buf_data(buf); + WMITLV_SET_HDR(&cmdTL->tlv_header, + WMITLV_TAG_STRUC_wmi_resmgr_set_chan_latency_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_resmgr_set_chan_latency_cmd_fixed_param)); + cmdTL->num_chans = num_channels; + /* Update channel time latency information for home channel(s) */ + buf_ptr += sizeof(*cmdTL); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + num_channels * sizeof(wmi_resmgr_chan_latency)); + buf_ptr += WMI_TLV_HDR_SIZE; + chan_latency.chan_mhz = chan1_freq; + chan_latency.latency = latency_chan1; + vos_mem_copy(buf_ptr, &chan_latency, sizeof(chan_latency)); + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_RESMGR_SET_CHAN_LATENCY_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send MCC Channel Time Latency command", + __func__); + adf_nbuf_free(buf); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/** + * Currently used to set time quota for 2 MCC vdevs/adapters using (operating + * channel, quota) for each mode . The info is provided run time using + * iwpriv command: iwpriv setMccQuota . + * Note: the quota provided in command is for the same mode in cmd. HDD + * checks if MCC mode is active, gets the second mode and its operating chan. + * Quota for the 2nd role is calculated as 100 - quota of first mode. + */ +static VOS_STATUS wma_set_mcc_channel_time_quota + ( + tp_wma_handle wma, + tANI_U32 adapter_1_chan_number, + tANI_U32 adapter_1_quota, + tANI_U32 adapter_2_chan_number + ) +{ + int ret = -1; + wmi_buf_t buf = 0; + u_int16_t len = 0; + u_int8_t *buf_ptr = NULL; + tANI_U32 cfg_val = 0; + struct sAniSirGlobal *pMac = NULL; + wmi_resmgr_set_chan_time_quota_cmd_fixed_param *cmdTQ = NULL; + wmi_resmgr_chan_time_quota chan_quota; + u_int32_t channel1 = adapter_1_chan_number; + u_int32_t channel2 = adapter_2_chan_number; + u_int32_t quota_chan1 = adapter_1_quota; + /* Knowing quota of 1st chan., derive quota for 2nd chan. */ + u_int32_t quota_chan2 = 100 - quota_chan1; + /* Note: setting time quota for MCC requires info for 2 channels */ + u_int32_t num_channels = 2; + u_int32_t chan1_freq = vos_chan_to_freq(adapter_1_chan_number); + u_int32_t chan2_freq = vos_chan_to_freq(adapter_2_chan_number); + + WMA_LOGD("%s: Channel1:%d, freq1:%dMHz, Quota1:%dms, " + "Channel2:%d, freq2:%dMHz, Quota2:%dms", __func__, + channel1, chan1_freq, quota_chan1, channel2, chan2_freq, + quota_chan2); + + if (!wma) { + WMA_LOGE("%s:NULL wma ptr. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pMac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + if (!pMac) { + WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* First step is to confirm if MCC is active */ + if (!limIsInMCC(pMac)) { + WMA_LOGD("%s: MCC is not active. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Confirm MCC adaptive scheduler feature is disabled */ + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, + &cfg_val) == eSIR_SUCCESS) { + if (cfg_val == WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX) { + WMA_LOGD("%s: Can't set channel quota while " + "MCC_ADAPTIVE_SCHED is enabled. Exit", + __func__); + return VOS_STATUS_SUCCESS; + } + } else { + WMA_LOGE("%s: Failed to retrieve " + "WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED. Exit", + __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /** + * Perform sanity check on time quota values provided. + */ + if (quota_chan1 < WMI_MCC_MIN_CHANNEL_QUOTA || + quota_chan1 > WMI_MCC_MAX_CHANNEL_QUOTA) { + WMA_LOGE("%s: Invalid time quota for Channel #1=%dms. Minimum " + "is 20ms & maximum is 80ms", __func__, quota_chan1); + return VOS_STATUS_E_INVAL; + } + /* Set WMI CMD for channel time quota here */ + len = sizeof(wmi_resmgr_set_chan_time_quota_cmd_fixed_param) + + WMI_TLV_HDR_SIZE + /* Place holder for chan_time_quota array */ + num_channels * sizeof(wmi_resmgr_chan_time_quota); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmdTQ = (wmi_resmgr_set_chan_time_quota_cmd_fixed_param *) + wmi_buf_data(buf); + WMITLV_SET_HDR(&cmdTQ->tlv_header, + WMITLV_TAG_STRUC_wmi_resmgr_set_chan_time_quota_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_resmgr_set_chan_time_quota_cmd_fixed_param)); + cmdTQ->num_chans = num_channels; + + /* Update channel time quota information for home channel(s) */ + buf_ptr += sizeof(*cmdTQ); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + num_channels * sizeof(wmi_resmgr_chan_time_quota)); + buf_ptr += WMI_TLV_HDR_SIZE; + chan_quota.chan_mhz = chan1_freq; + chan_quota.channel_time_quota = quota_chan1; + vos_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); + /* Construct channel and quota record for the 2nd MCC mode. */ + buf_ptr += sizeof(chan_quota); + chan_quota.chan_mhz = chan2_freq; + chan_quota.channel_time_quota = quota_chan2; + vos_mem_copy(buf_ptr, &chan_quota, sizeof(chan_quota)); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); + if (ret) { + WMA_LOGE("Failed to send MCC Channel Time Quota command"); + adf_nbuf_free(buf); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* function : wma_vdev_attach + * Description : + * Args : + * Returns : + */ +static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, + tpAddStaSelfParams self_sta_req, + u_int8_t generateRsp) +{ + ol_txrx_vdev_handle txrx_vdev_handle = NULL; + ol_txrx_pdev_handle txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, + wma_handle->vos_context); + enum wlan_op_mode txrx_vdev_type; + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct sAniSirGlobal *mac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + tANI_U32 cfg_val; + tANI_U16 val16; + int ret; + tSirMacHTCapabilityInfo *phtCapInfo; + + if (NULL == mac) { + WMA_LOGE("%s: Failed to get mac",__func__); + goto end; + } + + /* Create a vdev in target */ + if (wma_unified_vdev_create_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + self_sta_req->type, + self_sta_req->subType, + self_sta_req->selfMacAddr)) + { + WMA_LOGP("%s: Unable to add an interface for ath_dev", __func__); + status = VOS_STATUS_E_RESOURCES; + goto end; + } + + txrx_vdev_type = wma_get_txrx_vdev_type(self_sta_req->type); + + if (wlan_op_mode_unknown == txrx_vdev_type) { + WMA_LOGE("Failed to get txrx vdev type"); + wma_unified_vdev_delete_send(wma_handle->wmi_handle, + self_sta_req->sessionId); + goto end; + } + + txrx_vdev_handle = ol_txrx_vdev_attach(txrx_pdev, + self_sta_req->selfMacAddr, + self_sta_req->sessionId, + txrx_vdev_type); + wma_handle->interfaces[self_sta_req->sessionId].pause_bitmap = 0; + + WMA_LOGA("vdev_id %hu, txrx_vdev_handle = %p", self_sta_req->sessionId, + txrx_vdev_handle); + + if (NULL == txrx_vdev_handle) { + WMA_LOGP("%s: ol_txrx_vdev_attach failed", __func__); + status = VOS_STATUS_E_FAILURE; + wma_unified_vdev_delete_send(wma_handle->wmi_handle, + self_sta_req->sessionId); + goto end; + } + wma_handle->interfaces[self_sta_req->sessionId].handle = txrx_vdev_handle; + + wma_handle->interfaces[self_sta_req->sessionId].ptrn_match_enable = + wma_handle->ptrn_match_enable_all_vdev ? TRUE : FALSE; + + if (wlan_cfgGetInt(mac, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfg_val) + != eSIR_SUCCESS) + wma_handle->wow.deauth_enable = TRUE; + else + wma_handle->wow.deauth_enable = cfg_val ? TRUE : FALSE; + + if (wlan_cfgGetInt(mac, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfg_val) + != eSIR_SUCCESS) + wma_handle->wow.disassoc_enable = TRUE; + else + wma_handle->wow.disassoc_enable = cfg_val ? TRUE : FALSE; + + if (wlan_cfgGetInt(mac, WNI_CFG_WOWLAN_MAX_MISSED_BEACON, &cfg_val) + != eSIR_SUCCESS) + wma_handle->wow.bmiss_enable = TRUE; + else + wma_handle->wow.bmiss_enable = cfg_val ? TRUE : FALSE; + + vos_mem_copy(wma_handle->interfaces[self_sta_req->sessionId].addr, + self_sta_req->selfMacAddr, + sizeof(wma_handle->interfaces[self_sta_req->sessionId].addr)); + switch (self_sta_req->type) { + case WMI_VDEV_TYPE_STA: + if(wlan_cfgGetInt(mac, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, + &cfg_val ) != eSIR_SUCCESS) { + WMA_LOGE("Failed to get value for " + "WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD"); + cfg_val = DEFAULT_INFRA_STA_KEEP_ALIVE_PERIOD; + } + + wma_set_sta_keep_alive(wma_handle, + self_sta_req->sessionId, + SIR_KEEP_ALIVE_NULL_PKT, + cfg_val, + NULL, + NULL, + NULL); + break; + } + + wma_handle->interfaces[self_sta_req->sessionId].type = + self_sta_req->type; + wma_handle->interfaces[self_sta_req->sessionId].sub_type = + self_sta_req->subType; + adf_os_atomic_init(&wma_handle->interfaces + [self_sta_req->sessionId].bss_status); + + if ((self_sta_req->type == WMI_VDEV_TYPE_AP) && + (self_sta_req->subType == + WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) { + WMA_LOGA("P2P Device: creating self peer %pM, vdev_id %hu", + self_sta_req->selfMacAddr, + self_sta_req->sessionId); + status = wma_create_peer(wma_handle, txrx_pdev, + txrx_vdev_handle, self_sta_req->selfMacAddr, + WMI_PEER_TYPE_DEFAULT,self_sta_req->sessionId, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer", __func__); + status = VOS_STATUS_E_FAILURE; + wma_unified_vdev_delete_send(wma_handle->wmi_handle, + self_sta_req->sessionId); + } + } + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + WMI_VDEV_PARAM_DISCONNECT_TH, + self_sta_req->pkt_err_disconn_th); + if (ret) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_DISCONNECT_TH"); + + if (wlan_cfgGetInt(mac, WNI_CFG_RTS_THRESHOLD, + &cfg_val) == eSIR_SUCCESS) { + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + WMI_VDEV_PARAM_RTS_THRESHOLD, + cfg_val); + if (ret) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_RTS_THRESHOLD"); + } else { + WMA_LOGE("Failed to get value for WNI_CFG_RTS_THRESHOLD, leaving unchanged"); + } + + if (wlan_cfgGetInt(mac, WNI_CFG_FRAGMENTATION_THRESHOLD, + &cfg_val) == eSIR_SUCCESS) { + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, + cfg_val); + if (ret) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD"); + } else { + WMA_LOGE("Failed to get value for WNI_CFG_FRAGMENTATION_THRESHOLD, leaving unchanged"); + } + + if (wlan_cfgGetInt(mac, WNI_CFG_HT_CAP_INFO, + &cfg_val) == eSIR_SUCCESS) { + val16 = (tANI_U16)cfg_val; + phtCapInfo = (tSirMacHTCapabilityInfo *)&cfg_val; + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + WMI_VDEV_PARAM_TX_STBC, + phtCapInfo->txSTBC); + if (ret) + WMA_LOGE("Failed to set WMI_VDEV_PARAM_TX_STBC"); + } else { + WMA_LOGE("Failed to get value of HT_CAP, TX STBC unchanged"); + } + /* Initialize roaming offload state */ + if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && + (self_sta_req->subType == 0)) { + wma_handle->roam_offload_enabled = TRUE; + wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, + self_sta_req->sessionId, + WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, + (WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG | + WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG)); + } + + /* Initialize BMISS parameters */ + if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && + (self_sta_req->subType == 0)) { + wma_roam_scan_bmiss_cnt(wma_handle, + mac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt, + mac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt, + self_sta_req->sessionId); + } + + if (wlan_cfgGetInt(mac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, + &cfg_val) == eSIR_SUCCESS) { + WMA_LOGD("%s: setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d", + __func__, cfg_val); + ret = wma_set_enable_disable_mcc_adaptive_scheduler(cfg_val); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED"); + } + } else { + WMA_LOGE("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged"); + } + +end: + self_sta_req->status = status; + +#ifdef QCA_IBSS_SUPPORT + if (generateRsp) +#endif + wma_send_msg(wma_handle, WDA_ADD_STA_SELF_RSP, (void *)self_sta_req, 0); + + return txrx_vdev_handle; +} + +static VOS_STATUS wma_wni_cfg_dnld(tp_wma_handle wma_handle) +{ + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + v_VOID_t *file_img = NULL; + v_SIZE_t file_img_sz = 0; + v_VOID_t *cfg_bin = NULL; + v_SIZE_t cfg_bin_sz = 0; + v_BOOL_t status = VOS_FALSE; + v_VOID_t *mac = vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + WMA_LOGD("%s: Enter", __func__); + + if (NULL == mac) { + WMA_LOGP("%s: Invalid context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* get the number of bytes in the CFG Binary... */ + vos_status = vos_get_binary_blob(VOS_BINARY_ID_CONFIG, NULL, + &file_img_sz); + if (VOS_STATUS_E_NOMEM != vos_status) { + WMA_LOGP("%s: Error in obtaining the binary size", __func__); + goto fail; + } + + /* malloc a buffer to read in the Configuration binary file. */ + file_img = vos_mem_malloc(file_img_sz); + if (NULL == file_img) { + WMA_LOGP("%s: Unable to allocate memory for the CFG binary " + "[size= %d bytes]", __func__, file_img_sz); + vos_status = VOS_STATUS_E_NOMEM; + goto fail; + } + + /* Get the entire CFG file image. */ + vos_status = vos_get_binary_blob(VOS_BINARY_ID_CONFIG, file_img, + &file_img_sz); + if (VOS_STATUS_SUCCESS != vos_status) { + WMA_LOGP("%s: Cannot retrieve CFG file image from vOSS " + "[size= %d bytes]", __func__, file_img_sz); + goto fail; + } + + /* + * Validate the binary image. This function will return a pointer + * and length where the CFG binary is located within the binary image file. + */ + status = sys_validateStaConfig( file_img, file_img_sz, + &cfg_bin, &cfg_bin_sz ); + if ( VOS_FALSE == status ) + { + WMA_LOGP("%s: Cannot find STA CFG in binary image file", + __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto fail; + } + /* + * TODO: call the config download function + * for now calling the existing cfg download API + */ + processCfgDownloadReq(mac, cfg_bin_sz, cfg_bin); + if (file_img != NULL) { + vos_mem_free(file_img); + } + + WMA_LOGD("%s: Exit", __func__); + return vos_status; + +fail: + if(cfg_bin != NULL) + vos_mem_free( file_img ); + + WMA_LOGD("%s: Exit", __func__); + return vos_status; +} + +/* function : wma_set_scan_info + * Description : function to save current ongoing scan info + * Args : wma handle, scan id, scan requestor id, vdev id + * Returns : None + */ +static inline void wma_set_scan_info(tp_wma_handle wma_handle, + u_int32_t scan_id, + u_int32_t requestor, + u_int32_t vdev_id, + tSirP2pScanType p2p_scan_type) +{ + wma_handle->interfaces[vdev_id].scan_info.scan_id = scan_id; + wma_handle->interfaces[vdev_id].scan_info.scan_requestor_id = + requestor; + wma_handle->interfaces[vdev_id].scan_info.p2p_scan_type = p2p_scan_type; +} + +/* function : wma_reset_scan_info + * Description : function to reset the current ongoing scan info + * Args : wma handle, vdev_id + * Returns : None + */ +static inline void wma_reset_scan_info(tp_wma_handle wma_handle, + u_int8_t vdev_id) +{ + vos_mem_zero((void *) &(wma_handle->interfaces[vdev_id].scan_info), + sizeof(struct scan_param)); +} + +bool wma_check_scan_in_progress(WMA_HANDLE handle) +{ + tp_wma_handle wma_handle = handle; + int i; + + for (i = 0; i < wma_handle->max_bssid; i++){ + if (wma_handle->interfaces[i].scan_info.scan_id){ + + WMA_LOGE("%s: scan in progress on interface[%d],scanid = %d", + __func__, i, wma_handle->interfaces[i].scan_info.scan_id ); + return true; + } + } + return false; +} + +v_BOOL_t wma_is_SAP_active(tp_wma_handle wma_handle) +{ + int i; + + for (i = 0; i < wma_handle->max_bssid; i++) { + if (!wma_handle->interfaces[i].vdev_up) + continue; + if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_AP && + wma_handle->interfaces[i].sub_type == 0) + return TRUE; + } + return FALSE; +} + +v_BOOL_t wma_is_P2P_GO_active(tp_wma_handle wma_handle) +{ + int i; + + for (i = 0; i < wma_handle->max_bssid; i++) { + if (!wma_handle->interfaces[i].vdev_up) + continue; + if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_AP && + wma_handle->interfaces[i].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) + return TRUE; + } + return FALSE; +} + +v_BOOL_t wma_is_P2P_CLI_active(tp_wma_handle wma_handle) +{ + int i; + + for (i = 0; i < wma_handle->max_bssid; i++) { + if (!wma_handle->interfaces[i].vdev_up) + continue; + if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_STA && + wma_handle->interfaces[i].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) + return TRUE; + } + return FALSE; +} + +v_BOOL_t wma_is_STA_active(tp_wma_handle wma_handle) +{ + int i; + + for (i = 0; i < wma_handle->max_bssid; i++) { + if (!wma_handle->interfaces[i].vdev_up) + continue; + if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_STA && + wma_handle->interfaces[i].sub_type == 0) + return TRUE; + if (wma_handle->interfaces[i].type == WMI_VDEV_TYPE_IBSS) + return TRUE; + } + return FALSE; +} + + +/* function : wma_get_buf_start_scan_cmd + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, + tSirScanOffloadReq *scan_req, + wmi_buf_t *buf, + int *buf_len) +{ + wmi_start_scan_cmd_fixed_param *cmd; + wmi_chan_list *chan_list = NULL; + wmi_mac_addr *bssid; + wmi_ssid *ssid = NULL; + u_int32_t *tmp_ptr, ie_len_with_pad; + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + u_int8_t *buf_ptr; + u_int32_t dwell_time; + u_int8_t SSID_num; + int i; + int len = sizeof(*cmd); + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGP("%s: pMac is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + len += WMI_TLV_HDR_SIZE; /* Length TLV placeholder for array of uint32 */ + /* calculate the length of buffer required */ + if (scan_req->channelList.numChannels) + len += scan_req->channelList.numChannels * sizeof(u_int32_t); + + len += WMI_TLV_HDR_SIZE; /* Length TLV placeholder for array of wmi_ssid structures */ + if (scan_req->numSsid) + len += scan_req->numSsid * sizeof(wmi_ssid); + + len += WMI_TLV_HDR_SIZE; /* Length TLV placeholder for array of wmi_mac_addr structures */ + len += sizeof(wmi_mac_addr); + + len += WMI_TLV_HDR_SIZE; /* Length TLV placeholder for array of bytes */ + if (scan_req->uIEFieldLen) + len += roundup(scan_req->uIEFieldLen, sizeof(u_int32_t)); + + /* Allocate the memory */ + *buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!*buf) { + WMA_LOGP("%s: failed to allocate memory for start scan cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(*buf); + cmd = (wmi_start_scan_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_start_scan_cmd_fixed_param)); + + if (wma_handle->scan_id >= WMA_MAX_SCAN_ID) + wma_handle->scan_id = 0; + + cmd->vdev_id = scan_req->sessionId; + /* host cycles through the lower 12 bits of + wma_handle->scan_id to generate ids */ + cmd->scan_id = WMA_HOST_SCAN_REQID_PREFIX | ++wma_handle->scan_id; + cmd->scan_priority = WMI_SCAN_PRIORITY_LOW; + cmd->scan_req_id = WMA_HOST_SCAN_REQUESTOR_ID_PREFIX | + WMA_DEFAULT_SCAN_REQUESTER_ID; + + /* Set the scan events which the driver is intereseted to receive */ + /* TODO: handle all the other flags also */ + cmd->notify_scan_events = WMI_SCAN_EVENT_STARTED | + WMI_SCAN_EVENT_START_FAILED | + WMI_SCAN_EVENT_FOREIGN_CHANNEL | + WMI_SCAN_EVENT_COMPLETED | + WMI_SCAN_EVENT_DEQUEUED | + WMI_SCAN_EVENT_PREEMPTED | + WMI_SCAN_EVENT_RESTARTED; + + cmd->dwell_time_active = scan_req->maxChannelTime; + + if (scan_req->scanType == eSIR_ACTIVE_SCAN) { + /* In Active scan case, the firmware has to do passive scan on DFS channels + * So the passive scan duration should be updated properly so that the duration + * will be sufficient enough to receive the beacon from AP */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + &dwell_time) != eSIR_SUCCESS) { + WMA_LOGE("Failed to get passive max channel value" + "using default value"); + dwell_time = WMA_DWELL_TIME_PASSIVE_DEFAULT; + } + cmd->dwell_time_passive = dwell_time; + } + else + cmd->dwell_time_passive = scan_req->maxChannelTime; + + WMA_LOGI("Scan Type %x, Active dwell time %u, Passive dwell time %u", + scan_req->scanType, cmd->dwell_time_active, + cmd->dwell_time_passive); + + /* Ensure correct number of probes are sent on active channel */ + cmd->repeat_probe_time = cmd->dwell_time_active / WMA_SCAN_NPROBES_DEFAULT; + + /* CSR sends only one value restTime for staying on home channel + * to continue data traffic. Rome fw has facility to monitor the traffic + * and move to next channel. Stay on the channel for at least half + * of the requested time and then leave if there is no traffic. + */ + cmd->min_rest_time = scan_req->restTime / 2; + cmd->max_rest_time = scan_req->restTime; + + /* Check for traffic at idle_time interval after min_rest_time. + * Default value is 25 ms to allow full use of max_rest_time + * when voice packets are running at 20 ms interval. + */ + cmd->idle_time = WMA_SCAN_IDLE_TIME_DEFAULT; + + /* Large timeout value for full scan cycle, 30 seconds */ + cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; + + /* do not add OFDM rates in 11B mode */ + if (scan_req->dot11mode != WNI_CFG_DOT11_MODE_11B) + cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES; + else + WMA_LOGD("OFDM_RATES not included in 11B mode"); + + /* Do not combine multiple channels in a single burst. Come back + * to home channel for data traffic after every foreign channel. + * By default, prefer throughput performance over scan cycle time. + */ + cmd->burst_duration = 0; + + if (!scan_req->p2pScanType) { + WMA_LOGD("Normal Scan request"); + cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES; + if (!scan_req->numSsid) + cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; + if (scan_req->scanType == eSIR_PASSIVE_SCAN) + cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; + cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; + /* + * Decide burst_duration and dwell_time_active based on + * what type of devices are active. + */ + do { + if (wma_is_SAP_active(wma_handle)) { + /* Background scan while SoftAP is sending beacons. + * Max duration of CTS2self is 32 ms, which limits + * the dwell time. + */ + cmd->dwell_time_active = MIN(scan_req->maxChannelTime, + (WMA_CTS_DURATION_MS_MAX - WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)); + cmd->dwell_time_passive = cmd->dwell_time_active; + cmd->burst_duration = 0; + break; + } + if (wma_is_P2P_GO_active(wma_handle)) { + /* Background scan while GO is sending beacons. + * Every off-channel transition has overhead of 2 beacon + * intervals for NOA. Maximize number of channels in + * every transition by using burst scan. + */ + if (IS_MIRACAST_SESSION_PRESENT(pMac)) { + /* When miracast is running, burst duration + * needs to be minimum to avoid any stutter + * or glitch in miracast during station scan + */ + if (scan_req->maxChannelTime <= + WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION) + cmd->burst_duration = + scan_req->maxChannelTime; + else + cmd->burst_duration = + WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION; + } + else { + /* If miracast is not running, accomodate max + * stations to make the scans faster + */ + cmd->burst_duration = + WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS * + scan_req->maxChannelTime; + if (cmd->burst_duration > + WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { + u_int8_t channels = + WMA_P2P_SCAN_MAX_BURST_DURATION + / scan_req->maxChannelTime; + if (channels) + cmd->burst_duration = channels * + scan_req->maxChannelTime; + else + cmd->burst_duration = + WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION; + } + } + break; + } + if (wma_is_STA_active(wma_handle) || + wma_is_P2P_CLI_active(wma_handle)) { + /* Typical background scan. Disable burst scan for now. */ + cmd->burst_duration = 0; + break; + } + } while (0); + + } + else { + WMA_LOGD("P2P Scan"); + switch (scan_req->p2pScanType) { + case P2P_SCAN_TYPE_LISTEN: + WMA_LOGD("P2P_SCAN_TYPE_LISTEN"); + cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; + cmd->notify_scan_events |= + WMI_SCAN_EVENT_FOREIGN_CHANNEL; + cmd->repeat_probe_time = 0; + break; + case P2P_SCAN_TYPE_SEARCH: + WMA_LOGD("P2P_SCAN_TYPE_SEARCH"); + cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; + /* Default P2P burst duration of 120 ms will cover + * 3 channels with default max dwell time 40 ms. + * Cap limit will be set by + * WMA_P2P_SCAN_MAX_BURST_DURATION. Burst duration + * should be such that no channel is scanned less + * than the dwell time in normal scenarios. + */ + if (scan_req->channelList.numChannels == P2P_SOCIAL_CHANNELS + && (!IS_MIRACAST_SESSION_PRESENT(pMac))) + cmd->repeat_probe_time = scan_req->maxChannelTime/5; + else + cmd->repeat_probe_time = scan_req->maxChannelTime/3; + + cmd->burst_duration = WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS * scan_req->maxChannelTime; + if (cmd->burst_duration > WMA_P2P_SCAN_MAX_BURST_DURATION) { + u_int8_t channels = WMA_P2P_SCAN_MAX_BURST_DURATION / scan_req->maxChannelTime; + if (channels) + cmd->burst_duration = channels * scan_req->maxChannelTime; + else + cmd->burst_duration = WMA_P2P_SCAN_MAX_BURST_DURATION; + } + break; + default: + WMA_LOGE("Invalid scan type"); + goto error; + } + } + + cmd->n_probes = (cmd->repeat_probe_time > 0) ? + cmd->dwell_time_active/cmd->repeat_probe_time : 0; + + buf_ptr += sizeof(*cmd); + tmp_ptr = (u_int32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); + + if (scan_req->channelList.numChannels) { + chan_list = (wmi_chan_list *) tmp_ptr; + cmd->num_chan = scan_req->channelList.numChannels; + for (i = 0; i < scan_req->channelList.numChannels; ++i) { + tmp_ptr[i] = vos_chan_to_freq( + scan_req->channelList.channelNumber[i]); + } + } + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_UINT32, + (cmd->num_chan * sizeof(u_int32_t))); + buf_ptr += WMI_TLV_HDR_SIZE + (cmd->num_chan * sizeof(u_int32_t)); + if (scan_req->numSsid > SIR_SCAN_MAX_NUM_SSID) { + WMA_LOGE("Invalid value for numSsid"); + goto error; + } + cmd->num_ssids = scan_req->numSsid; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, + (cmd->num_ssids * sizeof(wmi_ssid))); + if (scan_req->numSsid) { + ssid = (wmi_ssid *) (buf_ptr + WMI_TLV_HDR_SIZE); + for (i = 0; i < scan_req->numSsid; ++i) { + ssid->ssid_len = scan_req->ssId[i].length; + vos_mem_copy(ssid->ssid, scan_req->ssId[i].ssId, + scan_req->ssId[i].length); + ssid++; + } + } + buf_ptr += WMI_TLV_HDR_SIZE + (cmd->num_ssids * sizeof(wmi_ssid)); + + cmd->num_bssid = 1; + + if (!scan_req->p2pScanType) { + if (wma_is_SAP_active(wma_handle)) { + SSID_num = cmd->num_ssids * cmd->num_bssid; + cmd->repeat_probe_time = + probeTime_dwellTime_map[MIN(SSID_num, + WMA_DWELL_TIME_PROBE_TIME_MAP_SIZE - 1)]. + probe_time; + } + } + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, + (cmd->num_bssid * sizeof(wmi_mac_addr))); + bssid = (wmi_mac_addr *) (buf_ptr + WMI_TLV_HDR_SIZE); + WMI_CHAR_ARRAY_TO_MAC_ADDR(scan_req->bssId, bssid); + buf_ptr += WMI_TLV_HDR_SIZE + (cmd->num_bssid * sizeof(wmi_mac_addr)); + + cmd->ie_len = scan_req->uIEFieldLen; + ie_len_with_pad = roundup(scan_req->uIEFieldLen, sizeof(u_int32_t)); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_with_pad); + if (scan_req->uIEFieldLen) { + vos_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE, + (u_int8_t *)scan_req + + (scan_req->uIEFieldOffset), + scan_req->uIEFieldLen); + } + buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; + + *buf_len = len; + return VOS_STATUS_SUCCESS; +error: + vos_mem_free(*buf); + *buf = NULL; + return vos_status; +} + +/* function : wma_get_buf_stop_scan_cmd + * Description : function to fill the args for wmi_stop_scan_cmd + * Args : wma handle, wmi command buffer, buffer length, vdev_id + * Returns : failure or success + */ +VOS_STATUS wma_get_buf_stop_scan_cmd(tp_wma_handle wma_handle, + wmi_buf_t *buf, + int *buf_len, + tAbortScanParams *abort_scan_req) +{ + wmi_stop_scan_cmd_fixed_param *cmd; + VOS_STATUS vos_status; + int len = sizeof(*cmd); + + /* Allocate the memory */ + *buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!*buf) { + WMA_LOGP("%s: failed to allocate memory for stop scan cmd", + __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + cmd = (wmi_stop_scan_cmd_fixed_param *) wmi_buf_data(*buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_stop_scan_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_stop_scan_cmd_fixed_param)); + cmd->vdev_id = abort_scan_req->SessionId; + cmd->requestor = + wma_handle->interfaces[cmd->vdev_id].scan_info.scan_requestor_id; + cmd->scan_id = wma_handle->interfaces[cmd->vdev_id].scan_info.scan_id; + /* stop the scan with the corresponding scan_id */ + cmd->req_type = WMI_SCAN_STOP_ONE; + + *buf_len = len; + vos_status = VOS_STATUS_SUCCESS; +error: + return vos_status; + +} + +void wma_process_link_status_req(tp_wma_handle wma, + tAniGetLinkStatus *pGetLinkStatus) +{ + wmi_buf_t buf; + wmi_request_stats_cmd_fixed_param *cmd; + u_int8_t len = sizeof(wmi_request_stats_cmd_fixed_param); + struct wma_txrx_node *iface = &wma->interfaces[pGetLinkStatus->sessionId]; + + if (iface->plink_status_req) { + WMA_LOGE( + "%s:previous link status request is pending,deleting the new request", + __func__); + vos_mem_free(pGetLinkStatus); + return; + } + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + goto end; + } + + iface->plink_status_req = pGetLinkStatus; + cmd = (wmi_request_stats_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param)); + cmd->stats_id = WMI_REQUEST_VDEV_RATE_STAT; + cmd->vdev_id = pGetLinkStatus->sessionId; + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_REQUEST_STATS_CMDID)) { + WMA_LOGE("Failed to send WMI link status request to fw"); + wmi_buf_free(buf); + iface->plink_status_req = NULL; + goto end; + } + + return; + +end: + wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY); +} + +VOS_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq, + v_S7_t first_rssi) +{ + wmi_buf_t buf; + wmi_request_stats_cmd_fixed_param *cmd; + u_int8_t len = sizeof(wmi_request_stats_cmd_fixed_param); + tAniGetRssiReq *pRssiBkUp = NULL; + + /* command is in progess */ + if(NULL != wma_handle->pGetRssiReq) + return VOS_STATUS_SUCCESS; + + wma_handle->first_rssi = first_rssi; + + /* create a copy of csrRssiCallback to send rssi value + * after wmi event + */ + if(pGetRssiReq) { + pRssiBkUp = adf_os_mem_alloc(NULL, sizeof(tAniGetRssiReq)); + if(!pRssiBkUp) { + WMA_LOGE("Failed to allocate memory for tAniGetRssiReq"); + wma_handle->pGetRssiReq = NULL; + return VOS_STATUS_E_FAILURE; + } + adf_os_mem_set(pRssiBkUp, 0, sizeof(tAniGetRssiReq)); + pRssiBkUp->sessionId = ((tAniGetRssiReq*)pGetRssiReq)->sessionId; + pRssiBkUp->rssiCallback = ((tAniGetRssiReq*)pGetRssiReq)->rssiCallback; + pRssiBkUp->pDevContext = ((tAniGetRssiReq*)pGetRssiReq)->pDevContext; + wma_handle->pGetRssiReq = (void*)pRssiBkUp; + } + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + adf_os_mem_free(pRssiBkUp); + wma_handle->pGetRssiReq = NULL; + return VOS_STATUS_E_FAILURE; + } + + cmd = (wmi_request_stats_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param)); + cmd->stats_id = WMI_REQUEST_VDEV_STAT; + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,WMI_REQUEST_STATS_CMDID)) { + WMA_LOGE("Failed to send host stats request to fw"); + wmi_buf_free(buf); + adf_os_mem_free(pRssiBkUp); + wma_handle->pGetRssiReq = NULL; + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* function : wma_start_scan + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_start_scan(tp_wma_handle wma_handle, + tSirScanOffloadReq *scan_req, v_U16_t msg_type) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + wmi_start_scan_cmd_fixed_param *cmd; + int status = 0; + int len; + tSirScanOffloadEvent *scan_event; + + if (scan_req->sessionId > wma_handle->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d, msg_type : 0x%x", __func__, + scan_req->sessionId, msg_type); + goto error1; + } + + /* Sanity check to find whether vdev id active or not */ + if (!wma_handle->interfaces[scan_req->sessionId].handle) { + WMA_LOGA("vdev id [%d] is not active", scan_req->sessionId); + goto error1; + } + if (msg_type == WDA_START_SCAN_OFFLOAD_REQ) { + /* Start the timer for scan completion */ + vos_status = vos_timer_start(&wma_handle->wma_scan_comp_timer, + WMA_HW_DEF_SCAN_MAX_DURATION); + if (vos_status != VOS_STATUS_SUCCESS ) { + WMA_LOGE("Failed to start the scan completion timer"); + vos_status = VOS_STATUS_E_FAILURE; + goto error1; + } + } + /* Fill individual elements of wmi_start_scan_req and + * TLV for channel list, bssid, ssid etc ... */ + vos_status = wma_get_buf_start_scan_cmd(wma_handle, scan_req, + &buf, &len); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to get buffer for start scan cmd"); + goto error0; + } + + if (NULL == buf) { + WMA_LOGE("Failed to get buffer for saving current scan info"); + goto error0; + } + + /* Save current scan info */ + cmd = (wmi_start_scan_cmd_fixed_param *) wmi_buf_data(buf); + if (msg_type == WDA_CHNL_SWITCH_REQ) { + /* Adjust parameters for channel switch scan */ + cmd->min_rest_time = WMA_ROAM_PREAUTH_REST_TIME; + cmd->max_rest_time = WMA_ROAM_PREAUTH_REST_TIME; + cmd->max_scan_time = WMA_ROAM_PREAUTH_MAX_SCAN_TIME; + cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH; + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + cmd->scan_id = ( (cmd->scan_id & WMA_MAX_SCAN_ID) | + WMA_HOST_ROAM_SCAN_REQID_PREFIX); + wma_handle->roam_preauth_scan_id = cmd->scan_id; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + } + + wma_set_scan_info(wma_handle, cmd->scan_id, + cmd->scan_req_id, cmd->vdev_id, + scan_req->p2pScanType); + + WMA_LOGE("scan_id %x, vdev_id %x, scan type %x, msg_type %x", + cmd->scan_id, cmd->vdev_id, scan_req->p2pScanType, + msg_type); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_START_SCAN_CMDID); + /* Call the wmi api to request the scan */ + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("WMA --> WMI_START_SCAN_CMDID"); + + /* Update the scan parameters for handler */ + wma_handle->wma_scan_timer_info.vdev_id = cmd->vdev_id; + wma_handle->wma_scan_timer_info.scan_id = cmd->scan_id; + + return VOS_STATUS_SUCCESS; +error: + wma_reset_scan_info(wma_handle, cmd->vdev_id); + if (buf) + adf_nbuf_free(buf); +error0: + /* Stop the timer for scan completion */ + if (vos_timer_stop(&wma_handle->wma_scan_comp_timer) + != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to stop the scan completion timer"); + } +error1: + /* Send completion event for only for start scan request */ + if (msg_type == WDA_START_SCAN_OFFLOAD_REQ) { + scan_event = + (tSirScanOffloadEvent *) vos_mem_malloc(sizeof(tSirScanOffloadEvent)); + if (!scan_event) { + WMA_LOGP("%s: Failed to allocate memory for scan rsp", + __func__); + return VOS_STATUS_E_NOMEM; + } + memset(scan_event, 0x00, sizeof(*scan_event)); + scan_event->event = WMI_SCAN_EVENT_COMPLETED; + scan_event->reasonCode = eSIR_SME_SCAN_FAILED; + scan_event->p2pScanType = scan_req->p2pScanType; + scan_event->sessionId = scan_req->sessionId; + wma_send_msg(wma_handle, WDA_RX_SCAN_EVENT, (void *) scan_event, 0) ; + } + return vos_status; +} + +/* function : wma_stop_scan + * Description : function to send the stop scan command + * Args : wma_handle + * Returns : failure or success + */ +static VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle, + tAbortScanParams *abort_scan_req) +{ + VOS_STATUS vos_status; + wmi_buf_t buf; + int status = 0; + int len; + + vos_status = wma_get_buf_stop_scan_cmd(wma_handle, &buf, &len, + abort_scan_req); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to get buffer for stop scan cmd"); + goto error1; + } + + if (NULL == buf) { + WMA_LOGE("Failed to get buffer for stop scan cmd"); + vos_status = VOS_STATUS_E_FAULT; + goto error1; + } + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_STOP_SCAN_CMDID); + /* Call the wmi api to request the scan */ + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_STOP_SCAN_CMDID returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("WMA --> WMI_STOP_SCAN_CMDID"); + + return VOS_STATUS_SUCCESS; +error: + if (buf) + adf_nbuf_free(buf); +error1: + return vos_status; +} + +/* function : wma_update_channel_list + * Description : Function is used to update the support channel list + * Args : wma_handle, list of supported channels and power + * Returns : SUCCESS or FAILURE + */ +VOS_STATUS wma_update_channel_list(WMA_HANDLE handle, + tSirUpdateChanList *chan_list) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_buf_t buf; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_scan_chan_list_cmd_fixed_param *cmd; + int status, i; + u_int8_t *buf_ptr; + wmi_channel *chan_info; + u_int16_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE; + + len += sizeof(wmi_channel) * chan_list->numChan; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("Failed to allocate memory"); + vos_status = VOS_STATUS_E_NOMEM; + goto end; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_scan_chan_list_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_scan_chan_list_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_scan_chan_list_cmd_fixed_param)); + + WMA_LOGD("no of channels = %d, len = %d", chan_list->numChan, len); + + cmd->num_scan_chans = chan_list->numChan; + WMITLV_SET_HDR((buf_ptr + sizeof(wmi_scan_chan_list_cmd_fixed_param)), + WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_channel) * chan_list->numChan); + chan_info = (wmi_channel *) (buf_ptr + sizeof(*cmd) + WMI_TLV_HDR_SIZE); + + for (i = 0; i < chan_list->numChan; ++i) { + WMITLV_SET_HDR(&chan_info->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + chan_info->mhz = + vos_chan_to_freq(chan_list->chanParam[i].chanId); + chan_info->band_center_freq1 = chan_info->mhz; + chan_info->band_center_freq2 = 0; + + WMA_LOGD("chan[%d] = %u", i, chan_info->mhz); + if (chan_list->chanParam[i].dfsSet) { + WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); + WMA_LOGI("chan[%d] DFS[%d]\n", + chan_list->chanParam[i].chanId, + chan_list->chanParam[i].dfsSet); + } + + if (chan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); + } else { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); + } + + + WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, + chan_list->chanParam[i].pwr); + + WMI_SET_CHANNEL_REG_POWER(chan_info, + chan_list->chanParam[i].pwr); + WMA_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, + chan_list->chanParam[i].pwr); + /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ + /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ + /*TODO: WMI_SET_CHANNEL_REG_CLASSID*/ + chan_info++; + } + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_SCAN_CHAN_LIST_CMDID); + + if (status != EOK) { + vos_status = VOS_STATUS_E_FAILURE; + WMA_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID"); + wmi_buf_free(buf); + } +end: + return vos_status; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +VOS_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle, + wmi_roam_offload_tlv_param *roam_offload_params, + tSirRoamOffloadScanReq *roam_req) +{ + struct sAniSirGlobal *pMac = NULL; + tSirMacCapabilityInfo selfCaps; + tANI_U32 val = 0; + tANI_U32 nCfgValue; + tANI_U16 *pCfgValue16; + tANI_U8 nCfgValue8, *pCfgValue8; + tSirMacQosInfoStation macQosInfoSta; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + tSirMacExtendedHTCapabilityInfo extHtCapInfo; + } uHTCapabilityInfo; + + vos_mem_set(&macQosInfoSta, 0, sizeof(tSirMacQosInfoStation)); + /* Roaming is done only for INFRA STA type. + * So, ess will be one and ibss will be Zero */ + pMac = (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + if (!pMac) { + WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, &val) != + eSIR_SUCCESS){ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_PRIVACY_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + selfCaps.ess = 1; + selfCaps.ibss = 0; + if (val) + selfCaps.privacy = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != + eSIR_SUCCESS){ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_SHORT_PREAMBLE"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.shortPreamble = 1; + + selfCaps.pbcc = 0; + selfCaps.channelAgility = 0; + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, + &val) != eSIR_SUCCESS){ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.shortSlotTime = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_11H_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.spectrumMgt = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_QOS_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.qos = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_APSD_ENABLED, &val) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_APSD_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.apsd = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_RRM_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + if (val) + selfCaps.rrm = 1; + if (wlan_cfgGetInt(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_BLOCK_ACK_ENABLED"); + return VOS_STATUS_E_FAILURE; + } + selfCaps.delayedBA = + (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); + selfCaps.immediateBA = + (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); + pCfgValue16 = (tANI_U16 *)&selfCaps; + roam_offload_params->capability = (*pCfgValue16) & 0xFFFF; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_HT_CAP_INFO"); + return VOS_STATUS_E_FAILURE; + } + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + roam_offload_params->ht_caps_info = + uHTCapabilityInfo.nCfgValue16 & 0xFFFF; + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_HT_AMPDU_PARAMS"); + return VOS_STATUS_E_FAILURE; + } + /* tSirMacHTParametersInfo */ + nCfgValue8 = ( tANI_U8 ) nCfgValue; + roam_offload_params->ampdu_param = (nCfgValue8) & 0xFF; + + val = ROAM_OFFLOAD_NUM_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + (tANI_U8*)roam_offload_params->mcsset, + &val) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_SUPPORTED_MCS_SET"); + return VOS_STATUS_E_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_EXT_HT_CAP_INFO, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_EXT_HT_CAP_INFO"); + return VOS_STATUS_E_FAILURE; + } + /* uHTCapabilityInfo.extHtCapInfo */ + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + roam_offload_params->ht_ext_cap = + uHTCapabilityInfo.nCfgValue16 & 0xFFFF; + + if (wlan_cfgGetInt(pMac, WNI_CFG_TX_BF_CAP, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_TX_BF_CAP"); + return VOS_STATUS_E_FAILURE; + } + /* tSirMacTxBFCapabilityInfo */ + nCfgValue8 = ( tANI_U8 ) nCfgValue; + roam_offload_params->ht_txbf = nCfgValue8 & 0xFF; + if (wlan_cfgGetInt(pMac, WNI_CFG_AS_CAP, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_AS_CAP"); + return VOS_STATUS_E_FAILURE; + } + /* tSirMacASCapabilityInfo */ + nCfgValue8 = ( tANI_U8 ) nCfgValue; + roam_offload_params->asel_cap = nCfgValue8 & 0xFF; + + /* QOS Info */ + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &nCfgValue) != + eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_MAX_SP_LENGTH"); + return VOS_STATUS_E_FAILURE; + } + nCfgValue8 = ( tANI_U8 ) nCfgValue; + macQosInfoSta.maxSpLen = nCfgValue8; + macQosInfoSta.moreDataAck = 0; + macQosInfoSta.qack = 0; + macQosInfoSta.acbe_uapsd = roam_req->AcUapsd.acbe_uapsd; + macQosInfoSta.acbk_uapsd = roam_req->AcUapsd.acbk_uapsd; + macQosInfoSta.acvi_uapsd = roam_req->AcUapsd.acvi_uapsd; + macQosInfoSta.acvo_uapsd = roam_req->AcUapsd.acvo_uapsd; + pCfgValue8 = (tANI_U8 *)&macQosInfoSta; + /* macQosInfoSta Only queue_request is set.Refer to + * PopulateDot11fWMMCaps for more details + */ + roam_offload_params->qos_caps = (*pCfgValue8) & 0xFF; + roam_offload_params->wmm_caps = 0x4 & 0xFF; + return VOS_STATUS_SUCCESS; +} + +#endif +/* function : wma_roam_scan_offload_mode + * Description : send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback + * : of WMI_ROAM_SCAN_MODE. + * Args : scan_cmd_fp contains the scan parameters. + * : mode controls rssi based and periodic scans by roam engine. + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, + wmi_start_scan_cmd_fixed_param *scan_cmd_fp, + tSirRoamOffloadScanReq *roam_req, + u_int32_t mode, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + int auth_mode = WMI_AUTH_NONE; + wmi_roam_offload_tlv_param *roam_offload_params; + wmi_roam_11i_offload_tlv_param *roam_offload_11i; + wmi_roam_11r_offload_tlv_param *roam_offload_11r; + wmi_roam_ese_offload_tlv_param *roam_offload_ese; + if (roam_req) + auth_mode = eCsrAuthType_to_rsn_authmode + (roam_req->ConnectedNetwork.authentication, + roam_req->ConnectedNetwork.encryption); + WMA_LOGD("%s : auth mode = %d",__func__, auth_mode); +#endif + /* Need to create a buf with roam_scan command at + * front and piggyback with scan command */ + len = sizeof(wmi_roam_scan_mode_fixed_param) + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + (2 * WMI_TLV_HDR_SIZE) + +#endif + sizeof(wmi_start_scan_cmd_fixed_param); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (roam_req && roam_req->RoamOffloadEnabled) { + len += sizeof(wmi_roam_offload_tlv_param); + len += WMI_TLV_HDR_SIZE; + if((auth_mode != WMI_AUTH_NONE) && + ((auth_mode != WMI_AUTH_OPEN) || + (auth_mode == WMI_AUTH_OPEN && + roam_req->MDID.mdiePresent) || roam_req->IsESEAssoc)){ + len += WMI_TLV_HDR_SIZE; + if(roam_req->IsESEAssoc) + len += sizeof(wmi_roam_ese_offload_tlv_param); + else if (auth_mode == WMI_AUTH_FT_RSNA || + auth_mode == WMI_AUTH_FT_RSNA_PSK || + (auth_mode == WMI_AUTH_OPEN && + roam_req->MDID.mdiePresent)) + len += sizeof(wmi_roam_11r_offload_tlv_param); + else + len += sizeof(wmi_roam_11i_offload_tlv_param); + } else { + len += WMI_TLV_HDR_SIZE; + } + } else { + if (roam_req) + WMA_LOGD("%s : roam offload = %d", + __func__, roam_req->RoamOffloadEnabled); + else + WMA_LOGD("%s : roam_req is NULL",__func__); + len += (2 * WMI_TLV_HDR_SIZE); + } + if (roam_req && roam_req->RoamOffloadEnabled) { + mode = mode | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; + } +#endif + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&roam_scan_mode_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param)); + + roam_scan_mode_fp->roam_scan_mode = mode; + roam_scan_mode_fp->vdev_id = vdev_id; + /* Fill in scan parameters suitable for roaming scan */ + buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); + vos_mem_copy(buf_ptr, scan_cmd_fp, sizeof(wmi_start_scan_cmd_fixed_param)); + /* Ensure there is no additional IEs */ + scan_cmd_fp->ie_len = 0; + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param)); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + buf_ptr += sizeof(wmi_start_scan_cmd_fixed_param); + if (roam_req && roam_req->RoamOffloadEnabled) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_offload_tlv_param)); + buf_ptr += WMI_TLV_HDR_SIZE; + roam_offload_params = (wmi_roam_offload_tlv_param *) buf_ptr; + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_offload_tlv_param)); + roam_offload_params->prefer_5g = roam_req->Prefer5GHz; + roam_offload_params->rssi_cat_gap = roam_req->RoamRssiCatGap; + roam_offload_params->select_5g_margin = roam_req->Select5GHzMargin; + roam_offload_params->reassoc_failure_timeout = + roam_req->ReassocFailureTimeout; + /* Fill the capabilities */ + wma_roam_scan_fill_self_caps(wma_handle, roam_offload_params, roam_req); + buf_ptr += sizeof(wmi_roam_offload_tlv_param); + /* The TLV's are in the order of 11i, 11R, ESE. Hence, + * they are filled in the same order.Depending on the + * authentication type, the other mode TLV's are nullified + * and only headers are filled.*/ + if ((auth_mode != WMI_AUTH_NONE) && + ((auth_mode != WMI_AUTH_OPEN) || + (auth_mode == WMI_AUTH_OPEN && roam_req->MDID.mdiePresent) || + (roam_req->IsESEAssoc))) { + if (roam_req->IsESEAssoc){ + WMITLV_SET_HDR(buf_ptr,WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_ese_offload_tlv_param)); + buf_ptr += WMI_TLV_HDR_SIZE; + roam_offload_ese = + (wmi_roam_ese_offload_tlv_param *) buf_ptr; + vos_mem_copy (roam_offload_ese->krk, roam_req->KRK, + sizeof(roam_req->KRK)); + vos_mem_copy (roam_offload_ese->btk, roam_req->BTK, + sizeof(roam_req->BTK)); + WMITLV_SET_HDR(&roam_offload_ese->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_ese_offload_tlv_param)); + buf_ptr += sizeof(wmi_roam_ese_offload_tlv_param); + } else if (auth_mode == WMI_AUTH_FT_RSNA || + auth_mode == WMI_AUTH_FT_RSNA_PSK || + (auth_mode == WMI_AUTH_OPEN && + roam_req->MDID.mdiePresent)){ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_11r_offload_tlv_param)); + buf_ptr += WMI_TLV_HDR_SIZE; + roam_offload_11r = + (wmi_roam_11r_offload_tlv_param *) buf_ptr; + roam_offload_11r->r0kh_id_len = roam_req->R0KH_ID_Length; + vos_mem_copy (roam_offload_11r->r0kh_id, roam_req->R0KH_ID, + roam_offload_11r->r0kh_id_len); + vos_mem_copy (roam_offload_11r->psk_msk, roam_req->PSK_PMK, + sizeof(roam_req->PSK_PMK)); + roam_offload_11r->psk_msk_len = roam_req->pmk_len; + roam_offload_11r->mdie_present = roam_req->MDID.mdiePresent; + roam_offload_11r->mdid = roam_req->MDID.mobilityDomain; + if(auth_mode == WMI_AUTH_OPEN) { + /* If FT-Open ensure pmk length + and r0khid len are zero */ + roam_offload_11r->r0kh_id_len = 0; + roam_offload_11r->psk_msk_len = 0; + } + WMITLV_SET_HDR(&roam_offload_11r->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_11r_offload_tlv_param)); + buf_ptr += sizeof(wmi_roam_11r_offload_tlv_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + } else { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_11i_offload_tlv_param)); + buf_ptr += WMI_TLV_HDR_SIZE; + roam_offload_11i = + (wmi_roam_11i_offload_tlv_param *) buf_ptr; + if (roam_req->RoamKeyMgmtOffloadEnabled) { + WMI_SET_ROAM_OFFLOAD_OKC_ENABLED( + roam_offload_11i->flags); + WMA_LOGE("LFR3:OKC Enabled"); + } else { + WMI_SET_ROAM_OFFLOAD_OKC_DISABLED( + roam_offload_11i->flags); + WMA_LOGE("LFR3:OKC Disabled"); + } + + + vos_mem_copy (roam_offload_11i->pmk, roam_req->PSK_PMK, + sizeof(roam_req->PSK_PMK)); + roam_offload_11i->pmk_len = roam_req->pmk_len; + WMITLV_SET_HDR(&roam_offload_11i->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_11i_offload_tlv_param) ); + buf_ptr += sizeof(wmi_roam_11i_offload_tlv_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,0); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,0); + buf_ptr += WMI_TLV_HDR_SIZE; + } + } else { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + } + } else { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + } +#endif + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_SCAN_MODE); + if (status != EOK) { + WMA_LOGE + ("wmi_unified_cmd_send WMI_ROAM_SCAN_MODE returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} + +/* function : wma_roam_scan_offload_rssi_threshold + * Description : Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware + * Args : + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle, + A_INT32 rssi_thresh, + A_INT32 rssi_thresh_diff, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp; + + /* Send rssi threshold */ + len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + rssi_threshold_fp = (wmi_roam_scan_rssi_threshold_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&rssi_threshold_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_roam_scan_rssi_threshold_fixed_param)); + /* fill in threshold values */ + rssi_threshold_fp->vdev_id = vdev_id; + rssi_threshold_fp->roam_scan_rssi_thresh = rssi_thresh & 0x000000ff; + rssi_threshold_fp->roam_rssi_thresh_diff = rssi_thresh_diff & 0x000000ff; + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_SCAN_RSSI_THRESHOLD); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_RSSI_THRESHOLD roam_scan_rssi_thresh=%d, roam_rssi_thresh_diff=%d", + __func__, rssi_thresh, rssi_thresh_diff); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} + +/* function : wma_roam_scan_offload_scan_period + * Description : Send WMI_ROAM_SCAN_PERIOD TLV to firmware + * Args : + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle, + A_UINT32 scan_period, + A_UINT32 scan_age, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + wmi_roam_scan_period_fixed_param *scan_period_fp; + + /* Send scan period values */ + len = sizeof(wmi_roam_scan_period_fixed_param); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + scan_period_fp = (wmi_roam_scan_period_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&scan_period_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_period_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_roam_scan_period_fixed_param)); + /* fill in scan period values */ + scan_period_fp->vdev_id = vdev_id; + scan_period_fp->roam_scan_period = scan_period; /* 20 seconds */ + scan_period_fp->roam_scan_age = scan_age; + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_SCAN_PERIOD); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_PERIOD returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_PERIOD roam_scan_period=%d, roam_scan_age=%d", + __func__, scan_period, scan_age); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} +/* function : wma_roam_scan_offload_rssi_change + * Description : Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD TLV to firmware + * Args : + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle, + A_INT32 rssi_change_thresh, + A_UINT32 bcn_rssi_weight, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + wmi_roam_scan_rssi_change_threshold_fixed_param *rssi_change_fp; + + /* Send rssi change parameters */ + len = sizeof(wmi_roam_scan_rssi_change_threshold_fixed_param); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + rssi_change_fp = (wmi_roam_scan_rssi_change_threshold_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&rssi_change_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_rssi_change_threshold_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_roam_scan_rssi_change_threshold_fixed_param)); + /* fill in rssi change threshold (hysteresis) values */ + rssi_change_fp->vdev_id = vdev_id; + rssi_change_fp->roam_scan_rssi_change_thresh = rssi_change_thresh; + rssi_change_fp->bcn_rssi_weight = bcn_rssi_weight; + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_RSSI_CHANGE_THERSHOLD roam_scan_rssi_change_thresh=%d, bcn_rssi_weight=%d", + __func__, rssi_change_thresh, bcn_rssi_weight); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} + +/* function : wma_roam_scan_offload_chan_list + * Description : Send WMI_ROAM_CHAN_LIST TLV to firmware + * Args : + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, + u_int8_t chan_count, + u_int8_t *chan_list, + u_int8_t list_type, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len, list_tlv_len; + int i; + u_int8_t *buf_ptr; + wmi_roam_chan_list_fixed_param *chan_list_fp; + A_UINT32 *roam_chan_list_array; + + if (chan_count == 0) + { + WMA_LOGD("%s : invalid number of channels %d", __func__, chan_count); + return VOS_STATUS_E_INVAL; + } + /* Channel list is a table of 2 TLV's */ + list_tlv_len = WMI_TLV_HDR_SIZE + chan_count * sizeof(A_UINT32); + len = sizeof(wmi_roam_chan_list_fixed_param) + list_tlv_len; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + chan_list_fp = (wmi_roam_chan_list_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&chan_list_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_chan_list_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_chan_list_fixed_param)); + chan_list_fp->vdev_id = vdev_id; + chan_list_fp->num_chan = chan_count; + if (chan_count > 0 && list_type == CHANNEL_LIST_STATIC) { + /* external app is controlling channel list */ + chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; + } else { + /* umac supplied occupied channel list in LFR */ + chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; + } + + buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (chan_list_fp->num_chan * sizeof(u_int32_t))); + roam_chan_list_array = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); + WMA_LOGI("%s: %d channels = ", __func__, chan_list_fp->num_chan); + for (i = 0; ((i < chan_list_fp->num_chan) && + (i < SIR_ROAM_MAX_CHANNELS)); i++) { + roam_chan_list_array[i] = vos_chan_to_freq(chan_list[i]); + WMA_LOGI("%d,",roam_chan_list_array[i]); + } + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_CHAN_LIST); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_CHAN_LIST returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_CHAN_LIST", __func__); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} + +/* function : eCsrAuthType_to_rsn_authmode + * Description : Map CSR's authentication type into RSN auth mode used by firmware + * Args : + * Returns : + */ + + +A_UINT32 eCsrAuthType_to_rsn_authmode (eCsrAuthType authtype, eCsrEncryptionType encr) { + switch(authtype) { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + return (WMI_AUTH_OPEN); + case eCSR_AUTH_TYPE_WPA: + return (WMI_AUTH_WPA); + case eCSR_AUTH_TYPE_WPA_PSK: + return (WMI_AUTH_WPA_PSK); + case eCSR_AUTH_TYPE_RSN: + return (WMI_AUTH_RSNA); + case eCSR_AUTH_TYPE_RSN_PSK: + return (WMI_AUTH_RSNA_PSK); +#if defined WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: + return (WMI_AUTH_FT_RSNA); + case eCSR_AUTH_TYPE_FT_RSN_PSK: + return (WMI_AUTH_FT_RSNA_PSK); +#endif +#ifdef FEATURE_WLAN_WAPI + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + return (WMI_AUTH_WAPI); + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + return(WMI_AUTH_WAPI_PSK); +#endif +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: + case eCSR_AUTH_TYPE_CCKM_RSN: + return (WMI_AUTH_CCKM); +#endif +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + return (WMI_AUTH_RSNA_PSK_SHA256); + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: + return (WMI_AUTH_RSNA_8021X_SHA256); +#endif + case eCSR_AUTH_TYPE_NONE: + case eCSR_AUTH_TYPE_AUTOSWITCH: + /* In case of WEP and other keys, NONE means OPEN auth */ + if (encr == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY || + encr == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY || + encr == eCSR_ENCRYPT_TYPE_WEP40 || + encr == eCSR_ENCRYPT_TYPE_WEP104 || + encr == eCSR_ENCRYPT_TYPE_TKIP || + encr == eCSR_ENCRYPT_TYPE_AES) { + return (WMI_AUTH_OPEN); + } + return(WMI_AUTH_NONE); + default: + return(WMI_AUTH_NONE); + } +} + +/* function : eCsrEncryptionType_to_rsn_cipherset + * Description : Map CSR's encryption type into RSN cipher types used by firmware + * Args : + * Returns : + */ + +A_UINT32 eCsrEncryptionType_to_rsn_cipherset (eCsrEncryptionType encr) { + + switch (encr) { + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + return (WMI_CIPHER_WEP); + case eCSR_ENCRYPT_TYPE_TKIP: + return (WMI_CIPHER_TKIP); + case eCSR_ENCRYPT_TYPE_AES: + return (WMI_CIPHER_AES_CCM); +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + return (WMI_CIPHER_WAPI); +#endif /* FEATURE_WLAN_WAPI */ + case eCSR_ENCRYPT_TYPE_ANY: + return (WMI_CIPHER_ANY); + case eCSR_ENCRYPT_TYPE_NONE: + default: + return (WMI_CIPHER_NONE); + } +} + +/* function : wma_roam_scan_fill_ap_profile + * Description : Fill ap_profile structure from configured parameters + * Args : + * Returns : + */ +v_VOID_t wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle, tpAniSirGlobal pMac, + tSirRoamOffloadScanReq *roam_req, wmi_ap_profile *ap_profile_p) +{ + vos_mem_zero(ap_profile_p, sizeof(wmi_ap_profile)); + if (roam_req == NULL) { + ap_profile_p->ssid.ssid_len = 0; + ap_profile_p->ssid.ssid[0] = 0; + ap_profile_p->rsn_authmode = WMI_AUTH_NONE; + ap_profile_p->rsn_ucastcipherset = WMI_CIPHER_NONE; + ap_profile_p->rsn_mcastcipherset = WMI_CIPHER_NONE; + ap_profile_p->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE; + ap_profile_p->rssi_threshold = WMA_ROAM_RSSI_DIFF_DEFAULT; + } else { + ap_profile_p->ssid.ssid_len = roam_req->ConnectedNetwork.ssId.length; + vos_mem_copy(ap_profile_p->ssid.ssid, roam_req->ConnectedNetwork.ssId.ssId, + ap_profile_p->ssid.ssid_len); + ap_profile_p->rsn_authmode = + eCsrAuthType_to_rsn_authmode(roam_req->ConnectedNetwork.authentication, + roam_req->ConnectedNetwork.encryption); + ap_profile_p->rsn_ucastcipherset = + eCsrEncryptionType_to_rsn_cipherset(roam_req->ConnectedNetwork.encryption); + ap_profile_p->rsn_mcastcipherset = + eCsrEncryptionType_to_rsn_cipherset(roam_req->ConnectedNetwork.mcencryption); + ap_profile_p->rsn_mcastmgmtcipherset = ap_profile_p->rsn_mcastcipherset; + ap_profile_p->rssi_threshold = roam_req->RoamRssiDiff; + } +} + +/* function : wma_roam_scan_scan_params + * Description : Fill scan_params structure from configured parameters + * Args : roam_req pointer = NULL if this routine is called before connect + * : It will be non-NULL if called after assoc. + * Returns : + */ +v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, + tpAniSirGlobal pMac, + tSirRoamOffloadScanReq *roam_req, + wmi_start_scan_cmd_fixed_param *scan_params) +{ + tANI_U8 channels_per_burst = 0; + tANI_U32 val = 0; + + if (NULL == pMac) { + WMA_LOGE("%s: pMac is NULL", __func__); + return; + } + + vos_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param)); + scan_params->scan_ctrl_flags = WMI_SCAN_ADD_CCK_RATES | + WMI_SCAN_ADD_OFDM_RATES; + if (roam_req != NULL) { + /* Parameters updated after association is complete */ + WMA_LOGI("%s: Input parameters: NeighborScanChannelMinTime" + " = %d, NeighborScanChannelMaxTime = %d", + __func__, + roam_req->NeighborScanChannelMinTime, + roam_req->NeighborScanChannelMaxTime); + WMA_LOGI("%s: Input parameters: NeighborScanTimerPeriod =" + " %d, HomeAwayTime = %d, nProbes = %d", + __func__, + roam_req->NeighborScanTimerPeriod, + roam_req->HomeAwayTime, + roam_req->nProbes); + + /* + * roam_req->NeighborScanChannelMaxTime = SCAN_CHANNEL_TIME + * roam_req->HomeAwayTime = SCAN_HOME_AWAY_TIME + * roam_req->NeighborScanTimerPeriod = SCAN_HOME_TIME + * + * scan_params->dwell_time_active = time station stays on channel + * and sends probes; + * scan_params->dwell_time_passive = time station stays on channel + * and listens probes; + * scan_params->burst_duration = time station goes off channel + * to scan; + */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value from CFG. Log error. + */ + WMA_LOGE("could not retrieve passive max channel value"); + + /* use a default value of 110ms */ + val = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT; + } + + scan_params->dwell_time_passive = val; + /* + * Here is the formula, + * T(HomeAway) = N * T(dwell) + (N+1) * T(cs) + * where N is number of channels scanned in single burst + */ + scan_params->dwell_time_active = roam_req->NeighborScanChannelMaxTime; + if (roam_req->HomeAwayTime < 2*WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) { + /* clearly we can't follow home away time. + * Make it a split scan. + */ + scan_params->burst_duration = 0; + } else { + channels_per_burst = + (roam_req->HomeAwayTime - WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) + / ( scan_params->dwell_time_active + WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME); + + if (channels_per_burst < 1) { + // dwell time and home away time conflicts + // we will override dwell time + scan_params->dwell_time_active = + roam_req->HomeAwayTime - 2*WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME; + scan_params->burst_duration = scan_params->dwell_time_active; + } else { + scan_params->burst_duration = + channels_per_burst * scan_params->dwell_time_active; + } + } + if (roam_req->allowDFSChannelRoam == SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL && + roam_req->HomeAwayTime > 0 && + roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) { + /* Roaming on DFS channels is supported and it is not app channel list. + * It is ok to override homeAwayTime to accomodate DFS dwell time in burst + * duration. + */ + scan_params->burst_duration = MAX(scan_params->burst_duration, + scan_params->dwell_time_passive); + } + scan_params->min_rest_time = roam_req->NeighborScanTimerPeriod; + scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod; + scan_params->repeat_probe_time = (roam_req->nProbes > 0) ? + VOS_MAX(scan_params->dwell_time_active / roam_req->nProbes, 1) : 0; + scan_params->probe_spacing_time = 0; + scan_params->probe_delay = 0; + scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; /* 30 seconds for full scan cycle */ + scan_params->idle_time = scan_params->min_rest_time; + scan_params->n_probes = roam_req->nProbes; + if (roam_req->allowDFSChannelRoam == SIR_ROAMING_DFS_CHANNEL_DISABLED) { + scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN; + } else { + /* Roaming scan on DFS channel is allowed. + * No need to change any flags for default allowDFSChannelRoam = 1. + * Special case where static channel list is given by application + * that contains DFS channels. Assume that the application + * has knowledge of matching APs being active and that + * probe request transmission is permitted on those channel. + * Force active scans on those channels. + */ + + if (roam_req->allowDFSChannelRoam == + SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE && + roam_req->ChannelCacheType == CHANNEL_LIST_STATIC && + roam_req->ConnectedNetwork.ChannelCount > 0) { + scan_params->scan_ctrl_flags |= + WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS; + } + } + } else { + /* roam_req = NULL during initial or pre-assoc invocation */ + scan_params->dwell_time_active = WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT; + scan_params->dwell_time_passive = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT; + scan_params->min_rest_time = WMA_ROAM_MIN_REST_TIME_DEFAULT; + scan_params->max_rest_time = WMA_ROAM_MAX_REST_TIME_DEFAULT; + scan_params->repeat_probe_time = 0; + scan_params->probe_spacing_time = 0; + scan_params->probe_delay = 0; + scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; + scan_params->idle_time = scan_params->min_rest_time; + scan_params->burst_duration = 0; + scan_params->n_probes = 0; + } + + WMA_LOGI("%s: Rome roam scan parameters:" + " dwell_time_active = %d, dwell_time_passive = %d", + __func__, + scan_params->dwell_time_active, + scan_params->dwell_time_passive); + WMA_LOGI("%s: min_rest_time = %d, max_rest_time = %d," + " repeat_probe_time = %d n_probes = %d", + __func__, + scan_params->min_rest_time, + scan_params->max_rest_time, + scan_params->repeat_probe_time, + scan_params->n_probes); + WMA_LOGI("%s: max_scan_time = %d, idle_time = %d," + " burst_duration = %d, scan_ctrl_flags = 0x%x", + __func__, + scan_params->max_scan_time, + scan_params->idle_time, + scan_params->burst_duration, + scan_params->scan_ctrl_flags); +} + +/* function : wma_roam_scan_offload_ap_profile + * Description : Send WMI_ROAM_AP_PROFILE TLV to firmware + * Args : AP profile parameters are passed in as the structure used in TLV + * Returns : + */ +VOS_STATUS wma_roam_scan_offload_ap_profile(tp_wma_handle wma_handle, + wmi_ap_profile *ap_profile_p, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + wmi_roam_ap_profile_fixed_param *roam_ap_profile_fp; + + len = sizeof(wmi_roam_ap_profile_fixed_param) + + sizeof(wmi_ap_profile); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + roam_ap_profile_fp = (wmi_roam_ap_profile_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&roam_ap_profile_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_ap_profile_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_roam_ap_profile_fixed_param)); + /* fill in threshold values */ + roam_ap_profile_fp->vdev_id = vdev_id; + roam_ap_profile_fp->id = 0; + buf_ptr += sizeof(wmi_roam_ap_profile_fixed_param); + + vos_mem_copy(buf_ptr, ap_profile_p, sizeof(wmi_ap_profile)); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_STRUC_wmi_ap_profile, + WMITLV_GET_STRUCT_TLVLEN( + wmi_ap_profile)); + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_AP_PROFILE); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_AP_PROFILE returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("WMA --> WMI_ROAM_AP_PROFILE and other parameters"); + return VOS_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + + return vos_status; +} + +VOS_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle, + u_int32_t command, + u_int32_t vdev_id) +{ + VOS_STATUS vos_status; + wmi_roam_scan_cmd_fixed_param *cmd_fp; + wmi_buf_t buf = NULL; + int status = 0; + int len; + u_int8_t *buf_ptr; + + len = sizeof(wmi_roam_scan_cmd_fixed_param); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + + cmd_fp = (wmi_roam_scan_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_cmd_fixed_param)); + cmd_fp->vdev_id = vdev_id; + cmd_fp->command_arg = command; + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_ROAM_SCAN_CMD); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_ROAM_SCAN_CMD returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + WMA_LOGI("%s: WMA --> WMI_ROAM_SCAN_CMD", __func__); + return VOS_STATUS_SUCCESS; + +error: + wmi_buf_free(buf); + + return vos_status; +} + +/* function : wma_process_roam_scan_req + * Description : Main routine to handle ROAM commands coming from CSR module. + * Args : + * Returns : + */ +VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, + tSirRoamOffloadScanReq *roam_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_start_scan_cmd_fixed_param scan_params; + wmi_ap_profile ap_profile; + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + u_int32_t mode = 0; + struct wma_txrx_node *intr = NULL; + + WMA_LOGI("%s: command 0x%x, reason %d", __func__, roam_req->Command, + roam_req->StartScanReason); + + if (NULL == pMac) + { + WMA_LOGE("%s: pMac is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (!wma_handle->roam_offload_enabled) { + /* roam scan offload is not enabled in firmware. + * Cannot initialize it in the middle of connection. + */ + vos_mem_free(roam_req); + return VOS_STATUS_E_PERM; + } + switch (roam_req->Command) { + case ROAM_SCAN_OFFLOAD_START: + intr = &wma_handle->interfaces[roam_req->sessionId]; + intr->delay_before_vdev_stop = roam_req->delay_before_vdev_stop; + /* + * Scan/Roam threshold parameters are translated from fields of tSirRoamOffloadScanReq + * to WMITLV values sent to Rome firmware. + * some of these parameters are configurable in qcom_cfg.ini file. + */ + + /* First parameter is positive rssi value to trigger rssi based scan. + * Opportunistic scan is started at 30 dB higher that trigger rssi. + */ + wma_handle->suitable_ap_hb_failure = FALSE; + + vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, + (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT), + roam_req->OpportunisticScanThresholdDiff, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + vos_status = wma_roam_scan_bmiss_cnt(wma_handle, + roam_req->RoamBmissFirstBcnt, roam_req->RoamBmissFinalBcnt, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + /* Opportunistic scan runs on a timer, value set by EmptyRefreshScanPeriod. + * Age out the entries after 3 such cycles. + */ + if (roam_req->EmptyRefreshScanPeriod > 0) { + vos_status = wma_roam_scan_offload_scan_period(wma_handle, + roam_req->EmptyRefreshScanPeriod, + roam_req->EmptyRefreshScanPeriod * 3, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + mode = WMI_ROAM_SCAN_MODE_PERIODIC; + /* Don't use rssi triggered roam scans if external app + * is in control of channel list. + */ + if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) { + mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } + } else { + mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } + + /* Start new rssi triggered scan only if it changes by RoamRssiDiff value. + * Beacon weight of 14 means average rssi is taken over 14 previous samples + + * 2 times the current beacon's rssi. + */ + vos_status = wma_roam_scan_offload_rssi_change(wma_handle, + roam_req->RoamRescanRssiDiff, + roam_req->RoamBeaconRssiWeight, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req, &ap_profile); + + vos_status = wma_roam_scan_offload_ap_profile(wma_handle, + &ap_profile, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + vos_status = wma_roam_scan_offload_chan_list(wma_handle, + roam_req->ConnectedNetwork.ChannelCount, + &roam_req->ConnectedNetwork.ChannelCache[0], + roam_req->ChannelCacheType, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + + wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params); + vos_status = wma_roam_scan_offload_mode(wma_handle, + &scan_params, + roam_req, + mode, + roam_req->sessionId); + break; + + case ROAM_SCAN_OFFLOAD_STOP: + wma_handle->suitable_ap_hb_failure = FALSE; + if (wma_handle->roam_offload_enabled) { + + wma_roam_scan_fill_scan_params(wma_handle, pMac, + NULL, &scan_params); + vos_status = wma_roam_scan_offload_mode(wma_handle, + &scan_params, + NULL, + WMI_ROAM_SCAN_MODE_NONE, + roam_req->sessionId); + } + + if (roam_req->StartScanReason == REASON_OS_REQUESTED_ROAMING_NOW) { + vos_msg_t vosMsg; + tSirRoamOffloadScanRsp *scan_offload_rsp; + scan_offload_rsp = vos_mem_malloc(sizeof(*scan_offload_rsp)); + if (!scan_offload_rsp) { + WMA_LOGE("%s: Alloc failed for scan_offload_rsp", __func__); + vos_mem_free(roam_req); + return VOS_STATUS_E_NOMEM; + } + vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP; + scan_offload_rsp->sessionId = roam_req->sessionId; + scan_offload_rsp->reason = roam_req->StartScanReason; + vosMsg.bodyptr = scan_offload_rsp; + /* + * Since REASSOC request is processed in Roam_Scan_Offload_Rsp + * post a dummy rsp msg back to SME with proper reason code. + */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, + (vos_msg_t*)&vosMsg)) + { + vos_mem_free(scan_offload_rsp); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Failed to post Scan Offload Rsp to UMAC", + __func__); + } + } + break; + + case ROAM_SCAN_OFFLOAD_ABORT_SCAN: + /* If roam scan is running, stop that cycle. + * It will continue automatically on next trigger. + */ + vos_status = wma_roam_scan_offload_command(wma_handle, + WMI_ROAM_SCAN_STOP_CMD, + roam_req->sessionId); + break; + + case ROAM_SCAN_OFFLOAD_RESTART: + /* Rome offload engine does not stop after any scan. + * If this command is sent because all preauth attempts failed + * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier, + * now it is time to call it heartbeat failure. + */ + if ((roam_req->StartScanReason == REASON_PREAUTH_FAILED_FOR_ALL) + && wma_handle->suitable_ap_hb_failure) { + WMA_LOGE("%s: Sending heartbeat failure after preauth failures", + __func__); + wma_beacon_miss_handler(wma_handle, roam_req->sessionId); + wma_handle->suitable_ap_hb_failure = FALSE; + } + break; + + case ROAM_SCAN_OFFLOAD_UPDATE_CFG: + wma_handle->suitable_ap_hb_failure = FALSE; + wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params); + vos_status = wma_roam_scan_offload_mode(wma_handle, + &scan_params, + roam_req, + WMI_ROAM_SCAN_MODE_NONE, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + if (roam_req->RoamScanOffloadEnabled == FALSE) { + break; + } + + vos_status = wma_roam_scan_bmiss_cnt(wma_handle, + roam_req->RoamBmissFirstBcnt, roam_req->RoamBmissFinalBcnt, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + /* + * Runtime (after association) changes to rssi thresholds and other parameters. + */ + vos_status = wma_roam_scan_offload_chan_list(wma_handle, + roam_req->ConnectedNetwork.ChannelCount, + &roam_req->ConnectedNetwork.ChannelCache[0], + roam_req->ChannelCacheType, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, + (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT), + roam_req->OpportunisticScanThresholdDiff, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + if (roam_req->EmptyRefreshScanPeriod > 0) { + vos_status = wma_roam_scan_offload_scan_period(wma_handle, + roam_req->EmptyRefreshScanPeriod, + roam_req->EmptyRefreshScanPeriod * 3, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + mode = WMI_ROAM_SCAN_MODE_PERIODIC; + /* Don't use rssi triggered roam scans if external app + * is in control of channel list. + */ + if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) { + mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } + } else { + mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } + + vos_status = wma_roam_scan_offload_rssi_change(wma_handle, + roam_req->RoamRescanRssiDiff, + roam_req->RoamBeaconRssiWeight, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req, &ap_profile); + vos_status = wma_roam_scan_offload_ap_profile(wma_handle, + &ap_profile, + roam_req->sessionId); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + + wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params); + vos_status = wma_roam_scan_offload_mode( + wma_handle, + &scan_params, + roam_req, + mode, + roam_req->sessionId); + + break; + + default: + break; + } + vos_mem_free(roam_req); + return vos_status; +} + +#ifdef FEATURE_WLAN_LPHB +/* function : wma_lphb_conf_hbenable + * Description : handles the enable command of LPHB configuration requests + * Args : wma_handle - WMA handle + * lphb_conf_req - configuration info + * by_user - whether this call is from user or cached resent + * Returns : + */ +VOS_STATUS wma_lphb_conf_hbenable(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req, + v_BOOL_t by_user) + +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int status = 0; + tSirLPHBEnableStruct *ts_lphb_enable; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_hb_set_enable_cmd_fixed_param *hb_enable_fp; + int len = sizeof(wmi_hb_set_enable_cmd_fixed_param); + int i; + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + ts_lphb_enable = &(lphb_conf_req->params.lphbEnableReq); + WMA_LOGI("%s: WMA --> WMI_HB_SET_ENABLE enable=%d, item=%d, session=%d", + __func__, + ts_lphb_enable->enable, + ts_lphb_enable->item, + ts_lphb_enable->session); + + if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) { + WMA_LOGE("%s : LPHB configuration wrong item %d", + __func__, + ts_lphb_enable->item); + return VOS_STATUS_E_FAILURE; + } + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + hb_enable_fp = (wmi_hb_set_enable_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&hb_enable_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_hb_set_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_hb_set_enable_cmd_fixed_param)); + + /* fill in values */ + hb_enable_fp->vdev_id = ts_lphb_enable->session; + hb_enable_fp->enable= ts_lphb_enable->enable; + hb_enable_fp->item = ts_lphb_enable->item; + hb_enable_fp->session = ts_lphb_enable->session; + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HB_SET_ENABLE_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_ENABLE returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + if (by_user) { + /* target already configured, now cache command status */ + if (ts_lphb_enable->enable) { + i = ts_lphb_enable->item-1; + wma_handle->wow.lphb_cache[i].cmd + = LPHB_SET_EN_PARAMS_INDID; + wma_handle->wow.lphb_cache[i].params.lphbEnableReq.enable + = ts_lphb_enable->enable; + wma_handle->wow.lphb_cache[i].params.lphbEnableReq.item + = ts_lphb_enable->item; + wma_handle->wow.lphb_cache[i].params.lphbEnableReq.session + = ts_lphb_enable->session; + + WMA_LOGI("%s: cached LPHB status in WMA context for item %d", + __func__, i); + } else { + vos_mem_zero((void *)&wma_handle->wow.lphb_cache, + sizeof(wma_handle->wow.lphb_cache)); + WMA_LOGI("%s: cleared all cached LPHB status in WMA context", + __func__); + } + } + + return VOS_STATUS_SUCCESS; +error: + return vos_status; +} + +/* function : wma_lphb_conf_tcp_params + * Description : handles the tcp params command of LPHB configuration requests + * Args : + * Returns : + */ +VOS_STATUS wma_lphb_conf_tcp_params(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int status = 0; + tSirLPHBTcpParamStruct *ts_lphb_tcp_param; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_hb_set_tcp_params_cmd_fixed_param *hb_tcp_params_fp; + int len = sizeof(wmi_hb_set_tcp_params_cmd_fixed_param); + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + ts_lphb_tcp_param = &(lphb_conf_req->params.lphbTcpParamReq); + WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, dev_ip=%08x, src_port=%d, " + "dst_port=%d, timeout=%d, session=%d, gateway_mac=%02x:%02x:%02x:%02x:%02x:%02x, " + "timePeriodSec=%d, tcpSn=%d", + __func__, + ts_lphb_tcp_param->srv_ip, ts_lphb_tcp_param->dev_ip, + ts_lphb_tcp_param->src_port, ts_lphb_tcp_param->dst_port, + ts_lphb_tcp_param->timeout, ts_lphb_tcp_param->session, + ts_lphb_tcp_param->gateway_mac[0], + ts_lphb_tcp_param->gateway_mac[1], + ts_lphb_tcp_param->gateway_mac[2], + ts_lphb_tcp_param->gateway_mac[3], + ts_lphb_tcp_param->gateway_mac[4], + ts_lphb_tcp_param->gateway_mac[5], + ts_lphb_tcp_param->timePeriodSec, ts_lphb_tcp_param->tcpSn); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + hb_tcp_params_fp = (wmi_hb_set_tcp_params_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&hb_tcp_params_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_hb_set_tcp_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_hb_set_tcp_params_cmd_fixed_param)); + + /* fill in values */ + hb_tcp_params_fp->vdev_id = ts_lphb_tcp_param->session; + hb_tcp_params_fp->srv_ip = ts_lphb_tcp_param->srv_ip; + hb_tcp_params_fp->dev_ip = ts_lphb_tcp_param->dev_ip; + hb_tcp_params_fp->seq = ts_lphb_tcp_param->tcpSn; + hb_tcp_params_fp->src_port = ts_lphb_tcp_param->src_port; + hb_tcp_params_fp->dst_port = ts_lphb_tcp_param->dst_port; + hb_tcp_params_fp->interval = ts_lphb_tcp_param->timePeriodSec; + hb_tcp_params_fp->timeout = ts_lphb_tcp_param->timeout; + hb_tcp_params_fp->session = ts_lphb_tcp_param->session; + WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac, &hb_tcp_params_fp->gateway_mac); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HB_SET_TCP_PARAMS_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PARAMS returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + return VOS_STATUS_SUCCESS; +error: + return vos_status; +} + +/* function : wma_lphb_conf_tcp_pkt_filter + * Description : handles the tcp packet filter command of LPHB configuration requests + * Args : + * Returns : + */ +VOS_STATUS wma_lphb_conf_tcp_pkt_filter(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int status = 0; + tSirLPHBTcpFilterStruct *ts_lphb_tcp_filter; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *hb_tcp_filter_fp; + int len = sizeof(wmi_hb_set_tcp_pkt_filter_cmd_fixed_param); + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + ts_lphb_tcp_filter = &(lphb_conf_req->params.lphbTcpFilterReq); + WMA_LOGI("%s: WMA --> WMI_HB_SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, " + "filter=%2x:%2x:%2x:%2x:%2x:%2x ...", + __func__, + ts_lphb_tcp_filter->length, + ts_lphb_tcp_filter->offset, + ts_lphb_tcp_filter->session, + ts_lphb_tcp_filter->filter[0], + ts_lphb_tcp_filter->filter[1], + ts_lphb_tcp_filter->filter[2], + ts_lphb_tcp_filter->filter[3], + ts_lphb_tcp_filter->filter[4], + ts_lphb_tcp_filter->filter[5]); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + hb_tcp_filter_fp = (wmi_hb_set_tcp_pkt_filter_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&hb_tcp_filter_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_hb_set_tcp_pkt_filter_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_hb_set_tcp_pkt_filter_cmd_fixed_param)); + + /* fill in values */ + hb_tcp_filter_fp->vdev_id = ts_lphb_tcp_filter->session; + hb_tcp_filter_fp->length = ts_lphb_tcp_filter->length; + hb_tcp_filter_fp->offset = ts_lphb_tcp_filter->offset; + hb_tcp_filter_fp->session = ts_lphb_tcp_filter->session; + memcpy((void *) &hb_tcp_filter_fp->filter, (void *) &ts_lphb_tcp_filter->filter, + WMI_WLAN_HB_MAX_FILTER_SIZE); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HB_SET_TCP_PKT_FILTER_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_TCP_PKT_FILTER returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + return VOS_STATUS_SUCCESS; +error: + return vos_status; +} + +/* function : wma_lphb_conf_udp_params + * Description : handles the udp params command of LPHB configuration requests + * Args : + * Returns : + */ +VOS_STATUS wma_lphb_conf_udp_params(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int status = 0; + tSirLPHBUdpParamStruct *ts_lphb_udp_param; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_hb_set_udp_params_cmd_fixed_param *hb_udp_params_fp; + int len = sizeof(wmi_hb_set_udp_params_cmd_fixed_param); + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + ts_lphb_udp_param = &(lphb_conf_req->params.lphbUdpParamReq); + WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, " + "dst_port=%d, interval=%d, timeout=%d, session=%d, " + "gateway_mac=%2x:%2x:%2x:%2x:%2x:%2x", + __func__, + ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip, + ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port, + ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout, ts_lphb_udp_param->session, + ts_lphb_udp_param->gateway_mac[0], + ts_lphb_udp_param->gateway_mac[1], + ts_lphb_udp_param->gateway_mac[2], + ts_lphb_udp_param->gateway_mac[3], + ts_lphb_udp_param->gateway_mac[4], + ts_lphb_udp_param->gateway_mac[5]); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + hb_udp_params_fp = (wmi_hb_set_udp_params_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&hb_udp_params_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_hb_set_udp_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_hb_set_udp_params_cmd_fixed_param)); + + /* fill in values */ + hb_udp_params_fp->vdev_id = ts_lphb_udp_param->session; + hb_udp_params_fp->srv_ip = ts_lphb_udp_param->srv_ip; + hb_udp_params_fp->dev_ip = ts_lphb_udp_param->dev_ip; + hb_udp_params_fp->src_port = ts_lphb_udp_param->src_port; + hb_udp_params_fp->dst_port = ts_lphb_udp_param->dst_port; + hb_udp_params_fp->interval = ts_lphb_udp_param->interval; + hb_udp_params_fp->timeout = ts_lphb_udp_param->timeout; + hb_udp_params_fp->session = ts_lphb_udp_param->session; + WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac, &hb_udp_params_fp->gateway_mac); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HB_SET_UDP_PARAMS_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PARAMS returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + return VOS_STATUS_SUCCESS; +error: + return vos_status; +} + +/* function : wma_lphb_conf_udp_pkt_filter + * Description : handles the udp packet filter command of LPHB configuration requests + * Args : + * Returns : + */ +VOS_STATUS wma_lphb_conf_udp_pkt_filter(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int status = 0; + tSirLPHBUdpFilterStruct *ts_lphb_udp_filter; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_hb_set_udp_pkt_filter_cmd_fixed_param *hb_udp_filter_fp; + int len = sizeof(wmi_hb_set_udp_pkt_filter_cmd_fixed_param); + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + ts_lphb_udp_filter = &(lphb_conf_req->params.lphbUdpFilterReq); + WMA_LOGI("%s: WMA --> WMI_HB_SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, " + "filter=%2x:%2x:%2x:%2x:%2x:%2x ...", + __func__, + ts_lphb_udp_filter->length, + ts_lphb_udp_filter->offset, + ts_lphb_udp_filter->session, + ts_lphb_udp_filter->filter[0], + ts_lphb_udp_filter->filter[1], + ts_lphb_udp_filter->filter[2], + ts_lphb_udp_filter->filter[3], + ts_lphb_udp_filter->filter[4], + ts_lphb_udp_filter->filter[5]); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + hb_udp_filter_fp = (wmi_hb_set_udp_pkt_filter_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&hb_udp_filter_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_hb_set_udp_pkt_filter_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_hb_set_udp_pkt_filter_cmd_fixed_param)); + + /* fill in values */ + hb_udp_filter_fp->vdev_id = ts_lphb_udp_filter->session; + hb_udp_filter_fp->length = ts_lphb_udp_filter->length; + hb_udp_filter_fp->offset = ts_lphb_udp_filter->offset; + hb_udp_filter_fp->session = ts_lphb_udp_filter->session; + memcpy((void *) &hb_udp_filter_fp->filter, (void *) &ts_lphb_udp_filter->filter, + WMI_WLAN_HB_MAX_FILTER_SIZE); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_HB_SET_UDP_PKT_FILTER_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send WMI_HB_SET_UDP_PKT_FILTER returned Error %d", + status); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + + return VOS_STATUS_SUCCESS; +error: + return vos_status; +} + +/* function : wma_process_lphb_conf_req + * Description : handles LPHB configuration requests + * Args : + * Returns : + */ +VOS_STATUS wma_process_lphb_conf_req(tp_wma_handle wma_handle, + tSirLPHBReq *lphb_conf_req) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + if (lphb_conf_req == NULL) + { + WMA_LOGE("%s : LPHB configuration is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGI("%s : LPHB configuration cmd id is %d", __func__, + lphb_conf_req->cmd); + switch (lphb_conf_req->cmd) { + case LPHB_SET_EN_PARAMS_INDID: + vos_status = wma_lphb_conf_hbenable(wma_handle, + lphb_conf_req, TRUE); + break; + + case LPHB_SET_TCP_PARAMS_INDID: + vos_status = wma_lphb_conf_tcp_params(wma_handle, + lphb_conf_req); + break; + + case LPHB_SET_TCP_PKT_FILTER_INDID: + vos_status = wma_lphb_conf_tcp_pkt_filter(wma_handle, + lphb_conf_req); + break; + + case LPHB_SET_UDP_PARAMS_INDID: + vos_status = wma_lphb_conf_udp_params(wma_handle, + lphb_conf_req); + break; + + case LPHB_SET_UDP_PKT_FILTER_INDID: + vos_status = wma_lphb_conf_udp_pkt_filter(wma_handle, + lphb_conf_req); + break; + + case LPHB_SET_NETWORK_INFO_INDID: + default: + break; + } + + vos_mem_free(lphb_conf_req); + return vos_status; +} +#endif + +VOS_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle, + tAniDHCPInd *ta_dhcp_ind) +{ + uint8_t vdev_id; + int status = 0; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; + int len = sizeof(wmi_peer_set_param_cmd_fixed_param); + + if (!ta_dhcp_ind) + { + WMA_LOGE("%s : DHCP indication is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (!wma_find_vdev_by_addr(wma_handle, ta_dhcp_ind->adapterMacAddr, + &vdev_id)) + { + WMA_LOGE("%s: Failed to find vdev id for DHCP indication", + __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGI("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, " + "msgType=%s," + "device_mode=%d, macAddr=" MAC_ADDRESS_STR, + __func__, + ta_dhcp_ind->msgType==WDA_DHCP_START_IND? + "WDA_DHCP_START_IND":"WDA_DHCP_STOP_IND", + ta_dhcp_ind->device_mode, + MAC_ADDR_ARRAY(ta_dhcp_ind->peerMacAddr)); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_set_param_cmd_fixed_param)); + + /* fill in values */ + peer_set_param_fp->vdev_id = vdev_id; + peer_set_param_fp->param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED; + if (WDA_DHCP_START_IND == ta_dhcp_ind->msgType) + peer_set_param_fp->param_value = 1; + else + peer_set_param_fp->param_value = 0; + WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->peerMacAddr, + &peer_set_param_fp->peer_macaddr); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_PEER_SET_PARAM_CMDID); + if (status != EOK) { + WMA_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" + " returned Error %d", + __func__, status); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static WLAN_PHY_MODE wma_chan_to_mode(u8 chan, ePhyChanBondState chan_offset, + u8 vht_capable, u8 dot11_mode) +{ + WLAN_PHY_MODE phymode = MODE_UNKNOWN; + + /* 2.4 GHz band */ + if ((chan >= WMA_11G_CHANNEL_BEGIN) && (chan <= WMA_11G_CHANNEL_END)) { + switch (chan_offset) { + case PHY_SINGLE_CHANNEL_CENTERED: + /* In case of no channel bonding, use dot11_mode + * to set phy mode + */ + switch (dot11_mode) { + case WNI_CFG_DOT11_MODE_11A: + phymode = MODE_11A; + break; + case WNI_CFG_DOT11_MODE_11B: + phymode = MODE_11B; + break; + case WNI_CFG_DOT11_MODE_11G: + phymode = MODE_11G; + break; + case WNI_CFG_DOT11_MODE_11G_ONLY: + phymode = MODE_11GONLY; + break; + default: + /* Configure MODE_11NG_HT20 for + * self vdev(for vht too) + */ + phymode = MODE_11NG_HT20; + break; + } + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + phymode = vht_capable ? MODE_11AC_VHT40_2G :MODE_11NG_HT40; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + phymode = MODE_11AC_VHT80_2G; + break; + + default: + break; + } + } + + /* 5 GHz band */ + if ((chan >= WMA_11A_CHANNEL_BEGIN) && (chan <= WMA_11A_CHANNEL_END)) { + switch (chan_offset) { + case PHY_SINGLE_CHANNEL_CENTERED: + phymode = vht_capable ? MODE_11AC_VHT20 :MODE_11NA_HT20; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + phymode = vht_capable ? MODE_11AC_VHT40 :MODE_11NA_HT40; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + phymode = MODE_11AC_VHT80; + break; + + default: + break; + } + } + WMA_LOGD("%s: phymode %d channel %d offset %d vht_capable %d " + "dot11_mode %d", __func__, phymode, chan, + chan_offset, vht_capable, dot11_mode); + + return phymode; +} + +tANI_U8 wma_getCenterChannel(tANI_U8 chan, tANI_U8 chan_offset) +{ + tANI_U8 band_center_chan = 0; + + if ((chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED) || + (chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW)) + band_center_chan = chan + 2; + else if (chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW) + band_center_chan = chan + 6; + else if ((chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH) || + (chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED)) + band_center_chan = chan - 2; + else if (chan_offset == PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH) + band_center_chan = chan - 6; + + return band_center_chan; +} + +static VOS_STATUS wma_vdev_start(tp_wma_handle wma, + struct wma_vdev_start_req *req, v_BOOL_t isRestart) +{ + wmi_vdev_start_request_cmd_fixed_param *cmd; + wmi_buf_t buf; + wmi_channel *chan; + int32_t len, ret; + WLAN_PHY_MODE chanmode; + u_int8_t *buf_ptr; + struct wma_txrx_node *intr = wma->interfaces; + tpAniSirGlobal pmac = NULL; + struct ath_dfs *dfs; + + pmac = (tpAniSirGlobal) + vos_get_context(VOS_MODULE_ID_PE, wma->vos_context); + dfs = (struct ath_dfs *)wma->dfs_ic->ic_dfs; + + WMA_LOGD("%s: Enter isRestart=%d vdev=%d", __func__, isRestart,req->vdev_id); + len = sizeof(*cmd) + sizeof(wmi_channel) + + WMI_TLV_HDR_SIZE; + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_vdev_start_request_cmd_fixed_param *) buf_ptr; + chan = (wmi_channel *) (buf_ptr + sizeof(*cmd)); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_start_request_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_start_request_cmd_fixed_param)); + WMITLV_SET_HDR(&chan->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + cmd->vdev_id = req->vdev_id; + + /* Fill channel info */ + chan->mhz = vos_chan_to_freq(req->chan); + chanmode = wma_chan_to_mode(req->chan, req->chan_offset, + req->vht_capable, req->dot11_mode); + + intr[cmd->vdev_id].chanmode = chanmode; /* save channel mode */ + intr[cmd->vdev_id].ht_capable = req->ht_capable; + intr[cmd->vdev_id].vht_capable = req->vht_capable; + intr[cmd->vdev_id].config.gtx_info.gtxRTMask[0] = CFG_TGT_DEFAULT_GTX_HT_MASK; + intr[cmd->vdev_id].config.gtx_info.gtxRTMask[1] = CFG_TGT_DEFAULT_GTX_VHT_MASK; + intr[cmd->vdev_id].config.gtx_info.gtxUsrcfg = CFG_TGT_DEFAULT_GTX_USR_CFG; + intr[cmd->vdev_id].config.gtx_info.gtxPERThreshold = CFG_TGT_DEFAULT_GTX_PER_THRESHOLD; + intr[cmd->vdev_id].config.gtx_info.gtxPERMargin = CFG_TGT_DEFAULT_GTX_PER_MARGIN; + intr[cmd->vdev_id].config.gtx_info.gtxTPCstep = CFG_TGT_DEFAULT_GTX_TPC_STEP; + intr[cmd->vdev_id].config.gtx_info.gtxTPCMin = CFG_TGT_DEFAULT_GTX_TPC_MIN; + intr[cmd->vdev_id].config.gtx_info.gtxBWMask = CFG_TGT_DEFAULT_GTX_BW_MASK; + intr[cmd->vdev_id].mhz = chan->mhz; + + WMI_SET_CHANNEL_MODE(chan, chanmode); + chan->band_center_freq1 = chan->mhz; + + if (chanmode == MODE_11AC_VHT80) + chan->band_center_freq1 = vos_chan_to_freq(wma_getCenterChannel + (req->chan, req->chan_offset)); + + if ((chanmode == MODE_11NA_HT40) || (chanmode == MODE_11NG_HT40) || + (chanmode == MODE_11AC_VHT40)) { + if (req->chan_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + chan->band_center_freq1 += 10; + else + chan->band_center_freq1 -= 10; + } + chan->band_center_freq2 = 0; + /* + * If the channel has DFS set, flip on radar reporting. + * + * It may be that this should only be done for IBSS/hostap operation + * as this flag may be interpreted (at some point in the future) + * by the firmware as "oh, and please do radar DETECTION." + * + * If that is ever the case we would insert the decision whether to + * enable the firmware flag here. + */ + + /* + * If the Channel is DFS, + * set the WMI_CHAN_FLAG_DFS flag + */ + if (req->is_dfs) { + WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS); + cmd->disable_hw_ack = VOS_TRUE; + + req->dfs_pri_multiplier = wma->dfs_pri_multiplier; + + /* + * Configure the current operating channel + * to DFS module only if the device operating + * mode is AP. + * Enable/Disable Phyerr filtering offload + * depending on dfs_phyerr_filter_offload + * flag status as set in ini for SAP mode. + * Currently, only AP supports DFS master + * mode operation on DFS channels, P2P-GO + * does not support operation on DFS Channels. + */ + if (intr[cmd->vdev_id].type == WMI_VDEV_TYPE_AP && + intr[cmd->vdev_id].sub_type == 0) { + /* + * If DFS regulatory domain is invalid, + * then, DFS radar filters intialization + * will fail. So, do not configure the + * channel in to DFS modlue, do not + * indicate if phyerror filtering offload + * is enabled or not to the firmware, simply + * fail the VDEV start on the DFS channel + * early on, to protect the DFS module from + * processing phyerrors without being intialized. + */ + if (DFS_UNINIT_DOMAIN == wma->dfs_ic->current_dfs_regdomain) { + WMA_LOGE("%s[%d]:DFS Configured with Invalid regdomain" + " Failed to send VDEV START command", + __func__, __LINE__); + + adf_nbuf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + if (wma->dfs_ic->ic_curchan) + { + OS_FREE(wma->dfs_ic->ic_curchan); + wma->dfs_ic->ic_curchan = NULL; + } + + /* provide the current channel to DFS */ + wma->dfs_ic->ic_curchan = + wma_dfs_configure_channel(wma->dfs_ic,chan,chanmode,req); + + wma_unified_dfs_phyerr_filter_offload_enable(wma); + dfs->disable_dfs_ch_switch = + pmac->sap.SapDfsInfo.disable_dfs_ch_switch; + } + } + + cmd->beacon_interval = req->beacon_intval; + cmd->dtim_period = req->dtim_period; + /* FIXME: Find out min, max and regulatory power levels */ + WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow); + WMI_SET_CHANNEL_MAX_TX_POWER(chan, req->max_txpow); + + /* TODO: Handle regulatory class, max antenna */ + if (!isRestart) { + cmd->beacon_interval = req->beacon_intval; + cmd->dtim_period = req->dtim_period; + + /* Copy the SSID */ + if (req->ssid.length) { + if (req->ssid.length < sizeof(cmd->ssid.ssid)) + cmd->ssid.ssid_len = req->ssid.length; + else + cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid); + vos_mem_copy(cmd->ssid.ssid, req->ssid.ssId, + cmd->ssid.ssid_len); + } + + if (req->hidden_ssid) + cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID; + + if (req->pmf_enabled) + cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED; + } + + cmd->num_noa_descriptors = 0; + buf_ptr = (u_int8_t *)(((uintptr_t) cmd) + sizeof(*cmd) + + sizeof(wmi_channel)); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + cmd->num_noa_descriptors * + sizeof(wmi_p2p_noa_descriptor)); + WMA_LOGD("%s: vdev_id %d freq %d channel %d chanmode %d is_dfs %d " + "beacon interval %d dtim %d center_chan %d center_freq2 %d " + "reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x", + __func__, req->vdev_id, chan->mhz, req->chan, chanmode, req->is_dfs, + req->beacon_intval, cmd->dtim_period, chan->band_center_freq1, + chan->band_center_freq2, chan->reg_info_1, chan->reg_info_2, + req->max_txpow); + + /* Store vdev params in SAP mode which can be used in vdev restart */ + if (intr[req->vdev_id].type == WMI_VDEV_TYPE_AP && + intr[req->vdev_id].sub_type == 0) { + intr[req->vdev_id].vdev_restart_params.vdev_id = req->vdev_id; + intr[req->vdev_id].vdev_restart_params.ssid.ssid_len = cmd->ssid.ssid_len; + vos_mem_copy(intr[req->vdev_id].vdev_restart_params.ssid.ssid, cmd->ssid.ssid, + cmd->ssid.ssid_len); + intr[req->vdev_id].vdev_restart_params.flags = cmd->flags; + intr[req->vdev_id].vdev_restart_params.requestor_id = cmd->requestor_id; + intr[req->vdev_id].vdev_restart_params.disable_hw_ack = cmd->disable_hw_ack; + intr[req->vdev_id].vdev_restart_params.chan.mhz = chan->mhz; + intr[req->vdev_id].vdev_restart_params.chan.band_center_freq1 = chan->band_center_freq1; + intr[req->vdev_id].vdev_restart_params.chan.band_center_freq2 = chan->band_center_freq1; + intr[req->vdev_id].vdev_restart_params.chan.info = chan->info; + intr[req->vdev_id].vdev_restart_params.chan.reg_info_1 = chan->reg_info_1; + intr[req->vdev_id].vdev_restart_params.chan.reg_info_2 = chan->reg_info_2; + } + + if (isRestart) { + /* + * Marking the VDEV UP STATUS to FALSE + * since, VDEV RESTART will do a VDEV DOWN + * in the firmware. + */ + intr[cmd->vdev_id].vdev_up = FALSE; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_RESTART_REQUEST_CMDID); + + } else { + WMA_LOGD("%s, vdev_id: %d, unpausing tx_ll_queue at VDEV_START", + __func__, cmd->vdev_id); + wdi_in_vdev_unpause(wma->interfaces[cmd->vdev_id].handle, + 0xffffffff); + wma->interfaces[cmd->vdev_id].pause_bitmap = 0; + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_START_REQUEST_CMDID); + } + + if (ret < 0) { + WMA_LOGP("%s: Failed to send vdev start command", __func__); + adf_nbuf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +void wma_vdev_resp_timer(void *data) +{ + tp_wma_handle wma; + struct wma_target_req *tgt_req = (struct wma_target_req *)data; + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + ol_txrx_peer_handle peer; + ol_txrx_pdev_handle pdev; + u_int8_t peer_id; + struct wma_target_req *msg; + + wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, vos_context); + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma", __func__); + return; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + vos_timer_stop(&tgt_req->event_timeout); + goto free_tgt_req; + } + + WMA_LOGA("%s: request %d is timed out for vdev_id - %d", __func__, + tgt_req->msg_type, tgt_req->vdev_id); + msg = wma_find_vdev_req(wma, tgt_req->vdev_id, tgt_req->type); + + if (!msg) { + WMA_LOGE("%s: Failed to lookup request message - %d", + __func__, tgt_req->msg_type); + return; + } + + if (tgt_req->msg_type == WDA_CHNL_SWITCH_REQ) { + tpSwitchChannelParams params = + (tpSwitchChannelParams)tgt_req->user_data; + params->status = VOS_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WDA_SWITCH_CHANNEL_REQ timedout", __func__); + wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + wma->roam_preauth_chan_context = NULL; + adf_os_spin_lock_bh(&wma->roam_preauth_lock); + wma->roam_preauth_scan_id = -1; + adf_os_spin_unlock_bh(&wma->roam_preauth_lock); + } else if (tgt_req->msg_type == WDA_DELETE_BSS_REQ) { + tpDeleteBssParams params = + (tpDeleteBssParams)tgt_req->user_data; + struct beacon_info *bcn; + struct wma_txrx_node *iface; + + if (tgt_req->vdev_id > wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d", __func__, + tgt_req->vdev_id); + vos_timer_stop(&tgt_req->event_timeout); + goto free_tgt_req; + } + + iface = &wma->interfaces[tgt_req->vdev_id]; + if (iface->handle == NULL) { + WMA_LOGE("%s vdev id %d is already deleted", + __func__, tgt_req->vdev_id); + vos_timer_stop(&tgt_req->event_timeout); + goto free_tgt_req; + } + +#ifdef QCA_IBSS_SUPPORT + if (wma_is_vdev_in_ibss_mode(wma, tgt_req->vdev_id)) + wma_delete_all_ibss_peers(wma, tgt_req->vdev_id); + else +#endif + { + if (wma_is_vdev_in_ap_mode(wma, tgt_req->vdev_id)) + { + wma_delete_all_ap_remote_peers(wma, tgt_req->vdev_id); + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, + &peer_id); + wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, + peer, VOS_FALSE); + } + + if (wmi_unified_vdev_down_send(wma->wmi_handle, tgt_req->vdev_id) < 0) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + tgt_req->vdev_id); + } else { + wma->interfaces[tgt_req->vdev_id].vdev_up = FALSE; + } + ol_txrx_vdev_flush(iface->handle); + WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for WDA_DELETE_BSS_REQ timeout", + __func__, tgt_req->vdev_id); + wdi_in_vdev_unpause(iface->handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); + WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", + __func__, iface->type, iface->sub_type); + + bcn = wma->interfaces[tgt_req->vdev_id].beacon; + + if (bcn) { + WMA_LOGD("%s: Freeing beacon struct %p, " + "template memory %p", __func__, + bcn, bcn->buf); + if (bcn->dma_mapped) + adf_nbuf_unmap_single(pdev->osdev, bcn->buf, + ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(bcn->buf); + vos_mem_free(bcn); + wma->interfaces[tgt_req->vdev_id].beacon = NULL; + } + +#ifdef QCA_IBSS_SUPPORT + /* recreate ibss vdev and bss peer for scan purpose */ + if (wma_is_vdev_in_ibss_mode(wma, tgt_req->vdev_id)) + wma_recreate_ibss_vdev_and_bss_peer(wma, tgt_req->vdev_id); +#endif + params->status = VOS_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WDA_DELETE_BSS_REQ timedout", __func__); + wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0); + if (iface->del_staself_req) { + WMA_LOGA("scheduling defered deletion(vdev id %x)", + tgt_req->vdev_id); + wma_vdev_detach(wma, iface->del_staself_req, 1); + } + } else if (tgt_req->msg_type == WDA_DEL_STA_SELF_REQ) { + struct wma_txrx_node *iface = + (struct wma_txrx_node *)tgt_req->user_data; + tpDelStaSelfParams params = + (tpDelStaSelfParams)iface->del_staself_req; + + params->status = VOS_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WDA_DEL_STA_SELF_REQ timedout", __func__); + wma_send_msg(wma, WDA_DEL_STA_SELF_RSP, + (void *)iface->del_staself_req, 0); + if(iface->addBssStaContext) + adf_os_mem_free(iface->addBssStaContext); +#if defined WLAN_FEATURE_VOWIFI_11R + if (iface->staKeyParams) + adf_os_mem_free(iface->staKeyParams); +#endif + vos_mem_zero(iface, sizeof(*iface)); + } else if (tgt_req->msg_type == WDA_ADD_BSS_REQ) { + tpAddBssParams params = (tpAddBssParams)tgt_req->user_data; + tDeleteBssParams *del_bss_params = + vos_mem_malloc(sizeof(tDeleteBssParams)); + if (NULL == del_bss_params) { + WMA_LOGE("Failed to allocate memory for del_bss_params"); + peer = ol_txrx_find_peer_by_addr(pdev, params->bssId, + &peer_id); + goto error0; + } + + del_bss_params->status = params->status = + eHAL_STATUS_FW_MSG_TIMEDOUT; + del_bss_params->sessionId = params->sessionId; + del_bss_params->bssIdx = params->bssIdx; + vos_mem_copy(del_bss_params->bssid, params->bssId, + sizeof(tSirMacAddr)); + + WMA_LOGA("%s: WDA_ADD_BSS_REQ timedout", __func__); + peer = ol_txrx_find_peer_by_addr(pdev, params->bssId, &peer_id); + if (!peer) { + WMA_LOGP("%s: Failed to find peer %pM", __func__, params->bssId); + } + msg = wma_fill_vdev_req(wma, tgt_req->vdev_id, WDA_DELETE_BSS_REQ, + WMA_TARGET_REQ_TYPE_VDEV_STOP, + del_bss_params, + WMA_VDEV_STOP_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s: Failed to fill vdev request for vdev_id %d", + __func__, tgt_req->vdev_id); + goto error0; + } + + WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (WDA_ADD_BSS_REQ timedout)", + __func__, tgt_req->vdev_id); + wdi_in_vdev_pause(wma->interfaces[tgt_req->vdev_id].handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + wma->interfaces[tgt_req->vdev_id].pause_bitmap |= + (1 << PAUSE_TYPE_HOST); + if (wmi_unified_vdev_stop_send(wma->wmi_handle, tgt_req->vdev_id)) { + WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__); + wma_remove_vdev_req(wma, tgt_req->vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_STOP); + goto error0; + } + WMA_LOGI("%s: bssid %pM vdev_id %d", __func__, params->bssId, + tgt_req->vdev_id); + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)params, 0); + goto free_tgt_req; +error0: + if (peer) + wma_remove_peer(wma, params->bssId, + tgt_req->vdev_id, peer, + VOS_FALSE); + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)params, 0); + } +free_tgt_req: + vos_timer_destroy(&tgt_req->event_timeout); + adf_os_mem_free(tgt_req); +} + +static struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev_id, + u_int32_t msg_type, u_int8_t type, + void *params, u_int32_t timeout) +{ + struct wma_target_req *req; + + req = adf_os_mem_alloc(NULL, sizeof(*req)); + if (!req) { + WMA_LOGP("%s: Failed to allocate memory for msg %d vdev %d", + __func__, msg_type, vdev_id); + return NULL; + } + + WMA_LOGD("%s: vdev_id %d msg %d", __func__, vdev_id, msg_type); + req->vdev_id = vdev_id; + req->msg_type = msg_type; + req->type = type; + req->user_data = params; + vos_timer_init(&req->event_timeout, VOS_TIMER_TYPE_SW, + wma_vdev_resp_timer, req); + vos_timer_start(&req->event_timeout, timeout); + adf_os_spin_lock_bh(&wma->vdev_respq_lock); + list_add_tail(&req->node, &wma->vdev_resp_queue); + adf_os_spin_unlock_bh(&wma->vdev_respq_lock); + return req; +} + +static void wma_remove_vdev_req(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t type) +{ + struct wma_target_req *req_msg; + + req_msg = wma_find_vdev_req(wma, vdev_id, type); + if (!req_msg) + return; + + vos_timer_stop(&req_msg->event_timeout); + vos_timer_destroy(&req_msg->event_timeout); + adf_os_mem_free(req_msg); +} + +/* function : wma_roam_preauth_chan_set + * Description: Send a single channel passive scan request + * to handle set_channel operation for preauth + * Args: + * Returns : + */ +VOS_STATUS wma_roam_preauth_chan_set(tp_wma_handle wma_handle, + tpSwitchChannelParams params, u_int8_t vdev_id) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tSirScanOffloadReq scan_req; + u_int8_t bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + WMA_LOGI("%s: channel %d", __func__, params->channelNumber); + + /* Check for prior operation in progress */ + if (wma_handle->roam_preauth_chan_context != NULL) { + vos_status = VOS_STATUS_E_FAILURE; + WMA_LOGE("%s: Rejected request. Previous operation in progress", __func__); + goto send_resp; + } + wma_handle->roam_preauth_chan_context = params; + + /* Prepare a dummy scan request and get the + * wmi_start_scan_cmd_fixed_param structure filled properly + */ + vos_mem_zero(&scan_req, sizeof(scan_req)); + vos_copy_macaddr((v_MACADDR_t *) &scan_req.bssId, (v_MACADDR_t *)bssid); + vos_copy_macaddr((v_MACADDR_t *)&scan_req.selfMacAddr, (v_MACADDR_t *)¶ms->selfStaMacAddr); + scan_req.channelList.numChannels = 1; + scan_req.channelList.channelNumber[0] = params->channelNumber; + scan_req.numSsid = 0; + scan_req.minChannelTime = WMA_ROAM_PREAUTH_SCAN_TIME; + scan_req.maxChannelTime = WMA_ROAM_PREAUTH_SCAN_TIME; + scan_req.scanType = eSIR_PASSIVE_SCAN; + scan_req.p2pScanType = P2P_SCAN_TYPE_LISTEN; + scan_req.sessionId = vdev_id; + wma_handle->roam_preauth_chanfreq = vos_chan_to_freq(params->channelNumber); + + /* set the state in advance before calling wma_start_scan and be ready + * to handle scan events from firmware. Otherwise print statments + * in wma_start_can create a race condition. + */ + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_REQUESTED; + vos_status = wma_start_scan(wma_handle, &scan_req, WDA_CHNL_SWITCH_REQ); + + if (vos_status == VOS_STATUS_SUCCESS) + return vos_status; + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; + /* Failed operation. Safely clear context */ + wma_handle->roam_preauth_chan_context = NULL; + +send_resp: + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, vos_status); + params->chainMask = wma_handle->pdevconfig.txchainmask; + params->smpsMode = SMPS_MODE_DISABLED; + params->status = vos_status; + wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + return vos_status; +} + +VOS_STATUS wma_roam_preauth_chan_cancel(tp_wma_handle wma_handle, + tpSwitchChannelParams params, u_int8_t vdev_id) +{ + tAbortScanParams abort_scan_req; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + WMA_LOGI("%s: channel %d", __func__, params->channelNumber); + /* Check for prior operation in progress */ + if (wma_handle->roam_preauth_chan_context != NULL) { + vos_status = VOS_STATUS_E_FAILURE; + WMA_LOGE("%s: Rejected request. Previous operation in progress", __func__); + goto send_resp; + } + wma_handle->roam_preauth_chan_context = params; + + abort_scan_req.SessionId = vdev_id; + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_CANCEL_REQUESTED; + vos_status = wma_stop_scan(wma_handle, &abort_scan_req); + if (vos_status == VOS_STATUS_SUCCESS) + return vos_status; + /* Failed operation. Safely clear context */ + wma_handle->roam_preauth_chan_context = NULL; + +send_resp: + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, vos_status); + params->chainMask = wma_handle->pdevconfig.txchainmask; + params->smpsMode = SMPS_MODE_DISABLED; + params->status = vos_status; + wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + return vos_status; +} + +static void wma_roam_preauth_scan_event_handler(tp_wma_handle wma_handle, + u_int8_t vdev_id, wmi_scan_event_fixed_param *wmi_event) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tSwitchChannelParams *params; + + WMA_LOGI("%s: preauth_scan_state %d, event 0x%x, reason 0x%x", + __func__, wma_handle->roam_preauth_scan_state, + wmi_event->event, wmi_event->reason); + switch(wma_handle->roam_preauth_scan_state) { + case WMA_ROAM_PREAUTH_CHAN_REQUESTED: + if (wmi_event->event & WMI_SCAN_EVENT_FOREIGN_CHANNEL) { + /* complete set_chan request */ + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_ON_CHAN; + vos_status = VOS_STATUS_SUCCESS; + } else if (wmi_event->event & WMI_SCAN_FINISH_EVENTS){ + /* Failed to get preauth channel or finished (unlikely) */ + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; + vos_status = VOS_STATUS_E_FAILURE; + } else + return; + break; + case WMA_ROAM_PREAUTH_CHAN_CANCEL_REQUESTED: + /* Completed or cancelled, complete set_chan cancel request */ + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; + break; + + case WMA_ROAM_PREAUTH_ON_CHAN: + if ((wmi_event->event & WMI_SCAN_EVENT_BSS_CHANNEL) || + (wmi_event->event & WMI_SCAN_FINISH_EVENTS)) + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_COMPLETED; + + /* There is no WDA request to complete. Next set channel request will + * look at this state and complete it. + */ + break; + default: + WMA_LOGE("%s: unhandled event 0x%x, reason 0x%x", + __func__, wmi_event->event, wmi_event->reason); + return; + } + + if((params = (tpSwitchChannelParams) wma_handle->roam_preauth_chan_context)) { + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, vos_status); + params->chainMask = wma_handle->pdevconfig.txchainmask; + params->smpsMode = SMPS_MODE_DISABLED; + params->status = vos_status; + wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + wma_handle->roam_preauth_chan_context = NULL; + } + +} + +void wma_roam_preauth_ind(tp_wma_handle wma_handle, u_int8_t *buf) { + wmi_scan_event_fixed_param *wmi_event = NULL; + u_int8_t vdev_id; + + wmi_event = (wmi_scan_event_fixed_param *)buf; + if (wmi_event == NULL) { + WMA_LOGE("%s: Invalid param wmi_event is null", __func__); + return; + } + + vdev_id = wmi_event->vdev_id; + if (vdev_id >= wma_handle->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d wmi_event %p", __func__, + vdev_id, wmi_event); + return; + } + + wma_roam_preauth_scan_event_handler(wma_handle, vdev_id, wmi_event); + return; +} + +/* + * wma_set_channel + * If this request is called when station is connected, it should use + */ +static void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) +{ + struct wma_vdev_start_req req; + struct wma_target_req *msg; + VOS_STATUS status = VOS_STATUS_SUCCESS; + u_int8_t vdev_id, peer_id; + ol_txrx_peer_handle peer; + ol_txrx_pdev_handle pdev; + struct wma_txrx_node *intr = wma->interfaces; + + WMA_LOGD("%s: Enter", __func__); + if (!wma_find_vdev_by_addr(wma, params->selfStaMacAddr, &vdev_id)) { + WMA_LOGP("%s: Failed to find vdev id for %pM", + __func__, params->selfStaMacAddr); + status = VOS_STATUS_E_FAILURE; + goto send_resp; + } + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + status = VOS_STATUS_E_FAILURE; + goto send_resp; + } + + peer = ol_txrx_find_peer_by_addr(pdev, intr[vdev_id].bssid, &peer_id); + + /* + * Roam offload feature is currently supported + * only in STA mode. Other modes still require + * to issue a Vdev Start/Vdev Restart for + * channel change. + */ + if (((wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) && + (wma->interfaces[vdev_id].sub_type == 0)) && + !wma->interfaces[vdev_id].is_channel_switch) { + + if (peer && (peer->state == ol_txrx_peer_state_conn || + peer->state == ol_txrx_peer_state_auth)) { + /* Trying to change channel while connected + * should not invoke VDEV_START. + * Instead, use start scan command in passive + * mode to park station on that channel + */ + WMA_LOGI("%s: calling set_scan, state 0x%x", + __func__, wma->roam_preauth_scan_state); + if (wma->roam_preauth_scan_state == + WMA_ROAM_PREAUTH_CHAN_NONE) { + /* Is channel change required? + */ + if(vos_chan_to_freq(params->channelNumber) != + wma->interfaces[vdev_id].mhz) + { + status = wma_roam_preauth_chan_set(wma, + params, vdev_id); + /* response will be asynchronous */ + return; + } + } else if (wma->roam_preauth_scan_state == + WMA_ROAM_PREAUTH_CHAN_REQUESTED || + wma->roam_preauth_scan_state == WMA_ROAM_PREAUTH_ON_CHAN) { + status = wma_roam_preauth_chan_cancel(wma, params, vdev_id); + /* response will be asynchronous */ + return; + } else if (wma->roam_preauth_scan_state == + WMA_ROAM_PREAUTH_CHAN_COMPLETED) { + /* Already back on home channel. Complete the request */ + wma->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; + status = VOS_STATUS_SUCCESS; + } + goto send_resp; + } + } + vos_mem_zero(&req, sizeof(req)); + req.vdev_id = vdev_id; + msg = wma_fill_vdev_req(wma, req.vdev_id, WDA_CHNL_SWITCH_REQ, + WMA_TARGET_REQ_TYPE_VDEV_START, params, + WMA_VDEV_START_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s: Failed to fill channel switch request for vdev %d", + __func__, req.vdev_id); + status = VOS_STATUS_E_NOMEM; + goto send_resp; + } + req.chan = params->channelNumber; + req.chan_offset = params->secondaryChannelOffset; + req.vht_capable = params->vhtCapable; + req.dot11_mode = params->dot11_mode; +#ifdef WLAN_FEATURE_VOWIFI + req.max_txpow = params->maxTxPower; +#else + req.max_txpow = params->localPowerConstraint; +#endif + req.beacon_intval = 100; + req.dtim_period = 1; + req.is_dfs = params->isDfsChannel; + + /* In case of AP mode, once radar is detected, we need to + * issuse VDEV RESTART, so we making is_channel_switch as + * TRUE + */ + if((wma->interfaces[req.vdev_id].type == WMI_VDEV_TYPE_AP ) && + (wma->interfaces[req.vdev_id].sub_type == 0)) + wma->interfaces[req.vdev_id].is_channel_switch = VOS_TRUE; + + status = wma_vdev_start(wma, &req, + wma->interfaces[req.vdev_id].is_channel_switch); + if (status != VOS_STATUS_SUCCESS) { + wma_remove_vdev_req(wma, req.vdev_id, WMA_TARGET_REQ_TYPE_VDEV_START); + WMA_LOGP("%s: vdev start failed status = %d", __func__, status); + goto send_resp; + } + + if (wma->interfaces[req.vdev_id].is_channel_switch) + wma->interfaces[req.vdev_id].is_channel_switch = VOS_FALSE; + return; +send_resp: + WMA_LOGD("%s: channel %d offset %d txpower %d status %d", __func__, + params->channelNumber, params->secondaryChannelOffset, +#ifdef WLAN_FEATURE_VOWIFI + params->maxTxPower, +#else + params->localPowerConstraint, +#endif + status); + params->status = status; + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, status); + wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); +} + +static WLAN_PHY_MODE wma_peer_phymode(tSirNwType nw_type, u_int8_t sta_type, + u_int8_t is_ht, u_int8_t is_cw40, u_int8_t is_vht, u_int8_t is_cw_vht) +{ + WLAN_PHY_MODE phymode = MODE_UNKNOWN; + + switch (nw_type) { + case eSIR_11B_NW_TYPE: + if (is_vht) { + if (is_cw_vht) + phymode = MODE_11AC_VHT80; + else + phymode = (is_cw40) ? + MODE_11AC_VHT40 : + MODE_11AC_VHT20; + } + else if (is_ht) { + phymode = (is_cw40) ? + MODE_11NG_HT40 : MODE_11NG_HT20; + } else + phymode = MODE_11B; + break; + case eSIR_11G_NW_TYPE: + if (is_vht) { + if (is_cw_vht) + phymode = MODE_11AC_VHT80; + else + phymode = (is_cw40) ? + MODE_11AC_VHT40 : + MODE_11AC_VHT20; + } + else if (is_ht) { + phymode = (is_cw40) ? + MODE_11NG_HT40 : + MODE_11NG_HT20; + } else + phymode = MODE_11G; + break; + case eSIR_11A_NW_TYPE: + if (is_vht) { + if (is_cw_vht) + phymode = MODE_11AC_VHT80; + else + phymode = (is_cw40) ? + MODE_11AC_VHT40 : + MODE_11AC_VHT20; + } + else if (is_ht) { + phymode = (is_cw40) ? + MODE_11NA_HT40 : + MODE_11NA_HT20; + } else + phymode = MODE_11A; + break; + default: + WMA_LOGP("%s: Invalid nw type %d", __func__, nw_type); + break; + } + WMA_LOGD("%s: nw_type %d is_ht %d is_cw40 %d is_vht %d is_cw_vht %d\ + phymode %d", __func__, nw_type, is_ht, is_cw40, + is_vht, is_cw_vht, phymode); + + return phymode; +} + +static int32_t wmi_unified_send_txbf(tp_wma_handle wma, + tpAddStaParams params) +{ + wmi_vdev_txbf_en txbf_en; + + /* This is set when Other partner is Bformer + and we are capable bformee(enabled both in ini and fw) */ + txbf_en.sutxbfee = params->vhtTxBFCapable; + txbf_en.mutxbfee = params->vhtTxMUBformeeCapable; + txbf_en.sutxbfer = 0; + txbf_en.mutxbfer = 0; + + /* When MU TxBfee is set, SU TxBfee must be set by default */ + if (txbf_en.mutxbfee) + txbf_en.sutxbfee = txbf_en.mutxbfee; + + WMA_LOGD("txbf_en.sutxbfee %d txbf_en.mutxbfee %d", + txbf_en.sutxbfee, txbf_en.mutxbfee); + + return(wmi_unified_vdev_set_param_send(wma->wmi_handle, + params->smesessionId, WMI_VDEV_PARAM_TXBF, + *((A_UINT8 *)&txbf_en))); +} + +static void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value) +{ + if (*cmd_value > WMA_MAX_RF_CHAINS(num_rf_chains)) { + WMA_LOGE("%s: Chainmask value exceeds the maximum" + " supported range setting it to" + " maximum value. Requested value %d" + " Updated value %d", __func__, *cmd_value, + WMA_MAX_RF_CHAINS(num_rf_chains)); + *cmd_value = WMA_MAX_RF_CHAINS(num_rf_chains); + } else if (*cmd_value < WMA_MIN_RF_CHAINS) { + WMA_LOGE("%s: Chainmask value is less than the minimum" + " supported range setting it to" + " minimum value. Requested value %d" + " Updated value %d", __func__, *cmd_value, + WMA_MIN_RF_CHAINS); + *cmd_value = WMA_MIN_RF_CHAINS; + } +} + +static int32_t wmi_unified_send_peer_assoc(tp_wma_handle wma, + tSirNwType nw_type, + tpAddStaParams params) +{ + ol_txrx_pdev_handle pdev; + wmi_peer_assoc_complete_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int32_t ret, max_rates, i; + u_int8_t rx_stbc, tx_stbc; + u_int8_t *rate_pos, *buf_ptr; + wmi_rate_set peer_legacy_rates, peer_ht_rates; + wmi_vht_rate_set *mcs; + u_int32_t num_peer_legacy_rates; + u_int32_t num_peer_ht_rates; + u_int32_t num_peer_11b_rates=0; + u_int32_t num_peer_11a_rates=0; + u_int32_t phymode; + u_int32_t peer_nss=1; + struct wma_txrx_node *intr = NULL; + + if (NULL == params) { + WMA_LOGE("%s: params is NULL", __func__); + return -EINVAL; + } + intr = &wma->interfaces[params->smesessionId]; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + return -EINVAL; + } + + vos_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set)); + vos_mem_zero(&peer_ht_rates, sizeof(wmi_rate_set)); + + phymode = wma_peer_phymode(nw_type, params->staType, + params->htCapable, + params->txChannelWidthSet, + params->vhtCapable, + params->vhtTxChannelWidthSet); + + /* Legacy Rateset */ + rate_pos = (u_int8_t *) peer_legacy_rates.rates; + for (i = 0; i < SIR_NUM_11B_RATES; i++) { + if (!params->supportedRates.llbRates[i]) + continue; + rate_pos[peer_legacy_rates.num_rates++] = + params->supportedRates.llbRates[i]; + num_peer_11b_rates++; + } + for (i = 0; i < SIR_NUM_11A_RATES; i++) { + if (!params->supportedRates.llaRates[i]) + continue; + rate_pos[peer_legacy_rates.num_rates++] = + params->supportedRates.llaRates[i]; + num_peer_11a_rates++; + } + + if ((phymode == MODE_11A && num_peer_11a_rates == 0) || + (phymode == MODE_11B && num_peer_11b_rates == 0)) { + WMA_LOGW("%s: Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d", + __func__, phymode, num_peer_11b_rates, num_peer_11a_rates); + return -EINVAL; + } + /* Set the Legacy Rates to Word Aligned */ + num_peer_legacy_rates = roundup(peer_legacy_rates.num_rates, + sizeof(u_int32_t)); + + /* HT Rateset */ + max_rates = sizeof(peer_ht_rates.rates) / + sizeof(peer_ht_rates.rates[0]); + rate_pos = (u_int8_t *) peer_ht_rates.rates; + for (i = 0; i < MAX_SUPPORTED_RATES; i++) { + if (params->supportedRates.supportedMCSSet[i / 8] & + (1 << (i % 8))) { + rate_pos[peer_ht_rates.num_rates++] = i; + if (i >= 8) { + /* MCS8 or higher rate is present, must be 2x2 */ + peer_nss = 2; + } + } + if (peer_ht_rates.num_rates == max_rates) + break; + } + + if (params->htCapable && !peer_ht_rates.num_rates) { + u_int8_t temp_ni_rates[8] = {0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7}; + /* + * Workaround for EV 116382: The peer is marked HT but with + * supported rx mcs set is set to 0. 11n spec mandates MCS0-7 + * for a HT STA. So forcing the supported rx mcs rate to + * MCS 0-7. This workaround will be removed once we get + * clarification from WFA regarding this STA behavior. + */ + + /* TODO: Do we really need this? */ + WMA_LOGW("Peer is marked as HT capable but supported mcs rate is 0"); + peer_ht_rates.num_rates = sizeof(temp_ni_rates); + vos_mem_copy((u_int8_t *) peer_ht_rates.rates, temp_ni_rates, + peer_ht_rates.num_rates); + } + + /* Set the Peer HT Rates to Word Aligned */ + num_peer_ht_rates = roundup(peer_ht_rates.num_rates, + sizeof(u_int32_t)); + + len = sizeof(*cmd) + + WMI_TLV_HDR_SIZE + /* Place holder for peer legacy rate array */ + (num_peer_legacy_rates * sizeof(u_int8_t)) + /* peer legacy rate array size */ + WMI_TLV_HDR_SIZE + /* Place holder for peer Ht rate array */ + (num_peer_ht_rates * sizeof(u_int8_t)) + /* peer HT rate array size */ + sizeof(wmi_vht_rate_set); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_peer_assoc_complete_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_assoc_complete_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_assoc_complete_cmd_fixed_param)); + + /* in ap/ibss mode and for tdls peer, use mac address of the peer in + * the other end as the new peer address; in sta mode, use bss id to + * be the new peer address + */ + if ((wma_is_vdev_in_ap_mode(wma, params->smesessionId)) +#ifdef QCA_IBSS_SUPPORT + || (wma_is_vdev_in_ibss_mode(wma, params->smesessionId)) +#endif +#ifdef FEATURE_WLAN_TDLS + || (STA_ENTRY_TDLS_PEER == params->staType) +#endif + ) + WMI_CHAR_ARRAY_TO_MAC_ADDR(params->staMac, &cmd->peer_macaddr); + else + WMI_CHAR_ARRAY_TO_MAC_ADDR(params->bssId, &cmd->peer_macaddr); + cmd->vdev_id = params->smesessionId; + cmd->peer_new_assoc = 1; + cmd->peer_associd = params->assocId; + + /* + * The target only needs a subset of the flags maintained in the host. + * Just populate those flags and send it down + */ + cmd->peer_flags = 0; + + if (params->wmmEnabled) + cmd->peer_flags |= WMI_PEER_QOS; + + if (params->uAPSD) { + cmd->peer_flags |= WMI_PEER_APSD; + WMA_LOGD("Set WMI_PEER_APSD: uapsd Mask %d", params->uAPSD); + } + + if (params->htCapable) { + cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_QOS); + cmd->peer_rate_caps |= WMI_RC_HT_FLAG; + } + + if (params->txChannelWidthSet) { + cmd->peer_flags |= WMI_PEER_40MHZ; + cmd->peer_rate_caps |= WMI_RC_CW40_FLAG; + if (params->fShortGI40Mhz) + cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; + } else if (params->fShortGI20Mhz) + cmd->peer_rate_caps |= WMI_RC_SGI_FLAG; + +#ifdef WLAN_FEATURE_11AC + if (params->vhtCapable) { + cmd->peer_flags |= (WMI_PEER_HT | WMI_PEER_VHT | WMI_PEER_QOS); + cmd->peer_rate_caps |= WMI_RC_HT_FLAG; + } + + if (params->vhtTxChannelWidthSet) + cmd->peer_flags |= WMI_PEER_80MHZ; + + cmd->peer_vht_caps = params->vht_caps; +#endif + + if (params->rmfEnabled) + cmd->peer_flags |= WMI_PEER_PMF; + + rx_stbc = (params->ht_caps & IEEE80211_HTCAP_C_RXSTBC) >> + IEEE80211_HTCAP_C_RXSTBC_S; + if (rx_stbc) { + cmd->peer_flags |= WMI_PEER_STBC; + cmd->peer_rate_caps |= (rx_stbc << WMI_RC_RX_STBC_FLAG_S); + } + + tx_stbc = (params->ht_caps & IEEE80211_HTCAP_C_TXSTBC) >> + IEEE80211_HTCAP_C_TXSTBC_S; + if (tx_stbc) { + cmd->peer_flags |= WMI_PEER_STBC; + cmd->peer_rate_caps |= (tx_stbc << WMI_RC_TX_STBC_FLAG_S); + } + + if (params->htLdpcCapable || params->vhtLdpcCapable) + cmd->peer_flags |= WMI_PEER_LDPC; + + switch (params->mimoPS) { + case eSIR_HT_MIMO_PS_STATIC: + cmd->peer_flags |= WMI_PEER_STATIC_MIMOPS; + break; + case eSIR_HT_MIMO_PS_DYNAMIC: + cmd->peer_flags |= WMI_PEER_DYN_MIMOPS; + break; + case eSIR_HT_MIMO_PS_NO_LIMIT: + cmd->peer_flags |= WMI_PEER_SPATIAL_MUX; + break; + default: + break; + } + +#ifdef FEATURE_WLAN_TDLS + if (STA_ENTRY_TDLS_PEER == params->staType) + cmd->peer_flags |= WMI_PEER_AUTH; +#endif + + if (params->wpa_rsn +#ifdef FEATURE_WLAN_WAPI + || params->encryptType == eSIR_ED_WPI +#endif + ) + cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; + if (params->wpa_rsn >> 1) + cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; + + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + if (STA_ENTRY_TDLS_PEER == params->staType) + ol_txrx_peer_state_update(pdev, params->staMac, ol_txrx_peer_state_auth); + else + ol_txrx_peer_state_update(pdev, params->bssId, ol_txrx_peer_state_auth); + #else + ol_txrx_peer_state_update(pdev, params->bssId, ol_txrx_peer_state_auth); + #endif + +#ifdef FEATURE_WLAN_WAPI + if (params->encryptType == eSIR_ED_WPI) { + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, + params->smesessionId, + WMI_VDEV_PARAM_DROP_UNENCRY, + FALSE); + if (ret) { + WMA_LOGE("Set WMI_VDEV_PARAM_DROP_UNENCRY Param status:%d\n", ret); + adf_nbuf_free(buf); + return ret; + } + } +#endif + + cmd->peer_caps = params->capab_info; + cmd->peer_listen_intval = params->listenInterval; + cmd->peer_ht_caps = params->ht_caps; + cmd->peer_max_mpdu = (1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + params->maxAmpduSize)) - 1; + cmd->peer_mpdu_density = wma_parse_mpdudensity(params->maxAmpduDensity); + + if (params->supportedRates.supportedMCSSet[1] && + params->supportedRates.supportedMCSSet[2]) + cmd->peer_rate_caps |= WMI_RC_TS_FLAG; + else if (params->supportedRates.supportedMCSSet[1]) + cmd->peer_rate_caps |= WMI_RC_DS_FLAG; + + /* Update peer legacy rate information */ + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + num_peer_legacy_rates); + buf_ptr += WMI_TLV_HDR_SIZE; + cmd->num_peer_legacy_rates = peer_legacy_rates.num_rates; + vos_mem_copy(buf_ptr, peer_legacy_rates.rates, + peer_legacy_rates.num_rates); + + /* Update peer HT rate information */ + buf_ptr += num_peer_legacy_rates; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + num_peer_ht_rates); + buf_ptr += WMI_TLV_HDR_SIZE; + cmd->num_peer_ht_rates = peer_ht_rates.num_rates; + vos_mem_copy(buf_ptr, peer_ht_rates.rates, + peer_ht_rates.num_rates); + + /* VHT Rates */ + buf_ptr += num_peer_ht_rates; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_vht_rate_set, + WMITLV_GET_STRUCT_TLVLEN(wmi_vht_rate_set)); + + cmd->peer_nss = peer_nss; + + WMA_LOGD("peer_nss %d peer_ht_rates.num_rates %d ", cmd->peer_nss, + peer_ht_rates.num_rates); + + mcs = (wmi_vht_rate_set *)buf_ptr; + if ( params->vhtCapable) { +#define VHT2x2MCSMASK 0xc + mcs->rx_max_rate = params->supportedRates.vhtRxHighestDataRate; + mcs->rx_mcs_set = params->supportedRates.vhtRxMCSMap; + mcs->tx_max_rate = params->supportedRates.vhtTxHighestDataRate; + mcs->tx_mcs_set = params->supportedRates.vhtTxMCSMap; + + if(params->vhtSupportedRxNss) { + cmd->peer_nss = params->vhtSupportedRxNss; + } else { + cmd->peer_nss = ((mcs->rx_mcs_set & VHT2x2MCSMASK) + == VHT2x2MCSMASK) ? 1 : 2; + } + } + + /* + * Limit nss to max number of rf chain supported by target + * Otherwise Fw will crash + */ + wma_update_txrx_chainmask(wma->num_rf_chains, &cmd->peer_nss); + + intr->nss = cmd->peer_nss; + cmd->peer_phymode = phymode; + + WMA_LOGD("%s: vdev_id %d associd %d peer_flags %x rate_caps %x " + "peer_caps %x listen_intval %d ht_caps %x max_mpdu %d " + "nss %d phymode %d peer_mpdu_density %d" + "cmd->peer_vht_caps %x", __func__, + cmd->vdev_id, cmd->peer_associd, cmd->peer_flags, + cmd->peer_rate_caps, cmd->peer_caps, + cmd->peer_listen_intval, cmd->peer_ht_caps, + cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode, + cmd->peer_mpdu_density, cmd->peer_vht_caps); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_PEER_ASSOC_CMDID); + if (ret != EOK) { + WMA_LOGP("%s: Failed to send peer assoc command ret = %d", + __func__, ret); + adf_nbuf_free(buf); + } + return ret; +} + +static int +wmi_unified_modem_power_state(wmi_unified_t wmi_handle, u_int32_t param_value) +{ + int ret; + wmi_modem_power_state_cmd_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_modem_power_state_cmd_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_modem_power_state_cmd_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_modem_power_state_cmd_param)); + cmd->modem_power_state = param_value; + WMA_LOGD("%s: Setting cmd->modem_power_state = %u", __func__, param_value); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_MODEM_POWER_STATE_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send notify cmd ret = %d", ret); + wmi_buf_free(buf); + } + return ret; +} + +VOS_STATUS wma_get_link_speed(WMA_HANDLE handle, + tSirLinkSpeedInfo *pLinkSpeed) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_peer_get_estimated_linkspeed_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_ESTIMATE_LINKSPEED)) { + WMA_LOGE("%s: Linkspeed feature bit not enabled" + " Sending value 0 as link speed.", + __func__); + wma_send_link_speed(0); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); + + /* Copy the peer macaddress to the wma buffer */ + WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr, &cmd->peer_macaddr); + + WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, " + "peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x", + __func__, pLinkSpeed->peer_macaddr, + cmd->peer_macaddr.mac_addr31to0, + cmd->peer_macaddr.mac_addr47to32); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { + WMA_LOGE("%s: failed to send link speed command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + + +static int +wmi_unified_pdev_set_param(wmi_unified_t wmi_handle, WMI_PDEV_PARAM param_id, + u_int32_t param_value) +{ + int ret; + wmi_pdev_set_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_set_param_cmd_fixed_param)); + cmd->reserved0 = 0; + cmd->param_id = param_id; + cmd->param_value = param_value; + WMA_LOGD("Setting pdev param = %x, value = %u", + param_id, param_value); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_PDEV_SET_PARAM_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send set param command ret = %d", ret); + wmi_buf_free(buf); + } + return ret; +} + +static int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle, + uint8_t vdev_id, u_int32_t value) +{ + struct ol_txrx_stats_req req; + ol_txrx_vdev_handle vdev; + + vdev = wma_find_vdev_by_id(wma_handle, vdev_id); + if (!vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + return -EINVAL; + } + vos_mem_zero(&req, sizeof(req)); + req.stats_type_reset_mask = value; + ol_txrx_fw_stats_get(vdev, &req); + + return 0; +} + +static int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle, + uint8_t vdev_id, u_int32_t value) +{ + struct ol_txrx_stats_req req; + ol_txrx_vdev_handle vdev; + + vdev = wma_find_vdev_by_id(wma_handle, vdev_id); + if (!vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + return -EINVAL; + } + vos_mem_zero(&req, sizeof(req)); + req.print.verbose = 1; + if (value <= WMA_FW_TX_PPDU_STATS) + req.stats_type_upload_mask = 1 << (value - 1); + else if (value == WMA_FW_TX_CONCISE_STATS) { + /* + * Stats request 5 is the same as stats request 4, + * but with only a concise printout. + */ + req.print.concise = 1; + req.stats_type_upload_mask = 1 << (WMA_FW_TX_PPDU_STATS - 1); + } else if (value == WMA_FW_TX_RC_STATS) { + req.stats_type_upload_mask = 1 << (WMA_FW_TX_CONCISE_STATS - 1); + /* + * This part of the code is a bit confusing. + * For the statistics command iwpriv wlan0 txrx_fw_stats , + * for all n <= 4, there is 1:1 mapping of WMA defined value (n) + * with f/w required stats_type_upload_mask. + * For n <= 4, stats_type_upload_mask = 1 << (n - 1) + * With the introduction of WMA_FW_TX_CONCISE_STATS, this changed + * & the code has a special case handling, where for n = 5, + * stats_type_upload_mask = 1 << (n - 2). + * However per current code, there is no way to set the value of + * stats_type_upload_mask for n > 5. + * In the mean-time for dumping Remote Ring Buffer information, + * f/w expects stats_type_upload_mask = 1 << 12. + * However going by CLI command arguments, n should be 7. + * There seems to be no apparent correlation between 7 & 12. + * To fix this properly, one needs to fix the WMA defines appropriately + * and always let n have a 1:1 correspondence with the bitmask expected by f/w. + * Do not want to disturb the existing code now, but extending this code, + * so that CLI argument "n" has 1:1 correpondence with f/w bitmask. + * With this approach, for remote ring information, the statistics + * command should be: + * iwpriv wlan0 txrx_fw_stats 12 + */ + /* FIXME : Fix all the values in the appropriate way. */ + } else if (value == WMA_FW_RX_REM_RING_BUF) { + req.stats_type_upload_mask = 1 << WMA_FW_RX_REM_RING_BUF; + } + + ol_txrx_fw_stats_get(vdev, &req); + + return 0; +} + +static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle, + wda_cli_set_cmd_t *privcmd) +{ + int32_t ret = 0; + + switch (privcmd->param_id) { + case WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID: + ret = wma_set_txrx_fw_stats_level(wma_handle, + privcmd->param_vdev_id, + privcmd->param_value); + break; + case WMA_VDEV_TXRX_FWSTATS_RESET_CMDID: + ret = wma_txrx_fw_stats_reset(wma_handle, + privcmd->param_vdev_id, + privcmd->param_value); + break; + case WMI_STA_SMPS_FORCE_MODE_CMDID: + wma_set_mimops(wma_handle, privcmd->param_vdev_id, + privcmd->param_value); + break; + case WMI_STA_SMPS_PARAM_CMDID: + wma_set_smps_params(wma_handle, privcmd->param_vdev_id, + privcmd->param_value); + break; + case WMA_VDEV_MCC_SET_TIME_LATENCY: + { + /* Extract first MCC adapter/vdev channel number and latency */ + tANI_U8 mcc_channel = privcmd->param_value & 0x000000FF; + tANI_U8 mcc_channel_latency = + (privcmd->param_value & 0x0000FF00) >> 8; + int ret = -1; + WMA_LOGD("%s: Parsed input: Channel #1:%d, latency:%dms", + __func__, mcc_channel, mcc_channel_latency); + ret = wma_set_mcc_channel_time_latency + ( + wma_handle, + mcc_channel, + mcc_channel_latency + ); + } + break; + case WMA_VDEV_MCC_SET_TIME_QUOTA: + { + /** Extract the MCC 2 adapters/vdevs channel numbers and time + * quota value for the first adapter only (which is specified + * in iwpriv command. + */ + tANI_U8 adapter_2_chan_number = + privcmd->param_value & 0x000000FF; + tANI_U8 adapter_1_chan_number = + (privcmd->param_value & 0x0000FF00) >> 8; + tANI_U8 adapter_1_quota = + (privcmd->param_value & 0x00FF0000) >> 16; + int ret = -1; + + WMA_LOGD("%s: Parsed input: Channel #1:%d, Channel #2:%d," + "quota 1:%dms", __func__, adapter_1_chan_number, + adapter_2_chan_number, adapter_1_quota); + ret = wma_set_mcc_channel_time_quota + ( + wma_handle, + adapter_1_chan_number, + adapter_1_quota, + adapter_2_chan_number + ); + } + break; + case WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE: + { + wma_handle->wma_ibss_power_save_params.atimWindowLength = + privcmd->param_value; + WMA_LOGD("%s: IBSS power save ATIM Window = %d", __func__, + wma_handle->wma_ibss_power_save_params.atimWindowLength); + } + break; + case WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED: + { + wma_handle->wma_ibss_power_save_params.isPowerSaveAllowed = + privcmd->param_value; + WMA_LOGD("%s: IBSS is Power Save Allowed = %d", __func__, + wma_handle->wma_ibss_power_save_params.isPowerSaveAllowed); + } + break; + case WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED: + { + wma_handle->wma_ibss_power_save_params.isPowerCollapseAllowed = + privcmd->param_value; + WMA_LOGD("%s: IBSS is Power Collapse Allowed = %d", __func__, + wma_handle->wma_ibss_power_save_params.isPowerCollapseAllowed); + } + break; + case WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX: + { + wma_handle->wma_ibss_power_save_params.isAwakeonTxRxEnabled = + privcmd->param_value; + WMA_LOGD("%s: IBSS Power Save Awake on Tx/Rx Enabled = %d", __func__, + wma_handle->wma_ibss_power_save_params.isAwakeonTxRxEnabled); + } + break; + case WMA_VDEV_IBSS_SET_INACTIVITY_TIME: + { + wma_handle->wma_ibss_power_save_params.inactivityCount = + privcmd->param_value; + WMA_LOGD("%s: IBSS Power Save Data Inactivity Count = %d", __func__, + wma_handle->wma_ibss_power_save_params.inactivityCount); + } + break; + case WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME: + { + wma_handle->wma_ibss_power_save_params.txSPEndInactivityTime = + privcmd->param_value; + WMA_LOGD("%s: IBSS Power Save Transmit EOSP inactivity time out = %d", + __func__, + wma_handle->wma_ibss_power_save_params.txSPEndInactivityTime); + } + break; + case WMA_VDEV_DFS_CONTROL_CMDID: + { + struct ieee80211com *dfs_ic = wma_handle->dfs_ic; + struct ath_dfs *dfs; + + if (!dfs_ic) { + ret = -ENOENT; + } else { + if (dfs_ic->ic_curchan) { + WMA_LOGD("%s: Debug cmd: %s received on ch: %d", + __func__, + "WMA_VDEV_DFS_CONTROL_CMDID", + dfs_ic->ic_curchan->ic_ieee); + + if (dfs_ic->ic_curchan->ic_flagext & + IEEE80211_CHAN_DFS) { + dfs = (struct ath_dfs *)dfs_ic->ic_dfs; + dfs->dfs_bangradar = 1; + dfs->ath_radar_tasksched = 1; + OS_SET_TIMER(&dfs->ath_dfs_task_timer, + 0); + } else { + ret = -ENOENT; + } + } else { + ret = -ENOENT; + } + } + + if ( ret == -ENOENT) { + WMA_LOGE("%s: Operating channel is not DFS capable, " + "ignoring %s", + __func__, + "WMA_VDEV_DFS_CONTROL_CMDID"); + } else if (ret) { + WMA_LOGE("%s: Sending command %s failed with %d\n", + __func__, + "WMA_VDEV_DFS_CONTROL_CMDID", + ret); + } + } + break; + case WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS: + { + wma_handle->wma_ibss_power_save_params.ibssPsWarmupTime = + privcmd->param_value; + WMA_LOGD("%s: IBSS Power Save Warm Up Time in Seconds = %d", + __func__, + wma_handle->wma_ibss_power_save_params.ibssPsWarmupTime); + } + break; + case WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW: + { + wma_handle->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable = + privcmd->param_value; + WMA_LOGD("%s: IBSS Power Save single RX Chain Enable In ATIM = %d", + __func__, + wma_handle->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable); + } + break; + +#ifdef IPA_UC_OFFLOAD + case WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID: + { + ol_txrx_pdev_handle pdev; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, + wma_handle->vos_context); + if (!pdev) { + WMA_LOGE("pdev NULL for uc stat"); + return -EINVAL; + } + ol_txrx_ipa_uc_get_stat(pdev); + } + break; +#endif /* IPA_UC_OFFLOAD */ + + default: + WMA_LOGE("Invalid wma config command id:%d", + privcmd->param_id); + ret = -EINVAL; + } + return ret; +} + +static int wmi_crash_inject(wmi_unified_t wmi_handle, u_int32_t type, + u_int32_t delay_time_ms) +{ + int ret = 0; + WMI_FORCE_FW_HANG_CMD_fixed_param *cmd; + u_int16_t len = sizeof(*cmd); + wmi_buf_t buf; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed!", __func__); + return -ENOMEM; + } + + cmd = (WMI_FORCE_FW_HANG_CMD_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_FORCE_FW_HANG_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_FORCE_FW_HANG_CMD_fixed_param)); + cmd->type = type; + cmd->delay_time_ms = delay_time_ms; + + ret = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_FORCE_FW_HANG_CMDID); + if (ret < 0) { + WMA_LOGE("%s: Failed to send set param command, ret = %d", + __func__, ret); + wmi_buf_free(buf); + } + + return ret; +} + +/** + * wma_crash_inject() - sends command to FW to simulate crash + * @wma_handle: pointer of WMA context + * @type: subtype of the command + * @delay_time_ms: time in milliseconds for FW to delay the crash + * + * This function will send a command to FW in order to simulate different + * kinds of FW crashes. + * + * Return: 0 for success or reasons for failure + */ + +int wma_crash_inject(tp_wma_handle wma_handle, uint32_t type, + uint32_t delay_time_ms) +{ + return wmi_crash_inject(wma_handle->wmi_handle, type, delay_time_ms); +} + +static int32_t wmi_unified_set_sta_ps_param(wmi_unified_t wmi_handle, + u_int32_t vdev_id, u_int32_t param, u_int32_t value) +{ + wmi_sta_powersave_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + tp_wma_handle wma; + struct wma_txrx_node *iface; + wma = vos_get_context(VOS_MODULE_ID_WDA, + vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return -EIO; + } + iface = &wma->interfaces[vdev_id]; + + WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d", + vdev_id, param, value); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: Set Sta Ps param Mem Alloc Failed", __func__); + return -ENOMEM; + } + + cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_powersave_param_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->param = param; + cmd->value = value; + + if (wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_STA_POWERSAVE_PARAM_CMDID)) { + WMA_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d", + vdev_id, param, value); + adf_nbuf_free(buf); + return -EIO; + } + /* Store the PS Status */ + iface->ps_enabled = value ? TRUE : FALSE; + return 0; +} + +#ifdef FEATURE_GREEN_AP +static int32_t wmi_unified_pdev_green_ap_ps_enable_cmd(wmi_unified_t wmi_handle, + u_int32_t value) +{ + wmi_pdev_green_ap_ps_enable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + WMA_LOGD("Set Green AP PS val %d", value); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: Green AP PS Mem Alloc Failed", __func__); + return -ENOMEM; + } + + cmd = (wmi_pdev_green_ap_ps_enable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_green_ap_ps_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_green_ap_ps_enable_cmd_fixed_param)); + cmd->reserved0 = 0; + cmd->enable = value; + + if (wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID)) { + WMA_LOGE("Set Green AP PS param Failed val %d", value); + + adf_nbuf_free(buf); + return -EIO; + } + return 0; +} +#endif /* FEATURE_GREEN_AP */ + +static int +wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle, u_int32_t if_id, + gtx_config_t *gtx_info) +{ + wmi_vdev_set_gtx_params_cmd_fixed_param *cmd; + wmi_buf_t buf; + int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param); + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __FUNCTION__); + return -1; + } + cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_set_gtx_params_cmd_fixed_param)); + cmd->vdev_id = if_id; + + cmd->gtxRTMask[0] = gtx_info->gtxRTMask[0]; + cmd->gtxRTMask[1] = gtx_info->gtxRTMask[1]; + cmd->userGtxMask = gtx_info->gtxUsrcfg; + cmd->gtxPERThreshold = gtx_info->gtxPERThreshold; + cmd->gtxPERMargin = gtx_info->gtxPERMargin; + cmd->gtxTPCstep = gtx_info->gtxTPCstep; + cmd->gtxTPCMin = gtx_info->gtxTPCMin; + cmd->gtxBWMask = gtx_info->gtxBWMask; + + WMA_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \ + gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \ + gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1], + cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin, + cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask); + return wmi_unified_cmd_send(wmi_handle, buf, len, WMI_VDEV_SET_GTX_PARAMS_CMDID); +} + +static void wma_process_cli_set_cmd(tp_wma_handle wma, + wda_cli_set_cmd_t *privcmd) +{ + int ret = 0, vid = privcmd->param_vdev_id, pps_val = 0; + struct wma_txrx_node *intr = wma->interfaces; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + struct qpower_params *qparams = &intr[vid].config.qpower_params; + + WMA_LOGD("wmihandle %p", wma->wmi_handle); + + if (NULL == pMac) { + WMA_LOGE("%s: Failed to get pMac", __func__); + return; + } + + if (privcmd->param_id >= WMI_CMDID_MAX) { + /* + * This configuration setting is not done using any wmi + * command, call appropriate handler. + */ + if (wma_set_priv_cfg(wma, privcmd)) + WMA_LOGE("Failed to set wma priv congiuration"); + return; + } + + switch (privcmd->param_vp_dev) { + case VDEV_CMD: + WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id, + privcmd->param_id, privcmd->param_value); + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, + privcmd->param_vdev_id, + privcmd->param_id, + privcmd->param_value); + if (ret) { + WMA_LOGE("wmi_unified_vdev_set_param_send" + " failed ret %d", ret); + return; + } + break; + case PDEV_CMD: + WMA_LOGD("pdev pid %d pval %d", privcmd->param_id, + privcmd->param_value); + if ((privcmd->param_id == WMI_PDEV_PARAM_RX_CHAIN_MASK) || + (privcmd->param_id == WMI_PDEV_PARAM_TX_CHAIN_MASK)) { + wma_update_txrx_chainmask(wma->num_rf_chains, + &privcmd->param_value); + } + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + privcmd->param_id, + privcmd->param_value); + if (ret) { + WMA_LOGE("wmi_unified_vdev_set_param_send" + " failed ret %d", ret); + return; + } + break; + case GEN_CMD: + { + ol_txrx_vdev_handle vdev = NULL; + struct wma_txrx_node *intr = wma->interfaces; + + vdev = wma_find_vdev_by_id(wma, privcmd->param_vdev_id); + if (!vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + return; + } + + WMA_LOGD("gen pid %d pval %d", privcmd->param_id, + privcmd->param_value); + + switch (privcmd->param_id) { + case GEN_VDEV_PARAM_AMPDU: + ret = ol_txrx_aggr_cfg(vdev, privcmd->param_value, 0); + if (ret) + WMA_LOGE("ol_txrx_aggr_cfg set ampdu" + " failed ret %d", ret); + else + intr[privcmd->param_vdev_id].config.ampdu = privcmd->param_value; + break; + case GEN_VDEV_PARAM_AMSDU: + ret = ol_txrx_aggr_cfg(vdev, 0, privcmd->param_value); + if (ret) + WMA_LOGE("ol_txrx_aggr_cfg set amsdu" + " failed ret %d", ret); + else + intr[privcmd->param_vdev_id].config.amsdu = privcmd->param_value; + break; + case GEN_PARAM_DUMP_AGC_START: + HTCDump(wma->htc_handle, AGC_DUMP, true); + break; + case GEN_PARAM_DUMP_AGC: + HTCDump(wma->htc_handle, AGC_DUMP, false); + break; + case GEN_PARAM_DUMP_CHANINFO_START: + HTCDump(wma->htc_handle, CHAN_DUMP, true); + break; + case GEN_PARAM_DUMP_CHANINFO: + HTCDump(wma->htc_handle, CHAN_DUMP, false); + break; + case GEN_PARAM_DUMP_WATCHDOG: + HTCDump(wma->htc_handle, WD_DUMP, false); + break; + case GEN_PARAM_CRASH_INJECT: + ret = wmi_crash_inject(wma->wmi_handle, + privcmd->param_value, privcmd->param_sec_value); + break; +#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG + case GEN_PARAM_DUMP_PCIE_ACCESS_LOG: + HTCDump(wma->htc_handle, PCIE_DUMP, false); + break; +#endif + default: + WMA_LOGE("Invalid param id 0x%x", privcmd->param_id); + break; + } + break; + } + case DBG_CMD: + WMA_LOGD("dbg pid %d pval %d", privcmd->param_id, + privcmd->param_value); + switch (privcmd->param_id) { + case WMI_DBGLOG_LOG_LEVEL: + ret = dbglog_set_log_lvl(wma->wmi_handle, privcmd->param_value); + if (ret) + WMA_LOGE("dbglog_set_log_lvl" + " failed ret %d", ret); + break; + case WMI_DBGLOG_VAP_ENABLE: + ret = dbglog_vap_log_enable(wma->wmi_handle, privcmd->param_value, TRUE); + if (ret) + WMA_LOGE("dbglog_vap_log_enable" + " failed ret %d", ret); + break; + case WMI_DBGLOG_VAP_DISABLE: + ret = dbglog_vap_log_enable(wma->wmi_handle, privcmd->param_value, FALSE); + if (ret) + WMA_LOGE("dbglog_vap_log_enable" + " failed ret %d", ret); + break; + case WMI_DBGLOG_MODULE_ENABLE: + ret = dbglog_module_log_enable(wma->wmi_handle, privcmd->param_value, TRUE); + if (ret) + WMA_LOGE("dbglog_module_log_enable" + " failed ret %d", ret); + break; + case WMI_DBGLOG_MODULE_DISABLE: + ret = dbglog_module_log_enable(wma->wmi_handle, privcmd->param_value, FALSE); + if (ret) + WMA_LOGE("dbglog_module_log_enable" + " failed ret %d", ret); + break; + case WMI_DBGLOG_MOD_LOG_LEVEL: + ret = dbglog_set_mod_log_lvl(wma->wmi_handle, privcmd->param_value); + if (ret) + WMA_LOGE("dbglog_module_log_enable" + " failed ret %d", ret); + break; + case WMI_DBGLOG_TYPE: + ret = dbglog_parser_type_init(wma->wmi_handle, privcmd->param_value); + if (ret) + WMA_LOGE("dbglog_parser_type_init" + " failed ret %d", ret); + break; + case WMI_DBGLOG_REPORT_ENABLE: + ret = dbglog_report_enable(wma->wmi_handle, privcmd->param_value); + if (ret) + WMA_LOGE("dbglog_report_enable" + " failed ret %d", ret); + break; +#ifdef FEATURE_GREEN_AP + case WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID: + /* Set the Green AP */ + ret = wmi_unified_pdev_green_ap_ps_enable_cmd(wma->wmi_handle, + privcmd->param_value); + if (ret) { + WMA_LOGE("Set GreenAP Failed val %d", privcmd->param_value); + } + break; +#endif /* FEATURE_GREEN_AP */ + + default: + WMA_LOGE("Invalid param id 0x%x", privcmd->param_id); + break; + } + break; + case PPS_CMD: + WMA_LOGD("dbg pid %d pval %d", privcmd->param_id, + privcmd->param_value); + switch (privcmd->param_id) { + + case WMI_VDEV_PPS_PAID_MATCH: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_PAID_MATCH & 0xffff); + intr[vid].config.pps_params.paid_match_enable = privcmd->param_value; + break; + case WMI_VDEV_PPS_GID_MATCH: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_GID_MATCH & 0xffff); + intr[vid].config.pps_params.gid_match_enable = privcmd->param_value; + break; + case WMI_VDEV_PPS_EARLY_TIM_CLEAR: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff); + intr[vid].config.pps_params.tim_clear = privcmd->param_value; + break; + case WMI_VDEV_PPS_EARLY_DTIM_CLEAR: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff); + intr[vid].config.pps_params.dtim_clear = privcmd->param_value; + break; + case WMI_VDEV_PPS_EOF_PAD_DELIM: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff); + intr[vid].config.pps_params.eof_delim = privcmd->param_value; + break; + case WMI_VDEV_PPS_MACADDR_MISMATCH: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff); + intr[vid].config.pps_params.mac_match = privcmd->param_value; + break; + case WMI_VDEV_PPS_DELIM_CRC_FAIL: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff); + intr[vid].config.pps_params.delim_fail = privcmd->param_value; + break; + case WMI_VDEV_PPS_GID_NSTS_ZERO: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff); + intr[vid].config.pps_params.nsts_zero = privcmd->param_value; + break; + case WMI_VDEV_PPS_RSSI_CHECK: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_RSSI_CHECK & 0xffff); + intr[vid].config.pps_params.rssi_chk = privcmd->param_value; + break; + case WMI_VDEV_PPS_5G_EBT: + pps_val = ((privcmd->param_value << 31) & 0xffff0000) | + (PKT_PWR_SAVE_5G_EBT & 0xffff); + intr[vid].config.pps_params.ebt_5g = privcmd->param_value; + break; + default: + WMA_LOGE("Invalid param id 0x%x", privcmd->param_id); + break; + } + break; + + case QPOWER_CMD: + WMA_LOGD("QPOWER CLI CMD pid %d pval %d", privcmd->param_id, + privcmd->param_value); + switch (privcmd->param_id) { + case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT: + WMA_LOGD("QPOWER CLI CMD:Ps Poll Cnt val %d", + privcmd->param_value); + /* Set the QPower Ps Poll Count */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vid, + WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT, + privcmd->param_value); + if (ret) { + WMA_LOGE("Set Q-PsPollCnt Failed vdevId %d val %d", + vid, privcmd->param_value); + } else { + qparams->max_ps_poll_cnt = + privcmd->param_value; + } + break; + case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE: + WMA_LOGD("QPOWER CLI CMD:Max Tx Before wake val %d", + privcmd->param_value); + /* Set the QPower Max Tx Before Wake */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vid, + WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE, + privcmd->param_value); + if (ret) { + WMA_LOGE("Set Q-MaxTxBefWake Failed vId %d val %d", + vid, privcmd->param_value); + } else { + qparams->max_tx_before_wake = + privcmd->param_value; + } + break; + case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL: + WMA_LOGD("QPOWER CLI CMD:Ps Poll Wake Inv val %d", + privcmd->param_value); + /* Set the QPower Spec Ps Poll Wake Inv */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vid, + WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL, + privcmd->param_value); + if (ret) { + WMA_LOGE("Set Q-PsPoll WakeIntv Failed vId %d val %d", + vid, privcmd->param_value); + } else { + qparams->spec_ps_poll_wake_interval = + privcmd->param_value; + } + break; + case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL: + WMA_LOGD("QPOWER CLI CMD:Spec NoData Ps Poll val %d", + privcmd->param_value); + /* Set the QPower Spec NoData PsPoll */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vid, + WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL, + privcmd->param_value); + if (ret) { + WMA_LOGE("Set Q-SpecNoDataPsPoll Failed vId %d val %d", + vid, privcmd->param_value); + } else { + qparams->max_spec_nodata_ps_poll = + privcmd->param_value; + } + break; + + default: + WMA_LOGE("Invalid param id 0x%x", privcmd->param_id); + break; + } + break; + case GTX_CMD: + WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id, + privcmd->param_id, privcmd->param_value); + switch (privcmd->param_id) { + case WMI_VDEV_PARAM_GTX_HT_MCS: + intr[vid].config.gtx_info.gtxRTMask[0] = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + case WMI_VDEV_PARAM_GTX_VHT_MCS: + intr[vid].config.gtx_info.gtxRTMask[1] = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_USR_CFG: + intr[vid].config.gtx_info.gtxUsrcfg = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_THRE: + intr[vid].config.gtx_info.gtxPERThreshold = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_MARGIN: + intr[vid].config.gtx_info.gtxPERMargin = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_STEP: + intr[vid].config.gtx_info.gtxTPCstep = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_MINTPC: + intr[vid].config.gtx_info.gtxTPCMin = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + break; + + case WMI_VDEV_PARAM_GTX_BW_MASK: + intr[vid].config.gtx_info.gtxBWMask = privcmd->param_value; + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, + privcmd->param_vdev_id, + &intr[vid].config.gtx_info); + if (ret) { + WMA_LOGE("wmi_unified_vdev_set_param_send" + " failed ret %d", ret); + return; + } + break; + default: + break; + } + break; + + default: + WMA_LOGE("Invalid vpdev command id"); + } + if (1 == privcmd->param_vp_dev) { + switch (privcmd->param_id) { + case WMI_VDEV_PARAM_NSS: + intr[vid].config.nss = privcmd->param_value; + break; + case WMI_VDEV_PARAM_LDPC: + intr[vid].config.ldpc = privcmd->param_value; + break; + case WMI_VDEV_PARAM_TX_STBC: + intr[vid].config.tx_stbc = privcmd->param_value; + break; + case WMI_VDEV_PARAM_RX_STBC: + intr[vid].config.rx_stbc = privcmd->param_value; + break; + case WMI_VDEV_PARAM_SGI: + intr[vid].config.shortgi = privcmd->param_value; + break; + case WMI_VDEV_PARAM_ENABLE_RTSCTS: + intr[vid].config.rtscts_en = privcmd->param_value; + break; + case WMI_VDEV_PARAM_CHWIDTH: + intr[vid].config.chwidth = privcmd->param_value; + break; + case WMI_VDEV_PARAM_FIXED_RATE: + intr[vid].config.tx_rate = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE: + intr[vid].config.erx_adjust = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM: + intr[vid].config.erx_bmiss_num = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE: + intr[vid].config.erx_bmiss_cycle = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP: + intr[vid].config.erx_slop_step = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP: + intr[vid].config.erx_init_slop = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE: + intr[vid].config.erx_adj_pause = privcmd->param_value; + break; + case WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE: + intr[vid].config.erx_dri_sample = privcmd->param_value; + break; + default: + WMA_LOGE("Invalid wda_cli_set vdev command/Not" + " yet implemented 0x%x", privcmd->param_id); + break; + } + } else if (2 == privcmd->param_vp_dev) { + switch (privcmd->param_id) { + case WMI_PDEV_PARAM_ANI_ENABLE: + wma->pdevconfig.ani_enable = privcmd->param_value; + break; + case WMI_PDEV_PARAM_ANI_POLL_PERIOD: + wma->pdevconfig.ani_poll_len = privcmd->param_value; + break; + case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD: + wma->pdevconfig.ani_listen_len = privcmd->param_value; + break; + case WMI_PDEV_PARAM_ANI_OFDM_LEVEL: + wma->pdevconfig.ani_ofdm_level = privcmd->param_value; + break; + case WMI_PDEV_PARAM_ANI_CCK_LEVEL: + wma->pdevconfig.ani_cck_level = privcmd->param_value; + break; + case WMI_PDEV_PARAM_DYNAMIC_BW: + wma->pdevconfig.cwmenable = privcmd->param_value; + break; + case WMI_PDEV_PARAM_CTS_CBW: + wma->pdevconfig.cts_cbw = privcmd->param_value; + break; + case WMI_PDEV_PARAM_TX_CHAIN_MASK: + wma->pdevconfig.txchainmask = privcmd->param_value; + break; + case WMI_PDEV_PARAM_RX_CHAIN_MASK: + wma->pdevconfig.rxchainmask = privcmd->param_value; + break; + case WMI_PDEV_PARAM_BURST_ENABLE: + wma->pdevconfig.burst_enable = privcmd->param_value; + if ((wma->pdevconfig.burst_enable == 1) && + (wma->pdevconfig.burst_dur == 0)) + wma->pdevconfig.burst_dur = WMA_DEFAULT_SIFS_BURST_DURATION; + else if (wma->pdevconfig.burst_enable == 0) + wma->pdevconfig.burst_dur = 0; + break; + case WMI_PDEV_PARAM_BURST_DUR: + wma->pdevconfig.burst_dur = privcmd->param_value; + break; + case WMI_PDEV_PARAM_POWER_GATING_SLEEP: + wma->pdevconfig.pwrgating = privcmd->param_value; + break; + case WMI_PDEV_PARAM_TXPOWER_LIMIT2G: + wma->pdevconfig.txpow2g = privcmd->param_value; + if ((pMac->roam.configParam.bandCapability == + eCSR_BAND_ALL) || + (pMac->roam.configParam.bandCapability == + eCSR_BAND_24)) { + if (cfgSetInt(pMac, + WNI_CFG_CURRENT_TX_POWER_LEVEL, + privcmd->param_value) != eSIR_SUCCESS) { + WMA_LOGE("could not set" + " WNI_CFG_CURRENT_TX_POWER_LEVEL"); + } + } + else + WMA_LOGE("Current band is not 2G"); + break; + case WMI_PDEV_PARAM_TXPOWER_LIMIT5G: + wma->pdevconfig.txpow5g = privcmd->param_value; + if ((pMac->roam.configParam.bandCapability == + eCSR_BAND_ALL) || + (pMac->roam.configParam.bandCapability == + eCSR_BAND_5G)) { + if (cfgSetInt(pMac, + WNI_CFG_CURRENT_TX_POWER_LEVEL, + privcmd->param_value) != eSIR_SUCCESS) { + WMA_LOGE("could not set" + " WNI_CFG_CURRENT_TX_POWER_LEVEL"); + } + } + else + WMA_LOGE("Current band is not 5G"); + break; + default: + WMA_LOGE("Invalid wda_cli_set pdev command/Not" + " yet implemented 0x%x", privcmd->param_id); + break; + } + } else if (5 == privcmd->param_vp_dev) { + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, privcmd->param_vdev_id, + WMI_VDEV_PARAM_PACKET_POWERSAVE, + pps_val); + if (ret) + WMA_LOGE("Failed to send wmi packet power save cmd"); + else + WMA_LOGD("Sent packet power save cmd %d value %x to target", + privcmd->param_id, pps_val); + } +} + +int wma_cli_get_command(void *wmapvosContext, int vdev_id, + int param_id, int vpdev) +{ + int ret = 0; + tp_wma_handle wma; + struct wma_txrx_node *intr = NULL; + + wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, + wmapvosContext); + + if (NULL == wma) + { + WMA_LOGE("%s: Invalid wma handle", __func__); + return -EINVAL; + } + + intr = wma->interfaces; + + if (VDEV_CMD == vpdev) { + switch (param_id) { + case WMI_VDEV_PARAM_NSS: + ret = intr[vdev_id].config.nss; + break; +#ifdef QCA_SUPPORT_GTX + case WMI_VDEV_PARAM_GTX_HT_MCS: + ret = intr[vdev_id].config.gtx_info.gtxRTMask[0]; + break; + case WMI_VDEV_PARAM_GTX_VHT_MCS: + ret = intr[vdev_id].config.gtx_info.gtxRTMask[1]; + break; + case WMI_VDEV_PARAM_GTX_USR_CFG: + ret = intr[vdev_id].config.gtx_info.gtxUsrcfg; + break; + case WMI_VDEV_PARAM_GTX_THRE: + ret = intr[vdev_id].config.gtx_info.gtxPERThreshold; + break; + case WMI_VDEV_PARAM_GTX_MARGIN: + ret = intr[vdev_id].config.gtx_info.gtxPERMargin; + break; + case WMI_VDEV_PARAM_GTX_STEP: + ret = intr[vdev_id].config.gtx_info.gtxTPCstep; + break; + case WMI_VDEV_PARAM_GTX_MINTPC: + ret = intr[vdev_id].config.gtx_info.gtxTPCMin; + break; + case WMI_VDEV_PARAM_GTX_BW_MASK: + ret = intr[vdev_id].config.gtx_info.gtxBWMask; + break; +#endif + case WMI_VDEV_PARAM_LDPC: + ret = intr[vdev_id].config.ldpc; + break; + case WMI_VDEV_PARAM_TX_STBC: + ret = intr[vdev_id].config.tx_stbc; + break; + case WMI_VDEV_PARAM_RX_STBC: + ret = intr[vdev_id].config.rx_stbc; + break; + case WMI_VDEV_PARAM_SGI: + ret = intr[vdev_id].config.shortgi; + break; + case WMI_VDEV_PARAM_ENABLE_RTSCTS: + ret = intr[vdev_id].config.rtscts_en; + break; + case WMI_VDEV_PARAM_CHWIDTH: + ret = intr[vdev_id].config.chwidth; + break; + case WMI_VDEV_PARAM_FIXED_RATE: + ret = intr[vdev_id].config.tx_rate; + break; + + default: + WMA_LOGE("Invalid cli_get vdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } else if (PDEV_CMD == vpdev) { + switch (param_id) { + case WMI_PDEV_PARAM_ANI_ENABLE: + ret = wma->pdevconfig.ani_enable; + break; + case WMI_PDEV_PARAM_ANI_POLL_PERIOD: + ret = wma->pdevconfig.ani_poll_len; + break; + case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD: + ret = wma->pdevconfig.ani_listen_len; + break; + case WMI_PDEV_PARAM_ANI_OFDM_LEVEL: + ret = wma->pdevconfig.ani_ofdm_level; + break; + case WMI_PDEV_PARAM_ANI_CCK_LEVEL: + ret = wma->pdevconfig.ani_cck_level; + break; + case WMI_PDEV_PARAM_DYNAMIC_BW: + ret = wma->pdevconfig.cwmenable; + break; + case WMI_PDEV_PARAM_CTS_CBW: + ret = wma->pdevconfig.cts_cbw; + break; + case WMI_PDEV_PARAM_TX_CHAIN_MASK: + ret = wma->pdevconfig.txchainmask; + break; + case WMI_PDEV_PARAM_RX_CHAIN_MASK: + ret = wma->pdevconfig.rxchainmask; + break; + case WMI_PDEV_PARAM_TXPOWER_LIMIT2G: + ret = wma->pdevconfig.txpow2g; + break; + case WMI_PDEV_PARAM_TXPOWER_LIMIT5G: + ret = wma->pdevconfig.txpow5g; + break; + case WMI_PDEV_PARAM_POWER_GATING_SLEEP: + ret = wma->pdevconfig.pwrgating; + break; + case WMI_PDEV_PARAM_BURST_ENABLE: + ret = wma->pdevconfig.burst_enable; + break; + case WMI_PDEV_PARAM_BURST_DUR: + ret = wma->pdevconfig.burst_dur; + break; + default: + WMA_LOGE("Invalid cli_get pdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } else if (GEN_CMD == vpdev) { + switch (param_id) { + case GEN_VDEV_PARAM_AMPDU: + ret = intr[vdev_id].config.ampdu; + break; + case GEN_VDEV_PARAM_AMSDU: + ret = intr[vdev_id].config.amsdu; + break; + default: + WMA_LOGE("Invalid generic vdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } else if (PPS_CMD == vpdev) { + switch (param_id) { + case WMI_VDEV_PPS_PAID_MATCH: + ret = intr[vdev_id].config.pps_params.paid_match_enable; + break; + case WMI_VDEV_PPS_GID_MATCH: + ret = intr[vdev_id].config.pps_params.gid_match_enable; + break; + case WMI_VDEV_PPS_EARLY_TIM_CLEAR: + ret = intr[vdev_id].config.pps_params.tim_clear; + break; + case WMI_VDEV_PPS_EARLY_DTIM_CLEAR: + ret = intr[vdev_id].config.pps_params.dtim_clear; + break; + case WMI_VDEV_PPS_EOF_PAD_DELIM: + ret = intr[vdev_id].config.pps_params.eof_delim; + break; + case WMI_VDEV_PPS_MACADDR_MISMATCH: + ret = intr[vdev_id].config.pps_params.mac_match; + break; + case WMI_VDEV_PPS_DELIM_CRC_FAIL: + ret = intr[vdev_id].config.pps_params.delim_fail; + break; + case WMI_VDEV_PPS_GID_NSTS_ZERO: + ret = intr[vdev_id].config.pps_params.nsts_zero; + break; + case WMI_VDEV_PPS_RSSI_CHECK: + ret = intr[vdev_id].config.pps_params.rssi_chk; + break; + default: + WMA_LOGE("Invalid pps vdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } else if (QPOWER_CMD == vpdev) { + switch (param_id) { + case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT: + ret = intr[vdev_id].config.qpower_params.max_ps_poll_cnt; + break; + + case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE: + ret = intr[vdev_id].config.qpower_params.max_tx_before_wake; + break; + + case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL: + ret = + intr[vdev_id].config.qpower_params.spec_ps_poll_wake_interval; + break; + + case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL: + ret = intr[vdev_id].config.qpower_params.max_spec_nodata_ps_poll; + break; + + default: + WMA_LOGE("Invalid generic vdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } else if (GTX_CMD == vpdev) { + switch (param_id) { + case WMI_VDEV_PARAM_GTX_HT_MCS: + ret = intr[vdev_id].config.gtx_info.gtxRTMask[0]; + break; + case WMI_VDEV_PARAM_GTX_VHT_MCS: + ret = intr[vdev_id].config.gtx_info.gtxRTMask[1]; + break; + case WMI_VDEV_PARAM_GTX_USR_CFG: + ret = intr[vdev_id].config.gtx_info.gtxUsrcfg; + break; + case WMI_VDEV_PARAM_GTX_THRE: + ret = intr[vdev_id].config.gtx_info.gtxPERThreshold; + break; + case WMI_VDEV_PARAM_GTX_MARGIN: + ret = intr[vdev_id].config.gtx_info.gtxPERMargin; + break; + case WMI_VDEV_PARAM_GTX_STEP: + ret = intr[vdev_id].config.gtx_info.gtxTPCstep; + break; + case WMI_VDEV_PARAM_GTX_MINTPC: + ret = intr[vdev_id].config.gtx_info.gtxTPCMin; + break; + case WMI_VDEV_PARAM_GTX_BW_MASK: + ret = intr[vdev_id].config.gtx_info.gtxBWMask; + break; + default: + WMA_LOGE("Invalid generic vdev command/Not" + " yet implemented 0x%x", param_id); + return -EINVAL; + } + } + return ret; +} + +static void +wma_update_protection_mode(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t llbcoexist) +{ + int ret; + enum ieee80211_protmode prot_mode; + + prot_mode = llbcoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE; + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PROTECTION_MODE, + prot_mode); + + if (ret) + WMA_LOGE("Failed to send wmi protection mode cmd"); + else + WMA_LOGD("Updated protection mode %d to target", prot_mode); +} + +static void +wma_update_beacon_interval(tp_wma_handle wma, u_int8_t vdev_id, + u_int16_t beaconInterval) +{ + int ret; + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_BEACON_INTERVAL, + beaconInterval); + + if (ret) + WMA_LOGE("Failed to update beacon interval"); + else + WMA_LOGI("Updated beacon interval %d for vdev %d", beaconInterval, vdev_id); +} + + +/* + * Function : wma_process_update_beacon_params + * Description : update the beacon parameters to target + * Args : wma handle, beacon parameters + * Returns : None + */ +static void +wma_process_update_beacon_params(tp_wma_handle wma, + tUpdateBeaconParams *bcn_params) +{ + if (!bcn_params) { + WMA_LOGE("bcn_params NULL"); + return; + } + + if (bcn_params->smeSessionId >= wma->max_bssid) { + WMA_LOGE("Invalid vdev id %d", bcn_params->smeSessionId); + return; + } + + if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) { + wma_update_beacon_interval(wma, bcn_params->smeSessionId, + bcn_params->beaconInterval); + } + + if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED) + wma_update_protection_mode(wma, bcn_params->smeSessionId, + bcn_params->llbCoexist); +} + +/* + * Function : wma_update_cfg_params + * Description : update the cfg parameters to target + * Args : wma handle, cfg parameter + * Returns : None + */ +static void +wma_update_cfg_params(tp_wma_handle wma, tSirMsgQ *cfgParam) +{ + u_int8_t vdev_id; + u_int32_t param_id; + tANI_U32 cfg_val; + int ret; + /* get mac to acess CFG data base */ + struct sAniSirGlobal *pmac; + + switch(cfgParam->bodyval) { + case WNI_CFG_RTS_THRESHOLD: + param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; + break; + case WNI_CFG_FRAGMENTATION_THRESHOLD: + param_id = WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD; + break; + default: + WMA_LOGD("Unhandled cfg parameter %d", cfgParam->bodyval); + return; + } + + pmac = (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + if (NULL == pmac) { + WMA_LOGE("%s: Failed to get pmac", __func__); + return; + } + + if (wlan_cfgGetInt(pmac, (tANI_U16) cfgParam->bodyval, + &cfg_val) != eSIR_SUCCESS) + { + WMA_LOGE("Failed to get value for CFG PARAMS %d. returning without updating", + cfgParam->bodyval); + return; + } + + for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { + if (wma->interfaces[vdev_id].handle != 0) { + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, + vdev_id, param_id, cfg_val); + if (ret) + WMA_LOGE("Update cfg params failed for vdevId %d", vdev_id); + } + } +} + +/* BSS set params functions */ +static void +wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id, + tSirMacBeaconInterval beaconInterval, tANI_U8 dtimPeriod, + tANI_U8 shortSlotTimeSupported, tANI_U8 llbCoexist, + tPowerdBm maxTxPower) +{ + int ret; + uint32_t slot_time; + struct wma_txrx_node *intr = wma->interfaces; + + /* Beacon Interval setting */ + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_BEACON_INTERVAL, + beaconInterval); + + if (ret) + WMA_LOGE("failed to set WMI_VDEV_PARAM_BEACON_INTERVAL"); + + ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id, + &intr[vdev_id].config.gtx_info); + if (ret) + WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DTIM_PERIOD, + dtimPeriod); + if (ret) + WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD"); + + if (!maxTxPower) + { + WMA_LOGW("Setting Tx power limit to 0"); + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_PWRLIMIT, + maxTxPower); + if (ret) + WMA_LOGE("failed to set WMI_VDEV_PARAM_TX_PWRLIMIT"); + else + intr[vdev_id].max_tx_power = maxTxPower; + + /* Slot time */ + if (shortSlotTimeSupported) + slot_time = WMI_VDEV_SLOT_TIME_SHORT; + else + slot_time = WMI_VDEV_SLOT_TIME_LONG; + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_SLOT_TIME, + slot_time); + if (ret) + WMA_LOGE("failed to set WMI_VDEV_PARAM_SLOT_TIME"); + + /* Initialize protection mode in case of coexistence */ + wma_update_protection_mode(wma, vdev_id, llbCoexist); +} + +static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + struct wma_vdev_start_req req; + ol_txrx_peer_handle peer; + struct wma_target_req *msg; + u_int8_t vdev_id, peer_id; + VOS_STATUS status; + tPowerdBm maxTxPower; +#ifdef WLAN_FEATURE_11W + int ret = 0; +#endif /* WLAN_FEATURE_11W */ + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + goto send_fail_resp; + } + + vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id); + if (!vdev) { + WMA_LOGE("%s: Failed to get vdev handle", __func__); + goto send_fail_resp; + } + wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss); + status = wma_create_peer(wma, pdev, vdev, add_bss->bssId, + WMI_PEER_TYPE_DEFAULT, vdev_id, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer", __func__); + goto send_fail_resp; + } + + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id); + if (!peer) { + WMA_LOGE("%s Failed to find peer %pM", __func__, + add_bss->bssId); + goto send_fail_resp; + } + msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ, + WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, + WMA_VDEV_START_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s Failed to allocate vdev request vdev_id %d", + __func__, vdev_id); + goto peer_cleanup; + } + + add_bss->staContext.staIdx = ol_txrx_local_peer_id(peer); + + vos_mem_zero(&req, sizeof(req)); + req.vdev_id = vdev_id; + req.chan = add_bss->currentOperChannel; + req.chan_offset = add_bss->currentExtChannel; + req.vht_capable = add_bss->vhtCapable; +#if defined WLAN_FEATURE_VOWIFI + req.max_txpow = add_bss->maxTxPower; + maxTxPower = add_bss->maxTxPower; +#else + req.max_txpow = 0; + maxTxPower = 0; +#endif +#ifdef WLAN_FEATURE_11W + if (add_bss->rmfEnabled) { + /* + * when 802.11w PMF is enabled for hw encr/decr + * use hw MFP Qos bits 0x10 + */ + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_PMF_QOS, TRUE); + if(ret) { + WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)", + __func__, ret); + } else { + WMA_LOGI("%s: QOS MFP/PMF set to %d", + __func__, TRUE); + } + } +#endif /* WLAN_FEATURE_11W */ + + req.beacon_intval = add_bss->beaconInterval; + req.dtim_period = add_bss->dtimPeriod; + req.hidden_ssid = add_bss->bHiddenSSIDEn; + req.is_dfs = add_bss->bSpectrumMgtEnabled; + req.oper_mode = BSS_OPERATIONAL_MODE_AP; + req.ssid.length = add_bss->ssId.length; + if (req.ssid.length > 0) + vos_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, + add_bss->ssId.length); + + status = wma_vdev_start(wma, &req, VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + wma_remove_vdev_req(wma, vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_START); + goto peer_cleanup; + } + + wma_vdev_set_bss_params(wma, vdev_id, + add_bss->beaconInterval, add_bss->dtimPeriod, + add_bss->shortSlotTimeSupported, add_bss->llbCoexist, + maxTxPower); + + return; + +peer_cleanup: + wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, + VOS_FALSE); +send_fail_resp: + add_bss->status = VOS_STATUS_E_FAILURE; + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); +} + +#ifdef QCA_IBSS_SUPPORT +static VOS_STATUS +wma_set_ibss_pwrsave_params(tp_wma_handle wma, u_int8_t vdev_id) +{ + int ret; + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH, + wma->wma_ibss_power_save_params.atimWindowLength); + if (ret < 0) { + WMA_LOGE("Failed to set WMI_VDEV_PARAM_ATIM_WINDOW_LENGTH ret = %d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, + wma->wma_ibss_power_save_params.isPowerSaveAllowed); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, + wma->wma_ibss_power_save_params.isPowerCollapseAllowed); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, + wma->wma_ibss_power_save_params.isAwakeonTxRxEnabled); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_INACTIVITY_CNT, + wma->wma_ibss_power_save_params.inactivityCount); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_INACTIVITY_CNT ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, + wma->wma_ibss_power_save_params.txSPEndInactivityTime); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, + wma->wma_ibss_power_save_params.ibssPsWarmupTime); + if (ret < 0) { + WMA_LOGE("Failed, set WMI_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, + wma->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable); + if (ret < 0) { + WMA_LOGE("Failed to set IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE ret=%d", + ret); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + struct wma_vdev_start_req req; + ol_txrx_peer_handle peer = NULL; + struct wma_target_req *msg; + u_int8_t vdev_id, peer_id; + VOS_STATUS status; + tDelStaSelfParams del_sta_param; + tAddStaSelfParams add_sta_self_param; + tSetBssKeyParams key_info; + + WMA_LOGD("%s: add_bss->sessionId = %d", __func__, add_bss->sessionId); + vdev_id = add_bss->sessionId; + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + goto send_fail_resp; + } + wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss); + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("%s: vdev not found for vdev id %d.", + __func__, vdev_id); + goto send_fail_resp; + } + + /* only change vdev type to ibss during 1st time join_ibss handling */ + + if (FALSE == wma_is_vdev_in_ibss_mode(wma, vdev_id)) { + + WMA_LOGD("%s: vdev found for vdev id %d. deleting the vdev", + __func__, vdev_id); + + /* remove peers on the existing non-ibss vdev */ + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + WMA_LOGE("%s: peer found for vdev id %d. deleting the peer", + __func__, vdev_id); + wma_remove_peer(wma, (u_int8_t *)&vdev->mac_addr, + vdev_id, peer, VOS_FALSE); + } + + /* remove the non-ibss vdev */ + vos_copy_macaddr((v_MACADDR_t *)&(del_sta_param.selfMacAddr), + (v_MACADDR_t *)&(vdev->mac_addr)); + del_sta_param.sessionId = vdev_id; + del_sta_param.status = 0; + + wma_vdev_detach(wma, &del_sta_param, 0); + + /* create new vdev for ibss */ + vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr), + (v_MACADDR_t *)&(add_bss->selfMacAddr)); + add_sta_self_param.sessionId = vdev_id; + add_sta_self_param.type = WMI_VDEV_TYPE_IBSS; + add_sta_self_param.subType = 0; + add_sta_self_param.status = 0; + + vdev = wma_vdev_attach(wma, &add_sta_self_param, 0); + if (!vdev) { + WMA_LOGE("%s: Failed to create vdev", __func__); + goto send_fail_resp; + } + + WLANTL_RegisterVdev(wma->vos_context, vdev); + /* Register with TxRx Module for Data Ack Complete Cb */ + wdi_in_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma); + WMA_LOGA("new IBSS vdev created with mac %pM", add_bss->selfMacAddr); + + /* create ibss bss peer */ + status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr, + WMI_PEER_TYPE_DEFAULT, vdev_id, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer", __func__); + goto send_fail_resp; + } + WMA_LOGA("IBSS BSS peer created with mac %pM", add_bss->selfMacAddr); + } + + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->selfMacAddr, &peer_id); + if (!peer) { + WMA_LOGE("%s Failed to find peer %pM", __func__, + add_bss->selfMacAddr); + goto send_fail_resp; + } + + /* clear leftover ibss keys on bss peer */ + + WMA_LOGD("%s: ibss bss key clearing", __func__); + vos_mem_set(&key_info, sizeof(key_info), 0); + key_info.smesessionId = vdev_id; + key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + vos_mem_copy(&wma->ibsskey_info, &key_info, sizeof(tSetBssKeyParams)); + + /* start ibss vdev */ + + add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS; + + msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ, + WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, + WMA_VDEV_START_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s Failed to allocate vdev request vdev_id %d", + __func__, vdev_id); + goto peer_cleanup; + } + WMA_LOGD("%s: vdev start request for IBSS enqueued", __func__); + + add_bss->staContext.staIdx = ol_txrx_local_peer_id(peer); + + /* + * If IBSS Power Save is supported by firmware + * set the IBSS power save params to firmware. + */ + if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_IBSS_PWRSAVE)) { + status = wma_set_ibss_pwrsave_params(wma, vdev_id); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to Set IBSS Power Save Params to firmware", + __func__); + goto peer_cleanup; + } + } + + + vos_mem_zero(&req, sizeof(req)); + req.vdev_id = vdev_id; + req.chan = add_bss->currentOperChannel; + req.chan_offset = add_bss->currentExtChannel; + req.vht_capable = add_bss->vhtCapable; +#if defined WLAN_FEATURE_VOWIF + req.max_txpow = add_bss->maxTxPower; +#else + req.max_txpow = 0; +#endif + req.beacon_intval = add_bss->beaconInterval; + req.dtim_period = add_bss->dtimPeriod; + req.hidden_ssid = add_bss->bHiddenSSIDEn; + req.is_dfs = add_bss->bSpectrumMgtEnabled; + req.oper_mode = BSS_OPERATIONAL_MODE_IBSS; + req.ssid.length = add_bss->ssId.length; + if (req.ssid.length > 0) + vos_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, + add_bss->ssId.length); + + WMA_LOGD("%s: chan %d chan_offset %d", __func__, req.chan, req.chan_offset); + WMA_LOGD("%s: ssid = %s", __func__, req.ssid.ssId); + + status = wma_vdev_start(wma, &req, VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + wma_remove_vdev_req(wma, vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_START); + goto peer_cleanup; + } + WMA_LOGD("%s: vdev start request for IBSS sent to target", __func__); + + /* Initialize protection mode to no protection */ + if (wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PROTECTION_MODE, + IEEE80211_PROT_NONE)) { + WMA_LOGE("Failed to initialize protection mode"); + } + + return; + +peer_cleanup: + if (peer) { + wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, + VOS_FALSE); + } +send_fail_resp: + add_bss->status = VOS_STATUS_E_FAILURE; + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); +} +#endif + +static void wma_set_bss_rate_flags(struct wma_txrx_node *iface, + tpAddBssParams add_bss) +{ + iface->rate_flags = 0; + +#ifdef WLAN_FEATURE_11AC + if (add_bss->vhtCapable) { + if (add_bss->vhtTxChannelWidthSet) + iface->rate_flags |= eHAL_TX_RATE_VHT80; + else if (add_bss->txChannelWidthSet) + iface->rate_flags |= eHAL_TX_RATE_VHT40; + else + iface->rate_flags |= eHAL_TX_RATE_VHT20; + } + /* avoid to conflict with htCapable flag */ + else +#endif + if (add_bss->htCapable) { + if (add_bss->txChannelWidthSet) + iface->rate_flags |= eHAL_TX_RATE_HT40; + else + iface->rate_flags |= eHAL_TX_RATE_HT20; + } + + if (add_bss->staContext.fShortGI20Mhz || + add_bss->staContext.fShortGI40Mhz) + iface->rate_flags |= eHAL_TX_RATE_SGI; + + if (!add_bss->htCapable && !add_bss->vhtCapable) + iface->rate_flags = eHAL_TX_RATE_LEGACY; +} + +static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss) +{ + ol_txrx_pdev_handle pdev; + struct wma_vdev_start_req req; + struct wma_target_req *msg; + u_int8_t vdev_id, peer_id; + ol_txrx_peer_handle peer; + VOS_STATUS status; + struct wma_txrx_node *iface; + int ret = 0; + int pps_val = 0; + v_BOOL_t roam_synch_in_progress = VOS_FALSE; + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + if (NULL == pMac) { + WMA_LOGE("%s: Unable to get PE context", __func__); + goto send_fail_resp; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s Failed to get pdev", __func__); + goto send_fail_resp; + } + + vdev_id = add_bss->staContext.smesessionId; + iface = &wma->interfaces[vdev_id]; + + wma_set_bss_rate_flags(iface, add_bss); + if (add_bss->operMode) { + // Save parameters later needed by WDA_ADD_STA_REQ + if (iface->addBssStaContext) { + adf_os_mem_free(iface->addBssStaContext); + } + iface->addBssStaContext = adf_os_mem_alloc(NULL, sizeof(tAddStaParams)); + if (!iface->addBssStaContext) { + WMA_LOGE("%s Failed to allocat memory", __func__); + goto send_fail_resp; + } + adf_os_mem_copy(iface->addBssStaContext, &add_bss->staContext, + sizeof(tAddStaParams)); + +#if defined WLAN_FEATURE_VOWIFI_11R + if (iface->staKeyParams) { + adf_os_mem_free(iface->staKeyParams); + iface->staKeyParams = NULL; + } + if (add_bss->extSetStaKeyParamValid) { + iface->staKeyParams = adf_os_mem_alloc(NULL, sizeof(tSetStaKeyParams)); + if (!iface->staKeyParams) { + WMA_LOGE("%s Failed to allocat memory", __func__); + goto send_fail_resp; + } + adf_os_mem_copy(iface->staKeyParams, &add_bss->extSetStaKeyParam, + sizeof(tSetStaKeyParams)); + } +#endif + // Save parameters later needed by WDA_ADD_STA_REQ + iface->rmfEnabled = add_bss->rmfEnabled; + iface->beaconInterval = add_bss->beaconInterval; + iface->dtimPeriod = add_bss->dtimPeriod; + iface->llbCoexist = add_bss->llbCoexist; + iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported; + iface->nwType = add_bss->nwType; + if(add_bss->nonRoamReassoc) { + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id); + if(peer) { + add_bss->staContext.staIdx = ol_txrx_local_peer_id(peer); + goto send_bss_resp; + } + } + if (add_bss->reassocReq) { +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + ol_txrx_vdev_handle vdev; +#endif + // Called in preassoc state. BSSID peer is already added by set_linkstate + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id); + if (!peer) { + WMA_LOGE("%s Failed to find peer %pM", __func__, + add_bss->bssId); + goto send_fail_resp; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(iface->roam_synch_in_progress) { + add_bss->staContext.staIdx = ol_txrx_local_peer_id(peer); + goto send_bss_resp; + } +#endif + msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ, + WMA_TARGET_REQ_TYPE_VDEV_START, + add_bss, + WMA_VDEV_START_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s Failed to allocate vdev request vdev_id %d", + __func__, vdev_id); + goto peer_cleanup; + } + + add_bss->staContext.staIdx = ol_txrx_local_peer_id(peer); + + vos_mem_zero(&req, sizeof(req)); + req.vdev_id = vdev_id; + req.chan = add_bss->currentOperChannel; + req.chan_offset = add_bss->currentExtChannel; +#if defined WLAN_FEATURE_VOWIFI + req.max_txpow = add_bss->maxTxPower; +#else + req.max_txpow = 0; +#endif + req.beacon_intval = add_bss->beaconInterval; + req.dtim_period = add_bss->dtimPeriod; + req.hidden_ssid = add_bss->bHiddenSSIDEn; + req.is_dfs = add_bss->bSpectrumMgtEnabled; + req.ssid.length = add_bss->ssId.length; + req.oper_mode = BSS_OPERATIONAL_MODE_STA; + if (req.ssid.length > 0) + vos_mem_copy(req.ssid.ssId, add_bss->ssId.ssId, + add_bss->ssId.length); + + status = wma_vdev_start(wma, &req, VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + wma_remove_vdev_req(wma, vdev_id, + WMA_TARGET_REQ_TYPE_VDEV_START); + goto peer_cleanup; + } +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("%s Invalid txrx vdev", __func__); + goto peer_cleanup; + } + wdi_in_vdev_pause(vdev, + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); +#endif + // ADD_BSS_RESP will be deferred to completion of VDEV_START + + return; + } + if (!add_bss->updateBss) { + goto send_bss_resp; + + } + /* Update peer state */ + if (add_bss->staContext.encryptType == eSIR_ED_NONE) { + WMA_LOGD("%s: Update peer(%pM) state into auth", + __func__, add_bss->bssId); + ol_txrx_peer_state_update(pdev, add_bss->bssId, + ol_txrx_peer_state_auth); + } else { +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + ol_txrx_vdev_handle vdev; +#endif + WMA_LOGD("%s: Update peer(%pM) state into conn", + __func__, add_bss->bssId); + ol_txrx_peer_state_update(pdev, add_bss->bssId, + ol_txrx_peer_state_conn); +#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id); + if (!peer) { + WMA_LOGE("%s:%d Failed to find peer %pM", __func__, + __LINE__, add_bss->bssId); + goto send_fail_resp; + } + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("%s Invalid txrx vdev", __func__); + goto peer_cleanup; + } + wdi_in_vdev_pause(vdev, + OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED); +#endif + } + + wmi_unified_send_txbf(wma, &add_bss->staContext); + + pps_val = ((pMac->enable5gEBT << 31) & 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff); + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PACKET_POWERSAVE, + pps_val); + if (ret) + WMA_LOGE("Failed to send wmi packet power save cmd"); + else + WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, ret = %d", + pps_val, ret); + + wmi_unified_send_peer_assoc(wma, add_bss->nwType, + &add_bss->staContext); +#ifdef WLAN_FEATURE_11W + if (add_bss->rmfEnabled) { + /* when 802.11w PMF is enabled for hw encr/decr + use hw MFP Qos bits 0x10 */ + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_PMF_QOS, TRUE); + if(ret) { + WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)", + __func__, ret); + } else { + WMA_LOGI("%s: QOS MFP/PMF set to %d", + __func__, TRUE); + } + } +#endif /* WLAN_FEATURE_11W */ + + wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId, + add_bss->beaconInterval, add_bss->dtimPeriod, + add_bss->shortSlotTimeSupported, add_bss->llbCoexist, + add_bss->maxTxPower); + + /* + * Store the bssid in interface table, bssid will + * be used during group key setting sta mode. + */ + vos_mem_copy(iface->bssid, add_bss->bssId, ETH_ALEN); + + } +send_bss_resp: + ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, + &add_bss->staContext.staIdx); + add_bss->status = (add_bss->staContext.staIdx < 0) ? + VOS_STATUS_E_FAILURE : VOS_STATUS_SUCCESS; + add_bss->bssIdx = add_bss->staContext.smesessionId; + vos_mem_copy(add_bss->staContext.staMac, add_bss->bssId, + sizeof(add_bss->staContext.staMac)); + WMA_LOGD("%s: opermode %d update_bss %d nw_type %d bssid %pM" + " staIdx %d status %d", __func__, add_bss->operMode, + add_bss->updateBss, add_bss->nwType, add_bss->bssId, + add_bss->staContext.staIdx, add_bss->status); + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); + return; + +peer_cleanup: + wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, + roam_synch_in_progress); +send_fail_resp: + add_bss->status = VOS_STATUS_E_FAILURE; + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); +} + +static void wma_add_bss(tp_wma_handle wma, tpAddBssParams params) +{ + WMA_LOGD("%s: add_bss_param.halPersona = %d", + __func__, params->halPersona); + + switch(params->halPersona) { + + case VOS_STA_SAP_MODE: + case VOS_P2P_GO_MODE: + wma_add_bss_ap_mode(wma, params); + break; + +#ifdef QCA_IBSS_SUPPORT + case VOS_IBSS_MODE: + wma_add_bss_ibss_mode(wma, params); + break; +#endif + + default: + wma_add_bss_sta_mode(wma, params); + break; + } +} + +static int wmi_unified_vdev_up_send(wmi_unified_t wmi, + u_int8_t vdev_id, u_int16_t aid, + u_int8_t bssid[IEEE80211_ADDR_LEN]) +{ + wmi_vdev_up_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + WMA_LOGD("%s: VDEV_UP", __func__); + WMA_LOGD("%s: vdev_id %d aid %d bssid %pM", __func__, + vdev_id, aid, bssid); + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_vdev_up_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_up_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_up_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->vdev_assoc_id = aid; + WMI_CHAR_ARRAY_TO_MAC_ADDR(bssid, &cmd->vdev_bssid); + if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_UP_CMDID)) { + WMA_LOGP("%s: Failed to send vdev up command", __func__); + adf_nbuf_free(buf); + return -EIO; + } + return 0; +} + +static int32_t wmi_unified_set_ap_ps_param(void *wma_ctx, u_int32_t vdev_id, + u_int8_t *peer_addr, u_int32_t param, u_int32_t value) +{ + tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx; + wmi_ap_ps_peer_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t err; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_ap_ps_param cmd"); + return -ENOMEM; + } + cmd = (wmi_ap_ps_peer_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ap_ps_peer_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_ap_ps_peer_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + cmd->param = param; + cmd->value = value; + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(*cmd), WMI_AP_PS_PEER_PARAM_CMDID); + if (err) { + WMA_LOGE("Failed to send set_ap_ps_param cmd"); + adf_os_mem_free(buf); + return -EIO; + } + return 0; +} + +static int32_t wma_set_ap_peer_uapsd(tp_wma_handle wma, u_int32_t vdev_id, + u_int8_t *peer_addr, u_int8_t uapsd_value, u_int8_t max_sp) +{ + u_int32_t uapsd = 0; + u_int32_t max_sp_len = 0; + int32_t ret = 0; + + if (uapsd_value & UAPSD_VO_ENABLED) { + uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN | + WMI_AP_PS_UAPSD_AC3_TRIGGER_EN; + } + + if (uapsd_value & UAPSD_VI_ENABLED) { + uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN | + WMI_AP_PS_UAPSD_AC2_TRIGGER_EN; + } + + if (uapsd_value & UAPSD_BK_ENABLED) { + uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN | + WMI_AP_PS_UAPSD_AC1_TRIGGER_EN; + } + + if (uapsd_value & UAPSD_BE_ENABLED) { + uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN | + WMI_AP_PS_UAPSD_AC0_TRIGGER_EN; + } + + switch (max_sp) { + case UAPSD_MAX_SP_LEN_2: + max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_2; + break; + case UAPSD_MAX_SP_LEN_4: + max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_4; + break; + case UAPSD_MAX_SP_LEN_6: + max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_6; + break; + default: + max_sp_len = WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED; + break; + } + + WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_UAPSD 0x%x for %pM", + uapsd, peer_addr); + + ret = wmi_unified_set_ap_ps_param(wma, vdev_id, + peer_addr, + WMI_AP_PS_PEER_PARAM_UAPSD, + uapsd); + if (ret) { + WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_UAPSD for %pM", + peer_addr); + return ret; + } + + WMA_LOGD("Set WMI_AP_PS_PEER_PARAM_MAX_SP 0x%x for %pM", + max_sp_len, peer_addr); + + ret = wmi_unified_set_ap_ps_param(wma, vdev_id, + peer_addr, + WMI_AP_PS_PEER_PARAM_MAX_SP, + max_sp_len); + if (ret) { + WMA_LOGE("Failed to set WMI_AP_PS_PEER_PARAM_MAX_SP for %pM", + peer_addr); + return ret; + } + return 0; +} + +static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) +{ + enum ol_txrx_peer_state state = ol_txrx_peer_state_conn; + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + u_int8_t peer_id; + VOS_STATUS status; + int32_t ret; +#ifdef WLAN_FEATURE_11W + struct wma_txrx_node *iface = NULL; +#endif /* WLAN_FEATURE_11W */ + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to find pdev", __func__); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + /* UMAC sends WDA_ADD_STA_REQ msg twice to WMA when the station + * associates. First WDA_ADD_STA_REQ will have staType as + * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF. + * Peer creation is done in first WDA_ADD_STA_REQ and second + * WDA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and + * send fake response with success to UMAC. Otherwise UMAC + * will get blocked. + */ + if (add_sta->staType != STA_ENTRY_PEER) { + add_sta->status = VOS_STATUS_SUCCESS; + goto send_rsp; + } + + vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); + if (!vdev) { + WMA_LOGE("%s: Failed to find vdev", __func__); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + peer = ol_txrx_find_peer_by_addr_and_vdev(pdev, + vdev, + add_sta->staMac, + &peer_id); + if (peer) { + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, + peer, VOS_FALSE); + WMA_LOGE("%s: Peer already exists, Deleted peer with peer_addr %pM", + __func__, add_sta->staMac); + } + + status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, + WMI_PEER_TYPE_DEFAULT, add_sta->smesessionId, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer for %pM", + __func__, add_sta->staMac); + add_sta->status = status; + goto send_rsp; + } + + peer = ol_txrx_find_peer_by_addr_and_vdev(pdev, + vdev, + add_sta->staMac, + &peer_id); + if (!peer) { + WMA_LOGE("%s: Failed to find peer handle using peer mac %pM", + __func__, add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, + peer, VOS_FALSE); + goto send_rsp; + } + + wmi_unified_send_txbf(wma, add_sta); + + ret = wmi_unified_send_peer_assoc(wma, add_sta->nwType, add_sta); + if (ret) { + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, + peer, VOS_FALSE); + goto send_rsp; + } + +#ifdef QCA_IBSS_SUPPORT + /* + * In IBSS mode send the peer + * Atim Window length if IBSS + * power save is enabled by the + * firmware. + */ + if ( wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId) && + WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_IBSS_PWRSAVE) ) { + /* + * If ATIM Window is present in the peer + * beacon then send it to firmware else + * configure Zero ATIM Window length to + * firmware. + */ + if(add_sta->atimIePresent) { + wma_set_peer_param(wma, add_sta->staMac, + WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, + add_sta->peerAtimWindowLength, + add_sta->smesessionId); + } + else { + wma_set_peer_param(wma, add_sta->staMac, + WMI_PEER_IBSS_ATIM_WINDOW_LENGTH, + 0, + add_sta->smesessionId); + } + } +#endif + +#ifdef WLAN_FEATURE_11W + if (add_sta->rmfEnabled) { + /* + * We have to store the state of PMF connection + * per STA for SAP case + * We will isolate the ifaces based on vdevid + */ + iface = &wma->interfaces[vdev->vdev_id]; + iface->rmfEnabled = add_sta->rmfEnabled; + /* + * when 802.11w PMF is enabled for hw encr/decr + * use hw MFP Qos bits 0x10 + */ + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_PMF_QOS, TRUE); + if(ret) { + WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)", + __func__, ret); + } + else { + WMA_LOGI("%s: QOS MFP/PMF set to %d", + __func__, TRUE); + } + } +#endif /* WLAN_FEATURE_11W */ + + if (add_sta->uAPSD) { + ret = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId, + add_sta->staMac, + add_sta->uAPSD, + add_sta->maxSPLen); + if (ret) { + WMA_LOGE("Failed to set peer uapsd param for %pM", + add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, + add_sta->smesessionId, peer, + VOS_FALSE); + goto send_rsp; + } + } + + WMA_LOGD("%s: Moving peer %pM to state %d", + __func__, add_sta->staMac, state); + ol_txrx_peer_state_update(pdev, add_sta->staMac, state); + + add_sta->staIdx = ol_txrx_local_peer_id(peer); + add_sta->status = VOS_STATUS_SUCCESS; +send_rsp: + WMA_LOGD("%s: Sending add sta rsp to umac (mac:%pM, status:%d)", + __func__, add_sta->staMac, add_sta->status); + wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)add_sta, 0); +} + +static int wmi_unified_nat_keepalive_enable(tp_wma_handle wma, + u_int8_t vdev_id) +{ + WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + WMA_LOGD("%s: vdev_id %d", __func__, vdev_id); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE; + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) { + WMA_LOGP("%s: Failed to send NAT keepalive enable command", + __func__); + wmi_buf_free(buf); + return -EIO; + } + return 0; +} + +static int wmi_unified_csa_offload_enable(tp_wma_handle wma, + u_int8_t vdev_id) +{ + wmi_csa_offload_enable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + WMA_LOGD("%s: vdev_id %d", __func__, vdev_id); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_csa_offload_enable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_csa_offload_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_csa_offload_enable_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->csa_offload_enable = WMI_CSA_OFFLOAD_ENABLE; + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_CSA_OFFLOAD_ENABLE_CMDID)) { + WMA_LOGP("%s: Failed to send CSA offload enable command", + __func__); + wmi_buf_free(buf); + return -EIO; + } + return 0; +} + +#ifdef QCA_IBSS_SUPPORT + +static u_int16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num) +{ + /* heart beat timer value look-up table */ + /* entry index : (the number of currently connected peers) - 1 + entry value : the heart time threshold value in seconds for + detecting ibss peer departure */ + static const u_int16_t heart_beat_timer[HDD_MAX_NUM_IBSS_STA] = { + 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 12, 12, 12, 12, + 16, 16, 16, 16, 16, 16, 16, 16}; + + if (peer_num < 1 || peer_num > HDD_MAX_NUM_IBSS_STA) + return 0; + + return heart_beat_timer[peer_num - 1]; + +} + +static void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma, + u_int8_t vdev_id, + int8_t peer_num_delta) +{ + ol_txrx_vdev_handle vdev; + int16_t new_peer_num; + u_int16_t new_timer_value_sec; + u_int32_t new_timer_value_ms; + + if (peer_num_delta != 1 && peer_num_delta != -1) { + WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta); + return; + } + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("vdev not found : vdev_id %d", vdev_id); + return; + } + + new_peer_num = vdev->ibss_peer_num + peer_num_delta; + if (new_peer_num > HDD_MAX_NUM_IBSS_STA || new_peer_num < 0) { + WMA_LOGE("new peer num %d out of valid boundary", new_peer_num); + return; + } + + /* adjust peer numbers */ + vdev->ibss_peer_num = new_peer_num; + + /* reset timer value if all peers departed */ + if (new_peer_num == 0) { + vdev->ibss_peer_heart_beat_timer = 0; + return; + } + + /* calculate new timer value */ + new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num); + if (new_timer_value_sec == 0) { + WMA_LOGE("timer value %d is invalid for peer number %d", + new_timer_value_sec, new_peer_num); + return; + } + if (new_timer_value_sec == vdev->ibss_peer_heart_beat_timer) { + WMA_LOGD("timer value %d stays same, no need to notify target", + new_timer_value_sec); + return; + } + + /* send new timer value to target */ + vdev->ibss_peer_heart_beat_timer = new_timer_value_sec; + + new_timer_value_ms = ((u_int32_t)new_timer_value_sec) * 1000; + + if (wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, + new_timer_value_ms)) { + WMA_LOGE("Failed to set IBSS link monitoring timer value"); + return; + } + + WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d", + new_peer_num, new_timer_value_ms); +} + +#endif /* QCA_IBSS_SUPPORT */ + +#ifdef FEATURE_WLAN_TDLS +static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + u_int8_t peer_id; + VOS_STATUS status; + int32_t ret; + tTdlsPeerStateParams *peerStateParams; + + WMA_LOGD("%s: staType: %d, staIdx: %d, updateSta: %d, " + "bssId: %pM, staMac: %pM", + __func__, add_sta->staType, add_sta->staIdx, + add_sta->updateSta, add_sta->bssId, add_sta->staMac); + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to find pdev", __func__); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); + if (!vdev) { + WMA_LOGE("%s: Failed to find vdev", __func__); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + if (0 == add_sta->updateSta) { + /* its a add sta request **/ +#if defined(CONFIG_HL_SUPPORT) + if (add_sta->bssId && vdev->last_real_peer && + (adf_os_mem_cmp((u8 *)add_sta->bssId, + vdev->last_real_peer->mac_addr.raw, + IEEE80211_ADDR_LEN) == 0)) { + adf_os_mem_copy(vdev->hl_tdls_ap_mac_addr.raw, + vdev->last_real_peer->mac_addr.raw, + OL_TXRX_MAC_ADDR_LEN); + } +#endif + WMA_LOGD("%s: addSta, calling wma_create_peer for %pM, vdev_id %hu", + __func__, add_sta->staMac, add_sta->smesessionId); + + status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, + WMI_PEER_TYPE_TDLS, add_sta->smesessionId, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer for %pM", + __func__, add_sta->staMac); + add_sta->status = status; + goto send_rsp; + } + + peer = ol_txrx_find_peer_by_addr(pdev, add_sta->staMac, &peer_id); + if (!peer) { + WMA_LOGE("%s: addSta, failed to find peer handle for mac %pM", + __func__, add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, peer, + VOS_FALSE); +#if defined(CONFIG_HL_SUPPORT) + if (vdev->last_real_peer == NULL) { + peer = NULL; + peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id); + if (peer && (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + vdev->last_real_peer = peer; + } +#endif + goto send_rsp; + } + + add_sta->staIdx = ol_txrx_local_peer_id(peer); + WMA_LOGD("%s: addSta, after calling ol_txrx_local_peer_id, " + "staIdx: %d, staMac: %pM", + __func__, add_sta->staIdx, add_sta->staMac); + + peerStateParams = vos_mem_malloc(sizeof(tTdlsPeerStateParams)); + if (!peerStateParams) { + WMA_LOGE("%s: Failed to allocate memory for peerStateParams for %pM", + __func__, add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + vos_mem_zero(peerStateParams, sizeof(*peerStateParams)); + peerStateParams->peerState = WMI_TDLS_PEER_STATE_PEERING; + peerStateParams->vdevId = vdev->vdev_id; + vos_mem_copy(&peerStateParams->peerMacAddr, + &add_sta->staMac, + sizeof(tSirMacAddr)); + wma_update_tdls_peer_state(wma, peerStateParams); + } else { + /* its a change sta request **/ + peer = ol_txrx_find_peer_by_addr(pdev, add_sta->staMac, &peer_id); + if (!peer) { + WMA_LOGE("%s: changeSta,failed to find peer handle for mac %pM", + __func__, add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, peer, + VOS_FALSE); +#if defined(CONFIG_HL_SUPPORT) + if (vdev->last_real_peer == NULL) { + peer = NULL; + peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id); + if (peer && (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + vdev->last_real_peer = peer; + } +#endif + goto send_rsp; + } + + WMA_LOGD("%s: changeSta, calling wmi_unified_send_peer_assoc", + __func__); + + ret = wmi_unified_send_peer_assoc(wma, add_sta->nwType, add_sta); + if (ret) { + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, peer, + VOS_FALSE); +#if defined(CONFIG_HL_SUPPORT) + if (vdev->last_real_peer == NULL) { + peer = NULL; + peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id); + if (peer && (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + vdev->last_real_peer = peer; + } +#endif + goto send_rsp; + } + } + +send_rsp: + WMA_LOGD("%s: Sending add sta rsp to umac (mac:%pM, status:%d), " + "staType: %d, staIdx: %d, updateSta: %d", + __func__, add_sta->staMac, add_sta->status, + add_sta->staType, add_sta->staIdx, add_sta->updateSta); + wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)add_sta, 0); +} +#endif + +static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) +{ + ol_txrx_pdev_handle pdev; + VOS_STATUS status = VOS_STATUS_SUCCESS; + ol_txrx_peer_handle peer; + struct wma_txrx_node *iface = NULL; + tPowerdBm maxTxPower; + int ret = 0; + +#ifdef FEATURE_WLAN_TDLS + if (STA_ENTRY_TDLS_PEER == params->staType) + { + wma_add_tdls_sta(wma, params); + return; + } +#endif + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Unable to get pdev", __func__); + goto out; + } + + iface = &wma->interfaces[params->smesessionId]; + if (params->staType != STA_ENTRY_SELF) { + WMA_LOGP("%s: unsupported station type %d", + __func__, params->staType); + goto out; + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssId, ¶ms->staIdx); + if(params->nonRoamReassoc) { + ol_txrx_peer_state_update(pdev, params->bssId, + ol_txrx_peer_state_auth); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); + iface->aid = params->assocId; + goto out; + } + if (wma->interfaces[params->smesessionId].vdev_up == true) { + WMA_LOGE("%s: vdev id %d is already UP for %pM", __func__, + params->smesessionId, params->bssId); + status = VOS_STATUS_E_FAILURE; + goto out; + } + if (peer != NULL && peer->state == ol_txrx_peer_state_disc) { + /* + * This is the case for reassociation. + * peer state update and peer_assoc is required since it + * was not done by WDA_ADD_BSS_REQ. + */ + + /* Update peer state */ + if (params->encryptType == eSIR_ED_NONE) { + WMA_LOGD("%s: Update peer(%pM) state into auth", + __func__, params->bssId); + ol_txrx_peer_state_update(pdev, params->bssId, + ol_txrx_peer_state_auth); + } else { + WMA_LOGD("%s: Update peer(%pM) state into conn", + __func__, params->bssId); + ol_txrx_peer_state_update(pdev, params->bssId, + ol_txrx_peer_state_conn); + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(iface->roam_synch_in_progress) + { + // iface->nss = params->nss; + /*In LFR2.0, the following operations are performed as + * part of wmi_unified_send_peer_assoc. As we are + * skipping this operation, we are just executing the + * following which are useful for LFR3.0.*/ + ol_txrx_peer_state_update(pdev, params->bssId, + ol_txrx_peer_state_auth); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); + iface->aid = params->assocId; + goto out; + } +#endif + wmi_unified_send_txbf(wma, params); + + ret = wmi_unified_send_peer_assoc(wma, + iface->nwType, + (tAddStaParams *)iface->addBssStaContext); + if (ret) { + status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, params->bssId, + params->smesessionId, peer, VOS_FALSE); + goto out; + } + +#ifdef WLAN_FEATURE_11W + if (params->rmfEnabled) { + /* when 802.11w PMF is enabled for hw encr/decr + use hw MFP Qos bits 0x10 */ + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_PMF_QOS, TRUE); + if(ret) { + WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)", + __func__, ret); + } else { + WMA_LOGI("%s: QOS MFP/PMF set to %d", + __func__, TRUE); + } + } +#endif /* WLAN_FEATURE_11W */ +#if defined WLAN_FEATURE_VOWIFI_11R + /* + * Set the PTK in 11r mode because we already have it. + */ + if (iface->staKeyParams) { + wma_set_stakey(wma, (tpSetStaKeyParams) iface->staKeyParams); + } +#endif + } +#if defined WLAN_FEATURE_VOWIFI + maxTxPower = params->maxTxPower; +#else + maxTxPower = 0; +#endif + wma_vdev_set_bss_params(wma, params->smesessionId, iface->beaconInterval, + iface->dtimPeriod, iface->shortSlotTimeSupported, + iface->llbCoexist, maxTxPower); + + params->csaOffloadEnable = 0; + if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_CSA_OFFLOAD)) { + params->csaOffloadEnable = 1; + if (wmi_unified_csa_offload_enable(wma, params->smesessionId) < 0) { + WMA_LOGE("Unable to enable CSA offload for vdev_id:%d", + params->smesessionId); + } + } + + if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE)) { + if (wmi_unified_nat_keepalive_enable(wma, params->smesessionId) < 0) { + WMA_LOGE("Unable to enable NAT keepalive for vdev_id:%d", + params->smesessionId); + } + } + + if (wmi_unified_vdev_up_send(wma->wmi_handle, params->smesessionId, + params->assocId, params->bssId) < 0) { + WMA_LOGP("%s: Failed to send vdev up cmd: vdev %d bssid %pM", + __func__, params->smesessionId, params->bssId); + status = VOS_STATUS_E_FAILURE; + } + else { + wma->interfaces[params->smesessionId].vdev_up = TRUE; + } + + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); + WMA_LOGD("%s: STA mode (type %d subtype %d) BSS is started", + __func__, iface->type, iface->sub_type); + /* Sta is now associated, configure various params */ + + /* SM power save, configure the h/w as configured + * in the ini file. SMPS is not published in assoc + * request. Once configured, fw sends the required + * action frame to AP. + */ + if (params->enableHtSmps) + wma_set_mimops(wma, params->smesessionId, + params->htSmpsconfig); + +#ifdef WLAN_FEATURE_11AC + /* Partial AID match power save, enable when SU bformee*/ + if (params->enableVhtpAid && params->vhtTxBFCapable) + wma_set_ppsconfig(params->smesessionId, + WMA_VHT_PPS_PAID_MATCH, 1); +#endif + + /* Enable AMPDU power save, if htCapable/vhtCapable */ + if (params->enableAmpduPs && + (params->htCapable || params->vhtCapable)) + wma_set_ppsconfig(params->smesessionId, + WMA_VHT_PPS_DELIM_CRC_FAIL, 1); + iface->aid = params->assocId; +out: + params->status = status; +/* change logging before release */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(iface && iface->roam_synch_in_progress) + WMA_LOGD("%s:statype %d vdevid %d aid %d bssid %pM staIdx %d status %d", + __func__, params->staType, params->smesessionId, + params->assocId, params->bssId, params->staIdx, status); + else + WMA_LOGE("%s:statype %d vdevid %d aid %d bssid %pM staIdx %d status %d", + __func__, params->staType, params->smesessionId, + params->assocId, params->bssId, params->staIdx, status); +#endif + wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)params, 0); +} + +#ifdef FEATURE_WLAN_D0WOW +static void wma_add_pm_vote(tp_wma_handle wma) +{ + if (++wma->ap_client_cnt == 1) + vos_pm_control(DISABLE_PCIE_POWER_COLLAPSE); +} + +static void wma_del_pm_vote(tp_wma_handle wma) +{ + if (--wma->ap_client_cnt == 0) + vos_pm_control(ENABLE_PCIE_POWER_COLLAPSE); +} + +int wma_get_client_count(WMA_HANDLE handle) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + return wma->ap_client_cnt; +} +#else +static void wma_prevent_suspend_check(tp_wma_handle wma) +{ + wma->ap_client_cnt++; + if (wma->ap_client_cnt == + wma->wlan_resource_config.num_offload_peers) { + vos_wake_lock_acquire(&wma->wow_wake_lock); + WMA_LOGW("%s: %d clients connected, prevent suspend", + __func__, wma->ap_client_cnt); + } +} + +static void wma_allow_suspend_check(tp_wma_handle wma) +{ + wma->ap_client_cnt--; + if (wma->ap_client_cnt == + wma->wlan_resource_config.num_offload_peers - 1) { + vos_wake_lock_release(&wma->wow_wake_lock); + WMA_LOGW("%s: %d clients connected, allow suspend", + __func__, wma->ap_client_cnt); + } +} +#endif /* FEATURE_WLAN_D0WOW */ + +static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) +{ + tANI_U8 oper_mode = BSS_OPERATIONAL_MODE_STA; + + WMA_LOGD("%s: add_sta->sessionId = %d.", __func__, add_sta->smesessionId); + WMA_LOGD("%s: add_sta->bssId = %x:%x:%x:%x:%x:%x", __func__, + add_sta->bssId[0], add_sta->bssId[1], add_sta->bssId[2], + add_sta->bssId[3], add_sta->bssId[4], add_sta->bssId[5]); + + if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId)) { +#ifdef FEATURE_WLAN_D0WOW + wma_add_pm_vote(wma); +#else + wma_prevent_suspend_check(wma); +#endif + oper_mode = BSS_OPERATIONAL_MODE_AP; + } +#ifdef QCA_IBSS_SUPPORT + else if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId)) { + oper_mode = BSS_OPERATIONAL_MODE_IBSS; +#ifdef FEATURE_WLAN_D0WOW + wma_add_pm_vote(wma); +#endif + } +#endif + + switch (oper_mode) { + case BSS_OPERATIONAL_MODE_STA: + wma_add_sta_req_sta_mode(wma, add_sta); + break; + +#ifdef QCA_IBSS_SUPPORT + case BSS_OPERATIONAL_MODE_IBSS: /* IBSS should share the same code as AP mode */ +#endif + case BSS_OPERATIONAL_MODE_AP: + wma_add_sta_req_ap_mode(wma, add_sta); + break; + } + +#ifdef QCA_IBSS_SUPPORT + /* adjust heart beat thresold timer value for detecting ibss peer departure */ + if (oper_mode == BSS_OPERATIONAL_MODE_IBSS) + wma_adjust_ibss_heart_beat_timer(wma, add_sta->smesessionId, 1); +#endif + +} + +/* + * This function reads WEP keys from cfg and fills + * up key_info. + */ +static void wma_read_cfg_wepkey(tp_wma_handle wma_handle, + tSirKeys *key_info, v_U32_t *def_key_idx, + u_int8_t *num_keys) +{ + tSirRetStatus status; + v_U32_t val = SIR_MAC_KEY_LENGTH; + u_int8_t i, j; + + WMA_LOGD("Reading WEP keys from cfg"); + /* NOTE:def_key_idx is initialized to 0 by the caller */ + status = wlan_cfgGetInt(wma_handle->mac_context, + WNI_CFG_WEP_DEFAULT_KEYID, def_key_idx); + if (status != eSIR_SUCCESS) + WMA_LOGE("Unable to read default id, defaulting to 0"); + + for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) { + status = wlan_cfgGetStr(wma_handle->mac_context, + (u_int16_t) WNI_CFG_WEP_DEFAULT_KEY_1 + i, + key_info[j].key, &val); + if (status != eSIR_SUCCESS) { + WMA_LOGE("WEP key is not configured at :%d", i); + } else { + key_info[j].keyId = i; + key_info[j].keyLength = (u_int16_t) val; + j++; + } + } + *num_keys = j; +} + +/* + * This function setsup wmi buffer from information + * passed in key_params. + */ +static wmi_buf_t wma_setup_install_key_cmd(tp_wma_handle wma_handle, + struct wma_set_key_params *key_params, + u_int32_t *len) +{ + wmi_vdev_install_key_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int8_t *buf_ptr; + u_int8_t *key_data; +#ifdef WLAN_FEATURE_11W + struct wma_txrx_node *iface = NULL; +#endif /* WLAN_FEATURE_11W */ + if ((key_params->key_type == eSIR_ED_NONE && + key_params->key_len) || (key_params->key_type != eSIR_ED_NONE && + !key_params->key_len)) { + WMA_LOGE("%s:Invalid set key request", __func__); + return NULL; + } + + *len = sizeof(*cmd) + roundup(key_params->key_len, sizeof(u_int32_t)) + + WMI_TLV_HDR_SIZE; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, *len); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set key cmd"); + return NULL; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_vdev_install_key_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_install_key_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_install_key_cmd_fixed_param)); + cmd->vdev_id = key_params->vdev_id; + cmd->key_ix = key_params->key_idx; + WMI_CHAR_ARRAY_TO_MAC_ADDR(key_params->peer_mac, + &cmd->peer_macaddr); + if (key_params->unicast) + cmd->key_flags |= PAIRWISE_USAGE; + else + cmd->key_flags |= GROUP_USAGE; + + switch (key_params->key_type) { + case eSIR_ED_NONE: + cmd->key_cipher = WMI_CIPHER_NONE; + break; + case eSIR_ED_WEP40: + case eSIR_ED_WEP104: + cmd->key_cipher = WMI_CIPHER_WEP; + if (key_params->unicast && + cmd->key_ix == key_params->def_key_idx) + cmd->key_flags |= TX_USAGE; + break; + case eSIR_ED_TKIP: + cmd->key_txmic_len = WMA_TXMIC_LEN; + cmd->key_rxmic_len = WMA_RXMIC_LEN; + cmd->key_cipher = WMI_CIPHER_TKIP; + break; +#ifdef FEATURE_WLAN_WAPI +#define WPI_IV_LEN 16 + case eSIR_ED_WPI: + { + /*initialize receive and transmit IV with default values*/ + unsigned char tx_iv[16] = {0x36,0x5c,0x36,0x5c,0x36,0x5c,0x36, + 0x5c,0x36,0x5c,0x36,0x5c,0x36,0x5c, + 0x36,0x5c}; + unsigned char rx_iv[16] = {0x5c,0x36,0x5c,0x36,0x5c,0x36,0x5c, + 0x36,0x5c,0x36,0x5c,0x36,0x5c,0x36, + 0x5c,0x37}; + cmd->key_txmic_len = WMA_TXMIC_LEN; + cmd->key_rxmic_len = WMA_RXMIC_LEN; + /*Authenticator initializes the value of PN as + *0x5C365C365C365C365C365C365C365C36 for multicast key update. + */ + if (!key_params->unicast) + rx_iv[WPI_IV_LEN - 1] = 0x36; + + vos_mem_copy(&cmd->wpi_key_rsc_counter, &rx_iv, WPI_IV_LEN); + vos_mem_copy(&cmd->wpi_key_tsc_counter, &tx_iv, WPI_IV_LEN); + cmd->key_cipher = WMI_CIPHER_WAPI; + break; + } +#endif + case eSIR_ED_CCMP: + cmd->key_cipher = WMI_CIPHER_AES_CCM; + break; +#ifdef WLAN_FEATURE_11W + case eSIR_ED_AES_128_CMAC: + cmd->key_cipher = WMI_CIPHER_AES_CMAC; + break; +#endif /* WLAN_FEATURE_11W */ + default: + /* TODO: MFP ? */ + WMA_LOGE("%s:Invalid encryption type:%d", __func__, key_params->key_type); + adf_nbuf_free(buf); + return NULL; + } + + buf_ptr += sizeof(wmi_vdev_install_key_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + roundup(key_params->key_len, sizeof(u_int32_t))); + key_data = (A_UINT8*)(buf_ptr + WMI_TLV_HDR_SIZE); +#ifdef BIG_ENDIAN_HOST + { + /* for big endian host, copy engine byte_swap is enabled + * But the key data content is in network byte order + * Need to byte swap the key data content - so when copy engine + * does byte_swap - target gets key_data content in the correct + * order. + */ + int8_t i; + u_int32_t *destp, *srcp; + + destp = (u_int32_t *) key_data; + srcp = (u_int32_t *) key_params->key_data; + for(i = 0; + i < roundup(key_params->key_len, sizeof(u_int32_t)) / 4; + i++) { + *destp = le32_to_cpu(*srcp); + destp++; + srcp++; + } + } +#else + vos_mem_copy((void *) key_data, + (const void *) key_params->key_data, + key_params->key_len); +#endif + cmd->key_len = key_params->key_len; + +#ifdef WLAN_FEATURE_11W + if (key_params->key_type == eSIR_ED_AES_128_CMAC) + { + iface = &wma_handle->interfaces[key_params->vdev_id]; + if (iface) { + iface->key.key_length = key_params->key_len; + vos_mem_copy (iface->key.key, + (const void *) key_params->key_data, + iface->key.key_length); + if ((cmd->key_ix == WMA_IGTK_KEY_INDEX_4) || + (cmd->key_ix == WMA_IGTK_KEY_INDEX_5)) + vos_mem_zero (iface->key.key_id[cmd->key_ix - WMA_IGTK_KEY_INDEX_4].ipn, + CMAC_IPN_LEN); + } + } +#endif /* WLAN_FEATURE_11W */ + + WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d" + " unicast %d peer_mac %pM def_key_idx %d", key_params->vdev_id, + key_params->key_idx, key_params->key_type, key_params->key_len, + key_params->unicast, key_params->peer_mac, + key_params->def_key_idx); + + return buf; +} + +static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) +{ + struct wma_set_key_params key_params; + wmi_buf_t buf; + int32_t status; + u_int32_t len = 0, i; + v_U32_t def_key_idx = 0; + ol_txrx_vdev_handle txrx_vdev; + + WMA_LOGD("BSS key setup"); + txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); + if (!txrx_vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + + /* + ** For IBSS, WMI expects the BSS key to be set per peer key + ** So cache the BSS key in the wma_handle and re-use it when the STA key is been setup for a peer + */ + if (wlan_op_mode_ibss == txrx_vdev->opmode) { + key_info->status = eHAL_STATUS_SUCCESS; + if (wma_handle->ibss_started > 0) + goto out; + WMA_LOGD("Caching IBSS Key"); + vos_mem_copy(&wma_handle->ibsskey_info, key_info, sizeof(tSetBssKeyParams)); + } + + adf_os_mem_set(&key_params, 0, sizeof(key_params)); + key_params.vdev_id = key_info->smesessionId; + key_params.key_type = key_info->encType; + key_params.singl_tid_rc = key_info->singleTidRc; + key_params.unicast = FALSE; + if (txrx_vdev->opmode == wlan_op_mode_sta) { + vos_mem_copy(key_params.peer_mac, + wma_handle->interfaces[key_info->smesessionId].bssid, + ETH_ALEN); + } else { + /* vdev mac address will be passed for all other modes */ + vos_mem_copy(key_params.peer_mac, txrx_vdev->mac_addr.raw, + ETH_ALEN); + WMA_LOGA("BSS Key setup with vdev_mac %pM\n", + txrx_vdev->mac_addr.raw); + } + + if (key_info->numKeys == 0 && + (key_info->encType == eSIR_ED_WEP40 || + key_info->encType == eSIR_ED_WEP104)) { + wma_read_cfg_wepkey(wma_handle, key_info->key, + &def_key_idx, &key_info->numKeys); + } + + for (i = 0; i < key_info->numKeys; i++) { + if (key_params.key_type != eSIR_ED_NONE && + !key_info->key[i].keyLength) + continue; + if (key_info->encType == eSIR_ED_WPI) { + key_params.key_idx = key_info->key[i].keyId; + key_params.def_key_idx = key_info->key[i].keyId; + } else + key_params.key_idx = key_info->key[i].keyId; + + key_params.key_len = key_info->key[i].keyLength; + if (key_info->encType == eSIR_ED_TKIP) { + vos_mem_copy(key_params.key_data, + key_info->key[i].key, 16); + vos_mem_copy(&key_params.key_data[16], + &key_info->key[i].key[24], 8); + vos_mem_copy(&key_params.key_data[24], + &key_info->key[i].key[16], 8); + } else + vos_mem_copy((v_VOID_t *) key_params.key_data, + (const v_VOID_t *) key_info->key[i].key, + key_info->key[i].keyLength); + + WMA_LOGD("%s: bss key[%d] length %d", __func__, i, + key_info->key[i].keyLength); + + buf = wma_setup_install_key_cmd(wma_handle, &key_params, &len); + if (!buf) { + WMA_LOGE("%s:Failed to setup install key buf", __func__); + key_info->status = eHAL_STATUS_FAILED_ALLOC; + goto out; + } + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_INSTALL_KEY_CMDID); + if (status) { + adf_nbuf_free(buf); + WMA_LOGE("%s:Failed to send install key command", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + } + + wma_handle->ibss_started++; + /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */ + key_info->status = eHAL_STATUS_SUCCESS; + +out: + wma_send_msg(wma_handle, WDA_SET_BSSKEY_RSP, (void *)key_info, 0); +} + +static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, tpSetBssKeyParams key_info, u_int8_t* peerMacAddr) +{ + struct wma_set_key_params key_params; + wmi_buf_t buf; + int32_t status; + u_int32_t len = 0, i; + v_U32_t def_key_idx = 0; + ol_txrx_vdev_handle txrx_vdev; + + WMA_LOGD("BSS key setup for peer"); + ASSERT( NULL != peerMacAddr); + txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); + if (!txrx_vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + key_info->status = eHAL_STATUS_FAILURE; + return; + } + + adf_os_mem_set(&key_params, 0, sizeof(key_params)); + key_params.vdev_id = key_info->smesessionId; + key_params.key_type = key_info->encType; + key_params.singl_tid_rc = key_info->singleTidRc; + key_params.unicast = FALSE; + ASSERT(wlan_op_mode_ibss == txrx_vdev->opmode); + + vos_mem_copy(key_params.peer_mac, peerMacAddr, ETH_ALEN); + + if (key_info->numKeys == 0 && + (key_info->encType == eSIR_ED_WEP40 || + key_info->encType == eSIR_ED_WEP104)) { + wma_read_cfg_wepkey(wma_handle, key_info->key, + &def_key_idx, &key_info->numKeys); + } + + for (i = 0; i < key_info->numKeys; i++) { + if (key_params.key_type != eSIR_ED_NONE && + !key_info->key[i].keyLength) + continue; + key_params.key_idx = key_info->key[i].keyId; + key_params.key_len = key_info->key[i].keyLength; + if (key_info->encType == eSIR_ED_TKIP) { + vos_mem_copy(key_params.key_data, + key_info->key[i].key, 16); + vos_mem_copy(&key_params.key_data[16], + &key_info->key[i].key[24], 8); + vos_mem_copy(&key_params.key_data[24], + &key_info->key[i].key[16], 8); + } else + vos_mem_copy((v_VOID_t *) key_params.key_data, + (const v_VOID_t *) key_info->key[i].key, + key_info->key[i].keyLength); + + WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i, + key_info->key[i].keyLength); + + buf = wma_setup_install_key_cmd(wma_handle, &key_params, &len); + if (!buf) { + WMA_LOGE("%s:Failed to setup install key buf", __func__); + return; + } + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_INSTALL_KEY_CMDID); + if (status) { + adf_nbuf_free(buf); + WMA_LOGE("%s:Failed to send install key command", __func__); + } + } +} + +static void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info) +{ + wmi_buf_t buf; + int32_t status, i; + u_int32_t len = 0; + ol_txrx_pdev_handle txrx_pdev; + ol_txrx_vdev_handle txrx_vdev; + struct ol_txrx_peer_t *peer; + u_int8_t num_keys = 0, peer_id; + struct wma_set_key_params key_params; + v_U32_t def_key_idx = 0; + + WMA_LOGD("STA key setup"); + + /* Get the txRx Pdev handle */ + txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, + wma_handle->vos_context); + if (!txrx_pdev) { + WMA_LOGE("%s:Invalid txrx pdev handle", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + + peer = ol_txrx_find_peer_by_addr(txrx_pdev, key_info->peerMacAddr, + &peer_id); + if (!peer) { + WMA_LOGE("%s:Invalid peer for key setting", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + + txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId); + if(!txrx_vdev) { + WMA_LOGE("%s:TxRx Vdev Handle is NULL", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + + if (key_info->defWEPIdx == WMA_INVALID_KEY_IDX && + (key_info->encType == eSIR_ED_WEP40 || + key_info->encType == eSIR_ED_WEP104) && + txrx_vdev->opmode != wlan_op_mode_ap) { + wma_read_cfg_wepkey(wma_handle, key_info->key, + &def_key_idx, &num_keys); + key_info->defWEPIdx = def_key_idx; + } else { + num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + if (key_info->encType != eSIR_ED_NONE) { + for (i = 0; i < num_keys; i++) { + if (key_info->key[i].keyDirection == + eSIR_TX_DEFAULT) { + key_info->defWEPIdx = i; + break; + } + } + } + } + adf_os_mem_set(&key_params, 0, sizeof(key_params)); + key_params.vdev_id = key_info->smesessionId; + key_params.key_type = key_info->encType; + key_params.singl_tid_rc = key_info->singleTidRc; + key_params.unicast = TRUE; + key_params.def_key_idx = key_info->defWEPIdx; + vos_mem_copy((v_VOID_t *) key_params.peer_mac, + (const v_VOID_t *) key_info->peerMacAddr, ETH_ALEN); + for (i = 0; i < num_keys; i++) { + if (key_params.key_type != eSIR_ED_NONE && + !key_info->key[i].keyLength) + continue; + if (key_info->encType == eSIR_ED_TKIP) { + vos_mem_copy(key_params.key_data, + key_info->key[i].key, 16); + vos_mem_copy(&key_params.key_data[16], + &key_info->key[i].key[24], 8); + vos_mem_copy(&key_params.key_data[24], + &key_info->key[i].key[16], 8); + } else + vos_mem_copy(key_params.key_data, key_info->key[i].key, + key_info->key[i].keyLength); + if (key_info->encType == eSIR_ED_WPI) { + key_params.key_idx = key_info->key[i].keyId; + key_params.def_key_idx = key_info->key[i].keyId; + } else + key_params.key_idx = i; + + key_params.key_len = key_info->key[i].keyLength; + buf = wma_setup_install_key_cmd(wma_handle, &key_params, &len); + if (!buf) { + WMA_LOGE("%s:Failed to setup install key buf", __func__); + key_info->status = eHAL_STATUS_FAILED_ALLOC; + goto out; + } + + WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i, + key_info->key[i].keyLength); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_INSTALL_KEY_CMDID); + if (status) { + adf_nbuf_free(buf); + WMA_LOGE("%s:Failed to send install key command", __func__); + key_info->status = eHAL_STATUS_FAILURE; + goto out; + } + } + + /* In IBSS mode, set the BSS KEY for this peer + ** BSS key is supposed to be cache into wma_handle + */ + if (wlan_op_mode_ibss == txrx_vdev->opmode){ + wma_set_ibsskey_helper(wma_handle, &wma_handle->ibsskey_info, key_info->peerMacAddr); + } + + /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */ + key_info->status = eHAL_STATUS_SUCCESS; +out: + if (key_info->sendRsp) + wma_send_msg(wma_handle, WDA_SET_STAKEY_RSP, (void *) key_info, 0); +} + +static void wma_delete_sta_req_ap_mode(tp_wma_handle wma, + tpDeleteStaParams del_sta) +{ + ol_txrx_pdev_handle pdev; + struct ol_txrx_peer_t *peer; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + peer = ol_txrx_peer_find_by_local_id(pdev, del_sta->staIdx); + if (!peer) { + WMA_LOGE("%s: Failed to get peer handle using peer id %d", + __func__, del_sta->staIdx); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + wma_remove_peer(wma, peer->mac_addr.raw, del_sta->smesessionId, peer, + VOS_FALSE); + del_sta->status = VOS_STATUS_SUCCESS; + +send_del_rsp: + if (del_sta->respReqd) { + WMA_LOGD("%s: Sending del rsp to umac (status: %d)", + __func__, del_sta->status); + wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)del_sta, 0); + } +} + +#ifdef FEATURE_WLAN_TDLS +static void wma_del_tdls_sta(tp_wma_handle wma, + tpDeleteStaParams del_sta) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + struct ol_txrx_peer_t *peer; + tTdlsPeerStateParams *peerStateParams; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to find pdev", __func__); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + vdev = wma_find_vdev_by_id(wma, del_sta->smesessionId); + if (!vdev) { + WMA_LOGE("%s: Failed to find vdev", __func__); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + peer = ol_txrx_peer_find_by_local_id(pdev, del_sta->staIdx); + if (!peer) { + WMA_LOGE("%s: Failed to get peer handle using peer id %d", + __func__, del_sta->staIdx); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + peerStateParams = vos_mem_malloc(sizeof(tTdlsPeerStateParams)); + if (!peerStateParams) { + WMA_LOGE("%s: Failed to allocate memory for peerStateParams for: %pM", + __func__, del_sta->staMac); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + vos_mem_zero(peerStateParams, sizeof(*peerStateParams)); + peerStateParams->peerState = WDA_TDLS_PEER_STATE_TEARDOWN; + peerStateParams->vdevId = vdev->vdev_id; + vos_mem_copy(&peerStateParams->peerMacAddr, + &del_sta->staMac, + sizeof(tSirMacAddr)); + + WMA_LOGD("%s: sending tdls_peer_state for peer mac: %pM, " + " peerState: %d", + __func__, peerStateParams->peerMacAddr, + peerStateParams->peerState); + + wma_update_tdls_peer_state(wma, peerStateParams); + + del_sta->status = VOS_STATUS_SUCCESS; + +send_del_rsp: + if (del_sta->respReqd) { + WMA_LOGD("%s: Sending del rsp to umac (status: %d)", + __func__, del_sta->status); + wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)del_sta, 0); + } +} +#endif + +static void wma_delete_sta_req_sta_mode(tp_wma_handle wma, + tpDeleteStaParams params) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct wma_txrx_node *iface; + iface = &wma->interfaces[params->smesessionId]; + iface->uapsd_cached_val = 0; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + /* In case of LFR3.0 we need not send any + * WMI commands to FW before SYNCH_CONFIRM */ +if(iface->roam_synch_in_progress) + goto send_del_sta_rsp; +#endif +#ifdef FEATURE_WLAN_TDLS + if (STA_ENTRY_TDLS_PEER == params->staType) + { + wma_del_tdls_sta(wma, params); + return; + } +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +send_del_sta_rsp: +#endif + params->status = status; + if (params->respReqd) { + WMA_LOGD("%s: vdev_id %d status %d", __func__, + params->smesessionId, status); + wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)params, 0); + } +} + +static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) +{ + tANI_U8 oper_mode = BSS_OPERATIONAL_MODE_STA; + u_int8_t smesession_id = del_sta->smesessionId; + bool rsp_requested = del_sta->respReqd; + + if (wma_is_vdev_in_ap_mode(wma, smesession_id)) { +#ifdef FEATURE_WLAN_D0WOW + wma_del_pm_vote(wma); +#else + wma_allow_suspend_check(wma); +#endif + oper_mode = BSS_OPERATIONAL_MODE_AP; + } +#ifdef QCA_IBSS_SUPPORT + if (wma_is_vdev_in_ibss_mode(wma, smesession_id)) { + oper_mode = BSS_OPERATIONAL_MODE_IBSS; +#ifdef FEATURE_WLAN_D0WOW + wma_del_pm_vote(wma); +#endif + WMA_LOGD("%s: to delete sta for IBSS mode", __func__); + } +#endif + + switch (oper_mode) { + case BSS_OPERATIONAL_MODE_STA: + wma_delete_sta_req_sta_mode(wma, del_sta); + break; + +#ifdef QCA_IBSS_SUPPORT + case BSS_OPERATIONAL_MODE_IBSS: /* IBSS shares AP code */ +#endif + case BSS_OPERATIONAL_MODE_AP: + wma_delete_sta_req_ap_mode(wma, del_sta); + break; + } + +#ifdef QCA_IBSS_SUPPORT + /* adjust heart beat thresold timer value for + * detecting ibss peer departure + */ + if (oper_mode == BSS_OPERATIONAL_MODE_IBSS) + wma_adjust_ibss_heart_beat_timer(wma, smesession_id, -1); +#endif + if (!rsp_requested) { + WMA_LOGD("%s: vdev_id %d status %d", __func__, + del_sta->smesessionId, del_sta->status); + vos_mem_free(del_sta); + } +} + +static int32_t wmi_unified_vdev_stop_send(wmi_unified_t wmi, u_int8_t vdev_id) +{ + wmi_vdev_stop_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wmi, len); + if (!buf) { + WMA_LOGP("%s : wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_vdev_stop_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_stop_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_stop_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_STOP_CMDID)) { + WMA_LOGP("%s: Failed to send vdev stop command", __func__); + adf_nbuf_free(buf); + return -EIO; + } + return 0; +} + +static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_peer_handle peer = NULL; + struct wma_target_req *msg; + VOS_STATUS status = VOS_STATUS_SUCCESS; + u_int8_t peer_id; + u_int8_t max_wait_iterations = 0; + ol_txrx_vdev_handle txrx_vdev = NULL; + v_BOOL_t roam_synch_in_progress = VOS_FALSE; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s:Unable to get TXRX context", __func__); + goto out; + } + +#ifdef QCA_IBSS_SUPPORT + if (wma_is_vdev_in_ibss_mode(wma, params->smesessionId)) + /* in rome ibss case, self mac is used to create the bss peer */ + peer = ol_txrx_find_peer_by_addr(pdev, + wma->interfaces[params->smesessionId].addr, + &peer_id); + else +#endif + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, + &peer_id); + + if (!peer) { + WMA_LOGP("%s: Failed to find peer %pM", __func__, + params->bssid); + status = VOS_STATUS_E_FAILURE; + goto out; + } + + vos_mem_zero(wma->interfaces[params->smesessionId].bssid, ETH_ALEN); + + txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId); + if (!txrx_vdev) { + WMA_LOGE("%s:Invalid vdev handle", __func__); + status = VOS_STATUS_E_FAILURE; + goto out; + } + + /*Free the allocated stats response buffer for the the session*/ + if (wma->interfaces[params->smesessionId].stats_rsp) { + vos_mem_free(wma->interfaces[params->smesessionId].stats_rsp); + wma->interfaces[params->smesessionId].stats_rsp = NULL; + } + + if (wlan_op_mode_ibss == txrx_vdev->opmode) { + wma->ibss_started = 0; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(wma->interfaces[params->smesessionId].roam_synch_in_progress) + { + roam_synch_in_progress = VOS_TRUE; + goto detach_peer; + } +#endif + msg = wma_fill_vdev_req(wma, params->smesessionId, WDA_DELETE_BSS_REQ, + WMA_TARGET_REQ_TYPE_VDEV_STOP, params, + WMA_VDEV_STOP_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP("%s: Failed to fill vdev request for vdev_id %d", + __func__, params->smesessionId); + status = VOS_STATUS_E_NOMEM; + goto detach_peer; + } + + WMA_LOGW(FL("Outstanding msdu packets: %d"), + ol_txrx_get_tx_pending(pdev)); + + max_wait_iterations = + wma->interfaces[params->smesessionId].delay_before_vdev_stop / + WMA_TX_Q_RECHECK_TIMER_WAIT; + + while ( ol_txrx_get_tx_pending(pdev) && max_wait_iterations ) + { + WMA_LOGW(FL("Waiting for outstanding packet to drain.")); + vos_wait_single_event(&wma->tx_queue_empty_event, + WMA_TX_Q_RECHECK_TIMER_WAIT); + max_wait_iterations--; + } + + if (ol_txrx_get_tx_pending(pdev)) + { + WMA_LOGW(FL("Outstanding msdu packets before VDEV_STOP : %d"), + ol_txrx_get_tx_pending(pdev)); + } + + WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", + __func__, params->smesessionId); + wdi_in_vdev_pause(wma->interfaces[params->smesessionId].handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + wma->interfaces[params->smesessionId].pause_bitmap |= + (1 << PAUSE_TYPE_HOST); + + if (wmi_unified_vdev_stop_send(wma->wmi_handle, params->smesessionId)) { + WMA_LOGP("%s: %d Failed to send vdev stop", + __func__, __LINE__); + wma_remove_vdev_req(wma, params->smesessionId, + WMA_TARGET_REQ_TYPE_VDEV_STOP); + status = VOS_STATUS_E_FAILURE; + goto detach_peer; + } + WMA_LOGD("%s: bssid %pM vdev_id %d", + __func__, params->bssid, params->smesessionId); + return; +detach_peer: + wma_remove_peer(wma, params->bssid, params->smesessionId, peer, + roam_synch_in_progress); +out: + params->status = status; + wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0); +} + +static void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) +{ + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + u_int8_t vdev_id, peer_id; + v_BOOL_t roam_synch_in_progress = VOS_FALSE; + VOS_STATUS status; + + params->status = VOS_TRUE; + WMA_LOGD("%s: state %d selfmac %pM", __func__, + params->state, params->selfMacAddr); + if ((params->state != eSIR_LINK_PREASSOC_STATE) && + (params->state != eSIR_LINK_DOWN_STATE)) { + WMA_LOGD("%s: unsupported link state %d", + __func__, params->state); + goto out; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Unable to get TXRX context", __func__); + goto out; + } + + vdev = wma_find_vdev_by_addr(wma, params->selfMacAddr, &vdev_id); + if (!vdev) { + WMA_LOGP("%s: vdev not found for addr: %pM", + __func__, params->selfMacAddr); + goto out; + } + + if (wma_is_vdev_in_ap_mode(wma, vdev_id)) { + WMA_LOGD("%s: Ignoring set link req in ap mode", __func__); + goto out; + } + + if (params->state == eSIR_LINK_PREASSOC_STATE) { +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(wma->interfaces[vdev_id].roam_synch_in_progress){ + roam_synch_in_progress = VOS_TRUE; + } +#endif + status = wma_create_peer(wma, pdev, vdev, params->bssid, + WMI_PEER_TYPE_DEFAULT, vdev_id, + roam_synch_in_progress); + if (status != VOS_STATUS_SUCCESS) + params->status = VOS_FALSE; + } + else { + WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", + __func__, vdev_id); + wdi_in_vdev_pause(wma->interfaces[vdev_id].handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST); + if (wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id)) { + WMA_LOGP("%s: %d Failed to send vdev stop", + __func__, __LINE__); + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); + if (peer) { + WMA_LOGP("%s: Deleting peer %pM vdev id %d", + __func__, params->bssid, vdev_id); + wma_remove_peer(wma, params->bssid, vdev_id, peer, + roam_synch_in_progress); + } + } +out: + wma_send_msg(wma, WDA_SET_LINK_STATE_RSP, (void *)params, 0); +} + +/* + * Function to update per ac EDCA parameters + */ +static void wma_update_edca_params_for_ac(tSirMacEdcaParamRecord *edca_param, + wmi_wmm_vparams *wmm_param, + int ac) +{ +#define WMA_WMM_EXPO_TO_VAL(val) ((1 << (val)) - 1) + wmm_param->cwmin = WMA_WMM_EXPO_TO_VAL(edca_param->cw.min); + wmm_param->cwmax = WMA_WMM_EXPO_TO_VAL(edca_param->cw.max); + wmm_param->aifs = edca_param->aci.aifsn; + wmm_param->txoplimit = edca_param->txoplimit; + wmm_param->acm = edca_param->aci.acm; + + /* TODO: No ack is not present in EdcaParamRecord */ + wmm_param->no_ack = 0; + + WMA_LOGI("WMM PARAMS AC[%d]: AIFS %d Min %d Max %d TXOP %d ACM %d NOACK %d", + ac, + wmm_param->aifs, + wmm_param->cwmin, + wmm_param->cwmax, + wmm_param->txoplimit, + wmm_param->acm, + wmm_param->no_ack); +} + +/* + * Set TX power limit through vdev param + */ +static void wma_set_tx_power(WMA_HANDLE handle, + tMaxTxPowerParams *tx_pwr_params) +{ + tp_wma_handle wma_handle = (tp_wma_handle)handle; + u_int8_t vdev_id; + int ret = -1; + void *pdev; + + if (tx_pwr_params->dev_mode == VOS_STA_SAP_MODE || + tx_pwr_params->dev_mode == VOS_P2P_GO_MODE) { + pdev = wma_find_vdev_by_addr(wma_handle, + tx_pwr_params->bssId, &vdev_id); + } else { + pdev = wma_find_vdev_by_bssid(wma_handle, + tx_pwr_params->bssId, &vdev_id); + } + if (!pdev) { + WMA_LOGE("vdev handle is invalid for %pM", tx_pwr_params->bssId); + vos_mem_free(tx_pwr_params); + return; + } + + if (!(wma_handle->interfaces[vdev_id].vdev_up)) { + WMA_LOGE("%s: vdev id %d is not up for %pM", __func__, vdev_id, + tx_pwr_params->bssId); + vos_mem_free(tx_pwr_params); + return; + } + + if (tx_pwr_params->power == 0) { + /* set to default. Since the app does not care the tx power + * we keep the previous setting */ + wma_handle->interfaces[vdev_id].tx_power = 0; + ret = 0; + goto end; + } + if (wma_handle->interfaces[vdev_id].max_tx_power != 0) { + /* make sure tx_power less than max_tx_power */ + if (tx_pwr_params->power > + wma_handle->interfaces[vdev_id].max_tx_power) { + tx_pwr_params->power = + wma_handle->interfaces[vdev_id].max_tx_power; + } + } + if (wma_handle->interfaces[vdev_id].tx_power != tx_pwr_params->power) { + + /* tx_power changed, Push the tx_power to FW */ + WMA_LOGW("%s: Set TX power limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d", + __func__, tx_pwr_params->power); + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_PWRLIMIT, tx_pwr_params->power); + if (ret == 0) + wma_handle->interfaces[vdev_id].tx_power = tx_pwr_params->power; + } else { + /* no tx_power change */ + ret = 0; + } +end: + vos_mem_free(tx_pwr_params); + if (ret) + WMA_LOGE("Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT"); +} + +/* + * Set TX power limit through vdev param + */ +static void wma_set_max_tx_power(WMA_HANDLE handle, + tMaxTxPowerParams *tx_pwr_params) +{ + tp_wma_handle wma_handle = (tp_wma_handle)handle; + u_int8_t vdev_id; + int ret = -1; + void *pdev; + tPowerdBm prev_max_power; + + pdev = wma_find_vdev_by_addr(wma_handle, tx_pwr_params->bssId, &vdev_id); + if (pdev == NULL) { + /* not in SAP array. Try the station/p2p array */ + pdev = wma_find_vdev_by_bssid(wma_handle, + tx_pwr_params->bssId, &vdev_id); + } + if (!pdev) { + WMA_LOGE("vdev handle is invalid for %pM", tx_pwr_params->bssId); + vos_mem_free(tx_pwr_params); + return; + } + + if (! (wma_handle->interfaces[vdev_id].vdev_up)) { + WMA_LOGE("%s: vdev id %d is not up",__func__, vdev_id); + vos_mem_free(tx_pwr_params); + return; + } + + if (wma_handle->interfaces[vdev_id].max_tx_power == tx_pwr_params->power) { + ret = 0; + goto end; + } + prev_max_power = wma_handle->interfaces[vdev_id].max_tx_power; + wma_handle->interfaces[vdev_id].max_tx_power = tx_pwr_params->power; + if (wma_handle->interfaces[vdev_id].max_tx_power == 0) { + ret = 0; + goto end; + } + WMA_LOGW("Set MAX TX power limit [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d", + wma_handle->interfaces[vdev_id].max_tx_power); + ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_PWRLIMIT, + wma_handle->interfaces[vdev_id].max_tx_power); + if (ret == 0) + wma_handle->interfaces[vdev_id].tx_power = + wma_handle->interfaces[vdev_id].max_tx_power; + else + wma_handle->interfaces[vdev_id].max_tx_power = prev_max_power; +end: + vos_mem_free(tx_pwr_params); + if (ret) + WMA_LOGE("%s: Failed to set vdev param WMI_VDEV_PARAM_TX_PWRLIMIT", __func__); +} + +/* + * Function to update the EDCA parameters to the target + */ +static VOS_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle, + tEdcaParams *edca_params) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + u_int8_t *buf_ptr; + wmi_buf_t buf; + wmi_vdev_set_wmm_params_cmd_fixed_param *cmd; + wmi_wmm_vparams *wmm_param; + tSirMacEdcaParamRecord *edca_record; + int ac; + int len = sizeof(*cmd); + ol_txrx_pdev_handle pdev; + struct ol_tx_wmm_param_t ol_tx_wmm_param; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_vdev_set_wmm_params_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_set_wmm_params_cmd_fixed_param)); + cmd->vdev_id = edca_params->bssIdx; + + for (ac = 0; ac < WME_NUM_AC; ac++) { + wmm_param = (wmi_wmm_vparams *)(&cmd->wmm_params[ac]); + WMITLV_SET_HDR(&wmm_param->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_wmm_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_vparams)); + switch (ac) { + case WME_AC_BE: + edca_record = &edca_params->acbe; + break; + case WME_AC_BK: + edca_record = &edca_params->acbk; + break; + case WME_AC_VI: + edca_record = &edca_params->acvi; + break; + case WME_AC_VO: + edca_record = &edca_params->acvo; + break; + default: + goto fail; + } + + wma_update_edca_params_for_ac(edca_record, wmm_param, ac); + + ol_tx_wmm_param.ac[ac].aifs = wmm_param->aifs; + ol_tx_wmm_param.ac[ac].cwmin = wmm_param->cwmin; + ol_tx_wmm_param.ac[ac].cwmax = wmm_param->cwmax; + } + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_VDEV_SET_WMM_PARAMS_CMDID)) + goto fail; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma_handle->vos_context); + wdi_in_set_wmm_param(pdev, ol_tx_wmm_param); + + return VOS_STATUS_SUCCESS; + +fail: + wmi_buf_free(buf); + WMA_LOGE("%s: Failed to set WMM Paremeters", __func__); + return VOS_STATUS_E_FAILURE; +} + +static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma, + u_int8_t vdev_id, + tpSendProbeRespParams probe_rsp_info) +{ + wmi_prb_tmpl_cmd_fixed_param *cmd; + wmi_bcn_prb_info *bcn_prb_info; + wmi_buf_t wmi_buf; + u_int32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; + u_int8_t *frm, *buf_ptr; + int ret; + u_int64_t adjusted_tsf_le; + struct ieee80211_frame *wh; + + WMA_LOGD(FL("Send probe response template for vdev %d"), vdev_id); + + frm = probe_rsp_info->pProbeRespTemplate; + tmpl_len = probe_rsp_info->probeRespTemplateLen; + tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32)); + /* + * Make the TSF offset negative so probe response in the same + * staggered batch have the same TSF. + */ + adjusted_tsf_le = cpu_to_le64(0ULL - + wma->interfaces[vdev_id].tsfadjust); + /* Update the timstamp in the probe response buffer with adjusted TSF */ + wh = (struct ieee80211_frame *)frm; + A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le)); + + wmi_buf_len = sizeof(wmi_prb_tmpl_cmd_fixed_param) + + sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + + tmpl_len_aligned; + + if (wmi_buf_len > BEACON_TX_BUFFER_SIZE) { + WMA_LOGE(FL("wmi_buf_len: %d > %d. Can't send wmi cmd"), + wmi_buf_len, BEACON_TX_BUFFER_SIZE); + return -EINVAL; + } + + wmi_buf = wmi_buf_alloc(wma->wmi_handle, wmi_buf_len); + if (!wmi_buf) { + WMA_LOGE(FL("wmi_buf_alloc failed")); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_prb_tmpl_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_prb_tmpl_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_prb_tmpl_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->buf_len = tmpl_len; + buf_ptr += sizeof(wmi_prb_tmpl_cmd_fixed_param); + + bcn_prb_info = (wmi_bcn_prb_info *)buf_ptr; + WMITLV_SET_HDR(&bcn_prb_info->tlv_header, + WMITLV_TAG_STRUC_wmi_bcn_prb_info, + WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); + bcn_prb_info->caps = 0; + bcn_prb_info->erp = 0; + buf_ptr += sizeof(wmi_bcn_prb_info); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, frm, tmpl_len); + + ret = wmi_unified_cmd_send(wma->wmi_handle, + wmi_buf, wmi_buf_len, + WMI_PRB_TMPL_CMDID); + if (ret) { + WMA_LOGE(FL("Failed to send PRB RSP tmpl: %d"), ret); + wmi_buf_free(wmi_buf); + } + + return ret; +} + +static int wmi_unified_bcn_tmpl_send(tp_wma_handle wma, + u_int8_t vdev_id, + tpSendbeaconParams bcn_info, + u_int8_t bytes_to_strip) +{ + wmi_bcn_tmpl_cmd_fixed_param *cmd; + wmi_bcn_prb_info *bcn_prb_info; + wmi_buf_t wmi_buf; + u_int32_t tmpl_len, tmpl_len_aligned, wmi_buf_len; + u_int8_t *frm, *buf_ptr; + int ret; + u_int8_t *p2p_ie; + u_int16_t p2p_ie_len = 0; + u_int64_t adjusted_tsf_le; + struct ieee80211_frame *wh; + + + WMA_LOGD("Send beacon template for vdev %d", vdev_id); + + if (bcn_info->p2pIeOffset) { + p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset; + p2p_ie_len = (u_int16_t) p2p_ie[1] + 2; + } + + /* + * XXX: The first byte of beacon buffer contains beacon length + * only when UMAC in sending the beacon template. In othercases + * (ex: from tbtt update) beacon length is read from beacon + * information. + */ + if (bytes_to_strip) + tmpl_len = *(u_int32_t *)&bcn_info->beacon[0]; + else + tmpl_len = bcn_info->beaconLength; + if (p2p_ie_len) { + tmpl_len -= (u_int32_t) p2p_ie_len; + } + + frm = bcn_info->beacon + bytes_to_strip; + tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32)); + /* + * Make the TSF offset negative so beacons in the same + * staggered batch have the same TSF. + */ + adjusted_tsf_le = cpu_to_le64(0ULL - + wma->interfaces[vdev_id].tsfadjust); + /* Update the timstamp in the beacon buffer with adjusted TSF */ + wh = (struct ieee80211_frame *)frm; + A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le)); + + wmi_buf_len = sizeof(wmi_bcn_tmpl_cmd_fixed_param) + + sizeof(wmi_bcn_prb_info) + WMI_TLV_HDR_SIZE + + tmpl_len_aligned; + + wmi_buf = wmi_buf_alloc(wma->wmi_handle, wmi_buf_len); + if (!wmi_buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_bcn_tmpl_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_bcn_tmpl_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->tim_ie_offset = bcn_info->timIeOffset - bytes_to_strip; + cmd->buf_len = tmpl_len; + buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param); + + bcn_prb_info = (wmi_bcn_prb_info *)buf_ptr; + WMITLV_SET_HDR(&bcn_prb_info->tlv_header, + WMITLV_TAG_STRUC_wmi_bcn_prb_info, + WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_prb_info)); + bcn_prb_info->caps = 0; + bcn_prb_info->erp = 0; + buf_ptr += sizeof(wmi_bcn_prb_info); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, tmpl_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, frm, tmpl_len); + + ret = wmi_unified_cmd_send(wma->wmi_handle, + wmi_buf, wmi_buf_len, + WMI_BCN_TMPL_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret); + wmi_buf_free(wmi_buf); + } + + return ret; +} + +VOS_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, u_int8_t vdev_id, + tpSendbeaconParams bcn_info) +{ + struct beacon_info *bcn; + u_int32_t len; + u_int8_t *bcn_payload; + struct beacon_tim_ie *tim_ie; + + bcn = wma->interfaces[vdev_id].beacon; + if (!bcn || !bcn->buf) { + WMA_LOGE("%s: Memory is not allocated to hold bcn template", + __func__); + return VOS_STATUS_E_INVAL; + } + + len = *(u32 *)&bcn_info->beacon[0]; + if (len > WMA_BCN_BUF_MAX_SIZE) { + WMA_LOGE("%s: Received beacon len %d exceeding max limit %d", + __func__, len, WMA_BCN_BUF_MAX_SIZE); + return VOS_STATUS_E_INVAL; + } + WMA_LOGD("%s: Storing received beacon template buf to local buffer", + __func__); + adf_os_spin_lock_bh(&bcn->lock); + + /* + * Copy received beacon template content in local buffer. + * this will be send to target on the reception of SWBA + * event from target. + */ + adf_nbuf_trim_tail(bcn->buf, adf_nbuf_len(bcn->buf)); + memcpy(adf_nbuf_data(bcn->buf), + bcn_info->beacon + 4 /* Exclude beacon length field */, + len); + if (bcn_info->timIeOffset > 3) + { + bcn->tim_ie_offset = bcn_info->timIeOffset - 4; + } + else + { + bcn->tim_ie_offset = bcn_info->timIeOffset; + } + + if (bcn_info->p2pIeOffset > 3) + { + bcn->p2p_ie_offset = bcn_info->p2pIeOffset - 4; + } + else + { + bcn->p2p_ie_offset = bcn_info->p2pIeOffset; + } + bcn_payload = adf_nbuf_data(bcn->buf); + if (bcn->tim_ie_offset) + { + tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]); + /* + * Intial Value of bcn->dtim_count will be 0. + * But if the beacon gets updated then current dtim + * count will be restored + */ + tim_ie->dtim_count = bcn->dtim_count; + tim_ie->tim_bitctl = 0; + } + + adf_nbuf_put_tail(bcn->buf, len); + bcn->len = len; + + adf_os_spin_unlock_bh(&bcn->lock); + + return VOS_STATUS_SUCCESS; +} + + + +static int wma_tbtt_update_ind(tp_wma_handle wma, u_int8_t *buf) +{ + struct wma_txrx_node *intf; + struct beacon_info *bcn; + tSendbeaconParams bcn_info; + u_int32_t *adjusted_tsf = NULL; + u_int32_t if_id = 0, vdev_map; + u_int32_t num_tbttoffset_list; + wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; + WMA_LOGI("%s: Enter", __func__); + if (!buf) { + WMA_LOGE("Invalid event buffer"); + return -EINVAL; + } + if (!wma) { + WMA_LOGE("Invalid wma handle"); + return -EINVAL; + } + intf = wma->interfaces; + tbtt_offset_event = (wmi_tbtt_offset_event_fixed_param *)buf; + vdev_map = tbtt_offset_event->vdev_map; + num_tbttoffset_list = *(u_int32_t *)(buf + sizeof(wmi_tbtt_offset_event_fixed_param)); + adjusted_tsf = (u_int32_t *) ((u_int8_t *)buf + + sizeof(wmi_tbtt_offset_event_fixed_param) + + sizeof (u_int32_t)); + if (!adjusted_tsf) { + WMA_LOGE("%s: Invalid adjusted_tsf", __func__); + return -EINVAL; + } + + for ( ;(vdev_map); vdev_map >>= 1, if_id++) { + if (!(vdev_map & 0x1) || (!(intf[if_id].handle))) + continue; + + bcn = intf[if_id].beacon; + if (!bcn) { + WMA_LOGE("%s: Invalid beacon", __func__); + return -EINVAL; + } + if (!bcn->buf) { + WMA_LOGE("%s: Invalid beacon buffer", __func__); + return -EINVAL; + } + /* Save the adjusted TSF */ + intf[if_id].tsfadjust = adjusted_tsf[if_id]; + + adf_os_spin_lock_bh(&bcn->lock); + vos_mem_zero(&bcn_info, sizeof(bcn_info)); + bcn_info.beacon = adf_nbuf_data(bcn->buf); + bcn_info.p2pIeOffset = bcn->p2p_ie_offset; + bcn_info.beaconLength = bcn->len; + bcn_info.timIeOffset = bcn->tim_ie_offset; + adf_os_spin_unlock_bh(&bcn->lock); + + /* Update beacon template in firmware */ + wmi_unified_bcn_tmpl_send(wma, if_id, &bcn_info, 0); + } + return 0; +} + +static int wma_tbttoffset_update_event_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf; + wmi_tbtt_offset_event_fixed_param *tbtt_offset_event; + u_int8_t *buf, *tempBuf; + vos_msg_t vos_msg = {0}; + + param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)event; + if(!param_buf) { + WMA_LOGE("Invalid tbtt update event buffer"); + return -EINVAL; + } + + tbtt_offset_event = param_buf->fixed_param; + buf = vos_mem_malloc(sizeof(wmi_tbtt_offset_event_fixed_param) + + sizeof (u_int32_t) + + (param_buf->num_tbttoffset_list * sizeof (u_int32_t))); + if (!buf) { + WMA_LOGE("%s: Failed alloc memory for buf", __func__); + return -EINVAL; + } + + tempBuf = buf; + vos_mem_zero(buf, (sizeof(wmi_tbtt_offset_event_fixed_param) + + sizeof (u_int32_t) + + (param_buf->num_tbttoffset_list * sizeof (u_int32_t)))); + vos_mem_copy(buf, (u_int8_t *)tbtt_offset_event, sizeof (wmi_tbtt_offset_event_fixed_param)); + buf += sizeof (wmi_tbtt_offset_event_fixed_param); + + vos_mem_copy(buf, (u_int8_t *) ¶m_buf->num_tbttoffset_list, sizeof (u_int32_t)); + buf += sizeof(u_int32_t); + + vos_mem_copy(buf, (u_int8_t *)param_buf->tbttoffset_list, (param_buf->num_tbttoffset_list * sizeof(u_int32_t))); + + vos_msg.type = WDA_TBTT_UPDATE_IND; + vos_msg.bodyptr = tempBuf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGP("%s: Failed to post WDA_TBTT_UPDATE_IND msg", __func__); + vos_mem_free(tempBuf); + return -1; + } + WMA_LOGD("WDA_TBTT_UPDATE_IND posted"); + return 0; +} + + +static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle, + A_UINT32 vdev_id, u_int8_t *p2pIe) +{ + int ret; + wmi_p2p_go_set_beacon_ie_fixed_param *cmd; + wmi_buf_t wmi_buf; + u_int32_t ie_len, ie_len_aligned, wmi_buf_len; + u_int8_t *buf_ptr; + + ie_len = (u_int32_t) (p2pIe[1] + 2); + + /* More than one P2P IE may be included in a single frame. + If multiple P2P IEs are present, the complete P2P attribute + data consists of the concatenation of the P2P Attribute + fields of the P2P IEs. The P2P Attributes field of each + P2P IE may be any length up to the maximum (251 octets). + In this case host sends one P2P IE to firmware so the length + should not exceed more than 251 bytes + */ + if (ie_len > 251) { + WMA_LOGE("%s : invalid p2p ie length %u", __func__, ie_len); + return -EINVAL; + } + + ie_len_aligned = roundup(ie_len, sizeof(A_UINT32)); + + wmi_buf_len = sizeof(wmi_p2p_go_set_beacon_ie_fixed_param) + ie_len_aligned + WMI_TLV_HDR_SIZE; + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, wmi_buf_len); + if (!wmi_buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_p2p_go_set_beacon_ie_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_go_set_beacon_ie_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_go_set_beacon_ie_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->ie_buf_len = ie_len; + + buf_ptr += sizeof(wmi_p2p_go_set_beacon_ie_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, p2pIe, ie_len); + + WMA_LOGI("%s: Sending WMI_P2P_GO_SET_BEACON_IE", __func__); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, + wmi_buf, wmi_buf_len, + WMI_P2P_GO_SET_BEACON_IE + ); + if (ret) { + WMA_LOGE("Failed to send bcn tmpl: %d", ret); + wmi_buf_free(wmi_buf); + } + + WMA_LOGI("%s: Successfully sent WMI_P2P_GO_SET_BEACON_IE", __func__); + return ret; +} + +static void wma_send_probe_rsp_tmpl(tp_wma_handle wma, + tpSendProbeRespParams probe_rsp_info) +{ + ol_txrx_vdev_handle vdev; + u_int8_t vdev_id; + tpAniProbeRspStruct probe_rsp; + + if(!probe_rsp_info) { + WMA_LOGE(FL("probe_rsp_info is NULL")); + return; + } + + probe_rsp = (tpAniProbeRspStruct)(probe_rsp_info->pProbeRespTemplate); + if(!probe_rsp) { + WMA_LOGE(FL("probe_rsp is NULL")); + return; + } + + vdev = wma_find_vdev_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id); + if (!vdev) { + WMA_LOGE(FL("failed to get vdev handle")); + return; + } + + if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_BEACON_OFFLOAD)) { + WMA_LOGI("Beacon Offload Enabled Sending Unified command"); + if (wmi_unified_probe_rsp_tmpl_send(wma, vdev_id, + probe_rsp_info) < 0){ + WMA_LOGE(FL("wmi_unified_probe_rsp_tmpl_send Failed ")); + return; + } + } +} + +static void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info) +{ + ol_txrx_vdev_handle vdev; + u_int8_t vdev_id; + VOS_STATUS status; + u_int8_t *p2p_ie; + tpAniBeaconStruct beacon; + + beacon = (tpAniBeaconStruct)(bcn_info->beacon); + vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id); + if (!vdev) { + WMA_LOGE("%s : failed to get vdev handle", __func__); + return; + } + + if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_BEACON_OFFLOAD)) { + WMA_LOGI("Beacon Offload Enabled Sending Unified command"); + if (wmi_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4) < 0){ + WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ", __func__); + return; + } + + if (bcn_info->p2pIeOffset) { + p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset; + WMA_LOGI(" %s: p2pIe is present - vdev_id %hu, p2p_ie = %p, p2p ie len = %hu", + __func__, vdev_id, p2p_ie, p2p_ie[1]); + if (wma_p2p_go_set_beacon_ie(wma, vdev_id, p2p_ie) < 0) { + WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ", __func__); + return; + } + } + } + status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s : wma_store_bcn_tmpl Failed", __func__); + return; + } + if (!wma->interfaces[vdev_id].vdev_up) { + if (wmi_unified_vdev_up_send(wma->wmi_handle, vdev_id, 0, + bcn_info->bssId) < 0) { + WMA_LOGE("%s : failed to send vdev up", __func__); + return; + } + wma->interfaces[vdev_id].vdev_up = TRUE; + wma_set_sap_keepalive(wma, vdev_id); + } +} + +#if !defined(REMOVE_PKT_LOG) +static VOS_STATUS wma_pktlog_wmi_send_cmd(WMA_HANDLE handle, + struct ath_pktlog_wmi_params *params) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_PKTLOG_EVENT PKTLOG_EVENT; + WMI_CMD_ID CMD_ID; + wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; + wmi_pdev_pktlog_disable_cmd_fixed_param *disable_cmd; + int len = 0; + wmi_buf_t buf; + + /*Check if packet log is enabled in cfg.ini*/ + if (! vos_is_packet_log_enabled()) + { + WMA_LOGE("%s:pkt log is not enabled in cfg.ini", __func__); + return VOS_STATUS_E_FAILURE; + } + + + PKTLOG_EVENT = params->pktlog_event; + CMD_ID = params->cmd_id; + + switch (CMD_ID) { + case WMI_PDEV_PKTLOG_ENABLE_CMDID: + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + cmd = + (wmi_pdev_pktlog_enable_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_pktlog_enable_cmd_fixed_param)); + cmd->evlist = PKTLOG_EVENT; + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_PDEV_PKTLOG_ENABLE_CMDID)) { + WMA_LOGE("failed to send pktlog enable cmdid"); + goto wmi_send_failed; + } + break; + case WMI_PDEV_PKTLOG_DISABLE_CMDID: + len = sizeof(*disable_cmd); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + disable_cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) + wmi_buf_data(buf); + WMITLV_SET_HDR(&disable_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_pktlog_disable_cmd_fixed_param)); + disable_cmd->reserved0 = 0; + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_PDEV_PKTLOG_DISABLE_CMDID)) { + WMA_LOGE("failed to send pktlog disable cmdid"); + goto wmi_send_failed; + } + break; + default: + WMA_LOGD("%s: invalid PKTLOG command", __func__); + break; + } + + return VOS_STATUS_SUCCESS; + +wmi_send_failed: + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; +} +#endif + +static int32_t wmi_unified_set_sta_ps(wmi_unified_t wmi_handle, + u_int32_t vdev_id, u_int8_t val) +{ + wmi_sta_powersave_mode_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + WMA_LOGD("Set Sta Mode Ps vdevId %d val %d", vdev_id, val); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: Set Sta Mode Ps Mem Alloc Failed", __func__); + return -ENOMEM; + } + cmd = (wmi_sta_powersave_mode_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_sta_powersave_mode_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_powersave_mode_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + if(val) + cmd->sta_ps_mode = WMI_STA_PS_MODE_ENABLED; + else + cmd->sta_ps_mode = WMI_STA_PS_MODE_DISABLED; + + if(wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_STA_POWERSAVE_MODE_CMDID)) + { + WMA_LOGE("Set Sta Mode Ps Failed vdevId %d val %d", + vdev_id, val); + adf_nbuf_free(buf); + return -EIO; + } + return 0; +} + +static inline u_int32_t wma_get_uapsd_mask(tpUapsd_Params uapsd_params) +{ + u_int32_t uapsd_val = 0; + + if(uapsd_params->beDeliveryEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC0_DELIVERY_EN; + + if(uapsd_params->beTriggerEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC0_TRIGGER_EN; + + if(uapsd_params->bkDeliveryEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC1_DELIVERY_EN; + + if(uapsd_params->bkTriggerEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC1_TRIGGER_EN; + + if(uapsd_params->viDeliveryEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC2_DELIVERY_EN; + + if(uapsd_params->viTriggerEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC2_TRIGGER_EN; + + if(uapsd_params->voDeliveryEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC3_DELIVERY_EN; + + if(uapsd_params->voTriggerEnabled) + uapsd_val |= WMI_STA_PS_UAPSD_AC3_TRIGGER_EN; + + return uapsd_val; +} + +static int32_t wma_set_force_sleep(tp_wma_handle wma, u_int32_t vdev_id, + u_int8_t enable, u_int8_t is_qpower_enabled) +{ + int32_t ret; + tANI_U32 cfg_data_val = 0; + /* get mac to acess CFG data base */ + struct sAniSirGlobal *mac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + u_int32_t rx_wake_policy; + u_int32_t tx_wake_threshold; + u_int32_t pspoll_count; + u_int32_t inactivity_time; + u_int32_t psmode; + + WMA_LOGD("Set Force Sleep vdevId %d val %d", vdev_id, enable); + + if (NULL == mac) { + WMA_LOGE("%s: Unable to get PE context", __func__); + return -ENOMEM; + } + + /* Set Tx/Rx Data InActivity Timeout */ + if (wlan_cfgGetInt(mac, WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT"); + cfg_data_val = POWERSAVE_DEFAULT_INACTIVITY_TIME; + } + inactivity_time = (u_int32_t)cfg_data_val; + + if (enable) { + /* override normal configuration and force station asleep */ + rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD; + tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER; + + if (wlan_cfgGetInt(mac, WNI_CFG_MAX_PS_POLL, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_PS_POLL"); + } + if (cfg_data_val) + pspoll_count = (u_int32_t)cfg_data_val; + else + pspoll_count = WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE; + + psmode = WMI_STA_PS_MODE_ENABLED; + } else { + /* Ps Poll Wake Policy */ + if (wlan_cfgGetInt(mac, WNI_CFG_MAX_PS_POLL, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_PS_POLL"); + } + if (cfg_data_val) { + /* Ps Poll is enabled */ + rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD; + pspoll_count = (u_int32_t)cfg_data_val; + tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER; + } else { + rx_wake_policy = WMI_STA_PS_RX_WAKE_POLICY_WAKE; + pspoll_count = WMI_STA_PS_PSPOLL_COUNT_NO_MAX; + tx_wake_threshold = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS; + } + psmode = WMI_STA_PS_MODE_ENABLED; + } + + /* + * QPower is enabled by default in Firmware + * So Disable QPower explicitly + */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_ENABLE_QPOWER, is_qpower_enabled); + if (ret) { + WMA_LOGE("Disable QPower Failed vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("QPower Disabled vdevId %d", vdev_id); + + /* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD*/ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_RX_WAKE_POLICY, + rx_wake_policy); + + if (ret) { + WMA_LOGE("Setting wake policy Failed vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("Setting wake policy to %d vdevId %d", + rx_wake_policy, vdev_id); + + /* Set the Tx Wake Threshold */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD, + tx_wake_threshold); + + if (ret) { + WMA_LOGE("Setting TxWake Threshold vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("Setting TxWake Threshold to %d vdevId %d", + tx_wake_threshold, vdev_id); + + /* Set the Ps Poll Count */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_PSPOLL_COUNT, + pspoll_count); + + if (ret) { + WMA_LOGE("Set Ps Poll Count Failed vdevId %d ps poll cnt %d", + vdev_id, pspoll_count); + return ret; + } + WMA_LOGD("Set Ps Poll Count vdevId %d ps poll cnt %d", + vdev_id, pspoll_count); + + /* Set the Tx/Rx InActivity */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_INACTIVITY_TIME, + inactivity_time); + + if (ret) { + WMA_LOGE("Setting Tx/Rx InActivity Failed vdevId %d InAct %d", + vdev_id, inactivity_time); + return ret; + } + WMA_LOGD("Set Tx/Rx InActivity vdevId %d InAct %d", + vdev_id, inactivity_time); + + /* Enable Sta Mode Power save */ + ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, true); + + if (ret) { + WMA_LOGE("Enable Sta Mode Ps Failed vdevId %d", vdev_id); + return ret; + } + + /* Set Listen Interval */ + if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LISTEN_INTERVAL"); + cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LISTEN_INTERVAL, + cfg_data_val); + if (ret) { + /* Even it fails continue Fw will take default LI */ + WMA_LOGE("Failed to Set Listen Interval vdevId %d", + vdev_id); + } + WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d", + vdev_id, cfg_data_val); + return 0; +} + +int32_t wma_set_qpower_force_sleep(tp_wma_handle wma, u_int32_t vdev_id, + u_int8_t enable) +{ + int32_t ret; + tANI_U32 cfg_data_val = 0; + /* get mac to acess CFG data base */ + struct sAniSirGlobal *mac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + u_int32_t pspoll_count = WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE; + + WMA_LOGE("Set QPower Force(1)/Normal(0) Sleep vdevId %d val %d", + vdev_id, enable); + + if (NULL == mac) { + WMA_LOGE("%s: Unable to get PE context", __func__); + return -ENOMEM; + } + + /* Get Configured Ps Poll Count */ + if (wlan_cfgGetInt(mac, WNI_CFG_MAX_PS_POLL, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_PS_POLL"); + } + if (cfg_data_val) { + pspoll_count = (u_int32_t)cfg_data_val; + } + + /* Enable QPower */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_ENABLE_QPOWER, 1); + + if (ret) { + WMA_LOGE("Enable QPower Failed vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("QPower Enabled vdevId %d", vdev_id); + + /* Set the Wake Policy to WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD*/ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_RX_WAKE_POLICY, + WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD); + + if (ret) { + WMA_LOGE("Setting wake policy to pspoll/uapsd Failed vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("Wake policy set to to pspoll/uapsd vdevId %d", + vdev_id); + + if (enable) { + /* Set the Tx Wake Threshold */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD, + WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER); + + if (ret) { + WMA_LOGE("Setting TxWake Threshold vdevId %d", vdev_id); + return ret; + } + WMA_LOGD("TxWake Threshold set to TX_WAKE_THRESHOLD_NEVER %d", vdev_id); + } + + /* Set the QPower Ps Poll Count */ + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT, + pspoll_count); + + if (ret) { + WMA_LOGE("Set QPower Ps Poll Count Failed vdevId %d ps poll cnt %d", + vdev_id, pspoll_count); + return ret; + } + WMA_LOGD("Set QPower Ps Poll Count vdevId %d ps poll cnt %d", + vdev_id, pspoll_count); + + /* Enable Sta Mode Power save */ + ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, true); + + if (ret) { + WMA_LOGE("Enable Sta Mode Ps Failed vdevId %d", vdev_id); + return ret; + } + + /* Set Listen Interval */ + if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL, + &cfg_data_val ) != eSIR_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LISTEN_INTERVAL"); + cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LISTEN_INTERVAL, + cfg_data_val); + if (ret) { + /* Even it fails continue Fw will take default LI */ + WMA_LOGE("Failed to Set Listen Interval vdevId %d", + vdev_id); + } + WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d", + vdev_id, cfg_data_val); + return 0; +} + +static u_int8_t wma_is_qpower_enabled(tp_wma_handle wma) +{ + if((wma->powersave_mode == PS_QPOWER_NODEEPSLEEP) || + (wma->powersave_mode == PS_QPOWER_DEEPSLEEP)) { + return true; + } + return false; +} + +static void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req) +{ + uint32_t vdev_id = ps_req->sessionid; + int32_t ret; + u_int8_t is_qpower_enabled = wma_is_qpower_enabled(wma); + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + + if (eSIR_ADDON_NOTHING == ps_req->psSetting) { + WMA_LOGD("Enable Sta Mode Ps vdevId %d", vdev_id); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_UAPSD, 0); + if (ret) { + WMA_LOGE("Set Uapsd param 0 Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + ret = wma_set_force_sleep(wma, vdev_id, false, + is_qpower_enabled); + if (ret) { + WMA_LOGE("Enable Sta Ps Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + } else if (eSIR_ADDON_ENABLE_UAPSD == ps_req->psSetting) { + u_int32_t uapsd_val = 0; + uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams); + + if(uapsd_val != iface->uapsd_cached_val) { + WMA_LOGD("Enable Uapsd vdevId %d Mask %d", + vdev_id, uapsd_val); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vdev_id, WMI_STA_PS_PARAM_UAPSD, + uapsd_val); + if (ret) { + WMA_LOGE("Enable Uapsd Failed vdevId %d", + vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + /* Cache the Uapsd Mask */ + iface->uapsd_cached_val = uapsd_val; + } else { + WMA_LOGD("Already Uapsd Enabled vdevId %d Mask %d", + vdev_id, uapsd_val); + } + + WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id); + + ret = wma_set_force_sleep(wma, vdev_id, true, + is_qpower_enabled); + + if (ret) { + WMA_LOGE("Enable Forced Sleep Failed vdevId %d", + vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + } + ps_req->status = VOS_STATUS_SUCCESS; + iface->dtimPeriod = ps_req->bcnDtimPeriod; +resp: + wma_send_msg(wma, WDA_ENTER_BMPS_RSP, ps_req, 0); +} + +static void wma_disable_sta_ps_mode(tp_wma_handle wma, tpDisablePsParams ps_req) +{ + int32_t ret; + uint32_t vdev_id = ps_req->sessionid; + + WMA_LOGD("Disable Sta Mode Ps vdevId %d", vdev_id); + + /* Disable Sta Mode Power save */ + ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false); + if(ret) { + WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + /* Disable UAPSD incase if additional Req came */ + if (eSIR_ADDON_DISABLE_UAPSD == ps_req->psSetting) { + WMA_LOGD("Disable Uapsd vdevId %d", vdev_id); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_UAPSD, 0); + if (ret) { + WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id); + /* + * Even this fails we can proceed as success + * since we disabled powersave + */ + } + } + + ps_req->status = VOS_STATUS_SUCCESS; +resp: + wma_send_msg(wma, WDA_EXIT_BMPS_RSP, ps_req, 0); +} + +static void wma_enable_uapsd_mode(tp_wma_handle wma, + tpEnableUapsdParams ps_req) +{ + int32_t ret; + u_int32_t vdev_id = ps_req->sessionid; + u_int32_t uapsd_val = 0; + u_int8_t is_qpower_enabled = wma_is_qpower_enabled(wma); + + /* Disable Sta Mode Power save */ + ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false); + if (ret) { + WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams); + + WMA_LOGD("Enable Uapsd vdevId %d Mask %d", vdev_id, uapsd_val); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_UAPSD, uapsd_val); + if (ret) { + WMA_LOGE("Enable Uapsd Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id); + + ret = wma_set_force_sleep(wma, vdev_id, true, + is_qpower_enabled); + if (ret) { + WMA_LOGE("Enable Forced Sleep Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + ps_req->status = VOS_STATUS_SUCCESS; +resp: + wma_send_msg(wma, WDA_ENTER_UAPSD_RSP, ps_req, 0); +} + +static void wma_disable_uapsd_mode(tp_wma_handle wma, + tpDisableUapsdParams ps_req) +{ + int32_t ret; + u_int32_t vdev_id = ps_req->sessionid; + u_int8_t is_qpower_enabled = wma_is_qpower_enabled(wma); + + WMA_LOGD("Disable Uapsd vdevId %d", vdev_id); + + /* Disable Sta Mode Power save */ + ret = wmi_unified_set_sta_ps(wma->wmi_handle, vdev_id, false); + if (ret) { + WMA_LOGE("Disable Sta Mode Ps Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_UAPSD, 0); + if (ret) { + WMA_LOGE("Disable Uapsd Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + /* Re enable Sta Mode Powersave with proper configuration */ + ret = wma_set_force_sleep(wma, vdev_id, false, + is_qpower_enabled); + if (ret) { + WMA_LOGE("Disable Forced Sleep Failed vdevId %d", vdev_id); + ps_req->status = VOS_STATUS_E_FAILURE; + goto resp; + } + + ps_req->status = VOS_STATUS_SUCCESS; +resp: + wma_send_msg(wma, WDA_EXIT_UAPSD_RSP, ps_req, 0); +} + +static void wma_set_keepalive_req(tp_wma_handle wma, + tSirKeepAliveReq *keepalive) +{ + WMA_LOGD("KEEPALIVE:PacketType:%d", keepalive->packetType); + wma_set_sta_keep_alive(wma, keepalive->sessionId, + keepalive->packetType, + keepalive->timePeriod, + keepalive->hostIpv4Addr, + keepalive->destIpv4Addr, + keepalive->destMacAddr); + + vos_mem_free(keepalive); +} +/* + * This function sets the trigger uapsd + * params such as service interval, delay + * interval and suspend interval which + * will be used by the firmware to send + * trigger frames periodically when there + * is no traffic on the transmit side. + */ +int32_t +wmi_unified_set_sta_uapsd_auto_trig_cmd( + wmi_unified_t wmi_handle, + u_int32_t vdevid, + u_int8_t peer_addr[IEEE80211_ADDR_LEN], + u_int8_t *autoTriggerparam, + u_int32_t num_ac) +{ + wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; + int32_t ret; + u_int32_t param_len = num_ac * + sizeof(wmi_sta_uapsd_auto_trig_param); + u_int32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE; + u_int32_t i; + wmi_buf_t buf; + u_int8_t *buf_ptr; + + buf = wmi_buf_alloc(wmi_handle, cmd_len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_sta_uapsd_auto_trig_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_uapsd_auto_trig_cmd_fixed_param)); + cmd->vdev_id = vdevid; + cmd->num_ac = num_ac; + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + + /* TLV indicating array of structures to follow */ + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, param_len); + + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, autoTriggerparam, param_len); + + /* + * Update tag and length for uapsd auto trigger params (this will take + * care of updating tag and length if it is not pre-filled by caller). + */ + for (i = 0; i < num_ac; i++) { + WMITLV_SET_HDR((buf_ptr + + (i * sizeof(wmi_sta_uapsd_auto_trig_param))), + WMITLV_TAG_STRUC_wmi_sta_uapsd_auto_trig_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_uapsd_auto_trig_param)); + } + + ret = wmi_unified_cmd_send(wmi_handle, buf, cmd_len, + WMI_STA_UAPSD_AUTO_TRIG_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send set uapsd param ret = %d", ret); + wmi_buf_free(buf); + } + return ret; +} + +/* + * This function sets the trigger uapsd + * params such as service interval, delay + * interval and suspend interval which + * will be used by the firmware to send + * trigger frames periodically when there + * is no traffic on the transmit side. + */ +VOS_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, u_int32_t vdev_id, + tp_wma_trigger_uapsd_params trigger_uapsd_params) +{ + int32_t ret; + wmi_sta_uapsd_auto_trig_param uapsd_trigger_param; + + WMA_LOGD("Trigger uapsd params vdev id %d", vdev_id); + + WMA_LOGD("WMM AC %d User Priority %d SvcIntv %d DelIntv %d SusIntv %d", + trigger_uapsd_params->wmm_ac, + trigger_uapsd_params->user_priority, + trigger_uapsd_params->service_interval, + trigger_uapsd_params->delay_interval, + trigger_uapsd_params->suspend_interval); + + if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_STA_UAPSD_BASIC_AUTO_TRIG) || + !WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_STA_UAPSD_VAR_AUTO_TRIG)) { + WMA_LOGD("Trigger uapsd is not supported vdev id %d", vdev_id); + return VOS_STATUS_SUCCESS; + } + + uapsd_trigger_param.wmm_ac = + trigger_uapsd_params->wmm_ac; + uapsd_trigger_param.user_priority = + trigger_uapsd_params->user_priority; + uapsd_trigger_param.service_interval = + trigger_uapsd_params->service_interval; + uapsd_trigger_param.suspend_interval = + trigger_uapsd_params->suspend_interval; + uapsd_trigger_param.delay_interval = + trigger_uapsd_params->delay_interval; + + ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle, vdev_id, + wma_handle->interfaces[vdev_id].bssid, + (u_int8_t*)(&uapsd_trigger_param), + 1); + if (ret) { + WMA_LOGE("Fail to send uapsd param cmd for vdevid %d ret = %d", + ret, vdev_id); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle, + u_int32_t vdev_id, + enum uapsd_ac ac) +{ + int32_t ret; + struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; + wmi_sta_uapsd_auto_trig_param uapsd_trigger_param; + enum uapsd_up user_priority; + + WMA_LOGD("Disable Uapsd per ac vdevId %d ac %d", vdev_id, ac); + + switch (ac) { + case UAPSD_VO: + iface->uapsd_cached_val &= + ~(WMI_STA_PS_UAPSD_AC3_DELIVERY_EN | + WMI_STA_PS_UAPSD_AC3_TRIGGER_EN); + user_priority = UAPSD_UP_VO; + break; + case UAPSD_VI: + iface->uapsd_cached_val &= + ~(WMI_STA_PS_UAPSD_AC2_DELIVERY_EN | + WMI_STA_PS_UAPSD_AC2_TRIGGER_EN); + user_priority = UAPSD_UP_VI; + break; + case UAPSD_BK: + iface->uapsd_cached_val &= + ~(WMI_STA_PS_UAPSD_AC1_DELIVERY_EN | + WMI_STA_PS_UAPSD_AC1_TRIGGER_EN); + user_priority = UAPSD_UP_BK; + break; + case UAPSD_BE: + iface->uapsd_cached_val &= + ~(WMI_STA_PS_UAPSD_AC0_DELIVERY_EN | + WMI_STA_PS_UAPSD_AC0_TRIGGER_EN); + user_priority = UAPSD_UP_BE; + break; + default: + WMA_LOGE("Invalid AC vdevId %d ac %d", vdev_id, ac); + return VOS_STATUS_E_FAILURE; + } + + /* + * Disable Auto Trigger Functionality before + * disabling uapsd for a particular AC + */ + uapsd_trigger_param.wmm_ac = ac; + uapsd_trigger_param.user_priority = user_priority; + uapsd_trigger_param.service_interval = 0; + uapsd_trigger_param.suspend_interval = 0; + uapsd_trigger_param.delay_interval = 0; + + ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wma_handle->wmi_handle, + vdev_id, + wma_handle->interfaces[vdev_id].bssid, + (u_int8_t*)(&uapsd_trigger_param), + 1); + if (ret) { + WMA_LOGE("Fail to send auto trig cmd for vdevid %d ret = %d", + ret, vdev_id); + return VOS_STATUS_E_FAILURE; + } + + ret = wmi_unified_set_sta_ps_param(wma_handle->wmi_handle, vdev_id, + WMI_STA_PS_PARAM_UAPSD, iface->uapsd_cached_val); + if (ret) { + WMA_LOGE("Disable Uapsd per ac Failed vdevId %d ac %d", vdev_id, ac); + return VOS_STATUS_E_FAILURE; + } + WMA_LOGD("Disable Uapsd per ac vdevId %d val %d", vdev_id, + iface->uapsd_cached_val); + return VOS_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_SCAN_PNO + +/* Request FW to start PNO operation */ +static VOS_STATUS wma_pno_start(tp_wma_handle wma, tpSirPNOScanReq pno) +{ + wmi_nlo_config_cmd_fixed_param *cmd; + nlo_configured_parameters *nlo_list; + u_int32_t *channel_list; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + u_int8_t i; + int ret; + + WMA_LOGD("PNO Start"); + + len = sizeof(*cmd) + + WMI_TLV_HDR_SIZE + /* TLV place holder for array of structures nlo_configured_parameters(nlo_list) */ + WMI_TLV_HDR_SIZE; /* TLV place holder for array of uint32 channel_list */ + + len += sizeof(u_int32_t) * MIN(pno->aNetworks[0].ucChannelCount, + WMI_NLO_MAX_CHAN); + len += sizeof(nlo_configured_parameters) * + MIN(pno->ucNetworksCount, WMI_NLO_MAX_SSIDS); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); + + buf_ptr = (u_int8_t *) cmd; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_nlo_config_cmd_fixed_param)); + cmd->vdev_id = pno->sessionId; + cmd->flags = WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN; + + /* Copy scan interval */ + if (pno->scanTimers.ucScanTimersCount) { + cmd->fast_scan_period = + WMA_SEC_TO_MSEC(pno->scanTimers.aTimerValues[0].uTimerValue); + cmd->slow_scan_period = cmd->fast_scan_period; + WMA_LOGD("Scan period : %d msec", cmd->slow_scan_period); + } + + buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); + + cmd->no_of_ssids = MIN(pno->ucNetworksCount, WMI_NLO_MAX_SSIDS); + WMA_LOGD("SSID count : %d", cmd->no_of_ssids); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + cmd->no_of_ssids * sizeof(nlo_configured_parameters)); + buf_ptr += WMI_TLV_HDR_SIZE; + + nlo_list = (nlo_configured_parameters *) buf_ptr; + for (i = 0; i < cmd->no_of_ssids; i++) { + WMITLV_SET_HDR(&nlo_list[i].tlv_header, + WMITLV_TAG_ARRAY_BYTE, + WMITLV_GET_STRUCT_TLVLEN(nlo_configured_parameters)); + /* Copy ssid and it's length */ + nlo_list[i].ssid.valid = TRUE; + nlo_list[i].ssid.ssid.ssid_len = pno->aNetworks[i].ssId.length; + vos_mem_copy(nlo_list[i].ssid.ssid.ssid, + pno->aNetworks[i].ssId.ssId, + nlo_list[i].ssid.ssid.ssid_len); + WMA_LOGD("index: %d ssid: %.*s len: %d", i, + nlo_list[i].ssid.ssid.ssid_len, + (char *) nlo_list[i].ssid.ssid.ssid, + nlo_list[i].ssid.ssid.ssid_len); + + /* Copy rssi threshold */ + if (pno->aNetworks[i].rssiThreshold && + pno->aNetworks[i].rssiThreshold > WMA_RSSI_THOLD_DEFAULT) { + nlo_list[i].rssi_cond.valid = TRUE; + nlo_list[i].rssi_cond.rssi = + pno->aNetworks[i].rssiThreshold; + WMA_LOGD("RSSI threshold : %d dBm", + nlo_list[i].rssi_cond.rssi); + } + nlo_list[i].bcast_nw_type.valid = TRUE; + nlo_list[i].bcast_nw_type.bcast_nw_type = + pno->aNetworks[i].bcastNetwType; + WMA_LOGI("Broadcast NW type (%u)", + nlo_list[i].bcast_nw_type.bcast_nw_type); + } + buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); + + /* Copy channel info */ + cmd->num_of_channels = MIN(pno->aNetworks[0].ucChannelCount, + WMI_NLO_MAX_CHAN); + WMA_LOGD("Channel count: %d", cmd->num_of_channels); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (cmd->num_of_channels * sizeof(u_int32_t))); + buf_ptr += WMI_TLV_HDR_SIZE; + + channel_list = (u_int32_t *) buf_ptr; + for (i = 0; i < cmd->num_of_channels; i++) { + channel_list[i] = pno->aNetworks[0].aChannels[i]; + + if (channel_list[i] < WMA_NLO_FREQ_THRESH) + channel_list[i] = vos_chan_to_freq(channel_list[i]); + + WMA_LOGD("Ch[%d]: %d MHz", i, channel_list[i]); + } + buf_ptr += cmd->num_of_channels * sizeof(u_int32_t); + + /* TODO: Discrete firmware doesn't have command/option to configure + * App IE which comes from wpa_supplicant as of part PNO start request. + */ + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send nlo wmi cmd", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + wma->interfaces[pno->sessionId].pno_in_progress = TRUE; + + WMA_LOGD("PNO start request sent successfully for vdev %d", + pno->sessionId); + + return VOS_STATUS_SUCCESS; +} + +/* Request FW to stop ongoing PNO operation */ +static VOS_STATUS wma_pno_stop(tp_wma_handle wma, u_int8_t vdev_id) +{ + wmi_nlo_config_cmd_fixed_param *cmd; + int32_t len = sizeof(*cmd); + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!wma->interfaces[vdev_id].pno_in_progress) { + WMA_LOGD("No active pno session found for vdev %d, skip pno stop request", + vdev_id); + return VOS_STATUS_SUCCESS; + } + + WMA_LOGD("PNO Stop"); + + len += WMI_TLV_HDR_SIZE + /* TLV place holder for array of structures nlo_configured_parameters(nlo_list) */ + WMI_TLV_HDR_SIZE; /* TLV place holder for array of uint32 channel_list */ + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_nlo_config_cmd_fixed_param *) wmi_buf_data(buf); + buf_ptr = (u_int8_t *) cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_nlo_config_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_nlo_config_cmd_fixed_param)); + + cmd->vdev_id = vdev_id; + cmd->flags = WMI_NLO_CONFIG_STOP; + buf_ptr += sizeof(*cmd); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send nlo wmi cmd", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + wma->interfaces[vdev_id].pno_in_progress = FALSE; + + WMA_LOGD("PNO stop request sent successfully for vdev %d", + vdev_id); + + return VOS_STATUS_SUCCESS; +} + +static void wma_config_pno(tp_wma_handle wma, tpSirPNOScanReq pno) +{ + VOS_STATUS ret; + + if (pno->enable) + ret = wma_pno_start(wma, pno); + else + ret = wma_pno_stop(wma, pno->sessionId); + + if (ret) + WMA_LOGE("%s: PNO %s failed %d", __func__, + pno->enable ? "start" : "stop", ret); + + /* SME expects WMA to free tpSirPNOScanReq memory after + * processing PNO request. */ + vos_mem_free(pno); +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +static VOS_STATUS wma_plm_start(tp_wma_handle wma, const tpSirPlmReq plm) +{ + wmi_vdev_plmreq_start_cmd_fixed_param *cmd; + u_int32_t *channel_list; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + u_int8_t count; + int ret; + + if (NULL == plm || NULL == wma) { + WMA_LOGE("%s: input pointer is NULL ", __func__); + return VOS_STATUS_E_FAILURE; + } + WMA_LOGD("PLM Start"); + + len = sizeof(*cmd) + + WMI_TLV_HDR_SIZE; /* TLV place holder for channel_list */ + len += sizeof(u_int32_t) * plm->plmNumCh; + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + cmd = (wmi_vdev_plmreq_start_cmd_fixed_param *) wmi_buf_data(buf); + + buf_ptr = (u_int8_t *) cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_plmreq_start_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_plmreq_start_cmd_fixed_param)); + + cmd->vdev_id = plm->sessionId; + + cmd->meas_token = plm->meas_token; + cmd->dialog_token = plm->diag_token; + cmd->number_bursts = plm->numBursts; + cmd->burst_interval = WMA_SEC_TO_MSEC(plm->burstInt); + cmd->off_duration = plm->measDuration; + cmd->burst_cycle = plm->burstLen; + cmd->tx_power = plm->desiredTxPwr; + WMI_CHAR_ARRAY_TO_MAC_ADDR(plm->macAddr, &cmd->dest_mac); + cmd->num_chans = plm->plmNumCh; + + buf_ptr += sizeof(wmi_vdev_plmreq_start_cmd_fixed_param); + + WMA_LOGD("vdev : %d measu token : %d", cmd->vdev_id, cmd->meas_token); + WMA_LOGD("dialog_token: %d", cmd->dialog_token); + WMA_LOGD("number_bursts: %d", cmd->number_bursts); + WMA_LOGD("burst_interval: %d", cmd->burst_interval); + WMA_LOGD("off_duration: %d", cmd->off_duration); + WMA_LOGD("burst_cycle: %d", cmd->burst_cycle); + WMA_LOGD("tx_power: %d", cmd->tx_power); + WMA_LOGD("Number of channels : %d", cmd->num_chans); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (cmd->num_chans * sizeof(u_int32_t))); + + buf_ptr += WMI_TLV_HDR_SIZE; + if (cmd->num_chans) + { + channel_list = (u_int32_t *) buf_ptr; + for (count = 0; count < cmd->num_chans; count++) { + channel_list[count] = plm->plmChList[count]; + if (channel_list[count] < WMA_NLO_FREQ_THRESH) + channel_list[count] = + vos_chan_to_freq(channel_list[count]); + WMA_LOGD("Ch[%d]: %d MHz", count, channel_list[count]); + } + buf_ptr += cmd->num_chans * sizeof(u_int32_t); + } + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_PLMREQ_START_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send plm start wmi cmd", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + wma->interfaces[plm->sessionId].plm_in_progress = TRUE; + + WMA_LOGD("Plm start request sent successfully for vdev %d", + plm->sessionId); + + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_plm_stop(tp_wma_handle wma, const tpSirPlmReq plm) +{ + wmi_vdev_plmreq_stop_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (NULL == plm || NULL == wma) { + WMA_LOGE("%s: input pointer is NULL ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (FALSE == wma->interfaces[plm->sessionId].plm_in_progress) { + WMA_LOGE("No active plm req found, skip plm stop req" ); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("PLM Stop"); + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_vdev_plmreq_stop_cmd_fixed_param *) wmi_buf_data(buf); + + buf_ptr = (u_int8_t *) cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_plmreq_stop_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_vdev_plmreq_stop_cmd_fixed_param)); + + cmd->vdev_id = plm->sessionId; + + cmd->meas_token = plm->meas_token; + WMA_LOGD("vdev %d meas token %d", cmd->vdev_id, cmd->meas_token); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_PLMREQ_STOP_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send plm stop wmi cmd", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + wma->interfaces[plm->sessionId].plm_in_progress = FALSE; + + WMA_LOGD("Plm stop request sent successfully for vdev %d", + plm->sessionId); + + return VOS_STATUS_SUCCESS; +} +static void wma_config_plm(tp_wma_handle wma, tpSirPlmReq plm) +{ + VOS_STATUS ret = 0; + + if (NULL == plm || NULL == wma) + return; + + if (plm->enable) + ret = wma_plm_start(wma, plm); + else + ret = wma_plm_stop(wma, plm); + + if (ret) + WMA_LOGE("%s: PLM %s failed %d", __func__, + plm->enable ? "start" : "stop", ret); + + /* SME expects WMA to free tpSirPlmReq memory after + * processing PLM request. */ + vos_mem_free(plm); + plm = NULL; +} +#endif + +/* + * After pushing cached scan results (that are stored in LIM) to SME, + * PE will post WDA_SME_SCAN_CACHE_UPDATED message indication to + * wma and intern this function handles that message. This function will + * check for PNO completion (by checking NLO match event) and post PNO + * completion back to SME if PNO operation is completed successfully. + */ +void wma_scan_cache_updated_ind(tp_wma_handle wma, u_int8_t sessionId) +{ + tSirPrefNetworkFoundInd *nw_found_ind; + VOS_STATUS status; + vos_msg_t vos_msg; + u_int8_t len, i; + + for (i = 0; i < wma->max_bssid; i++) { + if (wma->interfaces[i].nlo_match_evt_received) + break; + } + + if (i == wma->max_bssid) { + WMA_LOGD("PNO match event is not received in any vdev, skip scan cache update indication"); + return; + } + wma->interfaces[i].nlo_match_evt_received = FALSE; + + WMA_LOGD("Posting PNO completion to umac"); + + len = sizeof(tSirPrefNetworkFoundInd); + nw_found_ind = (tSirPrefNetworkFoundInd *) vos_mem_malloc(len); + + if (NULL == nw_found_ind) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return; + } + + nw_found_ind->mesgType = eWNI_SME_PREF_NETWORK_FOUND_IND; + nw_found_ind->mesgLen = len; + nw_found_ind->sessionId = sessionId; + + vos_msg.type = eWNI_SME_PREF_NETWORK_FOUND_IND; + vos_msg.bodyptr = (void *) nw_found_ind; + vos_msg.bodyval = 0; + + status = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to post PNO completion match event to SME", + __func__); + vos_mem_free(nw_found_ind); + } +} + +#endif + +static void wma_send_status_to_suspend_ind(tp_wma_handle wma, boolean suspended) +{ + tSirReadyToSuspendInd *ready_to_suspend; + VOS_STATUS status; + vos_msg_t vos_msg; + u_int8_t len; + + WMA_LOGD("Posting ready to suspend indication to umac"); + + len = sizeof(tSirReadyToSuspendInd); + ready_to_suspend = (tSirReadyToSuspendInd *) vos_mem_malloc(len); + + if (NULL == ready_to_suspend) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return; + } + + ready_to_suspend->mesgType = eWNI_SME_READY_TO_SUSPEND_IND; + ready_to_suspend->mesgLen = len; + ready_to_suspend->suspended = suspended; + + vos_msg.type = eWNI_SME_READY_TO_SUSPEND_IND; + vos_msg.bodyptr = (void *) ready_to_suspend; + vos_msg.bodyval = 0; + + status = vos_mq_post_message(VOS_MQ_ID_SME, &vos_msg); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to post ready to suspend"); + vos_mem_free(ready_to_suspend); + } +} + +/* Frees memory associated to given pattern ID in wow pattern cache. */ +static inline void wma_free_wow_ptrn(tp_wma_handle wma, u_int8_t ptrn_id) +{ + if (wma->wow.no_of_ptrn_cached <= 0 || + !wma->wow.cache[ptrn_id]) + return; + + WMA_LOGD("Deleting wow pattern %d from cache which belongs to vdev id %d", + ptrn_id, wma->wow.cache[ptrn_id]->vdev_id); + + vos_mem_free(wma->wow.cache[ptrn_id]->ptrn); + vos_mem_free(wma->wow.cache[ptrn_id]->mask); + vos_mem_free(wma->wow.cache[ptrn_id]); + wma->wow.cache[ptrn_id] = NULL; + + wma->wow.no_of_ptrn_cached--; +} + +/* Converts wow wakeup reason code to text format */ +static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason) +{ + switch (wake_reason) { + case WOW_REASON_UNSPECIFIED: + return "UNSPECIFIED"; + case WOW_REASON_NLOD: + return "NLOD"; + case WOW_REASON_AP_ASSOC_LOST: + return "AP_ASSOC_LOST"; + case WOW_REASON_LOW_RSSI: + return "LOW_RSSI"; + case WOW_REASON_DEAUTH_RECVD: + return "DEAUTH_RECVD"; + case WOW_REASON_DISASSOC_RECVD: + return "DISASSOC_RECVD"; + case WOW_REASON_GTK_HS_ERR: + return "GTK_HS_ERR"; + case WOW_REASON_EAP_REQ: + return "EAP_REQ"; + case WOW_REASON_FOURWAY_HS_RECV: + return "FOURWAY_HS_RECV"; + case WOW_REASON_TIMER_INTR_RECV: + return "TIMER_INTR_RECV"; + case WOW_REASON_PATTERN_MATCH_FOUND: + return "PATTERN_MATCH_FOUND"; + case WOW_REASON_RECV_MAGIC_PATTERN: + return "RECV_MAGIC_PATTERN"; + case WOW_REASON_P2P_DISC: + return "P2P_DISC"; +#ifdef FEATURE_WLAN_LPHB + case WOW_REASON_WLAN_HB: + return "WLAN_HB"; +#endif /* FEATURE_WLAN_LPHB */ + + case WOW_REASON_CSA_EVENT: + return "CSA_EVENT"; + case WOW_REASON_PROBE_REQ_WPS_IE_RECV: + return "PROBE_REQ_RECV"; + case WOW_REASON_AUTH_REQ_RECV: + return "AUTH_REQ_RECV"; + case WOW_REASON_ASSOC_REQ_RECV: + return "ASSOC_REQ_RECV"; + case WOW_REASON_HTT_EVENT: + return "WOW_REASON_HTT_EVENT"; +#ifdef FEATURE_WLAN_RA_FILTERING + case WOW_REASON_RA_MATCH: + return "WOW_REASON_RA_MATCH"; +#endif + case WOW_REASON_BEACON_RECV: + return "WOW_REASON_IBSS_BEACON_RECV"; +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + case WOW_REASON_HOST_AUTO_SHUTDOWN: + return "WOW_REASON_HOST_AUTO_SHUTDOWN"; +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WOW_REASON_ROAM_HO: + return "WOW_REASON_ROAM_HO"; +#endif + } + return "unknown"; +} + +static void wma_beacon_miss_handler(tp_wma_handle wma, u_int32_t vdev_id) +{ + tSirSmeMissedBeaconInd *beacon_miss_ind; + + beacon_miss_ind = (tSirSmeMissedBeaconInd *) vos_mem_malloc + (sizeof(tSirSmeMissedBeaconInd)); + + if (NULL == beacon_miss_ind) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return; + } + beacon_miss_ind->messageType = WDA_MISSED_BEACON_IND; + beacon_miss_ind->length = sizeof(tSirSmeMissedBeaconInd); + beacon_miss_ind->bssIdx = vdev_id; + + wma_send_msg(wma, WDA_MISSED_BEACON_IND, + (void *)beacon_miss_ind, 0); +} + +#ifdef FEATURE_WLAN_LPHB +static int wma_lphb_handler(tp_wma_handle wma, u_int8_t *event) +{ + wmi_hb_ind_event_fixed_param *hb_fp; + tSirLPHBInd *slphb_indication; + VOS_STATUS vos_status; + vos_msg_t sme_msg = {0} ; + + hb_fp = (wmi_hb_ind_event_fixed_param *)event; + if (!hb_fp) { + WMA_LOGE("Invalid wmi_hb_ind_event_fixed_param buffer"); + return -EINVAL; + } + + WMA_LOGD("lphb indication received with vdev_id=%d, session=%d, reason=%d", + hb_fp->vdev_id, hb_fp->session, hb_fp->reason); + + slphb_indication = (tSirLPHBInd *) vos_mem_malloc(sizeof(tSirLPHBInd)); + + if (!slphb_indication) { + WMA_LOGE("Invalid LPHB indication buffer"); + return -EINVAL; + } + + slphb_indication->sessionIdx = hb_fp->session; + slphb_indication->protocolType = hb_fp->reason; + slphb_indication->eventReason= hb_fp->reason; + + sme_msg.type = eWNI_SME_LPHB_IND; + sme_msg.bodyptr = slphb_indication; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if ( !VOS_IS_STATUS_SUCCESS(vos_status) ) + { + WMA_LOGE("Fail to post eWNI_SME_LPHB_IND msg to SME"); + vos_mem_free(slphb_indication); + return -EINVAL; + } + + return 0; +} +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_D0WOW +/* + * Handler to catch D0-WOW disable ACK event. + */ +static int wma_d0_wow_disable_ack_event(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *param_buf; + wmi_d0_wow_disable_ack_event_fixed_param *resp_data; + + param_buf = (WMI_D0_WOW_DISABLE_ACK_EVENTID_param_tlvs *)event; + if (!param_buf) { + WMA_LOGE("Invalid D0-WOW disable ACK event buffer!"); + return -EINVAL; + } + + resp_data = param_buf->fixed_param; + vos_event_set(&wma->wma_resume_event); + WMA_LOGD("Received D0-WOW disable ACK"); + return 0; +} +#endif + +/* + * Handler to catch wow wakeup host event. This event will have + * reason why the firmware has woken the host. + */ +static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf; + WOW_EVENT_INFO_fixed_param *wake_info; +#ifdef FEATURE_WLAN_SCAN_PNO + struct wma_txrx_node *node; +#endif + u_int32_t wake_lock_duration = 0; + u_int32_t wow_buf_pkt_len = 0; + + param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event; + if (!param_buf) { + WMA_LOGE("Invalid wow wakeup host event buf"); + return -EINVAL; + } + + wake_info = param_buf->fixed_param; + + WMA_LOGA("WOW wakeup host event received (reason: %s(%d)) for vdev %d", + wma_wow_wake_reason_str(wake_info->wake_reason), + wake_info->wake_reason, + wake_info->vdev_id); + + vos_event_set(&wma->wma_resume_event); + + switch (wake_info->wake_reason) { + case WOW_REASON_AUTH_REQ_RECV: + wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT; + break; + + case WOW_REASON_ASSOC_REQ_RECV: + wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION; + break; + + case WOW_REASON_DEAUTH_RECVD: + wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION; + break; + + case WOW_REASON_DISASSOC_RECVD: + wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION; + break; + + case WOW_REASON_AP_ASSOC_LOST: + WMA_LOGA("Beacon miss indication on vdev %x", + wake_info->vdev_id); + wma_beacon_miss_handler(wma, wake_info->vdev_id); + break; +#ifdef FEATURE_WLAN_RA_FILTERING + case WOW_REASON_RA_MATCH: + wake_lock_duration = WMA_RA_MATCH_RECV_WAKE_LOCK_DURATION; + break; +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + case WOW_REASON_HOST_AUTO_SHUTDOWN: + wake_lock_duration = WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION; + WMA_LOGA("Received WOW Auto Shutdown trigger in suspend"); + if (wma_post_auto_shutdown_msg()) + return -EINVAL; + break; +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + case WOW_REASON_NLOD: + wake_lock_duration = WMA_PNO_WAKE_LOCK_TIMEOUT; + node = &wma->interfaces[wake_info->vdev_id]; + if (node) { + WMA_LOGD("NLO match happened"); + node->nlo_match_evt_received = TRUE; + } + break; +#endif + + case WOW_REASON_CSA_EVENT: + { + WMI_CSA_HANDLING_EVENTID_param_tlvs param; + WMA_LOGD("Host woken up because of CSA IE"); + param.fixed_param = (wmi_csa_event_fixed_param *) + (((u_int8_t *) wake_info) + + sizeof(WOW_EVENT_INFO_fixed_param) + + WOW_CSA_EVENT_OFFSET); + wma_csa_offload_handler(handle, (u_int8_t *)¶m, + sizeof(param)); + } + break; + +#ifdef FEATURE_WLAN_LPHB + case WOW_REASON_WLAN_HB: + wma_lphb_handler(wma, (u_int8_t *)param_buf->hb_indevt); + break; +#endif + + case WOW_REASON_HTT_EVENT: + break; + case WOW_REASON_PATTERN_MATCH_FOUND: + WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr"); + if (param_buf->wow_packet_buffer) { + /* First 4-bytes of wow_packet_buffer is the length */ + vos_mem_copy((u_int8_t *) &wow_buf_pkt_len, + param_buf->wow_packet_buffer, 4); + vos_trace_hex_dump(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + param_buf->wow_packet_buffer + 4, + wow_buf_pkt_len); + } else { + WMA_LOGE("No wow packet buffer present"); + } + break; + + case WOW_REASON_LOW_RSSI: + { + /* WOW_REASON_LOW_RSSI is used for all roaming events. + * WMI_ROAM_REASON_BETTER_AP, WMI_ROAM_REASON_BMISS, + * WMI_ROAM_REASON_SUITABLE_AP will be handled by + * wma_roam_event_callback(). + */ + WMI_ROAM_EVENTID_param_tlvs param; + if (param_buf->wow_packet_buffer) { + /* Roam event is embedded in wow_packet_buffer */ + WMA_LOGD("Host woken up because of roam event"); + vos_mem_copy((u_int8_t *) &wow_buf_pkt_len, + param_buf->wow_packet_buffer, 4); + WMA_LOGD("wow_packet_buffer dump"); + vos_trace_hex_dump(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_DEBUG, + param_buf->wow_packet_buffer, wow_buf_pkt_len); + if (wow_buf_pkt_len >= sizeof(param)) { + param.fixed_param = (wmi_roam_event_fixed_param *) + (param_buf->wow_packet_buffer +4); + wma_roam_event_callback(handle, (u_int8_t *)¶m, + sizeof(param)); + } else { + WMA_LOGE("Wrong length for roam event = %d bytes", + wow_buf_pkt_len); + } + } else { + /* No wow_packet_buffer means a better AP beacon + * will follow in a later event. + */ + WMA_LOGD("Host woken up because of better AP beacon"); + } + break; + } + default: + break; + } + + if (wake_lock_duration) { + vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, + wake_lock_duration); + WMA_LOGA("Holding %d msec wake_lock", wake_lock_duration); + } + + return 0; +} + +static inline void wma_set_wow_bus_suspend(tp_wma_handle wma, int val) { + + adf_os_atomic_set(&wma->is_wow_bus_suspended, val); +} + +static inline int wma_get_wow_bus_suspend(tp_wma_handle wma) { + + return adf_os_atomic_read(&wma->is_wow_bus_suspended); +} + +/* Configures wow wakeup events. */ +static VOS_STATUS wma_add_wow_wakeup_event(tp_wma_handle wma, + WOW_WAKE_EVENT_TYPE event, + v_BOOL_t enable) +{ + WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *cmd; + u_int16_t len; + wmi_buf_t buf; + int ret; + + len = sizeof(WMI_WOW_ADD_DEL_EVT_CMD_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + cmd = (WMI_WOW_ADD_DEL_EVT_CMD_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_WOW_ADD_DEL_EVT_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_WOW_ADD_DEL_EVT_CMD_fixed_param)); + cmd->vdev_id = 0; + cmd->is_add = enable; + cmd->event_bitmap = (1 << event); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); + if (ret) { + WMA_LOGE("Failed to config wow wakeup event"); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Wakeup pattern 0x%x %s in fw", event, + enable ? "enabled":"disabled"); + + return VOS_STATUS_SUCCESS; +} + +/* Sends WOW patterns to FW. */ +static VOS_STATUS wma_send_wow_patterns_to_fw(tp_wma_handle wma, + u_int8_t vdev_id, u_int8_t ptrn_id, + u_int8_t *ptrn, u_int8_t ptrn_len, + u_int8_t ptrn_offset, u_int8_t *mask, + u_int8_t mask_len) + +{ + WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; + WOW_BITMAP_PATTERN_T *bitmap_pattern; + wmi_buf_t buf; + u_int8_t *buf_ptr; +#ifdef WMA_DUMP_WOW_PTRN + u_int8_t pos; + u_int8_t *tmp; +#endif + int32_t len; + int ret; + + len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + + WMI_TLV_HDR_SIZE + + 1 * sizeof(WOW_BITMAP_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(A_UINT32) + + WMI_TLV_HDR_SIZE + + 1 * sizeof(A_UINT32); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *)wmi_buf_data(buf); + buf_ptr = (u_int8_t *)cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_WOW_ADD_PATTERN_CMD_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->pattern_id = ptrn_id; + cmd->pattern_type = WOW_BITMAP_PATTERN; + buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(WOW_BITMAP_PATTERN_T)); + buf_ptr += WMI_TLV_HDR_SIZE; + bitmap_pattern = (WOW_BITMAP_PATTERN_T *)buf_ptr; + + WMITLV_SET_HDR(&bitmap_pattern->tlv_header, + WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T, + WMITLV_GET_STRUCT_TLVLEN(WOW_BITMAP_PATTERN_T)); + + vos_mem_copy(&bitmap_pattern->patternbuf[0], ptrn, ptrn_len); + vos_mem_copy(&bitmap_pattern->bitmaskbuf[0], mask, mask_len); + + bitmap_pattern->pattern_offset = ptrn_offset; + bitmap_pattern->pattern_len = ptrn_len; + + if(bitmap_pattern->pattern_len > WOW_DEFAULT_BITMAP_PATTERN_SIZE) + bitmap_pattern->pattern_len = WOW_DEFAULT_BITMAP_PATTERN_SIZE; + + if(bitmap_pattern->pattern_len > WOW_DEFAULT_BITMASK_SIZE) + bitmap_pattern->pattern_len = WOW_DEFAULT_BITMASK_SIZE; + + bitmap_pattern->bitmask_len = bitmap_pattern->pattern_len; + bitmap_pattern->pattern_id = ptrn_id; + + WMA_LOGD("vdev id : %d, ptrn id: %d, ptrn len: %d, ptrn offset: %d", + cmd->vdev_id, cmd->pattern_id, bitmap_pattern->pattern_len, + bitmap_pattern->pattern_offset); + +#ifdef WMA_DUMP_WOW_PTRN + printk("Pattern : "); + tmp = (u_int8_t *) &bitmap_pattern->patternbuf[0]; + for (pos = 0; pos < bitmap_pattern->pattern_len; pos++) + printk("%02X ", tmp[pos]); + + printk("\nMask : "); + tmp = (u_int8_t *) &bitmap_pattern->bitmaskbuf[0]; + for (pos = 0; pos < bitmap_pattern->pattern_len; pos++) + printk("%02X ", tmp[pos]); +#endif + + buf_ptr += sizeof(WOW_BITMAP_PATTERN_T); + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for pattern_info_timeout but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for ra_ratelimit_interval with dummy data as this fix elem*/ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 1 * sizeof(A_UINT32)); + buf_ptr += WMI_TLV_HDR_SIZE; + *(A_UINT32 *)buf_ptr = 0; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_ADD_WAKE_PATTERN_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send wow ptrn to fw", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +/* Sends delete pattern request to FW for given pattern ID on particular vdev */ +static VOS_STATUS wma_del_wow_pattern_in_fw(tp_wma_handle wma, + u_int8_t ptrn_id) +{ + WMI_WOW_DEL_PATTERN_CMD_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int ret; + + len = sizeof(WMI_WOW_DEL_PATTERN_CMD_fixed_param); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (WMI_WOW_DEL_PATTERN_CMD_fixed_param *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_WOW_DEL_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_WOW_DEL_PATTERN_CMD_fixed_param)); + cmd->vdev_id = 0; + cmd->pattern_id = ptrn_id; + cmd->pattern_type = WOW_BITMAP_PATTERN; + + WMA_LOGD("Deleting pattern id: %d in fw", cmd->pattern_id); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_DEL_WAKE_PATTERN_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to delete wow ptrn from fw", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_D0WOW +void wma_set_d0wow_flag(tp_wma_handle wma_handle, A_BOOL flag) +{ + atomic_set(&wma_handle->in_d0wow, flag); +} + +A_BOOL wma_read_d0wow_flag(tp_wma_handle wma_handle) +{ + return atomic_read(&wma_handle->in_d0wow); +} + +/* Enable D0-WOW in firmware. */ +VOS_STATUS wma_enable_d0wow_in_fw(tp_wma_handle wma) +{ + wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int host_credits; + int wmi_pending_cmds; + int ret = 0; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed to allocate WMI buffer!", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_d0_wow_enable_disable_cmd_fixed_param)); + cmd->enable = 1; + + vos_event_reset(&wma->target_suspend); + wma->wow_nack = 0; + + host_credits = wmi_get_host_credits(wma->wmi_handle); + wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); + if (host_credits < WMI_WOW_REQUIRED_CREDITS) { + WMA_LOGE("%s: Doesn't have enough credits to Post " + "WMI_D0_WOW_ENABLE_DISABLE_CMDID! " + "Credits: %d, pending_cmds: %d", __func__, + host_credits, wmi_pending_cmds); + goto error; + } + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_D0_WOW_ENABLE_DISABLE_CMDID); + if (ret) { + WMA_LOGE("Failed to enable D0-WOW in FW!"); + goto error; + } + + vos_status = vos_wait_single_event(&wma->target_suspend, + WMA_TGT_SUSPEND_COMPLETE_TIMEOUT); + if (VOS_STATUS_SUCCESS != vos_status) { + WMA_LOGE("Failed to receive D0-WoW enable HTC ACK from FW! " + "Credits: %d, pending_cmds: %d", + wmi_get_host_credits(wma->wmi_handle), + wmi_get_pending_cmds(wma->wmi_handle)); + VOS_BUG(0); + return VOS_STATUS_E_FAILURE; + } + + if (wma->wow_nack) { + WMA_LOGE("FW not ready for D0WOW."); + return VOS_STATUS_E_AGAIN; + } + + host_credits = wmi_get_host_credits(wma->wmi_handle); + wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); + if (host_credits < WMI_WOW_REQUIRED_CREDITS) { + WMA_LOGE("%s: No credits after HTC ACK: %d, pending_cmds: %d, " + "cannot resume back!", __func__, host_credits, + wmi_pending_cmds); + HTC_dump_counter_info(wma->htc_handle); + VOS_BUG(0); + } + + wma->wow.wow_enable_cmd_sent = TRUE; + wmi_set_d0wow_flag(wma->wmi_handle, TRUE); + wma_set_d0wow_flag(wma, TRUE); + WMA_LOGD("D0-WOW is enabled successfully in FW."); + return vos_status; + +error: + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; +} +#endif /* FEATURE_WLAN_D0WOW */ + +/* Enables WOW in firmware. */ +int wma_enable_wow_in_fw(WMA_HANDLE handle) +{ + tp_wma_handle wma = handle; + wmi_wow_enable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int ret; + struct ol_softc *scn; + int host_credits; + int wmi_pending_cmds; +#ifdef CONFIG_CNSS + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + if (NULL == pMac) { + WMA_LOGE("%s: Unable to get PE context", __func__); + return VOS_STATUS_E_FAILURE; + } +#endif + +#ifdef FEATURE_WLAN_D0WOW + if (wma->ap_client_cnt > 0) { + WMA_LOGD("Entering D0-WOW since client count is %d.", + wma->ap_client_cnt); + return wma_enable_d0wow_in_fw(wma); +} +#endif + + len = sizeof(wmi_wow_enable_cmd_fixed_param); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_wow_enable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_wow_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_wow_enable_cmd_fixed_param)); + cmd->enable = TRUE; + + vos_event_reset(&wma->target_suspend); + vos_event_reset(&wma->wow_tx_complete); + wma->wow_nack = 0; + + host_credits = wmi_get_host_credits(wma->wmi_handle); + wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); + + WMA_LOGD("Credits:%d; Pending_Cmds: %d", + host_credits, wmi_pending_cmds); + + if (host_credits < WMI_WOW_REQUIRED_CREDITS) { + WMA_LOGE("%s: Host Doesn't have enough credits to Post WMI_WOW_ENABLE_CMDID! " + "Credits:%d, pending_cmds:%d\n", __func__, + host_credits, wmi_pending_cmds); + goto error; + } + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_ENABLE_CMDID); + if (ret) { + WMA_LOGE("Failed to enable wow in fw"); + goto error; + } + + wmi_set_target_suspend(wma->wmi_handle, TRUE); + + if (vos_wait_single_event(&wma->target_suspend, + WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) + != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to receive WoW Enable Ack from FW"); + WMA_LOGE("Credits:%d; Pending_Cmds: %d", + wmi_get_host_credits(wma->wmi_handle), + wmi_get_pending_cmds(wma->wmi_handle)); +#ifdef CONFIG_CNSS + if (pMac->sme.enableSelfRecovery) { + vos_trigger_recovery(); + } else { + VOS_BUG(0); + } +#else + VOS_BUG(0); +#endif + wmi_set_target_suspend(wma->wmi_handle, FALSE); + return VOS_STATUS_E_FAILURE; + } + + if (wma->wow_nack) { + WMA_LOGE("FW not ready to WOW"); + wmi_set_target_suspend(wma->wmi_handle, FALSE); + return VOS_STATUS_E_AGAIN; + } + + host_credits = wmi_get_host_credits(wma->wmi_handle); + wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); + + if (host_credits < WMI_WOW_REQUIRED_CREDITS) { + WMA_LOGE("%s: No Credits after HTC ACK:%d, pending_cmds:%d, " + "cannot resume back", __func__, host_credits, wmi_pending_cmds); + HTC_dump_counter_info(wma->htc_handle); + if (!vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) + VOS_BUG(0); + else + WMA_LOGE("%s: SSR in progress, ignore no credit issue", __func__); + } + + + WMA_LOGD("WOW enabled successfully in fw: credits:%d" + "pending_cmds: %d", host_credits, wmi_pending_cmds); + + scn = vos_get_context(VOS_MODULE_ID_HIF, wma->vos_context); + + if (scn == NULL) { + WMA_LOGE("%s: Failed to get HIF context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + HTCCancelDeferredTargetSleep(scn); + + wma->wow.wow_enable_cmd_sent = TRUE; + + return VOS_STATUS_SUCCESS; + +error: + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; +} + +/* Sends user configured WOW patterns to the firmware. */ +static VOS_STATUS wma_wow_usr(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t *enable_ptrn_match) +{ + struct wma_wow_ptrn_cache *cache; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + u_int8_t new_mask[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; + u_int8_t bit_to_check, ptrn_id, pos; + + WMA_LOGD("Configuring user wow patterns for vdev %d", vdev_id); + + for (ptrn_id = 0; ptrn_id < WOW_MAX_BITMAP_FILTERS; ptrn_id++) { + cache = wma->wow.cache[ptrn_id]; + if (!cache) + continue; + + if (cache->vdev_id != vdev_id) + continue; + /* + * Convert received pattern mask value from bit representaion + * to byte representation. + * + * For example, received value from umac, + * + * Mask value : A1 (equivalent binary is "1010 0001") + * Pattern value : 12:00:13:00:00:00:00:44 + * + * The value which goes to FW after the conversion from this + * function (1 in mask value will become FF and 0 will + * become 00), + * + * Mask value : FF:00:FF:00:0:00:00:FF + * Pattern value : 12:00:13:00:00:00:00:44 + */ + vos_mem_zero(new_mask, sizeof(new_mask)); + for (pos = 0; pos < cache->ptrn_len; pos++) { + bit_to_check = (WMA_NUM_BITS_IN_BYTE - 1) - + (pos % WMA_NUM_BITS_IN_BYTE); + bit_to_check = 0x1 << bit_to_check; + if (cache->mask[pos / WMA_NUM_BITS_IN_BYTE] & bit_to_check) + new_mask[pos] = WMA_WOW_PTRN_MASK_VALID; + } + + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, ptrn_id, + cache->ptrn, cache->ptrn_len, + cache->ptrn_offset, new_mask, + cache->ptrn_len); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to submit wow pattern to fw (ptrn_id %d)", + ptrn_id); + break; + } + } + + *enable_ptrn_match = 1 << vdev_id; + return ret; +} + +/* Configures default WOW pattern for the given vdev_id which is in AP mode. */ +static VOS_STATUS wma_wow_ap(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t *enable_ptrn_match) +{ + u_int8_t arp_ptrn[] = { 0x08, 0x06 }; + u_int8_t arp_mask[] = { 0xff, 0xff }; + u_int8_t arp_offset = 20; + VOS_STATUS ret; + + /* Setup all ARP pkt pattern. This is dummy pattern hence the lenght + is zero */ + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, + wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++], + arp_ptrn, 0, arp_offset, + arp_mask, 0); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to add WOW ARP pattern"); + return ret; + } + + *enable_ptrn_match = 1 << vdev_id; + return ret; +} + +#ifdef FEATURE_WLAN_RA_FILTERING +static VOS_STATUS wma_wow_sta_ra_filter(tp_wma_handle wma, u_int8_t vdev_id) +{ + + WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int32_t len; + int ret; + + len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_BITMAP_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(WOW_MAGIC_PATTERN_CMD) + + WMI_TLV_HDR_SIZE + + 0 * sizeof(A_UINT32) + + WMI_TLV_HDR_SIZE + + 1 * sizeof(A_UINT32); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *)wmi_buf_data(buf); + buf_ptr = (u_int8_t *)cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_WOW_ADD_PATTERN_CMD_fixed_param)); + cmd->vdev_id = vdev_id; + cmd->pattern_id = 0; + cmd->pattern_type = WOW_IPV6_RA_PATTERN; + buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param); + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for pattern_info_timeout but no data. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Fill TLV for ra_ratelimit_interval. */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32)); + buf_ptr += WMI_TLV_HDR_SIZE; + + + *((A_UINT32 *)buf_ptr) = wma->RArateLimitInterval; + + WMA_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__, + wma->RArateLimitInterval, vdev_id); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_ADD_WAKE_PATTERN_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send RA rate limit to fw", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; + +} +#endif /* FEATURE_WLAN_RA_FILTERING */ + + +/* Configures default WOW pattern for the given vdev_id which is in STA mode. */ +static VOS_STATUS wma_wow_sta(tp_wma_handle wma, u_int8_t vdev_id, + u_int8_t *enable_ptrn_match) +{ + u_int8_t discvr_ptrn[] = { 0xe0, 0x00, 0x00, 0xf8 }; + u_int8_t discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u_int8_t discvr_offset = 30; + u_int8_t mac_mask[ETH_ALEN], free_slot; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + u_int8_t arp_ptrn[] = { 0x08, 0x06 }; + u_int8_t arp_mask[] = { 0xff, 0xff }; + u_int8_t arp_offset = 12; + u_int8_t ns_ptrn[] = {0x86, 0xDD}; + + free_slot = wma->wow.total_free_ptrn_id - wma->wow.used_free_ptrn_id ; + + if (free_slot < WMA_STA_WOW_DEFAULT_PTRN_MAX) { + WMA_LOGD("Free slots are not enough, avail:%d, need: %d", + free_slot, WMA_STA_WOW_DEFAULT_PTRN_MAX); + WMA_LOGD("Ignoring default STA mode wow pattern for vdev : %d", + vdev_id); + return ret; + } + + WMA_LOGD("Configuring default STA mode wow pattern for vdev %d", + vdev_id); + + /* Setup unicast pkt pattern */ + vos_mem_set(&mac_mask, ETH_ALEN, 0xFF); + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, + wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++], + wma->interfaces[vdev_id].addr, ETH_ALEN, 0, + mac_mask, ETH_ALEN); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to add WOW unicast pattern"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + if (wma->ssdp) { + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, + wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++], + discvr_ptrn, sizeof(discvr_ptrn), discvr_offset, + discvr_mask, sizeof(discvr_ptrn)); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to add WOW mDNS/SSDP/LLMNR pattern"); + return ret; + } + } + else + WMA_LOGD("mDNS, SSDP, LLMNR patterns are disabled from ini"); + + /* when arp offload or ns offloaded is disabled + * from ini file, configure broad cast arp pattern + * to fw, so that host can wake up + */ + if (!(wma->ol_ini_info & 0x1)) { + /* Setup all ARP pkt pattern */ + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, + wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++], + arp_ptrn, sizeof(arp_ptrn), arp_offset, + arp_mask, sizeof(arp_mask)); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to add WOW ARP pattern"); + return ret; + } + } + + /* for NS or NDP offload packets */ + if (!(wma->ol_ini_info & 0x2)) { + /* Setup all NS pkt pattern */ + ret = wma_send_wow_patterns_to_fw(wma, vdev_id, + wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++], + ns_ptrn, sizeof(arp_ptrn), arp_offset, + arp_mask, sizeof(arp_mask)); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to add WOW NS pattern"); + return ret; + } + + } + + *enable_ptrn_match = 1 << vdev_id; + return ret; +} + +/* Finds out list of unused slots in wow pattern cache. Those free slots number + * can be used as pattern ID while configuring default wow pattern. */ +static void wma_update_free_wow_ptrn_id(tp_wma_handle wma) +{ + struct wma_wow_ptrn_cache *cache; + u_int8_t ptrn_id; + + vos_mem_zero(wma->wow.free_ptrn_id, sizeof(wma->wow.free_ptrn_id)); + wma->wow.total_free_ptrn_id = 0; + wma->wow.used_free_ptrn_id = 0; + + for (ptrn_id = 0; ptrn_id < wma->wlan_resource_config.num_wow_filters; + ptrn_id++) { + cache = wma->wow.cache[ptrn_id]; + if (!cache) { + wma->wow.free_ptrn_id[wma->wow.total_free_ptrn_id] = + ptrn_id; + wma->wow.total_free_ptrn_id += 1; + + } + } + + WMA_LOGD("Total free wow pattern id for default patterns: %d", + wma->wow.total_free_ptrn_id ); +} + +/* Returns true if the user configured any wow pattern for given vdev id */ +static bool wma_is_wow_prtn_cached(tp_wma_handle wma, u_int8_t vdev_id) +{ + struct wma_wow_ptrn_cache *cache; + u_int8_t ptrn_id; + + for (ptrn_id = 0; ptrn_id < WOW_MAX_BITMAP_FILTERS; ptrn_id++) { + cache = wma->wow.cache[ptrn_id]; + if (!cache) + continue; + + if (cache->vdev_id == vdev_id) + return true; + } + + return false; +} + +/* Unpause all the vdev after resume */ +static void wma_unpause_vdev(tp_wma_handle wma) { + int8_t vdev_id; + struct wma_txrx_node *iface; + + for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { + if (!wma->interfaces[vdev_id].handle) + continue; + + #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + /* When host resume, by default, unpause all active vdev */ + if (wma->interfaces[vdev_id].pause_bitmap) { + wdi_in_vdev_unpause(wma->interfaces[vdev_id].handle, + 0xffffffff); + wma->interfaces[vdev_id].pause_bitmap = 0; + } + #endif /* QCA_SUPPORT_TXRX_VDEV_PAUSE_LL */ + + iface = &wma->interfaces[vdev_id]; + iface->conn_state = FALSE; + } +} + +static VOS_STATUS wma_resume_req(tp_wma_handle wma) +{ + VOS_STATUS ret = VOS_STATUS_SUCCESS; + u_int8_t ptrn_id; + + wma->no_of_resume_ind ++; + + if (wma->no_of_resume_ind < wma_get_vdev_count(wma)) + return VOS_STATUS_SUCCESS; + + wma->no_of_resume_ind = 0; + + WMA_LOGD("Clearing already configured wow patterns in fw"); + + /* Clear existing wow patterns in FW. */ + for (ptrn_id = 0; ptrn_id < wma->wlan_resource_config.num_wow_filters; + ptrn_id++) { + ret = wma_del_wow_pattern_in_fw(wma, ptrn_id); + if (ret != VOS_STATUS_SUCCESS) + goto end; + } + +end: + /* Reset the DTIM Parameters */ + wma_set_resume_dtim(wma); + /* need to reset if hif_pci_suspend_fails */ + wma_set_wow_bus_suspend(wma, 0); + /* unpause the vdev if left paused and hif_pci_suspend fails */ + wma_unpause_vdev(wma); + return ret; +} + +/* + * Pushes wow patterns from local cache to FW and configures + * wakeup trigger events. + */ +static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma, + v_BOOL_t pno_in_progress) +{ + struct wma_txrx_node *iface; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + u_int8_t vdev_id; + u_int8_t enable_ptrn_match = 0; + v_BOOL_t ap_vdev_available = FALSE; +#ifdef QCA_IBSS_SUPPORT + v_BOOL_t ibss_vdev_available = FALSE; +#endif + + /* Gather list of free ptrn id. This is needed while configuring + * default wow patterns. + */ + wma_update_free_wow_ptrn_id(wma); + + for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) { + iface = &wma->interfaces[vdev_id]; + + if (!iface->handle || + !iface->ptrn_match_enable || + (!(wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) && !iface->conn_state)) + continue; + + if (wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) + ap_vdev_available = TRUE; + +#ifdef QCA_IBSS_SUPPORT + if (wma_is_vdev_in_ibss_mode(wma, vdev_id)) + ibss_vdev_available = TRUE; +#endif + + if (wma_is_wow_prtn_cached(wma, vdev_id)) { + /* Configure wow patterns provided by the user */ + ret = wma_wow_usr(wma, vdev_id, &enable_ptrn_match); + } else if (wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + ||wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) + { + /* Configure AP mode default wow patterns */ + ret = wma_wow_ap(wma, vdev_id, &enable_ptrn_match); + } + else + { + /* Configure STA mode default wow patterns */ + ret = wma_wow_sta(wma, vdev_id, &enable_ptrn_match); + } + +#ifdef FEATURE_WLAN_RA_FILTERING + if ((ap_vdev_available == FALSE) && (wma->IsRArateLimitEnabled)) + { + ret = wma_wow_sta_ra_filter(wma, vdev_id); + + } + +#endif + if (ret != VOS_STATUS_SUCCESS) + goto end; + } + + /* + * Configure csa ie wakeup event. + */ + ret = wma_add_wow_wakeup_event(wma, WOW_CSA_IE_EVENT, TRUE); + + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure WOW_CSA_IE_EVENT"); + goto end; + } + else + WMA_LOGD("CSA IE match is enabled in fw"); + + /* + * Configure pattern match wakeup event. FW does pattern match + * only if pattern match event is enabled. + */ + ret = wma_add_wow_wakeup_event(wma, WOW_PATTERN_MATCH_EVENT, + enable_ptrn_match ? TRUE : FALSE); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to Configure WOW_PATTERN_MATCH_EVENT"); + goto end; + } else + WMA_LOGD("WOW_PATTERN_MATCH_EVENT enabled in fw"); + + WMA_LOGD("Pattern byte match is %s in fw", + enable_ptrn_match ? "enabled" : "disabled"); + + /* Configure magic pattern wakeup event */ + ret = wma_add_wow_wakeup_event(wma, WOW_MAGIC_PKT_RECVD_EVENT, + wma->wow.magic_ptrn_enable); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure magic pattern matching"); + goto end; + } else + WMA_LOGD("Magic pattern is %s in fw", + wma->wow.magic_ptrn_enable ? "enabled" : "disabled"); + + /* Configure deauth based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_DEAUTH_RECVD_EVENT, + wma->wow.deauth_enable); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure deauth based wakeup"); + goto end; + } else + WMA_LOGD("Deauth based wakeup is %s in fw", + wma->wow.deauth_enable ? "enabled" : "disabled"); + + /* Configure disassoc based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_DISASSOC_RECVD_EVENT, + wma->wow.disassoc_enable); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure disassoc based wakeup"); + goto end; + } else + WMA_LOGD("Disassoc based wakeup is %s in fw", + wma->wow.disassoc_enable ? "enabled" : "disabled"); + + /* Configure beacon miss based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_BMISS_EVENT, + wma->wow.bmiss_enable); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure beacon miss based wakeup"); + goto end; + } else + WMA_LOGD("Beacon miss based wakeup is %s in fw", + wma->wow.bmiss_enable ? "enabled" : "disabled"); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + /* Configure GTK based wakeup. Passing vdev_id 0 because + wma_add_wow_wakeup_event always uses vdev 0 for wow wake event id*/ + ret = wma_add_wow_wakeup_event(wma, WOW_GTK_ERR_EVENT, + wma->wow.gtk_pdev_enable); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure GTK based wakeup"); + goto end; + } else + WMA_LOGD("GTK based wakeup is %s in fw", + wma->wow.gtk_pdev_enable ? "enabled" : "disabled"); +#endif + /* Configure probe req based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_PROBE_REQ_WPS_IE_EVENT, + ap_vdev_available); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure probe req based wakeup"); + goto end; + } else + WMA_LOGD("Probe req based wakeup is %s in fw", + ap_vdev_available ? "enabled" : "disabled"); + + /* Configure auth req based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_AUTH_REQ_EVENT, + ap_vdev_available); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure auth req based wakeup"); + goto end; + } else + WMA_LOGD("Auth req based wakeup is %s in fw", + ap_vdev_available ? "enabled" : "disabled"); + + /* Configure assoc req based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_ASSOC_REQ_EVENT, + ap_vdev_available); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure assoc req based wakeup"); + goto end; + } else + WMA_LOGD("Assoc req based wakeup is %s in fw", + ap_vdev_available ? "enabled" : "disabled"); + + /* Configure pno based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_NLO_DETECTED_EVENT, + pno_in_progress); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure pno based wakeup"); + goto end; + } else + WMA_LOGD("PNO based wakeup is %s in fw", + pno_in_progress ? "enabled" : "disabled"); + + /* Configure roaming scan better AP based wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_BETTER_AP_EVENT, + TRUE); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure roaming scan better AP based wakeup"); + goto end; + } else + WMA_LOGD("Roaming scan better AP based wakeup is enabled in fw"); + + /* Configure ADDBA/DELBA wakeup */ + ret = wma_add_wow_wakeup_event(wma, WOW_HTT_EVENT, TRUE); + + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to Configure WOW_HTT_EVENT to FW"); + goto end; + } else + WMA_LOGD("Successfully Configured WOW_HTT_EVENT to FW"); + +#ifdef FEATURE_WLAN_RA_FILTERING + /* Configure RA filter wakeup */ + if (wma->IsRArateLimitEnabled) { + ret = wma_add_wow_wakeup_event(wma, WOW_RA_MATCH_EVENT, TRUE); + + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to Configure WOW_RA_MATCH_EVENT to FW"); + goto end; + } else + WMA_LOGD("Successfully Configured WOW_RA_MATCH_EVENT to FW"); + } else + WMA_LOGD("gRAFilterEnable is not set, RA filterning is disabled"); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + ret = wma_add_wow_wakeup_event(wma, WOW_HOST_AUTO_SHUTDOWN_EVENT, TRUE); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to Configure auto shutdown WOW event to FW"); + goto end; + } else + WMA_LOGE("Configure auto shutdown WOW event to FW: success"); +#endif + +#ifdef QCA_IBSS_SUPPORT + /* Configure beacon based wakeup */ + ret = wma_add_wow_wakeup_event(wma, + WOW_BEACON_EVENT,ibss_vdev_available); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to configure IBSS Beacon based wakeup"); + goto end; + } else { + WMA_LOGD("IBSS Beacon based wakeup is %s in fw", + ibss_vdev_available ? "enabled" : "disabled"); + } +#endif + + /* WOW is enabled in pcie suspend callback */ + wma->wow.wow_enable = TRUE; + wma->wow.wow_enable_cmd_sent = FALSE; + +end: + return ret; +} + +/* Adds received wow patterns in local wow pattern cache. */ +static VOS_STATUS wma_wow_add_pattern(tp_wma_handle wma, + tpSirWowlAddBcastPtrn ptrn) +{ + struct wma_wow_ptrn_cache *cache; + + WMA_LOGD("wow add pattern"); + + /* Free if there are any pattern cached already in the same slot. */ + if (wma->wow.cache[ptrn->ucPatternId]) + wma_free_wow_ptrn(wma, ptrn->ucPatternId); + + wma->wow.cache[ptrn->ucPatternId] = (struct wma_wow_ptrn_cache *) + vos_mem_malloc(sizeof(*cache)); + + cache = wma->wow.cache[ptrn->ucPatternId]; + if (!cache) { + WMA_LOGE("Unable to alloc memory for wow"); + return VOS_STATUS_E_NOMEM; + } + + cache->ptrn = (u_int8_t *) vos_mem_malloc(ptrn->ucPatternSize); + if (!cache->ptrn) { + WMA_LOGE("Unable to alloce memory to cache wow pattern"); + vos_mem_free(cache); + wma->wow.cache[ptrn->ucPatternId] = NULL; + return VOS_STATUS_E_NOMEM; + } + + cache->mask = (u_int8_t *) vos_mem_malloc(ptrn->ucPatternMaskSize); + if (!cache->mask) { + WMA_LOGE("Unable to alloc memory to cache wow ptrn mask"); + vos_mem_free(cache->ptrn); + vos_mem_free(cache); + wma->wow.cache[ptrn->ucPatternId] = NULL; + return VOS_STATUS_E_NOMEM; + } + + /* Cache wow pattern info until platform goes to suspend. */ + + cache->vdev_id = ptrn->sessionId; + cache->ptrn_len = ptrn->ucPatternSize; + cache->ptrn_offset = ptrn->ucPatternByteOffset; + cache->mask_len = ptrn->ucPatternMaskSize; + + vos_mem_copy(cache->ptrn, ptrn->ucPattern, cache->ptrn_len); + vos_mem_copy(cache->mask, ptrn->ucPatternMask, cache->mask_len); + wma->wow.no_of_ptrn_cached++; + + WMA_LOGD("wow pattern stored in cache (slot_id: %d, vdev id: %d)", + ptrn->ucPatternId, cache->vdev_id); + return VOS_STATUS_SUCCESS; +} + +/* Deletes given pattern from local wow pattern cache. */ +static VOS_STATUS wma_wow_del_pattern(tp_wma_handle wma, + tpSirWowlDelBcastPtrn ptrn) +{ + WMA_LOGD("wow delete pattern"); + + if (!wma->wow.cache[ptrn->ucPatternId]) { + WMA_LOGE("wow pattern not found (pattern id: %d) in cache", + ptrn->ucPatternId); + return VOS_STATUS_E_INVAL; + } + + wma_free_wow_ptrn(wma, ptrn->ucPatternId); + + return VOS_STATUS_SUCCESS; +} + +/* + * Records pattern enable/disable status locally. This choice will + * take effect when the driver enter into suspend state. + */ +static VOS_STATUS wma_wow_enter(tp_wma_handle wma, + tpSirHalWowlEnterParams info) +{ + struct wma_txrx_node *iface; + + WMA_LOGD("wow enable req received for vdev id: %d", info->sessionId); + + if (info->sessionId > wma->max_bssid) { + WMA_LOGE("Invalid vdev id (%d)", info->sessionId); + vos_mem_free(info); + return VOS_STATUS_E_INVAL; + } + + iface = &wma->interfaces[info->sessionId]; + iface->ptrn_match_enable = info->ucPatternFilteringEnable ? + TRUE : FALSE; + wma->wow.magic_ptrn_enable = info->ucMagicPktEnable ? TRUE : FALSE; + wma->wow.deauth_enable = info->ucWowDeauthRcv ? TRUE : FALSE; + wma->wow.disassoc_enable = info->ucWowDeauthRcv ? TRUE : FALSE; + wma->wow.bmiss_enable = info->ucWowMaxMissedBeacons ? TRUE : FALSE; + + vos_mem_free(info); + + return VOS_STATUS_SUCCESS; +} + +/* Clears all wow states */ +static VOS_STATUS wma_wow_exit(tp_wma_handle wma, + tpSirHalWowlExitParams info) +{ + struct wma_txrx_node *iface; + + WMA_LOGD("wow disable req received for vdev id: %d", info->sessionId); + + if (info->sessionId > wma->max_bssid) { + WMA_LOGE("Invalid vdev id (%d)", info->sessionId); + vos_mem_free(info); + return VOS_STATUS_E_INVAL; + } + + iface = &wma->interfaces[info->sessionId]; + iface->ptrn_match_enable = FALSE; + wma->wow.magic_ptrn_enable = FALSE; + vos_mem_free(info); + + return VOS_STATUS_SUCCESS; +} + +/* Handles suspend indication request received from umac. */ +static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info) +{ + struct wma_txrx_node *iface; + v_BOOL_t connected = FALSE, pno_in_progress = FALSE; + VOS_STATUS ret; + u_int8_t i; + + wma->no_of_suspend_ind++; + + if (info->sessionId > wma->max_bssid) { + WMA_LOGE("Invalid vdev id (%d)", info->sessionId); + vos_mem_free(info); + return VOS_STATUS_E_INVAL; + } + + iface = &wma->interfaces[info->sessionId]; + if (!iface) { + WMA_LOGD("vdev %d node is not found", info->sessionId); + vos_mem_free(info); + return VOS_STATUS_SUCCESS; + } + + if (!wma->wow.magic_ptrn_enable && !iface->ptrn_match_enable) { + vos_mem_free(info); + + if (wma->no_of_suspend_ind == wma_get_vdev_count(wma)) { + WMA_LOGD("Both magic and pattern byte match are disabled"); + wma->no_of_suspend_ind = 0; + goto send_ready_to_suspend; + } + + return VOS_STATUS_SUCCESS; + } + + iface->conn_state = (info->connectedState) ? TRUE : FALSE; + + /* + * Once WOW is enabled in FW, host can't send anymore + * data to fw. umac sends suspend indication on each + * vdev during platform suspend. WMA has to wait until + * suspend indication received on last vdev before + * enabling wow in fw. + */ + if (wma->no_of_suspend_ind < wma_get_vdev_count(wma)) { + vos_mem_free(info); + return VOS_STATUS_SUCCESS; + } + + wma->no_of_suspend_ind = 0; + wma->wow.gtk_pdev_enable = 0; + /* + * Enable WOW if any one of the condition meets, + * 1) Is any one of vdev in beaconning mode (in AP mode) ? + * 2) Is any one of vdev in connected state (in STA mode) ? + * 3) Is PNO in progress in any one of vdev ? + */ + for (i = 0; i < wma->max_bssid; i++) { + if ( (wma_is_vdev_in_ap_mode(wma, i) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, i) +#endif + ) && wma->interfaces[i].vdev_up && + WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_BEACON_OFFLOAD)) { + WMA_LOGD("vdev %d is in beaconning mode, enabling wow", + i); + goto enable_wow; + } + } + for (i = 0; i < wma->max_bssid; i++) { + if (wma->interfaces[i].conn_state) { + connected = TRUE; + break; + } +#ifdef FEATURE_WLAN_SCAN_PNO + if (wma->interfaces[i].pno_in_progress) { + WMA_LOGD("PNO is in progress, enabling wow"); + pno_in_progress = TRUE; + break; + } +#endif + } + for (i = 0; i < wma->max_bssid; i++) { + wma->wow.gtk_pdev_enable |= wma->wow.gtk_err_enable[i]; + WMA_LOGD("VDEV_ID:%d, gtk_err_enable[%d]:%d, gtk_pdev_enable:%d", + i, i, wma->wow.gtk_err_enable[i], + wma->wow.gtk_pdev_enable); + } + + if (!connected && !pno_in_progress) { + WMA_LOGD("All vdev are in disconnected state, skipping wow"); + vos_mem_free(info); + goto send_ready_to_suspend; + } + +enable_wow: + WMA_LOGD("WOW Suspend"); + + /* + * At this point, suspend indication is received on + * last vdev. It's the time to enable wow in fw. + */ +#ifdef FEATURE_WLAN_LPHB + /* LPHB cache, if any item was enabled, should be + * applied. + */ + WMA_LOGD("%s: checking LPHB cache", __func__); + for (i = 0; i < 2; i++) { + if (wma->wow.lphb_cache[i].params.lphbEnableReq.enable) { + WMA_LOGD("%s: LPHB cache for item %d is marked as enable", + __func__, i + 1); + wma_lphb_conf_hbenable( + wma, + &(wma->wow.lphb_cache[i]), + FALSE); + } + } +#endif + + ret = wma_feed_wow_config_to_fw(wma, pno_in_progress); + if (ret != VOS_STATUS_SUCCESS) { + vos_mem_free(info); + wma_send_status_to_suspend_ind(wma, FALSE); + return ret; + } + vos_mem_free(info); + +send_ready_to_suspend: + /* Set the Suspend DTIM Parameters */ + wma_set_suspend_dtim(wma); + wma_send_status_to_suspend_ind(wma, TRUE); + + /* to handle race between hif_pci_suspend and + * unpause/pause tx handler + */ + wma_set_wow_bus_suspend(wma, 1); + + return VOS_STATUS_SUCCESS; +} + +/* + * Sends host wakeup indication to FW. On receiving this indication, + * FW will come out of WOW. + */ +static VOS_STATUS wma_send_host_wakeup_ind_to_fw(tp_wma_handle wma) +{ + wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *cmd; + wmi_buf_t buf; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int32_t len; + int ret; +#ifdef CONFIG_CNSS + tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + if (NULL == pMac) { + WMA_LOGE("%s: Unable to get PE context", __func__); + return VOS_STATUS_E_FAILURE; + } +#endif + + len = sizeof(wmi_wow_hostwakeup_from_sleep_cmd_fixed_param); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_wow_hostwakeup_from_sleep_cmd_fixed_param *) + wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_wow_hostwakeup_from_sleep_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_wow_hostwakeup_from_sleep_cmd_fixed_param)); + + vos_event_reset(&wma->wma_resume_event); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); + if (ret) { + WMA_LOGE("Failed to send host wakeup indication to fw"); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Host wakeup indication sent to fw"); + + vos_status = vos_wait_single_event(&(wma->wma_resume_event), + WMA_RESUME_TIMEOUT); + if (VOS_STATUS_SUCCESS != vos_status) { + WMA_LOGP("%s: Timeout waiting for resume event from FW", __func__); + WMA_LOGP("%s: Pending commands %d credits %d", __func__, + wmi_get_pending_cmds(wma->wmi_handle), + wmi_get_host_credits(wma->wmi_handle)); + if (!vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) { +#ifdef CONFIG_CNSS + if (pMac->sme.enableSelfRecovery) { + vos_trigger_recovery(); + } else { + VOS_BUG(0); + } +#else + VOS_BUG(0); +#endif + } else { + WMA_LOGE("%s: SSR in progress, ignore resume timeout", __func__); + } + } else { + WMA_LOGD("Host wakeup received"); + } + + if (VOS_STATUS_SUCCESS == vos_status) + wmi_set_target_suspend(wma->wmi_handle, FALSE); + + return vos_status; +} + +#ifdef FEATURE_WLAN_D0WOW +/* Disable D0-WOW in firmware. */ +VOS_STATUS wma_disable_d0wow_in_fw(tp_wma_handle wma) +{ + wmi_d0_wow_enable_disable_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len; + int host_credits; + int wmi_pending_cmds; + int ret = 0; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + len = sizeof(wmi_d0_wow_enable_disable_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed to allocate WMI buffer!", __func__); + return VOS_STATUS_E_NOMEM; + } + + cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_d0_wow_enable_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_d0_wow_enable_disable_cmd_fixed_param)); + cmd->enable = 0; + + host_credits = wmi_get_host_credits(wma->wmi_handle); + wmi_pending_cmds = wmi_get_pending_cmds(wma->wmi_handle); + if (host_credits < WMI_WOW_REQUIRED_CREDITS) { + WMA_LOGE("%s: No Credits when resume: %d, pending_cmds: %d, " + "cannot resume back", __func__, host_credits, + wmi_pending_cmds); + HTC_dump_counter_info(wma->htc_handle); + VOS_BUG(0); + } + + vos_event_reset(&wma->wma_resume_event); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_D0_WOW_ENABLE_DISABLE_CMDID); + if (ret) { + WMA_LOGE("Failed to disable D0-WOW in FW!"); + goto error; + } + + vos_status = vos_wait_single_event(&(wma->wma_resume_event), + WMA_RESUME_TIMEOUT); + if (VOS_STATUS_SUCCESS != vos_status) { + WMA_LOGP("%s: Timeout waiting for resume event from FW!", + __func__); + WMA_LOGP("%s: Pending commands: %d credits: %d", __func__, + wmi_get_pending_cmds(wma->wmi_handle), + wmi_get_host_credits(wma->wmi_handle)); + VOS_BUG(0); + } + + wma->wow.wow_enable = FALSE; + wma->wow.wow_enable_cmd_sent = FALSE; + wmi_set_d0wow_flag(wma->wmi_handle, FALSE); + WMA_LOGD("D0-WOW is disabled successfully in FW."); + return vos_status; + +error: + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; +} +#endif /* FEATURE_WLAN_D0WOW */ + +/* Disable wow in PCIe resume context. */ +int wma_disable_wow_in_fw(WMA_HANDLE handle) +{ + tp_wma_handle wma = handle; + VOS_STATUS ret; + + if(!wma->wow.wow_enable || !wma->wow.wow_enable_cmd_sent) { + return VOS_STATUS_SUCCESS; + } + + WMA_LOGD("WoW Resume in PCIe Context\n"); + +#ifdef FEATURE_WLAN_D0WOW + if (wma->ap_client_cnt > 0) { + WMA_LOGD("Exiting D0-WOW since client count is %d.", + wma->ap_client_cnt); + return wma_disable_d0wow_in_fw(wma); + } +#endif + + ret = wma_send_host_wakeup_ind_to_fw(wma); + + if (ret != VOS_STATUS_SUCCESS) + return ret; + + wma->wow.wow_enable = FALSE; + wma->wow.wow_enable_cmd_sent = FALSE; + + /* To allow the tx pause/unpause events */ + wma_set_wow_bus_suspend(wma, 0); + /* Unpause the vdev as we are resuming */ + wma_unpause_vdev(wma); + + return ret; +} + +/* + * Returns true if wow parameters (patterns, wakeup events, etc) + * are configured in fw and waiting for wow to be enabled in fw. + * Other cases, returns false. + */ +int wma_is_wow_mode_selected(WMA_HANDLE handle) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + + return wma->wow.wow_enable; +} + +tAniGetPEStatsRsp * wma_get_stats_rsp_buf(tAniGetPEStatsReq *get_stats_param) +{ + tAniGetPEStatsRsp *stats_rsp_params; + tANI_U32 len, temp_mask, counter = 0; + + len= sizeof(tAniGetPEStatsRsp); + temp_mask = get_stats_param->statsMask; + + while (temp_mask) { + if (temp_mask & 1) { + switch (counter) { + case eCsrSummaryStats: + len += sizeof(tCsrSummaryStatsInfo); + break; + case eCsrGlobalClassAStats: + len += sizeof(tCsrGlobalClassAStatsInfo); + break; + case eCsrGlobalClassBStats: + len += sizeof(tCsrGlobalClassBStatsInfo); + break; + case eCsrGlobalClassCStats: + len += sizeof(tCsrGlobalClassCStatsInfo); + break; + case eCsrGlobalClassDStats: + len += sizeof(tCsrGlobalClassDStatsInfo); + break; + case eCsrPerStaStats: + len += sizeof(tCsrPerStaStatsInfo); + break; + } + } + + counter++; + temp_mask >>= 1; + } + + stats_rsp_params = (tAniGetPEStatsRsp *)vos_mem_malloc(len); + if (!stats_rsp_params) { + WMA_LOGE("memory allocation failed for tAniGetPEStatsRsp"); + VOS_ASSERT(0); + return NULL; + } + + vos_mem_zero(stats_rsp_params, len); + stats_rsp_params->staId = get_stats_param->staId; + stats_rsp_params->statsMask = get_stats_param->statsMask; + stats_rsp_params->msgType = WDA_GET_STATISTICS_RSP; + stats_rsp_params->msgLen = len - sizeof(tAniGetPEStatsRsp); + stats_rsp_params->rc = eHAL_STATUS_SUCCESS; + return stats_rsp_params; +} + +/* function : wma_get_stats_req + * Description : return the statistics + * Args : wma handle, pointer to tAniGetPEStatsReq + * Returns : nothing + */ +static void wma_get_stats_req(WMA_HANDLE handle, + tAniGetPEStatsReq *get_stats_param) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + struct wma_txrx_node *node; + wmi_buf_t buf; + wmi_request_stats_cmd_fixed_param *cmd; + tAniGetPEStatsRsp *pGetPEStatsRspParams; + u_int8_t len = sizeof(wmi_request_stats_cmd_fixed_param); + + WMA_LOGD("%s: Enter", __func__); + node = &wma_handle->interfaces[get_stats_param->sessionId]; + if (node->stats_rsp) { + pGetPEStatsRspParams = node->stats_rsp; + if (pGetPEStatsRspParams->staId == get_stats_param->staId && + pGetPEStatsRspParams->statsMask == + get_stats_param->statsMask) { + WMA_LOGI("Stats for staId %d with stats mask %d " + "is pending.... ignore new request", + get_stats_param->staId, + get_stats_param->statsMask); + goto end; + } else { + vos_mem_free(node->stats_rsp); + node->stats_rsp = NULL; + node->fw_stats_set = 0; + } + } + + pGetPEStatsRspParams = wma_get_stats_rsp_buf(get_stats_param); + if (!pGetPEStatsRspParams) + goto end; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: Failed to allocate wmi buffer", __func__); + goto failed; + } + + node->fw_stats_set = 0; + node->stats_rsp = pGetPEStatsRspParams; + cmd = (wmi_request_stats_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param)); + cmd->stats_id = WMI_REQUEST_PEER_STAT|WMI_REQUEST_PDEV_STAT| + WMI_REQUEST_VDEV_STAT; + cmd->vdev_id = get_stats_param->sessionId; + WMI_CHAR_ARRAY_TO_MAC_ADDR(node->bssid, &cmd->peer_macaddr); + WMA_LOGD("STATS REQ VDEV_ID:%d-->", cmd->vdev_id); + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_REQUEST_STATS_CMDID)) { + + WMA_LOGE("%s: Failed to send WMI_REQUEST_STATS_CMDID", + __func__); + wmi_buf_free(buf); + goto failed; + } + + goto end; +failed: + + pGetPEStatsRspParams->rc = eHAL_STATUS_FAILURE; + node->stats_rsp = NULL; + /* send response to UMAC*/ + wma_send_msg(wma_handle, WDA_GET_STATISTICS_RSP, pGetPEStatsRspParams, + 0) ; +end: + vos_mem_free(get_stats_param); + WMA_LOGD("%s: Exit", __func__); + return; +} + +static void wma_init_scan_req(tp_wma_handle wma_handle, + tInitScanParams *init_scan_param) +{ + WMA_LOGD("%s: Send dummy init scan response for legacy scan request", + __func__); + init_scan_param->status = eHAL_STATUS_SUCCESS; + /* send ini scan response message back to PE */ + wma_send_msg(wma_handle, WDA_INIT_SCAN_RSP, (void *)init_scan_param, + 0); +} + +static void wma_finish_scan_req(tp_wma_handle wma_handle, + tFinishScanParams *finish_scan_param) +{ + WMA_LOGD("%s: Send dummy finish scan response for legacy scan request", + __func__); + finish_scan_param->status = eHAL_STATUS_SUCCESS; + /* send finish scan response message back to PE */ + wma_send_msg(wma_handle, WDA_FINISH_SCAN_RSP, (void *)finish_scan_param, + 0); +} + +static void wma_process_update_opmode(tp_wma_handle wma_handle, + tUpdateVHTOpMode *update_vht_opmode) +{ + WMA_LOGD("%s: opMode = %d", __func__, update_vht_opmode->opMode); + + wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac, + WMI_PEER_CHWIDTH, update_vht_opmode->opMode, + update_vht_opmode->smesessionId); +} + +static void wma_process_update_rx_nss(tp_wma_handle wma_handle, + tUpdateRxNss *update_rx_nss) +{ + struct wma_txrx_node *intr = + &wma_handle->interfaces[update_rx_nss->smesessionId]; + int rxNss = update_rx_nss->rxNss; + + wma_update_txrx_chainmask(wma_handle->num_rf_chains, &rxNss); + intr->nss = (tANI_U8) rxNss; + update_rx_nss->rxNss = (tANI_U32) rxNss; + + WMA_LOGD("%s: Rx Nss = %d", __func__, update_rx_nss->rxNss); + + wma_set_peer_param(wma_handle, update_rx_nss->peer_mac, + WMI_PEER_NSS, update_rx_nss->rxNss, + update_rx_nss->smesessionId); +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +static void wma_start_oem_data_req(tp_wma_handle wma_handle, + tStartOemDataReq *startOemDataReq) +{ + wmi_buf_t buf; + u_int8_t *cmd; + int ret = 0; + u_int32_t *msg_subtype; + tStartOemDataRsp *pStartOemDataRsp; + + WMA_LOGD("%s: Send OEM Data Request to target", __func__); + + if (!startOemDataReq) { + WMA_LOGE("%s: startOemDataReq is null", __func__); + goto out; + } + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not send Oem data request cmd", __func__); + return; + } + + buf = wmi_buf_alloc(wma_handle->wmi_handle, + (OEM_DATA_REQ_SIZE + WMI_TLV_HDR_SIZE)); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + goto out; + } + + cmd = (u_int8_t *)wmi_buf_data(buf); + + WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, + OEM_DATA_REQ_SIZE); + cmd += WMI_TLV_HDR_SIZE; + vos_mem_copy(cmd, &startOemDataReq->oemDataReq[0], OEM_DATA_REQ_SIZE); + + WMA_LOGI("%s: Sending OEM Data Request to target, data len (%d)", + __func__, OEM_DATA_REQ_SIZE); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + (OEM_DATA_REQ_SIZE + + WMI_TLV_HDR_SIZE), + WMI_OEM_REQ_CMDID); + + if (ret != EOK) { + WMA_LOGE("%s:wmi cmd send failed", __func__); + adf_nbuf_free(buf); + } + +out: + /* free oem data req buffer received from UMAC */ + if (startOemDataReq) + vos_mem_free(startOemDataReq); + + /* Now send data resp back to PE/SME with message sub-type of + * WMI_OEM_INTERNAL_RSP. This is required so that PE/SME clears + * up pending active command. Later when desired oem response(s) + * comes as wmi event from target then those shall be passed + * to oem application + */ + pStartOemDataRsp = vos_mem_malloc(sizeof(*pStartOemDataRsp)); + if (!pStartOemDataRsp) + { + WMA_LOGE("%s:failed to allocate memory for OEM Data Resp to PE", + __func__); + return; + } + vos_mem_zero(pStartOemDataRsp, sizeof(tStartOemDataRsp)); + msg_subtype = (u_int32_t *)(&pStartOemDataRsp->oemDataRsp[0]); + *msg_subtype = WMI_OEM_INTERNAL_RSP; + + WMA_LOGI("%s: Sending WDA_START_OEM_DATA_RSP to clear up PE/SME pending cmd", + __func__); + + wma_send_msg(wma_handle, WDA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0); + + return; +} +#endif /* FEATURE_OEM_DATA_SUPPORT */ + +#ifdef FEATURE_WLAN_ESE + +#define TSM_DELAY_HISTROGRAM_BINS 4 +/* + * @brief: A parallel function to WDA_ProcessTsmStatsReq for pronto. This + * function fetches stats from data path APIs and post + * WDA_TSM_STATS_RSP msg back to LIM. + * @param: wma_handler - handle to wma + * @param: pTsmStatsMsg - TSM stats struct that needs to be populated and + * passed in message. + */ +VOS_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler, + void *pTsmStatsMsg) +{ + u_int8_t counter; + u_int32_t queue_delay_microsec = 0; + u_int32_t tx_delay_microsec = 0; + u_int16_t packet_count = 0; + u_int16_t packet_loss_count = 0; + tpAniTrafStrmMetrics pTsmMetric = NULL; +#ifdef FEATURE_WLAN_ESE_UPLOAD + tpAniGetTsmStatsReq pStats = (tpAniGetTsmStatsReq)pTsmStatsMsg; + tpAniGetTsmStatsRsp pTsmRspParams = NULL; +#else + tpTSMStats pStats = (tpTSMStats)pTsmStatsMsg; +#endif + int tid = pStats->tid; + /* + * The number of histrogram bin report by data path api are different + * than required by TSM, hence different (6) size array used + */ + u_int16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = {0,}; + + ol_txrx_pdev_handle pdev = vos_get_context(VOS_MODULE_ID_TXRX, + wma_handler->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + vos_mem_free(pTsmStatsMsg); + return VOS_STATUS_E_INVAL; + } + + /* get required values from data path APIs */ + ol_tx_delay(pdev, &queue_delay_microsec, &tx_delay_microsec, tid); + ol_tx_delay_hist(pdev, bin_values, tid); + ol_tx_packet_count(pdev, &packet_count, &packet_loss_count, tid ); + +#ifdef FEATURE_WLAN_ESE_UPLOAD + pTsmRspParams = + (tpAniGetTsmStatsRsp)vos_mem_malloc(sizeof(tAniGetTsmStatsRsp)); + if(NULL == pTsmRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pTsmStatsMsg); + return VOS_STATUS_E_NOMEM; + } + pTsmRspParams->staId = pStats->staId; + pTsmRspParams->rc = eSIR_FAILURE; + pTsmRspParams->tsmStatsReq = pStats; + pTsmMetric = &pTsmRspParams->tsmMetrics; +#else + pTsmMetric = (tpAniTrafStrmMetrics)&pStats->tsmMetrics; +#endif + /* populate pTsmMetric */ + pTsmMetric->UplinkPktQueueDly = queue_delay_microsec; + /* store only required number of bin values */ + for ( counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++) + { + pTsmMetric->UplinkPktQueueDlyHist[counter] = bin_values[counter]; + } + pTsmMetric->UplinkPktTxDly = tx_delay_microsec; + pTsmMetric->UplinkPktLoss = packet_loss_count; + pTsmMetric->UplinkPktCount = packet_count; + + /* + * No need to populate roaming delay and roaming count as they are + * being populated just before sending IAPP frame out + */ + /* post this message to LIM/PE */ +#ifdef FEATURE_WLAN_ESE_UPLOAD + wma_send_msg(wma_handler, WDA_TSM_STATS_RSP, (void *)pTsmRspParams , 0) ; +#else + wma_send_msg(wma_handler, WDA_TSM_STATS_RSP, (void *)pTsmStatsMsg , 0) ; +#endif + return VOS_STATUS_SUCCESS; +} + +#endif /* FEATURE_WLAN_ESE */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void wma_set_ric_req(tp_wma_handle wma, void *msg, tANI_U8 is_add_ts) +{ + wmi_ric_request_fixed_param *cmd; + wmi_ric_tspec *tspec_param; + wmi_buf_t buf; + u_int8_t *buf_ptr; + tSirMacTspecIE *ptspecIE; + int32_t len = sizeof(wmi_ric_request_fixed_param)+ + WMI_TLV_HDR_SIZE + + sizeof(wmi_ric_tspec); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return; + } + + buf_ptr = (u_int8_t *)wmi_buf_data(buf); + + cmd = (wmi_ric_request_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ric_request_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_ric_request_fixed_param)); + if (is_add_ts) + cmd->vdev_id = ((tAddTsParams *)msg)->sessionId; + else + cmd->vdev_id = ((tDelTsParams *)msg)->sessionId; + cmd->num_ric_request = 1; /* Today we are sending only 1 ric at once */ + cmd->is_add_ric = is_add_ts; + + buf_ptr += sizeof(wmi_ric_request_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_ric_tspec)); + + buf_ptr += WMI_TLV_HDR_SIZE; + tspec_param = (wmi_ric_tspec *)buf_ptr; + WMITLV_SET_HDR(&tspec_param->tlv_header, + WMITLV_TAG_STRUC_wmi_ric_tspec, + WMITLV_GET_STRUCT_TLVLEN(wmi_ric_tspec)); + + if(is_add_ts) + ptspecIE = &(((tAddTsParams *)msg)->tspec); + else + ptspecIE = &(((tDelTsParams *)msg)->delTsInfo.tspec); + + /* Fill the tsinfo in the format expected by firmware */ +#ifndef ANI_LITTLE_BIT_ENDIAN + vos_mem_copy(((tANI_U8 *)&tspec_param->ts_info)+1, + ((tANI_U8 *)&ptspecIE->tsinfo)+1, 2); +#else + vos_mem_copy(((tANI_U8 *)&tspec_param->ts_info), + ((tANI_U8 *)&ptspecIE->tsinfo)+1, 2); +#endif + + tspec_param->nominal_msdu_size = ptspecIE->nomMsduSz; + tspec_param->maximum_msdu_size = ptspecIE->maxMsduSz; + tspec_param->min_service_interval = ptspecIE->minSvcInterval; + tspec_param->max_service_interval = ptspecIE->maxSvcInterval; + tspec_param->inactivity_interval = ptspecIE->inactInterval; + tspec_param->suspension_interval = ptspecIE->suspendInterval; + tspec_param->svc_start_time = ptspecIE->svcStartTime; + tspec_param->min_data_rate = ptspecIE->minDataRate; + tspec_param->mean_data_rate = ptspecIE->meanDataRate; + tspec_param->peak_data_rate = ptspecIE->peakDataRate; + tspec_param->max_burst_size = ptspecIE->maxBurstSz; + tspec_param->delay_bound = ptspecIE->delayBound; + tspec_param->min_phy_rate = ptspecIE->minPhyRate; + tspec_param->surplus_bw_allowance = ptspecIE->surplusBw; + tspec_param->medium_time = 0; + + WMA_LOGI("%s: Set RIC Req is_add_ts:%d", __func__, is_add_ts); + + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_ROAM_SET_RIC_REQUEST_CMDID)) { + WMA_LOGP("%s: Failed to send vdev Set RIC Req command", __func__); + if(is_add_ts) + ((tAddTsParams *)msg)->status = eHAL_STATUS_FAILURE; + adf_nbuf_free(buf); + } +} +#endif + +static void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg) +{ + wmi_vdev_wmm_delts_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + goto err; + } + cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_wmm_delts_cmd_fixed_param)); + cmd->vdev_id = msg->sessionId; + cmd->ac = TID_TO_WME_AC(msg->userPrio); + + WMA_LOGD("Delts vdev:%d, ac:%d, %s:%d", + cmd->vdev_id, cmd->ac, __FUNCTION__, __LINE__); + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_WMM_DELTS_CMDID)) { + WMA_LOGP("%s: Failed to send vdev DELTS command", __func__); + adf_nbuf_free(buf); + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(msg->setRICparams == true) + wma_set_ric_req(wma, msg, false); +#endif + +err: + vos_mem_free(msg); +} + +/* + * @brief: A function to handle WDA_AGGR_QOS_REQ. This will send out + * ADD_TS requestes to firmware in loop for all the ACs with + * active flow. + * @param: wma_handler - handle to wma + * @param: pAggrQosRspMsg - combined struct for all ADD_TS requests. + */ +static void wma_aggr_qos_req(tp_wma_handle wma, tAggrAddTsParams *pAggrQosRspMsg) +{ + int i = 0; + wmi_vdev_wmm_addts_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + // if flow in this AC is active + if ( ((1 << i) & pAggrQosRspMsg->tspecIdx) ) + { + /* + * as per implementation of wma_add_ts_req() we + * are not waiting any response from firmware so + * apart from sending ADDTS to firmware just send + * success to upper layers + */ + pAggrQosRspMsg->status[i] = eHAL_STATUS_SUCCESS; + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + goto aggr_qos_exit; + } + cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_wmm_addts_cmd_fixed_param)); + cmd->vdev_id = pAggrQosRspMsg->sessionId; + cmd->ac = TID_TO_WME_AC(pAggrQosRspMsg->tspec[i].tsinfo.traffic.userPrio); + cmd->medium_time_us = pAggrQosRspMsg->tspec[i].mediumTime * 32; + cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO; + WMA_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d", + __func__, __LINE__, cmd->vdev_id, cmd->ac, + cmd->medium_time_us, cmd->downgrade_type); + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_WMM_ADDTS_CMDID)) { + WMA_LOGP("%s: Failed to send vdev ADDTS command", __func__); + pAggrQosRspMsg->status[i] = eHAL_STATUS_FAILURE; + adf_nbuf_free(buf); + } + } + } + +aggr_qos_exit: + // send reponse to upper layers from here only. + wma_send_msg(wma, WDA_AGGR_QOS_RSP, pAggrQosRspMsg, 0); +} + +static void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg) +{ + wmi_vdev_wmm_addts_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t len = sizeof(*cmd); + +#ifdef FEATURE_WLAN_ESE + /* + * msmt_interval is in unit called TU (1 TU = 1024 us) + * max value of msmt_interval cannot make resulting + * interval_miliseconds overflow 32 bit + */ + tANI_U32 intervalMiliseconds; + ol_txrx_pdev_handle pdev = + vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + goto err; + } + + intervalMiliseconds = (msg->tsm_interval*1024)/1000; + + ol_tx_set_compute_interval(pdev, intervalMiliseconds); +#endif + msg->status = eHAL_STATUS_SUCCESS; + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + goto err; + } + cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_wmm_addts_cmd_fixed_param)); + cmd->vdev_id = msg->sme_session_id; + cmd->ac = TID_TO_WME_AC(msg->tspec.tsinfo.traffic.userPrio); + cmd->medium_time_us = msg->tspec.mediumTime * 32; + cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP; + WMA_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d", + cmd->vdev_id, cmd->ac, cmd->medium_time_us, + cmd->downgrade_type, __func__, __LINE__); + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_VDEV_WMM_ADDTS_CMDID)) { + WMA_LOGP("%s: Failed to send vdev ADDTS command", __func__); + msg->status = eHAL_STATUS_FAILURE; + adf_nbuf_free(buf); + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(msg->setRICparams == true) + wma_set_ric_req(wma, msg, true); +#endif + +err: + wma_send_msg(wma, WDA_ADD_TS_RSP, msg, 0); +} + +static int wma_process_receive_filter_set_filter_req(tp_wma_handle wma_handle, + tSirRcvPktFilterCfgType *rcv_filter_param) +{ + wmi_chatter_coalescing_add_filter_cmd_fixed_param *cmd; + chatter_pkt_coalescing_filter *cmd_filter; + u_int8_t *buf_ptr; + wmi_buf_t buf; + int num_rules = 1; /* Only one rule at a time */ + int len; + int err; + int i; + + /* allocate the memory */ + len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*cmd_filter) * num_rules; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_param cmd"); + vos_mem_free(rcv_filter_param); + return -ENOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + + /* fill the fixed part */ + cmd = (wmi_chatter_coalescing_add_filter_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_chatter_coalescing_add_filter_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_chatter_coalescing_add_filter_cmd_fixed_param)); + cmd->num_of_filters = num_rules; + + /* specify the type of data in the subsequent buffer */ + buf_ptr += sizeof(*cmd); + cmd_filter = (chatter_pkt_coalescing_filter *) buf_ptr; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + num_rules * sizeof(chatter_pkt_coalescing_filter)); + + /* fill the actual filter data */ + buf_ptr += WMI_TLV_HDR_SIZE; + cmd_filter = (chatter_pkt_coalescing_filter *) buf_ptr; + + WMITLV_SET_HDR(&cmd_filter->tlv_header, + WMITLV_TAG_STRUC_wmi_chatter_pkt_coalescing_filter, + WMITLV_GET_STRUCT_TLVLEN(chatter_pkt_coalescing_filter)); + + cmd_filter->filter_id = rcv_filter_param->filterId; + cmd_filter->max_coalescing_delay = rcv_filter_param->coalesceTime; + cmd_filter->pkt_type = CHATTER_COALESCING_PKT_TYPE_UNICAST | + CHATTER_COALESCING_PKT_TYPE_MULTICAST | + CHATTER_COALESCING_PKT_TYPE_BROADCAST; + cmd_filter->num_of_test_field = MIN(rcv_filter_param->numFieldParams, + CHATTER_MAX_FIELD_TEST); + + for (i = 0; i < cmd_filter->num_of_test_field; i++) { + cmd_filter->test_fields[i].offset = rcv_filter_param->paramsData[i].dataOffset; + cmd_filter->test_fields[i].length = MIN(rcv_filter_param->paramsData[i].dataLength, + CHATTER_MAX_TEST_FIELD_LEN32); + cmd_filter->test_fields[i].test = rcv_filter_param->paramsData[i].cmpFlag; + memcpy(&cmd_filter->test_fields[i].value, rcv_filter_param->paramsData[i].compareData, + cmd_filter->test_fields[i].length); + memcpy(&cmd_filter->test_fields[i].mask, rcv_filter_param->paramsData[i].dataMask, + cmd_filter->test_fields[i].length); + } + WMA_LOGD("Chatter packets, adding filter with id: %d, num_test_fields=%d",cmd_filter->filter_id, + cmd_filter->num_of_test_field); + /* send the command along with data */ + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_CHATTER_ADD_COALESCING_FILTER_CMDID); + if (err) { + WMA_LOGE("Failed to send set_param cmd"); + wmi_buf_free(buf); + vos_mem_free(rcv_filter_param); + return -EIO; + } + vos_mem_free(rcv_filter_param); + return 0; /* SUCCESS */ +} + +static int wma_process_receive_filter_clear_filter_req(tp_wma_handle wma_handle, + tSirRcvFltPktClearParam *rcv_clear_param) +{ + wmi_chatter_coalescing_delete_filter_cmd_fixed_param *cmd; + wmi_buf_t buf; + int err; + + /* allocate the memory */ + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_param cmd"); + vos_mem_free(rcv_clear_param); + return -ENOMEM; + } + + /* fill the fixed part */ + cmd = (wmi_chatter_coalescing_delete_filter_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_chatter_coalescing_delete_filter_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_chatter_coalescing_delete_filter_cmd_fixed_param)); + cmd->filter_id = rcv_clear_param->filterId; + WMA_LOGD("Chatter packets, clearing filter with id: %d",cmd->filter_id); + + /* send the command along with data */ + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(*cmd), WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID); + if (err) { + WMA_LOGE("Failed to send set_param cmd"); + wmi_buf_free(buf); + vos_mem_free(rcv_clear_param); + return -EIO; + } + vos_mem_free(rcv_clear_param); + return 0; /* SUCCESS */ +} + +static int wma_set_base_macaddr_indicate(tp_wma_handle wma_handle, + tSirMacAddr *customAddr) +{ + wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd; + wmi_buf_t buf; + int err; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_base_macaddr cmd"); + return -ENOMEM; + } + + cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf); + vos_mem_zero(cmd, sizeof(*cmd)); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_set_base_macaddr_cmd_fixed_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(*customAddr, &cmd->base_macaddr); + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(*cmd), WMI_PDEV_SET_BASE_MACADDR_CMDID); + if (err) { + WMA_LOGE("Failed to send set_base_macaddr cmd"); + adf_os_mem_free(buf); + return -EIO; + } + WMA_LOGD("Base MAC Addr: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY((*customAddr))); + + return 0; +} + +static void wma_data_tx_ack_work_handler(struct work_struct *ack_work) +{ + struct wma_tx_ack_work_ctx *work; + tp_wma_handle wma_handle; + pWDAAckFnTxComp ack_cb; + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_WDA, NULL)) { + WMA_LOGE("%s: Driver load/unload in progress", __func__); + return; + } + + work = container_of(ack_work, struct wma_tx_ack_work_ctx, ack_cmp_work); + wma_handle = work->wma_handle; + ack_cb = wma_handle->umac_data_ota_ack_cb; + + if (work->status) + WMA_LOGE("Data Tx Ack Cb Status %d", work->status); + else + WMA_LOGD("Data Tx Ack Cb Status %d", work->status); + + /* Call the Ack Cb registered by UMAC */ + if (ack_cb) + ack_cb((tpAniSirGlobal)(wma_handle->mac_context), + work->status ? 0 : 1); + else + WMA_LOGE("Data Tx Ack Cb is NULL"); + + wma_handle->umac_data_ota_ack_cb = NULL; + wma_handle->last_umac_data_nbuf = NULL; + adf_os_mem_free(work); + wma_handle->ack_work_ctx = NULL; +} + +/** + * wma_data_tx_ack_comp_hdlr - handles tx data ack completion + * @context: context with which the handler is registered + * @netbuf: tx data nbuf + * @err: status of tx completion + * + * This is the cb registered with TxRx for + * Ack Complete + */ +static void +wma_data_tx_ack_comp_hdlr(void *wma_context, + adf_nbuf_t netbuf, int32_t status) +{ + ol_txrx_pdev_handle pdev; + tp_wma_handle wma_handle = (tp_wma_handle)wma_context; + + if (NULL == wma_handle) { + WMA_LOGE("%s: Invalid WMA Handle", __func__); + return; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma_handle->vos_context); + + if (NULL == pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + return; + } + + /* + * if netBuf does not match with pending nbuf then just free the + * netbuf and do not call ack cb + */ + if (wma_handle->last_umac_data_nbuf != netbuf) { + if (wma_handle->umac_data_ota_ack_cb) { + WMA_LOGE("%s: nbuf does not match but umac_data_ota_ack_cb is not null", + __func__); + } else { + WMA_LOGE("%s: nbuf does not match and umac_data_ota_ack_cb is also null", + __func__); + } + goto free_nbuf; + } + + if(wma_handle && wma_handle->umac_data_ota_ack_cb) { + struct wma_tx_ack_work_ctx *ack_work; + + ack_work = + adf_os_mem_alloc(NULL, sizeof(struct wma_tx_ack_work_ctx)); + wma_handle->ack_work_ctx = ack_work; + if(ack_work) { +#ifdef CONFIG_CNSS + cnss_init_work(&ack_work->ack_cmp_work, + wma_data_tx_ack_work_handler); +#else + INIT_WORK(&ack_work->ack_cmp_work, + wma_data_tx_ack_work_handler); +#endif + ack_work->wma_handle = wma_handle; + ack_work->sub_type = 0; + ack_work->status = status; + + /* Schedue the Work */ + schedule_work(&ack_work->ack_cmp_work); + } + } + +free_nbuf: + /* unmap and freeing the tx buf as txrx is not taking care */ + adf_nbuf_unmap_single(pdev->osdev, netbuf, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(netbuf); +} + +static int wma_add_clear_mcbc_filter(tp_wma_handle wma_handle, uint8_t vdev_id, + tSirMacAddr multicastAddr, bool clearList) +{ + WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *cmd; + wmi_buf_t buf; + int err; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_param cmd"); + return -ENOMEM; + } + + cmd = (WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param *) wmi_buf_data(buf); + vos_mem_zero(cmd, sizeof(*cmd)); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_SET_MCASTBCAST_FILTER_CMD_fixed_param)); + cmd->action = (clearList? WMI_MCAST_FILTER_DELETE : WMI_MCAST_FILTER_SET); + cmd->vdev_id = vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(multicastAddr, &cmd->mcastbdcastaddr); + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(*cmd), WMI_SET_MCASTBCAST_FILTER_CMDID); + if (err) { + WMA_LOGE("Failed to send set_param cmd"); + adf_os_mem_free(buf); + return -EIO; + } + WMA_LOGD("Action:%d; vdev_id:%d; clearList:%d\n", + cmd->action, vdev_id, clearList); + WMA_LOGD("MCBC MAC Addr: %0x:%0x:%0x:%0x:%0x:%0x\n", + multicastAddr[0], multicastAddr[1], multicastAddr[2], + multicastAddr[3], multicastAddr[4], multicastAddr[5]); + return 0; +} + +static VOS_STATUS wma_process_mcbc_set_filter_req(tp_wma_handle wma_handle, + tSirRcvFltMcAddrList *mcbc_param) +{ + uint8_t vdev_id = 0; + int i; + + if(mcbc_param->ulMulticastAddrCnt <= 0) { + WMA_LOGE("Number of multicast addresses is 0"); + return VOS_STATUS_E_FAILURE; + } + + if (!wma_find_vdev_by_addr(wma_handle, mcbc_param->selfMacAddr, &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for %pM", + __func__, mcbc_param->bssId); + return VOS_STATUS_E_FAILURE; + } + /* set mcbc_param->action to clear MCList and reset + * to configure the MCList in FW + */ + + for (i = 0; i < mcbc_param->ulMulticastAddrCnt; i++) { + wma_add_clear_mcbc_filter(wma_handle, vdev_id, + mcbc_param->multicastAddr[i], + (mcbc_param->action == 0)); + } + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define GTK_OFFLOAD_ENABLE 0 +#define GTK_OFFLOAD_DISABLE 1 + +static VOS_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, u_int8_t vdev_id, + tpSirGtkOffloadParams params) +{ + int len; + wmi_buf_t buf; + WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + WMA_LOGD("%s Enter", __func__); + + len = sizeof(*cmd); + + /* alloc wmi buffer */ + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); + status = VOS_STATUS_E_NOMEM; + goto out; + } + + cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_GTK_OFFLOAD_CMD_fixed_param)); + + cmd->vdev_id = vdev_id; + + /* Request target to enable GTK offload */ + if (params->ulFlags == GTK_OFFLOAD_ENABLE) { + cmd->flags = GTK_OFFLOAD_ENABLE_OPCODE; + wma->wow.gtk_err_enable[vdev_id] = TRUE; + + /* Copy the keys and replay counter */ + vos_mem_copy(cmd->KCK, params->aKCK, GTK_OFFLOAD_KCK_BYTES); + vos_mem_copy(cmd->KEK, params->aKEK, GTK_OFFLOAD_KEK_BYTES); + vos_mem_copy(cmd->replay_counter, ¶ms->ullKeyReplayCounter, + GTK_REPLAY_COUNTER_BYTES); + } else { + wma->wow.gtk_err_enable[vdev_id] = FALSE; + cmd->flags = GTK_OFFLOAD_DISABLE_OPCODE; + } + + /* send the wmi command */ + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_GTK_OFFLOAD_CMDID)) { + WMA_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID"); + wmi_buf_free(buf); + status = VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags); +out: + WMA_LOGD("%s Exit", __func__); + return status; +} + +static VOS_STATUS wma_process_gtk_offload_req(tp_wma_handle wma, + tpSirGtkOffloadParams params) +{ + u_int8_t vdev_id; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + WMA_LOGD("%s Enter", __func__); + + /* Get the vdev id */ + if (!wma_find_vdev_by_bssid(wma, params->bssId, &vdev_id)) { + WMA_LOGE("vdev handle is invalid for %pM", params->bssId); + status = VOS_STATUS_E_INVAL; + goto out; + } + + /* Validate vdev id */ + if (vdev_id >= wma->max_bssid){ + WMA_LOGE("invalid vdev_id %d for %pM", vdev_id, params->bssId); + status = VOS_STATUS_E_INVAL; + goto out; + } + + if ((params->ulFlags == GTK_OFFLOAD_ENABLE) && + (wma->wow.gtk_err_enable[vdev_id] == TRUE)) { + WMA_LOGE("%s GTK Offload already enabled. Disable it first " + "vdev_id %d", __func__, vdev_id); + params->ulFlags = GTK_OFFLOAD_DISABLE; + status = wma_send_gtk_offload_req(wma, vdev_id, params); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s Failed to disable GTK Offload", __func__); + goto out; + } + WMA_LOGD("%s Enable GTK Offload again with updated inputs", + __func__); + params->ulFlags = GTK_OFFLOAD_ENABLE; + } + status = wma_send_gtk_offload_req(wma, vdev_id, params); +out: + vos_mem_free(params); + WMA_LOGD("%s Exit", __func__); + return status; +} + +static VOS_STATUS wma_process_gtk_offload_getinfo_req(tp_wma_handle wma, + tpSirGtkOffloadGetInfoRspParams params) +{ + u_int8_t vdev_id; + int len; + wmi_buf_t buf; + WMI_GTK_OFFLOAD_CMD_fixed_param *cmd; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + WMA_LOGD("%s Enter", __func__); + + /* Get the vdev id */ + if (!wma_find_vdev_by_bssid(wma, params->bssId, &vdev_id)) { + WMA_LOGE("vdev handle is invalid for %pM", params->bssId); + status = VOS_STATUS_E_INVAL; + goto out; + } + + len = sizeof(*cmd); + + /* alloc wmi buffer */ + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("wmi_buf_alloc failed for WMI_GTK_OFFLOAD_CMD"); + status = VOS_STATUS_E_NOMEM; + goto out; + } + + cmd = (WMI_GTK_OFFLOAD_CMD_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_GTK_OFFLOAD_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_GTK_OFFLOAD_CMD_fixed_param)); + + /* Request for GTK offload status */ + cmd->flags = GTK_OFFLOAD_REQUEST_STATUS_OPCODE; + cmd->vdev_id = vdev_id; + + /* send the wmi command */ + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_GTK_OFFLOAD_CMDID)) { + WMA_LOGE("Failed to send WMI_GTK_OFFLOAD_CMDID for req info"); + wmi_buf_free(buf); + status = VOS_STATUS_E_FAILURE; + } +out: + vos_mem_free(params); + WMA_LOGD("%s Exit", __func__); + return status; +} +#endif + +/* + * Function : wma_enable_arp_ns_offload + * Description : To configure ARP NS off load data to firmware + * when target goes to wow mode. + * Args : @wma - wma handle, @tpSirHostOffloadReq - + * pHostOffloadParams,@bool bArpOnly + * Returns : Returns Failure or Success based on WMI cmd. + * Comments : Since firware expects ARP and NS to be configured + * at a time, Arp info is cached in wma and send along + * with NS info to make both work. + */ +static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma, tpSirHostOffloadReq pHostOffloadParams, bool bArpOnly) +{ + int32_t i; + int32_t res; + WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd; + WMI_NS_OFFLOAD_TUPLE *ns_tuple; + WMI_ARP_OFFLOAD_TUPLE *arp_tuple; + A_UINT8* buf_ptr; + wmi_buf_t buf; + int32_t len; + u_int8_t vdev_id; + + /* Get the vdev id */ + if (!wma_find_vdev_by_bssid(wma, pHostOffloadParams->bssId, &vdev_id)) { + WMA_LOGE("vdev handle is invalid for %pM", pHostOffloadParams->bssId); + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_E_INVAL; + } + + if (!wma->interfaces[vdev_id].vdev_up) { + + WMA_LOGE("vdev %d is not up skipping arp/ns offload", vdev_id); + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) + + WMI_TLV_HDR_SIZE + // TLV place holder size for array of NS tuples + WMI_MAX_NS_OFFLOADS*sizeof(WMI_NS_OFFLOAD_TUPLE) + + WMI_TLV_HDR_SIZE + // TLV place holder size for array of ARP tuples + WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (A_UINT8*)wmi_buf_data(buf); + cmd = (WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param)); + cmd->flags = 0; + cmd->vdev_id = vdev_id; + + WMA_LOGD("ARP NS Offload vdev_id: %d",cmd->vdev_id); + + /* Have copy of arp info to send along with NS, Since FW expects + * both ARP and NS info in single cmd */ + if(bArpOnly) + vos_mem_copy(&wma->mArpInfo, pHostOffloadParams, sizeof(tSirHostOffloadReq)); + + buf_ptr += sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param); + WMITLV_SET_HDR(buf_ptr,WMITLV_TAG_ARRAY_STRUC,(WMI_MAX_NS_OFFLOADS*sizeof(WMI_NS_OFFLOAD_TUPLE))); + buf_ptr += WMI_TLV_HDR_SIZE; + for(i = 0; i < WMI_MAX_NS_OFFLOADS; i++ ){ + ns_tuple = (WMI_NS_OFFLOAD_TUPLE *)buf_ptr; + WMITLV_SET_HDR(&ns_tuple->tlv_header, + WMITLV_TAG_STRUC_WMI_NS_OFFLOAD_TUPLE, + (sizeof(WMI_NS_OFFLOAD_TUPLE)-WMI_TLV_HDR_SIZE)); + + /* Fill data only for NS offload in the first ARP tuple for LA */ + if (!bArpOnly && + ((pHostOffloadParams->enableOrDisable & SIR_OFFLOAD_ENABLE) && i==0)) { + ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID; + +#ifdef WLAN_NS_OFFLOAD + /*Copy the target/solicitation/remote ip addr */ + if(pHostOffloadParams->nsOffloadInfo.targetIPv6AddrValid[0]) + A_MEMCPY(&ns_tuple->target_ipaddr[0], + &pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[0],sizeof(WMI_IPV6_ADDR)); + if(pHostOffloadParams->nsOffloadInfo.targetIPv6AddrValid[1]) + A_MEMCPY(&ns_tuple->target_ipaddr[1], + &pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[1],sizeof(WMI_IPV6_ADDR)); + A_MEMCPY(&ns_tuple->solicitation_ipaddr, + &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr,sizeof(WMI_IPV6_ADDR)); + WMA_LOGD("NS solicitedIp: %pI6, targetIp: %pI6", + pHostOffloadParams->nsOffloadInfo.selfIPv6Addr, + pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[0]); + + /* target MAC is optional, check if it is valid, if this is not valid, + * the target will use the known local MAC address rather than the tuple */ + WMI_CHAR_ARRAY_TO_MAC_ADDR(pHostOffloadParams->nsOffloadInfo.selfMacAddr, + &ns_tuple->target_mac); +#endif + if ((ns_tuple->target_mac.mac_addr31to0 != 0) || + (ns_tuple->target_mac.mac_addr47to32 != 0)) + { + ns_tuple->flags |= WMI_NSOFF_FLAGS_MAC_VALID; + } + } + buf_ptr += sizeof(WMI_NS_OFFLOAD_TUPLE); + } + + WMITLV_SET_HDR(buf_ptr,WMITLV_TAG_ARRAY_STRUC,(WMI_MAX_ARP_OFFLOADS*sizeof(WMI_ARP_OFFLOAD_TUPLE))); + buf_ptr += WMI_TLV_HDR_SIZE; + for(i = 0; i < WMI_MAX_ARP_OFFLOADS; i++){ + arp_tuple = (WMI_ARP_OFFLOAD_TUPLE *)buf_ptr; + WMITLV_SET_HDR(&arp_tuple->tlv_header, + WMITLV_TAG_STRUC_WMI_ARP_OFFLOAD_TUPLE, + WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE)); + + /* Fill data for ARP and NS in the first tupple for LA */ + if ((wma->mArpInfo.enableOrDisable & SIR_OFFLOAD_ENABLE) && (i==0)) { + /*Copy the target ip addr and flags*/ + arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID; + A_MEMCPY(&arp_tuple->target_ipaddr,wma->mArpInfo.params.hostIpv4Addr, + SIR_IPV4_ADDR_LEN); + WMA_LOGD("ARPOffload IP4 address: %pI4", + wma->mArpInfo.params.hostIpv4Addr); + } + buf_ptr += sizeof(WMI_ARP_OFFLOAD_TUPLE); + } + + res = wmi_unified_cmd_send(wma->wmi_handle, buf, len, WMI_SET_ARP_NS_OFFLOAD_CMDID); + if(res) { + WMA_LOGE("Failed to enable ARP NDP/NSffload"); + wmi_buf_free(buf); + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_SUCCESS; +} + +typedef struct { + int32_t rate; + tANI_U8 flag; +} wma_search_rate_t; + +#define WMA_MAX_OFDM_CCK_RATE_TBL_SIZE 12 +/* In ofdm_cck_rate_tbl->flag, if bit 7 is 1 it's CCK, otherwise it ofdm. + * Lower bit carries the ofdm/cck index for encoding the rate */ +static wma_search_rate_t ofdm_cck_rate_tbl[WMA_MAX_OFDM_CCK_RATE_TBL_SIZE] = { + {540, 4}, /* 4: OFDM 54 Mbps */ + {480, 0}, /* 0: OFDM 48 Mbps */ + {360, 5}, /* 5: OFDM 36 Mbps */ + {240, 1}, /* 1: OFDM 24 Mbps */ + {180, 6}, /* 6: OFDM 18 Mbps */ + {120, 2}, /* 2: OFDM 12 Mbps */ + {110, (1 << 7)}, /* 0: CCK 11 Mbps Long */ + {90, 7}, /* 7: OFDM 9 Mbps */ + {60, 3}, /* 3: OFDM 6 Mbps */ + {55, ((1 << 7)|1)}, /* 1: CCK 5.5 Mbps Long */ + {20, ((1 << 7)|2)}, /* 2: CCK 2 Mbps Long */ + {10, ((1 << 7)|3)} /* 3: CCK 1 Mbps Long */ +}; + +#define WMA_MAX_VHT20_RATE_TBL_SIZE 9 +/* In vht20_400ns_rate_tbl flag carries the mcs index for encoding the rate */ +static wma_search_rate_t vht20_400ns_rate_tbl[WMA_MAX_VHT20_RATE_TBL_SIZE] = { + {867, 8}, /* MCS8 1SS short GI */ + {722, 7}, /* MCS7 1SS short GI */ + {650, 6}, /* MCS6 1SS short GI */ + {578, 5}, /* MCS5 1SS short GI */ + {433, 4}, /* MCS4 1SS short GI */ + {289, 3}, /* MCS3 1SS short GI */ + {217, 2}, /* MCS2 1SS short GI */ + {144, 1}, /* MCS1 1SS short GI */ + {72, 0} /* MCS0 1SS short GI */ +}; +/* In vht20_800ns_rate_tbl flag carries the mcs index for encoding the rate */ +static wma_search_rate_t vht20_800ns_rate_tbl[WMA_MAX_VHT20_RATE_TBL_SIZE] = { + {780, 8}, /* MCS8 1SS long GI */ + {650, 7}, /* MCS7 1SS long GI */ + {585, 6}, /* MCS6 1SS long GI */ + {520, 5}, /* MCS5 1SS long GI */ + {390, 4}, /* MCS4 1SS long GI */ + {260, 3}, /* MCS3 1SS long GI */ + {195, 2}, /* MCS2 1SS long GI */ + {130, 1}, /* MCS1 1SS long GI */ + {65, 0} /* MCS0 1SS long GI */ +}; + +#define WMA_MAX_VHT40_RATE_TBL_SIZE 10 +/* In vht40_400ns_rate_tbl flag carries the mcs index for encoding the rate */ +static wma_search_rate_t vht40_400ns_rate_tbl[WMA_MAX_VHT40_RATE_TBL_SIZE] = { + {2000, 9}, /* MCS9 1SS short GI */ + {1800, 8}, /* MCS8 1SS short GI */ + {1500, 7}, /* MCS7 1SS short GI */ + {1350, 6}, /* MCS6 1SS short GI */ + {1200, 5}, /* MCS5 1SS short GI */ + {900, 4}, /* MCS4 1SS short GI */ + {600, 3}, /* MCS3 1SS short GI */ + {450, 2}, /* MCS2 1SS short GI */ + {300, 1}, /* MCS1 1SS short GI */ + {150, 0}, /* MCS0 1SS short GI */ +}; +static wma_search_rate_t vht40_800ns_rate_tbl[WMA_MAX_VHT40_RATE_TBL_SIZE] = { + {1800, 9}, /* MCS9 1SS long GI */ + {1620, 8}, /* MCS8 1SS long GI */ + {1350, 7}, /* MCS7 1SS long GI */ + {1215, 6}, /* MCS6 1SS long GI */ + {1080, 5}, /* MCS5 1SS long GI */ + {810, 4}, /* MCS4 1SS long GI */ + {540, 3}, /* MCS3 1SS long GI */ + {405, 2}, /* MCS2 1SS long GI */ + {270, 1}, /* MCS1 1SS long GI */ + {135, 0} /* MCS0 1SS long GI */ +}; + +#define WMA_MAX_VHT80_RATE_TBL_SIZE 10 +static wma_search_rate_t vht80_400ns_rate_tbl[WMA_MAX_VHT80_RATE_TBL_SIZE] = { + {4333, 9}, /* MCS9 1SS short GI */ + {3900, 8}, /* MCS8 1SS short GI */ + {3250, 7}, /* MCS7 1SS short GI */ + {2925, 6}, /* MCS6 1SS short GI */ + {2600, 5}, /* MCS5 1SS short GI */ + {1950, 4}, /* MCS4 1SS short GI */ + {1300, 3}, /* MCS3 1SS short GI */ + {975, 2}, /* MCS2 1SS short GI */ + {650, 1}, /* MCS1 1SS short GI */ + {325, 0} /* MCS0 1SS short GI */ +}; +static wma_search_rate_t vht80_800ns_rate_tbl[WMA_MAX_VHT80_RATE_TBL_SIZE] = { + {3900, 9}, /* MCS9 1SS long GI */ + {3510, 8}, /* MCS8 1SS long GI */ + {2925, 7}, /* MCS7 1SS long GI */ + {2633, 6}, /* MCS6 1SS long GI */ + {2340, 5}, /* MCS5 1SS long GI */ + {1755, 4}, /* MCS4 1SS long GI */ + {1170, 3}, /* MCS3 1SS long GI */ + {878, 2}, /* MCS2 1SS long GI */ + {585, 1}, /* MCS1 1SS long GI */ + {293, 0} /* MCS0 1SS long GI */ +}; + +#define WMA_MAX_HT20_RATE_TBL_SIZE 8 +static wma_search_rate_t ht20_400ns_rate_tbl[WMA_MAX_HT20_RATE_TBL_SIZE] = { + {722, 7}, /* MCS7 1SS short GI */ + {650, 6}, /* MCS6 1SS short GI */ + {578, 5}, /* MCS5 1SS short GI */ + {433, 4}, /* MCS4 1SS short GI */ + {289, 3}, /* MCS3 1SS short GI */ + {217, 2}, /* MCS2 1SS short GI */ + {144, 1}, /* MCS1 1SS short GI */ + {72, 0} /* MCS0 1SS short GI */ +}; +static wma_search_rate_t ht20_800ns_rate_tbl[WMA_MAX_HT20_RATE_TBL_SIZE] = { + {650, 7}, /* MCS7 1SS long GI */ + {585, 6}, /* MCS6 1SS long GI */ + {520, 5}, /* MCS5 1SS long GI */ + {390, 4}, /* MCS4 1SS long GI */ + {260, 3}, /* MCS3 1SS long GI */ + {195, 2}, /* MCS2 1SS long GI */ + {130, 1}, /* MCS1 1SS long GI */ + {65, 0} /* MCS0 1SS long GI */ +}; + +#define WMA_MAX_HT40_RATE_TBL_SIZE 8 +static wma_search_rate_t ht40_400ns_rate_tbl[WMA_MAX_HT40_RATE_TBL_SIZE] = { + {1500, 7}, /* MCS7 1SS short GI */ + {1350, 6}, /* MCS6 1SS short GI */ + {1200, 5}, /* MCS5 1SS short GI */ + {900, 4}, /* MCS4 1SS short GI */ + {600, 3}, /* MCS3 1SS short GI */ + {450, 2}, /* MCS2 1SS short GI */ + {300, 1}, /* MCS1 1SS short GI */ + {150, 0} /* MCS0 1SS short GI */ +}; +static wma_search_rate_t ht40_800ns_rate_tbl[WMA_MAX_HT40_RATE_TBL_SIZE] = { + {1350, 7}, /* MCS7 1SS long GI */ + {1215, 6}, /* MCS6 1SS long GI */ + {1080, 5}, /* MCS5 1SS long GI */ + {810, 4}, /* MCS4 1SS long GI */ + {540, 3}, /* MCS3 1SS long GI */ + {405, 2}, /* MCS2 1SS long GI */ + {270, 1}, /* MCS1 1SS long GI */ + {135, 0} /* MCS0 1SS long GI */ +}; + +static void wma_bin_search_rate(wma_search_rate_t *tbl, int32_t tbl_size, + tANI_S32 *mbpsx10_rate, tANI_U8 *ret_flag) +{ + int32_t upper, lower, mid; + + /* the table is descenting. index holds the largest value and the + * bottom index holds the smallest value */ + + upper = 0; /* index 0 */ + lower = tbl_size -1; /* last index */ + + if (*mbpsx10_rate >= tbl[upper].rate) { + /* use the largest rate */ + *mbpsx10_rate = tbl[upper].rate; + *ret_flag = tbl[upper].flag; + return; + } else if (*mbpsx10_rate <= tbl[lower].rate) { + /* use the smallest rate */ + *mbpsx10_rate = tbl[lower].rate; + *ret_flag = tbl[lower].flag; + return; + } + /* now we do binery search to get the floor value */ + while (lower - upper > 1) { + mid = (upper + lower) >> 1; + if (*mbpsx10_rate == tbl[mid].rate) { + /* found the exact match */ + *mbpsx10_rate = tbl[mid].rate; + *ret_flag = tbl[mid].flag; + return; + } else { + /* not found. if mid's rate is larger than input move + * upper to mid. If mid's rate is larger than input + * move lower to mid. */ + if (*mbpsx10_rate > tbl[mid].rate) + lower = mid; + else + upper = mid; + } + } + /* after the bin search the index is the ceiling of rate */ + *mbpsx10_rate = tbl[upper].rate; + *ret_flag = tbl[upper].flag; + return; +} + +static VOS_STATUS wma_fill_ofdm_cck_mcast_rate(tANI_S32 mbpsx10_rate, + tANI_U8 nss, tANI_U8 *rate) +{ + tANI_U8 idx = 0; + wma_bin_search_rate(ofdm_cck_rate_tbl, WMA_MAX_OFDM_CCK_RATE_TBL_SIZE, + &mbpsx10_rate, &idx); + + /* if bit 7 is set it uses CCK */ + if (idx & 0x80) + *rate |= (1 << 6) | (idx & 0xF); /* set bit 6 to 1 for CCK */ + else + *rate |= (idx & 0xF); + return VOS_STATUS_SUCCESS; +} + +static void wma_set_ht_vht_mcast_rate(u_int32_t shortgi, tANI_S32 mbpsx10_rate, + tANI_U8 sgi_idx, tANI_S32 sgi_rate, tANI_U8 lgi_idx, tANI_S32 lgi_rate, + tANI_U8 premable, tANI_U8 *rate, tANI_S32 *streaming_rate) +{ + if (shortgi == 0) { + *rate |= (premable << 6) | (lgi_idx & 0xF); + *streaming_rate = lgi_rate; + } else { + *rate |= (premable << 6) | (sgi_idx & 0xF); + *streaming_rate = sgi_rate; + } +} + +static VOS_STATUS wma_fill_ht20_mcast_rate(u_int32_t shortgi, + tANI_S32 mbpsx10_rate, tANI_U8 nss, tANI_U8 *rate, + tANI_S32 *streaming_rate) +{ + tANI_U8 sgi_idx = 0, lgi_idx = 0; + tANI_S32 sgi_rate, lgi_rate; + if (nss == 1) + mbpsx10_rate= mbpsx10_rate >> 1; + + sgi_rate = mbpsx10_rate; + lgi_rate = mbpsx10_rate; + if (shortgi) + wma_bin_search_rate(ht20_400ns_rate_tbl, + WMA_MAX_HT20_RATE_TBL_SIZE, &sgi_rate, &sgi_idx); + else + wma_bin_search_rate(ht20_800ns_rate_tbl, + WMA_MAX_HT20_RATE_TBL_SIZE, &lgi_rate, &lgi_idx); + + wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate, + lgi_idx, lgi_rate, 2, rate, streaming_rate); + if (nss == 1) + *streaming_rate = *streaming_rate << 1; + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_fill_ht40_mcast_rate(u_int32_t shortgi, + tANI_S32 mbpsx10_rate, tANI_U8 nss, tANI_U8 *rate, + tANI_S32 *streaming_rate) +{ + tANI_U8 sgi_idx = 0, lgi_idx = 0; + tANI_S32 sgi_rate, lgi_rate; + + /* for 2x2 divide the rate by 2 */ + if (nss == 1) + mbpsx10_rate= mbpsx10_rate >> 1; + + sgi_rate = mbpsx10_rate; + lgi_rate = mbpsx10_rate; + if (shortgi) + wma_bin_search_rate(ht40_400ns_rate_tbl, + WMA_MAX_HT40_RATE_TBL_SIZE, &sgi_rate, &sgi_idx); + else + wma_bin_search_rate(ht40_800ns_rate_tbl, + WMA_MAX_HT40_RATE_TBL_SIZE, &lgi_rate, &lgi_idx); + + wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate, + lgi_idx, lgi_rate, 2, rate, streaming_rate); + + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_fill_vht20_mcast_rate(u_int32_t shortgi, + tANI_S32 mbpsx10_rate, tANI_U8 nss, tANI_U8 *rate, + tANI_S32 *streaming_rate) +{ + tANI_U8 sgi_idx = 0, lgi_idx = 0; + tANI_S32 sgi_rate, lgi_rate; + + /* for 2x2 divide the rate by 2 */ + if (nss == 1) + mbpsx10_rate= mbpsx10_rate >> 1; + + sgi_rate = mbpsx10_rate; + lgi_rate = mbpsx10_rate; + if (shortgi) + wma_bin_search_rate(vht20_400ns_rate_tbl, + WMA_MAX_VHT20_RATE_TBL_SIZE, &sgi_rate, &sgi_idx); + else + wma_bin_search_rate(vht20_800ns_rate_tbl, + WMA_MAX_VHT20_RATE_TBL_SIZE, &lgi_rate, &lgi_idx); + + wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate, + lgi_idx, lgi_rate, 3, rate, streaming_rate); + if (nss == 1) + *streaming_rate = *streaming_rate << 1; + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_fill_vht40_mcast_rate(u_int32_t shortgi, + tANI_S32 mbpsx10_rate, tANI_U8 nss, tANI_U8 *rate, + tANI_S32 *streaming_rate) +{ + tANI_U8 sgi_idx = 0, lgi_idx = 0; + tANI_S32 sgi_rate, lgi_rate; + + /* for 2x2 divide the rate by 2 */ + if (nss == 1) + mbpsx10_rate= mbpsx10_rate >> 1; + + sgi_rate = mbpsx10_rate; + lgi_rate = mbpsx10_rate; + if (shortgi) + wma_bin_search_rate(vht40_400ns_rate_tbl, + WMA_MAX_VHT40_RATE_TBL_SIZE, &sgi_rate, &sgi_idx); + else + wma_bin_search_rate(vht40_800ns_rate_tbl, + WMA_MAX_VHT40_RATE_TBL_SIZE, &lgi_rate, &lgi_idx); + + wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, + sgi_idx, sgi_rate, lgi_idx, lgi_rate, + 3, rate, streaming_rate); + if (nss == 1) + *streaming_rate = *streaming_rate << 1; + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_fill_vht80_mcast_rate(u_int32_t shortgi, + tANI_S32 mbpsx10_rate, tANI_U8 nss, tANI_U8 *rate, + tANI_S32 *streaming_rate) +{ + tANI_U8 sgi_idx = 0, lgi_idx = 0; + tANI_S32 sgi_rate, lgi_rate; + + /* for 2x2 divide the rate by 2 */ + if (nss == 1) + mbpsx10_rate= mbpsx10_rate >> 1; + + sgi_rate = mbpsx10_rate; + lgi_rate = mbpsx10_rate; + if (shortgi) + wma_bin_search_rate(vht80_400ns_rate_tbl, + WMA_MAX_VHT80_RATE_TBL_SIZE, &sgi_rate, &sgi_idx); + else + wma_bin_search_rate(vht80_800ns_rate_tbl, + WMA_MAX_VHT80_RATE_TBL_SIZE, &lgi_rate, &lgi_idx); + + wma_set_ht_vht_mcast_rate(shortgi, mbpsx10_rate, sgi_idx, sgi_rate, + lgi_idx, lgi_rate, 3, rate, streaming_rate); + if (nss == 1) + *streaming_rate = *streaming_rate << 1; + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_fill_ht_mcast_rate(u_int32_t shortgi, + u_int32_t chwidth, tANI_S32 mbpsx10_rate, tANI_U8 nss, + WLAN_PHY_MODE chanmode, tANI_U8 *rate, tANI_S32 *streaming_rate) +{ + int32_t ret = 0; + + *streaming_rate = 0; + if (chwidth== 0) + ret = wma_fill_ht20_mcast_rate(shortgi, mbpsx10_rate, + nss, rate, streaming_rate); + else if (chwidth == 1) + ret = wma_fill_ht40_mcast_rate(shortgi, mbpsx10_rate, + nss, rate, streaming_rate); + else + WMA_LOGE("%s: Error, Invalid chwidth enum %d", __func__, chwidth); + return (*streaming_rate != 0) ? VOS_STATUS_SUCCESS : VOS_STATUS_E_INVAL; +} + +static VOS_STATUS wma_fill_vht_mcast_rate(u_int32_t shortgi, + u_int32_t chwidth, tANI_S32 mbpsx10_rate, tANI_U8 nss, + WLAN_PHY_MODE chanmode, tANI_U8 *rate, tANI_S32 *streaming_rate) +{ + int32_t ret = 0; + + *streaming_rate = 0; + if (chwidth== 0) + ret = wma_fill_vht20_mcast_rate(shortgi, mbpsx10_rate, nss, + rate, streaming_rate); + else if (chwidth == 1) + ret = wma_fill_vht40_mcast_rate(shortgi, mbpsx10_rate, nss, + rate, streaming_rate); + else if (chwidth == 2) + ret = wma_fill_vht80_mcast_rate(shortgi, mbpsx10_rate, nss, + rate, streaming_rate); + else + WMA_LOGE("%s: chwidth enum %d not supported", + __func__, chwidth); + return (*streaming_rate != 0) ? VOS_STATUS_SUCCESS : VOS_STATUS_E_INVAL; +} + +#define WMA_MCAST_1X1_CUT_OFF_RATE 2000 +/* + * FUNCTION: wma_encode_mc_rate + * + */ +static VOS_STATUS wma_encode_mc_rate(u_int32_t shortgi, u_int32_t chwidth, + WLAN_PHY_MODE chanmode, A_UINT32 mhz, tANI_S32 mbpsx10_rate, + tANI_U8 nss, tANI_U8 *rate) +{ + int32_t ret = 0; + + /* nss input value: 0 - 1x1; 1 - 2x2; 2 - 3x3 + * the phymode selection is based on following assumption: + * (1) if the app specifically requested 1x1 or 2x2 we hornor it + * (2) if mbpsx10_rate <= 540: always use BG + * (3) 540 < mbpsx10_rate <= 2000: use 1x1 HT/VHT + * (4) 2000 < mbpsx10_rate: use 2x2 HT/VHT + */ + WMA_LOGE("%s: Input: nss = %d, chanmode = %d, " + "mbpsx10 = 0x%x, chwidth = %d, shortgi = %d", + __func__, nss, chanmode, mbpsx10_rate, chwidth, shortgi); + if ((mbpsx10_rate & 0x40000000) && nss > 0) { + /* bit 30 indicates user inputed nss, + * bit 28 and 29 used to encode nss */ + tANI_U8 user_nss = (mbpsx10_rate & 0x30000000) >> 28; + + nss = (user_nss < nss) ? user_nss : nss; + /* zero out bits 19 - 21 to recover the actual rate */ + mbpsx10_rate &= ~0x70000000; + } else if (mbpsx10_rate <= WMA_MCAST_1X1_CUT_OFF_RATE) { + /* if the input rate is less or equal to the + * 1x1 cutoff rate we use 1x1 only */ + nss = 0; + } + /* encode NSS bits (bit 4, bit 5) */ + *rate = (nss & 0x3) << 4; + /* if mcast input rate exceeds the ofdm/cck max rate 54mpbs + * we try to choose best ht/vht mcs rate */ + if (540 < mbpsx10_rate) { + /* cannot use ofdm/cck, choose closest ht/vht mcs rate */ + tANI_U8 rate_ht = *rate; + tANI_U8 rate_vht = *rate; + tANI_S32 stream_rate_ht = 0; + tANI_S32 stream_rate_vht = 0; + tANI_S32 stream_rate = 0; + + ret = wma_fill_ht_mcast_rate(shortgi, chwidth, mbpsx10_rate, + nss, chanmode, &rate_ht, &stream_rate_ht); + if (ret != VOS_STATUS_SUCCESS) { + stream_rate_ht = 0; + } + if (mhz < WMA_2_4_GHZ_MAX_FREQ) { + /* not in 5 GHZ frequency */ + *rate = rate_ht; + stream_rate = stream_rate_ht; + goto ht_vht_done; + } + /* capable doing 11AC mcast so that search vht tables */ + ret = wma_fill_vht_mcast_rate(shortgi, chwidth, mbpsx10_rate, + nss, chanmode, &rate_vht, &stream_rate_vht); + if (ret != VOS_STATUS_SUCCESS) { + if (stream_rate_ht != 0) + ret = VOS_STATUS_SUCCESS; + *rate = rate_ht; + stream_rate = stream_rate_ht; + goto ht_vht_done; + } + if (stream_rate_ht == 0) { + /* only vht rate available */ + *rate = rate_vht; + stream_rate = stream_rate_vht; + } else { + /* set ht as default first */ + *rate = rate_ht; + stream_rate = stream_rate_ht; + if (stream_rate < mbpsx10_rate) { + if (mbpsx10_rate <= stream_rate_vht || + stream_rate < stream_rate_vht) { + *rate = rate_vht; + stream_rate = stream_rate_vht; + } + } else { + if (stream_rate_vht >= mbpsx10_rate && + stream_rate_vht < stream_rate) { + *rate = rate_vht; + stream_rate = stream_rate_vht; + } + } + } +ht_vht_done: + WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, " + "freq = %d, input_rate = %d, chwidth = %d " + "rate = 0x%x, streaming_rate = %d", + __func__, nss, chanmode, mhz, + mbpsx10_rate, chwidth, *rate, stream_rate); + } else { + if (mbpsx10_rate > 0) + ret = wma_fill_ofdm_cck_mcast_rate(mbpsx10_rate, + nss, rate); + else + *rate = 0xFF; + WMA_LOGE("%s: NSS = %d, ucast_chanmode = %d, " + "input_rate = %d, rate = 0x%x", + __func__, nss, chanmode, mbpsx10_rate, *rate); + } + return ret; +} +/* + * FUNCTION: wma_process_rate_update_indate + * + */ +VOS_STATUS wma_process_rate_update_indicate(tp_wma_handle wma, + tSirRateUpdateInd *pRateUpdateParams) +{ + int32_t ret = 0; + u_int8_t vdev_id = 0; + void *pdev; + tANI_S32 mbpsx10_rate = -1; + tANI_U32 paramId; + tANI_U8 rate = 0; + u_int32_t short_gi; + struct wma_txrx_node *intr = wma->interfaces; + + /* Get the vdev id */ + pdev = wma_find_vdev_by_addr(wma, pRateUpdateParams->bssid, &vdev_id); + if (!pdev) { + WMA_LOGE("vdev handle is invalid for %pM", pRateUpdateParams->bssid); + vos_mem_free(pRateUpdateParams); + return VOS_STATUS_E_INVAL; + } + short_gi = intr[vdev_id].config.shortgi; + if (short_gi == 0) + short_gi = (intr[vdev_id].rate_flags & eHAL_TX_RATE_SGI) ? TRUE : FALSE; + /* first check if reliable TX mcast rate is used. If not check the bcast. + * Then is mcast. Mcast rate is saved in mcastDataRate24GHz */ + if (pRateUpdateParams->reliableMcastDataRateTxFlag > 0) { + mbpsx10_rate = pRateUpdateParams->reliableMcastDataRate; + paramId = WMI_VDEV_PARAM_MCAST_DATA_RATE; + if (pRateUpdateParams->reliableMcastDataRateTxFlag & eHAL_TX_RATE_SGI) + short_gi = 1; /* upper layer specified short GI */ + } else if (pRateUpdateParams->bcastDataRate > -1) { + mbpsx10_rate = pRateUpdateParams->bcastDataRate; + paramId = WMI_VDEV_PARAM_BCAST_DATA_RATE; + } else { + mbpsx10_rate = pRateUpdateParams->mcastDataRate24GHz; + paramId = WMI_VDEV_PARAM_MCAST_DATA_RATE; + if (pRateUpdateParams->mcastDataRate24GHzTxFlag & eHAL_TX_RATE_SGI) + short_gi = 1; /* upper layer specified short GI */ + } + WMA_LOGE("%s: dev_id = %d, dev_type = %d, dev_mode = %d, " + "mac = %pM, config.shortgi = %d, rate_flags = 0x%x", + __func__, vdev_id, intr[vdev_id].type, + pRateUpdateParams->dev_mode, pRateUpdateParams->bssid, + intr[vdev_id].config.shortgi, intr[vdev_id].rate_flags); + ret = wma_encode_mc_rate(short_gi, intr[vdev_id].config.chwidth, + intr[vdev_id].chanmode, intr[vdev_id].mhz, + mbpsx10_rate, pRateUpdateParams->nss, &rate); + if (ret != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Error, Invalid input rate value", __func__); + vos_mem_free(pRateUpdateParams); + return ret; + } + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_SGI, short_gi); + if (ret) { + WMA_LOGE("%s: Failed to Set WMI_VDEV_PARAM_SGI (%d), ret = %d", + __func__, short_gi, ret); + vos_mem_free(pRateUpdateParams); + return VOS_STATUS_E_FAILURE; + } + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, + vdev_id, paramId, rate); + vos_mem_free(pRateUpdateParams); + if (ret) { + WMA_LOGE("%s: Failed to Set rate, ret = %d", __func__, ret); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_11AC +static void wma_process_update_membership(tp_wma_handle wma_handle, + tUpdateMembership *membership) +{ + WMA_LOGD("%s: membership = %x ", __func__, + membership->membership); + + wma_set_peer_param(wma_handle, membership->peer_mac, + WMI_PEER_MEMBERSHIP, membership->membership, + membership->smesessionId); +} + +static void wma_process_update_userpos(tp_wma_handle wma_handle, + tUpdateUserPos *userpos) +{ + WMA_LOGD("%s: userPos = %x ", __func__, userpos->userPos); + + wma_set_peer_param(wma_handle, userpos->peer_mac, + WMI_PEER_USERPOS, userpos->userPos, + userpos->smesessionId); + + /* Now that membership/userpos is updated in fw, + * enable GID PPS. + */ + wma_set_ppsconfig(userpos->smesessionId, + WMA_VHT_PPS_GID_MATCH, 1); + +} +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + +/* function : wma_batch_scan_enable + * Description : This function handles WDA_SET_BATCH_SCAN_REQ from UMAC + and sends WMI_BATCH_SCAN_ENABLE_CMDID to target + * Args : + handle : Pointer to WMA handle + * rep : Pointer to batch scan enable request from UMAC + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_batch_scan_enable +( + tp_wma_handle wma, + tSirSetBatchScanReq *pReq +) +{ + int ret; + u_int8_t *p; + u_int16_t len; + wmi_buf_t buf; + wmi_batch_scan_enable_cmd_fixed_param *p_bs_enable_cmd; + + len = sizeof(wmi_batch_scan_enable_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) + { + WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__); + return VOS_STATUS_E_FAILURE; + } + + p = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(p, len); + p_bs_enable_cmd = (wmi_batch_scan_enable_cmd_fixed_param *)p; + + WMITLV_SET_HDR(&p_bs_enable_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_batch_scan_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_batch_scan_enable_cmd_fixed_param)); + + p_bs_enable_cmd->vdev_id = pReq->sessionId; + p_bs_enable_cmd->numScan2Batch = pReq->numberOfScansToBatch; + p_bs_enable_cmd->bestNetworks = pReq->bestNetwork; + p_bs_enable_cmd->scanInterval = pReq->scanFrequency; + p_bs_enable_cmd->rfBand = pReq->rfBand; + p_bs_enable_cmd->rtt = pReq->rtt; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_BATCH_SCAN_ENABLE_CMDID); + + WMA_LOGE("batch scan cmd sent len: %d, vdev %d command id: %d, status: %d", + len, p_bs_enable_cmd->vdev_id, WMI_BATCH_SCAN_ENABLE_CMDID, ret); + + return VOS_STATUS_SUCCESS; +} + +/* function : wma_batch_scan_disable + * Description : This function handles WDA_STOP_BATCH_SCAN_REQ from UMAC + and sends WMI_BATCH_SCAN_DISABLE_CMDID to target + * Args : + handle : Pointer to WMA handle + * rep : Pointer to batch scan disable request from UMAC + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_batch_scan_disable +( + tp_wma_handle wma, + tSirStopBatchScanInd *pReq +) +{ + int ret; + u_int8_t *p; + wmi_buf_t buf; + u_int16_t len; + wmi_batch_scan_disable_cmd_fixed_param *p_bs_disable_cmd; + + len = sizeof(wmi_batch_scan_disable_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) + { + WMA_LOGE("%s %d: No WMI resource!", __func__, __LINE__); + return VOS_STATUS_E_FAILURE; + } + + p = (u_int8_t *) wmi_buf_data(buf); + p_bs_disable_cmd = (wmi_batch_scan_disable_cmd_fixed_param *)p; + vos_mem_zero(p, len); + + WMITLV_SET_HDR(&p_bs_disable_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_batch_scan_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_batch_scan_disable_cmd_fixed_param)); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_BATCH_SCAN_DISABLE_CMDID); + + WMA_LOGE("batch scan command sent len: %d, command id: %d, status: %d", + len, WMI_BATCH_SCAN_DISABLE_CMDID, ret); + + return VOS_STATUS_SUCCESS; +} + +/* function : wma_batch_scan_trigger_result + * Description : This function handles WDA_TRIGGER_BATCH_SCAN_RESULT_IND from + UMAC and sends WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID to target + * Args : + handle : Pointer to WMA handle + * rep : Pointer to batch scan trigger request from UMAC + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_batch_scan_trigger_result +( + tp_wma_handle wma, + tSirTriggerBatchScanResultInd *pReq +) +{ + int ret; + u_int8_t *p; + wmi_buf_t buf; + u_int16_t len; + wmi_batch_scan_trigger_result_cmd_fixed_param *p_bs_trigger_result_cmd; + + len = sizeof(wmi_batch_scan_trigger_result_cmd_fixed_param); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) + { + WMA_LOGE("%s %d : No WMI resource!", __func__, __LINE__); + return VOS_STATUS_E_FAILURE; + } + + p = (u_int8_t *) wmi_buf_data(buf); + p_bs_trigger_result_cmd =(wmi_batch_scan_trigger_result_cmd_fixed_param *)p; + vos_mem_zero(p, len); + + WMITLV_SET_HDR(&p_bs_trigger_result_cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_batch_scan_trigger_result_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_batch_scan_trigger_result_cmd_fixed_param)); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID); + + WMA_LOGE("batch scan command sent len: %d, command id: %d, status: %d", + len, WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID, ret); + + return VOS_STATUS_SUCCESS; +} +#endif + + +/* function : wma_process_init_thermal_info + * Description : This function initializes the thermal management table in WMA, + sends down the initial temperature thresholds to the firmware and + configures the throttle period in the tx rx module + * Args : + wma : Pointer to WMA handle + * pThermalParams : Pointer to thermal mitigation parameters + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_process_init_thermal_info(tp_wma_handle wma, + t_thermal_mgmt *pThermalParams) +{ + t_thermal_cmd_params thermal_params; + ol_txrx_pdev_handle curr_pdev; + + if (NULL == wma || NULL == pThermalParams) { + WMA_LOGE("TM Invalid input"); + return VOS_STATUS_E_FAILURE; + } + + curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == curr_pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("TM enable %d period %d", pThermalParams->thermalMgmtEnabled, + pThermalParams->throttlePeriod); + + wma->thermal_mgmt_info.thermalMgmtEnabled = + pThermalParams->thermalMgmtEnabled; + wma->thermal_mgmt_info.thermalLevels[0].minTempThreshold = + pThermalParams->thermalLevels[0].minTempThreshold; + wma->thermal_mgmt_info.thermalLevels[0].maxTempThreshold = + pThermalParams->thermalLevels[0].maxTempThreshold; + wma->thermal_mgmt_info.thermalLevels[1].minTempThreshold = + pThermalParams->thermalLevels[1].minTempThreshold; + wma->thermal_mgmt_info.thermalLevels[1].maxTempThreshold = + pThermalParams->thermalLevels[1].maxTempThreshold; + wma->thermal_mgmt_info.thermalLevels[2].minTempThreshold = + pThermalParams->thermalLevels[2].minTempThreshold; + wma->thermal_mgmt_info.thermalLevels[2].maxTempThreshold = + pThermalParams->thermalLevels[2].maxTempThreshold; + wma->thermal_mgmt_info.thermalLevels[3].minTempThreshold = + pThermalParams->thermalLevels[3].minTempThreshold; + wma->thermal_mgmt_info.thermalLevels[3].maxTempThreshold = + pThermalParams->thermalLevels[3].maxTempThreshold; + wma->thermal_mgmt_info.thermalCurrLevel = WLAN_WMA_THERMAL_LEVEL_0; + + WMA_LOGD("TM level min max:\n" + "0 %d %d\n" + "1 %d %d\n" + "2 %d %d\n" + "3 %d %d", + wma->thermal_mgmt_info.thermalLevels[0].minTempThreshold, + wma->thermal_mgmt_info.thermalLevels[0].maxTempThreshold, + wma->thermal_mgmt_info.thermalLevels[1].minTempThreshold, + wma->thermal_mgmt_info.thermalLevels[1].maxTempThreshold, + wma->thermal_mgmt_info.thermalLevels[2].minTempThreshold, + wma->thermal_mgmt_info.thermalLevels[2].maxTempThreshold, + wma->thermal_mgmt_info.thermalLevels[3].minTempThreshold, + wma->thermal_mgmt_info.thermalLevels[3].maxTempThreshold); + + if (wma->thermal_mgmt_info.thermalMgmtEnabled) + { + ol_tx_throttle_init_period(curr_pdev, pThermalParams->throttlePeriod); + + /* Get the temperature thresholds to set in firmware */ + thermal_params.minTemp = wma->thermal_mgmt_info. + thermalLevels[WLAN_WMA_THERMAL_LEVEL_0].minTempThreshold; + thermal_params.maxTemp = wma->thermal_mgmt_info. + thermalLevels[WLAN_WMA_THERMAL_LEVEL_0].maxTempThreshold; + thermal_params.thermalEnable = + wma->thermal_mgmt_info.thermalMgmtEnabled; + + WMA_LOGE("TM sending the following to firmware: min %d max %d enable %d", + thermal_params.minTemp, thermal_params.maxTemp, + thermal_params.thermalEnable); + + if(VOS_STATUS_SUCCESS != wma_set_thermal_mgmt(wma, thermal_params)) + { + WMA_LOGE("Could not send thermal mgmt command to the firmware!"); + } + } + return VOS_STATUS_SUCCESS; +} + + +/* function : wma_process_set_thermal_level + * Description : This function set the new thermal throttle level in the + txrx module and sends down the corresponding temperature + thresholds to the firmware + * Args : + wma : Pointer to WMA handle + * pThermalLevel : Pointer to thermal level + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_process_set_thermal_level(tp_wma_handle wma, + u_int8_t *pThermalLevel) +{ + u_int8_t thermal_level; + ol_txrx_pdev_handle curr_pdev; + + + if (NULL == wma || NULL == pThermalLevel) { + WMA_LOGE("TM Invalid input"); + return VOS_STATUS_E_FAILURE; + } + + thermal_level = (*pThermalLevel); + + curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == curr_pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGE("TM set level %d", thermal_level); + + /* Check if thermal mitigation is enabled */ + if (!wma->thermal_mgmt_info.thermalMgmtEnabled) { + WMA_LOGE("Thermal mgmt is not enabled, ignoring set level command"); + return VOS_STATUS_E_FAILURE; + } + + if (thermal_level >= WLAN_WMA_MAX_THERMAL_LEVELS) { + WMA_LOGE("Invalid thermal level set %d", thermal_level); + return VOS_STATUS_E_FAILURE; + } + + if (thermal_level == wma->thermal_mgmt_info.thermalCurrLevel) { + WMA_LOGD("Current level %d is same as the set level, ignoring", + wma->thermal_mgmt_info.thermalCurrLevel); + return VOS_STATUS_SUCCESS; + } + + wma->thermal_mgmt_info.thermalCurrLevel = thermal_level; + + ol_tx_throttle_set_level(curr_pdev, thermal_level); + + return VOS_STATUS_SUCCESS; +} + +/* function : wma_ProcessTxPowerLimits + * Description : This function sends the power limits for 2g/5g to firmware + * Args : + handle : Pointer to WMA handle + * ptxlim : Pointer to power limit values + * Returns : VOS_STATUS based on values sent to firmware + * + */ +VOS_STATUS wma_ProcessTxPowerLimits(WMA_HANDLE handle, + tSirTxPowerLimit *ptxlim) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + int32_t ret = 0; + u_int32_t txpower_params2g = 0; + u_int32_t txpower_params5g = 0; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue tx power limit", + __func__); + return VOS_STATUS_E_INVAL; + } + /* Set value and reason code for 2g and 5g power limit */ + + SET_PDEV_PARAM_TXPOWER_REASON(txpower_params2g, + WMI_PDEV_PARAM_TXPOWER_REASON_SAR); + SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params2g, + ptxlim->txPower2g); + + SET_PDEV_PARAM_TXPOWER_REASON(txpower_params5g, + WMI_PDEV_PARAM_TXPOWER_REASON_SAR); + SET_PDEV_PARAM_TXPOWER_VALUE(txpower_params5g, + ptxlim->txPower5g); + + WMA_LOGD("%s: txpower2g: %x txpower5g: %x", + __func__, txpower_params2g, txpower_params5g); + + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_TXPOWER_LIMIT2G, txpower_params2g); + if (ret) { + WMA_LOGE("%s: Failed to set txpower 2g (%d)", + __func__, ret); + return VOS_STATUS_E_FAILURE; + } + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_TXPOWER_LIMIT5G, txpower_params5g); + if (ret) { + WMA_LOGE("%s: Failed to set txpower 5g (%d)", + __func__, ret); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wma_ProcessAddPeriodicTxPtrnInd + * WMI command sent to firmware to add patterns + * for the corresponding vdev id + */ +VOS_STATUS wma_ProcessAddPeriodicTxPtrnInd(WMA_HANDLE handle, + tSirAddPeriodicTxPtrn *pAddPeriodicTxPtrnParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint32_t len; + uint8_t vdev_id; + u_int8_t *buf_ptr; + u_int32_t ptrn_len, ptrn_len_aligned; + int j; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; + ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); + len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + + WMI_TLV_HDR_SIZE + ptrn_len_aligned; + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + if (!wma_find_vdev_by_addr(wma_handle, + pAddPeriodicTxPtrnParams->macAddress, &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for %pM",__func__, + pAddPeriodicTxPtrnParams->macAddress); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_INVAL; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); + + /* Pass the pattern id to delete for the corresponding vdev id */ + cmd->vdev_id = vdev_id; + cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; + cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; + cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; + + /* Pattern info */ + buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, + ptrn_len); + for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) { + WMA_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); + } + WMA_LOGD("%s: Add ptrn id: %d vdev_id: %d", + __func__, cmd->pattern_id, cmd->vdev_id); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { + WMA_LOGE("%s: failed to add pattern set state command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wma_ProcessDelPeriodicTxPtrnInd + * WMI command sent to firmware to del patterns + * for the corresponding vdev id + */ +VOS_STATUS wma_ProcessDelPeriodicTxPtrnInd(WMA_HANDLE handle, + tSirDelPeriodicTxPtrn *pDelPeriodicTxPtrnParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint8_t vdev_id; + u_int32_t len = sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + if (!wma_find_vdev_by_addr(wma_handle, + pDelPeriodicTxPtrnParams->macAddress, &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for %pM",__func__, + pDelPeriodicTxPtrnParams->macAddress); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_INVAL; + } + cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); + + /* Pass the pattern id to delete for the corresponding vdev id */ + cmd->vdev_id = vdev_id; + cmd->pattern_id = pDelPeriodicTxPtrnParams->ucPtrnId; + WMA_LOGD("%s: Del ptrn id: %d vdev_id: %d", + __func__, cmd->pattern_id, cmd->vdev_id); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { + WMA_LOGE("%s: failed to send del pattern command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +static void wma_set_p2pgo_noa_Req(tp_wma_handle wma, + tP2pPsParams *noa) +{ + wmi_p2p_set_noa_cmd_fixed_param *cmd; + wmi_p2p_noa_descriptor *noa_discriptor; + wmi_buf_t buf; + u_int8_t *buf_ptr; + u_int16_t len; + int32_t status; + u_int32_t duration; + + WMA_LOGD("%s: Enter", __func__); + len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor); + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("Failed to allocate memory"); + goto end; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_p2p_set_noa_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_set_noa_cmd_fixed_param)); + duration = (noa->count == 1)? noa->single_noa_duration : noa->duration; + cmd->vdev_id = noa->sessionId; + cmd->enable = (duration)? true : false; + cmd->num_noa = 1; + + WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)), + WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_p2p_noa_descriptor)); + noa_discriptor = (wmi_p2p_noa_descriptor *) (buf_ptr + + sizeof(wmi_p2p_set_noa_cmd_fixed_param) + + WMI_TLV_HDR_SIZE); + WMITLV_SET_HDR(&noa_discriptor->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor, + WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor)); + noa_discriptor->type_count = noa->count; + noa_discriptor->duration = duration; + noa_discriptor->interval = noa->interval; + noa_discriptor->start_time = 0; + + WMA_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d", + cmd->vdev_id, noa->count, noa_discriptor->duration, + noa->interval); + status = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); + if (status != EOK) { + WMA_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID"); + wmi_buf_free(buf); + } + +end: + WMA_LOGD("%s: Exit", __func__); +} + +static void wma_set_p2pgo_oppps_req(tp_wma_handle wma, + tP2pPsParams *oppps) +{ + wmi_p2p_set_oppps_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t status; + + WMA_LOGD("%s: Enter", __func__); + buf = wmi_buf_alloc(wma->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate memory"); + goto end; + } + + cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_set_oppps_cmd_fixed_param)); + cmd->vdev_id = oppps->sessionId; + if (oppps->ctWindow) + WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd); + + WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctWindow); + WMA_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d", + cmd->vdev_id, oppps->ctWindow); + status = wmi_unified_cmd_send(wma->wmi_handle, buf, sizeof(*cmd), + WMI_P2P_SET_OPPPS_PARAM_CMDID); + if (status != EOK) { + WMA_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID"); + wmi_buf_free(buf); + } + +end: + WMA_LOGD("%s: Exit", __func__); +} + +static void wma_process_set_p2pgo_noa_Req(tp_wma_handle wma, + tP2pPsParams *ps_params) +{ + WMA_LOGD("%s: Enter", __func__); + if (ps_params->opp_ps) { + wma_set_p2pgo_oppps_req(wma, ps_params); + } else { + wma_set_p2pgo_noa_Req(wma, ps_params); + } + + WMA_LOGD("%s: Exit", __func__); +} + +/* function : wma_process_set_mimops_req + * Description : Set the received MiMo PS state to firmware. + * Args : + wma_handle : Pointer to WMA handle + * tSetMIMOPS : Pointer to MiMo PS struct + * Returns : + */ +static void wma_process_set_mimops_req(tp_wma_handle wma_handle, + tSetMIMOPS *mimops) +{ + /* Translate to what firmware understands */ + if ( mimops->htMIMOPSState == eSIR_HT_MIMO_PS_DYNAMIC) + mimops->htMIMOPSState = WMI_PEER_MIMO_PS_DYNAMIC; + else if ( mimops->htMIMOPSState == eSIR_HT_MIMO_PS_STATIC) + mimops->htMIMOPSState = WMI_PEER_MIMO_PS_STATIC; + else if ( mimops->htMIMOPSState == eSIR_HT_MIMO_PS_NO_LIMIT) + mimops->htMIMOPSState = WMI_PEER_MIMO_PS_NONE; + + WMA_LOGD("%s: htMIMOPSState = %d, sessionId = %d \ + peerMac <%02x:%02x:%02x:%02x:%02x:%02x>", __func__, + mimops->htMIMOPSState, mimops->sessionId, mimops->peerMac[0], + mimops->peerMac[1], mimops->peerMac[2], mimops->peerMac[3], + mimops->peerMac[4], mimops->peerMac[5]); + + wma_set_peer_param(wma_handle, mimops->peerMac, + WMI_PEER_MIMO_PS_STATE, mimops->htMIMOPSState, + mimops->sessionId); +} + +/* function : wma_set_vdev_intrabss_fwd + * Description : Set intra_fwd value to wni_in. + * Args : + * wma_handle : Pointer to WMA handle + * pdis_intra_fwd : Pointer to DisableIntraBssFwd struct + * Returns : + */ +static void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle, + tpDisableIntraBssFwd pdis_intra_fwd) +{ + ol_txrx_vdev_handle txrx_vdev; + WMA_LOGD("%s:intra_fwd:vdev(%d) intrabss_dis=%s", + __func__, pdis_intra_fwd->sessionId, + (pdis_intra_fwd->disableintrabssfwd ? "true" : "false")); + + txrx_vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].handle; + wdi_in_vdev_rx_fwd_disabled(txrx_vdev, pdis_intra_fwd->disableintrabssfwd); +} + +VOS_STATUS wma_notify_modem_power_state(void *wda_handle, + tSirModemPowerStateInd *pReq) +{ + int32_t ret; + tp_wma_handle wma = (tp_wma_handle)wda_handle; + + WMA_LOGD("%s: WMA Notify Modem Power State %d", __func__, pReq->param); + + ret = wmi_unified_modem_power_state(wma->wmi_handle, pReq->param); + if (ret) { + WMA_LOGE("%s: Fail to notify Modem Power State %d", + __func__, pReq->param); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Successfully notify Modem Power State %d", pReq->param); + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_STATS_EXT +VOS_STATUS wma_stats_ext_req(void *wda_handle, + tpStatsExtRequest preq) +{ + int32_t ret; + tp_wma_handle wma = (tp_wma_handle)wda_handle; + wmi_req_stats_ext_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int16_t len; + u_int8_t *buf_ptr; + + len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + + preq->request_data_len; + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_req_stats_ext_cmd_fixed_param *)buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_req_stats_ext_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_req_stats_ext_cmd_fixed_param)); + cmd->vdev_id = preq->vdev_id; + cmd->data_len = preq->request_data_len; + + WMA_LOGD("%s: The data len value is %u and vdev id set is %u ", + __func__, preq->request_data_len, preq->vdev_id); + + buf_ptr += sizeof(wmi_req_stats_ext_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, cmd->data_len); + + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, preq->request_data, + cmd->data_len); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_REQUEST_STATS_EXT_CMDID); + if (ret != EOK) { + WMA_LOGE("%s: Failed to send notify cmd ret = %d", __func__, ret); + wmi_buf_free(buf); + } + + return ret; +} + +#endif + +void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle, + tHalHiddenSsidVdevRestart *pReq) +{ + struct wma_txrx_node *intr = wma_handle->interfaces; + + if ((pReq->sessionId != intr[pReq->sessionId].vdev_restart_params.vdev_id) || + !((intr[pReq->sessionId].type == WMI_VDEV_TYPE_AP) && + (intr[pReq->sessionId].sub_type == 0))) + { + WMA_LOGE("%s : invalid session id", __func__); + return; + } + + intr[pReq->sessionId].vdev_restart_params.ssidHidden = pReq->ssidHidden; + adf_os_atomic_set(&intr[pReq->sessionId].vdev_restart_params.hidden_ssid_restart_in_progress,1); + + /* vdev stop -> vdev restart -> vdev up */ + WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", + __func__, pReq->sessionId); + wdi_in_vdev_pause(wma_handle->interfaces[pReq->sessionId].handle, + OL_TXQ_PAUSE_REASON_VDEV_STOP); + wma_handle->interfaces[pReq->sessionId].pause_bitmap |= + (1 << PAUSE_TYPE_HOST); + if (wmi_unified_vdev_stop_send(wma_handle->wmi_handle, pReq->sessionId)) { + WMA_LOGE("%s: %d Failed to send vdev stop", + __func__, __LINE__); + adf_os_atomic_set(&intr[pReq->sessionId].vdev_restart_params.hidden_ssid_restart_in_progress,0); + return; + } +} + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +static VOS_STATUS wma_process_ll_stats_clearReq +( + tp_wma_handle wma, + const tpSirLLStatsClearReq clearReq +) +{ + wmi_clear_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!clearReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_clear_link_stats_cmd_fixed_param)); + + cmd->stop_stats_collection_req = clearReq->stopReq; + cmd->vdev_id = clearReq->staId; + cmd->stats_clear_req_mask = clearReq->statsClearReqMask; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(wma->interfaces[clearReq->staId].addr, + &cmd->peer_macaddr); + + WMA_LOGD("LINK_LAYER_STATS - Clear Request Params"); + WMA_LOGD("StopReq : %d", cmd->stop_stats_collection_req); + WMA_LOGD("Vdev Id : %d", cmd->vdev_id); + WMA_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); + WMA_LOGD("Peer MAC Addr : %pM", wma->interfaces[clearReq->staId].addr); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_CLEAR_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send clear link stats req", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Clear Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_process_ll_stats_setReq +( + tp_wma_handle wma, + const tpSirLLStatsSetReq setReq +) +{ + wmi_start_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!setReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_start_link_stats_cmd_fixed_param)); + + cmd->mpdu_size_threshold = setReq->mpduSizeThreshold; + cmd->aggressive_statistics_gathering = setReq->aggressiveStatisticsGathering; + + WMA_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); + WMA_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); + WMA_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_START_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send set link stats request", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Set Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_process_ll_stats_getReq +( + tp_wma_handle wma, + const tpSirLLStatsGetReq getReq +) +{ + wmi_request_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!getReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_request_link_stats_cmd_fixed_param)); + + cmd->request_id = getReq->reqId; + cmd->stats_type = getReq->paramIdMask; + cmd->vdev_id = getReq->staId; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(wma->interfaces[getReq->staId].addr, + &cmd->peer_macaddr); + + WMA_LOGD("LINK_LAYER_STATS - Get Request Params"); + WMA_LOGD("Request ID : %d", cmd->request_id); + WMA_LOGD("Stats Type : %d", cmd->stats_type); + WMA_LOGD("Vdev ID : %d", cmd->vdev_id); + WMA_LOGD("Peer MAC Addr : %pM", wma->interfaces[getReq->staId].addr); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_REQUEST_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send get link stats request", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Get Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef FEATURE_WLAN_EXTSCAN + VOS_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle, + tSirWifiScanCmdReqParams *pstart, + wmi_buf_t *buf, + int *buf_len) +{ + wmi_extscan_start_cmd_fixed_param *cmd; + wmi_extscan_bucket *dest_blist; + wmi_extscan_bucket_channel *dest_clist; + tSirWifiScanBucketSpec *src_bucket = pstart->buckets; + tSirWifiScanChannelSpec *src_channel = src_bucket->channels; + tSirWifiScanChannelSpec save_channel[WLAN_EXTSCAN_MAX_CHANNELS]; + + u_int8_t *buf_ptr; + int i, k, count = 0; + int len = sizeof(*cmd); + int nbuckets = pstart->numBuckets; + int nchannels = 0; + + /* These TLV's are are NULL by default */ + u_int32_t ie_len_with_pad = 0; + int num_ssid = 0; + int num_bssid = 0; + int ie_len = 0; + + u_int32_t dwelltime = src_channel->dwellTimeMs; + uint32_t base_period = pstart->basePeriod; + + WMA_LOGD("%s: Extscan start:num_Channels is %d", + __func__, src_bucket->numChannels); + + WMA_LOGD("%s: Extscan start:num_Buckets is %d", + __func__, pstart->numBuckets); + + /* TLV placeholder for ssid_list (NULL) */ + len += WMI_TLV_HDR_SIZE; + len += num_ssid * sizeof(wmi_ssid); + + /* TLV placeholder for bssid_list (NULL) */ + len += WMI_TLV_HDR_SIZE; + len += num_bssid * sizeof(wmi_mac_addr); + + /* TLV placeholder for ie_data (NULL) */ + len += WMI_TLV_HDR_SIZE; + len += ie_len * sizeof(u_int32_t); + + /* TLV placeholder for bucket */ + len += WMI_TLV_HDR_SIZE; + len += nbuckets * sizeof(wmi_extscan_bucket); + + /* TLV channel placeholder */ + len += WMI_TLV_HDR_SIZE; + for (i = 0; i < nbuckets; i++) { + nchannels += src_bucket->numChannels; + src_bucket++; + } + len += nchannels * sizeof(wmi_extscan_bucket_channel); + /* Allocate the memory */ + *buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!*buf) { + WMA_LOGP("%s: failed to allocate memory" + " for start extscan cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + buf_ptr = (u_int8_t *)wmi_buf_data(*buf); + cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_start_cmd_fixed_param)); + + cmd->request_id = pstart->requestId; + cmd->vdev_id = pstart->sessionId; + cmd->base_period = pstart->basePeriod; + cmd->num_buckets = nbuckets; + + cmd->min_rest_time = WMA_EXTSCAN_REST_TIME; + cmd->max_rest_time = WMA_EXTSCAN_REST_TIME; + cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; + + /* The max dwell time is retrieved from the first channel + * of the first bucket and kept common for all channels. + */ + cmd->min_dwell_time_active = dwelltime; + cmd->max_dwell_time_active = dwelltime; + cmd->min_dwell_time_passive = dwelltime; + cmd->max_dwell_time_passive = dwelltime; + cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan; + cmd->max_table_usage = pstart->reportThreshold; + + cmd->repeat_probe_time = WMA_EXTSCAN_REPEAT_PROBE; + cmd->max_scan_time = WMA_EXTSCAN_MAX_SCAN_TIME; + cmd->probe_delay = 0; + cmd->repeat_probe_time = WMA_EXTSCAN_REPEAT_PROBE; + cmd->probe_spacing_time = 0; + cmd->idle_time = 0; + cmd->burst_duration = WMA_EXTSCAN_BURST_DURATION; + cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ | + WMI_SCAN_ADD_CCK_RATES | + WMI_SCAN_ADD_OFDM_RATES | + WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ; + cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH; + cmd->num_ssids = 0; + cmd->num_bssid = 0; + cmd->ie_len = 0; + cmd->n_probes = 1; + + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_FIXED_STRUC, + num_ssid * sizeof(wmi_ssid)); + buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid)); + + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_FIXED_STRUC, + num_bssid * sizeof(wmi_mac_addr)); + buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr)); + + ie_len_with_pad = 0; + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_BYTE, + ie_len_with_pad); + buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad; + + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + nbuckets * sizeof(wmi_extscan_bucket)); + dest_blist = (wmi_extscan_bucket *) + (buf_ptr + WMI_TLV_HDR_SIZE); + src_bucket = pstart->buckets; + + /* Retrieve scanning information from each bucket and + * channels and send it to the target + */ + for (i = 0; i < nbuckets; i++) { + WMITLV_SET_HDR(dest_blist, + WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket)); + + dest_blist->bucket_id = src_bucket->bucket; + dest_blist->base_period_multiplier = + src_bucket->period / base_period; + dest_blist->channel_band = src_bucket->band; + dest_blist->num_channels = src_bucket->numChannels; + dest_blist->notify_extscan_events = + WMI_EXTSCAN_CYCLE_COMPLETED_EVENT | + WMI_EXTSCAN_BUCKET_OVERRUN_EVENT; + if (src_bucket->reportEvents >= 2) { + dest_blist->forwarding_flags = + WMI_EXTSCAN_FORWARD_FRAME_TO_HOST; + } else { + dest_blist->forwarding_flags = + WMI_EXTSCAN_NO_FORWARDING; + } + if (src_bucket->reportEvents >= 1) + dest_blist->notify_extscan_events = + WMI_EXTSCAN_BUCKET_COMPLETED_EVENT; + if (src_bucket->reportEvents >= 2) + dest_blist->notify_extscan_events |= + WMI_EXTSCAN_CYCLE_STARTED_EVENT | + WMI_EXTSCAN_CYCLE_COMPLETED_EVENT; + + dest_blist->min_dwell_time_active = dwelltime; + dest_blist->max_dwell_time_active = dwelltime; + dest_blist->min_dwell_time_passive = dwelltime; + dest_blist->max_dwell_time_passive = dwelltime; + src_channel = src_bucket->channels; + + /* save the channel info to later populate + * the channel TLV + */ + for (k = 0; k < src_bucket->numChannels; k++) { + save_channel[count++].channel = + src_channel->channel; + src_channel++; + } + dest_blist++; + src_bucket++; + } + buf_ptr += WMI_TLV_HDR_SIZE + + (nbuckets * sizeof(wmi_extscan_bucket)); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + nchannels * sizeof(wmi_extscan_bucket_channel)); + dest_clist = (wmi_extscan_bucket_channel *) + (buf_ptr + WMI_TLV_HDR_SIZE); + + /* Active or passive scan is based on the bucket dwell time + * and channel specific active,passive scans are not + * supported yet + */ + for (i = 0; i < nchannels; i++) { + WMITLV_SET_HDR(dest_clist, + WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_bucket_channel)); + dest_clist->channel = save_channel[i].channel; + dest_clist++; + } + buf_ptr += WMI_TLV_HDR_SIZE + + (nchannels * sizeof(wmi_extscan_bucket_channel)); + *buf_len = len; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_start_extscan(tp_wma_handle wma, + tSirWifiScanCmdReqParams *pstart) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf; + int len; + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed,can not issue extscan cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: extscan feature bit not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + /* Fill individual elements of extscan request and + * TLV for buckets, channel list. + */ + vos_status = wma_get_buf_extscan_start_cmd(wma, pstart, + &buf, &len); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to get buffer for ext scan cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + if (!buf) { + WMA_LOGE("%s:Failed to get buffer" + "for current extscan info", __func__); + return VOS_STATUS_E_FAILURE; + } + if (wmi_unified_cmd_send(wma->wmi_handle, buf, + len, WMI_EXTSCAN_START_CMDID)) { + WMA_LOGE("%s: failed to send command", __func__); + adf_nbuf_free(buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_stop_extscan(tp_wma_handle wma, + tSirExtScanStopReqParams *pstopcmd) +{ + wmi_extscan_stop_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, cannot issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: extscan not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + cmd = (wmi_extscan_stop_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_stop_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_stop_cmd_fixed_param)); + + cmd->request_id = pstopcmd->requestId; + cmd->vdev_id = pstopcmd->sessionId; + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_EXTSCAN_STOP_CMDID)) { + WMA_LOGE("%s: failed to command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +static int wma_get_hotlist_entries_per_page(void *cmd, int numap) +{ + uint32_t avail_space = 0; + int num_entries = 0; + + /* Calculate num of hot list entries that can + * be passed in wma message request. + */ + avail_space = WMA_MAX_EXTSCAN_MSG_SIZE - + (sizeof(*cmd) - sizeof(WMI_TLV_HDR_SIZE)); + num_entries = avail_space / sizeof(wmi_extscan_hotlist_entry); + return num_entries; +} + +VOS_STATUS wma_get_buf_extscan_hotlist_cmd(tp_wma_handle wma_handle, + tSirExtScanSetBssidHotListReqParams *photlist, + int *buf_len) +{ + wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; + wmi_extscan_hotlist_entry *dest_hotlist; + tSirAPThresholdParam *src_ap = photlist->ap; + wmi_buf_t buf; + u_int8_t *buf_ptr; + + int j, index = 0; + int cmd_len = 0; + int num_entries = 0; + int min_entries = 0; + int numap = photlist->numAp; + int len = sizeof(*cmd); + + len += WMI_TLV_HDR_SIZE; + cmd_len = len; + + /* setbssid hotlist expects the bssid list + * to be non zero value + */ + if (!numap) { + WMA_LOGE("%s: Invalid number of bssid's", + __func__); + return VOS_STATUS_E_INVAL; + } + num_entries = wma_get_hotlist_entries_per_page( + cmd, numap); + + /* Split the hot list entry pages and send multiple command + * requests if the buffer reaches the maximum request size + */ + while (index < numap) { + min_entries = MIN(num_entries, numap); + len += min_entries * sizeof(wmi_extscan_hotlist_entry); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: failed to allocate memory" + "for start extscan cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + buf_ptr = (u_int8_t *)wmi_buf_data(buf); + cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) + buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); + + /* Multiple requests are sent until the num_entries_in_page + * matches the total_entries + */ + cmd->request_id = photlist->requestId; + cmd->vdev_id = photlist->sessionId; + cmd->total_entries = numap; + cmd->mode = 1; + cmd->num_entries_in_page = min_entries; + cmd->first_entry_index = index; + + WMA_LOGD("%s: vdev id:%d total_entries: %d num_entries: %d", + __func__, cmd->vdev_id, cmd->total_entries, + cmd->num_entries_in_page); + + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + min_entries * sizeof(wmi_extscan_hotlist_entry)); + dest_hotlist = (wmi_extscan_hotlist_entry *) + (buf_ptr + WMI_TLV_HDR_SIZE); + + /* Populate bssid, channel info and rssi + * for the bssid's that are sent as hotlists. + */ + for (j = 0; j < min_entries; j++) { + WMITLV_SET_HDR(dest_hotlist, + WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_hotlist_entry)); + + dest_hotlist->min_rssi = src_ap->low; + dest_hotlist->channel = src_ap->channel; + WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid, + &dest_hotlist->bssid); + + WMA_LOGD("%s:channel:%d min_rssi %d", + __func__, dest_hotlist->channel, + dest_hotlist->min_rssi); + WMA_LOGD("%s: bssid mac_addr31to0: 0x%x, mac_addr47to32: 0x%x", + __func__, dest_hotlist->bssid.mac_addr31to0, + dest_hotlist->bssid.mac_addr47to32); + dest_hotlist++; + src_ap++; + } + buf_ptr += WMI_TLV_HDR_SIZE + + (min_entries * sizeof(wmi_extscan_hotlist_entry)); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { + WMA_LOGE("%s: failed to send command", __func__); + adf_nbuf_free(buf); + return VOS_STATUS_E_FAILURE; + } + index = index + min_entries; + num_entries = numap - min_entries; + len = cmd_len; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma, + tSirExtScanSetBssidHotListReqParams *photlist) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int len; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue hotlist cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + /* Fill individual elements for hotlist request and + * TLV for bssid entries + */ + vos_status = wma_get_buf_extscan_hotlist_cmd(wma, photlist, + &len); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to get buffer" + "for hotlist scan cmd", __func__); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma, + tSirExtScanResetBssidHotlistReqParams *photlist_reset) +{ + wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + int hotlist_entries = 0; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!photlist_reset) { + WMA_LOGE("%s: Invalid reset hotlist buffer", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: extscan not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(*cmd); + + /* reset bssid hotlist with tlv set to 0 */ + len += WMI_TLV_HDR_SIZE; + len += hotlist_entries * sizeof(wmi_extscan_hotlist_entry); + + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + cmd = (wmi_extscan_configure_hotlist_monitor_cmd_fixed_param *) + buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_configure_hotlist_monitor_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_configure_hotlist_monitor_cmd_fixed_param)); + + cmd->request_id = photlist_reset->requestId; + cmd->vdev_id = photlist_reset->sessionId; + cmd->mode = 0; + + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); + buf_ptr += WMI_TLV_HDR_SIZE + + (hotlist_entries * sizeof(wmi_extscan_hotlist_entry)); + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID)) { + WMA_LOGE("%s: failed to command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_get_buf_extscan_change_monitor_cmd(tp_wma_handle wma_handle, + tSirExtScanSetSigChangeReqParams *psigchange, + wmi_buf_t *buf, int *buf_len) +{ + wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; + wmi_extscan_wlan_change_bssid_param *dest_chglist; + u_int8_t *buf_ptr; + int j; + int len = sizeof(*cmd); + int numap = psigchange->numAp; + tSirAPThresholdParam *src_ap = psigchange->ap; + + if (!numap) { + WMA_LOGE("%s: Invalid number of bssid's", + __func__); + return VOS_STATUS_E_INVAL; + } + len += WMI_TLV_HDR_SIZE; + len += numap * sizeof(wmi_extscan_wlan_change_bssid_param); + + *buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!*buf) { + WMA_LOGP("%s: failed to allocate memory for change monitor cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + buf_ptr = (u_int8_t *) wmi_buf_data(*buf); + cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); + + cmd->request_id = psigchange->requestId; + cmd->vdev_id = psigchange->sessionId; + cmd->total_entries = numap; + cmd->mode = 1; + cmd->num_entries_in_page = numap; + cmd->lost_ap_scan_count = psigchange->lostApSampleSize; + cmd->max_rssi_samples = psigchange->rssiSampleSize; + cmd->rssi_averaging_samples = psigchange->rssiSampleSize; + cmd->max_out_of_range_count = psigchange->minBreaching; + + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + numap * sizeof(wmi_extscan_wlan_change_bssid_param)); + dest_chglist = (wmi_extscan_wlan_change_bssid_param *) + (buf_ptr + WMI_TLV_HDR_SIZE); + + for (j = 0; j < numap; j++) { + WMITLV_SET_HDR(dest_chglist, + WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_wlan_change_bssid_param)); + + dest_chglist->lower_rssi_limit = src_ap->low; + dest_chglist->upper_rssi_limit = src_ap->high; + dest_chglist->channel = src_ap->channel; + WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid, + &dest_chglist->bssid); + + WMA_LOGD("%s:channel:%x min_rssi %d", + __func__, dest_chglist->channel, + dest_chglist->lower_rssi_limit); + dest_chglist++; + src_ap++; + } + buf_ptr += WMI_TLV_HDR_SIZE + + (numap * sizeof(wmi_extscan_wlan_change_bssid_param)); + *buf_len = len; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_start_change_monitor(tp_wma_handle wma, + tSirExtScanSetSigChangeReqParams *psigchange) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + wmi_buf_t buf; + int len; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed,can not issue extscan cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + /* Fill individual elements of change monitor and + * TLV info ... */ + + vos_status = wma_get_buf_extscan_change_monitor_cmd(wma, + psigchange, &buf, &len); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to get buffer for change monitor cmd", + __func__); + return VOS_STATUS_E_FAILURE; + } + if (!buf) { + WMA_LOGE("%s: Failed to get buffer", __func__); + return VOS_STATUS_E_FAILURE; + } + if (wmi_unified_cmd_send(wma->wmi_handle, buf, + len, WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { + WMA_LOGE("%s: failed to send command", __func__); + adf_nbuf_free(buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_stop_change_monitor(tp_wma_handle wma, + tSirExtScanResetSignificantChangeReqParams *pResetReq) +{ + wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + int change_list = 0; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: ext scan not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(*cmd); + + /* reset significant change tlv is set to 0 */ + len += WMI_TLV_HDR_SIZE; + len += change_list * + sizeof(wmi_extscan_wlan_change_bssid_param); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param)); + + cmd->request_id = pResetReq->requestId; + cmd->vdev_id = pResetReq->sessionId; + cmd->mode = 0; + + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + change_list * + sizeof(wmi_extscan_wlan_change_bssid_param)); + buf_ptr += WMI_TLV_HDR_SIZE + (change_list * + sizeof(wmi_extscan_wlan_change_bssid_param)); + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID)) { + WMA_LOGE("%s: failed to command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_get_cached_results(tp_wma_handle wma, + tSirExtScanGetCachedResultsReqParams *pcached_results) +{ + wmi_extscan_get_cached_results_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, cannot issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: extscan not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); + + cmd = (wmi_extscan_get_cached_results_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_get_cached_results_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_get_cached_results_cmd_fixed_param)); + + cmd->request_id = pcached_results->requestId; + cmd->vdev_id = pcached_results->sessionId; + cmd->control_flags = pcached_results->flush; + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID)) { + WMA_LOGE("%s: failed to command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wma_extscan_get_capabilities(tp_wma_handle wma, + tSirGetExtScanCapabilitiesReqParams *pgetcapab) +{ + wmi_extscan_get_capabilities_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + WMA_LOGE("%s: extscan not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); + + cmd = (wmi_extscan_get_capabilities_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_extscan_get_capabilities_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_extscan_get_capabilities_cmd_fixed_param)); + + cmd->request_id = pgetcapab->requestId; + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_EXTSCAN_GET_CAPABILITIES_CMDID)) { + WMA_LOGE("%s: failed to command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} +#endif + +#ifdef WLAN_FEATURE_NAN +/* function : wma_nan_req + * Descriptin : Function is used to send nan request down + * Args : wma_handle, request data which will be non-null + * Returns : SUCCESS or FAILURE + */ +static VOS_STATUS wma_nan_req(void *wda_handle, tpNanRequest nan_req) +{ + int ret; + tp_wma_handle wma_handle = (tp_wma_handle)wda_handle; + wmi_nan_cmd_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + u_int16_t nan_data_len, nan_data_len_aligned; + u_int8_t *buf_ptr; + + /* + * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ----> + * +------------+----------+-----------------------+--------------+ + * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data | + * +------------+----------+-----------------------+--------------+ + */ + if (!nan_req) { + WMA_LOGE("%s:nan req is not valid", __func__); + return VOS_STATUS_E_FAILURE; + } + nan_data_len = nan_req->request_data_len; + nan_data_len_aligned = roundup(nan_req->request_data_len, + sizeof(u_int32_t)); + len += WMI_TLV_HDR_SIZE + nan_data_len_aligned; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_nan_cmd_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_nan_cmd_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_nan_cmd_param)); + cmd->data_len = nan_req->request_data_len; + WMA_LOGD("%s: The data len value is %u", + __func__, nan_req->request_data_len); + buf_ptr += sizeof(wmi_nan_cmd_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, nan_req->request_data, + cmd->data_len); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_NAN_CMDID); + if (ret != EOK) { + WMA_LOGE("%s Failed to send set param command ret = %d", __func__, ret); + wmi_buf_free(buf); + } + return ret; +} +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void wma_process_unit_test_cmd(WMA_HANDLE handle, + t_wma_unit_test_cmd *wma_utest) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_unit_test_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + u_int8_t *buf_ptr; + int i; + u_int16_t len, args_tlv_len; + A_UINT32 *unit_test_cmd_args; + + args_tlv_len = WMI_TLV_HDR_SIZE + wma_utest->num_args * sizeof(A_UINT32); + len = sizeof(wmi_unit_test_cmd_fixed_param) + args_tlv_len; + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue fw unit test cmd", + __func__); + return; + } + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmai_buf_alloc failed", __func__); + return; + } + + cmd = (wmi_unit_test_cmd_fixed_param *)wmi_buf_data(wmi_buf); + buf_ptr = (u_int8_t *) cmd; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_unit_test_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_unit_test_cmd_fixed_param)); + cmd->vdev_id = wma_utest->vdev_id; + cmd->module_id = wma_utest->module_id; + cmd->num_args = wma_utest->num_args; + buf_ptr += sizeof(wmi_unit_test_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (wma_utest->num_args * sizeof(u_int32_t))); + unit_test_cmd_args = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); + WMA_LOGI("%s: %d num of args = ", __func__, wma_utest->num_args); + for (i = 0; (i < wma_utest->num_args && i < WMA_MAX_NUM_ARGS); i++) { + unit_test_cmd_args[i] = wma_utest->args[i]; + WMA_LOGI("%d,", wma_utest->args[i]); + } + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_UNIT_TEST_CMDID)) { + WMA_LOGP("%s: failed to send unit test command", __func__); + adf_nbuf_free(wmi_buf); + return; + } + return; +} +#endif + +VOS_STATUS wma_scan_probe_setoui(tp_wma_handle wma, + tSirScanMacOui *psetoui) +{ + wmi_scan_prob_req_oui_cmd_fixed_param *cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + u_int32_t *oui_buf; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + len = sizeof(*cmd); + wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf); + cmd = (wmi_scan_prob_req_oui_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_scan_prob_req_oui_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_scan_prob_req_oui_cmd_fixed_param)); + + oui_buf = &cmd->prob_req_oui; + vos_mem_zero(oui_buf, sizeof(cmd->prob_req_oui)); + *oui_buf = psetoui->oui[0] << 16 | psetoui->oui[1] << 8 + | psetoui->oui[2]; + WMA_LOGD("%s: wma:oui received from hdd %08x", __func__, + cmd->prob_req_oui); + + if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len, + WMI_SCAN_PROB_REQ_OUI_CMDID)) { + WMA_LOGE("%s: failed to send command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void wma_process_roam_invoke(WMA_HANDLE handle, + t_wma_roam_invoke_cmd *roaminvoke) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_roam_invoke_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + u_int8_t *buf_ptr; + u_int16_t len, args_tlv_len; + A_UINT32 *channel_list; + wmi_mac_addr *bssid_list; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not send roam invoke", + __func__); + return; + } + /* Host sends only one channel and one bssid */ + args_tlv_len = 2 * WMI_TLV_HDR_SIZE + sizeof(A_UINT32) + + sizeof(wmi_mac_addr); + len = sizeof(wmi_roam_invoke_cmd_fixed_param) + args_tlv_len; + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmai_buf_alloc failed", __func__); + return; + } + + cmd = (wmi_roam_invoke_cmd_fixed_param *)wmi_buf_data(wmi_buf); + buf_ptr = (u_int8_t *) cmd; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_invoke_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_invoke_cmd_fixed_param)); + cmd->vdev_id = roaminvoke->vdev_id; + cmd->flags = 0; + cmd->roam_scan_mode = 0; + cmd->roam_ap_sel_mode = 0; + cmd->roam_delay = 0; + cmd->num_chan = 1; + cmd->num_bssid = 1; + buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (sizeof(u_int32_t))); + channel_list = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE); + *channel_list = (A_UINT32)vos_chan_to_freq(roaminvoke->channel); + buf_ptr += sizeof(A_UINT32) + WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, + (sizeof(wmi_mac_addr))); + bssid_list = (wmi_mac_addr *)(buf_ptr + WMI_TLV_HDR_SIZE); + WMI_CHAR_ARRAY_TO_MAC_ADDR(roaminvoke->bssid, bssid_list); + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_ROAM_INVOKE_CMDID)) { + WMA_LOGP("%s: failed to send roam invoke command", __func__); + adf_nbuf_free(wmi_buf); + return; + } + return; +} +#endif + +/* + * function : wma_mc_process_msg + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tp_wma_handle wma_handle; + ol_txrx_vdev_handle txrx_vdev_handle = NULL; + extern tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ); + + WMA_LOGI("%s: Enter", __func__); + if(NULL == msg) { + WMA_LOGE("msg is NULL"); + VOS_ASSERT(0); + vos_status = VOS_STATUS_E_INVAL; + goto end; + } + + WMA_LOGD("msg->type = %x %s", msg->type, macTraceGetWdaMsgString(msg->type)); + + wma_handle = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, + vos_context); + + if (NULL == wma_handle) { + WMA_LOGP("%s: wma_handle is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(msg->bodyptr); + vos_status = VOS_STATUS_E_INVAL; + goto end; + } + + switch (msg->type) { +#ifdef FEATURE_WLAN_ESE + case WDA_TSM_STATS_REQ: + WMA_LOGA("McThread: WDA_TSM_STATS_REQ"); + wma_process_tsm_stats_req(wma_handle, (void*)msg->bodyptr); + break; +#endif + case WNI_CFG_DNLD_REQ: + WMA_LOGA("McThread: WNI_CFG_DNLD_REQ"); + vos_status = wma_wni_cfg_dnld(wma_handle); + if (VOS_IS_STATUS_SUCCESS(vos_status)) { + vos_WDAComplete_cback(vos_context); + } + else { + WMA_LOGD("config download failure"); + } + break ; + case WDA_ADD_STA_SELF_REQ: + txrx_vdev_handle = wma_vdev_attach(wma_handle, + (tAddStaSelfParams *)msg->bodyptr, 1); + if (!txrx_vdev_handle) { + WMA_LOGE("Failed to attach vdev"); + } else { + WLANTL_RegisterVdev(vos_context, + txrx_vdev_handle); + /* Register with TxRx Module for Data Ack Complete Cb */ + wdi_in_data_tx_cb_set(txrx_vdev_handle, + wma_data_tx_ack_comp_hdlr, wma_handle); + } + break; + case WDA_DEL_STA_SELF_REQ: + wma_vdev_detach(wma_handle, + (tDelStaSelfParams *)msg->bodyptr, 1); + break; + case WDA_START_SCAN_OFFLOAD_REQ: + wma_start_scan(wma_handle, msg->bodyptr, msg->type); + vos_mem_free(msg->bodyptr); + break; + case WDA_STOP_SCAN_OFFLOAD_REQ: + wma_stop_scan(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_UPDATE_CHAN_LIST_REQ: + wma_update_channel_list(wma_handle, + (tSirUpdateChanList *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_SET_LINK_STATE: + wma_set_linkstate(wma_handle, + (tpLinkStateParams)msg->bodyptr); + break; + case WDA_CHNL_SWITCH_REQ: + wma_set_channel(wma_handle, + (tpSwitchChannelParams)msg->bodyptr); + break; + case WDA_ADD_BSS_REQ: + wma_add_bss(wma_handle, (tpAddBssParams)msg->bodyptr); + break; + case WDA_ADD_STA_REQ: + wma_add_sta(wma_handle, (tpAddStaParams)msg->bodyptr); + break; + case WDA_SET_BSSKEY_REQ: + wma_set_bsskey(wma_handle, + (tpSetBssKeyParams)msg->bodyptr); + break; + case WDA_SET_STAKEY_REQ: + wma_set_stakey(wma_handle, + (tpSetStaKeyParams)msg->bodyptr); + break; + case WDA_DELETE_STA_REQ: + wma_delete_sta(wma_handle, + (tpDeleteStaParams)msg->bodyptr); + break; + case WDA_DELETE_BSS_REQ: + wma_delete_bss(wma_handle, + (tpDeleteBssParams)msg->bodyptr); + break; + case WDA_UPDATE_EDCA_PROFILE_IND: + wma_process_update_edca_param_req( + wma_handle, + (tEdcaParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_SEND_BEACON_REQ: + wma_send_beacon(wma_handle, + (tpSendbeaconParams)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_SEND_PROBE_RSP_TMPL: + wma_send_probe_rsp_tmpl(wma_handle, + (tpSendProbeRespParams)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_CLI_SET_CMD: + wma_process_cli_set_cmd(wma_handle, + (wda_cli_set_cmd_t *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#if !defined(REMOVE_PKT_LOG) + case WDA_PKTLOG_ENABLE_REQ: + wma_pktlog_wmi_send_cmd(wma_handle, + (struct ath_pktlog_wmi_params *) + msg->bodyptr); + break; +#endif +#if defined(QCA_WIFI_FTM) + case WDA_FTM_CMD_REQ: + wma_process_ftm_command(wma_handle, + (struct ar6k_testmode_cmd_data *)msg->bodyptr); + break; +#endif + case WDA_ENTER_BMPS_REQ: + wma_enable_sta_ps_mode(wma_handle, + (tpEnablePsParams)msg->bodyptr); + break; + case WDA_EXIT_BMPS_REQ: + wma_disable_sta_ps_mode(wma_handle, + (tpDisablePsParams)msg->bodyptr); + break; + case WDA_ENTER_UAPSD_REQ: + wma_enable_uapsd_mode(wma_handle, + (tpEnableUapsdParams)msg->bodyptr); + break; + case WDA_EXIT_UAPSD_REQ: + wma_disable_uapsd_mode(wma_handle, + (tpDisableUapsdParams)msg->bodyptr); + break; + case WDA_SET_TX_POWER_REQ: + wma_set_tx_power(wma_handle, + (tpMaxTxPowerParams)msg->bodyptr); + break; + case WDA_SET_MAX_TX_POWER_REQ: + wma_set_max_tx_power(wma_handle, + (tpMaxTxPowerParams)msg->bodyptr); + break; + case WDA_SET_KEEP_ALIVE: + wma_set_keepalive_req(wma_handle, + (tSirKeepAliveReq *)msg->bodyptr); + break; +#ifdef FEATURE_WLAN_SCAN_PNO + case WDA_SET_PNO_REQ: + wma_config_pno(wma_handle, + (tpSirPNOScanReq)msg->bodyptr); + break; + + case WDA_SME_SCAN_CACHE_UPDATED: + wma_scan_cache_updated_ind(wma_handle, msg->bodyval); + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case WDA_SET_PLM_REQ: + wma_config_plm(wma_handle, + (tpSirPlmReq)msg->bodyptr); + break; +#endif + case WDA_GET_STATISTICS_REQ: + wma_get_stats_req(wma_handle, + (tAniGetPEStatsReq *) msg->bodyptr); + break; + + case WDA_CONFIG_PARAM_UPDATE_REQ: + wma_update_cfg_params(wma_handle, + (tSirMsgQ *)msg); + break; + + case WDA_INIT_SCAN_REQ: + wma_init_scan_req(wma_handle, + (tInitScanParams *)msg->bodyptr); + break; + + case WDA_FINISH_SCAN_REQ: + wma_finish_scan_req(wma_handle, + (tFinishScanParams *)msg->bodyptr); + break; + case WDA_UPDATE_OP_MODE: + wma_process_update_opmode(wma_handle, + (tUpdateVHTOpMode *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_UPDATE_RX_NSS: + wma_process_update_rx_nss(wma_handle, + (tUpdateRxNss *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef WLAN_FEATURE_11AC + case WDA_UPDATE_MEMBERSHIP: + wma_process_update_membership(wma_handle, + (tUpdateMembership *)msg->bodyptr); + break; + case WDA_UPDATE_USERPOS: + wma_process_update_userpos(wma_handle, + (tUpdateUserPos *)msg->bodyptr); + break; +#endif + case WDA_UPDATE_BEACON_IND: + wma_process_update_beacon_params(wma_handle, + (tUpdateBeaconParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + + case WDA_ADD_TS_REQ: + wma_add_ts_req(wma_handle, (tAddTsParams *)msg->bodyptr); + break; + + case WDA_DEL_TS_REQ: + wma_del_ts_req(wma_handle, (tDelTsParams *)msg->bodyptr); + break; + + case WDA_AGGR_QOS_REQ: + wma_aggr_qos_req(wma_handle, (tAggrAddTsParams *)msg->bodyptr); + break; + + case WDA_RECEIVE_FILTER_SET_FILTER_REQ: + wma_process_receive_filter_set_filter_req(wma_handle, + (tSirRcvPktFilterCfgType *)msg->bodyptr); + break; + + case WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ: + wma_process_receive_filter_clear_filter_req(wma_handle, + (tSirRcvFltPktClearParam *)msg->bodyptr); + break; + + case WDA_WOWL_ADD_BCAST_PTRN: + wma_wow_add_pattern(wma_handle, + (tpSirWowlAddBcastPtrn)msg->bodyptr); + break; + case WDA_WOWL_DEL_BCAST_PTRN: + wma_wow_del_pattern(wma_handle, + (tpSirWowlDelBcastPtrn)msg->bodyptr); + break; + case WDA_WOWL_ENTER_REQ: + wma_wow_enter(wma_handle, + (tpSirHalWowlEnterParams)msg->bodyptr); + break; + case WDA_WOWL_EXIT_REQ: + wma_wow_exit(wma_handle, + (tpSirHalWowlExitParams)msg->bodyptr); + break; + case WDA_WLAN_SUSPEND_IND: + wma_suspend_req(wma_handle, + (tpSirWlanSuspendParam)msg->bodyptr); + break; + case WDA_8023_MULTICAST_LIST_REQ: + wma_process_mcbc_set_filter_req(wma_handle, + (tpSirRcvFltMcAddrList)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_REQ: + wma_process_gtk_offload_req( + wma_handle, + (tpSirGtkOffloadParams)msg->bodyptr); + break; + + case WDA_GTK_OFFLOAD_GETINFO_REQ: + wma_process_gtk_offload_getinfo_req( + wma_handle, + (tpSirGtkOffloadGetInfoRspParams)msg->bodyptr); + break; +#endif /* WLAN_FEATURE_GTK_OFFLOAD */ +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDA_START_OEM_DATA_REQ: + wma_start_oem_data_req(wma_handle, + (tStartOemDataReq *)msg->bodyptr); + break; +#endif /* FEATURE_OEM_DATA_SUPPORT */ + case WDA_SET_HOST_OFFLOAD: + wma_enable_arp_ns_offload(wma_handle, (tpSirHostOffloadReq)msg->bodyptr, true); + break; +#ifdef WLAN_NS_OFFLOAD + case WDA_SET_NS_OFFLOAD: + wma_enable_arp_ns_offload(wma_handle, (tpSirHostOffloadReq)msg->bodyptr, false); + break; +#endif /*WLAN_NS_OFFLOAD */ + case WDA_ROAM_SCAN_OFFLOAD_REQ: + /* + * Main entry point or roaming directives from CSR. + */ + wma_process_roam_scan_req(wma_handle, + (tSirRoamOffloadScanReq *)msg->bodyptr); + break; + + case WDA_RATE_UPDATE_IND: + wma_process_rate_update_indicate(wma_handle, (tSirRateUpdateInd *)msg->bodyptr); + break; + +#ifdef FEATURE_WLAN_TDLS + case WDA_UPDATE_FW_TDLS_STATE: + wma_update_fw_tdls_state(wma_handle, + (t_wma_tdls_params *)msg->bodyptr); + break; + case WDA_UPDATE_TDLS_PEER_STATE: + wma_update_tdls_peer_state(wma_handle, + (tTdlsPeerStateParams *)msg->bodyptr); + break; + case WDA_TDLS_SET_OFFCHAN_MODE: + wma_set_tdls_offchan_mode(wma_handle, + (tTdlsChanSwitchParams*)msg->bodyptr); + break; +#endif /* FEATURE_WLAN_TDLS */ +#ifdef FEATURE_WLAN_BATCH_SCAN + case WDA_SET_BATCH_SCAN_REQ: + wma_batch_scan_enable(wma_handle, + (tSirSetBatchScanReq *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + + case WDA_STOP_BATCH_SCAN_IND: + wma_batch_scan_disable(wma_handle, + (tSirStopBatchScanInd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + + case WDA_TRIGGER_BATCH_SCAN_RESULT_IND: + wma_batch_scan_trigger_result(wma_handle, + (tSirTriggerBatchScanResultInd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif + case WDA_ADD_PERIODIC_TX_PTRN_IND: + wma_ProcessAddPeriodicTxPtrnInd(wma_handle, + (tSirAddPeriodicTxPtrn *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_DEL_PERIODIC_TX_PTRN_IND: + wma_ProcessDelPeriodicTxPtrnInd(wma_handle, + (tSirDelPeriodicTxPtrn *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_TX_POWER_LIMIT: + wma_ProcessTxPowerLimits(wma_handle, + (tSirTxPowerLimit *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef FEATURE_WLAN_LPHB + case WDA_LPHB_CONF_REQ: + wma_process_lphb_conf_req(wma_handle, (tSirLPHBReq *)msg->bodyptr); + break; +#endif + +#ifdef FEATURE_WLAN_CH_AVOID + case WDA_CH_AVOID_UPDATE_REQ: + wma_process_ch_avoid_update_req(wma_handle, + (tSirChAvoidUpdateReq *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + case WDA_SET_AUTO_SHUTDOWN_TIMER_REQ: + wma_set_auto_shutdown_timer_req(wma_handle, + msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif + case WDA_DHCP_START_IND: + case WDA_DHCP_STOP_IND: + wma_process_dhcp_ind(wma_handle, + (tAniDHCPInd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + + + case WDA_INIT_THERMAL_INFO_CMD: + wma_process_init_thermal_info(wma_handle, (t_thermal_mgmt *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + + case WDA_SET_THERMAL_LEVEL: + wma_process_set_thermal_level(wma_handle, (u_int8_t *) msg->bodyptr); + break; + + case WDA_SET_P2P_GO_NOA_REQ: + wma_process_set_p2pgo_noa_Req(wma_handle, + (tP2pPsParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_SET_MIMOPS_REQ: + wma_process_set_mimops_req(wma_handle, (tSetMIMOPS *) msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_SET_SAP_INTRABSS_DIS: + wma_set_vdev_intrabss_fwd(wma_handle, (tDisableIntraBssFwd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_FW_STATS_IND: + wma_fw_stats_ind(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_GET_LINK_SPEED: + wma_get_link_speed(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_MODEM_POWER_STATE_IND: + wma_notify_modem_power_state(wma_handle, + (tSirModemPowerStateInd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_VDEV_STOP_IND: + wma_vdev_stop_ind(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_WLAN_RESUME_REQ: + wma_resume_req(wma_handle); + break; + +#ifdef WLAN_FEATURE_STATS_EXT + case WDA_STATS_EXT_REQUEST: + wma_stats_ext_req(wma_handle, + (tpStatsExtRequest)(msg->bodyptr)); + vos_mem_free(msg->bodyptr); + break; +#endif + case WDA_HIDDEN_SSID_VDEV_RESTART: + wma_hidden_ssid_vdev_restart(wma_handle, + (tHalHiddenSsidVdevRestart *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + case WDA_WLAN_EXT_WOW: + wma_enable_ext_wow(wma_handle, + (tSirExtWoWParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_WLAN_SET_APP_TYPE1_PARAMS: + wma_set_app_type1_params_in_fw(wma_handle, + (tSirAppType1Params *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_WLAN_SET_APP_TYPE2_PARAMS: + wma_set_app_type2_params_in_fw(wma_handle, + (tSirAppType2Params *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif + case WDA_VDEV_START_RSP_IND: + wma_vdev_start_rsp_ind(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_ROAM_PREAUTH_IND: + wma_roam_preauth_ind(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_TBTT_UPDATE_IND: + wma_tbtt_update_ind(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef FEATURE_WLAN_EXTSCAN + case WDA_EXTSCAN_START_REQ: + wma_start_extscan(wma_handle, + (tSirWifiScanCmdReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_STOP_REQ: + wma_stop_extscan(wma_handle, + (tSirExtScanStopReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ: + wma_extscan_start_hotlist_monitor(wma_handle, + (tSirExtScanSetBssidHotListReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ: + wma_extscan_stop_hotlist_monitor(wma_handle, + (tSirExtScanResetBssidHotlistReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_SET_SIGNF_CHANGE_REQ: + wma_extscan_start_change_monitor(wma_handle, + (tSirExtScanSetSigChangeReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_RESET_SIGNF_CHANGE_REQ: + wma_extscan_stop_change_monitor(wma_handle, + (tSirExtScanResetSignificantChangeReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_GET_CACHED_RESULTS_REQ: + wma_extscan_get_cached_results(wma_handle, + (tSirExtScanGetCachedResultsReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_EXTSCAN_GET_CAPABILITIES_REQ: + wma_extscan_get_capabilities(wma_handle, + (tSirGetExtScanCapabilitiesReqParams *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif + case WDA_SET_SCAN_MAC_OUI_REQ: + wma_scan_probe_setoui(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WDA_LINK_LAYER_STATS_CLEAR_REQ: + wma_process_ll_stats_clearReq(wma_handle, + (tpSirLLStatsClearReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_LINK_LAYER_STATS_SET_REQ: + wma_process_ll_stats_setReq(wma_handle, + (tpSirLLStatsSetReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_LINK_LAYER_STATS_GET_REQ: + wma_process_ll_stats_getReq(wma_handle, + (tpSirLLStatsGetReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WDA_ROAM_OFFLOAD_SYNCH_CNF: + wma_process_roam_synch_complete(wma_handle, + (tSirSmeRoamOffloadSynchCnf *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case SIR_HAL_UNIT_TEST_CMD: + wma_process_unit_test_cmd(wma_handle, + (t_wma_unit_test_cmd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_ROAM_OFFLOAD_SYNCH_FAIL: + wma_process_roam_synch_fail(wma_handle, + (tSirRoamOffloadSynchFail *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case SIR_HAL_ROAM_INVOKE: + wma_process_roam_invoke(wma_handle, + (t_wma_roam_invoke_cmd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif +#ifdef WLAN_FEATURE_NAN + case WDA_NAN_REQUEST: + wma_nan_req(wma_handle, + (tNanRequest *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif + case SIR_HAL_SET_BASE_MACADDR_IND: + wma_set_base_macaddr_indicate(wma_handle, + (tSirMacAddr *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_LINK_STATUS_GET_REQ: + wma_process_link_status_req(wma_handle, + (tAniGetLinkStatus *)msg->bodyptr); + break; + case WDA_GET_LINK_STATUS_RSP_IND: + wma_link_status_rsp(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + default: + WMA_LOGD("unknow msg type %x", msg->type); + /* Do Nothing? MSG Body should be freed at here */ + if(NULL != msg->bodyptr) { + vos_mem_free(msg->bodyptr); + } + } +end: + WMA_LOGI("%s: Exit", __func__); + return vos_status ; +} + +static int wma_scan_event_callback(WMA_HANDLE handle, u_int8_t *data, + u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL; + wmi_scan_event_fixed_param *wmi_event = NULL; + tSirScanOffloadEvent *scan_event; + u_int8_t vdev_id; + v_U32_t scan_id; + u_int8_t *buf; + vos_msg_t vos_msg = {0}; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + param_buf = (WMI_SCAN_EVENTID_param_tlvs *) data; + wmi_event = param_buf->fixed_param; + vdev_id = wmi_event->vdev_id; + scan_id = wma_handle->interfaces[vdev_id].scan_info.scan_id; + + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + if (wma_handle->roam_preauth_scan_id == wmi_event->scan_id) { + /* This is the scan requested by roam preauth set_channel operation */ + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + + if (wmi_event->event & WMI_SCAN_FINISH_EVENTS) { + WMA_LOGE(" roam scan complete - scan_id %x, vdev_id %x", + wmi_event->scan_id, vdev_id); + wma_reset_scan_info(wma_handle, vdev_id); + } + + buf = vos_mem_malloc(sizeof(wmi_scan_event_fixed_param)); + if (!buf) { + WMA_LOGE("%s: Memory alloc failed for roam preauth ind", + __func__); + return -ENOMEM; + } + vos_mem_zero(buf, sizeof(wmi_scan_event_fixed_param)); + vos_mem_copy(buf, (u_int8_t *)wmi_event, + sizeof(wmi_scan_event_fixed_param)); + + vos_msg.type = WDA_ROAM_PREAUTH_IND; + vos_msg.bodyptr = buf; + vos_msg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vos_msg)) { + WMA_LOGE("%s: Failed to post WDA_ROAM_PREAUTH_IND msg", + __func__); + vos_mem_free(buf); + return -1; + } + WMA_LOGD("%s: WDA_ROAM_PREAUTH_IND posted", __func__); + return 0; + } + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + + scan_event = (tSirScanOffloadEvent *) vos_mem_malloc + (sizeof(tSirScanOffloadEvent)); + if (!scan_event) { + WMA_LOGE("Memory allocation failed for tSirScanOffloadEvent"); + return -ENOMEM; + } + + scan_event->event = wmi_event->event; + + WMA_LOGI("WMA <-- wmi_scan_event : event %u, scan_id %u, " + "freq %u, reason %u", + wmi_event->event, wmi_event->scan_id, + wmi_event->channel_freq, wmi_event->reason); + + scan_event->scanId = wmi_event->scan_id; + scan_event->chanFreq = wmi_event->channel_freq; + scan_event->p2pScanType = + wma_handle->interfaces[vdev_id].scan_info.p2p_scan_type; + scan_event->sessionId = vdev_id; + + if (wmi_event->reason == WMI_SCAN_REASON_COMPLETED || + wmi_event->reason == WMI_SCAN_REASON_TIMEDOUT) + scan_event->reasonCode = eSIR_SME_SUCCESS; + else + scan_event->reasonCode = eSIR_SME_SCAN_FAILED; + + switch (wmi_event->event) { + case WMI_SCAN_EVENT_COMPLETED: + case WMI_SCAN_EVENT_DEQUEUED: + /* + * return success always so that SME can pick whatever scan + * results is available in scan cache(due to partial or + * aborted scan) + */ + scan_event->event = WMI_SCAN_EVENT_COMPLETED; + scan_event->reasonCode = eSIR_SME_SUCCESS; + break; + case WMI_SCAN_EVENT_START_FAILED: + scan_event->event = WMI_SCAN_EVENT_COMPLETED; + scan_event->reasonCode = eSIR_SME_SCAN_FAILED; + break; + case WMI_SCAN_EVENT_PREEMPTED: + WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_PREEMPTED", __func__); + break; + case WMI_SCAN_EVENT_RESTARTED: + WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_RESTARTED", __func__); + break; + } + + /* Stop the scan completion timeout if the event is WMI_SCAN_EVENT_COMPLETED */ + if (scan_event->event == (tSirScanEventType)WMI_SCAN_EVENT_COMPLETED) { + WMA_LOGE(" scan complete - scan_id %x, vdev_id %x", + wmi_event->scan_id, vdev_id); + /* + * first stop the timer then reset scan info, else there is a + * race condition between, timeout handler in host and reset + * operation here. because of that, sometime timeout handler + * triggers and scan ID mismatch messages is printed. + */ + vos_status = vos_timer_stop(&wma_handle->wma_scan_comp_timer); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to stop the scan completion timeout"); + vos_mem_free(scan_event); + return -EPERM; + } + if (wmi_event->scan_id == scan_id) + wma_reset_scan_info(wma_handle, vdev_id); + else + WMA_LOGE("Scan id not matched for SCAN COMPLETE event"); + } + + wma_send_msg(wma_handle, WDA_RX_SCAN_EVENT, (void *) scan_event, 0) ; + return 0; +} + +static void wma_mgmt_tx_ack_work_handler(struct work_struct *ack_work) +{ + struct wma_tx_ack_work_ctx *work; + tp_wma_handle wma_handle; + pWDAAckFnTxComp ack_cb; + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_WDA, NULL)) { + WMA_LOGE("%s: Driver load/unload in progress", __func__); + return; + } + + work = container_of(ack_work, struct wma_tx_ack_work_ctx, ack_cmp_work); + wma_handle = work->wma_handle; + ack_cb = wma_handle->umac_ota_ack_cb[work->sub_type]; + + WMA_LOGD("Tx Ack Cb SubType %d Status %d", + work->sub_type, work->status); + + /* Call the Ack Cb registered by UMAC */ + ack_cb((tpAniSirGlobal)(wma_handle->mac_context), + work->status ? 0 : 1); + + adf_os_mem_free(work); + wma_handle->ack_work_ctx = NULL; +} + +/* function : wma_mgmt_tx_comp_conf_ind + * Description : Post mgmt tx complete indication to PE. + * Args : + wma_handle : Pointer to WMA handle + * sub_type : Tx mgmt frame sub type + * status : Mgmt frame tx status + * Returns : + */ +static void +wma_mgmt_tx_comp_conf_ind(tp_wma_handle wma_handle, u_int8_t sub_type, + int32_t status) +{ + int32_t tx_comp_status; + + tx_comp_status = status ? 0 : 1; + if(sub_type == SIR_MAC_MGMT_DISASSOC) { + wma_send_msg(wma_handle, WDA_DISASSOC_TX_COMP, NULL, tx_comp_status); + } + else if(sub_type == SIR_MAC_MGMT_DEAUTH) { + wma_send_msg(wma_handle, WDA_DEAUTH_TX_COMP, NULL, tx_comp_status); + } +} + +/** + * wma_mgmt_tx_ack_comp_hdlr - handles tx ack mgmt completion + * @context: context with which the handler is registered + * @netbuf: tx mgmt nbuf + * @err: status of tx completion + * + * This is the cb registered with TxRx for + * Ack Complete + */ +static void +wma_mgmt_tx_ack_comp_hdlr(void *wma_context, + adf_nbuf_t netbuf, int32_t status) +{ + tpSirMacFrameCtl pFc = + (tpSirMacFrameCtl)(adf_nbuf_data(netbuf)); + tp_wma_handle wma_handle = (tp_wma_handle)wma_context; + + if(wma_handle && wma_handle->umac_ota_ack_cb[pFc->subType]) { + if((pFc->subType == SIR_MAC_MGMT_DISASSOC) || + (pFc->subType == SIR_MAC_MGMT_DEAUTH)) { + wma_mgmt_tx_comp_conf_ind(wma_handle, (u_int8_t)pFc->subType, + status); + } + else { + struct wma_tx_ack_work_ctx *ack_work; + + ack_work = + adf_os_mem_alloc(NULL, sizeof(struct wma_tx_ack_work_ctx)); + + if(ack_work) { +#ifdef CONFIG_CNSS + cnss_init_work(&ack_work->ack_cmp_work, + wma_mgmt_tx_ack_work_handler); +#else + INIT_WORK(&ack_work->ack_cmp_work, + wma_mgmt_tx_ack_work_handler); +#endif + ack_work->wma_handle = wma_handle; + ack_work->sub_type = pFc->subType; + ack_work->status = status; + + /* Schedue the Work */ + schedule_work(&ack_work->ack_cmp_work); + } + } + } +} + +/** + * wma_mgmt_tx_dload_comp_hldr - handles tx mgmt completion + * @context: context with which the handler is registered + * @netbuf: tx mgmt nbuf + * @err: status of tx completion + */ +static void +wma_mgmt_tx_dload_comp_hldr(void *wma_context, adf_nbuf_t netbuf, + int32_t status) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + tp_wma_handle wma_handle = (tp_wma_handle)wma_context; + void *mac_context = wma_handle->mac_context; + + WMA_LOGD("Tx Complete Status %d", status); + + if (!wma_handle->tx_frm_download_comp_cb) { + WMA_LOGE("Tx Complete Cb not registered by umac"); + return; + } + + /* Call Tx Mgmt Complete Callback registered by umac */ + wma_handle->tx_frm_download_comp_cb(mac_context, + netbuf, 0); + + /* Reset Callback */ + wma_handle->tx_frm_download_comp_cb = NULL; + + /* Set the Tx Mgmt Complete Event */ + vos_status = vos_event_set( + &wma_handle->tx_frm_download_comp_event); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + WMA_LOGP("%s: Event Set failed - tx_frm_comp_event", __func__); +} + +/** + * wma_tx_attach - attaches tx fn with underlying layer + * @pwmaCtx: wma context + */ +VOS_STATUS wma_tx_attach(tp_wma_handle wma_handle) +{ + /* Get the Vos Context */ + pVosContextType vos_handle = + (pVosContextType)(wma_handle->vos_context); + + /* Get the txRx Pdev handle */ + ol_txrx_pdev_handle txrx_pdev = + (ol_txrx_pdev_handle)(vos_handle->pdev_txrx_ctx); + + /* Register for Tx Management Frames */ + wdi_in_mgmt_tx_cb_set(txrx_pdev, GENERIC_NODOWLOAD_ACK_COMP_INDEX, + NULL, wma_mgmt_tx_ack_comp_hdlr,wma_handle); + + wdi_in_mgmt_tx_cb_set(txrx_pdev, GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX, + wma_mgmt_tx_dload_comp_hldr, NULL, wma_handle); + + wdi_in_mgmt_tx_cb_set(txrx_pdev, GENERIC_DOWNLD_COMP_ACK_COMP_INDEX, + wma_mgmt_tx_dload_comp_hldr, + wma_mgmt_tx_ack_comp_hdlr,wma_handle); + + /* Store the Mac Context */ + wma_handle->mac_context = vos_handle->pMACContext; + + return VOS_STATUS_SUCCESS; +} + +/** + * wma_tx_detach - detaches mgmt fn with underlying layer + * Deregister with TxRx for Tx Mgmt Download and Ack completion. + * @tp_wma_handle: wma context + */ +static VOS_STATUS wma_tx_detach(tp_wma_handle wma_handle) +{ + u_int32_t frame_index = 0; + + /* Get the Vos Context */ + pVosContextType vos_handle = + (pVosContextType)(wma_handle->vos_context); + + /* Get the txRx Pdev handle */ + ol_txrx_pdev_handle txrx_pdev = + (ol_txrx_pdev_handle)(vos_handle->pdev_txrx_ctx); + + /* Deregister with TxRx for Tx Mgmt completion call back */ + for (frame_index = 0; frame_index < FRAME_INDEX_MAX; frame_index++) { + wdi_in_mgmt_tx_cb_set(txrx_pdev, frame_index, NULL, NULL, + txrx_pdev); + } + + /* Destroy Tx Frame Complete event */ + vos_event_destroy(&wma_handle->tx_frm_download_comp_event); + + /* Tx queue empty check event (dummy event) */ + vos_event_destroy(&wma_handle->tx_queue_empty_event); + + /* Reset Tx Frm Callbacks */ + wma_handle->tx_frm_download_comp_cb = NULL; + + /* Reset Tx Data Frame Ack Cb */ + wma_handle->umac_data_ota_ack_cb = NULL; + + /* Reset last Tx Data Frame nbuf ptr */ + wma_handle->last_umac_data_nbuf = NULL; + + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +static void wma_roam_ho_fail_handler(tp_wma_handle wma, u_int32_t vdev_id) +{ + tSirSmeHOFailureInd *ho_failure_ind; + vos_msg_t sme_msg = {0}; + VOS_STATUS vos_status; + + ho_failure_ind = vos_mem_malloc(sizeof(tSirSmeHOFailureInd)); + + if (NULL == ho_failure_ind) { + WMA_LOGE("%s: Memory allocation failure", __func__); + return; + } + ho_failure_ind->sessionId = vdev_id; + sme_msg.type = eWNI_SME_HO_FAIL_IND; + sme_msg.bodyptr = ho_failure_ind; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGE("Fail to post eWNI_SME_HO_FAIL_IND msg to SME"); + vos_mem_free(ho_failure_ind); + return; + } + return; +} +#endif + +/* function : wma_roam_better_ap_handler + * Description : Handler for WMI_ROAM_REASON_BETTER_AP event from roam firmware in Rome. + * : This event means roam algorithm in Rome has found a better matching + * : candidate AP. The indication is sent through tl_shim as by repeating + * : the last beacon. Hence this routine calls a tlshim routine. + * Args : + * Returns : + */ +static void wma_roam_better_ap_handler(tp_wma_handle wma, u_int32_t vdev_id) +{ + VOS_STATUS ret; + /* abort existing scans from GUI, but not roaming preauth scan */ + if (wma->interfaces[vdev_id].scan_info.scan_id != 0 && + (wma->interfaces[vdev_id].scan_info.scan_id & + WMA_HOST_ROAM_SCAN_REQID_PREFIX) != + WMA_HOST_ROAM_SCAN_REQID_PREFIX) { + tAbortScanParams abortScan; + abortScan.SessionId = vdev_id; + wma_stop_scan(wma, &abortScan); + } + ret = tlshim_mgmt_roam_event_ind(wma->vos_context, vdev_id); +} + +/* function : wma_roam_event_callback + * Description : Handler for all events from roam engine in firmware + * Args : + * Returns : + */ + +static int wma_roam_event_callback(WMA_HANDLE handle, u_int8_t *event_buf, + u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_ROAM_EVENTID_param_tlvs *param_buf; + wmi_roam_event_fixed_param *wmi_event; + + param_buf = (WMI_ROAM_EVENTID_param_tlvs *) event_buf; + if (!param_buf) { + WMA_LOGE("Invalid roam event buffer"); + return -EINVAL; + } + + wmi_event = param_buf->fixed_param; + WMA_LOGD("%s: Reason %x for vdevid %x, rssi %d", + __func__, wmi_event->reason, wmi_event->vdev_id, wmi_event->rssi); + + switch(wmi_event->reason) { + case WMI_ROAM_REASON_BMISS: + WMA_LOGD("Beacon Miss for vdevid %x", + wmi_event->vdev_id); + wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id); + break; + case WMI_ROAM_REASON_BETTER_AP: + WMA_LOGD("%s:Better AP found for vdevid %x, rssi %d", __func__, + wmi_event->vdev_id, wmi_event->rssi); + wma_handle->suitable_ap_hb_failure = FALSE; + wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id); + break; + case WMI_ROAM_REASON_SUITABLE_AP: + wma_handle->suitable_ap_hb_failure = TRUE; + WMA_LOGD("%s:Bmiss scan AP found for vdevid %x, rssi %d", __func__, + wmi_event->vdev_id, wmi_event->rssi); + wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id); + break; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case WMI_ROAM_REASON_HO_FAILED: + WMA_LOGE("LFR3:Hand-Off Failed for vdevid %x", + wmi_event->vdev_id); + wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id); + break; +#endif + default: + WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__, + wmi_event->reason, wmi_event->vdev_id); + break; + } + return 0; +} + +#ifdef FEATURE_WLAN_SCAN_PNO + +/* Record NLO match event comes from FW. It's a indication that + * one of the profile is matched. + */ +static int wma_nlo_match_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + wmi_nlo_event *nlo_event; + WMI_NLO_MATCH_EVENTID_param_tlvs *param_buf = + (WMI_NLO_MATCH_EVENTID_param_tlvs *) event; + struct wma_txrx_node *node; + + if (!param_buf) { + WMA_LOGE("Invalid NLO match event buffer"); + return -EINVAL; + } + + nlo_event = param_buf->fixed_param; + WMA_LOGD("PNO match event received for vdev %d", + nlo_event->vdev_id); + + node = &wma->interfaces[nlo_event->vdev_id]; + if (node) + node->nlo_match_evt_received = TRUE; + + vos_wake_lock_timeout_acquire(&wma->pno_wake_lock, + WMA_PNO_WAKE_LOCK_TIMEOUT); + + return 0; +} + +/* Handles NLO scan completion event. */ +static int wma_nlo_scan_cmp_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + wmi_nlo_event *nlo_event; + WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *param_buf = + (WMI_NLO_SCAN_COMPLETE_EVENTID_param_tlvs *) event; + tSirScanOffloadEvent *scan_event; + struct wma_txrx_node *node; + + if (!param_buf) { + WMA_LOGE("Invalid NLO scan comp event buffer"); + return -EINVAL; + } + + nlo_event = param_buf->fixed_param; + WMA_LOGD("PNO scan completion event received for vdev %d", + nlo_event->vdev_id); + + node = &wma->interfaces[nlo_event->vdev_id]; + + /* Handle scan completion event only after NLO match event. */ + if (!node || !node->nlo_match_evt_received) { + + WMA_LOGD("NLO match not recieved skipping PNO complete ind for vdev %d", + nlo_event->vdev_id); + goto skip_pno_cmp_ind; + } + + scan_event = (tSirScanOffloadEvent *) vos_mem_malloc( + sizeof(tSirScanOffloadEvent)); + if (scan_event) { + /* Posting scan completion msg would take scan cache result + * from LIM module and update in scan cache maintained in SME.*/ + WMA_LOGD("Posting Scan completion to umac"); + vos_mem_zero(scan_event, sizeof(tSirScanOffloadEvent)); + scan_event->reasonCode = eSIR_SME_SUCCESS; + scan_event->event = SCAN_EVENT_COMPLETED; + scan_event->sessionId = nlo_event->vdev_id; + wma_send_msg(wma, WDA_RX_SCAN_EVENT, + (void *) scan_event, 0); + } else { + WMA_LOGE("Memory allocation failed for tSirScanOffloadEvent"); + } + +skip_pno_cmp_ind: + return 0; +} + +#endif + +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +/* Handle TX pause event from FW */ +static int wma_mcc_vdev_tx_pause_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_TX_PAUSE_EVENTID_param_tlvs *param_buf; + wmi_tx_pause_event_fixed_param *wmi_event; + u_int8_t vdev_id; + A_UINT32 vdev_map; + + param_buf = (WMI_TX_PAUSE_EVENTID_param_tlvs *) event; + if (!param_buf) + { + WMA_LOGE("Invalid roam event buffer"); + return -EINVAL; + } + + if (wma_get_wow_bus_suspend(wma)) { + WMA_LOGD(" Suspend is in progress: Pause/Unpause Tx is NoOp"); + return 0; + } + + wmi_event = param_buf->fixed_param; + vdev_map = wmi_event->vdev_map; + /* FW mapped vdev from ID + * vdev_map = (1 << vdev_id) + * So, host should unmap to ID */ + for (vdev_id = 0; vdev_map != 0; vdev_id++) + { + if (!(vdev_map & 0x1)) + { + /* No Vdev */ + } + else + { + if (!wma->interfaces[vdev_id].handle) + { + WMA_LOGE("%s: invalid vdev ID %d", __func__, vdev_id); + /* Test Next VDEV */ + vdev_map >>= 1; + continue; + } + + /* PAUSE action, add bitmap */ + if (ACTION_PAUSE == wmi_event->action) + { + /* + * Now only support per-dev pause so it is not necessary + * to pause a paused queue again. + */ + if (!wma->interfaces[vdev_id].pause_bitmap) + wdi_in_vdev_pause(wma->interfaces[vdev_id].handle, + OL_TXQ_PAUSE_REASON_FW); + wma->interfaces[vdev_id].pause_bitmap |= (1 << wmi_event->pause_type); + } + /* UNPAUSE action, clean bitmap */ + else if (ACTION_UNPAUSE == wmi_event->action) + { + /* Handle unpause only if already paused*/ + if(wma->interfaces[vdev_id].pause_bitmap) + { + wma->interfaces[vdev_id].pause_bitmap &= ~(1 << wmi_event->pause_type); + + if (!wma->interfaces[vdev_id].pause_bitmap) + { + /* PAUSE BIT MAP is cleared + * UNPAUSE VDEV */ + wdi_in_vdev_unpause(wma->interfaces[vdev_id].handle, + OL_TXQ_PAUSE_REASON_FW); + } + } + } + else + { + WMA_LOGE("Not Valid Action Type %d", wmi_event->action); + } + + WMA_LOGD("vdev_id %d, pause_map 0x%x, pause type %d, action %d", + vdev_id, wma->interfaces[vdev_id].pause_bitmap, + wmi_event->pause_type, wmi_event->action); + } + /* Test Next VDEV */ + vdev_map >>= 1; + } + + return 0; +} +#endif /* QCA_SUPPORT_TXRX_VDEV_PAUSE_LL */ + +/* function : wma_set_thermal_mgmt + * Description : This function sends the thermal management command to the firmware + * Args : + wma_handle : Pointer to WMA handle + * thermal_info : Thermal command information + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +static VOS_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle, + t_thermal_cmd_params thermal_info) +{ + wmi_thermal_mgmt_cmd_fixed_param *cmd = NULL; + wmi_buf_t buf = NULL; + int status = 0; + u_int32_t len = 0; + + len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set key cmd"); + return eHAL_STATUS_FAILURE; + } + + cmd = (wmi_thermal_mgmt_cmd_fixed_param *) wmi_buf_data (buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_thermal_mgmt_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_thermal_mgmt_cmd_fixed_param)); + + cmd->lower_thresh_degreeC = thermal_info.minTemp; + cmd->upper_thresh_degreeC = thermal_info.maxTemp; + cmd->enable = thermal_info.thermalEnable; + + WMA_LOGE("TM Sending thermal mgmt cmd: low temp %d, upper temp %d, enabled %d", + cmd->lower_thresh_degreeC, cmd->upper_thresh_degreeC, cmd->enable); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_THERMAL_MGMT_CMDID); + if (status) { + adf_nbuf_free(buf); + WMA_LOGE("%s:Failed to send thermal mgmt command", __func__); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* function : wma_thermal_mgmt_get_level + * Description : This function returns the thermal(throttle) level given the temperature + * Args : + handle : Pointer to WMA handle + * temp : temperature + * Returns : + * thermal (throttle) level + */ +u_int8_t wma_thermal_mgmt_get_level(void *handle, u_int32_t temp) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + int i; + u_int8_t level; + + level = i = wma->thermal_mgmt_info.thermalCurrLevel; + while (temp < wma->thermal_mgmt_info.thermalLevels[i].minTempThreshold && + i > 0) { + i--; + level = i; + } + + i = wma->thermal_mgmt_info.thermalCurrLevel; + while (temp > wma->thermal_mgmt_info.thermalLevels[i].maxTempThreshold && + i < (WLAN_WMA_MAX_THERMAL_LEVELS - 1)) { + i++; + level = i; + } + + WMA_LOGW("Change thermal level from %d -> %d\n", + wma->thermal_mgmt_info.thermalCurrLevel, level); + + return level; +} + +/* function : wma_thermal_mgmt_evt_handler + * Description : This function handles the thermal mgmt event from the firmware + * Args : + wma_handle : Pointer to WMA handle + * event : Thermal event information + * len : + * Returns : + * 0 for success otherwise failure + */ +static int wma_thermal_mgmt_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + tp_wma_handle wma; + wmi_thermal_mgmt_event_fixed_param *tm_event; + u_int8_t thermal_level; + t_thermal_cmd_params thermal_params; + WMI_THERMAL_MGMT_EVENTID_param_tlvs *param_buf; + ol_txrx_pdev_handle curr_pdev; + + if (NULL == event || NULL == handle) { + WMA_LOGE("Invalid thermal mitigation event buffer"); + return -EINVAL; + } + + wma = (tp_wma_handle) handle; + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma handle", __func__); + return -EINVAL; + } + + param_buf = (WMI_THERMAL_MGMT_EVENTID_param_tlvs *) event; + + curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == curr_pdev) { + WMA_LOGE("%s: Failed to get pdev", __func__); + return -EINVAL; + } + + /* Check if thermal mitigation is enabled */ + if (!wma->thermal_mgmt_info.thermalMgmtEnabled){ + WMA_LOGE("Thermal mgmt is not enabled, ignoring event"); + return -EINVAL; + } + + tm_event = param_buf->fixed_param; + WMA_LOGD("Thermal mgmt event received with temperature %d", + tm_event->temperature_degreeC); + + /* Get the thermal mitigation level for the reported temperature*/ + thermal_level = wma_thermal_mgmt_get_level(handle, tm_event->temperature_degreeC); + WMA_LOGD("Thermal mgmt level %d", thermal_level); + + if (thermal_level == wma->thermal_mgmt_info.thermalCurrLevel) { + WMA_LOGD("Current level %d is same as the set level, ignoring", + wma->thermal_mgmt_info.thermalCurrLevel); + return 0; + } + + wma->thermal_mgmt_info.thermalCurrLevel = thermal_level; + + /* Inform txrx */ + ol_tx_throttle_set_level(curr_pdev, thermal_level); + + /* Get the temperature thresholds to set in firmware */ + thermal_params.minTemp = + wma->thermal_mgmt_info.thermalLevels[thermal_level].minTempThreshold; + thermal_params.maxTemp = + wma->thermal_mgmt_info.thermalLevels[thermal_level].maxTempThreshold; + thermal_params.thermalEnable = + wma->thermal_mgmt_info.thermalMgmtEnabled; + + if (VOS_STATUS_SUCCESS != wma_set_thermal_mgmt(wma, thermal_params)) { + WMA_LOGE("Could not send thermal mgmt command to the firmware!"); + return -EINVAL; + } + + return 0; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/* function : wma_batch_scan_result_event_handler + * Description : Batch scan result event handler from target. This function + * converts target batch scan response into HDD readable format + * and calls HDD supplied callback + * Args : + handle : Pointer to WMA handle + * data : Pointer to batch scan response data from target + datalen : Length of response data from target + * Returns : + */ +static int +wma_batch_scan_result_event_handler +( + void *handle, + u_int8_t *data, + u_int32_t datalen +) +{ + void *pCallbackContext; + tSirBatchScanList *pHddScanList; + tSirBatchScanResultIndParam *pHddResult; + tSirBatchScanNetworkInfo *pHddApMetaInfo; + tp_wma_handle wma = (tp_wma_handle) handle; + wmi_batch_scan_result_scan_list *scan_list; + wmi_batch_scan_result_network_info *network_info; + wmi_batch_scan_result_event_fixed_param *fix_param; + WMI_BATCH_SCAN_RESULT_EVENTID_param_tlvs *param_tlvs; + u_int8_t bssid[IEEE80211_ADDR_LEN], ssid[33], *ssid_temp; + u_int32_t temp, count1, count2, scan_num, netinfo_num, total_size; + u_int32_t nextScanListOffset, nextApMetaInfoOffset, numNetworkInScanList; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + total_size = 0; + param_tlvs = (WMI_BATCH_SCAN_RESULT_EVENTID_param_tlvs *)data; + fix_param = param_tlvs->fixed_param; + scan_list = param_tlvs->scan_list; + network_info = param_tlvs->network_list; + scan_num = fix_param->numScanLists; + + WMA_LOGE("%s: scan_num %d isLast %d", __func__, scan_num, + fix_param->isLastResult); + + if (NULL == pMac) + { + WMA_LOGE("%s: Could not parse target response scan_num %d pMac %p", + __func__, scan_num, pMac); + return 0; + } + + if (0 == scan_num) + { + WMA_LOGE("%s: Could not parse target response scan_num %d pMac %p", + __func__, scan_num, pMac); + pHddResult = NULL; + goto done; + } + + for(count1 = 0; count1 < scan_num; count1++) + { + total_size += (sizeof(tSirBatchScanNetworkInfo) * + scan_list->numNetworksInScanList); + netinfo_num = scan_list->numNetworksInScanList; + WMA_LOGD("scanId %d numNetworksInScanList %d " + "netWorkStartIndex %d", scan_list->scanId, + scan_list->numNetworksInScanList, scan_list->netWorkStartIndex); + scan_list++; + } + total_size += (sizeof(tSirBatchScanResultIndParam) + + sizeof(tSirBatchScanList) * scan_num); + WMA_LOGE("%s: Batch scan response length %d", __func__, total_size); + pHddResult = (tSirBatchScanResultIndParam *)vos_mem_malloc(total_size); + if (NULL == pHddResult) + { + WMA_LOGE("%s:Could not allocate memory for len %d", __func__, + total_size); + goto done; + } + + /* + Parse target response and fill it in HDD format as shown below + Target Response: + =============== + | scan result | scan list 0 | scan list 1 | scan list 2 | ---- + | scan list N | network info 1to n1 | network info 1 to n2 |---- + | network info 1 to Nn | + + HDD requested format: + ==================== + | scan result | scan list 0 | network info 1 to n1 | scan list 2 | + | network info 1 to n2 | scan list 3 | network info 1 to n3 | ---- + | scan list N | network info 1 to Nn | + */ + vos_mem_zero((u_int8_t*)pHddResult, total_size); + pHddResult->timestamp = fix_param->timestamp; + pHddResult->numScanLists = fix_param->numScanLists; + pHddResult->isLastResult = fix_param->isLastResult; + scan_list = param_tlvs->scan_list; + network_info = param_tlvs->network_list; + nextScanListOffset = 0; + nextApMetaInfoOffset = 0; + numNetworkInScanList = 0; + + for(count1 = 0; count1 < scan_num; count1++) + { + pHddScanList = (tSirBatchScanList *)((tANI_U8 *)pHddResult->scanResults + + nextScanListOffset); + pHddScanList->scanId = scan_list->scanId; + pHddScanList->numNetworksInScanList = scan_list->numNetworksInScanList; + numNetworkInScanList = pHddScanList->numNetworksInScanList; + + /*Initialize next AP meta info offset for next scan list*/ + nextApMetaInfoOffset = 0; + + for (count2 = 0; count2 < scan_list->numNetworksInScanList; count2++) + { + int8_t raw_rssi; + + pHddApMetaInfo = + (tSirBatchScanNetworkInfo *)(pHddScanList->scanList + + nextApMetaInfoOffset); + + WMI_MAC_ADDR_TO_CHAR_ARRAY(&network_info->bssid, &bssid[0]); + vos_mem_copy(pHddApMetaInfo->bssid, bssid, IEEE80211_ADDR_LEN); + if (network_info->ssid.ssid_len <= 32) + { + ssid_temp = (u_int8_t *)network_info->ssid.ssid; + for(temp = 0; temp < network_info->ssid.ssid_len; temp++) + { + ssid[temp] = *ssid_temp; + ssid_temp++; + } + ssid[temp] = '\0'; + vos_mem_copy(pHddApMetaInfo->ssid, ssid, + (network_info->ssid.ssid_len + 1)); + WMA_LOGD("ssid %s",pHddApMetaInfo->ssid); + } + else + { + WMA_LOGE("invalid ssid_len %d received from target", + network_info->ssid.ssid_len); + pHddApMetaInfo->ssid[0] = '\0'; + } + pHddApMetaInfo->ch = network_info->ch; + raw_rssi = ((int32_t)network_info->rssi + WMA_TGT_NOISE_FLOOR_DBM); + if (raw_rssi < 0) + raw_rssi = raw_rssi * (-1); + pHddApMetaInfo->rssi = raw_rssi; + pHddApMetaInfo->timestamp = network_info->timestamp; + + WMA_LOGD("ch %d rssi %d timestamp %d",pHddApMetaInfo->ch, + pHddApMetaInfo->rssi, pHddApMetaInfo->timestamp); + + nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo); + network_info++; + } + + nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8)) + + (sizeof(tSirBatchScanNetworkInfo) + * numNetworkInScanList)); + scan_list++; + } + +done: + + pCallbackContext = pMac->pmc.batchScanResultCallbackContext; + /*call hdd callback with set batch scan response data*/ + if (pMac->pmc.batchScanResultCallback) + { + pMac->pmc.batchScanResultCallback(pCallbackContext, (void *)pHddResult); + } + else + { + WMA_LOGE("%s:HDD callback is null", __func__); + } + + /*free if memory was allocated*/ + if (pHddResult) + { + vos_mem_free(pHddResult); + } + + return 0; +} + +/* function : wma_batch_scan_enable_event_handler + * Description : Batch scan enable event handler from target. This function + * gets minimum no of supported batch scan info from target + * and calls HDD supplied callback + * Args : + handle : Pointer to WMA handle + * data : Pointer to batch scan enable data from target + datalen : Length of response data from target + * Returns : + */ +static int +wma_batch_scan_enable_event_handler +( + void *handle, + u_int8_t *data, + u_int32_t datalen +) +{ + void *pCallbackContext; + tSirSetBatchScanRsp hddSetBatchScanRsp; + tp_wma_handle wma = (tp_wma_handle) handle; + WMI_BATCH_SCAN_ENABLED_EVENTID_param_tlvs *param_tlvs; + wmi_batch_scan_enabled_event_fixed_param *fix_param; + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + + param_tlvs = (WMI_BATCH_SCAN_ENABLED_EVENTID_param_tlvs *)data; + fix_param = param_tlvs->fixed_param; + + WMA_LOGD("%s: support number of scan %d",__func__, + fix_param->supportedMscan); + + /*Call HDD callback*/ + if (NULL == pMac) + { + WMA_LOGE("%s: pMac is NULL", __func__); + return -1; + } + hddSetBatchScanRsp.nScansToBatch = fix_param->supportedMscan; + pCallbackContext = pMac->pmc.setBatchScanReqCallbackContext; + /*Call hdd callback with set batch scan response data*/ + if (pMac->pmc.setBatchScanReqCallback) + { + pMac->pmc.setBatchScanReqCallback(pCallbackContext, &hddSetBatchScanRsp); + } + else + { + WMA_LOGE("%s:HDD callback is null", __func__); + } + + return 0; +} +#endif + +#ifdef FEATURE_WLAN_CH_AVOID +/* Process channel to avoid event comes from FW. + */ +static int wma_channel_avoid_evt_handler(void *handle, u_int8_t *event, + u_int32_t len) +{ + wmi_avoid_freq_ranges_event_fixed_param *afr_fixed_param; + wmi_avoid_freq_range_desc *afr_desc; + u_int32_t num_freq_ranges, freq_range_idx; + tSirChAvoidIndType *sca_indication; + VOS_STATUS vos_status; + vos_msg_t sme_msg = {0} ; + WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *param_buf = + (WMI_WLAN_FREQ_AVOID_EVENTID_param_tlvs *) event; + + if (!param_buf) { + WMA_LOGE("Invalid channel avoid event buffer"); + return -EINVAL; + } + + afr_fixed_param = param_buf->fixed_param; + if (!afr_fixed_param) { + WMA_LOGE("Invalid channel avoid event fixed param buffer"); + return -EINVAL; + } + + num_freq_ranges = (afr_fixed_param->num_freq_ranges > SIR_CH_AVOID_MAX_RANGE)? + SIR_CH_AVOID_MAX_RANGE:afr_fixed_param->num_freq_ranges; + + WMA_LOGD("Channel avoid event received with %d ranges", num_freq_ranges); + for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; freq_range_idx++) { + afr_desc = (wmi_avoid_freq_range_desc *) ((void *)param_buf->avd_freq_range + + freq_range_idx * sizeof(wmi_avoid_freq_range_desc)); + WMA_LOGD("range %d: tlv id = %u, start freq = %u, end freq = %u", + freq_range_idx, + afr_desc->tlv_header, + afr_desc->start_freq, + afr_desc->end_freq); + } + + sca_indication = (tSirChAvoidIndType *) + vos_mem_malloc(sizeof(tSirChAvoidIndType)); + if (!sca_indication) { + WMA_LOGE("Invalid channel avoid indication buffer"); + return -EINVAL; + } + + sca_indication->avoid_range_count = num_freq_ranges; + for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; freq_range_idx++) { + afr_desc = (wmi_avoid_freq_range_desc *) ((void *)param_buf->avd_freq_range + + freq_range_idx * sizeof(wmi_avoid_freq_range_desc)); + sca_indication->avoid_freq_range[freq_range_idx].start_freq = + afr_desc->start_freq; + sca_indication->avoid_freq_range[freq_range_idx].end_freq = + afr_desc->end_freq; + } + + sme_msg.type = eWNI_SME_CH_AVOID_IND; + sme_msg.bodyptr = sca_indication; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if ( !VOS_IS_STATUS_SUCCESS(vos_status) ) + { + WMA_LOGE("Fail to post eWNI_SME_CH_AVOID_IND msg to SME"); + vos_mem_free(sca_indication); + return -EINVAL; + } + + return 0; +} + +/* function : wma_process_ch_avoid_update_req + * Description : handles channel avoid update request + * Args : + * Returns : + */ +VOS_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle, + tSirChAvoidUpdateReq *ch_avoid_update_req) +{ + int status = 0; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp; + int len = sizeof(wmi_chan_avoid_update_cmd_param); + + if (ch_avoid_update_req == NULL) + { + WMA_LOGE("%s : ch_avoid_update_req is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE", + __func__); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr; + WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_chan_avoid_update_cmd_param)); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_CHAN_AVOID_UPDATE_CMDID); + if (status != EOK) { + WMA_LOGE("wmi_unified_cmd_send" + " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE" + " returned Error %d", + status); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGI("%s: WMA --> WMI_CHAN_AVOID_UPDATE sent through WMI", + __func__); + return VOS_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_CH_AVOID */ + +/* function : wma_scan_completion_timeout + * Description : + * Args : + * Returns : + */ +void wma_scan_completion_timeout(void *data) +{ + tp_wma_handle wma_handle; + tSirScanOffloadEvent *scan_event; + u_int8_t vdev_id; + + WMA_LOGE("%s: Timeout occured for scan command", __func__); + + wma_handle = (tp_wma_handle) data; + + scan_event = (tSirScanOffloadEvent *) vos_mem_malloc + (sizeof(tSirScanOffloadEvent)); + if (!scan_event) { + WMA_LOGE("%s: Memory allocation failed for tSirScanOffloadEvent", __func__); + return; + } + + vdev_id = wma_handle->wma_scan_timer_info.vdev_id; + + if (wma_handle->wma_scan_timer_info.scan_id != + wma_handle->interfaces[vdev_id].scan_info.scan_id) { + vos_mem_free(scan_event); + WMA_LOGE("%s: Scan ID mismatch", __func__); + return; + } + + /* + * To avoid race condition between scan timeout in host and in firmware + * here we should just send abort scan to firmware and do cleanup after + * receiving event from firmware. Since at this moment there will be no + * outstanding scans, aborting should not cause any problem in firmware. + */ + if (wma_handle->interfaces[vdev_id].scan_info.scan_id != 0) { + tAbortScanParams abortScan; + abortScan.SessionId = vdev_id; + WMA_LOGW("%s: Sending abort for timed out scan", __func__); + wma_stop_scan(wma_handle, &abortScan); + } + + return; +} + +/* function : wma_start + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_start(v_VOID_t *vos_ctx) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tp_wma_handle wma_handle; + int status; + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + /* validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGP("%s: Invalid handle", __func__); + vos_status = VOS_STATUS_E_INVAL; + goto end; + } + + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_SCAN_EVENTID, + wma_scan_event_callback); + if (0 != status) { + WMA_LOGP("%s: Failed to register scan callback", __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_ROAM_EVENTID, + wma_roam_event_callback); + if (0 != status) { + WMA_LOGP("%s: Failed to register Roam callback", __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_WOW_WAKEUP_HOST_EVENTID, + wma_wow_wakeup_host_event); + if (status) { + WMA_LOGP("%s: Failed to register wow wakeup host event handler", + __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + +#ifdef FEATURE_WLAN_D0WOW + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_D0_WOW_DISABLE_ACK_EVENTID, + wma_d0_wow_disable_ack_event); + if (status) { + WMA_LOGE("%s: Failed to register D0-WOW disable event handler!", + __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_NLO)) { + + WMA_LOGD("FW supports pno offload, registering nlo match handler"); + + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_NLO_MATCH_EVENTID, + wma_nlo_match_evt_handler); + if (status) { + WMA_LOGE("Failed to register nlo match event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_NLO_SCAN_COMPLETE_EVENTID, + wma_nlo_scan_cmp_evt_handler); + if (status) { + WMA_LOGE("Failed to register nlo scan comp event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + } +#endif + +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) + WMA_LOGE("MCC TX Pause Event Handler register"); + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_TX_PAUSE_EVENTID, + wma_mcc_vdev_tx_pause_evt_handler); +#endif /* QCA_SUPPORT_TXRX_VDEV_PAUSE_LL */ +#ifdef FEATURE_WLAN_BATCH_SCAN + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_BATCH_SCAN)) + { + + WMA_LOGD("FW supports batch scan, registering batch scan handler"); + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_BATCH_SCAN_RESULT_EVENTID, + wma_batch_scan_result_event_handler); + if (status) + { + WMA_LOGE("Failed to register batch scan result event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_BATCH_SCAN_ENABLED_EVENTID, + wma_batch_scan_enable_event_handler); + if (status) + { + WMA_LOGE("Failed to register batch scan enable event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + } + else + { + WMA_LOGE("Target does not support batch scan feature"); + } +#endif + +#ifdef FEATURE_WLAN_CH_AVOID + WMA_LOGD("Registering channel to avoid handler"); + + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_WLAN_FREQ_AVOID_EVENTID, + wma_channel_avoid_evt_handler); + if (status) { + WMA_LOGE("Failed to register channel to avoid event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } +#endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + WMA_LOGD("Registering auto shutdown handler"); + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_HOST_AUTO_SHUTDOWN_EVENTID, wma_auto_shutdown_event_handler); + if (status) { + WMA_LOGE("Failed to register WMI Auto shutdown event handler"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } +#endif + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_THERMAL_MGMT_EVENTID, + wma_thermal_mgmt_evt_handler); + if (status) { + WMA_LOGE("Failed to register thermal mitigation event cb"); + vos_status = VOS_STATUS_E_FAILURE; + goto end; + } + + vos_status = VOS_STATUS_SUCCESS; + +#ifdef QCA_WIFI_FTM + /* + * Tx mgmt attach requires TXRX context which is not created + * in FTM mode as WLANTL_Open will not be called in this mode. + * So skip the TX mgmt attach. + */ + if (vos_get_conparam() == VOS_FTM_MODE) + goto end; +#endif + + vos_status = wma_tx_attach(wma_handle); + if(vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: Failed to register tx management", __func__); + goto end; + } + + /* Initialize scan completion timeout */ + vos_status = vos_timer_init(&wma_handle->wma_scan_comp_timer, + VOS_TIMER_TYPE_SW, + wma_scan_completion_timeout, + wma_handle); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to initialize scan completion timeout"); + goto end; + } + +end: + WMA_LOGD("%s: Exit", __func__); + return vos_status; +} + +/* function : wma_stop + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_stop(v_VOID_t *vos_ctx, tANI_U8 reason) +{ + tp_wma_handle wma_handle; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + WMA_LOGD("%s: Enter", __func__); + + /* validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGP("%s: Invalid handle", __func__); + vos_status = VOS_STATUS_E_INVAL; + goto end; + } + +#ifdef QCA_WIFI_FTM + /* + * Tx mgmt detach requires TXRX context which is not created + * in FTM mode as WLANTL_Open will not be called in this mode. + * So skip the TX mgmt detach. + */ + if (vos_get_conparam() == VOS_FTM_MODE) { + vos_status = VOS_STATUS_SUCCESS; + goto end; + } +#endif + + if (wma_handle->ack_work_ctx) { + vos_flush_work(&wma_handle->ack_work_ctx->ack_cmp_work); + adf_os_mem_free(wma_handle->ack_work_ctx); + wma_handle->ack_work_ctx = NULL; + } + + /* Destroy the timer for scan completion */ + vos_status = vos_timer_destroy(&wma_handle->wma_scan_comp_timer); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to destroy the scan completion timer"); + } + + /* There's no need suspend target which is already down during SSR. */ + if (!vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) { +#ifdef HIF_USB + /* Suspend the target and enable interrupt */ + if (wma_suspend_target(wma_handle, 0)) + WMA_LOGE("Failed to suspend target"); +#else + /* Suspend the target and disable interrupt */ + if (wma_suspend_target(wma_handle, 1)) + WMA_LOGE("Failed to suspend target"); +#endif + } + + vos_status = wma_tx_detach(wma_handle); + if(vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGP("%s: Failed to deregister tx management", __func__); + goto end; + } + +end: + WMA_LOGD("%s: Exit", __func__); + return vos_status; +} + +static void wma_cleanup_vdev_resp(tp_wma_handle wma) +{ + struct wma_target_req *msg, *tmp; + + adf_os_spin_lock_bh(&wma->vdev_respq_lock); + list_for_each_entry_safe(msg, tmp, + &wma->vdev_resp_queue, node) { + list_del(&msg->node); + vos_timer_destroy(&msg->event_timeout); + adf_os_mem_free(msg); + } + adf_os_spin_unlock_bh(&wma->vdev_respq_lock); +} + +VOS_STATUS wma_wmi_service_close(v_VOID_t *vos_ctx) +{ + tp_wma_handle wma_handle; + struct beacon_info *bcn; + int i; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + /* validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* validate the wmi handle */ + if (NULL == wma_handle->wmi_handle) { + WMA_LOGE("%s: Invalid wmi handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* dettach the wmi serice */ + WMA_LOGD("calling wmi_unified_detach"); + wmi_unified_detach(wma_handle->wmi_handle); + wma_handle->wmi_handle = NULL; + + for (i = 0; i < wma_handle->max_bssid; i++) { + bcn = wma_handle->interfaces[i].beacon; + + if (bcn) { + if (bcn->dma_mapped) + adf_nbuf_unmap_single(wma_handle->adf_dev, + bcn->buf, ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(bcn->buf); + vos_mem_free(bcn); + wma_handle->interfaces[i].beacon = NULL; + } + + if (wma_handle->interfaces[i].handle) { + adf_os_mem_free(wma_handle->interfaces[i].handle); + wma_handle->interfaces[i].handle = NULL; + } + } + + vos_mem_free(wma_handle->interfaces); + /* free the wma_handle */ + vos_free_context(wma_handle->vos_context, VOS_MODULE_ID_WDA, wma_handle); + + adf_os_mem_free(((pVosContextType) vos_ctx)->cfg_ctx); + WMA_LOGD("%s: Exit", __func__); + return VOS_STATUS_SUCCESS; +} + +/* + * Detach DFS methods + */ +static void wma_dfs_detach(struct ieee80211com *dfs_ic) +{ + dfs_detach(dfs_ic); + + if (NULL != dfs_ic->ic_curchan) { + OS_FREE(dfs_ic->ic_curchan); + dfs_ic->ic_curchan = NULL; + } + + OS_FREE(dfs_ic); +} + +/* function : wma_close + * Description : + * Args : + * Returns : + */ +VOS_STATUS wma_close(v_VOID_t *vos_ctx) +{ + tp_wma_handle wma_handle; + u_int32_t idx; + u_int8_t ptrn_id; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + /* validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* validate the wmi handle */ + if (NULL == wma_handle->wmi_handle) { + WMA_LOGP("%s: Invalid wmi handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* Free wow pattern cache */ + for (ptrn_id = 0; ptrn_id < wma_handle->wlan_resource_config.num_wow_filters; + ptrn_id++) + wma_free_wow_ptrn(wma_handle, ptrn_id); + + if (vos_get_conparam() != VOS_FTM_MODE) { +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_destroy(&wma_handle->pno_wake_lock); +#endif +#ifdef FEATURE_WLAN_EXTSCAN + vos_wake_lock_destroy(&wma_handle->extscan_wake_lock); +#endif + vos_wake_lock_destroy(&wma_handle->wow_wake_lock); + } + + /* unregister Firmware debug log */ + vos_status = dbglog_deinit(wma_handle->wmi_handle); + if(vos_status != VOS_STATUS_SUCCESS) + WMA_LOGP("%s: dbglog_deinit failed", __func__); + + /* close the vos events */ + vos_event_destroy(&wma_handle->wma_ready_event); + vos_event_destroy(&wma_handle->target_suspend); + vos_event_destroy(&wma_handle->wma_resume_event); + vos_event_destroy(&wma_handle->wow_tx_complete); + vos_event_destroy(&wma_handle->recovery_event); + wma_cleanup_vdev_resp(wma_handle); + for(idx = 0; idx < wma_handle->num_mem_chunks; ++idx) { + adf_os_mem_free_consistent( + wma_handle->adf_dev, + wma_handle->mem_chunks[idx].len, + wma_handle->mem_chunks[idx].vaddr, + wma_handle->mem_chunks[idx].paddr, + adf_os_get_dma_mem_context( + (&(wma_handle->mem_chunks[idx])), + memctx)); + } + +#if defined(QCA_WIFI_FTM) + /* Detach UTF and unregister the handler */ + if (vos_get_conparam() == VOS_FTM_MODE) + wma_utf_detach(wma_handle); +#endif + + if (NULL != wma_handle->dfs_ic){ + wma_dfs_detach(wma_handle->dfs_ic); + wma_handle->dfs_ic = NULL; + } + + if (NULL != wma_handle->pGetRssiReq) { + adf_os_mem_free(wma_handle->pGetRssiReq); + wma_handle->pGetRssiReq = NULL; + } + + WMA_LOGD("%s: Exit", __func__); + return VOS_STATUS_SUCCESS; +} + +static v_VOID_t wma_update_fw_config(tp_wma_handle wma_handle, + struct wma_target_cap *tgt_cap) +{ + /* + * tgt_cap contains default target resource configuration + * which can be modified here, if required + */ + /* Override the no. of max fragments as per platform configuration */ + tgt_cap->wlan_resource_config.max_frag_entries = + MIN(QCA_OL_11AC_TX_MAX_FRAGS, wma_handle->max_frag_entry); + wma_handle->max_frag_entry = tgt_cap->wlan_resource_config.max_frag_entries; +} + +/** + * allocate a chunk of memory at the index indicated and + * if allocation fail allocate smallest size possiblr and + * return number of units allocated. + */ +static u_int32_t wma_alloc_host_mem_chunk(tp_wma_handle wma_handle, + u_int32_t req_id, u_int32_t idx, + u_int32_t num_units, + u_int32_t unit_len) +{ + adf_os_dma_addr_t paddr; + if (!num_units || !unit_len) { + return 0; + } + wma_handle->mem_chunks[idx].vaddr = NULL ; + /** reduce the requested allocation by half until allocation succeeds */ + while(wma_handle->mem_chunks[idx].vaddr == NULL && num_units ) { + wma_handle->mem_chunks[idx].vaddr = adf_os_mem_alloc_consistent( + wma_handle->adf_dev, num_units*unit_len, &paddr, + adf_os_get_dma_mem_context( + (&(wma_handle->mem_chunks[idx])), + memctx)); + if(wma_handle->mem_chunks[idx].vaddr == NULL) { + num_units = (num_units >> 1) ; /* reduce length by half */ + } else { + wma_handle->mem_chunks[idx].paddr = paddr; + wma_handle->mem_chunks[idx].len = num_units*unit_len; + wma_handle->mem_chunks[idx].req_id = req_id; + } + } + return num_units; +} + +#define HOST_MEM_SIZE_UNIT 4 +/* + * allocate amount of memory requested by FW. + */ +static void wma_alloc_host_mem(tp_wma_handle wma_handle, u_int32_t req_id, + u_int32_t num_units, u_int32_t unit_len) +{ + u_int32_t remaining_units,allocated_units, idx; + + /* adjust the length to nearest multiple of unit size */ + unit_len = (unit_len + (HOST_MEM_SIZE_UNIT - 1)) & + (~(HOST_MEM_SIZE_UNIT - 1)); + idx = wma_handle->num_mem_chunks ; + remaining_units = num_units; + while(remaining_units) { + allocated_units = wma_alloc_host_mem_chunk(wma_handle, req_id, + idx, remaining_units, + unit_len); + if (allocated_units == 0) { + WMA_LOGE("FAILED TO ALLOCATED memory unit len %d" + " units requested %d units allocated %d ", + unit_len, num_units, + (num_units - remaining_units)); + wma_handle->num_mem_chunks = idx; + break; + } + remaining_units -= allocated_units; + ++idx; + if (idx == MAX_MEM_CHUNKS ) { + WMA_LOGE("RWACHED MAX CHUNK LIMIT for memory units %d" + " unit len %d requested by FW," + " only allocated %d ", + num_units,unit_len, + (num_units - remaining_units)); + wma_handle->num_mem_chunks = idx; + break; + } + } + wma_handle->num_mem_chunks = idx; +} + +static inline void wma_update_target_services(tp_wma_handle wh, + struct hdd_tgt_services *cfg) +{ + /* STA power save */ + cfg->sta_power_save = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_STA_PWRSAVE); + + /* Enable UAPSD */ + cfg->uapsd = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_AP_UAPSD); + + /* Update AP DFS service */ + cfg->ap_dfs = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_AP_DFS); + + /* Enable 11AC */ + cfg->en_11ac = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_11AC); + if (cfg->en_11ac) + gFwWlanFeatCaps |= (1 << DOT11AC); + + /* Proactive ARP response */ + gFwWlanFeatCaps |= (1 << WLAN_PERIODIC_TX_PTRN); + + /* Enable WOW */ + gFwWlanFeatCaps |= (1 << WOW); + + /* ARP offload */ + cfg->arp_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_ARPNS_OFFLOAD); + + /* Adaptive early-rx */ + cfg->early_rx = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_EARLY_RX); +#ifdef FEATURE_WLAN_SCAN_PNO + /* PNO offload */ + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_NLO)) + cfg->pno_offload = TRUE; +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_BATCH_SCAN)){ + gFwWlanFeatCaps |= (1 << BATCH_SCAN); + } +#endif + +#ifdef FEATURE_WLAN_EXTSCAN + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_EXTSCAN)) { + gFwWlanFeatCaps |= (1 << EXTENDED_SCAN); + } +#endif + cfg->lte_coex_ant_share = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_LTE_ANT_SHARE_SUPPORT); +#ifdef FEATURE_WLAN_TDLS + /* Enable TDLS */ + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS)) { + cfg->en_tdls = 1; + gFwWlanFeatCaps |= (1 << TDLS); + } + /* Enable advanced TDLS features */ + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_TDLS_OFFCHAN)) { + cfg->en_tdls_offchan = 1; + gFwWlanFeatCaps |= (1 << TDLS_OFF_CHANNEL); + } + + cfg->en_tdls_uapsd_buf_sta = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_TDLS_UAPSD_BUFFER_STA); + cfg->en_tdls_uapsd_sleep_sta = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_TDLS_UAPSD_SLEEP_STA); +#endif + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_BEACON_OFFLOAD)) + cfg->beacon_offload = TRUE; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + /* Enable Roam Offload */ + cfg->en_roam_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_ROAM_HO_OFFLOAD); +#endif + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_NAN)) + gFwWlanFeatCaps |= (1 << NAN); + + if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_RTT)) + gFwWlanFeatCaps |= (1 << RTT); +} + +static inline void wma_update_target_ht_cap(tp_wma_handle wh, + struct hdd_tgt_ht_cap *cfg) +{ + /* RX STBC */ + cfg->ht_rx_stbc = !!(wh->ht_cap_info & WMI_HT_CAP_RX_STBC); + + /* TX STBC */ + cfg->ht_tx_stbc = !!(wh->ht_cap_info & WMI_HT_CAP_TX_STBC); + + /* MPDU density */ + cfg->mpdu_density = wh->ht_cap_info & WMI_HT_CAP_MPDU_DENSITY; + + /* HT RX LDPC */ + cfg->ht_rx_ldpc = !!(wh->ht_cap_info & WMI_HT_CAP_LDPC); + + /* HT SGI */ + cfg->ht_sgi_20 = !!(wh->ht_cap_info & WMI_HT_CAP_HT20_SGI); + + cfg->ht_sgi_40 = !!(wh->ht_cap_info & WMI_HT_CAP_HT40_SGI); + + /* RF chains */ + cfg->num_rf_chains = wh->num_rf_chains; + + WMA_LOGD("%s: ht_cap_info - %x ht_rx_stbc - %d, ht_tx_stbc - %d\n\ + mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n\ + ht_sgi_40 - %d num_rf_chains - %d ", __func__, + wh->ht_cap_info, cfg->ht_rx_stbc, cfg->ht_tx_stbc, + cfg->mpdu_density, cfg->ht_rx_ldpc, cfg->ht_sgi_20, + cfg->ht_sgi_40, cfg->num_rf_chains); + +} + +#ifdef WLAN_FEATURE_11AC +static inline void wma_update_target_vht_cap(tp_wma_handle wh, + struct hdd_tgt_vht_cap *cfg) +{ + /* Max MPDU length */ + if (wh->vht_cap_info & IEEE80211_VHTCAP_MAX_MPDU_LEN_3839) + cfg->vht_max_mpdu = 0; + else if (wh->vht_cap_info & IEEE80211_VHTCAP_MAX_MPDU_LEN_7935) + cfg->vht_max_mpdu = 1; + else if (wh->vht_cap_info & IEEE80211_VHTCAP_MAX_MPDU_LEN_11454) + cfg->vht_max_mpdu = 2; + else + cfg->vht_max_mpdu = 0; + + /* supported channel width */ + if (wh->vht_cap_info & IEEE80211_VHTCAP_SUP_CHAN_WIDTH_80) + cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ; + + else if (wh->vht_cap_info & IEEE80211_VHTCAP_SUP_CHAN_WIDTH_160) + cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_160MHZ; + + else if (wh->vht_cap_info & IEEE80211_VHTCAP_SUP_CHAN_WIDTH_80_160) { + cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ; + cfg->supp_chan_width |= 1 << eHT_CHANNEL_WIDTH_160MHZ; + } + + else + cfg->supp_chan_width = 0; + + /* LDPC capability */ + cfg->vht_rx_ldpc = wh->vht_cap_info & IEEE80211_VHTCAP_RX_LDPC; + + /* Guard interval */ + cfg->vht_short_gi_80 = wh->vht_cap_info & IEEE80211_VHTCAP_SHORTGI_80; + cfg->vht_short_gi_160 = wh->vht_cap_info & IEEE80211_VHTCAP_SHORTGI_160; + + /* TX STBC capability */ + cfg->vht_tx_stbc = wh->vht_cap_info & IEEE80211_VHTCAP_TX_STBC; + + /* RX STBC capability */ + cfg->vht_rx_stbc = wh->vht_cap_info & IEEE80211_VHTCAP_RX_STBC; + + cfg->vht_max_ampdu_len_exp = (wh->vht_cap_info & + IEEE80211_VHTCAP_MAX_AMPDU_LEN_EXP) + >> IEEE80211_VHTCAP_MAX_AMPDU_LEN_EXP_S; + + /* SU beamformer cap */ + cfg->vht_su_bformer = wh->vht_cap_info & IEEE80211_VHTCAP_SU_BFORMER; + + /* SU beamformee cap */ + cfg->vht_su_bformee = wh->vht_cap_info & IEEE80211_VHTCAP_SU_BFORMEE; + + /* MU beamformer cap */ + cfg->vht_mu_bformer = wh->vht_cap_info & IEEE80211_VHTCAP_MU_BFORMER; + + /* MU beamformee cap */ + cfg->vht_mu_bformee = wh->vht_cap_info & IEEE80211_VHTCAP_MU_BFORMEE; + + /* VHT Max AMPDU Len exp */ + cfg->vht_max_ampdu_len_exp = wh->vht_cap_info & + IEEE80211_VHTCAP_MAX_AMPDU_LEN_EXP; + + /* VHT TXOP PS cap */ + cfg->vht_txop_ps = wh->vht_cap_info & IEEE80211_VHTCAP_TXOP_PS; + + WMA_LOGD(" %s: max_mpdu %d supp_chan_width %x rx_ldpc %x\n \ + short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n \ + su_bformee %x mu_bformee %x max_ampdu_len_exp %d", + __func__, cfg->vht_max_mpdu, cfg->supp_chan_width, + cfg->vht_rx_ldpc, cfg->vht_short_gi_80, cfg->vht_tx_stbc, + cfg->vht_rx_stbc, cfg->vht_txop_ps, cfg->vht_su_bformee, + cfg->vht_mu_bformee, cfg->vht_max_ampdu_len_exp); +} +#endif /* #ifdef WLAN_FEATURE_11AC */ + +static void wma_update_hdd_cfg(tp_wma_handle wma_handle) +{ + struct hdd_tgt_cfg hdd_tgt_cfg; + void *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, + wma_handle->vos_context); + + hdd_tgt_cfg.reg_domain = wma_handle->reg_cap.eeprom_rd; + hdd_tgt_cfg.eeprom_rd_ext = wma_handle->reg_cap.eeprom_rd_ext; + + switch (wma_handle->phy_capability) { + case WMI_11G_CAPABILITY: + case WMI_11NG_CAPABILITY: + hdd_tgt_cfg.band_cap = eCSR_BAND_24; + break; + case WMI_11A_CAPABILITY: + case WMI_11NA_CAPABILITY: + case WMI_11AC_CAPABILITY: + hdd_tgt_cfg.band_cap = eCSR_BAND_5G; + break; + case WMI_11AG_CAPABILITY: + case WMI_11NAG_CAPABILITY: + default: + hdd_tgt_cfg.band_cap = eCSR_BAND_ALL; + } + + hdd_tgt_cfg.max_intf_count = wma_handle->wlan_resource_config.num_vdevs; + + adf_os_mem_copy(hdd_tgt_cfg.hw_macaddr.bytes, wma_handle->hwaddr, + ATH_MAC_LEN); + + wma_update_target_services(wma_handle, &hdd_tgt_cfg.services); + wma_update_target_ht_cap(wma_handle, &hdd_tgt_cfg.ht_cap); +#ifdef WLAN_FEATURE_11AC + wma_update_target_vht_cap(wma_handle, &hdd_tgt_cfg.vht_cap); +#endif /* #ifdef WLAN_FEATURE_11AC */ + + hdd_tgt_cfg.target_fw_version = wma_handle->target_fw_version; +#ifdef WLAN_FEATURE_LPSS + hdd_tgt_cfg.lpss_support = wma_handle->lpss_support; +#endif + wma_handle->tgt_cfg_update_cb(hdd_ctx, &hdd_tgt_cfg); +} +static wmi_buf_t wma_setup_wmi_init_msg(tp_wma_handle wma_handle, + wmi_service_ready_event_fixed_param *ev, + WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf, + v_SIZE_t *len) +{ + wmi_buf_t buf; + wmi_init_cmd_fixed_param *cmd; + wlan_host_mem_req *ev_mem_reqs; + wmi_abi_version my_vers; + int num_whitelist; + u_int8_t *buf_ptr; + wmi_resource_config *resource_cfg; + wlan_host_memory_chunk *host_mem_chunks; + u_int32_t mem_chunk_len = 0; + u_int16_t idx; + u_int32_t num_units; + + *len = sizeof(*cmd) + sizeof(wmi_resource_config) + WMI_TLV_HDR_SIZE; + mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS); + buf = wmi_buf_alloc(wma_handle->wmi_handle, *len + mem_chunk_len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return NULL; + } + + ev_mem_reqs = param_buf->mem_reqs; + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + cmd = (wmi_init_cmd_fixed_param *) buf_ptr; + resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd)); + host_mem_chunks = (wlan_host_memory_chunk*) + (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config) + + WMI_TLV_HDR_SIZE); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param)); + + *resource_cfg = wma_handle->wlan_resource_config; + WMITLV_SET_HDR(&resource_cfg->tlv_header, + WMITLV_TAG_STRUC_wmi_resource_config, + WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config)); + + /* allocate memory requested by FW */ + if (ev->num_mem_reqs > WMI_MAX_MEM_REQS) { + VOS_ASSERT(0); + adf_nbuf_free(buf); + return NULL; + } + + cmd->num_host_mem_chunks = 0; + for(idx = 0; idx < ev->num_mem_reqs; ++idx) { + num_units = ev_mem_reqs[idx].num_units; + if (ev_mem_reqs[idx].num_unit_info & NUM_UNITS_IS_NUM_PEERS) { + /* + * number of units to allocate is number + * of peers, 1 extra for self peer on + * target. this needs to be fied, host + * and target can get out of sync + */ + num_units = resource_cfg->num_peers + 1; + } + WMA_LOGD("idx %d req %d num_units %d num_unit_info %d unit size %d actual units %d ", + idx, ev_mem_reqs[idx].req_id, + ev_mem_reqs[idx].num_units, + ev_mem_reqs[idx].num_unit_info, + ev_mem_reqs[idx].unit_size, + num_units); + wma_alloc_host_mem(wma_handle, ev_mem_reqs[idx].req_id, + num_units, ev_mem_reqs[idx].unit_size); + } + for(idx = 0; idx < wma_handle->num_mem_chunks; ++idx) { + WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header), + WMITLV_TAG_STRUC_wlan_host_memory_chunk, + WMITLV_GET_STRUCT_TLVLEN(wlan_host_memory_chunk)); + host_mem_chunks[idx].ptr = wma_handle->mem_chunks[idx].paddr; + host_mem_chunks[idx].size = wma_handle->mem_chunks[idx].len; + host_mem_chunks[idx].req_id = + wma_handle->mem_chunks[idx].req_id; + WMA_LOGD("chunk %d len %d requested ,ptr 0x%x ", + idx, host_mem_chunks[idx].size, + host_mem_chunks[idx].ptr) ; + } + cmd->num_host_mem_chunks = wma_handle->num_mem_chunks; + len += (wma_handle->num_mem_chunks * sizeof(wlan_host_memory_chunk)); + WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)), + WMITLV_TAG_ARRAY_STRUC, + (sizeof(wlan_host_memory_chunk) * + wma_handle->num_mem_chunks)); + vos_mem_copy(&wma_handle->target_abi_vers, + ¶m_buf->fixed_param->fw_abi_vers, + sizeof(wmi_abi_version)); + num_whitelist = sizeof(version_whitelist) / + sizeof(wmi_whitelist_version_info); + my_vers.abi_version_0 = WMI_ABI_VERSION_0; + my_vers.abi_version_1 = WMI_ABI_VERSION_1; + my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0; + my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1; + my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2; + my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3; + + wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist, + &my_vers, ¶m_buf->fixed_param->fw_abi_vers, + &cmd->host_abi_vers); + + WMA_LOGD("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x", + __func__, WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0), + WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0), + cmd->host_abi_vers.abi_version_ns_0, + cmd->host_abi_vers.abi_version_ns_1, + cmd->host_abi_vers.abi_version_ns_2, + cmd->host_abi_vers.abi_version_ns_3); + + vos_mem_copy(&wma_handle->final_abi_vers, &cmd->host_abi_vers, + sizeof(wmi_abi_version)); + return buf; +} + +/* Process service ready event and send wmi_init command */ +v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) +{ + wmi_buf_t buf; + v_SIZE_t len; + tp_wma_handle wma_handle = (tp_wma_handle) handle; + struct wma_target_cap target_cap; + WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; + wmi_service_ready_event_fixed_param *ev; + int status; + + WMA_LOGD("%s: Enter", __func__); + + param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) cmd_param_info; + if (!(handle && param_buf)) { + WMA_LOGP("%s: Invalid arguments", __func__); + return; + } + + ev = param_buf->fixed_param; + if (!ev) { + WMA_LOGP("%s: Invalid buffer", __func__); + return; + } + + WMA_LOGA("WMA <-- WMI_SERVICE_READY_EVENTID"); + + wma_handle->phy_capability = ev->phy_capability; + wma_handle->max_frag_entry = ev->max_frag_entry; + wma_handle->num_rf_chains = ev->num_rf_chains; + vos_mem_copy(&wma_handle->reg_cap, param_buf->hal_reg_capabilities, + sizeof(HAL_REG_CAPABILITIES)); + wma_handle->ht_cap_info = ev->ht_cap_info; +#ifdef WLAN_FEATURE_11AC + wma_handle->vht_cap_info = ev->vht_cap_info; + wma_handle->vht_supp_mcs = ev->vht_supp_mcs; +#endif + wma_handle->num_rf_chains = ev->num_rf_chains; + + wma_handle->target_fw_version = ev->fw_build_vers; + + WMA_LOGE("%s: Firmware build version : %08x", + __func__, ev->fw_build_vers); + + if (ev->hw_bd_id) { + wma_handle->hw_bd_id = ev->hw_bd_id; + vos_mem_copy(wma_handle->hw_bd_info, + ev->hw_bd_info, sizeof(ev->hw_bd_info)); + + WMA_LOGE("%s: Board version: %x.%x", + __func__, + wma_handle->hw_bd_info[0], + wma_handle->hw_bd_info[1]); + } else { + wma_handle->hw_bd_id = 0; + vos_mem_zero(wma_handle->hw_bd_info, + sizeof(wma_handle->hw_bd_info)); + WMA_LOGE("%s: Board version is unknown!", __func__); + } + + /* TODO: Recheck below line to dump service ready event */ + /* dbg_print_wmi_service_11ac(ev); */ + + /* wmi service is ready */ + vos_mem_copy(wma_handle->wmi_service_bitmap, + param_buf->wmi_service_bitmap, + sizeof(wma_handle->wmi_service_bitmap)); + /* SWBA event handler for beacon transmission */ + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_HOST_SWBA_EVENTID, + wma_beacon_swba_handler); + if (status) { + WMA_LOGE("Failed to register swba beacon event cb"); + return; + } + +#ifdef WLAN_FEATURE_LPSS + wma_handle->lpss_support = + WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_LPASS); +#endif + + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_CSA_OFFLOAD)) { + WMA_LOGD("%s: FW support CSA offload capability", __func__); + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_CSA_HANDLING_EVENTID, + wma_csa_offload_handler); + if (status) { + WMA_LOGE("Failed to register CSA offload event cb"); + return; + } + } + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_GTK_OFFLOAD)) { + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_GTK_OFFLOAD_STATUS_EVENTID, + wma_gtk_offload_status_event); + if (status) { + WMA_LOGE("Failed to register GTK offload event cb"); + return; + } + } +#endif + + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_P2P_NOA_EVENTID, + wma_p2p_noa_event_handler); + if (status) { + WMA_LOGE("Failed to register WMI_P2P_NOA_EVENTID callback"); + return; + } + status = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_TBTTOFFSET_UPDATE_EVENTID, + wma_tbttoffset_update_event_handler); + if (status) { + WMA_LOGE("Failed to register WMI_TBTTOFFSET_UPDATE_EVENTID callback"); + return; + } + + vos_mem_copy(target_cap.wmi_service_bitmap, + param_buf->wmi_service_bitmap, + sizeof(wma_handle->wmi_service_bitmap)); + target_cap.wlan_resource_config = wma_handle->wlan_resource_config; + wma_update_fw_config(wma_handle, &target_cap); + vos_mem_copy(wma_handle->wmi_service_bitmap, target_cap.wmi_service_bitmap, + sizeof(wma_handle->wmi_service_bitmap)); + wma_handle->wlan_resource_config = target_cap.wlan_resource_config; + + buf = wma_setup_wmi_init_msg(wma_handle, ev, param_buf, &len); + if (!buf) { + WMA_LOGE("Failed to setup buffer for wma init command"); + return; + } + + WMA_LOGA("WMA --> WMI_INIT_CMDID"); + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, WMI_INIT_CMDID); + if (status != EOK) { + WMA_LOGE("Failed to send WMI_INIT_CMDID command"); + wmi_buf_free(buf); + return; + } +} + +/* function : wma_rx_ready_event + * Description : + * Args : + * Retruns : + */ +v_VOID_t wma_rx_ready_event(WMA_HANDLE handle, void *cmd_param_info) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_READY_EVENTID_param_tlvs *param_buf = NULL; + wmi_ready_event_fixed_param *ev = NULL; + + WMA_LOGD("%s: Enter", __func__); + + param_buf = (WMI_READY_EVENTID_param_tlvs *) cmd_param_info; + if (!(wma_handle && param_buf)) { + WMA_LOGP("%s: Invalid arguments", __func__); + VOS_ASSERT(0); + return; + } + + WMA_LOGA("WMA <-- WMI_READY_EVENTID"); + + ev = param_buf->fixed_param; + /* Indicate to the waiting thread that the ready + * event was received */ + wma_handle->wmi_ready = TRUE; + wma_handle->wlan_init_status = ev->status; + + /* + * We need to check the WMI versions and make sure both + * host and fw are compatible. + */ + if (!wmi_versions_are_compatible(&wma_handle->final_abi_vers, + &ev->fw_abi_vers)) { + /* + * Error: Our host version and the given firmware version + * are incompatible. + */ + WMA_LOGE("%s: Error: Incompatible WMI version." + "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x", + __func__, + WMI_VER_GET_MAJOR( + wma_handle->final_abi_vers.abi_version_0), + WMI_VER_GET_MINOR( + wma_handle->final_abi_vers.abi_version_0), + wma_handle->final_abi_vers.abi_version_ns_0, + wma_handle->final_abi_vers.abi_version_ns_1, + wma_handle->final_abi_vers.abi_version_ns_2, + wma_handle->final_abi_vers.abi_version_ns_3, + WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0), + WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0), + ev->fw_abi_vers.abi_version_ns_0, + ev->fw_abi_vers.abi_version_ns_1, + ev->fw_abi_vers.abi_version_ns_2, + ev->fw_abi_vers.abi_version_ns_3); + if (wma_handle->wlan_init_status == WLAN_INIT_STATUS_SUCCESS) { + /* Failed this connection to FW */ + wma_handle->wlan_init_status = + WLAN_INIT_STATUS_GEN_FAILED; + } + } + vos_mem_copy(&wma_handle->final_abi_vers, &ev->fw_abi_vers, + sizeof(wmi_abi_version)); + vos_mem_copy(&wma_handle->target_abi_vers, &ev->fw_abi_vers, + sizeof(wmi_abi_version)); + + /* copy the mac addr */ + WMI_MAC_ADDR_TO_CHAR_ARRAY (&ev->mac_addr, wma_handle->myaddr); + WMI_MAC_ADDR_TO_CHAR_ARRAY (&ev->mac_addr, wma_handle->hwaddr); + + wma_update_hdd_cfg(wma_handle); + + vos_event_set(&wma_handle->wma_ready_event); + + wma_set_dfs_regdomain(wma_handle); + + WMA_LOGD("Exit"); +} + +int wma_set_peer_param(void *wma_ctx, u_int8_t *peer_addr, u_int32_t param_id, + u_int32_t param_value, u_int32_t vdev_id) +{ + tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx; + wmi_peer_set_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + int err; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set_param cmd"); + return -ENOMEM; + } + cmd = (wmi_peer_set_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_set_param_cmd_fixed_param)); + cmd->vdev_id = vdev_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_addr, &cmd->peer_macaddr); + cmd->param_id = param_id; + cmd->param_value = param_value; + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(wmi_peer_set_param_cmd_fixed_param), + WMI_PEER_SET_PARAM_CMDID); + if (err) { + WMA_LOGE("Failed to send set_param cmd"); + adf_os_mem_free(buf); + return -EIO; + } + + return 0; +} + +static void +wma_decap_to_8023 (adf_nbuf_t msdu, struct wma_decap_info_t *info) +{ + struct llc_snap_hdr_t *llc_hdr; + u_int16_t ether_type; + u_int16_t l2_hdr_space; + struct ieee80211_qosframe_addr4 *wh; + u_int8_t local_buf[ETHERNET_HDR_LEN]; + u_int8_t *buf; + struct ethernet_hdr_t *ethr_hdr; + + buf = (u_int8_t *)adf_nbuf_data(msdu); + llc_hdr = (struct llc_snap_hdr_t *)buf; + ether_type = (llc_hdr->ethertype[0] << 8)|llc_hdr->ethertype[1]; + /* do llc remove if needed */ + l2_hdr_space = 0; + if (IS_SNAP(llc_hdr)) { + if (IS_BTEP(llc_hdr)) { + /* remove llc*/ + l2_hdr_space += sizeof(struct llc_snap_hdr_t); + llc_hdr = NULL; + } else if (IS_RFC1042(llc_hdr)) { + if (!(ether_type == ETHERTYPE_AARP || + ether_type == ETHERTYPE_IPX)) { + /* remove llc*/ + l2_hdr_space += sizeof(struct llc_snap_hdr_t); + llc_hdr = NULL; + } + } + } + if (l2_hdr_space > ETHERNET_HDR_LEN) { + buf = adf_nbuf_pull_head(msdu, l2_hdr_space - ETHERNET_HDR_LEN); + } else if (l2_hdr_space < ETHERNET_HDR_LEN) { + buf = adf_nbuf_push_head(msdu, ETHERNET_HDR_LEN - l2_hdr_space); + } + + /* mpdu hdr should be present in info,re-create ethr_hdr based on mpdu hdr*/ + wh = (struct ieee80211_qosframe_addr4 *)info->hdr; + ethr_hdr = (struct ethernet_hdr_t *)local_buf; + switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { + case IEEE80211_FC1_DIR_NODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr1, + ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr2, + ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_TODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr3, + ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr2, + ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_FROMDS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr1, + ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr3, + ETHERNET_ADDR_LEN); + break; + case IEEE80211_FC1_DIR_DSTODS: + adf_os_mem_copy(ethr_hdr->dest_addr, wh->i_addr3, + ETHERNET_ADDR_LEN); + adf_os_mem_copy(ethr_hdr->src_addr, wh->i_addr4, + ETHERNET_ADDR_LEN); + break; + } + + if (llc_hdr == NULL) { + ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff; + ethr_hdr->ethertype[1] = (ether_type) & 0xff; + } else { + u_int32_t pktlen = adf_nbuf_len(msdu) - sizeof(ethr_hdr->ethertype); + ether_type = (u_int16_t)pktlen; + ether_type = adf_nbuf_len(msdu) - sizeof(struct ethernet_hdr_t); + ethr_hdr->ethertype[0] = (ether_type >> 8) & 0xff; + ethr_hdr->ethertype[1] = (ether_type) & 0xff; + } + adf_os_mem_copy(buf, ethr_hdr, ETHERNET_HDR_LEN); +} + +static int32_t +wma_ieee80211_hdrsize(const void *data) +{ + const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data; + int32_t size = sizeof(struct ieee80211_frame); + + if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) + size += IEEE80211_ADDR_LEN; + if (IEEE80211_QOS_HAS_SEQ(wh)) + size += sizeof(u_int16_t); + return size; +} + +/** + * WDA_TxPacket - Sends Tx Frame to TxRx + * This function sends the frame corresponding to the + * given vdev id. + * This is blocking call till the downloading of frame is complete. + */ +VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen, + eFrameType frmType, eFrameTxDir txDir, u_int8_t tid, + pWDATxRxCompFunc tx_frm_download_comp_cb, void *pData, + pWDAAckFnTxComp tx_frm_ota_comp_cb, u_int8_t tx_flag, + u_int8_t vdev_id, bool tdlsFlag) +{ + tp_wma_handle wma_handle = (tp_wma_handle)(wma_context); + int32_t status; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + int32_t is_high_latency; + ol_txrx_vdev_handle txrx_vdev; + enum frame_index tx_frm_index = + GENERIC_NODOWNLD_NOACK_COMP_INDEX; + tpSirMacFrameCtl pFc = (tpSirMacFrameCtl)(adf_nbuf_data(tx_frame)); + u_int8_t use_6mbps = 0; + u_int8_t downld_comp_required = 0; + u_int16_t chanfreq; +#ifdef WLAN_FEATURE_11W + tANI_U8 *pFrame = NULL; + void *pPacket = NULL; + u_int16_t newFrmLen = 0; +#endif /* WLAN_FEATURE_11W */ + struct wma_txrx_node *iface; + tpAniSirGlobal pMac; +#ifdef QCA_PKT_PROTO_TRACE + v_U8_t proto_type = 0; +#endif + + if (NULL == wma_handle) + { + WMA_LOGE("wma_handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + iface = &wma_handle->interfaces[vdev_id]; + pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + /* Get the vdev handle from vdev id */ + txrx_vdev = wma_handle->interfaces[vdev_id].handle; + + if(!txrx_vdev) { + WMA_LOGE("TxRx Vdev Handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + +#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + txrx_vdev->hlTdlsFlag = false; +#endif + + if (frmType >= HAL_TXRX_FRM_MAX) { + WMA_LOGE("Invalid Frame Type Fail to send Frame"); + return VOS_STATUS_E_FAILURE; + } + + if(!pMac) { + WMA_LOGE("pMac Handle is NULL"); + return VOS_STATUS_E_FAILURE; + } + /* + * Currently only support to + * send 80211 Mgmt and 80211 Data are added. + */ + if (!((frmType == HAL_TXRX_FRM_802_11_MGMT) || + (frmType == HAL_TXRX_FRM_802_11_DATA))) { + WMA_LOGE("No Support to send other frames except 802.11 Mgmt/Data"); + return VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_11W + if ((iface && iface->rmfEnabled) && + (frmType == HAL_TXRX_FRM_802_11_MGMT) && + (pFc->subType == SIR_MAC_MGMT_DISASSOC || + pFc->subType == SIR_MAC_MGMT_DEAUTH || + pFc->subType == SIR_MAC_MGMT_ACTION)) { + struct ieee80211_frame *wh = + (struct ieee80211_frame *)adf_nbuf_data(tx_frame); + if(!IEEE80211_IS_BROADCAST(wh->i_addr1) && + !IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (pFc->wep) { + /* Allocate extra bytes for privacy header and trailer */ + newFrmLen = frmLen + IEEE80211_CCMP_HEADERLEN + + IEEE80211_CCMP_MICLEN; + vos_status = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )newFrmLen, + ( void** ) &pFrame, + ( void** ) &pPacket ); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: Failed to allocate %d bytes for RMF status " + "code (%x)", __func__, newFrmLen, vos_status); + /* Free the original packet memory */ + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pData, ( void* ) tx_frame ); + goto error; + } + + /* + * Initialize the frame with 0's and only fill + * MAC header and data, Keep the CCMP header and + * trailer as 0's, firmware shall fill this + */ + vos_mem_set( pFrame, newFrmLen , 0 ); + vos_mem_copy( pFrame, wh, sizeof(*wh)); + vos_mem_copy( pFrame + sizeof(*wh) + IEEE80211_CCMP_HEADERLEN, + pData + sizeof(*wh), frmLen - sizeof(*wh)); + + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pData, ( void* ) tx_frame ); + tx_frame = pPacket; + frmLen = newFrmLen; + } + } else { + /* Allocate extra bytes for MMIE */ + newFrmLen = frmLen + IEEE80211_MMIE_LEN; + vos_status = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )newFrmLen, + ( void** ) &pFrame, + ( void** ) &pPacket ); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: Failed to allocate %d bytes for RMF status " + "code (%x)", __func__, newFrmLen, vos_status); + /* Free the original packet memory */ + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pData, ( void* ) tx_frame ); + goto error; + } + /* + * Initialize the frame with 0's and only fill + * MAC header and data. MMIE field will be + * filled by vos_attach_mmie API + */ + vos_mem_set( pFrame, newFrmLen , 0 ); + vos_mem_copy( pFrame, wh, sizeof(*wh)); + vos_mem_copy( pFrame + sizeof(*wh), + pData + sizeof(*wh), frmLen - sizeof(*wh)); + if (!vos_attach_mmie(iface->key.key, + iface->key.key_id[0].ipn, + WMA_IGTK_KEY_INDEX_4, + pFrame, + pFrame+newFrmLen, newFrmLen)) { + WMA_LOGP("%s: Failed to attach MMIE at the end of " + "frame", __func__); + /* Free the original packet memory */ + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pData, ( void* ) tx_frame ); + goto error; + } + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pData, ( void* ) tx_frame ); + tx_frame = pPacket; + frmLen = newFrmLen; + } + } +#endif /* WLAN_FEATURE_11W */ + + if ((frmType == HAL_TXRX_FRM_802_11_MGMT) && + (pFc->subType == SIR_MAC_MGMT_PROBE_RSP)) { + u_int64_t adjusted_tsf_le; + struct ieee80211_frame *wh = + (struct ieee80211_frame *)adf_nbuf_data(tx_frame); + + /* Make the TSF offset negative to match TSF in beacons */ + adjusted_tsf_le = cpu_to_le64(0ULL - + wma_handle->interfaces[vdev_id].tsfadjust); + A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le)); + } + if (frmType == HAL_TXRX_FRM_802_11_DATA) { + adf_nbuf_t ret; + adf_nbuf_t skb = (adf_nbuf_t)tx_frame; + ol_txrx_pdev_handle pdev = + vos_get_context(VOS_MODULE_ID_TXRX, wma_handle->vos_context); + + struct wma_decap_info_t decap_info; + struct ieee80211_frame *wh = + (struct ieee80211_frame *)adf_nbuf_data(skb); + v_TIME_t curr_timestamp = vos_timer_get_system_ticks(); + + if (pdev == NULL) { + WMA_LOGE("%s: pdev pointer is not available", __func__); + return VOS_STATUS_E_FAULT; + } + + /* + * 1) TxRx Module expects data input to be 802.3 format + * So Decapsulation has to be done. + * 2) Only one Outstanding Data pending for Ack is allowed + */ + if (tx_frm_ota_comp_cb) { + if (wma_handle->umac_data_ota_ack_cb) { + /* + * If last data frame was sent more than 5 seconds + * ago and still we did not receive ack/nack from + * fw then allow Tx of this data frame + */ + if (curr_timestamp >= + wma_handle->last_umac_data_ota_timestamp + 500) { + WMA_LOGE("%s: No Tx Ack for last data frame for more than 5 secs, allow Tx of current data frame", + __func__); + } else { + WMA_LOGE("%s: Already one Data pending for Ack, reject Tx of data frame", + __func__); + return VOS_STATUS_E_FAILURE; + } + } + } else { + /* + * Data Frames are sent through TxRx Non Standard Data Path + * so Ack Complete Cb is must + */ + WMA_LOGE("No Ack Complete Cb. Don't Allow"); + return VOS_STATUS_E_FAILURE; + } + + /* Take out 802.11 header from skb */ + decap_info.hdr_len = wma_ieee80211_hdrsize(wh); + adf_os_mem_copy(decap_info.hdr, wh, decap_info.hdr_len); + adf_nbuf_pull_head(skb, decap_info.hdr_len); + + /* Decapsulate to 802.3 format */ + wma_decap_to_8023(skb, &decap_info); + + /* Zero out skb's context buffer for the driver to use */ + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + + /* Do the DMA Mapping */ + adf_nbuf_map_single(pdev->osdev, skb, ADF_OS_DMA_TO_DEVICE); + + /* Terminate the (single-element) list of tx frames */ + skb->next = NULL; + + /* Store the Ack Complete Cb */ + wma_handle->umac_data_ota_ack_cb = tx_frm_ota_comp_cb; + + /* Store the timestamp and nbuf for this data Tx */ + wma_handle->last_umac_data_ota_timestamp = curr_timestamp; + wma_handle->last_umac_data_nbuf = skb; + + /* Send the Data frame to TxRx in Non Standard Path */ +#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + txrx_vdev->hlTdlsFlag = tdlsFlag; +#endif + ret = ol_tx_non_std(txrx_vdev, ol_tx_spec_no_free, skb); +#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) + txrx_vdev->hlTdlsFlag = false; +#endif + if (ret) { + WMA_LOGE("TxRx Rejected. Fail to do Tx"); + adf_nbuf_unmap_single(pdev->osdev, skb, ADF_OS_DMA_TO_DEVICE); + /* Call Download Cb so that umac can free the buffer */ + if (tx_frm_download_comp_cb) + tx_frm_download_comp_cb(wma_handle->mac_context, + tx_frame, + WMA_TX_FRAME_BUFFER_FREE); + wma_handle->umac_data_ota_ack_cb = NULL; + wma_handle->last_umac_data_nbuf = NULL; + return VOS_STATUS_E_FAILURE; + } + + /* Call Download Callback if passed */ + if (tx_frm_download_comp_cb) + tx_frm_download_comp_cb(wma_handle->mac_context, + tx_frame, + WMA_TX_FRAME_BUFFER_NO_FREE); + + return VOS_STATUS_SUCCESS; + } + + is_high_latency = wdi_out_cfg_is_high_latency( + txrx_vdev->pdev->ctrl_pdev); + + downld_comp_required = tx_frm_download_comp_cb && is_high_latency; + + /* Fill the frame index to send */ + if(pFc->type == SIR_MAC_MGMT_FRAME) { + if(tx_frm_ota_comp_cb) { + if(downld_comp_required) + tx_frm_index = + GENERIC_DOWNLD_COMP_ACK_COMP_INDEX; + else + tx_frm_index = + GENERIC_NODOWLOAD_ACK_COMP_INDEX; + + /* Store the Ack Cb sent by UMAC */ + if(pFc->subType < SIR_MAC_MGMT_RESERVED15) { + wma_handle->umac_ota_ack_cb[pFc->subType] = + tx_frm_ota_comp_cb; + } +#ifdef QCA_PKT_PROTO_TRACE + if (pFc->subType == SIR_MAC_MGMT_ACTION) + proto_type = vos_pkt_get_proto_type(tx_frame, + pMac->fEnableDebugLog, + NBUF_PKT_TRAC_TYPE_MGMT_ACTION); + if (proto_type & NBUF_PKT_TRAC_TYPE_MGMT_ACTION) + vos_pkt_trace_buf_update("WM:T:MACT"); + adf_nbuf_trace_set_proto_type(tx_frame, proto_type); +#endif /* QCA_PKT_PROTO_TRACE */ + } else { + if(downld_comp_required) + tx_frm_index = + GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX; + else + tx_frm_index = + GENERIC_NODOWNLD_NOACK_COMP_INDEX; + } + } + + /* + * If Dowload Complete is required + * Wait for download complete + */ + if(downld_comp_required) { + /* Store Tx Comp Cb */ + wma_handle->tx_frm_download_comp_cb = tx_frm_download_comp_cb; + + /* Reset the Tx Frame Complete Event */ + vos_status = vos_event_reset( + &wma_handle->tx_frm_download_comp_event); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: Event Reset failed tx comp event %x", + __func__, vos_status); + goto error; + } + } + + /* If the frame has to be sent at BD Rate2 inform TxRx */ + if(tx_flag & HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) + use_6mbps = 1; + + if (wma_handle->roam_preauth_scan_state == WMA_ROAM_PREAUTH_ON_CHAN) { + chanfreq = wma_handle->roam_preauth_chanfreq; + WMA_LOGI("%s: Preauth frame on channel %d", __func__, chanfreq); + } else if(pFc->subType == SIR_MAC_MGMT_PROBE_RSP){ + chanfreq = wma_handle->interfaces[vdev_id].mhz; + WMA_LOGI("%s: Probe response frame on channel %d", __func__, chanfreq); + WMA_LOGI("%s: Probe response frame on vdev id %d", __func__, vdev_id); + } else { + chanfreq = 0; + } + if (pMac->fEnableDebugLog & 0x1) { + if ((pFc->type == SIR_MAC_MGMT_FRAME) && + (pFc->subType != SIR_MAC_MGMT_PROBE_REQ) && + (pFc->subType != SIR_MAC_MGMT_PROBE_RSP)) { + WMA_LOGE("TX MGMT - Type %hu, SubType %hu", + pFc->type, pFc->subType); + } + } + /* Hand over the Tx Mgmt frame to TxRx */ + status = wdi_in_mgmt_send(txrx_vdev, tx_frame, tx_frm_index, use_6mbps, chanfreq); + + /* + * Failed to send Tx Mgmt Frame + */ + if (status) { + /* Call Download Cb so that umac can free the buffer */ + if (tx_frm_download_comp_cb) + tx_frm_download_comp_cb(wma_handle->mac_context, + tx_frame, + WMA_TX_FRAME_BUFFER_FREE); + WMA_LOGP("%s: Failed to send Mgmt Frame", __func__); + goto error; + } + + if (!tx_frm_download_comp_cb) + return VOS_STATUS_SUCCESS; + + /* + * Wait for Download Complete + * if required + */ + if (downld_comp_required) { + /* + * Wait for Download Complete + * @ Integrated : Dxe Complete + * @ Discrete : Target Download Complete + */ + vos_status = vos_wait_single_event( + &wma_handle->tx_frm_download_comp_event, + WMA_TX_FRAME_COMPLETE_TIMEOUT); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("Wait Event failed txfrm_comp_event"); + /* + * @Integrated: Something Wrong with Dxe + * TODO: Some Debug Code + * Here We need to trigger SSR since + * since system went into a bad state where + * we didn't get Download Complete for almost + * WMA_TX_FRAME_COMPLETE_TIMEOUT (1 sec) + */ + } + } else { + /* + * For Low Latency Devices + * Call the download complete + * callback once the frame is successfully + * given to txrx module + */ + tx_frm_download_comp_cb(wma_handle->mac_context, tx_frame, + WMA_TX_FRAME_BUFFER_NO_FREE); + } + + return VOS_STATUS_SUCCESS; + +error: + wma_handle->tx_frm_download_comp_cb = NULL; + return VOS_STATUS_E_FAILURE; +} + +/* function :wma_setneedshutdown + * Description : + * Args : + * Returns : + */ +v_VOID_t wma_setneedshutdown(v_VOID_t *vos_ctx) +{ + tp_wma_handle wma_handle; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + if (NULL == wma_handle) { + WMA_LOGP("%s: Invalid arguments", __func__); + VOS_ASSERT(0); + return; + } + + wma_handle->needShutdown = TRUE; + WMA_LOGD("%s: Exit", __func__); +} + +/* function : wma_rx_ready_event + * Description : + * Args : + * Returns : + */ + v_BOOL_t wma_needshutdown(v_VOID_t *vos_ctx) + { + tp_wma_handle wma_handle; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + if (NULL == wma_handle) { + WMA_LOGP("%s: Invalid arguments", __func__); + VOS_ASSERT(0); + return 0; + } + + WMA_LOGD("%s: Exit", __func__); + return wma_handle->needShutdown; +} + +VOS_STATUS wma_wait_for_ready_event(WMA_HANDLE handle) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + VOS_STATUS vos_status; + + /* wait until WMI_READY_EVENTID received from FW */ + vos_status = vos_wait_single_event( &(wma_handle->wma_ready_event), + WMA_READY_EVENTID_TIMEOUT ); + + if (VOS_STATUS_SUCCESS != vos_status) { + WMA_LOGP("%s: Timeout waiting for ready event from FW", __func__); + vos_status = VOS_STATUS_E_FAILURE; + } + return vos_status; +} + +int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_pdev_suspend_cmd_fixed_param* cmd; + wmi_buf_t wmibuf; + u_int32_t len = sizeof(*cmd); + struct ol_softc *scn; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("WMA is closed. can not issue suspend cmd"); + return -EINVAL; + } + /* + * send the comand to Target to ignore the + * PCIE reset so as to ensure that Host and target + * states are in sync + */ + wmibuf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (wmibuf == NULL) { + return -1; + } + + cmd = (wmi_pdev_suspend_cmd_fixed_param *) wmi_buf_data(wmibuf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_suspend_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_suspend_cmd_fixed_param)); + if (disable_target_intr) { + cmd->suspend_opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; + } + else { + cmd->suspend_opt = WMI_PDEV_SUSPEND; + } + vos_event_reset(&wma_handle->target_suspend); + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmibuf, len, + WMI_PDEV_SUSPEND_CMDID)) { + adf_nbuf_free(wmibuf); + return -1; + } + + + wmi_set_target_suspend(wma_handle->wmi_handle, TRUE); + + if (vos_wait_single_event(&wma_handle->target_suspend, + WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) + != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to get ACK from firmware for pdev suspend"); + wmi_set_target_suspend(wma_handle->wmi_handle, FALSE); + return -1; + } + + scn = vos_get_context(VOS_MODULE_ID_HIF,wma_handle->vos_context); + + if (scn == NULL) { + WMA_LOGE("%s: Failed to get HIF context", __func__); + VOS_ASSERT(0); + return -1; + } + + HTCCancelDeferredTargetSleep(scn); + + return 0; +} + +void wma_target_suspend_acknowledge(void *context) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + int wow_nack = *((int *)context); + + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + + wma->wow_nack = wow_nack; + vos_event_set(&wma->target_suspend); + if (wow_nack) + vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, WMA_WAKE_LOCK_TIMEOUT); +} + +int wma_resume_target(WMA_HANDLE handle) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_buf_t wmibuf; + wmi_pdev_resume_cmd_fixed_param *cmd; + int ret; + int timeout = 0; + int wmi_pending_cmds; + + wmibuf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (wmibuf == NULL) { + return -1; + } + cmd = (wmi_pdev_resume_cmd_fixed_param *) wmi_buf_data(wmibuf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_resume_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_resume_cmd_fixed_param)); + cmd->reserved0 = 0; + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, wmibuf, sizeof(*cmd), + WMI_PDEV_RESUME_CMDID); + if(ret != EOK) { + WMA_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); + wmi_buf_free(wmibuf); + } + wmi_pending_cmds = wmi_get_pending_cmds(wma_handle->wmi_handle); + while (wmi_pending_cmds && timeout++ < WMA_MAX_RESUME_RETRY) { + msleep(1); + wmi_pending_cmds = wmi_get_pending_cmds(wma_handle->wmi_handle); + } + + if (wmi_pending_cmds) { + WMA_LOGE("Failed to deliver WMI_PDEV_RESUME_CMDID command %d\n", timeout); + ret = -1; + } + + if (EOK == ret) + wmi_set_target_suspend(wma_handle->wmi_handle, FALSE); + + return ret; +} + +void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA) +{ +} +/* TODO: Below is stub should be removed later */ +void WDI_DS_ActivateTrafficStats(void) +{ +} +/* + * Function fills the rx packet meta info from the the vos packet + */ +VOS_STATUS WDA_DS_PeekRxPacketInfo(vos_pkt_t *pkt, v_PVOID_t *pkt_meta, + v_BOOL_t bSwap) +{ + /* Sanity Check */ + if(pkt == NULL) { + WMA_LOGE("wma:Invalid parameter sent on wma_peek_rx_pkt_info"); + return VOS_STATUS_E_FAULT; + } + + *pkt_meta = &(pkt->pkt_meta); + + return VOS_STATUS_SUCCESS; +} + +/* + * Function to lookup MAC address from vdev ID + */ +u_int8_t *wma_get_vdev_address_by_vdev_id(u_int8_t vdev_id) +{ + tp_wma_handle wma; + + wma = vos_get_context(VOS_MODULE_ID_WDA, + vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + if (!wma) { + WMA_LOGE("%s: Invalid WMA handle", __func__); + return NULL; + } + + if (vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id); + return NULL; + } + + return wma->interfaces[vdev_id].addr; +} + +/* + * Function to get the beacon buffer from vdev ID + * Note: The buffer returned must be freed explicitly by caller + */ +void *wma_get_beacon_buffer_by_vdev_id(u_int8_t vdev_id, u_int32_t *buffer_size) +{ + tp_wma_handle wma; + struct beacon_info *beacon; + u_int8_t *buf; + u_int32_t buf_size; + + wma = vos_get_context(VOS_MODULE_ID_WDA, + vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + + if (!wma) { + WMA_LOGE("%s: Invalid WMA handle", __func__); + return NULL; + } + + if (vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %u", __func__, vdev_id); + return NULL; + } + + if (!wma_is_vdev_in_ap_mode(wma, vdev_id)) { + WMA_LOGE("%s: vdevid %d is not in AP mode", + __func__, vdev_id); + return NULL; + } + + beacon = wma->interfaces[vdev_id].beacon; + + if (!beacon) { + WMA_LOGE("%s: beacon invalid", __func__); + return NULL; + } + + adf_os_spin_lock_bh(&beacon->lock); + + buf_size = adf_nbuf_len(beacon->buf); + buf = adf_os_mem_alloc(NULL, buf_size); + + if (!buf) { + adf_os_spin_unlock_bh(&beacon->lock); + WMA_LOGE("%s: alloc failed for beacon buf", __func__); + return NULL; + } + + adf_os_mem_copy(buf, adf_nbuf_data(beacon->buf), buf_size); + + adf_os_spin_unlock_bh(&beacon->lock); + + if (buffer_size) + *buffer_size = buf_size; + + return buf; +} + +#if defined(QCA_WIFI_FTM) +int wma_utf_rsp(tp_wma_handle wma_handle, u_int8_t **payload, u_int32_t *len) +{ + int ret = -1; + u_int32_t payload_len; + + payload_len = wma_handle->utf_event_info.length; + if (payload_len) { + ret = 0; + + /* + * The first 4 bytes holds the payload size + * and the actual payload sits next to it + */ + *payload = (u_int8_t *)vos_mem_malloc((v_SIZE_t)payload_len + + sizeof(A_UINT32)); + *(A_UINT32*)&(*payload[0]) = wma_handle->utf_event_info.length; + memcpy(*payload + sizeof(A_UINT32), + wma_handle->utf_event_info.data, + payload_len); + wma_handle->utf_event_info.length = 0; + *len = payload_len; + } + + return ret; +} + +static void wma_post_ftm_response(tp_wma_handle wma_handle) +{ + int ret; + u_int8_t *payload; + u_int32_t data_len; + vos_msg_t msg = {0}; + VOS_STATUS status; + + ret = wma_utf_rsp(wma_handle, &payload, &data_len); + + if (ret) { + return; + } + + msg.type = SYS_MSG_ID_FTM_RSP; + msg.bodyptr = payload; + msg.bodyval = 0; + msg.reserved = SYS_MSG_COOKIE; + + status = vos_mq_post_message(VOS_MQ_ID_SYS, &msg); + + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("failed to post ftm response to SYS"); + vos_mem_free(payload); + } +} + +static int +wma_process_utf_event(WMA_HANDLE handle, + u_int8_t *datap, u_int32_t dataplen) +{ + tp_wma_handle wma_handle = (tp_wma_handle)handle; + SEG_HDR_INFO_STRUCT segHdrInfo; + u_int8_t totalNumOfSegments,currentSeq; + WMI_PDEV_UTF_EVENTID_param_tlvs *param_buf; + u_int8_t *data; + u_int32_t datalen; + + param_buf = (WMI_PDEV_UTF_EVENTID_param_tlvs *) datap; + if (!param_buf) { + WMA_LOGE("Get NULL point message from FW"); + return -EINVAL; + } + data = param_buf->data; + datalen = param_buf->num_data; + + + segHdrInfo = *(SEG_HDR_INFO_STRUCT *)&(data[0]); + + wma_handle->utf_event_info.currentSeq = (segHdrInfo.segmentInfo & 0xF); + + currentSeq = (segHdrInfo.segmentInfo & 0xF); + totalNumOfSegments = (segHdrInfo.segmentInfo >> 4) & 0xF; + + datalen = datalen - sizeof(segHdrInfo); + + if (currentSeq == 0) { + wma_handle->utf_event_info.expectedSeq = 0; + wma_handle->utf_event_info.offset = 0; + } else { + if (wma_handle->utf_event_info.expectedSeq != currentSeq) + WMA_LOGE("Mismatch in expecting seq expected" + " Seq %d got seq %d", + wma_handle->utf_event_info.expectedSeq, + currentSeq); + } + + memcpy(&wma_handle->utf_event_info.data[wma_handle->utf_event_info.offset], + &data[sizeof(segHdrInfo)], + datalen); + wma_handle->utf_event_info.offset = wma_handle->utf_event_info.offset + datalen; + wma_handle->utf_event_info.expectedSeq++; + + if (wma_handle->utf_event_info.expectedSeq == totalNumOfSegments) { + if (wma_handle->utf_event_info.offset != segHdrInfo.len) + WMA_LOGE("All segs received total len mismatch.." + " len %zu total len %d", + wma_handle->utf_event_info.offset, + segHdrInfo.len); + + wma_handle->utf_event_info.length = wma_handle->utf_event_info.offset; + } + + wma_post_ftm_response(wma_handle); + + return 0; +} + +void wma_utf_detach(tp_wma_handle wma_handle) +{ + if (wma_handle->utf_event_info.data) { + vos_mem_free(wma_handle->utf_event_info.data); + wma_handle->utf_event_info.data = NULL; + wma_handle->utf_event_info.length = 0; + wmi_unified_unregister_event_handler(wma_handle->wmi_handle, + WMI_PDEV_UTF_EVENTID); + } +} + +void wma_utf_attach(tp_wma_handle wma_handle) +{ + int ret; + + wma_handle->utf_event_info.data = (unsigned char *) + vos_mem_malloc(MAX_UTF_EVENT_LENGTH); + wma_handle->utf_event_info.length = 0; + + ret = wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PDEV_UTF_EVENTID, + wma_process_utf_event); + + if (ret) + WMA_LOGP("%s: Failed to register UTF event callback", __func__); +} + +static int +wmi_unified_pdev_utf_cmd(wmi_unified_t wmi_handle, u_int8_t *utf_payload, + u_int16_t len) +{ + wmi_buf_t buf; + u_int8_t *cmd; + int ret = 0; + static u_int8_t msgref = 1; + u_int8_t segNumber = 0, segInfo, numSegments; + u_int16_t chunk_len, total_bytes; + u_int8_t *bufpos; + SEG_HDR_INFO_STRUCT segHdrInfo; + + bufpos = utf_payload; + total_bytes = len; + ASSERT(total_bytes / MAX_WMI_UTF_LEN == + (u_int8_t)(total_bytes / MAX_WMI_UTF_LEN)); + numSegments = (u_int8_t)(total_bytes / MAX_WMI_UTF_LEN); + + if (len - (numSegments * MAX_WMI_UTF_LEN)) + numSegments++; + + while (len) { + if (len > MAX_WMI_UTF_LEN) + chunk_len = MAX_WMI_UTF_LEN; /* MAX messsage */ + else + chunk_len = len; + + buf = wmi_buf_alloc(wmi_handle, + (chunk_len + sizeof(segHdrInfo) + + WMI_TLV_HDR_SIZE)); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -1; + } + + cmd = (u_int8_t *)wmi_buf_data(buf); + + segHdrInfo.len = total_bytes; + segHdrInfo.msgref = msgref; + segInfo = ((numSegments << 4 ) & 0xF0) | (segNumber & 0xF); + segHdrInfo.segmentInfo = segInfo; + segHdrInfo.pad = 0; + + WMA_LOGD("%s:segHdrInfo.len = %d, segHdrInfo.msgref = %d," + " segHdrInfo.segmentInfo = %d", + __func__, segHdrInfo.len, segHdrInfo.msgref, + segHdrInfo.segmentInfo); + + WMA_LOGD("%s:total_bytes %d segNumber %d totalSegments %d" + "chunk len %d", __func__, total_bytes, segNumber, + numSegments, chunk_len); + + segNumber++; + + WMITLV_SET_HDR(cmd, WMITLV_TAG_ARRAY_BYTE, + (chunk_len + sizeof(segHdrInfo))); + cmd += WMI_TLV_HDR_SIZE; + memcpy(cmd, &segHdrInfo, sizeof(segHdrInfo)); /* 4 bytes */ + memcpy(&cmd[sizeof(segHdrInfo)], bufpos, chunk_len); + + ret = wmi_unified_cmd_send(wmi_handle, buf, + (chunk_len + sizeof(segHdrInfo) + + WMI_TLV_HDR_SIZE), + WMI_PDEV_UTF_CMDID); + + if (ret != EOK) { + WMA_LOGE("Failed to send WMI_PDEV_UTF_CMDID command"); + wmi_buf_free(buf); + break; + } + + len -= chunk_len; + bufpos += chunk_len; + } + + msgref++; + + return ret; +} + +int wma_utf_cmd(tp_wma_handle wma_handle, u_int8_t *data, u_int16_t len) +{ + wma_handle->utf_event_info.length = 0; + return wmi_unified_pdev_utf_cmd(wma_handle->wmi_handle, data, len); +} + +static VOS_STATUS +wma_process_ftm_command(tp_wma_handle wma_handle, + struct ar6k_testmode_cmd_data *msg_buffer) +{ + u_int8_t *data = NULL; + u_int16_t len = 0; + int ret; + + if (!msg_buffer) + return VOS_STATUS_E_INVAL; + + if (vos_get_conparam() != VOS_FTM_MODE) { + WMA_LOGE("FTM command issued in non-FTM mode"); + vos_mem_free(msg_buffer->data); + vos_mem_free(msg_buffer); + return VOS_STATUS_E_NOSUPPORT; + } + + data = msg_buffer->data; + len = msg_buffer->len; + + ret = wma_utf_cmd(wma_handle, data, len); + + vos_mem_free(msg_buffer->data); + vos_mem_free(msg_buffer); + + if (ret) + return VOS_STATUS_E_FAILURE; + + return VOS_STATUS_SUCCESS; +} +#endif + +/* Function to enable/disble Low Power Support(Pdev Specific) */ +VOS_STATUS WDA_SetIdlePsConfig(void *wda_handle, tANI_U32 idle_ps) +{ + int32_t ret; + tp_wma_handle wma = (tp_wma_handle)wda_handle; + + WMA_LOGD("WMA Set Idle Ps Config [1:set 0:clear] val %d", idle_ps); + + /* Set Idle Mode Power Save Config */ + ret = wmi_unified_pdev_set_param(wma->wmi_handle, + WMI_PDEV_PARAM_IDLE_PS_CONFIG, idle_ps); + if(ret) { + WMA_LOGE("Fail to Set Idle Ps Config %d", idle_ps); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Successfully Set Idle Ps Config %d", idle_ps); + return VOS_STATUS_SUCCESS; +} + +eHalStatus wma_set_htconfig(tANI_U8 vdev_id, tANI_U16 ht_capab, int value) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + int ret = -EIO; + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma", __func__); + return eHAL_STATUS_INVALID_PARAMETER; + } + + switch (ht_capab) { + case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LDPC, value); + break; + case WNI_CFG_HT_CAP_INFO_TX_STBC: + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_TX_STBC, value); + break; + case WNI_CFG_HT_CAP_INFO_RX_STBC: + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_RX_STBC, value); + break; + case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: + case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: + WMA_LOGE("%s: ht_capab = %d, value = %d", __func__, ht_capab, value); + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_SGI, value); + if (ret == 0) + wma->interfaces[vdev_id].config.shortgi = value; + break; + default: + WMA_LOGE("%s:INVALID HT CONFIG", __func__); + } + + return (ret)? eHAL_STATUS_FAILURE : eHAL_STATUS_SUCCESS; +} + +eHalStatus WMA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + tAniBool sendRegHint) +{ + if(VOS_STATUS_SUCCESS != vos_nv_setRegDomain(clientCtxt, regId, sendRegHint)) + return eHAL_STATUS_INVALID_PARAMETER; + + return eHAL_STATUS_SUCCESS; +} + +tANI_U8 wma_getFwWlanFeatCaps(tANI_U8 featEnumValue) +{ + return ((gFwWlanFeatCaps & (1 << featEnumValue)) ? TRUE : FALSE); +} + +void wma_send_regdomain_info(u_int32_t reg_dmn, u_int16_t regdmn2G, + u_int16_t regdmn5G, int8_t ctl2G, int8_t ctl5G) +{ + wmi_buf_t buf; + wmi_pdev_set_regdomain_cmd_fixed_param *cmd; + int32_t len = sizeof(*cmd); + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + + if (NULL == wma) { + WMA_LOGE("%s: wma context is NULL", __func__); + return; + } + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return; + } + cmd = (wmi_pdev_set_regdomain_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_set_regdomain_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_pdev_set_regdomain_cmd_fixed_param)); + cmd->reg_domain = reg_dmn; + cmd->reg_domain_2G = regdmn2G; + cmd->reg_domain_5G = regdmn5G; + cmd->conformance_test_limit_2G = ctl2G; + cmd->conformance_test_limit_5G = ctl5G; + + if (wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_PDEV_SET_REGDOMAIN_CMDID)) { + WMA_LOGP("%s: Failed to send pdev set regdomain command", + __func__); + adf_nbuf_free(buf); + } + return; +} + +void wma_get_modeselect(tp_wma_handle wma, u_int32_t *modeSelect) +{ + + switch (wma->phy_capability) { + case WMI_11G_CAPABILITY: + case WMI_11NG_CAPABILITY: + *modeSelect &= ~(REGDMN_MODE_11A | REGDMN_MODE_TURBO | + REGDMN_MODE_108A | REGDMN_MODE_11A_HALF_RATE | + REGDMN_MODE_11A_QUARTER_RATE | REGDMN_MODE_11NA_HT20 | + REGDMN_MODE_11NA_HT40PLUS | REGDMN_MODE_11NA_HT40MINUS | + REGDMN_MODE_11AC_VHT20 | REGDMN_MODE_11AC_VHT40PLUS | + REGDMN_MODE_11AC_VHT40MINUS | REGDMN_MODE_11AC_VHT80); + break; + case WMI_11A_CAPABILITY: + case WMI_11NA_CAPABILITY: + case WMI_11AC_CAPABILITY: + *modeSelect &= ~(REGDMN_MODE_11B | REGDMN_MODE_11G | + REGDMN_MODE_108G | REGDMN_MODE_11NG_HT20 | + REGDMN_MODE_11NG_HT40PLUS | REGDMN_MODE_11NG_HT40MINUS | + REGDMN_MODE_11AC_VHT20_2G | REGDMN_MODE_11AC_VHT40_2G | + REGDMN_MODE_11AC_VHT80_2G); + break; + } +} + +tANI_U8 wma_map_channel(tANI_U8 mapChannel) +{ + return mapChannel; +} + +static eHalStatus wma_set_mimops(tp_wma_handle wma, tANI_U8 vdev_id, int value) +{ + int ret = eHAL_STATUS_SUCCESS; + wmi_sta_smps_force_mode_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_sta_smps_force_mode_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_sta_smps_force_mode_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_smps_force_mode_cmd_fixed_param)); + + cmd->vdev_id = vdev_id; + + switch(value) + { + case 0: + cmd->forced_mode = WMI_SMPS_FORCED_MODE_NONE; + break; + case 1: + cmd->forced_mode = WMI_SMPS_FORCED_MODE_DISABLED; + break; + case 2: + cmd->forced_mode = WMI_SMPS_FORCED_MODE_STATIC; + break; + case 3: + cmd->forced_mode = WMI_SMPS_FORCED_MODE_DYNAMIC; + break; + default: + WMA_LOGE("%s:INVALID Mimo PS CONFIG", __func__); + return eHAL_STATUS_FAILURE; + } + + WMA_LOGD("Setting vdev %d value = %u", vdev_id, value); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_STA_SMPS_FORCE_MODE_CMDID); + if (ret < 0) { + WMA_LOGE("Failed to send set Mimo PS ret = %d", ret); + wmi_buf_free(buf); + } + + return ret; +} + +static eHalStatus wma_set_ppsconfig(tANI_U8 vdev_id, tANI_U16 pps_param, int val) +{ + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); + int ret = -EIO; + u_int32_t pps_val; + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma", __func__); + return eHAL_STATUS_INVALID_PARAMETER; + } + + switch (pps_param) { + case WMA_VHT_PPS_PAID_MATCH: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_PAID_MATCH & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_GID_MATCH: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_GID_MATCH & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_DELIM_CRC_FAIL: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff); + goto pkt_pwr_save_config; + + /* Enable the code below as and when the functionality + * is supported/added in host. + */ +#ifdef NOT_YET + case WMA_VHT_PPS_EARLY_TIM_CLEAR: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_EARLY_DTIM_CLEAR: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_EOF_PAD_DELIM: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_MACADDR_MISMATCH: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_GID_NSTS_ZERO: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff); + goto pkt_pwr_save_config; + case WMA_VHT_PPS_RSSI_CHECK: + pps_val = ((val << 31) & 0xffff0000) | + (PKT_PWR_SAVE_RSSI_CHECK & 0xffff); + goto pkt_pwr_save_config; +#endif +pkt_pwr_save_config: + WMA_LOGD("vdev_id:%d val:0x%x pps_val:0x%x", vdev_id, + val, pps_val); + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_PACKET_POWERSAVE, pps_val); + break; + default: + WMA_LOGE("%s:INVALID PPS CONFIG", __func__); + } + + return (ret)? eHAL_STATUS_FAILURE : eHAL_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_TDLS +static int wma_set_tdls_offchan_mode(WMA_HANDLE handle, + tTdlsChanSwitchParams* pChanSwitchParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_tdls_set_offchan_mode_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); + int ret = 0; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue tdls off channel cmd", + __func__); + ret = -EINVAL; + goto end; + } + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmai_buf_alloc failed", __func__); + ret = -ENOMEM; + goto end; + } + cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param*)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_set_offchan_mode_cmd_fixed_param)); + + WMI_CHAR_ARRAY_TO_MAC_ADDR(pChanSwitchParams->peerMacAddr, + &cmd->peer_macaddr); + cmd->vdev_id = pChanSwitchParams->vdevId; + cmd->offchan_mode = pChanSwitchParams->tdlsSwMode; + cmd->is_peer_responder = pChanSwitchParams->is_responder; + cmd->offchan_num = pChanSwitchParams->tdlsOffCh; + cmd->offchan_bw_bitmap = pChanSwitchParams->tdlsOffChBwOffset; + cmd->offchan_oper_class = pChanSwitchParams->operClass; + + WMA_LOGD("%s: Peer MAC Addr mac_addr31to0: 0x%x, " + "mac_addr47to32: 0x%x", + __func__, cmd->peer_macaddr.mac_addr31to0, + cmd->peer_macaddr.mac_addr47to32); + + WMA_LOGD("%s: vdev_id: %d, " + "off channel mode: %d, " + "off channel Num: %d, " + "off channel offset: 0x%x, " + "is_peer_responder: %d, " + "operating class: %d, ", + __func__, cmd->vdev_id, + cmd->offchan_mode, + cmd->offchan_num, + cmd->offchan_bw_bitmap, + cmd->is_peer_responder, + cmd->offchan_oper_class); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { + WMA_LOGP("%s: failed to send tdls off chan command", __func__); + adf_nbuf_free(wmi_buf); + ret = -EIO; + } + +end: + if (pChanSwitchParams) + vos_mem_free(pChanSwitchParams); + return ret; +} + +/* wmi tdls command sent to firmware to enable/disable tdls for a vdev */ +static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_tdls_set_state_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + t_wma_tdls_mode tdls_mode; + t_wma_tdls_params *wma_tdls = (t_wma_tdls_params *)pwmaTdlsparams; + u_int16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); + int ret = 0; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue fw tdls state cmd", + __func__); + ret = -EINVAL; + goto end_fw_tdls_state; + } + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmai_buf_alloc failed", __func__); + ret = ENOMEM; + goto end_fw_tdls_state; + } + tdls_mode = wma_tdls->tdls_state; + cmd = (wmi_tdls_set_state_cmd_fixed_param *)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_set_state_cmd_fixed_param)); + cmd->vdev_id = wma_tdls->vdev_id; + + if (WMA_TDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode) { + cmd->state = WMI_TDLS_ENABLE_PASSIVE; + } else if (WMA_TDLS_SUPPORT_ENABLED == tdls_mode) { + cmd->state = WMI_TDLS_ENABLE_ACTIVE; + } else { + cmd->state = WMI_TDLS_DISABLE; + } + + cmd->notification_interval_ms = wma_tdls->notification_interval_ms; + cmd->tx_discovery_threshold = wma_tdls->tx_discovery_threshold; + cmd->tx_teardown_threshold = wma_tdls->tx_teardown_threshold; + cmd->rssi_teardown_threshold = wma_tdls->rssi_teardown_threshold; + cmd->rssi_delta = wma_tdls->rssi_delta; + cmd->tdls_options = wma_tdls->tdls_options; + cmd->tdls_peer_traffic_ind_window = + wma_tdls->peer_traffic_ind_window; + cmd->tdls_peer_traffic_response_timeout_ms = + wma_tdls->peer_traffic_response_timeout; + cmd->tdls_puapsd_mask = + wma_tdls->puapsd_mask; + cmd->tdls_puapsd_inactivity_time_ms = + wma_tdls->puapsd_inactivity_time; + cmd->tdls_puapsd_rx_frame_threshold = + wma_tdls->puapsd_rx_frame_threshold; + + WMA_LOGD("%s: tdls_mode: %d, state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "tdls_peer_traffic_ind_window: %d, " + "tdls_peer_traffic_response_timeout: %d, " + "tdls_puapsd_mask: 0x%x, " + "tdls_puapsd_inactivity_time: %d, " + "tdls_puapsd_rx_frame_threshold: %d ", + __func__, tdls_mode, cmd->state, + cmd->notification_interval_ms, + cmd->tx_discovery_threshold, + cmd->tx_teardown_threshold, + cmd->rssi_teardown_threshold, + cmd->rssi_delta, + cmd->tdls_options, + cmd->tdls_peer_traffic_ind_window, + cmd->tdls_peer_traffic_response_timeout_ms, + cmd->tdls_puapsd_mask, + cmd->tdls_puapsd_inactivity_time_ms, + cmd->tdls_puapsd_rx_frame_threshold); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_TDLS_SET_STATE_CMDID)) { + WMA_LOGP("%s: failed to send tdls set state command", __func__); + adf_nbuf_free(wmi_buf); + ret = -EIO; + goto end_fw_tdls_state; + } + WMA_LOGD("%s: vdev_id %d", __func__, wma_tdls->vdev_id); + +end_fw_tdls_state: + if (pwmaTdlsparams) + vos_mem_free(pwmaTdlsparams); + return ret; +} + +static int wma_update_tdls_peer_state(WMA_HANDLE handle, + tTdlsPeerStateParams *peerStateParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_tdls_peer_update_cmd_fixed_param* cmd; + wmi_tdls_peer_capabilities *peer_cap; + wmi_channel *chan_info; + wmi_buf_t wmi_buf; + u_int8_t *buf_ptr; + u_int32_t i; + ol_txrx_pdev_handle pdev; + u_int8_t peer_id; + struct ol_txrx_peer_t *peer; + int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + + sizeof(wmi_tdls_peer_capabilities); + int ret = 0; +#if defined(CONFIG_HL_SUPPORT) + struct ol_txrx_vdev_t *vdev; + bool restore_last_peer = false; +#endif + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__); + ret = -EINVAL; + goto end_tdls_peer_state; + } + + /* peer capability info is valid only when peer state is connected */ + if (WDA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) { + vos_mem_zero(&peerStateParams->peerCap, sizeof(tTdlsPeerCapParams)); + } + + len += WMI_TLV_HDR_SIZE + + sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; + + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + ret = ENOMEM; + goto end_tdls_peer_state; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_update_cmd_fixed_param)); + + cmd->vdev_id = peerStateParams->vdevId; + WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr, &cmd->peer_macaddr); + + switch (peerStateParams->peerState) { + case WDA_TDLS_PEER_STATE_PEERING: + cmd->peer_state = WMI_TDLS_PEER_STATE_PEERING; + break; + case WDA_TDLS_PEER_STATE_CONNECTED: + cmd->peer_state = WMI_TDLS_PEER_STATE_CONNECTED; + break; + case WDA_TDLS_PEER_STATE_TEARDOWN: + cmd->peer_state = WMI_TDLS_PEER_STATE_TEARDOWN; + break; + } + + WMA_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, " + "peer_macaddr.mac_addr31to0: 0x%x, " + "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d", + __func__, cmd->vdev_id, peerStateParams->peerMacAddr, + cmd->peer_macaddr.mac_addr31to0, + cmd->peer_macaddr.mac_addr47to32, cmd->peer_state); + + buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param); + peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr; + WMITLV_SET_HDR(&peer_cap->tlv_header, + WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, + WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); + + if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) + WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); + if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) + WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); + if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) + WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); + if (peerStateParams->peerCap.peerUapsdQueue & 0x01) + WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); + + /* Ack and More Data Ack are sent as 0, so no need to set + * but fill SP + */ + WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, peerStateParams->peerCap.peerMaxSp); + + peer_cap->buff_sta_support = + peerStateParams->peerCap.peerBuffStaSupport; + peer_cap->off_chan_support = + peerStateParams->peerCap.peerOffChanSupport; + peer_cap->peer_curr_operclass = + peerStateParams->peerCap.peerCurrOperClass; + /* self curr operclass is not being used and so pass op class for + * preferred off chan in it. + */ + peer_cap->self_curr_operclass = + peerStateParams->peerCap.opClassForPrefOffChan; + peer_cap->peer_chan_len = + peerStateParams->peerCap.peerChanLen; + peer_cap->peer_operclass_len = + peerStateParams->peerCap.peerOperClassLen; + + WMA_LOGD("%s: peer_operclass_len: %d", + __func__, peer_cap->peer_operclass_len); + for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { + peer_cap->peer_operclass[i] = + peerStateParams->peerCap.peerOperClass[i]; + WMA_LOGD("%s: peer_operclass[%d]: %d", + __func__, i, peer_cap->peer_operclass[i]); + } + + peer_cap->is_peer_responder = + peerStateParams->peerCap.isPeerResponder; + peer_cap->pref_offchan_num = + peerStateParams->peerCap.prefOffChanNum; + peer_cap->pref_offchan_bw = + peerStateParams->peerCap.prefOffChanBandwidth; + + WMA_LOGD("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: %d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num: %d, pref_offchan_bw: %d", + __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, + peer_cap->off_chan_support, peer_cap->peer_curr_operclass, + peer_cap->self_curr_operclass, peer_cap->peer_chan_len, + peer_cap->peer_operclass_len, peer_cap->is_peer_responder, + peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); + + /* next fill variable size array of peer chan info */ + buf_ptr += sizeof(wmi_tdls_peer_capabilities); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen); + chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); + + for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { + WMITLV_SET_HDR(&chan_info->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + chan_info->mhz = + vos_chan_to_freq(peerStateParams->peerCap.peerChan[i].chanId); + chan_info->band_center_freq1 = chan_info->mhz; + chan_info->band_center_freq2 = 0; + + WMA_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); + + if (peerStateParams->peerCap.peerChan[i].dfsSet) { + WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); + WMA_LOGI("chan[%d] DFS[%d]\n", + peerStateParams->peerCap.peerChan[i].chanId, + peerStateParams->peerCap.peerChan[i].dfsSet); + } + + if (chan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); + } else { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); + } + + WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, + peerStateParams->peerCap.peerChan[i].pwr); + + WMI_SET_CHANNEL_REG_POWER(chan_info, + peerStateParams->peerCap.peerChan[i].pwr); + WMA_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, + peerStateParams->peerCap.peerChan[i].pwr); + + chan_info++; + } + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_TDLS_PEER_UPDATE_CMDID)) { + WMA_LOGE("%s: failed to send tdls peer update state command", + __func__); + adf_nbuf_free(wmi_buf); + ret = -EIO; + goto end_tdls_peer_state; + } + + /* in case of teardown, remove peer from fw */ + if (WDA_TDLS_PEER_STATE_TEARDOWN == peerStateParams->peerState) { + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma_handle->vos_context); + if (!pdev) { + WMA_LOGE("%s: Failed to find pdev", __func__); + ret = -EIO; + goto end_tdls_peer_state; + } + + peer = ol_txrx_find_peer_by_addr(pdev, peerStateParams->peerMacAddr, + &peer_id); + if (!peer) { + WMA_LOGE("%s: Failed to get peer handle using peer mac %pM", + __func__, peerStateParams->peerMacAddr); + ret = -EIO; + goto end_tdls_peer_state; + } + +#if defined(CONFIG_HL_SUPPORT) + vdev = peer->vdev; + if (vdev->last_real_peer && (vdev->last_real_peer == peer)) + restore_last_peer = true; +#endif + + WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR + " vdevId: %d", __func__, + MAC_ADDR_ARRAY(peer->mac_addr.raw), peerStateParams->vdevId); + wma_remove_peer(wma_handle, peer->mac_addr.raw, + peerStateParams->vdevId, peer, + VOS_FALSE); +#if defined(CONFIG_HL_SUPPORT) + if (restore_last_peer && (vdev->last_real_peer == NULL)) { + peer = NULL; + peer = ol_txrx_find_peer_by_addr(pdev, vdev->hl_tdls_ap_mac_addr.raw, &peer_id); + if (peer && (peer->peer_ids[0] != HTT_INVALID_PEER_ID)) + vdev->last_real_peer = peer; + } +#endif + } + +end_tdls_peer_state: + if (peerStateParams) + vos_mem_free(peerStateParams); + return ret; +} +#endif /* FEATURE_WLAN_TDLS */ + +/* + * Attach DFS methods to the umac state. + */ +struct ieee80211com* wma_dfs_attach(struct ieee80211com *dfs_ic) +{ + /*Allocate memory for dfs_ic before passing it up to dfs_attach()*/ + dfs_ic = (struct ieee80211com *) + OS_MALLOC(NULL, sizeof(struct ieee80211com), GFP_ATOMIC); + if (dfs_ic == NULL) + { + WMA_LOGE("%s:Allocation of dfs_ic failed %zu", + __func__, sizeof(struct ieee80211com)); + return NULL; + } + OS_MEMZERO(dfs_ic, sizeof (struct ieee80211com)); + /* DFS pattern matching hooks */ + dfs_ic->ic_dfs_attach = ol_if_dfs_attach; + dfs_ic->ic_dfs_disable = ol_if_dfs_disable; + dfs_ic->ic_find_channel = ieee80211_find_channel; + dfs_ic->ic_dfs_enable = ol_if_dfs_enable; + dfs_ic->ic_ieee2mhz = ieee80211_ieee2mhz; + + /* Hardware facing hooks */ + dfs_ic->ic_get_ext_busy = ol_if_dfs_get_ext_busy; + dfs_ic->ic_get_mib_cycle_counts_pct = + ol_if_dfs_get_mib_cycle_counts_pct; + dfs_ic->ic_get_TSF64 = ol_if_get_tsf64; + + /* NOL related hooks */ + dfs_ic->ic_dfs_usenol = ol_if_dfs_usenol; + /* + * Hooks from wma/dfs/ back + * into the PE/SME + * and shared DFS code + */ + dfs_ic->ic_dfs_notify_radar = ieee80211_mark_dfs; + + /* Initializes DFS Data Structures and queues*/ + dfs_attach(dfs_ic); + + return dfs_ic; +} + +/* + * Configures Radar Filters during + * vdev start/channel change/regulatory domain + * change.This Configuration enables to program + * the DFS pattern matching module. + */ +void wma_dfs_configure(struct ieee80211com *ic) +{ + struct ath_dfs_radar_tab_info rinfo; + int dfsdomain; + int radar_enabled_status = 0; + if(ic == NULL) { + WMA_LOGE("%s: DFS ic is Invalid",__func__); + return; + } + + dfsdomain = ic->current_dfs_regdomain; + + /* Fetch current radar patterns from the lmac */ + OS_MEMZERO(&rinfo, sizeof(rinfo)); + + /* + * Look up the current DFS + * regulatory domain and decide + * which radar pulses to use. + */ + switch (dfsdomain) + { + case DFS_FCC_DOMAIN: + WMA_LOGI("%s: DFS-FCC domain",__func__); + rinfo.dfsdomain = DFS_FCC_DOMAIN; + rinfo.dfs_radars = dfs_fcc_radars; + rinfo.numradars = ARRAY_LENGTH(dfs_fcc_radars); + rinfo.b5pulses = dfs_fcc_bin5pulses; + rinfo.numb5radars = ARRAY_LENGTH(dfs_fcc_bin5pulses); + break; + case DFS_ETSI_DOMAIN: + WMA_LOGI("%s: DFS-ETSI domain",__func__); + rinfo.dfsdomain = DFS_ETSI_DOMAIN; + rinfo.dfs_radars = dfs_etsi_radars; + rinfo.numradars = ARRAY_LENGTH(dfs_etsi_radars); + rinfo.b5pulses = NULL; + rinfo.numb5radars = 0; + break; + case DFS_MKK4_DOMAIN: + WMA_LOGI("%s: DFS-MKK4 domain",__func__); + rinfo.dfsdomain = DFS_MKK4_DOMAIN; + rinfo.dfs_radars = dfs_mkk4_radars; + rinfo.numradars = ARRAY_LENGTH(dfs_mkk4_radars); + rinfo.b5pulses = dfs_jpn_bin5pulses; + rinfo.numb5radars = ARRAY_LENGTH(dfs_jpn_bin5pulses); + break; + default: + WMA_LOGI("%s: DFS-UNINT domain",__func__); + rinfo.dfsdomain = DFS_UNINIT_DOMAIN; + rinfo.dfs_radars = NULL; + rinfo.numradars = 0; + rinfo.b5pulses = NULL; + rinfo.numb5radars = 0; + break; + } + + rinfo.dfs_pri_multiplier = ic->dfs_pri_multiplier; + + + /* + * Set the regulatory domain, + * radar pulse table and enable + * radar events if required. + * dfs_radar_enable() returns + * 0 on success and non-zero + * failure. + */ + radar_enabled_status = dfs_radar_enable(ic, &rinfo); + if (radar_enabled_status != DFS_STATUS_SUCCESS) { + WMA_LOGE("%s[%d]: DFS- Radar Detection Enabling Failed", + __func__, __LINE__); + } +} + +/* + * Set the Channel parameters in to DFS module + * Also,configure the DFS radar filters for + * matching the DFS phyerrors. + */ +struct ieee80211_channel * +wma_dfs_configure_channel(struct ieee80211com *dfs_ic, + wmi_channel *chan, + WLAN_PHY_MODE chanmode, + struct wma_vdev_start_req *req) +{ + if(dfs_ic == NULL) + { + WMA_LOGE("%s: DFS ic is Invalid",__func__); + return NULL; + } + dfs_ic->ic_curchan = (struct ieee80211_channel *) OS_MALLOC(NULL, + sizeof(struct ieee80211_channel), + GFP_ATOMIC); + if (dfs_ic->ic_curchan == NULL) + { + WMA_LOGE("%s: allocation of dfs_ic->ic_curchan failed %zu", + __func__, + sizeof(struct ieee80211_channel)); + return NULL; + } + OS_MEMZERO(dfs_ic->ic_curchan, sizeof (struct ieee80211_channel)); + + dfs_ic->ic_curchan->ic_ieee = req->chan; + dfs_ic->ic_curchan->ic_freq = chan->mhz; + dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1 = chan->band_center_freq1; + dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg2 = chan->band_center_freq2; + + if ( (dfs_ic->ic_curchan->ic_ieee >= WMA_11A_CHANNEL_BEGIN) && + (dfs_ic->ic_curchan->ic_ieee <= WMA_11A_CHANNEL_END) ) + { + dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_5GHZ; + } + if(chanmode == MODE_11AC_VHT80) + { + dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_VHT80; + } + if (req->chan_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + { + dfs_ic->ic_curchan->ic_flags |= + (req->vht_capable ? + IEEE80211_CHAN_VHT40PLUS : IEEE80211_CHAN_HT40PLUS); + } + else if (req->chan_offset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + { + dfs_ic->ic_curchan->ic_flags |= + (req->vht_capable ? + IEEE80211_CHAN_VHT40MINUS : IEEE80211_CHAN_HT40MINUS); + } + else if (req->chan_offset == PHY_SINGLE_CHANNEL_CENTERED) + { + dfs_ic->ic_curchan->ic_flags |= + (req->vht_capable ? IEEE80211_CHAN_VHT20 : IEEE80211_CHAN_HT20); + } + dfs_ic->ic_curchan->ic_flagext |= IEEE80211_CHAN_DFS; + + if (req->oper_mode == BSS_OPERATIONAL_MODE_AP) + { + dfs_ic->ic_opmode = IEEE80211_M_HOSTAP; + dfs_ic->vdev_id = req->vdev_id; + } + + dfs_ic->dfs_pri_multiplier = req->dfs_pri_multiplier; + + /* + * Configuring the DFS with current channel and the radar filters + */ + wma_dfs_configure(dfs_ic); + WMA_LOGI("%s: DFS- CHANNEL CONFIGURED",__func__); + return dfs_ic->ic_curchan; +} +/* + * Configure the regulatory domain for DFS radar filter initialization + */ +void wma_set_dfs_regdomain(tp_wma_handle wma) +{ + u_int8_t ctl; + u_int32_t regdmn = wma->reg_cap.eeprom_rd; + u_int32_t regdmn5G; + + if (regdmn < 0) + { + WMA_LOGE("%s:DFS-Invalid regdomain",__func__); + /* + * Set the DFS reg domain to unintlialized domain + * to indicate dfs regdomain configuration failure + */ + wma->dfs_ic->current_dfs_regdomain = DFS_UNINIT_DOMAIN; + return; + } + + regdmn5G = get_regdmn_5g(regdmn); + ctl = regdmn_get_ctl_for_regdmn(regdmn5G); + + if (!ctl) + { + WMA_LOGI("%s:DFS-Invalid CTL",__func__); + /* + * Set the DFS reg domain to unintlialized domain + * to indicate dfs regdomain configuration failure + */ + wma->dfs_ic->current_dfs_regdomain = DFS_UNINIT_DOMAIN; + return; + } + if (ctl == FCC) + { + WMA_LOGI("%s:DFS- CTL = FCC",__func__); + wma->dfs_ic->current_dfs_regdomain = DFS_FCC_DOMAIN; + } + else if (ctl == ETSI) + { + WMA_LOGI("%s:DFS- CTL = ETSI",__func__); + wma->dfs_ic->current_dfs_regdomain = DFS_ETSI_DOMAIN; + } + else if (ctl == MKK) + { + WMA_LOGI("%s:DFS- CTL = MKK",__func__); + wma->dfs_ic->current_dfs_regdomain = DFS_MKK4_DOMAIN; + } + WMA_LOGI("%s: ****** Current Reg Domain: %d *******", __func__, + wma->dfs_ic->current_dfs_regdomain); +} + +int wma_get_channels(struct ieee80211_channel *ichan, + struct wma_dfs_radar_channel_list *chan_list) +{ + uint8_t center_chan = vos_freq_to_chan(ichan->ic_vhtop_ch_freq_seg1); + + chan_list->nchannels = 0; + + if (IEEE80211_IS_CHAN_11AC_VHT80(ichan)) + { + chan_list->nchannels= 4; + chan_list->channels[0] = center_chan - 6; + chan_list->channels[1] = center_chan - 2; + chan_list->channels[2] = center_chan + 2; + chan_list->channels[3] = center_chan + 6; + } + else if(IEEE80211_IS_CHAN_11N_HT40(ichan) || + IEEE80211_IS_CHAN_11AC_VHT40(ichan)) + { + chan_list->nchannels = 2; + chan_list->channels[0] = center_chan - 2; + chan_list->channels[1] = center_chan + 2; + } + else + { + chan_list->nchannels = 1; + chan_list->channels[0] = center_chan; + } + + return chan_list->nchannels; +} + + +/* + * Indicate Radar to SAP/HDD + */ +int wma_dfs_indicate_radar(struct ieee80211com *ic, + struct ieee80211_channel *ichan) +{ + tp_wma_handle wma; + void *hdd_ctx; + struct wma_dfs_radar_indication *radar_event; + struct hdd_dfs_radar_ind hdd_radar_event; + void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tpAniSirGlobal pmac = NULL; + + wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, vos_context); + + if (wma == NULL) + { + WMA_LOGE("%s: DFS- Invalid wma", __func__); + return -ENOENT; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD,wma->vos_context); + pmac = (tpAniSirGlobal) + vos_get_context(VOS_MODULE_ID_PE, wma->vos_context); + + if (wma->dfs_ic != ic) + { + WMA_LOGE("%s:DFS- Invalid WMA handle",__func__); + return -ENOENT; + } + radar_event = (struct wma_dfs_radar_indication *) + vos_mem_malloc(sizeof(struct wma_dfs_radar_indication)); + if (radar_event == NULL) + { + WMA_LOGE("%s:DFS- Invalid radar_event",__func__); + return -ENOENT; + } + + /* + * Do not post multiple Radar events on the same channel. + * But, when DFS test mode is enabled, allow multiple dfs + * radar events to be posted on the same channel. + */ + if ((ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan)) || + ( pmac->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_TRUE) ) + { + wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee; + /* Indicate the radar event to HDD to stop the netif Tx queues*/ + hdd_radar_event.ieee_chan_number = ichan->ic_ieee; + hdd_radar_event.chan_freq = ichan->ic_freq; + hdd_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND; + wma->dfs_radar_indication_cb(hdd_ctx,&hdd_radar_event); + WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD",__func__); + + /* + * Indicate to the radar event to SAP to + * select a new channel and set CSA IE + */ + radar_event->vdev_id = ic->vdev_id; + wma_get_channels(ichan, &radar_event->chan_list); + radar_event->dfs_radar_status = WMA_DFS_RADAR_FOUND; + radar_event->use_nol = ic->ic_dfs_usenol(ic); + wma_send_msg(wma, WDA_DFS_RADAR_IND, (void *)radar_event, 0); + WMA_LOGE("%s:DFS- WDA_DFS_RADAR_IND Message Posted",__func__); + } + + return 0; +} + +static eHalStatus wma_set_smps_params(tp_wma_handle wma, tANI_U8 vdev_id, int value) +{ + int ret = eHAL_STATUS_SUCCESS; + wmi_sta_smps_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + u_int16_t len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s:wmi_buf_alloc failed", __func__); + return -ENOMEM; + } + cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_sta_smps_param_cmd_fixed_param)); + + cmd->vdev_id = vdev_id; + cmd->value = value & WMA_SMPS_MASK_LOWER_16BITS; + cmd->param = (value >> WMA_SMPS_PARAM_VALUE_S) & WMA_SMPS_MASK_UPPER_3BITS; + + WMA_LOGD("Setting vdev %d value = %x param %x", vdev_id, cmd->value, cmd->param); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_STA_SMPS_PARAM_CMDID); + if (ret < 0) { + WMA_LOGE("Failed to send set Mimo PS ret = %d", ret); + wmi_buf_free(buf); + } + + return ret; +} + +VOS_STATUS WMA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + + tp_wma_handle wma_handle; + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, pvosGCtx); + + if (NULL == wma_handle) { + WMA_LOGE("%s: Failed to get wma", __func__); + return VOS_STATUS_E_FAULT; + } + + snprintf(pVersion, versionBufferSize, "%x", (unsigned int)wma_handle->target_fw_version); + return VOS_STATUS_SUCCESS; +} + +void ol_rx_err(ol_pdev_handle pdev, u_int8_t vdev_id, + u_int8_t *peer_mac_addr, int tid, u_int32_t tsf32, + enum ol_rx_err_type err_type, adf_nbuf_t rx_frame, + u_int64_t *pn, u_int8_t key_id) +{ + void *g_vos_ctx = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, g_vos_ctx); + tpSirSmeMicFailureInd mic_err_ind; + struct ether_header *eth_hdr; + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma", __func__); + return; + } + + if (err_type != OL_RX_ERR_TKIP_MIC) + return; + + if (adf_nbuf_len(rx_frame) < sizeof(*eth_hdr)) + return; + eth_hdr = (struct ether_header *) adf_nbuf_data(rx_frame); + mic_err_ind = vos_mem_malloc(sizeof(*mic_err_ind)); + if (!mic_err_ind) { + WMA_LOGE("%s: Failed to allocate memory for MIC indication message", __func__); + return; + } + adf_os_mem_set((void *) mic_err_ind, 0, sizeof(*mic_err_ind)); + + mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND; + mic_err_ind->length = sizeof(*mic_err_ind); + adf_os_mem_copy(mic_err_ind->bssId, + (v_MACADDR_t *) wma->interfaces[vdev_id].bssid, + sizeof(tSirMacAddr)); + adf_os_mem_copy(mic_err_ind->info.taMacAddr, + (v_MACADDR_t *) peer_mac_addr, sizeof(tSirMacAddr)); + adf_os_mem_copy(mic_err_ind->info.srcMacAddr, + (v_MACADDR_t *) eth_hdr->ether_shost, sizeof(tSirMacAddr)); + adf_os_mem_copy(mic_err_ind->info.dstMacAddr, + (v_MACADDR_t *) eth_hdr->ether_dhost, sizeof(tSirMacAddr)); + mic_err_ind->info.keyId = key_id; + mic_err_ind->info.multicast = IEEE80211_IS_MULTICAST(eth_hdr->ether_dhost); + adf_os_mem_copy(mic_err_ind->info.TSC, pn, SIR_CIPHER_SEQ_CTR_SIZE); + wma_send_msg(wma, SIR_HAL_MIC_FAILURE_IND, (void *) mic_err_ind, 0); +} + +void WDA_TxAbort(v_U8_t vdev_id) +{ +#define PEER_ALL_TID_BITMASK 0xffffffff + tp_wma_handle wma; + u_int32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK; + struct wma_txrx_node *iface; + + wma = vos_get_context(VOS_MODULE_ID_WDA, + vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + + iface = &wma->interfaces[vdev_id]; + if (!iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); + return; + } + WMA_LOGA("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid); + iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST); + wdi_in_vdev_pause(iface->handle, OL_TXQ_PAUSE_REASON_TX_ABORT); + + /* Flush all TIDs except MGMT TID for this peer in Target */ + peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); + wmi_unified_peer_flush_tids_send(wma->wmi_handle, iface->bssid, + peer_tid_bitmap, vdev_id); +} + +static void wma_set_vdev_suspend_dtim(tp_wma_handle wma, v_U8_t vdev_id) +{ + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + u_int8_t is_qpower_enabled = wma_is_qpower_enabled(wma); + + if ((iface->type == WMI_VDEV_TYPE_STA) && + (iface->ps_enabled == TRUE) && + (iface->dtimPeriod != 0)) { + int32_t ret; + u_int32_t listen_interval; + u_int32_t max_mod_dtim; + + if (wma->staDynamicDtim) { + if (iface->dtimPeriod < + WMA_DYNAMIC_DTIM_SETTING_THRESHOLD) { + /* Set DTIM Policy to Normal DTIM */ + /* Configure LI = Dynamic DTIM Value */ + listen_interval = wma->staDynamicDtim; + } else { + return; + } + } else if ((wma->staModDtim)&& (wma->staMaxLIModDtim)) { + /* + * When the system is in suspend + * (maximum beacon will be at 1s == 10) + * If maxModulatedDTIM ((MAX_LI_VAL = 10) / AP_DTIM) + * equal or larger than MDTIM (configured in WCNSS_qcom_cfg.ini) + * Set LI to MDTIM * AP_DTIM + * If Dtim = 2 and Mdtim = 2 then LI is 4 + * Else + * Set LI to maxModulatedDTIM * AP_DTIM + */ + max_mod_dtim = wma->staMaxLIModDtim/iface->dtimPeriod; + if (max_mod_dtim >= wma->staModDtim) { + listen_interval = + (wma->staModDtim * iface->dtimPeriod); + } else { + listen_interval = + (max_mod_dtim * iface->dtimPeriod); + } + } else { + return; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LISTEN_INTERVAL, + listen_interval); + if (ret) { + /* Even it fails continue Fw will take default LI */ + WMA_LOGE("Failed to Set Listen Interval vdevId %d", + vdev_id); + } + + WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d", + vdev_id, listen_interval); + + if (is_qpower_enabled) { + WMA_LOGD("disable Qpower in suspend mode!"); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vdev_id, + WMI_STA_PS_ENABLE_QPOWER, + 0); + if (ret) + WMA_LOGE("Failed to disable Qpower in suspend mode!"); + + iface->ps_enabled = TRUE; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DTIM_POLICY , + NORMAL_DTIM); + if (ret) { + /* Set it to Normal DTIM */ + WMA_LOGE("Failed to Set to Normal DTIM vdevId %d", + vdev_id); + } + iface->dtim_policy = NORMAL_DTIM; + WMA_LOGD("Set DTIM Policy to Normal Dtim vdevId %d", vdev_id); + } +} + +static void wma_set_suspend_dtim(tp_wma_handle wma) +{ + u_int8_t i; + + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + + for (i = 0; i < wma->max_bssid; i++) { + if (wma->interfaces[i].handle) { + wma_set_vdev_suspend_dtim(wma, i); + } + } +} + +static void wma_set_vdev_resume_dtim(tp_wma_handle wma, v_U8_t vdev_id) +{ + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + u_int8_t is_qpower_enabled = wma_is_qpower_enabled(wma); + + if ((iface->type == WMI_VDEV_TYPE_STA) && + (iface->ps_enabled == TRUE) && + (iface->dtim_policy == NORMAL_DTIM)) { + int32_t ret; + tANI_U32 cfg_data_val = 0; + /* get mac to acess CFG data base */ + struct sAniSirGlobal *mac = + (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, + wma->vos_context); + /* Set Listen Interval */ + if ((NULL == mac) || (wlan_cfgGetInt(mac, + WNI_CFG_LISTEN_INTERVAL, + &cfg_data_val ) != eSIR_SUCCESS)) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for listen interval"); + cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL; + } + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LISTEN_INTERVAL, + cfg_data_val); + if (ret) { + /* Even it fails continue Fw will take default LI */ + WMA_LOGE("Failed to Set Listen Interval vdevId %d", + vdev_id); + } + + WMA_LOGD("Set Listen Interval vdevId %d Listen Intv %d", + vdev_id, cfg_data_val); + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DTIM_POLICY , + STICK_DTIM); + if (ret) { + /* Set it back to Stick DTIM */ + WMA_LOGE("Failed to Set to Stick DTIM vdevId %d", + vdev_id); + } + iface->dtim_policy = STICK_DTIM; + WMA_LOGD("Set DTIM Policy to Stick Dtim vdevId %d", vdev_id); + + if (is_qpower_enabled) { + WMA_LOGD("enable Qpower in resume mode!"); + ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, + vdev_id, + WMI_STA_PS_ENABLE_QPOWER, + 1); + if (ret) + WMA_LOGE("Failed to enable Qpower in resume mode!"); + } + } +} + +static void wma_set_resume_dtim(tp_wma_handle wma) +{ + u_int8_t i; + + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + + for (i = 0; i < wma->max_bssid; i++) { + if (wma->interfaces[i].handle) { + wma_set_vdev_resume_dtim(wma, i); + } + } +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +void wma_process_roam_synch_complete(WMA_HANDLE handle, + tSirSmeRoamOffloadSynchCnf *synchcnf) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_roam_synch_complete_fixed_param* cmd; + wmi_buf_t wmi_buf; + u_int8_t *buf_ptr; + u_int16_t len; + v_BOOL_t roam_synch_in_progress; + len = sizeof(wmi_roam_synch_complete_fixed_param); + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue roam synch cnf", + __func__); + return; + } + roam_synch_in_progress = + wma_handle->interfaces[synchcnf->sessionId].roam_synch_in_progress; + if (roam_synch_in_progress == VOS_FALSE) { + WMA_LOGE("%s: Dont send the roam synch complete since Roam Synch" + "Propagation is not in Progress", __func__); + return; + } else { + adf_os_spin_lock_bh(&wma_handle->roam_synch_lock); + wma_handle->interfaces[synchcnf->sessionId].roam_synch_in_progress = + VOS_FALSE; + adf_os_spin_unlock_bh(&wma_handle->roam_synch_lock); + } + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return; + } + cmd = (wmi_roam_synch_complete_fixed_param *)wmi_buf_data(wmi_buf); + buf_ptr = (u_int8_t *) cmd; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_synch_complete_fixed_param)); + cmd->vdev_id = synchcnf->sessionId; + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_ROAM_SYNCH_COMPLETE)) { + WMA_LOGP("%s: failed to send roam synch confirmation", __func__); + adf_nbuf_free(wmi_buf); + return; + } + return; +} +void wma_process_roam_synch_fail(WMA_HANDLE handle, + tSirRoamOffloadSynchFail *synchfail) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not clean-up roam synch", + __func__); + return; + } + /* Hand Off Failure could happen as an exception, when a roam synch + * indication is posted to Host, but a roam synch complete is not + * posted to the firmware.So, clear the roam synch in progress + * flag before disconnecting the session through this event.*/ + adf_os_spin_lock_bh(&wma_handle->roam_synch_lock); + wma_handle->interfaces[synchfail->sessionId].roam_synch_in_progress = + VOS_FALSE; + adf_os_spin_unlock_bh(&wma_handle->roam_synch_lock); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h new file mode 100644 index 0000000000000..fa6f7f715237e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h @@ -0,0 +1,1561 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wma.h + \brief Implementation of WMA + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- ----------------------------------------- + 12/03/2013 Ganesh Created module for WMA + Kondabattini + 27/03/2013 Ganesh Rx Mgmt Related added + Babu + ==========================================================================*/ +#ifndef WMA_H +#define WMA_H + +#include "a_types.h" +#include "vos_types.h" +#include "osapi_linux.h" +#include "htc_packet.h" +#include "i_vos_event.h" +#include "wmi_services.h" +#include "wmi_unified.h" +#include "wmi_version.h" +#include "halTypes.h" +#include "cfgApi.h" +#include "vos_status.h" +#include "vos_sched.h" +#include "wlan_hdd_tgt_cfg.h" +#include "ol_txrx_api.h" +#include "sirMacProtDef.h" +#include "wlan_qct_wda.h" +#include "ol_txrx_types.h" +#include "wlan_qct_wda.h" +#include + +/* Platform specific configuration for max. no. of fragments */ +#define QCA_OL_11AC_TX_MAX_FRAGS 2 + +/** Private **/ +#define WMA_CFG_NV_DNLD_TIMEOUT 500 +#define WMA_READY_EVENTID_TIMEOUT 2000 +#define WMA_TGT_SUSPEND_COMPLETE_TIMEOUT 3000 +#define WMA_WAKE_LOCK_TIMEOUT 1000 +#define WMA_MAX_RESUME_RETRY 1000 +#define WMA_RESUME_TIMEOUT 3000 +#define WMA_TGT_WOW_TX_COMPLETE_TIMEOUT 2000 +#define MAX_MEM_CHUNKS 32 +#define WMA_CRASH_INJECT_TIMEOUT 5000 + +/* + In prima 12 HW stations are supported including BCAST STA(staId 0) + and SELF STA(staId 1) so total ASSOC stations which can connect to Prima + SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. */ + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WMA_MAX_SUPPORTED_STAS 38 +#else +#define WMA_MAX_SUPPORTED_STAS 12 +#endif +#define WMA_MAX_SUPPORTED_BSS 5 + +#define FRAGMENT_SIZE 3072 + +#define WMA_INVALID_VDEV_ID 0xFF +#define MAX_MEM_CHUNKS 32 +#define WMA_MAX_VDEV_SIZE 20 +#define WMA_VDEV_TBL_ENTRY_ADD 1 +#define WMA_VDEV_TBL_ENTRY_DEL 0 + + +/* 11A/G channel boundary */ +#define WMA_11A_CHANNEL_BEGIN 34 +#define WMA_11A_CHANNEL_END 165 +#define WMA_11G_CHANNEL_BEGIN 1 +#define WMA_11G_CHANNEL_END 14 + +#define WMA_LOGD(args...) \ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, ## args) +#define WMA_LOGI(args...) \ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, ## args) +#define WMA_LOGW(args...) \ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, ## args) +#define WMA_LOGE(args...) \ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, ## args) +#define WMA_LOGP(args...) \ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, ## args) + +#define WMA_DEBUG_ALWAYS + +#ifdef WMA_DEBUG_ALWAYS +#define WMA_LOGA(fmt, args...) \ + printk(KERN_INFO "%s-%d: " fmt"\n", __func__, __LINE__, ## args) +#else +#define WMA_LOGA(fmt, args...) +#endif + +#define ALIGNED_WORD_SIZE 4 +#define WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE 0x7FFF + +/* Prefix used by scan req ids generated on the host */ +#define WMA_HOST_SCAN_REQID_PREFIX 0xA000 +/* Prefix used by roam scan req ids generated on the host */ +#define WMA_HOST_ROAM_SCAN_REQID_PREFIX 0xA800 +/* Prefix used by scan requestor id on host */ +#define WMA_HOST_SCAN_REQUESTOR_ID_PREFIX 0xA000 +#define WMA_HW_DEF_SCAN_MAX_DURATION 30000 /* 30 secs */ + +/* Max offchannel duration */ +#define WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS (3) +#define WMA_SCAN_NPROBES_DEFAULT (2) +#define WMA_SCAN_IDLE_TIME_DEFAULT (25) +#define WMA_P2P_SCAN_MAX_BURST_DURATION (180) +#define WMA_CTS_DURATION_MS_MAX (32) +#define WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION (40) +#define WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION (120) +#define WMA_DWELL_TIME_PASSIVE_DEFAULT (110) +#define WMA_DWELL_TIME_PROBE_TIME_MAP_SIZE (11) + +#define WMA_SEC_TO_USEC (1000000) + +#define BEACON_TX_BUFFER_SIZE (512) + +typedef struct probeTime_dwellTime { + u_int8_t dwell_time; + u_int8_t probe_time; +} t_probeTime_dwellTime; + +static const t_probeTime_dwellTime + probeTime_dwellTime_map[WMA_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { + {28, 0}, /* 0 SSID */ + {28, 20}, /* 1 SSID */ + {28, 20}, /* 2 SSID */ + {28, 20}, /* 3 SSID */ + {28, 20}, /* 4 SSID */ + {28, 20}, /* 5 SSID */ + {28, 20}, /* 6 SSID */ + {28, 11}, /* 7 SSID */ + {28, 11}, /* 8 SSID */ + {28, 11}, /* 9 SSID */ + {28, 8} /* 10 SSID */ +}; + +/* Roaming default values + * All time and period values are in milliseconds. + * All rssi values are in dB except for WMA_NOISE_FLOOR_DBM_DEFAULT. + */ + +#define WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME (4) +#define WMA_NOISE_FLOOR_DBM_DEFAULT (-96) +#define WMA_ROAM_RSSI_DIFF_DEFAULT (5) +#define WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT (100) +#define WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT (110) +#define WMA_ROAM_MIN_REST_TIME_DEFAULT (50) +#define WMA_ROAM_MAX_REST_TIME_DEFAULT (500) +#define WMA_ROAM_LOW_RSSI_TRIGGER_DEFAULT (20) +#define WMA_ROAM_LOW_RSSI_TRIGGER_VERYLOW (10) +#define WMA_ROAM_BEACON_WEIGHT_DEFAULT (14) +#define WMA_ROAM_OPP_SCAN_PERIOD_DEFAULT (120000) +#define WMA_ROAM_OPP_SCAN_AGING_PERIOD_DEFAULT (WMA_ROAM_OPP_SCAN_PERIOD_DEFAULT * 5) +#define WMA_ROAM_PREAUTH_SCAN_TIME (50) +#define WMA_ROAM_PREAUTH_REST_TIME (0) +#define WMA_ROAM_PREAUTH_MAX_SCAN_TIME (10000) +#define WMA_ROAM_BMISS_FIRST_BCNT_DEFAULT (10) +#define WMA_ROAM_BMISS_FINAL_BCNT_DEFAULT (10) +#define WMA_ROAM_BMISS_FIRST_BCNT_DEFAULT_P2P (15) +#define WMA_ROAM_BMISS_FINAL_BCNT_DEFAULT_P2P (45) + +#define WMA_INVALID_KEY_IDX 0xff +#define WMA_DFS_RADAR_FOUND 1 + +#define WMA_MAX_RF_CHAINS(x) ((1 << x) - 1) +#define WMA_MIN_RF_CHAINS (1) + +#ifdef FEATURE_WLAN_EXTSCAN +#define WMA_MAX_EXTSCAN_MSG_SIZE 1536 +#define WMA_EXTSCAN_REST_TIME 100 +#define WMA_EXTSCAN_MAX_SCAN_TIME 50000 +#define WMA_EXTSCAN_REPEAT_PROBE 10 +#define WMA_EXTSCAN_BURST_DURATION 150 +#endif + +typedef struct { + HTC_ENDPOINT_ID endpoint_id; +}t_cfg_nv_param; + +typedef enum +{ + WMA_DRIVER_TYPE_PRODUCTION = 0, + WMA_DRIVER_TYPE_MFG = 1, + WMA_DRIVER_TYPE_DVT = 2, + WMA_DRIVER_TYPE_INVALID = 0x7FFFFFFF +}t_wma_drv_type; + +typedef enum { + WMA_STATE_OPEN, + WMA_STATE_START, + WMA_STATE_STOP, + WMA_STATE_CLOSE +}t_wma_state; + +#ifdef FEATURE_WLAN_TDLS +typedef enum { + WMA_TDLS_SUPPORT_NOT_ENABLED = 0, + WMA_TDLS_SUPPORT_DISABLED, /* suppress implicit trigger and not respond to the peer */ + WMA_TDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY, /* suppress implicit trigger, but respond to the peer */ + WMA_TDLS_SUPPORT_ENABLED, /* implicit trigger */ +}t_wma_tdls_mode; + +/** TDLS EVENTS */ +enum wma_tdls_peer_notification { + /** tdls discovery recommended for peer (always based + * on tx bytes per second > tx_discover threshold + * NB: notification will be re-sent after + * discovery_request_interval_ms */ + WMA_TDLS_SHOULD_DISCOVER, + /** tdls link tear down recommended for peer + * due to tx bytes per second below tx_teardown_threshold + * NB: this notification sent once */ + WMA_TDLS_SHOULD_TEARDOWN, + /** tx peer TDLS link tear down complete */ + WMA_TDLS_PEER_DISCONNECTED, +}; + +enum wma_tdls_peer_reason { + /** tdls teardown recommended due to low transmits */ + WMA_TDLS_TEARDOWN_REASON_TX, + /** tdls tear down recommended due to packet rates < AP rates */ + WMA_TDLS_TEARDOWN_REASON_RATE, + /** tdls link tear down recommended due to poor RSSI */ + WMA_TDLS_TEARDOWN_REASON_RSSI, + /** tdls link tear down recommended due to offchannel scan */ + WMA_TDLS_TEARDOWN_REASON_SCAN, + /** tdls peer disconnected due to peer deletion */ + WMA_TDLS_DISCONNECTED_REASON_PEER_DELETE, +}; +#endif /* FEATURE_WLAN_TDLS */ + +typedef enum { + /* Roaming preauth channel state */ + WMA_ROAM_PREAUTH_CHAN_NONE, + WMA_ROAM_PREAUTH_CHAN_REQUESTED, + WMA_ROAM_PREAUTH_ON_CHAN, + WMA_ROAM_PREAUTH_CHAN_CANCEL_REQUESTED, + WMA_ROAM_PREAUTH_CHAN_COMPLETED +} t_wma_roam_preauth_chan_state_t; +/* + * memory chunck allocated by Host to be managed by FW + * used only for low latency interfaces like pcie + */ +struct wma_mem_chunk { + u_int32_t *vaddr; + u_int32_t paddr; + adf_os_dma_mem_context(memctx); + u_int32_t len; + u_int32_t req_id; +}; + +typedef struct s_vdev_tbl { + u_int8_t vdev_id; + u_int8_t sta_mac[ETH_ALEN]; + ol_txrx_vdev_handle tx_rx_vdev_handle; + u_int32_t vdev_type; + bool used; +}t_vdev_tbl; + +struct scan_param{ + u_int32_t scan_id; + u_int32_t scan_requestor_id; + tSirP2pScanType p2p_scan_type; +}; + + +#define WMA_BCN_BUF_MAX_SIZE 2500 +#define WMA_NOA_IE_SIZE(num_desc) (2 + (13 * (num_desc))) +#define WMA_MAX_NOA_DESCRIPTORS 4 +struct beacon_info { + adf_nbuf_t buf; + u_int32_t len; + u_int8_t dma_mapped; + u_int32_t tim_ie_offset; + u_int8_t dtim_count; + u_int16_t seq_no; + u_int8_t noa_sub_ie[2 + WMA_NOA_IE_SIZE(WMA_MAX_NOA_DESCRIPTORS)]; + u_int16_t noa_sub_ie_len; + u_int8_t *noa_ie; + u_int16_t p2p_ie_offset; + adf_os_spinlock_t lock; +}; + +struct beacon_tim_ie { + u_int8_t tim_ie; + u_int8_t tim_len; + u_int8_t dtim_count; + u_int8_t dtim_period; + u_int8_t tim_bitctl; + u_int8_t tim_bitmap[1]; +} __ATTRIB_PACK; + +#define WMA_TIM_SUPPORTED_PVB_LENGTH (HAL_NUM_STA / 8) + 1 + + +struct pps { + v_BOOL_t paid_match_enable; + v_BOOL_t gid_match_enable; + v_BOOL_t tim_clear; + v_BOOL_t dtim_clear; + v_BOOL_t eof_delim; + v_BOOL_t mac_match; + v_BOOL_t delim_fail; + v_BOOL_t nsts_zero; + v_BOOL_t rssi_chk; + v_BOOL_t ebt_5g; +}; + +struct qpower_params { + u_int32_t max_ps_poll_cnt; + u_int32_t max_tx_before_wake; + u_int32_t spec_ps_poll_wake_interval; + u_int32_t max_spec_nodata_ps_poll; +}; + +typedef struct { + u_int32_t gtxRTMask[2]; /* for HT and VHT rate masks */ + u_int32_t gtxUsrcfg; /* host request for GTX mask */ + u_int32_t gtxPERThreshold; /* default: 10% */ + u_int32_t gtxPERMargin; /* default: 2% */ + u_int32_t gtxTPCstep; /* default: 1 */ + u_int32_t gtxTPCMin; /* default: 5 */ + u_int32_t gtxBWMask; /* 20/40/80/160 Mhz */ +}gtx_config_t; + +typedef struct { + u_int32_t ani_enable; + u_int32_t ani_poll_len; + u_int32_t ani_listen_len; + u_int32_t ani_ofdm_level; + u_int32_t ani_cck_level; + u_int32_t cwmenable; + u_int32_t cts_cbw; + u_int32_t txchainmask; + u_int32_t rxchainmask; + u_int32_t txpow2g; + u_int32_t txpow5g; + u_int32_t pwrgating; + u_int32_t burst_enable; + u_int32_t burst_dur; +} pdev_cli_config_t; + +typedef struct { + u_int32_t nss; + u_int32_t ldpc; + u_int32_t tx_stbc; + u_int32_t rx_stbc; + u_int32_t shortgi; + u_int32_t rtscts_en; + u_int32_t chwidth; + u_int32_t tx_rate; + u_int32_t ampdu; + u_int32_t amsdu; + u_int32_t erx_adjust; + u_int32_t erx_bmiss_num; + u_int32_t erx_bmiss_cycle; + u_int32_t erx_slop_step; + u_int32_t erx_init_slop; + u_int32_t erx_adj_pause; + u_int32_t erx_dri_sample; + struct pps pps_params; + struct qpower_params qpower_params; + gtx_config_t gtx_info; +} vdev_cli_config_t; + +#define WMA_WOW_PTRN_MASK_VALID 0xFF +#define WMA_NUM_BITS_IN_BYTE 8 + +#define WMA_AP_WOW_DEFAULT_PTRN_MAX 4 +#define WMA_STA_WOW_DEFAULT_PTRN_MAX 4 + +struct wma_wow_ptrn_cache { + u_int8_t vdev_id; + u_int8_t *ptrn; + u_int8_t ptrn_len; + u_int8_t ptrn_offset; + u_int8_t *mask; + u_int8_t mask_len; +}; + +struct wma_wow { + struct wma_wow_ptrn_cache *cache[WOW_MAX_BITMAP_FILTERS]; + u_int8_t no_of_ptrn_cached; + + u_int8_t free_ptrn_id[WOW_MAX_BITMAP_FILTERS]; + u_int8_t total_free_ptrn_id; + u_int8_t used_free_ptrn_id; + + v_BOOL_t magic_ptrn_enable; + v_BOOL_t wow_enable; + v_BOOL_t wow_enable_cmd_sent; + v_BOOL_t deauth_enable; + v_BOOL_t disassoc_enable; + v_BOOL_t bmiss_enable; + v_BOOL_t gtk_pdev_enable; + v_BOOL_t gtk_err_enable[WMA_MAX_SUPPORTED_BSS]; +#ifdef FEATURE_WLAN_LPHB + /* currently supports only vdev 0. + * cache has two entries: one for TCP and one for UDP. + */ + tSirLPHBReq lphb_cache[2]; +#endif +}; +#ifdef WLAN_FEATURE_11W +#define CMAC_IPN_LEN (6) +#define WMA_IGTK_KEY_INDEX_4 (4) +#define WMA_IGTK_KEY_INDEX_5 (5) + +typedef struct { + u_int8_t ipn[CMAC_IPN_LEN]; +} wma_igtk_ipn_t; + +typedef struct { + u_int16_t key_length; + u_int8_t key[CSR_AES_KEY_LEN]; + + /* IPN is maintained per iGTK keyID + * 0th index for iGTK keyID = 4; + * 1st index for iGTK KeyID = 5 + */ + wma_igtk_ipn_t key_id[2]; +} wma_igtk_key_t; +#endif + +#define WMA_BSS_STATUS_STARTED 0x1 +#define WMA_BSS_STATUS_STOPPED 0x2 + +typedef struct { + A_UINT32 vdev_id; + wmi_ssid ssid; + A_UINT32 flags; + A_UINT32 requestor_id; + A_UINT32 disable_hw_ack; + wmi_channel chan; + adf_os_atomic_t hidden_ssid_restart_in_progress; + tANI_U8 ssidHidden; +} vdev_restart_params_t; + +struct wma_txrx_node { + u_int8_t addr[ETH_ALEN]; + u_int8_t bssid[ETH_ALEN]; + void *handle; + struct beacon_info *beacon; + vdev_restart_params_t vdev_restart_params; + vdev_cli_config_t config; + struct scan_param scan_info; + u_int32_t type; + u_int32_t sub_type; +#ifdef FEATURE_WLAN_SCAN_PNO + v_BOOL_t nlo_match_evt_received; + v_BOOL_t pno_in_progress; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + v_BOOL_t plm_in_progress; +#endif + v_BOOL_t ptrn_match_enable; + v_BOOL_t conn_state; + /* BSS parameters cached for use in WDA_ADD_STA */ + tSirMacBeaconInterval beaconInterval; + tANI_U8 llbCoexist; + tANI_U8 shortSlotTimeSupported; + tANI_U8 dtimPeriod; + WLAN_PHY_MODE chanmode; + tANI_U8 vht_capable; + tANI_U8 ht_capable; + A_UINT32 mhz; /* channel frequency in KHZ */ + v_BOOL_t vdev_up; + u_int64_t tsfadjust; + void *addBssStaContext; + tANI_U8 aid; + /* Robust Management Frame (RMF) enabled/disabled */ + tANI_U8 rmfEnabled; +#ifdef WLAN_FEATURE_11W + wma_igtk_key_t key; +#endif /* WLAN_FEATURE_11W */ + u_int32_t uapsd_cached_val; + tAniGetPEStatsRsp *stats_rsp; + tANI_U8 fw_stats_set; + void *del_staself_req; + adf_os_atomic_t bss_status; + tANI_U8 rate_flags; + tANI_U8 nss; + v_BOOL_t is_channel_switch; + u_int16_t pause_bitmap; + tPowerdBm tx_power; /* TX power in dBm */ + tPowerdBm max_tx_power; /* max Tx power in dBm */ + u_int32_t nwType; +#if defined WLAN_FEATURE_VOWIFI_11R + void *staKeyParams; +#endif + v_BOOL_t ps_enabled; + u_int32_t dtim_policy; + u_int32_t peer_count; + v_BOOL_t roam_synch_in_progress; + void *plink_status_req; + u_int8_t delay_before_vdev_stop; +}; + +#if defined(QCA_WIFI_FTM) +#define MAX_UTF_EVENT_LENGTH 2048 +#define MAX_WMI_UTF_LEN 252 +#define SYS_MSG_COOKIE (0xFACE) + +typedef struct { + A_UINT32 len; + A_UINT32 msgref; + A_UINT32 segmentInfo; + A_UINT32 pad; +} SEG_HDR_INFO_STRUCT; + +struct utf_event_info { + u_int8_t *data; + u_int32_t length; + adf_os_size_t offset; + u_int8_t currentSeq; + u_int8_t expectedSeq; +}; +#endif + +typedef struct { + u_int8_t vdev_id; + u_int32_t scan_id; +}scan_timer_info; + +typedef struct { + u_int32_t atimWindowLength; + u_int32_t isPowerSaveAllowed; + u_int32_t isPowerCollapseAllowed; + u_int32_t isAwakeonTxRxEnabled; + u_int32_t inactivityCount; + u_int32_t txSPEndInactivityTime; + u_int32_t ibssPsWarmupTime; + u_int32_t ibssPs1RxChainInAtimEnable; +}ibss_power_save_params; + +typedef struct { + void *wmi_handle; + void *htc_handle; + void *vos_context; + void *mac_context; + + vos_event_t wma_ready_event; + vos_event_t wma_resume_event; + vos_event_t target_suspend; + vos_event_t wow_tx_complete; + vos_event_t recovery_event; + + t_cfg_nv_param cfg_nv; + + v_U16_t max_station; + v_U16_t max_bssid; + v_U32_t frame_xln_reqd; + t_wma_drv_type driver_type; + + /* TODO: Check below 2 parameters are required for ROME/PRONTO ? */ + u_int8_t myaddr[ETH_ALEN]; /* current mac address */ + u_int8_t hwaddr[ETH_ALEN]; /* mac address from EEPROM */ + + wmi_abi_version target_abi_vers; /* The target firmware version */ + /* The final negotiated ABI version to be used for communicating */ + wmi_abi_version final_abi_vers; + v_U32_t target_fw_version; /* Target f/w build version */ +#ifdef WLAN_FEATURE_LPSS + v_U8_t lpss_support; /* LPSS feature is supported in target or not */ +#endif + bool wmi_ready; + u_int32_t wlan_init_status; + adf_os_device_t adf_dev; + u_int32_t phy_capability; /* PHY Capability from Target*/ + u_int32_t max_frag_entry; /* Max number of Fragment entry */ + u_int32_t wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; /* wmi services bitmap received from Target */ + wmi_resource_config wlan_resource_config; + u_int32_t frameTransRequired; + tBssSystemRole wmaGlobalSystemRole; + + /* Tx Frame Compl Cb registered by umac */ + pWDATxRxCompFunc tx_frm_download_comp_cb; + + /* Event to wait for tx download completion */ + vos_event_t tx_frm_download_comp_event; + + /* + * Dummy event to wait for draining MSDUs left in hardware tx + * queue and before requesting VDEV_STOP. Nobody will set this + * and wait will timeout, and code will poll the pending tx + * descriptors number to be zero. + */ + vos_event_t tx_queue_empty_event; + + /* Ack Complete Callback registered by umac */ + pWDAAckFnTxComp umac_ota_ack_cb[SIR_MAC_MGMT_RESERVED15]; + pWDAAckFnTxComp umac_data_ota_ack_cb; + + /* timestamp when OTA of last umac data was done */ + v_TIME_t last_umac_data_ota_timestamp; + /* cache nbuf ptr for the last umac data buf */ + adf_nbuf_t last_umac_data_nbuf; + + v_BOOL_t needShutdown; + u_int32_t num_mem_chunks; + struct wma_mem_chunk mem_chunks[MAX_MEM_CHUNKS]; + wda_tgt_cfg_cb tgt_cfg_update_cb; + /*Callback to indicate radar to HDD*/ + wda_dfs_radar_indication_cb dfs_radar_indication_cb; + HAL_REG_CAPABILITIES reg_cap; + u_int32_t scan_id; + struct wma_txrx_node *interfaces; + pdev_cli_config_t pdevconfig; + struct list_head vdev_resp_queue; + adf_os_spinlock_t vdev_respq_lock; + adf_os_spinlock_t vdev_detach_lock; + u_int32_t ht_cap_info; +#ifdef WLAN_FEATURE_11AC + u_int32_t vht_cap_info; + u_int32_t vht_supp_mcs; +#endif + u_int32_t num_rf_chains; + +#if defined(QCA_WIFI_FTM) + /* UTF event information */ + struct utf_event_info utf_event_info; +#endif + u_int8_t is_fw_assert; + struct wma_wow wow; + u_int8_t no_of_suspend_ind; + u_int8_t no_of_resume_ind; + + /* Have a back up of arp info to send along + * with ns info suppose if ns also enabled + */ + tSirHostOffloadReq mArpInfo; + struct wma_tx_ack_work_ctx *ack_work_ctx; + u_int8_t powersave_mode; + v_BOOL_t ptrn_match_enable_all_vdev; + void* pGetRssiReq; + v_S7_t first_rssi; + t_thermal_mgmt thermal_mgmt_info; + v_BOOL_t roam_offload_enabled; + t_wma_roam_preauth_chan_state_t roam_preauth_scan_state; + u_int32_t roam_preauth_scan_id; + u_int16_t roam_preauth_chanfreq; + void *roam_preauth_chan_context; + adf_os_spinlock_t roam_preauth_lock; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + adf_os_spinlock_t roam_synch_lock; +#endif + /* Here ol_ini_info is used to store ini + * status of arp offload, ns offload + * and others. Currently 1st bit is used + * for arp off load and 2nd bit for ns + * offload currently, rest bits are unused + */ + u_int8_t ol_ini_info; + v_BOOL_t ssdp; + u_int8_t ibss_started; + tSetBssKeyParams ibsskey_info; + + /*DFS umac interface information*/ + struct ieee80211com *dfs_ic; +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_t pno_wake_lock; +#endif +#ifdef FEATURE_WLAN_EXTSCAN + vos_wake_lock_t extscan_wake_lock; +#endif + vos_wake_lock_t wow_wake_lock; + int wow_nack; + u_int32_t ap_client_cnt; + adf_os_atomic_t is_wow_bus_suspended; + + vos_timer_t wma_scan_comp_timer; + scan_timer_info wma_scan_timer_info; + + u_int8_t dfs_phyerr_filter_offload; + v_BOOL_t suitable_ap_hb_failure; + + /* IBSS Power Save config Parameters */ + ibss_power_save_params wma_ibss_power_save_params; +#ifdef FEATURE_WLAN_RA_FILTERING + v_BOOL_t IsRArateLimitEnabled; + u_int16_t RArateLimitInterval; +#endif + + + /* Powersave Configuration Parameters */ + u_int8_t staMaxLIModDtim; + u_int8_t staModDtim; + u_int8_t staDynamicDtim; + + int32_t dfs_pri_multiplier; + + u_int32_t hw_bd_id; + u_int32_t hw_bd_info[HW_BD_INFO_SIZE]; + +#ifdef FEATURE_WLAN_D0WOW + atomic_t in_d0wow; +#endif +}t_wma_handle, *tp_wma_handle; + +struct wma_target_cap { + u_int32_t wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; /* wmi services bitmap received from Target */ + wmi_resource_config wlan_resource_config; /* default resource config,the os shim can overwrite it */ +}; + +/********** The following structures are referenced from legacy prima code *********/ +typedef enum { + QWLAN_ISOC_START_CMDID = 0x4000, + QWLAN_ISOC_END_CMDID = 0x4FFF, + + FW_CFG_DOWNLOAD_REQ = QWLAN_ISOC_START_CMDID, + FW_NV_DOWNLOAD_REQ, + FW_WLAN_HAL_STOP_REQ, + /* Add additional commands here */ + + QWLAN_ISOC_MAX_CMDID = QWLAN_ISOC_END_CMDID - 1 +}QWLAN_CMD_ID; +/* The shared memory between WDI and HAL is 4K so maximum data can be transferred +from WDI to HAL is 4K.This 4K should also include the Message header so sending 4K +of NV fragment is nt possbile.The next multiple of 1Kb is 3K */ + +typedef struct +{ + v_VOID_t *pConfigBuffer; + + /*Length of the config buffer above*/ + v_U16_t usConfigBufferLen; + + /*Production or FTM driver*/ + t_wma_drv_type driver_type; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + v_VOID_t *pUserData; + + /*The user data passed in by UMAC, it will be sent back when the indication + function pointer will be called */ + v_VOID_t *pIndUserData; +}t_wma_start_req; + +/* Message types for messages exchanged between WDI and HAL */ +typedef enum +{ + //Init/De-Init + WLAN_HAL_START_REQ = 0, + WLAN_HAL_START_RSP = 1, + WLAN_HAL_STOP_REQ = 2, + WLAN_HAL_STOP_RSP = 3, + + //Scan + WLAN_HAL_INIT_SCAN_REQ = 4, + WLAN_HAL_INIT_SCAN_RSP = 5, + WLAN_HAL_START_SCAN_REQ = 6, + WLAN_HAL_START_SCAN_RSP = 7 , + WLAN_HAL_END_SCAN_REQ = 8, + WLAN_HAL_END_SCAN_RSP = 9, + WLAN_HAL_FINISH_SCAN_REQ = 10, + WLAN_HAL_FINISH_SCAN_RSP = 11, + + // HW STA configuration/deconfiguration + WLAN_HAL_CONFIG_STA_REQ = 12, + WLAN_HAL_CONFIG_STA_RSP = 13, + WLAN_HAL_DELETE_STA_REQ = 14, + WLAN_HAL_DELETE_STA_RSP = 15, + WLAN_HAL_CONFIG_BSS_REQ = 16, + WLAN_HAL_CONFIG_BSS_RSP = 17, + WLAN_HAL_DELETE_BSS_REQ = 18, + WLAN_HAL_DELETE_BSS_RSP = 19, + + //Infra STA asscoiation + WLAN_HAL_JOIN_REQ = 20, + WLAN_HAL_JOIN_RSP = 21, + WLAN_HAL_POST_ASSOC_REQ = 22, + WLAN_HAL_POST_ASSOC_RSP = 23, + + //Security + WLAN_HAL_SET_BSSKEY_REQ = 24, + WLAN_HAL_SET_BSSKEY_RSP = 25, + WLAN_HAL_SET_STAKEY_REQ = 26, + WLAN_HAL_SET_STAKEY_RSP = 27, + WLAN_HAL_RMV_BSSKEY_REQ = 28, + WLAN_HAL_RMV_BSSKEY_RSP = 29, + WLAN_HAL_RMV_STAKEY_REQ = 30, + WLAN_HAL_RMV_STAKEY_RSP = 31, + + //Qos Related + WLAN_HAL_ADD_TS_REQ = 32, + WLAN_HAL_ADD_TS_RSP = 33, + WLAN_HAL_DEL_TS_REQ = 34, + WLAN_HAL_DEL_TS_RSP = 35, + WLAN_HAL_UPD_EDCA_PARAMS_REQ = 36, + WLAN_HAL_UPD_EDCA_PARAMS_RSP = 37, + WLAN_HAL_ADD_BA_REQ = 38, + WLAN_HAL_ADD_BA_RSP = 39, + WLAN_HAL_DEL_BA_REQ = 40, + WLAN_HAL_DEL_BA_RSP = 41, + + WLAN_HAL_CH_SWITCH_REQ = 42, + WLAN_HAL_CH_SWITCH_RSP = 43, + WLAN_HAL_SET_LINK_ST_REQ = 44, + WLAN_HAL_SET_LINK_ST_RSP = 45, + WLAN_HAL_GET_STATS_REQ = 46, + WLAN_HAL_GET_STATS_RSP = 47, + WLAN_HAL_UPDATE_CFG_REQ = 48, + WLAN_HAL_UPDATE_CFG_RSP = 49, + + WLAN_HAL_MISSED_BEACON_IND = 50, + WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = 51, + WLAN_HAL_MIC_FAILURE_IND = 52, + WLAN_HAL_FATAL_ERROR_IND = 53, + WLAN_HAL_SET_KEYDONE_MSG = 54, + + //NV Interface + WLAN_HAL_DOWNLOAD_NV_REQ = 55, + WLAN_HAL_DOWNLOAD_NV_RSP = 56, + + WLAN_HAL_ADD_BA_SESSION_REQ = 57, + WLAN_HAL_ADD_BA_SESSION_RSP = 58, + WLAN_HAL_TRIGGER_BA_REQ = 59, + WLAN_HAL_TRIGGER_BA_RSP = 60, + WLAN_HAL_UPDATE_BEACON_REQ = 61, + WLAN_HAL_UPDATE_BEACON_RSP = 62, + WLAN_HAL_SEND_BEACON_REQ = 63, + WLAN_HAL_SEND_BEACON_RSP = 64, + + WLAN_HAL_SET_BCASTKEY_REQ = 65, + WLAN_HAL_SET_BCASTKEY_RSP = 66, + WLAN_HAL_DELETE_STA_CONTEXT_IND = 67, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ = 68, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP = 69, + + // PTT interface support + WLAN_HAL_PROCESS_PTT_REQ = 70, + WLAN_HAL_PROCESS_PTT_RSP = 71, + + // BTAMP related events + WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ = 72, + WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP = 73, + WLAN_HAL_TL_HAL_FLUSH_AC_REQ = 74, + WLAN_HAL_TL_HAL_FLUSH_AC_RSP = 75, + + WLAN_HAL_ENTER_IMPS_REQ = 76, + WLAN_HAL_EXIT_IMPS_REQ = 77, + WLAN_HAL_ENTER_BMPS_REQ = 78, + WLAN_HAL_EXIT_BMPS_REQ = 79, + WLAN_HAL_ENTER_UAPSD_REQ = 80, + WLAN_HAL_EXIT_UAPSD_REQ = 81, + WLAN_HAL_UPDATE_UAPSD_PARAM_REQ = 82, + WLAN_HAL_CONFIGURE_RXP_FILTER_REQ = 83, + WLAN_HAL_ADD_BCN_FILTER_REQ = 84, + WLAN_HAL_REM_BCN_FILTER_REQ = 85, + WLAN_HAL_ADD_WOWL_BCAST_PTRN = 86, + WLAN_HAL_DEL_WOWL_BCAST_PTRN = 87, + WLAN_HAL_ENTER_WOWL_REQ = 88, + WLAN_HAL_EXIT_WOWL_REQ = 89, + WLAN_HAL_HOST_OFFLOAD_REQ = 90, + WLAN_HAL_SET_RSSI_THRESH_REQ = 91, + WLAN_HAL_GET_RSSI_REQ = 92, + WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ = 93, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 94, + + WLAN_HAL_ENTER_IMPS_RSP = 95, + WLAN_HAL_EXIT_IMPS_RSP = 96, + WLAN_HAL_ENTER_BMPS_RSP = 97, + WLAN_HAL_EXIT_BMPS_RSP = 98, + WLAN_HAL_ENTER_UAPSD_RSP = 99, + WLAN_HAL_EXIT_UAPSD_RSP = 100, + WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP = 101, + WLAN_HAL_UPDATE_UAPSD_PARAM_RSP = 102, + WLAN_HAL_CONFIGURE_RXP_FILTER_RSP = 103, + WLAN_HAL_ADD_BCN_FILTER_RSP = 104, + WLAN_HAL_REM_BCN_FILTER_RSP = 105, + WLAN_HAL_SET_RSSI_THRESH_RSP = 106, + WLAN_HAL_HOST_OFFLOAD_RSP = 107, + WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP = 108, + WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP = 109, + WLAN_HAL_ENTER_WOWL_RSP = 110, + WLAN_HAL_EXIT_WOWL_RSP = 111, + WLAN_HAL_RSSI_NOTIFICATION_IND = 112, + WLAN_HAL_GET_RSSI_RSP = 113, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP = 114, + + //11k related events + WLAN_HAL_SET_MAX_TX_POWER_REQ = 115, + WLAN_HAL_SET_MAX_TX_POWER_RSP = 116, + + //11R related msgs + WLAN_HAL_AGGR_ADD_TS_REQ = 117, + WLAN_HAL_AGGR_ADD_TS_RSP = 118, + + //P2P WLAN_FEATURE_P2P + WLAN_HAL_SET_P2P_GONOA_REQ = 119, + WLAN_HAL_SET_P2P_GONOA_RSP = 120, + + //WLAN Dump commands + WLAN_HAL_DUMP_COMMAND_REQ = 121, + WLAN_HAL_DUMP_COMMAND_RSP = 122, + + //OEM_DATA FEATURE SUPPORT + WLAN_HAL_START_OEM_DATA_REQ = 123, + WLAN_HAL_START_OEM_DATA_RSP = 124, + + //ADD SELF STA REQ and RSP + WLAN_HAL_ADD_STA_SELF_REQ = 125, + WLAN_HAL_ADD_STA_SELF_RSP = 126, + + //DEL SELF STA SUPPORT + WLAN_HAL_DEL_STA_SELF_REQ = 127, + WLAN_HAL_DEL_STA_SELF_RSP = 128, + + // Coex Indication + WLAN_HAL_COEX_IND = 129, + + // Tx Complete Indication + WLAN_HAL_OTA_TX_COMPL_IND = 130, + + //Host Suspend/resume messages + WLAN_HAL_HOST_SUSPEND_IND = 131, + WLAN_HAL_HOST_RESUME_REQ = 132, + WLAN_HAL_HOST_RESUME_RSP = 133, + + WLAN_HAL_SET_TX_POWER_REQ = 134, + WLAN_HAL_SET_TX_POWER_RSP = 135, + WLAN_HAL_GET_TX_POWER_REQ = 136, + WLAN_HAL_GET_TX_POWER_RSP = 137, + + WLAN_HAL_P2P_NOA_ATTR_IND = 138, + + WLAN_HAL_ENABLE_RADAR_DETECT_REQ = 139, + WLAN_HAL_ENABLE_RADAR_DETECT_RSP = 140, + WLAN_HAL_GET_TPC_REPORT_REQ = 141, + WLAN_HAL_GET_TPC_REPORT_RSP = 142, + WLAN_HAL_RADAR_DETECT_IND = 143, + WLAN_HAL_RADAR_DETECT_INTR_IND = 144, + WLAN_HAL_KEEP_ALIVE_REQ = 145, + WLAN_HAL_KEEP_ALIVE_RSP = 146, + + /*PNO messages*/ + WLAN_HAL_SET_PREF_NETWORK_REQ = 147, + WLAN_HAL_SET_PREF_NETWORK_RSP = 148, + WLAN_HAL_SET_RSSI_FILTER_REQ = 149, + WLAN_HAL_SET_RSSI_FILTER_RSP = 150, + WLAN_HAL_UPDATE_SCAN_PARAM_REQ = 151, + WLAN_HAL_UPDATE_SCAN_PARAM_RSP = 152, + WLAN_HAL_PREF_NETW_FOUND_IND = 153, + + WLAN_HAL_SET_TX_PER_TRACKING_REQ = 154, + WLAN_HAL_SET_TX_PER_TRACKING_RSP = 155, + WLAN_HAL_TX_PER_HIT_IND = 156, + + WLAN_HAL_8023_MULTICAST_LIST_REQ = 157, + WLAN_HAL_8023_MULTICAST_LIST_RSP = 158, + + WLAN_HAL_SET_PACKET_FILTER_REQ = 159, + WLAN_HAL_SET_PACKET_FILTER_RSP = 160, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_REQ = 161, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_RSP = 162, + WLAN_HAL_CLEAR_PACKET_FILTER_REQ = 163, + WLAN_HAL_CLEAR_PACKET_FILTER_RSP = 164, + /*This is temp fix. Should be removed once + * Host and Riva code is in sync*/ + WLAN_HAL_INIT_SCAN_CON_REQ = 165, + + WLAN_HAL_SET_POWER_PARAMS_REQ = 166, + WLAN_HAL_SET_POWER_PARAMS_RSP = 167, + + WLAN_HAL_TSM_STATS_REQ = 168, + WLAN_HAL_TSM_STATS_RSP = 169, + + // wake reason indication (WOW) + WLAN_HAL_WAKE_REASON_IND = 170, + // GTK offload support + WLAN_HAL_GTK_OFFLOAD_REQ = 171, + WLAN_HAL_GTK_OFFLOAD_RSP = 172, + WLAN_HAL_GTK_OFFLOAD_GETINFO_REQ = 173, + WLAN_HAL_GTK_OFFLOAD_GETINFO_RSP = 174, + + WLAN_HAL_FEATURE_CAPS_EXCHANGE_REQ = 175, + WLAN_HAL_FEATURE_CAPS_EXCHANGE_RSP = 176, + WLAN_HAL_EXCLUDE_UNENCRYPTED_IND = 177, + + WLAN_HAL_SET_THERMAL_MITIGATION_REQ = 178, + WLAN_HAL_SET_THERMAL_MITIGATION_RSP = 179, + + WLAN_HAL_UPDATE_VHT_OP_MODE_REQ = 182, + WLAN_HAL_UPDATE_VHT_OP_MODE_RSP = 183, + + WLAN_HAL_P2P_NOA_START_IND = 184, + + WLAN_HAL_GET_ROAM_RSSI_REQ = 185, + WLAN_HAL_GET_ROAM_RSSI_RSP = 186, + + WLAN_HAL_CLASS_B_STATS_IND = 187, + WLAN_HAL_DEL_BA_IND = 188, + WLAN_HAL_DHCP_START_IND = 189, + WLAN_HAL_DHCP_STOP_IND = 190, + + WLAN_HAL_MSG_MAX = WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE +}tHalHostMsgType; + +/* Enumeration for Version */ +typedef enum +{ + WLAN_HAL_MSG_VERSION0 = 0, + WLAN_HAL_MSG_VERSION1 = 1, + WLAN_HAL_MSG_WCNSS_CTRL_VERSION = 0x7FFF, /*define as 2 bytes data*/ + WLAN_HAL_MSG_VERSION_MAX_FIELD = WLAN_HAL_MSG_WCNSS_CTRL_VERSION +} tHalHostMsgVersion; + +/* 4-byte control message header used by HAL*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalHostMsgType msgType:16; + tHalHostMsgVersion msgVersion:16; + tANI_U32 msgLen; +} tHalMsgHeader, *tpHalMsgHeader; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_REQ + ---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST sHalMacStartParameter +{ + /* Drive Type - Production or FTM etc */ + tDriverType driverType; + + /*Length of the config buffer*/ + tANI_U32 uConfigBufferLen; + + /* Following this there is a TLV formatted buffer of length + * "uConfigBufferLen" bytes containing all config values. + * The TLV is expected to be formatted like this: + * 0 15 31 31+CFG_LEN-1 length-1 + * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| + */ +} tHalMacStartParameter, *tpHalMacStartParameter; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalMacStartReqMsg messages should be + * header.msgLen = sizeof(tHalMacStartReqMsg) + uConfigBufferLen */ + tHalMsgHeader header; + tHalMacStartParameter startReqParams; +} tHalMacStartReqMsg, *tpHalMacStartReqMsg; + +extern v_BOOL_t sys_validateStaConfig(void *pImage, unsigned long cbFile, + void **ppStaConfig, v_SIZE_t *pcbStaConfig); +extern void vos_WDAComplete_cback(v_PVOID_t pVosContext); +extern void wma_send_regdomain_info(u_int32_t reg_dmn, u_int16_t regdmn2G, + u_int16_t regdmn5G, int8_t ctl2G, int8_t ctl5G); +void wma_get_modeselect(tp_wma_handle wma, u_int32_t *modeSelect); + + +/** + * Frame index + */ +enum frame_index { + GENERIC_NODOWNLD_NOACK_COMP_INDEX, + GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX, + GENERIC_DOWNLD_COMP_ACK_COMP_INDEX, + GENERIC_NODOWLOAD_ACK_COMP_INDEX, + FRAME_INDEX_MAX +}; + +VOS_STATUS wma_update_vdev_tbl(tp_wma_handle wma_handle, u_int8_t vdev_id, + ol_txrx_vdev_handle tx_rx_vdev_handle, u_int8_t *mac, + u_int32_t vdev_type, bool add_del); + +int32_t regdmn_get_regdmn_for_country(u_int8_t *alpha2); +void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail, + u_int32_t modeSelect); + +/*get the ctl from regdomain*/ +u_int8_t regdmn_get_ctl_for_regdmn(u_int32_t reg_dmn); +u_int16_t get_regdmn_5g(u_int32_t reg_dmn); + +#define WMA_FW_PHY_STATS 0x1 +#define WMA_FW_RX_REORDER_STATS 0x2 +#define WMA_FW_RX_RC_STATS 0x3 +#define WMA_FW_TX_PPDU_STATS 0x4 +#define WMA_FW_TX_CONCISE_STATS 0x5 +#define WMA_FW_TX_RC_STATS 0x6 +#define WMA_FW_RX_REM_RING_BUF 0xc + +/* + * Setting the Tx Comp Timeout to 1 secs. + * TODO: Need to Revist the Timing + */ +#define WMA_TX_FRAME_COMPLETE_TIMEOUT 1000 +#define WMA_TX_FRAME_BUFFER_NO_FREE 0 +#define WMA_TX_FRAME_BUFFER_FREE 1 + +struct wma_tx_ack_work_ctx { + tp_wma_handle wma_handle; + u_int16_t sub_type; + int32_t status; + struct work_struct ack_cmp_work; +}; + +#define WMA_TARGET_REQ_TYPE_VDEV_START 0x1 +#define WMA_TARGET_REQ_TYPE_VDEV_STOP 0x2 +#define WMA_TARGET_REQ_TYPE_VDEV_DEL 0x3 + +#define WMA_VDEV_START_REQUEST_TIMEOUT (3000) /* 3 seconds */ +#define WMA_VDEV_STOP_REQUEST_TIMEOUT (3000) /* 3 seconds */ + +struct wma_target_req { + vos_timer_t event_timeout; + struct list_head node; + void *user_data; + u_int32_t msg_type; + u_int8_t vdev_id; + u_int8_t type; +}; + +struct wma_vdev_start_req { + u_int32_t beacon_intval; + u_int32_t dtim_period; + int32_t max_txpow; + ePhyChanBondState chan_offset; + bool is_dfs; + u_int8_t vdev_id; + u_int8_t chan; + u_int8_t oper_mode; + tSirMacSSid ssid; + u_int8_t hidden_ssid; + u_int8_t pmf_enabled; + u_int8_t vht_capable; + u_int8_t ht_capable; + int32_t dfs_pri_multiplier; + u_int8_t dot11_mode; +}; + +struct wma_set_key_params { + u_int8_t vdev_id; + /* def_key_idx can be used to see if we have to read the key from cfg */ + u_int32_t def_key_idx; + u_int16_t key_len; + u_int8_t peer_mac[ETH_ALEN]; + u_int8_t singl_tid_rc; + enum eAniEdType key_type; + u_int32_t key_idx; + bool unicast; + u_int8_t key_data[SIR_MAC_MAX_KEY_LENGTH]; +}; + +typedef struct { + u_int16_t minTemp; + u_int16_t maxTemp; + u_int8_t thermalEnable; +} t_thermal_cmd_params, *tp_thermal_cmd_params; + +/* Powersave Related */ +/* Default InActivity Time is 200 ms */ +#define POWERSAVE_DEFAULT_INACTIVITY_TIME 200 + +/* Default Listen Interval */ +#define POWERSAVE_DEFAULT_LISTEN_INTERVAL 1 + +/* + * TODO: Add WMI_CMD_ID_MAX as part of WMI_CMD_ID + * instead of assigning it to the last valid wmi + * cmd+1 to avoid updating this when a command is + * added/deleted. + */ +#define WMI_CMDID_MAX (WMI_TXBF_CMDID + 1) + +/* + * wma cmd ids for configuration request which + * does not involve sending a wmi command. + */ +enum wma_cfg_cmd_id { + WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID = WMI_CMDID_MAX, + WMA_VDEV_TXRX_FWSTATS_RESET_CMDID, + /* Set time latency and time quota for MCC home channels */ + WMA_VDEV_MCC_SET_TIME_LATENCY, + WMA_VDEV_MCC_SET_TIME_QUOTA, + + /* IBSS Power Save Parameters */ + WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE, + WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED, + WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED, + WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX, + WMA_VDEV_IBSS_SET_INACTIVITY_TIME, + WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME, + WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS, + WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW, + + /* dfs control interface */ + WMA_VDEV_DFS_CONTROL_CMDID, + WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID, + + /* Add any new command before this */ + WMA_CMD_ID_MAX +}; + +typedef struct wma_trigger_uapsd_params +{ + u_int32_t wmm_ac; + u_int32_t user_priority; + u_int32_t service_interval; + u_int32_t suspend_interval; + u_int32_t delay_interval; +}t_wma_trigger_uapsd_params, *tp_wma_trigger_uapsd_params; + +VOS_STATUS wma_trigger_uapsd_params(tp_wma_handle wma_handle, u_int32_t vdev_id, + tp_wma_trigger_uapsd_params trigger_uapsd_params); + +/* added to get average snr for both data and beacon */ +VOS_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq, + v_S7_t first_rssi); + + +#define WMA_NLO_FREQ_THRESH 1000 /* in MHz */ +#define WMA_SEC_TO_MSEC(sec) (sec * 1000) /* sec to msec */ + +/* Default rssi threshold defined in CFG80211 */ +#define WMA_RSSI_THOLD_DEFAULT -300 + +#ifdef FEATURE_WLAN_SCAN_PNO +#define WMA_PNO_WAKE_LOCK_TIMEOUT (30 * 1000) /* in msec */ +#endif +#define WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT (50 * 1000) /* in msec */ +#define WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */ +#define WMA_DEAUTH_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */ +#define WMA_DISASSOC_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */ +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +#define WMA_AUTO_SHUTDOWN_WAKE_LOCK_DURATION (30 * 1000) /* in msec */ +#endif +#ifdef FEATURE_WLAN_RA_FILTERING +#define WMA_RA_MATCH_RECV_WAKE_LOCK_DURATION (5 * 1000) /* in msec */ +#endif + +/* U-APSD maximum service period of peer station */ +enum uapsd_peer_param_max_sp { + UAPSD_MAX_SP_LEN_UNLIMITED = 0, + UAPSD_MAX_SP_LEN_2 = 2, + UAPSD_MAX_SP_LEN_4 = 4, + UAPSD_MAX_SP_LEN_6 = 6 +}; + +/* U-APSD Enabled AC's of peer station */ +enum uapsd_peer_param_enabled_ac { + UAPSD_VO_ENABLED = 0x01, + UAPSD_VI_ENABLED = 0x02, + UAPSD_BK_ENABLED = 0x04, + UAPSD_BE_ENABLED = 0x08 +}; + +#define WMA_TXMIC_LEN 8 +#define WMA_RXMIC_LEN 8 + +/* + * Length = (2 octets for Index and CTWin/Opp PS) and + * (13 octets for each NOA Descriptors) + */ + +#define WMA_P2P_NOA_IE_OPP_PS_SET (0x80) +#define WMA_P2P_NOA_IE_CTWIN_MASK (0x7F) + +#define WMA_P2P_IE_ID 0xdd +#define WMA_P2P_WFA_OUI { 0x50,0x6f,0x9a } +#define WMA_P2P_WFA_VER 0x09 /* ver 1.0 */ +#define WMA_WSC_OUI { 0x00,0x50,0xF2 } /* Microsoft WSC OUI byte */ + +/* P2P Sub element defintions (according to table 5 of Wifi's P2P spec) */ +#define WMA_P2P_SUB_ELEMENT_STATUS 0 +#define WMA_P2P_SUB_ELEMENT_MINOR_REASON 1 +#define WMA_P2P_SUB_ELEMENT_CAPABILITY 2 +#define WMA_P2P_SUB_ELEMENT_DEVICE_ID 3 +#define WMA_P2P_SUB_ELEMENT_GO_INTENT 4 +#define WMA_P2P_SUB_ELEMENT_CONFIGURATION_TIMEOUT 5 +#define WMA_P2P_SUB_ELEMENT_LISTEN_CHANNEL 6 +#define WMA_P2P_SUB_ELEMENT_GROUP_BSSID 7 +#define WMA_P2P_SUB_ELEMENT_EXTENDED_LISTEN_TIMING 8 +#define WMA_P2P_SUB_ELEMENT_INTENDED_INTERFACE_ADDR 9 +#define WMA_P2P_SUB_ELEMENT_MANAGEABILITY 10 +#define WMA_P2P_SUB_ELEMENT_CHANNEL_LIST 11 +#define WMA_P2P_SUB_ELEMENT_NOA 12 +#define WMA_P2P_SUB_ELEMENT_DEVICE_INFO 13 +#define WMA_P2P_SUB_ELEMENT_GROUP_INFO 14 +#define WMA_P2P_SUB_ELEMENT_GROUP_ID 15 +#define WMA_P2P_SUB_ELEMENT_INTERFACE 16 +#define WMA_P2P_SUB_ELEMENT_OP_CHANNEL 17 +#define WMA_P2P_SUB_ELEMENT_INVITATION_FLAGS 18 +#define WMA_P2P_SUB_ELEMENT_VENDOR 221 + +/* Macros for handling unaligned memory accesses */ +#define P2PIE_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define P2PIE_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +/* + * P2P IE structural definition. + */ +struct p2p_ie { + u_int8_t p2p_id; + u_int8_t p2p_len; + u_int8_t p2p_oui[3]; + u_int8_t p2p_oui_type; +} __packed; + +struct p2p_noa_descriptor { + u_int8_t type_count; /* 255: continuous schedule, 0: reserved */ + u_int32_t duration ; /* Absent period duration in micro seconds */ + u_int32_t interval; /* Absent period interval in micro seconds */ + u_int32_t start_time; /* 32 bit tsf time when in starts */ +} __packed; + +struct p2p_sub_element_noa { + u_int8_t p2p_sub_id; + u_int8_t p2p_sub_len; + u_int8_t index; /* identifies instance of NOA su element */ + u_int8_t oppPS:1, /* oppPS state of the AP */ + ctwindow:7; /* ctwindow in TUs */ + u_int8_t num_descriptors; /* number of NOA descriptors */ + struct p2p_noa_descriptor noa_descriptors[WMA_MAX_NOA_DESCRIPTORS]; +}; + +struct wma_decap_info_t { + u_int8_t hdr[sizeof(struct ieee80211_qosframe_addr4)]; + int32_t hdr_len; +}; + +enum powersave_mode { + PS_NOT_SUPPORTED = 0, + PS_LEGACY_NODEEPSLEEP = 1, + PS_QPOWER_NODEEPSLEEP = 2, + PS_LEGACY_DEEPSLEEP = 3, + PS_QPOWER_DEEPSLEEP = 4 +}; + +#define WMA_DEFAULT_MAX_PSPOLL_BEFORE_WAKE 1 + +typedef enum { + /* set packet power save */ + WMI_VDEV_PPS_PAID_MATCH = 0, + WMI_VDEV_PPS_GID_MATCH = 1, + WMI_VDEV_PPS_EARLY_TIM_CLEAR = 2, + WMI_VDEV_PPS_EARLY_DTIM_CLEAR = 3, + WMI_VDEV_PPS_EOF_PAD_DELIM = 4, + WMI_VDEV_PPS_MACADDR_MISMATCH = 5, + WMI_VDEV_PPS_DELIM_CRC_FAIL = 6, + WMI_VDEV_PPS_GID_NSTS_ZERO = 7, + WMI_VDEV_PPS_RSSI_CHECK = 8, + WMI_VDEV_VHT_SET_GID_MGMT = 9, + WMI_VDEV_PPS_5G_EBT = 10 +} packet_power_save; + +typedef enum { + WMI_VDEV_PARAM_GTX_HT_MCS, + WMI_VDEV_PARAM_GTX_VHT_MCS, + WMI_VDEV_PARAM_GTX_USR_CFG, + WMI_VDEV_PARAM_GTX_THRE, + WMI_VDEV_PARAM_GTX_MARGIN, + WMI_VDEV_PARAM_GTX_STEP, + WMI_VDEV_PARAM_GTX_MINTPC, + WMI_VDEV_PARAM_GTX_BW_MASK, +}green_tx_param; + +#define WMA_DEFAULT_QPOWER_MAX_PSPOLL_BEFORE_WAKE 1 +#define WMA_DEFAULT_QPOWER_TX_WAKE_THRESHOLD 2 +#define WMA_DEFAULT_SIFS_BURST_DURATION 8160 + +#define WMA_VHT_PPS_PAID_MATCH 1 +#define WMA_VHT_PPS_GID_MATCH 2 +#define WMA_VHT_PPS_DELIM_CRC_FAIL 3 + +#ifdef FEATURE_WLAN_TDLS +typedef struct wma_tdls_params +{ + tANI_U32 vdev_id; + tANI_U32 tdls_state; + tANI_U32 notification_interval_ms; + tANI_U32 tx_discovery_threshold; + tANI_U32 tx_teardown_threshold; + tANI_S32 rssi_teardown_threshold; + tANI_S32 rssi_delta; + tANI_U32 tdls_options; + tANI_U32 peer_traffic_ind_window; + tANI_U32 peer_traffic_response_timeout; + tANI_U32 puapsd_mask; + tANI_U32 puapsd_inactivity_time; + tANI_U32 puapsd_rx_frame_threshold; +} t_wma_tdls_params; + +typedef struct { + /** unique id identifying the VDEV */ + A_UINT32 vdev_id; + /** peer MAC address */ + wmi_mac_addr peer_macaddr; + /** TDLS peer status (wma_tdls_peer_notification)*/ + A_UINT32 peer_status; + /** TDLS peer reason (wma_tdls_peer_reason) */ + A_UINT32 peer_reason; +} wma_tdls_peer_event; + +#endif /* FEATURE_WLAN_TDLS */ + +#define WMA_DFS_MAX_20M_SUB_CH 8 + +struct wma_dfs_radar_channel_list { + A_UINT32 nchannels; + /*Channel number including bonded channels on which the RADAR is present */ + u_int8_t channels[WMA_DFS_MAX_20M_SUB_CH]; +}; + +/* + * Structure to indicate RADAR + */ + +struct wma_dfs_radar_indication { + /* unique id identifying the VDEV */ + A_UINT32 vdev_id; + /* Channel list on which RADAR is detected */ + struct wma_dfs_radar_channel_list chan_list; + /* Flag to Indicate RADAR presence on the + * current operating channel + */ + u_int32_t dfs_radar_status; + /* Flag to indicate use NOL */ + int use_nol; +}; + +/* + * WMA-DFS Hooks + */ +int ol_if_dfs_attach(struct ieee80211com *ic, void *ptr, void *radar_info); +u_int64_t ol_if_get_tsf64(struct ieee80211com *ic); +int ol_if_dfs_disable(struct ieee80211com *ic); +struct ieee80211_channel * ieee80211_find_channel(struct ieee80211com *ic, + int freq, u_int32_t flags); +int ol_if_dfs_enable(struct ieee80211com *ic, int *is_fastclk, void *pe); +u_int32_t ieee80211_ieee2mhz(u_int32_t chan, u_int32_t flags); +int ol_if_dfs_get_ext_busy(struct ieee80211com *ic); +int ol_if_dfs_get_mib_cycle_counts_pct(struct ieee80211com *ic, + u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt); +u_int16_t ol_if_dfs_usenol(struct ieee80211com *ic); +void ieee80211_mark_dfs(struct ieee80211com *ic, + struct ieee80211_channel *ichan); +int wma_dfs_indicate_radar(struct ieee80211com *ic, + struct ieee80211_channel *ichan); +u_int16_t dfs_usenol(struct ieee80211com *ic); + +#define WMA_SMPS_MASK_LOWER_16BITS 0xFF +#define WMA_SMPS_MASK_UPPER_3BITS 0x7 +#define WMA_SMPS_PARAM_VALUE_S 29 + +#define WMA_MAX_SCAN_ID 0x00FF + +/* U-APSD Access Categories */ +enum uapsd_ac { + UAPSD_BE, + UAPSD_BK, + UAPSD_VI, + UAPSD_VO +}; + +VOS_STATUS wma_disable_uapsd_per_ac(tp_wma_handle wma_handle, + u_int32_t vdev_id, + enum uapsd_ac ac); + +/* U-APSD User Priorities */ +enum uapsd_up { + UAPSD_UP_BE, + UAPSD_UP_BK, + UAPSD_UP_RESV, + UAPSD_UP_EE, + UAPSD_UP_CL, + UAPSD_UP_VI, + UAPSD_UP_VO, + UAPSD_UP_NC, + UAPSD_UP_MAX +}; + +#ifdef FEATURE_WLAN_D0WOW +void wma_set_d0wow_flag(tp_wma_handle wma_handle, A_BOOL flag); +A_BOOL wma_read_d0wow_flag(tp_wma_handle wma_handle); +#endif + +A_UINT32 eCsrAuthType_to_rsn_authmode (eCsrAuthType authtype, + eCsrEncryptionType encr); +A_UINT32 eCsrEncryptionType_to_rsn_cipherset (eCsrEncryptionType encr); + +#define WMA_TGT_INVALID_SNR (-1) +#define WMA_DYNAMIC_DTIM_SETTING_THRESHOLD 2 + +#define WMA_TX_Q_RECHECK_TIMER_WAIT 2 // 2 ms +#define WMA_TX_Q_RECHECK_TIMER_MAX_WAIT 20 // 20 ms +#define WMA_MAX_NUM_ARGS 8 +typedef struct wma_unit_test_cmd +{ + v_UINT_t vdev_id; + WLAN_MODULE_ID module_id; + v_U32_t num_args; + v_U32_t args[WMA_MAX_NUM_ARGS]; +}t_wma_unit_test_cmd; + +typedef struct wma_roam_invoke_cmd +{ + v_UINT_t vdev_id; + u_int8_t bssid[6]; + v_U32_t channel; +}t_wma_roam_invoke_cmd; + +int wma_crash_inject(tp_wma_handle wma_handle, uint32_t type, + uint32_t delay_time_ms); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_dfs_interface.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_dfs_interface.c new file mode 100644 index 0000000000000..edd5a80cc7fd6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_dfs_interface.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wma_dfs_interface.c + + OVERVIEW: + + Source code borrowed from QCA_MAIN DFS module + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- + +===========================================================================*/ + + + +#include "wma.h" +#include "ath_dfs_structs.h" +#include "wma_dfs_interface.h" + +#ifndef ATH_SUPPORT_DFS +#define ATH_SUPPORT_DFS 1 +#endif + +int +ol_if_dfs_attach(struct ieee80211com *ic, void *ptr, void *radar_info) +{ + struct ath_dfs_caps *pCap = (struct ath_dfs_caps *) ptr; + + adf_os_print("%s: called; ptr=%p, radar_info=%p\n", + __func__, ptr, radar_info); + + pCap->ath_chip_is_bb_tlv = 1; + pCap->ath_dfs_combined_rssi_ok = 0; + pCap->ath_dfs_ext_chan_ok = 0; + pCap->ath_dfs_use_enhancement = 0; + pCap->ath_strong_signal_diversiry = 0; + pCap->ath_fastdiv_val = 0; + + return(0); +} + +/* + * Place Holder API + * We get the tsf from Firmware. + */ +u_int64_t +ol_if_get_tsf64(struct ieee80211com *ic) +{ + return (0); +} + +/* + * ic_dfs_disable is just a place holder + * function since firmware takes care of + * disabling the dfs phyerrors disabling. + */ +int +ol_if_dfs_disable(struct ieee80211com *ic) +{ + return (0); +} + + +/* + * Locate a channel given a frequency+flags. We cache + * the previous lookup to optimize swithing between two + * channels--as happens with dynamic turbo. + * This verifies that found channels have not been excluded because of 11d. + */ +struct ieee80211_channel * +ieee80211_find_channel(struct ieee80211com *ic, int freq, u_int32_t flags) +{ + struct ieee80211_channel *c; + int i; + + flags &= IEEE80211_CHAN_ALLTURBO; + /* brute force search */ + for (i = 0; i < ic->ic_nchans; i++) + { + c = &ic->ic_channels[i]; + + if ((! IEEE80211_IS_CHAN_11D_EXCLUDED(c)) && + (c->ic_freq == freq) && + ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)) + { + return c; + } + } + + return NULL; +} + + +/* + * ic_dfs_enable - enable DFS + * For offload solutions, radar PHY errors will be enabled by the target + * firmware when DFS is requested for the current channel. + */ +int ol_if_dfs_enable(struct ieee80211com *ic, int *is_fastclk, void *pe) +{ + /* + * For peregrine, treat fastclk as the "oversampling" mode. + * It's on by default. This may change at some point, so + * we should really query the firmware to find out what + * the current configuration is. + */ + (* is_fastclk) = 1; + + return (0); +} + +/* + * Convert IEEE channel number to MHz frequency. + */ +u_int32_t +ieee80211_ieee2mhz(u_int32_t chan, u_int32_t flags) +{ + if (flags & IEEE80211_CHAN_2GHZ) + { + /* 2GHz band */ + if (chan == 14) + return 2484; + if (chan < 14) + return 2407 + chan*5; + else + return 2512 + ((chan-15)*20); + } + else if (flags & IEEE80211_CHAN_5GHZ) + { + /* 5Ghz band */ + return 5000 + (chan*5); + } + else + { + /* either, guess */ + if (chan == 14) + return 2484; + if (chan < 14) /* 0-13 */ + return 2407 + chan*5; + if (chan < 27) /* 15-26 */ + return 2512 + ((chan-15)*20); + return 5000 + (chan*5); + } +} + +/* + * Place holder function ic_get_ext_busy + */ +int +ol_if_dfs_get_ext_busy(struct ieee80211com *ic) +{ + return (0); +} + +/* + * ic_get_mib_cycle_counts_pct + */ +int +ol_if_dfs_get_mib_cycle_counts_pct(struct ieee80211com *ic, + u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt) +{ + return (0); +} + +u_int16_t +ol_if_dfs_usenol(struct ieee80211com *ic) +{ +#if ATH_SUPPORT_DFS + return(dfs_usenol(ic)); +#else + return (0); +#endif /* ATH_SUPPORT_DFS */ + return 0; +} + +/* + * Function to indicate Radar on the current + * SAP operating channel.This indication will + * be posted to SAP to select a new channel + * randomly and issue a vdev restart to + * operate on the new channel. + */ +void +ieee80211_mark_dfs(struct ieee80211com *ic, struct ieee80211_channel *ichan) +{ + int status; + status = wma_dfs_indicate_radar(ic, ichan); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_stub.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_stub.h new file mode 100644 index 0000000000000..5a9a68fc1620c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma_stub.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WMA_STUB +#define WMA_STUB + +#include "vos_api.h" +#include "vos_packet.h" +#include "vos_types.h" + +static inline VOS_STATUS wma_shutdown(v_PVOID_t pVosContext, v_BOOL_t closeTransport) +{ + return VOS_STATUS_SUCCESS; +} + +static inline void WMA_TimerTrafficStatsInd(void *pWMA) { + return; +} + +static inline VOS_STATUS WMA_GetWcnssHardwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + return VOS_STATUS_SUCCESS; +} + +static inline VOS_STATUS WMA_GetWcnssWlanCompiledVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion) +{ + return VOS_STATUS_SUCCESS; +} + +static inline tANI_U8 WMA_getFwWlanFeatCaps(tANI_U8 featEnumValue) +{ + return featEnumValue; +} + +static inline void WMA_disableCapablityFeature(tANI_U8 feature_index) { + return; +} + +static inline VOS_STATUS WMA_HALDumpCmdReq(tpAniSirGlobal pMac, tANI_U32 cmd, + tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, + tANI_U32 arg4, tANI_U8 *pBuffer) { + return VOS_STATUS_SUCCESS; +} + +static inline void WMA_TrafficStatsTimerActivate(v_BOOL_t activate) +{ + return; +} + +static inline VOS_STATUS WMA_GetWcnssWlanReportedVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion) +{ + return VOS_STATUS_SUCCESS; +} + +static inline void WMA_featureCapsExchange(v_PVOID_t pVosContext) { + return; +} + +static inline void WMA_UpdateRssiBmps(v_PVOID_t pvosGCtx, + v_U8_t staId, v_S7_t rssi) +{ +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_helper.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_helper.c new file mode 100644 index 0000000000000..1edd553fbbadd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_helper.c @@ -0,0 +1,998 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* wmi_tlv_platform.c file will be different for different components like Pronto firmware, Pronto windows host driver, + Pronto LA host driver because their memory management functions are different */ +#include "wmi_tlv_platform.c" +#include "wmi_tlv_defs.h" +#include "wmi_version.h" + +#define WMITLV_GET_ATTRIB_NUM_TLVS 0xFFFFFFFF + +#define WMITLV_GET_CMDID(val) (val & 0x00FFFFFF) +#define WMITLV_GET_NUM_TLVS(val) ((val >> 24) & 0xFF) + +#define WMITLV_GET_TAGID(val) (val & 0x00000FFF) +#define WMITLV_GET_TAG_STRUCT_SIZE(val) ((val >> 12) & 0x000001FF) +#define WMITLV_GET_TAG_ARRAY_SIZE(val) ((val >> 21) & 0x000001FF) +#define WMITLV_GET_TAG_VARIED(val) ((val >> 30) & 0x00000001) + +#define WMITLV_SET_ATTRB0(id) ((WMITLV_GET_TAG_NUM_TLV_ATTRIB(id) << 24) | (id & 0x00FFFFFF)) +#define WMITLV_SET_ATTRB1(tagID, tagStructSize, tagArraySize, tagVaried) (((tagVaried&0x1)<<30) | ((tagArraySize&0x1FF)<<21) | ((tagStructSize&0x1FF)<<12) | (tagID&0xFFF)) + +#define WMITLV_OP_SET_TLV_ATTRIB_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + WMITLV_SET_ATTRB1(elem_tlv_tag, sizeof(elem_struc_type), arr_size, var_len), + +#define WMITLV_GET_CMD_EVT_ATTRB_LIST(id) \ + WMITLV_SET_ATTRB0(id), \ + WMITLV_TABLE(id,SET_TLV_ATTRIB,NULL,0) + +A_UINT32 cmdAttrList[] = + { + WMITLV_ALL_CMD_LIST(WMITLV_GET_CMD_EVT_ATTRB_LIST) + }; + +A_UINT32 evtAttrList[] = + { + WMITLV_ALL_EVT_LIST(WMITLV_GET_CMD_EVT_ATTRB_LIST) + }; + + +#ifdef NO_DYNAMIC_MEM_ALLOC +static wmitlv_cmd_param_info *g_WmiStaticCmdParamInfoBuf = NULL; +A_UINT32 g_WmiStaticMaxCmdParamTlvs=0; +#endif + +/* TLV helper routines */ + +/* + * WMI TLV Helper function to set the static cmd_param_tlv structure and number of TLVs that can be + * accomodated in the structure. This function should be used when dynamic memory allocation is not + * supported. + * + * When dynamic memory allocation is not supported by any component then NO_DYNAMIC_MEMALLOC + * macro has to be defined in respective tlv_platform.c file. And respective component has to allocate + * cmd_param_tlv structure buffer to accomodate whatever number of TLV's. Both the buffer address + * and number of TLV's that can be accomodated in the buffer should be sent as arguments to this function. + * + * Return None + */ +void +wmitlv_set_static_param_tlv_buf(void *param_tlv_buf, A_UINT32 max_tlvs_accomodated) +{ +#ifdef NO_DYNAMIC_MEM_ALLOC + g_WmiStaticCmdParamInfoBuf = param_tlv_buf; + g_WmiStaticMaxCmdParamTlvs = max_tlvs_accomodated; +#endif +} + +/* + * WMI TLV Helper functions to find the attributes of the Command/Event TLVs. + * Return 0 if success. Return >=1 if failure. + */ +A_UINT32 wmitlv_get_attributes(A_UINT32 is_cmd_id, A_UINT32 cmd_event_id, A_UINT32 curr_tlv_order, wmitlv_attributes_struc* tlv_attr_ptr) +{ + A_UINT32 i, base_index, num_tlvs, num_entries; + A_UINT32 *pAttrArrayList; + + if (is_cmd_id) + { + pAttrArrayList = &cmdAttrList[0]; + num_entries = (sizeof(cmdAttrList)/sizeof(A_UINT32)); + } + else + { + pAttrArrayList = &evtAttrList[0]; + num_entries = (sizeof(evtAttrList)/sizeof(A_UINT32)); + } + + for (i = 0; i < num_entries; i++) + { + num_tlvs = WMITLV_GET_NUM_TLVS(pAttrArrayList[i]); + if (WMITLV_GET_CMDID(cmd_event_id) == WMITLV_GET_CMDID(pAttrArrayList[i])) + { + tlv_attr_ptr->cmd_num_tlv = num_tlvs; + /* Return success from here when only number of TLVS for this command/event is required */ + if (curr_tlv_order == WMITLV_GET_ATTRIB_NUM_TLVS) + { + wmi_tlv_print_verbose("%s: WMI TLV attribute definitions for %s:0x%x found; num_of_tlvs:%d\n", + __func__, (is_cmd_id ? "Cmd" : "Evt"), cmd_event_id, num_tlvs); + return 0; + } + + /* Return failure if tlv_order is more than the expected number of TLVs */ + if (curr_tlv_order >= num_tlvs) + { + wmi_tlv_print_error("%s: ERROR: TLV order %d greater than num_of_tlvs:%d for %s:0x%x\n", + __func__, curr_tlv_order, num_tlvs, (is_cmd_id ? "Cmd" : "Evt"), cmd_event_id); + return 1; + } + + base_index = i + 1; // index to first TLV attributes + wmi_tlv_print_verbose("%s: WMI TLV attributes for %s:0x%x tlv[%d]:0x%x\n", + __func__, (is_cmd_id ? "Cmd" : "Evt"), cmd_event_id, curr_tlv_order, pAttrArrayList[(base_index+curr_tlv_order)]); + tlv_attr_ptr->tag_order = curr_tlv_order; + tlv_attr_ptr->tag_id = WMITLV_GET_TAGID(pAttrArrayList[(base_index+curr_tlv_order)]); + tlv_attr_ptr->tag_struct_size = WMITLV_GET_TAG_STRUCT_SIZE(pAttrArrayList[(base_index+curr_tlv_order)]); + tlv_attr_ptr->tag_varied_size = WMITLV_GET_TAG_VARIED(pAttrArrayList[(base_index+curr_tlv_order)]); + tlv_attr_ptr->tag_array_size = WMITLV_GET_TAG_ARRAY_SIZE(pAttrArrayList[(base_index+curr_tlv_order)]); + return 0; + } + i += num_tlvs; + } + + wmi_tlv_print_error("%s: ERROR: Didn't found WMI TLV attribute definitions for %s:0x%x\n", + __func__, (is_cmd_id ? "Cmd" : "Evt"), cmd_event_id); + return 1; +} + +/* + * Helper Function to vaidate the prepared TLV's for an WMI event/command to be sent + * Return 0 if success. + * <0 if failure. + */ +static int +wmitlv_check_tlv_params( + void *os_handle, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 is_cmd_id, A_UINT32 wmi_cmd_event_id) +{ + wmitlv_attributes_struc attr_struct_ptr; + A_UINT32 buf_idx = 0; + A_UINT32 tlv_index = 0; + A_UINT8 *buf_ptr = (unsigned char *)param_struc_ptr; + A_UINT32 expected_num_tlvs, expected_tlv_len; + + /* Get the number of TLVs for this command/event */ + if (wmitlv_get_attributes(is_cmd_id, wmi_cmd_event_id, WMITLV_GET_ATTRIB_NUM_TLVS, &attr_struct_ptr) != 0) + { + wmi_tlv_print_error("%s: ERROR: Couldn't get expected number of TLVs for Cmd=%d\n", + __func__, wmi_cmd_event_id); + goto Error_wmitlv_check_tlv_params; + } + + /* NOTE: the returned number of TLVs is in "attr_struct_ptr.cmd_num_tlv" */ + + expected_num_tlvs = attr_struct_ptr.cmd_num_tlv; + + while ((buf_idx + WMI_TLV_HDR_SIZE) <= param_buf_len) + { + A_UINT32 curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr)); + A_UINT32 curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); + + if ((buf_idx + WMI_TLV_HDR_SIZE + curr_tlv_len) > param_buf_len) + { + wmi_tlv_print_error("%s: ERROR: Invalid TLV length for Cmd=%d Tag_order=%d buf_idx=%d Tag:%d Len:%d TotalLen:%d\n", + __func__, wmi_cmd_event_id, tlv_index, buf_idx, curr_tlv_tag, curr_tlv_len, param_buf_len); + goto Error_wmitlv_check_tlv_params; + } + + + /* Get the attributes of the TLV with the given order in "tlv_index" */ + wmi_tlv_OS_MEMZERO(&attr_struct_ptr,sizeof(wmitlv_attributes_struc)); + if (wmitlv_get_attributes(is_cmd_id, wmi_cmd_event_id, tlv_index, &attr_struct_ptr) != 0) + { + wmi_tlv_print_error("%s: ERROR: No TLV attributes found for Cmd=%d Tag_order=%d\n", + __func__, wmi_cmd_event_id, tlv_index); + goto Error_wmitlv_check_tlv_params; + } + + /* Found the TLV that we wanted */ + wmi_tlv_print_verbose("%s: [tlv %d]: tag=%d, len=%d\n", __func__, tlv_index, curr_tlv_tag, curr_tlv_len); + + /* Validating Tag ID order */ + if (curr_tlv_tag != attr_struct_ptr.tag_id) { + wmi_tlv_print_error("%s: ERROR: TLV has wrong tag in order for Cmd=0x%x. Given=%d, Expected=%d.\n", + __func__, wmi_cmd_event_id,curr_tlv_tag, attr_struct_ptr.tag_id); + goto Error_wmitlv_check_tlv_params; + } + + /* Validate Tag length */ + /* Array TLVs length checking needs special handling */ + if ((curr_tlv_tag >= WMITLV_TAG_FIRST_ARRAY_ENUM) && (curr_tlv_tag <= WMITLV_TAG_LAST_ARRAY_ENUM)) + { + if (attr_struct_ptr.tag_varied_size == WMITLV_SIZE_FIX) + { + /* Array size can't be invalid for fixed size Array TLV */ + if (WMITLV_ARR_SIZE_INVALID == attr_struct_ptr.tag_array_size){ + wmi_tlv_print_error("%s: ERROR: array_size can't be invalid for Array TLV Cmd=0x%x Tag=%d\n", + __func__, wmi_cmd_event_id, curr_tlv_tag); + goto Error_wmitlv_check_tlv_params; + } + + expected_tlv_len = attr_struct_ptr.tag_array_size * attr_struct_ptr.tag_struct_size; + /* Paddding is only required for Byte array Tlvs all other array tlv's should be aligned to 4 bytes during their definition */ + if (WMITLV_TAG_ARRAY_BYTE == attr_struct_ptr.tag_id) + { + expected_tlv_len = roundup(expected_tlv_len, sizeof(A_UINT32)); + } + + if (curr_tlv_len != expected_tlv_len){ + wmi_tlv_print_error("%s: ERROR: TLV has wrong length for Cmd=0x%x. Tag_order=%d Tag=%d, Given_Len:%d Expected_Len=%d.\n", + __func__, wmi_cmd_event_id, tlv_index, curr_tlv_tag, curr_tlv_len, expected_tlv_len); + goto Error_wmitlv_check_tlv_params; + } + } + else + { + /* Array size should be invalid for variable size Array TLV */ + if (WMITLV_ARR_SIZE_INVALID != attr_struct_ptr.tag_array_size){ + wmi_tlv_print_error("%s: ERROR: array_size should be invalid for Array TLV Cmd=0x%x Tag=%d\n", + __func__, wmi_cmd_event_id, curr_tlv_tag); + goto Error_wmitlv_check_tlv_params; + } + + /* Incase of variable length TLV's, there is no expectation on the length field so do whatever checking + you can depending on the TLV tag if TLV length is non-zero */ + if (curr_tlv_len != 0) + { + /* Verify TLV length is aligned to the size of structure */ + if ((curr_tlv_len%attr_struct_ptr.tag_struct_size)!=0) + { + wmi_tlv_print_error("%s: ERROR: TLV length %d for Cmd=0x%x is not aligned to size of structure(%d bytes)\n", + __func__, curr_tlv_len, wmi_cmd_event_id, attr_struct_ptr.tag_struct_size); + goto Error_wmitlv_check_tlv_params; + } + + if (curr_tlv_tag == WMITLV_TAG_ARRAY_STRUC) + { + A_UINT8 *tlv_buf_ptr = NULL; + A_UINT32 in_tlv_len; + A_UINT32 idx; + A_UINT32 num_of_elems; + + /* Verify length of inner TLVs */ + + num_of_elems = curr_tlv_len/attr_struct_ptr.tag_struct_size; + /* Set tlv_buf_ptr to the first inner TLV address */ + tlv_buf_ptr = buf_ptr + WMI_TLV_HDR_SIZE; + for(idx=0; idx g_WmiStaticMaxCmdParamTlvs) + { + /* Error: Expecting more TLVs that accomodated for static structure */ + wmi_tlv_print_error("%s: Error: Expecting more TLVs that accomodated for static structure. Expected:%d Accomodated:%d\n", + __func__, attr_struct_ptr.cmd_num_tlv, g_WmiStaticMaxCmdParamTlvs); + return -1; + } +#endif + if (*wmi_cmd_struct_ptr == NULL) { + /* Error: unable to alloc memory */ + wmi_tlv_print_error("%s: Error: unable to alloc memory (size=%d) for TLV\n", + __func__, len_wmi_cmd_struct_buf); + return -1; + } + + + cmd_param_tlvs_ptr = (wmitlv_cmd_param_info *)*wmi_cmd_struct_ptr; + wmi_tlv_OS_MEMZERO(cmd_param_tlvs_ptr, len_wmi_cmd_struct_buf); + remaining_expected_tlvs = attr_struct_ptr.cmd_num_tlv; + + while (((buf_idx + WMI_TLV_HDR_SIZE) <= param_buf_len)&&(remaining_expected_tlvs)) + { + A_UINT32 curr_tlv_tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(buf_ptr)); + A_UINT32 curr_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); + int num_padding_bytes = 0; + + /* Get the attributes of the TLV with the given order in "tlv_index" */ + wmi_tlv_OS_MEMZERO(&attr_struct_ptr,sizeof(wmitlv_attributes_struc)); + if (wmitlv_get_attributes(is_cmd_id, wmi_cmd_event_id, tlv_index, &attr_struct_ptr) != 0) + { + wmi_tlv_print_error("%s: ERROR: No TLV attributes found for Cmd=%d Tag_order=%d\n", + __func__, wmi_cmd_event_id, tlv_index); + goto Error_wmitlv_check_and_pad_tlvs; + } + + /* Found the TLV that we wanted */ + wmi_tlv_print_verbose("%s: [tlv %d]: tag=%d, len=%d\n", __func__, tlv_index, curr_tlv_tag, curr_tlv_len); + + /* Validating Tag order */ + if (curr_tlv_tag != attr_struct_ptr.tag_id) { + wmi_tlv_print_error("%s: ERROR: TLV has wrong tag in order for Cmd=0x%x. Given=%d, Expected=%d.\n", + __func__, wmi_cmd_event_id,curr_tlv_tag, attr_struct_ptr.tag_id); + goto Error_wmitlv_check_and_pad_tlvs; + } + + if ((curr_tlv_tag >= WMITLV_TAG_FIRST_ARRAY_ENUM) && (curr_tlv_tag <= WMITLV_TAG_LAST_ARRAY_ENUM)) + { + /* Current Tag is an array of some kind. */ + /* Skip the TLV header of this array */ + buf_ptr += WMI_TLV_HDR_SIZE; + buf_idx += WMI_TLV_HDR_SIZE; + } + else + { + /* Non-array TLV. */ + curr_tlv_len += WMI_TLV_HDR_SIZE; + } + + if (attr_struct_ptr.tag_varied_size == WMITLV_SIZE_FIX) + { + /* This TLV is fixed length */ + if (WMITLV_ARR_SIZE_INVALID == attr_struct_ptr.tag_array_size) + { + tlv_size_diff = curr_tlv_len - attr_struct_ptr.tag_struct_size; + num_of_elems = (curr_tlv_len>WMI_TLV_HDR_SIZE)?1:0; + } + else + { + tlv_size_diff = curr_tlv_len - (attr_struct_ptr.tag_struct_size*attr_struct_ptr.tag_array_size); + num_of_elems = attr_struct_ptr.tag_array_size; + } + } + else + { + /* This TLV has a variable number of elements */ + if (WMITLV_TAG_ARRAY_STRUC == attr_struct_ptr.tag_id) + { + A_UINT32 in_tlv_len = 0; + + if (curr_tlv_len != 0) + { + in_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)); + in_tlv_len += WMI_TLV_HDR_SIZE; + tlv_size_diff = in_tlv_len - attr_struct_ptr.tag_struct_size; + num_of_elems = curr_tlv_len/in_tlv_len; + wmi_tlv_print_verbose("%s: WARN: TLV array of structures in_tlv_len=%d struct_size:%d diff:%d num_of_elems=%d \n", + __func__, in_tlv_len, attr_struct_ptr.tag_struct_size, tlv_size_diff, num_of_elems); + } + else + { + tlv_size_diff = 0; + num_of_elems = 0; + } + } + else if ((WMITLV_TAG_ARRAY_UINT32 == attr_struct_ptr.tag_id) || + (WMITLV_TAG_ARRAY_BYTE == attr_struct_ptr.tag_id) || + (WMITLV_TAG_ARRAY_FIXED_STRUC == attr_struct_ptr.tag_id)) + { + tlv_size_diff = 0; + num_of_elems = curr_tlv_len/attr_struct_ptr.tag_struct_size; + } + else + { + wmi_tlv_print_error("%s ERROR Need to handle this tag ID for variable length %d\n",__func__,attr_struct_ptr.tag_id); + goto Error_wmitlv_check_and_pad_tlvs; + } + } + + if ((WMITLV_TAG_ARRAY_STRUC == attr_struct_ptr.tag_id) && + (tlv_size_diff!=0)) + { + void *new_tlv_buf = NULL; + A_UINT8 *tlv_buf_ptr = NULL; + A_UINT32 in_tlv_len; + A_UINT32 i; + + if (attr_struct_ptr.tag_varied_size == WMITLV_SIZE_FIX) + { + /* This is not allowed. The tag WMITLV_TAG_ARRAY_STRUC can only be used with variable-length structure array + should not have a fixed number of elements (contradicting). Use WMITLV_TAG_ARRAY_FIXED_STRUC tag for + fixed size structure array(where structure never change without breaking compatibility) */ + wmi_tlv_print_error("%s: ERROR: TLV (tag=%d) should be variable-length and not fixed length\n", + __func__, curr_tlv_tag); + goto Error_wmitlv_check_and_pad_tlvs; + } + + /* Warning: Needs to allocate a larger structure and pad with zeros */ + wmi_tlv_print_error("%s: WARN: TLV array of structures needs padding. tlv_size_diff=%d\n", + __func__, tlv_size_diff); + + /* incoming structure length */ + in_tlv_len = WMITLV_GET_TLVLEN(WMITLV_GET_HDR(buf_ptr)) + WMI_TLV_HDR_SIZE; +#ifndef NO_DYNAMIC_MEM_ALLOC + wmi_tlv_os_mem_alloc(os_handle, new_tlv_buf, (num_of_elems * attr_struct_ptr.tag_struct_size)); + if (new_tlv_buf == NULL) { + /* Error: unable to alloc memory */ + wmi_tlv_print_error("%s: Error: unable to alloc memory (size=%d) for padding the TLV array %d\n", + __func__, (num_of_elems * attr_struct_ptr.tag_struct_size), curr_tlv_tag); + goto Error_wmitlv_check_and_pad_tlvs; + } + + wmi_tlv_OS_MEMZERO(new_tlv_buf, (num_of_elems * attr_struct_ptr.tag_struct_size)); + tlv_buf_ptr = (A_UINT8 *)new_tlv_buf; + for(i=0; i0) + { + /* Incoming structure size is greater than expected structure size. + so copy the number of bytes equal to expected structure size */ + wmi_tlv_OS_MEMCPY(tlv_buf_ptr, (void*)(buf_ptr+i*in_tlv_len), attr_struct_ptr.tag_struct_size); + } + else + { + /* Incoming structure size is smaller than expected structure size. + so copy the number of bytes equal to incoming structure size + (other bytes would be zeroes) */ + wmi_tlv_OS_MEMCPY(tlv_buf_ptr, (void*)(buf_ptr+i*in_tlv_len), in_tlv_len); + } + tlv_buf_ptr += attr_struct_ptr.tag_struct_size; + } +#else + { + A_UINT8 *src_addr; + A_UINT8 *dst_addr; + A_UINT32 buf_mov_len; + + if (tlv_size_diff < 0) + { + /* Incoming structure size is smaller than expected size then this needs padding for each element in the array */ + + /* Find amount of bytes to be padded for one element */ + num_padding_bytes = tlv_size_diff * -1; + + /* Move subsequent TLVs by number of bytes to be padded for all elements */ + if (param_buf_len > (buf_idx + curr_tlv_len)) + { + src_addr = buf_ptr + curr_tlv_len; + dst_addr = buf_ptr + curr_tlv_len + (num_padding_bytes * num_of_elems); + buf_mov_len = param_buf_len - (buf_idx + curr_tlv_len); + + wmi_tlv_OS_MEMMOVE(dst_addr, src_addr, buf_mov_len); + } + + /* Move subsequent elements of array down by number of bytes to be padded for one element and alse set padding bytes to zero */ + tlv_buf_ptr = buf_ptr; + for(i=0; i (buf_idx + curr_tlv_len)) + { + src_addr = buf_ptr + curr_tlv_len; + dst_addr = buf_ptr + curr_tlv_len + (num_padding_bytes * num_of_elems); + buf_mov_len = param_buf_len - (buf_idx + curr_tlv_len); + + wmi_tlv_OS_MEMMOVE(dst_addr, src_addr, buf_mov_len); + } + + /* Update the number of padding bytes to total number of bytes shrinked for all elements in the array */ + num_padding_bytes = num_padding_bytes * num_of_elems; + + new_tlv_buf = buf_ptr; + } + } +#endif + cmd_param_tlvs_ptr[tlv_index].tlv_ptr = new_tlv_buf; + cmd_param_tlvs_ptr[tlv_index].num_elements = num_of_elems; + cmd_param_tlvs_ptr[tlv_index].buf_is_allocated = 1; // Indicates that buffer is allocated + + } + else if (tlv_size_diff>=0) + { + /* Warning: some parameter truncation */ + if (tlv_size_diff > 0) + { + wmi_tlv_print_verbose("%s: WARN: TLV truncated. tlv_size_diff=%d, curr_tlv_len=%d\n", + __func__, tlv_size_diff, curr_tlv_len); + } + /* TODO: this next line needs more comments and explanation */ + cmd_param_tlvs_ptr[tlv_index].tlv_ptr = (attr_struct_ptr.tag_varied_size && !curr_tlv_len)?NULL:(void *)buf_ptr; + cmd_param_tlvs_ptr[tlv_index].num_elements = num_of_elems; + cmd_param_tlvs_ptr[tlv_index].buf_is_allocated = 0; // Indicates that buffer is not allocated + } + else + { + void *new_tlv_buf = NULL; + + /* Warning: Needs to allocate a larger structure and pad with zeros */ + wmi_tlv_print_verbose("%s: WARN: TLV needs padding. tlv_size_diff=%d\n", + __func__, tlv_size_diff); +#ifndef NO_DYNAMIC_MEM_ALLOC + /* Dynamic memory allocation is supported */ + wmi_tlv_os_mem_alloc(os_handle, new_tlv_buf, (curr_tlv_len-tlv_size_diff)); + if (new_tlv_buf == NULL) { + /* Error: unable to alloc memory */ + wmi_tlv_print_error("%s: Error: unable to alloc memory (size=%d) for padding the TLV %d\n", + __func__, (curr_tlv_len-tlv_size_diff), curr_tlv_tag); + goto Error_wmitlv_check_and_pad_tlvs; + } + + wmi_tlv_OS_MEMZERO(new_tlv_buf, (curr_tlv_len-tlv_size_diff)); + wmi_tlv_OS_MEMCPY(new_tlv_buf, (void*)buf_ptr, curr_tlv_len); +#else + /* Dynamic memory allocation is not supported. Padding has to be done with in the existing buffer assuming we have enough space + to grow */ + { + /* Note: tlv_size_diff is a value less than zero */ + /* Move the Subsequent TLVs by amount of bytes needs to be padded */ + A_UINT8 *src_addr; + A_UINT8 *dst_addr; + A_UINT32 src_len; + + num_padding_bytes = (tlv_size_diff * -1); + + src_addr = buf_ptr + curr_tlv_len; + dst_addr = buf_ptr + curr_tlv_len + num_padding_bytes; + src_len = param_buf_len - (buf_idx + curr_tlv_len); + + wmi_tlv_OS_MEMMOVE(dst_addr, src_addr, src_len); + + /* Set the padding bytes to zeroes */ + wmi_tlv_OS_MEMZERO(src_addr, num_padding_bytes); + + new_tlv_buf = buf_ptr; + } +#endif + cmd_param_tlvs_ptr[tlv_index].tlv_ptr = new_tlv_buf; + cmd_param_tlvs_ptr[tlv_index].num_elements = num_of_elems; + cmd_param_tlvs_ptr[tlv_index].buf_is_allocated = 1; // Indicates that buffer is allocated + } + + tlv_index++; + remaining_expected_tlvs--; + buf_ptr += curr_tlv_len + num_padding_bytes; + buf_idx += curr_tlv_len + num_padding_bytes; + } + + return(0); +Error_wmitlv_check_and_pad_tlvs: + if (is_cmd_id) { + wmitlv_free_allocated_command_tlvs(wmi_cmd_event_id, wmi_cmd_struct_ptr); + } + else { + wmitlv_free_allocated_event_tlvs(wmi_cmd_event_id, wmi_cmd_struct_ptr); + } + *wmi_cmd_struct_ptr = NULL; + return(-1); +} + +/* + * Helper Function to validate and pad(if necessary) for incoming WMI Event TLVs + * Return 0 if success. + <0 if failure. + */ +int +wmitlv_check_and_pad_event_tlvs( + void *os_handle, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id, void **wmi_cmd_struct_ptr) +{ + A_UINT32 is_cmd_id = 0; + return(wmitlv_check_and_pad_tlvs(os_handle,param_struc_ptr,param_buf_len,is_cmd_id,wmi_cmd_event_id,wmi_cmd_struct_ptr)); +} + +/* + * Helper Function to validate and pad(if necessary) for incoming WMI Command TLVs + * Return 0 if success. + <0 if failure. + */ +int +wmitlv_check_and_pad_command_tlvs( + void *os_handle, void *param_struc_ptr, A_UINT32 param_buf_len, A_UINT32 wmi_cmd_event_id, void **wmi_cmd_struct_ptr) +{ + A_UINT32 is_cmd_id = 1; + return(wmitlv_check_and_pad_tlvs(os_handle,param_struc_ptr,param_buf_len,is_cmd_id,wmi_cmd_event_id,wmi_cmd_struct_ptr)); +} + +/* + * Helper Function to free any allocated buffers for WMI Event/Command TLV processing + * Return None + */ +static void wmitlv_free_allocated_tlvs(A_UINT32 is_cmd_id, A_UINT32 cmd_event_id, void **wmi_cmd_struct_ptr) +{ + void *ptr = *wmi_cmd_struct_ptr; + + if(!ptr) + { + wmi_tlv_print_error("%s: Nothing to free for CMD/Event 0x%x\n",__func__,cmd_event_id); + return; + } + +#ifndef NO_DYNAMIC_MEM_ALLOC + +/* macro to free that previously allocated memory for this TLV. When (op==FREE_TLV_ELEM). */ +#define WMITLV_OP_FREE_TLV_ELEM_macro(param_ptr, param_len, wmi_cmd_event_id, elem_tlv_tag, elem_struc_type, elem_name, var_len, arr_size) \ + if ((((WMITLV_TYPEDEF_STRUCT_PARAMS_TLVS(wmi_cmd_event_id)*)ptr)->WMITLV_FIELD_BUF_IS_ALLOCATED(elem_name)) && \ + (((WMITLV_TYPEDEF_STRUCT_PARAMS_TLVS(wmi_cmd_event_id)*)ptr)->elem_name != NULL)) \ + { \ + wmi_tlv_os_mem_free(((WMITLV_TYPEDEF_STRUCT_PARAMS_TLVS(wmi_cmd_event_id)*)ptr)->elem_name);\ + } + + +#define WMITLV_FREE_TLV_ELEMS(id) \ + case id:\ + {\ + WMITLV_TABLE(id, FREE_TLV_ELEM, NULL, 0) \ + } \ + break; + + if (is_cmd_id) { + switch(cmd_event_id) + { + WMITLV_ALL_CMD_LIST(WMITLV_FREE_TLV_ELEMS); + default: + wmi_tlv_print_error("%s: ERROR: Cannot find the TLVs attributes for Cmd=0x%x, %d\n", + __func__, cmd_event_id, cmd_event_id); + } + } + else { + switch(cmd_event_id) + { + WMITLV_ALL_EVT_LIST(WMITLV_FREE_TLV_ELEMS); + default: + wmi_tlv_print_error("%s: ERROR: Cannot find the TLVs attributes for Cmd=0x%x, %d\n", + __func__, cmd_event_id, cmd_event_id); + } + } + + wmi_tlv_os_mem_free(*wmi_cmd_struct_ptr); + *wmi_cmd_struct_ptr = NULL; +#endif + + return; +} + +/* + * Helper Function to free any allocated buffers for WMI Command TLV processing + * Return None + */ +void wmitlv_free_allocated_command_tlvs(A_UINT32 cmd_event_id, void **wmi_cmd_struct_ptr) +{ + wmitlv_free_allocated_tlvs(1, cmd_event_id, wmi_cmd_struct_ptr); +} + +/* + * Helper Function to free any allocated buffers for WMI Event TLV processing + * Return None + */ +void wmitlv_free_allocated_event_tlvs(A_UINT32 cmd_event_id, void **wmi_cmd_struct_ptr) +{ + wmitlv_free_allocated_tlvs(0, cmd_event_id, wmi_cmd_struct_ptr); +} + +/* + * Returns 1 if the two given versions are compatible. + * Else return 0 if Incompatible. + */ +int +wmi_versions_are_compatible(wmi_abi_version *vers1, wmi_abi_version *vers2) +{ + if ((vers1->abi_version_ns_0 != vers2->abi_version_ns_0) || + (vers1->abi_version_ns_1 != vers2->abi_version_ns_1) || + (vers1->abi_version_ns_2 != vers2->abi_version_ns_2) || + (vers1->abi_version_ns_3 != vers2->abi_version_ns_3)) + { + /* The namespaces are different. Incompatible. */ + return 0; + } + + if (vers1->abi_version_0 != vers2->abi_version_0) { + /* The major or minor versions are different. Incompatible */ + return 0; + } + /* We ignore the build version */ + return 1; +} + +/* + * Returns 1 if the two given versions are compatible. + * Else return 0 if Incompatible. + */ +int +wmi_versions_can_downgrade(int num_whitelist, wmi_whitelist_version_info *version_whitelist_table, + wmi_abi_version *my_vers, wmi_abi_version *opp_vers, wmi_abi_version *out_vers) +{ + A_UINT8 can_try_to_downgrade; + A_UINT32 my_major_vers = WMI_VER_GET_MAJOR(my_vers->abi_version_0); + A_UINT32 my_minor_vers = WMI_VER_GET_MINOR(my_vers->abi_version_0); + A_UINT32 opp_major_vers = WMI_VER_GET_MAJOR(opp_vers->abi_version_0); + A_UINT32 opp_minor_vers = WMI_VER_GET_MINOR(opp_vers->abi_version_0); + A_UINT32 downgraded_minor_vers; + + if ((my_vers->abi_version_ns_0 != opp_vers->abi_version_ns_0) || + (my_vers->abi_version_ns_1 != opp_vers->abi_version_ns_1) || + (my_vers->abi_version_ns_2 != opp_vers->abi_version_ns_2) || + (my_vers->abi_version_ns_3 != opp_vers->abi_version_ns_3)) + { + /* The namespaces are different. Incompatible. */ + can_try_to_downgrade = FALSE; + } + else if (my_major_vers != opp_major_vers) { + /* Major version is different. Incompatible and cannot downgrade. */ + can_try_to_downgrade = FALSE; + } + else { + /* Same major version. */ + + if (my_minor_vers < opp_minor_vers) { + /* Opposite party is newer. Incompatible and cannot downgrade. */ + can_try_to_downgrade = FALSE; + } + else if (my_minor_vers > opp_minor_vers) { + /* Opposite party is older. Check whitelist if we can downgrade */ + can_try_to_downgrade = TRUE; + } + else { + /* Same version */ + wmi_tlv_OS_MEMCPY(out_vers, my_vers, sizeof(wmi_abi_version)); + return 1; + } + } + + if (!can_try_to_downgrade) { + wmi_tlv_print_error("%s: Warning: incompatible WMI version.\n", __func__); + wmi_tlv_OS_MEMCPY(out_vers, my_vers, sizeof(wmi_abi_version)); + return 0; + } + /* Try to see we can downgrade the supported version */ + downgraded_minor_vers = my_minor_vers; + while (downgraded_minor_vers > opp_minor_vers) + { + A_UINT8 downgraded = FALSE; + int i; + + for (i=0; iabi_version_ns_0) || + (version_whitelist_table[i].namespace_1 != my_vers->abi_version_ns_1) || + (version_whitelist_table[i].namespace_2 != my_vers->abi_version_ns_2) || + (version_whitelist_table[i].namespace_3 != my_vers->abi_version_ns_3)) + { + continue; /* skip */ + } + if (version_whitelist_table[i].minor == downgraded_minor_vers) { + /* Found the next version that I can downgrade */ + wmi_tlv_print_error("%s: Note: found a whitelist entry to downgrade. wh. list ver: %d,%d,0x%x 0x%x 0x%x 0x%x\n", + __func__, version_whitelist_table[i].major, version_whitelist_table[i].minor, + version_whitelist_table[i].namespace_0, version_whitelist_table[i].namespace_1, + version_whitelist_table[i].namespace_2, version_whitelist_table[i].namespace_3); + downgraded_minor_vers--; + downgraded = TRUE; + break; + } + } + if (!downgraded) { + break; /* Done since we did not find any whitelist to downgrade version */ + } + } + wmi_tlv_OS_MEMCPY(out_vers, my_vers, sizeof(wmi_abi_version)); + out_vers->abi_version_0 = WMI_VER_GET_VERSION_0(my_major_vers, downgraded_minor_vers); + if (downgraded_minor_vers != opp_minor_vers) { + wmi_tlv_print_error("%s: Warning: incompatible WMI version and cannot downgrade.\n", __func__); + return 0; /* Incompatible */ + } + else { + return 1; /* Compatible */ + } +} + +/* + * This routine will compare and set the WMI ABI version. + * First, compare my version with the opposite side's version. + * If incompatible, then check the whitelist to see if our side can downgrade. + * Finally, fill in the final ABI version into the output, out_vers. + * Return 0 if the output version is compatible . + * Else return 1 if the output version is incompatible. . + */ +int +wmi_cmp_and_set_abi_version(int num_whitelist, wmi_whitelist_version_info *version_whitelist_table, + struct _wmi_abi_version *my_vers, + struct _wmi_abi_version *opp_vers, + struct _wmi_abi_version *out_vers) +{ + wmi_tlv_print_verbose("%s: Our WMI Version: Mj=%d, Mn=%d, bd=%d, ns0=0x%x ns1:0x%x ns2:0x%x ns3:0x%x\n", __func__, + WMI_VER_GET_MAJOR(my_vers->abi_version_0), WMI_VER_GET_MINOR(my_vers->abi_version_0), my_vers->abi_version_1, + my_vers->abi_version_ns_0, my_vers->abi_version_ns_1, my_vers->abi_version_ns_2, my_vers->abi_version_ns_3); + + wmi_tlv_print_verbose("%s: Opposite side WMI Version: Mj=%d, Mn=%d, bd=%d, ns0=0x%x ns1:0x%x ns2:0x%x ns3:0x%x\n", __func__, + WMI_VER_GET_MAJOR(opp_vers->abi_version_0), WMI_VER_GET_MINOR(opp_vers->abi_version_0), opp_vers->abi_version_1, + opp_vers->abi_version_ns_0, opp_vers->abi_version_ns_1, opp_vers->abi_version_ns_2, opp_vers->abi_version_ns_3); + + /* By default, the output version is our version. */ + wmi_tlv_OS_MEMCPY(out_vers, my_vers, sizeof(wmi_abi_version)); + if (!wmi_versions_are_compatible(my_vers, opp_vers)) + { + /* Our host version and the given firmware version are incompatible. */ + if (wmi_versions_can_downgrade(num_whitelist, version_whitelist_table, my_vers, opp_vers, out_vers)) + { + /* We can downgrade our host versions to match firmware. */ + wmi_tlv_print_error("%s: Host downgraded WMI Versions to match fw. Ret version: Mj=%d, Mn=%d, bd=%d, ns0=0x%x ns1:0x%x ns2:0x%x ns3:0x%x\n", __func__, + WMI_VER_GET_MAJOR(out_vers->abi_version_0), WMI_VER_GET_MINOR(out_vers->abi_version_0), out_vers->abi_version_1, + out_vers->abi_version_ns_0, out_vers->abi_version_ns_1, out_vers->abi_version_ns_2, out_vers->abi_version_ns_3); + return 0; /* Compatible */ + } + else { + /* Warn: We cannot downgrade our host versions to match firmware. */ + wmi_tlv_print_error("%s: WARN: Host WMI Versions mismatch with fw. Ret version: Mj=%d, Mn=%d, bd=%d, ns0=0x%x ns1:0x%x ns2:0x%x ns3:0x%x\n", __func__, + WMI_VER_GET_MAJOR(out_vers->abi_version_0), WMI_VER_GET_MINOR(out_vers->abi_version_0), out_vers->abi_version_1, + out_vers->abi_version_ns_0, out_vers->abi_version_ns_1, out_vers->abi_version_ns_2, out_vers->abi_version_ns_3); + + return 1; /* Incompatible */ + } + } + else { + /* We are compatible. Our host version is the output version */ + wmi_tlv_print_verbose("%s: Host and FW Compatible WMI Versions. Ret version: Mj=%d, Mn=%d, bd=%d, ns0=0x%x ns1:0x%x ns2:0x%x ns3:0x%x\n", __func__, + WMI_VER_GET_MAJOR(out_vers->abi_version_0), WMI_VER_GET_MINOR(out_vers->abi_version_0), out_vers->abi_version_1, + out_vers->abi_version_ns_0, out_vers->abi_version_ns_1, out_vers->abi_version_ns_2, out_vers->abi_version_ns_3); + return 0; /* Compatible */ + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_platform.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_platform.c new file mode 100644 index 0000000000000..09091b589bc17 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_tlv_platform.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * LMAC offload interface functions for WMI TLV Interface + */ + +#include "ol_if_athvar.h" +#include /* adf_os_mem_alloc,free, etc. */ +#include +#include "htc_api.h" +#include "wmi.h" +#include "wma.h" + +// QCA Main host has dynamic memory allocation and should not define NO_DYNAMIC_MEM_ALLOC +//#define NO_DYNAMIC_MEM_ALLOC + +/* Following macro definitions use OS or platform specific functions */ +/* Following macro definitions use QCA MAIN windows host driver(applicable for Perigrene and its future platforms, + Pronto and its future platforms) specific APIs */ + #define dummy_print(fmt, ...) {} + #define wmi_tlv_print_verbose dummy_print + #define wmi_tlv_print_error adf_os_print + #define wmi_tlv_OS_MEMCPY OS_MEMCPY + #define wmi_tlv_OS_MEMZERO OS_MEMZERO + #define wmi_tlv_OS_MEMMOVE OS_MEMMOVE + +#ifndef NO_DYNAMIC_MEM_ALLOC + #define wmi_tlv_os_mem_alloc(scn, ptr, numBytes) \ + { \ + (ptr) = OS_MALLOC(NULL, (numBytes), GFP_ATOMIC); \ + } + #define wmi_tlv_os_mem_free adf_os_mem_free +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c new file mode 100644 index 0000000000000..346ea83003293 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c @@ -0,0 +1,1135 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * Host WMI unified implementation + */ +#include "athdefs.h" +#include "osapi_linux.h" +#include "a_types.h" +#include "a_debug.h" +#include "ol_if_athvar.h" +#include "ol_defines.h" +#include "ol_fw.h" +#include "htc_api.h" +#include "htc_api.h" +#include "dbglog_host.h" +#include "wmi.h" +#include "wmi_unified_priv.h" +#include "wma_api.h" +#include "wma.h" +#include "macTrace.h" +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#endif + +#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS) +#include +#endif + +#define WMI_MIN_HEAD_ROOM 64 +#define WMI_MAX_LEN_BYTES 2048 + +#ifdef WMI_INTERFACE_EVENT_LOGGING +/* WMI commands */ +u_int32_t g_wmi_command_buf_idx = 0; +struct wmi_command_debug wmi_command_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; + +/* WMI commands TX completed */ +u_int32_t g_wmi_command_tx_cmp_buf_idx = 0; +struct wmi_command_debug wmi_command_tx_cmp_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; + +/* WMI events when processed */ +u_int32_t g_wmi_event_buf_idx = 0; +struct wmi_event_debug wmi_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; + +/* WMI events when queued */ +u_int32_t g_wmi_rx_event_buf_idx = 0; +struct wmi_event_debug wmi_rx_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; + +#define WMI_COMMAND_RECORD(a, b) { \ + if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_command_buf_idx) \ + g_wmi_command_buf_idx = 0; \ + wmi_command_log_buffer[g_wmi_command_buf_idx].command = a; \ + adf_os_mem_copy(wmi_command_log_buffer[g_wmi_command_buf_idx].data, b, 16);\ + wmi_command_log_buffer[g_wmi_command_buf_idx].time = \ + adf_get_boottime(); \ + g_wmi_command_buf_idx++; \ +} + +#define WMI_COMMAND_TX_CMP_RECORD(a, b) { \ + if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_command_tx_cmp_buf_idx) \ + g_wmi_command_tx_cmp_buf_idx = 0; \ + wmi_command_tx_cmp_log_buffer[g_wmi_command_tx_cmp_buf_idx].command = a;\ + adf_os_mem_copy(wmi_command_tx_cmp_log_buffer \ + [g_wmi_command_tx_cmp_buf_idx].data, b, 16); \ + wmi_command_tx_cmp_log_buffer[g_wmi_command_tx_cmp_buf_idx].time =\ + adf_get_boottime(); \ + g_wmi_command_tx_cmp_buf_idx++; \ +} + +#define WMI_EVENT_RECORD(a, b) { \ + if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_event_buf_idx) \ + g_wmi_event_buf_idx = 0; \ + wmi_event_log_buffer[g_wmi_event_buf_idx].event = a; \ + adf_os_mem_copy(wmi_event_log_buffer[g_wmi_event_buf_idx].data, b, 16);\ + wmi_event_log_buffer[g_wmi_event_buf_idx].time = \ + adf_get_boottime(); \ + g_wmi_event_buf_idx++; \ +} + +#define WMI_RX_EVENT_RECORD(a,b) { \ + if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_rx_event_buf_idx) \ + g_wmi_rx_event_buf_idx = 0; \ + wmi_rx_event_log_buffer[g_wmi_rx_event_buf_idx].event = a; \ + adf_os_mem_copy(wmi_rx_event_log_buffer[g_wmi_rx_event_buf_idx].data, b, 16);\ + wmi_rx_event_log_buffer[g_wmi_rx_event_buf_idx].time = \ + adf_get_boottime(); \ + g_wmi_rx_event_buf_idx++; \ +} + +#endif /*WMI_INTERFACE_EVENT_LOGGING*/ + + +static void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf); +int wmi_get_host_credits(wmi_unified_t wmi_handle); +/* WMI buffer APIs */ + +wmi_buf_t +wmi_buf_alloc(wmi_unified_t wmi_handle, u_int16_t len) +{ + wmi_buf_t wmi_buf; + + if (roundup(len + WMI_MIN_HEAD_ROOM, 4) > + wmi_handle->max_msg_len) { + VOS_ASSERT(0); + return NULL; + } + wmi_buf = adf_nbuf_alloc(NULL, roundup(len + WMI_MIN_HEAD_ROOM, 4), + WMI_MIN_HEAD_ROOM, 4, FALSE); + if (!wmi_buf) + return NULL; + + /* Clear the wmi buffer */ + OS_MEMZERO(adf_nbuf_data(wmi_buf), len); + + /* + * Set the length of the buffer to match the allocation size. + */ + adf_nbuf_set_pktlen(wmi_buf, len); + return wmi_buf; +} + +static u_int8_t* get_wmi_cmd_string(WMI_CMD_ID wmi_command) +{ + switch(wmi_command) + { + /** initialize the wlan sub system */ + CASE_RETURN_STRING(WMI_INIT_CMDID); + + /* Scan specific commands */ + + /** start scan request to FW */ + CASE_RETURN_STRING(WMI_START_SCAN_CMDID); + /** stop scan request to FW */ + CASE_RETURN_STRING(WMI_STOP_SCAN_CMDID); + /** full list of channels as defined by the regulatory that will be used by scanner */ + CASE_RETURN_STRING(WMI_SCAN_CHAN_LIST_CMDID); + /** overwrite default priority table in scan scheduler */ + CASE_RETURN_STRING(WMI_SCAN_SCH_PRIO_TBL_CMDID); + /** This command to adjust the priority and min.max_rest_time + * of an on ongoing scan request. + */ + CASE_RETURN_STRING(WMI_SCAN_UPDATE_REQUEST_CMDID); + + /* PDEV(physical device) specific commands */ + /** set regulatorty ctl id used by FW to determine the exact ctl power limits */ + CASE_RETURN_STRING(WMI_PDEV_SET_REGDOMAIN_CMDID); + /** set channel. mainly used for supporting monitor mode */ + CASE_RETURN_STRING(WMI_PDEV_SET_CHANNEL_CMDID); + /** set pdev specific parameters */ + CASE_RETURN_STRING(WMI_PDEV_SET_PARAM_CMDID); + /** enable packet log */ + CASE_RETURN_STRING(WMI_PDEV_PKTLOG_ENABLE_CMDID); + /** disable packet log*/ + CASE_RETURN_STRING(WMI_PDEV_PKTLOG_DISABLE_CMDID); + /** set wmm parameters */ + CASE_RETURN_STRING(WMI_PDEV_SET_WMM_PARAMS_CMDID); + /** set HT cap ie that needs to be carried probe requests HT/VHT channels */ + CASE_RETURN_STRING(WMI_PDEV_SET_HT_CAP_IE_CMDID); + /** set VHT cap ie that needs to be carried on probe requests on VHT channels */ + CASE_RETURN_STRING(WMI_PDEV_SET_VHT_CAP_IE_CMDID); + + /** Command to send the DSCP-to-TID map to the target */ + CASE_RETURN_STRING(WMI_PDEV_SET_DSCP_TID_MAP_CMDID); + /** set quiet ie parameters. primarily used in AP mode */ + CASE_RETURN_STRING(WMI_PDEV_SET_QUIET_MODE_CMDID); + /** Enable/Disable Green AP Power Save */ + CASE_RETURN_STRING(WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID); + /** get TPC config for the current operating channel */ + CASE_RETURN_STRING(WMI_PDEV_GET_TPC_CONFIG_CMDID); + + /** set the base MAC address for the physical device before a VDEV is created. + * For firmware that doesn’t support this feature and this command, the pdev + * MAC address will not be changed. */ + CASE_RETURN_STRING(WMI_PDEV_SET_BASE_MACADDR_CMDID); + + /* eeprom content dump , the same to bdboard data */ + CASE_RETURN_STRING(WMI_PDEV_DUMP_CMDID); + + /* VDEV(virtual device) specific commands */ + /** vdev create */ + CASE_RETURN_STRING(WMI_VDEV_CREATE_CMDID); + /** vdev delete */ + CASE_RETURN_STRING(WMI_VDEV_DELETE_CMDID); + /** vdev start request */ + CASE_RETURN_STRING(WMI_VDEV_START_REQUEST_CMDID); + /** vdev restart request (RX only, NO TX, used for CAC period)*/ + CASE_RETURN_STRING(WMI_VDEV_RESTART_REQUEST_CMDID); + /** vdev up request */ + CASE_RETURN_STRING(WMI_VDEV_UP_CMDID); + /** vdev stop request */ + CASE_RETURN_STRING(WMI_VDEV_STOP_CMDID); + /** vdev down request */ + CASE_RETURN_STRING(WMI_VDEV_DOWN_CMDID); + /* set a vdev param */ + CASE_RETURN_STRING(WMI_VDEV_SET_PARAM_CMDID); + /* set a key (used for setting per peer unicast and per vdev multicast) */ + CASE_RETURN_STRING(WMI_VDEV_INSTALL_KEY_CMDID); + + /* wnm sleep mode command */ + CASE_RETURN_STRING(WMI_VDEV_WNM_SLEEPMODE_CMDID); + CASE_RETURN_STRING(WMI_VDEV_WMM_ADDTS_CMDID); + CASE_RETURN_STRING(WMI_VDEV_WMM_DELTS_CMDID); + CASE_RETURN_STRING(WMI_VDEV_SET_WMM_PARAMS_CMDID); + CASE_RETURN_STRING(WMI_VDEV_SET_GTX_PARAMS_CMDID); + CASE_RETURN_STRING(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID); + + CASE_RETURN_STRING(WMI_VDEV_PLMREQ_START_CMDID); + CASE_RETURN_STRING(WMI_VDEV_PLMREQ_STOP_CMDID); + CASE_RETURN_STRING(WMI_VDEV_TSF_TSTAMP_ACTION_CMDID); + CASE_RETURN_STRING(WMI_VDEV_SET_IE_CMDID); + /* peer specific commands */ + + /** create a peer */ + CASE_RETURN_STRING(WMI_PEER_CREATE_CMDID); + /** delete a peer */ + CASE_RETURN_STRING(WMI_PEER_DELETE_CMDID); + /** flush specific tid queues of a peer */ + CASE_RETURN_STRING(WMI_PEER_FLUSH_TIDS_CMDID); + /** set a parameter of a peer */ + CASE_RETURN_STRING(WMI_PEER_SET_PARAM_CMDID); + /** set peer to associated state. will cary all parameters determined during assocication time */ + CASE_RETURN_STRING(WMI_PEER_ASSOC_CMDID); + /**add a wds (4 address ) entry. used only for testing WDS feature on AP products */ + CASE_RETURN_STRING(WMI_PEER_ADD_WDS_ENTRY_CMDID); + /**remove wds (4 address ) entry. used only for testing WDS feature on AP products */ + CASE_RETURN_STRING(WMI_PEER_REMOVE_WDS_ENTRY_CMDID); + /** set up mcast group infor for multicast to unicast conversion */ + CASE_RETURN_STRING(WMI_PEER_MCAST_GROUP_CMDID); + /** request peer info from FW. FW shall respond with PEER_INFO_EVENTID */ + CASE_RETURN_STRING(WMI_PEER_INFO_REQ_CMDID); + + /* beacon/management specific commands */ + + /** transmit beacon by reference . used for transmitting beacon on low latency interface like pcie */ + CASE_RETURN_STRING(WMI_BCN_TX_CMDID); + /** transmit beacon by value */ + CASE_RETURN_STRING(WMI_PDEV_SEND_BCN_CMDID); + /** set the beacon template. used in beacon offload mode to setup the + * the common beacon template with the FW to be used by FW to generate beacons */ + CASE_RETURN_STRING(WMI_BCN_TMPL_CMDID); + /** set beacon filter with FW */ + CASE_RETURN_STRING(WMI_BCN_FILTER_RX_CMDID); + /* enable/disable filtering of probe requests in the firmware */ + CASE_RETURN_STRING(WMI_PRB_REQ_FILTER_RX_CMDID); + /** transmit management frame by value. will be deprecated */ + CASE_RETURN_STRING(WMI_MGMT_TX_CMDID); + /** set the probe response template. used in beacon offload mode to setup the + * the common probe response template with the FW to be used by FW to generate + * probe responses */ + CASE_RETURN_STRING(WMI_PRB_TMPL_CMDID); + + /** commands to directly control ba negotiation directly from host. only used in test mode */ + + /** turn off FW Auto addba mode and let host control addba */ + CASE_RETURN_STRING(WMI_ADDBA_CLEAR_RESP_CMDID); + /** send add ba request */ + CASE_RETURN_STRING(WMI_ADDBA_SEND_CMDID); + CASE_RETURN_STRING(WMI_ADDBA_STATUS_CMDID); + /** send del ba */ + CASE_RETURN_STRING(WMI_DELBA_SEND_CMDID); + /** set add ba response will be used by FW to generate addba response*/ + CASE_RETURN_STRING(WMI_ADDBA_SET_RESP_CMDID); + /** send single VHT MPDU with AMSDU */ + CASE_RETURN_STRING(WMI_SEND_SINGLEAMSDU_CMDID); + + /** Station power save specific config */ + /** enable/disable station powersave */ + CASE_RETURN_STRING(WMI_STA_POWERSAVE_MODE_CMDID); + /** set station power save specific parameter */ + CASE_RETURN_STRING(WMI_STA_POWERSAVE_PARAM_CMDID); + /** set station mimo powersave mode */ + CASE_RETURN_STRING(WMI_STA_MIMO_PS_MODE_CMDID); + + + /** DFS-specific commands */ + /** enable DFS (radar detection)*/ + CASE_RETURN_STRING(WMI_PDEV_DFS_ENABLE_CMDID); + /** disable DFS (radar detection)*/ + CASE_RETURN_STRING(WMI_PDEV_DFS_DISABLE_CMDID); + /** enable DFS phyerr/parse filter offload */ + CASE_RETURN_STRING(WMI_DFS_PHYERR_FILTER_ENA_CMDID); + /** enable DFS phyerr/parse filter offload */ + CASE_RETURN_STRING(WMI_DFS_PHYERR_FILTER_DIS_CMDID); + + /* Roaming specific commands */ + /** set roam scan mode */ + CASE_RETURN_STRING(WMI_ROAM_SCAN_MODE); + /** set roam scan rssi threshold below which roam scan is enabled */ + CASE_RETURN_STRING(WMI_ROAM_SCAN_RSSI_THRESHOLD); + /** set roam scan period for periodic roam scan mode */ + CASE_RETURN_STRING(WMI_ROAM_SCAN_PERIOD); + /** set roam scan trigger rssi change threshold */ + CASE_RETURN_STRING(WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD); + /** set roam AP profile */ + CASE_RETURN_STRING(WMI_ROAM_AP_PROFILE); + /** set channel list for roam scans */ + CASE_RETURN_STRING(WMI_ROAM_CHAN_LIST); + /** offload scan specific commands */ + /** set offload scan AP profile */ + CASE_RETURN_STRING(WMI_OFL_SCAN_ADD_AP_PROFILE); + /** remove offload scan AP profile */ + CASE_RETURN_STRING(WMI_OFL_SCAN_REMOVE_AP_PROFILE); + /** set offload scan period */ + CASE_RETURN_STRING(WMI_OFL_SCAN_PERIOD); + + /* P2P specific commands */ + /**set P2P device info. FW will used by FW to create P2P IE to be carried in probe response + * generated during p2p listen and for p2p discoverability */ + CASE_RETURN_STRING(WMI_P2P_DEV_SET_DEVICE_INFO); + /** enable/disable p2p discoverability on STA/AP VDEVs */ + CASE_RETURN_STRING(WMI_P2P_DEV_SET_DISCOVERABILITY); + /** set p2p ie to be carried in beacons generated by FW for GO */ + CASE_RETURN_STRING(WMI_P2P_GO_SET_BEACON_IE); + /** set p2p ie to be carried in probe response frames generated by FW for GO */ + CASE_RETURN_STRING(WMI_P2P_GO_SET_PROBE_RESP_IE); + /** set the vendor specific p2p ie data. FW will use this to parse the P2P NoA + * attribute in the beacons/probe responses received. + */ + CASE_RETURN_STRING(WMI_P2P_SET_VENDOR_IE_DATA_CMDID); + /** set the configure of p2p find offload */ + CASE_RETURN_STRING(WMI_P2P_DISC_OFFLOAD_CONFIG_CMDID); + /** set the vendor specific p2p ie data for p2p find offload using */ + CASE_RETURN_STRING(WMI_P2P_DISC_OFFLOAD_APPIE_CMDID); + /** set the BSSID/device name pattern of p2p find offload */ + CASE_RETURN_STRING(WMI_P2P_DISC_OFFLOAD_PATTERN_CMDID); + /** set OppPS related parameters **/ + CASE_RETURN_STRING(WMI_P2P_SET_OPPPS_PARAM_CMDID); + + /** AP power save specific config */ + /** set AP power save specific param */ + CASE_RETURN_STRING(WMI_AP_PS_PEER_PARAM_CMDID); + /** set AP UAPSD coex pecific param */ + CASE_RETURN_STRING(WMI_AP_PS_PEER_UAPSD_COEX_CMDID); + + + /** Rate-control specific commands */ + CASE_RETURN_STRING(WMI_PEER_RATE_RETRY_SCHED_CMDID); + + /** WLAN Profiling commands. */ + CASE_RETURN_STRING(WMI_WLAN_PROFILE_TRIGGER_CMDID); + CASE_RETURN_STRING(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID); + CASE_RETURN_STRING(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID); + CASE_RETURN_STRING(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID); + CASE_RETURN_STRING(WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID); + + /** Suspend resume command Ids */ + CASE_RETURN_STRING(WMI_PDEV_SUSPEND_CMDID); + CASE_RETURN_STRING(WMI_PDEV_RESUME_CMDID); + + /* Beacon filter commands */ + /** add a beacon filter */ + CASE_RETURN_STRING(WMI_ADD_BCN_FILTER_CMDID); + /** remove a beacon filter */ + CASE_RETURN_STRING(WMI_RMV_BCN_FILTER_CMDID); + + /* WOW Specific WMI commands*/ + /** add pattern for awake */ + CASE_RETURN_STRING(WMI_WOW_ADD_WAKE_PATTERN_CMDID); + /** deleta a wake pattern */ + CASE_RETURN_STRING(WMI_WOW_DEL_WAKE_PATTERN_CMDID); + /** enable/deisable wake event */ + CASE_RETURN_STRING(WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID); + /** enable WOW */ + CASE_RETURN_STRING(WMI_WOW_ENABLE_CMDID); + /** host woke up from sleep event to FW. Generated in response to WOW Hardware event */ + CASE_RETURN_STRING(WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID); + + /* RTT measurement related cmd */ + /** reques to make an RTT measurement */ + CASE_RETURN_STRING(WMI_RTT_MEASREQ_CMDID); + /** reques to report a tsf measurement */ + CASE_RETURN_STRING(WMI_RTT_TSF_CMDID); + + /** spectral scan command */ + /** configure spectral scan */ + CASE_RETURN_STRING(WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID); + /** enable/disable spectral scan and trigger */ + CASE_RETURN_STRING(WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID); + + /* F/W stats */ + /** one time request for stats */ + CASE_RETURN_STRING(WMI_REQUEST_STATS_CMDID); + /** Push MCC Adaptive Scheduler Stats to Firmware */ + CASE_RETURN_STRING(WMI_MCC_SCHED_TRAFFIC_STATS_CMDID); + + /** ARP OFFLOAD REQUEST*/ + CASE_RETURN_STRING(WMI_SET_ARP_NS_OFFLOAD_CMDID); + + /** Proactive ARP Response Add Pattern Command*/ + CASE_RETURN_STRING(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID); + + /** Proactive ARP Response Del Pattern Command*/ + CASE_RETURN_STRING(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID); + + /** NS offload confid*/ + CASE_RETURN_STRING(WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID); + + /* GTK offload Specific WMI commands*/ + CASE_RETURN_STRING(WMI_GTK_OFFLOAD_CMDID); + + /* CSA offload Specific WMI commands*/ + /** csa offload enable */ + CASE_RETURN_STRING(WMI_CSA_OFFLOAD_ENABLE_CMDID); + /** chan switch command */ + CASE_RETURN_STRING(WMI_CSA_OFFLOAD_CHANSWITCH_CMDID); + + /* Chatter commands*/ + /* Change chatter mode of operation */ + CASE_RETURN_STRING(WMI_CHATTER_SET_MODE_CMDID); + /** chatter add coalescing filter command */ + CASE_RETURN_STRING(WMI_CHATTER_ADD_COALESCING_FILTER_CMDID); + /** chatter delete coalescing filter command */ + CASE_RETURN_STRING(WMI_CHATTER_DELETE_COALESCING_FILTER_CMDID); + /** chatter coalecing query command */ + CASE_RETURN_STRING(WMI_CHATTER_COALESCING_QUERY_CMDID); + + /**addba specific commands */ + /** start the aggregation on this TID */ + CASE_RETURN_STRING(WMI_PEER_TID_ADDBA_CMDID); + /** stop the aggregation on this TID */ + CASE_RETURN_STRING(WMI_PEER_TID_DELBA_CMDID); + + /** set station mimo powersave method */ + CASE_RETURN_STRING(WMI_STA_DTIM_PS_METHOD_CMDID); + /** Configure the Station UAPSD AC Auto Trigger Parameters */ + CASE_RETURN_STRING(WMI_STA_UAPSD_AUTO_TRIG_CMDID); + /** Configure the Keep Alive Parameters */ + CASE_RETURN_STRING(WMI_STA_KEEPALIVE_CMDID); + + /* Request ssn from target for a sta/tid pair */ + CASE_RETURN_STRING(WMI_BA_REQ_SSN_CMDID); + /* misc command group */ + /** echo command mainly used for testing */ + CASE_RETURN_STRING(WMI_ECHO_CMDID); + + /* !!IMPORTANT!! + * If you need to add a new WMI command to the CASE_RETURN_STRING(WMI_GRP_MISC sub-group, + * please make sure you add it BEHIND CASE_RETURN_STRING(WMI_PDEV_UTF_CMDID); + * as we MUST have a fixed value here to maintain compatibility between + * UTF and the ART2 driver + */ + /** UTF WMI commands */ + CASE_RETURN_STRING(WMI_PDEV_UTF_CMDID); + + /** set debug log config */ + CASE_RETURN_STRING(WMI_DBGLOG_CFG_CMDID); + /* QVIT specific command id */ + CASE_RETURN_STRING(WMI_PDEV_QVIT_CMDID); + /* Factory Testing Mode request command + * used for integrated chipsets */ + CASE_RETURN_STRING(WMI_PDEV_FTM_INTG_CMDID); + /* set and get keepalive parameters command */ + CASE_RETURN_STRING(WMI_VDEV_SET_KEEPALIVE_CMDID); + CASE_RETURN_STRING(WMI_VDEV_GET_KEEPALIVE_CMDID); + /* For fw recovery test command */ + CASE_RETURN_STRING(WMI_FORCE_FW_HANG_CMDID); + /* Set Mcast/Bdcast filter */ + CASE_RETURN_STRING(WMI_SET_MCASTBCAST_FILTER_CMDID); + /** set thermal management params **/ + CASE_RETURN_STRING(WMI_THERMAL_MGMT_CMDID); + CASE_RETURN_STRING(WMI_RSSI_BREACH_MONITOR_CONFIG_CMDID); + /* GPIO Configuration */ + CASE_RETURN_STRING(WMI_GPIO_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_GPIO_OUTPUT_CMDID); + + /* Txbf configuration command */ + CASE_RETURN_STRING(WMI_TXBF_CMDID); + + /* FWTEST Commands */ + CASE_RETURN_STRING(WMI_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID); + /** set NoA descs **/ + CASE_RETURN_STRING(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID); + + /** TDLS Configuration */ + /** enable/disable TDLS */ + CASE_RETURN_STRING(WMI_TDLS_SET_STATE_CMDID); + /** set tdls peer state */ + CASE_RETURN_STRING(WMI_TDLS_PEER_UPDATE_CMDID); + + /** Resmgr Configuration */ + /** Adaptive OCS is enabled by default in the FW. This command is used to + * disable FW based adaptive OCS. + */ + CASE_RETURN_STRING(WMI_RESMGR_ADAPTIVE_OCS_ENABLE_DISABLE_CMDID); + /** set the requested channel time quota for the home channels */ + CASE_RETURN_STRING(WMI_RESMGR_SET_CHAN_TIME_QUOTA_CMDID); + /** set the requested latency for the home channels */ + CASE_RETURN_STRING(WMI_RESMGR_SET_CHAN_LATENCY_CMDID); + + /** STA SMPS Configuration */ + /** force SMPS mode */ + CASE_RETURN_STRING(WMI_STA_SMPS_FORCE_MODE_CMDID); + /** set SMPS parameters */ + CASE_RETURN_STRING(WMI_STA_SMPS_PARAM_CMDID); + + /* Wlan HB commands*/ + /* enalbe/disable wlan HB */ + CASE_RETURN_STRING(WMI_HB_SET_ENABLE_CMDID); + /* set tcp parameters for wlan HB */ + CASE_RETURN_STRING(WMI_HB_SET_TCP_PARAMS_CMDID); + /* set tcp pkt filter for wlan HB */ + CASE_RETURN_STRING(WMI_HB_SET_TCP_PKT_FILTER_CMDID); + /* set udp parameters for wlan HB */ + CASE_RETURN_STRING(WMI_HB_SET_UDP_PARAMS_CMDID); + /* set udp pkt filter for wlan HB */ + CASE_RETURN_STRING(WMI_HB_SET_UDP_PKT_FILTER_CMDID); + + /** Wlan RMC commands*/ + /** enable/disable RMC */ + CASE_RETURN_STRING(WMI_RMC_SET_MODE_CMDID); + /** configure action frame period */ + CASE_RETURN_STRING(WMI_RMC_SET_ACTION_PERIOD_CMDID); + /** For debug/future enhancement purposes only, + * configures/finetunes RMC algorithms */ + CASE_RETURN_STRING(WMI_RMC_CONFIG_CMDID); + + /** WLAN MHF offload commands */ + /** enable/disable MHF offload */ + CASE_RETURN_STRING(WMI_MHF_OFFLOAD_SET_MODE_CMDID); + /** Plumb routing table for MHF offload */ + CASE_RETURN_STRING(WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID); + + /*location scan commands*/ + /*start batch scan*/ + CASE_RETURN_STRING(WMI_BATCH_SCAN_ENABLE_CMDID); + /*stop batch scan*/ + CASE_RETURN_STRING(WMI_BATCH_SCAN_DISABLE_CMDID); + /*get batch scan result*/ + CASE_RETURN_STRING(WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID); + /* OEM related cmd */ + CASE_RETURN_STRING(WMI_OEM_REQ_CMDID); + /* NAN request cmd */ + CASE_RETURN_STRING(WMI_NAN_CMDID); + /* Modem power state cmd */ + CASE_RETURN_STRING(WMI_MODEM_POWER_STATE_CMDID); + CASE_RETURN_STRING(WMI_REQUEST_STATS_EXT_CMDID); + CASE_RETURN_STRING(WMI_OBSS_SCAN_ENABLE_CMDID); + CASE_RETURN_STRING(WMI_OBSS_SCAN_DISABLE_CMDID); + CASE_RETURN_STRING(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID); + CASE_RETURN_STRING(WMI_ROAM_SCAN_CMD); + CASE_RETURN_STRING(WMI_PDEV_SET_LED_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID); + CASE_RETURN_STRING(WMI_CHAN_AVOID_UPDATE_CMDID); + CASE_RETURN_STRING(WMI_WOW_IOAC_ADD_KEEPALIVE_CMDID); + CASE_RETURN_STRING(WMI_WOW_IOAC_DEL_KEEPALIVE_CMDID); + CASE_RETURN_STRING(WMI_WOW_IOAC_ADD_WAKE_PATTERN_CMDID); + CASE_RETURN_STRING(WMI_WOW_IOAC_DEL_WAKE_PATTERN_CMDID); + CASE_RETURN_STRING(WMI_REQUEST_LINK_STATS_CMDID); + CASE_RETURN_STRING(WMI_START_LINK_STATS_CMDID); + CASE_RETURN_STRING(WMI_CLEAR_LINK_STATS_CMDID); + CASE_RETURN_STRING(WMI_GET_FW_MEM_DUMP_CMDID); + CASE_RETURN_STRING(WMI_LPI_MGMT_SNOOPING_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_LPI_START_SCAN_CMDID); + CASE_RETURN_STRING(WMI_LPI_STOP_SCAN_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_START_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_STOP_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_SET_CAPABILITIES_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_GET_CAPABILITIES_CMDID); + CASE_RETURN_STRING(WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID); + CASE_RETURN_STRING(WMI_ROAM_SYNCH_COMPLETE); + CASE_RETURN_STRING(WMI_D0_WOW_ENABLE_DISABLE_CMDID); + CASE_RETURN_STRING(WMI_EXTWOW_ENABLE_CMDID); + CASE_RETURN_STRING(WMI_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID); + CASE_RETURN_STRING(WMI_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID); + CASE_RETURN_STRING(WMI_UNIT_TEST_CMDID); + CASE_RETURN_STRING(WMI_ROAM_SET_RIC_REQUEST_CMDID); + CASE_RETURN_STRING(WMI_PDEV_GET_TEMPERATURE_CMDID); + CASE_RETURN_STRING(WMI_SET_DHCP_SERVER_OFFLOAD_CMDID); + CASE_RETURN_STRING(WMI_TPC_CHAINMASK_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_IPA_OFFLOAD_ENABLE_DISABLE_CMDID); + CASE_RETURN_STRING(WMI_SCAN_PROB_REQ_OUI_CMDID); + CASE_RETURN_STRING(WMI_TDLS_SET_OFFCHAN_MODE_CMDID); + CASE_RETURN_STRING(WMI_PDEV_SET_LED_FLASHING_CMDID); + CASE_RETURN_STRING(WMI_MDNS_OFFLOAD_ENABLE_CMDID); + CASE_RETURN_STRING(WMI_MDNS_SET_FQDN_CMDID); + CASE_RETURN_STRING(WMI_MDNS_SET_RESPONSE_CMDID); + CASE_RETURN_STRING(WMI_MDNS_GET_STATS_CMDID); + CASE_RETURN_STRING(WMI_ROAM_INVOKE_CMDID); + CASE_RETURN_STRING(WMI_SET_ANTENNA_DIVERSITY_CMDID); + CASE_RETURN_STRING(WMI_SAP_OFL_ENABLE_CMDID); + CASE_RETURN_STRING(WMI_APFIND_CMDID); + CASE_RETURN_STRING(WMI_PASSPOINT_LIST_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_OCB_SET_SCHED_CMDID); + CASE_RETURN_STRING(WMI_OCB_SET_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_OCB_SET_UTC_TIME_CMDID); + CASE_RETURN_STRING(WMI_OCB_START_TIMING_ADVERT_CMDID); + CASE_RETURN_STRING(WMI_OCB_STOP_TIMING_ADVERT_CMDID); + CASE_RETURN_STRING(WMI_OCB_GET_TSF_TIMER_CMDID); + CASE_RETURN_STRING(WMI_DCC_GET_STATS_CMDID); + CASE_RETURN_STRING(WMI_DCC_CLEAR_STATS_CMDID); + CASE_RETURN_STRING(WMI_DCC_UPDATE_NDL_CMDID); + CASE_RETURN_STRING(WMI_ROAM_FILTER_CMDID); + CASE_RETURN_STRING(WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID); + CASE_RETURN_STRING(WMI_DEBUG_MESG_FLUSH_CMDID); + CASE_RETURN_STRING(WMI_PEER_SET_RATE_REPORT_CONDITION_CMDID); + CASE_RETURN_STRING(WMI_SOC_SET_PCL_CMDID); + CASE_RETURN_STRING(WMI_SOC_SET_HW_MODE_CMDID); + } + return "Invalid WMI cmd"; +} + +/* worker thread to recover when Target doesn't respond with credits */ +static void recovery_work_handler(struct work_struct *recovery) +{ + cnss_device_self_recovery(); +} + +static DECLARE_WORK(recovery_work, recovery_work_handler); + +/* WMI command API */ +int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, + WMI_CMD_ID cmd_id) +{ + HTC_PACKET *pkt; + A_STATUS status; + void *vos_context; + struct ol_softc *scn; + + if (adf_os_atomic_read(&wmi_handle->is_target_suspended) && + ( (WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID != cmd_id) && + (WMI_PDEV_RESUME_CMDID != cmd_id)) ){ + pr_err("%s: Target is suspended could not send WMI command\n", __func__); + VOS_ASSERT(0); + return -EBUSY; + } + + /* Do sanity check on the TLV parameter structure */ + { + void *buf_ptr = (void *) adf_nbuf_data(buf); + + if (wmitlv_check_command_tlv_params(NULL, buf_ptr, len, cmd_id) != 0) + { + adf_os_print("\nERROR: %s: Invalid WMI Parameter Buffer for Cmd:%d\n", + __func__, cmd_id); + return -1; + } + } + + if (adf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR)) == NULL) { + pr_err("%s, Failed to send cmd %x, no memory\n", + __func__, cmd_id); + return -ENOMEM; + } + + WMI_SET_FIELD(adf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id); + + adf_os_atomic_inc(&wmi_handle->pending_cmds); + if (adf_os_atomic_read(&wmi_handle->pending_cmds) >= WMI_MAX_CMDS) { + vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); + pr_err("\n%s: hostcredits = %d\n", __func__, + wmi_get_host_credits(wmi_handle)); + HTC_dump_counter_info(wmi_handle->htc_handle); + //dump_CE_register(scn); + //dump_CE_debug_register(scn->hif_sc); + adf_os_atomic_dec(&wmi_handle->pending_cmds); + pr_err("%s: MAX 1024 WMI Pending cmds reached.\n", __func__); + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + schedule_work(&recovery_work); + return -EBUSY; + } + + pkt = adf_os_mem_alloc(NULL, sizeof(*pkt)); + if (!pkt) { + adf_os_atomic_dec(&wmi_handle->pending_cmds); + pr_err("%s, Failed to alloc htc packet %x, no memory\n", + __func__, cmd_id); + return -ENOMEM; + } + + SET_HTC_PACKET_INFO_TX(pkt, + NULL, + adf_nbuf_data(buf), + len + sizeof(WMI_CMD_HDR), + /* htt_host_data_dl_len(buf)+20 */ + wmi_handle->wmi_endpoint_id, + 0/*htc_tag*/); + + SET_HTC_PACKET_NET_BUF_CONTEXT(pkt, buf); + + WMA_LOGD("Send WMI command:%s command_id:%d", + get_wmi_cmd_string(cmd_id), cmd_id); + +#ifdef WMI_INTERFACE_EVENT_LOGGING + adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); + /*Record 16 bytes of WMI cmd data - exclude TLV and WMI headers*/ + WMI_COMMAND_RECORD(cmd_id ,((u_int32_t *)adf_nbuf_data(buf) + 2)); + adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); +#endif + + status = HTCSendPkt(wmi_handle->htc_handle, pkt); + + if (A_OK != status) { + adf_os_atomic_dec(&wmi_handle->pending_cmds); + pr_err("%s %d, HTCSendPkt failed\n", __func__, __LINE__); + } + + + return ((status == A_OK) ? EOK : -1); +} + + +/* WMI Event handler register API */ +int wmi_unified_get_event_handler_ix(wmi_unified_t wmi_handle, + WMI_EVT_ID event_id) +{ + u_int32_t idx = 0; + for (idx = 0; (idx < wmi_handle->max_event_idx && + idx < WMI_UNIFIED_MAX_EVENT); ++idx) { + if (wmi_handle->event_id[idx] == event_id && + wmi_handle->event_handler[idx] != NULL ) { + return idx; + } + } + return -1; +} + +int wmi_unified_register_event_handler(wmi_unified_t wmi_handle, + WMI_EVT_ID event_id, + wmi_unified_event_handler handler_func) +{ + u_int32_t idx=0; + + if ( wmi_unified_get_event_handler_ix( wmi_handle, event_id) != -1) { + printk("%s : event handler already registered 0x%x \n", + __func__, event_id); + return -1; + } + if ( wmi_handle->max_event_idx == WMI_UNIFIED_MAX_EVENT ) { + printk("%s : no more event handlers 0x%x \n", + __func__, event_id); + return -1; + } + idx=wmi_handle->max_event_idx; + wmi_handle->event_handler[idx] = handler_func; + wmi_handle->event_id[idx] = event_id; + wmi_handle->max_event_idx++; + + return 0; +} + +int wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle, + WMI_EVT_ID event_id) +{ + u_int32_t idx=0; + if ( (idx = wmi_unified_get_event_handler_ix( wmi_handle, event_id)) == -1) { + printk("%s : event handler is not registered: event id 0x%x \n", + __func__, event_id); + return -1; + } + wmi_handle->event_handler[idx] = NULL; + wmi_handle->event_id[idx] = 0; + --wmi_handle->max_event_idx; + wmi_handle->event_handler[idx] = wmi_handle->event_handler[wmi_handle->max_event_idx]; + wmi_handle->event_id[idx] = wmi_handle->event_id[wmi_handle->max_event_idx] ; + return 0; +} + +#if 0 /* currently not used */ +static int wmi_unified_event_rx(struct wmi_unified *wmi_handle, + wmi_buf_t evt_buf) +{ + u_int32_t id; + u_int8_t *event; + u_int16_t len; + int status = -1; + u_int32_t idx = 0; + + ASSERT(evt_buf != NULL); + + id = WMI_GET_FIELD(adf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID); + + if (adf_nbuf_pull_head(evt_buf, sizeof(WMI_CMD_HDR)) == NULL) + goto end; + + idx = wmi_unified_get_event_handler_ix(wmi_handle, id); + if (idx == -1) { + pr_err("%s : event handler is not registered: event id: 0x%x\n", + __func__, id); + goto end; + } + + event = adf_nbuf_data(evt_buf); + len = adf_nbuf_len(evt_buf); + + /* Call the WMI registered event handler */ + status = wmi_handle->event_handler[idx](wmi_handle->scn_handle, + event, len); + +end: + adf_nbuf_free(evt_buf); + return status; +} +#endif /* 0 */ + +/* + * Temporarily added to support older WMI events. We should move all events to unified + * when the target is ready to support it. + */ +void wmi_control_rx(void *ctx, HTC_PACKET *htc_packet) +{ + struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; + wmi_buf_t evt_buf; + +#ifndef QCA_CONFIG_SMP + /* MDM is single core apps processor + * As a result, PAUSE event cannot be processed fast enough + * if RX process reserve CPU + * To ensure PAUSE event processed fast enough + * only PAUSE event should not be scheduled on worker thread */ + u_int32_t len; + void *wmi_cmd_struct_ptr = NULL; + u_int32_t idx = 0; + int tlv_ok_status = 0; +#endif /* QCA_CONFIG_SMP */ + +#if defined(WMI_INTERFACE_EVENT_LOGGING) || !defined(QCA_CONFIG_SMP) + u_int32_t id; + u_int8_t *data; +#endif + + evt_buf = (wmi_buf_t) htc_packet->pPktContext; +#ifndef QCA_CONFIG_SMP + id = WMI_GET_FIELD(adf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID); + /* TX_PAUSE EVENT should be handled with tasklet context */ + if (WMI_TX_PAUSE_EVENTID == id) { + if (adf_nbuf_pull_head(evt_buf, sizeof(WMI_CMD_HDR)) == NULL) + return; + + data = adf_nbuf_data(evt_buf); + len = adf_nbuf_len(evt_buf); + tlv_ok_status = wmitlv_check_and_pad_event_tlvs( + wmi_handle->scn_handle, + data, len, id, + &wmi_cmd_struct_ptr); + if (tlv_ok_status != 0) { + if (tlv_ok_status == 1) { + wmi_cmd_struct_ptr = data; + } else { + return; + } + } + + idx = wmi_unified_get_event_handler_ix(wmi_handle, id); + if (idx == -1) { + wmitlv_free_allocated_event_tlvs(id, + &wmi_cmd_struct_ptr); + adf_nbuf_free(evt_buf); + return; + } + wmi_handle->event_handler[idx](wmi_handle->scn_handle, + wmi_cmd_struct_ptr, len); + wmitlv_free_allocated_event_tlvs(id, &wmi_cmd_struct_ptr); + adf_nbuf_free(evt_buf); + return; + } +#endif /* QCA_CONFIG_SMP */ + +#ifdef WMI_INTERFACE_EVENT_LOGGING + id = WMI_GET_FIELD(adf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID); + data = adf_nbuf_data(evt_buf); + + adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); + /* Exclude 4 bytes of TLV header */ + WMI_RX_EVENT_RECORD(id, ((u_int8_t *)data + 4)); + adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); +#endif + adf_os_spin_lock_bh(&wmi_handle->eventq_lock); + adf_nbuf_queue_add(&wmi_handle->event_queue, evt_buf); + adf_os_spin_unlock_bh(&wmi_handle->eventq_lock); + schedule_work(&wmi_handle->rx_event_work); +} + +void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf) +{ + u_int32_t id; + u_int8_t *data; + u_int32_t len; + void *wmi_cmd_struct_ptr = NULL; + int tlv_ok_status = 0; + + id = WMI_GET_FIELD(adf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID); + + if (adf_nbuf_pull_head(evt_buf, sizeof(WMI_CMD_HDR)) == NULL) + goto end; + + data = adf_nbuf_data(evt_buf); + len = adf_nbuf_len(evt_buf); + + /* Validate and pad(if necessary) the TLVs */ + tlv_ok_status = wmitlv_check_and_pad_event_tlvs(wmi_handle->scn_handle, + data, len, id, + &wmi_cmd_struct_ptr); + if (tlv_ok_status != 0) { + pr_err("%s: Error: id=0x%d, wmitlv_check_and_pad_tlvs ret=%d\n", + __func__, id, tlv_ok_status); + goto end; + } + +#ifdef FEATURE_WLAN_D0WOW + if (wmi_handle->in_d0wow) + pr_debug("%s: WMI event ID is 0x%x\n", __func__, id); +#endif + + if (id >= WMI_EVT_GRP_START_ID(WMI_GRP_START)) { + u_int32_t idx = 0; + + idx = wmi_unified_get_event_handler_ix(wmi_handle, id) ; + if (idx == -1) { + pr_err("%s : event handler is not registered: event id 0x%x\n", + __func__, id); + goto end; + } + +#ifdef WMI_INTERFACE_EVENT_LOGGING + adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); + /* Exclude 4 bytes of TLV header */ + WMI_EVENT_RECORD(id, ((u_int8_t *)data + 4)); + adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); +#endif + /* Call the WMI registered event handler */ + wmi_handle->event_handler[idx](wmi_handle->scn_handle, + wmi_cmd_struct_ptr, len); + goto end; + } + + switch (id) { + default: + pr_info("%s: Unhandled WMI event %d\n", __func__, id); + break; + case WMI_SERVICE_READY_EVENTID: + pr_info("%s: WMI UNIFIED SERVICE READY event\n", __func__); + wma_rx_service_ready_event(wmi_handle->scn_handle, + wmi_cmd_struct_ptr); + break; + case WMI_READY_EVENTID: + pr_info("%s: WMI UNIFIED READY event\n", __func__); + wma_rx_ready_event(wmi_handle->scn_handle, wmi_cmd_struct_ptr); + break; + } +end: + wmitlv_free_allocated_event_tlvs(id, &wmi_cmd_struct_ptr); + adf_nbuf_free(evt_buf); +} + +void __wmi_rx_event_work(struct work_struct *work) +{ + struct wmi_unified *wmi = container_of(work, struct wmi_unified, + rx_event_work); + wmi_buf_t buf; + + adf_os_spin_lock_bh(&wmi->eventq_lock); + buf = adf_nbuf_queue_remove(&wmi->event_queue); + adf_os_spin_unlock_bh(&wmi->eventq_lock); + while (buf) { + __wmi_control_rx(wmi, buf); + adf_os_spin_lock_bh(&wmi->eventq_lock); + buf = adf_nbuf_queue_remove(&wmi->event_queue); + adf_os_spin_unlock_bh(&wmi->eventq_lock); + } +} + +void wmi_rx_event_work(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __wmi_rx_event_work(work); + vos_ssr_unprotect(__func__); +} + +/* WMI Initialization functions */ + +void * +wmi_unified_attach(ol_scn_t scn_handle, wma_wow_tx_complete_cbk func) +{ + struct wmi_unified *wmi_handle; + wmi_handle = (struct wmi_unified *)OS_MALLOC(NULL, sizeof(struct wmi_unified), GFP_ATOMIC); + if (wmi_handle == NULL) { + printk("allocation of wmi handle failed %zu \n", sizeof(struct wmi_unified)); + return NULL; + } + OS_MEMZERO(wmi_handle, sizeof(struct wmi_unified)); + wmi_handle->scn_handle = scn_handle; + adf_os_atomic_init(&wmi_handle->pending_cmds); + adf_os_atomic_init(&wmi_handle->is_target_suspended); + adf_os_spinlock_init(&wmi_handle->eventq_lock); + adf_nbuf_queue_init(&wmi_handle->event_queue); +#ifdef CONFIG_CNSS + cnss_init_work(&wmi_handle->rx_event_work, wmi_rx_event_work); +#else + INIT_WORK(&wmi_handle->rx_event_work, wmi_rx_event_work); +#endif +#ifdef WMI_INTERFACE_EVENT_LOGGING + adf_os_spinlock_init(&wmi_handle->wmi_record_lock); +#endif + wmi_handle->wma_wow_tx_complete_cbk = func; + return wmi_handle; +} + +void +wmi_unified_detach(struct wmi_unified* wmi_handle) +{ + wmi_buf_t buf; + + vos_flush_work(&wmi_handle->rx_event_work); + adf_os_spin_lock_bh(&wmi_handle->eventq_lock); + buf = adf_nbuf_queue_remove(&wmi_handle->event_queue); + while (buf) { + adf_nbuf_free(buf); + buf = adf_nbuf_queue_remove(&wmi_handle->event_queue); + } + adf_os_spin_unlock_bh(&wmi_handle->eventq_lock); + if (wmi_handle != NULL) { + OS_FREE(wmi_handle); + wmi_handle = NULL; + } +} + +void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt) +{ + struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; + wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); +#ifdef WMI_INTERFACE_EVENT_LOGGING + u_int32_t cmd_id; +#endif + + ASSERT(wmi_cmd_buf); +#ifdef WMI_INTERFACE_EVENT_LOGGING + cmd_id = WMI_GET_FIELD(adf_nbuf_data(wmi_cmd_buf), + WMI_CMD_HDR, COMMANDID); + adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); + /* Record 16 bytes of WMI cmd tx complete data + - exclude TLV and WMI headers */ + WMI_COMMAND_TX_CMP_RECORD(cmd_id, + ((u_int32_t *)adf_nbuf_data(wmi_cmd_buf) + 2)); + adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); +#endif + adf_nbuf_free(wmi_cmd_buf); + adf_os_mem_free(htc_pkt); + adf_os_atomic_dec(&wmi_handle->pending_cmds); +} + +int +wmi_unified_connect_htc_service(struct wmi_unified * wmi_handle, void *htc_handle) +{ + + int status; + HTC_SERVICE_CONNECT_RESP response; + HTC_SERVICE_CONNECT_REQ connect; + + OS_MEMZERO(&connect, sizeof(connect)); + OS_MEMZERO(&response, sizeof(response)); + + /* meta data is unused for now */ + connect.pMetaData = NULL; + connect.MetaDataLength = 0; + /* these fields are the same for all service endpoints */ + connect.EpCallbacks.pContext = wmi_handle; + connect.EpCallbacks.EpTxCompleteMultiple = NULL /* Control path completion ar6000_tx_complete */; + connect.EpCallbacks.EpRecv = wmi_control_rx /* Control path rx */; + connect.EpCallbacks.EpRecvRefill = NULL /* ar6000_rx_refill */; + connect.EpCallbacks.EpSendFull = NULL /* ar6000_tx_queue_full */; + connect.EpCallbacks.EpTxComplete = wmi_htc_tx_complete /* ar6000_tx_queue_full */; + + /* connect to control service */ + connect.ServiceID = WMI_CONTROL_SVC; + + if ((status = HTCConnectService(htc_handle, &connect, &response)) != EOK) + { + printk(" Failed to connect to WMI CONTROL service status:%d \n", status); + return -1;; + } + wmi_handle->wmi_endpoint_id = response.Endpoint; + wmi_handle->htc_handle = htc_handle; + wmi_handle->max_msg_len = response.MaxMsgLength; + + return EOK; +} + +int wmi_get_host_credits(wmi_unified_t wmi_handle) +{ + int host_credits; + + HTCGetControlEndpointTxHostCredits(wmi_handle->htc_handle, + &host_credits); + return host_credits; +} + +int wmi_get_pending_cmds(wmi_unified_t wmi_handle) +{ + return adf_os_atomic_read(&wmi_handle->pending_cmds); +} + +void wmi_set_target_suspend(wmi_unified_t wmi_handle, A_BOOL val) +{ + adf_os_atomic_set(&wmi_handle->is_target_suspended, val); +} + +#ifdef FEATURE_WLAN_D0WOW +void wmi_set_d0wow_flag(wmi_unified_t wmi_handle, A_BOOL flag) +{ + wmi_handle->in_d0wow = flag; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified_priv.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified_priv.h new file mode 100644 index 0000000000000..633bf8320abe0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified_priv.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file contains the API definitions for the Unified Wireless Module Interface (WMI). + */ +#ifndef _WMI_UNIFIED_PRIV_H_ +#define _WMI_UNIFIED_PRIV_H_ +#include +#include "a_types.h" +#include "wmi.h" +#include "wmi_unified.h" +#include "adf_os_atomic.h" + +#define WMI_UNIFIED_MAX_EVENT 0x100 +#define WMI_MAX_CMDS 1024 + +typedef adf_nbuf_t wmi_buf_t; + +#ifdef WMI_INTERFACE_EVENT_LOGGING + +#define WMI_EVENT_DEBUG_MAX_ENTRY (1024) + +struct wmi_command_debug{ + u_int32_t command; + u_int32_t data[4]; /*16 bytes of WMI cmd excluding TLV and WMI headers*/ + u_int64_t time; +}; + +struct wmi_event_debug{ + u_int32_t event; + u_int32_t data[4]; /*16 bytes of WMI event data excluding TLV header*/ + u_int64_t time; +}; + +#endif /*WMI_INTERFACE_EVENT_LOGGING*/ + + +#ifdef WLAN_OPEN_SOURCE +struct fwdebug { + struct sk_buff_head fwlog_queue; + struct completion fwlog_completion; + A_BOOL fwlog_open; +}; +#endif /* WLAN_OPEN_SOURCE */ + +struct wmi_unified { + ol_scn_t scn_handle; /* handle to device */ + adf_os_atomic_t pending_cmds; + HTC_ENDPOINT_ID wmi_endpoint_id; + uint16_t max_msg_len; + WMI_EVT_ID event_id[WMI_UNIFIED_MAX_EVENT]; + wmi_unified_event_handler event_handler[WMI_UNIFIED_MAX_EVENT]; + u_int32_t max_event_idx; + void *htc_handle; + adf_os_spinlock_t eventq_lock; + adf_nbuf_queue_t event_queue; + struct work_struct rx_event_work; +#ifdef WLAN_OPEN_SOURCE + struct fwdebug dbglog; + struct dentry *debugfs_phy; +#endif /* WLAN_OPEN_SOURCE */ + +#ifdef WMI_INTERFACE_EVENT_LOGGING + adf_os_spinlock_t wmi_record_lock; +#endif /*WMI_INTERFACE_EVENT_LOGGING*/ + + adf_os_atomic_t is_target_suspended; + void (*wma_wow_tx_complete_cbk)(ol_scn_t scn_handle); +#ifdef FEATURE_WLAN_D0WOW + A_BOOL in_d0wow; +#endif +}; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/btcApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/btcApi.h new file mode 100644 index 0000000000000..65f26b702156e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/btcApi.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: btcApi.h +* +* Description: BTC Events Layer API definitions. +* + +* +******************************************************************************/ + +#ifndef __BTC_API_H__ +#define __BTC_API_H__ + +#include "vos_types.h" +#include "vos_timer.h" +#include "vos_nvitem.h" + +#define BT_INVALID_CONN_HANDLE (0xFFFF) /**< Invalid connection handle */ + +/* ACL and Sync connection attempt results */ +#define BT_CONN_STATUS_FAIL (0) /**< Connection failed */ +#define BT_CONN_STATUS_SUCCESS (1) /**< Connection successful */ +#define BT_CONN_STATUS_MAX (2) /**< This and beyond are invalid values */ + +/** ACL and Sync link types + These must match the Bluetooth Spec! +*/ +#define BT_SCO (0) /**< SCO Link */ +#define BT_ACL (1) /**< ACL Link */ +#define BT_eSCO (2) /**< eSCO Link */ +#define BT_LINK_TYPE_MAX (3) /**< This value and higher are invalid */ + +/** ACL link modes + These must match the Bluetooth Spec! +*/ +#define BT_ACL_ACTIVE (0) /**< Active mode */ +#define BT_ACL_HOLD (1) /**< Hold mode */ +#define BT_ACL_SNIFF (2) /**< Sniff mode */ +#define BT_ACL_PARK (3) /**< Park mode */ +#define BT_ACL_MODE_MAX (4) /**< This value and higher are invalid */ + +/** + * A2DP BTC max no of BT sub intervals + * + * **/ +#define BTC_MAX_NUM_ACL_BT_SUB_INTS (7) + +/** BTC Executions Modes allowed to be set by user +*/ +#define BTC_SMART_COEXISTENCE (0) /** BTC Mapping Layer decides whats best */ +#define BTC_WLAN_ONLY (1) /** WLAN takes all mode */ +#define BTC_PTA_ONLY (2) /** Allow only 3 wire protocol in H/W */ +#define BTC_SMART_MAX_WLAN (3) /** BTC Mapping Layer decides whats best, WLAN weighted */ +#define BTC_SMART_MAX_BT (4) /** BTC Mapping Layer decides whats best, BT weighted */ +#define BTC_SMART_BT_A2DP (5) /** BTC Mapping Layer decides whats best, balanced + BT A2DP weight */ +#define BT_EXEC_MODE_MAX (6) /** This and beyond are invalid values */ + +/** Enumeration of different kinds actions that BTC Mapping Layer + can do if PM indication (to AP) fails. +*/ +#define BTC_RESTART_CURRENT (0) /** Restart the interval we just failed to leave */ +#define BTC_START_NEXT (1) /** Start the next interval even though the PM transition at the AP was unsuccessful */ +#define BTC_ACTION_TYPE_MAX (2) /** This and beyond are invalid values */ + +#define BTC_BT_INTERVAL_MODE1_DEFAULT (120) /** BT Interval in Mode 1 */ +#define BTC_WLAN_INTERVAL_MODE1_DEFAULT (30) /** WLAN Interval in Mode 1 */ + +/** Bitmaps used for maintaining various BT events that requires + enough time to complete such that it might require disbling of + heartbeat monitoring to avoid WLAN link loss with the AP +*/ +#define BT_INQUIRY_STARTED (1<<0) +#define BT_PAGE_STARTED (1<<1) +#define BT_CREATE_ACL_CONNECTION_STARTED (1<<2) +#define BT_CREATE_SYNC_CONNECTION_STARTED (1<<3) + +/** Maximum time duration in milliseconds between a specific BT start event and its + respective stop event, before it can be declared timed out on receiving the stop event. +*/ +#define BT_MAX_EVENT_DONE_TIMEOUT 45000 + + +/* + To suppurt multiple SCO connections for BT+UAPSD work +*/ +#define BT_MAX_SCO_SUPPORT 3 +#define BT_MAX_ACL_SUPPORT 3 +#define BT_MAX_DISCONN_SUPPORT (BT_MAX_SCO_SUPPORT+BT_MAX_ACL_SUPPORT) +#define BT_MAX_NUM_EVENT_ACL_DEFERRED 4 //We may need to defer these many BT events for ACL +#define BT_MAX_NUM_EVENT_SCO_DEFERRED 4 //We may need to defer these many BT events for SYNC + +/** Default values for the BTC tunables parameters +*/ +#define BTC_STATIC_BT_LEN_INQ_DEF (120000) // 120 msec +#define BTC_STATIC_BT_LEN_PAGE_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_BT_LEN_CONN_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_BT_LEN_LE_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_WLAN_LEN_INQ_DEF (30000) // 30 msec +#define BTC_STATIC_WLAN_LEN_PAGE_DEF (0) // 0 msec (BT takes all) +#define BTC_STATIC_WLAN_LEN_CONN_DEF (0) // 0 msec (BT takes all) +#define BTC_STATIC_WLAN_LEN_LE_DEF (0) // 0 msec (BT takes all) +#define BTC_DYNAMIC_BT_LEN_MAX_DEF (250000) // 250 msec +#define BTC_DYNAMIC_WLAN_LEN_MAX_DEF (45000) // 45 msec +#define BTC_SCO_BLOCK_PERC_DEF (1) // 1 percent +#define BTC_DHCP_ON_A2DP_DEF (1) // ON +#define BTC_DHCP_ON_SCO_DEF (0) // OFF + +/* + * Number of victim tables and mws coex configurations + */ +#define MWS_COEX_MAX_VICTIM_TABLE 10 +#define MWS_COEX_MAX_CONFIG 6 + +/** Enumeration of all the different kinds of BT events +*/ +typedef enum eSmeBtEventType +{ + BT_EVENT_DEVICE_SWITCHED_ON, + BT_EVENT_DEVICE_SWITCHED_OFF, + BT_EVENT_INQUIRY_STARTED, + BT_EVENT_INQUIRY_STOPPED, + BT_EVENT_INQUIRY_SCAN_STARTED, + BT_EVENT_INQUIRY_SCAN_STOPPED, + BT_EVENT_PAGE_STARTED, + BT_EVENT_PAGE_STOPPED, + BT_EVENT_PAGE_SCAN_STARTED, + BT_EVENT_PAGE_SCAN_STOPPED, + BT_EVENT_CREATE_ACL_CONNECTION, + BT_EVENT_ACL_CONNECTION_COMPLETE, + BT_EVENT_CREATE_SYNC_CONNECTION, + BT_EVENT_SYNC_CONNECTION_COMPLETE, + BT_EVENT_SYNC_CONNECTION_UPDATED, + BT_EVENT_DISCONNECTION_COMPLETE, + BT_EVENT_MODE_CHANGED, + BT_EVENT_A2DP_STREAM_START, + BT_EVENT_A2DP_STREAM_STOP, + BT_EVENT_TYPE_MAX, //This and beyond are invalid values +} tSmeBtEventType; + +/** BT-AMP events type +*/ +typedef enum eSmeBtAmpEventType +{ + BTAMP_EVENT_CONNECTION_START, + BTAMP_EVENT_CONNECTION_STOP, + BTAMP_EVENT_CONNECTION_TERMINATED, + BTAMP_EVENT_TYPE_MAX, //This and beyond are invalid values +} tSmeBtAmpEventType; + + +/**Data structure that specifies the needed event parameters for + BT_EVENT_CREATE_ACL_CONNECTION and BT_EVENT_ACL_CONNECTION_COMPLETE +*/ +typedef struct sSmeBtAclConnectionParam +{ + v_U8_t bdAddr[6]; + v_U16_t connectionHandle; + v_U8_t status; +} tSmeBtAclConnectionParam, *tpSmeBtAclConnectionParam; + +/** Data structure that specifies the needed event parameters for + BT_EVENT_CREATE_SYNC_CONNECTION, BT_EVENT_SYNC_CONNECTION_COMPLETE + and BT_EVENT_SYNC_CONNECTION_UPDATED +*/ +typedef struct sSmeBtSyncConnectionParam +{ + v_U8_t bdAddr[6]; + v_U16_t connectionHandle; + v_U8_t status; + v_U8_t linkType; + v_U8_t scoInterval; //units in number of 625us slots + v_U8_t scoWindow; //units in number of 625us slots + v_U8_t retransmisisonWindow; //units in number of 625us slots +} tSmeBtSyncConnectionParam, *tpSmeBtSyncConnectionParam; + +typedef struct sSmeBtSyncUpdateHist +{ + tSmeBtSyncConnectionParam btSyncConnection; + v_BOOL_t fValid; +} tSmeBtSyncUpdateHist, *tpSmeBtSyncUpdateHist; + +/**Data structure that specifies the needed event parameters for + BT_EVENT_MODE_CHANGED +*/ +typedef struct sSmeBtAclModeChangeParam +{ + v_U16_t connectionHandle; + v_U8_t mode; +} tSmeBtAclModeChangeParam, *tpSmeBtAclModeChangeParam; + +/*Data structure that specifies the needed event parameters for + BT_EVENT_DISCONNECTION_COMPLETE +*/ +typedef struct sSmeBtDisconnectParam +{ + v_U16_t connectionHandle; +} tSmeBtDisconnectParam, *tpSmeBtDisconnectParam; + +/*Data structure that specifies the needed event parameters for + BT_EVENT_A2DP_STREAM_START + BT_EVENT_A2DP_STREAM_STOP +*/ +typedef struct sSmeBtA2DPParam +{ + v_U8_t bdAddr[6]; +} tSmeBtA2DPParam, *tpSmeBtA2DPParam; + + +/** Generic Bluetooth Event structure for BTC +*/ +typedef struct sSmeBtcBtEvent +{ + tSmeBtEventType btEventType; + union + { + v_U8_t bdAddr[6]; /**< For events with only a BT Addr in event_data */ + tSmeBtAclConnectionParam btAclConnection; + tSmeBtSyncConnectionParam btSyncConnection; + tSmeBtDisconnectParam btDisconnect; + tSmeBtAclModeChangeParam btAclModeChange; + }uEventParam; +} tSmeBtEvent, *tpSmeBtEvent; + + +/** + BT-AMP Event Structure +*/ +typedef struct sSmeBtAmpEvent +{ + tSmeBtAmpEventType btAmpEventType; + +} tSmeBtAmpEvent, *tpSmeBtAmpEvent; + + +/** Data structure that specifies the BTC Configuration parameters +*/ +typedef struct sSmeBtcConfig +{ + v_U8_t btcExecutionMode; + v_U8_t btcConsBtSlotsToBlockDuringDhcp; + v_U8_t btcA2DPBtSubIntervalsDuringDhcp; + v_U8_t btcActionOnPmFail; + v_U8_t btcBtIntervalMode1; + v_U8_t btcWlanIntervalMode1; + + v_U32_t btcStaticLenInqBt; + v_U32_t btcStaticLenPageBt; + v_U32_t btcStaticLenConnBt; + v_U32_t btcStaticLenLeBt; + v_U32_t btcStaticLenInqWlan; + v_U32_t btcStaticLenPageWlan; + v_U32_t btcStaticLenConnWlan; + v_U32_t btcStaticLenLeWlan; + v_U32_t btcDynMaxLenBt; + v_U32_t btcDynMaxLenWlan; + v_U32_t btcMaxScoBlockPerc; + v_U32_t btcDhcpProtOnA2dp; + v_U32_t btcDhcpProtOnSco; + + v_U32_t mwsCoexVictimWANFreq[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimWLANFreq[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimConfig[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimConfig2[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexModemBackoff; + v_U32_t mwsCoexConfig[MWS_COEX_MAX_CONFIG]; + v_U32_t SARPowerBackoff; +} tSmeBtcConfig, *tpSmeBtcConfig; + + +typedef struct sSmeBtAclModeChangeEventHist +{ + tSmeBtAclModeChangeParam btAclModeChange; + v_BOOL_t fValid; +} tSmeBtAclModeChangeEventHist, *tpSmeBtAclModeChangeEventHist; + +typedef struct sSmeBtAclEventHist +{ + //At most, cached events are COMPLETION, DISCONNECT, CREATION, COMPLETION + tSmeBtEventType btEventType[BT_MAX_NUM_EVENT_ACL_DEFERRED]; + tSmeBtAclConnectionParam btAclConnection[BT_MAX_NUM_EVENT_ACL_DEFERRED]; + //bNextEventIdx == 0 meaning no event cached here + tANI_U8 bNextEventIdx; +} tSmeBtAclEventHist, *tpSmeBtAclEventHist; + +typedef struct sSmeBtSyncEventHist +{ + //At most, cached events are COMPLETION, DISCONNECT, CREATION, COMPLETION + tSmeBtEventType btEventType[BT_MAX_NUM_EVENT_SCO_DEFERRED]; + tSmeBtSyncConnectionParam btSyncConnection[BT_MAX_NUM_EVENT_SCO_DEFERRED]; + //bNextEventIdx == 0 meaning no event cached here + tANI_U8 bNextEventIdx; +} tSmeBtSyncEventHist, *tpSmeBtSyncEventHist; + +typedef struct sSmeBtDisconnectEventHist +{ + tSmeBtDisconnectParam btDisconnect; + v_BOOL_t fValid; +} tSmeBtDisconnectEventHist, *tpSmeBtDisconnectEventHist; + + +/* + Data structure for the history of BT events +*/ +typedef struct sSmeBtcEventHist +{ + tSmeBtSyncEventHist btSyncConnectionEvent[BT_MAX_SCO_SUPPORT]; + tSmeBtAclEventHist btAclConnectionEvent[BT_MAX_ACL_SUPPORT]; + tSmeBtAclModeChangeEventHist btAclModeChangeEvent[BT_MAX_ACL_SUPPORT]; + tSmeBtDisconnectEventHist btDisconnectEvent[BT_MAX_DISCONN_SUPPORT]; + tSmeBtSyncUpdateHist btSyncUpdateEvent[BT_MAX_SCO_SUPPORT]; + int nInquiryEvent; //>0 for # of outstanding inquiriy starts + //<0 for # of outstanding inquiry stops + //0 == no inquiry event + int nPageEvent; //>0 for # of outstanding page starts + //<0 for # of outstanding page stops + //0 == no page event + v_BOOL_t fA2DPStarted; + v_BOOL_t fA2DPStopped; +} tSmeBtcEventHist, *tpSmeBtcEventHist; + +typedef struct sSmeBtcEventReplay +{ + tSmeBtcEventHist btcEventHist; + v_BOOL_t fBTSwitchOn; + v_BOOL_t fBTSwitchOff; + //This is not directly tied to BT event so leave it alone when processing BT events + v_BOOL_t fRestoreHBMonitor; +} tSmeBtcEventReplay, *tpSmeBtcEventReplay; + +typedef struct sSmeBtcInfo +{ + tSmeBtcConfig btcConfig; + v_BOOL_t btcReady; + v_U8_t btcEventState; + v_U8_t btcHBActive; /* Is HB currently active */ + v_U8_t btcHBCount; /* default HB count */ + vos_timer_t restoreHBTimer; /* Timer to restore heart beat */ + tSmeBtcEventReplay btcEventReplay; + v_BOOL_t fReplayBTEvents; + v_BOOL_t btcUapsdOk; /* Indicate whether BTC is ok with UAPSD */ + v_BOOL_t fA2DPTrafStop;/*flag to check A2DP_STOP event has come before MODE_CHANGED*/ + v_U16_t btcScoHandles[BT_MAX_SCO_SUPPORT]; /* Handles for SCO, if any*/ + v_BOOL_t fA2DPUp; /*remember whether A2DP is in session*/ + v_BOOL_t btcScanCompromise; + v_U8_t btcBssfordisableaggr[VOS_MAC_ADDRESS_LEN]; +} tSmeBtcInfo, *tpSmeBtcInfo; + + +/** Routine definitions +*/ + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +VOS_STATUS btcOpen (tHalHandle hHal); +VOS_STATUS btcClose (tHalHandle hHal); +VOS_STATUS btcReady (tHalHandle hHal); +VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent); +VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +/* + Caller can check whether BTC's current event allows UAPSD. This doesn't affect + BMPS. + return: VOS_TRUE -- BTC is ready for UAPSD + VOS_FALSE -- certain BT event is active, cannot enter UAPSD +*/ +v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal ); +eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg); +#endif /* End of WLAN_MDM_CODE_REDUCTION_OPT */ + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/ccmApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/ccmApi.h new file mode 100644 index 0000000000000..ddffaf0de0838 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/ccmApi.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file ccmApi.h + + \brief Exports and types for the Common Config Module (CCM) + + $Id$This file contains all the interfaces for thge Platform Abstration Layer + functions. It is intended to be included in all modules that are using + the PAL interfaces. + + ========================================================================== */ +#ifndef CCMAPI_H__ +#define CCMAPI_H__ + +#include "wniCfgSta.h" +#include "halTypes.h" + +#define CCM_IS_RESULT_SUCCESS(result) (WNI_CFG_SUCCESS == (result) ||\ + WNI_CFG_NEED_RESTART == (result) || \ + WNI_CFG_NEED_RELOAD == (result)) + +#define CCM_INTEGER_TYPE 0 +#define CCM_STRING_TYPE 1 + +typedef void (*tCcmCfgSetCallback)(tHalHandle hHal, tANI_S32 result) ; + +typedef enum { + eCCM_STOPPED, + eCCM_STARTED, + eCCM_REQ_SENT, + eCCM_REQ_QUEUED, + eCCM_REQ_DONE, +} eCcmState ; + +/* We do not use Linux's list facility */ +typedef struct cfgreq { + struct cfgreq *next ; + tANI_U16 cfgId ; + tANI_U8 type ; + tANI_U8 state : 7 ; + tANI_U8 toBeSaved : 1 ; + tANI_S32 length ; + void *ccmPtr; + tANI_U32 ccmValue; + tCcmCfgSetCallback callback; + void *done ; +} tCfgReq ; + +typedef struct { + tANI_U16 started : 1 ; + tANI_U16 in_progress : 1 ; + tANI_U16 reserved : 14 ; + tANI_S16 nr_param ; + tANI_U32 result ; + tCcmCfgSetCallback callback ; + void *done ; +} tCfgReplay ; + +struct ccmlink { + tCfgReq *head; + tCfgReq *tail; +} ; + +typedef struct { + struct ccmlink reqQ ; + eCcmState state ; + tCfgReq * comp[CFG_PARAM_MAX_NUM] ; + tCfgReplay replay ; + void *lock; +} tCcm ; + +void ccmCfgCnfMsgHandler(tHalHandle hHal, void *msg) ; +eHalStatus ccmOpen(tHalHandle hHal) ; +eHalStatus ccmClose(tHalHandle hHal) ; +void ccmStart(tHalHandle hHal) ; +void ccmStop(tHalHandle hHal) ; +//If callback is NULL, the API is not serialized for the CFGs +eHalStatus ccmCfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; +//If callback is NULL, the API is not serialized for the CFGs +eHalStatus ccmCfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, tANI_U32 length, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; +eHalStatus ccmCfgUpdate(tHalHandle hHal, tCcmCfgSetCallback callback) ; +eHalStatus ccmCfgGetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 *pValue) ; +eHalStatus ccmCfgGetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) ; + +void ccmDumpInit(tHalHandle hHal); + +#endif /*CCMAPI_H__*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/csrApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrApi.h new file mode 100644 index 0000000000000..5a4d2ca84fa34 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrApi.h @@ -0,0 +1,1776 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrApi.h + + Exports and types for the Common Scan and Roaming Module interfaces. +========================================================================== */ +#ifndef CSRAPI_H__ +#define CSRAPI_H__ + +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "csrLinkList.h" + +typedef enum +{ + eCSR_AUTH_TYPE_NONE, //never used + // MAC layer authentication types + eCSR_AUTH_TYPE_OPEN_SYSTEM, + eCSR_AUTH_TYPE_SHARED_KEY, + eCSR_AUTH_TYPE_AUTOSWITCH, + + // Upper layer authentication types + eCSR_AUTH_TYPE_WPA, + eCSR_AUTH_TYPE_WPA_PSK, + eCSR_AUTH_TYPE_WPA_NONE, + + eCSR_AUTH_TYPE_RSN, + eCSR_AUTH_TYPE_RSN_PSK, +#if defined WLAN_FEATURE_VOWIFI_11R + eCSR_AUTH_TYPE_FT_RSN, + eCSR_AUTH_TYPE_FT_RSN_PSK, +#endif +#ifdef FEATURE_WLAN_WAPI + eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + eCSR_AUTH_TYPE_WAPI_WAI_PSK, +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + eCSR_AUTH_TYPE_CCKM_WPA, + eCSR_AUTH_TYPE_CCKM_RSN, +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + eCSR_AUTH_TYPE_RSN_PSK_SHA256, + eCSR_AUTH_TYPE_RSN_8021X_SHA256, +#endif + eCSR_NUM_OF_SUPPORT_AUTH_TYPE, + eCSR_AUTH_TYPE_FAILED = 0xff, + eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED, + +}eCsrAuthType; + + +typedef enum +{ + eCSR_ENCRYPT_TYPE_NONE, + eCSR_ENCRYPT_TYPE_WEP40_STATICKEY, + eCSR_ENCRYPT_TYPE_WEP104_STATICKEY, + + eCSR_ENCRYPT_TYPE_WEP40, + eCSR_ENCRYPT_TYPE_WEP104, + eCSR_ENCRYPT_TYPE_TKIP, + eCSR_ENCRYPT_TYPE_AES, +#ifdef FEATURE_WLAN_WAPI + eCSR_ENCRYPT_TYPE_WPI, //WAPI +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + eCSR_ENCRYPT_TYPE_KRK, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + eCSR_ENCRYPT_TYPE_BTK, +#endif +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + //11w BIP + eCSR_ENCRYPT_TYPE_AES_CMAC, +#endif + eCSR_ENCRYPT_TYPE_ANY, + eCSR_NUM_OF_ENCRYPT_TYPE = eCSR_ENCRYPT_TYPE_ANY, + + eCSR_ENCRYPT_TYPE_FAILED = 0xff, + eCSR_ENCRYPT_TYPE_UNKNOWN = eCSR_ENCRYPT_TYPE_FAILED, + +}eCsrEncryptionType; + +/*--------------------------------------------------------------------------- + Enumeration of the various Security types +---------------------------------------------------------------------------*/ +typedef enum +{ + eCSR_SECURITY_TYPE_WPA, + eCSR_SECURITY_TYPE_RSN, +#ifdef FEATURE_WLAN_WAPI + eCSR_SECURITY_TYPE_WAPI, +#endif /* FEATURE_WLAN_WAPI */ + eCSR_SECURITY_TYPE_UNKNOWN, + +}eCsrSecurityType; + +typedef enum +{ + eCSR_DOT11_MODE_TAURUS = 0, //This mean everything because it covers all thing we support + eCSR_DOT11_MODE_abg = 0x0001, //11a/b/g only, no HT, no proprietary + eCSR_DOT11_MODE_11a = 0x0002, + eCSR_DOT11_MODE_11b = 0x0004, + eCSR_DOT11_MODE_11g = 0x0008, + eCSR_DOT11_MODE_11n = 0x0010, + eCSR_DOT11_MODE_POLARIS = 0x0020, + eCSR_DOT11_MODE_TITAN = 0x0040, + eCSR_DOT11_MODE_11g_ONLY = 0x0080, + eCSR_DOT11_MODE_11n_ONLY = 0x0100, + eCSR_DOT11_MODE_TAURUS_ONLY = 0x0200, + eCSR_DOT11_MODE_11b_ONLY = 0x0400, + eCSR_DOT11_MODE_11a_ONLY = 0x0800, +#ifdef WLAN_FEATURE_11AC + eCSR_DOT11_MODE_11ac = 0x1000, + eCSR_DOT11_MODE_11ac_ONLY = 0x2000, +#endif + //This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL except when it starts IBSS in 11B of 2.4GHz + //It is for CSR internal use + eCSR_DOT11_MODE_AUTO = 0x4000, + + eCSR_NUM_PHY_MODE = 16, //specify the number of maximum bits for phyMode +}eCsrPhyMode; + + +typedef tANI_U8 tCsrBssid[VOS_MAC_ADDR_SIZE]; + +typedef enum +{ + eCSR_BSS_TYPE_NONE, + eCSR_BSS_TYPE_INFRASTRUCTURE, + eCSR_BSS_TYPE_INFRA_AP, // SoftAP AP + eCSR_BSS_TYPE_IBSS, // an IBSS network we will NOT start + eCSR_BSS_TYPE_START_IBSS, // an IBSS network we will start if no partners detected. + eCSR_BSS_TYPE_WDS_AP, // BT-AMP AP + eCSR_BSS_TYPE_WDS_STA, // BT-AMP station + eCSR_BSS_TYPE_ANY, // any BSS type (IBSS or Infrastructure). +}eCsrRoamBssType; + + + +typedef enum { + eCSR_SCAN_REQUEST_11D_SCAN = 1, + eCSR_SCAN_REQUEST_FULL_SCAN, + eCSR_SCAN_IDLE_MODE_SCAN, + eCSR_SCAN_HO_BG_SCAN, // bg scan request in NRT & RT Handoff sub-states + eCSR_SCAN_HO_PROBE_SCAN, // directed probe on an entry from the candidate list + eCSR_SCAN_HO_NT_BG_SCAN, // bg scan request in NT sub-state + eCSR_SCAN_P2P_DISCOVERY, + + eCSR_SCAN_SOFTAP_CHANNEL_RANGE, + eCSR_SCAN_P2P_FIND_PEER, +}eCsrRequestType; + +typedef enum { + eCSR_SCAN_RESULT_GET = 0, + eCSR_SCAN_RESULT_FLUSH = 1, //to delete all cached scan results +}eCsrScanResultCmd; + +typedef enum +{ + eCSR_SCAN_SUCCESS, + eCSR_SCAN_FAILURE, + eCSR_SCAN_ABORT, + eCSR_SCAN_FOUND_PEER, +}eCsrScanStatus; + +/* Reason to abort the scan + * The reason can used later to decide whether to update the scan results + * to upper layer or not + */ +typedef enum +{ + eCSR_SCAN_ABORT_DEFAULT, + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE, //Scan aborted due to band change +}eCsrAbortReason; + +typedef enum +{ + eCSR_BW_20MHz_VAL = 20, + eCSR_BW_40MHz_VAL = 40, + eCSR_BW_80MHz_VAL = 80, + eCSR_BW_160MHz_VAL = 160 +}eCSR_BW_Val; + +typedef enum +{ + eCSR_INI_SINGLE_CHANNEL_CENTERED = 0, + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY, + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY, +#ifdef WLAN_FEATURE_11AC + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH, +#endif + eCSR_INI_CHANNEL_BONDING_STATE_MAX +}eIniChanBondState; + + +#define CSR_RSN_PMKID_SIZE 16 +#define CSR_MAX_PMKID_ALLOWED 32 +#define CSR_WEP40_KEY_LEN 5 +#define CSR_WEP104_KEY_LEN 13 +#define CSR_TKIP_KEY_LEN 32 +#define CSR_AES_KEY_LEN 16 +#define CSR_MAX_TX_POWER ( WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX ) +#define CSR_MAX_RSC_LEN 16 +#ifdef FEATURE_WLAN_WAPI +#define CSR_WAPI_BKID_SIZE 16 +#define CSR_MAX_BKID_ALLOWED 16 +#define CSR_WAPI_KEY_LEN 32 +#define CSR_MAX_KEY_LEN ( CSR_WAPI_KEY_LEN ) //longest one is for WAPI +#else +#define CSR_MAX_KEY_LEN ( CSR_TKIP_KEY_LEN ) //longest one is for TKIP +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE +#define CSR_KRK_KEY_LEN 16 +#endif + + +typedef struct tagCsrChannelInfo +{ + tANI_U8 numOfChannels; + tANI_U8 *ChannelList; //it will be an array of channels +}tCsrChannelInfo, *tpCsrChannelInfo; + +typedef struct tagCsrSSIDInfo +{ + tSirMacSSid SSID; + tANI_BOOLEAN handoffPermitted; + tANI_BOOLEAN ssidHidden; +}tCsrSSIDInfo; + +typedef struct tagCsrSSIDs +{ + tANI_U32 numOfSSIDs; + tCsrSSIDInfo *SSIDList; //To be allocated for array of SSIDs +}tCsrSSIDs; + +typedef struct tagCsrBSSIDs +{ + tANI_U32 numOfBSSIDs; + tCsrBssid *bssid; +}tCsrBSSIDs; + +typedef struct tagCsrStaParams +{ + tANI_U16 capability; + tANI_U8 extn_capability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supported_rates_len; + tANI_U8 supported_rates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap HTCap; + tANI_U8 vhtcap_present; + tSirVHTCap VHTCap; + tANI_U8 uapsd_queues; + tANI_U8 max_sp; + tANI_U8 supported_channels_len; + tANI_U8 supported_channels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supported_oper_classes_len; + tANI_U8 supported_oper_classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tCsrStaParams; + +typedef struct tagCsrScanRequest +{ + tSirScanType scanType; + tCsrBssid bssid; + eCsrRoamBssType BSSType; + tCsrSSIDs SSIDs; + tCsrChannelInfo ChannelInfo; + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 minChnTimeBtc; //in units of milliseconds + tANI_U32 maxChnTimeBtc; //in units of milliseconds + tANI_U32 restTime; //in units of milliseconds //ignored when not connected + tANI_U32 uIEFieldLen; + tANI_U8 *pIEField; + eCsrRequestType requestType; //11d scan or full scan + tANI_BOOLEAN p2pSearch; + tANI_BOOLEAN skipDfsChnlInP2pSearch; + tANI_BOOLEAN bcnRptReqScan; //is Scan issued by Beacon Report Request +}tCsrScanRequest; + +typedef struct tagCsrBGScanRequest +{ + tSirScanType scanType; + tSirMacSSid SSID; + tCsrChannelInfo ChannelInfo; + tANI_U32 scanInterval; //in units of milliseconds + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 minChnTimeBtc; //in units of milliseconds + tANI_U32 maxChnTimeBtc; //in units of milliseconds + tANI_U32 restTime; //in units of milliseconds //ignored when not connected + tANI_U32 throughputImpact; //specify whether BG scan cares about impacting throughput //ignored when not connected + tCsrBssid bssid; //how to use it?? Apple +}tCsrBGScanRequest, *tpCsrBGScanRequest; + + +typedef struct tagCsrScanResultInfo +{ + //Carry the IEs for the current BSSDescription. A pointer to tDot11fBeaconIEs. Maybe NULL for start BSS. + void *pvIes; + tAniSSID ssId; + v_TIME_t timer; // timer is variable which is used for hidden SSID's timer value + //This member must be the last in the structure because the end of tSirBssDescription is an + // array with nonknown size at this time + tSirBssDescription BssDescriptor; +}tCsrScanResultInfo; + +typedef struct tagCsrEncryptionList +{ + + tANI_U32 numEntries; + eCsrEncryptionType encryptionType[eCSR_NUM_OF_ENCRYPT_TYPE]; + +}tCsrEncryptionList, *tpCsrEncryptionList; + +typedef struct tagCsrAuthList +{ + tANI_U32 numEntries; + eCsrAuthType authType[eCSR_NUM_OF_SUPPORT_AUTH_TYPE]; +}tCsrAuthList, *tpCsrAuthList; + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsrMobilityDomainInfo +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +} tCsrMobilityDomainInfo; +#endif + +#ifdef FEATURE_WLAN_ESE +typedef struct tagCsrEseCckmInfo +{ + tANI_U32 reassoc_req_num; + tANI_BOOLEAN krk_plumbed; + tANI_U8 krk[SIR_KRK_KEY_LEN]; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 btk[SIR_BTK_KEY_LEN]; +#endif +} tCsrEseCckmInfo; +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define CSR_DOT11F_IE_RSN_MAX_LEN (114) /*TODO: duplicate one in dot11f.h */ +typedef struct tagCsrEseCckmIe +{ + tANI_U8 cckmIe[CSR_DOT11F_IE_RSN_MAX_LEN]; + tANI_U8 cckmIeLen; +} tCsrEseCckmIe; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +typedef struct tagCsrScanResultFilter +{ + tCsrBSSIDs BSSIDs; //each bssid has a length of VOS_MAC_ADDR_SIZE (6) + tCsrSSIDs SSIDs; + tCsrChannelInfo ChannelInfo; + tCsrAuthList authType; + tCsrEncryptionList EncryptionType; + //eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type. If caller doesn't case, + //put all supported encryption types in here + tCsrEncryptionList mcEncryptionType; + eCsrRoamBssType BSSType; + //this is a bit mask of all the needed phy mode defined in eCsrPhyMode + tANI_U32 phyMode; + //If countryCode[0] is not 0, countryCode is checked independent of fCheckUnknownCountryCode + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; + tANI_U8 uapsd_mask; + /*For WPS filtering if true => auth and ecryption should be ignored*/ + tANI_BOOLEAN bWPSAssociation; + tANI_BOOLEAN bOSENAssociation; +#if defined WLAN_FEATURE_VOWIFI + /*For measurement reports --> if set, only SSID, BSSID and channel is considered for filtering.*/ + tANI_BOOLEAN fMeasurement; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + tANI_BOOLEAN p2pResult; +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif +}tCsrScanResultFilter; + + +typedef struct sCsrChnPower_ +{ + tANI_U8 firstChannel; + tANI_U8 numChannels; + tANI_U8 maxtxPower; +}sCsrChnPower; + + +typedef struct sCsrChannel_ +{ + tANI_U8 numChannels; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}sCsrChannel; + + +typedef struct tagCsr11dinfo +{ + sCsrChannel Channels; + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN+1]; + //max power channel list + sCsrChnPower ChnPower[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsr11dinfo; + + +typedef enum +{ + eCSR_ROAM_CANCELLED = 1, + //this mean error happens before association_start or roaming_start is called. + eCSR_ROAM_FAILED, + //a CSR trigger roaming operation starts, callback may get a pointer to tCsrConnectedProfile + eCSR_ROAM_ROAMING_START, + //a CSR trigger roaming operation is completed + eCSR_ROAM_ROAMING_COMPLETION, + //Connection completed status. + eCSR_ROAM_CONNECT_COMPLETION, + //an association or start_IBSS operation starts, + //callback may get a pointer to tCsrRoamProfile and a pointer to tSirBssDescription + eCSR_ROAM_ASSOCIATION_START, + //a roaming operation is finish, see eCsrRoamResult for + //possible data passed back + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_DISASSOCIATED, + eCSR_ROAM_ASSOCIATION_FAILURE, + //when callback with this flag. callback gets a pointer to the BSS desc. + eCSR_ROAM_SHOULD_ROAM, + //A new candidate for PMKID is found + eCSR_ROAM_SCAN_FOUND_NEW_BSS, + //CSR is done lostlink roaming and still cannot reconnect + eCSR_ROAM_LOSTLINK, + //a link lost is detected. CSR starts roaming. + eCSR_ROAM_LOSTLINK_DETECTED, + //TKIP MIC error detected, callback gets a pointer to tpSirSmeMicFailureInd + eCSR_ROAM_MIC_ERROR_IND, + eCSR_ROAM_IBSS_IND, //IBSS indications. + //Update the connection status, useful for IBSS: new peer added, network is active etc. + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_GEN_INFO, + eCSR_ROAM_SET_KEY_COMPLETE, + eCSR_ROAM_REMOVE_KEY_COMPLETE, + eCSR_ROAM_IBSS_LEAVE, //IBSS indications. + //BSS in WDS mode status indication + eCSR_ROAM_WDS_IND, + //BSS in SoftAP mode status indication + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, +#ifdef WLAN_FEATURE_VOWIFI_11R + eCSR_ROAM_FT_RESPONSE, +#endif + eCSR_ROAM_FT_START, + eCSR_ROAM_INDICATE_MGMT_FRAME, + eCSR_ROAM_REMAIN_CHAN_READY, + eCSR_ROAM_SEND_ACTION_CNF, + //this mean error happens before association_start or roaming_start is called. + eCSR_ROAM_SESSION_OPENED, + eCSR_ROAM_FT_REASSOC_FAILED, +#ifdef FEATURE_WLAN_LFR + eCSR_ROAM_PMK_NOTIFY, +#endif +#ifdef FEATURE_WLAN_LFR_METRICS + eCSR_ROAM_PREAUTH_INIT_NOTIFY, + eCSR_ROAM_PREAUTH_STATUS_SUCCESS, + eCSR_ROAM_PREAUTH_STATUS_FAILURE, + eCSR_ROAM_HANDOVER_SUCCESS, +#endif +#ifdef FEATURE_WLAN_TDLS + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, +#endif + eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, //Disaconnect all the clients + eCSR_ROAM_SEND_P2P_STOP_BSS, //Stopbss triggered from SME due to different + // beacon interval +#ifdef WLAN_FEATURE_11W + eCSR_ROAM_UNPROT_MGMT_FRAME_IND, +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + eCSR_ROAM_TSM_IE_IND, + eCSR_ROAM_CCKM_PREAUTH_NOTIFY, + eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, + eCSR_ROAM_ESE_BCN_REPORT_IND, +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + // Radar indication from lower layers + eCSR_ROAM_DFS_RADAR_IND, + eCSR_ROAM_SET_CHANNEL_RSP, + + // Channel sw update notification + eCSR_ROAM_DFS_CHAN_SW_NOTIFY, +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + eCSR_ROAM_AUTHORIZED_EVENT +#endif +}eRoamCmdStatus; + + +//comment inside indicates what roaming callback gets +typedef enum +{ + eCSR_ROAM_RESULT_NONE, + //this means no more action in CSR + //If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION, tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_FAILURE, + //Pass back pointer to tCsrRoamInfo + eCSR_ROAM_RESULT_ASSOCIATED, + eCSR_ROAM_RESULT_NOT_ASSOCIATED, + eCSR_ROAM_RESULT_MIC_FAILURE, + eCSR_ROAM_RESULT_FORCED, + eCSR_ROAM_RESULT_DISASSOC_IND, + eCSR_ROAM_RESULT_DEAUTH_IND, + eCSR_ROAM_RESULT_CAP_CHANGED, + //This means we starts an IBSS + //tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_IBSS_STARTED, + //START_BSS failed + //tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_IBSS_START_FAILED, + eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS, + eCSR_ROAM_RESULT_IBSS_JOIN_FAILED, + eCSR_ROAM_RESULT_IBSS_CONNECT, + eCSR_ROAM_RESULT_IBSS_INACTIVE, + //If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION + //tCsrRoamInfo's pBssDesc may pass back. and the peer's MAC address in peerMacOrBssid + //If roamStatus is eCSR_ROAM_IBSS_IND, + //the peer's MAC address in peerMacOrBssid and a beacon frame of the IBSS in pbFrames + eCSR_ROAM_RESULT_IBSS_NEW_PEER, + //Peer departed from IBSS, Callback may get a pointer tSmeIbssPeerInd in pIbssPeerInd + eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED, + //Coalescing in the IBSS network (joined an IBSS network) + //Callback pass a BSSID in peerMacOrBssid + eCSR_ROAM_RESULT_IBSS_COALESCED, + //If roamStatus is eCSR_ROAM_ROAMING_START, callback may get a pointer to tCsrConnectedProfile used to connect. + eCSR_ROAM_RESULT_IBSS_STOP, + eCSR_ROAM_RESULT_LOSTLINK, + eCSR_ROAM_RESULT_MIC_ERROR_UNICAST, + eCSR_ROAM_RESULT_MIC_ERROR_GROUP, + eCSR_ROAM_RESULT_AUTHENTICATED, + eCSR_ROAM_RESULT_NEW_RSN_BSS, +#ifdef FEATURE_WLAN_WAPI + eCSR_ROAM_RESULT_NEW_WAPI_BSS, +#endif /* FEATURE_WLAN_WAPI */ + // WDS started successfully + eCSR_ROAM_RESULT_WDS_STARTED, + // WDS start failed + eCSR_ROAM_RESULT_WDS_START_FAILED, + // WDS stopped + eCSR_ROAM_RESULT_WDS_STOPPED, + // WDS joined successfully in STA mode + eCSR_ROAM_RESULT_WDS_ASSOCIATED, + // A station joined WDS AP + eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND, + // WDS join failed in STA mode + eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED, + // WDS disassociated + eCSR_ROAM_RESULT_WDS_DISASSOCIATED, + // INFRA started successfully + eCSR_ROAM_RESULT_INFRA_STARTED, + // INFRA start failed + eCSR_ROAM_RESULT_INFRA_START_FAILED, + // INFRA stopped + eCSR_ROAM_RESULT_INFRA_STOPPED, + // A station joining INFRA AP + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND, + // A station joined INFRA AP + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF, + // INFRA disassociated + eCSR_ROAM_RESULT_INFRA_DISASSOCIATED, + eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL, + // peer rejected assoc because max assoc limit reached. callback gets pointer to peer + eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED, + //Assoc rejected due to concurrent session running on a different channel + eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL, +#ifdef FEATURE_WLAN_TDLS + eCSR_ROAM_RESULT_ADD_TDLS_PEER, + eCSR_ROAM_RESULT_UPDATE_TDLS_PEER, + eCSR_ROAM_RESULT_DELETE_TDLS_PEER, + eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND, + eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND, + eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP, + eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER, + eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN, + eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED, +#endif + + eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND, + eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS, + eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE, + eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS, + eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE, +}eCsrRoamResult; + + + +/*---------------------------------------------------------------------------- + List of link quality indications HDD can receive from SME +-----------------------------------------------------------------------------*/ +typedef enum +{ + eCSR_ROAM_LINK_QUAL_MIN_IND = -1, + + eCSR_ROAM_LINK_QUAL_POOR_IND = 0, /* bad link */ + eCSR_ROAM_LINK_QUAL_GOOD_IND = 1, /* acceptable for voice */ + eCSR_ROAM_LINK_QUAL_VERY_GOOD_IND = 2, /* suitable for voice */ + eCSR_ROAM_LINK_QUAL_EXCELLENT_IND = 3, /* suitable for voice */ + + eCSR_ROAM_LINK_QUAL_MAX_IND /* invalid value */ + +} eCsrRoamLinkQualityInd; + +typedef enum +{ + eCSR_DISCONNECT_REASON_UNSPECIFIED = 0, + eCSR_DISCONNECT_REASON_MIC_ERROR, + eCSR_DISCONNECT_REASON_DISASSOC, + eCSR_DISCONNECT_REASON_DEAUTH, + eCSR_DISCONNECT_REASON_HANDOFF, + eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE, + eCSR_DISCONNECT_REASON_IBSS_LEAVE, + eCSR_DISCONNECT_REASON_STA_HAS_LEFT, +}eCsrRoamDisconnectReason; + +typedef enum +{ + // Not associated in Infra or participating in an IBSS / Ad-hoc network. + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED, + // Associated in an Infrastructure network. + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED, + // Participating in an IBSS network though disconnected (no partner stations + // in the IBSS). + eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED, + // Participating in an IBSS network with partner stations also present + eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED, + // Participating in a WDS network in AP or STA mode but not connected yet + eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED, + // Participating in a WDS network and connected peer to peer + eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED, + // Participating in a Infra network in AP not yet in connected state + eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED, + // Participating in a Infra network and connected to a peer + eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED, + +}eCsrConnectState; + + +// This parameter is no longer supported in the Profile. Need to set this in the global properties +// for the adapter. +typedef enum eCSR_MEDIUM_ACCESS +{ + eCSR_MEDIUM_ACCESS_AUTO = 0, + eCSR_MEDIUM_ACCESS_DCF, + eCSR_MEDIUM_ACCESS_eDCF, + eCSR_MEDIUM_ACCESS_HCF, + + eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p, + eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP, + eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify, + eCSR_MEDIUM_ACCESS_11e_eDCF = eCSR_MEDIUM_ACCESS_eDCF, + eCSR_MEDIUM_ACCESS_11e_HCF = eCSR_MEDIUM_ACCESS_HCF, +}eCsrMediaAccessType; + +typedef enum +{ + eCSR_TX_RATE_AUTO = 0, // use rate adaption to determine Tx rate. + + eCSR_TX_RATE_1Mbps = 0x00000001, + eCSR_TX_RATE_2Mbps = 0x00000002, + eCSR_TX_RATE_5_5Mbps = 0x00000004, + eCSR_TX_RATE_6Mbps = 0x00000008, + eCSR_TX_RATE_9Mbps = 0x00000010, + eCSR_TX_RATE_11Mbps = 0x00000020, + eCSR_TX_RATE_12Mbps = 0x00000040, + eCSR_TX_RATE_18Mbps = 0x00000080, + eCSR_TX_RATE_24Mbps = 0x00000100, + eCSR_TX_RATE_36Mbps = 0x00000200, + eCSR_TX_RATE_42Mbps = 0x00000400, + eCSR_TX_RATE_48Mbps = 0x00000800, + eCSR_TX_RATE_54Mbps = 0x00001000, + eCSR_TX_RATE_72Mbps = 0x00002000, + eCSR_TX_RATE_84Mbps = 0x00004000, + eCSR_TX_RATE_96Mbps = 0x00008000, + eCSR_TX_RATE_108Mbps = 0x00010000, + eCSR_TX_RATE_126Mbps = 0x00020000, + eCSR_TX_RATE_144Mbps = 0x00040000, + eCSR_TX_RATE_168Mbps = 0x00080000, + eCSR_TX_RATE_192Mbps = 0x00100000, + eCSR_TX_RATE_216Mbps = 0x00200000, + eCSR_TX_RATE_240Mbps = 0x00400000, + +}eCsrExposedTxRate; + +typedef enum +{ + eCSR_OPERATING_CHANNEL_ALL = 0, + eCSR_OPERATING_CHANNEL_AUTO = eCSR_OPERATING_CHANNEL_ALL, + eCSR_OPERATING_CHANNEL_ANY = eCSR_OPERATING_CHANNEL_ALL, +}eOperationChannel; + +typedef enum +{ + eCSR_DOT11_FRAG_THRESH_AUTO = -1, + eCSR_DOT11_FRAG_THRESH_MIN = 256, + eCSR_DOT11_FRAG_THRESH_MAX = 2346, + eCSR_DOT11_FRAG_THRESH_DEFAULT = 2000 +}eCsrDot11FragThresh; + + +//for channel bonding for ibss +typedef enum +{ + eCSR_CB_OFF = 0, + eCSR_CB_AUTO = 1, + eCSR_CB_DOWN = 2, + eCSR_CB_UP = 3, +}eCsrCBChoice; + +//For channel bonding, the channel number gap is 4, either up or down. For both 11a and 11g mode. +#define CSR_CB_CHANNEL_GAP 4 +#define CSR_CB_CENTER_CHANNEL_OFFSET 2 +#define CSR_MAX_24GHz_CHANNEL_NUMBER ( SIR_11B_CHANNEL_END ) +#define CSR_MIN_5GHz_CHANNEL_NUMBER ( SIR_11A_CHANNEL_BEGIN ) +#define CSR_MAX_5GHz_CHANNEL_NUMBER ( SIR_11A_CHANNEL_END ) + +// WEP keysize (in bits)... +typedef enum +{ + eCSR_SECURITY_WEP_KEYSIZE_40 = 40, // 40 bit key + 24bit IV = 64bit WEP + eCSR_SECURITY_WEP_KEYSIZE_104 = 104, // 104bit key + 24bit IV = 128bit WEP + + eCSR_SECURITY_WEP_KEYSIZE_MIN = eCSR_SECURITY_WEP_KEYSIZE_40, + eCSR_SECURITY_WEP_KEYSIZE_MAX = eCSR_SECURITY_WEP_KEYSIZE_104, + eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES = ( eCSR_SECURITY_WEP_KEYSIZE_MAX / 8 ), +}eCsrWEPKeySize; + + +// Possible values for the WEP static key ID... +typedef enum +{ + + eCSR_SECURITY_WEP_STATIC_KEY_ID_MIN = 0, + eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX = 3, + eCSR_SECURITY_WEP_STATIC_KEY_ID_DEFAULT = 0, + + eCSR_SECURITY_WEP_STATIC_KEY_ID_INVALID = -1, + +}eCsrWEPStaticKeyID; + +// Two extra key indicies are used for the IGTK (which is used by BIP) +#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1) + +typedef enum +{ + eCSR_SECURITY_SET_KEY_ACTION_NO_CHANGE, + eCSR_SECURITY_SET_KEY_ACTION_SET_KEY, + eCSR_SECURITY_SET_KEY_ACTION_DELETE_KEY, +}eCsrSetKeyAction; + +typedef enum +{ + eCSR_BAND_ALL, + eCSR_BAND_24, + eCSR_BAND_5G, + eCSR_BAND_MAX, +}eCsrBand; + + +typedef enum +{ + // Roaming because HDD requested for reassoc by changing one of the fields in + // tCsrRoamModifyProfileFields. OR + // Roaming because SME requested for reassoc by changing one of the fields in + // tCsrRoamModifyProfileFields. + eCsrRoamReasonStaCapabilityChanged, + // Roaming because SME requested for reassoc to a different AP, as part of + // inter AP handoff. + eCsrRoamReasonBetterAP, + // Roaming because SME requested it as the link is lost - placeholder, will + // clean it up once handoff code gets in + eCsrRoamReasonSmeIssuedForLostLink, + +}eCsrRoamReasonCodes; + +typedef enum +{ + eCsrRoamWmmAuto = 0, + eCsrRoamWmmQbssOnly = 1, + eCsrRoamWmmNoQos = 2, + +} eCsrRoamWmmUserModeType; + +typedef enum +{ + eCSR_REQUESTER_MIN = 0, + eCSR_DIAG, + eCSR_UMA_GAN, + eCSR_HDD +} eCsrStatsRequesterType; + +typedef struct tagPmkidCandidateInfo +{ + tCsrBssid BSSID; + tANI_BOOLEAN preAuthSupported; +}tPmkidCandidateInfo; + +typedef struct tagPmkidCacheInfo +{ + tCsrBssid BSSID; + tANI_U8 PMKID[CSR_RSN_PMKID_SIZE]; +}tPmkidCacheInfo; + +#ifdef FEATURE_WLAN_WAPI +typedef struct tagBkidCandidateInfo +{ + tCsrBssid BSSID; + tANI_BOOLEAN preAuthSupported; +}tBkidCandidateInfo; + +typedef struct tagBkidCacheInfo +{ + tCsrBssid BSSID; + tANI_U8 BKID[CSR_WAPI_BKID_SIZE]; +}tBkidCacheInfo; +#endif /* FEATURE_WLAN_WAPI */ + +typedef struct tagCsrKeys +{ + tANI_U8 KeyLength[ CSR_MAX_NUM_KEY ]; //Also use to indicate whether the key index is set + tANI_U8 KeyMaterial[ CSR_MAX_NUM_KEY ][ CSR_MAX_KEY_LEN ]; + tANI_U8 defaultIndex; +}tCsrKeys; + +/* Following are fields which are part of tCsrRoamConnectedProfile might need + modification dynamically once STA is up & running and this could trigger + reassoc */ +typedef struct tagCsrRoamModifyProfileFields +{ + // during connect this specifies ACs U-APSD is to be setup + // for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored). + // During assoc response this COULD carry confirmation of what ACs U-APSD + // got setup for. Later if an APP looking for APSD, SME-QoS might need to + // modify this field + tANI_U8 uapsd_mask; + // HDD might ask to modify this field + tANI_U16 listen_interval; +}tCsrRoamModifyProfileFields; + +typedef struct tagCsrRoamProfile +{ + //For eCSR_BSS_TYPE_WDS_AP. There must be one SSID in SSIDs. + //For eCSR_BSS_TYPE_WDS_STA. There must be two SSIDs. Index 0 is the SSID of the WDS-AP + //that we need to join. Index 1 is the SSID for self BSS. + tCsrSSIDs SSIDs; + tCsrBSSIDs BSSIDs; + tANI_U32 phyMode; //this is a bit mask of all the needed phy mode defined in eCsrPhyMode + eCsrRoamBssType BSSType; + + tCsrAuthList AuthType; + eCsrAuthType negotiatedAuthType; + + tCsrEncryptionList EncryptionType; + //This field is for output only, not for input + eCsrEncryptionType negotiatedUCEncryptionType; + + //eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type. If caller doesn't case, + //put all supported encryption types in here + tCsrEncryptionList mcEncryptionType; + //This field is for output only, not for input + eCsrEncryptionType negotiatedMCEncryptionType; + +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif + + tCsrKeys Keys; + eCsrCBChoice CBMode; //up, down or auto + tCsrChannelInfo ChannelInfo; + tANI_U8 operationChannel; + tANI_U16 beaconInterval; //If this is 0, SME will fill in for caller. + // during connect this specifies ACs U-APSD is to be setup + // for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored). + // During assoc response this COULD carry confirmation of what ACs U-APSD got setup for + tANI_U8 uapsd_mask; + tANI_U32 nWPAReqIELength; //The byte count in the pWPAReqIE + tANI_U8 *pWPAReqIE; //If not null, it has the IE byte stream for WPA + tANI_U32 nRSNReqIELength; //The byte count in the pRSNReqIE + tANI_U8 *pRSNReqIE; //If not null, it has the IE byte stream for RSN +#ifdef FEATURE_WLAN_WAPI + tANI_U32 nWAPIReqIELength; //The byte count in the pWAPIReqIE + tANI_U8 *pWAPIReqIE; //If not null, it has the IE byte stream for WAPI +#endif /* FEATURE_WLAN_WAPI */ + + tANI_U32 nAddIEScanLength; //The byte count in the pAddIE for scan (at the time of join) + tANI_U8 *pAddIEScan; //If not null, it has the IE byte stream for additional IE, which can be WSC IE and/or P2P IE + tANI_U32 nAddIEAssocLength; //The byte count in the pAddIE for assoc + tANI_U8 *pAddIEAssoc; //If not null, it has the IE byte stream for additional IE, which can be WSC IE and/or P2P IE + + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //it is ignored if [0] is 0. + /*WPS Association if true => auth and ecryption should be ignored*/ + tANI_BOOLEAN bWPSAssociation; + tANI_BOOLEAN bOSENAssociation; + tANI_U32 nWSCReqIELength; //The byte count in the pWSCReqIE + tANI_U8 *pWSCReqIE; //If not null, it has the IE byte stream for WSC + + tANI_U8 ieee80211d; + tANI_U8 privacy; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tAniAuthType csr80211AuthType; + tANI_U32 dtimPeriod; + tANI_BOOLEAN ApUapsdEnable; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tANI_U16 cfg_protection; + tANI_U8 wps_state; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + tVOS_CON_MODE csrPersona; + + tANI_U8 disableDFSChSwitch; + /* addIe params */ + tSirAddIeParams addIeParams; + uint8_t sap_dot11mc; +}tCsrRoamProfile; + + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +typedef struct tagCsrRoamHTProfile +{ + eCsrPhyMode phymode; + tANI_U8 htCapability; + tANI_U8 htSupportedChannelWidthSet; + tANI_U8 htRecommendedTxWidthSet; + ePhyChanBondState htSecondaryChannelOffset; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability; + tANI_U8 vhtTxChannelWidthSet; + tANI_U8 apCenterChan; + tANI_U8 apChanWidth; +#endif +}tCsrRoamHTProfile; +#endif +typedef struct tagCsrRoamConnectedProfile +{ + tSirMacSSid SSID; + tANI_BOOLEAN handoffPermitted; + tANI_BOOLEAN ssidHidden; + tCsrBssid bssid; + eCsrRoamBssType BSSType; + eCsrAuthType AuthType; + tCsrAuthList AuthInfo; + eCsrEncryptionType EncryptionType; + tCsrEncryptionList EncryptionInfo; + eCsrEncryptionType mcEncryptionType; + tCsrEncryptionList mcEncryptionInfo; + eCsrCBChoice CBMode; //up, down or auto + tANI_U8 operationChannel; + tANI_U16 beaconInterval; + tCsrKeys Keys; + // meaningless on connect. It's an OUT param from CSR's point of view + // During assoc response carries the ACM bit-mask i.e. what + // ACs have ACM=1 (if any), + // (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) + tANI_U8 acm_mask; + tCsrRoamModifyProfileFields modifyProfileFields; + tANI_U32 nAddIEAssocLength; //The byte count in the pAddIE for assoc + tANI_U8 *pAddIEAssoc; //If not null, it has the IE byte stream for additional IE, which can be WSC IE and/or P2P IE + + tSirBssDescription *pBssDesc; + tANI_BOOLEAN qap; //AP supports QoS + tANI_BOOLEAN qosConnection; //A connection is QoS enabled +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + +#ifdef FEATURE_WLAN_ESE + tCsrEseCckmInfo eseCckmInfo; + tANI_BOOLEAN isESEAssoc; +#endif + tANI_U32 dot11Mode; + tANI_U8 proxyARPService; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tCsrRoamHTProfile HTProfile; +#endif +#ifdef WLAN_FEATURE_11W + /* Management Frame Protection */ + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif +}tCsrRoamConnectedProfile; + + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsr11rConfigParams +{ + tANI_BOOLEAN IsFTResourceReqSupported; +} tCsr11rConfigParams; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +typedef struct tagCsrNeighborRoamConfigParams +{ + + tANI_U32 nNeighborScanTimerPeriod; + tANI_U8 nNeighborLookupRssiThreshold; + tANI_U8 nNeighborReassocRssiThreshold; + tANI_U16 nNeighborScanMinChanTime; + tANI_U16 nNeighborScanMaxChanTime; + sCsrChannel neighborScanChanList; + tANI_U8 nMaxNeighborRetries; + tANI_U16 nNeighborResultsRefreshPeriod; + tANI_U16 nEmptyScanRefreshPeriod; + tANI_U8 nOpportunisticThresholdDiff; + tANI_U8 nRoamRescanRssiDiff; + tANI_U8 nRoamBmissFirstBcnt; + tANI_U8 nRoamBmissFinalBcnt; + tANI_U8 nRoamBeaconRssiWeight; + tANI_U8 delay_before_vdev_stop; +}tCsrNeighborRoamConfigParams; +#endif + +typedef struct tagCsrConfigParam +{ + tANI_U32 FragmentationThreshold; + tANI_U32 channelBondingMode24GHz; // keep this tANI_U32. This gets converted to ePhyChannelBondState + tANI_U32 channelBondingMode5GHz; // in csrChangeDefaultConfigParam using convertCBIniValueToPhyCBState + eCsrPhyMode phyMode; + eCsrBand eBand; + tANI_U32 RTSThreshold; + tANI_U32 HeartbeatThresh50; + tANI_U32 HeartbeatThresh24; + eCsrCBChoice cbChoice; + eCsrBand bandCapability; //indicate hw capability + tANI_U32 bgScanInterval; + tANI_U16 TxRate; + eCsrRoamWmmUserModeType WMMSupportMode; + tANI_BOOLEAN Is11eSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabledOriginal; + tANI_BOOLEAN Is11hSupportEnabled; + tANI_BOOLEAN shortSlotTime; + tANI_BOOLEAN ProprietaryRatesEnabled; + tANI_U8 AdHocChannel24; + tANI_U8 AdHocChannel5G; + tANI_U32 impsSleepTime; //in units of seconds + tANI_U32 nScanResultAgeCount; //this number minus one is the number of times a scan doesn't find it before it is removed + tANI_U32 scanAgeTimeNCNPS; //scan result aging time threshold when Not-Connect-No-Power-Save, in seconds + tANI_U32 scanAgeTimeNCPS; //scan result aging time threshold when Not-Connect-Power-Save, in seconds + tANI_U32 scanAgeTimeCNPS; //scan result aging time threshold when Connect-No-Power-Save, in seconds, + tANI_U32 scanAgeTimeCPS; //scan result aging time threshold when Connect-Power-Savein seconds + tANI_U32 nRoamingTime; //In seconds, CSR will try this long before gives up. 0 means no roaming + tANI_U8 bCatRssiOffset; //to set the RSSI difference for each category + tANI_U8 fEnableMCCMode; //to set MCC Enable/Disable mode + tANI_U8 fAllowMCCGODiffBI; //to allow MCC GO different B.I than STA's. NOTE: make sure if RIVA firmware can handle this combination before enabling this + //at the moment, this flag is provided only to pass Wi-Fi Cert. 5.1.12 + tCsr11dinfo Csr11dinfo; + //Whether to limit the channels to the ones set in Csr11dInfo. If true, the opertaional + //channels are limited to the default channel list. It is an "AND" operation between the + //default channels and the channels in the 802.11d IE. + tANI_BOOLEAN fEnforce11dChannels; + //Country Code Priority + //0 = 802.11D > Country IOCTL > NV + //1 = Country IOCTL > 802.11D > NV + tANI_BOOLEAN fSupplicantCountryCodeHasPriority; + //When true, AP with unknown country code won't be see. + //"Unknown country code" means either Ap doesn't have 11d IE or we cannot + //find a domain for the country code in its 11d IE. + tANI_BOOLEAN fEnforceCountryCodeMatch; + //When true, only APs in the default domain can be seen. If the Ap has "unknown country + //code", or the domain of the country code doesn't match the default domain, the Ap is + //not acceptable. + tANI_BOOLEAN fEnforceDefaultDomain; + + tANI_U16 vccRssiThreshold; + tANI_U32 vccUlMacLossThreshold; + + tANI_U32 nPassiveMinChnTime; //in units of milliseconds + tANI_U32 nPassiveMaxChnTime; //in units of milliseconds + tANI_U32 nActiveMinChnTime; //in units of milliseconds + tANI_U32 nActiveMaxChnTime; //in units of milliseconds + + tANI_U32 nInitialDwellTime; //in units of milliseconds + bool initial_scan_no_dfs_chnl; + + tANI_U32 nActiveMinChnTimeBtc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeBtc; //in units of milliseconds + tANI_U32 disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + tANI_U32 nPassiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nPassiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nRestTimeConc; //in units of milliseconds + tANI_U8 nNumStaChanCombinedConc; //number of channels combined for + //STA in each split scan operation + tANI_U8 nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + tANI_BOOLEAN IsIdleScanEnabled; + //in dBm, the maximum TX power + //The actual TX power is the lesser of this value and 11d. + //If 11d is disable, the lesser of this and default setting. + tANI_U8 nTxPowerCap; + tANI_U32 statsReqPeriodicity; //stats request frequency from PE while in full power + tANI_U32 statsReqPeriodicityInPS;//stats request frequency from PE while in power save +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsr11rConfigParams csr11rConfig; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_U8 nImmediateRoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamConfigParams neighborRoamConfig; +#endif + + /* Instead of Reassoc, send ADDTS/DELTS even when ACM is off for that AC + * This is mandated by WMM-AC certification */ + tANI_BOOLEAN addTSWhenACMIsOff; + + + /*channelPowerInfoList24 has been seen corrupted. Set this flag to true trying to + * detect when it happens. Adding this into code because we can't reproduce it easily. + * We don't know when it happens. */ + tANI_BOOLEAN fValidateList; + + /*Customer wants to start with an active scan based on the default country code. + * This optimization will minimize the driver load to association time. + * Based on this flag we will bypass the initial passive scan needed for 11d + * to determine the country code & domain */ + tANI_BOOLEAN fEnableBypass11d; + + /*Customer wants to optimize the scan time. Avoiding scans(passive) on DFS + * channels while swipping through both bands can save some time + * (apprx 1.3 sec) */ + tANI_BOOLEAN fEnableDFSChnlScan; + + //To enable/disable scanning 2.4Ghz channels twice on a single scan request from HDD + tANI_BOOLEAN fScanTwice; +#ifdef WLAN_FEATURE_11AC + tANI_U32 nVhtChannelWidth; + tANI_U8 enableTxBF; + tANI_U8 txBFCsnValue; + tANI_U8 enable2x2; + tANI_BOOLEAN enableVhtFor24GHz; + tANI_U8 enableMuBformee; + tANI_U8 enableVhtpAid; + tANI_U8 enableVhtGid; +#endif + tANI_U8 enableAmpduPs; + tANI_U8 enableHtSmps; + tANI_U8 htSmps; + + /* + * To enable/disable scanning only 2.4Ghz channels on first scan + */ + tANI_BOOLEAN fFirstScanOnly2GChnl; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_BOOLEAN nRoamPrefer5GHz; + tANI_BOOLEAN nRoamIntraBand; + tANI_U8 nProbes; + tANI_U16 nRoamScanHomeAwayTime; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tANI_BOOLEAN isRoamOffloadScanEnabled; + tANI_BOOLEAN bFastRoamInConIniFeatureEnabled; +#endif +#endif + + + tANI_U8 scanCfgAgingTime; + + tANI_U8 enableTxLdpc; + + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 nSelect5GHzMargin; + + tANI_U8 isCoalesingInIBSSAllowed; + + eCsrBand scanBandPreference; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 cc_switch_mode; +#endif + tANI_U8 allowDFSChannelRoam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_BOOLEAN isRoamOffloadEnabled; +#endif + + tANI_BOOLEAN obssEnabled; + + v_U16_t pkt_err_disconn_th; +}tCsrConfigParam; + +//Tush +typedef struct tagCsrUpdateConfigParam +{ + tCsr11dinfo Csr11dinfo; +}tCsrUpdateConfigParam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define csrRoamIsRoamOffloadEnabled(pMac)\ + (pMac->roam.configParam.isRoamOffloadEnabled) + +#define DEFAULT_REASSOC_FAILURE_TIMEOUT 1000 +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define CSR_ROAM_AUTH_STATUS_CONNECTED 0x1 /** connected, + but not authenticated */ +#define CSR_ROAM_AUTH_STATUS_AUTHENTICATED 0x2 /** connected + and authenticated */ +#endif + +typedef struct tagCsrRoamInfo +{ + tCsrRoamProfile *pProfile; //may be NULL + tSirBssDescription *pBssDesc; //May be NULL + tANI_U32 nBeaconLength; //the length, in bytes, of the beacon frame, can be 0 + tANI_U32 nAssocReqLength; //the length, in bytes, of the assoc req frame, can be 0 + tANI_U32 nAssocRspLength; //The length, in bytes, of the assoc rsp frame, can be 0 + tANI_U32 nFrameLength; + tANI_U8 frameType; + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. + tANI_BOOLEAN fReassocReq; //set to true if for re-association + tANI_BOOLEAN fReassocRsp; //set to true if for re-association + tCsrBssid bssid; + //Only valid in IBSS + //this is the peers MAC address for eCSR_ROAM_RESULT_IBSS_NEW_PEER or PEER_DEPARTED + tCsrBssid peerMac; + tSirResultCodes statusCode; + tANI_U32 reasonCode; //this could be our own defined or sent from the other BSS(per 802.11 spec) + tANI_U8 staId; // Peer stationId when connected + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + tANI_BOOLEAN fAuthRequired; //FALSE means auth needed from supplicant. TRUE means authenticated(static WEP, open) + tANI_U8 sessionId; + tANI_U8 rsnIELen; + tANI_U8 *prsnIE; + + tANI_U8 addIELen; + tANI_U8 *paddIE; + + union + { + tSirMicFailureInfo *pMICFailureInfo; + tCsrRoamConnectedProfile *pConnectedProfile; + tSirWPSPBCProbeReq *pWPSPBCProbeReq; + } u; + + tANI_BOOLEAN wmmEnabledSta; //set to true if WMM enabled STA + tANI_U32 dtimPeriod; + +#ifdef FEATURE_WLAN_ESE + tANI_BOOLEAN isESEAssoc; +#ifdef FEATURE_WLAN_ESE_UPLOAD + tSirTsmIE tsmIe; + tANI_U32 timestamp[2]; + tANI_U16 tsmRoamDelay; + tSirEseBcnReportRsp *pEseBcnReportRsp; +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + void* pRemainCtx; + tANI_U32 rxChan; + +#ifdef FEATURE_WLAN_TDLS + tANI_U8 staType; + bool tdls_prohibited; /* per ExtCap in Assoc/Reassoc resp */ + bool tdls_chan_swit_prohibited; /* per ExtCap in Assoc/Reassoc resp */ +#endif + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + + tANI_S8 rxRssi; + tSirSmeDfsEventInd dfs_event; + tSirChanChangeResponse *channelChangeRespEvent; + /* Timing and fine Timing measurement capability clubbed together */ + tANI_U8 timingMeasCap; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 roamSynchInProgress; + tANI_U8 synchAuthStatus; + tANI_U8 kck[SIR_KCK_KEY_LEN]; + tANI_U8 kek[SIR_KEK_KEY_LEN]; + tANI_U8 replay_ctr[SIR_REPLAY_CTR_LEN]; +#endif + tSirSmeChanInfo chan_info; +}tCsrRoamInfo; + + +typedef struct tagCsrFreqScanInfo +{ + tANI_U32 nStartFreq; //in unit of MHz + tANI_U32 nEndFreq; //in unit of MHz + tSirScanType scanType; +}tCsrFreqScanInfo; + + +typedef struct sSirSmeAssocIndToUpperLayerCnf +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_CNF + tANI_U16 length; + tANI_U8 sessionId; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; + tANI_U8 wmmEnabledSta; //set to true if WMM enabled STA + tSirRSNie rsnIE; // RSN IE received from peer + tSirAddie addIE; // Additional IE received from peer, which can be WSC and/or P2P IE + tANI_U8 reassocReq; //set to true if reassoc + /* Timing and fine Timing measurement capability clubbed together */ + tANI_U8 timingMeasCap; + tSirSmeChanInfo chan_info; +} tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf; + +typedef struct tagCsrSummaryStatsInfo +{ + tANI_U32 retry_cnt[4]; + tANI_U32 multiple_retry_cnt[4]; + tANI_U32 tx_frm_cnt[4]; + //tANI_U32 num_rx_frm_crc_err; same as rx_error_cnt + //tANI_U32 num_rx_frm_crc_ok; same as rx_frm_cnt + tANI_U32 rx_frm_cnt; + tANI_U32 frm_dup_cnt; + tANI_U32 fail_cnt[4]; + tANI_U32 rts_fail_cnt; + tANI_U32 ack_fail_cnt; + tANI_U32 rts_succ_cnt; + tANI_U32 rx_discard_cnt; + tANI_U32 rx_error_cnt; + tANI_U32 tx_byte_cnt; + +}tCsrSummaryStatsInfo; + +typedef struct tagCsrGlobalClassAStatsInfo +{ + tANI_U32 rx_frag_cnt; + tANI_U32 promiscuous_rx_frag_cnt; + //tANI_U32 rx_fcs_err; + tANI_U32 rx_input_sensitivity; + tANI_U32 max_pwr; + //tANI_U32 default_pwr; + tANI_U32 sync_fail_cnt; + tANI_U32 tx_rate; + //mcs index for HT20 and HT40 rates + tANI_U32 mcs_index; + //to defferentiate between HT20 and HT40 rates;short and long guard interval + tANI_U32 tx_rate_flags; + +}tCsrGlobalClassAStatsInfo; + +typedef struct tagCsrGlobalClassBStatsInfo +{ + tANI_U32 uc_rx_wep_unencrypted_frm_cnt; + tANI_U32 uc_rx_mic_fail_cnt; + tANI_U32 uc_tkip_icv_err; + tANI_U32 uc_aes_ccmp_format_err; + tANI_U32 uc_aes_ccmp_replay_cnt; + tANI_U32 uc_aes_ccmp_decrpt_err; + tANI_U32 uc_wep_undecryptable_cnt; + tANI_U32 uc_wep_icv_err; + tANI_U32 uc_rx_decrypt_succ_cnt; + tANI_U32 uc_rx_decrypt_fail_cnt; + tANI_U32 mcbc_rx_wep_unencrypted_frm_cnt; + tANI_U32 mcbc_rx_mic_fail_cnt; + tANI_U32 mcbc_tkip_icv_err; + tANI_U32 mcbc_aes_ccmp_format_err; + tANI_U32 mcbc_aes_ccmp_replay_cnt; + tANI_U32 mcbc_aes_ccmp_decrpt_err; + tANI_U32 mcbc_wep_undecryptable_cnt; + tANI_U32 mcbc_wep_icv_err; + tANI_U32 mcbc_rx_decrypt_succ_cnt; + tANI_U32 mcbc_rx_decrypt_fail_cnt; + +}tCsrGlobalClassBStatsInfo; + +typedef struct tagCsrGlobalClassCStatsInfo +{ + tANI_U32 rx_amsdu_cnt; + tANI_U32 rx_ampdu_cnt; + tANI_U32 tx_20_frm_cnt; + tANI_U32 rx_20_frm_cnt; + tANI_U32 rx_mpdu_in_ampdu_cnt; + tANI_U32 ampdu_delimiter_crc_err; + +}tCsrGlobalClassCStatsInfo; + +typedef struct tagCsrGlobalClassDStatsInfo +{ + tANI_U32 tx_uc_frm_cnt; + tANI_U32 tx_mc_frm_cnt; + tANI_U32 tx_bc_frm_cnt; + tANI_U32 rx_uc_frm_cnt; + tANI_U32 rx_mc_frm_cnt; + tANI_U32 rx_bc_frm_cnt; + tANI_U32 tx_uc_byte_cnt[4]; + tANI_U32 tx_mc_byte_cnt; + tANI_U32 tx_bc_byte_cnt; + tANI_U32 rx_uc_byte_cnt[4]; + tANI_U32 rx_mc_byte_cnt; + tANI_U32 rx_bc_byte_cnt; + tANI_U32 rx_byte_cnt; + tANI_U32 num_rx_bytes_crc_ok; + tANI_U32 rx_rate; + +}tCsrGlobalClassDStatsInfo; + +typedef struct tagCsrPerStaStatsInfo +{ + tANI_U32 tx_frag_cnt[4]; + tANI_U32 tx_ampdu_cnt; + tANI_U32 tx_mpdu_in_ampdu_cnt; +} tCsrPerStaStatsInfo; + +typedef struct tagCsrRoamSetKey +{ + eCsrEncryptionType encType; + tAniKeyDirection keyDirection; //Tx, Rx or Tx-and-Rx + tCsrBssid peerMac; //Peers MAC address. ALL 1's for group key + tANI_U8 paeRole; //0 for supplicant + tANI_U8 keyId; // Kye index + tANI_U16 keyLength; //Number of bytes containing the key in pKey + tANI_U8 Key[CSR_MAX_KEY_LEN]; + tANI_U8 keyRsc[CSR_MAX_RSC_LEN]; +} tCsrRoamSetKey; + +typedef struct tagCsrRoamRemoveKey +{ + eCsrEncryptionType encType; + tCsrBssid peerMac; //Peers MAC address. ALL 1's for group key + tANI_U8 keyId; //key index +} tCsrRoamRemoveKey; + +#ifdef FEATURE_WLAN_TDLS + +typedef struct tagCsrLinkEstablishParams +{ + tSirMacAddr peerMac; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 isResponder; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tCsrTdlsLinkEstablishParams; + +typedef struct tagCsrTdlsSendMgmt +{ + tSirMacAddr peerMac; + tANI_U8 frameType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tANI_U8 *buf; + tANI_U8 len; + +}tCsrTdlsSendMgmt; + +#endif + +typedef void * tScanResultHandle; + +#define CSR_INVALID_SCANRESULT_HANDLE (NULL) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +typedef enum +{ + REASSOC = 0, + FASTREASSOC = 1 +}handoff_src; + +typedef struct tagCsrHandoffRequest +{ + tCsrBssid bssid; + tANI_U8 channel; + tANI_U8 src; /* To check if its a REASSOC or a FASTREASSOC IOCTL */ +}tCsrHandoffRequest; +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +typedef struct tagCsrEseBeaconReqParams +{ + tANI_U16 measurementToken; + tANI_U8 channel; + tANI_U8 scanMode; + tANI_U16 measurementDuration; +} tCsrEseBeaconReqParams, *tpCsrEseBeaconReqParams; + +typedef struct tagCsrEseBeaconReq +{ + tANI_U8 numBcnReqIe; + tCsrEseBeaconReqParams bcnReq[SIR_ESE_MAX_MEAS_IE_REQS]; +} tCsrEseBeaconReq, *tpCsrEseBeaconReq; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +////////////////////////////////////////////Common SCAN starts + +//void *p2 -- the second context pass in for the caller +//***what if callback is called before requester gets the scanId?? +typedef eHalStatus (*csrScanCompleteCallback)(tHalHandle, void *p2, + tANI_U8 sessionId, + tANI_U32 scanID, + eCsrScanStatus status); + + + +///////////////////////////////////////////Common Roam starts + +//pContext is the pContext passed in with the roam request +//pParam is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and +// eRoamCmdResult for detail valid members. It may be NULL +//roamId is to identify the callback related roam request. 0 means unsolicit +//roamStatus is a flag indicating the status of the callback +//roamResult is the result +typedef eHalStatus (*csrRoamCompleteCallback)(void *pContext, tCsrRoamInfo *pParam, tANI_U32 roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult); + +typedef eHalStatus (*csrRoamSessionCloseCallback)(void *pContext); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetNumPMKIDCache + \brief return number of PMKID cache entries + \return tANI_U32 - the number of PMKID cache entries + -------------------------------------------------------------------------------*/ +//tANI_U32 csrRoamGetNumPMKIDCache(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetPMKIDCache + \brief return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +//eHalStatus csrRoamGetPMKIDCache(tHalHandle hHal, tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache); + +//pProfile - pointer to tCsrRoamProfile +#define CSR_IS_START_IBSS(pProfile) (eCSR_BSS_TYPE_START_IBSS == (pProfile)->BSSType) +#define CSR_IS_JOIN_TO_IBSS(pProfile) (eCSR_BSS_TYPE_IBSS == (pProfile)->BSSType) +#define CSR_IS_IBSS(pProfile) ( CSR_IS_START_IBSS(pProfile) || CSR_IS_JOIN_TO_IBSS(pProfile) ) +#define CSR_IS_INFRASTRUCTURE(pProfile) (eCSR_BSS_TYPE_INFRASTRUCTURE == (pProfile)->BSSType) +#define CSR_IS_ANY_BSS_TYPE(pProfile) (eCSR_BSS_TYPE_ANY == (pProfile)->BSSType) +#define CSR_IS_WDS_AP( pProfile ) ( eCSR_BSS_TYPE_WDS_AP == (pProfile)->BSSType ) +#define CSR_IS_WDS_STA( pProfile ) ( eCSR_BSS_TYPE_WDS_STA == (pProfile)->BSSType ) +#define CSR_IS_WDS( pProfile ) ( CSR_IS_WDS_AP( pProfile ) || CSR_IS_WDS_STA( pProfile ) ) +#define CSR_IS_INFRA_AP( pProfile ) ( eCSR_BSS_TYPE_INFRA_AP == (pProfile)->BSSType ) + +//pProfile - pointer to tCsrRoamConnectedProfile +#define CSR_IS_CONN_INFRA_AP( pProfile ) ( eCSR_BSS_TYPE_INFRA_AP == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS_AP( pProfile ) ( eCSR_BSS_TYPE_WDS_AP == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS_STA( pProfile ) ( eCSR_BSS_TYPE_WDS_STA == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS( pProfile ) ( CSR_IS_WDS_AP( pProfile ) || CSR_IS_WDS_STA( pProfile ) ) + + + +///////////////////////////////////////////Common Roam ends + + + +/* --------------------------------------------------------------------------- + \fn csrSetChannels + \brief HDD calls this function to change some global settings. + caller must set the all fields or call csrGetConfigParam to prefill the fields. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus csrSetChannels(tHalHandle hHal, tCsrConfigParam *pParam ); + +eHalStatus csrSetRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode); + + +//enum to string conversion for debug output +const char * get_eRoamCmdStatus_str(eRoamCmdStatus val); +const char * get_eCsrRoamResult_str(eCsrRoamResult val); +/* --------------------------------------------------------------------------- + \fn csrSetPhyMode + \brief HDD calls this function to set the phyMode. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param phyMode - indicate the phyMode needs to set to. The value has to be either 0, or some bits set. + See eCsrPhyMode for definition + \param eBand - specify the operational band (2.4, 5 or both) + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI_BOOLEAN *pfRestartNeeded); + +void csrDumpInit(tHalHandle hHal); + + +/*--------------------------------------------------------------------------- + This is the type for a link quality callback to be registered with SME + for indications + Once the link quality has been indicated, subsequently, link indications are + posted each time there is a CHANGE in link quality. + *** If there is no change in link, there will be no indication *** + + The indications may be based on one or more criteria internal to SME + such as RSSI and PER. + + \param ind - Indication being posted + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void (* csrRoamLinkQualityIndCallback) + (eCsrRoamLinkQualityInd ind, void *pContext); + + +/*--------------------------------------------------------------------------- + This is the type for a statistics callback to be registered with SME + for stats reporting + + Since the client requesting for the stats already know which class/type of + stats it asked for, the callback will carry them in the rsp buffer + (void * stats) whose size will be same as the size of requested stats & + will be exactly in the same order requested in the stats mask from LSB to MSB + + \param stats - stats rsp buffer sent back with the report + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void ( *tCsrStatsCallback) (void * stats, void *pContext); + +/*--------------------------------------------------------------------------- + This is the type for a rssi callback to be registered with SME + for getting rssi + + \param rssi - rssi + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ + +typedef void ( *tCsrRssiCallback) (v_S7_t rssi, tANI_U32 staId, void *pContext); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/*--------------------------------------------------------------------------- + This is the type for a tsm stats callback to be registered with SME + for getting tsm stats + \param tsmMetrics - tsmMetrics + \param pContext - any user data given at callback registration. + \return None +---------------------------------------------------------------------------*/ +typedef void ( *tCsrTsmStatsCallback) (tAniTrafStrmMetrics tsmMetrics, + tANI_U32 staId, + void *pContext); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/*--------------------------------------------------------------------------- + This is the type for a snr callback to be registered with SME + for getting snr + + \param snr + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void (*tCsrSnrCallback) (v_S7_t snr, tANI_U32 staId, void *pContext); + +#ifdef WLAN_FEATURE_VOWIFI_11R +eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tpSirBssDescription pBssDescription); +#endif + +/*--------------------------------------------------------------------------- + This is the function to change the Band configuraiton (ALL/2.4 GHZ/5 GHZ) + + \param hHal - handle to Hal context + \param eBand - band value + \param sessionId - Session Identifier + \return eHalStatus + +---------------------------------------------------------------------------*/ +eHalStatus csrSetBand(tHalHandle hHal, tANI_U8 sessionId, eCsrBand eBand); + +/*--------------------------------------------------------------------------- + This is the function to get the current operating band value + \param hHal - handl to Hal context + \return eCsrband - band value + +---------------------------------------------------------------------------*/ +eCsrBand csrGetCurrentBand (tHalHandle hHal); + +typedef void (*csrReadyToSuspendCallback)(void *pContext, boolean suspended); + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +typedef void (*csrReadyToExtWoWCallback)(void *pContext, boolean status); +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrRoamIssueFTRoamOffloadSynch(tHalHandle hHal, tANI_U32 sessionId, + tSirBssDescription *pBssDescription); +#endif + +/*--------------------------------------------------------------------------- + Callback to be registered with SME for getting link status + \param status - link stats req result status + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void (*tCsrLinkStatusCallback)(v_U8_t status, void *pContext); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/csrInternal.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrInternal.h new file mode 100644 index 0000000000000..a7a00cb9f1a8e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrInternal.h @@ -0,0 +1,1544 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrInternal.h + + Define internal data structure for MAC. +========================================================================== */ +#ifndef CSRINTERNAL_H__ +#define CSRINTERNAL_H__ + +#include "vos_status.h" +#include "vos_lock.h" + +#include "vos_timer.h" +#include "csrSupport.h" +#include "vos_nvitem.h" +#include "wlan_qct_tl.h" + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "csrNeighborRoam.h" +#endif + +#define CSR_MAX_STA (HAL_NUM_STA) + +//define scan return criteria. LIM should use these define as well +#define CSR_SCAN_RETURN_AFTER_ALL_CHANNELS ( 0 ) +#define CSR_SCAN_RETURN_AFTER_FIRST_MATCH ( 0x01 ) +#define CSR_SCAN_RETURN_AFTER_5_BAND_11d_FOUND ( 0x80 ) +#define CSR_SCAN_RETURN_AFTER_24_BAND_11d_FOUND ( 0x40 ) +#define CSR_SCAN_RETURN_AFTER_EITHER_BAND_11d_FOUND ( CSR_SCAN_RETURN_AFTER_5_BAND_11d_FOUND | CSR_SCAN_RETURN_AFTER_24_BAND_11d_FOUND ) +#define CSR_NUM_RSSI_CAT 15 +#define CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME 3 + +//Support for multiple session +#define CSR_SESSION_ID_INVALID 0xFF // session ID invalid +#define CSR_ROAM_SESSION_MAX 5 // No of sessions to be supported, and a + // session is for Infra, IBSS or BT-AMP +#define CSR_SESSION_ID_ANY 50 + +#define CSR_IS_SESSION_VALID( pMac, sessionId ) ( ( (sessionId) < CSR_ROAM_SESSION_MAX ) \ + && ( (pMac)->roam.roamSession[(sessionId)].sessionActive ) ) +#define CSR_GET_SESSION( pMac, sessionId ) \ +( \ + (sessionId < CSR_ROAM_SESSION_MAX) ? \ + (&(pMac)->roam.roamSession[(sessionId)]) :\ + NULL \ +) + +#define CSR_IS_SESSION_ANY(sessionId) (sessionId == CSR_SESSION_ID_ANY) +#define CSR_MAX_NUM_COUNTRY_CODE 100 +#define CSR_IS_SELECT_5GHZ_MARGIN( pMac ) \ +( \ + (((pMac)->roam.configParam.nSelect5GHzMargin)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CSR_IS_ROAM_PREFER_5GHZ( pMac ) \ +( \ + (((pMac)->roam.configParam.nRoamPrefer5GHz)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#define CSR_IS_ROAM_INTRA_BAND_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.nRoamIntraBand)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CSR_IS_ROAM_SCAN_OFFLOAD_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.isRoamOffloadScanEnabled)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#define CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.bFastRoamInConIniFeatureEnabled)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#endif + +//Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) +#define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15 + +typedef enum +{ + //eCSR_CFG_DOT11_MODE_BEST = 0, + eCSR_CFG_DOT11_MODE_TAURUS = 0, + eCSR_CFG_DOT11_MODE_ABG, + eCSR_CFG_DOT11_MODE_11A, + eCSR_CFG_DOT11_MODE_11B, + eCSR_CFG_DOT11_MODE_11G, + eCSR_CFG_DOT11_MODE_11N, + eCSR_CFG_DOT11_MODE_POLARIS, + eCSR_CFG_DOT11_MODE_TITAN, +#ifdef WLAN_FEATURE_11AC + eCSR_CFG_DOT11_MODE_11AC, +#endif + eCSR_CFG_DOT11_MODE_11G_ONLY, + eCSR_CFG_DOT11_MODE_11N_ONLY, +#ifdef WLAN_FEATURE_11AC + eCSR_CFG_DOT11_MODE_11AC_ONLY, +#endif + //This value can never set to CFG. It is for CSR's internal use + eCSR_CFG_DOT11_MODE_AUTO, +}eCsrCfgDot11Mode; //Used to determine what to set to the WNI_CFG_DOT11_MODE + +typedef enum etCsrRoamCommands +{ + eCsrRoamNoCommand, + eCsrRoamCommandScan, + eCsrRoamCommandRoam, + eCsrRoamCommandWmStatusChange, + eCsrRoamCommandSetKey, + eCsrRoamCommandRemoveKey, + +} eCsrRoamCommands; + +typedef enum +{ + eCsrScanOther = 1, + eCsrScanLostLink1, + eCsrScanLostLink2, + eCsrScanLostLink3, + eCsrScanLostLink4, + eCsrScan11d1, //First 11d scan + eCsrScan11d2, //First 11d scan has failed + eCsrScan11dDone, //11d scan succeeded, try the rest of the channel + eCsrScanUserRequest, + eCsrScanGetResult, + eCsrScanSetBGScanParam, //used for HO too - bg scan request in NT Handoff sub-state + eCsrScanForSsid, + eCsrScanForCapsChange, + eCsrScanBGScanAbort, + eCsrScanBGScanEnable, + eCsrScanIdleScan, + eCsrScanGetScanChnInfo, //To get the list of channels scanned + + eCsrScanBgScan, // bg scan request in NRT & RT Handoff sub-states + eCsrScanProbeBss, // directed probe on an entry from the candidate list - HO + eCsrScanAbortBgScan, //aborting a BG scan (meaning the scan is triggered by LIM timer) + eCsrScanAbortNormalScan, //aborting a normal scan (the scan is trigger by eWNI_SME_SCAN_REQ) + eCsrScanP2PFindPeer, + eCsrScanGetLfrResult, // get the LFR candidates from PE scan cache +}eCsrScanReason; + +typedef enum +{ + eCsrNoConnection, // Roaming because we have not established the initial connection. + eCsrCapsChange, // roaming because LIM reported a Capability change in the associated AP. + eCsrForcedDisassoc, // roaming becuase someone asked us to Disassoc and stay disassociated. + eCsrHddIssued, // roaming because an 802.11 request was issued to the driver. + eCsrLostLink1, // roaming because we lost link to an associated AP + eCsrLostLink2, + eCsrLostLink3, + eCsrForcedDisassocMICFailure, // roaming because we need to force a Disassoc due to MIC failure + eCsrHddIssuedReassocToSameAP, + eCsrSmeIssuedReassocToSameAP, + eCsrSmeIssuedReassocToDiffAP, + eCsrForcedDeauth, // roaming becuase someone asked us to deauth and stay disassociated. + eCsrSmeIssuedDisassocForHandoff, // will be issued by Handoff logic to disconect from current AP + eCsrSmeIssuedAssocToSimilarAP, // will be issued by Handoff logic to join a new AP with same profile + eCsrSmeIssuedIbssJoinFailure, // ibss join timer fired before any perr showed up, so shut down the network + eCsrForcedIbssLeave, + eCsrStopBss, + eCsrSmeIssuedFTReassoc, + eCsrForcedDisassocSta, + eCsrForcedDeauthSta, + eCsrPerformPreauth, + eCsrLostLink1Abort, + eCsrLostLink2Abort, + eCsrLostLink3Abort, +}eCsrRoamReason; + +typedef enum +{ + eCSR_ROAM_SUBSTATE_NONE = 0, + eCSR_ROAM_SUBSTATE_START_BSS_REQ, + eCSR_ROAM_SUBSTATE_JOIN_REQ, + eCSR_ROAM_SUBSTATE_REASSOC_REQ, + eCSR_ROAM_SUBSTATE_DISASSOC_REQ, + eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, //Continue the current roam command after disconnect + eCSR_ROAM_SUBSTATE_AUTH_REQ, + eCSR_ROAM_SUBSTATE_CONFIG, + eCSR_ROAM_SUBSTATE_DEAUTH_REQ, + eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, + eCSR_ROAM_SUBSTATE_DISASSOC_FORCED, + eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, + eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF, + eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC, + eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC, + eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC, + eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT, +// max is 15 unless the bitfield is expanded... +} eCsrRoamSubState; + + +typedef enum +{ + eCSR_ROAMING_STATE_STOP = 0, + eCSR_ROAMING_STATE_IDLE, + eCSR_ROAMING_STATE_SCANNING, + eCSR_ROAMING_STATE_JOINING, + eCSR_ROAMING_STATE_JOINED, +}eCsrRoamState; + + +typedef enum +{ + eCsrContinueRoaming, + eCsrStopRoaming, + eCsrStartIbss, + eCsrStartIbssSameIbss, + eCsrReassocToSelfNoCapChange, + eCsrStopRoamingDueToConcurrency, + +}eCsrJoinState; + +typedef enum +{ + eCsrNotRoaming, + eCsrLostlinkRoamingDisassoc, + eCsrLostlinkRoamingDeauth, + eCsrDynamicRoaming, + eCsrReassocRoaming, +}eCsrRoamingReason; + +typedef enum +{ + eCsrDisassociated, + eCsrDeauthenticated + +}eCsrRoamWmStatusChangeTypes; + +typedef enum +{ + eCsrSummaryStats = 0, + eCsrGlobalClassAStats, + eCsrGlobalClassBStats, + eCsrGlobalClassCStats, + eCsrGlobalClassDStats, + eCsrPerStaStats, + eCsrMaxStats +}eCsrRoamStatsClassTypes; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +typedef enum +{ + eCSR_WLAN_STATUS_CONNECT =0, + eCSR_WLAN_STATUS_DISCONNECT + +}eCsrDiagWlanStatusEventSubtype; + +typedef enum +{ + eCSR_REASON_UNSPECIFIED = 0, + eCSR_REASON_USER_REQUESTED, + eCSR_REASON_MIC_ERROR, + eCSR_REASON_DISASSOC, + eCSR_REASON_DEAUTH, + eCSR_REASON_HANDOFF, + +}eCsrDiagWlanStatusEventReason; + +#endif //FEATURE_WLAN_DIAG_SUPPORT + +typedef struct tagCsrChannel +{ + tANI_U8 numChannels; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsrChannel; + +typedef struct tagScanProfile +{ + tANI_U32 minChnTime; + tANI_U32 maxChnTime; + tANI_U32 restTime; //This is ignored if not associated + tANI_U32 numOfChannels; + tANI_U8 *pChannelList; + tSirScanType scanType; //active or passive + eCsrRoamBssType bssType; //BSS or IBSS + tANI_U8 ssid[WNI_CFG_SSID_LEN]; + tANI_U8 bReturnAfter1stMatch; + tANI_U8 fUniqueResult; + tANI_U8 freshScan; + tCsrBssid bssid; +}tScanProfile; + +typedef struct tagBssConfigParam +{ + eCsrMediaAccessType qosType; + tSirMacSSid SSID; + tANI_U32 uRTSThresh; + tANI_U32 uDeferThresh; // + eCsrCfgDot11Mode uCfgDot11Mode; + eCsrBand eBand; + tANI_U8 standardRate[CSR_DOT11_SUPPORTED_RATES_MAX]; + tANI_U8 extendedRate[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; + eCsrExposedTxRate txRate; + tAniAuthType authType; + eCsrEncryptionType encType; + tANI_U32 uShortSlotTime; + tANI_U32 uHTSupport; //High throughput + tANI_U32 uPowerLimit; + tANI_U32 uHeartBeatThresh; + tANI_U32 uJoinTimeOut; + tSirMacCapabilityInfo BssCap; + tANI_BOOLEAN f11hSupport; + ePhyChanBondState cbMode; +}tBssConfigParam; + + +typedef struct tagCsrRoamStartBssParams +{ + tSirMacSSid ssId; + tCsrBssid bssid; //this is the BSSID for the party we want to join (only use for IBSS or WDS) + tSirNwType sirNwType; + ePhyChanBondState cbMode; + tSirMacRateSet operationalRateSet; + tSirMacRateSet extendedRateSet; + tANI_U8 operationChn; + eCsrCfgDot11Mode uCfgDot11Mode; + tANI_U8 privacy; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tAniAuthType authType; + tANI_U16 beaconInterval; //If this is 0, SME will fill in for caller. + tANI_U16 ht_protection; + tANI_U32 dtimPeriod; + tANI_U8 ApUapsdEnable; + tANI_U8 ssidHidden; + tANI_U8 wps_state; + tVOS_CON_MODE bssPersona; + tANI_U16 nRSNIELength; //The byte count in the pRSNIE, if 0, pRSNIE is ignored. + tANI_U8 *pRSNIE; //If not null, it has the IE byte stream for RSN + tANI_BOOLEAN updatebeaconInterval; //Flag used to indicate update + // beaconInterval +#ifdef WLAN_FEATURE_11W + tANI_BOOLEAN mfpCapable; + tANI_BOOLEAN mfpRequired; +#endif + + tSirAddIeParams addIeParams; + uint8_t sap_dot11mc; + +}tCsrRoamStartBssParams; + + +typedef struct tagScanCmd +{ + tANI_U32 scanID; + csrScanCompleteCallback callback; + void *pContext; + eCsrScanReason reason; + eCsrRoamState lastRoamState[CSR_ROAM_SESSION_MAX]; + tCsrRoamProfile *pToRoamProfile; + tANI_U32 roamId; //this is the ID related to the pToRoamProfile + union + { + tCsrScanRequest scanRequest; + tCsrBGScanRequest bgScanRequest; + }u; + //This flag will be set while aborting the scan due to band change + tANI_BOOLEAN abortScanDueToBandChange; +}tScanCmd; + +typedef struct tagRoamCmd +{ + tANI_U32 roamId; + eCsrRoamReason roamReason; + tCsrRoamProfile roamProfile; + tScanResultHandle hBSSList; //BSS list fits the profile + tListElem *pRoamBssEntry; //point to the current BSS in the list that is roaming. It starts from head to tail + tSirBssDescription *pLastRoamBss; //the last BSS we try and failed + tANI_BOOLEAN fReleaseBssList; //whether to free hBSSList + tANI_BOOLEAN fReleaseProfile; //whether to free roamProfile + tANI_BOOLEAN fReassoc; //whether this command is for reassociation + tANI_BOOLEAN fUpdateCurRoamProfile; //whether pMac->roam.pCurRoamProfile needs to be updated + //this is for CSR internal used only. And it should not be assigned when creating the command + //This causes the roam command not to do anything. + tANI_BOOLEAN fReassocToSelfNoCapChange; + + tANI_BOOLEAN fStopWds; + tSirMacAddr peerMac; + tSirMacReasonCodes reason; +}tRoamCmd; + +typedef struct tagSetKeyCmd +{ + tANI_U32 roamId; + eCsrEncryptionType encType; + eCsrAuthType authType; + tAniKeyDirection keyDirection; //Tx, Rx or Tx-and-Rx + tSirMacAddr peerMac; //Peer's MAC address. ALL 1's for group key + tANI_U8 paeRole; //0 for supplicant + tANI_U8 keyId; // Kye index + tANI_U8 keyLength; //Number of bytes containing the key in pKey + tANI_U8 Key[CSR_MAX_KEY_LEN]; + tANI_U8 keyRsc[CSR_MAX_RSC_LEN]; +} tSetKeyCmd; + +typedef struct tahRemoveKeyCmd +{ + tANI_U32 roamId; + eCsrEncryptionType encType; + eCsrAuthType authType; + tSirMacAddr peerMac; //Peer's MAC address. ALL 1's for group key + tANI_U8 keyId; //key index +} tRemoveKeyCmd; + +typedef struct tagWmStatusChangeCmd +{ + eCsrRoamWmStatusChangeTypes Type; + union + { + tSirSmeDeauthInd DeauthIndMsg; + tSirSmeDisassocInd DisassocIndMsg; + }u; + +}tWmStatusChangeCmd; + + +typedef struct tagAddStaForSessionCmd +{ + //Session self mac addr + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; + tANI_U32 type; + tANI_U32 subType; + tANI_U8 sessionId; +}tAddStaForSessionCmd; + +typedef struct tagDelStaForSessionCmd +{ + //Session self mac addr + tSirMacAddr selfMacAddr; + csrRoamSessionCloseCallback callback; + void *pContext; +}tDelStaForSessionCmd; + +//This structure represents one scan request +typedef struct tagCsrCmd +{ + tListElem Link; + eCsrRoamCommands command; + tANI_U8 sessionId; // Session ID for this command + union + { + tScanCmd scanCmd; + tRoamCmd roamCmd; + tWmStatusChangeCmd wmStatusChangeCmd; + tSetKeyCmd setKeyCmd; + tRemoveKeyCmd removeKeyCmd; + tAddStaForSessionCmd addStaSessionCmd; + tDelStaForSessionCmd delStaSessionCmd; + }u; +}tCsrCmd; + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsr11rConfig +{ + tANI_BOOLEAN IsFTResourceReqSupported; +} tCsr11rConfig; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +typedef struct tagCsrNeighborRoamConfig +{ + tANI_U32 nNeighborScanTimerPeriod; + tANI_U8 nNeighborLookupRssiThreshold; + tANI_U8 nNeighborReassocRssiThreshold; + tANI_U16 nNeighborScanMinChanTime; + tANI_U16 nNeighborScanMaxChanTime; + sCsrChannel neighborScanChanList; + tANI_U8 nMaxNeighborRetries; + tANI_U16 nNeighborResultsRefreshPeriod; + tANI_U16 nEmptyScanRefreshPeriod; + tANI_U8 nOpportunisticThresholdDiff; + tANI_U8 nRoamRescanRssiDiff; + tANI_U8 nRoamBmissFirstBcnt; + tANI_U8 nRoamBmissFinalBcnt; + tANI_U8 nRoamBeaconRssiWeight; + tANI_U8 delay_before_vdev_stop; +}tCsrNeighborRoamConfig; +#endif + +typedef struct tagCsrConfig +{ + tANI_U32 agingCount; + tANI_U32 FragmentationThreshold; + tANI_U32 channelBondingMode24GHz; + tANI_U32 channelBondingMode5GHz; + tANI_U32 RTSThreshold; + eCsrPhyMode phyMode; + eCsrCfgDot11Mode uCfgDot11Mode; + eCsrBand eBand; + tANI_U32 HeartbeatThresh50; + tANI_U32 HeartbeatThresh24; + tANI_U32 bgScanInterval; + eCsrCBChoice cbChoice; + eCsrBand bandCapability; //indicate hw capability + eCsrRoamWmmUserModeType WMMSupportMode; + tANI_BOOLEAN Is11eSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabledOriginal; + tANI_BOOLEAN Is11hSupportEnabled; + tANI_BOOLEAN shortSlotTime; + tANI_BOOLEAN ProprietaryRatesEnabled; + tANI_BOOLEAN fenableMCCMode; + tANI_U16 TxRate; + tANI_U8 fAllowMCCGODiffBI; + tANI_U8 AdHocChannel24; + tANI_U8 AdHocChannel5G; + tANI_U32 impsSleepTime; //in units of microseconds + tANI_U32 scanAgeTimeNCNPS; //scan result aging time threshold when Not-Connect-No-Power-Save, in seconds + tANI_U32 scanAgeTimeNCPS; //scan result aging time threshold when Not-Connect-Power-Save, in seconds + tANI_U32 scanAgeTimeCNPS; //scan result aging time threshold when Connect-No-Power-Save, in seconds, + tANI_U32 scanAgeTimeCPS; //scan result aging time threshold when Connect-Power-Savein seconds + tANI_U32 BssPreferValue[CSR_NUM_RSSI_CAT]; //each RSSI category has one value + int RSSICat[CSR_NUM_RSSI_CAT]; + tANI_U8 bCatRssiOffset; //to set the RSSI difference for each category + tANI_U32 nRoamingTime; //In seconds, CSR will try this long before gives up, 0 means no roaming + //Whether to limit the channels to the ones set in Csr11dInfo. If true, the opertaional + //channels are limited to the default channel list. It is an "AND" operation between the + //default channels and the channels in the 802.11d IE. + tANI_BOOLEAN fEnforce11dChannels; + //Country Code Priority + //0 = 802.11D > Configured Country > NV + //1 = Configured Country > 802.11D > NV + tANI_BOOLEAN fSupplicantCountryCodeHasPriority; + //When true, AP with unknown country code won't be see. + //"Unknown country code" means either Ap doesn't have 11d IE or we cannot + //find a domain for the country code in its 11d IE. + tANI_BOOLEAN fEnforceCountryCodeMatch; + //When true, only APs in the default domain can be seen. If the Ap has "unknown country + //code", or the doamin of the country code doesn't match the default domain, the Ap is + //not acceptable. + tANI_BOOLEAN fEnforceDefaultDomain; + + tANI_U16 vccRssiThreshold; + tANI_U32 vccUlMacLossThreshold; + + tANI_U32 nPassiveMinChnTime; //in units of milliseconds + tANI_U32 nPassiveMaxChnTime; //in units of milliseconds + tANI_U32 nActiveMinChnTime; //in units of milliseconds + tANI_U32 nActiveMaxChnTime; //in units of milliseconds + + tANI_U32 nInitialDwellTime; //in units of milliseconds + bool initial_scan_no_dfs_chnl; + + tANI_U32 nActiveMinChnTimeBtc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeBtc; //in units of milliseconds + tANI_U8 disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + tANI_U32 nPassiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nPassiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nRestTimeConc; //in units of milliseconds + tANI_U8 nNumStaChanCombinedConc; //number of channels combined for + //Sta in each split scan operation + tANI_U8 nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + tANI_BOOLEAN IsIdleScanEnabled; + //in dBm, the maximum TX power + //The actual TX power is the lesser of this value and 11d. + //If 11d is disable, the lesser of this and default setting. + tANI_U8 nTxPowerCap; + tANI_U32 statsReqPeriodicity; //stats request frequency from PE while in full power + tANI_U32 statsReqPeriodicityInPS;//stats request frequency from PE while in power save + tANI_U32 dtimPeriod; + tANI_BOOLEAN ssidHidden; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsr11rConfig csr11rConfig; +#endif + +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tANI_U8 isRoamOffloadScanEnabled; + tANI_BOOLEAN bFastRoamInConIniFeatureEnabled; +#endif +#endif + +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_U8 nImmediateRoamRssiDiff; + tANI_BOOLEAN nRoamPrefer5GHz; + tANI_BOOLEAN nRoamIntraBand; + tANI_BOOLEAN isWESModeEnabled; + tANI_BOOLEAN nRoamScanControl; + tANI_U8 nProbes; + tANI_U16 nRoamScanHomeAwayTime; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamConfig neighborRoamConfig; +#endif + + /* Instead of Reassoc, send ADDTS/DELTS even when ACM is off for that AC + * This is mandated by WMM-AC certification */ + tANI_BOOLEAN addTSWhenACMIsOff; + + tANI_BOOLEAN fValidateList; + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + tANI_BOOLEAN doBMPSWorkaround; + + //To enable/disable scanning 2.4Ghz channels twice on a single scan request from HDD + tANI_BOOLEAN fScanTwice; +#ifdef WLAN_FEATURE_11AC + tANI_U32 nVhtChannelWidth; + tANI_U8 txBFEnable; + tANI_U8 txBFCsnValue; + tANI_U8 enable2x2; + tANI_BOOLEAN enableVhtFor24GHz; + tANI_U8 txMuBformee; + tANI_U8 enableVhtpAid; + tANI_U8 enableVhtGid; +#endif + tANI_U8 enableAmpduPs; + tANI_U8 enableHtSmps; + tANI_U8 htSmps; + tANI_U8 txLdpcEnable; + + /* + * Enable/Disable heartbeat offload + */ + tANI_BOOLEAN enableHeartBeatOffload; + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 nSelect5GHzMargin; + tANI_U8 isCoalesingInIBSSAllowed; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + tANI_U8 cc_switch_mode; +#endif + tANI_U8 allowDFSChannelRoam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_BOOLEAN isRoamOffloadEnabled; +#endif + tANI_BOOLEAN obssEnabled; + v_U16_t pkt_err_disconn_th; +}tCsrConfig; + +typedef struct tagCsrChannelPowerInfo +{ + tListElem link; + tANI_U8 firstChannel; + tANI_U8 numChannels; + tANI_U8 txPower; + tANI_U8 interChannelOffset; +}tCsrChannelPowerInfo; + +typedef struct tagRoamJoinStatus +{ + tSirResultCodes statusCode; + //this is set to unspecified if statusCode indicates timeout. Or it is the failed reason from the other BSS(per 802.11 spec) + tANI_U32 reasonCode; + tSirMacAddr bssId; +}tCsrRoamJoinStatus; + +typedef struct tagCsrOsChannelMask +{ + tANI_U8 numChannels; + tANI_BOOLEAN scanEnabled[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsrOsChannelMask; + +typedef struct tagCsrVotes11d +{ + tANI_U8 votes; + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; +}tCsrVotes11d; + +typedef struct tagCsrScanStruct +{ + tScanProfile scanProfile; + tANI_U32 nextScanID; + tDblLinkList scanResultList; + tDblLinkList tempScanResults; + tANI_BOOLEAN fScanEnable; + tANI_BOOLEAN fFullScanIssued; + vos_timer_t hTimerGetResult; +#ifdef WLAN_AP_STA_CONCURRENCY + vos_timer_t hTimerStaApConcTimer; +#endif + vos_timer_t hTimerIdleScan; + vos_timer_t hTimerResultAging; + vos_timer_t hTimerResultCfgAging; + //changes on every scan, it is used as a flag for whether 11d info is found on every scan + tANI_U8 channelOf11dInfo; + tANI_U8 scanResultCfgAgingTime; + //changes on every scan, a flag to tell whether conflict 11d info found on each BSS + tANI_BOOLEAN fAmbiguous11dInfoFound; + //changes on every scan, a flag to tell whether the applied 11d info present in one of the scan results + tANI_BOOLEAN fCurrent11dInfoMatch; + tANI_BOOLEAN f11dInfoReset; //to indicate whether the 11d info in CFG is reset to default + tSirScanType curScanType; + tCsrChannel baseChannels; //This are all the supported channels AND(&) to the current eBand + tCsrChannel channels11d; + tChannelListWithPower defaultPowerTable[WNI_CFG_VALID_CHANNEL_LIST_LEN]; //From NV + tChannelListWithPower defaultPowerTable40MHz[WNI_CFG_VALID_CHANNEL_LIST_LEN]; //From NV + tANI_U32 numChannelsDefault; //total channels of NV + tCsrChannel base20MHzChannels; //The channel base to work on + tCsrChannel base40MHzChannels; //center channels for 40MHz channels + tDblLinkList channelPowerInfoList24; + tDblLinkList channelPowerInfoList5G; + tANI_U32 nLastAgeTimeOut; + tANI_U32 nAgingCountDown; + tANI_U8 countryCodeDefault[WNI_CFG_COUNTRY_CODE_LEN]; //The country code from NV + tANI_U8 countryCodeCurrent[WNI_CFG_COUNTRY_CODE_LEN]; + tANI_U8 countryCode11d[WNI_CFG_COUNTRY_CODE_LEN]; + v_REGDOMAIN_t domainIdDefault; //default regulatory domain + v_REGDOMAIN_t domainIdCurrent; //current regulatory domain + tCsrBssid currentCountryBssid; // Bssid for current country code + tANI_S8 currentCountryRSSI; // RSSI for current country code + tANI_BOOLEAN f11dInfoApplied; + tANI_BOOLEAN fCancelIdleScan; + tANI_U8 countryCodeCount; + tCsrVotes11d votes11d[CSR_MAX_NUM_COUNTRY_CODE]; //counts for various advertized country codes + //in 11d IE from probe rsp or beacons of neighboring APs; + //will use the most popular one (max count) + tANI_U8 countryCodeElected[WNI_CFG_COUNTRY_CODE_LEN]; + + tANI_U8 numBGScanChannel; //number of valid channels in the bgScanChannelList + tANI_U8 bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + //the ChannelInfo member is not used in this structure. + //numBGScanChannel and bgScanChannelList are used for the BG scan channel info + tCsrBGScanRequest bgScanParams; + tANI_BOOLEAN fRestartIdleScan; + tANI_U32 nIdleScanTimeGap; //the time since last trying to trigger idle scan + tCsrOsChannelMask osScanChannelMask;//keep a track of channels to be scnned while in traffic condition + tANI_U16 nBssLimit; //the maximum number of BSS in scan cache + /*channelPowerInfoList24 has been seen corrupted. Set this flag to true trying to + * detect when it happens. Adding this into code because we can't reproduce it easily. + * We don't know when it happens. */ + tANI_BOOLEAN fValidateList; + /*Customer wants to start with an active scan based on the default country code. + * This optimization will minimize the driver load to association time. + * Based on this flag we will bypass the initial passive scan needed for 11d + * to determine the country code & domain */ + tANI_BOOLEAN fEnableBypass11d; + + /*Customer wants to optimize the scan time. Avoiding scans(passive) on DFS + * channels while swipping through both bands can save some time + * (apprx 1.3 sec) */ + tANI_BOOLEAN fEnableDFSChnlScan; + + /* + * To enable/disable scanning only 2.4Ghz channels on first scan + */ + tANI_BOOLEAN fFirstScanOnly2GChnl; + + tANI_BOOLEAN fDropScanCmd; //true means we don't accept scan commands + +#ifdef WLAN_AP_STA_CONCURRENCY + tDblLinkList scanCmdPendingList; +#endif + /* This includes all channels on which candidate APs are found */ + tCsrChannel occupiedChannels[CSR_ROAM_SESSION_MAX]; + tANI_S8 inScanResultBestAPRssi; + eCsrBand scanBandPreference; //This defines the band perference for scan + csrScanCompleteCallback callback11dScanDone; + bool fcc_constraint; +}tCsrScanStruct; + +//Save the connected information. This structure + connectedProfile +//should contain all information about the connection +typedef struct tagRoamCsrConnectedInfo +{ + tANI_U32 nBeaconLength; //the length, in bytes, of the beacon frame, can be 0 + tANI_U32 nAssocReqLength; //the length, in bytes, of the assoc req frame, can be 0 + tANI_U32 nAssocRspLength; //The length, in bytes, of the assoc rsp frame, can be 0 +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 nRICRspLength; //Length of the parsed RIC response IEs received in reassoc response +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 nTspecIeLength; +#endif + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. + tANI_U8 staId; +}tCsrRoamConnectedInfo; + + +typedef struct tagCsrLinkQualityIndInfo +{ + csrRoamLinkQualityIndCallback callback; + void *context; +}tCsrLinkQualityIndInfo; + +typedef struct tagCsrPeStatsReqInfo +{ + tListElem link; /* list links */ + tANI_U32 statsMask; + tANI_U32 periodicity; + tANI_BOOLEAN rspPending; + vos_timer_t hPeStatsTimer; + tANI_BOOLEAN timerRunning; + tANI_U8 staId; + tANI_U8 numClient; + tpAniSirGlobal pMac; + /* To remember if the peStats timer is stopped successfully or not */ + tANI_BOOLEAN timerStopFailed; + tANI_U8 sessionId; + +}tCsrPeStatsReqInfo; + +typedef struct tagCsrStatsClientReqInfo +{ + tListElem link; /* list links */ + eCsrStatsRequesterType requesterId; + tCsrStatsCallback callback; + tANI_U32 periodicity; + void *pContext; + tANI_U32 statsMask; + tCsrPeStatsReqInfo *pPeStaEntry; + tANI_U8 staId; + vos_timer_t timer; + tANI_BOOLEAN timerExpired; + tpAniSirGlobal pMac; // TODO: Confirm this change BTAMP + tANI_U8 sessionId; +}tCsrStatsClientReqInfo; + +typedef struct tagCsrTlStatsReqInfo +{ + tANI_U32 periodicity; + tANI_BOOLEAN timerRunning; + vos_timer_t hTlStatsTimer; + tANI_U8 numClient; +}tCsrTlStatsReqInfo; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +typedef enum +{ + + /* reassociation is done but couldn't finish security handshake */ + eSIR_ROAM_AUTH_STATUS_CONNECTED = 1, + + /* roam successfully completed by firmware */ + eSIR_ROAM_AUTH_STATUS_AUTHENTICATED = 2, + + /* unknown error */ + eSIR_ROAM_AUTH_STATUS_UNKNOWN = 0xff + +} tCsrRoamOffloadAuthStatus; +typedef struct tagCsrRoamOffloadSynchStruct +{ + tANI_U8 roamedVdevId; /* vdevId after roaming */ + tANI_S8 txMgmtPower; /* HAL fills in the tx power used for */ + tANI_U8 rssi; /* RSSI */ + tANI_U8 roamReason; /* Roam reason */ + tANI_U8 nss; /* no of spatial streams */ + tANI_U16 chainMask; /* chainmask */ + tANI_U16 smpsMode; /* smps.mode */ + tSirMacAddr bssid; /* MAC address of roamed AP */ + tANI_BOOLEAN bRoamSynchInProgress; /* a roam offload synch*/ + tCsrRoamOffloadAuthStatus authStatus; /* authentication + status */ + tANI_U8 kck[SIR_KCK_KEY_LEN]; + tANI_U8 kek[SIR_KEK_KEY_LEN]; + tANI_U8 replay_ctr[SIR_REPLAY_CTR_LEN]; + tpSirBssDescription pbssDescription; /*BSS descriptor*/ +} tCsrRoamOffloadSynchStruct; +#endif + +typedef struct tagCsrRoamSession +{ + tANI_U8 sessionId; // Session ID + tANI_BOOLEAN sessionActive; // TRUE if it is used + tCsrBssid selfMacAddr; // For BT-AMP station, this serve as BSSID for self-BSS. + csrRoamCompleteCallback callback; + void *pContext; + eCsrConnectState connectState; + tCsrRoamConnectedProfile connectedProfile; + tCsrRoamConnectedInfo connectedInfo; + tCsrRoamProfile *pCurRoamProfile; + tSirBssDescription *pConnectBssDesc; + tANI_U16 NumPmkidCache; + tPmkidCacheInfo PmkidCacheInfo[CSR_MAX_PMKID_ALLOWED]; + tANI_U8 cJoinAttemps; + //This may or may not have the up-to-date valid channel list + //It is used to get WNI_CFG_VALID_CHANNEL_LIST and not allocate memory all the time + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_S32 sPendingCommands; //0 means CSR is ok to low power +#ifdef FEATURE_WLAN_WAPI + tANI_U16 NumBkidCache; + tBkidCacheInfo BkidCacheInfo[CSR_MAX_BKID_ALLOWED]; +#endif /* FEATURE_WLAN_WAPI */ + tANI_BOOLEAN fRoaming; //indicate whether CSR is roaming (either via lostlink or dynamic roaming) + //to remember some parameters needed for START_BSS. + //All member must be set every time we try to join or start an IBSS or BT-AMP + tCsrRoamStartBssParams bssParams; + tANI_U32 nWpaRsnReqIeLength; //the byte count of pWpaRsnIE; + tANI_U8 *pWpaRsnReqIE; //this contain the WPA/RSN IE in assoc request or the one sent in beacon (IBSS) + tANI_U32 nWpaRsnRspIeLength; //the byte count for pWpaRsnRspIE + tANI_U8 *pWpaRsnRspIE; //this contain the WPA/RSN IE in beacon/probe rsp +#ifdef FEATURE_WLAN_WAPI + tANI_U32 nWapiReqIeLength; //the byte count of pWapiReqIE; + tANI_U8 *pWapiReqIE; //this contain the WAPI IE in assoc request or the one sent in beacon (IBSS) + tANI_U32 nWapiRspIeLength; //the byte count for pWapiRspIE + tANI_U8 *pWapiRspIE; //this contain the WAPI IE in beacon/probe rsp +#endif /* FEATURE_WLAN_WAPI */ + tANI_U32 nAddIEScanLength; //the byte count of pAddIeScanIE; + tANI_U8 *pAddIEScan; //this contains the additional IE in (unicast) probe request at the time of join + tANI_U32 nAddIEAssocLength; //the byte count for pAddIeAssocIE + tANI_U8 *pAddIEAssoc; //this contains the additional IE in (re) assoc request + + tANI_TIMESTAMP roamingStartTime; //in units of 10ms + tCsrTimerInfo roamingTimerInfo; + eCsrRoamingReason roamingReason; + tANI_BOOLEAN fCancelRoaming; + vos_timer_t hTimerRoaming; + eCsrRoamResult roamResult; //the roamResult that is used when the roaming timer fires + tCsrRoamJoinStatus joinFailStatusCode; //This is the reason code for join(assoc) failure + //The status code returned from PE for deauth or disassoc (in case of lostlink), or our own dynamic roaming + tANI_U32 roamingStatusCode; + tANI_U16 NumPmkidCandidate; + tPmkidCandidateInfo PmkidCandidateInfo[CSR_MAX_PMKID_ALLOWED]; + #ifdef FEATURE_WLAN_WAPI + tANI_U16 NumBkidCandidate; + tBkidCandidateInfo BkidCandidateInfo[CSR_MAX_BKID_ALLOWED]; +#endif + tANI_BOOLEAN fWMMConnection; + tANI_BOOLEAN fQOSConnection; + +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //To retry a join later when it fails if so desired + vos_timer_t hTimerJoinRetry; + tCsrTimerInfo joinRetryTimerInfo; + tANI_U32 maxRetryCount; +#endif +#ifdef FEATURE_WLAN_ESE + tCsrEseCckmInfo eseCckmInfo; + tANI_BOOLEAN isPrevApInfoValid; + tSirMacSSid prevApSSID; + tCsrBssid prevApBssid; + tANI_U8 prevOpChannel; + tANI_U16 clientDissSecs; + tANI_U32 roamTS1; +#if defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrEseCckmIe suppCckmIeInfo; +#endif +#endif + tANI_U8 bRefAssocStartCnt; //Tracking assoc start indication + //ht config + tSirHTConfig htConfig; +#ifdef FEATURE_WLAN_SCAN_PNO + tANI_BOOLEAN pnoStarted; +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tCsrRoamOffloadSynchStruct roamOffloadSynchParams; + tANI_U8 psk_pmk[SIR_ROAM_SCAN_PSK_SIZE]; + size_t pmk_len; + tANI_U8 RoamKeyMgmtOffloadEnabled; +#endif + + /* SME FT Context */ +#if defined WLAN_FEATURE_VOWIFI_11R + tftSMEContext ftSmeContext; +#endif + uint8_t join_bssid_count; /* This count represents the number of + * bssid's we are trying to join. + */ +} tCsrRoamSession; + +typedef struct tagCsrRoamStruct +{ + tANI_U32 nextRoamId; + tDblLinkList roamCmdPendingList; + tDblLinkList channelList5G; + tDblLinkList channelList24; + tCsrConfig configParam; + tANI_U32 numChannelsEeprom; //total channels of eeprom + tCsrChannel base20MHzChannels; //The channel base to work on + tCsrChannel base40MHzChannels; //center channels for 40MHz channels + eCsrRoamState curState[CSR_ROAM_SESSION_MAX]; + eCsrRoamSubState curSubState[CSR_ROAM_SESSION_MAX]; + //This may or may not have the up-to-date valid channel list + //It is used to get WNI_CFG_VALID_CHANNEL_LIST and not allocate memory all the time + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U32 numValidChannels; //total number of channels in CFG + + tANI_S32 sPendingCommands; + vos_timer_t hTimerWaitForKey; //To support timeout for WaitForKey state + tCsrSummaryStatsInfo summaryStatsInfo; + tCsrGlobalClassAStatsInfo classAStatsInfo; + tCsrGlobalClassBStatsInfo classBStatsInfo; + tCsrGlobalClassCStatsInfo classCStatsInfo; + tCsrGlobalClassDStatsInfo classDStatsInfo; + tCsrPerStaStatsInfo perStaStatsInfo[CSR_MAX_STA]; + tDblLinkList statsClientReqList; + tDblLinkList peStatsReqList; + tCsrTlStatsReqInfo tlStatsReqInfo; + eCsrRoamLinkQualityInd vccLinkQuality; + tCsrLinkQualityIndInfo linkQualityIndInfo; + v_CONTEXT_t gVosContext; //used for interaction with TL + v_U8_t ucACWeights[WLANTL_MAX_AC]; + /* TODO : Upto here */ + tCsrTimerInfo WaitForKeyTimerInfo; + tCsrRoamSession *roamSession; + tANI_U32 transactionId; // Current transaction ID for internal use. +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamControlInfo neighborRoamInfo[CSR_ROAM_SESSION_MAX]; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 RoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + tANI_U32 deauthRspStatus; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 *pReassocResp; /* reassociation response from new AP */ + tANI_U16 reassocRespLen; /* length of reassociation response */ +#endif +}tCsrRoamStruct; + + +#define GET_NEXT_ROAM_ID(pRoamStruct) (((pRoamStruct)->nextRoamId + 1 == 0) ? 1 : (pRoamStruct)->nextRoamId) +#define CSR_IS_ROAM_STATE(pMac, state, sessionId) ( (state) == (pMac)->roam.curState[sessionId] ) + +#define CSR_IS_ROAM_STOP(pMac, sessionId) CSR_IS_ROAM_STATE( (pMac), eCSR_ROAMING_STATE_STOP, sessionId ) +#define CSR_IS_ROAM_INIT(pMac, sessionId) CSR_IS_ROAM_STATE( (pMac), eCSR_ROAMING_STATE_INIT, sessionId ) +#define CSR_IS_ROAM_SCANNING(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_SCANNING, sessionId ) +#define CSR_IS_ROAM_JOINING(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ) +#define CSR_IS_ROAM_IDLE(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ) +#define CSR_IS_ROAM_JOINED(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ) + +#define CSR_IS_ROAM_SUBSTATE(pMac, subState, sessionId) ((subState) == (pMac)->roam.curSubState[sessionId]) +#define CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_AUTH_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_AUTH_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, sessionId) +#define CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_FORCED, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DEAUTH_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, sessionId) +#define CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_CONFIG, sessionId) +#define CSR_IS_ROAM_SUBSTATE_WAITFORKEY(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_NT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_NRT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_RT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC, sessionId) + +#define CSR_IS_PHY_MODE_B_ONLY(pMac) \ + ((eCSR_DOT11_MODE_11b == (pMac)->roam.configParam.phyMode) ||\ + (eCSR_DOT11_MODE_11b_ONLY == (pMac)->roam.configParam.phyMode)) + +#define CSR_IS_PHY_MODE_G_ONLY(pMac) \ + (eCSR_DOT11_MODE_11g == (pMac)->roam.configParam.phyMode || eCSR_DOT11_MODE_11g_ONLY == (pMac)->roam.configParam.phyMode) + +#define CSR_IS_PHY_MODE_A_ONLY(pMac) \ + ((eCSR_DOT11_MODE_11a == (pMac)->roam.configParam.phyMode) ||\ + (eCSR_DOT11_MODE_11a_ONLY == (pMac)->roam.configParam.phyMode)) + +#ifdef WLAN_FEATURE_11AC +#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \ + ((eCSR_DOT11_MODE_abg & (phyMode)) || (eCSR_DOT11_MODE_11n & (phyMode)) || \ + (eCSR_DOT11_MODE_11ac & (phyMode)) || \ + (eCSR_DOT11_MODE_TAURUS & (phyMode)) || \ + (eCSR_DOT11_MODE_AUTO & (phyMode))) +#else +#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \ + ((eCSR_DOT11_MODE_abg & (phyMode)) || (eCSR_DOT11_MODE_11n & (phyMode)) || \ + (eCSR_DOT11_MODE_TAURUS & (phyMode)) || \ + (eCSR_DOT11_MODE_AUTO & (phyMode))) +#endif + + +// this function returns TRUE if the NIC is operating exclusively in the 2.4 GHz band, meaning +// it is NOT operating in the 5.0 GHz band. +#define CSR_IS_24_BAND_ONLY(pMac) \ + (eCSR_BAND_24 == (pMac)->roam.configParam.eBand) + +#define CSR_IS_5G_BAND_ONLY(pMac) \ + (eCSR_BAND_5G == (pMac)->roam.configParam.eBand) + +#define CSR_IS_RADIO_DUAL_BAND(pMac) \ + (eCSR_BAND_ALL == (pMac)->roam.configParam.bandCapability) + +#define CSR_IS_RADIO_BG_ONLY(pMac) \ + (eCSR_BAND_24 == (pMac)->roam.configParam.bandCapability) + +// this function returns TRUE if the NIC is operating exclusively in the 5.0 GHz band, meaning +// it is NOT operating in the 2.4 GHz band +#define CSR_IS_RADIO_A_ONLY(pMac) \ + (eCSR_BAND_5G == (pMac)->roam.configParam.bandCapability) + +// this function returns TRUE if the NIC is operating in both bands. +#define CSR_IS_OPEARTING_DUAL_BAND(pMac) \ + ((eCSR_BAND_ALL == (pMac)->roam.configParam.bandCapability) && (eCSR_BAND_ALL == (pMac)->roam.configParam.eBand)) + +// this function returns TRUE if the NIC can operate in the 5.0 GHz band (could operate in the +// 2.4 GHz band also). +#define CSR_IS_OPERATING_A_BAND(pMac) \ + (CSR_IS_OPEARTING_DUAL_BAND((pMac)) || CSR_IS_RADIO_A_ONLY((pMac)) || CSR_IS_5G_BAND_ONLY((pMac))) + +// this function returns TRUE if the NIC can operate in the 2.4 GHz band (could operate in the +// 5.0 GHz band also). +#define CSR_IS_OPERATING_BG_BAND(pMac) \ + (CSR_IS_OPEARTING_DUAL_BAND((pMac)) || CSR_IS_RADIO_BG_ONLY((pMac)) || CSR_IS_24_BAND_ONLY((pMac))) + +#define CSR_IS_CHANNEL_5GHZ(chnNum) \ + (((chnNum) >= CSR_MIN_5GHz_CHANNEL_NUMBER) && ((chnNum) <= CSR_MAX_5GHz_CHANNEL_NUMBER)) + +#define CSR_IS_CHANNEL_DFS(chnNum) \ + (NV_CHANNEL_ENABLE != vos_nv_getChannelEnabledState(chnNum)) + +#define CSR_IS_CHANNEL_24GHZ(chnNum) \ + (((chnNum) > 0) && ((chnNum) <= CSR_MAX_24GHz_CHANNEL_NUMBER)) + +#define CSR_IS_SAME_BAND_CHANNELS(ch1, ch2) (CSR_IS_CHANNEL_5GHZ(ch1) == CSR_IS_CHANNEL_5GHZ(ch2)) + + +#define CSR_IS_11D_INFO_FOUND(pMac) \ + (0 != (pMac)->scan.channelOf11dInfo) +// DEAUTHIND +#define CSR_IS_ROAMING(pSession) ((CSR_IS_LOSTLINK_ROAMING((pSession)->roamingReason)) || \ + (eCsrDynamicRoaming == (pSession)->roamingReason) || \ + (eCsrReassocRoaming == (pSession)->roamingReason)) + + +#define CSR_IS_SET_KEY_COMMAND( pCommand ) ( eSmeCommandSetKey == (pCommand)->command ) + +#define CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) (pMac->roam.configParam.addTSWhenACMIsOff) +// DEAUTHIND +#define CSR_IS_LOSTLINK_ROAMING(reason) ((eCsrLostlinkRoamingDisassoc == (reason)) || (eCsrLostlinkRoamingDeauth == (reason))) + +#define CSR_IS_ROAMING_COMMAND(pCommand) ((eCsrLostLink1 == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrLostLink2 == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrLostLink3 == (pCommand)->u.roamCmd.roamReason) ) + + +//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR +void csrScanSuspendIMPS( tpAniSirGlobal pMac ); +//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS +//because IMPS maybe disabled. +void csrScanResumeIMPS( tpAniSirGlobal pMac ); + +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac); +eHalStatus csrScanFilter11dResult(tpAniSirGlobal pMac); + +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac); + +eHalStatus csrSetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields); +/* --------------------------------------------------------------------------- + \fn csrGetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields); +void csrSetGlobalCfgs( tpAniSirGlobal pMac ); +void csrSetDefaultDot11Mode( tpAniSirGlobal pMac ); +void csrScanSetChannelMask(tpAniSirGlobal pMac, tCsrChannelInfo *pChannelInfo); +tANI_BOOLEAN csrIsConnStateDisconnected(tpAniSirGlobal pMac, tANI_U32 sessionId); +tANI_BOOLEAN csrIsConnStateConnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateDisconnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnectedInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnected( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateDisconnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsAnySessionInConnectState( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsAllSessionDisconnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsStaSessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsP2pSessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsAnySessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsInfraConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsConcurrentInfraConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsConcurrentSessionRunning( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsInfraApStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsIBSSStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsBTAMPStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsBTAMP( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrIsBTAMPAllowed( tpAniSirGlobal pMac, tANI_U32 chnId ); +tANI_BOOLEAN csrIsValidMcConcurrentSession(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc); +tANI_BOOLEAN csrIsConnStateConnectedInfraAp( tpAniSirGlobal pMac, tANI_U32 sessionId ); +/*---------------------------------------------------------------------------- + \fn csrRoamRegisterLinkQualityIndCallback + + \brief + a CSR function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus csrRoamRegisterLinkQualityIndCallback(tpAniSirGlobal pMac, + csrRoamLinkQualityIndCallback callback, + void *pContext); +/* --------------------------------------------------------------------------- + \fn csrGetStatistics + \brief csr function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update, 0 means it's an one + time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param sessionId - sme session Id. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrGetTLSTAState + \helper function to get the TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 csrGetTLSTAState(tpAniSirGlobal pMac, tANI_U8 staId); + +/* --------------------------------------------------------------------------- + \fn csrGetRssi + \ creates SME req packet for getRSSI and post to Self + + \param pMac - global MAC context + \param callback - hdd callback function to be called once FW returns the + RSSI value + \param staId - The staID to be passed to the TL to get the relevant + TL STA State + \param bssID - bssid for which RSSI is requested + \param lastRSSI - RSSI value at time of request. In case request cannot + be sent to firmware, do not hold up but return this value. + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos conext + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +eHalStatus csrGetRssi(tpAniSirGlobal pMac,tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, tANI_S8 lastRSSI, + void * pContext,void * pVosContext); + +/* --------------------------------------------------------------------------- + \fn csrGetSnr + \brief csr function that client calls to register a callback to get + SNR stored in TL + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid for the connected session + \param pContext - user context to be passed back along with the callback + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrGetSnr(tpAniSirGlobal pMac, tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void * pContext, + void * pVosContext); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrGetTsmStats(tpAniSirGlobal pMac, + tCsrTsmStatsCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void *pContext, + void* pVosContext, + tANI_U8 tid); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* --------------------------------------------------------------------------- + \fn csrGetConfigParam + \brief HDD calls this function to get the global settings currently maintained by CSR. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam); + +/* --------------------------------------------------------------------------- + \fn csrMsgProcessor + \brief HDD calls this function to change some global settings. + caller must set the all fields or call csrGetConfigParam to prefill the fields. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam); + + +/* --------------------------------------------------------------------------- + \fn csrMsgProcessor + \brief HDD calls this function for the messages that are handled by CSR. + \param pMsgBuf - a pointer to a buffer that maps to various structures base on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); + +/* --------------------------------------------------------------------------- + \fn csrOpen + \brief This function must be called before any API call to CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrOpen(tpAniSirGlobal pMac); +/* --------------------------------------------------------------------------- + \fn csr_init_chan_list + \brief This function needs to called to initialize channel information, + which, for discrete, will come from targer fw. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csr_init_chan_list(tpAniSirGlobal mac, v_U8_t *alpha2); + +/* --------------------------------------------------------------------------- + \fn csrClose + \brief To close down CSR module. There should not be any API call into CSR after calling this function. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrClose(tpAniSirGlobal pMac); +/* --------------------------------------------------------------------------- + \fn csrStart + \brief To start CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrStart(tpAniSirGlobal pMac); +/* --------------------------------------------------------------------------- + \fn csrStop + \brief To stop CSR. CSR still keeps its current setting. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrStop(tpAniSirGlobal pMac, tHalStopType stopType); +/* --------------------------------------------------------------------------- + \fn csrReady + \brief To let CSR is ready to operate + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrReady(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_WAPI + +eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems ); +/* --------------------------------------------------------------------------- + \fn csrRoamGetWapiReqIE + \brief return the WAPI IE CSR passes to PE to JOIN request or START_BSS request + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWapiReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWapiRspIE + \brief return the WAPI IE from the beacon or probe rsp if connected + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWapiRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); +tANI_U8 csrConstructWapiIe( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ); +#endif /* FEATURE_WLAN_WAPI */ + +eHalStatus csrRoamUpdateAPWPSIE( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirAPWPSIEs *pAPWPSIES ); +eHalStatus csrRoamUpdateWPARSNIEs( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirRSNie * pAPSirRSNie); +void csrSetCfgPrivacy( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy ); +tANI_S8 csrGetInfraSessionId( tpAniSirGlobal pMac ); +tANI_U8 csrGetInfraOperationChannel( tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_BOOLEAN csrIsSessionClientAndConnected(tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_U8 csrGetConcurrentOperationChannel( tpAniSirGlobal pMac ); + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +v_U16_t csrCheckConcurrentChannelOverlap(tpAniSirGlobal pMac, v_U16_t sap_ch, + eCsrPhyMode sap_phymode, v_U8_t cc_switch_mode ); +#endif +eHalStatus csrRoamCopyConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamConnectedProfile *pProfile); +tANI_BOOLEAN csrIsSetKeyAllowed(tpAniSirGlobal pMac, tANI_U32 sessionId); + +void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac ); +void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList, + tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels ); +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd); +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +//Returns whether the current association is a 11r assoc or not +tANI_BOOLEAN csrRoamIs11rAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId); +#endif + +#ifdef FEATURE_WLAN_ESE +//Returns whether the current association is a ESE assoc or not +tANI_BOOLEAN csrRoamIsESEAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_BOOLEAN csrRoamIsEseIniFeatureEnabled(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamIsESEAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId); +#endif + +//Remove this code once SLM_Sessionization is supported +//BMPS_WORKAROUND_NOT_NEEDED +void csrDisconnectAllActiveSessions(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_LFR +//Returns whether "Legacy Fast Roaming" is enabled...or not +tANI_BOOLEAN csrRoamIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U32 sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +tANI_BOOLEAN csrRoamIsRoamOffloadScanEnabled(tpAniSirGlobal pMac); +#endif +tANI_BOOLEAN csrIsChannelPresentInList( tANI_U8 *pChannelList, int numChannels, tANI_U8 channel ); +VOS_STATUS csrAddToChannelListFront( tANI_U8 *pChannelList, int numChannels, tANI_U8 channel ); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId, + csrScanCompleteCallback callback, void *pContext); +eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, + tpSirRoamOffloadScanRsp scanOffloadRsp); +eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, + tCsrHandoffRequest *pHandoffInfo); +#endif +tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif + + +/* Post Channel Change Indication */ +eHalStatus csrRoamChannelChangeReq(tpAniSirGlobal pMac, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 cbMode); + +/* Post Beacon Tx Start Indication */ +eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, + tCsrBssid bssid, tANI_U8 dfsCacWaitStatus); + +eHalStatus +csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 csaIeReqd); + +/*---------------------------------------------------------------------------- + \fn csrRoamModifyAddIEs + \brief This function sends msg to modify the additional IE buffers in PE + \param pMac - pMac global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - Type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamModifyAddIEs(tpAniSirGlobal pMac, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType); + + +/*---------------------------------------------------------------------------- + \fn csrRoamUpdateAddIEs + \brief This function sends msg to updates the additional IE buffers in PE + \param pMac - pMac global structure + \param pUpdateIE - pointer to tSirUpdateIE structure + \param updateType, - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamUpdateAddIEs(tpAniSirGlobal pMac, + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +void csrProcessRoamOffloadSynchInd(tHalHandle hHal, + tpSirRoamOffloadSynchInd pSmeRoamOffloadSynchInd); +eHalStatus csrScanSaveRoamOffloadApToScanCache(tpAniSirGlobal pMac, + tSirRoamOffloadSynchInd *pRoamOffloadSynchInd); +void csrProcessHOFailInd(tpAniSirGlobal pMac, void *pMsgBuf); +#endif +#endif + diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/csrLinkList.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrLinkList.h new file mode 100644 index 0000000000000..ed647bbc39d40 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrLinkList.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrLinkList.h + + Exports and types for the Common link list interfaces. +========================================================================== */ +#ifndef CSR_LINK_LIST_H__ +#define CSR_LINK_LIST_H__ + +#include "vos_lock.h" + + +#define LL_ACCESS_LOCK eANI_BOOLEAN_TRUE +#define LL_ACCESS_NOLOCK eANI_BOOLEAN_FALSE + +typedef struct tagListElem +{ + struct tagListElem *last; + struct tagListElem *next; +}tListElem; + +typedef enum +{ + LIST_FLAG_CLOSE = 0, + LIST_FLAG_OPEN = 0xa1b2c4d7, +}tListFlag; + +//This is a circular double link list +typedef struct tagDblLinkList +{ + tListElem ListHead; + vos_lock_t Lock; + tANI_U32 Count; + tHddHandle hHdd; + tListFlag Flag; + + /*command debugging */ + tANI_U32 cmdTimeoutDuration; /* command timeout duration */ + vos_timer_t *cmdTimeoutTimer; /*command timeout Timer */ +}tDblLinkList; + +//To get the address of an object of (type) base on the (address) of one of its (field) +#define GET_BASE_ADDR(address, type, field) ((type *)( \ + (tANI_U8 *)(address) - \ + (tANI_U8 *)(&((type *)0)->field))) + +//To get the offset of (field) inside structure (type) +#define GET_FIELD_OFFSET(type, field) ((uintptr_t)(&(((type *)0)->field))) + +#define GET_ROUND_UP( _Field, _Boundary ) (((_Field) + ((_Boundary) - 1)) & ~((_Boundary) - 1)) +#define BITS_ON( _Field, _Bitmask ) ( (_Field) |= (_Bitmask) ) +#define BITS_OFF( _Field, _Bitmask ) ( (_Field) &= ~(_Bitmask) ) + +#define CSR_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define CSR_MIN(a, b) ((a) < (b) ? (a) : (b)) + + +#define csrIsListEmpty(pHead) ((pHead)->next == (pHead)) + +tANI_U32 csrLLCount( tDblLinkList *pList ); + +eHalStatus csrLLOpen( tHddHandle hHdd, tDblLinkList *pList ); +void csrLLClose( tDblLinkList *pList ); + +void csrLLLock( tDblLinkList *pList ); +void csrLLUnlock( tDblLinkList *pList ); + +tANI_BOOLEAN csrLLIsListEmpty( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +void csrLLInsertHead( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); +void csrLLInsertTail( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); +//This function put pNewEntry before pEntry. Caller should have found pEntry +void csrLLInsertEntry( tDblLinkList *pList, tListElem *pEntry, tListElem *pNewEntry, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLPeekHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tListElem *csrLLPeekTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLRemoveHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tListElem *csrLLRemoveTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tANI_BOOLEAN csrLLRemoveEntry( tDblLinkList *pList, tListElem *pEntryToRemove, tANI_BOOLEAN fInterlocked ); +void csrLLPurge( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +//csrLLNext return NULL if reaching the end or list is empty +tListElem *csrLLNext( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLPrevious( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); + +tANI_BOOLEAN csrLLFindEntry( tDblLinkList *pList, tListElem *pEntryToFind ); + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/csrNeighborRoam.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrNeighborRoam.h new file mode 100644 index 0000000000000..ed999d820a498 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrNeighborRoam.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrNeighborRoam.h + + Exports and types for the neighbor roaming algorithm which is sepcifically + designed for Android. +========================================================================== */ +#ifndef CSR_NEIGHBOR_ROAM_H +#define CSR_NEIGHBOR_ROAM_H + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "sme_Api.h" + +#define ROAM_AP_AGE_LIMIT_MS 10000 + +/* Enumeration of various states in neighbor roam algorithm */ +typedef enum +{ + eCSR_NEIGHBOR_ROAM_STATE_CLOSED, + eCSR_NEIGHBOR_ROAM_STATE_INIT, + eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN, + eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, +#ifdef WLAN_FEATURE_VOWIFI_11R + eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY, + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING, + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, +#endif /* WLAN_FEATURE_VOWIFI_11R */ + eNEIGHBOR_STATE_MAX +} eCsrNeighborRoamState; + +/* Parameters that are obtained from CFG */ +typedef struct sCsrNeighborRoamCfgParams +{ + tANI_U8 maxNeighborRetries; + tANI_U32 neighborScanPeriod; + tCsrChannelInfo channelInfo; + tANI_U8 neighborLookupThreshold; + tANI_U8 neighborReassocThreshold; + tANI_U32 minChannelScanTime; + tANI_U32 maxChannelScanTime; + tANI_U16 neighborResultsRefreshPeriod; + tANI_U16 emptyScanRefreshPeriod; + tANI_U8 nOpportunisticThresholdDiff; + tANI_U8 nRoamRescanRssiDiff; + tANI_U8 nRoamBmissFirstBcnt; + tANI_U8 nRoamBmissFinalBcnt; + tANI_U8 nRoamBeaconRssiWeight; + tANI_U8 delay_before_vdev_stop; +} tCsrNeighborRoamCfgParams, *tpCsrNeighborRoamCfgParams; + +#define CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX 255 +typedef struct sCsrNeighborRoamChannelInfo +{ + tANI_BOOLEAN IAPPNeighborListReceived; // Flag to mark reception of IAPP Neighbor list + tANI_BOOLEAN chanListScanInProgress; + tANI_U8 currentChanIndex; //Current channel index that is being scanned + tCsrChannelInfo currentChannelListInfo; //Max number of channels in channel list and the list of channels +} tCsrNeighborRoamChannelInfo, *tpCsrNeighborRoamChannelInfo; + +typedef struct sCsrNeighborRoamBSSInfo +{ + tListElem List; + tANI_U8 apPreferenceVal; +// tCsrScanResultInfo *scanResultInfo; + tpSirBssDescription pBssDescription; +} tCsrNeighborRoamBSSInfo, *tpCsrNeighborRoamBSSInfo; + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT 1000 //in milliseconds +#define CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER 10 //in milliseconds +#define MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS 10 //Max number of MAC addresses with which the pre-auth was failed +#define MAX_BSS_IN_NEIGHBOR_RPT 15 +#define CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES 3 + +/* Black listed APs. List of MAC Addresses with which the Preauthentication was failed. */ +typedef struct sCsrPreauthFailListInfo +{ + tANI_U8 numMACAddress; + tSirMacAddr macAddress[MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS]; +} tCsrPreauthFailListInfo, *tpCsrPreauthFailListInfo; + +typedef struct sCsrNeighborReportBssInfo +{ + tANI_U8 channelNum; + tANI_U8 neighborScore; + tSirMacAddr neighborBssId; +} tCsrNeighborReportBssInfo, *tpCsrNeighborReportBssInfo; + +typedef struct sCsr11rAssocNeighborInfo +{ + tANI_BOOLEAN preauthRspPending; + tANI_BOOLEAN neighborRptPending; + tANI_U8 currentNeighborRptRetryNum; + tCsrPreauthFailListInfo preAuthFailList; + tANI_U32 neighborReportTimeout; + tANI_U32 PEPreauthRespTimeout; + tANI_U8 numPreAuthRetries; + tDblLinkList preAuthDoneList; /* Linked list which consists or preauthenticated nodes */ + tANI_U8 numBssFromNeighborReport; + tCsrNeighborReportBssInfo neighboReportBssInfo[MAX_BSS_IN_NEIGHBOR_RPT]; //Contains info needed during REPORT_SCAN State +} tCsr11rAssocNeighborInfo, *tpCsr11rAssocNeighborInfo; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* + * Set lookup UP threshold 5 dB higher than the configured + * lookup DOWN threshold to minimize thrashing between + * DOWN and UP events. + */ +#define NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD \ + (pNeighborRoamInfo->cfgParams.neighborLookupThreshold-5) +#ifdef FEATURE_WLAN_LFR +typedef enum +{ + eFirstEmptyScan=1, + eSecondEmptyScan, + eThirdEmptyScan, + eFourthEmptyScan, + eFifthEmptyScan, + eMaxEmptyScan=eFifthEmptyScan, +} eNeighborRoamEmptyScanCount; + +typedef enum +{ + DEFAULT_SCAN=0, + SPLIT_SCAN_OCCUPIED_LIST=1, +} eNeighborRoamScanMode; +#endif + +/* Complete control information for neighbor roam algorithm */ +typedef struct sCsrNeighborRoamControlInfo +{ + eCsrNeighborRoamState neighborRoamState; + eCsrNeighborRoamState prevNeighborRoamState; + tCsrNeighborRoamCfgParams cfgParams; + tCsrBssid currAPbssid; // current assoc AP + tANI_U8 currAPoperationChannel; // current assoc AP + vos_timer_t neighborScanTimer; + vos_timer_t neighborResultsRefreshTimer; + vos_timer_t emptyScanRefreshTimer; + tCsrTimerInfo neighborScanTimerInfo; + tCsrNeighborRoamChannelInfo roamChannelInfo; + tANI_U8 currentNeighborLookupThreshold; + tANI_U8 currentOpportunisticThresholdDiff; + tANI_U8 currentRoamRescanRssiDiff; + tANI_BOOLEAN scanRspPending; + tANI_TIMESTAMP scanRequestTimeStamp; + tDblLinkList roamableAPList; // List of current FT candidates + tCsrRoamProfile csrNeighborRoamProfile; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_BOOLEAN is11rAssoc; + tCsr11rAssocNeighborInfo FTRoamInfo; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + tANI_BOOLEAN isESEAssoc; + tANI_BOOLEAN isVOAdmitted; + tANI_U32 MinQBssLoadRequired; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 uEmptyScanCount; /* Consecutive number of times scan + yielded no results. */ + tCsrRoamConnectedProfile prevConnProfile; /* Previous connected profile. If the + new profile does not match previous + we re-initialize occupied channel list */ + tANI_S8 lookupDOWNRssi; + tANI_U8 uScanMode; + tANI_U8 uOsRequestedHandoff; /* upper layer requested + a reassoc */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tCsrHandoffRequest handoffReqInfo; /* handoff related info came + with upper layer's req for + reassoc */ +#endif +#endif + tSmeFastRoamTrigger cfgRoamEn; + tSirMacAddr cfgRoambssId; + tANI_U8 currentRoamBmissFirstBcnt; + tANI_U8 currentRoamBmissFinalBcnt; + tANI_U8 currentRoamBeaconRssiWeight; +} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo; + +/* All the necessary Function declarations are here */ +eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId, VOS_STATUS status); +eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, + tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac, + tANI_U8 sessionId); +void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac, tANI_U8 sessionId); +eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac, tANI_U8 sessionId); +void csrNeighborRoamClose(tpAniSirGlobal pMac, tANI_U8 sessionId); +void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac); +VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac, + tANI_U8 sessionId); +VOS_STATUS csrNeighborRoamTransitionToPreauthDone(tpAniSirGlobal pMac); +eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, + tCsrScanResultFilter *pScanFilter, + tANI_U8 sessionId); +void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, + tpCsrNeighborRoamBSSInfo pHandoffNode, + tANI_U8 sessionId); +eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tSirRetStatus limStatus); +#ifdef WLAN_FEATURE_VOWIFI_11R +tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac, + tANI_U8 sessionId); +#endif +VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac, + tANI_U8 sessionId); +void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac, + tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac, + tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamScanRspPending(tHalHandle hHal, + tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborMiddleOfRoaming(tHalHandle hHal, tANI_U8 sessionId); +VOS_STATUS csrNeighborRoamSetLookupRssiThreshold(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t neighborLookupRssiThreshold); +VOS_STATUS +csrNeighborRoamSetOpportunisticScanThresholdDiff(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nOpportunisticThresholdDiff); +VOS_STATUS +csrNeighborRoamSetRoamRescanRssiDiff(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamRescanRssiDiff); +VOS_STATUS +csrNeighborRoamSetRoamBmissFirstBcnt(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBmissFirstBcnt); +VOS_STATUS +csrNeighborRoamSetRoamBmissFinalBcnt(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBmissFinalBcnt); +VOS_STATUS +csrNeighborRoamSetRoamBeaconRssiWeight(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBeaconRssiWeight); +VOS_STATUS csrNeighborRoamUpdateFastRoamingEnabled(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const v_BOOL_t fastRoamEnabled); +VOS_STATUS csrNeighborRoamUpdateEseModeEnabled(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const v_BOOL_t eseMode); +VOS_STATUS csrNeighborRoamChannelsFilterByCurrentBand( + tpAniSirGlobal pMac, + tANI_U8 sessionId, + tANI_U8* pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8* pOutputChannelList, + tANI_U8* pMergedOutputNumOfChannels + ); +VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter, + v_U8_t trafficStatus, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +VOS_STATUS csrNeighborRoamMergeChannelLists(tpAniSirGlobal pMac, + tANI_U8 *pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 outputNumOfChannels, + tANI_U8 *pMergedOutputNumOfChannels); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define ROAM_SCAN_OFFLOAD_START 1 +#define ROAM_SCAN_OFFLOAD_STOP 2 +#define ROAM_SCAN_OFFLOAD_RESTART 3 +#define ROAM_SCAN_OFFLOAD_UPDATE_CFG 4 +#define ROAM_SCAN_OFFLOAD_ABORT_SCAN 5 + +#define REASON_CONNECT 1 +#define REASON_CHANNEL_LIST_CHANGED 2 +#define REASON_LOOKUP_THRESH_CHANGED 3 +#define REASON_DISCONNECTED 4 +#define REASON_RSSI_DIFF_CHANGED 5 +#define REASON_ESE_INI_CFG_CHANGED 6 +#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7 +#define REASON_VALID_CHANNEL_LIST_CHANGED 8 +#define REASON_FLUSH_CHANNEL_LIST 9 +#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED 10 +#define REASON_PREAUTH_FAILED_FOR_ALL 11 +#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW 12 +#define REASON_NPROBES_CHANGED 13 +#define REASON_HOME_AWAY_TIME_CHANGED 14 +#define REASON_OS_REQUESTED_ROAMING_NOW 15 +#define REASON_SCAN_CH_TIME_CHANGED 16 +#define REASON_SCAN_HOME_TIME_CHANGED 17 +#define REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED 18 +#define REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED 19 +#define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED 20 +#define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED 21 +#define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED 22 +#define REASON_ROAM_DFS_SCAN_MODE_CHANGED 23 +#define REASON_ROAM_ABORT_ROAM_SCAN 24 +eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, + tANI_U8 command, tANI_U8 reason); +eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, + void* pMsg); +eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg); +eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac, + tANI_U8 sessionId); +eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eHalStatus status); +eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 sessionId); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, + const tANI_U8 *pCckmIe, + const tANI_U8 ccKmIeLen); +VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, + const tANI_U8 sessionId); +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrRoamOffloadSendSynchCnf(tpAniSirGlobal pMac, tANI_U8 sessionId); +eHalStatus +csrNeighborRoamOffloadUpdatePreauthList(tpAniSirGlobal pMac, + tpSirRoamOffloadSynchInd pSmeRoamOffloadSynchInd, + tANI_U8 sessionId); +#endif +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +#endif /* CSR_NEIGHBOR_ROAM_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/csrSupport.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrSupport.h new file mode 100644 index 0000000000000..9244090baf56c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/csrSupport.h @@ -0,0 +1,816 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrSupport.h + + Exports and types for the Common Scan and Roaming supporting interfaces. +========================================================================== */ +#ifndef CSR_SUPPORT_H__ +#define CSR_SUPPORT_H__ + +#include "csrLinkList.h" +#include "csrApi.h" +#include "vos_nvitem.h" + +#ifdef FEATURE_WLAN_WAPI +#define CSR_WAPI_OUI_SIZE ( 4 ) +#define CSR_WAPI_VERSION_SUPPORTED ( 1 ) +#define CSR_WAPI_MAX_AUTH_SUITES ( 2 ) +#define CSR_WAPI_MAX_CYPHERS ( 5 ) +#define CSR_WAPI_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_WAPI_MAX_MULTICAST_CYPHERS ( 1 ) +#endif /* FEATURE_WLAN_WAPI */ + +#define CSR_RSN_OUI_SIZE ( 4 ) +#define CSR_RSN_VERSION_SUPPORTED ( 1 ) +#define CSR_RSN_MAX_AUTH_SUITES ( 4 ) +#define CSR_RSN_MAX_CYPHERS ( 5 ) +#define CSR_RSN_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_RSN_MAX_MULTICAST_CYPHERS ( 1 ) + +#define CSR_WPA_OUI_SIZE ( 4 ) +#define CSR_WPA_VERSION_SUPPORTED ( 1 ) +#define CSR_WME_OUI_SIZE ( 4 ) +#define CSR_WPA_MAX_AUTH_SUITES ( 2 ) +#define CSR_WPA_MAX_CYPHERS ( 5 ) +#define CSR_WPA_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_WPA_MAX_MULTICAST_CYPHERS ( 1 ) +#define CSR_WPA_IE_MIN_SIZE ( 6 ) // minimum size of the IE->length is the size of the Oui + Version. +#define CSR_WPA_IE_MIN_SIZE_W_MULTICAST ( HDD_WPA_IE_MIN_SIZE + HDD_WPA_OUI_SIZE ) +#define CSR_WPA_IE_MIN_SIZE_W_UNICAST ( HDD_WPA_IE_MIN_SIZE + HDD_WPA_OUI_SIZE + sizeof( pWpaIe->cUnicastCyphers ) ) + +#define CSR_DOT11_SUPPORTED_RATES_MAX ( 12 ) +#define CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ( 8 ) + +#define CSR_DOT11_BASIC_RATE_MASK ( 0x80 ) + +#define CSR_OUI_USE_GROUP_CIPHER_INDEX 0x00 +#define CSR_OUI_WEP40_OR_1X_INDEX 0x01 +#define CSR_OUI_TKIP_OR_PSK_INDEX 0x02 +#define CSR_OUI_RESERVED_INDEX 0x03 +#define CSR_OUI_AES_INDEX 0x04 +#define CSR_OUI_WEP104_INDEX 0x05 + +#ifdef FEATURE_WLAN_WAPI +#define CSR_OUI_WAPI_RESERVED_INDEX 0x00 +#define CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX 0x01 +#define CSR_OUI_WAPI_WAI_PSK_INDEX 0x02 +#define CSR_OUI_WAPI_WAI_MAX_INDEX 0x03 // max index, should be last & highest +#endif /* FEATURE_WLAN_WAPI */ + + +typedef enum +{ + // 11b rates + eCsrSuppRate_1Mbps = 1 * 2, + eCsrSuppRate_2Mbps = 2 * 2, + eCsrSuppRate_5_5Mbps = 11, // 5.5 * 2 + eCsrSuppRate_11Mbps = 11 * 2, + + // 11a / 11g rates + eCsrSuppRate_6Mbps = 6 * 2, + eCsrSuppRate_9Mbps = 9 * 2, + eCsrSuppRate_12Mbps = 12 * 2, + eCsrSuppRate_18Mbps = 18 * 2, + eCsrSuppRate_24Mbps = 24 * 2, + eCsrSuppRate_36Mbps = 36 * 2, + eCsrSuppRate_48Mbps = 48 * 2, + eCsrSuppRate_54Mbps = 54 * 2, + + // airgo proprietary rates + eCsrSuppRate_10Mbps = 10 * 2, + eCsrSuppRate_10_5Mbps= 21, // 10.5 * 2 + eCsrSuppRate_20Mbps = 20 * 2, + eCsrSuppRate_21Mbps = 21 * 2, + eCsrSuppRate_40Mbps = 40 * 2, + eCsrSuppRate_42Mbps = 42 * 2, + eCsrSuppRate_60Mbps = 60 * 2, + eCsrSuppRate_63Mbps = 63 * 2, + eCsrSuppRate_72Mbps = 72 * 2, + eCsrSuppRate_80Mbps = 80 * 2, + eCsrSuppRate_84Mbps = 84 * 2, + eCsrSuppRate_96Mbps = 96 * 2, + eCsrSuppRate_108Mbps = 108 * 2, + eCsrSuppRate_120Mbps = 120 * 2, + eCsrSuppRate_126Mbps = 126 * 2, + eCsrSuppRate_144Mbps = 144 * 2, + eCsrSuppRate_160Mbps = 160 * 2, + eCsrSuppRate_168Mbps = 168 * 2, + eCsrSuppRate_192Mbps = 192 * 2, + eCsrSuppRate_216Mbps = 216 * 2, + eCsrSuppRate_240Mbps = 240 * 2 +}eCsrSupportedRates; + +typedef enum +{ + eCsrPassiveScanNot, //can be scanned actively on the whole 5GHz band + eCsrPassiveScanCat1, //always passive scan from 5250 to 5350MHz + eCsrPassiveScanCat2, //always passive scan from 5250 to 5350MHz, and from 5470 to 5725MHz + eCsrPassiveScanCat3, //always passive scan from 5250 to 5350MHz, from 5470 to 5725MHz, and from 5500 to 5560MHz +}eCsrPassiveScanCat; + + +//Please donot insert in the middle of the enum here because they tie to the indiex +typedef enum +{ + eCSR_COUNTRY_INDEX_US = 0, //Always set US as index 0 + eCSR_COUNTRY_INDEX_ANDORRA, + eCSR_COUNTRY_INDEX_UAE, //United Arab Emirates + eCSR_COUNTRY_INDEX_AFGHANISTAN, + eCSR_COUNTRY_INDEX_ANTIGUA_AND_BARBUDA, + eCSR_COUNTRY_INDEX_ANGUILLA, + eCSR_COUNTRY_INDEX_ALBANIA, + eCSR_COUNTRY_INDEX_ARMENIA, + eCSR_COUNTRY_INDEX_NETHERLANDS_ANTILLES, + eCSR_COUNTRY_INDEX_ANGOLA, + eCSR_COUNTRY_INDEX_ANTARCTICA, + eCSR_COUNTRY_INDEX_ARGENTINA, + eCSR_COUNTRY_INDEX_AMERICAN_SAMOA, + eCSR_COUNTRY_INDEX_AUSTRIA, + eCSR_COUNTRY_INDEX_AUSTRALIA, + eCSR_COUNTRY_INDEX_ARUBA, + eCSR_COUNTRY_INDEX_ALAND_ISLANDS, + eCSR_COUNTRY_INDEX_AZERBAIJAN, + eCSR_COUNTRY_INDEX_BOSNIA_AND_HERZEGOVINA, + eCSR_COUNTRY_INDEX_BARBADOS, + eCSR_COUNTRY_INDEX_BANGLADESH, + eCSR_COUNTRY_INDEX_BELGIUM, + eCSR_COUNTRY_INDEX_BURKINA_FASO, + eCSR_COUNTRY_INDEX_BULGARIA, + eCSR_COUNTRY_INDEX_BAHRAIN, + eCSR_COUNTRY_INDEX_BURUNDI, + eCSR_COUNTRY_INDEX_BENIN, + eCSR_COUNTRY_INDEX_SAINT_BARTHELEMY, + eCSR_COUNTRY_INDEX_BERMUDA, + eCSR_COUNTRY_INDEX_BRUNEI_DARUSSALAM, + eCSR_COUNTRY_INDEX_BOLVIA, + eCSR_COUNTRY_INDEX_BRAZIL, + eCSR_COUNTRY_INDEX_BAHAMAS, + eCSR_COUNTRY_INDEX_BHUTAN, + eCSR_COUNTRY_INDEX_BOUVET_ISLAND, + eCSR_COUNTRY_INDEX_BOTSWANA, + eCSR_COUNTRY_INDEX_BELARUS, + eCSR_COUNTRY_INDEX_BELIZE, + eCSR_COUNTRY_INDEX_CANADA, + eCSR_COUNTRY_INDEX_COCOS_KEELING_ISLANDS, + eCSR_COUNTRY_INDEX_CONGO_REP, + eCSR_COUNTRY_INDEX_CENTRAL_AFRICAN, + eCSR_COUNTRY_INDEX_CONGO, + eCSR_COUNTRY_INDEX_SWITZERLAND, + eCSR_COUNTRY_INDEX_COTE_DIVOIRE, + eCSR_COUNTRY_INDEX_COOK_ISLANDS, + eCSR_COUNTRY_INDEX_CHILE, + eCSR_COUNTRY_INDEX_CAMEROON, + eCSR_COUNTRY_INDEX_CHINA, + eCSR_COUNTRY_INDEX_COLUMBIA, + eCSR_COUNTRY_INDEX_COSTA_RICA, + eCSR_COUNTRY_INDEX_CUBA, + eCSR_COUNTRY_INDEX_CAPE_VERDE, + eCSR_COUNTRY_INDEX_CHRISTMAS_ISLAND, + eCSR_COUNTRY_INDEX_CYPRUS, + eCSR_COUNTRY_INDEX_CZECH, + eCSR_COUNTRY_INDEX_GERMANY, + eCSR_COUNTRY_INDEX_DJIBOUTI, + eCSR_COUNTRY_INDEX_DENMARK, + eCSR_COUNTRY_INDEX_DOMINICA, + eCSR_COUNTRY_INDEX_DOMINICAN_REP, + eCSR_COUNTRY_INDEX_ALGERIA, + eCSR_COUNTRY_INDEX_ECUADOR, + eCSR_COUNTRY_INDEX_ESTONIA, + eCSR_COUNTRY_INDEX_EGYPT, + eCSR_COUNTRY_INDEX_WESTERN_SAHARA, + eCSR_COUNTRY_INDEX_ERITREA, + eCSR_COUNTRY_INDEX_SPAIN, + eCSR_COUNTRY_INDEX_ETHIOPIA, + eCSR_COUNTRY_INDEX_FINLAND, + eCSR_COUNTRY_INDEX_FIJI, + eCSR_COUNTRY_INDEX_FALKLAND_ISLANDS, + eCSR_COUNTRY_INDEX_MICRONESIA, + eCSR_COUNTRY_INDEX_FAROE_ISLANDS, + eCSR_COUNTRY_INDEX_FRANCE, + eCSR_COUNTRY_INDEX_GABON, + eCSR_COUNTRY_INDEX_UNITED_KINGDOM, + eCSR_COUNTRY_INDEX_GRENADA, + eCSR_COUNTRY_INDEX_GEORGIA, + eCSR_COUNTRY_INDEX_FRENCH_GUIANA, + eCSR_COUNTRY_INDEX_GUERNSEY, + eCSR_COUNTRY_INDEX_GHANA, + eCSR_COUNTRY_INDEX_GIBRALTAR, + eCSR_COUNTRY_INDEX_GREENLAND, + eCSR_COUNTRY_INDEX_GAMBIA, + eCSR_COUNTRY_INDEX_GUINEA, + eCSR_COUNTRY_INDEX_GUADELOUPE, + eCSR_COUNTRY_INDEX_EQUATORIAL_GUINEA, + eCSR_COUNTRY_INDEX_GREECE, + eCSR_COUNTRY_INDEX_SOUTH_GEORGIA, + eCSR_COUNTRY_INDEX_GUATEMALA, + eCSR_COUNTRY_INDEX_GUAM, + eCSR_COUNTRY_INDEX_GUINEA_BISSAU, + eCSR_COUNTRY_INDEX_GUYANA, + eCSR_COUNTRY_INDEX_HONGKONG, + eCSR_COUNTRY_INDEX_HEARD_ISLAND, + eCSR_COUNTRY_INDEX_HONDURAS, + eCSR_COUNTRY_INDEX_CROATIA, + eCSR_COUNTRY_INDEX_HAITI, + eCSR_COUNTRY_INDEX_HUNGARY, + eCSR_COUNTRY_INDEX_INDONESIA, + eCSR_COUNTRY_INDEX_IRELAND, + eCSR_COUNTRY_INDEX_ISRAEL, + eCSR_COUNTRY_INDEX_ISLE_OF_MAN, + eCSR_COUNTRY_INDEX_INDIA, + eCSR_COUNTRY_INDEX_BRITISH_INDIAN, + eCSR_COUNTRY_INDEX_IRAQ, + eCSR_COUNTRY_INDEX_IRAN, + eCSR_COUNTRY_INDEX_ICELAND, + eCSR_COUNTRY_INDEX_ITALY, + eCSR_COUNTRY_INDEX_JERSEY, + eCSR_COUNTRY_INDEX_JAMAICA, + eCSR_COUNTRY_INDEX_JORDAN, + eCSR_COUNTRY_INDEX_JAPAN, + eCSR_COUNTRY_INDEX_KENYA, + eCSR_COUNTRY_INDEX_KYRGYZSTAN, + eCSR_COUNTRY_INDEX_CAMBODIA, + eCSR_COUNTRY_INDEX_KIRIBATI, + eCSR_COUNTRY_INDEX_COMOROS, + eCSR_COUNTRY_INDEX_SAINT_KITTS_AND_NEVIS, + eCSR_COUNTRY_INDEX_KOREA_NORTH, + eCSR_COUNTRY_INDEX_KOREA_SOUTH, + eCSR_COUNTRY_INDEX_KUWAIT, + eCSR_COUNTRY_INDEX_CAYMAN_ISLANDS, + eCSR_COUNTRY_INDEX_KAZAKHSTAN, + eCSR_COUNTRY_INDEX_LAO, + eCSR_COUNTRY_INDEX_LEBANON, + eCSR_COUNTRY_INDEX_SAINT_LUCIA, + eCSR_COUNTRY_INDEX_LIECHTENSTEIN, + eCSR_COUNTRY_INDEX_SRI_LANKA, + eCSR_COUNTRY_INDEX_LIBERIA, + eCSR_COUNTRY_INDEX_LESOTHO, + eCSR_COUNTRY_INDEX_LITHUANIA, + eCSR_COUNTRY_INDEX_LUXEMBOURG, + eCSR_COUNTRY_INDEX_LATVIA, + eCSR_COUNTRY_INDEX_LIBYAN_ARAB_JAMAHIRIYA, + eCSR_COUNTRY_INDEX_MOROCCO, + eCSR_COUNTRY_INDEX_MONACO, + eCSR_COUNTRY_INDEX_MOLDOVA, + eCSR_COUNTRY_INDEX_MONTENEGRO, + eCSR_COUNTRY_INDEX_MADAGASCAR, + eCSR_COUNTRY_INDEX_MARSHALL_ISLANDS, + eCSR_COUNTRY_INDEX_MACEDONIA, + eCSR_COUNTRY_INDEX_MALI, + eCSR_COUNTRY_INDEX_MYANMAR, + eCSR_COUNTRY_INDEX_MONGOLIA, + eCSR_COUNTRY_INDEX_MACAO, + eCSR_COUNTRY_INDEX_NORTHERN_MARIANA_ISLANDS, + eCSR_COUNTRY_INDEX_MARTINIQUE, + eCSR_COUNTRY_INDEX_MAURITANIA, + eCSR_COUNTRY_INDEX_MONTSERRAT, + eCSR_COUNTRY_INDEX_MALTA, + eCSR_COUNTRY_INDEX_MAURITIUS, + eCSR_COUNTRY_INDEX_MALDIVES, + eCSR_COUNTRY_INDEX_MALAWI, + eCSR_COUNTRY_INDEX_MEXICO, + eCSR_COUNTRY_INDEX_MALAYSIA, + eCSR_COUNTRY_INDEX_MOZAMBIQUE, + eCSR_COUNTRY_INDEX_NAMIBIA, + eCSR_COUNTRY_INDEX_NEW_CALENDONIA, + eCSR_COUNTRY_INDEX_NIGER, + eCSR_COUNTRY_INDEX_NORFOLK_ISLAND, + eCSR_COUNTRY_INDEX_NIGERIA, + eCSR_COUNTRY_INDEX_NICARAGUA, + eCSR_COUNTRY_INDEX_NETHERLANDS, + eCSR_COUNTRY_INDEX_NORWAY, + eCSR_COUNTRY_INDEX_NEPAL, + eCSR_COUNTRY_INDEX_NAURU, + eCSR_COUNTRY_INDEX_NIUE, + eCSR_COUNTRY_INDEX_NEW_ZEALAND, + eCSR_COUNTRY_INDEX_OMAN, + eCSR_COUNTRY_INDEX_PANAMA, + eCSR_COUNTRY_INDEX_PERU, + eCSR_COUNTRY_INDEX_FRENCH_POLYNESIA, + eCSR_COUNTRY_INDEX_PAPUA_NEW_HUINEA, + eCSR_COUNTRY_INDEX_PHILIPPINES, + eCSR_COUNTRY_INDEX_PAKISTAN, + eCSR_COUNTRY_INDEX_POLAND, + eCSR_COUNTRY_INDEX_SAINT_PIERRE_AND_MIQUELON, + eCSR_COUNTRY_INDEX_PITCAIRN, + eCSR_COUNTRY_INDEX_PUERTO_RICO, + eCSR_COUNTRY_INDEX_PALESTINIAN_TERRITOTY_OCCUPIED, + eCSR_COUNTRY_INDEX_PORTUGAL, + eCSR_COUNTRY_INDEX_PALAU, + eCSR_COUNTRY_INDEX_PARAGUAY, + eCSR_COUNTRY_INDEX_QATAR, + eCSR_COUNTRY_INDEX_REUNION, + eCSR_COUNTRY_INDEX_ROMANIA, + eCSR_COUNTRY_INDEX_SERBIA, + eCSR_COUNTRY_INDEX_RUSSIAN, + eCSR_COUNTRY_INDEX_RWANDA, + eCSR_COUNTRY_INDEX_SAUDI_ARABIA, + eCSR_COUNTRY_INDEX_SOLOMON_ISLANDS, + eCSR_COUNTRY_INDEX_SEYCHELLES, + eCSR_COUNTRY_INDEX_SUDAN, + eCSR_COUNTRY_INDEX_SWEDEN, + eCSR_COUNTRY_INDEX_SINGAPORE, + eCSR_COUNTRY_INDEX_SAINT_HELENA, + eCSR_COUNTRY_INDEX_SLOVENIA, + eCSR_COUNTRY_INDEX_SVALBARD_AND_JAN_MAYEN, + eCSR_COUNTRY_INDEX_SLOVAKIA, + eCSR_COUNTRY_INDEX_SIERRA_LEONE, + eCSR_COUNTRY_INDEX_SAN_MARINO, + eCSR_COUNTRY_INDEX_SENEGAL, + eCSR_COUNTRY_INDEX_SOMOLIA, + eCSR_COUNTRY_INDEX_SURINAME, + eCSR_COUNTRY_INDEX_SAO_TOME_AND_PRINCIPE, + eCSR_COUNTRY_INDEX_EL_SALVADOR, + eCSR_COUNTRY_INDEX_SYRIAN_REP, + eCSR_COUNTRY_INDEX_SWAZILAND, + eCSR_COUNTRY_INDEX_TURKS_AND_CAICOS_ISLANDS, + eCSR_COUNTRY_INDEX_CHAD, + eCSR_COUNTRY_INDEX_FRENCH_SOUTHERN_TERRRTORY, + eCSR_COUNTRY_INDEX_TOGO, + eCSR_COUNTRY_INDEX_THAILAND, + eCSR_COUNTRY_INDEX_TAJIKSTAN, + eCSR_COUNTRY_INDEX_TOKELAU, + eCSR_COUNTRY_INDEX_TIMOR_LESTE, + eCSR_COUNTRY_INDEX_TURKMENISTAN, + eCSR_COUNTRY_INDEX_TUNISIA, + eCSR_COUNTRY_INDEX_TONGA, + eCSR_COUNTRY_INDEX_TURKEY, + eCSR_COUNTRY_INDEX_TRINIDAD_AND_TOBAGO, + eCSR_COUNTRY_INDEX_TUVALU, + eCSR_COUNTRY_INDEX_TAIWAN, + eCSR_COUNTRY_INDEX_TANZANIA, + eCSR_COUNTRY_INDEX_UKRAINE, + eCSR_COUNTRY_INDEX_UGANDA, + eCSR_COUNTRY_INDEX_US_MINOR_OUTLYING_ISLANDS, + eCSR_COUNTRY_INDEX_URUGUAY, + eCSR_COUNTRY_INDEX_UZBEKISTAN, + eCSR_COUNTRY_INDEX_HOLY_SEE, + eCSR_COUNTRY_INDEX_SAINT_VINCENT_AND_THE_GRENADINES, + eCSR_COUNTRY_INDEX_VENESUELA, + eCSR_COUNTRY_INDEX_VIRGIN_ISLANDS_BRITISH, + eCSR_COUNTRY_INDEX_VIRGIN_ISLANDS_US, + eCSR_COUNTRY_INDEX_VIET_NAM, + eCSR_COUNTRY_INDEX_VANUATU, + eCSR_COUNTRY_INDEX_WALLIS_AND_FUTUNA, + eCSR_COUNTRY_INDEX_SAMOA, + eCSR_COUNTRY_INDEX_YEMEN, + eCSR_COUNTRY_INDEX_MAYOTTE, + eCSR_COUNTRY_INDEX_SOTHER_AFRICA, + eCSR_COUNTRY_INDEX_ZAMBIA, + eCSR_COUNTRY_INDEX_ZIMBABWE, + + eCSR_COUNTRY_INDEX_KOREA_1, + eCSR_COUNTRY_INDEX_KOREA_2, + eCSR_COUNTRY_INDEX_KOREA_3, + eCSR_COUNTRY_INDEX_KOREA_4, + + eCSR_NUM_COUNTRY_INDEX, +}eCsrCountryIndex; +//Please donot insert in the middle of the enum above because they tie to the indiex + + +typedef struct tagCsrSirMBMsgHdr +{ + tANI_U16 type; + tANI_U16 msgLen; + +}tCsrSirMBMsgHdr; + +typedef struct tagCsrCfgMsgTlvHdr +{ + tANI_U32 type; + tANI_U32 length; + +}tCsrCfgMsgTlvHdr; + + + +typedef struct tagCsrCfgMsgTlv +{ + tCsrCfgMsgTlvHdr Hdr; + tANI_U32 variable[ 1 ]; // placeholder for the data + +}tCsrCfgMsgTlv; + +typedef struct tagCsrCfgGetRsp +{ + tCsrSirMBMsgHdr hdr; + tANI_U32 respStatus; + tANI_U32 paramId; + tANI_U32 attribLen; + tANI_U32 attribVal[1]; +}tCsrCfgGetRsp; + +typedef struct tagCsrCfgSetRsp +{ + + tCsrSirMBMsgHdr hdr; + tANI_U32 respStatus; + tANI_U32 paramId; +}tCsrCfgSetRsp; + + +typedef struct tagCsrDomainChnScanInfo +{ + tANI_U8 chnId; + tSirScanType scanType; //whether this channel must be scan passively +}tCsrDomainChnScanInfo; + + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( push ) +#pragma pack( 1 ) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack( 1 ) +#endif + +// Generic Information Element Structure +typedef __ani_attr_pre_packed struct sDot11IEHeader +{ + tANI_U8 ElementID; + tANI_U8 Length; +}__ani_attr_packed tDot11IEHeader; + +typedef __ani_attr_pre_packed struct tagCsrWmeInfoIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WME_OUI_SIZE ]; // includes the 3 byte OUI + 1 byte Type + tANI_U8 Subtype; + tANI_U8 Version; + tANI_U8 QoSInfo; + +} __ani_attr_packed tCsrWmeInfoIe; + +typedef __ani_attr_pre_packed struct tagCsrWmeAcParms +{ + tANI_U8 AciAifsn; + tANI_U8 EcwMinEcwMax; + tANI_U16 TxOpLimit; + +} __ani_attr_packed tCsrWmeAcParms; + +typedef __ani_attr_pre_packed struct tagCsrWmeParmIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WME_OUI_SIZE ]; // includes the 3 byte OUI + 1 byte Type + tANI_U8 Subtype; + tANI_U8 Version; + tANI_U8 QoSInfo; + tANI_U8 Reserved; + tCsrWmeAcParms BestEffort; + tCsrWmeAcParms Background; + tCsrWmeAcParms Video; + tCsrWmeAcParms Voice; + +} __ani_attr_packed tCsrWmeParmIe; + +typedef __ani_attr_pre_packed struct tagCsrWpaIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + tANI_U16 Version; + tANI_U8 MulticastOui[ CSR_WPA_OUI_SIZE ]; + tANI_U16 cUnicastCyphers; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + +} __ani_attr_packed tCsrWpaIe; + +typedef __ani_attr_pre_packed struct tagCsrWpaAuthIe +{ + + tANI_U16 cAuthenticationSuites; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + +} __ani_attr_packed tCsrWpaAuthIe; + + +typedef __ani_attr_pre_packed struct tagCsrRSNIe +{ + tDot11IEHeader IeHeader; + tANI_U16 Version; + tANI_U8 MulticastOui[ CSR_RSN_OUI_SIZE ]; + tANI_U16 cUnicastCyphers; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_RSN_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + +} __ani_attr_packed tCsrRSNIe; + +typedef __ani_attr_pre_packed struct tagCsrRSNAuthIe +{ + tANI_U16 cAuthenticationSuites; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_RSN_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + +} __ani_attr_packed tCsrRSNAuthIe; + +typedef __ani_attr_pre_packed struct tagCsrRSNCapabilities +{ + tANI_U16 PreAuthSupported:1; + tANI_U16 NoPairwise:1; + tANI_U16 PTKSAReplayCounter:2; + tANI_U16 GTKSAReplayCounter:2; + tANI_U16 MFPRequired:1; + tANI_U16 MFPCapable:1; + tANI_U16 Reserved:8; +} __ani_attr_packed tCsrRSNCapabilities; + +typedef __ani_attr_pre_packed struct tagCsrRSNPMKIe +{ + tANI_U16 cPMKIDs; + + __ani_attr_pre_packed struct { + + tANI_U8 PMKID[ CSR_RSN_PMKID_SIZE ]; + + } __ani_attr_packed PMKIDList[ 1 ]; + + +} __ani_attr_packed tCsrRSNPMKIe; + +typedef __ani_attr_pre_packed struct tCsrIELenInfo +{ + tANI_U8 min; + tANI_U8 max; +} __ani_attr_packed tCsrIELenInfo; + +#ifdef FEATURE_WLAN_WAPI +typedef __ani_attr_pre_packed struct tagCsrWapiIe +{ + tDot11IEHeader IeHeader; + tANI_U16 Version; + + tANI_U16 cAuthenticationSuites; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WAPI_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + + tANI_U16 cUnicastCyphers; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WAPI_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + + tANI_U8 MulticastOui[ CSR_WAPI_OUI_SIZE ]; + + __ani_attr_pre_packed struct { + tANI_U16 PreAuthSupported:1; + tANI_U16 Reserved:15; + } __ani_attr_packed tCsrWapiCapabilities; + + +} __ani_attr_packed tCsrWapiIe; + +typedef __ani_attr_pre_packed struct tagCsrWAPIBKIe +{ + tANI_U16 cBKIDs; + __ani_attr_pre_packed struct { + + tANI_U8 BKID[ CSR_WAPI_BKID_SIZE ]; + + } __ani_attr_packed BKIDList[ 1 ]; + + +} __ani_attr_packed tCsrWAPIBKIe; +#endif /* FEATURE_WLAN_WAPI */ + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( pop ) +#endif + +// Structure used to describe a group of continuous channels and hook it into the +// corresponding channel list +typedef struct tagCsrChannelSet +{ + tListElem channelListLink; + tANI_U8 firstChannel; + tANI_U8 interChannelOffset; + tANI_U8 numChannels; + tANI_U8 txPower; +}tCsrChannelSet; + + +typedef struct sDot11InfoIBSSParmSet +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ATIMWindow; +}tDot11InfoIBSSParmSet; + + +typedef struct sDot11IECountry +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 countryString[3]; + tSirMacChanInfo chanInfo[1]; +}tDot11IECountry; + + +typedef struct sDot11IEExtenedSupportedRates +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ExtendedSupportedRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; +}tDot11IEExtenedSupportedRates; + +#define CSR_DOT11_AP_NAME_MAX_LENGTH ( 32 ) + +typedef struct tagDot11IEAPName +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ApName[ CSR_DOT11_AP_NAME_MAX_LENGTH ]; +}tDot11IEAPName; + +typedef struct tagDot11IE11HLocalPowerConstraint +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 localPowerConstraint; + +}tDot11IE11HLocalPowerConstraint; + +typedef struct tagRoamingTimerInfo +{ + tpAniSirGlobal pMac; + tANI_U8 sessionId; +} tCsrTimerInfo; + + +#define CSR_IS_11A_BSS(pBssDesc) ( eSIR_11A_NW_TYPE == (pBssDesc)->nwType ) +#define CSR_IS_BASIC_RATE(rate) ((rate) & CSR_DOT11_BASIC_RATE_MASK) +#define CSR_IS_QOS_BSS(pIes) ( (pIes)->WMMParams.present || (pIes)->WMMInfoAp.present ) + +#define CSR_IS_UAPSD_BSS(pIes) \ + ( ((pIes)->WMMParams.present && ((pIes)->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD)) || \ + ((pIes)->WMMInfoAp.present && (pIes)->WMMInfoAp.uapsd) ) + +//This macro returns the total length needed of Tlv with with len bytes of data +#define GET_TLV_MSG_LEN(len) GET_ROUND_UP((sizeof(tCsrCfgMsgTlvHdr) + (len)), sizeof(tANI_U32)) + +tANI_BOOLEAN csrGetBssIdBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tCsrBssid *pBssId ); +tANI_BOOLEAN csrIsBssIdEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ); + +eCsrMediaAccessType csrGetQoSFromBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes); +tANI_BOOLEAN csrIsNULLSSID( tANI_U8 *pBssSsid, tANI_U8 len ); +tANI_BOOLEAN csrIsInfraBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_BOOLEAN csrIsIbssBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_BOOLEAN csrIsPrivacy( tSirBssDescription *pSirBssDesc ); +tSirResultCodes csrGetDisassocRspStatusCode( tSirSmeDisassocRsp *pSmeDisassocRsp ); +tSirResultCodes csrGetDeAuthRspStatusCode( tSirSmeDeauthRsp *pSmeRsp ); +tANI_U32 csrGetFragThresh( tHalHandle hHal ); +tANI_U32 csrGetRTSThresh( tHalHandle hHal ); +eCsrPhyMode csrGetPhyModeFromBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_U32 csrGet11hPowerConstraint( tHalHandle hHal, tDot11fIEPowerConstraints *pPowerConstraint ); +tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe ); +tANI_U8 csrConstructWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ); +#ifdef FEATURE_WLAN_WAPI + +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ); +#endif /* FEATURE_WLAN_WAPI */ +//If a WPAIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ); +tANI_BOOLEAN csrIsSsidEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 ); +//Null ssid means match +tANI_BOOLEAN csrIsSsidInList( tHalHandle hHal, tSirMacSSid *pSsid, tCsrSSIDs *pSsidList ); +tANI_BOOLEAN csrIsProfileWpa( tCsrRoamProfile *pProfile ); +tANI_BOOLEAN csrIsProfileRSN( tCsrRoamProfile *pProfile ); +//This function returns the raw byte array of WPA and/or RSN IE +tANI_BOOLEAN csrGetWpaRsnIe( tHalHandle hHal, tANI_U8 *pIes, tANI_U32 len, + tANI_U8 *pWpaIe, tANI_U8 *pcbWpaIe, tANI_U8 *pRSNIe, tANI_U8 *pcbRSNIe); +//If a RSNIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveRsnIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe ); +#ifdef FEATURE_WLAN_WAPI +//If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE +tANI_U8 csrRetrieveWapiIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ); +#endif /* FEATURE_WLAN_WAPI */ +tANI_BOOLEAN csrSearchChannelListForTxPower(tHalHandle hHal, tSirBssDescription *pBssDescription, tCsrChannelSet *returnChannelGroup); +tANI_BOOLEAN csrRatesIsDot11Rate11bSupportedRate( tANI_U8 dot11Rate ); +tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate ); +tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType ); +//pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs +tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, + tCsrEncryptionList *pUCEncryptionType, + tCsrEncryptionList *pMCEncryptionType, + tANI_BOOLEAN *pMFPEnabled, + tANI_U8 *pMFPRequired, + tANI_U8 *pMFPCapable, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, + eCsrAuthType *negotiatedAuthtype, eCsrEncryptionType *negotiatedUCCipher, eCsrEncryptionType *negotiatedMCCipher ); +tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2); +tANI_BOOLEAN csrIsBssTypeIBSS(eCsrRoamBssType bssType); +tANI_BOOLEAN csrIsBssTypeWDS(eCsrRoamBssType bssType); +//ppIes can be NULL. If caller want to get the *ppIes allocated by this function, pass in *ppIes = NULL +//Caller needs to free the memory in this case +tANI_BOOLEAN csrMatchBSS( tHalHandle hHal, tSirBssDescription *pBssDesc, tCsrScanResultFilter *pFilter, + eCsrAuthType *pNegAuth, eCsrEncryptionType *pNegUc, eCsrEncryptionType *pNegMc, + tDot11fBeaconIEs **ppIes); + +tANI_BOOLEAN csrIsBssidMatch( tHalHandle hHal, tCsrBssid *pProfBssid, tCsrBssid *BssBssid ); +tANI_BOOLEAN csrMatchBSSToConnectProfile( tHalHandle hHal, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ); + +void csrAddRateBitmap(tANI_U8 rate, tANI_U16 *pRateBitmap); +tANI_BOOLEAN csrCheckRateBitmap(tANI_U8 rate, tANI_U16 RateBitmap); + +tANI_BOOLEAN csrRatesIsDot11RateSupported( tHalHandle hHal, tANI_U8 rate ); +tANI_U16 csrRatesFindBestRate( tSirMacRateSet *pSuppRates, tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates ); +tSirBssType csrTranslateBsstypeToMacType(eCsrRoamBssType csrtype); + +//Caller allocates memory for pIEStruct +eHalStatus csrParseBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIEStruct); +//This function will allocate memory for the parsed IEs to the caller. Caller must free the memory +//after it is done with the data only if this function succeeds +eHalStatus csrGetParsedBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs **ppIEStruct); + +tANI_BOOLEAN csrValidateCountryString( tHalHandle hHal, tANI_U8 *pCountryString ); +tSirScanType csrGetScanType(tpAniSirGlobal pMac, tANI_U8 chnId); + +tANI_U8 csrToUpper( tANI_U8 ch ); +eHalStatus csrGetPhyModeFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription, + eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes); + +//fForce -- force reassoc regardless of whether there is any change +//The reason is that for UAPSD-bypass, the code underneath this call determine whether +//to allow UAPSD. The information in pModProfileFields reflects what the user wants. +//There may be discrepency in it. UAPSD-bypass logic should decide if it needs to reassoc +eHalStatus csrReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce); + +eHalStatus +csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona); + +//Update beaconInterval for P2P-GO case if it is different +eHalStatus csrUpdatep2pBeaconInterval(tpAniSirGlobal pMac); + +//BeaconInterval validation for MCC support +eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, + tANI_U16 *beaconInterval, tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona); + +#ifdef WLAN_FEATURE_VOWIFI_11R +tANI_BOOLEAN csrIsProfile11r( tCsrRoamProfile *pProfile ); +tANI_BOOLEAN csrIsAuthType11r( eCsrAuthType AuthType, tANI_U8 mdiePresent); +#endif + +#ifdef FEATURE_WLAN_ESE +tANI_BOOLEAN csrIsAuthTypeESE( eCsrAuthType AuthType ); +tANI_BOOLEAN csrIsProfileESE( tCsrRoamProfile *pProfile ); +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/nan_Api.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/nan_Api.h new file mode 100644 index 0000000000000..9e4b19d67c67f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/nan_Api.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: nan_Api.h +* +* Description: NAN FSM defines. +* +******************************************************************************/ + +#ifndef __NAN_API_H__ +#define __NAN_API_H__ + +#include "vos_types.h" +#include "halTypes.h" + +typedef struct sNanRequestReq { + tANI_U16 request_data_len; + tANI_U8* request_data; +} tNanRequestReq, *tpNanRequestReq; + +/****************************************************************************** + * Function: Pointer NanCallback + * + * Description: + * this function pointer is used hold nan response callback. When ever we + * receive nan response, we will use this callback. + * + * Args: + * first argument to pass hHal pointer and second argument + * to pass the nan response data. + * + * Returns: + * void +******************************************************************************/ +typedef void (*NanCallback)(void*, tSirNanEvent*); + +/****************************************************************************** + * Function: sme_NanRegisterCallback + * + * Description: + * This function gets called when HDD wants register nan rsp callback with + * sme layer. + * + * Args: + * hHal and callback which needs to be registered. + * + * Returns: + * void +******************************************************************************/ +void sme_NanRegisterCallback(tHalHandle hHal, NanCallback callback); + +/****************************************************************************** + * Function: sme_NanRequest + * + * Description: + * This function gets called when HDD receives NAN vendor command + * from userspace + * + * Args: + * Nan Request structure ptr + * + * Returns: + * VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanRequest(tpNanRequestReq input); + + +#endif /* __NAN_API_H__ */ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataApi.h new file mode 100644 index 0000000000000..2945848dc1732 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataApi.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataApi.h + + Exports and types for the Common OEM DATA REQ/RSP Module interfaces. +========================================================================== */ + +#ifndef __OEM_DATA_API_H__ +#define __OEM_DATA_API_H__ +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "csrLinkList.h" + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +/* message subtype for internal purpose */ +#define OEM_MESSAGE_SUBTYPE_INTERNAL 0xdeadbeef + +/************************************************************************************************************* + OEM DATA REQ/RSP - DATA STRUCTURES +*************************************************************************************************************/ + +/* Structure for defining req sent to the PE */ +typedef struct tagOemDataReq +{ + tANI_U8 sessionId; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tOemDataReq, tOemDataReqConfig; + +/************************************************************************************************************* + OEM DATA RESPONSE - DATA STRUCTURES +*************************************************************************************************************/ +typedef struct tagOemDataRsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tOemDataRsp; + +/*************************************************************************************************************/ + +typedef enum +{ + eOEM_DATA_REQ_SUCCESS=1, + eOEM_DATA_REQ_FAILURE, + eOEM_DATA_REQ_INVALID_MODE, +} eOemDataReqStatus; + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqOpen + \brief This function must be called before any API call to MEAS (OEM DATA REQ/RSP module) + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqOpen(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqClose + \brief This function must be called before closing the csr module + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqClose(tHalHandle hHal); + +/* HDD Callback function for the sme to callback when the oem data rsp is available */ +typedef eHalStatus (*oemData_OemDataReqCompleteCallback)( + tHalHandle, + void* p2, + tANI_U32 oemDataReqID, + eOemDataReqStatus status); + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReq + \brief Request an OEM DATA RSP + \param sessionId - Id of session to be used + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_OemDataReq(tHalHandle, tANI_U8, tOemDataReqConfig *, tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, void *pContext); + +/* --------------------------------------------------------------------------- + \fn sme_HandleOemDataRsp + \brief This function processes the oem data response obtained from the PE + \param pMsg - Pointer to the pSirSmeOemDataRsp + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8*); + +/* --------------------------------------------------------------------------- + \fn oemData_IsOemDataReqAllowed + \brief This function checks if oem data req/rsp can be performed in the + current driver state + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn send_oem_data_rsp_msg + \brief This function sends oem data response message to registered + application + \return None + --------------------------------------------------------------------------*/ +void send_oem_data_rsp_msg(int length, tANI_U8 *oemDataRsp); + +#endif //_OEM_DATA_API_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataInternal.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataInternal.h new file mode 100644 index 0000000000000..99742f127ee02 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/oemDataInternal.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataInternal.h + + Exports and types for the Common OEM DATA REQ/RSP Module interfaces. +========================================================================== */ + + +#ifndef __OEM_DATA_INTERNAL_H__ +#define __OEM_DATA_INTERNAL_H__ + +#include "csrSupport.h" +#include "vos_nvitem.h" +#include "wlan_qct_tl.h" + +#include "oemDataApi.h" + +typedef struct tagOemDataStruct +{ + tANI_U32 nextOemReqId; //a global req id + tANI_BOOLEAN oemDataReqActive; //indicates that currently a request has been posted and + //waiting for the response + oemData_OemDataReqCompleteCallback callback; //callback function pointer for returning the response + void* pContext; //context of the original caller + tANI_U32 oemDataReqID; //original request ID + tOemDataRsp* pOemDataRsp; //response + tOemDataReqConfig oemDataReqConfig; //current oem data request + tANI_U8 sessionId; //Session on which oem data req is active +} tOemDataStruct; + +typedef struct tagOemDataCmd +{ + tANI_U32 oemDataReqID; + oemData_OemDataReqCompleteCallback callback; + void* pContext; + tOemDataReq oemDataReq; +} tOemDataCmd; + +#endif //__OEM_DATA_INTERNAL_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/p2p_Api.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/p2p_Api.h new file mode 100644 index 0000000000000..4a04c84997fa4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/p2p_Api.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: p2p_Api.h +* +* Description: P2P FSM defines. +* + +* +******************************************************************************/ + +#ifndef __P2P_API_H__ +#define __P2P_API_H__ + +#include "vos_types.h" +#include "halTypes.h" +#include "vos_timer.h" +#include "vos_lock.h" + +typedef struct sP2pPsConfig{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; + tANI_U8 sessionid; +}tP2pPsConfig,*tpP2pPsConfig; + +typedef eHalStatus (*remainOnChanCallback)( tHalHandle, void* context, + eHalStatus status ); + +typedef struct sRemainOnChn{ + tANI_U8 chn; + tANI_U32 duration; + remainOnChanCallback callback; + void *pCBContext; +}tRemainOnChn, tpRemainOnChn; + +#define SIZE_OF_NOA_DESCRIPTOR 13 +#define MAX_NOA_PERIOD_IN_MICROSECS 3000000 + +#define P2P_CLEAR_POWERSAVE 0 +#define P2P_OPPORTUNISTIC_PS 1 +#define P2P_PERIODIC_NOA 2 +#define P2P_SINGLE_NOA 4 + + +typedef struct sp2pContext +{ + v_CONTEXT_t vosContext; + tHalHandle hHal; + tANI_U8 sessionId; //Session id corresponding to P2P. On windows it is same as HDD sessionid not sme sessionid. + tANI_U8 SMEsessionId; + tANI_U8 probeReqForwarding; + tANI_U8 *probeRspIe; + tANI_U32 probeRspIeLength; +} tp2pContext, *tPp2pContext; + +eHalStatus sme_RemainOnChannel( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed); +eHalStatus sme_ReportProbeReq( tHalHandle hHal, tANI_U8 flag ); +eHalStatus sme_updateP2pIe( tHalHandle hHal, void *p2pIe, + tANI_U32 p2pIeLength ); +eHalStatus sme_sendAction( tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack); +eHalStatus sme_CancelRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId ); +eHalStatus sme_p2pOpen( tHalHandle hHal ); +eHalStatus p2pStop( tHalHandle hHal ); +eHalStatus sme_p2pClose( tHalHandle hHal ); +eHalStatus sme_p2pSetPs( tHalHandle hHal, tP2pPsConfig * data ); +eHalStatus p2pRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed); +eHalStatus p2pSendAction( tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack); +eHalStatus p2pCancelRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId ); +eHalStatus p2pSetPs( tHalHandle hHal, tP2pPsConfig *pNoA ); +tSirRFBand GetRFBand(tANI_U8 channel); +#endif //__P2P_API_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/pmc.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/pmc.h new file mode 100644 index 0000000000000..ff618b4c33f9d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/pmc.h @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmc.h +* +* Description: Power Management Control (PMC) internal definitions. +* + +* +******************************************************************************/ + +#ifndef __PMC_H__ +#define __PMC_H__ + + +#include "csrLinkList.h" +#include "pmcApi.h" +#include "smeInternal.h" + + +//Change PMC_ABORT to no-op for now. We need to define it as VOS_ASSERT(0) once we +//cleanup the usage. +#define PMC_ABORT + +#define PMC_SESSION_MAX 5 + +/* Auto Ps Entry Timer Default value - 1000 ms */ +#define AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE 1000 + +/* Auto Deferred Ps Entry Timer value - 5000 ms */ +#define AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE 5000 + + +/* Host power sources. */ +typedef enum ePowerSource +{ + AC_POWER, /* host is operating from AC power */ + BATTERY_POWER /* host is operating from battery power */ +} tPowerSource; + + +/* Power save check routine list entry. */ +typedef struct sPowerSaveCheckEntry +{ + tListElem link; /* list links */ + tANI_BOOLEAN (*checkRoutine) (void *checkContext); /* power save check routine */ + void *checkContext; /* value to be passed as parameter to routine specified above */ +} tPowerSaveCheckEntry, *tpPowerSaveCheckEntry; + + +/* Device Power State update indication list entry. */ +typedef struct sDeviceStateUpdateIndEntry +{ + tListElem link; /* list links */ + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState); /* Callback routine to be invoked when pmc changes device state */ + void *callbackContext; /* value to be passed as parameter to routine specified above */ +} tDeviceStateUpdateIndEntry, *tpDeviceStateUpdateIndEntry; + +/* Request full power callback routine list entry. */ +typedef struct sRequestFullPowerEntry +{ + tListElem link; /* list links */ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call when full power is restored */ + void *callbackContext; /* value to be passed as parameter to routine specified above */ +} tRequestFullPowerEntry, *tpRequestFullPowerEntry; + + +/* Request BMPS callback routine list entry. */ +typedef struct sRequestBmpsEntry +{ + tListElem link; /* list links */ + + /* routine to call when BMPS request succeeded/failed */ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + +} tRequestBmpsEntry, *tpRequestBmpsEntry; + + +/* Start U-APSD callback routine list entry. */ +typedef struct sStartUapsdEntry +{ + tListElem link; /* list links */ + + /* routine to call when Uapsd Start succeeded/failed*/ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + +} tStartUapsdEntry, *tpStartUapsdEntry; + +typedef struct sPmcDeferredMsg +{ + tListElem link; + tpAniSirGlobal pMac; + tANI_U16 messageType; + tANI_U16 size; //number of bytes in u.data + union + { + tSirPowerSaveCfg powerSaveConfig; + tSirWowlAddBcastPtrn wowlAddPattern; + tSirWowlDelBcastPtrn wowlDelPattern; + tANI_U8 data[1]; //a place holder + }u; +} tPmcDeferredMsg; + + + +/* Current PMC information for a particular device. */ +typedef struct sPmcInfo +{ + tPowerSource powerSource; /* host power source */ + tPmcSwitchState hwWlanSwitchState; /* Hardware WLAN Switch state */ + tPmcSwitchState swWlanSwitchState; /* Software WLAN Switch state */ + tPmcState pmcState; /* PMC state */ + tANI_BOOLEAN requestFullPowerPending; /* TRUE if a request for full power is pending */ + tRequestFullPowerReason requestFullPowerReason; /* reason for requesting full power */ + tPmcImpsConfigParams impsConfig; /* IMPS configuration */ + tPmcBmpsConfigParams bmpsConfig; /* BMPS configuration */ + tPmcSmpsConfigParams smpsConfig; /* SMPS configuration */ + tANI_BOOLEAN impsEnabled; /* TRUE if IMPS is enabled */ + tANI_BOOLEAN bmpsEnabled; /* TRUE if BMPS is enabled */ + tANI_BOOLEAN autoBmpsEntryEnabled; /* TRUE if auto BMPS entry is enabled. If set to TRUE, PMC will + attempt to put the device into BMPS on entry into full Power */ + tANI_BOOLEAN bmpsRequestedByHdd; /*TRUE if BMPS mode has been requested by HDD */ + tANI_BOOLEAN bmpsRequestQueued; /*If a enter BMPS request is queued*/ + tANI_BOOLEAN smpsEnabled; /* TRUE if SMPS is enabled */ + tANI_BOOLEAN remainInPowerActiveTillDHCP; /* Remain in Power active till DHCP completes */ + tANI_U32 remainInPowerActiveThreshold; /*Remain in Power active till DHCP threshold*/ + tANI_U32 impsPeriod; /* amount of time to remain in IMPS */ + void (*impsCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call when IMPS period + has finished */ + void *impsCallbackContext; /* value to be passed as parameter to routine specified above */ + vos_timer_t hImpsTimer; /* timer to use with IMPS */ + vos_timer_t hTrafficTimer; /* timer to measure traffic for BMPS */ +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_timer_t hDiagEvtTimer; /* timer to report PMC state through DIAG event */ +#endif + vos_timer_t hExitPowerSaveTimer; /* timer for deferred exiting of power save mode */ + tDblLinkList powerSaveCheckList; /* power save check routine list */ + tDblLinkList requestFullPowerList; /* request full power callback routine list */ + tANI_U32 cLastTxUnicastFrames; /* transmit unicast frame count at last BMPS traffic timer expiration */ + tANI_U32 cLastRxUnicastFrames; /* receive unicast frame count at last BMPS traffic timer expiration */ + + + tANI_BOOLEAN uapsdEnabled; /* TRUE if UAPSD is enabled */ + tANI_BOOLEAN uapsdSessionRequired; /* TRUE if device should go to UAPSD on entering BMPS*/ + tDblLinkList requestBmpsList; /* request Bmps callback routine list */ + tDblLinkList requestStartUapsdList; /* request start Uapsd callback routine list */ + tANI_BOOLEAN standbyEnabled; /* TRUE if Standby is enabled */ + void (*standbyCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call for standby request */ + void *standbyCallbackContext;/* value to be passed as parameter to routine specified above */ + tDblLinkList deviceStateUpdateIndList; /*update device state indication list */ + tANI_BOOLEAN pmcReady; /*whether eWNI_SME_SYS_READY_IND has been sent to PE or not */ + tANI_BOOLEAN wowlEnabled; /* TRUE if WoWL is enabled */ + tANI_BOOLEAN wowlModeRequired; /* TRUE if device should go to WOWL on entering BMPS */ + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call for wowl request */ + void *enterWowlCallbackContext;/* value to be passed as parameter to routine specified above */ + tSirSmeWowlEnterParams wowlEnterParams; /* WOWL mode configuration */ + tDblLinkList deferredMsgList; //The message in here are deferred and DONOT expect response from PE +#ifdef FEATURE_WLAN_SCAN_PNO + preferredNetworkFoundIndCallback prefNetwFoundCB; /* routine to call for Preferred Network Found Indication */ + void *preferredNetworkFoundIndCallbackContext;/* value to be passed as parameter to routine specified above */ +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_PACKET_FILTERING + FilterMatchCountCallback FilterMatchCountCB; /* routine to call for Packet Coalescing Filter Match Count */ + void *FilterMatchCountCBContext;/* value to be passed as parameter to routine specified above */ +#endif // WLAN_FEATURE_PACKET_FILTERING +#ifdef WLAN_FEATURE_GTK_OFFLOAD + GTKOffloadGetInfoCallback GtkOffloadGetInfoCB; /* routine to call for GTK Offload Information */ + void *GtkOffloadGetInfoCBContext; /* value to be passed as parameter to routine specified above */ +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd); /* routine to call for Wake Reason Indication */ + void *wakeReasonIndCBContext; /* value to be passed as parameter to routine specified above */ +#endif // WLAN_WAKEUP_EVENTS + +/* If TRUE driver will go to BMPS only if host operatiing system asks to enter BMPS. +* For android wlan_hdd_cfg80211_set_power_mgmt API will be used to set host powersave*/ + v_BOOL_t isHostPsEn; + v_BOOL_t ImpsReqFailed; + v_BOOL_t ImpsReqTimerFailed; + tANI_U8 ImpsReqFailCnt; + tANI_U8 ImpsReqTimerfailCnt; + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*HDD callback to be called after receiving SET BATCH SCAN RSP from FW*/ + hddSetBatchScanReqCallback setBatchScanReqCallback; + void * setBatchScanReqCallbackContext; + /*HDD callback to be called after receiving BATCH SCAN iRESULT IND from FW*/ + hddTriggerBatchScanResultIndCallback batchScanResultCallback; + void * batchScanResultCallbackContext; +#endif + + +} tPmcInfo, *tpPmcInfo; + + +//MACRO +#define PMC_IS_READY(pMac) ( ((pMac)->pmc.pmcReady) && (STOPPED != (pMac)->pmc.pmcState) ) + + +/* Routine definitions. */ +extern eHalStatus pmcEnterLowPowerState (tHalHandle hHal); +extern eHalStatus pmcExitLowPowerState (tHalHandle hHal); +extern eHalStatus pmcEnterFullPowerState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestFullPowerState (tHalHandle hHal, tRequestFullPowerReason fullPowerReason); +extern eHalStatus pmcEnterRequestImpsState (tHalHandle hHal); +extern eHalStatus pmcEnterImpsState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestBmpsState (tHalHandle hHal); +extern eHalStatus pmcEnterBmpsState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStartUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStopUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStandbyState (tHalHandle hHal); +extern eHalStatus pmcEnterStandbyState (tHalHandle hHal); +extern tANI_BOOLEAN pmcPowerSaveCheck (tHalHandle hHal); +extern eHalStatus pmcSendPowerSaveConfigMessage (tHalHandle hHal); +extern eHalStatus pmcSendMessage (tpAniSirGlobal pMac, tANI_U16 messageType, void *pMessageData, tANI_U32 messageSize); +extern void pmcDoCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoBmpsCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoStartUapsdCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoStandbyCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern eHalStatus pmcStartTrafficTimer (tHalHandle hHal, tANI_U32 expirationTime); +extern void pmcStopTrafficTimer (tHalHandle hHal); +extern void pmcImpsTimerExpired (tHalHandle hHal); +extern void pmcTrafficTimerExpired (tHalHandle hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +extern eHalStatus pmcStartDiagEvtTimer (tHalHandle hHal); +extern void pmcStopDiagEvtTimer (tHalHandle hHal); +extern void pmcDiagEvtTimerExpired (tHalHandle hHal); +#endif + +extern void pmcExitPowerSaveTimerExpired (tHalHandle hHal); +extern tPmcState pmcGetPmcState (tHalHandle hHal); +extern const char* pmcGetPmcStateStr(tPmcState state); +extern void pmcDoDeviceStateUpdateCallbacks (tHalHandle hHal, tPmcState state); +extern eHalStatus pmcRequestEnterWowlState(tHalHandle hHal, tpSirSmeWowlEnterParams wowlEnterParams); +extern eHalStatus pmcEnterWowlState (tHalHandle hHal); +extern eHalStatus pmcRequestExitWowlState(tHalHandle hHal, + tpSirSmeWowlExitParams wowlExitParams); +extern void pmcDoEnterWowlCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +//The function will request for full power as well in addition to defer the message +extern eHalStatus pmcDeferMsg( tpAniSirGlobal pMac, tANI_U16 messageType, + void *pData, tANI_U32 size); +extern eHalStatus pmcIssueCommand(tpAniSirGlobal pMac, tANI_U32 sessionId, + eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tANI_BOOLEAN fPutToListHead); +extern eHalStatus pmcEnterImpsCheck( tpAniSirGlobal pMac ); +extern eHalStatus pmcEnterBmpsCheck( tpAniSirGlobal pMac ); +extern tANI_BOOLEAN pmcShouldBmpsTimerRun( tpAniSirGlobal pMac ); + +/* Power Save Offload Changes */ +/* Per SME Session PMC Offload Structure */ +typedef struct sPsOffloadPerSessionInfo +{ + tpAniSirGlobal pMac; + + tANI_U32 sessionId; + + /* TRUE if Sta Mode Ps is Enabled */ + tANI_BOOLEAN configStaPsEnabled; + + /* TRUE if deferred Sta Mode Ps is Enabled */ + tANI_BOOLEAN configDefStaPsEnabled; + + /* + * Indicates current uapsd status + * Enabled/Disabled/Required + */ + tUapsdStatus uapsdStatus; + + tANI_BOOLEAN uapsdSessionRequired; + + /* Current Power Save State */ + tPmcState pmcState; + + /* + * Auto Sta Ps Enable Timer + * Upon expiration of this timer + * Power Save Offload module will + * try to enable sta mode ps + */ + vos_timer_t autoPsEnableTimer; + + /* Auto Sta Ps Entry Timer Period */ + tANI_U32 autoPsEntryTimerPeriod; + + /* Full Power Request Pending */ + tANI_BOOLEAN fullPowerReqPend; + + /* + * List contains functions registered by different modules + * PsOffload Module will call this to check whether + * the particular module is ok to enable station mode power save + */ + tDblLinkList pwrsaveCheckList; + + /* + * List contains cbs passed by different modules + * to indicate power state change + */ + tDblLinkList deviceStateUpdateIndList; + + /* + * List contains cbs passed by different modules + * upon requesting full power + */ + tDblLinkList fullPowerCbList; + + /* + * List contains cbs passed by different modules + * upon requesting uapsd + */ + tDblLinkList uapsdCbList; + + /* + * Whether TDLS session allows powersave or not + */ +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t isTdlsPowerSaveProhibited; +#endif + tANI_BOOLEAN UapsdEnabled; +}tPsOffloadPerSessionInfo,*tpPsOffloadPerSessionInfo; + +typedef struct sPmcOffloadInfo +{ + /* Based on Whether BMPS is enabled or not in ini */ + tANI_BOOLEAN staPsEnabled; + + tPsOffloadPerSessionInfo pmc[PMC_SESSION_MAX]; + +}tPmcOffloadInfo,*tpPmcOffloadInfo; + +/* Power save check routine list entry. */ +typedef struct sPmcOffloadPsCheckEntry +{ + /* list links */ + tListElem link; + + /* power save check routine */ + PwrSaveCheckRoutine pwrsaveCheckCb; + + /* value to be passed as parameter to routine specified above */ + void *checkContext; + + /* Session Id */ + tANI_U32 sessionId; +} tPmcOffloadPsCheckEntry,*tpPmcOffloadPsCheckEntry; + + +/* Device Power State update indication list entry. */ +typedef struct sPmcOffloadDevStateUpdIndEntry +{ + /* list links */ + tListElem link; + + /* Callback routine to be invoked when pmc changes device state */ + PwrSaveStateChangeIndCb stateChangeCb; + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + + /* Session Id */ + tANI_U32 sessionId; +} tPmcOffloadDevStateUpdIndEntry,*tpPmcOffloadDevStateUpdIndEntry; + +/* Request full power callback routine list entry. */ +typedef struct sPmcOffloadReqFullPowerEntry +{ + /* list links */ + tListElem link; + + /* routine to call when full power is restored */ + FullPowerReqCb fullPwrCb; + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + + /* SessionId */ + tANI_U32 sessionId; +}tPmcOffloadReqFullPowerEntry,*tpPmcOffloadReqFullPowerEntry; + +/* Start U-APSD callback routine list entry. */ +typedef struct sPmcOffloadStartUapsdEntry +{ + tListElem link; /* list links */ + + /* routine to call when Uapsd Start succeeded/failed*/ + UapsdStartIndCb uapsdStartInd; + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + + /* SessionId */ + tANI_U32 sessionId; +} tPmcOffloadStartUapsdEntry,*tpPmcOffloadStartUapsdEntry; + +eHalStatus pmcOffloadOpenPerSession(tHalHandle hHal, tANI_U32 sessionId); +eHalStatus pmcOffloadClosePerSession(tHalHandle hHal, tANI_U32 sessionId); +eHalStatus pmcOffloadStartPerSession(tHalHandle hHal, tANI_U32 sessionId); +eHalStatus pmcOffloadStopPerSession(tHalHandle hHal, tANI_U32 sessionId); + +eHalStatus pmcOffloadStartAutoStaPsTimer (tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U32 timerValue); + +void pmcOffloadStopAutoStaPsTimer(tpAniSirGlobal pMac, tANI_U32 sessionId); + +eHalStatus pmcOffloadQueueRequestFullPower (tpAniSirGlobal pMac, + tANI_U32 sessionId, tRequestFullPowerReason fullPowerReason); + +eHalStatus pmcOffloadEnableStaPsHandler(tpAniSirGlobal pMac, + tANI_U32 sessionId); + +void pmcOffloadProcessResponse(tpAniSirGlobal pMac, tSirSmeRsp *pMsg); +void pmcOffloadAutoPsEntryTimerExpired(void *pmcInfo); +void pmcOffloadDoFullPowerCallbacks (tpAniSirGlobal pMac, tANI_U32 sessionId, + eHalStatus status); +void pmcOffloadDoDeviceStateUpdateCallbacks (tpAniSirGlobal pMac, + tANI_U32 sessionId, tPmcState state); +void pmcOffloadDoStartUapsdCallbacks (tpAniSirGlobal pMac, tANI_U32 sessionId, + eHalStatus status); +eHalStatus pmcOffloadDisableStaPsHandler(tpAniSirGlobal pMac, + tANI_U8 sessionId); +eHalStatus pmcOffloadEnableStaPsCheck(tpAniSirGlobal pMac, + tANI_U32 sessionId); +eHalStatus pmcOffloadExitPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId); + +eHalStatus pmcOffloadEnterPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId); +void pmcOffloadExitBmpsIndHandler(tpAniSirGlobal pMac, tSirSmeRsp *pMsg); + +eHalStatus pmcOffloadQueueStartUapsdRequest(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus pmcOffloadQueueStopUapsdRequest(tpAniSirGlobal pMac, tANI_U32 sessionId); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/pmcApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/pmcApi.h new file mode 100644 index 0000000000000..46ee179ceb1ea --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/pmcApi.h @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + +* + +* Name: pmcApi.h + +* + +* Description: Power Management Control (PMC) API definitions. + + + + + +* + +******************************************************************************/ + + +#ifndef __PMC_API_H__ + +#define __PMC_API_H__ + +//This timer value determines the default periodicity at which BMPS retries will happen +//This default value is overwritten typicaly by OS specific registry/INI values. +#define BMPS_TRAFFIC_TIMER_DEFAULT 5000 //unit = ms +#define DHCP_REMAIN_POWER_ACTIVE_THRESHOLD 12 // (12 * 5) sec = 60 seconds = 1 min + +//This timer value is used when starting the timer right after association. This value +//should be large enough to allow the auth, DHCP handshake to complete +#define BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP 8000 //unit = ms + +#define PMC_IS_CHIP_ACCESSIBLE(pmcState) ( (IMPS != (pmcState)) && (REQUEST_IMPS != (pmcState)) && \ + (STANDBY != (pmcState)) && (REQUEST_STANDBY != (pmcState)) ) + + + +/* Power events that are signaled to PMC. */ + +typedef enum ePmcPowerEvent + +{ + + ePMC_SYSTEM_HIBERNATE, /* host is entering hibernation */ + + ePMC_SYSTEM_RESUME, /* host is resuming after hibernation */ + + ePMC_HW_WLAN_SWITCH_OFF, /* Hardware WLAN Switch has been turned off */ + + ePMC_HW_WLAN_SWITCH_ON, /* Hardware WLAN Switch has been turned on */ + + ePMC_SW_WLAN_SWITCH_OFF, /* Software WLAN Switch has been turned off */ + + ePMC_SW_WLAN_SWITCH_ON, /* Software WLAN Switch has been turned on */ + + ePMC_BATTERY_OPERATION, /* host is now operating on battery power */ + + ePMC_AC_OPERATION /* host is now operating on AC power */ + +} tPmcPowerEvent; + + + + +/* Power saving modes. */ + +typedef enum ePmcPowerSavingMode + +{ + + ePMC_IDLE_MODE_POWER_SAVE, /* Idle Mode Power Save (IMPS) */ + + ePMC_BEACON_MODE_POWER_SAVE, /* Beacon Mode Power Save (BMPS) */ + + ePMC_SPATIAL_MULTIPLEX_POWER_SAVE, /* Spatial Multiplexing Power Save (SMPS) */ + + ePMC_UAPSD_MODE_POWER_SAVE, /* Unscheduled Automatic Power Save Delivery Mode */ + + ePMC_STANDBY_MODE_POWER_SAVE, /* Standby Power Save Mode */ + + ePMC_WOWL_MODE_POWER_SAVE /* Wake-on-Wireless LAN Power Save Mode */ + +} tPmcPowerSavingMode; + + + + +/* Switch states. */ + +typedef enum ePmcSwitchState + +{ + + ePMC_SWITCH_OFF, /* switch off */ + + ePMC_SWITCH_ON /* switch on */ + +} tPmcSwitchState; + + + + +/* Device power states. */ + +typedef enum ePmcPowerState + +{ + + ePMC_FULL_POWER, /* full power */ + + ePMC_LOW_POWER, /* low power */ + +} tPmcPowerState; + + + +/* PMC states. */ + +typedef enum ePmcState + +{ + + STOPPED, /* PMC is stopped */ + + FULL_POWER, /* full power */ + + LOW_POWER, /* low power */ + + REQUEST_IMPS, /* requesting IMPS */ + + IMPS, /* in IMPS */ + + REQUEST_BMPS, /* requesting BMPS */ + + BMPS, /* in BMPS */ + + REQUEST_FULL_POWER, /* requesting full power */ + + REQUEST_START_UAPSD, /* requesting Start UAPSD */ + + REQUEST_STOP_UAPSD, /* requesting Stop UAPSD */ + + UAPSD, /* in UAPSD */ + + REQUEST_STANDBY, /* requesting standby mode */ + + STANDBY, /* in standby mode */ + + REQUEST_ENTER_WOWL, /* requesting enter WOWL */ + + REQUEST_EXIT_WOWL, /* requesting exit WOWL */ + + WOWL /* Chip in WOWL mode */ + +} tPmcState; + + +/* Which beacons should be forwarded to the host. */ + +typedef enum ePmcBeaconsToForward + +{ + + ePMC_NO_BEACONS, /* none */ + + ePMC_BEACONS_WITH_TIM_SET, /* with TIM set */ + + ePMC_BEACONS_WITH_DTIM_SET, /* with DTIM set */ + + ePMC_NTH_BEACON, /* every Nth beacon */ + + ePMC_ALL_BEACONS /* all beacons */ + +} tPmcBeaconsToForward; + + + + +/* The Spatial Mulitplexing Power Save modes. */ + +typedef enum ePmcSmpsMode + +{ + + ePMC_DYNAMIC_SMPS, /* dynamic SMPS */ + + ePMC_STATIC_SMPS /* static SMPS */ + +} tPmcSmpsMode; + + + + +/* Configuration parameters for Idle Mode Power Save (IMPS). */ + +typedef struct sPmcImpsConfigParams + +{ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter IMPS only when host operating + + on battery power, TRUE if device should enter always */ + +} tPmcImpsConfigParams, *tpPmcImpsConfigParams; + + + + +/* Configuration parameters for Beacon Mode Power Save (BMPS). */ + +typedef struct sPmcBmpsConfigParams + +{ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter BMPS only when host operating on + + battery power, TRUE if device should enter always */ + + tANI_U32 txThreshold; /* transmit rate under which BMPS should be entered (frames / traffic measurement period) */ + + tANI_U32 rxThreshold; /* receive rate under which BMPS should be entered (frames / traffic measurement period) */ + + tANI_U32 trafficMeasurePeriod; /* period for BMPS traffic measurement (milliseconds) */ + + tANI_U32 bmpsPeriod; /* amount of time in low power (beacon intervals) */ + + tPmcBeaconsToForward forwardBeacons; /* which beacons should be forwarded to the host */ + + tANI_U32 valueOfN; /* the value of N when forwardBeacons is set to ePMC_NTH_BEACON */ + + tANI_BOOLEAN usePsPoll; /* TRUE if PS-POLL should be used to retrieve frames from AP, FALSE if a + + null data frame with the PM bit reset should be used */ + + tANI_BOOLEAN setPmOnLastFrame; /* TRUE to keep device in BMPS as much as possible, FALSE otherwise, TRUE means: + + 1) PM bit should be set on last pending transmit data frame + + 2) null frame with PM bit set should be transmitted after last pending receive + + frame has been processed */ + + tANI_BOOLEAN enableBeaconEarlyTermination; /* if TRUE, BET feature in RIVA + will be enabled, FALSE otherwise, TRUE means: + RXP will read the beacon header for the + TIM bit & discard the rest if set to 0, + while in BMPS */ + tANI_U8 bcnEarlyTermWakeInterval; /* This specifies how often in terms + of LI we will disable BET in order to sync + up TSF*/ + +} tPmcBmpsConfigParams, *tpPmcBmpsConfigParams; + + + + +/* Configuration parameters for Spatial Mulitplexing Power Save (SMPS). */ + +typedef struct sPmcSmpsConfigParams + +{ + + tPmcSmpsMode mode; /* mode to use */ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter SMPS only when host operating on + + battery power, TRUE if device should enter always */ + +} tPmcSmpsConfigParams, *tpPmcSmpsConfigParams; + + +/* Routine definitions. */ + +extern eHalStatus pmcOpen (tHalHandle hHal); + +extern eHalStatus pmcStart (tHalHandle hHal); + +extern eHalStatus pmcStop (tHalHandle hHal); + +extern eHalStatus pmcClose (tHalHandle hHal ); + +extern eHalStatus pmcSetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams); + +extern eHalStatus pmcGetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams); + +extern eHalStatus pmcEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcStartAutoBmpsTimer (tHalHandle hHal); + +extern eHalStatus pmcStopAutoBmpsTimer (tHalHandle hHal); + +extern eHalStatus pmcDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcQueryPowerState (tHalHandle hHal, tPmcPowerState *pPowerState, tPmcSwitchState *pHwWlanSwitchState, + + tPmcSwitchState *pSwWlanSwitchState); + +extern tANI_BOOLEAN pmcIsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext, tRequestFullPowerReason fullPowerReason); + +extern eHalStatus pmcRequestImps (tHalHandle hHal, tANI_U32 impsPeriod, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + +extern eHalStatus pmcRegisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext), + + void *checkContext); + +extern eHalStatus pmcDeregisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext)); + +extern void pmcMessageProcessor (tHalHandle hHal, tSirSmeRsp *pMsg); +extern void pmcResetImpsFailStatus (tHalHandle hHal); +extern v_BOOL_t IsPmcImpsReqFailed (tHalHandle hHal); + +extern eHalStatus pmcRequestBmps ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcStartUapsd ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcStopUapsd (tHalHandle hHal); + + +extern eHalStatus pmcRequestStandby ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcRegisterDeviceStateUpdateInd (tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + + void *callbackContext); + + +extern eHalStatus pmcDeregisterDeviceStateUpdateInd (tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)); + + +extern eHalStatus pmcReady(tHalHandle hHal); + + +void pmcDumpInit(tHalHandle hHal); + + +extern eHalStatus pmcWowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId); + + +extern eHalStatus pmcWowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId); + + +extern eHalStatus pmcEnterWowl ( + + tHalHandle hHal, + + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId); + +extern eHalStatus pmcExitWowl (tHalHandle hHal, + tpSirSmeWowlExitParams wowlExitParams); + +extern eHalStatus pmcSetHostOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn pmcSetKeepAlive + \brief Set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the keepalive. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcSetKeepAlive (tHalHandle hHal, tpSirKeepAliveReq pRequest, tANI_U8 sessionId); + +extern tANI_BOOLEAN pmcValidateConnectState( tHalHandle hHal ); + +extern tANI_BOOLEAN pmcAllowImps( tHalHandle hHal ); + + +#ifdef FEATURE_WLAN_SCAN_PNO +/*Pref netw found Cb declaration*/ +typedef void(*preferredNetworkFoundIndCallback)(void *callbackContext, tpSirPrefNetworkFoundInd pPrefNetworkFoundInd); + +extern eHalStatus pmcSetPreferredNetworkList(tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext); +extern eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_PACKET_FILTERING +// Packet Coalescing Filter Match Count Callback declaration +typedef void(*FilterMatchCountCallback)(void *callbackContext, + tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp); +extern eHalStatus pmcGetFilterMatchCount(tHalHandle hHal, FilterMatchCountCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +// GTK Offload Information Callback declaration +typedef void(*GTKOffloadGetInfoCallback)(void *callbackContext, tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp); + +/* --------------------------------------------------------------------------- + \fn pmcSetGTKOffload + \brief Set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pGtkOffload - Pointer to the GTK offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcSetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pGtkOffload, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn pmcGetGTKOffload + \brief Get GTK offload information. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to the GTK Offload Get Info response callback routine. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcGetGTKOffload(tHalHandle hHal, + GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*Set batch scan request Cb declaration*/ +typedef void(*hddSetBatchScanReqCallback)(void *callbackContext, + tSirSetBatchScanRsp *pRsp); + +/*Trigger batch scan result indication Cb declaration*/ +typedef void(*hddTriggerBatchScanResultIndCallback)(void *callbackContext, + void *pRsp); + +/* ----------------------------------------------------------------------------- + \fn pmcSetBatchScanReq + \brief Setting batch scan request in FW + \param hHal - The handle returned by macOpen. + \param sessionId - session id + \param callbackRoutine - Pointer to set batch scan request callback routine + \param calbackContext - callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ +extern eHalStatus pmcSetBatchScanReq(tHalHandle hHal, tSirSetBatchScanReq + *pRequest, tANI_U8 sessionId, hddSetBatchScanReqCallback callbackRoutine, + void *callbackContext); + +/* ----------------------------------------------------------------------------- + \fn pmcTriggerBatchScanResultInd + \brief API to pull batch scan result from FW + \param hHal - The handle returned by macOpen. + \param sessionId - session id + \param callbackRoutine - Pointer to get batch scan request callback routine + \param calbackContext - callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ +extern eHalStatus pmcTriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + hddTriggerBatchScanResultIndCallback callbackRoutine, void *callbackContext +); + + +/* ----------------------------------------------------------------------------- + \fn pmcStopBatchScanInd + \brief Stoping batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pInd - Pointer to stop batch scan indication + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +extern eHalStatus pmcStopBatchScanInd +( + tHalHandle hHal, + tSirStopBatchScanInd *pInd, + tANI_U8 sessionId +); + +#endif // FEATURE_WLAN_BATCH_SCAN + + +/* Power Save Offload Changes */ +typedef enum eUapsdStatus +{ + PMC_UAPSD_DISABLED, + PMC_UAPSD_ENABLED, + PMC_UAPSD_DISABLE_PENDING, + PMC_UAPSD_ENABLE_PENDING +}tUapsdStatus; + +/* Powersave Check Routine */ +typedef tANI_BOOLEAN (*PwrSaveCheckRoutine)(void *checkContext, + tANI_U32 sessionId); + +/* Power State Change Indication */ +typedef void (*PwrSaveStateChangeIndCb)(void *callbackContext, + tANI_U32 sessionId, + tPmcState pmcState); + +/* Full Power Req Callback */ +typedef void (*FullPowerReqCb)(void *callbackContext, + tANI_U32 sessionId, + eHalStatus status); + +/* Full Power Req Callback */ +typedef void (*UapsdStartIndCb)(void *callbackContext, + tANI_U32 sessionId, + eHalStatus status); + +eHalStatus pmcOffloadOpen(tHalHandle hHal); + +eHalStatus pmcOffloadStart(tHalHandle hHal); + +eHalStatus pmcOffloadStop(tHalHandle hHal); + +eHalStatus pmcOffloadClose(tHalHandle hHal); + +eHalStatus pmcOffloadCleanup(tHalHandle hHal, tANI_U32 sessionId); + +eHalStatus pmcOffloadConfigEnablePowerSave(tHalHandle hHal, + tPmcPowerSavingMode psMode); + +eHalStatus pmcOffloadConfigDisablePowerSave(tHalHandle hHal, + tPmcPowerSavingMode psMode); + +tPmcState pmcOffloadGetPmcState(tHalHandle hHal, tANI_U32 sessionId); + +void pmcOffloadMessageProcessor(tHalHandle hHal, tSirSmeRsp *pMsg); + +eHalStatus pmcOffloadRegisterPowerSaveCheck(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveCheckRoutine checkRoutine, + void *checkContext); + +eHalStatus pmcOffloadDeregisterPowerSaveCheck(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveCheckRoutine checkRoutine); + +eHalStatus pmcOffloadRegisterDeviceStateUpdateInd(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveStateChangeIndCb stateChangeCb, + void *callbackContext); + +eHalStatus pmcOffloadDeregisterDeviceStateUpdateInd(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveStateChangeIndCb stateChangeCb); + +eHalStatus PmcOffloadEnableStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId); + +eHalStatus PmcOffloadDisableStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId); + +eHalStatus pmcOffloadRequestFullPower(tHalHandle hHal, tANI_U32 sessionId, + FullPowerReqCb fullpwrReqCb,void *callbackContext, + tRequestFullPowerReason fullPowerReason); + +eHalStatus pmcOffloadStartUapsd(tHalHandle hHal, tANI_U32 sessionId, + UapsdStartIndCb uapsdStartIndCb, + void *callbackContext); + +eHalStatus pmcOffloadStopUapsd(tHalHandle hHal, tANI_U32 sessionId); + +#ifdef FEATURE_WLAN_TDLS +eHalStatus pmcOffloadSetTdlsProhibitBmpsStatus(tHalHandle hHal, + tANI_U32 sessionId, + v_BOOL_t val); +#endif + +tANI_BOOLEAN pmcOffloadIsPowerSaveEnabled (tHalHandle hHal, tANI_U32 sessionId, + tPmcPowerSavingMode psMode); + +eHalStatus PmcOffloadEnableDeferredStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId, + tANI_BOOLEAN isReassoc); + +eHalStatus PmcOffloadDisableDeferredStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInside.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInside.h new file mode 100644 index 0000000000000..dcd8f044dd523 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInside.h @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SMEINSIDE_H ) +#define __SMEINSIDE_H + + +/**========================================================================= + + \file smeInside.h + + \brief prototype for SME structures and APIs used insside SME + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "sirApi.h" +#include "csrInternal.h" +#include "sme_QosApi.h" +#include "smeQosInternal.h" + + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataInternal.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "sme_RrmApi.h" +#endif +ePhyChanBondState csrConvertCBIniValueToPhyCBState(v_U32_t cbIniValue); + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +#define SME_TOTAL_COMMAND 40 + + +typedef struct sGenericPmcCmd +{ + tANI_U32 size; //sizeof the data in the union, if any + tANI_U32 sessionId; + tRequestFullPowerReason fullPowerReason; + tANI_BOOLEAN fReleaseWhenDone; //if TRUE, the command shall not put back to the queue, free te memory instead. + union + { + tExitBmpsInfo exitBmpsInfo; + tSirSmeWowlEnterParams enterWowlInfo; + tSirSmeWowlExitParams exitWowlInfo; + }u; +} tGenericPmcCmd; + + +typedef struct sGenericQosCmd +{ + sme_QosWmmTspecInfo tspecInfo; + sme_QosEdcaAcType ac; + v_U8_t tspec_mask; +} tGenericQosCmd; + +typedef struct sRemainChlCmd +{ + tANI_U8 chn; + tANI_U8 phyMode; + tANI_U32 duration; + tANI_U8 isP2PProbeReqAllowed; + void* callback; + void* callbackCtx; +}tRemainChlCmd; + +typedef struct sNoACmd +{ + tP2pPsConfig NoA; +} tNoACmd; +#ifdef FEATURE_WLAN_TDLS +typedef struct TdlsSendMgmtInfo +{ + tSirMacAddr peerMac; + tANI_U8 frameType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tANI_U8 *buf; + tANI_U8 len; +} tTdlsSendMgmtCmdInfo; + +typedef struct TdlsLinkEstablishInfo +{ + tSirMacAddr peerMac; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 isResponder; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +} tTdlsLinkEstablishCmdInfo; + +typedef struct TdlsAddStaInfo +{ + eTdlsAddOper tdlsAddOper; + tSirMacAddr peerMac; + tANI_U16 capability; + tANI_U8 extnCapability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supportedRatesLen; + tANI_U8 supportedRates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap HTCap; + tANI_U8 vhtcap_present; + tSirVHTCap VHTCap; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; +} tTdlsAddStaCmdInfo; + +typedef struct TdlsDelStaInfo +{ + tSirMacAddr peerMac; +} tTdlsDelStaCmdInfo; +/* + * TDLS cmd info, CMD from SME to PE. + */ +typedef struct s_tdls_cmd +{ + tANI_U32 size; + union + { + tTdlsLinkEstablishCmdInfo tdlsLinkEstablishCmdInfo; + tTdlsSendMgmtCmdInfo tdlsSendMgmtCmdInfo; + tTdlsAddStaCmdInfo tdlsAddStaCmdInfo; + tTdlsDelStaCmdInfo tdlsDelStaCmdInfo; + }u; +} tTdlsCmd; +#endif /* FEATURE_WLAN_TDLS */ + +typedef struct tagSmeCmd +{ + tListElem Link; + eSmeCommandType command; + tANI_U32 sessionId; + union + { + tScanCmd scanCmd; + tRoamCmd roamCmd; + tWmStatusChangeCmd wmStatusChangeCmd; + tSetKeyCmd setKeyCmd; + tRemoveKeyCmd removeKeyCmd; + tGenericPmcCmd pmcCmd; + tGenericQosCmd qosCmd; +#ifdef FEATURE_OEM_DATA_SUPPORT + tOemDataCmd oemDataCmd; +#endif + tRemainChlCmd remainChlCmd; + tNoACmd NoACmd; + tAddStaForSessionCmd addStaSessionCmd; + tDelStaForSessionCmd delStaSessionCmd; +#ifdef FEATURE_WLAN_TDLS + tTdlsCmd tdlsCmd; +#endif + }u; +}tSmeCmd; + + + +/*-------------------------------------------------------------------------- + Internal to SME + ------------------------------------------------------------------------*/ + +//To get a command buffer +//Return: NULL if there no more command buffer left +tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac ); +void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority ); +void smeProcessPendingQueue( tpAniSirGlobal pMac ); +void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd); +void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tDblLinkList *pList); +tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac); +tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +tANI_BOOLEAN pmcOffloadProcessCommand(tpAniSirGlobal pMac,tSmeCmd *pCommand); +tANI_BOOLEAN pmcOffloadIsStaInPowerSave(tpAniSirGlobal pMac, tANI_U32 sessionId); + +//this function is used to abort a command where the normal processing of the command +//is terminated without going through the normal path. it is here to take care of callbacks for +//the command, if applicable. +void pmcAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); +void pmcOffloadAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tANI_BOOLEAN fStopping ); + +tANI_BOOLEAN qosProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); + +eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrRoamProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrRoamProcessWmStatusChangeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrReinitRoamCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitWmStatusChangeCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitSetKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitRemoveKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +eHalStatus csrRoamProcessSetKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrRoamProcessRemoveKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrReleaseCommandSetKey(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandRemoveKey(tpAniSirGlobal pMac, tSmeCmd *pCommand); +//eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +eHalStatus csrRoamIssueRemoveKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 roamId ); +eHalStatus csrIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand, tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower); +void csrAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); + +VOS_STATUS csrIsValidChannel(tpAniSirGlobal pMac, tANI_U8 chnNum); + +eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme); +eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme); + +#ifdef FEATURE_OEM_DATA_SUPPORT +eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand); +#endif + +eHalStatus csrProcessAddStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrProcessAddStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); +eHalStatus csrProcessDelStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrProcessDelStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); + +#ifdef WLAN_NS_OFFLOAD +/* --------------------------------------------------------------------------- + \fn pmcSetNSOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \param sessionId . Session index of the session + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetNSOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, tANI_U8 sessionId); +#endif //WLAN_NS_OFFLOAD + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus pmcSetPreferredNetworkList(tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext); +eHalStatus pmcUpdateScanParams(tHalHandle hHal, tCsrConfig *pRequest, tCsrChannel *pChannelList, tANI_U8 b11dResolved); +eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold); +#endif // FEATURE_WLAN_SCAN_PNO +eHalStatus pmcSetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced); + +tANI_BOOLEAN csrRoamGetConcurrencyConnectStatusForBmps(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_TDLS +eHalStatus csrTdlsSendMgmtReq(tHalHandle hHal, tANI_U8 sessionId, tCsrTdlsSendMgmt *tdlsSendMgmt); +VOS_STATUS csrTdlsSendLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams); +eHalStatus csrTdlsAddPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac); +eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, tCsrStaParams *pstaParams); +eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac); +eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac,tSmeCmd *pCommand ); +eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd ); +eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac,v_U16_t msg_type, + void *pMsgBuf); +#endif /* FEATURE_WLAN_TDLS */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +eHalStatus csrFlushCfgBgScanRoamChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId); +eHalStatus csrCreateBgScanRoamChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const tANI_U8 *pChannelList, + const tANI_U8 numChannels); +eHalStatus csrUpdateBgScanConfigIniChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eCsrBand eBand); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrCreateRoamScanChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels, + const eCsrBand eBand); +#endif + +ePhyChanBondState csrConvertCBIniValueToPhyCBState(v_U32_t cbIniValue); + +eHalStatus csrPsOffloadIsFullPowerNeeded(tpAniSirGlobal pMac, + tSmeCmd *pCommand, + tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower); + +void activeListCmdTimeoutHandle(void *userData); + +#endif //#if !defined( __SMEINSIDE_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInternal.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInternal.h new file mode 100644 index 0000000000000..61d325d078e57 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeInternal.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SMEINTERNAL_H ) +#define __SMEINTERNAL_H + + +/**========================================================================= + + \file smeInternal.h + + \brief prototype for SME internal structures and APIs used for SME and MAC + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "vos_diag_core_event.h" +#include "csrLinkList.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +// Mask can be only have one bit set +typedef enum eSmeCommandType +{ + eSmeNoCommand = 0, + eSmeDropCommand, + //CSR + eSmeCsrCommandMask = 0x10000, //this is not a command, it is to identify this is a CSR command + eSmeCommandScan, + eSmeCommandRoam, + eSmeCommandWmStatusChange, + eSmeCommandSetKey, + eSmeCommandRemoveKey, + eSmeCommandAddStaSession, + eSmeCommandDelStaSession, +#ifdef FEATURE_WLAN_TDLS + //eSmeTdlsCommandMask = 0x80000, //To identify TDLS commands + //These can be considered as csr commands. + eSmeCommandTdlsSendMgmt, + eSmeCommandTdlsAddPeer, + eSmeCommandTdlsDelPeer, + eSmeCommandTdlsLinkEstablish, +#endif + //PMC + eSmePmcCommandMask = 0x20000, //To identify PMC commands + eSmeCommandEnterImps, + eSmeCommandExitImps, + eSmeCommandEnterBmps, + eSmeCommandExitBmps, + eSmeCommandEnterUapsd, + eSmeCommandExitUapsd, + eSmeCommandEnterWowl, + eSmeCommandExitWowl, + eSmeCommandEnterStandby, + //QOS + eSmeQosCommandMask = 0x40000, //To identify Qos commands + eSmeCommandAddTs, + eSmeCommandDelTs, +#ifdef FEATURE_OEM_DATA_SUPPORT + eSmeCommandOemDataReq = 0x80000, //To identify the oem data commands +#endif + eSmeCommandRemainOnChannel, + eSmeCommandNoAUpdate, +} eSmeCommandType; + + +typedef enum eSmeState +{ + SME_STATE_STOP, + SME_STATE_START, + SME_STATE_READY, +} eSmeState; + +#define SME_IS_START(pMac) (SME_STATE_STOP != (pMac)->sme.state) +#define SME_IS_READY(pMac) (SME_STATE_READY == (pMac)->sme.state) + +typedef struct sStatsExtEvent { + tANI_U32 vdev_id; + tANI_U32 event_data_len; + tANI_U8 event_data[]; +} tStatsExtEvent, *tpStatsExtEvent; + +#define MAX_ACTIVE_CMD_STATS 16 + +typedef struct sActiveCmdStats { + eSmeCommandType command; + tANI_U32 reason; + tANI_U32 sessionId; + v_U64_t timestamp; +} tActiveCmdStats; + +typedef struct sSelfRecoveryStats { + tActiveCmdStats activeCmdStats[MAX_ACTIVE_CMD_STATS]; + tANI_U8 cmdStatsIndx; +} tSelfRecoveryStats; + +typedef struct tagSmeStruct +{ + eSmeState state; + vos_lock_t lkSmeGlobalLock; + tANI_U32 totalSmeCmd; + void *pSmeCmdBufAddr; + tDblLinkList smeCmdActiveList; + tDblLinkList smeCmdPendingList; + tDblLinkList smeCmdFreeList; //preallocated roam cmd list + void (*pTxPerHitCallback) (void *pCallbackContext); /* callback for Tx PER hit to HDD */ + void *pTxPerHitCbContext; + tVOS_CON_MODE currDeviceMode; +#ifdef FEATURE_WLAN_LPHB + void (*pLphbIndCb) (void *pHddCtx, tSirLPHBInd *indParam); +#endif /* FEATURE_WLAN_LPHB */ + //pending scan command list + tDblLinkList smeScanCmdPendingList; + //active scan command list + tDblLinkList smeScanCmdActiveList; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + vos_event_wlan_status_payload_type eventPayload; +#endif +#ifdef FEATURE_WLAN_CH_AVOID + void (*pChAvoidNotificationCb) (void *hdd_context, void *indi_param); +#endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + void(*pLinkLayerStatsIndCallback)(void *callbackContext, + int indType, void *pRsp); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + void (*pAutoShutdownNotificationCb) (void); +#endif + /* Maximum interfaces allowed by the host */ + tANI_U8 max_intf_count; + void (* StatsExtCallback) (void *, tStatsExtEvent *); + /* linkspeed callback */ + void (*pLinkSpeedIndCb) (tSirLinkSpeedInfo *indParam, void *pDevContext); + void *pLinkSpeedCbContext; +#ifdef FEATURE_WLAN_EXTSCAN + void (*pExtScanIndCb) (void *, const tANI_U16, void *); +#endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_NAN + void (*nanCallback) (void*, tSirNanEvent*); +#endif + v_BOOL_t enableSelfRecovery; + tCsrLinkStatusCallback linkStatusCallback; + void *linkStatusContext; +} tSmeStruct, *tpSmeStruct; + + +#endif //#if !defined( __SMEINTERNAL_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/smeQosInternal.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeQosInternal.h new file mode 100644 index 0000000000000..2f45a6e5bf60f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeQosInternal.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SMEQOSINTERNAL_H ) +#define __SMEQOSINTERNAL_H + + +/**========================================================================= + + \file smeQosInternal.h + + \brief prototype for SME QoS APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "sme_QosApi.h" +#include "smeInternal.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +#define SME_QOS_AP_SUPPORTS_APSD 0x80 + +/*--------------------------------------------------------------------------- + Enumeration of the various EDCA Access Categories: + Based on AC to ACI mapping in 802.11e spec (identical to WMM) +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_EDCA_AC_BE = 0, /* Best effort access category */ + SME_QOS_EDCA_AC_BK = 1, /* Background access category */ + SME_QOS_EDCA_AC_VI = 2, /* Video access category */ + SME_QOS_EDCA_AC_VO = 3, /* Voice access category */ + + SME_QOS_EDCA_AC_MAX +} sme_QosEdcaAcType; + + +/*--------------------------------------------------------------------------- + Enumeration of the various CSR event indication types that would be reported + by CSR +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_CSR_JOIN_REQ = 0, + SME_QOS_CSR_ASSOC_COMPLETE, + SME_QOS_CSR_REASSOC_REQ, + SME_QOS_CSR_REASSOC_COMPLETE, + SME_QOS_CSR_REASSOC_FAILURE, + SME_QOS_CSR_DISCONNECT_REQ, + SME_QOS_CSR_DISCONNECT_IND, + SME_QOS_CSR_HANDOFF_ASSOC_REQ, + SME_QOS_CSR_HANDOFF_COMPLETE, + SME_QOS_CSR_HANDOFF_FAILURE, +#ifdef WLAN_FEATURE_VOWIFI_11R + SME_QOS_CSR_PREAUTH_SUCCESS_IND, + SME_QOS_CSR_SET_KEY_SUCCESS_IND, +#endif +}sme_QosCsrEventIndType; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +typedef enum +{ + SME_QOS_DIAG_ADDTS_REQ = 0, + SME_QOS_DIAG_ADDTS_RSP, + SME_QOS_DIAG_DELTS + +}sme_QosDiagQosEventSubtype; + +typedef enum +{ + SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED = 0, + SME_QOS_DIAG_ADDTS_INVALID_PARAMS, + SME_QOS_DIAG_ADDTS_RESERVED, + SME_QOS_DIAG_ADDTS_REFUSED, + SME_QOS_DIAG_USER_REQUESTED, + SME_QOS_DIAG_DELTS_IND_FROM_AP, + +}sme_QosDiagQosEventReasonCode; + +#endif //FEATURE_WLAN_DIAG_SUPPORT +/*--------------------------------------------------------------------------- + The association information structure to be passed by CSR after assoc or + reassoc is done +---------------------------------------------------------------------------*/ +typedef struct +{ + tSirBssDescription *pBssDesc; + tCsrRoamProfile *pProfile; +} sme_QosAssocInfo; + +/*-------------------------------------------------------------------------- + External APIs for CSR - Internal to SME + ------------------------------------------------------------------------*/ + +/* -------------------------------------------------------------------------- + \brief sme_QosOpen() - This function must be called before any API call to + SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosOpen(tpAniSirGlobal pMac); + +/* -------------------------------------------------------------------------- + \brief sme_QosClose() - To close down SME QoS module. There should not be + any API call into this module after calling this function until another + call of sme_QosOpen. + + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosClose(tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief sme_QosSetParams() - This function is used by HDD to provide the + default TSPEC params to SME. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info per AC as defined above, provided by HDD + + \return eHAL_STATUS_SUCCESS - Setparam is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetParams(tpAniSirGlobal pMac, sme_QosWmmTspecInfo * pQoSInfo); + +/*-------------------------------------------------------------------------- + \brief sme_QosMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHalStatus. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf); + +/*-------------------------------------------------------------------------- + Internal APIs for CSR + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_QosValidateParams() - The SME QoS API exposed to CSR to validate AP + capabilities regarding QoS support & any other QoS parameter validation. + + \param pMac - Pointer to the global MAC parameter structure. + \param pBssDesc - Pointer to the BSS Descriptor information passed down by + CSR to PE while issuing the Join request + + \return eHAL_STATUS_SUCCESS - Validation is successful + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosValidateParams(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc); + +/*-------------------------------------------------------------------------- + \brief sme_QosCsrEventInd() - The QoS sub-module in SME expects notifications + from CSR when certain events occur as mentioned in sme_QosCsrEventIndType. + + \param pMac - Pointer to the global MAC parameter structure. + \param ind - The event occurred of type sme_QosCsrEventIndType. + \param pEvent_info - Information related to the event + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosCsrEventInd(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosCsrEventIndType ind, + void *pEvent_info); + +/*-------------------------------------------------------------------------- + \brief sme_QosGetACMMask() - The QoS sub-module API to find out on which ACs + AP mandates Admission Control (ACM = 1) + + \param pMac - Pointer to the global MAC parameter structure. + \param pSirBssDesc - The event occurred of type sme_QosCsrEventIndType. + \param pIes - the parsed IE for pSirBssDesc. This can be NULL. + + + \return a bit mask indicating for which ACs AP has ACM set to 1 + + \sa + + --------------------------------------------------------------------------*/ +v_U8_t sme_QosGetACMMask(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes); + +/* + sme_QosTriggerUapsdChange + It trigger a change on UAPSD (either disable/enable UAPSD) on current QoS flows +*/ +sme_QosStatusType sme_QosTriggerUapsdChange( tpAniSirGlobal pMac ); + +#ifdef FEATURE_WLAN_ESE +v_U8_t sme_QosEseRetrieveTspecInfo(tpAniSirGlobal pMac, v_U8_t sessionId, tTspecInfo *pTspecInfo); + +#endif + +#endif //#if !defined( __SMEQOSINTERNAL_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/smeRrmInternal.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeRrmInternal.h new file mode 100644 index 0000000000000..20a90e40e38bb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/smeRrmInternal.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SMERRMINTERNAL_H ) +#define __SMERRMINTERNAL_H + + +/**========================================================================= + + \file smeRrmInternal.h + + \brief prototype for SME RRM APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "rrmGlobal.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct sRrmConfigParam +{ + tANI_U8 rrmEnabled; + tANI_U8 maxRandnInterval; +}tRrmConfigParam, *tpRrmConfigParam; + +typedef struct sRrmNeighborReportDesc +{ + tListElem List; + tSirNeighborBssDescription *pNeighborBssDescription; + tANI_U32 roamScore; + tANI_U8 sessionId; +} tRrmNeighborReportDesc, *tpRrmNeighborReportDesc; + + +typedef void (*NeighborReportRspCallback) (void *context, VOS_STATUS vosStatus); + +typedef struct sRrmNeighborRspCallbackInfo +{ + tANI_U32 timeout; //in ms.. min value is 10 (10ms) + NeighborReportRspCallback neighborRspCallback; + void *neighborRspCallbackContext; +} tRrmNeighborRspCallbackInfo, *tpRrmNeighborRspCallbackInfo; + +typedef struct sRrmNeighborRequestControlInfo +{ + tANI_BOOLEAN isNeighborRspPending; //To check whether a neighbor req is already sent and response pending + vos_timer_t neighborRspWaitTimer; + tRrmNeighborRspCallbackInfo neighborRspCallbackInfo; +} tRrmNeighborRequestControlInfo, *tpRrmNeighborRequestControlInfo; + +typedef struct sRrmSMEContext +{ + tANI_U16 token; + tCsrBssid sessionBssId; + tANI_U8 regClass; + tCsrChannelInfo channelList; //list of all channels to be measured. + tANI_U8 currentIndex; + tAniSSID ssId; //SSID used in the measuring beacon report. + tSirMacAddr bssId; //bssid used for beacon report measurement. + tANI_U16 randnIntvl; //Randomization interval to be used in subsequent measurements. + tANI_U16 duration[SIR_ESE_MAX_MEAS_IE_REQS]; + tANI_U8 measMode[SIR_ESE_MAX_MEAS_IE_REQS]; + tRrmConfigParam rrmConfig; + vos_timer_t IterMeasTimer; + tDblLinkList neighborReportCache; + tRrmNeighborRequestControlInfo neighborReqControlInfo; + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrEseBeaconReq eseBcnReqInfo; + tANI_BOOLEAN eseBcnReqInProgress; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + tRrmMsgReqSource msgSource; +}tRrmSMEContext, *tpRrmSMEContext; + +typedef struct sRrmNeighborReq +{ + tANI_U8 no_ssid; + tSirMacSSid ssid; +}tRrmNeighborReq, *tpRrmNeighborReq; + +#endif //#if !defined( __SMERRMINTERNAL_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Api.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Api.h new file mode 100644 index 0000000000000..69d803da5625a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Api.h @@ -0,0 +1,4133 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SME_API_H ) +#define __SME_API_H + + +/**========================================================================= + + \file smeApi.h + + \brief prototype for SME APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "ccmApi.h" +#include "csrApi.h" +#include "pmcApi.h" +#include "vos_mq.h" +#include "vos_lock.h" +#include "halTypes.h" +#include "sirApi.h" +#include "btcApi.h" +#include "vos_nvitem.h" +#include "p2p_Api.h" +#include "smeInternal.h" +#include "regdomain.h" + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define SME_SUMMARY_STATS 1 +#define SME_GLOBAL_CLASSA_STATS 2 +#define SME_GLOBAL_CLASSB_STATS 4 +#define SME_GLOBAL_CLASSC_STATS 8 +#define SME_GLOBAL_CLASSD_STATS 16 +#define SME_PER_STA_STATS 32 + +#define SME_INVALID_COUNTRY_CODE "XX" + +#define SME_2_4_GHZ_MAX_FREQ 3000 + +#define SME_SET_CHANNEL_REG_POWER(reg_info_1, val) do { \ + reg_info_1 &= 0xff00ffff; \ + reg_info_1 |= ((val & 0xff) << 16); \ +} while(0) + +#define SME_SET_CHANNEL_MAX_TX_POWER(reg_info_2, val) do { \ + reg_info_2 &= 0xffff00ff; \ + reg_info_2 |= ((val & 0xff) << 8); \ +} while(0) + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct _smeConfigParams +{ + tCsrConfigParam csrConfig; +#if defined WLAN_FEATURE_VOWIFI + tRrmConfigParam rrmConfig; +#endif +#if defined FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#endif +#if defined FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + tANI_BOOLEAN fScanOffload; + tANI_U8 isAmsduSupportInAMPDU; + tANI_BOOLEAN fP2pListenOffload; + tANI_BOOLEAN pnoOffload; + tANI_U8 fEnableDebugLog; + tANI_U8 max_intf_count; + tANI_BOOLEAN enable5gEBT; + tANI_BOOLEAN enableSelfRecovery; +} tSmeConfigParams, *tpSmeConfigParams; + +typedef enum +{ + eSME_ROAM_TRIGGER_NONE = 0, + eSME_ROAM_TRIGGER_SCAN = 1, + eSME_ROAM_TRIGGER_FAST_ROAM = 2, + eSME_ROAM_TRIGGER_MAX +} tSmeFastRoamTrigger; + +#ifdef FEATURE_WLAN_TDLS + +#define SME_TDLS_MAX_SUPP_CHANNELS 128 +#define SME_TDLS_MAX_SUPP_OPER_CLASSES 32 + +typedef struct _smeTdlsPeerCapParams { + tANI_U8 isPeerResponder; + tANI_U8 peerUapsdQueue; + tANI_U8 peerMaxSp; + tANI_U8 peerBuffStaSupport; + tANI_U8 peerOffChanSupport; + tANI_U8 peerCurrOperClass; + tANI_U8 selfCurrOperClass; + tANI_U8 peerChanLen; + tANI_U8 peerChan[SME_TDLS_MAX_SUPP_CHANNELS]; + tANI_U8 peerOperClassLen; + tANI_U8 peerOperClass[SME_TDLS_MAX_SUPP_OPER_CLASSES]; + tANI_U8 prefOffChanNum; + tANI_U8 prefOffChanBandwidth; + tANI_U8 opClassForPrefOffChan; + tANI_U8 opClassForPrefOffChanIsSet; +} tSmeTdlsPeerCapParams; + +typedef enum +{ + eSME_TDLS_PEER_STATE_PEERING, + eSME_TDLS_PEER_STATE_CONNECTED, + eSME_TDLS_PEER_STATE_TEARDOWN +} eSmeTdlsPeerState; + +typedef struct _smeTdlsPeerStateParams +{ + tANI_U32 vdevId; + tSirMacAddr peerMacAddr; + tANI_U32 peerState; + tSmeTdlsPeerCapParams peerCap; +} tSmeTdlsPeerStateParams; + +#define ENABLE_CHANSWITCH 1 +#define DISABLE_CHANSWITCH 2 +#define BW_20_OFFSET_BIT 0 +#define BW_40_OFFSET_BIT 1 +#define BW_80_OFFSET_BIT 2 +#define BW_160_OFFSET_BIT 3 + +typedef struct _smeTdlsChanSwitchParams +{ + tANI_U32 vdev_id; + tSirMacAddr peer_mac_addr; + tANI_U16 tdls_off_ch_bw_offset;/* Target Off Channel Bandwidth offset */ + tANI_U8 tdls_off_channel; /* Target Off Channel */ + tANI_U8 tdls_off_ch_mode; /* TDLS Off Channel Mode */ + tANI_U8 is_responder; /* is peer responder or initiator */ +} tSmeTdlsChanSwitchParams; +#endif /* FEATURE_WLAN_TDLS */ + +/* Thermal Mitigation*/ + +typedef struct { + u_int16_t smeMinTempThreshold; + u_int16_t smeMaxTempThreshold; +} tSmeThermalLevelInfo; + +#define SME_MAX_THERMAL_LEVELS (4) + +typedef struct { + /* Array of thermal levels */ + tSmeThermalLevelInfo smeThermalLevels[SME_MAX_THERMAL_LEVELS]; + u_int8_t smeThermalMgmtEnabled; + u_int32_t smeThrottlePeriod; +} tSmeThermalParams; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief sme_Open() - Initialze all SME modules and put them at idle state + + The function initializes each module inside SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are at idle state ready to start. + + smeOpen must be called before any other SME APIs can be involved. + smeOpen must be called after macOpen. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully initialized. + + Other status means SME is failed to be initialized + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Open(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \breif sme_init_chan_list() - Initialize sme channel info + + This function initializes sme channel information which can + be known only after getting the regulatory information which, for discrete, + will come from target after the fw got downloaded. For ISOC, this information + will be available in nv. + + \param hal - The handle returned by macOpen. + + \param alpha2 - Country code passed by the hdd context. + + \param cc_src - Country code source passed by the hdd context. + + \return eHAL_STATUS_SUCCESS - SME is successfully initialized. + + Other status means SME is failed to be initialized + \sa + +---------------------------------------------------------------------------*/ +eHalStatus sme_init_chan_list(tHalHandle hal, v_U8_t *alpha2, + COUNTRY_CODE_SOURCE cc_src); + +/*-------------------------------------------------------------------------- + + \brief sme_Close() - Release all SME modules and their resources. + + The function release each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at closed state. + + No SME APIs can be involved after sme_Close except sme_Open. + sme_Close must be called before macClose. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully close. + + Other status means SME is failed to be closed but caller still cannot + call any other SME functions except smeOpen. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Close(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_Start() - Put all SME modules at ready state. + + The function starts each module in SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are ready to run. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is ready. + + Other status means SME is failed to start. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Start(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_Stop() - Stop all SME modules and put them at idle state + + The function stops each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at idle state ready to start. + + + \param hHal - The handle returned by macOpen. + + \param tHalStopType - reason for stopping + + \return eHAL_STATUS_SUCCESS - SME is stopped. + + Other status means SME is failed to stop but caller should still consider + SME is stopped. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Stop(tHalHandle hHal, tHalStopType stopType); + + +/*-------------------------------------------------------------------------- + + \brief sme_OpenSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + \param callback - A pointer to the function caller specifies for roam/connect status indication + \param pContext - The context passed with callback + \param pSelfMacAddr - Caller allocated memory filled with self MAC address (6 bytes) + \param pbSessionId - pointer to a caller allocated buffer for returned session ID + + \return eHAL_STATUS_SUCCESS - session is opened. sessionId returned. + + Other status means SME is failed to open the session. + eHAL_STATUS_RESOURCES - no more session available. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_OpenSession(tHalHandle hHal, csrRoamCompleteCallback callback, + void *pContext, tANI_U8 *pSelfMacAddr, + tANI_U8 *pbSessionId, tANI_U32 type, + tANI_U32 subType); + +/*-------------------------------------------------------------------------- + + \brief sme_SetCurrDeviceMode() - Sets the current operating device mode. + \param hHal - The handle returned by macOpen. + \param currDeviceMode - Current operating device mode. + --------------------------------------------------------------------------*/ + +void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode); + +/*-------------------------------------------------------------------------- + + \brief sme_CloseSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + + \param sessionId - A previous opened session's ID. + + \return eHAL_STATUS_SUCCESS - session is closed. + + Other status means SME is failed to open the session. + eHAL_STATUS_INVALID_PARAMETER - session is not opened. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId, + csrRoamSessionCloseCallback callback, void *pContext); + + + +/*-------------------------------------------------------------------------- + + \brief sme_UpdateConfig() - Change configurations for all SME moduels + + The function updates some configuration for modules in SME, CCM, CSR, etc + during SMEs close -> open sequence. + + Modules inside SME apply the new configuration at the next transaction. + + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams); + +#ifdef FEATURE_WLAN_SCAN_PNO +/*-------------------------------------------------------------------------- + + \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA. + + It is used at driver start up to inform RIVA of the default channel + configuration. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. + + Other status means SME is failed to update the channel config. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateChannelConfig(tHalHandle hHal); + +#endif // FEATURE_WLAN_SCAN_PNLO + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/*-------------------------------------------------------------------------- + + \brief sme_SetPlmRequest() - send PLM request to firmware + + It is used to initiate PLM request + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME could successfully sent PLM command + + Other status means SME is failed to send plm command + + --------------------------------------------------------------------------*/ +eHalStatus sme_SetPlmRequest(tHalHandle hHal, tpSirPlmReq pPlm); + +#endif + +/*-------------------------------------------------------------------------- + + \brief sme_set11dinfo() - Set the 11d information about valid channels + and there power using information from nvRAM + This function is called only for AP. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams); + +/*-------------------------------------------------------------------------- + + \brief sme_getSoftApDomain() - Get the current regulatory domain of softAp. + + This is a synchronuous call + + \param hHal - The handle returned by HostapdAdapter. + \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp. + + \return eHAL_STATUS_SUCCESS - SME successfully completed the request. + + Other status means, failed to get the current regulatory domain. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_getSoftApDomain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp); + +eHalStatus sme_setRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode); + + +/* --------------------------------------------------------------------------- + \fn sme_ChangeConfigParams + \brief The SME API exposed for HDD to provide config params to SME during + SMEs stop -> start sequence. + + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + + \Param + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ChangeConfigParams(tHalHandle hHal, + tCsrUpdateConfigParam *pUpdateConfigParam); + +/*-------------------------------------------------------------------------- + + \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform that the NIC + is ready tio run. + + The function is called by HDD at the end of initialization stage so PE/HAL can enable the NIC + to running state. + + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE successfully. + + Other status means SME failed to send the message to PE. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_HDDReadyInd(tHalHandle hHal); + + +/*-------------------------------------------------------------------------- + + \brief sme_ProcessMsg() - The main message processor for SME. + + The function is called by a message dispatcher when to process a message + targeted for SME. + + + \param hHal - The handle returned by macOpen. + \param pMsg - A pointer to a caller allocated object of tSirMsgQ. + + \return eHAL_STATUS_SUCCESS - SME successfully process the message. + + Other status means SME failed to process the message. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg); + +v_VOID_t sme_FreeMsg( tHalHandle hHal, vos_msg_t* pMsg ); + +/* --------------------------------------------------------------------------- + \fn sme_ScanRequest + \brief a wrapper function to Request a 11d or full scan from CSR. + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not + be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanRequest(tHalHandle hHal, tANI_U8 sessionId, tCsrScanRequest *, + tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanSetBGScanparams + \brief a wrapper function to request CSR to set BG scan params in PE + \param pScanReq - BG scan request structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanSetBGScanparams(tHalHandle hHal, tANI_U8 sessionId, tCsrBGScanRequest *pScanReq); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetResult + \brief a wrapper function to request scan results from CSR. + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetResult(tHalHandle hHal, tANI_U8 sessionId, tCsrScanResultFilter *pFilter, + tScanResultHandle *phResult); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanFlushResult + \brief a wrapper function to request CSR to clear scan results. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanFlushResult(tHalHandle hHal, tANI_U8 sessionId); + +/* + * --------------------------------------------------------------------------- + * \fn sme_FilterScanResults + * \brief a wrapper function to request CSR to filter the scan results based + * on valid chennel list. + * \param hHal - The handle returned by macOpen. + * \param sessionId - the sessionId returned by sme_OpenSession. + * \return eHalStatus + *--------------------------------------------------------------------------- + */ +eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId); + +eHalStatus sme_ScanFlushP2PResult(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetFirst + \brief a wrapper function to request CSR to returns the first element of + scan result. + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetFirst(tHalHandle, + tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetNext + \brief a wrapper function to request CSR to returns the next element of + scan result. It can be called without calling csrScanResultGetFirst + first + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetNext(tHalHandle, + tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultPurge + \brief a wrapper function to request CSR to remove all items(tCsrScanResult) + in the list and free memory for each item + \param hScanResult - returned from csrScanGetResult. hScanResult is + considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetPMKIDCandidateList + \brief a wrapper function to return the PMKID candidate list + \param pPmkidList - caller allocated buffer point to an array of + tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tPmkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, + not sizeof(tPmkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetPMKIDCandidateList(tHalHandle hHal, tANI_U8 sessionId, + tPmkidCandidateInfo *pPmkidList, + tANI_U32 *pNumItems ); + + +/*---------------------------------------------------------------------------- + \fn sme_RoamRegisterLinkQualityIndCallback + + \brief + a wrapper function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus sme_RoamRegisterLinkQualityIndCallback(tHalHandle hHal, tANI_U8 sessionId, + csrRoamLinkQualityIndCallback callback, + void *pContext); + + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnect + \brief a wrapper function to request CSR to inititiate an association + \param sessionId - the sessionId returned by sme_OpenSession. + \param pProfile - can be NULL to join to any open ones + \param pRoamId - to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnect(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamReassoc + \brief a wrapper function to request CSR to inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamReassoc(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce); + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnectToLastProfile + \brief a wrapper function to request CSR to disconnect and reconnect with + the same profile + \return eHalStatus. It returns fail if currently connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnectToLastProfile(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnect + \brief a wrapper function to request CSR to disconnect from a network + \param reason -- To indicate the reason for disconnecting. Currently, only + eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason); + +/* --------------------------------------------------------------------------- + \fn sme_RoamStopBss + \brief a wrapper function to request CSR to stop bss + \param sessionId - sessionId of SoftAP + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamStopBss(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetAssociatedStas + \brief To probe the list of associated stations from various modules of CORE stack. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param modId - Module from whom list of associtated stations is to be probed. + If an invalid module is passed then by default VOS_MODULE_ID_PE will be probed + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetAssociatedStas(tHalHandle hHal, tANI_U8 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnectSta + \brief To disassociate a station. This is an asynchronous API. + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnectSta(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 *pPeerMacAddr); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDeauthSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDeauthSta(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pPeerMacAddr); + +/* --------------------------------------------------------------------------- + \fn sme_RoamTKIPCounterMeasures + \brief To start or stop TKIP counter measures. This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param bEnable - Flag to start/stop TKIP countermeasures + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamTKIPCounterMeasures(tHalHandle hHal, tANI_U8 sessionId, tANI_BOOLEAN bEnable); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetWpsSessionOverlap + \brief To get the WPS PBC session overlap information. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetWpsSessionOverlap(tHalHandle hHal, tANI_U8 sessionId, + void *pUsrContext, void *pfnSapEventCallback, + v_MACADDR_t pRemoveMac); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectState + \brief a wrapper function to request CSR to return the current connect state + of Roaming + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectState(tHalHandle hHal, tANI_U8 sessionId, eCsrConnectState *pState); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectProfile + \brief a wrapper function to request CSR to return the current connect + profile. Caller must call csrRoamFreeConnectProfile after it is done + and before reuse for another csrRoamGetConnectProfile call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectProfile(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn sme_RoamFreeConnectProfile + \brief a wrapper function to request CSR to free and reinitialize the + profile returned previously by csrRoamGetConnectProfile. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamFreeConnectProfile(tHalHandle hHal, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn sme_RoamSetPMKIDCache + \brief a wrapper function to request CSR to return the PMKID candidate list + \param pPMKIDCache - caller allocated buffer point to an array of + tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo + allocated when retruning, this is either the number + needed or number of items put into pPMKIDCache + \param update_entire_cache - if TRUE, then it overwrites the entire cache + with pPMKIDCache, else it updates entry by + entry without deleting the old entries. + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of + tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, + not sizeof(tPmkidCacheInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPMKIDCache( tHalHandle hHal, tANI_U8 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/* --------------------------------------------------------------------------- + * \fn sme_RoamSetPSK_PMK + * \brief a wrapper function to request CSR to save PSK/PMK + * This is a synchronous call. + * \param hHal - Global structure + * \param sessionId - SME sessionId + * \param pPSK_PMK - pointer to an array of Psk[]/Pmk[] + * \param pmk_len - Length could be only 16 bytes in case if LEAP + * connections. Need to pass this information to + * firmware. + *\return eHalStatus -status whether PSK/PMK is set or not + * ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPSK_PMK (tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pPSK_PMK, size_t pmk_len); +#endif +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityReqIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR + passes to PE to JOIN request or START_BSS request + This is a synchronuous call. + \param sessionId - returned by sme_OpenSession. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityReqIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityRspIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE from + the beacon or probe rsp if connected + \param sessionId - returned by sme_OpenSession. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityRspIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType); + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumPMKIDCache + \brief a wrapper function to request CSR to return number of PMKID cache + entries + \return tANI_U32 - the number of PMKID cache entries + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumPMKIDCache(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetPMKIDCache + \brief a wrapper function to request CSR to return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of + pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if + any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetPMKIDCache(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pNum, + tPmkidCacheInfo *pPmkidCache); + +/* --------------------------------------------------------------------------- + \fn sme_GetConfigParam + \brief a wrapper function that HDD calls to get the global settings + currently maintained by CSR. + \param pParam - caller allocated memory + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam); + +/* --------------------------------------------------------------------------- + \fn sme_GetStatistics + \brief a wrapper function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + The order in which you set the bits in the statsMask for requesting + different type of stats is: + + eCsrSummaryStats = bit 0 + eCsrGlobalClassAStats = bit 1 + eCsrGlobalClassBStats = bit 2 + eCsrGlobalClassCStats = bit 3 + eCsrGlobalClassDStats = bit 4 + eCsrPerStaStats = bit 5 + + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update, 0 means it's an one + time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param sessionId - sme session interface + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn smeGetTLSTAState + \helper function to get teh TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 smeGetTLSTAState(tHalHandle hHal, tANI_U8 staId); + +/* --------------------------------------------------------------------------- + \fn sme_GetRssi + \brief a wrapper function that client calls to register a callback to get + RSSI + + \param hHal - HAL handle for device + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid of the connected session + \param lastRSSI - RSSI value at time of request. In case fw cannot provide + RSSI, do not hold up but return this value. + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, tANI_S8 lastRSSI, + void *pContext, void* pVosContext); + +/* --------------------------------------------------------------------------- + \fn sme_GetSnr + \brief a wrapper function that client calls to register a callback to get + SNR from FW + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid of the connected session + \param pContext - user context to be passed back along with the callback + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetSnr(tHalHandle hHal, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext); +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus sme_GetRoamRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void *pContext, + void* pVosContext); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn sme_GetTsmStats + \brief a wrapper function that client calls to register a callback to get + TSM Stats + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetTsmStats(tHalHandle hHal, + tCsrTsmStatsCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext, tANI_U8 tid); +/* --------------------------------------------------------------------------- + \fn sme_SetCCKMIe + \brief function to store the CCKM IE passed from supplicant and use it + while packing reassociation request + \param hHal - HAL handle for device + \param pCckmIe - pointer to CCKM IE data + \param pCckmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetCCKMIe(tHalHandle hHal, + tANI_U8 sessionId, + tANI_U8 *pCckmIe, + tANI_U8 cckmIeLen); +/* --------------------------------------------------------------------------- + \fn sme_SetEseBeaconRequest + \brief function to set ESE beacon request parameters + \param hHal - HAL handle for device + \param pEseBcnReq - pointer to ESE beacon request + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId, + const tCsrEseBeaconReq* pEseBcnReq); + +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetInt + \brief a wrapper function that HDD calls to set parameters in CFG. + \param cfgId - Configuration Parameter ID (type) for STA. + \param ccmValue - The information related to Configuration Parameter ID + which needs to be saved in CFG + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetStr + \brief a wrapper function that HDD calls to set parameters in CFG. + \param cfgId - Configuration Parameter ID (type) for STA. + \param pStr - Pointer to the byte array which carries the information needs + to be saved in CFG + \param length - Length of the data to be saved + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, + tANI_U32 length, tCcmCfgSetCallback callback, + eAniBoolean toBeSaved) ; + + +/* --------------------------------------------------------------------------- + \fn sme_GetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields, changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. Also, make sure to call this function to get the current profile + fields before calling the reassoc. So that pModifyProfileFields will have + all the latest values plus the one(s) has been updated as part of reassoc + request. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetModifyProfileFields(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields); + + +/*-------------------------------------------------------------------------- + \fn sme_SetConfigPowerSave + \brief Wrapper fn to change power save configuration in SME (PMC) module. + For BMPS related configuration, this function also updates the CFG + and sends a message to FW to pick up the new values. Note: Calling + this function only updates the configuration and does not enable + the specified power save mode. + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode being modified + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_SetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams); + +/*-------------------------------------------------------------------------- + \fn sme_GetConfigPowerSave + \brief Wrapper fn to retireve power save configuration in SME (PMC) module + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams); + +/* --------------------------------------------------------------------------- + \fn sme_EnablePowerSave + \brief Enables one of the power saving modes. This API does not cause a + device state change. This is purely a configuration API. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_EnablePowerSave ( + tHalHandle hHal, + tPmcPowerSavingMode psMode); + +/* --------------------------------------------------------------------------- + \fn sme_DisablePowerSave + \brief Disables one of the power saving modes.Disabling does not imply + that device will be brought out of the current PS mode. This is + purely a configuration API. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to disable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DisablePowerSave ( + tHalHandle hHal, + tPmcPowerSavingMode psMode); + + /* --------------------------------------------------------------------------- + \fn sme_SetHostPowerSave + \brief The BMPS logic is controlled by the User level Apps + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_SetHostPowerSave ( + tHalHandle hHal, + v_BOOL_t psMode); + +/* --------------------------------------------------------------------------- + \fn sme_StartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StartAutoBmpsTimer ( tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_StopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the sme_RequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StopAutoBmpsTimer ( tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_QueryPowerState + \brief Returns the current power state of the device. + \param hHal - The handle returned by macOpen. + \param pPowerState - pointer to location to return power state + \param pSwWlanSwitchState - ptr to location to return SW WLAN Switch state + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_QueryPowerState ( + tHalHandle hHal, + tPmcPowerState *pPowerState, + tPmcSwitchState *pSwWlanSwitchState); + +/* --------------------------------------------------------------------------- + \fn sme_IsPowerSaveEnabled + \brief Checks if the device is able to enter a particular power save mode + This does not imply that the device is in a particular PS mode + \param hHal - The handle returned by macOpen. + \param sessionId - sme sessionid + \param psMode - the power saving mode + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern tANI_BOOLEAN sme_IsPowerSaveEnabled ( + tHalHandle hHal, + tANI_U32 sessionId, + tPmcPowerSavingMode psMode); + +/* --------------------------------------------------------------------------- + \fn sme_RequestFullPower + \brief Request that the device be brought to full power state. + Note 1: If "fullPowerReason" specificied in this API is set to + eSME_FULL_PWR_NEEDED_BY_HDD, PMC will clear any "buffered wowl" requests + and also clear any "buffered BMPS requests by HDD". Assumption is that since + HDD is requesting full power, we need to undo any previous HDD requests for + BMPS (using sme_RequestBmps) or WoWL (using sme_EnterWoWL). If the reason is + specified anything other than above, the buffered requests for BMPS and WoWL + will not be cleared. + Note 2: Requesting full power (no matter what the fullPowerReason is) doesn't + disable the "auto bmps timer" (if it is enabled) or clear any "buffered uapsd + request". + Note 3: When the device finally enters Full Power PMC will start a timer + if any of the following holds true: + - Auto BMPS mode is enabled + - Uapsd request is pending + - HDD's request for BMPS is pending + - HDD's request for WoWL is pending + On timer expiry PMC will attempt to put the device in BMPS mode if following + (in addition to those listed above) holds true: + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \param - fullPowerReason - Reason why this API is being invoked. SME needs to + distinguish between BAP and HDD requests + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestFullPower ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, + tRequestFullPowerReason fullPowerReason); + +/* --------------------------------------------------------------------------- + \fn sme_RequestBmps + \brief Request that the device be put in BMPS state. Request will be + accepted only if BMPS mode is enabled and power save check routine + passes. Only HDD should invoke this API. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought to BMPS state + eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_SetDHCPTillPowerActiveFlag + \brief Sets/Clears DHCP related flag in PMC to disable/enable auto BMPS + entry by PMC + \param hHal - The handle returned by macOpen. + ---------------------------------------------------------------------------*/ +void sme_SetDHCPTillPowerActiveFlag(tHalHandle hHal, tANI_U8 flag); + + +/* --------------------------------------------------------------------------- + \fn sme_StartUapsd + \brief Request that the device be put in UAPSD state. If the device is in + Full Power it will be put in BMPS mode first and then into UAPSD + mode. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + eHAL_STATUS_SUCCESS - device is in UAPSD state + eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state + eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state + eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_StopUapsd + \brief Request that the device be put out of UAPSD state. Device will be + put in in BMPS state after stop UAPSD completes. Buffered requests for + UAPSD will be cleared after this. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StopUapsd (tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_RequestStandby + \brief Request that the device be put in standby. It is HDD's responsibility + to bring the chip to full power and do a discconnect before calling + this API. Request for standby will be rejected if STA is associated + to an AP. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_RegisterPowerSaveCheck + \brief Register a power save check routine that is called whenever + the device is about to enter one of the power save modes. + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RegisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext), void *checkContext); + +/* --------------------------------------------------------------------------- + \fn sme_Register11dScanDoneCallback + \brief Register a routine of type csrScanCompleteCallback which is + called whenever an 11d scan is done + \param hHal - The handle returned by macOpen. + \param callback - 11d scan complete routine to be registered + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_Register11dScanDoneCallback ( + tHalHandle hHal, + csrScanCompleteCallback); + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterPowerSaveCheck + \brief Deregister a power save check routine + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DeregisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext)); + +/* --------------------------------------------------------------------------- + \fn sme_RegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RegisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DeregisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)); + +/* --------------------------------------------------------------------------- + \fn sme_WowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_WowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_WowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_WowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_EnterWowl + \brief This is the API to request entry into WOWL mode. + WoWLAN works on top of BMPS mode. If the device is not in BMPS mode, + SME will will cache the information that WOWL has been requested and + attempt to put the device in BMPS first. On entry into BMPS, SME will + enter the WOWL mode. + Note 1: After WoWL request is accepted, If module other than HDD requests + full power BEFORE WoWL request is completed, PMC will buffer the WoWL request + and attempt to put the chip into BMPS+WOWL based on a timer. + Note 2: Buffered request for WoWL will be cleared immedisately AFTER "enter Wowl" + completes or if HDD requests full power or if sme_ExitWoWL API is invoked. + Note 3: Both UAPSD and WOWL work on top of BMPS. On entry into BMPS, SME + will give priority to UAPSD and enable only UAPSD if both UAPSD and WOWL + are required. Currently there is no requirement or use case to support UAPSD + and WOWL at the same time. + Note 4. Request for WoWL is rejected if there is a pending UAPSD request. + Note 5. Request for WoWL is rejected if BMPS is disabled. + + \param hHal - The handle returned by macOpen. + \param enterWowlCallbackRoutine - Callback routine provided by HDD. + Used for success/failure notification by SME + \param enterWowlCallbackContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \param wakeReasonIndCB - Callback routine provided by HDD. + Used for Wake Reason Indication by SME + \param wakeReasonIndCBContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \return eHalStatus + eHAL_STATUS_SUCCESS Device is already in WoWLAN mode + eHAL_STATUS_FAILURE Device cannot enter WoWLAN mode. + eHAL_STATUS_PMC_PENDING Request accepted. SME will enable WOWL when BMPS + mode is entered. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_EnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. Any Buffered request for WoWL will be cleared after this API. + \param hHal - The handle returned by macOpen. + \param wowlExitParams - Carries info on which smesession wowl exit + is requested. + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. This can happen + only if the previous "Enter WOWL" transaction has + not even completed. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_ExitWowl (tHalHandle hHal, tpSirSmeWowlExitParams wowlExitParams); + +/* --------------------------------------------------------------------------- + + \fn sme_RoamSetKey + + \brief To set encryption key. This function should be called only when connected + This is an asynchronous API. + + \param pSetKeyInfo - pointer to a caller allocated object of tCsrSetContextInfo + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetKey(tHalHandle, tANI_U8 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + + \fn sme_RoamRemoveKey + + \brief To set encryption key. This is an asynchronous API. + + \param pRemoveKey - pointer to a caller allocated object of tCsrRoamRemoveKey + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamRemoveKey(tHalHandle, tANI_U8 sessionId, tCsrRoamRemoveKey *pRemoveKey, tANI_U32 *pRoamId); + + +/* --------------------------------------------------------------------------- + + \fn sme_GetCountryCode + + \brief To return the current country code. If no country code is applied, default country code is + used to fill the buffer. + If 11d supported is turned off, an error is return and the last applied/default country code is used. + This is a synchronous API. + + \param pBuf - pointer to a caller allocated buffer for returned country code. + + \param pbLen For input, this parameter indicates how big is the buffer. + Upon return, this parameter has the number of bytes for country. If pBuf + doesn't have enough space, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U8 *pbLen); + +/* --------------------------------------------------------------------------- + + \fn sme_SetCountryCode + + \brief To change the current/default country code. + If 11d supported is turned off, an error is return. + This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for the country code. + + \param pfRestartNeeded A pointer to caller allocated memory, upon successful return, it indicates + whether a reset is required. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetCountryCode(tHalHandle hHal, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn sme_ResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. This is a synchronous API. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_ResetCountryCodeInformation(tHalHandle hHal, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn sme_GetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed byte count. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf. If pbuf is NULL, as input, *pbLen should be 0. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U32 *pbLen); + +/* --------------------------------------------------------------------------- + \fn sme_GetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. This is a synchronous API. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. The function fails if 11d support is turned off. + \param pDomain - Caller allocated buffer to return the current domain. + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t *pDomain); + +/* --------------------------------------------------------------------------- + \fn sme_SetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. This is a synchronous API. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See v_REGDOMAIN_t for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + + \fn sme_GetRegulatoryDomainForCountry + + \brief To return a regulatory domain base on a country code. This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for input country code. + + \param pDomainId Upon successful return, it is the domain that country belongs to. + If it is NULL, returning success means that the country code is known. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetRegulatoryDomainForCountry(tHalHandle hHal, tANI_U8 *pCountry, v_REGDOMAIN_t *pDomainId); + + + +/* --------------------------------------------------------------------------- + + \fn sme_GetSupportedRegulatoryDomains + + \brief To return a list of supported regulatory domains. This is a synchronous API. + + \param pDomains - pointer to a caller allocated buffer for returned regulatory domains. + + \param pNumDomains For input, this parameter indicates howm many domains pDomains can hold. + Upon return, this parameter has the number for supported domains. If pDomains + doesn't have enough space for all the supported domains, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedRegulatoryDomains(tHalHandle hHal, v_REGDOMAIN_t *pDomains, tANI_U32 *pNumDomains); + +//some support functions +tANI_BOOLEAN sme_Is11dSupported(tHalHandle hHal); +tANI_BOOLEAN sme_Is11hSupported(tHalHandle hHal); +tANI_BOOLEAN sme_IsWmmSupported(tHalHandle hHal); +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus sme_ScanGetBaseChannels( tHalHandle hHal, tCsrChannelInfo * pChannelInfo ); + +typedef void ( *tSmeChangeCountryCallback)(void *pContext); +/* --------------------------------------------------------------------------- + + \fn sme_ChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param sendRegHint If we want to send reg hint to nl80211 + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeCountryCode( tHalHandle hHal, + tSmeChangeCountryCallback callback, + tANI_U8 *pCountry, + void *pContext, + void* pVosContext, + tAniBool countryFromUserSpace, + tAniBool sendRegHint); + +/* --------------------------------------------------------------------------- + + \fn sme_GenericChangeCountryCode + + \brief Generic API to change country code + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param reg_domain Regulatory domain for the new country code + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GenericChangeCountryCode( tHalHandle hHal, + tANI_U8 *pCountry, + v_REGDOMAIN_t reg_domain); + +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStartInd + + \brief Indicate FW about DHCP start event. + + \param hHal - The handle returned by macOpen. + + \param device_mode the mode of the device + + \param macAddr the MAC address of the adapter + + \param sessionId session ID + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ + +eHalStatus sme_DHCPStartInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 *macAddr, + tANI_U8 sessionId ); + +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStopInd + + \brief Indicate FW about DHCP stop event. + + \param hHal - The handle returned by macOpen. + + \param device_mode the mode of the device + + \param macAddr the MAC address of the adapter + + \param sessionId session ID + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStopInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 *macAddr, + tANI_U8 sessionId ); + +/* --------------------------------------------------------------------------- + \fn sme_BtcSignalBtEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtcBtEvent - Pointer to a caller allocated object of type tSmeBtEvent + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE BT Event not passed to HAL. This can happen + if driver has not yet been initialized or if BTC + Events Layer has been disabled. + VOS_STATUS_SUCCESS BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSignalBtEvent (tHalHandle hHal, tpSmeBtEvent pBtcBtEvent); + +/* --------------------------------------------------------------------------- + \fn sme_BtcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + Calling it after sme_HDDReadyInd is recommended. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); + +/* --------------------------------------------------------------------------- + \fn sme_BtcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type tSmeBtcConfig. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); + +/* --------------------------------------------------------------------------- + \fn sme_SetCfgPrivacy + \brief API to set configure privacy parameters + \param hHal - The handle returned by macOpen. + \param pProfile - Pointer CSR Roam profile. + \param fPrivacy - This parameter indicates status of privacy + + \return void + ---------------------------------------------------------------------------*/ +void sme_SetCfgPrivacy(tHalHandle hHal, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy); + +/* --------------------------------------------------------------------------- + \fn sme_getRecoveryStats + \brief API to get recovery stats for SME stuck cmds. + \param hHal - The handle returned by macOpen. + + \return void + ---------------------------------------------------------------------------*/ +void sme_getRecoveryStats(tHalHandle hHal); + +#if defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + \fn sme_NeighborReportRequest + \brief API to request neighbor report. + \param hHal - The handle returned by macOpen. + \param pRrmNeighborReq - Pointer to a caller allocated object of type + tRrmNeighborReq. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_NeighborReportRequest (tHalHandle hHal, tANI_U8 sessionId, + tpRrmNeighborReq pRrmNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo); +#endif + +VOS_STATUS sme_GetWcnssWlanCompiledVersion(tHalHandle hHal, + tSirVersionType *pVersion); +VOS_STATUS sme_GetWcnssWlanReportedVersion(tHalHandle hHal, + tSirVersionType *pVersion); +VOS_STATUS sme_GetWcnssSoftwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); +VOS_STATUS sme_GetWcnssHardwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); + +#ifdef FEATURE_WLAN_WAPI +/* --------------------------------------------------------------------------- + \fn sme_ScanGetBKIDCandidateList + \brief a wrapper function to return the BKID candidate list + \param pBkidList - caller allocated buffer point to an array of + tBkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tBkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tBkidCandidateInfo. + \Note: pNumItems is a number of tBkidCandidateInfo, + not sizeof(tBkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetBKIDCandidateList(tHalHandle hHal, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, + tANI_U32 *pNumItems ); +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/******************************************************************************************** + Oem data related modifications +*********************************************************************************************/ +/* --------------------------------------------------------------------------- + \fn sme_OemDataReq + \param sessionId - session id of session to be used for oem data req. + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext); + +/* --------------------------------------------------------------------------- + \fn sme_getOemDataRsp + \param pOemDataRsp - A pointer to the response object + \param pOemDataReqID - pointer to an object to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_getOemDataRsp(tHalHandle hHal, + tOemDataRsp **pOemDataRsp); + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + + + +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPSIE + + \brief To update AP's WPS IE. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPWPSIES - pointer to a caller allocated object of tCsrRoamAPWPSIES + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ + +eHalStatus sme_RoamUpdateAPWPSIE(tHalHandle, tANI_U8 sessionId, tSirAPWPSIEs *pAPWPSIES); +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPARSNIEs + + \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs + + \return eHalStatus SUCCESS + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie); + +/* --------------------------------------------------------------------------- + + sme_ChangeMCCBeaconInterval + + \brief To update P2P-GO's beacon Interval. + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId); + + + +/* --------------------------------------------------------------------------- + \fn sme_sendBTAmpEvent + \brief API to send the btAMPstate to FW + \param hHal - The handle returned by macOpen. + \param btAmpEvent -- btAMP event + \return eHalStatus SUCCESS + FAILURE or RESOURCES The API finished and failed. + +--------------------------------------------------------------------------- */ + +eHalStatus sme_sendBTAmpEvent(tHalHandle hHal, tSmeBtAmpEvent btAmpEvent); + + + +/* --------------------------------------------------------------------------- + \fn sme_SetHostOffload + \brief API to set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostOffload (tHalHandle hHal, tANI_U8 sessionId, + tpSirHostOffloadReq pRequest); + +/* --------------------------------------------------------------------------- + \fn sme_SetKeepAlive + \brief API to set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetKeepAlive (tHalHandle hHal, tANI_U8 sessionId, + tpSirKeepAliveReq pRequest); + +/* ---------------------------------------------------------------------------- + \fn sme_GetOperationChannel + \brief API to get current channel on which STA is parked + this function gives channel information only of infra station or IBSS station. + \param hHal, pointer to memory location and sessionId + \returns eHAL_STATUS_SUCCESS + eHAL_STATUS_FAILURE +-------------------------------------------------------------------------------*/ +eHalStatus sme_GetOperationChannel(tHalHandle hHal, tANI_U32 *pChannel, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + + \fn sme_RegisterMgtFrame + + \brief To register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RegisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen); + +/* --------------------------------------------------------------------------- + + \fn sme_DeregisterMgtFrame + + \brief To De-register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureRxpFilter + + \brief + SME will pass this request to lower mac to set/reset the filter on RXP for + multicast & broadcast traffic. + + \param + + hHal - The handle returned by macOpen. + + filterMask- Currently the API takes a 1 or 0 (set or reset) as filter. + Basically to enable/disable the filter (to filter "all" mcbc traffic) based + on this param. In future we can use this as a mask to set various types of + filters as suggested below: + FILTER_ALL_MULTICAST: + FILTER_ALL_BROADCAST: + FILTER_ALL_MULTICAST_BROADCAST: + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureRxpFilter( tHalHandle hHal, + tpSirWlanSetRxpFilters wlanRxpFilterParam); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppsCpuWakeupState + + \brief + SME will pass this request to lower mac to dynamically adjusts the listen + interval based on the WLAN/MSM activity. This feature is named as + Telescopic Beacon wakeup feature. + + \param + + hHal - The handle returned by macOpen. + + isAppsAwake- Depicts the state of the Apps CPU + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppsCpuWakeupState( tHalHandle hHal, tANI_BOOLEAN isAppsAwake); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureSuspendInd + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be suspended + + \param + + hHal - The handle returned by macOpen. + + wlanSuspendParam- Depicts the wlan suspend params + + csrReadyToSuspendCallback - Callback to be called when ready to suspend + event is received. + callbackContext - Context associated with csrReadyToSuspendCallback. + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal, + tpSirWlanSuspendParam wlanSuspendParam, + csrReadyToSuspendCallback, + void *callbackContext); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureResumeReq + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be Resumed + + \param + + hHal - The handle returned by macOpen. + + wlanResumeParam- Depicts the wlan resume params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureResumeReq( tHalHandle hHal, + tpSirWlanResumeParam wlanResumeParam); + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureExtWoW + + \brief + SME will pass this request to lower mac to configure Indoor WoW parameters. + + \param + + hHal - The handle returned by macOpen. + + wlanExtParams- Depicts the wlan Ext params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureExtWoW( tHalHandle hHal, + tpSirExtWoWParams wlanExtParams, + csrReadyToSuspendCallback callback, + void *callbackContext); + + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppType1Params + + \brief + SME will pass this request to lower mac to configure Indoor WoW parameters. + + \param + + hHal - The handle returned by macOpen. + + wlanAppType1Params- Depicts the wlan Indoor params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppType1Params( tHalHandle hHal, + tpSirAppType1Params wlanAppType1Params); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppType2Params + + \brief + SME will pass this request to lower mac to configure Indoor WoW parameters. + + \param + + hHal - The handle returned by macOpen. + + wlanAppType2Params- Depicts the wlan Indoor params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppType2Params( tHalHandle hHal, + tpSirAppType2Params wlanAppType2Params); +#endif + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraSessionId + + \brief To get the session ID for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \return sessionid, -1 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_S8 sme_GetInfraSessionId(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraOperationChannel + + \brief To get the operating channel for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param sessionId - the sessionId returned by sme_OpenSession. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetInfraOperationChannel( tHalHandle hHal, tANI_U8 sessionId); +/* --------------------------------------------------------------------------- + + \fn sme_GetConcurrentOperationChannel + + \brief To get the operating channel for other concurrent sessions, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param currentPersona - persona that is trying to come up. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetConcurrentOperationChannel( tHalHandle hHal ); + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +v_U16_t sme_CheckConcurrentChannelOverlap( tHalHandle hHal, v_U16_t sap_ch, + eCsrPhyMode sapPhyMode, v_U8_t cc_switch_mode); +#endif +/* --------------------------------------------------------------------------- + \fn sme_AbortMacScan + \brief API to cancel MAC scan. + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId for interface + \param reason - Reason to abort the scan + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +eHalStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId, + eCsrAbortReason reason); + +/* --------------------------------------------------------------------------- + \fn sme_GetCfgValidChannels + \brief API to get valid channel list + \param hHal - The handle returned by macOpen. + \param aValidChannels - Pointer to the valid channel list + \param len - valid channel list length + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetCfgValidChannels(tHalHandle hHal, tANI_U8 *aValidChannels, tANI_U32 *len); + +#ifdef FEATURE_WLAN_SCAN_PNO + +/* --------------------------------------------------------------------------- + \fn sme_SetPreferredNetworkList + \brief API to set the Preferred Network List Offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPreferredNetworkList (tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext ); + +/* --------------------------------------------------------------------------- + \fn sme_SetRSSIFilter + \brief API to set RSSI Filter feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetRSSIFilter(tHalHandle hHal, v_U8_t rssiThreshold); + +/****************************************************************************** +* +* Name: sme_PreferredNetworkFoundInd +* +* Description: +* Invoke Preferred Network Found Indication +* +* Parameters: +* hHal - HAL handle for device +* pMsg - found network description +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PreferredNetworkFoundInd (tHalHandle hHal, void* pMsg); +#endif // FEATURE_WLAN_SCAN_PNO + +/* --------------------------------------------------------------------------- + \fn sme_SetPowerParams + \brief API to set Power Parameters + \param hHal - The handle returned by macOpen. + \param pwParams - Pointer to the power parameters requested. + \param forced - if true, not to be dropped silently in host, it must reach + FW; It is added to avoid a race condition scenario where LIM hasn't deleted + the session yet before power params gets sent to PMC + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced); + +/* --------------------------------------------------------------------------- + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterSetFilter + \brief API to set 8023 Multicast Address List + \param hHal - The handle returned by macOpen. + \param pMulticastAddrs - Pointer to the Multicast Address List + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_8023MulticastList(tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFltMcAddrList pMulticastAddrs); + +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterSetFilter + \brief API to set Receive Packet Filter + \param hHal - The handle returned by macOpen. + \param pRcvPktFilterCfg - Receive Packet Filter parameter + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ReceiveFilterSetFilter(tHalHandle hHal, tpSirRcvPktFilterCfgType pRcvPktFilterCfg, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_GetFilterMatchCount + \brief API to get D0 PC Filter Match Count + \param hHal - The handle returned by macOpen + \param callbackRoutine - Callback routine invoked to receive Packet Coalescing Filter Match Count + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetFilterMatchCount(tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterClearFilter + \brief API to clear Receive Packet Filter + \param hHal - The handle returned by macOpen. + \param pRcvFltPktClearParam - Receive Packet Filter Clear parameter + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ReceiveFilterClearFilter(tHalHandle hHal, + tpSirRcvFltPktClearParam pRcvFltPktClearParam, + tANI_U8 sessionId); +#endif // WLAN_FEATURE_PACKET_FILTERING +/* --------------------------------------------------------------------------- + + \fn sme_IsChannelValid + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel); + +/* --------------------------------------------------------------------------- + \fn sme_SetFreqBand + \brief Used to set frequency band. + \param hHal + \sessionId Session identifier + \eBand band value to be configured + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetFreqBand(tHalHandle hHal, tANI_U8 sessionId, eCsrBand eBand); + +/* --------------------------------------------------------------------------- + \fn sme_GetFreqBand + \brief Used to get the current band settings. + \param hHal + \pBand pointer to hold the current band value + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetFreqBand(tHalHandle hHal, eCsrBand *pBand); + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_SetGTKOffload + \brief API to set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pRequest, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_GetGTKOffload + \brief API to get GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload response. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetGTKOffload (tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +eHalStatus sme_WakeReasonIndCallback (tHalHandle hHal, void* pMsg); +#endif // WLAN_WAKEUP_EVENTS + +/* --------------------------------------------------------------------------- + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + + +//return frequency for a particular channel +tANI_U16 sme_ChnToFreq(tANI_U8 chanNum); + +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel); + +/* --------------------------------------------------------------------------- + \fn sme_SetMaxTxPower + \brief Used to set the Maximum Transmit Power dynamically. Note: this + setting will not persist over reboots + \param hHal + \param pBssid BSSID to set the power cap for + \param pBssid pSelfMacAddress self MAC Address + \param pBssid power to set in dB + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr pBssid, + tSirMacAddr pSelfMacAddress, v_S7_t dB); + +/* --------------------------------------------------------------------------- + \fn sme_SetMaxTxPowerPerBand + \brief Used to set the Maximum Transmit Power for + specific band dynamically. Note: this setting will not persist over reboots + \param band + \param power to set in dB + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t db); + +/* --------------------------------------------------------------------------- + \fn sme_SetTxPower + \brief Set Transmit Power dynamically. + \param hHal + \param sessionId Target Session ID + \param pBSSId BSSId + \param dev_mode device mode + \param power power to set in dBm + \- return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId, + tSirMacAddr pBSSId, + tVOS_CON_MODE dev_mode, int power); + + +/* --------------------------------------------------------------------------- + + \fn sme_SetCustomMacAddr + + \brief Set the customer Mac Address. + + \param customMacAddr customer MAC Address + \- return eHalStatus + + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetCustomMacAddr(tSirMacAddr customMacAddr); + +/* --------------------------------------------------------------------------- + + \fn sme_HideSSID + + \brief Enable/Disables hidden SSID dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId + \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HideSSID(tHalHandle hHal, v_U8_t sessionId, v_U8_t ssidHidden); + +/* --------------------------------------------------------------------------- + + \fn sme_SetTmLevel + \brief Set Thermal Mitigation Level to RIVA + \param hHal - The handle returned by macOpen. + \param newTMLevel - new Thermal Mitigation Level + \param tmMode - Thermal Mitigation handle mode, default 0 + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode); + +/*--------------------------------------------------------------------------- + + \brief sme_featureCapsExchange() - SME interface to exchange capabilities between + Host and FW. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_featureCapsExchange(tHalHandle hHal); + +/*--------------------------------------------------------------------------- + + \brief sme_disableActiveModeOffload() - SME interface to disable Active mode Offload capabilitu + between in Host. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_disableFeatureCapablity(tANI_U8 feature_index); + +/*--------------------------------------------------------------------------- + + \brief sme_GetDefaultCountryCodeFrmNv() - SME interface to get the default + country code + Host and FW. + + \param hHal - HAL handle for device + \param pCountry - pointer to country code + + \return Success or failure + + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetDefaultCountryCodeFrmNv(tHalHandle hHal, tANI_U8 *pCountry); + +/*--------------------------------------------------------------------------- + + \brief sme_GetCurrentCountryCode() - SME interface to get the current operating + country code. + + \param hHal - HAL handle for device + \param pCountry - pointer to country code + + \return Success or failure + + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentCountryCode(tHalHandle hHal, tANI_U8 *pCountry); + +/* --------------------------------------------------------------------------- + \fn sme_transportDebug + \brief Dynamically monitoring Transport channels + Private IOCTL will querry transport channel status if driver loaded + \param hHal Upper MAC context + \param displaySnapshot Display transport channel snapshot option + \param toggleStallDetect Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + \- return NONE + -------------------------------------------------------------------------*/ +void sme_transportDebug(tHalHandle hHal, v_BOOL_t displaySnapshot, v_BOOL_t toggleStallDetect); + +/* --------------------------------------------------------------------------- + \fn sme_ResetPowerValuesFor5G + \brief Reset the power values for 5G band with NV power values. + \param hHal - HAL handle for device + \- return NONE + -------------------------------------------------------------------------*/ +void sme_ResetPowerValuesFor5G (tHalHandle hHal); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamPrefer5GHz + \brief enable/disable Roam prefer 5G runtime option + This function is called through dynamic setConfig callback function + to configure the Roam prefer 5G runtime option + \param hHal - HAL handle for device + \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamPrefer5GHz(tHalHandle hHal, v_BOOL_t nRoamPrefer5GHz); + +/* --------------------------------------------------------------------------- + \fn sme_setRoamIntraBand + \brief enable/disable Intra band roaming + This function is called through dynamic setConfig callback function + to configure the intra band roaming + \param hHal - HAL handle for device + \param nRoamIntraBand Enable/Disable Intra band roaming + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setRoamIntraBand(tHalHandle hHal, const v_BOOL_t nRoamIntraBand); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanNProbes + \brief function to update roam scan N probes + This function is called through dynamic setConfig callback function + to update roam scan N probes + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nProbes number of probe requests to be sent out + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, tANI_U8 sessionId, + const v_U8_t nProbes); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanHomeAwayTime + \brief function to update roam scan Home away time + This function is called through dynamic setConfig callback function + to update roam scan home away time + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nRoamScanAwayTime Scan home away time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanHomeAwayTime(tHalHandle hHal, tANI_U8 sessionId, + const v_U16_t nRoamScanHomeAwayTime, + const eAniBoolean bSendOffloadCmd); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamIntraBand + \brief get Intra band roaming + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_BOOL_t sme_getRoamIntraBand(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanNProbes + \brief get N Probes + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U8_t sme_getRoamScanNProbes(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanHomeAwayTime + \brief get Roam scan home away time + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U16_t sme_getRoamScanHomeAwayTime(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateImmediateRoamRssiDiff + \brief Update nImmediateRoamRssiDiff + This function is called through dynamic setConfig callback function + to configure nImmediateRoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param nImmediateRoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \param sessionId - Session identifier + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal, + v_U8_t nImmediateRoamRssiDiff, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamRssiDiff + \brief Update RoamRssiDiff + This function is called through dynamic setConfig callback function + to configure RoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param RoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, tANI_U8 sessionId, + v_U8_t RoamRssiDiff); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateFastTransitionEnabled() - enable/disable Fast Transition support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastTransitionEnabled. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastTransitionEnabled config successfully. + Other status means SME is failed to update isFastTransitionEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateFastTransitionEnabled(tHalHandle hHal, + v_BOOL_t isFastTransitionEnabled); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateWESMode + \brief Update WESMode + This function is called through dynamic setConfig callback function + to configure isWESModeEnabled + \param hHal - HAL handle for device + \param isWESModeEnabled - Enable/Disable WES Mode + \param sessionId - Session identifier + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateWESMode(tHalHandle hHal, v_BOOL_t isWESModeEnabled, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamScanControl + \brief Set roam scan control + This function is called to set roam scan control + if roam scan control is set to 0, roaming scan cache is cleared + any value other than 0 is treated as invalid value + \param hHal - HAL handle for device + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME failure to update + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamScanControl(tHalHandle hHal, tANI_U8 sessionId, + v_BOOL_t roamScanControl); +#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsFastRoamIniFeatureEnabled() - enable/disable LFR support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastRoamIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully. + Other status means SME is failed to update isFastRoamIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled(tHalHandle hHal, + tANI_U8 sessionId, + const v_BOOL_t isFastRoamIniFeatureEnabled); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsMAWCIniFeatureEnabled() - + Enable/disable LFR MAWC support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isMAWCIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update MAWCEnabled config successfully. + Other status means SME is failed to update MAWCEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsMAWCIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t MAWCEnabled); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_stopRoaming() - Stop roaming for a given sessionId + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - sessionId + \param reason - reason + \return eHAL_STATUS_SUCCESS on success + Other status on failure + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_stopRoaming(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 reason); + +/*-------------------------------------------------------------------------- + \brief sme_startRoaming() - Start roaming for a given sessionId + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - sessionId + \param reason - reason + \return eHAL_STATUS_SUCCESS on success + Other status on failure + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_startRoaming(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 reason); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if + Concurrent session exists + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS + Other status means SME is failed + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEnableFastRoamInConcurrency(tHalHandle hHal, + v_BOOL_t bFastRoamInConIniFeatureEnabled); +#endif +#endif /* FEATURE_WLAN_LFR */ + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsEseFeatureEnabled() - enable/disable ESE support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isEseIniFeatureEnabled. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully. + Other status means SME is failed to update isEseIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsEseFeatureEnabled(tHalHandle hHal, tANI_U8 sessionId, + const v_BOOL_t isEseIniFeatureEnabled); + +#endif /* FEATURE_WLAN_ESE */ + +/*-------------------------------------------------------------------------- + \brief sme_UpdateConfigFwRssiMonitoring() - enable/disable firmware RSSI Monitornig at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + fEnableFwRssiMonitoring. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring config successfully. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateConfigFwRssiMonitoring(tHalHandle hHal, + v_BOOL_t fEnableFwRssiMonitoring); + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +/* --------------------------------------------------------------------------- + \fn sme_SetRoamRescanRssiDiff + \brief Update Roam Rescan RSSI diff + This function is called through dynamic setConfig callback function + to configure nRoamRescanRssiDiff + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nRoamRescanRssiDiff - Roam Rescan Rssi Diff + \return eHAL_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config + successfully. + else SME is failed to update nRoamRescanRssiDiff + -------------------------------------------------------------------------*/ + +eHalStatus sme_SetRoamRescanRssiDiff(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamRescanRssiDiff); + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamRescanRssiDiff + \brief gets Roam Rescan RSSI diff + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamRescanRssiDiff + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamRescanRssiDiff(tHalHandle hHal); + + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamOpportunisticScanThresholdDiff + \brief Update Opportunistic Scan threshold diff + This function is called through dynamic setConfig callback function + to configure nOpportunisticThresholdDiff + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nOpportunisticThresholdDiff - Opportunistic Scan threshold diff + \return eHAL_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config + successfully. + else SME is failed to update nOpportunisticThresholdDiff. + -------------------------------------------------------------------------*/ + +eHalStatus sme_SetRoamOpportunisticScanThresholdDiff(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nOpportunisticThresholdDiff); + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamOpportunisticScanThresholdDiff() + \brief gets Opportunistic Scan threshold diff + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nOpportunisticThresholdDiff + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamOpportunisticScanThresholdDiff(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborLookupRssiThreshold() - update neighbor lookup rssi threshold + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborLookupRssiThreshold(tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t neighborLookupRssiThreshold); + +/*-------------------------------------------------------------------------- + \brief sme_set_delay_before_vdev_stop() - update delay before vdev stop + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_set_delay_before_vdev_stop(tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t delay_before_vdev_stop); + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborReassocRssiThreshold(tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t neighborReassocRssiThreshold); + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborLookupRssiThreshold() - get neighbor lookup rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getNeighborLookupRssiThreshold(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborScanRefreshPeriod() - set neighbor scan results refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanRefreshPeriod(tHalHandle hHal, + tANI_U8 sessionId, + v_U16_t neighborScanResultsRefreshPeriod); + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborScanRefreshPeriod() - get neighbor scan results refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanRefreshPeriod(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getEmptyScanRefreshPeriod() - get empty scan refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getEmptyScanRefreshPeriod(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal,tANI_U8 sessionId, + v_U16_t nEmptyScanRefreshPeriod); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMinChanTime + \brief Update nNeighborScanMinChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMinTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMinTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel minimum dwell time + \param sessionId - Session identifier + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal, + const v_U16_t nNeighborScanMinChanTime, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMaxChanTime + \brief Update nNeighborScanMaxChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMaxTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMaxTime=[0 .. 60] + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nNeighborScanMinChanTime - Channel maximum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId, + const v_U16_t nNeighborScanMaxChanTime); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMinChanTime + \brief get neighbor scan min channel time + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return v_U16_t - channel min time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborRoamState + \brief get neighbor roam state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - neighbor roam state + -------------------------------------------------------------------------*/ +v_U32_t sme_getNeighborRoamState(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getCurrentRoamState + \brief get current roam state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - current roam state + -------------------------------------------------------------------------*/ +v_U32_t sme_getCurrentRoamState(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getCurrentRoamSubState + \brief get neighbor roam sub state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - current roam sub state + -------------------------------------------------------------------------*/ +v_U32_t sme_getCurrentRoamSubState(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getLimSmeState + \brief get Lim Sme state + \param hHal - The handle returned by macOpen. + \return v_U32_t - Lim Sme state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimSmeState(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getLimMlmState + \brief get Lim Mlm state + \param hHal - The handle returned by macOpen. + \return v_U32_t - Lim Mlm state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimMlmState(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_IsLimSessionValid + \brief is Lim session valid + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_BOOL_t - true or false + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsLimSessionValid(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getLimSmeSessionState + \brief get Lim Sme session state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - Lim Sme session state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimSmeSessionState(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getLimMlmSessionState + \brief get Lim Mlm session state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - Lim Mlm session state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimMlmSessionState(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMaxChanTime + \brief get neighbor scan max channel time + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return v_U16_t - channel max time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanPeriod + \brief Update nNeighborScanPeriod + This function is called through dynamic setConfig callback function + to configure nNeighborScanPeriod + Usage: adb shell iwpriv wlan0 setConfig nNeighborScanPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nNeighborScanPeriod - neighbor scan period + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId, + const v_U16_t nNeighborScanPeriod); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanPeriod + \brief get neighbor scan period + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return v_U16_t - neighbor scan period + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBmissFirstBcnt + \brief Update Roam count for first beacon miss + This function is called through dynamic setConfig callback function + to configure nRoamBmissFirstBcnt + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nRoamBmissFirstBcnt - Roam first bmiss count + \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt + successfully. + else SME is failed to update nRoamBmissFirstBcnt + -------------------------------------------------------------------------*/ + +eHalStatus sme_SetRoamBmissFirstBcnt(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamBmissFirstBcnt); + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamBmissFirstBcnt + \brief gets Roam count for first beacon miss + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamBmissFirstBcnt + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBmissFirstBcnt(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBmissFinalBcnt + \brief Update Roam count for final beacon miss + This function is called through dynamic setConfig callback function + to configure nRoamBmissFinalBcnt + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nRoamBmissFinalBcnt - Roam final bmiss count + \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt + successfully. + else SME is failed to update nRoamBmissFinalBcnt + -------------------------------------------------------------------------*/ + +eHalStatus sme_SetRoamBmissFinalBcnt(tHalHandle hHal, tANI_U8 sessionId, + const v_U8_t nRoamBmissFinalBcnt); + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamBmissFinalBcnt + \brief gets Roam count for final beacon miss + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamBmissFinalBcnt + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBmissFinalBcnt(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBeaconRssiWeight + \brief Update Roam beacon rssi weight + This function is called through dynamic setConfig callback function + to configure nRoamBeaconRssiWeight + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param nRoamBeaconRssiWeight - Roam beacon rssi weight + \return eHAL_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config + successfully. + else SME is failed to update nRoamBeaconRssiWeight + -------------------------------------------------------------------------*/ + +eHalStatus sme_SetRoamBeaconRssiWeight(tHalHandle hHal, tANI_U8 sessionId, + const v_U8_t nRoamBeaconRssiWeight); + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamBeaconRssiWeight + \brief gets Roam beacon rssi weight + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamBeaconRssiWeight + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBeaconRssiWeight(tHalHandle hHal); +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/*-------------------------------------------------------------------------- + \brief sme_getRoamRssiDiff() - get Roam rssi diff + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getRoamRssiDiff(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_ChangeRoamScanChannelList() - Change roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels); + +#ifdef FEATURE_WLAN_ESE_UPLOAD +/*-------------------------------------------------------------------------- + \brief sme_SetEseRoamScanChannelList() - set ese roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels); +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getRoamScanChannelList() - get roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param pChannelList - Output channel list + \param pNumChannels - Output number of channels + \param sessionId - Session identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_getRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels, tANI_U8 sessionId); + +/*-------------------------------------------------------------------------- + \brief sme_getIsEseFeatureEnabled() - get ESE feature enabled or not + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the ESE feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsEseFeatureEnabled(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getWESMode() - getWES Mode + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U8_t - WES Mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetWESMode(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_GetRoamScanControl() - get scan control + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_BOOL_t - Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetRoamScanControl(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nnEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nnEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_getIsLfrFeatureEnabled() - get LFR feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsLfrFeatureEnabled(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getIsFtFeatureEnabled() - get FT feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsFtFeatureEnabled(tHalHandle hHal); + +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamScanOffloadEnabled() - enable/disable roam scan offload feaure + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + gRoamScanOffloadEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamScanOffloadEnabled(tHalHandle hHal, v_BOOL_t nRoamScanOffloadEnabled); +#endif + + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByFW + \brief Check if an feature is enabled by FW + + \param feattEnumValue - Enumeration value of the feature to be checked. + A value from enum placeHolderInCapBitmap + + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ +tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue); +#ifdef FEATURE_WLAN_TDLS + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsLinkEstablishParams + \brief API to send TDLS Link Establishment Parameters. + + \param peerMac - peer's Mac Adress. + \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ + +VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams); + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsMgmtFrame + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param frame_type - Type of TDLS mgmt frame to be sent. + \param dialog - dialog token used in the frame. + \param status - status to be incuded in the frame. + \param peerCapability - peerCapability to be incuded in the frame. + \param buf - additional IEs to be included + \param len - lenght of additional Ies + \param responder - Tdls request type + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, + tANI_U8 frame_type, tANI_U8 dialog, tANI_U16 status, tANI_U32 peerCapability, tANI_U8 *buf, tANI_U8 len, tANI_U8 responder); +/* --------------------------------------------------------------------------- + \fn sme_ChangeTdlsPeerSta + \brief API to Update TDLS peer sta parameters. + + \param peerMac - peer's Mac Adress. + \param staParams - Peer Station Parameters. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, + tCsrStaParams *pstaParams); +/* --------------------------------------------------------------------------- + \fn sme_AddTdlsPeerSta + \brief API to Add TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac); +/* --------------------------------------------------------------------------- + \fn sme_DeleteTdlsPeerSta + \brief API to Delete TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac); +/* --------------------------------------------------------------------------- + \fn sme_SetTdlsPowerSaveProhibited + \API to set/reset the isTdlsPowerSaveProhibited. + + \- return void + -------------------------------------------------------------------------*/ +void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, tANI_U32 sessionId, + v_BOOL_t val); + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsChanSwitchReq + \API to set tdls channel switch parameters. + + \- return void + -------------------------------------------------------------------------*/ +eHalStatus sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tSmeTdlsChanSwitchParams *chSwitchParams); +#endif +/* --------------------------------------------------------------------------- + \fn sme_IsPmcBmps + \brief API to Check if PMC state is BMPS. + + \- return v_BOOL_t + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsPmcBmps(tHalHandle hHal); + +eHalStatus sme_UpdateDfsSetting(tHalHandle hHal, tANI_U8 fUpdateEnableDFSChnlScan); + +/* + * SME API to enable/disable WLAN driver initiated SSR + */ +void sme_UpdateEnableSSR(tHalHandle hHal, tANI_BOOLEAN enableSSR); + +/* --------------------------------------------------------------------------- + + \fn sme_SetPhyMode + + \brief Changes the PhyMode. + + \param hHal - The handle returned by macOpen. + + \param phyMode new phyMode which is to set + + \return eHalStatus SUCCESS. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetPhyMode(tHalHandle hHal, eCsrPhyMode phyMode); + +/* --------------------------------------------------------------------------- + + \fn sme_GetPhyMode + + \brief gets current PhyMode. + + \param hHal - The handle returned by macOpen. + + \return eHalStatus PhyMode + + -------------------------------------------------------------------------------*/ +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal); + +/* + * SME API to determine the channel bonding mode + */ +VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, tANI_U8 channel); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_HandoffRequest() - a wrapper function to Request a handoff + from CSR. + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - Session identifier + \param pHandoffInfo - info provided by HDD with the handoff request (namely: + BSSID, channel etc.) + \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_HandoffRequest(tHalHandle hHal, tANI_U8 sessionId, + tCsrHandoffRequest *pHandoffInfo); +#endif +/*-------------------------------------------------------------------------- + \brief sme_isSta_p2p_clientConnected() - a wrapper function to check if there + is any connected session . + This is a synchronous call + \param hHal - The handle returned by macOpen + \return VOS_STATUS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal); + +#ifdef FEATURE_WLAN_LPHB +/* --------------------------------------------------------------------------- + \fn sme_LPHBConfigReq + \API to make configuration LPHB within FW. + \param hHal - The handle returned by macOpen + \param lphdReq - LPHB request argument by client + \param pCallbackfn - LPHB timeout notification callback function pointer + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_LPHBConfigReq( + tHalHandle hHal, + tSirLPHBReq *lphdReq, + void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd *indParam)); +#endif /* FEATURE_WLAN_LPHB */ + +/* --------------------------------------------------------------------------- + \fn sme_AddPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param addPeriodicTxPtrnParams - Pointer to the add pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_AddPeriodicTxPtrn(tHalHandle hHal, tSirAddPeriodicTxPtrn + *addPeriodicTxPtrnParams); + +/* --------------------------------------------------------------------------- + \fn sme_DelPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param delPeriodicTxPtrnParams - Pointer to the deleting pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_DelPeriodicTxPtrn(tHalHandle hHal, tSirDelPeriodicTxPtrn + *delPeriodicTxPtrnParams); +/*-------------------------------------------------------------------------- + \brief sme_enable_disable_split_scan() - a wrapper function to set the split + scan parameter. + This is a synchronous call + \param hHal - The handle returned by macOpen + \return None. + \sa + --------------------------------------------------------------------------*/ +void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan, + tANI_U8 nNumP2PChan); + +/* --------------------------------------------------------------------------- + \fn sme_SendRateUpdateInd + \brief API to Update rate + \param hHal - The handle returned by macOpen + \param rateUpdateParams - Pointer to rate update params + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams); + +/* + * sme API to trigger fast BSS roam to a given BSSID independent of RSSI + * triggers + * return status +*/ +eHalStatus smeIssueFastRoamNeighborAPEvent (tHalHandle hHal, + tANI_U8 *bssid, + tSmeFastRoamTrigger fastRoamTrig, + tANI_U8 sessionId); + +eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pBSSId, + tANI_BOOLEAN flush_cache ); + +void smeGetCommandQStatus( tHalHandle hHal ); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* --------------------------------------------------------------------------- + \fn sme_SetBatchScanReq + \brief API to set batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting set batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_SetBatchScanReq +( + tHalHandle hHal, tSirSetBatchScanReq *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, tSirSetBatchScanRsp *pRsp), + void *callbackContext +); + +/* --------------------------------------------------------------------------- + \fn sme_TriggerBatchScanResultInd + \brief API to trigger batch scan result indications from from FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to get batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting get batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_TriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, void *pRsp), + void *callbackContext +); + +/* --------------------------------------------------------------------------- + \fn sme_StopBatchScanInd + \brief API to stop batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to stop batch indication + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_StopBatchScanInd +( + tHalHandle hHal, tSirStopBatchScanInd *pInd, tANI_U8 sessionId +); + +#endif + +/* + * SME API to enable/disable idle mode powersave + * This should be called only if powersave offload + * is enabled + */ +VOS_STATUS sme_SetIdlePowersaveConfig(v_PVOID_t vosContext, tANI_U32 value); +VOS_STATUS sme_notify_modem_power_state(tHalHandle hHal, tANI_U32 value); + +eHalStatus sme_ConfigEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); +eHalStatus sme_ConfigDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); +eHalStatus sme_PsOffloadEnablePowerSave (tHalHandle hHal, tANI_U32 sessionId); +eHalStatus sme_PsOffloadDisablePowerSave (tHalHandle hHal, tANI_U32 sessionId); +eHalStatus sme_PsOffloadEnableDeferredPowerSave (tHalHandle hHal, + tANI_U32 sessionId, + tANI_BOOLEAN isReassoc); +eHalStatus sme_PsOffloadDisableDeferredPowerSave (tHalHandle hHal, + tANI_U32 sessionId); + + +/*SME API to convert convert the ini value to the ENUM used in csr and MAC*/ +ePhyChanBondState sme_GetCBPhyStateFromCBIniValue(tANI_U32 cb_ini_value); + +int sme_UpdateHTConfig(tHalHandle hHal, tANI_U8 sessionId, tANI_U16 htCapab, + int value); +tANI_S16 sme_GetHTConfig(tHalHandle hHal, tANI_U8 session_id, tANI_U16 ht_capab); + +#ifdef QCA_HT_2040_COEX +VOS_STATUS sme_notify_ht2040_mode(tHalHandle hHal, tANI_U16 staId, + v_MACADDR_t macAddrSTA, v_U8_t sessionId, tANI_U8 channel_type); +eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel_type, tANI_BOOLEAN obssEnabled); +eHalStatus sme_SetPhyCBMode24G(tHalHandle hHal, ePhyChanBondState phyCBMode); +#endif + +eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, + tANI_U32 *regInfo1, tANI_U32 *regInfo2); + +#ifdef FEATURE_WLAN_TDLS +eHalStatus sme_UpdateFwTdlsState(tHalHandle hHal, void *psmeTdlsParams, + tANI_BOOLEAN useSmeLock); +eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, + tSmeTdlsPeerStateParams *pPeerStateParams); +#endif /* FEATURE_WLAN_TDLS */ + +#ifdef FEATURE_WLAN_CH_AVOID +/* --------------------------------------------------------------------------- + \fn sme_AddChAvoidCallback + \brief Used to plug in callback function + Which notify channel may not be used with SAP or P2PGO mode. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus +-------------------------------------------------------------------------*/ +eHalStatus sme_AddChAvoidCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *hdd_context, void *indi_param) +); + +/* --------------------------------------------------------------------------- + \fn sme_ChAvoidUpdateReq + \API to request channel avoidance update from FW. + \param hHal - The handle returned by macOpen + \param update_type - The udpate_type parameter of this request call + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_ChAvoidUpdateReq +( + tHalHandle hHal +); +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +/* --------------------------------------------------------------------------- + \fn sme_auto_shutdown_cb + \brief Used to plug in callback function for receiving auto shutdown evt + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus +-------------------------------------------------------------------------*/ +eHalStatus sme_set_auto_shutdown_cb(tHalHandle hHal, + void (*pCallbackfn)(void)); + +/* --------------------------------------------------------------------------- + \fn sme_set_auto_shutdown_timer + \API to set auto shutdown timer value in FW. + \param hHal - The handle returned by macOpen + \param timer_val - The auto shutdown timer value to be set + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_set_auto_shutdown_timer(tHalHandle hHal, tANI_U32 timer_value); +#endif + +eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal, tCsrBssid bssid, + tANI_U8 targetChannel, eCsrPhyMode phyMode ); + +eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, + tCsrBssid bssid, tANI_U8 dfsCacWaitStatus); +/* ------------------------------------------------------------------------- + \fn sme_RoamCsaIeRequest + \brief API to request CSA IE transmission from PE + \param hHal - The handle returned by macOpen + \param pDfsCsaReq - CSA IE request + \param bssid - SAP bssid + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 csaIeReqd); + +/* --------------------------------------------------------------------------- + \fn sme_InitThermalInfo + \brief SME API to initialize the thermal mitigation parameters + \param hHal + \param thermalParam : thermal mitigation parameters + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_InitThermalInfo( tHalHandle hHal, tSmeThermalParams thermalParam ); +/* --------------------------------------------------------------------------- + \fn sme_InitThermalInfo + \brief SME API to set the thermal mitigation level + \param hHal + \param level : thermal mitigation level + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level ); +/* --------------------------------------------------------------------------- + \fn sme_TxpowerLimit + \brief SME API to set txpower limits + \param hHal + \param psmetx : power limits for 2g/5g + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_TxpowerLimit( tHalHandle hHal, tSirTxPowerLimit *psmetx); +/* --------------------------------------------------------------------------- + \fn sme_GetLinkSpeed + \brief SME API to get the linkspeed for peermac + \param hHal + \param lsReq: peermac address to retrieve linkspeed + \param plsContext: callback context + \param pCallbackfn: callback fn with response (linkspeed) + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetLinkSpeed(tHalHandle hHal,tSirLinkSpeedInfo *lsReq,void *plsContext, + void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, void *pContext) ); + +/*---------------------------------------------------------------------------- + \fn sme_ModifyAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_ModifyAddIE(tHalHandle hHal, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType); + +/*---------------------------------------------------------------------------- + \fn sme_UpdateAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pUpdateIE - pointer to structure tSirUpdateIE + \param updateType - Type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_UpdateAddIE(tHalHandle hHal, + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType); + +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value); +eHalStatus sme_ApDisableIntraBssFwd(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN disablefwd); +tANI_U32 sme_GetChannelBondingMode5G(tHalHandle hHal); +tANI_U32 sme_GetChannelBondingMode24G(tHalHandle hHal); + +#ifdef WLAN_FEATURE_STATS_EXT + +typedef struct sStatsExtRequestReq { + tANI_U32 request_data_len; + tANI_U8* request_data; +} tStatsExtRequestReq, *tpStatsExtRequestReq; + +typedef void (* StatsExtCallback)(void *, tStatsExtEvent *); + +void sme_StatsExtRegisterCallback(tHalHandle hHal, StatsExtCallback callback); + +eHalStatus sme_StatsExtRequest(tANI_U8 session_id, tpStatsExtRequestReq input); + +eHalStatus sme_StatsExtEvent (tHalHandle hHal, void* pMsg); + +#endif +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS roam scan mode + This function is called through dynamic setConfig callback function + to configure allowDFSChannelRoam. + \param hHal - HAL handle for device + \param sessionId - Session identifier + \param allowDFSChannelRoam - DFS roaming scan mode 0 (disable), + 1 (passive), 2 (active) + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS roaming scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t allowDFSChannelRoam); + +/*-------------------------------------------------------------------------- + \brief sme_GetDFSScanMode() - get DFS roam scan mode + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return DFS roaming mode 0 (disabled), 1 (passive), 2 (active) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetDFSScanMode(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_staInMiddleOfRoaming + \brief This function returns TRUE if STA is in the middle of roaming state + \param hHal - HAL handle for device + \param sessionId - Session identifier + \- return TRUE or FALSE + -------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_staInMiddleOfRoaming(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_PsOffloadIsStaInPowerSave + \brief This function returns TRUE if STA is in power save + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \- return TRUE or FALSE + -------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_PsOffloadIsStaInPowerSave(tHalHandle hHal, tANI_U8 sessionId); + +#ifdef FEATURE_WLAN_EXTSCAN +/* --------------------------------------------------------------------------- + \fn sme_GetValidChannelsByBand + \brief SME API to fetch all valid channel filtered by band + \param hHal + \param wifiBand: RF band information + \param aValidChannels: Array to store channel info + \param len: number of channels + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetValidChannelsByBand (tHalHandle hHal, tANI_U8 wifiBand, + tANI_U32 *aValidChannels, tANI_U8 *pNumChannels); + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanGetCapabilities + \brief SME API to fetch extscan capabilities + \param hHal + \param pReq: extscan capabilities structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanGetCapabilities (tHalHandle hHal, + tSirGetExtScanCapabilitiesReqParams *pReq); + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanStart + \brief SME API to issue extscan start + \param hHal + \param pStartCmd: extscan start structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanStart (tHalHandle hHal, + tSirWifiScanCmdReqParams *pStartCmd); + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanStop + \brief SME API to issue extscan stop + \param hHal + \param pStopReq: extscan stop structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanStop(tHalHandle hHal, + tSirExtScanStopReqParams *pStopReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetBssHotlist + \brief SME API to set BSSID hotlist + \param hHal + \param pSetHotListReq: extscan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetBssHotlist (tHalHandle hHal, + tSirExtScanSetBssidHotListReqParams *pSetHotListReq); + +/* --------------------------------------------------------------------------- + \fn sme_ResetBssHotlist + \brief SME API to reset BSSID hotlist + \param hHal + \param pSetHotListReq: extscan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetBssHotlist (tHalHandle hHal, + tSirExtScanResetBssidHotlistReqParams *pResetReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetSignificantChange + \brief SME API to set significant change + \param hHal + \param pSetSignificantChangeReq: extscan set significant change structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetSignificantChange (tHalHandle hHal, + tSirExtScanSetSigChangeReqParams* pSetSignificantChangeReq); + +/* --------------------------------------------------------------------------- + \fn sme_ResetSignificantChange + \brief SME API to reset significant change + \param hHal + \param pResetReq: extscan reset significant change structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetSignificantChange (tHalHandle hHal, + tSirExtScanResetSignificantChangeReqParams *pResetReq); + +/* --------------------------------------------------------------------------- + \fn sme_getCachedResults + \brief SME API to get cached results + \param hHal + \param pCachedResultsReq: extscan get cached results structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_getCachedResults (tHalHandle hHal, + tSirExtScanGetCachedResultsReqParams *pCachedResultsReq); + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanRegisterCallback + \brief SME API to register extscan notification callback + \param pExtScanIndCb + \- return void + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, + void (*pExtScanIndCb)(void *, const tANI_U16, void *)); + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_abortRoamScan + \brief API to abort current roam scan cycle by roam scan offload module. + \param hHal - The handle returned by macOpen. + \param sessionId - Session identifier + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_abortRoamScan(tHalHandle hHal, tANI_U8 sessionId); +#endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamOffloadEnabled() - enable/disable roam offload feature + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param nRoamOffloadEnabled - The boolean to update with + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamOffloadEnabled(tHalHandle hHal, + v_BOOL_t nRoamOffloadEnabled); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamKeyMgmtOffloadEnabled() - enable/disable key mgmt offload + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param nRoamKeyMgmtOffloadEnabled - The boolean to update with + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamKeyMgmtOffloadEnabled(tHalHandle hHal, + tANI_U8 sessionId, + v_BOOL_t nRoamKeyMgmtOffloadEnabled); + +#endif + +#ifdef WLAN_FEATURE_NAN +/****************************************************************************** + \fn sme_NanEvent + + \brief + a callback function called when SME received eWNI_SME_NAN_EVENT + event from WDA + + \param hHal - HAL handle for device + \param pMsg - Message body passed from WDA; includes NAN header + + \return VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanEvent(tHalHandle hHal, void* pMsg); +#endif /* WLAN_FEATURE_NAN */ + +/*-------------------------------------------------------------------------- + \brief sme_getLinkStatus() - api to get the link status + \param hHal - The handle returned by macOpen. + \param callback - callback function for link status result from FW + \param pContext - The context passed with callback + \param sessionId - SME sessionId + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_getLinkStatus(tHalHandle hHal, + tCsrLinkStatusCallback callback, + void *pContext, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_SetScanningMacOui + \brief SME API to set scanning mac oui + \param hHal + \param pScanMacOui: Scanning Mac Oui (input 3 bytes) + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetScanningMacOui(tHalHandle hHal, tSirScanMacOui *pScanMacOui); + +#ifdef DHCP_SERVER_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_setDhcpSrvOffload + \brief SME API to set DHCP server offload info + \param hHal + \param pDhcpSrvInfo : DHCP server offload info struct + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_setDhcpSrvOffload(tHalHandle hHal, + tSirDhcpSrvOffloadInfo *pDhcpSrvInfo); +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef WLAN_FEATURE_GPIO_LED_FLASHING +/* --------------------------------------------------------------------------- + \fn sme_SetLedFlashing + \brief API to set the LED flashing feature. + \param hHal - The handle returned by macOpen. + \param x0, x1 - led flashing parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetLedFlashing (tHalHandle hHal, tANI_U8 type, + tANI_U32 x0, tANI_U32 x1); +#endif +/* --------------------------------------------------------------------------- + \fn sme_handle_dfS_chan_scan + \brief SME API to enable/disable DFS channel scan + \param hHal + \param dfs_flag: whether dfs needs to be enabled or disabled + \return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_handle_dfs_chan_scan(tHalHandle hHal, tANI_U8 dfs_flag); + +eHalStatus sme_update_nss(tHalHandle h_hal, uint8_t nss); + +uint8_t sme_is_any_session_in_connected_state(tHalHandle h_hal); + +bool smeNeighborRoamIsHandoffInProgress(tHalHandle hHal, tANI_U8 sessionId); + +eHalStatus sme_disable_non_fcc_channel(tHalHandle hHal, + bool fcc_constraint); + +#endif //#if !defined( __SME_API_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_FTApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_FTApi.h new file mode 100644 index 0000000000000..b963843db6a35 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_FTApi.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#if defined(WLAN_FEATURE_VOWIFI_11R) + +#if !defined( __SME_FTAPI_H ) +#define __SME_FTAPI_H + +#include + +/**========================================================================= + + \brief macros and prototype for SME APIs + + ========================================================================*/ +typedef enum eFTIEState +{ + eFT_START_READY, // Start before and after 11r assoc + eFT_AUTH_REQ_READY, // When we have recvd the 1st or nth auth req + eFT_WAIT_AUTH2, // Sent auth1 and waiting auth2 + eFT_AUTH_COMPLETE, // We are now ready for FT phase, send auth1, recd auth2 + eFT_REASSOC_REQ_WAIT, // Now we have sent Auth Rsp to the supplicant and waiting + // Reassoc Req from the supplicant. + eFT_SET_KEY_WAIT, // We have received the Reassoc request from + // supplicant. Waiting for the keys. +} tFTIEStates; + +/* FT neighbor roam callback user context */ +typedef struct sFTRoamCallbackUsrCtx +{ + tpAniSirGlobal pMac; + tANI_U8 sessionId; +} tFTRoamCallbackUsrCtx, *tpFTRoamCallbackUsrCtx; + +typedef struct sFTSMEContext +{ + /* Received and processed during pre-auth */ + tANI_U8 *auth_ft_ies; + tANI_U32 auth_ft_ies_length; + + /* Received and processed during re-assoc */ + tANI_U8 *reassoc_ft_ies; + tANI_U16 reassoc_ft_ies_length; + + /* Pre-Auth info */ + tFTIEStates FTState; // The state of FT in the current 11rAssoc + tSirMacAddr preAuthbssId; // BSSID to preauth to + tANI_U32 smeSessionId; + + /* Saved pFTPreAuthRsp */ + tpSirFTPreAuthRsp psavedFTPreAuthRsp; + v_BOOL_t setFTPreAuthState; + v_BOOL_t setFTPTKState; + + /* Time to trigger reassoc once pre-auth is successful */ + vos_timer_t preAuthReassocIntvlTimer; + + v_BOOL_t addMDIE; + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U32 r0kh_id_len; + tANI_U8 r0kh_id[SIR_ROAM_R0KH_ID_MAX_LEN]; +#endif + + /* User context for the timer callback */ + tpFTRoamCallbackUsrCtx pUsrCtx; +} tftSMEContext, *tpftSMEContext; + +/*-------------------------------------------------------------------------- + Prototype functions + ------------------------------------------------------------------------*/ +void sme_FTOpen(tHalHandle hHal, tANI_U32 sessionId); +void sme_FTClose(tHalHandle hHal, tANI_U32 sessionId); +void sme_FTReset(tHalHandle hHal, tANI_U32 sessionId); +void sme_SetFTIEs( tHalHandle hHal, tANI_U32 sessionId, const tANI_U8 *ft_ies, tANI_U16 ft_ies_length ); +eHalStatus sme_FTUpdateKey( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamSetKey * pFTKeyInfo ); +void sme_GetFTPreAuthResponse(tHalHandle hHal, tANI_U32 sessionId, tANI_U8 *ft_ies, + tANI_U32 ft_ies_ip_len, tANI_U16 *ft_ies_length ); +void sme_GetRICIEs(tHalHandle hHal, tANI_U32 sessionId, tANI_U8 *ric_ies, + tANI_U32 ric_ies_ip_len, tANI_U32 *ric_ies_length ); +void sme_PreauthReassocIntvlTimerCallback(void *context); +void sme_SetFTPreAuthState(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t state); +v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal, tANI_U32 sessionId); +v_BOOL_t sme_GetFTPTKState(tHalHandle hHal, tANI_U32 sessionId); +void sme_SetFTPTKState(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t state); +#endif + +#endif //#if !defined( __SME_FTAPI_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_QosApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_QosApi.h new file mode 100644 index 0000000000000..4c138481983b1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_QosApi.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SME_QOSAPI_H ) +#define __SME_QOSAPI_H + + +/**========================================================================= + + \file sme_QosApi.h + + \brief prototype for SME QoS APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" + +/*-------------------------------------------------------------------------- + Pre-processor Definitions + ------------------------------------------------------------------------*/ +#define SME_QOS_UAPSD_VO 0x01 +#define SME_QOS_UAPSD_VI 0x02 +#define SME_QOS_UAPSD_BE 0x08 +#define SME_QOS_UAPSD_BK 0x04 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Enumeration of the various QoS status types that would be reported to HDD +---------------------------------------------------------------------------*/ +typedef enum +{ + //async: once PE notifies successful TSPEC negotiation, or CSR notifies for + //successful reassoc, notifies HDD with current QoS Params + SME_QOS_STATUS_SETUP_SUCCESS_IND = 0, + //sync: only when App asked for APSD & it's already set with ACM = 0 + SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_SETUP_FAILURE_RSP, + //sync + SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP, + //sync: AP doesn't support QoS (WMM) + SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP, + //sync: either req has been sent down to PE or just buffered in SME + SME_QOS_STATUS_SETUP_REQ_PENDING_RSP, + //async: in case of flow aggregation, if the new TSPEC negotiation is + //successful, OR, + //notify existing flows that TSPEC is modified with current QoS Params + SME_QOS_STATUS_SETUP_MODIFIED_IND, + //sync: no APSD asked for & ACM = 0 + SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode right away (eHAL_STATUS_PMC_PENDING) + SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode at all (eHAL_STATUS_FAILURE) + SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED, + + //sync: req has been sent down to PE in case of delts or addts for remain + // flows, OR if the AC doesn't have APSD or ACM + //async: once the downgrade req for QoS params is successful + SME_QOS_STATUS_RELEASE_SUCCESS_RSP = 100, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_RELEASE_FAILURE_RSP, + //async: AP sent DELTS indication + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + //sync: an addts req has been sent down to PE to downgrade the QoS params or + // just buffered in SME + SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP, + //sync + SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP, + + //async: for QoS modify request if modification is successful, notifies HDD + // with current QoS Params + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND = 200, + //sync: only when App asked for APSD & it's already set with ACM = 0 + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP, + //sync: either req has been sent down to PE or just buffered in SME + SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP, + //sync: no APSD asked for & ACM = 0 + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP, + //sync + SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode right away (eHAL_STATUS_PMC_PENDING) + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode at all (eHAL_STATUS_FAILURE) + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED, + //sync: STA is handing off to a new AP + SME_QOS_STATUS_HANDING_OFF = 300, + //async:powersave mode changed by PMC from UAPSD to Full power + SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND = 400, + //async:powersave mode changed by PMC from Full power to UAPSD + SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND, + +}sme_QosStatusType; + +/*--------------------------------------------------------------------------- + Enumeration of the various User priority (UP) types + + From 802.1D/802.11e/WMM specifications (all refer to same table) +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_WMM_UP_BE = 0, + SME_QOS_WMM_UP_BK = 1, + SME_QOS_WMM_UP_RESV = 2, /* Reserved */ + SME_QOS_WMM_UP_EE = 3, + SME_QOS_WMM_UP_CL = 4, + SME_QOS_WMM_UP_VI = 5, + SME_QOS_WMM_UP_VO = 6, + SME_QOS_WMM_UP_NC = 7, + + SME_QOS_WMM_UP_MAX + +}sme_QosWmmUpType; + +/*--------------------------------------------------------------------------- + Enumeration of the various TSPEC directions + + From 802.11e/WMM specifications +---------------------------------------------------------------------------*/ + +typedef enum +{ + SME_QOS_WMM_TS_DIR_UPLINK = 0, + SME_QOS_WMM_TS_DIR_DOWNLINK = 1, + SME_QOS_WMM_TS_DIR_RESV = 2, /* Reserved */ + SME_QOS_WMM_TS_DIR_BOTH = 3, + +}sme_QosWmmDirType; + +/*--------------------------------------------------------------------------- + Enumeration of the various TSPEC ack policies. + + From 802.11 WMM specification +---------------------------------------------------------------------------*/ + +typedef enum +{ + SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK = 0, + SME_QOS_WMM_TS_ACK_POLICY_RESV1 = 1, + SME_QOS_WMM_TS_ACK_POLICY_RESV2 = 2, /* Reserved */ + SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 3, + +}sme_QosWmmAckPolicyType; + +/*--------------------------------------------------------------------------- + TS Info field in the WMM TSPEC + + See suggestive values above +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t burst_size_defn; + sme_QosWmmAckPolicyType ack_policy; + sme_QosWmmUpType up; /* User priority */ + v_U8_t psb; /* power-save bit */ + sme_QosWmmDirType direction; /* Direction */ + v_U8_t tid; /* TID : To be filled up by SME-QoS */ +} sme_QosWmmTsInfoType; + +/*--------------------------------------------------------------------------- + The WMM TSPEC Element (from the WMM spec) +---------------------------------------------------------------------------*/ +typedef struct +{ + sme_QosWmmTsInfoType ts_info; + v_U16_t nominal_msdu_size; + v_U16_t maximum_msdu_size; + v_U32_t min_service_interval; + v_U32_t max_service_interval; + v_U32_t inactivity_interval; + v_U32_t suspension_interval; + v_U32_t svc_start_time; + v_U32_t min_data_rate; + v_U32_t mean_data_rate; + v_U32_t peak_data_rate; + v_U32_t max_burst_size; + v_U32_t delay_bound; + v_U32_t min_phy_rate; + v_U16_t surplus_bw_allowance; + v_U16_t medium_time; +} sme_QosWmmTspecInfo; + + +/*-------------------------------------------------------------------------- + External APIs + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_QosCallback() - This is a callback function which is registered + per flow while HDD is requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to be sent to HDD. HDD + will notify the application in turn, if needed. + + \param hHal - The handle returned by macOpen. + \param HDDcontext - A cookie passed by HDD during QoS setup, to be used by SME + during any QoS notification (through the callabck) to HDD + \param pCurrentQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above, fed back to HDD + \param status - The status of the flow running on an AC. It could be of + sme_QosStatusType + + \return eHAL_STATUS_SUCCESS - Callback invoke successful. + + + \sa + + --------------------------------------------------------------------------*/ +typedef eHalStatus (*sme_QosCallback)(tHalHandle hHal, void * HDDcontext, + sme_QosWmmTspecInfo * pCurrentQoSInfo, + sme_QosStatusType status, + v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosSetupReq() - The SME QoS API exposed to HDD to request for QoS + on a particular AC. This function should be called after a link has been + established, i.e. STA is associated with an AP etc. If the request involves + admission control on the requested AC, HDD needs to provide the necessary + Traffic Specification (TSPEC) parameters otherwise SME is going to use the + default params. + + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId returned by sme_OpenSession. Current QOS code doesn't + support multiple session. This function returns failure when different + sessionId is passed in before calling sme_QosReleaseReq. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param pQosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + + \return SME_QOS_STATUS_SETUP_SUCCESS - Setup request processed successfully. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetupReq(tHalHandle hHal, tANI_U32 sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, void * HDDcontext, + sme_QosWmmUpType UPType, v_U32_t * pQosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosModifyReq() - The SME QoS API exposed to HDD to request for + modification of certain QoS params on a flow running on a particular AC. + This function should be called after a link has been established, i.e. STA is + associated with an AP etc. & a QoS setup has been succesful for that flow. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param hHal - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS - Modification request processed + successfully. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosModifyReq(tHalHandle hHal, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosReleaseReq() - The SME QoS API exposed to HDD to request for + releasing a QoS flow running on a particular AC. This function should be + called only if a QoS is set up with a valid FlowID. HDD sould invoke this + API only if an explicit request for QoS release has come from Application + + \param hHal - The handle returned by macOpen. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return SME_QOS_STATUS_RELEASE_SUCCESS - Release request processed + successfully. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosReleaseReq(tHalHandle hHal, v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosIsTSInfoAckPolicyValid() - The SME QoS API exposed to HDD to + check if TS info ack policy field can be set to "HT-immediate block acknowledgement" + + \param pMac - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info, provided by HDD + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE - Current Association is HT association and so TS info ack policy + can be set to "HT-immediate block acknowledgement" + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsTSInfoAckPolicyValid(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId); + + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateHandOff() - Function which can be called to update + Hand-off state of SME QoS Session + \param sessionId - session id + \param updateHandOff - value True/False to update the handoff flag + + \sa + +-------------------------------------------------------------------------*/ +void sme_QosUpdateHandOff(v_U8_t sessionId, + v_BOOL_t updateHandOff); + + +/*-------------------------------------------------------------------------- + \brief sme_UpdateDSCPtoUPMapping() - Function which can be called to update + qos mapping table maintained in HDD + \param hHal - The handle returned by macOpen. + \param dscpmapping - pointer to the qos mapping structure in HDD + \param sessionId - session id + + \sa +-------------------------------------------------------------------------*/ +VOS_STATUS sme_UpdateDSCPtoUPMapping(tHalHandle hHal, + sme_QosWmmUpType* dscpmapping, v_U8_t sessionId); + +#endif //#if !defined( __SME_QOSAPI_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_RrmApi.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_RrmApi.h new file mode 100644 index 0000000000000..e4f5c3a42ce64 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_RrmApi.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SMERRMAPI_H ) +#define __SMERRMAPI_H + + +/**========================================================================= + + \file sme_RrmApi.h + + \brief prototype for SME RRM APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "smeInternal.h" +#include "smeRrmInternal.h" + + +//APIs +eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf); + +VOS_STATUS rrmClose (tpAniSirGlobal pMac); +VOS_STATUS rrmReady (tpAniSirGlobal pMac); +VOS_STATUS rrmOpen (tpAniSirGlobal pMac); +VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig); +VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo); + +tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac); +tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac, tpRrmNeighborReportDesc pBssEntry); +eHalStatus sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf); + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Trace.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Trace.h new file mode 100644 index 0000000000000..dfdb9962fc6ed --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/sme_Trace.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*********************************************************************** + sme_Trace.h + + \brief definition for trace related APIs + + \author Kiran Kumar Reddy CH L V + + ========================================================================*/ + +#ifndef __SME_TRACE_H__ +#define __SME_TRACE_H__ + + +#include "macTrace.h" + +#define NO_SESSION 0xFF +#define TRACE_CODE_SME_COMMAND 0xFF +enum { + TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, + TRACE_CODE_SME_RX_HDD_MSG_CONNECT, + TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, + TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, + TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, + TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, + TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, + TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, + TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, + TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, + TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, + TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, + TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, + TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, + TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE, + TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE, + TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE, + TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE, + TRACE_CODE_SME_RX_HDD_SIGNAL_POWER_EVENT, + TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER, + TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER, + TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED, + TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER, + TRACE_CODE_SME_RX_HDD_REQUEST_BMPS, + TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, + TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY, + TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, + TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, + TRACE_CODE_SME_RX_HDD_ENTER_WOWL, + TRACE_CODE_SME_RX_HDD_EXIT_WOWL, + TRACE_CODE_SME_RX_HDD_SET_KEY, + TRACE_CODE_SME_RX_HDD_REMOVE_KEY, + TRACE_CODE_SME_RX_HDD_GET_STATS, + TRACE_CODE_SME_RX_HDD_GET_RSSI, + TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT, + TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG, + TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG, + TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, + TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, + TRACE_CODE_SME_RX_HDD_DBG_READREG, + TRACE_CODE_SME_RX_HDD_DBG_WRITEREG, + TRACE_CODE_SME_RX_HDD_DBG_READMEM, + TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION, + TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, + TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, + TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD, + TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD, + TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS, + TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, + TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, + TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, + TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, + TRACE_CODE_SME_RX_HDD_SEND_ACTION, + TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, + TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, + TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, + TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, + TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, + TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, +#endif + TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, + TRACE_CODE_SME_RX_HDD_SET_TXPOW, + TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, + TRACE_CODE_SME_RX_HDD_CAPS_EXCH, + TRACE_CODE_SME_RX_HDD_DISABLE_CAP, + TRACE_CODE_SME_RX_HDD_GET_DEFCCNV, + TRACE_CODE_SME_RX_HDD_GET_CURCC, + TRACE_CODE_SME_RX_HDD_RESET_PW5G, + TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, + TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, + TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, + TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF, + TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF, + TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, + TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE, + TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, + TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, + TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES, + TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME, +}; + +void smeTraceInit(tpAniSirGlobal pMac); +#endif //__SME_TRACE_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/smsDebug.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/smsDebug.h new file mode 100644 index 0000000000000..c773d92221d34 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/smsDebug.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file cssDebug.h + + Define debug log interface for SMS. +========================================================================== */ + +#ifndef SMS_DEBUG_H__ +#define SMS_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) +smsLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...); + +void __printf(3,4) +pmcLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...); + +#endif // __SMS_DEBUG_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/inc/wlan_ps_wow_diag.h b/drivers/staging/qcacld-2.0/CORE/SME/inc/wlan_ps_wow_diag.h new file mode 100644 index 0000000000000..cd1c64b6848bd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/inc/wlan_ps_wow_diag.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_PS_WOW_DIAG_H_ +#define _WLAN_PS_WOW_DIAG_H_ + + +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +typedef enum +{ + WLAN_BMPS_ENTER_REQ =0, + WLAN_UAPSD_START_REQ =1, + WLAN_UAPSD_STOP_REQ =2, + WLAN_ENTER_STANDBY_REQ =3, + WLAN_ENTER_DEEP_SLEEP_REQ =4, + WLAN_START_BMPS_AUTO_TIMER_REQ =5, + WLAN_STOP_BMPS_AUTO_TIMER_REQ =6, + WLAN_IMPS_ENTER_REQ =7, + WLAN_ENTER_FULL_POWER_REQ =8, + WLAN_PMC_CURRENT_STATE =9, + WLAN_PS_MODE_ENABLE_REQ =10, + WLAN_PS_MODE_DISABLE_REQ =11, + WLAN_WINMOB_D_POWER_STATE =12, + WLAN_BMPS_DTIM_PERIOD =13, + WLAN_BMPS_FINAL_LI =14, + WLAN_BMPS_SET_CONFIG =15, + +} wlan_ps_evt_subtype_t; + +// maps directly to eRequestFullPowerReason +typedef enum +{ + WLAN_MISSED_BEACON_IND_RCVD, /* PE received a MAX_MISSED_BEACON_IND */ + WLAN_BMPS_STATUS_IND_RCVD, /* PE received a SIR_HAL_BMPS_STATUS_IND */ + WLAN_BMPS_MODE_DISABLED, /* BMPS mode was disabled by HDD in SME */ + WLAN_LINK_DISCONNECTED_BY_HDD, /* Link has been disconnected requested by HDD */ + WLAN_LINK_DISCONNECTED_BY_OTHER,/* Disconnect due to linklost or requested by peer */ + WLAN_FULL_PWR_NEEDED_BY_HDD, /* HDD request full power for some reason */ + WLAN_FULL_PWR_NEEDED_BY_BAP, /* BAP request full power for BT_AMP */ + WLAN_FULL_PWR_NEEDED_BY_CSR, /* CSR requests full power */ + WLAN_FULL_PWR_NEEDED_BY_QOS, /* QOS requests full power */ + WLAN_REASON_OTHER /* No specific reason. General reason code */ + +} wlan_ps_full_power_request_reason_t; + +// maps directly to ePmcState +typedef enum +{ + WLAN_PMC_STOPPED, /* PMC is stopped */ + WLAN_PMC_FULL_POWER, /* full power */ + WLAN_PMC_LOW_POWER, /* low power */ + WLAN_PMC_REQUEST_IMPS, /* requesting IMPS */ + WLAN_PMC_IMPS, /* in IMPS */ + WLAN_PMC_REQUEST_BMPS, /* requesting BMPS */ + WLAN_PMC_BMPS, /* in BMPS */ + WLAN_PMC_REQUEST_FULL_POWER, /* requesting full power */ + WLAN_PMC_REQUEST_START_UAPSD, /* requesting Start UAPSD */ + WLAN_PMC_REQUEST_STOP_UAPSD, /* requesting Stop UAPSD */ + WLAN_PMC_UAPSD, /* in UAPSD */ + WLAN_PMC_REQUEST_STANDBY, /* requesting standby mode */ + WLAN_PMC_STANDBY, /* in standby mode */ + WLAN_PMC_REQUEST_ENTER_WOWL, /* requesting enter WOWL */ + WLAN_PMC_REQUEST_EXIT_WOWL, /* requesting exit WOWL */ + WLAN_PMC_WOWL /* Chip in WOWL mode */ + +} wlan_ps_pmc_current_state_t; + +// maps directly to ePmcPowerSavingMode +typedef enum +{ + WLAN_IDLE_MODE_POWER_SAVE, /* Idle Mode Power Save (IMPS) */ + WLAN_BEACON_MODE_POWER_SAVE, /* Beacon Mode Power Save (BMPS) */ + WLAN_SPATIAL_MULTIPLEX_POWER_SAVE, /* Spatial Multiplexing Power Save (SMPS) */ + WLAN_UAPSD_MODE_POWER_SAVE, /* Unscheduled Automatic Power Save Delivery Mode */ + WLAN_STANDBY_MODE_POWER_SAVE, /* Standby Power Save Mode */ + WLAN_WOWL_MODE_POWER_SAVE /* Wake-on-Wireless LAN Power Save Mode */ + +} wlan_ps_enable_disable_ps_mode_t; + +typedef enum +{ + WLAN_D0, + WLAN_D1, + WLAN_D2, + WLAN_D3, + WLAN_D4 + +} wlan_ps_winmob_d_power_state_t; + +typedef enum +{ + WLAN_WOW_ENTER_REQ =0, + WLAN_WOW_EXIT_REQ =1, + WLAN_WOW_DEL_PTRN_REQ =2, + WLAN_WOW_WAKEUP = 3 + +} wlan_ps_wow_evt_subtype_t; + +typedef enum +{ + WLAN_WOW_TYPE_NONE, + WLAN_WOW_TYPE_MAGIC_PKT_ONLY, + WLAN_WOW_TYPE_PTRN_BYTE_MATCH_ONLY, + WLAN_WOW_TYPE_MAGIC_PKT_PTRN_BYTE_MATCH, + +} wlan_ps_wow_type_t; + +typedef enum +{ + WLAN_WOW_MAGIC_PKT_MATCH, + WLAN_WOW_PTRN_BYTE_MATCH + +} wlan_ps_wos_wakeup_cause_t; + +#endif // FEATURE_WLAN_DIAG_SUPPORT + +#endif // _WLAN_PS_WOW_DIAG_H_ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/QoS/sme_Qos.c b/drivers/staging/qcacld-2.0/CORE/SME/src/QoS/sme_Qos.c new file mode 100644 index 0000000000000..6665d87b605ab --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/QoS/sme_Qos.c @@ -0,0 +1,8565 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file sme_Qos.c + + \brief implementation for SME QoS APIs + + ========================================================================*/ +/* $Header$ */ +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + +#include "aniGlobal.h" + +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" + +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "smsDebug.h" +#include "utilsParser.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include +#endif + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/* TODO : 6Mbps as Cisco APs seem to like only this value; analysis req. */ +#define SME_QOS_MIN_PHY_RATE 0x5B8D80 +#define SME_QOS_SURPLUS_BW_ALLOWANCE 0x2000 /* Ratio of 1.0 */ +/*--------------------------------------------------------------------------- + Max values to bound tspec params against and avoid rollover +---------------------------------------------------------------------------*/ +#define SME_QOS_32BIT_MAX 0xFFFFFFFF +#define SME_QOS_16BIT_MAX 0xFFFF +#define SME_QOS_16BIT_MSB 0x8000 +/*--------------------------------------------------------------------------- + Adds y to x, but saturates at 32-bit max to avoid rollover +---------------------------------------------------------------------------*/ +#define SME_QOS_BOUNDED_U32_ADD_Y_TO_X( _x, _y ) \ + do \ + { \ + (_x) = ( (SME_QOS_32BIT_MAX-(_x))<(_y) ) ? \ + (SME_QOS_32BIT_MAX) : (_x)+(_y); \ + } while(0) +/*--------------------------------------------------------------------------- + As per WMM spec there could be max 2 TSPEC running on the same AC with + different direction. We will refer each TSPEC with an index +---------------------------------------------------------------------------*/ +#define SME_QOS_TSPEC_INDEX_0 0 +#define SME_QOS_TSPEC_INDEX_1 1 +#define SME_QOS_TSPEC_INDEX_MAX 2 +#define SME_QOS_TSPEC_MASK_BIT_1_SET 1 +#define SME_QOS_TSPEC_MASK_BIT_2_SET 2 +#define SME_QOS_TSPEC_MASK_BIT_1_2_SET 3 +#define SME_QOS_TSPEC_MASK_CLEAR 0 + +//which key to search on, in the flowlist (1 = flowID, 2 = AC, 4 = reason) +#define SME_QOS_SEARCH_KEY_INDEX_1 1 +#define SME_QOS_SEARCH_KEY_INDEX_2 2 +#define SME_QOS_SEARCH_KEY_INDEX_3 4 +#define SME_QOS_SEARCH_KEY_INDEX_4 8 // ac + direction +#define SME_QOS_SEARCH_KEY_INDEX_5 0x10 // ac + tspec_mask +//special value for searching any Session Id +#define SME_QOS_SEARCH_SESSION_ID_ANY CSR_ROAM_SESSION_MAX +#define SME_QOS_ACCESS_POLICY_EDCA 1 +#define SME_QOS_MAX_TID 255 +#define SME_QOS_TSPEC_IE_LENGTH 61 +#define SME_QOS_TSPEC_IE_TYPE 2 +#define SME_QOS_MIN_FLOW_ID 1 +#define SME_QOS_MAX_FLOW_ID 0xFFFFFFFE +#define SME_QOS_INVALID_FLOW_ID 0xFFFFFFFF +// per the WMM Specification v1.2 Section 2.2.10 +// The Dialog Token field shall be set [...] to a non-zero value +#define SME_QOS_MIN_DIALOG_TOKEN 1 +#define SME_QOS_MAX_DIALOG_TOKEN 0xFF +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + Enumeration of the various states in the QoS state m/c +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_CLOSED = 0, + SME_QOS_INIT, + SME_QOS_LINK_UP, + SME_QOS_REQUESTED, + SME_QOS_QOS_ON, + SME_QOS_HANDOFF, + +}sme_QosStates; +/*--------------------------------------------------------------------------- + Enumeration of the various Release QoS trigger +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_RELEASE_DEFAULT = 0, + SME_QOS_RELEASE_BY_AP, +}sme_QosRelTriggers; +/*--------------------------------------------------------------------------- + Enumeration of the various QoS cmds +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_SETUP_REQ = 0, + SME_QOS_RELEASE_REQ, + SME_QOS_MODIFY_REQ, + SME_QOS_RESEND_REQ, + SME_QOS_CMD_MAX +}sme_QosCmdType; +/*--------------------------------------------------------------------------- + Enumeration of the various QoS reason codes to be used in the Flow list +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_REASON_SETUP = 0, + SME_QOS_REASON_RELEASE, + SME_QOS_REASON_MODIFY, + SME_QOS_REASON_MODIFY_PENDING, + SME_QOS_REASON_REQ_SUCCESS, + SME_QOS_REASON_MAX +}sme_QosReasonType; + +/*--------------------------------------------------------------------------- + Table to map user priority passed in as an argument to appropriate Access + Category as specified in 802.11e/WMM +---------------------------------------------------------------------------*/ +sme_QosEdcaAcType sme_QosUPtoACMap[SME_QOS_WMM_UP_MAX] = +{ + SME_QOS_EDCA_AC_BE, /* User Priority 0 */ + SME_QOS_EDCA_AC_BK, /* User Priority 1 */ + SME_QOS_EDCA_AC_BK, /* User Priority 2 */ + SME_QOS_EDCA_AC_BE, /* User Priority 3 */ + SME_QOS_EDCA_AC_VI, /* User Priority 4 */ + SME_QOS_EDCA_AC_VI, /* User Priority 5 */ + SME_QOS_EDCA_AC_VO, /* User Priority 6 */ + SME_QOS_EDCA_AC_VO /* User Priority 7 */ +}; + +/*--------------------------------------------------------------------------- + Table to map access category (AC) to appropriate user priority as specified + in 802.11e/WMM + Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs + Mapping is done for consistency +---------------------------------------------------------------------------*/ +sme_QosWmmUpType sme_QosACtoUPMap[SME_QOS_EDCA_AC_MAX] = +{ + SME_QOS_WMM_UP_BE, /* AC BE */ + SME_QOS_WMM_UP_BK, /* AC BK */ + SME_QOS_WMM_UP_VI, /* AC VI */ + SME_QOS_WMM_UP_VO /* AC VO */ +}; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's FLOW Link List structure. This list can hold information per + flow/request, like TSPEC params requested, which AC it is running on +---------------------------------------------------------------------------*/ +typedef struct sme_QosFlowInfoEntry_s +{ + tListElem link; /* list links */ + v_U8_t sessionId; + v_U8_t tspec_mask; + sme_QosReasonType reason; + v_U32_t QosFlowID; + sme_QosEdcaAcType ac_type; + sme_QosWmmTspecInfo QoSInfo; + void * HDDcontext; + sme_QosCallback QoSCallback; + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +} sme_QosFlowInfoEntry; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's setup request cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosSetupCmdInfo_s +{ + v_U32_t QosFlowID; + sme_QosWmmTspecInfo QoSInfo; + void *HDDcontext; + sme_QosCallback QoSCallback; + sme_QosWmmUpType UPType; + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +} sme_QosSetupCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's modify cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosModifyCmdInfo_s +{ + v_U32_t QosFlowID; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo QoSInfo; +} sme_QosModifyCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's resend cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosResendCmdInfo_s +{ + v_U8_t tspecMask; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo QoSInfo; +} sme_QosResendCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's release cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosReleaseCmdInfo_s +{ + v_U32_t QosFlowID; +} sme_QosReleaseCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's buffered cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosCmdInfo_s +{ + sme_QosCmdType command; + tpAniSirGlobal pMac; + v_U8_t sessionId; + union + { + sme_QosSetupCmdInfo setupCmdInfo; + sme_QosModifyCmdInfo modifyCmdInfo; + sme_QosResendCmdInfo resendCmdInfo; + sme_QosReleaseCmdInfo releaseCmdInfo; + }u; +} sme_QosCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's buffered cmd List structure. This list can hold information + related to any pending cmd from HDD +---------------------------------------------------------------------------*/ +typedef struct sme_QosCmdInfoEntry_s +{ + tListElem link; /* list links */ + sme_QosCmdInfo cmdInfo; +} sme_QosCmdInfoEntry; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's Per AC information structure. This can hold information on + how many flows running on the AC, the current, previous states the AC is in +---------------------------------------------------------------------------*/ +typedef struct sme_QosACInfo_s +{ + v_U8_t num_flows[SME_QOS_TSPEC_INDEX_MAX]; + sme_QosStates curr_state; + sme_QosStates prev_state; + sme_QosWmmTspecInfo curr_QoSInfo[SME_QOS_TSPEC_INDEX_MAX]; + sme_QosWmmTspecInfo requested_QoSInfo[SME_QOS_TSPEC_INDEX_MAX]; + v_BOOL_t reassoc_pending;//reassoc requested for APSD + //As per WMM spec there could be max 2 TSPEC running on the same AC with + //different direction. We will refer each TSPEC with an index + v_U8_t tspec_mask_status; //status showing if both the indices are in use + v_U8_t tspec_pending;//tspec negotiation going on for which index + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +#ifdef WLAN_FEATURE_VOWIFI_11R + v_U8_t ricIdentifier[SME_QOS_TSPEC_INDEX_MAX]; + /* stores the ADD TS response for each AC. The ADD TS response is formed by + parsing the RIC received in the the reassoc response */ + tSirAddtsRsp addTsRsp[SME_QOS_TSPEC_INDEX_MAX]; +#endif + sme_QosRelTriggers relTrig; + +} sme_QosACInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's Per session information structure. This can hold information + on the state of the session +---------------------------------------------------------------------------*/ +typedef struct sme_QosSessionInfo_s +{ + // what is this entry's session id + v_U8_t sessionId; + // is the session currently active + v_BOOL_t sessionActive; + // All AC info for this session + sme_QosACInfo ac_info[SME_QOS_EDCA_AC_MAX]; + // Bitmask of the ACs with APSD on + // Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored + v_U8_t apsdMask; + // association information for this session + sme_QosAssocInfo assocInfo; + // ID assigned to our reassoc request + v_U32_t roamID; + // maintaining a powersave status in QoS module, to be fed back to PMC at + // times through the sme_QosPmcCheckRoutine + v_BOOL_t readyForPowerSave; + // are we in the process of handing off to a different AP + v_BOOL_t handoffRequested; + // following reassoc or AddTS has UAPSD already been requested from PMC + v_BOOL_t uapsdAlreadyRequested; + // commands that are being buffered for this session + tDblLinkList bufferedCommandList; + +#ifdef WLAN_FEATURE_VOWIFI_11R + v_BOOL_t ftHandoffInProgress; +#endif + +} sme_QosSessionInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + Search key union. We can use the flowID, ac type, or reason to find an entry + in the flow list +---------------------------------------------------------------------------*/ +typedef union sme_QosSearchKey_s +{ + v_U32_t QosFlowID; + sme_QosEdcaAcType ac_type; + sme_QosReasonType reason; +}sme_QosSearchKey; +/*--------------------------------------------------------------------------- +DESCRIPTION + We can either use the flowID or the ac type to find an entry in the flow list. + The index is a bitmap telling us which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type +---------------------------------------------------------------------------*/ +typedef struct sme_QosSearchInfo_s +{ + v_U8_t sessionId; + v_U8_t index; + sme_QosSearchKey key; + sme_QosWmmDirType direction; + v_U8_t tspec_mask; +}sme_QosSearchInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's internal control block. +---------------------------------------------------------------------------*/ +struct sme_QosCb_s +{ + //global Mac pointer + tpAniSirGlobal pMac; + //All Session Info + sme_QosSessionInfo sessionInfo[CSR_ROAM_SESSION_MAX]; + //All FLOW info + tDblLinkList flow_list; + //default TSPEC params + sme_QosWmmTspecInfo def_QoSInfo[SME_QOS_EDCA_AC_MAX]; + //counter for assigning Flow IDs + v_U32_t nextFlowId; + //counter for assigning Dialog Tokens + v_U8_t nextDialogToken; +}sme_QosCb; +typedef eHalStatus (*sme_QosProcessSearchEntry)(tpAniSirGlobal pMac, tListElem *pEntry); +/*-------------------------------------------------------------------------- + Internal function declarations + ------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd, + v_BOOL_t hoRenewal); +sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd); +sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd); +sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo *pTspec_Info, + sme_QosEdcaAcType ac); +eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pTspec_Info, + sme_QosEdcaAcType ac); +eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask); +eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +#ifdef WLAN_FEATURE_VOWIFI_11R +eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId ); +#endif +eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp); +eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp); +eHalStatus sme_QosAggregateParams( + sme_QosWmmTspecInfo * pInput_Tspec_Info, + sme_QosWmmTspecInfo * pCurrent_Tspec_Info, + sme_QosWmmTspecInfo * pUpdated_Tspec_Info); +static eHalStatus sme_QosUpdateParams(v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask, + sme_QosWmmTspecInfo * pTspec_Info); +sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac); +sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up); +v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes); +tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key); +eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac, + sme_QosSearchInfo search_key, + sme_QosProcessSearchEntry fnp); +static void sme_QosStateTransition(v_U8_t sessionId, + sme_QosEdcaAcType ac, + sme_QosStates new_state); +eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head); +static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId); +eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info); +eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry); +static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac); +static v_BOOL_t sme_QosIsUapsdActive(void); +void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status); +void sme_QosPmcOffloadFullPowerCallback(void *callbackContext, tANI_U32 sessionId, + eHalStatus status); + +void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status); +void sme_QosPmcOffloadStartUapsdCallback(void *callbackContext, + tANI_U32 sessionId, eHalStatus status); +v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext); +v_BOOL_t sme_QosPmcOffloadCheckRoutine(void *callbackContext, tANI_U32 sessionId); + +void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState); +void sme_OffloadQosPmcDeviceStateUpdateInd(void *callbackContext, + tANI_U32 sessionId, tPmcState pmcState); + +eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac); +eHalStatus sme_OffloadQosProcessOutOfUapsdMode(tpAniSirGlobal pMac, + tANI_U32 sessionId); +eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac); +eHalStatus sme_OffloadQosProcessIntoUapsdMode(tpAniSirGlobal pMac, + tANI_U32 sessionId); +static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId); +static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId); +static void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac, + v_U8_t sessionId); +static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac, + v_U8_t sessionId); +v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId); + +extern eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme); +extern eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme); +static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId, + eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, v_U8_t tspec_mask ); +/* + sme_QosReRequestAddTS to re-send AddTS for the combined QoS request +*/ +static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, + v_U8_t tspecMask); +static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId); +static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId, + tCsrRoamModifyProfileFields *pModFields, + v_BOOL_t fForce ); +static v_U32_t sme_QosAssignFlowId(void); +static v_U8_t sme_QosAssignDialogToken(void); +static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId, + sme_QosSearchInfo search_key, + v_U8_t new_tspec_mask); +/*-------------------------------------------------------------------------- + External APIs definitions + ------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------------- + \brief sme_QosOpen() - This function must be called before any API call to + SME QoS module. + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosOpen(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + eHalStatus status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: initializing SME-QoS module", + __func__, __LINE__); + //init the control block + //(note that this will make all sessions invalid) + vos_mem_zero(&sme_QosCb, sizeof(sme_QosCb)); + sme_QosCb.pMac = pMac; + sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID; + sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN; + //init flow list + status = csrLLOpen(pMac->hHdd, &sme_QosCb.flow_list); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot initialize Flow List", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + pSession->sessionId = sessionId; + // initialize the session's per-AC information + sme_QosInitACs(pMac, sessionId); + // initialize the session's buffered command list + status = csrLLOpen(pMac->hHdd, &pSession->bufferedCommandList); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot initialize cmd list for session %d", + __func__, __LINE__, + sessionId); + return eHAL_STATUS_FAILURE; + } + pSession->readyForPowerSave = VOS_TRUE; + + if(pMac->psOffloadEnabled) + { + if(eHAL_STATUS_SUCCESS != pmcOffloadRegisterPowerSaveCheck(pMac, + sessionId, sme_QosPmcOffloadCheckRoutine, pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcOffloadRegisterPowerSaveCheck()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + if(eHAL_STATUS_SUCCESS != pmcOffloadRegisterDeviceStateUpdateInd(pMac, + sessionId, sme_OffloadQosPmcDeviceStateUpdateInd, pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcOffloadRegisterPowerSaveCheck()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + } + } + + if(!pMac->psOffloadEnabled) + { + //the routine registered here gets called by PMC + //whenever the device is about + //to enter one of the power save modes. + //PMC runs a poll with all the + //registered modules if device can enter + //powersave mode or remain full power + if(!HAL_STATUS_SUCCESS( + pmcRegisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcRegisterPowerSaveCheck()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + //the routine registered here gets called by PMC + //whenever there is a device + // state change. PMC might go to full power + //because of many reasons and this + // is the way for PMC to inform all the other + //registered modules so that + // everyone is in sync. + if(!HAL_STATUS_SUCCESS( + pmcRegisterDeviceStateUpdateInd(pMac, + sme_QosPmcDeviceStateUpdateInd, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcRegisterDeviceStateUpdateInd()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: done initializing SME-QoS module", + __func__, __LINE__); + return eHAL_STATUS_SUCCESS; +} +/* -------------------------------------------------------------------------- + \brief sme_QosClose() - To close down SME QoS module. There should not be + any API call into this module after calling this function until another + call of sme_QosOpen. + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosClose(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + v_U8_t sessionId; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: closing down SME-QoS", + __func__, __LINE__); + if(!pMac->psOffloadEnabled) + { + // deregister with PMC + if(!HAL_STATUS_SUCCESS( + pmcDeregisterDeviceStateUpdateInd(pMac, + sme_QosPmcDeviceStateUpdateInd))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister pmcDeregisterDeviceStateUpdateInd()", + __func__, __LINE__); + } + if(!HAL_STATUS_SUCCESS( + pmcDeregisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister with pmcDeregisterPowerSaveCheck()", + __func__, __LINE__); + } + } + else + { + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + /* deregister with PMC */ + if(!HAL_STATUS_SUCCESS( + pmcOffloadDeregisterDeviceStateUpdateInd(pMac, sessionId, + sme_OffloadQosPmcDeviceStateUpdateInd))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister DeviceStateUpdateInd()", + __func__, __LINE__); + } + if(!HAL_STATUS_SUCCESS( + pmcOffloadDeregisterPowerSaveCheck(pMac, sessionId, + sme_QosPmcOffloadCheckRoutine))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister with PowerSaveCheck()", + __func__, __LINE__); + } + } + } + + //cleanup control block + //close the flow list + csrLLClose(&sme_QosCb.flow_list); + // shut down all of the sessions + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if (pSession == NULL) + continue; + + sme_QosInitACs(pMac, sessionId); + // this session doesn't require UAPSD + pSession->apsdMask = 0; + + pSession->uapsdAlreadyRequested = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + pSession->roamID = 0; + //need to clean up buffered req + sme_QosDeleteBufferedRequests(pMac, sessionId); + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + + // Clean up the assoc info if already allocated + if (pSession->assocInfo.pBssDesc) { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + + // close the session's buffered command list + csrLLClose(&pSession->bufferedCommandList); + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_CLOSED); + } + pSession->sessionActive = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: closed down QoS", + __func__, __LINE__); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSetupReq() - The SME QoS API exposed to HDD to request for QoS + on a particular AC. This function should be called after a link has been + established, i.e. STA is associated with an AP etc. If the request involves + admission control on the requested AC, HDD needs to provide the necessary + Traffic Specification (TSPEC) parameters otherwise SME is going to use the + default params. + + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId returned by sme_OpenSession. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param pQosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Setup is successful. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetupReq(tHalHandle hHal, tANI_U32 sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, v_U32_t * pQosFlowID) +{ + sme_QosSessionInfo *pSession; + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Setup requested by client on session %d", + __func__, __LINE__, + sessionId); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + //Make sure the session is valid + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Supplied Session ID %d is invalid", + __func__, __LINE__, + sessionId); + status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + else + { + //Make sure the session is active + pSession = &sme_QosCb.sessionInfo[sessionId]; + if (!pSession->sessionActive) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Supplied Session ID %d is inactive", + __func__, __LINE__, + sessionId); + status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + else + { + //Assign a Flow ID + *pQosFlowID = sme_QosAssignFlowId(); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS request on session %d assigned Flow ID %d", + __func__, __LINE__, + sessionId, *pQosFlowID); + //Call the internal function for QoS setup, + // adding a layer of abstraction + status = sme_QosInternalSetupReq(pMac, (v_U8_t)sessionId, pQoSInfo, + QoSCallback, HDDcontext, UPType, + *pQosFlowID, VOS_FALSE, VOS_FALSE); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS setup return status on session %d is %d", + __func__, __LINE__, + sessionId, status); + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosModifyReq() - The SME QoS API exposed to HDD to request for + modification of certain QoS params on a flow running on a particular AC. + This function should be called after a link has been established, i.e. STA is + associated with an AP etc. & a QoS setup has been succesful for that flow. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param hHal - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosModifyReq(tHalHandle hHal, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID) +{ + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Modify requested by client for Flow %d", + __func__, __LINE__, + QosFlowID); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + //Call the internal function for QoS modify, adding a layer of abstraction + status = sme_QosInternalModifyReq(pMac, pQoSInfo, QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Modify return status on Flow %d is %d", + __func__, __LINE__, + QosFlowID, status); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosReleaseReq() - The SME QoS API exposed to HDD to request for + releasing a QoS flow running on a particular AC. This function should be + called only if a QoS is set up with a valid FlowID. HDD sould invoke this + API only if an explicit request for QoS release has come from Application + + \param hHal - The handle returned by macOpen. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Release is successful. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosReleaseReq(tHalHandle hHal, v_U32_t QosFlowID) +{ + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release requested by client for Flow %d", + __func__, __LINE__, + QosFlowID); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + //Call the internal function for QoS release, adding a layer of abstraction + status = sme_QosInternalReleaseReq(pMac, QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release return status on Flow %d is %d", + __func__, __LINE__, + QosFlowID, status); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSetParams() - This function is used by HDD to provide the + default TSPEC params to SME. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info per AC as defined above, provided by HDD + + \return eHAL_STATUS_SUCCESS - Setparam is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetParams(tpAniSirGlobal pMac, sme_QosWmmTspecInfo * pQoSInfo) +{ + sme_QosEdcaAcType ac; + // find the AC + ac = sme_QosUpToAc(pQoSInfo->ts_info.up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Invalid AC %d (via UP %d)", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up ); + return eHAL_STATUS_FAILURE; + } + //copy over the default params for this AC + sme_QosCb.def_QoSInfo[ac] = *pQoSInfo; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS default params set for AC %d (via UP %d)", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up ); + return eHAL_STATUS_SUCCESS; +} + +void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + vos_mem_zero( &pCommand->u.qosCmd, sizeof( tGenericQosCmd ) ); + smeReleaseCommand( pMac, pCommand ); +} + +/*-------------------------------------------------------------------------- + \brief sme_QosMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry; + tSmeCmd *pCommand; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: msg = %d for QoS", + __func__, __LINE__, msg_type); + //switch on the msg type & make the state transition accordingly + switch(msg_type) + { + case eWNI_SME_ADDTS_RSP: + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandAddTs == pCommand->command ) + { + status = sme_QosProcessAddTsRsp(pMac, pMsgBuf); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + qosReleaseCommand( pMac, pCommand ); + } + smeProcessPendingQueue( pMac ); + } + } + break; + case eWNI_SME_DELTS_RSP: + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandDelTs == pCommand->command ) + { + status = sme_QosProcessDelTsRsp(pMac, pMsgBuf); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + qosReleaseCommand( pMac, pCommand ); + } + smeProcessPendingQueue( pMac ); + } + } + break; + case eWNI_SME_DELTS_IND: + status = sme_QosProcessDelTsInd(pMac, pMsgBuf); + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_AGGR_QOS_RSP: + status = sme_QosProcessAggrQosRsp(pMac, pMsgBuf); + break; +#endif + + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unknown msg type = %d", + __func__, __LINE__, msg_type); + break; + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosValidateParams() - The SME QoS API exposed to CSR to validate AP + capabilities regarding QoS support & any other QoS parameter validation. + + \param pMac - Pointer to the global MAC parameter structure. + \param pBssDesc - Pointer to the BSS Descriptor information passed down by + CSR to PE while issuing the Join request + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosValidateParams(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc) +{ + tDot11fBeaconIEs *pIes = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: validation for QAP & APSD", + __func__, __LINE__); + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: csrGetParsedBssDescriptionIEs() failed", + __func__, __LINE__); + break; + } + //check if the AP is QAP & it supports APSD + if( !CSR_IS_QOS_BSS(pIes) ) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: AP doesn't support QoS", + __func__, __LINE__); + + break; + } + if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: AP doesn't support APSD", + __func__, __LINE__); + break; + } + status = eHAL_STATUS_SUCCESS; + }while(0); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: validated with status = %d", + __func__, __LINE__, status); + if(pIes) + { + vos_mem_free(pIes); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosCsrEventInd() - The QoS sub-module in SME expects notifications + from CSR when certain events occur as mentioned in sme_QosCsrEventIndType. + \param pMac - Pointer to the global MAC parameter structure. + \param ind - The event occurred of type sme_QosCsrEventIndType. + \param pEvent_info - Information related to the event + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosCsrEventInd(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosCsrEventIndType ind, + void *pEvent_info) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On Session %d Event %d received from CSR", + __func__, __LINE__, + sessionId, ind ); + switch(ind) + { + case SME_QOS_CSR_ASSOC_COMPLETE: + //expecting assoc info in pEvent_info + status = sme_QosProcessAssocCompleteEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessReassocReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_COMPLETE: + //expecting assoc info in pEvent_info + status = sme_QosProcessReassocSuccessEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_FAILURE: + //nothing expected in pEvent_info + status = sme_QosProcessReassocFailureEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_DISCONNECT_REQ: + case SME_QOS_CSR_DISCONNECT_IND: + //nothing expected in pEvent_info + status = sme_QosProcessDisconnectEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_JOIN_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessJoinReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_ASSOC_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffAssocReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_COMPLETE: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffSuccessEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_FAILURE: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffFailureEv(pMac, sessionId, pEvent_info); + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SME_QOS_CSR_PREAUTH_SUCCESS_IND: + status = sme_QosProcessPreauthSuccessInd(pMac, sessionId, pEvent_info); + break; +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + case SME_QOS_CSR_SET_KEY_SUCCESS_IND: + status = sme_QosProcessSetKeySuccessInd(pMac, sessionId, pEvent_info); + break; +#endif +#endif + default: + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d Unknown Event %d received from CSR", + __func__, __LINE__, + sessionId, ind ); + break; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On Session %d processed Event %d with status %d", + __func__, __LINE__, + sessionId, ind, status ); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosGetACMMask() - The QoS sub-module API to find out on which ACs + AP mandates Admission Control (ACM = 1) + (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) + \param pMac - Pointer to the global MAC parameter structure. + \param pSirBssDesc - The event occurred of type sme_QosCsrEventIndType. + + \return a bit mask indicating for which ACs AP has ACM set to 1 + + \sa + + --------------------------------------------------------------------------*/ +v_U8_t sme_QosGetACMMask(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes) +{ + sme_QosEdcaAcType ac; + v_U8_t acm_mask = 0; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked", + __func__, __LINE__); + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + if(sme_QosIsACM(pMac, pSirBssDesc, ac, pIes)) + { + acm_mask = acm_mask | (1 << (SME_QOS_EDCA_AC_VO - ac)); + } + + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: mask is %d", + __func__, __LINE__, acm_mask); + return acm_mask; +} +/*-------------------------------------------------------------------------- + Internal function definitions + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + \brief sme_QosInternalSetupReq() - The SME QoS internal setup request handling + function. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters otherwise SME + is going to use the default params. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + \param buffered_cmd - tells us if the cmd was a buffered one or fresh from + client + + \return eHAL_STATUS_SUCCESS - Setup is successful. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd, + v_BOOL_t hoRenewal) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo Tspec_Info; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosFlowInfoEntry *pentry = NULL; + sme_QosCmdInfo cmd; + sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + v_U8_t tmask = 0; + v_U8_t new_tmask = 0; + sme_QosSearchInfo search_key; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for flow %d", + __func__, __LINE__, + sessionId, QosFlowID); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // if caller sent an empty TSPEC, fill up with the default one + if(!pQoSInfo) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: caller sent an empty QoS param list, using defaults", + __func__, __LINE__); + // find the AC with UPType passed in + ac = sme_QosUpToAc(UPType); + if(SME_QOS_EDCA_AC_MAX == ac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, UPType); + + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + Tspec_Info = sme_QosCb.def_QoSInfo[ac]; + } + else + { + // find the AC + ac = sme_QosUpToAc(pQoSInfo->ts_info.up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up); + + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + //validate QoS params + if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid params", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + Tspec_Info = *pQoSInfo; + } + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the setup request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // an AddTS or reassoc if necessary + if(!pMac->psOffloadEnabled) + { + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + else + { + hstatus = pmcOffloadRequestFullPower(pMac, sessionId, + sme_QosPmcOffloadFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the setup request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = Tspec_Info; + cmd.u.setupCmdInfo.QoSCallback = QoSCallback; + cmd.u.setupCmdInfo.UPType = UPType; + cmd.u.setupCmdInfo.hoRenewal = hoRenewal; + cmd.u.setupCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the setup request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered setup request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + } + + //get into the state m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + //call the internal qos setup logic to decide on if the + // request is NOP, or need reassoc for APSD and/or need to send out ADDTS + status = sme_QosSetup(pMac, sessionId, &Tspec_Info, ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_LINK_UP " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + // we received an expected "good" status + //create an entry in the flow list + pentry = vos_mem_malloc(sizeof(*pentry)); + if (!pentry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pentry->ac_type = ac; + pentry->HDDcontext = HDDcontext; + pentry->QoSCallback = QoSCallback; + pentry->hoRenewal = hoRenewal; + pentry->QosFlowID = QosFlowID; + pentry->sessionId = sessionId; + // since we are in state SME_QOS_LINK_UP this must be the + // first TSPEC on this AC, so use index 0 (mask bit 1) + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info; + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + if(pACInfo->tspec_mask_status && + !pACInfo->reassoc_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d with AC %d in state " + "SME_QOS_LINK_UP tspec_mask_status is %d " + "but should not be set yet", + __func__, __LINE__, + sessionId, ac, pACInfo->tspec_mask_status); + VOS_ASSERT(0); + vos_mem_free(pentry); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + if(!pACInfo->reassoc_pending) + { + // we didn't request for reassoc, it must be a tspec negotiation + pACInfo->tspec_pending = 1; + } + + pentry->reason = SME_QOS_REASON_SETUP; + new_state = SME_QOS_REQUESTED; + } + else + { + // SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP or + // SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY + pentry->reason = SME_QOS_REASON_REQ_SUCCESS; + new_state = SME_QOS_QOS_ON; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info; + if(buffered_cmd && !pentry->hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + status, + pentry->QosFlowID); + } + pentry->hoRenewal = VOS_FALSE; + } + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]++; + + //indicate on which index the flow entry belongs to & add it to the + //Flow List at the end + pentry->tspec_mask = pACInfo->tspec_mask_status; + pentry->QoSInfo = Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Creating entry on session %d at %p with flowID %d", + __func__, __LINE__, + sessionId, pentry, QosFlowID); + csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE); + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = pACInfo->curr_state; + if(buffered_cmd && hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + QosFlowID); + } + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: Buffering setup request for flow %d in state = %d", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + //buffer cmd + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = Tspec_Info; + cmd.u.setupCmdInfo.QoSCallback = QoSCallback; + cmd.u.setupCmdInfo.UPType = UPType; + cmd.u.setupCmdInfo.hoRenewal = hoRenewal; + cmd.u.setupCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d couldn't buffer the setup " + "request for flow %d in state = %d", + __func__, __LINE__, + sessionId, QosFlowID, pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + new_state = pACInfo->curr_state; + break; + case SME_QOS_QOS_ON: + + //check if multiple flows running on the ac + if((pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] > 0)|| + (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) + { + //do we need to care about the case where APSD needed on ACM = 0 below? + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac); + if(!pACInfo->tspec_mask_status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: tspec_mask_status can't be 0 for ac = %d in " + "state = %d", + __func__, __LINE__, + ac, pACInfo->curr_state); + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return status; + } + /* Flow aggregation */ + if ( ((pACInfo->tspec_mask_status > 0) && + (pACInfo->tspec_mask_status <= SME_QOS_TSPEC_INDEX_MAX)) ) + { + /* Either of upstream, downstream or bidirectional flows are present */ + /* If either of new stream or current stream is for bidirecional, aggregate + * the new stream with the current streams present and send out aggregated Tspec.*/ + if((Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) || + (pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1]. + ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH)) + { + // Aggregate the new stream with the current stream(s). + tmask = pACInfo->tspec_mask_status; + } + /* None of new stream or current (aggregated) streams are for bidirectional. + * Check if the new stream direction matches the current stream direction. */ + else if(pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1]. + ts_info.direction == Tspec_Info.ts_info.direction) + { + // Aggregate the new stream with the current stream(s). + tmask = pACInfo->tspec_mask_status; + } + /* New stream is in different direction. */ + else + { + // No Aggregation. Mark the 2nd tpsec index also as active. + tmask = SME_QOS_TSPEC_MASK_CLEAR; + new_tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~pACInfo->tspec_mask_status; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + } + } + else if(SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status) + { + /* Both uplink and downlink streams are present. */ + /* If new stream is bidirectional, aggregate new stream with all existing + * upstreams and downstreams. Send out new aggregated tpsec. */ + if(Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) + { + // Only one tspec index (0) will be in use after this aggregation. + tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + /* New stream is also uni-directional + * Find out the tsepc index with which it needs to be aggregated */ + else if(pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.direction != + Tspec_Info.ts_info.direction) + { + // Aggregate with 2nd tspec index + tmask = SME_QOS_TSPEC_MASK_BIT_2_SET; + } + else + { + // Aggregate with 1st tspec index + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: wrong tmask = %d", __func__, __LINE__, + pACInfo->tspec_mask_status ); + } + } + else + { + //ACM = 0 + // We won't be sending a TSPEC to the AP but we still need + // to aggregate to calculate trigger frame parameters + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tmask = %d, new_tmask = %d in state = %d", + __func__, __LINE__, + tmask, new_tmask, pACInfo->curr_state ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac); + if(tmask) + { + // create the aggregate TSPEC + if(tmask != SME_QOS_TSPEC_MASK_BIT_1_2_SET) + { + hstatus = sme_QosAggregateParams(&Tspec_Info, + &pACInfo->curr_QoSInfo[tmask - 1], + &pACInfo->requested_QoSInfo[tmask - 1]); + } + else + { + /* Aggregate the new bidirectional stream with the existing upstreams and + * downstreams in tspec indices 0 and 1. */ + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + + if((hstatus = sme_QosAggregateParams(&Tspec_Info, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + &pACInfo->requested_QoSInfo[tmask - 1])) + == eHAL_STATUS_SUCCESS) + { + hstatus = sme_QosAggregateParams(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + &pACInfo->requested_QoSInfo[tmask - 1], + NULL); + } + } + + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: failed to aggregate params", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + } + else + { + if (!(new_tmask > 0 && new_tmask <= SME_QOS_TSPEC_INDEX_MAX)) + { + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + tmask = new_tmask; + pACInfo->requested_QoSInfo[tmask-1] = Tspec_Info; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no flows running for ac = %d while in state = %d", + __func__, __LINE__, + ac, pACInfo->curr_state ); + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return status; + } + //although aggregating, make sure to request on the correct UP,TID,PSB and direction + pACInfo->requested_QoSInfo[tmask - 1].ts_info.up = Tspec_Info.ts_info.up; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.tid = Tspec_Info.ts_info.tid; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.direction = Tspec_Info.ts_info.direction; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.psb = Tspec_Info.ts_info.psb; + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[tmask - 1], ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + // we received an expected "good" status + //create an entry in the flow list + pentry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pentry)); + if (!pentry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pentry->ac_type = ac; + pentry->HDDcontext = HDDcontext; + pentry->QoSCallback = QoSCallback; + pentry->hoRenewal = hoRenewal; + pentry->QosFlowID = QosFlowID; + pentry->sessionId = sessionId; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Creating flow %d", + __func__, __LINE__, + QosFlowID); + if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = pACInfo->curr_state; + pentry->reason = SME_QOS_REASON_REQ_SUCCESS; + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0]; + if(buffered_cmd && !pentry->hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + status, + pentry->QosFlowID); + } + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + // if we are not in handoff, then notify all flows on + // this AC that the aggregate TSPEC may have changed + if(!pentry->hoRenewal) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosSetupFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + } + pentry->hoRenewal = VOS_FALSE; + } + else + { + // SME_QOS_STATUS_SETUP_REQ_PENDING_RSP + new_state = SME_QOS_REQUESTED; + pentry->reason = SME_QOS_REASON_SETUP; + //Need this info when addts comes back from PE to know on + //which index of the AC the request was from + pACInfo->tspec_pending = tmask; + } + pACInfo->num_flows[tmask - 1]++; + //indicate on which index the flow entry belongs to & add it to the + //Flow List at the end + pentry->tspec_mask = tmask; + pentry->QoSInfo = Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d creating entry at %p with flowID %d", + __func__, __LINE__, + sessionId, pentry, QosFlowID); + csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE); + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = pACInfo->curr_state; + } + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: setup requested in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + VOS_ASSERT(0); + new_state = pACInfo->curr_state; + } + /* if current state is same as previous no need for transistion, + if we are doing reassoc & we are already in handoff state, no need to move + to requested state. But make sure to set the previous state as requested + state + */ + if((new_state != pACInfo->curr_state)&& + (!(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state)))) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + + if(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state)) + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosInternalModifyReq() - The SME QoS internal function to request + for modification of certain QoS params on a flow running on a particular AC. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd) +{ + tListElem *pEntry= NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *pNewEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosEdcaAcType ac; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + sme_QosWmmTspecInfo Aggr_Tspec_Info; + sme_QosSearchInfo search_key; + sme_QosCmdInfo cmd; + v_U8_t sessionId; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked for flow %d", + __func__, __LINE__, + QosFlowID); + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.QosFlowID = QosFlowID; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_1; + search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY; + //go through the link list to find out the details on the flow + pEntry = sme_QosFindInFlowList(search_key); + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for flowID = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + // find the AC + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + + sessionId = flow_info->sessionId; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + + //validate QoS params + if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid params", + __func__, __LINE__); + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + // For modify, make sure that direction, TID and UP are not being altered + if((pQoSInfo->ts_info.direction != flow_info->QoSInfo.ts_info.direction) || + (pQoSInfo->ts_info.up != flow_info->QoSInfo.ts_info.up) || + (pQoSInfo->ts_info.tid != flow_info->QoSInfo.ts_info.tid)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Modification of direction/tid/up is not allowed", + __func__, __LINE__); + + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the modify request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // an AddTS or reassoc if necessary + if(!pMac->psOffloadEnabled) + { + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + else + { + hstatus = pmcOffloadRequestFullPower(pMac, sessionId, + sme_QosPmcOffloadFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the modify request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered modify request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + } + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + //save the new params adding a new (duplicate) entry in the Flow List + //Once we have decided on OTA exchange needed or not we can delete the + //original one from the List + pNewEntry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pNewEntry)); + if (!pNewEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + pNewEntry->ac_type = ac; + pNewEntry->sessionId = sessionId; + pNewEntry->HDDcontext = flow_info->HDDcontext; + pNewEntry->QoSCallback = flow_info->QoSCallback; + pNewEntry->QosFlowID = flow_info->QosFlowID; + pNewEntry->reason = SME_QOS_REASON_MODIFY_PENDING; + //since it is a modify request, use the same index on which the flow + //entry originally was running & add it to the Flow List at the end + pNewEntry->tspec_mask = flow_info->tspec_mask; + pNewEntry->QoSInfo = *pQoSInfo; + //update the entry from Flow List which needed to be modified + flow_info->reason = SME_QOS_REASON_MODIFY; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d creating modified " + "entry at %p with flowID %d", + __func__, __LINE__, + sessionId, pNewEntry, pNewEntry->QosFlowID); + //add the new entry under construction to the Flow List + csrLLInsertTail(&sme_QosCb.flow_list, &pNewEntry->link, VOS_TRUE); + //update TSPEC with the new param set + hstatus = sme_QosUpdateParams(sessionId, + ac, pNewEntry->tspec_mask, + &Aggr_Tspec_Info); + if(HAL_STATUS_SUCCESS(hstatus)) + { + pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1] = Aggr_Tspec_Info; + //if ACM, send out a new ADDTS + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1], + ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + new_state = SME_QOS_REQUESTED; + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + pACInfo->tspec_pending = pNewEntry->tspec_mask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = SME_QOS_QOS_ON; + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //delete the original entry in FLOW list which got modified + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosModifyFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP != status) + { + pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1] = + pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1]; + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY; + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosModificationNotifyFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + else if(SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP; + } + } + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1], + status, + flow_info->QosFlowID); + } + + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = SME_QOS_QOS_ON; + } + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosUpdateParams() failed", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + new_state = SME_QOS_LINK_UP; + } + /* if we are doing reassoc & we are already in handoff state, no need + to move to requested state. But make sure to set the previous state + as requested state + */ + if(!(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state))) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + else + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: Buffering modify request for flow %d in state = %d", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + //buffer cmd + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: modify requested in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + break; + } + if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosInternalReleaseReq() - The SME QoS internal function to request + for releasing a QoS flow running on a particular AC. + + \param pMac - Pointer to the global MAC parameter structure. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Release is successful. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd) +{ + tListElem *pEntry= NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosFlowInfoEntry *pDeletedFlow = NULL; + sme_QosEdcaAcType ac; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosStatusType status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + sme_QosWmmTspecInfo Aggr_Tspec_Info; + sme_QosSearchInfo search_key; + sme_QosCmdInfo cmd; + tCsrRoamModifyProfileFields modifyProfileFields; + v_BOOL_t deltsIssued = VOS_FALSE; + v_U8_t sessionId; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + v_BOOL_t biDirectionalFlowsPresent = VOS_FALSE; + v_BOOL_t uplinkFlowsPresent = VOS_FALSE; + v_BOOL_t downlinkFlowsPresent = VOS_FALSE; + tListElem *pResult= NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked for flow %d", + __func__, __LINE__, + QosFlowID); + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.QosFlowID = QosFlowID; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_1; + search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY; + //go through the link list to find out the details on the flow + pEntry = sme_QosFindInFlowList(search_key); + + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for flowID = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP; + } + // find the AC + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + sessionId = flow_info->sessionId; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the release request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // a DelTS or reassoc if necessary + if(!pMac->psOffloadEnabled) + { + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + else + { + hstatus = pmcOffloadRequestFullPower(pMac, sessionId, + sme_QosPmcOffloadFullPowerCallback, + pSession, eSME_REASON_OTHER); + } + + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the release request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered release request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + } + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d with " + "entry tspec_mask = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac, flow_info->tspec_mask); + + //check if multiple flows running on the ac + if(pACInfo->num_flows[flow_info->tspec_mask - 1] > 1) + { + //don't want to include the flow in the new TSPEC on which release + //is requested + flow_info->reason = SME_QOS_REASON_RELEASE; + + /* Check if the flow being released is for bi-diretional. + * Following flows may present in the system. + * a) bi-directional flows + * b) uplink flows + * c) downlink flows. + * If the flow being released is for bidirectional, splitting of existing + * streams into two tspec indices is required in case ff (b), (c) are present + * and not (a). + * In case if split occurs, all upstreams are aggregated into tspec index 0, + * downstreams are aggregaed into tspec index 1 and two tspec requests for + * (aggregated) upstream(s) followed by (aggregated) downstream(s) is sent + * to AP. */ + if(flow_info->QoSInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_4; + search_key.sessionId = sessionId; + search_key.direction = SME_QOS_WMM_TS_DIR_BOTH; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + biDirectionalFlowsPresent = VOS_TRUE; + + if(!biDirectionalFlowsPresent) + { + // The only existing bidirectional flow is being released + + // Check if uplink flows exist + search_key.direction = SME_QOS_WMM_TS_DIR_UPLINK; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + uplinkFlowsPresent = VOS_TRUE; + + // Check if downlink flows exist + search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + downlinkFlowsPresent = VOS_TRUE; + + if(uplinkFlowsPresent && downlinkFlowsPresent) + { + // Need to split the uni-directional flows into SME_QOS_TSPEC_INDEX_0 and SME_QOS_TSPEC_INDEX_1 + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + // Mark all downstream flows as using tspec index 1 + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_4; + search_key.sessionId = sessionId; + search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_2_SET); + + // Aggregate all downstream flows + hstatus = sme_QosUpdateParams(sessionId, + ac, SME_QOS_TSPEC_MASK_BIT_2_SET, + &Aggr_Tspec_Info); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d buffering the AddTS request " + "for AC %d in state %d as Addts is pending " + "on other Tspec index of this AC", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + + // Buffer the (aggregated) tspec request for downstream flows. + // Please note that the (aggregated) tspec for upstream flows is sent + // out by the susequent logic. + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = SME_QOS_TSPEC_MASK_BIT_2_SET; + cmd.u.resendCmdInfo.QoSInfo = Aggr_Tspec_Info; + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_MASK_BIT_2_SET - 1] = Aggr_Tspec_Info; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to buffer the AddTS " + "request for AC %d TSPEC %d in state %d", + __func__, __LINE__, + sessionId, ac, SME_QOS_TSPEC_MASK_BIT_2_SET, pACInfo->curr_state); + + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + + } + } + } + + /* In case of splitting of existing streams, + * tspec_mask will be pointing to tspec index 0 and + * aggregated tspec for upstream(s) is sent out here. */ + hstatus = sme_QosUpdateParams(sessionId, + ac, flow_info->tspec_mask, + &Aggr_Tspec_Info); + if(HAL_STATUS_SUCCESS(hstatus)) + { + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1] = Aggr_Tspec_Info; + //if ACM, send out a new ADDTS + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1], ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + new_state = SME_QOS_REQUESTED; + status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + pACInfo->tspec_pending = flow_info->tspec_mask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = SME_QOS_QOS_ON; + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] = + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1]; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosSetupFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = SME_QOS_LINK_UP; + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] = + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1]; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d deleting entry at " + "%p with flowID %d", + __func__, __LINE__, + sessionId, flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosUpdateParams() failed", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + new_state = SME_QOS_LINK_UP; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + } + else + { + // this is the only flow aggregated in this TSPEC + status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if (ac == SME_QOS_EDCA_AC_VO) + { + // Indicate to neighbor roam logic of the new required VO + // ac bandwidth requirement. + csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[0].peak_data_rate, FALSE ); + } +#endif + //check if delts needs to be sent + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + //check if other TSPEC for this AC is also in use + if(SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status) + { + // this is the only TSPEC active on this AC + // so indicate that we no longer require APSD + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + //Also update modifyProfileFields.uapsd_mask in CSR for consistency + csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask = pSession->apsdMask; + csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + if(!pSession->apsdMask) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + if(!pMac->psOffloadEnabled) + { + (void)pmcStopUapsd(pMac); + } + else + { + (void)pmcOffloadStopUapsd(pMac, sessionId); + } + } + } + } + if (SME_QOS_RELEASE_DEFAULT == pACInfo->relTrig) + { + //send delts + hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandDelTs, + NULL, ac, flow_info->tspec_mask); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosDelTsReq() failed", + __func__, __LINE__); + status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + else + { + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~flow_info->tspec_mask); + deltsIssued = VOS_TRUE; + } + } + else + { + pSession->readyForPowerSave = VOS_TRUE; + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~flow_info->tspec_mask); + deltsIssued = VOS_TRUE; + } + } + else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + //reassoc logic + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + if(!pSession->apsdMask) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + if(!pMac->psOffloadEnabled) + { + (void)pmcStopUapsd(pMac); + } + else + { + (void)pmcOffloadStopUapsd(pMac, sessionId); + } + } + } + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Reassoc failed", + __func__, __LINE__); + status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + else + { + pACInfo->reassoc_pending = VOS_FALSE;//no need to wait + pACInfo->prev_state = SME_QOS_LINK_UP; + pACInfo->tspec_pending = 0; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: nothing to do for AC = %d", + __func__, __LINE__, ac); + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + + if (SME_QOS_RELEASE_BY_AP == pACInfo->relTrig) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + } + else if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + NULL, + status, + flow_info->QosFlowID); + } + + if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == status) + { + break; + } + + if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) > 0) && + ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) <= + SME_QOS_TSPEC_INDEX_MAX)) + { + if(pACInfo->num_flows[(SME_QOS_TSPEC_MASK_BIT_1_2_SET & + ~flow_info->tspec_mask) - 1] > 0) + { + new_state = SME_QOS_QOS_ON; + } + else + { + new_state = SME_QOS_LINK_UP; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pACInfo->num_flows", + __func__, __LINE__); + VOS_ASSERT (0); + return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP; + } + + if(VOS_FALSE == deltsIssued) + { + vos_mem_zero(&pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + } + vos_mem_zero(&pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d deleting entry at %p with flowID %d", + __func__, __LINE__, + sessionId, flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + pACInfo->relTrig = SME_QOS_RELEASE_DEFAULT; + } + /* if we are doing reassoc & we are already in handoff state, no need + to move to requested state. But make sure to set the previous state + as requested state + */ + if(SME_QOS_HANDOFF != pACInfo->curr_state) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + if(pACInfo->reassoc_pending) + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + //buffer cmd + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + //print error msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: release request in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + break; + } + // if we deleted a flow, reclaim the memory + if (pDeletedFlow) + { + vos_mem_free(pDeletedFlow); + } + if((SME_QOS_STATUS_RELEASE_SUCCESS_RSP == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosSetup() - The internal qos setup function which has the + intelligence if the request is NOP, or for APSD and/or need to send out ADDTS. + It also does the sanity check for QAP, AP supports APSD etc. + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session upon which setup is being performed + \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above + \param ac - Enumeration of the various EDCA Access Categories. + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP if the setup is successful + The logic used in the code might be confusing. Trying to cover all the cases + here. + AP supports App wants ACM = 1 Already set APSD Result + | 0 | 0 | 0 | 0 | NO ACM NO APSD + | 0 | 0 | 0 | 1 | NO ACM NO APSD/INVALID + | 0 | 0 | 1 | 0 | ADDTS + | 0 | 0 | 1 | 1 | ADDTS + | 0 | 1 | 0 | 0 | FAILURE + | 0 | 1 | 0 | 1 | INVALID + | 0 | 1 | 1 | 0 | ADDTS + | 0 | 1 | 1 | 1 | ADDTS + | 1 | 0 | 0 | 0 | NO ACM NO APSD + | 1 | 0 | 0 | 1 | NO ACM NO APSD + | 1 | 0 | 1 | 0 | ADDTS + | 1 | 0 | 1 | 1 | ADDTS + | 1 | 1 | 0 | 0 | REASSOC + | 1 | 1 | 0 | 1 | NOP: APSD SET ALREADY + | 1 | 1 | 1 | 0 | ADDTS + | 1 | 1 | 1 | 1 | ADDTS + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo *pTspec_Info, + sme_QosEdcaAcType ac) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + tDot11fBeaconIEs *pIes = NULL; + tCsrRoamModifyProfileFields modifyProfileFields; + eHalStatus hstatus; + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session Id %d is invalid", + __func__, __LINE__, + sessionId); + return status; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d is inactive", + __func__, __LINE__, + sessionId); + return status; + } + if(!pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d has an Invalid BSS Descriptor", + __func__, __LINE__, + sessionId); + return status; + } + hstatus = csrGetParsedBssDescriptionIEs(pMac, + pSession->assocInfo.pBssDesc, + &pIes); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to parse BSS IEs", + __func__, __LINE__, + sessionId); + return status; + } + + /* success so pIes was allocated */ + + if( !CSR_IS_QOS_BSS(pIes) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support QoS", + __func__, __LINE__, + sessionId); + vos_mem_free(pIes); + //notify HDD through the synchronous status msg + return SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "%s: %d: UAPSD/PSB set %d: ", __func__, __LINE__, + pTspec_Info->ts_info.psb); + + pACInfo = &pSession->ac_info[ac]; + do + { + // is ACM enabled for this AC? + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + // ACM is enabled for this AC so we must send an AddTS + if(pTspec_Info->ts_info.psb && + !(pMac->psOffloadEnabled && pMac->pmcOffloadInfo.pmc[sessionId].UapsdEnabled) + && (!pMac->pmc.uapsdEnabled )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is looking for APSD but PMC doesn't " + "have support for APSD", + __func__, __LINE__); + break; + } + + if (pTspec_Info->ts_info.psb && + !(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + // application is looking for APSD but AP doesn't support it + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support APSD", + __func__, __LINE__, + sessionId); + break; + } + + if(SME_QOS_MAX_TID == pTspec_Info->ts_info.tid) + { + //App didn't set TID, generate one + pTspec_Info->ts_info.tid = + (v_U8_t)(SME_QOS_WMM_UP_NC - pTspec_Info->ts_info.up); + } + //addts logic + hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandAddTs, + pTspec_Info, ac, 0); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosAddTsReq() failed", + __func__, __LINE__); + break; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AddTS on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + break; + } + // ACM is not enabled for this AC + // Is the application looking for APSD? + if(0 == pTspec_Info->ts_info.psb) + { + //no, we don't need APSD + //but check the case, if the setup is called as a result of a release + // or modify which boils down to the fact that APSD was set on this AC + // but no longer needed - so we need a reassoc for the above case to + // let the AP know + if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + // APSD was formerly enabled on this AC but is no longer required + // so we must reassociate + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassoc needed " + "to disable APSD on AC %d", + __func__, __LINE__, + sessionId, ac); + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to request reassociation", + __func__, __LINE__); + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassociation to enable " + "APSD on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + pACInfo->reassoc_pending = VOS_TRUE; + } + } + else + { + // we don't need APSD on this AC + // and we don't currently have APSD on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is not looking for APSD & Admission " + "Control isn't mandatory for the AC", + __func__, __LINE__); + //return success right away + status = SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP; + } + break; + } + else if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + // application is looking for APSD but AP doesn't support it + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support APSD", + __func__, __LINE__, + sessionId); + break; + } + else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + // application is looking for APSD + // and it is already enabled on this AC + status = SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is looking for APSD and it is already " + "set for the AC", + __func__, __LINE__); + break; + } + else + { + // application is looking for APSD + // but it is not enabled on this AC + // so we need to reassociate + if(pMac->pmc.uapsdEnabled || (pMac->psOffloadEnabled + && pMac->pmcOffloadInfo.pmc[sessionId].UapsdEnabled)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassoc needed " + "to enable APSD on AC %d", + __func__, __LINE__, + sessionId, ac); + //reassoc logic + // update the UAPSD mask to include the new + // AC on which APSD is requested + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to request reassociation", + __func__, __LINE__); + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassociation to enable " + "APSD on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + pACInfo->reassoc_pending = VOS_TRUE; + } + } + else + { + //err msg: no support for APSD from PMC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no support for APSD or BMPS from PMC", + __func__, __LINE__); + } + } + }while(0); + + vos_mem_free(pIes); + return status; +} + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* This is a dummy function now. But the purpose of me adding this was to + * delay the TSPEC processing till SET_KEY completes. This function can be + * used to do any SME_QOS processing after the SET_KEY. As of now, it is + * not required as we are ok with tspec getting programmed before set_key + * as the roam timings are measured without tspec in reassoc! + */ +eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "########### Set Key Complete #############"); + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; +} +#endif + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_QosESESaveTspecResponse() - This function saves the TSPEC + parameters that came along in the TSPEC IE in the reassoc response + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pTspec - Pointer to the TSPEC IE from the reassoc rsp + \param ac - Access Category for which this TSPEC rsp is received + \param tspecIndex - flow/direction + + \return eHAL_STATUS_SUCCESS - Release is successful. + --------------------------------------------------------------------------*/ +eHalStatus sme_QosESESaveTspecResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIEWMMTSPEC *pTspec, v_U8_t ac, v_U8_t tspecIndex) +{ + tpSirAddtsRsp pAddtsRsp = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex]; + + ac = sme_QosUPtoACMap[pTspec->user_priority]; + + vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp)); + + pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP; + pAddtsRsp->length = sizeof(tSirAddtsRsp); + pAddtsRsp->rc = eSIR_SUCCESS; + pAddtsRsp->sessionId = sessionId; + pAddtsRsp->rsp.dialogToken = 0; + pAddtsRsp->rsp.status = eSIR_SUCCESS; + pAddtsRsp->rsp.wmeTspecPresent = pTspec->present; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Copy Tspec to local data structure ac=%d, tspecIdx=%d", + __func__, ac, tspecIndex); + + if (pAddtsRsp->rsp.wmeTspecPresent) + { + //Copy TSPEC params received in assoc response to addts response + ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, pTspec); + } + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosESEProcessReassocTspecRsp() - This function processes the + WMM TSPEC IE in the reassoc response. Reassoc triggered as part of + ESE roaming to another ESE capable AP. If the TSPEC was added before + reassoc, as part of Call Admission Control, the reasso req from the + STA would carry the TSPEC parameters which were already negotiated + with the older AP. + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pEven_info - Pointer to the smeJoinRsp structure + + \return eHAL_STATUS_SUCCESS - Release is successful. + --------------------------------------------------------------------------*/ +eHalStatus sme_QosESEProcessReassocTspecRsp(tpAniSirGlobal pMac, v_U8_t sessionId, void* pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + tDot11fIEWMMTSPEC *pTspecIE = NULL; + tCsrRoamSession *pCsrSession = NULL; + tCsrRoamConnectedInfo *pCsrConnectedInfo = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + v_U8_t ac, numTspec, cnt; + v_U8_t tspec_flow_index, tspec_mask_status; + v_U32_t tspecIeLen; + + pCsrSession = CSR_GET_SESSION(pMac, sessionId); + if (NULL == pCsrSession) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + + pCsrConnectedInfo = &pCsrSession->connectedInfo; + pSession = &sme_QosCb.sessionInfo[sessionId]; + + // Get the TSPEC IEs which came along with the reassoc response + // from the pbFrames pointer + pTspecIE = (tDot11fIEWMMTSPEC *)(pCsrConnectedInfo->pbFrames + pCsrConnectedInfo->nBeaconLength + + pCsrConnectedInfo->nAssocReqLength + pCsrConnectedInfo->nAssocRspLength + pCsrConnectedInfo->nRICRspLength); + + // Get the number of tspecs Ies in the frame, the min length + // should be atleast equal to the one TSPEC IE + tspecIeLen = pCsrConnectedInfo->nTspecIeLength; + if (tspecIeLen < sizeof(tDot11fIEWMMTSPEC)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("ESE Tspec IE len %d less than min %zu"), + tspecIeLen, sizeof(tDot11fIEWMMTSPEC)); + return eHAL_STATUS_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "TspecLen = %d, pbFrames = %p, pTspecIE = %p", + tspecIeLen, pCsrConnectedInfo->pbFrames, pTspecIE); + + numTspec = (tspecIeLen)/sizeof(tDot11fIEWMMTSPEC); + for(cnt=0; cntuser_priority); + if (ac >= SME_QOS_EDCA_AC_MAX) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("ac %d more than it`s max value"), ac); + return eHAL_STATUS_FAILURE; + } + pACInfo = &pSession->ac_info[ac]; + tspec_mask_status = pACInfo->tspec_mask_status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("UP=%d, ac=%d, tspec_mask_status=%x"), + pTspecIE->user_priority, ac, tspec_mask_status ); + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) { + if (tspec_mask_status & (1 << tspec_flow_index)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac); + sme_QosESESaveTspecResponse(pMac, sessionId, pTspecIE, ac, tspec_flow_index); + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Not found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac); + } + } + // Increment the pointer to point it to the next TSPEC IE + pTspecIE++; + } + + /* Send the Aggregated QoS request to HAL */ + status = sme_QosFTAggrQosReq(pMac,sessionId); + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosCopyTspecInfo() - This function copies the existing TSPEC + parameters from the source structure to the destination structure. + + \param pMac - Pointer to the global MAC parameter structure. + \param pTspec_Info - source structure + \param pTspec - destination structure + + \return void + --------------------------------------------------------------------------*/ +static void sme_QosCopyTspecInfo(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info, tSirMacTspecIE* pTspec) +{ + /* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + * Interval, Service Start Time, Suspension Interval and Delay Bound are + * all intended for HCCA operation and therefore must be set to zero*/ + pTspec->delayBound = pTspec_Info->delay_bound; + pTspec->inactInterval = pTspec_Info->inactivity_interval; + pTspec->length = SME_QOS_TSPEC_IE_LENGTH; + pTspec->maxBurstSz = pTspec_Info->max_burst_size; + pTspec->maxMsduSz = pTspec_Info->maximum_msdu_size; + pTspec->maxSvcInterval = pTspec_Info->max_service_interval; + pTspec->meanDataRate = pTspec_Info->mean_data_rate; + pTspec->mediumTime = pTspec_Info->medium_time; + pTspec->minDataRate = pTspec_Info->min_data_rate; + pTspec->minPhyRate = pTspec_Info->min_phy_rate; + pTspec->minSvcInterval = pTspec_Info->min_service_interval; + pTspec->nomMsduSz = pTspec_Info->nominal_msdu_size; + pTspec->peakDataRate = pTspec_Info->peak_data_rate; + pTspec->surplusBw = pTspec_Info->surplus_bw_allowance; + pTspec->suspendInterval = pTspec_Info->suspension_interval; + pTspec->svcStartTime = pTspec_Info->svc_start_time; + pTspec->tsinfo.traffic.direction = pTspec_Info->ts_info.direction; + + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if (pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac)) { + pTspec->tsinfo.traffic.psb = pTspec_Info->ts_info.psb; + } else { + pTspec->tsinfo.traffic.psb = 0; + pTspec_Info->ts_info.psb = 0; + } + pTspec->tsinfo.traffic.tsid = pTspec_Info->ts_info.tid; + pTspec->tsinfo.traffic.userPrio = pTspec_Info->ts_info.up; + pTspec->tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pTspec->tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn; + pTspec->tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy; + pTspec->type = SME_QOS_TSPEC_IE_TYPE; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspec_Info->ts_info.up, + pTspec_Info->ts_info.tid); +} + +/*-------------------------------------------------------------------------- + \brief sme_QosEseRetrieveTspecInfo() - This function is called by CSR + when try to create reassoc request message to PE - csrSendSmeReassocReqMsg + This functions get the existing tspec parameters to be included + in the reassoc request. + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pTspecInfo - Pointer to the structure to carry back the TSPEC parameters + + \return v_U8_t - number of existing negotiated TSPECs + --------------------------------------------------------------------------*/ +v_U8_t sme_QosEseRetrieveTspecInfo(tpAniSirGlobal pMac, v_U8_t sessionId, tTspecInfo *pTspecInfo) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t tspec_mask_status = 0; + v_U8_t tspec_pending_status = 0; + v_U8_t ac, numTspecs = 0; + tTspecInfo *pDstTspec = pTspecInfo; + + //TODO: Check if TSPEC has already been established, if not return + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) { + volatile v_U8_t tspec_index = 0; + + pACInfo = &pSession->ac_info[ac]; + tspec_pending_status = pACInfo->tspec_pending; + tspec_mask_status = pACInfo->tspec_mask_status; + + do { + if (tspec_mask_status & SME_QOS_TSPEC_MASK_BIT_1_SET) { + /* If a tspec status is pending, take requested_QoSInfo for RIC request, else use curr_QoSInfo + for the RIC request */ + if (tspec_pending_status & SME_QOS_TSPEC_MASK_BIT_1_SET) { + sme_QosCopyTspecInfo(pMac, &pACInfo->requested_QoSInfo[tspec_index], &pDstTspec->tspec); + } else { + sme_QosCopyTspecInfo(pMac, &pACInfo->curr_QoSInfo[tspec_index], &pDstTspec->tspec); + } + pDstTspec->valid = TRUE; + numTspecs++; + pDstTspec++; + } + tspec_mask_status >>= 1; + tspec_pending_status >>= 1; + tspec_index++; + } while (tspec_mask_status); + } + + return numTspecs; +} + +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + +eHalStatus sme_QosCreateTspecRICIE(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info, + v_U8_t *pRICBuffer, v_U32_t *pRICLength, v_U8_t *pRICIdentifier) +{ + tDot11fIERICDataDesc ricIE; + tANI_U32 nStatus; + + if (pRICBuffer == NULL || pRICIdentifier == NULL || pRICLength == NULL) + { + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(&ricIE, sizeof(tDot11fIERICDataDesc)); + + ricIE.present = 1; + ricIE.RICData.present = 1; + ricIE.RICData.resourceDescCount = 1; + ricIE.RICData.statusCode = 0; + ricIE.RICData.Identifier = sme_QosAssignDialogToken(); +#ifndef USE_80211_WMMTSPEC_FOR_RIC + ricIE.TSPEC.present = 1; + ricIE.TSPEC.delay_bound = pTspec_Info->delay_bound; + ricIE.TSPEC.inactivity_int = pTspec_Info->inactivity_interval; + ricIE.TSPEC.burst_size = pTspec_Info->max_burst_size; + ricIE.TSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size; + ricIE.TSPEC.max_service_int = pTspec_Info->max_service_interval; + ricIE.TSPEC.mean_data_rate = pTspec_Info->mean_data_rate; + ricIE.TSPEC.medium_time = 0; + ricIE.TSPEC.min_data_rate = pTspec_Info->min_data_rate; + ricIE.TSPEC.min_phy_rate = pTspec_Info->min_phy_rate; + ricIE.TSPEC.min_service_int = pTspec_Info->min_service_interval; + ricIE.TSPEC.size = pTspec_Info->nominal_msdu_size; + ricIE.TSPEC.peak_data_rate = pTspec_Info->peak_data_rate; + ricIE.TSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance; + ricIE.TSPEC.suspension_int = pTspec_Info->suspension_interval; + ricIE.TSPEC.service_start_time = pTspec_Info->svc_start_time; + ricIE.TSPEC.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) ) + { + ricIE.TSPEC.psb = pTspec_Info->ts_info.psb; + } + else + { + ricIE.TSPEC.psb = 0; + } + ricIE.TSPEC.tsid = pTspec_Info->ts_info.tid; + ricIE.TSPEC.user_priority = pTspec_Info->ts_info.up; + ricIE.TSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA; + + *pRICIdentifier = ricIE.RICData.Identifier; + + nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength); + if (DOT11F_FAILED(nStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Packing of RIC Data of length %d failed with status %d"), + *pRICLength, nStatus); + } +#else // WMM TSPEC + /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + Interval, Service Start Time, Suspension Interval and Delay Bound are + all intended for HCCA operation and therefore must be set to zero*/ + ricIE.WMMTSPEC.present = 1; + ricIE.WMMTSPEC.version = 1; + ricIE.WMMTSPEC.delay_bound = pTspec_Info->delay_bound; + ricIE.WMMTSPEC.inactivity_int = pTspec_Info->inactivity_interval; + ricIE.WMMTSPEC.burst_size = pTspec_Info->max_burst_size; + ricIE.WMMTSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size; + ricIE.WMMTSPEC.max_service_int = pTspec_Info->max_service_interval; + ricIE.WMMTSPEC.mean_data_rate = pTspec_Info->mean_data_rate; + ricIE.WMMTSPEC.medium_time = 0; + ricIE.WMMTSPEC.min_data_rate = pTspec_Info->min_data_rate; + ricIE.WMMTSPEC.min_phy_rate = pTspec_Info->min_phy_rate; + ricIE.WMMTSPEC.min_service_int = pTspec_Info->min_service_interval; + ricIE.WMMTSPEC.size = pTspec_Info->nominal_msdu_size; + ricIE.WMMTSPEC.peak_data_rate = pTspec_Info->peak_data_rate; + ricIE.WMMTSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance; + ricIE.WMMTSPEC.suspension_int = pTspec_Info->suspension_interval; + ricIE.WMMTSPEC.service_start_time = pTspec_Info->svc_start_time; + ricIE.WMMTSPEC.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) ) + { + ricIE.WMMTSPEC.psb = pTspec_Info->ts_info.psb; + } + else + { + ricIE.WMMTSPEC.psb = 0; + } + ricIE.WMMTSPEC.tsid = pTspec_Info->ts_info.tid; + ricIE.WMMTSPEC.user_priority = pTspec_Info->ts_info.up; + ricIE.WMMTSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA; + + + nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength); + if (DOT11F_FAILED(nStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Packing of RIC Data of length %d failed with status %d"), + *pRICLength, nStatus); + } +#endif /* 80211_TSPEC */ + *pRICIdentifier = ricIE.RICData.Identifier; + return nStatus; +} + +eHalStatus sme_QosProcessFTReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac, qos_requested = FALSE; + v_U8_t tspec_flow_index; + sme_QosFlowInfoEntry *flow_info = NULL; + tListElem *pEntry= NULL; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Invoked on session %d"), sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + qos_requested = FALSE; + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) + { + /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */ + if ((pACInfo->ricIdentifier[tspec_flow_index] && !pACInfo->tspec_pending) || + (pACInfo->tspec_mask_status & (1<requested_QoSInfo[tspec_flow_index] = pACInfo->curr_QoSInfo[tspec_flow_index]; + vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_flow_index], sizeof(sme_QosWmmTspecInfo)); + qos_requested = TRUE; + } + } + + // Only if the tspec is required, transition the state to + // SME_QOS_REQUESTED for this AC + if (qos_requested) + { + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_REQUESTED); + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("FT Reassoc req event in unexpected state %d"), pACInfo->curr_state); + VOS_ASSERT(0); + } + } + + } + + /* At this point of time, we are disconnected from the old AP, so it is safe + * to reset all these session variables */ + pSession->apsdMask = 0; + pSession->uapsdAlreadyRequested = 0; + pSession->readyForPowerSave = 0; + + /* Now change reason and HO renewal of all the flow in this session only */ + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + do + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(sessionId == flow_info->sessionId) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Changing FlowID %d reason to SETUP and HO renewal to FALSE", + __func__, __LINE__, + flow_info->QosFlowID); + flow_info->reason = SME_QOS_REASON_SETUP; + flow_info->hoRenewal = eANI_BOOLEAN_TRUE; + } + pEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + } while( pEntry ); + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId ) +{ + tSirAggrQosReq *pMsg = NULL; + sme_QosSessionInfo *pSession; + eHalStatus status = eHAL_STATUS_FAILURE; + int i, j = 0; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", __func__, __LINE__, + sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + pMsg = (tSirAggrQosReq *)vos_mem_malloc(sizeof(tSirAggrQosReq)); + + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(pMsg, sizeof(tSirAggrQosReq)); + + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_FT_AGGR_QOS_REQ); + pMsg->length = sizeof(tSirAggrQosReq); + pMsg->sessionId = sessionId; + pMsg->timeout = 0; + pMsg->rspReqd = VOS_TRUE; + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + + for( i = 0; i < SME_QOS_EDCA_AC_MAX; i++ ) + { + for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("ac=%d, tspec_mask_staus=%x, tspec_index=%d"), + i, pSession->ac_info[i].tspec_mask_status, j); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("direction = %d"), pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction); + // Check if any flow is active on this AC + if ((pSession->ac_info[i].tspec_mask_status) & (1 << j)) + { + tANI_U8 direction = pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction; + if ((direction == SME_QOS_WMM_TS_DIR_UPLINK) || + (direction == SME_QOS_WMM_TS_DIR_BOTH)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Found tspec entry AC=%d, flow=%d, direction = %d"), i, j, direction); + pMsg->aggrInfo.aggrAddTsInfo[i].dialogToken = + sme_QosAssignDialogToken(); + pMsg->aggrInfo.aggrAddTsInfo[i].lleTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.lleTspecPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].numTclas = + pSession->ac_info[i].addTsRsp[j].rsp.numTclas; + vos_mem_copy( pMsg->aggrInfo.aggrAddTsInfo[i].tclasInfo, + pSession->ac_info[i].addTsRsp[j].rsp.tclasInfo, + SIR_MAC_TCLASIE_MAXNUM ); + pMsg->aggrInfo.aggrAddTsInfo[i].tclasProc = + pSession->ac_info[i].addTsRsp[j].rsp.tclasProc; + pMsg->aggrInfo.aggrAddTsInfo[i].tclasProcPresent = + pSession->ac_info[i].addTsRsp[j].rsp.tclasProcPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].tspec = + pSession->ac_info[i].addTsRsp[j].rsp.tspec; + pMsg->aggrInfo.aggrAddTsInfo[i].wmeTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.wmeTspecPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].wsmTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.wsmTspecPresent; + pMsg->aggrInfo.tspecIdx |= ( 1 << i ); + + // Mark the index for this AC as pending for response, which would be + // used to validate the AddTS response from HAL->PE->SME + pSession->ac_info[i].tspec_pending = (1<aggrInfo.tspecIdx); + + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sent down a AGGR QoS req to PE", + __func__, __LINE__); + } + + return status; +} + +eHalStatus sme_QosProcessFTRICResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIERICDataDesc *pRicDataDesc, v_U8_t ac, v_U8_t tspecIndex) +{ + tANI_U8 i = 0; + tpSirAddtsRsp pAddtsRsp + = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex]; + + vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp)); + + pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP; + pAddtsRsp->length = sizeof(tSirAddtsRsp); + pAddtsRsp->rc = pRicDataDesc->RICData.statusCode; + pAddtsRsp->sessionId = sessionId; + pAddtsRsp->rsp.dialogToken = pRicDataDesc->RICData.Identifier; + pAddtsRsp->rsp.status = pRicDataDesc->RICData.statusCode; + pAddtsRsp->rsp.wmeTspecPresent = pRicDataDesc->TSPEC.present; + if (pAddtsRsp->rsp.wmeTspecPresent) + { + //Copy TSPEC params received in RIC response to addts response + ConvertTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->TSPEC); + } + + pAddtsRsp->rsp.numTclas = pRicDataDesc->num_TCLAS; + if (pAddtsRsp->rsp.numTclas) + { + for (i = 0; i < pAddtsRsp->rsp.numTclas; i++) + { + //Copy TCLAS info per index to the addts response + ConvertTCLAS(pMac, &pAddtsRsp->rsp.tclasInfo[i], &pRicDataDesc->TCLAS[i]); + } + } + + pAddtsRsp->rsp.tclasProcPresent = pRicDataDesc->TCLASSPROC.present; + if (pAddtsRsp->rsp.tclasProcPresent) + pAddtsRsp->rsp.tclasProc = pRicDataDesc->TCLASSPROC.processing; + + + pAddtsRsp->rsp.schedulePresent = pRicDataDesc->Schedule.present; + if (pAddtsRsp->rsp.schedulePresent) + { + //Copy Schedule IE params to addts response + ConvertSchedule(pMac, &pAddtsRsp->rsp.schedule, &pRicDataDesc->Schedule); + } + + //Need to check the below portion is a part of WMM TSPEC + //Process Delay element + if (pRicDataDesc->TSDelay.present) + ConvertTSDelay(pMac, &pAddtsRsp->rsp.delay, &pRicDataDesc->TSDelay); + + //Need to call for WMMTSPEC + if (pRicDataDesc->WMMTSPEC.present) + { + ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->WMMTSPEC); + } + //return sme_QosProcessAddTsRsp(pMac, &addtsRsp); + return eHAL_STATUS_SUCCESS; +} +eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirAggrQosRsp pAggrRsp = (tpSirAggrQosRsp)pMsgBuf; + tSirAddtsRsp addtsRsp; + eHalStatus status = eHAL_STATUS_SUCCESS; + int i, j = 0; + tANI_U8 sessionId = pAggrRsp->sessionId; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Received AGGR_QOS resp from LIM")); + + /* Copy over the updated response information for TSPEC of all the ACs */ + for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ ) + { + tANI_U8 tspec_mask_status = sme_QosCb.sessionInfo[sessionId].ac_info[i].tspec_mask_status; + for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ ) + { + tANI_U8 direction = sme_QosCb.sessionInfo[sessionId].ac_info[i]. + addTsRsp[j].rsp.tspec.tsinfo.traffic.direction; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Addts rsp from LIM AC=%d, flow=%d dir=%d, tspecIdx=%x"), + i, j, direction, pAggrRsp->aggrInfo.tspecIdx); + // Check if the direction is Uplink or bi-directional + if( ((1<aggrInfo.tspecIdx) && + ((tspec_mask_status) & (1<aggrInfo.aggrRsp[i].status; + addtsRsp.rsp.status = pAggrRsp->aggrInfo.aggrRsp[i].status; + addtsRsp.rsp.tspec = pAggrRsp->aggrInfo.aggrRsp[i].tspec; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Processing Addts rsp from LIM AC=%d, flow=%d"), i, j); + /* post ADD TS response for each */ + if (sme_QosProcessAddTsRsp(pMac, &addtsRsp) != eHAL_STATUS_SUCCESS) + { + status = eHAL_STATUS_FAILURE; + } + } + } + } + return status; +} + + +eHalStatus sme_QosProcessFTReassocRspEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + v_U8_t tspec_flow_index; + tDot11fIERICDataDesc *pRicDataDesc = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamConnectedInfo *pCsrConnectedInfo = NULL; + tANI_U32 ricRspLen; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tDot11fIERICDataDesc *pRicData = NULL; + tANI_U32 ricLen; + v_BOOL_t Found = false; + sme_QosWmmDirType direction; + v_U8_t ac1; +#endif + + if (NULL == pCsrSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("The Session pointer is NULL")); + return eHAL_STATUS_FAILURE; + } + pCsrConnectedInfo = &pCsrSession->connectedInfo; + + ricRspLen = pCsrConnectedInfo->nRICRspLength; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + pRicDataDesc = (tDot11fIERICDataDesc *)((pCsrConnectedInfo->pbFrames) + + (pCsrConnectedInfo->nBeaconLength + pCsrConnectedInfo->nAssocReqLength + + pCsrConnectedInfo->nAssocRspLength)); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if(!pCsrSession->roamOffloadSynchParams.bRoamSynchInProgress) + { +#endif + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) + { + /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */ + if (pACInfo->ricIdentifier[tspec_flow_index]) + { + + if (!ricRspLen) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC Response not received for AC %d on TSPEC Index %d, RIC Req Identifier = %d"), + ac, tspec_flow_index, pACInfo->ricIdentifier[tspec_flow_index]); + VOS_ASSERT(0); + } + else + { + /* Now we got response for this identifier. Process it. */ + if (pRicDataDesc->present) + { + if (pRicDataDesc->RICData.present) + { + if (pRicDataDesc->RICData.Identifier != pACInfo->ricIdentifier[tspec_flow_index]) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC response order not same as request sent. Request ID = %d, Response ID = %d"), + pACInfo->ricIdentifier[tspec_flow_index], pRicDataDesc->RICData.Identifier); + VOS_ASSERT(0); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Processing RIC Response for AC %d, TSPEC Flow index %d with RIC ID %d "), + ac, tspec_flow_index, pRicDataDesc->RICData.Identifier); + status = sme_QosProcessFTRICResponse(pMac, sessionId, pRicDataDesc, ac, tspec_flow_index); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed with status %d for AC %d in TSPEC Flow index = %d"), + status, ac, tspec_flow_index); + } + } + pRicDataDesc++; + ricRspLen -= sizeof(tDot11fIERICDataDesc); + } + } + } + } + + } + } + + if (ricRspLen) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC Response still follows despite traversing through all ACs. Remaining len = %d"), ricRspLen); + VOS_ASSERT(0); + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + } + else + { + /* It means LFR3.0 roaming with RIC, + * currently we have support for WMM TSPEC alone + * In LFR3.0 11r since we do not have a RIC identifier + * maintained in host so identify the tspec from the AC + * and direction info */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("LFR3-11r Compare RIC in Reassoc Resp to find" + " matching tspec in host.")); + + pRicData = pRicDataDesc; + ricLen = ricRspLen; + + if (ricRspLen && pRicDataDesc->present && + pRicDataDesc->WMMTSPEC.present) { + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + for (tspec_flow_index = 0; + tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; + tspec_flow_index++) { + if((pSession->ac_info[ac].tspec_mask_status) + & (1 << tspec_flow_index)) { + do { + ac1 = sme_QosUpToAc(pRicData->WMMTSPEC.user_priority); + if (ac == SME_QOS_EDCA_AC_MAX) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Invalid AC %d UP %d"), ac, + pRicData->WMMTSPEC.user_priority); + break; + } + direction = pRicData->WMMTSPEC.direction; + + if (ac == ac1 && + direction == pACInfo->requested_QoSInfo[tspec_flow_index].ts_info.direction) + { + /* It means we found a matching tspec */ + Found = true; + status = sme_QosProcessFTRICResponse(pMac, + sessionId, + pRicData, + ac, + tspec_flow_index); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed with status %d for AC %d in TSPEC Flow index = %d"), + status, ac, tspec_flow_index); + } + break; + } + pRicData++; + ricLen -= sizeof(tDot11fIERICDataDesc); + }while(ricLen); + } + pRicData = pRicDataDesc; + ricLen = ricRspLen; + Found = false; + } + } + }else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("LFR3-11r ricRspLen is zero or pRicDataDesc is not" + " present or wmmtspec is not present")); + } + } +#endif + + /* Send the Aggregated QoS request to HAL */ + status = sme_QosFTAggrQosReq(pMac,sessionId); + + return status; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + + +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsReq() - To send down the ADDTS request with TSPEC params + to PE + + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session upon which the TSPEC should be added + \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above + \param ac - Enumeration of the various EDCA Access Categories. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pTspec_Info, + sme_QosEdcaAcType ac) +{ + tSirAddtsReq *pMsg = NULL; + sme_QosSessionInfo *pSession; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef FEATURE_WLAN_ESE + tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId ); +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d", + __func__, __LINE__, + sessionId, ac); + if (sessionId >= CSR_ROAM_SESSION_MAX) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sessionId(%d) is invalid", + __func__, __LINE__, sessionId); + return eHAL_STATUS_FAILURE; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + pMsg = (tSirAddtsReq *)vos_mem_malloc(sizeof(tSirAddtsReq)); + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pMsg, sizeof(tSirAddtsReq)); + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_ADDTS_REQ); + pMsg->length = sizeof(tSirAddtsReq); + pMsg->sessionId = sessionId; + pMsg->timeout = 0; + pMsg->rspReqd = VOS_TRUE; + pMsg->req.dialogToken = sme_QosAssignDialogToken(); + /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + Interval, Service Start Time, Suspension Interval and Delay Bound are + all intended for HCCA operation and therefore must be set to zero*/ + pMsg->req.tspec.delayBound = 0; + pMsg->req.tspec.inactInterval = pTspec_Info->inactivity_interval; + pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH; + pMsg->req.tspec.maxBurstSz = pTspec_Info->max_burst_size; + pMsg->req.tspec.maxMsduSz = pTspec_Info->maximum_msdu_size; + pMsg->req.tspec.maxSvcInterval = pTspec_Info->max_service_interval; + pMsg->req.tspec.meanDataRate = pTspec_Info->mean_data_rate; + pMsg->req.tspec.mediumTime = pTspec_Info->medium_time; + pMsg->req.tspec.minDataRate = pTspec_Info->min_data_rate; + pMsg->req.tspec.minPhyRate = pTspec_Info->min_phy_rate; + pMsg->req.tspec.minSvcInterval = pTspec_Info->min_service_interval; + pMsg->req.tspec.nomMsduSz = pTspec_Info->nominal_msdu_size; + pMsg->req.tspec.peakDataRate = pTspec_Info->peak_data_rate; + pMsg->req.tspec.surplusBw = pTspec_Info->surplus_bw_allowance; + pMsg->req.tspec.suspendInterval = pTspec_Info->suspension_interval; + pMsg->req.tspec.svcStartTime = 0; + pMsg->req.tspec.tsinfo.traffic.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb + && btcIsReadyForUapsd(pMac) + ) + { + pMsg->req.tspec.tsinfo.traffic.psb = pTspec_Info->ts_info.psb; + } + else + { + pMsg->req.tspec.tsinfo.traffic.psb = 0; + pTspec_Info->ts_info.psb = 0; + } + pMsg->req.tspec.tsinfo.traffic.tsid = pTspec_Info->ts_info.tid; + pMsg->req.tspec.tsinfo.traffic.userPrio = pTspec_Info->ts_info.up; + pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn; + pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy; + pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE; + /*Fill the BSSID pMsg->req.bssId*/ + if (NULL == pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: BSS descriptor is NULL so we don't send request to PE", + __func__, __LINE__); + vos_mem_free(pMsg); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspec_Info->ts_info.up, + pTspec_Info->ts_info.tid); +#ifdef FEATURE_WLAN_ESE + if(pCsrSession->connectedProfile.isESEAssoc) + { + pMsg->req.tsrsIE.tsid = pTspec_Info->ts_info.up; + pMsg->req.tsrsPresent = 1; + } +#endif + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sent down a ADDTS req to PE", + __func__, __LINE__); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_REQ; + qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDelTsReq() - To send down the DELTS request with TSPEC params + to PE + + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session from which the TSPEC should be deleted + \param ac - Enumeration of the various EDCA Access Categories. + \param tspec_mask - on which tspec per AC, the delts is requested + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + tSirDeltsReq *pMsg; + sme_QosWmmTspecInfo *pTspecInfo; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d", + __func__, __LINE__, + sessionId, ac); + pMsg = (tSirDeltsReq *)vos_mem_malloc(sizeof(tSirDeltsReq)); + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pMsg, sizeof(tSirDeltsReq)); + // get pointer to the TSPEC being deleted + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + pTspecInfo = &pACInfo->curr_QoSInfo[tspec_mask - 1]; + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_DELTS_REQ); + pMsg->length = sizeof(tSirDeltsReq); + pMsg->sessionId = sessionId; + pMsg->rspReqd = VOS_TRUE; + pMsg->req.tspec.delayBound = pTspecInfo->delay_bound; + pMsg->req.tspec.inactInterval = pTspecInfo->inactivity_interval; + pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH; + pMsg->req.tspec.maxBurstSz = pTspecInfo->max_burst_size; + pMsg->req.tspec.maxMsduSz = pTspecInfo->maximum_msdu_size; + pMsg->req.tspec.maxSvcInterval = pTspecInfo->max_service_interval; + pMsg->req.tspec.meanDataRate = pTspecInfo->mean_data_rate; + pMsg->req.tspec.mediumTime = pTspecInfo->medium_time; + pMsg->req.tspec.minDataRate = pTspecInfo->min_data_rate; + pMsg->req.tspec.minPhyRate = pTspecInfo->min_phy_rate; + pMsg->req.tspec.minSvcInterval = pTspecInfo->min_service_interval; + pMsg->req.tspec.nomMsduSz = pTspecInfo->nominal_msdu_size; + pMsg->req.tspec.peakDataRate = pTspecInfo->peak_data_rate; + pMsg->req.tspec.surplusBw = pTspecInfo->surplus_bw_allowance; + pMsg->req.tspec.suspendInterval = pTspecInfo->suspension_interval; + pMsg->req.tspec.svcStartTime = pTspecInfo->svc_start_time; + pMsg->req.tspec.tsinfo.traffic.direction = pTspecInfo->ts_info.direction; + pMsg->req.tspec.tsinfo.traffic.psb = pTspecInfo->ts_info.psb; + pMsg->req.tspec.tsinfo.traffic.tsid = pTspecInfo->ts_info.tid; + pMsg->req.tspec.tsinfo.traffic.userPrio = pTspecInfo->ts_info.up; + pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspecInfo->ts_info.burst_size_defn; + pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspecInfo->ts_info.ack_policy; + pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE; + /*Fill the BSSID pMsg->req.bssId*/ + if (NULL == pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: BSS descriptor is NULL so we don't send request to PE", + __func__, __LINE__); + vos_mem_free(pMsg); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspecInfo->ts_info.up, + pTspecInfo->ts_info.tid); + vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sme_QosDelTsReq:Test: sent down a DELTS req to PE", + __func__, __LINE__); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_DELTS; + qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + } + + return status; +} + + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsRsp() - Function to process the + eWNI_SME_ADDTS_RSP came from PE + + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirAddtsRsp paddts_rsp = (tpSirAddtsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + v_U8_t sessionId = paddts_rsp->sessionId; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef WLAN_FEATURE_VOWIFI_11R + sme_QosWmmUpType up = (sme_QosWmmUpType)paddts_rsp->rsp.tspec.tsinfo.traffic.userPrio; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + + pSession = &sme_QosCb.sessionInfo[sessionId]; + +#ifdef WLAN_FEATURE_VOWIFI_11R + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + + return eHAL_STATUS_FAILURE; + } + pACInfo = &pSession->ac_info[ac]; + if (SME_QOS_HANDOFF == pACInfo->curr_state) + { + smsLog(pMac, LOG1, FL("ADDTS Response received for AC %d in HANDOFF State.. Dropping"), ac); + pSession->readyForPowerSave = VOS_TRUE; + return eHAL_STATUS_SUCCESS; + } +#endif + + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with return code %d", + __func__, __LINE__, + sessionId, paddts_rsp->rc); + // our outstanding request has been serviced + // we can go into powersave + pSession->readyForPowerSave = VOS_TRUE; + if(paddts_rsp->rc) + { + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_RSP; + qos.reasonCode = SME_QOS_DIAG_ADDTS_REFUSED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + status = sme_QosProcessAddTsFailureRsp(pMac, sessionId, &paddts_rsp->rsp); + } + else + { + status = sme_QosProcessAddTsSuccessRsp(pMac, sessionId, &paddts_rsp->rsp); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDelTsRsp() - Function to process the + eWNI_SME_DELTS_RSP came from PE + + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirDeltsRsp pDeltsRsp = (tpSirDeltsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + v_U8_t sessionId = pDeltsRsp->sessionId; + // msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with return code %d", + __func__, __LINE__, + sessionId, pDeltsRsp->rc); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our outstanding request has been serviced + // we can go into powersave + pSession->readyForPowerSave = VOS_TRUE; + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDelTsInd() - Function to process the + eWNI_SME_DELTS_IND came from PE + + Since it's a DELTS indication from AP, will notify all the flows running on + this AC about QoS release + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirDeltsRsp pdeltsind = (tpSirDeltsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t sessionId = pdeltsind->sessionId; + sme_QosEdcaAcType ac; + sme_QosSearchInfo search_key; + sme_QosWmmUpType up = (sme_QosWmmUpType)pdeltsind->rsp.tspec.tsinfo.traffic.userPrio; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, up); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //find all Flows on the perticular AC & delete them, also send HDD indication + // through the callback it registered per request + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosDelTsIndFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for ac = %d", + __func__, __LINE__, + search_key.key.ac_type); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + +//event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_DELTS; + qos.reasonCode = SME_QOS_DIAG_DELTS_IND_FROM_AP; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAssocCompleteEv() - Function to process the + SME_QOS_CSR_ASSOC_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + eHalStatus status = eHAL_STATUS_FAILURE; + sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_BE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(((SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state)) || + (pSession->handoffRequested)) + { + //get the association info + if(!pEvent_info) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pEvent_info is NULL", + __func__, __LINE__); + return status; + } + if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pBssDesc is NULL", + __func__, __LINE__); + return status; + } + if((pSession->assocInfo.pBssDesc) && + (csrIsBssidMatch(pMac, (tCsrBssid *)&pSession->assocInfo.pBssDesc->bssId, + (tCsrBssid *) &(((sme_QosAssocInfo *)pEvent_info)->pBssDesc->bssId)))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: assoc with the same BSS, no update needed", + __func__, __LINE__); + } + else + { + status = sme_QosSaveAssocInfo(pSession, pEvent_info); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: wrong state: BE %d, BK %d, VI %d, VO %d", + __func__, __LINE__, + pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state); + VOS_ASSERT(0); + return status; + } + // the session is active + pSession->sessionActive = VOS_TRUE; + if(pSession->handoffRequested) + { + pSession->handoffRequested = VOS_FALSE; + //renew all flows + (void)sme_QosProcessBufferedCmd(sessionId); + status = eHAL_STATUS_SUCCESS; + } + else + { + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_INIT: + sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP); + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + case SME_QOS_HANDOFF: + case SME_QOS_CLOSED: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocReqEv() - Function to process the + SME_QOS_CSR_REASSOC_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) + { + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info); + return eHAL_STATUS_SUCCESS; + } +#endif + + if(pSession->handoffRequested) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + + if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) + { + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + //buffer the existing flows to be renewed after handoff is done + sme_QosBufferExistingFlows(pMac, sessionId); + //clean up the control block partially for handoff + sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId); + return eHAL_STATUS_SUCCESS; + } +//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + + if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) + { + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info); + return eHAL_STATUS_SUCCESS; + } +#endif + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //This is normal because sme_QosRequestReassoc may already change the state + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocSuccessEv() - Function to process the + SME_QOS_CSR_REASSOC_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + + tCsrRoamSession *pCsrRoamSession = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac, ac_index; + sme_QosSearchInfo search_key; + sme_QosSearchInfo search_key1; + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + + if (CSR_ROAM_SESSION_MAX <= sessionId) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + return status; + } + + pCsrRoamSession = CSR_GET_SESSION( pMac, sessionId ); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our pending reassociation has completed + // we can allow powersave + pSession->readyForPowerSave = VOS_TRUE; + //get the association info + if(!pEvent_info) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pEvent_info is NULL", + __func__, __LINE__); + return status; + } + if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pBssDesc is NULL", + __func__, __LINE__); + return status; + } + status = sme_QosSaveAssocInfo(pSession, pEvent_info); + if(status) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosSaveAssocInfo() failed", + __func__, __LINE__); + } +//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time + if(pSession->handoffRequested) + { + pSession->handoffRequested = VOS_FALSE; + //renew all flows + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSession->ftHandoffInProgress) + { + if (csrRoamIs11rAssoc(pMac, sessionId)) { + if (pCsrRoamSession && + pCsrRoamSession->connectedInfo.nRICRspLength) { + status = sme_QosProcessFTReassocRspEv(pMac, sessionId, + pEvent_info); + } + } +#ifdef FEATURE_WLAN_ESE + // If ESE association check for TSPEC IEs in the reassoc rsp frame + if (csrRoamIsESEAssoc(pMac, sessionId)) { + if (pCsrRoamSession && + pCsrRoamSession->connectedInfo.nTspecIeLength) { + status = sme_QosESEProcessReassocTspecRsp(pMac, sessionId, + pEvent_info); + } + } +#endif + pSession->ftHandoffInProgress = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + return status; + } +#endif + + pSession->sessionActive = VOS_TRUE; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + // return to our previous state + sme_QosStateTransition(sessionId, ac, pACInfo->prev_state); + //for which ac APSD (hence the reassoc) is requested + if(pACInfo->reassoc_pending) + { + //update the apsd mask in CB - make sure to take care of the case + //where we are resetting the bit in apsd_mask + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + } + else + { + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + } + pACInfo->reassoc_pending = VOS_FALSE; + //during setup it gets set as addts & reassoc both gets a pending flag + //pACInfo->tspec_pending = 0; + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + // notify HDD with new Service Interval + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0]; + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //notify PMC that reassoc is done for APSD on certain AC?? + + vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo)); + //set the hoRenewal field in control block if needed + search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3; + search_key1.key.reason = SME_QOS_REASON_SETUP; + search_key1.sessionId = sessionId; + for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++) + { + pEntry = sme_QosFindInFlowList(search_key1); + if(pEntry) + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(flow_info->ac_type == ac) + { + pACInfo->hoRenewal = flow_info->hoRenewal; + break; + } + } + } + //notify HDD the success for the requested flow + //notify all the other flows running on the AC that QoS got modified + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosReassocSuccessEvFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for ac = %d", + __func__, __LINE__, + search_key.key.ac_type); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + pACInfo->hoRenewal = VOS_FALSE; + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + } + status = eHAL_STATUS_SUCCESS; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + //NOP + status = eHAL_STATUS_SUCCESS; + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + (void)sme_QosProcessBufferedCmd(sessionId); + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocFailureEv() - Function to process the + SME_QOS_CSR_REASSOC_FAILURE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our pending reassociation has completed + // we can allow powersave + pSession->readyForPowerSave = VOS_TRUE; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + if(pACInfo->reassoc_pending) + { + pACInfo->reassoc_pending = VOS_FALSE; + } + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR; + pACInfo->tspec_pending = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + //NOP + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffAssocReqEv() - Function to process the + SME_QOS_CSR_HANDOFF_ASSOC_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //print error msg +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: SME_QOS_CSR_HANDOFF_ASSOC_REQ received in " + "SME_QOS_HANDOFF state with FT in progress" + , __func__, __LINE__); + break; + } +#endif + + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (csrRoamIs11rAssoc(pMac, sessionId)) { + /* Need not check here if it is LFR3.0 roaming, + * since ftHandoffInProgress will be true if it + * is 11r assoc even with LFR2.0 */ + pSession->ftHandoffInProgress = VOS_TRUE; + } +#endif + + // If FT handoff is in progress, legacy handoff need not be enabled + if (!pSession->ftHandoffInProgress) { + pSession->handoffRequested = VOS_TRUE; + } + // this session no longer needs UAPSD + pSession->apsdMask = 0; + // do any sessions still require UAPSD? + if(!pMac->psOffloadEnabled) + { + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + else + { + (void)pmcOffloadStopUapsd(pMac, sessionId); + } + pSession->uapsdAlreadyRequested = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffSuccessEv() - Function to process the + SME_QOS_CSR_HANDOFF_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + //go back to original state before handoff + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, pACInfo->prev_state); + //we will retry for the requested flow(s) with the new AP + if(SME_QOS_REQUESTED == pACInfo->curr_state) + { + pACInfo->curr_state = SME_QOS_LINK_UP; + } + status = eHAL_STATUS_SUCCESS; + break; + // FT logic, has already moved it to QOS_REQUESTED state during the + // reassoc request event, which would include the Qos (TSPEC) params + // in the reassoc req frame + case SME_QOS_REQUESTED: + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + case SME_QOS_LINK_UP: + case SME_QOS_QOS_ON: + default: +#ifdef WLAN_FEATURE_VOWIFI_11R +/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the + state may be SME_QOS_REQUESTED */ + if( pSession->ftHandoffInProgress ) + break; +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffFailureEv() - Function to process the + SME_QOS_CSR_HANDOFF_FAILURE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + //need to clean up flows: TODO + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR; + pACInfo->tspec_pending = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + //no longer in handoff + pSession->handoffRequested = VOS_FALSE; + //clean up the assoc info + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDisconnectEv() - Function to process the + SME_QOS_CSR_DISCONNECT_REQ or SME_QOS_CSR_DISCONNECT_IND event indication + from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if((pSession->handoffRequested) +#ifdef WLAN_FEATURE_VOWIFI_11R +/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the + state may be SME_QOS_REQUESTED */ + && !pSession->ftHandoffInProgress +#endif + ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) + { + VOS_ASSERT(0); + return eHAL_STATUS_SUCCESS; + } + + return eHAL_STATUS_SUCCESS; + } + sme_QosInitACs(pMac, sessionId); + // this session doesn't require UAPSD + pSession->apsdMask = 0; + + if(!pMac->psOffloadEnabled) + { + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + else + { + (void)pmcOffloadStopUapsd(pMac, sessionId); + } + + pSession->uapsdAlreadyRequested = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + pSession->roamID = 0; + //need to clean up buffered req + sme_QosDeleteBufferedRequests(pMac, sessionId); + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + //clean up the assoc info + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + sme_QosCb.sessionInfo[sessionId].sessionActive = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessJoinReqEv() - Function to process the + SME_QOS_CSR_JOIN_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(pSession->handoffRequested) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + if ((pSession->ac_info[0].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[1].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[2].curr_state != SME_QOS_HANDOFF) || + (pSession->ac_info[3].curr_state != SME_QOS_HANDOFF)) + { + // just print + VOS_ASSERT(0); + } + + //buffer the existing flows to be renewed after handoff is done + sme_QosBufferExistingFlows(pMac, sessionId); + //clean up the control block partially for handoff + sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId); + return eHAL_STATUS_SUCCESS; + } + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + } + //clean up the assoc info if already set + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*-------------------------------------------------------------------------- + \brief sme_QosProcessPreauthSuccessInd() - Function to process the + SME_QOS_CSR_PREAUTH_SUCCESS_IND event indication from CSR + + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, + v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + tCsrRoamSession *pSmeSession = CSR_GET_SESSION( pMac, sessionId ); + sme_QosACInfo *pACInfo; + v_U8_t ac; + eHalStatus status = eHAL_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL("invoked on SME session %d"), sessionId); + + if (NULL == pSmeSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("pSmeSession is NULL")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //print error msg + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + VOS_ASSERT(0); + break; + } + } + + pSession->ftHandoffInProgress = VOS_TRUE; + + // Check if its a 11R roaming before preparing the RIC IEs + if (csrRoamIs11rAssoc(pMac, sessionId)) { + v_U16_t ricOffset = 0; + v_U32_t ricIELength = 0; + v_U8_t *ricIE; + v_U8_t tspec_mask_status = 0; + v_U8_t tspec_pending_status = 0; + + /* Data is accessed from saved PreAuth Rsp */ + if (NULL == pSmeSession->ftSmeContext.psavedFTPreAuthRsp) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("psavedFTPreAuthRsp is NULL")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + /* Any Block Ack info there, should have been already filled by PE and + present in this buffer and the ric_ies_length should contain the + length of the whole RIC IEs. Filling of TSPEC info should start + from this length */ + ricIE = pSmeSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies; + ricOffset = + pSmeSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length; + + /* Now we have to process the currentTspeInfo inside this session and + create the RIC IEs */ + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + volatile v_U8_t tspec_index = 0; + ricIELength = 0; + pACInfo = &pSession->ac_info[ac]; + tspec_pending_status = pACInfo->tspec_pending; + tspec_mask_status = pACInfo->tspec_mask_status; + vos_mem_zero(pACInfo->ricIdentifier, SME_QOS_TSPEC_INDEX_MAX); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("AC %d ==> TSPEC status = %d, tspec pending = %d"), + ac, tspec_mask_status, tspec_pending_status); + + do + { + if (tspec_mask_status & 0x1) + { + /* If a tspec status is pending, take requested_QoSInfo for + RIC request, else use curr_QoSInfo for the RIC request */ + if (tspec_pending_status & 0x1) + { + status = sme_QosCreateTspecRICIE(pMac, + &pACInfo->requested_QoSInfo[tspec_index], + ricIE + ricOffset, &ricIELength, + &pACInfo->ricIdentifier[tspec_index]); + } + else + { + status = sme_QosCreateTspecRICIE(pMac, + &pACInfo->curr_QoSInfo[tspec_index], + ricIE + ricOffset, &ricIELength, + &pACInfo->ricIdentifier[tspec_index]); + } + } + ricOffset += ricIELength; + pSmeSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length += + ricIELength; + + tspec_mask_status >>= 1; + tspec_pending_status >>= 1; + tspec_index++; + } while (tspec_mask_status); + } + } + return status; +} + +#endif + + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsFailureRsp() - Function to process the + Addts request failure response came from PE + + We will notify HDD only for the requested Flow, other Flows running on the AC + stay intact + + \param pMac - Pointer to the global MAC parameter structure. + \param pRsp - Pointer to the addts response structure came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + sme_QosSearchInfo search_key; + v_U8_t tspec_pending; + sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // is there a TSPEC request pending on this AC? + tspec_pending = pACInfo->tspec_pending; + if(!tspec_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d an AddTS is not pending on AC %d", + __func__, __LINE__, + sessionId, ac); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsFailureFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d no match found for ac = %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1], + sizeof(sme_QosWmmTspecInfo)); + + if((!pACInfo->num_flows[0])&& + (!pACInfo->num_flows[1])) + { + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~pACInfo->tspec_pending); + sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP); + } + else + { + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + } + pACInfo->tspec_pending = 0; + + (void)sme_QosProcessBufferedCmd(sessionId); + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateTspecMask() - Utiltity function to update the tspec. + Typical usage while aggregating unidirectional flows into a bi-directional + flow on AC which is running multiple flows + + \param sessionId - Session upon which the TSPEC is being updated + \param ac - Enumeration of the various EDCA Access Categories. + \param old_tspec_mask - on which tspec per AC, the update is requested + \param new_tspec_mask - tspec to be set for this AC + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId, + sme_QosSearchInfo search_key, + v_U8_t new_tspec_mask) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type, new_tspec_mask); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + if (search_key.key.ac_type < SME_QOS_EDCA_AC_MAX) + { + pACInfo = &pSession->ac_info[search_key.key.ac_type]; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pSession->ac_info", + __func__, __LINE__); + VOS_ASSERT (0); + return eHAL_STATUS_FAILURE; + } + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + + if(search_key.sessionId == flow_info->sessionId) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.direction == flow_info->QoSInfo.ts_info.direction)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->num_flows[new_tspec_mask - 1]++; + flow_info->tspec_mask = new_tspec_mask; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_5) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.tspec_mask == flow_info->tspec_mask)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->num_flows[new_tspec_mask - 1]++; + flow_info->tspec_mask = new_tspec_mask; + } + } + } + + pEntry = pNextEntry; + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsSuccessRsp() - Function to process the + Addts request success response came from PE + + We will notify HDD with addts success for the requested Flow, & for other + Flows running on the AC we will send an addts modify status + + + \param pMac - Pointer to the global MAC parameter structure. + \param pRsp - Pointer to the addts response structure came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac, ac_index; + sme_QosSearchInfo search_key; + sme_QosSearchInfo search_key1; + v_U8_t tspec_pending; + tListElem *pEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); + vos_log_qos_tspec_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + pSession = &sme_QosCb.sessionInfo[sessionId]; + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + return eHAL_STATUS_FAILURE; + } + pACInfo = &pSession->ac_info[ac]; + // is there a TSPEC request pending on this AC? + tspec_pending = pACInfo->tspec_pending; + if(!tspec_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d an AddTS is not pending on AC %d", + __func__, __LINE__, + sessionId, ac); + return eHAL_STATUS_FAILURE; + } + //App is looking for APSD or the App which was looking for APSD has been + //released, so STA re-negotiated with AP + if(pACInfo->requested_QoSInfo[tspec_pending - 1].ts_info.psb) + { + //update the session's apsd mask + pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + } + else + { + if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) > 0) && + ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) <= + SME_QOS_TSPEC_INDEX_MAX)) + { + if(!pACInfo->requested_QoSInfo + [(SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) - 1].ts_info.psb) + { + //update the session's apsd mask + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pACInfo->requested_QosInfo", + __func__, __LINE__); + VOS_ASSERT (0); + return eHAL_STATUS_FAILURE; + } + } + + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.burst_size_defn = + pRsp->tspec.tsinfo.traffic.burstSizeDefn; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.ack_policy = + pRsp->tspec.tsinfo.traffic.ackPolicy; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up = + pRsp->tspec.tsinfo.traffic.userPrio; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb = + pRsp->tspec.tsinfo.traffic.psb; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction = + pRsp->tspec.tsinfo.traffic.direction; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid = + pRsp->tspec.tsinfo.traffic.tsid; + pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size = + pRsp->tspec.nomMsduSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size = + pRsp->tspec.maxMsduSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval = + pRsp->tspec.minSvcInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval = + pRsp->tspec.maxSvcInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval = + pRsp->tspec.inactInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval = + pRsp->tspec.suspendInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time = + pRsp->tspec.svcStartTime; + pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate = + pRsp->tspec.minDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate = + pRsp->tspec.meanDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate = + pRsp->tspec.peakDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size = + pRsp->tspec.maxBurstSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound = + pRsp->tspec.delayBound; + + pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate = + pRsp->tspec.minPhyRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance = + pRsp->tspec.surplusBw; + pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time = + pRsp->tspec.mediumTime; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AddTspec Medium Time %d", + __func__, __LINE__, + sessionId, pRsp->tspec.mediumTime); + + /* Check if the current flow is for bi-directional. If so, update the number of flows + * to reflect that all flows are aggregated into tspec index 0. */ + if((pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) && + (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + /* update tspec_mask for all the flows having SME_QOS_TSPEC_MASK_BIT_2_SET to SME_QOS_TSPEC_MASK_BIT_1_SET */ + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_5; + search_key.sessionId = sessionId; + search_key.tspec_mask = SME_QOS_TSPEC_MASK_BIT_2_SET; + sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_1_SET); + } + + vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo)); + //set the horenewal field in control block if needed + search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3; + search_key1.key.reason = SME_QOS_REASON_SETUP; + search_key1.sessionId = sessionId; + for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++) + { + pEntry = sme_QosFindInFlowList(search_key1); + if(pEntry) + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(flow_info->ac_type == ac) + { + pACInfo->hoRenewal = flow_info->hoRenewal; + break; + } + } + } + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //notify HDD the success for the requested flow + //notify all the other flows running on the AC that QoS got modified + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsSuccessFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d no match found for ac %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + pACInfo->hoRenewal = VOS_FALSE; + vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1], + sizeof(sme_QosWmmTspecInfo)); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_RSP; + qos.reasonCode = SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_tspec_pkt_type, LOG_WLAN_QOS_TSPEC_C); + if(log_ptr) + { + log_ptr->delay_bound = pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound; + log_ptr->inactivity_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval; + log_ptr->max_burst_size = pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size; + log_ptr->max_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval; + log_ptr->maximum_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size; + log_ptr->mean_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate; + log_ptr->medium_time = pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time; + log_ptr->min_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate; + log_ptr->min_phy_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate; + log_ptr->min_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval; + log_ptr->nominal_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size; + log_ptr->peak_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate; + log_ptr->surplus_bw_allowance = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance; + log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance; + log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval; + log_ptr->svc_start_time = pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time; + log_ptr->tsinfo[0] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction << 5 | + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid << 1; + log_ptr->tsinfo[1] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up << 11 | + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb << 10; + log_ptr->tsinfo[2] = 0; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if (ac == SME_QOS_EDCA_AC_VO) + { + // Indicate to neighbor roam logic of the new required VO + // ac bandwidth requirement. + csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate, TRUE ); + } +#endif + pACInfo->tspec_pending = 0; + + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + + + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; + +} +/*-------------------------------------------------------------------------- + \brief sme_QosAggregateParams() - Utiltity function to increament the TSPEC + params per AC. Typical usage while using flow aggregation or deletion of flows + + \param pInput_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains the + WMM TSPEC related info with which pCurrent_Tspec_Info will be updated + \param pCurrent_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains + current the WMM TSPEC related info + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAggregateParams( + sme_QosWmmTspecInfo * pInput_Tspec_Info, + sme_QosWmmTspecInfo * pCurrent_Tspec_Info, + sme_QosWmmTspecInfo * pUpdated_Tspec_Info) +{ + sme_QosWmmTspecInfo TspecInfo; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked", + __func__, __LINE__); + if(!pInput_Tspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: input is NULL, nothing to aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + if(!pCurrent_Tspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Current is NULL, can't aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(&TspecInfo, pCurrent_Tspec_Info, + sizeof(sme_QosWmmTspecInfo)); + TspecInfo.ts_info.psb = pInput_Tspec_Info->ts_info.psb; + /*------------------------------------------------------------------------- + APSD preference is only meaningful if service interval was set by app + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->min_service_interval && + pInput_Tspec_Info->min_service_interval && + (pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction)) + { + TspecInfo.min_service_interval = VOS_MIN( + pCurrent_Tspec_Info->min_service_interval, + pInput_Tspec_Info->min_service_interval); + } + else if(pInput_Tspec_Info->min_service_interval) + { + TspecInfo.min_service_interval = pInput_Tspec_Info->min_service_interval; + } + if(pCurrent_Tspec_Info->max_service_interval && + pInput_Tspec_Info->max_service_interval && + (pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction)) + { + TspecInfo.max_service_interval = VOS_MIN( + pCurrent_Tspec_Info->max_service_interval, + pInput_Tspec_Info->max_service_interval); + } + else + { + TspecInfo.max_service_interval = pInput_Tspec_Info->max_service_interval; + } + /*------------------------------------------------------------------------- + If directions don't match, it must necessarily be both uplink and + downlink + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction) + { + TspecInfo.ts_info.direction = pInput_Tspec_Info->ts_info.direction; + } + /*------------------------------------------------------------------------- + Max MSDU size : these sizes are `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.maximum_msdu_size = VOS_MAX(pCurrent_Tspec_Info->maximum_msdu_size, + pInput_Tspec_Info->maximum_msdu_size); + + /*------------------------------------------------------------------------- + Inactivity interval : these sizes are `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.inactivity_interval = VOS_MAX(pCurrent_Tspec_Info->inactivity_interval, + pInput_Tspec_Info->inactivity_interval); + + /*------------------------------------------------------------------------- + Delay bounds: min of all values + Check on 0: if 0, it means initial value since delay can never be 0!! + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->delay_bound) + { + TspecInfo.delay_bound = VOS_MIN(pCurrent_Tspec_Info->delay_bound, + pInput_Tspec_Info->delay_bound); + } + else + { + TspecInfo.delay_bound = pInput_Tspec_Info->delay_bound; + } + TspecInfo.max_burst_size = VOS_MAX(pCurrent_Tspec_Info->max_burst_size, + pInput_Tspec_Info->max_burst_size); + + /*------------------------------------------------------------------------- + Nominal MSDU size also has a fixed bit that needs to be `handled' before + aggregation + This can be handled only if previous size is the same as new or both have + the fixed bit set + These sizes are not added: but `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.nominal_msdu_size = VOS_MAX( + pCurrent_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB, + pInput_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB); + + if( ((pCurrent_Tspec_Info->nominal_msdu_size == 0) || + (pCurrent_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)) && + ((pInput_Tspec_Info->nominal_msdu_size == 0) || + (pInput_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB))) + { + TspecInfo.nominal_msdu_size |= SME_QOS_16BIT_MSB; + } + + /*------------------------------------------------------------------------- + Data rates: + Add up the rates for aggregation + -------------------------------------------------------------------------*/ + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.peak_data_rate, + pInput_Tspec_Info->peak_data_rate ); + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.min_data_rate, + pInput_Tspec_Info->min_data_rate ); + /* mean data rate = peak data rate: aggregate to be flexible on apps */ + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.mean_data_rate, + pInput_Tspec_Info->mean_data_rate ); + + /*------------------------------------------------------------------------- + Suspension interval : this is set to the inactivity interval since per + spec it is less than or equal to inactivity interval + This is not provided by app since we currently don't support the HCCA + mode of operation + Currently set it to 0 to avoid confusion: Cisco ESE needs ~0; spec + requires inactivity interval to be > suspension interval: this could + be tricky! + -------------------------------------------------------------------------*/ + TspecInfo.suspension_interval = pInput_Tspec_Info->suspension_interval; + /*------------------------------------------------------------------------- + Remaining parameters do not come from app as they are very WLAN + air interface specific + Set meaningful values here + -------------------------------------------------------------------------*/ + TspecInfo.medium_time = 0; /* per WMM spec */ + TspecInfo.min_phy_rate = SME_QOS_MIN_PHY_RATE; + TspecInfo.svc_start_time = 0; /* arbitrary */ + TspecInfo.surplus_bw_allowance += pInput_Tspec_Info->surplus_bw_allowance; + if(TspecInfo.surplus_bw_allowance > SME_QOS_SURPLUS_BW_ALLOWANCE) + { + TspecInfo.surplus_bw_allowance = SME_QOS_SURPLUS_BW_ALLOWANCE; + } + /* Set ack_policy to block ack even if one stream requests block ack policy */ + if((pInput_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) || + (pCurrent_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)) + { + TspecInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + } + + if(pInput_Tspec_Info->ts_info.burst_size_defn || pCurrent_Tspec_Info->ts_info.burst_size_defn ) + { + TspecInfo.ts_info.burst_size_defn = 1; + } + if(pUpdated_Tspec_Info) + { + vos_mem_copy(pUpdated_Tspec_Info, &TspecInfo, + sizeof(sme_QosWmmTspecInfo)); + } + else + { + vos_mem_copy(pCurrent_Tspec_Info, &TspecInfo, + sizeof(sme_QosWmmTspecInfo)); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateParams() - Utiltity function to update the TSPEC + params per AC. Typical usage while deleting flows on AC which is running + multiple flows + + \param sessionId - Session upon which the TSPEC is being updated + \param ac - Enumeration of the various EDCA Access Categories. + \param tspec_mask - on which tspec per AC, the update is requested + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosUpdateParams(v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask, + sme_QosWmmTspecInfo * pTspec_Info) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosWmmTspecInfo Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, ac, tspec_mask); + if(!pTspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: output is NULL, can't aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(&Tspec_Info, sizeof(sme_QosWmmTspecInfo)); + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + //init the TS info field + Tspec_Info.ts_info.up = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.up; + Tspec_Info.ts_info.psb = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.psb; + Tspec_Info.ts_info.tid = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.tid; + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if((sessionId == flow_info->sessionId) && + (ac == flow_info->ac_type) && + (tspec_mask == flow_info->tspec_mask)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + + if((SME_QOS_REASON_RELEASE == flow_info->reason ) || + (SME_QOS_REASON_MODIFY == flow_info->reason)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Skipping Flow %d as it is marked " + "for release/modify", + __func__, __LINE__, + flow_info->QosFlowID); + } + else if(!HAL_STATUS_SUCCESS(sme_QosAggregateParams(&flow_info->QoSInfo, + &Tspec_Info, + NULL))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosAggregateParams() failed", + __func__, __LINE__); + } + } + pEntry = pNextEntry; + } + // return the aggregate + *pTspec_Info = Tspec_Info; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAcToUp() - Utiltity function to map an AC to UP + Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs + Mapping is done for consistency + \param ac - Enumeration of the various EDCA Access Categories. + \return an User Priority + + \sa + + --------------------------------------------------------------------------*/ +sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac) +{ + sme_QosWmmUpType up = SME_QOS_WMM_UP_MAX; + if(ac >= 0 && ac < SME_QOS_EDCA_AC_MAX) + { + up = sme_QosACtoUPMap[ac]; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: ac = %d up = %d returned", + __func__, __LINE__, ac, up); + return up; +} +/*-------------------------------------------------------------------------- + \brief sme_QosUpToAc() - Utiltity function to map an UP to AC + \param up - Enumeration of the various User priorities (UP). + \return an Access Category + + \sa + + --------------------------------------------------------------------------*/ +sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up) +{ + sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_MAX; + if(up >= 0 && up < SME_QOS_WMM_UP_MAX) + { + ac = sme_QosUPtoACMap[up]; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: up = %d ac = %d returned", + __func__, __LINE__, up, ac); + return ac; +} +/*-------------------------------------------------------------------------- + \brief sme_QosStateTransition() - The state transition function per AC. We + save the previous state also. + \param sessionId - Session upon which the state machine is running + \param ac - Enumeration of the various EDCA Access Categories. + \param new_state - The state FSM is moving to. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +static void sme_QosStateTransition(v_U8_t sessionId, + sme_QosEdcaAcType ac, + sme_QosStates new_state) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + pACInfo->prev_state = pACInfo->curr_state; + pACInfo->curr_state = new_state; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d new state=%d, old state=%d, for AC=%d", + __func__, __LINE__, + sessionId, pACInfo->curr_state, pACInfo->prev_state, ac ); +} +/*-------------------------------------------------------------------------- + \brief sme_QosFindInFlowList() - Utility function to find an flow entry from + the flow_list. + \param search_key - We can either use the flowID or the ac type to find the + entry in the flow list. + A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type + \return the pointer to the entry in the link list + + \sa + + --------------------------------------------------------------------------*/ +tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return NULL; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if((search_key.sessionId == flow_info->sessionId) || + (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY)) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) + { + if(search_key.key.QosFlowID == flow_info->QosFlowID) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on flowID, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) + { + if(search_key.key.ac_type == flow_info->ac_type) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on ac, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_3) + { + if(search_key.key.reason == flow_info->reason) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on reason, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.direction == flow_info->QoSInfo.ts_info.direction)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on reason, ending search", + __func__, __LINE__); + + break; + } + } + } + pEntry = pNextEntry; + } + return pEntry; +} +/*-------------------------------------------------------------------------- + \brief sme_QosFindAllInFlowList() - Utility function to find an flow entry + from the flow_list & act on it. + \param search_key - We can either use the flowID or the ac type to find the + entry in the flow list. + A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type + \param fnp - function pointer specifying the action type for the entry found + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac, + sme_QosSearchInfo search_key, + sme_QosProcessSearchEntry fnp) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosFlowInfoEntry *flow_info = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + if((search_key.sessionId == flow_info->sessionId) || + (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY)) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) + { + if(search_key.key.QosFlowID == flow_info->QosFlowID) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on flowID, ending search", + __func__, __LINE__); + status = fnp(pMac, pEntry); + if(eHAL_STATUS_FAILURE == status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Failed to process entry", + __func__, __LINE__); + break; + } + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) + { + if(search_key.key.ac_type == flow_info->ac_type) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on ac, ending search", + __func__, __LINE__); + flow_info->hoRenewal = pSession->ac_info[flow_info->ac_type].hoRenewal; + status = fnp(pMac, pEntry); + if(eHAL_STATUS_FAILURE == status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Failed to process entry", + __func__, __LINE__); + break; + } + } + } + } + pEntry = pNextEntry; + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosIsACM() - Utility function to check if a particular AC + mandates Admission Control. + \param ac - Enumeration of the various EDCA Access Categories. + + \return VOS_TRUE if the AC mandates Admission Control + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes) +{ + v_BOOL_t ret_val = VOS_FALSE; + tDot11fBeaconIEs *pIesLocal; + if(!pSirBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pSirBssDesc is NULL", + __func__, __LINE__); + return VOS_FALSE; + } + + if (NULL != pIes) + { + /* IEs were provided so use them locally */ + pIesLocal = pIes; + } + else + { + /* IEs were not provided so parse them ourselves */ + if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: csrGetParsedBssDescriptionIEs() failed", + __func__, __LINE__); + return VOS_FALSE; + } + + /* if success then pIesLocal was allocated */ + } + + if(CSR_IS_QOS_BSS(pIesLocal)) + { + switch(ac) + { + case SME_QOS_EDCA_AC_BE: + if(pIesLocal->WMMParams.acbe_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_BK: + if(pIesLocal->WMMParams.acbk_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_VI: + if(pIesLocal->WMMParams.acvi_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_VO: + if(pIesLocal->WMMParams.acvo_acm) ret_val = VOS_TRUE; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unknown AC = %d", + __func__, __LINE__, ac); + //Assert + VOS_ASSERT(0); + break; + } + }//IS_QOS_BSS + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: ACM = %d for AC = %d", + __func__, __LINE__, ret_val, ac ); + if (NULL == pIes) + { + /* IEs were allocated locally so free them */ + vos_mem_free(pIesLocal); + } + return ret_val; +} +/*-------------------------------------------------------------------------- + \brief sme_QosBufferExistingFlows() - Utility function to buffer the existing + flows in flow_list, so that we can renew them after handoff is done. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosCmdInfo cmd; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow List empty, nothing to buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if (flow_info->sessionId == sessionId) + { + if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )|| + (SME_QOS_REASON_SETUP == flow_info->reason )) + { + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = flow_info->HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = flow_info->QoSInfo; + cmd.u.setupCmdInfo.QoSCallback = flow_info->QoSCallback; + cmd.u.setupCmdInfo.UPType = SME_QOS_WMM_UP_MAX;//shouldn't be needed + cmd.u.setupCmdInfo.QosFlowID = flow_info->QosFlowID; + if(SME_QOS_REASON_SETUP == flow_info->reason ) + { + cmd.u.setupCmdInfo.hoRenewal = VOS_FALSE; + } + else + { + cmd.u.setupCmdInfo.hoRenewal = VOS_TRUE;//TODO: might need this for modify + } + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the setup request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a setup request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + else if(SME_QOS_REASON_RELEASE == flow_info->reason ) + { + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = flow_info->QosFlowID; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a release request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + else if(SME_QOS_REASON_MODIFY_PENDING == flow_info->reason) + { + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = flow_info->QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = flow_info->QoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a modify request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting original entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + vos_mem_free(flow_info); + } + pEntry = pNextEntry; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pSession->uapsdAlreadyRequested = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDeleteExistingFlows() - Utility function to Delete the existing + flows in flow_list, if we lost connectivity. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_TRUE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Flow List empty, nothing to delete", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_TRUE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if (flow_info->sessionId == sessionId) + { + if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )|| + (SME_QOS_REASON_SETUP == flow_info->reason )|| + (SME_QOS_REASON_RELEASE == flow_info->reason )|| + (SME_QOS_REASON_MODIFY == flow_info->reason )) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + NULL, + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + //delete the entry from Flow List + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + vos_mem_free(flow_info); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosBufferCmd() - Utility function to buffer a request (setup/modify/ + release) from client while processing another one on the same AC. + \param pcmd - a pointer to the cmd structure to be saved inside the buffered + cmd link list + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry * pentry = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked", + __func__, __LINE__); + pentry = (sme_QosCmdInfoEntry *) vos_mem_malloc(sizeof(sme_QosCmdInfoEntry)); + if (!pentry) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Memory allocation failure", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + // copy the entire CmdInfo + pentry->cmdInfo = *pcmd; + + pSession = &sme_QosCb.sessionInfo[pcmd->sessionId]; + if(insert_head) + { + csrLLInsertHead(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE); + } + else + { + csrLLInsertTail(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessBufferedCmd() - Utility function to process a buffered + request (setup/modify/release) initially came from the client. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry *pcmd = NULL; + tListElem *pEntry= NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(!csrLLIsListEmpty( &pSession->bufferedCommandList, VOS_FALSE )) + { + pEntry = csrLLRemoveHead( &pSession->bufferedCommandList, VOS_TRUE ); + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no more buffered commands on session %d", + __func__, __LINE__, + sessionId); + pSession->readyForPowerSave = VOS_TRUE; + return eHAL_STATUS_FAILURE; + } + pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link ); + switch(pcmd->cmdInfo.command) + { + case SME_QOS_SETUP_REQ: + hdd_status = sme_QosInternalSetupReq(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.sessionId, + &pcmd->cmdInfo.u.setupCmdInfo.QoSInfo, + pcmd->cmdInfo.u.setupCmdInfo.QoSCallback, + pcmd->cmdInfo.u.setupCmdInfo.HDDcontext, + pcmd->cmdInfo.u.setupCmdInfo.UPType, + pcmd->cmdInfo.u.setupCmdInfo.QosFlowID, + VOS_TRUE, + pcmd->cmdInfo.u.setupCmdInfo.hoRenewal); + if(SME_QOS_STATUS_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalSetupReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_RELEASE_REQ: + hdd_status = sme_QosInternalReleaseReq(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.u.releaseCmdInfo.QosFlowID, + VOS_TRUE); + if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalReleaseReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_MODIFY_REQ: + hdd_status = sme_QosInternalModifyReq(pcmd->cmdInfo.pMac, + &pcmd->cmdInfo.u.modifyCmdInfo.QoSInfo, + pcmd->cmdInfo.u.modifyCmdInfo.QosFlowID, + VOS_TRUE); + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalModifyReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_RESEND_REQ: + hdd_status = sme_QosReRequestAddTS(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.sessionId, + &pcmd->cmdInfo.u.resendCmdInfo.QoSInfo, + pcmd->cmdInfo.u.resendCmdInfo.ac, + pcmd->cmdInfo.u.resendCmdInfo.tspecMask); + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosReRequestAddTS failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unknown cmd = %d", + __func__, __LINE__, + sessionId, pcmd->cmdInfo.command); + VOS_ASSERT(0); + break; + } + // buffered command has been processed, reclaim the memory + vos_mem_free(pcmd); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: cmd buffer empty", + __func__, __LINE__); + pSession->readyForPowerSave = VOS_TRUE; + } + return halStatus; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDeleteBufferedRequests() - Utility function to Delete the buffered + requests in the buffered_cmd_list, if we lost connectivity. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry *pcmd = NULL; + tListElem *pEntry= NULL, *pNextEntry = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d", + __func__, __LINE__, sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + pEntry = csrLLPeekHead( &pSession->bufferedCommandList, VOS_TRUE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Buffered List empty, nothing to delete on session %d", + __func__, __LINE__, + sessionId); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &pSession->bufferedCommandList, pEntry, VOS_TRUE ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: deleting entry from buffered List", + __func__, __LINE__); + //delete the entry from Flow List + csrLLRemoveEntry(&pSession->bufferedCommandList, pEntry, VOS_TRUE ); + // reclaim the memory + pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link ); + vos_mem_free(pcmd); + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSaveAssocInfo() - Utility function to save the assoc info in the + CB like BSS descritor of the AP, the profile that HDD sent down with the + connect request, while CSR notifies for assoc/reassoc success. + \param pAssoc_info - pointer to the assoc structure to store the BSS descritor + of the AP, the profile that HDD sent down with the + connect request + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info) +{ + tSirBssDescription *pBssDesc = NULL; + v_U32_t bssLen = 0; + if(NULL == pAssoc_info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pAssoc_info is NULL", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + //clean up the assoc info if already set + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + bssLen = pAssoc_info->pBssDesc->length + + sizeof(pAssoc_info->pBssDesc->length); + //save the bss Descriptor + pBssDesc = (tSirBssDescription *)vos_mem_malloc(bssLen); + if (!pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the bss Descriptor", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pBssDesc, pAssoc_info->pBssDesc, bssLen); + pSession->assocInfo.pBssDesc = pBssDesc; + //save the apsd info from assoc + if(pAssoc_info->pProfile) + { + pSession->apsdMask |= pAssoc_info->pProfile->uapsd_mask; + } + // [TODO] Do we need to update the global APSD bitmap? + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosSetupFnp() - Utility function (pointer) to notify other entries + in FLOW list on the same AC that qos params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) + { + //notify HDD, only the other Flows running on the AC + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + hdd_status, + flow_info->QosFlowID); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Entry with flowID = %d getting notified", + __func__, __LINE__, + flow_info->QosFlowID); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosModificationNotifyFnp() - Utility function (pointer) to notify + other entries in FLOW list on the same AC that qos params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) + { + //notify HDD, only the other Flows running on the AC + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + hdd_status, + flow_info->QosFlowID); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Entry with flowID = %d getting notified", + __func__, __LINE__, + flow_info->QosFlowID); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosModifyFnp() - Utility function (pointer) to delete the origianl + entry in FLOW list & add the modified one + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosFlowInfoEntry *flow_info = NULL; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + switch(flow_info->reason) + { + case SME_QOS_REASON_MODIFY_PENDING: + //set the proper reason code for the new (with modified params) entry + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + break; + case SME_QOS_REASON_MODIFY: + //delete the original entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting original entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + break; + default: + break; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDelTsIndFnp() - Utility function (pointer) to find all Flows on + the perticular AC & delete them, also send HDD indication through the callback + it registered per request + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosEdcaAcType ac; + eHalStatus lock_status = eHAL_STATUS_FAILURE; + sme_QosStatusType status; + + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + //delete the entry from Flow List + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + pACInfo->relTrig = SME_QOS_RELEASE_BY_AP; + + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + //Call the internal function for QoS release, adding a layer of abstraction + status = sme_QosInternalReleaseReq(pMac, flow_info->QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release return status on Flow %d is %d", + __func__, __LINE__, + flow_info->QosFlowID, status); + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosReassocSuccessEvFnp() - Utility function (pointer) to notify HDD + the success for the requested flow & notify all the other flows running on the + same AC that QoS params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t delete_entry = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + eHalStatus pmc_status = eHAL_STATUS_FAILURE; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR(pEntry, sme_QosFlowInfoEntry, link); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + //check for the case where we had to do reassoc to reset the apsd bit + //for the ac - release or modify scenario + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything. + if(!pSession->uapsdAlreadyRequested) + { + // this is the first flow to detect we need PMC in UAPSD mode + if(!pMac->psOffloadEnabled) + { + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + } + else + { + pmc_status = pmcOffloadStartUapsd(pMac, + flow_info->sessionId, + sme_QosPmcOffloadStartUapsdCallback, + pSession); + } + + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED; + //we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_RELEASE: + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]--; + // fall through + case SME_QOS_REASON_MODIFY: + delete_entry = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + + if(!pSession->uapsdAlreadyRequested) + { + if(!pMac->psOffloadEnabled) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + } + else + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcOffloadStartUapsd(pMac, + flow_info->sessionId, + sme_QosPmcOffloadStartUapsdCallback, + pSession); + } + + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_REQ_SUCCESS: + hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + // fall through + default: + delete_entry = VOS_FALSE; + break; + } + if(!delete_entry) + { + if(!flow_info->hoRenewal) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + hdd_status, + flow_info->QosFlowID); + } + else + { + flow_info->hoRenewal = VOS_FALSE; + } + } + else + { + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsFailureFnp() - Utility function (pointer), + if the Addts request was for for an flow setup request, delete the entry from + Flow list & notify HDD + if the Addts request was for downgrading of QoS params because of an flow + release requested on the AC, delete the entry from Flow list & notify HDD + if the Addts request was for change of QoS params because of an flow + modification requested on the AC, delete the new entry from Flow list & notify + HDD + + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t inform_hdd = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_RELEASE: + hdd_status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY: + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + case SME_QOS_REASON_REQ_SUCCESS: + default: + inform_hdd = VOS_FALSE; + break; + } + if(inform_hdd) + { + //notify HDD, only the requested Flow, other Flows running on the AC stay + // intact + if(!flow_info->hoRenewal) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + hdd_status, + flow_info->QosFlowID); + } + else + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + } + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsSuccessFnp() - Utility function (pointer), + if the Addts request was for for an flow setup request, notify HDD for success + for the flow & notify all the other flows running on the same AC that QoS + params got modified + if the Addts request was for downgrading of QoS params because of an flow + release requested on the AC, delete the entry from Flow list & notify HDD + if the Addts request was for change of QoS params because of an flow + modification requested on the AC, delete the old entry from Flow list & notify + HDD for success for the flow & notify all the other flows running on the same + AC that QoS params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t inform_hdd = VOS_FALSE; + v_BOOL_t delete_entry = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + eHalStatus pmc_status = eHAL_STATUS_FAILURE; + tCsrRoamModifyProfileFields modifyProfileFields; + + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(flow_info->tspec_mask != pACInfo->tspec_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: No need to notify the HDD, the ADDTS " + "success is not for index = %d of the AC = %d", + __func__, __LINE__, + flow_info->tspec_mask, ac); + return eHAL_STATUS_SUCCESS; + } + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + delete_entry = VOS_FALSE; + inform_hdd = VOS_TRUE; + // check if App is looking for APSD + if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything + if(!pSession->uapsdAlreadyRequested) + { + if(!pMac->psOffloadEnabled) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + } + else + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcOffloadStartUapsd(pMac, + flow_info->sessionId, + sme_QosPmcOffloadStartUapsdCallback, + pSession); + } + + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_RELEASE: + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + hdd_status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; + inform_hdd = VOS_TRUE; + delete_entry = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY: + delete_entry = VOS_TRUE; + inform_hdd = VOS_FALSE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + inform_hdd = VOS_TRUE; + //notify PMC if App is looking for APSD + if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything. + if(!pSession->uapsdAlreadyRequested) + { + if(!pMac->psOffloadEnabled) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + } + else + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcOffloadStartUapsd(pMac, + flow_info->sessionId, + sme_QosPmcOffloadStartUapsdCallback, + pSession); + } + + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + else + { + if((pACInfo->num_flows[flow_info->tspec_mask - 1] == 1) && + (SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status)) + { + // this is the only TSPEC active on this AC + // so indicate that we no longer require APSD + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + //Also update modifyProfileFields.uapsd_mask in CSR for consistency + csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask = pSession->apsdMask; + csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + if(!pSession->apsdMask) + { + if(!pMac->psOffloadEnabled) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + else + { + (void)pmcOffloadStopUapsd(pMac, flow_info->sessionId); + } + } + } + } + break; + case SME_QOS_REASON_REQ_SUCCESS: + hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + inform_hdd = VOS_TRUE; + default: + delete_entry = VOS_FALSE; + break; + } + if(inform_hdd) + { + if(!flow_info->hoRenewal) + { + + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + hdd_status, + flow_info->QosFlowID); + } + else + { + flow_info->hoRenewal = VOS_FALSE; + } + } + if(delete_entry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + //delete the entry from Flow List + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosIsRspPending() - Utility function to check if we are waiting + for an AddTS or reassoc response on some AC other than the given AC + + \param sessionId - Session we are interted in + \param ac - Enumeration of the various EDCA Access Categories. + + \return boolean + TRUE - Response is pending on an AC + + \sa + + --------------------------------------------------------------------------*/ +static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType acIndex; + v_BOOL_t status = VOS_FALSE; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(acIndex = SME_QOS_EDCA_AC_BE; acIndex < SME_QOS_EDCA_AC_MAX; acIndex++) + { + if(acIndex == ac) + { + continue; + } + pACInfo = &pSession->ac_info[acIndex]; + if((pACInfo->tspec_pending) || (pACInfo->reassoc_pending)) + { + status = VOS_TRUE; + break; + } + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateHandOff() - Function which can be called to update + Hand-off state of SME QoS Session + \param sessionId - session id + \param updateHandOff - value True/False to update the handoff flag + + \sa + +-------------------------------------------------------------------------*/ +void sme_QosUpdateHandOff(v_U8_t sessionId, + v_BOOL_t updateHandOff) +{ + sme_QosSessionInfo *pSession; + pSession = &sme_QosCb.sessionInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: handoffRequested %d updateHandOff %d", + __func__, __LINE__,pSession->handoffRequested, + updateHandOff); + + pSession->handoffRequested = updateHandOff; + +} + +/*-------------------------------------------------------------------------- + \brief sme_QosIsUapsdActive() - Function which can be called to determine + if any sessions require PMC to be in U-APSD mode. + \return boolean + + Returns true if at least one session required PMC to be in U-APSD mode + Returns false if no sessions require PMC to be in U-APSD mode + + \sa + + --------------------------------------------------------------------------*/ +static v_BOOL_t sme_QosIsUapsdActive(void) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if ((pSession->sessionActive) && (pSession->apsdMask)) + { + return VOS_TRUE; + } + } + // no active sessions have U-APSD active + return VOS_FALSE; +} +/*-------------------------------------------------------------------------- + \brief sme_QosPmcFullPowerCallback() - Callback function registered with PMC + to notify SME-QoS when it puts the chip into full power + + \param callbackContext - The context passed to PMC during pmcRequestFullPower + call. + \param status - eHalStatus returned by PMC. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + if(HAL_STATUS_SUCCESS(status)) + { + (void)sme_QosProcessBufferedCmd(pSession->sessionId); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: PMC failed to put the chip in Full power", + __func__, __LINE__); + VOS_ASSERT(0); + } +} + +void sme_QosPmcOffloadFullPowerCallback(void *callbackContext, tANI_U32 sessionId, + eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + if(HAL_STATUS_SUCCESS(status)) + { + (void)sme_QosProcessBufferedCmd(pSession->sessionId); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: PMC failed to put the chip in Full power", + __func__, __LINE__); + VOS_ASSERT(0); + } +} + +/*-------------------------------------------------------------------------- + \brief sme_QosPmcStartUAPSDCallback() - Callback function registered with PMC + to notify SME-QoS when it puts the chip into UAPSD mode + + \param callbackContext - The context passed to PMC during pmcStartUapsd call. + \param status - eHalStatus returned by PMC. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + // NOTE WELL + // + // In the orignal QoS design the TL module was responsible for + // the generation of trigger frames. When that design was in + // use, we had to queue up any flows which were waiting for PMC + // since we didn't want to notify HDD until PMC had changed to + // UAPSD state. Otherwise HDD would provide TL with the trigger + // frame parameters, and TL would start trigger frame generation + // before PMC was ready. The flows were queued in various places + // throughout this module, and they were dequeued here following + // a successful transition to the UAPSD state by PMC. + // + // In the current QoS design the Firmware is responsible for the + // generation of trigger frames, but the parameters are still + // provided by TL via HDD. The Firmware will be notified of the + // change to UAPSD state directly by PMC, at which time it will be + // responsible for the generation of trigger frames. Therefore + // where we used to queue up flows waiting for PMC to transition + // to the UAPSD state, we now always transition directly to the + // "success" state so that HDD will immediately provide the trigger + // frame parameters to TL, who will in turn plumb them down to the + // Firmware. That way the Firmware will have the trigger frame + // parameters when it needs them + // just note that there is no longer an outstanding request + pSession->uapsdAlreadyRequested = VOS_FALSE; +} + +void sme_QosPmcOffloadStartUapsdCallback(void *callbackContext, + tANI_U32 sessionId, eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + pSession->uapsdAlreadyRequested = VOS_FALSE; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosPmcCheckRoutine() - Function registered with PMC to check with + SME-QoS whenever the device is about to enter one of the power + save modes. PMC runs a poll with all the registered modules if device can + enter powersave mode or remain in full power + + \param callbackContext - The context passed to PMC during registration through + pmcRegisterPowerSaveCheck. + \return boolean + + SME-QOS returns PMC true or false respectively if it wants to vote for + entering power save or not + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if ((pSession->sessionActive) && + (!pSession->readyForPowerSave)) + { + return VOS_FALSE; + } + } + // all active sessions have voted for powersave + return VOS_TRUE; +} + +v_BOOL_t sme_QosPmcOffloadCheckRoutine(void *callbackContext, tANI_U32 sessionId) +{ + sme_QosSessionInfo *pSession = &sme_QosCb.sessionInfo[sessionId]; + + if ((pSession->sessionActive) && + (!pSession->readyForPowerSave)) + { + return VOS_FALSE; + } + return VOS_TRUE; + +} + +/*-------------------------------------------------------------------------- + \brief sme_QosPmcDeviceStateUpdateInd() - Callback function registered with + PMC to notify SME-QoS when it changes the power state + + \param callbackContext - The context passed to PMC during registration + through pmcRegisterDeviceStateUpdateInd. + \param pmcState - Current power state that PMC moved into. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext ); + //check all the entries in Flow list for non-zero service interval, which will + //tell us if we need to notify HDD when PMC is out of UAPSD mode or going + // back to UAPSD mode + switch(pmcState) + { + case FULL_POWER: + status = sme_QosProcessOutOfUapsdMode(pMac); + break; + case UAPSD: + status = sme_QosProcessIntoUapsdMode(pMac); + break; + default: + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: nothing to process in PMC state %d", + __func__, __LINE__, + pmcState); + } + if(!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: ignoring Device(PMC) state change to %d", + __func__, __LINE__, + pmcState); + } + +} + +void sme_OffloadQosPmcDeviceStateUpdateInd(void *callbackContext, + tANI_U32 sessionId, tPmcState pmcState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext ); + /* + * check all the entries in Flow list for non-zero service interval, + * which will tell us if we need to notify HDD when + * PMC is out of UAPSD mode or going + * back to UAPSD mode + */ + switch(pmcState) + { + case FULL_POWER: + status = sme_OffloadQosProcessOutOfUapsdMode(pMac, sessionId); + break; + case UAPSD: + status = sme_OffloadQosProcessIntoUapsdMode(pMac, sessionId); + break; + default: + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: nothing to process in PMC state %d", + __func__, __LINE__, + pmcState); + } + if(!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: ignoring Device(PMC) state change to %d", + __func__, __LINE__, + pmcState); + } +} + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessOutOfUapsdMode() - Function to notify HDD when PMC + notifies SME-QoS that it moved out of UAPSD mode to FULL power + + \param pMac - Pointer to the global MAC parameter structure. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + //only notify the flows which already successfully setup UAPSD + if((flow_info->QoSInfo.max_service_interval || + flow_info->QoSInfo.min_service_interval) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_OffloadQosProcessOutOfUapsdMode(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while(pEntry) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + /* only notify the flows which already successfully setup UAPSD */ + if((sessionId == flow_info->sessionId) && + (flow_info->QoSInfo.max_service_interval || + flow_info->QoSInfo.min_service_interval) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type]. + curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessIntoUapsdMode() - Function to notify HDD when PMC + notifies SME-QoS that it is moving into UAPSD mode + + \param pMac - Pointer to the global MAC parameter structure. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + //only notify the flows which already successfully setup UAPSD + if( (flow_info->QoSInfo.ts_info.psb) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) ) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_OffloadQosProcessIntoUapsdMode(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while(pEntry) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + /* only notify the flows which already successfully setup UAPSD */ + if((sessionId == flow_info->sessionId) && + (flow_info->QoSInfo.max_service_interval || + flow_info->QoSInfo.min_service_interval) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type]. + curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} + +void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac, v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + vos_mem_zero(pACInfo->curr_QoSInfo, + sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX); + vos_mem_zero(pACInfo->requested_QoSInfo, + sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX); + pACInfo->num_flows[0] = 0; + pACInfo->num_flows[1] = 0; + pACInfo->reassoc_pending = VOS_FALSE; + pACInfo->tspec_mask_status = 0; + pACInfo->tspec_pending = VOS_FALSE; + pACInfo->hoRenewal = VOS_FALSE; + pACInfo->prev_state = SME_QOS_LINK_UP; + } +} + +/*-------------------------------------------------------------------------- + \brief sme_QosIsTSInfoAckPolicyValid() - The SME QoS API exposed to HDD to + check if TS info ack policy field can be set to "HT-immediate block acknowledgement" + + \param pMac - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info, provided by HDD + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE - Current Association is HT association and so TS info ack policy + can be set to "HT-immediate block acknowledgement" + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsTSInfoAckPolicyValid(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId) +{ + tDot11fBeaconIEs *pIes = NULL; + sme_QosSessionInfo *pSession; + eHalStatus hstatus; + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session Id %d is invalid", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d is inactive", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + if(!pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d has an Invalid BSS Descriptor", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + hstatus = csrGetParsedBssDescriptionIEs(pMac, + pSession->assocInfo.pBssDesc, + &pIes); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to parse BSS IEs", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + /* success means pIes was allocated */ + + if(!pIes->HTCaps.present && + pQoSInfo->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d HT Caps aren't present but application set ack policy to HT ", + __func__, __LINE__, + sessionId); + + vos_mem_free(pIes); + return VOS_FALSE; + } + + vos_mem_free(pIes); + return VOS_TRUE; +} + +v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId) +{ + v_BOOL_t rc = VOS_FALSE; + + do + { + if(SME_QOS_WMM_TS_DIR_RESV == pQoSInfo->ts_info.direction) break; + if(!sme_QosIsTSInfoAckPolicyValid(pMac, pQoSInfo, sessionId)) break; + + rc = VOS_TRUE; + }while(0); + return rc; +} + +static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId, + eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, v_U8_t tspec_mask ) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + do + { + pCommand = smeGetCommandBuffer( pMac ); + if ( !pCommand ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: fail to get command buffer for command %d", + __func__, __LINE__, cmdType); + break; + } + pCommand->command = cmdType; + pCommand->sessionId = sessionId; + switch ( cmdType ) + { + case eSmeCommandAddTs: + if( pQoSInfo ) + { + status = eHAL_STATUS_SUCCESS; + pCommand->u.qosCmd.tspecInfo = *pQoSInfo; + pCommand->u.qosCmd.ac = ac; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: NULL pointer passed", + __func__, __LINE__); + status = eHAL_STATUS_INVALID_PARAMETER; + } + break; + case eSmeCommandDelTs: + status = eHAL_STATUS_SUCCESS; + pCommand->u.qosCmd.ac = ac; + pCommand->u.qosCmd.tspec_mask = tspec_mask; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid command type %d", + __func__, __LINE__, cmdType ); + status = eHAL_STATUS_INVALID_PARAMETER; + break; + } + } while( 0 ); + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + smePushCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + else if( pCommand ) + { + qosReleaseCommand( pMac, pCommand ); + } + return( status ); +} +tANI_BOOLEAN qosProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE; + do + { + switch ( pCommand->command ) + { + case eSmeCommandAddTs: + status = sme_QosAddTsReq( pMac, (v_U8_t)pCommand->sessionId, &pCommand->u.qosCmd.tspecInfo, pCommand->u.qosCmd.ac); + if( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + } + break; + case eSmeCommandDelTs: + status = sme_QosDelTsReq( pMac, (v_U8_t)pCommand->sessionId, pCommand->u.qosCmd.ac, pCommand->u.qosCmd.tspec_mask ); + if( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid command type %d", + __func__, __LINE__, pCommand->command ); + break; + }//switch + } while(0); + return( fRemoveCmd ); +} + +/* + sme_QosTriggerUapsdChange + Invoked by BTC when UAPSD bypass is enabled or disabled + We, in turn, must disable or enable UAPSD on all flows as appropriate + That may require us to re-add TSPECs or to reassociate +*/ +sme_QosStatusType sme_QosTriggerUapsdChange( tpAniSirGlobal pMac ) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac, tspec1 = 0, tspec2 = 0; + v_U8_t uapsd_mask; + tDot11fBeaconIEs *pIesLocal; + v_U8_t acm_mask; + v_BOOL_t fIsUapsdNeeded; + v_U8_t sessionId; + v_BOOL_t addtsWhenACMNotSet = CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked", + __func__, __LINE__); + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if( !pSession->sessionActive ) + { + continue; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Session %d is active", + __func__, __LINE__, + sessionId); + if( HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSession->assocInfo.pBssDesc, &pIesLocal)) ) + { + // get the ACM mask + acm_mask = sme_QosGetACMMask(pMac, pSession->assocInfo.pBssDesc, pIesLocal); + vos_mem_free(pIesLocal); + // get the uapsd mask for this session + uapsd_mask = pSession->apsdMask; + // unmask the bits with ACM on to avoid reassoc on them + uapsd_mask &= ~acm_mask; + // iterate through the ACs to determine if we need to re-add any TSPECs + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + // Does this AC have QoS active? + if( SME_QOS_QOS_ON == pACInfo->curr_state ) + { + // Yes, QoS is active on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has QoS active", + __func__, __LINE__, + sessionId, ac); + // Does this AC require ACM? + if(( acm_mask & (1 << (SME_QOS_EDCA_AC_VO - ac)) ) || addtsWhenACMNotSet ) + { + // Yes, so we need to re-add any TSPECS + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has ACM enabled", + __func__, __LINE__, + sessionId, ac); + // Are any TSPECs active? + if( pACInfo->tspec_mask_status ) + { + // Yes, at least 1 TSPEC is active. Are they both active? + if( SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status ) + { + //both TSPECS are active + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_SET; + tspec2 = SME_QOS_TSPEC_MASK_BIT_2_SET; + } + else + { + // only one TSPEC is active, get its mask + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_2_SET & pACInfo->tspec_mask_status; + } + // Does TSPEC 1 really require UAPSD? + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec1 - 1].ts_info.psb); + //double check whether we need to do anything + if( fIsUapsdNeeded ) + { + pACInfo->requested_QoSInfo[tspec1 - 1] = + pACInfo->curr_QoSInfo[tspec1 - 1]; + sme_QosReRequestAddTS( pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec1 - 1], + ac, + tspec1 ); + } + // Is TSPEC 2 active? + if( tspec2 ) + { + // Does TSPEC 2 really require UAPSD? + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec2 - 1].ts_info.psb); + if( fIsUapsdNeeded ) + { + //No need to inform HDD + //pACInfo->hoRenewal = VOS_TRUE; + pACInfo->requested_QoSInfo[tspec2 - 1] = + pACInfo->curr_QoSInfo[tspec2 - 1]; + sme_QosReRequestAddTS( pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec2 - 1], + ac, + tspec2); + } + } + } + else + { + // QoS is set, ACM is on, but no TSPECs -- inconsistent state + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d has QoS enabled and ACM is set, but no TSPEC", + __func__, __LINE__, + sessionId, ac); + VOS_ASSERT(0); + } + } + else + { + //Since ACM bit is not set, there should be only one QoS information for both directions. + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[0].ts_info.psb); + if(fIsUapsdNeeded) + { + // we need UAPSD on this AC (and we may not currently have it) + uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has ACM disabled, uapsd mask now 0x%X", + __func__, __LINE__, + sessionId, ac, uapsd_mask); + } + } + } + } + // do we need to reassociate? + if(uapsd_mask) + { + tCsrRoamModifyProfileFields modifyProfileFields; + //we need to do a reassoc on these AC + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + if( btcIsReadyForUapsd(pMac) ) + { + modifyProfileFields.uapsd_mask = uapsd_mask; + } + else + { + modifyProfileFields.uapsd_mask = 0; + } + //Do we need to inform HDD? + if(!HAL_STATUS_SUCCESS(sme_QosRequestReassoc(pMac, sessionId, &modifyProfileFields, VOS_TRUE))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d Reassoc failed", + __func__, __LINE__, + sessionId); + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d failed to parse IEs", + __func__, __LINE__, + sessionId); + } + } + // return status is ignored by BTC + return SME_QOS_STATUS_SETUP_SUCCESS_IND; +} + +/* + sme_QosReRequestAddTS to re-send AddTS for the combined QoS request +*/ +static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, + v_U8_t tspecMask) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + sme_QosCmdInfo cmd; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, ac, tspecMask); + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + //call PMC's request for power function + // AND + //another check is added considering the flowing scenario + //Addts reqest is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(!pMac->psOffloadEnabled) + { + if(sme_QosIsRspPending(sessionId, ac) || + ( eHAL_STATUS_PMC_PENDING == pmcRequestFullPower(pMac, + sme_QosPmcFullPowerCallback, pSession, eSME_REASON_OTHER))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d buffering the AddTS request " + "for AC %d in state %d as Addts is pending " + "on other AC or waiting for full power", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //buffer cmd + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = tspecMask; + cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to buffer the AddTS " + "request for AC %d TSPEC %d in state %d", + __func__, __LINE__, + sessionId, ac, tspecMask, pACInfo->curr_state); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + } + } + else + { + if(sme_QosIsRspPending(sessionId, ac) || + (eHAL_STATUS_PMC_PENDING == pmcOffloadRequestFullPower(pMac, sessionId, + sme_QosPmcOffloadFullPowerCallback, pSession, eSME_REASON_OTHER))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d buffering the AddTS request " + "for AC %d in state %d as Addts is pending " + "on other AC or waiting for full power", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //buffer cmd + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = tspecMask; + cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to buffer the AddTS " + "request for AC %d TSPEC %d in state %d", + __func__, __LINE__, + sessionId, ac, tspecMask, pACInfo->curr_state); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + } + } + + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + { + //if ACM, send out a new ADDTS + pACInfo->hoRenewal = VOS_TRUE; + status = sme_QosSetup(pMac, sessionId, pQoSInfo, ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sme_QosSetup returned in SME_QOS_QOS_ON state on " + "AC %d with status =%d", + __func__, __LINE__, + ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + pACInfo->tspec_pending = tspecMask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING == status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: UAPSD is setup already status = %d " + "returned by sme_QosSetup", + __func__, __LINE__, + status); + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unexpected status = %d returned by sme_QosSetup", + __func__, __LINE__, + status); + } + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Re-Add request in state = %d buffer the request", + __func__, __LINE__, + pACInfo->curr_state); + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = tspecMask; + cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the readd request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + //print error msg, + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: ReAdd request in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + // ASSERT? + break; + } + if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return (status); +} + +static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + vos_mem_zero(&pSession->ac_info[ac], sizeof(sme_QosACInfo)); + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + } +} +static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId, + tCsrRoamModifyProfileFields *pModFields, + v_BOOL_t fForce ) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + eHalStatus status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with UAPSD mask 0x%X", + __func__, __LINE__, + sessionId, pModFields->uapsd_mask); + pSession = &sme_QosCb.sessionInfo[sessionId]; + status = csrReassoc(pMac, sessionId, pModFields, &pSession->roamID, fForce); + if(HAL_STATUS_SUCCESS(status)) + { + //Update the state to Handoff so subsequent requests are queued until + // this one is finished + sme_QosEdcaAcType ac; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: AC[%d] is in state [%d]", + __func__, __LINE__, + ac, pACInfo->curr_state ); + // If it is already in HANDOFF state, don't do anything since we + // MUST preserve the previous state and sme_QosStateTransition + // will change the previous state + if(SME_QOS_HANDOFF != pACInfo->curr_state) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + } + } + } + return status; +} +static v_U32_t sme_QosAssignFlowId(void) +{ + v_U32_t flowId; + flowId = sme_QosCb.nextFlowId; + if (SME_QOS_MAX_FLOW_ID == flowId) + { + // The Flow ID wrapped. This is obviously not a real life scenario + // but handle it to keep the software test folks happy + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: Software Test made the flow counter wrap, " + "QoS may no longer be functional", + __func__, __LINE__); + sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID; + } + else + { + sme_QosCb.nextFlowId++; + } + return flowId; +} + +static v_U8_t sme_QosAssignDialogToken(void) +{ + v_U8_t token; + token = sme_QosCb.nextDialogToken; + if (SME_QOS_MAX_DIALOG_TOKEN == token) + { + // wrap is ok + sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN; + } + else + { + sme_QosCb.nextDialogToken++; + } + return token; +} +#endif /* WLAN_MDM_CODE_REDUCTION_OPT */ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/btc/btcApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/btc/btcApi.c new file mode 100644 index 0000000000000..4b5169d14ed10 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/btc/btcApi.c @@ -0,0 +1,2095 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: btcApi.c +* +* Description: Routines that make up the BTC API. +* + +* +******************************************************************************/ +#include "wlan_qct_wda.h" +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +#include "aniGlobal.h" +#include "smsDebug.h" +#include "btcApi.h" +#include "cfgApi.h" +#include "pmc.h" +#include "smeQosInternal.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent); +static void btcRestoreHeartBeatMonitoringHandle(void* hHal); +static void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent ); +VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent); +static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState ); +static void btcPowerOffloadStateCB(v_PVOID_t pContext, tANI_U32 sessionId, + tPmcState pmcState ); +static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ); +static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT +static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +/* --------------------------------------------------------------------------- + \fn btcOpen + \brief API to init the BTC Events Layer + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + VOS_STATUS_E_FAILURE success + VOS_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +VOS_STATUS btcOpen (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + int i; + + /* Initialize BTC configuartion. */ + pMac->btc.btcConfig.btcExecutionMode = BTC_SMART_COEXISTENCE; + pMac->btc.btcConfig.btcConsBtSlotsToBlockDuringDhcp = 0; + pMac->btc.btcConfig.btcA2DPBtSubIntervalsDuringDhcp = BTC_MAX_NUM_ACL_BT_SUB_INTS; + pMac->btc.btcConfig.btcBtIntervalMode1 = BTC_BT_INTERVAL_MODE1_DEFAULT; + pMac->btc.btcConfig.btcWlanIntervalMode1 = BTC_WLAN_INTERVAL_MODE1_DEFAULT; + pMac->btc.btcConfig.btcActionOnPmFail = BTC_START_NEXT; + + pMac->btc.btcConfig.btcStaticLenInqBt = BTC_STATIC_BT_LEN_INQ_DEF; + pMac->btc.btcConfig.btcStaticLenPageBt = BTC_STATIC_BT_LEN_PAGE_DEF; + pMac->btc.btcConfig.btcStaticLenConnBt = BTC_STATIC_BT_LEN_CONN_DEF; + pMac->btc.btcConfig.btcStaticLenLeBt = BTC_STATIC_BT_LEN_LE_DEF; + pMac->btc.btcConfig.btcStaticLenInqWlan = BTC_STATIC_WLAN_LEN_INQ_DEF; + pMac->btc.btcConfig.btcStaticLenPageWlan = BTC_STATIC_WLAN_LEN_PAGE_DEF; + pMac->btc.btcConfig.btcStaticLenConnWlan = BTC_STATIC_WLAN_LEN_CONN_DEF; + pMac->btc.btcConfig.btcStaticLenLeWlan = BTC_STATIC_WLAN_LEN_LE_DEF; + pMac->btc.btcConfig.btcDynMaxLenBt = BTC_DYNAMIC_BT_LEN_MAX_DEF; + pMac->btc.btcConfig.btcDynMaxLenWlan = BTC_DYNAMIC_WLAN_LEN_MAX_DEF; + pMac->btc.btcConfig.btcMaxScoBlockPerc = BTC_SCO_BLOCK_PERC_DEF; + pMac->btc.btcConfig.btcDhcpProtOnA2dp = BTC_DHCP_ON_A2DP_DEF; + pMac->btc.btcConfig.btcDhcpProtOnSco = BTC_DHCP_ON_SCO_DEF; + + pMac->btc.btcReady = VOS_FALSE; + pMac->btc.btcEventState = 0; + pMac->btc.btcHBActive = VOS_TRUE; + pMac->btc.btcScanCompromise = VOS_FALSE; + + for (i = 0; i < MWS_COEX_MAX_VICTIM_TABLE; i++) + { + pMac->btc.btcConfig.mwsCoexVictimWANFreq[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimWLANFreq[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimConfig[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimConfig2[i] = 0; + } + + for (i = 0; i < MWS_COEX_MAX_CONFIG; i++) + { + pMac->btc.btcConfig.mwsCoexConfig[i] = 0; + } + + pMac->btc.btcConfig.mwsCoexModemBackoff = 0; + pMac->btc.btcConfig.SARPowerBackoff = 0; + + vosStatus = vos_timer_init( &pMac->btc.restoreHBTimer, + VOS_TIMER_TYPE_SW, + btcRestoreHeartBeatMonitoringHandle, + (void*) hHal); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to init timer"); + return VOS_STATUS_E_FAILURE; + } + + if(!pMac->psOffloadEnabled) + { + if(!HAL_STATUS_SUCCESS(pmcRegisterDeviceStateUpdateInd(pMac, + btcPowerStateCB, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "btcOpen: Fail to register PMC callback"); + return VOS_STATUS_E_FAILURE; + } + } + else + { + tANI_U32 i; + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + if(!HAL_STATUS_SUCCESS(pmcOffloadRegisterDeviceStateUpdateInd(pMac, + i, btcPowerOffloadStateCB, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "btcOpen: Fail to register PMC callback"); + return VOS_STATUS_E_FAILURE; + } + } + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcClose + \brief API to exit the BTC Events Layer + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + VOS_STATUS_E_FAILURE success + VOS_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +VOS_STATUS btcClose (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + pMac->btc.btcReady = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_FALSE; + vos_timer_stop(&pMac->btc.restoreHBTimer); + vosStatus = vos_timer_destroy(&pMac->btc.restoreHBTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcClose: Fail to destroy timer"); + return VOS_STATUS_E_FAILURE; + } + + if(!pMac->psOffloadEnabled) + { + if(!HAL_STATUS_SUCCESS( + pmcDeregisterDeviceStateUpdateInd(pMac, btcPowerStateCB))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister pmcDeregisterDeviceStateUpdateInd()", + __func__, __LINE__); + } + } + else + { + tANI_U32 i; + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + if(!HAL_STATUS_SUCCESS(pmcOffloadDeregisterDeviceStateUpdateInd(pMac, + i, btcPowerOffloadStateCB))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "btcOpen: Fail to deregister PMC callback"); + return VOS_STATUS_E_FAILURE; + } + } + } + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn btcReady + \brief fn to inform BTC that eWNI_SME_SYS_READY_IND has been sent to PE. + This acts as a trigger to send a message to HAL to update the BTC + related conig to FW. Note that if HDD configures any power BTC + related stuff before this API is invoked, BTC will buffer all the + configutaion. + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + ---------------------------------------------------------------------------*/ +VOS_STATUS btcReady (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_U32_t cfgVal = 0; + v_U8_t i; + pMac->btc.btcReady = VOS_TRUE; + pMac->btc.btcUapsdOk = VOS_TRUE; + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + + // Read heartbeat threshold CFG and save it. + ccmCfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &cfgVal); + pMac->btc.btcHBCount = (v_U8_t)cfgVal; + if (btcSendCfgMsg(hHal, &(pMac->btc.btcConfig)) != VOS_STATUS_SUCCESS) + { + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS btcSendBTEvent(tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent) +{ + vos_msg_t msg; + tpSmeBtEvent ptrSmeBtEvent = NULL; + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + if(pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && + pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid link type %d for Sync Connection. BT event will be dropped ", + __func__, pBtEvent->uEventParam.btSyncConnection.linkType); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + if((pBtEvent->uEventParam.btSyncConnection.status == BT_CONN_STATUS_SUCCESS) && + ((pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) || + (pBtEvent->uEventParam.btSyncConnection.connectionHandle == BT_INVALID_CONN_HANDLE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid connection handle %d or link type %d for Sync Connection. BT event will be dropped ", + __func__, + pBtEvent->uEventParam.btSyncConnection.connectionHandle, + pBtEvent->uEventParam.btSyncConnection.linkType); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_MODE_CHANGED: + if(pBtEvent->uEventParam.btAclModeChange.mode >= BT_ACL_MODE_MAX) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid mode %d for ACL Connection. BT event will be dropped ", + __func__, + pBtEvent->uEventParam.btAclModeChange.mode); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + pMac->btc.btcEventState = 0; + break; + default: + break; + } + ptrSmeBtEvent = vos_mem_malloc(sizeof(tSmeBtEvent)); + if (NULL == ptrSmeBtEvent) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for BT event", __func__); + return VOS_STATUS_E_FAILURE; + } + btcLogEvent(pMac, pBtEvent); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + btcDiagEventLog(pMac, pBtEvent); +#endif + vos_mem_copy(ptrSmeBtEvent, pBtEvent, sizeof(tSmeBtEvent)); + msg.type = WDA_SIGNAL_BT_EVENT; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtEvent; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post WDA_SIGNAL_BT_EVENT message to WDA", __func__); + vos_mem_free( ptrSmeBtEvent ); + return VOS_STATUS_E_FAILURE; + } + // After successfully posting the message, check if heart beat + // monitoring needs to be turned off + (void)btcCheckHeartBeatMonitoring(pMac, pBtEvent); + //Check whether BTC and UAPSD can co-exist + btcUapsdCheck( pMac, pBtEvent ); + return VOS_STATUS_SUCCESS; + } + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/* --------------------------------------------------------------------------- + \fn btcSignalBTEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE – BT Event not passed to HAL. This can happen + if driver has not yet been initialized or if BTC + Events Layer has been disabled. + VOS_STATUS_SUCCESS – BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + VOS_STATUS vosStatus; + if( NULL == pBtEvent ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Null pointer for SME BT Event", __func__); + return VOS_STATUS_E_FAILURE; + } + if(( BTC_WLAN_ONLY == pMac->btc.btcConfig.btcExecutionMode ) || + ( BTC_PTA_ONLY == pMac->btc.btcConfig.btcExecutionMode )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "BTC execution mode not set to BTC_SMART_COEXISTENCE. BT event will be dropped", __func__); + return VOS_STATUS_E_FAILURE; + } + if( pBtEvent->btEventType < 0 || pBtEvent->btEventType >= BT_EVENT_TYPE_MAX ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid BT event %d being passed. BT event will be dropped", + __func__, pBtEvent->btEventType); + return VOS_STATUS_E_FAILURE; + } + //Check PMC state to make sure whether we need to defer + //If we already have deferred events, defer the new one as well, in case PMC is in transition state + if( pMac->btc.fReplayBTEvents || !PMC_IS_CHIP_ACCESSIBLE(pmcGetPmcState( pMac )) ) + { + //We need to defer the event + vosStatus = btcDeferEvent(pMac, pBtEvent); + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + pMac->btc.fReplayBTEvents = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + else + { + return vosStatus; + } + } + btcSendBTEvent(pMac, pBtEvent); + return VOS_STATUS_SUCCESS; +} +#endif +/* --------------------------------------------------------------------------- + \fn btcCheckHeartBeatMonitoring + \brief API to check whether heartbeat monitoring is required to be disabled + for specific BT start events which takes significant time to complete + during which WLAN misses beacons. To avoid WLAN-MAC from disconnecting + for the not enough beacons received we stop the heartbeat timer during + this start BT event till the stop of that BT event. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + VOS_STATUS vosStatus; + switch(pBtEvent->btEventType) + { + // Start events which requires heartbeat monitoring be disabled. + case BT_EVENT_INQUIRY_STARTED: + pMac->btc.btcEventState |= BT_INQUIRY_STARTED; + break; + case BT_EVENT_PAGE_STARTED: + pMac->btc.btcEventState |= BT_PAGE_STARTED; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + pMac->btc.btcEventState |= BT_CREATE_ACL_CONNECTION_STARTED; + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + pMac->btc.btcEventState |= BT_CREATE_SYNC_CONNECTION_STARTED; + break; + // Stop/done events which indicates heartbeat monitoring can be enabled + case BT_EVENT_INQUIRY_STOPPED: + pMac->btc.btcEventState &= ~(BT_INQUIRY_STARTED); + break; + case BT_EVENT_PAGE_STOPPED: + pMac->btc.btcEventState &= ~(BT_PAGE_STARTED); + break; + case BT_EVENT_ACL_CONNECTION_COMPLETE: + pMac->btc.btcEventState &= ~(BT_CREATE_ACL_CONNECTION_STARTED); + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + pMac->btc.btcEventState &= ~(BT_CREATE_SYNC_CONNECTION_STARTED); + break; + default: + // Ignore other events + return VOS_STATUS_SUCCESS; + } + // Check if any of the BT start events are active + if (pMac->btc.btcEventState) { + if (pMac->btc.btcHBActive) { + // set heartbeat threshold CFG to zero + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_FALSE; + } + // Deactivate and active the restore HB timer + vos_timer_stop( &pMac->btc.restoreHBTimer); + vosStatus= vos_timer_start( &pMac->btc.restoreHBTimer, BT_MAX_EVENT_DONE_TIMEOUT ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to start timer"); + return VOS_STATUS_E_FAILURE; + } + } else { + // Restore CFG back to the original value only if it was disabled + if (!pMac->btc.btcHBActive) { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + // Deactivate the timer + vosStatus = vos_timer_stop( &pMac->btc.restoreHBTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to stop timer"); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcRestoreHeartBeatMonitoringHandle + \brief Timer handler to handlet the timeout condition when a specific BT + stop event does not come back, in which case to restore back the + heartbeat timer. + \param hHal - The handle returned by macOpen. + \return VOID + ---------------------------------------------------------------------------*/ +void btcRestoreHeartBeatMonitoringHandle(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if( !pMac->btc.btcHBActive ) + { + tPmcState pmcState; + //Check PMC state to make sure whether we need to defer + pmcState = pmcGetPmcState( pMac ); + if( PMC_IS_CHIP_ACCESSIBLE(pmcState) ) + { + // Restore CFG back to the original value + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BT event timeout, restoring back HeartBeat timer"); + } + else + { + //defer it + pMac->btc.btcEventReplay.fRestoreHBMonitor = VOS_TRUE; + } + } +} + + +/* --------------------------------------------------------------------------- + \fn btcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + //Save a copy in the global BTC config + vos_mem_copy(&(pMac->btc.btcConfig), pSmeBtcConfig, sizeof(tSmeBtcConfig)); + //Send the config down only if SME_HddReady has been invoked. If not ready, + //BTC config will plumbed down when btcReady is eventually invoked. + if(pMac->btc.btcReady) + { + if(VOS_STATUS_SUCCESS != btcSendCfgMsg(hHal, pSmeBtcConfig)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "Failure to send BTC config down"); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcPostBtcCfgMsg + \brief Private API to post BTC config message to HAL + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpSmeBtcConfig ptrSmeBtcConfig = NULL; + vos_msg_t msg; + if( NULL == pSmeBtcConfig ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Null pointer for BTC Config"); + return VOS_STATUS_E_FAILURE; + } + if( pSmeBtcConfig->btcExecutionMode >= BT_EXEC_MODE_MAX ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Invalid BT execution mode %d being set", + pSmeBtcConfig->btcExecutionMode); + return VOS_STATUS_E_FAILURE; + } + ptrSmeBtcConfig = vos_mem_malloc(sizeof(tSmeBtcConfig)); + if (NULL == ptrSmeBtcConfig) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Not able to allocate memory for SME BTC Config"); + return VOS_STATUS_E_FAILURE; + } + vos_mem_copy(ptrSmeBtcConfig, pSmeBtcConfig, sizeof(tSmeBtcConfig)); + msg.type = WDA_BTC_SET_CFG; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtcConfig; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Not able to post WDA_BTC_SET_CFG message to WDA"); + vos_mem_free( ptrSmeBtcConfig ); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if( NULL == pSmeBtcConfig ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcGetConfig: " + "Null pointer for BTC Config"); + return VOS_STATUS_E_FAILURE; + } + vos_mem_copy(pSmeBtcConfig, &(pMac->btc.btcConfig), sizeof(tSmeBtcConfig)); + return VOS_STATUS_SUCCESS; +} +/* + btcFindAclEventHist find a suited ACL event buffer + Param: bdAddr - NULL meaning not care. + pointer to caller alocated buffer containing the BD address to find a match + handle - BT_INVALID_CONN_HANDLE == not care + otherwise, a handle to match + NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither + bdAddr nor handle is valid, return the next free slot. +*/ +static tpSmeBtAclEventHist btcFindAclEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle ) +{ + int i, j; + tpSmeBtAclEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + for( i = 0; (i < BT_MAX_ACL_SUPPORT) && (NULL == pRet); i++ ) + { + if( NULL != bdAddr ) + { + //try to match addr + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( vos_mem_compare(pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].bdAddr, + bdAddr, 6) ) + { + //found it + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + } + } + else if( BT_INVALID_CONN_HANDLE != handle ) + { + //try to match handle + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].connectionHandle == + handle ) + { + //found it + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + } + } + else if( 0 == pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + return (pRet); +} + +/* + btcFindSyncEventHist find a suited SYNC event buffer + Param: bdAddr - NULL meaning not care. + pointer to caller alocated buffer containing the BD address to find a match + handle - BT_INVALID_CONN_HANDLE == not care + otherwise, a handle to match + NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither + bdAddr nor handle is valid, return the next free slot. +*/ +static tpSmeBtSyncEventHist btcFindSyncEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle ) +{ + int i, j; + tpSmeBtSyncEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + for( i = 0; (i < BT_MAX_SCO_SUPPORT) && (NULL == pRet); i++ ) + { + if( NULL != bdAddr ) + { + //try to match addr + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( vos_mem_compare(pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].bdAddr, + bdAddr, 6) ) + { + //found it + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + } + } + else if( BT_INVALID_CONN_HANDLE != handle ) + { + //try to match handle + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].connectionHandle == + handle ) + { + //found it + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + } + } + else if( !pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + return (pRet); +} + +/* + btcFindDisconnEventHist find a slot for the deferred disconnect event + If handle is invlid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +static tpSmeBtDisconnectEventHist btcFindDisconnEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtDisconnectEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++) + { + if( pReplay->btcEventHist.btDisconnectEvent[i].fValid && + (handle == pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btDisconnectEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btDisconnectEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btDisconnectEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + btcFindModeChangeEventHist find a slot for the deferred mopde change event + If handle is invalid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +tpSmeBtAclModeChangeEventHist btcFindModeChangeEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtAclModeChangeEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_ACL_SUPPORT; i++) + { + if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid && + (handle == pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_ACL_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btAclModeChangeEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + btcFindSyncUpdateEventHist find a slot for the deferred SYNC_UPDATE event + If handle is invalid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +tpSmeBtSyncUpdateHist btcFindSyncUpdateEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtSyncUpdateHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid && + (handle == pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btSyncUpdateEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + Call must validate pAclEventHist +*/ +static void btcReleaseAclEventHist( tpAniSirGlobal pMac, tpSmeBtAclEventHist pAclEventHist ) +{ + vos_mem_zero( pAclEventHist, sizeof(tSmeBtAclEventHist) ); +} + +/* + Call must validate pSyncEventHist +*/ +static void btcReleaseSyncEventHist( tpAniSirGlobal pMac, tpSmeBtSyncEventHist pSyncEventHist ) +{ + vos_mem_zero( pSyncEventHist, sizeof(tSmeBtSyncEventHist) ); +} + +/*To defer a ACL creation event + We only support one ACL per BD address. + If the last cached event another ACL create event, replace that event with the new event + If a completion event with success status code, and the new ACL creation + on same address, defer a new disconnect event(fake one), then cache this ACL creation event. + Otherwise, save this create event. +*/ +static VOS_STATUS btcDeferAclCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + tSmeBtAclConnectionParam *pAclEvent = NULL; + do + { + //Find a match + pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if( NULL == pAclEventHist ) + { + //No cached ACL event on this address + //Find a free slot and save it + pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + if( NULL != pAclEventHist ) + { + vos_mem_copy(&pAclEventHist->btAclConnection[0], &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->btEventType[0] = BT_EVENT_CREATE_ACL_CONNECTION; + pAclEventHist->bNextEventIdx = 1; + } + else + { + smsLog(pMac, LOGE, FL(" failed to find ACL event slot")); + status = VOS_STATUS_E_RESOURCES; + } + //done + break; + } + else + { + //There is history on this BD address + if ((pAclEventHist->bNextEventIdx <= 0) || + (pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED)) + { + VOS_ASSERT(0); + status = VOS_STATUS_E_FAILURE; + break; + } + pAclEvent = &pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx - 1]; + if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1]) + { + //The last cached event is creation, replace it with the new one + if (pAclEvent) + { + vos_mem_copy(pAclEvent, + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + } + //done + break; + } + else if(BT_EVENT_ACL_CONNECTION_COMPLETE == + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1]) + { + //The last cached event is completion, check the status. + if(BT_CONN_STATUS_SUCCESS == pAclEvent->status) + { + tSmeBtEvent btEvent; + //The last event we have is success completion event. + //Should not get a creation event before creation. + smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pAclEvent->connectionHandle); + //Fake a disconnect event + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + btEvent.uEventParam.btDisconnect.connectionHandle = pAclEvent->connectionHandle; + btcDeferDisconnEvent(pMac, &btEvent); + } + } + //Need to save the new event + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_CREATE_ACL_CONNECTION; + vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx], + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + VOS_ASSERT(0); + } + } + }while(0); + return status; +} + +/*Defer a ACL completion event + If there is cached event on this BD address, check completion status. + If status is fail and last cached event is creation, remove the creation event and drop + this completion event. Otherwise, cache this completion event as the latest one. +*/ +static VOS_STATUS btcDeferAclComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + do + { + //Find a match + pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if(pAclEventHist) + { + if (pAclEventHist->bNextEventIdx <= 0) + { + VOS_ASSERT(pAclEventHist->bNextEventIdx >0); + return VOS_STATUS_E_EMPTY; + } + //Found one + if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btAclConnection.status) + { + //If completion fails, and the last one is creation, remove the creation event + if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]) + { + vos_mem_zero(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx-1], + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx--; + //Done with this event + break; + } + else + { + smsLog(pMac, LOGE, FL(" ACL completion fail but last event(%d) not creation"), + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]); + } + } + } + if( NULL == pAclEventHist ) + { + pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + } + if(pAclEventHist) + { + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + //Save this event + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_ACL_CONNECTION_COMPLETE; + vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx], + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + VOS_ASSERT(0); + } + } + else + { + smsLog(pMac, LOGE, FL(" cannot find match for failed " + "BT_EVENT_ACL_CONNECTION_COMPLETE of bdAddr " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pEvent->uEventParam.btAclConnection.bdAddr)); + status = VOS_STATUS_E_EMPTY; + } + }while(0); + return (status); +} + +/*To defer a SYNC creation event + If the last cached event is another SYNC create event, replace + that event with the new event. + If there is a completion event with success status code, cache a new + disconnect event(fake) first, then cache this SYNC creation event. + Otherwise, cache this create event. +*/ +static VOS_STATUS btcDeferSyncCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + tSmeBtSyncConnectionParam *pSyncEvent = NULL; + do + { + //Find a match + pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if( NULL == pSyncEventHist ) + { + //No cached ACL event on this address + //Find a free slot and save it + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + if( NULL != pSyncEventHist ) + { + vos_mem_copy(&pSyncEventHist->btSyncConnection[0], &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->btEventType[0] = BT_EVENT_CREATE_SYNC_CONNECTION; + pSyncEventHist->bNextEventIdx = 1; + } + else + { + smsLog(pMac, LOGE, FL(" failed to find SYNC event slot")); + status = VOS_STATUS_E_RESOURCES; + } + //done + break; + } + else + { + //There is history on this BD address + if ((pSyncEventHist->bNextEventIdx <= 0) || + (pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED)) + { + VOS_ASSERT(0); + status = VOS_STATUS_E_FAILURE; + return status; + } + pSyncEvent = &pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx - 1]; + if(BT_EVENT_CREATE_SYNC_CONNECTION == + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1]) + { + //The last cached event is creation, replace it with the new one + if(pSyncEvent) + { + vos_mem_copy(pSyncEvent, + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + } + //done + break; + } + else if(BT_EVENT_SYNC_CONNECTION_COMPLETE == + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1]) + { + //The last cached event is completion, check the status. + if(BT_CONN_STATUS_SUCCESS == pSyncEvent->status) + { + tSmeBtEvent btEvent; + //The last event we have is success completion event. + //Should not get a creation event before creation. + smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pSyncEvent->connectionHandle); + //Fake a disconnect event + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + btEvent.uEventParam.btDisconnect.connectionHandle = pSyncEvent->connectionHandle; + btcDeferDisconnEvent(pMac, &btEvent); + } + } + //Need to save the new event + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_CREATE_SYNC_CONNECTION; + vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx], + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + } + } + }while(0); + return status; +} + +/*Defer a SYNC completion event + If there is cached event on this BD address, check completion status. + If status is fail and last cached event is creation, remove te creation event and drop + this completion event. + Otherwise, cache this completion event as the latest one. +*/ +static VOS_STATUS btcDeferSyncComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + do + { + //Find a match + pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if(pSyncEventHist) + { + if (pSyncEventHist->bNextEventIdx <= 0) + { + VOS_ASSERT(pSyncEventHist->bNextEventIdx >0); + return VOS_STATUS_E_EMPTY; + } + //Found one + if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btSyncConnection.status) + { + //If completion fails, and the last one is creation, remove the creation event + if(BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]) + { + vos_mem_zero(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx-1], + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx--; + //Done with this event + break; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC completion fail but last event(%d) not creation"), + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]); + } + } + } + if(NULL == pSyncEventHist) + { + //In case we don't defer the creation event + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + } + if(pSyncEventHist) + { + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + //Save this event + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_SYNC_CONNECTION_COMPLETE; + vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx], + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + } + } + else + { + smsLog(pMac, LOGE, FL(" cannot find match for " + "BT_EVENT_SYNC_CONNECTION_COMPLETE of bdAddr " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pEvent->uEventParam.btSyncConnection.bdAddr)); + status = VOS_STATUS_E_EMPTY; + } + }while(0); + return (status); +} + +//return VOS_STATUS_E_EXISTS if the event handle cannot be found +//VOS_STATUS_SUCCESS if the event is processed +//Other error status meaning it cannot continue due to other errors +/* + Defer a disconnect event for ACL + Check if any history on this event handle. + If both ACL_CREATION and ACL_COMPLETION is cached, remove both those events and drop + this disconnect event. + Otherwise save disconnect event in this ACL's bin. + If not ACL match on this handle, not to do anything. + Either way, remove any cached MODE_CHANGE event matches this disconnect event's handle. +*/ +static VOS_STATUS btcDeferDisconnectEventForACL( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + tpSmeBtAclModeChangeEventHist pModeChangeEventHist; + v_BOOL_t fDone = VOS_FALSE; + int i; + pAclEventHist = btcFindAclEventHist( pMac, NULL, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if(pAclEventHist) + { + if( pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + smsLog(pMac, LOGE, FL(" ACL event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_ACL_DEFERRED"), pAclEventHist->bNextEventIdx); + pAclEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_ACL_DEFERRED; + } + //Looking backwords + for(i = pAclEventHist->bNextEventIdx - 1; i >= 0; i--) + { + if( BT_EVENT_ACL_CONNECTION_COMPLETE == pAclEventHist->btEventType[i] ) + { + //make sure we can cancel the link + if( (i > 0) && (BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[i - 1]) ) + { + fDone = VOS_TRUE; + if(i == 1) + { + //All events can be wiped off + btcReleaseAclEventHist(pMac, pAclEventHist); + break; + } + //we have both ACL creation and completion, wipe out all of them + pAclEventHist->bNextEventIdx = (tANI_U8)(i - 1); + vos_mem_zero(&pAclEventHist->btAclConnection[i-1], sizeof(tSmeBtAclConnectionParam)); + vos_mem_zero(&pAclEventHist->btAclConnection[i], sizeof(tSmeBtAclConnectionParam)); + break; + } + } + }//for loop + if(!fDone) + { + //Save this disconnect event + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = + BT_EVENT_DISCONNECTION_COMPLETE; + pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx].connectionHandle = + pEvent->uEventParam.btDisconnect.connectionHandle; + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + status = VOS_STATUS_E_FAILURE; + } + } + } + else + { + status = VOS_STATUS_E_EXISTS; + } + //Wipe out the related mode change event if it is there + pModeChangeEventHist = btcFindModeChangeEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pModeChangeEventHist && pModeChangeEventHist->fValid ) + { + pModeChangeEventHist->fValid = VOS_FALSE; + } + return status; +} + +//This function works the same as btcDeferDisconnectEventForACL except it hanldes SYNC events +//return VOS_STATUS_E_EXISTS if the event handle cannot be found +//VOS_STATUS_SUCCESS if the event is processed +//Other error status meaning it cannot continue due to other errors +/* + Defer a disconnect event for SYNC + Check if any SYNC history on this event handle. + If yes and if both SYNC_CREATION and SYNC_COMPLETION is cached, remove both those events and drop + this disconnect event. + Otherwise save disconnect event in this SYNC's bin. + If no match found, not to save this event here. + Either way, remove any cached SYNC_UPDATE event matches this disconnect event's handle. +*/ +static VOS_STATUS btcDeferDisconnectEventForSync( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + tpSmeBtSyncUpdateHist pSyncUpdateHist; + v_BOOL_t fDone = VOS_FALSE; + int i; + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if(pSyncEventHist) + { + if( pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + smsLog(pMac, LOGE, FL(" SYNC event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_SCO_DEFERRED"), pSyncEventHist->bNextEventIdx); + pSyncEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_SCO_DEFERRED; + } + //Looking backwords + for(i = pSyncEventHist->bNextEventIdx - 1; i >= 0; i--) + { + //if a mode change event exists, drop it + if( BT_EVENT_SYNC_CONNECTION_COMPLETE == pSyncEventHist->btEventType[i] ) + { + //make sure we can cancel the link + if( (i > 0) && (BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[i - 1]) ) + { + fDone = VOS_TRUE; + if(i == 1) + { + //All events can be wiped off + btcReleaseSyncEventHist(pMac, pSyncEventHist); + break; + } + //we have both ACL creation and completion, wipe out all of them + pSyncEventHist->bNextEventIdx = (tANI_U8)(i - 1); + vos_mem_zero(&pSyncEventHist->btSyncConnection[i-1], sizeof(tSmeBtSyncConnectionParam)); + vos_mem_zero(&pSyncEventHist->btSyncConnection[i], sizeof(tSmeBtSyncConnectionParam)); + break; + } + } + }//for loop + if(!fDone) + { + //Save this disconnect event + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = + BT_EVENT_DISCONNECTION_COMPLETE; + pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx].connectionHandle = + pEvent->uEventParam.btDisconnect.connectionHandle; + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + status = VOS_STATUS_E_FAILURE; + } + } + } + else + { + status = VOS_STATUS_E_EXISTS; + } + //Wipe out the related mode change event if it is there + pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pSyncUpdateHist && pSyncUpdateHist->fValid ) + { + pSyncUpdateHist->fValid = VOS_FALSE; + } + return status; +} + +/* + Defer a disconnect event. + Try to defer it as part of the ACL event first. + If no match is found, try SYNC. + If still no match found, defer it at DISCONNECT event bin. +*/ +static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtDisconnectEventHist pDisconnEventHist; + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + return (VOS_STATUS_E_INVAL); + } + //Check ACL first + status = btcDeferDisconnectEventForACL(pMac, pEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + status = btcDeferDisconnectEventForSync(pMac, pEvent); + } + if( !VOS_IS_STATUS_SUCCESS(status) ) + { + //Save the disconnect event + pDisconnEventHist = btcFindDisconnEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pDisconnEventHist ) + { + pDisconnEventHist->fValid = VOS_TRUE; + vos_mem_copy( &pDisconnEventHist->btDisconnect, &pEvent->uEventParam.btDisconnect, + sizeof(tSmeBtDisconnectParam) ); + status = VOS_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_DISCONNECTION_COMPLETE of handle (%d)"), + pEvent->uEventParam.btDisconnect.connectionHandle); + status = VOS_STATUS_E_EMPTY; + } + } + return (status); +} + +/* + btcDeferEvent save the event for possible replay when chip can be accessed + This function is called only when in IMPS/Standby state +*/ +static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncUpdateHist pSyncUpdateHist; + tpSmeBtAclModeChangeEventHist pModeChangeEventHist; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + switch(pEvent->btEventType) + { + case BT_EVENT_DEVICE_SWITCHED_ON: + //Clear all events first + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + pReplay->fBTSwitchOn = VOS_TRUE; + pReplay->fBTSwitchOff = VOS_FALSE; + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + //Clear all events first + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + pReplay->fBTSwitchOff = VOS_TRUE; + pReplay->fBTSwitchOn = VOS_FALSE; + break; + case BT_EVENT_INQUIRY_STARTED: + pReplay->btcEventHist.nInquiryEvent++; + break; + case BT_EVENT_INQUIRY_STOPPED: + pReplay->btcEventHist.nInquiryEvent--; + break; + case BT_EVENT_PAGE_STARTED: + pReplay->btcEventHist.nPageEvent++; + break; + case BT_EVENT_PAGE_STOPPED: + pReplay->btcEventHist.nPageEvent--; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + status = btcDeferAclCreate(pMac, pEvent); + break; + case BT_EVENT_ACL_CONNECTION_COMPLETE: + status = btcDeferAclComplete( pMac, pEvent ); + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + status = btcDeferSyncCreate(pMac, pEvent); + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + status = btcDeferSyncComplete( pMac, pEvent ); + break; + case BT_EVENT_SYNC_CONNECTION_UPDATED: + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + status = VOS_STATUS_E_INVAL; + break; + } + //Find a match on handle. If not found, get a free slot. + pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac, + pEvent->uEventParam.btSyncConnection.connectionHandle ); + if(pSyncUpdateHist) + { + pSyncUpdateHist->fValid = VOS_TRUE; + vos_mem_copy(&pSyncUpdateHist->btSyncConnection, &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_UPDATED of handle (%d)"), + pEvent->uEventParam.btSyncConnection.connectionHandle ); + status = VOS_STATUS_E_EMPTY; + } + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + status = btcDeferDisconnEvent( pMac, pEvent ); + break; + case BT_EVENT_MODE_CHANGED: + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + status = VOS_STATUS_E_INVAL; + break; + } + //Find a match on handle, If not found, return a free slot + pModeChangeEventHist = btcFindModeChangeEventHist( pMac, + pEvent->uEventParam.btAclModeChange.connectionHandle ); + if(pModeChangeEventHist) + { + pModeChangeEventHist->fValid = VOS_TRUE; + vos_mem_copy( &pModeChangeEventHist->btAclModeChange, + &pEvent->uEventParam.btAclModeChange, sizeof(tSmeBtAclModeChangeParam) ); + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_MODE_CHANGED of handle (%d)"), + pEvent->uEventParam.btAclModeChange.connectionHandle); + status = VOS_STATUS_E_EMPTY; + } + break; + case BT_EVENT_A2DP_STREAM_START: + pReplay->btcEventHist.fA2DPStarted = VOS_TRUE; + pReplay->btcEventHist.fA2DPStopped = VOS_FALSE; + break; + case BT_EVENT_A2DP_STREAM_STOP: + pReplay->btcEventHist.fA2DPStopped = VOS_TRUE; + pReplay->btcEventHist.fA2DPStarted = VOS_FALSE; + break; + default: + smsLog( pMac, LOGE, FL(" event (%d) is not deferred"), pEvent->btEventType ); + status = VOS_STATUS_E_NOSUPPORT; + break; + } + return (status); +} + +/* + Replay all cached events in the following order + 1. If BT_SWITCH_OFF event, send it. + 2. Send INQUIRY event (START or STOP),if available + 3. Send PAGE event (START or STOP), if available + 4. Send DISCONNECT events, these DISCONNECT events are not tied to + any ACL/SYNC event that we have cached + 5. Send ACL events (possible events, CREATION, COMPLETION, DISCONNECT) + 6. Send MODE_CHANGE events, if available + 7. Send A2DP event(START or STOP), if available + 8. Send SYNC events (possible events, CREATION, COMPLETION, DISCONNECT) + 9. Send SYNC_UPDATE events, if available +*/ +static void btcReplayEvents( tpAniSirGlobal pMac ) +{ + int i, j; + tSmeBtEvent btEvent; + tpSmeBtAclEventHist pAclHist; + tpSmeBtSyncEventHist pSyncHist; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + //Always turn on HB monitor first. + //It is independent of BT events even though BT event causes this + if( pReplay->fRestoreHBMonitor ) + { + pReplay->fRestoreHBMonitor = VOS_FALSE; + //Only do it when needed + if( !pMac->btc.btcHBActive ) + { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + } + if( pMac->btc.fReplayBTEvents ) + { + /*Set the flag to false here so btcSignalBTEvent won't defer any further. + This works because SME has it global lock*/ + pMac->btc.fReplayBTEvents = VOS_FALSE; + if( pReplay->fBTSwitchOff ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_OFF; + btcSendBTEvent( pMac, &btEvent ); + pReplay->fBTSwitchOff = VOS_FALSE; + } + else if( pReplay->fBTSwitchOn ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_ON; + btcSendBTEvent( pMac, &btEvent ); + pReplay->fBTSwitchOn = VOS_FALSE; + } + //Do inquire first + if( pReplay->btcEventHist.nInquiryEvent > 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_INQUIRY_STARTED; + i = pReplay->btcEventHist.nInquiryEvent; + while(i--) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + else if( pReplay->btcEventHist.nInquiryEvent < 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_INQUIRY_STOPPED; + i = pReplay->btcEventHist.nInquiryEvent; + while(i++) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + //Page + if( pReplay->btcEventHist.nPageEvent > 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_PAGE_STARTED; + i = pReplay->btcEventHist.nPageEvent; + while(i--) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + else if( pReplay->btcEventHist.nPageEvent < 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_PAGE_STOPPED; + i = pReplay->btcEventHist.nPageEvent; + while(i++) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + //Replay non-completion disconnect events first + //Disconnect + for( i = 0; i < BT_MAX_DISCONN_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btDisconnectEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + vos_mem_copy( &btEvent.uEventParam.btDisconnect, + &pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect, sizeof(tSmeBtDisconnectParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //ACL + for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + pAclHist = &pReplay->btcEventHist.btAclConnectionEvent[i]; + //Replay all ACL events for this BD address/handle + for(j = 0; j < pAclHist->bNextEventIdx; j++) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = pAclHist->btEventType[j]; + if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType) + { + //It must be CREATE or CONNECTION_COMPLETE + vos_mem_copy( &btEvent.uEventParam.btAclConnection, + &pAclHist->btAclConnection[j], sizeof(tSmeBtAclConnectionParam) ); + } + else + { + btEvent.uEventParam.btDisconnect.connectionHandle = pAclHist->btAclConnection[j].connectionHandle; + } + btcSendBTEvent( pMac, &btEvent ); + } + } + } + //Mode change + for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_MODE_CHANGED; + vos_mem_copy( &btEvent.uEventParam.btAclModeChange, + &pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange, sizeof(tSmeBtAclModeChangeParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //A2DP + if( pReplay->btcEventHist.fA2DPStarted ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_A2DP_STREAM_START; + btcSendBTEvent( pMac, &btEvent ); + } + else if( pReplay->btcEventHist.fA2DPStopped ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_A2DP_STREAM_STOP; + btcSendBTEvent( pMac, &btEvent ); + } + //SCO + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + pSyncHist = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + //Replay all SYNC events for this BD address/handle + for(j = 0; j < pSyncHist->bNextEventIdx; j++) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = pSyncHist->btEventType[j]; + if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType) + { + //Must be CREATION or CONNECTION_COMPLETE + vos_mem_copy( &btEvent.uEventParam.btSyncConnection, + &pSyncHist->btSyncConnection[j], sizeof(tSmeBtSyncConnectionParam) ); + } + else + { + btEvent.uEventParam.btDisconnect.connectionHandle = pSyncHist->btSyncConnection[j].connectionHandle; + } + btcSendBTEvent( pMac, &btEvent ); + } + } + } + //SYNC update + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_SYNC_CONNECTION_UPDATED; + vos_mem_copy( &btEvent.uEventParam.btSyncConnection, + &pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection, + sizeof(tSmeBtSyncConnectionParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //Clear all events + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + } +} + +static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(pContext); + if( FULL_POWER == pmcState ) + { + btcReplayEvents( pMac ); + } +} + +static void btcPowerOffloadStateCB(v_PVOID_t pContext, tANI_U32 sessionId, + tPmcState pmcState ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(pContext); + if(FULL_POWER == pmcState) + { + btcReplayEvents(pMac); + } +} + + +/* --------------------------------------------------------------------------- + \fn btcLogEvent + \brief API to log the the current Bluetooth event + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtEvent. Caller owns the memory and is responsible + for freeing it. + \return None + ---------------------------------------------------------------------------*/ +static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + v_U8_t bdAddrRev[6]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Bluetooth Event %d received", __func__, pBtEvent->btEventType); + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "SCO Connection: " + "connectionHandle = %d status = %d linkType %d " + "scoInterval %d scoWindow %d retransmisisonWindow = %d ", + pBtEvent->uEventParam.btSyncConnection.connectionHandle, + pBtEvent->uEventParam.btSyncConnection.status, + pBtEvent->uEventParam.btSyncConnection.linkType, + pBtEvent->uEventParam.btSyncConnection.scoInterval, + pBtEvent->uEventParam.btSyncConnection.scoWindow, + pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow); + + bdAddrRev[0] = pBtEvent->uEventParam.btSyncConnection.bdAddr[5]; + bdAddrRev[1] = pBtEvent->uEventParam.btSyncConnection.bdAddr[4]; + bdAddrRev[2] = pBtEvent->uEventParam.btSyncConnection.bdAddr[3]; + bdAddrRev[3] = pBtEvent->uEventParam.btSyncConnection.bdAddr[2]; + bdAddrRev[4] = pBtEvent->uEventParam.btSyncConnection.bdAddr[1]; + bdAddrRev[5] = pBtEvent->uEventParam.btSyncConnection.bdAddr[0]; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(bdAddrRev)); + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Connection: " + "connectionHandle = %d status = %d ", + pBtEvent->uEventParam.btAclConnection.connectionHandle, + pBtEvent->uEventParam.btAclConnection.status); + + bdAddrRev[0] = pBtEvent->uEventParam.btAclConnection.bdAddr[5]; + bdAddrRev[1] = pBtEvent->uEventParam.btAclConnection.bdAddr[4]; + bdAddrRev[2] = pBtEvent->uEventParam.btAclConnection.bdAddr[3]; + bdAddrRev[3] = pBtEvent->uEventParam.btAclConnection.bdAddr[2]; + bdAddrRev[4] = pBtEvent->uEventParam.btAclConnection.bdAddr[1]; + bdAddrRev[5] = pBtEvent->uEventParam.btAclConnection.bdAddr[0]; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(bdAddrRev)); + break; + case BT_EVENT_MODE_CHANGED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Mode change : " + "connectionHandle %d mode %d ", + pBtEvent->uEventParam.btAclModeChange.connectionHandle, + pBtEvent->uEventParam.btAclModeChange.mode); + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Disconnect Event : " + "connectionHandle %d ", pBtEvent->uEventParam.btAclModeChange.connectionHandle); + break; + default: + break; + } + } + +/* + Caller can check whether BTC's current event allows UAPSD. This doesn't affect + BMPS. + return: VOS_TRUE -- BTC is ready for UAPSD + VOS_FALSE -- certain BT event is active, cannot enter UAPSD +*/ +v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return( pMac->btc.btcUapsdOk ); +} + +/* + Base on the BT event, this function sets the flag on whether to allow UAPSD + At this time, we are only interested in SCO and A2DP. + A2DP tracking is through BT_EVENT_A2DP_STREAM_START and BT_EVENT_A2DP_STREAM_STOP + SCO is through BT_EVENT_SYNC_CONNECTION_COMPLETE and BT_EVENT_DISCONNECTION_COMPLETE + BT_EVENT_DEVICE_SWITCHED_OFF overwrites them all +*/ +void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent ) +{ + v_U8_t i; + v_BOOL_t fLastUapsdState = pMac->btc.btcUapsdOk, fMoreSCO = VOS_FALSE; + switch( pBtEvent->btEventType ) + { + case BT_EVENT_DISCONNECTION_COMPLETE: + if( (VOS_FALSE == pMac->btc.btcUapsdOk) && + BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btDisconnect.connectionHandle ) + { + //Check whether all SCO connections are gone + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( (BT_INVALID_CONN_HANDLE != pMac->btc.btcScoHandles[i]) && + (pMac->btc.btcScoHandles[i] != pBtEvent->uEventParam.btDisconnect.connectionHandle) ) + { + //We still have outstanding SCO connection + fMoreSCO = VOS_TRUE; + } + else if( pMac->btc.btcScoHandles[i] == pBtEvent->uEventParam.btDisconnect.connectionHandle ) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + } + if( !fMoreSCO && !pMac->btc.fA2DPUp ) + { + //All SCO is disconnected + smsLog( pMac, LOGE, "BT event (DISCONNECTION) happens, UAPSD-allowed flag (%d) change to TRUE", + pMac->btc.btcUapsdOk ); + pMac->btc.btcUapsdOk = VOS_TRUE; + } + } + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + smsLog( pMac, LOGE, "BT event (DEVICE_OFF) happens, UAPSD-allowed flag (%d) change to TRUE", + pMac->btc.btcUapsdOk ); + //Clean up SCO + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + pMac->btc.fA2DPUp = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_TRUE; + break; + case BT_EVENT_A2DP_STREAM_STOP: + smsLog( pMac, LOGE, "BT event (A2DP_STREAM_STOP) happens, UAPSD-allowed flag (%d)", + pMac->btc.btcUapsdOk ); + pMac->btc.fA2DPUp = VOS_FALSE; + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + if( BT_MAX_SCO_SUPPORT == i ) + { + pMac->btc.fA2DPTrafStop = VOS_TRUE; + smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_STOP: UAPSD-allowed flag is now %d", + pMac->btc.btcUapsdOk ); + } + break; + + case BT_EVENT_MODE_CHANGED: + smsLog( pMac, LOGE, "BT event (BT_EVENT_MODE_CHANGED) happens, Mode (%d) UAPSD-allowed flag (%d)", + pBtEvent->uEventParam.btAclModeChange.mode, pMac->btc.btcUapsdOk ); + if(pBtEvent->uEventParam.btAclModeChange.mode == BT_ACL_SNIFF) + { + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + if( BT_MAX_SCO_SUPPORT == i ) + { + if(VOS_TRUE == pMac->btc.fA2DPTrafStop) + { + pMac->btc.btcUapsdOk = VOS_TRUE; + pMac->btc.fA2DPTrafStop = VOS_FALSE; + } + smsLog( pMac, LOGE, "BT_EVENT_MODE_CHANGED with Mode:%d UAPSD-allowed flag is now %d", + pBtEvent->uEventParam.btAclModeChange.mode,pMac->btc.btcUapsdOk ); + } + } + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + { + pMac->btc.btcUapsdOk = VOS_FALSE; + smsLog( pMac, LOGE, "BT_EVENT_CREATE_SYNC_CONNECTION (%d) happens, UAPSD-allowed flag (%d) change to FALSE", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + } + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + //Make sure it is a success + if( BT_CONN_STATUS_FAIL != pBtEvent->uEventParam.btSyncConnection.status ) + { + //Save te handle for later use + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + VOS_ASSERT(BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle); + if( (BT_INVALID_CONN_HANDLE == pMac->btc.btcScoHandles[i]) && + (BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle)) + { + pMac->btc.btcScoHandles[i] = pBtEvent->uEventParam.btSyncConnection.connectionHandle; + break; + } + } + + if( i >= BT_MAX_SCO_SUPPORT ) + { + smsLog(pMac, LOGE, FL("Too many SCO, ignore this one")); + } + } + else + { + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + /*If No Other Sco/A2DP is ON reenable UAPSD*/ + if( (BT_MAX_SCO_SUPPORT == i) && !pMac->btc.fA2DPUp) + { + pMac->btc.btcUapsdOk = VOS_TRUE; + } + smsLog(pMac, LOGE, FL("TSYNC complete failed")); + } + break; + case BT_EVENT_A2DP_STREAM_START: + smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_START (%d) happens, UAPSD-allowed flag (%d) change to FALSE", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + pMac->btc.fA2DPTrafStop = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_FALSE; + pMac->btc.fA2DPUp = VOS_TRUE; + break; + default: + //No change for these events + smsLog( pMac, LOGE, "BT event (%d) happens, UAPSD-allowed flag (%d) no change", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + break; + } + if(fLastUapsdState != pMac->btc.btcUapsdOk) + { + sme_QosTriggerUapsdChange( pMac ); + } +} + +/* --------------------------------------------------------------------------- + \fn btcHandleCoexInd + \brief API to handle Coex indication from WDI + \param pMac - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_FAILURE success + eHAL_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + // DEBUG + smsLog(pMac, LOG1, "Coex indication in %s(), type %d", + __func__, pSmeCoexInd->coexIndType); + + // suspend heartbeat monitoring + if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR) + { + // set heartbeat threshold CFG to zero + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_FALSE; + } + + // resume heartbeat monitoring + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR) + { + if (!pMac->btc.btcHBActive) + { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_COMPROMISED) + { + pMac->btc.btcScanCompromise = VOS_TRUE; + smsLog(pMac, LOGW, "Coex indication in %s(), type - SIR_COEX_IND_TYPE_SCAN_COMPROMISED", + __func__); + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED) + { + pMac->btc.btcScanCompromise = VOS_FALSE; + smsLog(pMac, LOGW, "Coex indication in %s(), type - SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED", + __func__); + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4) + { + if (pMac->roam.configParam.disableAggWithBtc) + { + ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, 1, + NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcBssfordisableaggr[0] = pSmeCoexInd->coexIndData[0] & 0xFF; + pMac->btc.btcBssfordisableaggr[1] = pSmeCoexInd->coexIndData[0] >> 8; + pMac->btc.btcBssfordisableaggr[2] = pSmeCoexInd->coexIndData[1] & 0xFF; + pMac->btc.btcBssfordisableaggr[3] = pSmeCoexInd->coexIndData[1] >> 8; + pMac->btc.btcBssfordisableaggr[4] = pSmeCoexInd->coexIndData[2] & 0xFF; + pMac->btc.btcBssfordisableaggr[5] = pSmeCoexInd->coexIndData[2] >> 8; + smsLog(pMac, LOGW, "Coex indication in %s(), " + "type - SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 " + "for BSSID "MAC_ADDRESS_STR,__func__, + MAC_ADDR_ARRAY(pMac->btc.btcBssfordisableaggr)); + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4) + { + if (pMac->roam.configParam.disableAggWithBtc) + { + ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC, 0, + NULL, eANI_BOOLEAN_FALSE); + smsLog(pMac, LOGW, + "Coex indication in %s(), type - SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4", + __func__); + } + } + // unknown indication type + else + { + smsLog(pMac, LOGE, "unknown Coex indication type in %s()", __func__); + } + } + + return(status); +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/* --------------------------------------------------------------------------- + \fn btcDiagEventLog + \brief API to log the the current Bluetooth event + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtEvent. Caller owns the memory and is responsible + for freeing it. + \return None + ---------------------------------------------------------------------------*/ +static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + //vos_event_wlan_btc_type *log_ptr = NULL; + WLAN_VOS_DIAG_EVENT_DEF(btDiagEvent, vos_event_wlan_btc_type); + { + btDiagEvent.eventId = pBtEvent->btEventType; + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + btDiagEvent.connHandle = pBtEvent->uEventParam.btSyncConnection.connectionHandle; + btDiagEvent.connStatus = pBtEvent->uEventParam.btSyncConnection.status; + btDiagEvent.linkType = pBtEvent->uEventParam.btSyncConnection.linkType; + btDiagEvent.scoInterval = pBtEvent->uEventParam.btSyncConnection.scoInterval; + btDiagEvent.scoWindow = pBtEvent->uEventParam.btSyncConnection.scoWindow; + btDiagEvent.retransWindow = pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow; + vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btSyncConnection.bdAddr, + sizeof(btDiagEvent.btAddr)); + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclConnection.connectionHandle; + btDiagEvent.connStatus = pBtEvent->uEventParam.btAclConnection.status; + vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btAclConnection.bdAddr, + sizeof(btDiagEvent.btAddr)); + break; + case BT_EVENT_MODE_CHANGED: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle; + btDiagEvent.mode = pBtEvent->uEventParam.btAclModeChange.mode; + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle; + break; + default: + break; + } + } + WLAN_VOS_DIAG_EVENT_REPORT(&btDiagEvent, EVENT_WLAN_BTC); +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmApi.c new file mode 100644 index 0000000000000..7f6648a83a710 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmApi.c @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "palTypes.h" +#include "wniApi.h" /* WNI_CFG_SET_REQ */ +#include "sirParams.h" /* tSirMbMsg */ +#include "smsDebug.h" /* smsLog */ +#include "cfgApi.h" +#include "ccmApi.h" +#include "logDump.h" + +//#define CCM_DEBUG +#undef CCM_DEBUG + +#define CCM_DEBUG2 +//#undef CCM_DEBUG2 + +#define CFGOBJ_ALIGNTO 4 +#define CFGOBJ_ALIGN(len) ( ((len)+CFGOBJ_ALIGNTO-1) & ~(CFGOBJ_ALIGNTO-1) ) + +#define CFGOBJ_ID_SIZE 4 /* 4 bytes for cfgId */ +#define CFGOBJ_LEN_SIZE 4 /* 4 bytes for length */ +#define CFGOBJ_INTEGER_VALUE_SIZE 4 /* 4 bytes for integer value */ + +#define CFG_UPDATE_MAGIC_DWORD 0xabab + +#define halHandle2HddHandle(hHal) ( (NULL == (hHal)) ? 0 : ((tpAniSirGlobal)(hHal))->hHdd ) + +static void ccmComplete(tHddHandle hHdd, void *done) +{ + if (done) + { + (void)palSemaphoreGive(hHdd, done); + } +} + +static void ccmWaitForCompletion(tHddHandle hHdd, void *done) +{ + if (done) + { + (void)palSemaphoreTake(hHdd, done); + } +} + +static tANI_U32 * encodeCfgReq(tHddHandle hHdd, tANI_U32 *pl, tANI_U32 cfgId, tANI_S32 length, void *pBuf, tANI_U32 value, tANI_U32 type) +{ + *pl++ = pal_cpu_to_be32(cfgId) ; + *pl++ = pal_cpu_to_be32(length) ; + if (type == CCM_INTEGER_TYPE) + { + *pl++ = pal_cpu_to_be32(value) ; + } + else + { + vos_mem_copy((void *)pl, (void *)pBuf, length); + pl += (CFGOBJ_ALIGN(length) / CFGOBJ_ALIGNTO); + } + return pl ; +} + +/* + * CCM_STRING_TYPE CCM_INTEGER_TYPE + * |<-------- 4 ----->| |<-------- 4 ----->| + * +----------+ <-- msg --> +----------+ + * |type | |type | + * +----------+ +----------+ + * |msgLen=24 | |msgLen=16 | + * +----------+----------+ +----------+----------+ + * | cfgId | | cfgId | + * +---------------------+ +---------------------+ + * | length=11 | | length=4 | + * +---------------------+ +---------------------+ + * | | | value | + * | | +---------------------+ + * | | + * | +----+ + * | |////| <- padding to 4-byte boundary + * +----------------+----+ + */ +static eHalStatus sendCfg(tpAniSirGlobal pMac, tHddHandle hHdd, tCfgReq *req, tANI_BOOLEAN fRsp) +{ + tSirMbMsg *msg; + eHalStatus status; + tANI_S16 msgLen = (tANI_U16)(4 + /* 4 bytes for msg header */ + CFGOBJ_ID_SIZE + + CFGOBJ_LEN_SIZE + + CFGOBJ_ALIGN(req->length)) ; + + msg = vos_mem_malloc(msgLen); + if ( NULL != msg ) + { + if( fRsp ) + { + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ); + } + else + { + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ_NO_RSP); + } + msg->msgLen = pal_cpu_to_be16(msgLen); + (void)encodeCfgReq(hHdd, msg->data, req->cfgId, req->length, req->ccmPtr, req->ccmValue, req->type) ; + + status = palSendMBMessage(hHdd, msg) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("palSendMBMessage() failed")); + //No need to free msg. palSendMBMessage frees it. + status = eHAL_STATUS_FAILURE ; + } + } + else + { + smsLog( pMac, LOGW, FL("failed to allocate memory(len=%d)"), msgLen ); + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +static tCfgReq * allocateCfgReq(tHddHandle hHdd, tANI_U32 type, tANI_S32 length) +{ + tCfgReq *req ; + tANI_S32 alloc_len = sizeof(tCfgReq) ; + + if (type == CCM_STRING_TYPE) + { + alloc_len += length ; + } + + req = vos_mem_malloc(alloc_len); + if ( NULL == req ) + { + return NULL ; + } + + req->ccmPtr = (req+1); + + return req ; +} + +static void freeCfgReq(tHddHandle hHdd, tCfgReq *req) +{ + vos_mem_free(req); +} + +static void add_req_tail(tCfgReq *req, struct ccmlink *q) +{ + if (q->tail) + { + q->tail->next = req; + q->tail = req ; + } + else + { + q->head = q->tail = req ; + } +} + +static void del_req(tCfgReq *req, struct ccmlink *q) +{ + q->head = req->next ; + req->next = NULL ; + if (q->head == NULL) + { + q->tail = NULL ; + } +} + +static void purgeReqQ(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCfgReq *req, *tmp ; + + for (req = pMac->ccm.reqQ.head; req; req = tmp) + { + /* loop thru reqQ and invoke callback to return failure */ + smsLog(pMac, LOGW, FL("deleting cfgReq, cfgid=%d"), (int)req->cfgId); + + tmp = req->next ; + + if (req->callback) + { + req->callback(hHal, eHAL_STATUS_FAILURE); + } + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + freeCfgReq(hHdd, req); + } + return ; +} + +static void sendQueuedReqToMacSw(tpAniSirGlobal pMac, tHddHandle hHdd) +{ + tCfgReq *req ; + + /* Send the head req */ + req = pMac->ccm.reqQ.head ; + if (req) + { + if (req->state == eCCM_REQ_QUEUED) + { + /* Send WNI_CFG_SET_REQ */ + req->state = eCCM_REQ_SENT; + if (sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("sendCfg() failed")); + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ) ; + palSpinLockGive(hHdd, pMac->ccm.lock); + if (req->callback) + { + req->callback((tHalHandle)pMac, WNI_CFG_OTHER_ERROR) ; + } + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); +#endif + ccmComplete(hHdd, req->done); + + freeCfgReq(hHdd, req); + } + } + else + { + smsLog( pMac, LOGW, FL("reqState is not eCCM_REQ_QUEUED, is %d"), req->state ); + } + } + + return ; +} + +static eHalStatus cfgSetSub(tpAniSirGlobal pMac, tHddHandle hHdd, tANI_U32 cfgId, tANI_U32 type, + tANI_S32 length, void *ccmPtr, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved, void *sem, tCfgReq **r) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCfgReq *req ; + + do + { + *r = NULL ; + + if (pMac->ccm.state == eCCM_STOPPED) + { + status = eHAL_STATUS_FAILURE ; + break ; + } + + req = allocateCfgReq(hHdd, type, length); + if (req == NULL) + { + status = eHAL_STATUS_FAILED_ALLOC ; + break ; + } + + req->next = NULL ; + req->cfgId = (tANI_U16)cfgId ; + req->type = (tANI_U8)type ; + req->state = eCCM_REQ_QUEUED ; + req->toBeSaved = !!toBeSaved ; + req->length = length ; + req->done = sem ; + req->callback = callback ; + if (type == CCM_INTEGER_TYPE) + { + req->ccmValue = ccmValue ; + } + else + { + vos_mem_copy((void *)req->ccmPtr, (void *)ccmPtr, length); + } + + palSpinLockTake(hHdd, pMac->ccm.lock); + + add_req_tail(req, &pMac->ccm.reqQ); + /* If this is the first req on the queue, send it to MAC SW */ + if ((pMac->ccm.replay.started == 0) && (pMac->ccm.reqQ.head == req)) + { + /* Send WNI_CFG_SET_REQ */ + req->state = eCCM_REQ_SENT; + palSpinLockGive(hHdd, pMac->ccm.lock); + status = sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("sendCfg() failed")); + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + freeCfgReq(hHdd, req); + break ; + } + else + { + palSpinLockTake(hHdd, pMac->ccm.lock); + if(req != pMac->ccm.reqQ.head) + { + //We send the request and it must be done already + req = NULL; + } + palSpinLockGive(hHdd, pMac->ccm.lock); + } + } + else + { + palSpinLockGive(hHdd, pMac->ccm.lock); + } + *r = req ; + + } while(0) ; + + return status; +} + +static eHalStatus cfgSet(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 type, tANI_S32 length, void * ccmPtr, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + tCfgReq *req ; + + if (pal_in_interrupt()) + { +#ifdef CCM_DEBUG2 + smsLog(pMac, LOG1, FL("WNI_CFG_%s (%d 0x%x), in_interrupt()=TRUE"), gCfgParamName[cfgId], (int)cfgId, (int)cfgId); +#endif + status = cfgSetSub(pMac, hHdd, cfgId, type, length, ccmPtr, ccmValue, callback, toBeSaved, NULL, &req); + } + else + { + void *sem ; + +#ifdef CCM_DEBUG2 + smsLog(pMac, LOG1, FL("WNI_CFG_%s (%d 0x%x), in_interrupt()=FALSE"), gCfgParamName[cfgId], (int)cfgId, (int)cfgId); +#endif + pal_local_bh_disable() ; + + status = palMutexAllocLocked( hHdd, &sem ) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("mutex alloc failed")); + sem = NULL; + } + else + { + status = cfgSetSub(pMac, hHdd, cfgId, type, length, ccmPtr, ccmValue, callback, toBeSaved, sem, &req); + if ((status != eHAL_STATUS_SUCCESS) || (req == NULL)) + { + //Either it fails to send or the req is finished already + palSemaphoreFree( hHdd, sem ); + sem = NULL; + } + } + + pal_local_bh_enable() ; + + if ((status == eHAL_STATUS_SUCCESS) && (sem != NULL)) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOG1, FL("ccmWaitForCompletion(%p)"), req->done); +#endif + ccmWaitForCompletion(hHdd, sem); + +#ifdef CCM_DEBUG + smsLog(pMac, LOG1, FL("free(%p)"), req->done); +#endif + palSemaphoreFree( hHdd, sem ) ; + } + } + + return status ; +} + +eHalStatus ccmOpen(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + vos_mem_set(&pMac->ccm, sizeof(tCcm), 0); + return palSpinLockAlloc(hHdd, &pMac->ccm.lock); +} + +eHalStatus ccmClose(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 i ; + tCfgReq *req ; + + ccmStop(hHal); + + /* Go thru comp[] to free all saved requests */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + freeCfgReq(hHdd, req); + } + } + + return palSpinLockFree(hHdd, pMac->ccm.lock); +} + +/* This function executes in (Linux) softirq context */ +void ccmCfgCnfMsgHandler(tHalHandle hHal, void *m) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSirMbMsg *msg = (tSirMbMsg *)m ; + tANI_U32 result, cfgId ; + tCfgReq *req, *old ; + + result = pal_be32_to_cpu(msg->data[0]); + cfgId = pal_be32_to_cpu(msg->data[1]); + + if (pMac->ccm.replay.started && cfgId == CFG_UPDATE_MAGIC_DWORD) + { + pMac->ccm.replay.in_progress = 1 ; + return ; + } + + if (pMac->ccm.replay.in_progress) + { + /* save error code */ + if (!CCM_IS_RESULT_SUCCESS(result)) + { + pMac->ccm.replay.result = result ; + } + + if (--pMac->ccm.replay.nr_param == 0) + { + pMac->ccm.replay.in_progress = 0 ; + + if (pMac->ccm.replay.callback) + { + pMac->ccm.replay.callback(hHal, pMac->ccm.replay.result); + } + + pMac->ccm.replay.started = 0 ; + + /* Wake up the sleeping process */ +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), pMac->ccm.replay.done); +#endif + ccmComplete(hHdd, pMac->ccm.replay.done); + //Let go with the rest of the set CFGs waiting. + sendQueuedReqToMacSw(pMac, hHdd); + } + } + else + { + /* + * Try to match this response with the request. + * What if i could not find the req entry ??? + */ + req = pMac->ccm.reqQ.head ; + if (req) + { + + if (req->cfgId == cfgId && req->state == eCCM_REQ_SENT) + { + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + req->state = eCCM_REQ_DONE ; + + if (result == WNI_CFG_NEED_RESTART || + result == WNI_CFG_NEED_RELOAD) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("need restart/reload, cfgId=%d"), req->cfgId) ; +#endif + //purgeReqQ(hHal); + } + + /* invoke callback */ + if (req->callback) + { +#ifdef CCM_DEBUG + req->callback(hHal, cfgId) ; +#else + req->callback(hHal, result) ; +#endif + } + + /* Wake up the sleeping process */ +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("cfgId=%ld, calling ccmComplete(%p)"), cfgId, req->done); +#endif + ccmComplete(hHdd, req->done); + + /* move the completed req from reqQ to comp[] */ + if (req->toBeSaved && (CCM_IS_RESULT_SUCCESS(result))) + { + if (cfgId < CFG_PARAM_MAX_NUM) + { + if ((old = pMac->ccm.comp[cfgId]) != NULL) + { + freeCfgReq(hHdd, old) ; + } + pMac->ccm.comp[cfgId] = req ; + } + } + else + { + freeCfgReq(hHdd, req) ; + } + sendQueuedReqToMacSw(pMac, hHdd); + } + else + { + smsLog( pMac, LOGW, FL("can not match RSP with REQ, rspcfgid=%d result=%d reqcfgid=%d reqstate=%d"), + (int)cfgId, (int)result, req->cfgId, req->state); + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); +#endif + } + + } + } + + return ; +} + +void ccmStart(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->ccm.state = eCCM_STARTED ; + +#if defined(ANI_LOGDUMP) + ccmDumpInit(hHal); +#endif //#if defined(ANI_LOGDUMP) + + return ; +} + +void ccmStop(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->ccm.state = eCCM_STOPPED ; + + pal_local_bh_disable() ; + purgeReqQ(hHal); + pal_local_bh_enable() ; + + return ; +} + +eHalStatus ccmCfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + if( callback || toBeSaved) + { + //we need to sychronous this one + return cfgSet(hHal, cfgId, CCM_INTEGER_TYPE, sizeof(tANI_U32), NULL, ccmValue, callback, toBeSaved); + } + else + { + //Simply push to CFG and not waiting for the response + tCfgReq req; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + req.callback = NULL; + req.next = NULL; + req.cfgId = ( tANI_U16 )cfgId; + req.length = sizeof( tANI_U32 ); + req.type = CCM_INTEGER_TYPE; + req.ccmPtr = NULL; + req.ccmValue = ccmValue; + req.toBeSaved = toBeSaved; + req.state = eCCM_REQ_SENT; + + return ( sendCfg( pMac, pMac->hHdd, &req, eANI_BOOLEAN_FALSE ) ); + } +} + +eHalStatus ccmCfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, tANI_U32 length, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + if( callback || toBeSaved ) + { + //we need to sychronous this one + return cfgSet(hHal, cfgId, CCM_STRING_TYPE, length, pStr, 0, callback, toBeSaved); + } + else + { + //Simply push to CFG and not waiting for the response + tCfgReq req; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + req.callback = NULL; + req.next = NULL; + req.cfgId = ( tANI_U16 )cfgId; + req.length = length; + req.type = CCM_STRING_TYPE; + req.ccmPtr = pStr; + req.ccmValue = 0; + req.toBeSaved = toBeSaved; + req.state = eCCM_REQ_SENT; + + return ( sendCfg( pMac, pMac->hHdd, &req, eANI_BOOLEAN_FALSE ) ); + } +} + +eHalStatus ccmCfgGetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 *pValue) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS ; + tCfgReq *req; + + if (cfgId >= CFG_PARAM_MAX_NUM) { + smsLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId); + return eHAL_STATUS_INVALID_PARAMETER; + } + + req = pMac->ccm.comp[cfgId] ; + + if (req && req->state == eCCM_REQ_DONE) + { + *pValue = req->ccmValue ; + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId, pValue) != eSIR_SUCCESS) + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +eHalStatus ccmCfgGetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tHddHandle hHdd; + eHalStatus status = eHAL_STATUS_SUCCESS ; + tCfgReq *req; + + if (!pMac) + return eHAL_STATUS_FAILURE; + + hHdd = halHandle2HddHandle(hHal); + + if (cfgId >= CFG_PARAM_MAX_NUM) { + smsLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId); + return eHAL_STATUS_INVALID_PARAMETER; + } + + req = pMac->ccm.comp[cfgId] ; + + if (req && req->state == eCCM_REQ_DONE && (tANI_U32)req->length <= *pLength) + { + *pLength = req->length ; + vos_mem_copy((void *)pBuf, (void *)req->ccmPtr, req->length); + } + else + { + if (wlan_cfgGetStr(pMac, (tANI_U16)cfgId, pBuf, pLength) != eSIR_SUCCESS) + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +/* + * Loop thru comp[] and form an ANI message which contains all completed cfgIds. + * The message begins with an INTEGER parameter (cfgId=CFG_UPDATE_MAGIC_DWORD) + * to mark the start of the message. + */ +static eHalStatus cfgUpdate(tpAniSirGlobal pMac, tHddHandle hHdd, tCcmCfgSetCallback callback) +{ + tANI_U32 i, *pl ; + tCfgReq *req ; + tSirMbMsg *msg ; + eHalStatus status ; + tANI_S16 msgLen = 4 + /* 4 bytes for msg header */ + /* for CFG_UPDATE_MAGIC_DWORD */ + CFGOBJ_ID_SIZE + + CFGOBJ_LEN_SIZE + + CFGOBJ_INTEGER_VALUE_SIZE ; + + if (pMac->ccm.state == eCCM_STOPPED || pMac->ccm.replay.started) + { + status = eHAL_STATUS_FAILURE ; + goto end ; + } + + palSpinLockTake(hHdd, pMac->ccm.lock); + + pMac->ccm.replay.started = 1 ; + pMac->ccm.replay.nr_param = 0 ; + + palSpinLockGive(hHdd, pMac->ccm.lock); + + /* Calculate message length */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + msgLen += (tANI_S16)(CFGOBJ_ID_SIZE + CFGOBJ_LEN_SIZE + CFGOBJ_ALIGN(req->length)) ; + pMac->ccm.replay.nr_param += 1 ; +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("cfgId=%d"), req->cfgId); +#endif + } + } + + if (pMac->ccm.replay.nr_param == 0) + { + if (callback) + { + callback((tHalHandle)pMac, WNI_CFG_SUCCESS) ; + } + status = eHAL_STATUS_SUCCESS ; + goto end ; + } + + pMac->ccm.replay.in_progress = 0 ; + pMac->ccm.replay.result = WNI_CFG_SUCCESS ; + pMac->ccm.replay.callback = callback ; + pMac->ccm.replay.done = NULL ; + + msg = vos_mem_malloc(msgLen); + if ( NULL == msg ) + { + pMac->ccm.replay.started = 0 ; + status = eHAL_STATUS_FAILURE; + goto end; + } + + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ); + msg->msgLen = pal_cpu_to_be16(msgLen); + + /* Encode the starting cfgId */ + pl = encodeCfgReq(hHdd, msg->data, CFG_UPDATE_MAGIC_DWORD, 4, NULL, 0, CCM_INTEGER_TYPE) ; + + /* Encode the saved cfg requests */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + pl = encodeCfgReq(hHdd, pl, req->cfgId, req->length, req->ccmPtr, req->ccmValue, req->type) ; + } + } + + status = palSendMBMessage(hHdd, msg) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGW, FL("palSendMBMessage() failed. status=%d"), status); + pMac->ccm.replay.started = 0 ; + //No need to free msg. palSendMBMessage frees it. + goto end ; + } + + end: + return status ; +} + +eHalStatus ccmCfgUpdate(tHalHandle hHal, tCcmCfgSetCallback callback) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status ; + + pal_local_bh_disable() ; + + status = cfgUpdate(pMac, hHdd, callback) ; + if (status == eHAL_STATUS_SUCCESS) + { + if (pMac->ccm.replay.nr_param == 0) + { + /* there is nothing saved at comp[], so we are done! */ + pMac->ccm.replay.started = 0 ; + } + else + { + /* we have sent update message to MAC SW */ + void *sem ; + + status = palMutexAllocLocked( hHdd, &sem ) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("mutex alloc failed")); + pMac->ccm.replay.started = 0 ; + } + else + { + pMac->ccm.replay.done = sem ; + } + } + } + + pal_local_bh_enable() ; + + /* Waiting here ... */ + if (status == eHAL_STATUS_SUCCESS && pMac->ccm.replay.done) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmWaitForCompletion(%p)"), pMac->ccm.replay.done); +#endif + ccmWaitForCompletion(hHdd, pMac->ccm.replay.done); + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("free(%p)"), pMac->ccm.replay.done); +#endif + palSemaphoreFree( hHdd, pMac->ccm.replay.done) ; + } + + return status ; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmLogDump.c b/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmLogDump.c new file mode 100644 index 0000000000000..7ebd35b260c5f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/ccm/ccmLogDump.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +ccmLogDump.c + +Implements the dump commands specific to the ccm module. + ============================================================================*/ + + +#include "aniGlobal.h" +#include "logDump.h" + +#if defined(ANI_LOGDUMP) + +static tDumpFuncEntry ccmMenuDumpTable[] = { + + {0, "CCM (861-870)", NULL}, + //{861, "CCM: CCM testing ", dump_ccm} + +}; + +void ccmDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal) hHal, &ccmMenuDumpTable[0], + sizeof(ccmMenuDumpTable)/sizeof(ccmMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c new file mode 100644 index 0000000000000..04cebbb073b4c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiRoam.c @@ -0,0 +1,18930 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrApiRoam.c + + Implementation for the Common Roaming interfaces. +========================================================================== */ +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + when who what, where, why +---------- --- -------------------------------------------------------- +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure +===========================================================================*/ +#include "aniGlobal.h" //for tpAniSirGlobal +#include "wlan_qct_wda.h" +#include "halMsgApi.h" //for HAL_STA_INVALID_IDX. +#include "limUtils.h" +#include "palApi.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "logDump.h" +#include "smeQosInternal.h" +#include "wlan_qct_tl.h" +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#include "csrApi.h" +#include "pmc.h" +#include "vos_nvitem.h" +#include "macTrace.h" +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "csrNeighborRoam.h" +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ +#include "regdomain_common.h" +#include "vos_utils.h" + +#define CSR_NUM_IBSS_START_CHANNELS_50 4 +#define CSR_NUM_IBSS_START_CHANNELS_24 3 +#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD ( 5 * VOS_TIMER_TO_SEC_UNIT ) // 5 seconds, for WPA, WPA2, CCKM +#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD ( 120 * VOS_TIMER_TO_SEC_UNIT ) // 120 seconds, for WPS +/*--------------------------------------------------------------------------- + OBIWAN recommends [8 10]% : pick 9% +---------------------------------------------------------------------------*/ +#define CSR_VCC_UL_MAC_LOSS_THRESHOLD 9 +/*--------------------------------------------------------------------------- + OBIWAN recommends -85dBm +---------------------------------------------------------------------------*/ +#define CSR_VCC_RSSI_THRESHOLD 80 +#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD 500 //ms +#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS 2000 //ms +#define CSR_MIN_TL_STAT_QUERY_PERIOD 500 //ms +//We use constant 4 here +//This macro returns true when higher AC parameter is bigger than lower AC for a difference +//The bigger the number, the less chance of TX +//It must put lower AC as the first parameter. +#define SME_DETECT_AC_WEIGHT_DIFF(loAC, hiAC) (v_BOOL_t)(((hiAC) > (loAC)) ? (((hiAC)-(loAC)) > 4) : 0) +//Flag to send/do not send disassoc frame over the air +#define CSR_DONT_SEND_DISASSOC_OVER_THE_AIR 1 +#define RSSI_HACK_BMPS (-40) +#define MAX_CB_VALUE_IN_INI (2) + +#define MAX_SOCIAL_CHANNELS 3 + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static tANI_BOOLEAN bRoamScanOffloadStarted = VOS_FALSE; +#endif + +/*-------------------------------------------------------------------------- + Static Type declarations + ------------------------------------------------------------------------*/ +static tCsrRoamSession csrRoamRoamSession[CSR_ROAM_SESSION_MAX]; + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +int diagAuthTypeFromCSRType(eCsrAuthType authType) +{ + int n = AUTH_OPEN; + switch(authType) + { + case eCSR_AUTH_TYPE_SHARED_KEY: + n = AUTH_SHARED; + break; + case eCSR_AUTH_TYPE_WPA: + n = AUTH_WPA_EAP; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + n = AUTH_WPA_PSK; + break; + case eCSR_AUTH_TYPE_RSN: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + n = AUTH_WPA2_EAP; + break; + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: +#endif + n = AUTH_WPA2_PSK; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + n = AUTH_WAPI_CERT; + break; + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + n = AUTH_WAPI_PSK; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: + break; + } + return (n); +} +int diagEncTypeFromCSRType(eCsrEncryptionType encType) +{ + int n = ENC_MODE_OPEN; + switch(encType) + { + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + n = ENC_MODE_WEP40; + break; + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + n = ENC_MODE_WEP104; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + n = ENC_MODE_TKIP; + break; + case eCSR_ENCRYPT_TYPE_AES: + n = ENC_MODE_AES; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + n = ENC_MODE_SMS4; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: + break; + } + return (n); +} +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +static const tANI_U8 csrStartIbssChannels50[ CSR_NUM_IBSS_START_CHANNELS_50 ] = { 36, 40, 44, 48}; +static const tANI_U8 csrStartIbssChannels24[ CSR_NUM_IBSS_START_CHANNELS_24 ] = { 1, 6, 11 }; +static void initConfigParam(tpAniSirGlobal pMac); +static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + eCsrRoamCompleteResult Result, void *Context ); +static eHalStatus csrRoamStartIbss( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamProfile *pProfile, + tANI_BOOLEAN *pfSameIbss ); +static void csrRoamUpdateConnectedProfileFromNewBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirSmeNewBssInfo *pNewBss ); +static void csrRoamPrepareBssParams(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, tDot11fBeaconIEs *pIes); +static ePhyChanBondState csrGetCBModeFromIes(tpAniSirGlobal pMac, tANI_U8 primaryChn, tDot11fBeaconIEs *pIes); +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac); +static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 result ); +eHalStatus csrRoamOpen(tpAniSirGlobal pMac); +eHalStatus csrRoamClose(tpAniSirGlobal pMac); +void csrRoamMICErrorTimerHandler(void *pv); +void csrRoamTKIPCounterMeasureTimerHandler(void *pv); +tANI_BOOLEAN csrRoamIsSameProfileKeys(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile, tCsrRoamProfile *pProfile2); + +static eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval); +static eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId); +static void csrRoamRoamingTimerHandler(void *pv); +eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval); +eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac); +static void csrRoamWaitForKeyTimeOutHandler(void *pv); +static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo); +static eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo); +static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo ); +eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U8 keyLength, tANI_U8 *pKey, tANI_U8 paeRole, + tANI_U8 *pKeyRsc ); +static eHalStatus csrRoamIssueReassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, + tCsrRoamProfile *pProfile ); +void csrRoamStatisticsTimerHandler(void *pv); +void csrRoamStatsGlobalClassDTimerHandler(void *pv); +static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid); +VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal, + v_U8_t rssiNotification, + void * context); +static void csrRoamLinkDown(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRoamVccTrigger(tpAniSirGlobal pMac); +eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, + tANI_U8 staId, tANI_U8 sessionId); +/* + pStaEntry is no longer invalid upon the return of this function. +*/ +static void csrRoamRemoveStatListEntry(tpAniSirGlobal pMac, tListElem *pEntry); +static eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile,tANI_U8 operationChn, eCsrBand *pBand ); +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc); +tCsrStatsClientReqInfo * csrRoamInsertEntryIntoList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrStatsClientReqInfo *pStaEntry); +void csrRoamStatsClientTimerHandler(void *pv); +tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask, + tANI_U32 periodicity, + tANI_BOOLEAN *pFound, + tANI_U8 staId, + tANI_U8 sessionId); +void csrRoamReportStatistics(tpAniSirGlobal pMac, tANI_U32 statsMask, + tCsrStatsCallback callback, tANI_U8 staId, void *pContext); +void csrRoamSaveStatsFromTl(tpAniSirGlobal pMac, WLANTL_TRANSFER_STA_TYPE *pTlStats); +void csrRoamTlStatsTimerHandler(void *pv); +void csrRoamPeStatsTimerHandler(void *pv); +tListElem * csrRoamCheckClientReqList(tpAniSirGlobal pMac, tANI_U32 statsMask); +void csrRoamRemoveEntryFromPeStatsReqList(tpAniSirGlobal pMac, tCsrPeStatsReqInfo *pPeStaEntry); +tListElem * csrRoamFindInPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask); +eHalStatus csrRoamDeregStatisticsReq(tpAniSirGlobal pMac); +static tANI_U32 csrFindIbssSession( tpAniSirGlobal pMac ); +static eHalStatus csrRoamStartWds( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc ); +static void csrInitSession( tpAniSirGlobal pMac, tANI_U32 sessionId ); +static eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc); +void csrRoamReissueRoamCommand(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_BTAMP_UT_RF +void csrRoamJoinRetryTimerHandler(void *pv); +#endif +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +extern void btampEstablishLogLinkHdlr(void* pMsg); +static void csrSerDesUnpackDiassocRsp(tANI_U8 *pBuf, tSirSmeDisassocRsp *pRsp); +void csrReinitPreauthCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrInitOperatingClasses(tHalHandle hHal); + +//Initialize global variables +static void csrRoamInitGlobals(tpAniSirGlobal pMac) +{ + if(pMac) + { + vos_mem_zero(&csrRoamRoamSession, sizeof(csrRoamRoamSession)); + pMac->roam.roamSession = csrRoamRoamSession; + } + return; +} + +static void csrRoamDeInitGlobals(tpAniSirGlobal pMac) +{ + if(pMac) + { + pMac->roam.roamSession = NULL; + } + return; +} +eHalStatus csrOpen(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + + do + { + /* Initialize CSR Roam Globals */ + csrRoamInitGlobals(pMac); + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_STOP, i); + + initConfigParam(pMac); + if(!HAL_STATUS_SUCCESS((status = csrScanOpen(pMac)))) + break; + if(!HAL_STATUS_SUCCESS((status = csrRoamOpen(pMac)))) + break; + pMac->roam.nextRoamId = 1; //Must not be 0 + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.statsClientReqList))) + break; + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.peStatsReqList))) + break; + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.roamCmdPendingList))) + break; + }while(0); + + return (status); +} + +eHalStatus csr_init_chan_list(tpAniSirGlobal mac, v_U8_t *alpha2) +{ + eHalStatus status; + v_REGDOMAIN_t reg_id; + v_CountryInfoSource_t source = COUNTRY_INIT; + + mac->scan.countryCodeDefault[0] = alpha2[0]; + mac->scan.countryCodeDefault[1] = alpha2[1]; + mac->scan.countryCodeDefault[2] = alpha2[2]; + + smsLog(mac, LOGE, FL("init time country code %.2s"), + mac->scan.countryCodeDefault); + + status = csrGetRegulatoryDomainForCountry(mac, + mac->scan.countryCodeDefault, + ®_id, source); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(mac, LOGE, FL("csrGetRegulatoryDomainForCountry failed")); + return status; + } + + if (vos_nv_setRegDomain(mac, reg_id, FALSE) != VOS_STATUS_SUCCESS) + { + smsLog(mac, LOGE, FL("vos_nv_setRegDomain failed")); + return eHAL_STATUS_FAILURE; + } + mac->scan.domainIdDefault = reg_id; + mac->scan.domainIdCurrent = mac->scan.domainIdDefault; + vos_mem_copy(mac->scan.countryCodeCurrent, + mac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(mac->scan.countryCodeElected, + mac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels(mac); + csrClearVotesForCountryInfo(mac); + return status; +} + +eHalStatus csrSetRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_REGDOMAIN_t regId; + v_U8_t cntryCodeLength; + if(NULL == apCntryCode) + { + smsLog( pMac, LOGE, FL(" Invalid country Code Pointer") ); + return eHAL_STATUS_FAILURE; + } + smsLog( pMac, LOG1, FL(" country Code %.2s"), apCntryCode ); + /* To get correct Regulatory domain from NV table + * 2 character Country code should be used + * 3rd charater is optional for indoor/outdoor setting */ + cntryCodeLength = WNI_CFG_COUNTRY_CODE_LEN; + status = csrGetRegulatoryDomainForCountry(pMac, apCntryCode, ®Id, + COUNTRY_USER); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to get regId for country Code %.2s"), apCntryCode ); + return status; + } + status = WDA_SetRegDomain(hHal, regId, eSIR_TRUE); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to get regId for country Code %.2s"), apCntryCode ); + return status; + } + pMac->scan.domainIdDefault = regId; + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + /* Clear CC field */ + vos_mem_set(pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN, 0); + + /* Copy 2 or 3 bytes country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, apCntryCode, cntryCodeLength); + + /* If 2 bytes country code, 3rd byte must be filled with space */ + if((WNI_CFG_COUNTRY_CODE_LEN - 1) == cntryCodeLength) + { + vos_mem_set(pMac->scan.countryCodeDefault + 2, 1, 0x20); + } + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels( pMac ); + return status; +} +eHalStatus csrSetChannels(tHalHandle hHal, tCsrConfigParam *pParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 index = 0; + vos_mem_copy(pParam->Csr11dinfo.countryCode, pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + for ( index = 0; index < pMac->scan.base20MHzChannels.numChannels ; index++) + { + pParam->Csr11dinfo.Channels.channelList[index] = pMac->scan.base20MHzChannels.channelList[ index ]; + pParam->Csr11dinfo.ChnPower[index].firstChannel = pMac->scan.base20MHzChannels.channelList[ index ]; + pParam->Csr11dinfo.ChnPower[index].numChannels = 1; + pParam->Csr11dinfo.ChnPower[index].maxtxPower = pMac->scan.defaultPowerTable[index].pwr; + } + pParam->Csr11dinfo.Channels.numChannels = pMac->scan.base20MHzChannels.numChannels; + + return status; +} +eHalStatus csrClose(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + csrRoamClose(pMac); + csrScanClose(pMac); + csrLLClose(&pMac->roam.statsClientReqList); + csrLLClose(&pMac->roam.peStatsReqList); + csrLLClose(&pMac->roam.roamCmdPendingList); + /* DeInit Globals */ + csrRoamDeInitGlobals(pMac); + return (status); +} + +static tChannelPwrLimit csrFindChannelPwr(tChannelListWithPower * pdefaultPowerTable, + tANI_U8 ChannelNum) +{ + tANI_U8 i; + // TODO: if defaultPowerTable is guaranteed to be in ascending + // order of channel numbers, we can employ binary search + for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) + { + if (pdefaultPowerTable[i].chanId == ChannelNum) + return pdefaultPowerTable[i].pwr; + } + // could not find the channel list in default list + // this should not have occured + VOS_ASSERT(0); + return 0; +} + +eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac) +{ + tSirUpdateChanList *pChanList; + tCsrScanStruct *pScan = &pMac->scan; + tANI_U8 numChan = pScan->base20MHzChannels.numChannels; + tANI_U8 num_channel = 0; + tANI_U32 bufLen; + vos_msg_t msg; + tANI_U8 i, j, social_channel[MAX_SOCIAL_CHANNELS] = {1,6,11}; + tANI_U8 channel_state; + + if (CSR_IS_5G_BAND_ONLY(pMac)) + { + for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) + { + if (vos_nv_getChannelEnabledState(social_channel[i]) + == NV_CHANNEL_ENABLE) + numChan++; + } + } + + bufLen = sizeof(tSirUpdateChanList) + + (sizeof(tSirUpdateChanParam) * (numChan)); + + csrInitOperatingClasses((tHalHandle)pMac); + pChanList = (tSirUpdateChanList *) vos_mem_malloc(bufLen); + if (!pChanList) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate memory for tSirUpdateChanList"); + return eHAL_STATUS_FAILED_ALLOC; + } + + for (i = 0; i < pScan->base20MHzChannels.numChannels; i++) + { + if (pScan->fcc_constraint) { + if (pScan->base20MHzChannels.channelList[i] == 12) + continue; + if (pScan->base20MHzChannels.channelList[i] == 13) + continue; + } + channel_state = + vos_nv_getChannelEnabledState( + pScan->base20MHzChannels.channelList[i]); + if ((NV_CHANNEL_ENABLE == channel_state) || + pMac->scan.fEnableDFSChnlScan) + { + pChanList->chanParam[num_channel].chanId = + pScan->base20MHzChannels.channelList[i]; + pChanList->chanParam[num_channel].pwr = + csrFindChannelPwr(pScan->defaultPowerTable, + pChanList->chanParam[num_channel].chanId); + if (NV_CHANNEL_ENABLE == channel_state) + pChanList->chanParam[num_channel].dfsSet = VOS_FALSE; + else + pChanList->chanParam[num_channel].dfsSet = VOS_TRUE; + num_channel++; + } + } + + + if (CSR_IS_5G_BAND_ONLY(pMac)) + { + for (j = 0; j < MAX_SOCIAL_CHANNELS; j++) + { + if (vos_nv_getChannelEnabledState(social_channel[j]) + == NV_CHANNEL_ENABLE) + { + pChanList->chanParam[num_channel].chanId = social_channel[j]; + pChanList->chanParam[num_channel].pwr = + csrFindChannelPwr(pScan->defaultPowerTable, + social_channel[j]); + pChanList->chanParam[num_channel].dfsSet = VOS_FALSE; + num_channel++; + } + } + } + + msg.type = WDA_UPDATE_CHAN_LIST_REQ; + msg.reserved = 0; + msg.bodyptr = pChanList; + pChanList->numChan = num_channel; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to post msg to WDA", __func__); + vos_mem_free(pChanList); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrStart(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + + do + { + //save the global vos context + pMac->roam.gVosContext = vos_get_global_context(VOS_MODULE_ID_SME, pMac); + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, i ); + + status = csrRoamStart(pMac); + if(!HAL_STATUS_SUCCESS(status)) break; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE; + + if(!pMac->psOffloadEnabled) + { + status = pmcRegisterPowerSaveCheck(pMac, csrCheckPSReady, pMac); + if(!HAL_STATUS_SUCCESS(status)) break; + } + else + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + status = pmcOffloadRegisterPowerSaveCheck(pMac, i, + csrCheckPSOffloadReady, pMac); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + "csrStart: Register Power Check Failed Session Id %x", i); + return status; + } + } + } + pMac->roam.sPendingCommands = 0; + csrScanEnable(pMac); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) + status = csrNeighborRoamInit(pMac, i); +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + pMac->roam.tlStatsReqInfo.numClient = 0; + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + //init the link quality indication also + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrStart: Couldn't Init HO control blk "); + break; + } + + if (pMac->fScanOffload) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Scan offload is enabled, update default chan list"); + status = csrUpdateChannelList(pMac); + } + + }while(0); +#if defined(ANI_LOGDUMP) + csrDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + return (status); +} + +eHalStatus csrStop(tpAniSirGlobal pMac, tHalStopType stopType) +{ + tANI_U32 sessionId; + + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + csrRoamCloseSession(pMac, sessionId, TRUE, NULL, NULL); + } + csrScanDisable(pMac); + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE; + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + csrLLPurge( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_TRUE ); + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + csrNeighborRoamClose(pMac, sessionId); +#endif + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + if (CSR_IS_SESSION_VALID(pMac, sessionId)) + csrScanFlushResult(pMac, sessionId); + + // deregister from PMC since we register during csrStart() + // (ignore status since there is nothing we can do if it fails) + if(!pMac->psOffloadEnabled) + { + (void) pmcDeregisterPowerSaveCheck(pMac, csrCheckPSReady); + } + else + { + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + pmcOffloadDeregisterPowerSaveCheck(pMac, sessionId, + csrCheckPSOffloadReady); + } + } + + //Reset the domain back to the deault + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) { + csrRoamStateChange(pMac, eCSR_ROAMING_STATE_STOP, sessionId); + pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE; + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* When HAL resets all the context information + * in HAL is lost, so we might need to send the + * scan offload request again when it comes + * out of reset for scan offload to be functional + */ + if (HAL_STOP_TYPE_SYS_RESET == stopType) + { + bRoamScanOffloadStarted = VOS_FALSE; + } +#endif + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus csrReady(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + csrScanGetSupportedChannels( pMac ); + //WNI_CFG_VALID_CHANNEL_LIST should be set by this time + //use it to init the background scan list + csrInitBGScanChannelList(pMac); + /* HDD issues the init scan */ + csrScanStartResultAgingTimer(pMac); + /* If the gScanAgingTime is set to '0' then scan results aging timeout + based on timer feature is not enabled*/ + if(0 != pMac->scan.scanResultCfgAgingTime ) + { + csrScanStartResultCfgAgingTimer(pMac); + } + //Store the AC weights in TL for later use + WLANTL_GetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + status = csrInitChannelList( pMac ); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "csrInitChannelList failed during csrReady with status=%d", + status ); + } + return (status); +} +void csrSetDefaultDot11Mode( tpAniSirGlobal pMac ) +{ + v_U32_t wniDot11mode = 0; + wniDot11mode = csrTranslateToWNICfgDot11Mode(pMac,pMac->roam.configParam.uCfgDot11Mode); + ccmCfgSetInt(pMac, WNI_CFG_DOT11_MODE, wniDot11mode, NULL, eANI_BOOLEAN_FALSE); +} +void csrSetGlobalCfgs( tpAniSirGlobal pMac ) +{ + + ccmCfgSetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, csrGetFragThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_RTS_THRESHOLD, csrGetRTSThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_11D_ENABLED, + ((pMac->roam.configParam.Is11hSupportEnabled) ? pMac->roam.configParam.Is11dSupportEnabled : pMac->roam.configParam.Is11dSupportEnabled), + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_11H_ENABLED, pMac->roam.configParam.Is11hSupportEnabled, NULL, eANI_BOOLEAN_FALSE); + /* For now we will just use the 5GHz CB mode ini parameter to decide whether CB supported or not in Probes when there is no session + * Once session is established we will use the session related params stored in PE session for CB mode + */ + ccmCfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, !!(pMac->roam.configParam.channelBondingMode5GHz), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->roam.configParam.HeartbeatThresh24, NULL, eANI_BOOLEAN_FALSE); + + //Update the operating mode to configured value during initialization, + //So that client can advertise full capabilities in Probe request frame. + csrSetDefaultDot11Mode( pMac ); +} + +eHalStatus csrRoamOpen(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + tCsrRoamSession *pSession; + do + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + pSession = CSR_GET_SESSION( pMac, i ); + pSession->roamingTimerInfo.pMac = pMac; + pSession->roamingTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + } + pMac->roam.WaitForKeyTimerInfo.pMac = pMac; + pMac->roam.WaitForKeyTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + status = vos_timer_init(&pMac->roam.hTimerWaitForKey, VOS_TIMER_TYPE_SW, + csrRoamWaitForKeyTimeOutHandler, + &pMac->roam.WaitForKeyTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for WaitForKey time out timer")); + break; + } + status = vos_timer_init(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + VOS_TIMER_TYPE_SW, csrRoamTlStatsTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for summary Statistics timer")); + return eHAL_STATUS_FAILURE; + } + }while (0); + return (status); +} + +eHalStatus csrRoamClose(tpAniSirGlobal pMac) +{ + tANI_U32 sessionId; + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + csrRoamCloseSession(pMac, sessionId, TRUE, NULL, NULL); + } + vos_timer_stop(&pMac->roam.hTimerWaitForKey); + vos_timer_destroy(&pMac->roam.hTimerWaitForKey); + vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + vos_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus csrRoamStart(tpAniSirGlobal pMac) +{ + (void)pMac; + return (eHAL_STATUS_SUCCESS); +} + +void csrRoamStop(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + csrRoamStopRoamingTimer(pMac, sessionId); + /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers*/ + csrRoamDeregStatisticsReq(pMac); +} +eHalStatus csrRoamGetConnectState(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrConnectState *pState) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if ( CSR_IS_SESSION_VALID(pMac, sessionId) && (NULL != pState) ) + { + status = eHAL_STATUS_SUCCESS; + *pState = pMac->roam.roamSession[sessionId].connectState; + } + return (status); +} + +eHalStatus csrRoamCopyConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 size = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pProfile) + { + if(pSession->pConnectBssDesc) + { + do + { + size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length); + if(size) + { + pProfile->pBssDesc = vos_mem_malloc(size); + if ( NULL != pProfile->pBssDesc ) + { + vos_mem_copy(pProfile->pBssDesc, + pSession->pConnectBssDesc, size); + status = eHAL_STATUS_SUCCESS; + } + else + break; + } + else + { + pProfile->pBssDesc = NULL; + } + pProfile->AuthType = pSession->connectedProfile.AuthType; + pProfile->EncryptionType = pSession->connectedProfile.EncryptionType; + pProfile->mcEncryptionType = pSession->connectedProfile.mcEncryptionType; + pProfile->BSSType = pSession->connectedProfile.BSSType; + pProfile->operationChannel = pSession->connectedProfile.operationChannel; + pProfile->CBMode = pSession->connectedProfile.CBMode; + vos_mem_copy(&pProfile->bssid, &pSession->connectedProfile.bssid, + sizeof(tCsrBssid)); + vos_mem_copy(&pProfile->SSID, &pSession->connectedProfile.SSID, + sizeof(tSirMacSSid)); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSession->connectedProfile.MDID.mdiePresent) + { + pProfile->MDID.mdiePresent = 1; + pProfile->MDID.mobilityDomain = pSession->connectedProfile.MDID.mobilityDomain; + } + else + { + pProfile->MDID.mdiePresent = 0; + pProfile->MDID.mobilityDomain = 0; + } +#endif +#ifdef FEATURE_WLAN_ESE + pProfile->isESEAssoc = pSession->connectedProfile.isESEAssoc; + if (csrIsAuthTypeESE(pSession->connectedProfile.AuthType)) + { + vos_mem_copy (pProfile->eseCckmInfo.krk, + pSession->connectedProfile.eseCckmInfo.krk, + SIR_KRK_KEY_LEN); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + vos_mem_copy (pProfile->eseCckmInfo.btk, + pSession->connectedProfile.eseCckmInfo.btk, + SIR_BTK_KEY_LEN); +#endif + pProfile->eseCckmInfo.reassoc_req_num= + pSession->connectedProfile.eseCckmInfo.reassoc_req_num; + pProfile->eseCckmInfo.krk_plumbed = + pSession->connectedProfile.eseCckmInfo.krk_plumbed; + } +#endif + }while(0); + } + } + + return (status); +} + +eHalStatus csrRoamGetConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + if((csrIsConnStateConnected(pMac, sessionId)) || + (csrIsConnStateIbss(pMac, sessionId))) + { + if(pProfile) + { + status = csrRoamCopyConnectProfile(pMac, sessionId, pProfile); + } + } + return (status); +} + +eHalStatus csrRoamFreeConnectProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if (pProfile->pBssDesc) + { + vos_mem_free(pProfile->pBssDesc); + } + if (pProfile->pAddIEAssoc) + { + vos_mem_free(pProfile->pAddIEAssoc); + } + vos_mem_set(pProfile, sizeof(tCsrRoamConnectedProfile), 0); + + pProfile->AuthType = eCSR_AUTH_TYPE_UNKNOWN; + return (status); +} + +static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + if( pConnectedInfo->pbFrames ) + { + vos_mem_free(pConnectedInfo->pbFrames); + pConnectedInfo->pbFrames = NULL; + } + pConnectedInfo->nBeaconLength = 0; + pConnectedInfo->nAssocReqLength = 0; + pConnectedInfo->nAssocRspLength = 0; + pConnectedInfo->staId = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + pConnectedInfo->nRICRspLength = 0; +#endif +#ifdef FEATURE_WLAN_ESE + pConnectedInfo->nTspecIeLength = 0; +#endif + return ( status ); +} + + + + +void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitPreauthCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitRoamCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitScanCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitWmStatusChangeCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReinitSetKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.setKeyCmd, sizeof(tSetKeyCmd), 0); +} + +void csrReinitRemoveKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.removeKeyCmd, sizeof(tRemoveKeyCmd), 0); +} + +void csrReleaseCommandSetKey(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitSetKeyCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} +void csrReleaseCommandRemoveKey(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitRemoveKeyCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} +void csrAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + + if( eSmeCsrCommandMask & pCommand->command ) + { + switch (pCommand->command) + { + case eSmeCommandScan: + // We need to inform the requester before dropping the scan command + smsLog( pMac, LOGW, "%s: Drop scan reason %d callback %p", + __func__, pCommand->u.scanCmd.reason, + pCommand->u.scanCmd.callback); + if (NULL != pCommand->u.scanCmd.callback) + { + smsLog( pMac, LOGW, "%s callback scan requester", __func__); + csrScanCallCallback(pMac, pCommand, eCSR_SCAN_ABORT); + } + csrReleaseCommandScan( pMac, pCommand ); + break; + case eSmeCommandRoam: + csrReleaseCommandRoam( pMac, pCommand ); + break; + + case eSmeCommandWmStatusChange: + csrReleaseCommandWmStatusChange( pMac, pCommand ); + break; + + case eSmeCommandSetKey: + csrReleaseCommandSetKey( pMac, pCommand ); + break; + + case eSmeCommandRemoveKey: + csrReleaseCommandRemoveKey( pMac, pCommand ); + break; + + default: + smsLog( pMac, LOGW, " CSR abort standard command %d", pCommand->command ); + csrReleaseCommand( pMac, pCommand ); + break; + } + } +} + +void csrRoamSubstateChange( tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate, tANI_U32 sessionId) +{ + smsLog(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"), + macTraceGetcsrRoamSubState(NewSubstate), + macTraceGetcsrRoamSubState(pMac->roam.curSubState[sessionId])); + if(pMac->roam.curSubState[sessionId] == NewSubstate) + { + return; + } + pMac->roam.curSubState[sessionId] = NewSubstate; +} + +eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId) +{ + eCsrRoamState PreviousState; + + smsLog(pMac, LOG1, FL("CSR RoamState[%hu]: [ %s <== %s ]"), sessionId, + macTraceGetcsrRoamState(NewRoamState), + macTraceGetcsrRoamState(pMac->roam.curState[sessionId])); + PreviousState = pMac->roam.curState[sessionId]; + + if ( NewRoamState != pMac->roam.curState[sessionId] ) + { + // Whenever we transition OUT of the Roaming state, clear the Roaming substate... + if ( CSR_IS_ROAM_JOINING(pMac, sessionId) ) + { + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + + pMac->roam.curState[sessionId] = NewRoamState; + } + return( PreviousState ); +} + +void csrAssignRssiForCategory(tpAniSirGlobal pMac, tANI_S8 bestApRssi, tANI_U8 catOffset) +{ + int i; + if(catOffset) + { + pMac->roam.configParam.bCatRssiOffset = catOffset; + for(i = 0; i < CSR_NUM_RSSI_CAT; i++) + { + pMac->roam.configParam.RSSICat[CSR_NUM_RSSI_CAT - i - 1] = (int)bestApRssi - pMac->roam.configParam.nSelect5GHzMargin - (int)(i * catOffset); + } + } +} + +static void initConfigParam(tpAniSirGlobal pMac) +{ + int i; + pMac->roam.configParam.agingCount = CSR_AGING_COUNT; + pMac->roam.configParam.channelBondingMode24GHz = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pMac->roam.configParam.channelBondingMode5GHz = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + + pMac->roam.configParam.phyMode = eCSR_DOT11_MODE_TAURUS; + pMac->roam.configParam.eBand = eCSR_BAND_ALL; + pMac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + pMac->roam.configParam.FragmentationThreshold = eCSR_DOT11_FRAG_THRESH_DEFAULT; + pMac->roam.configParam.HeartbeatThresh24 = 40; + pMac->roam.configParam.HeartbeatThresh50 = 40; + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.Is11dSupportEnabledOriginal = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.Is11eSupportEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.Is11hSupportEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.RTSThreshold = 2346; + pMac->roam.configParam.shortSlotTime = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.WMMSupportMode = eCsrRoamWmmAuto; + pMac->roam.configParam.ProprietaryRatesEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.TxRate = eCSR_TX_RATE_AUTO; + pMac->roam.configParam.impsSleepTime = CSR_IDLE_SCAN_NO_PS_INTERVAL; + pMac->roam.configParam.scanAgeTimeNCNPS = CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS; + pMac->roam.configParam.scanAgeTimeNCPS = CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS; + pMac->roam.configParam.scanAgeTimeCNPS = CSR_SCAN_AGING_TIME_CONNECT_NO_PS; + pMac->roam.configParam.scanAgeTimeCPS = CSR_SCAN_AGING_TIME_CONNECT_W_PS; + for(i = 0; i < CSR_NUM_RSSI_CAT; i++) + { + pMac->roam.configParam.BssPreferValue[i] = i; + } + csrAssignRssiForCategory(pMac, CSR_BEST_RSSI_VALUE, CSR_DEFAULT_RSSI_DB_GAP); + pMac->roam.configParam.nRoamingTime = CSR_DEFAULT_ROAMING_TIME; + pMac->roam.configParam.fEnforce11dChannels = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fSupplicantCountryCodeHasPriority = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fEnforceCountryCodeMatch = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fEnforceDefaultDomain = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.nActiveMaxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME; + pMac->roam.configParam.nActiveMinChnTime = CSR_ACTIVE_MIN_CHANNEL_TIME; + pMac->roam.configParam.nPassiveMaxChnTime = CSR_PASSIVE_MAX_CHANNEL_TIME; + pMac->roam.configParam.nPassiveMinChnTime = CSR_PASSIVE_MIN_CHANNEL_TIME; + pMac->roam.configParam.nActiveMaxChnTimeBtc = CSR_ACTIVE_MAX_CHANNEL_TIME_BTC; + pMac->roam.configParam.nActiveMinChnTimeBtc = CSR_ACTIVE_MIN_CHANNEL_TIME_BTC; + pMac->roam.configParam.disableAggWithBtc = eANI_BOOLEAN_TRUE; +#ifdef WLAN_AP_STA_CONCURRENCY + pMac->roam.configParam.nActiveMaxChnTimeConc = CSR_ACTIVE_MAX_CHANNEL_TIME_CONC; + pMac->roam.configParam.nActiveMinChnTimeConc = CSR_ACTIVE_MIN_CHANNEL_TIME_CONC; + pMac->roam.configParam.nPassiveMaxChnTimeConc = CSR_PASSIVE_MAX_CHANNEL_TIME_CONC; + pMac->roam.configParam.nPassiveMinChnTimeConc = CSR_PASSIVE_MIN_CHANNEL_TIME_CONC; + pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC; + pMac->roam.configParam.nNumStaChanCombinedConc = CSR_NUM_STA_CHAN_COMBINED_CONC; + pMac->roam.configParam.nNumP2PChanCombinedConc = CSR_NUM_P2P_CHAN_COMBINED_CONC; +#endif + pMac->roam.configParam.IsIdleScanEnabled = TRUE; //enable the idle scan by default + pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER; + pMac->roam.configParam.statsReqPeriodicity = CSR_MIN_GLOBAL_STAT_QUERY_PERIOD; + pMac->roam.configParam.statsReqPeriodicityInPS = CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS; +#ifdef WLAN_FEATURE_VOWIFI_11R + pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported = 0; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries = 3; + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold = 120; + pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff = 30; + pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff = 5; + pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold = 125; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = 20; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = 40; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod = 200; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels = 3; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[0] = 1; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[1] = 6; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[2] = 11; + pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = 20000; //20 seconds + pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0; + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt = 10; + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt = 10; + pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight = 14; +#endif +#ifdef WLAN_FEATURE_11AC + pMac->roam.configParam.nVhtChannelWidth = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1; +#endif + + pMac->roam.configParam.addTSWhenACMIsOff = 0; + pMac->roam.configParam.fScanTwice = eANI_BOOLEAN_FALSE; + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + pMac->roam.configParam.doBMPSWorkaround = 0; + + pMac->roam.configParam.nInitialDwellTime = 0; + pMac->roam.configParam.initial_scan_no_dfs_chnl = 0; +} +eCsrBand csrGetCurrentBand(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.bandCapability; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* + This function flushes the roam scan cache +*/ +eHalStatus csrFlushRoamScanRoamChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo + = &pMac->roam.neighborRoamInfo[sessionId]; + /* Free up the memory first (if required) */ + if (NULL != + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free( + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList + ); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList + = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels + = 0; + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* + This function flushes the roam scan cache +*/ +eHalStatus csrFlushCfgBgScanRoamChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + /* Free up the memory first (if required) */ + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0; + } + return status; +} + + + +/* + This function flushes the roam scan cache and creates fresh cache + based on the input channel list +*/ +eHalStatus csrCreateBgScanRoamChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const tANI_U8 *pChannelList, + const tANI_U8 numChannels) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = numChannels; + + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = + vos_mem_malloc(pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed")); + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0; + return eHAL_STATUS_RESOURCES; + } + + /* Update the roam global structure */ + vos_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + return status; +} + +/* This function modifies the bgscan channel list set via config ini or + runtime, whenever the band changes. + if the band is auto, then no operation is performed on the channel list + if the band is 2.4G, then make sure channel list contains only 2.4G valid channels + if the band is 5G, then make sure channel list contains only 5G valid channels +*/ +eHalStatus csrUpdateBgScanConfigIniChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 outNumChannels = 0; + tANI_U8 inNumChannels = 0; + tANI_U8 *inPtr = NULL; + tANI_U8 i = 0; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "No update required for channel list " + "either cfg.ini channel list is not set up or " + "auto band (Band %d)", eBand); + return status; + } + + inNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; + inPtr = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList; + if (eCSR_BAND_24 == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (CSR_IS_CHANNEL_24GHZ(inPtr[i]) && csrRoamIsChannelValid(pMac, inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac, sessionId); + csrCreateBgScanRoamChannelList(pMac, sessionId, ChannelList, + outNumChannels); + } + else if (eCSR_BAND_5G == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + /* Add 5G Non-DFS channel */ + if (CSR_IS_CHANNEL_5GHZ(inPtr[i]) && + csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac, sessionId); + csrCreateBgScanRoamChannelList(pMac, sessionId, ChannelList, + outNumChannels); + } + else if (eCSR_BAND_ALL == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac, sessionId); + csrCreateBgScanRoamChannelList(pMac, sessionId, ChannelList, + outNumChannels); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Invalid band, No operation carried out (Band %d)", eBand); + status = eHAL_STATUS_INVALID_PARAMETER; + } + + return status; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* + * This function modifies the roam scan channel list as per AP neighbor + * report; AP neighbor report may be empty or may include only other AP + * channels; in any case, we merge the channel list with the learned occupied + * channels list. + * if the band is 2.4G, then make sure channel list contains only 2.4G + * valid channels if the band is 5G, then make sure channel list contains + * only 5G valid channels + */ +eHalStatus csrCreateRoamScanChannelList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels, + const eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo + = &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 outNumChannels = 0; + tANI_U8 inNumChannels = numChannels; + tANI_U8 *inPtr = pChannelList; + tANI_U8 i = 0; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 mergedOutputNumOfChannels = 0; + tpCsrChannelInfo currChannelListInfo + = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + /* + * Create a Union of occupied channel list learnt by the DUT along + * with the Neighbor report Channels. This increases the chances of + * the DUT to get a candidate AP while roaming even if the Neighbor + * Report is not able to provide sufficient information. + */ + if (pMac->scan.occupiedChannels[sessionId].numChannels) + { + csrNeighborRoamMergeChannelLists(pMac, + &pMac->scan.occupiedChannels[sessionId].channelList[0], + pMac->scan.occupiedChannels[sessionId].numChannels, + inPtr, + inNumChannels, + &mergedOutputNumOfChannels); + inNumChannels = mergedOutputNumOfChannels; + } + if (eCSR_BAND_24 == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (CSR_IS_CHANNEL_24GHZ(inPtr[i]) + && csrRoamIsChannelValid(pMac, inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else if (eCSR_BAND_5G == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + /* Add 5G Non-DFS channel */ + if (CSR_IS_CHANNEL_5GHZ(inPtr[i]) && + csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else if (eCSR_BAND_ALL == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Invalid band, No operation carried out (Band %d)", eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + /* + * if roaming within band is enabled, then select only the + * in band channels . + * This is required only if the band capability is set to ALL, + * E.g., if band capability is only 2.4G then all the channels in the + * list are already filtered for 2.4G channels, hence ignore this check + */ + if ((eCSR_BAND_ALL == eBand) && CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByCurrentBand( + pMac, + sessionId, + ChannelList, + outNumChannels, + tmpChannelList, + &outNumChannels); + vos_mem_copy(ChannelList, + tmpChannelList, outNumChannels); + } + /* Prepare final roam scan channel list */ + if(outNumChannels) + { + /* Clear the channel list first */ + if (NULL != currChannelListInfo->ChannelList) + { + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + } + currChannelListInfo->ChannelList + = vos_mem_malloc(outNumChannels * sizeof(tANI_U8)); + if (NULL == currChannelListInfo->ChannelList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "Failed to allocate memory for roam scan channel list"); + currChannelListInfo->numOfChannels = 0; + return VOS_STATUS_E_RESOURCES; + } + vos_mem_copy(currChannelListInfo->ChannelList, + ChannelList, outNumChannels); + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +eHalStatus csrSetBand(tHalHandle hHal, tANI_U8 sessionId, eCsrBand eBand) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + if (CSR_IS_PHY_MODE_A_ONLY(pMac) && + (eBand == eCSR_BAND_24)) + { + /* DOT11 mode configured to 11a only and received + request to change the band to 2.4 GHz */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to set band cfg80211 = %u, band = %u", + pMac->roam.configParam.uCfgDot11Mode, eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + if ((CSR_IS_PHY_MODE_B_ONLY(pMac) || + CSR_IS_PHY_MODE_G_ONLY(pMac)) && + (eBand == eCSR_BAND_5G)) + { + /* DOT11 mode configured to 11b/11g only and received + request to change the band to 5 GHz */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to set band dot11mode = %u, band = %u", + pMac->roam.configParam.uCfgDot11Mode, eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Band changed to %u (0 - ALL, 1 - 2.4 GHZ, 2 - 5GHZ)", eBand); + pMac->roam.configParam.eBand = eBand; + pMac->roam.configParam.bandCapability = eBand; + csrScanGetSupportedChannels( pMac ); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) +#endif + csrUpdateBgScanConfigIniChannelList(pMac, sessionId, eBand); +#endif + status = csrInitGetChannels( pMac ); + if (eHAL_STATUS_SUCCESS == status) + csrInitChannelList( hHal ); + return status; +} + + +/* The funcns csrConvertCBIniValueToPhyCBState and csrConvertPhyCBStateToIniValue have been + * introduced to convert the ini value to the ENUM used in csr and MAC for CB state + * Ideally we should have kept the ini value and enum value same and representing the same + * cb values as in 11n standard i.e. + * Set to 1 (SCA) if the secondary channel is above the primary channel + * Set to 3 (SCB) if the secondary channel is below the primary channel + * Set to 0 (SCN) if no secondary channel is present + * However, since our driver is already distributed we will keep the ini definition as it is which is: + * 0 - secondary none + * 1 - secondary LOW + * 2 - secondary HIGH + * and convert to enum value used within the driver in csrChangeDefaultConfigParam using this funcn + * The enum values are as follows: + * PHY_SINGLE_CHANNEL_CENTERED = 0 + * PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1 + * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + */ +ePhyChanBondState csrConvertCBIniValueToPhyCBState(v_U32_t cbIniValue) +{ + + ePhyChanBondState phyCbState; + switch (cbIniValue) { + // secondary none + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + phyCbState = PHY_SINGLE_CHANNEL_CENTERED; + break; + // secondary LOW + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + // secondary HIGH + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + break; +#endif + default: + // If an invalid value is passed, disable CHANNEL BONDING + phyCbState = PHY_SINGLE_CHANNEL_CENTERED; + break; + } + return phyCbState; +} + +v_U32_t csrConvertPhyCBStateToIniValue(ePhyChanBondState phyCbState) +{ + + v_U32_t cbIniValue; + switch (phyCbState) { + // secondary none + case PHY_SINGLE_CHANNEL_CENTERED: + cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED; + break; + // secondary LOW + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + // secondary HIGH + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + break; +#endif + default: + // return some invalid value + cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX; + break; + } + return cbIniValue; +} + +eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pParam) + { + pMac->roam.configParam.pkt_err_disconn_th = pParam->pkt_err_disconn_th; + pMac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode; + pMac->roam.configParam.Is11eSupportEnabled = pParam->Is11eSupportEnabled; + pMac->roam.configParam.FragmentationThreshold = pParam->FragmentationThreshold; + pMac->roam.configParam.Is11dSupportEnabled = pParam->Is11dSupportEnabled; + pMac->roam.configParam.Is11dSupportEnabledOriginal = pParam->Is11dSupportEnabled; + pMac->roam.configParam.Is11hSupportEnabled = pParam->Is11hSupportEnabled; + + pMac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode; + pMac->roam.configParam.fAllowMCCGODiffBI = pParam->fAllowMCCGODiffBI; + + /* channelBondingMode5GHz plays a dual role right now + * INFRA STA will use this non zero value as CB enabled and SOFTAP will use this non-zero value to determine the secondary channel offset + * This is how channelBondingMode5GHz works now and this is kept intact to avoid any cfg.ini change + */ + if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI) + { + smsLog( pMac, LOGW, "Invalid CB value from ini in 2.4GHz band %d, CB DISABLED", pParam->channelBondingMode24GHz); + } + pMac->roam.configParam.channelBondingMode24GHz = csrConvertCBIniValueToPhyCBState(pParam->channelBondingMode24GHz); + if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI) + { + smsLog( pMac, LOGW, "Invalid CB value from ini in 5GHz band %d, CB DISABLED", pParam->channelBondingMode5GHz); + } + pMac->roam.configParam.channelBondingMode5GHz = csrConvertCBIniValueToPhyCBState(pParam->channelBondingMode5GHz); + pMac->roam.configParam.RTSThreshold = pParam->RTSThreshold; + pMac->roam.configParam.phyMode = pParam->phyMode; + pMac->roam.configParam.shortSlotTime = pParam->shortSlotTime; + pMac->roam.configParam.HeartbeatThresh24 = pParam->HeartbeatThresh24; + pMac->roam.configParam.HeartbeatThresh50 = pParam->HeartbeatThresh50; + pMac->roam.configParam.ProprietaryRatesEnabled = pParam->ProprietaryRatesEnabled; + pMac->roam.configParam.TxRate = pParam->TxRate; + pMac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24; + pMac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G; + pMac->roam.configParam.bandCapability = pParam->bandCapability; + pMac->roam.configParam.cbChoice = pParam->cbChoice; + pMac->roam.configParam.bgScanInterval = pParam->bgScanInterval; + pMac->roam.configParam.disableAggWithBtc = pParam->disableAggWithBtc; + + pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop = + pParam->neighborRoamConfig.delay_before_vdev_stop; + + //if HDD passed down non zero values then only update, + //otherwise keep using the defaults + if (pParam->initial_scan_no_dfs_chnl) { + pMac->roam.configParam.initial_scan_no_dfs_chnl = + pParam->initial_scan_no_dfs_chnl; + } + if (pParam->nInitialDwellTime) + { + pMac->roam.configParam.nInitialDwellTime = + pParam->nInitialDwellTime; + } + if (pParam->nActiveMaxChnTime) + { + pMac->roam.configParam.nActiveMaxChnTime = pParam->nActiveMaxChnTime; + cfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + pParam->nActiveMaxChnTime); + } + if (pParam->nActiveMinChnTime) + { + pMac->roam.configParam.nActiveMinChnTime = pParam->nActiveMinChnTime; + cfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + pParam->nActiveMinChnTime); + } + if (pParam->nPassiveMaxChnTime) + { + pMac->roam.configParam.nPassiveMaxChnTime = pParam->nPassiveMaxChnTime; + cfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pParam->nPassiveMaxChnTime); + } + if (pParam->nPassiveMinChnTime) + { + pMac->roam.configParam.nPassiveMinChnTime = pParam->nPassiveMinChnTime; + cfgSetInt(pMac, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + pParam->nPassiveMinChnTime); + } + if (pParam->nActiveMaxChnTimeBtc) + { + pMac->roam.configParam.nActiveMaxChnTimeBtc = pParam->nActiveMaxChnTimeBtc; + } + if (pParam->nActiveMinChnTimeBtc) + { + pMac->roam.configParam.nActiveMinChnTimeBtc = pParam->nActiveMinChnTimeBtc; + } +#ifdef WLAN_AP_STA_CONCURRENCY + if (pParam->nActiveMaxChnTimeConc) + { + pMac->roam.configParam.nActiveMaxChnTimeConc = pParam->nActiveMaxChnTimeConc; + } + if (pParam->nActiveMinChnTimeConc) + { + pMac->roam.configParam.nActiveMinChnTimeConc = pParam->nActiveMinChnTimeConc; + } + if (pParam->nPassiveMaxChnTimeConc) + { + pMac->roam.configParam.nPassiveMaxChnTimeConc = pParam->nPassiveMaxChnTimeConc; + } + if (pParam->nPassiveMinChnTimeConc) + { + pMac->roam.configParam.nPassiveMinChnTimeConc = pParam->nPassiveMinChnTimeConc; + } + if (pParam->nRestTimeConc) + { + pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc; + } + if (pParam->nNumStaChanCombinedConc) + { + pMac->roam.configParam.nNumStaChanCombinedConc = pParam->nNumStaChanCombinedConc; + } + if (pParam->nNumP2PChanCombinedConc) + { + pMac->roam.configParam.nNumP2PChanCombinedConc = pParam->nNumP2PChanCombinedConc; + } +#endif + //if upper layer wants to disable idle scan altogether set it to 0 + if (pParam->impsSleepTime) + { + //Change the unit from second to microsecond + tANI_U32 impsSleepTime = + pParam->impsSleepTime * VOS_TIMER_TO_SEC_UNIT; + + if(CSR_IDLE_SCAN_NO_PS_INTERVAL_MIN <= impsSleepTime) + { + pMac->roam.configParam.impsSleepTime = impsSleepTime; + } + else + { + pMac->roam.configParam.impsSleepTime = CSR_IDLE_SCAN_NO_PS_INTERVAL; + } + } + else + { + pMac->roam.configParam.impsSleepTime = 0; + } + pMac->roam.configParam.eBand = pParam->eBand; + pMac->roam.configParam.uCfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(NULL, pMac->roam.configParam.phyMode, + pMac->roam.configParam.ProprietaryRatesEnabled); + //if HDD passed down non zero values for age params, then only update, + //otherwise keep using the defaults + if (pParam->nScanResultAgeCount) + { + pMac->roam.configParam.agingCount = pParam->nScanResultAgeCount; + } + if(pParam->scanAgeTimeNCNPS) + { + pMac->roam.configParam.scanAgeTimeNCNPS = pParam->scanAgeTimeNCNPS; + } + if(pParam->scanAgeTimeNCPS) + { + pMac->roam.configParam.scanAgeTimeNCPS = pParam->scanAgeTimeNCPS; + } + if(pParam->scanAgeTimeCNPS) + { + pMac->roam.configParam.scanAgeTimeCNPS = pParam->scanAgeTimeCNPS; + } + if(pParam->scanAgeTimeCPS) + { + pMac->roam.configParam.scanAgeTimeCPS = pParam->scanAgeTimeCPS; + } + + csrAssignRssiForCategory(pMac, CSR_BEST_RSSI_VALUE, pParam->bCatRssiOffset); + pMac->roam.configParam.nRoamingTime = pParam->nRoamingTime; + pMac->roam.configParam.fEnforce11dChannels = pParam->fEnforce11dChannels; + pMac->roam.configParam.fSupplicantCountryCodeHasPriority = pParam->fSupplicantCountryCodeHasPriority; + pMac->roam.configParam.fEnforceCountryCodeMatch = pParam->fEnforceCountryCodeMatch; + pMac->roam.configParam.fEnforceDefaultDomain = pParam->fEnforceDefaultDomain; + pMac->roam.configParam.vccRssiThreshold = pParam->vccRssiThreshold; + pMac->roam.configParam.vccUlMacLossThreshold = pParam->vccUlMacLossThreshold; + pMac->roam.configParam.IsIdleScanEnabled = pParam->IsIdleScanEnabled; + pMac->roam.configParam.statsReqPeriodicity = pParam->statsReqPeriodicity; + pMac->roam.configParam.statsReqPeriodicityInPS = pParam->statsReqPeriodicityInPS; + //Assign this before calling CsrInit11dInfo + pMac->roam.configParam.nTxPowerCap = pParam->nTxPowerCap; + if( csrIs11dSupported( pMac ) ) + { + status = CsrInit11dInfo(pMac, &pParam->Csr11dinfo); + } + else + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + + /* Initialize the power + channel information if 11h is enabled. + If 11d is enabled this information has already been initialized */ + if( csrIs11hSupported( pMac ) && !csrIs11dSupported( pMac ) ) + { + csrInitChannelPowerList(pMac, &pParam->Csr11dinfo); + } + + +#ifdef WLAN_FEATURE_VOWIFI_11R + vos_mem_copy(&pMac->roam.configParam.csr11rConfig, + &pParam->csr11rConfig, sizeof(tCsr11rConfigParams)); + smsLog( pMac, LOG1, "IsFTResourceReqSupp = %d", pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->roam.configParam.isFastTransitionEnabled = pParam->isFastTransitionEnabled; + pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff; + pMac->roam.configParam.nImmediateRoamRssiDiff = pParam->nImmediateRoamRssiDiff; + smsLog( pMac, LOG1, "nImmediateRoamRssiDiff = %d", + pMac->roam.configParam.nImmediateRoamRssiDiff ); + pMac->roam.configParam.nRoamPrefer5GHz = pParam->nRoamPrefer5GHz; + pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand; + pMac->roam.configParam.isWESModeEnabled = pParam->isWESModeEnabled; + pMac->roam.configParam.nProbes = pParam->nProbes; + pMac->roam.configParam.nRoamScanHomeAwayTime = pParam->nRoamScanHomeAwayTime; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->roam.configParam.isRoamOffloadScanEnabled = pParam->isRoamOffloadScanEnabled; + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = pParam->bFastRoamInConIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled; + pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled; +#endif + +#ifdef FEATURE_WLAN_ESE + pMac->roam.configParam.isEseIniFeatureEnabled = pParam->isEseIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pMac->roam.configParam.neighborRoamConfig, + &pParam->neighborRoamConfig, sizeof(tCsrNeighborRoamConfigParams)); + smsLog( pMac, LOG1, "nNeighborScanTimerPerioid = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod); + smsLog( pMac, LOG1, "nNeighborReassocRssiThreshold = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold); + smsLog( pMac, LOG1, "nNeighborLookupRssiThreshold = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold); + smsLog( pMac, LOG1, "nOpportunisticThresholdDiff = %d", pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff); + smsLog( pMac, LOG1, "nRoamRescanRssiDiff = %d", pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff); + smsLog( pMac, LOG1, "nNeighborScanMinChanTime = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime); + smsLog( pMac, LOG1, "nNeighborScanMaxChanTime = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime); + smsLog( pMac, LOG1, "nMaxNeighborRetries = %d", pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries); + smsLog( pMac, LOG1, "nNeighborResultsRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod); + smsLog( pMac, LOG1, "nEmptyScanRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod); + { + int i; + smsLog( pMac, LOG1, FL("Num of Channels in CFG Channel List: %d"), pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + for( i=0; i< pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; i++) + { + smsLog( pMac, LOG1, "%d ", pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[i] ); + } + } + smsLog( pMac, LOG1, "nRoamBmissFirstBcnt = %d", pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt); + smsLog( pMac, LOG1, "nRoamBmissFinalBcnt = %d", pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt); + smsLog( pMac, LOG1, "nRoamBeaconRssiWeight = %d", pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight); +#endif + pMac->roam.configParam.addTSWhenACMIsOff = pParam->addTSWhenACMIsOff; + pMac->scan.fValidateList = pParam->fValidateList; + pMac->scan.fEnableBypass11d = pParam->fEnableBypass11d; + pMac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan; + pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime; + pMac->roam.configParam.fScanTwice = pParam->fScanTwice; + pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl; + pMac->scan.scanBandPreference = pParam->scanBandPreference; + /* This parameter is not available in cfg and not passed from upper layers. Instead it is initialized here + * This paramtere is used in concurrency to determine if there are concurrent active sessions. + * Is used as a temporary fix to disconnect all active sessions when BMPS enabled so the active session if Infra STA + * will automatically connect back and resume BMPS since resume BMPS is not working when moving from concurrent to + * single session + */ + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + pMac->roam.configParam.doBMPSWorkaround = 0; + +#ifdef WLAN_FEATURE_11AC + pMac->roam.configParam.nVhtChannelWidth = pParam->nVhtChannelWidth; + pMac->roam.configParam.txBFEnable= pParam->enableTxBF; + pMac->roam.configParam.txBFCsnValue = pParam->txBFCsnValue; + pMac->roam.configParam.enable2x2= pParam->enable2x2; + pMac->roam.configParam.enableVhtFor24GHz = pParam->enableVhtFor24GHz; + pMac->roam.configParam.txMuBformee= pParam->enableMuBformee; + pMac->roam.configParam.enableVhtpAid = pParam->enableVhtpAid; + pMac->roam.configParam.enableVhtGid = pParam->enableVhtGid; +#endif + pMac->roam.configParam.enableAmpduPs = pParam->enableAmpduPs; + pMac->roam.configParam.enableHtSmps = pParam->enableHtSmps; + pMac->roam.configParam.htSmps= pParam->htSmps; + pMac->roam.configParam.txLdpcEnable = pParam->enableTxLdpc; + + pMac->roam.configParam.isAmsduSupportInAMPDU = pParam->isAmsduSupportInAMPDU; + pMac->roam.configParam.nSelect5GHzMargin = pParam->nSelect5GHzMargin; + pMac->roam.configParam.isCoalesingInIBSSAllowed = + pParam->isCoalesingInIBSSAllowed; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + pMac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode; +#endif + pMac->roam.configParam.allowDFSChannelRoam = pParam->allowDFSChannelRoam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pMac->roam.configParam.isRoamOffloadEnabled = + pParam->isRoamOffloadEnabled; +#endif + pMac->roam.configParam.obssEnabled = pParam->obssEnabled; + } + + return status; +} + +eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if(pParam) + { + pParam->WMMSupportMode = pMac->roam.configParam.WMMSupportMode; + pParam->Is11eSupportEnabled = pMac->roam.configParam.Is11eSupportEnabled; + pParam->FragmentationThreshold = pMac->roam.configParam.FragmentationThreshold; + pParam->Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabled; + pParam->Is11dSupportEnabledOriginal = pMac->roam.configParam.Is11dSupportEnabledOriginal; + pParam->Is11hSupportEnabled = pMac->roam.configParam.Is11hSupportEnabled; + pParam->channelBondingMode24GHz = csrConvertPhyCBStateToIniValue(pMac->roam.configParam.channelBondingMode24GHz); + pParam->channelBondingMode5GHz = csrConvertPhyCBStateToIniValue(pMac->roam.configParam.channelBondingMode5GHz); + pParam->RTSThreshold = pMac->roam.configParam.RTSThreshold; + pParam->phyMode = pMac->roam.configParam.phyMode; + pParam->shortSlotTime = pMac->roam.configParam.shortSlotTime; + pParam->HeartbeatThresh24 = pMac->roam.configParam.HeartbeatThresh24; + pParam->HeartbeatThresh50 = pMac->roam.configParam.HeartbeatThresh50; + pParam->ProprietaryRatesEnabled = pMac->roam.configParam.ProprietaryRatesEnabled; + pParam->TxRate = pMac->roam.configParam.TxRate; + pParam->AdHocChannel24 = pMac->roam.configParam.AdHocChannel24; + pParam->AdHocChannel5G = pMac->roam.configParam.AdHocChannel5G; + pParam->bandCapability = pMac->roam.configParam.bandCapability; + pParam->cbChoice = pMac->roam.configParam.cbChoice; + pParam->bgScanInterval = pMac->roam.configParam.bgScanInterval; + pParam->nActiveMaxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pParam->nActiveMinChnTime = pMac->roam.configParam.nActiveMinChnTime; + pParam->nPassiveMaxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + pParam->nPassiveMinChnTime = pMac->roam.configParam.nPassiveMinChnTime; + pParam->nActiveMaxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pParam->nActiveMinChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + pParam->disableAggWithBtc = pMac->roam.configParam.disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + pParam->nActiveMaxChnTimeConc = pMac->roam.configParam.nActiveMaxChnTimeConc; + pParam->nActiveMinChnTimeConc = pMac->roam.configParam.nActiveMinChnTimeConc; + pParam->nPassiveMaxChnTimeConc = pMac->roam.configParam.nPassiveMaxChnTimeConc; + pParam->nPassiveMinChnTimeConc = pMac->roam.configParam.nPassiveMinChnTimeConc; + pParam->nRestTimeConc = pMac->roam.configParam.nRestTimeConc; + pParam->nNumStaChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + pParam->nNumP2PChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; +#endif + //Change the unit from microsecond to second + pParam->impsSleepTime = + pMac->roam.configParam.impsSleepTime / VOS_TIMER_TO_SEC_UNIT; + pParam->eBand = pMac->roam.configParam.eBand; + pParam->nScanResultAgeCount = pMac->roam.configParam.agingCount; + pParam->scanAgeTimeNCNPS = pMac->roam.configParam.scanAgeTimeNCNPS; + pParam->scanAgeTimeNCPS = pMac->roam.configParam.scanAgeTimeNCPS; + pParam->scanAgeTimeCNPS = pMac->roam.configParam.scanAgeTimeCNPS; + pParam->scanAgeTimeCPS = pMac->roam.configParam.scanAgeTimeCPS; + pParam->bCatRssiOffset = pMac->roam.configParam.bCatRssiOffset; + pParam->nRoamingTime = pMac->roam.configParam.nRoamingTime; + pParam->fEnforce11dChannels = pMac->roam.configParam.fEnforce11dChannels; + pParam->fSupplicantCountryCodeHasPriority = pMac->roam.configParam.fSupplicantCountryCodeHasPriority; + pParam->fEnforceCountryCodeMatch = pMac->roam.configParam.fEnforceCountryCodeMatch; + pParam->fEnforceDefaultDomain = pMac->roam.configParam.fEnforceDefaultDomain; + pParam->vccRssiThreshold = pMac->roam.configParam.vccRssiThreshold; + pParam->vccUlMacLossThreshold = pMac->roam.configParam.vccUlMacLossThreshold; + pParam->IsIdleScanEnabled = pMac->roam.configParam.IsIdleScanEnabled; + pParam->nTxPowerCap = pMac->roam.configParam.nTxPowerCap; + pParam->statsReqPeriodicity = pMac->roam.configParam.statsReqPeriodicity; + pParam->statsReqPeriodicityInPS = pMac->roam.configParam.statsReqPeriodicityInPS; + pParam->addTSWhenACMIsOff = pMac->roam.configParam.addTSWhenACMIsOff; + pParam->fValidateList = pMac->roam.configParam.fValidateList; + pParam->fEnableBypass11d = pMac->scan.fEnableBypass11d; + pParam->fEnableDFSChnlScan = pMac->scan.fEnableDFSChnlScan; + pParam->fScanTwice = pMac->roam.configParam.fScanTwice; + pParam->fFirstScanOnly2GChnl = pMac->scan.fFirstScanOnly2GChnl; + pParam->fEnableMCCMode = pMac->roam.configParam.fenableMCCMode; + pParam->fAllowMCCGODiffBI = pMac->roam.configParam.fAllowMCCGODiffBI; + pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime; + pParam->scanBandPreference = pMac->scan.scanBandPreference; +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pParam->neighborRoamConfig, + &pMac->roam.configParam.neighborRoamConfig, + sizeof(tCsrNeighborRoamConfigParams)); +#endif +#ifdef WLAN_FEATURE_11AC + pParam->nVhtChannelWidth = pMac->roam.configParam.nVhtChannelWidth; + pParam->enableTxBF = pMac->roam.configParam.txBFEnable; + pParam->txBFCsnValue = pMac->roam.configParam.txBFCsnValue; + pParam->enableMuBformee = pMac->roam.configParam.txMuBformee; + pParam->enableVhtFor24GHz = pMac->roam.configParam.enableVhtFor24GHz; + pParam->enable2x2 = pMac->roam.configParam.enable2x2; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + vos_mem_copy(&pMac->roam.configParam.csr11rConfig, + &pParam->csr11rConfig, sizeof(tCsr11rConfigParams)); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pParam->isFastTransitionEnabled = pMac->roam.configParam.isFastTransitionEnabled; + pParam->RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff; + pParam->nImmediateRoamRssiDiff = pMac->roam.configParam.nImmediateRoamRssiDiff; + pParam->nRoamPrefer5GHz = pMac->roam.configParam.nRoamPrefer5GHz; + pParam->nRoamIntraBand = pMac->roam.configParam.nRoamIntraBand; + pParam->isWESModeEnabled = pMac->roam.configParam.isWESModeEnabled; + pParam->nProbes = pMac->roam.configParam.nProbes; + pParam->nRoamScanHomeAwayTime = pMac->roam.configParam.nRoamScanHomeAwayTime; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pParam->isRoamOffloadScanEnabled = pMac->roam.configParam.isRoamOffloadScanEnabled; + pParam->bFastRoamInConIniFeatureEnabled = pMac->roam.configParam.bFastRoamInConIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled; +#endif + +#ifdef FEATURE_WLAN_ESE + pParam->isEseIniFeatureEnabled = pMac->roam.configParam.isEseIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pParam->neighborRoamConfig, + &pMac->roam.configParam.neighborRoamConfig, + sizeof(tCsrNeighborRoamConfigParams)); + { + int i; + smsLog( pMac, LOG1, FL("Num of Channels in CFG Channel List: %d"), pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + for( i=0; i< pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; i++) + { + smsLog( pMac, LOG1, "%d ", pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[i] ); + } + } +#endif + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + pParam->cc_switch_mode = pMac->roam.configParam.cc_switch_mode; +#endif + pParam->enableTxLdpc = pMac->roam.configParam.txLdpcEnable; + + pParam->isAmsduSupportInAMPDU = pMac->roam.configParam.isAmsduSupportInAMPDU; + pParam->nSelect5GHzMargin = pMac->roam.configParam.nSelect5GHzMargin; + + pParam->isCoalesingInIBSSAllowed = + pMac->roam.configParam.isCoalesingInIBSSAllowed; + pParam->allowDFSChannelRoam = + pMac->roam.configParam.allowDFSChannelRoam; + pParam->nInitialDwellTime = + pMac->roam.configParam.nInitialDwellTime; + pParam->initial_scan_no_dfs_chnl = + pMac->roam.configParam.initial_scan_no_dfs_chnl; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pParam->isRoamOffloadEnabled = + pMac->roam.configParam.isRoamOffloadEnabled; +#endif + csrSetChannels(pMac, pParam); + + pParam->obssEnabled = pMac->roam.configParam.obssEnabled; + + status = eHAL_STATUS_SUCCESS; + } + return (status); +} + +eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRestartNeeded = eANI_BOOLEAN_FALSE; + eCsrPhyMode newPhyMode = eCSR_DOT11_MODE_AUTO; + do + { + if(eCSR_BAND_24 == eBand) + { + if(CSR_IS_RADIO_A_ONLY(pMac)) break; + if((eCSR_DOT11_MODE_11a & phyMode) || (eCSR_DOT11_MODE_11a_ONLY & phyMode)) break; + } + if(eCSR_BAND_5G == eBand) + { + if(CSR_IS_RADIO_BG_ONLY(pMac)) break; + if((eCSR_DOT11_MODE_11b & phyMode) || (eCSR_DOT11_MODE_11b_ONLY & phyMode) || + (eCSR_DOT11_MODE_11g & phyMode) || (eCSR_DOT11_MODE_11g_ONLY & phyMode) + ) + { + break; + } + } + if((0 == phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode)) + { + newPhyMode = eCSR_DOT11_MODE_TAURUS; + } + else if(eCSR_DOT11_MODE_AUTO & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_AUTO; + } + else + { + //Check for dual band and higher capability first + if(eCSR_DOT11_MODE_11n_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11n_ONLY != phyMode) break; + newPhyMode = eCSR_DOT11_MODE_11n_ONLY; + } + else if(eCSR_DOT11_MODE_11a_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11a_ONLY != phyMode) break; + if(eCSR_BAND_24 == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11a_ONLY; + eBand = eCSR_BAND_5G; + } + else if(eCSR_DOT11_MODE_11g_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11g_ONLY != phyMode) break; + if(eCSR_BAND_5G == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11g_ONLY; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11b_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11b_ONLY != phyMode) break; + if(eCSR_BAND_5G == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11b_ONLY; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11n & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11n; + } + else if(eCSR_DOT11_MODE_abg & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_abg; + } + else if(eCSR_DOT11_MODE_11a & phyMode) + { + if((eCSR_DOT11_MODE_11g & phyMode) || (eCSR_DOT11_MODE_11b & phyMode)) + { + if(eCSR_BAND_ALL == eBand) + { + newPhyMode = eCSR_DOT11_MODE_abg; + } + else + { + //bad setting + break; + } + } + else + { + newPhyMode = eCSR_DOT11_MODE_11a; + eBand = eCSR_BAND_5G; + } + } + else if(eCSR_DOT11_MODE_11g & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11g; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11b & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11b; + eBand = eCSR_BAND_24; + } + else + { + //We will never be here + smsLog( pMac, LOGE, FL(" cannot recognize the phy mode 0x%08X"), phyMode ); + newPhyMode = eCSR_DOT11_MODE_AUTO; + } + } + //Done validating + status = eHAL_STATUS_SUCCESS; + //Now we need to check whether a restart is needed. + if(eBand != pMac->roam.configParam.eBand) + { + fRestartNeeded = eANI_BOOLEAN_TRUE; + break; + } + if(newPhyMode != pMac->roam.configParam.phyMode) + { + fRestartNeeded = eANI_BOOLEAN_TRUE; + break; + } + }while(0); + if(HAL_STATUS_SUCCESS(status)) + { + pMac->roam.configParam.eBand = eBand; + pMac->roam.configParam.phyMode = newPhyMode; + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestartNeeded; + } + } + return (status); +} + +void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList ) +{ + tANI_U8 Index; + tANI_U8 cChannels; + // for dual band NICs, don't need to trim the channel list.... + if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) + { + // 2.4 GHz band operation requires the channel list to be trimmed to + // the 2.4 GHz channels only... + if ( CSR_IS_24_BAND_ONLY( pMac ) ) + { + for( Index = 0, cChannels = 0; Index < pChannelList->numChannels; + Index++ ) + { + if ( CSR_IS_CHANNEL_24GHZ(pChannelList->channelList[ Index ]) ) + { + pChannelList->channelList[ cChannels ] = pChannelList->channelList[ Index ]; + cChannels++; + } + } + // Cleanup the rest of channels. Note we only need to clean up the channels if we had + // to trim the list. Calling palZeroMemory() with a 0 size is going to throw asserts on + // the debug builds so let's be a bit smarter about that. Zero out the reset of the channels + // only if we need to. + // + // The amount of memory to clear is the number of channesl that we trimmed + // (pChannelList->numChannels - cChannels) times the size of a channel in the structure. + + if ( pChannelList->numChannels > cChannels ) + { + vos_mem_set(&pChannelList->channelList[ cChannels ], + sizeof( pChannelList->channelList[ 0 ] ) * + ( pChannelList->numChannels - cChannels ), 0); + } + + pChannelList->numChannels = cChannels; + } + else if ( CSR_IS_5G_BAND_ONLY( pMac ) ) + { + for ( Index = 0, cChannels = 0; Index < pChannelList->numChannels; Index++ ) + { + if ( CSR_IS_CHANNEL_5GHZ(pChannelList->channelList[ Index ]) ) + { + pChannelList->channelList[ cChannels ] = pChannelList->channelList[ Index ]; + cChannels++; + } + } + // Cleanup the rest of channels. Note we only need to clean up the channels if we had + // to trim the list. Calling palZeroMemory() with a 0 size is going to throw asserts on + // the debug builds so let's be a bit smarter about that. Zero out the reset of the channels + // only if we need to. + // + // The amount of memory to clear is the number of channesl that we trimmed + // (pChannelList->numChannels - cChannels) times the size of a channel in the structure. + if ( pChannelList->numChannels > cChannels ) + { + vos_mem_set(&pChannelList->channelList[ cChannels ], + sizeof( pChannelList->channelList[ 0 ] ) * + ( pChannelList->numChannels - cChannels ), 0); + } + + pChannelList->numChannels = cChannels; + } + } +} +#define INFRA_AP_DEFAULT_CHANNEL 6 +VOS_STATUS csrIsValidChannel(tpAniSirGlobal pMac, tANI_U8 chnNum) +{ + tANI_U8 index= 0; + VOS_STATUS status = VOS_STATUS_E_NOSUPPORT; + + /* regulatory check */ + for (index=0; index < pMac->scan.base20MHzChannels.numChannels ;index++) + { + if(pMac->scan.base20MHzChannels.channelList[ index ] == chnNum){ + status = VOS_STATUS_SUCCESS; + break; + } + } + + if (status == VOS_STATUS_SUCCESS) + { + /* dfs nol */ + for (index = 0; + index < pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels; + index++) + { + tSapDfsNolInfo* dfsChan = + &pMac->sap.SapDfsInfo.sapDfsChannelNolList[index]; + if ((dfsChan->dfs_channel_number == chnNum) && + (dfsChan->radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("channel %d is in dfs nol"), + chnNum); + status = VOS_STATUS_E_FAILURE; + break; + } + } + } + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("channel %d is not available"), + chnNum); + } + + return status; +} + + +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 num20MHzChannelsFound = 0; + VOS_STATUS vosStatus; + tANI_U8 Index = 0; + tANI_U8 num40MHzChannelsFound = 0; + + + //TODO: this interface changed to include the 40MHz channel list + // this needs to be tied into the adapter structure somehow and referenced appropriately for CB operation + // Read the scan channel list (including the power limit) from EEPROM + vosStatus = vos_nv_getChannelListWithPower( pMac->scan.defaultPowerTable, &num20MHzChannelsFound, + pMac->scan.defaultPowerTable40MHz, &num40MHzChannelsFound); + if ( (VOS_STATUS_SUCCESS != vosStatus) || (num20MHzChannelsFound == 0) ) + { + smsLog( pMac, LOGE, FL("failed to get channels ")); + status = eHAL_STATUS_FAILURE; + } + else + { + if ( num20MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN ) + { + num20MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + pMac->scan.numChannelsDefault = num20MHzChannelsFound; + // Move the channel list to the global data + // structure -- this will be used as the scan list + for ( Index = 0; Index < num20MHzChannelsFound; Index++) + { + pMac->scan.base20MHzChannels.channelList[ Index ] = pMac->scan.defaultPowerTable[ Index ].chanId; + } + pMac->scan.base20MHzChannels.numChannels = num20MHzChannelsFound; + if(num40MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + num40MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + for ( Index = 0; Index < num40MHzChannelsFound; Index++) + { + pMac->scan.base40MHzChannels.channelList[ Index ] = pMac->scan.defaultPowerTable40MHz[ Index ].chanId; + } + pMac->scan.base40MHzChannels.numChannels = num40MHzChannelsFound; + } + return (status); +} +eHalStatus csrInitChannelList( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels); + csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + // Apply the base channel list, power info, and set the Country code... + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); + csrInitOperatingClasses(hHal); + return (status); +} +eHalStatus csrChangeConfigParams(tpAniSirGlobal pMac, + tCsrUpdateConfigParam *pUpdateConfigParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsr11dinfo *ps11dinfo = NULL; + ps11dinfo = &pUpdateConfigParam->Csr11dinfo; + status = CsrInit11dInfo(pMac, ps11dinfo); + return status; +} + +static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U8 index; + tANI_U32 count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + tANI_BOOLEAN applyConfig = TRUE; + + pMac->scan.currentCountryRSSI = -128; + if(!ps11dinfo) + { + return (status); + } + if ( ps11dinfo->Channels.numChannels && ( WNI_CFG_VALID_CHANNEL_LIST_LEN >= ps11dinfo->Channels.numChannels ) ) + { + pMac->scan.base20MHzChannels.numChannels = ps11dinfo->Channels.numChannels; + vos_mem_copy(pMac->scan.base20MHzChannels.channelList, + ps11dinfo->Channels.channelList, + ps11dinfo->Channels.numChannels); + } + else + { + //No change + return (eHAL_STATUS_SUCCESS); + } + //legacy maintenance + + vos_mem_copy(pMac->scan.countryCodeDefault, ps11dinfo->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + + + //Tush: at csropen get this initialized with default, during csr reset if this + // already set with some value no need initilaize with default again + if(0 == pMac->scan.countryCodeCurrent[0]) + { + vos_mem_copy(pMac->scan.countryCodeCurrent, ps11dinfo->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + // need to add the max power channel list + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if (pChanInfo != NULL) + { + vos_mem_set(pChanInfo, + sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN , + 0); + + pChanInfoStart = pChanInfo; + for(index = 0; index < ps11dinfo->Channels.numChannels; index++) + { + pChanInfo->firstChanNum = ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; + pChanInfo->maxTxPower = CSR_ROAM_MIN( ps11dinfo->ChnPower[index].maxtxPower, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } + //Only apply them to CFG when not in STOP state. Otherwise they will be applied later + if( HAL_STATUS_SUCCESS(status) ) + { + for( index = 0; index < CSR_ROAM_SESSION_MAX; index++ ) + { + if((CSR_IS_SESSION_VALID(pMac, index)) && CSR_IS_ROAM_STOP(pMac, index)) + { + applyConfig = FALSE; + } + } + + if(TRUE == applyConfig) + { + // Apply the base channel list, power info, and set the Country code... + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); + } + + } + return (status); +} +/* Initialize the Channel + Power List in the local cache and in the CFG */ +eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo) +{ + tANI_U8 index; + tANI_U32 count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + + if(!ps11dinfo || !pMac) + { + return eHAL_STATUS_FAILURE; + } + + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if (pChanInfo != NULL) + { + vos_mem_set(pChanInfo, + sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN, + 0); + pChanInfoStart = pChanInfo; + + for(index = 0; index < ps11dinfo->Channels.numChannels; index++) + { + pChanInfo->firstChanNum = ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; + pChanInfo->maxTxPower = CSR_ROAM_MIN( ps11dinfo->ChnPower[index].maxtxPower, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } + + return eHAL_STATUS_SUCCESS; +} + +//pCommand may be NULL +//Pass in sessionId in case pCommand is NULL. sessionId is not used in case pCommand is not NULL. +void csrRoamRemoveDuplicateCommand(tpAniSirGlobal pMac, tANI_U32 sessionId, tSmeCmd *pCommand, eCsrRoamReason eRoamReason) +{ + tListElem *pEntry, *pNextEntry; + tSmeCmd *pDupCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + csrLLLock( &pMac->sme.smeCmdPendingList ); + pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pNextEntry = csrLLNext( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); + pDupCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + // Remove the previous command if.. + // - the new roam command is for the same RoamReason... + // - the new roam command is a NewProfileList. + // - the new roam command is a Forced Dissoc + // - the new roam command is from an 802.11 OID (OID_SSID or OID_BSSID). + if ( + (pCommand && ( pCommand->sessionId == pDupCommand->sessionId ) && + ((pCommand->command == pDupCommand->command) && + /* This peermac check is requried for Softap/GO scenarios + * For STA scenario below OR check will suffice as pCommand will + * always be NULL for STA scenarios + */ + (vos_mem_compare(pDupCommand->u.roamCmd.peerMac, pCommand->u.roamCmd.peerMac, sizeof(v_MACADDR_t))) && + (pCommand->u.roamCmd.roamReason == pDupCommand->u.roamCmd.roamReason || + eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason || + eCsrHddIssued == pCommand->u.roamCmd.roamReason))) + || + //below the pCommand is NULL + ( (sessionId == pDupCommand->sessionId) && + (eSmeCommandRoam == pDupCommand->command) && + ((eCsrForcedDisassoc == eRoamReason) || + (eCsrHddIssued == eRoamReason)) + ) + ) + { + smsLog(pMac, LOGW, FL(" roamReason = %d"), pDupCommand->u.roamCmd.roamReason); + // Remove the 'stale' roam command from the pending list... + if(csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK )) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + } + pEntry = pNextEntry; + } + csrLLUnlock( &pMac->sme.smeCmdPendingList ); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pDupCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + //Tell caller that the command is cancelled + csrRoamCallCallback(pMac, pDupCommand->sessionId, NULL, pDupCommand->u.roamCmd.roamId, + eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE); + csrReleaseCommandRoam(pMac, pDupCommand); + } + csrLLClose(&localList); +} +eHalStatus csrRoamCallCallback(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus u1, eCsrRoamResult u2) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + tANI_U32 rssi = 0; + WLAN_VOS_DIAG_EVENT_DEF(connectionStatus, vos_event_wlan_status_payload_type); +#endif + tCsrRoamSession *pSession; + tDot11fBeaconIEs *beacon_ies = NULL; + tANI_U8 chan1, chan2; + ePhyChanBondState phy_state; + + if( CSR_IS_SESSION_VALID( pMac, sessionId) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + } + else + { + smsLog(pMac, LOGE, "Session ID:%d is not valid", sessionId); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + if (eANI_BOOLEAN_FALSE == pSession->sessionActive) + { + smsLog(pMac, LOG1, "%s Session is not Active", __func__); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG4, "Recieved RoamCmdStatus %d with Roam Result %d", u1, u2); + + if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1 && + eCSR_ROAM_RESULT_ASSOCIATED == u2 && pRoamInfo) + { + smsLog(pMac, LOGW, " Assoc complete result = %d statusCode = %d reasonCode = %d", u2, pRoamInfo->statusCode, pRoamInfo->reasonCode); + + beacon_ies = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + + if ((NULL != beacon_ies) && (NULL != pRoamInfo->pBssDesc)) { + status = csrParseBssDescriptionIEs((tHalHandle)pMac, + pRoamInfo->pBssDesc, + beacon_ies); + + /* now extract the phymode and center frequencies */ + + /* get the VHT OPERATION IE */ + if (beacon_ies->VHTOperation.present) { + + chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1; + chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2; + pRoamInfo->chan_info.info = MODE_11AC_VHT80; + + } else if (beacon_ies->HTInfo.present) { + + if (beacon_ies->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ) { + phy_state = beacon_ies->HTInfo.secondaryChannelOffset; + if (phy_state == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + + chan1 = beacon_ies->HTInfo.primaryChannel + + CSR_CB_CENTER_CHANNEL_OFFSET; + else if (phy_state == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + chan1 = beacon_ies->HTInfo.primaryChannel - + CSR_CB_CENTER_CHANNEL_OFFSET; + else + chan1 = beacon_ies->HTInfo.primaryChannel; + pRoamInfo->chan_info.info = MODE_11NA_HT40; + } else { + chan1 = beacon_ies->HTInfo.primaryChannel; + pRoamInfo->chan_info.info = MODE_11NA_HT20; + } + chan2 = 0; + } else { + chan1 = 0; + chan2 = 0; + pRoamInfo->chan_info.info = MODE_11A; + } + + if (0 != chan1) + pRoamInfo->chan_info.band_center_freq1 = + vos_chan_to_freq(chan1); + else + pRoamInfo->chan_info.band_center_freq1 = 0; + + if (0 != chan2) + pRoamInfo->chan_info.band_center_freq2 = + vos_chan_to_freq(chan2); + else + pRoamInfo->chan_info.band_center_freq2 = 0; + } + else { + pRoamInfo->chan_info.band_center_freq1 = 0; + pRoamInfo->chan_info.band_center_freq2 = 0; + pRoamInfo->chan_info.info = 0; + } + pRoamInfo->chan_info.chan_id = pRoamInfo->u.pConnectedProfile->operationChannel; + pRoamInfo->chan_info.mhz = vos_chan_to_freq(pRoamInfo->chan_info.chan_id); + pRoamInfo->chan_info.reg_info_1 = + (csrGetCfgMaxTxPower(pMac, pRoamInfo->chan_info.chan_id) << 16); + pRoamInfo->chan_info.reg_info_2 = + (csrGetCfgMaxTxPower(pMac, pRoamInfo->chan_info.chan_id) << 8); + vos_mem_free(beacon_ies); + } + + if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED) && (pSession->bRefAssocStartCnt)) { + /* + * Decrement bRefAssocStartCnt for FT reassoc failure. + * Reason: For FT reassoc failures, we first call + * csrRoamCallCallback before notifying a failed roam + * completion through csrRoamComplete. The latter in + * turn calls csrRoamProcessResults which tries to + * once again call csrRoamCallCallback if bRefAssocStartCnt + * is non-zero. Since this is redundant for FT reassoc + * failure, decrement bRefAssocStartCnt. + */ + pSession->bRefAssocStartCnt--; + } + + if(NULL != pSession->callback) + { + if( pRoamInfo ) + { + pRoamInfo->sessionId = (tANI_U8)sessionId; + /* + * the reasonCode will be passed to supplicant by cfg80211_disconnected. + * Based on the document, the reason code passed to supplicant needs to set + * to 0 if unknow. eSIR_BEACON_MISSED reason code is not recognizable so that + * we set to 0 instead. + */ + pRoamInfo->reasonCode = + (pRoamInfo->reasonCode == eSIR_BEACON_MISSED) ? + 0 : pRoamInfo->reasonCode; + } + /* avoid holding the global lock when making the roaming callback, original change came + from a raised CR (CR304874). Since this callback is in HDD a potential deadlock + is possible on other OS ports where the callback may need to take locks to protect + HDD state + UPDATE : revert this change but keep the comments here. Need to revisit as there are callbacks + that may actually depend on the lock being held */ + // TODO: revisit: sme_ReleaseGlobalLock( &pMac->sme ); + status = pSession->callback(pSession->pContext, pRoamInfo, roamId, u1, u2); + // TODO: revisit: sme_AcquireGlobalLock( &pMac->sme ); + } + //EVENT_WLAN_STATUS: eCSR_ROAM_ASSOCIATION_COMPLETION, + // eCSR_ROAM_LOSTLINK, eCSR_ROAM_DISASSOCIATED, +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + vos_mem_set(&connectionStatus, + sizeof(vos_event_wlan_status_payload_type), 0); + + if((eCSR_ROAM_ASSOCIATION_COMPLETION == u1) && (eCSR_ROAM_RESULT_ASSOCIATED == u2) && pRoamInfo) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_CONNECT; + connectionStatus.bssType = pRoamInfo->u.pConnectedProfile->BSSType; + + if(NULL != pRoamInfo->pBssDesc) + { + connectionStatus.rssi = pRoamInfo->pBssDesc->rssi * (-1); + connectionStatus.channel = pRoamInfo->pBssDesc->channelId; + } + if (ccmCfgSetInt(pMac, WNI_CFG_CURRENT_RSSI, connectionStatus.rssi, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) { + smsLog(pMac, LOGE, "Could not pass WNI_CFG_CURRENT_RSSI to Cfg"); + } + + connectionStatus.qosCapability = pRoamInfo->u.pConnectedProfile->qosConnection; + connectionStatus.authType = (v_U8_t)diagAuthTypeFromCSRType(pRoamInfo->u.pConnectedProfile->AuthType); + connectionStatus.encryptionType = (v_U8_t)diagEncTypeFromCSRType(pRoamInfo->u.pConnectedProfile->EncryptionType); + vos_mem_copy(connectionStatus.ssid, + pRoamInfo->u.pConnectedProfile->SSID.ssId, 6); + + connectionStatus.reason = eCSR_REASON_UNSPECIFIED; + vos_mem_copy(&pMac->sme.eventPayload, &connectionStatus, + sizeof(vos_event_wlan_status_payload_type)); + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS); + } + if((eCSR_ROAM_MIC_ERROR_IND == u1) || (eCSR_ROAM_RESULT_MIC_FAILURE == u2)) + { + vos_mem_copy(&connectionStatus, &pMac->sme.eventPayload, + sizeof(vos_event_wlan_status_payload_type)); + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_CURRENT_RSSI, &rssi))) + connectionStatus.rssi = rssi; + + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_MIC_ERROR; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS); + } + if(eCSR_ROAM_RESULT_FORCED == u2) + { + vos_mem_copy(&connectionStatus, &pMac->sme.eventPayload, + sizeof(vos_event_wlan_status_payload_type)); + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_CURRENT_RSSI, &rssi))) + connectionStatus.rssi = rssi; + + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS); + } + if(eCSR_ROAM_RESULT_DISASSOC_IND == u2) + { + vos_mem_copy(&connectionStatus, &pMac->sme.eventPayload, + sizeof(vos_event_wlan_status_payload_type)); + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_CURRENT_RSSI, &rssi))) + connectionStatus.rssi = rssi; + + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_DISASSOC; + if(pRoamInfo) + connectionStatus.reasonDisconnect = pRoamInfo->reasonCode; + + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS); + } + if(eCSR_ROAM_RESULT_DEAUTH_IND == u2) + { + vos_mem_copy(&connectionStatus, &pMac->sme.eventPayload, + sizeof(vos_event_wlan_status_payload_type)); + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_CURRENT_RSSI, &rssi))) + connectionStatus.rssi = rssi; + + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_DEAUTH; + if(pRoamInfo) + connectionStatus.reasonDisconnect = pRoamInfo->reasonCode; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + + return (status); +} +// Returns whether handoff is currently in progress or not +tANI_BOOLEAN csrRoamIsHandoffInProgress(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIsHandoffInProgress(pMac, sessionId); +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +eHalStatus csrRoamIssueDisassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, + eCsrRoamSubState NewSubstate, tANI_BOOLEAN fMICFailure ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_U16 reasonCode; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + //Restore AC weight in case we change it + if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" restore AC weights (%d-%d-%d-%d)"), pMac->roam.ucACWeights[0], pMac->roam.ucACWeights[1], + pMac->roam.ucACWeights[2], pMac->roam.ucACWeights[3]); + WLANTL_SetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + } + + if ( fMICFailure ) + { + reasonCode = eSIR_MAC_MIC_FAILURE_REASON; + } + else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) + { + reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON; + } + else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) + { + reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON; + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON" + " and set back NewSubstate")); + } + else + { + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if ( (csrRoamIsHandoffInProgress(pMac, sessionId)) && + (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) + { + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + vos_mem_copy(&bssId, + pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, + sizeof(tSirMacAddr)); + } + else +#endif + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + + smsLog(pMac, LOG2, FL("CSR Attempting to Disassociate Bssid="MAC_ADDRESS_STR + " subState = %s reason=%d"), + MAC_ADDR_ARRAY(bssId), macTraceGetcsrRoamSubState(NewSubstate), + reasonCode); + + csrRoamSubstateChange( pMac, NewSubstate, sessionId); + + status = csrSendMBDisassocReqMsg( pMac, sessionId, bssId, reasonCode ); + + if(HAL_STATUS_SUCCESS(status)) + { + csrRoamLinkDown(pMac, sessionId); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + //no need to tell QoS that we are disassociating, it will be taken care off in assoc req for HO + if(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) + { + //notify QoS module that disassoc happening + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_REQ, NULL); + } +#endif + } + else + { + smsLog(pMac, LOGW, FL("csrSendMBDisassocReqMsg failed with status %d"), status); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDisassociateStaCmd + \brief csr function that HDD calls to disassociate a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDisassociateStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 *pPeerMacAddr, + tANI_U32 reason) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + do + { + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta; + vos_mem_copy(pCommand->u.roamCmd.peerMac, pPeerMacAddr, 6); + pCommand->u.roamCmd.reason = (tSirMacReasonCodes)reason; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + }while(0); + + return status; +} + + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDeauthSta + \brief csr function that HDD calls to delete a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDeauthStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 *pPeerMacAddr, + tANI_U32 reason) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + do + { + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta; + vos_mem_copy(pCommand->u.roamCmd.peerMac, pPeerMacAddr, 6); + pCommand->u.roamCmd.reason = (tSirMacReasonCodes)reason; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + }while(0); + + return status; +} +eHalStatus +csrRoamIssueTkipCounterMeasures( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN bEnable ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamIssueTkipCounterMeasures:CSR Session not found"); + return (status); + } + if (pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamIssueTkipCounterMeasures:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR issuing tkip counter measures for Bssid = "MAC_ADDRESS_STR", Enable = %d", + MAC_ADDR_ARRAY(bssId), bEnable); + status = csrSendMBTkipCounterMeasuresReqMsg( pMac, sessionId, bEnable, bssId ); + return (status); +} +eHalStatus +csrRoamGetAssociatedStas( tpAniSirGlobal pMac, tANI_U32 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, v_U8_t *pAssocStasBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamGetAssociatedStas:CSR Session not found"); + return (status); + } + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamGetAssociatedStas:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR getting associated stations for Bssid = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + status = csrSendMBGetAssociatedStasReqMsg( pMac, sessionId, modId, bssId, pUsrContext, pfnSapEventCallback, pAssocStasBuf ); + return (status); +} +eHalStatus +csrRoamGetWpsSessionOverlap( tpAniSirGlobal pMac, tANI_U32 sessionId, + void *pUsrContext, void *pfnSapEventCallback, v_MACADDR_t pRemoveMac ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamGetWpsSessionOverlap:CSR Session not found"); + return (status); + } + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamGetWpsSessionOverlap:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR getting WPS Session Overlap for Bssid = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + + status = csrSendMBGetWPSPBCSessions( pMac, sessionId, bssId, pUsrContext, pfnSapEventCallback, pRemoveMac); + + return (status); +} +eHalStatus csrRoamIssueDeauth( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + smsLog( pMac, LOG2, "CSR Attempting to Deauth Bssid= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + csrRoamSubstateChange( pMac, NewSubstate, sessionId); + + status = csrSendMBDeauthReqMsg( pMac, sessionId, bssId, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON ); + if (HAL_STATUS_SUCCESS(status)) + csrRoamLinkDown(pMac, sessionId); + else + { + smsLog(pMac, LOGE, FL("csrSendMBDeauthReqMsg failed with status %d Session ID: %d" + MAC_ADDRESS_STR ), status, sessionId, MAC_ADDR_ARRAY(bssId)); + } + + return (status); +} + +eHalStatus csrRoamSaveConnectedBssDesc( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDesc ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U32 size; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + // If no BSS description was found in this connection (happens with start IBSS), then + // nix the BSS description that we keep around for the connected BSS) and get out... + if(NULL == pBssDesc) + { + csrFreeConnectBssDesc(pMac, sessionId); + } + else + { + size = pBssDesc->length + sizeof( pBssDesc->length ); + if(NULL != pSession->pConnectBssDesc) + { + if(((pSession->pConnectBssDesc->length) + sizeof(pSession->pConnectBssDesc->length)) < size) + { + //not enough room for the new BSS, pMac->roam.pConnectBssDesc is freed inside + csrFreeConnectBssDesc(pMac, sessionId); + } + } + if(NULL == pSession->pConnectBssDesc) + { + pSession->pConnectBssDesc = vos_mem_malloc(size); + } + if (NULL == pSession->pConnectBssDesc) + status = eHAL_STATUS_FAILURE; + else + vos_mem_copy(pSession->pConnectBssDesc, pBssDesc, size); + } + return (status); +} + +eHalStatus csrRoamPrepareBssConfig(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrCfgDot11Mode cfgDot11Mode; + VOS_ASSERT( pIes != NULL ); + if (pIes == NULL) + return eHAL_STATUS_FAILURE; + + do + { + vos_mem_copy(&pBssConfig->BssCap, &pBssDesc->capabilityInfo, + sizeof(tSirMacCapabilityInfo)); + //get qos + pBssConfig->qosType = csrGetQoSFromBssDesc(pMac, pBssDesc, pIes); + //get SSID + if(pIes->SSID.present) + { + vos_mem_copy(&pBssConfig->SSID.ssId, pIes->SSID.ssid, pIes->SSID.num_ssid); + pBssConfig->SSID.length = pIes->SSID.num_ssid; + } + else + pBssConfig->SSID.length = 0; + if(csrIsNULLSSID(pBssConfig->SSID.ssId, pBssConfig->SSID.length)) + { + smsLog(pMac, LOGW, " BSS desc SSID is a wildcard"); + //Return failed if profile doesn't have an SSID either. + if(pProfile->SSIDs.numOfSSIDs == 0) + { + smsLog(pMac, LOGW, " Both BSS desc and profile doesn't have SSID"); + status = eHAL_STATUS_FAILURE; + break; + } + } + if(CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId)) + { + pBssConfig->eBand = eCSR_BAND_5G; + } + else + { + pBssConfig->eBand = eCSR_BAND_24; + } + //phymode + if(csrIsPhyModeMatch( pMac, pProfile->phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes )) + { + pBssConfig->uCfgDot11Mode = cfgDot11Mode; + } + else + { + smsLog(pMac, LOGW, " Can not find match phy mode"); + //force it + if(eCSR_BAND_24 == pBssConfig->eBand) + { + pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + else + { + pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + //Qos + if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) && + (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos)) + { + //Joining BSS is not 11n capable and WMM is disabled on client. + //Disable QoS and WMM + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF; + } + + if (((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N) || + (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC)) && + ((pBssConfig->qosType != eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP) || + (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_HCF) || + (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_eDCF) )) + { + //Joining BSS is 11n capable and WMM is disabled on AP. + //Assume all HT AP's are QOS AP's and enable WMM + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } + + //auth type + switch( pProfile->negotiatedAuthType ) + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pBssConfig->authType = eSIR_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + pBssConfig->authType = eSIR_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + pBssConfig->authType = eSIR_AUTO_SWITCH; + break; + } + //short slot time + if( eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode ) + { + pBssConfig->uShortSlotTime = pMac->roam.configParam.shortSlotTime; + } + else + { + pBssConfig->uShortSlotTime = 0; + } + if(pBssConfig->BssCap.ibss) + { + //We don't support 11h on IBSS + pBssConfig->f11hSupport = eANI_BOOLEAN_FALSE; + } + else + { + pBssConfig->f11hSupport = pMac->roam.configParam.Is11hSupportEnabled; + } + //power constraint + pBssConfig->uPowerLimit = csrGet11hPowerConstraint(pMac, &pIes->PowerConstraints); + //heartbeat + if ( CSR_IS_11A_BSS( pBssDesc ) ) + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh50; + } + else + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh24; + } + //Join timeout + // if we find a BeaconInterval in the BssDescription, then set the Join Timeout to + // be 10 x the BeaconInterval. + if ( pBssDesc->beaconInterval ) + { + //Make sure it is bigger than the minimal + pBssConfig->uJoinTimeOut = CSR_ROAM_MAX(10 * pBssDesc->beaconInterval, CSR_JOIN_FAILURE_TIMEOUT_MIN); + } + else + { + pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT; + } + //validate CB + pBssConfig->cbMode = csrGetCBModeFromIes(pMac, pBssDesc->channelId, pIes); + }while(0); + return (status); +} + +static eHalStatus csrRoamPrepareBssConfigFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tBssConfigParam *pBssConfig, tSirBssDescription *pBssDesc) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 operationChannel = 0; + tANI_U8 qAPisEnabled = FALSE; + //SSID + pBssConfig->SSID.length = 0; + if(pProfile->SSIDs.numOfSSIDs) + { + //only use the first one + vos_mem_copy(&pBssConfig->SSID, &pProfile->SSIDs.SSIDList[0].SSID, + sizeof(tSirMacSSid)); + } + else + { + //SSID must present + return eHAL_STATUS_FAILURE; + } + //Settomg up the capabilities + if( csrIsBssTypeIBSS(pProfile->BSSType) ) + { + pBssConfig->BssCap.ibss = 1; + } + else + { + pBssConfig->BssCap.ess = 1; + } + if( eCSR_ENCRYPT_TYPE_NONE != pProfile->EncryptionType.encryptionType[0] ) + { + pBssConfig->BssCap.privacy = 1; + } + pBssConfig->eBand = pMac->roam.configParam.eBand; + //phymode + if(pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + pBssConfig->uCfgDot11Mode = csrRoamGetPhyModeBandForBss(pMac, pProfile, operationChannel, + &pBssConfig->eBand); + //QOS + //Is this correct to always set to this //*** + if ( pBssConfig->BssCap.ess == 1 ) + { + /*For Softap case enable WMM*/ + if(CSR_IS_INFRA_AP(pProfile) && (eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode )){ + qAPisEnabled = TRUE; + } + else + if (csrRoamGetQosInfoFromBss(pMac, pBssDesc) == eHAL_STATUS_SUCCESS) { + qAPisEnabled = TRUE; + } else { + qAPisEnabled = FALSE; + } + } else { + qAPisEnabled = TRUE; + } + if (( eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode && qAPisEnabled) || + (( eCSR_CFG_DOT11_MODE_11N == pBssConfig->uCfgDot11Mode && qAPisEnabled) || + ( eCSR_CFG_DOT11_MODE_TAURUS == pBssConfig->uCfgDot11Mode ) ) //For 11n, need QoS + ) + { + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } else { + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF; + } + + //auth type + switch( pProfile->AuthType.authType[0] ) //Take the preferred Auth type. + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pBssConfig->authType = eSIR_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + pBssConfig->authType = eSIR_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + pBssConfig->authType = eSIR_AUTO_SWITCH; + break; + } + //short slot time + if( WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode ) + { + pBssConfig->uShortSlotTime = pMac->roam.configParam.shortSlotTime; + } + else + { + pBssConfig->uShortSlotTime = 0; + } + //power constraint. We don't support 11h on IBSS + pBssConfig->f11hSupport = eANI_BOOLEAN_FALSE; + pBssConfig->uPowerLimit = 0; + //heartbeat + if ( eCSR_BAND_5G == pBssConfig->eBand ) + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh50; + } + else + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh24; + } + //Join timeout + pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT; + + return (status); +} +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tDot11fBeaconIEs *pIes = NULL; + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "csrRoamGetQosInfoFromBss() failed"); + break; + } + //check if the AP is QAP & it supports APSD + if( CSR_IS_QOS_BSS(pIes) ) + { + status = eHAL_STATUS_SUCCESS; + } + } while (0); + + if (NULL != pIes) + { + vos_mem_free(pIes); + } + + return status; +} + +void csrSetCfgPrivacy( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy ) +{ + // !! Note: the only difference between this function and the csrSetCfgPrivacyFromProfile() is the + // setting of the privacy CFG based on the advertised privacy setting from the AP for WPA associations. + // See !!Note: below in this function... + tANI_U32 PrivacyEnabled = 0; + tANI_U32 RsnEnabled = 0; + tANI_U32 WepDefaultKeyId = 0; + tANI_U32 WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5; /* default 40 bits */ + tANI_U32 Key0Length = 0; + tANI_U32 Key1Length = 0; + tANI_U32 Key2Length = 0; + tANI_U32 Key3Length = 0; + + // Reserve for the biggest key + tANI_U8 Key0[ WNI_CFG_WEP_DEFAULT_KEY_1_LEN ]; + tANI_U8 Key1[ WNI_CFG_WEP_DEFAULT_KEY_2_LEN ]; + tANI_U8 Key2[ WNI_CFG_WEP_DEFAULT_KEY_3_LEN ]; + tANI_U8 Key3[ WNI_CFG_WEP_DEFAULT_KEY_4_LEN ]; + + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_NONE: + + // for NO encryption, turn off Privacy and Rsn. + PrivacyEnabled = 0; + RsnEnabled = 0; + + // WEP key length and Wep Default Key ID don't matter in this case.... + + // clear out the WEP keys that may be hanging around. + Key0Length = 0; + Key1Length = 0; + Key2Length = 0; + Key3Length = 0; + + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + + // Privacy is ON. NO RSN for Wep40 static key. + PrivacyEnabled = 1; + RsnEnabled = 0; + + // Set the Wep default key ID. + WepDefaultKeyId = pProfile->Keys.defaultIndex; + // Wep key size if 5 bytes (40 bits). + WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5; + + // set encryption keys in the CFG database or clear those that are not present in this profile. + if ( pProfile->Keys.KeyLength[0] ) + { + vos_mem_copy(Key0, pProfile->Keys.KeyMaterial[0], + WNI_CFG_WEP_KEY_LENGTH_5); + Key0Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key0Length = 0; + } + + if ( pProfile->Keys.KeyLength[1] ) + { + vos_mem_copy(Key1, pProfile->Keys.KeyMaterial[1], + WNI_CFG_WEP_KEY_LENGTH_5); + Key1Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key1Length = 0; + } + + if ( pProfile->Keys.KeyLength[2] ) + { + vos_mem_copy(Key2, pProfile->Keys.KeyMaterial[2], + WNI_CFG_WEP_KEY_LENGTH_5); + Key2Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key2Length = 0; + } + + if ( pProfile->Keys.KeyLength[3] ) + { + vos_mem_copy(Key3, pProfile->Keys.KeyMaterial[3], + WNI_CFG_WEP_KEY_LENGTH_5); + Key3Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key3Length = 0; + } + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + + // Privacy is ON. NO RSN for Wep40 static key. + PrivacyEnabled = 1; + RsnEnabled = 0; + + // Set the Wep default key ID. + WepDefaultKeyId = pProfile->Keys.defaultIndex; + + // Wep key size if 13 bytes (104 bits). + WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_13; + + // set encryption keys in the CFG database or clear those that are not present in this profile. + if ( pProfile->Keys.KeyLength[0] ) + { + vos_mem_copy(Key0, pProfile->Keys.KeyMaterial[ 0 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key0Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key0Length = 0; + } + + if ( pProfile->Keys.KeyLength[1] ) + { + vos_mem_copy(Key1, pProfile->Keys.KeyMaterial[ 1 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key1Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key1Length = 0; + } + + if ( pProfile->Keys.KeyLength[2] ) + { + vos_mem_copy(Key2, pProfile->Keys.KeyMaterial[ 2 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key2Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key2Length = 0; + } + + if ( pProfile->Keys.KeyLength[3] ) + { + vos_mem_copy(Key3, pProfile->Keys.KeyMaterial[ 3 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key3Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key3Length = 0; + } + + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: +#endif /* FEATURE_WLAN_WAPI */ + // !! Note: this is the only difference between this function and the csrSetCfgPrivacyFromProfile() + // (setting of the privacy CFG based on the advertised privacy setting from the AP for WPA/WAPI associations ). + PrivacyEnabled = (0 != fPrivacy); + + // turn on RSN enabled for WPA associations + RsnEnabled = 1; + + // WEP key length and Wep Default Key ID don't matter in this case.... + + // clear out the static WEP keys that may be hanging around. + Key0Length = 0; + Key1Length = 0; + Key2Length = 0; + Key3Length = 0; + + break; + default: + PrivacyEnabled = 0; + RsnEnabled = 0; + break; + } + + ccmCfgSetInt(pMac, WNI_CFG_PRIVACY_ENABLED, PrivacyEnabled, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_RSN_ENABLED, RsnEnabled, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0, Key0Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1, Key1Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2, Key2Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3, Key3Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_WEP_KEY_LENGTH, WepKeyLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, WepDefaultKeyId, NULL, eANI_BOOLEAN_FALSE); +} + +static void csrSetCfgSsid( tpAniSirGlobal pMac, tSirMacSSid *pSSID ) +{ + tANI_U32 len = 0; + if(pSSID->length <= WNI_CFG_SSID_LEN) + { + len = pSSID->length; + } + ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pSSID->ssId, len, NULL, eANI_BOOLEAN_FALSE); +} + +eHalStatus csrSetQosToCfg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrMediaAccessType qosType ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 QoSEnabled; + tANI_U32 WmeEnabled; + // set the CFG enable/disable variables based on the qosType being configured... + switch( qosType ) + { + case eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_11e_eDCF: + QoSEnabled = TRUE; + WmeEnabled = FALSE; + break; + case eCSR_MEDIUM_ACCESS_11e_HCF: + QoSEnabled = TRUE; + WmeEnabled = FALSE; + break; + default: + case eCSR_MEDIUM_ACCESS_DCF: + QoSEnabled = FALSE; + WmeEnabled = FALSE; + break; + } + //save the WMM setting for later use + pMac->roam.roamSession[sessionId].fWMMConnection = (tANI_BOOLEAN)WmeEnabled; + pMac->roam.roamSession[sessionId].fQOSConnection = (tANI_BOOLEAN)QoSEnabled; + return (status); +} +static eHalStatus csrGetRateSet( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes, tSirMacRateSet *pOpRateSet, tSirMacRateSet *pExRateSet) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + int i; + eCsrCfgDot11Mode cfgDot11Mode; + tANI_U8 *pDstRate; + tANI_U16 rateBitmap = 0; + vos_mem_set(pOpRateSet, sizeof(tSirMacRateSet), 0); + vos_mem_set(pExRateSet, sizeof(tSirMacRateSet), 0); + VOS_ASSERT( pIes != NULL ); + + if( NULL != pIes ) + { + csrIsPhyModeMatch( pMac, phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes ); + // Originally, we thought that for 11a networks, the 11a rates are always + // in the Operational Rate set & for 11b and 11g networks, the 11b rates + // appear in the Operational Rate set. Consequently, in either case, we + // would blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are + // supported earlier in the roaming decision). + // However, it turns out that this is not always the case. Some AP's + // (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, + // too. Now, we're a little more careful: + pDstRate = pOpRateSet->rate; + if(pIes->SuppRates.present) + { + for ( i = 0; i < pIes->SuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->SuppRates.rates[ i ] ) ) + { + csrAddRateBitmap(pIes->SuppRates.rates[ i ], &rateBitmap); + *pDstRate++ = pIes->SuppRates.rates[ i ]; + pOpRateSet->numRates++; + } + } + } + if ( eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode +#ifdef WLAN_FEATURE_11AC + || eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode +#endif + ) + { + // If there are Extended Rates in the beacon, we will reflect those + // extended rates that we support in out Extended Operational Rate + // set: + pDstRate = pExRateSet->rate; + if(pIes->ExtSuppRates.present) + { + for ( i = 0; i < pIes->ExtSuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->ExtSuppRates.rates[ i ] ) ) + { + if (!csrCheckRateBitmap(pIes->ExtSuppRates.rates[ i ], rateBitmap)) + { + *pDstRate++ = pIes->ExtSuppRates.rates[ i ]; + pExRateSet->numRates++; + } + } + } + } + } + }//Parsing BSSDesc + else + { + smsLog(pMac, LOGE, FL("failed to parse BssDesc")); + } + if (pOpRateSet->numRates > 0 || pExRateSet->numRates > 0) status = eHAL_STATUS_SUCCESS; + return status; +} + +static void csrSetCfgRateSet( tpAniSirGlobal pMac, eCsrPhyMode phyMode, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + int i; + tANI_U8 *pDstRate; + eCsrCfgDot11Mode cfgDot11Mode; + tANI_U8 OperationalRates[ CSR_DOT11_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 OperationalRatesLength = 0; + tANI_U8 ExtendedOperationalRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 ExtendedOperationalRatesLength = 0; + tANI_U8 ProprietaryOperationalRates[ 4 ]; // leave enough room for the max number of proprietary rates + tANI_U32 ProprietaryOperationalRatesLength = 0; + tANI_U32 PropRatesEnable = 0; + tANI_U8 MCSRateIdxSet[ SIZE_OF_SUPPORTED_MCS_SET ]; + tANI_U32 MCSRateLength = 0; + VOS_ASSERT( pIes != NULL ); + if( NULL != pIes ) + { + csrIsPhyModeMatch( pMac, phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes ); + // Originally, we thought that for 11a networks, the 11a rates are always + // in the Operational Rate set & for 11b and 11g networks, the 11b rates + // appear in the Operational Rate set. Consequently, in either case, we + // would blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are + // supported earlier in the roaming decision). + // However, it turns out that this is not always the case. Some AP's + // (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, + // too. Now, we're a little more careful: + pDstRate = OperationalRates; + if(pIes->SuppRates.present) + { + for ( i = 0; i < pIes->SuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->SuppRates.rates[ i ] ) && + ( OperationalRatesLength < CSR_DOT11_SUPPORTED_RATES_MAX )) + { + *pDstRate++ = pIes->SuppRates.rates[ i ]; + OperationalRatesLength++; + } + } + } + if ( eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode ) + { + // If there are Extended Rates in the beacon, we will reflect those + // extended rates that we support in out Extended Operational Rate + // set: + pDstRate = ExtendedOperationalRates; + if(pIes->ExtSuppRates.present) + { + for ( i = 0; i < pIes->ExtSuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->ExtSuppRates.rates[ i ] ) && + ( ExtendedOperationalRatesLength < CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX )) + { + *pDstRate++ = pIes->ExtSuppRates.rates[ i ]; + ExtendedOperationalRatesLength++; + } + } + } + } + // Enable proprietary MAC features if peer node is Airgo node and STA + // user wants to use them + if( pIes->Airgo.present && pMac->roam.configParam.ProprietaryRatesEnabled ) + { + PropRatesEnable = 1; + } + else + { + PropRatesEnable = 0; + } + // For ANI network companions, we need to populate the proprietary rate + // set with any proprietary rates we found in the beacon, only if user + // allows them... + if ( PropRatesEnable && pIes->Airgo.PropSuppRates.present && + ( pIes->Airgo.PropSuppRates.num_rates > 0 )) + { + ProprietaryOperationalRatesLength = pIes->Airgo.PropSuppRates.num_rates; + if ( ProprietaryOperationalRatesLength > sizeof(ProprietaryOperationalRates) ) + { + ProprietaryOperationalRatesLength = sizeof (ProprietaryOperationalRates); + } + vos_mem_copy(ProprietaryOperationalRates, + pIes->Airgo.PropSuppRates.rates, + ProprietaryOperationalRatesLength); + } + else { + // No proprietary modes... + ProprietaryOperationalRatesLength = 0; + } + /* Get MCS Rate */ + pDstRate = MCSRateIdxSet; + if ( pIes->HTCaps.present ) + { + for ( i = 0; i < VALID_MAX_MCS_INDEX; i++ ) + { + if ( (unsigned int)pIes->HTCaps.supportedMCSSet[0] & (1 << i) ) + { + MCSRateLength++; + *pDstRate++ = i; + } + } + } + // Set the operational rate set CFG variables... + ccmCfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, + OperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedOperationalRates, + ExtendedOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + ProprietaryOperationalRates, + ProprietaryOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, PropRatesEnable, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_CURRENT_MCS_SET, MCSRateIdxSet, + MCSRateLength, NULL, eANI_BOOLEAN_FALSE); + }//Parsing BSSDesc + else + { + smsLog(pMac, LOGE, FL("failed to parse BssDesc")); + } +} + +static void csrSetCfgRateSetFromProfile( tpAniSirGlobal pMac, + tCsrRoamProfile *pProfile ) +{ + tSirMacRateSetIE DefaultSupportedRates11a = { SIR_MAC_RATESET_EID, + { 8, + { SIR_MAC_RATE_6, + SIR_MAC_RATE_9, + SIR_MAC_RATE_12, + SIR_MAC_RATE_18, + SIR_MAC_RATE_24, + SIR_MAC_RATE_36, + SIR_MAC_RATE_48, + SIR_MAC_RATE_54 } } }; + tSirMacRateSetIE DefaultSupportedRates11b = { SIR_MAC_RATESET_EID, + { 4, + { SIR_MAC_RATE_1, + SIR_MAC_RATE_2, + SIR_MAC_RATE_5_5, + SIR_MAC_RATE_11 } } }; + + + tSirMacPropRateSet DefaultSupportedPropRates = { 3, + { SIR_MAC_RATE_72, + SIR_MAC_RATE_96, + SIR_MAC_RATE_108 } }; + eCsrCfgDot11Mode cfgDot11Mode; + eCsrBand eBand; + tANI_U8 OperationalRates[ CSR_DOT11_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 OperationalRatesLength = 0; + tANI_U8 ExtendedOperationalRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 ExtendedOperationalRatesLength = 0; + tANI_U8 ProprietaryOperationalRates[ 4 ]; // leave enough room for the max number of proprietary rates + tANI_U32 ProprietaryOperationalRatesLength = 0; + tANI_U32 PropRatesEnable = 0; + tANI_U8 operationChannel = 0; + if(pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + cfgDot11Mode = csrRoamGetPhyModeBandForBss( pMac, pProfile, operationChannel, &eBand ); + // For 11a networks, the 11a rates go into the Operational Rate set. For 11b and 11g + // networks, the 11b rates appear in the Operational Rate set. In either case, + // we can blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are supported + // earlier in the roaming decision). + if ( eCSR_BAND_5G == eBand ) + { + // 11a rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11a.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11a.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11a.supportedRateSet.rate, + OperationalRatesLength); + + // Nothing in the Extended rate set. + ExtendedOperationalRatesLength = 0; + // populate proprietary rates if user allows them + if ( pMac->roam.configParam.ProprietaryRatesEnabled ) + { + ProprietaryOperationalRatesLength = DefaultSupportedPropRates.numPropRates * + sizeof(*DefaultSupportedPropRates.propRate); + vos_mem_copy(ProprietaryOperationalRates, + DefaultSupportedPropRates.propRate, + ProprietaryOperationalRatesLength); + } + else + { + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + } + else if ( eCSR_CFG_DOT11_MODE_11B == cfgDot11Mode ) + { + // 11b rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11b.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11b.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11b.supportedRateSet.rate, + OperationalRatesLength); + // Nothing in the Extended rate set. + ExtendedOperationalRatesLength = 0; + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + else + { + // 11G + + // 11b rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11b.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11b.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11b.supportedRateSet.rate, + OperationalRatesLength); + + // 11a rates go in the Extended rate set. + ExtendedOperationalRatesLength = DefaultSupportedRates11a.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11a.supportedRateSet.rate); + vos_mem_copy(ExtendedOperationalRates, + DefaultSupportedRates11a.supportedRateSet.rate, + ExtendedOperationalRatesLength); + + // populate proprietary rates if user allows them + if ( pMac->roam.configParam.ProprietaryRatesEnabled ) + { + ProprietaryOperationalRatesLength = DefaultSupportedPropRates.numPropRates * + sizeof(*DefaultSupportedPropRates.propRate); + vos_mem_copy(ProprietaryOperationalRates, + DefaultSupportedPropRates.propRate, + ProprietaryOperationalRatesLength); + } + else + { + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + } + // set this to 1 if prop. rates need to be advertised in to the IBSS beacon and user wants to use them + if ( ProprietaryOperationalRatesLength && pMac->roam.configParam.ProprietaryRatesEnabled ) + { + PropRatesEnable = 1; + } + else + { + PropRatesEnable = 0; + } + + // Set the operational rate set CFG variables... + ccmCfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, + OperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedOperationalRates, + ExtendedOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + ProprietaryOperationalRates, + ProprietaryOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, PropRatesEnable, NULL, eANI_BOOLEAN_FALSE); +} +void csrRoamCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + tListElem *pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + tANI_U32 sessionId; + tSmeCmd *pCommand = NULL; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tCsrRoamSession *pSession = NULL; +#endif + if(NULL == pEntry) + { + smsLog(pMac, LOGW, " CFG_CNF with active list empty"); + return; + } + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + sessionId = pCommand->sessionId; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pSession = &pMac->roam.roamSession[sessionId]; + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:csrRoamCcmCfgSetCallback"); + } +#endif + + if(CSR_IS_ROAM_JOINING(pMac, sessionId) && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) + { + csrRoamingStateConfigCnfProcessor(pMac, (tANI_U32)result); + } +} + +//This function is very dump. It is here because PE still need WNI_CFG_PHY_MODE +tANI_U32 csrRoamGetPhyModeFromDot11Mode(eCsrCfgDot11Mode dot11Mode, eCsrBand band) +{ + if(eCSR_CFG_DOT11_MODE_11B == dot11Mode) + { + return (WNI_CFG_PHY_MODE_11B); + } + else + { + if(eCSR_BAND_24 == band) + return (WNI_CFG_PHY_MODE_11G); + } + return (WNI_CFG_PHY_MODE_11A); +} + + +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState csrGetHTCBStateFromVHTCBState(ePhyChanBondState aniCBMode) +{ + switch ( aniCBMode ) + { + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + default : + return PHY_SINGLE_CHANNEL_CENTERED; + } +} +#endif + +//pIes may be NULL +eHalStatus csrRoamSetBssConfigCfg(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN resetCountry) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + tANI_U8 channel = 0; + //Make sure we have the domain info for the BSS we try to connect to. + //Do we need to worry about sequence for OSs that are not Windows?? + if (pBssDesc) + { + if (csrLearnCountryInformation(pMac, pBssDesc, pIes, eANI_BOOLEAN_TRUE)) + { + //Make sure the 11d info from this BSSDesc can be applied + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + if (VOS_TRUE == resetCountry) + { + csrApplyCountryInformation(pMac, FALSE); + } + else + { + csrApplyCountryInformation(pMac, TRUE); + } + } + if ((csrIs11dSupported (pMac)) && pIes) + { + if (!pIes->Country.present) + { + csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE ); + } + else + { + //Let's also update the below to make sure we don't update CC while + //connected to an AP which is advertising some CC + vos_mem_copy(pMac->scan.currentCountryBssid, + pBssDesc->bssId, sizeof(tSirMacAddr)); + } + } + } + //Qos + csrSetQosToCfg( pMac, sessionId, pBssConfig->qosType ); + //SSID + csrSetCfgSsid(pMac, &pBssConfig->SSID ); + + //Auth type + ccmCfgSetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, pBssConfig->authType, NULL, eANI_BOOLEAN_FALSE); + //encryption type + csrSetCfgPrivacy(pMac, pProfile, (tANI_BOOLEAN)pBssConfig->BssCap.privacy ); + //short slot time + ccmCfgSetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, pBssConfig->uShortSlotTime, NULL, eANI_BOOLEAN_FALSE); + //11d + ccmCfgSetInt(pMac, WNI_CFG_11D_ENABLED, + ((pBssConfig->f11hSupport) ? pBssConfig->f11hSupport : pProfile->ieee80211d), + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, pBssConfig->uPowerLimit, NULL, eANI_BOOLEAN_FALSE); + //CB + + if(CSR_IS_INFRA_AP(pProfile) || CSR_IS_WDS_AP(pProfile) || CSR_IS_IBSS(pProfile)) + { + channel = pProfile->operationChannel; + } + else + { + if(pBssDesc) + { + channel = pBssDesc->channelId; + } + } + if(0 != channel) + { + if(CSR_IS_CHANNEL_24GHZ(channel)) + {//for now if we are on 2.4 Ghz, CB will be always disabled + cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + else + { + cfgCb = pBssConfig->cbMode; + } + } +#ifdef WLAN_FEATURE_11AC + // cbMode = 1 in cfg.ini is mapped to PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + // in function csrConvertCBIniValueToPhyCBState() + // So, max value for cbMode in 40MHz mode is 3 (MAC\src\include\sirParams.h) + if(cfgCb > PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + { + if(!WDA_getFwWlanFeatCaps(DOT11AC)) { + cfgCb = csrGetHTCBStateFromVHTCBState(cfgCb); + } + else + { + ccmCfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, pMac->roam.configParam.nVhtChannelWidth, NULL, eANI_BOOLEAN_FALSE); + } + } + else +#endif + ccmCfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, cfgCb, NULL, eANI_BOOLEAN_FALSE); + //Rate + //Fixed Rate + if(pBssDesc) + { + csrSetCfgRateSet(pMac, (eCsrPhyMode)pProfile->phyMode, pProfile, pBssDesc, pIes); + } + else + { + csrSetCfgRateSetFromProfile(pMac, pProfile); + } + //Make this the last CFG to set. The callback will trigger a join_req + //Join time out + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId ); + + ccmCfgSetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, pBssConfig->uJoinTimeOut, (tCcmCfgSetCallback)csrRoamCcmCfgSetCallback, eANI_BOOLEAN_FALSE); + return (status); +} + +eHalStatus csrRoamStopNetwork( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + eHalStatus status; + tBssConfigParam *pBssConfig; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pBssConfig = vos_mem_malloc(sizeof(tBssConfigParam)); + if ( NULL == pBssConfig ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pBssConfig, sizeof(tBssConfigParam), 0); + status = csrRoamPrepareBssConfig(pMac, pProfile, pBssDesc, pBssConfig, pIes); + if(HAL_STATUS_SUCCESS(status)) + { + pSession->bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode; + /* This will allow to pass cbMode during join req */ + pSession->bssParams.cbMode= pBssConfig->cbMode; + //For IBSS, we need to prepare some more information + if( csrIsBssTypeIBSS(pProfile->BSSType) || CSR_IS_WDS( pProfile ) + || CSR_IS_INFRA_AP(pProfile) + ) + { + csrRoamPrepareBssParams(pMac, sessionId, pProfile, pBssDesc, pBssConfig, pIes); + } + // If we are in an IBSS, then stop the IBSS... + ////Not worry about WDS connection for now + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + else + { + // if we are in an Infrastructure association.... + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + // and the new Bss is an Ibss OR we are roaming from Infra to Infra + // across SSIDs (roaming to a new SSID)... // + //Not worry about WDS connection for now + if ( pBssDesc && ( ( csrIsIbssBssDesc( pBssDesc ) ) || + !csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, pIes ) ) ) + { + // then we need to disassociate from the Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + // In an Infrastucture and going to an Infrastructure network with the same SSID. This + // calls for a Reassociation sequence. So issue the CFG sets for this new AP. + if ( pBssDesc ) + { + // Set parameters for this Bss. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, pBssConfig, + pIes, eANI_BOOLEAN_FALSE); + } + } + } + else + { + // Neiher in IBSS nor in Infra. We can go ahead and set the CFG for tne new network... + // Nothing to stop. + if ( pBssDesc || CSR_IS_WDS_AP( pProfile ) + || CSR_IS_INFRA_AP(pProfile) + ) + { + tANI_BOOLEAN is11rRoamingFlag = eANI_BOOLEAN_FALSE; + is11rRoamingFlag = csrRoamIs11rAssoc(pMac, sessionId); + // Set parameters for this Bss. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, pBssConfig, + pIes, is11rRoamingFlag); + } + } + } + }//Success getting BSS config info + vos_mem_free(pBssConfig); + }//Allocate memory + return (status); +} + +eCsrJoinState csrRoamJoin( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrScanResultInfo *pScanResult, tCsrRoamProfile *pProfile ) +{ + eCsrJoinState eRoamState = eCsrContinueRoaming; + eHalStatus status; + tSirBssDescription *pBssDesc = &pScanResult->BssDescriptor; + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)( pScanResult->pvIes ); //This may be NULL + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (eCsrStopRoaming); + } + + if( CSR_IS_WDS_STA( pProfile ) ) + { + status = csrRoamStartWds( pMac, sessionId, pProfile, pBssDesc ); + if( !HAL_STATUS_SUCCESS( status ) ) + { + eRoamState = eCsrStopRoaming; + } + } + else + { + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + return (eCsrStopRoaming); + } + if ( csrIsInfraBssDesc( pBssDesc ) ) + { + // If we are connected in infrastructure mode and the Join Bss description is for the same BssID, then we are + // attempting to join the AP we are already connected with. In that case, see if the Bss or Sta capabilities + // have changed and handle the changes (without disturbing the current association). + + if ( csrIsConnStateConnectedInfra(pMac, sessionId) && + csrIsBssIdEqual( pMac, pBssDesc, pSession->pConnectBssDesc ) && + csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, pIesLocal ) + ) + { + // Check to see if the Auth type has changed in the Profile. If so, we don't want to Reassociate + // with Authenticating first. To force this, stop the current association (Disassociate) and + // then re 'Join' the AP, wihch will force an Authentication (with the new Auth type) followed by + // a new Association. + if(csrIsSameProfile(pMac, &pSession->connectedProfile, pProfile)) + { + smsLog(pMac, LOGW, FL(" detect same profile")); + if(csrRoamIsSameProfileKeys(pMac, &pSession->connectedProfile, pProfile)) + { + eRoamState = eCsrReassocToSelfNoCapChange; + } + else + { + tBssConfigParam bssConfig; + //The key changes + vos_mem_set(&bssConfig, sizeof(bssConfig), 0); + status = csrRoamPrepareBssConfig(pMac, pProfile, pBssDesc, &bssConfig, pIesLocal); + if(HAL_STATUS_SUCCESS(status)) + { + pSession->bssParams.uCfgDot11Mode = bssConfig.uCfgDot11Mode; + pSession->bssParams.cbMode = bssConfig.cbMode; + //Reapply the config including Keys so reassoc is happening. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, &bssConfig, + pIesLocal, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + eRoamState = eCsrStopRoaming; + } + } + else + { + eRoamState = eCsrStopRoaming; + } + }//same profile + } + else + { + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REQ, FALSE ))) + { + smsLog(pMac, LOGE, FL(" fail to issue disassociate with Session ID %d"), + sessionId); + eRoamState = eCsrStopRoaming; + } + } + } + else + { + // note: we used to pre-auth here with open authentication networks but that was not working so well. + // + // stop the existing network before attempting to join the new network... + if(!HAL_STATUS_SUCCESS(csrRoamStopNetwork(pMac, sessionId, pProfile, pBssDesc, pIesLocal))) + { + eRoamState = eCsrStopRoaming; + } + } + }//Infra + else + { + if(!HAL_STATUS_SUCCESS(csrRoamStopNetwork(pMac, sessionId, pProfile, pBssDesc, pIesLocal))) + { + eRoamState = eCsrStopRoaming; + } + } + if( pIesLocal && !pScanResult->pvIes ) + { + vos_mem_free(pIesLocal); + } + } + return( eRoamState ); +} + +eHalStatus csrRoamShouldRoam(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tANI_U32 roamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pBssDesc; + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, roamId, eCSR_ROAM_SHOULD_ROAM, eCSR_ROAM_RESULT_NONE); + return (status); +} +//In case no matching BSS is found, use whatever default we can find +static void csrRoamAssignDefaultParam( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + //Need to get all negotiated types in place first + //auth type + switch( pCommand->u.roamCmd.roamProfile.AuthType.authType[0] ) //Take the preferred Auth type. + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + + case eCSR_AUTH_TYPE_SHARED_KEY: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; + break; + + case eCSR_AUTH_TYPE_AUTOSWITCH: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; + break; + } + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0]; + //In this case, the multicast encryption needs to follow the uncast ones. + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0]; +} + + +static void csrSetAbortRoamingCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + switch(pCommand->u.roamCmd.roamReason) + { + case eCsrLostLink1: + pCommand->u.roamCmd.roamReason = eCsrLostLink1Abort; + break; + case eCsrLostLink2: + pCommand->u.roamCmd.roamReason = eCsrLostLink2Abort; + break; + case eCsrLostLink3: + pCommand->u.roamCmd.roamReason = eCsrLostLink3Abort; + break; + default: + smsLog(pMac, LOGE, FL(" aborting roaming reason %d not recognized"), + pCommand->u.roamCmd.roamReason); + break; + } +} + +static eCsrJoinState csrRoamJoinNextBss( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fUseSameBss ) +{ + eHalStatus status; + tCsrScanResult *pScanResult = NULL; + eCsrJoinState eRoamState = eCsrStopRoaming; + tScanResultList *pBSSList = (tScanResultList *)pCommand->u.roamCmd.hBSSList; + tANI_BOOLEAN fDone = eANI_BOOLEAN_FALSE; + tCsrRoamInfo roamInfo, *pRoamInfo = NULL; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + v_U8_t acm_mask = 0; +#endif + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamProfile *pProfile = &pCommand->u.roamCmd.roamProfile; + tANI_U8 concurrentChannel = 0; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (eCsrStopRoaming); + } + + do + { + // Check for Cardbus eject condition, before trying to Roam to any BSS + //***if( !balIsCardPresent(pAdapter) ) break; + + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + memcpy (&roamInfo.bssid, &pSession->joinFailStatusCode.bssId, sizeof(tSirMacAddr)); + if(NULL != pBSSList) + { + // When handling AP's capability change, continue to associate to + // same BSS and make sure pRoamBssEntry is not Null. + if((eANI_BOOLEAN_FALSE == fUseSameBss) || (pCommand->u.roamCmd.pRoamBssEntry == NULL)) + { + if(pCommand->u.roamCmd.pRoamBssEntry == NULL) + { + //Try the first BSS + pCommand->u.roamCmd.pLastRoamBss = NULL; + pCommand->u.roamCmd.pRoamBssEntry = csrLLPeekHead(&pBSSList->List, LL_ACCESS_LOCK); + } + else + { + pCommand->u.roamCmd.pRoamBssEntry = csrLLNext(&pBSSList->List, pCommand->u.roamCmd.pRoamBssEntry, LL_ACCESS_LOCK); + if(NULL == pCommand->u.roamCmd.pRoamBssEntry) + { + //Done with all the BSSs + //In this case, will tell HDD the completion + break; + } + else + { + //We need to indicate to HDD that we are done with this one. + //vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; //this shall not be NULL + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + pRoamInfo = &roamInfo; + } + } + while(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + /*If concurrency enabled take the concurrent connected channel first. */ + /* Valid multichannel concurrent sessions exempted */ + if (vos_concurrent_open_sessions_running() && + !csrIsValidMcConcurrentSession(pMac, sessionId, + &pScanResult->Result.BssDescriptor)) + { + concurrentChannel = + csrGetConcurrentOperationChannel(pMac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: " + " csr Concurrent Channel = %d", __func__, concurrentChannel); + if ((concurrentChannel) && + (concurrentChannel == + pScanResult->Result.BssDescriptor.channelId)) + { + //make this 0 because we do not want the + //below check to pass as we don't want to + //connect on other channel + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Concurrent channel match =%d"), + concurrentChannel); + concurrentChannel = 0; + } + } + + if (!concurrentChannel) + { +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("csrRoamShouldRoam")); +#endif + + if(HAL_STATUS_SUCCESS(csrRoamShouldRoam(pMac, + sessionId, &pScanResult->Result.BssDescriptor, + pCommand->u.roamCmd.roamId))) + { + //Ok to roam this + break; + } + } + else + { + eRoamState = eCsrStopRoamingDueToConcurrency; + } + pCommand->u.roamCmd.pRoamBssEntry = csrLLNext(&pBSSList->List, pCommand->u.roamCmd.pRoamBssEntry, LL_ACCESS_LOCK); + if(NULL == pCommand->u.roamCmd.pRoamBssEntry) + { + //Done with all the BSSs + fDone = eANI_BOOLEAN_TRUE; + break; + } + } + if(fDone) + { + break; + } + } + } + + if (!pRoamInfo) + pRoamInfo = &roamInfo; + + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + + //We have something to roam, tell HDD when it is infra. + //For IBSS, the indication goes back to HDD via eCSR_ROAM_IBSS_IND + //For WDS, the indication is eCSR_ROAM_WDS_IND + if( CSR_IS_INFRASTRUCTURE( pProfile ) ) + { + if(pSession->bRefAssocStartCnt) + { + pSession->bRefAssocStartCnt--; + pRoamInfo->pProfile = pProfile; + /* Complete the last association attempt because a new one + is about to be tried */ + csrRoamCallCallback(pMac, sessionId, pRoamInfo, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_NOT_ASSOCIATED); + } + /* If the roaming has stopped, not to continue the roaming command*/ + if ( !CSR_IS_ROAMING(pSession) && CSR_IS_ROAMING_COMMAND(pCommand) ) + { + //No need to complete roaming here as it already completes + smsLog(pMac, LOGW, FL(" Roam command (reason %d) aborted due to roaming completed"), + pCommand->u.roamCmd.roamReason); + eRoamState = eCsrStopRoaming; + csrSetAbortRoamingCommand(pMac, pCommand); + break; + } + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + if(pScanResult) + { + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)pScanResult->Result.pvIes; + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" cannot parse IEs")); + fDone = eANI_BOOLEAN_TRUE; + eRoamState = eCsrStopRoaming; + break; + } + roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor; + pCommand->u.roamCmd.pLastRoamBss = roamInfo.pBssDesc; + //No need to put uapsd_mask in if the BSS doesn't support uAPSD + if( pCommand->u.roamCmd.roamProfile.uapsd_mask && + CSR_IS_QOS_BSS(pIesLocal) && + CSR_IS_UAPSD_BSS(pIesLocal) ) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, &pScanResult->Result.BssDescriptor, + pIesLocal); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + else + { + pCommand->u.roamCmd.roamProfile.uapsd_mask = 0; + } + if( pIesLocal && !pScanResult->Result.pvIes) + { + vos_mem_free(pIesLocal); + } + } + else + { + pCommand->u.roamCmd.roamProfile.uapsd_mask = 0; + } + roamInfo.pProfile = pProfile; + pSession->bRefAssocStartCnt++; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("csrGetParsedBssDescriptionIEs")); +#endif + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_START, eCSR_ROAM_RESULT_NONE ); + } + if ( NULL == pCommand->u.roamCmd.pRoamBssEntry ) + { + // If this is a start IBSS profile, then we need to start the IBSS. + if ( CSR_IS_START_IBSS(pProfile) ) + { + tANI_BOOLEAN fSameIbss = eANI_BOOLEAN_FALSE; + // Attempt to start this IBSS... + csrRoamAssignDefaultParam( pMac, pCommand ); + status = csrRoamStartIbss( pMac, sessionId, pProfile, &fSameIbss ); + if(HAL_STATUS_SUCCESS(status)) + { + if ( fSameIbss ) + { + eRoamState = eCsrStartIbssSameIbss; + } + else + { + eRoamState = eCsrContinueRoaming; + } + } + else + { + //it somehow fail need to stop + eRoamState = eCsrStopRoaming; + } + break; + } + else if ( (CSR_IS_WDS_AP(pProfile)) + || (CSR_IS_INFRA_AP(pProfile)) + ) + { + // Attempt to start this WDS... + csrRoamAssignDefaultParam( pMac, pCommand ); + /* For AP WDS, we dont have any BSSDescription */ + status = csrRoamStartWds( pMac, sessionId, pProfile, NULL ); + if(HAL_STATUS_SUCCESS(status)) + { + eRoamState = eCsrContinueRoaming; + } + else + { + //it somehow fail need to stop + eRoamState = eCsrStopRoaming; + } + } + else + { + //Nothing we can do + smsLog(pMac, LOGW, FL("cannot continue without BSS list")); + eRoamState = eCsrStopRoaming; + break; + } + } + else //We have BSS + { + //Need to assign these value because they are used in csrIsSameProfile + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + /* The OSEN IE doesn't provide the cipher suite. + * Therefore set to constant value of AES */ + if(pCommand->u.roamCmd.roamProfile.bOSENAssociation) + { + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + eCSR_ENCRYPT_TYPE_AES; + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + eCSR_ENCRYPT_TYPE_AES; + } + else + { + //Negotiated while building scan result. + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + pScanResult->ucEncryptionType; + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + pScanResult->mcEncryptionType; + } + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = pScanResult->authType; + if ( CSR_IS_START_IBSS(&pCommand->u.roamCmd.roamProfile) ) + { + if(csrIsSameProfile(pMac, &pSession->connectedProfile, pProfile)) + { + eRoamState = eCsrStartIbssSameIbss; + break; + } + } + if( pCommand->u.roamCmd.fReassocToSelfNoCapChange ) + { + //trying to connect to the one already connected + pCommand->u.roamCmd.fReassocToSelfNoCapChange = eANI_BOOLEAN_FALSE; + eRoamState = eCsrReassocToSelfNoCapChange; + break; + } + // Attempt to Join this Bss... + eRoamState = csrRoamJoin( pMac, sessionId, &pScanResult->Result, pProfile ); + break; + } + + } while( 0 ); + if( (eCsrStopRoaming == eRoamState) && (CSR_IS_INFRASTRUCTURE( pProfile )) ) + { + //Need to indicate association_completion if association_start has been done + if(pSession->bRefAssocStartCnt > 0) + { + pSession->bRefAssocStartCnt--; + //Complete the last association attemp because a new one is about to be tried + pRoamInfo = &roamInfo; + pRoamInfo->pProfile = pProfile; + csrRoamCallCallback(pMac, sessionId, pRoamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_NOT_ASSOCIATED); + } + } + + return( eRoamState ); +} + +static eHalStatus csrRoam( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrJoinState RoamState; + tANI_U32 sessionId = pCommand->sessionId; + + //***if( hddIsRadioStateOn( pAdapter ) ) + { + // Attept to join a Bss... + RoamState = csrRoamJoinNextBss( pMac, pCommand, eANI_BOOLEAN_FALSE ); + + // if nothing to join.. + if (( eCsrStopRoaming == RoamState ) || ( eCsrStopRoamingDueToConcurrency == RoamState)) + { + tANI_BOOLEAN fComplete = eANI_BOOLEAN_FALSE; + // and if connected in Infrastructure mode... + if ( csrIsConnStateInfra(pMac, sessionId) ) + { + //... then we need to issue a disassociation + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, FALSE ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue disassociate, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else if( csrIsConnStateIbss(pMac, sessionId) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue stop bss, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else if (csrIsConnStateConnectedInfraAp(pMac, sessionId)) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue stop bss, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else + { + fComplete = eANI_BOOLEAN_TRUE; + } + if(fComplete) + { + // ... otherwise, we can complete the Roam command here. + if(eCsrStopRoamingDueToConcurrency == RoamState) + { + csrRoamComplete( pMac, eCsrJoinFailureDueToConcurrency, NULL ); + } + else + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + } + else if ( eCsrReassocToSelfNoCapChange == RoamState ) + { + csrRoamComplete( pMac, eCsrSilentlyStopRoamingSaveState, NULL ); + } + else if ( eCsrStartIbssSameIbss == RoamState ) + { + csrRoamComplete( pMac, eCsrSilentlyStopRoaming, NULL ); + } + }//hddIsRadioStateOn + + return status; +} +eHalStatus csrProcessFTReassocRoamCommand ( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tANI_U32 sessionId; + tCsrRoamSession *pSession; + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDesc = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOG1, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + return eHAL_STATUS_FAILURE; + } + if (pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + pBssDesc = &pScanResult->Result.BssDescriptor; + } + else + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOG1, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + return eHAL_STATUS_FAILURE; + } + status = csrRoamIssueReassociate(pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), &pCommand->u.roamCmd.roamProfile); + return status; +} + +eHalStatus csrRoamProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + if (eCSR_ROAMING_STATE_IDLE == pMac->roam.curState[sessionId]) { + smsLog(pMac, LOGE, FL("Ignore eCsrForcedDisassoc cmd on roam state" + " %d"), eCSR_ROAMING_STATE_IDLE); + return eHAL_STATUS_FAILURE; + } + + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, FALSE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrSmeIssuedDisassocForHandoff: + //Not to free pMac->roam.pCurRoamProfile (via csrFreeRoamProfile) because it is needed after disconnect + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, FALSE ); + + break; + case eCsrForcedDisassocMICFailure: + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, TRUE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrForcedDeauth: + status = csrRoamProcessDisassocDeauth( pMac, pCommand, FALSE, FALSE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + { + tDot11fBeaconIEs *pIes = NULL; + + if( pSession->pConnectBssDesc ) + { + status = csrGetParsedBssDescriptionIEs(pMac, pSession->pConnectBssDesc, &pIes); + if(!HAL_STATUS_SUCCESS(status) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + } + else + { + roamInfo.reasonCode = eCsrRoamReasonStaCapabilityChanged; + csrRoamCallCallback(pMac, pSession->sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + pSession->roamingReason = eCsrReassocRoaming; + roamInfo.pBssDesc = pSession->pConnectBssDesc; + roamInfo.pProfile = &pCommand->u.roamCmd.roamProfile; + pSession->bRefAssocStartCnt++; + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_START, eCSR_ROAM_RESULT_NONE ); + + smsLog(pMac, LOG1, FL(" calling csrRoamIssueReassociate")); + status = csrRoamIssueReassociate( pMac, sessionId, pSession->pConnectBssDesc, pIes, + &pCommand->u.roamCmd.roamProfile ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamIssueReassociate failed with status %d"), status); + csrReleaseCommandRoam( pMac, pCommand ); + } + + vos_mem_free(pIes); + pIes = NULL; + } + } + else + { + smsLog(pMac, LOGE, FL + ("Reassoc To Same AP failed since Connected BSS is NULL")); + return eHAL_STATUS_FAILURE; + } + break; + } + case eCsrCapsChange: + smsLog(pMac, LOGE, FL("received eCsrCapsChange ")); + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE); + break; + case eCsrSmeIssuedFTReassoc: + smsLog(pMac, LOG1, FL("received FT Reassoc Req ")); + status = csrProcessFTReassocRoamCommand(pMac, pCommand); + break; + + case eCsrStopBss: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + break; + + case eCsrForcedDisassocSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_DISASSOC_REQ, sessionId); + status = csrSendMBDisassocReqMsg( pMac, sessionId, pCommand->u.roamCmd.peerMac, + pCommand->u.roamCmd.reason); + break; + + case eCsrForcedDeauthSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_DEAUTH_REQ, sessionId); + status = csrSendMBDeauthReqMsg( pMac, sessionId, pCommand->u.roamCmd.peerMac, + pCommand->u.roamCmd.reason); + break; + + case eCsrPerformPreauth: + smsLog(pMac, LOG1, FL("Attempting FT PreAuth Req")); + status = csrRoamIssueFTPreauthReq(pMac, sessionId, + pCommand->u.roamCmd.pLastRoamBss); + break; + default: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + + if( pCommand->u.roamCmd.fUpdateCurRoamProfile ) + { + //Remember the roaming profile + csrFreeRoamProfile(pMac, sessionId); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, &pCommand->u.roamCmd.roamProfile); + } + } + + //At this point, original uapsd_mask is saved in pCurRoamProfile + //uapsd_mask in the pCommand may change from this point on. + + // Attempt to roam with the new scan results (if we need to..) + status = csrRoam( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL("csrRoam() failed with status = 0x%08X"), status); + } + break; + } + return (status); +} + +void csrReinitPreauthCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + pCommand->u.roamCmd.pLastRoamBss = NULL; + pCommand->u.roamCmd.pRoamBssEntry = NULL; + //Because u.roamCmd is union and share with scanCmd and StatusChange + vos_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0); +} + +void csrReinitRoamCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + if(pCommand->u.roamCmd.fReleaseBssList) + { + csrScanResultPurge(pMac, pCommand->u.roamCmd.hBSSList); + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_FALSE; + pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + } + if(pCommand->u.roamCmd.fReleaseProfile) + { + csrReleaseProfile(pMac, &pCommand->u.roamCmd.roamProfile); + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + } + pCommand->u.roamCmd.pRoamBssEntry = NULL; + //Because u.roamCmd is union and share with scanCmd and StatusChange + vos_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0); +} + +void csrReinitWmStatusChangeCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.wmStatusChangeCmd, sizeof(tWmStatusChangeCmd), 0); +} +void csrRoamComplete( tpAniSirGlobal pMac, eCsrRoamCompleteResult Result, void *Context ) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tANI_BOOLEAN fReleaseCommand = eANI_BOOLEAN_TRUE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "%s: Roam Completion ...", __func__); + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + // If the head of the queue is Active and it is a ROAM command, remove + // and put this on the Free queue. + if ( eSmeCommandRoam == pCommand->command ) + { + //we need to process the result first before removing it from active list because state changes + //still happening insides roamQProcessRoamResults so no other roam command should be issued + fReleaseCommand = csrRoamProcessResults( pMac, pCommand, Result, Context ); + if( fReleaseCommand ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + else + { + smsLog( pMac, LOGE, " **********csrRoamComplete fail to release command reason %d", + pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGE, " **********csrRoamComplete fail to release command reason %d", + pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but ROAM command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but NO commands are ACTIVE ..." ); + } + if( fReleaseCommand ) + { + smeProcessPendingQueue( pMac ); + } +} + +void csrResetPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + vos_mem_set(&(pSession->PmkidCandidateInfo[0]), + sizeof(tPmkidCandidateInfo) * CSR_MAX_PMKID_ALLOWED, 0); + pSession->NumPmkidCandidate = 0; +} +#ifdef FEATURE_WLAN_WAPI +void csrResetBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + vos_mem_set(&(pSession->BkidCandidateInfo[0]), + sizeof(tBkidCandidateInfo) * CSR_MAX_BKID_ALLOWED, 0); + pSession->NumBkidCandidate = 0; +} +#endif /* FEATURE_WLAN_WAPI */ +extern tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ]; + +static eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrAuthType authType, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tDot11fBeaconIEs *pIesLocal = pIes; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("LFR3:csrRoamSaveSecurityRspIE")); + } +#endif + + if((eCSR_AUTH_TYPE_WPA == authType) || + (eCSR_AUTH_TYPE_WPA_PSK == authType) || + (eCSR_AUTH_TYPE_RSN == authType) || + (eCSR_AUTH_TYPE_RSN_PSK == authType) +#if defined WLAN_FEATURE_VOWIFI_11R + || + (eCSR_AUTH_TYPE_FT_RSN == authType) || + (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_WAPI + || + (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) || + (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType) +#endif /* FEATURE_WLAN_WAPI */ +#ifdef WLAN_FEATURE_11W + || + (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) || + (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType) +#endif /* FEATURE_WLAN_WAPI */ + ) + { + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" cannot parse IEs")); + } + if( pIesLocal ) + { + tANI_U32 nIeLen; + tANI_U8 *pIeBuf; + if((eCSR_AUTH_TYPE_RSN == authType) || +#if defined WLAN_FEATURE_VOWIFI_11R + (eCSR_AUTH_TYPE_FT_RSN == authType) || + (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) || +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#if defined WLAN_FEATURE_11W + (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) || + (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType) || +#endif + (eCSR_AUTH_TYPE_RSN_PSK == authType)) + { + if(pIesLocal->RSN.present) + { + //Calculate the actual length + nIeLen = 8 //version + gp_cipher_suite + pwise_cipher_suite_count + + pIesLocal->RSN.pwise_cipher_suite_count * 4 //pwise_cipher_suites + + 2 //akm_suite_count + + pIesLocal->RSN.akm_suite_count * 4 //akm_suites + + 2; //reserved + if( pIesLocal->RSN.pmkid_count ) + { + nIeLen += 2 + pIesLocal->RSN.pmkid_count * 4; //pmkid + } + //nIeLen doesn't count EID and length fields + pSession->pWpaRsnRspIE = vos_mem_malloc(nIeLen + 2); + if (NULL == pSession->pWpaRsnRspIE) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pSession->pWpaRsnRspIE, nIeLen + 2, 0); + pSession->pWpaRsnRspIE[0] = DOT11F_EID_RSN; + pSession->pWpaRsnRspIE[1] = (tANI_U8)nIeLen; + //copy upto akm_suites + pIeBuf = pSession->pWpaRsnRspIE + 2; + vos_mem_copy(pIeBuf, &pIesLocal->RSN.version, + sizeof(pIesLocal->RSN.version)); + pIeBuf += sizeof(pIesLocal->RSN.version); + vos_mem_copy(pIeBuf, &pIesLocal->RSN.gp_cipher_suite, + sizeof(pIesLocal->RSN.gp_cipher_suite)); + pIeBuf += sizeof(pIesLocal->RSN.gp_cipher_suite); + vos_mem_copy(pIeBuf, &pIesLocal->RSN.pwise_cipher_suite_count, + sizeof(pIesLocal->RSN.pwise_cipher_suite_count)); + pIeBuf += sizeof(pIesLocal->RSN.pwise_cipher_suite_count ); + if( pIesLocal->RSN.pwise_cipher_suite_count ) + { + //copy pwise_cipher_suites + vos_mem_copy(pIeBuf, + pIesLocal->RSN.pwise_cipher_suites, + pIesLocal->RSN.pwise_cipher_suite_count * 4); + pIeBuf += pIesLocal->RSN.pwise_cipher_suite_count * 4; + } + vos_mem_copy(pIeBuf, &pIesLocal->RSN.akm_suite_count, 2); + pIeBuf += 2; + if( pIesLocal->RSN.akm_suite_count ) + { + //copy akm_suites + vos_mem_copy(pIeBuf, + pIesLocal->RSN.akm_suites, + pIesLocal->RSN.akm_suite_count * 4); + pIeBuf += pIesLocal->RSN.akm_suite_count * 4; + } + //copy the rest + vos_mem_copy(pIeBuf, + pIesLocal->RSN.akm_suites + pIesLocal->RSN.akm_suite_count * 4, + 2 + pIesLocal->RSN.pmkid_count * 4); + pSession->nWpaRsnRspIeLength = nIeLen + 2; + } + } + } + else if((eCSR_AUTH_TYPE_WPA == authType) || + (eCSR_AUTH_TYPE_WPA_PSK == authType)) + { + if(pIesLocal->WPA.present) + { + //Calculate the actual length + nIeLen = 12 //OUI + version + multicast_cipher + unicast_cipher_count + + pIesLocal->WPA.unicast_cipher_count * 4 //unicast_ciphers + + 2 //auth_suite_count + + pIesLocal->WPA.auth_suite_count * 4; //auth_suites + // The WPA capabilities follows the Auth Suite (two octects)-- + // this field is optional, and we always "send" zero, so just + // remove it. This is consistent with our assumptions in the + // frames compiler; c.f. bug 15234: + //nIeLen doesn't count EID and length fields + + pSession->pWpaRsnRspIE = vos_mem_malloc(nIeLen + 2); + if ( NULL == pSession->pWpaRsnRspIE ) + status = eHAL_STATUS_FAILURE; + else + { + pSession->pWpaRsnRspIE[0] = DOT11F_EID_WPA; + pSession->pWpaRsnRspIE[1] = (tANI_U8)nIeLen; + pIeBuf = pSession->pWpaRsnRspIE + 2; + //Copy WPA OUI + vos_mem_copy(pIeBuf, &csrWpaOui[1], 4); + pIeBuf += 4; + vos_mem_copy(pIeBuf, &pIesLocal->WPA.version, + 8 + pIesLocal->WPA.unicast_cipher_count * 4); + pIeBuf += 8 + pIesLocal->WPA.unicast_cipher_count * 4; + vos_mem_copy(pIeBuf, &pIesLocal->WPA.auth_suite_count, + 2 + pIesLocal->WPA.auth_suite_count * 4); + pIeBuf += pIesLocal->WPA.auth_suite_count * 4; + pSession->nWpaRsnRspIeLength = nIeLen + 2; + } + } + } +#ifdef FEATURE_WLAN_WAPI + else if((eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) || + (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)) + { + if(pIesLocal->WAPI.present) + { + //Calculate the actual length + nIeLen = 4 //version + akm_suite_count + + pIesLocal->WAPI.akm_suite_count * 4 // akm_suites + + 2 //pwise_cipher_suite_count + + pIesLocal->WAPI.unicast_cipher_suite_count * 4 //pwise_cipher_suites + + 6; //gp_cipher_suite + preauth + reserved + if( pIesLocal->WAPI.bkid_count ) + { + nIeLen += 2 + pIesLocal->WAPI.bkid_count * 4; //bkid + } + + //nIeLen doesn't count EID and length fields + pSession->pWapiRspIE = vos_mem_malloc(nIeLen + 2); + if ( NULL == pSession->pWapiRspIE ) + status = eHAL_STATUS_FAILURE; + else + { + pSession->pWapiRspIE[0] = DOT11F_EID_WAPI; + pSession->pWapiRspIE[1] = (tANI_U8)nIeLen; + pIeBuf = pSession->pWapiRspIE + 2; + //copy upto akm_suite_count + vos_mem_copy(pIeBuf, &pIesLocal->WAPI.version, 2); + pIeBuf += 4; + if( pIesLocal->WAPI.akm_suite_count ) + { + //copy akm_suites + vos_mem_copy(pIeBuf, pIesLocal->WAPI.akm_suites, + pIesLocal->WAPI.akm_suite_count * 4); + pIeBuf += pIesLocal->WAPI.akm_suite_count * 4; + } + vos_mem_copy(pIeBuf, + &pIesLocal->WAPI.unicast_cipher_suite_count, + 2); + pIeBuf += 2; + if( pIesLocal->WAPI.unicast_cipher_suite_count ) + { + //copy pwise_cipher_suites + vos_mem_copy( pIeBuf, + pIesLocal->WAPI.unicast_cipher_suites, + pIesLocal->WAPI.unicast_cipher_suite_count * 4); + pIeBuf += pIesLocal->WAPI.unicast_cipher_suite_count * 4; + } + //gp_cipher_suite + vos_mem_copy(pIeBuf, + pIesLocal->WAPI.multicast_cipher_suite, + 4); + pIeBuf += 4; + //preauth + reserved + vos_mem_copy(pIeBuf, + pIesLocal->WAPI.multicast_cipher_suite + 4, + 2); + pIeBuf += 2; + if (pIesLocal->WAPI.bkid_count) { + /* bkid_count */ + vos_mem_copy(pIeBuf, &pIesLocal->WAPI.bkid_count, 2); + pIeBuf += 2; + //copy akm_suites + vos_mem_copy(pIeBuf, pIesLocal->WAPI.bkid, + pIesLocal->WAPI.bkid_count * 4); + pIeBuf += pIesLocal->WAPI.bkid_count * 4; + } + pSession->nWapiRspIeLength = nIeLen + 2; + } + } + } +#endif /* FEATURE_WLAN_WAPI */ + if( !pIes ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + } + } + return (status); +} + +static void csrCheckAndUpdateACWeight( tpAniSirGlobal pMac, tDot11fBeaconIEs *pIEs ) +{ + v_U8_t bACWeights[WLANTL_MAX_AC]; + v_U8_t paramBk, paramBe, paramVi, paramVo; + v_BOOL_t fWeightChange = VOS_FALSE; + //Compare two ACs' EDCA parameters, from low to high (BK, BE, VI, VO) + //The "formula" is, if lower AC's AIFSN+CWMin is bigger than a fixed amount + //of the higher AC one, make the higher AC has the same weight as the lower AC. + //This doesn't address the case where the lower AC needs a real higher weight + if( pIEs->WMMParams.present ) + { + //no change to the lowest ones + bACWeights[WLANTL_AC_BK] = pMac->roam.ucACWeights[WLANTL_AC_BK]; + bACWeights[WLANTL_AC_BE] = pMac->roam.ucACWeights[WLANTL_AC_BE]; + bACWeights[WLANTL_AC_VI] = pMac->roam.ucACWeights[WLANTL_AC_VI]; + bACWeights[WLANTL_AC_VO] = pMac->roam.ucACWeights[WLANTL_AC_VO]; + paramBk = pIEs->WMMParams.acbk_aifsn + pIEs->WMMParams.acbk_acwmin; + paramBe = pIEs->WMMParams.acbe_aifsn + pIEs->WMMParams.acbe_acwmin; + paramVi = pIEs->WMMParams.acvi_aifsn + pIEs->WMMParams.acvi_acwmin; + paramVo = pIEs->WMMParams.acvo_aifsn + pIEs->WMMParams.acvo_acwmin; + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramBe) ) + { + bACWeights[WLANTL_AC_BE] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramVi) ) + { + bACWeights[WLANTL_AC_VI] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramBe, paramVi) ) + { + bACWeights[WLANTL_AC_VI] = bACWeights[WLANTL_AC_BE]; + fWeightChange = VOS_TRUE; + } + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramBe, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_BE]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramVi, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_VI]; + fWeightChange = VOS_TRUE; + } + if(fWeightChange) + { + smsLog(pMac, LOGE, FL(" change AC weights (%d-%d-%d-%d)"), bACWeights[0], bACWeights[1], + bACWeights[2], bACWeights[3]); + WLANTL_SetACWeights(pMac->roam.gVosContext, bACWeights); + } + } +} +#ifdef WLAN_FEATURE_VOWIFI_11R +//Returns whether the current association is a 11r assoc or not +tANI_BOOLEAN csrRoamIs11rAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIs11rAssoc(pMac, sessionId); +#else + return eANI_BOOLEAN_FALSE; +#endif +} +#endif +#ifdef FEATURE_WLAN_ESE +//Returns whether the current association is a ESE assoc or not +tANI_BOOLEAN csrRoamIsESEAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIsESEAssoc(pMac, sessionId); +#else + return eANI_BOOLEAN_FALSE; +#endif +} +#endif +#ifdef FEATURE_WLAN_LFR +//Returns whether "Legacy Fast Roaming" is currently enabled...or not +tANI_BOOLEAN csrRoamIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = NULL; + + if (CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona != VOS_STA_MODE) + { + return eANI_BOOLEAN_FALSE; + } + } + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eANI_BOOLEAN_TRUE == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) + { + return (pMac->roam.configParam.isFastRoamIniFeatureEnabled); + } + else +#endif + { + return (pMac->roam.configParam.isFastRoamIniFeatureEnabled && + (!csrIsConcurrentSessionRunning(pMac))); + } +} + +#ifdef FEATURE_WLAN_ESE +/* --------------------------------------------------------------------------- + \fn csrNeighborRoamIsESEAssoc + + \brief This function returns whether the current association + is a ESE assoc or not + + \param pMac - The handle returned by macOpen. + \param sessionId - Session Id + + \return eANI_BOOLEAN_TRUE if current assoc is ESE, eANI_BOOLEAN_FALSE + otherwise +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsESEAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + return pMac->roam.neighborRoamInfo[sessionId].isESEAssoc; +} +#endif /* FEATURE_WLAN_ESE */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +//Returns whether "FW based BG scan" is currently enabled...or not +tANI_BOOLEAN csrRoamIsRoamOffloadScanEnabled(tpAniSirGlobal pMac) +{ + return (pMac->roam.configParam.isRoamOffloadScanEnabled); +} +#endif +#endif + +#if defined(FEATURE_WLAN_ESE) +tANI_BOOLEAN csrRoamIsEseIniFeatureEnabled(tpAniSirGlobal pMac) +{ + return pMac->roam.configParam.isEseIniFeatureEnabled; +} +#endif /*FEATURE_WLAN_ESE*/ + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +eCsrPhyMode csrRoamdot11modeToPhymode(tANI_U8 dot11mode) +{ + eCsrPhyMode phymode = eCSR_DOT11_MODE_abg; + + switch (dot11mode) + { + case WNI_CFG_DOT11_MODE_ALL: + phymode = eCSR_DOT11_MODE_abg; + break; + case WNI_CFG_DOT11_MODE_11A: + phymode = eCSR_DOT11_MODE_11a; + break; + case WNI_CFG_DOT11_MODE_11B: + phymode = eCSR_DOT11_MODE_11b; + break; + case WNI_CFG_DOT11_MODE_11G: + phymode = eCSR_DOT11_MODE_11g; + break; + case WNI_CFG_DOT11_MODE_11N: + phymode = eCSR_DOT11_MODE_11n; + break; + case WNI_CFG_DOT11_MODE_POLARIS: + phymode = eCSR_DOT11_MODE_POLARIS; + break; + case WNI_CFG_DOT11_MODE_TITAN: + phymode = eCSR_DOT11_MODE_TITAN; + break; + case WNI_CFG_DOT11_MODE_TAURUS: + phymode = eCSR_DOT11_MODE_TAURUS; + break; + case WNI_CFG_DOT11_MODE_11G_ONLY: + phymode = eCSR_DOT11_MODE_11g_ONLY; + break; + case WNI_CFG_DOT11_MODE_11N_ONLY: + phymode = eCSR_DOT11_MODE_11n_ONLY; + break; + case WNI_CFG_DOT11_MODE_11AC: + phymode = eCSR_DOT11_MODE_11ac; + break; + case WNI_CFG_DOT11_MODE_11AC_ONLY: + phymode = eCSR_DOT11_MODE_11ac_ONLY; + break; + default: + break; + } + + return phymode; +} +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrRoamOffloadSendSynchCnf(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpSirSmeRoamOffloadSynchCnf pRoamOffloadSynchCnf; + vos_msg_t msg; + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + pRoamOffloadSynchCnf = + vos_mem_malloc(sizeof(tSirSmeRoamOffloadSynchCnf)); + if (NULL == pRoamOffloadSynchCnf) + { + VOS_TRACE(VOS_MODULE_ID_SME, + VOS_TRACE_LEVEL_ERROR, + "%s: not able to allocate memory for roam" + "offload synch confirmation data", __func__); + pSession->roamOffloadSynchParams.bRoamSynchInProgress = VOS_FALSE; + return eHAL_STATUS_FAILURE; + } + pRoamOffloadSynchCnf->sessionId = sessionId; + msg.type = WDA_ROAM_OFFLOAD_SYNCH_CNF; + msg.reserved = 0; + msg.bodyptr = pRoamOffloadSynchCnf; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3: Posting WDA_ROAM_OFFLOAD_SYNCH_CNF"); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message( + VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME,VOS_TRACE_LEVEL_DEBUG, + "%s: Not able to post WDA_ROAM_OFFLOAD_SYNCH_CNF message to WDA", + __func__); + vos_mem_free(pRoamOffloadSynchCnf); + pSession->roamOffloadSynchParams.bRoamSynchInProgress = VOS_FALSE; + return eHAL_STATUS_FAILURE; + } + pSession->roamOffloadSynchParams.bRoamSynchInProgress = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +void csrRoamSynchCleanUp (tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + vos_msg_t msg; + tpSirRoamOffloadSynchFail pRoamOffloadFailed = NULL; + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + + /*Clean up the roam synch in progress for LFR3 */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Roam Synch Failed, Clean Up", __func__); + pSession->roamOffloadSynchParams.bRoamSynchInProgress = VOS_FALSE; + + pRoamOffloadFailed = + vos_mem_malloc(sizeof(tSirRoamOffloadSynchFail)); + if (NULL == pRoamOffloadFailed) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: unable to allocate memory for roam synch fail" , __func__); + return; + } + pRoamOffloadFailed->sessionId = sessionId; + msg.type = WDA_ROAM_OFFLOAD_SYNCH_FAIL; + msg.reserved = 0; + msg.bodyptr = pRoamOffloadFailed; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) { + VOS_TRACE(VOS_MODULE_ID_SME,VOS_TRACE_LEVEL_DEBUG, + "%s:Unable to post WDA_ROAM_OFFLOAD_SYNCH_FAIL msg to WDA",__func__); + vos_mem_free(pRoamOffloadFailed); + } +} +#endif + +//Return true means the command can be release, else not +static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + eCsrRoamCompleteResult Result, void *Context ) +{ + tANI_BOOLEAN fReleaseCommand = eANI_BOOLEAN_TRUE; + tSirBssDescription *pSirBssDesc = NULL; + tSirMacAddr BroadcastMac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + tCsrScanResult *pScanResult = NULL; + tCsrRoamInfo roamInfo; + sme_QosAssocInfo assocInfo; + sme_QosCsrEventIndType ind_qos;//indication for QoS module in SME + tANI_U8 acm_mask = 0; //HDD needs the ACM mask in the assoc rsp callback + tDot11fBeaconIEs *pIes = NULL; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamProfile *pProfile = &pCommand->u.roamCmd.roamProfile; + eRoamCmdStatus roamStatus; + eCsrRoamResult roamResult; + eHalStatus status; + tANI_U32 key_timeout_interval = 0; + tSirSmeStartBssRsp *pSmeStartBssRsp = NULL; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eANI_BOOLEAN_FALSE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("Processing ROAM results...")); + switch( Result ) + { + case eCsrJoinSuccess: + // reset the IDLE timer + // !! + // !! fall through to the next CASE statement here is intentional !! + // !! + case eCsrReassocSuccess: + if(eCsrReassocSuccess == Result) + { + ind_qos = SME_QOS_CSR_REASSOC_COMPLETE; + } + else + { + ind_qos = SME_QOS_CSR_ASSOC_COMPLETE; + } + // Success Join Response from LIM. Tell NDIS we are connected and save the + // Connected state... + smsLog(pMac, LOGW, FL("receives association indication")); + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + //always free the memory here + if(pSession->pWpaRsnRspIE) + { + pSession->nWpaRsnRspIeLength = 0; + vos_mem_free(pSession->pWpaRsnRspIE); + pSession->pWpaRsnRspIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + if(pSession->pWapiRspIE) + { + pSession->nWapiRspIeLength = 0; + vos_mem_free(pSession->pWapiRspIE); + pSession->pWapiRspIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //Reset counter so no join retry is needed. + pSession->maxRetryCount = 0; + csrRoamStopJoinRetryTimer(pMac, sessionId); +#endif + /* This creates problem since we have not saved the connected profile. + So moving this after saving the profile + */ + //csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED ); + + /* Reset remainInPowerActiveTillDHCP as it might have been set + * by last failed secured connection. + * It should be set only for secured connection. + */ + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + if( CSR_IS_INFRASTRUCTURE( pProfile ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED; + } + else + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED; + } + //Use the last connected bssdesc for reassoc-ing to the same AP. + //NOTE: What to do when reassoc to a different AP??? + if( (eCsrHddIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) || + (eCsrSmeIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) ) + { + pSirBssDesc = pSession->pConnectBssDesc; + if(pSirBssDesc) + { + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + } + else + { + + if(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + if(pScanResult != NULL) + { + pSirBssDesc = &pScanResult->Result.BssDescriptor; + //this can be NULL + pIes = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + } + } + if( pSirBssDesc ) + { + roamInfo.staId = HAL_STA_INVALID_IDX; + csrRoamSaveConnectedInfomation(pMac, sessionId, pProfile, pSirBssDesc, pIes); + //Save WPA/RSN IE + csrRoamSaveSecurityRspIE(pMac, sessionId, pProfile->negotiatedAuthType, pSirBssDesc, pIes); +#ifdef FEATURE_WLAN_ESE + roamInfo.isESEAssoc = pSession->connectedProfile.isESEAssoc; +#endif + + // csrRoamStateChange also affects sub-state. Hence, csrRoamStateChange happens first and then + // substate change. + // Moving even save profile above so that below mentioned conditon is also met. + // JEZ100225: Moved to after saving the profile. Fix needed in main/latest + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + // Make sure the Set Context is issued before link indication to NDIS. After link indication is + // made to NDIS, frames could start flowing. If we have not set context with LIM, the frames + // will be dropped for the security context may not be set properly. + // + // this was causing issues in the 2c_wlan_wep WHQL test when the SetContext was issued after the link + // indication. (Link Indication happens in the profFSMSetConnectedInfra call). + // + // this reordering was done on titan_prod_usb branch and is being replicated here. + // + + if( CSR_IS_ENC_TYPE_STATIC( pProfile->negotiatedUCEncryptionType ) && + !pProfile->bWPSAssociation) + { + // Issue the set Context request to LIM to establish the Unicast STA context + if( !HAL_STATUS_SUCCESS( csrRoamIssueSetContextReq( pMac, sessionId, + pProfile->negotiatedUCEncryptionType, + pSirBssDesc, &(pSirBssDesc->bssId), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ) ) ) // NO keys... these key parameters don't matter. + { + smsLog( pMac, LOGE, FL(" Set context for unicast fail") ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + // Issue the set Context request to LIM to establish the Broadcast STA context + csrRoamIssueSetContextReq( pMac, sessionId, pProfile->negotiatedMCEncryptionType, + pSirBssDesc, &BroadcastMac, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + else + { +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress && + (pSession->roamOffloadSynchParams.authStatus == + CSR_ROAM_AUTH_STATUS_AUTHENTICATED)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("LFR3:Do not start the wait for key timer")); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } else { +#endif + //Need to wait for supplicant authtication + roamInfo.fAuthRequired = eANI_BOOLEAN_TRUE; + //Set the subestate to WaitForKey in case authentiation is needed + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, sessionId ); + + /* Set remainInPowerActiveTillDHCP to make sure we wait for + * until keys are set before going into BMPS. + */ + pMac->pmc.remainInPowerActiveTillDHCP = TRUE; + + if(pProfile->bWPSAssociation) + { + key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD; + } + else + { + key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD; + } + + //Save sessionId in case of timeout + pMac->roam.WaitForKeyTimerInfo.sessionId = (tANI_U8)sessionId; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress && + (pSession->roamOffloadSynchParams.authStatus == + CSR_ROAM_AUTH_STATUS_CONNECTED)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("LFR3:Send Synch Cnf for Auth status connected")); + csrRoamOffloadSendSynchCnf( pMac, sessionId); + + } +#endif + //This time should be long enough for the rest of the process plus setting key + if(!HAL_STATUS_SUCCESS( csrRoamStartWaitForKeyTimer( pMac, key_timeout_interval ) ) ) + { + //Reset our state so nothting is blocked. + smsLog( pMac, LOGE, FL(" Failed to start pre-auth timer") ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + } +#endif + } + + assocInfo.pBssDesc = pSirBssDesc; //could be NULL + assocInfo.pProfile = pProfile; + if(Context) + { + tSirSmeJoinRsp *pJoinRsp = (tSirSmeJoinRsp *)Context; + tANI_U32 len; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("LFR3:csrRoamFreeConnectedInfo")); + } +#endif + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + len = pJoinRsp->assocReqLength + pJoinRsp->assocRspLength + pJoinRsp->beaconLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + len += pJoinRsp->parsedRicRspLen; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + len += pJoinRsp->tspecIeLen; +#endif + if(len) + { + pSession->connectedInfo.pbFrames = vos_mem_malloc(len); + if ( pSession->connectedInfo.pbFrames != NULL ) + { + vos_mem_copy(pSession->connectedInfo.pbFrames, + pJoinRsp->frames, len); + pSession->connectedInfo.nAssocReqLength = pJoinRsp->assocReqLength; + pSession->connectedInfo.nAssocRspLength = pJoinRsp->assocRspLength; + pSession->connectedInfo.nBeaconLength = pJoinRsp->beaconLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + pSession->connectedInfo.nRICRspLength = pJoinRsp->parsedRicRspLen; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + pSession->connectedInfo.nTspecIeLength = pJoinRsp->tspecIeLen; +#endif + roamInfo.nAssocReqLength = pJoinRsp->assocReqLength; + roamInfo.nAssocRspLength = pJoinRsp->assocRspLength; + roamInfo.nBeaconLength = pJoinRsp->beaconLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + } + } + if(pCommand->u.roamCmd.fReassoc) + { + roamInfo.fReassocReq = roamInfo.fReassocRsp = eANI_BOOLEAN_TRUE; + } + pSession->connectedInfo.staId = ( tANI_U8 )pJoinRsp->staId; + roamInfo.staId = ( tANI_U8 )pJoinRsp->staId; + roamInfo.ucastSig = ( tANI_U8 )pJoinRsp->ucastSig; + roamInfo.bcastSig = ( tANI_U8 )pJoinRsp->bcastSig; + roamInfo.timingMeasCap = pJoinRsp->timingMeasCap; +#ifdef FEATURE_WLAN_TDLS + roamInfo.tdls_prohibited = pJoinRsp->tdls_prohibited; + roamInfo.tdls_chan_swit_prohibited = + pJoinRsp->tdls_chan_swit_prohibited; + smsLog(pMac, LOG1, + FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"), + roamInfo.tdls_prohibited, + roamInfo.tdls_chan_swit_prohibited); +#endif +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (pMac->roam.configParam.cc_switch_mode + != VOS_MCC_TO_SCC_SWITCH_DISABLE) { + pSession->connectedProfile.HTProfile.phymode = + csrRoamdot11modeToPhymode(pJoinRsp->HTProfile.dot11mode); + pSession->connectedProfile.HTProfile.htCapability = + pJoinRsp->HTProfile.htCapability; + pSession->connectedProfile.HTProfile.htSupportedChannelWidthSet = + pJoinRsp->HTProfile.htSupportedChannelWidthSet; + pSession->connectedProfile.HTProfile.htRecommendedTxWidthSet = + pJoinRsp->HTProfile.htRecommendedTxWidthSet; + pSession->connectedProfile.HTProfile.htSecondaryChannelOffset = + pJoinRsp->HTProfile.htSecondaryChannelOffset; +#ifdef WLAN_FEATURE_11AC + pSession->connectedProfile.HTProfile.vhtCapability = + pJoinRsp->HTProfile.vhtCapability; + pSession->connectedProfile.HTProfile.vhtTxChannelWidthSet = + pJoinRsp->HTProfile.vhtTxChannelWidthSet; + pSession->connectedProfile.HTProfile.apCenterChan = + pJoinRsp->HTProfile.apCenterChan; + pSession->connectedProfile.HTProfile.apChanWidth = + pJoinRsp->HTProfile.apChanWidth; +#endif + } +#endif + } + else + { + if(pCommand->u.roamCmd.fReassoc) + { + roamInfo.fReassocReq = roamInfo.fReassocRsp = eANI_BOOLEAN_TRUE; + roamInfo.nAssocReqLength = pSession->connectedInfo.nAssocReqLength; + roamInfo.nAssocRspLength = pSession->connectedInfo.nAssocRspLength; + roamInfo.nBeaconLength = pSession->connectedInfo.nBeaconLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + } + } + + /* Update the staId from the previous connected profile info + as the reassociation is triggred at SME/HDD */ + if ((eCsrHddIssuedReassocToSameAP == + pCommand->u.roamCmd.roamReason) || + (eCsrSmeIssuedReassocToSameAP == + pCommand->u.roamCmd.roamReason)) + roamInfo.staId = pSession->connectedInfo.staId; + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + // Indicate SME-QOS with reassoc success event, only after + // copying the frames + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, ind_qos, &assocInfo); +#endif + roamInfo.pBssDesc = pSirBssDesc; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, pSirBssDesc, NULL); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + pSession->connectedProfile.acm_mask = acm_mask; + //start UAPSD if uapsd_mask is not 0 because HDD will configure for trigger frame + //It may be better to let QoS do this???? + if( pSession->connectedProfile.modifyProfileFields.uapsd_mask ) + { + smsLog(pMac, LOGE, " uapsd_mask (0x%X) set, request UAPSD now", + pSession->connectedProfile.modifyProfileFields.uapsd_mask); + if(!pMac->psOffloadEnabled) + { + pmcStartUapsd( pMac, NULL, NULL ); + } + else + { + pmcOffloadStartUapsd(pMac, sessionId, NULL, NULL); + } + } + pSession->connectedProfile.dot11Mode = pSession->bssParams.uCfgDot11Mode; + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + + if( pSession->bRefAssocStartCnt > 0 ) + { + pSession->bRefAssocStartCnt--; + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && ( csrIsConcurrentSessionRunning( pMac ))) + { + pMac->roam.configParam.doBMPSWorkaround = 1; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + roamInfo.roamSynchInProgress = 1; + roamInfo.synchAuthStatus = pSession->roamOffloadSynchParams.authStatus; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("LFR3:csrRoamCallCallback:eCSR_ROAM_RESULT_ASSOCIATED")); + } +#endif + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED); + } + + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_NONE, eANI_BOOLEAN_TRUE); + // reset the PMKID candidate list + csrResetPMKIDCandidateList( pMac, sessionId ); + //Update TL's AC weight base on the current EDCA parameters + //These parameters may change in the course of the connection, that sictuation + //is not taken care here. This change is mainly to address a WIFI WMM test where + //BE has a equal or higher TX priority than VI. + //We only do this for infra link + if( csrIsConnStateConnectedInfra(pMac, sessionId ) && pIes ) + { + csrCheckAndUpdateACWeight(pMac, pIes); + } +#ifdef FEATURE_WLAN_WAPI + // reset the BKID candidate list + csrResetBKIDCandidateList( pMac, sessionId ); +#endif /* FEATURE_WLAN_WAPI */ + } + else + { + smsLog(pMac, LOGW, " Roam command doesn't have a BSS desc"); + } + csrScanCancelIdleScan(pMac); + //Not to signal link up because keys are yet to be set. + //The linkup function will overwrite the sub-state that we need to keep at this point. + if( !CSR_IS_WAIT_FOR_KEY(pMac, sessionId) ) + { +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("NO CSR_IS_WAIT_FOR_KEY -> csrRoamLinkUp")); + } +#endif + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + } + //Check if BMPS is required and start the BMPS retry timer. Timer period is large + //enough to let security and DHCP handshake succeed before entry into BMPS + if (!pMac->psOffloadEnabled && pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(pMac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP) + != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGP, FL("Cannot start BMPS Retry timer")); + } + smsLog(pMac, LOG2, FL("BMPS Retry Timer already running or started")); + } + break; + + case eCsrStartBssSuccess: + // on the StartBss Response, LIM is returning the Bss Description that we + // are beaconing. Add this Bss Description to our scan results and + // chain the Profile to this Bss Description. On a Start BSS, there was no + // detected Bss description (no partner) so we issued the Start Bss to + // start the Ibss without any Bss description. Lim was kind enough to return + // the Bss Description that we start beaconing for the newly started Ibss. + smsLog(pMac, LOG2, FL("receives start BSS ok indication")); + status = eHAL_STATUS_FAILURE; + pSmeStartBssRsp = (tSirSmeStartBssRsp *)Context; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + if( CSR_IS_IBSS( pProfile ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; + } + else if (CSR_IS_INFRA_AP(pProfile)) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED; + } + else + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED; + } + if( !CSR_IS_WDS_STA( pProfile ) ) + { + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + pSirBssDesc = &pSmeStartBssRsp->bssDescription; + if( !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs( pMac, pSirBssDesc, &pIes )) ) + { + smsLog(pMac, LOGW, FL("cannot parse IBSS IEs")); + roamInfo.pBssDesc = pSirBssDesc; + //We need to associate_complete it first, becasue Associate_start already indicated. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_IBSS_START_FAILED ); + break; + } + if (!CSR_IS_INFRA_AP(pProfile)) + { + pScanResult = csrScanAppendBssDescription(pMac, + pSirBssDesc, + pIes, FALSE, + sessionId); + } + csrRoamSaveConnectedBssDesc(pMac, sessionId, pSirBssDesc); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + if(pSirBssDesc) + { + csrRoamSaveConnectedInfomation(pMac, sessionId, pProfile, pSirBssDesc, pIes); + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + //We are doen with the IEs so free it + vos_mem_free(pIes); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + tANI_U32 bi; + + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + if(CSR_INVALID_SCANRESULT_HANDLE == pCommand->u.roamCmd.hBSSList) + { + //We start the IBSS (didn't find any matched IBSS out there) + pIbssLog->eventId = WLAN_IBSS_EVENT_START_IBSS_RSP; + } + else + { + pIbssLog->eventId = WLAN_IBSS_EVENT_JOIN_IBSS_RSP; + } + if(pSirBssDesc) + { + vos_mem_copy(pIbssLog->bssid, pSirBssDesc->bssId, 6); + pIbssLog->operatingChannel = pSirBssDesc->channelId; + } + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &bi))) + { + //***U8 is not enough for beacon interval + pIbssLog->beaconInterval = (v_U8_t)bi; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + //Only set context for non-WDS_STA. We don't even need it for WDS_AP. But since the encryption + //is WPA2-PSK so it won't matter. + if( CSR_IS_ENC_TYPE_STATIC( pProfile->negotiatedUCEncryptionType ) && !CSR_IS_INFRA_AP( pSession->pCurRoamProfile )) + { + // Issue the set Context request to LIM to establish the Broadcast STA context for the Ibss. + // In Rome IBSS case, dummy key installation will break + // proper BSS key installation, so skip it. + if (!CSR_IS_IBSS( pSession->pCurRoamProfile )) + { + csrRoamIssueSetContextReq( pMac, sessionId, + pProfile->negotiatedMCEncryptionType, + pSirBssDesc, &BroadcastMac, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + + } + } + else + { + //Keep the state to eCSR_ROAMING_STATE_JOINING + //Need to send join_req. + if(pCommand->u.roamCmd.pRoamBssEntry) + { + if((pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link))) + { + pSirBssDesc = &pScanResult->Result.BssDescriptor; + pIes = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId); + status = csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_JOIN_REQ ); + } + } + else + { + smsLog( pMac, LOGE, " StartBSS for WDS station with no BssDesc" ); + VOS_ASSERT( 0 ); + } + } + //Only tell upper layer is we start the BSS because Vista doesn't like multiple connection + //indications. If we don't start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS will + //trigger the connection start indication in Vista + if( !CSR_IS_JOIN_TO_IBSS( pProfile ) ) + { + roamStatus = eCSR_ROAM_IBSS_IND; + roamResult = eCSR_ROAM_RESULT_IBSS_STARTED; + if( CSR_IS_WDS( pProfile ) ) + { + roamStatus = eCSR_ROAM_WDS_IND; + roamResult = eCSR_ROAM_RESULT_WDS_STARTED; + } + if( CSR_IS_INFRA_AP( pProfile ) ) + { + roamStatus = eCSR_ROAM_INFRA_IND; + roamResult = eCSR_ROAM_RESULT_INFRA_STARTED; + } + + //Only tell upper layer is we start the BSS because Vista doesn't like multiple connection + //indications. If we don't start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS will + //trigger the connection start indication in Vista + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + //We start the IBSS (didn't find any matched IBSS out there) + roamInfo.pBssDesc = pSirBssDesc; + roamInfo.staId = (tANI_U8)pSmeStartBssRsp->staId; + vos_mem_copy(roamInfo.bssid, pSirBssDesc->bssId, + sizeof(tCsrBssid)); + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + ( csrIsConcurrentSessionRunning( pMac ))) + { + pMac->roam.configParam.doBMPSWorkaround = 1; + } + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + if (pMac->roam.configParam.cc_switch_mode + != VOS_MCC_TO_SCC_SWITCH_DISABLE) { + pSession->connectedProfile.HTProfile.phymode = + csrRoamdot11modeToPhymode(pSmeStartBssRsp->HTProfile.dot11mode); + pSession->connectedProfile.HTProfile.htCapability = + pSmeStartBssRsp->HTProfile.htCapability; + pSession->connectedProfile.HTProfile.htSupportedChannelWidthSet = + pSmeStartBssRsp->HTProfile.htSupportedChannelWidthSet; + pSession->connectedProfile.HTProfile.htRecommendedTxWidthSet = + pSmeStartBssRsp->HTProfile.htRecommendedTxWidthSet; + pSession->connectedProfile.HTProfile.htSecondaryChannelOffset = + pSmeStartBssRsp->HTProfile.htSecondaryChannelOffset; +#ifdef WLAN_FEATURE_11AC + pSession->connectedProfile.HTProfile.vhtCapability = + pSmeStartBssRsp->HTProfile.vhtCapability; + pSession->connectedProfile.HTProfile.vhtTxChannelWidthSet = + pSmeStartBssRsp->HTProfile.vhtTxChannelWidthSet; + pSession->connectedProfile.HTProfile.apCenterChan = + pSmeStartBssRsp->HTProfile.apCenterChan; + pSession->connectedProfile.HTProfile.apChanWidth = + pSmeStartBssRsp->HTProfile.apChanWidth; +#endif + } +#endif + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, roamStatus, roamResult ); + } + + csrScanCancelIdleScan(pMac); + + if( CSR_IS_WDS_STA( pProfile ) ) + { + //need to send stop BSS because we fail to send join_req + csrRoamIssueDisassociateCmd( pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED ); + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_STOPPED ); + } + break; + case eCsrStartBssFailure: +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->status = WLAN_IBSS_STATUS_FAILURE; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + roamStatus = eCSR_ROAM_IBSS_IND; + roamResult = eCSR_ROAM_RESULT_IBSS_STARTED; + if( CSR_IS_WDS( pProfile ) ) + { + roamStatus = eCSR_ROAM_WDS_IND; + roamResult = eCSR_ROAM_RESULT_WDS_STARTED; + } + if( CSR_IS_INFRA_AP( pProfile ) ) + { + roamStatus = eCSR_ROAM_INFRA_IND; + roamResult = eCSR_ROAM_RESULT_INFRA_START_FAILED; + } + if(Context) + { + pSirBssDesc = (tSirBssDescription *)Context; + } + else + { + pSirBssDesc = NULL; + } + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pSirBssDesc; + //We need to associate_complete it first, becasue Associate_start already indicated. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, roamStatus, roamResult ); + csrSetDefaultDot11Mode( pMac ); + break; + case eCsrSilentlyStopRoaming: + // We are here because we try to start the same IBSS + //No message to PE + // return the roaming state to Joined. + smsLog(pMac, LOGW, FL("receives silently roaming indication")); + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pSession->pConnectBssDesc; + if( roamInfo.pBssDesc ) + { + vos_mem_copy(&roamInfo.bssid, &roamInfo.pBssDesc->bssId, + sizeof(tCsrBssid)); + } + //Since there is no change in the current state, simply pass back no result otherwise + //HDD may be mistakenly mark to disconnected state. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_NONE ); + break; + case eCsrSilentlyStopRoamingSaveState: + //We are here because we try to connect to the same AP + //No message to PE + smsLog(pMac, LOGW, FL("receives silently stop roaming indication")); + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + + //to aviod resetting the substate to NONE + pMac->roam.curState[sessionId] = eCSR_ROAMING_STATE_JOINED; + //No need to change substate to wai_for_key because there is no state change + roamInfo.pBssDesc = pSession->pConnectBssDesc; + if( roamInfo.pBssDesc ) + { + vos_mem_copy(&roamInfo.bssid, &roamInfo.pBssDesc->bssId, + sizeof(tCsrBssid)); + } + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + roamInfo.nBeaconLength = pSession->connectedInfo.nBeaconLength; + roamInfo.nAssocReqLength = pSession->connectedInfo.nAssocReqLength; + roamInfo.nAssocRspLength = pSession->connectedInfo.nAssocRspLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + roamInfo.staId = pSession->connectedInfo.staId; + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + if (0 == roamInfo.staId) + { + VOS_ASSERT( 0 ); + return eANI_BOOLEAN_FALSE; + } + pSession->bRefAssocStartCnt--; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED); + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_ASSOCIATED, eANI_BOOLEAN_TRUE); + break; + case eCsrReassocFailure: +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_REASSOC_FAILURE, NULL); +#endif + case eCsrJoinWdsFailure: + smsLog(pMac, LOGW, FL("failed to join WDS")); + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, + eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED); + //Need to issue stop_bss + break; + case eCsrJoinFailure: + case eCsrNothingToJoin: + case eCsrJoinFailureDueToConcurrency: + default: + { + smsLog(pMac, LOGW, FL("receives no association indication")); + smsLog(pMac, LOG1, FL("Assoc ref count %d"), + pSession->bRefAssocStartCnt); + if( CSR_IS_INFRASTRUCTURE( &pSession->connectedProfile ) || + CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, sessionId ) ) + { + //do not free for the other profiles as we need to send down stop BSS later + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + csrSetDefaultDot11Mode( pMac ); + } + + switch( pCommand->u.roamCmd.roamReason ) + { + // If this transition is because of an 802.11 OID, then we transition + // back to INIT state so we sit waiting for more OIDs to be issued and + // we don't start the IDLE timer. + case eCsrSmeIssuedFTReassoc: + case eCsrSmeIssuedAssocToSimilarAP: + case eCsrHddIssued: + case eCsrSmeIssuedDisassocForHandoff: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.pProfile = &pCommand->u.roamCmd.roamProfile; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + vos_mem_copy(&roamInfo.bssid, + &pSession->joinFailStatusCode.bssId, + sizeof(tCsrBssid)); + + /* Defeaturize this later if needed */ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + /* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */ + if (csrRoamIsHandoffInProgress(pMac, sessionId)) + { + /* Should indicate neighbor roam algorithm about the connect failure here */ + csrNeighborRoamIndicateConnect(pMac, (tANI_U8)sessionId, VOS_STATUS_E_FAILURE); + } +#endif + if(pSession->bRefAssocStartCnt > 0) + { + pSession->bRefAssocStartCnt--; + if(eCsrJoinFailureDueToConcurrency == Result) + { + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL); + } + else + { + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_FAILURE); + } + } + else + { + /* bRefAssocStartCnt is not incremented when + * eRoamState == eCsrStopRoamingDueToConcurrency + * in csrRoamJoinNextBss API. so handle this in + * else case by sending assoc failure + */ + csrRoamCallCallback(pMac, sessionId, &roamInfo, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_FAILURE); + } + smsLog(pMac, LOG1, FL(" roam(reason %d) failed"), pCommand->u.roamCmd.roamReason); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosUpdateHandOff((tANI_U8)sessionId, VOS_FALSE); + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrScanStartIdleScan(pMac); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //For WDS STA. To fix the issue where the WDS AP side may be too busy by + //BT activity and not able to recevie WLAN traffic. Retry the join + if( CSR_IS_WDS_STA(pProfile) ) + { + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + break; + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId); + + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrScanStartIdleScan(pMac); + break; + case eCsrForcedDisassoc: + case eCsrForcedDeauth: + case eCsrSmeIssuedIbssJoinFailure: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId); + + if(eCsrSmeIssuedIbssJoinFailure == pCommand->u.roamCmd.roamReason) + { + // Notify HDD that IBSS join failed + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_IBSS_JOIN_FAILED); + } + else + { + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + + /* + DelSta not done FW still in conneced state so dont + issue IMPS req + */ + + if (pMac->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) + { + smsLog(pMac, LOGW, FL("FW still in connected state ")); + break; + } + csrScanStartIdleScan(pMac); + break; + case eCsrForcedIbssLeave: + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_LEAVE, + eCSR_ROAM_RESULT_IBSS_STOP); + break; + case eCsrForcedDisassocMICFailure: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_MIC_FAILURE); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_REQ, NULL); +#endif + csrScanStartIdleScan(pMac); + break; + case eCsrStopBss: + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_STOPPED); + break; + case eCsrForcedDisassocSta: + case eCsrForcedDeauthSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId); + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + vos_mem_copy(roamInfo.peerMac, + pCommand->u.roamCmd.peerMac, + sizeof(tSirMacAddr)); + roamInfo.reasonCode = eCSR_ROAM_RESULT_FORCED; + roamInfo.statusCode = eSIR_SME_SUCCESS; + status = csrRoamCallCallback(pMac, sessionId, + &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED); + } + } + break; + case eCsrLostLink1: + // if lost link roam1 failed, then issue lost link Scan2 ... + csrScanRequestLostLink2(pMac, sessionId); + break; + case eCsrLostLink2: + // if lost link roam2 failed, then issue lost link scan3 ... + csrScanRequestLostLink3(pMac, sessionId); + break; + case eCsrLostLink3: + default: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + + //We are done with one round of lostlink roaming here + csrScanHandleFailedLostlink3(pMac, sessionId); + break; + } + break; + } + } + return ( fReleaseCommand ); +} + +eHalStatus csrRoamCopyProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pDstProfile, tCsrRoamProfile *pSrcProfile) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 size = 0; + + do + { + vos_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0); + if(pSrcProfile->BSSIDs.numOfBSSIDs) + { + size = sizeof(tCsrBssid) * pSrcProfile->BSSIDs.numOfBSSIDs; + pDstProfile->BSSIDs.bssid = vos_mem_malloc(size); + if ( NULL == pDstProfile->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->BSSIDs.numOfBSSIDs = pSrcProfile->BSSIDs.numOfBSSIDs; + vos_mem_copy(pDstProfile->BSSIDs.bssid, + pSrcProfile->BSSIDs.bssid, size); + } + if(pSrcProfile->SSIDs.numOfSSIDs) + { + size = sizeof(tCsrSSIDInfo) * pSrcProfile->SSIDs.numOfSSIDs; + pDstProfile->SSIDs.SSIDList = vos_mem_malloc(size); + if ( NULL == pDstProfile->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->SSIDs.numOfSSIDs = pSrcProfile->SSIDs.numOfSSIDs; + vos_mem_copy(pDstProfile->SSIDs.SSIDList, + pSrcProfile->SSIDs.SSIDList, size); + } + if(pSrcProfile->nWPAReqIELength) + { + pDstProfile->pWPAReqIE = vos_mem_malloc(pSrcProfile->nWPAReqIELength); + if ( NULL == pDstProfile->pWPAReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nWPAReqIELength = pSrcProfile->nWPAReqIELength; + vos_mem_copy(pDstProfile->pWPAReqIE, pSrcProfile->pWPAReqIE, + pSrcProfile->nWPAReqIELength); + } + if(pSrcProfile->nRSNReqIELength) + { + pDstProfile->pRSNReqIE = vos_mem_malloc(pSrcProfile->nRSNReqIELength); + if ( NULL == pDstProfile->pRSNReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nRSNReqIELength = pSrcProfile->nRSNReqIELength; + vos_mem_copy(pDstProfile->pRSNReqIE, pSrcProfile->pRSNReqIE, + pSrcProfile->nRSNReqIELength); + } +#ifdef FEATURE_WLAN_WAPI + if(pSrcProfile->nWAPIReqIELength) + { + pDstProfile->pWAPIReqIE = vos_mem_malloc(pSrcProfile->nWAPIReqIELength); + if ( NULL == pDstProfile->pWAPIReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nWAPIReqIELength = pSrcProfile->nWAPIReqIELength; + vos_mem_copy(pDstProfile->pWAPIReqIE, pSrcProfile->pWAPIReqIE, + pSrcProfile->nWAPIReqIELength); + } +#endif /* FEATURE_WLAN_WAPI */ + if(pSrcProfile->nAddIEScanLength) + { + pDstProfile->pAddIEScan = vos_mem_malloc(pSrcProfile->nAddIEScanLength); + if ( NULL == pDstProfile->pAddIEScan ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nAddIEScanLength = pSrcProfile->nAddIEScanLength; + vos_mem_copy(pDstProfile->pAddIEScan, pSrcProfile->pAddIEScan, + pSrcProfile->nAddIEScanLength); + } + if(pSrcProfile->nAddIEAssocLength) + { + pDstProfile->pAddIEAssoc = vos_mem_malloc(pSrcProfile->nAddIEAssocLength); + if ( NULL == pDstProfile->pAddIEAssoc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength; + vos_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, + pSrcProfile->nAddIEAssocLength); + } + if(pSrcProfile->ChannelInfo.ChannelList) + { + pDstProfile->ChannelInfo.ChannelList = vos_mem_malloc( + pSrcProfile->ChannelInfo.numOfChannels); + if ( NULL == pDstProfile->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->ChannelInfo.numOfChannels = pSrcProfile->ChannelInfo.numOfChannels; + vos_mem_copy(pDstProfile->ChannelInfo.ChannelList, + pSrcProfile->ChannelInfo.ChannelList, + pSrcProfile->ChannelInfo.numOfChannels); + } + pDstProfile->AuthType = pSrcProfile->AuthType; + pDstProfile->EncryptionType = pSrcProfile->EncryptionType; + pDstProfile->mcEncryptionType = pSrcProfile->mcEncryptionType; + pDstProfile->negotiatedUCEncryptionType = pSrcProfile->negotiatedUCEncryptionType; + pDstProfile->negotiatedMCEncryptionType = pSrcProfile->negotiatedMCEncryptionType; + pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType; +#ifdef WLAN_FEATURE_11W + pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled; + pDstProfile->MFPRequired = pSrcProfile->MFPRequired; + pDstProfile->MFPCapable = pSrcProfile->MFPCapable; +#endif + pDstProfile->BSSType = pSrcProfile->BSSType; + pDstProfile->phyMode = pSrcProfile->phyMode; + pDstProfile->csrPersona = pSrcProfile->csrPersona; + +#ifdef FEATURE_WLAN_WAPI + if(csrIsProfileWapi(pSrcProfile)) + { + if(pDstProfile->phyMode & eCSR_DOT11_MODE_11n) + { + pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n; + } + } +#endif /* FEATURE_WLAN_WAPI */ + pDstProfile->CBMode = pSrcProfile->CBMode; + /*Save the WPS info*/ + pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation; + pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation; + pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask; + pDstProfile->beaconInterval = pSrcProfile->beaconInterval; + pDstProfile->privacy = pSrcProfile->privacy; + pDstProfile->fwdWPSPBCProbeReq = pSrcProfile->fwdWPSPBCProbeReq; + pDstProfile->csr80211AuthType = pSrcProfile->csr80211AuthType; + pDstProfile->dtimPeriod = pSrcProfile->dtimPeriod; + pDstProfile->ApUapsdEnable = pSrcProfile->ApUapsdEnable; + pDstProfile->SSIDs.SSIDList[0].ssidHidden = pSrcProfile->SSIDs.SSIDList[0].ssidHidden; + pDstProfile->protEnabled = pSrcProfile->protEnabled; + pDstProfile->obssProtEnabled = pSrcProfile->obssProtEnabled; + pDstProfile->cfg_protection = pSrcProfile->cfg_protection; + pDstProfile->wps_state = pSrcProfile->wps_state; + pDstProfile->ieee80211d = pSrcProfile->ieee80211d; + pDstProfile->sap_dot11mc = pSrcProfile->sap_dot11mc; + vos_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys, + sizeof(pDstProfile->Keys)); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSrcProfile->MDID.mdiePresent) + { + pDstProfile->MDID.mdiePresent = 1; + pDstProfile->MDID.mobilityDomain = pSrcProfile->MDID.mobilityDomain; + } +#endif + vos_mem_copy(&pDstProfile->addIeParams, + &pSrcProfile->addIeParams, + sizeof(tSirAddIeParams)); + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseProfile(pMac, pDstProfile); + pDstProfile = NULL; + } + + return (status); +} + +eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamConnectedProfile *pSrcProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + do + { + vos_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0); + if(pSrcProfile->bssid) + { + pDstProfile->BSSIDs.bssid = vos_mem_malloc(sizeof(tCsrBssid)); + if ( NULL == pDstProfile->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pDstProfile->BSSIDs.bssid, pSrcProfile->bssid, + sizeof(tCsrBssid)); + } + if(pSrcProfile->SSID.ssId) + { + pDstProfile->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pDstProfile->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->SSIDs.numOfSSIDs = 1; + pDstProfile->SSIDs.SSIDList[0].handoffPermitted = pSrcProfile->handoffPermitted; + pDstProfile->SSIDs.SSIDList[0].ssidHidden = pSrcProfile->ssidHidden; + vos_mem_copy(&pDstProfile->SSIDs.SSIDList[0].SSID, + &pSrcProfile->SSID, sizeof(tSirMacSSid)); + } + if(pSrcProfile->nAddIEAssocLength) + { + pDstProfile->pAddIEAssoc = vos_mem_malloc(pSrcProfile->nAddIEAssocLength); + if ( NULL == pDstProfile->pAddIEAssoc) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" failed to allocate memory for additional IEs ") ); + break; + } + pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength; + vos_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, + pSrcProfile->nAddIEAssocLength); + } + pDstProfile->ChannelInfo.ChannelList = vos_mem_malloc(1); + if ( NULL == pDstProfile->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->ChannelInfo.numOfChannels = 1; + pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel; + pDstProfile->AuthType.numEntries = 1; + pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType; + pDstProfile->negotiatedAuthType = pSrcProfile->AuthType; + pDstProfile->EncryptionType.numEntries = 1; + pDstProfile->EncryptionType.encryptionType[0] = pSrcProfile->EncryptionType; + pDstProfile->negotiatedUCEncryptionType = pSrcProfile->EncryptionType; + pDstProfile->mcEncryptionType.numEntries = 1; + pDstProfile->mcEncryptionType.encryptionType[0] = pSrcProfile->mcEncryptionType; + pDstProfile->negotiatedMCEncryptionType = pSrcProfile->mcEncryptionType; + pDstProfile->BSSType = pSrcProfile->BSSType; + pDstProfile->CBMode = pSrcProfile->CBMode; + vos_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys, + sizeof(pDstProfile->Keys)); +#ifdef WLAN_FEATURE_11W + pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled; + pDstProfile->MFPRequired = pSrcProfile->MFPRequired; + pDstProfile->MFPCapable = pSrcProfile->MFPCapable; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSrcProfile->MDID.mdiePresent) + { + pDstProfile->MDID.mdiePresent = 1; + pDstProfile->MDID.mobilityDomain = pSrcProfile->MDID.mobilityDomain; + } +#endif + + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseProfile(pMac, pDstProfile); + pDstProfile = NULL; + } + + return (status); +} + +eHalStatus csrRoamIssueConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBSSList, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate, + tANI_BOOLEAN fClearScan) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + if( fClearScan ) + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + } + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + if(NULL == pProfile) + { + //We can roam now + //Since pProfile is NULL, we need to build our own profile, set everything to default + //We can only support open and no encryption + pCommand->u.roamCmd.roamProfile.AuthType.numEntries = 1; + pCommand->u.roamCmd.roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pCommand->u.roamCmd.roamProfile.EncryptionType.numEntries = 1; + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pCommand->u.roamCmd.roamProfile.csrPersona = VOS_STA_MODE; + } + else + { + //make a copy of the profile + status = csrRoamCopyProfile(pMac, &pCommand->u.roamCmd.roamProfile, pProfile); + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_TRUE; + } + } + + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.hBSSList = hBSSList; + pCommand->u.roamCmd.roamId = roamId; + pCommand->u.roamCmd.roamReason = reason; + //We need to free the BssList when the command is done + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_TRUE; + pCommand->u.roamCmd.fUpdateCurRoamProfile = eANI_BOOLEAN_TRUE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("CSR PERSONA=%d"), + pCommand->u.roamCmd.roamProfile.csrPersona); + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + + return (status); +} +eHalStatus csrRoamIssueReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields *pMmodProfileFields, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + if(pProfile) + { + //This is likely trying to reassoc to different profile + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + //make a copy of the profile + status = csrRoamCopyProfile(pMac, &pCommand->u.roamCmd.roamProfile, pProfile); + pCommand->u.roamCmd.fUpdateCurRoamProfile = eANI_BOOLEAN_TRUE; + } + else + { + status = csrRoamCopyConnectedProfile(pMac, sessionId, &pCommand->u.roamCmd.roamProfile); + //how to update WPA/WPA2 info in roamProfile?? + pCommand->u.roamCmd.roamProfile.uapsd_mask = pMmodProfileFields->uapsd_mask; + } + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_TRUE; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamId = roamId; + pCommand->u.roamCmd.roamReason = reason; + //We need to free the BssList when the command is done + //For reassoc there is no BSS list, so the boolean set to false + pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_FALSE; + pCommand->u.roamCmd.fReassoc = eANI_BOOLEAN_TRUE; + csrRoamRemoveDuplicateCommand(pMac, sessionId, pCommand, reason); + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + return (status); +} + +eHalStatus csrRoamEnqueuePreauth(tpAniSirGlobal pMac, tANI_U32 sessionId, tpSirBssDescription pBssDescription, + eCsrRoamReason reason, tANI_BOOLEAN fImmediate) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + if(pBssDescription) + { + //copy over the parameters we need later + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = reason; + //this is the important parameter + //in this case we are using this field for the "next" BSS + pCommand->u.roamCmd.pLastRoamBss = pBssDescription; + status = csrQueueSmeCommand(pMac, pCommand, fImmediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to enqueue preauth command, status = %d"), status ); + csrReleaseCommandPreauth( pMac, pCommand ); + } + } + else + { + //Return failure + status = eHAL_STATUS_RESOURCES; + } + } + return (status); +} + +eHalStatus csrDequeueRoamCommand(tpAniSirGlobal pMac, eCsrRoamReason reason) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( (eSmeCommandRoam == pCommand->command) && + (eCsrPerformPreauth == reason)) + { + smsLog( pMac, LOG1, FL("DQ-Command = %d, Reason = %d"), + pCommand->command, pCommand->u.roamCmd.roamReason); + if (csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK )) { + csrReleaseCommandPreauth( pMac, pCommand ); + } + } + else if ((eSmeCommandRoam == pCommand->command) && + (eCsrSmeIssuedFTReassoc == reason)) + { + smsLog( pMac, LOG1, FL("DQ-Command = %d, Reason = %d"), + pCommand->command, pCommand->u.roamCmd.roamReason); + if (csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK )) { + csrReleaseCommandRoam( pMac, pCommand ); + } + } + else { + smsLog( pMac, LOGE, FL("Command = %d, Reason = %d "), + pCommand->command, pCommand->u.roamCmd.roamReason); + } + } + else { + smsLog( pMac, LOGE, FL("pEntry NULL for eWNI_SME_FT_PRE_AUTH_RSP")); + } + smeProcessPendingQueue( pMac ); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrRoamConnectWithBSSList(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList; + tANI_U32 roamId = 0; + status = csrScanCopyResultList(pMac, hBssListIn, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("failed to start a join process")); + csrScanResultPurge(pMac, hBSSList); + } + } + return (status); +} + +eHalStatus csrRoamConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tScanResultHandle hBSSList; + tCsrScanResultFilter *pScanFilter; + tANI_U32 roamId = 0; + tANI_BOOLEAN fCallCallback = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (NULL == pSession) { + smsLog(pMac, LOGE, + FL("session does not exist for given sessionId:%d"), sessionId); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pProfile) { + smsLog(pMac, LOGP, FL("No profile specified")); + return eHAL_STATUS_FAILURE; + } + /* Initialize the bssid count before proceeding with the Join requests */ + pSession->join_bssid_count = 0; + smsLog(pMac, LOG1, FL("called BSSType = %d authtype = %d encryType = %d"), + pProfile->BSSType, pProfile->AuthType.authType[0], pProfile->EncryptionType.encryptionType[0]); + if( CSR_IS_WDS( pProfile ) && + !HAL_STATUS_SUCCESS( status = csrIsBTAMPAllowed( pMac, pProfile->operationChannel ) ) ) + { + smsLog(pMac, LOGE, FL("Request for BT AMP connection failed, channel requested is different than infra = %d"), + pProfile->operationChannel); + return status; + } + csrRoamCancelRoaming(pMac, sessionId); + csrScanRemoveFreshScanCommand(pMac, sessionId); + csrScanCancelIdleScan(pMac); + //Only abort the scan if it is not used for other roam/connect purpose + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + if (!vos_concurrent_open_sessions_running() && + (VOS_STA_SAP_MODE == pProfile->csrPersona)) + { + /* In case of AP mode we do not want idle mode scan */ + csrScanDisable(pMac); + } + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssued); + //Check whether ssid changes + if(csrIsConnStateConnected(pMac, sessionId)) + { + if(pProfile->SSIDs.numOfSSIDs && !csrIsSsidInList(pMac, &pSession->connectedProfile.SSID, &pProfile->SSIDs)) + { + csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT; +#endif + if(CSR_INVALID_SCANRESULT_HANDLE != hBssListIn) + { + smsLog(pMac, LOG1, FL("is called with BSSList")); + status = csrRoamConnectWithBSSList(pMac, sessionId, pProfile, hBssListIn, pRoamId); + if(pRoamId) + { + roamId = *pRoamId; + } + if(!HAL_STATUS_SUCCESS(status)) + { + fCallCallback = eANI_BOOLEAN_TRUE; + } + } + else + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Try to connect to any BSS + if(NULL == pProfile) + { + //No encryption + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + }//we don't have a profile + else + { + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + if(HAL_STATUS_SUCCESS(status)) + { + /*Save the WPS info*/ + if(NULL != pProfile) + { + pScanFilter->bWPSAssociation = pProfile->bWPSAssociation; + pScanFilter->bOSENAssociation = pProfile->bOSENAssociation; + } + else + { + pScanFilter->bWPSAssociation = 0; + pScanFilter->bOSENAssociation = 0; + } + do + { + if( (pProfile && CSR_IS_WDS_AP( pProfile ) ) + || (pProfile && CSR_IS_INFRA_AP ( pProfile )) + ) + { + //This can be started right away + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue start BSS command with status = 0x%08X"), status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + else + { + smsLog(pMac, LOG1, FL("Connect request to proceed for AMP/SoftAP mode")); + } + break; + } + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + smsLog(pMac, LOG1, "************ csrScanGetResult Status ********* %d", status); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue connect command with status = 0x%08X"), status); + csrScanResultPurge(pMac, hBSSList); + fCallCallback = eANI_BOOLEAN_TRUE; + } + }//Have scan result + else if(NULL != pProfile) + { + //Check whether it is for start ibss + if(CSR_IS_START_IBSS(pProfile)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " CSR failed to issue startIBSS command with status = 0x%08X", status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + } + else + { + //scan for this SSID + status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue SSID scan command with status = 0x%08X"), status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + else + { + smsLog(pMac, LOG1, FL("SSID scan requested for Infra connect req")); + } + } + } + else + { + fCallCallback = eANI_BOOLEAN_TRUE; + } + } while (0); + if(NULL != pProfile) + { + //we need to free memory for filter if profile exists + csrFreeScanFilter(pMac, pScanFilter); + } + }//Got the scan filter from profile + + vos_mem_free(pScanFilter); + }//allocated memory for pScanFilter + }//No Bsslist coming in + //tell the caller if we fail to trigger a join request + if( fCallCallback ) + { + csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + + return (status); +} +eHalStatus csrRoamReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fCallCallback = eANI_BOOLEAN_TRUE; + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pProfile) + { + smsLog(pMac, LOGP, FL("No profile specified")); + return eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL("called BSSType = %d authtype = %d encryType = %d"), pProfile->BSSType, pProfile->AuthType.authType[0], pProfile->EncryptionType.encryptionType[0]); + csrRoamCancelRoaming(pMac, sessionId); + csrScanRemoveFreshScanCommand(pMac, sessionId); + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssuedReassocToSameAP); + if(csrIsConnStateConnected(pMac, sessionId)) + { + if(pProfile) + { + if(pProfile->SSIDs.numOfSSIDs && + csrIsSsidInList(pMac, &pSession->connectedProfile.SSID, &pProfile->SSIDs)) + { + fCallCallback = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOG1, FL("Not connected to the same SSID asked in the profile")); + } + } + else if (!vos_mem_compare(&modProfileFields, + &pSession->connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields))) + { + fCallCallback = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOG1, FL("Either the profile is NULL or none of the fields " + "in tCsrRoamModifyProfileFields got modified")); + } + } + else + { + smsLog(pMac, LOG1, FL("Not connected! No need to reassoc")); + } + if(!fCallCallback) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + status = csrRoamIssueReassoc(pMac, sessionId, pProfile, &modProfileFields, + eCsrHddIssuedReassocToSameAP, roamId, eANI_BOOLEAN_FALSE); + } + else + { + status = csrRoamCallCallback(pMac, sessionId, NULL, roamId, + eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + return status; +} +eHalStatus csrRoamJoinLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + if(pSession->pCurRoamProfile) + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if (!HAL_STATUS_SUCCESS(status)) + break; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + break; + } + } + else + { + //Do a scan on this profile + //scan for this SSID only in case the AP suppresses SSID + status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + } + }//We have a profile + else + { + smsLog(pMac, LOGW, FL("cannot find a roaming profile")); + break; + } + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + return (status); +} +eHalStatus csrRoamReconnect(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + if(csrIsConnStateConnected(pMac, sessionId)) + { + status = csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrRoamJoinLastProfile(pMac, sessionId); + } + } + return (status); +} + +eHalStatus csrRoamConnectToLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGW, FL("is called")); + csrRoamCancelRoaming(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssued); + if(csrIsConnStateDisconnected(pMac, sessionId)) + { + status = csrRoamJoinLastProfile(pMac, sessionId); + } + return (status); +} + +eHalStatus csrRoamProcessDisassocDeauth( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fDisassoc, tANI_BOOLEAN fMICFailure ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fComplete = eANI_BOOLEAN_FALSE; + eCsrRoamSubState NewSubstate; + tANI_U32 sessionId = pCommand->sessionId; + + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" Stop Wait for key timer and change substate to" + " eCSR_ROAM_SUBSTATE_NONE")); + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + // change state to 'Roaming'... + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + // If we are in an IBSS, then stop the IBSS... + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + else if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" restore AC weights (%d-%d-%d-%d)"), pMac->roam.ucACWeights[0], pMac->roam.ucACWeights[1], + pMac->roam.ucACWeights[2], pMac->roam.ucACWeights[3]); + //Restore AC weight in case we change it + WLANTL_SetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + // in Infrasturcture, we need to disassociate from the Infrastructure network... + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED; + if(eCsrSmeIssuedDisassocForHandoff == pCommand->u.roamCmd.roamReason) + { + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF; + } + else if ((eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason) + && (eSIR_MAC_DISASSOC_LEAVING_BSS_REASON == + pCommand->u.roamCmd.reason)) + { + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("set to substate eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT")); + } + if( fDisassoc ) + { + status = csrRoamIssueDisassociate( pMac, sessionId, NewSubstate, fMICFailure ); + } + else + { + status = csrRoamIssueDeauth( pMac, sessionId, eCSR_ROAM_SUBSTATE_DEAUTH_REQ ); + } + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + else if ( csrIsConnStateWds( pMac, sessionId ) ) + { + if( CSR_IS_WDS_AP( &pMac->roam.roamSession[sessionId].connectedProfile ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + //This has to be WDS station + else if( csrIsConnStateConnectedWds( pMac, sessionId ) ) //This has to be WDS station + { + + pCommand->u.roamCmd.fStopWds = eANI_BOOLEAN_TRUE; + if( fDisassoc ) + { + status = csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, fMICFailure ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + } + } else { + // we got a dis-assoc request while not connected to any peer + // just complete the command + fComplete = eANI_BOOLEAN_TRUE; + status = eHAL_STATUS_FAILURE; + } + if(fComplete) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + + if(HAL_STATUS_SUCCESS(status)) + { + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + //Set the state to disconnect here + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } + } + else + { + smsLog(pMac, LOGW, FL(" failed with status %d"), status); + } + return (status); +} + + +eHalStatus csrRoamIssueDisassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + tANI_BOOLEAN fHighPriority = eANI_BOOLEAN_FALSE; + do + { + smsLog( pMac, LOG1, FL(" reason = %d"), reason ); + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + switch ( reason ) + { + case eCSR_DISCONNECT_REASON_MIC_ERROR: + pCommand->u.roamCmd.roamReason = eCsrForcedDisassocMICFailure; + break; + case eCSR_DISCONNECT_REASON_DEAUTH: + pCommand->u.roamCmd.roamReason = eCsrForcedDeauth; + break; + case eCSR_DISCONNECT_REASON_HANDOFF: + fHighPriority = eANI_BOOLEAN_TRUE; + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedDisassocForHandoff; + break; + case eCSR_DISCONNECT_REASON_UNSPECIFIED: + case eCSR_DISCONNECT_REASON_DISASSOC: + pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc; + break; + case eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE: + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedIbssJoinFailure; + break; + case eCSR_DISCONNECT_REASON_IBSS_LEAVE: + pCommand->u.roamCmd.roamReason = eCsrForcedIbssLeave; + break; + case eCSR_DISCONNECT_REASON_STA_HAS_LEFT: + pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc; + pCommand->u.roamCmd.reason = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("SME convert to internal reason code eCsrStaHasLeft")); + break; + default: + break; + } + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } while( 0 ); + return( status ); +} + +eHalStatus csrRoamIssueStopBssCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN fHighPriority ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer( pMac ); + if ( NULL != pCommand ) + { + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrStopBss; + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + return ( status ); +} + +eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //Stop te retry + pSession->maxRetryCount = 0; + csrRoamStopJoinRetryTimer(pMac, sessionId); +#endif + //Not to call cancel roaming here + //Only issue disconnect when necessary + if(csrIsConnStateConnected(pMac, sessionId) || csrIsBssTypeIBSS(pSession->connectedProfile.BSSType) + || csrIsBssTypeWDS(pSession->connectedProfile.BSSType) + || csrIsRoamCommandWaitingForSession(pMac, sessionId) ) + + { + smsLog(pMac, LOG2, FL("called")); + status = csrRoamIssueDisassociateCmd(pMac, sessionId, reason); + } + else + { + csrScanAbortScanForSSID(pMac, sessionId); + status = eHAL_STATUS_CMD_NOT_QUEUED; + smsLog( pMac, LOG1, FL(" Disconnect cmd not queued, Roam command is not present" + " return with status %d"), status); + } + return (status); +} + +eHalStatus csrRoamDisconnect(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + csrRoamCancelRoaming(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrForcedDisassoc); + + return (csrRoamDisconnectInternal(pMac, sessionId, reason)); +} + +eHalStatus csrRoamSaveConnectedInfomation(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tDot11fBeaconIEs *pIesTemp = pIes; + tANI_U8 index; + tCsrRoamSession *pSession = NULL; + tCsrRoamConnectedProfile *pConnectProfile = NULL; + + pSession = CSR_GET_SESSION(pMac, sessionId); + if (NULL == pSession) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + + pConnectProfile = &pSession->connectedProfile; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("csrRoamSaveConnectedInfomation")); + } +#endif + if(pConnectProfile->pAddIEAssoc) + { + vos_mem_free(pConnectProfile->pAddIEAssoc); + pConnectProfile->pAddIEAssoc = NULL; + } + vos_mem_set(&pSession->connectedProfile, sizeof(tCsrRoamConnectedProfile), 0); + pConnectProfile->AuthType = pProfile->negotiatedAuthType; + pConnectProfile->AuthInfo = pProfile->AuthType; + pConnectProfile->CBMode = pProfile->CBMode; //*** this may not be valid + pConnectProfile->EncryptionType = pProfile->negotiatedUCEncryptionType; + pConnectProfile->EncryptionInfo = pProfile->EncryptionType; + pConnectProfile->mcEncryptionType = pProfile->negotiatedMCEncryptionType; + pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType; + pConnectProfile->BSSType = pProfile->BSSType; + pConnectProfile->modifyProfileFields.uapsd_mask = pProfile->uapsd_mask; + pConnectProfile->operationChannel = pSirBssDesc->channelId; + pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval; + if (!pConnectProfile->beaconInterval) + { + smsLog(pMac, LOGW, FL("ERROR: Beacon interval is ZERO")); + } + vos_mem_copy(&pConnectProfile->Keys, &pProfile->Keys, sizeof(tCsrKeys)); + /* saving the addional IE`s like Hot spot indication element and extended capabilities */ + if(pProfile->nAddIEAssocLength) + { + pConnectProfile->pAddIEAssoc = vos_mem_malloc(pProfile->nAddIEAssocLength); + if ( NULL == pConnectProfile->pAddIEAssoc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory for additional IEs")) ; + return eHAL_STATUS_FAILURE; + } + pConnectProfile->nAddIEAssocLength = pProfile->nAddIEAssocLength; + vos_mem_copy(pConnectProfile->pAddIEAssoc, pProfile->pAddIEAssoc, + pProfile->nAddIEAssocLength); + } + +#ifdef WLAN_FEATURE_11W + pConnectProfile->MFPEnabled = pProfile->MFPEnabled; + pConnectProfile->MFPRequired = pProfile->MFPRequired; + pConnectProfile->MFPCapable = pProfile->MFPCapable; +#endif + //Save bssid + csrGetBssIdBssDesc(pMac, pSirBssDesc, &pConnectProfile->bssid); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSirBssDesc->mdiePresent) + { + pConnectProfile->MDID.mdiePresent = 1; + pConnectProfile->MDID.mobilityDomain = (pSirBssDesc->mdie[1] << 8) | (pSirBssDesc->mdie[0]); + } +#endif + if( NULL == pIesTemp ) + { + status = csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesTemp); + } +#ifdef FEATURE_WLAN_ESE + if ((csrIsProfileESE(pProfile) || + (HAL_STATUS_SUCCESS(status) && (pIesTemp->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + pConnectProfile->isESEAssoc = 1; + } +#endif + //save ssid + if(HAL_STATUS_SUCCESS(status)) + { + if(pIesTemp->SSID.present) + { + pConnectProfile->SSID.length = pIesTemp->SSID.num_ssid; + vos_mem_copy(pConnectProfile->SSID.ssId, pIesTemp->SSID.ssid, + pIesTemp->SSID.num_ssid); + } + + //Save the bss desc + status = csrRoamSaveConnectedBssDesc(pMac, sessionId, pSirBssDesc); + + if( CSR_IS_QOS_BSS(pIesTemp) || pIesTemp->HTCaps.present) + { + //Some HT AP's dont send WMM IE so in that case we assume all HT Ap's are Qos Enabled AP's + pConnectProfile->qap = TRUE; + } + else + { + pConnectProfile->qap = FALSE; + } + + if (pIesTemp->ExtCap.present) + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + pIesTemp->ExtCap.bytes; + pConnectProfile->proxyARPService = p_ext_cap->proxyARPService; + } + + if ( NULL == pIes ) + { + //Free memory if it allocated locally + vos_mem_free(pIesTemp); + } + } + //Save Qos connection + pConnectProfile->qosConnection = pMac->roam.roamSession[sessionId].fWMMConnection; + + if(!HAL_STATUS_SUCCESS(status)) + { + csrFreeConnectBssDesc(pMac, sessionId); + } + for(index = 0; index < pProfile->SSIDs.numOfSSIDs; index++) + { + if ((pProfile->SSIDs.SSIDList[index].SSID.length == pConnectProfile->SSID.length) && + vos_mem_compare(pProfile->SSIDs.SSIDList[index].SSID.ssId, + pConnectProfile->SSID.ssId, + pConnectProfile->SSID.length)) + { + pConnectProfile->handoffPermitted = pProfile->SSIDs.SSIDList[index].handoffPermitted; + break; + } + pConnectProfile->handoffPermitted = FALSE; + } + + return (status); +} + +static void csrRoamJoinRspProcessor( tpAniSirGlobal pMac, tSirSmeJoinRsp *pSmeJoinRsp ) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession; + + if (pSmeJoinRsp) + pSession = CSR_GET_SESSION(pMac, pSmeJoinRsp->sessionId); + else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Sme Join Response is NULL")); + return; + } + if (!pSession) { + smsLog(pMac, LOGE, FL("session %d not found"), pSmeJoinRsp->sessionId); + return; + } + //The head of the active list is the request we sent + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + if ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) + { + if(pCommand && eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, pSmeJoinRsp->sessionId, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); +#endif + } + /* The join bssid count can be reset as soon as + * we are done with the join requests and returning + * the response to upper layers + */ + pSession->join_bssid_count = 0; + csrRoamComplete( pMac, eCsrJoinSuccess, (void *)pSmeJoinRsp ); + } + else + { + tANI_U32 roamId = 0; + //The head of the active list is the request we sent + //Try to get back the same profile and roam again + if(pCommand) + { + roamId = pCommand->u.roamCmd.roamId; + } + pSession->joinFailStatusCode.statusCode = pSmeJoinRsp->statusCode; + pSession->joinFailStatusCode.reasonCode = pSmeJoinRsp->protStatusCode; + smsLog( pMac, LOGW, "SmeJoinReq failed with statusCode= 0x%08X [%d]", pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode ); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */ + if (csrRoamIsHandoffInProgress(pMac, pSmeJoinRsp->sessionId)) + { + csrRoamCallCallback(pMac, pSmeJoinRsp->sessionId, NULL, roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); + /* Should indicate neighbor roam algorithm about the connect failure here */ + csrNeighborRoamIndicateConnect(pMac, pSmeJoinRsp->sessionId, VOS_STATUS_E_FAILURE); + } +#endif + if (pCommand && (pSession->join_bssid_count < CSR_MAX_BSSID_COUNT)) + { + if(CSR_IS_WDS_STA( &pCommand->u.roamCmd.roamProfile )) + { + pCommand->u.roamCmd.fStopWds = eANI_BOOLEAN_TRUE; + pSession->connectedProfile.BSSType = eCSR_BSS_TYPE_WDS_STA; + csrRoamReissueRoamCommand(pMac); + } + else if( CSR_IS_WDS( &pCommand->u.roamCmd.roamProfile ) ) + { + pSession->join_bssid_count = 0; + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else + { + csrRoam(pMac, pCommand); + } + } + else { + /* When the upper layers issue a connect command, there is a + * roam command with reason eCsrHddIssued that gets enqueued + * and an associated timer for the SME command timeout is + * started which is currently 120 seconds. This command would + * be dequeued only upon succesfull connections. In case of join + * failures, if there are too many BSS in the cache, and if we + * fail Join requests with all of them, there is a chance of + * timing out the above timer. + */ + if (pSession->join_bssid_count >= CSR_MAX_BSSID_COUNT) + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Excessive Join Request Failures")); + pSession->join_bssid_count = 0; + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + } + } /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */ +} + +eHalStatus csrRoamIssueJoin( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, + tCsrRoamProfile *pProfile, tANI_U32 roamId ) +{ + eHalStatus status; + smsLog( pMac, LOG1, "Attempting to Join Bssid= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pSirBssDesc->bssId)); + + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId); + // attempt to Join this BSS... + status = csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_JOIN_REQ ); + return (status); +} + +static eHalStatus csrRoamIssueReassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile) +{ + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL(" calling csrSendJoinReqMsg (eWNI_SME_REASSOC_REQ)")); + // attempt to Join this BSS... + return csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_REASSOC_REQ); +} + +void csrRoamReissueRoamCommand(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tCsrRoamInfo roamInfo; + tANI_U32 sessionId; + tCsrRoamSession *pSession; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if ( eSmeCommandRoam == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if( pCommand->u.roamCmd.fStopWds ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + if (CSR_IS_WDS(&pSession->connectedProfile)){ + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, + eCSR_ROAM_RESULT_WDS_DISASSOCIATED); + }else if (CSR_IS_INFRA_AP(&pSession->connectedProfile)){ + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_DISASSOCIATED); + } + + + if( !HAL_STATUS_SUCCESS( csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ) ) ) + { + smsLog(pMac, LOGE, " Failed to reissue stop_bss command for WDS after disassociated"); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + else + { + if (pSession->bRefAssocStartCnt > 0) + { + /* bRefAssocStartCnt was incremented in csrRoamJoinNextBss + * when the roam command issued previously. As part of reissuing + * the roam command again csrRoamJoinNextBss is going increment + * RefAssocStartCnt. So make sure to decrement the bRefAssocStartCnt + */ + pSession->bRefAssocStartCnt--; + } + + if(eCsrStopRoaming == csrRoamJoinNextBss(pMac, pCommand, eANI_BOOLEAN_TRUE)) + { + smsLog(pMac, LOGW, " Failed to reissue join command after disassociated"); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + } + else + { + smsLog(pMac, LOGW, " Command is not roaming after disassociated"); + } + } + else + { + smsLog(pMac, LOGE, " Disassoc rsp cannot continue because no command is available"); + } +} + +tANI_BOOLEAN csrIsRoamCommandWaitingForSession(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + tSmeCmd *pCommand = NULL; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( ( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + } + } + if(eANI_BOOLEAN_FALSE == fRet) + { + csrLLLock(&pMac->sme.smeCmdPendingList); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( ( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + pEntry = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pMac->sme.smeCmdPendingList); + } + if (eANI_BOOLEAN_FALSE == fRet) + { + csrLLLock(&pMac->roam.roamCmdPendingList); + pEntry = csrLLPeekHead(&pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK); + while (pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if (( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + pEntry = csrLLNext(&pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pMac->roam.roamCmdPendingList); + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} + +tANI_BOOLEAN csrIsRoamCommandWaiting(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && ( fRet = csrIsRoamCommandWaitingForSession( pMac, i ) ) ) + { + break; + } + } + return ( fRet ); +} + +tANI_BOOLEAN csrIsCommandWaiting(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + fRet = csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if(eANI_BOOLEAN_FALSE == fRet) + { + fRet = csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK); + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} + +tANI_BOOLEAN csrIsScanForRoamCommandActive( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + tCsrCmd *pCommand; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tCsrCmd, Link); + if( ( eCsrRoamCommandScan == pCommand->command ) && + ( ( eCsrScanForSsid == pCommand->u.scanCmd.reason ) || + ( eCsrScanForCapsChange == pCommand->u.scanCmd.reason ) || + ( eCsrScanP2PFindPeer == pCommand->u.scanCmd.reason ) ) ) + { + fRet = eANI_BOOLEAN_TRUE; + } + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} +eHalStatus csrRoamIssueReassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fHighPriority = eANI_BOOLEAN_TRUE; + tANI_BOOLEAN fRemoveCmd = FALSE; + tListElem *pEntry; + // Delete the old assoc command. All is setup for reassoc to be serialized + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + return eHAL_STATUS_RESOURCES; + } + if ( eSmeCommandRoam == pCommand->command ) + { + if (pCommand->u.roamCmd.roamReason == eCsrSmeIssuedAssocToSimilarAP) + { + fRemoveCmd = csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ); + } + else + { + smsLog( pMac, LOGE, FL(" Unexpected active roam command present ") ); + } + if (fRemoveCmd == FALSE) + { + // Implies we did not get the serialized assoc command we + // were expecting + pCommand = NULL; + } + } + } + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer as expected based on previous connect roam command") ); + return eHAL_STATUS_RESOURCES; + } + do + { + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc; + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } while( 0 ); + + return( status ); +} +static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 result ) +{ + tListElem *pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDesc = NULL; + tSmeCmd *pCommand = NULL; + tANI_U32 sessionId; + tCsrRoamSession *pSession; + if(NULL == pEntry) + { + smsLog(pMac, LOGE, " CFG_CNF with active list empty"); + return; + } + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOGW, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + } + /* If the roaming has stopped, not to continue the roaming command*/ + else if ( !CSR_IS_ROAMING(pSession) && CSR_IS_ROAMING_COMMAND(pCommand) ) + { + //No need to complete roaming here as it already completes + smsLog(pMac, LOGW, FL(" Roam command (reason %d) aborted due to roaming completed\n"), + pCommand->u.roamCmd.roamReason); + csrSetAbortRoamingCommand( pMac, pCommand ); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + } + else + { + if ( CCM_IS_RESULT_SUCCESS(result) ) + { + smsLog(pMac, LOG2, "Cfg sequence complete"); + // Successfully set the configuration parameters for the new Bss. Attempt to + // join the roaming Bss. + if(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + pBssDesc = &pScanResult->Result.BssDescriptor; + } + if ( csrIsBssTypeIBSS( pCommand->u.roamCmd.roamProfile.BSSType ) || + CSR_IS_WDS( &pCommand->u.roamCmd.roamProfile ) + || CSR_IS_INFRA_AP(&pCommand->u.roamCmd.roamProfile) + ) + { + if(!HAL_STATUS_SUCCESS(csrRoamIssueStartBss( pMac, sessionId, + &pSession->bssParams, &pCommand->u.roamCmd.roamProfile, + pBssDesc, pCommand->u.roamCmd.roamId ))) + { + smsLog(pMac, LOGE, " CSR start BSS failed"); + //We need to complete the command + csrRoamComplete(pMac, eCsrStartBssFailure, NULL); + } + } + else + { + if (!pCommand->u.roamCmd.pRoamBssEntry) + { + smsLog(pMac, LOGE, " pRoamBssEntry is NULL"); + //We need to complete the command + csrRoamComplete(pMac, eCsrJoinFailure, NULL); + return; + } + if ( NULL == pScanResult) + { + // If we are roaming TO an Infrastructure BSS... + VOS_ASSERT(pScanResult != NULL); + return; + } + if ( csrIsInfraBssDesc( pBssDesc ) ) + { + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)pScanResult->Result.pvIes; + if(pIesLocal || (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) ) + { + // ..and currently in an Infrastructure connection.... + if( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + // ...and the SSIDs are equal, then we Reassoc. + if ( csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, + pIesLocal ) ) + // ..and currently in an infrastructure connection + { + // then issue a Reassoc. + pCommand->u.roamCmd.fReassoc = eANI_BOOLEAN_TRUE; + csrRoamIssueReassociate( pMac, sessionId, pBssDesc, pIesLocal, + &pCommand->u.roamCmd.roamProfile ); + } + else + { + + // otherwise, we have to issue a new Join request to LIM because we disassociated from the + // previously associated AP. + if(!HAL_STATUS_SUCCESS(csrRoamIssueJoin( pMac, sessionId, pBssDesc, + pIesLocal, + &pCommand->u.roamCmd.roamProfile, pCommand->u.roamCmd.roamId ))) + { + //try something else + csrRoam( pMac, pCommand ); + } + } + } + else + { + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* We need to come with other way to figure out that this is because of HO in BMP + The below API will be only available for Android as it uses a different HO algorithm */ + /* Reassoc request will be used only for ESE and 11r handoff whereas other legacy roaming should + * use join request */ +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIsHandoffInProgress(pMac, sessionId) && + csrRoamIs11rAssoc(pMac, sessionId)) + { + status = csrRoamIssueReassociate(pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), &pCommand->u.roamCmd.roamProfile); + } + else +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsHandoffInProgress(pMac, sessionId) && + csrRoamIsESEAssoc(pMac, sessionId)) + { + // Now serialize the reassoc command. + status = csrRoamIssueReassociateCmd(pMac, sessionId); + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsHandoffInProgress(pMac, sessionId) && + csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + // Now serialize the reassoc command. + status = csrRoamIssueReassociateCmd(pMac, sessionId); + } + else +#endif + // else we are not connected and attempting to Join. Issue the + // Join request. + { + status = csrRoamIssueJoin( pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), + &pCommand->u.roamCmd.roamProfile, pCommand->u.roamCmd.roamId ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + //try something else + csrRoam( pMac, pCommand ); + } + } + if( !pScanResult->Result.pvIes ) + { + //Locally allocated + vos_mem_free(pIesLocal); + } + } + }//if ( csrIsInfraBssDesc( pBssDesc ) ) + else + { + smsLog(pMac, LOGW, FL(" found BSSType mismatching the one in BSS description")); + } + }//else + }//if ( WNI_CFG_SUCCESS == result ) + else + { + // In the event the configuration failed, for infra let the roam processor + //attempt to join something else... + if( pCommand->u.roamCmd.pRoamBssEntry && CSR_IS_INFRASTRUCTURE( &pCommand->u.roamCmd.roamProfile ) ) + { + csrRoam(pMac, pCommand); + } + else + { + //We need to complete the command + if ( csrIsBssTypeIBSS( pCommand->u.roamCmd.roamProfile.BSSType ) ) + { + csrRoamComplete(pMac, eCsrStartBssFailure, NULL); + } + else + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + } + }//we have active entry +} + +static void csrRoamRoamingStateReassocRspProcessor( tpAniSirGlobal pMac, tpSirSmeJoinRsp pSmeJoinRsp ) +{ + eCsrRoamCompleteResult result; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId]; + tCsrRoamInfo roamInfo; + tANI_U32 roamId = 0; + + if ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("CSR SmeReassocReq Successful")); + result = eCsrReassocSuccess; + /* Defeaturize this part later if needed */ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + /* Since the neighbor roam algorithm uses reassoc req for handoff instead of join, + * we need the response contents while processing the result in csrRoamProcessResults() */ + if (csrRoamIsHandoffInProgress(pMac, pSmeJoinRsp->sessionId)) + { + /* Need to dig more on indicating events to SME QoS module */ + sme_QosCsrEventInd(pMac, pSmeJoinRsp->sessionId, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); + csrRoamComplete( pMac, result, pSmeJoinRsp); + } + else +#endif + { + csrRoamComplete( pMac, result, NULL ); + } + } + /* Should we handle this similar to handling the join failure? Is it ok + * to call csrRoamComplete() with state as CsrJoinFailure */ + else + { + smsLog( pMac, LOGW, "CSR SmeReassocReq failed with statusCode= 0x%08X [%d]", pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode ); + result = eCsrReassocFailure; +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \ + defined(FEATURE_WLAN_LFR) + if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE == pSmeJoinRsp->statusCode) || + (eSIR_SME_FT_REASSOC_FAILURE == pSmeJoinRsp->statusCode)) { + /* Inform HDD to turn off FT flag in HDD */ + if (pNeighborRoamInfo) { + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, pSmeJoinRsp->sessionId, &roamInfo, + roamId, eCSR_ROAM_FT_REASSOC_FAILED, + eSIR_SME_SUCCESS); + /* + * Since the above callback sends a disconnect + * to HDD, we should clean-up our state + * machine as well to be in sync with the upper + * layers. There is no need to send a disassoc + * since: 1) we will never reassoc to the current + * AP in LFR, and 2) there is no need to issue a + * disassoc to the AP with which we were trying + * to reassoc. + */ + csrRoamComplete(pMac, eCsrJoinFailure, NULL); + return; + } + } +#endif + // In the event that the Reassociation fails, then we need to Disassociate the current association and keep + // roaming. Note that we will attempt to Join the AP instead of a Reassoc since we may have attempted a + // 'Reassoc to self', which AP's that don't support Reassoc will force a Disassoc. + //The disassoc rsp message will remove the command from active list + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate( pMac, pSmeJoinRsp->sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, FALSE ))) + { + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } + } +} + +static void csrRoamRoamingStateStopBssRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSmeRsp) +{ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_RSP; + if(eSIR_SME_SUCCESS != pSmeRsp->statusCode) + { + pIbssLog->status = WLAN_IBSS_STATUS_FAILURE; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + pMac->roam.roamSession[pSmeRsp->sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + if(CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, pSmeRsp->sessionId)) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if(CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE( pMac, pSmeRsp->sessionId)) + { + csrRoamReissueRoamCommand(pMac); + } +} + +void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeRsp ) +{ + tSirResultCodes statusCode; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + tScanResultHandle hBSSList; + tANI_BOOLEAN fCallCallback, fRemoveCmd; + eHalStatus status; + tCsrRoamInfo roamInfo; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pCurRoamProfile = NULL; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; +#endif + tANI_U32 sessionId; + tCsrRoamSession *pSession; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + tSirSmeDisassocRsp SmeDisassocRsp; + + csrSerDesUnpackDiassocRsp((tANI_U8 *)pSmeRsp, &SmeDisassocRsp); + sessionId = SmeDisassocRsp.sessionId; + statusCode = SmeDisassocRsp.statusCode; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("csrRoamRoamingStateDisassocRspProcessor sessionId %d"), sessionId); + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN( pMac, sessionId ) ) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED( pMac, sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ( pMac, sessionId ) ) + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + smsLog( pMac, LOG2, "CSR SmeDisassocReq force disassociated Successfully" ); + //A callback to HDD will be issued from csrRoamComplete so no need to do anything here + } + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "CSR SmeDisassocReq due to HO on session %d", sessionId ); + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; +#if defined (WLAN_FEATURE_NEIGHBOR_ROAMING) + /* + * First ensure if the roam profile is in the scan cache. + * If not, post a reassoc failure and disconnect. + */ + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, + &pNeighborRoamInfo->csrNeighborRoamProfile, + pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "%s: failed to prepare scan filter with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + else + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE,"%s: csrScanGetResult failed with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + } + } + else + { + smsLog( pMac, LOGE,"%s: alloc for pScanFilter failed with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + + /* + * After ensuring that the roam profile is in the scan result list, + * dequeue the command from the active list. + */ + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* If the head of the queue is Active and it is a ROAM command, remove + * and put this on the Free queue. + */ + if ( eSmeCommandRoam == pCommand->command ) + { + + /* + * we need to process the result first before removing it from active list + * because state changes still happening insides roamQProcessRoamResults so + * no other roam command should be issued. + */ + fRemoveCmd = csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ); + if(pCommand->u.roamCmd.fReleaseProfile) + { + csrReleaseProfile(pMac, &pCommand->u.roamCmd.roamProfile); + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + } + if( fRemoveCmd ) + csrReleaseCommandRoam( pMac, pCommand ); + else + { + smsLog( pMac, LOGE, "%s: fail to remove cmd reason %d", + __func__, pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGE, "%s: roam command not active", __func__ ); + } + } + else + { + smsLog( pMac, LOGE, "%s: NO commands are active", __func__ ); + } + + /* Notify HDD about handoff and provide the BSSID too */ + roamInfo.reasonCode = eCsrRoamReasonBetterAP; + + vos_mem_copy(roamInfo.bssid, + pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, + sizeof(tSirMacAddr)); + + csrRoamCallCallback(pMac,sessionId, &roamInfo, 0, + eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + + /* Copy the connected profile to apply the same for this connection as well */ + pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( pCurRoamProfile != NULL ) + { + vos_mem_set(pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pCurRoamProfile, pSession->pCurRoamProfile); + //make sure to put it at the head of the cmd queue + status = csrRoamIssueConnect(pMac, sessionId, pCurRoamProfile, + hBSSList, eCsrSmeIssuedAssocToSimilarAP, + roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE,"%s: csrRoamIssueConnect failed with status %d", + __func__, status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + + /* Notify sub-modules like QoS etc. that handoff happening */ + sme_QosCsrEventInd(pMac, sessionId, SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL); + csrReleaseProfile(pMac, pCurRoamProfile); + vos_mem_free(pCurRoamProfile); + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + return; + } + +POST_ROAM_FAILURE: + if (pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if (pCurRoamProfile) + vos_mem_free(pCurRoamProfile); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + csrRoamSynchCleanUp(pMac, sessionId); +#endif + /* Inform the upper layers that the reassoc failed */ + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, sessionId, + &roamInfo, 0, eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS); + + /* + * Issue a disassoc request so that PE/LIM uses this to clean-up the FT session. + * Upon success, we would re-enter this routine after receiving the disassoc + * response and will fall into the reassoc fail sub-state. And, eventually + * call csrRoamComplete which would remove the roam command from SME active + * queue. + */ + if (!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate(pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, FALSE))) + { + smsLog( pMac, LOGE,"%s: csrRoamIssueDisassociate failed with status %d", + __func__, status); + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } +#endif + + } //else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac ) ) + else if ( CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL( pMac, sessionId ) ) + { + // Disassoc due to Reassoc failure falls into this codepath.... + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } + else + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + // Successfully disassociated from the 'old' Bss... + // + // We get Disassociate response in three conditions. + // - First is the case where we are disasociating from an Infra Bss to start an IBSS. + // - Second is the when we are disassociating from an Infra Bss to join an IBSS or a new + // Infrastructure network. + // - Third is where we are doing an Infra to Infra roam between networks with different + // SSIDs. In all cases, we set the new Bss configuration here and attempt to join + + smsLog( pMac, LOG2, "CSR SmeDisassocReq disassociated Successfully" ); + } + else + { + smsLog( pMac, LOGE, "SmeDisassocReq failed with statusCode= 0x%08X", statusCode ); + } + //We are not done yet. Get the data and continue roaming + csrRoamReissueRoamCommand(pMac); + } +} + +static void csrRoamRoamingStateDeauthRspProcessor( tpAniSirGlobal pMac, tSirSmeDeauthRsp *pSmeRsp ) +{ + tSirResultCodes statusCode; + //No one is sending eWNI_SME_DEAUTH_REQ to PE. + smsLog(pMac, LOGW, FL("is no-op")); + statusCode = csrGetDeAuthRspStatusCode( pSmeRsp ); + pMac->roam.deauthRspStatus = statusCode; + if ( CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ( pMac, pSmeRsp->sessionId) ) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + // Successfully deauth from the 'old' Bss... + // + smsLog( pMac, LOG2, "CSR SmeDeauthReq disassociated Successfully" ); + } + else + { + smsLog( pMac, LOGW, "SmeDeauthReq failed with statusCode= 0x%08X", statusCode ); + } + //We are not done yet. Get the data and continue roaming + csrRoamReissueRoamCommand(pMac); + } +} + +static void csrRoamRoamingStateStartBssRspProcessor( tpAniSirGlobal pMac, tSirSmeStartBssRsp *pSmeStartBssRsp ) +{ + eCsrRoamCompleteResult result; + + if ( eSIR_SME_SUCCESS == pSmeStartBssRsp->statusCode ) + { + smsLog( pMac, LOGW, "SmeStartBssReq Successful" ); + result = eCsrStartBssSuccess; + } + else + { + smsLog( pMac, LOGW, "SmeStartBssReq failed with statusCode= 0x%08X", pSmeStartBssRsp->statusCode ); + //Let csrRoamComplete decide what to do + result = eCsrStartBssFailure; + } + csrRoamComplete( pMac, result, pSmeStartBssRsp); +} + +/* + We need to be careful on whether to cast pMsgBuf (pSmeRsp) to other type of strucutres. + It depends on how the message is constructed. If the message is sent by limSendSmeRsp, + the pMsgBuf is only a generic response and can only be used as pointer to tSirSmeRsp. + For the messages where sender allocates memory for specific structures, then it can be + cast accordingly. +*/ +void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + tSirSmeRsp *pSmeRsp; + tSmeIbssPeerInd *pIbssPeerInd; + tCsrRoamInfo roamInfo; + // TODO Session Id need to be acquired in this function + tANI_U32 sessionId = 0; + pSmeRsp = (tSirSmeRsp *)pMsgBuf; + smsLog(pMac, LOG2, FL("Message %d[0x%04X] received in substate %s"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + pSmeRsp->messageType = (pSmeRsp->messageType); + pSmeRsp->length = (pSmeRsp->length); + pSmeRsp->statusCode = (pSmeRsp->statusCode); + switch (pSmeRsp->messageType) + { + + case eWNI_SME_JOIN_RSP: // in Roaming state, process the Join response message... + if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, pSmeRsp->sessionId)) + { + //We sent a JOIN_REQ + csrRoamJoinRspProcessor( pMac, (tSirSmeJoinRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_REASSOC_RSP: // or the Reassociation response message... + if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ( pMac, pSmeRsp->sessionId) ) + { + csrRoamRoamingStateReassocRspProcessor( pMac, (tpSirSmeJoinRsp )pSmeRsp ); + } + break; + + case eWNI_SME_STOP_BSS_RSP: // or the Stop Bss response message... + { + csrRoamRoamingStateStopBssRspProcessor(pMac, pSmeRsp); + } + break; + + case eWNI_SME_DISASSOC_RSP: // or the Disassociate response message... + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE( pMac, pSmeRsp->sessionId ) || +//HO + CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, pSmeRsp->sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("eWNI_SME_DISASSOC_RSP subState = %s"), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + csrRoamRoamingStateDisassocRspProcessor( pMac, (tSirSmeDisassocRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_DEAUTH_RSP: // or the Deauthentication response message... + if ( CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ( pMac, pSmeRsp->sessionId ) ) + { + csrRoamRoamingStateDeauthRspProcessor( pMac, (tSirSmeDeauthRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_START_BSS_RSP: // or the Start BSS response message... + if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ( pMac, pSmeRsp->sessionId ) ) + { + csrRoamRoamingStateStartBssRspProcessor( pMac, (tSirSmeStartBssRsp *)pSmeRsp ); + } + break; + + case WNI_CFG_SET_CNF: // process the Config Confirm messages when we are in 'Config' substate... + if ( CSR_IS_ROAM_SUBSTATE_CONFIG( pMac, pSmeRsp->sessionId ) ) + { + csrRoamingStateConfigCnfProcessor( pMac, ((tCsrCfgSetRsp *)pSmeRsp)->respStatus ); + } + break; + //In case CSR issues STOP_BSS, we need to tell HDD about peer departed becasue PE is removing them + case eWNI_SME_IBSS_PEER_DEPARTED_IND: + pIbssPeerInd = (tSmeIbssPeerInd*)pSmeRsp; + smsLog(pMac, LOGE, "CSR: Peer departed notification from LIM in joining state"); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); + break; + case eWNI_SME_GET_RSSI_REQ: + { + tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)pMsgBuf; + if (NULL != pGetRssiReq->rssiCallback) + { + ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))( pGetRssiReq->lastRSSI, + pGetRssiReq->staId, + pGetRssiReq->pDevContext); + } + else + { + smsLog(pMac, LOGE, FL("pGetRssiReq->rssiCallback is NULL")); + } + } + break; + + default: + smsLog(pMac, LOG1, + FL("Unexpected message type = %d[0x%X] received in substate %s"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + //If we are connected, check the link status change + if(!csrIsConnStateDisconnected(pMac, sessionId)) + { + csrRoamCheckForLinkStatusChange( pMac, pSmeRsp ); + } + break; + } +} + +void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + tSirSmeRsp *pSirMsg = (tSirSmeRsp *)pMsgBuf; + switch (pSirMsg->messageType) + { + case eWNI_SME_GET_STATISTICS_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamStatsRspProcessor( pMac, pSirMsg ); + break; + case eWNI_SME_UPPER_LAYER_ASSOC_CNF: + { + tCsrRoamSession *pSession; + tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf; + tCsrRoamInfo roamInfo; + tCsrRoamInfo *pRoamInfo = NULL; + tANI_U32 sessionId; + eHalStatus status; + smsLog( pMac, LOG1, FL("ASSOCIATION confirmation can be given to upper layer ")); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + pRoamInfo = &roamInfo; + pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pUpperLayerAssocCnf->bssId, &sessionId ); + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid; + pRoamInfo->rsnIELen = (tANI_U8)pUpperLayerAssocCnf->rsnIE.length; + pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata; + pRoamInfo->addIELen = (tANI_U8)pUpperLayerAssocCnf->addIE.length; + pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, pUpperLayerAssocCnf->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pUpperLayerAssocCnf->bssId, + sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta; + pRoamInfo->timingMeasCap = pUpperLayerAssocCnf->timingMeasCap; + vos_mem_copy(&pRoamInfo->chan_info, &pUpperLayerAssocCnf->chan_info, + sizeof(tSirSmeChanInfo)); + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) ) + { + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; + pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + } + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + vos_sleep( 100 ); + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + } + + } + break; + default: + csrRoamCheckForLinkStatusChange( pMac, pSirMsg ); + break; + } +} + +eHalStatus csrRoamIssueSetContextReq( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrEncryptionType EncryptType, + tSirBssDescription *pBssDescription, + tSirMacAddr *bssId, tANI_BOOLEAN addKey, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U16 keyLength, + tANI_U8 *pKey, tANI_U8 paeRole ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniEdType edType; + + if(eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType) + { + EncryptType = eCSR_ENCRYPT_TYPE_NONE; //*** + } + + edType = csrTranslateEncryptTypeToEdType( EncryptType ); + + // Allow 0 keys to be set for the non-WPA encrypt types... For WPA encrypt types, the num keys must be non-zero + // or LIM will reject the set context (assumes the SET_CONTEXT does not occur until the keys are distrubuted). + if ( CSR_IS_ENC_TYPE_STATIC( EncryptType ) || + addKey ) + { + tCsrRoamSetKey setKey; + setKey.encType = EncryptType; + setKey.keyDirection = aniKeyDirection; //Tx, Rx or Tx-and-Rx + vos_mem_copy(&setKey.peerMac, bssId, sizeof(tCsrBssid)); + setKey.paeRole = paeRole; //0 for supplicant + setKey.keyId = keyId; // Kye index + setKey.keyLength = keyLength; + if( keyLength ) + { + vos_mem_copy(setKey.Key, pKey, keyLength); + } + status = csrRoamIssueSetKeyCommand( pMac, sessionId, &setKey, 0 ); + } + return (status); +} + +static eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamSetKey *pSetKey, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pCommand = NULL; +#ifdef FEATURE_WLAN_ESE + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } +#endif /* FEATURE_WLAN_ESE */ + + do + { + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_zero(pCommand, sizeof(tSmeCmd)); + pCommand->command = eSmeCommandSetKey; + pCommand->sessionId = (tANI_U8)sessionId; + // validate the key length, Adjust if too long... + // for static WEP the keys are not set thru' SetContextReq + if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pSetKey->encType ) ) + { + //KeyLength maybe 0 for static WEP + if( pSetKey->keyLength ) + { + if ( pSetKey->keyLength < CSR_WEP40_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WEP40 keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + + pCommand->u.setKeyCmd.keyLength = CSR_WEP40_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WEP40_KEY_LEN); + } + } + else if ( ( eCSR_ENCRYPT_TYPE_WEP104 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pSetKey->encType ) ) + { + //KeyLength maybe 0 for static WEP + if( pSetKey->keyLength ) + { + if ( pSetKey->keyLength < CSR_WEP104_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WEP104 keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + + pCommand->u.setKeyCmd.keyLength = CSR_WEP104_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WEP104_KEY_LEN); + } + } + else if ( eCSR_ENCRYPT_TYPE_TKIP == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_TKIP_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid TKIP keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_TKIP_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_TKIP_KEY_LEN); + } + else if ( eCSR_ENCRYPT_TYPE_AES == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_AES_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_AES_KEY_LEN); + } +#ifdef FEATURE_WLAN_WAPI + else if ( eCSR_ENCRYPT_TYPE_WPI == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_WAPI_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WAPI keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_WAPI_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WAPI_KEY_LEN); + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + else if ( eCSR_ENCRYPT_TYPE_KRK == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_KRK_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid KRK keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + vos_mem_copy(pSession->eseCckmInfo.krk, pSetKey->Key, + CSR_KRK_KEY_LEN); + pSession->eseCckmInfo.reassoc_req_num=1; + pSession->eseCckmInfo.krk_plumbed = eANI_BOOLEAN_TRUE; + status = eHAL_STATUS_SUCCESS; + break; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + else if (eCSR_ENCRYPT_TYPE_BTK == pSetKey->encType) { + if (pSetKey->keyLength < SIR_BTK_KEY_LEN) { + smsLog(pMac, LOGW, + "LFR3:Invalid BTK keylength [= %d] in SetContext call", + pSetKey->keyLength); + break; + } + vos_mem_copy(pSession->eseCckmInfo.btk, pSetKey->Key, + SIR_BTK_KEY_LEN); + status = eHAL_STATUS_SUCCESS; + break; + } +#endif +#endif /* FEATURE_WLAN_ESE */ + +#ifdef WLAN_FEATURE_11W + //Check for 11w BIP + else if (eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType) + { + if (pSetKey->keyLength < CSR_AES_KEY_LEN) + { + smsLog(pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN); + } +#endif + status = eHAL_STATUS_SUCCESS; + pCommand->u.setKeyCmd.roamId = roamId; + pCommand->u.setKeyCmd.encType = pSetKey->encType; + pCommand->u.setKeyCmd.keyDirection = pSetKey->keyDirection; //Tx, Rx or Tx-and-Rx + vos_mem_copy(&pCommand->u.setKeyCmd.peerMac, &pSetKey->peerMac, + sizeof(tCsrBssid)); + pCommand->u.setKeyCmd.paeRole = pSetKey->paeRole; //0 for supplicant + pCommand->u.setKeyCmd.keyId = pSetKey->keyId; + vos_mem_copy(pCommand->u.setKeyCmd.keyRsc, pSetKey->keyRsc, CSR_MAX_RSC_LEN); + //Always put set key to the head of the Q because it is the only thing to get executed in case of WT_KEY state + + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } while (0); + // Free the command if there has been a failure, or it is a + // "local" operation like the set ESE CCKM KRK key. + if ( ( NULL != pCommand ) && + ( (!HAL_STATUS_SUCCESS( status ) ) +#ifdef FEATURE_WLAN_ESE + || ( eCSR_ENCRYPT_TYPE_KRK == pSetKey->encType ) +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + || ( eCSR_ENCRYPT_TYPE_BTK == pSetKey->encType ) +#endif /* WLAN_FEATURE_ROAM_OFFLOAD */ +#endif /* FEATURE_WLAN_ESE */ + ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + return( status ); +} + +eHalStatus csrRoamIssueRemoveKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fImediate = eANI_BOOLEAN_TRUE; + do + { + if( !csrIsSetKeyAllowed(pMac, sessionId) ) + { + smsLog( pMac, LOGW, FL(" wrong state not allowed to set key") ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRemoveKey; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.removeKeyCmd.roamId = roamId; + pCommand->u.removeKeyCmd.encType = pRemoveKey->encType; + vos_mem_copy(&pCommand->u.removeKeyCmd.peerMac, &pRemoveKey->peerMac, + sizeof(tSirMacAddr)); + pCommand->u.removeKeyCmd.keyId = pRemoveKey->keyId; + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + //in this case, put it to the end of the Q incase there is a set key pending. + fImediate = eANI_BOOLEAN_FALSE; + } + smsLog( pMac, LOGE, FL("keyType=%d, keyId=%d, PeerMac="MAC_ADDRESS_STR), + pRemoveKey->encType, pRemoveKey->keyId, + MAC_ADDR_ARRAY(pCommand->u.removeKeyCmd.peerMac)); + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while (0); + if( !HAL_STATUS_SUCCESS( status ) && ( NULL != pCommand ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + return (status ); +} + +eHalStatus csrRoamProcessSetKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status; + tANI_U8 numKeys = ( pCommand->u.setKeyCmd.keyLength ) ? 1 : 0; + tAniEdType edType = csrTranslateEncryptTypeToEdType( pCommand->u.setKeyCmd.encType ); + tANI_BOOLEAN fUnicast = ( pCommand->u.setKeyCmd.peerMac[0] == 0xFF ) ? eANI_BOOLEAN_FALSE : eANI_BOOLEAN_TRUE; + tANI_U32 sessionId = pCommand->sessionId; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + WLAN_VOS_DIAG_EVENT_DEF(setKeyEvent, vos_event_wlan_security_payload_type); + + if(NULL == pSession){ + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(eSIR_ED_NONE != edType) + { + vos_mem_set(&setKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + if( *(( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac) & 0x01 ) + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_REQ; + setKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pCommand->u.setKeyCmd.encType); + setKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + } + else + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_REQ; + setKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pCommand->u.setKeyCmd.encType); + setKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + } + vos_mem_copy(setKeyEvent.bssid, pSession->connectedProfile.bssid, 6); + if(CSR_IS_ENC_TYPE_STATIC(pCommand->u.setKeyCmd.encType)) + { + tANI_U32 defKeyId; + //It has to be static WEP here + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, &defKeyId))) + { + setKeyEvent.keyId = (v_U8_t)defKeyId; + } + } + else + { + setKeyEvent.keyId = pCommand->u.setKeyCmd.keyId; + } + setKeyEvent.authMode = (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( csrIsSetKeyAllowed(pMac, sessionId) ) + { + status = csrSendMBSetContextReqMsg( pMac, sessionId, + ( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac, + numKeys, edType, fUnicast, pCommand->u.setKeyCmd.keyDirection, + pCommand->u.setKeyCmd.keyId, pCommand->u.setKeyCmd.keyLength, + pCommand->u.setKeyCmd.Key, pCommand->u.setKeyCmd.paeRole, + pCommand->u.setKeyCmd.keyRsc); + } + else + { + smsLog( pMac, LOGW, FL(" cannot process not connected") ); + //Set this status so the error handling take care of the case. + status = eHAL_STATUS_CSR_WRONG_STATE; + } + if( !HAL_STATUS_SUCCESS(status) ) + { + smsLog( pMac, LOGE, FL(" error status %d"), status ); + csrRoamCallCallback( pMac, sessionId, NULL, pCommand->u.setKeyCmd.roamId, eCSR_ROAM_SET_KEY_COMPLETE, eCSR_ROAM_RESULT_FAILURE); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(eSIR_ED_NONE != edType) + { + if( *(( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac) & 0x01 ) + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_RSP; + } + else + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_RSP; + } + setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + } + return ( status ); +} + +eHalStatus csrRoamProcessRemoveKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status; + tpSirSmeRemoveKeyReq pMsg = NULL; + tANI_U16 wMsgLen = sizeof(tSirSmeRemoveKeyReq); + tANI_U8 *p; + tANI_U32 sessionId = pCommand->sessionId; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + WLAN_VOS_DIAG_EVENT_DEF(removeKeyEvent, vos_event_wlan_security_payload_type); + + if(NULL == pSession){ + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + vos_mem_set(&removeKeyEvent, + sizeof(vos_event_wlan_security_payload_type),0); + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_REQ; + removeKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + removeKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(removeKeyEvent.bssid, pSession->connectedProfile.bssid, 6); + removeKeyEvent.keyId = pCommand->u.removeKeyCmd.keyId; + removeKeyEvent.authMode = (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( csrIsSetKeyAllowed(pMac, sessionId) ) + { + pMsg = vos_mem_malloc(wMsgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGW, FL(" wrong state not allowed to set key") ); + //Set the error status so error handling kicks in below + status = eHAL_STATUS_CSR_WRONG_STATE; + } + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(pMsg, wMsgLen ,0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_REMOVEKEY_REQ); + pMsg->length = pal_cpu_to_be16(wMsgLen); + pMsg->sessionId = (tANI_U8)sessionId; + pMsg->transactionId = 0; + p = (tANI_U8 *)pMsg + sizeof(pMsg->messageType) + sizeof(pMsg->length) + + sizeof(pMsg->sessionId) + sizeof(pMsg->transactionId); + // bssId - copy from session Info + vos_mem_copy(p, + &pMac->roam.roamSession[sessionId].connectedProfile.bssid, + sizeof(tSirMacAddr)); + p += sizeof(tSirMacAddr); + // peerMacAddr + vos_mem_copy(p, pCommand->u.removeKeyCmd.peerMac, sizeof(tSirMacAddr)); + p += sizeof(tSirMacAddr); + // edType + *p = (tANI_U8)csrTranslateEncryptTypeToEdType( pCommand->u.removeKeyCmd.encType ); + p++; + // weptype + if( ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pCommand->u.removeKeyCmd.encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pCommand->u.removeKeyCmd.encType ) ) + { + *p = (tANI_U8)eSIR_WEP_STATIC; + } + else + { + *p = (tANI_U8)eSIR_WEP_DYNAMIC; + } + p++; + //keyid + *p = pCommand->u.removeKeyCmd.keyId; + p++; + *p = (pCommand->u.removeKeyCmd.peerMac[0] == 0xFF ) ? 0 : 1; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" error status %d"), status ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_RSP; + removeKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + csrRoamCallCallback( pMac, sessionId, NULL, pCommand->u.removeKeyCmd.roamId, eCSR_ROAM_REMOVE_KEY_COMPLETE, eCSR_ROAM_RESULT_FAILURE); + } + return ( status ); +} + +eHalStatus csrRoamSetKey( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ) +{ + eHalStatus status; + + if( !csrIsSetKeyAllowed(pMac, sessionId) ) + { + status = eHAL_STATUS_CSR_WRONG_STATE; + } + else + { + status = csrRoamIssueSetKeyCommand( pMac, sessionId, pSetKey, roamId ); + } + return ( status ); +} + +/* + Prepare a filter base on a profile for parsing the scan results. + Upon successful return, caller MUST call csrFreeScanFilter on + pScanFilter when it is done with the filter. +*/ +eHalStatus csrRoamPrepareFilterFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tCsrScanResultFilter *pScanFilter) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 size = 0; + tANI_U8 index = 0; + + do + { + if(pProfile->BSSIDs.numOfBSSIDs) + { + size = sizeof(tCsrBssid) * pProfile->BSSIDs.numOfBSSIDs; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(size); + if ( NULL == pScanFilter->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pScanFilter->BSSIDs.numOfBSSIDs = pProfile->BSSIDs.numOfBSSIDs; + vos_mem_copy(pScanFilter->BSSIDs.bssid, pProfile->BSSIDs.bssid, size); + } + if(pProfile->SSIDs.numOfSSIDs) + { + if( !CSR_IS_WDS_STA( pProfile ) ) + { + pScanFilter->SSIDs.numOfSSIDs = pProfile->SSIDs.numOfSSIDs; + } + else + { + //For WDS station + //We always use index 1 for self SSID. Index 0 for peer's SSID that we want to join + pScanFilter->SSIDs.numOfSSIDs = 1; + } + size = sizeof(tCsrSSIDInfo) * pProfile->SSIDs.numOfSSIDs; + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(size); + if ( NULL == pScanFilter->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_copy(pScanFilter->SSIDs.SSIDList, pProfile->SSIDs.SSIDList, + size); + } + if(!pProfile->ChannelInfo.ChannelList || (pProfile->ChannelInfo.ChannelList[0] == 0) ) + { + pScanFilter->ChannelInfo.numOfChannels = 0; + pScanFilter->ChannelInfo.ChannelList = NULL; + } + else if(pProfile->ChannelInfo.numOfChannels) + { + pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc( + sizeof(*pScanFilter->ChannelInfo.ChannelList) * + pProfile->ChannelInfo.numOfChannels); + if ( NULL == pScanFilter->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + pScanFilter->ChannelInfo.numOfChannels = 0; + if(HAL_STATUS_SUCCESS(status)) + { + for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++) + { + if(csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[index])) + { + pScanFilter->ChannelInfo.ChannelList[pScanFilter->ChannelInfo.numOfChannels] + = pProfile->ChannelInfo.ChannelList[index]; + pScanFilter->ChannelInfo.numOfChannels++; + } + else + { + smsLog(pMac, LOG1, FL("process a channel (%d) that is invalid"), pProfile->ChannelInfo.ChannelList[index]); + } + } + } + else + { + break; + } + } + else + { + smsLog(pMac, LOGE, FL("Channel list empty")); + status = eHAL_STATUS_FAILURE; + break; + } + pScanFilter->uapsd_mask = pProfile->uapsd_mask; + pScanFilter->authType = pProfile->AuthType; + pScanFilter->EncryptionType = pProfile->EncryptionType; + pScanFilter->mcEncryptionType = pProfile->mcEncryptionType; + pScanFilter->BSSType = pProfile->BSSType; + pScanFilter->phyMode = pProfile->phyMode; +#ifdef FEATURE_WLAN_WAPI + //check if user asked for WAPI with 11n or auto mode, in that case modify + //the phymode to 11g + if(csrIsProfileWapi(pProfile)) + { + if(pScanFilter->phyMode & eCSR_DOT11_MODE_11n) + { + pScanFilter->phyMode &= ~eCSR_DOT11_MODE_11n; + } + if(pScanFilter->phyMode & eCSR_DOT11_MODE_AUTO) + { + pScanFilter->phyMode &= ~eCSR_DOT11_MODE_AUTO; + } + if(!pScanFilter->phyMode) + { + pScanFilter->phyMode = eCSR_DOT11_MODE_11g; + } + } +#endif /* FEATURE_WLAN_WAPI */ + /*Save the WPS info*/ + pScanFilter->bWPSAssociation = pProfile->bWPSAssociation; + pScanFilter->bOSENAssociation = pProfile->bOSENAssociation; + if( pProfile->countryCode[0] ) + { + //This causes the matching function to use countryCode as one of the criteria. + vos_mem_copy(pScanFilter->countryCode, pProfile->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pProfile->MDID.mdiePresent) + { + pScanFilter->MDID.mdiePresent = 1; + pScanFilter->MDID.mobilityDomain = pProfile->MDID.mobilityDomain; + } +#endif + +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + pScanFilter->MFPEnabled = pProfile->MFPEnabled; + pScanFilter->MFPRequired = pProfile->MFPRequired; + pScanFilter->MFPCapable = pProfile->MFPCapable; +#endif + + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrFreeScanFilter(pMac, pScanFilter); + } + + return(status); +} + +tANI_BOOLEAN csrRoamIssueWmStatusChange( tpAniSirGlobal pMac, tANI_U32 sessionId, + eCsrRoamWmStatusChangeTypes Type, tSirSmeRsp *pSmeRsp ) +{ + tANI_BOOLEAN fCommandQueued = eANI_BOOLEAN_FALSE; + tSmeCmd *pCommand; + do + { + // Validate the type is ok... + if ( ( eCsrDisassociated != Type ) && ( eCsrDeauthenticated != Type ) ) break; + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + break; + } + //Change the substate in case it is waiting for key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandWmStatusChange; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.wmStatusChangeCmd.Type = Type; + if ( eCsrDisassociated == Type ) + { + vos_mem_copy(&pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg, + pSmeRsp, + sizeof( pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg )); + } + else + { + vos_mem_copy(&pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg, + pSmeRsp, + sizeof( pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg )); + } + if( HAL_STATUS_SUCCESS( csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE) ) ) + { + fCommandQueued = eANI_BOOLEAN_TRUE; + } + else + { + smsLog( pMac, LOGE, FL(" fail to send message ") ); + csrReleaseCommandWmStatusChange( pMac, pCommand ); + } + + /* AP has issued Dissac/Deauth, Set the operating mode value to configured value */ + csrSetDefaultDot11Mode( pMac ); + } while( 0 ); + return( fCommandQueued ); +} + +static void csrUpdateRssi(tpAniSirGlobal pMac, void* pMsg) +{ + v_S7_t rssi = 0; + tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)pMsg; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + if(pGetRssiReq) + { + if(NULL != pGetRssiReq->pVosContext) + { + vosStatus = WLANTL_GetRssi(pGetRssiReq->pVosContext, pGetRssiReq->staId, &rssi,pGetRssiReq); + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq->pVosContext is NULL")); + return; + } + + if(NULL != pGetRssiReq->rssiCallback) + { + if(vosStatus!=VOS_STATUS_E_BUSY) + ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(rssi, pGetRssiReq->staId, pGetRssiReq->pDevContext); + else smsLog( pMac, LOG1, FL("rssi request is posted. waiting for reply")); + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq->rssiCallback is NULL")); + return; + } + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq is NULL")); + } + return; + +} + +static void csrUpdateSnr(tpAniSirGlobal pMac, void* pMsg) +{ + tANI_S8 snr = 0; + tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq*)pMsg; + + if (pGetSnrReq) + { + if (VOS_STATUS_SUCCESS != + WDA_GetSnr(pGetSnrReq->staId, &snr)) + { + smsLog(pMac, LOGE, FL("Error in WLANTL_GetSnr")); + return; + } + + if (pGetSnrReq->snrCallback) + { + ((tCsrSnrCallback)(pGetSnrReq->snrCallback))(snr, pGetSnrReq->staId, + pGetSnrReq->pDevContext); + } + else + { + smsLog(pMac, LOGE, FL("pGetSnrReq->snrCallback is NULL")); + return; + } + } + else + { + smsLog(pMac, LOGE, FL("pGetSnrReq is NULL")); + } + return; +} +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +void csrRoamRssiRspProcessor(tpAniSirGlobal pMac, void* pMsg) +{ + tAniGetRoamRssiRsp* pRoamRssiRsp = (tAniGetRoamRssiRsp*)pMsg; + + if (NULL != pRoamRssiRsp) + { + /* Get roam Rssi request is backed up and passed back to the response, + Extract the request message to fetch callback */ + tpAniGetRssiReq reqBkp = (tAniGetRssiReq*)pRoamRssiRsp->rssiReq; + v_S7_t rssi = pRoamRssiRsp->rssi; + if ((NULL != reqBkp) && (NULL != reqBkp->rssiCallback)) + { + ((tCsrRssiCallback)(reqBkp->rssiCallback))(rssi, pRoamRssiRsp->staId, reqBkp->pDevContext); + vos_mem_free(reqBkp); + pRoamRssiRsp->rssiReq = NULL; + } + else + { + smsLog( pMac, LOGE, FL("reqBkp->rssiCallback is NULL")); + if (NULL != reqBkp) + { + vos_mem_free(reqBkp); + pRoamRssiRsp->rssiReq = NULL; + } + } + } + else + { + smsLog( pMac, LOGE, FL("pRoamRssiRsp is NULL")); + } + return; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void csrTsmStatsRspProcessor(tpAniSirGlobal pMac, void* pMsg) +{ + tAniGetTsmStatsRsp* pTsmStatsRsp = (tAniGetTsmStatsRsp*)pMsg; + + if (NULL != pTsmStatsRsp) + { + /* Get roam Rssi request is backed up and passed back to the response, + Extract the request message to fetch callback */ + tpAniGetTsmStatsReq reqBkp + = (tAniGetTsmStatsReq*)pTsmStatsRsp->tsmStatsReq; + + if (NULL != reqBkp) + { + if (NULL != reqBkp->tsmStatsCallback) + { + ((tCsrTsmStatsCallback)(reqBkp->tsmStatsCallback))( + pTsmStatsRsp->tsmMetrics, + pTsmStatsRsp->staId, + reqBkp->pDevContext + ); + reqBkp->tsmStatsCallback = NULL; + } + vos_mem_free(reqBkp); + pTsmStatsRsp->tsmStatsReq = NULL; + } + else + { + smsLog( pMac, LOGE, FL("reqBkp is NULL")); + if (NULL != reqBkp) + { + vos_mem_free(reqBkp); + pTsmStatsRsp->tsmStatsReq = NULL; + } + } + } + else + { + smsLog( pMac, LOGE, FL("pTsmStatsRsp is NULL")); + } + return; +} + +void csrSendEseAdjacentApRepInd(tpAniSirGlobal pMac, tCsrRoamSession *pSession) +{ + tANI_U32 roamTS2 = 0; + tCsrRoamInfo roamInfo; + tpPESession pSessionEntry = NULL; + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL")); + return; + } + + roamTS2 = vos_timer_get_system_time(); + roamInfo.tsmRoamDelay = roamTS2 - pSession->roamTS1; + smsLog(pMac, LOG1, "Bssid("MAC_ADDRESS_STR") Roaming Delay(%u ms)", + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid), + roamInfo.tsmRoamDelay); + + pSessionEntry = peFindSessionByBssid(pMac, + pSession->connectedProfile.bssid, + &sessionId); + if (NULL == pSessionEntry) + { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + return; + } + + pSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly + = roamInfo.tsmRoamDelay; + + csrRoamCallCallback(pMac, pSession->sessionId, &roamInfo, + 0, eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0); +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +static void csrRoamRssiIndHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + WLANTL_TlIndicationReq *pTlRssiInd = (WLANTL_TlIndicationReq*)pMsg; + if(pTlRssiInd) + { + if(NULL != pTlRssiInd->tlCallback) + { + ((WLANTL_RSSICrossThresholdCBType)(pTlRssiInd->tlCallback)) + (pTlRssiInd->pAdapter, pTlRssiInd->rssiNotification, pTlRssiInd->pUserCtxt, pTlRssiInd->avgRssi); + } + else + { + smsLog( pMac, LOGE, FL("pTlRssiInd->tlCallback is NULL")); + } + } + else + { + smsLog( pMac, LOGE, FL("pTlRssiInd is NULL")); + } + return; +} + +eHalStatus csrSendResetApCapsChanged(tpAniSirGlobal pMac, tSirMacAddr *bssId) +{ + tpSirResetAPCapsChange pMsg; + tANI_U16 len; + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* Create the message and send to lim */ + len = sizeof(tSirResetAPCapsChange); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirResetAPCapsChange), 0); + pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED; + pMsg->length = len; + vos_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr)); + smsLog( pMac, LOG1, FL("CSR reset caps change for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + else + { + smsLog( pMac, LOGE, FL("Memory allocation failed\n")); + } + return status; +} + +void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg ) +{ + tSirSmeAssocInd *pAssocInd; + tSirSmeDisassocInd *pDisassocInd; + tSirSmeDeauthInd *pDeauthInd; + tSirSmeWmStatusChangeNtf *pStatusChangeMsg; + tSirSmeNewBssInfo *pNewBss; + tSmeIbssPeerInd *pIbssPeerInd; + tSirMacAddr Broadcastaddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tSirSmeApNewCaps *pApNewCaps; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED; + tCsrRoamInfo *pRoamInfo = NULL; + tCsrRoamInfo roamInfo; + eHalStatus status; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + tCsrRoamSession *pSession = NULL; + tpSirSmeSwitchChannelInd pSwitchChnInd; + tSmeMaxAssocInd *pSmeMaxAssocInd; + tSmeCmd pCommand; + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + + if (NULL == pSirMsg) + { smsLog(pMac, LOGE, FL("pSirMsg is NULL")); + return; + } + switch( pSirMsg->messageType ) + { + case eWNI_SME_ASSOC_IND: + { + tCsrRoamSession *pSession; + smsLog( pMac, LOG1, FL("ASSOCIATION Indication from SME")); + pAssocInd = (tSirSmeAssocInd *)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pAssocInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pRoamInfo = &roamInfo; + + // Required for indicating the frames to upper layer + pRoamInfo->assocReqLength = pAssocInd->assocReqLength; + pRoamInfo->assocReqPtr = pAssocInd->assocReqPtr; + + pRoamInfo->beaconPtr = pAssocInd->beaconPtr; + pRoamInfo->beaconLength = pAssocInd->beaconLength; + pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + + pRoamInfo->staId = (tANI_U8)pAssocInd->staId; + pRoamInfo->rsnIELen = (tANI_U8)pAssocInd->rsnIE.length; + pRoamInfo->prsnIE = pAssocInd->rsnIE.rsnIEdata; + + pRoamInfo->addIELen = (tANI_U8)pAssocInd->addIE.length; + pRoamInfo->paddIE = pAssocInd->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pAssocInd->bssId, + sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pAssocInd->wmmEnabledSta; + pRoamInfo->timingMeasCap = pAssocInd->timingMeasCap; + vos_mem_copy(&pRoamInfo->chan_info, &pAssocInd->chan_info, + sizeof(tSirSmeChanInfo)); + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) + { + if( CSR_IS_ENC_TYPE_STATIC( pSession->pCurRoamProfile->negotiatedUCEncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, pSession->pCurRoamProfile->negotiatedUCEncryptionType, + pSession->pConnectBssDesc, + &(pRoamInfo->peerMac), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + pRoamInfo->fAuthRequired = FALSE; + } + else + { + pRoamInfo->fAuthRequired = TRUE; + } + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND); + if (!HAL_STATUS_SUCCESS(status)) + pRoamInfo->statusCode = eSIR_SME_ASSOC_REFUSED;// Refused due to Mac filtering + } + /* Send Association completion message to PE */ + status = csrSendAssocCnfMsg( pMac, pAssocInd, status );//Sta + + /* send a message to CSR itself just to avoid the EAPOL frames going + * OTA before association response */ + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + status = csrSendAssocIndToUpperLayerCnfMsg(pMac, pAssocInd, status, sessionId); + } + else if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) && (pRoamInfo->statusCode != eSIR_SME_ASSOC_REFUSED)) + { + pRoamInfo->fReassocReq = pAssocInd->reassocReq; + //status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + status = csrSendAssocIndToUpperLayerCnfMsg(pMac, pAssocInd, status, sessionId); + } + } + } + break; + case eWNI_SME_DISASSOC_IND: + // Check if AP dis-associated us because of MIC failure. If so, + // then we need to take action immediately and not wait till the + // the WmStatusChange requests is pushed and processed + pDisassocInd = (tSirSmeDisassocInd *)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pDisassocInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("DISASSOCIATION Indication from MAC for session %d "), sessionId); + smsLog( pMac, LOGE, FL("DISASSOCIATION from peer =" MAC_ADDRESS_STR " " + " reason = %d status = %d "), + MAC_ADDR_ARRAY(pDisassocInd->peerMacAddr), + pDisassocInd->reasonCode, pDisassocInd->statusCode); + // If we are in neighbor preauth done state then on receiving + // disassoc or deauth we dont roam instead we just disassoc + // from current ap and then go to disconnected state + // This happens for ESE and 11r FT connections ONLY. +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsESEAssoc(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + csrRoamIssueWmStatusChange( pMac, sessionId, eCsrDisassociated, pSirMsg ); + if(CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + + pRoamInfo = &roamInfo; + + pRoamInfo->statusCode = pDisassocInd->statusCode; + pRoamInfo->reasonCode = pDisassocInd->reasonCode; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + + pRoamInfo->staId = (tANI_U8)pDisassocInd->staId; + + vos_mem_copy(pRoamInfo->peerMac, pDisassocInd->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pDisassocInd->bssId, + sizeof(tCsrBssid)); + + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_DISASSOC_IND); + + /* + * STA/P2P client got disassociated so remove any pending deauth + * commands in sme pending list + */ + pCommand.command = eSmeCommandRoam; + pCommand.sessionId = (tANI_U8)sessionId; + pCommand.u.roamCmd.roamReason = eCsrForcedDeauthSta; + vos_mem_copy(pCommand.u.roamCmd.peerMac, + pDisassocInd->peerMacAddr, + sizeof(tSirMacAddr)); + csrRoamRemoveDuplicateCommand(pMac, sessionId, &pCommand, eCsrForcedDeauthSta); + } + } + else + { + smsLog(pMac, LOGE, FL(" Session Id not found for BSSID " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pDisassocInd->bssId)); + } + break; + case eWNI_SME_DEAUTH_IND: + smsLog( pMac, LOG1, FL("DEAUTHENTICATION Indication from MAC")); + pDeauthInd = (tpSirSmeDeauthInd)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pDeauthInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + // If we are in neighbor preauth done state then on receiving + // disassoc or deauth we dont roam instead we just disassoc + // from current ap and then go to disconnected state + // This happens for ESE and 11r FT connections ONLY. +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsESEAssoc(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac, sessionId))) { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac, + sessionId); + } +#endif + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + csrRoamIssueWmStatusChange( pMac, sessionId, eCsrDeauthenticated, pSirMsg ); + if(CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + + pRoamInfo = &roamInfo; + + pRoamInfo->statusCode = pDeauthInd->statusCode; + pRoamInfo->reasonCode = pDeauthInd->reasonCode; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + + pRoamInfo->staId = (tANI_U8)pDeauthInd->staId; + + vos_mem_copy(pRoamInfo->peerMac, pDeauthInd->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pDeauthInd->bssId, + sizeof(tCsrBssid)); + + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_DEAUTH_IND); + } + } + break; + + case eWNI_SME_SWITCH_CHL_REQ: // in case of STA, the SWITCH_CHANNEL originates from its AP + smsLog( pMac, LOGW, FL("eWNI_SME_SWITCH_CHL_REQ from SME")); + pSwitchChnInd = (tpSirSmeSwitchChannelInd)pSirMsg; + //Update with the new channel id. + //The channel id is hidden in the statusCode. + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pSwitchChnInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectedProfile.operationChannel = (tANI_U8)pSwitchChnInd->newChannelId; + if(pSession->pConnectBssDesc) + { + pSession->pConnectBssDesc->channelId = (tANI_U8)pSwitchChnInd->newChannelId; + } + } + break; + + case eWNI_SME_DEAUTH_RSP: + smsLog( pMac, LOGW, FL("eWNI_SME_DEAUTH_RSP from SME")); + { + tSirSmeDeauthRsp* pDeauthRsp = (tSirSmeDeauthRsp *)pSirMsg; + sessionId = pDeauthRsp->sessionId; + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + pRoamInfo = &roamInfo; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + vos_mem_copy(pRoamInfo->peerMac, pDeauthRsp->peerMacAddr, + sizeof(tSirMacAddr)); + pRoamInfo->reasonCode = eCSR_ROAM_RESULT_FORCED; + pRoamInfo->statusCode = pDeauthRsp->statusCode; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED); + } + } + } + break; + + case eWNI_SME_DISASSOC_RSP: + /* session id is invalid here so cant use it to access the array curSubstate as index */ + smsLog( pMac, LOGW, FL("eWNI_SME_DISASSOC_RSP from SME ")); + { + tSirSmeDisassocRsp *pDisassocRsp = (tSirSmeDisassocRsp *)pSirMsg; + sessionId = pDisassocRsp->sessionId; + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + pRoamInfo = &roamInfo; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + vos_mem_copy(pRoamInfo->peerMac, pDisassocRsp->peerMacAddr, + sizeof(tSirMacAddr)); + pRoamInfo->reasonCode = eCSR_ROAM_RESULT_FORCED; + pRoamInfo->statusCode = pDisassocRsp->statusCode; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED); + } + } + } + break; + case eWNI_SME_MIC_FAILURE_IND: + { + tpSirSmeMicFailureInd pMicInd = (tpSirSmeMicFailureInd)pSirMsg; + eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pMicInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pMICFailureInfo = &pMicInd->info; + pRoamInfo = &roamInfo; + if(pMicInd->info.multicast) + { + result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP; + } + else + { + result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + } + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_MIC_ERROR_IND, result); + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + vos_mem_set(&secEvent, sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + vos_mem_copy(secEvent.bssid, + pSession->connectedProfile.bssid, 6); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//FEATURE_WLAN_DIAG_SUPPORT_CSR + } + break; + case eWNI_SME_WPS_PBC_PROBE_REQ_IND: + { + tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd)pSirMsg; + smsLog( pMac, LOG1, FL("WPS PBC Probe request Indication from SME")); + + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pProbeReqInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq; + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, + eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND); + } + } + break; + + case eWNI_SME_WM_STATUS_CHANGE_NTF: + pStatusChangeMsg = (tSirSmeWmStatusChangeNtf *)pSirMsg; + switch( pStatusChangeMsg->statusChangeCode ) + { + case eSIR_SME_IBSS_ACTIVE: + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED; + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&roamInfo.bssid, + pSession->pConnectBssDesc->bssId, + sizeof(tCsrBssid)); + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo = &roamInfo; + } + else + { + smsLog(pMac, LOGE, " CSR eSIR_SME_IBSS_NEW_PEER connected BSS is empty"); + } + result = eCSR_ROAM_RESULT_IBSS_CONNECT; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + } + break; + case eSIR_SME_IBSS_INACTIVE: + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; + result = eCSR_ROAM_RESULT_IBSS_INACTIVE; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + } + break; + case eSIR_SME_JOINED_NEW_BSS: // IBSS coalescing. + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + // update the connection state information + pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + tANI_U32 bi; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING; + if(pNewBss) + { + vos_mem_copy(pIbssLog->bssid, pNewBss->bssId, 6); + if(pNewBss->ssId.length) + { + vos_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId, + pNewBss->ssId.length); + } + pIbssLog->operatingChannel = pNewBss->channelNumber; + } + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &bi))) + { + //***U8 is not enough for beacon interval + pIbssLog->beaconInterval = (v_U8_t)bi; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + csrRoamUpdateConnectedProfileFromNewBss( pMac, sessionId, pNewBss ); + + if ((eCSR_ENCRYPT_TYPE_NONE == + pSession->connectedProfile.EncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, + pSession->connectedProfile.EncryptionType, + pSession->pConnectBssDesc, + &Broadcastaddr, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); + } + result = eCSR_ROAM_RESULT_IBSS_COALESCED; + roamStatus = eCSR_ROAM_IBSS_IND; + vos_mem_copy(&roamInfo.bssid, &pNewBss->bssId, + sizeof(tCsrBssid)); + pRoamInfo = &roamInfo; + //This BSSID is th ereal BSSID, let's save it + if(pSession->pConnectBssDesc) + { + vos_mem_copy(pSession->pConnectBssDesc->bssId, + &pNewBss->bssId, sizeof(tCsrBssid)); + } + } + smsLog(pMac, LOGW, "CSR: eSIR_SME_JOINED_NEW_BSS received from PE"); + break; + // detection by LIM that the capabilities of the associated AP have changed. + case eSIR_SME_AP_CAPS_CHANGED: + pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps; + smsLog(pMac, LOGW, "CSR handling eSIR_SME_AP_CAPS_CHANGED"); + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pApNewCaps->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + if ((eCSR_ROAMING_STATE_JOINED == pMac->roam.curState[sessionId]) && + ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_NONE == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC == pMac->roam.curSubState[sessionId])) + ) + { + smsLog(pMac, LOGW, "Calling csrRoamDisconnectInternal"); + csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + else + { + smsLog(pMac, LOGW, + FL("Skipping csrScanForCapabilityChange as " + "CSR is in state %s and sub-state %s"), + macTraceGetcsrRoamState( + pMac->roam.curState[sessionId]), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[sessionId])); + /* We ignore the caps change event if CSR is not in full connected state. + * Send one event to PE to reset limSentCapsChangeNtf + * Once limSentCapsChangeNtf set 0, lim can send sub sequent CAPS change event + * otherwise lim cannot send any CAPS change events to SME */ + csrSendResetApCapsChanged(pMac, &pApNewCaps->bssId); + } + } + break; + + default: + roamStatus = eCSR_ROAM_FAILED; + result = eCSR_ROAM_RESULT_NONE; + break; + } // end switch on statusChangeCode + if(eCSR_ROAM_RESULT_NONE != result) + { + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, roamStatus, result); + } + break; + case eWNI_SME_IBSS_NEW_PEER_IND: + pIbssPeerInd = (tSmeIbssPeerInd *)pSirMsg; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN; + vos_mem_copy(pIbssLog->peerMacAddr, &pIbssPeerInd->peerAddr, 6); + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + // Issue the set Context request to LIM to establish the Unicast STA context for the new peer... + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + vos_mem_copy(&roamInfo.bssid, pSession->pConnectBssDesc->bssId, + sizeof(tCsrBssid)); + if(pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) + { + roamInfo.pbFrames = vos_mem_malloc((pIbssPeerInd->mesgLen + - sizeof(tSmeIbssPeerInd))); + if ( NULL == roamInfo.pbFrames ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + roamInfo.nBeaconLength = (pIbssPeerInd->mesgLen - sizeof(tSmeIbssPeerInd)); + vos_mem_copy(roamInfo.pbFrames, + ((tANI_U8 *)pIbssPeerInd) + sizeof(tSmeIbssPeerInd), + roamInfo.nBeaconLength); + } + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + roamInfo.pBssDesc = vos_mem_malloc(pSession->pConnectBssDesc->length); + if ( NULL == roamInfo.pBssDesc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(roamInfo.pBssDesc, + pSession->pConnectBssDesc, + pSession->pConnectBssDesc->length); + } + if(HAL_STATUS_SUCCESS(status)) + { + pRoamInfo = &roamInfo; + } + else + { + if(roamInfo.pbFrames) + { + vos_mem_free(roamInfo.pbFrames); + } + if(roamInfo.pBssDesc) + { + vos_mem_free(roamInfo.pBssDesc); + } + } + } + else + { + pRoamInfo = &roamInfo; + } + if ((eCSR_ENCRYPT_TYPE_NONE == + pSession->connectedProfile.EncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, + pSession->connectedProfile.EncryptionType, + pSession->pConnectBssDesc, + &(pIbssPeerInd->peerAddr), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + } + else + { + smsLog(pMac, LOGW, " CSR eSIR_SME_IBSS_NEW_PEER connected BSS is empty"); + } + //send up the sec type for the new peer + if (pRoamInfo) + { + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + } + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_NEW_PEER); + if(pRoamInfo) + { + if(roamInfo.pbFrames) + { + vos_mem_free(roamInfo.pbFrames); + } + if(roamInfo.pBssDesc) + { + vos_mem_free(roamInfo.pBssDesc); + } + } + } + break; + case eWNI_SME_IBSS_PEER_DEPARTED_IND: + pIbssPeerInd = (tSmeIbssPeerInd*)pSirMsg; + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE; + if(pIbssPeerInd) + { + vos_mem_copy(pIbssLog->peerMacAddr, + &pIbssPeerInd->peerAddr, 6); + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + smsLog(pMac, LOGW, "CSR: Peer departed notification from LIM"); + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); + } + break; + case eWNI_SME_SETCONTEXT_RSP: + { + tSirSmeSetContextRsp *pRsp = (tSirSmeSetContextRsp *)pSirMsg; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandSetKey == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(eCSR_ENCRYPT_TYPE_NONE != pSession->connectedProfile.EncryptionType) + { + WLAN_VOS_DIAG_EVENT_DEF(setKeyEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&setKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + if( pRsp->peerMacAddr[0] & 0x01 ) + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_RSP; + } + else + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_RSP; + } + setKeyEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + setKeyEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(setKeyEvent.bssid, + pSession->connectedProfile.bssid, 6); + setKeyEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + if( eSIR_SME_SUCCESS != pRsp->statusCode ) + { + setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + } + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + + //We are done with authentication, whethere succeed or not + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + //We do it here because this linkup function is not called after association + //when a key needs to be set. + if( csrIsConnStateConnectedInfra(pMac, sessionId) ) + { + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + } + } + if( eSIR_SME_SUCCESS == pRsp->statusCode ) + { + vos_mem_copy(&roamInfo.peerMac, + &pRsp->peerMacAddr, sizeof(tCsrBssid)); + //Make sure we install the GTK before indicating to HDD as authenticated + //This is to prevent broadcast packets go out after PTK and before GTK. + if ( vos_mem_compare( &Broadcastaddr, pRsp->peerMacAddr, + sizeof(tSirMacAddr) ) ) + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + tpSirSetActiveModeSetBncFilterReq pMsg; + pMsg = vos_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq)); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_BCN_FILTER_REQ); + pMsg->length = pal_cpu_to_be16(sizeof( tANI_U8)); + pMsg->seesionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg ); + } +#endif + result = eCSR_ROAM_RESULT_AUTHENTICATED; + } + else + { + result = eCSR_ROAM_RESULT_NONE; + } + pRoamInfo = &roamInfo; + } + else + { + result = eCSR_ROAM_RESULT_FAILURE; + smsLog(pMac, LOGE, "CSR: Roam Completion setkey " + "command failed(%d) PeerMac "MAC_ADDRESS_STR, + pRsp->statusCode, MAC_ADDR_ARRAY(pRsp->peerMacAddr)); + } + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.setKeyCmd.roamId, + eCSR_ROAM_SET_KEY_COMPLETE, result); + // Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS + // can go ahead and initiate the TSPEC if any are pending + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL); +#ifdef FEATURE_WLAN_ESE + //Send Adjacent AP repot to new AP. + if (result == eCSR_ROAM_RESULT_AUTHENTICATED && + pSession->isPrevApInfoValid && + pSession->connectedProfile.isESEAssoc) + { +#ifdef FEATURE_WLAN_ESE_UPLOAD + csrSendEseAdjacentApRepInd(pMac, pSession); +#else + csrEseSendAdjacentApRepMsg(pMac, pSession); +#endif + pSession->isPrevApInfoValid = FALSE; + } +#endif + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGE, "CSR: Roam Completion called but setkey command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGE, "CSR: SetKey Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); + } + break; + case eWNI_SME_REMOVEKEY_RSP: + { + tSirSmeRemoveKeyRsp *pRsp = (tSirSmeRemoveKeyRsp *)pSirMsg; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandRemoveKey == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(removeKeyEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&removeKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_RSP; + removeKeyEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + removeKeyEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy( removeKeyEvent.bssid, + pSession->connectedProfile.bssid, 6); + removeKeyEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + if( eSIR_SME_SUCCESS != pRsp->statusCode ) + { + removeKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + } + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( eSIR_SME_SUCCESS == pRsp->statusCode ) + { + vos_mem_copy(&roamInfo.peerMac, &pRsp->peerMacAddr, + sizeof(tCsrBssid)); + result = eCSR_ROAM_RESULT_NONE; + pRoamInfo = &roamInfo; + } + else + { + result = eCSR_ROAM_RESULT_FAILURE; + } + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.setKeyCmd.roamId, + eCSR_ROAM_REMOVE_KEY_COMPLETE, result); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but setkey command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: SetKey Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); + } + break; + case eWNI_SME_GET_STATISTICS_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamStatsRspProcessor( pMac, pSirMsg ); + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamRssiRspProcessor( pMac, pSirMsg ); + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_RSP: + smsLog( pMac, LOG2, FL("TSM Stats rsp from PE")); + csrTsmStatsRspProcessor( pMac, pSirMsg ); + break; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_GET_RSSI_REQ: + smsLog( pMac, LOG2, FL("GetRssiReq from self")); + csrUpdateRssi( pMac, pSirMsg ); + break; + + case eWNI_SME_GET_SNR_REQ: + smsLog( pMac, LOG2, FL("GetSnrReq from self")); + csrUpdateSnr(pMac, pSirMsg); + break; + +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_PRE_AUTH_RSP: + csrRoamFTPreAuthRspProcessor( pMac, (tpSirFTPreAuthRsp)pSirMsg ); + break; +#endif + case eWNI_SME_MAX_ASSOC_EXCEEDED: + pSmeMaxAssocInd = (tSmeMaxAssocInd*)pSirMsg; + smsLog( pMac, LOG1, FL("send indication that max assoc have been reached and the new peer cannot be accepted")); + sessionId = pSmeMaxAssocInd->sessionId; + roamInfo.sessionId = sessionId; + vos_mem_copy(&roamInfo.peerMac, pSmeMaxAssocInd->peerMac, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED); + break; + + case eWNI_SME_BTAMP_LOG_LINK_IND: + smsLog( pMac, LOG1, FL("Establish logical link req from HCI serialized through MC thread")); + btampEstablishLogLinkHdlr( pSirMsg ); + break; + case eWNI_SME_RSSI_IND: + smsLog( pMac, LOG1, FL("RSSI indication from TL serialized through MC thread")); + csrRoamRssiIndHdlr( pMac, pSirMsg ); + break; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eWNI_SME_CANDIDATE_FOUND_IND: + smsLog(pMac, LOG2, FL("Candidate found indication from PE")); + csrNeighborRoamCandidateFoundIndHdlr(pMac, pSirMsg); + break; + case eWNI_SME_HANDOFF_REQ: + smsLog( pMac, LOG2, FL("Handoff Req from self")); + csrNeighborRoamHandoffReqHdlr( pMac, pSirMsg ); + break; +#endif + + default: + break; + } // end switch on message type +} + +void csrCallRoamingCompletionCallback(tpAniSirGlobal pMac, tCsrRoamSession *pSession, + tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, eCsrRoamResult roamResult) +{ + if(pSession) + { + if(pSession->bRefAssocStartCnt) + { + pSession->bRefAssocStartCnt--; + + if (0 != pSession->bRefAssocStartCnt) + { + VOS_ASSERT( pSession->bRefAssocStartCnt == 0); + return; + } + //Need to call association_completion because there is an assoc_start pending. + csrRoamCallCallback(pMac, pSession->sessionId, NULL, roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_FAILURE); + } + csrRoamCallCallback(pMac, pSession->sessionId, pRoamInfo, roamId, eCSR_ROAM_ROAMING_COMPLETION, roamResult); + } + else + { + smsLog(pMac, LOGW, FL(" pSession is NULL")); + } +} + + +eHalStatus csrRoamStartRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamingReason roamingReason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + if(CSR_IS_LOSTLINK_ROAMING(roamingReason) && + (eANI_BOOLEAN_FALSE == pMac->roam.roamSession[sessionId].fCancelRoaming)) + { + status = csrScanRequestLostLink1( pMac, sessionId ); + } + return(status); +} + +//return a boolean to indicate whether roaming completed or continue. +tANI_BOOLEAN csrRoamCompleteRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fForce, eCsrRoamResult roamResult) +{ + tANI_BOOLEAN fCompleted = eANI_BOOLEAN_TRUE; + tANI_TIMESTAMP roamTime = (tANI_TIMESTAMP)(pMac->roam.configParam.nRoamingTime * PAL_TICKS_PER_SECOND); + tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eANI_BOOLEAN_FALSE; + } + //Check whether time is up + if(pSession->fCancelRoaming || fForce || + ((curTime - pSession->roamingStartTime) > roamTime) || + eCsrReassocRoaming == pSession->roamingReason || + eCsrDynamicRoaming == pSession->roamingReason) + { + smsLog(pMac, LOGW, FL(" indicates roaming completion")); + if(pSession->fCancelRoaming && CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason)) + { + //roaming is cancelled, tell HDD to indicate disconnect + //Because LIM overload deauth_ind for both deauth frame and missed beacon + //we need to use this logic to detinguish it. For missed beacon, LIM set reason + //to be eSIR_BEACON_MISSED + if(eSIR_BEACON_MISSED == pSession->roamingStatusCode) + { + roamResult = eCSR_ROAM_RESULT_LOSTLINK; + } + else if(eCsrLostlinkRoamingDisassoc == pSession->roamingReason) + { + roamResult = eCSR_ROAM_RESULT_DISASSOC_IND; + } + else if(eCsrLostlinkRoamingDeauth == pSession->roamingReason) + { + roamResult = eCSR_ROAM_RESULT_DEAUTH_IND; + } + else + { + roamResult = eCSR_ROAM_RESULT_LOSTLINK; + } + } + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + else + { + pSession->roamResult = roamResult; + if(!HAL_STATUS_SUCCESS(csrRoamStartRoamingTimer(pMac, sessionId, + VOS_TIMER_TO_SEC_UNIT))) + { + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + else + { + fCompleted = eANI_BOOLEAN_FALSE; + } + } + return(fCompleted); +} + +void csrRoamCancelRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(CSR_IS_ROAMING(pSession)) + { + smsLog(pMac, LOGW, " Cancelling roaming"); + pSession->fCancelRoaming = eANI_BOOLEAN_TRUE; + if(CSR_IS_ROAM_JOINING(pMac, sessionId) && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) + { + //No need to do anything in here because the handler takes care of it + } + else + { + eCsrRoamResult roamResult = CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason) ? + eCSR_ROAM_RESULT_LOSTLINK : eCSR_ROAM_RESULT_NONE; + //Roaming is stopped after here + csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_TRUE, roamResult); + //Since CSR may be in lostlink roaming situation, abort all roaming related activities + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + csrRoamStopRoamingTimer(pMac, sessionId); + } + } +} + +void csrRoamRoamingTimerHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tANI_U32 sessionId = pInfo->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(eANI_BOOLEAN_FALSE == pSession->fCancelRoaming) + { + if(!HAL_STATUS_SUCCESS(csrRoamStartRoaming(pMac, sessionId, pSession->roamingReason))) + { + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, pSession->roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + } +} + +eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval) +{ + eHalStatus status; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG1, " csrScanStartRoamingTimer"); + pSession->roamingTimerInfo.sessionId = (tANI_U8)sessionId; + status = vos_timer_start(&pSession->hTimerRoaming, + interval/VOS_TIMER_TO_MS_UNIT); + + return (status); +} + +eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (vos_timer_stop(&pMac->roam.roamSession[sessionId].hTimerRoaming)); +} + +void csrRoamWaitForKeyTimeOutHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pInfo->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if(pSession == NULL) { + smsLog(pMac, LOGE, "%s: session not found", __func__); + return; + } + + smsLog(pMac, LOGW, FL("WaitForKey timer expired in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[pInfo->sessionId].neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pInfo->sessionId])); + + if( CSR_IS_WAIT_FOR_KEY( pMac, pInfo->sessionId ) ) + { +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac, pInfo->sessionId)) + { + /* + * Enable heartbeat timer when hand-off is in progress + * and Key Wait timer expired. + */ + smsLog(pMac, LOG2, "Enabling HB timer after WaitKey expiry" + " (nHBCount=%d)", + pMac->roam.configParam.HeartbeatThresh24); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, + pMac->roam.configParam.HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE); + } +#endif + smsLog(pMac, LOGE, " SME pre-auth state timeout. "); + + //Change the substate so command queue is unblocked. + if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) + { + csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE, + pInfo->sessionId); + } + + if( csrIsConnStateConnectedInfra(pMac, pInfo->sessionId) ) + { + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + smeProcessPendingQueue(pMac); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status )) + { + csrRoamDisconnect(pMac, pInfo->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + sme_ReleaseGlobalLock(&pMac->sme); + } + } + else + { + smsLog(pMac, LOGE, "%s: Session id %d is disconnected", + __func__, pInfo->sessionId); + } + } +} + +eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval) +{ + eHalStatus status; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.sessionId]; +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac, + pMac->roam.WaitForKeyTimerInfo.sessionId)) + { + /* Disable heartbeat timer when hand-off is in progress */ + smsLog(pMac, LOG2, FL("disabling HB timer in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pMac->roam.WaitForKeyTimerInfo.sessionId] + )); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + } +#endif + smsLog(pMac, LOG1, " csrScanStartWaitForKeyTimer"); + status = vos_timer_start(&pMac->roam.hTimerWaitForKey, + interval/VOS_TIMER_TO_MS_UNIT); + + return (status); +} + +eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.sessionId]; + + smsLog(pMac, LOG2, FL("WaitForKey timer stopped in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pMac->roam.WaitForKeyTimerInfo.sessionId])); +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac, + pMac->roam.WaitForKeyTimerInfo.sessionId)) + { + /* + * Enable heartbeat timer when hand-off is in progress + * and Key Wait timer got stopped for some reason + */ + smsLog(pMac, LOG2, "Enabling HB timer after WaitKey stop" + " (nHBCount=%d)", + pMac->roam.configParam.HeartbeatThresh24); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, + pMac->roam.configParam.HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE); + } +#endif + return (vos_timer_stop(&pMac->roam.hTimerWaitForKey)); +} + +void csrRoamCompletion(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand, + eCsrRoamResult roamResult, tANI_BOOLEAN fSuccess) +{ + eRoamCmdStatus roamStatus = csrGetRoamCompleteStatus(pMac, sessionId); + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(pCommand) + { + roamId = pCommand->u.roamCmd.roamId; + if (sessionId != pCommand->sessionId) + { + VOS_ASSERT( sessionId == pCommand->sessionId ); + return; + } + } + if(eCSR_ROAM_ROAMING_COMPLETION == roamStatus) + { + //if success, force roaming completion + csrRoamCompleteRoaming(pMac, sessionId, fSuccess, roamResult); + } + else + { + if (pSession->bRefAssocStartCnt != 0) + { + VOS_ASSERT(pSession->bRefAssocStartCnt == 0); + return; + } + smsLog(pMac, LOGW, FL(" indicates association completion. roamResult = %d"), roamResult); + csrRoamCallCallback(pMac, sessionId, pRoamInfo, roamId, roamStatus, roamResult); + } +} + +eHalStatus csrRoamLostLink( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 type, tSirSmeRsp *pSirMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthInd *pDeauthIndMsg = NULL; + tSirSmeDisassocInd *pDisassocIndMsg = NULL; + eCsrRoamResult result = eCSR_ROAM_RESULT_LOSTLINK; + tCsrRoamInfo *pRoamInfo = NULL; + tCsrRoamInfo roamInfo; + tANI_BOOLEAN fToRoam; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + //Only need to roam for infra station. In this case P2P client will roam as well + fToRoam = CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile); + pSession->fCancelRoaming = eANI_BOOLEAN_FALSE; + if ( eWNI_SME_DISASSOC_IND == type ) + { + result = eCSR_ROAM_RESULT_DISASSOC_IND; + pDisassocIndMsg = (tSirSmeDisassocInd *)pSirMsg; + pSession->roamingStatusCode = pDisassocIndMsg->statusCode; + pSession->joinFailStatusCode.reasonCode = pDisassocIndMsg->reasonCode; + } + else if ( eWNI_SME_DEAUTH_IND == type ) + { + result = eCSR_ROAM_RESULT_DEAUTH_IND; + pDeauthIndMsg = (tSirSmeDeauthInd *)pSirMsg; + pSession->roamingStatusCode = pDeauthIndMsg->statusCode; + /* Convert into proper reason code */ + pSession->joinFailStatusCode.reasonCode = + (pDeauthIndMsg->reasonCode == eSIR_BEACON_MISSED) ? + 0 : pDeauthIndMsg->reasonCode; + /* cfg layer expects 0 as reason code if + the driver dosent know the reason code + eSIR_BEACON_MISSED is defined as locally */ + } + else + { + smsLog(pMac, LOGW, FL("gets an unknown type (%d)"), type); + result = eCSR_ROAM_RESULT_NONE; + pSession->joinFailStatusCode.reasonCode = 1; + } + + // call profile lost link routine here + if(!CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_LOSTLINK_DETECTED, result); + /*Move the state to Idle after disconnection*/ + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + + } + + if ( eWNI_SME_DISASSOC_IND == type ) + { + status = csrSendMBDisassocCnfMsg(pMac, pDisassocIndMsg); + } + else if ( eWNI_SME_DEAUTH_IND == type ) + { + status = csrSendMBDeauthCnfMsg(pMac, pDeauthIndMsg); + } + if(!HAL_STATUS_SUCCESS(status)) + { + //If fail to send confirmation to PE, not to trigger roaming + fToRoam = eANI_BOOLEAN_FALSE; + } + + //prepare to tell HDD to disconnect + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.statusCode = (tSirResultCodes)pSession->roamingStatusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + if( eWNI_SME_DISASSOC_IND == type) + { + //staMacAddr + vos_mem_copy(roamInfo.peerMac, pDisassocIndMsg->peerMacAddr, + sizeof(tSirMacAddr)); + roamInfo.staId = (tANI_U8)pDisassocIndMsg->staId; + roamInfo.reasonCode = pDisassocIndMsg->reasonCode; + } + else if( eWNI_SME_DEAUTH_IND == type ) + { + //staMacAddr + vos_mem_copy(roamInfo.peerMac, pDeauthIndMsg->peerMacAddr, + sizeof(tSirMacAddr)); + roamInfo.staId = (tANI_U8)pDeauthIndMsg->staId; + roamInfo.reasonCode = pDeauthIndMsg->reasonCode; + } + smsLog(pMac, LOGW, FL("roamInfo.staId (%d)"), roamInfo.staId); + + /* See if we can possibly roam. If so, start the roaming process and notify HDD + that we are roaming. But if we cannot possibly roam, or if we are unable to + currently roam, then notify HDD of the lost link */ + if(fToRoam) + { + //Only remove the connected BSS in infrastructure mode + csrRoamRemoveConnectedBssFromScanCache(pMac, &pSession->connectedProfile); + //Not to do anying for lostlink with WDS + if( pMac->roam.configParam.nRoamingTime ) + { + if(HAL_STATUS_SUCCESS(status = csrRoamStartRoaming(pMac, sessionId, + ( eWNI_SME_DEAUTH_IND == type ) ? + eCsrLostlinkRoamingDeauth : eCsrLostlinkRoamingDisassoc))) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + //For IBSS, we need to give some more info to HDD + if(csrIsBssTypeIBSS(pSession->connectedProfile.BSSType)) + { + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + roamInfo.statusCode = (tSirResultCodes)pSession->roamingStatusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + } + else + { + roamInfo.reasonCode = eCsrRoamReasonSmeIssuedForLostLink; + } + pRoamInfo = &roamInfo; + pSession->roamingReason = ( eWNI_SME_DEAUTH_IND == type ) ? + eCsrLostlinkRoamingDeauth : eCsrLostlinkRoamingDisassoc; + pSession->roamingStartTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_LOSTLINK); + } + else + { + smsLog(pMac, LOGW, " %s Fail to start roaming, status = %d", __func__, status); + fToRoam = eANI_BOOLEAN_FALSE; + } + } + else + { + //We are told not to roam, indicate lostlink + fToRoam = eANI_BOOLEAN_FALSE; + } + } + if(!fToRoam) + { + //Tell HDD about the lost link + if(!CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + /* Don't call csrRoamCallCallback for GO/SoftAp case as this indication + * was already given as part of eWNI_SME_DISASSOC_IND msg handling in + * csrRoamCheckForLinkStatusChange API. + */ + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_LOSTLINK, result); + } + + /*No need to start idle scan in case of IBSS/SAP + Still enable idle scan for polling in case concurrent sessions are running */ + if(CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile)) + { + csrScanStartIdleScan(pMac); + } + } + + return (status); +} + +eHalStatus csrRoamLostLinkAfterhandoffFailure( tpAniSirGlobal pMac,tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pSession->fCancelRoaming = eANI_BOOLEAN_FALSE; + //Only remove the connected BSS in infrastructure mode + csrRoamRemoveConnectedBssFromScanCache(pMac, &pSession->connectedProfile); + if(pMac->roam.configParam.nRoamingTime) + { + if(HAL_STATUS_SUCCESS(status = csrRoamStartRoaming(pMac,sessionId, pSession->roamingReason))) + { + //before starting the lost link logic release the roam command for handoff + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + if(pCommand) + { + if (( eSmeCommandRoam == pCommand->command ) && + ( eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + } + } + smsLog( pMac, LOGW, "Lost link roaming started ..."); + } + } + else + { + //We are told not to roam, indicate lostlink + status = eHAL_STATUS_FAILURE; + } + + return (status); +} +void csrRoamWmStatusChangeComplete( tpAniSirGlobal pMac ) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandWmStatusChange == pCommand->command ) + { + // Nothing to process in a Lost Link completion.... It just kicks off a + // roaming sequence. + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandWmStatusChange( pMac, pCommand ); + } + else + { + smsLog( pMac, LOGE, " ******csrRoamWmStatusChangeComplete fail to release command"); + } + + } + else + { + smsLog( pMac, LOGW, "CSR: WmStatusChange Completion called but LOST LINK command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: WmStatusChange Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); +} + +void csrRoamProcessWmStatusChangeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirSmeRsp *pSirSmeMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pCommand->sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), pCommand->sessionId); + return; + } + + switch ( pCommand->u.wmStatusChangeCmd.Type ) + { + case eCsrDisassociated: + pSirSmeMsg = (tSirSmeRsp *)&pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg; + status = csrRoamLostLink(pMac, pCommand->sessionId, eWNI_SME_DISASSOC_IND, pSirSmeMsg); + break; + case eCsrDeauthenticated: + pSirSmeMsg = (tSirSmeRsp *)&pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg; + status = csrRoamLostLink(pMac, pCommand->sessionId, eWNI_SME_DEAUTH_IND, pSirSmeMsg); + break; + default: + smsLog(pMac, LOGW, FL("gets an unknown command %d"), pCommand->u.wmStatusChangeCmd.Type); + break; + } + //For WDS, we want to stop BSS as well when it is indicated that it is disconnected. + if( CSR_IS_CONN_WDS(&pSession->connectedProfile) ) + { + if( !HAL_STATUS_SUCCESS(csrRoamIssueStopBssCmd( pMac, pCommand->sessionId, eANI_BOOLEAN_TRUE )) ) + { + //This is not good + smsLog(pMac, LOGE, FL(" failed to issue stopBSS command")); + } + } + // Lost Link just triggers a roaming sequence. We can complte the Lost Link + // command here since there is nothing else to do. + csrRoamWmStatusChangeComplete( pMac ); +} + +//This function returns band and mode information. +//The only tricky part is that if phyMode is set to 11abg, this function may return eCSR_CFG_DOT11_MODE_11B +//instead of eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick. +static eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tANI_U8 operationChn, eCsrBand *pBand ) +{ + eCsrPhyMode phyModeIn = (eCsrPhyMode)pProfile->phyMode; + eCsrCfgDot11Mode cfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(pProfile, phyModeIn, + pMac->roam.configParam.ProprietaryRatesEnabled); + eCsrBand eBand; + //If the global setting for dot11Mode is set to auto/abg, we overwrite the setting in the profile. + if( ((!CSR_IS_INFRA_AP(pProfile )&& !CSR_IS_WDS(pProfile )) && + ((eCSR_CFG_DOT11_MODE_AUTO == pMac->roam.configParam.uCfgDot11Mode) || + (eCSR_CFG_DOT11_MODE_ABG == pMac->roam.configParam.uCfgDot11Mode))) || + (eCSR_CFG_DOT11_MODE_AUTO == cfgDot11Mode) || (eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode) ) + { + switch( pMac->roam.configParam.uCfgDot11Mode ) + { + case eCSR_CFG_DOT11_MODE_11A: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + eBand = eCSR_BAND_5G; + break; + case eCSR_CFG_DOT11_MODE_11B: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + eBand = eCSR_BAND_24; + break; + case eCSR_CFG_DOT11_MODE_11G: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + eBand = eCSR_BAND_24; + break; + case eCSR_CFG_DOT11_MODE_11N: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_CFG_DOT11_MODE_11AC: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + break; + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; +#endif + case eCSR_CFG_DOT11_MODE_AUTO: + eBand = pMac->roam.configParam.eBand; + if (eCSR_BAND_24 == eBand) + { + // WiFi tests require IBSS networks to start in 11b mode + // without any change to the default parameter settings + // on the adapter. We use ACU to start an IBSS through + // creation of a startIBSS profile. This startIBSS profile + // has Auto MACProtocol and the adapter property setting + // for dot11Mode is also AUTO. So in this case, let's + // start the IBSS network in 11b mode instead of 11g mode. + // So this is for Auto=profile->MacProtocol && Auto=Global. + // dot11Mode && profile->channel is < 14, then start the IBSS + // in b mode. + // + // Note: we used to have this start as an 11g IBSS for best + // performance... now to specify that the user will have to + // set the do11Mode in the property page to 11g to force it. + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { +#ifdef WLAN_FEATURE_11AC + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } +#else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; +#endif + } + break; + default: + // Global dot11 Mode setting is 11a/b/g. + // use the channel number to determine the Mode setting. + if ( eCSR_OPERATING_CHANNEL_AUTO == operationChn ) + { + eBand = pMac->roam.configParam.eBand; + if(eCSR_BAND_24 == eBand) + { + //See reason in else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) to pick 11B + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + //prefer 5GHz + eBand = eCSR_BAND_5G; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + // WiFi tests require IBSS networks to start in 11b mode + // without any change to the default parameter settings + // on the adapter. We use ACU to start an IBSS through + // creation of a startIBSS profile. This startIBSS profile + // has Auto MACProtocol and the adapter property setting + // for dot11Mode is also AUTO. So in this case, let's + // start the IBSS network in 11b mode instead of 11g mode. + // So this is for Auto=profile->MacProtocol && Auto=Global. + // dot11Mode && profile->channel is < 14, then start the IBSS + // in b mode. + // + // Note: we used to have this start as an 11g IBSS for best + // performance... now to specify that the user will have to + // set the do11Mode in the property page to 11g to force it. + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + eBand = eCSR_BAND_24; + } + else + { + // else, it's a 5.0GHz channel. Set mode to 11a. + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + eBand = eCSR_BAND_5G; + } + break; + }//switch + }//if( eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode ) + else + { + //dot11 mode is set, lets pick the band + if ( eCSR_OPERATING_CHANNEL_AUTO == operationChn ) + { + // channel is Auto also. + eBand = pMac->roam.configParam.eBand; + if(eCSR_BAND_ALL == eBand) + { + //prefer 5GHz + eBand = eCSR_BAND_5G; + } + } + else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + eBand = eCSR_BAND_24; + } + else + { + eBand = eCSR_BAND_5G; + } + } + if(pBand) + { + *pBand = eBand; + } + + if (operationChn == 14){ + smsLog(pMac, LOGE, FL(" Switching to Dot11B mode ")); + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + + /* Incase of WEP Security encryption type is coming as part of add key. So while STart BSS dont have information */ + if( (!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) || ((pProfile->privacy == 1) && (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE)) ) && + ((eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode) || +#ifdef WLAN_FEATURE_11AC + (eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode) || +#endif + (eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11Mode)) ) + { + //We cannot do 11n here + if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + return( cfgDot11Mode ); +} + +eHalStatus csrRoamIssueStopBss( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ) +{ + eHalStatus status; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_REQ; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + // Set the roaming substate to 'stop Bss request'... + csrRoamSubstateChange( pMac, NewSubstate, sessionId ); + + // attempt to stop the Bss (reason code is ignored...) + status = csrSendMBStopBssReqMsg( pMac, sessionId ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL("csrSendMBStopBssReqMsg failed with status %d"), status); + } + return (status); +} + +//pNumChan is a caller allocated space with the sizeof pChannels +eHalStatus csrGetCfgValidChannels(tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U32 *pNumChan) +{ + + return (ccmCfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + (tANI_U8 *)pChannels, + pNumChan)); +} + +tPowerdBm csrGetCfgMaxTxPower (tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U32 cfgLength = 0; + tANI_U16 cfgId = 0; + tPowerdBm maxTxPwr = 0; + tANI_U8 *pCountryInfo = NULL; + eHalStatus status; + tANI_U8 count = 0; + tANI_U8 firstChannel; + tANI_U8 maxChannels; + + if (CSR_IS_CHANNEL_5GHZ(channel)) + { + cfgId = WNI_CFG_MAX_TX_POWER_5; + cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN; + } + else if (CSR_IS_CHANNEL_24GHZ(channel)) + { + cfgId = WNI_CFG_MAX_TX_POWER_2_4; + cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN; + } + else + return maxTxPwr; + + pCountryInfo = vos_mem_malloc(cfgLength); + if ( NULL == pCountryInfo ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("%s: failed to allocate memory, status = %d"), + __FUNCTION__, status); + goto error; + } + status = ccmCfgGetStr(pMac, cfgId, (tANI_U8 *)pCountryInfo, &cfgLength); + if (status != eHAL_STATUS_SUCCESS) + { + goto error; + } + /* Identify the channel and maxtxpower */ + while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) + { + firstChannel = pCountryInfo[count++]; + maxChannels = pCountryInfo[count++]; + maxTxPwr = pCountryInfo[count++]; + + if ((channel >= firstChannel) && + (channel < (firstChannel + maxChannels))) + { + break; + } + } + +error: + if (NULL != pCountryInfo) + vos_mem_free(pCountryInfo); + + return maxTxPwr; +} + + +tANI_BOOLEAN csrRoamIsChannelValid( tpAniSirGlobal pMac, tANI_U8 channel ) +{ + tANI_BOOLEAN fValid = FALSE; + tANI_U32 idxValidChannels; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ ) + { + if ( channel == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fValid = TRUE; + break; + } + } + } + pMac->roam.numValidChannels = len; + return fValid; +} + +tANI_BOOLEAN csrRoamIsValid40MhzChannel(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_BOOLEAN fValid = eANI_BOOLEAN_FALSE; + tANI_U8 i; + for(i = 0; i < pMac->scan.base40MHzChannels.numChannels; i++) + { + if(channel == pMac->scan.base40MHzChannels.channelList[i]) + { + fValid = eANI_BOOLEAN_TRUE; + break; + } + } + return (fValid); +} + +//This function check and validate whether the NIC can do CB (40MHz) + static ePhyChanBondState csrGetCBModeFromIes(tpAniSirGlobal pMac, tANI_U8 primaryChn, tDot11fBeaconIEs *pIes) +{ + ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED; + tANI_U8 centerChn; + tANI_U32 ChannelBondingMode; + if(CSR_IS_CHANNEL_24GHZ(primaryChn)) + { + ChannelBondingMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + ChannelBondingMode = pMac->roam.configParam.channelBondingMode5GHz; + } + //Figure what the other side's CB mode + if(WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != ChannelBondingMode) + { + if(pIes->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ == + pIes->HTCaps.supportedChannelWidthSet)) + { + // Check set as TKIP or not. + if (((NULL != &(pIes->RSN.pwise_cipher_suites[0][0]) && + (pIes->RSN.pwise_cipher_suite_count == 1)) && + !memcmp( &(pIes->RSN.pwise_cipher_suites[0][0]), + "\x00\x0f\xac\x02" ,4)) + || (((NULL != &(pIes->WPA)) && + (pIes->WPA.unicast_cipher_count == 1)) + && ((NULL != &(pIes->WPA.unicast_ciphers[0])) + && !memcmp(&(pIes->WPA.unicast_ciphers[0]), + "\x00\x0f\xac\x02", 4)))) + { + smsLog(pMac, LOGW, " No channel bonding in TKIP mode "); + eRet = PHY_SINGLE_CHANNEL_CENTERED; + } + + else if(pIes->HTInfo.present) + { + /* This is called during INFRA STA/CLIENT and should use the merged value of + * supported channel width and recommended tx width as per standard + */ + smsLog(pMac, LOG1, "scws %u rtws %u sco %u", + pIes->HTCaps.supportedChannelWidthSet, + pIes->HTInfo.recommendedTxWidthSet, + pIes->HTInfo.secondaryChannelOffset); + + if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ) + eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset; + else + eRet = PHY_SINGLE_CHANNEL_CENTERED; + switch (eRet) { + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + centerChn = primaryChn + CSR_CB_CENTER_CHANNEL_OFFSET; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + centerChn = primaryChn - CSR_CB_CENTER_CHANNEL_OFFSET; + break; + case PHY_SINGLE_CHANNEL_CENTERED: + default: + centerChn = primaryChn; + break; + } + if((PHY_SINGLE_CHANNEL_CENTERED != eRet) && !csrRoamIsValid40MhzChannel(pMac, centerChn)) + { + smsLog(pMac, LOGE, " Invalid center channel (%d), disable 40MHz mode", centerChn); + eRet = PHY_SINGLE_CHANNEL_CENTERED; + } + } + } + } + return eRet; +} +tANI_BOOLEAN csrIsEncryptionInList( tpAniSirGlobal pMac, tCsrEncryptionList *pCipherList, eCsrEncryptionType encryptionType ) +{ + tANI_BOOLEAN fFound = FALSE; + tANI_U32 idx; + for( idx = 0; idx < pCipherList->numEntries; idx++ ) + { + if( pCipherList->encryptionType[idx] == encryptionType ) + { + fFound = TRUE; + break; + } + } + return fFound; +} +tANI_BOOLEAN csrIsAuthInList( tpAniSirGlobal pMac, tCsrAuthList *pAuthList, eCsrAuthType authType ) +{ + tANI_BOOLEAN fFound = FALSE; + tANI_U32 idx; + for( idx = 0; idx < pAuthList->numEntries; idx++ ) + { + if( pAuthList->authType[idx] == authType ) + { + fFound = TRUE; + break; + } + } + return fFound; +} +tANI_BOOLEAN csrIsSameProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile1, tCsrRoamProfile *pProfile2) +{ + tANI_BOOLEAN fCheck = eANI_BOOLEAN_FALSE; + tCsrScanResultFilter *pScanFilter = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pProfile1 && pProfile2) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile2, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + fCheck = eANI_BOOLEAN_FALSE; + do + { + tANI_U32 i; + for(i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) + { + fCheck = csrIsSsidMatch( pMac, pScanFilter->SSIDs.SSIDList[i].SSID.ssId, + pScanFilter->SSIDs.SSIDList[i].SSID.length, + pProfile1->SSID.ssId, pProfile1->SSID.length, eANI_BOOLEAN_FALSE ); + if ( fCheck ) break; + } + if(!fCheck) + { + break; + } + if( !csrIsAuthInList( pMac, &pProfile2->AuthType, pProfile1->AuthType) + || pProfile2->BSSType != pProfile1->BSSType + || !csrIsEncryptionInList( pMac, &pProfile2->EncryptionType, pProfile1->EncryptionType ) + ) + { + fCheck = eANI_BOOLEAN_FALSE; + break; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pProfile1->MDID.mdiePresent || pProfile2->MDID.mdiePresent) + { + if (pProfile1->MDID.mobilityDomain != pProfile2->MDID.mobilityDomain) + { + fCheck = eANI_BOOLEAN_FALSE; + break; + } + } +#endif + //Match found + fCheck = eANI_BOOLEAN_TRUE; + }while(0); + csrFreeScanFilter(pMac, pScanFilter); + } + vos_mem_free(pScanFilter); + } + } + + return (fCheck); +} + +tANI_BOOLEAN csrRoamIsSameProfileKeys(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile, tCsrRoamProfile *pProfile2) +{ + tANI_BOOLEAN fCheck = eANI_BOOLEAN_FALSE; + int i; + do + { + //Only check for static WEP + if(!csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) && + !csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) + { + fCheck = eANI_BOOLEAN_TRUE; + break; + } + if(!csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, pConnProfile->EncryptionType)) break; + if(pConnProfile->Keys.defaultIndex != pProfile2->Keys.defaultIndex) break; + for(i = 0; i < CSR_MAX_NUM_KEY; i++) + { + if(pConnProfile->Keys.KeyLength[i] != pProfile2->Keys.KeyLength[i]) break; + if (!vos_mem_compare(&pConnProfile->Keys.KeyMaterial[i], + &pProfile2->Keys.KeyMaterial[i], pProfile2->Keys.KeyLength[i])) + { + break; + } + } + if( i == CSR_MAX_NUM_KEY) + { + fCheck = eANI_BOOLEAN_TRUE; + } + }while(0); + return (fCheck); +} + +//IBSS + +tANI_U8 csrRoamGetIbssStartChannelNumber50( tpAniSirGlobal pMac ) +{ + tANI_U8 channel = 0; + tANI_U32 idx; + tANI_U32 idxValidChannels; + tANI_BOOLEAN fFound = FALSE; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if(eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel5G) + { + channel = pMac->roam.configParam.AdHocChannel5G; + if(!csrRoamIsChannelValid(pMac, channel)) + { + channel = 0; + } + } + if (0 == channel && HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + for ( idx = 0; ( idx < CSR_NUM_IBSS_START_CHANNELS_50 ) && !fFound; idx++ ) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ) && !fFound; idxValidChannels++ ) + { + if ( csrStartIbssChannels50[ idx ] == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fFound = TRUE; + channel = csrStartIbssChannels50[ idx ]; + } + } + } + // this is rare, but if it does happen, we find anyone in 11a bandwidth and return the first 11a channel found! + if (!fFound) + { + for ( idxValidChannels = 0; idxValidChannels < len ; idxValidChannels++ ) + { + if ( CSR_IS_CHANNEL_5GHZ(pMac->roam.validChannelList[ idxValidChannels ]) ) // the max channel# in 11g is 14 + { + if (idxValidChannels < CSR_NUM_IBSS_START_CHANNELS_50) + { + channel = csrStartIbssChannels50[ idxValidChannels ]; + } + break; + } + } + } + }//if + + return( channel ); +} + +tANI_U8 csrRoamGetIbssStartChannelNumber24( tpAniSirGlobal pMac ) +{ + tANI_U8 channel = 1; + tANI_U32 idx; + tANI_U32 idxValidChannels; + tANI_BOOLEAN fFound = FALSE; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if(eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel24) + { + channel = pMac->roam.configParam.AdHocChannel24; + if(!csrRoamIsChannelValid(pMac, channel)) + { + channel = 0; + } + } + + if (0 == channel && HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + for ( idx = 0; ( idx < CSR_NUM_IBSS_START_CHANNELS_24 ) && !fFound; idx++ ) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ) && !fFound; idxValidChannels++ ) + { + if ( csrStartIbssChannels24[ idx ] == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fFound = TRUE; + channel = csrStartIbssChannels24[ idx ]; + } + } + } + } + + return( channel ); +} + +static void csrRoamGetBssStartParms( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tCsrRoamStartBssParams *pParam ) +{ + eCsrCfgDot11Mode cfgDot11Mode; + eCsrBand eBand; + tANI_U8 channel = 0; + tSirNwType nwType; + tANI_U8 operationChannel = 0; + + if(pProfile->ChannelInfo.numOfChannels && pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + + cfgDot11Mode = csrRoamGetPhyModeBandForBss( pMac, pProfile, operationChannel, &eBand ); + + if( ( (pProfile->csrPersona == VOS_P2P_CLIENT_MODE) || + (pProfile->csrPersona == VOS_P2P_GO_MODE) ) + && ( cfgDot11Mode == eCSR_CFG_DOT11_MODE_11B) + ) + { + /* This should never happen */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + FL("For P2PClient/P2P-GO (persona %d) cfgDot11Mode is 11B"), + pProfile->csrPersona); + VOS_ASSERT(0); + } + switch( cfgDot11Mode ) + { + case eCSR_CFG_DOT11_MODE_11G: + nwType = eSIR_11G_NW_TYPE; + break; + case eCSR_CFG_DOT11_MODE_11B: + nwType = eSIR_11B_NW_TYPE; + break; + case eCSR_CFG_DOT11_MODE_11A: + nwType = eSIR_11A_NW_TYPE; + break; + default: + case eCSR_CFG_DOT11_MODE_11N: + case eCSR_CFG_DOT11_MODE_TAURUS: + //Because LIM only verifies it against 11a, 11b or 11g, set only 11g or 11a here + if(eCSR_BAND_24 == eBand) + { + nwType = eSIR_11G_NW_TYPE; + } + else + { + nwType = eSIR_11A_NW_TYPE; + } + break; + } + + pParam->extendedRateSet.numRates = 0; + + switch ( nwType ) + { + default: + smsLog(pMac, LOGE, FL("sees an unknown pSirNwType (%d)"), nwType); + case eSIR_11A_NW_TYPE: + + pParam->operationalRateSet.numRates = 8; + + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_6 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_12 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->operationalRateSet.rate[4] = SIR_MAC_RATE_24 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->operationalRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->operationalRateSet.rate[7] = SIR_MAC_RATE_54; + + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber50( pMac ); + if( 0 == channel && + CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) && + CSR_IS_PHY_MODE_DUAL_BAND(pMac->roam.configParam.phyMode) + ) + { + //We could not find a 5G channel by auto pick, let's try 2.4G channels + //We only do this here because csrRoamGetPhyModeBandForBss always picks 11a for AUTO + nwType = eSIR_11B_NW_TYPE; + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + } + } + else + { + channel = operationChannel; + } + break; + + case eSIR_11B_NW_TYPE: + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + } + else + { + channel = operationChannel; + } + + break; + case eSIR_11G_NW_TYPE: + /* For P2P Client and P2P GO, disable 11b rates */ + if( (pProfile->csrPersona == VOS_P2P_CLIENT_MODE) || + (pProfile->csrPersona == VOS_P2P_GO_MODE) || + (eCSR_CFG_DOT11_MODE_11G_ONLY == cfgDot11Mode) + ) + { + pParam->operationalRateSet.numRates = 8; + + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_6 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_12 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->operationalRateSet.rate[4] = SIR_MAC_RATE_24 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->operationalRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->operationalRateSet.rate[7] = SIR_MAC_RATE_54; + } + else + { + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + + pParam->extendedRateSet.numRates = 8; + pParam->extendedRateSet.rate[0] = SIR_MAC_RATE_6; + pParam->extendedRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->extendedRateSet.rate[2] = SIR_MAC_RATE_12; + pParam->extendedRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->extendedRateSet.rate[4] = SIR_MAC_RATE_24; + pParam->extendedRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->extendedRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->extendedRateSet.rate[7] = SIR_MAC_RATE_54; + } + + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + } + else + { + channel = operationChannel; + } + + break; + } + pParam->operationChn = channel; + pParam->sirNwType = nwType; +} + +static void csrRoamGetBssStartParmsFromBssDesc( tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes, tCsrRoamStartBssParams *pParam ) +{ + + if( pParam ) + { + pParam->sirNwType = pBssDesc->nwType; + pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED; + pParam->operationChn = pBssDesc->channelId; + vos_mem_copy(&pParam->bssid, pBssDesc->bssId, sizeof(tCsrBssid)); + + if( pIes ) + { + if(pIes->SuppRates.present) + { + pParam->operationalRateSet.numRates = pIes->SuppRates.num_rates; + if(pIes->SuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) + { + smsLog(pMac, LOGE, FL("num_rates :%d is more than SIR_MAC_RATESET_EID_MAX, resetting to SIR_MAC_RATESET_EID_MAX"), + pIes->SuppRates.num_rates); + pIes->SuppRates.num_rates = SIR_MAC_RATESET_EID_MAX; + } + vos_mem_copy(pParam->operationalRateSet.rate, pIes->SuppRates.rates, + sizeof(*pIes->SuppRates.rates) * pIes->SuppRates.num_rates); + } + if (pIes->ExtSuppRates.present) + { + pParam->extendedRateSet.numRates = pIes->ExtSuppRates.num_rates; + if(pIes->ExtSuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) + { + smsLog(pMac, LOGE, FL("num_rates :%d is more than \ + SIR_MAC_RATESET_EID_MAX, resetting to \ + SIR_MAC_RATESET_EID_MAX"), + pIes->ExtSuppRates.num_rates); + pIes->ExtSuppRates.num_rates = SIR_MAC_RATESET_EID_MAX; + } + vos_mem_copy(pParam->extendedRateSet.rate, + pIes->ExtSuppRates.rates, + sizeof(*pIes->ExtSuppRates.rates) * pIes->ExtSuppRates.num_rates); + } + if( pIes->SSID.present ) + { + pParam->ssId.length = pIes->SSID.num_ssid; + vos_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid, + pParam->ssId.length); + } + pParam->cbMode = csrGetCBModeFromIes(pMac, pParam->operationChn, pIes); + } + else + { + pParam->ssId.length = 0; + pParam->operationalRateSet.numRates = 0; + } + } +} + +static void csrRoamDetermineMaxRateForAdHoc( tpAniSirGlobal pMac, tSirMacRateSet *pSirRateSet ) +{ + tANI_U8 MaxRate = 0; + tANI_U32 i; + tANI_U8 *pRate; + + pRate = pSirRateSet->rate; + for ( i = 0; i < pSirRateSet->numRates; i++ ) + { + MaxRate = CSR_MAX( MaxRate, ( pRate[ i ] & (~CSR_DOT11_BASIC_RATE_MASK) ) ); + } + + // Save the max rate in the connected state information... + + // modify LastRates variable as well + + return; +} + +eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamStartBssParams *pParam, + tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrBand eBand; + // Set the roaming substate to 'Start BSS attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + //Need to figure out whether we need to log WDS??? + if( CSR_IS_IBSS( pProfile ) ) + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + if(pBssDesc) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_JOIN_IBSS_REQ; + vos_mem_copy(pIbssLog->bssid, pBssDesc->bssId, 6); + } + else + { + pIbssLog->eventId = WLAN_IBSS_EVENT_START_IBSS_REQ; + } + vos_mem_copy(pIbssLog->ssid, pParam->ssId.ssId, pParam->ssId.length); + if(pProfile->ChannelInfo.numOfChannels == 0) + { + pIbssLog->channelSetting = AUTO_PICK; + } + else + { + pIbssLog->channelSetting = SPECIFIED; + } + pIbssLog->operatingChannel = pParam->operationChn; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + //Put RSN information in for Starting BSS + pParam->nRSNIELength = (tANI_U16)pProfile->nRSNReqIELength; + pParam->pRSNIE = pProfile->pRSNReqIE; + + pParam->privacy = pProfile->privacy; + pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq; + pParam->authType = pProfile->csr80211AuthType; + pParam->beaconInterval = pProfile->beaconInterval; + pParam->dtimPeriod = pProfile->dtimPeriod; + pParam->ApUapsdEnable = pProfile->ApUapsdEnable; + pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden; + if (CSR_IS_INFRA_AP(pProfile)&& (pParam->operationChn != 0)) + { + if (csrIsValidChannel(pMac, pParam->operationChn) != VOS_STATUS_SUCCESS) + { + pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL; + } + } + pParam->protEnabled = pProfile->protEnabled; + pParam->obssProtEnabled = pProfile->obssProtEnabled; + pParam->ht_protection = pProfile->cfg_protection; + pParam->wps_state = pProfile->wps_state; + + pParam->uCfgDot11Mode = csrRoamGetPhyModeBandForBss(pMac, pProfile, pParam->operationChn /* pProfile->operationChannel*/, + &eBand); + pParam->bssPersona = pProfile->csrPersona; + +#ifdef WLAN_FEATURE_11W + pParam->mfpCapable = (0 != pProfile->MFPCapable); + pParam->mfpRequired = (0 != pProfile->MFPRequired); +#endif + + pParam->addIeParams.probeRespDataLen = + pProfile->addIeParams.probeRespDataLen; + pParam->addIeParams.probeRespData_buff = + pProfile->addIeParams.probeRespData_buff; + + pParam->addIeParams.assocRespDataLen = + pProfile->addIeParams.assocRespDataLen; + pParam->addIeParams.assocRespData_buff = + pProfile->addIeParams.assocRespData_buff; + + if (CSR_IS_IBSS( pProfile )) + { + pParam->addIeParams.probeRespBCNDataLen = + pProfile->nWPAReqIELength; + pParam->addIeParams.probeRespBCNData_buff = + pProfile->pWPAReqIE; + } + else + { + pParam->addIeParams.probeRespBCNDataLen = + pProfile->addIeParams.probeRespBCNDataLen; + pParam->addIeParams.probeRespBCNData_buff = + pProfile->addIeParams.probeRespBCNData_buff; + } + pParam->sap_dot11mc = pProfile->sap_dot11mc; + // When starting an IBSS, start on the channel from the Profile. + status = csrSendMBStartBssReqMsg( pMac, sessionId, pProfile->BSSType, pParam, pBssDesc ); + return (status); +} + +static void csrRoamPrepareBssParams(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, tDot11fBeaconIEs *pIes) +{ + tANI_U8 Channel; + ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if( pBssDesc ) + { + csrRoamGetBssStartParmsFromBssDesc( pMac, pBssDesc, pIes, &pSession->bssParams ); + //Since csrRoamGetBssStartParmsFromBssDesc fills in the bssid for pSession->bssParams + //The following code has to be do after that. + //For WDS station, use selfMac as the self BSSID + if( CSR_IS_WDS_STA( pProfile ) ) + { + vos_mem_copy(&pSession->bssParams.bssid, &pSession->selfMacAddr, + sizeof(tCsrBssid)); + } + } + else + { + csrRoamGetBssStartParms(pMac, pProfile, &pSession->bssParams); + //Use the first SSID + if(pProfile->SSIDs.numOfSSIDs) + { + vos_mem_copy(&pSession->bssParams.ssId, pProfile->SSIDs.SSIDList, + sizeof(tSirMacSSid)); + } + //For WDS station, use selfMac as the self BSSID + if( CSR_IS_WDS_STA( pProfile ) ) + { + vos_mem_copy(&pSession->bssParams.bssid, &pSession->selfMacAddr, + sizeof(tCsrBssid)); + } + //Use the first BSSID + else if( pProfile->BSSIDs.numOfBSSIDs ) + { + vos_mem_copy(&pSession->bssParams.bssid, pProfile->BSSIDs.bssid, + sizeof(tCsrBssid)); + } + else + { + vos_mem_set(&pSession->bssParams.bssid, sizeof(tCsrBssid), 0); + } + } + Channel = pSession->bssParams.operationChn; + //Set operating channel in pProfile which will be used + //in csrRoamSetBssConfigCfg() to determine channel bonding + //mode and will be configured in CFG later + pProfile->operationChannel = Channel; + + if(Channel == 0) + { + smsLog(pMac, LOGE, " CSR cannot find a channel to start IBSS"); + } + else + { + + csrRoamDetermineMaxRateForAdHoc( pMac, &pSession->bssParams.operationalRateSet ); + if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS( pProfile ) ) + { + if(CSR_IS_CHANNEL_24GHZ(Channel) ) + { + cbMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + cbMode = pMac->roam.configParam.channelBondingMode5GHz; + } + smsLog(pMac, LOG1, "## cbMode %d", cbMode); + pBssConfig->cbMode = cbMode; + pSession->bssParams.cbMode = cbMode; + } + } +} + +static eHalStatus csrRoamStartIbss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tANI_BOOLEAN *pfSameIbss ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fSameIbss = FALSE; + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + // Check if any profile parameter has changed ? If any profile parameter + // has changed then stop old BSS and start a new one with new parameters + if ( csrIsSameProfile( pMac, &pMac->roam.roamSession[sessionId].connectedProfile, pProfile ) ) + { + fSameIbss = TRUE; + } + else + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + } + else if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + // Disassociate from the connected Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + tBssConfigParam *pBssConfig; + + pBssConfig = vos_mem_malloc(sizeof(tBssConfigParam)); + if ( NULL == pBssConfig ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pBssConfig, sizeof(tBssConfigParam), 0); + // there is no Bss description before we start an IBSS so we need to adopt + // all Bss configuration parameters from the Profile. + status = csrRoamPrepareBssConfigFromProfile(pMac, pProfile, pBssConfig, NULL); + if(HAL_STATUS_SUCCESS(status)) + { + //save dotMode + pMac->roam.roamSession[sessionId].bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode; + //Prepare some more parameters for this IBSS + csrRoamPrepareBssParams(pMac, sessionId, pProfile, NULL, pBssConfig, NULL); + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + NULL, pBssConfig, + NULL, eANI_BOOLEAN_FALSE); + } + + vos_mem_free(pBssConfig); + }//Allocate memory + } + + if(pfSameIbss) + { + *pfSameIbss = fSameIbss; + } + return( status ); +} + +static void csrRoamUpdateConnectedProfileFromNewBss( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirSmeNewBssInfo *pNewBss ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if( pNewBss ) + { + // Set the operating channel. + pSession->connectedProfile.operationChannel = pNewBss->channelNumber; + // move the BSSId from the BSS description into the connected state information. + vos_mem_copy(&pSession->connectedProfile.bssid, &(pNewBss->bssId), + sizeof( tCsrBssid )); + } + return; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrRoamSetPSK_PMK(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 *pPSK_PMK, size_t pmk_len) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pSession->psk_pmk, pPSK_PMK, sizeof(pSession->psk_pmk)); + pSession->pmk_len = pmk_len; + return eHAL_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_ROAM_OFFLOAD */ +eHalStatus csrRoamSetPMKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrRoamSetPMKIDCache called, numItems = %d", numItems); + + if (numItems <= CSR_MAX_PMKID_ALLOWED) + { +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&secEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid, 6); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//FEATURE_WLAN_DIAG_SUPPORT_CSR + + status = eHAL_STATUS_SUCCESS; + if (update_entire_cache) { + pSession->NumPmkidCache = (tANI_U16)numItems; + if (numItems && pPMKIDCache) + { + vos_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache, + sizeof(tPmkidCacheInfo) * numItems); + } + } else { + tANI_U32 i = 0, j = 0; + tANI_U8 BSSIDMatched = 0; + tPmkidCacheInfo *pmksa; + + for (i = 0; i < numItems; i++) { + pmksa = &pPMKIDCache[i]; + for (j = 0; j < CSR_MAX_PMKID_ALLOWED; j++) { + if (vos_mem_compare(pSession->PmkidCacheInfo[j].BSSID, + pmksa->BSSID, VOS_MAC_ADDR_SIZE)) { + /* If a matching BSSID found, update it */ + BSSIDMatched = 1; + vos_mem_copy(pSession->PmkidCacheInfo[j].PMKID, + pmksa->PMKID, CSR_RSN_PMKID_SIZE); + break; + } + } + + if (!BSSIDMatched) { + vos_mem_copy( + pSession->PmkidCacheInfo[pSession->NumPmkidCache].BSSID, + pmksa->BSSID, ETHER_ADDR_LEN); + vos_mem_copy( + pSession->PmkidCacheInfo[pSession->NumPmkidCache].PMKID, + pmksa->PMKID, CSR_RSN_PMKID_SIZE); + /* Increment the CSR local cache index */ + if (pSession->NumPmkidCache < (CSR_MAX_PMKID_ALLOWED - 1)) + pSession->NumPmkidCache++; + else + pSession->NumPmkidCache = 0; + } + BSSIDMatched = 0; + } + } + } + return (status); +} + +eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 *pBSSId, + tANI_BOOLEAN flush_cache ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_BOOLEAN fMatchFound = FALSE; + tANI_U32 Index; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + /* Check if there are no entries to delete */ + if (0 == pSession->NumPmkidCache) { + smsLog(pMac, LOG1, FL("No entries to delete/Flush")); + return eHAL_STATUS_SUCCESS; + } + + if (!flush_cache) { + for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) { + if (vos_mem_compare(pSession->PmkidCacheInfo[Index].BSSID, + pBSSId, VOS_MAC_ADDR_SIZE)) { + fMatchFound = 1; + + /* Clear this - the matched entry */ + vos_mem_zero(&pSession->PmkidCacheInfo[Index], + sizeof(tPmkidCacheInfo)); + + status = eHAL_STATUS_SUCCESS; + break; + } + } + + if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) { + smsLog(pMac, LOG1, FL("No such PMKSA entry exists "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pBSSId)); + return status; + } + + return status; + } else { + /* Flush the entire cache */ + vos_mem_zero(pSession->PmkidCacheInfo, + sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED); + pSession->NumPmkidCache = 0; + return eHAL_STATUS_SUCCESS; + } +} + +tANI_U32 csrRoamGetNumPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (pMac->roam.roamSession[sessionId].NumPmkidCache); +} + +eHalStatus csrRoamGetPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pNum && pPmkidCache) + { + if(pSession->NumPmkidCache == 0) + { + *pNum = 0; + status = eHAL_STATUS_SUCCESS; + } + else if(*pNum >= pSession->NumPmkidCache) + { + if(pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) + { + smsLog(pMac, LOGE, FL("NumPmkidCache :%d is more than CSR_MAX_PMKID_ALLOWED, resetting to CSR_MAX_PMKID_ALLOWED"), + pSession->NumPmkidCache); + pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED; + } + vos_mem_copy(pPmkidCache, pSession->PmkidCacheInfo, + sizeof(tPmkidCacheInfo) * pSession->NumPmkidCache); + *pNum = pSession->NumPmkidCache; + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} + +eHalStatus csrRoamGetWpaRsnReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWpaRsnReqIeLength; + if(pBuf) + { + if(len >= pSession->nWpaRsnReqIeLength) + { + vos_mem_copy(pBuf, pSession->pWpaRsnReqIE, + pSession->nWpaRsnReqIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} + +eHalStatus csrRoamGetWpaRsnRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWpaRsnRspIeLength; + if(pBuf) + { + if(len >= pSession->nWpaRsnRspIeLength) + { + vos_mem_copy(pBuf, pSession->pWpaRsnRspIE, + pSession->nWpaRsnRspIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrRoamGetWapiReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWapiReqIeLength; + if(pBuf) + { + if(len >= pSession->nWapiReqIeLength) + { + vos_mem_copy(pBuf, pSession->pWapiReqIE, + pSession->nWapiReqIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +eHalStatus csrRoamGetWapiRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWapiRspIeLength; + if(pBuf) + { + if(len >= pSession->nWapiRspIeLength) + { + vos_mem_copy(pBuf, pSession->pWapiRspIE, + pSession->nWapiRspIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ +eRoamCmdStatus csrGetRoamCompleteStatus(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eRoamCmdStatus retStatus = eCSR_ROAM_CONNECT_COMPLETION; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (retStatus); + } + + if(CSR_IS_ROAMING(pSession)) + { + retStatus = eCSR_ROAM_ROAMING_COMPLETION; + pSession->fRoaming = eANI_BOOLEAN_FALSE; + } + return (retStatus); +} + +//This function remove the connected BSS from te cached scan result +eHalStatus csrRoamRemoveConnectedBssFromScanCache(tpAniSirGlobal pMac, + tCsrRoamConnectedProfile *pConnProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrScanResultFilter *pScanFilter = NULL; + tListElem *pEntry; + tCsrScanResult *pResult; + tDot11fBeaconIEs *pIes; + tANI_BOOLEAN fMatch; + if(!(csrIsMacAddressZero(pMac, &pConnProfile->bssid) || + csrIsMacAddressBroadcast(pMac, &pConnProfile->bssid))) + { + do + { + //Prepare the filter. Only fill in the necessary fields. Not all fields are needed + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tCsrBssid)); + if ( NULL == pScanFilter->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + vos_mem_copy(pScanFilter->BSSIDs.bssid, &pConnProfile->bssid, + sizeof(tCsrBssid)); + pScanFilter->BSSIDs.numOfBSSIDs = 1; + if(!csrIsNULLSSID(pConnProfile->SSID.ssId, pConnProfile->SSID.length)) + { + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pScanFilter->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_copy(&pScanFilter->SSIDs.SSIDList[0].SSID, + &pConnProfile->SSID, sizeof(tSirMacSSid)); + } + pScanFilter->authType.numEntries = 1; + pScanFilter->authType.authType[0] = pConnProfile->AuthType; + pScanFilter->BSSType = pConnProfile->BSSType; + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = pConnProfile->EncryptionType; + pScanFilter->mcEncryptionType.numEntries = 1; + pScanFilter->mcEncryptionType.encryptionType[0] = pConnProfile->mcEncryptionType; + //We ignore the channel for now, BSSID should be enough + pScanFilter->ChannelInfo.numOfChannels = 0; + //Also ignore the following fields + pScanFilter->uapsd_mask = 0; + pScanFilter->bWPSAssociation = eANI_BOOLEAN_FALSE; + pScanFilter->bOSENAssociation = eANI_BOOLEAN_FALSE; + pScanFilter->countryCode[0] = 0; + pScanFilter->phyMode = eCSR_DOT11_MODE_TAURUS; + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pResult->Result.pvIes ); + fMatch = csrMatchBSS(pMac, &pResult->Result.BssDescriptor, + pScanFilter, NULL, NULL, NULL, &pIes); + //Release the IEs allocated by csrMatchBSS is needed + if( !pResult->Result.pvIes ) + { + //need to free the IEs since it is allocated by csrMatchBSS + vos_mem_free(pIes); + } + if(fMatch) + { + //We found the one + if( csrLLRemoveEntry(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK) ) + { + //Free the memory + csrFreeScanResultEntry( pMac, pResult ); + } + break; + } + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + }//while + csrLLUnlock(&pMac->scan.scanResultList); + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + } + return (status); +} + +//BT-AMP +eHalStatus csrIsBTAMPAllowed( tpAniSirGlobal pMac, tANI_U32 chnId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId; + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if( csrIsConnStateIbss( pMac, sessionId ) || csrIsBTAMP( pMac, sessionId ) ) + { + //co-exist with IBSS or BT-AMP is not supported + smsLog( pMac, LOGW, " BTAMP is not allowed due to IBSS/BT-AMP exist in session %d", sessionId ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + if( csrIsConnStateInfra( pMac, sessionId ) ) + { + if( chnId && + ( (tANI_U8)chnId != pMac->roam.roamSession[sessionId].connectedProfile.operationChannel ) ) + { + smsLog( pMac, LOGW, " BTAMP is not allowed due to channel (%d) diff than infr channel (%d)", + chnId, pMac->roam.roamSession[sessionId].connectedProfile.operationChannel ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + } + } + } + return ( status ); +} + +static eHalStatus csrRoamStartWds( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tBssConfigParam bssConfig; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + else if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + // Disassociate from the connected Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + //We don't expect Bt-AMP HDD not to disconnect the last connection first at this time. + //Otherwise we need to add code to handle the + //situation just like IBSS. Though for WDS station, we need to send disassoc to PE first then + //send stop_bss to PE, before we can continue. + + if (csrIsConnStateWds( pMac, sessionId )) + { + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(&bssConfig, sizeof(tBssConfigParam), 0); + /* Assume HDD provide bssid in profile */ + vos_mem_copy(&pSession->bssParams.bssid, pProfile->BSSIDs.bssid[0], + sizeof(tCsrBssid)); + // there is no Bss description before we start an WDS so we need + // to adopt all Bss configuration parameters from the Profile. + status = csrRoamPrepareBssConfigFromProfile(pMac, pProfile, &bssConfig, pBssDesc); + if(HAL_STATUS_SUCCESS(status)) + { + //Save profile for late use + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if (pSession->pCurRoamProfile != NULL ) + { + vos_mem_set(pSession->pCurRoamProfile, + sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + //Prepare some more parameters for this WDS + csrRoamPrepareBssParams(pMac, sessionId, pProfile, NULL, &bssConfig, NULL); + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + NULL, &bssConfig, + NULL, eANI_BOOLEAN_FALSE); + } + } + + return( status ); +} + +////////////////////Mail box + +//pBuf is caller allocated memory point to &(tSirSmeJoinReq->rsnIE.rsnIEdata[ 0 ]) + pMsg->rsnIE.length; +//or &(tSirSmeReassocReq->rsnIE.rsnIEdata[ 0 ]) + pMsg->rsnIE.length; +static void csrPrepareJoinReassocReqBuffer( tpAniSirGlobal pMac, + tSirBssDescription *pBssDescription, + tANI_U8 *pBuf, tANI_U8 uapsdMask) +{ + tCsrChannelSet channelGroup; + tSirMacCapabilityInfo *pAP_capabilityInfo; + tAniBool fTmp; + tANI_BOOLEAN found = FALSE; + tANI_U32 size = 0; + tANI_S8 pwrLimit = 0; + tANI_U16 i; + // plug in neighborhood occupancy info (i.e. BSSes on primary or secondary channels) + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundPri + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundSecDown + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundSecUp + // 802.11h + //We can do this because it is in HOST CPU order for now. + pAP_capabilityInfo = (tSirMacCapabilityInfo *)&pBssDescription->capabilityInfo; + //tell the target AP my 11H capability only if both AP and STA support 11H and the channel being used is 11a + if ( csrIs11hSupported( pMac ) && pAP_capabilityInfo->spectrumMgt && eSIR_11A_NW_TYPE == pBssDescription->nwType ) + { + fTmp = (tAniBool)pal_cpu_to_be32(1); + } + else + fTmp = (tAniBool)0; + + // corresponds to --- pMsg->spectrumMgtIndicator = ON; + vos_mem_copy(pBuf, (tANI_U8 *)&fTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + *pBuf++ = MIN_TX_PWR_CAP; // it is for pMsg->powerCap.minTxPower = 0; + found = csrSearchChannelListForTxPower(pMac, pBssDescription, &channelGroup); + // This is required for 11k test VoWiFi Ent: Test 2. + // We need the power capabilities for Assoc Req. + // This macro is provided by the halPhyCfg.h. We pick our + // max and min capability by the halPhy provided macros + pwrLimit = csrGetCfgMaxTxPower (pMac, pBssDescription->channelId); + if (0 != pwrLimit) + { + *pBuf++ = pwrLimit; + } + else + { + *pBuf++ = MAX_TX_PWR_CAP; + } + size = sizeof(pMac->roam.validChannelList); + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &size))) + { + *pBuf++ = (tANI_U8)size; //tSirSupChnl->numChnl + for ( i = 0; i < size; i++) + { + *pBuf++ = pMac->roam.validChannelList[ i ]; //tSirSupChnl->channelList[ i ] + + } + } + else + { + smsLog(pMac, LOGE, FL("can not find any valid channel")); + *pBuf++ = 0; //tSirSupChnl->numChnl + } + //Check whether it is ok to enter UAPSD +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( btcIsReadyForUapsd(pMac) ) +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + { + *pBuf++ = uapsdMask; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + else + { + smsLog(pMac, LOGE, FL(" BTC doesn't allow UAPSD for uapsd_mask(0x%X)"), uapsdMask); + *pBuf++ = 0; + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + + // move the entire BssDescription into the join request. + vos_mem_copy(pBuf, pBssDescription, + pBssDescription->length + sizeof( pBssDescription->length )); + pBuf += pBssDescription->length + sizeof( pBssDescription->length ); // update to new location +} + +/* + * The communication between HDD and LIM is thru mailbox (MB). + * Both sides will access the data structure "tSirSmeJoinReq". + * The rule is, while the components of "tSirSmeJoinReq" can be accessed in the regular way like tSirSmeJoinReq.assocType, this guideline + * stops at component tSirRSNie; any acces to the components after tSirRSNie is forbidden because the space from tSirRSNie is quueezed + * with the component "tSirBssDescription". And since the size of actual 'tSirBssDescription' varies, the receiving side (which is the routine + * limJoinReqSerDes() of limSerDesUtils.cc) should keep in mind not to access the components DIRECTLY after tSirRSNie. + */ +eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, + tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeJoinReq *pMsg; + tANI_U8 *pBuf; + v_U8_t acm_mask = 0, uapsd_mask; + tANI_U16 msgLen, wTmp, ieLen; + tSirMacRateSet OpRateSet; + tSirMacRateSet ExRateSet; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U32 dwTmp; + tANI_U8 wpaRsnIE[DOT11F_IE_RSN_MAX_LEN]; //RSN MAX is bigger than WPA MAX + tANI_U32 ucDot11Mode = 0; + tANI_U8 txBFCsnValue = 0; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + /* To satisfy klockworks */ + if (NULL == pBssDescription) + { + smsLog(pMac, LOGE, FL(" pBssDescription is NULL")); + return eHAL_STATUS_FAILURE; + } + + do { + pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS; + pSession->joinFailStatusCode.reasonCode = 0; + memcpy (&pSession->joinFailStatusCode.bssId, &pBssDescription->bssId, sizeof(tSirMacAddr)); + // There are a number of variable length fields to consider. First, the tSirSmeJoinReq + // includes a single bssDescription. bssDescription includes a single tANI_U32 for the + // IE fields, but the length field in the bssDescription needs to be interpreted to + // determine length of the IE fields. + // + // So, take the size of the JoinReq, subtract the size of the bssDescription and + // add in the length from the bssDescription (then add the size of the 'length' field + // itself because that is NOT included in the length field). + msgLen = sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) + + pBssDescription->length + sizeof( pBssDescription->length ) + + sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 ); // add in the size of the WPA IE that we may build. + pMsg = vos_mem_malloc(msgLen); + if (NULL == pMsg) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, msgLen , 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)messageType); + pMsg->length = pal_cpu_to_be16(msgLen); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // ssId + if( pIes->SSID.present && pIes->SSID.num_ssid ) + { + // ssId len + *pBuf = pIes->SSID.num_ssid; + pBuf++; + vos_mem_copy(pBuf, pIes->SSID.ssid, pIes->SSID.num_ssid); + pBuf += pIes->SSID.num_ssid; + } + else + { + *pBuf = 0; + pBuf++; + } + // selfMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // bsstype + dwTmp = pal_cpu_to_be32( csrTranslateBsstypeToMacType( pProfile->BSSType ) ); + if (dwTmp == eSIR_BTAMP_STA_MODE) dwTmp = eSIR_BTAMP_AP_MODE; // Override BssType for BTAMP + vos_mem_copy(pBuf, &dwTmp, sizeof(tSirBssType)); + pBuf += sizeof(tSirBssType); + // dot11mode + ucDot11Mode = csrTranslateToWNICfgDot11Mode( pMac, pSession->bssParams.uCfgDot11Mode ); + if (pBssDescription->channelId <= 14 && + FALSE == pMac->roam.configParam.enableVhtFor24GHz && + WNI_CFG_DOT11_MODE_11AC == ucDot11Mode) + { + //Need to disable VHT operation in 2.4 GHz band + ucDot11Mode = WNI_CFG_DOT11_MODE_11N; + } + *pBuf = (tANI_U8)ucDot11Mode; + pBuf++; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + *pBuf = pMac->roam.configParam.cc_switch_mode; + pBuf += 1; +#endif + //Persona + *pBuf = (tANI_U8)pProfile->csrPersona; + pBuf++; + //CBMode + *pBuf = (tANI_U8)pSession->bssParams.cbMode; + pBuf++; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("CSR PERSONA=%d CSR CbMode %d"), pProfile->csrPersona, pSession->bssParams.cbMode); + + // uapsdPerAcBitmask + *pBuf = pProfile->uapsd_mask; + pBuf++; + + + + status = csrGetRateSet(pMac, pProfile, (eCsrPhyMode)pProfile->phyMode, pBssDescription, pIes, &OpRateSet, &ExRateSet); + if (HAL_STATUS_SUCCESS(status) ) + { + // OperationalRateSet + if (OpRateSet.numRates) { + *pBuf++ = OpRateSet.numRates; + vos_mem_copy(pBuf, OpRateSet.rate, OpRateSet.numRates); + pBuf += OpRateSet.numRates; + } else *pBuf++ = 0; + // ExtendedRateSet + if (ExRateSet.numRates) { + *pBuf++ = ExRateSet.numRates; + vos_mem_copy(pBuf, ExRateSet.rate, ExRateSet.numRates); + pBuf += ExRateSet.numRates; + } else *pBuf++ = 0; + } + else + { + *pBuf++ = 0; + *pBuf++ = 0; + } + // rsnIE + if ( csrIsProfileWpa( pProfile ) ) + { + // Insert the Wpa IE into the join request + ieLen = csrRetrieveWpaIe( pMac, pProfile, pBssDescription, pIes, + (tCsrWpaIe *)( wpaRsnIE ) ); + } + else if( csrIsProfileRSN( pProfile ) ) + { + // Insert the RSN IE into the join request + ieLen = csrRetrieveRsnIe( pMac, sessionId, pProfile, pBssDescription, pIes, + (tCsrRSNIe *)( wpaRsnIE ) ); + } +#ifdef FEATURE_WLAN_WAPI + else if( csrIsProfileWapi( pProfile ) ) + { + // Insert the WAPI IE into the join request + ieLen = csrRetrieveWapiIe( pMac, sessionId, pProfile, pBssDescription, pIes, + (tCsrWapiIe *)( wpaRsnIE ) ); + } +#endif /* FEATURE_WLAN_WAPI */ + else + { + ieLen = 0; + } + //remember the IE for future use + if( ieLen ) + { + if(ieLen > DOT11F_IE_RSN_MAX_LEN) + { + smsLog(pMac, LOGE, FL(" WPA RSN IE length :%d is more than DOT11F_IE_RSN_MAX_LEN, resetting to %d"), ieLen, DOT11F_IE_RSN_MAX_LEN); + ieLen = DOT11F_IE_RSN_MAX_LEN; + } +#ifdef FEATURE_WLAN_WAPI + if( csrIsProfileWapi( pProfile ) ) + { + //Check whether we need to allocate more memory + if(ieLen > pSession->nWapiReqIeLength) + { + if(pSession->pWapiReqIE && pSession->nWapiReqIeLength) + { + vos_mem_free(pSession->pWapiReqIE); + } + pSession->pWapiReqIE = vos_mem_malloc(ieLen); + if (NULL == pSession->pWapiReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nWapiReqIeLength = ieLen; + vos_mem_copy(pSession->pWapiReqIE, wpaRsnIE, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + else//should be WPA/WPA2 otherwise +#endif /* FEATURE_WLAN_WAPI */ + { + //Check whether we need to allocate more memory + if(ieLen > pSession->nWpaRsnReqIeLength) + { + if(pSession->pWpaRsnReqIE && pSession->nWpaRsnReqIeLength) + { + vos_mem_free(pSession->pWpaRsnReqIE); + } + pSession->pWpaRsnReqIE = vos_mem_malloc(ieLen); + if (NULL == pSession->pWpaRsnReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nWpaRsnReqIeLength = ieLen; + vos_mem_copy(pSession->pWpaRsnReqIE, wpaRsnIE, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + } + else + { + //free whatever old info + pSession->nWpaRsnReqIeLength = 0; + if(pSession->pWpaRsnReqIE) + { + vos_mem_free(pSession->pWpaRsnReqIE); + pSession->pWpaRsnReqIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + pSession->nWapiReqIeLength = 0; + if(pSession->pWapiReqIE) + { + vos_mem_free(pSession->pWapiReqIE); + pSession->pWapiReqIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } +#ifdef FEATURE_WLAN_ESE + if( eWNI_SME_JOIN_REQ == messageType ) + { + // Never include the cckmIE in an Join Request + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + else if(eWNI_SME_REASSOC_REQ == messageType ) + { + // cckmIE + if( csrIsProfileESE( pProfile ) ) + { + // Insert the CCKM IE into the join request +#ifdef FEATURE_WLAN_ESE_UPLOAD + ieLen = pSession->suppCckmIeInfo.cckmIeLen; + vos_mem_copy((void *) (wpaRsnIE), + pSession->suppCckmIeInfo.cckmIe, ieLen); +#else + ieLen = csrConstructEseCckmIe( pMac, + pSession, + pProfile, + pBssDescription, + pSession->pWpaRsnReqIE, + pSession->nWpaRsnReqIeLength, + (void *)( wpaRsnIE ) ); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + } + else + { + ieLen = 0; + } + //If present, copy the IE into the eWNI_SME_REASSOC_REQ message buffer + if( ieLen ) + { + //Copy the CCKM IE over from the temp buffer (wpaRsnIE) + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + else + { + //Indicate you have no CCKM IE + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + } +#endif /* FEATURE_WLAN_ESE */ + // addIEScan + if(pProfile->nAddIEScanLength && pProfile->pAddIEScan) + { + ieLen = pProfile->nAddIEScanLength; + if(ieLen > pSession->nAddIEScanLength) + { + if(pSession->pAddIEScan && pSession->nAddIEScanLength) + { + vos_mem_free(pSession->pAddIEScan); + } + pSession->pAddIEScan = vos_mem_malloc(ieLen); + if (NULL == pSession->pAddIEScan) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nAddIEScanLength = ieLen; + vos_mem_copy(pSession->pAddIEScan, pProfile->pAddIEScan, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, pProfile->pAddIEScan, ieLen); + pBuf += ieLen; + } + else + { + pSession->nAddIEScanLength = 0; + if(pSession->pAddIEScan) + { + vos_mem_free(pSession->pAddIEScan); + pSession->pAddIEScan = NULL; + } + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + // addIEAssoc + if(pProfile->nAddIEAssocLength && pProfile->pAddIEAssoc) + { + ieLen = pProfile->nAddIEAssocLength; + if(ieLen > pSession->nAddIEAssocLength) + { + if(pSession->pAddIEAssoc && pSession->nAddIEAssocLength) + { + vos_mem_free(pSession->pAddIEAssoc); + } + pSession->pAddIEAssoc = vos_mem_malloc(ieLen); + if (NULL == pSession->pAddIEAssoc) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nAddIEAssocLength = ieLen; + vos_mem_copy(pSession->pAddIEAssoc, pProfile->pAddIEAssoc, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, pProfile->pAddIEAssoc, ieLen); + pBuf += ieLen; + } + else + { + pSession->nAddIEAssocLength = 0; + if(pSession->pAddIEAssoc) + { + vos_mem_free(pSession->pAddIEAssoc); + pSession->pAddIEAssoc = NULL; + } + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + + if(eWNI_SME_REASSOC_REQ == messageType ) + { + //Unmask any AC in reassoc that is ACM-set + uapsd_mask = (v_U8_t)pProfile->uapsd_mask; + if( uapsd_mask && ( NULL != pBssDescription ) ) + { + if( CSR_IS_QOS_BSS(pIes) && CSR_IS_UAPSD_BSS(pIes) ) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, pBssDescription, pIes); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + else + { + uapsd_mask = 0; + } + } + } + + dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedUCEncryptionType) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + + dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedMCEncryptionType) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); +#ifdef WLAN_FEATURE_11W + //MgmtEncryption + if (pProfile->MFPEnabled) + { + dwTmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC); + } + else + { + dwTmp = pal_cpu_to_be32(eSIR_ED_NONE); + } + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + pProfile->MDID.mdiePresent = pBssDescription->mdiePresent; + if (csrIsProfile11r( pProfile ) +#ifdef FEATURE_WLAN_ESE + && !((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) && + (pIes->ESEVersion.present) && (pMac->roam.configParam.isEseIniFeatureEnabled)) +#endif + ) + { + // is11Rconnection; + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)) ; + pBuf += sizeof(tAniBool); + } + else + { + // is11Rconnection; + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_ESE + + // isESEFeatureIniEnabled + if (TRUE == pMac->roam.configParam.isEseIniFeatureEnabled) + { + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + /* A profile can not be both ESE and 11R. But an 802.11R AP + * may be advertising support for ESE as well. So if we are + * associating Open or explicitly ESE then we will get ESE. + * If we are associating explictly 11R only then we will get + * 11R. + */ + if ((csrIsProfileESE(pProfile) || + ((pIes->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + // isESEconnection; + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + //isESEconnection; + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + if (eWNI_SME_JOIN_REQ == messageType) + { + tESETspecInfo eseTspec; + // ESE-Tspec IEs in the ASSOC request is presently not supported + // so nullify the TSPEC parameters + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(pBuf, &eseTspec, sizeof(tESETspecInfo)); + pBuf += sizeof(tESETspecInfo); + } + else if (eWNI_SME_REASSOC_REQ == messageType) + { + if ((csrIsProfileESE(pProfile) || + ((pIes->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + tESETspecInfo eseTspec; + // ESE Tspec information + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + eseTspec.numTspecs = sme_QosEseRetrieveTspecInfo(pMac, sessionId, (tTspecInfo *) &eseTspec.tspec[0]); + *pBuf = eseTspec.numTspecs; + pBuf += sizeof(tANI_U8); + // Copy the TSPEC information only if present + if (eseTspec.numTspecs) { + vos_mem_copy(pBuf, (void*)&eseTspec.tspec[0], + (eseTspec.numTspecs*sizeof(tTspecInfo))); + } + pBuf += sizeof(eseTspec.tspec); + } + else + { + tESETspecInfo eseTspec; + // ESE-Tspec IEs in the ASSOC request is presently not supported + // so nullify the TSPEC parameters + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(pBuf, &eseTspec, sizeof(tESETspecInfo)); + pBuf += sizeof(tESETspecInfo); + } + } +#endif // FEATURE_WLAN_ESE +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + // Fill in isFastTransitionEnabled + if (pMac->roam.configParam.isFastTransitionEnabled +#ifdef FEATURE_WLAN_LFR + || csrRoamIsFastRoamEnabled(pMac, sessionId) +#endif + ) + { + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_LFR + if(csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + //legacy fast roaming enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif + + // txLdpcIniFeatureEnabled + *pBuf = (tANI_U8)pMac->roam.configParam.txLdpcEnable; + pBuf++; + + if ((csrIs11hSupported (pMac)) && (CSR_IS_CHANNEL_5GHZ(pBssDescription->channelId)) && + (pIes->Country.present) && (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + csrSaveToChannelPower2G_5G( pMac, pIes->Country.num_triplets * sizeof(tSirMacChanInfo), + (tSirMacChanInfo *)(&pIes->Country.triplets[0]) ); + csrApplyPower2Current(pMac); + } + + //HT Config + vos_mem_copy(pBuf, &pSession->htConfig, + sizeof(tSirHTConfig)); + pBuf += sizeof(tSirHTConfig); +#ifdef WLAN_FEATURE_11AC + // txBFIniFeatureEnabled + *pBuf = (tANI_U8)pMac->roam.configParam.txBFEnable; + pBuf++; + + // txBFCsnValue + if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) && + pMac->roam.configParam.txBFEnable) { + txBFCsnValue = (tANI_U8)pMac->roam.configParam.txBFCsnValue; + if (pIes->VHTCaps.numSoundingDim) + txBFCsnValue = MIN(txBFCsnValue, + pIes->VHTCaps.numSoundingDim); + } + *pBuf = txBFCsnValue; + pBuf++; + + // txMuBformee + *pBuf = (tANI_U8)pMac->roam.configParam.txMuBformee; + pBuf++; + + // enableVhtpAid + *pBuf = (tANI_U8)pMac->roam.configParam.enableVhtpAid; + pBuf++; + + // enableVhtGid + *pBuf = (tANI_U8)pMac->roam.configParam.enableVhtGid; + pBuf++; + +#endif + // enableAmpduPs + *pBuf = (tANI_U8)pMac->roam.configParam.enableAmpduPs; + pBuf++; + + // enableHtSmps + *pBuf = (tANI_U8)pMac->roam.configParam.enableHtSmps; + pBuf++; + + // htSmps + *pBuf = (tANI_U8)pMac->roam.configParam.htSmps; + pBuf++; + + *pBuf = (tANI_U8)pMac->roam.configParam.isAmsduSupportInAMPDU; + pBuf++; + + // WME + if(pMac->roam.roamSession[sessionId].fWMMConnection) + { + //WME enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + // QOS + if(pMac->roam.roamSession[sessionId].fQOSConnection) + { + //QOS enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + // OSEN + if(pProfile->bOSENAssociation) + { + //OSEN connection + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + //BssDesc + csrPrepareJoinReassocReqBuffer( pMac, pBssDescription, pBuf, + (tANI_U8)pProfile->uapsd_mask); + + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + else + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if (eWNI_SME_JOIN_REQ == messageType) + { + //Tush-QoS: notify QoS module that join happening + pSession->join_bssid_count++; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "BSSID Count = %d", pSession->join_bssid_count); + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_JOIN_REQ, NULL); + } + else if (eWNI_SME_REASSOC_REQ == messageType) + { + //Tush-QoS: notify QoS module that reassoc happening + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_REASSOC_REQ, NULL); + } +#endif + } + } while( 0 ); + return( status ); +} + +// +eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDisassocReq *pMsg; + tANI_U8 *pBuf; + tANI_U16 wTmp; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + return eHAL_STATUS_FAILURE; + do { + pMsg = vos_mem_malloc(sizeof(tSirSmeDisassocReq)); + if (NULL == pMsg) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDisassocReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DISASSOC_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDisassocReq )); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf++ = (tANI_U8)sessionId; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + + if ( (pSession->pCurRoamProfile != NULL) && + ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile)) || + (CSR_IS_WDS_AP(pSession->pCurRoamProfile))) ) + { + // Set the bssid address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, pSession->selfMacAddr, + sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + // Set the peer MAC address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( tSirMacAddr )); + //perMacAddr is passed as bssId for softAP + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + } + else + { + // Set the peer MAC address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( pMsg->bssId )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + // reasonCode + wTmp = pal_cpu_to_be16(reasonCode); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + pBuf += sizeof(tANI_U16); + /* The state will be DISASSOC_HANDOFF only when we are doing handoff. + Here we should not send the disassoc over the air to the AP */ + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) +#ifdef WLAN_FEATURE_VOWIFI_11R + && csrRoamIs11rAssoc(pMac, sessionId) +#endif + ) + { + *pBuf = CSR_DONT_SEND_DISASSOC_OVER_THE_AIR; /* Set DoNotSendOverTheAir flag to 1 only for handoff case */ + } + pBuf += sizeof(tANI_U8); + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus csrSendMBTkipCounterMeasuresReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN bEnable, tSirMacAddr bssId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeTkipCntrMeasReq *pMsg; + tANI_U8 *pBuf; + do + { + pMsg = vos_mem_malloc(sizeof( tSirSmeTkipCntrMeasReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeTkipCntrMeasReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_TKIP_CNTR_MEAS_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeTkipCntrMeasReq )); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf++ = (tANI_U8)sessionId; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // bssid + vos_mem_copy(pMsg->bssId, bssId, sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + // bEnable + *pBuf = (tANI_BOOLEAN)bEnable; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus +csrSendMBGetAssociatedStasReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + VOS_MODULE_ID modId, tSirMacAddr bssId, + void *pUsrContext, void *pfnSapEventCallback, + tANI_U8 *pAssocStasBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeGetAssocSTAsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + tANI_U32 dwTmp; + do + { + pMsg = vos_mem_malloc(sizeof( tSirSmeGetAssocSTAsReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pMsg, sizeof( tSirSmeGetAssocSTAsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_ASSOC_STAS_REQ); + pBuf = (tANI_U8 *)&pMsg->bssId; + wTmpBuf = pBuf; + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // modId + dwTmp = pal_cpu_to_be16((tANI_U16)modId); + vos_mem_copy(pBuf, (tANI_U8 *)&dwTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + // pUsrContext + vos_mem_copy(pBuf, (tANI_U8 *)pUsrContext, sizeof(void *)); + pBuf += sizeof(void*); + // pfnSapEventCallback + vos_mem_copy(pBuf, (tANI_U8 *)pfnSapEventCallback, sizeof(void*)); + pBuf += sizeof(void*); + // pAssocStasBuf + vos_mem_copy(pBuf, pAssocStasBuf, sizeof(void*)); + pBuf += sizeof(void*); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)));//msg_header + msg + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); + } +eHalStatus +csrSendMBGetWPSPBCSessions( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr bssId, void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac) + { + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeGetWPSPBCSessionsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + + do + { + pMsg = vos_mem_malloc(sizeof(tSirSmeGetWPSPBCSessionsReq)); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pMsg, sizeof( tSirSmeGetWPSPBCSessionsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_WPSPBC_SESSION_REQ); + pBuf = (tANI_U8 *)&pMsg->pUsrContext; + + if( NULL == pBuf) + { + VOS_ASSERT(pBuf); + return eHAL_STATUS_FAILURE; + } + wTmpBuf = pBuf; + // pUsrContext + vos_mem_copy(pBuf, (tANI_U8 *)pUsrContext, sizeof(void*)); + pBuf += sizeof(void *); + // pSapEventCallback + vos_mem_copy(pBuf, (tANI_U8 *)pfnSapEventCallback, sizeof(void *)); + pBuf += sizeof(void *); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // MAC Address of STA in WPS session + vos_mem_copy((tSirMacAddr *)pBuf, pRemoveMac.bytes, sizeof(v_MACADDR_t)); + pBuf += sizeof(v_MACADDR_t); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)));//msg_header + msg + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus +csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpSirChangeBIParams pMsg; + tANI_U16 len = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + //NO need to update the Beacon Params if update beacon parameter flag is not set + if(!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval ) + return eHAL_STATUS_SUCCESS; + + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_FALSE; + + /* Create the message and send to lim */ + len = sizeof(tSirChangeBIParams); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirChangeBIParams), 0); + pMsg->messageType = eWNI_SME_CHNG_MCC_BEACON_INTERVAL; + pMsg->length = len; + + // bssId + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + smsLog( pMac, LOG1, FL("CSR Attempting to change BI for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + pMsg->sessionId = sessionId; + smsLog(pMac, LOG1, FL(" session %d BeaconInterval %d"), sessionId, pMac->roam.roamSession[sessionId].bssParams.beaconInterval); + pMsg->beaconInterval = pMac->roam.roamSession[sessionId].bssParams.beaconInterval; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + return status; +} + +#ifdef QCA_HT_2040_COEX +eHalStatus csrSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 sessionId, + ePhyChanBondState cbMode, tANI_BOOLEAN obssEnabled) +{ + tpSirSetHT2040Mode pMsg; + tANI_U16 len = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + /* Create the message and send to lim */ + len = sizeof(tSirSetHT2040Mode); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirSetHT2040Mode), 0); + pMsg->messageType = eWNI_SME_SET_HT_2040_MODE; + pMsg->length = len; + + // bssId + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + smsLog( pMac, LOG1, FL("CSR Attempting to set HT20/40 mode for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + pMsg->sessionId = sessionId; + smsLog(pMac, LOG1, FL(" session %d HT20/40 mode %d"), sessionId, cbMode); + pMsg->cbMode = cbMode; + pMsg->obssEnabled = obssEnabled; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + return status; +} +#endif + +eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthReq *pMsg; + tANI_U8 *pBuf; + tANI_U16 wTmp; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + return eHAL_STATUS_FAILURE; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDeauthReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDeauthReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEAUTH_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDeauthReq )); + //sessionId + pBuf = &pMsg->sessionId; + *pBuf++ = (tANI_U8)sessionId; + + //tansactionId + *pBuf = 0; + *(pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + if ((pSession->pCurRoamProfile != NULL) && ( + (CSR_IS_INFRA_AP(pSession->pCurRoamProfile)) || + (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))){ + // Set the BSSID before sending the message to LIM + vos_mem_copy( (tSirMacAddr *)pBuf, pSession->selfMacAddr, + sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + } + else + { + // Set the BSSID before sending the message to LIM + vos_mem_copy( (tSirMacAddr *)pBuf, bssId, sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + } + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + // Set the peer MAC address before sending the message to LIM + vos_mem_copy( (tSirMacAddr *) pBuf, bssId, sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + wTmp = pal_cpu_to_be16(reasonCode); + vos_mem_copy( pBuf, &wTmp,sizeof( tANI_U16 ) ); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDisassocCnf *pMsg; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDisassocCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDisassocCnf), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DISASSOC_CNF); + pMsg->statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDisassocCnf )); + vos_mem_copy(pMsg->peerMacAddr, pDisassocInd->peerMacAddr, + sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + + vos_mem_copy(pMsg->bssId, pDisassocInd->bssId, sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthCnf *pMsg; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDeauthCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDeauthCnf ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEAUTH_CNF); + pMsg->statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDeauthCnf )); + vos_mem_copy(pMsg->bssId, pDeauthInd->bssId, sizeof(pMsg->bssId)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + vos_mem_copy(pMsg->peerMacAddr, pDeauthInd->peerMacAddr, + sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus csrSendAssocCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus Halstatus ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeAssocCnf *pMsg; + tANI_U8 *pBuf; + tSirResultCodes statusCode; + tANI_U16 wTmp; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeAssocCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeAssocCnf ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_ASSOC_CNF); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeAssocCnf )); + pBuf = (tANI_U8 *)&pMsg->statusCode; + if(HAL_STATUS_SUCCESS(Halstatus)) + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + else + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_ASSOC_REFUSED); + vos_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes)); + pBuf += sizeof(tSirResultCodes); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // peerMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // aid + wTmp = pal_cpu_to_be16(pAssocInd->aid); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof (tANI_U16); + // alternateBssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // alternateChannelId + *pBuf = 11; + status = palSendMBMessage( pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + //pMsg is freed by palSendMBMessage + break; + } + } while( 0 ); + return( status ); +} +eHalStatus csrSendAssocIndToUpperLayerCnfMsg( tpAniSirGlobal pMac, + tpSirSmeAssocInd pAssocInd, + eHalStatus Halstatus, + tANI_U8 sessionId) +{ + tSirMsgQ msgQ; + tSirSmeAssocIndToUpperLayerCnf *pMsg; + tANI_U8 *pBuf; + tSirResultCodes statusCode; + tANI_U16 wTmp; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeAssocIndToUpperLayerCnf )); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirSmeAssocIndToUpperLayerCnf ), 0); + + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_UPPER_LAYER_ASSOC_CNF); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeAssocIndToUpperLayerCnf )); + + pMsg->sessionId = sessionId; + + pBuf = (tANI_U8 *)&pMsg->statusCode; + if(HAL_STATUS_SUCCESS(Halstatus)) + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + else + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_ASSOC_REFUSED); + vos_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes)) ; + pBuf += sizeof(tSirResultCodes); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // peerMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // StaId + wTmp = pal_cpu_to_be16(pAssocInd->staId); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof (tANI_U16); + // alternateBssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // alternateChannelId + *pBuf = 11; + pBuf += sizeof (tANI_U8); + // Instead of copying roam Info, we just copy only WmmEnabled, RsnIE information + //Wmm + *pBuf = pAssocInd->wmmEnabledSta; + pBuf += sizeof (tANI_U8); + //RSN IE + vos_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE, sizeof(tSirRSNie)); + pBuf += sizeof (tSirRSNie); + //Additional IE + vos_mem_copy((void *)pBuf, &pAssocInd->addIE, sizeof(tSirAddie)); + pBuf += sizeof (tSirAddie); + //reassocReq + *pBuf = pAssocInd->reassocReq; + pBuf += sizeof (tANI_U8); + //timingMeasCap + *pBuf = pAssocInd->timingMeasCap; + pBuf += sizeof (tANI_U8); + vos_mem_copy((void *)pBuf, &pAssocInd->chan_info, + sizeof(tSirSmeChanInfo)); + msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; + msgQ.bodyptr = pMsg; + msgQ.bodyval = 0; + SysProcessMmhMsg(pMac, &msgQ); + } while( 0 ); + return( eHAL_STATUS_SUCCESS ); +} + +eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U8 keyLength, tANI_U8 *pKey, tANI_U8 paeRole, + tANI_U8 *pKeyRsc ) +{ + tSirSmeSetContextReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + tAniEdType tmpEdType; + tAniKeyDirection tmpDirection; + tANI_U8 *pBuf = NULL; + tANI_U8 *p = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + smsLog( pMac, LOG1, FL("keylength is %d, Encry type is : %d"), + keyLength, edType); + do { + if( ( 1 != numKeys ) && ( 0 != numKeys ) ) break; + // all of these fields appear in every SET_CONTEXT message. Below we'll add in the size for each + // key set. Since we only support upto one key, we always allocate memory for 1 key + msgLen = sizeof( tANI_U16) + sizeof( tANI_U16 ) + sizeof( tSirMacAddr ) + + sizeof( tSirMacAddr ) + 1 + sizeof(tANI_U16) + + sizeof( pMsg->keyMaterial.length ) + sizeof( pMsg->keyMaterial.edType ) + sizeof( pMsg->keyMaterial.numKeys ) + + ( sizeof( pMsg->keyMaterial.key ) ); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SETCONTEXT_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + //sessionId + pBuf = &pMsg->sessionId; + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += sizeof(tANI_U16); + // peerMacAddr + vos_mem_copy(pBuf, (tANI_U8 *)peerMacAddr, sizeof(tSirMacAddr)); + + pBuf += sizeof(tSirMacAddr); + + // bssId + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + pBuf += sizeof(tSirMacAddr); + + p = pBuf; + // Set the pMsg->keyMaterial.length field (this length is defined as all data that follows the edType field + // in the tSirKeyMaterial keyMaterial; field). + // + // !!NOTE: This keyMaterial.length contains the length of a MAX size key, though the keyLength can be + // shorter than this max size. Is LIM interpreting this ok ? + p = pal_set_U16( p, pal_cpu_to_be16((tANI_U16)( sizeof( pMsg->keyMaterial.numKeys ) + ( numKeys * sizeof( pMsg->keyMaterial.key ) ) )) ); + // set pMsg->keyMaterial.edType + tmpEdType = (tAniEdType)pal_cpu_to_be32(edType); + vos_mem_copy(p, (tANI_U8 *)&tmpEdType, sizeof(tAniEdType)); + p += sizeof( pMsg->keyMaterial.edType ); + // set the pMsg->keyMaterial.numKeys field + *p = numKeys; + p += sizeof( pMsg->keyMaterial.numKeys ); + // set pSirKey->keyId = keyId; + *p = keyId; + p += sizeof( pMsg->keyMaterial.key[ 0 ].keyId ); + // set pSirKey->unicast = (tANI_U8)fUnicast; + *p = (tANI_U8)fUnicast; + p += sizeof( pMsg->keyMaterial.key[ 0 ].unicast ); + // set pSirKey->keyDirection = aniKeyDirection; + tmpDirection = (tAniKeyDirection)pal_cpu_to_be32(aniKeyDirection); + vos_mem_copy(p, (tANI_U8 *)&tmpDirection, sizeof(tAniKeyDirection)); + p += sizeof(tAniKeyDirection); + // pSirKey->keyRsc = ;; + vos_mem_copy(p, pKeyRsc, CSR_MAX_RSC_LEN); + p += sizeof( pMsg->keyMaterial.key[ 0 ].keyRsc ); + // set pSirKey->paeRole + *p = paeRole; // 0 is Supplicant + p++; + // set pSirKey->keyLength = keyLength; + p = pal_set_U16( p, pal_cpu_to_be16(keyLength) ); + if ( keyLength && pKey ) + { + vos_mem_copy(p, pKey, keyLength); + if(keyLength == 16) + { + smsLog(pMac, LOG1, " SME Set keyIdx (%d) encType(%d) key = %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", + keyId, edType, pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], + pKey[5], pKey[6], pKey[7], pKey[8], + pKey[9], pKey[10], pKey[11], pKey[12], pKey[13], pKey[14], pKey[15]); + } + } + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBStartBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamBssType bssType, + tCsrRoamStartBssParams *pParam, tSirBssDescription *pBssDesc ) +{ + eHalStatus status; + tSirSmeStartBssReq *pMsg; + tANI_U8 *pBuf = NULL; + tANI_U8 *wTmpBuf = NULL; + tANI_U16 msgLen, wTmp; + tANI_U32 dwTmp; + tSirNwType nwType; + ePhyChanBondState cbMode; + tANI_U32 authType; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do { + pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS; + pSession->joinFailStatusCode.reasonCode = 0; + msgLen = sizeof(tSirSmeStartBssReq); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_START_BSS_REQ); + pBuf = &pMsg->sessionId; + wTmpBuf = pBuf; + //sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += sizeof(tANI_U16); + // bssid + vos_mem_copy(pBuf, pParam->bssid, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // selfMacAddr + vos_mem_copy(pBuf, pSession->selfMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // beaconInterval + if( pBssDesc && pBssDesc->beaconInterval ) + { + wTmp = pal_cpu_to_be16( pBssDesc->beaconInterval ); + } + else if(pParam->beaconInterval) + { + wTmp = pal_cpu_to_be16( pParam->beaconInterval ); + } + else + { + wTmp = pal_cpu_to_be16( WNI_CFG_BEACON_INTERVAL_STADEF ); + } + if(csrIsconcurrentsessionValid (pMac, sessionId, + pParam->bssPersona) + == eHAL_STATUS_SUCCESS ) + { + csrValidateMCCBeaconInterval(pMac, pParam->operationChn, &wTmp, sessionId, + pParam->bssPersona); + //Update the beacon Interval + pParam->beaconInterval = wTmp; + } + else + { + smsLog( pMac,LOGE, FL("****Start BSS failed persona already exists***")); + status = eHAL_STATUS_FAILURE; + vos_mem_free(pMsg); + return status; + } + + vos_mem_copy(pBuf, &wTmp, sizeof( tANI_U16 )); + pBuf += sizeof(tANI_U16); + // dot11mode + *pBuf = (tANI_U8)csrTranslateToWNICfgDot11Mode( pMac, pParam->uCfgDot11Mode ); + pBuf += 1; +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + *pBuf = pMac->roam.configParam.cc_switch_mode; + pBuf += 1; +#endif + + // bssType + dwTmp = pal_cpu_to_be32( csrTranslateBsstypeToMacType( bssType ) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tSirBssType)); + pBuf += sizeof(tSirBssType); + // ssId + if( pParam->ssId.length ) + { + // ssId len + *pBuf = pParam->ssId.length; + pBuf++; + vos_mem_copy(pBuf, pParam->ssId.ssId, pParam->ssId.length); + pBuf += pParam->ssId.length; + } + else + { + *pBuf = 0; + pBuf++; + } + // set the channel Id + *pBuf = pParam->operationChn; + pBuf++; + //What should we really do for the cbmode. + cbMode = (ePhyChanBondState)pal_cpu_to_be32(pParam->cbMode); + vos_mem_copy(pBuf, (tANI_U8 *)&cbMode, sizeof(ePhyChanBondState)); + pBuf += sizeof(ePhyChanBondState); + + // Set privacy + *pBuf = pParam->privacy; + pBuf++; + + //Set Uapsd + *pBuf = pParam->ApUapsdEnable; + pBuf++; + //Set SSID hidden + *pBuf = pParam->ssidHidden; + pBuf++; + *pBuf = (tANI_U8)pParam->fwdWPSPBCProbeReq; + pBuf++; + + //Ht protection Enable/Disable + *pBuf = (tANI_U8)pParam->protEnabled; + pBuf++; + //Enable Beacons to Receive for OBSS protection Enable/Disable + *pBuf = (tANI_U8)pParam->obssProtEnabled; + pBuf++; + //set cfg related to protection + wTmp = pal_cpu_to_be16( pParam->ht_protection ); + vos_mem_copy(pBuf, &wTmp, sizeof( tANI_U16 )); + pBuf += sizeof(tANI_U16); + // Set Auth type + authType = pal_cpu_to_be32(pParam->authType); + vos_mem_copy(pBuf, (tANI_U8 *)&authType, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + // Set DTIM + dwTmp = pal_cpu_to_be32(pParam->dtimPeriod); + vos_mem_copy(pBuf, (tANI_U8 *)&dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + // Set wps_state + *pBuf = pParam->wps_state; + pBuf++; + // set isCoalesingInIBSSAllowed + *pBuf = pMac->isCoalesingInIBSSAllowed; + pBuf++; + //Persona + *pBuf = (tANI_U8)pParam->bssPersona; + pBuf++; + + //txLdpcIniFeatureEnabled + *pBuf = (tANI_U8)(tANI_U8)pMac->roam.configParam.txLdpcEnable; + pBuf++; + +#ifdef WLAN_FEATURE_11W + // Set MFP capable/required + *pBuf = (tANI_U8)pParam->mfpCapable; + pBuf++; + *pBuf = (tANI_U8)pParam->mfpRequired; + pBuf++; +#endif + + // set RSN IE + if( pParam->nRSNIELength > sizeof(pMsg->rsnIE.rsnIEdata) ) + { + status = eHAL_STATUS_INVALID_PARAMETER; + vos_mem_free(pMsg); + break; + } + wTmp = pal_cpu_to_be16( pParam->nRSNIELength ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + if( wTmp ) + { + wTmp = pParam->nRSNIELength; + vos_mem_copy(pBuf, pParam->pRSNIE, wTmp); + pBuf += wTmp; + } + nwType = (tSirNwType)pal_cpu_to_be32(pParam->sirNwType); + vos_mem_copy(pBuf, (tANI_U8 *)&nwType, sizeof(tSirNwType)); + pBuf += sizeof(tSirNwType); + *pBuf = pParam->operationalRateSet.numRates; //tSirMacRateSet->numRates + pBuf++; + vos_mem_copy(pBuf, pParam->operationalRateSet.rate, + pParam->operationalRateSet.numRates ); + pBuf += pParam->operationalRateSet.numRates ; + *pBuf++ = pParam->extendedRateSet.numRates; + if(0 != pParam->extendedRateSet.numRates) + { + vos_mem_copy(pBuf, pParam->extendedRateSet.rate, + pParam->extendedRateSet.numRates); + pBuf += pParam->extendedRateSet.numRates; + } + + //HT Config + vos_mem_copy(pBuf, &pSession->htConfig, + sizeof(tSirHTConfig)); + pBuf += sizeof(tSirHTConfig); + + vos_mem_copy(pBuf, &pParam->addIeParams, sizeof( pParam->addIeParams )); + pBuf += sizeof(pParam->addIeParams); + + *pBuf++ = (tANI_U8)pMac->roam.configParam.obssEnabled; + *pBuf++ = (tANI_U8)pParam->sap_dot11mc; + + msgLen = (tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)); //msg_header + msg + pMsg->length = pal_cpu_to_be16(msgLen); + + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBStopBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirSmeStopBssReq *pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U8 *pBuf; + tANI_U16 msgLen; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do { + pMsg = vos_mem_malloc(sizeof(tSirSmeStopBssReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirSmeStopBssReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_STOP_BSS_REQ); + pBuf = &pMsg->sessionId; + //sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + pBuf += sizeof(tANI_U16); + //reason code + *pBuf = 0; + pBuf += sizeof(tSirResultCodes); + // bssid + // if BSSType is WDS sta, use selfmacAddr as bssid, else use bssid in connectedProfile + if( CSR_IS_CONN_WDS_STA(&pSession->connectedProfile) ) + { + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->selfMacAddr, + sizeof(tSirMacAddr)); + } + else + { + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + } + pBuf += sizeof(tSirMacAddr); + msgLen = sizeof(tANI_U16) + sizeof(tANI_U16) + 1 + sizeof(tANI_U16) + sizeof(tSirResultCodes) + sizeof(tSirMacAddr); + pMsg->length = pal_cpu_to_be16(msgLen); + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus csrReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if((csrIsConnStateConnected(pMac, sessionId)) && + (fForce || (!vos_mem_compare( &pModProfileFields, + &pSession->connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)))) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + status = csrRoamIssueReassoc(pMac, sessionId, NULL, pModProfileFields, + eCsrSmeIssuedReassocToSameAP, roamId, + eANI_BOOLEAN_FALSE); + } + return status; +} +static eHalStatus csrRoamSessionOpened(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_SESSION_OPENED, eCSR_ROAM_RESULT_NONE); + return (status); +} +eHalStatus csrProcessAddStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirSmeAddStaSelfRsp *pRsp; + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if(pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandAddStaSession == pCommand->command) + { + pRsp = (tSirSmeAddStaSelfRsp*)pMsg; + smsLog( pMac, LOG1, "Add Sta rsp status = %d", pRsp->status ); + //Nothing to be done. May be indicate the self sta addition success by calling session callback (TODO). + csrRoamSessionOpened(pMac, pCommand->sessionId); + //Remove this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK)) + { + //Now put this command back on the avilable command list + csrReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_ADD_STA_SELF_RSP Received but NO Add sta session command are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_ADD_STA_SELF_RSP Received but NO commands are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } while(0); + return status; +} +eHalStatus csrSendMBAddSelfStaReqMsg( tpAniSirGlobal pMac, + tAddStaForSessionCmd *pAddStaReq, + tANI_U8 sessionId) +{ + tSirSmeAddStaSelfReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + do { + msgLen = sizeof(tSirSmeAddStaSelfReq); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) break; + vos_mem_set(pMsg, msgLen, 0); + pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_ADD_STA_SELF_REQ); + pMsg->mesgLen = pal_cpu_to_be16(msgLen); + // self station address + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, + (tANI_U8 *)&pAddStaReq->selfMacAddr, sizeof(tSirMacAddr)); + + pMsg->currDeviceMode = pAddStaReq->currDeviceMode; + pMsg->type = pAddStaReq->type; + pMsg->subType = pAddStaReq->subType; + pMsg->sessionId = sessionId; + pMsg->pkt_err_disconn_th = pMac->roam.configParam.pkt_err_disconn_th; + smsLog( pMac, LOG1, FL("selfMac="MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->selfMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrIssueAddStaForSessionReq(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr sessionMacAddr, + tANI_U32 type, tANI_U32 subType) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + status = eHAL_STATUS_RESOURCES; + } + else + { + pCommand->command = eSmeCommandAddStaSession; + pCommand->sessionId = (tANI_U8)sessionId; + vos_mem_copy(pCommand->u.addStaSessionCmd.selfMacAddr, sessionMacAddr, + sizeof( tSirMacAddr ) ); + pCommand->u.addStaSessionCmd.currDeviceMode = pMac->sme.currDeviceMode; + pCommand->u.addStaSessionCmd.type = type; + pCommand->u.addStaSessionCmd.subType = subType; + status = csrQueueSmeCommand(pMac, pCommand, TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + //Should be panic?? + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } + return (status); +} +eHalStatus csrProcessAddStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + return csrSendMBAddSelfStaReqMsg(pMac, + &pCommand->u.addStaSessionCmd, + pCommand->sessionId); +} +eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, + csrRoamCompleteCallback callback, + void *pContext, + tANI_U8 *pSelfMacAddr, tANI_U8 *pbSessionId, + tANI_U32 type, tANI_U32 subType ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i, value = 0; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + }uHTCapabilityInfo; + tCsrRoamSession *pSession; + *pbSessionId = CSR_SESSION_ID_INVALID; + + for( i = 0; i < pMac->sme.max_intf_count; i++ ) + { + if( !CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if (!pSession) + { + smsLog(pMac, LOGE, + FL("Session does not exist for interface %d"), i); + break; + } + status = eHAL_STATUS_SUCCESS; + pSession->sessionActive = eANI_BOOLEAN_TRUE; + pSession->sessionId = (tANI_U8)i; + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Initialize FT related data structures only in STA mode */ + sme_FTOpen(pMac, pSession->sessionId); +#endif + + pSession->callback = callback; + pSession->pContext = pContext; + vos_mem_copy(&pSession->selfMacAddr, pSelfMacAddr, + sizeof(tCsrBssid)); + *pbSessionId = (tANI_U8)i; + status = vos_timer_init(&pSession->hTimerRoaming, VOS_TIMER_TYPE_SW, + csrRoamRoamingTimerHandler, + &pSession->roamingTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("cannot allocate memory for Roaming timer")); + break; + } + /* get the HT capability info*/ + status = ccmCfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &value); + if (!HAL_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: could not get HT capability info", + __func__); + break; + } + +#ifdef FEATURE_WLAN_BTAMP_UT_RF + status = vos_timer_init(&pSession->hTimerJoinRetry, + VOS_TIMER_TYPE_SW, + csrRoamJoinRetryTimerHandler, + &pSession->joinRetryTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("cannot allocate memory for joinretry timer")); + break; + } +#endif + uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value; + pSession->htConfig.ht_rx_ldpc = + uHTCapabilityInfo.htCapInfo.advCodingCap; + pSession->htConfig.ht_tx_stbc = uHTCapabilityInfo.htCapInfo.txSTBC; + pSession->htConfig.ht_rx_stbc = uHTCapabilityInfo.htCapInfo.rxSTBC; + pSession->htConfig.ht_sgi = VOS_TRUE; + status = csrIssueAddStaForSessionReq ( pMac, i, pSelfMacAddr, type, + subType ); + break; + } + } + if( pMac->sme.max_intf_count == i ) + { + //No session is available + smsLog(pMac, LOGE, + "%s: Reached max interfaces: %d! Session creation will fail", + __func__, pMac->sme.max_intf_count); + status = eHAL_STATUS_RESOURCES; + } + return ( status ); +} + +eHalStatus csrProcessDelStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirSmeDelStaSelfRsp *pRsp; + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if(pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandDelStaSession == pCommand->command) + { + tANI_U8 sessionId = pCommand->sessionId; + pRsp = (tSirSmeDelStaSelfRsp*)pMsg; + smsLog( pMac, LOG1, "Del Sta rsp status = %d", pRsp->status ); + //This session is done. + csrCleanupSession(pMac, sessionId); + if(pCommand->u.delStaSessionCmd.callback) + { + + status = sme_ReleaseGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pCommand->u.delStaSessionCmd.callback( + pCommand->u.delStaSessionCmd.pContext); + status = sme_AcquireGlobalLock( &pMac->sme ); + if (! HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGP, "%s: Failed to Acquire Lock", __func__); + return status; + } + } + else { + smsLog(pMac, LOGE, "%s: Failed to Release Lock", __func__); + } + } + + //Remove this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK)) + { + //Now put this command back on the avilable command list + csrReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_DEL_STA_SELF_RSP Received but NO Del sta session command are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_DEL_STA_SELF_RSP Received but NO commands are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } while(0); + return status; +} +eHalStatus csrSendMBDelSelfStaReqMsg( tpAniSirGlobal pMac, tSirMacAddr macAddr, + tANI_U8 sessionId) +{ + tSirSmeDelStaSelfReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + do { + msgLen = sizeof(tSirSmeDelStaSelfReq); + pMsg = vos_mem_malloc(msgLen); + if (NULL == pMsg) + return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + + pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEL_STA_SELF_REQ); + pMsg->mesgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + // self station address + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, (tANI_U8 *)macAddr, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} +eHalStatus csrIssueDelStaForSessionReq(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr sessionMacAddr, + csrRoamSessionCloseCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + status = eHAL_STATUS_RESOURCES; + } + else + { + pCommand->command = eSmeCommandDelStaSession; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.delStaSessionCmd.callback = callback; + pCommand->u.delStaSessionCmd.pContext = pContext; + vos_mem_copy(pCommand->u.delStaSessionCmd.selfMacAddr, sessionMacAddr, + sizeof( tSirMacAddr )); + status = csrQueueSmeCommand(pMac, pCommand, TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + //Should be panic?? + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } + return (status); +} +eHalStatus csrProcessDelStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + return csrSendMBDelSelfStaReqMsg( pMac, + pCommand->u.delStaSessionCmd.selfMacAddr, + (tANI_U8)pCommand->sessionId); +} +static void purgeCsrSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tDblLinkList *pList = &pMac->roam.roamCmdPendingList; + tListElem *pEntry, *pNext; + tSmeCmd *pCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + csrLLLock(pList); + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while(pEntry != NULL) + { + pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(pCommand->sessionId == sessionId) + { + if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + } + pEntry = pNext; + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } + csrLLClose(&localList); +} + +void csrCleanupSession(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + csrRoamStop(pMac, sessionId); + + /* Clean up FT related data structures */ +#if defined WLAN_FEATURE_VOWIFI_11R + sme_FTClose(pMac, sessionId); +#endif + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile( pMac, &pSession->connectedProfile ); + csrRoamFreeConnectedInfo ( pMac, &pSession->connectedInfo); + vos_timer_destroy(&pSession->hTimerRoaming); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + vos_timer_destroy(&pSession->hTimerJoinRetry); +#endif + purgeSmeSessionCmdList(pMac, sessionId, &pMac->sme.smeCmdPendingList); + if (pMac->fScanOffload) + { + purgeSmeSessionCmdList(pMac, sessionId, + &pMac->sme.smeScanCmdPendingList); + } + + purgeCsrSessionCmdList(pMac, sessionId); + csrInitSession(pMac, sessionId); + } +} + +eHalStatus csrRoamCloseSession( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fSync, + csrRoamSessionCloseCallback callback, + void *pContext ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(fSync) + { + csrCleanupSession(pMac, sessionId); + } + else + { + purgeSmeSessionCmdList(pMac, sessionId, + &pMac->sme.smeCmdPendingList); + if (pMac->fScanOffload) + { + purgeSmeSessionCmdList(pMac, sessionId, + &pMac->sme.smeScanCmdPendingList); + } + purgeCsrSessionCmdList(pMac, sessionId); + status = csrIssueDelStaForSessionReq( pMac, sessionId, + pSession->selfMacAddr, callback, pContext); + } + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + return ( status ); +} + +static void csrInitSession( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pSession->sessionActive = eANI_BOOLEAN_FALSE; + pSession->sessionId = CSR_SESSION_ID_INVALID; + pSession->callback = NULL; + pSession->pContext = NULL; + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + csrFreeRoamProfile( pMac, sessionId ); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + csrFreeConnectBssDesc(pMac, sessionId); + csrScanEnable(pMac); + vos_mem_set(&pSession->selfMacAddr, sizeof(tCsrBssid), 0); + if (pSession->pWpaRsnReqIE) + { + vos_mem_free(pSession->pWpaRsnReqIE); + pSession->pWpaRsnReqIE = NULL; + } + pSession->nWpaRsnReqIeLength = 0; + if (pSession->pWpaRsnRspIE) + { + vos_mem_free(pSession->pWpaRsnRspIE); + pSession->pWpaRsnRspIE = NULL; + } + pSession->nWpaRsnRspIeLength = 0; +#ifdef FEATURE_WLAN_WAPI + if (pSession->pWapiReqIE) + { + vos_mem_free(pSession->pWapiReqIE); + pSession->pWapiReqIE = NULL; + } + pSession->nWapiReqIeLength = 0; + if (pSession->pWapiRspIE) + { + vos_mem_free(pSession->pWapiRspIE); + pSession->pWapiRspIE = NULL; + } + pSession->nWapiRspIeLength = 0; +#endif /* FEATURE_WLAN_WAPI */ + if (pSession->pAddIEScan) + { + vos_mem_free(pSession->pAddIEScan); + pSession->pAddIEScan = NULL; + } + pSession->nAddIEScanLength = 0; + if (pSession->pAddIEAssoc) + { + vos_mem_free(pSession->pAddIEAssoc); + pSession->pAddIEAssoc = NULL; + } + pSession->nAddIEAssocLength = 0; +} + +eHalStatus csrRoamGetSessionIdFromBSSID( tpAniSirGlobal pMac, tCsrBssid *bssid, tANI_U32 *pSessionId ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 i; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + if( csrIsMacAddressEqual( pMac, bssid, &pMac->roam.roamSession[i].connectedProfile.bssid ) ) + { + //Found it + status = eHAL_STATUS_SUCCESS; + *pSessionId = i; + break; + } + } + } + return( status ); +} + +//This function assumes that we only support one IBSS session. We cannot use BSSID to identify +//session because for IBSS, the bssid changes. +static tANI_U32 csrFindIbssSession( tpAniSirGlobal pMac ) +{ + tANI_U32 i, nRet = CSR_SESSION_ID_INVALID; + tCsrRoamSession *pSession; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if( pSession->pCurRoamProfile && ( csrIsBssTypeIBSS( pSession->connectedProfile.BSSType ) ) ) + { + //Found it + nRet = i; + break; + } + } + } + return (nRet); +} +static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid) +{ + /* Update the current BSS info in ho control block based on connected + profile info from pmac global structure */ + + smsLog(pMac, LOGW, " csrRoamLinkUp: WLAN link UP with AP= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssid)); + /* Check for user misconfig of RSSI trigger threshold */ + pMac->roam.configParam.vccRssiThreshold = + ( 0 == pMac->roam.configParam.vccRssiThreshold ) ? + CSR_VCC_RSSI_THRESHOLD : pMac->roam.configParam.vccRssiThreshold; + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + /* Check for user misconfig of UL MAC Loss trigger threshold */ + pMac->roam.configParam.vccUlMacLossThreshold = + ( 0 == pMac->roam.configParam.vccUlMacLossThreshold ) ? + CSR_VCC_UL_MAC_LOSS_THRESHOLD : pMac->roam.configParam.vccUlMacLossThreshold; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + { + tANI_U32 sessionId = 0; + /* Indicate the neighbor roal algorithm about the connect indication */ + csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssid, &sessionId); + csrNeighborRoamIndicateConnect(pMac, sessionId, VOS_STATUS_SUCCESS); + } +#endif +} + +static void csrRoamLinkDown(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + //Only to handle the case for Handover on infra link + if( eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType ) + { + return; + } + /* + * Incase of station mode, immediately stop data transmission whenever + * link down is detected. + */ + if (csrRoamIsStaMode(pMac, sessionId) + && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) +#ifdef WLAN_FEATURE_VOWIFI_11R + && !csrRoamIs11rAssoc(pMac, sessionId) +#endif + ) { + smsLog(pMac, LOG1, FL("Inform Link lost for session %d"), sessionId); + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_LOSTLINK); + } + /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers*/ + csrRoamDeregStatisticsReq(pMac); + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Indicate the neighbor roal algorithm about the disconnect indication */ + csrNeighborRoamIndicateDisconnect(pMac, sessionId); +#endif + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + csrIsInfraApStarted( pMac ) && + pMac->roam.configParam.doBMPSWorkaround) + { + pMac->roam.configParam.doBMPSWorkaround = 0; + } + + if(pMac->psOffloadEnabled) + pmcOffloadCleanup(pMac, sessionId); + +} + +void csrRoamTlStatsTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + eHalStatus status; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + + smsLog(pMac, LOG1, FL(" TL stat timer is no-op. It needs to support multiple stations")); + + if(!pMac->roam.tlStatsReqInfo.timerRunning) + { + if(pMac->roam.tlStatsReqInfo.periodicity) + { + //start timer + status = vos_timer_start(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + pMac->roam.tlStatsReqInfo.periodicity); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamTlStatsTimerHandler:cannot start TlStatsTimer timer")); + return; + } + pMac->roam.tlStatsReqInfo.timerRunning = TRUE; + } + } +} +void csrRoamPeStatsTimerHandler(void *pv) +{ + tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *)pv; + eHalStatus status; + tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac; + VOS_STATUS vosStatus; + tPmcPowerState powerState; + pPeStatsReqListEntry->timerRunning = FALSE; + if( pPeStatsReqListEntry->timerStopFailed == TRUE ) + { + // If we entered here, meaning the timer could not be successfully + // stopped in csrRoamRemoveEntryFromPeStatsReqList(). So do it here. + + /* Destroy the timer */ + vosStatus = vos_timer_destroy( &pPeStatsReqListEntry->hPeStatsTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:failed to destroy hPeStatsTimer timer")); + } + + // Free the entry + vos_mem_free(pPeStatsReqListEntry); + pPeStatsReqListEntry = NULL; + } + else + { + if(!pPeStatsReqListEntry->rspPending) + { + status = csrSendMBStatsReqMsg(pMac, pPeStatsReqListEntry->statsMask & ~(1 << eCsrGlobalClassDStats), + pPeStatsReqListEntry->staId, + pPeStatsReqListEntry->sessionId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:failed to send down stats req to PE")); + } + else + { + pPeStatsReqListEntry->rspPending = TRUE; + } + } + + //send down a req + if(pPeStatsReqListEntry->periodicity && + (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pPeStatsReqListEntry->hPeStatsTimer))) + { + pmcQueryPowerState(pMac, &powerState, NULL, NULL); + if(ePMC_FULL_POWER == powerState) + { + if(pPeStatsReqListEntry->periodicity < pMac->roam.configParam.statsReqPeriodicity) + { + pPeStatsReqListEntry->periodicity = pMac->roam.configParam.statsReqPeriodicity; + } + } + else + { + if(pPeStatsReqListEntry->periodicity < pMac->roam.configParam.statsReqPeriodicityInPS) + { + pPeStatsReqListEntry->periodicity = pMac->roam.configParam.statsReqPeriodicityInPS; + } + } + //start timer + vosStatus = vos_timer_start( &pPeStatsReqListEntry->hPeStatsTimer, pPeStatsReqListEntry->periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:cannot start hPeStatsTimer timer")); + return; + } + pPeStatsReqListEntry->timerRunning = TRUE; + + } + + } +} +void csrRoamStatsClientTimerHandler(void *pv) +{ + tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *)pv; + if (VOS_TIMER_STATE_STOPPED == + vos_timer_getCurrentState(&pStaEntry->timer)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("roam stats client timer is stopped")); + } +} + + + +eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, + tANI_U8 staId, tANI_U8 sessionId) +{ + tAniGetPEStatsReq *pMsg; + eHalStatus status = eHAL_STATUS_SUCCESS; + pMsg = vos_mem_malloc(sizeof(tAniGetPEStatsReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL( "Failed to allocate mem for stats req ")); + return eHAL_STATUS_FAILURE; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_STATISTICS_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetPEStatsReq); + pMsg->staId = staId; + pMsg->statsMask = statsMask; + pMsg->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOG1, FL("Failed to send down the stats req ")); + } + return status; +} +void csrRoamStatsRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg) +{ + tAniGetPEStatsRsp *pSmeStatsRsp; + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry = NULL; + tCsrStatsClientReqInfo *pTempStaEntry = NULL; + tCsrPeStatsReqInfo *pPeStaEntry = NULL; + tANI_U32 tempMask = 0; + tANI_U8 counter = 0; + tANI_U8 *pStats = NULL; + tANI_U32 length = 0; + v_PVOID_t pvosGCtx; + v_S7_t rssi = 0, snr = 0; + tANI_U32 *pRssi = NULL, *pSnr = NULL; + tANI_U32 linkCapacity; + pSmeStatsRsp = (tAniGetPEStatsRsp *)pSirMsg; + if(pSmeStatsRsp->rc) + { + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:stats rsp from PE shows failure")); + goto post_update; + } + tempMask = pSmeStatsRsp->statsMask; + pStats = ((tANI_U8 *)&pSmeStatsRsp->statsMask) + sizeof(pSmeStatsRsp->statsMask); + /* subtract all statistics from this length, and after processing the entire + * 'stat' part of the message, if the length is not zero, then rssi is piggy packed + * in this 'stats' message. + */ + length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp); + //new stats info from PE, fill up the stats strucutres in PMAC + while(tempMask) + { + if(tempMask & 1) + { + switch(counter) + { + case eCsrSummaryStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:summary stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.summaryStatsInfo, + pStats, sizeof(tCsrSummaryStatsInfo)); + pStats += sizeof(tCsrSummaryStatsInfo); + length -= sizeof(tCsrSummaryStatsInfo); + break; + case eCsrGlobalClassAStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassA stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classAStatsInfo, + pStats, sizeof(tCsrGlobalClassAStatsInfo)); + pStats += sizeof(tCsrGlobalClassAStatsInfo); + length -= sizeof(tCsrGlobalClassAStatsInfo); + break; + case eCsrGlobalClassBStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassB stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classBStatsInfo, + pStats, sizeof(tCsrGlobalClassBStatsInfo)); + pStats += sizeof(tCsrGlobalClassBStatsInfo); + length -= sizeof(tCsrGlobalClassBStatsInfo); + break; + case eCsrGlobalClassCStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassC stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classCStatsInfo, + pStats, sizeof(tCsrGlobalClassCStatsInfo)); + pStats += sizeof(tCsrGlobalClassCStatsInfo); + length -= sizeof(tCsrGlobalClassCStatsInfo); + break; + case eCsrPerStaStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:PerSta stats")); + if( CSR_MAX_STA > pSmeStatsRsp->staId ) + { + vos_mem_copy((tANI_U8 *)&pMac->roam.perStaStatsInfo[pSmeStatsRsp->staId], + pStats, sizeof(tCsrPerStaStatsInfo)); + } + else + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, FL("csrRoamStatsRspProcessor:out bound staId:%d"), pSmeStatsRsp->staId); + VOS_ASSERT( 0 ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:failed to copy PerSta stats")); + } + pStats += sizeof(tCsrPerStaStatsInfo); + length -= sizeof(tCsrPerStaStatsInfo); + break; + default: + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:unknown stats type")); + break; + } + } + tempMask >>=1; + counter++; + } + pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SME, pMac); + if (length != 0) + { + pRssi = (tANI_U32*)pStats; + rssi = (v_S7_t)*pRssi; + pStats += sizeof(tANI_U32); + length -= sizeof(tANI_U32); + } + else + { + /* If riva is not sending rssi, continue to use the hack */ + rssi = RSSI_HACK_BMPS; + } + + WDA_UpdateRssiBmps(pvosGCtx, pSmeStatsRsp->staId, rssi); + + if (length != 0) + { + linkCapacity = *(tANI_U32*)pStats; + pStats += sizeof(tANI_U32); + length -= sizeof(tANI_U32); + } + else + { + linkCapacity = 0; + } + + WDA_UpdateLinkCapacity(pvosGCtx, pSmeStatsRsp->staId, linkCapacity); + + if (length != 0) + { + pSnr = (tANI_U32*)pStats; + snr = (v_S7_t)*pSnr; + } + else + { + snr = SNR_HACK_BMPS; + } + + WDA_UpdateSnrBmps(pvosGCtx, pSmeStatsRsp->staId, snr); +post_update: + //make sure to update the pe stats req list + pEntry = csrRoamFindInPeStatsReqList(pMac, pSmeStatsRsp->statsMask); + if(pEntry) + { + pPeStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + pPeStaEntry->rspPending = FALSE; + + } + //check the one timer cases + pEntry = csrRoamCheckClientReqList(pMac, pSmeStatsRsp->statsMask); + if(pEntry) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if(pTempStaEntry->timerExpired) + { + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + //also remove from the client list + csrRoamRemoveStatListEntry(pMac, pEntry); + pTempStaEntry = NULL; + } + } +} +tListElem * csrRoamFindInPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask) +{ + tListElem *pEntry = NULL; + tCsrPeStatsReqInfo *pTempStaEntry = NULL; + pEntry = csrLLPeekHead( &pMac->roam.peStatsReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamFindInPeStatsReqList: List empty, no request to PE"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + if(pTempStaEntry->statsMask == statsMask) + { + smsLog(pMac, LOG3, "csrRoamFindInPeStatsReqList: match found"); + break; + } + pEntry = csrLLNext( &pMac->roam.peStatsReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} + +tListElem * csrRoamChecknUpdateClientReqList(tpAniSirGlobal pMac, tCsrStatsClientReqInfo *pStaEntry, + tANI_BOOLEAN update) +{ + tListElem *pEntry; + tCsrStatsClientReqInfo *pTempStaEntry; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamChecknUpdateClientReqList: List empty, no request from " + "upper layer client(s)"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if((pTempStaEntry->requesterId == pStaEntry->requesterId) && + (pTempStaEntry->statsMask == pStaEntry->statsMask)) + { + smsLog(pMac, LOG3, "csrRoamChecknUpdateClientReqList: match found"); + if(update) + { + pTempStaEntry->periodicity = pStaEntry->periodicity; + pTempStaEntry->callback = pStaEntry->callback; + pTempStaEntry->pContext = pStaEntry->pContext; + } + break; + } + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} +tListElem * csrRoamCheckClientReqList(tpAniSirGlobal pMac, tANI_U32 statsMask) +{ + tListElem *pEntry; + tCsrStatsClientReqInfo *pTempStaEntry; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamCheckClientReqList: List empty, no request from " + "upper layer client(s)"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if((pTempStaEntry->statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) + { + smsLog(pMac, LOG3, "csrRoamCheckClientReqList: match found"); + break; + } + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} +eHalStatus csrRoamRegisterLinkQualityIndCallback(tpAniSirGlobal pMac, + csrRoamLinkQualityIndCallback callback, + void *pContext) +{ + pMac->roam.linkQualityIndInfo.callback = callback; + pMac->roam.linkQualityIndInfo.context = pContext; + if( NULL == callback ) + { + smsLog(pMac, LOGW, "csrRoamRegisterLinkQualityIndCallback: indication callback being deregistered"); + } + else + { + smsLog(pMac, LOGW, "csrRoamRegisterLinkQualityIndCallback: indication callback being registered"); + /* do we need to invoke the callback to notify client of initial value ?? */ + } + return eHAL_STATUS_SUCCESS; +} +void csrRoamVccTrigger(tpAniSirGlobal pMac) +{ + eCsrRoamLinkQualityInd newVccLinkQuality; + tANI_U32 ul_mac_loss = 0; + tANI_U32 ul_mac_loss_trigger_threshold; + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /*------------------------------------------------------------------------- + Link quality is currently binary based on OBIWAN recommended triggers + Check for a change in link quality and notify client if necessary + -------------------------------------------------------------------------*/ + ul_mac_loss_trigger_threshold = + pMac->roam.configParam.vccUlMacLossThreshold; + if (0 == ul_mac_loss_trigger_threshold) + { + VOS_ASSERT( ul_mac_loss_trigger_threshold != 0 ); + return; + } + smsLog(pMac, LOGW, "csrRoamVccTrigger: UL_MAC_LOSS_THRESHOLD is %d", + ul_mac_loss_trigger_threshold ); + if(ul_mac_loss_trigger_threshold < ul_mac_loss) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality is POOR "); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + } + else + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality is GOOD"); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND; + } + smsLog(pMac, LOGW, "csrRoamVccTrigger: link qual : *** UL_MAC_LOSS %d *** ", + ul_mac_loss); + if(newVccLinkQuality != pMac->roam.vccLinkQuality) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality changed: trigger necessary"); + if(NULL != pMac->roam.linkQualityIndInfo.callback) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality indication %d", + newVccLinkQuality ); + + /* we now invoke the callback once to notify client of initial value */ + pMac->roam.linkQualityIndInfo.callback( newVccLinkQuality, + pMac->roam.linkQualityIndInfo.context ); + //event: EVENT_WLAN_VCC + } + } + pMac->roam.vccLinkQuality = newVccLinkQuality; + +} +VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal, + v_U8_t rssiNotification, + void * context) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( context ); + eCsrRoamLinkQualityInd newVccLinkQuality; + tANI_U32 sessionId = 0; + VOS_STATUS status = VOS_STATUS_SUCCESS; + /*------------------------------------------------------------------------- + Link quality is currently binary based on OBIWAN recommended triggers + Check for a change in link quality and notify client if necessary + -------------------------------------------------------------------------*/ + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: RSSI trigger threshold is %d", + pMac->roam.configParam.vccRssiThreshold); + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: ignoring the indication as we are not connected"); + return VOS_STATUS_SUCCESS; + } + if(WLANTL_HO_THRESHOLD_DOWN == rssiNotification) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality is POOR"); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + } + else if(WLANTL_HO_THRESHOLD_UP == rssiNotification) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality is GOOD "); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND; + } + else + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: unknown rssi notification %d", rssiNotification); + //Set to this so the code below won't do anything + newVccLinkQuality = pMac->roam.vccLinkQuality; + VOS_ASSERT(0); + } + + if(newVccLinkQuality != pMac->roam.vccLinkQuality) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality changed: trigger necessary"); + if(NULL != pMac->roam.linkQualityIndInfo.callback) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality indication %d", + newVccLinkQuality); + /* we now invoke the callback once to notify client of initial value */ + pMac->roam.linkQualityIndInfo.callback( newVccLinkQuality, + pMac->roam.linkQualityIndInfo.context ); + //event: EVENT_WLAN_VCC + } + } + pMac->roam.vccLinkQuality = newVccLinkQuality; + return status; +} +tCsrStatsClientReqInfo * csrRoamInsertEntryIntoList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrStatsClientReqInfo *pStaEntry) +{ + tCsrStatsClientReqInfo *pNewStaEntry = NULL; + //if same entity requested for same set of stats with different periodicity & + // callback update it + if(NULL == csrRoamChecknUpdateClientReqList(pMac, pStaEntry, TRUE)) + { + + pNewStaEntry = vos_mem_malloc(sizeof(tCsrStatsClientReqInfo)); + if (NULL == pNewStaEntry) + { + smsLog(pMac, LOGW, "csrRoamInsertEntryIntoList: couldn't allocate memory for the " + "entry"); + return NULL; + } + + pNewStaEntry->callback = pStaEntry->callback; + pNewStaEntry->pContext = pStaEntry->pContext; + pNewStaEntry->periodicity = pStaEntry->periodicity; + pNewStaEntry->requesterId = pStaEntry->requesterId; + pNewStaEntry->statsMask = pStaEntry->statsMask; + pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry; + pNewStaEntry->pMac = pStaEntry->pMac; + pNewStaEntry->staId = pStaEntry->staId; + pNewStaEntry->timerExpired = pStaEntry->timerExpired; + + csrLLInsertTail( pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK ); + } + return pNewStaEntry; +} + +tCsrPeStatsReqInfo * csrRoamInsertEntryIntoPeStatsReqList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrPeStatsReqInfo *pStaEntry) +{ + tCsrPeStatsReqInfo *pNewStaEntry = NULL; + pNewStaEntry = vos_mem_malloc(sizeof(tCsrPeStatsReqInfo)); + if (NULL == pNewStaEntry) + { + smsLog(pMac, LOGW, "csrRoamInsertEntryIntoPeStatsReqList: couldn't allocate memory for the " + "entry"); + return NULL; + } + + pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer; + pNewStaEntry->numClient = pStaEntry->numClient; + pNewStaEntry->periodicity = pStaEntry->periodicity; + pNewStaEntry->statsMask = pStaEntry->statsMask; + pNewStaEntry->pMac = pStaEntry->pMac; + pNewStaEntry->staId = pStaEntry->staId; + pNewStaEntry->timerRunning = pStaEntry->timerRunning; + pNewStaEntry->rspPending = pStaEntry->rspPending; + + csrLLInsertTail( pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK ); + return pNewStaEntry; +} +eHalStatus csrGetRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + tANI_S8 lastRSSI, + void *pContext, + void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + tANI_U32 sessionId; + + tAniGetRssiReq *pMsg; + smsLog(pMac, LOG2, FL("called")); + + status = csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssId, &sessionId); + if (!HAL_STATUS_SUCCESS(status)) + { + callback(lastRSSI, staId, pContext); + smsLog(pMac, LOGE, FL("Failed to get SessionId")); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tAniGetRssiReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrGetRssi: failed to allocate mem for req "); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_RSSI_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetRssiReq); + pMsg->sessionId = sessionId; + pMsg->staId = staId; + pMsg->rssiCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + /* + * store RSSI at time of calling, so that if RSSI request cannot + * be sent to firmware, this value can be used to return immediately + */ + pMsg->lastRSSI = lastRSSI; + msg.type = eWNI_SME_GET_RSSI_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " csrGetRssi failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG2, FL("returned")); + return status; +} + +eHalStatus csrGetSnr(tpAniSirGlobal pMac, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + tANI_U32 sessionId; + + tAniGetSnrReq *pMsg; + + smsLog(pMac, LOG2, FL("called")); + + pMsg =(tAniGetSnrReq *)vos_mem_malloc(sizeof(tAniGetSnrReq)); + if (NULL == pMsg ) + { + smsLog(pMac, LOGE, "%s: failed to allocate mem for req",__func__); + return status; + } + + csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssId, &sessionId); + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_SNR_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetSnrReq); + pMsg->sessionId = sessionId; + pMsg->staId = staId; + pMsg->snrCallback = callback; + pMsg->pDevContext = pContext; + msg.type = eWNI_SME_GET_SNR_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, "%s failed to post msg to self", __func__); + vos_mem_free((v_VOID_t *)pMsg); + status = eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG2, FL("returned")); + return status; +} + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniGetRssiReq *pMsg; + + pMsg = vos_mem_malloc(sizeof(tAniGetRssiReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL("Failed to allocate mem for req")); + return eHAL_STATUS_FAILURE; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_ROAM_RSSI_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetRssiReq); + pMsg->staId = staId; + pMsg->rssiCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" Failed to send down get rssi req")); + //pMsg is freed by palSendMBMessage + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrGetTsmStats(tpAniSirGlobal pMac, + tCsrTsmStatsCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void *pContext, + void* pVosContext, + tANI_U8 tid) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniGetTsmStatsReq *pMsg = NULL; + pMsg = vos_mem_malloc(sizeof(tAniGetTsmStatsReq)); + if (!pMsg) + { + smsLog(pMac, LOGE, "csrGetTsmStats: failed to allocate mem for req"); + return status; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_TSM_STATS_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetTsmStatsReq); + pMsg->staId = staId; + pMsg->tid = tid; + vos_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr)); + pMsg->tsmStatsCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOG1, " csrGetTsmStats: failed to send down the rssi req"); + //pMsg is freed by palSendMBMessage + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* --------------------------------------------------------------------------- + \fn csrGetTLSTAState + \helper function to get teh TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 csrGetTLSTAState(tpAniSirGlobal pMac, tANI_U8 staId) +{ + WLANTL_STAStateType tlSTAState; + tlSTAState = WLANTL_STA_INIT; + + //request TL for STA State + if ( !VOS_IS_STATUS_SUCCESS(WLANTL_GetSTAState(pMac->roam.gVosContext, staId, &tlSTAState)) ) + { + smsLog(pMac, LOGE, FL("csrGetTLSTAState:couldn't get the STA state from TL")); + } + + return tlSTAState; +} + +eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext, + tANI_U8 sessionId) +{ + tCsrStatsClientReqInfo staEntry; + tCsrStatsClientReqInfo *pStaEntry = NULL; + tCsrPeStatsReqInfo *pPeStaEntry = NULL; + tListElem *pEntry = NULL; + tANI_BOOLEAN found = FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN insertInClientList = FALSE; + VOS_STATUS vosStatus; + WLANTL_TRANSFER_STA_TYPE *pTlStats; + + if( csrIsAllSessionDisconnected(pMac) ) + { + //smsLog(pMac, LOGW, "csrGetStatistics: wrong state curState(%d) not connected", pMac->roam.curState); + return eHAL_STATUS_FAILURE; + } + + if (csrNeighborMiddleOfRoaming((tHalHandle)pMac, sessionId)) + { + smsLog(pMac, LOG1, FL("in the middle of roaming states")); + return eHAL_STATUS_FAILURE; + } + + if((!statsMask) && (!callback)) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: statsMask & callback empty in the request"); + return eHAL_STATUS_FAILURE; + } + //for the search list method for deregister + staEntry.requesterId = requesterId; + staEntry.statsMask = statsMask; + //requester wants to deregister or just an error + if((statsMask) && (!callback)) + { + pEntry = csrRoamChecknUpdateClientReqList(pMac, &staEntry, FALSE); + if(!pEntry) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: callback is empty in the request & couldn't " + "find any existing request in statsClientReqList"); + return eHAL_STATUS_FAILURE; + } + else + { + //clean up & return + pStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if(NULL != pStaEntry->pPeStaEntry) + { + pStaEntry->pPeStaEntry->numClient--; + //check if we need to delete the entry from peStatsReqList too + if(!pStaEntry->pPeStaEntry->numClient) + { + csrRoamRemoveEntryFromPeStatsReqList(pMac, pStaEntry->pPeStaEntry); + } + } + + //check if we need to stop the tl stats timer too + pMac->roam.tlStatsReqInfo.numClient--; + if(!pMac->roam.tlStatsReqInfo.numClient) + { + if(pMac->roam.tlStatsReqInfo.timerRunning) + { + status = vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot stop TlStatsTimer timer")); + return eHAL_STATUS_FAILURE; + } + } + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + } + vos_timer_stop( &pStaEntry->timer ); + // Destroy the vos timer... + vosStatus = vos_timer_destroy( &pStaEntry->timer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:failed to destroy Client req timer")); + } + csrRoamRemoveStatListEntry(pMac, pEntry); + pStaEntry = NULL; + return eHAL_STATUS_SUCCESS; + } + } + + if(cache && !periodicity) + { + //return the cached stats + csrRoamReportStatistics(pMac, statsMask, callback, staId, pContext); + } + else + { + //add the request in the client req list + staEntry.callback = callback; + staEntry.pContext = pContext; + staEntry.periodicity = periodicity; + staEntry.pPeStaEntry = NULL; + staEntry.staId = staId; + staEntry.pMac = pMac; + staEntry.timerExpired = FALSE; + staEntry.sessionId = sessionId; + + + //if periodic report requested with non cached result from PE/TL + if(periodicity) + { + + //if looking for stats from PE + if(statsMask & ~(1 << eCsrGlobalClassDStats)) + { + + //check if same request made already & waiting for rsp + pPeStaEntry = csrRoamCheckPeStatsReqList(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), + periodicity, &found, staId, + sessionId); + if(!pPeStaEntry) + { + //bail out, maxed out on number of req for PE + return eHAL_STATUS_FAILURE; + } + else + { + staEntry.pPeStaEntry = pPeStaEntry; + } + + } + //request stats from TL rightaway if requested by client, update tlStatsReqInfo if needed + if(statsMask & (1 << eCsrGlobalClassDStats)) + { + if(cache && pMac->roam.tlStatsReqInfo.numClient) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:Looking for cached stats from TL")); + } + else + { + + //update periodicity + if(pMac->roam.tlStatsReqInfo.periodicity) + { + pMac->roam.tlStatsReqInfo.periodicity = + CSR_ROAM_MIN(periodicity, pMac->roam.tlStatsReqInfo.periodicity); + } + else + { + pMac->roam.tlStatsReqInfo.periodicity = periodicity; + } + if(pMac->roam.tlStatsReqInfo.periodicity < CSR_MIN_TL_STAT_QUERY_PERIOD) + { + pMac->roam.tlStatsReqInfo.periodicity = CSR_MIN_TL_STAT_QUERY_PERIOD; + } + + if(!pMac->roam.tlStatsReqInfo.timerRunning) + { + pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); + if (NULL != pTlStats) + { + //req TL for class D stats + if(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:couldn't get the stats from TL")); + } + else + { + //save in SME + csrRoamSaveStatsFromTl(pMac, pTlStats); + } + vos_mem_free(pTlStats); + pTlStats = NULL; + } + else + { + smsLog(pMac, LOGE, FL("cannot allocate memory for TL stat")); + } + + if(pMac->roam.tlStatsReqInfo.periodicity) + { + //start timer + status = vos_timer_start(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + pMac->roam.tlStatsReqInfo.periodicity); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot start TlStatsTimer timer")); + return eHAL_STATUS_FAILURE; + } + pMac->roam.tlStatsReqInfo.timerRunning = TRUE; + } + } + } + pMac->roam.tlStatsReqInfo.numClient++; + } + + insertInClientList = TRUE; + } + //if one time report requested with non cached result from PE/TL + else if(!cache && !periodicity) + { + if(statsMask & ~(1 << eCsrGlobalClassDStats)) + { + //send down a req + status = csrSendMBStatsReqMsg(pMac, + statsMask & ~(1 << eCsrGlobalClassDStats), + staId, + sessionId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:failed to send down stats req to PE")); + } + //so that when the stats rsp comes back from PE we respond to upper layer + //right away + staEntry.timerExpired = TRUE; + insertInClientList = TRUE; + } + if(statsMask & (1 << eCsrGlobalClassDStats)) + { + pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); + if (NULL != pTlStats) + { + //req TL for class D stats + if(!VOS_IS_STATUS_SUCCESS(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId))) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:couldn't get the stats from TL")); + } + else + { + //save in SME + csrRoamSaveStatsFromTl(pMac, pTlStats); + } + vos_mem_free(pTlStats); + pTlStats = NULL; + } + else + { + smsLog(pMac, LOGE, FL("cannot allocate memory for TL stat")); + } + + } + //if looking for stats from TL only + if(!insertInClientList) + { + //return the stats + csrRoamReportStatistics(pMac, statsMask, callback, staId, pContext); + } + } + if(insertInClientList) + { + pStaEntry = csrRoamInsertEntryIntoList(pMac, &pMac->roam.statsClientReqList, &staEntry); + if(!pStaEntry) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: Failed to insert req in statsClientReqList"); + return eHAL_STATUS_FAILURE; + } + pStaEntry->periodicity = periodicity; + //Init & start timer if needed + if(periodicity) + { + vosStatus = vos_timer_init( &pStaEntry->timer, VOS_TIMER_TYPE_SW, + csrRoamStatsClientTimerHandler, pStaEntry ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot init StatsClient timer")); + return eHAL_STATUS_FAILURE; + } + vosStatus = vos_timer_start( &pStaEntry->timer, periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot start StatsClient timer")); + return eHAL_STATUS_FAILURE; + } + } + } + } + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +static tSirRetStatus +csrRoamScanOffloadPopulateMacHeader(tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, + tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /* Prepare MAC management header */ + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + /* Prepare FC */ + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + /* Prepare Address 1 */ + vos_mem_copy((tANI_U8 *) pMacHdr->da, (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + /* Prepare Address 3 */ + vos_mem_copy((tANI_U8 *) pMacHdr->bssId, (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + return statusCode; +} /*** csrRoamScanOffloadPopulateMacHeader() ***/ + +static tSirRetStatus +csrRoamScanOffloadPrepareProbeReqTemplate(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tANI_U32 dot11mode, + tSirMacAddr selfMacAddr, + tANI_U8 *pFrame, + tANI_U16 *pusLen, + tCsrRoamSession *psession) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + /*Bcast tx*/ + tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + PopulateDot11fSuppRates( pMac, nChannelNum, &pr.SuppRates,NULL); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + + + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, NULL, &pr.HTCaps ); + pr.HTCaps.advCodingCap = psession->htConfig.ht_rx_ldpc; + pr.HTCaps.txSTBC = psession->htConfig.ht_tx_stbc; + pr.HTCaps.rxSTBC = psession->htConfig.ht_rx_stbc; + if (!psession->htConfig.ht_sgi) { + pr.HTCaps.shortGI20MHz = pr.HTCaps.shortGI40MHz = 0; + } + } + + + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to calculate the packed size f" + "or a Probe Request (0x%08x).\n", nStatus ); + + + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x).\n", nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + /* Prepare outgoing frame*/ + vos_mem_set(pFrame, nBytes , 0); + + + nSirStatus = csrRoamScanOffloadPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssId,selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to populate the buffer descriptor for a Probe Request (%d).\n", + nSirStatus ); + return nSirStatus; + } + + + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to pack a Probe Request (0x%08x).\n", nStatus ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while packing a Probe Request (0x%08x).\n", + nStatus ); + } + + *pusLen = nPayload + sizeof(tSirMacMgmtHdr); + return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrRoamSetKeyMgmtOffload(tpAniSirGlobal pMac, + tANI_U32 sessionId, + v_BOOL_t nRoamKeyMgmtOffloadEnabled) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + pSession->RoamKeyMgmtOffloadEnabled = nRoamKeyMgmtOffloadEnabled; + return eHAL_STATUS_SUCCESS; +} + +void csrRoamOffload(tpAniSirGlobal pMac, tSirRoamOffloadScanReq *pRequestBuf, + tCsrRoamSession *pSession) +{ + vos_mem_copy(pRequestBuf->PSK_PMK, pSession->psk_pmk, + sizeof(pRequestBuf->PSK_PMK)); + pRequestBuf->pmk_len = pSession->pmk_len; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3: PMK Length = %d", pRequestBuf->pmk_len); + pRequestBuf->R0KH_ID_Length = pSession->ftSmeContext.r0kh_id_len; + vos_mem_copy(pRequestBuf->R0KH_ID, pSession->ftSmeContext.r0kh_id, + pRequestBuf->R0KH_ID_Length); + pRequestBuf->Prefer5GHz = pMac->roam.configParam.nRoamPrefer5GHz; + pRequestBuf->RoamRssiCatGap = pMac->roam.configParam.bCatRssiOffset; + pRequestBuf->Select5GHzMargin = pMac->roam.configParam.nSelect5GHzMargin; + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *)&pRequestBuf->ReassocFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error and set some default value + */ + smsLog(pMac, LOGE, FL("could not retrieve ReassocFailureTimeout value")); + pRequestBuf->ReassocFailureTimeout = DEFAULT_REASSOC_FAILURE_TIMEOUT; + } +#ifdef FEATURE_WLAN_ESE + if (csrIsAuthTypeESE(pRequestBuf->ConnectedNetwork.authentication)) { + vos_mem_copy(pRequestBuf->KRK,pSession->eseCckmInfo.krk, SIR_KRK_KEY_LEN); + vos_mem_copy(pRequestBuf->BTK,pSession->eseCckmInfo.btk, SIR_BTK_KEY_LEN); + } +#endif + pRequestBuf->AcUapsd.acbe_uapsd = + SIR_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + pRequestBuf->AcUapsd.acbk_uapsd = + SIR_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + pRequestBuf->AcUapsd.acvi_uapsd = + SIR_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + pRequestBuf->AcUapsd.acvo_uapsd = + SIR_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); +} +#endif + +eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, + tANI_U8 command, tANI_U8 reason) +{ + vos_msg_t msg; + tSirRoamOffloadScanReq *pRequestBuf; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrRoamSession *pSession; + tANI_U8 i,j,num_channels = 0, ucDot11Mode; + tANI_U8 *ChannelList = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrChannelInfo currChannelListInfo; + tANI_U32 host_channels = 0; + eCsrBand eBand; + tANI_U8 ChannelCacheStr[128] = {0}; + currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:pSession is null", __func__); + return eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress + && (ROAM_SCAN_OFFLOAD_STOP == command)) + { + /* When roam synch is in progress for propagation, there is no + * need to send down the STOP command since the firmware is not + * expecting any WMI commands when the roam synch is in progress.*/ + bRoamScanOffloadStarted = VOS_FALSE; + return eHAL_STATUS_SUCCESS; + } +#endif + if (0 == csrRoamIsRoamOffloadScanEnabled(pMac)) + { + smsLog( pMac, LOGE,"isRoamOffloadScanEnabled not set"); + return eHAL_STATUS_FAILURE; + } + + if ((VOS_TRUE == bRoamScanOffloadStarted) && (ROAM_SCAN_OFFLOAD_START == command)) + { + smsLog( pMac, LOGE,"Roam Scan Offload is already started"); + return eHAL_STATUS_FAILURE; + } + /*The Dynamic Config Items Update may happen even if the state is in INIT. + * It is important to ensure that the command is passed down to the FW only + * if the Infra Station is in a connected state.A connected station could also be + * in a PREAUTH or REASSOC states.So, consider not sending the command down in INIT state. + * We also have to ensure that if there is a STOP command we always have to inform Riva, + * irrespective of whichever state we are in.*/ + + if ((pMac->roam.neighborRoamInfo[sessionId].neighborRoamState == + eCSR_NEIGHBOR_ROAM_STATE_INIT) && + (command != ROAM_SCAN_OFFLOAD_STOP)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Scan Command not sent to FW with state = %s and cmd=%d"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState), command); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirRoamOffloadScanReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to allocate memory for Roam Offload scan request)")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pRequestBuf, sizeof(tSirRoamOffloadScanReq)); + /* If command is STOP, then pass down ScanOffloadEnabled as Zero.This will handle the case of + * host driver reloads, but Riva still up and running*/ + if(command == ROAM_SCAN_OFFLOAD_STOP) + pRequestBuf->RoamScanOffloadEnabled = 0; + else + pRequestBuf->RoamScanOffloadEnabled = pMac->roam.configParam.isRoamOffloadScanEnabled; + vos_mem_copy(pRequestBuf->ConnectedNetwork.currAPbssid, + pNeighborRoamInfo->currAPbssid, + sizeof(tCsrBssid)); + pRequestBuf->ConnectedNetwork.ssId.length = + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length; + vos_mem_copy(pRequestBuf->ConnectedNetwork.ssId.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.ssId, + pRequestBuf->ConnectedNetwork.ssId.length); + pRequestBuf->ConnectedNetwork.authentication = + pMac->roam.roamSession[sessionId].connectedProfile.AuthType; + pRequestBuf->ConnectedNetwork.encryption = + pMac->roam.roamSession[sessionId].connectedProfile.EncryptionType; + pRequestBuf->ConnectedNetwork.mcencryption = + pMac->roam.roamSession[sessionId].connectedProfile.mcEncryptionType; + pRequestBuf->LookupThreshold = + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1); + pRequestBuf->delay_before_vdev_stop = + pNeighborRoamInfo->cfgParams.delay_before_vdev_stop; + pRequestBuf->OpportunisticScanThresholdDiff = + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff; + pRequestBuf->RoamRescanRssiDiff = + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff; + pRequestBuf->RoamRssiDiff = + pMac->roam.configParam.RoamRssiDiff; + pRequestBuf->Command = command; + pRequestBuf->StartScanReason = reason; + pRequestBuf->NeighborScanTimerPeriod = + pNeighborRoamInfo->cfgParams.neighborScanPeriod; + pRequestBuf->NeighborRoamScanRefreshPeriod = + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod; + pRequestBuf->NeighborScanChannelMinTime = + pNeighborRoamInfo->cfgParams.minChannelScanTime; + pRequestBuf->NeighborScanChannelMaxTime = + pNeighborRoamInfo->cfgParams.maxChannelScanTime; + pRequestBuf->EmptyRefreshScanPeriod = + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod; + pRequestBuf->RoamBmissFirstBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt; + pRequestBuf->RoamBmissFinalBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt; + pRequestBuf->RoamBeaconRssiWeight = + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight; + /* MAWC feature */ + pRequestBuf->MAWCEnabled = + pMac->roam.configParam.MAWCEnabled; +#ifdef FEATURE_WLAN_ESE + pRequestBuf->IsESEAssoc = csrNeighborRoamIsESEAssoc(pMac, sessionId) && + ((pRequestBuf->ConnectedNetwork.authentication == + eCSR_AUTH_TYPE_OPEN_SYSTEM) || + (csrIsAuthTypeESE(pRequestBuf->ConnectedNetwork.authentication))); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:IsEseAssoc=%d\n", __func__, pRequestBuf->IsESEAssoc); +#endif + if ( +#ifdef FEATURE_WLAN_ESE + ((pNeighborRoamInfo->isESEAssoc) && + (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == + eANI_BOOLEAN_FALSE)) || + (pNeighborRoamInfo->isESEAssoc == eANI_BOOLEAN_FALSE) || +#endif // ESE + currChannelListInfo->numOfChannels == 0) { + /* Retrieve the Channel Cache either from ini or from the Occupied + * Channels list. Give Preference to INI Channels.*/ + if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) { + ChannelList = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList; + /* The INI channels need to be filtered with respect to the current + * band that is supported. */ + eBand = pMac->roam.configParam.bandCapability; + if ((eCSR_BAND_24 != eBand) && (eCSR_BAND_5G != eBand) && + (eCSR_BAND_ALL != eBand)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Invalid band, No operation carried out (Band %d)", eBand); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + for (i = 0; + i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; + i++) { + if (((eCSR_BAND_24 == eBand) && + CSR_IS_CHANNEL_24GHZ(*ChannelList)) || + ((eCSR_BAND_5G == eBand) && + CSR_IS_CHANNEL_5GHZ(*ChannelList)) || + (eCSR_BAND_ALL == eBand)) { + /* Allow DFS channels only if the DFS channel + * roam flag is enabled */ + if (((pMac->roam.configParam.allowDFSChannelRoam + != CSR_ROAMING_DFS_CHANNEL_DISABLED) || + (!CSR_IS_CHANNEL_DFS(*ChannelList))) && + csrRoamIsChannelValid(pMac, *ChannelList) && + *ChannelList && + (num_channels < SIR_ROAM_MAX_CHANNELS)) { + pRequestBuf->ConnectedNetwork.ChannelCache[ + num_channels++] = *ChannelList; + } + ChannelList++; + } + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + pRequestBuf->ChannelCacheType = CHANNEL_LIST_STATIC; + } else { + ChannelList = pMac->scan.occupiedChannels[sessionId].channelList; + for (i = 0; + i < pMac->scan.occupiedChannels[sessionId].numChannels; + i++) { + if(((pMac->roam.configParam.allowDFSChannelRoam + != CSR_ROAMING_DFS_CHANNEL_DISABLED) || + (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList && + (num_channels < SIR_ROAM_MAX_CHANNELS)) { + pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = + *ChannelList; + } + ChannelList++; + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + /* If the profile changes as to what it was earlier, inform the + * FW through FLUSH as ChannelCacheType in which case, + * the FW will flush the occupied channels for the earlier profile and + * try to learn them afresh.*/ + if (reason == REASON_FLUSH_CHANNEL_LIST) + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_FLUSH; + else { + if (csrNeighborRoamIsNewConnectedProfile(pMac, sessionId)) + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT; + else + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; + } + } + } +#ifdef FEATURE_WLAN_ESE + else + { + /* If ESE is enabled, and a neighbor Report is received,then + * Ignore the INI Channels or the Occupied Channel List. Consider + * the channels in the neighbor list sent by the ESE AP.*/ + if (currChannelListInfo->numOfChannels != 0) + { + ChannelList = currChannelListInfo->ChannelList; + for (i=0;inumOfChannels;i++) + { + if(((pMac->roam.configParam.allowDFSChannelRoam + != CSR_ROAMING_DFS_CHANNEL_DISABLED) || + (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList) + { + pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList; + } + ChannelList++; + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; + } + } +#endif + for (i = 0, j = 0; i < pRequestBuf->ConnectedNetwork.ChannelCount; i++) + { + if (j < sizeof(ChannelCacheStr)) + { + j += snprintf(ChannelCacheStr + j, sizeof(ChannelCacheStr) - j," %d", + pRequestBuf->ConnectedNetwork.ChannelCache[i]); + } + else + { + break; + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "ChnlCacheType:%d, No of Chnls:%d,Channels: %s", + pRequestBuf->ChannelCacheType, + pRequestBuf->ConnectedNetwork.ChannelCount, + ChannelCacheStr); + num_channels = 0; + ChannelList = NULL; + + /* Maintain the Valid Channels List*/ + host_channels = sizeof(pMac->roam.validChannelList); + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &host_channels))) + { + ChannelList = pMac->roam.validChannelList; + pMac->roam.numValidChannels = host_channels; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Failed to get the valid channel list", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + for(i=0; iroam.numValidChannels; i++) + { + if(((pMac->roam.configParam.allowDFSChannelRoam + != CSR_ROAMING_DFS_CHANNEL_DISABLED) || + (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList) + { + pRequestBuf->ValidChannelList[num_channels++] = *ChannelList; + } + ChannelList++; + } + pRequestBuf->ValidChannelCount = num_channels; + + pRequestBuf->MDID.mdiePresent = + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent; + pRequestBuf->MDID.mobilityDomain = + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mobilityDomain; + pRequestBuf->sessionId = sessionId; + pRequestBuf->nProbes = pMac->roam.configParam.nProbes; + + pRequestBuf->HomeAwayTime = pMac->roam.configParam.nRoamScanHomeAwayTime; + + /* Home Away Time should be at least equal to (MaxDwell time + (2*RFS)), + * where RFS is the RF Switching time. It is twice RFS to consider the + * time to go off channel and return to the home channel. */ + if (pRequestBuf->HomeAwayTime < (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)" + " Hence enforcing home away time to disable (0)", + __func__, pRequestBuf->HomeAwayTime, + (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME) + )); + pRequestBuf->HomeAwayTime = 0; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,"HomeAwayTime:%d",pRequestBuf->HomeAwayTime); + + /*Prepare a probe request for 2.4GHz band and one for 5GHz band*/ + ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, + csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + csrRoamScanOffloadPrepareProbeReqTemplate(pMac,SIR_ROAM_SCAN_24G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p24GProbeTemplate, + &pRequestBuf->us24GProbeTemplateLen, + pSession); + + csrRoamScanOffloadPrepareProbeReqTemplate(pMac,SIR_ROAM_SCAN_5G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p5GProbeTemplate, + &pRequestBuf->us5GProbeTemplateLen, + pSession); + pRequestBuf->allowDFSChannelRoam = pMac->roam.configParam.allowDFSChannelRoam; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + pRequestBuf->RoamOffloadEnabled = csrRoamIsRoamOffloadEnabled(pMac); + pRequestBuf->RoamKeyMgmtOffloadEnabled = pSession->RoamKeyMgmtOffloadEnabled; + /* Roam Offload piggybacks upon the Roam Scan offload command.*/ + if (pRequestBuf->RoamOffloadEnabled){ + csrRoamOffload(pMac, pRequestBuf, pSession); + } +#endif + msg.type = WDA_ROAM_SCAN_OFFLOAD_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_ROAM_SCAN_OFFLOAD_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + else + { + if (ROAM_SCAN_OFFLOAD_START == command) + bRoamScanOffloadStarted = VOS_TRUE; + else if (ROAM_SCAN_OFFLOAD_STOP == command) + bRoamScanOffloadStarted = VOS_FALSE; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Roam Scan Offload Command %d, Reason %d", command, reason); + return status; +} + +eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, + tpSirRoamOffloadScanRsp scanOffloadRsp) +{ + switch (scanOffloadRsp->reason) { + case 0: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "Rsp for Roam Scan Offload with failure status"); + break; + case REASON_OS_REQUESTED_ROAMING_NOW: + csrNeighborRoamProceedWithHandoffReq(pMac, + scanOffloadRsp->sessionId); + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Rsp for Roam Scan Offload with reason %d", + scanOffloadRsp->reason); + } + return eHAL_STATUS_SUCCESS; +} +#endif + +tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, + tANI_U32 statsMask, + tANI_U32 periodicity, + tANI_BOOLEAN *pFound, + tANI_U8 staId, + tANI_U8 sessionId) +{ + tANI_BOOLEAN found = FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrPeStatsReqInfo staEntry; + tCsrPeStatsReqInfo *pTempStaEntry = NULL; + tListElem *pStaEntry = NULL; + VOS_STATUS vosStatus; + tPmcPowerState powerState; + *pFound = FALSE; + + pStaEntry = csrRoamFindInPeStatsReqList(pMac, statsMask); + if(pStaEntry) + { + pTempStaEntry = GET_BASE_ADDR( pStaEntry, tCsrPeStatsReqInfo, link ); + if(pTempStaEntry->periodicity) + { + pTempStaEntry->periodicity = + CSR_ROAM_MIN(periodicity, pTempStaEntry->periodicity); + } + else + { + pTempStaEntry->periodicity = periodicity; + } + pTempStaEntry->numClient++; + found = TRUE; + } + else + { + vos_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0); + staEntry.numClient = 1; + staEntry.periodicity = periodicity; + staEntry.pMac = pMac; + staEntry.rspPending = FALSE; + staEntry.staId = staId; + staEntry.statsMask = statsMask; + staEntry.timerRunning = FALSE; + staEntry.sessionId = sessionId; + pTempStaEntry = csrRoamInsertEntryIntoPeStatsReqList(pMac, &pMac->roam.peStatsReqList, &staEntry); + if(!pTempStaEntry) + { + //msg + smsLog(pMac, LOGW, "csrRoamCheckPeStatsReqList: Failed to insert req in peStatsReqList"); + return NULL; + } + } + pmcQueryPowerState(pMac, &powerState, NULL, NULL); + if(ePMC_FULL_POWER == powerState) + { + if(pTempStaEntry->periodicity < pMac->roam.configParam.statsReqPeriodicity) + { + pTempStaEntry->periodicity = pMac->roam.configParam.statsReqPeriodicity; + } + } + else + { + if(pTempStaEntry->periodicity < pMac->roam.configParam.statsReqPeriodicityInPS) + { + pTempStaEntry->periodicity = pMac->roam.configParam.statsReqPeriodicityInPS; + } + } + if(!pTempStaEntry->timerRunning) + { + //send down a req in case of one time req, for periodic ones wait for timer to expire + if(!pTempStaEntry->rspPending && + !pTempStaEntry->periodicity) + { + status = csrSendMBStatsReqMsg(pMac, + statsMask & ~(1 << eCsrGlobalClassDStats), + staId, + sessionId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:failed to send down stats req to PE")); + } + else + { + pTempStaEntry->rspPending = TRUE; + } + } + if(pTempStaEntry->periodicity) + { + if(!found) + { + + vosStatus = vos_timer_init( &pTempStaEntry->hPeStatsTimer, VOS_TIMER_TYPE_SW, + csrRoamPeStatsTimerHandler, pTempStaEntry ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:cannot init hPeStatsTimer timer")); + return NULL; + } + } + //start timer + smsLog(pMac, LOG1, "csrRoamCheckPeStatsReqList:peStatsTimer period %d", pTempStaEntry->periodicity); + vosStatus = vos_timer_start( &pTempStaEntry->hPeStatsTimer, pTempStaEntry->periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:cannot start hPeStatsTimer timer")); + return NULL; + } + pTempStaEntry->timerRunning = TRUE; + } + } + *pFound = found; + return pTempStaEntry; +} + +/* + pStaEntry is no longer invalid upon the return of this function. +*/ +static void csrRoamRemoveStatListEntry(tpAniSirGlobal pMac, tListElem *pEntry) +{ + if(pEntry) + { + if(csrLLRemoveEntry(&pMac->roam.statsClientReqList, pEntry, LL_ACCESS_LOCK)) + { + vos_mem_free(GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link )); + } + } + } + +void csrRoamRemoveEntryFromPeStatsReqList(tpAniSirGlobal pMac, tCsrPeStatsReqInfo *pPeStaEntry) +{ + tListElem *pEntry; + tCsrPeStatsReqInfo *pTempStaEntry; + VOS_STATUS vosStatus; + pEntry = csrLLPeekHead( &pMac->roam.peStatsReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOGE, FL(" List empty, no stats req for PE")); + return; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + if( pTempStaEntry && pTempStaEntry->statsMask == pPeStaEntry->statsMask) + { + smsLog(pMac, LOGW, FL("Match found")); + if(pTempStaEntry->timerRunning) + { + vosStatus = vos_timer_stop( &pTempStaEntry->hPeStatsTimer ); + /* If we are not able to stop the timer here, just remove + * the entry from the linked list. Destroy the timer object + * and free the memory in the timer CB + */ + if ( vosStatus == VOS_STATUS_SUCCESS ) + { + /* the timer is successfully stopped */ + pTempStaEntry->timerRunning = FALSE; + + /* Destroy the timer */ + vosStatus = vos_timer_destroy( &pTempStaEntry->hPeStatsTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamRemoveEntryFromPeStatsReqList:failed to destroy hPeStatsTimer timer")); + } + } + else + { + // the timer could not be stopped. Hence destroy and free the + // memory for the PE stat entry in the timer CB. + pTempStaEntry->timerStopFailed = TRUE; + } + } + + if(csrLLRemoveEntry(&pMac->roam.peStatsReqList, pEntry, LL_ACCESS_LOCK)) + { + // Only free the memory if we could stop the timer successfully + if(!pTempStaEntry->timerStopFailed) + { + vos_mem_free(pTempStaEntry); + pTempStaEntry = NULL; + } + break; + } + + pEntry = csrLLNext( &pMac->roam.peStatsReqList, pEntry, LL_ACCESS_NOLOCK ); + } + } + return; +} + + +void csrRoamSaveStatsFromTl(tpAniSirGlobal pMac, WLANTL_TRANSFER_STA_TYPE *pTlStats) +{ + + pMac->roam.classDStatsInfo.num_rx_bytes_crc_ok = pTlStats->rxBcntCRCok; + pMac->roam.classDStatsInfo.rx_bc_byte_cnt = pTlStats->rxBCBcnt; + pMac->roam.classDStatsInfo.rx_bc_frm_cnt = pTlStats->rxBCFcnt; + pMac->roam.classDStatsInfo.rx_byte_cnt = pTlStats->rxBcnt; + pMac->roam.classDStatsInfo.rx_mc_byte_cnt = pTlStats->rxMCBcnt; + pMac->roam.classDStatsInfo.rx_mc_frm_cnt = pTlStats->rxMCFcnt; + pMac->roam.classDStatsInfo.rx_rate = pTlStats->rxRate; + //?? need per AC + pMac->roam.classDStatsInfo.rx_uc_byte_cnt[0] = pTlStats->rxUCBcnt; + pMac->roam.classDStatsInfo.rx_uc_frm_cnt = pTlStats->rxUCFcnt; + pMac->roam.classDStatsInfo.tx_bc_byte_cnt = pTlStats->txBCBcnt; + pMac->roam.classDStatsInfo.tx_bc_frm_cnt = pTlStats->txBCFcnt; + pMac->roam.classDStatsInfo.tx_mc_byte_cnt = pTlStats->txMCBcnt; + pMac->roam.classDStatsInfo.tx_mc_frm_cnt = pTlStats->txMCFcnt; + //?? need per AC + pMac->roam.classDStatsInfo.tx_uc_byte_cnt[0] = pTlStats->txUCBcnt; + pMac->roam.classDStatsInfo.tx_uc_frm_cnt = pTlStats->txUCFcnt; + +} + +void csrRoamReportStatistics(tpAniSirGlobal pMac, tANI_U32 statsMask, + tCsrStatsCallback callback, tANI_U8 staId, void *pContext) +{ + tANI_U8 stats[500]; + tANI_U8 *pStats = NULL; + tANI_U32 tempMask = 0; + tANI_U8 counter = 0; + if(!callback) + { + smsLog(pMac, LOGE, FL("Cannot report callback NULL")); + return; + } + if(!statsMask) + { + smsLog(pMac, LOGE, FL("Cannot report statsMask is 0")); + return; + } + pStats = stats; + tempMask = statsMask; + while(tempMask) + { + if(tempMask & 1) + { + //new stats info from PE, fill up the stats strucutres in PMAC + switch(counter) + { + case eCsrSummaryStats: + smsLog( pMac, LOG2, FL("Summary stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.summaryStatsInfo, + sizeof(tCsrSummaryStatsInfo)); + pStats += sizeof(tCsrSummaryStatsInfo); + break; + case eCsrGlobalClassAStats: + smsLog( pMac, LOG2, FL("ClassA stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classAStatsInfo, + sizeof(tCsrGlobalClassAStatsInfo)); + pStats += sizeof(tCsrGlobalClassAStatsInfo); + break; + case eCsrGlobalClassBStats: + smsLog( pMac, LOG2, FL("ClassB stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classBStatsInfo, + sizeof(tCsrGlobalClassBStatsInfo)); + pStats += sizeof(tCsrGlobalClassBStatsInfo); + break; + case eCsrGlobalClassCStats: + smsLog( pMac, LOG2, FL("ClassC stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classCStatsInfo, + sizeof(tCsrGlobalClassCStatsInfo)); + pStats += sizeof(tCsrGlobalClassCStatsInfo); + break; + case eCsrGlobalClassDStats: + smsLog( pMac, LOG2, FL("ClassD stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classDStatsInfo, + sizeof(tCsrGlobalClassDStatsInfo)); + pStats += sizeof(tCsrGlobalClassDStatsInfo); + break; + case eCsrPerStaStats: + smsLog( pMac, LOG2, FL("PerSta stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.perStaStatsInfo[staId], + sizeof(tCsrPerStaStatsInfo)); + pStats += sizeof(tCsrPerStaStatsInfo); + break; + default: + smsLog( pMac, LOGE, FL("Unknown stats type and counter %d"), counter); + break; + } + } + tempMask >>=1; + counter++; + } + callback(stats, pContext ); +} + +eHalStatus csrRoamDeregStatisticsReq(tpAniSirGlobal pMac) +{ + tListElem *pEntry = NULL; + tListElem *pPrevEntry = NULL; + tCsrStatsClientReqInfo *pTempStaEntry = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOGW, "csrRoamDeregStatisticsReq: List empty, no request from " + "upper layer client(s)"); + return status; + } + while( pEntry ) + { + if(pPrevEntry) + { + pTempStaEntry = GET_BASE_ADDR( pPrevEntry, tCsrStatsClientReqInfo, link ); + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + csrRoamRemoveStatListEntry(pMac, pPrevEntry); + } + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if (pTempStaEntry->pPeStaEntry) //pPeStaEntry can be NULL + { + pTempStaEntry->pPeStaEntry->numClient--; + //check if we need to delete the entry from peStatsReqList too + if(!pTempStaEntry->pPeStaEntry->numClient) + { + csrRoamRemoveEntryFromPeStatsReqList(pMac, pTempStaEntry->pPeStaEntry); + } + } + //check if we need to stop the tl stats timer too + pMac->roam.tlStatsReqInfo.numClient--; + if(!pMac->roam.tlStatsReqInfo.numClient) + { + if(pMac->roam.tlStatsReqInfo.timerRunning) + { + status = vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamDeregStatisticsReq:cannot stop TlStatsTimer timer")); + //we will continue + } + } + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + } + if (pTempStaEntry->periodicity) + { + //While creating StaEntry in csrGetStatistics, + //Initializing and starting timer only when periodicity is set. + //So Stop and Destroy timer only when periodicity is set. + + vos_timer_stop( &pTempStaEntry->timer ); + // Destroy the vos timer... + vosStatus = vos_timer_destroy( &pTempStaEntry->timer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamDeregStatisticsReq:failed to destroy Client req timer")); + } + } + + + pPrevEntry = pEntry; + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + //the last one + if(pPrevEntry) + { + pTempStaEntry = GET_BASE_ADDR( pPrevEntry, tCsrStatsClientReqInfo, link ); + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + csrRoamRemoveStatListEntry(pMac, pPrevEntry); + } + return status; + +} + +eHalStatus csrIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower ) +{ + tANI_BOOLEAN fNeedFullPower = eANI_BOOLEAN_FALSE; + tRequestFullPowerReason reason = eSME_REASON_OTHER; + tPmcState pmcState; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId = 0; + if( pfNeedPower ) + { + *pfNeedPower = eANI_BOOLEAN_FALSE; + } + //We only handle CSR commands + if( !(eSmeCsrCommandMask & pCommand->command) ) + { + return eHAL_STATUS_SUCCESS; + } + //Check PMC state first + pmcState = pmcGetPmcState( pMac ); + switch( pmcState ) + { + case REQUEST_IMPS: + case IMPS: + if( eSmeCommandScan == pCommand->command ) + { + switch( pCommand->u.scanCmd.reason ) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + //Internal process, no need for full power + fNeedFullPower = eANI_BOOLEAN_FALSE; + break; + default: + //Other scans are real scan, ask for power + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + } //switch + } + else + { + //ask for power for roam and status change + fNeedFullPower = eANI_BOOLEAN_TRUE; + } + break; + case REQUEST_BMPS: + case BMPS: + case REQUEST_START_UAPSD: + case UAPSD: + //We treat WOWL same as BMPS + case REQUEST_ENTER_WOWL: + case WOWL: + if( eSmeCommandRoam == pCommand->command ) + { + tScanResultList *pBSSList = (tScanResultList *)pCommand->u.roamCmd.hBSSList; + tCsrScanResult *pScanResult; + tListElem *pEntry; + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + case eCsrForcedDisassocMICFailure: + reason = eSME_LINK_DISCONNECTED_BY_HDD; + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + case eCsrSmeIssuedDisassocForHandoff: + case eCsrForcedDeauth: + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + case eCsrCapsChange: + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + default: + //Check whether the profile is already connected. If so, no need for full power + //Note: IBSS is ignored for now because we don't support powersave in IBSS + if ( csrIsConnStateConnectedInfra(pMac, sessionId) && pBSSList ) + { + //Only need to check the first one + pEntry = csrLLPeekHead(&pBSSList->List, LL_ACCESS_LOCK); + if( pEntry ) + { + pScanResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + } + } + //If we are here, full power is needed + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + } + } + else if( eSmeCommandWmStatusChange == pCommand->command ) + { + //need full power for all + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_LINK_DISCONNECTED_BY_OTHER; + } +#ifdef FEATURE_WLAN_TDLS + else if( eSmeCommandTdlsAddPeer == pCommand->command ) + { + //TDLS link is getting established. need full power + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_FULL_PWR_NEEDED_BY_TDLS_PEER_SETUP; + } +#endif + break; + case REQUEST_STOP_UAPSD: + case REQUEST_EXIT_WOWL: + if( eSmeCommandRoam == pCommand->command ) + { + fNeedFullPower = eANI_BOOLEAN_TRUE; + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + case eCsrForcedDisassocMICFailure: + reason = eSME_LINK_DISCONNECTED_BY_HDD; + break; + default: + break; + } + } + break; + case STOPPED: + case REQUEST_STANDBY: + case STANDBY: + case LOW_POWER: + //We are not supposed to do anything + smsLog( pMac, LOGE, FL( " cannot process because PMC is in stopped/standby state %d" ), pmcState ); + status = eHAL_STATUS_FAILURE; + break; + case FULL_POWER: + case REQUEST_FULL_POWER: + default: + //No need to ask for full power. This has to be FULL_POWER state + break; + } //switch + if( pReason ) + { + *pReason = reason; + } + if( pfNeedPower ) + { + *pfNeedPower = fNeedFullPower; + } + return ( status ); +} + +eHalStatus csrPsOffloadIsFullPowerNeeded(tpAniSirGlobal pMac, + tSmeCmd *pCommand, + tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower) +{ + tANI_BOOLEAN fNeedFullPower = eANI_BOOLEAN_FALSE; + tRequestFullPowerReason reason = eSME_REASON_OTHER; + tPmcState pmcState; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pfNeedPower) + { + *pfNeedPower = eANI_BOOLEAN_FALSE; + } + + /* We only handle CSR commands */ + if(!(eSmeCsrCommandMask & pCommand->command)) + { + return eHAL_STATUS_SUCCESS; + } + + /* + * No need to request for full power for the following commands + * Scan Related Command + * IMPS is handled in Fw so no need + */ + if(eSmeCommandScan == pCommand->command) + { + return eHAL_STATUS_SUCCESS; + } + + /* + * Check PMC state first + * Commands which require Full Power + * 1) eSmeCommandRoam + * -----eCsrForcedDisassoc + * -----eCsrForcedDisassocMICFailure + * -----eCsrSmeIssuedDisassocForHandoff + * -----eCsrForcedDeauth + * -----eCsrHddIssuedReassocToSameAP + * -----eCsrSmeIssuedReassocToSameAP + * -----eCsrCapsChange + * -----AddTs + * -----DelTs + * ----- etc + * 2) eSmeCommandWmStatusChange + * 3) eSmeCommandTdlsAddPeer + */ + pmcState = pmcOffloadGetPmcState(pMac, pCommand->sessionId); + switch(pmcState) + { + case REQUEST_BMPS: + case BMPS: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case UAPSD: + if(eSmeCommandRoam == pCommand->command) + { + switch (pCommand->u.roamCmd.roamReason) + { + case eCsrForcedDisassoc: + case eCsrForcedDisassocMICFailure: + reason = eSME_LINK_DISCONNECTED_BY_HDD; + case eCsrSmeIssuedDisassocForHandoff: + case eCsrForcedDeauth: + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + case eCsrCapsChange: + default: + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + } + } + else if(eSmeCommandWmStatusChange == pCommand->command) + { + /* need full power for all */ + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_LINK_DISCONNECTED_BY_OTHER; + } +#ifdef FEATURE_WLAN_TDLS + else if(eSmeCommandTdlsAddPeer == pCommand->command) + { + /* TDLS link is getting established. need full power */ + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_FULL_PWR_NEEDED_BY_TDLS_PEER_SETUP; + } +#endif + break; + case STOPPED: + /* We are not supposed to do anything */ + smsLog( pMac, LOGE, + FL("cannot process because PMC is in stopped/standby state %d"), + pmcState ); + status = eHAL_STATUS_FAILURE; + break; + default: + /* No need to ask for full power. This has to be FULL_POWER state */ + break; + } + + if(pReason) + { + *pReason = reason; + } + if(pfNeedPower) + { + *pfNeedPower = fNeedFullPower; + } + return status; +} + +static eHalStatus csrRequestFullPower( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fNeedFullPower = eANI_BOOLEAN_FALSE; + tRequestFullPowerReason reason = eSME_REASON_OTHER; + + if(pMac->psOffloadEnabled) + status = csrPsOffloadIsFullPowerNeeded(pMac, pCommand, + &reason, &fNeedFullPower); + else + status = csrIsFullPowerNeeded(pMac, pCommand, &reason, + &fNeedFullPower); + + if( fNeedFullPower && HAL_STATUS_SUCCESS( status ) ) + { + if(!pMac->psOffloadEnabled) + { + status = pmcRequestFullPower(pMac, csrFullPowerCallback, + pMac, reason); + } + else + { + status = pmcOffloadRequestFullPower(pMac, pCommand->sessionId, + csrFullPowerOffloadCallback, + pMac, reason); + } + + } + return ( status ); +} + +tSmeCmd *csrGetCommandBuffer( tpAniSirGlobal pMac ) +{ + tSmeCmd *pCmd = smeGetCommandBuffer( pMac ); + if( pCmd ) + { + pMac->roam.sPendingCommands++; + } + return ( pCmd ); +} + +void csrReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + if (pMac->roam.sPendingCommands > 0) + { + //All command allocated through csrGetCommandBuffer need to + //decrement the pending count when releasing. + pMac->roam.sPendingCommands--; + smeReleaseCommand( pMac, pCommand ); + } + else + { + smsLog(pMac, LOGE, FL( "no pending commands")); + VOS_ASSERT(0); + } +} + +//Return SUCCESS is the command is queued, failed +eHalStatus csrQueueSmeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fHighPriority ) +{ + eHalStatus status; + + if( (eSmeCommandScan == pCommand->command) && pMac->scan.fDropScanCmd ) + { + smsLog(pMac, LOGW, FL(" drop scan (scan reason %d) command"), + pCommand->u.scanCmd.reason); + return eHAL_STATUS_CSR_WRONG_STATE; + } + + if (((pMac->fScanOffload) && (pCommand->command == eSmeCommandScan)) || + ((pMac->fP2pListenOffload) && + (pCommand->command == eSmeCommandRemainOnChannel))) + { + csrLLInsertTail(&pMac->sme.smeScanCmdPendingList, + &pCommand->Link, LL_ACCESS_LOCK); + // process the command queue... + smeProcessPendingQueue(pMac); + status = eHAL_STATUS_SUCCESS; + goto end; + } + + //We can call request full power first before putting the command into pending Q + //because we are holding SME lock at this point. + status = csrRequestFullPower( pMac, pCommand ); + if( HAL_STATUS_SUCCESS( status ) ) + { + tANI_BOOLEAN fNoCmdPending; + //make sure roamCmdPendingList is not empty first + fNoCmdPending = csrLLIsListEmpty( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_FALSE ); + if( fNoCmdPending ) + { + smePushCommand( pMac, pCommand, fHighPriority ); + } + else + { + //Other commands are waiting for PMC callback, queue the new command to the pending Q + //no list lock is needed since SME lock is held + if( !fHighPriority ) + { + csrLLInsertTail( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + else { + csrLLInsertHead( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + } + } + else if( eHAL_STATUS_PMC_PENDING == status ) + { + //no list lock is needed since SME lock is held + if( !fHighPriority ) + { + csrLLInsertTail( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + else { + csrLLInsertHead( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + //Let caller know the command is queue + status = eHAL_STATUS_SUCCESS; + } + else + { + //Not to decrease pMac->roam.sPendingCommands here. Caller will decrease it when it + //release the command. + smsLog( pMac, LOGE, FL( " cannot queue command %d" ), pCommand->command ); + } +end: + return ( status ); +} +eHalStatus csrRoamUpdateAPWPSIE( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirAPWPSIEs* pAPWPSIES ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirUpdateAPWPSIEsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + pMsg = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof(tSirUpdateAPWPSIEsReq), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_UPDATE_APWPSIE_REQ); + + pBuf = (tANI_U8 *)&pMsg->transactionId; + + if (NULL == pBuf) + { + VOS_ASSERT(pBuf); + return eHAL_STATUS_FAILURE; + } + + wTmpBuf = pBuf; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr) ); + pBuf += sizeof(tSirMacAddr); + //sessionId + *pBuf++ = (tANI_U8)sessionId; + // APWPSIEs + vos_mem_copy((tSirAPWPSIEs *)pBuf, pAPWPSIES, sizeof(tSirAPWPSIEs)); + pBuf += sizeof(tSirAPWPSIEs); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32) + (pBuf - wTmpBuf))); //msg_header + msg + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return ( status ); +} +eHalStatus csrRoamUpdateWPARSNIEs( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirRSNie * pAPSirRSNie) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirUpdateAPWPARSNIEsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + do + { + pMsg = vos_mem_malloc(sizeof(tSirUpdateAPWPARSNIEsReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirUpdateAPWPARSNIEsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_APWPARSNIEs_REQ); + pBuf = (tANI_U8 *)&pMsg->transactionId; + wTmpBuf = pBuf; + + if (NULL == pBuf) + { + VOS_ASSERT(pBuf); + return eHAL_STATUS_FAILURE; + } + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // sessionId + *pBuf++ = (tANI_U8)sessionId; + + // APWPARSNIEs + vos_mem_copy((tSirRSNie *)pBuf, pAPSirRSNie, sizeof(tSirRSNie)); + pBuf += sizeof(tSirRSNie); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf))); //msg_header + msg + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return ( status ); +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +eHalStatus +csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, + tpSirBssDescription pBssDescription) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpSirFTPreAuthReq pftPreAuthReq; + tANI_U16 auth_req_len = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (NULL == pSession) { + smsLog(pMac, LOGE, + FL("Session does not exist for session id(%d)"), sessionId); + return eHAL_STATUS_FAILURE; + } + + auth_req_len = sizeof(tSirFTPreAuthReq); + pftPreAuthReq = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len); + if (NULL == pftPreAuthReq) + { + smsLog(pMac, LOGE, + FL("Memory allocation for FT Preauth request failed")); + return eHAL_STATUS_RESOURCES; + } + // Save the SME Session ID here. We need it while processing the preauth response + pSession->ftSmeContext.smeSessionId = sessionId; + vos_mem_zero(pftPreAuthReq, auth_req_len); + + pftPreAuthReq->pbssDescription = (tpSirBssDescription)vos_mem_malloc( + sizeof(pBssDescription->length) + pBssDescription->length); + if (NULL == pftPreAuthReq->pbssDescription) + { + smsLog(pMac, LOGE, + FL("Memory allocation for FT Preauth request failed")); + vos_mem_free(pftPreAuthReq); + return eHAL_STATUS_RESOURCES; + } + + pftPreAuthReq->messageType = pal_cpu_to_be16(eWNI_SME_FT_PRE_AUTH_REQ); + + pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId; + + vos_mem_copy((void *)&pftPreAuthReq->currbssId, + (void *)pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + vos_mem_copy((void *)&pftPreAuthReq->preAuthbssId, + (void *)pBssDescription->bssId, sizeof(tSirMacAddr)); + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac, sessionId) && + (pMac->roam.roamSession[sessionId].connectedProfile.AuthType != eCSR_AUTH_TYPE_OPEN_SYSTEM)) + { + pftPreAuthReq->ft_ies_length = + (tANI_U16)pSession->ftSmeContext.auth_ft_ies_length; + vos_mem_copy(pftPreAuthReq->ft_ies, pSession->ftSmeContext.auth_ft_ies, + pSession->ftSmeContext.auth_ft_ies_length); + } + else +#endif + { + pftPreAuthReq->ft_ies_length = 0; + } + vos_mem_copy(pftPreAuthReq->pbssDescription, pBssDescription, + sizeof(pBssDescription->length) + pBssDescription->length); + pftPreAuthReq->length = pal_cpu_to_be16(auth_req_len); + return palSendMBMessage(pMac->hHdd, pftPreAuthReq); +} +/*-------------------------------------------------------------------------- + * This will receive and process the FT Pre Auth Rsp from the current + * associated ap. + * + * This will invoke the hdd call back. This is so that hdd can now + * send the FTIEs from the Auth Rsp (Auth Seq 2) to the supplicant. + ------------------------------------------------------------------------*/ +void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuthRsp ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; +#if defined(FEATURE_WLAN_LFR) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrRoamInfo roamInfo; +#endif + eCsrAuthType conn_Auth_type; + tANI_U32 sessionId = pFTPreAuthRsp->smeSessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL")); + return; + } + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + status = csrNeighborRoamPreauthRspHandler(pMac, pFTPreAuthRsp->smeSessionId, + pFTPreAuthRsp->status); + if (status != eHAL_STATUS_SUCCESS) { + /* + * Bail out if pre-auth was not even processed. + */ + smsLog(pMac, LOGE,FL("Preauth was not processed: %d SessionID: %d"), + status, sessionId); + return; + } +#endif + + /* The below function calls/timers should be invoked only if the pre-auth is successful */ + if (VOS_STATUS_SUCCESS != (VOS_STATUS)pFTPreAuthRsp->status) + return; + // Implies a success + pSession->ftSmeContext.FTState = eFT_AUTH_COMPLETE; + // Indicate SME QoS module the completion of Preauth success. This will trigger the creation of RIC IEs + pSession->ftSmeContext.psavedFTPreAuthRsp = pFTPreAuthRsp; + /* No need to notify qos module if this is a non 11r roam*/ + if (csrRoamIs11rAssoc(pMac, pFTPreAuthRsp->smeSessionId)) + { + sme_QosCsrEventInd(pMac, + pSession->ftSmeContext.smeSessionId, + SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL); + } + /* Start the pre-auth reassoc interval timer with a period of 400ms. When this expires, + * actual transition from the current to handoff AP is triggered */ + status = vos_timer_start(&pSession->ftSmeContext.preAuthReassocIntvlTimer, + 60); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Preauth reassoc interval timer start failed to start with status %d"), status); + return; + } + // Save the received response + vos_mem_copy((void *)&pSession->ftSmeContext.preAuthbssId, + (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + if (csrRoamIs11rAssoc(pMac, pFTPreAuthRsp->smeSessionId)) + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, NULL, 0, + eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + if (csrRoamIsESEAssoc(pMac, pFTPreAuthRsp->smeSessionId)) + { + /* read TSF */ + csrRoamReadTSF(pMac, (tANI_U8 *)roamInfo.timestamp, + pFTPreAuthRsp->smeSessionId); + // Save the bssid from the received response + vos_mem_copy((void *)&roamInfo.bssid, + (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, &roamInfo, + 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY, 0); + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#ifdef FEATURE_WLAN_LFR + // If Legacy Fast Roaming is enabled, signal the supplicant + // So he can send us a PMK-ID for this candidate AP. + if (csrRoamIsFastRoamEnabled(pMac, pFTPreAuthRsp->smeSessionId)) + { + // Save the bssid from the received response + vos_mem_copy((void *)&roamInfo.bssid, + (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, &roamInfo, 0, eCSR_ROAM_PMK_NOTIFY, 0); + } + +#endif + + // If its an Open Auth, FT IEs are not provided by supplicant + // Hence populate them here + conn_Auth_type = + pMac->roam.roamSession[sessionId].connectedProfile.AuthType; + + pSession->ftSmeContext.addMDIE = FALSE; + if (csrRoamIs11rAssoc(pMac, pFTPreAuthRsp->smeSessionId) && + (conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) + { + tANI_U16 ft_ies_length; + ft_ies_length = pFTPreAuthRsp->ric_ies_length; + + if ( (pSession->ftSmeContext.reassoc_ft_ies) && + (pSession->ftSmeContext.reassoc_ft_ies_length)) + { + vos_mem_free(pSession->ftSmeContext.reassoc_ft_ies); + pSession->ftSmeContext.reassoc_ft_ies_length = 0; + pSession->ftSmeContext.reassoc_ft_ies = NULL; + } + + pSession->ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length); + if ( NULL == pSession->ftSmeContext.reassoc_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for ft_ies")); + return; + } + else + { + // Copy the RIC IEs to reassoc IEs + vos_mem_copy(((tANI_U8 *)pSession->ftSmeContext.reassoc_ft_ies), + (tANI_U8 *)pFTPreAuthRsp->ric_ies, + pFTPreAuthRsp->ric_ies_length); + pSession->ftSmeContext.reassoc_ft_ies_length = ft_ies_length; + pSession->ftSmeContext.addMDIE = TRUE; + } + } + + // Done with it, init it. + pSession->ftSmeContext.psavedFTPreAuthRsp = NULL; +} +#endif + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +void csrRoamJoinRetryTimerHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tANI_U32 sessionId = pInfo->sessionId; + tCsrRoamSession *pSession; + + if (CSR_IS_SESSION_VALID(pMac, sessionId) ) { + smsLog( pMac, LOGE, + FL("retrying the last roam profile on session %d" ), sessionId ); + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (pSession->pCurRoamProfile && + csrIsConnStateDisconnected(pMac, sessionId)) + { + if (!HAL_STATUS_SUCCESS(csrRoamJoinLastProfile(pMac, sessionId)) ) + { + smsLog( pMac, LOGE, + FL("fail to retry the last roam profile" ) ); + } + } + } +} +eHalStatus csrRoamStartJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U32 interval) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(pSession->pCurRoamProfile && pSession->maxRetryCount) + { + smsLog(pMac, LOGE, FL(" call sessionId %d retry count %d left"), + sessionId, pSession->maxRetryCount); + pSession->maxRetryCount--; + pSession->joinRetryTimerInfo.pMac = pMac; + pSession->joinRetryTimerInfo.sessionId = (tANI_U8)sessionId; + status = + vos_timer_start(&pSession->hTimerJoinRetry, + interval/VOS_TIMER_TO_MS_UNIT); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to start timer status %s"), status); + } + } + else + { + smsLog(pMac, LOGE, + FL("not to start timer due to no profile or reach mac ret (%d)"), + pSession->maxRetryCount); + } + + return (status); +} +eHalStatus csrRoamStopJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + smsLog(pMac, LOGE, " csrRoamStopJoinRetryTimer"); + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + return (vos_timer_stop( + &pMac->roam.roamSession[sessionId].hTimerJoinRetry)); + } + + return eHAL_STATUS_SUCCESS; +} +#endif + + +/* + pBuf points to the beginning of the message + LIM packs disassoc rsp as below, + messageType - 2 bytes + messageLength - 2 bytes + sessionId - 1 byte + transactionId - 2 bytes (tANI_U16) + reasonCode - 4 bytes (sizeof(tSirResultCodes)) + peerMacAddr - 6 bytes + The rest is conditionally defined of (WNI_POLARIS_FW_PRODUCT == AP) and not used +*/ +static void csrSerDesUnpackDiassocRsp(tANI_U8 *pBuf, tSirSmeDisassocRsp *pRsp) +{ + if(pBuf && pRsp) + { + pBuf += 4; //skip type and length + pRsp->sessionId = *pBuf++; + pal_get_U16( pBuf, (tANI_U16 *)&pRsp->transactionId ); + pBuf += 2; + pal_get_U32( pBuf, (tANI_U32 *)&pRsp->statusCode ); + pBuf += 4; + vos_mem_copy(pRsp->peerMacAddr, pBuf, 6); + } +} + +eHalStatus csrGetDefaultCountryCodeFrmNv(tpAniSirGlobal pMac, tANI_U8 *pCountry) +{ + static uNvTables nvTables; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + + /* read the country code from NV and use it */ + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pCountry, nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + return status; + } + else + { + vos_mem_copy(pCountry, "XXX", WNI_CFG_COUNTRY_CODE_LEN); + status = eHAL_STATUS_FAILURE; + return status; + } +} + +eHalStatus csrGetCurrentCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry) +{ + vos_mem_copy(pCountry, pMac->scan.countryCode11d, WNI_CFG_COUNTRY_CODE_LEN); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrSetTxPower(tpAniSirGlobal pMac, v_U8_t sessionId, v_U8_t mW) +{ + tSirSetTxPowerReq *pMsg = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirSetTxPowerReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set((void *)pMsg, sizeof(tSirSetTxPowerReq), 0); + pMsg->messageType = eWNI_SME_SET_TX_POWER_REQ; + pMsg->length = sizeof(tSirSetTxPowerReq); + pMsg->mwPower = mW; + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" csr set TX Power Post MSG Fail %d "), status); + //pMsg is freed by palSendMBMessage + } + return status; +} + +/* Returns whether a session is in VOS_STA_MODE...or not */ +tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = NULL; + pSession = CSR_GET_SESSION ( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" %s: session %d not found "), __func__, sessionId); + return eANI_BOOLEAN_FALSE; + } + if ( !CSR_IS_SESSION_VALID ( pMac, sessionId ) ) + { + smsLog(pMac, LOGE, FL(" %s: Inactive session"), __func__); + return eANI_BOOLEAN_FALSE; + } + if ( eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType ) + { + return eANI_BOOLEAN_FALSE; + } + /* There is a possibility that the above check may fail,because + * P2P CLI also uses the same BSSType (eCSR_BSS_TYPE_INFRASTRUCTURE) + * when it is connected.So,we may sneak through the above check even + * if we are not a STA mode INFRA station. So, if we sneak through + * the above condition, we can use the following check if we are + * really in STA Mode.*/ + + if ( NULL != pSession->pCurRoamProfile ) + { + if ( pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE ) + { + return eANI_BOOLEAN_TRUE; + } else { + smsLog(pMac, LOGE, FL(" %s: pCurRoamProfile is NULL\n"), __func__); + return eANI_BOOLEAN_FALSE; + } + } + + return eANI_BOOLEAN_FALSE; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tCsrHandoffRequest *pHandoffInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + + tAniHandoffReq *pMsg; + pMsg = vos_mem_malloc(sizeof(tAniHandoffReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrHandoffRequest: failed to allocate mem for req "); + return eHAL_STATUS_FAILURE; + } + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_HANDOFF_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniHandoffReq); + pMsg->sessionId = sessionId; + pMsg->channel = pHandoffInfo->channel; + pMsg->handoff_src = pHandoffInfo->src; + vos_mem_copy(pMsg->bssid, + pHandoffInfo->bssid, + 6); + msg.type = eWNI_SME_HANDOFF_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " csrHandoffRequest failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn csrSetCCKMIe + \brief This function stores the CCKM IE passed by the supplicant + in a place holder data structure and this IE will be packed inside + reassociation request + \param pMac - pMac global structure + \param sessionId - Current session id + \param pCckmIe - pointer to CCKM IE data + \param ccKmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, + const tANI_U8 *pCckmIe, + const tANI_U8 ccKmIeLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pSession->suppCckmIeInfo.cckmIe, pCckmIe, + ccKmIeLen); + pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen; + return status; +} + +/* --------------------------------------------------------------------------- + \fn csrRoamReadTSF + \brief This function reads the TSF; and also add the time elapsed since + last beacon or probe response reception from the hand off AP to arrive at + the latest TSF value. + \param pMac - pMac global structure + \param pTimestamp - output TSF timestamp + \- return Success or failure + -------------------------------------------------------------------------*/ +VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamBSSInfo handoffNode; + tANI_U32 timer_diff = 0; + tANI_U32 timeStamp[2]; + tpSirBssDescription pBssDescription = NULL; + csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode, sessionId); + pBssDescription = handoffNode.pBssDescription; + // Get the time diff in milli seconds + timer_diff = vos_timer_get_system_time() - pBssDescription->scanSysTimeMsec; + // Convert msec to micro sec timer + timer_diff = (tANI_U32)(timer_diff * SYSTEM_TIME_MSEC_TO_USEC); + timeStamp[0] = pBssDescription->timeStamp[0]; + timeStamp[1] = pBssDescription->timeStamp[1]; + UpdateCCKMTSF(&(timeStamp[0]), &(timeStamp[1]), &timer_diff); + vos_mem_copy(pTimestamp, (void *) &timeStamp[0], + sizeof (tANI_U32) * 2); + return status; +} +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* + * Post Channel Change Request to LIM + * This API is primarily used to post + * Channel Change Req for SAP + */ +eHalStatus +csrRoamChannelChangeReq( tpAniSirGlobal pMac, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 cbMode ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirChanChangeRequest *pMsg; + tANI_U32 vhtChannelWidth; + + pMsg = vos_mem_malloc( sizeof(tSirChanChangeRequest) ); + if (!pMsg) + { + return ( eHAL_STATUS_FAILURE ); + } + + vos_mem_set((void *)pMsg, sizeof( tSirChanChangeRequest ), 0); + + /* + * We are getting channel width from sapDfsInfor structure + * because we've implemented channel width fallback mechanism for DFS + * which will result in channel width changing dynamically. + */ + vhtChannelWidth = pMac->sap.SapDfsInfo.new_chanWidth; + +#ifdef WLAN_FEATURE_11AC + // cbMode = 1 in cfg.ini is mapped to PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + // in function csrConvertCBIniValueToPhyCBState() + // So, max value for cbMode in 40MHz mode is 3 (MAC\src\include\sirParams.h) + if(cbMode > PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + { + if(!WDA_getFwWlanFeatCaps(DOT11AC)) { + cbMode = csrGetHTCBStateFromVHTCBState(cbMode); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + FL("sapdfs: channel width is [%d]"), vhtChannelWidth); + ccmCfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + vhtChannelWidth, NULL, eANI_BOOLEAN_FALSE); + } + } +#endif + + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANNEL_CHANGE_REQ); + pMsg->messageLen = sizeof(tSirChanChangeRequest); + pMsg->targetChannel = targetChannel; + pMsg->cbMode = cbMode; + vos_mem_copy(pMsg->bssid, bssid, VOS_MAC_ADDR_SIZE); + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return ( status ); +} + +/* + * Post Beacon Tx Start request to LIM + * immediately after SAP CAC WAIT is + * completed without any RADAR indications. + */ +eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, tCsrBssid bssid, + tANI_U8 dfsCacWaitStatus) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirStartBeaconIndication *pMsg; + + pMsg = vos_mem_malloc(sizeof(tSirStartBeaconIndication)); + + if (!pMsg) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_set((void *)pMsg, sizeof( tSirStartBeaconIndication ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_START_BEACON_REQ); + pMsg->messageLen = sizeof(tSirStartBeaconIndication); + pMsg->beaconStartStatus = dfsCacWaitStatus; + vos_mem_copy(pMsg->bssid, bssid, VOS_MAC_ADDR_SIZE); + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return ( status ); +} + + +/*---------------------------------------------------------------------------- + \fn csrRoamModifyAddIEs + \brief This function sends msg to modify the additional IE buffers in PE + \param pMac - pMac global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - Type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamModifyAddIEs(tpAniSirGlobal pMac, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType) +{ + tpSirModifyIEsInd pModifyAddIEInd = NULL; + tANI_U8 *pLocalBuffer = NULL; + eHalStatus status; + + /* following buffer will be freed by consumer (PE) */ + pLocalBuffer = vos_mem_malloc(pModifyIE->ieBufferlength); + + if (NULL == pLocalBuffer) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + return eHAL_STATUS_FAILED_ALLOC; + } + + pModifyAddIEInd = vos_mem_malloc(sizeof(tSirModifyIEsInd)); + if (NULL == pModifyAddIEInd) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + vos_mem_free(pLocalBuffer); + return eHAL_STATUS_FAILED_ALLOC; + } + + /*copy the IE buffer */ + vos_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer, pModifyIE->ieBufferlength); + vos_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd)); + + pModifyAddIEInd->msgType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_MODIFY_ADDITIONAL_IES); + pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd); + + vos_mem_copy(pModifyAddIEInd->modifyIE.bssid, pModifyIE->bssid, + sizeof(tSirMacAddr)); + + pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId; + pModifyAddIEInd->modifyIE.notify = pModifyIE->notify; + pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID; + pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen; + pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer; + pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength; + + pModifyAddIEInd->updateType = updateType; + + status = palSendMBMessage(pMac->hHdd, pModifyAddIEInd); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg" + "!!! status %d"), status); + vos_mem_free(pLocalBuffer); + } + return status; +} + + +/*---------------------------------------------------------------------------- + \fn csrRoamUpdateAddIEs + \brief This function sends msg to updates the additional IE buffers in PE + \param pMac - pMac global structure + \param sessionId - SME session id + \param bssid - BSSID + \param additionIEBuffer - buffer containing addition IE from hostapd + \param length - length of buffer + \param updateType - Type of buffer + \param append - append or replace completely + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamUpdateAddIEs(tpAniSirGlobal pMac, + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType) +{ + tpSirUpdateIEsInd pUpdateAddIEs = NULL; + tANI_U8 *pLocalBuffer = NULL; + eHalStatus status; + + if (pUpdateIE->ieBufferlength != 0) + { + /* Following buffer will be freed by consumer (PE) */ + pLocalBuffer = vos_mem_malloc(pUpdateIE->ieBufferlength); + if (NULL == pLocalBuffer) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer, + pUpdateIE->ieBufferlength); + } + + pUpdateAddIEs = vos_mem_malloc( sizeof(tSirUpdateIEsInd) ); + if (NULL == pUpdateAddIEs) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + if (pLocalBuffer != NULL) + { + vos_mem_free(pLocalBuffer); + } + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pUpdateAddIEs, sizeof(tSirUpdateIEsInd)); + + pUpdateAddIEs->msgType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_UPDATE_ADDITIONAL_IES); + pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd); + + vos_mem_copy(pUpdateAddIEs->updateIE.bssid, pUpdateIE->bssid, sizeof(tSirMacAddr)); + + pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId; + pUpdateAddIEs->updateIE.append = pUpdateIE->append; + pUpdateAddIEs->updateIE.notify = pUpdateIE->notify; + pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength; + pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer; + + pUpdateAddIEs->updateType = updateType; + + status = palSendMBMessage(pMac->hHdd, pUpdateAddIEs); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg" + "!!! status %d"), status); + vos_mem_free(pLocalBuffer); + } + return status; +} + + +/*---------------------------------------------------------------------------- + \fn csrRoamSendChanSwIERequest + \brief This function sends request to transmit channel switch announcement + IE to lower layers + \param pMac - pMac global structure + \param sessionId - SME session id + \param pDfsCacInd - CAC indication data to PE/LIM + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 csaIeReqd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirDfsCsaIeRequest *pMsg; + + pMsg = vos_mem_malloc(sizeof(tSirDfsCsaIeRequest)); + if (!pMsg) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_set((void *)pMsg, sizeof(tSirDfsCsaIeRequest), 0); + pMsg->msgType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ); + pMsg->msgLen = sizeof(tSirDfsCsaIeRequest); + + pMsg->targetChannel = targetChannel; + pMsg->csaIeRequired = csaIeReqd; + vos_mem_copy(pMsg->bssid, bssid, VOS_MAC_ADDR_SIZE); + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return status; +} +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/*---------------------------------------------------------------------------- + * fn csrProcessRoamOffloadSynchInd + * brief This will receive and process the Roam Offload Synch Ind + * param hHal - pMac global structure + * param pSmeRoamOffloadSynchInd - Roam Synch info is retrieved + * --------------------------------------------------------------------------*/ +void csrProcessRoamOffloadSynchInd( + tHalHandle hHal, tpSirRoamOffloadSynchInd pSmeRoamOffloadSynchInd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = NULL; + tANI_U8 sessionId = pSmeRoamOffloadSynchInd->roamedVdevId; + pSession = CSR_GET_SESSION(pMac, pSmeRoamOffloadSynchInd->roamedVdevId); + if (!pSession) { + smsLog(pMac, LOGE, FL("LFR3: session %d not found "), + pSmeRoamOffloadSynchInd->roamedVdevId); + goto err_synch_rsp; + } + if (!HAL_STATUS_SUCCESS(csrScanSaveRoamOffloadApToScanCache(pMac, + pSmeRoamOffloadSynchInd))) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "fail to save roam offload AP to scan cache"); + goto err_synch_rsp; + } + pSession->roamOffloadSynchParams.rssi = pSmeRoamOffloadSynchInd->rssi; + pSession->roamOffloadSynchParams.roamReason = + pSmeRoamOffloadSynchInd->roamReason; + pSession->roamOffloadSynchParams.roamedVdevId = + pSmeRoamOffloadSynchInd->roamedVdevId; + vos_mem_copy(pSession->roamOffloadSynchParams.bssid, + pSmeRoamOffloadSynchInd->bssId, sizeof(tSirMacAddr)); + pSession->roamOffloadSynchParams.txMgmtPower = + pSmeRoamOffloadSynchInd->txMgmtPower; + pSession->roamOffloadSynchParams.authStatus = + pSmeRoamOffloadSynchInd->authStatus; + pSession->roamOffloadSynchParams.bRoamSynchInProgress = eANI_BOOLEAN_TRUE; + /*Save the BSS descriptor for later use*/ + pSession->roamOffloadSynchParams.pbssDescription = + pSmeRoamOffloadSynchInd->pbssDescription; + pMac->roam.reassocRespLen = pSmeRoamOffloadSynchInd->reassocRespLength; + pMac->roam.pReassocResp = + vos_mem_malloc(pMac->roam.reassocRespLen); + if (NULL == pMac->roam.pReassocResp) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Memory allocation for reassoc response failed"); + goto err_synch_rsp; + } + vos_mem_copy(pMac->roam.pReassocResp, + (tANI_U8 *)pSmeRoamOffloadSynchInd + + pSmeRoamOffloadSynchInd->reassocRespOffset, + pMac->roam.reassocRespLen); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "LFR3:%s: the reassoc resp frame data:", __func__); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + pMac->roam.pReassocResp, pMac->roam.reassocRespLen); + + vos_mem_copy(pSession->roamOffloadSynchParams.kck, + pSmeRoamOffloadSynchInd->kck, SIR_KCK_KEY_LEN); + vos_mem_copy(pSession->roamOffloadSynchParams.kek, + pSmeRoamOffloadSynchInd->kek, SIR_KEK_KEY_LEN); + vos_mem_copy(pSession->roamOffloadSynchParams.replay_ctr, + pSmeRoamOffloadSynchInd->replay_ctr, SIR_REPLAY_CTR_LEN); + + if (eHAL_STATUS_SUCCESS != csrNeighborRoamOffloadUpdatePreauthList(pMac, + pSmeRoamOffloadSynchInd, sessionId)) { + /* + * Bail out if Roam Offload Synch Response was not even handled. + */ + smsLog(pMac, LOGE, FL("Roam Offload Synch Response " + "was not processed")); + goto err_synch_rsp; + } + + csrNeighborRoamRequestHandoff(pMac, sessionId); + +err_synch_rsp: + vos_mem_free(pSmeRoamOffloadSynchInd->pbssDescription); + pSmeRoamOffloadSynchInd->pbssDescription = NULL; +} + +/*---------------------------------------------------------------------------- + * fn csrProcessHOFailInd + * brief This function will process the Hand Off Failure indication + * received from the firmware. It will trigger a disconnect on + * the session which the firmware reported a hand off failure + * param pMac global structure + * param pMsgBuf - Contains the session ID for which the handler should apply + * --------------------------------------------------------------------------*/ +void csrProcessHOFailInd(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tSirSmeHOFailureInd *pSmeHOFailInd = (tSirSmeHOFailureInd *)pMsgBuf; + tANI_U32 sessionId; + + if (pSmeHOFailInd) + sessionId = pSmeHOFailInd->sessionId; + else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3: Hand-Off Failure Ind is NULL"); + return; + } + /* Roaming is supported only on Infra STA Mode. */ + if (!csrRoamIsStaMode(pMac, sessionId)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3:HO Fail cannot be handled for session %d",sessionId); + return; + } + + csrRoamSynchCleanUp(pMac, sessionId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3:Issue Disconnect on session %d", sessionId); + csrRoamDisconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); +} +#endif + +void csrInitOperatingClasses(tHalHandle hHal) +{ + tANI_U8 Index = 0; + tANI_U8 class = 0; + tANI_U8 i = 0; + tANI_U8 j = 0; + tANI_U8 swap = 0; + tANI_U8 numChannels = 0; + tANI_U8 numClasses = 0; + tANI_BOOLEAN found; + tANI_U8 opClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG1, FL("Current Country = %c%c"), + pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1]); + + for (j = 0; j < SIR_MAC_MAX_SUPP_OPER_CLASSES; j++) { + opClasses[j] = 0; + } + + numChannels = pMac->scan.baseChannels.numChannels; + + smsLog(pMac, LOG1, FL("Num of base channels %d"), numChannels); + + for (Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) { + class = regdm_get_opclass_from_channel(pMac->scan.countryCodeCurrent, + pMac->scan.baseChannels.channelList[Index], + BWALL); + smsLog(pMac, LOG4, FL("for chan %d, op class: %d"), + pMac->scan.baseChannels.channelList[Index], + class); + + found = FALSE; + for (j = 0 ; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) { + if (opClasses[j] == class) { + found = TRUE; + break; + } + } + if (!found) { + opClasses[i]= class; + i++; + } + } + + numChannels = pMac->scan.base20MHzChannels.numChannels; + + smsLog(pMac, LOG1, FL("Num of 20MHz channels %d"), numChannels); + + for (Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) { + class = regdm_get_opclass_from_channel(pMac->scan.countryCodeCurrent, + pMac->scan.base20MHzChannels.channelList[Index], + BWALL); + smsLog(pMac, LOG4, FL("for chan %d, op class: %d"), + pMac->scan.base20MHzChannels.channelList[ Index ], + class); + + found = FALSE; + for (j = 0 ; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) { + if (opClasses[j] == class) { + found = TRUE; + break; + } + } + if (!found) { + opClasses[i]= class; + i++; + } + } + + numChannels = pMac->scan.base40MHzChannels.numChannels; + + smsLog(pMac, LOG1, FL("Num of 40MHz channels %d"), numChannels); + + for (Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) { + class = regdm_get_opclass_from_channel(pMac->scan.countryCodeCurrent, + pMac->scan.base40MHzChannels.channelList[Index], + BWALL); + smsLog(pMac, LOG4, FL("for chan %d, op class: %d"), + pMac->scan.base40MHzChannels.channelList[ Index ], + class); + + found = FALSE; + for (j = 0 ; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) { + if (opClasses[j] == class) { + found = TRUE; + break; + } + } + if (!found) { + opClasses[i]= class; + i++; + } + } + + numClasses = i; + + /* As per spec the operating classes should be in ascending order. + * Bubble sort is fine since we don't have many classes + */ + for (i = 0 ; i < (numClasses - 1); i++) { + for (j = 0 ; j < (numClasses - i - 1); j++) { + /* For decreasing order use < */ + if (opClasses[j] > opClasses[j+1]) { + swap = opClasses[j]; + opClasses[j] = opClasses[j+1]; + opClasses[j+1] = swap; + } + } + } + + smsLog(pMac, LOG1, FL("Total number of unique supported op classes %d"), + numClasses); + for (i = 0; i < numClasses; i++) { + smsLog(pMac, LOG1, FL("supported opClasses[%d] = %d"), i, + opClasses[i]); + } + + /* Set the ordered list of op classes in regdomain + * for use by other modules + */ + regdm_set_curr_opclasses(numClasses, &opClasses[0]); +} + diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiScan.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiScan.c new file mode 100644 index 0000000000000..ae75a706d4657 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrApiScan.c @@ -0,0 +1,8725 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrApiScan.c + + Implementation for the Common Scan interfaces. +========================================================================== */ + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" + +#include "vos_nvitem.h" +#include "wlan_qct_wda.h" +#include "vos_utils.h" + +#define MIN_CHN_TIME_TO_FIND_GO 100 +#define MAX_CHN_TIME_TO_FIND_GO 100 +#define DIRECT_SSID_LEN 7 + +/* Purpose of HIDDEN_TIMER +** When we remove hidden ssid from the profile i.e., forget the SSID via GUI that SSID shouldn't see in the profile +** For above requirement we used timer limit, logic is explained below +** Timer value is initialsed to current time when it receives corresponding probe response of hidden SSID (The probe request is +** received regularly till SSID in the profile. Once it is removed from profile probe request is not sent.) when we receive probe response +** for broadcast probe request, during update SSID with saved SSID we will diff current time with saved SSID time if it is greater than 1 min +** then we are not updating with old one +*/ + +#define HIDDEN_TIMER (1*60*1000) +#define CSR_SCAN_RESULT_RSSI_WEIGHT 80 // must be less than 100, represent the persentage of new RSSI + +#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140 +#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120 + +#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30 +#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20 + +#define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) \ + ( (pMac)->scan.nBssLimit <= (csrLLCount(&(pMac)->scan.scanResultList)) ) + +//*** This is temporary work around. It need to call CCM api to get to CFG later +/// Get string parameter value +extern tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*); + +void csrScanGetResultTimerHandler(void *); +void csrScanResultAgingTimerHandler(void *pv); +static void csrScanResultCfgAgingTimerHandler(void *pv); +void csrScanIdleScanTimerHandler(void *); +static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest); +#ifdef WLAN_AP_STA_CONCURRENCY +static void csrStaApConcTimerHandler(void *); +#endif +tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId); +eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels ); +void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId ); +void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode ); +void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList ); +//if bgPeriod is 0, background scan is disabled. It is in millisecond units +eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod); +eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus); +static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, + tANI_U8 numChn, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs **ppIes ); +eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels); +void csrReleaseCmdSingle(tpAniSirGlobal pMac, tSmeCmd *pCommand); +tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel ); +void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList ); + +#define CSR_IS_SOCIAL_CHANNEL(channel) (((channel) == 1) || ((channel) == 6) || ((channel) == 11) ) + + + +static void csrReleaseScanCmdPendingList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + + while((pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK)) != NULL) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCsrCommandMask & pCommand->command ) + { + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_TRUE ); + } + else + { + smsLog(pMac, LOGE, FL("Error: Received command : %d"),pCommand->command); + } + } +} +//pResult is invalid calling this function. +void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult ) +{ + if( NULL != pResult->Result.pvIes ) + { + vos_mem_free(pResult->Result.pvIes); + } + vos_mem_free(pResult); +} + + +static eHalStatus csrLLScanPurgeResult(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tCsrScanResult *pBssDesc; + + csrLLLock(pList); + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + csrFreeScanResultEntry( pMac, pBssDesc ); + } + + csrLLUnlock(pList); + + return (status); +} + +eHalStatus csrScanOpen( tpAniSirGlobal pMac ) +{ + eHalStatus status; + + do + { + csrLLOpen(pMac->hHdd, &pMac->scan.scanResultList); + csrLLOpen(pMac->hHdd, &pMac->scan.tempScanResults); + csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList24); + csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList5G); +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLOpen(pMac->hHdd, &pMac->scan.scanCmdPendingList); +#endif + pMac->scan.fFullScanIssued = eANI_BOOLEAN_FALSE; + pMac->scan.nBssLimit = CSR_MAX_BSS_SUPPORT; + status = vos_timer_init(&pMac->scan.hTimerGetResult, VOS_TIMER_TYPE_SW, csrScanGetResultTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for getResult timer")); + break; + } +#ifdef WLAN_AP_STA_CONCURRENCY + status = vos_timer_init(&pMac->scan.hTimerStaApConcTimer, VOS_TIMER_TYPE_SW, csrStaApConcTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for hTimerStaApConcTimer timer")); + break; + } +#endif + status = vos_timer_init(&pMac->scan.hTimerIdleScan, VOS_TIMER_TYPE_SW, csrScanIdleScanTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for idleScan timer")); + break; + } + status = vos_timer_init(&pMac->scan.hTimerResultAging, VOS_TIMER_TYPE_SW, csrScanResultAgingTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for ResultAging timer")); + break; + } + status = vos_timer_init(&pMac->scan.hTimerResultCfgAging, VOS_TIMER_TYPE_SW, + csrScanResultCfgAgingTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for CFG ResultAging timer")); + break; + } + }while(0); + + return (status); +} + + +eHalStatus csrScanClose( tpAniSirGlobal pMac ) +{ + csrLLScanPurgeResult(pMac, &pMac->scan.tempScanResults); + csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList); +#ifdef WLAN_AP_STA_CONCURRENCY + csrReleaseScanCmdPendingList(pMac); +#endif + csrLLClose(&pMac->scan.scanResultList); + csrLLClose(&pMac->scan.tempScanResults); +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLClose(&pMac->scan.scanCmdPendingList); +#endif + csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList24); + csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList5G); + csrLLClose(&pMac->scan.channelPowerInfoList24); + csrLLClose(&pMac->scan.channelPowerInfoList5G); + csrScanDisable(pMac); + vos_timer_destroy(&pMac->scan.hTimerResultAging); + vos_timer_destroy(&pMac->scan.hTimerResultCfgAging); + vos_timer_destroy(&pMac->scan.hTimerGetResult); +#ifdef WLAN_AP_STA_CONCURRENCY + vos_timer_destroy(&pMac->scan.hTimerStaApConcTimer); +#endif + vos_timer_destroy(&pMac->scan.hTimerIdleScan); + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus csrScanEnable( tpAniSirGlobal pMac ) +{ + + pMac->scan.fScanEnable = eANI_BOOLEAN_TRUE; + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus csrScanDisable( tpAniSirGlobal pMac ) +{ + + csrScanStopTimers(pMac); + pMac->scan.fScanEnable = eANI_BOOLEAN_FALSE; + + return eHAL_STATUS_SUCCESS; +} + + +//Set scan timing parameters according to state of other driver sessions +//No validation of the parameters is performed. +static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest) +{ +#ifdef WLAN_AP_STA_CONCURRENCY + if(csrIsAnySessionConnected(pMac)) + { + //If multi-session, use the appropriate default scan times + if(scanType == eSIR_ACTIVE_SCAN) + { + pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTimeConc; + } + else + { + pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTimeConc; + } + pScanRequest->maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pScanRequest->minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + + pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc; + + //Return so that fields set above will not be overwritten. + return; + } +#endif + + //This portion of the code executed if multi-session not supported + //(WLAN_AP_STA_CONCURRENCY not defined) or no multi-session. + //Use the "regular" (non-concurrency) default scan timing. + if(pScanRequest->scanType == eSIR_ACTIVE_SCAN) + { + pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTime; + } + else + { + pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + pScanRequest->maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pScanRequest->minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + +#ifdef WLAN_AP_STA_CONCURRENCY + //No rest time if no sessions are connected. + pScanRequest->restTime = 0; +#endif +} + +#ifdef WLAN_AP_STA_CONCURRENCY +//Return SUCCESS is the command is queued, else returns eHAL_STATUS_FAILURE +eHalStatus csrQueueScanRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, + tSmeCmd *pScanCmd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + tANI_BOOLEAN fNoCmdPending; + tSmeCmd *pQueueScanCmd=NULL; + tSmeCmd *pSendScanCmd=NULL; + tANI_U8 nNumChanCombinedConc = 0; + if (NULL == pScanCmd) + { + smsLog (pMac, LOGE, FL("Scan Req cmd is NULL")); + return eHAL_STATUS_FAILURE; + } + /* split scan if any one of the following: + * - STA session is connected and the scan is not a P2P search + * - any P2P session is connected + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + + if(csrIsStaSessionConnected(pMac) && + !csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + } + else if(csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; + } + if ( (csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) && + (pMac->roam.neighborRoamInfo[sessionId].neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac)) ) + { + tCsrScanRequest scanReq; + tANI_U8 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_BOOLEAN bMemAlloc = eANI_BOOLEAN_FALSE; + + if (numChn == 0) + { + + numChn = pMac->scan.baseChannels.numChannels; + + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(numChn); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + { + smsLog( pMac, LOGE, FL(" Failed to get memory for channel list ") ); + return eHAL_STATUS_FAILURE; + } + bMemAlloc = eANI_BOOLEAN_TRUE; + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pMac->scan.baseChannels.channelList, numChn); + status = eHAL_STATUS_SUCCESS; + if( !HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list ") ); + return eHAL_STATUS_FAILURE; + } + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn; + } + + //Whenever we get a scan request with multiple channels we break it up into 2 requests + //First request for first channel to scan and second request to scan remaining channels + if ( numChn > nNumChanCombinedConc) + { + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only + if (!pQueueScanCmd) + { + if (bMemAlloc) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + + } + smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") ); + return eHAL_STATUS_FAILURE; + } + pQueueScanCmd->command = pScanCmd->command; + pQueueScanCmd->sessionId = pScanCmd->sessionId; + pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback; + pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext; + pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason; + pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + /* First copy all the parameters to local variable of scan request */ + csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest); + + /* Now modify the elements of local var scan request required to be modified for split scan */ + if(scanReq.ChannelInfo.ChannelList != NULL) + { + vos_mem_free(scanReq.ChannelInfo.ChannelList); + scanReq.ChannelInfo.ChannelList = NULL; + } + + pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - nNumChanCombinedConc; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL(" &channelToScan %p pScanCmd(%p) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(%p)numChn(%d)"), + &channelToScan[0], pScanCmd, + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn); + + vos_mem_copy(&channelToScan[0], + &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[ + nNumChanCombinedConc], + pChnInfo->numOfChannels * sizeof(tANI_U8)); + + pChnInfo->ChannelList = &channelToScan[0]; + + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + //Modify callers parameters in case of concurrency + if (!pScanCmd->u.scanCmd.u.scanRequest.bcnRptReqScan) + scanReq.scanType = eSIR_ACTIVE_SCAN; + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq); + + status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq); + + if(!HAL_STATUS_SUCCESS(status)) + { + if (bMemAlloc) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + + } + if( scanReq.pIEField != NULL) + { + vos_mem_free(scanReq.pIEField); + scanReq.pIEField = NULL; + } + smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status ); + return eHAL_STATUS_FAILURE; + } + /* Clean the local scan variable */ + scanReq.ChannelInfo.ChannelList = NULL; + scanReq.ChannelInfo.numOfChannels = 0; + csrScanFreeRequest(pMac, &scanReq); + + /* setup the command to scan 2 channels */ + pSendScanCmd = pScanCmd; + pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nNumChanCombinedConc; + pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + if (!pSendScanCmd->u.scanCmd.u.scanRequest.bcnRptReqScan) + pSendScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest); + pSendScanCmd->u.scanCmd.callback = NULL; + } else { + pSendScanCmd = pScanCmd; + pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + if (!pSendScanCmd->u.scanCmd.u.scanRequest.bcnRptReqScan) + pSendScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest); + } + + fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK ); + + //Logic Below is as follows + // If the scanCmdPendingList is empty then we directly send that command + // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue + if( fNoCmdPending ) + { + if (pQueueScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK ); + } + + if (pSendScanCmd != NULL) + { + return csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE); + } + } + else + { + if (pSendScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pSendScanCmd->Link, LL_ACCESS_LOCK ); + } + + if (pQueueScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK ); + } + } + } + else + { //No concurrency case + smsLog( pMac, LOG2, FL("Queuing scan command (reason=%d, roamState=%d" + " numOfChannels=%d)"), + pScanCmd->u.scanCmd.reason, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState, + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels); + return csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + } + + return ( status ); +} +#endif + +/* --------------------------------------------------------------------------- + \fn csrScan2GOnyRequest + \brief This function will update the scan request with only + 2.4GHz valid channel list. + \param pMac + \param pScanCmd + \param pScanRequest + \return None + -------------------------------------------------------------------------------*/ +static void csrScan2GOnyRequest(tpAniSirGlobal pMac,tSmeCmd *pScanCmd, + tCsrScanRequest *pScanRequest) +{ + tANI_U8 index, channelId, channelListSize = 0; + tANI_U8 channelList2G[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + static tANI_U8 validchannelList[CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS] = {0}; + + VOS_ASSERT(pScanCmd && pScanRequest); + /* To silence the KW tool null check is added */ + if((pScanCmd == NULL) || (pScanRequest == NULL)) + { + smsLog( pMac, LOGE, FL(" pScanCmd or pScanRequest is NULL ")); + return; + } + + if ((pScanCmd->u.scanCmd.scanID != FIRST_SCAN_ID) || + (eCSR_SCAN_REQUEST_FULL_SCAN != pScanRequest->requestType)) + return; + + smsLog( pMac, LOG1, FL("Scanning only 2G Channels during first scan")); + /* Construct valid Supported 2.4 GHz Channel List */ + for( index = 0; index < ARRAY_SIZE(channelList2G); index++ ) + { + channelId = channelList2G[index]; + if ( csrIsSupportedChannel( pMac, channelId ) ) + { + validchannelList[channelListSize++] = channelId; + } + } + + pScanRequest->ChannelInfo.numOfChannels = channelListSize; + pScanRequest->ChannelInfo.ChannelList = validchannelList; +} + +eHalStatus csrScanRequest(tpAniSirGlobal pMac, tANI_U16 sessionId, + tCsrScanRequest *pScanRequest, tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSmeCmd *pScanCmd = NULL; + eCsrConnectState ConnectState; + + if(pScanRequest == NULL) + { + smsLog( pMac, LOGE, FL(" pScanRequest is NULL")); + VOS_ASSERT(0); + return status; + } + + /* During group formation, the P2P client scans for GO with the specific SSID. + * There will be chances of GO switching to other channels because of scan or + * to STA channel in case of STA+GO MCC scenario. So to increase the possibility + * of client to find the GO, the dwell time of scan is increased to 100ms. + */ + if(pScanRequest->p2pSearch) + { + if ((pScanRequest->SSIDs.numOfSSIDs) && (NULL != pScanRequest->SSIDs.SSIDList)) + { + //If the scan request is for specific SSId the length of SSID will be + //greater than 7 as SSID for p2p search contains "DIRECT-") + if(pScanRequest->SSIDs.SSIDList->SSID.length > DIRECT_SSID_LEN) + { + smsLog( pMac, LOG1, FL("P2P: Increasing the min and max Dwell" + " time to %d for specific SSID scan %.*s"), + MAX_CHN_TIME_TO_FIND_GO, + pScanRequest->SSIDs.SSIDList->SSID.length, + pScanRequest->SSIDs.SSIDList->SSID.ssId); + pScanRequest->maxChnTime = MAX_CHN_TIME_TO_FIND_GO; + pScanRequest->minChnTime = MIN_CHN_TIME_TO_FIND_GO; + } + } + } + + do + { + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = sessionId; + if (pScanCmd->sessionId >= CSR_ROAM_SESSION_MAX) + smsLog( pMac, LOGE, FL("Invalid Sme Session ID = %d"), sessionId); + pScanCmd->u.scanCmd.callback = callback; + pScanCmd->u.scanCmd.pContext = pContext; + if(eCSR_SCAN_REQUEST_11D_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScan11d1; + } + else if((eCSR_SCAN_REQUEST_FULL_SCAN == pScanRequest->requestType) || + (eCSR_SCAN_P2P_DISCOVERY == pScanRequest->requestType) +#ifdef SOFTAP_CHANNEL_RANGE + ||(eCSR_SCAN_SOFTAP_CHANNEL_RANGE == pScanRequest->requestType) +#endif + ) + { + pScanCmd->u.scanCmd.reason = eCsrScanUserRequest; + } + else if(eCSR_SCAN_HO_BG_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanBgScan; + } + else if(eCSR_SCAN_HO_PROBE_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanProbeBss; + } + else if(eCSR_SCAN_P2P_FIND_PEER == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanP2PFindPeer; + } + else + { + pScanCmd->u.scanCmd.reason = eCsrScanIdleScan; + } + if(pScanRequest->minChnTime == 0 && pScanRequest->maxChnTime == 0) + { + //The caller doesn't set the time correctly. Set it here + csrSetDefaultScanTiming(pMac, pScanRequest->scanType, + pScanRequest); + smsLog(pMac, LOG1, FL("Setting default min %d and max %d" + " ChnTime"), pScanRequest->minChnTime, + pScanRequest->maxChnTime); + } +#ifdef WLAN_AP_STA_CONCURRENCY + if(pScanRequest->restTime == 0) + { + //Need to set restTime only if at least one session is connected + if(csrIsAnySessionConnected(pMac)) + { + pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc; + if(pScanRequest->scanType == eSIR_ACTIVE_SCAN) + { + pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTimeConc; + } + else + { + pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTimeConc; + } + } + } +#endif + /* Increase dwell time in case P2P Search and Miracast is not present*/ + if(pScanRequest->p2pSearch && + pScanRequest->ChannelInfo.numOfChannels == P2P_SOCIAL_CHANNELS + && (!IS_MIRACAST_SESSION_PRESENT(pMac))) + { + pScanRequest->maxChnTime += P2P_SEARCH_DWELL_TIME_INCREASE; + } + + /*For Standalone wlan : channel time will remain the same. + For BTC with A2DP up: Channel time = Channel time * 2, if station is not already associated. + This has been done to provide a larger scan window for faster connection during btc.Else Scan is seen + to take a long time. + For BTC with A2DP up: Channel time will not be doubled, if station is already associated. + */ + status = csrRoamGetConnectState(pMac,sessionId,&ConnectState); + if (HAL_STATUS_SUCCESS(status) && + pMac->btc.fA2DPUp && + (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED != ConnectState) && + (eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED != ConnectState)) + { + pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1; + pScanRequest->minChnTime = pScanRequest->minChnTime << 1; + smsLog( pMac, LOG1, FL("BTC A2DP up, doubling max and min" + " ChnTime (Max=%d Min=%d)"), + pScanRequest->maxChnTime, + pScanRequest->minChnTime); + } + + pScanRequest->maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pScanRequest->minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + if(pScanRequestID) + { + *pScanRequestID = pScanCmd->u.scanCmd.scanID; + } + + // If it is the first scan request from HDD, CSR checks if it is for 11d. + // If it is not, CSR will save the scan request in the pending cmd queue + // & issue an 11d scan request to PE. + if (((FIRST_SCAN_ID == pScanCmd->u.scanCmd.scanID) + && (eCSR_SCAN_REQUEST_11D_SCAN != pScanRequest->requestType)) +#ifdef SOFTAP_CHANNEL_RANGE + && (eCSR_SCAN_SOFTAP_CHANNEL_RANGE != pScanRequest->requestType) +#endif + && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d) + ) + { + tSmeCmd *p11dScanCmd; + tCsrScanRequest scanReq; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + p11dScanCmd = csrGetCommandBuffer(pMac); + if (p11dScanCmd) + { + tANI_U32 numChn = pMac->scan.baseChannels.numChannels; + + vos_mem_set(&p11dScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pChnInfo->ChannelList = vos_mem_malloc(numChn); + if ( NULL == pChnInfo->ChannelList ) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory")); + status = eHAL_STATUS_FAILURE; + break; + } + vos_mem_copy(pChnInfo->ChannelList, + pMac->scan.baseChannels.channelList, + numChn); + + pChnInfo->numOfChannels = (tANI_U8)numChn; + p11dScanCmd->command = eSmeCommandScan; + p11dScanCmd->u.scanCmd.callback = pMac->scan.callback11dScanDone; + p11dScanCmd->u.scanCmd.pContext = NULL; + p11dScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + if ( csrIs11dSupported(pMac) ) + { + scanReq.bcnRptReqScan = pScanRequest->bcnRptReqScan; + if (pScanRequest->bcnRptReqScan) + scanReq.scanType = pScanRequest->scanType ? + eSIR_PASSIVE_SCAN : + pScanRequest->scanType; + else + scanReq.scanType = eSIR_PASSIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN; + p11dScanCmd->u.scanCmd.reason = eCsrScan11d1; + scanReq.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + else + { + scanReq.bcnRptReqScan = pScanRequest->bcnRptReqScan; + if (pScanRequest->bcnRptReqScan) + scanReq.scanType = pScanRequest->scanType; + else + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = eCSR_SCAN_IDLE_MODE_SCAN; + p11dScanCmd->u.scanCmd.reason = eCsrScanIdleScan; + scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + + scanReq.maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + scanReq.minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + } + if (pMac->roam.configParam.nInitialDwellTime) + { + scanReq.maxChnTime = + pMac->roam.configParam.nInitialDwellTime; + smsLog(pMac, LOG1, FL("11d scan, updating" + "dwell time for first scan %u"), + scanReq.maxChnTime); + } + + status = csrScanCopyRequest(pMac, &p11dScanCmd->u.scanCmd.u.scanRequest, &scanReq); + //Free the channel list + vos_mem_free(pChnInfo->ChannelList); + pChnInfo->ChannelList = NULL; + + if (HAL_STATUS_SUCCESS(status)) + { + //Start process the command +#ifdef WLAN_AP_STA_CONCURRENCY + if (!pMac->fScanOffload) + status = csrQueueScanRequest(pMac, sessionId, + p11dScanCmd); + else + status = csrQueueSmeCommand(pMac, p11dScanCmd, + eANI_BOOLEAN_FALSE); +#else + status = csrQueueSmeCommand(pMac, p11dScanCmd, eANI_BOOLEAN_FALSE); +#endif + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" Failed to send message" + " status = %d"), status); + break; + } + } + else + { + smsLog(pMac, LOGE, FL("csrScanCopyRequest failed")); + break; + } + } + else + { + //error + smsLog( pMac, LOGE, FL("p11dScanCmd failed") ); + break; + } + } + + //Scan only 2G Channels if set in ini file + //This is mainly to reduce the First Scan duration + //Once we turn on Wifi + if(pMac->scan.fFirstScanOnly2GChnl) + { + csrScan2GOnyRequest(pMac, pScanCmd, pScanRequest); + } + + if (pMac->roam.configParam.nInitialDwellTime) + { + pScanRequest->maxChnTime = + pMac->roam.configParam.nInitialDwellTime; + pMac->roam.configParam.nInitialDwellTime = 0; + smsLog(pMac, LOG1, + FL("updating dwell time for first scan %u"), + pScanRequest->maxChnTime); + } + + status = csrScanCopyRequest(pMac, &pScanCmd->u.scanCmd.u.scanRequest, pScanRequest); + /* + * Reset the variable after the first scan is queued after + * loading the driver. The purpose of this parameter is that + * DFS channels are skipped during the first scan after loading + * the driver. The above API builds the target scan request in + * which this variable is used. + */ + pMac->roam.configParam.initial_scan_no_dfs_chnl = 0; + if(HAL_STATUS_SUCCESS(status)) + { + tCsrScanRequest *pTempScanReq = + &pScanCmd->u.scanCmd.u.scanRequest; + pMac->scan.scanProfile.numOfChannels = + pTempScanReq->ChannelInfo.numOfChannels; + + smsLog(pMac, LOG1, FL(" SId=%d scanId=%d" + " Scan reason=%u numSSIDs=%d" + " numChan=%d P2P search=%d minCT=%d maxCT=%d" + " minCBtc=%d maxCBtx=%d uIEFieldLen=%d"), + sessionId, pScanCmd->u.scanCmd.scanID, + pScanCmd->u.scanCmd.reason, + pTempScanReq->SSIDs.numOfSSIDs, + pTempScanReq->ChannelInfo.numOfChannels, + pTempScanReq->p2pSearch, + pTempScanReq->minChnTime, + pTempScanReq->maxChnTime, + pTempScanReq->minChnTimeBtc, + pTempScanReq->maxChnTimeBtc, + pTempScanReq->uIEFieldLen); + + //Start process the command +#ifdef WLAN_AP_STA_CONCURRENCY + if (!pMac->fScanOffload) + status = csrQueueScanRequest(pMac, sessionId, pScanCmd); + else + status = csrQueueSmeCommand(pMac, pScanCmd, + eANI_BOOLEAN_FALSE); +#else + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); +#endif + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } + else + { + smsLog( pMac, LOGE, FL(" fail to copy request status = %d"), status ); + break; + } + } + else + { + smsLog( pMac, LOGE, FL(" pScanCmd is NULL")); + break; + } + } + else + { + smsLog( pMac, LOGE, FL("SId: %d Scanning not enabled" + " Scan type=%u, numOfSSIDs=%d P2P search=%d"), + sessionId, pScanRequest->requestType, + pScanRequest->SSIDs.numOfSSIDs, + pScanRequest->p2pSearch ); + } + } while(0); + if(!HAL_STATUS_SUCCESS(status) && pScanCmd) + { + if( eCsrScanIdleScan == pScanCmd->u.scanCmd.reason ) + { + //Set the flag back for restarting idle scan + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + smsLog( pMac, LOGE, FL(" SId: %d Failed with status=%d" + " Scan reason=%u numOfSSIDs=%d" + " P2P search=%d scanId=%d"), + sessionId, status, pScanCmd->u.scanCmd.reason, + pScanRequest->SSIDs.numOfSSIDs, pScanRequest->p2pSearch, + pScanCmd->u.scanCmd.scanID ); + csrReleaseCommandScan(pMac, pScanCmd); + } + + return (status); +} + + +eHalStatus csrScanRequestResult(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + pScanCmd->u.scanCmd.reason = eCsrScanGetResult; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if (pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if (pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = sessionId; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.callback = callback; + pScanCmd->u.scanCmd.pContext = pContext; + pScanCmd->u.scanCmd.reason = eCsrScanGetLfrResult; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_TRUE); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer\n")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +eHalStatus csrScanAllChannels(tpAniSirGlobal pMac, eCsrRequestType reqType) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 scanId; + tCsrScanRequest scanReq; + + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = reqType; + scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + scanReq.maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + scanReq.minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + //Scan with invalid sessionId. + //This results in SME using the first available session to scan. + status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq, + &scanId, NULL, NULL); + + return (status); +} + + + + +eHalStatus csrIssueRoamAfterLostlinkScan(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamReason reason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + smsLog(pMac, LOG1, " csrIssueRoamAfterLostlinkScan called"); + if(pSession->fCancelRoaming) + { + smsLog(pMac, LOGW, " lostlink roaming is cancelled"); + csrScanStartIdleScan(pMac); + status = eHAL_STATUS_SUCCESS; + break; + } + //Here is the profile we need to connect to + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + if(NULL == pSession->pCurRoamProfile) + { + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + if(eCsrLostLink1 == reason) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + } + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, reason, + roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + } + }//Have scan result + } + }while(0); + if(pScanFilter) + { + //we need to free memory for filter if profile exists + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return (status); +} + + +eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tANI_U8 sessionId, + void *pContext, void *callback, + tANI_U32 scanID) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.callback = callback; + pScanCmd->u.scanCmd.pContext = pContext; + pScanCmd->u.scanCmd.reason = eCsrScanGetScanChnInfo; + if (callback) + { + //use same scanID as maintained in pAdapter + pScanCmd->u.scanCmd.scanID = scanID; + } + else + { + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = + pMac->scan.nextScanID++; //let it wrap around + } + + pScanCmd->sessionId = sessionId; + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} + + +eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " Lostlink scan 1 failed"); + if(pSession->fCancelRoaming) + { + csrScanStartIdleScan(pMac); + } + else if(pSession->pCurRoamProfile) + { + //We fail lostlink1 but there may be other BSS in the cached result fit the profile. Give it a try first + if(pSession->pCurRoamProfile->SSIDs.numOfSSIDs == 0 || + pSession->pCurRoamProfile->SSIDs.numOfSSIDs > 1) + { + //try lostlink scan2 + status = csrScanRequestLostLink2(pMac, sessionId); + } + else if(!pSession->pCurRoamProfile->ChannelInfo.ChannelList || + pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) + { + //go straight to lostlink scan3 + status = csrScanRequestLostLink3(pMac, sessionId); + } + else + { + //we are done with lostlink + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + status = eHAL_STATUS_SUCCESS; + } + } + else + { + status = csrScanRequestLostLink3(pMac, sessionId); + } + + return (status); +} + + + +eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " Lostlink scan 2 failed"); + if(pSession->fCancelRoaming) + { + csrScanStartIdleScan(pMac); + } + else if(!pSession->pCurRoamProfile || !pSession->pCurRoamProfile->ChannelInfo.ChannelList || + pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) + { + //try lostlink scan3 + status = csrScanRequestLostLink3(pMac, sessionId); + } + else + { + //we are done with lostlink + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + } + + return (status); +} + + + +eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOGW, " Lostlink scan 3 failed"); + if(eANI_BOOLEAN_TRUE == csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + //we are done with lostlink + csrScanStartIdleScan(pMac); + } + + return (status); +} + + + + +//Lostlink1 scan is to actively scan the last connected profile's SSID on all matched BSS channels. +//If no roam profile (it should not), it is like lostlinkscan3 +eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrScanResultFilter *pScanFilter = NULL; + tScanResultHandle hBSSList = NULL; + tCsrScanResultInfo *pScanResult = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink1; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(pSession->connectedProfile.SSID.length) + { + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1; + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID, + &pSession->connectedProfile.SSID, sizeof(tSirMacSSid)); + } + else + { + pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 0; + } + if(pSession->pCurRoamProfile) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + //Don't change variable status here because whether we can get result or not, the command goes to PE. + //The status is also used to indicate whether the command is queued. Not success meaning not queue + if(HAL_STATUS_SUCCESS((csrScanGetResult(pMac, pScanFilter, &hBSSList))) && hBSSList) + { + tANI_U8 i, nChn = 0; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = + vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && + nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pScanResult->BssDescriptor.channelId) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId; + } + } + //Include the last connected BSS' channel + if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel)) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pSession->connectedProfile.operationChannel) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pSession->connectedProfile.operationChannel; + } + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn; + } + else + { + if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel)) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(1); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + //just try the last connected channel + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0] = pSession->connectedProfile.operationChannel; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1; + } + else + { + break; + } + } + } + } + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink1 failed with status %d", status); + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + status = csrScanHandleFailedLostlink1( pMac, sessionId ); + } + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + + return( status ); +} + + +//Lostlink2 scan is to actively scan the all SSIDs of the last roaming profile's on all matched BSS channels. +//Since MAC doesn't support multiple SSID, we scan all SSIDs and filter them afterwards +eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrScanResultFilter *pScanFilter = NULL; + tScanResultHandle hBSSList = NULL; + tCsrScanResultInfo *pScanResult = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink2; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(pSession->pCurRoamProfile) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + if(hBSSList) + { + tANI_U8 i, nChn = 0; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = + vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && + nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pScanResult->BssDescriptor.channelId) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId; + } + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn; + } + } + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + //Put to the head in pending queue + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink2 failed with status %d", status); + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + status = csrScanHandleFailedLostlink2( pMac, sessionId ); + } + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + + return( status ); +} + + +//To actively scan all valid channels +eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink3; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.maxChnTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.minChnTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + //Put to the head of pending queue + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink3 failed with status %d", status); + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + } + + return( status ); +} + + +eHalStatus csrScanHandleSearchForSSID(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + tCsrScanResultFilter *pScanFilter = NULL; + tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile; + tANI_U32 sessionId = pCommand->sessionId; +#ifdef FEATURE_WLAN_BTAMP_UT_RF + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); +#endif + do + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* If this scan is for LFR */ + if (pMac->roam.neighborRoamInfo[sessionId].uOsRequestedHandoff) { + /* Notify LFR state m/c */ + if (eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, + sessionId, + eHAL_STATUS_SUCCESS)) { + csrNeighborRoamStartLfrScan(pMac, sessionId); + } + status = eHAL_STATUS_SUCCESS; + break; + } +#endif + //If there is roam command waiting, ignore this roam because the newer roam command is the one to execute + if(csrIsRoamCommandWaitingForSession(pMac, sessionId)) + { + smsLog(pMac, LOGW, FL(" aborts because roam command waiting")); + break; + } + if(pProfile == NULL) + break; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(CSR_INVALID_SCANRESULT_HANDLE != hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + //We haven't done anything to this profile + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, eCSR_ROAM_RESULT_FAILURE); + //In case we have nothing else to do, restart idle scan + if(csrIsConnStateDisconnected(pMac, sessionId) && !csrIsRoamCommandWaiting(pMac)) + { + status = csrScanStartIdleScan(pMac); + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //In case of WDS station, let it retry. + if( CSR_IS_WDS_STA(pProfile) ) + { + //Save the roma profile so we can retry + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfilee, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + } + if (pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + + return (status); +} + + +eHalStatus csrScanHandleSearchForSSIDFailure(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* If this scan is for LFR */ + if (pMac->roam.neighborRoamInfo[sessionId].uOsRequestedHandoff) { + /* Notify LFR state m/c */ + if (eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, + sessionId, + eHAL_STATUS_FAILURE)) { + csrNeighborRoamStartLfrScan(pMac, sessionId); + } + return eHAL_STATUS_SUCCESS; + } +#endif + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#if defined(WLAN_DEBUG) + if(pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs == 1) + { + char str[36]; + vos_mem_copy(str, + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.ssId, + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length); + str[pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length] = 0; + smsLog(pMac, LOGW, FL(" SSID = %s"), str); + } +#endif + //Check whether it is for start ibss. No need to do anything if it is a JOIN request + if(pProfile && CSR_IS_START_IBSS(pProfile)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("failed to issue startIBSS command with status = 0x%08X"), status); + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + } + else + { + eCsrRoamResult roamResult = eCSR_ROAM_RESULT_FAILURE; + + if(csrIsConnStateDisconnected(pMac, sessionId) && + !csrIsRoamCommandWaitingForSession(pMac, sessionId)) + { + status = csrScanStartIdleScan(pMac); + } + if((NULL == pProfile) || !csrIsBssTypeIBSS(pProfile->BSSType)) + { + //Only indicate assoc_completion if we indicate assoc_start. + if(pSession->bRefAssocStartCnt > 0) + { + tCsrRoamInfo *pRoamInfo = NULL, roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + pRoamInfo = &roamInfo; + if(pCommand->u.roamCmd.pRoamBssEntry) + { + tCsrScanResult *pScanResult = + GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, + tCsrScanResult, Link); + roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor; + } + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + pSession->bRefAssocStartCnt--; + csrRoamCallCallback(pMac, sessionId, pRoamInfo, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_FAILURE); + } + else + { + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_FAILURE); + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //In case of WDS station, let it retry. + if( CSR_IS_WDS_STA(pProfile) ) + { + //Save the roma profile so we can retry + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + } + else + { + roamResult = eCSR_ROAM_RESULT_IBSS_START_FAILED; + } + csrRoamCompletion(pMac, sessionId, NULL, pCommand, roamResult, eANI_BOOLEAN_FALSE); + } + + return (status); +} + + +//After scan for cap changes, issue a roaming command to either reconnect to the AP or pick another one to connect +eHalStatus csrScanHandleCapChangeScanComplete(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + do + { + //Here is the profile we need to connect to + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + if (NULL == pSession) break; + if (NULL == pSession->pCurRoamProfile) + { + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, + eCsrCapsChange, 0, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + } + }//Have scan result + else + { + smsLog(pMac, LOGW, FL("cannot find matching BSS of " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid)); + //Disconnect + csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return (status); +} + + + +eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanList) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tScanResultList *pScanList = (tScanResultList *)hScanList; + + if(pScanList) + { + status = csrLLScanPurgeResult(pMac, &pScanList->List); + csrLLClose(&pScanList->List); + vos_mem_free(pScanList); + } + return (status); +} + + +static tANI_U32 csrGetBssPreferValue(tpAniSirGlobal pMac, int rssi) +{ + tANI_U32 ret = 0; + int i = CSR_NUM_RSSI_CAT - 1; + + while(i >= 0) + { + if(rssi >= pMac->roam.configParam.RSSICat[i]) + { + ret = pMac->roam.configParam.BssPreferValue[i]; + break; + } + i--; + }; + + return (ret); +} + + +//Return a CapValue base on the capabilities of a BSS +static tANI_U32 csrGetBssCapValue(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + tANI_U32 ret = CSR_BSS_CAP_VALUE_NONE; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if(CSR_IS_ROAM_PREFER_5GHZ(pMac)) + { + if((pBssDesc) && CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId)) + { + ret += CSR_BSS_CAP_VALUE_5GHZ; + } + } +#endif + /* if strict select 5GHz is non-zero then ignore the capability checking */ + if (pIes && !CSR_IS_SELECT_5GHZ_MARGIN(pMac)) + { + //We only care about 11N capability + if(pIes->HTCaps.present) + { + ret += CSR_BSS_CAP_VALUE_HT; + } + if(CSR_IS_QOS_BSS(pIes)) + { + ret += CSR_BSS_CAP_VALUE_WMM; + //Give advantage to UAPSD + if(CSR_IS_UAPSD_BSS(pIes)) + { + ret += CSR_BSS_CAP_VALUE_UAPSD; + } + } + } + + return (ret); +} + + +//To check whther pBss1 is better than pBss2 +static tANI_BOOLEAN csrIsBetterBss(tCsrScanResult *pBss1, tCsrScanResult *pBss2) +{ + tANI_BOOLEAN ret; + + if(CSR_IS_BETTER_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue)) + { + ret = eANI_BOOLEAN_TRUE; + } + else if(CSR_IS_EQUAL_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue)) + { + if(CSR_IS_BETTER_CAP_VALUE(pBss1->capValue, pBss2->capValue)) + { + ret = eANI_BOOLEAN_TRUE; + } + else + { + ret = eANI_BOOLEAN_FALSE; + } + } + else + { + ret = eANI_BOOLEAN_FALSE; + } + + return (ret); +} + + +#ifdef FEATURE_WLAN_LFR +//Add the channel to the occupiedChannels array +static void csrScanAddToOccupiedChannels( + tpAniSirGlobal pMac, + tCsrScanResult *pResult, + tANI_U8 sessionId, + tCsrChannel *pOccupiedChannels, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status; + tANI_U8 channel; + tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels; + tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList; + + channel = pResult->Result.BssDescriptor.channelId; + + if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, channel) + && csrNeighborRoamConnectedProfileMatch(pMac, sessionId, pResult, pIes)) + { + status = csrAddToChannelListFront(pOccupiedChannelList, numOccupiedChannels, channel); + if(HAL_STATUS_SUCCESS(status)) + { + pOccupiedChannels->numChannels++; + smsLog(pMac, LOG2, FL("Added channel %d to the list (count=%d)"), + channel, pOccupiedChannels->numChannels); + if (pOccupiedChannels->numChannels > CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN) + pOccupiedChannels->numChannels = CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN; + } + } +} +#endif + +//Put the BSS into the scan result list +//pIes can not be NULL +static void csrScanAddResult(tpAniSirGlobal pMac, tCsrScanResult *pResult, + tDot11fBeaconIEs *pIes, tANI_U32 sessionId) +{ +#ifdef FEATURE_WLAN_LFR + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; +#endif + + pResult->preferValue = + csrGetBssPreferValue(pMac, (int)pResult->Result.BssDescriptor.rssi); + pResult->capValue = + csrGetBssCapValue(pMac, &pResult->Result.BssDescriptor, pIes); + csrLLInsertTail( &pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK ); +#ifdef FEATURE_WLAN_LFR + if(0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + /* Build the occupied channel list, only if "gNeighborScanChannelList" is + NOT set in the cfg.ini file */ + csrScanAddToOccupiedChannels(pMac, pResult, sessionId, + &pMac->scan.occupiedChannels[sessionId], + pIes); + } +#endif +} + + +eHalStatus csrScanGetResult(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult) +{ + eHalStatus status; + tScanResultList *pRetList; + tCsrScanResult *pResult, *pBssDesc; + tANI_U32 count = 0; + tListElem *pEntry; + tANI_U32 bssLen, allocLen; + eCsrEncryptionType uc = eCSR_ENCRYPT_TYPE_NONE, mc = eCSR_ENCRYPT_TYPE_NONE; + eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM; + tDot11fBeaconIEs *pIes, *pNewIes; + tANI_BOOLEAN fMatch; + tANI_U16 i = 0; + + if(phResult) + { + *phResult = CSR_INVALID_SCANRESULT_HANDLE; + } + + if (pMac->roam.configParam.nSelect5GHzMargin) + { + pMac->scan.inScanResultBestAPRssi = -128; +#ifdef WLAN_DEBUG_ROAM_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("nSelect5GHzMargin")); +#endif + csrLLLock(&pMac->scan.scanResultList); + + /* Find out the best AP Rssi going thru the scan results */ + pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); + while ( NULL != pEntry) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + fMatch = FALSE; + + if (pFilter) + for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++) + { + fMatch = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length, + pBssDesc->Result.ssId.ssId, + pBssDesc->Result.ssId.length, eANI_BOOLEAN_TRUE ); + if (fMatch) + { + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + + //At this time, pBssDescription->Result.pvIes may be NULL + if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pBssDesc->Result.BssDescriptor, &pIes))) ) + { + continue; + } + + smsLog(pMac, LOG1, FL("SSID Matched")); + + if ( pFilter->bOSENAssociation ) + { + fMatch = TRUE; + } + else + { +#ifdef WLAN_FEATURE_11W + fMatch = csrIsSecurityMatch(pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + &pFilter->MFPEnabled, + &pFilter->MFPRequired, + &pFilter->MFPCapable, + &pBssDesc->Result.BssDescriptor, + pIes, NULL, NULL, NULL ); +#else + fMatch = csrIsSecurityMatch(pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + NULL, NULL, NULL, + &pBssDesc->Result.BssDescriptor, + pIes, NULL, NULL, NULL ); +#endif + } + if ((pBssDesc->Result.pvIes == NULL) && pIes) + vos_mem_free(pIes); + + if (fMatch) + smsLog(pMac, LOG1, FL(" Security Matched")); + } + } + + if (fMatch && (pBssDesc->Result.BssDescriptor.rssi > pMac->scan.inScanResultBestAPRssi)) + { + smsLog(pMac, LOG1, FL("Best AP Rssi changed from %d to %d"), + pMac->scan.inScanResultBestAPRssi, + pBssDesc->Result.BssDescriptor.rssi); + pMac->scan.inScanResultBestAPRssi = pBssDesc->Result.BssDescriptor.rssi; + } + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + } + + if ( -128 != pMac->scan.inScanResultBestAPRssi) + { + smsLog(pMac, LOG1, FL("Best AP Rssi is %d"), pMac->scan.inScanResultBestAPRssi); + /* Modify Rssi category based on best AP Rssi */ + csrAssignRssiForCategory(pMac, pMac->scan.inScanResultBestAPRssi, pMac->roam.configParam.bCatRssiOffset); + pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); + while ( NULL != pEntry) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + /* re-assign preference value based on modified rssi bucket */ + pBssDesc->preferValue = csrGetBssPreferValue(pMac, (int)pBssDesc->Result.BssDescriptor.rssi); + + smsLog(pMac, LOG2, FL("BSSID("MAC_ADDRESS_STR + ") Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s"), + MAC_ADDR_ARRAY(pBssDesc->Result.BssDescriptor.bssId), + pBssDesc->Result.BssDescriptor.rssi, + pBssDesc->Result.BssDescriptor.channelId, + pBssDesc->preferValue, + pBssDesc->Result.ssId.length, pBssDesc->Result.ssId.ssId); + + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + } + } + + csrLLUnlock(&pMac->scan.scanResultList); + } + + pRetList = vos_mem_malloc(sizeof(tScanResultList)); + if ( NULL == pRetList ) + status = eHAL_STATUS_FAILURE; + else + { + status = eHAL_STATUS_SUCCESS; + vos_mem_set(pRetList, sizeof(tScanResultList), 0); + csrLLOpen(pMac->hHdd, &pRetList->List); + pRetList->pCurEntry = NULL; + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + //if pBssDesc->Result.pvIes is NULL, we need to free any memory allocated by csrMatchBSS + //for any error condition, otherwiase, it will be freed later. + //reset + fMatch = eANI_BOOLEAN_FALSE; + pNewIes = NULL; + + if(pFilter) + { + fMatch = csrMatchBSS(pMac, &pBssDesc->Result.BssDescriptor, pFilter, &auth, &uc, &mc, &pIes); +#ifdef WLAN_DEBUG_ROAM_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("csrMatchBSS fmatch %d"), fMatch); +#endif + if( NULL != pIes ) + { + //Only save it when matching + if(fMatch) + { + if( !pBssDesc->Result.pvIes ) + { + //csrMatchBSS allocates the memory. Simply pass it and it is freed later + pNewIes = pIes; + } + else + { + //The pIes is allocated by someone else. make a copy + //Only to save parsed IEs if caller provides a filter. Most likely the caller + //is using to for association, hence save the parsed IEs + pNewIes = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pNewIes ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_copy(pNewIes, pIes, sizeof( tDot11fBeaconIEs )); + } + else + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for IEs")); + //Need to free memory allocated by csrMatchBSS + if( !pBssDesc->Result.pvIes ) + { + vos_mem_free(pIes); + } + break; + } + } + }//fMatch + else if( !pBssDesc->Result.pvIes ) + { + vos_mem_free(pIes); + } + } + } + if(NULL == pFilter || fMatch) + { + bssLen = pBssDesc->Result.BssDescriptor.length + sizeof(pBssDesc->Result.BssDescriptor.length); + allocLen = sizeof( tCsrScanResult ) + bssLen; + pResult = vos_mem_malloc(allocLen); + if ( NULL == pResult ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for scan result, len=%d"), allocLen); + if(pNewIes) + { + vos_mem_free(pNewIes); + } + break; + } + vos_mem_set(pResult, allocLen, 0); + pResult->capValue = pBssDesc->capValue; + pResult->preferValue = pBssDesc->preferValue; + pResult->ucEncryptionType = uc; + pResult->mcEncryptionType = mc; + pResult->authType = auth; + pResult->Result.ssId = pBssDesc->Result.ssId; + pResult->Result.timer = pBssDesc->Result.timer; + //save the pIes for later use + pResult->Result.pvIes = pNewIes; + //save bss description + vos_mem_copy(&pResult->Result.BssDescriptor, + &pBssDesc->Result.BssDescriptor, bssLen); + //No need to lock pRetList because it is locally allocated and no outside can access it at this time + if(csrLLIsListEmpty(&pRetList->List, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_NOLOCK); + } + else + { + //To sort the list + tListElem *pTmpEntry; + tCsrScanResult *pTmpResult; + + pTmpEntry = csrLLPeekHead(&pRetList->List, LL_ACCESS_NOLOCK); + while(pTmpEntry) + { + pTmpResult = GET_BASE_ADDR( pTmpEntry, tCsrScanResult, Link ); + if(csrIsBetterBss(pResult, pTmpResult)) + { + csrLLInsertEntry(&pRetList->List, pTmpEntry, &pResult->Link, LL_ACCESS_NOLOCK); + //To indicate we are done + pResult = NULL; + break; + } + pTmpEntry = csrLLNext(&pRetList->List, pTmpEntry, LL_ACCESS_NOLOCK); + } + if(pResult != NULL) + { + //This one is not better than any one + csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_NOLOCK); + } + } + count++; + } + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pMac->scan.scanResultList); + + smsLog(pMac, LOG2, FL("return %d BSS"), csrLLCount(&pRetList->List)); + + if( !HAL_STATUS_SUCCESS(status) || (phResult == NULL) ) + { + //Fail or No one wants the result. + csrScanResultPurge(pMac, (tScanResultHandle)pRetList); + } + else + { + if(0 == count) + { + //We are here meaning the there is no match + csrLLClose(&pRetList->List); + vos_mem_free(pRetList); + status = eHAL_STATUS_E_NULL_VALUE; + } + else if(phResult) + { + *phResult = pRetList; + } + } + }//Allocated pRetList + + return (status); +} + +/* + * NOTE: This routine is being added to make + * sure that scan results are not being flushed + * while roaming. If the scan results are flushed, + * we are unable to recover from + * csrRoamRoamingStateDisassocRspProcessor. + * If it is needed to remove this routine, + * first ensure that we recover gracefully from + * csrRoamRoamingStateDisassocRspProcessor if + * csrScanGetResult returns with a failure because + * of not being able to find the roaming BSS. + */ +tANI_U8 csrScanFlushDenied(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + switch(pMac->roam.neighborRoamInfo[sessionId].neighborRoamState) { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE: + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + return (pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + default: + return 0; + } +} + +eHalStatus csrScanFlushResult(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 isFlushDenied = csrScanFlushDenied(pMac, sessionId); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + if (isFlushDenied) { + smsLog(pMac, LOGW, "%s: scan flush denied in roam state %d", + __func__, isFlushDenied); + return eHAL_STATUS_FAILURE; + } + + /* prepare and send clear cached scan results msg to lim */ + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_CLEAR_LIM_SCAN_CACHE); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + palSendMBMessage(pMac->hHdd, pMsg); + } else { + status = eHAL_STATUS_FAILED_ALLOC; + } + + csrLLScanPurgeResult( pMac, &pMac->scan.tempScanResults ); + csrLLScanPurgeResult( pMac, &pMac->scan.scanResultList ); + return( status ); +} + +eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal pMac, v_BOOL_t flushP2P) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pFreeElem; + tCsrScanResult *pBssDesc; + tDblLinkList *pList = &pMac->scan.scanResultList; + + csrLLLock(pList); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + while( pEntry != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if( flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId, + "DIRECT-", 7) ) + { + pFreeElem = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK); + csrFreeScanResultEntry( pMac, pBssDesc ); + continue; + } + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + } + + csrLLUnlock(pList); + + return (status); +} + +void csrScanFlushBssEntry(tpAniSirGlobal pMac, + tpSmeCsaOffloadInd pCsaOffloadInd) +{ + tListElem *pEntry,*pFreeElem; + tCsrScanResult *pBssDesc; + tDblLinkList *pList = &pMac->scan.scanResultList; + + csrLLLock(pList); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + while( pEntry != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if( vos_mem_compare(pBssDesc->Result.BssDescriptor.bssId, + pCsaOffloadInd->bssId, sizeof(tSirMacAddr)) ) + { + pFreeElem = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK); + csrFreeScanResultEntry( pMac, pBssDesc ); + smsLog( pMac, LOG1, FL("Removed BSS entry:%pM"), + pCsaOffloadInd->bssId); + continue; + } + + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + } + + csrLLUnlock(pList); +} + +/** + * csrCheck11dChannel + * + *FUNCTION: + * This function is called from csrScanFilterResults function and + * compare channel number with given channel list. + * + *LOGIC: + * Check Scan result channel number with CFG channel list + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param channelId channel number + * @param pChannelList Pointer to channel list + * @param numChannels Number of channel in channel list + * + * @return Status + */ + +eHalStatus csrCheck11dChannel(tANI_U8 channelId, tANI_U8 *pChannelList, tANI_U32 numChannels) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U8 i = 0; + + for (i = 0; i < numChannels; i++) + { + if(pChannelList[ i ] == channelId) + { + status = eHAL_STATUS_SUCCESS; + break; + } + } + return status; +} + +/** + * csrScanFilterResults + * + *FUNCTION: + * This function is called from csrApplyCountryInformation function and + * filter scan result based on valid channel list number. + * + *LOGIC: + * Get scan result from scan list and Check Scan result channel number + * with 11d channel list if channel number is found in 11d channel list + * then do not remove scan result entry from scan list + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * + * @return Status + */ + +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pTempEntry; + tCsrScanResult *pBssDesc; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + /* Get valid channels list from CFG */ + if (!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + pMac->roam.validChannelList, &len))) + { + smsLog( pMac, LOGE, "Failed to get Channel list from CFG"); + } + + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK ); + if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId, + pMac->roam.validChannelList, len)) + { + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + else + { + smsLog( pMac, LOG1, FL("%d is a Valid channel"), + pBssDesc->Result.BssDescriptor.channelId); + } + pEntry = pTempEntry; + } + + pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK ); + if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId, + pMac->roam.validChannelList, len)) + { + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + else + { + smsLog( pMac, LOG1, FL("%d is a Valid channel"), + pBssDesc->Result.BssDescriptor.channelId); + } + pEntry = pTempEntry; + } + return status; +} + + +eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tScanResultList *pRetList, *pInList = (tScanResultList *)hIn; + tCsrScanResult *pResult, *pScanResult; + tANI_U32 count = 0; + tListElem *pEntry; + tANI_U32 bssLen, allocLen; + + if(phResult) + { + *phResult = CSR_INVALID_SCANRESULT_HANDLE; + } + pRetList = vos_mem_malloc(sizeof(tScanResultList)); + if ( NULL == pRetList ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pRetList, sizeof(tScanResultList), 0); + csrLLOpen(pMac->hHdd, &pRetList->List); + pRetList->pCurEntry = NULL; + csrLLLock(&pMac->scan.scanResultList); + csrLLLock(&pInList->List); + + pEntry = csrLLPeekHead( &pInList->List, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pScanResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + bssLen = pScanResult->Result.BssDescriptor.length + sizeof(pScanResult->Result.BssDescriptor.length); + allocLen = sizeof( tCsrScanResult ) + bssLen; + pResult = vos_mem_malloc(allocLen); + if ( NULL == pResult ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, (tScanResultHandle *)pRetList); + count = 0; + break; + } + vos_mem_set(pResult, allocLen , 0); + vos_mem_copy(&pResult->Result.BssDescriptor, &pScanResult->Result.BssDescriptor, bssLen); + if( pScanResult->Result.pvIes ) + { + pResult->Result.pvIes = vos_mem_malloc(sizeof( tDot11fBeaconIEs )); + if ( NULL == pResult->Result.pvIes ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + //Free the memory we allocate above first + vos_mem_free(pResult); + csrScanResultPurge(pMac, (tScanResultHandle *)pRetList); + count = 0; + break; + } + vos_mem_copy(pResult->Result.pvIes, pScanResult->Result.pvIes, + sizeof( tDot11fBeaconIEs )); + } + csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_LOCK); + count++; + pEntry = csrLLNext( &pInList->List, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pInList->List); + csrLLUnlock(&pMac->scan.scanResultList); + + if(HAL_STATUS_SUCCESS(status)) + { + if(0 == count) + { + csrLLClose(&pRetList->List); + vos_mem_free(pRetList); + status = eHAL_STATUS_E_NULL_VALUE; + } + else if(phResult) + { + *phResult = pRetList; + } + } + }//Allocated pRetList + + return (status); +} + + + +eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf; + + if((eWNI_SME_SCAN_RSP == pMsg->type) || (eWNI_SME_GET_SCANNED_CHANNEL_RSP == pMsg->type)) + { + status = csrScanSmeScanResponse( pMac, pMsgBuf ); + } + else + { + if(pMsg->type == eWNI_SME_UPPER_LAYER_ASSOC_CNF) + { + tCsrRoamSession *pSession; + tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf; + tCsrRoamInfo roamInfo; + tCsrRoamInfo *pRoamInfo = NULL; + tANI_U32 sessionId; + eHalStatus status; + smsLog( pMac, LOG1, FL("Scanning : ASSOCIATION confirmation can be given to upper layer ")); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + pRoamInfo = &roamInfo; + pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pUpperLayerAssocCnf->bssId, &sessionId ); + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid; + pRoamInfo->rsnIELen = (tANI_U8)pUpperLayerAssocCnf->rsnIE.length; + pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata; + pRoamInfo->addIELen = (tANI_U8)pUpperLayerAssocCnf->addIE.length; + pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, pUpperLayerAssocCnf->peerMacAddr, sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pUpperLayerAssocCnf->bssId, sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta; + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) ) + { + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; + pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + } + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + vos_sleep( 100 ); + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + } + + } + else + { + + if( csrIsAnySessionInConnectState( pMac ) ) + { + //In case of we are connected, we need to check whether connect status changes + //because scan may also run while connected. + csrRoamCheckForLinkStatusChange( pMac, ( tSirSmeRsp * )pMsgBuf ); + } + else + { + smsLog( pMac, LOGW, "Message [0x%04x] received in state, when expecting Scan Response", pMsg->type ); + } + } + } + + return (status); +} + + + +void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr, tSirBssDescription *pOldBssDescr) +{ + int idx, len; + tANI_U8 *pbIe; + + //If failed to remove, assuming someone else got it. + if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) && + (0 == pNewBssDescr->WscIeLen)) + { + idx = 0; + len = pOldBssDescr->length - sizeof(tSirBssDescription) + + sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)pOldBssDescr->ieFields; + //Save WPS IE if it exists + pNewBssDescr->WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Founrd it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy(pNewBssDescr->WscIeProbeRsp, pbIe, pbIe[1] + 2); + pNewBssDescr->WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } +} + + + +//pIes may be NULL +tANI_BOOLEAN csrRemoveDupBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDescr, + tDot11fBeaconIEs *pIes, tAniSSID *pSsid, v_TIME_t *timer, tANI_BOOLEAN fForced ) +{ + tListElem *pEntry; + + tCsrScanResult *pBssDesc; + tANI_BOOLEAN fRC = FALSE; + + // Walk through all the chained BssDescriptions. If we find a chained BssDescription that + // matches the BssID of the BssDescription passed in, then these must be duplicate scan + // results for this Bss. In that case, remove the 'old' Bss description from the linked list. + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType + // matches + if ( csrIsDuplicateBssDescription( pMac, &pBssDesc->Result.BssDescriptor, + pSirBssDescr, pIes, fForced ) ) + { + int32_t rssi_new, rssi_old; + + rssi_new = (int32_t) pSirBssDescr->rssi; + rssi_old = (int32_t) pBssDesc->Result.BssDescriptor.rssi; + rssi_new = ((rssi_new * CSR_SCAN_RESULT_RSSI_WEIGHT) + + rssi_old * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT)) / 100; + pSirBssDescr->rssi = (tANI_S8) rssi_new; + + rssi_new = (int32_t) pSirBssDescr->rssi_raw; + rssi_old = (int32_t) pBssDesc->Result.BssDescriptor.rssi_raw; + rssi_new = ((rssi_new * CSR_SCAN_RESULT_RSSI_WEIGHT) + + rssi_old * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT)) / 100; + pSirBssDescr->rssi_raw = (tANI_S8) rssi_new; + + // Remove the 'old' entry from the list.... + if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ) ) + { + // !we need to free the memory associated with this node + //If failed to remove, assuming someone else got it. + *pSsid = pBssDesc->Result.ssId; + *timer = pBssDesc->Result.timer; + csrCheckNSaveWscIe(pMac, pSirBssDescr, &pBssDesc->Result.BssDescriptor); + + csrFreeScanResultEntry( pMac, pBssDesc ); + } + else + { + smsLog( pMac, LOGW, FL( " fail to remove entry" ) ); + } + fRC = TRUE; + + // If we found a match, we can stop looking through the list. + break; + } + + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ); + } + + return fRC; +} + + +eHalStatus csrAddPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrAddPMKIDCandidateList called pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate); + if( pIes ) + { + // check if this is a RSN BSS + if( pIes->RSN.present ) + { + // Check if the BSS is capable of doing pre-authentication + if( pSession->NumPmkidCandidate < CSR_MAX_PMKID_ALLOWED ) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&secEvent, sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid, 6); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + // if yes, then add to PMKIDCandidateList + vos_mem_copy(pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].BSSID, + pBssDesc->bssId, VOS_MAC_ADDR_SIZE); + // Bit 0 offirst byte - PreAuthentication Capability + if ( (pIes->RSN.RSN_Cap[0] >> 0) & 0x1 ) + { + pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported + = eANI_BOOLEAN_TRUE; + } + else + { + pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported + = eANI_BOOLEAN_FALSE; + } + pSession->NumPmkidCandidate++; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + } + + return (status); +} + +//This function checks whether new AP is found for the current connected profile +//If it is found, it return the sessionId, else it return invalid sessionID +eHalStatus csrProcessBSSDescForPMKIDList(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes, + tANI_U8 sessionId) +{ + tCsrRoamSession *pSession; + tDot11fBeaconIEs *pIesLocal = pIes; + eHalStatus status = eHAL_STATUS_FAILURE; + + if (pIesLocal || + HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs( + pMac, pBssDesc, &pIesLocal))) { + if (CSR_IS_SESSION_VALID(pMac, sessionId)) { + pSession = CSR_GET_SESSION(pMac, sessionId); + if (csrIsConnStateConnectedInfra(pMac, sessionId) && + (eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType)) { + if (csrMatchBSSToConnectProfile(pMac, + &pSession->connectedProfile, + pBssDesc, pIesLocal)) { + /* This new BSS fits the current profile connected */ + if (!HAL_STATUS_SUCCESS(csrAddPMKIDCandidateList(pMac, + sessionId, pBssDesc, pIesLocal))) { + smsLog(pMac, LOGE, + FL("csrAddPMKIDCandidateList failed")); + } else { + status = eHAL_STATUS_SUCCESS; + } + } + } + } + + if (!pIes) { + vos_mem_free(pIesLocal); + } + } + return status; +} + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrAddBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrAddBKIDCandidateList called pMac->scan.NumBkidCandidate = %d", + pSession->NumBkidCandidate); + if( pIes ) + { + // check if this is a WAPI BSS + if( pIes->WAPI.present ) + { + // Check if the BSS is capable of doing pre-authentication + if( pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED ) + { + + // if yes, then add to BKIDCandidateList + vos_mem_copy(pSession->BkidCandidateInfo[pSession->NumBkidCandidate].BSSID, + pBssDesc->bssId, VOS_MAC_ADDR_SIZE); + if ( pIes->WAPI.preauth ) + { + pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported + = eANI_BOOLEAN_TRUE; + } + else + { + pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported + = eANI_BOOLEAN_FALSE; + } + pSession->NumBkidCandidate++; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + } + + return (status); +} + +//This function checks whether new AP is found for the current connected profile +//if so add to BKIDCandidateList +tANI_BOOLEAN csrProcessBSSDescForBKIDList(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fRC = FALSE; + tDot11fBeaconIEs *pIesLocal = pIes; + tANI_U32 sessionId; + tCsrRoamSession *pSession; + + if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) ) + { + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if( csrIsConnStateConnectedInfra( pMac, sessionId ) && + eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == pSession->connectedProfile.AuthType) + { + if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile,pBssDesc, pIesLocal)) + { + //this new BSS fits the current profile connected + if(HAL_STATUS_SUCCESS(csrAddBKIDCandidateList(pMac, sessionId, pBssDesc, pIesLocal))) + { + fRC = TRUE; + } + } + } + } + } + if(!pIes) + { + vos_mem_free(pIesLocal); + } + + } + return fRC; +} + +#endif + + +static void csrMoveTempScanResultsToMainList(tpAniSirGlobal pMac, + tANI_U8 reason, + tANI_U8 sessionId) +{ + tListElem *pEntry; + tCsrScanResult *pBssDescription; + tANI_BOOLEAN fDupBss; +#ifdef FEATURE_WLAN_WAPI + tANI_BOOLEAN fNewWapiBSSForCurConnection = eANI_BOOLEAN_FALSE; +#endif /* FEATURE_WLAN_WAPI */ + tDot11fBeaconIEs *pIesLocal = NULL; + tAniSSID tmpSsid; + v_TIME_t timer=0; + + tmpSsid.length = 0; + + // remove the BSS descriptions from temporary list + while( ( pEntry = csrLLRemoveTail( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ) ) != NULL) + { + pBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + smsLog( pMac, LOGW, "...Bssid= "MAC_ADDRESS_STR" chan= %d, rssi = -%d", + MAC_ADDR_ARRAY(pBssDescription->Result.BssDescriptor.bssId), + pBssDescription->Result.BssDescriptor.channelId, + pBssDescription->Result.BssDescriptor.rssi * (-1) ); + + //At this time, pBssDescription->Result.pvIes may be NULL + pIesLocal = (tDot11fBeaconIEs *)( pBssDescription->Result.pvIes ); + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssDescription->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" Cannot pared IEs")); + csrFreeScanResultEntry(pMac, pBssDescription); + continue; + } + fDupBss = csrRemoveDupBssDescription( pMac, &pBssDescription->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE ); + //Check whether we have reach out limit, but don't lose the LFR candidates came from FW + if( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !( eCsrScanGetLfrResult == reason ) +#endif + ) + { + //Limit reach + smsLog(pMac, LOGW, FL(" BSS limit reached")); + //Free the resources + if( (pBssDescription->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + csrFreeScanResultEntry(pMac, pBssDescription); + //Continue because there may be duplicated BSS + continue; + } + // check for duplicate scan results + if ( !fDupBss ) + { + if (HAL_STATUS_SUCCESS(csrProcessBSSDescForPMKIDList(pMac, + &pBssDescription->Result.BssDescriptor, + pIesLocal, sessionId))) { + /* Found a new BSS */ + csrRoamCallCallback(pMac, sessionId, NULL, 0, + eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NONE); + } + } + else + { + //Check if the new one has SSID it it, if not, use the older SSID if it exists. + if( (0 == pBssDescription->Result.ssId.length) && tmpSsid.length ) + { + //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only + //if diff of saved SSID time and current time is less than 1 min to avoid + //side effect of saving SSID with old one is that if AP changes its SSID while remain + //hidden, we may never see it and also to address the requirement of + //When we remove hidden ssid from the profile i.e., forget the SSID via + // GUI that SSID shouldn't see in the profile + if( (vos_timer_get_system_time() - timer) <= HIDDEN_TIMER) + { + pBssDescription->Result.timer = timer; + pBssDescription->Result.ssId = tmpSsid; + } + } + } + + //Find a good AP for 11d info + if ( csrIs11dSupported( pMac ) ) + { + // check if country information element is present + if (pIesLocal->Country.present) + { + csrAddVoteForCountryInfo(pMac, pIesLocal->Country.country); + smsLog(pMac, LOGW, FL("11d AP Bssid " MAC_ADDRESS_STR + " chan= %d, rssi = -%d, countryCode %c%c"), + MAC_ADDR_ARRAY( pBssDescription->Result.BssDescriptor.bssId), + pBssDescription->Result.BssDescriptor.channelId, + pBssDescription->Result.BssDescriptor.rssi * (-1), + pIesLocal->Country.country[0],pIesLocal->Country.country[1] ); + } + } + + // append to main list + csrScanAddResult(pMac, pBssDescription, pIesLocal, sessionId); + if ( (pBssDescription->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + } + + /* We don't need to update CC while connected to an AP + which is advertising CC already */ + if (csrIs11dSupported(pMac)) + { + tCsrRoamSession *pSession; + tANI_U32 i; + + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if (CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if (csrIsConnStateConnected(pMac, i)) + { + smsLog(pMac, LOGW, FL("No need for updating CC in" + "connected state")); + goto end; + } + } + } + csrElectedCountryInfo(pMac); + csrLearnCountryInformation( pMac, NULL, NULL, eANI_BOOLEAN_TRUE ); + } + +end: + //If we can find the current 11d info in any of the scan results, or + // a good enough AP with the 11d info from the scan results then no need to + // get into ambiguous state + if(pMac->scan.fAmbiguous11dInfoFound) + { + if((pMac->scan.fCurrent11dInfoMatch)) + { + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + } + } + +#ifdef FEATURE_WLAN_WAPI + if(fNewWapiBSSForCurConnection) + { + //remember it first + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NEW_WAPI_BSS); + } +#endif /* FEATURE_WLAN_WAPI */ + + return; +} + + +static tCsrScanResult * +csrScanSaveBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pBSSDescription, + tDot11fBeaconIEs *pIes, + tANI_U8 sessionId) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tANI_U32 cbBSSDesc; + tANI_U32 cbAllocated; + + // figure out how big the BSS description is (the BSSDesc->length does NOT + // include the size of the length field itself). + cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length ); + + cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc; + + pCsrBssDescription = vos_mem_malloc(cbAllocated); + if ( NULL != pCsrBssDescription ) + { + vos_mem_set(pCsrBssDescription, cbAllocated, 0); + pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + smsLog(pMac, LOGW, + FL(" Set Aging Count = %d for BSS "MAC_ADDRESS_STR" "), + pCsrBssDescription->AgingCount, + MAC_ADDR_ARRAY(pCsrBssDescription->Result.BssDescriptor.bssId)); + vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc); +#if defined(VOSS_ENSBALED) + if ( NULL != pCsrBssDescription->Result.pvIes) + { + VOS_ASSERT( pCsrBssDescription->Result.pvIes == NULL ); + return NULL; + } +#endif + csrScanAddResult(pMac, pCsrBssDescription, pIes, sessionId); + } + + return( pCsrBssDescription ); +} + +// Append a Bss Description... +tCsrScanResult * +csrScanAppendBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescription, + tDot11fBeaconIEs *pIes, + tANI_BOOLEAN fForced, + tANI_U8 sessionId) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tAniSSID tmpSsid; + v_TIME_t timer = 0; + int result; + + tmpSsid.length = 0; + result = csrRemoveDupBssDescription( pMac, pSirBssDescription, pIes, &tmpSsid, &timer, fForced ); + pCsrBssDescription = csrScanSaveBssDescription(pMac, pSirBssDescription, + pIes, sessionId); + if (result && (pCsrBssDescription != NULL)) + { + //Check if the new one has SSID it it, if not, use the older SSID if it exists. + if( (0 == pCsrBssDescription->Result.ssId.length) && tmpSsid.length ) + { + //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only + //if diff of saved SSID time and current time is less than 1 min to avoid + //side effect of saving SSID with old one is that if AP changes its SSID while remain + //hidden, we may never see it and also to address the requirement of + //When we remove hidden ssid from the profile i.e., forget the SSID via + // GUI that SSID shouldn't see in the profile + if((vos_timer_get_system_time()-timer) <= HIDDEN_TIMER) + { + pCsrBssDescription->Result.ssId = tmpSsid; + pCsrBssDescription->Result.timer = timer; + } + } + } + + + return( pCsrBssDescription ); +} + + + +void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList ) +{ + tCsrChannelPowerInfo *pChannelSet; + tListElem *pEntry; + + csrLLLock(pChannelList); + // Remove the channel sets from the learned list and put them in the free list + while( ( pEntry = csrLLRemoveHead( pChannelList, LL_ACCESS_NOLOCK ) ) != NULL) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if( pChannelSet ) + { + vos_mem_free(pChannelSet); + } + } + csrLLUnlock(pChannelList); + return; +} + + +/* + * Save the channelList into the ultimate storage as the final stage of channel + * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power limit are all stored inside this data structure + */ +eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable ) +{ + tANI_U32 i = tableSize / sizeof( tSirMacChanInfo ); + tSirMacChanInfo *pChannelInfo; + tCsrChannelPowerInfo *pChannelSet; + tANI_BOOLEAN f2GHzInfoFound = FALSE; + tANI_BOOLEAN f2GListPurged = FALSE, f5GListPurged = FALSE; + + pChannelInfo = channelTable; + // atleast 3 bytes have to be remaining -- from "countryString" + while ( i-- ) + { + pChannelSet = vos_mem_malloc(sizeof(tCsrChannelPowerInfo)); + if ( NULL != pChannelSet ) + { + vos_mem_set(pChannelSet, sizeof(tCsrChannelPowerInfo), 0); + pChannelSet->firstChannel = pChannelInfo->firstChanNum; + pChannelSet->numChannels = pChannelInfo->numChannels; + + // Now set the inter-channel offset based on the frequency band the channel set lies in + if( (CSR_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) && + ((pChannelSet->firstChannel + (pChannelSet->numChannels - 1)) <= CSR_MAX_24GHz_CHANNEL_NUMBER) ) + + { + pChannelSet->interChannelOffset = 1; + f2GHzInfoFound = TRUE; + } + else if ( (CSR_IS_CHANNEL_5GHZ(pChannelSet->firstChannel)) && + ((pChannelSet->firstChannel + ((pChannelSet->numChannels - 1) * 4)) <= CSR_MAX_5GHz_CHANNEL_NUMBER) ) + { + pChannelSet->interChannelOffset = 4; + f2GHzInfoFound = FALSE; + } + else + { + smsLog( pMac, LOGW, FL("Invalid Channel %d Present in Country IE"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + return eHAL_STATUS_FAILURE; + } + + pChannelSet->txPower = CSR_ROAM_MIN( pChannelInfo->maxTxPower, pMac->roam.configParam.nTxPowerCap ); + + if( f2GHzInfoFound ) + { + if( !f2GListPurged ) + { + // purge previous results if found new + csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList24 ); + f2GListPurged = TRUE; + } + + if(CSR_IS_OPERATING_BG_BAND(pMac)) + { + // add to the list of 2.4 GHz channel sets + csrLLInsertTail( &pMac->scan.channelPowerInfoList24, &pChannelSet->link, LL_ACCESS_LOCK ); + } + else { + smsLog( pMac, LOGW, FL("Adding 11B/G channels in 11A mode -- First Channel is %d"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + } + } + else + { + // 5GHz info found + if( !f5GListPurged ) + { + // purge previous results if found new + csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList5G ); + f5GListPurged = TRUE; + } + + if(CSR_IS_OPERATING_A_BAND(pMac)) + { + // add to the list of 5GHz channel sets + csrLLInsertTail( &pMac->scan.channelPowerInfoList5G, &pChannelSet->link, LL_ACCESS_LOCK ); + } + else { + smsLog( pMac, LOGW, FL("Adding 11A channels in B/G mode -- First Channel is %d"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + } + } + } + + pChannelInfo++; // move to next entry + } + + return eHAL_STATUS_SUCCESS; +} + +static void csrClearDfsChannelList( tpAniSirGlobal pMac ) +{ + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_CLEAR_DFS_CHANNEL_LIST); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + palSendMBMessage(pMac->hHdd, pMsg); + } +} + +void csrApplyPower2Current( tpAniSirGlobal pMac ) +{ + smsLog( pMac, LOG3, FL(" Updating Cfg with power settings")); + csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList24, WNI_CFG_MAX_TX_POWER_2_4 ); + csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList5G, WNI_CFG_MAX_TX_POWER_5 ); +} + + +void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva) +{ + int i; + tANI_U8 numChannels = 0; + tANI_U8 tempNumChannels = 0; + tCsrChannel ChannelList; + + if (pChannelList->numChannels) + { + tempNumChannels = CSR_MIN(pChannelList->numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN); + + for (i = 0; i < tempNumChannels; i++) + { + ChannelList.channelList[numChannels] = pChannelList->channelList[i]; + numChannels++; + } + + ChannelList.numChannels = numChannels; + csrSetCfgValidChannelList(pMac, ChannelList.channelList, ChannelList.numChannels); + + // extend scan capability + // build a scan list based on the channel list : channel# + active/passive scan + csrSetCfgScanControlList(pMac, countryCode, &ChannelList); + /*Send msg to Lim to clear DFS channel list */ + csrClearDfsChannelList(pMac); +#ifdef FEATURE_WLAN_SCAN_PNO + if (updateRiva) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, FL(" Sending 11d PNO info to Riva")); + // Send HAL UpdateScanParams message + pmcUpdateScanParams(pMac, &(pMac->roam.configParam), &ChannelList, TRUE); + } +#endif // FEATURE_WLAN_SCAN_PNO + } + else + { + smsLog( pMac, LOGE, FL(" 11D channel list is empty")); + } + csrApplyPower2Current( pMac ); // Store the channel+power info in the global place: Cfg + csrSetCfgCountryCode(pMac, countryCode); +} + + +void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva ) +{ + if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset))) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_802_11d_pkt_type *p11dLog; + int Index; + + WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C); + if(p11dLog) + { + p11dLog->eventId = WLAN_80211D_EVENT_RESET; + vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3); + p11dLog->numChannel = pMac->scan.base20MHzChannels.numChannels; + if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL) + { + vos_mem_copy(p11dLog->Channels, + pMac->scan.base20MHzChannels.channelList, + p11dLog->numChannel); + for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++) + { + p11dLog->TxPwr[Index] = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap ); + } + } + if(!pMac->roam.configParam.Is11dSupportEnabled) + { + p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED; + } + else if(pMac->roam.configParam.fEnforceDefaultDomain) + { + p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN; + } + else + { + p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN; + } + WLAN_VOS_DIAG_LOG_REPORT(p11dLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels); + csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels); + + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + // ... and apply the channel list, power settings, and the country code. + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, updateRiva ); + // clear the 11d channel list + vos_mem_set(&pMac->scan.channels11d, sizeof(pMac->scan.channels11d), 0); + pMac->scan.f11dInfoReset = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE; + } + + return; +} + + +eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRestart = eANI_BOOLEAN_FALSE; + + //Use the Country code and domain from EEPROM + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + csrSetRegulatoryDomain(pMac, pMac->scan.domainIdCurrent, &fRestart); + if( ((eANI_BOOLEAN_FALSE == fRestart) || (pfRestartNeeded == NULL) ) + && !csrIsInfraConnected(pMac)) + { + //Only reset the country info if we don't need to restart + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + } + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestart; + } + + return (status); +} + +void csrClearVotesForCountryInfo(tpAniSirGlobal pMac) +{ + pMac->scan.countryCodeCount = 0; + vos_mem_set(pMac->scan.votes11d, + sizeof(tCsrVotes11d) * CSR_MAX_NUM_COUNTRY_CODE, 0); +} + +void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode) +{ + tANI_BOOLEAN match = FALSE; + tANI_U8 i; + + /* convert to UPPER here so we are assured + * the strings are always in upper case. + */ + for( i = 0; i < 3; i++ ) + { + pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] ); + } + + /* Some of the 'old' Cisco 350 series AP's advertise NA as the + * country code (for North America ??). NA is not a valid country code + * or domain so let's allow this by changing it to the proper + * country code (which is US). We've also seen some NETGEAR AP's + * that have "XX " as the country code with valid 2.4 GHz US channel + * information. If we cannot find the country code advertised in the + * 11d information element, let's default to US. + */ + + if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, + pCountryCode, NULL,COUNTRY_QUERY ) ) ) + { + pCountryCode[ 0 ] = '0'; + pCountryCode[ 1 ] = '0'; + } + + /* We've seen some of the AP's improperly put a 0 for the + * third character of the country code. spec says valid charcters are + * 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either). + * if we see a 0 in this third character, let's change it to a ' '. + */ + if ( 0 == pCountryCode[ 2 ] ) + { + pCountryCode[ 2 ] = ' '; + } + + for (i = 0; i < pMac->scan.countryCodeCount; i++) + { + match = (vos_mem_compare(pMac->scan.votes11d[i].countryCode, + pCountryCode, 2)); + if(match) + { + break; + } + } + + if (match) + { + pMac->scan.votes11d[i].votes++; + } + else + { + vos_mem_copy( pMac->scan.votes11d[pMac->scan.countryCodeCount].countryCode, + pCountryCode, 3 ); + pMac->scan.votes11d[pMac->scan.countryCodeCount].votes = 1; + pMac->scan.countryCodeCount++; + } + + return; +} + +tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = FALSE; + tANI_U8 maxVotes = 0; + tANI_U8 i, j=0; + + if (!pMac->scan.countryCodeCount) + { + return fRet; + } + maxVotes = pMac->scan.votes11d[0].votes; + fRet = TRUE; + + for(i = 1; i < pMac->scan.countryCodeCount; i++) + { + /* If we have a tie for max votes for 2 different country codes, + * pick random.we can put some more intelligence - TBD + */ + if (maxVotes < pMac->scan.votes11d[i].votes) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + " Votes for Country %c%c : %d\n", + pMac->scan.votes11d[i].countryCode[0], + pMac->scan.votes11d[i].countryCode[1], + pMac->scan.votes11d[i].votes); + + maxVotes = pMac->scan.votes11d[i].votes; + j = i; + fRet = TRUE; + } + + } + if (fRet) + { + memcpy(pMac->scan.countryCodeElected, + pMac->scan.votes11d[j].countryCode, WNI_CFG_COUNTRY_CODE_LEN); + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Selected Country is %c%c With count %d\n", + pMac->scan.votes11d[j].countryCode[0], + pMac->scan.votes11d[j].countryCode[1], + pMac->scan.votes11d[j].votes); + } + return fRet; +} + +eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + v_REGDOMAIN_t domainId; + + if(pCountry) + { + status = csrGetRegulatoryDomainForCountry(pMac, pCountry, &domainId, COUNTRY_USER); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrSetRegulatoryDomain(pMac, domainId, pfRestartNeeded); + if(HAL_STATUS_SUCCESS(status)) + { + //We don't need to check the pMac->roam.configParam.fEnforceDefaultDomain flag here, + //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria. + vos_mem_copy(pMac->scan.countryCodeCurrent, pCountry, WNI_CFG_COUNTRY_CODE_LEN); + if((pfRestartNeeded == NULL) || !(*pfRestartNeeded)) + { + //Simply set it to cfg. If we need to restart, restart will apply it to the CFG + csrSetCfgCountryCode(pMac, pCountry); + } + } + } + } + + return (status); +} + + + +//caller allocated memory for pNumChn and pChnPowerInfo +//As input, *pNumChn has the size of the array of pChnPowerInfo +//Upon return, *pNumChn has the number of channels assigned. +void csrGetChannelPowerInfo( tpAniSirGlobal pMac, tDblLinkList *pList, + tANI_U32 *pNumChn, tChannelListWithPower *pChnPowerInfo) +{ + tListElem *pEntry; + tANI_U32 chnIdx = 0, idx; + tCsrChannelPowerInfo *pChannelSet; + + //Get 2.4Ghz first + pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + while( pEntry && (chnIdx < *pNumChn) ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if ( 1 != pChannelSet->interChannelOffset ) + { + for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ ) + { + pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset )); + pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower; + } + } + else + { + for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ ) + { + pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + idx); + pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower; + } + } + + pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK ); + } + *pNumChn = chnIdx; + + return ; +} + + + +void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce ) +{ + v_REGDOMAIN_t domainId; + eHalStatus status = eHAL_STATUS_SUCCESS; + + do + { + if( !csrIs11dSupported( pMac ) || 0 == pMac->scan.channelOf11dInfo) break; + if( pMac->scan.fAmbiguous11dInfoFound ) + { + // ambiguous info found + //Restore te default domain as well + if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( + pMac, pMac->scan.countryCodeCurrent, + &domainId, COUNTRY_QUERY))) + { + pMac->scan.domainIdCurrent = domainId; + } + else + { + smsLog(pMac, LOGE, FL(" failed to get domain from currentCountryCode %02X%02X"), + pMac->scan.countryCodeCurrent[0], pMac->scan.countryCodeCurrent[1]); + } + csrResetCountryInformation( pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE ); + break; + } + if ( pMac->scan.f11dInfoApplied && !fForce ) break; + if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( + pMac, pMac->scan.countryCode11d, + &domainId, COUNTRY_QUERY))) + { + //Check whether we need to enforce default domain + if( ( !pMac->roam.configParam.fEnforceDefaultDomain ) || + (pMac->scan.domainIdCurrent == domainId) ) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_802_11d_pkt_type *p11dLog; + tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U32 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp; + + WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C); + if(p11dLog) + { + p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET; + vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCode11d, 3); + p11dLog->numChannel = pMac->scan.channels11d.numChannels; + if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL) + { + vos_mem_copy(p11dLog->Channels, + pMac->scan.channels11d.channelList, + p11dLog->numChannel); + csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList24, + &nChnInfo, chnPwrInfo); + nTmp = nChnInfo; + nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp; + csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList5G, + &nChnInfo, &chnPwrInfo[nTmp]); + for(nTmp = 0; nTmp < p11dLog->numChannel; nTmp++) + { + for(nChnInfo = 0; nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN; nChnInfo++) + { + if(p11dLog->Channels[nTmp] == chnPwrInfo[nChnInfo].chanId) + { + p11dLog->TxPwr[nTmp] = chnPwrInfo[nChnInfo].pwr; + break; + } + } + } + } + if(!pMac->roam.configParam.Is11dSupportEnabled) + { + p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED; + } + else if(pMac->roam.configParam.fEnforceDefaultDomain) + { + p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN; + } + else + { + p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN; + } + WLAN_VOS_DIAG_LOG_REPORT(p11dLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(pMac->scan.domainIdCurrent != domainId) + { + smsLog(pMac, LOGW, FL("Domain Changed Old %d, new %d"), + pMac->scan.domainIdCurrent, domainId); + status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE); + } + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), domainId ); + } + pMac->scan.domainIdCurrent = domainId; + + // switch to active scans using this new channel list + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE; + } + } + + } while( 0 ); + + return; +} + + + +tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode, + tANI_BOOLEAN fForce) +{ + tANI_BOOLEAN fCountryStringChanged = FALSE, fUnknownCountryCode = FALSE; + tANI_U32 i; + v_REGDOMAIN_t regd; + tANI_BOOLEAN fCountryNotPresentInDriver = FALSE; + + // convert to UPPER here so we are assured the strings are always in upper case. + for( i = 0; i < 3; i++ ) + { + pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] ); + } + + // Some of the 'old' Cisco 350 series AP's advertise NA as the country code (for North America ??). + // NA is not a valid country code or domain so let's allow this by changing it to the proper + // country code (which is US). We've also seen some NETGEAR AP's that have "XX " as the country code + // with valid 2.4 GHz US channel information. If we cannot find the country code advertised in the + // 11d information element, let's default to US. + if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, + pCountryCode, + ®d, + COUNTRY_QUERY) ) ) + { + // Check the enforcement first + if( pMac->roam.configParam.fEnforceDefaultDomain || pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + fUnknownCountryCode = TRUE; + } + else + { + fCountryNotPresentInDriver = TRUE; + } + } + //right now, even if we don't find the CC in driver we set to world. Making + //sure countryCode11d doesn't get updated with the invalid CC, instead + //reflect the world CC + else if (REGDOMAIN_WORLD == regd) + { + fCountryNotPresentInDriver = TRUE; + } + + // We've seen some of the AP's improperly put a 0 for the third character of the country code. + // spec says valid charcters are 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either). + // if we see a 0 in this third character, let's change it to a ' '. + if ( 0 == pCountryCode[ 2 ] ) + { + pCountryCode[ 2 ] = ' '; + } + + if( !fUnknownCountryCode ) + { + fCountryStringChanged = (!vos_mem_compare(pMac->scan.countryCode11d, pCountryCode, 2)); + + + if(( 0 == pMac->scan.countryCode11d[ 0 ] && 0 == pMac->scan.countryCode11d[ 1 ] ) + || (fForce)) + { + if (!fCountryNotPresentInDriver) + { + // this is the first .11d information + vos_mem_copy(pMac->scan.countryCode11d, pCountryCode, + sizeof( pMac->scan.countryCode11d )); + + } + else + { + pMac->scan.countryCode11d[0] = '0'; + pMac->scan.countryCode11d[1] = '0'; + } + } + } + + return( fCountryStringChanged ); +} + + +void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand ) +{ + tANI_U32 Index, count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + tANI_S32 maxChannelIndex; + + maxChannelIndex = ( pMac->scan.base20MHzChannels.numChannels < WNI_CFG_VALID_CHANNEL_LIST_LEN ) ? + pMac->scan.base20MHzChannels.numChannels : WNI_CFG_VALID_CHANNEL_LIST_LEN ; + + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL != pChanInfo ) + { + vos_mem_set(pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN, 0); + pChanInfoStart = pChanInfo; + for (Index=0; Index < maxChannelIndex; Index++) + { + if ((fPopulate5GBand && (CSR_IS_CHANNEL_5GHZ(pMac->scan.defaultPowerTable[Index].chanId))) || + (!fPopulate5GBand && (CSR_IS_CHANNEL_24GHZ(pMac->scan.defaultPowerTable[Index].chanId))) ) + { + if(count >= WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + smsLog( pMac, LOGW, FL(" csrSaveChannelPowerForBand, count exceeded, count = %d"), count); + break; + } + pChanInfo->firstChanNum = pMac->scan.defaultPowerTable[Index].chanId; + pChanInfo->numChannels = 1; + pChanInfo->maxTxPower = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } +} + + +void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fPopulate5GBand = FALSE; + + do + { + // if this is not a dual band product, then we don't need to set the opposite + // band info. We only work in one band so no need to look in the other band. + if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) break; + // if we found channel info on the 5.0 band and... + if ( CSR_IS_CHANNEL_5GHZ( pMac->scan.channelOf11dInfo ) ) + { + // and the 2.4 band is empty, then populate the 2.4 channel info + if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList24, LL_ACCESS_LOCK ) ) break; + fPopulate5GBand = FALSE; + } + else + { + // else, we found channel info in the 2.4 GHz band. If the 5.0 band is empty + // set the 5.0 band info from the 2.4 country code. + if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList5G, LL_ACCESS_LOCK ) ) break; + fPopulate5GBand = TRUE; + } + csrSaveChannelPowerForBand( pMac, fPopulate5GBand ); + + } while( 0 ); +} + + +tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + + //Make sure it is a channel that is in our supported list. + for ( i = 0; i < pMac->scan.baseChannels.numChannels; i++ ) + { + if ( channelId == pMac->scan.baseChannels.channelList[i] ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + + //If it is configured to limit a set of the channels + if( fRet && pMac->roam.configParam.fEnforce11dChannels ) + { + fRet = eANI_BOOLEAN_FALSE; + for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ ) + { + if ( channelId == pMac->scan.base20MHzChannels.channelList[i] ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + } + + return (fRet); +} + + + +//bSize specify the buffer size of pChannelList +tANI_U8 csrGetChannelListFromChannelSet( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 bSize, tCsrChannelPowerInfo *pChannelSet ) +{ + tANI_U8 i, j = 0, chnId; + + bSize = CSR_MIN(bSize, pChannelSet->numChannels); + for( i = 0; i < bSize; i++ ) + { + chnId = (tANI_U8)(pChannelSet->firstChannel + ( i * pChannelSet->interChannelOffset )); + if ( csrIsSupportedChannel( pMac, chnId ) ) + { + pChannelList[j++] = chnId; + } + } + + return (j); +} + + + +//bSize -- specify the buffer size of pChannelList +void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList, + tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels ) +{ + tListElem *pEntry; + tCsrChannelPowerInfo *pChannelSet; + tANI_U8 numChannels; + tANI_U8 *pChannels; + + if( pChannelSetList && pChannelList && pNumChannels ) + { + pChannels = pChannelList; + *pNumChannels = 0; + pEntry = csrLLPeekHead( pChannelSetList, LL_ACCESS_LOCK ); + while( pEntry ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + numChannels = csrGetChannelListFromChannelSet( pMac, pChannels, bSize, pChannelSet ); + pChannels += numChannels; + *pNumChannels += numChannels; + pEntry = csrLLNext( pChannelSetList, pEntry, LL_ACCESS_LOCK ); + } + } +} + + +/* + * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d +*/ +tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce) +{ + eHalStatus status; + tANI_U8 *pCountryCodeSelected; + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + v_REGDOMAIN_t domainId; + tDot11fBeaconIEs *pIesLocal = pIes; + tANI_BOOLEAN useVoting = eANI_BOOLEAN_FALSE; + + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + return eHAL_STATUS_SUCCESS; + + if ((NULL == pSirBssDesc) && (NULL == pIes)) + useVoting = eANI_BOOLEAN_TRUE; + + do + { + // check if .11d support is enabled + if( !csrIs11dSupported( pMac ) ) break; + + if (eANI_BOOLEAN_FALSE == useVoting) + { + if( !pIesLocal && + (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pSirBssDesc, &pIesLocal)))) + { + break; + } + // check if country information element is present + if(!pIesLocal->Country.present) + { + //No country info + break; + } + + if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry + (pMac, pIesLocal->Country.country, &domainId, + COUNTRY_QUERY)) && + ( domainId == REGDOMAIN_WORLD)) + { + break; + } + } //useVoting == eANI_BOOLEAN_FALSE + + if (eANI_BOOLEAN_FALSE == useVoting) + pCountryCodeSelected = pIesLocal->Country.country; + else + pCountryCodeSelected = pMac->scan.countryCodeElected; + + status = csrGetRegulatoryDomainForCountry(pMac, + pCountryCodeSelected, &domainId, COUNTRY_IE); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get regId %d"), domainId ); + fRet = eANI_BOOLEAN_FALSE; + break; + } + + /* updating 11d Country Code with Country code selected. */ + vos_mem_copy(pMac->scan.countryCode11d, + pCountryCodeSelected, + WNI_CFG_COUNTRY_CODE_LEN); + +#ifndef CONFIG_ENABLE_LINUX_REG + // Checking for Domain Id change + if ( domainId != pMac->scan.domainIdCurrent ) + { + vos_mem_copy(pMac->scan.countryCode11d, + pCountryCodeSelected, + sizeof( pMac->scan.countryCode11d ) ); + /* Set Current Country code and Current Regulatory domain */ + status = csrSetRegulatoryDomain(pMac, domainId, NULL); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, "Set Reg Domain Fail %d", status); + fRet = eANI_BOOLEAN_FALSE; + break; + } + //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria. + vos_mem_copy(pMac->scan.countryCodeCurrent, + pCountryCodeSelected, WNI_CFG_COUNTRY_CODE_LEN); + //Simply set it to cfg. + csrSetCfgCountryCode(pMac, pCountryCodeSelected); + + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + /* Set Current RegDomain */ + status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to Set regId %d"), domainId ); + fRet = eANI_BOOLEAN_FALSE; + break; + } + /* set to default domain ID */ + pMac->scan.domainIdCurrent = domainId; + /* get the channels based on new cc */ + status = csrInitGetChannels( pMac ); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + fRet = eANI_BOOLEAN_FALSE; + break; + } + } +#endif + fRet = eANI_BOOLEAN_TRUE; + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( fRet ); +} + + +static void csrSaveScanResults(tpAniSirGlobal pMac, tANI_U8 reason, + tANI_U8 sessionId) +{ + // initialize this to FALSE. profMoveInterimScanResultsToMainList() routine + // will set this to the channel where an .11d beacon is seen + pMac->scan.channelOf11dInfo = 0; + // if we get any ambiguous .11d information then this will be set to TRUE + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + //Tush + // if we get any ambiguous .11d information, then this will be set to TRUE + // only if the applied 11d info could be found in one of the scan results + pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_FALSE; + // move the scan results from interim list to the main scan list + csrMoveTempScanResultsToMainList(pMac, reason, sessionId); + + // Now check if we gathered any domain/country specific information + // If so, we should update channel list and apply Tx power settings + if( csrIs11dSupported(pMac) ) + { + csrApplyCountryInformation( pMac, FALSE ); + } +} + + +void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + switch (pCommand->u.scanCmd.reason) + { + case eCsrScanSetBGScanParam: + case eCsrScanAbortBgScan: + if(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList) + { + vos_mem_free(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL; + } + break; + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + break; + case eCsrScanAbortNormalScan: + default: + csrScanFreeRequest(pMac, &pCommand->u.scanCmd.u.scanRequest); + break; + } + if(pCommand->u.scanCmd.pToRoamProfile) + { + csrReleaseProfile(pMac, pCommand->u.scanCmd.pToRoamProfile); + vos_mem_free(pCommand->u.scanCmd.pToRoamProfile); + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); +} + + +tANI_BOOLEAN csrGetRemainingChannelsFor11dScan( tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U8 *pcChannels ) +{ + tANI_U32 index11dChannels, index; + tANI_U32 indexCurrentChannels; + tANI_BOOLEAN fChannelAlreadyScanned; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + *pcChannels = 0; + if ( CSR_IS_11D_INFO_FOUND(pMac) && csrRoamIsChannelValid(pMac, pMac->scan.channelOf11dInfo) ) + { + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + //Find the channel index where we found the 11d info + for(index = 0; index < len; index++) + { + if(pMac->scan.channelOf11dInfo == pMac->roam.validChannelList[index]) + break; + } + //check whether we found the channel index + if(index < len) + { + // Now, look through the 11d channel list and create a list of all channels in the 11d list that are + // NOT in the current channel list. This gives us a list of the new channels that have not been + // scanned. We'll scan this new list so we have a complete set of scan results on all of the domain channels + // initially. + for ( index11dChannels = 0; index11dChannels < pMac->scan.channels11d.numChannels; index11dChannels++ ) + { + fChannelAlreadyScanned = eANI_BOOLEAN_FALSE; + + for( indexCurrentChannels = 0; indexCurrentChannels < index; indexCurrentChannels++ ) + { + if ( pMac->roam.validChannelList[ indexCurrentChannels ] == pMac->scan.channels11d.channelList[ index11dChannels ] ) + { + fChannelAlreadyScanned = eANI_BOOLEAN_TRUE; + break; + } + } + + if ( !fChannelAlreadyScanned ) + { + pChannels[ *pcChannels ] = pMac->scan.channels11d.channelList[ index11dChannels ]; + ( *pcChannels )++; + } + } + } + }//GetCFG + } + return( *pcChannels ); +} + + +eCsrScanCompleteNextCommand csrScanGetNextCommandState( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fSuccess ) +{ + eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing; + + switch( pCommand->u.scanCmd.reason ) + { + case eCsrScan11d1: + NextCommand = (fSuccess) ? eCsrNext11dScan1Success : eCsrNext11dScan1Failure; + break; + case eCsrScan11d2: + NextCommand = (fSuccess) ? eCsrNext11dScan2Success : eCsrNext11dScan2Failure; + break; + case eCsrScan11dDone: + NextCommand = eCsrNext11dScanComplete; + break; + case eCsrScanLostLink1: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan1Success : eCsrNextLostLinkScan1Failed; + break; + case eCsrScanLostLink2: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan2Success : eCsrNextLostLinkScan2Failed; + break; + case eCsrScanLostLink3: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan3Success : eCsrNextLostLinkScan3Failed; + break; + case eCsrScanForSsid: + NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess : eCsrNexteScanForSsidFailure; + break; + case eCsrScanForCapsChange: + NextCommand = eCsrNextCapChangeScanComplete; //don't care success or not + break; + case eCsrScanIdleScan: + NextCommand = eCsrNextIdleScanComplete; + break; + default: + NextCommand = eCsrNextScanNothing; + break; + } + return( NextCommand ); +} + + +//Return whether the pCommand is finished. +tANI_BOOLEAN csrHandleScan11d1Failure(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + + //Apply back the default setting and passively scan one more time. + csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + pCommand->u.scanCmd.reason = eCsrScan11d2; + if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand))) + { + fRet = eANI_BOOLEAN_FALSE; + } + + return (fRet); +} + + +tANI_BOOLEAN csrHandleScan11dSuccess(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + tANI_U8 *pChannels; + tANI_U8 cChannels; + + pChannels = vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL != pChannels ) + { + vos_mem_set(pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN, 0); + if ( csrGetRemainingChannelsFor11dScan( pMac, pChannels, &cChannels ) ) + { + pCommand->u.scanCmd.reason = eCsrScan11dDone; + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + { + vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(cChannels); + if ( NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + { + vos_mem_copy(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pChannels, cChannels); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = cChannels; + pCommand->u.scanCmd.u.scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand))) + { + //Reuse the same command buffer + fRet = eANI_BOOLEAN_FALSE; + } + } + } + vos_mem_free(pChannels); + } + + return (fRet); +} + +//Return whether the command should be removed +tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ) +{ + eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing; + tListElem *pEntry; + tSmeCmd *pCommand; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + tANI_BOOLEAN fSuccess; + + if (pMac->fScanOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + // If the head of the queue is Active and it is a SCAN command, remove + // and put this on the Free queue. + if ( eSmeCommandScan == pCommand->command ) + { + tANI_U32 sessionId = pCommand->sessionId; + + if(eSIR_SME_SUCCESS != pScanRsp->statusCode) + { + fSuccess = eANI_BOOLEAN_FALSE; + } + else + { + //pMac->scan.tempScanResults is not empty meaning the scan found something + //This check only valid here because csrSaveScanresults is not yet called + fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK)); + } + if (pCommand->u.scanCmd.abortScanDueToBandChange) + { + /* + * Scan aborted due to band change + * The scan results need to be flushed + */ + if (pCommand->u.scanCmd.callback + != pMac->scan.callback11dScanDone) + { + smsLog(pMac, LOG1, FL("Filtering the scan results as the " + "results may belong to wrong band")); + csrScanFilterResults(pMac); + } + else + { + smsLog(pMac, LOG1, FL("11d_scan_done will flush the scan" + " results")); + } + pCommand->u.scanCmd.abortScanDueToBandChange + = eANI_BOOLEAN_FALSE; + } + csrSaveScanResults(pMac, pCommand->u.scanCmd.reason, sessionId); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + tScanResultHandle hScanResult; + tCsrScanResultInfo *pScanResult; + tDot11fBeaconIEs *pIes; + int n = 0, c = 0; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason || + eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP; + } + else + { + if( eSIR_PASSIVE_SCAN != pMac->scan.curScanType ) + { + pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP; + } + else + { + pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP; + } + } + if(eSIR_SME_SUCCESS == pScanRsp->statusCode) + { + if(HAL_STATUS_SUCCESS(csrScanGetResult(pMac, NULL, &hScanResult))) + { + while(((pScanResult = csrScanResultGetNext(pMac, hScanResult)) != NULL)) + { + if( n < VOS_LOG_MAX_NUM_BSSID ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->BssDescriptor, &pIes))) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + break; + } + vos_mem_copy(pScanLog->bssid[n], + pScanResult->BssDescriptor.bssId, 6); + if(pIes && pIes->SSID.present && VOS_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid) + { + vos_mem_copy(pScanLog->ssid[n], + pIes->SSID.ssid, pIes->SSID.num_ssid); + } + vos_mem_free(pIes); + n++; + } + c++; + } + pScanLog->numSsid = (v_U8_t)n; + pScanLog->totalSsid = (v_U8_t)c; + csrScanResultPurge(pMac, hScanResult); + } + } + else + { + pScanLog->status = WLAN_SCAN_STATUS_FAILURE; + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + NextCommand = csrScanGetNextCommandState(pMac, pCommand, fSuccess); + //We reuse the command here instead reissue a new command + switch(NextCommand) + { + case eCsrNext11dScan1Success: + case eCsrNext11dScan2Success: + smsLog( pMac, LOG2, FL("11dScan1/3 produced results. Reissue Active scan...")); + // if we found country information, no need to continue scanning further, bail out + fRemoveCommand = eANI_BOOLEAN_TRUE; + NextCommand = eCsrNext11dScanComplete; + break; + case eCsrNext11dScan1Failure: + //We are not done yet. 11d scan fail once. We will try to reset anything and do it over again + //The only meaningful thing for this retry is that we cannot find 11d information after a reset so + //we clear the "old" 11d info and give it once more chance + fRemoveCommand = csrHandleScan11d1Failure(pMac, pCommand); + if(fRemoveCommand) + { + NextCommand = eCsrNext11dScanComplete; + } + break; + case eCsrNextLostLinkScan1Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink1))) + { + csrScanHandleFailedLostlink1(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan2Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink2))) + { + csrScanHandleFailedLostlink2(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan3Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink3))) + { + csrScanHandleFailedLostlink3(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan1Failed: + csrScanHandleFailedLostlink1(pMac, sessionId); + break; + case eCsrNextLostLinkScan2Failed: + csrScanHandleFailedLostlink2(pMac, sessionId); + break; + case eCsrNextLostLinkScan3Failed: + csrScanHandleFailedLostlink3(pMac, sessionId); + break; + case eCsrNexteScanForSsidSuccess: + csrScanHandleSearchForSSID(pMac, pCommand); + break; + case eCsrNexteScanForSsidFailure: + csrScanHandleSearchForSSIDFailure(pMac, pCommand); + break; + case eCsrNextIdleScanComplete: + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + break; + case eCsrNextCapChangeScanComplete: + csrScanHandleCapChangeScanComplete(pMac, sessionId); + break; + default: + + break; + } + } + else + { + smsLog( pMac, LOGW, FL("Scan Completion called but SCAN command is not ACTIVE ...")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + } + } + else + { + smsLog( pMac, LOGW, FL("Scan Completion called but NO commands are ACTIVE ...")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + } + + return( fRemoveCommand ); +} + + + +static void csrScanRemoveDupBssDescriptionFromInterimList( tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescr, + tDot11fBeaconIEs *pIes) +{ + tListElem *pEntry; + tCsrScanResult *pCsrBssDescription; + + // Walk through all the chained BssDescriptions. If we find a chained BssDescription that + // matches the BssID of the BssDescription passed in, then these must be duplicate scan + // results for this Bss. In that case, remove the 'old' Bss description from the linked list. + pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ); + while( pEntry ) + { + pCsrBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType + // matches + + if ( csrIsDuplicateBssDescription( pMac, &pCsrBssDescription->Result.BssDescriptor, + pSirBssDescr, pIes, FALSE ) ) + { + pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) + + ((tANI_S32)pCsrBssDescription->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 ); + + // Remove the 'old' entry from the list.... + if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ) ) + { + csrCheckNSaveWscIe(pMac, pSirBssDescr, &pCsrBssDescription->Result.BssDescriptor); + // we need to free the memory associated with this node + csrFreeScanResultEntry( pMac, pCsrBssDescription ); + } + + // If we found a match, we can stop looking through the list. + break; + } + + pEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ); + } +} + + + +//Caller allocated memory pfNewBssForConn to return whether new candidate for +//current connection is found. Cannot be NULL +tCsrScanResult *csrScanSaveBssDescriptionToInterimList( tpAniSirGlobal pMac, + tSirBssDescription *pBSSDescription, + tDot11fBeaconIEs *pIes) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tANI_U32 cbBSSDesc; + tANI_U32 cbAllocated; + + // figure out how big the BSS description is (the BSSDesc->length does NOT + // include the size of the length field itself). + cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length ); + + cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc; + + pCsrBssDescription = vos_mem_malloc(cbAllocated); + if ( NULL != pCsrBssDescription ) + { + vos_mem_set(pCsrBssDescription, cbAllocated, 0); + pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + smsLog(pMac, LOGW, + FL(" Set Aging Count = %d for BSS "MAC_ADDRESS_STR" "), + pCsrBssDescription->AgingCount, + MAC_ADDR_ARRAY(pBSSDescription->bssId)); + vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc ); + //Save SSID separately for later use + if( pIes->SSID.present && !csrIsNULLSSID(pIes->SSID.ssid, pIes->SSID.num_ssid) ) + { + //SSID not hidden + tANI_U32 len = pIes->SSID.num_ssid; + if (len > SIR_MAC_MAX_SSID_LENGTH) + { + // truncate to fit in our struct + len = SIR_MAC_MAX_SSID_LENGTH; + } + pCsrBssDescription->Result.ssId.length = len; + pCsrBssDescription->Result.timer = vos_timer_get_system_time(); + vos_mem_copy(pCsrBssDescription->Result.ssId.ssId, pIes->SSID.ssid, len); + } + csrLLInsertTail( &pMac->scan.tempScanResults, &pCsrBssDescription->Link, LL_ACCESS_LOCK ); + } + + return( pCsrBssDescription ); +} + + + + +tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2, tANI_BOOLEAN fForced ) +{ + tANI_BOOLEAN fMatch = FALSE; + tSirMacCapabilityInfo *pCap1, *pCap2; + tDot11fBeaconIEs *pIes1 = NULL; + tDot11fBeaconIEs *pIesTemp = pIes2; + + pCap1 = (tSirMacCapabilityInfo *)&pSirBssDesc1->capabilityInfo; + pCap2 = (tSirMacCapabilityInfo *)&pSirBssDesc2->capabilityInfo; + if(pCap1->ess == pCap2->ess) + { + if (pCap1->ess && + csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)&& + (fForced || (vos_chan_to_band(pSirBssDesc1->channelId) == vos_chan_to_band((pSirBssDesc2->channelId))))) + { + fMatch = TRUE; + // Check for SSID match, if exists + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( NULL == pIesTemp ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp))) + { + break; + } + } + if(pIes1->SSID.present && pIesTemp->SSID.present) + { + fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, + pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE); + } + }while(0); + + } + else if (pCap1->ibss && (pSirBssDesc1->channelId == pSirBssDesc2->channelId)) + { + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( NULL == pIesTemp ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp))) + { + break; + } + } + //Same channel cannot have same SSID for different IBSS + if(pIes1->SSID.present && pIesTemp->SSID.present) + { + fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, + pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE); + } + }while(0); + } + /* In case of P2P devices, ess and ibss will be set to zero */ + else if (!pCap1->ess && + csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)) + { + fMatch = TRUE; + } + } + + if(pIes1) + { + vos_mem_free(pIes1); + } + + if( (NULL == pIes2) && pIesTemp ) + { + //locally allocated + vos_mem_free(pIesTemp); + } + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ) +{ + return( pSirBssDesc1->nwType == pSirBssDesc2->nwType ); +} + + +//to check whether the BSS matches the dot11Mode +static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fAllowed = eANI_BOOLEAN_FALSE; + eCsrPhyMode phyMode; + + if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pBssDesc, &phyMode, pIes))) + { + switch(pMac->roam.configParam.phyMode) + { + case eCSR_DOT11_MODE_11b: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode); + break; + case eCSR_DOT11_MODE_11g: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode); + break; + case eCSR_DOT11_MODE_11g_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11g == phyMode); + break; + case eCSR_DOT11_MODE_11a: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11b != phyMode) && (eCSR_DOT11_MODE_11g != phyMode)); + break; + case eCSR_DOT11_MODE_11n_ONLY: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11n == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode)); + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac_ONLY: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11ac == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode)); + break; +#endif + case eCSR_DOT11_MODE_11b_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode); + break; + case eCSR_DOT11_MODE_11a_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode); + break; + case eCSR_DOT11_MODE_11n: +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: +#endif + case eCSR_DOT11_MODE_TAURUS: + default: + fAllowed = eANI_BOOLEAN_TRUE; + break; + } + } + + return (fAllowed); +} + + + +//Return pIes to caller for future use when returning TRUE. +static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, + tANI_U8 numChn, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs **ppIes ) +{ + tANI_BOOLEAN fValidChannel = FALSE; + tDot11fBeaconIEs *pIes = NULL; + tANI_U8 index; + + for( index = 0; index < numChn; index++ ) + { + // This check relies on the fact that a single BSS description is returned in each + // ScanRsp call, which is the way LIM implemented the scan req/rsp funtions. We changed + // to this model when we ran with a large number of APs. If this were to change, then + // this check would have to mess with removing the bssDescription from somewhere in an + // arbitrary index in the bssDescription array. + if ( pChannels[ index ] == pBssDesc->channelId ) + { + fValidChannel = TRUE; + break; + } + } + *ppIes = NULL; + if(fValidChannel) + { + if( HAL_STATUS_SUCCESS( csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes) ) ) + { + fValidChannel = csrScanIsBssAllowed(pMac, pBssDesc, pIes); + if( fValidChannel ) + { + *ppIes = pIes; + } + else + { + vos_mem_free(pIes); + } + } + else + { + fValidChannel = FALSE; + } + } + + return( fValidChannel ); +} + + +//Return whether last scan result is received +static tANI_BOOLEAN csrScanProcessScanResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tSirSmeScanRsp *pScanRsp, tANI_BOOLEAN *pfRemoveCommand ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE, fRemoveCommand = eANI_BOOLEAN_FALSE; + tDot11fBeaconIEs *pIes = NULL; + tANI_U32 cbParsed; + tSirBssDescription *pSirBssDescription; + tANI_U32 cbBssDesc; + tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ) + + sizeof(tSirBssDescription); //We need at least one CB + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pScanRsp->sessionId]; + + // don't consider the scan rsp to be valid if the status code is Scan Failure. Scan Failure + // is returned when the scan could not find anything. so if we get scan failure return that + // the scan response is invalid. Also check the lenght in the scan result for valid scan + // BssDescriptions.... + do + { + if ( ( cbScanResult <= pScanRsp->length ) && + (( eSIR_SME_SUCCESS == pScanRsp->statusCode ) || + ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW == pScanRsp->statusCode ) ) ) + { + tANI_U8 *pChannelList = NULL; + tANI_U8 cChannels = 0; + + //Different scan type can reach this point, we need to distinguish it +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if( eCsrScanGetLfrResult == pCommand->u.scanCmd.reason ) + { + pChannelList = NULL; + cChannels = 0; + } + else +#endif + if( eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason ) + { + //eCsrScanSetBGScanParam uses different structure + tCsrBGScanRequest *pBgScanReq = &pCommand->u.scanCmd.u.bgScanRequest; + + cChannels = pBgScanReq->ChannelInfo.numOfChannels; + pChannelList = pBgScanReq->ChannelInfo.ChannelList; + } + else + { + //the rest use generic scan request + cChannels = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + pChannelList = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList; + } + + // if the scan result is not on one of the channels in the Valid channel list, then it + // must have come from an AP on an overlapping channel (in the 2.4GHz band). In this case, + // let's drop the scan result. + // + // The other situation is where the scan request is for a scan on a particular channel set + // and the scan result is from a + + // if the NumChannels is 0, then we are supposed to be scanning all channels. Use the full channel + // list as the 'valid' channel list. Otherwise, use the specific channel list in the scan parms + // as the valid channels. + if ( 0 == cChannels ) + { + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + pChannelList = pMac->roam.validChannelList; + cChannels = (tANI_U8)len; + } + else + { + //Cannot continue + smsLog( pMac, LOGE, "CSR: Processing internal SCAN results...csrGetCfgValidChannels failed" ); + break; + } + } + + smsLog( pMac, LOG2, "CSR: Processing internal SCAN results..." ); + cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ); + pSirBssDescription = pScanRsp->bssDescription; + while( cbParsed < pScanRsp->length ) + { + if ( csrScanValidateScanResult( pMac, pChannelList, cChannels, pSirBssDescription, &pIes ) ) + { + csrScanRemoveDupBssDescriptionFromInterimList(pMac, pSirBssDescription, pIes); + csrScanSaveBssDescriptionToInterimList( pMac, pSirBssDescription, pIes ); + if( eSIR_PASSIVE_SCAN == pMac->scan.curScanType ) + { + if( csrIs11dSupported( pMac) ) + { + //Check whether the BSS is acceptable base on 11d info and our configs. + if( csrMatchCountryCode( pMac, NULL, pIes ) ) + { + //Double check whether the channel is acceptable by us. + if( csrIsSupportedChannel( pMac, pSirBssDescription->channelId ) ) + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + } + } + else + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + } + //Free the resource + vos_mem_free(pIes); + } + // skip over the BSS description to the next one... + cbBssDesc = pSirBssDescription->length + sizeof( pSirBssDescription->length ); + + cbParsed += cbBssDesc; + pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + cbBssDesc ); + + } //while + } + else + { + smsLog( pMac, LOGW, " Scanrsp fail (0x%08X), length = %d (expected %d)", + pScanRsp->statusCode, pScanRsp->length, cbScanResult); + //HO bg scan/probe failed no need to try autonomously + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason || +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + eCsrScanGetLfrResult == pCommand->u.scanCmd.reason || +#endif + eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason) + { + fRemoveCommand = eANI_BOOLEAN_TRUE; + } + } + }while(0); + if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode ) + { + smsLog(pMac, LOGE, "Found %d BSS, statusCode %d", + csrLLCount(&pMac->scan.tempScanResults), + pScanRsp->statusCode); + smsLog(pMac, LOG1, "scan reason is %d", pCommand->u.scanCmd.reason); + fRemoveCommand = csrScanComplete( pMac, pScanRsp ); + fRet = eANI_BOOLEAN_TRUE; + }//if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode ) + if(pfRemoveCommand) + { + *pfRemoveCommand = fRemoveCommand; + } + +#ifdef WLAN_AP_STA_CONCURRENCY + if (pMac->fScanOffload) + return fRet; + + if (!csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK )) + { + /* Pending scan commands in the list because the previous scan command + * was split into a scan command on one channel + a scan command for all + * remaining channels. + * + * Start timer to trigger processing of the next scan command. + * NOTE for LFR: + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + if ((csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pCommand->u.scanCmd.reason != eCsrScanBgScan) && + (pNeighborRoamInfo->neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pCommand->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac))) + { + /* if active connected sessions present then continue to split scan + * with specified interval between consecutive scans */ + csrSetDefaultScanTiming(pMac, pCommand->u.scanCmd.u.scanRequest.scanType, &(pCommand->u.scanCmd.u.scanRequest)); + vos_timer_start(&pMac->scan.hTimerStaApConcTimer, + pCommand->u.scanCmd.u.scanRequest.restTime); + } else { + /* if no connected sessions present then initiate next scan command immediately */ + /* minimum timer granularity is 10ms */ + vos_timer_start(&pMac->scan.hTimerStaApConcTimer, 10); + } + } +#endif + return (fRet); +} + + +tANI_BOOLEAN csrScanIsWildCardScan( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0}; + tANI_BOOLEAN f = vos_mem_compare(pCommand->u.scanCmd.u.scanRequest.bssid, + bssid, sizeof(tCsrBssid)); + + //It is not a wild card scan if the bssid is not broadcast and the number of SSID is 1. + return ((tANI_BOOLEAN)( (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid[0])) && + (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1) )); +} + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus csrSavePnoScanResults(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp, + tANI_U8 sessionId) +{ + tSirBssDescription *pSirBssDescription; + tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ) + + sizeof(tSirBssDescription); //We need at least one CB + tCsrScanResult *pScanResult = NULL; + tAniSSID tmpSsid; + v_TIME_t timer; + tANI_U32 cbParsed; + tANI_U32 cbBssDesc; + tANI_U16 ieLen; + + if ((cbScanResult > pScanRsp->length ) || + (( eSIR_SME_SUCCESS != pScanRsp->statusCode ) && + ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode ) ) ) + return eHAL_STATUS_FAILURE; + + cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ); + pSirBssDescription = pScanRsp->bssDescription; + + while( cbParsed < pScanRsp->length ) + { + // Check whether we have reach out limit + if ( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) ) + { + smsLog( pMac, LOGW, FL( "BSS limit reached")); + return eHAL_STATUS_RESOURCES; + } + + ieLen = (pSirBssDescription->length + sizeof( pSirBssDescription->length ) + - GET_FIELD_OFFSET( tSirBssDescription, ieFields )); + + pScanResult = vos_mem_malloc(sizeof(tCsrScanResult) + ieLen); + if (NULL == pScanResult) + { + smsLog(pMac, LOGE, FL(" Fail to allocate memory for frame")); + return eHAL_STATUS_RESOURCES; + } + + vos_mem_set(pScanResult, sizeof(tCsrScanResult) + ieLen, 0); + + if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pSirBssDescription, (tDot11fBeaconIEs **)&pScanResult->Result.pvIes))) + { + smsLog(pMac, LOGE, FL(" Cannot parse IEs")); + csrFreeScanResultEntry(pMac, pScanResult); + return eHAL_STATUS_RESOURCES; + } + + cbBssDesc = pSirBssDescription->length + + sizeof( pSirBssDescription->length ); + + vos_mem_copy(&pScanResult->Result.BssDescriptor, pSirBssDescription, + cbBssDesc); + + // Remove duplicate entry + csrRemoveDupBssDescription( pMac, &pScanResult->Result.BssDescriptor, + (tDot11fBeaconIEs *)pScanResult->Result.pvIes, + &tmpSsid , &timer, FALSE ); + //Add to scan cache + csrScanAddResult(pMac, pScanResult, + (tDot11fBeaconIEs *)pScanResult->Result.pvIes, + sessionId); + + // skip over the BSS description to the next one... + cbParsed += cbBssDesc; + pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + + cbBssDesc ); + } + + return eHAL_STATUS_SUCCESS; +} +#endif + +eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tSmeCmd *pCommand; + eCsrScanStatus scanStatus; + tSirSmeScanRsp *pScanRsp = (tSirSmeScanRsp *)pMsgBuf; + tSmeGetScanChnRsp *pScanChnInfo; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + eCsrScanReason reason = eCsrScanOther; + + if (pMac->fScanOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandScan == pCommand->command ) + { + scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + reason = pCommand->u.scanCmd.reason; + switch(pCommand->u.scanCmd.reason) + { + case eCsrScanAbortBgScan: + case eCsrScanAbortNormalScan: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + break; + case eCsrScanGetScanChnInfo: + pScanChnInfo = (tSmeGetScanChnRsp *)pMsgBuf; + /* + * status code not available in tSmeGetScanChnRsp, so + * by default considereing it to be success + */ + scanStatus = eSIR_SME_SUCCESS; + csrScanAgeResults(pMac, pScanChnInfo); + break; + case eCsrScanForCapsChange: + csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand ); + break; + case eCsrScanP2PFindPeer: + scanStatus = ((eSIR_SME_SUCCESS == pScanRsp->statusCode) && (pScanRsp->length > 50)) ? eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE; + csrScanProcessScanResults( pMac, pCommand, pScanRsp, NULL ); + break; + case eCsrScanSetBGScanParam: + default: + if(csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand )) + { + //Not to get channel info if the scan is not a wildcard scan because + //it may cause scan results got aged out incorrectly. + if( csrScanIsWildCardScan( pMac, pCommand ) && (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (pCommand->u.scanCmd.reason != eCsrScanGetLfrResult) +#endif + ) + { + //Get the list of channels scanned + if( pCommand->u.scanCmd.reason != eCsrScanUserRequest) + { + csrScanGetScanChnInfo(pMac, pCommand->sessionId, + NULL, NULL, + pCommand->u.scanCmd.scanID); + } + else + { + csrScanGetScanChnInfo(pMac, + pCommand->sessionId, + pCommand->u.scanCmd.pContext, + pCommand->u.scanCmd.callback, + pCommand->u.scanCmd.scanID); + pCommand->u.scanCmd.callback = NULL; + } + } + } + break; + }//switch + if(fRemoveCommand) + { + + csrReleaseScanCommand(pMac, pCommand, scanStatus); + + } + smeProcessPendingQueue( pMac ); + } +#ifdef FEATURE_WLAN_SCAN_PNO + else if (pMac->pnoOffload && + !HAL_STATUS_SUCCESS(csrSavePnoScanResults(pMac, pScanRsp, + pScanRsp->sessionId))) + { + smsLog( pMac, LOGE, "CSR: Unable to store scan results for PNO" ); + status = eHAL_STATUS_FAILURE; + } +#endif + else + { + smsLog( pMac, LOGE, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." ); + status = eHAL_STATUS_FAILURE; + } + } +#ifdef FEATURE_WLAN_SCAN_PNO + else if (pMac->pnoOffload && + !HAL_STATUS_SUCCESS(csrSavePnoScanResults(pMac, pScanRsp, + pScanRsp->sessionId))) + { + smsLog( pMac, LOGE, "CSR: Unable to store scan results for PNO" ); + status = eHAL_STATUS_FAILURE; + } +#endif + else if (pMac->pnoOffload == FALSE) + { + smsLog( pMac, LOGE, "CSR: Scan Completion called but NO commands are ACTIVE ..." ); + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + + + +tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal pMac, tScanResultHandle hScanResult) +{ + tListElem *pEntry; + tCsrScanResult *pResult; + tCsrScanResultInfo *pRet = NULL; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + + if(pResultList) + { + csrLLLock(&pResultList->List); + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + pRet = &pResult->Result; + } + pResultList->pCurEntry = pEntry; + csrLLUnlock(&pResultList->List); + } + + return pRet; +} + + +tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal pMac, tScanResultHandle hScanResult) +{ + tListElem *pEntry = NULL; + tCsrScanResult *pResult = NULL; + tCsrScanResultInfo *pRet = NULL; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + + if(pResultList) + { + csrLLLock(&pResultList->List); + if(NULL == pResultList->pCurEntry) + { + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + } + else + { + pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK); + } + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + pRet = &pResult->Result; + } + pResultList->pCurEntry = pEntry; + csrLLUnlock(&pResultList->List); + } + + return pRet; +} + + +//This function moves the first BSS that matches the bssid to the head of the result +eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + tCsrScanResult *pResult = NULL; + tListElem *pEntry = NULL; + + if(pResultList && bssid) + { + csrLLLock(&pResultList->List); + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + while(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + if (vos_mem_compare(bssid, pResult->Result.BssDescriptor.bssId, sizeof(tCsrBssid))) + { + status = eHAL_STATUS_SUCCESS; + csrLLRemoveEntry(&pResultList->List, pEntry, LL_ACCESS_NOLOCK); + csrLLInsertHead(&pResultList->List, pEntry, LL_ACCESS_NOLOCK); + break; + } + pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pResultList->List); + } + + return (status); +} + + +//Remove the BSS if possible. +//Return -- TRUE == the BSS is remove. False == Fail to remove it +//This function is called when list lock is held. Be caution what functions it can call. +tANI_BOOLEAN csrScanAgeOutBss(tpAniSirGlobal pMac, tCsrScanResult *pResult) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + tCsrRoamSession *pSession; + tANI_BOOLEAN isConnBssfound = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + //Not to remove the BSS we are connected to. + if(csrIsConnStateConnectedInfra(pMac, i) && (NULL != pSession->pConnectBssDesc) && + (csrIsDuplicateBssDescription(pMac, &pResult->Result.BssDescriptor, + pSession->pConnectBssDesc, NULL, FALSE)) + ) + { + isConnBssfound = eANI_BOOLEAN_TRUE; + break; + } + } + } + + if( isConnBssfound ) + { + //Reset the counter so that aging out of connected BSS won't hapeen too soon + pResult->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + smsLog(pMac, LOGW, + FL(" Connected BSS, Set Aging Count=%d for BSS "MAC_ADDRESS_STR" "), + pResult->AgingCount, + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId)); + pResult->Result.BssDescriptor.nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + return (fRet); + } + else + { + smsLog(pMac, LOGW, "Aging out BSS "MAC_ADDRESS_STR" Channel %d", + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId), + pResult->Result.BssDescriptor.channelId); + //No need to hold the spin lock because caller should hold the lock for pMac->scan.scanResultList + if( csrLLRemoveEntry(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_NOLOCK) ) + { + if (csrIsMacAddressEqual(pMac, + (tCsrBssid *) pResult->Result.BssDescriptor.bssId, + (tCsrBssid *) pMac->scan.currentCountryBssid)) + { + smsLog(pMac, LOGW, "Aging out 11d BSS "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId)); + pMac->scan.currentCountryRSSI = -128; + } + csrFreeScanResultEntry(pMac, pResult); + fRet = eANI_BOOLEAN_TRUE; + } + } + + return (fRet); +} + + +eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + tLimScanChn *pChnInfo; + tANI_U8 i; + + csrLLLock(&pMac->scan.scanResultList); + for(i = 0; i < pScanChnInfo->numChn; i++) + { + pChnInfo = &pScanChnInfo->scanChn[i]; + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if(pResult->Result.BssDescriptor.channelId == pChnInfo->channelId) + { + if(pResult->AgingCount <= 0) + { + smsLog(pMac, LOGW, " age out due to ref count"); + csrScanAgeOutBss(pMac, pResult); + } + else + { + pResult->AgingCount--; + smsLog(pMac, LOGW, + FL("Decremented AgingCount=%d for BSS "MAC_ADDRESS_STR""), + pResult->AgingCount, + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId)); + } + } + pEntry = tmpEntry; + } + } + csrLLUnlock(&pMac->scan.scanResultList); + + return (status); +} + + +eHalStatus csrSendMBScanReq( tpAniSirGlobal pMac, tANI_U16 sessionId, + tCsrScanRequest *pScanReq, tScanReqParam *pScanReqParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanReq *pMsg; + tANI_U16 msgLen; + tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0}; + tSirScanType scanType = pScanReq->scanType; + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 i; + tANI_U8 selfMacAddr[VOS_MAC_ADDR_SIZE]; + tANI_U8 *pSelfMac = NULL; + + msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + + ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) + + ( pScanReq->uIEFieldLen ) ; + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + do + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + //ToDO: Fill in session info when we need to do scan base on session. + if ((pMac->fScanOffload) && (sessionId != CSR_SESSION_ID_INVALID)) + { + pMsg->sessionId = sessionId; + } + else + { + /* if sessionId == CSR_SESSION_ID_INVALID, then send the scan + request on first available session */ + pMsg->sessionId = 0; + } + if (pMsg->sessionId >= CSR_ROAM_SESSION_MAX) + smsLog( pMac, LOGE, FL(" Invalid Sme Session ID = %d"), pMsg->sessionId ); + pMsg->transactionId = 0; + pMsg->dot11mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + pMsg->bssType = pal_cpu_to_be32(csrTranslateBsstypeToMacType(pScanReq->BSSType)); + + if ( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[sessionId].selfMacAddr; + } + else + { + // Since we don't have session for the scanning, we find a valid session. In case we fail to + // do so, get the WNI_CFG_STA_ID + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[i].selfMacAddr; + break; + } + } + if( CSR_ROAM_SESSION_MAX == i ) + { + tANI_U32 len = VOS_MAC_ADDR_SIZE; + pSelfMac = selfMacAddr; + status = ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pSelfMac, &len ); + if( !HAL_STATUS_SUCCESS( status ) || + ( len < VOS_MAC_ADDR_SIZE ) ) + { + smsLog( pMac, LOGE, FL(" Can not get self MAC address from CFG status = %d"), status ); + //Force failed status + status = eHAL_STATUS_FAILURE; + break; + } + } + } + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, pSelfMac, sizeof(tSirMacAddr)); + + //sirCopyMacAddr + vos_mem_copy((tANI_U8 *)pMsg->bssId, (tANI_U8 *)&pScanReq->bssid, sizeof(tSirMacAddr)); + if ( vos_mem_compare(pScanReq->bssid, bssid, sizeof(tCsrBssid))) + { + vos_mem_set(pMsg->bssId, sizeof(tSirMacAddr), 0xff); + } + else + { + vos_mem_copy(pMsg->bssId, pScanReq->bssid, VOS_MAC_ADDR_SIZE); + } + minChnTime = pScanReq->minChnTime; + maxChnTime = pScanReq->maxChnTime; + + //Verify the scan type first, if the scan is active scan, we need to make sure we + //are allowed to do so. + /* if 11d is enabled & we don't see any beacon around, scan type falls + back to passive. But in BT AMP STA mode we need to send out a + directed probe*/ + if( (eSIR_PASSIVE_SCAN != scanType) && (eCSR_SCAN_P2P_DISCOVERY != pScanReq->requestType) + && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType) + && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d)) + { + scanType = pMac->scan.curScanType; + if(eSIR_PASSIVE_SCAN == pMac->scan.curScanType) + { + if(minChnTime < pMac->roam.configParam.nPassiveMinChnTime) + { + minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + if(maxChnTime < pMac->roam.configParam.nPassiveMaxChnTime) + { + maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + } + } + } + pMsg->scanType = pal_cpu_to_be32(scanType); + + pMsg->numSsid = + (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ? + pScanReq->SSIDs.numOfSSIDs : SIR_SCAN_MAX_NUM_SSID; + if((pScanReq->SSIDs.numOfSSIDs != 0) && ( eSIR_PASSIVE_SCAN != scanType )) + { + for (i = 0; i < pMsg->numSsid; i++) + { + vos_mem_copy(&pMsg->ssId[i], + &pScanReq->SSIDs.SSIDList[i].SSID, sizeof(tSirMacSSid)); + } + } + else + { + //Otherwise we scan all SSID and let the result filter later + for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++) + { + pMsg->ssId[i].length = 0; + } + } + + pMsg->minChannelTime = pal_cpu_to_be32(minChnTime); + pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime); + pMsg->minChannelTimeBtc = pMac->roam.configParam.nActiveMinChnTimeBtc; + pMsg->maxChannelTimeBtc = pMac->roam.configParam.nActiveMaxChnTimeBtc; + //hidden SSID option + pMsg->hiddenSsid = pScanReqParam->hiddenSsid; + //rest time + pMsg->restTime = pScanReq->restTime; + pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch; + // All the scan results caching will be done by Roaming + // We do not want LIM to do any caching of scan results, + // so delete the LIM cache on all scan requests + pMsg->returnFreshResults = pScanReqParam->freshScan; + //Always ask for unique result + pMsg->returnUniqueResults = pScanReqParam->fUniqueResult; + pMsg->channelList.numChannels = (tANI_U8)pScanReq->ChannelInfo.numOfChannels; + if(pScanReq->ChannelInfo.numOfChannels) + { + //Assuming the channelNumber is tANI_U8 (1 byte) + vos_mem_copy(pMsg->channelList.channelNumber, + pScanReq->ChannelInfo.ChannelList, + pScanReq->ChannelInfo.numOfChannels); + } + + pMsg->uIEFieldLen = (tANI_U16) pScanReq->uIEFieldLen; + pMsg->uIEFieldOffset = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + + ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) ; + if(pScanReq->uIEFieldLen != 0) + { + vos_mem_copy((tANI_U8 *)pMsg+pMsg->uIEFieldOffset, pScanReq->pIEField, + pScanReq->uIEFieldLen); + } + pMsg->p2pSearch = pScanReq->p2pSearch; + + if (pScanReq->requestType == eCSR_SCAN_HO_BG_SCAN) + { + pMsg->backgroundScanMode = eSIR_ROAMING_SCAN; + } + + }while(0); + smsLog(pMac, LOG1, FL("domainIdCurrent %d scanType %d bssType %d requestType %d numChannels %d "), + pMac->scan.domainIdCurrent, pMsg->scanType, pMsg->bssType, + pScanReq->requestType, pMsg->channelList.numChannels); + + for(i = 0; i < pMsg->channelList.numChannels; i++) + { + smsLog(pMac, LOG1, FL("channelNumber[%d]= %d"), i, pMsg->channelList.channelNumber[i]); + } + + if(HAL_STATUS_SUCCESS(status)) + { + status = palSendMBMessage(pMac->hHdd, pMsg); + } + else + { + smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d"), status ); + vos_mem_free(pMsg); + } + }//Success allocated memory + else + { + smsLog( pMac, LOGE, FL(" memory allocation failure")); + } + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOG1, FL("Failed: SId: %d FirstMatch = %d" + " UniqueResult = %d freshScan = %d hiddenSsid = %d"), + sessionId, pScanReqParam->bReturnAfter1stMatch, + pScanReqParam->fUniqueResult, pScanReqParam->freshScan, + pScanReqParam->hiddenSsid ); + smsLog( pMac, LOG1, FL("scanType = %u BSSType = %u numOfSSIDs = %d" + " numOfChannels = %d requestType = %d p2pSearch = %d\n"), + pScanReq->scanType, pScanReq->BSSType, + pScanReq->SSIDs.numOfSSIDs, + pScanReq->ChannelInfo.numOfChannels, pScanReq->requestType, + pScanReq->p2pSearch ); + } + + return( status ); +} + +eHalStatus csrSendMBScanResultReq( tpAniSirGlobal pMac, tANI_U32 sessionId, tScanReqParam *pScanReqParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanReq *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirSmeScanReq )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + pMsg->transactionId = 0; + pMsg->returnFreshResults = pScanReqParam->freshScan; + //Always ask for unique result + pMsg->returnUniqueResults = pScanReqParam->fUniqueResult; + pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch; + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d\n"), status ); + } + + } + + return( status ); +} + + + +eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanReqParam scanReq; + + do + { + /* + * Don't delete cached results. Rome rssi based scan candidates + * may land up in scan cache instead of LFR cache. + * They will be deleted upon query. + */ + scanReq.freshScan = SIR_BG_SCAN_RETURN_FRESH_RESULTS; + scanReq.fUniqueResult = TRUE; + scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID; + if(eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_FIRST_MATCH; + } + else + { + // Basically do scan on all channels even for 11D 1st scan case. + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + if((eCsrScanBgScan == pCommand->u.scanCmd.reason)|| + (eCsrScanProbeBss == pCommand->u.scanCmd.reason)) + { + scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ; + } + else + { + if( (eSIR_PASSIVE_SCAN != pCommand->u.scanCmd.u.scanRequest.scanType) && + (eSIR_PASSIVE_SCAN != pMac->scan.curScanType) ) + { + pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ; + } + else + { + pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ; + } + } + pScanLog->minChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.minChnTime; + pScanLog->maxChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.maxChnTime; + pScanLog->numChannel = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL)) + { + vos_mem_copy(pScanLog->channels, + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pScanLog->numChannel); + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + csrClearVotesForCountryInfo(pMac); + status = csrSendMBScanReq(pMac, pCommand->sessionId, + &pCommand->u.scanCmd.u.scanRequest, &scanReq); + }while(0); + + return( status ); +} + + +eHalStatus csrScanRetrieveResult(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanReqParam scanReq; + + do + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eCsrScanGetLfrResult == pCommand->u.scanCmd.reason) + { + //to get the LFR candidates from PE cache + scanReq.freshScan = SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS|SIR_BG_SCAN_PURGE_LFR_RESULTS; + scanReq.fUniqueResult = TRUE; + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + else +#endif + { + //not a fresh scan + scanReq.freshScan = SIR_BG_SCAN_PURGE_RESUTLS; + scanReq.fUniqueResult = TRUE; + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + status = csrSendMBScanResultReq(pMac, pCommand->sessionId, &scanReq); + }while(0); + + return (status); +} + + + +eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrChannelInfo newChannelInfo = {0, NULL}; + int i, j; + tANI_U8 *pChannel = NULL; + tANI_U32 len = 0; + + // Transition to Scanning state... + if (!pMac->fScanOffload) + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + pCommand->u.scanCmd.lastRoamState[i] = + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_SCANNING, i); + smsLog( pMac, LOG3, "starting SCAN command from %d state...." + " reason is %d", pCommand->u.scanCmd.lastRoamState[i], + pCommand->u.scanCmd.reason ); + } + } + else + { + pCommand->u.scanCmd.lastRoamState[pCommand->sessionId] = + csrRoamStateChange(pMac, eCSR_ROAMING_STATE_SCANNING, + pCommand->sessionId); + smsLog( pMac, LOG3, + "starting SCAN command from %d state.... reason is %d", + pCommand->u.scanCmd.lastRoamState[pCommand->sessionId], + pCommand->u.scanCmd.reason ); + } + + switch(pCommand->u.scanCmd.reason) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanForCapsChange: //For cap change, LIM already save BSS description + status = csrScanRetrieveResult(pMac, pCommand); + break; + case eCsrScanSetBGScanParam: + status = csrProcessSetBGScanParam(pMac, pCommand); + break; + case eCsrScanBGScanAbort: + status = csrSetCfgBackgroundScanPeriod(pMac, 0); + break; + case eCsrScanBGScanEnable: + status = csrSetCfgBackgroundScanPeriod(pMac, pMac->roam.configParam.bgScanInterval); + break; + case eCsrScanGetScanChnInfo: + status = csrScanGetScanChannelInfo(pMac, pCommand->sessionId); + break; + case eCsrScanUserRequest: + if(pMac->roam.configParam.fScanTwice) + { + //We scan 2.4 channel twice + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels && + (NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)) + { + len = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + //allocate twice the channel + newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(newChannelInfo.numOfChannels * 2); + pChannel = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList; + } + else + { + //get the valid channel list to scan all. + len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + //allocate twice the channel + newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2); + pChannel = pMac->roam.validChannelList; + } + } + if(NULL == newChannelInfo.ChannelList) + { + newChannelInfo.numOfChannels = 0; + } + else + { + j = 0; + for(i = 0; i < len; i++) + { + newChannelInfo.ChannelList[j++] = pChannel[i]; + if(CSR_MAX_24GHz_CHANNEL_NUMBER >= pChannel[i]) + { + newChannelInfo.ChannelList[j++] = pChannel[i]; + } + } + if(NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + { + //pChannel points to the channellist from the command, free it. + vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = newChannelInfo.ChannelList; + } + } //if(pMac->roam.configParam.fScanTwice) + + status = csrScanChannels(pMac, pCommand); + + break; + default: + status = csrScanChannels(pMac, pCommand); + break; + } + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseScanCommand(pMac, pCommand, eCSR_SCAN_FAILURE); + } + + return (status); +} + + +eHalStatus csrScanSetBGScanparams(tpAniSirGlobal pMac, tCsrBGScanRequest *pScanReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + if(pScanReq) + { + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanSetBGScanParam; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + vos_mem_copy(&pCommand->u.scanCmd.u.bgScanRequest, pScanReq, sizeof(tCsrBGScanRequest)); + //we have to do the follow + if(pScanReq->ChannelInfo.numOfChannels == 0) + { + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL; + } + else + { + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList + = vos_mem_malloc(pScanReq->ChannelInfo.numOfChannels); + if ( NULL != pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList ) + { + vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList, + pScanReq->ChannelInfo.ChannelList, + pScanReq->ChannelInfo.numOfChannels); + } + else + { + smsLog(pMac, LOGE, FL("ran out of memory")); + csrReleaseCommandScan(pMac, pCommand); + return eHAL_STATUS_FAILURE; + } + } + + //scan req for SSID + if(pScanReq->SSID.length) + { + vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.SSID.ssId, + pScanReq->SSID.ssId, pScanReq->SSID.length); + pCommand->u.scanCmd.u.bgScanRequest.SSID.length = pScanReq->SSID.length; + + } + pCommand->u.scanCmd.u.bgScanRequest.maxChnTime= pScanReq->maxChnTime; + pCommand->u.scanCmd.u.bgScanRequest.minChnTime = pScanReq->minChnTime; + pCommand->u.scanCmd.u.bgScanRequest.scanInterval = pScanReq->scanInterval; + + + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + } + + return (status); +} + +eHalStatus csrScanBGScanAbort( tpAniSirGlobal pMac ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanBGScanAbort; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + + return (status); +} + + +//This will enable the background scan with the non-zero interval +eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + if(pMac->roam.configParam.bgScanInterval) + { + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanBGScanEnable; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + //BG scan results are reported automatically by PE to SME once the scan is done. + //No need to fetch the results explicitly. + //csrScanStartGetResultTimer(pMac); + csrScanStartResultAgingTimer(pMac); + } + else + { + //We don't have BG scan so stop the aging timer + csrScanStopResultAgingTimer(pMac); + smsLog(pMac, LOGE, FL("cannot continue because the bgscan interval is 0")); + status = eHAL_STATUS_INVALID_PARAMETER; + } + + return (status); +} + + +eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + tANI_U32 index = 0; + tANI_U32 new_index = 0; + eNVChannelEnabledType NVchannel_state; + uint8_t skip_dfs_chnl = pMac->roam.configParam.initial_scan_no_dfs_chnl; + + do + { + status = csrScanFreeRequest(pMac, pDstReq); + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pDstReq, pSrcReq, sizeof(tCsrScanRequest)); + /* Re-initialize the pointers to NULL since we did a copy */ + pDstReq->pIEField = NULL; + pDstReq->ChannelInfo.ChannelList = NULL; + pDstReq->SSIDs.SSIDList = NULL; + + if(pSrcReq->uIEFieldLen == 0) + { + pDstReq->pIEField = NULL; + } + else + { + pDstReq->pIEField = vos_mem_malloc(pSrcReq->uIEFieldLen); + if ( NULL == pDstReq->pIEField ) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, FL("No memory for scanning IE fields")); + break; + } + else + { + status = eHAL_STATUS_SUCCESS; + vos_mem_copy(pDstReq->pIEField, pSrcReq->pIEField, + pSrcReq->uIEFieldLen); + pDstReq->uIEFieldLen = pSrcReq->uIEFieldLen; + } + }//Allocate memory for IE field + { + if(pSrcReq->ChannelInfo.numOfChannels == 0) + { + pDstReq->ChannelInfo.ChannelList = NULL; + pDstReq->ChannelInfo.numOfChannels = 0; + } + else + { + pDstReq->ChannelInfo.ChannelList = vos_mem_malloc( + pSrcReq->ChannelInfo.numOfChannels + * sizeof(*pDstReq->ChannelInfo.ChannelList)); + if ( NULL == pDstReq->ChannelInfo.ChannelList ) + { status = eHAL_STATUS_FAILURE; + pDstReq->ChannelInfo.numOfChannels = 0; + smsLog(pMac, LOGE, FL("No memory for scanning Channel" + " List")); + break; + } + + if((pSrcReq->scanType == eSIR_PASSIVE_SCAN) && (pSrcReq->requestType == eCSR_SCAN_REQUEST_11D_SCAN)) + { + for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ ) + { + NVchannel_state = vos_nv_getChannelEnabledState( + pSrcReq->ChannelInfo.ChannelList[index]); + if ((NV_CHANNEL_ENABLE == NVchannel_state) || + ((NV_CHANNEL_DFS == NVchannel_state) && + !skip_dfs_chnl)) + { + pDstReq->ChannelInfo.ChannelList[new_index] = + pSrcReq->ChannelInfo.ChannelList[index]; + new_index++; + } + } + pDstReq->ChannelInfo.numOfChannels = new_index; + } + else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + new_index = 0; + pMac->roam.numValidChannels = len; + for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ ) + { + /* Allow scan on valid channels only. + * If it is p2p scan and valid channel list doesnt contain + * social channels, enforce scan on social channels because + * that is the only way to find p2p peers. + * This can happen only if band is set to 5Ghz mode. + */ + if((csrRoamIsValidChannel(pMac, pSrcReq->ChannelInfo.ChannelList[index])) || + ((eCSR_SCAN_P2P_DISCOVERY == pSrcReq->requestType) && + CSR_IS_SOCIAL_CHANNEL(pSrcReq->ChannelInfo.ChannelList[index]))) + { + if( ((pSrcReq->skipDfsChnlInP2pSearch || + skip_dfs_chnl) && + (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(pSrcReq->ChannelInfo.ChannelList[index])) ) +#ifdef FEATURE_WLAN_LFR + /* + * If LFR is requesting a contiguous scan + * (i.e. numOfChannels > 1), then ignore + * DFS channels. + * TODO: vos_nv_getChannelEnabledState is returning + * 120, 124 and 128 as non-DFS channels. Hence, the + * use of direct check for channels below. + */ + || ((eCSR_SCAN_HO_BG_SCAN == pSrcReq->requestType) && + (pSrcReq->ChannelInfo.numOfChannels > 1) && + (CSR_IS_CHANNEL_DFS(pSrcReq->ChannelInfo.ChannelList[index]))) +#endif + ) + { +#ifdef FEATURE_WLAN_LFR + smsLog(pMac, LOG2, + FL(" reqType=%d, numOfChannels=%d," + " ignoring DFS channel %d"), + pSrcReq->requestType, + pSrcReq->ChannelInfo.numOfChannels, + pSrcReq->ChannelInfo.ChannelList[index]); +#endif + continue; + } + + pDstReq->ChannelInfo.ChannelList[new_index] = + pSrcReq->ChannelInfo.ChannelList[index]; + new_index++; + } + } + pDstReq->ChannelInfo.numOfChannels = new_index; +#ifdef FEATURE_WLAN_LFR + if ((eCSR_SCAN_HO_BG_SCAN == pSrcReq->requestType) && + (0 == pDstReq->ChannelInfo.numOfChannels)) + { + /* + * No valid channels found in the request. + * Only perform scan on the channels passed + * pSrcReq if it is a eCSR_SCAN_HO_BG_SCAN. + * Passing 0 to LIM will trigger a scan on + * all valid channels which is not desirable. + */ + smsLog(pMac, LOGE, FL(" no valid channels found" + " (request=%d)"), pSrcReq->requestType); + for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ ) + { + smsLog(pMac, LOGE, FL("pSrcReq index=%d" + " channel=%d"), index, + pSrcReq->ChannelInfo.ChannelList[index]); + } + status = eHAL_STATUS_FAILURE; + break; + } +#endif + } + else + { + smsLog(pMac, LOGE, FL("Couldn't get the valid Channel" + " List, keeping requester's list")); + vos_mem_copy(pDstReq->ChannelInfo.ChannelList, + pSrcReq->ChannelInfo.ChannelList, + pSrcReq->ChannelInfo.numOfChannels + * sizeof(*pDstReq->ChannelInfo.ChannelList)); + pDstReq->ChannelInfo.numOfChannels = pSrcReq->ChannelInfo.numOfChannels; + } + }//Allocate memory for Channel List + } + if(pSrcReq->SSIDs.numOfSSIDs == 0) + { + pDstReq->SSIDs.numOfSSIDs = 0; + pDstReq->SSIDs.SSIDList = NULL; + } + else + { + pDstReq->SSIDs.SSIDList = vos_mem_malloc( + pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList)); + if ( NULL == pDstReq->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + pDstReq->SSIDs.numOfSSIDs = pSrcReq->SSIDs.numOfSSIDs; + vos_mem_copy(pDstReq->SSIDs.SSIDList, + pSrcReq->SSIDs.SSIDList, + pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList)); + } + else + { + pDstReq->SSIDs.numOfSSIDs = 0; + smsLog(pMac, LOGE, FL("No memory for scanning SSID List")); + break; + } + }//Allocate memory for SSID List + pDstReq->p2pSearch = pSrcReq->p2pSearch; + pDstReq->skipDfsChnlInP2pSearch = pSrcReq->skipDfsChnlInP2pSearch; + + } + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanFreeRequest(pMac, pDstReq); + } + + return (status); +} + + +eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq) +{ + + if(pReq->ChannelInfo.ChannelList) + { + vos_mem_free(pReq->ChannelInfo.ChannelList); + pReq->ChannelInfo.ChannelList = NULL; + } + pReq->ChannelInfo.numOfChannels = 0; + if(pReq->pIEField) + { + vos_mem_free(pReq->pIEField); + pReq->pIEField = NULL; + } + pReq->uIEFieldLen = 0; + if(pReq->SSIDs.SSIDList) + { + vos_mem_free(pReq->SSIDs.SSIDList); + pReq->SSIDs.SSIDList = NULL; + } + pReq->SSIDs.numOfSSIDs = 0; + + return eHAL_STATUS_SUCCESS; +} + + +void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus) +{ + if(pCommand->u.scanCmd.callback) + { + pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, + pCommand->sessionId, + pCommand->u.scanCmd.scanID, scanStatus); + } else { + smsLog( pMac, LOG2, "%s:%d - Callback NULL!!!", __func__, __LINE__); + } +} + + +void csrScanStopTimers(tpAniSirGlobal pMac) +{ + csrScanStopResultAgingTimer(pMac); + csrScanStopIdleScanTimer(pMac); + csrScanStopGetResultTimer(pMac); + if(0 != pMac->scan.scanResultCfgAgingTime ) + { + csrScanStopResultCfgAgingTimer(pMac); + } + +} + + +eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac) +{ + eHalStatus status; + + if(pMac->scan.fScanEnable) + { + status = vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/VOS_TIMER_TO_MS_UNIT); + } + else + { + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + +eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerGetResult)); +} + + +void csrScanGetResultTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + + csrScanRequestResult(pMac); + + vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/VOS_TIMER_TO_MS_UNIT); +} + +#ifdef WLAN_AP_STA_CONCURRENCY +static void csrStaApConcTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry; + tSmeCmd *pScanCmd; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + + csrLLLock(&pMac->scan.scanCmdPendingList); + + if ( NULL != ( pEntry = csrLLPeekHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) ) + { + tCsrScanRequest scanReq; + tSmeCmd *pSendScanCmd = NULL; + tANI_U8 numChn = 0; + tANI_U8 nNumChanCombinedConc = 0; + tANI_U8 i, j; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + eHalStatus status; + + pScanCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + sessionId = pScanCmd->sessionId; + + /* if any session is connected and the number of channels to scan is + * greater than 1 then split the scan into multiple scan operations + * on each individual channel else continue to perform scan on all + * specified channels */ + + /* split scan if number of channels to scan is greater than 1 and + * any one of the following: + * - STA session is connected and the scan is not a P2P search + * - any P2P session is connected + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + + if((csrIsStaSessionConnected(pMac) && + !csrIsP2pSessionConnected(pMac))) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + } + else if(csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; + } + + if ( (numChn > nNumChanCombinedConc) && + ((csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) && + (pMac->roam.neighborRoamInfo[sessionId].neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac)))) + { + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + pSendScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only + if (!pSendScanCmd) + { + smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") ); + csrLLUnlock(&pMac->scan.scanCmdPendingList); + return; + } + pSendScanCmd->command = pScanCmd->command; + pSendScanCmd->sessionId = pScanCmd->sessionId; + pSendScanCmd->u.scanCmd.callback = NULL; + pSendScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext; + pSendScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason; + pSendScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + /* First copy all the parameters to local variable of scan request */ + csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest); + + /* Now modify the elements of local var scan request required to be modified for split scan */ + if(scanReq.ChannelInfo.ChannelList != NULL) + { + vos_mem_free(scanReq.ChannelInfo.ChannelList); + scanReq.ChannelInfo.ChannelList = NULL; + } + + pChnInfo->numOfChannels = nNumChanCombinedConc; + vos_mem_copy(&channelToScan[0], + &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0], + pChnInfo->numOfChannels * sizeof(tANI_U8));//just send one channel + pChnInfo->ChannelList = &channelToScan[0]; + + for (i = 0, j = nNumChanCombinedConc; i < (numChn-nNumChanCombinedConc); i++, j++) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] = + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[j]; //Move all the channels one step + } + + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn - nNumChanCombinedConc; //reduce outstanding # of channels to be scanned + + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + //Modify callers parameters in case of concurrency + scanReq.scanType = eSIR_ACTIVE_SCAN; + //Use concurrency values for min/maxChnTime. + csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq); + + status = csrScanCopyRequest(pMac, &pSendScanCmd->u.scanCmd.u.scanRequest, &scanReq); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status ); + csrLLUnlock(&pMac->scan.scanCmdPendingList); + return; + } + /* Clean the local scan variable */ + scanReq.ChannelInfo.ChannelList = NULL; + scanReq.ChannelInfo.numOfChannels = 0; + csrScanFreeRequest(pMac, &scanReq); + } + else + { + /* no active connected session present or numChn == 1 + * scan all remaining channels */ + pSendScanCmd = pScanCmd; + //remove this command from pending list + if (csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) == NULL) + { //In case between PeekHead and here, the entry got removed by another thread. + smsLog( pMac, LOGE, FL(" Failed to remove entry from scanCmdPendingList")); + } + + } + csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE); + + } + + csrLLUnlock(&pMac->scan.scanCmdPendingList); + +} +#endif + +eHalStatus csrScanStartResultAgingTimer(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + if(pMac->scan.fScanEnable) + { + status = vos_timer_start(&pMac->scan.hTimerResultAging, CSR_SCAN_RESULT_AGING_INTERVAL/VOS_TIMER_TO_MS_UNIT); + } + return (status); +} + +eHalStatus csrScanStartResultCfgAgingTimer(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + if(pMac->scan.fScanEnable) + { + status = vos_timer_start(&pMac->scan.hTimerResultCfgAging, CSR_SCAN_RESULT_CFG_AGING_INTERVAL/VOS_TIMER_TO_MS_UNIT); + } + return (status); +} + +eHalStatus csrScanStopResultAgingTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerResultAging)); +} + +eHalStatus csrScanStopResultCfgAgingTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerResultCfgAging)); +} + +//This function returns the maximum time a BSS is allowed in the scan result. +//The time varies base on connection and power saving factors. +//Not connected, No PS +//Not connected, with PS +//Connected w/o traffic, No PS +//Connected w/o traffic, with PS +//Connected w/ traffic, no PS -- Not supported +//Connected w/ traffic, with PS -- Not supported +//the return unit is in seconds. +tANI_U32 csrScanGetAgeOutTime(tpAniSirGlobal pMac) +{ + tANI_U32 nRet; + + if(pMac->scan.nAgingCountDown) + { + //Calculate what should be the timeout value for this + nRet = pMac->scan.nLastAgeTimeOut * pMac->scan.nAgingCountDown; + pMac->scan.nAgingCountDown--; + } + else + { + if( csrIsAllSessionDisconnected( pMac ) ) + { + if(pmcIsPowerSaveEnabled(pMac, ePMC_IDLE_MODE_POWER_SAVE)) + { + nRet = pMac->roam.configParam.scanAgeTimeNCPS; + } + else + { + nRet = pMac->roam.configParam.scanAgeTimeNCNPS; + } + } + else + { + if(pmcIsPowerSaveEnabled(pMac, ePMC_BEACON_MODE_POWER_SAVE)) + { + nRet = pMac->roam.configParam.scanAgeTimeCPS; + } + else + { + nRet = pMac->roam.configParam.scanAgeTimeCNPS; + } + } + //If state-change causing aging time out change, we want to delay it somewhat to avoid + //unnecessary removal of BSS. This is mostly due to transition from connect to disconnect. + if(pMac->scan.nLastAgeTimeOut > nRet) + { + if(nRet) + { + pMac->scan.nAgingCountDown = (pMac->scan.nLastAgeTimeOut / nRet); + } + pMac->scan.nLastAgeTimeOut = nRet; + nRet *= pMac->scan.nAgingCountDown; + } + else + { + pMac->scan.nLastAgeTimeOut = nRet; + } + } + + return (nRet); +} + + +void csrScanResultAgingTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tANI_BOOLEAN fDisconnected = csrIsAllSessionDisconnected(pMac); + + //no scan, no aging + if (pMac->scan.fScanEnable && + (((eANI_BOOLEAN_FALSE == fDisconnected) && pMac->roam.configParam.bgScanInterval) + || (fDisconnected && (pMac->scan.fCancelIdleScan == eANI_BOOLEAN_FALSE)) + || (pMac->fScanOffload)) + ) + { + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + tANI_TIMESTAMP ageOutTime = (tANI_TIMESTAMP)(csrScanGetAgeOutTime(pMac) * PAL_TICKS_PER_SECOND); //turn it into 10ms units + tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime) + { + smsLog(pMac, LOGW, " age out due to time out"); + csrScanAgeOutBss(pMac, pResult); + } + pEntry = tmpEntry; + } + csrLLUnlock(&pMac->scan.scanResultList); + } + vos_timer_start(&pMac->scan.hTimerResultAging, CSR_SCAN_RESULT_AGING_INTERVAL/VOS_TIMER_TO_MS_UNIT); +} + +static void csrScanResultCfgAgingTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + tANI_TIMESTAMP ageOutTime = pMac->scan.scanResultCfgAgingTime * PAL_TICKS_PER_SECOND; + tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime) + { + smsLog(pMac, LOGW, " age out due to time out"); + csrScanAgeOutBss(pMac, pResult); + } + pEntry = tmpEntry; + } + csrLLUnlock(&pMac->scan.scanResultList); + vos_timer_start(&pMac->scan.hTimerResultCfgAging, CSR_SCAN_RESULT_CFG_AGING_INTERVAL/VOS_TIMER_TO_MS_UNIT); +} + +eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval) +{ + eHalStatus status; + + smsLog(pMac, LOG1, " csrScanStartIdleScanTimer"); + if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) && interval) + { + pMac->scan.nIdleScanTimeGap += interval; + vos_timer_stop(&pMac->scan.hTimerIdleScan); + status = vos_timer_start(&pMac->scan.hTimerIdleScan, interval/VOS_TIMER_TO_MS_UNIT); + if( !HAL_STATUS_SUCCESS(status) ) + { + smsLog(pMac, LOGE, " Fail to start Idle scan timer. status = %d interval = %d", status, interval); + //This should not happen but set the flag to restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + } + else + { + if( pMac->scan.fScanEnable && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) ) + { + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + +eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerIdleScan)); +} + + +//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR +void csrScanSuspendIMPS( tpAniSirGlobal pMac ) +{ + csrScanCancelIdleScan(pMac); +} + + +//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS +//because IMPS maybe disabled. +void csrScanResumeIMPS( tpAniSirGlobal pMac ) +{ + csrScanStartIdleScan( pMac ); +} + + +void csrScanIMPSCallback(void *callbackContext, eHalStatus status) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext ); + + if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + if(pMac->roam.configParam.IsIdleScanEnabled) + { + if(HAL_STATUS_SUCCESS(status)) + { + if(csrIsAllSessionDisconnected(pMac) && !csrIsRoamCommandWaiting(pMac)) + { + smsLog(pMac, LOGW, FL("starts idle mode full scan")); + csrScanAllChannels(pMac, eCSR_SCAN_IDLE_MODE_SCAN); + } + else + { + smsLog(pMac, LOGW, FL("cannot start idle mode full scan")); + //even though we are in timer handle, calling stop timer will make sure the timer + //doesn't get to restart. + csrScanStopIdleScanTimer(pMac); + } + } + else + { + smsLog(pMac, LOGE, FL("sees not success status (%d)"), status); + } + } + else + {//we might need another flag to check if CSR needs to request imps at all + + tANI_U32 nTime = 0; + + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime))) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } + } +} + + +//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for +//idle scan timer interval +//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan +eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval) +{ + eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE; + + //Do not trigger IMPS in case of concurrency + if (vos_concurrent_open_sessions_running() && + csrIsAnySessionInConnectState(pMac)) + { + smsLog( pMac, LOG1, FL("Cannot request IMPS because Concurrent Sessions Running") ); + return (status); + } + + if(pTimeInterval) + { + *pTimeInterval = 0; + } + + smsLog(pMac, LOG3, FL("called")); + if( smeCommandPending( pMac ) ) + { + smsLog( pMac, LOG1, FL(" Cannot request IMPS because command pending") ); + //Not to enter IMPS because more work to do + if(pTimeInterval) + { + *pTimeInterval = 0; + } + //restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return (status); + } + if (IsPmcImpsReqFailed (pMac)) + { + if(pTimeInterval) + { + *pTimeInterval = 1000000; //usec + } + //restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return status; + } + if((pMac->scan.fScanEnable) && + (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)) { + //Stop get result timer because idle scan gets scan result out of PE + csrScanStopGetResultTimer(pMac); + if(pTimeInterval) + { + *pTimeInterval = pMac->roam.configParam.impsSleepTime; + } + //pmcRequestImps take a period in millisecond unit. + status = pmcRequestImps(pMac, + pMac->roam.configParam.impsSleepTime / VOS_TIMER_TO_MS_UNIT, + csrScanIMPSCallback, pMac); + if(!HAL_STATUS_SUCCESS(status)) + { + if(eHAL_STATUS_PMC_ALREADY_IN_IMPS != status) + { + //Do restart the timer if CSR thinks it cannot do IMPS + if( !csrCheckPSReady( pMac ) ) + { + if(pTimeInterval) + { + *pTimeInterval = 0; + } + //Set the restart flag to true because that idle scan + //can be restarted even though the timer will not be running + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + else + { + //For not now, we do a quicker retry + if(pTimeInterval) + { + *pTimeInterval = CSR_IDLE_SCAN_WAIT_TIME; + } + } + smsLog(pMac, LOGW, FL("call pmcRequestImps and it returns status code (%d)"), status); + } + else + { + smsLog(pMac, LOGW, FL("already in IMPS")); + //Since CSR is the only module to request for IMPS. If it is already in IMPS, CSR assumes + //the callback will be called in the future. Should not happen though. + status = eHAL_STATUS_SUCCESS; + pMac->scan.nIdleScanTimeGap = 0; + } + } + else + { + //requested so let's reset the value + pMac->scan.nIdleScanTimeGap = 0; + } + } + + return (status); +} + + +eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE; + tANI_U32 nTime = 0; + + smsLog(pMac, LOGW, FL("called")); + /* + * Idle Scan not supported with Power Save Offload + * Enabled + */ + if(pMac->psOffloadEnabled) + { + return eHAL_STATUS_SUCCESS; + } + + if(pMac->roam.configParam.IsIdleScanEnabled) + { + //stop bg scan first + csrScanBGScanAbort(pMac); + //Stop get result timer because idle scan gets scan result out of PE + csrScanStopGetResultTimer(pMac); + //Enable aging timer since idle scan is going on + csrScanStartResultAgingTimer(pMac); + } + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE; + status = csrScanTriggerIdleScan(pMac, &nTime); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + + return (status); +} + + +void csrScanCancelIdleScan(tpAniSirGlobal pMac) +{ + /* + * Idle Scan not supported with Power Save Offload + * Enabled + */ + if(pMac->psOffloadEnabled) + { + return; + } + + if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + if (vos_concurrent_open_sessions_running()) { + return; + } + smsLog(pMac, LOG1, " csrScanCancelIdleScan"); + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE; + //Set the restart flag in case later on it is uncancelled + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + csrScanStopIdleScanTimer(pMac); + csrScanRemoveNotRoamingScanCommand(pMac); + } +} + + +void csrScanIdleScanTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + eHalStatus status; + tANI_U32 nTime = 0; + + smsLog(pMac, LOGW, " csrScanIdleScanTimerHandler called "); + pmcResetImpsFailStatus (pMac); + status = csrScanTriggerIdleScan(pMac, &nTime); + if(!HAL_STATUS_SUCCESS(status) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)) + { + //Check whether it is time to actually do an idle scan + if(pMac->scan.nIdleScanTimeGap >= pMac->roam.configParam.impsSleepTime) + { + pMac->scan.nIdleScanTimeGap = 0; + csrScanIMPSCallback(pMac, eHAL_STATUS_SUCCESS); + } + else + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } +} + + + + +tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry, *pEntryTmp; + tSmeCmd *pCommand; + tDblLinkList localList; + tDblLinkList *pCmdList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return fRet; + } + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdPendingList; + else + pCmdList = &pMac->sme.smeScanCmdPendingList; + + csrLLLock(pCmdList); + pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandScan == pCommand->command ) + { + switch( pCommand->u.scanCmd.reason ) + { + case eCsrScanIdleScan: + if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) ) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + fRet = eANI_BOOLEAN_TRUE; + break; + + default: + break; + } //switch + } + pEntry = pEntryTmp; + } + + csrLLUnlock(pCmdList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + csrReleaseCommandScan( pMac, pCommand ); + } + + csrLLClose(&localList); + + return (fRet); +} + + +tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry, *pEntryTmp; + tSmeCmd *pCommand; + tDblLinkList localList; + tDblLinkList *pCmdList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return fRet; + } + + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdPendingList; + else + pCmdList = &pMac->sme.smeScanCmdPendingList; + + csrLLLock(pCmdList); + pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( (eSmeCommandScan == pCommand->command) && (sessionId == pCommand->sessionId) ) + { + switch(pCommand->u.scanCmd.reason) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanSetBGScanParam: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + break; + default: + smsLog (pMac, LOGW, "%s: -------- abort scan command reason = %d", + __func__, pCommand->u.scanCmd.reason); + //The rest are fresh scan requests + if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) ) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + pEntry = pEntryTmp; + } + + csrLLUnlock(pCmdList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if (pCommand->u.scanCmd.callback) + { + /* User scan request is pending, + * send response with status eCSR_SCAN_ABORT*/ + pCommand->u.scanCmd.callback(pMac, + pCommand->u.scanCmd.pContext, + sessionId, + pCommand->u.scanCmd.scanID, + eCSR_SCAN_ABORT); + } + csrReleaseCommandScan( pMac, pCommand ); + } + csrLLClose(&localList); + + return (fRet); +} + + +void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus) +{ + eCsrScanReason reason = pCommand->u.scanCmd.reason; + tANI_BOOLEAN status; + + if (!pMac->fScanOffload) + { + tANI_U32 i; + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + csrRoamStateChange(pMac, pCommand->u.scanCmd.lastRoamState[i], i); + } + else + { + csrRoamStateChange(pMac, + pCommand->u.scanCmd.lastRoamState[pCommand->sessionId], + pCommand->sessionId); + } + + csrScanCallCallback(pMac, pCommand, scanStatus); + + smsLog(pMac, LOG3, " Remove Scan command reason = %d", reason); + if (pMac->fScanOffload) + { + status = csrLLRemoveEntry(&pMac->sme.smeScanCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK); + } + else + { + status = csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK); + } + + if(status) + { + csrReleaseCommandScan( pMac, pCommand ); + } + else + { + smsLog(pMac, LOGE, + " ********csrReleaseScanCommand cannot release command reason %d", + pCommand->u.scanCmd.reason ); + } +} + + +eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate); + csrResetPMKIDCandidateList(pMac, sessionId); + if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile) + { + tCsrScanResultFilter *pScanFilter; + tCsrScanResultInfo *pScanResult; + tScanResultHandle hBSSList; + tANI_U32 nItems = *pNumItems; + + *pNumItems = 0; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumPmkidCandidate < nItems)) + { + //NumPmkidCandidate adds up here + csrProcessBSSDescForPMKIDList(pMac, + &pScanResult->BssDescriptor, + (tDot11fBeaconIEs *)(pScanResult->pvIes), + sessionId); + } + if(pSession->NumPmkidCandidate) + { + *pNumItems = pSession->NumPmkidCandidate; + vos_mem_copy(pPmkidList, pSession->PmkidCandidateInfo, + pSession->NumPmkidCandidate * sizeof(tPmkidCandidateInfo)); + } + csrScanResultPurge(pMac, hBSSList); + }//Have scan result + csrFreeScanFilter(pMac, pScanFilter); + } + vos_mem_free(pScanFilter); + } + } + + return (status); +} + + + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " pMac->scan.NumBkidCandidate = %d", pSession->NumBkidCandidate); + csrResetBKIDCandidateList(pMac, sessionId); + if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile) + { + tCsrScanResultFilter *pScanFilter; + tCsrScanResultInfo *pScanResult; + tScanResultHandle hBSSList; + tANI_U32 nItems = *pNumItems; + *pNumItems = 0; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumBkidCandidate < nItems)) + { + //pMac->scan.NumBkidCandidate adds up here + csrProcessBSSDescForBKIDList(pMac, &pScanResult->BssDescriptor, + (tDot11fBeaconIEs *)( pScanResult->pvIes )); + + } + if(pSession->NumBkidCandidate) + { + *pNumItems = pSession->NumBkidCandidate; + vos_mem_copy(pBkidList, pSession->BkidCandidateInfo, pSession->NumBkidCandidate * sizeof(tBkidCandidateInfo)); + } + csrScanResultPurge(pMac, hBSSList); + }//Have scan result + } + vos_mem_free(pScanFilter); + } + } + + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ + + + +//This function is usually used for BSSs that suppresses SSID so the profile +//shall have one and only one SSID +eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pScanCmd = NULL; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_U8 index = 0; + tANI_U32 numSsid = pProfile->SSIDs.numOfSSIDs; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + smsLog(pMac, LOG2, FL("called")); + //For WDS, we use the index 0. There must be at least one in there + if( CSR_IS_WDS_STA( pProfile ) && numSsid ) + { + numSsid = 1; + } + if(pMac->scan.fScanEnable && ( numSsid == 1 ) ) + { + do + { + pScanCmd = csrGetCommandBuffer(pMac); + if(!pScanCmd) + { + smsLog(pMac, LOGE, FL("failed to allocate command buffer")); + break; + } + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.pToRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pScanCmd->u.scanCmd.pToRoamProfile ) + { + status = eHAL_STATUS_FAILURE; + } + else + { + status = csrRoamCopyProfile(pMac, pScanCmd->u.scanCmd.pToRoamProfile, pProfile); + } + if(!HAL_STATUS_SUCCESS(status)) + break; + pScanCmd->u.scanCmd.roamId = roamId; + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = (tANI_U8)sessionId; + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + pScanCmd->u.scanCmd.reason = eCsrScanForSsid;//Need to check: might need a new reason for SSID scan for LFR during multisession with p2p + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + vos_mem_set(&pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest), 0); + pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + pScanCmd->u.scanCmd.u.scanRequest.BSSType = pProfile->BSSType; + // To avoid 11b rate in probe request Set p2pSearch flag as 1 for P2P Client Mode + if(VOS_P2P_CLIENT_MODE == pProfile->csrPersona) + { + pScanCmd->u.scanCmd.u.scanRequest.p2pSearch = 1; + } + if(pProfile->pAddIEScan) + { + pScanCmd->u.scanCmd.u.scanRequest.pIEField = vos_mem_malloc( + pProfile->nAddIEScanLength); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.pIEField ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + vos_mem_set(pScanCmd->u.scanCmd.u.scanRequest.pIEField, + pProfile->nAddIEScanLength, 0); + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.pIEField, + pProfile->pAddIEScan, pProfile->nAddIEScanLength); + pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = pProfile->nAddIEScanLength; + } + else + { + smsLog(pMac, LOGE, "No memory for scanning IE fields"); + } + } //Allocate memory for IE field + else + { + pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = 0; + } + /* For one channel be good enpugh time to receive beacon atleast */ + if( 1 == pProfile->ChannelInfo.numOfChannels ) + { +#if defined (WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + if (pNeighborRoamInfo->handoffReqInfo.src == FASTREASSOC) { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = + MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime = + MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC; + /* Reset this value */ + pNeighborRoamInfo->handoffReqInfo.src = 0; + } + else +#endif + { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL; + } + } + else + { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = + pMac->roam.configParam.nActiveMaxChnTime; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime = + pMac->roam.configParam.nActiveMinChnTime; + } + pScanCmd->u.scanCmd.u.scanRequest.maxChnTimeBtc = + pMac->roam.configParam.nActiveMaxChnTimeBtc; + pScanCmd->u.scanCmd.u.scanRequest.minChnTimeBtc = + pMac->roam.configParam.nActiveMinChnTimeBtc; + if(pProfile->BSSIDs.numOfBSSIDs == 1) + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid, + pProfile->BSSIDs.bssid, sizeof(tCsrBssid)); + } + else + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid, bAddr, 6); + } + if(pProfile->ChannelInfo.numOfChannels) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc( + sizeof(*pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + * pProfile->ChannelInfo.numOfChannels); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0; + if(HAL_STATUS_SUCCESS(status)) + { + csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[0]); + for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++) + { + if(csrRoamIsValidChannel(pMac, pProfile->ChannelInfo.ChannelList[index])) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels] + = pProfile->ChannelInfo.ChannelList[index]; + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++; + } + else + { + smsLog(pMac, LOGW, FL("process a channel (%d) that is invalid"), pProfile->ChannelInfo.ChannelList[index]); + } + + } + } + else + { + break; + } + + } + else + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0; + } + if(pProfile->SSIDs.numOfSSIDs) + { + pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc( + pProfile->SSIDs.numOfSSIDs * sizeof(tCsrSSIDInfo)); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pScanCmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1; + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList, + pProfile->SSIDs.SSIDList, sizeof(tCsrSSIDInfo)); + } + //Start process the command + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(pScanCmd) + { + csrReleaseCommandScan(pMac, pScanCmd); + //TODO:free the memory that is allocated in this function + } + if(notify) + { + csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + } + }//valid + else + { + smsLog(pMac, LOGE, FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid"), + pMac->scan.fScanEnable, pProfile->SSIDs.numOfSSIDs); + } + + return (status); +} + + +//Issue a scan base on the new capability infomation +//This should only happen when the associated AP changes its capability. +//After this scan is done, CSR reroams base on the new scan results +eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pScanCmd = NULL; + + if(pNewCaps) + { + do + { + pScanCmd = csrGetCommandBuffer(pMac); + if(!pScanCmd) + { + smsLog(pMac, LOGE, FL("failed to allocate command buffer")); + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + status = eHAL_STATUS_SUCCESS; + pScanCmd->u.scanCmd.roamId = 0; + pScanCmd->command = eSmeCommandScan; + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + pScanCmd->u.scanCmd.reason = eCsrScanForCapsChange; + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(pScanCmd) + { + csrReleaseCommandScan(pMac, pScanCmd); + } + } + } + + return (status); +} + + + +void csrInitBGScanChannelList(tpAniSirGlobal pMac) +{ + tANI_U32 len = CSR_MIN(sizeof(pMac->roam.validChannelList), sizeof(pMac->scan.bgScanChannelList)); + + vos_mem_set(pMac->scan.bgScanChannelList, len, 0); + pMac->scan.numBGScanChannel = 0; + + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + pMac->roam.numValidChannels = len; + pMac->scan.numBGScanChannel = (tANI_U8)CSR_MIN(len, WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN); + vos_mem_copy(pMac->scan.bgScanChannelList, pMac->roam.validChannelList, + pMac->scan.numBGScanChannel); + csrSetBGScanChannelList(pMac, pMac->scan.bgScanChannelList, pMac->scan.numBGScanChannel); + } +} + + +//This function return TRUE if background scan channel list is adjusted. +//this function will only shrink the background scan channel list +tANI_BOOLEAN csrAdjustBGScanChannelList(tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels, + tANI_U8 *pAdjustChannels, tANI_U8 *pNumAdjustChannels) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U8 i, j, count = *pNumAdjustChannels; + + i = 0; + while(i < count) + { + for(j = 0; j < NumChannels; j++) + { + if(pChannelList[j] == pAdjustChannels[i]) + break; + } + if(j == NumChannels) + { + //This channel is not in the list, remove it + fRet = eANI_BOOLEAN_TRUE; + count--; + if(count - i) + { + vos_mem_copy(&pAdjustChannels[i], &pAdjustChannels[i+1], count - i); + } + else + { + //already remove the last one. Done. + break; + } + } + else + { + i++; + } + }//while(iscan.baseChannels.channelList, &n, NULL, NULL ); + if( HAL_STATUS_SUCCESS(status) ) + { + pMac->scan.baseChannels.numChannels = (tANI_U8)n; + } + else + { + smsLog( pMac, LOGE, FL(" failed") ); + pMac->scan.baseChannels.numChannels = 0; + } + + return ( status ); +} + +//This function use the input pChannelList to validate the current saved channel list +eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels) +{ + tANI_U32 dataLen = sizeof( tANI_U8 ) * NumAdjustChannels; + + return (ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pAdjustChannels, dataLen, NULL, eANI_BOOLEAN_FALSE)); +} + + +void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels ) +{ + tANI_U32 dataLen = sizeof( tANI_U8 ) * NumChannels; + eHalStatus status; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: dump valid channel list(NumChannels(%d))", + __func__,NumChannels); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + pChannelList, NumChannels); + ccmCfgSetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE); + + if (pMac->fScanOffload) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Scan offload is enabled, update default chan list"); + /* + * disable fcc constraint since new country code + * is being set + */ + pMac->scan.fcc_constraint = false; + status = csrUpdateChannelList(pMac); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to update the supported channel list"); + } + } + return; +} + + + +/* + * The Tx power limits are saved in the cfg for future usage. + */ +void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId ) +{ + tListElem *pEntry; + tANI_U32 cbLen = 0, dataLen; + tCsrChannelPowerInfo *pChannelSet; + tANI_U32 idx; + tSirMacChanInfo *pChannelPowerSet; + tANI_U8 *pBuf = NULL; + + //allocate maximum space for all channels + dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo); + if ( (pBuf = vos_mem_malloc(dataLen)) != NULL ) + { + vos_mem_set(pBuf, dataLen, 0); + pChannelPowerSet = (tSirMacChanInfo *)(pBuf); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + // write the tuples (startChan, numChan, txPower) for each channel found in the channel power list. + while( pEntry ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if ( 1 != pChannelSet->interChannelOffset ) + { + // we keep the 5G channel sets internally with an interchannel offset of 4. Expand these + // to the right format... (inter channel offset of 1 is the only option for the triplets + // that 11d advertises. + if ((cbLen + (pChannelSet->numChannels * sizeof(tSirMacChanInfo))) >= dataLen) + { + // expanding this entry will overflow our allocation + smsLog(pMac, LOGE, + "%s: Buffer overflow, start %d, num %d, offset %d", + __func__, + pChannelSet->firstChannel, + pChannelSet->numChannels, + pChannelSet->interChannelOffset); + break; + } + + for( idx = 0; idx < pChannelSet->numChannels; idx++ ) + { + pChannelPowerSet->firstChanNum = (tSirMacChanNum)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset )); + smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum); + pChannelPowerSet->numChannels = 1; + pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap ); + smsLog(pMac, LOG3, " Setting Max Transmit Power %d", pChannelPowerSet->maxTxPower); + cbLen += sizeof( tSirMacChanInfo ); + pChannelPowerSet++; + } + } + else + { + if (cbLen >= dataLen) + { + // this entry will overflow our allocation + smsLog(pMac, LOGE, + "%s: Buffer overflow, start %d, num %d, offset %d", + __func__, + pChannelSet->firstChannel, + pChannelSet->numChannels, + pChannelSet->interChannelOffset); + break; + } + pChannelPowerSet->firstChanNum = pChannelSet->firstChannel; + smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum); + pChannelPowerSet->numChannels = pChannelSet->numChannels; + pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap ); + smsLog(pMac, LOG3, " Setting Max Transmit Power %d, nTxPower %d", pChannelPowerSet->maxTxPower,pMac->roam.configParam.nTxPowerCap ); + + + cbLen += sizeof( tSirMacChanInfo ); + pChannelPowerSet++; + } + + pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK ); + } + + if(cbLen) + { + ccmCfgSetStr(pMac, cfgId, (tANI_U8 *)pBuf, cbLen, NULL, eANI_BOOLEAN_FALSE); + } + vos_mem_free(pBuf); + }//Allocate memory +} + + +void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode ) +{ + tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN]; + ///v_REGDOMAIN_t DomainId; + + smsLog( pMac, LOG3, "Setting Country Code in Cfg from csrSetCfgCountryCode %s",countryCode ); + vos_mem_copy(cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN); + + // don't program the bogus country codes that we created for Korea in the MAC. if we see + // the bogus country codes, program the MAC with the right country code. + if ( ( 'K' == countryCode[ 0 ] && '1' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '2' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '3' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '4' == countryCode[ 1 ] ) ) + { + // replace the alternate Korea country codes, 'K1', 'K2', .. with 'KR' for Korea + cc[ 1 ] = 'R'; + } + ccmCfgSetStr(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN, NULL, eANI_BOOLEAN_FALSE); + + //Need to let HALPHY know about the current domain so it can apply some + //domain-specific settings (TX filter...) + /*if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, cc, &DomainId))) + { + halPhySetRegDomain(pMac, DomainId); + }*/ +} + + + +eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + + if(pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN)) + { + len = *pbLen; + status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len); + if(HAL_STATUS_SUCCESS(status)) + { + *pbLen = (tANI_U8)len; + } + } + + return (status); +} + + +void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList ) +{ + tANI_U8 i, j; + tANI_BOOLEAN found=FALSE; + tANI_U8 *pControlList = NULL; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + + if ( (pControlList = vos_mem_malloc(WNI_CFG_SCAN_CONTROL_LIST_LEN)) != NULL ) + { + vos_mem_set((void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN, 0); + if(HAL_STATUS_SUCCESS(ccmCfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, &len))) + { + for (i = 0; i < pChannelList->numChannels; i++) + { + for (j = 0; j < len; j += 2) + { + if (pControlList[j] == pChannelList->channelList[i]) + { + found = TRUE; + break; + } + } + + if (found) // insert a pair(channel#, flag) + { + pControlList[j+1] = csrGetScanType(pMac, pControlList[j]); + found = FALSE; // reset the flag + } + + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: dump scan control list",__func__); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + pControlList, len); + + ccmCfgSetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, len, NULL, eANI_BOOLEAN_FALSE); + }//Successfully getting scan control list + vos_mem_free(pControlList); + }//AllocateMemory +} + + +//if bgPeriod is 0, background scan is disabled. It is in millisecond units +eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod) +{ + return (ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, bgPeriod, (tCcmCfgSetCallback) csrScanCcmCfgSetCallback, eANI_BOOLEAN_FALSE)); +} + + +void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tDblLinkList *pCmdList ; + + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdActiveList; + else + pCmdList = &pMac->sme.smeScanCmdActiveList; + + pEntry = csrLLPeekHead( pCmdList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandScan == pCommand->command ) + { + eCsrScanStatus scanStatus = (CCM_IS_RESULT_SUCCESS(result)) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + csrReleaseScanCommand(pMac, pCommand, scanStatus); + } + else + { + smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." ); + } + } + smeProcessPendingQueue( pMac ); +} + +eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status; + tCsrBGScanRequest *pScanReq = &pCommand->u.scanCmd.u.bgScanRequest; + tANI_U32 dataLen = sizeof( tANI_U8 ) * pScanReq->ChannelInfo.numOfChannels; + + //***setcfg for background scan channel list + status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, pScanReq->minChnTime, NULL, eANI_BOOLEAN_FALSE); + status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, pScanReq->maxChnTime, NULL, eANI_BOOLEAN_FALSE); + //Not set the background scan interval if not connected because bd scan should not be run if not connected + if(!csrIsAllSessionDisconnected(pMac)) + { + //If disbaling BG scan here, we need to stop aging as well + if(pScanReq->scanInterval == 0) + { + //Stop aging because no new result is coming in + csrScanStopResultAgingTimer(pMac); + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ; + pScanLog->minChnTime = (v_U8_t)pScanReq->minChnTime; + pScanLog->maxChnTime = (v_U8_t)pScanReq->maxChnTime; + pScanLog->timeBetweenBgScan = (v_U8_t)pScanReq->scanInterval; + pScanLog->numChannel = pScanReq->ChannelInfo.numOfChannels; + if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL)) + { + vos_mem_copy(pScanLog->channels, + pScanReq->ChannelInfo.ChannelList, + pScanLog->numChannel); + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, pScanReq->scanInterval, NULL, eANI_BOOLEAN_FALSE); + } + else + { + //No need to stop aging because IDLE scan is still running + status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, 0, NULL, eANI_BOOLEAN_FALSE); + } + + if(pScanReq->SSID.length > WNI_CFG_SSID_LEN) + { + pScanReq->SSID.length = WNI_CFG_SSID_LEN; + } + + status = ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pScanReq->ChannelInfo.ChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE); + status = ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pScanReq->SSID.ssId, pScanReq->SSID.length, NULL, eANI_BOOLEAN_FALSE); + + + + return (status); +} + + +eHalStatus csrScanAbortMacScan(tpAniSirGlobal pMac, tANI_U8 sessionId, + eCsrAbortReason reason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirSmeScanAbortReq *pMsg; + tANI_U16 msgLen; + tListElem *pEntry; + tSmeCmd *pCommand; + + if (!pMac->fScanOffload) + { +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLLock(&pMac->scan.scanCmdPendingList); + while(NULL != + (pEntry = csrLLRemoveHead(&pMac->scan.scanCmdPendingList, + LL_ACCESS_NOLOCK))) + { + + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLUnlock(&pMac->scan.scanCmdPendingList); +#endif + + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveCmdFromPendingList( pMac, &pMac->roam.roamCmdPendingList, eSmeCommandScan); + csrRemoveCmdFromPendingList( pMac, &pMac->sme.smeCmdPendingList, eSmeCommandScan); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + } + else + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveCmdWithSessionIdFromPendingList(pMac, + sessionId, + &pMac->sme.smeScanCmdPendingList, + eSmeCommandScan); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + } + + //We need to abort scan only if we are scanning + if(NULL != pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandScan == pCommand->command && + pCommand->sessionId == sessionId) + { + msgLen = (tANI_U16)(sizeof(tSirSmeScanAbortReq)); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq")); + } + else + { + if(reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) + { + pCommand->u.scanCmd.abortScanDueToBandChange + = eANI_BOOLEAN_TRUE; + } + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + } + } + + return(status); +} + +void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tDblLinkList *pList, + eSmeCommandType commandType) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if ((pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK))) + { + + /* Have to make sure we don't loop back to the head of the list, + * which will happen if the entry is NOT on the list */ + while (pEntry) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ((pCommand->command == commandType) && + (pCommand->sessionId == sessionId)) + { + /* Remove that entry only */ + if (csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, + LL_ACCESS_NOLOCK); + } + } + } + } + csrLLUnlock(pList); + + while ((pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK))) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + csrAbortCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + } + + csrLLClose(&localList); +} + +void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, + eSmeCommandType commandType ) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry ) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ( pCommand->command == commandType ) + { + // Remove that entry only + if(csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK); + } + } + } + + + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLClose(&localList); + +} + +eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanAbortReq *pMsg; + tANI_U16 msgLen; + tListElem *pEntry; + tSmeCmd *pCommand; + + if (!pMac->fScanOffload) + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; +#ifdef WLAN_AP_STA_CONCURRENCY + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->scan.scanCmdPendingList, sessionId); +#endif + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->roam.roamCmdPendingList, sessionId); + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeCmdPendingList, sessionId); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + } + else + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeScanCmdPendingList, sessionId); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + } + + if(NULL != pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + if ( (eSmeCommandScan == pCommand->command ) && + (sessionId == pCommand->sessionId)) + { + if ( eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + msgLen = (tANI_U16)(sizeof( tSirSmeScanAbortReq )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq")); + } + else + { + vos_mem_zero((void *)pMsg, msgLen); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + } + } + } + return( status ); +} + +void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry ) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ( (eSmeCommandScan == pCommand->command ) && + (sessionId == pCommand->sessionId) ) + { + if ( eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + // Remove that entry only + if ( csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK); + } + } + } + } + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLClose(&localList); +} + +eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if( !csrIsScanForRoamCommandActive( pMac ) ) + { + //Only abort the scan if it is not used for other roam/connect purpose + status = csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + } + + return (status); +} + + +eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + if (pMac->fScanOffload) + msgLen = (tANI_U16)(sizeof(tSirSmeGetScanChanReq)); + else + msgLen = (tANI_U16)(sizeof(tSirMbMsg)); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->type = eWNI_SME_GET_SCANNED_CHANNEL_REQ; + pMsg->msgLen = msgLen; + if (pMac->fScanOffload) + ((tSirSmeGetScanChanReq *)pMsg)->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel ) +{ + tANI_BOOLEAN fValid = FALSE; + tANI_U32 idxValidChannels; + tANI_U32 len = pMac->roam.numValidChannels; + + for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ ) + { + if ( channel == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fValid = TRUE; + break; + } + } + + return fValid; +} + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + v_U32_t uLen = 0; + tpSirProbeRespBeacon pParsedFrame; + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDescr = NULL; + tANI_BOOLEAN fDupBss; + tDot11fBeaconIEs *pIesLocal = NULL; + tAniSSID tmpSsid; + v_TIME_t timer=0; + tpSirMacMgmtHdr macHeader = (tpSirMacMgmtHdr)pPrefNetworkFoundInd->data; + + pParsedFrame = + (tpSirProbeRespBeacon)vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + + if (NULL == pParsedFrame) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for frame")); + return eHAL_STATUS_RESOURCES; + } + + if ( pPrefNetworkFoundInd->frameLength <= SIR_MAC_HDR_LEN_3A ) + { + smsLog(pMac, LOGE, + FL("Not enough bytes in PNO indication probe resp frame! length=%d"), + pPrefNetworkFoundInd->frameLength); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + + if (sirConvertProbeFrame2Struct(pMac, + &pPrefNetworkFoundInd->data[SIR_MAC_HDR_LEN_3A], + pPrefNetworkFoundInd->frameLength - SIR_MAC_HDR_LEN_3A, + pParsedFrame) != eSIR_SUCCESS || + !pParsedFrame->ssidPresent) + { + smsLog(pMac, LOGE, + FL("Parse error ProbeResponse, length=%d"), + pPrefNetworkFoundInd->frameLength); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + //24 byte MAC header and 12 byte to ssid IE + if (pPrefNetworkFoundInd->frameLength > + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) + { + uLen = pPrefNetworkFoundInd->frameLength - + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET); + } + + pScanResult = vos_mem_malloc(sizeof(tCsrScanResult) + uLen); + if ( NULL == pScanResult ) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for frame")); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + + vos_mem_set(pScanResult, sizeof(tCsrScanResult) + uLen, 0); + pBssDescr = &pScanResult->Result.BssDescriptor; + /** + * Length of BSS desription is without length of + * length itself and length of pointer + * that holds the next BSS description + */ + pBssDescr->length = (tANI_U16)( + sizeof(tSirBssDescription) - sizeof(tANI_U16) - + sizeof(tANI_U32) + uLen); + if (pParsedFrame->dsParamsPresent) + { + pBssDescr->channelId = pParsedFrame->channelNumber; + } + else if (pParsedFrame->HTInfo.present) + { + pBssDescr->channelId = pParsedFrame->HTInfo.primaryChannel; + } + else + { + pBssDescr->channelId = pParsedFrame->channelNumber; + } + + if ((pBssDescr->channelId > 0) && (pBssDescr->channelId < 15)) + { + int i; + // 11b or 11g packet + // 11g iff extended Rate IE is present or + // if there is an A rate in suppRate IE + for (i = 0; i < pParsedFrame->supportedRates.numRates; i++) + { + if (sirIsArate(pParsedFrame->supportedRates.rate[i] & 0x7f)) + { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + break; + } + } + if (pParsedFrame->extendedRatesPresent) + { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + } + } + else + { + // 11a packet + pBssDescr->nwType = eSIR_11A_NW_TYPE; + } + + pBssDescr->sinr = 0; + pBssDescr->rssi = -1 * pPrefNetworkFoundInd->rssi; + pBssDescr->beaconInterval = pParsedFrame->beaconInterval; + if (!pBssDescr->beaconInterval) + { + smsLog(pMac, LOGW, + FL("Bcn Interval is Zero , default to 100" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pBssDescr->bssId) ); + pBssDescr->beaconInterval = 100; + } + pBssDescr->timeStamp[0] = pParsedFrame->timeStamp[0]; + pBssDescr->timeStamp[1] = pParsedFrame->timeStamp[1]; + pBssDescr->capabilityInfo = *((tANI_U16 *)&pParsedFrame->capabilityInfo); + vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr)); + pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + smsLog( pMac, LOG2, "(%s):Bssid= "MAC_ADDRESS_STR + " chan= %d, rssi = %d", __func__, + MAC_ADDR_ARRAY(pBssDescr->bssId), + pBssDescr->channelId, + pBssDescr->rssi ); + + //IEs + if (uLen) + { + vos_mem_copy(&pBssDescr->ieFields, + pPrefNetworkFoundInd->data + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET), + uLen); + } + + pIesLocal = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + if ( !pIesLocal && + (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pScanResult->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" Cannot parse IEs")); + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + + fDupBss = csrRemoveDupBssDescription( pMac, + &pScanResult->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE); + //Check whether we have reach out limit + if ( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) ) + { + //Limit reach + smsLog(pMac, LOGE, FL(" BSS limit reached")); + //Free the resources + if( (pScanResult->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + //Add to scan cache + csrScanAddResult(pMac, pScanResult, pIesLocal, + pPrefNetworkFoundInd->sessionId); + + if( (pScanResult->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + + vos_mem_free(pParsedFrame); + + return eHAL_STATUS_SUCCESS; +} +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef FEATURE_WLAN_LFR +void csrInitOccupiedChannelsList(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tListElem *pEntry = NULL; + tCsrScanResult *pBssDesc = NULL; + tDot11fBeaconIEs *pIes = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + smsLog(pMac, LOG1, FL("Ini file contains neighbor scan channel list, " + "hence NO need to build occupied channel list (numChannels = %d)"), + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + return; + } + + if (!csrNeighborRoamIsNewConnectedProfile(pMac, sessionId)) + { + smsLog(pMac, LOG2, FL("donot flush occupied list since current roam " + "profile matches previous (numChannels = %d)"), + pMac->scan.occupiedChannels[sessionId].numChannels); + return; + } + + /* Empty occupied channels here */ + pMac->scan.occupiedChannels[sessionId].numChannels = 0; + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + + //At this time, pBssDescription->Result.pvIes may be NULL + if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pBssDesc->Result.BssDescriptor, &pIes))) ) + { + continue; + } + + csrScanAddToOccupiedChannels(pMac, pBssDesc, sessionId, + &pMac->scan.occupiedChannels[sessionId], + pIes); + + /* + * Free the memory allocated for pIes in csrGetParsedBssDescriptionIEs + */ + if( (pBssDesc->Result.pvIes == NULL) && pIes ) + { + vos_mem_free(pIes); + } + + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pMac->scan.scanResultList); +} +#endif + +eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrBssid bssid, tANI_U8 channel) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tDot11fBeaconIEs *pNewIes = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tSirBssDescription *pNewBssDescriptor = NULL; + tANI_U32 size = 0; + + if(NULL == pSession) + { + status = eHAL_STATUS_FAILURE; + return status; + } + smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: Current bssid::" + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId)); + smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: My bssid::" + MAC_ADDRESS_STR" channel %d"), + MAC_ADDR_ARRAY(bssid), channel); + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pSession->pConnectBssDesc, &pNewIes))) + { + smsLog(pMac, LOGE, FL("%s: Failed to parse IEs"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length); + if (size) + { + pNewBssDescriptor = vos_mem_malloc(size); + if ( NULL == pNewBssDescriptor ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size); + } + else + { + smsLog(pMac, LOGE, FL("%s: memory allocation failed"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + //change the BSSID & channel as passed + vos_mem_copy(pNewBssDescriptor->bssId, bssid, sizeof(tSirMacAddr)); + pNewBssDescriptor->channelId = channel; + if (NULL == csrScanAppendBssDescription(pMac, pNewBssDescriptor, + pNewIes, TRUE, sessionId)) { + smsLog(pMac, LOGE, FL("csrScanAppendBssDescription failed")); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, FL("%s: length of bss descriptor is 0"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + smsLog(pMac, LOGE, FL("%s: entry successfully added in scan cache"), + __func__); + }while(0); + + if(pNewIes) + { + vos_mem_free(pNewIes); + } + if(pNewBssDescriptor) + { + vos_mem_free(pNewBssDescriptor); + } + return status; +} + +#ifdef FEATURE_WLAN_ESE +// Update the TSF with the difference in system time +void UpdateCCKMTSF(tANI_U32 *timeStamp0, tANI_U32 *timeStamp1, tANI_U32 *incr) +{ + tANI_U64 timeStamp64 = ((tANI_U64)*timeStamp1 << 32) | (*timeStamp0); + timeStamp64 = (tANI_U64)(timeStamp64 + (tANI_U64)*incr); + *timeStamp0 = (tANI_U32)(timeStamp64 & 0xffffffff); + *timeStamp1 = (tANI_U32)((timeStamp64 >> 32) & 0xffffffff); +} +#endif + +/** + * csrScanSaveRoamOffloadApToScanCache + * This function parses the received beacon/probe response + * from the firmware as part of the roam synch indication. + * The beacon or the probe response is parsed and is also + * saved into the scan cache + * + * @param pMac Pointer to Global Mac + * @param pRoamOffloadSynchInd Roam Synch Indication from + * firmware which also contains the beacon/probe + * response + * @return Status + */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +eHalStatus csrScanSaveRoamOffloadApToScanCache(tpAniSirGlobal pMac, + tSirRoamOffloadSynchInd *pRoamOffloadSynchInd) +{ + v_U32_t uLen = 0; + tANI_BOOLEAN fDupBss; + tDot11fBeaconIEs *pIesLocal = NULL; + tAniSSID tmpSsid; + v_TIME_t timer=0; + tCsrScanResult *pScanResult = NULL; + tANI_U8 sessionId = pRoamOffloadSynchInd->roamedVdevId; + + uLen = pRoamOffloadSynchInd->beaconProbeRespLength - + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET); + pScanResult = vos_mem_malloc(sizeof(tCsrScanResult) + uLen); + if ( pScanResult == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " fail to allocate memory for frame"); + return eHAL_STATUS_RESOURCES; + } + + vos_mem_zero(pScanResult, sizeof(tCsrScanResult) + uLen ); + vos_mem_copy(&pScanResult->Result.BssDescriptor, + pRoamOffloadSynchInd->pbssDescription, + (sizeof(tSirBssDescription) + uLen)); + pIesLocal = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + if ( !pIesLocal && + (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pScanResult->Result.BssDescriptor, &pIesLocal))) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Cannot Parse IEs", __func__); + csrFreeScanResultEntry(pMac, pScanResult); + return eHAL_STATUS_RESOURCES; + } + + fDupBss = csrRemoveDupBssDescription(pMac, + &pScanResult->Result.BssDescriptor, + pIesLocal, &tmpSsid, &timer, TRUE); + if ( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:BSS Limit Exceed", __func__); + if( (pScanResult->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + csrFreeScanResultEntry(pMac, pScanResult); + return eHAL_STATUS_RESOURCES; + } + csrScanAddResult(pMac, pScanResult, pIesLocal, sessionId); + return eHAL_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrCmdProcess.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrCmdProcess.c new file mode 100644 index 0000000000000..dd3b97fe01264 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrCmdProcess.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrCmdProcess.c + + Implementation for processing various commands. +========================================================================== */ + + + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" +#include "macTrace.h" + + + +eHalStatus csrMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeRsp *pSmeRsp = (tSirSmeRsp *)pMsgBuf; +#ifdef FEATURE_WLAN_SCAN_PNO + tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf; + tCsrRoamSession *pSession; +#endif + + smsLog(pMac, LOG2, FL("Message %d[0x%04X] received in curState %s" + " and substate %s sessionId (%d)"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamState(pMac->roam.curState[pSmeRsp->sessionId]), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId]), pSmeRsp->sessionId); + +#ifdef FEATURE_WLAN_SCAN_PNO + /* + * PNO scan responses have to be handled irrespective of CSR roam state. + * Check if PNO has been started and only then process the PNO scan results. + * Also note that normal scan is not allowed when PNO scan is in progress + * and so the scan responses reaching here when PNO is started must be + * PNO responses. For normal scan, the PNO started flag will be FALSE and + * it will be processed as usual based on the current CSR roam state. + */ + pSession = CSR_GET_SESSION(pMac, pSmeRsp->sessionId); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found, msgType : %d"), pSmeRsp->sessionId, + pMsg->type); + return eHAL_STATUS_FAILURE; + } + + if((eWNI_SME_SCAN_RSP == pMsg->type) && (TRUE == pSession->pnoStarted)) + { + status = csrScanningStateMsgProcessor(pMac, pMsgBuf); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL(" handling PNO scan resp msg 0x%X CSR state is %d"), + pSmeRsp->messageType, pMac->roam.curState[pSmeRsp->sessionId]); + } + return (status); + } +#endif + + // Process the message based on the state of the roaming states... + +#if defined( ANI_RTT_DEBUG ) + if(!pAdapter->fRttModeEnabled) + { +#endif//RTT + switch (pMac->roam.curState[pSmeRsp->sessionId]) + { + case eCSR_ROAMING_STATE_SCANNING: + { + //Are we in scan state +#if defined( ANI_EMUL_ASSOC ) + emulScanningStateMsgProcessor( pAdapter, pMBBufHdr ); +#else + status = csrScanningStateMsgProcessor(pMac, pMsgBuf); +#endif + break; + } + + case eCSR_ROAMING_STATE_JOINED: + { + //are we in joined state + csrRoamJoinedStateMsgProcessor( pMac, pMsgBuf ); + break; + } + + case eCSR_ROAMING_STATE_JOINING: + { + //are we in roaming states +#if defined( ANI_EMUL_ASSOC ) + emulRoamingStateMsgProcessor( pAdapter, pMBBufHdr ); +#endif + csrRoamingStateMsgProcessor( pMac, pMsgBuf ); + break; + } + + //For all other messages, we ignore it + default: + { + /*To work-around an issue where checking for set/remove key base on connection state is no longer + * workable due to failure or finding the condition meets both SAP and infra/IBSS requirement. + */ + if( (eWNI_SME_SETCONTEXT_RSP == pSmeRsp->messageType) || + (eWNI_SME_REMOVEKEY_RSP == pSmeRsp->messageType) ) + { + smsLog(pMac, LOGW, FL(" handling msg 0x%X CSR state is %d"), pSmeRsp->messageType, pMac->roam.curState[pSmeRsp->sessionId]); + csrRoamCheckForLinkStatusChange(pMac, pSmeRsp); + } + else if(eWNI_SME_GET_RSSI_REQ == pSmeRsp->messageType) + { + tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)pMsgBuf; + if(NULL != pGetRssiReq->rssiCallback) + { + smsLog(pMac, + LOGW, + FL("Message eWNI_SME_GET_RSSI_REQ is not handled" + " by CSR in state %d. calling RSSI callback"), + pMac->roam.curState[pSmeRsp->sessionId]); + ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(pGetRssiReq->lastRSSI, + pGetRssiReq->staId, + pGetRssiReq->pDevContext); + } + else + { + smsLog(pMac, LOGE, FL("pGetRssiReq->rssiCallback is NULL")); + } + } + else + { + smsLog(pMac, LOGE, "Message 0x%04X is not handled by CSR " + " CSR state is %d session Id %d", pSmeRsp->messageType, + pMac->roam.curState[pSmeRsp->sessionId], pSmeRsp->sessionId); + + if (eWNI_SME_FT_PRE_AUTH_RSP == pSmeRsp->messageType) { + smsLog(pMac, LOGE, "Dequeue eSmeCommandRoam command" + " with reason eCsrPerformPreauth"); + csrDequeueRoamCommand(pMac, eCsrPerformPreauth); + } + else if (eWNI_SME_REASSOC_RSP == pSmeRsp->messageType) { + smsLog(pMac, LOGE, "Dequeue eSmeCommandRoam command" + " with reason eCsrSmeIssuedFTReassoc"); + csrDequeueRoamCommand(pMac, eCsrSmeIssuedFTReassoc); + } + } + break; + } + + }//switch + +#if defined( ANI_RTT_DEBUG ) + } +#endif//RTT + + return (status); +} + + + +tANI_BOOLEAN csrCheckPSReady(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + + if (pMac->roam.sPendingCommands < 0) + { + VOS_ASSERT( pMac->roam.sPendingCommands >= 0 ); + return 0; + } + return (pMac->roam.sPendingCommands == 0); +} + +tANI_BOOLEAN csrCheckPSOffloadReady(void *pv, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(pv); + + VOS_ASSERT(pMac->roam.sPendingCommands >= 0); + return (pMac->roam.sPendingCommands == 0); +} + +void csrFullPowerCallback(void *pv, eHalStatus status) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry; + tSmeCmd *pCommand; + + (void)status; + + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_TRUE ) ) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smePushCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + +} + +void csrFullPowerOffloadCallback(void *pv, tANI_U32 sessionId, eHalStatus status) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry; + tSmeCmd *pCommand; + + (void)status; + + while(NULL != (pEntry = csrLLRemoveHead(&pMac->roam.roamCmdPendingList, + eANI_BOOLEAN_TRUE))) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + smePushCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + } + +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrInsideApi.h b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrInsideApi.h new file mode 100644 index 0000000000000..911209818b8e0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrInsideApi.h @@ -0,0 +1,1060 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrInsideApi.h + + Define interface only used by CSR. +========================================================================== */ +#ifndef CSR_INSIDE_API_H__ +#define CSR_INSIDE_API_H__ + + +#include "csrSupport.h" +#include "smeInside.h" +#include "vos_nvitem.h" + +#define CSR_PASSIVE_MAX_CHANNEL_TIME 110 +#define CSR_PASSIVE_MIN_CHANNEL_TIME 60 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME 40 +#define CSR_ACTIVE_MIN_CHANNEL_TIME 20 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME_BTC 120 +#define CSR_ACTIVE_MIN_CHANNEL_TIME_BTC 60 + +#ifdef WLAN_AP_STA_CONCURRENCY +#define CSR_PASSIVE_MAX_CHANNEL_TIME_CONC 110 +#define CSR_PASSIVE_MIN_CHANNEL_TIME_CONC 60 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME_CONC 27 +#define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC 20 + +#define CSR_REST_TIME_CONC 100 + +#define CSR_NUM_STA_CHAN_COMBINED_CONC 3 +#define CSR_NUM_P2P_CHAN_COMBINED_CONC 1 +#endif + +#define CSR_MAX_NUM_SUPPORTED_CHANNELS 55 + +#define CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS 14 + +#define CSR_MAX_BSS_SUPPORT 250 +#define SYSTEM_TIME_MSEC_TO_USEC 1000 + +//This number minus 1 means the number of times a channel is scanned before a BSS is remvoed from +//cache scan result +#define CSR_AGING_COUNT 3 +//The following defines are used by palTimer +//This is used for palTimer when request to imps fails +#define CSR_IDLE_SCAN_WAIT_TIME (1 * VOS_TIMER_TO_SEC_UNIT) //1 second +//This is used for palTimer when imps ps is disabled +//This number shall not be smaller than 5-6 seconds in general because a full scan may take 3-4 seconds +#define CSR_IDLE_SCAN_NO_PS_INTERVAL (10 * VOS_TIMER_TO_SEC_UNIT) //10 second +#define CSR_IDLE_SCAN_NO_PS_INTERVAL_MIN (5 * VOS_TIMER_TO_SEC_UNIT) +#define CSR_SCAN_GET_RESULT_INTERVAL (5 * VOS_TIMER_TO_SEC_UNIT) //5 seconds +#define CSR_MIC_ERROR_TIMEOUT (60 * VOS_TIMER_TO_SEC_UNIT) //60 seconds +#define CSR_TKIP_COUNTER_MEASURE_TIMEOUT (60 * VOS_TIMER_TO_SEC_UNIT) //60 seconds +#define CSR_SCAN_RESULT_AGING_INTERVAL (5 * VOS_TIMER_TO_SEC_UNIT) //5 seconds +#define CSR_SCAN_RESULT_CFG_AGING_INTERVAL (VOS_TIMER_TO_SEC_UNIT) // 1 second +//the following defines are NOT used by palTimer +#define CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS 50 //50 seconds +#define CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS 300 //300 seconds +#define CSR_SCAN_AGING_TIME_CONNECT_NO_PS 150 //150 seconds +#define CSR_SCAN_AGING_TIME_CONNECT_W_PS 600 //600 seconds +#define CSR_JOIN_FAILURE_TIMEOUT_DEFAULT ( 3000 ) +#define CSR_JOIN_FAILURE_TIMEOUT_MIN (1000) //minimal value +//These are going against the signed RSSI (tANI_S8) so it is between -+127 +#define CSR_BEST_RSSI_VALUE (-30) //RSSI >= this is in CAT4 +#define CSR_DEFAULT_RSSI_DB_GAP 30 //every 30 dbm for one category +#define CSR_BSS_CAP_VALUE_NONE 0 //not much value +#define CSR_BSS_CAP_VALUE_HT 2 +#define CSR_BSS_CAP_VALUE_WMM 1 +#define CSR_BSS_CAP_VALUE_UAPSD 1 +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CSR_BSS_CAP_VALUE_5GHZ 1 +#endif +#define CSR_DEFAULT_ROAMING_TIME 10 //10 seconds +#define CSR_ROAM_MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#define CSR_ROAM_MAX(X, Y) ((X) > (Y) ? (X) : (Y)) + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +#define CSR_JOIN_MAX_RETRY_COUNT 10 +#define CSR_JOIN_RETRY_TIMEOUT_PERIOD ( 1 * VOS_TIMER_TO_SEC_UNIT ) // 1 second +#endif + +#define CSR_ROAMING_DFS_CHANNEL_DISABLED (0) +#define CSR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL (1) +#define CSR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE (2) + +/* The MAX BSSID Count should be lower than the command timeout + * value and it can be of a fraction of 3/4 of the total command + * timeout value */ +#define CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE 1000*30*4 //120s +#define CSR_MAX_BSSID_COUNT ((CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE/4000) * 3) +typedef enum +{ + eCsrNextScanNothing, + eCsrNextLostLinkScan1Success, + eCsrNextLostLinkScan1Failed, + eCsrNextLostLinkScan2Success, + eCsrNextLostLinkScan2Failed, + eCsrNextLostLinkScan3Success, + eCsrNexteScanForSsidSuccess, + eCsrNextLostLinkScan3Failed, + eCsrNext11dScan1Failure, + eCsrNext11dScan1Success, + eCsrNext11dScan2Failure, + eCsrNext11dScan2Success, + eCsrNext11dScanComplete, + eCsrNexteScanForSsidFailure, + eCsrNextIdleScanComplete, + eCsrNextCapChangeScanComplete, + +}eCsrScanCompleteNextCommand; + +typedef enum +{ + eCsrJoinSuccess, + eCsrJoinFailure, + eCsrReassocSuccess, + eCsrReassocFailure, + eCsrNothingToJoin, + eCsrStartBssSuccess, + eCsrStartBssFailure, + eCsrSilentlyStopRoaming, + eCsrSilentlyStopRoamingSaveState, + eCsrJoinWdsFailure, + eCsrJoinFailureDueToConcurrency, + +}eCsrRoamCompleteResult; + +typedef struct tagScanReqParam +{ + tANI_U8 bReturnAfter1stMatch; + tANI_U8 fUniqueResult; + tANI_U8 freshScan; + tANI_U8 hiddenSsid; + tANI_U8 reserved; +}tScanReqParam; + +typedef struct tagCsrScanResult +{ + tListElem Link; + tANI_S32 AgingCount; //This BSS is removed when it reaches 0 or less + tANI_U32 preferValue; //The bigger the number, the better the BSS. This value override capValue + tANI_U32 capValue; //The biggger the better. This value is in use only if we have equal preferValue + //This member must be the last in the structure because the end of tSirBssDescription (inside) is an + // array with nonknown size at this time + + eCsrEncryptionType ucEncryptionType; //Preferred Encryption type that matched with profile. + eCsrEncryptionType mcEncryptionType; + eCsrAuthType authType; //Preferred auth type that matched with the profile. + + tCsrScanResultInfo Result; +}tCsrScanResult; + +typedef struct +{ + tDblLinkList List; + tListElem *pCurEntry; +}tScanResultList; + + + + +#define CSR_IS_ROAM_REASON( pCmd, reason ) ( (reason) == (pCmd)->roamCmd.roamReason ) +#define CSR_IS_BETTER_PREFER_VALUE(v1, v2) ((v1) > (v2)) +#define CSR_IS_EQUAL_PREFER_VALUE(v1, v2) ((v1) == (v2)) +#define CSR_IS_BETTER_CAP_VALUE(v1, v2) ((v1) > (v2)) +#define CSR_IS_ENC_TYPE_STATIC( encType ) ( ( eCSR_ENCRYPT_TYPE_NONE == (encType) ) || \ + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == (encType) ) || \ + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == (encType) ) ) +#define CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ( CSR_IS_ROAM_JOINED( pMac, sessionId ) && CSR_IS_ROAM_SUBSTATE_WAITFORKEY( pMac, sessionId ) ) +//WIFI has a test case for not using HT rates with TKIP as encryption +//We may need to add WEP but for now, TKIP only. + +#define CSR_IS_11n_ALLOWED( encType ) (( eCSR_ENCRYPT_TYPE_TKIP != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP40 != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP104 != (encType) ) ) + +#define CSR_IS_DISCONNECT_COMMAND(pCommand) ( ( eSmeCommandRoam == (pCommand)->command ) &&\ + ( ( eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason ) ||\ + ( eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason ) ||\ + ( eCsrSmeIssuedDisassocForHandoff ==\ + (pCommand)->u.roamCmd.roamReason ) ||\ + ( eCsrForcedDisassocMICFailure ==\ + (pCommand)->u.roamCmd.roamReason ) ) ) + +eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId); +eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ); +void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand); + +tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2, tANI_BOOLEAN fForced ); +eHalStatus csrRoamSaveConnectedBssDesc( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDesc ); +tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ); +eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf ); +/* + Prepare a filter base on a profile for parsing the scan results. + Upon successful return, caller MUST call csrFreeScanFilter on + pScanFilter when it is done with the filter. +*/ +eHalStatus csrRoamPrepareFilterFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tCsrScanResultFilter *pScanFilter); +eHalStatus csrRoamCopyProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pDstProfile, tCsrRoamProfile *pSrcProfile); +eHalStatus csrRoamStart(tpAniSirGlobal pMac); +void csrRoamStop(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRoamStartMICFailureTimer(tpAniSirGlobal pMac); +void csrRoamStopMICFailureTimer(tpAniSirGlobal pMac); +void csrRoamStartTKIPCounterMeasureTimer(tpAniSirGlobal pMac); +void csrRoamStopTKIPCounterMeasureTimer(tpAniSirGlobal pMac); + +eHalStatus csrScanOpen(tpAniSirGlobal pMac); +eHalStatus csrScanClose(tpAniSirGlobal pMac); +eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId); +tCsrScanResult *csrScanAppendBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescription, + tDot11fBeaconIEs *pIes, + tANI_BOOLEAN fForced, + tANI_U8 sessionId); +void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus); +eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq); +eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq); +eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult); +void csrInitBGScanChannelList(tpAniSirGlobal pMac); +eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify); +eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps); +eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStartResultAgingTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStopResultAgingTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStartResultCfgAgingTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStopResultCfgAgingTimer(tpAniSirGlobal pMac); +eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac); +eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval); +eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac); +//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for +//idle scan timer interval +//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan +eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval); +void csrScanCancelIdleScan(tpAniSirGlobal pMac); +void csrScanStopTimers(tpAniSirGlobal pMac); +//This function will remove scan commands that are not related to association or IBSS +tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac); +//To remove fresh scan commands from the pending queue +tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId); +eHalStatus csrScanAbortMacScan(tpAniSirGlobal pMac, tANI_U8 sessionId, + eCsrAbortReason reason); +void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, + eSmeCommandType commandType ); +void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tDblLinkList *pList, + eSmeCommandType commandType); +eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId); +eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId); +eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId); + +//To age out scan results base. tSmeGetScanChnRsp is a pointer returned by LIM that +//has the information regarding scanned channels. +//The logic is that whenever CSR add a BSS to scan result, it set the age count to +//a value. This function deduct the age count if channelId matches the BSS' channelId +//The BSS is remove if the count reaches 0. +eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo); + +//If fForce is TRUE we will save the new String that is learn't. +//Typically it will be true in case of Join or user initiated ioctl +tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce ); +void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce ); +void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList ); +void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult ); + +eHalStatus csrRoamCallCallback(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus u1, eCsrRoamResult u2); +eHalStatus csrRoamIssueConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBSSList, + eCsrRoamReason reason, tANI_U32 roamId, + tANI_BOOLEAN fImediate, tANI_BOOLEAN fClearScan); +eHalStatus csrRoamIssueReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields *pModProfileFields, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate); +void csrRoamComplete( tpAniSirGlobal pMac, eCsrRoamCompleteResult Result, void *Context ); +eHalStatus csrRoamIssueSetContextReq( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrEncryptionType EncryptType, + tSirBssDescription *pBssDescription, + tSirMacAddr *bssId, tANI_BOOLEAN addKey, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U16 keyLength, + tANI_U8 *pKey, tANI_U8 paeRole ); +eHalStatus csrRoamProcessDisassocDeauth( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tANI_BOOLEAN fDisassoc, tANI_BOOLEAN fMICFailure ); +eHalStatus csrRoamSaveConnectedInfomation(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes); +void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg ); +void csrRoamStatsRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg); +eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamStartBssParams *pParam, + tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc, tANI_U32 roamId ); +eHalStatus csrRoamIssueStopBss( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ); +tANI_BOOLEAN csrIsSameProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile1, tCsrRoamProfile *pProfile2); +tANI_BOOLEAN csrIsRoamCommandWaiting(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsRoamCommandWaitingForSession(tpAniSirGlobal pMac, tANI_U32 sessionId); +tANI_BOOLEAN csrIsScanForRoamCommandActive( tpAniSirGlobal pMac ); +eRoamCmdStatus csrGetRoamCompleteStatus(tpAniSirGlobal pMac, tANI_U32 sessionId); +//pBand can be NULL if caller doesn't need to get it +//eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, eCsrPhyMode phyModeIn, tANI_U8 operationChn, eCsrBand *pBand ); +eHalStatus csrRoamIssueDisassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason ); +eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason); +//pCommand may be NULL +void csrRoamRemoveDuplicateCommand(tpAniSirGlobal pMac, tANI_U32 sessionId, tSmeCmd *pCommand, eCsrRoamReason eRoamReason); + +eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, + tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType ); +eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ); +eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ); +eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd ); +eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd ); +eHalStatus csrSendAssocCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus status ); +eHalStatus csrSendAssocIndToUpperLayerCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus Halstatus, tANI_U8 sessionId ); +eHalStatus csrSendMBStartBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamBssType bssType, + tCsrRoamStartBssParams *pParam, tSirBssDescription *pBssDesc ); +eHalStatus csrSendMBStopBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId ); + +tANI_BOOLEAN csrIsMacAddressEqual( tpAniSirGlobal pMac, tCsrBssid *pMacAddr1, tCsrBssid *pMacAddr2 ); +//Caller should put the BSS' ssid to fiedl bssSsid when comparing SSID for a BSS. +tANI_BOOLEAN csrIsSsidMatch( tpAniSirGlobal pMac, tANI_U8 *ssid1, tANI_U8 ssid1Len, tANI_U8 *bssSsid, + tANI_U8 bssSsidLen, tANI_BOOLEAN fSsidRequired ); +tANI_BOOLEAN csrIsPhyModeMatch( tpAniSirGlobal pMac, tANI_U32 phyMode, + tSirBssDescription *pSirBssDesc, tCsrRoamProfile *pProfile, + eCsrCfgDot11Mode *pReturnCfgDot11Mode, + tDot11fBeaconIEs *pIes); +tANI_BOOLEAN csrRoamIsChannelValid( tpAniSirGlobal pMac, tANI_U8 channel ); + +//pNumChan is a caller allocated space with the sizeof pChannels +eHalStatus csrGetCfgValidChannels(tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U32 *pNumChan); +void csrRoamCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result); +void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result); + +tPowerdBm csrGetCfgMaxTxPower (tpAniSirGlobal pMac, tANI_U8 channel); + +//To free the last roaming profile +void csrFreeRoamProfile(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrFreeConnectBssDesc(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult); +tANI_BOOLEAN csrCheckPSReady(void *pv); +tANI_BOOLEAN csrCheckPSOffloadReady(void *pv, tANI_U32 sessionId); +void csrFullPowerCallback(void *pv, eHalStatus status); +void csrFullPowerOffloadCallback(void *pv, tANI_U32 sessionId, + eHalStatus status); + +//to free memory allocated inside the profile structure +void csrReleaseProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile); +//To free memory allocated inside scanFilter +void csrFreeScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter); +eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tANI_BOOLEAN fProprietary); +tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode); +void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand ); +void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva); +void csrApplyPower2Current( tpAniSirGlobal pMac ); +void csrAssignRssiForCategory(tpAniSirGlobal pMac, tANI_S8 bestApRssi, tANI_U8 catOffset); +tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ); +tANI_BOOLEAN csrIsMacAddressBroadcast( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ); +eHalStatus csrRoamRemoveConnectedBssFromScanCache(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile); +eHalStatus csrRoamStartRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamingReason roamingReason); +//return a boolean to indicate whether roaming completed or continue. +tANI_BOOLEAN csrRoamCompleteRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fForce, eCsrRoamResult roamResult); +void csrRoamCompletion(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand, eCsrRoamResult roamResult, tANI_BOOLEAN fSuccess); +void csrRoamCancelRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva ); +void csrResetPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ); +#ifdef FEATURE_WLAN_WAPI +void csrResetBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ); +#endif /* FEATURE_WLAN_WAPI */ +eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable ); +//Get the list of the base channels to scan for passively 11d info +eHalStatus csrScanGetSupportedChannels( tpAniSirGlobal pMac ); +//To check whether a country code matches the one in the IE +//Only check the first two characters, ignoring in/outdoor +//pCountry -- caller allocated buffer contain the country code that is checking against +//the one in pIes. It can be NULL. +//caller must provide pIes, it cannot be NULL +//This function always return TRUE if 11d support is not turned on. +//pIes cannot be NULL +tANI_BOOLEAN csrMatchCountryCode( tpAniSirGlobal pMac, tANI_U8 *pCountry, tDot11fBeaconIEs *pIes ); +eHalStatus csrRoamSetKey( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, + csrRoamCompleteCallback callback, + void *pContext, + tANI_U8 *pSelfMacAddr, tANI_U8 *pbSessionId, + tANI_U32 type, tANI_U32 subType ); +//fSync: TRUE means cleanupneeds to handle synchronously. +eHalStatus csrRoamCloseSession( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fSync, + csrRoamSessionCloseCallback callback, + void *pContext ); +void csrCleanupSession(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrRoamGetSessionIdFromBSSID( tpAniSirGlobal pMac, tCsrBssid *bssid, tANI_U32 *pSessionId ); +eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode ); + +/* --------------------------------------------------------------------------- + \fn csrScanEnable + \brief Enable the scanning feature of CSR. It must be called before any scan request can be performed. + \param tHalHandle - HAL context handle + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanEnable(tpAniSirGlobal); + +/* --------------------------------------------------------------------------- + \fn csrScanDisable + \brief Disableing the scanning feature of CSR. After this function return success, no scan is performed until +a successfull to csrScanEnable + \param tHalHandle - HAL context handle + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanDisable(tpAniSirGlobal); +/* --------------------------------------------------------------------------- + \fn csrScanRequest + \brief Request a 11d or full scan. + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanRequest(tpAniSirGlobal, tANI_U16, tCsrScanRequest *, + tANI_U32 *pScanRequestID, csrScanCompleteCallback callback, + void *pContext); + +/* --------------------------------------------------------------------------- + \fn csrScanAbort + \brief If a scan request is abort, the scan complete callback will be called first before csrScanAbort returns. + \param pScanRequestID - The request ID returned from csrScanRequest + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanAbort(tpAniSirGlobal, tANI_U32 scanRequestID); + +eHalStatus csrScanSetBGScanparams(tpAniSirGlobal, tCsrBGScanRequest *); +eHalStatus csrScanBGScanAbort(tpAniSirGlobal); + +/* --------------------------------------------------------------------------- + \fn csrScanGetResult + \brief Return scan results. + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanGetResult(tpAniSirGlobal, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult); + +/* --------------------------------------------------------------------------- + \fn csrScanFlushResult + \brief Clear scan results. + \param pMac - pMac global pointer + \param sessionId - Session Identifier + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanFlushResult(tpAniSirGlobal, tANI_U8 sessionId); +/* --------------------------------------------------------------------------- + * \fn csrScanFilterResults + * \brief Filter scan results based on valid channel list. + * \param pMac - Pointer to Global MAC structure + * \return eHalStatus + *------------------------------------------------------------------------------- + */ +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac); + +eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal, v_BOOL_t flushP2P); +/* --------------------------------------------------------------------------- + \fn csrScanBGScanGetParam + \brief Returns the current background scan settings. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanBGScanGetParam(tpAniSirGlobal, tCsrBGScanRequest *); + +/* --------------------------------------------------------------------------- + \fn csrScanResultGetFirst + \brief Returns the first element of scan result. + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + -------------------------------------------------------------------------------*/ +tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal, tScanResultHandle hScanResult); +/* --------------------------------------------------------------------------- + \fn csrScanResultGetNext + \brief Returns the next element of scan result. It can be called without calling csrScanResultGetFirst first + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + -------------------------------------------------------------------------------*/ +tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal, tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn csrGetCountryCode + \brief this function is to get the country code current being used + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, this has the country code + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen); + +/* --------------------------------------------------------------------------- + \fn csrSetCountryCode + \brief this function is to set the country code so channel/power setting matches the countrycode and + the domain it belongs to. + \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrGetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed bytes. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen); + +/* --------------------------------------------------------------------------- + \fn csrSetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See eRegDomainId for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetRegulatoryDomain(tpAniSirGlobal pMac, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrGetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \return eRegDomainId + -------------------------------------------------------------------------------*/ +v_REGDOMAIN_t csrGetCurrentRegulatoryDomain(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------- + \fn csrGetRegulatoryDomainForCountry + \brief this function is to get the regulatory domain for a country. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code + \param pDomainId - Caller allocated buffer to get the return domain ID upon success return. Can be NULL. + \param source - the source of country information. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetRegulatoryDomainForCountry(tpAniSirGlobal pMac, + tANI_U8 *pCountry, + v_REGDOMAIN_t *pDomainId, + v_CountryInfoSource_t source); + + +tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode, tANI_BOOLEAN fForce ); + +//some support functions +tANI_BOOLEAN csrIs11dSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIs11hSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIs11eSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsWmmSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsMCCSupported(tpAniSirGlobal pMac); + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus csrScanGetBaseChannels( tpAniSirGlobal pMac, tCsrChannelInfo * pChannelInfo ); +//Return SUCCESS is the command is queued, failed +eHalStatus csrQueueSmeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fHighPriority ); +tSmeCmd *csrGetCommandBuffer( tpAniSirGlobal pMac ); +void csrReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrScanFlushBssEntry(tpAniSirGlobal pMac, + tpSmeCsaOffloadInd pCsaOffloadInd); +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ); +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + +//Security +#define WLAN_SECURITY_EVENT_SET_PTK_REQ 1 +#define WLAN_SECURITY_EVENT_SET_PTK_RSP 2 +#define WLAN_SECURITY_EVENT_SET_GTK_REQ 3 +#define WLAN_SECURITY_EVENT_SET_GTK_RSP 4 +#define WLAN_SECURITY_EVENT_REMOVE_KEY_REQ 5 +#define WLAN_SECURITY_EVENT_REMOVE_KEY_RSP 6 +#define WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND 7 +#define WLAN_SECURITY_EVENT_PMKID_UPDATE 8 +#define WLAN_SECURITY_EVENT_MIC_ERROR 9 + +#define AUTH_OPEN 0 +#define AUTH_SHARED 1 +#define AUTH_WPA_EAP 2 +#define AUTH_WPA_PSK 3 +#define AUTH_WPA2_EAP 4 +#define AUTH_WPA2_PSK 5 +#ifdef FEATURE_WLAN_WAPI +#define AUTH_WAPI_CERT 6 +#define AUTH_WAPI_PSK 7 +#endif /* FEATURE_WLAN_WAPI */ + +#define ENC_MODE_OPEN 0 +#define ENC_MODE_WEP40 1 +#define ENC_MODE_WEP104 2 +#define ENC_MODE_TKIP 3 +#define ENC_MODE_AES 4 +#ifdef FEATURE_WLAN_WAPI +#define ENC_MODE_SMS4 5 //WAPI +#endif /* FEATURE_WLAN_WAPI */ + +#define NO_MATCH 0 +#define MATCH 1 + +#define WLAN_SECURITY_STATUS_SUCCESS 0 +#define WLAN_SECURITY_STATUS_FAILURE 1 + +//Scan +#define WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ 1 +#define WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP 2 +#define WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ 3 +#define WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP 4 +#define WLAN_SCAN_EVENT_HO_SCAN_REQ 5 +#define WLAN_SCAN_EVENT_HO_SCAN_RSP 6 + +#define WLAN_SCAN_STATUS_SUCCESS 0 +#define WLAN_SCAN_STATUS_FAILURE 1 +#define WLAN_SCAN_STATUS_ABORT 2 + +//Ibss +#define WLAN_IBSS_EVENT_START_IBSS_REQ 0 +#define WLAN_IBSS_EVENT_START_IBSS_RSP 1 +#define WLAN_IBSS_EVENT_JOIN_IBSS_REQ 2 +#define WLAN_IBSS_EVENT_JOIN_IBSS_RSP 3 +#define WLAN_IBSS_EVENT_COALESCING 4 +#define WLAN_IBSS_EVENT_PEER_JOIN 5 +#define WLAN_IBSS_EVENT_PEER_LEAVE 6 +#define WLAN_IBSS_EVENT_STOP_REQ 7 +#define WLAN_IBSS_EVENT_STOP_RSP 8 + +#define AUTO_PICK 0 +#define SPECIFIED 1 + +#define WLAN_IBSS_STATUS_SUCCESS 0 +#define WLAN_IBSS_STATUS_FAILURE 1 + +//11d +#define WLAN_80211D_EVENT_COUNTRY_SET 0 +#define WLAN_80211D_EVENT_RESET 1 + +#define WLAN_80211D_DISABLED 0 +#define WLAN_80211D_SUPPORT_MULTI_DOMAIN 1 +#define WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN 2 + +int diagAuthTypeFromCSRType(eCsrAuthType authType); +int diagEncTypeFromCSRType(eCsrEncryptionType encType); +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +/* --------------------------------------------------------------------------- + \fn csrScanResultPurge + \brief remove all items(tCsrScanResult) in the list and free memory for each item + \param hScanResult - returned from csrScanGetResult. hScanResult is considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanResult); + + +///////////////////////////////////////////Common Scan ends + +/* --------------------------------------------------------------------------- + \fn csrRoamConnect + \brief To inititiate an association + \param pProfile - can be NULL to join to any open ones + \param hBssListIn - a list of BSS descriptor to roam to. It is returned from csrScanGetResult + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + \fn csrRoamReassoc + \brief To inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId); + + +/* --------------------------------------------------------------------------- + \fn csrRoamReconnect + \brief To disconnect and reconnect with the same profile + \return eHalStatus. It returns fail if currently not connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamReconnect(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamSetPMKIDCache + \brief return the PMKID candidate list + \param pPMKIDCache - caller allocated buffer point to an array of tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo allocated + when retruning, this is either the number needed or number of items put into pPMKIDCache + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough and pNumItems + has the number of tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, not sizeof(tPmkidCacheInfo) * something + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamSetPMKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ); + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/* --------------------------------------------------------------------------- + *\fn csrRoamSetPSK_PMK + *\brief store PSK/PMK + *\param pMac - pointer to global structure for MAC + *\param sessionId - Sme session id + *\param pPSK_PMK - pointer to an array of Psk/Pmk + *\return eHalStatus - usually it succeed unless sessionId is not found + *\Note: + *-------------------------------------------------------------------------------*/ +eHalStatus csrRoamSetPSK_PMK(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 *pPSK_PMK, size_t pmk_len); + +/* --------------------------------------------------------------------------- + *\fn csrRoamSetKeyMgmtOffload + *\brief sets nRoamKeyMgmtOffloadEnabled + *\param pMac - pointer to global structure for MAC + *\param sessionId - Sme session id + *\param nRoamKeyMgmtOffloadEnabled - value of key mgmt offload enable + *\return eHalStatus - usually it succeed unless sessionId is not found + *\Note: + *-------------------------------------------------------------------------------*/ +eHalStatus csrRoamSetKeyMgmtOffload(tpAniSirGlobal pMac, + tANI_U32 sessionId, + v_BOOL_t nRoamKeyMgmtOffloadEnabled); +#endif +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpaRsnReqIE + \brief return the WPA or RSN IE CSR passes to PE to JOIN request or START_BSS request + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpaRsnReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpaRsnRspIE + \brief return the WPA or RSN IE from the beacon or probe rsp if connected + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpaRsnRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + + +/* --------------------------------------------------------------------------- + \fn csrRoamGetNumPMKIDCache + \brief return number of PMKID cache entries + \return tANI_U32 - the number of PMKID cache entries + -------------------------------------------------------------------------------*/ +tANI_U32 csrRoamGetNumPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetPMKIDCache + \brief return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetConnectProfile + \brief To return the current connect profile. Caller must call csrRoamFreeConnectProfile + after it is done and before reuse for another csrRoamGetConnectProfile call. + \param pProfile - pointer to a caller allocated structure tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetConnectState + \brief To return the current connect state of Roaming + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetConnectState(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrConnectState *pState); + +/* --------------------------------------------------------------------------- + \fn csrRoamFreeConnectProfile + \brief To free and reinitialize the profile return previous by csrRoamGetConnectProfile. + \param pProfile - pointer to a caller allocated structure tCsrRoamConnectedProfile + \return eHalStatus. + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamFreeConnectProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn csrInitChannelList + \brief HDD calls this function to set the WNI_CFG_VALID_CHANNEL_LIST base on the band/mode settings. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrInitChannelList( tHalHandle hHal ); + +/* --------------------------------------------------------------------------- + \fn csrChangeConfigParams + \brief The CSR API exposed for HDD to provide config params to CSR during + SMEs stop -> start sequence. + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + \param + hHal - Handle to the HAL. The HAL handle is returned by the HAL after it is + opened (by calling halOpen). + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrChangeConfigParams(tpAniSirGlobal pMac, + tCsrUpdateConfigParam *pUpdateConfigParam); + +/* --------------------------------------------------------------------------- + \fn csrRoamConnectToLastProfile + \brief To disconnect and reconnect with the same profile + \return eHalStatus. It returns fail if currently connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamConnectToLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamDisconnect + \brief To disconnect from a network + \param reason -- To indicate the reason for disconnecting. Currently, only eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamDisconnect(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason); + +/* --------------------------------------------------------------------------- + \fn csrScanGetPMKIDCandidateList + \brief return the PMKID candidate list + \param pPmkidList - caller allocated buffer point to an array of tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of tPmkidCandidateInfo allocated + when retruning, this is either the number needed or number of items put into pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, not sizeof(tPmkidCandidateInfo) * something + -------------------------------------------------------------------------------*/ +eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems ); + +//This function is used to stop a BSS. It is similar of csrRoamIssueDisconnect but this function +//doesn't have any logic other than blindly trying to stop BSS +eHalStatus csrRoamIssueStopBssCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN fHighPriority ); + +void csrCallRoamingCompletionCallback(tpAniSirGlobal pMac, tCsrRoamSession *pSession, + tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, eCsrRoamResult roamResult); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDisassociateStaCmd + \brief csr function that HDD calls to disassociate a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDisassociateStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 *pPeerMacAddr, + tANI_U32 reason); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDeauthSta + \brief csr function that HDD calls to delete a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDeauthStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 *pPeerMacAddr, + tANI_U32 reason); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueTkipCounterMeasures + \brief csr function that HDD calls to start and stop tkip countermeasures + \param sessionId - session Id for Soft AP + \param bEnable - Flag to start/stop countermeasures + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueTkipCounterMeasures( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN bEnable); + +eHalStatus csrSendMBTkipCounterMeasuresReqMsg( tpAniSirGlobal pMac, tANI_U32 sessinId, tANI_BOOLEAN bEnable, tSirMacAddr bssId ); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetAssociatedStas + \brief csr function that HDD calls to get list of associated stations based on module ID + \param sessionId - session Id for Soft AP + \param modId - module ID - PE/HAL/TL + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocStasBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamGetAssociatedStas( tpAniSirGlobal pMac, tANI_U32 sessionId, VOS_MODULE_ID modId, + void *pUsrContext, void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf ); + +eHalStatus csrSendMBGetAssociatedStasReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, VOS_MODULE_ID modId, tSirMacAddr bssId, + void *pUsrContext, void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf ); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpsSessionOverlap + \brief csr function that HDD calls to get WPS PBC session overlap information + \param sessionId - session Id for Soft AP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pRemoveMac - pointer to MAC address of session to be removed + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpsSessionOverlap( tpAniSirGlobal pMac, tANI_U32 sessionId, + void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac ); + +eHalStatus csrSendMBGetWPSPBCSessions( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr bssId, void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac); + +/* --------------------------------------------------------------------------- + \fn csrSendChngMCCBeaconInterval + \brief csr function that HDD calls to send Update beacon interval + \param sessionId - session Id for Soft AP + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId); + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +eHalStatus csrRoamStartJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval); +eHalStatus csrRoamStopJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + \fn csrRoamFTPreAuthRspProcessor + \brief csr function that handles pre auth response from LIM + ---------------------------------------------------------------------------*/ +void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuthRsp ); +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void csrEseSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession); +#endif + +#if defined(FEATURE_WLAN_ESE) +void UpdateCCKMTSF(tANI_U32 *timeStamp0, tANI_U32 *timeStamp1, tANI_U32 *incr); +#endif + +eHalStatus csrGetDefaultCountryCodeFrmNv(tpAniSirGlobal pMac, tANI_U8 *pCountry); +eHalStatus csrGetCurrentCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry); + + +eHalStatus csrRoamEnqueuePreauth(tpAniSirGlobal pMac, tANI_U32 sessionId, tpSirBssDescription pBssDescription, + eCsrRoamReason reason, tANI_BOOLEAN fImmediate); +eHalStatus csrDequeueRoamCommand(tpAniSirGlobal pMac, eCsrRoamReason reason); +#ifdef FEATURE_WLAN_LFR +void csrInitOccupiedChannelsList(tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile(tpAniSirGlobal pMac, + tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tCsrScanResult *pResult, + tDot11fBeaconIEs *pIes); +#endif +eHalStatus csrSetTxPower(tpAniSirGlobal pMac, v_U8_t sessionId, v_U8_t mW); + +eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrBssid bssid, tANI_U8 channel); + +eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac); +eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U8 *pBSSId, tANI_BOOLEAN flush_cache ); + +tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac); +void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode); +void csrClearVotesForCountryInfo(tpAniSirGlobal pMac); + +#endif + +#ifdef QCA_HT_2040_COEX +eHalStatus csrSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 sessionId, + ePhyChanBondState cbMode, tANI_BOOLEAN obssEnabled); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLinkList.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLinkList.c new file mode 100644 index 0000000000000..8a81a344e4b16 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLinkList.c @@ -0,0 +1,659 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrLinkList.c + + Implementation for the Common link list interfaces. +========================================================================== */ + +#include "palApi.h" +#include "csrLinkList.h" +#include "vos_lock.h" +#include "vos_memory.h" +#include "vos_trace.h" +#include "vos_timer.h" + + +ANI_INLINE_FUNCTION void csrListInit(tListElem *pList) +{ + pList->last = pList->next = pList; +} + + +ANI_INLINE_FUNCTION void csrListRemoveEntry(tListElem *pEntry) +{ + tListElem *pLast; + tListElem *pNext; + + pLast = pEntry->last; + pNext = pEntry->next; + pLast->next = pNext; + pNext->last = pLast; +} + + +ANI_INLINE_FUNCTION tListElem * csrListRemoveHead(tListElem *pHead) +{ + tListElem *pEntry; + tListElem *pNext; + + pEntry = pHead->next; + pNext = pEntry->next; + pHead->next = pNext; + pNext->last = pHead; + + return (pEntry); +} + + + +ANI_INLINE_FUNCTION tListElem * csrListRemoveTail(tListElem *pHead) +{ + tListElem *pEntry; + tListElem *pLast; + + pEntry = pHead->last; + pLast = pEntry->last; + pHead->last = pLast; + pLast->next = pHead; + + return (pEntry); +} + + +ANI_INLINE_FUNCTION void csrListInsertTail(tListElem *pHead, tListElem *pEntry) +{ + tListElem *pLast; + + pLast = pHead->last; + pEntry->last = pLast; + pEntry->next = pHead; + pLast->next = pEntry; + pHead->last = pEntry; +} + + +ANI_INLINE_FUNCTION void csrListInsertHead(tListElem *pHead, tListElem *pEntry) +{ + tListElem *pNext; + + pNext = pHead->next; + pEntry->next = pNext; + pEntry->last = pHead; + pNext->last = pEntry; + pHead->next = pEntry; +} + + +//Insert pNewEntry before pEntry +void csrListInsertEntry(tListElem *pEntry, tListElem *pNewEntry) +{ + tListElem *pLast; + if( !pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pEntry is Null", __func__); + return; + } + + pLast = pEntry->last; + pLast->next = pNewEntry; + pEntry->last = pNewEntry; + pNewEntry->next = pEntry; + pNewEntry->last = pLast; +} + +tANI_U32 csrLLCount( tDblLinkList *pList ) +{ + tANI_U32 c = 0; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return c; + } + + if ( pList && ( LIST_FLAG_OPEN == pList->Flag ) ) + { + c = pList->Count; + } + + return( c ); +} + + +void csrLLLock( tDblLinkList *pList ) +{ + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + vos_lock_acquire(&pList->Lock); + } +} + + +void csrLLUnlock( tDblLinkList *pList ) +{ + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + vos_lock_release(&pList->Lock); + } +} + + +tANI_BOOLEAN csrLLIsListEmpty( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tANI_BOOLEAN fEmpty = eANI_BOOLEAN_TRUE; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fEmpty ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + + fEmpty = csrIsListEmpty( &pList->ListHead ); + + if(fInterlocked) + { + csrLLUnlock(pList); + } + } + return( fEmpty ); +} + + + +tANI_BOOLEAN csrLLFindEntry( tDblLinkList *pList, tListElem *pEntryToFind ) +{ + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fFound ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + + while( pEntry && ( pEntry != &pList->ListHead ) ) + { + if ( pEntry == pEntryToFind ) + { + fFound = eANI_BOOLEAN_TRUE; + break; + } + pEntry = pEntry->next; + } + + } + return( fFound ); +} + + +eHalStatus csrLLOpen( tHddHandle hHdd, tDblLinkList *pList ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return eHAL_STATUS_FAILURE ; + } + + if ( LIST_FLAG_OPEN != pList->Flag ) + { + pList->Count = 0; + pList->cmdTimeoutTimer = NULL; + vosStatus = vos_lock_init(&pList->Lock); + + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + csrListInit( &pList->ListHead ); + pList->Flag = LIST_FLAG_OPEN; + pList->hHdd = hHdd; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + return (status); +} + +void csrLLClose( tDblLinkList *pList ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + // Make sure the list is empty... + csrLLPurge( pList, LL_ACCESS_LOCK ); + vos_lock_destroy( &pList->Lock ); + pList->Flag = LIST_FLAG_CLOSE; + } +} + +void csrLLInsertTail( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertTail( &pList->ListHead, pEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + } +} + + + +void csrLLInsertHead( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertHead( &pList->ListHead, pEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + if ( pList->cmdTimeoutTimer && pList->cmdTimeoutDuration ) + { + /* timer to detect pending command in activelist*/ + vos_timer_start( pList->cmdTimeoutTimer, + pList->cmdTimeoutDuration); + } + } +} + + +void csrLLInsertEntry( tDblLinkList *pList, tListElem *pEntry, tListElem *pNewEntry, tANI_BOOLEAN fInterlocked ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertEntry( pEntry, pNewEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + } +} + + + +tListElem *csrLLRemoveTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + + pEntry = csrListRemoveTail( &pList->ListHead ); + pList->Count--; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + +tListElem *csrLLPeekTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = pList->ListHead.last; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + + +tListElem *csrLLRemoveHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = csrListRemoveHead( &pList->ListHead ); + pList->Count--; + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + +tListElem *csrLLPeekHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = pList->ListHead.next; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + + +void csrLLPurge( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + while( (pEntry = csrLLRemoveHead( pList, LL_ACCESS_NOLOCK )) ) + { + // just remove everything from the list until + // nothing left on the list. + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } +} + + +tANI_BOOLEAN csrLLRemoveEntry( tDblLinkList *pList, tListElem *pEntryToRemove, tANI_BOOLEAN fInterlocked ) +{ + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fFound; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry && ( pEntry != &pList->ListHead ) ) + { + if ( pEntry == pEntryToRemove ) + { + csrListRemoveEntry( pEntry ); + pList->Count--; + + fFound = eANI_BOOLEAN_TRUE; + break; + } + + pEntry = pEntry->next; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + if ( pList->cmdTimeoutTimer ) + { + vos_timer_stop(pList->cmdTimeoutTimer); + } + } + + return( fFound ); +} + + + +tListElem *csrLLNext( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pNextEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pNextEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) && csrLLFindEntry( pList, pEntry ) ) + { + pNextEntry = pEntry->next; + //Make sure we don't walk past the head + if ( pNextEntry == &pList->ListHead ) + { + pNextEntry = NULL; + } + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pNextEntry ); +} + + +tListElem *csrLLPrevious( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pNextEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pNextEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) && csrLLFindEntry( pList, pEntry ) ) + { + pNextEntry = pEntry->last; + //Make sure we don't walk past the head + if ( pNextEntry == &pList->ListHead ) + { + pNextEntry = NULL; + } + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pNextEntry ); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLogDump.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLogDump.c new file mode 100644 index 0000000000000..0a64afd382353 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrLogDump.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +csrLogDump.c +Implements the dump commands specific to the csr module. +============================================================================*/ +#include "aniGlobal.h" +#include "csrApi.h" +#include "btcApi.h" +#include "logDump.h" +#include "smsDebug.h" +#include "smeInside.h" +#include "csrInsideApi.h" +#if defined(ANI_LOGDUMP) +static char * +dump_csr( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + static tCsrRoamProfile x; + static tSirMacSSid ssid; //To be allocated for array of SSIDs + static tANI_U8 sessionId; // Defined for fixed session ID + vos_mem_set((void*)&x, sizeof(x), 0); + x.SSIDs.numOfSSIDs=1 ; + x.SSIDs.SSIDList[0].SSID = ssid ; + ssid.length=6 ; + vos_mem_copy(ssid.ssId, "AniNet", 6); + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + (void)csrRoamConnect(pMac, sessionId, &x, NULL, NULL); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return p; +} +static char *dump_btcSetEvent( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + tSmeBtEvent btEvent; + if( arg1 < BT_EVENT_TYPE_MAX ) + { + smsLog(pMac, LOGE, FL(" signal BT event (%d) handle (%d) 3rd param(%d)"), arg1, arg2, arg3); + vos_mem_zero(&btEvent, sizeof(tSmeBtEvent)); + btEvent.btEventType = arg1; + switch( arg1 ) + { + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + btEvent.uEventParam.btSyncConnection.connectionHandle = (v_U16_t)arg2; + btEvent.uEventParam.btSyncConnection.status = (v_U8_t)arg3; + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + btEvent.uEventParam.btDisconnect.connectionHandle = (v_U16_t)arg2; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + btEvent.uEventParam.btAclConnection.connectionHandle = (v_U16_t)arg2; + btEvent.uEventParam.btAclConnection.status = (v_U8_t)arg3; + break; + case BT_EVENT_MODE_CHANGED: + btEvent.uEventParam.btAclModeChange.connectionHandle = (v_U16_t)arg2; + break; + default: + break; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + btcSignalBTEvent(pMac, &btEvent); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + } + else + { + smsLog(pMac, LOGE, FL(" invalid event (%d)"), arg1); + } + return p; +} +static char* dump_csrApConcScanParams( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + if( arg1 ) + { + pMac->roam.configParam.nRestTimeConc = arg1; + } + if( arg2 ) + { + pMac->roam.configParam.nActiveMinChnTimeConc = arg2; + } + if( arg3 ) + { + pMac->roam.configParam.nActiveMaxChnTimeConc = arg3; + } + + smsLog(pMac, LOGE, FL(" Working %d %d %d"), (int) pMac->roam.configParam.nRestTimeConc, + (int)pMac->roam.configParam.nActiveMinChnTimeConc, (int) pMac->roam.configParam.nActiveMaxChnTimeConc); + return p; +} + +static tDumpFuncEntry csrMenuDumpTable[] = { + {0, "CSR (850-860)", NULL}, + {851, "CSR: CSR testing connection to AniNet", dump_csr}, + {852, "BTC: Fake BT events (event, handle)", dump_btcSetEvent}, + {853, "CSR: Split Scan related params", dump_csrApConcScanParams}, +}; + +void csrDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal)hHal, &csrMenuDumpTable[0], + sizeof(csrMenuDumpTable)/sizeof(csrMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrNeighborRoam.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrNeighborRoam.c new file mode 100644 index 0000000000000..a3d24aae3cc2b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrNeighborRoam.c @@ -0,0 +1,6153 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrNeighborRoam.c + + Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform. +========================================================================== */ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +08/01/10 Murali Created + +===========================================================================*/ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "wlan_qct_wda.h" +#include "palApi.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "logDump.h" +#include "smeQosInternal.h" +#include "wlan_qct_tl.h" +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#include "csrApi.h" +#include "wlan_qct_tl.h" +#include "sme_Api.h" +#include "csrNeighborRoam.h" +#include "macTrace.h" +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif + +#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1 +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG +#define NEIGHBOR_ROAM_DEBUG smsLog +#else +#define NEIGHBOR_ROAM_DEBUG(x...) +#endif + +static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo); +static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId); +static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId); +static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac, + tANI_U8 sessionId); + +VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus); +eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile ); + +#ifdef WLAN_FEATURE_VOWIFI_11R +static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac, + tANI_U8 sessionId); +VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac, + tANI_U8 sessionId); +#endif + +v_U8_t *csrNeighborRoamStateToString(v_U8_t state) +{ + switch(state) + { + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CLOSED ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_INIT ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CONNECTED ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE ); + default: + return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN"; + } + +} + +/* State Transition macro */ +#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState, sessionId)\ +{\ + pMac->roam.neighborRoamInfo[sessionId].prevNeighborRoamState = \ + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;\ + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState = newState;\ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \ + FL("Session id(%d) Neighbor Roam Transition from state %s ==> %s"), \ + sessionId, \ + csrNeighborRoamStateToString ( \ + pMac->roam.neighborRoamInfo[sessionId].prevNeighborRoamState), \ + csrNeighborRoamStateToString (newState));\ +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamFreeNeighborRoamBSSNode + + \brief This function frees all the internal pointers CSR NeighborRoam BSS Info + and also frees the node itself + + \param pMac - The handle returned by macOpen. + neighborRoamBSSNode - Neighbor Roam BSS Node to be freed + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode) +{ + if (neighborRoamBSSNode) + { + if (neighborRoamBSSNode->pBssDescription) + { + vos_mem_free(neighborRoamBSSNode->pBssDescription); + neighborRoamBSSNode->pBssDescription = NULL; + } + vos_mem_free(neighborRoamBSSNode); + neighborRoamBSSNode = NULL; + } + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRemoveRoamableAPListEntry + + \brief This function removes a given entry from the given list + + \param pMac - The handle returned by macOpen. + pList - The list from which the entry should be removed + pNeighborEntry - Neighbor Roam BSS Node to be removed + + \return TRUE if successfully removed, else FALSE + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry) +{ + if(pList) + { + return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK); + } + + smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d"), csrLLCount(pList)); + + return eANI_BOOLEAN_FALSE; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamGetRoamableAPListNextEntry + + \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list + + \param pMac - The handle returned by macOpen. + pList - The list from which the entry should be returned + pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned + + \return Neighbor Roam BSS Node to be returned + +---------------------------------------------------------------------------*/ +tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry) +{ + tListElem *pEntry = NULL; + tpCsrNeighborRoamBSSInfo pResult = NULL; + + if(pList) + { + if(NULL == pNeighborEntry) + { + pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK); + } + else + { + pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK); + } + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List); + } + } + + return pResult; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamFreeRoamableBSSList + + \brief Empties and frees all the nodes in the roamable AP list + + \param pMac - The handle returned by macOpen. + pList - Neighbor Roam BSS List to be emptied + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tpCsrNeighborRoamBSSInfo pResult = NULL; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Emptying the BSS list. Current count = %d"), csrLLCount(pList)); + + /* Pick up the head, remove and free the node till the list becomes empty */ + while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL) + { + csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult); + csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult); + } + return; +} + +static void csrNeighborRoamTriggerHandoff(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((pNeighborRoamInfo->is11rAssoc) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn)) + { + csrNeighborRoamIssuePreauthReq(pMac, sessionId); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_NONE; + vos_mem_set(&pNeighborRoamInfo->cfgRoambssId[0], + sizeof(pNeighborRoamInfo->cfgRoambssId), + 0xFF); + } + else + { + smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif + +#ifdef FEATURE_WLAN_ESE + if ((pNeighborRoamInfo->isESEAssoc) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) + { + csrNeighborRoamIssuePreauthReq(pMac, sessionId); + } + else + { + smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + || csrRoamIsRoamOffloadScanEnabled(pMac) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn) +#endif + ) + { + csrNeighborRoamIssuePreauthReq(pMac, sessionId); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_NONE; + vos_mem_set(&pNeighborRoamInfo->cfgRoambssId[0], + sizeof(pNeighborRoamInfo->cfgRoambssId), + 0xFF); + } + else + { + smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif + { + if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState) + { + csrNeighborRoamRequestHandoff(pMac, sessionId); + } + else + { + smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %s or Roaming is diisabled"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + } + } +} + +VOS_STATUS +csrNeighborRoamUpdateFastRoamingEnabled(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const v_BOOL_t fastRoamEnabled) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpFTRoamCallbackUsrCtx pUsrCtx; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + if (VOS_TRUE == fastRoamEnabled) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, + REASON_CONNECT); + } else { +#endif + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup " + "DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + + /* Both pMac and sessionId are required to identify for which + * session the indication is being received + */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + /* Register Neighbor Lookup threshold callback with TL for + DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + smsLog(pMac, LOGW, + FL("Failed to register RSSI indication callback = %d"), + vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (VOS_FALSE == fastRoamEnabled) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in CONNECTED state, so deregister all events")); + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, + REASON_DISCONNECTED); + } else { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in INIT state, Nothing to do")); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Unexpected state %s, returning failure"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +#ifdef FEATURE_WLAN_ESE +VOS_STATUS csrNeighborRoamUpdateEseModeEnabled(tpAniSirGlobal pMac, + tANI_U8 sessionId, + const v_BOOL_t eseMode) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpFTRoamCallbackUsrCtx pUsrCtx; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + if (VOS_TRUE == eseMode) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, + REASON_CONNECT); + } else { +#endif + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + smsLog(pMac, LOGW, + FL("Failed to register RSSI indication callback: Status = %d"), + vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (VOS_FALSE == eseMode) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Currently in CONNECTED state, so deregister all events")); + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, + REASON_DISCONNECTED); + } else { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == + pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Currently in INIT state, Nothing to do")); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Unexpected state %d, returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +#endif + + +VOS_STATUS csrNeighborRoamSetLookupRssiThreshold(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t neighborLookupRssiThreshold) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpFTRoamCallbackUsrCtx pUsrCtx; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == + pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("In CONNECTED state, re-register for DOWN event only")); + + pNeighborRoamInfo->cfgParams.neighborLookupThreshold = + neighborLookupRssiThreshold; + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_LOOKUP_THRESH_CHANGED); + } + else + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); + + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + smsLog(pMac, LOGE, + FL("Failed to register DOWN event with TL: Status = %d"), + vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Currently in INIT state, safe to set lookupRssi threshold")); + pNeighborRoamInfo->cfgParams.neighborLookupThreshold = + neighborLookupRssiThreshold; + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Unexpected state %s, returning failure"), + macTraceGetNeighbourRoamState(pNeighborRoamInfo->neighborRoamState)); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +VOS_STATUS +csrNeighborRoamSetOpportunisticScanThresholdDiff(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nOpportunisticThresholdDiff) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in CONNECTED state, so deregister " + "all and re-register for DOWN event again")); + + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff = + nOpportunisticThresholdDiff; + pNeighborRoamInfo->currentOpportunisticThresholdDiff = + nOpportunisticThresholdDiff; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, + sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED); + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in INIT state, safe to set " + "opportunistic threshold diff")); + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff = + nOpportunisticThresholdDiff; + pNeighborRoamInfo->currentOpportunisticThresholdDiff = + nOpportunisticThresholdDiff; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOGE, + FL("Unexpected state %d returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +VOS_STATUS +csrNeighborRoamSetRoamRescanRssiDiff(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamRescanRssiDiff) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in CONNECTED state, so deregister " + "all and re-register for DOWN event again")); + + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff = + nRoamRescanRssiDiff; + pNeighborRoamInfo->currentRoamRescanRssiDiff = + nRoamRescanRssiDiff; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, + sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED); + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in INIT state, safe to set roam " + "rescan rssi diff")); + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff = + nRoamRescanRssiDiff; + pNeighborRoamInfo->currentRoamRescanRssiDiff = nRoamRescanRssiDiff; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOGE, + FL("Unexpected state %d returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +VOS_STATUS +csrNeighborRoamSetRoamBmissFirstBcnt(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBmissFirstBcnt) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in CONNECTED state, so deregister all and re-register for DOWN event again")); + + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt = + nRoamBmissFirstBcnt; + pNeighborRoamInfo->currentRoamBmissFirstBcnt = nRoamBmissFirstBcnt; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, + sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_BMISS_FIRST_BCNT_CHANGED); + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in INIT state, safe to set roam rescan rssi diff")); + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt = + nRoamBmissFirstBcnt; + pNeighborRoamInfo->currentRoamBmissFirstBcnt = nRoamBmissFirstBcnt; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOGE, + FL("Unexpected state %d returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +VOS_STATUS +csrNeighborRoamSetRoamBmissFinalBcnt(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBmissFinalBcnt) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in CONNECTED state, so deregister all and re-register for DOWN event again")); + + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt = + nRoamBmissFinalBcnt; + pNeighborRoamInfo->currentRoamBmissFinalBcnt = nRoamBmissFinalBcnt; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_BMISS_FINAL_BCNT_CHANGED); + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in INIT state, safe to set roam rescan rssi diff")); + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt = + nRoamBmissFinalBcnt; + pNeighborRoamInfo->currentRoamBmissFinalBcnt = nRoamBmissFinalBcnt; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOGE, + FL("Unexpected state %d returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +VOS_STATUS +csrNeighborRoamSetRoamBeaconRssiWeight(tpAniSirGlobal pMac, + tANI_U8 sessionId, + v_U8_t nRoamBeaconRssiWeight) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in CONNECTED state, so deregister all and re-register for DOWN event again")); + + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight = + nRoamBeaconRssiWeight; + pNeighborRoamInfo->currentRoamBeaconRssiWeight = nRoamBeaconRssiWeight; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED); + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT + == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOG2, + FL("Currently in INIT state, safe to set roam rescan rssi diff")); + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight = + nRoamBeaconRssiWeight; + pNeighborRoamInfo->currentRoamBeaconRssiWeight = + nRoamBeaconRssiWeight; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, + LOGE, + FL("Unexpected state %d returning failure"), + pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamReassocIndCallback + + \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold. + Directly triggere HO in case of non-11r association + In case of 11R association, triggers a pre-auth eventually followed by actual HO + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOID + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter, + v_U8_t trafficStatus, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *)pUserCtxt; + tANI_U8 sessionId = pUsrCtx->sessionId; + tpAniSirGlobal pMac = pUsrCtx->pMac; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (eSME_ROAM_TRIGGER_FAST_ROAM != pNeighborRoamInfo->cfgRoamEn) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregistering DOWN event reassoc callback with TL. " + "Threshold RSSI = %d Reported RSSI = %d"), + pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + avgRssi); + + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d"), vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Rcvd reassoc notification-deregister UP indication. Threshold RSSI = %d Reported RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), avgRssi); + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupUPCallback with TL: Status = %d"), vosStatus); + } + } + /* We dont need to run this timer any more. */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + + csrNeighborRoamTriggerHandoff(pMac, sessionId); + vos_mem_free(pUsrCtx); + + return VOS_STATUS_SUCCESS; +} + +/*CleanUP Routines*/ +static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo) +{ + if ((rChInfo->IAPPNeighborListReceived == FALSE) && + (rChInfo->currentChannelListInfo.numOfChannels)) + { + rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + rChInfo->currentChannelListInfo.numOfChannels = 0; + + if (rChInfo->currentChannelListInfo.ChannelList) + vos_mem_free(rChInfo->currentChannelListInfo.ChannelList); + + rChInfo->currentChannelListInfo.ChannelList = NULL; + rChInfo->chanListScanInProgress = eANI_BOOLEAN_FALSE; + } + else + { + rChInfo->currentChanIndex = 0; + rChInfo->chanListScanInProgress = eANI_BOOLEAN_TRUE; + } +} + +static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + /* Stop neighbor scan timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + + /* Stop neighbor scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + + /* Stop empty scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + + /* Abort any ongoing scan */ + if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending) + { + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + } + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + /* Reset roam channel list information */ + csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo); +} + +static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE; + /* Purge pre-auth fail list */ + csrNeighborRoamPurgePreauthFailedList(pMac); +#endif + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Do not free up the preauth done list here */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; + vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, + sizeof(tCsrHandoffRequest)); +#endif +} + +static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregister neighbor lookup UP callback with TL. RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't deregister csrNeighborRoamNeighborLookupUPCallback with TL: Status = %d"), + vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregistering reassoc DOWN callback with TL. RSSI = %d"), + pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d"), + vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregistering neighborLookup DOWN callback with TL. RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + + /* Deregister neighbor lookup callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), + vosStatus); + } + + /* Reset thresholds only after deregistering DOWN event from TL */ + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; + pNeighborRoamInfo->currentOpportunisticThresholdDiff = + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff; + pNeighborRoamInfo->currentRoamRescanRssiDiff = + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff; + pNeighborRoamInfo->currentRoamBmissFirstBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt; + pNeighborRoamInfo->currentRoamBmissFinalBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt; + pNeighborRoamInfo->currentRoamBeaconRssiWeight = + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResetConnectedStateControlInfo + + \brief This function will reset the neighbor roam control info data structures. + This function should be invoked whenever we move to CONNECTED state from + any state other than INIT state + + \param pMac - The handle returned by macOpen. + \param sessionId - session id + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo); + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + + /* We dont need to run this timer any more. */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Do not free up the preauth done list here */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0; + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; + vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, + sizeof(tCsrHandoffRequest)); +#endif +} + +void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0); + pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac; + pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID; +#ifdef FEATURE_WLAN_ESE + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->MinQBssLoadRequired = 0; +#endif + + /* Stop scan refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + /* Stop empty scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + /* Purge roamable AP list */ + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResetInitStateControlInfo + + \brief This function will reset the neighbor roam control info data structures. + This function should be invoked whenever we move to CONNECTED state from + INIT state + + \param pMac - The handle returned by macOpen. + \param sessionId - Session Id + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + csrNeighborRoamResetConnectedStateControlInfo(pMac, sessionId); + + /* In addition to the above resets, + we should clear off the curAPBssId/Session ID in the timers */ + csrNeighborRoamResetReportScanStateControlInfo(pMac, sessionId); +} + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamBssIdScanFilter + + \brief This API is used to prepare a filter to obtain scan results when + we complete the scan in the REPORT_SCAN state after receiving a + valid neighbor report from AP. This filter includes BSSIDs received from + the neighbor report from the AP in addition to the other filter parameters + created from connected profile + + \param pMac - The handle returned by macOpen. + pScanFilter - Scan filter to be filled and returned + + \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error + code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tCsrScanResultFilter *pScanFilter) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 i = 0; + + VOS_ASSERT(pScanFilter != NULL); + if (pScanFilter == NULL) + return eHAL_STATUS_FAILURE; + vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter)); + + pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + if (NULL == pScanFilter->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from Neighbor BSS info received from neighbor report */ + for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) { + vos_mem_copy(&pScanFilter->BSSIDs.bssid[i], + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, + sizeof(tSirMacAddr)); + } + + /* Fill other general scan filter params */ + return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter, sessionId); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPurgePreauthFailList + + \brief This function empties the preauth fail list + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list")); + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i]; + while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress) { + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1], + sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--; + } + } + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamAddBssIdToPreauthFailList + + \brief This function adds the given BSSID to the Preauth fail list + + \param pMac - The handle returned by macOpen. + bssId - BSSID to be added to the preauth fail list + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tSirMacAddr bssId) +{ + tANI_U8 i = 0; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Added BSSID "MAC_ADDRESS_STR + " to Preauth failed list"), MAC_ADDR_ARRAY(bssId)); + + for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; + i++) { + if (VOS_TRUE == vos_mem_compare( + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i], + bssId, sizeof(tSirMacAddr))) { + smsLog(pMac, LOGW, FL("BSSID "MAC_ADDRESS_STR" already present in preauth fail list"), + MAC_ADDR_ARRAY(bssId)); + return eHAL_STATUS_SUCCESS; + } + } + + if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) > + MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) + { + smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one")); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[ + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress], + bssId, + sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++; + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIsPreauthCandidate + + \brief This function checks whether the given MAC address is already + present in the preauth fail list and returns TRUE/FALSE accordingly + + \param pMac - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tSirMacAddr bssId) +{ + tANI_U8 i = 0; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + return eANI_BOOLEAN_TRUE; + } +#endif + if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress) + return eANI_BOOLEAN_TRUE; + + for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++) + { + if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i], + bssId, sizeof(tSirMacAddr))) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID "MAC_ADDRESS_STR" already present in preauth fail list"), + MAC_ADDR_ARRAY(bssId)); + return eANI_BOOLEAN_FALSE; + } + } + + return eANI_BOOLEAN_TRUE; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssuePreauthReq + + \brief This function issues preauth request to PE with the 1st AP entry in the + roamable AP list + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo pNeighborBssNode; + +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfo; +#endif + + if (eANI_BOOLEAN_FALSE != pNeighborRoamInfo->FTRoamInfo.preauthRspPending) + { + /* This must not be true here */ + VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE); + return eHAL_STATUS_FAILURE; + } + + /* Issue Preauth request to PE here */ + /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */ + /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */ + /* If roamableAPList gets empty, should transition to REPORT_SCAN state */ + pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL); + + if (NULL == pNeighborBssNode) + { + smsLog(pMac, LOGW, FL("Roamable AP list is empty.. ")); + return eHAL_STATUS_FAILURE; + } + else + { +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth initiation metric. + Send the event to supplicant that pre-auth was initiated */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pNeighborBssNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, roamInfo, 0, + eCSR_ROAM_PREAUTH_INIT_NOTIFY, 0); + vos_mem_free(pRoamInfo); + } +#endif + + status = csrRoamEnqueuePreauth(pMac, sessionId, + pNeighborBssNode->pBssDescription, + eCsrPerformPreauth, eANI_BOOLEAN_TRUE); + + smsLog(pMac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"), + MAC_ADDR_ARRAY(pNeighborBssNode->pBssDescription->bssId), + (int)pNeighborBssNode->pBssDescription->channelId); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d"), status); + return status; + } + } + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE; + + /* Increment the preauth retry count */ + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++; + + /* Transition the state to preauthenticating */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING, + sessionId) + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPreauthRspHandler + + \brief This function handle the Preauth response from PE + Every preauth is allowed max 3 tries if it fails. If a bssid failed + for more than MAX_TRIES, we will remove it from the list and try + with the next node in the roamable AP list and add the BSSID to pre-auth failed + list. If no more entries present in + roamable AP list, transition to REPORT_SCAN state + + \param pMac - The handle returned by macOpen. + limStatus - eSIR_SUCCESS/eSIR_FAILURE/eSIR_LIM_MAX_STA_REACHED_ERROR/ + eSIT_LIM_AUTH_RSP_TIMEOUT status from PE + + \return eHAL_STATUS_SUCCESS on success (i.e. pre-auth processed), + eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tSirRetStatus limStatus) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus preauthProcessed = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL; + tpFTRoamCallbackUsrCtx pUsrCtx; + +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfo; +#endif + + if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->FTRoamInfo.preauthRspPending) + { + + /* This can happen when we disconnect immediately + * after sending a pre-auth request. During processing + * of the disconnect command, we would have reset + * preauthRspPending and transitioned to INIT state. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("Unexpected pre-auth response in state %d"), + pNeighborRoamInfo->neighborRoamState); + preauthProcessed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + // We can receive it in these 2 states. + if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) && + (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("Preauth response received in state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + preauthProcessed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE; + + if (eSIR_SUCCESS == limStatus) + { + pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, + &pNeighborRoamInfo->roamableAPList, + NULL); + } + if ((eSIR_SUCCESS == limStatus) && (NULL != pPreauthRspNode)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Preauth completed successfully after %d tries"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries); + + smsLog(pMac, LOG1, FL("After Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"), + MAC_ADDR_ARRAY(pPreauthRspNode->pBssDescription->bssId), + (int)pPreauthRspNode->pBssDescription->channelId); + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. + Send the event to supplicant that pre-auth successfully completed */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pPreauthRspNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, roamInfo, 0, + eCSR_ROAM_PREAUTH_STATUS_SUCCESS, 0); + vos_mem_free(pRoamInfo); + } +#endif + + /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */ + csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode); + csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK); + + /* Pre-auth completed successfully. Transition to PREAUTH Done state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, + sessionId) + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + + /* The caller of this function would start a timer and by the time it expires, supplicant should + have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */ + } + else + { + tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL; + tListElem *pEntry; + + smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = 0x%x"), + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, limStatus); + + /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */ + if ((pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= + CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) || + (eSIR_LIM_MAX_STA_REACHED_ERROR == limStatus)) + { + /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */ + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + + /* The one in the head of the list should be one with which we issued pre-auth and failed */ + pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK); + if(pEntry) + { + pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List); + /* Add the BSSID to pre-auth fail list if it is not requested by HDD */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!pNeighborRoamInfo->uOsRequestedHandoff) +#endif + { + status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, + sessionId, + pNeighborBssNode->pBssDescription->bssId); + } + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. Send the event + to supplicant that pre-auth successfully completed */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pNeighborBssNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, roamInfo, 0, + eCSR_ROAM_PREAUTH_STATUS_FAILURE, 0); + vos_mem_free(pRoamInfo); + } +#endif + + /* Now we can free this node */ + csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode); + } + } + + /* Issue preauth request for the same/next entry */ + if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac, + sessionId)) + goto DEQ_PREAUTH; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + if(pNeighborRoamInfo->uOsRequestedHandoff) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; + csrRoamOffloadScan(pMac, 0, ROAM_SCAN_OFFLOAD_START, + REASON_PREAUTH_FAILED_FOR_ALL); + } + else + { + csrRoamOffloadScan(pMac, 0, ROAM_SCAN_OFFLOAD_RESTART, + REASON_PREAUTH_FAILED_FOR_ALL); + } + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + sessionId); + } else + { +#endif + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + sessionId); + + /* Register Neighbor Lookup threshold callback with TL + for UP event now */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No more pre-auth candidates-" + "register UP indication with TL. RSSI = %d,"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failed for pUsrCtx")); + return eHAL_STATUS_FAILED_ALLOC; + } + + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d"), status); + } + + /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */ + status = vos_timer_start(&pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d"), status); + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + +DEQ_PREAUTH: + csrDequeueRoamCommand(pMac, eCsrPerformPreauth); + return preauthProcessed; +} +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/* --------------------------------------------------------------------------- + * \fn csrNeighborRoamOffloadUpdatePreauthList + * \brief This function handle the RoamOffloadSynch and adds the + * roamed AP to the preauth done list + * \param pMac - The handle returned by macOpen. + * \param pSmeRoamOffloadSynchInd - Roam offload sync Ind Info + * \param sessionId - Session identifier + * \return eHAL_STATUS_SUCCESS on success, + * eHAL_STATUS_FAILURE otherwise + * --------------------------------------------------------------------------*/ +eHalStatus +csrNeighborRoamOffloadUpdatePreauthList(tpAniSirGlobal pMac, + tpSirRoamOffloadSynchInd pSmeRoamOffloadSynchInd, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrNeighborRoamBSSInfo pBssInfo; + tANI_U16 bssDescLen; + + if (pNeighborRoamInfo->neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("LFR3:Roam Offload Synch Ind received in state %d"), + pNeighborRoamInfo->neighborRoamState); + return eHAL_STATUS_FAILURE; + } + + pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo)); + if (NULL == pBssInfo) + { + smsLog(pMac, LOGE, + FL("LFR3:Memory allocation for Neighbor Roam BSS Info failed")); + return eHAL_STATUS_FAILURE; + } + bssDescLen = pSmeRoamOffloadSynchInd->pbssDescription->length + + sizeof(pSmeRoamOffloadSynchInd->pbssDescription->length); + pBssInfo->pBssDescription = vos_mem_malloc(bssDescLen); + if (pBssInfo->pBssDescription != NULL) + { + vos_mem_copy(pBssInfo->pBssDescription, + pSmeRoamOffloadSynchInd->pbssDescription, + bssDescLen); + } + else + { + smsLog(pMac, LOGE, + FL("LFR3:Mem alloc for Neighbor Roam BSS Descriptor failed")); + vos_mem_free(pBssInfo); + return eHAL_STATUS_FAILURE; + + } + csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, + &pBssInfo->List, LL_ACCESS_LOCK); + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, + sessionId) + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:Entry added to Auth Done List"); + + return eHAL_STATUS_SUCCESS; +} +#endif +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPrepareScanProfileFilter + + \brief This function creates a scan filter based on the currently connected profile. + Based on this filter, scan results are obtained + + \param pMac - The handle returned by macOpen. + pScanFilter - Populated scan filter based on the connected profile + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus +csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, + tCsrScanResultFilter *pScanFilter, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + tANI_U8 i = 0; + + VOS_ASSERT(pScanFilter != NULL); + if (pScanFilter == NULL) + return eHAL_STATUS_FAILURE; + + vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter)); + + /* We dont want to set BSSID based Filter */ + pScanFilter->BSSIDs.numOfBSSIDs = 0; + + //only for HDD requested handoff fill in the BSSID in the filter +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pNeighborRoamInfo->uOsRequestedHandoff) + { + pScanFilter->BSSIDs.numOfBSSIDs = 1; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + if (NULL == pScanFilter->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from handoff info received from HDD */ + for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) + { + vos_mem_copy(&pScanFilter->BSSIDs.bssid[i], + pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr)); + } + } +#endif + /* Populate all the information from the connected profile */ + pScanFilter->SSIDs.numOfSSIDs = 1; + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if (NULL == pScanFilter->SSIDs.SSIDList) + { + smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + pScanFilter->SSIDs.SSIDList->handoffPermitted = 1; + pScanFilter->SSIDs.SSIDList->ssidHidden = 0; + pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length; + vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length); + + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Filtering for SSID %.*s from scan results," + "length of SSID = %u"), + pScanFilter->SSIDs.SSIDList->SSID.length, + pScanFilter->SSIDs.SSIDList->SSID.ssId, + pScanFilter->SSIDs.SSIDList->SSID.length); + pScanFilter->authType.numEntries = 1; + pScanFilter->authType.authType[0] = pCurProfile->AuthType; + + pScanFilter->EncryptionType.numEntries = 1; //This must be 1 + pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType; + + pScanFilter->mcEncryptionType.numEntries = 1; + pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType; + + pScanFilter->BSSType = pCurProfile->BSSType; + + /* We are intrested only in the scan results on channels that we scanned */ + pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; + pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8)); + if (NULL == pScanFilter->ChannelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed")); + vos_mem_free(pScanFilter->SSIDs.SSIDList); + pScanFilter->SSIDs.SSIDList = NULL; + return eHAL_STATUS_FAILED_ALLOC; + } + for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++) + { + pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) + { + /* MDIE should be added as a part of profile. This should be added as a part of filter as well */ + pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent; + pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain; + } +#endif + +#ifdef WLAN_FEATURE_11W + pScanFilter->MFPEnabled = pCurProfile->MFPEnabled; + pScanFilter->MFPRequired = pCurProfile->MFPRequired; + pScanFilter->MFPCapable = pCurProfile->MFPCapable; +#endif + return eHAL_STATUS_SUCCESS; +} + +tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, + tScanResultHandle *pScanResultList, + tANI_U8 sessionId) +{ + tCsrScanResultInfo *pScanResult; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; +#ifdef FEATURE_WLAN_LFR + tANI_U32 CurrAPRssi = pNeighborRoamInfo->lookupDOWNRssi; +#else + /* We are setting this as default value to make sure we return this value, + when we do not see this AP in the scan result for some reason.However,it is + less likely that we are associated to an AP and do not see it in the scan list */ + tANI_U32 CurrAPRssi = -125; +#endif + + while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList))) + { + if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr))) + { + /* We got a match with the currently associated AP. + * Capture the RSSI value and complete the while loop. + * The while loop is completed in order to make the current entry go back to NULL, + * and in the next while loop, it properly starts searching from the head of the list. + * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/ + + CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1); + + } else { + continue; + } + } + + return CurrAPRssi; + +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProcessScanResults + + \brief This function extracts scan results, sorts on the basis of neighbor score(todo). + Assumed that the results are already sorted by RSSI by csrScanGetResult + + \param pMac - The handle returned by macOpen. + pScanResultList - Scan result result obtained from csrScanGetResult() + + \return tANI_BOOLEAN - return TRUE if we have a candidate we can immediately + roam to. Otherwise, return FALSE. + +---------------------------------------------------------------------------*/ + +static tANI_BOOLEAN +csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tScanResultHandle *pScanResultList) +{ + tCsrScanResultInfo *pScanResult; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrNeighborRoamBSSInfo pBssInfo; + tANI_U32 CurrAPRssi; + tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 immediateRoamRssiDiff = + pMac->roam.configParam.nImmediateRoamRssiDiff; +#endif + tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE; + tScanResultHandle *pScanResultListSaved = NULL; + tANI_U32 apAgeTicks = 0; + tANI_U32 apAgeLimitTicks = adf_os_msecs_to_ticks(ROAM_AP_AGE_LIMIT_MS); + tANI_U8 numCandidates = 0; + tANI_U8 numAPsDropped = 0; + /* + * first iteration of scan list should consider + * age constraint for candidates + */ + tANI_BOOLEAN ageConstraint = eANI_BOOLEAN_TRUE; + + /*************************************************************** + * Find out the Current AP RSSI and keep it handy to check if + * it is better than the RSSI of the AP which we are + * going to roam.If so, we are going to continue with the + * current AP. + ***************************************************************/ + CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList, sessionId); + + /* + * Expecting the scan result already to be in the sorted order based on the + * RSSI. Based on the previous state we need to check whether the list + * should be sorted again taking neighbor score into consideration. If + * previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor + * score associated with any of the BSS. If the previous state is + * REPORT_QUERY, then there will be neighbor score for each of the APs. For + * now, let us take the top of the list provided as it is by the CSR Scan + * result API. This means it is assumed that neighbor score and rssi score + * are in the same order. This will be taken care later + */ + + do { + /* save the scan result pointer for next iteration */ + pScanResultListSaved = pScanResultList; + while (NULL != (pScanResult = csrScanResultGetNext(pMac, + *pScanResultList))) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("Scan result: BSSID "MAC_ADDRESS_STR" (Rssi %ld, Ch:%d)"), + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId), + abs(pScanResult->BssDescriptor.rssi), + pScanResult->BssDescriptor.channelId); + + if ((VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr))) || + ((eSME_ROAM_TRIGGER_SCAN == pNeighborRoamInfo->cfgRoamEn) && + (VOS_TRUE != vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->cfgRoambssId, sizeof(tSirMacAddr))))) { + /* + * currently associated AP. Do not have this in the roamable AP + * list + */ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "SKIP-currently associated AP"); + continue; + } + +#ifdef FEATURE_WLAN_LFR +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* + * In case of reassoc requested by upper layer, look for exact match + * of bssid & channel. csr cache might have duplicates + */ + if ((pNeighborRoamInfo->uOsRequestedHandoff) && + ((VOS_FALSE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->handoffReqInfo.bssid, + sizeof(tSirMacAddr)))|| + (pScanResult->BssDescriptor.channelId != + pNeighborRoamInfo->handoffReqInfo.channel))) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "SKIP-not a candidate AP for OS requested roam"); + continue; + } +#endif +#endif + + /* + * This condition is to ensure to roam to an AP with better RSSI. + * if the value of RoamRssiDiff is Zero, this feature + * is disabled and we continue to roam without any check + */ + if ((RoamRssiDiff > 0) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + && ((eSME_ROAM_TRIGGER_SCAN != pNeighborRoamInfo->cfgRoamEn) || + (eSME_ROAM_TRIGGER_FAST_ROAM != pNeighborRoamInfo->cfgRoamEn))) { + /* + * If RSSI is lower than the lookup threshold, then continue. + */ + if (abs(pScanResult->BssDescriptor.rssi) > + pNeighborRoamInfo->currentNeighborLookupThreshold) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("new ap rssi (%d) lower than lookup threshold (%d)"), + (int)pScanResult->BssDescriptor.rssi * (-1), + (int)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + continue; + } + + if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi)) { + /* Do not roam to an AP with worse RSSI than the current */ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap rssi " + "worse=%d", __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1) ); + continue; + } else { + /* + * Do not roam to an AP which is having better RSSI than the + * current AP, but still less than the margin that is + * provided by user from the ini file (RoamRssiDiff) + */ + if (abs(abs(CurrAPRssi) - + abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap " + "rssi=%d not good enough, roamRssiDiff=%d", + __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1), + RoamRssiDiff); + continue; + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap " + "rssi better=%d", + __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1) ); + } + } + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) { + if (!csrNeighborRoamIsPreauthCandidate(pMac, sessionId, + pScanResult->BssDescriptor.bssId)) { + smsLog(pMac, LOGE, + FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef FEATURE_WLAN_ESE +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) { +#endif + if (pNeighborRoamInfo->isESEAssoc) { + if (!csrNeighborRoamIsPreauthCandidate(pMac, sessionId, + pScanResult->BssDescriptor.bssId)) { + smsLog(pMac, LOGE, + FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } + if ((pScanResult->BssDescriptor.QBSSLoad_present) && + (pScanResult->BssDescriptor.QBSSLoad_avail)) { + if (pNeighborRoamInfo->isVOAdmitted) { + smsLog(pMac, LOG1, FL("New AP has %x BW available"), + (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail); + smsLog(pMac, LOG1, FL("We need %x BW available"), + (unsigned int)pNeighborRoamInfo->MinQBssLoadRequired); + if (pScanResult->BssDescriptor.QBSSLoad_avail < + pNeighborRoamInfo->MinQBssLoadRequired) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "[INFOLOG]BSSID : "MAC_ADDRESS_STR" has no" + " bandwidth ignoring..not adding to roam" + " list", + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId)); + continue; + } + } + } else { + smsLog(pMac, LOGE, FL("No QBss %x %x"), + (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, + (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present); + if (pNeighborRoamInfo->isVOAdmitted) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "[INFOLOG]BSSID : "MAC_ADDRESS_STR" has no " + "QBSSLoad IE, ignoring..not adding to roam list", + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId)); + continue; + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif +#endif /* FEATURE_WLAN_ESE */ + +#ifdef FEATURE_WLAN_LFR + /* + * If we are supporting legacy roaming, and + * if the candidate is on the "pre-auth failed" list, ignore it. + */ + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) { + if (!csrNeighborRoamIsPreauthCandidate(pMac, sessionId, + pScanResult->BssDescriptor.bssId)) { + smsLog(pMac, LOGE, + FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } +#endif /* FEATURE_WLAN_LFR */ + + /* + * If the received timestamp in BSS description is earlier than the + * scan request timestamp, skip this result + */ + if ((pNeighborRoamInfo->scanRequestTimeStamp >= + pScanResult->BssDescriptor.nReceivedTime) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) { + smsLog(pMac, LOGE, + FL("Ignoring BSS as it is older than the scan request " + "timestamp")); + continue; + } + + pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo)); + if (NULL == pBssInfo) { + smsLog(pMac, LOGE, + FL("Memory allocation for Neighbor Roam BSS Info " + "failed.. Just ignoring")); + continue; + } + + pBssInfo->pBssDescription = + vos_mem_malloc(pScanResult->BssDescriptor.length + + sizeof(pScanResult->BssDescriptor.length)); + if (pBssInfo->pBssDescription != NULL) { + vos_mem_copy(pBssInfo->pBssDescription, + &pScanResult->BssDescriptor, + pScanResult->BssDescriptor.length + + sizeof(pScanResult->BssDescriptor.length)); + } else { + smsLog(pMac, LOGE, + FL("Memory allocation for Neighbor Roam BSS Descriptor " + "failed.. Just ignoring")); + vos_mem_free(pBssInfo); + continue; + } + /* + * some value for now. Need to calculate the actual score based on + * RSSI and neighbor AP score + */ + pBssInfo->apPreferenceVal = 10; + + if (ageConstraint == eANI_BOOLEAN_FALSE) { + /* just add to candidate list, irrespective of age */ + numCandidates++; + csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, + &pBssInfo->List, + LL_ACCESS_LOCK); + } else { + /* check the age of the AP first */ + apAgeTicks = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd) - + pScanResult->BssDescriptor.nReceivedTime; + if (apAgeTicks < apAgeLimitTicks) { + numCandidates++; + csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, + &pBssInfo->List, + LL_ACCESS_LOCK); + } else { + numAPsDropped++; + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Skipping because received AP " + "(probe rsp/beacon) is old.")); + if (pBssInfo->pBssDescription) + vos_mem_free(pBssInfo->pBssDescription); + if (pBssInfo) + vos_mem_free(pBssInfo); + continue; + } + } +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if ((eSME_ROAM_TRIGGER_SCAN == pNeighborRoamInfo->cfgRoamEn) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn)) { + roamNow = eANI_BOOLEAN_FALSE; + } + else if ((abs(abs(CurrAPRssi) - + abs(pScanResult->BssDescriptor.rssi)) >= + immediateRoamRssiDiff) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] potential candidate to roam " + "immediately (diff=%ld, expected=%d)", + __func__, + abs(abs(CurrAPRssi) - + abs(pScanResult->BssDescriptor.rssi)), + immediateRoamRssiDiff); + roamNow = eANI_BOOLEAN_TRUE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* + * If we are here means, FW already found candidates to roam, + * so we are good to go with pre-auth + */ + if(csrRoamIsRoamOffloadScanEnabled(pMac)) { + roamNow = eANI_BOOLEAN_TRUE; + } +#endif +#endif + } /* end of while (csrScanResultGetNext) */ + /* set the scan results for next iteration */ + pScanResultList = pScanResultListSaved; + + /* if some candidates were found, then no need to repeat */ + if (numCandidates) + break; + /* + * if ageConstraint is already false, we have done two + * iterations and no candidate were found */ + if (ageConstraint == eANI_BOOLEAN_FALSE) { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: No roamable candidates found", __func__); + break; + } + /* + * if all candidates were dropped rescan the scan + * list but this time without age constraint. + */ + ageConstraint = eANI_BOOLEAN_FALSE; + /* if no candidates were dropped no need to repeat */ + } while (numAPsDropped); + + /* + * Now we have all the scan results in our local list. Good time to free + * up the the list we got as a part of csrGetScanResult + */ + csrScanResultPurge(pMac, *pScanResultList); + + return roamNow; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamHandleEmptyScanResult + + \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when + there are no valid APs in the scan result for roaming. This means + our AP is the best and no other AP is around. No point in scanning + again and again. Performing the following here. + 1. Stop the neighbor scan timer. + 2a. If this is the first time we encountered empty scan, then + re-register with TL with modified lookup threshold. + 2b. Else if this is the second time we encountered empty scan, + then start neighbor scan results refresh timer (20s). + 2c. Else, nothing more to do. + NOTE: In LFR, channels selected for scanning is dervied from + the occuped channel list. Scan cycle following one which + yielded empty results is split into two halves: (i) scan on + channels in the occupied list, and (ii) scan on channels not + in the occupied list. This helps converging faster (while + looking for candidates in the occupied list first), and also, + adds channels to the occupied channel list upon finding candidates + matching SSID profile of interest. + + uEmptyScanCount Comments + eFirstEmptyScan Previous scan was done on channels in the + occupied list and yielded potential candidates. + This scan cycle was likely triggered through + receipt of lookup DOWN notification event. + eSecondEmptyScan Previous scan was done on channels in the + occupied list and yielded no candidates. This scan + cycle was triggered through RSSI notification + with modified lookup threshold. + eThirdEmptyScan Previous scan was done on channels NOT in + the occupied list and yielded no candidates. This + scan cycle was triggered immediately after scanning + channels in the occupied list and no candidates + were found. + eFourthEmptyScan Previous scan was done on channels in the + occupied list and yielded no candidates. This scan + cycle was triggered upon expiry of + neighborScanResultsRefreshPeriod (=20s). + eFifthEmptyScan Previous scan was done on channels NOT in + the occupied list and yielded no candidates. This + scan cycle was triggered immediately after scanning + channels in the occupied list and no candidates + were found. + + [1], [2,3] and [4,5] together form one discrete set of scan cycle. + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpFTRoamCallbackUsrCtx pUsrCtx; + +#ifdef FEATURE_WLAN_LFR + tANI_BOOLEAN performPeriodicScan = + (pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod) ? TRUE : FALSE; +#endif + + /* Stop neighbor scan timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + /* + * Increase the neighbor lookup threshold by 3 dB + * after every scan cycle. NOTE: uEmptyScanCount + * would be either 1, 3 or 5 at the end of every + * scan cycle. + */ +#ifdef FEATURE_WLAN_LFR + if ((++pNeighborRoamInfo->uEmptyScanCount) > eFifthEmptyScan) + { + pNeighborRoamInfo->uEmptyScanCount = eFifthEmptyScan; + } + if (((0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) || + (abs(pNeighborRoamInfo->lookupDOWNRssi) > + abs(pNeighborRoamInfo->cfgParams.neighborReassocThreshold))) && + ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) || + (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan))) + { + /* + * If the scan was triggered due to lookupDOWNRssi > reassoc threshold, + * then it would be a contiguous scan on all valid non-DFS channels. + * If channels are configured in INI, then only those channels need + * to be scanned. + * In either of these modes, there is no need to trigger an immediate + * scan upon empty scan results for the second and fourth time (which + * would be equivalent to scanning on channels in non-occupied list). + * Incrementing uEmptyScanCount will correspond to skipping this step. + * NOTE: double increment of uEmptyScanCount corresponds to completion + * of scans on all valid channels. + */ + ++pNeighborRoamInfo->uEmptyScanCount; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Extra increment of empty scan count (=%d)" + " in contiguous scan mode", pNeighborRoamInfo->uEmptyScanCount); + } +#endif + if (((pNeighborRoamInfo->currentNeighborLookupThreshold+3) < + pNeighborRoamInfo->cfgParams.neighborReassocThreshold) +#ifdef FEATURE_WLAN_LFR + && ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1) +#endif + ) + { + pNeighborRoamInfo->currentNeighborLookupThreshold += 3; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Clear off the old neighbor report details */ + vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif + + /* Transition to CONNECTED state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + sessionId); + + /* Reset all the necessary variables before transitioning to the CONNECTED state */ + csrNeighborRoamResetConnectedStateControlInfo(pMac, sessionId); + +#ifdef FEATURE_WLAN_LFR + if (pNeighborRoamInfo->uEmptyScanCount == eFirstEmptyScan) + { +#endif + /* Empty scan results for the first time */ + /* Re-register neighbor lookup DOWN threshold callback with TL */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); + + vos_mem_free(pUsrCtx); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback" + " with TL: Status = %d"), status); + } + +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; + } + else if ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) || + (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan)) + { + /* Empty scan results for the second or fourth time */ + + /* Immediately scan on channels in non-occupied list */ + csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + } + else if (pNeighborRoamInfo->uEmptyScanCount >= eThirdEmptyScan) + { + /* Empty scan results for the third time */ + if (performPeriodicScan) + { + smsLog(pMac, LOGE, FL("Performing periodic scan, uEmptyScanCount=%d"), + pNeighborRoamInfo->uEmptyScanCount); + + /* + * Set uEmptyScanCount to MAX so that we always enter this + * condition on subsequent empty scan results + */ + pNeighborRoamInfo->uEmptyScanCount = eMaxEmptyScan; + + /* From here on, ONLY scan on channels in the occupied list */ + pNeighborRoamInfo->uScanMode = SPLIT_SCAN_OCCUPIED_LIST; + + /* Start empty scan refresh timer */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&pNeighborRoamInfo->emptyScanRefreshTimer, + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod)) + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer failed to start (%d)"), + status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + vosStatus = VOS_STATUS_E_FAILURE; + } + else + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer started (%d ms)"), + (pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod)); + } + } + else if (eThirdEmptyScan == pNeighborRoamInfo->uEmptyScanCount) + { + /* Start neighbor scan results refresh timer */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod)) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start (%d)"), + status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + vosStatus = VOS_STATUS_E_FAILURE; + } + else + { + smsLog(pMac, LOG2, FL("Neighbor results refresh timer started (%d ms)"), + (pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * VOS_TIMER_TO_MS_UNIT)); + } + } + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Neighbor roam empty scan count=%d scan mode=%d", + pNeighborRoamInfo->uEmptyScanCount, pNeighborRoamInfo->uScanMode); +#endif + return vosStatus; +} + + +static eHalStatus csrNeighborRoamProcessScanComplete (tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrScanResultFilter scanFilter; + tScanResultHandle scanResult; + tANI_U32 tempVal = 0; + tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE; + eHalStatus hstatus; + tpFTRoamCallbackUsrCtx pUsrCtx; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we + should use the BSSID filter made out of neighbor reports */ + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (!csrRoamIsRoamOffloadScanEnabled(pMac)) +#endif + ) + { + hstatus = csrNeighborRoamBssIdScanFilter(pMac, sessionId, &scanFilter); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R or ESE Association: Prepare scan filter status with neighbor AP = %d"), hstatus); + tempVal = 1; + } + else +#endif + { + hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, + &scanFilter, sessionId); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R/ESE/Other Association: Prepare scan to find neighbor AP filter status = %d"), hstatus); + } + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal); + return eHAL_STATUS_FAILURE; + } + hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult); + if (hstatus != eHAL_STATUS_SUCCESS) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus); + } + /* Process the scan results and update roamable AP list */ + roamNow = csrNeighborRoamProcessScanResults(pMac, sessionId, + &scanResult); + + /* Free the scan filter */ + csrFreeScanFilter(pMac, &scanFilter); + + tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + switch(pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + if (tempVal) + { +#ifdef FEATURE_WLAN_LFR + /* + * Since there are non-zero candidates found + * after the scan, reset empty scan count. + */ + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + /* If this is a non-11r association, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (pNeighborRoamInfo->is11rAssoc) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + sessionId) + } + else +#endif +#ifdef FEATURE_WLAN_ESE + /* If this is a non-11r association, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (pNeighborRoamInfo->isESEAssoc) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + sessionId) + } + else +#endif +#ifdef FEATURE_WLAN_LFR + /* If LFR is enabled, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + sessionId) + } + else +#endif + { + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback")); + /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */ + /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we + need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL + within certain duration */ + +// vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + } + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("No candidate found after" + "scanning in state %s .. "), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + /* Handle it appropriately */ + csrNeighborRoamHandleEmptyScanResult(pMac, sessionId); + } + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + if (!tempVal) + { + smsLog(pMac, LOGE, + FL("No candidate found after scanning" + "in state %s .. "), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */ + csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + default: + // Can come only in INIT state. Where in we are associated, we sent scan and user + // in the meantime decides to disassoc, we will be in init state and still received call + // back issued. Should not come here in any other state, printing just in case + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("State %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + // Lets just exit out silently. + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + if (tempVal) + { + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (roamNow) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Immediate roam-deregister UP indication. RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't deregister lookup UP callback with TL: Status = %d"), vosStatus); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + csrNeighborRoamTriggerHandoff(pMac, sessionId); + return eHAL_STATUS_SUCCESS; + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + hstatus = vos_timer_start( + &pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod); + + /* This timer should be started before registering the Reassoc + * callback with TL. This is because, it is very likely that the + * callback getting called immediately and the timer would never + * be stopped when pre-auth is in progress */ + if (hstatus != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL( + "Neighbor results refresh timer failed to start, status = %d"), + hstatus); + vos_mem_free( + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = + NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = + 0; + return eHAL_STATUS_FAILURE; + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL( + "Registering DOWN event Reassoc callback with TL. RSSI = %d"), + pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Allocation failed for pUsrCtx")); + return eHAL_STATUS_FAILURE; + } + + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + /* Register a reassoc Indication callback */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL( + "Couldn't register with TL: Status = %d"), + vosStatus); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + if (!tempVal || !roamNow) + { + if (pNeighborRoamInfo->uOsRequestedHandoff) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + else + { + /* There is no candidate or We are not roaming Now. + * Inform the FW to restart Roam Offload Scan */ + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_RESTART, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + } + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + sessionId); + } + } +#endif + return eHAL_STATUS_SUCCESS; + +} + + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamScanRequestCallback + + \brief This function is the callback function registered in csrScanRequest() to + indicate the completion of scan. If scan is completed for all the channels in + the channel list, this function gets the scan result and starts the refresh results + timer to avoid having stale results. If scan is not completed on all the channels, + it restarts the neighbor scan timer which on expiry issues scan on the next + channel + + \param halHandle - The handle returned by macOpen. + pContext - not used + scanId - not used + status - not used + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, + void *pContext, tANI_U8 sessionId, + tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 currentChanIndex; + eHalStatus hstatus; + + if (NULL != pContext) + { +#ifdef FEATURE_WLAN_LFR + if (!csrRoamIsStaMode(pMac, sessionId)) + { + smsLog(pMac, LOGE, + FL("Ignoring scan request callback on non-infra" + "session %d in state %s"), + sessionId, macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (!csrRoamIsFastRoamEnabled(pMac,sessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } +#endif + } + + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + /* -1 is done because the chanIndex would have got incremented after + issuing a successful scan request */ + currentChanIndex = (pNeighborRoamInfo->roamChannelInfo.currentChanIndex) ? (pNeighborRoamInfo->roamChannelInfo.currentChanIndex - 1) : 0; + + /* Validate inputs */ + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("csrNeighborRoamScanRequestCallback received for Channel = %d, " + "ChanIndex = %d"), + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], + currentChanIndex); + } + else + { + smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event.")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress) + { + /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state + just to get the results and perform PREAUTH */ + /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter + sort the results based on neighborScore and RSSI and select the best candidate out of the list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex); + + if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex != 0) + { + VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0); + return eHAL_STATUS_FAILURE; + } + + hstatus = csrNeighborRoamProcessScanComplete(pMac, sessionId); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_FAILURE; + } + } + else + { + + /* Restart the timer for the next scan sequence as scanning is not over */ + hstatus = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + if (eHAL_STATUS_SUCCESS != hstatus) + { + /* Timer start failed.. Should we ASSERT here??? */ + smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_FAILURE; + } + } + + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamScanResultRequestCallback + + \brief This function is the callback function registered in csrScanRequestLfrResult() to + indicate the completion of scan. If scan is completed for all the channels in + the channel list, this function gets the scan result and treats them as candidates + + \param halHandle - The handle returned by macOpen. + pContext - not used + scanId - not used + status - not used + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamScanResultRequestCallback(tHalHandle halHandle, + void *pContext, + tANI_U8 sessionId, + tANI_U32 scanId, + eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus hstatus; + + smsLog(pMac, LOG2, FL("called ")); + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGW, FL("Received in not CONNECTED state. Ignore it")); + return eHAL_STATUS_SUCCESS; + } + + /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter + sort the results based on neighborScore and RSSI and select the best candidate out of the list */ + + hstatus = csrNeighborRoamProcessScanComplete(pMac, sessionId); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef FEATURE_WLAN_LFR +static eHalStatus csrNeighborRoamContiguousScanRequestCallback(tHalHandle halHandle, + void *pContext, tANI_U8 sessionId, + tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus hstatus = eHAL_STATUS_SUCCESS; + + if (NULL != pContext) + { + sessionId = *((tANI_U32*)pContext); + if (!csrRoamIsFastRoamEnabled(pMac,sessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + } + + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in INIT state. Must have disconnected. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: process scan results", __func__); + hstatus = csrNeighborRoamProcessScanComplete(pMac, sessionId); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + } + + if (NULL != pContext) + vos_mem_free(pContext); + + return hstatus; +} +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssueBgScanRequest + + \brief This function issues CSR scan request after populating all the BG scan params + passed + + \param pMac - The handle returned by macOpen. + pBgScanParams - Params that need to be populated into csr Scan request + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, + tCsrBGScanRequest *pBgScanParams, + tANI_U32 sessionId, + csrScanCompleteCallback callbackfn) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 scanId; + tCsrScanRequest scanReq; + tANI_U8 channel; + void * userData = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel = %d, ChanIndex = %d"), + pBgScanParams->ChannelInfo.ChannelList[0], + pNeighborRoamInfo->roamChannelInfo.currentChanIndex); + + //send down the scan req for 1 channel on the associated SSID + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + /* Fill in the SSID Info */ + scanReq.SSIDs.numOfSSIDs = 1; + scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs); + if (NULL == scanReq.SSIDs.SSIDList) + { + //err msg + smsLog(pMac, LOGE, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List")); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs); + + scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE; + scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE; + vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID)); + + scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels; + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + { + channel = pBgScanParams->ChannelInfo.ChannelList[0]; + scanReq.ChannelInfo.ChannelList = &channel; + } + else + { + scanReq.ChannelInfo.ChannelList = pBgScanParams->ChannelInfo.ChannelList; + } + + scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = eCSR_SCAN_HO_BG_SCAN; + scanReq.maxChnTime = pBgScanParams->maxChnTime; + scanReq.minChnTime = pBgScanParams->minChnTime; + + userData = vos_mem_malloc(sizeof(tANI_U32)); + if (NULL == userData) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory for scan request")); + vos_mem_free(scanReq.SSIDs.SSIDList); + return eHAL_STATUS_FAILURE; + } + *((tANI_U32*)userData) = sessionId; + status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq, + &scanId, callbackfn, (void *) userData); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status); + vos_mem_free(scanReq.SSIDs.SSIDList); + vos_mem_free(userData); + return status; + } + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_TRUE; + + vos_mem_free(scanReq.SSIDs.SSIDList); + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, + FL("Channel List Address = %p, Actual index = %d"), + &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0], + pNeighborRoamInfo->roamChannelInfo.currentChanIndex); + + return status; +} + +static void csrNeighborRoamFillNonChannelBgScanParams (tpAniSirGlobal pMac, + tANI_U8 sessionId, + tpCsrBGScanRequest bgScanParams) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + vos_mem_copy(bgScanParams->bssid, broadcastBssid, sizeof(tCsrBssid)); + bgScanParams->SSID.length = + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length; + vos_mem_copy(bgScanParams->SSID.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length); + + bgScanParams->minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime; + bgScanParams->maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPerformBgScan + + \brief This function is invoked on every expiry of neighborScanTimer till all + the channels in the channel list are scanned. It populates necessary + parameters for BG scan and calls appropriate AP to invoke the CSR scan + request + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrBGScanRequest bgScanParams; + tANI_U8 channel = 0; + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %p"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty")); + // Go back and restart. Mostly timer start failure has occurred. + // When timer start is declared a failure, then we delete the list. + // Should not happen now as we stop and then only start the scan timer. + // still handle the unlikely case. + csrNeighborRoamHandleEmptyScanResult(pMac, sessionId); + return status; + } + + /* Validate the currentChanIndex value before using it to index the ChannelList array */ + if ( pNeighborRoamInfo->roamChannelInfo.currentChanIndex + > pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Invalid channel index: %d"), pNeighborRoamInfo->roamChannelInfo.currentChanIndex); + // Go back and restart. + csrNeighborRoamHandleEmptyScanResult(pMac, sessionId); + return status; + } + + /* Need to perform scan here before getting the list */ + + vos_mem_set(&bgScanParams, sizeof(tCsrBGScanRequest), 0); + + channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex]; + bgScanParams.ChannelInfo.numOfChannels = 1; + bgScanParams.ChannelInfo.ChannelList = &channel; + + csrNeighborRoamFillNonChannelBgScanParams(pMac, sessionId, &bgScanParams); + /* Update the passive scan time for DFS channel */ + if ((TRUE == CSR_IS_CHANNEL_DFS(channel)) && + (CSR_ROAMING_DFS_CHANNEL_DISABLED != + pMac->roam.configParam.allowDFSChannelRoam)) + { + bgScanParams.minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + bgScanParams.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + } + + status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams, + sessionId, csrNeighborRoamScanRequestCallback); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status); + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex++; + if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >= + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"), + pNeighborRoamInfo->roamChannelInfo.currentChanIndex, + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels); + /* We have completed scanning all the channels */ + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results + and select the best AP in the list */ + if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress) + { + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + } + } + + if (eHAL_STATUS_SUCCESS != status) + { + /* + * If the status is not success, we need to call the callback + * routine so that the state machine does not get stuck. + */ + csrNeighborRoamScanRequestCallback(pMac, NULL, sessionId, 0, + eCSR_SCAN_FAILURE); + } + + return status; +} + +#ifdef FEATURE_WLAN_LFR +eHalStatus csrNeighborRoamPerformContiguousBgScan(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBGScanRequest bgScanParams; + tANI_U8 numOfChannels = 0, i = 0; + tANI_U8 *channelList = NULL; + tANI_U8 *pInChannelList = NULL; + tANI_U8 tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + vos_mem_set(&bgScanParams, sizeof(tCsrBGScanRequest), 0); + + /* Contiguously scan all channels from valid list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("get valid channel list")); + + numOfChannels = sizeof(pMac->roam.validChannelList); + + if(!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + (tANI_U32 *) &numOfChannels))) + { + smsLog(pMac, LOGE, FL("Could not get valid channel list")); + return eHAL_STATUS_FAILURE; + } + pInChannelList = pMac->roam.validChannelList; + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByCurrentBand( + pMac, + sessionId, + pInChannelList, + numOfChannels, + tmpChannelList, + &numOfChannels); + pInChannelList = tmpChannelList; + } + + channelList = vos_mem_malloc(numOfChannels); + if ( NULL == channelList ) + { + smsLog(pMac, LOGE, FL("could not allocate memory for channelList")); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(channelList, (tANI_U8 *)pInChannelList, + numOfChannels * sizeof(tANI_U8)); + + bgScanParams.ChannelInfo.numOfChannels = numOfChannels; + bgScanParams.ChannelInfo.ChannelList = channelList; + for (i = 0; i < numOfChannels; i++) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: valid channel list = %d", + __func__, bgScanParams.ChannelInfo.ChannelList[i]); + } + csrNeighborRoamFillNonChannelBgScanParams(pMac, sessionId, &bgScanParams); + + status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams, + sessionId, csrNeighborRoamContiguousScanRequestCallback); + + vos_mem_free(channelList); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status); + } + + return status; +} +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborScanTimerCallback + + \brief This function is the neighbor scan timer callback function. It invokes + the BG scan request based on the current and previous states + + \param pv - CSR timer context info which includes pMac and session ID + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamNeighborScanTimerCallback(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tANI_U32 sessionId = pInfo->sessionId; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + // check if bg scan is on going, no need to send down the new params if true + if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending) + { + //msg + smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending")); + return; + } + + switch (pNeighborRoamInfo->neighborRoamState) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + switch(pNeighborRoamInfo->prevNeighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY: + csrNeighborRoamPerformBgScan(pMac, sessionId); + break; + default: + smsLog(pMac, LOGE, + FL("Neighbor scan callback received in" + "state %s, prev state = %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->prevNeighborRoamState)); + break; + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + csrNeighborRoamPerformBgScan(pMac, sessionId); + break; + default: + break; + } + return; +} + +void csrNeighborRoamEmptyScanRefreshTimerCallback(void *context) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context; + tpAniSirGlobal pMac = pInfo->pMac; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tANI_U32 sessionId = pInfo->sessionId; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + /* Reset all the variables just as no scan had happened before */ + csrNeighborRoamResetConnectedStateControlInfo(pMac, sessionId); + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY, + sessionId) + } else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or ESE Association:empty scan refresh timer expired")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + return; + } + } + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResultsRefreshTimerCallback + + \brief This function is the timer callback function for results refresh timer. + When this is invoked, it is as good as down event received from TL. So, + clear off the roamable AP list and start the scan procedure based on 11R + or non-11R association + + \param context - CSR timer context info which includes pMac and session ID + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResultsRefreshTimerCallback(void *context) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context; + tpAniSirGlobal pMac = pInfo->pMac; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tANI_U32 sessionId = pInfo->sessionId; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pInfo->sessionId]; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d"), vosStatus); + } + + /* Reset all the variables just as no scan had happened before */ + csrNeighborRoamResetConnectedStateControlInfo(pMac, pInfo->sessionId); + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY, + sessionId) + } + else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or ESE Association:results refresh timer expired")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + return; + } + } + return; +} + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssueNeighborRptRequest + + \brief This function is invoked when TL issues a down event and the current assoc + is a 11R association. It invokes SME RRM API to issue the neighbor request to + the currently associated AP with the current SSID + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tRrmNeighborRspCallbackInfo callbackInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tRrmNeighborReq neighborReq; + tpFTRoamCallbackUsrCtx pUsrCtx; + + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + neighborReq.no_ssid = 0; + + /* Fill in the SSID */ + neighborReq.ssid.length = + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length; + vos_mem_copy(neighborReq.ssid.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length); + + callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult; + callbackInfo.neighborRspCallbackContext = pUsrCtx; + callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout; + + return sme_NeighborReportRequest(pMac, sessionId, &neighborReq, + &callbackInfo); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamChannelsFilterByCurrentBand + + \brief This function is used to filter out the channels + based on the currently associated AP channel + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The input channel list + \param inputNumOfChannels - The number of channels in input channel list + \param pOutputChannelList - The output channel list + \param outputNumOfChannels - The number of channels in output channel list + \param pMergedOutputNumOfChannels - The final number of channels in the output channel list. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ + +VOS_STATUS csrNeighborRoamChannelsFilterByCurrentBand( + tpAniSirGlobal pMac, + tANI_U8 sessionId, + tANI_U8* pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8* pOutputChannelList, + tANI_U8* pMergedOutputNumOfChannels + ) +{ + tANI_U8 i = 0; + tANI_U8 numChannels = 0; + tANI_U8 currAPoperationChannel = + pMac->roam.neighborRoamInfo[sessionId].currAPoperationChannel; + // Check for NULL pointer + if (!pInputChannelList) return VOS_STATUS_E_INVAL; + + // Check for NULL pointer + if (!pOutputChannelList) return VOS_STATUS_E_INVAL; + + if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Input Channels %d", + __func__, inputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + for (i = 0; i < inputNumOfChannels; i++) + { + if (GetRFBand(currAPoperationChannel) == GetRFBand(pInputChannelList[i])) + { + pOutputChannelList[numChannels] = pInputChannelList[i]; + numChannels++; + } + } + + // Return final number of channels + *pMergedOutputNumOfChannels = numChannels; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamMergeChannelLists + + \brief This function is used to merge two channel list. + NB: If called with outputNumOfChannels == 0, this routines + simply copies the input channel list to the output channel list. + if number of merged channels are more than 100, num of channels + set to 100 + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The additional channels to merge in to the "merged" channels list. + \param inputNumOfChannels - The number of additional channels. + \param pOutputChannelList - The place to put the "merged" channel list. + \param outputNumOfChannels - The original number of channels in the "merged" channels list. + \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamMergeChannelLists( + tpAniSirGlobal pMac, + tANI_U8 *pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 outputNumOfChannels, + tANI_U8 *pMergedOutputNumOfChannels + ) +{ + tANI_U8 i = 0; + tANI_U8 j = 0; + tANI_U8 numChannels = outputNumOfChannels; + + // Check for NULL pointer + if (!pInputChannelList) return VOS_STATUS_E_INVAL; + + // Check for NULL pointer + if (!pOutputChannelList) return VOS_STATUS_E_INVAL; + + if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Input Channels %d", + __func__, inputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + if (outputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Output Channels %d", + __func__, outputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + // Add the "new" channels in the input list to the end of the output list. + for (i = 0; i < inputNumOfChannels; i++) + { + for (j = 0; j < outputNumOfChannels; j++) + { + if (pInputChannelList[i] == pOutputChannelList[j]) + break; + } + if (j == outputNumOfChannels) + { + if (pInputChannelList[i]) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding extra %d to Neighbor channel list", __func__, + pInputChannelList[i]); + pOutputChannelList[numChannels] = pInputChannelList[i]; + numChannels++; + } + } + if (numChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Merge Neighbor channel list reached Max " + "limit %d", __func__, + numChannels); + break; + } + } + + // Return final number of channels + *pMergedOutputNumOfChannels = numChannels; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamCreateChanListFromNeighborReport + + \brief This function is invoked when neighbor report is received for the + neighbor request. Based on the channels present in the neighbor report, + it generates channel list which will be used in REPORT_SCAN state to + scan for these neighbor APs + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpRrmNeighborReportDesc pNeighborBssDesc; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 numChannels = 0; + tANI_U8 i = 0; + tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT]; + tANI_U8 mergedOutputNumOfChannels = 0; + + /* This should always start from 0 whenever we create a channel list out of neighbor AP list */ + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + + pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac); + + while (pNeighborBssDesc) + { + if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break; + + /* Update the neighbor BSS Info in the 11r FT Roam Info */ + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum = + pNeighborBssDesc->pNeighborBssDescription->channel; + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore = + (tANI_U8)pNeighborBssDesc->roamScore; + vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId, + pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++; + + /* Saving the channel list non-redundantly */ + for (i = 0; (i < numChannels && i < MAX_BSS_IN_NEIGHBOR_RPT); i++) + { + if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i]) + break; + } + + if (i == numChannels) + { + if (pNeighborBssDesc->pNeighborBssDescription->channel) + { + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + // Make sure to add only if its the same band + if (GetRFBand(pNeighborRoamInfo->currAPoperationChannel) == + GetRFBand(pNeighborBssDesc->pNeighborBssDescription->channel)) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding %d to Neighbor channel list (Same band)\n", __func__, + pNeighborBssDesc->pNeighborBssDescription->channel); + channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel; + numChannels++; + } + } + else + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__, + pNeighborBssDesc->pNeighborBssDescription->channel); + channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel; + numChannels++; + } + } + } + + pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc); + } + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + } + + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + /* Store the obtained channel list to the Neighbor Control data structure */ + if (numChannels) + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8)); + if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored")); + return VOS_STATUS_E_RESOURCES; + } + + vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, + channelList, (numChannels) * sizeof(tANI_U8)); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels; + /* + * Create a Union of occupied channel list learnt by the DUT along with the Neighbor + * report Channels. This increases the chances of the DUT to get a candidate AP while + * roaming even if the Neighbor Report is not able to provide sufficient information. + * */ + if (pMac->scan.occupiedChannels[sessionId].numChannels) { + csrNeighborRoamMergeChannelLists(pMac, + &pMac->scan.occupiedChannels[sessionId].channelList[0], + pMac->scan.occupiedChannels[sessionId].numChannels, + &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0], + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels, + &mergedOutputNumOfChannels); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = + mergedOutputNumOfChannels; + + } + /*Indicate the firmware about the update only if any new channels are added. + * Otherwise, the firmware would already be knowing the non-IAPPneighborlist + * channels. There is no need to update.*/ + if (numChannels) + { + smsLog(pMac, LOG1, + FL("IAPP Neighbor list callback received as expected" + "in state %s."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_CHANNEL_LIST_CHANGED); + } +#endif + } + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRRMNeighborReportResult + + \brief This function is the neighbor report callback that will be invoked by + SME RRM on receiving a neighbor report or of neighbor report is not + received after timeout. On receiving a valid report, it generates a + channel list from the neighbor report and starts the + neighbor scan timer + + \param context - The handle returned by macOpen. + vosStatus - Status of the callback(SUCCESS/FAILURE) + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus) +{ + tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *)context; + tANI_U32 sessionId = pUsrCtx->sessionId; + tpAniSirGlobal pMac = pUsrCtx->pMac; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d"), vosStatus); + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY: + /* Reset the report pending variable */ + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */ + vosStatus = csrNeighborRoamCreateChanListFromNeighborReport( + pMac, + sessionId); + if (VOS_STATUS_SUCCESS == vosStatus) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state")); + } + + /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */ + pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + /* Now ready for neighbor scan based on the channel list created */ + status = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + if (eHAL_STATUS_SUCCESS != status) + { + /* Timer start failed.. Should we ASSERT here??? */ + smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + vos_mem_free(pUsrCtx); + return; + } + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + /* Neighbor scan timer started. Transition to REPORT_SCAN state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + sessionId) + } + else + { + /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we + reach the maxNeighborRetries or receiving a successful neighbor response */ + smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d"), + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries); + if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >= + pNeighborRoamInfo->cfgParams.maxNeighborRetries) + { + smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. ")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, + sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d "), vosStatus); + vos_mem_free(pUsrCtx); + return; + } + /* We transitioned to different state now. Reset the Neighbor report retry count */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + } + else + { + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac, + sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + vos_mem_free(pUsrCtx); + return; + } + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + } + } + break; + default: + smsLog(pMac, LOGE, + FL("Neighbor result callback not expected in" + "state %s, Ignoring.."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + } + vos_mem_free(pUsrCtx); + return; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +#ifdef FEATURE_WLAN_LFR +tANI_BOOLEAN csrNeighborRoamIsSsidAndSecurityMatch( + tpAniSirGlobal pMac, + tCsrRoamConnectedProfile *pCurProfile, + tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tCsrAuthList authType; + tCsrEncryptionList uCEncryptionType; + tCsrEncryptionList mCEncryptionType; + tANI_BOOLEAN fMatch = FALSE; + + authType.numEntries = 1; + authType.authType[0] = pCurProfile->AuthType; + uCEncryptionType.numEntries = 1; + uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType; + mCEncryptionType.numEntries = 1; + mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType; + + if( pIes ) + { + if(pIes->SSID.present) + { + fMatch = csrIsSsidMatch( pMac, + (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length, + pIes->SSID.ssid, pIes->SSID.num_ssid, + eANI_BOOLEAN_TRUE ); + if(TRUE == fMatch) + { + /* + * for now we are sending NULL for all PMF related filter + * parameters during roam to the neighbor AP because + * so far 80211W spec doesn't specify anything about + * roaming scenario. + * + * Once roaming scenario is defined, we should re-visit + * this section and remove this comment. + */ + fMatch = csrIsSecurityMatch(pMac, &authType, &uCEncryptionType, + &mCEncryptionType, + NULL, NULL, NULL, + pBssDesc, pIes, NULL, NULL, NULL); + return (fMatch); + } + else + { + return (fMatch); + } + + } + else + { + return FALSE; // Treat a missing SSID as a non-match. + } + } + else + { + return FALSE; // Again, treat missing pIes as a non-match. + } +} + +tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrRoamConnectedProfile *pCurrProfile = NULL; + tCsrRoamConnectedProfile *pPrevProfile = NULL; + tDot11fBeaconIEs *pIes = NULL; + tSirBssDescription *pBssDesc = NULL; + tANI_BOOLEAN fNew = TRUE; + + if(!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId))) + { + return (fNew); + } + + pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + if( !pCurrProfile ) + { + return (fNew); +} + + pPrevProfile = &pNeighborRoamInfo->prevConnProfile; + if( !pPrevProfile ) + { + return (fNew); + } + + pBssDesc = pPrevProfile->pBssDesc; + if (pBssDesc) + { + if (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pBssDesc, &pIes)) && + csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurrProfile, pBssDesc, pIes)) + { + fNew = FALSE; + } + if (pIes) + { + vos_mem_free(pIes); + } + } + + if (fNew) + { + smsLog(pMac, LOG1, FL("Prev roam profile did not match current")); + } + else + { + smsLog(pMac, LOG1, FL("Prev roam profile matches current")); + } + + return (fNew); +} + +tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch( + tpAniSirGlobal pMac, + tANI_U8 sessionId, + tCsrScanResult *pResult, + tDot11fBeaconIEs *pIes) +{ + tCsrRoamConnectedProfile *pCurProfile = NULL; + tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor; + + if( !(pMac->roam.roamSession + && CSR_IS_SESSION_VALID(pMac, sessionId))) + { + return FALSE; + } + + pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + + if( !pCurProfile) + { + return FALSE; + } + + return csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurProfile, pBssDesc, pIes); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPrepareNonOccupiedChannelList + + \brief This function is used to prepare a channel list that is derived from + the list of valid channels and does not include those in the occupied + list. + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The default channels list. + \param numOfChannels - The number of channels in the default channels list. + \param pOutputChannelList - The place to put the non-occupied channel list. + \param pOutputNumOfChannels - The number of channels in the non-occupied channel list. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamPrepareNonOccupiedChannelList( + tpAniSirGlobal pMac, + tANI_U8 sessionId, + tANI_U8 *pInputChannelList, + tANI_U8 numOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 *pOutputNumOfChannels + ) +{ + tANI_U8 i = 0; + tANI_U8 outputNumOfChannels = 0; // Clear the output number of channels + tANI_U8 numOccupiedChannels = + pMac->scan.occupiedChannels[sessionId].numChannels; + tANI_U8 *pOccupiedChannelList = + pMac->scan.occupiedChannels[sessionId].channelList; + + for (i = 0; i < numOfChannels; i++) + { + if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, + pInputChannelList[i])) + { + /* DFS channel will be added in the list only when the + DFS Roaming scan flag is enabled*/ + if (CSR_IS_CHANNEL_DFS(pInputChannelList[i])) + { + if (CSR_ROAMING_DFS_CHANNEL_DISABLED != + pMac->roam.configParam.allowDFSChannelRoam) + { + pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i]; + } + } + else + { + pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i]; + } + } + } + + smsLog(pMac, LOG2, FL("Number of channels in the valid channel list=%d; " + "Number of channels in the non-occupied list list=%d"), + numOfChannels, outputNumOfChannels); + + // Return the number of channels + *pOutputNumOfChannels = outputNumOfChannels; + + return eHAL_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_LFR */ + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamTransitToCFGChanScan + + \brief This function is called whenever there is a transition to CFG chan scan + state from any state. It frees up the current channel list and allocates + a new memory for the channels received from CFG item. It then starts the + neighbor scan timer to perform the scan on each channel one by one + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + int i = 0; + tANI_U8 numOfChannels = 0; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tpCsrChannelInfo currChannelListInfo; + currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + + if ( +#ifdef FEATURE_WLAN_ESE + ((pNeighborRoamInfo->isESEAssoc) && + (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) || + (pNeighborRoamInfo->isESEAssoc == eANI_BOOLEAN_FALSE) || +#endif // ESE + currChannelListInfo->numOfChannels == 0) + { + smsLog(pMac, LOGW, FL("Building channel list to scan")); + + + /* Free up the channel list and allocate a new memory. This is because we dont know how much + was allocated last time. If we directly copy more number of bytes than allocated earlier, this might + result in memory corruption */ + if (NULL != currChannelListInfo->ChannelList) + { + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + } + + // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER + // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR. + if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini". + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini"); + status = csrNeighborRoamMergeChannelLists( + pMac, + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels, + channelList, + 0, //NB: If 0, simply copy the input channel list to the output list. + &numOfChannels ); + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByCurrentBand( + pMac, + sessionId, + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels, + channelList, + &numOfChannels); + } + if(numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + smsLog(pMac, LOGE, FL("Received wrong number of Channel list")); + return VOS_STATUS_E_INVAL; + } + currChannelListInfo->ChannelList = + vos_mem_malloc(numOfChannels*sizeof(tANI_U8)); + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } + vos_mem_copy(currChannelListInfo->ChannelList, + channelList, numOfChannels * sizeof(tANI_U8)); + } +#ifdef FEATURE_WLAN_LFR + else if ((pNeighborRoamInfo->uScanMode == DEFAULT_SCAN) && + (abs(pNeighborRoamInfo->lookupDOWNRssi) > + abs(pNeighborRoamInfo->cfgParams.neighborReassocThreshold))) + { + /* + * Trigger a contiguous scan on all channels when the + * RSSI in the lookup DOWN notification is below reassoc + * threshold. This will help us find the best available + * candidate and also update the channel cache. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Triggering contiguous scan " + "(lookupDOWNRssi=%d,reassocThreshold=%d)", + pNeighborRoamInfo->lookupDOWNRssi, + pNeighborRoamInfo->cfgParams.neighborReassocThreshold*(-1)); + + pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + + csrNeighborRoamPerformContiguousBgScan(pMac, sessionId); + + /* Transition to CFG_CHAN_LIST_SCAN */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN, + sessionId); + + return VOS_STATUS_SUCCESS; + } +#endif + else + { + numOfChannels = pMac->scan.occupiedChannels[sessionId].numChannels; + if (numOfChannels +#ifdef FEATURE_WLAN_LFR + && ((pNeighborRoamInfo->uScanMode == SPLIT_SCAN_OCCUPIED_LIST) || + (pNeighborRoamInfo->uEmptyScanCount == 0) || + ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1)) +#endif + ) + { + /* + * Always scan channels in the occupied channel list + * before scanning on the non-occupied list. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Switching to occupied channel list" +#ifdef FEATURE_WLAN_LFR + "-uScanMode=%d, uEmptyScanCount=%d", + pNeighborRoamInfo->uScanMode, + pNeighborRoamInfo->uEmptyScanCount +#endif + ); + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByCurrentBand( + pMac, + sessionId, + pMac->scan.occupiedChannels[sessionId].channelList, + numOfChannels, + channelList, + &numOfChannels); + } + else + { + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + vos_mem_copy(channelList, + pMac->scan.occupiedChannels[sessionId].channelList, + numOfChannels * sizeof(tANI_U8)); + } + + currChannelListInfo->ChannelList = vos_mem_malloc(numOfChannels * sizeof(tANI_U8)); + + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + vos_mem_copy(currChannelListInfo->ChannelList, + channelList, + numOfChannels * sizeof(tANI_U8)); + } + else + { + /* Scan all channels from non-occupied list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Get valid channel list"); + numOfChannels = sizeof(pMac->roam.validChannelList); + + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + (tANI_U32 *) &numOfChannels))) + { + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } +#ifdef FEATURE_WLAN_LFR + /* + * Prepare non-occupied channel list (channelList) + * from the actual "valid channel list" information + * formed by CSR. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to non-occupied channel list"); + status = csrNeighborRoamPrepareNonOccupiedChannelList(pMac, + sessionId, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, + channelList, + &numOfChannels); +#else + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Merging channel list"); + status = csrNeighborRoamMergeChannelLists( + pMac, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, // The number of channels in the validChannelList + channelList, + 0, //NB: If 0, simply copy the input channel list to the output list. + &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels +#endif + } + else + { + smsLog(pMac, LOGE, FL("Could not get valid channel list")); + return VOS_STATUS_E_FAILURE; + } + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByCurrentBand( + pMac, + sessionId, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, + channelList, + &numOfChannels); + } + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + + currChannelListInfo->ChannelList = + vos_mem_malloc(numOfChannels*sizeof(tANI_U8)); + + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } +#ifdef FEATURE_WLAN_LFR + vos_mem_copy(currChannelListInfo->ChannelList, + channelList, numOfChannels * sizeof(tANI_U8)); +#else + vos_mem_copy(currChannelListInfo->ChannelList, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels * sizeof(tANI_U8)); +#endif + } + } + + /* Adjust for the actual number that are used */ + currChannelListInfo->numOfChannels = numOfChannels; + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + "Number of channels from CFG (or) (non-)occupied list=%d", + currChannelListInfo->numOfChannels); + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Channel List from CFG (or) (non-)occupied list" + "= %d", currChannelListInfo->ChannelList[i]); + } + } + + /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */ + pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + status = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + + if (eHAL_STATUS_SUCCESS != status) + { + /* Timer start failed.. */ + smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status); + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + return VOS_STATUS_E_FAILURE; + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE; + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + + /* We are about to start a fresh scan cycle, + * purge failed pre-auth results from the past */ + csrNeighborRoamPurgePreauthFailedList(pMac); + + /* Transition to CFG_CHAN_LIST_SCAN_STATE */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN, + sessionId) + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupUpEvent + + \brief This function is called as soon as TL indicates that the current AP's + RSSI is better than the neighbor lookup threshold. Here, we transition to + CONNECTED state and reset all the scan parameters + + \param pMac - The handle returned by macOpen. + \param sessionId - Session ID + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus; + tpFTRoamCallbackUsrCtx pUsrCtx; + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); + + /* Recheck whether the below check is needed. */ + if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + sessionId) +#ifdef FEATURE_WLAN_LFR + if (!csrRoamIsFastRoamEnabled(pMac, sessionId)) { + smsLog(pMac, LOGE, FL("LookUp event received when fast roam is " + "disabled. Ignore it")); + return eHAL_STATUS_SUCCESS; + } +#endif + /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */ + csrNeighborRoamResetConnectedStateControlInfo(pMac, sessionId); + + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + /* Register Neighbor Lookup threshold callback with TL for DOWN event now */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; +#endif + vos_mem_free(pUsrCtx); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d"), vosStatus); + } + + + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupDownEvent + + \brief This function is called as soon as TL indicates that the current AP's + RSSI falls below the current eighbor lookup threshold. Here, we transition to + REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is + a non-11R association. + + \param pMac - The handle returned by macOpen. + \param sessionId - Session Id + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpFTRoamCallbackUsrCtx pUsrCtx; + + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED: + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + /* De-register Neighbor Lookup threshold callback with TL */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d"), vosStatus); + } +#ifdef FEATURE_WLAN_LFR + if (!csrRoamIsFastRoamEnabled(pMac, sessionId)) { + smsLog(pMac, LOGE, FL("LookDown event received when fast roam " + "is disabled. Ignore it")); + return eHAL_STATUS_SUCCESS; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac, + sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return vosStatus; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY, + sessionId) + } + else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or ESE Association:Neighbor Lookup Down event received in CONNECTED state")); + + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamTransitToCFGChanScan failed" + " with status=%d"), vosStatus); + return vosStatus; + } + } + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + /* Register Neighbor Lookup threshold callback with TL for UP event now */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME, pUsrCtx); + vos_mem_free(pUsrCtx); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, + FL(" Couldn't register csrNeighborRoamNeighborLookupCallback" + "UP event with TL: Status = %d"), + status); + } + break; + default: + smsLog(pMac, LOGE, FL("DOWN event received in invalid" + "state %s ..Ignoring..."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + + } + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupUPCallback + + \brief This function is registered with TL to indicate whenever the RSSI + gets better than the neighborLookup RSSI Threshold + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS +csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *)pUserCtxt; + tANI_U32 sessionId = pUsrCtx->sessionId; + tpAniSirGlobal pMac = pUsrCtx->pMac; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup UP indication callback called with notification %d Reported RSSI = %d"), + rssiNotification, + avgRssi); + + if (!csrIsConnStateConnectedInfra(pMac, sessionId)) { + smsLog(pMac, LOGW, FL("LookUp Event received when we are not connected. " + "Ignore it")); + vos_mem_free(pUsrCtx); + return VOS_STATUS_SUCCESS; + } + + if (WLANTL_HO_THRESHOLD_UP != rssiNotification) + { + VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification); + vos_mem_free(pUsrCtx); + return VOS_STATUS_E_FAILURE; + } + vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac, sessionId); + vos_mem_free(pUsrCtx); + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupDOWNCallback + + \brief This function is registered with TL to indicate whenever the RSSI + falls below the current neighborLookup RSSI Threshold + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS +csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *)pUserCtxt; + tANI_U32 sessionId = pUsrCtx->sessionId; + tpAniSirGlobal pMac = pUsrCtx->pMac; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup DOWN indication callback called with notification %d Reported RSSI = %d"), + rssiNotification, + avgRssi); + +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = avgRssi; +#endif + if (!csrIsConnStateConnectedInfra(pMac, sessionId)) { + smsLog(pMac, LOGW, FL("LookDown Event received when we are not " + "connected. Ignore it")); + vos_mem_free(pUsrCtx); + return VOS_STATUS_SUCCESS; + } + + if (WLANTL_HO_THRESHOLD_DOWN != rssiNotification) + { + VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification); + vos_mem_free(pUsrCtx); + return VOS_STATUS_E_FAILURE; + } + vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac, sessionId); + vos_mem_free(pUsrCtx); + + return vosStatus; +} + +#ifdef RSSI_HACK +extern int dumpCmdRSSI; +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIndicateDisconnect + + \brief This function is called by CSR as soon as the station disconnects from + the AP. This function does the necessary cleanup of neighbor roam data + structures. Neighbor roam state transitions to INIT state whenever this + function is called except if the current state is REASSOCIATING + + \param pMac - The handle returned by macOpen. + sessionId - CSR session id that got disconnected + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; +#ifdef FEATURE_WLAN_LFR + tCsrRoamConnectedProfile *pPrevProfile = &pNeighborRoamInfo->prevConnProfile; +#endif + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId); + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL ")); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Disconnect indication on session %d in state %d from BSSID : " + MAC_ADDRESS_STR), sessionId, pNeighborRoamInfo->neighborRoamState, + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid)); +#ifdef FEATURE_WLAN_LFR + /*Free the current previous profile and move the current profile to prev profile.*/ + csrRoamFreeConnectProfile(pMac, pPrevProfile); + csrRoamCopyConnectProfile(pMac, sessionId, pPrevProfile); +#endif + if (NULL != pSession) + { + if (NULL != pSession->pCurRoamProfile) + { + if (VOS_STA_MODE != pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona) + { + smsLog(pMac, LOGE, FL("Ignoring Disconnect indication received from a non STA persona." + "sessionId: %d, csrPersonna %d"), sessionId, + (int)pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona); + return eHAL_STATUS_SUCCESS; + } + } + +#ifdef FEATURE_WLAN_ESE + if (pSession->connectedProfile.isESEAssoc) + { + vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, + sizeof(tSirMacSSid)); + vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + pSession->prevOpChannel = pSession->connectedProfile.operationChannel; + pSession->isPrevApInfoValid = TRUE; + pSession->roamTS1 = vos_timer_get_system_time(); + } +#endif + } //if (NULL != pSession) + +#ifdef RSSI_HACK + dumpCmdRSSI = -40; +#endif + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + // Stop scan and neighbor refresh timers. + // These are indeed not required when we are in reassociating + // state. + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId )) { + /* + * Disconnect indication during Disassoc Handoff sub-state + * is received when we are trying to disconnect with the old + * AP during roam. BUT, if receive a disconnect indication + * outside of Disassoc Handoff sub-state, then it means that + * this is a genuine disconnect and we need to clean up. + * Otherwise, we will be stuck in reassoc state which will + * in-turn block scans. + */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + } + break; + + case eCSR_NEIGHBOR_ROAM_STATE_INIT: + csrNeighborRoamResetInitStateControlInfo(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetConnectedStateControlInfo(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetCfgListChanScanControlInfo(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE: + /* Stop pre-auth to reassoc interval timer */ + vos_timer_stop(&pSession->ftSmeContext.preAuthReassocIntvlTimer); + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetPreauthControlInfo(pMac, sessionId); + csrNeighborRoamResetReportScanStateControlInfo(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + default: + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event" + "in state %s "), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state")); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + break; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /*Inform the Firmware to STOP Scanning as the host has a disconnect.*/ + if (csrRoamIsStaMode(pMac, sessionId)) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, + REASON_DISCONNECTED); + } +#endif + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIndicateConnect + + \brief This function is called by CSR as soon as the station connects to an AP. + This initializes all the necessary data structures related to the + associated AP and transitions the state to CONNECTED state + + \param pMac - The handle returned by macOpen. + sessionId - CSR session id that got connected + vosStatus - connect status SUCCESS/FAILURE + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId, + VOS_STATUS vosStatus) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vstatus; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tCsrRoamInfo roamInfo; + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; +#endif + tpFTRoamCallbackUsrCtx pUsrCtx; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + int init_ft_flag = FALSE; +#endif + // if session id invalid then we need return failure + if (NULL == pNeighborRoamInfo || !CSR_IS_SESSION_VALID(pMac, sessionId) || + (NULL == pMac->roam.roamSession[sessionId].pCurRoamProfile)) + { + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG2, + FL("Connect indication received with session id %d" + "in state %s"), + sessionId, macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + + + // Bail out if this is NOT a STA persona + if (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona != VOS_STA_MODE) + { + smsLog(pMac, LOGE, FL("Ignoring Connect indication received from a non STA persona." + "sessionId: %d, csrPersonna %d"), + sessionId, + (int)pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona); + return eHAL_STATUS_SUCCESS; + } + + // if a concurrent session is running +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eANI_BOOLEAN_FALSE == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) + { +#endif + if (csrIsConcurrentSessionRunning(pMac)) + { + smsLog(pMac, LOGE, FL("Ignoring Connect indication received in multisession %d"), + csrIsConcurrentSessionRunning(pMac)); + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress && + (eSIR_ROAM_AUTH_STATUS_AUTHENTICATED == + pSession->roamOffloadSynchParams.authStatus)) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:csrNeighborRoamIndicateConnect"); +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + tpSirSetActiveModeSetBncFilterReq pMsg; + pMsg = vos_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq)); + if (pMsg == NULL) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3:Mem Alloc failed for tSirSetActiveModeSetBncFilterReq"); + return eHAL_STATUS_FAILURE; + } + pMsg->messageType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_BCN_FILTER_REQ); + pMsg->length = pal_cpu_to_be16(sizeof( tANI_U8)); + pMsg->seesionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg ); + } +#endif + vos_mem_copy(&roamInfo.peerMac, + pMac->roam.roamSession[sessionId].connectedProfile.bssid,6); + roamInfo.roamSynchInProgress = + pSession->roamOffloadSynchParams.bRoamSynchInProgress; + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_SET_KEY_COMPLETE, eCSR_ROAM_RESULT_AUTHENTICATED); + } +#endif + + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_INIT, + sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + break; + } + /* Fall through if the status is SUCCESS */ + case eCSR_NEIGHBOR_ROAM_STATE_INIT: + /* Reset all the data structures here */ + csrNeighborRoamResetInitStateControlInfo(pMac, sessionId); + +#ifdef FEATURE_WLAN_LFR + /* + * Initialize the occupied list ONLY if we are + * transitioning from INIT state to CONNECTED state. + */ + if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + csrInitOccupiedChannelsList(pMac, sessionId); +#endif + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + sessionId); + + vos_mem_copy(pNeighborRoamInfo->currAPbssid, + pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid)); + pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel; + pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac; + pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId; + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; + pNeighborRoamInfo->currentOpportunisticThresholdDiff = + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff; + pNeighborRoamInfo->currentRoamRescanRssiDiff = + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff; + pNeighborRoamInfo->currentRoamBmissFirstBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt; + pNeighborRoamInfo->currentRoamBmissFinalBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt; + pNeighborRoamInfo->currentRoamBeaconRssiWeight = + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif + + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* Now we can clear the preauthDone that was saved as we are connected afresh */ + csrNeighborRoamFreeRoamableBSSList(pMac, + &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList); +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + // Based on the auth scheme tell if we are 11r + if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType, + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent)) + { + if (pMac->roam.configParam.isFastTransitionEnabled) + init_ft_flag = TRUE; + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE; + } + else + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc); +#endif + +#ifdef FEATURE_WLAN_ESE + // Based on the auth scheme tell if we are 11r + if (pMac->roam.roamSession[sessionId].connectedProfile.isESEAssoc) + { + if (pMac->roam.configParam.isFastTransitionEnabled) + init_ft_flag = TRUE; + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_TRUE; + } + else + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_FALSE; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isESEAssoc is = %d ft = %d"), + pNeighborRoamInfo->isESEAssoc, init_ft_flag); + +#endif + +#ifdef FEATURE_WLAN_LFR + // If "Legacy Fast Roaming" is enabled + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + init_ft_flag = TRUE; + } +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if ( init_ft_flag == TRUE ) + { + /* Initialize all the data structures needed for the 11r FT Preauth */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + csrNeighborRoamPurgePreauthFailedList(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!vos_is_multiple_active_sta_sessions() && + csrRoamIsRoamOffloadScanEnabled(pMac)) + { + /*If this is not a INFRA type BSS, then do not send the command + * down to firmware.Do not send the START command for other session + * connections.*/ + if(csrRoamIsStaMode(pMac, sessionId)) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) + { + if (pMac->roam.pReassocResp != NULL) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "Free Reassoc Rsp"); + vos_mem_free(pMac->roam.pReassocResp); + pMac->roam.pReassocResp = NULL; + } + if (eSIR_ROAM_AUTH_STATUS_AUTHENTICATED == + pSession->roamOffloadSynchParams.authStatus) { + if (pSession->connectedProfile.AuthType != + eCSR_AUTH_TYPE_OPEN_SYSTEM) { + vos_mem_copy(roamInfo.kck, + pSession->roamOffloadSynchParams.kck, + SIR_KCK_KEY_LEN); + vos_mem_copy(roamInfo.kek, + pSession->roamOffloadSynchParams.kek, + SIR_KEK_KEY_LEN); + vos_mem_copy(roamInfo.replay_ctr, + pSession->roamOffloadSynchParams.replay_ctr, + SIR_REPLAY_CTR_LEN); + VOS_TRACE(VOS_MODULE_ID_SME, + VOS_TRACE_LEVEL_DEBUG, + "LFR3:Send authorized event to supplicant"); + csrRoamCallCallback(pMac, sessionId, + &roamInfo, 0, eCSR_ROAM_AUTHORIZED_EVENT, 0); + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:Send SynchCnf auth status authenticated"); + csrRoamOffloadSendSynchCnf( pMac, sessionId); + } + } else +#endif + csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_START, + REASON_CONNECT); + } + } else { +#endif + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + + /* This user context data will be returned with callback */ + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold); + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pUsrCtx); +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; +#endif + vos_mem_free(pUsrCtx); + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), vstatus); + status = eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ + } +#endif + break; + default: + smsLog(pMac, LOGE, + FL("Connect event received in invalid state %s" + "..Ignoring..."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + } + return status; +} + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPurgePreauthFailedList + + \brief This function purges all the MAC addresses in the pre-auth fail list + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac) +{ + tANI_U8 i, j; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + for (j = 0; j < CSR_ROAM_SESSION_MAX; j++) { + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[j]; + for (i = 0; + i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; + i++) { + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i], + sizeof(tSirMacAddr)); + } + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress = 0; + } +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamInit11rAssocInfo + + \brief This function initializes 11r related neighbor roam data structures + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac) +{ + eHalStatus status; + tANI_U8 i; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + tpCsr11rAssocNeighborInfo pFTRoamInfo = NULL; + + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i]; + pFTRoamInfo = &pNeighborRoamInfo->FTRoamInfo; + + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->cfgParams.maxNeighborRetries = + pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries; + + pFTRoamInfo->neighborReportTimeout = + CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT; + pFTRoamInfo->PEPreauthRespTimeout = + CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * + pNeighborRoamInfo->cfgParams.neighborScanPeriod; + pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE; + pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE; + + pFTRoamInfo->currentNeighborRptRetryNum = 0; + pFTRoamInfo->numBssFromNeighborReport = 0; + + vos_mem_zero(pFTRoamInfo->neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); + + status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed")); + return eHAL_STATUS_RESOURCES; + } + } + return status; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamInit + + \brief This function initializes neighbor roam data structures + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + eHalStatus status; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED; + pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED; + pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime; + pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime; + pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0; + pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold; + pNeighborRoamInfo->cfgParams.delay_before_vdev_stop = + pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop; + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff = + pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff; + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff = + pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff; + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt = + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt; + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt = + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt; + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight = + pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight; + pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold; + pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod; + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod; + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod; + + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; + + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = + vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed")); + return eHAL_STATUS_RESOURCES; + } + + /* Update the roam global structure from CFG */ + vos_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList, + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + + vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0); + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; + pNeighborRoamInfo->currentOpportunisticThresholdDiff = + pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff; + pNeighborRoamInfo->currentRoamRescanRssiDiff = + pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff; + pNeighborRoamInfo->currentRoamBmissFirstBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt; + pNeighborRoamInfo->currentRoamBmissFinalBcnt = + pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt; + pNeighborRoamInfo->currentRoamBeaconRssiWeight = + pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; + vos_mem_set(&pNeighborRoamInfo->prevConnProfile, sizeof(tCsrRoamConnectedProfile), 0); +#endif + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac; + pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + status = vos_timer_init(&pNeighborRoamInfo->neighborScanTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Neighbor scan timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + return eHAL_STATUS_RESOURCES; + } + + status = vos_timer_init(&pNeighborRoamInfo->neighborResultsRefreshTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + return eHAL_STATUS_RESOURCES; + } + + status = vos_timer_init(&pNeighborRoamInfo->emptyScanRefreshTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamEmptyScanRefreshTimerCallback, + (void *)&pNeighborRoamInfo->neighborScanTimerInfo); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + return eHAL_STATUS_RESOURCES; + } + + status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + return eHAL_STATUS_RESOURCES; + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + +#ifdef WLAN_FEATURE_VOWIFI_11R + status = csrNeighborRoamInit11rAssocInfo(pMac); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + csrLLClose(&pNeighborRoamInfo->roamableAPList); + return eHAL_STATUS_RESOURCES; + } +#endif + /* Initialize this with the current tick count */ + pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamClose + + \brief This function closes/frees all the neighbor roam data structures + + \param pMac - The handle returned by macOpen. + \param sessionId - Session identifier + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamClose(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + + if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed")); + return; + } + + if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + + pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL; + pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + + /* Should free up the nodes in the list before closing the double Linked list */ + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + csrLLClose(&pNeighborRoamInfo->roamableAPList); + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + } + + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + + /* Free the profile.. */ + csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile); +#ifdef FEATURE_WLAN_LFR + csrRoamFreeConnectProfile(pMac, &pNeighborRoamInfo->prevConnProfile); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); + csrNeighborRoamFreeRoamableBSSList(pMac, + &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList); + csrLLClose(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED, + sessionId) + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRequestHandoff + + \brief This function triggers actual switching from one AP to the new AP. + It issues disassociate with reason code as Handoff and CSR as a part of + handling disassoc rsp, issues reassociate to the new AP + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tCsrRoamInfo roamInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrNeighborRoamBSSInfo handoffNode; + + extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp ); + tANI_U32 roamId = 0; + +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfoMetrics; +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,"%s sessionId=%d", + __func__, sessionId); + + if (pNeighborRoamInfo->neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) { + smsLog(pMac, LOGE, + FL("Roam requested when Neighbor roam is in %s state"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + return; + } + + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, roamId, eCSR_ROAM_FT_START, + eSIR_SME_SUCCESS); + + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, + sessionId) + + csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode, sessionId); + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(handoffNode.pBssDescription->bssId)); + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. + Send the event to supplicant that pre-auth successfully completed */ + roamInfoMetrics = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfoMetrics) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfoMetrics->bssid, + (void *)&handoffNode.pBssDescription->bssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, roamInfoMetrics, 0, + eCSR_ROAM_HANDOVER_SUCCESS, 0); + vos_mem_free(pRoamInfo); + } +#endif + + /* Free the profile.. Just to make sure we dont leak memory here */ + csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile); + /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number + This should happen before issuing disconnect */ + csrRoamCopyConnectedProfile(pMac, sessionId, + &pNeighborRoamInfo->csrNeighborRoamProfile); + vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr)); + pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP"); + + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF))) + { + smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate"); + return; + } + + //notify HDD for handoff, providing the BSSID too + roamInfo.reasonCode = eCsrRoamReasonBetterAP; + + vos_mem_copy(roamInfo.bssid, + handoffNode.pBssDescription->bssId, + sizeof( tCsrBssid )); + + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIsHandoffInProgress + + \brief This function returns whether handoff is in progress or not based on + the current neighbor roam state + + \param pMac - The handle returned by macOpen. + is11rReassoc - Return whether reassoc is of type 802.11r reassoc + + \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState) + return eANI_BOOLEAN_TRUE; + + return eANI_BOOLEAN_FALSE; +} + +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(WLAN_FEATURE_NEIGHBOR_ROAMING) +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIs11rAssoc + + \brief This function returns whether the current association is a 11r assoc or not + + \param pMac - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + return pMac->roam.neighborRoamInfo[sessionId].is11rAssoc; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamGetHandoffAPInfo + + \brief This function returns the best possible AP for handoff. For 11R case, it + returns the 1st entry from pre-auth done list. For non-11r case, it returns + the 1st entry from roamable AP list + + \param pMac - The handle returned by macOpen. + pHandoffNode - AP node that is the handoff candidate returned + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, + tpCsrNeighborRoamBSSInfo pHandoffNode, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrNeighborRoamBSSInfo pBssNode; + + if (NULL == pHandoffNode) + { + VOS_ASSERT(NULL != pHandoffNode); + return; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, + &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif +#ifdef FEATURE_WLAN_ESE + if (pNeighborRoamInfo->isESEAssoc) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif + { + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList)); + } + vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo)); + + return; +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if preauth is completed + + \param pMac - The handle returned by macOpen. + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + return (pMac->roam.neighborRoamInfo[sessionId].neighborRoamState == + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE); +} + +/* --------------------------------------------------------------------------- + \brief In the event that we are associated with AP1 and we have + completed pre auth with AP2. Then we receive a deauth/disassoc from + AP1. + At this point neighbor roam is in pre auth done state, pre auth timer + is running. We now handle this case by stopping timer and clearing + the pre-auth state. We basically clear up and just go to disconnected + state. + + \param pMac - The handle returned by macOpen. + + \return boolean +---------------------------------------------------------------------------*/ +void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("pSession is NULL")); + return; + } + + if (pNeighborRoamInfo->neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return; + + // Stop timer + vos_timer_stop(&pSession->ftSmeContext.preAuthReassocIntvlTimer); + + // Transition to init state + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if background scan triggered by + LFR is in progress. + + \param halHandle - The handle from HDD context. + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamScanRspPending(tHalHandle hHal, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return (pMac->roam.neighborRoamInfo[sessionId].scanRspPending); +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if STA is in the middle of roaming states + + \param halHandle - The handle from HDD context. + \param sessionId - Session identifier + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborMiddleOfRoaming(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_BOOLEAN val = (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == + pNeighborRoamInfo->neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING == + pNeighborRoamInfo->neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE == + pNeighborRoamInfo->neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == + pNeighborRoamInfo->neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == + pNeighborRoamInfo->neighborRoamState); + return (val); +} +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamCandidateFoundIndHdlr + + \brief This function is called by CSR as soon as TL posts the candidate + found indication to SME via MC thread + + \param pMac - The handle returned by macOpen. + pMsg - Msg sent by PE + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd = + (tSirSmeCandidateFoundInd *)pMsg; + tANI_U32 sessionId = pSirSmeCandidateFoundInd->sessionId; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + || (pNeighborRoamInfo->uOsRequestedHandoff)) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state OR uOsRequestedHandoff is set. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + /* Once it gets the candidates found indication from PE, will issue + * a scan req to PE with “freshScan” in scanreq structure set + * as follows: 0x42 - Return & purge LFR scan results + */ + status = csrScanRequestLfrResult(pMac, sessionId, + csrNeighborRoamScanResultRequestCallback, + pMac); + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProcessHandoffReq + + \brief This function is called start with the handoff process. First do a + SSID scan for the BSSID provided + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamProcessHandoffReq(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 roamId; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + tANI_U8 i = 0; + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL ")); + return eHAL_STATUS_FAILURE; + } + + do + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + { + smsLog(pMac, LOGE, FL("Memory alloc failed")); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Profile copy failed")); + break; + } + + //Add the BSSID & Channel + pProfile->BSSIDs.numOfBSSIDs = 1; + + if (NULL == pProfile->BSSIDs.bssid) + { + pProfile->BSSIDs.bssid = + vos_mem_malloc(sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs); + if (NULL == pProfile->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("mem alloc failed for BSSID")); + status = eHAL_STATUS_FAILURE; + break; + } + } + + vos_mem_zero(pProfile->BSSIDs.bssid, sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from handoff info received from HDD */ + for (i = 0; i < pProfile->BSSIDs.numOfBSSIDs; i++) + { + vos_mem_copy(&pProfile->BSSIDs.bssid[i], + pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr)); + } + + pProfile->ChannelInfo.numOfChannels = 1; + if (NULL == pProfile->ChannelInfo.ChannelList) + { + pProfile->ChannelInfo.ChannelList = + vos_mem_malloc(sizeof(*pProfile->ChannelInfo.ChannelList) * + pProfile->ChannelInfo.numOfChannels); + if (NULL == pProfile->ChannelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("mem alloc failed for ChannelList")); + status = eHAL_STATUS_FAILURE; + break; + } + } + pProfile->ChannelInfo.ChannelList[0] = pNeighborRoamInfo->handoffReqInfo.channel; + + //do a SSID scan + status = csrScanForSSID(pMac, sessionId, pProfile, roamId, FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("SSID scan failed")); + } + }while(0); + + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamSssidScanDone + + \brief This function is called once SSID scan is done. If SSID scan failed + to find our candidate add an entry to csr scan cache ourself before starting + the handoff process + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eHalStatus status) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus hstatus; + + smsLog(pMac, LOGE, FL("called ")); + + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it")); + return eHAL_STATUS_FAILURE; + } + + //if SSID scan failed to find our candidate add an entry to csr scan cache ourself + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Add an entry to csr scan cache")); + hstatus = csrScanCreateEntryInScanCache(pMac, sessionId, + pNeighborRoamInfo->handoffReqInfo.bssid, + pNeighborRoamInfo->handoffReqInfo.channel); + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("csrScanCreateEntryInScanCache failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + } + + /* Now we have completed scanning for the candidate provided by HDD. Let move on to HO*/ + hstatus = csrNeighborRoamProcessScanComplete(pMac, sessionId); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamHandoffReqHdlr + + \brief This function is called by CSR as soon as it gets a handoff request + to SME via MC thread + + \param pMac - The handle returned by macOpen. + pMsg - Msg sent by HDD + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + tAniHandoffReq *pHandoffReqInfo = (tAniHandoffReq *)pMsg; + tANI_U32 sessionId = pHandoffReqInfo->sessionId; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + //save the handoff info came from HDD as part of the reassoc req + pHandoffReqInfo = (tAniHandoffReq *)pMsg; + if (NULL != pHandoffReqInfo) + { + //sanity check + if (VOS_FALSE == vos_mem_compare(pHandoffReqInfo->bssid, + pNeighborRoamInfo->currAPbssid, + sizeof(tSirMacAddr))) + { + + pNeighborRoamInfo->handoffReqInfo.channel = pHandoffReqInfo->channel; + pNeighborRoamInfo->handoffReqInfo.src = pHandoffReqInfo->handoff_src; + vos_mem_copy(pNeighborRoamInfo->handoffReqInfo.bssid, + pHandoffReqInfo->bssid, + 6); + pNeighborRoamInfo->uOsRequestedHandoff = 1; + status = csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_STOP, + REASON_OS_REQUESTED_ROAMING_NOW); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("csrRoamOffloadScan failed")); + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + } + else + { + smsLog(pMac, LOGE, FL("Received req has same BSSID as current AP!!")); + status = eHAL_STATUS_FAILURE; + } + } + else + { + smsLog(pMac, LOGE, FL("Received msg is NULL")); + status = eHAL_STATUS_FAILURE; + } + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProceedWithHandoffReq + + \brief This function is called by CSR as soon as it gets rsp back for + ROAM_SCAN_OFFLOAD_STOP with reason REASON_OS_REQUESTED_ROAMING_NOW + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + || (!pNeighborRoamInfo->uOsRequestedHandoff)) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state or uOsRequestedHandoff is not set. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + //Let's go ahead with handoff + status = csrNeighborRoamProcessHandoffReq(pMac, sessionId); + } + if(!HAL_STATUS_SUCCESS(status)) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamStartLfrScan + + \brief This function is called if HDD requested handoff failed for some + reason. start the LFR logic at that point.By the time, this function is + called, a STOP command has already been issued. + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + pNeighborRoamInfo->uOsRequestedHandoff = 0; + /* There is no candidate or We are not roaming Now. + * Inform the FW to restart Roam Offload Scan */ + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + + return eHAL_STATUS_SUCCESS; +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrTdlsProcess.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrTdlsProcess.c new file mode 100644 index 0000000000000..fe94a0a82b188 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrTdlsProcess.c @@ -0,0 +1,836 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrTdlsProcess.c + + Implementation for the TDLS interface to PE. +========================================================================== */ + +#ifdef FEATURE_WLAN_TDLS + +#include "aniGlobal.h" //for tpAniSirGlobal +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" +#include "csrInternal.h" + + + + +/* + * common routine to remove TDLS cmd from SME command list.. + * commands are removed after getting reponse from PE. + */ +eHalStatus csrTdlsRemoveSmeCmd(tpAniSirGlobal pMac, eSmeCommandType cmdType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( cmdType == pCommand->command ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + pEntry, LL_ACCESS_LOCK ) ) + { + vos_mem_zero( &pCommand->u.tdlsCmd, sizeof( tTdlsCmd ) ); + csrReleaseCommand( pMac, pCommand ); + smeProcessPendingQueue( pMac ); + status = eHAL_STATUS_SUCCESS ; + } + } + } + return status ; +} + +/* + * TDLS request API, called from HDD to send a TDLS frame + * in SME/CSR and send message to PE to trigger TDLS discovery procedure. + */ +eHalStatus csrTdlsSendMgmtReq(tHalHandle hHal, tANI_U8 sessionId, tCsrTdlsSendMgmt *tdlsSendMgmt) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsSendMgmtCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != tdlsSendMgmt) ) + { + tdlsSendMgmtCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsSendMgmtCmd) + { + tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = + &tdlsSendMgmtCmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; + + tdlsSendMgmtCmd->sessionId = sessionId; + + tdlsSendMgmtCmdInfo->frameType = tdlsSendMgmt->frameType ; + tdlsSendMgmtCmdInfo->dialog = tdlsSendMgmt->dialog ; + tdlsSendMgmtCmdInfo->statusCode = tdlsSendMgmt->statusCode ; + tdlsSendMgmtCmdInfo->responder = tdlsSendMgmt->responder; + tdlsSendMgmtCmdInfo->peerCapability = tdlsSendMgmt->peerCapability; + vos_mem_copy(tdlsSendMgmtCmdInfo->peerMac, + tdlsSendMgmt->peerMac, sizeof(tSirMacAddr)) ; + + if( (0 != tdlsSendMgmt->len) && (NULL != tdlsSendMgmt->buf) ) + { + tdlsSendMgmtCmdInfo->buf = vos_mem_malloc(tdlsSendMgmt->len); + if ( NULL == tdlsSendMgmtCmdInfo->buf ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Alloc Failed") ); + VOS_ASSERT(0) ; + return status ; + } + vos_mem_copy(tdlsSendMgmtCmdInfo->buf, + tdlsSendMgmt->buf, tdlsSendMgmt->len ); + tdlsSendMgmtCmdInfo->len = tdlsSendMgmt->len; + } + else + { + tdlsSendMgmtCmdInfo->buf = NULL; + tdlsSendMgmtCmdInfo->len = 0; + } + + tdlsSendMgmtCmd->command = eSmeCommandTdlsSendMgmt ; + tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo) ; + smePushCommand(pMac, tdlsSendMgmtCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to add a TDLS peer + */ +eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, + tCsrStaParams *pstaParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsAddStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if (CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) && (NULL != pstaParams)) { + + tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; + + if (tdlsAddStaCmd) + { + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = + &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + + tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_UPDATE; + + tdlsAddStaCmd->sessionId = sessionId; + + vos_mem_copy(tdlsAddStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + tdlsAddStaCmdInfo->capability = pstaParams->capability; + tdlsAddStaCmdInfo->uapsdQueues = pstaParams->uapsd_queues; + tdlsAddStaCmdInfo->maxSp = pstaParams->max_sp; + vos_mem_copy(tdlsAddStaCmdInfo->extnCapability, + pstaParams->extn_capability, + sizeof(pstaParams->extn_capability)); + + tdlsAddStaCmdInfo->htcap_present = pstaParams->htcap_present; + if(pstaParams->htcap_present) + vos_mem_copy(&tdlsAddStaCmdInfo->HTCap, + &pstaParams->HTCap, sizeof(pstaParams->HTCap)); + else + vos_mem_set(&tdlsAddStaCmdInfo->HTCap, sizeof(pstaParams->HTCap), 0); + + tdlsAddStaCmdInfo->vhtcap_present = pstaParams->vhtcap_present; + if(pstaParams->vhtcap_present) + vos_mem_copy(&tdlsAddStaCmdInfo->VHTCap, + &pstaParams->VHTCap, sizeof(pstaParams->VHTCap)); + else + vos_mem_set(&tdlsAddStaCmdInfo->VHTCap, sizeof(pstaParams->VHTCap), 0); + + tdlsAddStaCmdInfo->supportedRatesLen = pstaParams->supported_rates_len; + + if (0 != pstaParams->supported_rates_len) + vos_mem_copy(&tdlsAddStaCmdInfo->supportedRates, + pstaParams->supported_rates, + pstaParams->supported_rates_len); + + tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer; + tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; + smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} +/* + * TDLS request API, called from HDD to Send Link Establishment Parameters + */ +VOS_STATUS csrTdlsSendLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsLinkEstablishCmd; + eHalStatus status = eHAL_STATUS_FAILURE ; + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsLinkEstablishCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsLinkEstablishCmd) + { + tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = + &tdlsLinkEstablishCmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; + + tdlsLinkEstablishCmd->sessionId = sessionId; + + vos_mem_copy( tdlsLinkEstablishCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)); + tdlsLinkEstablishCmdInfo->isBufSta = tdlsLinkEstablishParams->isBufSta; + tdlsLinkEstablishCmdInfo->isResponder= tdlsLinkEstablishParams->isResponder; + tdlsLinkEstablishCmdInfo->maxSp= tdlsLinkEstablishParams->maxSp; + tdlsLinkEstablishCmdInfo->uapsdQueues= tdlsLinkEstablishParams->uapsdQueues; + tdlsLinkEstablishCmdInfo->isOffChannelSupported = + tdlsLinkEstablishParams->isOffChannelSupported; + vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedChannels, + tdlsLinkEstablishParams->supportedChannels, + tdlsLinkEstablishParams->supportedChannelsLen); + tdlsLinkEstablishCmdInfo->supportedChannelsLen = + tdlsLinkEstablishParams->supportedChannelsLen; + vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedOperClasses, + tdlsLinkEstablishParams->supportedOperClasses, + tdlsLinkEstablishParams->supportedOperClassesLen); + tdlsLinkEstablishCmdInfo->supportedOperClassesLen = + tdlsLinkEstablishParams->supportedOperClassesLen; + tdlsLinkEstablishCmdInfo->isResponder= tdlsLinkEstablishParams->isResponder; + tdlsLinkEstablishCmdInfo->maxSp= tdlsLinkEstablishParams->maxSp; + tdlsLinkEstablishCmdInfo->uapsdQueues= tdlsLinkEstablishParams->uapsdQueues; + tdlsLinkEstablishCmd->command = eSmeCommandTdlsLinkEstablish ; + tdlsLinkEstablishCmd->u.tdlsCmd.size = sizeof(tTdlsLinkEstablishCmdInfo) ; + smePushCommand(pMac, tdlsLinkEstablishCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to add a TDLS peer + */ +eHalStatus csrTdlsAddPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsAddStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsAddStaCmd) + { + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = + &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + + tdlsAddStaCmd->sessionId = sessionId; + tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_ADD; + + vos_mem_copy( tdlsAddStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + + tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer ; + tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; + smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to delete a TDLS peer + */ +eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsDelStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsDelStaCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsDelStaCmd) + { + tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = + &tdlsDelStaCmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; + + tdlsDelStaCmd->sessionId = sessionId; + + vos_mem_copy(tdlsDelStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + + tdlsDelStaCmd->command = eSmeCommandTdlsDelPeer ; + tdlsDelStaCmd->u.tdlsCmd.size = sizeof(tTdlsDelStaCmdInfo) ; + smePushCommand(pMac, tdlsDelStaCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} + +/* + * TDLS messages sent to PE . + */ +eHalStatus tdlsSendMessage(tpAniSirGlobal pMac, tANI_U16 msg_type, + void *msg_data, tANI_U32 msg_size) +{ + + tSirMbMsg *pMsg = (tSirMbMsg *)msg_data ; + pMsg->type = msg_type ; + pMsg->msgLen = (tANI_U16) (msg_size) ; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + ("sending msg = %d"), pMsg->type) ; + /* Send message. */ + if (palSendMBMessage(pMac->hHdd, pMsg) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("Cannot send message")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrTdlsProcessSendMgmt( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = &cmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; + tSirTdlsSendMgmtReq *tdlsSendMgmtReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS Description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsSendMgmtReq = vos_mem_malloc( + sizeof(tSirTdlsSendMgmtReq) + tdlsSendMgmtCmdInfo->len); + if ( NULL == tdlsSendMgmtReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsSendMgmtReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsSendMgmtReq->transactionId = tdlsSendMgmtCmdInfo->dialog; + tdlsSendMgmtReq->reqType = tdlsSendMgmtCmdInfo->frameType ; + tdlsSendMgmtReq->dialog = tdlsSendMgmtCmdInfo->dialog ; + tdlsSendMgmtReq->statusCode = tdlsSendMgmtCmdInfo->statusCode ; + tdlsSendMgmtReq->responder = tdlsSendMgmtCmdInfo->responder; + tdlsSendMgmtReq->peerCapability = tdlsSendMgmtCmdInfo->peerCapability; + + vos_mem_copy(tdlsSendMgmtReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy(tdlsSendMgmtReq->peerMac, + tdlsSendMgmtCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) + { + vos_mem_copy(tdlsSendMgmtReq->addIe, tdlsSendMgmtCmdInfo->buf, + tdlsSendMgmtCmdInfo->len); + + } + // Send the request to PE. + smsLog( pMac, LOG1, "sending TDLS Mgmt Frame req to PE " ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ, + (void *)tdlsSendMgmtReq , sizeof(tSirTdlsSendMgmtReq)+tdlsSendMgmtCmdInfo->len) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) + { + //Done with the buf. Free it. + vos_mem_free( tdlsSendMgmtCmdInfo->buf ); + tdlsSendMgmtCmdInfo->buf = NULL; + tdlsSendMgmtCmdInfo->len = 0; + } + + return status; +} + +eHalStatus csrTdlsProcessAddSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + tSirTdlsAddStaReq *tdlsAddStaReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsAddStaReq = vos_mem_malloc(sizeof(tSirTdlsAddStaReq)); + if ( NULL == tdlsAddStaReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsAddStaReq->sessionId = cmd->sessionId; + tdlsAddStaReq->tdlsAddOper = tdlsAddStaCmdInfo->tdlsAddOper; + //Using dialog as transactionId. This can be used to match response with request + tdlsAddStaReq->transactionId = 0; + + vos_mem_copy( tdlsAddStaReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy( tdlsAddStaReq->peerMac, + tdlsAddStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + tdlsAddStaReq->capability = tdlsAddStaCmdInfo->capability; + tdlsAddStaReq->uapsd_queues = tdlsAddStaCmdInfo->uapsdQueues; + tdlsAddStaReq->max_sp = tdlsAddStaCmdInfo->maxSp; + + vos_mem_copy( tdlsAddStaReq->extn_capability, + tdlsAddStaCmdInfo->extnCapability, + SIR_MAC_MAX_EXTN_CAP); + tdlsAddStaReq->htcap_present = tdlsAddStaCmdInfo->htcap_present; + vos_mem_copy( &tdlsAddStaReq->htCap, + &tdlsAddStaCmdInfo->HTCap, sizeof(tdlsAddStaCmdInfo->HTCap)); + tdlsAddStaReq->vhtcap_present = tdlsAddStaCmdInfo->vhtcap_present; + vos_mem_copy( &tdlsAddStaReq->vhtCap, + &tdlsAddStaCmdInfo->VHTCap, sizeof(tdlsAddStaCmdInfo->VHTCap)); + tdlsAddStaReq->supported_rates_length = tdlsAddStaCmdInfo->supportedRatesLen; + vos_mem_copy( &tdlsAddStaReq->supported_rates, + tdlsAddStaCmdInfo->supportedRates, tdlsAddStaCmdInfo->supportedRatesLen); + + // Send the request to PE. + smsLog( pMac, LOGE, "sending TDLS Add Sta req to PE " ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_ADD_STA_REQ, + (void *)tdlsAddStaReq , sizeof(tSirTdlsAddStaReq)) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + return status; +} + +eHalStatus csrTdlsProcessDelSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; + tSirTdlsDelStaReq *tdlsDelStaReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsDelStaReq = vos_mem_malloc(sizeof(tSirTdlsDelStaReq)); + if ( NULL == tdlsDelStaReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsDelStaReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsDelStaReq->transactionId = 0; + + vos_mem_copy( tdlsDelStaReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy( tdlsDelStaReq->peerMac, + tdlsDelStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + // Send the request to PE. +#ifdef WLAN_FEATURE_TDLS_DEBUG + smsLog( pMac, LOGE, +#else + smsLog( pMac, LOG1, +#endif + "sending TDLS Del Sta "MAC_ADDRESS_STR" req to PE", + MAC_ADDR_ARRAY(tdlsDelStaCmdInfo->peerMac)); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_DEL_STA_REQ, + (void *)tdlsDelStaReq , sizeof(tSirTdlsDelStaReq)) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + return status; +} +/* + * commands received from CSR + */ +eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac, tSmeCmd *cmd) +{ + eSmeCommandType cmdType = cmd->command ; + tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; + switch(cmdType) + { + case eSmeCommandTdlsSendMgmt: + { + status = csrTdlsProcessSendMgmt( pMac, cmd ); + if(HAL_STATUS_SUCCESS( status ) ) + { + status = eANI_BOOLEAN_FALSE ; + } + } + break ; + case eSmeCommandTdlsAddPeer: + { + status = csrTdlsProcessAddSta( pMac, cmd ); + if(HAL_STATUS_SUCCESS( status ) ) + { + status = eANI_BOOLEAN_FALSE ; + } + } + break; + case eSmeCommandTdlsDelPeer: + { + status = csrTdlsProcessDelSta( pMac, cmd ); + if(HAL_STATUS_SUCCESS( status ) ) + { + status = eANI_BOOLEAN_FALSE ; + } + } + break; + case eSmeCommandTdlsLinkEstablish: + { + status = csrTdlsProcessLinkEstablish( pMac, cmd ); + if(HAL_STATUS_SUCCESS( status ) ) + { + status = eANI_BOOLEAN_FALSE ; + } + } + break; + default: + { + /* TODO: Add defualt handling */ + break ; + } + + } + return status ; +} + +eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = &cmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; + tSirTdlsLinkEstablishReq *tdlsLinkEstablishReq = NULL ; + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + tdlsLinkEstablishReq = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReq)); + + if (tdlsLinkEstablishReq == NULL) + { + smsLog( pMac, LOGE, FL("alloc failed \n") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsLinkEstablishReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsLinkEstablishReq->transactionId = 0; + vos_mem_copy(tdlsLinkEstablishReq->peerMac, + tdlsLinkEstablishCmdInfo->peerMac, sizeof(tSirMacAddr)); + vos_mem_copy(tdlsLinkEstablishReq->bssid, pSession->pConnectBssDesc->bssId, + sizeof (tSirMacAddr)); + vos_mem_copy(tdlsLinkEstablishReq->supportedChannels, + tdlsLinkEstablishCmdInfo->supportedChannels, + tdlsLinkEstablishCmdInfo->supportedChannelsLen); + tdlsLinkEstablishReq->supportedChannelsLen = + tdlsLinkEstablishCmdInfo->supportedChannelsLen; + vos_mem_copy(tdlsLinkEstablishReq->supportedOperClasses, + tdlsLinkEstablishCmdInfo->supportedOperClasses, + tdlsLinkEstablishCmdInfo->supportedOperClassesLen); + tdlsLinkEstablishReq->supportedOperClassesLen = + tdlsLinkEstablishCmdInfo->supportedOperClassesLen; + tdlsLinkEstablishReq->isBufSta = tdlsLinkEstablishCmdInfo->isBufSta; + tdlsLinkEstablishReq->isResponder= tdlsLinkEstablishCmdInfo->isResponder; + tdlsLinkEstablishReq->uapsdQueues= tdlsLinkEstablishCmdInfo->uapsdQueues; + tdlsLinkEstablishReq->maxSp= tdlsLinkEstablishCmdInfo->maxSp; + + + // Send the request to PE. + smsLog( pMac, LOGE, "sending TDLS Link Establish Request to PE \n" ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_LINK_ESTABLISH_REQ, + (void *)tdlsLinkEstablishReq, + sizeof(tSirTdlsLinkEstablishReq)); + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC\n")); + } + return status; +} + +/* + * TDLS Message processor, will be called after TDLS message recieved from + * PE + */ +eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, + void *pMsgBuf) +{ + tCsrRoamInfo roamInfo = {0} ; + switch(msgType) + { + case eWNI_SME_TDLS_SEND_MGMT_RSP: + { + /* remove pending eSmeCommandTdlsDiscovery command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsSendMgmt) ; + } + break; + case eWNI_SME_TDLS_ADD_STA_RSP: + { + tSirTdlsAddStaRsp *addStaRsp = (tSirTdlsAddStaRsp *) pMsgBuf ; + eCsrRoamResult roamResult ; + vos_mem_copy( &roamInfo.peerMac, addStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = addStaRsp->staId ; + roamInfo.ucastSig = addStaRsp->ucastSig ; + roamInfo.bcastSig = addStaRsp->bcastSig ; + roamInfo.statusCode = addStaRsp->statusCode ; + /* + * register peer with TL, we have to go through HDD as this is + * the only way to register any STA with TL. + */ + if (addStaRsp->tdlsAddOper == TDLS_OPER_ADD) + roamResult = eCSR_ROAM_RESULT_ADD_TDLS_PEER; + else /* addStaRsp->tdlsAddOper must be TDLS_OPER_UPDATE */ + roamResult = eCSR_ROAM_RESULT_UPDATE_TDLS_PEER; + csrRoamCallCallback(pMac, addStaRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + roamResult); + + /* remove pending eSmeCommandTdlsDiscovery command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsAddPeer) ; + } + break; + case eWNI_SME_TDLS_DEL_STA_RSP: + { + tSirTdlsDelStaRsp *delStaRsp = (tSirTdlsDelStaRsp *) pMsgBuf ; + + vos_mem_copy( &roamInfo.peerMac, delStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = delStaRsp->staId ; + roamInfo.statusCode = delStaRsp->statusCode ; + /* + * register peer with TL, we have to go through HDD as this is + * the only way to register any STA with TL. + */ + csrRoamCallCallback(pMac, delStaRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_DELETE_TDLS_PEER); + + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsDelPeer) ; + } + break; + case eWNI_SME_TDLS_DEL_STA_IND: + { + tpSirTdlsDelStaInd pSirTdlsDelStaInd = (tpSirTdlsDelStaInd) pMsgBuf ; + vos_mem_copy( &roamInfo.peerMac, pSirTdlsDelStaInd->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = pSirTdlsDelStaInd->staId ; + roamInfo.reasonCode = pSirTdlsDelStaInd->reasonCode ; + + /* Sending the TEARDOWN indication to HDD. */ + csrRoamCallCallback(pMac, pSirTdlsDelStaInd->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND); + break ; + } + case eWNI_SME_TDLS_DEL_ALL_PEER_IND: + { + tpSirTdlsDelAllPeerInd pSirTdlsDelAllPeerInd = (tpSirTdlsDelAllPeerInd) pMsgBuf ; + + /* Sending the TEARDOWN indication to HDD. */ + csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND); + break ; + } + case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: + { + tpSirMgmtTxCompletionInd pSirTdlsDelAllPeerInd = (tpSirMgmtTxCompletionInd) pMsgBuf ; + roamInfo.reasonCode = pSirTdlsDelAllPeerInd->txCompleteStatus; + + csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, + 0, eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, 0); + break; + } + case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: + { + tSirTdlsLinkEstablishReqRsp *linkEstablishReqRsp = (tSirTdlsLinkEstablishReqRsp *) pMsgBuf ; + csrRoamCallCallback(pMac, linkEstablishReqRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP); + /* remove pending eSmeCommandTdlsLinkEstablish command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsLinkEstablish); + break; + } + case eWNI_SME_TDLS_SHOULD_DISCOVER: + { + tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; + vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, + sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: eWNI_SME_TDLS_SHOULD_DISCOVER for peer mac: " + MAC_ADDRESS_STR " peer_reason: %d", + __func__, MAC_ADDR_ARRAY(tevent->peerMac), + tevent->peer_reason); + csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER); + break; + } + case eWNI_SME_TDLS_SHOULD_TEARDOWN: + { + tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; + vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, + sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: eWNI_SME_TDLS_SHOULD_TEARDOWN for peer mac: " + MAC_ADDRESS_STR " peer_reason: %d", + __func__, MAC_ADDR_ARRAY(tevent->peerMac), + tevent->peer_reason); + csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN); + break; + } + case eWNI_SME_TDLS_PEER_DISCONNECTED: + { + tSirTdlsEventNotify *tevent = (tSirTdlsEventNotify *) pMsgBuf; + vos_mem_copy(&roamInfo.peerMac, tevent->peerMac, + sizeof(tSirMacAddr)); + roamInfo.reasonCode = tevent->peer_reason; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: eWNI_SME_TDLS_PEER_DISCONNECTED for peer mac: " + MAC_ADDRESS_STR " peer_reason: %d", + __func__, MAC_ADDR_ARRAY(tevent->peerMac), + tevent->peer_reason); + csrRoamCallCallback(pMac, tevent->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED); + break; + } + default: + { + break ; + } + } + + return eHAL_STATUS_SUCCESS ; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrUtil.c b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrUtil.c new file mode 100644 index 0000000000000..6ecf1b9dabc0d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/csr/csrUtil.c @@ -0,0 +1,5981 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrUtil.c + + Implementation supporting routines for CSR. +========================================================================== */ + + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrSupport.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "smeQosInternal.h" +#include "wlan_qct_wda.h" +#include "vos_utils.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD*/ + +tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ] = { + { 0x00, 0x50, 0xf2, 0x00 }, + { 0x00, 0x50, 0xf2, 0x01 }, + { 0x00, 0x50, 0xf2, 0x02 }, + { 0x00, 0x50, 0xf2, 0x03 }, + { 0x00, 0x50, 0xf2, 0x04 }, + { 0x00, 0x50, 0xf2, 0x05 }, +#ifdef FEATURE_WLAN_ESE + { 0x00, 0x40, 0x96, 0x00 }, // CCKM +#endif /* FEATURE_WLAN_ESE */ +}; + +tANI_U8 csrRSNOui[][ CSR_RSN_OUI_SIZE ] = { + { 0x00, 0x0F, 0xAC, 0x00 }, // group cipher + { 0x00, 0x0F, 0xAC, 0x01 }, // WEP-40 or RSN + { 0x00, 0x0F, 0xAC, 0x02 }, // TKIP or RSN-PSK + { 0x00, 0x0F, 0xAC, 0x03 }, // Reserved + { 0x00, 0x0F, 0xAC, 0x04 }, // AES-CCMP + { 0x00, 0x0F, 0xAC, 0x05 }, // WEP-104 + { 0x00, 0x40, 0x96, 0x00 }, // CCKM + { 0x00, 0x0F, 0xAC, 0x06 }, // BIP (encryption type) or RSN-PSK-SHA256 (authentication type) + /* RSN-8021X-SHA256 (authentication type) */ + { 0x00, 0x0F, 0xAC, 0x05 } +}; + +#ifdef FEATURE_WLAN_WAPI +tANI_U8 csrWapiOui[][ CSR_WAPI_OUI_SIZE ] = { + { 0x00, 0x14, 0x72, 0x00 }, // Reserved + { 0x00, 0x14, 0x72, 0x01 }, // WAI certificate or SMS4 + { 0x00, 0x14, 0x72, 0x02 } // WAI PSK +}; +#endif /* FEATURE_WLAN_WAPI */ +tANI_U8 csrWmeInfoOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; +tANI_U8 csrWmeParmOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; + +static tCsrIELenInfo gCsrIELengthTable[] = { +/* 000 */ { SIR_MAC_SSID_EID_MIN, SIR_MAC_SSID_EID_MAX }, +/* 001 */ { SIR_MAC_RATESET_EID_MIN, SIR_MAC_RATESET_EID_MAX }, +/* 002 */ { SIR_MAC_FH_PARAM_SET_EID_MIN, SIR_MAC_FH_PARAM_SET_EID_MAX }, +/* 003 */ { SIR_MAC_DS_PARAM_SET_EID_MIN, SIR_MAC_DS_PARAM_SET_EID_MAX }, +/* 004 */ { SIR_MAC_CF_PARAM_SET_EID_MIN, SIR_MAC_CF_PARAM_SET_EID_MAX }, +/* 005 */ { SIR_MAC_TIM_EID_MIN, SIR_MAC_TIM_EID_MAX }, +/* 006 */ { SIR_MAC_IBSS_PARAM_SET_EID_MIN, SIR_MAC_IBSS_PARAM_SET_EID_MAX }, +/* 007 */ { SIR_MAC_COUNTRY_EID_MIN, SIR_MAC_COUNTRY_EID_MAX }, +/* 008 */ { SIR_MAC_FH_PARAMS_EID_MIN, SIR_MAC_FH_PARAMS_EID_MAX }, +/* 009 */ { SIR_MAC_FH_PATTERN_EID_MIN, SIR_MAC_FH_PATTERN_EID_MAX }, +/* 010 */ { SIR_MAC_REQUEST_EID_MIN, SIR_MAC_REQUEST_EID_MAX }, +/* 011 */ { SIR_MAC_QBSS_LOAD_EID_MIN, SIR_MAC_QBSS_LOAD_EID_MAX }, +/* 012 */ { SIR_MAC_EDCA_PARAM_SET_EID_MIN, SIR_MAC_EDCA_PARAM_SET_EID_MAX }, +/* 013 */ { SIR_MAC_TSPEC_EID_MIN, SIR_MAC_TSPEC_EID_MAX }, +/* 014 */ { SIR_MAC_TCLAS_EID_MIN, SIR_MAC_TCLAS_EID_MAX }, +/* 015 */ { SIR_MAC_QOS_SCHEDULE_EID_MIN, SIR_MAC_QOS_SCHEDULE_EID_MAX }, +/* 016 */ { SIR_MAC_CHALLENGE_TEXT_EID_MIN, SIR_MAC_CHALLENGE_TEXT_EID_MAX }, +/* 017 */ { 0, 255 }, +/* 018 */ { 0, 255 }, +/* 019 */ { 0, 255 }, +/* 020 */ { 0, 255 }, +/* 021 */ { 0, 255 }, +/* 022 */ { 0, 255 }, +/* 023 */ { 0, 255 }, +/* 024 */ { 0, 255 }, +/* 025 */ { 0, 255 }, +/* 026 */ { 0, 255 }, +/* 027 */ { 0, 255 }, +/* 028 */ { 0, 255 }, +/* 029 */ { 0, 255 }, +/* 030 */ { 0, 255 }, +/* 031 */ { 0, 255 }, +/* 032 */ { SIR_MAC_PWR_CONSTRAINT_EID_MIN, SIR_MAC_PWR_CONSTRAINT_EID_MAX }, +/* 033 */ { SIR_MAC_PWR_CAPABILITY_EID_MIN, SIR_MAC_PWR_CAPABILITY_EID_MAX }, +/* 034 */ { SIR_MAC_TPC_REQ_EID_MIN, SIR_MAC_TPC_REQ_EID_MAX }, +/* 035 */ { SIR_MAC_TPC_RPT_EID_MIN, SIR_MAC_TPC_RPT_EID_MAX }, +/* 036 */ { SIR_MAC_SPRTD_CHNLS_EID_MIN, SIR_MAC_SPRTD_CHNLS_EID_MAX }, +/* 037 */ { SIR_MAC_CHNL_SWITCH_ANN_EID_MIN, SIR_MAC_CHNL_SWITCH_ANN_EID_MAX }, +/* 038 */ { SIR_MAC_MEAS_REQ_EID_MIN, SIR_MAC_MEAS_REQ_EID_MAX }, +/* 039 */ { SIR_MAC_MEAS_RPT_EID_MIN, SIR_MAC_MEAS_RPT_EID_MAX }, +/* 040 */ { SIR_MAC_QUIET_EID_MIN, SIR_MAC_QUIET_EID_MAX }, +/* 041 */ { SIR_MAC_IBSS_DFS_EID_MIN, SIR_MAC_IBSS_DFS_EID_MAX }, +/* 042 */ { SIR_MAC_ERP_INFO_EID_MIN, SIR_MAC_ERP_INFO_EID_MAX }, +/* 043 */ { SIR_MAC_TS_DELAY_EID_MIN, SIR_MAC_TS_DELAY_EID_MAX }, +/* 044 */ { SIR_MAC_TCLAS_PROC_EID_MIN, SIR_MAC_TCLAS_PROC_EID_MAX }, +/* 045 */ { SIR_MAC_QOS_ACTION_EID_MIN, SIR_MAC_QOS_ACTION_EID_MAX }, +/* 046 */ { SIR_MAC_QOS_CAPABILITY_EID_MIN, SIR_MAC_QOS_CAPABILITY_EID_MAX }, +/* 047 */ { 0, 255 }, +/* 048 */ { SIR_MAC_RSN_EID_MIN, SIR_MAC_RSN_EID_MAX }, +/* 049 */ { 0, 255 }, +/* 050 */ { SIR_MAC_EXTENDED_RATE_EID_MIN, SIR_MAC_EXTENDED_RATE_EID_MAX }, +/* 051 */ { 0, 255 }, +/* 052 */ { 0, 255 }, +/* 053 */ { 0, 255 }, +/* 054 */ { 0, 255 }, +/* 055 */ { 0, 255 }, +/* 056 */ { 0, 255 }, +/* 057 */ { 0, 255 }, +/* 058 */ { 0, 255 }, +/* 059 */ { 0, 255 }, +/* 060 */ { 0, 255 }, +/* 061 */ { 0, 255 }, +/* 062 */ { 0, 255 }, +/* 063 */ { 0, 255 }, +/* 064 */ { 0, 255 }, +/* 065 */ { 0, 255 }, +/* 066 */ { 0, 255 }, +/* 067 */ { 0, 255 }, +#ifdef FEATURE_WLAN_WAPI +/* 068 */ { DOT11F_EID_WAPI, DOT11F_IE_WAPI_MAX_LEN }, +#else +/* 068 */ { 0, 255 }, +#endif /* FEATURE_WLAN_WAPI */ +/* 069 */ { 0, 255 }, +/* 070 */ { 0, 255 }, +/* 071 */ { 0, 255 }, +/* 072 */ { 0, 255 }, +/* 073 */ { 0, 255 }, +/* 074 */ { 0, 255 }, +/* 075 */ { 0, 255 }, +/* 076 */ { 0, 255 }, +/* 077 */ { 0, 255 }, +/* 078 */ { 0, 255 }, +/* 079 */ { 0, 255 }, +/* 080 */ { 0, 255 }, +/* 081 */ { 0, 255 }, +/* 082 */ { 0, 255 }, +/* 083 */ { 0, 255 }, +/* 084 */ { 0, 255 }, +/* 085 */ { 0, 255 }, +/* 086 */ { 0, 255 }, +/* 087 */ { 0, 255 }, +/* 088 */ { 0, 255 }, +/* 089 */ { 0, 255 }, +/* 090 */ { 0, 255 }, +/* 091 */ { 0, 255 }, +/* 092 */ { 0, 255 }, +/* 093 */ { 0, 255 }, +/* 094 */ { 0, 255 }, +/* 095 */ { 0, 255 }, +/* 096 */ { 0, 255 }, +/* 097 */ { 0, 255 }, +/* 098 */ { 0, 255 }, +/* 099 */ { 0, 255 }, +/* 100 */ { 0, 255 }, +/* 101 */ { 0, 255 }, +/* 102 */ { 0, 255 }, +/* 103 */ { 0, 255 }, +/* 104 */ { 0, 255 }, +/* 105 */ { 0, 255 }, +/* 106 */ { 0, 255 }, +/* 107 */ { 0, 255 }, +/* 108 */ { 0, 255 }, +/* 109 */ { 0, 255 }, +/* 110 */ { 0, 255 }, +/* 111 */ { 0, 255 }, +/* 112 */ { 0, 255 }, +/* 113 */ { 0, 255 }, +/* 114 */ { 0, 255 }, +/* 115 */ { 0, 255 }, +/* 116 */ { 0, 255 }, +/* 117 */ { 0, 255 }, +/* 118 */ { 0, 255 }, +/* 119 */ { 0, 255 }, +/* 120 */ { 0, 255 }, +/* 121 */ { 0, 255 }, +/* 122 */ { 0, 255 }, +/* 123 */ { 0, 255 }, +/* 124 */ { 0, 255 }, +/* 125 */ { 0, 255 }, +/* 126 */ { 0, 255 }, +/* 127 */ { 0, 255 }, +/* 128 */ { 0, 255 }, +/* 129 */ { 0, 255 }, +/* 130 */ { 0, 255 }, +/* 131 */ { 0, 255 }, +/* 132 */ { 0, 255 }, +/* 133 */ { 0, 255 }, +/* 134 */ { 0, 255 }, +/* 135 */ { 0, 255 }, +/* 136 */ { 0, 255 }, +/* 137 */ { 0, 255 }, +/* 138 */ { 0, 255 }, +/* 139 */ { 0, 255 }, +/* 140 */ { 0, 255 }, +/* 141 */ { 0, 255 }, +/* 142 */ { 0, 255 }, +/* 143 */ { 0, 255 }, +/* 144 */ { 0, 255 }, +/* 145 */ { 0, 255 }, +/* 146 */ { 0, 255 }, +/* 147 */ { 0, 255 }, +/* 148 */ { 0, 255 }, +/* 149 */ { 0, 255 }, +/* 150 */ { 0, 255 }, +/* 151 */ { 0, 255 }, +/* 152 */ { 0, 255 }, +/* 153 */ { 0, 255 }, +/* 154 */ { 0, 255 }, +/* 155 */ { 0, 255 }, +/* 156 */ { 0, 255 }, +/* 157 */ { 0, 255 }, +/* 158 */ { 0, 255 }, +/* 159 */ { 0, 255 }, +/* 160 */ { 0, 255 }, +/* 161 */ { 0, 255 }, +/* 162 */ { 0, 255 }, +/* 163 */ { 0, 255 }, +/* 164 */ { 0, 255 }, +/* 165 */ { 0, 255 }, +/* 166 */ { 0, 255 }, +/* 167 */ { 0, 255 }, +/* 168 */ { 0, 255 }, +/* 169 */ { 0, 255 }, +/* 170 */ { 0, 255 }, +/* 171 */ { 0, 255 }, +/* 172 */ { 0, 255 }, +/* 173 */ { 0, 255 }, +/* 174 */ { 0, 255 }, +/* 175 */ { 0, 255 }, +/* 176 */ { 0, 255 }, +/* 177 */ { 0, 255 }, +/* 178 */ { 0, 255 }, +/* 179 */ { 0, 255 }, +/* 180 */ { 0, 255 }, +/* 181 */ { 0, 255 }, +/* 182 */ { 0, 255 }, +/* 183 */ { 0, 255 }, +/* 184 */ { 0, 255 }, +/* 185 */ { 0, 255 }, +/* 186 */ { 0, 255 }, +/* 187 */ { 0, 255 }, +/* 188 */ { 0, 255 }, +/* 189 */ { 0, 255 }, +/* 190 */ { 0, 255 }, +/* 191 */ { 0, 255 }, +/* 192 */ { 0, 255 }, +/* 193 */ { 0, 255 }, +/* 194 */ { 0, 255 }, +/* 195 */ { 0, 255 }, +/* 196 */ { 0, 255 }, +/* 197 */ { 0, 255 }, +/* 198 */ { 0, 255 }, +/* 199 */ { 0, 255 }, +/* 200 */ { 0, 255 }, +/* 201 */ { 0, 255 }, +/* 202 */ { 0, 255 }, +/* 203 */ { 0, 255 }, +/* 204 */ { 0, 255 }, +/* 205 */ { 0, 255 }, +/* 206 */ { 0, 255 }, +/* 207 */ { 0, 255 }, +/* 208 */ { 0, 255 }, +/* 209 */ { 0, 255 }, +/* 210 */ { 0, 255 }, +/* 211 */ { 0, 255 }, +/* 212 */ { 0, 255 }, +/* 213 */ { 0, 255 }, +/* 214 */ { 0, 255 }, +/* 215 */ { 0, 255 }, +/* 216 */ { 0, 255 }, +/* 217 */ { 0, 255 }, +/* 218 */ { 0, 255 }, +/* 219 */ { 0, 255 }, +/* 220 */ { 0, 255 }, +/* 221 */ { SIR_MAC_WPA_EID_MIN, SIR_MAC_WPA_EID_MAX }, +/* 222 */ { 0, 255 }, +/* 223 */ { 0, 255 }, +/* 224 */ { 0, 255 }, +/* 225 */ { 0, 255 }, +/* 226 */ { 0, 255 }, +/* 227 */ { 0, 255 }, +/* 228 */ { 0, 255 }, +/* 229 */ { 0, 255 }, +/* 230 */ { 0, 255 }, +/* 231 */ { 0, 255 }, +/* 232 */ { 0, 255 }, +/* 233 */ { 0, 255 }, +/* 234 */ { 0, 255 }, +/* 235 */ { 0, 255 }, +/* 236 */ { 0, 255 }, +/* 237 */ { 0, 255 }, +/* 238 */ { 0, 255 }, +/* 239 */ { 0, 255 }, +/* 240 */ { 0, 255 }, +/* 241 */ { 0, 255 }, +/* 242 */ { 0, 255 }, +/* 243 */ { 0, 255 }, +/* 244 */ { 0, 255 }, +/* 245 */ { 0, 255 }, +/* 246 */ { 0, 255 }, +/* 247 */ { 0, 255 }, +/* 248 */ { 0, 255 }, +/* 249 */ { 0, 255 }, +/* 250 */ { 0, 255 }, +/* 251 */ { 0, 255 }, +/* 252 */ { 0, 255 }, +/* 253 */ { 0, 255 }, +/* 254 */ { 0, 255 }, +/* 255 */ { SIR_MAC_ANI_WORKAROUND_EID_MIN, SIR_MAC_ANI_WORKAROUND_EID_MAX } +}; + +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +//////////////////////////////////////////////////////////////////////// + +/** + * \var gPhyRatesSuppt + * + * \brief Rate support lookup table + * + * + * This is a lookup table indexing rates & configuration parameters to + * support. Given a rate (in unites of 0.5Mpbs) & three booleans (MIMO + * Enabled, Channel Bonding Enabled, & Concatenation Enabled), one can + * determine whether the given rate is supported by computing two + * indices. The first maps the rate to table row as indicated below + * (i.e. eHddSuppRate_6Mbps maps to row zero, eHddSuppRate_9Mbps to row + * 1, and so on). Index two can be computed like so: + * + * \code + idx2 = ( fEsf ? 0x4 : 0x0 ) | + ( fCb ? 0x2 : 0x0 ) | + ( fMimo ? 0x1 : 0x0 ); + * \endcode + * + * + * Given that: + * + \code + fSupported = gPhyRatesSuppt[idx1][idx2]; + \endcode + * + * + * This table is based on the document "PHY Supported Rates.doc". This + * table is permissive in that a rate is reflected as being supported + * even when turning off an enabled feature would be required. For + * instance, "PHY Supported Rates" lists 42Mpbs as unsupported when CB, + * ESF, & MIMO are all on. However, if we turn off either of CB or + * MIMO, it then becomes supported. Therefore, we mark it as supported + * even in index 7 of this table. + * + * + */ + +static const tANI_BOOLEAN gPhyRatesSuppt[24][8] = { + + // SSF SSF SSF SSF ESF ESF ESF ESF + // SIMO MIMO SIMO MIMO SIMO MIMO SIMO MIMO + // No CB No CB CB CB No CB No CB CB CB + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 6Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 9Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 12Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 18Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE }, // 20Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 24Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 36Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 40Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 42Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 48Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 54Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 72Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 80Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 84Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 96Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 108Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 120Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 126Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 144Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 160Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 168Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 192Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 216Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 240Mbps + +}; + +#define CASE_RETURN_STR(n) case (n): return (#n) + +const char * +get_eRoamCmdStatus_str(eRoamCmdStatus val) +{ + switch (val) + { + CASE_RETURN_STR(eCSR_ROAM_CANCELLED); + CASE_RETURN_STR(eCSR_ROAM_ROAMING_START); + CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION); + CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START); + CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION); + CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM); + CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS); + CASE_RETURN_STR(eCSR_ROAM_LOSTLINK); + default: + return "unknown"; + } +} + +const char * +get_eCsrRoamResult_str(eCsrRoamResult val) +{ + switch (val) + { + CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND); + CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND); + CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED); + default: + return "unknown"; + } +} + + + +tANI_BOOLEAN csrGetBssIdBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tCsrBssid *pBssId ) +{ + vos_mem_copy(pBssId, &pSirBssDesc->bssId[ 0 ], sizeof(tCsrBssid)); + return( TRUE ); +} + + +tANI_BOOLEAN csrIsBssIdEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fEqual = FALSE; + tCsrBssid bssId1; + tCsrBssid bssId2; + + do { + if ( !pSirBssDesc1 ) break; + if ( !pSirBssDesc2 ) break; + + if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc1, &bssId1 ) ) break; + if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc2, &bssId2 ) ) break; + + //sirCompareMacAddr + fEqual = csrIsMacAddressEqual(pMac, &bssId1, &bssId2); + + } while( 0 ); + + return( fEqual ); +} + +tANI_BOOLEAN csrIsConnStateConnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateDisconnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnectedInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnected( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + if( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateConnectedInfra( pMac, sessionId ) || csrIsConnStateConnectedWds( pMac, sessionId) ) + return TRUE; + else + return FALSE; +} + +tANI_BOOLEAN csrIsConnStateInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedInfra( pMac, sessionId ) ); +} + +tANI_BOOLEAN csrIsConnStateIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateDisconnectedIbss( pMac, sessionId ) ); +} + + +tANI_BOOLEAN csrIsConnStateConnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnectedInfraAp( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == pMac->roam.roamSession[sessionId].connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ) ); +} + +tANI_BOOLEAN csrIsConnStateDisconnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedWds( pMac, sessionId ) || + csrIsConnStateDisconnectedWds( pMac, sessionId ) ); +} + +tANI_BOOLEAN csrIsConnStateAp( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession; + pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) + return eANI_BOOLEAN_FALSE; + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +tANI_BOOLEAN csrIsAnySessionInConnectState( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && + ( csrIsConnStateInfra( pMac, i ) + || csrIsConnStateIbss( pMac, i ) + || csrIsConnStateAp( pMac, i) ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_S8 csrGetInfraSessionId( tpAniSirGlobal pMac ) +{ + tANI_U8 i; + tANI_S8 sessionid = -1; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateInfra( pMac, i ) ) + { + sessionid = i; + break; + } + } + + return ( sessionid ); +} + +tANI_U8 csrGetInfraOperationChannel( tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 channel; + + if( CSR_IS_SESSION_VALID( pMac, sessionId )) + { + channel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel; + } + else + { + channel = 0; + } + return channel; +} + +tANI_BOOLEAN csrIsSessionClientAndConnected(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tCsrRoamSession *pSession = NULL; + if (CSR_IS_SESSION_VALID( pMac, sessionId) && csrIsConnStateInfra( pMac, sessionId)) + { + pSession = CSR_GET_SESSION( pMac, sessionId); + if (NULL != pSession->pCurRoamProfile) + { + if ((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE)) + return TRUE; + } + } + return FALSE; +} +//This routine will return operating channel on FIRST BSS that is active/operating to be used for concurrency mode. +//If other BSS is not up or not connected it will return 0 + +tANI_U8 csrGetConcurrentOperationChannel( tpAniSirGlobal pMac ) +{ + tCsrRoamSession *pSession = NULL; + tANI_U8 i = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if ( + (((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE)) && + (pSession->connectState == eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) + || + (((pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_STA_SAP_MODE)) && + (pSession->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + ) + return (pSession->connectedProfile.operationChannel); + } + + } + } + return 0; +} +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH + +#define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2) + +/* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */ + +#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2) +#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2) + +#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6) +#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2) +#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2) +#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6) + +void csrGetChFromHTProfile (tpAniSirGlobal pMac, tCsrRoamHTProfile *htp, + tANI_U16 och, tANI_U16 *cfreq, tANI_U16 *hbw) +{ + tANI_U16 cch, ch_bond; + + if (och > 14) + ch_bond = pMac->roam.configParam.channelBondingMode5GHz; + else + ch_bond = pMac->roam.configParam.channelBondingMode24GHz; + + cch = och; + *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); + + if (!ch_bond) { + goto ret; + } + smsLog(pMac, LOG1, + FL("##HTC: %d scbw: %d rcbw: %d sco: %d" +#ifdef WLAN_FEATURE_11AC + "VHTC: %d apc: %d apbw: %d" +#endif + ), + htp->htCapability, htp->htSupportedChannelWidthSet, + htp->htRecommendedTxWidthSet, htp->htSecondaryChannelOffset, +#ifdef WLAN_FEATURE_11AC + htp->vhtCapability, htp->apCenterChan, htp->apChanWidth +#endif + ); + +#ifdef WLAN_FEATURE_11AC + if (htp->vhtCapability) { + cch = htp->apCenterChan; + if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + *hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL); + else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) + *hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL); + + if (!*hbw && htp->htCapability) { + if (htp->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ) + *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); + else + *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); + } + } else +#endif + if (htp->htCapability) { + if (htp->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ) { + *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); + if (htp->htSecondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + cch = CSR_GET_HT40_PLUS_CCH(och); + else if (htp->htSecondaryChannelOffset == + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + cch = CSR_GET_HT40_MINUS_CCH(och); + } else { + cch = och; + *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); + } + } + +ret: + *cfreq = vos_chan_to_freq(cch); + return; +} + +v_U16_t csrCheckConcurrentChannelOverlap(tpAniSirGlobal pMac, v_U16_t sap_ch, + eCsrPhyMode sap_phymode, v_U8_t cc_switch_mode) +{ + tCsrRoamSession *pSession = NULL; + v_U8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED; + v_U16_t intf_ch=0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0, sap_cfreq = 0; + v_U16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch; + + if (pMac->roam.configParam.cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_DISABLE) + return 0; + + if (sap_ch !=0) { + + sap_cch = sap_ch; + sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); + + if (sap_ch > 14) + chb = pMac->roam.configParam.channelBondingMode5GHz; + else + chb = pMac->roam.configParam.channelBondingMode24GHz; + + if (chb) { + if (sap_phymode == eCSR_DOT11_MODE_11n || + sap_phymode == eCSR_DOT11_MODE_11n_ONLY) { + + sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); + if (chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch); + else if (chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch); + + } +#ifdef WLAN_FEATURE_11AC + else if (sap_phymode == eCSR_DOT11_MODE_11ac || + sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) { + /*11AC only 80/40/20 Mhz supported in Rome */ + if (pMac->roam.configParam.nVhtChannelWidth == + (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) { + sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL); + if (chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW-1)) + sap_cch = CSR_GET_HT80_PLUS_LL_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW-1)) + sap_cch = CSR_GET_HT80_PLUS_HL_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH-1)) + sap_cch = CSR_GET_HT80_MINUS_LH_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH-1)) + sap_cch = CSR_GET_HT80_MINUS_HH_CCH(sap_ch); + } else { + sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); + if (chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW-1)) + sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW-1)) + sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH-1)) + sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch); + else if (chb == + (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH-1)) + sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch); + } + } +#endif + } + sap_cfreq = vos_chan_to_freq(sap_cch); + } + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) { + if( !CSR_IS_SESSION_VALID( pMac, i ) ) + continue; + + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) { + if (((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) || + (pSession->pCurRoamProfile->csrPersona == + VOS_P2P_CLIENT_MODE)) && + (pSession->connectState == + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) { + intf_ch = pSession->connectedProfile.operationChannel; + csrGetChFromHTProfile(pMac, + &pSession->connectedProfile.HTProfile, intf_ch, + &intf_cfreq, &intf_hbw); + } else if(((pSession->pCurRoamProfile->csrPersona == + VOS_P2P_GO_MODE) || + (pSession->pCurRoamProfile->csrPersona == + VOS_STA_SAP_MODE)) && + (pSession->connectState != + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) { + if (sap_ch == 0) { + sap_ch = pSession->connectedProfile.operationChannel; + csrGetChFromHTProfile(pMac, + &pSession->connectedProfile.HTProfile, sap_ch, + &sap_cfreq, &sap_hbw); + } else if (sap_ch != + pSession->connectedProfile.operationChannel) { + intf_ch = pSession->connectedProfile.operationChannel; + csrGetChFromHTProfile(pMac, + &pSession->connectedProfile.HTProfile, intf_ch, + &intf_cfreq, &intf_hbw); + } + } + } + } + + + if (intf_ch && sap_ch != intf_ch && + cc_switch_mode != VOS_MCC_TO_SCC_SWITCH_FORCE) { + sap_lfreq = sap_cfreq - sap_hbw; + sap_hfreq = sap_cfreq + sap_hbw; + intf_lfreq = intf_cfreq -intf_hbw; + intf_hfreq = intf_cfreq +intf_hbw; + + smsLog(pMac, LOGE, + FL("\nSAP: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n" + "INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"), + sap_ch, vos_chan_to_freq(sap_ch), vos_freq_to_chan(sap_cfreq), + sap_cfreq, sap_hbw*2, sap_lfreq, sap_hfreq, + intf_ch, vos_chan_to_freq(intf_ch), + vos_freq_to_chan(intf_cfreq), + intf_cfreq, intf_hbw*2, intf_lfreq, intf_hfreq); + + if (!( + ((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) || + (sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) + || ((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) || + (intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq)) + )) { + intf_ch = 0; + } + } + else if (intf_ch && sap_ch!= intf_ch && + cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_FORCE) { + if (!((intf_ch < 14 && sap_ch < 14) || (intf_ch > 14 && sap_ch > 14))) + intf_ch = 0; + }else if (intf_ch == sap_ch) + intf_ch = 0; + + smsLog(pMac, LOGE, FL("##Concurrent Channels %s Interfering"), intf_ch == 0 ? + "Not" : "Are" ); + return intf_ch; +} +#endif + +tANI_BOOLEAN csrIsAllSessionDisconnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_TRUE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + fRc = eANI_BOOLEAN_FALSE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsStaSessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = NULL; + tANI_U32 countSta = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) { + countSta++; + } + } + } + } + + /* return TRUE if one of the following conditions is TRUE: + * - more than one STA session connected + */ + if ( countSta > 0) { + fRc = eANI_BOOLEAN_TRUE; + } + + return( fRc ); +} + +tANI_BOOLEAN csrIsP2pSessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = NULL; + tANI_U32 countP2pCli = 0; + tANI_U32 countP2pGo = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE) { + countP2pCli++; + } + + if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) { + countP2pGo++; + } + } + } + } + + /* return TRUE if one of the following conditions is TRUE: + * - at least one P2P CLI session is connected + * - at least one P2P GO session is connected + */ + if ( (countP2pCli > 0) || (countP2pGo > 0 ) ) { + fRc = eANI_BOOLEAN_TRUE; + } + + return( fRc ); +} + +tANI_BOOLEAN csrIsAnySessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i, count; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + count = 0; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + count++; + } + } + + if (count > 0) + { + fRc = eANI_BOOLEAN_TRUE; + } + return( fRc ); +} + +tANI_BOOLEAN csrIsInfraConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsConcurrentInfraConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i, noOfConnectedInfra = 0; + + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) ) + { + ++noOfConnectedInfra; + } + } + + // More than one Infra Sta Connected + if(noOfConnectedInfra > 1) + { + fRc = eANI_BOOLEAN_TRUE; + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsIBSSStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateIbss( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + + +tANI_BOOLEAN csrIsBTAMPStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedWds( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsConcurrentSessionRunning( tpAniSirGlobal pMac ) +{ + tANI_U32 sessionId, noOfCocurrentSession = 0; + eCsrConnectState connectState; + + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + connectState = pMac->roam.roamSession[sessionId].connectState; + if( (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == connectState) ) + { + ++noOfCocurrentSession; + } + } + } + + // More than one session is Up and Running + if(noOfCocurrentSession > 1) + { + fRc = eANI_BOOLEAN_TRUE; + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsInfraApStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 sessionId; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && (csrIsConnStateConnectedInfraAp(pMac, sessionId)) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); + +} + +tANI_BOOLEAN csrIsBTAMP( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return ( csrIsConnStateConnectedWds( pMac, sessionId ) ); +} + + +tANI_BOOLEAN csrIsConnStateDisconnected(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED == pMac->roam.roamSession[sessionId].connectState); +} + +tANI_BOOLEAN csrIsValidMcConcurrentSession(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc) +{ + tCsrRoamSession *pSession = NULL; + eAniBoolean status = eANI_BOOLEAN_FALSE; + + //Check for MCC support + if (!pMac->roam.configParam.fenableMCCMode) + { + return status; + } + + //Validate BeaconInterval + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL != pSession->pCurRoamProfile) + { + if (csrIsconcurrentsessionValid (pMac, sessionId, + pSession->pCurRoamProfile->csrPersona) + == eHAL_STATUS_SUCCESS ) + { + if (csrValidateMCCBeaconInterval( pMac, pBssDesc->channelId, + &pBssDesc->beaconInterval, sessionId, + pSession->pCurRoamProfile->csrPersona) + != eHAL_STATUS_SUCCESS) + { + status = eANI_BOOLEAN_FALSE; + } + else + { + status = eANI_BOOLEAN_TRUE; + } + } + else + { + status = eANI_BOOLEAN_FALSE; + } + } + } + return status; +} + +static tSirMacCapabilityInfo csrGetBssCapabilities( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps; + + //tSirMacCapabilityInfo is 16-bit + pal_get_U16( (tANI_U8 *)&pSirBssDesc->capabilityInfo, (tANI_U16 *)&dot11Caps ); + + return( dot11Caps ); +} + +tANI_BOOLEAN csrIsInfraBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.ess ); +} + + +tANI_BOOLEAN csrIsIbssBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.ibss ); +} + +tANI_BOOLEAN csrIsQoSBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.qos ); +} + +tANI_BOOLEAN csrIsPrivacy( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.privacy ); +} + + +tANI_BOOLEAN csrIs11dSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11dSupportEnabled); +} + + +tANI_BOOLEAN csrIs11hSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11hSupportEnabled); +} + + +tANI_BOOLEAN csrIs11eSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11eSupportEnabled); +} + +tANI_BOOLEAN csrIsMCCSupported ( tpAniSirGlobal pMac ) +{ + return(pMac->roam.configParam.fenableMCCMode); + +} + +tANI_BOOLEAN csrIsWmmSupported(tpAniSirGlobal pMac) +{ + if(eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode) + { + return eANI_BOOLEAN_FALSE; + } + else + { + return eANI_BOOLEAN_TRUE; + } +} + + + + +//pIes is the IEs for pSirBssDesc2 +tANI_BOOLEAN csrIsSsidEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 ) +{ + tANI_BOOLEAN fEqual = FALSE; + tSirMacSSid Ssid1, Ssid2; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tDot11fBeaconIEs *pIes1 = NULL; + tDot11fBeaconIEs *pIesLocal = pIes2; + + do { + if( ( NULL == pSirBssDesc1 ) || ( NULL == pSirBssDesc2 ) ) break; + if( !pIesLocal && !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesLocal)) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + break; + } + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( ( !pIes1->SSID.present ) || ( !pIesLocal->SSID.present ) ) break; + if ( pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid ) break; + vos_mem_copy(Ssid1.ssId, pIes1->SSID.ssid, pIes1->SSID.num_ssid); + vos_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid); + + fEqual = vos_mem_compare(Ssid1.ssId, Ssid2.ssId, pIesLocal->SSID.num_ssid); + + } while( 0 ); + if(pIes1) + { + vos_mem_free(pIes1); + } + if( pIesLocal && !pIes2 ) + { + vos_mem_free(pIesLocal); + } + + return( fEqual ); +} + +tANI_BOOLEAN csrIsAniWmeSupported(tDot11fIEAirgo *pIeAirgo) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + + if(pIeAirgo && pIeAirgo->present && pIeAirgo->PropCapability.present) + { + fRet = (tANI_BOOLEAN)(PROP_CAPABILITY_GET( WME, pIeAirgo->PropCapability.capability )); + } + + return fRet; +} + + + + +//pIes can be passed in as NULL if the caller doesn't have one prepared +tANI_BOOLEAN csrIsBssDescriptionWme( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + // Assume that WME is found... + tANI_BOOLEAN fWme = TRUE; + tDot11fBeaconIEs *pIesTemp = pIes; + + do + { + if(pIesTemp == NULL) + { + if( !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesTemp)) ) + { + fWme = FALSE; + break; + } + } + // if the AirgoProprietary indicator is found, then WME is supported... + if ( csrIsAniWmeSupported(&pIesTemp->Airgo) ) break; + // if the Wme Info IE is found, then WME is supported... + if ( CSR_IS_QOS_BSS(pIesTemp) ) break; + // if none of these are found, then WME is NOT supported... + fWme = FALSE; + } while( 0 ); + if( !csrIsWmmSupported( pMac ) && fWme) + { + if( !pIesTemp->HTCaps.present ) + { + fWme = FALSE; + } + } + if( ( pIes == NULL ) && ( NULL != pIesTemp ) ) + { + //we allocate memory here so free it before returning + vos_mem_free(pIesTemp); + } + + return( fWme ); +} + +tANI_BOOLEAN csrIsHcfEnabled( tDot11fIEAirgo *pIeAirgo ) +{ + tANI_BOOLEAN fHcfSupported = FALSE; + + fHcfSupported = ((tANI_BOOLEAN)(PROP_CAPABILITY_GET( WME, pIeAirgo->PropCapability.capability )) || + (pIeAirgo->present && pIeAirgo->HCF.present && pIeAirgo->HCF.enabled)); + + return( fHcfSupported ); +} + + +eCsrMediaAccessType csrGetQoSFromBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes ) +{ + eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF; + + if (NULL == pIes) + { + VOS_ASSERT( pIes != NULL ); + return( qosType ); + } + + do + { + // if we find WMM in the Bss Description, then we let this + // override and use WMM. + if ( csrIsBssDescriptionWme( hHal, pSirBssDesc, pIes ) ) + { + qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } + else + { + // if the QoS bit is on, then the AP is advertising 11E QoS... + if ( csrIsQoSBssDesc( pSirBssDesc ) ) + { + // which could be HCF or eDCF. + if ( csrIsHcfEnabled( &pIes->Airgo ) ) + { + qosType = eCSR_MEDIUM_ACCESS_11e_HCF; + } + else + { + qosType = eCSR_MEDIUM_ACCESS_11e_eDCF; + } + } + else + { + qosType = eCSR_MEDIUM_ACCESS_DCF; + } + // scale back based on the types turned on for the adapter... + if ( eCSR_MEDIUM_ACCESS_11e_eDCF == qosType && !csrIs11eSupported( hHal ) ) + { + qosType = eCSR_MEDIUM_ACCESS_DCF; + } + } + + } while(0); + + return( qosType ); +} + + + + +//Caller allocates memory for pIEStruct +eHalStatus csrParseBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIEStruct) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + int ieLen = (int)(pBssDesc->length + sizeof( pBssDesc->length ) - GET_FIELD_OFFSET( tSirBssDescription, ieFields )); + + if(ieLen > 0 && pIEStruct) + { + if(!DOT11F_FAILED(dot11fUnpackBeaconIEs( pMac, (tANI_U8 *)pBssDesc->ieFields, ieLen, pIEStruct ))) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + +//This function will allocate memory for the parsed IEs to the caller. Caller must free the memory +//after it is done with the data only if this function succeeds +eHalStatus csrGetParsedBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs **ppIEStruct) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if(pBssDesc && ppIEStruct) + { + *ppIEStruct = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( (*ppIEStruct) != NULL) + { + vos_mem_set((void *)*ppIEStruct, sizeof(tDot11fBeaconIEs), 0); + status = csrParseBssDescriptionIEs(hHal, pBssDesc, *ppIEStruct); + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(*ppIEStruct); + *ppIEStruct = NULL; + } + } + else + { + smsLog( pMac, LOGE, FL(" failed to allocate memory") ); + VOS_ASSERT( 0 ); + return eHAL_STATUS_FAILURE; + } + } + + return (status); +} + + + + +tANI_BOOLEAN csrIsNULLSSID( tANI_U8 *pBssSsid, tANI_U8 len ) +{ + tANI_BOOLEAN fNullSsid = FALSE; + + tANI_U32 SsidLength; + tANI_U8 *pSsidStr; + + do + { + if ( 0 == len ) + { + fNullSsid = TRUE; + break; + } + + //Consider 0 or space for hidden SSID + if ( 0 == pBssSsid[0] ) + { + fNullSsid = TRUE; + break; + } + + SsidLength = len; + pSsidStr = pBssSsid; + + while ( SsidLength ) + { + if( *pSsidStr ) + break; + + pSsidStr++; + SsidLength--; + } + + if( 0 == SsidLength ) + { + fNullSsid = TRUE; + break; + } + } + while( 0 ); + + return fNullSsid; +} + + +tANI_U32 csrGetFragThresh( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return pMac->roam.configParam.FragmentationThreshold; +} + +tANI_U32 csrGetRTSThresh( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return pMac->roam.configParam.RTSThreshold; +} + +eCsrPhyMode csrTranslateToPhyModeFromBssDesc( tSirBssDescription *pSirBssDesc ) +{ + eCsrPhyMode phyMode; + + switch ( pSirBssDesc->nwType ) + { + case eSIR_11A_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11a; + break; + + case eSIR_11B_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11b; + break; + + case eSIR_11G_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11g; + break; + + case eSIR_11N_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11n; + break; +#ifdef WLAN_FEATURE_11AC + case eSIR_11AC_NW_TYPE: + default: + phyMode = eCSR_DOT11_MODE_11ac; +#else + default: + phyMode = eCSR_DOT11_MODE_11n; +#endif + break; + } + return( phyMode ); +} + + +tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode) +{ + tANI_U32 ret; + + switch(csrDot11Mode) + { + case eCSR_CFG_DOT11_MODE_AUTO: + smsLog(pMac, LOGW, FL(" Warning: sees eCSR_CFG_DOT11_MODE_AUTO ")); + //We cannot decide until now. + if(pMac->roam.configParam.ProprietaryRatesEnabled) + { + ret = WNI_CFG_DOT11_MODE_TAURUS; + } + else + { + ret = WNI_CFG_DOT11_MODE_11AC; + } + break; + case eCSR_CFG_DOT11_MODE_TAURUS: + ret = WNI_CFG_DOT11_MODE_TAURUS; + break; + case eCSR_CFG_DOT11_MODE_11A: + ret = WNI_CFG_DOT11_MODE_11A; + break; + case eCSR_CFG_DOT11_MODE_11B: + ret = WNI_CFG_DOT11_MODE_11B; + break; + case eCSR_CFG_DOT11_MODE_11G: + ret = WNI_CFG_DOT11_MODE_11G; + break; + case eCSR_CFG_DOT11_MODE_11N: + ret = WNI_CFG_DOT11_MODE_11N; + break; + case eCSR_CFG_DOT11_MODE_POLARIS: + ret = WNI_CFG_DOT11_MODE_POLARIS; + break; + case eCSR_CFG_DOT11_MODE_TITAN: + ret = WNI_CFG_DOT11_MODE_TITAN; + break; + case eCSR_CFG_DOT11_MODE_11G_ONLY: + ret = WNI_CFG_DOT11_MODE_11G_ONLY; + break; + case eCSR_CFG_DOT11_MODE_11N_ONLY: + ret = WNI_CFG_DOT11_MODE_11N_ONLY; + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + ret = WNI_CFG_DOT11_MODE_11AC_ONLY; + break; + case eCSR_CFG_DOT11_MODE_11AC: + ret = WNI_CFG_DOT11_MODE_11AC; + break; +#endif + default: + smsLog(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"), csrDot11Mode); + if(eCSR_BAND_24 == pMac->roam.configParam.eBand) + { + ret = WNI_CFG_DOT11_MODE_11G; + } + else + { + ret = WNI_CFG_DOT11_MODE_11A; + } + break; + } + + return (ret); +} + + +//This function should only return the super set of supported modes. 11n implies 11b/g/a/n. +eHalStatus csrGetPhyModeFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription, + eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrPhyMode phyMode = csrTranslateToPhyModeFromBssDesc(pBSSDescription); + + if( pIes ) + { + if(pIes->Airgo.present) + { + if(pIes->Airgo.PropCapability.present) + { + if( PROP_CAPABILITY_GET( TAURUS, pIes->Airgo.PropCapability.capability )) + { + phyMode = eCSR_DOT11_MODE_TAURUS; + } + } + } + if(pIes->HTCaps.present && (eCSR_DOT11_MODE_TAURUS != phyMode)) + { + phyMode = eCSR_DOT11_MODE_11n; + } + +#ifdef WLAN_FEATURE_11AC + if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps)) { + phyMode = eCSR_DOT11_MODE_11ac; + } +#endif + *pPhyMode = phyMode; + } + + return (status); + +} + + +//This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes matches +//bssPhyMode is the mode derived from the BSS description +//f5GhzBand is derived from the channel id of BSS description +tANI_BOOLEAN csrGetPhyModeInUse( eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode, tANI_BOOLEAN f5GhzBand, + eCsrCfgDot11Mode *pCfgDot11ModeToUse ) +{ + tANI_BOOLEAN fMatch = FALSE; + eCsrCfgDot11Mode cfgDot11Mode; + + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; // to suppress compiler warning + + switch( phyModeIn ) + { + case eCSR_DOT11_MODE_abg: //11a or 11b or 11g + if( f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + else if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + break; + + case eCSR_DOT11_MODE_11a: //11a + if( f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + break; + + case eCSR_DOT11_MODE_11a_ONLY: //11a + if( eCSR_DOT11_MODE_11a == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + break; + + case eCSR_DOT11_MODE_11g: + if(!f5GhzBand) + { + if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + } + break; + + case eCSR_DOT11_MODE_11g_ONLY: + if( eCSR_DOT11_MODE_11g == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + break; + + case eCSR_DOT11_MODE_11b: + if( !f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + break; + + case eCSR_DOT11_MODE_11b_ONLY: + if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + break; + + case eCSR_DOT11_MODE_11n: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: +#endif + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + + case eCSR_DOT11_MODE_TAURUS: + default: +#ifdef WLAN_FEATURE_11AC + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; +#else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; +#endif + break; + } + break; + + case eCSR_DOT11_MODE_11n_ONLY: + if((eCSR_DOT11_MODE_11n == bssPhyMode) || (eCSR_DOT11_MODE_TAURUS == bssPhyMode)) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + + } + + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + case eCSR_DOT11_MODE_11ac: + case eCSR_DOT11_MODE_TAURUS: + default: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + break; + } + break; + + case eCSR_DOT11_MODE_11ac_ONLY: + if((eCSR_DOT11_MODE_11ac == bssPhyMode) || (eCSR_DOT11_MODE_TAURUS == bssPhyMode)) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + break; +#endif + + case eCSR_DOT11_MODE_TAURUS: + default: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + break; +#endif + case eCSR_DOT11_MODE_TAURUS: + default: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + break; + } + break; + } + + if ( fMatch && pCfgDot11ModeToUse ) + { +#ifdef WLAN_FEATURE_11AC + if(cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))) + { + *pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + else +#endif + { + *pCfgDot11ModeToUse = cfgDot11Mode; + } + } + return( fMatch ); +} + + +//This function decides whether the one of the bit of phyMode is matching the mode in the BSS and allowed by the user +//setting, pMac->roam.configParam.uCfgDot11Mode. It returns the mode that fits the criteria. +tANI_BOOLEAN csrIsPhyModeMatch( tpAniSirGlobal pMac, tANI_U32 phyMode, + tSirBssDescription *pSirBssDesc, tCsrRoamProfile *pProfile, + eCsrCfgDot11Mode *pReturnCfgDot11Mode, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fMatch = FALSE; + eCsrPhyMode phyModeInBssDesc, phyMode2; + eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_TAURUS; + tANI_U32 bitMask, loopCount; + + if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pSirBssDesc, &phyModeInBssDesc, pIes ))) + { + //In case some change change eCSR_DOT11_MODE_TAURUS to non-0 + if ( (0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode)) + { + //Taurus means anything + if ( eCSR_CFG_DOT11_MODE_ABG == pMac->roam.configParam.uCfgDot11Mode ) + { + phyMode = eCSR_DOT11_MODE_abg; + } + else if(eCSR_CFG_DOT11_MODE_AUTO == pMac->roam.configParam.uCfgDot11Mode) + { + if(pMac->roam.configParam.ProprietaryRatesEnabled) + { + phyMode = eCSR_DOT11_MODE_TAURUS; + } + else + { + +#ifdef WLAN_FEATURE_11AC + phyMode = eCSR_DOT11_MODE_11ac; +#else + phyMode = eCSR_DOT11_MODE_11n; +#endif + + } + } + else + { + //user's pick + phyMode = pMac->roam.configParam.phyMode; + } + } + if ( (0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode) ) + { + if(0 != phyMode) + { + if(eCSR_DOT11_MODE_AUTO & phyMode) + { + phyMode2 = eCSR_DOT11_MODE_AUTO & phyMode; + } + else + { + phyMode2 = eCSR_DOT11_MODE_TAURUS & phyMode; + } + } + else + { + phyMode2 = phyMode; + } + fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId), + &cfgDot11ModeToUse ); + } + else + { + bitMask = 1; + loopCount = 0; + while(loopCount < eCSR_NUM_PHY_MODE) + { + if(0 != ( phyMode2 = (phyMode & (bitMask << loopCount++)) )) + { + fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId), + &cfgDot11ModeToUse ); + if(fMatch) break; + } + } + } + if ( fMatch && pReturnCfgDot11Mode ) + { + if( pProfile ) + { + /* IEEE 11n spec (8.4.3): HT STA shall eliminate TKIP as a + * choice for the pairwise cipher suite if CCMP is advertised + * by the AP or if the AP included an HT capabilities element + * in its Beacons and Probe Response. + */ + if( (!CSR_IS_11n_ALLOWED( pProfile->negotiatedUCEncryptionType )) && + ((eCSR_CFG_DOT11_MODE_11N == cfgDot11ModeToUse) || +#ifdef WLAN_FEATURE_11AC + (eCSR_CFG_DOT11_MODE_11AC == cfgDot11ModeToUse) || +#endif + (eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11ModeToUse)) ) + { + //We cannot do 11n here + if( !CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId) ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + } + } + *pReturnCfgDot11Mode = cfgDot11ModeToUse; + } + } + + return( fMatch ); +} + + +eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode ) +{ + eCsrCfgDot11Mode cfgDot11ModeToUse; + eCsrBand eBand = pMac->roam.configParam.eBand; + + + if ((0 == phyMode) || +#ifdef WLAN_FEATURE_11AC + (eCSR_DOT11_MODE_11ac & phyMode) || +#endif + (eCSR_DOT11_MODE_AUTO & phyMode)) + { +#ifdef WLAN_FEATURE_11AC + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC; + } + else +#endif + { + /* Default to 11N mode if user has configured 11ac mode + * and FW doesn't supports 11ac mode . + */ + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + } + else + { + if( ( eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + else if ( eCSR_DOT11_MODE_abg & phyMode ) + { + if( eCSR_BAND_24 != eBand ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + } + else if( ( eCSR_DOT11_MODE_11a | eCSR_DOT11_MODE_11a_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + else if( ( eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B; + } + } + + return ( cfgDot11ModeToUse ); +} + + + + +tANI_U32 csrGet11hPowerConstraint( tHalHandle hHal, tDot11fIEPowerConstraints *pPowerConstraint ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 localPowerConstraint = 0; + + // check if .11h support is enabled, if not, the power constraint is 0. + if(pMac->roam.configParam.Is11hSupportEnabled && pPowerConstraint->present) + { + localPowerConstraint = pPowerConstraint->localPowerConstraints; + } + + return( localPowerConstraint ); +} + + +tANI_BOOLEAN csrIsProfileWpa( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fWpaProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: +#endif + fWpaProfile = TRUE; + break; + + default: + fWpaProfile = FALSE; + break; + } + + if ( fWpaProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + fWpaProfile = TRUE; + break; + + default: + fWpaProfile = FALSE; + break; + } + } + return( fWpaProfile ); +} + +tANI_BOOLEAN csrIsProfileRSN( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fRSNProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_RSN: + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_RSN: +#endif +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + fRSNProfile = TRUE; + break; + + default: + fRSNProfile = FALSE; + break; + } + + if ( fRSNProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + // !!REVIEW - For WPA2, use of RSN IE mandates + // use of AES as encryption. Here, we qualify + // even if encryption type is WEP or TKIP + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + fRSNProfile = TRUE; + break; + + default: + fRSNProfile = FALSE; + break; + } + } + return( fRSNProfile ); +} + +eHalStatus +csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona) +{ + tANI_U32 sessionId = 0; + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if (cursessionId != sessionId ) + { + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + continue; + } + + switch (currBssPersona) + { + case VOS_STA_MODE: + smsLog(pMac, LOG1, FL(" **** STA session ****")); + return eHAL_STATUS_SUCCESS; + + case VOS_STA_SAP_MODE: +#ifndef WLAN_FEATURE_MBSSID + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE)&& + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****SoftAP mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else +#endif + if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) || + (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + + case VOS_P2P_GO_MODE: + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) && + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****P2P GO mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) || + (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED) ) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + case VOS_IBSS_MODE: + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE) && + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****IBSS mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE || + pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + case VOS_P2P_CLIENT_MODE: + smsLog(pMac, LOG1, FL(" **** P2P-Client session ****")); + return eHAL_STATUS_SUCCESS; + default : + smsLog(pMac, LOGE, FL("***Persona not handled = %d*****"),currBssPersona); + break; + } + } + } + return eHAL_STATUS_SUCCESS; + +} + +eHalStatus csrUpdateMCCp2pBeaconInterval(tpAniSirGlobal pMac) +{ + tANI_U32 sessionId = 0; + + //If MCC is not supported just break and return SUCCESS + if ( !pMac->roam.configParam.fenableMCCMode){ + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + /* If GO in MCC support different beacon interval, + * change the BI of the P2P-GO */ + if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) + { + /* Handle different BI scneario based on the configuration set. + * If Config is set to 0x02 then Disconnect all the P2P clients + * associated. If config is set to 0x04 then update the BI + * without disconnecting all the clients + */ + if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x04) && + (pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)) + { + return csrSendChngMCCBeaconInterval( pMac, sessionId); + } + //If the configuration of fAllowMCCGODiffBI is set to other than 0x04 + else if ( pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval) + { + return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, eCSR_ROAM_RESULT_NONE); + } + } + } + return eHAL_STATUS_FAILURE; +} + +tANI_U16 csrCalculateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U16 sta_bi, tANI_U16 go_gbi) +{ + tANI_U8 num_beacons = 0; + tANI_U8 is_multiple = 0; + tANI_U16 go_cbi = 0; + tANI_U16 go_fbi = 0; + tANI_U16 sta_cbi = 0; + + //If GO's given beacon Interval is less than 100 + if(go_gbi < 100) + go_cbi = 100; + //if GO's given beacon Interval is greater than or equal to 100 + else + go_cbi = 100 + (go_gbi % 100); + + if ( sta_bi == 0 ) + { + /* There is possibility to receive zero as value. + Which will cause divide by zero. Hence initialise with 100 + */ + sta_bi = 100; + smsLog(pMac, LOGW, + FL("sta_bi 2nd parameter is zero, initialise to %d"), sta_bi); + } + + // check, if either one is multiple of another + if (sta_bi > go_cbi) + { + is_multiple = !(sta_bi % go_cbi); + } + else + { + is_multiple = !(go_cbi % sta_bi); + } + // if it is multiple, then accept GO's beacon interval range [100,199] as it is + if (is_multiple) + { + return go_cbi; + } + //else , if it is not multiple, then then check for number of beacons to be + //inserted based on sta BI + num_beacons = sta_bi / 100; + if (num_beacons) + { + // GO's final beacon interval will be aligned to sta beacon interval, but + //in the range of [100, 199]. + sta_cbi = sta_bi / num_beacons; + go_fbi = sta_cbi; + } + else + { + // if STA beacon interval is less than 100, use GO's change bacon interval + //instead of updating to STA's beacon interval. + go_fbi = go_cbi; + } + return go_fbi; +} + +eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, + tANI_U16 *beaconInterval, tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona) +{ + tANI_U32 sessionId = 0; + tANI_U16 new_beaconInterval = 0; + + //If MCC is not supported just break + if (!pMac->roam.configParam.fenableMCCMode){ + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if (cursessionId != sessionId ) + { + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + continue; + } + + switch (currBssPersona) + { + case VOS_STA_MODE: + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_P2P_CLIENT_MODE)) //check for P2P client mode + { + smsLog(pMac, LOG1, FL(" Beacon Interval Validation not required for STA/CLIENT")); + } + //IF SAP has started and STA wants to connect on different channel MCC should + //MCC should not be enabled so making it false to enforce on same channel + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) + { + if (pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) + { + smsLog(pMac, LOGE, FL("*** MCC with SAP+STA sessions ****")); + return eHAL_STATUS_SUCCESS; + } + } + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) //Check for P2P go scenario + { + /* if GO in MCC support different beacon interval, + * change the BI of the P2P-GO */ + if ((pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) && + (pMac->roam.roamSession[sessionId].bssParams.beaconInterval + != *beaconInterval)) + { + /* if GO in MCC support different beacon interval, return success */ + if ( pMac->roam.configParam.fAllowMCCGODiffBI == 0x01) + { + return eHAL_STATUS_SUCCESS; + } + // Send only Broadcast disassoc and update beaconInterval + //If configuration is set to 0x04 then dont + // disconnect all the station + else if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x02) || + (pMac->roam.configParam.fAllowMCCGODiffBI == 0x04)) + { + //Check to pass the right beacon Interval + new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, *beaconInterval, + pMac->roam.roamSession[sessionId].bssParams.beaconInterval); + smsLog(pMac, LOG1, FL(" Peer AP BI : %d, new Beacon Interval: %d"),*beaconInterval,new_beaconInterval ); + //Update the becon Interval + if (new_beaconInterval != pMac->roam.roamSession[sessionId].bssParams.beaconInterval) + { + //Update the beaconInterval now + smsLog(pMac, LOGE, FL(" Beacon Interval got changed config used: %d\n"), + pMac->roam.configParam.fAllowMCCGODiffBI); + + pMac->roam.roamSession[sessionId].bssParams.beaconInterval = new_beaconInterval; + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_TRUE; + return csrUpdateMCCp2pBeaconInterval(pMac); + } + return eHAL_STATUS_SUCCESS; + } + //Disconnect the P2P session + else if (pMac->roam.configParam.fAllowMCCGODiffBI == 0x03) + { + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_FALSE; + return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SEND_P2P_STOP_BSS, eCSR_ROAM_RESULT_NONE); + } + else + { + smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to preferred AP...")); + return eHAL_STATUS_FAILURE; + } + } + } + break; + + case VOS_P2P_CLIENT_MODE: + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_STA_MODE)) //check for P2P client mode + { + smsLog(pMac, LOG1, FL(" Ignore Beacon Interval Validation...")); + } + //IF SAP has started and STA wants to connect on different channel MCC should + //MCC should not be enabled so making it false to enforce on same channel + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) + { + if (pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) + { + smsLog(pMac, LOGE, FL("***MCC is not enabled for SAP + CLIENT****")); + return eHAL_STATUS_FAILURE; + } + } + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) //Check for P2P go scenario + { + if ((pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) && + (pMac->roam.roamSession[sessionId].bssParams.beaconInterval + != *beaconInterval)) + { + smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to P2P_GO network ...")); + return eHAL_STATUS_FAILURE; + } + } + break; + + case VOS_P2P_GO_MODE : + { + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + ((pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_P2P_CLIENT_MODE) || + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_STA_MODE))) //check for P2P_client scenario + { + if ((pMac->roam.roamSession[sessionId].connectedProfile.operationChannel + == 0 )&& + (pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval + == 0)) + { + continue; + } + + + if (csrIsConnStateConnectedInfra(pMac, sessionId) && + (pMac->roam.roamSession[sessionId].connectedProfile.operationChannel + != channelId ) && + (pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval + != *beaconInterval)) + { + /* + * Updated beaconInterval should be used only when we are starting a new BSS + * not incase of client or STA case + */ + //Calculate beacon Interval for P2P-GO incase of MCC + new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, + pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval, + *beaconInterval ); + if(*beaconInterval != new_beaconInterval) + *beaconInterval = new_beaconInterval; + return eHAL_STATUS_SUCCESS; + } + } + } + break; + + default : + smsLog(pMac, LOGE, FL(" Persona not supported : %d"),currBssPersona); + return eHAL_STATUS_FAILURE; + } + } + } + + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* Function to return TRUE if the authtype is 11r */ +tANI_BOOLEAN csrIsAuthType11r( eCsrAuthType AuthType, tANI_U8 mdiePresent) +{ + switch ( AuthType ) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + if(mdiePresent) + return TRUE; + break; + case eCSR_AUTH_TYPE_FT_RSN_PSK: + case eCSR_AUTH_TYPE_FT_RSN: + return TRUE; + break; + default: + break; + } + return FALSE; +} + +/* Function to return TRUE if the profile is 11r */ +tANI_BOOLEAN csrIsProfile11r( tCsrRoamProfile *pProfile ) +{ + return csrIsAuthType11r( pProfile->negotiatedAuthType, pProfile->MDID.mdiePresent ); +} + +#endif + +#ifdef FEATURE_WLAN_ESE + +/* Function to return TRUE if the authtype is ESE */ +tANI_BOOLEAN csrIsAuthTypeESE( eCsrAuthType AuthType ) +{ + switch ( AuthType ) + { + case eCSR_AUTH_TYPE_CCKM_WPA: + case eCSR_AUTH_TYPE_CCKM_RSN: + return TRUE; + break; + default: + break; + } + return FALSE; +} + +/* Function to return TRUE if the profile is ESE */ +tANI_BOOLEAN csrIsProfileESE( tCsrRoamProfile *pProfile ) +{ + return (csrIsAuthTypeESE( pProfile->negotiatedAuthType )); +} + +#endif + +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fWapiProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + fWapiProfile = TRUE; + break; + + default: + fWapiProfile = FALSE; + break; + } + + if ( fWapiProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_WPI: + fWapiProfile = TRUE; + break; + + default: + fWapiProfile = FALSE; + break; + } + } + return( fWapiProfile ); +} + +static tANI_BOOLEAN csrIsWapiOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 ) +{ + return (vos_mem_compare(Oui1, Oui2, CSR_WAPI_OUI_SIZE)); +} + +static tANI_BOOLEAN csrIsWapiOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Cypher[], + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + tANI_U8 idx; + + for ( idx = 0; idx < cAllCyphers; idx++ ) + { + if ( csrIsWapiOuiEqual( pMac, AllCyphers[ idx ], Cypher ) ) + { + fYes = TRUE; + break; + } + } + + if ( fYes && Oui ) + { + vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WAPI_OUI_SIZE); + } + + return( fYes ); +} +#endif /* FEATURE_WLAN_WAPI */ + +static tANI_BOOLEAN csrIsWpaOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 ) +{ + return(vos_mem_compare(Oui1, Oui2, CSR_WPA_OUI_SIZE)); +} + +static tANI_BOOLEAN csrIsOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Cypher[], + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + tANI_U8 idx; + + for ( idx = 0; idx < cAllCyphers; idx++ ) + { + if ( csrIsWpaOuiEqual( pMac, AllCyphers[ idx ], Cypher ) ) + { + fYes = TRUE; + break; + } + } + + if ( fYes && Oui ) + { + vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WPA_OUI_SIZE); + } + + return( fYes ); +} + +static tANI_BOOLEAN csrMatchRSNOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui[ouiIndex], Oui ) ); + +} + +#ifdef FEATURE_WLAN_WAPI +static tANI_BOOLEAN csrMatchWapiOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + return( csrIsWapiOuiMatch( pMac, AllCyphers, cAllCyphers, csrWapiOui[ouiIndex], Oui ) ); + +} +#endif /* FEATURE_WLAN_WAPI */ + +static tANI_BOOLEAN csrMatchWPAOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui[ouiIndex], Oui ) ); + +} + +#ifdef FEATURE_WLAN_WAPI +static tANI_BOOLEAN csrIsAuthWapiCert( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[1], Oui ) ); +} +static tANI_BOOLEAN csrIsAuthWapiPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[2], Oui ) ); +} +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/* + * Function for 11R FT Authentication. We match the FT Authentication Cipher suite + * here. This matches for FT Auth with the 802.1X exchange. + * + */ +static tANI_BOOLEAN csrIsFTAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[03], Oui ) ); +} + +/* + * Function for 11R FT Authentication. We match the FT Authentication Cipher suite + * here. This matches for FT Auth with the PSK. + * + */ +static tANI_BOOLEAN csrIsFTAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[04], Oui ) ); +} + +#endif + +#ifdef FEATURE_WLAN_ESE + +/* + * Function for ESE CCKM AKM Authentication. We match the CCKM AKM Authentication Key Management suite + * here. This matches for CCKM AKM Auth with the 802.1X exchange. + * + */ +static tANI_BOOLEAN csrIsEseCckmAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ) ); +} + +static tANI_BOOLEAN csrIsEseCckmAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[06], Oui ) ); +} + +#endif + +static tANI_BOOLEAN csrIsAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) ); +} +static tANI_BOOLEAN csrIsAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[02], Oui ) ); +} + +#ifdef WLAN_FEATURE_11W +static tANI_BOOLEAN csrIsAuthRSNPskSha256( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[07], Oui ); +} +static tANI_BOOLEAN csrIsAuthRSN8021xSha256(tpAniSirGlobal pMac, + tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[8], Oui ); +} +#endif + +static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[01], Oui ) ); +} + +static tANI_BOOLEAN csrIsAuthWpaPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[02], Oui ) ); +} + +tANI_U8 csrGetOUIIndexFromCipher( eCsrEncryptionType enType ) +{ + tANI_U8 OUIIndex; + + switch ( enType ) + { + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + OUIIndex = CSR_OUI_WEP104_INDEX; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX; + break; + case eCSR_ENCRYPT_TYPE_AES: + OUIIndex = CSR_OUI_AES_INDEX; + break; + case eCSR_ENCRYPT_TYPE_NONE: + OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: //HOWTO handle this? + OUIIndex = CSR_OUI_RESERVED_INDEX; + break; + }//switch + + return OUIIndex; +} + +tANI_BOOLEAN csrGetRSNInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIERSN *pRSNIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + tCsrRSNCapabilities *Capabilities, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0, i; + tANI_U8 Unicast[ CSR_RSN_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_RSN_OUI_SIZE ]; + tANI_U8 AuthSuites[ CSR_RSN_MAX_AUTH_SUITES ][ CSR_RSN_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_RSN_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ CSR_RSN_MAX_MULTICAST_CYPHERS ][ CSR_RSN_OUI_SIZE ]; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + do{ + if ( pRSNIe->present ) + { + cMulticastCyphers++; + vos_mem_copy(MulticastCyphers, pRSNIe->gp_cipher_suite, CSR_RSN_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pRSNIe->pwise_cipher_suite_count); + cAuthSuites = (tANI_U8)(pRSNIe->akm_suite_count); + for(i = 0; i < cAuthSuites && i < CSR_RSN_MAX_AUTH_SUITES; i++) + { + vos_mem_copy((void *)&AuthSuites[i], + (void *)&pRSNIe->akm_suites[i], + CSR_RSN_OUI_SIZE); + } + + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, pRSNIe->pwise_cipher_suites, cUnicastCyphers, + csrGetOUIIndexFromCipher( enType ), Unicast ); + + if( !fAcceptableCyphers ) break; + + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] ), Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + /* Initializing with FALSE as it has TRUE value already */ + fAcceptableCyphers = FALSE; + for (i = 0 ; i < pAuthType->numEntries; i++) + { + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + #ifdef WLAN_FEATURE_VOWIFI_11R + /* Changed the AKM suites according to order of preference */ + if ( csrIsFTAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_FT_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_FT_RSN; + } + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsFTAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_FT_RSN_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_FT_RSN_PSK; + } +#endif +#ifdef FEATURE_WLAN_ESE + /* ESE only supports 802.1X. No PSK. */ + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_CCKM_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_CCKM_RSN; + } +#endif + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN; + } + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_PSK; + } +#ifdef WLAN_FEATURE_11W + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPskSha256( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && + csrIsAuthRSN8021xSha256(pMac, AuthSuites, + cAuthSuites, Authentication)) { + if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == + pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } +#endif + + // The 1st auth type in the APs RSN IE, to match stations connecting + // profiles auth type will cause us to exit this loop + // This is added as some APs advertise multiple akms in the RSN IE. + if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType) + { + fAcceptableCyphers = TRUE; + break; + } + } // for + } + + }while (0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy(MulticastCypher, Multicast, CSR_RSN_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy(UnicastCypher, Unicast, CSR_RSN_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy(AuthSuite, Authentication, CSR_RSN_OUI_SIZE); + } + + if ( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + if ( Capabilities ) + { + Capabilities->PreAuthSupported = (pRSNIe->RSN_Cap[0] >> 0) & 0x1 ; // Bit 0 PreAuthentication + Capabilities->NoPairwise = (pRSNIe->RSN_Cap[0] >> 1) & 0x1 ; // Bit 1 No Pairwise + Capabilities->PTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 2) & 0x3 ; // Bit 2, 3 PTKSA Replay Counter + Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4, 5 GTKSA Replay Counter + Capabilities->MFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1 ; // Bit 6 MFPR + Capabilities->MFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1 ; // Bit 7 MFPC + Capabilities->Reserved = pRSNIe->RSN_Cap[1] & 0xff ; // remaining reserved + } + } + return( fAcceptableCyphers ); +} + +#ifdef WLAN_FEATURE_11W +/* --------------------------------------------------------------------------- + \fn csrIsPMFCapabilitiesInRSNMatch + + \brief this function is to match our current capabilities with the AP + to which we are expecting make the connection. + + \param hHal - HAL Pointer + pFilterMFPEnabled - given by supplicant to us to specify what kind + of connection supplicant is expecting to make + if it is enabled then make PMF connection. + if it is disabled then make normal connection. + pFilterMFPRequired - given by supplicant based on our configuration + if it is 1 then we will require mandatory + PMF connection and if it is 0 then we PMF + connection is optional. + pFilterMFPCapable - given by supplicant based on our configuration + if it 1 then we are PMF capable and if it 0 + then we are not PMF capable. + pRSNIe - RSNIe from Beacon/probe response of + neighbor AP against which we will compare + our capabilities. + + \return tANI_BOOLEAN - if our PMF capabilities matches with AP then we + will return true to indicate that we are good + to make connection with it. Else we will return + false. + -------------------------------------------------------------------------------*/ +static tANI_BOOLEAN +csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal, + tANI_BOOLEAN *pFilterMFPEnabled, + tANI_U8 *pFilterMFPRequired, + tANI_U8 *pFilterMFPCapable, + tDot11fIERSN *pRSNIe) +{ + tANI_U8 apProfileMFPCapable = 0; + tANI_U8 apProfileMFPRequired = 0; + if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable && pFilterMFPRequired) + { + /* Extracting MFPCapable bit from RSN Ie */ + apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1; + apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1; + if (*pFilterMFPEnabled && *pFilterMFPCapable && *pFilterMFPRequired + && (apProfileMFPCapable == 0)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "AP is not capable to make PMF connection"); + return VOS_FALSE; + } + else if (*pFilterMFPEnabled && *pFilterMFPCapable && + !(*pFilterMFPRequired) && (apProfileMFPCapable == 0)) + { + /* + * This is tricky, because supplicant asked us to make mandatory + * PMF connection eventhough PMF connection is optional here. + * so if AP is not capable of PMF then drop it. Don't try to + * connect with it. + */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "we need PMF connection & AP isn't capable to make PMF connection"); + return VOS_FALSE; + } + else if (!(*pFilterMFPCapable) && + apProfileMFPCapable && apProfileMFPRequired) + { + + /* + * In this case, AP with whom we trying to connect requires + * mandatory PMF connections and we are not capable so this AP + * is not good choice to connect + */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "AP needs PMF connection and we are not capable of pmf connection"); + return VOS_FALSE; + } + else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable && + (apProfileMFPCapable == 1)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "we don't need PMF connection eventhough both parties are capable"); + return VOS_FALSE; + } + } + return VOS_TRUE; +} +#endif + +tANI_BOOLEAN csrIsRSNMatch( tHalHandle hHal, tCsrAuthList *pAuthType, + eCsrEncryptionType enType, + tCsrEncryptionList *pEnMcType, + tANI_BOOLEAN *pMFPEnabled, tANI_U8 *pMFPRequired, + tANI_U8 *pMFPCapable, + tDot11fBeaconIEs *pIes, + eCsrAuthType *pNegotiatedAuthType, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fRSNMatch = FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fRSNMatch = csrGetRSNInformation( hHal, pAuthType, enType, pEnMcType, &pIes->RSN, NULL, NULL, NULL, NULL, + pNegotiatedAuthType, pNegotiatedMCCipher ); +#ifdef WLAN_FEATURE_11W + /* If all the filter matches then finally checks for PMF capabilities */ + if (fRSNMatch) + { + fRSNMatch = csrIsPMFCapabilitiesInRSNMatch( hHal, pMFPEnabled, + pMFPRequired, pMFPCapable, + &pIes->RSN); + } +#endif + return( fRSNMatch ); +} + + +tANI_BOOLEAN csrLookupPMKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pPMKId ) +{ + tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE; + tANI_U32 Index; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return FALSE; + } + + do + { + for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) + { + smsLog(pMac, LOG1, "match PMKID "MAC_ADDRESS_STR " to ", + MAC_ADDR_ARRAY(pBSSId)); + if( vos_mem_compare(pBSSId, pSession->PmkidCacheInfo[Index].BSSID, sizeof(tCsrBssid)) ) + { + // match found + fMatchFound = TRUE; + break; + } + } + + if( !fMatchFound ) break; + + vos_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID, CSR_RSN_PMKID_SIZE); + + fRC = TRUE; + } + while( 0 ); + smsLog(pMac, LOGW, "csrLookupPMKID called return match = %d pMac->roam.NumPmkidCache = %d", + fRC, pSession->NumPmkidCache); + + return fRC; +} + + +tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRSNMatch; + tANI_U8 cbRSNIe = 0; + tANI_U8 UnicastCypher[ CSR_RSN_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_RSN_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_RSN_OUI_SIZE ]; + tCsrRSNAuthIe *pAuthSuite; + tCsrRSNCapabilities RSNCapabilities; + tCsrRSNPMKIe *pPMK; + tANI_U8 PMKId[CSR_RSN_PMKID_SIZE]; +#ifdef WLAN_FEATURE_11W + tANI_U8 *pGroupMgmtCipherSuite; +#endif + tDot11fBeaconIEs *pIesLocal = pIes; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + smsLog(pMac, LOGW, "%s called...", __func__); + + do + { + if ( !csrIsProfileRSN( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + + // See if the cyphers in the Bss description match with the settings in the profile. + fRSNMatch = csrGetRSNInformation( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, + &pProfile->mcEncryptionType, &pIesLocal->RSN, + UnicastCypher, MulticastCypher, AuthSuite, &RSNCapabilities, &negAuthType, NULL ); + if ( !fRSNMatch ) break; + + pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID; + + pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED; + + vos_mem_copy(pRSNIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher )); + + pRSNIe->cUnicastCyphers = 1; + + vos_mem_copy(&pRSNIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher )); + + pAuthSuite = (tCsrRSNAuthIe *)( &pRSNIe->UnicastOui[ pRSNIe->cUnicastCyphers ] ); + + pAuthSuite->cAuthenticationSuites = 1; + vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + // RSN capabilities follows the Auth Suite (two octects) + // !!REVIEW - What should STA put in RSN capabilities, currently + // just putting back APs capabilities + // For one, we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability + // For another, we should use the Management Frame Protection values given by the supplicant + RSNCapabilities.PreAuthSupported = 0; +#ifdef WLAN_FEATURE_11W + if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) { + RSNCapabilities.MFPCapable = pProfile->MFPCapable; + RSNCapabilities.MFPRequired = pProfile->MFPRequired; + } + else { + RSNCapabilities.MFPCapable = 0; + RSNCapabilities.MFPRequired = 0; + } +#endif + *(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities)); + + pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) ); + + // Don't include the PMK SA IDs for CCKM associations. + if ( +#ifdef FEATURE_WLAN_ESE + (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) && +#endif + csrLookupPMKID( pMac, sessionId, pSirBssDesc->bssId, &(PMKId[0]))) + { + pPMK->cPMKIDs = 1; + + vos_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId, CSR_RSN_PMKID_SIZE); + } + else + { + pPMK->cPMKIDs = 0; + } + +#ifdef WLAN_FEATURE_11W + if ( pProfile->MFPEnabled ) + { + pGroupMgmtCipherSuite = (tANI_U8 *) pPMK + sizeof ( tANI_U16 ) + + ( pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE ); + vos_mem_copy(pGroupMgmtCipherSuite, csrRSNOui[07], CSR_WPA_OUI_SIZE); + } +#endif + + // Add in the fixed fields plus 1 Unicast cypher, less the IE Header length + // Add in the size of the Auth suite (count plus a single OUI) + // Add in the RSN caps field. + // Add PMKID count and PMKID (if any) + // Add group management cipher suite + pRSNIe->IeHeader.Length = (tANI_U8) (sizeof( *pRSNIe ) - sizeof ( pRSNIe->IeHeader ) + + sizeof( *pAuthSuite ) + + sizeof( tCsrRSNCapabilities )); + if(pPMK->cPMKIDs) + { + pRSNIe->IeHeader.Length += (tANI_U8)(sizeof( tANI_U16 ) + + (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE)); + } +#ifdef WLAN_FEATURE_11W + if ( pProfile->MFPEnabled ) + { + if ( 0 == pPMK->cPMKIDs ) + pRSNIe->IeHeader.Length += sizeof( tANI_U16 ); + pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE; + } +#endif + + // return the size of the IE header (total) constructed... + cbRSNIe = pRSNIe->IeHeader.Length + sizeof( pRSNIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbRSNIe ); +} + + +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrGetWapiInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIEWAPI *pWapiIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0, i; + tANI_U8 Unicast[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 AuthSuites[ CSR_WAPI_MAX_AUTH_SUITES ][ CSR_WAPI_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ CSR_WAPI_MAX_MULTICAST_CYPHERS ][ CSR_WAPI_OUI_SIZE ]; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + tANI_U8 wapiOuiIndex = 0; + do{ + if ( pWapiIe->present ) + { + cMulticastCyphers++; + vos_mem_copy(MulticastCyphers, pWapiIe->multicast_cipher_suite, + CSR_WAPI_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pWapiIe->unicast_cipher_suite_count); + cAuthSuites = (tANI_U8)(pWapiIe->akm_suite_count); + for(i = 0; i < cAuthSuites && i < CSR_WAPI_MAX_AUTH_SUITES; i++) + { + vos_mem_copy((void *)&AuthSuites[i], (void *)&pWapiIe->akm_suites[i], + CSR_WAPI_OUI_SIZE); + } + + wapiOuiIndex = csrGetOUIIndexFromCipher( enType ); + if (wapiOuiIndex >= CSR_OUI_WAPI_WAI_MAX_INDEX) + { + smsLog(pMac, LOGE, FL("Wapi OUI index = %d out of limit"), wapiOuiIndex); + fAcceptableCyphers = FALSE; + break; + } + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, pWapiIe->unicast_cipher_suites, cUnicastCyphers, + wapiOuiIndex, Unicast ); + + if( !fAcceptableCyphers ) break; + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + wapiOuiIndex = csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] ); + if (wapiOuiIndex >= CSR_OUI_WAPI_WAI_MAX_INDEX) + { + smsLog(pMac, LOGE, FL("Wapi OUI index = %d out of limit"), wapiOuiIndex); + fAcceptableCyphers = FALSE; + break; + } + fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + wapiOuiIndex, Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + if ( csrIsAuthWapiCert( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + } + else if ( csrIsAuthWapiPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + } + else + { + fAcceptableCyphers = FALSE; + negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + } + if( ( 0 == pAuthType->numEntries ) || ( FALSE == fAcceptableCyphers ) ) + { + //Caller doesn't care about auth type, or BSS doesn't match + break; + } + fAcceptableCyphers = FALSE; + for( i = 0 ; i < pAuthType->numEntries; i++ ) + { + if( pAuthType->authType[i] == negAuthType ) + { + fAcceptableCyphers = TRUE; + break; + } + } + } + }while (0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy(MulticastCypher, Multicast, CSR_WAPI_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy(UnicastCypher, Unicast, CSR_WAPI_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy(AuthSuite, Authentication, CSR_WAPI_OUI_SIZE); + } + + if ( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + } + return( fAcceptableCyphers ); +} + +tANI_BOOLEAN csrIsWapiMatch( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType, + tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fWapiMatch = FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fWapiMatch = csrGetWapiInformation( hHal, pAuthType, enType, pEnMcType, &pIes->WAPI, NULL, NULL, NULL, + pNegotiatedAuthType, pNegotiatedMCCipher ); + + return( fWapiMatch ); +} + +tANI_BOOLEAN csrLookupBKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pBKId ) +{ + tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE; + tANI_U32 Index; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return FALSE; + } + + do + { + for( Index=0; Index < pSession->NumBkidCache; Index++ ) + { + smsLog(pMac, LOGW, "match BKID "MAC_ADDRESS_STR" to ", + MAC_ADDR_ARRAY(pBSSId)); + if (vos_mem_compare(pBSSId, pSession->BkidCacheInfo[Index].BSSID, sizeof(tCsrBssid) ) ) + { + // match found + fMatchFound = TRUE; + break; + } + } + + if( !fMatchFound ) break; + + vos_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID, CSR_WAPI_BKID_SIZE); + + fRC = TRUE; + } + while( 0 ); + smsLog(pMac, LOGW, "csrLookupBKID called return match = %d pMac->roam.NumBkidCache = %d", fRC, pSession->NumBkidCache); + + return fRC; +} + +tANI_U8 csrConstructWapiIe( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ) +{ + tANI_BOOLEAN fWapiMatch = FALSE; + tANI_U8 cbWapiIe = 0; + tANI_U8 UnicastCypher[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 BKId[CSR_WAPI_BKID_SIZE]; + tANI_U8 *pWapi = NULL; + tANI_BOOLEAN fBKIDFound = FALSE; + tDot11fBeaconIEs *pIesLocal = pIes; + + do + { + if ( !csrIsProfileWapi( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + + // See if the cyphers in the Bss description match with the settings in the profile. + fWapiMatch = csrGetWapiInformation( pMac, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, + &pProfile->mcEncryptionType, &pIesLocal->WAPI, + UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL ); + if ( !fWapiMatch ) break; + + vos_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0); + + pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI; + + pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED; + + pWapiIe->cAuthenticationSuites = 1; + vos_mem_copy(&pWapiIe->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + pWapi = (tANI_U8 *) (&pWapiIe->AuthOui[ 1 ]); + + *pWapi = (tANI_U16)1; //cUnicastCyphers + pWapi+=2; + vos_mem_copy(pWapi, UnicastCypher, sizeof( UnicastCypher )); + pWapi += sizeof( UnicastCypher ); + + vos_mem_copy(pWapi, MulticastCypher, sizeof( MulticastCypher )); + pWapi += sizeof( MulticastCypher ); + + + // WAPI capabilities follows the Auth Suite (two octects) + // we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability + // & since we already did a memset pWapiIe to 0, skip these fields + pWapi +=2; + + fBKIDFound = csrLookupBKID( pMac, sessionId, pSirBssDesc->bssId, &(BKId[0]) ); + + + if( fBKIDFound ) + { + /* Do we need to change the endianness here */ + *pWapi = (tANI_U16)1; //cBKIDs + pWapi+=2; + vos_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE); + } + else + { + *pWapi = 0; + pWapi+=1; + *pWapi = 0; + pWapi+=1; + } + + // Add in the IE fields except the IE header + // Add BKID count and BKID (if any) + pWapiIe->IeHeader.Length = (tANI_U8) (sizeof( *pWapiIe ) - sizeof ( pWapiIe->IeHeader )); + + /*2 bytes for BKID Count field*/ + pWapiIe->IeHeader.Length += sizeof( tANI_U16 ); + + if(fBKIDFound) + { + pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE; + } + // return the size of the IE header (total) constructed... + cbWapiIe = pWapiIe->IeHeader.Length + sizeof( pWapiIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbWapiIe ); +} +#endif /* FEATURE_WLAN_WAPI */ + +tANI_BOOLEAN csrGetWpaCyphers( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIEWPA *pWpaIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0; + tANI_U8 Unicast[ CSR_WPA_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_WPA_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_WPA_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ 1 ][ CSR_WPA_OUI_SIZE ]; + tANI_U8 i; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + do + { + if ( pWpaIe->present ) + { + cMulticastCyphers = 1; + vos_mem_copy(MulticastCyphers, pWpaIe->multicast_cipher, CSR_WPA_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pWpaIe->unicast_cipher_count); + cAuthSuites = (tANI_U8)(pWpaIe->auth_suite_count); + + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, pWpaIe->unicast_ciphers, cUnicastCyphers, + csrGetOUIIndexFromCipher( enType ), Unicast ); + + if( !fAcceptableCyphers ) break; + + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i]), Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + /* Initializing with FALSE as it has TRUE value already */ + fAcceptableCyphers = FALSE; + for (i = 0 ; i < pAuthType->numEntries; i++) + { + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + if ( csrIsAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_WPA == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_WPA; + } + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthWpaPsk( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_WPA_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_WPA_PSK; + } +#ifdef FEATURE_WLAN_ESE + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_CCKM_WPA == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_CCKM_WPA; + } +#endif /* FEATURE_WLAN_ESE */ + + // The 1st auth type in the APs WPA IE, to match stations connecting + // profiles auth type will cause us to exit this loop + // This is added as some APs advertise multiple akms in the WPA IE. + if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType) + { + fAcceptableCyphers = TRUE; + break; + } + } // for + } + }while(0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy((tANI_U8 **)MulticastCypher, Multicast, CSR_WPA_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy((tANI_U8 **)UnicastCypher, Unicast, CSR_WPA_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy((tANI_U8 **)AuthSuite, Authentication, CSR_WPA_OUI_SIZE); + } + + if( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + } + + return( fAcceptableCyphers ); +} + + + +tANI_BOOLEAN csrIsWpaEncryptionMatch( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType, + tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthtype, eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fWpaMatch = eANI_BOOLEAN_FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fWpaMatch = csrGetWpaCyphers( pMac, pAuthType, enType, pEnMcType, &pIes->WPA, NULL, NULL, NULL, pNegotiatedAuthtype, pNegotiatedMCCipher ); + + return( fWpaMatch ); +} + + +tANI_U8 csrConstructWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fWpaMatch; + tANI_U8 cbWpaIe = 0; + tANI_U8 UnicastCypher[ CSR_WPA_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_WPA_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_WPA_OUI_SIZE ]; + tCsrWpaAuthIe *pAuthSuite; + tDot11fBeaconIEs *pIesLocal = pIes; + + do + { + if ( !csrIsProfileWpa( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + // See if the cyphers in the Bss description match with the settings in the profile. + fWpaMatch = csrGetWpaCyphers( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, &pProfile->mcEncryptionType, + &pIesLocal->WPA, UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL ); + if ( !fWpaMatch ) break; + + pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID; + + vos_mem_copy(pWpaIe->Oui, csrWpaOui[01], sizeof( pWpaIe->Oui )); + + pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED; + + vos_mem_copy(pWpaIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher )); + + pWpaIe->cUnicastCyphers = 1; + + vos_mem_copy(&pWpaIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher )); + + pAuthSuite = (tCsrWpaAuthIe *)( &pWpaIe->UnicastOui[ pWpaIe->cUnicastCyphers ] ); + + pAuthSuite->cAuthenticationSuites = 1; + vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + // The WPA capabilities follows the Auth Suite (two octects)-- + // this field is optional, and we always "send" zero, so just + // remove it. This is consistent with our assumptions in the + // frames compiler; c.f. bug 15234: + // http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 + + // Add in the fixed fields plus 1 Unicast cypher, less the IE Header length + // Add in the size of the Auth suite (count plus a single OUI) + pWpaIe->IeHeader.Length = sizeof( *pWpaIe ) - sizeof ( pWpaIe->IeHeader ) + + sizeof( *pAuthSuite ); + + // return the size of the IE header (total) constructed... + cbWpaIe = pWpaIe->IeHeader.Length + sizeof( pWpaIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbWpaIe ); +} + + +tANI_BOOLEAN csrGetWpaRsnIe( tHalHandle hHal, tANI_U8 *pIes, tANI_U32 len, + tANI_U8 *pWpaIe, tANI_U8 *pcbWpaIe, tANI_U8 *pRSNIe, tANI_U8 *pcbRSNIe) +{ + tDot11IEHeader *pIEHeader; + tSirMacPropIE *pSirMacPropIE; + tANI_U32 cbParsed; + tANI_U32 cbIE; + int cExpectedIEs = 0; + int cFoundIEs = 0; + int cbPropIETotal; + + pIEHeader = (tDot11IEHeader *)pIes; + if(pWpaIe) cExpectedIEs++; + if(pRSNIe) cExpectedIEs++; + + // bss description length includes all fields other than the length itself + cbParsed = 0; + + // Loop as long as there is data left in the IE of the Bss Description + // and the number of Expected IEs is NOT found yet. + while( ( (cbParsed + sizeof( *pIEHeader )) <= len ) && ( cFoundIEs < cExpectedIEs ) ) + { + cbIE = sizeof( *pIEHeader ) + pIEHeader->Length; + + if ( ( cbIE + cbParsed ) > len ) break; + + if ( ( pIEHeader->Length >= gCsrIELengthTable[ pIEHeader->ElementID ].min ) && + ( pIEHeader->Length <= gCsrIELengthTable[ pIEHeader->ElementID ].max ) ) + { + switch( pIEHeader->ElementID ) + { + // Parse the 221 (0xdd) Proprietary IEs here... + // Note that the 221 IE is overloaded, containing the WPA IE, WMM/WME IE, and the + // Airgo proprietary IE information. + case SIR_MAC_WPA_EID: + { + tANI_U32 aniOUI; + tANI_U8 *pOui = (tANI_U8 *)&aniOUI; + + pOui++; + aniOUI = ANI_OUI; + aniOUI = i_ntohl( aniOUI ); + + pSirMacPropIE = ( tSirMacPropIE *)pIEHeader; + cbPropIETotal = pSirMacPropIE->length; + + // Validate the ANI OUI is in the OUI field in the proprietary IE... + if ( ( pSirMacPropIE->length >= WNI_CFG_MANUFACTURER_OUI_LEN ) && + pOui[ 0 ] == pSirMacPropIE->oui[ 0 ] && + pOui[ 1 ] == pSirMacPropIE->oui[ 1 ] && + pOui[ 2 ] == pSirMacPropIE->oui[ 2 ] ) + { + } + else + { + tCsrWpaIe *pIe = ( tCsrWpaIe * )pIEHeader; + + if(!pWpaIe || !pcbWpaIe) break; + // Check if this is a valid WPA IE. Then check that the + // WPA OUI is in place and the version is one that we support. + if ( ( pIe->IeHeader.Length >= SIR_MAC_WPA_IE_MIN_LENGTH ) && + ( vos_mem_compare( pIe->Oui, (void *)csrWpaOui[1], + sizeof( pIe->Oui ) ) ) && + ( pIe->Version <= CSR_WPA_VERSION_SUPPORTED ) ) + { + vos_mem_copy(pWpaIe, pIe, + pIe->IeHeader.Length + sizeof( pIe->IeHeader )); + *pcbWpaIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader ); + cFoundIEs++; + + break; + } + } + + break; + } + + case SIR_MAC_RSN_EID: + { + tCsrRSNIe *pIe; + + if(!pcbRSNIe || !pRSNIe) break; + pIe = (tCsrRSNIe *)pIEHeader; + + // Check the length of the RSN Ie to assure it is valid. Then check that the + // version is one that we support. + + if ( pIe->IeHeader.Length < SIR_MAC_RSN_IE_MIN_LENGTH ) break; + if ( pIe->Version > CSR_RSN_VERSION_SUPPORTED ) break; + + cFoundIEs++; + + // if there is enough room in the WpaIE passed in, then copy the Wpa IE into + // the buffer passed in. + if ( *pcbRSNIe < pIe->IeHeader.Length + sizeof( pIe->IeHeader ) ) break; + vos_mem_copy(pRSNIe, pIe, + pIe->IeHeader.Length + sizeof( pIe->IeHeader )); + *pcbRSNIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader ); + + break; + } + + // Add support for other IE here... + default: + break; + } + } + + cbParsed += cbIE; + + pIEHeader = (tDot11IEHeader *)( ((tANI_U8 *)pIEHeader) + cbIE ); + + } + + // return a BOOL that tells if all of the IEs asked for were found... + return( cFoundIEs == cExpectedIEs ); +} + + +//If a WPAIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbWpaIe = 0; + + do + { + if ( !csrIsProfileWpa( pProfile ) ) break; + if(pProfile->nWPAReqIELength && pProfile->pWPAReqIE) + { + if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nWPAReqIELength) + { + cbWpaIe = (tANI_U8)pProfile->nWPAReqIELength; + vos_mem_copy(pWpaIe, pProfile->pWPAReqIE, cbWpaIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveWpaIe detect invalid WPA IE length (%d) ", pProfile->nWPAReqIELength); + } + } + else + { + cbWpaIe = csrConstructWpaIe(pMac, pProfile, pSirBssDesc, pIes, pWpaIe); + } + }while(0); + + return (cbWpaIe); +} + + +//If a RSNIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveRsnIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbRsnIe = 0; + + do + { + if ( !csrIsProfileRSN( pProfile ) ) break; +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + // If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from + // scratch. So it contains the current PMK-IDs + cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe); + } + else +#endif + if(pProfile->nRSNReqIELength && pProfile->pRSNReqIE) + { + // If you have one started away, re-use it. + if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nRSNReqIELength) + { + cbRsnIe = (tANI_U8)pProfile->nRSNReqIELength; + vos_mem_copy(pRsnIe, pProfile->pRSNReqIE, cbRsnIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveRsnIe detect invalid RSN IE length (%d) ", pProfile->nRSNReqIELength); + } + } + else + { + cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe); + } + }while(0); + + return (cbRsnIe); +} + + +#ifdef FEATURE_WLAN_WAPI +//If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE +tANI_U8 csrRetrieveWapiIe( tHalHandle hHal, tANI_U32 sessionId, + tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbWapiIe = 0; + + do + { + if ( !csrIsProfileWapi( pProfile ) ) break; + if(pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) + { + if(DOT11F_IE_WAPI_MAX_LEN >= pProfile->nWAPIReqIELength) + { + cbWapiIe = (tANI_U8)pProfile->nWAPIReqIELength; + vos_mem_copy(pWapiIe, pProfile->pWAPIReqIE, cbWapiIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveWapiIe detect invalid WAPI IE length (%d) ", pProfile->nWAPIReqIELength); + } + } + else + { + cbWapiIe = csrConstructWapiIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pWapiIe); + } + }while(0); + + return (cbWapiIe); +} +#endif /* FEATURE_WLAN_WAPI */ + +tANI_BOOLEAN csrSearchChannelListForTxPower(tHalHandle hHal, tSirBssDescription *pBssDescription, tCsrChannelSet *returnChannelGroup) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tListElem *pEntry; + tANI_U16 i; + tANI_U16 startingChannel; + tANI_BOOLEAN found = FALSE; + tCsrChannelSet *pChannelGroup; + + pEntry = csrLLPeekHead( &pMac->roam.channelList5G, LL_ACCESS_LOCK ); + + while ( pEntry ) + { + pChannelGroup = GET_BASE_ADDR( pEntry, tCsrChannelSet, channelListLink ); + startingChannel = pChannelGroup->firstChannel; + for ( i = 0; i < pChannelGroup->numChannels; i++ ) + { + if ( startingChannel + i * pChannelGroup->interChannelOffset == pBssDescription->channelId ) + { + found = TRUE; + break; + } + } + + if ( found ) + { + vos_mem_copy(returnChannelGroup, pChannelGroup, sizeof(tCsrChannelSet)); + break; + } + else + { + pEntry = csrLLNext( &pMac->roam.channelList5G, pEntry, LL_ACCESS_LOCK ); + } + } + + return( found ); +} + +tANI_BOOLEAN csrRatesIsDot11Rate11bSupportedRate( tANI_U8 dot11Rate ) +{ + tANI_BOOLEAN fSupported = FALSE; + tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) ); + + switch ( nonBasicRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_11Mbps: + fSupported = TRUE; + break; + + default: + break; + } + + return( fSupported ); +} + +tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate ) +{ + tANI_BOOLEAN fSupported = FALSE; + tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) ); + + switch ( nonBasicRate ) + { + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + + default: + break; + } + + return( fSupported ); +} + + + +tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType ) +{ + tAniEdType edType; + + switch ( EncryptType ) + { + default: + case eCSR_ENCRYPT_TYPE_NONE: + edType = eSIR_ED_NONE; + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + edType = eSIR_ED_WEP40; + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + edType = eSIR_ED_WEP104; + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + edType = eSIR_ED_TKIP; + break; + + case eCSR_ENCRYPT_TYPE_AES: + edType = eSIR_ED_CCMP; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + edType = eSIR_ED_WPI; + break ; +#endif +#ifdef WLAN_FEATURE_11W + //11w BIP + case eCSR_ENCRYPT_TYPE_AES_CMAC: + edType = eSIR_ED_AES_128_CMAC; + break; +#endif + } + + return( edType ); +} + + +//pIes can be NULL +tANI_BOOLEAN csrValidateWep( tpAniSirGlobal pMac, eCsrEncryptionType ucEncryptionType, + tCsrAuthList *pAuthList, tCsrEncryptionList *pMCEncryptionList, + eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCEncryption, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes ) +{ + tANI_U32 idx; + tANI_BOOLEAN fMatch = FALSE; + eCsrAuthType negotiatedAuth = eCSR_AUTH_TYPE_OPEN_SYSTEM; + eCsrEncryptionType negotiatedMCCipher = eCSR_ENCRYPT_TYPE_UNKNOWN; + + //This function just checks whether HDD is giving correct values for Multicast cipher and Auth. + + do + { + //If privacy bit is not set, consider no match + if ( !csrIsPrivacy( pSirBssDesc ) ) break; + + for( idx = 0; idx < pMCEncryptionList->numEntries; idx++ ) + { + switch( pMCEncryptionList->encryptionType[idx] ) + { + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + /* Multicast list may contain WEP40/WEP104. Check whether it matches UC. + */ + if( ucEncryptionType == pMCEncryptionList->encryptionType[idx] ) + { + fMatch = TRUE; + negotiatedMCCipher = pMCEncryptionList->encryptionType[idx]; + } + break; + default: + fMatch = FALSE; + break; + } + if(fMatch) break; + } + + if(!fMatch) break; + + for( idx = 0; idx < pAuthList->numEntries; idx++ ) + { + switch( pAuthList->authType[idx] ) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + case eCSR_AUTH_TYPE_SHARED_KEY: + case eCSR_AUTH_TYPE_AUTOSWITCH: + fMatch = TRUE; + negotiatedAuth = pAuthList->authType[idx]; + break; + default: + fMatch = FALSE; + } + if (fMatch) break; + } + + if(!fMatch) break; + //In case of WPA / WPA2, check whether it supports WEP as well + if(pIes) + { + //Prepare the encryption type for WPA/WPA2 functions + if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == ucEncryptionType ) + { + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + } + else if( eCSR_ENCRYPT_TYPE_WEP104 == ucEncryptionType ) + { + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + //else we can use the encryption type directly + if ( pIes->WPA.present ) + { + fMatch = vos_mem_compare(pIes->WPA.multicast_cipher, + csrWpaOui[csrGetOUIIndexFromCipher( ucEncryptionType )], + CSR_WPA_OUI_SIZE); + if( fMatch ) break; + } + if ( pIes->RSN.present ) + { + fMatch = vos_mem_compare(pIes->RSN.gp_cipher_suite, + csrRSNOui[csrGetOUIIndexFromCipher( ucEncryptionType )], + CSR_RSN_OUI_SIZE); + } + } + + }while(0); + + if( fMatch ) + { + if( pNegotiatedAuthType ) + *pNegotiatedAuthType = negotiatedAuth; + + if( pNegotiatedMCEncryption ) + *pNegotiatedMCEncryption = negotiatedMCCipher; + } + + + return fMatch; +} + + +//pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs +tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, + tCsrEncryptionList *pUCEncryptionType, + tCsrEncryptionList *pMCEncryptionType, + tANI_BOOLEAN *pMFPEnabled, + tANI_U8 *pMFPRequired, tANI_U8 *pMFPCapable, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, + eCsrAuthType *negotiatedAuthtype, + eCsrEncryptionType *negotiatedUCCipher, + eCsrEncryptionType *negotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fMatch = FALSE; + tANI_U8 i,idx; + eCsrEncryptionType mcCipher = eCSR_ENCRYPT_TYPE_UNKNOWN, ucCipher = eCSR_ENCRYPT_TYPE_UNKNOWN; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + for( i = 0 ; ((i < pUCEncryptionType->numEntries) && (!fMatch)) ; i++ ) + { + ucCipher = pUCEncryptionType->encryptionType[i]; + // If the Bss description shows the Privacy bit is on, then we must have some sort of encryption configured + // for the profile to work. Don't attempt to join networks with Privacy bit set when profiles say NONE for + // encryption type. + switch ( ucCipher ) + { + case eCSR_ENCRYPT_TYPE_NONE: + { + // for NO encryption, if the Bss description has the Privacy bit turned on, then encryption is + // required so we have to reject this Bss. + if ( csrIsPrivacy( pSirBssDesc ) ) + { + fMatch = FALSE; + } + else + { + fMatch = TRUE; + } + + if ( fMatch ) + { + fMatch = FALSE; + //Check Multicast cipher requested and Auth type requested. + for( idx = 0 ; idx < pMCEncryptionType->numEntries ; idx++ ) + { + if( eCSR_ENCRYPT_TYPE_NONE == pMCEncryptionType->encryptionType[idx] ) + { + fMatch = TRUE; //Multicast can only be none. + mcCipher = pMCEncryptionType->encryptionType[idx]; + break; + } + } + if (!fMatch) break; + + fMatch = FALSE; + //Check Auth list. It should contain AuthOpen. + for( idx = 0 ; idx < authType->numEntries ; idx++ ) + { + if(( eCSR_AUTH_TYPE_OPEN_SYSTEM == authType->authType[idx] ) || + ( eCSR_AUTH_TYPE_AUTOSWITCH == authType->authType[idx] )) + { + fMatch = TRUE; + negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + } + } + if (!fMatch) break; + + } + break; + } + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + // !! might want to check for WEP keys set in the Profile.... ? + // !! don't need to have the privacy bit in the Bss description. Many AP policies make legacy + // encryption 'optional' so we don't know if we can associate or not. The AP will reject if + // encryption is not allowed without the Privacy bit turned on. + fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes); + + break; + + // these are all of the WPA encryption types... + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes); + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + { + if(pIes) + { + // First check if there is a RSN match + fMatch = csrIsRSNMatch( pMac, authType, ucCipher, + pMCEncryptionType, pMFPEnabled, + pMFPRequired, pMFPCapable, + pIes, &negAuthType, &mcCipher ); + if( !fMatch ) + { + // If not RSN, then check if there is a WPA match + fMatch = csrIsWpaEncryptionMatch( pMac, authType, ucCipher, pMCEncryptionType, pIes, + &negAuthType, &mcCipher ); + } + } + else + { + fMatch = FALSE; + } + break; + } +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI://WAPI + { + if(pIes) + { + fMatch = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher ); + } + else + { + fMatch = FALSE; + } + break; + } +#endif /* FEATURE_WLAN_WAPI */ + case eCSR_ENCRYPT_TYPE_ANY: + default: + { + tANI_BOOLEAN fMatchAny = eANI_BOOLEAN_FALSE; + + fMatch = eANI_BOOLEAN_TRUE; + //It is allowed to match anything. Try the more secured ones first. + if(pIes) + { + //Check AES first + ucCipher = eCSR_ENCRYPT_TYPE_AES; + fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, + pMCEncryptionType, pMFPEnabled, + pMFPRequired, pMFPCapable, pIes, + &negAuthType, &mcCipher ); + if(!fMatchAny) + { + //Check TKIP + ucCipher = eCSR_ENCRYPT_TYPE_TKIP; + fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, + pMCEncryptionType, + pMFPEnabled, pMFPRequired, + pMFPCapable, pIes, + &negAuthType, &mcCipher ); + } +#ifdef FEATURE_WLAN_WAPI + if(!fMatchAny) + { + //Check WAPI + ucCipher = eCSR_ENCRYPT_TYPE_WPI; + fMatchAny = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher ); + } +#endif /* FEATURE_WLAN_WAPI */ + } + if(!fMatchAny) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP104; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP40; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + //It must be open and no encryption + if ( csrIsPrivacy( pSirBssDesc ) ) + { + //This is not right + fMatch = eANI_BOOLEAN_FALSE; + } + else + { + negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + mcCipher = eCSR_ENCRYPT_TYPE_NONE; + ucCipher = eCSR_ENCRYPT_TYPE_NONE; + } + } + } + } + } + } + break; + } + } + + } + + if( fMatch ) + { + if( negotiatedUCCipher ) + *negotiatedUCCipher = ucCipher; + + if( negotiatedMCCipher ) + *negotiatedMCCipher = mcCipher; + + if( negotiatedAuthtype ) + *negotiatedAuthtype = negAuthType; + } + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsSsidMatch( tpAniSirGlobal pMac, tANI_U8 *ssid1, tANI_U8 ssid1Len, tANI_U8 *bssSsid, + tANI_U8 bssSsidLen, tANI_BOOLEAN fSsidRequired ) +{ + tANI_BOOLEAN fMatch = FALSE; + + do { + + // There are a few special cases. If the Bss description has a Broadcast SSID, + // then our Profile must have a single SSID without Wildcards so we can program + // the SSID. + // SSID could be suppressed in beacons. In that case SSID IE has valid length + // but the SSID value is all NULL characters. That condition is trated same + // as NULL SSID + if ( csrIsNULLSSID( bssSsid, bssSsidLen ) ) + { + if ( eANI_BOOLEAN_FALSE == fSsidRequired ) + { + fMatch = TRUE; + break; + } + } + + // Check for the specification of the Broadcast SSID at the beginning of the list. + // If specified, then all SSIDs are matches (broadcast SSID means accept all SSIDs). + if ( ssid1Len == 0 ) + { + fMatch = TRUE; + break; + } + + if(ssid1Len != bssSsidLen) break; + if (vos_mem_compare(bssSsid, ssid1, bssSsidLen)) + { + fMatch = TRUE; + break; + } + + } while( 0 ); + + return( fMatch ); +} + + +//Null ssid means match +tANI_BOOLEAN csrIsSsidInList( tHalHandle hHal, tSirMacSSid *pSsid, tCsrSSIDs *pSsidList ) +{ + tANI_BOOLEAN fMatch = FALSE; + tANI_U32 i; + + if ( pSsidList && pSsid ) + { + for(i = 0; i < pSsidList->numOfSSIDs; i++) + { + if(csrIsNULLSSID(pSsidList->SSIDList[i].SSID.ssId, pSsidList->SSIDList[i].SSID.length) || + ((pSsidList->SSIDList[i].SSID.length == pSsid->length) && + vos_mem_compare(pSsid->ssId, pSsidList->SSIDList[i].SSID.ssId, pSsid->length))) + { + fMatch = TRUE; + break; + } + } + } + + return (fMatch); +} + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ) +{ + tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0}; + + return (vos_mem_compare(bssid, pMacAddr, VOS_MAC_ADDR_SIZE)); +} + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressBroadcast( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ) +{ + tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + return(vos_mem_compare(bssid, pMacAddr, VOS_MAC_ADDR_SIZE)); +} + + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressEqual( tpAniSirGlobal pMac, tCsrBssid *pMacAddr1, tCsrBssid *pMacAddr2 ) +{ + return(vos_mem_compare(pMacAddr1, pMacAddr2, sizeof(tCsrBssid))); +} + + +tANI_BOOLEAN csrIsBssidMatch( tHalHandle hHal, tCsrBssid *pProfBssid, tCsrBssid *BssBssid ) +{ + tANI_BOOLEAN fMatch = FALSE; + tCsrBssid ProfileBssid; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + // for efficiency of the MAC_ADDRESS functions, move the + // Bssid's into MAC_ADDRESS structs. + vos_mem_copy(&ProfileBssid, pProfBssid, sizeof(tCsrBssid)); + + do { + + // Give the profile the benefit of the doubt... accept either all 0 or + // the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to + // match any Bssids). + if ( csrIsMacAddressZero( pMac, &ProfileBssid ) || + csrIsMacAddressBroadcast( pMac, &ProfileBssid ) ) + { + fMatch = TRUE; + break; + } + + if ( csrIsMacAddressEqual( pMac, BssBssid, &ProfileBssid ) ) + { + fMatch = TRUE; + break; + } + + } while( 0 ); + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2) +{ + if((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2) && (bssType1 != bssType2)) + return eANI_BOOLEAN_FALSE; + else + return eANI_BOOLEAN_TRUE; +} + + +tANI_BOOLEAN csrIsBssTypeIBSS(eCsrRoamBssType bssType) +{ + return((tANI_BOOLEAN)(eCSR_BSS_TYPE_START_IBSS == bssType || eCSR_BSS_TYPE_IBSS == bssType)); +} + +tANI_BOOLEAN csrIsBssTypeWDS(eCsrRoamBssType bssType) +{ + return((tANI_BOOLEAN)(eCSR_BSS_TYPE_WDS_STA == bssType || eCSR_BSS_TYPE_WDS_AP == bssType)); +} + +tANI_BOOLEAN csrIsBSSTypeCapsMatch( eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + switch( bssType ) + { + case eCSR_BSS_TYPE_ANY: + break; + + case eCSR_BSS_TYPE_INFRASTRUCTURE: + case eCSR_BSS_TYPE_WDS_STA: + if( !csrIsInfraBssDesc( pSirBssDesc ) ) + fMatch = FALSE; + + break; + + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + if( !csrIsIbssBssDesc( pSirBssDesc ) ) + fMatch = FALSE; + + break; + + case eCSR_BSS_TYPE_WDS_AP: //For WDS AP, no need to match anything + default: + fMatch = FALSE; + break; + } + } + while( 0 ); + + + return( fMatch ); +} + +static tANI_BOOLEAN csrIsCapabilitiesMatch( tpAniSirGlobal pMac, eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc ) +{ + return( csrIsBSSTypeCapsMatch( bssType, pSirBssDesc ) ); +} + + + +static tANI_BOOLEAN csrIsSpecificChannelMatch( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tANI_U8 Channel ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + // if the channel is ANY, then always match... + if ( eCSR_OPERATING_CHANNEL_ANY == Channel ) break; + if ( Channel == pSirBssDesc->channelId ) break; + + // didn't match anything.. so return NO match + fMatch = FALSE; + + } while( 0 ); + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsChannelBandMatch( tpAniSirGlobal pMac, tANI_U8 channelId, tSirBssDescription *pSirBssDesc ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + // if the profile says Any channel AND the global settings says ANY channel, then we + // always match... + if ( eCSR_OPERATING_CHANNEL_ANY == channelId ) break; + + if ( eCSR_OPERATING_CHANNEL_ANY != channelId ) + { + fMatch = csrIsSpecificChannelMatch( pMac, pSirBssDesc, channelId ); + } + + } while( 0 ); + + return( fMatch ); +} + + +/** + * \brief Enquire as to whether a given rate is supported by the + * adapter as currently configured + * + * + * \param nRate A rate in units of 500kbps + * + * \return TRUE if the adapter is currently capable of supporting this + * rate, FALSE else + * + * + * The rate encoding is just as in 802.11 Information Elements, except + * that the high bit is \em not interpreted as indicating a Basic Rate, + * and proprietary rates are allowed, too. + * + * Note that if the adapter's dot11Mode is g, we don't restrict the + * rates. According to hwReadEepromParameters, this will happen when: + * + * ... the card is configured for ALL bands through the property + * page. If this occurs, and the card is not an ABG card ,then this + * code is setting the dot11Mode to assume the mode that the + * hardware can support. For example, if the card is an 11BG card + * and we are configured to support ALL bands, then we change the + * dot11Mode to 11g because ALL in this case is only what the + * hardware can support. + * + * + */ + +static tANI_BOOLEAN csrIsAggregateRateSupported( tpAniSirGlobal pMac, tANI_U16 rate ) +{ + tANI_BOOLEAN fSupported = eANI_BOOLEAN_FALSE; + tANI_U16 idx, newRate; + + //In case basic rate flag is set + newRate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); + if ( eCSR_CFG_DOT11_MODE_11A == pMac->roam.configParam.uCfgDot11Mode ) + { + switch ( newRate ) + { + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + + } + else if( eCSR_CFG_DOT11_MODE_11B == pMac->roam.configParam.uCfgDot11Mode ) + { + switch ( newRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_11Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + } + else if ( !pMac->roam.configParam.ProprietaryRatesEnabled ) + { + + switch ( newRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_11Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + + } + else { + + if ( eCsrSuppRate_1Mbps == newRate || + eCsrSuppRate_2Mbps == newRate || + eCsrSuppRate_5_5Mbps == newRate || + eCsrSuppRate_11Mbps == newRate ) + { + fSupported = TRUE; + } + else { + idx = 0x1; + + switch ( newRate ) + { + case eCsrSuppRate_6Mbps: + fSupported = gPhyRatesSuppt[0][idx]; + break; + case eCsrSuppRate_9Mbps: + fSupported = gPhyRatesSuppt[1][idx]; + break; + case eCsrSuppRate_12Mbps: + fSupported = gPhyRatesSuppt[2][idx]; + break; + case eCsrSuppRate_18Mbps: + fSupported = gPhyRatesSuppt[3][idx]; + break; + case eCsrSuppRate_20Mbps: + fSupported = gPhyRatesSuppt[4][idx]; + break; + case eCsrSuppRate_24Mbps: + fSupported = gPhyRatesSuppt[5][idx]; + break; + case eCsrSuppRate_36Mbps: + fSupported = gPhyRatesSuppt[6][idx]; + break; + case eCsrSuppRate_40Mbps: + fSupported = gPhyRatesSuppt[7][idx]; + break; + case eCsrSuppRate_42Mbps: + fSupported = gPhyRatesSuppt[8][idx]; + break; + case eCsrSuppRate_48Mbps: + fSupported = gPhyRatesSuppt[9][idx]; + break; + case eCsrSuppRate_54Mbps: + fSupported = gPhyRatesSuppt[10][idx]; + break; + case eCsrSuppRate_72Mbps: + fSupported = gPhyRatesSuppt[11][idx]; + break; + case eCsrSuppRate_80Mbps: + fSupported = gPhyRatesSuppt[12][idx]; + break; + case eCsrSuppRate_84Mbps: + fSupported = gPhyRatesSuppt[13][idx]; + break; + case eCsrSuppRate_96Mbps: + fSupported = gPhyRatesSuppt[14][idx]; + break; + case eCsrSuppRate_108Mbps: + fSupported = gPhyRatesSuppt[15][idx]; + break; + case eCsrSuppRate_120Mbps: + fSupported = gPhyRatesSuppt[16][idx]; + break; + case eCsrSuppRate_126Mbps: + fSupported = gPhyRatesSuppt[17][idx]; + break; + case eCsrSuppRate_144Mbps: + fSupported = gPhyRatesSuppt[18][idx]; + break; + case eCsrSuppRate_160Mbps: + fSupported = gPhyRatesSuppt[19][idx]; + break; + case eCsrSuppRate_168Mbps: + fSupported = gPhyRatesSuppt[20][idx]; + break; + case eCsrSuppRate_192Mbps: + fSupported = gPhyRatesSuppt[21][idx]; + break; + case eCsrSuppRate_216Mbps: + fSupported = gPhyRatesSuppt[22][idx]; + break; + case eCsrSuppRate_240Mbps: + fSupported = gPhyRatesSuppt[23][idx]; + break; + default: + fSupported = FALSE; + break; + } + } + } + + return fSupported; +} + + + +static tANI_BOOLEAN csrIsRateSetMatch( tpAniSirGlobal pMac, + tDot11fIESuppRates *pBssSuppRates, + tDot11fIEExtSuppRates *pBssExtSuppRates ) +{ + tANI_BOOLEAN fMatch = TRUE; + tANI_U32 i; + + + // Validate that all of the Basic rates advertised in the Bss description are supported. + if ( pBssSuppRates ) + { + for( i = 0; i < pBssSuppRates->num_rates; i++ ) + { + if ( CSR_IS_BASIC_RATE( pBssSuppRates->rates[ i ] ) ) + { + if ( !csrIsAggregateRateSupported( pMac, pBssSuppRates->rates[ i ] ) ) + { + fMatch = FALSE; + break; + } + } + } + } + + if ( fMatch && pBssExtSuppRates ) + { + for( i = 0; i < pBssExtSuppRates->num_rates; i++ ) + { + if ( CSR_IS_BASIC_RATE( pBssExtSuppRates->rates[ i ] ) ) + { + if ( !csrIsAggregateRateSupported( pMac, pBssExtSuppRates->rates[ i ] ) ) + { + fMatch = FALSE; + break; + } + } + } + } + + return( fMatch ); + +} + + +//ppIes can be NULL. If caller want to get the *ppIes allocated by this function, pass in *ppIes = NULL +tANI_BOOLEAN csrMatchBSS( tHalHandle hHal, tSirBssDescription *pBssDesc, tCsrScanResultFilter *pFilter, + eCsrAuthType *pNegAuth, eCsrEncryptionType *pNegUc, eCsrEncryptionType *pNegMc, + tDot11fBeaconIEs **ppIes) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck; + tANI_U32 i; + tDot11fBeaconIEs *pIes = NULL; + tANI_U8 *pb; + + do { + if( ( NULL == ppIes ) || ( *ppIes ) == NULL ) + { + //If no IEs passed in, get our own. + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + break; + } + } + else + { + //Save the one pass in for local use + pIes = *ppIes; + } + + //Check if caller wants P2P + fCheck = (!pFilter->p2pResult || pIes->P2PBeaconProbeRes.present); + if(!fCheck) break; + + if(pIes->SSID.present) + { + for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++) + { + fCheck = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length, + pIes->SSID.ssid, + pIes->SSID.num_ssid, eANI_BOOLEAN_TRUE ); + if ( fCheck ) break; + } + if(!fCheck) break; + } + fCheck = eANI_BOOLEAN_TRUE; + for(i = 0; i < pFilter->BSSIDs.numOfBSSIDs; i++) + { + fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i], (tCsrBssid *)pBssDesc->bssId ); + if ( fCheck ) break; + + if (pFilter->p2pResult && pIes->P2PBeaconProbeRes.present) + { + fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i], + (tCsrBssid *)pIes->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress ); + + if ( fCheck ) break; + } + } + if(!fCheck) break; + + fCheck = eANI_BOOLEAN_TRUE; + for(i = 0; i < pFilter->ChannelInfo.numOfChannels; i++) + { + fCheck = csrIsChannelBandMatch( pMac, pFilter->ChannelInfo.ChannelList[i], pBssDesc ); + if ( fCheck ) break; + } + if(!fCheck) + break; +#if defined WLAN_FEATURE_VOWIFI + /* If this is for measurement filtering */ + if( pFilter->fMeasurement ) + { + fRC = eANI_BOOLEAN_TRUE; + break; + } +#endif + if ( !csrIsPhyModeMatch( pMac, pFilter->phyMode, pBssDesc, NULL, NULL, pIes ) ) break; + if ( (!pFilter->bWPSAssociation) && (!pFilter->bOSENAssociation) && +#ifdef WLAN_FEATURE_11W + !csrIsSecurityMatch( pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + &pFilter->MFPEnabled, + &pFilter->MFPRequired, + &pFilter->MFPCapable, + pBssDesc, pIes, pNegAuth, + pNegUc, pNegMc ) +#else + !csrIsSecurityMatch( pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + NULL, NULL, NULL, + pBssDesc, pIes, pNegAuth, + pNegUc, pNegMc ) +#endif + ) break; + if ( !csrIsCapabilitiesMatch( pMac, pFilter->BSSType, pBssDesc ) ) break; + if ( !csrIsRateSetMatch( pMac, &pIes->SuppRates, &pIes->ExtSuppRates ) ) break; + //Tush-QoS: validate first if asked for APSD or WMM association + if ( (eCsrRoamWmmQbssOnly == pMac->roam.configParam.WMMSupportMode) && + !CSR_IS_QOS_BSS(pIes) ) + break; + //Check country. check even when pb is NULL because we may want to make sure + //AP has a country code in it if fEnforceCountryCodeMatch is set. + pb = ( pFilter->countryCode[0] ) ? ( pFilter->countryCode) : NULL; + + fCheck = csrMatchCountryCode( pMac, pb, pIes ); + if(!fCheck) + break; + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pFilter->MDID.mdiePresent) + { + if (pBssDesc->mdiePresent) + { + if (pFilter->MDID.mobilityDomain != (pBssDesc->mdie[1] << 8 | pBssDesc->mdie[0])) + break; + } + else + break; + } +#endif + fRC = eANI_BOOLEAN_TRUE; + + } while( 0 ); + if( ppIes ) + { + *ppIes = pIes; + } + else if( pIes ) + { + vos_mem_free(pIes); + } + + return( fRC ); +} + +tANI_BOOLEAN csrMatchConnectedBSSSecurity( tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + tCsrEncryptionList ucEncryptionList, mcEncryptionList; + tCsrAuthList authList; + + ucEncryptionList.numEntries = 1; + ucEncryptionList.encryptionType[0] = pProfile->EncryptionType; + + mcEncryptionList.numEntries = 1; + mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType; + + authList.numEntries = 1; + authList.authType[0] = pProfile->AuthType; + + return( csrIsSecurityMatch( pMac, &authList, &ucEncryptionList, + &mcEncryptionList, NULL, NULL, NULL, + pBssDesc, pIes, NULL, NULL, NULL )); + +} + + +tANI_BOOLEAN csrMatchBSSToConnectProfile( tHalHandle hHal, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck; + tDot11fBeaconIEs *pIesLocal = pIes; + + do { + if( !pIes ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) + { + break; + } + } + fCheck = eANI_BOOLEAN_TRUE; + if(pIesLocal->SSID.present) + { + tANI_BOOLEAN fCheckSsid = eANI_BOOLEAN_FALSE; + if(pProfile->SSID.length) + { + fCheckSsid = eANI_BOOLEAN_TRUE; + } + fCheck = csrIsSsidMatch( pMac, pProfile->SSID.ssId, pProfile->SSID.length, + pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid, fCheckSsid ); + if(!fCheck) break; + } + if ( !csrMatchConnectedBSSSecurity( pMac, pProfile, pBssDesc, pIesLocal) ) break; + if ( !csrIsCapabilitiesMatch( pMac, pProfile->BSSType, pBssDesc ) ) break; + if ( !csrIsRateSetMatch( pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates ) ) break; + fCheck = csrIsChannelBandMatch( pMac, pProfile->operationChannel, pBssDesc ); + if(!fCheck) + break; + + fRC = eANI_BOOLEAN_TRUE; + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( fRC ); +} + +void csrAddRateBitmap(tANI_U8 rate, tANI_U16 *pRateBitmap) +{ + tANI_U16 rateBitmap; + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + rateBitmap = *pRateBitmap; + switch(n) + { + case SIR_MAC_RATE_1: + rateBitmap |= SIR_MAC_RATE_1_BITMAP; + break; + case SIR_MAC_RATE_2: + rateBitmap |= SIR_MAC_RATE_2_BITMAP; + break; + case SIR_MAC_RATE_5_5: + rateBitmap |= SIR_MAC_RATE_5_5_BITMAP; + break; + case SIR_MAC_RATE_11: + rateBitmap |= SIR_MAC_RATE_11_BITMAP; + break; + case SIR_MAC_RATE_6: + rateBitmap |= SIR_MAC_RATE_6_BITMAP; + break; + case SIR_MAC_RATE_9: + rateBitmap |= SIR_MAC_RATE_9_BITMAP; + break; + case SIR_MAC_RATE_12: + rateBitmap |= SIR_MAC_RATE_12_BITMAP; + break; + case SIR_MAC_RATE_18: + rateBitmap |= SIR_MAC_RATE_18_BITMAP; + break; + case SIR_MAC_RATE_24: + rateBitmap |= SIR_MAC_RATE_24_BITMAP; + break; + case SIR_MAC_RATE_36: + rateBitmap |= SIR_MAC_RATE_36_BITMAP; + break; + case SIR_MAC_RATE_48: + rateBitmap |= SIR_MAC_RATE_48_BITMAP; + break; + case SIR_MAC_RATE_54: + rateBitmap |= SIR_MAC_RATE_54_BITMAP; + break; + } + *pRateBitmap = rateBitmap; +} + +tANI_BOOLEAN csrCheckRateBitmap(tANI_U8 rate, tANI_U16 rateBitmap) +{ + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + + switch(n) + { + case SIR_MAC_RATE_1: + rateBitmap &= SIR_MAC_RATE_1_BITMAP; + break; + case SIR_MAC_RATE_2: + rateBitmap &= SIR_MAC_RATE_2_BITMAP; + break; + case SIR_MAC_RATE_5_5: + rateBitmap &= SIR_MAC_RATE_5_5_BITMAP; + break; + case SIR_MAC_RATE_11: + rateBitmap &= SIR_MAC_RATE_11_BITMAP; + break; + case SIR_MAC_RATE_6: + rateBitmap &= SIR_MAC_RATE_6_BITMAP; + break; + case SIR_MAC_RATE_9: + rateBitmap &= SIR_MAC_RATE_9_BITMAP; + break; + case SIR_MAC_RATE_12: + rateBitmap &= SIR_MAC_RATE_12_BITMAP; + break; + case SIR_MAC_RATE_18: + rateBitmap &= SIR_MAC_RATE_18_BITMAP; + break; + case SIR_MAC_RATE_24: + rateBitmap &= SIR_MAC_RATE_24_BITMAP; + break; + case SIR_MAC_RATE_36: + rateBitmap &= SIR_MAC_RATE_36_BITMAP; + break; + case SIR_MAC_RATE_48: + rateBitmap &= SIR_MAC_RATE_48_BITMAP; + break; + case SIR_MAC_RATE_54: + rateBitmap &= SIR_MAC_RATE_54_BITMAP; + break; + } + return !!rateBitmap; +} + +tANI_BOOLEAN csrRatesIsDot11RateSupported( tHalHandle hHal, tANI_U8 rate ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + + return csrIsAggregateRateSupported( pMac, n ); +} + + +tANI_U16 csrRatesMacPropToDot11( tANI_U16 Rate ) +{ + tANI_U16 ConvertedRate = Rate; + + switch( Rate ) + { + case SIR_MAC_RATE_1: + ConvertedRate = 2; + break; + case SIR_MAC_RATE_2: + ConvertedRate = 4; + break; + case SIR_MAC_RATE_5_5: + ConvertedRate = 11; + break; + case SIR_MAC_RATE_11: + ConvertedRate = 22; + break; + + case SIR_MAC_RATE_6: + ConvertedRate = 12; + break; + case SIR_MAC_RATE_9: + ConvertedRate = 18; + break; + case SIR_MAC_RATE_12: + ConvertedRate = 24; + break; + case SIR_MAC_RATE_18: + ConvertedRate = 36; + break; + case SIR_MAC_RATE_24: + ConvertedRate = 48; + break; + case SIR_MAC_RATE_36: + ConvertedRate = 72; + break; + case SIR_MAC_RATE_42: + ConvertedRate = 84; + break; + case SIR_MAC_RATE_48: + ConvertedRate = 96; + break; + case SIR_MAC_RATE_54: + ConvertedRate = 108; + break; + + case SIR_MAC_RATE_72: + ConvertedRate = 144; + break; + case SIR_MAC_RATE_84: + ConvertedRate = 168; + break; + case SIR_MAC_RATE_96: + ConvertedRate = 192; + break; + case SIR_MAC_RATE_108: + ConvertedRate = 216; + break; + case SIR_MAC_RATE_126: + ConvertedRate = 252; + break; + case SIR_MAC_RATE_144: + ConvertedRate = 288; + break; + case SIR_MAC_RATE_168: + ConvertedRate = 336; + break; + case SIR_MAC_RATE_192: + ConvertedRate = 384; + break; + case SIR_MAC_RATE_216: + ConvertedRate = 432; + break; + case SIR_MAC_RATE_240: + ConvertedRate = 480; + break; + + case 0xff: + ConvertedRate = 0; + break; + } + + return ConvertedRate; +} + + +tANI_U16 csrRatesFindBestRate( tSirMacRateSet *pSuppRates, tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates ) +{ + tANI_U8 i; + tANI_U16 nBest; + + nBest = pSuppRates->rate[ 0 ] & ( ~CSR_DOT11_BASIC_RATE_MASK ); + + if(pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) + { + pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX; + } + + for ( i = 1U; i < pSuppRates->numRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, pSuppRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) ); + } + + if ( NULL != pExtRates ) + { + for ( i = 0U; i < pExtRates->numRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, pExtRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) ); + } + } + + if ( NULL != pPropRates ) + { + for ( i = 0U; i < pPropRates->numPropRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, csrRatesMacPropToDot11( pPropRates->propRate[ i ] ) ); + } + } + + return nBest; +} + + +void csrReleaseProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile) +{ + if(pProfile) + { + if(pProfile->BSSIDs.bssid) + { + vos_mem_free(pProfile->BSSIDs.bssid); + pProfile->BSSIDs.bssid = NULL; + } + if(pProfile->SSIDs.SSIDList) + { + vos_mem_free(pProfile->SSIDs.SSIDList); + pProfile->SSIDs.SSIDList = NULL; + } + if(pProfile->pWPAReqIE) + { + vos_mem_free(pProfile->pWPAReqIE); + pProfile->pWPAReqIE = NULL; + } + if(pProfile->pRSNReqIE) + { + vos_mem_free(pProfile->pRSNReqIE); + pProfile->pRSNReqIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + if(pProfile->pWAPIReqIE) + { + vos_mem_free(pProfile->pWAPIReqIE); + pProfile->pWAPIReqIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ + + if(pProfile->pAddIEScan) + { + vos_mem_free(pProfile->pAddIEScan); + pProfile->pAddIEScan = NULL; + } + + if(pProfile->pAddIEAssoc) + { + vos_mem_free(pProfile->pAddIEAssoc); + pProfile->pAddIEAssoc = NULL; + } + if(pProfile->ChannelInfo.ChannelList) + { + vos_mem_free(pProfile->ChannelInfo.ChannelList); + pProfile->ChannelInfo.ChannelList = NULL; + } + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + } +} + +void csrFreeScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter) +{ + if(pScanFilter->BSSIDs.bssid) + { + vos_mem_free(pScanFilter->BSSIDs.bssid); + pScanFilter->BSSIDs.bssid = NULL; + } + if(pScanFilter->ChannelInfo.ChannelList) + { + vos_mem_free(pScanFilter->ChannelInfo.ChannelList); + pScanFilter->ChannelInfo.ChannelList = NULL; + } + if(pScanFilter->SSIDs.SSIDList) + { + vos_mem_free(pScanFilter->SSIDs.SSIDList); + pScanFilter->SSIDs.SSIDList = NULL; + } +} + + +void csrFreeRoamProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + + if(pSession->pCurRoamProfile) + { + csrReleaseProfile(pMac, pSession->pCurRoamProfile); + vos_mem_free(pSession->pCurRoamProfile); + pSession->pCurRoamProfile = NULL; + } +} + + +void csrFreeConnectBssDesc(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + + if(pSession->pConnectBssDesc) + { + vos_mem_free(pSession->pConnectBssDesc); + pSession->pConnectBssDesc = NULL; + } +} + + + +tSirResultCodes csrGetDisassocRspStatusCode( tSirSmeDisassocRsp *pSmeDisassocRsp ) +{ + tANI_U8 *pBuffer = (tANI_U8 *)pSmeDisassocRsp; + tANI_U32 ret; + + pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tSirMacAddr)); + //tSirResultCodes is an enum, assuming is 32bit + //If we cannot make this assumption, use copymemory + pal_get_U32( pBuffer, &ret ); + + return( ( tSirResultCodes )ret ); +} + + +tSirResultCodes csrGetDeAuthRspStatusCode( tSirSmeDeauthRsp *pSmeRsp ) +{ + tANI_U8 *pBuffer = (tANI_U8 *)pSmeRsp; + tANI_U32 ret; + + pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tANI_U8) +sizeof(tANI_U16)); + //tSirResultCodes is an enum, assuming is 32bit + //If we cannot make this assumption, use copymemory + pal_get_U32( pBuffer, &ret ); + + return( ( tSirResultCodes )ret ); +} + +tSirScanType csrGetScanType(tpAniSirGlobal pMac, tANI_U8 chnId) +{ + tSirScanType scanType = eSIR_PASSIVE_SCAN; + eNVChannelEnabledType channelEnabledType; + + channelEnabledType = vos_nv_getChannelEnabledState(chnId); + if( NV_CHANNEL_ENABLE == channelEnabledType) + { + scanType = eSIR_ACTIVE_SCAN; + } + return (scanType); +} + + +tANI_U8 csrToUpper( tANI_U8 ch ) +{ + tANI_U8 chOut; + + if ( ch >= 'a' && ch <= 'z' ) + { + chOut = ch - 'a' + 'A'; + } + else + { + chOut = ch; + } + return( chOut ); +} + + +tSirBssType csrTranslateBsstypeToMacType(eCsrRoamBssType csrtype) +{ + tSirBssType ret; + + switch(csrtype) + { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + ret = eSIR_INFRASTRUCTURE_MODE; + break; + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + ret = eSIR_IBSS_MODE; + break; + case eCSR_BSS_TYPE_WDS_AP: + ret = eSIR_BTAMP_AP_MODE; + break; + case eCSR_BSS_TYPE_WDS_STA: + ret = eSIR_BTAMP_STA_MODE; + break; + case eCSR_BSS_TYPE_INFRA_AP: + ret = eSIR_INFRA_AP_MODE; + break; + case eCSR_BSS_TYPE_ANY: + default: + ret = eSIR_AUTO_MODE; + break; + } + + return (ret); +} + + +//This function use the parameters to decide the CFG value. +//CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG +//So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value +eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tANI_BOOLEAN fProprietary) +{ + tANI_U32 cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; + + switch(phyMode) + { + case eCSR_DOT11_MODE_11a: + case eCSR_DOT11_MODE_11a_ONLY: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11b: + case eCSR_DOT11_MODE_11b_ONLY: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: + if(pProfile && (CSR_IS_INFRA_AP(pProfile)) && (phyMode == eCSR_DOT11_MODE_11g_ONLY)) + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY; + else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11n: + if(fProprietary) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; + case eCSR_DOT11_MODE_11n_ONLY: + if(pProfile && CSR_IS_INFRA_AP(pProfile)) + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY; + else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + case eCSR_DOT11_MODE_TAURUS: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + break; + case eCSR_DOT11_MODE_abg: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; + break; + case eCSR_DOT11_MODE_AUTO: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO; + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; + case eCSR_DOT11_MODE_11ac_ONLY: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; +#endif + default: + //No need to assign anything here + break; + } + + return (cfgDot11Mode); +} + + +eHalStatus csrSetRegulatoryDomain(tpAniSirGlobal pMac, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRestart; + + if(pMac->scan.domainIdCurrent == domainId) + { + //no change + fRestart = eANI_BOOLEAN_FALSE; + } + else if( !pMac->roam.configParam.fEnforceDefaultDomain ) + { + pMac->scan.domainIdCurrent = domainId; + fRestart = eANI_BOOLEAN_TRUE; + } + else + { + //We cannot change the domain + status = eHAL_STATUS_CSR_WRONG_STATE; + fRestart = eANI_BOOLEAN_FALSE; + } + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestart; + } + + return (status); +} + + +v_REGDOMAIN_t csrGetCurrentRegulatoryDomain(tpAniSirGlobal pMac) +{ + return (pMac->scan.domainIdCurrent); +} + + +eHalStatus csrGetRegulatoryDomainForCountry +( +tpAniSirGlobal pMac, +tANI_U8 *pCountry, +v_REGDOMAIN_t *pDomainId, +v_CountryInfoSource_t source +) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + VOS_STATUS vosStatus; + v_COUNTRYCODE_t countryCode; + v_REGDOMAIN_t domainId; + + if(pCountry) + { + countryCode[0] = pCountry[0]; + countryCode[1] = pCountry[1]; + vosStatus = vos_nv_getRegDomainFromCountryCode(&domainId, + countryCode, + source); + + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + if( pDomainId ) + { + *pDomainId = domainId; + } + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog(pMac, LOGW, FL(" Couldn't find domain for country code %c%c"), pCountry[0], pCountry[1]); + status = eHAL_STATUS_INVALID_PARAMETER; + } + } + + return (status); +} + +//To check whether a country code matches the one in the IE +//Only check the first two characters, ignoring in/outdoor +//pCountry -- caller allocated buffer contain the country code that is checking against +//the one in pIes. It can be NULL. +//caller must provide pIes, it cannot be NULL +//This function always return TRUE if 11d support is not turned on. +tANI_BOOLEAN csrMatchCountryCode( tpAniSirGlobal pMac, tANI_U8 *pCountry, tDot11fBeaconIEs *pIes ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + v_REGDOMAIN_t domainId = REGDOMAIN_COUNT; //This is init to invalid value + eHalStatus status; + + do + { + if( !csrIs11dSupported( pMac) ) + { + break; + } + if( !pIes ) + { + smsLog(pMac, LOGE, FL(" No IEs")); + break; + } + if( pMac->roam.configParam.fEnforceDefaultDomain || + pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + //Make sure this country is recognizable + if( pIes->Country.present ) + { + status = csrGetRegulatoryDomainForCountry(pMac, + pIes->Country.country, + &domainId, COUNTRY_QUERY); + if( !HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCode11d, + (v_REGDOMAIN_t *) &domainId, + COUNTRY_QUERY); + if( !HAL_STATUS_SUCCESS( status ) ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } + //check whether it is needed to enforce to the default regulatory domain first + if( pMac->roam.configParam.fEnforceDefaultDomain ) + { + if( domainId != pMac->scan.domainIdCurrent ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + if( pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + if( domainId >= REGDOMAIN_COUNT ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } + if( pCountry ) + { + tANI_U32 i; + + if( !pIes->Country.present ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + // Convert the CountryCode characters to upper + for ( i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++ ) + { + pCountry[i] = csrToUpper( pCountry[i] ); + } + if (!vos_mem_compare(pIes->Country.country, pCountry, + WNI_CFG_COUNTRY_CODE_LEN - 1)) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } while(0); + + return (fRet); +} + + +eHalStatus csrGetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields) +{ + + if(!pModifyProfileFields) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pModifyProfileFields, + &pMac->roam.roamSession[sessionId].connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrSetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + vos_mem_copy(&pSession->connectedProfile.modifyProfileFields, + pModifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)); + + return eHAL_STATUS_SUCCESS; +} + + + +/* --------------------------------------------------------------------------- + \fn csrGetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed bytes. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + v_SIZE_t size = (v_SIZE_t)*pbLen; + + vosStatus = vos_nv_getSupportedCountryCode( pBuf, &size, 1 ); + //eiter way, return the value back + *pbLen = (tANI_U32)size; + + //If pBuf is NULL, caller just want to get the size, consider it success + if(pBuf) + { + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + tANI_U32 i, n = *pbLen / 3; + + for( i = 0; i < n; i++ ) + { + pBuf[i*3 + 2] = ' '; + } + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + + return (status); +} + + + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus csrScanGetBaseChannels( tpAniSirGlobal pMac, tCsrChannelInfo * pChannelInfo ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + do + { + + if(!pMac->scan.baseChannels.numChannels || !pChannelInfo) + { + break; + } + pChannelInfo->ChannelList = vos_mem_malloc(pMac->scan.baseChannels.numChannels); + if ( NULL == pChannelInfo->ChannelList ) + { + smsLog( pMac, LOGE, FL("csrScanGetBaseChannels: fail to allocate memory") ); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pChannelInfo->ChannelList, + pMac->scan.baseChannels.channelList, + pMac->scan.baseChannels.numChannels); + pChannelInfo->numOfChannels = pMac->scan.baseChannels.numChannels; + + }while(0); + + return ( status ); +} + + +tANI_BOOLEAN csrIsSetKeyAllowed(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + tCsrRoamSession *pSession; + + pSession =CSR_GET_SESSION(pMac, sessionId); + + /*This condition is not working for infra state. When infra is in not-connected state + * the pSession->pCurRoamProfile is NULL. And this function returns TRUE, that is incorrect. + * Since SAP requires to set key without any BSS started, it needs this condition to be met. + * In other words, this function is useless. + * The current work-around is to process setcontext_rsp and removekey_rsp no matter what the + * state is. + */ + smsLog( pMac, LOG2, FL(" is not what it intends to. Must be revisit or removed") ); + if( (NULL == pSession) || + ( csrIsConnStateDisconnected( pMac, sessionId ) && + (pSession->pCurRoamProfile != NULL) && + (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) ) + ) + { + fRet = eANI_BOOLEAN_FALSE; + } + + return ( fRet ); +} + +//no need to acquire lock for this basic function +tANI_U16 sme_ChnToFreq(tANI_U8 chanNum) +{ + int i; + + for (i = 0; i < NUM_RF_CHANNELS; i++) + { + if (rfChannels[i].channelNum == chanNum) + { + return rfChannels[i].targetFreq; + } + } + + return (0); +} + +/* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we + * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and + * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there + * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to + * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS + */ + +//Remove this code once SLM_Sessionization is supported +//BMPS_WORKAROUND_NOT_NEEDED +void csrDisconnectAllActiveSessions(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + /* Disconnect all the active sessions */ + for (i=0; i 0; i--) + { + pChannelList[i] = pChannelList[i-1]; + } + + // Now add the NEW channel...at the front + pChannelList[0] = channel; + + return eHAL_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/nan/nan_Api.c b/drivers/staging/qcacld-2.0/CORE/SME/src/nan/nan_Api.c new file mode 100644 index 0000000000000..ce10b62e8db58 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/nan/nan_Api.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "sme_Api.h" +#include "smsDebug.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "nan_Api.h" +#include "limApi.h" +#include "cfgApi.h" + +/****************************************************************************** + * Function: sme_NanRegisterCallback + * + * Description: + * This function gets called when HDD wants register nan rsp callback with + * sme layer. + * + * Args: + * hHal and callback which needs to be registered. + * + * Returns: + * void + *****************************************************************************/ +void sme_NanRegisterCallback(tHalHandle hHal, NanCallback callback) +{ + tpAniSirGlobal pMac = NULL; + + if (NULL == hHal) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("hHal is not valid")); + return; + } + pMac = PMAC_STRUCT(hHal); + pMac->sme.nanCallback = callback; +} + +/****************************************************************************** + * Function: sme_NanRequest + * + * Description: + * This function gets called when HDD receives NAN vendor command + * from userspace + * + * Args: + * Nan Request structure ptr + * + * Returns: + * VOS_STATUS + *****************************************************************************/ +VOS_STATUS sme_NanRequest(tpNanRequestReq input) +{ + vos_msg_t msg; + tpNanRequest data; + size_t data_len; + + data_len = sizeof(tNanRequest) + input->request_data_len; + data = vos_mem_malloc(data_len); + + if (data == NULL) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Memory allocation failure")); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero(data, data_len); + data->request_data_len = input->request_data_len; + if (input->request_data_len) { + vos_mem_copy(data->request_data, + input->request_data, input->request_data_len); + } + + msg.type = WDA_NAN_REQUEST; + msg.reserved = 0; + msg.bodyptr = data; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, + &msg)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post WDA_NAN_REQUEST message to WDA")); + vos_mem_free(data); + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_SUCCESS; +} + +/****************************************************************************** + * Function: sme_NanEvent + * + * Description: + * This callback function will be called when SME received eWNI_SME_NAN_EVENT + * event from WMA + * + * Args: + * hHal - HAL handle for device + * pMsg - Message body passed from WDA; includes NAN header + * + * Returns: + * VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanEvent(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("msg ptr is NULL")); + status = VOS_STATUS_E_FAILURE; + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + FL("SME: Received sme_NanEvent")); + if (pMac->sme.nanCallback) { + pMac->sme.nanCallback(pMac->hHdd, + (tSirNanEvent *)pMsg); + } + } + + return status; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/oemData/oemDataApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/oemData/oemDataApi.c new file mode 100644 index 0000000000000..df3eb0aff542c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/oemData/oemDataApi.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataApi.c + + Implementation for the OEM DATA REQ/RSP interfaces. +========================================================================== */ +#include "aniGlobal.h" +#include "oemDataApi.h" +#include "palApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqOpen + \brief This function must be called before any API call to (OEM DATA REQ/RSP module) + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqOpen(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //initialize all the variables to null + vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function"); + break; + } + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqClose + \brief This function must be called before closing the csr module + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqClose(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers"); + break; + } + + if(pMac->oemData.pOemDataRsp != NULL) + { + vos_mem_free(pMac->oemData.pOemDataRsp); + } + + //initialize all the variables to null + vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0); + } while(0); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn oemData_ReleaseOemDataReqCommand + \brief This function removes the oemDataCommand from the active list and + and frees up any memory occupied by this + \return eHalStatus + -------------------------------------------------------------------------------*/ +void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus) +{ + + //First take this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK)) + { + vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0); + + //Now put this command back on the avilable command list + smeReleaseCommand(pMac, pOemDataCmd); + } + else + { + smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command"); + } +} + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReq + \brief Request an OEM DATA RSP + \param sessionId - Id of session to be used + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *oemDataReqConfig, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *pOemDataCmd = NULL; + + do + { + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = eHAL_STATUS_FAILURE; + break; + } + + pMac->oemData.oemDataReqConfig.sessionId = sessionId; + pMac->oemData.callback = callback; + pMac->oemData.pContext = pContext; + pMac->oemData.oemDataReqID = *(pOemDataReqID); + + vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), + (v_VOID_t*)(oemDataReqConfig->oemDataReq), + OEM_DATA_REQ_SIZE); + + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + + pOemDataCmd = smeGetCommandBuffer(pMac); + + //fill up the command before posting it. + if(pOemDataCmd) + { + pOemDataCmd->command = eSmeCommandOemDataReq; + pOemDataCmd->u.oemDataCmd.callback = callback; + pOemDataCmd->u.oemDataCmd.pContext = pContext; + pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID; + + //set the oem data request + pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId; + vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq), + (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), + OEM_DATA_REQ_SIZE); + } + else + { + status = eHAL_STATUS_FAILURE; + break; + } + + //now queue this command in the sme command queue + //Here since this is not interacting with the csr just push the command + //into the sme queue. Also push this command with the normal priority + smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE); + + } while(0); + + if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd) + { + oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_SendMBOemDataReq + \brief Request an OEM DATA REQ to be passed down to PE + \param pMac: + \param pOemDataReq: Pointer to the oem data request + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirOemDataReq* pMsg; + tANI_U16 msgLen; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId ); + + smsLog(pMac, LOGW, "OEM_DATA: entering Function %s", __func__); + + msgLen = (tANI_U16)(sizeof(tSirOemDataReq)); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ); + pMsg->messageLen = pal_cpu_to_be16(msgLen); + vos_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) ); + vos_mem_copy(pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE); + smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s", __func__); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s", __func__); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_ProcessOemDataReqCommand + \brief This function is called by the smeProcessCommand when the case hits + eSmeCommandOemDataReq + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + //check if the system is in proper mode of operation for + //oem data req/rsp to be functional. Currently, concurrency is not + //supported and the driver must be operational only as + //STA for oem data req/rsp to be functional. We return an invalid + //mode flag if it is operational as any one of the following + //in any of the active sessions + //1. AP Mode + //2. IBSS Mode + //3. BTAMP Mode ... + + if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac)) + { + smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode", __func__); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE; + status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq)); + } + else + { + smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode", __func__); + oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_HandleOemDataRsp + \brief This function processes the oem data response obtained from the PE + \param pMsg - Pointer to the pSirOemDataRsp + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirOemDataRsp* pOemDataRsp = NULL; + tANI_U32 *msgSubType; + + pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__); + + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + /* In this case, there can be multiple OEM Data Responses for one + * OEM Data request, SME does not peek into data response so SME + * can not know which response is the last one. So SME clears active + * request command on receiving first response and thereafter SME + * passes each sunsequent response to upper user layer. + */ + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if (eSmeCommandOemDataReq == pCommand->command) + { + if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + { + vos_mem_set(&(pCommand->u.oemDataCmd), + sizeof(tOemDataCmd), 0); + smeReleaseCommand(pMac, pCommand); + } + } + } + + pOemDataRsp = (tSirOemDataRsp *)pMsg; + + /* check if message is to be forwarded to oem application or not */ + msgSubType = (tANI_U32 *) (&pOemDataRsp->oemDataRsp[0]); + if (*msgSubType != OEM_MESSAGE_SUBTYPE_INTERNAL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: calling send_oem_data_rsp_msg, msgSubType(0x%x)", + __func__, *msgSubType); + send_oem_data_rsp_msg(sizeof(tOemDataRsp), + &pOemDataRsp->oemDataRsp[0]); + } + else + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: received internal oem data resp, msgSubType (0x%x)", + __func__, *msgSubType); + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_IsOemDataReqAllowed + \brief This function checks if OEM DATA REQs can be performed in the + current driver state + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId; + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + if(CSR_IS_SESSION_VALID(pMac, sessionId)) + { + //co-exist with IBSS or BT-AMP mode is not supported + if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId) ) + { + //co-exist with IBSS or BT-AMP mode is not supported + smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP exist in session %d", sessionId); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + } + } + + smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d", status); + + return (status); +} + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/p2p/p2p_Api.c b/drivers/staging/qcacld-2.0/CORE/SME/src/p2p/p2p_Api.c new file mode 100644 index 0000000000000..1d4b5306af0a2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/p2p/p2p_Api.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#include "sme_Api.h" +#include "smsDebug.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "p2p_Api.h" +#include "limApi.h" +#include "cfgApi.h" + + +eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd); +/*------------------------------------------------------------------ + * + * handle SME remain on channel request. + * + *------------------------------------------------------------------*/ + +eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirRemainOnChnReq* pMsg; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, p2pRemainonChn->sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), p2pRemainonChn->sessionId); + return eHAL_STATUS_FAILURE; + } + + + if(!pSession->sessionActive) + { + smsLog(pMac, LOGE, FL(" session %d is invalid or listen is disabled "), + p2pRemainonChn->sessionId); + return eHAL_STATUS_FAILURE; + } + len = sizeof(tSirRemainOnChnReq) + pMac->p2pContext.probeRspIeLength; + + if( len > 0xFFFF ) + { + /*In coming len for Msg is more then 16bit value*/ + smsLog(pMac, LOGE, FL(" Message length is very large, %d"), + len); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s call", __func__); + vos_mem_set(pMsg, sizeof(tSirRemainOnChnReq), 0); + pMsg->messageType = eWNI_SME_REMAIN_ON_CHANNEL_REQ; + pMsg->length = (tANI_U16)len; + vos_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr)); + pMsg->chnNum = p2pRemainonChn->u.remainChlCmd.chn; + pMsg->phyMode = p2pRemainonChn->u.remainChlCmd.phyMode; + pMsg->duration = p2pRemainonChn->u.remainChlCmd.duration; + pMsg->sessionId = p2pRemainonChn->sessionId; + pMsg->isProbeRequestAllowed = p2pRemainonChn->u.remainChlCmd.isP2PProbeReqAllowed; + if( pMac->p2pContext.probeRspIeLength ) + vos_mem_copy((void *)pMsg->probeRspIe, (void *)pMac->p2pContext.probeRspIe, + pMac->p2pContext.probeRspIeLength); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return status; +} + + +/*------------------------------------------------------------------ + * + * handle LIM remain on channel rsp: Success/failure. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fFound; + + if (pMac->fP2pListenOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandRemainOnChannel == pCommand->command ) + { + remainOnChanCallback callback = pCommand->u.remainChlCmd.callback; + /* process the msg */ + if( callback ) + callback(pMac, pCommand->u.remainChlCmd.callbackCtx, 0); + + if (pMac->fP2pListenOffload) + { + fFound = csrLLRemoveEntry( &pMac->sme.smeScanCmdActiveList, + pEntry, LL_ACCESS_LOCK); + } + else + { + fFound = csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, + LL_ACCESS_LOCK); + } + + if (fFound) + { + //Now put this command back on the avilable command list + smeReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + } + return status; +} + + +/*------------------------------------------------------------------ + * + * Handle the Mgmt frm ind from LIM and forward to HDD. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_mgmtFrmInd( tHalHandle hHal, tpSirSmeMgmtFrameInd pSmeMgmtFrm) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tANI_U8 i = 0; + tANI_U32 SessionId = pSmeMgmtFrm->sessionId; + + pRoamInfo.nFrameLength = pSmeMgmtFrm->mesgLen - sizeof(tSirSmeMgmtFrameInd); + pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf; + pRoamInfo.frameType = pSmeMgmtFrm->frameType; + pRoamInfo.rxChan = pSmeMgmtFrm->rxChan; + pRoamInfo.rxRssi = pSmeMgmtFrm->rxRssi; + if(CSR_IS_SESSION_ANY(SessionId)) + { + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + if(CSR_IS_SESSION_VALID(pMac, i)) + { + SessionId = i; + break; + } + } + } + + if (i == CSR_ROAM_SESSION_MAX) { + smsLog(pMac, LOGE, FL("No valid sessions found.")); + return eHAL_STATUS_FAILURE; + } + /* forward the mgmt frame to HDD */ + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_INDICATE_MGMT_FRAME, 0); + + return status; +} + + +/*------------------------------------------------------------------ + * + * Handle the remain on channel ready indication from PE + * + *------------------------------------------------------------------*/ + +eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamInfo RoamInfo; + + if (pMac->fP2pListenOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandRemainOnChannel == pCommand->command ) + { + + /* forward the indication to HDD */ + RoamInfo.pRemainCtx = pCommand->u.remainChlCmd.callbackCtx; + csrRoamCallCallback(pMac, ((tSirSmeRsp*)pMsg)->sessionId, &RoamInfo, + 0, eCSR_ROAM_REMAIN_CHAN_READY, 0); + } + } + + return status; +} + + +eHalStatus sme_sendActionCnf( tHalHandle hHal, tANI_U8* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo RoamInfo; + tSirSmeRsp* pSmeRsp = (tSirSmeRsp*)pMsg; + + /* forward the indication to HDD */ + //RoamInfo can be passed as NULL....todo + csrRoamCallCallback(pMac, pSmeRsp->sessionId, &RoamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + (pSmeRsp->statusCode == eSIR_SME_SUCCESS) ? 0: + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); + return status; +} + + + + +eHalStatus sme_p2pOpen( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + //If static structure is too big, Need to change this function to allocate memory dynamically + vos_mem_zero(&pMac->p2pContext, sizeof( tp2pContext )); + + if(!HAL_STATUS_SUCCESS(status)) + { + sme_p2pClose(hHal); + } + + return status; +} + + +eHalStatus p2pStop( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if( pMac->p2pContext.probeRspIe ) + { + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIe = NULL; + } + + pMac->p2pContext.probeRspIeLength = 0; + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus sme_p2pClose( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if( pMac->p2pContext.probeRspIe ) + { + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIe = NULL; + } + + pMac->p2pContext.probeRspIeLength = 0; + + return eHAL_STATUS_SUCCESS; +} + + +tSirRFBand GetRFBand(tANI_U8 channel) +{ + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + return SIR_BAND_5_GHZ; + + if ((channel >= SIR_11B_CHANNEL_BEGIN) && + (channel <= SIR_11B_CHANNEL_END)) + return SIR_BAND_2_4_GHZ; + + return SIR_BAND_UNKNOWN; +} + +/* --------------------------------------------------------------------------- + + \fn p2pRemainOnChannel + \brief API to post the remain on channel command. + \param hHal - The handle returned by macOpen. + \param sessinId - HDD session ID. + \param channel - Channel to remain on channel. + \param duration - Duration for which we should remain on channel + \param callback - callback function. + \param pContext - argument to the callback function + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus p2pRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, tANI_U8 isP2PProbeReqAllowed + ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeCmd *pRemainChlCmd = NULL; + tANI_U32 phyMode; + + pRemainChlCmd = smeGetCommandBuffer(pMac); + if(pRemainChlCmd == NULL) + return eHAL_STATUS_FAILURE; + + if (SIR_BAND_5_GHZ == GetRFBand(channel)) + { + phyMode = WNI_CFG_PHY_MODE_11A; + } + else + { + phyMode = WNI_CFG_PHY_MODE_11G; + } + + cfgSetInt(pMac, WNI_CFG_PHY_MODE, phyMode); + + do + { + /* call set in context */ + pRemainChlCmd->command = eSmeCommandRemainOnChannel; + pRemainChlCmd->sessionId = sessionId; + pRemainChlCmd->u.remainChlCmd.chn = channel; + pRemainChlCmd->u.remainChlCmd.duration = duration; + pRemainChlCmd->u.remainChlCmd.isP2PProbeReqAllowed = isP2PProbeReqAllowed; + pRemainChlCmd->u.remainChlCmd.callback = callback; + pRemainChlCmd->u.remainChlCmd.callbackCtx = pContext; + + //Put it at the head of the Q if we just finish finding the peer and ready to send a frame + csrQueueSmeCommand(pMac, pRemainChlCmd, eANI_BOOLEAN_FALSE); + } while(0); + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +eHalStatus p2pSendAction(tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, tANI_U16 wait, tANI_BOOLEAN noack) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMbMsgP2p *pMsg; + tANI_U16 msgLen; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + " %s sends action frame", __func__); + msgLen = (tANI_U16)((sizeof( tSirMbMsg )) + len); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SEND_ACTION_FRAME_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + pMsg->noack = noack; + pMsg->wait = (tANI_U16)wait; + vos_mem_copy(pMsg->data, pBuf, len); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +eHalStatus p2pCancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMbMsgP2p *pMsg; + tANI_U16 msgLen; + + //Need to check session ID to support concurrency + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_ABORT_REMAIN_ON_CHAN_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +eHalStatus p2pSetPs(tHalHandle hHal, tP2pPsConfig *pNoA) +{ + tpP2pPsConfig pNoAParam; + tSirMsgQ msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pNoAParam = vos_mem_malloc(sizeof(tP2pPsConfig)); + if ( NULL == pNoAParam ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pNoAParam, sizeof(tP2pPsConfig), 0); + vos_mem_copy(pNoAParam, pNoA, sizeof(tP2pPsConfig)); + msg.type = eWNI_SME_UPDATE_NOA; + msg.bodyval = 0; + msg.bodyptr = pNoAParam; + limPostMsgApi(pMac, &msg); + } + return status; +} + + +eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd) +{ + tpP2pPsConfig pNoA; + tSirMsgQ msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + + pNoA = vos_mem_malloc(sizeof(tP2pPsConfig)); + if ( NULL == pNoA ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pNoA, sizeof(tP2pPsConfig), 0); + pNoA->opp_ps = pNoACmd->u.NoACmd.NoA.opp_ps; + pNoA->ctWindow = pNoACmd->u.NoACmd.NoA.ctWindow; + pNoA->duration = pNoACmd->u.NoACmd.NoA.duration; + pNoA->interval = pNoACmd->u.NoACmd.NoA.interval; + pNoA->count = pNoACmd->u.NoACmd.NoA.count; + pNoA->single_noa_duration = pNoACmd->u.NoACmd.NoA.single_noa_duration; + pNoA->psSelection = pNoACmd->u.NoACmd.NoA.psSelection; + pNoA->sessionid = pNoACmd->u.NoACmd.NoA.sessionid; + msg.type = eWNI_SME_UPDATE_NOA; + msg.bodyval = 0; + msg.bodyptr = pNoA; + limPostMsgApi(pMac, &msg); + } + return status; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmc.c b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmc.c new file mode 100644 index 0000000000000..768cc8053ee9b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmc.c @@ -0,0 +1,3627 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmc.c +* +* Description: + Power Management Control (PMC) processing routines. +* + +* +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "csrLinkList.h" +#include "csrApi.h" +#include "smeInside.h" +#include "sme_Api.h" +#include "smsDebug.h" +#include "pmc.h" +#include "wlan_qct_wda.h" +#include "wlan_ps_wow_diag.h" +#include "csrInsideApi.h" + +static void pmcProcessDeferredMsg( tpAniSirGlobal pMac ); + +/****************************************************************************** +* +* Name: pmcEnterLowPowerState +* +* Description: +* Have the device enter Low Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterLowPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterLowPowerState")); + + /* If already in Low Power State, just return. */ + if (pMac->pmc.pmcState == LOW_POWER) + return eHAL_STATUS_SUCCESS; + + /* Cancel any running timers. */ + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + return eHAL_STATUS_FAILURE; + } + + pmcStopTrafficTimer(hHal); + + if (vos_timer_stop(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel exit power save mode timer")); + return eHAL_STATUS_FAILURE; + } + + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_FAILURE); + + /* Change state. */ + pMac->pmc.pmcState = LOW_POWER; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcExitLowPowerState +* +* Description: +* Have the device exit the Low Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcExitLowPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcExitLowPowerState")); + + /* Must be in Low Power State if we are going to exit that state. */ + if (pMac->pmc.pmcState != LOW_POWER) + { + pmcLog(pMac, LOGE, FL("Cannot exit Low Power State if not in that state")); + return eHAL_STATUS_FAILURE; + } + + /* Both WLAN switches much be on to exit Low Power State. */ + if ((pMac->pmc.hwWlanSwitchState == ePMC_SWITCH_OFF) || (pMac->pmc.swWlanSwitchState == ePMC_SWITCH_OFF)) + return eHAL_STATUS_SUCCESS; + + /* Change state. */ + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterFullPowerState +* +* Description: +* Have the device enter the Full Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterFullPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterFullPowerState")); + + /* Take action based on the current state. */ + switch (pMac->pmc.pmcState) + { + + /* Already in Full Power State. */ + case FULL_POWER: + break; + + /* Notify everyone that we are going to full power. + Change to Full Power State. */ + case REQUEST_FULL_POWER: + case REQUEST_IMPS: + case REQUEST_BMPS: + case REQUEST_STANDBY: + + /* Change state. */ + pMac->pmc.pmcState = FULL_POWER; + pMac->pmc.requestFullPowerPending = FALSE; + + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + + pmcProcessDeferredMsg( pMac ); + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_SUCCESS); + + /* Update registerd modules that we are entering Full Power. This is + only way to inform modules if PMC exited a power save mode because + of error conditions or if som other module requested full power */ + pmcDoDeviceStateUpdateCallbacks(hHal, FULL_POWER); + break; + + /* Cannot go directly to Full Power State from these states. */ + default: + pmcLog(pMac, LOGE, FL("Trying to enter Full Power State from state %d"), pMac->pmc.pmcState); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + pmcLog(pMac, LOG1, "PMC: Enter full power done"); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestFullPowerState +* +* Description: +* Have the device enter the Request Full Power State. +* +* Parameters: +* hHal - HAL handle for device +* fullPowerReason - Reason code for requesting full power +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestFullPowerState (tHalHandle hHal, tRequestFullPowerReason fullPowerReason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterRequestFullPowerState")); + + /* Take action based on the current state of the device. */ + switch (pMac->pmc.pmcState) + { + + /* Should not request full power if already there. */ + case FULL_POWER: + pmcLog(pMac, LOGE, FL("Requesting Full Power State when already there")); + return eHAL_STATUS_FAILURE; + + /* Only power events can take device out of Low Power State. */ + case LOW_POWER: + pmcLog(pMac, LOGE, FL("Cannot request exit from Low Power State")); + return eHAL_STATUS_FAILURE; + + /* Cannot go directly to Request Full Power state from these states. + Record that this is pending and take care of it later. */ + case REQUEST_IMPS: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case REQUEST_STANDBY: + case REQUEST_BMPS: + case REQUEST_ENTER_WOWL: + case REQUEST_EXIT_WOWL: + pmcLog(pMac, LOGW, FL("Request for full power is being buffered. " + "Current state is %d"), pMac->pmc.pmcState); + //Ignore the new reason if request for full power is already pending + if( !pMac->pmc.requestFullPowerPending ) + { + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = fullPowerReason; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case IMPS: + if (pmcIssueCommand( pMac, 0, eSmeCommandExitImps, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case BMPS: + { + tExitBmpsInfo exitBmpsInfo; + exitBmpsInfo.exitBmpsReason = fullPowerReason; + + if (pmcIssueCommand(hHal, 0, eSmeCommandExitBmps, &exitBmpsInfo, + sizeof(tExitBmpsInfo), FALSE) != eHAL_STATUS_SUCCESS) + { + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + /* Already in Request Full Power State. */ + case REQUEST_FULL_POWER: + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case STANDBY: + if (pmcIssueCommand(hHal, 0, eSmeCommandExitImps, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_IMPS_REQ"); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device exit UAPSD mode first */ + case UAPSD: + //Need to save the reason code here in case later on we need to exit BMPS as well + if (pmcIssueCommand(hHal, 0, eSmeCommandExitUapsd, &fullPowerReason, + sizeof(tRequestFullPowerReason), FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device exit WOWL mode first */ + case WOWL: + if (pmcIssueCommand(hHal, 0, eSmeCommandExitWowl, &fullPowerReason, + sizeof(tRequestFullPowerReason), FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGP, "PMC: failure to send message " + "eWNI_PMC_EXIT_WOWL_REQ"); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Cannot go directly to Request Full Power State from these states. */ + default: + pmcLog(pMac, LOGE, + FL("Trying to enter Request Full Power State from state %d"), pMac->pmc.pmcState); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestImpsState +* +* Description: +* Have the device enter the Request IMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestImpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterRequestImpsState")); + + /* Can enter Request IMPS State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Trying to enter Request IMPS State from state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Make sure traffic timer that triggers bmps entry is not running */ + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter IMPS mode. */ + if (pmcIssueCommand(hHal, 0, eSmeCommandEnterImps, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_IMPS_REQ"); + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + return eHAL_STATUS_FAILURE; + } + + pmcLog(pMac, LOG2, FL("eWNI_PMC_ENTER_IMPS_REQ sent to PE")); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterImpsState +* +* Description: +* Have the device enter the IMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterImpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterImpsState")); + + /* Can enter IMPS State only from Request IMPS State. */ + if (pMac->pmc.pmcState != REQUEST_IMPS) + { + pmcLog(pMac, LOGE, FL("Trying to enter IMPS State from state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = IMPS; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + + /* Start exit IMPS sequence now. */ + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + /* Set timer to come out of IMPS.only if impsPeriod is non-Zero*/ + if(0 != pMac->pmc.impsPeriod) + { + if (vos_timer_start(&pMac->pmc.hImpsTimer, pMac->pmc.impsPeriod) != VOS_STATUS_SUCCESS) + { + PMC_ABORT; + pMac->pmc.ImpsReqTimerFailed = VOS_TRUE; + if (!(pMac->pmc.ImpsReqTimerfailCnt & 0xF)) + { + pMac->pmc.ImpsReqTimerfailCnt++; + pmcLog(pMac, LOGE, + FL("Cannot start IMPS timer, FailCnt - %d"), pMac->pmc.ImpsReqTimerfailCnt); + } + pmcEnterRequestFullPowerState(hHal, eSME_REASON_OTHER); + return eHAL_STATUS_FAILURE; + } + if (pMac->pmc.ImpsReqTimerfailCnt) + { + pmcLog(pMac, LOGE, + FL("Start IMPS timer was failed %d times before success"), pMac->pmc.ImpsReqTimerfailCnt); + } + pMac->pmc.ImpsReqTimerfailCnt = 0; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestBmpsState +* +* Description: +* Have the device enter the Request BMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestBmpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterRequestBmpsState")); + + /* Can enter Request BMPS State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, + FL("Trying to enter Request BMPS State from state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Stop Traffic timer if running. Note: timer could have expired because of possible + race conditions. So no need to check for errors. Just make sure timer is not running */ + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter BMPS mode. */ + if ( !pMac->pmc.bmpsRequestQueued ) + { + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_TRUE; + if(pmcIssueCommand(hHal, 0, eSmeCommandEnterBmps, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_BMPS_REQ"); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + { + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + return eHAL_STATUS_FAILURE; + } + } + else + { + pmcLog(pMac, LOGE, "PMC: enter BMPS command already queued"); + //restart the timer if needed + if(pmcShouldBmpsTimerRun(pMac)) + { + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + return eHAL_STATUS_SUCCESS; + } + + pmcLog(pMac, LOGW, FL("eWNI_PMC_ENTER_BMPS_REQ sent to PE")); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterBmpsState +* +* Description: +* Have the device enter the BMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterBmpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterBmpsState")); + + /* Can enter BMPS State only from 5 states. */ + if (pMac->pmc.pmcState != REQUEST_BMPS && + pMac->pmc.pmcState != REQUEST_START_UAPSD && + pMac->pmc.pmcState != REQUEST_STOP_UAPSD && + pMac->pmc.pmcState != REQUEST_ENTER_WOWL && + pMac->pmc.pmcState != REQUEST_EXIT_WOWL) + { + pmcLog(pMac, LOGE, FL("Trying to enter BMPS State from state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = BMPS; + + /* Update registerd modules that we are entering BMPS. This is + only way to inform modules if PMC entered BMPS power save mode + on its own because of traffic timer */ + pmcDoDeviceStateUpdateCallbacks(hHal, BMPS); + + /* If we have a reqeust for full power pending then we have to go directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + + /* Start exit BMPS sequence now. */ + pmcLog(pMac, LOGW, FL("Pending Full Power request found on entering BMPS mode. " + "Start exit BMPS exit sequence")); + //Note: Reason must have been set when requestFullPowerPending flag was set. + pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + return eHAL_STATUS_SUCCESS; + } + + /*This should never happen ideally. WOWL and UAPSD not supported at the same time */ + if (pMac->pmc.wowlModeRequired && pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGW, FL("Both UAPSD and WOWL is required on entering BMPS mode. " + "UAPSD will be prioritized over WOWL")); + } + + /* Do we need Uapsd?*/ + if (pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGW, FL("UAPSD session is required on entering BMPS mode. " + "Start UAPSD entry sequence")); + pmcEnterRequestStartUapsdState(hHal); + return eHAL_STATUS_SUCCESS; + } + + /* Do we need WOWL?*/ + if (pMac->pmc.wowlModeRequired) + { + pmcLog(pMac, LOGW, FL("WOWL is required on entering BMPS mode. " + "Start WOWL entry sequence")); + pmcRequestEnterWowlState(hHal, &(pMac->pmc.wowlEnterParams)); + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcPowerSaveCheck +* +* Description: +* Check if device is allowed to enter a power save mode. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* TRUE - entry is allowed +* FALSE - entry is not allowed at this time +* +******************************************************************************/ +tANI_BOOLEAN pmcPowerSaveCheck (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + tANI_BOOLEAN (*checkRoutine) (void *checkContext); + tANI_BOOLEAN bResult=FALSE; + + pmcLog(pMac, LOG2, FL("Entering pmcPowerSaveCheck")); + + /* Call the routines in the power save check routine list. If any + return FALSE, then we cannot go into power save mode. */ + pEntry = csrLLPeekHead(&pMac->pmc.powerSaveCheckList, FALSE); + while (pEntry != NULL) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + checkRoutine = pPowerSaveCheckEntry->checkRoutine; + + /* If the checkRoutine is NULL for a paricular entry, proceed with other entries + * in the list */ + if (NULL != checkRoutine) + { + if (!checkRoutine(pPowerSaveCheckEntry->checkContext)) + { + pmcLog(pMac, LOGE, FL("pmcPowerSaveCheck fail!")); + bResult = FALSE; + break; + } + else + { + bResult = TRUE; + } + } + pEntry = csrLLNext(&pMac->pmc.powerSaveCheckList, pEntry, FALSE); + } + + return bResult; +} + + +/****************************************************************************** +* +* Name: pmcSendPowerSaveConfigMessage +* +* Description: +* Send a message to PE/MAC to configure the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - message successfuly sent +* eHAL_STATUS_FAILURE - error while sending message +* +******************************************************************************/ +eHalStatus pmcSendPowerSaveConfigMessage (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirPowerSaveCfg powerSaveConfig; + + pmcLog(pMac, LOG2, FL("Entering pmcSendPowerSaveConfigMessage")); + + vos_mem_set(&(powerSaveConfig), sizeof(tSirPowerSaveCfg), 0); + + switch (pMac->pmc.bmpsConfig.forwardBeacons) + { + case ePMC_NO_BEACONS: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NONE; + break; + case ePMC_BEACONS_WITH_TIM_SET: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_TIM; + break; + case ePMC_BEACONS_WITH_DTIM_SET: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_DTIM; + break; + case ePMC_NTH_BEACON: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NTH; + powerSaveConfig.nthBeaconFwd = (tANI_U16)pMac->pmc.bmpsConfig.valueOfN; + break; + case ePMC_ALL_BEACONS: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NTH; + powerSaveConfig.nthBeaconFwd = 1; + break; + } + powerSaveConfig.fEnablePwrSaveImmediately = pMac->pmc.bmpsConfig.setPmOnLastFrame; + powerSaveConfig.fPSPoll = pMac->pmc.bmpsConfig.usePsPoll; + powerSaveConfig.fEnableBeaconEarlyTermination = + pMac->pmc.bmpsConfig.enableBeaconEarlyTermination; + powerSaveConfig.bcnEarlyTermWakeInterval = + pMac->pmc.bmpsConfig.bcnEarlyTermWakeInterval; + + /* setcfg for listenInterval. Make sure CFG is updated because PE reads this + from CFG at the time of assoc or reassoc */ + ccmCfgSetInt(pMac, WNI_CFG_LISTEN_INTERVAL, pMac->pmc.bmpsConfig.bmpsPeriod, + NULL, eANI_BOOLEAN_FALSE); + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + //Wake up the chip first + eHalStatus status = pmcDeferMsg( pMac, eWNI_PMC_PWR_SAVE_CFG, + &powerSaveConfig, sizeof(tSirPowerSaveCfg) ); + + if( eHAL_STATUS_PMC_PENDING == status ) + { + return eHAL_STATUS_SUCCESS; + } + else + { + //either fail or already in full power + if( !HAL_STATUS_SUCCESS( status ) ) + { + return ( status ); + } + //else let it through because it is in full power state + } + } + /* Send a message so that FW System config is also updated and is in sync with + the CFG.*/ + if (pmcSendMessage(hHal, eWNI_PMC_PWR_SAVE_CFG, &powerSaveConfig, sizeof(tSirPowerSaveCfg)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_PWR_SAVE_CFG to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcSendMessage +* +* Description: +* Send a message to PE/MAC. +* +* Parameters: +* hHal - HAL handle for device +* messageType - message type to send +* pMessageData - pointer to message data +* messageSize - Size of the message data +* +* Returns: +* eHAL_STATUS_SUCCESS - message successfuly sent +* eHAL_STATUS_FAILURE - error while sending message +* +******************************************************************************/ +eHalStatus pmcSendMessage (tpAniSirGlobal pMac, tANI_U16 messageType, void *pMessageData, tANI_U32 messageSize) +{ + tSirMbMsg *pMsg; + + pmcLog(pMac, LOG2, FL("Entering pmcSendMessage, message type %d"), messageType); + + /* Allocate and fill in message. */ + pMsg = vos_mem_malloc(WNI_CFG_MB_HDR_LEN + messageSize); + if ( NULL == pMsg ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for message")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + pMsg->type = messageType; + pMsg->msgLen = (tANI_U16) (WNI_CFG_MB_HDR_LEN + messageSize); + if (messageSize > 0) + { + vos_mem_copy(pMsg->data, pMessageData, messageSize); + } + + /* Send message. */ + if (palSendMBMessage(pMac->hHdd, pMsg) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot send message")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcDoCallbacks +* +* Description: +* Call the IMPS callback routine and the routines in the request full +* power callback routine list. +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - status to pass to the callback routines +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpRequestFullPowerEntry pRequestFullPowerEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcDoCallbacks")); + + /* Call IMPS callback routine. */ + if (pMac->pmc.impsCallbackRoutine != NULL) + { + pMac->pmc.impsCallbackRoutine(pMac->pmc.impsCallbackContext, callbackStatus); + pMac->pmc.impsCallbackRoutine = NULL; + } + + /* Call the routines in the request full power callback routine list. */ + while (NULL != (pEntry = csrLLRemoveHead(&pMac->pmc.requestFullPowerList, TRUE))) + { + pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link); + if (pRequestFullPowerEntry->callbackRoutine) + pRequestFullPowerEntry->callbackRoutine(pRequestFullPowerEntry->callbackContext, callbackStatus); + vos_mem_free(pRequestFullPowerEntry); + } + +} + + +/****************************************************************************** +* +* Name: pmcStartTrafficTimer +* +* Description: +* Start the timer used in Full Power State to measure traffic +* levels and determine when to enter BMPS. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - timer successfuly started +* eHAL_STATUS_FAILURE - error while starting timer +* +******************************************************************************/ +eHalStatus pmcStartTrafficTimer (tHalHandle hHal, tANI_U32 expirationTime) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + + pmcLog(pMac, LOG2, FL("Entering pmcStartTrafficTimer")); + + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, expirationTime); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + if( VOS_STATUS_E_ALREADY == vosStatus ) + { + //Consider this ok since the timer is already started. + pmcLog(pMac, LOGW, FL(" traffic timer is already started")); + } + else + { + pmcLog(pMac, LOGP, FL("Cannot start traffic timer")); + return eHAL_STATUS_FAILURE; + } + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStopTrafficTimer +* +* Description: +* Cancels the timer (if running) used in Full Power State to measure traffic +* levels and determine when to enter BMPS. +* +* Parameters: +* hHal - HAL handle for device +* +* +******************************************************************************/ +void pmcStopTrafficTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pmcLog(pMac, LOG2, FL("Entering pmcStopTrafficTimer")); + vos_timer_stop(&pMac->pmc.hTrafficTimer); +} + + +/****************************************************************************** +* +* Name: pmcImpsTimerExpired +* +* Description: +* Called when IMPS timer expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcImpsTimerExpired (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcImpsTimerExpired")); + + /* If timer expires and we are in a state other than IMPS State then something is wrong. */ + if (pMac->pmc.pmcState != IMPS) + { + pmcLog(pMac, LOGE, FL("Got IMPS timer expiration in state %d"), pMac->pmc.pmcState); + PMC_ABORT; + return; + } + + /* Start on the path of going back to full power. */ + pmcEnterRequestFullPowerState(hHal, eSME_REASON_OTHER); +} + + +/****************************************************************************** +* +* Name: pmcTrafficTimerExpired +* +* Description: +* Called when traffic measurement timer expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcTrafficTimerExpired (tHalHandle hHal) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + + pmcLog(pMac, LOG2, FL("BMPS Traffic timer expired")); + + /* If timer expires and we are in a state other than Full Power State then something is wrong. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Got traffic timer expiration in state %d"), pMac->pmc.pmcState); + return; + } + + /* Untill DHCP is not completed remain in power active */ + if(pMac->pmc.remainInPowerActiveTillDHCP) + { + pmcLog(pMac, LOG2, FL("BMPS Traffic Timer expired before DHCP completion ignore enter BMPS")); + pMac->pmc.remainInPowerActiveThreshold++; + if( pMac->pmc.remainInPowerActiveThreshold >= DHCP_REMAIN_POWER_ACTIVE_THRESHOLD) + { + pmcLog(pMac, LOGE, + FL("Remain in power active DHCP threshold reached FALLBACK to enable enter BMPS")); + /*FALLBACK: reset the flag to make BMPS entry possible*/ + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + pMac->pmc.remainInPowerActiveThreshold = 0; + } + //Activate the Traffic Timer again for entering into BMPS + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) && (VOS_STATUS_E_ALREADY != vosStatus) ) + { + pmcLog(pMac, LOGP, FL("Cannot re-start traffic timer")); + } + return; + } + + /* Clear remain in power active threshold */ + pMac->pmc.remainInPowerActiveThreshold = 0; + + /* Check if the timer should be running */ + if (!pmcShouldBmpsTimerRun(pMac)) + { + pmcLog(pMac, LOGE, FL("BMPS timer should not be running")); + return; + } + +#ifdef FEATURE_WLAN_TDLS + if (pMac->isTdlsPowerSaveProhibited) + { + pmcLog(pMac, LOGE, FL("TDLS peer(s) connected/discovery sent. Dont enter BMPS")); + return; + } +#endif + + if (pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOGW, FL("BMPS entry criteria satisfied. Requesting BMPS state")); + (void)pmcEnterRequestBmpsState(hHal); + } + else + { + /*Some module voted against Power Save. So timer should be restarted again to retry BMPS */ + pmcLog(pMac, LOGE, FL("Power Save check failed. Retry BMPS again later")); + //Since hTrafficTimer is a vos_timer now, we need to restart the timer here + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) && (VOS_STATUS_E_ALREADY != vosStatus) ) + { + pmcLog(pMac, LOGP, FL("Cannot start traffic timer")); + return; + } + } +} + + +/****************************************************************************** +* +* Name: pmcExitPowerSaveTimerExpired +* +* Description: +* Called when timer used to schedule a deferred power save mode exit expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcExitPowerSaveTimerExpired (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcExitPowerSaveTimerExpired")); + + /* Make sure process of exiting power save mode might hasn't already been started due to another trigger. */ + if (pMac->pmc.requestFullPowerPending) + + /* Start on the path of going back to full power. */ + pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); +} + +/****************************************************************************** +* +* Name: pmcDoBmpsCallbacks +* +* Description: +* Call the registered BMPS callback routines because device is unable to +* enter BMPS state +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoBmpsCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpRequestBmpsEntry pRequestBmpsEntry; + + pmcLog(pMac, LOG2, "PMC: entering pmcDoBmpsCallbacks"); + + /* Call the routines in the request BMPS callback routine list. */ + csrLLLock(&pMac->pmc.requestBmpsList); + pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE); + while (pEntry != NULL) + { + pRequestBmpsEntry = GET_BASE_ADDR(pEntry, tRequestBmpsEntry, link); + if (pRequestBmpsEntry->callbackRoutine) + pRequestBmpsEntry->callbackRoutine(pRequestBmpsEntry->callbackContext, + callbackStatus); + vos_mem_free(pRequestBmpsEntry); + pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE); + } + csrLLUnlock(&pMac->pmc.requestBmpsList); +} + + + + +/****************************************************************************** +* +* Name: pmcDoStartUapsdCallbacks +* +* Description: +* Call the registered UAPSD callback routines because device is unable to +* start UAPSD state +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoStartUapsdCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpStartUapsdEntry pStartUapsdEntry; + + pmcLog(pMac, LOG2, "PMC: entering pmcDoStartUapsdCallbacks"); + csrLLLock(&pMac->pmc.requestStartUapsdList); + /* Call the routines in the request start UAPSD callback routine list. */ + pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE); + while (pEntry != NULL) + { + pStartUapsdEntry = GET_BASE_ADDR(pEntry, tStartUapsdEntry, link); + pStartUapsdEntry->callbackRoutine(pStartUapsdEntry->callbackContext, + callbackStatus); + vos_mem_free(pStartUapsdEntry); + pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE); + } + csrLLUnlock(&pMac->pmc.requestStartUapsdList); +} + +/****************************************************************************** +* +* Name: pmcEnterRequestStartUapsdState +* +* Description: +* Have the device enter the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStartUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_BOOL_t fFullPower = VOS_FALSE; //need to get back to full power state + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterRequestStartUapsdState"); + + /* Can enter UAPSD State only from FULL_POWER or BMPS State. */ + switch (pMac->pmc.pmcState) + { + case FULL_POWER: + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOGW, "PMC: Power save check failed. UAPSD request " + "will be accepted and buffered"); + /* UAPSD mode will be attempted when we enter BMPS later */ + pMac->pmc.uapsdSessionRequired = TRUE; + /* Make sure the BMPS retry timer is running */ + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + break; + } + else + { + pMac->pmc.uapsdSessionRequired = TRUE; + //Check BTC state +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( btcIsReadyForUapsd( pMac ) ) +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + { + /* Put device in BMPS mode first. This step should NEVER fail. + That is why no need to buffer the UAPSD request*/ + if(pmcEnterRequestBmpsState(hHal) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: Device in Full Power. Enter Request Bmps failed. " + "UAPSD request will be dropped "); + return eHAL_STATUS_FAILURE; + } + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + else + { + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + break; + + case BMPS: + //It is already in BMPS mode, check BTC state +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( btcIsReadyForUapsd(pMac) ) +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + { + /* Tell MAC to have device enter UAPSD mode. */ + if (pmcIssueCommand(hHal, 0, eSmeCommandEnterUapsd, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_BMPS_REQ"); + return eHAL_STATUS_FAILURE; + } + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + else + { + //Not ready for UAPSD at this time, save it first and wake up the chip + pmcLog(pMac, LOGE, " PMC state = %d",pMac->pmc.pmcState); + pMac->pmc.uapsdSessionRequired = TRUE; + /* While BTC traffic is going on, STA can be in BMPS + * and need not go to Full Power */ + //fFullPower = VOS_TRUE; + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + break; + + case REQUEST_START_UAPSD: +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( !btcIsReadyForUapsd(pMac) ) + { + //BTC rejects UAPSD, bring it back to full power + fFullPower = VOS_TRUE; + } +#endif + break; + + case REQUEST_BMPS: + /* Buffer request for UAPSD mode. */ + pMac->pmc.uapsdSessionRequired = TRUE; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( !btcIsReadyForUapsd(pMac) ) + { + //BTC rejects UAPSD, bring it back to full power + fFullPower = VOS_TRUE; + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + break; + + default: + pmcLog(pMac, LOGE, "PMC: trying to enter UAPSD State from state %d", + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + if(fFullPower) + { + if( eHAL_STATUS_PMC_PENDING != pmcRequestFullPower( pMac, NULL, NULL, eSME_REASON_OTHER ) ) + { + //This is an error + pmcLog(pMac, LOGE, FL(" fail to request full power because BTC")); + } + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterUapsdState +* +* Description: +* Have the device enter the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterUapsdState"); + + /* Can enter UAPSD State only from Request UAPSD State. */ + if (pMac->pmc.pmcState != REQUEST_START_UAPSD ) + { + pmcLog(pMac, LOGE, "PMC: trying to enter UAPSD State from state %d", + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = UAPSD; + + /* Update registerd modules that we are entering UAPSD. This is + only way to inform modules if PMC resumed UAPSD power save mode + on its own after full power mode */ + pmcDoDeviceStateUpdateCallbacks(hHal, UAPSD); + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit UAPSD sequence now. */ + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestStopUapsdState +* +* Description: +* Have the device Stop the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStopUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterRequestStopUapsdState"); + + /* If already in REQUEST_STOP_UAPSD, simply return */ + if (pMac->pmc.pmcState == REQUEST_STOP_UAPSD) + { + return eHAL_STATUS_SUCCESS; + } + + /* Can enter Request Stop UAPSD State only from UAPSD */ + if (pMac->pmc.pmcState != UAPSD) + { + pmcLog(pMac, LOGE, "PMC: trying to enter Request Stop UAPSD State from " + "state %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Tell MAC to have device exit UAPSD mode. */ + if (pmcIssueCommand(hHal, 0, eSmeCommandExitUapsd, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterRequestStandbyState +* +* Description: +* Have the device enter the Request STANDBY State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStandbyState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterRequestStandbyState"); + + /* Can enter Standby State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, "PMC: trying to enter Standby State from " + "state %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + // Stop traffic timer. Just making sure timer is not running + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter STANDBY mode. We are using the same message + as IMPS mode to avoid code changes in layer below (PE/HAL)*/ + if (pmcIssueCommand(hHal, 0, eSmeCommandEnterStandby, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_IMPS_REQ"); + pMac->pmc.pmcState = FULL_POWER; + + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterStandbyState +* +* Description: +* Have the device enter the STANDBY State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterStandbyState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterStandbyState"); + + /* Can enter STANDBY State only from REQUEST_STANDBY State. */ + if (pMac->pmc.pmcState != REQUEST_STANDBY) + { + pmcLog(pMac, LOGE, "PMC: trying to enter STANDBY State from state %d", + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = STANDBY; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit STANDBY sequence now. */ + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDoStandbyCallbacks +* +* Description: +* Call the registered Standby callback routines +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoStandbyCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcDoStandbyCallbacks"); + + /* Call Standby callback routine. */ + if (pMac->pmc.standbyCallbackRoutine != NULL) + pMac->pmc.standbyCallbackRoutine(pMac->pmc.standbyCallbackContext, callbackStatus); + pMac->pmc.standbyCallbackRoutine = NULL; + pMac->pmc.standbyCallbackContext = NULL; +} + +/****************************************************************************** +* +* Name: pmcGetPmcState +* +* Description: +* Return the PMC state +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* tPmcState (one of IMPS, REQUEST_IMPS, BMPS, REQUEST_BMPS etc) +* +******************************************************************************/ +tPmcState pmcGetPmcState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->pmc.pmcState; +} + +const char* pmcGetPmcStateStr(tPmcState state) +{ + switch(state) + { + case STOPPED: + return "STOPPED"; + case FULL_POWER: + return "FULL_POWER"; + case LOW_POWER: + return "LOW_POWER"; + case IMPS: + return "IMPS"; + case BMPS: + return "BMPS"; + case UAPSD: + return "UAPSD"; + case STANDBY: + return "STANDBY"; + case REQUEST_IMPS: + return "REQUEST_IMPS"; + case REQUEST_BMPS: + return "REQUEST_BMPS"; + case REQUEST_START_UAPSD: + return "REQUEST_START_UAPSD"; + case REQUEST_STOP_UAPSD: + return "REQUEST_STOP_UAPSD"; + case REQUEST_FULL_POWER: + return "REQUEST_FULL_POWER"; + case REQUEST_STANDBY: + return "REQUEST_STANDBY"; + case REQUEST_ENTER_WOWL: + return "REQUEST_ENTER_WOWL"; + case REQUEST_EXIT_WOWL: + return "REQUEST_EXIT_WOWL"; + case WOWL: + return "WOWL"; + default: + break; + } + + return "UNKNOWN"; +} + +void pmcDoDeviceStateUpdateCallbacks (tHalHandle hHal, tPmcState state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState); + + pmcLog(pMac, LOG2, FL("PMC - Update registered modules of new device " + "state: %s"), pmcGetPmcStateStr(state)); + + /* Call the routines in the update device state routine list. */ + pEntry = csrLLPeekHead(&pMac->pmc.deviceStateUpdateIndList, FALSE); + while (pEntry != NULL) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + callbackRoutine = pDeviceStateUpdateIndEntry->callbackRoutine; + callbackRoutine(pDeviceStateUpdateIndEntry->callbackContext, state); + pEntry = csrLLNext(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE); + } +} + +/****************************************************************************** +* +* Name: pmcRequestEnterWowlState +* +* Description: +* Have the device enter the WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - WOWL mode will be entered +* eHAL_STATUS_FAILURE - WOWL mode cannot be entered +* +******************************************************************************/ +eHalStatus pmcRequestEnterWowlState(tHalHandle hHal, tpSirSmeWowlEnterParams wowlEnterParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pmcLog(pMac, LOG2, "PMC: entering pmcRequestEnterWowlState"); + + if(pMac->psOffloadEnabled) + { + if (pmcIssueCommand(hHal, 0, eSmeCommandEnterWowl, wowlEnterParams, + sizeof(tSirSmeWowlEnterParams), FALSE) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ"); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; + } + + switch (pMac->pmc.pmcState) + { + case FULL_POWER: + /* Put device in BMPS mode first. This step should NEVER fail. */ + if(pmcEnterRequestBmpsState(hHal) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: Device in Full Power. pmcEnterRequestBmpsState failed. " + "Cannot enter WOWL"); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_BMPS: + pmcLog(pMac, LOGW, "PMC: BMPS transaction going on. WOWL request " + "will be buffered"); + break; + + case BMPS: + case WOWL: + /* Tell MAC to have device enter WOWL mode. Note: We accept WOWL request + when we are in WOWL mode. This allows HDD to change WOWL configuration + without having to exit WOWL mode */ + if (pmcIssueCommand(hHal, 0, eSmeCommandEnterWowl, wowlEnterParams, + sizeof(tSirSmeWowlEnterParams), FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ"); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_ENTER_WOWL: + //Multiple enter WOWL requests at the same time are not accepted + pmcLog(pMac, LOGE, "PMC: Enter WOWL transaction already going on. New WOWL request " + "will be rejected"); + return eHAL_STATUS_FAILURE; + + case REQUEST_EXIT_WOWL: + pmcLog(pMac, LOGW, "PMC: Exit WOWL transaction going on. New WOWL request " + "will be buffered"); + break; + + default: + pmcLog(pMac, LOGE, "PMC: Trying to enter WOWL State from state %s", + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterWowlState +* +* Description: +* Have the device enter the WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterWowlState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterWowlState"); + + /* Can enter WOWL State only from Request WOWL State. */ + if (pMac->pmc.pmcState != REQUEST_ENTER_WOWL ) + { + pmcLog(pMac, LOGP, "PMC: trying to enter WOWL State from state %d", + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = WOWL; + + /* Clear the buffered command for WOWL */ + pMac->pmc.wowlModeRequired = FALSE; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit Wowl sequence now. */ + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcRequestExitWowlState +* +* Description: +* Have the device exit WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* wowlExitParams - Carries info on which smesession wowl exit is requested. + +* Returns: +* eHAL_STATUS_SUCCESS - Exit WOWL successful +* eHAL_STATUS_FAILURE - Exit WOWL unsuccessful +* +******************************************************************************/ +eHalStatus pmcRequestExitWowlState(tHalHandle hHal, + tpSirSmeWowlExitParams wowlExitParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestExitWowlState"); + + if (pMac->psOffloadEnabled) + { + if (pmcIssueCommand(hHal, 0, eSmeCommandExitWowl, wowlExitParams, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGP, "PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ"); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; + } + + switch (pMac->pmc.pmcState) + { + case WOWL: + /* Tell MAC to have device exit WOWL mode. */ + if (pmcIssueCommand(hHal, 0, eSmeCommandExitWowl, NULL, 0, FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGP, "PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ"); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_ENTER_WOWL: + pmcLog(pMac, LOGP, "PMC: Rcvd exit WOWL even before enter WOWL was completed"); + return eHAL_STATUS_FAILURE; + + default: + pmcLog(pMac, LOGW, "PMC: Got exit WOWL in state %s. Nothing to do as already out of WOWL", + pmcGetPmcStateStr(pMac->pmc.pmcState)); + break; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDoEnterWowlCallbacks +* +* Description: +* Invoke Enter WOWL callbacks +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: None +* +******************************************************************************/ +void pmcDoEnterWowlCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcDoWowlCallbacks"); + + /* Call Wowl callback routine. */ + if (pMac->pmc.enterWowlCallbackRoutine != NULL) + pMac->pmc.enterWowlCallbackRoutine(pMac->pmc.enterWowlCallbackContext, callbackStatus); + + pMac->pmc.enterWowlCallbackRoutine = NULL; + pMac->pmc.enterWowlCallbackContext = NULL; +} + + +static void pmcProcessDeferredMsg( tpAniSirGlobal pMac ) +{ + tPmcDeferredMsg *pDeferredMsg; + tListElem *pEntry; + + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->pmc.deferredMsgList, eANI_BOOLEAN_TRUE ) ) ) + { + pDeferredMsg = GET_BASE_ADDR( pEntry, tPmcDeferredMsg, link ); + switch (pDeferredMsg->messageType) + { + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + if (pDeferredMsg->size != sizeof(tSirWowlAddBcastPtrn)) + { + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirWowlAddBcastPtrn) ); + return; + } + + if (pmcSendMessage(pMac, eWNI_PMC_WOWL_ADD_BCAST_PTRN, + &pDeferredMsg->u.wowlAddPattern, sizeof(tSirWowlAddBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + } + break; + + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + if (pDeferredMsg->size != sizeof(tSirWowlDelBcastPtrn)) + { + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirWowlDelBcastPtrn) ); + return; + } + if (pmcSendMessage(pMac, eWNI_PMC_WOWL_DEL_BCAST_PTRN, + &pDeferredMsg->u.wowlDelPattern, sizeof(tSirWowlDelBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + } + break; + + case eWNI_PMC_PWR_SAVE_CFG: + if (pDeferredMsg->size != sizeof(tSirPowerSaveCfg)) + { + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirPowerSaveCfg) ); + return; + } + if (pmcSendMessage(pMac, eWNI_PMC_PWR_SAVE_CFG, + &pDeferredMsg->u.powerSaveConfig, sizeof(tSirPowerSaveCfg)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_PWR_SAVE_CFG to PE failed")); + } + break; + + default: + pmcLog(pMac, LOGE, FL("unknown message (%d)"), pDeferredMsg->messageType); + break; + } + //Need to free the memory here + vos_mem_free(pDeferredMsg); + } //while +} + + +eHalStatus pmcDeferMsg( tpAniSirGlobal pMac, tANI_U16 messageType, void *pData, tANI_U32 size) +{ + tPmcDeferredMsg *pDeferredMsg; + eHalStatus status; + + pDeferredMsg = vos_mem_malloc(sizeof(tPmcDeferredMsg)); + if ( NULL == pDeferredMsg ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for callback context")); + return eHAL_STATUS_RESOURCES; + } + vos_mem_set(pDeferredMsg, sizeof(tPmcDeferredMsg), 0); + pDeferredMsg->messageType = messageType; + pDeferredMsg->size = (tANI_U16)size; + if( pData ) + { + vos_mem_copy(&pDeferredMsg->u.data, pData, size); + } + csrLLInsertTail( &pMac->pmc.deferredMsgList, &pDeferredMsg->link, eANI_BOOLEAN_TRUE ); + //No callback is needed. The messages are put into deferred queue and be processed first + //when enter full power is complete. + status = pmcRequestFullPower( pMac, NULL, NULL, eSME_REASON_OTHER ); + if( eHAL_STATUS_PMC_PENDING != status ) + { + //either fail or already in full power + if( csrLLRemoveEntry( &pMac->pmc.deferredMsgList, &pDeferredMsg->link, eANI_BOOLEAN_TRUE ) ) + { + vos_mem_free(pDeferredMsg); + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, FL("failed to request full power status = %d"), status); + } + } + + return (status); +} + +void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + if(!pCommand->u.pmcCmd.fReleaseWhenDone) + { + //This is a normal command, put it back to the free lsit + pCommand->u.pmcCmd.size = 0; + smeReleaseCommand( pMac, pCommand ); + } + else + { + //this is a specially allocated comamnd due to out of command buffer. free it. + vos_mem_free(pCommand); + } +} + + +//this function is used to abort a command where the normal processing of the command +//is terminated without going through the normal path. it is here to take care of callbacks for +//the command, if applicable. +void pmcAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + if( eSmePmcCommandMask & pCommand->command ) + { + if( !fStopping ) + { + switch( pCommand->command ) + { + case eSmeCommandEnterImps: + pmcLog(pMac, LOGE, FL("aborting request to enter IMPS")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandExitImps: + pmcLog(pMac, LOGE, FL("aborting request to exit IMPS ")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandEnterBmps: + pmcLog(pMac, LOGE, FL("aborting request to enter BMPS ")); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pmcEnterFullPowerState(pMac); + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitBmps: + pmcLog(pMac, LOGE, FL("aborting request to exit BMPS ")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandEnterUapsd: + pmcLog(pMac, LOGE, FL("aborting request to enter UAPSD ")); + //Since there is no retry for UAPSD, tell the requester here we are done with failure + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitUapsd: + pmcLog(pMac, LOGE, FL("aborting request to exit UAPSD ")); + break; + + case eSmeCommandEnterWowl: + pmcLog(pMac, LOGE, FL("aborting request to enter WOWL ")); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitWowl: + pmcLog(pMac, LOGE, FL("aborting request to exit WOWL ")); + break; + + case eSmeCommandEnterStandby: + pmcLog(pMac, LOGE, FL("aborting request to enter Standby ")); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + default: + pmcLog(pMac, LOGE, FL("Request for PMC command (%d) is dropped"), pCommand->command); + break; + } + }// !stopping + pmcReleaseCommand( pMac, pCommand ); + } +} + + + +//These commands are not supposed to fail due to out of command buffer, +//otherwise other commands are not executed and no command is released. It will be deadlock. +#define PMC_IS_COMMAND_CANNOT_FAIL(cmdType)\ + ( (eSmeCommandEnterStandby == (cmdType )) ||\ + (eSmeCommandExitImps == (cmdType )) ||\ + (eSmeCommandExitBmps == (cmdType )) ||\ + (eSmeCommandExitUapsd == (cmdType )) ||\ + (eSmeCommandExitWowl == (cmdType )) ) + +eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tSmeCmd **ppCmd) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + + if (NULL == ppCmd) + { + VOS_ASSERT( ppCmd ); + return eHAL_STATUS_FAILURE; + } + do + { + pCommand = smeGetCommandBuffer( pMac ); + if ( pCommand ) + { + //Make sure it will be put back to the list + pCommand->u.pmcCmd.fReleaseWhenDone = FALSE; + } + else + { + pmcLog( pMac, LOGE, + FL(" fail to get command buffer for command 0x%X curState = %d"), + cmdType, pMac->pmc.pmcState ); + //For certain PMC command, we cannot fail + if( PMC_IS_COMMAND_CANNOT_FAIL(cmdType) ) + { + pmcLog( pMac, LOGE, + FL(" command 0x%X cannot fail try allocating memory for it"), cmdType ); + pCommand = vos_mem_malloc(sizeof(tSmeCmd)); + if ( NULL == pCommand ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s fail to allocate memory for command (0x%X)", + __func__, cmdType); + pCommand = NULL; + return eHAL_STATUS_FAILURE; + } + vos_mem_set(pCommand, sizeof(tSmeCmd), 0); + //Make sure it will be free when it is done + pCommand->u.pmcCmd.fReleaseWhenDone = TRUE; + } + else + { + break; + } + } + pCommand->command = cmdType; + pCommand->sessionId = sessionId; + pCommand->u.pmcCmd.size = size; + //Initialize the reason code here. It may be overwritten later when + //a particular reason is needed. + pCommand->u.pmcCmd.fullPowerReason = eSME_REASON_OTHER; + switch ( cmdType ) + { + case eSmeCommandEnterImps: + case eSmeCommandExitImps: + case eSmeCommandEnterBmps: + case eSmeCommandEnterUapsd: + case eSmeCommandEnterStandby: + status = eHAL_STATUS_SUCCESS; + break; + + case eSmeCommandExitUapsd: + case eSmeCommandExitWowl: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + if (pMac->psOffloadEnabled && cmdType == eSmeCommandExitWowl) + { + pCommand->u.pmcCmd.u.exitWowlInfo = + *( ( tSirSmeWowlExitParams * )pvParam ); + } + else + { + pCommand->u.pmcCmd.fullPowerReason = + *( (tRequestFullPowerReason *)pvParam ); + } + } + break; + + case eSmeCommandExitBmps: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + pCommand->u.pmcCmd.u.exitBmpsInfo = *( (tExitBmpsInfo *)pvParam ); + pCommand->u.pmcCmd.fullPowerReason = pCommand->u.pmcCmd.u.exitBmpsInfo.exitBmpsReason; + } + else + { + pmcLog( pMac, LOGE, (" exit BMPS must have a reason code") ); + } + break; + + case eSmeCommandEnterWowl: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + pCommand->u.pmcCmd.u.enterWowlInfo = *( ( tSirSmeWowlEnterParams * )pvParam ); + } + break; + + default: + pmcLog( pMac, LOGE, FL(" invalid command type %d"), cmdType ); + status = eHAL_STATUS_INVALID_PARAMETER; + break; + } + + } while( 0 ); + + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + *ppCmd = pCommand; + } + else if( pCommand ) + { + pmcReleaseCommand( pMac, pCommand ); + } + + return (status); +} + + +eHalStatus pmcIssueCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tANI_BOOLEAN fPutToListHead ) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + + status = pmcPrepareCommand( pMac, sessionId, cmdType, pvParam, size, + &pCommand ); + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + smePushCommand( pMac, pCommand, fPutToListHead ); + } + else if( pCommand ) + { + pmcReleaseCommand( pMac, pCommand ); + } + + return( status ); +} + + + +tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE; + + do + { + switch ( pCommand->command ) + { + case eSmeCommandEnterImps: + if( FULL_POWER == pMac->pmc.pmcState ) + { + status = pmcEnterImpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Change state. */ + pMac->pmc.pmcState = REQUEST_IMPS; + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_IMPS_REQ, NULL, 0); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* If we already went back Full Power State (meaning that request did not + get as far as the device) then we are not successfull. */ + if ( FULL_POWER != pMac->pmc.pmcState ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + } + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, + "PMC: failure to send message eWNI_PMC_ENTER_IMPS_REQ or pmcEnterImpsCheck failed"); + pmcEnterFullPowerState( pMac ); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + }//full_power + break; + + case eSmeCommandExitImps: + pMac->pmc.requestFullPowerPending = FALSE; + if( ( IMPS == pMac->pmc.pmcState ) || ( STANDBY == pMac->pmc.pmcState ) ) + { + //Check state before sending message. The state may change after that + if( STANDBY == pMac->pmc.pmcState ) + { + //Enable Idle scan in CSR + csrScanResumeIMPS(pMac); + } + + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_IMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->pmc.pmcState = REQUEST_FULL_POWER; + pmcLog(pMac, LOG2, FL("eWNI_PMC_EXIT_IMPS_REQ sent to PE")); + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, + FL("eWNI_PMC_EXIT_IMPS_REQ fail to be sent to PE status %d"), status); + //Callbacks are called with success srarus, do we need to pass in real status?? + pmcEnterFullPowerState(pMac); + } + } + break; + + case eSmeCommandEnterBmps: + if( FULL_POWER == pMac->pmc.pmcState ) + { + //This function will not return success because the pmc state is not BMPS + status = pmcEnterBmpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Change PMC state */ + pMac->pmc.pmcState = REQUEST_BMPS; + pmcLog(pMac, LOG2, "PMC: Enter BMPS req done"); + /* Tell MAC to have device enter BMPS mode. */ + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_BMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "Fail to send enter BMPS msg to PE"); + } + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, + "PMC: failure to send message eWNI_PMC_ENTER_BMPS_REQ status %d", status); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pmcEnterFullPowerState(pMac); + //Do not call UAPSD callback here since it may be retried + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + } + break; + + case eSmeCommandExitBmps: + if( BMPS == pMac->pmc.pmcState ) + { + pMac->pmc.requestFullPowerPending = FALSE; + + status = pmcSendMessage( pMac, eWNI_PMC_EXIT_BMPS_REQ, + &pCommand->u.pmcCmd.u.exitBmpsInfo, sizeof(tExitBmpsInfo) ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->pmc.pmcState = REQUEST_FULL_POWER; + fRemoveCmd = eANI_BOOLEAN_FALSE; + pmcLog(pMac, LOG2, FL("eWNI_PMC_EXIT_BMPS_REQ sent to PE")); + + } + else + { + pmcLog(pMac, LOGE, FL("eWNI_PMC_EXIT_BMPS_REQ fail to be sent to PE status %d"), status); + pmcEnterFullPowerState(pMac); + } + } + break; + + case eSmeCommandEnterUapsd: + if( BMPS == pMac->pmc.pmcState ) + { + pMac->pmc.uapsdSessionRequired = TRUE; + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_UAPSD_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->pmc.pmcState = REQUEST_START_UAPSD; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_BMPS_REQ"); + //there is no retry for re-entering UAPSD so tell the requester we are done witgh failure. + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + break; + + case eSmeCommandExitUapsd: + if( UAPSD == pMac->pmc.pmcState ) + { + pMac->pmc.requestFullPowerPending = FALSE; + /* If already in REQUEST_STOP_UAPSD, simply return */ + if (pMac->pmc.pmcState == REQUEST_STOP_UAPSD) + { + break; + } + + /* Tell MAC to have device exit UAPSD mode. */ + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_UAPSD_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + /* Change state. Note that device will be put in BMPS state at the + end of REQUEST_STOP_UAPSD state even if response is a failure*/ + pMac->pmc.pmcState = REQUEST_STOP_UAPSD; + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = pCommand->u.pmcCmd.fullPowerReason; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + pmcEnterBmpsState(pMac); + } + } + + break; + + case eSmeCommandEnterWowl: + if( ( BMPS == pMac->pmc.pmcState ) || ( WOWL == pMac->pmc.pmcState ) ) + { + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_WOWL_REQ, + &pCommand->u.pmcCmd.u.enterWowlInfo, sizeof(tSirSmeWowlEnterParams)); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->pmc.pmcState = REQUEST_ENTER_WOWL; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ"); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + else + { + fRemoveCmd = eANI_BOOLEAN_TRUE; + } + break; + + case eSmeCommandExitWowl: + if( WOWL == pMac->pmc.pmcState ) + { + pMac->pmc.requestFullPowerPending = FALSE; + pMac->pmc.pmcState = REQUEST_EXIT_WOWL; + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_WOWL_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = pCommand->u.pmcCmd.fullPowerReason; + } + else + { + pmcLog(pMac, LOGP, "PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ"); + pmcEnterBmpsState(pMac); + } + } + break; + + case eSmeCommandEnterStandby: + if( FULL_POWER == pMac->pmc.pmcState ) + { + //Disallow standby if concurrent sessions are present. Note that CSR would have + //caused the STA to disconnect the Infra session (if not already disconnected) because of + //standby request. But we are now failing the standby request because of concurrent session. + //So was the tearing of infra session wasteful if we were going to fail the standby request ? + //Not really. This is beacuse if and when BT-AMP etc sessions are torn down we will transition + //to IMPS/standby and still save power. + if (csrIsIBSSStarted(pMac) || csrIsBTAMPStarted(pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "WLAN: IBSS or BT-AMP session present. Cannot honor standby request"); + + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_PMC_NOT_NOW); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + break; + } + + // Stop traffic timer. Just making sure timer is not running + pmcStopTrafficTimer(pMac); + + /* Change state. */ + pMac->pmc.pmcState = REQUEST_STANDBY; + + /* Tell MAC to have device enter STANDBY mode. We are using the same message + as IMPS mode to avoid code changes in layer below (PE/HAL)*/ + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_IMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + //Disable Idle scan in CSR + csrScanSuspendIMPS(pMac); + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_IMPS_REQ"); + pmcEnterFullPowerState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + /* Start the timer only if Auto BMPS feature is enabled or an UAPSD session is + required */ + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + } + break; + + default: + pmcLog( pMac, LOGE, FL(" invalid command type %d"), pCommand->command ); + break; + } + + } while( 0 ); + + return( fRemoveCmd ); +} + +eHalStatus pmcEnterImpsCheck( tpAniSirGlobal pMac ) +{ + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting IMPS when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check if IMPS is enabled. */ + if (!pMac->pmc.impsEnabled) + { + pmcLog(pMac, LOG2, FL("IMPS is disabled")); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check if IMPS enabled for current power source. */ + if ((pMac->pmc.powerSource == AC_POWER) && !pMac->pmc.impsConfig.enterOnAc) + { + pmcLog(pMac, LOG2, FL("IMPS is disabled when operating on AC power")); + return eHAL_STATUS_PMC_AC_POWER; + } + + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(pMac)) + { + pmcLog(pMac, LOG2, FL("IMPS cannot be entered now")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Check that entry into a power save mode is allowed at this time if all + running sessions agree. */ + if (!pmcAllowImps(pMac)) + { + pmcLog(pMac, LOG2, FL("IMPS cannot be entered now")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Check if already in IMPS. */ + if ((pMac->pmc.pmcState == REQUEST_IMPS) || (pMac->pmc.pmcState == IMPS) || + (pMac->pmc.pmcState == REQUEST_FULL_POWER)) + { + pmcLog(pMac, LOG2, FL("Already in IMPS")); + return eHAL_STATUS_PMC_ALREADY_IN_IMPS; + } + + /* Check whether driver load unload is in progress */ + if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) + { + pmcLog(pMac, LOGW, FL("Driver load/unload is in progress")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + return ( eHAL_STATUS_SUCCESS ); +} + +/* This API detrmines if it is ok to proceed with a Enter BMPS Request or not . Note when + device is in BMPS/UAPSD states, this API returns failure because it is not ok to issue + a BMPS request */ +eHalStatus pmcEnterBmpsCheck( tpAniSirGlobal pMac ) +{ + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot initiate BMPS. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting BMPS when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check that we are associated with a single active session. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, LOGE, "PMC: STA not associated with an AP with single active session. BMPS cannot be entered"); + return eHAL_STATUS_FAILURE; + } + + /* BMPS can only be requested when device is in Full Power */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, + "PMC: Device not in full power. Cannot request BMPS. pmcState %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(pMac)) + { + pmcLog(pMac, LOGE, "PMC: Power save check failed. BMPS cannot be entered now"); + return eHAL_STATUS_PMC_NOT_NOW; + } + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + pmcLog(pMac, LOG1, FL("doBMPSWorkaround %u"), pMac->roam.configParam.doBMPSWorkaround); + if (pMac->roam.configParam.doBMPSWorkaround) + { + pMac->roam.configParam.doBMPSWorkaround = 0; + pmcLog(pMac, LOG1, + FL("reset doBMPSWorkaround to disabled %u"), pMac->roam.configParam.doBMPSWorkaround); + csrDisconnectAllActiveSessions(pMac); + pmcLog(pMac, LOGE, + "PMC: doBMPSWorkaround was enabled. First Disconnect all sessions. pmcState %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + } + + return ( eHAL_STATUS_SUCCESS ); +} + +tANI_BOOLEAN pmcShouldBmpsTimerRun( tpAniSirGlobal pMac ) +{ + /* Check if BMPS is enabled and if Auto BMPS Feature is still enabled + * or there is a pending Uapsd request or HDD requested BMPS or there + * is a pending request for WoWL. In all these cases BMPS is required. + * Otherwise just stop the timer and return. + */ + if (!(pMac->pmc.bmpsEnabled && (pMac->pmc.autoBmpsEntryEnabled || + pMac->pmc.uapsdSessionRequired || pMac->pmc.bmpsRequestedByHdd || + pMac->pmc.wowlModeRequired ))) + { + pmcLog(pMac, LOG1, FL("BMPS is not enabled or not required")); + return eANI_BOOLEAN_FALSE; + } + + if(pMac->pmc.isHostPsEn && pMac->pmc.remainInPowerActiveTillDHCP) + { + pmcLog(pMac, LOG1, + FL("Host controlled ps enabled and host wants active mode, so dont allow BMPS")); + return eANI_BOOLEAN_FALSE; + } + + if ((vos_concurrent_open_sessions_running()) && + ((csrIsConcurrentInfraConnected( pMac ) || + (vos_get_concurrency_mode()& VOS_SAP) || + (vos_get_concurrency_mode()& VOS_P2P_GO)))) + { + pmcLog(pMac, LOG1, FL("Multiple Sessions/GO/SAP sessions . BMPS should not be started")); + return eANI_BOOLEAN_FALSE; + } + /* Check if there is an Infra session. BMPS is possible only if there is + * an Infra session */ + if (!csrIsInfraConnected(pMac)) + { + pmcLog(pMac, LOG1, FL("No Infra Session or multiple sessions. BMPS should not be started")); + return eANI_BOOLEAN_FALSE; + } + return eANI_BOOLEAN_TRUE; +} + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +#define PMC_DIAG_EVT_TIMER_INTERVAL ( 5000 ) + +void pmcDiagEvtTimerExpired (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_PMC_CURRENT_STATE; + psRequest.pmc_current_state = pMac->pmc.pmcState; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); + + pmcLog(pMac, LOGW, FL("DIAG event timer expired")); + + /* re-arm timer */ + if (pmcStartDiagEvtTimer(hHal) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGP, FL("Cannot re-arm DIAG evt timer")); + } + vos_timer_start(&pMac->pmc.hDiagEvtTimer, PMC_DIAG_EVT_TIMER_INTERVAL); +} + +eHalStatus pmcStartDiagEvtTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcStartDiagEvtTimer")); + + if ( vos_timer_start(&pMac->pmc.hDiagEvtTimer, PMC_DIAG_EVT_TIMER_INTERVAL) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGP, FL("Cannot start DIAG evt timer")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +void pmcStopDiagEvtTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pmcLog(pMac, LOG2, FL("Entering pmcStopDiagEvtTimer")); + (void)vos_timer_stop(&pMac->pmc.hDiagEvtTimer); +} +#endif + +void pmcOffloadClosePowerSaveCheckList(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tListElem *pEntry; + tpPmcOffloadPsCheckEntry pPowerSaveCheckEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + csrLLLock(&pmc->pwrsaveCheckList); + pEntry = csrLLRemoveHead(&pmc->pwrsaveCheckList, FALSE); + while(pEntry) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPmcOffloadPsCheckEntry, + link); + vos_mem_free(pPowerSaveCheckEntry); + pEntry = csrLLRemoveHead(&pmc->pwrsaveCheckList, FALSE); + } + csrLLUnlock(&pmc->pwrsaveCheckList); + csrLLClose(&pmc->pwrsaveCheckList); +} + +void pmcOffloadCloseDeviceStateUpdateList(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tListElem *pEntry; + tpPmcOffloadDevStateUpdIndEntry pPowerSaveDevStateEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + csrLLLock(&pmc->deviceStateUpdateIndList); + pEntry = csrLLRemoveHead(&pmc->deviceStateUpdateIndList, FALSE); + while(pEntry) + { + pPowerSaveDevStateEntry = GET_BASE_ADDR(pEntry, + tPmcOffloadDevStateUpdIndEntry, link); + vos_mem_free(pPowerSaveDevStateEntry); + pEntry = csrLLRemoveHead(&pmc->deviceStateUpdateIndList, FALSE); + } + csrLLUnlock(&pmc->deviceStateUpdateIndList); + csrLLClose(&pmc->deviceStateUpdateIndList); +} + +void pmcOffloadCloseReqStartUapsdList(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tListElem *pEntry; + tpPmcOffloadStartUapsdEntry pPowerSaveStartUapsdEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + csrLLLock(&pmc->uapsdCbList); + pEntry = csrLLRemoveHead(&pmc->uapsdCbList, FALSE); + while(pEntry) + { + pPowerSaveStartUapsdEntry = GET_BASE_ADDR(pEntry, + tPmcOffloadStartUapsdEntry, link); + vos_mem_free(pPowerSaveStartUapsdEntry); + pEntry = csrLLRemoveHead(&pmc->uapsdCbList, FALSE); + } + csrLLUnlock(&pmc->uapsdCbList); + csrLLClose(&pmc->uapsdCbList); +} + +void pmcOffloadCloseReqFullPwrList(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tListElem *pEntry; + tpPmcOffloadReqFullPowerEntry pPowerSaveFullPowerReqEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + csrLLLock(&pmc->fullPowerCbList); + pEntry = csrLLRemoveHead(&pmc->fullPowerCbList, FALSE); + while(pEntry) + { + pPowerSaveFullPowerReqEntry = GET_BASE_ADDR(pEntry, + tPmcOffloadReqFullPowerEntry, link); + vos_mem_free(pPowerSaveFullPowerReqEntry); + pEntry = csrLLRemoveHead(&pmc->fullPowerCbList, FALSE); + } + csrLLUnlock(&pmc->fullPowerCbList); + csrLLClose(&pmc->fullPowerCbList); +} + +eHalStatus pmcOffloadOpenPerSession(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadOpenPerSession")); + + pmc->pmcState = STOPPED; + pmc->sessionId = sessionId; + pmc->pMac = pMac; + + /* Allocate a timer to enable ps automatically */ + if (!VOS_IS_STATUS_SUCCESS(vos_timer_init(&pmc->autoPsEnableTimer, + VOS_TIMER_TYPE_SW, + pmcOffloadAutoPsEntryTimerExpired, pmc))) + { + smsLog(pMac, LOGE, FL("Cannot allocate timer for auto ps entry")); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for power save check routines and request full power callback routines. */ + if (csrLLOpen(pMac->hHdd, &pmc->pwrsaveCheckList) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Cannot initialize power save check routine list")); + return eHAL_STATUS_FAILURE; + } + if (csrLLOpen(pMac->hHdd, &pmc->fullPowerCbList) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Cannot initialize request full power callback routine list")); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for request start UAPSD callback routines. */ + if (csrLLOpen(pMac->hHdd, &pmc->uapsdCbList) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Cannot initialize uapsd callback routine list")); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for device state update indication callback routines. */ + if (csrLLOpen(pMac->hHdd, &pmc->deviceStateUpdateIndList) + != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Cannot initialize device state update ind callback list")); + return eHAL_STATUS_FAILURE; + } + + pmc->UapsdEnabled = TRUE; + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadStartPerSession(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadStartPerSession")); + pmc->uapsdSessionRequired = FALSE; + pmc->fullPowerReqPend = FALSE; + pmc->configStaPsEnabled = FALSE; + pmc->pmcState = FULL_POWER; + pmc->autoPsEntryTimerPeriod = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE; +#ifdef FEATURE_WLAN_TDLS + pmc->isTdlsPowerSaveProhibited = FALSE; +#endif + pmc->configDefStaPsEnabled = FALSE; + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadStopPerSession(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadStopPerSession")); + pmc->uapsdSessionRequired = FALSE; + pmc->fullPowerReqPend = FALSE; + pmc->configStaPsEnabled = FALSE; + pmc->pmcState = STOPPED; + pmc->autoPsEntryTimerPeriod = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE; + pmc->pMac = pMac; +#ifdef FEATURE_WLAN_TDLS + pmc->isTdlsPowerSaveProhibited = FALSE; +#endif + pmc->configDefStaPsEnabled = FALSE; + + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + pmcOffloadDoFullPowerCallbacks(pMac, sessionId, eHAL_STATUS_FAILURE); + pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, eHAL_STATUS_FAILURE); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadClosePerSession(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadDeInitPerSession")); + + if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pmc->autoPsEnableTimer))) + { + smsLog(pMac, LOGE, FL("Cannot deallocate traffic timer")); + } + + pmcOffloadClosePowerSaveCheckList(pMac, sessionId); + pmcOffloadCloseDeviceStateUpdateList(pMac, sessionId); + pmcOffloadCloseReqStartUapsdList(pMac, sessionId); + pmcOffloadCloseReqFullPwrList(pMac, sessionId); + return eHAL_STATUS_SUCCESS; +} + +void pmcOffloadDoFullPowerCallbacks(tpAniSirGlobal pMac, tANI_U32 sessionId, + eHalStatus status) +{ + tListElem *pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + tpPmcOffloadReqFullPowerEntry pReqFullPwrEntry; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadDoFullPowerCallbacks")); + + /* Call the routines in the request full power callback routine list. */ + pEntry = csrLLRemoveHead(&pmc->fullPowerCbList, TRUE); + while(pEntry) + { + pReqFullPwrEntry = + GET_BASE_ADDR(pEntry, tPmcOffloadReqFullPowerEntry, link); + + if(pReqFullPwrEntry->fullPwrCb) + pReqFullPwrEntry->fullPwrCb(pReqFullPwrEntry->callbackContext, + sessionId, status); + vos_mem_free(pReqFullPwrEntry); + pEntry = csrLLRemoveHead(&pmc->fullPowerCbList, TRUE); + } +} + +void pmcOffloadDoDeviceStateUpdateCallbacks (tpAniSirGlobal pMac, + tANI_U32 sessionId, tPmcState state) +{ + tListElem *pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + tpPmcOffloadDevStateUpdIndEntry pDeviceStateUpdateIndEntry; + + smsLog(pMac, LOG2, FL("PMC - Update registered modules of new device " + "state: %s"), pmcGetPmcStateStr(state)); + + /* Call the routines in the update device state routine list. */ + pEntry = csrLLPeekHead(&pmc->deviceStateUpdateIndList, FALSE); + while(pEntry) + { + pDeviceStateUpdateIndEntry = + GET_BASE_ADDR(pEntry, tPmcOffloadDevStateUpdIndEntry, link); + + pDeviceStateUpdateIndEntry->stateChangeCb( + pDeviceStateUpdateIndEntry->callbackContext, + sessionId, state); + pEntry = csrLLNext(&pmc->deviceStateUpdateIndList, pEntry, FALSE); + } +} + +void pmcOffloadDoStartUapsdCallbacks(tpAniSirGlobal pMac, tANI_U32 sessionId, + eHalStatus status) +{ + tListElem *pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + tpPmcOffloadStartUapsdEntry pStartUapsdEntry; + + smsLog(pMac, LOG2, "PMC: entering pmcOffloadDoStartUapsdCallbacks"); + + csrLLLock(&pmc->uapsdCbList); + /* Call the routines in the request start UAPSD callback routine list. */ + pEntry = csrLLRemoveHead(&pmc->uapsdCbList, FALSE); + while(pEntry) + { + pStartUapsdEntry = GET_BASE_ADDR(pEntry, tPmcOffloadStartUapsdEntry, link); + pStartUapsdEntry->uapsdStartInd(pStartUapsdEntry->callbackContext, + pStartUapsdEntry->sessionId, status); + vos_mem_free(pStartUapsdEntry); + pEntry = csrLLRemoveHead(&pmc->uapsdCbList, FALSE); + } + csrLLUnlock(&pmc->uapsdCbList); +} + +tANI_BOOLEAN pmcOffloadPowerSaveCheck(tHalHandle hHal, + tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPmcOffloadPsCheckEntry pPowerSaveCheckEntry; + PwrSaveCheckRoutine checkRoutine = NULL; + tANI_BOOLEAN bResult=TRUE; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadPowerSaveCheck")); + + /* + * Call the routines in the power save check routine list. + * If any return FALSE, then we cannot go into power save mode. + */ + pEntry = csrLLPeekHead(&pmc->pwrsaveCheckList, FALSE); + while(pEntry) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPmcOffloadPsCheckEntry, + link); + checkRoutine = pPowerSaveCheckEntry->pwrsaveCheckCb; + /* + * If the checkRoutine is NULL for a paricular entry, + * proceed with other entries + * in the list + */ + if(checkRoutine) + { + if (!checkRoutine(pPowerSaveCheckEntry->checkContext, sessionId)) + { + smsLog(pMac, LOGE, FL("pmcOffloadPowerSaveCheck fail!")); + bResult = FALSE; + break; + } + } + pEntry = csrLLNext(&pmc->pwrsaveCheckList, pEntry, FALSE); + } + return bResult; +} + +/* + * This API checks whether it is ok to enable sta mode power save. + * Pre Condition for enabling sta mode power save + * 1) Sta Mode Ps should be enabled in ini file. + * 2) Session should be in infra mode and in connected state. + * 3) Ps State should be in full power + * 4) Modules registered with PMC Offload should vote + * for power save enabling. + */ +eHalStatus pmcOffloadEnableStaPsCheck(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + /* Check if Sta Ps is enabled. */ + if(!pMac->pmcOffloadInfo.staPsEnabled) + { + smsLog(pMac, LOG1, "PMC: Cannot initiate BMPS. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check whether the give session is Infra and in Connected State */ + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOG1, "PMC:Sta not infra/connected state %d", sessionId); + return eHAL_STATUS_FAILURE; + } + + /* Check whether the PMC Offload state is in Full Power or not */ + if(FULL_POWER != pMac->pmcOffloadInfo.pmc[sessionId].pmcState) + { + smsLog(pMac, LOG1, + "PMC: Device not in full power. Cannot request BMPS. pmcState %d", + pMac->pmcOffloadInfo.pmc[sessionId].pmcState); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_TDLS + if (pMac->pmcOffloadInfo.pmc[sessionId].isTdlsPowerSaveProhibited) + { + smsLog(pMac, LOG1, + "Dont enter BMPS.TDLS session active on session %d", sessionId); + return eHAL_STATUS_FAILURE; + } +#endif + + /* Check that entry into a power save mode is allowed at this time. */ + if(!pmcOffloadPowerSaveCheck(pMac, sessionId)) + { + smsLog(pMac, LOG1, + "PMC: Power save check failed. BMPS cannot be entered now"); + return eHAL_STATUS_PMC_NOT_NOW; + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadStartAutoStaPsTimer (tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U32 timerValue) +{ + VOS_STATUS vosStatus; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Entering pmcOffloadStartAutoStaPsTimer")); + + vosStatus = vos_timer_start(&pmc->autoPsEnableTimer, + timerValue); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + if(VOS_STATUS_E_ALREADY == vosStatus) + { + /* Consider this ok since the timer is already started */ + smsLog(pMac, LOGW, + FL("pmcOffloadStartAutoStaPsTimer is already started")); + } + else + { + smsLog(pMac, LOGP, + FL("Cannot start pmcOffloadStartAutoStaPsTimer")); + return eHAL_STATUS_FAILURE; + } + } + return eHAL_STATUS_SUCCESS; +} + +void pmcOffloadStopAutoStaPsTimer(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + /* + * Stop the auto ps entry timer if runnin + */ + if(VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pmc->autoPsEnableTimer)) + { + vos_timer_stop(&pmc->autoPsEnableTimer); + } +} + +eHalStatus pmcOffloadQueueStartUapsdRequest(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + switch(pmc->pmcState) + { + case FULL_POWER: + case REQUEST_BMPS: + pmc->uapsdSessionRequired = TRUE; + break; + case BMPS: + if(pmc->uapsdSessionRequired) + { + smsLog(pMac, LOGE, + FL("Uapsd is already pending")); + break; + } + /* Request to Enable Sta Mode Power Save */ + if(pmcIssueCommand(pMac, sessionId, eSmeCommandEnterUapsd, + NULL, 0, FALSE) == eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOG2, + FL("eSmeCommandEnterUapsd issue successfully")); + break; + } + else + { + /* Fail to issue eSmeCommandEnterUapsd */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandEnterUapsd")); + return eHAL_STATUS_FAILURE; + } + default: + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_PMC_PENDING; +} + +eHalStatus pmcOffloadQueueStopUapsdRequest(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + switch(pmc->pmcState) + { + case REQUEST_STOP_UAPSD: + break; + case UAPSD: + /* Queue the Stop UAPSD Request */ + if(pmcIssueCommand(pMac, sessionId, eSmeCommandExitUapsd, + NULL, 0, FALSE) == eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOG2, + FL("eSmeCommandExitUapsd issue successfully")); + break; + } + else + { + /* + * Fail to issue eSmeCommandExitUapsd + * just fall through to restart the timer + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandExitUapsd")); + return eHAL_STATUS_FAILURE; + } + default: + pmc->uapsdSessionRequired = FALSE; + smsLog(pMac, LOG2, + "PMC: trying to enter Req Stop UAPSD State from state %d", + pmc->pmcState); + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadQueueRequestFullPower (tpAniSirGlobal pMac, + tANI_U32 sessionId, tRequestFullPowerReason fullPowerReason) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + tExitBmpsInfo exitBmpsInfo; + + if(FULL_POWER == pmc->pmcState) + { + smsLog(pMac, LOG2, + FL("Already in Full Power")); + return eHAL_STATUS_SUCCESS; + } + + exitBmpsInfo.exitBmpsReason = fullPowerReason; + + /* Queue Full Power Request */ + if(pmcIssueCommand(pMac, sessionId, eSmeCommandExitBmps, &exitBmpsInfo, + sizeof(tExitBmpsInfo), FALSE) == eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOG2, + FL("eSmeCommandExitBmps issue successfully")); + pmc->fullPowerReqPend = TRUE; + } + else + { + /* + * Fail to issue eSmeCommandExitBmps + */ + pmc->fullPowerReqPend = FALSE; + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandExitBmps")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_PMC_PENDING; +} + +eHalStatus pmcOffloadEnableStaPsHandler(tpAniSirGlobal pMac, + tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + VOS_STATUS vosStatus; + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadEnableStaPsHandler")); + + status = pmcOffloadEnableStaPsCheck(pMac, sessionId); + + switch(status) + { + case eHAL_STATUS_SUCCESS: + /* Request to Enable Sta Mode Power Save */ + if(pmcIssueCommand(pMac, sessionId, eSmeCommandEnterBmps, + NULL, 0, FALSE) == eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOG2, + FL("eSmeCommandEnterBmps issue successfully")); + break; + } + else + { + /* + * Fail to issue eSmeCommandEnterBmps + * just fall through to restart the timer + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandEnterBmps")); + } + case eHAL_STATUS_PMC_NOT_NOW: + /* + * Some module voted against Power Save. + * Restart the Auto Ps Entry Timer + */ + smsLog(pMac, LOGE, + FL("Power Save check failed. Retry Enable Sta Ps later")); + vosStatus = vos_timer_start(&pmc->autoPsEnableTimer, + pmc->autoPsEntryTimerPeriod); + if (!VOS_IS_STATUS_SUCCESS(vosStatus) && + (VOS_STATUS_E_ALREADY != vosStatus)) + { + smsLog(pMac, LOGP, FL("Cannot start traffic timer")); + return eHAL_STATUS_FAILURE; + } + break; + + default: + break; + } + return status; +} + +eHalStatus pmcOffloadDisableStaPsHandler(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadDisableStaPsHandler")); + + /* + * Clear the master flag so that + * further enable request will not be + * honored + */ + pmc->configStaPsEnabled = FALSE; + + /* + * Check whether the give session is Infra and in Connected State + * This is case where Session is already disconnected + */ + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + /* + * Stop the auto ps entry timer if running + */ + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + smsLog(pMac, LOG2, "PMC:Sta not infra/connected state %d", sessionId); + return eHAL_STATUS_SUCCESS; + } + + switch(pmc->pmcState) + { + case REQUEST_FULL_POWER: + case FULL_POWER: + /* + * Stop the auto ps entry timer if running + */ + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + break; + + case REQUEST_BMPS: + case BMPS: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case UAPSD: + if(eHAL_STATUS_FAILURE == + pmcOffloadQueueRequestFullPower(pMac, sessionId, + eSME_BMPS_MODE_DISABLED)) + { + /* + * Fail to issue eSmeCommandExitBmps + */ + smsLog(pMac, LOGW, FL("Fail to issue eSmeCommandExitBmps")); + return eHAL_STATUS_FAILURE; + } + break; + + default: + smsLog(pMac, LOGW, + FL("Invalid pmcState State %x"), pmc->pmcState); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + +void pmcOffloadAutoPsEntryTimerExpired(void *pmcInfo) +{ + tpPsOffloadPerSessionInfo pmc = (tpPsOffloadPerSessionInfo)pmcInfo; + tpAniSirGlobal pMac = pmc->pMac; + + smsLog(pMac, LOG2, FL("Auto PS timer expired")); + + if(eHAL_STATUS_FAILURE == pmcOffloadEnableStaPsHandler(pMac, + pmc->sessionId)) + { + smsLog(pMac, LOGE, FL("Auto PS timer expired in wrong state")); + } +} + +eHalStatus pmcOffloadEnterPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + /* + * Sta Power Save is successfully Enabled + * 1)If Req for full power is pending then + * Queue the Full power Req + * Else + * Queue uapsd req if pending + * 2) Change PS State + * PMC_POWER_SAVE if uapsd is not enabled + * PMC_POWER_SAVE_UAPSD if uapsd is already enabled + */ + if(PMC_UAPSD_ENABLE_PENDING == pmc->uapsdStatus) + { + pmc->pmcState = UAPSD; + pmc->uapsdStatus = PMC_UAPSD_ENABLED; + /* Call registered uapsd cbs */ + pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, eHAL_STATUS_SUCCESS); + } + else + { + pmc->uapsdStatus = PMC_UAPSD_DISABLED; + if (pmc->pmcState == UAPSD) + pmc->uapsdSessionRequired = FALSE; + + pmc->pmcState = BMPS; + } + + /* Indicate Device State Change Indication */ + pmcOffloadDoDeviceStateUpdateCallbacks(pMac, sessionId, pmc->pmcState); + + if(pmc->fullPowerReqPend) + { + if(eHAL_STATUS_FAILURE == + pmcOffloadQueueRequestFullPower(pMac, sessionId, + eSME_REASON_OTHER)) + { + /* + * Fail to issue eSmeCommandExitBmps + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandExitBmps")); + + /* Call registered callbacks with failure */ + pmcOffloadDoFullPowerCallbacks(pMac, sessionId, + eHAL_STATUS_FAILURE); + } + } + else if((UAPSD != pmc->pmcState) && pmc->uapsdSessionRequired) + { + if(eHAL_STATUS_FAILURE == + pmcOffloadQueueStartUapsdRequest(pMac, sessionId)) + { + pmc->uapsdSessionRequired = FALSE; + /* + * Fail to issue eSmeCommandEnterUapsd + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandEnterUapsd")); + + /* Call uapsd Cbs with failure */ + pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, + eHAL_STATUS_FAILURE); + } + } + else + { + smsLog(pMac, LOG2, FL("Stay in Power Save State")); + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadExitPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + /* + * Sta Power Save is successfully Disabled + * 1) Set the PS State to Full Power + * 2) Indicate State Change + * 3) Start Auto Ps Entry Timer + * We can try to Queue the ps request + * then we can start the timer if any module + * votes against ps + */ + pmc->pmcState = FULL_POWER; + pmc->fullPowerReqPend = FALSE; + + if(PMC_UAPSD_DISABLE_PENDING == pmc->uapsdStatus) + { + pmc->uapsdStatus = PMC_UAPSD_DISABLED; + } + + /* Indicate Device State Change Indication */ + pmcOffloadDoDeviceStateUpdateCallbacks(pMac, sessionId, pmc->pmcState); + + /* Call Full Power Req Cbs */ + pmcOffloadDoFullPowerCallbacks(pMac, sessionId, eHAL_STATUS_SUCCESS); + + if (pmc->configStaPsEnabled || pmc->configDefStaPsEnabled) + pmcOffloadStartAutoStaPsTimer(pMac, sessionId, + pmc->autoPsEntryTimerPeriod); + else + smsLog(pMac, LOGE, FL("Master Sta Ps Disabled")); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadEnterUapsdState(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, "PMC: entering pmcOffloadEnterUapsdState"); + + /* Can enter UAPSD State only from Request UAPSD State. */ + if(REQUEST_START_UAPSD != pmc->pmcState) + { + smsLog(pMac, LOGE, "PMC: trying to enter UAPSD State from state %d", + pmc->pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change the State */ + pmc->pmcState = UAPSD; + + /* Call the State Chnage Indication through Registered Cbs */ + pmcOffloadDoDeviceStateUpdateCallbacks(pMac, sessionId, UAPSD); + + /* Call the registered uapsd cbs */ + pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, eHAL_STATUS_SUCCESS); + + if(pmc->fullPowerReqPend) + { + if(eHAL_STATUS_FAILURE == pmcOffloadQueueRequestFullPower(pMac, + sessionId, eSME_REASON_OTHER)) + { + /* + * Fail to issue eSmeCommandExitBmps + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandExitBmps")); + + /* Call registered callbacks with failure */ + pmcOffloadDoFullPowerCallbacks(pMac, sessionId, + eHAL_STATUS_FAILURE); + } + } + return eHAL_STATUS_SUCCESS; +} + +void pmcOffloadExitBmpsIndHandler(tpAniSirGlobal pMac, tSirSmeRsp *pMsg) +{ + tpSirSmeExitBmpsInd pExitBmpsInd = (tpSirSmeExitBmpsInd)pMsg; + /* Enter Full Power State. */ + if (pExitBmpsInd->statusCode != eSIR_SME_SUCCESS) + { + smsLog(pMac, LOGP, + FL("Exit BMPS indication indicates failure, status %x"), + pMsg->statusCode); + } + else + { + smsLog(pMac, LOG1, + FL("Exit BMPS indication on session %u, reason %d"), + pExitBmpsInd->smeSessionId, pExitBmpsInd->exitBmpsReason); + pmcOffloadQueueRequestFullPower(pMac, pExitBmpsInd->smeSessionId, + pExitBmpsInd->exitBmpsReason); + } +} + +void pmcOffloadProcessResponse(tpAniSirGlobal pMac, tSirSmeRsp *pMsg) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + tpPsOffloadPerSessionInfo pmc = NULL; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + + smsLog(pMac, LOG2, FL("process message = %d"), pMsg->messageType); + + /* Process each different type of message. */ + switch(pMsg->messageType) + { + case eWNI_PMC_ENTER_BMPS_RSP: + smsLog(pMac, LOG2, + FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP with status = %d"), + pMsg->statusCode); + + if(eSmeCommandEnterBmps != pCommand->command) + { + smsLog(pMac, LOGW, + FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP without request")); + + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + + /* Enter PS State if response indicates success. */ + if(eSIR_SME_SUCCESS == pMsg->statusCode) + { + pmcOffloadEnterPowersaveState(pMac, pCommand->sessionId); + } + else + { + pmcOffloadExitPowersaveState(pMac, pCommand->sessionId); + } + break; + + case eWNI_PMC_EXIT_BMPS_RSP: + smsLog(pMac, LOG2, + FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP with status = %d"), + pMsg->statusCode); + + if(eSmeCommandExitBmps != pCommand->command) + { + smsLog(pMac, LOGW, + FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP without req")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + + /* Enter Full Power State if response indicates success. */ + if(eSIR_SME_SUCCESS == pMsg->statusCode) + { + pmcOffloadExitPowersaveState(pMac, pCommand->sessionId); + } + else + { + pmc = &pMac->pmcOffloadInfo.pmc[pCommand->sessionId]; + pmc->fullPowerReqPend = FALSE; + + /* Indicate Full Power Req Failure */ + pmcOffloadDoFullPowerCallbacks(pMac, pCommand->sessionId, + eHAL_STATUS_FAILURE); + pmcOffloadEnterPowersaveState(pMac, pCommand->sessionId); + } + break; + + case eWNI_PMC_ENTER_UAPSD_RSP: + smsLog(pMac, LOG2, + FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP with status = %d"), + pMsg->statusCode); + if(eSmeCommandEnterUapsd != pCommand->command) + { + smsLog(pMac, LOGW, + FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + + pmc = &pMac->pmcOffloadInfo.pmc[pCommand->sessionId]; + + /* Check that we are in the correct state for this message. */ + if(REQUEST_START_UAPSD != pmc->pmcState) + { + smsLog(pMac, LOGE, + FL("Got Enter Uapsd rsp Message while in state %d"), + pmc->pmcState); + break; + } + + /* Enter uapsd State if response indicates success. */ + if(eSIR_SME_SUCCESS == pMsg->statusCode) + { + pmcOffloadEnterUapsdState(pMac, pCommand->sessionId); + } + else + { + smsLog(pMac, LOGE, FL("Got Enter Uapsd rsp Failed")); + pmc->uapsdSessionRequired = FALSE; + /* Indicate Failure through registered cbs */ + pmcOffloadDoStartUapsdCallbacks(pMac, pCommand->sessionId, + eHAL_STATUS_FAILURE); + pmcOffloadEnterPowersaveState(pMac, pCommand->sessionId); + } + break; + + case eWNI_PMC_EXIT_UAPSD_RSP: + smsLog(pMac, LOG2, + FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP with status = %d"), + pMsg->statusCode); + if(eSmeCommandExitUapsd != pCommand->command) + { + smsLog(pMac, LOGW, + FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP without req")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + + /* Enter Full Power State if response indicates success. */ + if(pMsg->statusCode != eSIR_SME_SUCCESS) + { + smsLog(pMac, LOGE, + FL("eWNI_PMC_EXIT_UAPSD_RSP Failed SessionId %d"), + pCommand->sessionId); + } + + /* Move to BMPS State irrespective of Status */ + pmcOffloadEnterPowersaveState(pMac, pCommand->sessionId); + break; + + default: + smsLog(pMac, LOGE, + FL("Invalid message type %d received"), pMsg->messageType); + break; + } + + if(fRemoveCommand) + { + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, pEntry, + LL_ACCESS_LOCK)) + { + pmcReleaseCommand(pMac, pCommand ); + smeProcessPendingQueue(pMac); + } + } + } + else + { + smsLog(pMac, LOGE, + FL("message type %d received but no request is found"), + pMsg->messageType); + } +} + +void pmcOffloadAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tANI_BOOLEAN fStopping ) +{ + if(eSmePmcCommandMask & pCommand->command) + { + if( !fStopping ) + { + tpPsOffloadPerSessionInfo pmc = + &pMac->pmcOffloadInfo.pmc[pCommand->sessionId]; + switch( pCommand->command ) + { + case eSmeCommandEnterBmps: + smsLog(pMac, LOGE, FL("aborting request to enter BMPS ")); + pmcOffloadExitPowersaveState(pMac, pCommand->sessionId); + break; + + case eSmeCommandExitBmps: + smsLog(pMac, LOGE, FL("aborting request to exit BMPS ")); + pmcOffloadEnterPowersaveState(pMac, pCommand->sessionId); + break; + + case eSmeCommandEnterUapsd: + smsLog(pMac, LOGE, FL("aborting request to enter UAPSD ")); + /* + * Since there is no retry for UAPSD, + * tell the requester here we are done with failure + */ + pmc->uapsdSessionRequired = FALSE; + pmcOffloadDoStartUapsdCallbacks(pMac, pCommand->sessionId, + eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitUapsd: + smsLog(pMac, LOGE, FL("aborting request to exit UAPSD ")); + break; + + case eSmeCommandEnterWowl: + smsLog(pMac, LOGE, FL("aborting request to enter WOWL ")); + break; + + case eSmeCommandExitWowl: + smsLog(pMac, LOGE, FL("aborting request to exit WOWL ")); + break; + + default: + smsLog(pMac, LOGE, FL("Request for PMC command (%d) is dropped"), pCommand->command); + break; + } + }// !stopping + pmcReleaseCommand( pMac, pCommand ); + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcApi.c new file mode 100644 index 0000000000000..3633b543e4020 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcApi.c @@ -0,0 +1,4307 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmcApi.c +* +* Description: Routines that make up the Power Management Control (PMC) API. +* + +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "csrLinkList.h" +#include "smsDebug.h" +#include "pmcApi.h" +#include "pmc.h" +#include "cfgApi.h" +#include "smeInside.h" +#include "csrInsideApi.h" +#include "wlan_ps_wow_diag.h" +#include "wlan_qct_wda.h" +#include "limSessionUtils.h" +#include "csrInsideApi.h" +#include "sme_Api.h" + +extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); + +void pmcCloseDeferredMsgList(tpAniSirGlobal pMac); +void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac); +void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac); +void pmcCloseRequestBmpsList(tpAniSirGlobal pMac); +void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac); +void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac); + +/****************************************************************************** +* +* Name: pmcOpen +* +* Description: +* Does a PMC open operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - open successful +* eHAL_STATUS_FAILURE - open not successful +* +******************************************************************************/ +eHalStatus pmcOpen (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcOpen")); + + /* Initialize basic PMC information about device. */ + pMac->pmc.powerSource = BATTERY_POWER; + pMac->pmc.pmcState = STOPPED; + pMac->pmc.pmcReady = FALSE; + + /* Initialize Power Save Modes */ + pMac->pmc.impsEnabled = FALSE; + pMac->pmc.autoBmpsEntryEnabled = FALSE; + pMac->pmc.smpsEnabled = FALSE; + pMac->pmc.uapsdEnabled = TRUE; + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.standbyEnabled = TRUE; + pMac->pmc.wowlEnabled = TRUE; + + vos_mem_set(&(pMac->pmc.bmpsConfig), sizeof(tPmcBmpsConfigParams), 0); + vos_mem_set(&(pMac->pmc.impsConfig), sizeof(tPmcImpsConfigParams), 0); + vos_mem_set(&(pMac->pmc.smpsConfig), sizeof(tPmcSmpsConfigParams), 0); + + /* Allocate a timer to use with IMPS. */ + if (vos_timer_init(&pMac->pmc.hImpsTimer, VOS_TIMER_TYPE_SW, pmcImpsTimerExpired, hHal) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot allocate timer for IMPS")); + return eHAL_STATUS_FAILURE; + } + + /* Allocate a timer used in Full Power State to measure traffic + levels and determine when to enter BMPS. */ + if (!VOS_IS_STATUS_SUCCESS(vos_timer_init(&pMac->pmc.hTrafficTimer, + VOS_TIMER_TYPE_SW, pmcTrafficTimerExpired, hHal))) + { + pmcLog(pMac, LOGE, FL("Cannot allocate timer for traffic measurement")); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + /* Allocate a timer used to report current PMC state through periodic DIAG event */ + if (vos_timer_init(&pMac->pmc.hDiagEvtTimer, VOS_TIMER_TYPE_SW, pmcDiagEvtTimerExpired, hHal) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot allocate timer for diag event reporting")); + return eHAL_STATUS_FAILURE; + } +#endif + + //Initialize the default value for Bmps related config. + pMac->pmc.bmpsConfig.trafficMeasurePeriod = BMPS_TRAFFIC_TIMER_DEFAULT; + pMac->pmc.bmpsConfig.bmpsPeriod = WNI_CFG_LISTEN_INTERVAL_STADEF; + + /* Allocate a timer used to schedule a deferred power save mode exit. */ + if (vos_timer_init(&pMac->pmc.hExitPowerSaveTimer, VOS_TIMER_TYPE_SW, + pmcExitPowerSaveTimerExpired, hHal) !=VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot allocate exit power save mode timer")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for power save check routines and request full power callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.powerSaveCheckList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize power save check routine list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestFullPowerList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize request full power callback routine list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for request BMPS callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestBmpsList) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize request BMPS callback routine list"); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for request start UAPSD callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestStartUapsdList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize request start UAPSD callback routine list"); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for device state update indication callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.deviceStateUpdateIndList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize device state update indication callback list"); + return eHAL_STATUS_FAILURE; + } + + if (csrLLOpen(pMac->hHdd, &pMac->pmc.deferredMsgList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize deferred msg list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStart +* +* Description: +* Does a PMC start operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - start successful +* eHAL_STATUS_FAILURE - start not successful +* +******************************************************************************/ +eHalStatus pmcStart (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + + pmcLog(pMac, LOG2, FL("Entering pmcStart")); + + /* Initialize basic PMC information about device. */ + pMac->pmc.pmcState = FULL_POWER; + pMac->pmc.requestFullPowerPending = FALSE; + pMac->pmc.uapsdSessionRequired = FALSE; + pMac->pmc.wowlModeRequired = FALSE; + pMac->pmc.bmpsRequestedByHdd = FALSE; + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + pMac->pmc.remainInPowerActiveThreshold = 0; + + /* WLAN Switch initial states. */ + pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_ON; + pMac->pmc.swWlanSwitchState = ePMC_SWITCH_ON; + + /* No IMPS callback routine yet. */ + pMac->pmc.impsCallbackRoutine = NULL; + + /* No STANDBY callback routine yet. */ + pMac->pmc.standbyCallbackRoutine = NULL; + + /* No WOWL callback routine yet. */ + pMac->pmc.enterWowlCallbackRoutine = NULL; + + /* Initialize BMPS traffic counts. */ + pMac->pmc.cLastTxUnicastFrames = 0; + pMac->pmc.cLastRxUnicastFrames = 0; + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pMac->pmc.ImpsReqFailCnt = 0; + pMac->pmc.ImpsReqTimerFailed = 0; + pMac->pmc.ImpsReqTimerfailCnt = 0; + + /* Configure SMPS. */ + if (pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc)) + { + if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC; + if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC; + } + else + htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT; + + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + if (pmcStartDiagEvtTimer(hHal) != eHAL_STATUS_SUCCESS) + { + return eHAL_STATUS_FAILURE; + } +#endif + +#if defined(ANI_LOGDUMP) + pmcDumpInit(hHal); +#endif + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStop +* +* Description: +* Does a PMC stop operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - stop successful +* eHAL_STATUS_FAILURE - stop not successful +* +******************************************************************************/ +eHalStatus pmcStop (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tPmcDeferredMsg *pDeferredMsg; + + pmcLog(pMac, LOG2, FL("Entering pmcStop")); + + /* Cancel any running timers. */ + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + } + + pmcStopTrafficTimer(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + pmcStopDiagEvtTimer(hHal); +#endif + + if (vos_timer_stop(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel exit power save mode timer")); + } + + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_FAILURE); + pmcDoBmpsCallbacks(hHal, eHAL_STATUS_FAILURE); + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(hHal, eHAL_STATUS_FAILURE); + pmcDoStandbyCallbacks(hHal, eHAL_STATUS_FAILURE); + + //purge the deferred msg list + csrLLLock( &pMac->pmc.deferredMsgList ); + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->pmc.deferredMsgList, eANI_BOOLEAN_FALSE ) ) ) + { + pDeferredMsg = GET_BASE_ADDR( pEntry, tPmcDeferredMsg, link ); + vos_mem_free(pDeferredMsg); + } + csrLLUnlock( &pMac->pmc.deferredMsgList ); + + /* PMC is stopped. */ + pMac->pmc.pmcState = STOPPED; + pMac->pmc.pmcReady = FALSE; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcClose +* +* Description: +* Does a PMC close operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - close successful +* eHAL_STATUS_FAILURE - close not successful +* +******************************************************************************/ +eHalStatus pmcClose (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcClose")); + + /* Free up allocated resources. */ + if (vos_timer_destroy(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate IMPS timer")); + } + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pMac->pmc.hTrafficTimer))) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate traffic timer")); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + if (vos_timer_destroy(&pMac->pmc.hDiagEvtTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate timer for diag event reporting")); + } +#endif + if (vos_timer_destroy(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate exit power save mode timer")); + } + + /* + The following list's entries are dynamically allocated so they need their own + cleanup function + */ + pmcClosePowerSaveCheckList(pMac); + pmcCloseRequestFullPowerList(pMac); + pmcCloseRequestBmpsList(pMac); + pmcCloseRequestStartUapsdList(pMac); + pmcCloseDeviceStateUpdateList(pMac); + pmcCloseDeferredMsgList(pMac); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcSetConfigPowerSave +* +* Description: +* Configures one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to configure +* pConfigParams - pointer to configuration parameters specific to the +* power saving mode +* +* Returns: +* eHAL_STATUS_SUCCESS - configuration successful +* eHAL_STATUS_FAILURE - configuration not successful +* +******************************************************************************/ +eHalStatus pmcSetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcSetConfigPowerSave, power save mode %d"), psMode); + + /* Configure the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsConfig = *(tpPmcImpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("IMPS configuration")); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.impsConfig.enterOnAc); + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsConfig = *(tpPmcBmpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("BMPS configuration")); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.bmpsConfig.enterOnAc); + pmcLog(pMac, LOG3, " TX threshold: %d", + pMac->pmc.bmpsConfig.txThreshold); + pmcLog(pMac, LOG3, " RX threshold: %d", + pMac->pmc.bmpsConfig.rxThreshold); + pmcLog(pMac, LOG3, " traffic measurement period (ms): %d", + pMac->pmc.bmpsConfig.trafficMeasurePeriod); + pmcLog(pMac, LOG3, " BMPS period: %d", + pMac->pmc.bmpsConfig.bmpsPeriod); + pmcLog(pMac, LOG3, " beacons to forward code: %d", + pMac->pmc.bmpsConfig.forwardBeacons); + pmcLog(pMac, LOG3, " value of N: %d", + pMac->pmc.bmpsConfig.valueOfN); + pmcLog(pMac, LOG3, " use PS poll: %d", + pMac->pmc.bmpsConfig.usePsPoll); + pmcLog(pMac, LOG3, " set PM on last frame: %d", + pMac->pmc.bmpsConfig.setPmOnLastFrame); + pmcLog(pMac, LOG3, " value of enableBeaconEarlyTermination: %d", + pMac->pmc.bmpsConfig.enableBeaconEarlyTermination); + pmcLog(pMac, LOG3, " value of bcnEarlyTermWakeInterval: %d", + pMac->pmc.bmpsConfig.bcnEarlyTermWakeInterval); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_BMPS_SET_CONFIG; + /* possible loss of data due to mismatch but expectation is that + values can reasonably be expected to fit in target widths */ + psRequest.bmps_auto_timer_duration = (v_U16_t)pMac->pmc.bmpsConfig.trafficMeasurePeriod; + psRequest.bmps_period = (v_U16_t)pMac->pmc.bmpsConfig.bmpsPeriod; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsConfig = *(tpPmcSmpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("SMPS configuration")); + pmcLog(pMac, LOG3, " mode: %d", pMac->pmc.smpsConfig.mode); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.smpsConfig.enterOnAc); + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + //Send the power save config down to PE/HAL/FW if BMPS mode is being configured + //and pmcReady has been invoked + if(PMC_IS_READY(pMac) && psMode == ePMC_BEACON_MODE_POWER_SAVE) + { + if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcGetConfigPowerSave +* +* Description: +* Get the config for the specified power save mode +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to configure +* pConfigParams - pointer to configuration parameters specific to the +* power saving mode +* +* Returns: +* eHAL_STATUS_SUCCESS - configuration successful +* eHAL_STATUS_FAILURE - configuration not successful +* +******************************************************************************/ +eHalStatus pmcGetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcGetConfigPowerSave, power save mode %d"), psMode); + + /* Configure the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + *(tpPmcImpsConfigParams)pConfigParams = pMac->pmc.impsConfig; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + *(tpPmcBmpsConfigParams)pConfigParams = pMac->pmc.bmpsConfig; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + *(tpPmcSmpsConfigParams)pConfigParams = pMac->pmc.smpsConfig; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +/****************************************************************************** +* +* Name: pmcEnablePowerSave +* +* Description: +* Enables one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to enable +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully enabled +* eHAL_STATUS_FAILURE - not successfully enabled +* +******************************************************************************/ +eHalStatus pmcEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_PS_MODE_ENABLE_REQ; + psRequest.enable_disable_powersave_mode = psMode; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcEnablePowerSave, power save mode %d"), psMode); + + /* Enable the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsEnabled = TRUE; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsEnabled = TRUE; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsEnabled = TRUE; + + /* If PMC already started, then turn on SMPS. */ + if (pMac->pmc.pmcState != STOPPED) + if (pMac->pmc.powerSource != AC_POWER || + pMac->pmc.smpsConfig.enterOnAc) + { + if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC; + if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + break; + + case ePMC_UAPSD_MODE_POWER_SAVE: + pMac->pmc.uapsdEnabled = TRUE; + break; + + case ePMC_STANDBY_MODE_POWER_SAVE: + pMac->pmc.standbyEnabled = TRUE; + break; + + case ePMC_WOWL_MODE_POWER_SAVE: + pMac->pmc.wowlEnabled = TRUE; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn pmcStartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcStartAutoBmpsTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_START_BMPS_AUTO_TIMER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcStartAutoBmpsTimer")); + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enable BMPS timer. BMPS is disabled"); + return eHAL_STATUS_FAILURE; + } + + pMac->pmc.autoBmpsEntryEnabled = TRUE; + + /* Check if there is an Infra session. If there is no Infra session, timer will be started + when STA associates to AP */ + + if (pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcStopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the pmcRequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcStopAutoBmpsTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_STOP_BMPS_AUTO_TIMER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcStopAutoBmpsTimer")); + + pMac->pmc.autoBmpsEntryEnabled = FALSE; + /* If uapsd session is not required or HDD has not requested BMPS, stop the auto bmps timer.*/ + if (!pMac->pmc.uapsdSessionRequired && !pMac->pmc.bmpsRequestedByHdd) + pmcStopTrafficTimer(hHal); + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDisablePowerSave +* +* Description: +* Disables one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to disable +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully disabled +* eHAL_STATUS_FAILURE - not successfully disabled +* +******************************************************************************/ +eHalStatus pmcDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_PS_MODE_DISABLE_REQ; + psRequest.enable_disable_powersave_mode = psMode; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcDisablePowerSave, power save mode %d"), psMode); + + /* Disable the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsEnabled = FALSE; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsEnabled = FALSE; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsEnabled = FALSE; + + /* Turn off SMPS. */ + htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + break; + + case ePMC_UAPSD_MODE_POWER_SAVE: + pMac->pmc.uapsdEnabled = FALSE; + break; + + case ePMC_STANDBY_MODE_POWER_SAVE: + pMac->pmc.standbyEnabled = FALSE; + break; + + case ePMC_WOWL_MODE_POWER_SAVE: + pMac->pmc.wowlEnabled = FALSE; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcQueryPowerState +* +* Description: +* Returns the current power state of the device. +* +* Parameters: +* hHal - HAL handle for device +* pPowerState - pointer to location to return power state +* pHwWlanSwitchState - pointer to location to return Hardware WLAN +* Switch state +* pSwWlanSwitchState - pointer to location to return Software WLAN +* Switch state +* +* Returns: +* eHAL_STATUS_SUCCESS - power state successfully returned +* eHAL_STATUS_FAILURE - power state not successfully returned +* +******************************************************************************/ +eHalStatus pmcQueryPowerState (tHalHandle hHal, tPmcPowerState *pPowerState, + tPmcSwitchState *pHwWlanSwitchState, tPmcSwitchState *pSwWlanSwitchState) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcQueryPowerState")); + + /* Return current power state based on PMC state. */ + if(pPowerState != NULL) + { + /* Return current power state based on PMC state. */ + switch (pMac->pmc.pmcState) + { + + case FULL_POWER: + *pPowerState = ePMC_FULL_POWER; + break; + + default: + *pPowerState = ePMC_LOW_POWER; + break; + } + } + + /* Return current switch settings. */ + if(pHwWlanSwitchState != NULL) + *pHwWlanSwitchState = pMac->pmc.hwWlanSwitchState; + if(pSwWlanSwitchState != NULL) + *pSwWlanSwitchState = pMac->pmc.swWlanSwitchState; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcIsPowerSaveEnabled +* +* Description: +* Checks if the device is able to enter one of the power save modes. +* "Able to enter" means the power save mode is enabled for the device +* and the host is using the correct power source for entry into the +* power save mode. This routine does not indicate whether the device +* is actually in the power save mode at a particular point in time. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode +* +* Returns: +* TRUE if device is able to enter the power save mode, FALSE otherwise +* +******************************************************************************/ +tANI_BOOLEAN pmcIsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcIsPowerSaveEnabled, power save mode %d"), psMode); + + /* Check ability to enter based on the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + return pMac->pmc.impsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.impsConfig.enterOnAc); + + case ePMC_BEACON_MODE_POWER_SAVE: + return pMac->pmc.bmpsEnabled; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + return pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc); + + case ePMC_UAPSD_MODE_POWER_SAVE: + return pMac->pmc.uapsdEnabled; + + case ePMC_STANDBY_MODE_POWER_SAVE: + return pMac->pmc.standbyEnabled; + + case ePMC_WOWL_MODE_POWER_SAVE: + return pMac->pmc.wowlEnabled; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return FALSE; + } +} + + +/****************************************************************************** +* +* Name: pmcRequestFullPower +* +* Description: +* Request that the device be brought to full power state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - routine to call when device actually achieves full +* power state if "eHAL_STATUS_PMC_PENDING" is returned +* callbackContext - value to be passed as parameter to routine specified +* above +* fullPowerReason - Reason for requesting full power mode. This is used +* by PE to decide whether data null should be sent to +* AP when exiting BMPS mode. Caller should use the +* eSME_LINK_DISCONNECTED reason if link is disconnected +* and there is no need to tell the AP that we are going +* out of power save. +* +* Returns: +* eHAL_STATUS_SUCCESS - device brought to full power state +* eHAL_STATUS_FAILURE - device cannot be brought to full power state +* eHAL_STATUS_PMC_PENDING - device is being brought to full power state, +* callbackRoutine will be called when completed +* +******************************************************************************/ +eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, tRequestFullPowerReason fullPowerReason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpRequestFullPowerEntry pEntry; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_ENTER_FULL_POWER_REQ; + psRequest.full_power_request_reason = fullPowerReason; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcRequestFullPower")); + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting Full Power when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* If HDD is requesting full power, clear any buffered requests for WOWL and BMPS that were + requested by HDD previously */ + if(SIR_IS_FULL_POWER_NEEDED_BY_HDD(fullPowerReason)) + { + pMac->pmc.bmpsRequestedByHdd = FALSE; + pMac->pmc.wowlModeRequired = FALSE; + } + + /* If already in full power, just return. */ + if (pMac->pmc.pmcState == FULL_POWER) + return eHAL_STATUS_SUCCESS; + + /* If in IMPS State, then cancel the timer. */ + if (pMac->pmc.pmcState == IMPS) + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + } + /* Enter Request Full Power State. */ + if (pmcEnterRequestFullPowerState(hHal, fullPowerReason) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + /* If able to enter Request Full Power State, then request is pending. + Allocate entry for request full power callback routine list. */ + //If caller doesn't need a callback, simply waits up the chip. + if( callbackRoutine ) + { + pEntry = vos_mem_malloc(sizeof(tRequestFullPowerEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, + FL("Cannot allocate memory for request full power routine list entry")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestFullPowerList, &pEntry->link, TRUE); + } + + return eHAL_STATUS_PMC_PENDING; +} + + +/****************************************************************************** +* +* Name: pmcRequestImps +* +* Description: +* Request that the device be placed in Idle Mode Power Save (IMPS). +* The Common Scan/Roam Module makes this request. The device will be +* placed into IMPS for the specified amount of time, and then returned +* to full power. +* +* Parameters: +* hHal - HAL handle for device +* impsPeriod - amount of time to remain in IMPS (milliseconds) +* callbackRoutine - routine to call when IMPS period has finished and +* the device has been brought to full power +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device will enter IMPS +* eHAL_STATUS_PMC_DISABLED - IMPS is disabled +* eHAL_STATUS_PMC_NOT_NOW - another module is prohibiting entering IMPS +* at this time +* eHAL_STATUS_PMC_AC_POWER - IMPS is disabled when host operating from +* AC power +* eHAL_STATUS_PMC_ALREADY_IN_IMPS - device is already in IMPS +* eHAL_STATUS_PMC_SYS_ERROR - system error that prohibits entering IMPS +* +******************************************************************************/ +eHalStatus pmcRequestImps (tHalHandle hHal, tANI_U32 impsPeriod, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_IMPS_ENTER_REQ; + psRequest.imps_period = impsPeriod; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + + pmcLog(pMac, LOG2, FL("Entering pmcRequestImps")); + + status = pmcEnterImpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Enter Request IMPS State. */ + status = pmcEnterRequestImpsState( hHal ); + if (HAL_STATUS_SUCCESS( status )) + { + /* Save the period and callback routine for when we need it. */ + pMac->pmc.impsPeriod = impsPeriod; + pMac->pmc.impsCallbackRoutine = callbackRoutine; + pMac->pmc.impsCallbackContext = callbackContext; + + } + else + { + status = eHAL_STATUS_PMC_SYS_ERROR; + } + } + + return status; +} + + +/****************************************************************************** +* +* Name: pmcRegisterPowerSaveCheck +* +* Description: +* Allows a routine to be registered so that the routine is called whenever +* the device is about to enter one of the power save modes. This routine +* will say whether the device is allowed to enter the power save mode at +* the time of the call. +* +* Parameters: +* hHal - HAL handle for device +* checkRoutine - routine to call before entering a power save mode, should +* return TRUE if the device is allowed to enter the power +* save mode, FALSE otherwise +* checkContext - value to be passed as parameter to routine specified above +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully registered +* eHAL_STATUS_FAILURE - not successfully registered +* +******************************************************************************/ +eHalStatus pmcRegisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext), + void *checkContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPowerSaveCheckEntry pEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcRegisterPowerSaveCheck")); + + /* Allocate entry for power save check routine list. */ + pEntry = vos_mem_malloc(sizeof(tPowerSaveCheckEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for power save check routine list entry")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->checkRoutine = checkRoutine; + pEntry->checkContext = checkContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.powerSaveCheckList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcDeregisterPowerSaveCheck +* +* Description: +* Reregisters a routine that was previously registered with +* pmcRegisterPowerSaveCheck. +* +* Parameters: +* hHal - HAL handle for device +* checkRoutine - routine to deregister +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully deregistered +* eHAL_STATUS_FAILURE - not successfully deregistered +* +******************************************************************************/ +eHalStatus pmcDeregisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext)) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcDeregisterPowerSaveCheck")); + + /* Find entry in the power save check routine list that matches + the specified routine and remove it. */ + pEntry = csrLLPeekHead(&pMac->pmc.powerSaveCheckList, FALSE); + while (pEntry != NULL) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + if (pPowerSaveCheckEntry->checkRoutine == checkRoutine) + { + if (csrLLRemoveEntry(&pMac->pmc.powerSaveCheckList, pEntry, FALSE)) + { + vos_mem_free(pPowerSaveCheckEntry); + } + else + { + pmcLog(pMac, LOGE, FL("Cannot remove power save check routine list entry")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pMac->pmc.powerSaveCheckList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + + +static void pmcProcessResponse( tpAniSirGlobal pMac, tSirSmeRsp *pMsg ) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + + pmcLog(pMac, LOG2, FL("process message = %d"), pMsg->messageType); + + /* Process each different type of message. */ + switch (pMsg->messageType) + { + + /* We got a response to our IMPS request. */ + case eWNI_PMC_ENTER_IMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP with status = %d"), pMsg->statusCode); + if( (eSmeCommandEnterImps != pCommand->command) && (eSmeCommandEnterStandby != pCommand->command) ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + if(pMac->pmc.pmcState == REQUEST_IMPS) + { + /* Enter IMPS State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pmcEnterImpsState(pMac); + if (!(pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed) && pMac->pmc.ImpsReqFailCnt) + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter IMPS was failed %d times before success"), + pMac->pmc.ImpsReqFailCnt); + pMac->pmc.ImpsReqFailCnt = 0; + } + } + + /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into IMPS. */ + else + { + pMac->pmc.ImpsReqFailed = VOS_TRUE; + if (!(pMac->pmc.ImpsReqFailCnt & 0xF)) + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter IMPS indicates failure, status %x, FailCnt - %d"), + pMsg->statusCode, ++pMac->pmc.ImpsReqFailCnt); + } + else + { + pMac->pmc.ImpsReqFailCnt++; + } + pmcEnterFullPowerState(pMac); + } + } + else if (pMac->pmc.pmcState == REQUEST_STANDBY) + { + /* Enter STANDBY State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterStandbyState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + + /* If response is failure, then we stay in Full Power State + and tell everyone that we aren't going into STANDBY. */ + else + { + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "standby indicates failure, status %x", pMsg->statusCode); + pmcEnterFullPowerState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + else + { + pmcLog(pMac, LOGE, "PMC: Enter IMPS rsp rcvd when device is " + "in %d state", pMac->pmc.pmcState); + } + break; + + /* We got a response to our wake from IMPS request. */ + case eWNI_PMC_EXIT_IMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitImps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Got Exit IMPS Response Message while " + "in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Response message to request to exit " + "IMPS indicates failure, status %x"), pMsg->statusCode); + } + pmcEnterFullPowerState(pMac); + break; + + /* We got a response to our BMPS request. */ + case eWNI_PMC_ENTER_BMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandEnterBmps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_BMPS) + { + pmcLog(pMac, LOGE, + FL("Got Enter BMPS Response Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterBmpsState(pMac); + /* Note: If BMPS was requested because of start UAPSD, + there will no entries for BMPS callback routines and + pmcDoBmpsCallbacks will be a No-Op*/ + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into BMPS. */ + else + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter BMPS indicates failure, status %x"), + pMsg->statusCode); + pmcEnterFullPowerState(pMac); + //Do not call UAPSD callback here since it may be re-entered + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + } + break; + + /* We got a response to our wake from BMPS request. */ + case eWNI_PMC_EXIT_BMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitBmps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_FULL_POWER) + { + pmcLog(pMac, LOGE, + FL("Got Exit BMPS Response Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGP, + FL("Response message to request to exit BMPS indicates failure, status %x"), + pMsg->statusCode); + } + pmcEnterFullPowerState(pMac); + break; + + /* We got a response to our Start UAPSD request. */ + case eWNI_PMC_ENTER_UAPSD_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandEnterUapsd != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_START_UAPSD) + { + pmcLog(pMac, LOGE, + FL("Got Enter Uapsd rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter UAPSD State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterUapsdState(pMac); + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + /* If response is failure, then we try to put the chip back in + BMPS mode*/ + else { + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "UAPSD indicates failure, status %x", pMsg->statusCode); + //Need to reset the UAPSD flag so pmcEnterBmpsState won't try to enter UAPSD. + pMac->pmc.uapsdSessionRequired = FALSE; + pmcEnterBmpsState(pMac); + //UAPSD will not be retied in this case so tell requester we are done with failure + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + } + break; + + /* We got a response to our Stop UAPSD request. */ + case eWNI_PMC_EXIT_UAPSD_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitUapsd != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_STOP_UAPSD) + { + pmcLog(pMac, LOGE, + FL("Got Exit Uapsd rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) { + pmcLog(pMac, LOGP, "PMC: response message to request to exit " + "UAPSD indicates failure, status %x", pMsg->statusCode); + } + pmcEnterBmpsState(pMac); + break; + + /* We got a response to our enter WOWL request. */ + case eWNI_PMC_ENTER_WOWL_RSP: + + if( eSmeCommandEnterWowl != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_WOWL_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_ENTER_WOWL) + { + pmcLog(pMac, LOGE, FL("Got eWNI_PMC_ENTER_WOWL_RSP while in state %s"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + break; + } + + /* Enter WOWL State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) { + pmcEnterWowlState(pMac); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + + /* If response is failure, then we try to put the chip back in + BMPS mode*/ + else { + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "WOWL indicates failure, status %x", pMsg->statusCode); + pmcEnterBmpsState(pMac); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + } + break; + + /* We got a response to our exit WOWL request. */ + case eWNI_PMC_EXIT_WOWL_RSP: + + if( eSmeCommandExitWowl != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_WOWL_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_EXIT_WOWL) + { + pmcLog(pMac, LOGE, FL("Got Exit WOWL rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) { + pmcLog(pMac, LOGP, "PMC: response message to request to exit " + "WOWL indicates failure, status %x", pMsg->statusCode); + } + pmcEnterBmpsState(pMac); + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid message type %d received"), pMsg->messageType); + PMC_ABORT; + break; + }//switch + + if( fRemoveCommand ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + smeProcessPendingQueue( pMac ); + } + } + } + else + { + pmcLog(pMac, LOGE, FL("message type %d received but no request is found"), pMsg->messageType); + } +} + + +/****************************************************************************** +* +* Name: pmcMessageProcessor +* +* Description: +* Process a message received by PMC. +* +* Parameters: +* hHal - HAL handle for device +* pMsg - pointer to received message +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcMessageProcessor (tHalHandle hHal, tSirSmeRsp *pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcMessageProcessor, message type %d"), pMsg->messageType); + + switch( pMsg->messageType ) + { + case eWNI_PMC_EXIT_BMPS_IND: + //When PMC needs to handle more indication from PE, they need to be added here. + { + /* Device left BMPS on its own. */ + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_IND with status = %d"), pMsg->statusCode); + /* Check that we are in the correct state for this message. */ + switch(pMac->pmc.pmcState) + { + case BMPS: + case REQUEST_START_UAPSD: + case UAPSD: + case REQUEST_STOP_UAPSD: + case REQUEST_ENTER_WOWL: + case WOWL: + case REQUEST_EXIT_WOWL: + case REQUEST_FULL_POWER: + pmcLog(pMac, LOGW, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState); + break; + default: + pmcLog(pMac, LOGE, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState); + PMC_ABORT; + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGP, FL("Exit BMPS indication indicates failure, status %x"), pMsg->statusCode); + } + else + { + tpSirSmeExitBmpsInd pExitBmpsInd = (tpSirSmeExitBmpsInd)pMsg; + pmcEnterRequestFullPowerState(hHal, pExitBmpsInd->exitBmpsReason); + } + break; + } + + default: + pmcProcessResponse( pMac, pMsg ); + break; + } + +} + + +tANI_BOOLEAN pmcValidateConnectState( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ( !csrIsInfraConnected( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: STA not associated. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + //Cannot have other session + if ( csrIsIBSSStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: IBSS started. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ( csrIsBTAMPStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: BT-AMP exists. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ((vos_concurrent_open_sessions_running()) && + (csrIsConcurrentInfraConnected( pMac ) || + (vos_get_concurrency_mode()& VOS_SAP) || + (vos_get_concurrency_mode()& VOS_P2P_GO))) + { + pmcLog(pMac, LOGW, "PMC: Multiple active sessions exists. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + return eANI_BOOLEAN_TRUE; +} + +tANI_BOOLEAN pmcAllowImps( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + //Cannot have other session like IBSS or BT AMP running + if ( csrIsIBSSStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: IBSS started. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ( csrIsBTAMPStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: BT-AMP exists. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + //All sessions must be disconnected to allow IMPS + if ( !csrIsAllSessionDisconnected( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: Atleast one connected session. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + return eANI_BOOLEAN_TRUE; +} + +/****************************************************************************** +* +* Name: pmcRequestBmps +* +* Description: +* Request that the device be put in BMPS state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - Callback routine invoked in case of success/failure +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device is in BMPS state +* eHAL_STATUS_FAILURE - device cannot be brought to BMPS state +* eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state, +* +******************************************************************************/ +eHalStatus pmcRequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpRequestBmpsEntry pEntry; + eHalStatus status; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_BMPS_ENTER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestBmps"); + + /* If already in BMPS, just return. */ + if (pMac->pmc.pmcState == BMPS || REQUEST_START_UAPSD == pMac->pmc.pmcState || UAPSD == pMac->pmc.pmcState) + { + pmcLog(pMac, LOG2, "PMC: Device already in BMPS pmcState %d", pMac->pmc.pmcState); + pMac->pmc.bmpsRequestedByHdd = TRUE; + return eHAL_STATUS_SUCCESS; + } + + status = pmcEnterBmpsCheck( pMac ); + if(HAL_STATUS_SUCCESS( status )) + { + status = pmcEnterRequestBmpsState(hHal); + /* Enter Request BMPS State. */ + if ( HAL_STATUS_SUCCESS( status ) ) + { + /* Remember that HDD requested BMPS. This flag will be used to put the + device back into BMPS if any module other than HDD (e.g. CSR, QoS, or BAP) + requests full power for any reason */ + pMac->pmc.bmpsRequestedByHdd = TRUE; + + /* If able to enter Request BMPS State, then request is pending. + Allocate entry for request BMPS callback routine list. */ + pEntry = vos_mem_malloc(sizeof(tRequestBmpsEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, "PMC: cannot allocate memory for request " + "BMPS routine list entry"); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestBmpsList, &pEntry->link, FALSE); + + status = eHAL_STATUS_PMC_PENDING; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + /* Retry to enter the BMPS if the + status = eHAL_STATUS_PMC_NOT_NOW */ + else if (status == eHAL_STATUS_PMC_NOT_NOW) + { + pmcStopTrafficTimer(hHal); + pmcLog(pMac, LOG1, FL("Can't enter BMPS+++")); + if (pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(pMac, + pMac->pmc.bmpsConfig.trafficMeasurePeriod) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOG1, FL("Cannot start BMPS Retry timer")); + } + pmcLog(pMac, LOG1, + FL("BMPS Retry Timer already running or started")); + } + } + + return status; +} + +/****************************************************************************** +* +* Name: pmcStartUapsd +* +* Description: +* Request that the device be put in UAPSD state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - Callback routine invoked in case of success/failure +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device is in UAPSD state +* eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state +* eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state +* eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled +* +******************************************************************************/ +eHalStatus pmcStartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpStartUapsdEntry pEntry; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_UAPSD_START_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcStartUapsd"); + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting UAPSD when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter UAPSD. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check if UAPSD is enabled. */ + if (!pMac->pmc.uapsdEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter UAPSD. UAPSD is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* If already in UAPSD, just return. */ + if (pMac->pmc.pmcState == UAPSD) + return eHAL_STATUS_SUCCESS; + + /* Check that we are associated. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, LOGE, "PMC: STA not associated with an AP. UAPSD cannot be entered"); + return eHAL_STATUS_FAILURE; + } + + /* Enter REQUEST_START_UAPSD State. */ + if (pmcEnterRequestStartUapsdState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + if( NULL != callbackRoutine ) + { + /* If success then request is pending. Allocate entry for callback routine list. */ + pEntry = vos_mem_malloc(sizeof(tStartUapsdEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, "PMC: cannot allocate memory for request " + "start UAPSD routine list entry"); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestStartUapsdList, &pEntry->link, FALSE); + } + + return eHAL_STATUS_PMC_PENDING; +} + +/****************************************************************************** +* +* Name: pmcStopUapsd +* +* Description: +* Request that the device be put out of UAPSD state. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state +* eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state +* +******************************************************************************/ +eHalStatus pmcStopUapsd (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_UAPSD_STOP_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcStopUapsd"); + + /* Clear any buffered command for entering UAPSD */ + pMac->pmc.uapsdSessionRequired = FALSE; + + /* Nothing to be done if we are already out of UAPSD. This can happen if + some other module (HDD, BT-AMP) requested Full Power.*/ + if (pMac->pmc.pmcState != UAPSD && pMac->pmc.pmcState != REQUEST_STOP_UAPSD) + { + pmcLog(pMac, LOGW, "PMC: Device is already out of UAPSD " + "state. Current state is %d", pMac->pmc.pmcState); + return eHAL_STATUS_SUCCESS; + } + + /* Enter REQUEST_STOP_UAPSD State*/ + if (pmcEnterRequestStopUapsdState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcRequestStandby + \brief Request that the device be put in standby. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine invoked in case of success/failure + \param callbackContext - value to be passed as parameter to callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcRequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_ENTER_STANDBY_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestStandby"); + + /* Check if standby is enabled. */ + if (!pMac->pmc.standbyEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter standby. Standby is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting standby when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* If already in STANDBY, just return. */ + if (pMac->pmc.pmcState == STANDBY) + return eHAL_STATUS_SUCCESS; + + + if (csrIsIBSSStarted(pMac) || csrIsBTAMPStarted(pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "WLAN: IBSS or BT-AMP session present. Cannot honor standby request"); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Enter Request Standby State. */ + if (pmcEnterRequestStandbyState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + /* Save the callback routine for when we need it. */ + pMac->pmc.standbyCallbackRoutine = callbackRoutine; + pMac->pmc.standbyCallbackContext = callbackContext; + + return eHAL_STATUS_PMC_PENDING; +} + +/* --------------------------------------------------------------------------- + \fn pmcRegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcRegisterDeviceStateUpdateInd (tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpDeviceStateUpdateIndEntry pEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcRegisterDeviceStateUpdateInd")); + + /* Allocate entry for device power state update indication. */ + pEntry = vos_mem_malloc(sizeof(tDeviceStateUpdateIndEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for device power state update indication")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.deviceStateUpdateIndList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcDeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus pmcDeregisterDeviceStateUpdateInd (tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcDeregisterDeviceStateUpdateInd")); + + /* Find entry in the power save update routine list that matches + the specified routine and remove it. */ + pEntry = csrLLPeekHead(&pMac->pmc.deviceStateUpdateIndList, FALSE); + while (pEntry != NULL) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + if (pDeviceStateUpdateIndEntry->callbackRoutine == callbackRoutine) + { + if (!csrLLRemoveEntry(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE)) + { + pmcLog(pMac, LOGE, FL("Cannot remove device state update ind entry from list")); + return eHAL_STATUS_FAILURE; + } + vos_mem_free(pDeviceStateUpdateIndEntry); + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + +/* --------------------------------------------------------------------------- + \fn pmcReady + \brief fn to inform PMC that eWNI_SME_SYS_READY_IND has been sent to PE. + This acts as a trigger to send a message to PE to update the power + save related conig to FW. Note that if HDD configures any power save + related stuff before this API is invoked, PMC will buffer all the + configutaion. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcReady(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcReady")); + + if(pMac->pmc.pmcState == STOPPED) + { + pmcLog(pMac, LOGP, FL("pmcReady is invoked even before pmcStart")); + return eHAL_STATUS_FAILURE; + } + + pMac->pmc.pmcReady = TRUE; + if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS) + { + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcWowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. Note that Firmware performs the pattern matching only on + broadcast frames and while Libra is in BMPS mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pointer to the pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcWowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_log_powersave_wow_add_ptrn_pkt_type *log_ptr = NULL; + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_powersave_wow_add_ptrn_pkt_type, LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C); +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT + + pmcLog(pMac, LOG2, "PMC: entering pmcWowlAddBcastPattern"); + + if(pattern == NULL) + { + pmcLog(pMac, LOGE, FL("Null broadcast pattern being passed")); + return eHAL_STATUS_FAILURE; + } + + if( pSession == NULL) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + if( log_ptr ) + { + log_ptr->pattern_id = pattern->ucPatternId; + log_ptr->pattern_byte_offset = pattern->ucPatternByteOffset; + log_ptr->pattern_size = + (pattern->ucPatternSize <= VOS_LOG_MAX_WOW_PTRN_SIZE) ? + pattern->ucPatternSize : VOS_LOG_MAX_WOW_PTRN_SIZE; + log_ptr->pattern_mask_size = + (pattern->ucPatternMaskSize <= VOS_LOG_MAX_WOW_PTRN_MASK_SIZE) ? + pattern->ucPatternMaskSize : VOS_LOG_MAX_WOW_PTRN_MASK_SIZE; + + vos_mem_copy(log_ptr->pattern, pattern->ucPattern, + log_ptr->pattern_size); + /* 1 bit in the pattern mask denotes 1 byte of pattern. */ + vos_mem_copy(log_ptr->pattern_mask, pattern->ucPatternMask, + log_ptr->pattern_mask_size); + } + + //The same macro frees the memory. + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif + + + /* No need to care PMC state transition when ps offload is enabled. */ + if(pMac->psOffloadEnabled) + goto skip_pmc_state_transition; + + if( pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + if( !csrIsConnStateConnected(pMac, sessionId) ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern session in %d state"), + pSession->connectState); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + +skip_pmc_state_transition: + + if (pmcSendMessage(hHal, eWNI_PMC_WOWL_ADD_BCAST_PTRN, pattern, sizeof(tSirWowlAddBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcWowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcWowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_DEL_PTRN_REQ; + wowRequest.wow_del_ptrn_id = pattern->ucPatternId; + + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcWowlDelBcastPattern"); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + + /* No need to care PMC state transition when ps offload is enabled. */ + if(pMac->psOffloadEnabled) + goto skip_pmc_state_transition; + + if(pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY) + { + pmcLog(pMac, LOGE, FL("Cannot delete WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + eHalStatus status; + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + //Wake up the chip first + status = pmcDeferMsg( pMac, eWNI_PMC_WOWL_DEL_BCAST_PTRN, + pattern, sizeof(tSirWowlDelBcastPtrn) ); + + if( eHAL_STATUS_PMC_PENDING == status ) + { + return eHAL_STATUS_SUCCESS; + } + else + { + //either fail or already in full power + if( !HAL_STATUS_SUCCESS( status ) ) + { + return ( status ); + } + //else let it through because it is in full power state + } + } + +skip_pmc_state_transition: + + if (pmcSendMessage(hHal, eWNI_PMC_WOWL_DEL_BCAST_PTRN, pattern, sizeof(tSirWowlDelBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_DEL_BCAST_PTRN to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcEnterWowl + \brief Request that the device be brought to full power state. + Note 1: If "fullPowerReason" specificied in this API is set to + eSME_FULL_PWR_NEEDED_BY_HDD, PMC will clear any "buffered wowl" requests + and also clear any "buffered BMPS requests by HDD". Assumption is that since + HDD is requesting full power, we need to undo any previous HDD requests for + BMPS (using sme_RequestBmps) or WoWL (using sme_EnterWoWL). If the reason is + specified anything other than above, the buffered requests for BMPS and WoWL + will not be cleared. + Note 2: Requesting full power (no matter what the fullPowerReason is) doesn't + disable the "auto bmps timer" (if it is enabled) or clear any "buffered uapsd + request". + Note 3: When the device finally enters Full Power PMC will start a timer + if any of the following holds true: + - Auto BMPS mode is enabled + - Uapsd request is pending + - HDD's request for BMPS is pending + - HDD's request for WoWL is pending + On timer expiry PMC will attempt to put the device in BMPS mode if following + (in addition to those listed above) holds true: + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - enterWowlCallbackRoutine Callback routine invoked in case of success/failure + \param - enterWowlCallbackContext - Cookie to be passed back during callback + \param - wakeReasonIndCB Callback routine invoked for Wake Reason Indication + \param - wakeReasonIndCBContext - Cookie to be passed back during callback + \param - fullPowerReason - Reason why this API is being invoked. SME needs to + distinguish between BAP and HDD requests + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +eHalStatus pmcEnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_ENTER_REQ; + wowRequest.wow_type = 0; + + if(wowlEnterParams->ucMagicPktEnable) + { + wowRequest.wow_type |= 1; + vos_mem_copy(wowRequest.wow_magic_pattern, + (tANI_U8 *)wowlEnterParams->magicPtrn, 6); + } + + if(wowlEnterParams->ucPatternFilteringEnable) + { + wowRequest.wow_type |= 2; + } + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, FL("PMC: entering pmcEnterWowl")); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + /* No need worry about PMC state when power save offload is enabled. */ + if( pMac->psOffloadEnabled ) + goto skip_pmc_state_transition; + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting WoWL when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check if WoWL is enabled. */ + if (!pMac->pmc.wowlEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. WoWL is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check that we are associated with single Session. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, LOGE, "PMC: Cannot enable WOWL. STA not associated " + "with an Access Point in Infra Mode with single active session"); + return eHAL_STATUS_FAILURE; + } + + /* Is there a pending UAPSD request? HDD should have triggered QoS + module to do the necessary cleanup before triggring WOWL*/ + if(pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGE, "PMC: Cannot request WOWL. Pending UAPSD request"); + return eHAL_STATUS_FAILURE; + } + + /* Check that entry into a power save mode is allowed at this time. */ + if (pMac->pmc.pmcState == FULL_POWER && !pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOGE, "PMC: Power save check failed. WOWL request " + "will not be accepted"); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(wowlEnterParams->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + +skip_pmc_state_transition: + // To avoid race condition, set callback routines before sending message. + /* cache the WOWL information */ + pMac->pmc.wowlEnterParams = *wowlEnterParams; + pMac->pmc.enterWowlCallbackRoutine = enterWowlCallbackRoutine; + pMac->pmc.enterWowlCallbackContext = enterWowlCallbackContext; +#ifdef WLAN_WAKEUP_EVENTS + /* Cache the Wake Reason Indication callback information */ + pMac->pmc.wakeReasonIndCB = wakeReasonIndCB; + pMac->pmc.wakeReasonIndCBContext = wakeReasonIndCBContext; +#endif // WLAN_WAKEUP_EVENTS + + /* Enter Request WOWL State. */ + if (pmcRequestEnterWowlState(hHal, wowlEnterParams) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + if(!pMac->psOffloadEnabled) + pMac->pmc.wowlModeRequired = TRUE; + + return eHAL_STATUS_PMC_PENDING; +} + +/* --------------------------------------------------------------------------- + \fn pmcExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. + \param hHal - The handle returned by macOpen. + \param wowlExitParams - Carries info on which smesession + wowl exit is requested. + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +eHalStatus pmcExitWowl (tHalHandle hHal, tpSirSmeWowlExitParams wowlExitParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_EXIT_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcExitWowl"); + + /* Clear any buffered command for entering WOWL */ + pMac->pmc.wowlModeRequired = FALSE; + + /* Enter REQUEST_EXIT_WOWL State*/ + if (pmcRequestExitWowlState(hHal, wowlExitParams) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + /* Clear the callback routines */ + pMac->pmc.enterWowlCallbackRoutine = NULL; + pMac->pmc.enterWowlCallbackContext = NULL; + + return eHAL_STATUS_SUCCESS; +} + + + +/* --------------------------------------------------------------------------- + \fn pmcSetHostOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetHostOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId) +{ + tpSirHostOffloadReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: IP address = %d.%d.%d.%d", __func__, + pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1], + pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: SESSION not Found\n", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for host offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq)); + + msg.type = WDA_SET_HOST_OFFLOAD; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_HOST_OFFLOAD message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcSetKeepAlive + \brief Set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the keepalive. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetKeepAlive (tHalHandle hHal, tpSirKeepAliveReq pRequest, tANI_U8 sessionId) +{ + tpSirKeepAliveReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "%s: " + "WDA_SET_KEEP_ALIVE message", __func__); + + if(pSession == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + " Session not Found", __func__); + return eHAL_STATUS_FAILURE; + } + pRequestBuf = vos_mem_malloc(sizeof(tSirKeepAliveReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for keep alive request", + __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirKeepAliveReq)); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "buff TP %d " + "input TP %d ", pRequestBuf->timePeriod, pRequest->timePeriod); + pRequestBuf->sessionId = sessionId; + + msg.type = WDA_SET_KEEP_ALIVE; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post WDA_SET_KEEP_ALIVE message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +#ifdef WLAN_NS_OFFLOAD + +/* --------------------------------------------------------------------------- + \fn pmcSetNSOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetNSOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpSirHostOffloadReq pRequestBuf; + vos_msg_t msg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for NS offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq)); + + msg.type = WDA_SET_NS_OFFLOAD; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post SIR_HAL_SET_HOST_OFFLOAD message to HAL", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#endif //WLAN_NS_OFFLOAD + + +void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + + csrLLLock(&pMac->pmc.powerSaveCheckList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.powerSaveCheckList, FALSE)) ) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + vos_mem_free(pPowerSaveCheckEntry); + } + csrLLUnlock(&pMac->pmc.powerSaveCheckList); + csrLLClose(&pMac->pmc.powerSaveCheckList); +} + + +void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpRequestFullPowerEntry pRequestFullPowerEntry; + + csrLLLock(&pMac->pmc.requestFullPowerList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestFullPowerList, FALSE)) ) + { + pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link); + vos_mem_free(pRequestFullPowerEntry); + } + csrLLUnlock(&pMac->pmc.requestFullPowerList); + csrLLClose(&pMac->pmc.requestFullPowerList); +} + + +void pmcCloseRequestBmpsList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpRequestBmpsEntry pRequestBmpsEntry; + + csrLLLock(&pMac->pmc.requestBmpsList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE)) ) + { + pRequestBmpsEntry = GET_BASE_ADDR(pEntry, tRequestBmpsEntry, link); + vos_mem_free(pRequestBmpsEntry); + } + csrLLUnlock(&pMac->pmc.requestBmpsList); + csrLLClose(&pMac->pmc.requestBmpsList); +} + + +void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpStartUapsdEntry pStartUapsdEntry; + + csrLLLock(&pMac->pmc.requestStartUapsdList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE)) ) + { + pStartUapsdEntry = GET_BASE_ADDR(pEntry, tStartUapsdEntry, link); + vos_mem_free(pStartUapsdEntry); + } + csrLLUnlock(&pMac->pmc.requestStartUapsdList); + csrLLClose(&pMac->pmc.requestStartUapsdList); +} + + +void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + + csrLLLock(&pMac->pmc.deviceStateUpdateIndList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deviceStateUpdateIndList, FALSE)) ) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + vos_mem_free(pDeviceStateUpdateIndEntry); + } + csrLLUnlock(&pMac->pmc.deviceStateUpdateIndList); + csrLLClose(&pMac->pmc.deviceStateUpdateIndList); +} + + +void pmcCloseDeferredMsgList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tPmcDeferredMsg *pDeferredMsg; + + csrLLLock(&pMac->pmc.deferredMsgList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deferredMsgList, FALSE)) ) + { + pDeferredMsg = GET_BASE_ADDR(pEntry, tPmcDeferredMsg, link); + vos_mem_free(pDeferredMsg); + } + csrLLUnlock(&pMac->pmc.deferredMsgList); + csrLLClose(&pMac->pmc.deferredMsgList); +} + + +#ifdef FEATURE_WLAN_SCAN_PNO + +static tSirRetStatus +pmcPopulateMacHeader( tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, + tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /// Prepare MAC management header + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + // Prepare FC + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + // Prepare Address 1 + vos_mem_copy((tANI_U8 *) pMacHdr->da, (tANI_U8 *) peerAddr, sizeof( tSirMacAddr )); + + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + // Prepare Address 3 + vos_mem_copy((tANI_U8 *) pMacHdr->bssId, (tANI_U8 *) peerAddr, sizeof( tSirMacAddr )); + return statusCode; +} /*** pmcPopulateMacHeader() ***/ + + +static tSirRetStatus +pmcPrepareProbeReqTemplate(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tANI_U32 dot11mode, + tSirMacAddr selfMacAddr, + tANI_U8 *pFrame, + tANI_U16 *pusLen, + tCsrRoamSession *psession) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + /*Bcast tx*/ + tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + // The scheme here is to fill out a 'tDot11fProbeRequest' structure + // and then hand it off to 'dot11fPackProbeRequest' (for + // serialization). We start by zero-initializing the structure: + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + PopulateDot11fSuppRates( pMac, nChannelNum, &pr.SuppRates,NULL); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + + + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, NULL, &pr.HTCaps ); + pr.HTCaps.advCodingCap = psession->htConfig.ht_rx_ldpc; + pr.HTCaps.txSTBC = psession->htConfig.ht_tx_stbc; + pr.HTCaps.rxSTBC = psession->htConfig.ht_rx_stbc; + if (!psession->htConfig.ht_sgi) { + pr.HTCaps.shortGI20MHz = pr.HTCaps.shortGI40MHz = 0; + } + } + + // That's it-- now we pack it. First, how much space are we going to + // need? + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to calculate the packed size f" + "or a Probe Request (0x%08x).", nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x).", nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + /* Prepare outgoing frame*/ + vos_mem_set(pFrame, nBytes, 0); + + // Next, we fill out the buffer descriptor: + nSirStatus = pmcPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssId,selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to populate the buffer descriptor for a Probe Request (%d).", + nSirStatus ); + return nSirStatus; // allocated! + } + + // That done, pack the Probe Request: + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to pack a Probe Request (0x%08x).", nStatus ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while packing a Probe Request" ); + } + + *pusLen = nPayload + sizeof(tSirMacMgmtHdr); + return eSIR_SUCCESS; +} // End pmcPrepareProbeReqTemplate. + + +eHalStatus pmcSetPreferredNetworkList +( + tHalHandle hHal, + tpSirPNOScanReq pRequest, + tANI_U8 sessionId, + preferredNetworkFoundIndCallback callbackRoutine, + void *callbackContext +) +{ + tpSirPNOScanReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U8 ucDot11Mode; + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pSession is NULL", __func__); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: SSID = 0x%08x%08x%08x%08x%08x%08x%08x%08x, " + "0x%08x%08x%08x%08x%08x%08x%08x%08x", __func__, + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[0]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[4]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[8]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[12]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[16]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[20]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[24]), + *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[28]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[0]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[4]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[8]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[12]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[16]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[20]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[24]), + *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[28])); + + if (!pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pSessionis NULL", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirPNOScanReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for PNO request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirPNOScanReq)); + + /*Must translate the mode first*/ + ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, + csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + + /*Prepare a probe request for 2.4GHz band and one for 5GHz band*/ + if (eSIR_SUCCESS == pmcPrepareProbeReqTemplate(pMac, SIR_PNO_24G_DEFAULT_CH, + ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p24GProbeTemplate, + &pRequestBuf->us24GProbeTemplateLen, pSession)) + { + /* Append IE passed by supplicant(if any) to probe request */ + if ((0 < pRequest->us24GProbeTemplateLen) && + ((pRequestBuf->us24GProbeTemplateLen + + pRequest->us24GProbeTemplateLen) < SIR_PNO_MAX_PB_REQ_SIZE )) + { + vos_mem_copy((tANI_U8 *)&pRequestBuf->p24GProbeTemplate + + pRequestBuf->us24GProbeTemplateLen, + (tANI_U8 *)&pRequest->p24GProbeTemplate, + pRequest->us24GProbeTemplateLen); + pRequestBuf->us24GProbeTemplateLen += + pRequest->us24GProbeTemplateLen; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: pRequest->us24GProbeTemplateLen = %d", __func__, + pRequest->us24GProbeTemplateLen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Extra ie discarded on 2.4G, IE length = %d", __func__, + pRequest->us24GProbeTemplateLen); + } + } + + if (eSIR_SUCCESS == pmcPrepareProbeReqTemplate(pMac, SIR_PNO_5G_DEFAULT_CH, + ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p5GProbeTemplate, + &pRequestBuf->us5GProbeTemplateLen, pSession)) + { + /* Append IE passed by supplicant(if any) to probe request */ + if ((0 < pRequest->us5GProbeTemplateLen ) && + ((pRequestBuf->us5GProbeTemplateLen + + pRequest->us5GProbeTemplateLen) < SIR_PNO_MAX_PB_REQ_SIZE )) + { + vos_mem_copy((tANI_U8 *)&pRequestBuf->p5GProbeTemplate + + pRequestBuf->us5GProbeTemplateLen, + (tANI_U8 *)&pRequest->p5GProbeTemplate, + pRequest->us5GProbeTemplateLen); + pRequestBuf->us5GProbeTemplateLen += pRequest->us5GProbeTemplateLen; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: pRequestBuf->us5GProbeTemplateLen = %d", __func__, + pRequest->us5GProbeTemplateLen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Extra IE discarded on 5G, IE length = %d", __func__, + pRequest->us5GProbeTemplateLen); + } + } + + if (pMac->pnoOffload) + { + if (pRequestBuf->enable) + { + pSession->pnoStarted = TRUE; + } + else + { + pSession->pnoStarted = FALSE; + } + + pRequestBuf->sessionId = sessionId; + } + + msg.type = WDA_SET_PNO_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_PNO_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + /* Cache the Preferred Network Found Indication callback information */ + pMac->pmc.prefNetwFoundCB = callbackRoutine; + pMac->pmc.preferredNetworkFoundIndCallbackContext = callbackContext; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold) +{ + tpSirSetRSSIFilterReq pRequestBuf; + vos_msg_t msg; + + + pRequestBuf = vos_mem_malloc(sizeof(tpSirSetRSSIFilterReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for PNO request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + + pRequestBuf->rssiThreshold = rssiThreshold; + + msg.type = WDA_SET_RSSI_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_PNO_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus pmcUpdateScanParams(tHalHandle hHal, tCsrConfig *pRequest, tCsrChannel *pChannelList, tANI_U8 b11dResolved) +{ + tpSirUpdateScanParams pRequestBuf; + vos_msg_t msg; + int i; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s started", __func__); + + pRequestBuf = vos_mem_malloc(sizeof(tSirUpdateScanParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for UpdateScanParams request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + // + // Fill pRequestBuf structure from pRequest + // + pRequestBuf->b11dEnabled = pRequest->Is11eSupportEnabled; + pRequestBuf->b11dResolved = b11dResolved; + pRequestBuf->ucChannelCount = + ( pChannelList->numChannels < SIR_PNO_MAX_NETW_CHANNELS_EX )? + pChannelList->numChannels:SIR_PNO_MAX_NETW_CHANNELS_EX; + + for (i=0; i < pRequestBuf->ucChannelCount; i++) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Channel List %d: %d", __FUNCTION__, i, pChannelList->channelList[i] ); + + pRequestBuf->aChannels[i] = pChannelList->channelList[i]; + } + pRequestBuf->usPassiveMinChTime = pRequest->nPassiveMinChnTime; + pRequestBuf->usPassiveMaxChTime = pRequest->nPassiveMaxChnTime; + pRequestBuf->usActiveMinChTime = pRequest->nActiveMinChnTime; + pRequestBuf->usActiveMaxChTime = pRequest->nActiveMaxChnTime; + pRequestBuf->ucCBState = PHY_SINGLE_CHANNEL_CENTERED; + + msg.type = WDA_UPDATE_SCAN_PARAMS_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_UPDATE_SCAN_PARAMS message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // FEATURE_WLAN_SCAN_PNO + +eHalStatus pmcSetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced) +{ + tSirSetPowerParamsReq* pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPESession psessionEntry; + + psessionEntry = peGetValidPowerSaveSession(pMac); + if (!forced && (psessionEntry == NULL)) + { + return eHAL_STATUS_NOT_INITIALIZED; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirSetPowerParamsReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for Power Paramrequest", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + + vos_mem_copy(pRequestBuf, pwParams, sizeof(*pRequestBuf)); + + + msg.type = WDA_SET_POWER_PARAMS_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_POWER_PARAMS_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +eHalStatus pmcGetFilterMatchCount +( + tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId +) +{ + tpSirRcvFltPktMatchRsp pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s", __func__); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktMatchRsp)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate " + "memory for Get PC Filter Match Count request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + msg.type = WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + /* Cache the Packet Coalescing Filter Match Count callback information */ + if (NULL != pMac->pmc.FilterMatchCountCB) + { + // Do we need to check if the callback is in use? + // Because we are not sending the same message again when it is pending, + // the only case when the callback is not NULL is that the previous message + //was timed out or failed. + // So, it will be safe to set the callback in this case. + } + + pMac->pmc.FilterMatchCountCB = callbackRoutine; + pMac->pmc.FilterMatchCountCBContext = callbackContext; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ " + "message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn pmcSetGTKOffload + \brief Set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pGtkOffload - Pointer to the GTK offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pGtkOffload, + tANI_U8 sessionId) +{ + tpSirGtkOffloadParams pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: KeyReplayCounter: %lld", + __func__, pGtkOffload->ullKeyReplayCounter); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = (tpSirGtkOffloadParams)vos_mem_malloc(sizeof(tSirGtkOffloadParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate " + "memory for GTK offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pGtkOffload->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pGtkOffload, sizeof(tSirGtkOffloadParams)); + + msg.type = WDA_GTK_OFFLOAD_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "SIR_HAL_SET_GTK_OFFLOAD message to HAL", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcGetGTKOffload + \brief Get GTK offload information. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to the GTK Offload Get Info response callback routine. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcGetGTKOffload(tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId) +{ + tpSirGtkOffloadGetInfoRspParams pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: Entered", + __func__); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = (tpSirGtkOffloadGetInfoRspParams) + vos_mem_malloc(sizeof (tSirGtkOffloadGetInfoRspParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate " + "memory for Get GTK offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + msg.type = WDA_GTK_OFFLOAD_GETINFO_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + /* Cache the Get GTK Offload callback information */ + if (NULL != pMac->pmc.GtkOffloadGetInfoCB) + { + // Do we need to check if the callback is in use? + // Because we are not sending the same message again when it is pending, + // the only case when the callback is not NULL is that the previous message was timed out or failed. + // So, it will be safe to set the callback in this case. + } + + pMac->pmc.GtkOffloadGetInfoCB = callbackRoutine; + pMac->pmc.GtkOffloadGetInfoCBContext = callbackContext; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_GTK_OFFLOAD_GETINFO_REQ message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +v_BOOL_t IsPmcImpsReqFailed (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_BOOL_t impsReqFailStatus; + + impsReqFailStatus = (pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed); + + return impsReqFailStatus; + +} + +void pmcResetImpsFailStatus (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pMac->pmc.ImpsReqTimerFailed = VOS_FALSE; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* ----------------------------------------------------------------------------- + \fn pmcSetBatchScanReq + \brief setting batch scan request in FW + \param hHal - The handle returned by macOpen. + \param sessionId - session ID + \param callbackRoutine - Pointer to set batch scan request callback routine + \param callbackContext - Pointer to set batch scan request callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcSetBatchScanReq(tHalHandle hHal, tSirSetBatchScanReq *pRequest, + tANI_U8 sessionId, hddSetBatchScanReqCallback callbackRoutine, + void *callbackContext) +{ + tpSirSetBatchScanReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pRequestBuf = vos_mem_malloc(sizeof(tSirSetBatchScanReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for SET BATCH SCAN req", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + /* Cache HDD callback information*/ + pMac->pmc.setBatchScanReqCallback = callbackRoutine; + pMac->pmc.setBatchScanReqCallbackContext = callbackContext; + + pRequestBuf->sessionId = sessionId; + pRequestBuf->scanFrequency = pRequest->scanFrequency; + pRequestBuf->numberOfScansToBatch = pRequest->numberOfScansToBatch; + pRequestBuf->bestNetwork = pRequest->bestNetwork; + pRequestBuf->rfBand = pRequest->rfBand; + pRequestBuf->rtt = pRequest->rtt; + + msg.type = WDA_SET_BATCH_SCAN_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_BATCH_SCAN_REQ message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + \fn pmcTriggerBatchScanResultInd + \brief API to trigger batch scan results indications from FW + \param hHal - The handle returned by macOpen. + \param sessionId - session ID + \param callbackRoutine - Pointer to get batch scan request callback routine + \param callbackContext - Pointer to get batch scan request callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcTriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + hddTriggerBatchScanResultIndCallback callbackRoutine, void *callbackContext +) +{ + tpSirTriggerBatchScanResultInd pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pRequestBuf = vos_mem_malloc(sizeof(tSirTriggerBatchScanResultInd)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_TRIGGER_BATCH_SCAN_RESULT_IND", + __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + /*HDD callback to be called after getting batch scan result ind from FW*/ + pMac->pmc.batchScanResultCallback = callbackRoutine; + pMac->pmc.batchScanResultCallbackContext = callbackContext; + + pRequestBuf->param = pRequest->param; + + msg.type = WDA_TRIGGER_BATCH_SCAN_RESULT_IND; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_TRIGGER_BATCH_SCAN_RESULT_IND message" + " to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + \fn pmcStopBatchScanInd + \brief Stoping batch scan request in FW + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to stop batch scan request callback routine + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcStopBatchScanInd(tHalHandle hHal, tSirStopBatchScanInd *pRequest, + tANI_U8 sessionId) +{ + tSirStopBatchScanInd *pRequestBuf; + vos_msg_t msg; + + pRequestBuf = vos_mem_malloc(sizeof(tSirStopBatchScanInd)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for STOP BATCH SCAN IND", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + pRequestBuf->param = pRequest->param; + + msg.type = WDA_STOP_BATCH_SCAN_IND; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_TOP_BATCH_SCAN_IND message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#endif + +eHalStatus pmcOffloadCleanup(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter")); + + pmc->uapsdSessionRequired = FALSE; + pmc->configStaPsEnabled = FALSE; + pmc->configDefStaPsEnabled = FALSE; + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, eHAL_STATUS_FAILURE); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadOpen(tHalHandle hHal) +{ + tANI_U32 i; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG2, FL("Enter")); + + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + if(eHAL_STATUS_SUCCESS != pmcOffloadOpenPerSession(hHal, i)) + { + smsLog(pMac, LOGE, FL("PMC Init Failed for session %d"), i); + return eHAL_STATUS_FAILURE; + } + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadClose(tHalHandle hHal) +{ + tANI_U32 i; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG2, FL("Entering pmcOffloadClose")); + + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + pmcOffloadClosePerSession(hHal, i); + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadStart(tHalHandle hHal) +{ + tANI_U32 i; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG2, FL("Entering pmcOffloadStart")); + + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + if(eHAL_STATUS_SUCCESS != pmcOffloadStartPerSession(hHal, i)) + { + smsLog(pMac, LOGE, FL("PMC Init Failed for session %d"), i); + return eHAL_STATUS_FAILURE; + } + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadStop(tHalHandle hHal) +{ + tANI_U32 i; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG2, FL("Entering pmcOffloadStop")); + + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + { + pmcOffloadStopPerSession(hHal, i); + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadConfigEnablePowerSave(tHalHandle hHal, + tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG1, FL("Config Set Power Save Mode %d"), psMode); + + switch(psMode) + { + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmcOffloadInfo.staPsEnabled = TRUE; + break; + case ePMC_UAPSD_MODE_POWER_SAVE: + break; + default: + smsLog(pMac, LOGE, + FL("Config Set Power Save Mode -> Not Supported %d"), psMode); + break; + } + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadConfigDisablePowerSave(tHalHandle hHal, + tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG1, FL("Config Set Power Save Mode %d"), psMode); + + switch(psMode) + { + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmcOffloadInfo.staPsEnabled = FALSE; + break; + case ePMC_UAPSD_MODE_POWER_SAVE: + break; + default: + smsLog(pMac, LOGE, + FL("Config Set Power Save Mode -> Not Supported %d"), psMode); + break; + } + return eHAL_STATUS_SUCCESS; +} + +tPmcState pmcOffloadGetPmcState(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->pmcOffloadInfo.pmc[sessionId].pmcState; +} + +eHalStatus pmcOffloadRegisterPowerSaveCheck(tHalHandle hHal, tANI_U32 sessionId, + PwrSaveCheckRoutine checkRoutine, + void *checkContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPmcOffloadPsCheckEntry pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadRegPowerSaveCheck")); + + /* Allocate entry for power save check routine list. */ + pEntry = vos_mem_malloc(sizeof(tPmcOffloadPsCheckEntry)); + if (!pEntry) + { + smsLog(pMac, LOGE, + FL("Cannot allocate memory for power save check routine list")); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->pwrsaveCheckCb = checkRoutine; + pEntry->checkContext = checkContext; + pEntry->sessionId = sessionId; + + /* Add entry to list. */ + csrLLInsertTail(&pmc->pwrsaveCheckList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadDeregisterPowerSaveCheck(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveCheckRoutine checkRoutine) + +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPmcOffloadPsCheckEntry pPowerSaveCheckEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadDeregisterPowerSaveCheck")); + + /* + * Find entry in the power save check routine list that matches + * the specified routine and remove it. + */ + pEntry = csrLLPeekHead(&pmc->pwrsaveCheckList, FALSE); + while(pEntry != NULL) + { + pPowerSaveCheckEntry = + GET_BASE_ADDR(pEntry, tPmcOffloadPsCheckEntry, link); + if(pPowerSaveCheckEntry->pwrsaveCheckCb == checkRoutine) + { + if(csrLLRemoveEntry(&pmc->pwrsaveCheckList, pEntry, FALSE)) + { + vos_mem_free(pPowerSaveCheckEntry); + } + else + { + smsLog(pMac, LOGE, + FL("Cannot remove powersave check routine list entry")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pmc->pwrsaveCheckList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + +eHalStatus pmcOffloadRegisterDeviceStateUpdateInd(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveStateChangeIndCb stateChangeCb, + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPmcOffloadDevStateUpdIndEntry pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadRegisterDeviceStateUpdateInd")); + + /* Allocate entry for device power state update indication. */ + pEntry = vos_mem_malloc(sizeof(tPmcOffloadDevStateUpdIndEntry)); + if (!pEntry) + { + smsLog(pMac, LOGE, + FL("Cannot allocate memory for device power state update ind")); + return eHAL_STATUS_FAILURE; + } + + /* Store routine in entry. */ + pEntry->stateChangeCb = stateChangeCb; + pEntry->callbackContext = callbackContext; + pEntry->sessionId = sessionId; + + /* Add entry to list. */ + csrLLInsertTail(&pmc->deviceStateUpdateIndList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcOffloadDeregisterDeviceStateUpdateInd(tHalHandle hHal, + tANI_U32 sessionId, PwrSaveStateChangeIndCb stateChangeCb) + +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPmcOffloadDevStateUpdIndEntry pDeviceStateUpdateIndEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOG2, FL("Enter pmcOffloadDeregisterDeviceStateUpdateInd")); + + /* + * Find entry in the power save update routine list that matches + * the specified routine and remove it. + */ + pEntry = csrLLPeekHead(&pmc->deviceStateUpdateIndList, FALSE); + while(pEntry != NULL) + { + pDeviceStateUpdateIndEntry = + GET_BASE_ADDR(pEntry, tPmcOffloadDevStateUpdIndEntry, link); + if(pDeviceStateUpdateIndEntry->stateChangeCb == stateChangeCb) + { + if(!csrLLRemoveEntry(&pmc->deviceStateUpdateIndList, + pEntry, FALSE)) + { + smsLog(pMac, LOGE, + FL("Cannot remove devicestate update ind entry list")); + return eHAL_STATUS_FAILURE; + } + vos_mem_free(pDeviceStateUpdateIndEntry); + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pmc->deviceStateUpdateIndList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + +eHalStatus PmcOffloadEnableStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + if(!pMac->pmcOffloadInfo.staPsEnabled) + { + smsLog(pMac, LOGE, + FL("STA Mode PowerSave is not enabled in ini")); + return eHAL_STATUS_FAILURE; + } + + if(!pmc->configStaPsEnabled) + { + eHalStatus status; + status = pmcOffloadEnableStaPsHandler(pMac, sessionId); + + if((eHAL_STATUS_SUCCESS == status) || + (eHAL_STATUS_PMC_NOT_NOW == status)) + { + /* Successfully Queued Enabling Sta Mode Ps Request */ + smsLog(pMac, LOG2, + FL("Successfull Queued Enabling Sta Mode Ps Request")); + + pmc->configStaPsEnabled = TRUE; + return eHAL_STATUS_SUCCESS; + } + else + { + /* Failed to Queue Sta Mode Ps Request */ + smsLog(pMac, LOGE, + FL("Failed to Queue Sta Mode Ps Request")); + return eHAL_STATUS_FAILURE; + } + } + else + { + /* + * configStaPsEnabled is the master flag + * to enable sta mode power save + * If it is already set Auto Powersave Timer + * will take care of enabling Power Save + */ + smsLog(pMac, LOGE, + FL("sta mode power save already enabled")); + return eHAL_STATUS_SUCCESS; + } +} + +eHalStatus PmcOffloadDisableStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pmc->configStaPsEnabled) + { + status = pmcOffloadDisableStaPsHandler(pMac, sessionId); + } + else + { + /* + * configStaPsEnabled is the master flag + * to enable sta mode power save + * If it is already cleared then no need to + * do anything + */ + smsLog(pMac, LOGE, + FL("sta mode power save already disabled")); + /* Stop the Auto Sta Ps Timer if running */ + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + pmc->configDefStaPsEnabled = FALSE; + } + return status; +} + +eHalStatus pmcOffloadRequestFullPower (tHalHandle hHal, tANI_U32 sessionId, + FullPowerReqCb fullpwrReqCb,void *callbackContext, + tRequestFullPowerReason fullPowerReason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + if(FULL_POWER == pmc->pmcState) + { + smsLog(pMac, LOG2, + FL("Already in Full Power")); + return eHAL_STATUS_SUCCESS; + } + + if(pmc->fullPowerReqPend) + { + smsLog(pMac, LOG2, + FL("Full Power Req Pending")); + goto full_pwr_req_pending; + } + + if(eHAL_STATUS_FAILURE == + pmcOffloadQueueRequestFullPower(pMac, sessionId, fullPowerReason)) + { + /* + * Fail to issue eSmeCommandExitBmps + */ + smsLog(pMac, LOGE, FL("Fail to issue eSmeCommandExitBmps")); + return eHAL_STATUS_FAILURE; + } +full_pwr_req_pending: + if(fullpwrReqCb) + { + tpPmcOffloadReqFullPowerEntry pEntry; + + /* Allocate entry for Full Power Cb list. */ + pEntry = vos_mem_malloc(sizeof(tPmcOffloadReqFullPowerEntry)); + if (!pEntry) + { + smsLog(pMac, LOGE, + FL("Cannot allocate memory for Full Power routine list")); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->fullPwrCb = fullpwrReqCb; + pEntry->callbackContext = callbackContext; + pEntry->sessionId = sessionId; + + /* Add entry to list. */ + csrLLInsertTail(&pmc->fullPowerCbList, &pEntry->link, FALSE); + } + return eHAL_STATUS_PMC_PENDING; +} + +eHalStatus pmcOffloadStartUapsd(tHalHandle hHal, tANI_U32 sessionId, + UapsdStartIndCb uapsdStartIndCb, void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG2, "PMC: Start UAPSD Req"); + + /* Check if Sta Ps is enabled. */ + if(!pMac->pmcOffloadInfo.staPsEnabled) + { + smsLog(pMac, LOG2, "PMC: Cannot start uapsd. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check whether the give session is Infra and in Connected State */ + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOG2, "PMC:Sta not infra/connected state %d", sessionId); + return eHAL_STATUS_FAILURE; + } + + status = pmcOffloadQueueStartUapsdRequest(pMac, sessionId); + + if(eHAL_STATUS_PMC_PENDING != status) + { + smsLog(pMac, LOG2, "PMC: Start UAPSD Req:Not Pending"); + return status; + } + + /* + * Store the cbs so that corresponding registered + * module will be notified upon starting of + * uapsd + */ + if(uapsdStartIndCb) + { + tpPmcOffloadStartUapsdEntry pEntry; + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + /* Allocate entry for Start Uapsd Cb list. */ + pEntry = vos_mem_malloc(sizeof(tPmcOffloadStartUapsdEntry)); + if (!pEntry) + { + smsLog(pMac, LOGE, + FL("Cannot allocate memory for start uapsd list")); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->uapsdStartInd = uapsdStartIndCb; + pEntry->callbackContext = callbackContext; + pEntry->sessionId = sessionId; + + /* Add entry to list. */ + csrLLInsertTail(&pmc->uapsdCbList, &pEntry->link, FALSE); + } + return status; +} + +eHalStatus pmcOffloadStopUapsd(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG2, "PMC: Stop UAPSD Req"); + + /* Check if Sta Ps is enabled. */ + if(!pMac->pmcOffloadInfo.staPsEnabled) + { + smsLog(pMac, LOGW, "PMC: Cannot stop uapsd. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check whether the give session is Infra and in Connected State */ + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOGW, "PMC:Sta not infra/connected state %d", sessionId); + return eHAL_STATUS_FAILURE; + } + + status = pmcOffloadQueueStopUapsdRequest(pMac, sessionId); + if(eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGW, "PMC:Failed to queue Stop Uapsd Req SessionId %d", + sessionId); + } + return status; +} + +tANI_BOOLEAN pmcOffloadIsStaInPowerSave(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpPsOffloadPerSessionInfo pmc; + tANI_BOOLEAN StainPS = TRUE; + + if(!CSR_IS_SESSION_VALID(pMac, sessionId)) + { + smsLog(pMac, LOGE, FL("Invalid SessionId %x"), sessionId); + return TRUE; + } + + /* Check whether the give session is Infra and in Connected State */ + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOG1, FL("Sta not infra/connected state %d"), sessionId); + return TRUE; + } + else + { + pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + StainPS = (pmc->pmcState == BMPS) || (pmc->pmcState == UAPSD); + return StainPS; + } +} + +tANI_BOOLEAN pmcOffloadProcessCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE; + tANI_U32 sessionId = pCommand->sessionId; + tpPsOffloadPerSessionInfo pmc; + + /* Check whether Session is valid or not */ + if(!CSR_IS_SESSION_VALID(pMac, sessionId)) + { + smsLog(pMac, LOGE, "PMC Offload Proc Cmd Fail:Invalid SessionId %x", + pCommand->sessionId); + return fRemoveCmd; + } + + /* Get the Session specific PMC info */ + pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + do + { + switch(pCommand->command) + { + case eSmeCommandEnterBmps: + if(FULL_POWER == pmc->pmcState) + { + status = pmcOffloadEnableStaPsCheck(pMac, sessionId); + if(HAL_STATUS_SUCCESS(status)) + { + tSirPsReqData psData; + tCsrRoamSession *pSession = + CSR_GET_SESSION(pMac, sessionId); + + /* PE uses this BSSID to retrieve corresponding PE Session */ + vos_mem_copy(psData.bssId, + pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + /* + * If uapsd is pending + * sent the req as combined request for both + * enabling ps and uapsd + */ + if(pmc->uapsdSessionRequired) + { + psData.addOnReq = eSIR_ADDON_ENABLE_UAPSD; + pmc->uapsdStatus = PMC_UAPSD_ENABLE_PENDING; + } + else + { + psData.addOnReq = eSIR_ADDON_NOTHING; + pmc->uapsdStatus = PMC_UAPSD_DISABLED; + } + + smsLog(pMac, LOG2, "PMC: Enter BMPS req done"); + + /* Tell MAC to have device enter BMPS mode. */ + status = + pmcSendMessage(pMac,eWNI_PMC_ENTER_BMPS_REQ, + &psData, sizeof(tSirPsReqData)); + if(HAL_STATUS_SUCCESS(status)) + { + /* Change PMC state */ + pmc->pmcState = REQUEST_BMPS; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + } + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + "PMC: failure to send message" + "eWNI_PMC_ENTER_BMPS_REQ status %d", status); + + pmcOffloadExitPowersaveState(pMac, sessionId); + } + } + else + { + smsLog(pMac, LOGE, + "Fail to send enterBMPS msg to PE state %d", pmc->pmcState); + } + break; + + case eSmeCommandExitBmps: + if((BMPS == pmc->pmcState) || + (UAPSD == pmc->pmcState)) + { + tSirPsReqData psData; + tCsrRoamSession *pSession = + CSR_GET_SESSION(pMac, sessionId); + + /* PE uses this BSSID to retrieve corresponding PE Session */ + vos_mem_copy(psData.bssId, + pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + if(UAPSD == pmc->pmcState) + { + psData.addOnReq = eSIR_ADDON_DISABLE_UAPSD; + pmc->uapsdStatus = PMC_UAPSD_DISABLE_PENDING; + } + else + { + psData.addOnReq = eSIR_ADDON_NOTHING; + } + + /* Tell MAC to have device exit BMPS mode. */ + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_BMPS_REQ, &psData, + sizeof(tSirPsReqData)); + if(HAL_STATUS_SUCCESS(status)) + { + /* Change PMC state */ + pmc->pmcState = REQUEST_FULL_POWER; + fRemoveCmd = eANI_BOOLEAN_FALSE; + smsLog(pMac, LOG2, + FL("eWNI_PMC_OFFLOAD_PS_REQ (disable) sent to PE")); + } + else + { + /* Call Full Req Cb with Failure */ + pmcOffloadDoFullPowerCallbacks(pMac, sessionId, + eHAL_STATUS_FAILURE); + smsLog(pMac, LOGE, "Fail to send exit BMPS msg to PE"); + } + } + else + { + smsLog(pMac, LOGE, + "Fail to send exitBMPS msg to PE state %d", pmc->pmcState); + } + break; + + case eSmeCommandEnterUapsd: + if(BMPS == pmc->pmcState) + { + tSirPsReqData psData; + tCsrRoamSession *pSession = + CSR_GET_SESSION(pMac, sessionId); + /* PE uses this BSSID to retrieve corresponding PE Session */ + vos_mem_copy(psData.bssId, + pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + pmc->uapsdSessionRequired = TRUE; + + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_UAPSD_REQ, &psData, + sizeof(tSirPsReqData)); + + if(HAL_STATUS_SUCCESS(status)) + { + pmc->pmcState = REQUEST_START_UAPSD; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_UAPSD_REQ"); + /* there is no retry for re-entering UAPSD so tell the requester */ + pMac->pmc.uapsdSessionRequired = FALSE; + /* call uapsd cbs with failure */ + pmcOffloadDoStartUapsdCallbacks(pMac, pCommand->sessionId, + eHAL_STATUS_FAILURE); + } + } + else + { + smsLog(pMac, LOGE, + "Fail to send EnterUapsd to PE state %d", pmc->pmcState); + } + break; + + case eSmeCommandExitUapsd: + if(UAPSD == pmc->pmcState) + { + tSirPsReqData psData; + tCsrRoamSession *pSession = + CSR_GET_SESSION(pMac, sessionId); + /* PE uses this BSSID to retrieve corresponding PE Session */ + vos_mem_copy(psData.bssId, + pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_UAPSD_REQ, &psData, + sizeof(tSirPsReqData)); + + if(HAL_STATUS_SUCCESS(status)) + { + pmc->pmcState = REQUEST_STOP_UAPSD; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + pmcOffloadEnterPowersaveState(pMac, sessionId); + } + } + else + { + smsLog(pMac, LOGE, + "Fail to send ExitUapsd to PE state %d", pmc->pmcState); + } + break; + + case eSmeCommandEnterWowl: + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_WOWL_REQ, + &pCommand->u.pmcCmd.u.enterWowlInfo, + sizeof(tSirSmeWowlEnterParams)); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ"); + } + break; + + case eSmeCommandExitWowl: + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_WOWL_REQ, + &pCommand->u.pmcCmd.u.exitWowlInfo, + sizeof(tSirSmeWowlExitParams)); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGP, "PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ"); + } + break; + + case eSmeCommandEnterStandby: + smsLog(pMac, LOGE, "PMC: eSmeCommandEnterStandby " + "is not supported"); + break; + + default: + smsLog( pMac, LOGE, FL(" invalid command type %d"), pCommand->command ); + break; + } + } while(0); + + return fRemoveCmd; +} + +void pmcOffloadMessageProcessor(tHalHandle hHal, tSirSmeRsp *pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG2, + FL("Entering pmcMessageProcessor, message type %d"), pMsg->messageType); + + switch(pMsg->messageType) + { + case eWNI_PMC_EXIT_BMPS_IND: + /* Device left BMPS on its own. */ + smsLog(pMac, LOGW, + FL("Rcvd eWNI_PMC_EXIT_BMPS_IND with status = %d"), pMsg->statusCode); + + pmcOffloadExitBmpsIndHandler(pMac, pMsg); + break; + + default: + pmcOffloadProcessResponse(pMac,pMsg ); + break; + } +} + +#ifdef FEATURE_WLAN_TDLS +eHalStatus pmcOffloadSetTdlsProhibitBmpsStatus(tHalHandle hHal, + tANI_U32 sessionId, + v_BOOL_t val) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc; + + /* Get the Session specific PMC info */ + pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + smsLog(pMac, LOGW, + FL("Set TdlsProhibitBmpsStatus %d for session %d"), val, sessionId); + + pmc->isTdlsPowerSaveProhibited = val; + return eHAL_STATUS_SUCCESS; +} +#endif + +/****************************************************************************** +* +* Name: pmcOffloadIsPowerSaveEnabled +* +* Description: +* Checks if the device is able to enter one of the power save modes. +* "Able to enter" means the power save mode is enabled for the device +* and the host is using the correct power source for entry into the +* power save mode. This routine does not indicate whether the device +* is actually in the power save mode at a particular point in time. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode +* +* Returns: +* TRUE if device is able to enter the power save mode, FALSE otherwise +* +******************************************************************************/ +tANI_BOOLEAN pmcOffloadIsPowerSaveEnabled (tHalHandle hHal, tANI_U32 sessionId, + tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + pmcLog(pMac, LOG2, FL("Entering pmcIsPowerSaveEnabled, power save mode %d"), + psMode); + + /* Check ability to enter based on the specified power saving mode. */ + switch (psMode) + { + case ePMC_BEACON_MODE_POWER_SAVE: + return pMac->pmcOffloadInfo.staPsEnabled; + + case ePMC_UAPSD_MODE_POWER_SAVE: + return pmc->UapsdEnabled; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return FALSE; + } +} + +eHalStatus PmcOffloadEnableDeferredStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId, + tANI_BOOLEAN isReassoc) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 timer_value; + + if (!pMac->pmcOffloadInfo.staPsEnabled) + { + smsLog(pMac, LOGE, + FL("STA Mode PowerSave is not enabled in ini")); + return status; + } + + if(isReassoc) + timer_value = AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE; + else + timer_value = AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE; + + pmcLog(pMac, LOG1, FL("Start AutoPsTimer for %d isReassoc:%d "), + timer_value, isReassoc); + + status = pmcOffloadStartAutoStaPsTimer(pMac, sessionId, + timer_value); + if (eHAL_STATUS_SUCCESS == status) + { + smsLog(pMac, LOG2, + FL("Enabled Deferred ps for session %d"), sessionId); + pmc->configDefStaPsEnabled = TRUE; + } + return status; +} + +eHalStatus PmcOffloadDisableDeferredStaModePowerSave(tHalHandle hHal, + tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId]; + + /* Stop the Auto Sta Ps Timer if running */ + pmcOffloadStopAutoStaPsTimer(pMac, sessionId); + pmc->configDefStaPsEnabled = FALSE; + return eHAL_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcLogDump.c b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcLogDump.c new file mode 100644 index 0000000000000..264a4bfcfb699 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/pmc/pmcLogDump.c @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmcLogDump.c +* +* Description: Implements the dump commands specific to PMC module +* + +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "pmcApi.h" +#include "pmc.h" +#include "logDump.h" +#include "smsDebug.h" +#include "sme_Api.h" +#include "cfgApi.h" + +#if defined(ANI_LOGDUMP) + +void dump_pmc_callbackRoutine (void *callbackContext, eHalStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received callback from PMC with status = %d\n*********",status); +} + +#ifdef WLAN_WAKEUP_EVENTS +void dump_pmc_callbackRoutine2 (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received callback from PMC with reason = %d\n*********",pWakeReasonInd->ulReason); +} +#endif // WLAN_WAKEUP_EVENTS + +void dump_pmc_deviceUpdateRoutine (void *callbackContext, tPmcState pmcState) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received msg from PMC: Device is in %s state\n*********", pmcGetPmcStateStr(pmcState)); +} + +static char * +dump_pmc_state( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + char *ptr = p; + + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + p += log_sprintf( pMac,p, "******** PMC State & Configuration ******** \n"); + p += log_sprintf( pMac,p, " PMC: IMPS Enabled? %d\n", pMac->pmc.impsEnabled); + p += log_sprintf( pMac,p, " PMC: Auto BMPS Timer Enabled? %d\n", pMac->pmc.autoBmpsEntryEnabled); + p += log_sprintf( pMac,p, " PMC: BMPS Enabled? %d\n", pMac->pmc.bmpsEnabled); + p += log_sprintf( pMac,p, " PMC: UAPSD Enabled? %d\n", pMac->pmc.uapsdEnabled); + p += log_sprintf( pMac,p, " PMC: WoWL Enabled? %d\n", pMac->pmc.wowlEnabled); + p += log_sprintf( pMac,p, " PMC: Standby Enabled? %d\n", pMac->pmc.standbyEnabled); + p += log_sprintf( pMac,p, " PMC: Auto BMPS timer period (ms): %d\n", pMac->pmc.bmpsConfig.trafficMeasurePeriod); + p += log_sprintf( pMac,p, " PMC: BMPS Listen Interval (Beacon intervals): %d\n", pMac->pmc.bmpsConfig.bmpsPeriod); + p += log_sprintf( pMac,p, " PMC: Device State = %s\n", pmcGetPmcStateStr(pMac->pmc.pmcState)); + p += log_sprintf( pMac,p, " PMC: RequestFullPowerPending = %d\n", pMac->pmc.requestFullPowerPending); + p += log_sprintf( pMac,p, " PMC: UapsdSessionRequired = %d\n", pMac->pmc.uapsdSessionRequired); + p += log_sprintf( pMac,p, " PMC: wowlModeRequired = %d\n\n", pMac->pmc.wowlModeRequired); + + pmcLog(pMac, LOGW, "\n%s", ptr); + + return p; +} + +static char * +dump_pmc_enable_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_IDLE_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_IDLE_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_request_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.impsEnabled = TRUE; + (void)pmcRequestImps(pMac, arg1, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_start_auto_bmps_timer( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + (void)pmcStartAutoBmpsTimer(pMac); + return p; +} + +static char * +dump_pmc_stop_auto_bmps_timer( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcStopAutoBmpsTimer(pMac); + return p; +} + +static char * +dump_pmc_enable_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_BEACON_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_BEACON_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_request_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + (void)sme_RequestBmps(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_enable_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_UAPSD_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_UAPSD_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_start_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.uapsdEnabled = TRUE; + (void)pmcStartUapsd(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_stop_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcStopUapsd(pMac); + return p; +} + +static char * +dump_pmc_request_standby( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.standbyEnabled = TRUE; + (void)pmcRequestStandby(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_request_full_power( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)sme_RequestFullPower(pMac, dump_pmc_callbackRoutine, pMac, eSME_FULL_PWR_NEEDED_BY_HDD); + return p; +} + +static char * +dump_pmc_enter_wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeWowlEnterParams wowlEnterParams; + tSirRetStatus status; + tANI_U32 length; + tANI_U8 sessionId = 0; + + (void) arg4; + + vos_mem_set(&wowlEnterParams, sizeof(tSirSmeWowlEnterParams), 0); + + if (arg1 == 0 && arg2 == 0) + { + pmcLog(pMac, LOGE, + "Requesting WoWL but neither magic pkt and ptrn byte matching is being enabled\n"); + return p; + } + if(arg1 == 1) + { + wowlEnterParams.ucMagicPktEnable = 1; + /* magic packet */ + length = SIR_MAC_ADDR_LENGTH; + status = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8 *)wowlEnterParams.magicPtrn, &length); + if (eSIR_SUCCESS != status) + { + pmcLog(pMac, LOGE, + "Reading of WNI_CFG_STA_ID from CFG failed. Using hardcoded STA MAC Addr\n"); + wowlEnterParams.magicPtrn[0] = 0x00; + wowlEnterParams.magicPtrn[1] = 0x0a; + wowlEnterParams.magicPtrn[2] = 0xf5; + wowlEnterParams.magicPtrn[3] = 0x04; + wowlEnterParams.magicPtrn[4] = 0x05; + wowlEnterParams.magicPtrn[5] = 0x06; + } + } + if(arg2 == 1) + { + wowlEnterParams.ucPatternFilteringEnable = 1; + } + + if(arg3 == CSR_ROAM_SESSION_MAX ) + { + pmcLog(pMac, LOGE, "Enter valid sessionId\n"); + return p; + } + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.wowlEnabled = TRUE; + + sessionId = (tANI_U8 ) arg3; +#ifdef WLAN_WAKEUP_EVENTS + (void)sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, dump_pmc_callbackRoutine2, pMac, + &wowlEnterParams, sessionId); +#else // WLAN_WAKEUP_EVENTS + (void)sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, &wowlEnterParams, sessionId); +#endif // WLAN_WAKEUP_EVENTS + return p; +} + +static char * +dump_pmc_exit_wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeWowlExitParams wowlExitParams; + + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)sme_ExitWowl(pMac, &wowlExitParams); + return p; +} + +static char * +dump_pmc_remove_ptrn( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirWowlDelBcastPtrn delPattern; + tANI_U8 sessionId = 0; + (void) arg3; (void) arg4; + + vos_mem_set(&delPattern, sizeof(tSirWowlDelBcastPtrn), 0); + + if((arg1 <= 7) || (arg2 == CSR_ROAM_SESSION_MAX)) + { + delPattern.ucPatternId = (tANI_U8)arg1; + } + else + { + pmcLog(pMac, LOGE, "dump_pmc_remove_ptrn: Invalid pattern Id %d\n",arg1); + return p; + } + + sessionId = (tANI_U8 ) arg2; + (void)pmcWowlDelBcastPattern(pMac, &delPattern, sessionId); + return p; +} + +static char * +dump_pmc_test_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeRsp smeRsp; + smeRsp.statusCode = eSIR_SME_SUCCESS; + + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + pMac->pmc.uapsdEnabled = TRUE; + pMac->pmc.pmcState = BMPS; + + pmcRegisterDeviceStateUpdateInd(pMac, dump_pmc_deviceUpdateRoutine, pMac); + + pmcStartUapsd(pMac, dump_pmc_callbackRoutine, pMac); + smeRsp.messageType = eWNI_PMC_ENTER_UAPSD_RSP; + pmcMessageProcessor(pMac, &smeRsp); + pmcStopUapsd(pMac); + smeRsp.messageType = eWNI_PMC_EXIT_UAPSD_RSP; + pmcMessageProcessor(pMac, &smeRsp); + pmcDeregisterDeviceStateUpdateInd(pMac, dump_pmc_deviceUpdateRoutine); + return p; +} + +static char * +dump_pmc_test_Wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeRsp smeRsp; + tSirWowlAddBcastPtrn addPattern; + tSirWowlDelBcastPtrn delPattern; + tSirSmeWowlEnterParams wowlEnterParams; + tSirSmeWowlExitParams wowlExitParams; + tANI_U8 sessionId = 0; + + smeRsp.statusCode = eSIR_SME_SUCCESS; + vos_mem_set(&addPattern, sizeof(tSirWowlAddBcastPtrn), 0); + vos_mem_set(&delPattern, sizeof(tSirWowlDelBcastPtrn), 0); + vos_mem_set(&wowlEnterParams, sizeof(tSirSmeWowlEnterParams), 0); + + (void) arg2; (void) arg3; (void) arg4; + + if(arg1 == CSR_ROAM_SESSION_MAX) + { + pmcLog(pMac, LOGE, "dump_pmc_test_Wowl: Invalid sessionId\n"); + return p; + } + + sessionId = (tANI_U8 ) arg1; + //Add pattern + sme_WowlAddBcastPattern(pMac, &addPattern, sessionId); + + //Delete pattern + sme_WowlDelBcastPattern(pMac, &delPattern, sessionId); + + //Force the device into BMPS + pMac->pmc.pmcState = BMPS; + + //Enter Wowl +#ifdef WLAN_WAKEUP_EVENTS + sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, dump_pmc_callbackRoutine2, pMac, + &wowlEnterParams, sessionId); +#else // WLAN_WAKEUP_EVENTS + sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, &wowlEnterParams, sessionId); +#endif // WLAN_WAKEUP_EVENTS + smeRsp.messageType = eWNI_PMC_ENTER_WOWL_RSP; + pmcMessageProcessor(pMac, &smeRsp); + + //Exit Wowl + sme_ExitWowl(pMac, &wowlExitParams); + smeRsp.messageType = eWNI_PMC_EXIT_WOWL_RSP; + pmcMessageProcessor(pMac, &smeRsp); + return p; +} + +static tDumpFuncEntry pmcMenuDumpTable[] = { + {0, "PMC (900-925)", NULL}, + // General + {900, "PMC: Dump State + config", dump_pmc_state}, + // IMPS Related + {901, "PMC: Enable IMPS", dump_pmc_enable_imps}, + {902, "PMC: Disable IMPS", dump_pmc_disable_imps}, + {903, "PMC: Request IMPS: Syntax: dump 903 ", dump_pmc_request_imps}, + // BMPS Related + {904, "PMC: Start Auto BMPS Timer", dump_pmc_start_auto_bmps_timer}, + {905, "PMC: Stop Auto BMPS Timer", dump_pmc_stop_auto_bmps_timer}, + {906, "PMC: Request BMPS", dump_pmc_request_bmps}, + // UAPSD Related + {907, "PMC: Enable UAPSD", dump_pmc_enable_uapsd}, + {908, "PMC: Disable UAPSD", dump_pmc_disable_uapsd}, + {909, "PMC: Start UAPSD", dump_pmc_start_uapsd}, + {910, "PMC: Stop UAPSD", dump_pmc_stop_uapsd}, + // Standby Related + {911, "PMC: Request Standby", dump_pmc_request_standby}, + // Full Power Related + {912, "PMC: Request Full Power", dump_pmc_request_full_power}, + //Unit Test Related + {913, "PMC: Test UAPSD", dump_pmc_test_uapsd}, + {914, "PMC: Test WOWL : Syntax :dump 914 ", dump_pmc_test_Wowl}, + // WoWL Related + {915, "PMC: Enter WoWL: Syntax: dump 915 ", dump_pmc_enter_wowl}, + {916, "PMC: Exit WoWL", dump_pmc_exit_wowl}, + {917, "PMC: Remove a pattern: Syntax: dump 917 >", dump_pmc_remove_ptrn}, + {918, "PMC: Enable BMPS", dump_pmc_enable_bmps}, + {919, "PMC: Disable BMPS", dump_pmc_disable_bmps} +}; + +void pmcDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal)hHal, &pmcMenuDumpTable[0], + sizeof(pmcMenuDumpTable)/sizeof(pmcMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/rrm/sme_rrm.c b/drivers/staging/qcacld-2.0/CORE/SME/src/rrm/sme_rrm.c new file mode 100644 index 0000000000000..83e52761939d9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/rrm/sme_rrm.c @@ -0,0 +1,1620 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/**========================================================================= + + \file sme_Rrm.c + + \brief implementation for SME RRM APIs + + ========================================================================*/ + +/* $Header$ */ + +#if defined WLAN_FEATURE_VOWIFI +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "smeInside.h" +#include "sme_Api.h" +#include "smsDebug.h" +#include "cfgApi.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#include "csrInsideApi.h" + +#include "rrmGlobal.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif + +/* Roam score for a neighbor AP will be calculated based on the below definitions. + The calculated roam score will be used to select the roamable candidate from neighbor AP list */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY 0 /* When we support 11r over the DS, this should have a non-zero value */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY 10 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE 20 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0 /* Not used */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS 5 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD 3 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM 8 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA 0 /* We dont support delayed BA */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA 3 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN 30 + +#ifdef FEATURE_WLAN_ESE +#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST 30 +#endif + +v_TIME_t RRM_scan_timer; + +/**--------------------------------------------------------------------------- + + \brief rrmLLPurgeNeighborCache() - + This function purges all the entries in the neighbor cache and frees up all the internal nodes + + \param - pMac - Pointer to the Hal Handle. + - pList - Pointer the List that should be purged. + \return - void + + --------------------------------------------------------------------------*/ +static void rrmLLPurgeNeighborCache(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pNeighborReportDesc; + + csrLLLock(pList); + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL) + { + pNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + vos_mem_free(pNeighborReportDesc->pNeighborBssDescription); + vos_mem_free(pNeighborReportDesc); + } + + csrLLUnlock(pList); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief rrmIndicateNeighborReportResult() - + This function calls the callback register by the caller while requesting for + neighbor report. This function gets invoked if a neighbor report is received from an AP + or neighbor response wait timer expires. + + \param - pMac - Pointer to the Hal Handle. + - vosStatus - VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE based on whether a valid report is + received or neighbor timer expired + \return - void + + --------------------------------------------------------------------------*/ +void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus) +{ + NeighborReportRspCallback callback; + void *callbackContext; + + /* Reset the neighbor response pending status */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE; + + /* Stop the timer if it is already running. The timer should be running only in the SUCCESS case. */ + if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer)) + { + smsLog( pMac, LOG1, FL("No entry in neighbor report cache")); + vos_timer_stop(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer); + } + callback = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback; + callbackContext = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext; + + /* Reset the callback and the callback context before calling the callback. It is very likely that there may be a registration in + callback itself. */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = NULL; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = NULL; + + /* Call the callback with the status received from caller */ + if (callback) + callback(callbackContext, vosStatus); +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + // We came here with IAPP AP List + // Make sure we inform CSR of the neighbor list + // for ESE Associations. First clear the cache. + else + if (csrNeighborRoamIsESEAssoc(pMac)) + { + ProcessIAPPNeighborAPList(pMac); + } +#endif + + return; + +} + +/**--------------------------------------------------------------------------- + + \brief sme_RrmBeaconReportXmitInd() - + + Create and send the beacon report Xmit ind message to PE. + + \param - pMac - Pointer to the Hal Handle. + - pResult - scan result. + - measurementDone - flag to indicate that the measurement is done. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, + tCsrScanResultInfo **pResultArr, + tANI_U8 measurementDone, + tANI_U8 bss_count ) +{ + tpSirBssDescription pBssDesc = NULL; + tpSirBeaconReportXmitInd pBeaconRep; + tANI_U16 length, ie_len; + tANI_U8 bssCounter=0, msgCounter=0; + tCsrScanResultInfo *pCurResult=NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Beacon report xmit Ind to PE"); +#endif + + if( NULL == pResultArr && !measurementDone ) + { + smsLog( pMac, LOGE, "Beacon report xmit Ind to PE Failed"); + return eHAL_STATUS_FAILURE; + } + + if (pResultArr) + pCurResult=pResultArr[bssCounter]; + + do + { + length = sizeof(tSirBeaconReportXmitInd); + pBeaconRep = vos_mem_malloc ( length ); + if ( NULL == pBeaconRep ) + { + smsLog( pMac, LOGP, "Unable to allocate memory for beacon report"); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero( pBeaconRep, length ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for pBeaconRep")); +#endif + pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND; + pBeaconRep->length = length; + pBeaconRep->uDialogToken = pSmeRrmContext->token; + pBeaconRep->duration = pSmeRrmContext->duration[0]; + pBeaconRep->regClass = pSmeRrmContext->regClass; + vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) ); + + msgCounter=0; + while (pCurResult) + { + pBssDesc = &pCurResult->BssDescriptor; + if(pBssDesc != NULL) + { + ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length ); + pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( + ie_len+sizeof(tSirBssDescription)); + if (NULL == pBeaconRep->pBssDescription[msgCounter]) + break; + vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], + pBssDesc, + sizeof(tSirBssDescription) ); + vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0], + pBssDesc->ieFields, ie_len ); + smsLog( pMac, LOG1, + "...RRM Result Bssid = "MAC_ADDRESS_STR" chan= %d, rssi = -%d", + MAC_ADDR_ARRAY(pBeaconRep->pBssDescription[msgCounter]->bssId), + pBeaconRep->pBssDescription[msgCounter]->channelId, + pBeaconRep->pBssDescription[msgCounter]->rssi * (-1)); + + pBeaconRep->numBssDesc++; + + if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + + pCurResult = pResultArr[bssCounter + msgCounter]; + } + else + { + pCurResult = NULL; + break; + } + } + + bssCounter+=msgCounter; + if (!pResultArr || (pCurResult == NULL) || (bssCounter >= bss_count)) + { + pCurResult = NULL; + smsLog(pMac, LOG1, + "Reached to the max/last BSS in pCurResult list"); + } + else + { + pCurResult = pResultArr[bssCounter]; + smsLog(pMac, LOG1, + "Move to the next BSS set in pCurResult list"); + } + + pBeaconRep->fMeasureDone = (pCurResult)?false:measurementDone; + + smsLog(pMac, LOG1, + "SME Sending BcnRepXmit to PE numBss %d msgCounter %d bssCounter %d", + pBeaconRep->numBssDesc, msgCounter, bssCounter); + + status = palSendMBMessage(pMac->hHdd, pBeaconRep); + + } while (pCurResult); + + return status; +} + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief sme_EseSendBeaconReqScanResults() + + This function sends up the scan results received as a part of + beacon request scanning. + This function is called after receiving the scan results per channel + Due to the limitation on the size of the IWEVCUSTOM buffer, we send 3 BSSIDs of + beacon report information in one custom event; + + \param - pMac - Pointer to the Hal Handle. + - sessionId - Session id + - channel - scan results belongs to this channel + - pResultArr - scan result. + - measurementDone - flag to indicate that the measurement is done. + - bss_count - number of bss found + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_EseSendBeaconReqScanResults(tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 channel, + tCsrScanResultInfo **pResultArr, + tANI_U8 measurementDone, + tANI_U8 bss_count) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirRetStatus fillIeStatus; + tpSirBssDescription pBssDesc = NULL; + tANI_U32 ie_len = 0; + tANI_U32 outIeLen = 0; + tANI_U8 bssCounter = 0; + tCsrScanResultInfo *pCurResult = NULL; + tANI_U8 msgCounter = 0; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tCsrRoamInfo roamInfo; + tSirEseBcnReportRsp bcnReport; + tpSirEseBcnReportRsp pBcnReport = &bcnReport; + tpCsrEseBeaconReqParams pCurMeasReqIe = NULL; + tANI_U8 i = 0; + + if (NULL == pSmeRrmContext) + { + smsLog( pMac, LOGE, "pSmeRrmContext is NULL"); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pResultArr && !measurementDone) + { + smsLog( pMac, LOGE, "Beacon report xmit Ind to HDD Failed"); + return eHAL_STATUS_FAILURE; + } + + if (pResultArr) + pCurResult=pResultArr[bssCounter]; + + vos_mem_zero(&bcnReport, sizeof(tSirEseBcnReportRsp)); + do + { + pCurMeasReqIe = NULL; + for (i = 0; i < pSmeRrmContext->eseBcnReqInfo.numBcnReqIe; i++) + { + if(pSmeRrmContext->eseBcnReqInfo.bcnReq[i].channel == channel) + { + pCurMeasReqIe = &pSmeRrmContext->eseBcnReqInfo.bcnReq[i]; + break; + } + } + if(NULL != pCurMeasReqIe) + pBcnReport->measurementToken = pCurMeasReqIe->measurementToken; + smsLog( pMac, LOG1, "Channel(%d) MeasToken(%d)", channel, pBcnReport->measurementToken); + + msgCounter=0; + while (pCurResult) + { + pBssDesc = &pCurResult->BssDescriptor; + if (NULL != pBssDesc) + { + ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length ); + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ChanNum = pBssDesc->channelId; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Spare = 0; + if(NULL != pCurMeasReqIe) + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.MeasDuration = pCurMeasReqIe->measurementDuration; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.PhyType = pBssDesc->nwType; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.RecvSigPower = pBssDesc->rssi; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ParentTsf = pBssDesc->parentTSF; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[0] = pBssDesc->timeStamp[0]; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[1] = pBssDesc->timeStamp[1]; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.BcnInterval = pBssDesc->beaconInterval; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.CapabilityInfo = pBssDesc->capabilityInfo; + vos_mem_copy(pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Bssid, + pBssDesc->bssId, sizeof(tSirMacAddr)); + + fillIeStatus = sirFillBeaconMandatoryIEforEseBcnReport(pMac, + (tANI_U8 *)pBssDesc->ieFields, + ie_len, + &(pBcnReport->bcnRepBssInfo[msgCounter].pBuf), + &outIeLen); + if (eSIR_FAILURE == fillIeStatus) + { + continue; + } + pBcnReport->bcnRepBssInfo[msgCounter].ieLen = outIeLen; + + smsLog( pMac, LOG1,"Bssid("MAC_ADDRESS_STR") Channel=%d Rssi=%d", + MAC_ADDR_ARRAY(pBssDesc->bssId), + pBssDesc->channelId, (-1) * pBssDesc->rssi); + + pBcnReport->numBss++; + + if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + + pCurResult = pResultArr[msgCounter]; + } + else + { + pCurResult = NULL; + break; + } + } + + bssCounter += msgCounter; + if (!pResultArr || !pCurResult || (bssCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)) + { + pCurResult = NULL; + smsLog(pMac, LOGE, + "Reached to the max/last BSS in pCurResult list"); + } + else + { + pCurResult = pResultArr[bssCounter]; + smsLog(pMac, LOGE, + "Move to the next BSS set in pCurResult list"); + } + + pBcnReport->flag = (measurementDone << 1)|((pCurResult)?true:false); + + smsLog(pMac, LOG1, "SME Sending BcnRep to HDD numBss(%d)" + " msgCounter(%d) bssCounter(%d) flag(%d)", + pBcnReport->numBss, msgCounter, bssCounter, pBcnReport->flag); + + roamInfo.pEseBcnReportRsp = pBcnReport; + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, + 0, eCSR_ROAM_ESE_BCN_REPORT_IND, 0); + + /* Free the memory allocated to IE */ + for (i = 0; i < msgCounter; i++) + { + if (pBcnReport->bcnRepBssInfo[i].pBuf) + vos_mem_free(pBcnReport->bcnRepBssInfo[i].pBuf); + } + } while (pCurResult); + return status; +} + +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +/**--------------------------------------------------------------------------- + + \brief sme_RrmSendScanRequest() - + + This function is called to get the scan result from CSR and send the beacon report + xmit ind message to PE. + + \param - pMac - Pointer to the Hal Handle. + - num_chan - number of channels. + - channel list - list of channels to fetch the result from. + - measurementDone - flag to indicate that the measurement is done. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, + tANI_U8 num_chan, + tANI_U8* chanList, + tANI_U8 measurementDone ) +{ + tCsrScanResultFilter filter; + tScanResultHandle pResult; + tCsrScanResultInfo *pScanResult, *pNextResult; + tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC]; + eHalStatus status; + tANI_U8 counter=0; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 sessionId; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Send scan result to PE "); +#endif + + vos_mem_zero( &filter, sizeof(filter) ); + vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC ); + + filter.BSSIDs.numOfBSSIDs = 1; + filter.BSSIDs.bssid = &pSmeRrmContext->bssId; + + if( pSmeRrmContext->ssId.length ) + { + filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if( filter.SSIDs.SSIDList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for SSIDList")); +#endif + vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) ); + + filter.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length; + vos_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length); + filter.SSIDs.numOfSSIDs = 1; + } + else + { + filter.SSIDs.numOfSSIDs = 0; + } + + filter.ChannelInfo.numOfChannels = num_chan; + filter.ChannelInfo.ChannelList = chanList; + + filter.fMeasurement = TRUE; + + /* + * In case this is beacon report request from last AP (before roaming) + * following call to csrRoamGetSessionIdFromBSSID will fail, hence use + * current session ID instead of one stored in SME rrm context + */ + if (eHAL_STATUS_FAILURE == + csrRoamGetSessionIdFromBSSID(pMac, + (tCsrBssid*)pSmeRrmContext->sessionBssId, + &sessionId )) { + smsLog( pMac, LOG1, FL("BSSID mismatch, using current sessionID")); + sessionId = pMac->roam.roamSession->sessionId; + } + + status = sme_ScanGetResult(pMac, (tANI_U8)sessionId, &filter, &pResult); + + if( filter.SSIDs.SSIDList ) + { + //Free the memory allocated for SSIDList. + vos_mem_free( filter.SSIDs.SSIDList ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for SSIDList") ); +#endif + } + + if (NULL == pResult) + { + // no scan results + // + // Spec. doesnt say anything about such condition. + // Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report frame should contain + // one or more report IEs. It probably means dont send any respose if no matching + // BSS found. Moreover, there is no flag or field in measurement report IE(7.3.2.22) + // OR beacon report IE(7.3.2.22.6) that can be set to indicate no BSS found on a given channel. + // + // If we finished measurement on all the channels, we still need to + // send a xmit indication with moreToFollow set to MEASURMENT_DONE + // so that PE can clean any context allocated. + if( measurementDone ) + { +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + NULL, + measurementDone, + 0); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0); + } + return status; + } + + pScanResult = sme_ScanResultGetFirst(pMac, pResult); + + if( NULL == pScanResult && measurementDone ) + { +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + NULL, + measurementDone, + 0); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 ); + } + + counter=0; + while (pScanResult) + { + pNextResult = sme_ScanResultGetNext(pMac, pResult); + if(pScanResult->timer >= RRM_scan_timer) + { + pScanResultsArr[counter++] = pScanResult; + } + pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult); + if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + } + + if (counter) + { + smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ", counter); +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + pScanResultsArr, + measurementDone, + counter); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, + pScanResultsArr, + measurementDone, + counter); + } + sme_ScanResultPurge(pMac, pResult); + + return status; +} +/**--------------------------------------------------------------------------- + + \brief sme_RrmScanRequestCallback() - + + The sme module calls this callback function once it finish the scan request + and this function send the beacon report xmit to PE and starts a timer of + random interval to issue next request. + + \param - halHandle - Pointer to the Hal Handle. + - pContext - Pointer to the data context. + - scanId - Scan ID. + - status - CSR Status. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static eHalStatus sme_RrmScanRequestCallback(tHalHandle halHandle, + void *pContext, + tANI_U8 sessionId, + tANI_U32 scanId, + eCsrScanStatus status) +{ + + tANI_U16 interval; + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 time_tick; + + + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Scan Request callback "); +#endif + //if any more channels are pending, start a timer of a random value within randomization interval. + // + // + if( (pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels ) + { + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false ); + + pSmeRrmContext->currentIndex++; //Advance the current index. + //start the timer to issue next request. + //From timer tick get a random number within 10ms and max randmization interval. + time_tick = vos_timer_get_system_ticks(); + interval = time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Set timer for interval %d ", interval); +#endif + vos_timer_start( &pSmeRrmContext->IterMeasTimer, interval ); + + } + else + { + //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set. + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true ); + vos_mem_free( pSmeRrmContext->channelList.ChannelList ); +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + pSmeRrmContext->eseBcnReqInProgress = FALSE; +#endif +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for ChannelList") ); +#endif + } + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmIssueScanReq() - This is called to send a scan request as part + of beacon report request . + + \param pMac - pMac global pointer + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmIssueScanReq( tpAniSirGlobal pMac ) +{ + //Issue scan request. + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 sessionId; + tSirScanType scanType; + + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId ); + if( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, "%s : Invalid sme Session ID", __func__); + return eHAL_STATUS_FAILURE; + } + + if ((pSmeRrmContext->currentIndex) >= pSmeRrmContext->channelList.numOfChannels) + return status; + + if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource || + eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource ) + scanType = pSmeRrmContext->measMode[pSmeRrmContext->currentIndex]; + else + scanType = pSmeRrmContext->measMode[0]; + + if ((eSIR_ACTIVE_SCAN == scanType) || (eSIR_PASSIVE_SCAN == scanType)) + { +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Issue scan request " ); +#endif + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + /* set scanType, active or passive */ + scanRequest.bcnRptReqScan = TRUE; + scanRequest.scanType = scanType; + + vos_mem_copy(scanRequest.bssid, + pSmeRrmContext->bssId, sizeof(scanRequest.bssid) ); + + if (pSmeRrmContext->ssId.length) + { + scanRequest.SSIDs.numOfSSIDs = 1; + scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if (NULL == scanRequest.SSIDs.SSIDList) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList")); +#endif + vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) ); + scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length; + vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length); + } + + /* set min and max channel time */ + scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout. + if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource || + eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource ) + scanRequest.maxChnTime = pSmeRrmContext->duration[pSmeRrmContext->currentIndex]; + else + scanRequest.maxChnTime = pSmeRrmContext->duration[0]; + + smsLog( pMac, LOG1, "Scan Type(%d) Max Dwell Time(%d)", scanRequest.scanType, + scanRequest.maxChnTime ); + + RRM_scan_timer = vos_timer_get_system_time(); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "For Duration %d ", scanRequest.maxChnTime ); +#endif + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 1; + + scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex]; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "On channel %d ", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] ); +#endif + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL ); + + if ( pSmeRrmContext->ssId.length ) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for SSIDList")); +#endif + } + } + else if (eSIR_BEACON_TABLE == scanType) /* beacon table */ + { + /*In beacon table mode, scan results are taken directly from scan cache + without issuing any scan request. So, it is not proper to update + RRM_scan_timer with latest time and hence made it to zero to satisfy + pScanResult->timer >= RRM_scan_timer */ + RRM_scan_timer = 0; + + if ((pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels) + { + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false ); + pSmeRrmContext->currentIndex++; //Advance the current index. + sme_RrmIssueScanReq(pMac); +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + pSmeRrmContext->eseBcnReqInProgress = FALSE; +#endif + } + else + { + //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set. + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true ); + vos_mem_free( pSmeRrmContext->channelList.ChannelList ); + } + } + else + { + smsLog( pMac, LOGE, "Unknown beacon report request mode(%d)", scanType); + /* Indicate measurement completion to PE */ + /* If this is not done, pCurrentReq pointer will not be freed and + PE will not handle subsequent Beacon requests */ + sme_RrmSendBeaconReportXmitInd(pMac, NULL, true, 0); + } + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmProcessBeaconReportReqInd() - This is called to process the Beacon + report request from peer AP forwarded through PE . + + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 len = 0, i = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d", pBeaconReq->channelInfo.channelNum ); +#endif + //section 11.10.8.1 (IEEE Std 802.11k-2008) + //channel 0 and 255 has special meaning. + if( (pBeaconReq->channelInfo.channelNum == 0) || + ((pBeaconReq->channelInfo.channelNum == 255) && (pBeaconReq->channelList.numChannels == 0) ) ) + { + //Add all the channel in the regulatory domain. + wlan_cfgGetStrLen( pMac, WNI_CFG_VALID_CHANNEL_LIST, &len ); + pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len ); + if( pSmeRrmContext->channelList.ChannelList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") ); +#endif + csrGetCfgValidChannels( pMac, pSmeRrmContext->channelList.ChannelList, &len ); + pSmeRrmContext->channelList.numOfChannels = (tANI_U8)len; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "channel == 0 performing on all channels"); +#endif + } + else + { + len = 0; + pSmeRrmContext->channelList.numOfChannels = 0; + + //If valid channel is present. We first Measure on the given channel. and + //if there are additional channels present in APchannelreport, measure on these also. + if ( pBeaconReq->channelInfo.channelNum != 255 ) + len = 1; +#if defined WLAN_VOWIFI_DEBUG + else + smsLog( pMac, LOGE, "channel == 255"); +#endif + + len += pBeaconReq->channelList.numChannels; + + pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len ); + if( pSmeRrmContext->channelList.ChannelList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") ); +#endif + + if ( pBeaconReq->channelInfo.channelNum != 255 ) + { +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "channel == %d ", pBeaconReq->channelInfo.channelNum ); +#endif + if(csrRoamIsChannelValid( pMac, pBeaconReq->channelInfo.channelNum )) + pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels++] = pBeaconReq->channelInfo.channelNum; +#if defined WLAN_VOWIFI_DEBUG + else + smsLog( pMac, LOGE, "is Invalid channel, Ignoring this channel" ); +#endif + } + + for ( i = 0 ; i < pBeaconReq->channelList.numChannels; i++ ) + { + if(csrRoamIsChannelValid( pMac, pBeaconReq->channelList.channelNumber[i] )) + { + pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels] = pBeaconReq->channelList.channelNumber[i]; + pSmeRrmContext->channelList.numOfChannels++; + } + } + } + + //Copy session bssid + vos_mem_copy( pSmeRrmContext->sessionBssId, pBeaconReq->bssId, sizeof(tSirMacAddr) ); + + //copy measurement bssid + vos_mem_copy( pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, sizeof(tSirMacAddr) ); + + //Copy ssid + vos_mem_copy( &pSmeRrmContext->ssId, &pBeaconReq->ssId, sizeof(tAniSSID) ); + + pSmeRrmContext->token = pBeaconReq->uDialogToken; + pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass; + pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval ); + pSmeRrmContext->currentIndex = 0; + pSmeRrmContext->msgSource = pBeaconReq->msgSource; + vos_mem_copy((tANI_U8*)&pSmeRrmContext->measMode, (tANI_U8*)&pBeaconReq->fMeasurementtype, SIR_ESE_MAX_MEAS_IE_REQS); + vos_mem_copy((tANI_U8*)&pSmeRrmContext->duration, (tANI_U8*)&pBeaconReq->measurementDuration, SIR_ESE_MAX_MEAS_IE_REQS); + + status = sme_RrmIssueScanReq( pMac ); + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmNeighborReportRequest() - This is API can be used to trigger a + Neighbor report from the peer. + + \param sessionId - session identifier on which the request should be made. + \param pNeighborReq - a pointer to a neighbor report request. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, + tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirNeighborReportReqInd pMsg; + tCsrRoamSession *pSession; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Request to send Neighbor report request received ")); +#endif + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + smsLog( pMac, LOGE, FL("Invalid session %d"), sessionId ); + return VOS_STATUS_E_INVAL; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + + /* If already a report is pending, return failure */ + if (eANI_BOOLEAN_TRUE == pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending) + { + smsLog( pMac, LOGE, FL("Neighbor request already pending.. Not allowed")); + return VOS_STATUS_E_AGAIN; + } + + pMsg = vos_mem_malloc ( sizeof(tSirNeighborReportReqInd) ); + if ( NULL == pMsg ) + { + smsLog( pMac, LOGE, "Unable to allocate memory for Neighbor request"); + return VOS_STATUS_E_NOMEM; + } + + + vos_mem_zero( pMsg, sizeof(tSirNeighborReportReqInd) ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL(" Allocated memory for Neighbor request") ); +#endif + + rrmLLPurgeNeighborCache(pMac, &pMac->rrm.rrmSmeContext.neighborReportCache); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Purged the neighbor cache before sending Neighbor request: Status = %d"), status ); +#endif + + pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND; + pMsg->length = sizeof( tSirNeighborReportReqInd ); + vos_mem_copy( &pMsg->bssId, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + pMsg->noSSID = pNeighborReq->no_ssid; + vos_mem_copy( &pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + if( status != eHAL_STATUS_SUCCESS ) + return VOS_STATUS_E_FAILURE; + + /* Neighbor report request message sent successfully to PE. Now register the callbacks */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = + callbackInfo->neighborRspCallback; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = + callbackInfo->neighborRspCallbackContext; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_TRUE; + + /* Start neighbor response wait timer now */ + vos_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer, callbackInfo->timeout); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief rrmCalculateNeighborAPRoamScore() - This API is called while handling + individual neighbor reports from the APs neighbor AP report to + calculate the cumulative roam score before storing it in neighbor + cache. + + \param pNeighborReportDesc - Neighbor BSS Descriptor node for which roam score + should be calculated + + \return void. +--------------------------------------------------------------------------*/ +static void rrmCalculateNeighborAPRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc) +{ + tpSirNeighborBssDescripton pNeighborBssDesc; + tANI_U32 roamScore = 0; +#ifdef FEATURE_WLAN_ESE + tANI_U8 sessionId; +#endif + + if (NULL == pNeighborReportDesc) + { + VOS_ASSERT(0); + return; + } + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + VOS_ASSERT(0); + return; + } + + pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription; + + if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY; + } + } + } + } +#ifdef FEATURE_WLAN_ESE + sessionId = pNeighborReportDesc->sessionId; + /* It has come in the report so its the best score */ + if (csrNeighborRoamIs11rAssoc(pMac, sessionId) == FALSE) { + /* IAPP Route so lets make use of this info + * save all AP, as the list does not come all the time + * Save and reuse till the next AP List comes to us. + * Even save our own MAC address. Will be useful next time around. + */ + roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST; + } +#endif + pNeighborReportDesc->roamScore = roamScore; + + return; +} + +/*-------------------------------------------------------------------------- + \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given + Neighbor BSS descriptor to the neighbor cache. This function + stores the neighbor BSS descriptors in such a way that descriptors + are sorted by roamScore in descending order + + \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache + + \return void. +--------------------------------------------------------------------------*/ +void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc) +{ + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tListElem *pEntry; + tRrmNeighborReportDesc *pTempNeighborReportDesc; + + if (NULL == pNeighborReportDesc) + { + VOS_ASSERT(0); + return; + } + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + VOS_ASSERT(0); + return; + } + + if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK)) + { + smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now")); + /* Neighbor list cache is empty. Insert this entry in the tail */ + csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + return; + } + else + { + /* Should store the neighbor BSS description in the order sorted by roamScore in descending + order. APs with highest roamScore should be the 1st entry in the list */ + pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK); + while (pEntry != NULL) + { + pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore) + break; + pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK); + } + + if (pEntry) + /* This BSS roamscore is better than something in the list. Insert this before that one */ + csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + else + /* All the entries in the list has a better roam Score than this one. Insert this at the last */ + csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + } + return; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor + report received from PE. + + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf; + tpRrmNeighborReportDesc pNeighborReportDesc; + tANI_U8 i = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tANI_U8 sessionId; + + /* Get the session id */ + status = csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)pNeighborRpt->bssId, + (tANI_U32*) &sessionId); + if (HAL_STATUS_SUCCESS(status)) { +#ifdef FEATURE_WLAN_ESE + /* Clear the cache for ESE. */ + if (csrNeighborRoamIsESEAssoc(pMac, sessionId)) { + rrmLLPurgeNeighborCache(pMac, + &pMac->rrm.rrmSmeContext.neighborReportCache); + } +#endif + } + + for (i = 0; i < pNeighborRpt->numNeighborReports; i++) + { + pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc)); + if (NULL == pNeighborReportDesc) + { + smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc"); + status = eHAL_STATUS_FAILED_ALLOC; + goto end; + + } + + vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc)); + pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription)); + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description"); + vos_mem_free(pNeighborReportDesc); + status = eHAL_STATUS_FAILED_ALLOC; + goto end; + } + vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription)); + vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i], + sizeof(tSirNeighborBssDescription)); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId)); +#endif + + /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */ + rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc); + + /* Store the Neighbor report Desc in the cache based on the roam score */ + if ( pNeighborReportDesc->roamScore > 0) + { + rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc); + } + else + { + smsLog(pMac, LOGE, FL("Roam score of BSSID "MAC_ADDRESS_STR" is 0, Ignoring.."), + MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId)); + + vos_mem_free(pNeighborReportDesc->pNeighborBssDescription); + vos_mem_free(pNeighborReportDesc); + } + } +end: + + if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache)) + vosStatus = VOS_STATUS_E_FAILURE; + + /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */ + rrmIndicateNeighborReportResult(pMac, vosStatus); + + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME RRM module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf) +{ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL(" Msg = %d for RRM measurement") , msg_type ); + + //switch on the msg type & make the state transition accordingly + switch(msg_type) + { + case eWNI_SME_NEIGHBOR_REPORT_IND: + sme_RrmProcessNeighborReport( pMac, pMsgBuf ); + break; + + case eWNI_SME_BEACON_REPORT_REQ_IND: + sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf ); + break; + + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("sme_RrmMsgProcessor:unknown msg type = %d"), msg_type); + + break; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn rrmIterMeasTimerHandle + + \brief Timer handler to handlet the timeout condition when a specific BT + + stop event does not come back, in which case to restore back the + + heartbeat timer. + + \param pMac - The handle returned by macOpen. + + \return VOID + + ---------------------------------------------------------------------------*/ + +void rrmIterMeasTimerHandle( v_PVOID_t userData ) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) userData; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Randomization timer expired...send on next channel "); +#endif + //Issue a scan req for next channel. + sme_RrmIssueScanReq( pMac ); +} + +/* --------------------------------------------------------------------------- + + \fn rrmNeighborRspTimeoutHandler + + \brief Timer handler to handle the timeout condition when a neighbor request is sent + and no neighbor response is received from the AP + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ + +void rrmNeighborRspTimeoutHandler +( v_PVOID_t userData ) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) userData; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Neighbor Response timed out "); +#endif + rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE); + return; +} + +/* --------------------------------------------------------------------------- + + \fn rrmOpen + + \brief + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + VOS_STATUS_E_FAILURE success + + VOS_STATUS_SUCCESS failure + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmOpen (tpAniSirGlobal pMac) + +{ + + VOS_STATUS vosStatus; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms + + vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer, + + VOS_TIMER_TYPE_SW, + + rrmIterMeasTimerHandle, + + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer"); + + return VOS_STATUS_E_FAILURE; + } + + vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer, + + VOS_TIMER_TYPE_SW, + + rrmNeighborRspTimeoutHandler, + + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer"); + + return VOS_STATUS_E_FAILURE; + } + + pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE; + + halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache); + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result"); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + +/* --------------------------------------------------------------------------- + + \fn rrmClose + + \brief + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + VOS_STATUS_E_FAILURE success + + VOS_STATUS_SUCCESS failure + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmClose (tpAniSirGlobal pMac) + +{ + + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) ) + { + vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer ); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") ); + } + } + + vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") ); + + } + + if( VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) ) + { + vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") ); + } + } + + vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") ); + + } + + rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache); + + csrLLClose(&pSmeRrmContext->neighborReportCache); + + return vosStatus; + +} + + + + +/* --------------------------------------------------------------------------- + + \fn rrmReady + + \brief fn + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmReady (tpAniSirGlobal pMac) + +{ + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn rrmChangeDefaultConfigParam + \brief fn + + \param pMac - The handle returned by macOpen. + \param pRrmConfig - pointer to new rrm configs. + + \return VOS_STATUS + + ---------------------------------------------------------------------------*/ +VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig) +{ + vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) ); + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn smeRrmGetFirstBssEntryFromNeighborCache() + + \brief This function returns the first entry from the neighbor cache to the caller + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pTempBssEntry = NULL; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + + pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK ); + + if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache)) + { + //list empty + smsLog(pMac, LOGW, FL("List empty")); + return NULL; + } + + pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + + return pTempBssEntry; +} + +/* --------------------------------------------------------------------------- + + \fn smeRrmGetNextBssEntryFromNeighborCache() + + \brief This function returns the entry next to the given entry from the + neighbor cache to the caller + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac, + tpRrmNeighborReportDesc pBssEntry) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pTempBssEntry = NULL; + + pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK); + + if(!pEntry) + { + //list empty + smsLog(pMac, LOGW, FL("List empty")); + return NULL; + } + + pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + + return pTempBssEntry; +} + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void csrEseSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession) +{ + tpSirAdjacentApRepInd pAdjRep; + tANI_U16 length; + tANI_U32 roamTS2; + + smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE"); + + length = sizeof(tSirAdjacentApRepInd ); + pAdjRep = vos_mem_malloc ( length ); + + if ( NULL == pAdjRep ) + { + smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report"); + return; + } + + vos_mem_zero( pAdjRep, length ); + pAdjRep->messageType = eWNI_SME_ESE_ADJACENT_AP_REPORT; + pAdjRep->length = length; + pAdjRep->channelNum = pSession->prevOpChannel; + vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) ); + vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) ); + roamTS2 = vos_timer_get_system_time(); + pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1; + pAdjRep->roamReason =SIR_ESE_ASSOC_REASON_UNSPECIFIED; + pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000); + + palSendMBMessage(pMac->hHdd, pAdjRep); + + return; +} +#endif /* FEATURE_WLAN_ESE */ +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c new file mode 100644 index 0000000000000..6f2b350cba07b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c @@ -0,0 +1,14333 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/**========================================================================= + + \file smeApi.c + + \brief Definitions for SME APIs + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure + +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include "smsDebug.h" +#include "sme_Api.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "csrInternal.h" +#include "wlan_qct_wda.h" +#include "halMsgApi.h" +#include "vos_trace.h" +#include "sme_Trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_utils.h" +#include "sapApi.h" +#include "macTrace.h" +#ifdef WLAN_FEATURE_NAN +#include "nan_Api.h" +#endif +#include "regdomain_common.h" + +extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); + +#include +#define LOG_SIZE 256 +#define READ_MEMORY_DUMP_CMD 9 +#define TL_INIT_STATE 0 + +static tSelfRecoveryStats gSelfRecoveryStats; + + +// TxMB Functions +extern eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tSmeCmd **ppCmd); +extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +extern void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +extern eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn); +extern eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); +extern eHalStatus sme_mgmtFrmInd( tHalHandle hHal, tpSirSmeMgmtFrameInd pSmeMgmtFrm); +extern eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg); +extern eHalStatus sme_sendActionCnf( tHalHandle hHal, tANI_U8* pMsg); +extern eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd); + +static eHalStatus initSmeCmdList(tpAniSirGlobal pMac); +static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); + +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal); + +eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); + +void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac); + +eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); + +eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal, void *pMsgBuf); + +eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId); +#endif + +#ifdef WLAN_FEATURE_11W +eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, + tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm ); +#endif + +/* Message processor for events from DFS */ +eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, + v_U16_t msg_type,void *pMsgBuf); + +/* Channel Change Response Indication Handler */ +eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac, + v_U16_t msg_type,void *pMsgBuf); + +//Internal SME APIs +eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psSme) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psSme->lkSmeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + +eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psSme) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psSme->lkSmeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + + +static eHalStatus initSmeCmdList(tpAniSirGlobal pMac) +{ + eHalStatus status; + tSmeCmd *pCmd; + tANI_U32 cmd_idx; + VOS_STATUS vosStatus; + vos_timer_t* cmdTimeoutTimer = NULL; + + pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND; + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdActiveList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdPendingList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeScanCmdActiveList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeScanCmdPendingList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdFreeList))) + goto end; + + pCmd = vos_mem_malloc(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd); + if ( NULL == pCmd ) + status = eHAL_STATUS_FAILURE; + else + { + status = eHAL_STATUS_SUCCESS; + + vos_mem_set(pCmd, sizeof(tSmeCmd) * pMac->sme.totalSmeCmd, 0); + pMac->sme.pSmeCmdBufAddr = pCmd; + + for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) + { + csrLLInsertTail(&pMac->sme.smeCmdFreeList, + &pCmd[cmd_idx].Link, LL_ACCESS_LOCK); + } + } + + /* This timer is only to debug the active list command timeout */ + + cmdTimeoutTimer = (vos_timer_t*)vos_mem_malloc(sizeof(vos_timer_t)); + if (cmdTimeoutTimer) + { + pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer; + vosStatus = + vos_timer_init( pMac->sme.smeCmdActiveList.cmdTimeoutTimer, + VOS_TIMER_TYPE_SW, + activeListCmdTimeoutHandle, + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Init Timer fail for active list command process time out"); + vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + } + else + { + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; + } + } +end: + if (!HAL_STATUS_SUCCESS(status)) + smsLog(pMac, LOGE, "failed to initialize sme command list:%d\n", + status); + + return (status); +} + + +void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd) +{ + pCmd->command = eSmeNoCommand; + csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK); +} + + + +static void smeReleaseCmdList(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_LOCK)) != NULL) + { + //TODO: base on command type to call release functions + //reinitialize different command types so they can be reused + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } +} + +static void purgeSmeCmdList(tpAniSirGlobal pMac) +{ + //release any out standing commands back to free command list + smeReleaseCmdList(pMac, &pMac->sme.smeCmdPendingList); + smeReleaseCmdList(pMac, &pMac->sme.smeCmdActiveList); + smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdPendingList); + smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdActiveList); +} + +void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tDblLinkList *pList) +{ + //release any out standing commands back to free command list + tListElem *pEntry, *pNext; + tSmeCmd *pCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while(pEntry != NULL) + { + pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(pCommand->sessionId == sessionId) + { + if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + } + pEntry = pNext; + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } + csrLLClose(&localList); +} + + +static eHalStatus freeSmeCmdList(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + purgeSmeCmdList(pMac); + csrLLClose(&pMac->sme.smeCmdPendingList); + csrLLClose(&pMac->sme.smeCmdActiveList); + csrLLClose(&pMac->sme.smeScanCmdPendingList); + csrLLClose(&pMac->sme.smeScanCmdActiveList); + csrLLClose(&pMac->sme.smeCmdFreeList); + + /*destroy active list command time out timer */ + vos_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL; + + status = vos_lock_acquire(&pMac->sme.lkSmeGlobalLock); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Failed to acquire the lock status = %d"), status); + goto done; + } + + if(NULL != pMac->sme.pSmeCmdBufAddr) + { + vos_mem_free(pMac->sme.pSmeCmdBufAddr); + pMac->sme.pSmeCmdBufAddr = NULL; + } + + status = vos_lock_release(&pMac->sme.lkSmeGlobalLock); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Failed to release the lock status = %d"), status); + } +done: + return (status); +} + + +void dumpCsrCommandInfo(tpAniSirGlobal pMac, tSmeCmd *pCmd) +{ + switch( pCmd->command ) + { + case eSmeCommandScan: + smsLog( pMac, LOGE, " scan command reason is %d", pCmd->u.scanCmd.reason ); + break; + + case eSmeCommandRoam: + smsLog( pMac, LOGE, " roam command reason is %d", pCmd->u.roamCmd.roamReason ); + break; + + case eSmeCommandWmStatusChange: + smsLog( pMac, LOGE, " WMStatusChange command type is %d", pCmd->u.wmStatusChangeCmd.Type ); + break; + + case eSmeCommandSetKey: + smsLog( pMac, LOGE, " setKey command auth(%d) enc(%d)", + pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType ); + break; + + case eSmeCommandRemoveKey: + smsLog( pMac, LOGE, " removeKey command auth(%d) enc(%d)", + pCmd->u.removeKeyCmd.authType, pCmd->u.removeKeyCmd.encType ); + break; + + default: + smsLog( pMac, LOGE, " default: Unhandled command %d", + pCmd->command); + break; + } +} + +tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac ) +{ + tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL; + tListElem *pEntry; + static int smeCommandQueueFull = 0; + + pEntry = csrLLRemoveHead( &pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK ); + + // If we can get another MS Msg buffer, then we are ok. Just link + // the entry onto the linked list. (We are using the linked list + // to keep track of tfhe message buffers). + if ( pEntry ) + { + pRetCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* reset when free list is available */ + smeCommandQueueFull = 0; + } + else + { + int idx = 1; + + //Cannot change pRetCmd here since it needs to return later. + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if( pEntry ) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + } + smsLog( pMac, LOGE, "Out of command buffer.... command (0x%X) stuck", + (pTempCmd) ? pTempCmd->command : eSmeNoCommand ); + if(pTempCmd) + { + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + } //if(pTempCmd) + + //dump what is in the pending queue + csrLLLock(&pMac->sme.smeCmdPendingList); + pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK ); + while(pEntry && !smeCommandQueueFull) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* Print only 1st five commands from pending queue. */ + if (idx <= 5) + smsLog( pMac, LOGE, "Out of command buffer.... SME pending command #%d (0x%X)", + idx, pTempCmd->command ); + idx++; + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + pEntry = csrLLNext( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); + } + csrLLUnlock(&pMac->sme.smeCmdPendingList); + + idx = 1; + //There may be some more command in CSR's own pending queue + csrLLLock(&pMac->roam.roamCmdPendingList); + pEntry = csrLLPeekHead( &pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK ); + while(pEntry && !smeCommandQueueFull) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* Print only 1st five commands from CSR pending queue */ + if (idx <= 5) + smsLog( pMac, LOGE, + "Out of command buffer.... CSR roamCmdPendingList command #%d (0x%X)", + idx, pTempCmd->command ); + idx++; + dumpCsrCommandInfo(pMac, pTempCmd); + pEntry = csrLLNext( &pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); + } + /* Increament static variable so that it prints pending command only once*/ + smeCommandQueueFull++; + csrLLUnlock(&pMac->roam.roamCmdPendingList); + + /* panic with out-of-command */ + VOS_BUG(0); + } + + /* memset to zero */ + if (pRetCmd) { + vos_mem_set((tANI_U8 *)&pRetCmd->command, sizeof(pRetCmd->command), 0); + vos_mem_set((tANI_U8 *)&pRetCmd->sessionId, + sizeof(pRetCmd->sessionId), 0); + vos_mem_set((tANI_U8 *)&pRetCmd->u, sizeof(pRetCmd->u), 0); + } + + return(pRetCmd); +} + + +void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority ) +{ + if ( fHighPriority ) + { + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); + } + else + { + csrLLInsertTail( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); + } + + // process the command queue... + smeProcessPendingQueue( pMac ); + + return; +} + + +static eSmeCommandType smeIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eSmeCommandType pmcCommand = eSmeNoCommand; + tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE; + tPmcState pmcState; + eHalStatus status; + + do + { + pmcState = pmcGetPmcState(pMac); + + status = csrIsFullPowerNeeded( pMac, pCommand, NULL, &fFullPowerNeeded ); + if( !HAL_STATUS_SUCCESS(status) ) + { + //PMC state is not right for the command, drop it + return ( eSmeDropCommand ); + } + if( fFullPowerNeeded ) break; + fFullPowerNeeded = ( ( eSmeCommandAddTs == pCommand->command ) || + ( eSmeCommandDelTs == pCommand->command ) ); + if( fFullPowerNeeded ) break; +#ifdef FEATURE_OEM_DATA_SUPPORT + fFullPowerNeeded = (pmcState == IMPS && + eSmeCommandOemDataReq == pCommand->command); + if(fFullPowerNeeded) break; +#endif + fFullPowerNeeded = (pmcState == IMPS && + eSmeCommandRemainOnChannel == pCommand->command); + if(fFullPowerNeeded) break; + } while(0); + + if( fFullPowerNeeded ) + { + switch( pmcState ) + { + case IMPS: + case STANDBY: + pmcCommand = eSmeCommandExitImps; + break; + + case BMPS: + pmcCommand = eSmeCommandExitBmps; + break; + + case UAPSD: + pmcCommand = eSmeCommandExitUapsd; + break; + + case WOWL: + pmcCommand = eSmeCommandExitWowl; + break; + + default: + break; + } + } + + return ( pmcCommand ); +} + +static eSmeCommandType smePsOffloadIsFullPowerNeeded(tpAniSirGlobal pMac, + tSmeCmd *pCommand) +{ + eSmeCommandType pmcCommand = eSmeNoCommand; + tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE; + eHalStatus status; + tPmcState pmcState; + + do + { + /* Check for CSR Commands which require full power */ + status = csrPsOffloadIsFullPowerNeeded(pMac, pCommand, NULL, + &fFullPowerNeeded); + if(!HAL_STATUS_SUCCESS(status)) + { + /* PMC state is not right for the command, drop it */ + return eSmeDropCommand; + } + if(fFullPowerNeeded) break; + + /* Check for SME Commands which require Full Power */ + if((eSmeCommandAddTs == pCommand->command) || + ((eSmeCommandDelTs == pCommand->command))) + { + /* Get the PMC State */ + pmcState = pmcOffloadGetPmcState(pMac, pCommand->sessionId); + switch(pmcState) + { + case REQUEST_BMPS: + case BMPS: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case UAPSD: + fFullPowerNeeded = eANI_BOOLEAN_TRUE; + break; + case STOPPED: + break; + default: + break; + } + break; + } + } while(0); + + if(fFullPowerNeeded) + { + pmcCommand = eSmeCommandExitBmps; + } + + return pmcCommand; +} + + +//For commands that need to do extra cleanup. +static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + if( eSmePmcCommandMask & pCommand->command ) + { + if(!pMac->psOffloadEnabled) + pmcAbortCommand( pMac, pCommand, fStopping ); + else + pmcOffloadAbortCommand(pMac, pCommand, fStopping); + } + else if ( eSmeCsrCommandMask & pCommand->command ) + { + csrAbortCommand( pMac, pCommand, fStopping ); + } + else + { + switch( pCommand->command ) + { + case eSmeCommandRemainOnChannel: + if (NULL != pCommand->u.remainChlCmd.callback) + { + remainOnChanCallback callback = + pCommand->u.remainChlCmd.callback; + /* process the msg */ + if( callback ) + { + callback(pMac, pCommand->u.remainChlCmd.callbackCtx, + eCSR_SCAN_ABORT ); + } + } + smeReleaseCommand( pMac, pCommand ); + break; + default: + smeReleaseCommand( pMac, pCommand ); + break; + } + } +} + +tListElem *csrGetCmdToProcess(tpAniSirGlobal pMac, tDblLinkList *pList, + tANI_U8 sessionId, tANI_BOOLEAN fInterlocked) +{ + tListElem *pCurEntry = NULL; + tSmeCmd *pCommand; + + /* Go through the list and return the command whose session id is not + * matching with the current ongoing scan cmd sessionId */ + pCurEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + while (pCurEntry) + { + pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link); + if (pCommand->sessionId != sessionId) + { + smsLog(pMac, LOG1, "selected the command with different sessionId"); + return pCurEntry; + } + + pCurEntry = csrLLNext(pList, pCurEntry, fInterlocked); + } + + smsLog(pMac, LOG1, "No command pending with different sessionId"); + return NULL; +} + +tANI_BOOLEAN smeProcessScanQueue(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pSmeEntry; + tSmeCmd *pSmeCommand; + tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; + + csrLLLock( &pMac->sme.smeScanCmdActiveList ); + if (csrLLIsListEmpty( &pMac->sme.smeScanCmdActiveList, + LL_ACCESS_NOLOCK )) + { + if (!csrLLIsListEmpty(&pMac->sme.smeScanCmdPendingList, + LL_ACCESS_LOCK)) + { + pEntry = csrLLPeekHead( &pMac->sme.smeScanCmdPendingList, + LL_ACCESS_LOCK ); + if (pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + //We cannot execute any command in wait-for-key state until setKey is through. + if (CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId)) + { + if (!CSR_IS_SET_KEY_COMMAND(pCommand)) + { + smsLog(pMac, LOGE, + " Cannot process command(%d) while waiting for key", + pCommand->command); + status = eANI_BOOLEAN_FALSE; + goto end; + } + } + + if ((!csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, + LL_ACCESS_LOCK ))) + { + pSmeEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + if (pEntry) + { + pSmeCommand = GET_BASE_ADDR(pEntry, tSmeCmd, + Link) ; + + /* if scan is running on one interface and SME recei + ves the next command on the same interface then + dont the allow the command to be queued to + smeCmdPendingList. If next scan is allowed on + the same interface the CSR state machine will + get screwed up. */ + if (pSmeCommand->sessionId == pCommand->sessionId) + { + status = eANI_BOOLEAN_FALSE; + goto end; + } + } + } + if ( csrLLRemoveEntry( &pMac->sme.smeScanCmdPendingList, + pEntry, LL_ACCESS_LOCK ) ) + { + csrLLInsertHead( &pMac->sme.smeScanCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ); + + switch (pCommand->command) + { + case eSmeCommandScan: + smsLog(pMac, LOG1, + " Processing scan offload command "); + csrProcessScanCommand( pMac, pCommand ); + break; + case eSmeCommandRemainOnChannel: + smsLog(pMac, LOG1, + "Processing req remain on channel offload" + " command"); + p2pProcessRemainOnChannelCmd(pMac, pCommand); + break; + default: + smsLog(pMac, LOGE, + " Something wrong, wrong command enqueued" + " to smeScanCmdPendingList"); + pEntry = csrLLRemoveHead( + &pMac->sme.smeScanCmdActiveList, + LL_ACCESS_NOLOCK ); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeReleaseCommand( pMac, pCommand ); + break; + } + } + } + } + } +end: + csrLLUnlock(&pMac->sme.smeScanCmdActiveList); + return status; +} + +tANI_BOOLEAN smeProcessCommand( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fContinue = eANI_BOOLEAN_FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pSmeEntry; + tSmeCmd *pSmeCommand; + eSmeCommandType pmcCommand = eSmeNoCommand; + + // if the ActiveList is empty, then nothing is active so we can process a + // pending command... + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + if ( csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) ) + { + if(!csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK)) + { + /* If scan command is pending in the smeScanCmdActive list + * then pick the command from smeCmdPendingList which is + * not matching with the scan command session id. + * At any point of time only one command will be allowed + * on a single session. */ + if ((pMac->fScanOffload) && + (!csrLLIsListEmpty(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK))) + { + pSmeEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK); + if (pSmeEntry) + { + pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link); + + pEntry = csrGetCmdToProcess(pMac, + &pMac->sme.smeCmdPendingList, + pSmeCommand->sessionId, + LL_ACCESS_LOCK); + goto sme_process_cmd; + } + } + + //Peek the command + pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK ); +sme_process_cmd: + if( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + /* Allow only disconnect command + * in wait-for-key state until setKey is through. + */ + if( CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId ) && + !CSR_IS_DISCONNECT_COMMAND( pCommand ) ) + { + if( !CSR_IS_SET_KEY_COMMAND( pCommand ) ) + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog(pMac, LOGE, FL("SessionId %d: Cannot process " + "command(%d) while waiting for key"), + pCommand->sessionId, pCommand->command); + fContinue = eANI_BOOLEAN_FALSE; + goto sme_process_scan_queue; + } + } + if(pMac->psOffloadEnabled) + pmcCommand = smePsOffloadIsFullPowerNeeded(pMac, pCommand); + else + pmcCommand = smeIsFullPowerNeeded( pMac, pCommand ); + if( eSmeDropCommand == pmcCommand ) + { + csrLLUnlock(&pMac->sme.smeCmdActiveList); + //This command is not ok for current PMC state + if( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) + { + smeAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + //tell caller to continue + fContinue = eANI_BOOLEAN_TRUE; + goto sme_process_scan_queue; + } + else if( eSmeNoCommand != pmcCommand ) + { + tExitBmpsInfo exitBmpsInfo; + void *pv = NULL; + tANI_U32 size = 0; + tSmeCmd *pPmcCmd = NULL; + + if( eSmeCommandExitBmps == pmcCommand ) + { + exitBmpsInfo.exitBmpsReason = eSME_REASON_OTHER; + pv = (void *)&exitBmpsInfo; + size = sizeof(tExitBmpsInfo); + } + //pmcCommand has to be one of the exit power save command + status = pmcPrepareCommand(pMac, pCommand->sessionId, + pmcCommand, pv, size, + &pPmcCmd); + if( HAL_STATUS_SUCCESS( status ) && pPmcCmd ) + { + //Force this command to wake up the chip + csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_COMMAND, pPmcCmd->sessionId, pPmcCmd->command)); + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + /* Handle PS Offload Case Separately */ + if(pMac->psOffloadEnabled) + { + fContinue = pmcOffloadProcessCommand(pMac, pPmcCmd); + } + else + { + fContinue = pmcProcessCommand( pMac, pPmcCmd ); + } + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ) ) + { + pmcReleaseCommand( pMac, pPmcCmd ); + } + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog( pMac, LOGE, FL( "Cannot issue command(0x%X) to wake up the chip. Status = %d"), pmcCommand, status ); + //Let it retry + fContinue = eANI_BOOLEAN_TRUE; + } + goto sme_process_scan_queue; + } + if ( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) + { + // we can reuse the pCommand + + // Insert the command onto the ActiveList... + csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_NOLOCK ); + + // .... and process the command. + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_COMMAND, pCommand->sessionId, pCommand->command)); + switch ( pCommand->command ) + { + + case eSmeCommandScan: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrProcessScanCommand( pMac, pCommand ); + break; + + case eSmeCommandRoam: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + } + break; + + case eSmeCommandWmStatusChange: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrRoamProcessWmStatusChangeCommand(pMac, pCommand); + break; + + case eSmeCommandSetKey: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessSetKeyCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + } + break; + + case eSmeCommandRemoveKey: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessRemoveKeyCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + } + break; + + case eSmeCommandAddStaSession: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessAddStaSessionCommand( pMac, pCommand ); + break; + case eSmeCommandDelStaSession: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessDelStaSessionCommand( pMac, pCommand ); + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case eSmeCommandOemDataReq: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + oemData_ProcessOemDataReqCommand(pMac, pCommand); + break; +#endif + case eSmeCommandRemainOnChannel: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + p2pProcessRemainOnChannelCmd(pMac, pCommand); + break; + case eSmeCommandNoAUpdate: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + p2pProcessNoAReq(pMac,pCommand); + case eSmeCommandEnterImps: + case eSmeCommandExitImps: + case eSmeCommandEnterBmps: + case eSmeCommandExitBmps: + case eSmeCommandEnterUapsd: + case eSmeCommandExitUapsd: + case eSmeCommandEnterWowl: + case eSmeCommandExitWowl: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + if(pMac->psOffloadEnabled) + { + fContinue = + pmcOffloadProcessCommand(pMac, pCommand); + } + else + { + fContinue = pmcProcessCommand(pMac, pCommand); + } + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + break; + + //Treat standby differently here because caller may not be able to handle + //the failure so we do our best here + case eSmeCommandEnterStandby: + if( csrIsConnStateDisconnected( pMac, pCommand->sessionId ) ) + { + //It can continue + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + if(pMac->psOffloadEnabled) + { + fContinue = + pmcOffloadProcessCommand(pMac, pCommand); + } + else + { + fContinue = + pmcProcessCommand(pMac, pCommand); + } + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + } + else + { + //Need to issue a disconnect first before processing this command + tSmeCmd *pNewCmd; + + //We need to re-run the command + fContinue = eANI_BOOLEAN_TRUE; + //Pull off the standby command first + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ) ) + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + //Need to call CSR function here because the disconnect command + //is handled by CSR + pNewCmd = csrGetCommandBuffer( pMac ); + if( NULL != pNewCmd ) + { + //Put the standby command to the head of the pending list first + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCommand->Link, + LL_ACCESS_LOCK ); + pNewCmd->command = eSmeCommandRoam; + pNewCmd->u.roamCmd.roamReason = eCsrForcedDisassoc; + //Put the disassoc command before the standby command + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pNewCmd->Link, + LL_ACCESS_LOCK ); + } + else + { + //Continue the command here + if(pMac->psOffloadEnabled) + { + fContinue = + pmcOffloadProcessCommand(pMac, + pCommand); + } + else + { + fContinue = pmcProcessCommand(pMac, + pCommand); + } + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog( pMac, LOGE, FL(" failed to remove standby command") ); + VOS_ASSERT(0); + } + } + break; + + case eSmeCommandAddTs: + case eSmeCommandDelTs: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + fContinue = qosProcessCommand( pMac, pCommand ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ) ) + { +//#ifndef WLAN_MDM_CODE_REDUCTION_OPT + qosReleaseCommand( pMac, pCommand ); +//#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + } +#endif + break; +#ifdef FEATURE_WLAN_TDLS + case eSmeCommandTdlsSendMgmt: + case eSmeCommandTdlsAddPeer: + case eSmeCommandTdlsDelPeer: + case eSmeCommandTdlsLinkEstablish: + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "sending TDLS Command 0x%x to PE", pCommand->command); + + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrTdlsProcessCmd( pMac, pCommand ); + } + break ; +#endif + + default: + //something is wrong + //remove it from the active list + smsLog(pMac, LOGE, " csrProcessCommand processes an unknown command %d", pCommand->command); + pEntry = csrLLRemoveHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ); + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeReleaseCommand( pMac, pCommand ); + status = eHAL_STATUS_FAILURE; + break; + } + if(!HAL_STATUS_SUCCESS(status)) + { + fContinue = eANI_BOOLEAN_TRUE; + } + }//if(pEntry) + else + { + //This is odd. Some one else pull off the command. + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + } + else + { + //No command waiting + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + /* + * This is only used to restart an idle mode scan, + * it means at least one other idle scan has finished. + * Moreover Idle Scan is not supported with power + * save offload supported + */ + if(!pMac->psOffloadEnabled && + pMac->scan.fRestartIdleScan && + eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + tANI_U32 nTime = 0; + + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime))) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } + } + } + else { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + +sme_process_scan_queue: + if (pMac->fScanOffload && !(smeProcessScanQueue(pMac))) + fContinue = eANI_BOOLEAN_FALSE; + + return ( fContinue ); +} + +void smeProcessPendingQueue( tpAniSirGlobal pMac ) +{ + while( smeProcessCommand( pMac ) ); +} + + +tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac) +{ + return ( !csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) || + !csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK) ); +} + + + +//Global APIs + +/*-------------------------------------------------------------------------- + + \brief sme_Open() - Initialze all SME modules and put them at idle state + + The function initializes each module inside SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are at idle state ready to start. + + smeOpen must be called before any other SME APIs can be involved. + smeOpen must be called after macOpen. + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully initialized. + + Other status means SME is failed to be initialized + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Open(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); +#ifndef WLAN_FEATURE_MBSSID + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); +#endif + + do { + pMac->sme.state = SME_STATE_STOP; + pMac->sme.currDeviceMode = VOS_STA_MODE; + if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->sme.lkSmeGlobalLock ) ) ) + { + smsLog( pMac, LOGE, "sme_Open failed init lock" ); + status = eHAL_STATUS_FAILURE; + break; + } + + status = ccmOpen(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "ccmOpen failed during initialization with status=%d", status ); + break; + } + + status = csrOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "csrOpen failed during initialization with status=%d", status ); + break; + } + + if(!pMac->psOffloadEnabled) + { + status = pmcOpen(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcOpen failed during initialization with status=%d", + status ); + break; + } + } + else + { + status = pmcOffloadOpen(hHal); + if (! HAL_STATUS_SUCCESS(status)) { + smsLog( pMac, LOGE, + "pmcOffloadOpen failed during initialization with status=%d", + status ); + break; + } + } + +#ifdef FEATURE_WLAN_TDLS + pMac->isTdlsPowerSaveProhibited = 0; +#endif + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = sme_QosOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "Qos open failed during initialization with status=%d", status ); + break; + } + + status = btcOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "btcOpen open failed during initialization with status=%d", status ); + break; + } +#endif +#ifdef FEATURE_OEM_DATA_SUPPORT + status = oemData_OemDataReqOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog(pMac, LOGE, + "oemData_OemDataReqOpen failed during initialization with status=%d", status ); + break; + } +#endif + + if(!HAL_STATUS_SUCCESS((status = initSmeCmdList(pMac)))) + break; + +#ifndef WLAN_FEATURE_MBSSID + if ( NULL == pvosGCtx ){ + smsLog( pMac, LOGE, "WLANSAP_Open open failed during initialization"); + status = eHAL_STATUS_FAILURE; + break; + } + + status = WLANSAP_Open( pvosGCtx ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "WLANSAP_Open open failed during initialization with status=%d", status ); + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI + status = rrmOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "rrmOpen open failed during initialization with status=%d", status ); + break; + } +#endif + + sme_p2pOpen(pMac); + smeTraceInit(pMac); + + }while (0); + + return status; +} + +/* + * sme_init_chan_list, triggers channel setup based on country code. + */ +eHalStatus sme_init_chan_list(tHalHandle hal, v_U8_t *alpha2, + COUNTRY_CODE_SOURCE cc_src) +{ + tpAniSirGlobal pmac = PMAC_STRUCT(hal); + + if ((cc_src == COUNTRY_CODE_SET_BY_USER) && + (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + pmac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + } + + return csr_init_chan_list(pmac, alpha2); +} + +/*-------------------------------------------------------------------------- + + \brief sme_set11dinfo() - Set the 11d information about valid channels + and there power using information from nvRAM + This function is called only for AP. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0)); + if (NULL == pSmeConfigParams ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to update"); + return status; + } + + status = csrSetChannels(hHal, &pSmeConfigParams->csrConfig ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", + status ); + } + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_getSoftApDomain() - Get the current regulatory domain of softAp. + + This is a synchronous call + + \param hHal - The handle returned by HostapdAdapter. + \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp. + + \return eHAL_STATUS_SUCCESS - SME successfully completed the request. + + Other status means, failed to get the current regulatory domain. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_getSoftApDomain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, NO_SESSION, 0)); + if (NULL == domainIdSoftAp ) { + smsLog( pMac, LOGE, "Uninitialized domain Id"); + return status; + } + + *domainIdSoftAp = pMac->scan.domainIdCurrent; + status = eHAL_STATUS_SUCCESS; + + return status; +} + + +eHalStatus sme_setRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0)); + if (NULL == apCntryCode ) { + smsLog( pMac, LOGE, "Empty Country Code, nothing to update"); + return status; + } + + status = csrSetRegInfo(hHal, apCntryCode ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrSetRegInfo failed with status=%d", + status ); + } + return status; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus sme_SetPlmRequest(tHalHandle hHal, tpSirPlmReq pPlmReq) +{ + eHalStatus status; + tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST] = {0}; + tANI_U8 count, valid_count = 0; + vos_msg_t msg; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pPlmReq->sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), pPlmReq->sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Invalid Sessionid", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if (pPlmReq->enable) { + + /* validating channel numbers */ + for (count = 0; count < pPlmReq->plmNumCh; count++) { + + ret = csrIsSupportedChannel(pMac, pPlmReq->plmChList[count]); + if (ret && pPlmReq->plmChList[count] > 14) + { + if (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState(pPlmReq->plmChList[count])) + { + /* DFS channel is provided, no PLM bursts can be + * transmitted. Ignoring these channels. + */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s DFS channel %d ignored for PLM", __func__, + pPlmReq->plmChList[count]); + continue; + } + } + else if (!ret) + { + /* Not supported, ignore the channel */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s Unsupported channel %d ignored for PLM", + __func__, pPlmReq->plmChList[count]); + continue; + } + ch_list[valid_count] = pPlmReq->plmChList[count]; + valid_count++; + } /* End of for () */ + + /* Copying back the valid channel list to plm struct */ + vos_mem_set((void *)pPlmReq->plmChList, pPlmReq->plmNumCh, 0); + if (valid_count) + vos_mem_copy(pPlmReq->plmChList, ch_list, valid_count); + /* All are invalid channels, FW need to send the PLM + * report with "incapable" bit set. + */ + pPlmReq->plmNumCh = valid_count; + } /* PLM START */ + + msg.type = WDA_SET_PLM_REQ; + msg.reserved = 0; + msg.bodyptr = pPlmReq; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able \ + to post WDA_SET_PLM_REQ message to WDA", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + } + return (status); +} +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +/*-------------------------------------------------------------------------- + + \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA. + + It is used at driver start up to inform RIVA of the default channel + configuration. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. + + Other status means SME is failed to update the channel config. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateChannelConfig(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, NO_SESSION, 0)); + pmcUpdateScanParams( pMac, &(pMac->roam.configParam), + &pMac->scan.base20MHzChannels, FALSE); + return eHAL_STATUS_SUCCESS; +} +#endif // FEATURE_WLAN_SCAN_PNLO + +/*-------------------------------------------------------------------------- + + \brief sme_UpdateConfig() - Change configurations for all SME moduels + + The function updates some configuration for modules in SME, CCM, CSR, etc + during SMEs close open sequence. + + Modules inside SME apply the new configuration at the next transaction. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, 0)); + if (NULL == pSmeConfigParams ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to update"); + return status; + } + + status = csrChangeDefaultConfigParam(pMac, &pSmeConfigParams->csrConfig); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", + status ); + } +#if defined WLAN_FEATURE_VOWIFI + status = rrmChangeDefaultConfigParam(hHal, &pSmeConfigParams->rrmConfig); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "rrmChangeDefaultConfigParam failed with status=%d", + status ); + } +#endif + //For SOC, CFG is set before start + //We don't want to apply global CFG in connect state because that may cause some side affect + if( + csrIsAllSessionDisconnected( pMac) ) + { + csrSetGlobalCfgs(pMac); + } + + /* update the directed scan offload setting */ + pMac->fScanOffload = pSmeConfigParams->fScanOffload; + + if (pMac->fScanOffload) + { + /* If scan offload is enabled then lim has allow the sending of + scan request to firmware even in powersave mode. The firmware has + to take care of exiting from power save mode */ + status = ccmCfgSetInt(hHal, WNI_CFG_SCAN_IN_POWERSAVE, + eANI_BOOLEAN_TRUE, NULL, eANI_BOOLEAN_FALSE); + + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CCM"); + } + } + pMac->isCoalesingInIBSSAllowed = + pSmeConfigParams->csrConfig.isCoalesingInIBSSAllowed; + + /* update the p2p listen offload setting */ + pMac->fP2pListenOffload = pSmeConfigParams->fP2pListenOffload; + + /* update p2p offload status */ + pMac->pnoOffload = pSmeConfigParams->pnoOffload; + + pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog; + + /* update interface configuration */ + pMac->sme.max_intf_count = pSmeConfigParams->max_intf_count; + + pMac->enable5gEBT = pSmeConfigParams->enable5gEBT; + pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery; + + return status; +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void sme_ProcessGetGtkInfoRsp( tHalHandle hHal, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return ; + } + if (pMac->pmc.GtkOffloadGetInfoCB == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: HDD callback is null", __func__); + return ; + } + pMac->pmc.GtkOffloadGetInfoCB(pMac->pmc.GtkOffloadGetInfoCBContext, + pGtkOffloadGetInfoRsp); +} +#endif + +/*-------------------------------------------------------------------------- + + \fn - sme_ProcessReadyToSuspend + \brief - On getting ready to suspend indication, this function calls + callback registered (HDD callbacks) with SME to inform + ready to suspend indication. + + \param hHal - Handle returned by macOpen. + pReadyToSuspend - Parameter received along with ready to suspend + indication from WMA. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_ProcessReadyToSuspend( tHalHandle hHal, + tpSirReadyToSuspendInd pReadyToSuspend) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return ; + } + + if (NULL != pMac->readyToSuspendCallback) + { + pMac->readyToSuspendCallback (pMac->readyToSuspendContext, + pReadyToSuspend->suspended); + pMac->readyToSuspendCallback = NULL; + } +} + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +/*-------------------------------------------------------------------------- + + \fn - sme_ProcessReadyToExtWoW + \brief - On getting ready to Ext WoW indication, this function calls + callback registered (HDD callbacks) with SME to inform + ready to ExtWoW indication. + + \param hHal - Handle returned by macOpen. + pReadyToExtWoW - Parameter received along with ready to Ext WoW + indication from WMA. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_ProcessReadyToExtWoW( tHalHandle hHal, + tpSirReadyToExtWoWInd pReadyToExtWoW) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return ; + } + + if (NULL != pMac->readyToExtWoWCallback) + { + pMac->readyToExtWoWCallback (pMac->readyToExtWoWContext, + pReadyToExtWoW->status); + pMac->readyToExtWoWCallback = NULL; + pMac->readyToExtWoWContext = NULL; + } + +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_ChangeConfigParams + \brief The SME API exposed for HDD to provide config params to SME during + SMEs stop -> start sequence. + + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + + \Param + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ChangeConfigParams(tHalHandle hHal, + tCsrUpdateConfigParam *pUpdateConfigParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pUpdateConfigParam ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to reset"); + return status; + } + + status = csrChangeConfigParams(pMac, pUpdateConfigParam); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrUpdateConfigParam failed with status=%d", + status ); + } + + return status; + +} + +/*-------------------------------------------------------------------------- + + \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform + that the NIC is ready tio run. + + The function is called by HDD at the end of initialization stage so PE/HAL can + enable the NIC to running state. + + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE + successfully. + + Other status means SME failed to send the message to PE. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_HDDReadyInd(tHalHandle hHal) +{ + tSirSmeReadyReq Msg; + eHalStatus status = eHAL_STATUS_FAILURE; + tPmcPowerState powerState; + tPmcSwitchState hwWlanSwitchState; + tPmcSwitchState swWlanSwitchState; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0)); + do + { + + Msg.messageType = eWNI_SME_SYS_READY_IND; + Msg.length = sizeof( tSirSmeReadyReq ); + + if (eSIR_FAILURE != uMacPostCtrlMsg( hHal, (tSirMbMsg*)&Msg )) + { + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGE, + "uMacPostCtrlMsg failed to send eWNI_SME_SYS_READY_IND"); + break; + } + + if(!pMac->psOffloadEnabled) + { + status = pmcQueryPowerState( hHal, &powerState, + &hwWlanSwitchState, &swWlanSwitchState ); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "pmcQueryPowerState failed with status=%d", + status ); + break; + } + + if ( (ePMC_SWITCH_OFF != hwWlanSwitchState) && + (ePMC_SWITCH_OFF != swWlanSwitchState) ) + { + status = csrReady(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "csrReady failed with status=%d", status ); + break; + } + status = pmcReady(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "pmcReady failed with status=%d", status ); + break; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if(VOS_STATUS_SUCCESS != btcReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "btcReady failed"); + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI + if(VOS_STATUS_SUCCESS != rrmReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "rrmReady failed"); + break; + } +#endif + } + } + else + { + status = csrReady(pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, "csrReady failed with status=%d", status ); + break; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if(VOS_STATUS_SUCCESS != btcReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "btcReady failed"); + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI + if(VOS_STATUS_SUCCESS != rrmReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "rrmReady failed"); + break; + } +#endif + } + pMac->sme.state = SME_STATE_READY; + } while( 0 ); + + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_Start() - Put all SME modules at ready state. + + The function starts each module in SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are ready to run. + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is ready. + + Other status means SME is failed to start + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Start(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + do + { + status = csrStart(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrStart failed during smeStart with status=%d", + status ); + break; + } + + if(!pMac->psOffloadEnabled) + { + status = pmcStart(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcStart failed during smeStart with status=%d", + status ); + break; + } + } + else + { + status = pmcOffloadStart(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcOffloadStart failed during smeStart with status=%d", + status ); + break; + } + } + +#ifndef WLAN_FEATURE_MBSSID + status = WLANSAP_Start(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_Start failed during smeStart with status=%d", + status ); + break; + } +#endif + + pMac->sme.state = SME_STATE_START; + }while (0); + + return status; +} + + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/****************************************************************************** +* +* Name: sme_PCFilterMatchCountResponseHandler +* +* Description: +* Invoke Packet Coalescing Filter Match Count callback routine +* +* Parameters: +* hHal - HAL handle for device +* pMsg - Pointer to tRcvFltPktMatchRsp structure +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PCFilterMatchCountResponseHandler(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp = (tpSirRcvFltPktMatchRsp)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + smsLog(pMac, LOG2, "SME: entering " + "sme_FilterMatchCountResponseHandler"); + + /* Call Packet Coalescing Filter Match Count callback routine. */ + if (pMac->pmc.FilterMatchCountCB != NULL) + pMac->pmc.FilterMatchCountCB(pMac->pmc.FilterMatchCountCBContext, + pRcvFltPktMatchRsp); + + smsLog(pMac, LOG1, "%s: status=0x%x", __func__, + pRcvFltPktMatchRsp->status); + + pMac->pmc.FilterMatchCountCB = NULL; + pMac->pmc.FilterMatchCountCBContext = NULL; + } + + return(status); +} +#endif // WLAN_FEATURE_PACKET_FILTERING + + +#ifdef WLAN_FEATURE_11W +/*------------------------------------------------------------------ + * + * Handle the unprotected management frame indication from LIM and + * forward it to HDD. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, + tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tANI_U32 SessionId = pSmeMgmtFrm->sessionId; + + pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen; + pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf; + pRoamInfo.frameType = pSmeMgmtFrm->frameType; + + /* forward the mgmt frame to HDD */ + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0); + + return status; +} +#endif + +/*------------------------------------------------------------------ + * + * Handle the DFS Radar Event and indicate it to the SAP + * + *------------------------------------------------------------------*/ +eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo = {0}; + tSirSmeDfsEventInd *dfs_event; + tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp; + tANI_U32 sessionId = 0; + eRoamCmdStatus roamStatus; + eCsrRoamResult roamResult; + int i; + + switch (msgType) + { + case eWNI_SME_DFS_RADAR_FOUND: + { + /* Radar found !! */ + dfs_event = (tSirSmeDfsEventInd *)pMsgBuf; + if (NULL == dfs_event) + { + smsLog(pMac, LOGE, + "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message", + __func__); + return eHAL_STATUS_FAILURE; + } + sessionId = dfs_event->sessionId; + roamInfo.dfs_event.sessionId = sessionId; + roamInfo.dfs_event.chan_list.nchannels = + dfs_event->chan_list.nchannels; + for (i = 0; i < dfs_event->chan_list.nchannels; i++) + { + roamInfo.dfs_event.chan_list.channels[i] = + dfs_event->chan_list.channels[i]; + } + + roamInfo.dfs_event.dfs_radar_status = dfs_event->dfs_radar_status; + roamInfo.dfs_event.use_nol = dfs_event->use_nol; + + roamStatus = eCSR_ROAM_DFS_RADAR_IND; + roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Radar indication event occured"); + break; + } + case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: + { + csaIeTxCompleteRsp = (tSirSmeCSAIeTxCompleteRsp *)pMsgBuf; + if (NULL == csaIeTxCompleteRsp) + { + smsLog(pMac, LOGE, + "%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND", + __func__); + return eHAL_STATUS_FAILURE; + } + sessionId = csaIeTxCompleteRsp->sessionId; + roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY; + roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]", + sessionId ); + break; + } + default: + { + smsLog(pMac, LOG1, "%s: Invalid DFS message = 0x%x", __func__, + msgType); + status = eHAL_STATUS_FAILURE; + return status; + } + } + + /* Indicate Radar Event to SAP */ + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + roamStatus, roamResult); + return status; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/*------------------------------------------------------------------ + * + * Handle the tsm ie indication from LIM and forward it to HDD. + * + *------------------------------------------------------------------*/ +eHalStatus sme_TsmIeInd(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tANI_U32 SessionId = pSmeTsmIeInd->sessionId; + pRoamInfo.tsmIe.tsid= pSmeTsmIeInd->tsmIe.tsid; + pRoamInfo.tsmIe.state= pSmeTsmIeInd->tsmIe.state; + pRoamInfo.tsmIe.msmt_interval= pSmeTsmIeInd->tsmIe.msmt_interval; + /* forward the tsm ie information to HDD */ + csrRoamCallCallback(pMac, + SessionId, + &pRoamInfo, + 0, + eCSR_ROAM_TSM_IE_IND, + 0); + return status; +} +/* --------------------------------------------------------------------------- + \fn sme_SetCCKMIe + \brief function to store the CCKM IE passed from supplicant and use + it while packing reassociation request + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param pCckmIe - pointer to CCKM IE data + \param pCckmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetCCKMIe(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pCckmIe, tANI_U8 cckmIeLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrSetCCKMIe(pMac, sessionId, pCckmIe, cckmIeLen); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetEseBeaconRequest + \brief function to set ESE beacon request parameters + \param hHal - HAL handle for device + \param sessionId - Session id + \param pEseBcnReq - pointer to ESE beacon request + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId, + const tCsrEseBeaconReq* pEseBcnReq) +{ + eHalStatus status = eSIR_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpSirBeaconReportReqInd pSmeBcnReportReq = NULL; + tCsrEseBeaconReqParams *pBeaconReq = NULL; + tANI_U8 counter = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + if (pSmeRrmContext->eseBcnReqInProgress == TRUE) + { + smsLog(pMac, LOGE, "A Beacon Report Req is already in progress"); + return eHAL_STATUS_RESOURCES; + } + + /* Store the info in RRM context */ + vos_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq, sizeof(tCsrEseBeaconReq)); + + //Prepare the request to send to SME. + pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd )); + if(NULL == pSmeBcnReportReq) + { + smsLog(pMac, LOGP, "Memory Allocation Failure!!! ESE BcnReq Ind to SME"); + return eSIR_FAILURE; + } + + pSmeRrmContext->eseBcnReqInProgress = TRUE; + + smsLog(pMac, LOGE, "Sending Beacon Report Req to SME"); + vos_mem_zero( pSmeBcnReportReq, sizeof( tSirBeaconReportReqInd )); + + pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ); + vos_mem_copy( pSmeBcnReportReq->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + pSmeBcnReportReq->channelInfo.channelNum = 255; + pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe; + pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; + + for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) + { + pBeaconReq = (tCsrEseBeaconReqParams *)&pEseBcnReq->bcnReq[counter]; + pSmeBcnReportReq->fMeasurementtype[counter] = pBeaconReq->scanMode; + pSmeBcnReportReq->measurementDuration[counter] = SYS_TU_TO_MS(pBeaconReq->measurementDuration); + pSmeBcnReportReq->channelList.channelNumber[counter] = pBeaconReq->channel; + } + + status = sme_RrmProcessBeaconReportReqInd(pMac, pSmeBcnReportReq); + + if(status != eHAL_STATUS_SUCCESS) + pSmeRrmContext->eseBcnReqInProgress = FALSE; + + return status; +} + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/*-------------------------------------------------------------------------- + + \brief sme_ProcessMsg() - The main message processor for SME. + + The function is called by a message dispatcher when to process a message + targeted for SME. + + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param pMsg - A pointer to a caller allocated object of tSirMsgQ. + + \return eHAL_STATUS_SUCCESS - SME successfully process the message. + + Other status means SME failed to process the message to HAL. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (pMsg == NULL) { + smsLog( pMac, LOGE, "Empty message for SME, nothing to process"); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( SME_IS_START(pMac) ) + { + switch (pMsg->type) { // TODO: Will be modified to do a range check for msgs instead of having cases for each msgs +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + case eWNI_SME_HO_FAIL_IND: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "LFR3:%s: Rcvd eWNI_SME_HO_FAIL_IND", __func__); + csrProcessHOFailInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + break; + case eWNI_SME_ROAM_OFFLOAD_SYNCH_IND: + csrProcessRoamOffloadSynchInd(pMac, + (tpSirRoamOffloadSynchInd)pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + break; +#endif + case eWNI_PMC_ENTER_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_IND: + case eWNI_PMC_ENTER_IMPS_RSP: + case eWNI_PMC_EXIT_IMPS_RSP: + case eWNI_PMC_SMPS_STATE_IND: + case eWNI_PMC_ENTER_UAPSD_RSP: + case eWNI_PMC_EXIT_UAPSD_RSP: + case eWNI_PMC_ENTER_WOWL_RSP: + case eWNI_PMC_EXIT_WOWL_RSP: + //PMC + if (pMsg->bodyptr) + { + if(!pMac->psOffloadEnabled) + { + pmcMessageProcessor(hHal, pMsg->bodyptr); + } + else + { + pmcOffloadMessageProcessor(hHal, pMsg->bodyptr); + } + status = eHAL_STATUS_SUCCESS; + vos_mem_free(pMsg->bodyptr); + } else { + smsLog( pMac, LOGE, "Empty rsp message for PMC, nothing to process"); + } + break; + + case WNI_CFG_SET_CNF: + case WNI_CFG_DNLD_CNF: + case WNI_CFG_GET_RSP: + case WNI_CFG_ADD_GRP_ADDR_CNF: + case WNI_CFG_DEL_GRP_ADDR_CNF: + //CCM + if (pMsg->bodyptr) + { + ccmCfgCnfMsgHandler(hHal, pMsg->bodyptr); + status = eHAL_STATUS_SUCCESS; + vos_mem_free(pMsg->bodyptr); + } else { + smsLog( pMac, LOGE, "Empty rsp message for CCM, nothing to process"); + } + break; + + case eWNI_SME_ADDTS_RSP: + case eWNI_SME_DELTS_RSP: + case eWNI_SME_DELTS_IND: +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_AGGR_QOS_RSP: +#endif + //QoS + if (pMsg->bodyptr) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = sme_QosMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); +#endif + } else { + smsLog( pMac, LOGE, "Empty rsp message for QoS, nothing to process"); + } + break; +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_IND: + case eWNI_SME_BEACON_REPORT_REQ_IND: +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received RRM message. Message Id = %d", pMsg->type ); +#endif + if ( pMsg->bodyptr ) + { + status = sme_RrmMsgProcessor( pMac, pMsg->type, pMsg->bodyptr ); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty message for RRM, nothing to process"); + } + break; +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT + //Handle the eWNI_SME_OEM_DATA_RSP: + case eWNI_SME_OEM_DATA_RSP: + if(pMsg->bodyptr) + { + status = sme_HandleOemDataRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for oemData_ (eWNI_SME_OEM_DATA_RSP), nothing to process"); + } + smeProcessPendingQueue( pMac ); + break; +#endif + + case eWNI_SME_ADD_STA_SELF_RSP: + if(pMsg->bodyptr) + { + status = csrProcessAddStaSessionRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ADD_STA_SELF_RSP), nothing to process"); + } + break; + case eWNI_SME_DEL_STA_SELF_RSP: + if(pMsg->bodyptr) + { + status = csrProcessDelStaSessionRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_DEL_STA_SELF_RSP), nothing to process"); + } + break; + case eWNI_SME_REMAIN_ON_CHN_RSP: + if(pMsg->bodyptr) + { + status = sme_remainOnChnRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RSP), nothing to process"); + } + break; + case eWNI_SME_REMAIN_ON_CHN_RDY_IND: + if(pMsg->bodyptr) + { + status = sme_remainOnChnReady(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RDY_IND), nothing to process"); + } + break; + case eWNI_SME_MGMT_FRM_IND: + if(pMsg->bodyptr) + { + sme_mgmtFrmInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_MGMT_FRM_IND), nothing to process"); + } + break; + case eWNI_SME_ACTION_FRAME_SEND_CNF: + if(pMsg->bodyptr) + { + status = sme_sendActionCnf(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ACTION_FRAME_SEND_CNF), nothing to process"); + } + break; + case eWNI_SME_COEX_IND: + if(pMsg->bodyptr) + { + status = btcHandleCoexInd((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_COEX_IND), nothing to process"); + } + break; + +#ifdef FEATURE_WLAN_SCAN_PNO + case eWNI_SME_PREF_NETWORK_FOUND_IND: + if(pMsg->bodyptr) + { + status = sme_PreferredNetworkFoundInd((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_PREF_NETWORK_FOUND_IND), nothing to process"); + } + break; +#endif // FEATURE_WLAN_SCAN_PNO + + case eWNI_SME_TX_PER_HIT_IND: + if (pMac->sme.pTxPerHitCallback) + { + pMac->sme.pTxPerHitCallback(pMac->sme.pTxPerHitCbContext); + } + break; + + case eWNI_SME_CHANGE_COUNTRY_CODE: + if(pMsg->bodyptr) + { + status = sme_HandleChangeCountryCode((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_CHANGE_COUNTRY_CODE), nothing to process"); + } + break; + + case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE: + if (pMsg->bodyptr) + { + status = sme_HandleGenericChangeCountryCode((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE), nothing to process"); + } + break; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + case eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + if(pMsg->bodyptr) + { + status = sme_PCFilterMatchCountResponseHandler((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas " + "(PACKET_COALESCING_FILTER_MATCH_COUNT_RSP), nothing to process"); + } + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + case eWNI_SME_PRE_SWITCH_CHL_IND: + if(pMsg->bodyptr) + { + status = sme_HandlePreChannelSwitchInd(pMac,pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas " + "(eWNI_SME_PRE_SWITCH_CHL_IND), nothing to process"); + } + break; + case eWNI_SME_POST_SWITCH_CHL_IND: + { + status = sme_HandlePostChannelSwitchInd(pMac); + break; + } + +#ifdef WLAN_WAKEUP_EVENTS + case eWNI_SME_WAKE_REASON_IND: + if(pMsg->bodyptr) + { + status = sme_WakeReasonIndCallback((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_WAKE_REASON_IND), nothing to process"); + } + break; +#endif // WLAN_WAKEUP_EVENTS + +#ifdef FEATURE_WLAN_TDLS + /* + * command rescived from PE, SME tdls msg processor shall be called + * to process commands recieved from PE + */ + case eWNI_SME_TDLS_SEND_MGMT_RSP: + case eWNI_SME_TDLS_ADD_STA_RSP: + case eWNI_SME_TDLS_DEL_STA_RSP: + case eWNI_SME_TDLS_DEL_STA_IND: + case eWNI_SME_TDLS_DEL_ALL_PEER_IND: + case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: + case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: + case eWNI_SME_TDLS_SHOULD_DISCOVER: + case eWNI_SME_TDLS_SHOULD_TEARDOWN: + case eWNI_SME_TDLS_PEER_DISCONNECTED: + { + if (pMsg->bodyptr) + { + status = tdlsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for TDLS, \ + nothing to process"); + } + break; + } +#endif + +#ifdef WLAN_FEATURE_11W + case eWNI_SME_UNPROT_MGMT_FRM_IND: + if (pMsg->bodyptr) + { + sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process"); + } + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_TSM_IE_IND: + { + if (pMsg->bodyptr) + { + sme_TsmIeInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, + "Empty rsp message for (eWNI_SME_TSM_IE_IND), nothing to process"); + } + break; + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP: + status = csrRoamOffloadScanRspHdlr((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + break; +#endif // WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP: + if (pMsg->bodyptr) + { + sme_ProcessGetGtkInfoRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for (eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP), nothing to process"); + } + break ; +#endif + +#ifdef FEATURE_WLAN_LPHB + /* LPHB timeout indication arrived, send IND to client */ + case eWNI_SME_LPHB_IND: + if (pMac->sme.pLphbIndCb) + { + pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr); + } + vos_mem_free(pMsg->bodyptr); + + break; +#endif /* FEATURE_WLAN_LPHB */ + + case eWNI_SME_READY_TO_SUSPEND_IND: + if (pMsg->bodyptr) + { + sme_ProcessReadyToSuspend(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for (eWNI_SME_READY_TO_SUSPEND_IND), nothing to process"); + } + break ; + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + case eWNI_SME_READY_TO_EXTWOW_IND: + if (pMsg->bodyptr) + { + sme_ProcessReadyToExtWoW(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message" + "for (eWNI_SME_READY_TO_EXTWOW_IND), nothing to process"); + } + break ; +#endif + +#ifdef FEATURE_WLAN_CH_AVOID + /* channel avoid message arrived, send IND to client */ + case eWNI_SME_CH_AVOID_IND: + if (pMac->sme.pChAvoidNotificationCb) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: CH avoid notification", __func__); + pMac->sme.pChAvoidNotificationCb(pMac->hHdd, pMsg->bodyptr); + } + vos_mem_free(pMsg->bodyptr); + break; +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + case eWNI_SME_AUTO_SHUTDOWN_IND: + if (pMac->sme.pAutoShutdownNotificationCb) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Auto shutdown notification", __func__); + pMac->sme.pAutoShutdownNotificationCb(); + } + vos_mem_free(pMsg->bodyptr); + break; +#endif + + case eWNI_SME_DFS_RADAR_FOUND: + case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: + { + status = dfsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free( pMsg->bodyptr ); + } + break; + + case eWNI_SME_CHANNEL_CHANGE_RSP: + if (pMsg->bodyptr) + { + status = sme_ProcessChannelChangeResp(pMac, + pMsg->type, pMsg->bodyptr); + vos_mem_free( pMsg->bodyptr ); + } + else + { + smsLog( pMac, LOGE, + "Empty rsp message for (eWNI_SME_CHANNEL_CHANGE_RSP)," + "nothing to process"); + } + break ; + +#ifdef WLAN_FEATURE_STATS_EXT + case eWNI_SME_STATS_EXT_EVENT: + if (pMsg->bodyptr) + { + status = sme_StatsExtEvent(hHal, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, + "Empty event message for eWNI_SME_STATS_EXT_EVENT, nothing to process"); + } + break; +#endif + case eWNI_SME_LINK_SPEED_IND: + if (pMac->sme.pLinkSpeedIndCb) + { + pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr, + pMac->sme.pLinkSpeedCbContext); + } + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; + case eWNI_SME_CSA_OFFLOAD_EVENT: + if (pMsg->bodyptr) + { + csrScanFlushBssEntry(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + break; +#ifdef WLAN_FEATURE_NAN + case eWNI_SME_NAN_EVENT: + if (pMsg->bodyptr) + { + sme_NanEvent(hHal, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + break; +#endif /* WLAN_FEATURE_NAN */ + case eWNI_SME_LINK_STATUS_IND: + { + tAniGetLinkStatus *pLinkStatus = + (tAniGetLinkStatus *) pMsg->bodyptr; + if (pLinkStatus) { + if (pMac->sme.linkStatusCallback) { + pMac->sme.linkStatusCallback(pLinkStatus->linkStatus, + pMac->sme.linkStatusContext); + } + + pMac->sme.linkStatusCallback = NULL; + pMac->sme.linkStatusContext = NULL; + vos_mem_free(pLinkStatus); + } + break; + } +#ifdef FEATURE_WLAN_EXTSCAN + case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND: + { + pMac->sme.pExtScanIndCb(pMac->hHdd, + eSIR_EXTSCAN_FULL_SCAN_RESULT_IND, + pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + break; + } +#endif + default: + + if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) + && ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) ) + { + //CSR + if (pMsg->bodyptr) + { + status = csrMsgProcessor(hHal, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for CSR, nothing to process"); + } + } + else + { + smsLog( pMac, LOGW, "Unknown message type %d, nothing to process", + pMsg->type); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + }//switch + } //SME_IS_START + else + { + smsLog( pMac, LOGW, "message type %d in stop state ignored", pMsg->type); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + smsLog( pMac, LOGW, "Locking failed, bailing out"); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + + return status; +} + + +//No need to hold the global lock here because this function can only be called +//after sme_Stop. +v_VOID_t sme_FreeMsg( tHalHandle hHal, vos_msg_t* pMsg ) +{ + if( pMsg ) + { + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + +} + + +/*-------------------------------------------------------------------------- + + \brief sme_Stop() - Stop all SME modules and put them at idle state + + The function stops each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at idle state ready to start. + + This is a synchronous call + \param hHal - The handle returned by macOpen + \param tHalStopType - reason for stopping + + \return eHAL_STATUS_SUCCESS - SME is stopped. + + Other status means SME is failed to stop but caller should still + consider SME is stopped. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Stop(tHalHandle hHal, tHalStopType stopType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + eHalStatus fail_status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + +#ifndef WLAN_FEATURE_MBSSID + status = WLANSAP_Stop(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_Stop failed during smeStop with status=%d", + status ); + fail_status = status; + } +#endif + + p2pStop(hHal); + + if(!pMac->psOffloadEnabled) + { + status = pmcStop(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcStop failed during smeStop with status=%d", + status ); + fail_status = status; + } + } + else + { + status = pmcOffloadStop(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcOffloadStop failed during smeStop with status=%d", + status ); + fail_status = status; + } + } + + status = csrStop(pMac, stopType); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrStop failed during smeStop with status=%d", + status ); + fail_status = status; + } + + ccmStop(hHal); + + purgeSmeCmdList(pMac); + + if (!HAL_STATUS_SUCCESS( fail_status )) { + status = fail_status; + } + + pMac->sme.state = SME_STATE_STOP; + + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_Close() - Release all SME modules and their resources. + + The function release each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at closed state. + + No SME APIs can be involved after smeClose except smeOpen. + smeClose must be called before macClose. + This is a synchronous call + \param hHal - The handle returned by macOpen + + \return eHAL_STATUS_SUCCESS - SME is successfully close. + + Other status means SME is failed to be closed but caller still cannot + call any other SME functions except smeOpen. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Close(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + eHalStatus fail_status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + /* Note: pSession will be invalid from here on, do not access */ + status = csrClose(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrClose failed during sme close with status=%d", + status ); + fail_status = status; + } + +#ifndef WLAN_FEATURE_MBSSID + status = WLANSAP_Close(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = btcClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "BTC close failed during sme close with status=%d", + status ); + fail_status = status; + } + + status = sme_QosClose(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "Qos close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif +#ifdef FEATURE_OEM_DATA_SUPPORT + status = oemData_OemDataReqClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "OEM DATA REQ close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif + + status = ccmClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "ccmClose failed during sme close with status=%d", + status ); + fail_status = status; + } + + if(!pMac->psOffloadEnabled) + { + status = pmcClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog(pMac, LOGE, "pmcClose failed during sme close with status=%d", + status); + fail_status = status; + } + } + else + { + status = pmcOffloadClose(hHal); + if(!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, LOGE, "pmcOffloadClose failed during smeClose status=%d", + status); + fail_status = status; + } + } +#if defined WLAN_FEATURE_VOWIFI + status = rrmClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "RRM close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif + + sme_p2pClose(hHal); + + freeSmeCmdList(pMac); + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->sme.lkSmeGlobalLock ) ) ) + { + fail_status = eHAL_STATUS_FAILURE; + } + + if (!HAL_STATUS_SUCCESS( fail_status )) { + status = fail_status; + } + + pMac->sme.state = SME_STATE_STOP; + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanRequest + \brief a wrapper function to Request a 11d or full scan from CSR. + This is an asynchronous call + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not + be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanRequest(tHalHandle hHal, tANI_U8 sessionId, tCsrScanRequest *pscanReq, + tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, sessionId, pscanReq->scanType)); + smsLog(pMac, LOG2, FL("enter")); + do + { + if(pMac->scan.fScanEnable) + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if (HAL_STATUS_SUCCESS(status )) { + status = csrScanRequest(hHal, sessionId, pscanReq, + pScanRequestID, callback, pContext); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, LOGE, + FL("csrScanRequest failed sessionId(%d)"), sessionId); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } else { + smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed")); + } + } //if(pMac->scan.fScanEnable) + else + { + smsLog(pMac, LOGE, FL("fScanEnable FALSE")); + } + } while( 0 ); + + return (status); + + +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetResult + \brief a wrapper function to request scan results from CSR. + This is a synchronous call + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetResult(tHalHandle hHal, tANI_U8 sessionId, tCsrScanResultFilter *pFilter, + tScanResultHandle *phResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,0 )); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetResult( hHal, pFilter, phResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + smsLog(pMac, LOG2, FL("exit status %d"), status); + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanFlushResult + \brief a wrapper function to request CSR to clear scan results. + This is a synchronous call + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanFlushResult(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanFlushResult(hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_FilterScanResults + \brief a wrapper function to request CSR to clear scan results. + This is a synchronous call + \param tHalHandle - HAL context handle + \param sessionId - session id + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrScanFilterResults(pMac); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_ScanFlushP2PResult(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanFlushSelectiveResult( hHal, VOS_TRUE ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetFirst + \brief a wrapper function to request CSR to returns the first element of + scan result. + This is a synchronous call + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetFirst(tHalHandle hHal, + tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrScanResultInfo *pRet = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, NO_SESSION,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pRet = csrScanResultGetFirst( pMac, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (pRet); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetNext + \brief a wrapper function to request CSR to returns the next element of + scan result. It can be called without calling csrScanResultGetFirst + first + This is a synchronous call + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetNext(tHalHandle hHal, + tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrScanResultInfo *pRet = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME , + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT, NO_SESSION,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pRet = csrScanResultGetNext( pMac, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (pRet); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanSetBGScanparams + \brief a wrapper function to request CSR to set BG scan params in PE + This is a synchronous call + \param pScanReq - BG scan request structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanSetBGScanparams(tHalHandle hHal, tANI_U8 sessionId, tCsrBGScanRequest *pScanReq) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if( NULL != pScanReq ) + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanSetBGScanparams( hHal, pScanReq ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultPurge + \brief a wrapper function to request CSR to remove all items(tCsrScanResult) + in the list and free memory for each item + This is a synchronous call + \param hScanResult - returned from csrScanGetResult. hScanResult is + considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, NO_SESSION,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanResultPurge( hHal, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetPMKIDCandidateList + \brief a wrapper function to return the PMKID candidate list + This is a synchronous call + \param pPmkidList - caller allocated buffer point to an array of + tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tPmkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, + not sizeof(tPmkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetPMKIDCandidateList(tHalHandle hHal, tANI_U8 sessionId, + tPmkidCandidateInfo *pPmkidList, + tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetPMKIDCandidateList( pMac, sessionId, pPmkidList, pNumItems ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*---------------------------------------------------------------------------- + \fn sme_RoamRegisterLinkQualityIndCallback + + \brief + a wrapper function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus sme_RoamRegisterLinkQualityIndCallback(tHalHandle hHal, tANI_U8 sessionId, + csrRoamLinkQualityIndCallback callback, + void *pContext) +{ + return(csrRoamRegisterLinkQualityIndCallback((tpAniSirGlobal)hHal, callback, pContext)); +} + +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->roam.configParam.phyMode; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetChannelBondingMode5G + \brief get the channel bonding mode for 5G band + \param hHal - HAL handle + \return channel bonding mode for 5G + ---------------------------------------------------------------------------*/ +tANI_U32 sme_GetChannelBondingMode5G(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeConfigParams smeConfig; + + sme_GetConfigParam(pMac, &smeConfig); + + return smeConfig.csrConfig.channelBondingMode5GHz; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetChannelBondingMode24G + \brief get the channel bonding mode for 2.4G band + \param hHal - HAL handle + \return channel bonding mode for 2.4G + ---------------------------------------------------------------------------*/ +tANI_U32 sme_GetChannelBondingMode24G(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeConfigParams smeConfig; + + sme_GetConfigParam(pMac, &smeConfig); + + return smeConfig.csrConfig.channelBondingMode24GHz; +} + + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnect + \brief a wrapper function to request CSR to inititiate an association + This is an asynchronous call. + \param sessionId - the sessionId returned by sme_OpenSession. + \param pProfile - description of the network to which to connect + \param hBssListIn - a list of BSS descriptor to roam to. It is returned + from csrScanGetResult + \param pRoamId - to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnect(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (!pMac) + { + return eHAL_STATUS_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamConnect( pMac, sessionId, pProfile, NULL, pRoamId ); + } + else + { + smsLog(pMac, LOGE, FL("invalid sessionID %d"), sessionId); + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed")); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetPhyMode + + \brief Changes the PhyMode. + + \param hHal - The handle returned by macOpen. + + \param phyMode new phyMode which is to set + + \return eHalStatus SUCCESS. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetPhyMode(tHalHandle hHal, eCsrPhyMode phyMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return eHAL_STATUS_FAILURE; + } + + pMac->roam.configParam.phyMode = phyMode; + pMac->roam.configParam.uCfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(NULL, + pMac->roam.configParam.phyMode, + pMac->roam.configParam.ProprietaryRatesEnabled); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamReassoc + \brief a wrapper function to request CSR to inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamReassoc(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if((NULL == pProfile) && (fForce == 1)) + { + status = csrReassoc( pMac, sessionId, &modProfileFields, pRoamId , fForce); + } + else + { + status = csrRoamReassoc( pMac, sessionId, pProfile, modProfileFields, pRoamId ); + } + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnectToLastProfile + \brief a wrapper function to request CSR to disconnect and reconnect with + the same profile + This is an asynchronous call. + \return eHalStatus. It returns fail if currently connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnectToLastProfile(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamConnectToLastProfile( pMac, sessionId ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnect + \brief a wrapper function to request CSR to disconnect from a network + This is an asynchronous call. + \param reason -- To indicate the reason for disconnecting. Currently, only + eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId, reason)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamDisconnect( pMac, sessionId, reason ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamStopBss + \brief To stop BSS for Soft AP. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamStopBss(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueStopBssCmd( pMac, sessionId, eANI_BOOLEAN_TRUE ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnectSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnectSta(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pPeerMacAddr) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueDisassociateStaCmd( pMac, sessionId, pPeerMacAddr, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDeauthSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDeauthSta(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pPeerMacAddr) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueDeauthStaCmd( pMac, sessionId, pPeerMacAddr, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamTKIPCounterMeasures + \brief To start or stop TKIP counter measures. This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamTKIPCounterMeasures(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN bEnable) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueTkipCounterMeasures( pMac, sessionId, bEnable); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetAssociatedStas + \brief To probe the list of associated stations from various modules of CORE stack. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param modId - Module from whom list of associtated stations is to be probed. + If an invalid module is passed then by default VOS_MODULE_ID_PE will be probed + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetAssociatedStas(tHalHandle hHal, tANI_U8 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetAssociatedStas( pMac, sessionId, modId, pUsrContext, pfnSapEventCallback, pAssocStasBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetWpsSessionOverlap + \brief To get the WPS PBC session overlap information. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \pRemoveMac - pointer to Mac address which needs to be removed from session + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetWpsSessionOverlap(tHalHandle hHal, tANI_U8 sessionId, + void *pUsrContext, void + *pfnSapEventCallback, v_MACADDR_t pRemoveMac) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpsSessionOverlap( pMac, sessionId, pUsrContext, pfnSapEventCallback, pRemoveMac); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectState + \brief a wrapper function to request CSR to return the current connect state + of Roaming + This is a synchronous call. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectState(tHalHandle hHal, tANI_U8 sessionId, eCsrConnectState *pState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetConnectState( pMac, sessionId, pState ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectProfile + \brief a wrapper function to request CSR to return the current connect + profile. Caller must call csrRoamFreeConnectProfile after it is done + and before reuse for another csrRoamGetConnectProfile call. + This is a synchronous call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectProfile(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetConnectProfile( pMac, sessionId, pProfile ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamFreeConnectProfile + \brief a wrapper function to request CSR to free and reinitialize the + profile returned previously by csrRoamGetConnectProfile. + This is a synchronous call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamFreeConnectProfile(tHalHandle hHal, + tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamFreeConnectProfile( pMac, pProfile ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamSetPMKIDCache + \brief a wrapper function to request CSR to return the PMKID candidate list + This is a synchronous call. + \param pPMKIDCache - caller allocated buffer point to an array of + tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo + allocated when retruning, this is either the number needed + or number of items put into pPMKIDCache + \param update_entire_cache - this bool value specifies if the entire pmkid + cache should be overwritten or should it be + updated entry by entry. + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of + tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, + not sizeof(tPmkidCacheInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPMKIDCache( tHalHandle hHal, tANI_U8 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId, numItems)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamSetPMKIDCache( pMac, sessionId, pPMKIDCache, + numItems, update_entire_cache); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pBSSId, + tANI_BOOLEAN flush_cache ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamDelPMKIDfromCache( pMac, sessionId, + pBSSId, flush_cache ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/* --------------------------------------------------------------------------- + *\fn sme_RoamSetPSK_PMK + *\brief a wrapper function to request CSR to save PSK/PMK + * This is a synchronous call. + *\param hHal - Global structure + *\param sessionId - SME sessionId + *\param pPSK_PMK - pointer to an array of Psk[]/Pmk + *\param pmk_len - Length could be only 16 bytes in case if LEAP + connections. Need to pass this information to + firmware. + *\return eHalStatus -status whether PSK/PMK is set or not + *---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPSK_PMK (tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pPSK_PMK, size_t pmk_len) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) { + if (CSR_IS_SESSION_VALID(pMac, sessionId)) { + status = csrRoamSetPSK_PMK(pMac, sessionId, pPSK_PMK, pmk_len); + } + else { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return (status); +} +#endif +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityReqIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR + passes to PE to JOIN request or START_BSS request + This is a synchronous call. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityReqIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpaRsnReqIE( hHal, sessionId, pLen, pBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityRspIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE from + the beacon or probe rsp if connected + This is a synchronous call. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityRspIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpaRsnRspIE( pMac, sessionId, pLen, pBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + +} + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumPMKIDCache + \brief a wrapper function to request CSR to return number of PMKID cache + entries + This is a synchronous call. + \return tANI_U32 - the number of PMKID cache entries + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumPMKIDCache(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 numPmkidCache = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + numPmkidCache = csrRoamGetNumPMKIDCache( pMac, sessionId ); + status = eHAL_STATUS_SUCCESS; + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (numPmkidCache); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetPMKIDCache + \brief a wrapper function to request CSR to return PMKID cache from CSR + This is a synchronous call. + \param pNum - caller allocated memory that has the space of the number of + pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if + any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetPMKIDCache(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pNum, + tPmkidCacheInfo *pPmkidCache) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetPMKIDCache( pMac, sessionId, pNum, pPmkidCache ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetConfigParam + \brief a wrapper function that HDD calls to get the global settings + currently maintained by CSR. + This is a synchronous call. + \param pParam - caller allocated memory + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetConfigParam(pMac, &pParam->csrConfig); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, "%s csrGetConfigParam failed", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + pParam->fScanOffload = pMac->fScanOffload; + pParam->fP2pListenOffload = pMac->fP2pListenOffload; + pParam->max_intf_count = pMac->sme.max_intf_count; + pParam->enableSelfRecovery = pMac->sme.enableSelfRecovery; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetInt + \brief a wrapper function that HDD calls to set parameters in CFG. + This is a synchronous call. + \param cfgId - Configuration Parameter ID (type) for STA. + \param ccmValue - The information related to Configuration Parameter ID + which needs to be saved in CFG + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + return(ccmCfgSetInt(hHal, cfgId, ccmValue, callback, toBeSaved)); +} + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetStr + \brief a wrapper function that HDD calls to set parameters in CFG. + This is a synchronous call. + \param cfgId - Configuration Parameter ID (type) for STA. + \param pStr - Pointer to the byte array which carries the information needs + to be saved in CFG + \param length - Length of the data to be saved + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, + tANI_U32 length, tCcmCfgSetCallback callback, + eAniBoolean toBeSaved) +{ + return(ccmCfgSetStr(hHal, cfgId, pStr, length, callback, toBeSaved)); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields, changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. Also, make sure to call this function to get the current profile + fields before calling the reassoc. So that pModifyProfileFields will have + all the latest values plus the one(s) has been updated as part of reassoc + request. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetModifyProfileFields(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrGetModifyProfileFields(pMac, sessionId, pModifyProfileFields); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*-------------------------------------------------------------------------- + \fn sme_SetConfigPowerSave + \brief Wrapper fn to change power save configuration in SME (PMC) module. + For BMPS related configuration, this function also updates the CFG + and sends a message to FW to pick up the new values. Note: Calling + this function only updates the configuration and does not enable + the specified power save mode. + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode being modified + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_SetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE, NO_SESSION, 0)); + if (NULL == pConfigParams ) { + smsLog( pMac, LOGE, "Empty config param structure for PMC, " + "nothing to update"); + return eHAL_STATUS_FAILURE; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcSetConfigPowerSave(hHal, psMode, pConfigParams); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*-------------------------------------------------------------------------- + \fn sme_GetConfigPowerSave + \brief Wrapper fn to retrieve power save configuration in SME (PMC) module + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE, NO_SESSION, 0)); + if (NULL == pConfigParams ) { + smsLog( pMac, LOGE, "Empty config param structure for PMC, " + "nothing to update"); + return eHAL_STATUS_FAILURE; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcGetConfigPowerSave(hHal, psMode, pConfigParams); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EnablePowerSave + \brief Enables one of the power saving modes. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. If BMPS mode is enabled + while the chip is operating in Full Power, PMC will start + a timer that will try to put the chip in BMPS mode after + expiry. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_EnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcEnablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DisablePowerSave + \brief Disables one of the power saving modes. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to disable. Disabling does not imply + that device will be brought out of the current PS mode. This + is purely a configuration API. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_DisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDisablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + } + +/* --------------------------------------------------------------------------- ++ \fn sme_SetHostPowerSave ++ \brief Enables BMPS logic to be controlled by User level apps ++ \param hHal - The handle returned by macOpen. ++ \param psMode - The power saving mode to disable. Disabling does not imply ++ that device will be brought out of the current PS mode. This ++ is purely a configuration API. ++ \return eHalStatus ++ ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostPowerSave (tHalHandle hHal, v_BOOL_t psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->pmc.isHostPsEn = psMode; + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_StartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StartAutoBmpsTimer ( tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStartAutoBmpsTimer(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_StopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the sme_RequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopAutoBmpsTimer ( tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStopAutoBmpsTimer(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_QueryPowerState + \brief Returns the current power state of the device. + \param hHal - The handle returned by macOpen. + \param pPowerState - pointer to location to return power state (LOW or HIGH) + \param pSwWlanSwitchState - ptr to location to return SW WLAN Switch state + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_QueryPowerState ( + tHalHandle hHal, + tPmcPowerState *pPowerState, + tPmcSwitchState *pSwWlanSwitchState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcQueryPowerState (hHal, pPowerState, NULL, pSwWlanSwitchState); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_IsPowerSaveEnabled + \brief Checks if the device is able to enter a particular power save mode + This does not imply that the device is in a particular PS mode + \param hHal - The handle returned by macOpen. + \param sessionId - sme session id + \param psMode - the power saving mode + \return eHalStatus + ---------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal, + tANI_U32 sessionId, + tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN result = false; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if(!pMac->psOffloadEnabled) + result = pmcIsPowerSaveEnabled(hHal, psMode); + else + result = pmcOffloadIsPowerSaveEnabled(hHal, sessionId, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + return result; + } + + return false; +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestFullPower + \brief Request that the device be brought to full power state. When the + device enters Full Power PMC will start a BMPS timer if BMPS PS mode + is enabled. On timer expiry PMC will attempt to put the device in + BMPS mode if following holds true: + - BMPS mode is enabled + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestFullPower ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, + tRequestFullPowerReason fullPowerReason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER, NO_SESSION, fullPowerReason)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestFullPower(hHal, callbackRoutine, callbackContext, fullPowerReason); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestBmps + \brief Request that the device be put in BMPS state. Request will be + accepted only if BMPS mode is enabled and power save check routine + passes. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought to BMPS state + eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_BMPS, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestBmps(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_SetDHCPTillPowerActiveFlag + \brief Sets/Clears DHCP related flag in PMC to disable/enable auto BMPS + entry by PMC + \param hHal - The handle returned by macOpen. + ---------------------------------------------------------------------------*/ +void sme_SetDHCPTillPowerActiveFlag(tHalHandle hHal, tANI_U8 flag) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION, flag)); + // Set/Clear the DHCP flag which will disable/enable auto BMPS entery by PMC + pMac->pmc.remainInPowerActiveTillDHCP = flag; +} + + +/* --------------------------------------------------------------------------- + \fn sme_StartUapsd + \brief Request that the device be put in UAPSD state. If the device is in + Full Power it will be put in BMPS mode first and then into UAPSD + mode. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + eHAL_STATUS_SUCCESS - device is in UAPSD state + eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state + eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state + eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStartUapsd(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + } + +/* --------------------------------------------------------------------------- + \fn sme_StopUapsd + \brief Request that the device be put out of UAPSD state. Device will be + put in in BMPS state after stop UAPSD completes. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopUapsd (tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStopUapsd(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestStandby + \brief Request that the device be put in standby. It is HDD's responsibility + to bring the chip to full power and do a disassoc before calling + this API. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY, NO_SESSION, 0)); + smsLog( pMac, LOG1, FL(" called") ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestStandby(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RegisterPowerSaveCheck + \brief Register a power save check routine that is called whenever + the device is about to enter one of the power save modes. + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be registered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +eHalStatus sme_RegisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext), void *checkContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRegisterPowerSaveCheck (hHal, checkRoutine, checkContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_Register11dScanDoneCallback + \brief Register a routine of type csrScanCompleteCallback which is + called whenever an 11d scan is done + \param hHal - The handle returned by macOpen. + \param callback - 11d scan complete routine to be registered + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_Register11dScanDoneCallback ( + tHalHandle hHal, + csrScanCompleteCallback callback) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->scan.callback11dScanDone = callback; + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterPowerSaveCheck + \brief Deregister a power save check routine + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext)) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDeregisterPowerSaveCheck (hHal, checkRoutine); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +eHalStatus sme_RegisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRegisterDeviceStateUpdateInd (hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDeregisterDeviceStateUpdateInd (hHal, callbackRoutine); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_WowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. Note that Firmware performs the pattern matching only on + broadcast frames and while Libra is in BMPS mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus sme_WowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcWowlAddBcastPattern (hHal, pattern, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_WowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus sme_WowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcWowlDelBcastPattern (hHal, pattern, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EnterWowl + \brief This is the SME API exposed to HDD to request enabling of WOWL mode. + WoWLAN works on top of BMPS mode. If the device is not in BMPS mode, + SME will will cache the information that WOWL has been enabled and + attempt to put the device in BMPS. On entry into BMPS, SME will + enable the WOWL mode. + Note 1: If we exit BMPS mode (someone requests full power), we + will NOT resume WOWL when we go back to BMPS again. Request for full + power (while in WOWL mode) means disable WOWL and go to full power. + Note 2: Both UAPSD and WOWL work on top of BMPS. On entry into BMPS, SME + will give priority to UAPSD and enable only UAPSD if both UAPSD and WOWL + are required. Currently there is no requirement or use case to support + UAPSD and WOWL at the same time. + + \param hHal - The handle returned by macOpen. + \param enterWowlCallbackRoutine - Callback routine provided by HDD. + Used for success/failure notification by SME + \param enterWowlCallbackContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \param wakeReasonIndCB - Callback routine provided by HDD. + Used for Wake Reason Indication by SME + \param wakeReasonIndCBContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \return eHalStatus + eHAL_STATUS_SUCCESS Device is already in WoWLAN mode + eHAL_STATUS_FAILURE Device cannot enter WoWLAN mode. + eHAL_STATUS_PMC_PENDING Request accepted. SME will enable WOWL after + BMPS mode is entered. + ---------------------------------------------------------------------------*/ +eHalStatus sme_EnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeIndicationCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeIndicationCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ENTER_WOWL, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcEnterWowl (hHal, enterWowlCallbackRoutine, enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + wakeIndicationCB, wakeIndicationCBContext, +#endif // WLAN_WAKEUP_EVENTS + wowlEnterParams, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_ExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. + \param hHal - The handle returned by macOpen. + \param wowlExitParams - Carries info on which smesession + wowl exit is requested. + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +eHalStatus sme_ExitWowl (tHalHandle hHal, tpSirSmeWowlExitParams wowlExitParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcExitWowl (hHal, wowlExitParams); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_RoamSetKey + + \brief To set encryption key. This function should be called only when connected + This is an asynchronous API. + + \param pSetKeyInfo - pointer to a caller allocated object of tCsrSetContextInfo + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetKey(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 roamId; + tANI_U32 i; + tCsrRoamSession *pSession = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_KEY, sessionId, 0)); + if (pSetKey->keyLength > CSR_MAX_KEY_LEN) + { + smsLog(pMac, LOGE, FL("Invalid key length %d"), pSetKey->keyLength); + return eHAL_STATUS_FAILURE; + } + /*Once Setkey is done, we can go in BMPS*/ + if(pSetKey->keyLength) + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + smsLog(pMac, LOG2, FL("keyLength %d"), pSetKey->keyLength); + + for(i=0; ikeyLength; i++) + smsLog(pMac, LOG2, FL("%02x"), pSetKey->Key[i]); + + smsLog(pMac, LOG2, "\n sessionId=%d roamId=%d", sessionId, roamId); + + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if(CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + if(pSetKey->keyDirection == eSIR_TX_DEFAULT) + { + if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pSetKey->encType )) + { + pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + if ( ( eCSR_ENCRYPT_TYPE_WEP104 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pSetKey->encType )) + { + pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + } + + status = csrRoamSetKey ( pMac, sessionId, pSetKey, roamId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_RoamRemoveKey + + \brief To set encryption key. This is an asynchronous API. + + \param pRemoveKey - pointer to a caller allocated object of tCsrRoamRemoveKey + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamRemoveKey(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 roamId; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REMOVE_KEY, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + status = csrRoamIssueRemoveKeyCommand( pMac, sessionId, pRemoveKey, roamId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetRssi + \brief a wrapper function that client calls to register a callback to get + RSSI + + \param hHal - HAL handle for device + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid of the connected session + \param lastRSSI - RSSI value at time of request. In case fw cannot provide + RSSI, do not hold up but return this value. + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, tANI_S8 lastRSSI, + void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRssi( pMac, callback, + staId, bssId, lastRSSI, + pContext, pVosContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetSnr + \brief a wrapper function that client calls to register a callback to + get SNR + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetSnr(tHalHandle hHal, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetSnr(pMac, callback, + staId, bssId, pContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_GetRoamRssi + \brief a wrapper function that client calls to register a callback to get Roam RSSI + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetRoamRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRoamRssi( pMac, callback, + staId, bssId, pContext, pVosContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn sme_GetTsmStats + \brief a wrapper function that client calls to register a callback to + get TSM Stats + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetTsmStats(tHalHandle hHal, + tCsrTsmStatsCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext, tANI_U8 tid) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetTsmStats( pMac, callback, + staId, bssId, pContext, pVosContext, tid); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_GetStatistics + \brief a wrapper function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update in millisec, 0 means + it's an one time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param sessionId - sme session interface + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION, periodicity)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetStatistics( pMac, requesterId , statsMask, callback, + periodicity, cache, staId, pContext, + sessionId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + +} + +eHalStatus sme_getLinkStatus(tHalHandle hHal, + tCsrLinkStatusCallback callback, + void *pContext, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tAniGetLinkStatus *pMsg; + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) { + pMsg = vos_mem_malloc(sizeof(tAniGetLinkStatus)); + if (NULL == pMsg) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for link status", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = WDA_LINK_STATUS_GET_REQ; + pMsg->msgLen = (tANI_U16)sizeof(tAniGetLinkStatus); + pMsg->sessionId = sessionId; + pMac->sme.linkStatusContext = pContext; + pMac->sme.linkStatusCallback = callback; + + vosMessage.type = WDA_LINK_STATUS_GET_REQ; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, + &vosMessage))) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post LINK STATUS MSG fail", __func__); + vos_mem_free(pMsg); + pMac->sme.linkStatusContext = NULL; + pMac->sme.linkStatusCallback = NULL; + status = eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn smeGetTLSTAState + \helper function to get the TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 smeGetTLSTAState(tHalHandle hHal, tANI_U8 staId) +{ + tANI_U16 tlSTAState = TL_INIT_STATE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + tlSTAState = csrGetTLSTAState( pMac, staId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return tlSTAState; +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetCountryCode + + \brief To return the current country code. If no country code is applied, default country code is + used to fill the buffer. + If 11d supported is turned off, an error is return and the last applied/default country code is used. + This is a synchronous API. + + \param pBuf - pointer to a caller allocated buffer for returned country code. + + \param pbLen For input, this parameter indicates how big is the buffer. + Upon return, this parameter has the number of bytes for country. If pBuf + doesn't have enough space, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U8 *pbLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0)); + + return ( csrGetCountryCode( pMac, pBuf, pbLen ) ); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_SetCountryCode + + \brief To change the current/default country code. + If 11d supported is turned off, an error is return. + This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for the country code. + + \param pfRestartNeeded A pointer to caller allocated memory, upon successful return, it indicates + whether a reset is required. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetCountryCode(tHalHandle hHal, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, NO_SESSION, 0)); + return ( csrSetCountryCode( pMac, pCountry, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. This is a synchronous API. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_ResetCountryCodeInformation(tHalHandle hHal, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrResetCountryCodeInformation( pMac, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed byte count. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf. If pbuf is NULL, as input, *pbLen should be 0. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U32 *pbLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrGetSupportedCountryCode( pMac, pBuf, pbLen ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. This is a synchronous API. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. The function fails if 11d support is turned off. + \param pDomain - Caller allocated buffer to return the current domain. + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t *pDomain) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if( pDomain ) + { + if( csrIs11dSupported( pMac ) ) + { + *pDomain = csrGetCurrentRegulatoryDomain( pMac ); + status = eHAL_STATUS_SUCCESS; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + + return ( status ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_SetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. This is a synchronous API. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See v_REGDOMAIN_t for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrSetRegulatoryDomain( pMac, domainId, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_GetRegulatoryDomainForCountry + + \brief To return a regulatory domain base on a country code. This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for input country code. + + \param pDomainId Upon successful return, it is the domain that country belongs to. + If it is NULL, returning success means that the country code is known. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetRegulatoryDomainForCountry(tHalHandle hHal, tANI_U8 *pCountry, v_REGDOMAIN_t *pDomainId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return csrGetRegulatoryDomainForCountry(pMac, pCountry, pDomainId, + COUNTRY_QUERY); +} + + + + +/* --------------------------------------------------------------------------- + + \fn sme_GetSupportedRegulatoryDomains + + \brief To return a list of supported regulatory domains. This is a synchronous API. + + \param pDomains - pointer to a caller allocated buffer for returned regulatory domains. + + \param pNumDomains For input, this parameter indicates howm many domains pDomains can hold. + Upon return, this parameter has the number for supported domains. If pDomains + doesn't have enough space for all the supported domains, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedRegulatoryDomains(tHalHandle hHal, v_REGDOMAIN_t *pDomains, tANI_U32 *pNumDomains) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + //We support all domains for now + if( pNumDomains ) + { + if( NUM_REG_DOMAINS <= *pNumDomains ) + { + status = eHAL_STATUS_SUCCESS; + } + *pNumDomains = NUM_REG_DOMAINS; + } + if( HAL_STATUS_SUCCESS( status ) ) + { + if( pDomains ) + { + pDomains[0] = REGDOMAIN_FCC; + pDomains[1] = REGDOMAIN_ETSI; + pDomains[2] = REGDOMAIN_JAPAN; + pDomains[3] = REGDOMAIN_WORLD; + pDomains[4] = REGDOMAIN_N_AMER_EXC_FCC; + pDomains[5] = REGDOMAIN_APAC; + pDomains[6] = REGDOMAIN_KOREA; + pDomains[7] = REGDOMAIN_HI_5GHZ; + pDomains[8] = REGDOMAIN_NO_5GHZ; + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + } + + return ( status ); +} + + +//some support functions +tANI_BOOLEAN sme_Is11dSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIs11dSupported( pMac ) ); +} + + +tANI_BOOLEAN sme_Is11hSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIs11hSupported( pMac ) ); +} + + +tANI_BOOLEAN sme_IsWmmSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIsWmmSupported( pMac ) ); +} + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus sme_ScanGetBaseChannels( tHalHandle hHal, tCsrChannelInfo * pChannelInfo ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return(csrScanGetBaseChannels(pMac,pChannelInfo) ); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param sendRegHint If we want to send reg hint to nl80211 + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeCountryCode( tHalHandle hHal, + tSmeChangeCountryCallback callback, + tANI_U8 *pCountry, + void *pContext, + void* pVosContext, + tAniBool countryFromUserSpace, + tAniBool sendRegHint ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + tAniChangeCountryCodeReq *pMsg; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOG1, FL(" called")); + + if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true) && + (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + + smsLog(pMac, LOGW, "Set Country Code Fail since the STA is associated and userspace does not have priority "); + + sme_ReleaseGlobalLock( &pMac->sme ); + status = eHAL_STATUS_FAILURE; + return status; + } + + pMsg = vos_mem_malloc(sizeof(tAniChangeCountryCodeReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrChangeCountryCode: failed to allocate mem for req"); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANGE_COUNTRY_CODE); + pMsg->msgLen = (tANI_U16)sizeof(tAniChangeCountryCodeReq); + vos_mem_copy(pMsg->countryCode, pCountry, 3); + pMsg->countryFromUserSpace = countryFromUserSpace; + pMsg->sendRegHint = sendRegHint; + pMsg->changeCCCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + + msg.type = eWNI_SME_CHANGE_COUNTRY_CODE; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " sme_ChangeCountryCode failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL(" returned")); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*-------------------------------------------------------------------------- + + \fn sme_GenericChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param reg_domain regulatory domain + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + +-----------------------------------------------------------------------------*/ +eHalStatus sme_GenericChangeCountryCode( tHalHandle hHal, + tANI_U8 *pCountry, + v_REGDOMAIN_t reg_domain) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + tAniGenericChangeCountryCodeReq *pMsg; + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOG1, FL(" called")); + pMsg = vos_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq)); + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, " sme_GenericChangeCountryCode: failed to allocate mem for req"); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE); + pMsg->msgLen = (tANI_U16)sizeof(tAniGenericChangeCountryCodeReq); + vos_mem_copy(pMsg->countryCode, pCountry, 2); + pMsg->domain_index = reg_domain; + + msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, "sme_GenericChangeCountryCode failed to post msg to self"); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL(" returned")); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStartInd + + \brief API to signal the FW about the DHCP Start event. + + \param hHal - HAL handle for device. + + \param device_mode - mode(AP,SAP etc) of the device. + + \param macAddr - MAC address of the adapter. + + \param sessionId - session ID. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + --------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStartInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 *macAddr, + tANI_U8 sessionId ) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t vosMessage; + tAniDHCPInd *pMsg; + tCsrRoamSession *pSession; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for dhcp start", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pMsg->msgType = WDA_DHCP_START_IND; + pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd); + pMsg->device_mode = device_mode; + vos_mem_copy( pMsg->adapterMacAddr, macAddr, sizeof(tSirMacAddr)); + vos_mem_copy( pMsg->peerMacAddr, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr) ); + + vosMessage.type = WDA_DHCP_START_IND; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post DHCP Start MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_DHCPStopInd + + \brief API to signal the FW about the DHCP complete event. + + \param hHal - HAL handle for device. + + \param device_mode - mode(AP, SAP etc) of the device. + + \param macAddr - MAC address of the adapter. + + \param sessionId - session ID. + + \return eHalStatus SUCCESS. + FAILURE or RESOURCES The API finished and failed. + --------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStopInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 *macAddr, + tANI_U8 sessionId ) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t vosMessage; + tAniDHCPInd *pMsg; + tCsrRoamSession *pSession; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for dhcp stop", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = WDA_DHCP_STOP_IND; + pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd); + pMsg->device_mode = device_mode; + vos_mem_copy( pMsg->adapterMacAddr, macAddr, sizeof(tSirMacAddr)); + vos_mem_copy( pMsg->peerMacAddr, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr) ); + + vosMessage.type = WDA_DHCP_STOP_IND; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post DHCP Stop MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_BtcSignalBtEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE BT Event not passed to HAL. This can happen + if BTC execution mode is set to BTC_WLAN_ONLY + or BTC_PTA_ONLY. + VOS_STATUS_SUCCESS BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSignalBtEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcSignalBTEvent (hHal, pBtEvent); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_BtcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + Calling it after sme_HDDReadyInd is recommended. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type tSmeBtcConfig. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcSetConfig (hHal, pSmeBtcConfig); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_BtcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcGetConfig (hHal, pSmeBtcConfig); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_SetCfgPrivacy + \brief API to set configure privacy parameters + \param hHal - The handle returned by macOpen. + \param pProfile - Pointer CSR Roam profile. + \param fPrivacy - This parameter indicates status of privacy + + \return void + ---------------------------------------------------------------------------*/ +void sme_SetCfgPrivacy( tHalHandle hHal, + tCsrRoamProfile *pProfile, + tANI_BOOLEAN fPrivacy + ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + csrSetCfgPrivacy(pMac, pProfile, fPrivacy); + sme_ReleaseGlobalLock( &pMac->sme ); + } +} + +#if defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + \fn sme_NeighborReportRequest + \brief API to request neighbor report. + \param hHal - The handle returned by macOpen. + \param pRrmNeighborReq - Pointer to a caller allocated object of type + tRrmNeighborReq. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_NeighborReportRequest (tHalHandle hHal, tANI_U8 sessionId, + tpRrmNeighborReq pRrmNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION, 0)); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = sme_RrmNeighborReportRequest (hHal, sessionId, pRrmNeighborReq, callbackInfo); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif + +void pmcLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) +{ + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level */ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + + VOS_TRACE(VOS_MODULE_ID_PMC, vosDebugLevel, "%s", logBuffer); + va_end( marker ); +} + + +void smsLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SMS_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssWlanCompiledVersion + \brief This API returns the version of the WCNSS WLAN API with + which the HOST driver was built + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version structure to be filled + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssWlanCompiledVersion(tHalHandle hHal, + tSirVersionType *pVersion) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssWlanCompiledVersion(vosContext, pVersion); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssWlanReportedVersion + \brief This API returns the version of the WCNSS WLAN API with + which the WCNSS driver reports it was built + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version structure to be filled + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssWlanReportedVersion(tHalHandle hHal, + tSirVersionType *pVersion) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssWlanReportedVersion(vosContext, pVersion); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssSoftwareVersion + \brief This API returns the version string of the WCNSS driver + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version string buffer to be filled + \param versionBufferSize - THe size of the Version string buffer + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssSoftwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssSoftwareVersion(vosContext, pVersion, + versionBufferSize); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssHardwareVersion + \brief This API returns the version string of the WCNSS hardware + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version string buffer to be filled + \param versionBufferSize - THe size of the Version string buffer + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssHardwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssHardwareVersion(vosContext, pVersion, + versionBufferSize); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +#ifdef FEATURE_WLAN_WAPI + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetBKIDCandidateList + \brief a wrapper function to return the BKID candidate list + \param pBkidList - caller allocated buffer point to an array of + tBkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tBkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tBkidCandidateInfo. + \Note: pNumItems is a number of tBkidCandidateInfo, + not sizeof(tBkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetBKIDCandidateList(tHalHandle hHal, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, + tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetBKIDCandidateList( pMac, sessionId, pBkidList, pNumItems ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/***************************************************************************** + OEM DATA related modifications and function additions + *****************************************************************************/ + +/* --------------------------------------------------------------------------- + \fn sme_getOemDataRsp + \brief a wrapper function to obtain the OEM DATA RSP + \param pOemDataRsp - A pointer to the response object + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_getOemDataRsp(tHalHandle hHal, + tOemDataRsp **pOemDataRsp) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + + if(pMac->oemData.pOemDataRsp != NULL) + { + *pOemDataRsp = pMac->oemData.pOemDataRsp; + } + else + { + status = eHAL_STATUS_FAILURE; + } + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_OemDataReq + \brief a wrapper function for OEM DATA REQ + \param sessionId - session id to be used. + \param pOemDataReqId - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *pOemDataReqConfig, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + tANI_U32 lOemDataReqId = pMac->oemData.oemDataReqID++; //let it wrap around + + if(pOemDataReqID) + { + *pOemDataReqID = lOemDataReqId; + } + else + { + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + status = oemData_OemDataReq(hHal, sessionId, pOemDataReqConfig, pOemDataReqID, callback, pContext); + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + } while(0); + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + +/*-------------------------------------------------------------------------- + + \brief sme_OpenSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + \param callback - A pointer to the function caller specifies for roam/connect status indication + \param pContext - The context passed with callback + \param pSelfMacAddr - Caller allocated memory filled with self MAC address (6 bytes) + \param pbSessionId - pointer to a caller allocated buffer for returned session ID + + \return eHAL_STATUS_SUCCESS - session is opened. sessionId returned. + + Other status means SME is failed to open the session. + eHAL_STATUS_RESOURCES - no more session available. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_OpenSession(tHalHandle hHal, csrRoamCompleteCallback callback, + void *pContext, + tANI_U8 *pSelfMacAddr, tANI_U8 *pbSessionId, + tANI_U32 type, tANI_U32 subType) +{ + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: type=%d, subType=%d", __func__, type, subType); + + if( NULL == pbSessionId ) + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + else + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamOpenSession( pMac, callback, pContext, pSelfMacAddr, + pbSessionId, type, subType ); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + if( NULL != pbSessionId ) + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION,*pbSessionId, 0)); + + return ( status ); +} + + +/*-------------------------------------------------------------------------- + + \brief sme_CloseSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + + \param sessionId - A previous opened session's ID. + + \return eHAL_STATUS_SUCCESS - session is closed. + + Other status means SME is failed to open the session. + eHAL_STATUS_INVALID_PARAMETER - session is not opened. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId, + csrRoamSessionCloseCallback callback, void *pContext) +{ + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamCloseSession( pMac, sessionId, FALSE, + callback, pContext ); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return ( status ); +} + +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPSIE + + \brief To update AP's WPS IE. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs + + \return eHalStatus – SUCCESS – + + FAILURE or RESOURCES – The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPSIE(tHalHandle hHal, tANI_U8 sessionId, tSirAPWPSIEs *pAPWPSIES) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + status = csrRoamUpdateAPWPSIE( pMac, sessionId, pAPWPSIES ); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPARSNIEs + + \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs + + \return eHalStatus – SUCCESS – + + FAILURE or RESOURCES – The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + status = csrRoamUpdateWPARSNIEs( pMac, sessionId, pAPSirRSNie); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + + \fn sme_ChangeMCCBeaconInterval + + \brief To update P2P-GO beaconInterval. This function should be called after + disassociating all the station is done + This is an asynchronous API. + + \param + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG1, FL("Update Beacon PARAMS ")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrSendChngMCCBeaconInterval( pMac, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/*-------------------------------------------------------------------------------* + + \fn sme_sendBTAmpEvent + + \brief to receive the coex priorty request from BT-AMP PAL + and send the BT_AMP link state to HAL + + \param btAmpEvent - btAmpEvent + + \return eHalStatus: SUCCESS : BTAmp event successfully sent to HAL + + FAILURE: API failed + +-------------------------------------------------------------------------------*/ + +eHalStatus sme_sendBTAmpEvent(tHalHandle hHal, tSmeBtAmpEvent btAmpEvent) +{ + vos_msg_t msg; + tpSmeBtAmpEvent ptrSmeBtAmpEvent = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + + ptrSmeBtAmpEvent = vos_mem_malloc(sizeof(tpSmeBtAmpEvent)); + if (NULL == ptrSmeBtAmpEvent) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for BTAmp event", __func__); + return status; + } + + vos_mem_copy(ptrSmeBtAmpEvent, (void*)&btAmpEvent, sizeof(tSmeBtAmpEvent)); + msg.type = WDA_SIGNAL_BTAMP_EVENT; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtAmpEvent; + + //status = halFW_SendBTAmpEventMesg(pMac, event); + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_SIGNAL_BTAMP_EVENT message to HAL", __func__); + vos_mem_free(ptrSmeBtAmpEvent); + return status; + } + + return eHAL_STATUS_SUCCESS; + +} + +/* --------------------------------------------------------------------------- + \fn smeIssueFastRoamNeighborAPEvent + \brief API to trigger fast BSS roam independent of RSSI triggers + \param hHal - The handle returned by macOpen. + \param bssid - Pointer to the BSSID to roam to. + \param fastRoamTrig - Trigger to Scan or roam + \param sessionId - Session Identifier + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus smeIssueFastRoamNeighborAPEvent(tHalHandle hHal, + tANI_U8 *bssid, + tSmeFastRoamTrigger fastRoamTrig, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + tFTRoamCallbackUsrCtx *pUsrCtx; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: invoked", __func__); + + if (eSME_ROAM_TRIGGER_SCAN == fastRoamTrig) + { + smsLog(pMac, LOG1, FL("CFG Channel list scan... ")); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_SCAN; + vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId), + (void *)bssid, sizeof(tSirMacAddr)); + smsLog(pMac, LOG1, "Calling Roam Look Up down Event BSSID " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId)); + + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac, sessionId); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, + FL("CFG Channel list scan state failed with status %d "), + vosStatus); + } + } + else if (eSME_ROAM_TRIGGER_FAST_ROAM == fastRoamTrig) + { + vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId), + (void *)bssid, sizeof(tSirMacAddr)); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_FAST_ROAM; + smsLog(pMac, LOG1, "Roam to BSSID "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId)); + + pUsrCtx = vos_mem_malloc(sizeof(*pUsrCtx)); + if (NULL == pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + /* Populate user context */ + pUsrCtx->pMac = pMac; + pUsrCtx->sessionId = sessionId; + + vosStatus = csrNeighborRoamReassocIndCallback( + pMac->roam.gVosContext, + 0, pUsrCtx, 0); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, + LOGE, + FL(" Call to csrNeighborRoamReassocIndCallback failed, status = %d"), + vosStatus); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return vosStatus; +} +/* --------------------------------------------------------------------------- + \fn sme_SetHostOffload + \brief API to set the host offload feature. + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostOffload (tHalHandle hHal, tANI_U8 sessionId, + tpSirHostOffloadReq pRequest) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { +#ifdef WLAN_NS_OFFLOAD + if(SIR_IPV6_NS_OFFLOAD == pRequest->offloadType) + { + status = pmcSetNSOffload( hHal, pRequest, sessionId); + } + else +#endif //WLAN_NS_OFFLOAD + { + status = pmcSetHostOffload (hHal, pRequest, sessionId); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_SetGTKOffload + \brief API to set GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pRequest, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = pmcSetGTKOffload( hHal, pRequest, sessionId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetGTKOffload + \brief API to get GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload response. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetGTKOffload (tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcGetGTKOffload(hHal, callbackRoutine, callbackContext, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/* --------------------------------------------------------------------------- + \fn sme_SetKeepAlive + \brief API to set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetKeepAlive (tHalHandle hHal, tANI_U8 sessionId, + tpSirKeepAliveReq pRequest) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = pmcSetKeepAlive (hHal, pRequest, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/* --------------------------------------------------------------------------- + \fn sme_SetPreferredNetworkList + \brief API to set the Preferred Network List Offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPreferredNetworkList (tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, void (*callbackRoutine) (void *callbackContext, tSirPrefNetworkFoundInd *pPrefNetworkFoundInd), void *callbackContext ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetPreferredNetworkList(hHal, pRequest, sessionId, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_SetRSSIFilter(tHalHandle hHal, v_U8_t rssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetRssiFilter(hHal, rssiThreshold); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#endif // FEATURE_WLAN_SCAN_PNO + +eHalStatus sme_SetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetPowerParams(hHal, pwParams, forced); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_AbortMacScan + \brief API to cancel MAC scan. + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId on which we need to abort scan. + \param reason - Reason to abort the scan. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +eHalStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId, + eCsrAbortReason reason) +{ + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanAbortMacScan(pMac, sessionId, reason); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return ( status ); +} + +/* ---------------------------------------------------------------------------- + \fn sme_GetOperationChannel + \brief API to get current channel on which STA is parked + this function gives channel information only of infra station or IBSS station + \param hHal, pointer to memory location and sessionId + \returns eHAL_STATUS_SUCCESS + eHAL_STATUS_FAILURE +-------------------------------------------------------------------------------*/ +eHalStatus sme_GetOperationChannel(tHalHandle hHal, tANI_U32 *pChannel, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession; + + if (CSR_IS_SESSION_VALID( pMac, sessionId )) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_IBSS ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRA_AP ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_START_IBSS )) + { + *pChannel =pSession->connectedProfile.operationChannel; + return eHAL_STATUS_SUCCESS; + } + } + return eHAL_STATUS_FAILURE; +}// sme_GetOperationChannel ends here + +/* --------------------------------------------------------------------------- + + \fn sme_RegisterMgtFrame + + \brief To register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RegisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tSirRegisterMgmtFrame *pMsg; + tANI_U16 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!CSR_IS_SESSION_ANY(sessionId) && !pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Invalid Sessionid", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + len = sizeof(tSirRegisterMgmtFrame) + matchLen; + + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, len, 0); + pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; + pMsg->length = len; + pMsg->sessionId = sessionId; + pMsg->registerFrame = VOS_TRUE; + pMsg->frameType = frameType; + pMsg->matchLen = matchLen; + vos_mem_copy(pMsg->matchData, matchData, matchLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_DeregisterMgtFrame + + \brief To De-register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tSirRegisterMgmtFrame *pMsg; + tANI_U16 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!CSR_IS_SESSION_ANY(sessionId) && !pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Invalid Sessionid", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + len = sizeof(tSirRegisterMgmtFrame) + matchLen; + + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, len, 0); + pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; + pMsg->length = len; + pMsg->registerFrame = VOS_FALSE; + pMsg->frameType = frameType; + pMsg->matchLen = matchLen; + vos_mem_copy(pMsg->matchData, matchData, matchLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_RemainOnChannel + \brief API to request remain on channel for 'x' duration. used in p2p in listen state + \param hHal - The handle returned by macOpen. + \param pRequest - channel + \param duration - duration in ms + \param callback - HDD registered callback to process reaminOnChannelRsp + \param context - HDD Callback param + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RemainOnChannel(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pRemainOnChannel (hHal, sessionId, channel, duration, callback, pContext, + isP2PProbeReqAllowed + ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ReportProbeReq + \brief API to enable/disable forwarding of probeReq to apps in p2p. + \param hHal - The handle returned by macOpen. + \param falg: to set the Probe request forarding to wpa_supplicant in listen state in p2p + \return eHalStatus + ---------------------------------------------------------------------------*/ + +#ifndef WLAN_FEATURE_CONCURRENT_P2P +eHalStatus sme_ReportProbeReq(tHalHandle hHal, tANI_U8 flag) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + /* call set in context */ + pMac->p2pContext.probeReqForwarding = flag; + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + } while(0); + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_updateP2pIe + \brief API to set the P2p Ie in p2p context + \param hHal - The handle returned by macOpen. + \param p2pIe - Ptr to p2pIe from HDD. + \param p2pIeLength: length of p2pIe + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_updateP2pIe(tHalHandle hHal, void *p2pIe, tANI_U32 p2pIeLength) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, NO_SESSION, 0)); + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + if(NULL != pMac->p2pContext.probeRspIe){ + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIeLength = 0; + } + + pMac->p2pContext.probeRspIe = vos_mem_malloc(p2pIeLength); + if (NULL == pMac->p2pContext.probeRspIe) + { + smsLog(pMac, LOGE, "%s: Unable to allocate P2P IE", __func__); + pMac->p2pContext.probeRspIeLength = 0; + status = eHAL_STATUS_FAILURE; + } + else + { + pMac->p2pContext.probeRspIeLength = p2pIeLength; + + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG2, + pMac->p2pContext.probeRspIe, + pMac->p2pContext.probeRspIeLength ); + vos_mem_copy((tANI_U8 *)pMac->p2pContext.probeRspIe, p2pIe, + p2pIeLength); + } + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + + smsLog(pMac, LOG2, "exiting function %s", __func__); + + return(status); +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_sendAction + \brief API to send action frame from supplicant. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_sendAction(tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0)); + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + p2pSendAction(hHal, sessionId, pBuf, len, wait, noack); + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +eHalStatus sme_CancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pCancelRemainOnChannel (hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +//Power Save Related +eHalStatus sme_p2pSetPs(tHalHandle hHal, tP2pPsConfig * data) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pSetPs (hHal, data); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureRxpFilter + + \brief + SME will pass this request to lower mac to set/reset the filter on RXP for + multicast & broadcast traffic. + + \param + + hHal - The handle returned by macOpen. + + filterMask- Currently the API takes a 1 or 0 (set or reset) as filter. + Basically to enable/disable the filter (to filter "all" mcbc traffic) based + on this param. In future we can use this as a mask to set various types of + filters as suggested below: + FILTER_ALL_MULTICAST: + FILTER_ALL_BROADCAST: + FILTER_ALL_MULTICAST_BROADCAST: + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureRxpFilter( tHalHandle hHal, + tpSirWlanSetRxpFilters wlanRxpFilterParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanRxpFilterParam; + vosMessage.type = WDA_CFG_RXP_FILTER_REQ; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureSuspendInd + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be suspended + + \param + + hHal - The handle returned by macOpen. + + wlanSuspendParam- Depicts the wlan suspend params + + csrReadyToSuspendCallback - Callback to be called when ready to suspend + event is received. + callbackContext - Context associated with csrReadyToSuspendCallback. + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal, + tpSirWlanSuspendParam wlanSuspendParam, + csrReadyToSuspendCallback callback, + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION, 0)); + + pMac->readyToSuspendCallback = callback; + pMac->readyToSuspendContext = callbackContext; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanSuspendParam; + vosMessage.type = WDA_WLAN_SUSPEND_IND; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) { + pMac->readyToSuspendCallback = NULL; + pMac->readyToSuspendContext = NULL; + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureResumeReq + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be Resumed + + \param + + hHal - The handle returned by macOpen. + + wlanResumeParam- Depicts the wlan resume params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureResumeReq( tHalHandle hHal, + tpSirWlanResumeParam wlanResumeParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanResumeParam; + vosMessage.type = WDA_WLAN_RESUME_REQ; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureExtWoW + + \brief + SME will pass this request to lower mac to configure Extr WoW + + \param + + hHal - The handle returned by macOpen. + + wlanExtParams- Depicts the wlan Ext params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureExtWoW( tHalHandle hHal, + tpSirExtWoWParams wlanExtParams, + csrReadyToExtWoWCallback callback, + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirExtWoWParams MsgPtr = vos_mem_malloc(sizeof(*MsgPtr)); + + if (!MsgPtr) + return eHAL_STATUS_FAILURE; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0)); + + pMac->readyToExtWoWCallback = callback; + pMac->readyToExtWoWContext = callbackContext; + + if ( eHAL_STATUS_SUCCESS == + ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) { + + /* serialize the req through MC thread */ + vos_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr)); + vosMessage.bodyptr = MsgPtr; + vosMessage.type = WDA_WLAN_EXT_WOW; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) { + pMac->readyToExtWoWCallback = NULL; + pMac->readyToExtWoWContext = NULL; + vos_mem_free(MsgPtr); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } else { + pMac->readyToExtWoWCallback = NULL; + pMac->readyToExtWoWContext = NULL; + vos_mem_free(MsgPtr); + } + + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppType1Params + + \brief + SME will pass this request to lower mac to configure Indoor WoW parameters. + + \param + + hHal - The handle returned by macOpen. + + wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppType1Params( tHalHandle hHal, + tpSirAppType1Params wlanAppType1Params) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirAppType1Params MsgPtr = vos_mem_malloc(sizeof(*MsgPtr)); + + if (!MsgPtr) + return eHAL_STATUS_FAILURE; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION, 0)); + + if ( eHAL_STATUS_SUCCESS == + ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) { + + /* serialize the req through MC thread */ + vos_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr)); + vosMessage.bodyptr = MsgPtr; + vosMessage.type = WDA_WLAN_SET_APP_TYPE1_PARAMS; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) { + vos_mem_free(MsgPtr); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } else { + vos_mem_free(MsgPtr); + } + + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppType2Params + + \brief + SME will pass this request to lower mac to configure Indoor WoW parameters. + + \param + + hHal - The handle returned by macOpen. + + wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppType2Params( tHalHandle hHal, + tpSirAppType2Params wlanAppType2Params) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirAppType2Params MsgPtr = vos_mem_malloc(sizeof(*MsgPtr)); + + if (!MsgPtr) + return eHAL_STATUS_FAILURE; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION, 0)); + + if ( eHAL_STATUS_SUCCESS == + ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) { + + /* serialize the req through MC thread */ + vos_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr)); + vosMessage.bodyptr = MsgPtr; + vosMessage.type = WDA_WLAN_SET_APP_TYPE2_PARAMS; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) { + vos_mem_free(MsgPtr); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } else { + vos_mem_free(MsgPtr); + } + + return(status); +} +#endif + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraSessionId + + \brief To get the session ID for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \return sessionid, -1 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_S8 sme_GetInfraSessionId(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_S8 sessionid = -1; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + sessionid = csrGetInfraSessionId( pMac); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (sessionid); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraOperationChannel + + \brief To get the operating channel for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param sessionId - the sessionId returned by sme_OpenSession. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetInfraOperationChannel( tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 channel = 0; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + channel = csrGetInfraOperationChannel( pMac, sessionId); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (channel); +} + +//This routine will return poerating channel on which other BSS is operating to be used for concurrency mode. +//If other BSS is not up or not connected it will return 0 +tANI_U8 sme_GetConcurrentOperationChannel( tHalHandle hHal ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 channel = 0; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + channel = csrGetConcurrentOperationChannel( pMac ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: " + " Other Concurrent Channel = %d", __func__,channel); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (channel); +} +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +v_U16_t sme_CheckConcurrentChannelOverlap( tHalHandle hHal, v_U16_t sap_ch, + eCsrPhyMode sapPhyMode, v_U8_t cc_switch_mode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_U16_t channel = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + channel = csrCheckConcurrentChannelOverlap( pMac, sap_ch, sapPhyMode, + cc_switch_mode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (channel); +} +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +/****************************************************************************** +* +* Name: sme_PreferredNetworkFoundInd +* +* Description: +* Invoke Preferred Network Found Indication +* +* Parameters: +* hHal - HAL handle for device +* pMsg - found network description +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PreferredNetworkFoundInd (tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd = (tSirPrefNetworkFoundInd *)pMsg; + v_U8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1]; + tANI_U8 ssIdLength = 0; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + return eHAL_STATUS_FAILURE; + } + + if (pMac->pnoOffload) + { + /* Call Preferred Network Found Indication callback routine. */ + if (pMac->pmc.prefNetwFoundCB != NULL) + { + pMac->pmc.prefNetwFoundCB( + pMac->pmc.preferredNetworkFoundIndCallbackContext, + pPrefNetworkFoundInd); + } + return status; + } + + if (pPrefNetworkFoundInd->ssId.length > 0) + { + ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH, + pPrefNetworkFoundInd->ssId.length); + vos_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId, ssIdLength); + dumpSsId[ssIdLength] = 0; + smsLog(pMac, LOG2, "%s:SSID=%s frame length %d", + __func__, dumpSsId, pPrefNetworkFoundInd->frameLength); + + /* Flush scan results, So as to avoid indication/updation of + * stale entries, which may not have aged out during APPS collapse + */ + sme_ScanFlushResult(hHal,0); + + //Save the frame to scan result + if (pPrefNetworkFoundInd->mesgLen > sizeof(tSirPrefNetworkFoundInd)) + { + //we may have a frame + status = csrScanSavePreferredNetworkFound(pMac, + pPrefNetworkFoundInd); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to save preferred network")); + } + } + else + { + smsLog(pMac, LOGE, FL(" not enough data length %d needed %zu"), + pPrefNetworkFoundInd->mesgLen, sizeof(tSirPrefNetworkFoundInd)); + } + + /* Call Preferred Netowrk Found Indication callback routine. */ + if (HAL_STATUS_SUCCESS(status) && (pMac->pmc.prefNetwFoundCB != NULL)) + { + pMac->pmc.prefNetwFoundCB( + pMac->pmc.preferredNetworkFoundIndCallbackContext, + pPrefNetworkFoundInd); + } + } + else + { + smsLog(pMac, LOGE, "%s: callback failed - SSID is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + + return(status); +} + +#endif // FEATURE_WLAN_SCAN_PNO + + +eHalStatus sme_GetCfgValidChannels(tHalHandle hHal, tANI_U8 *aValidChannels, tANI_U32 *len) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetCfgValidChannels(pMac, aValidChannels, len); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPerTracking + + \brief Set Tx PER tracking configuration parameters + + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingConf - Tx PER configuration parameters + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking(tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam) +{ + vos_msg_t msg; + tpSirTxPerTrackingParam pTxPerTrackingParamReq = NULL; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + pMac->sme.pTxPerHitCallback = pCallbackfn; + pMac->sme.pTxPerHitCbContext = pCallbackContext; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + // free this memory in failure case or WDA request callback function + pTxPerTrackingParamReq = vos_mem_malloc(sizeof(tSirTxPerTrackingParam)); + if (NULL == pTxPerTrackingParamReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for tSirTxPerTrackingParam", __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pTxPerTrackingParamReq, (void*)pTxPerTrackingParam, + sizeof(tSirTxPerTrackingParam)); + msg.type = WDA_SET_TX_PER_TRACKING_REQ; + msg.reserved = 0; + msg.bodyptr = pTxPerTrackingParamReq; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_TX_PER_TRACKING_REQ message to WDA", __func__); + vos_mem_free(pTxPerTrackingParamReq); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCode + + \brief Change Country code, Reg Domain and channel list + + \details Country Code Priority + 0 = 11D > Configured Country > NV + 1 = Configured Country > 11D > NV + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from Supplicant is set as current courtry code. + User can send reset command XX (instead of country code) to reset the + country code to default values which is read from NV. + In case of reset, 11D is enabled and default NV code is Set as current country code + If 11D is priority, + Than Supplicant country code code is set to default code. But 11D code is set as current country code + + \param pMac - The handle returned by macOpen. + \param pMsgBuf - MSG Buffer + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniChangeCountryCodeReq *pMsg; + v_REGDOMAIN_t domainIdIoctl; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + static uNvTables nvTables; + pMsg = (tAniChangeCountryCodeReq *)pMsgBuf; + + + /* if the reset Supplicant country code command is triggered, enable 11D, reset the NV country code and return */ + if( VOS_TRUE == vos_mem_compare(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2) ) + { + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + + vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + + /* read the country code from NV and use it */ + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pMsg->countryCode, + nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + else + { + status = eHAL_STATUS_FAILURE; + return status; + } + } + else + { + /* if Supplicant country code has priority, disable 11d */ + if(pMac->roam.configParam.fSupplicantCountryCodeHasPriority && + pMsg->countryFromUserSpace) + { + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + } + } + + /* WEXT set country code means + * 11D should be supported? + * 11D Channel should be enforced? + * 11D Country code should be matched? + * 11D Reg Domian should be matched? + * Country string changed */ + if(pMac->roam.configParam.Is11dSupportEnabled && + pMac->roam.configParam.fEnforce11dChannels && + pMac->roam.configParam.fEnforceCountryCodeMatch && + pMac->roam.configParam.fEnforceDefaultDomain && + !csrSave11dCountryString(pMac, pMsg->countryCode, eANI_BOOLEAN_TRUE)) + { + /* All 11D related options are already enabled + * Country string is not changed + * Do not need do anything for country code change request */ + return eHAL_STATUS_SUCCESS; + } + + /* Set Current Country code and Current Regulatory domain */ + status = csrSetCountryCode(pMac, pMsg->countryCode, NULL); + if(eHAL_STATUS_SUCCESS != status) + { + /* Supplicant country code failed. So give 11D priority */ + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + smsLog(pMac, LOGE, "Set Country Code Fail %d", status); + return status; + } + + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + + /* Get Domain ID from country code */ + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCodeCurrent, + (v_REGDOMAIN_t *) &domainIdIoctl, + COUNTRY_QUERY); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get regId %d"), domainIdIoctl ); + return status; + } + else if (REGDOMAIN_WORLD == domainIdIoctl) + { + /* Supplicant country code is invalid, so we are on world mode now. So + give 11D chance to update */ + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + smsLog(pMac, LOG1, FL("Country Code unrecognized by driver")); + } + + + status = WDA_SetRegDomain(pMac, domainIdIoctl, pMsg->sendRegHint); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), domainIdIoctl ); + return status; + } + else + { + //if 11d has priority, clear currentCountryBssid & countryCode11d to get + //set again if we find AP with 11d info during scan + if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) + { + smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d")); + vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid)); + vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) ); + } + } + + if( pMsg->changeCCCallback ) + { + ((tSmeChangeCountryCallback)(pMsg->changeCCCallback))((void *)pMsg->pDevContext); + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCodeByUser + + \brief Change Country code, Reg Domain and channel list + + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from Supplicant is set as current country code. + + \param pMac - The handle returned by macOpen. + \param pMsg - Carrying new CC & domain set in kernel by user + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCodeByUser(tpAniSirGlobal pMac, + tAniGenericChangeCountryCodeReq *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + v_REGDOMAIN_t reg_domain_id; + v_BOOL_t is11dCountry = VOS_FALSE; + + smsLog(pMac, LOG1, FL(" called")); + reg_domain_id = (v_REGDOMAIN_t)pMsg->domain_index; + + if (memcmp(pMsg->countryCode, pMac->scan.countryCode11d, + VOS_COUNTRY_CODE_LEN) == 0) + { + is11dCountry = VOS_TRUE; + } + + /* Set the country code given by userspace when 11dOriginal is FALSE + * when 11doriginal is True,is11dCountry =0 and + * fSupplicantCountryCodeHasPriority = 0, then revert the country code, + * and return failure + */ + if(pMac->roam.configParam.Is11dSupportEnabledOriginal == true) + { + if ((!is11dCountry) && (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + + smsLog( pMac, LOGW, FL(" incorrect country being set, nullify this request")); + + /* we have got a request for a country that should not have been added since the + * STA is associated; nullify this request. + * If both countryCode11d[0] and countryCode11d[1] are zero, revert it to World + * domain to avoid from causing cfg80211 call trace. + */ + if ((pMac->scan.countryCode11d[0] == 0) && (pMac->scan.countryCode11d[1] == 0)) + status = csrGetRegulatoryDomainForCountry(pMac, + "00", + (v_REGDOMAIN_t *) ®_domain_id, + COUNTRY_IE); + else + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCode11d, + (v_REGDOMAIN_t *) ®_domain_id, + COUNTRY_IE); + + return eHAL_STATUS_FAILURE; + } + } + /* if Supplicant country code has priority, disable 11d */ + if (!is11dCountry && pMac->roam.configParam.fSupplicantCountryCodeHasPriority) + { + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + } + + vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + + status = WDA_SetRegDomain(pMac, reg_domain_id, eSIR_TRUE); + + if (VOS_FALSE == is11dCountry ) + { + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + /* set to default domain ID */ + pMac->scan.domainIdDefault = pMac->scan.domainIdCurrent; + } + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), reg_domain_id ); + return status; + } + else + { + //if 11d has priority, clear currentCountryBssid & countryCode11d to get + //set again if we find AP with 11d info during scan + if((!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) && + (VOS_FALSE == is11dCountry )) + { + smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d")); + vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid)); + vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) ); + } + } + + /* get the channels based on new cc */ + status = csrInitGetChannels(pMac); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + return status; + } + + /* reset info based on new cc, and we are done */ + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if (VOS_TRUE == is11dCountry) + { + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE; + } + /* Country code Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + // Do active scans after the country is set by User hints or Country IE + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + + sme_DisconnectConnectedSessions(pMac); + + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCodeByCore + + \brief Update Country code in the driver if set by kernel as world + + If 11D is enabled, we update the country code after every scan & notify kernel. + This is to make sure kernel & driver are in sync in case of CC found in + driver but not in kernel database + + \param pMac - The handle returned by macOpen. + \param pMsg - Carrying new CC set in kernel + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCodeByCore(tpAniSirGlobal pMac, tAniGenericChangeCountryCodeReq *pMsg) +{ + eHalStatus status; + + smsLog(pMac, LOG1, FL(" called")); + + //this is to make sure kernel & driver are in sync in case of CC found in + //driver but not in kernel database + if (('0' == pMsg->countryCode[0]) && ('0' == pMsg->countryCode[1])) + { + smsLog( pMac, LOGW, FL("Setting countryCode11d & countryCodeCurrent to world CC")); + vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + + status = WDA_SetRegDomain(pMac, REGDOMAIN_WORLD, eSIR_TRUE); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId") ); + return status; + } + else + { + status = csrInitGetChannels(pMac); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + } + else + { + csrInitChannelList(pMac); + } + } + /* Country code Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_DisconnectConnectedSessions + + \brief Disconnect STA and P2P client session if channel is not supported + + If new country code does not support the channel on which STA/P2P client + is connetced, it sends the disconnect to the AP/P2P GO + + \param pMac - The handle returned by macOpen + + \return void + + -------------------------------------------------------------------------------*/ + +void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac) +{ + v_U8_t i,sessionId, isChanFound = false; + tANI_U8 currChannel; + + for (sessionId=0; sessionId< CSR_ROAM_SESSION_MAX; sessionId++) + { + if (csrIsSessionClientAndConnected(pMac, sessionId)) + { + isChanFound = false; + //Session is connected.Check the channel + currChannel = csrGetInfraOperationChannel(pMac, sessionId); + smsLog(pMac, LOGW, "Current Operating channel : %d, session :%d", + currChannel, sessionId); + for (i=0; i < pMac->scan.base20MHzChannels.numChannels; i++) + { + if (pMac->scan.base20MHzChannels.channelList[i] == currChannel) + { + isChanFound = true; + break; + } + } + + if (!isChanFound) + { + for (i=0; i < pMac->scan.base40MHzChannels.numChannels; i++) + { + if(pMac->scan.base40MHzChannels.channelList[i] == currChannel) + { + isChanFound = true; + break; + } + } + } + + if (!isChanFound) + { + smsLog(pMac, LOGW, "%s : Disconnect Session :%d", __func__, sessionId); + csrRoamDisconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } + } +} + + +/* --------------------------------------------------------------------------- + + \fn sme_HandleGenericChangeCountryCode + + \brief Change Country code, Reg Domain and channel list + + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from kernel is set as current country code. + + \param pMac - The handle returned by macOpen. + \param pMsgBuf - message buffer + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tAniGenericChangeCountryCodeReq *pMsg; + v_REGDOMAIN_t reg_domain_id; + + smsLog(pMac, LOG1, FL(" called")); + pMsg = (tAniGenericChangeCountryCodeReq *)pMsgBuf; + reg_domain_id = (v_REGDOMAIN_t)pMsg->domain_index; + + if (REGDOMAIN_COUNT == reg_domain_id) + { + sme_HandleChangeCountryCodeByCore(pMac, pMsg); + } + else + { + sme_HandleChangeCountryCodeByUser(pMac, pMsg); + } + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +eHalStatus sme_8023MulticastList (tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFltMcAddrList pMulticastAddrs) +{ + tpSirRcvFltMcAddrList pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = NULL; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: " + "ulMulticastAddrCnt=%d, multicastAddr[0]=%p", __func__, + pMulticastAddrs->ulMulticastAddrCnt, + pMulticastAddrs->multicastAddr[0]); + + /* + *Find the connected Infra / P2P_client connected session + */ + if (CSR_IS_SESSION_VALID(pMac, sessionId) && + csrIsConnStateInfra(pMac, sessionId)) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + } + + if(pSession == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Unable to find " + "the session Id: %d", __func__, sessionId); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "allocate memory for 8023 Multicast List request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + if( !csrIsConnStateConnectedInfra (pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Ignoring the " + "indication as we are not connected", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRequestBuf, pMulticastAddrs, sizeof(tSirRcvFltMcAddrList)); + + vos_mem_copy(pRequestBuf->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + msg.type = WDA_8023_MULTICAST_LIST_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "post WDA_8023_MULTICAST_LIST message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_ReceiveFilterSetFilter(tHalHandle hHal, tpSirRcvPktFilterCfgType pRcvPktFilterCfg, + tANI_U8 sessionId) +{ + tpSirRcvPktFilterCfgType pRequestBuf; + v_SINT_t allocSize; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + v_U8_t idx=0; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterType=%d, " + "filterId = %d", __func__, + pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId); + + allocSize = sizeof(tSirRcvPktFilterCfgType); + + pRequestBuf = vos_mem_malloc(allocSize); + + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "allocate memory for Receive Filter Set Filter request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + if( NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Session Not found ", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRcvPktFilterCfg->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRcvPktFilterCfg->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf, pRcvPktFilterCfg, allocSize); + + msg.type = WDA_RECEIVE_FILTER_SET_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : " + "FT %d FID %d ", + pRequestBuf->filterType, pRequestBuf->filterId); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : " + "params %d CT %d", + pRequestBuf->numFieldParams, pRequestBuf->coalesceTime); + + for (idx=0; idxnumFieldParams; idx++) + { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Proto %d Comp Flag %d ", + pRequestBuf->paramsData[idx].protocolLayer, + pRequestBuf->paramsData[idx].cmpFlag); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Data Offset %d Data Len %d", + pRequestBuf->paramsData[idx].dataOffset, + pRequestBuf->paramsData[idx].dataLength); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "CData: %d:%d:%d:%d:%d:%d", + pRequestBuf->paramsData[idx].compareData[0], + pRequestBuf->paramsData[idx].compareData[1], + pRequestBuf->paramsData[idx].compareData[2], + pRequestBuf->paramsData[idx].compareData[3], + pRequestBuf->paramsData[idx].compareData[4], + pRequestBuf->paramsData[idx].compareData[5]); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "MData: %d:%d:%d:%d:%d:%d", + pRequestBuf->paramsData[idx].dataMask[0], + pRequestBuf->paramsData[idx].dataMask[1], + pRequestBuf->paramsData[idx].dataMask[2], + pRequestBuf->paramsData[idx].dataMask[3], + pRequestBuf->paramsData[idx].dataMask[4], + pRequestBuf->paramsData[idx].dataMask[5]); + + } + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "WDA_RECEIVE_FILTER_SET_FILTER message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_GetFilterMatchCount(tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "+%s", __func__); + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme))) + { + pmcGetFilterMatchCount(hHal, callbackRoutine, callbackContext, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__); + + return (status); +} + +eHalStatus sme_ReceiveFilterClearFilter(tHalHandle hHal, tpSirRcvFltPktClearParam pRcvFltPktClearParam, + tANI_U8 sessionId) +{ + tpSirRcvFltPktClearParam pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterId = %d", __func__, + pRcvFltPktClearParam->filterId); + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktClearParam)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for Receive Filter " + "Clear Filter request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + if( NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session Not find ", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRcvFltPktClearParam->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRcvFltPktClearParam->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pRcvFltPktClearParam, sizeof(tSirRcvFltPktClearParam)); + + msg.type = WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "WDA_RECEIVE_FILTER_CLEAR_FILTER message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +/* --------------------------------------------------------------------------- + \fn sme_PreChannelSwitchIndFullPowerCB + \brief call back function for the PMC full power request because of pre + channel switch. + \param callbackContext + \param status + ---------------------------------------------------------------------------*/ +void sme_PreChannelSwitchIndFullPowerCB(void *callbackContext, + eHalStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return; +} + +/* --------------------------------------------------------------------------- + \fn sme_PreChannelSwitchIndOffloadFullPowerCB + \brief call back function for the PMC full power request because of pre + channel switch for offload case. + \param callbackContext + \param sessionId + \param status + ---------------------------------------------------------------------------*/ +void sme_PreChannelSwitchIndOffloadFullPowerCB(void *callbackContext,tANI_U32 sessionId, + eHalStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return; +} + +/* --------------------------------------------------------------------------- + \fn sme_HandlePreChannelSwitchInd + \brief Processes the indcation from PE for pre-channel switch. + \param hHal + \param void *pMsgBuf to carry session id + \- The handle returned by macOpen. return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpSirSmePreSwitchChannelInd pPreSwitchChInd = (tpSirSmePreSwitchChannelInd)pMsgBuf; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + if(!pMac->psOffloadEnabled) + { + status = pmcRequestFullPower(hHal, sme_PreChannelSwitchIndFullPowerCB, + pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH); + } + else + { + if (NULL != pPreSwitchChInd) + { + status = pmcOffloadRequestFullPower(hHal, pPreSwitchChInd->sessionId, + sme_PreChannelSwitchIndOffloadFullPowerCB, + pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH); + } + else + { + smsLog(pMac, LOGE, "Empty pMsgBuf message for channel switch " + "(eWNI_SME_PRE_SWITCH_CHL_IND), nothing to process"); + } + } + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_HandlePostChannelSwitchInd + \brief Processes the indcation from PE for post-channel switch. + \param hHal + \- The handle returned by macOpen. return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestBmps(hHal, NULL, NULL); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_IsChannelValid + + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_BOOLEAN valid = FALSE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + valid = csrRoamIsChannelValid( pMac, channel); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (valid); +} + +/* --------------------------------------------------------------------------- + \fn sme_SetFreqBand + \brief Used to set frequency band. + \param hHal + \param sessionId - Session Identifier + \eBand band value to be configured + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetFreqBand(tHalHandle hHal, tANI_U8 sessionId, eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrSetBand(hHal, sessionId, eBand); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetFreqBand + \brief Used to get the current band settings. + \param hHal + \pBand pointer to hold band value + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetFreqBand(tHalHandle hHal, eCsrBand *pBand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + *pBand = csrGetCurrentBand( hHal ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +#ifdef WLAN_WAKEUP_EVENTS +/****************************************************************************** + \fn sme_WakeReasonIndCallback + + \brief + a callback function called when SME received eWNI_SME_WAKE_REASON_IND event from WDA + + \param hHal - HAL handle for device + \param pMsg - Message body passed from WDA; includes Wake Reason Indication parameter + + \return eHalStatus +******************************************************************************/ +eHalStatus sme_WakeReasonIndCallback (tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirWakeReasonInd *pWakeReasonInd = (tSirWakeReasonInd *)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + smsLog(pMac, LOG2, "SME: entering sme_WakeReasonIndCallback"); + + /* Call Wake Reason Indication callback routine. */ + if (pMac->pmc.wakeReasonIndCB != NULL) + pMac->pmc.wakeReasonIndCB(pMac->pmc.wakeReasonIndCBContext, pWakeReasonInd); + + pMac->pmc.wakeReasonIndCB = NULL; + pMac->pmc.wakeReasonIndCBContext = NULL; + + smsLog(pMac, LOG1, "Wake Reason Indication in %s(), reason=%d", __func__, pWakeReasonInd->ulReason); + } + + return(status); +} +#endif // WLAN_WAKEUP_EVENTS + + +/* --------------------------------------------------------------------------- + \fn sme_SetMaxTxPowerPerBand + + \brief Set the Maximum Transmit Power specific to band dynamically. + Note: this setting will not persist over reboots. + + \param band + \param power to set in dB + \- return eHalStatus + + ----------------------------------------------------------------------------*/ +eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB) +{ + vos_msg_t msg; + tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL; + + pMaxTxPowerPerBandParams = vos_mem_malloc(sizeof(tMaxTxPowerPerBandParams)); + if (NULL == pMaxTxPowerPerBandParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Not able to allocate memory for pMaxTxPowerPerBandParams", + __func__); + return eHAL_STATUS_FAILURE; + } + + pMaxTxPowerPerBandParams->power = dB; + pMaxTxPowerPerBandParams->bandInfo = band; + + msg.type = WDA_SET_MAX_TX_POWER_PER_BAND_REQ; + msg.reserved = 0; + msg.bodyptr = pMaxTxPowerPerBandParams; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Not able to post WDA_SET_MAX_TX_POWER_PER_BAND_REQ", + __func__); + vos_mem_free(pMaxTxPowerPerBandParams); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetMaxTxPower + + \brief Set the Maximum Transmit Power dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param pBssid BSSID to set the power cap for + \param pBssid pSelfMacAddress self MAC Address + \param pBssid power to set in dB + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr pBssid, + tSirMacAddr pSelfMacAddress, v_S7_t dB) +{ + vos_msg_t msg; + tpMaxTxPowerParams pMaxTxParams = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0)); + pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if (NULL == pMaxTxParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for pMaxTxParams", __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pMaxTxParams->bssId, pBssid, SIR_MAC_ADDR_LENGTH); + vos_mem_copy(pMaxTxParams->selfStaMacAddr, pSelfMacAddress, + SIR_MAC_ADDR_LENGTH); + pMaxTxParams->power = dB; + + msg.type = WDA_SET_MAX_TX_POWER_REQ; + msg.reserved = 0; + msg.bodyptr = pMaxTxParams; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_MAX_TX_POWER_REQ message to WDA", __func__); + vos_mem_free(pMaxTxParams); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetCustomMacAddr + + \brief Set the customer Mac Address. + + \param customMacAddr customer MAC Address + \- return eHalStatus + + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetCustomMacAddr(tSirMacAddr customMacAddr) +{ + vos_msg_t msg; + tSirMacAddr *pBaseMacAddr; + + pBaseMacAddr = vos_mem_malloc(sizeof(tSirMacAddr)); + if (NULL == pBaseMacAddr) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to allocate memory for pBaseMacAddr")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr)); + + msg.type = SIR_HAL_SET_BASE_MACADDR_IND; + msg.reserved = 0; + msg.bodyptr = pBaseMacAddr; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WDA")); + vos_mem_free(pBaseMacAddr); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------- + \fn sme_SetTxPower + \brief Set Transmit Power dynamically. + \param hHal + \param sessionId Target Session ID + \pBSSId BSSID + \dev_mode dev_mode such as station, P2PGO, SAP + \param dBm power to set + \- return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId, + tSirMacAddr pBSSId, + tVOS_CON_MODE dev_mode, int dBm) +{ + vos_msg_t msg; + tpMaxTxPowerParams pTxParams = NULL; + v_S7_t power = (v_S7_t)dBm; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0)); + + /* make sure there is no overflow */ + if ((int)power != dBm) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: error, invalid power = %d", __func__, dBm); + return eHAL_STATUS_FAILURE; + } + + pTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if (NULL == pTxParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for pTxParams", __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pTxParams->bssId, pBSSId, SIR_MAC_ADDR_LENGTH); + pTxParams->power = power; /* unit is dBm */ + pTxParams->dev_mode = dev_mode; + msg.type = WDA_SET_TX_POWER_REQ; + msg.reserved = 0; + msg.bodyptr = pTxParams; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post WDA_SET_TX_POWER_REQ to WDA", + __func__); + vos_mem_free(pTxParams); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HideSSID + + \brief hide/show SSID dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId + \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HideSSID(tHalHandle hHal, v_U8_t sessionId, v_U8_t ssidHidden) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U16 len; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tpSirUpdateParams pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !pSession->sessionActive ) + VOS_ASSERT(0); + + /* Create the message and send to lim */ + len = sizeof(tSirUpdateParams); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, sizeof(tSirUpdateParams), 0); + pMsg->messageType = eWNI_SME_HIDE_SSID_REQ; + pMsg->length = len; + /* Data starts from here */ + pMsg->sessionId = sessionId; + pMsg->ssidHidden = ssidHidden; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetTmLevel + \brief Set Thermal Mitigation Level to RIVA + \param hHal - The handle returned by macOpen. + \param newTMLevel - new Thermal Mitigation Level + \param tmMode - Thermal Mitigation handle mode, default 0 + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tAniSetTmLevelReq *setTmLevelReq = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + setTmLevelReq = (tAniSetTmLevelReq *)vos_mem_malloc(sizeof(tAniSetTmLevelReq)); + if (NULL == setTmLevelReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for sme_SetTmLevel", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + setTmLevelReq->tmMode = tmMode; + setTmLevelReq->newTmLevel = newTMLevel; + + /* serialize the req through MC thread */ + vosMessage.bodyptr = setTmLevelReq; + vosMessage.type = WDA_SET_TM_LEVEL_REQ; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(setTmLevelReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/*--------------------------------------------------------------------------- + + \brief sme_featureCapsExchange() - SME interface to exchange capabilities between + Host and FW. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_featureCapsExchange( tHalHandle hHal) +{ + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION, 0)); + WDA_featureCapsExchange(vosContext); +} + +/*--------------------------------------------------------------------------- + + \brief sme_disableFeatureCapablity() - SME interface to disable Active mode offload capablity + in Host. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_disableFeatureCapablity(tANI_U8 feature_index) +{ + WDA_disableCapablityFeature(feature_index); +} + + + +/* --------------------------------------------------------------------------- + + \fn sme_GetDefaultCountryCode + + \brief Get the default country code from NV + + \param hHal + \param pCountry + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetDefaultCountryCodeFrmNv(tHalHandle hHal, tANI_U8 *pCountry) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_DEFCCNV, NO_SESSION, 0)); + return csrGetDefaultCountryCodeFrmNv(pMac, pCountry); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetCurrentCountryCode + + \brief Get the current country code + + \param hHal + \param pCountry + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentCountryCode(tHalHandle hHal, tANI_U8 *pCountry) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CURCC, NO_SESSION, 0)); + return csrGetCurrentCountryCode(pMac, pCountry); +} + +/* --------------------------------------------------------------------------- + \fn sme_transportDebug + \brief Dynamically monitoring Transport channels + Private IOCTL will querry transport channel status if driver loaded + \param hHal Upper MAC context + \param displaySnapshot Display transport channel snapshot option + \param toggleStallDetect Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + \- return NONE + -------------------------------------------------------------------------*/ +void sme_transportDebug(tHalHandle hHal, v_BOOL_t displaySnapshot, v_BOOL_t toggleStallDetect) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return; + } + WDA_TransportChannelDebug(pMac, displaySnapshot, toggleStallDetect); +} + +/* --------------------------------------------------------------------------- + \fn sme_ResetPowerValuesFor5G + \brief Reset the power values for 5G band with NV power values. + \param hHal - HAL handle for device + \- return NONE + -------------------------------------------------------------------------*/ +void sme_ResetPowerValuesFor5G (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT (hHal); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0)); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + csrApplyPower2Current(pMac); // Store the channel+power info in the global place: Cfg +} + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamPrefer5GHz + \brief enable/disable Roam prefer 5G runtime option + This function is called through dynamic setConfig callback function + to configure the Roam prefer 5G runtime option + \param hHal - HAL handle for device + \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamPrefer5GHz(tHalHandle hHal, v_BOOL_t nRoamPrefer5GHz) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamPrefer5GHz is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamPrefer5GHz, + nRoamPrefer5GHz); + pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setRoamIntraBand + \brief enable/disable Intra band roaming + This function is called through dynamic setConfig callback function + to configure the intra band roaming + \param hHal - HAL handle for device + \param nRoamIntraBand Enable/Disable Intra band roaming + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setRoamIntraBand(tHalHandle hHal, const v_BOOL_t nRoamIntraBand) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamIntraBand is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamIntraBand, + nRoamIntraBand); + pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanNProbes + \brief function to update roam scan N probes + This function is called through dynamic setConfig callback function + to update roam scan N probes + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nProbes number of probe requests to be sent out + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, tANI_U8 sessionId, + const v_U8_t nProbes) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamScanNProbes is changed from %d to %d", __func__, + pMac->roam.configParam.nProbes, + nProbes); + pMac->roam.configParam.nProbes = nProbes; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_NPROBES_CHANGED); + } +#endif + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanHomeAwayTime + \brief function to update roam scan Home away time + This function is called through dynamic setConfig callback function + to update roam scan home away time + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nRoamScanAwayTime Scan home away time + \param bSendOffloadCmd If TRUE then send offload command to firmware + If FALSE then command is not sent to firmware + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanHomeAwayTime(tHalHandle hHal, + tANI_U8 sessionId, + const v_U16_t nRoamScanHomeAwayTime, + const eAniBoolean bSendOffloadCmd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamScanHomeAwayTime is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamScanHomeAwayTime, + nRoamScanHomeAwayTime); + pMac->roam.configParam.nRoamScanHomeAwayTime = nRoamScanHomeAwayTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_HOME_AWAY_TIME_CHANGED); + } +#endif + return status; +} + + +/* --------------------------------------------------------------------------- + \fn sme_getRoamIntraBand + \brief get Intra band roaming + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_BOOL_t sme_getRoamIntraBand(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0)); + return pMac->roam.configParam.nRoamIntraBand; +} + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanNProbes + \brief get N Probes + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U8_t sme_getRoamScanNProbes(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nProbes; +} + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanHomeAwayTime + \brief get Roam scan home away time + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U16_t sme_getRoamScanHomeAwayTime(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nRoamScanHomeAwayTime; +} + + +/* --------------------------------------------------------------------------- + \fn sme_UpdateImmediateRoamRssiDiff + \brief Update nImmediateRoamRssiDiff + This function is called through dynamic setConfig callback function + to configure nImmediateRoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param nImmediateRoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \param sessionId - Session Identifier + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal, + v_U8_t nImmediateRoamRssiDiff, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF, NO_SESSION, 0)); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set immediate roam rssi diff to %d - old value is %d - roam state is %s", + nImmediateRoamRssiDiff, + pMac->roam.configParam.nImmediateRoamRssiDiff, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.nImmediateRoamRssiDiff = nImmediateRoamRssiDiff; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamRssiDiff + \brief Update RoamRssiDiff + This function is called through dynamic setConfig callback function + to configure RoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param RoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, tANI_U8 sessionId, + v_U8_t RoamRssiDiff) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s", + RoamRssiDiff, + pMac->roam.configParam.RoamRssiDiff, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_RSSI_DIFF_CHANGED); + } +#endif + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateFastTransitionEnabled() - enable/disable Fast Transition support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastTransitionEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastTransitionEnabled config successfully. + Other status means SME is failed to update isFastTransitionEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateFastTransitionEnabled(tHalHandle hHal, + v_BOOL_t isFastTransitionEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: FastTransitionEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isFastTransitionEnabled, + isFastTransitionEnabled); + pMac->roam.configParam.isFastTransitionEnabled = isFastTransitionEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateWESMode + \brief Update WES Mode + This function is called through dynamic setConfig callback function + to configure isWESModeEnabled + \param hHal - HAL handle for device + \param isWESModeEnabled - WES mode + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update isWESModeEnabled config successfully. + Other status means SME is failed to update isWESModeEnabled. + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateWESMode(tHalHandle hHal, v_BOOL_t isWESModeEnabled, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s", + isWESModeEnabled, + pMac->roam.configParam.isWESModeEnabled, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamScanControl + \brief Set roam scan control + This function is called to set roam scan control + if roam scan control is set to 0, roaming scan cache is cleared + any value other than 0 is treated as invalid value + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME failure to update + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamScanControl(tHalHandle hHal, tANI_U8 sessionId, + v_BOOL_t roamScanControl) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s", + roamScanControl, + pMac->roam.configParam.nRoamScanControl, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.nRoamScanControl = roamScanControl; + if ( 0 == roamScanControl) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully cleared roam scan cache"); + csrFlushCfgBgScanRoamChannelList(pMac, sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_FLUSH_CHANNEL_LIST); + } +#endif + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} +#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsFastRoamIniFeatureEnabled() - enable/disable LFR support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastRoamIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully. + Other status means SME is failed to update isFastRoamIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled +( + tHalHandle hHal, + tANI_U8 sessionId, + const v_BOOL_t isFastRoamIniFeatureEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (pMac->roam.configParam.isFastRoamIniFeatureEnabled == + isFastRoamIniFeatureEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__, + pMac->roam.configParam.isFastRoamIniFeatureEnabled, + isFastRoamIniFeatureEnabled); + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "%s: FastRoamEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isFastRoamIniFeatureEnabled, + isFastRoamIniFeatureEnabled); + pMac->roam.configParam.isFastRoamIniFeatureEnabled = + isFastRoamIniFeatureEnabled; + csrNeighborRoamUpdateFastRoamingEnabled(pMac, sessionId, + isFastRoamIniFeatureEnabled); + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsMAWCIniFeatureEnabled() - + Enable/disable LFR MAWC support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isMAWCIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update MAWCEnabled config successfully. + Other status means SME is failed to update MAWCEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsMAWCIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t MAWCEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: MAWCEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.MAWCEnabled, + MAWCEnabled); + pMac->roam.configParam.MAWCEnabled = MAWCEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_stopRoaming() - Stop roaming for a given sessionId + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS on success + Other status on failure + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_stopRoaming(tHalHandle hHal, + tANI_U8 sessionId, + tANI_U8 reason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, reason); + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_startRoaming() - Start roaming for a given sessionId + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS on success + Other status on failure + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_startRoaming(tHalHandle hHal, + tANI_U8 sessionId, + tANI_U8 reason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, reason); + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if Concurrent session exists + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS + Other status means SME is failed + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEnableFastRoamInConcurrency(tHalHandle hHal, + v_BOOL_t bFastRoamInConIniFeatureEnabled) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = bFastRoamInConIniFeatureEnabled; + if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) + { + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = 0; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} +#endif +#endif /* FEATURE_WLAN_LFR */ + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsEseFeatureEnabled() - enable/disable ESE support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isEseIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param isEseIniFeatureEnabled - flag to enable/disable + \return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully. + Other status means SME is failed to update isEseIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsEseFeatureEnabled +( + tHalHandle hHal, + tANI_U8 sessionId, + const v_BOOL_t isEseIniFeatureEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (pMac->roam.configParam.isEseIniFeatureEnabled == isEseIniFeatureEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__, + pMac->roam.configParam.isEseIniFeatureEnabled, + isEseIniFeatureEnabled); + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: EseEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isEseIniFeatureEnabled, + isEseIniFeatureEnabled); + pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled; + csrNeighborRoamUpdateEseModeEnabled(pMac, sessionId, + isEseIniFeatureEnabled); + + if (TRUE == isEseIniFeatureEnabled) + { + sme_UpdateFastTransitionEnabled(hHal, TRUE); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ESE_INI_CFG_CHANGED); + } +#endif + return eHAL_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_ESE */ + +/*-------------------------------------------------------------------------- + \brief sme_UpdateConfigFwRssiMonitoring() - enable/disable firmware RSSI Monitoring at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + fEnableFwRssiMonitoring. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring. config successfully. + Other status means SME is failed to update fEnableFwRssiMonitoring. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateConfigFwRssiMonitoring(tHalHandle hHal, + v_BOOL_t fEnableFwRssiMonitoring) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + if (ccmCfgSetInt(hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, fEnableFwRssiMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + halStatus = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failure: Could not pass on WNI_CFG_PS_RSSI_MONITOR configuration info to CCM"); + } + + return (halStatus); +} + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +/* --------------------------------------------------------------------------- + \fn sme_SetRoamOpportunisticScanThresholdDiff + \brief Update Opportunistic Scan threshold diff + This function is called through dynamic setConfig callback function + to configure nOpportunisticThresholdDiff + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nOpportunisticThresholdDiff - Opportunistic Scan threshold diff + \return eHAL_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config + successfully. + else SME is failed to update nOpportunisticThresholdDiff. + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamOpportunisticScanThresholdDiff(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nOpportunisticThresholdDiff) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetOpportunisticScanThresholdDiff(pMac, + sessionId, + nOpportunisticThresholdDiff); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set " + "opportunistic threshold diff to %d" + " - old value is %d - roam state is %d", + nOpportunisticThresholdDiff, + pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff = nOpportunisticThresholdDiff; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamOpportunisticScanThresholdDiff() + \brief gets Opportunistic Scan threshold diff + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nOpportunisticThresholdDiff + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamOpportunisticScanThresholdDiff(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamRescanRssiDiff + \brief Update roam rescan rssi diff + This function is called through dynamic setConfig callback function + to configure nRoamRescanRssiDiff + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nRoamRescanRssiDiff - roam rescan rssi diff + \return eHAL_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config + successfully. + else SME is failed to update nRoamRescanRssiDiff. + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamRescanRssiDiff(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamRescanRssiDiff) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetRoamRescanRssiDiff(pMac, sessionId, + nRoamRescanRssiDiff); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set " + "opportunistic threshold diff to %d" + " - old value is %d - roam state is %d", + nRoamRescanRssiDiff, + pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff = + nRoamRescanRssiDiff; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamRescanRssiDiff + \brief gets roam rescan rssi diff + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_S7_t - nRoamRescanRssiDiff + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamRescanRssiDiff(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBmissFirstBcnt + \brief Update Roam count for first beacon miss + This function is called through dynamic setConfig callback function + to configure nRoamBmissFirstBcnt + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nRoamBmissFirstBcnt - Roam first bmiss count + \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt + successfully. + else SME is failed to update nRoamBmissFirstBcnt + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamBmissFirstBcnt(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamBmissFirstBcnt) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetRoamBmissFirstBcnt(pMac, sessionId, + nRoamBmissFirstBcnt); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set " + "beacon miss first beacon count to %d" + " - old value is %d - roam state is %d", + nRoamBmissFirstBcnt, + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt = + nRoamBmissFirstBcnt; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetRoamBmissFirstBcnt + \brief get neighbor roam beacon miss first count + \param hHal - The handle returned by macOpen. + \return v_U8_t - neighbor roam beacon miss first count + -------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBmissFirstBcnt(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBmissFinalBcnt + \brief Update Roam count for final beacon miss + This function is called through dynamic setConfig callback function + to configure nRoamBmissFinalBcnt + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nRoamBmissFinalBcnt - Roam final bmiss count + \return eHAL_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt + successfully. + else SME is failed to update nRoamBmissFinalBcnt + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamBmissFinalBcnt(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamBmissFinalBcnt) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetRoamBmissFinalBcnt(pMac, sessionId, + nRoamBmissFinalBcnt); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set " + "beacon miss final beacon count to %d" + " - old value is %d - roam state is %d", + nRoamBmissFinalBcnt, + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt = + nRoamBmissFinalBcnt; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamBmissFinalBcnt + \brief gets Roam count for final beacon miss + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamBmissFinalBcnt + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBmissFinalBcnt(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamBeaconRssiWeight + \brief Update Roam beacon rssi weight + This function is called through dynamic setConfig callback function + to configure nRoamBeaconRssiWeight + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nRoamBeaconRssiWeight - Roam beacon rssi weight + \return eHAL_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config + successfully. + else SME is failed to update nRoamBeaconRssiWeight + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamBeaconRssiWeight(tHalHandle hHal, + tANI_U8 sessionId, + const v_U8_t nRoamBeaconRssiWeight) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetRoamBeaconRssiWeight(pMac, sessionId, + nRoamBeaconRssiWeight); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set " + "beacon miss final beacon count to %d" + " - old value is %d - roam state is %d", + nRoamBeaconRssiWeight, + pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight = + nRoamBeaconRssiWeight; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/*-------------------------------------------------------------------------- + \fn sme_GetRoamBeaconRssiWeight + \brief gets Roam beacon rssi weight + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - nRoamBeaconRssiWeight + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetRoamBeaconRssiWeight(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight; +} +/*-------------------------------------------------------------------------- + \brief sme_setNeighborLookupRssiThreshold() - update neighbor lookup rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborLookupRssiThreshold +( + tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t neighborLookupRssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrNeighborRoamSetLookupRssiThreshold(pMac, sessionId, + neighborLookupRssiThreshold); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set Lookup threshold to %d - old value is %d - roam state is %s", + neighborLookupRssiThreshold, + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold = + neighborLookupRssiThreshold; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_set_delay_before_vdev_stop(tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t delay_before_vdev_stop) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + status = sme_AcquireGlobalLock( &pMac->sme ); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, + VOS_TRACE_LEVEL_DEBUG, + FL("LFR param delay_before_vdev_stop changed from %d to %d"), + pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop, + delay_before_vdev_stop); + + pMac->roam.neighborRoamInfo[sessionId].cfgParams.delay_before_vdev_stop = + delay_before_vdev_stop; + pMac->roam.configParam.neighborRoamConfig.delay_before_vdev_stop = + delay_before_vdev_stop; + sme_ReleaseGlobalLock( &pMac->sme ); + } + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborReassocRssiThreshold +( + tHalHandle hHal, + tANI_U8 sessionId, + v_U8_t neighborReassocRssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (HAL_STATUS_SUCCESS(status)) + { + pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig; + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set Reassoc threshold to %d- old value is %d - roam state is %s", + neighborReassocRssiThreshold, + pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pNeighborRoamConfig->nNeighborReassocRssiThreshold = + neighborReassocRssiThreshold; + pNeighborRoamInfo->cfgParams.neighborReassocThreshold = + neighborReassocRssiThreshold; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborLookupRssiThreshold() - get neighbor lookup rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getNeighborLookupRssiThreshold(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold; +} + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborScanRefreshPeriod() - set neighbor scan results refresh period + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanRefreshPeriod +( + tHalHandle hHal, + tANI_U8 sessionId, + v_U16_t neighborScanResultsRefreshPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig; + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s", + neighborScanResultsRefreshPeriod, + pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pNeighborRoamConfig->nNeighborResultsRefreshPeriod = + neighborScanResultsRefreshPeriod; + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = + neighborScanResultsRefreshPeriod; + + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED); + } +#endif + return status ; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamScanOffloadEnabled() - enable/disable roam scan offload feaure + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + gRoamScanOffloadEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamScanOffloadEnabled(tHalHandle hHal, + v_BOOL_t nRoamScanOffloadEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("gRoamScanOffloadEnabled is changed from %d to %d"), + pMac->roam.configParam.isRoamOffloadScanEnabled, + nRoamScanOffloadEnabled); + pMac->roam.configParam.isRoamOffloadScanEnabled = + nRoamScanOffloadEnabled; + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status ; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborScanRefreshPeriod() - get neighbor scan results refresh period + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U16_t - Neighbor scan results refresh period value + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanRefreshPeriod(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod; +} + +/*-------------------------------------------------------------------------- + \brief sme_getEmptyScanRefreshPeriod() - get empty scan refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getEmptyScanRefreshPeriod(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal, tANI_U8 sessionId, + v_U16_t nEmptyScanRefreshPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig; + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s", + nEmptyScanRefreshPeriod, + pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pNeighborRoamConfig->nEmptyScanRefreshPeriod = nEmptyScanRefreshPeriod; + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = + nEmptyScanRefreshPeriod; + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_EMPTY_SCAN_REF_PERIOD_CHANGED); + } +#endif + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMinChanTime + \brief Update nNeighborScanMinChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMinTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMinTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel minimum dwell time + \param sessionId - Session Identifier + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal, + const v_U16_t nNeighborScanMinChanTime, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s", + nNeighborScanMinChanTime, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = + nNeighborScanMinChanTime; + pMac->roam.neighborRoamInfo[sessionId].cfgParams.minChannelScanTime = + nNeighborScanMinChanTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMaxChanTime + \brief Update nNeighborScanMaxChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMaxTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMaxTime=[0 .. 60] + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nNeighborScanMinChanTime - Channel maximum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId, + const v_U16_t nNeighborScanMaxChanTime) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig; + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s", + nNeighborScanMaxChanTime, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pNeighborRoamConfig->nNeighborScanMaxChanTime = + nNeighborScanMaxChanTime; + pNeighborRoamInfo->cfgParams.maxChannelScanTime = + nNeighborScanMaxChanTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_SCAN_CH_TIME_CHANGED); + } +#endif + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMinChanTime + \brief get neighbor scan min channel time + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U16_t - channel min time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo[sessionId].cfgParams.minChannelScanTime; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborRoamState + \brief get neighbor roam state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - neighbor roam state + -------------------------------------------------------------------------*/ +v_U32_t sme_getNeighborRoamState(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState; +} + +/* --------------------------------------------------------------------------- + \fn sme_getCurrentRoamState + \brief get current roam state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - current roam state + -------------------------------------------------------------------------*/ +v_U32_t sme_getCurrentRoamState(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->roam.curState[sessionId]; +} + +/* --------------------------------------------------------------------------- + \fn sme_getCurrentRoamSubState + \brief get neighbor roam sub state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - current roam sub state + -------------------------------------------------------------------------*/ +v_U32_t sme_getCurrentRoamSubState(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->roam.curSubState[sessionId]; +} + +/* --------------------------------------------------------------------------- + \fn sme_getLimSmeState + \brief get Lim Sme state + \param hHal - The handle returned by macOpen. + \return v_U32_t - Lim Sme state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimSmeState(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->lim.gLimSmeState; +} + +/* --------------------------------------------------------------------------- + \fn sme_getLimMlmState + \brief get Lim Mlm state + \param hHal - The handle returned by macOpen. + \return v_U32_t - Lim Mlm state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimMlmState(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->lim.gLimMlmState; +} + +/* --------------------------------------------------------------------------- + \fn sme_IsLimSessionValid + \brief is Lim session valid + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_BOOL_t - true or false + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsLimSessionValid(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->lim.gpSession[sessionId].valid; +} + +/* --------------------------------------------------------------------------- + \fn sme_getLimSmeSessionState + \brief get Lim Sme session state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - Lim Sme session state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimSmeSessionState(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->lim.gpSession[sessionId].limSmeState; +} + +/* --------------------------------------------------------------------------- + \fn sme_getLimMlmSessionState + \brief get Lim Mlm session state + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U32_t - Lim Mlm session state + -------------------------------------------------------------------------*/ +v_U32_t sme_getLimMlmSessionState(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->lim.gpSession[sessionId].limMlmState; +} + + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMaxChanTime + \brief get neighbor scan max channel time + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U16_t - channel max time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo[sessionId].cfgParams.maxChannelScanTime; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanPeriod + \brief Update nNeighborScanPeriod + This function is called through dynamic setConfig callback function + to configure nNeighborScanPeriod + Usage: adb shell iwpriv wlan0 setConfig nNeighborScanPeriod=[0 .. 1000] + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param nNeighborScanPeriod - neighbor scan period + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId, + const v_U16_t nNeighborScanPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pNeighborRoamConfig = &pMac->roam.configParam.neighborRoamConfig; + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set neighbor scan period to %d" + " - old value is %d - roam state is %s", + nNeighborScanPeriod, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pNeighborRoamConfig->nNeighborScanTimerPeriod = nNeighborScanPeriod; + pNeighborRoamInfo->cfgParams.neighborScanPeriod = nNeighborScanPeriod; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_SCAN_HOME_TIME_CHANGED); + } +#endif + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanPeriod + \brief get neighbor scan period + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return v_U16_t - neighbor scan period + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo[sessionId].cfgParams.neighborScanPeriod; +} + +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + +/*-------------------------------------------------------------------------- + \brief sme_getRoamRssiDiff() - get Roam rssi diff + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U16_t - Rssi diff value + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getRoamRssiDiff(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.RoamRssiDiff; +} + +/*-------------------------------------------------------------------------- + \brief sme_ChangeRoamScanChannelList() - Change roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param pChannelList - Output channel list + \param numChannels - Output number of channels + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + tANI_U8 oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 i = 0, j = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++) + { + if (j < sizeof(oldChannelList)) + { + j += snprintf(oldChannelList + j, sizeof(oldChannelList) - j," %d", + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]); + } + else + { + break; + } + } + } + csrFlushCfgBgScanRoamChannelList(pMac, sessionId); + csrCreateBgScanRoamChannelList(pMac, sessionId, pChannelList, + numChannels); + sme_SetRoamScanControl(hHal, sessionId, 1); + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + j = 0; + for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++) + { + if (j < sizeof(newChannelList)) + { + j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d", + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]); + } + else + { + break; + } + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d", + newChannelList, oldChannelList, + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_CHANNEL_LIST_CHANGED); + } +#endif + + return status ; +} + +#ifdef FEATURE_WLAN_ESE_UPLOAD +/*-------------------------------------------------------------------------- + \brief sme_SetEseRoamScanChannelList() - set ese roam scan channel list + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param pChannelList - Input channel list + \param numChannels - Input number of channels + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal, + tANI_U8 sessionId, + tANI_U8 *pChannelList, + tANI_U8 numChannels) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo + = &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrChannelInfo currChannelListInfo + = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + tANI_U8 oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 newChannelList[128] = {0}; + tANI_U8 i = 0, j = 0; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL != currChannelListInfo->ChannelList) + { + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + j += snprintf(oldChannelList + j, + sizeof(oldChannelList) - j, + " %d", + currChannelListInfo->ChannelList[i]); + } + } + status = csrCreateRoamScanChannelList(pMac, sessionId, pChannelList, + numChannels, csrGetCurrentBand(hHal)); + if ( HAL_STATUS_SUCCESS( status )) + { + if (NULL != currChannelListInfo->ChannelList) + { + j = 0; + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + j += snprintf(newChannelList + j, + sizeof(newChannelList) - j, + " %d", + currChannelListInfo->ChannelList[i]); + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, +"ESE roam scan channel list successfully set to \ +%s - old value is %s - roam state is %d", + newChannelList, oldChannelList, + pNeighborRoamInfo->neighborRoamState); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_CHANNEL_LIST_CHANGED); + } +#endif + return status ; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getRoamScanChannelList() - get roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param pChannelList - Output channel list + \param numChannels - Output number of channels + \param sessionId - Session Identifier + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_getRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels, tANI_U8 sessionId) +{ + int i = 0; + tANI_U8 *pOutPtr = pChannelList; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[sessionId]; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Roam Scan channel list is NOT yet initialized"); + *pNumChannels = 0; + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + + *pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; + for (i = 0; i < (*pNumChannels); i++) + { + pOutPtr[i] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]; + } + pOutPtr[i] = '\0'; + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_getIsEseFeatureEnabled() - get ESE feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the ESE feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsEseFeatureEnabled(tHalHandle hHal) +{ +#ifdef FEATURE_WLAN_ESE + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return csrRoamIsEseIniFeatureEnabled(pMac); +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +/*-------------------------------------------------------------------------- + \brief sme_GetWESMode() - get WES Mode + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - WES Mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetWESMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isWESModeEnabled; +} + +/*-------------------------------------------------------------------------- + \brief sme_GetRoamScanControl() - get scan control + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_BOOL_t - Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetRoamScanControl(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nRoamScanControl; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getIsLfrFeatureEnabled() - get LFR feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsLfrFeatureEnabled(tHalHandle hHal) +{ +#ifdef FEATURE_WLAN_LFR + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isFastRoamIniFeatureEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +/*-------------------------------------------------------------------------- + \brief sme_getIsFtFeatureEnabled() - get FT feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsFtFeatureEnabled(tHalHandle hHal) +{ +#ifdef WLAN_FEATURE_VOWIFI_11R + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isFastTransitionEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} + + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByFW + \brief Check if an feature is enabled by FW + + \param feattEnumValue - Enumeration value from placeHolderInCapBitmap + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ +tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue) +{ + return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue); +} +#ifdef FEATURE_WLAN_TDLS + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsLinkEstablishParams + \brief API to send TDLS Peer Link Establishment Parameters. + + \param peerMac - peer's Mac Adress. + \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsSendLinkEstablishParams(hHal, sessionId, peerMac, tdlsLinkEstablishParams) ; + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsMgmtFrame + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param frame_type - Type of TDLS mgmt frame to be sent. + \param dialog - dialog token used in the frame. + \param status - status to be incuded in the frame. + \param peerCapability - peer cpabilities + \param buf - additional IEs to be included + \param len - lenght of additional Ies + \param responder - Tdls request type + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tSirMacAddr peerMac, tANI_U8 frame_type, + tANI_U8 dialog, tANI_U16 statusCode, + tANI_U32 peerCapability, tANI_U8 *buf, + tANI_U8 len, tANI_U8 responder) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrTdlsSendMgmt sendTdlsReq = {{0}} ; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr)) ; + sendTdlsReq.frameType = frame_type; + sendTdlsReq.buf = buf; + sendTdlsReq.len = len; + sendTdlsReq.dialog = dialog; + sendTdlsReq.statusCode = statusCode; + sendTdlsReq.responder = responder; + sendTdlsReq.peerCapability = peerCapability; + + status = csrTdlsSendMgmtReq(hHal, sessionId, &sendTdlsReq) ; + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_ChangeTdlsPeerSta + \brief API to Update TDLS peer sta parameters. + + \param peerMac - peer's Mac Adress. + \param staParams - Peer Station Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac, + tCsrStaParams *pstaParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pstaParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s :pstaParams is NULL",__func__); + return eHAL_STATUS_FAILURE; + } + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsChangePeerSta(hHal, sessionId, peerMac,pstaParams); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} + +/* --------------------------------------------------------------------------- + \fn sme_AddTdlsPeerSta + \brief API to Add TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsAddPeerSta(hHal, sessionId, peerMac); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_DeleteTdlsPeerSta + \brief API to Delete TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsDelPeerSta(hHal, sessionId, peerMac) ; + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_SetTdlsPowerSaveProhibited + \API to set/reset the isTdlsPowerSaveProhibited. + + \- return void + -------------------------------------------------------------------------*/ +void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t val) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (!pMac->psOffloadEnabled) + { + pMac->isTdlsPowerSaveProhibited = val; + } + else + { + pmcOffloadSetTdlsProhibitBmpsStatus(hHal, sessionId, val); + } + return; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateFwTdlsState + + \brief + SME will send message to WMA to set TDLS state in f/w + + \param + + hHal - The handle returned by macOpen + + psmeTdlsParams - TDLS state info to update in f/w + + useSmeLock - Need to acquire SME Global Lock before state update or not + + \return eHalStatus +--------------------------------------------------------------------------- */ +eHalStatus sme_UpdateFwTdlsState(tHalHandle hHal, void *psmeTdlsParams, + tANI_BOOLEAN useSmeLock) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = NULL; + vos_msg_t vosMessage; + + /* only acquire sme global lock before state update if asked to */ + if (useSmeLock) { + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) + return eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS != status) + return status; + } + + /* serialize the req through MC thread */ + vosMessage.bodyptr = psmeTdlsParams; + vosMessage.type = WDA_UPDATE_FW_TDLS_STATE; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + /* release the lock if it was acquired */ + if (useSmeLock) + sme_ReleaseGlobalLock(&pMac->sme); + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateTdlsPeerState + + \brief + SME will send message to WMA to set TDLS Peer state in f/w + + \param + + hHal - The handle returned by macOpen + + peerStateParams - TDLS Peer state info to update in f/w + + \return eHalStatus +--------------------------------------------------------------------------- */ +eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, + tSmeTdlsPeerStateParams *peerStateParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tTdlsPeerStateParams *pTdlsPeerStateParams = NULL; + vos_msg_t vosMessage; + tANI_U8 num; + tANI_U8 chanId; + tANI_U8 i; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + pTdlsPeerStateParams = vos_mem_malloc(sizeof(*pTdlsPeerStateParams)); + if (NULL == pTdlsPeerStateParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to allocate mem for tdls peer state param", + __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams)); + vos_mem_copy(&pTdlsPeerStateParams->peerMacAddr, + &peerStateParams->peerMacAddr, + sizeof(tSirMacAddr)); + pTdlsPeerStateParams->vdevId = peerStateParams->vdevId; + pTdlsPeerStateParams->peerState = peerStateParams->peerState; + + switch (peerStateParams->peerState) + { + case eSME_TDLS_PEER_STATE_PEERING: + pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_PEERING; + break; + + case eSME_TDLS_PEER_STATE_CONNECTED: + pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_CONNECTED; + break; + + case eSME_TDLS_PEER_STATE_TEARDOWN: + pTdlsPeerStateParams->peerState = WDA_TDLS_PEER_STATE_TEARDOWN; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid peer state param (%d)", + __func__, peerStateParams->peerState); + vos_mem_free(pTdlsPeerStateParams); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + pTdlsPeerStateParams->peerCap.isPeerResponder = + peerStateParams->peerCap.isPeerResponder; + pTdlsPeerStateParams->peerCap.peerUapsdQueue = + peerStateParams->peerCap.peerUapsdQueue; + pTdlsPeerStateParams->peerCap.peerMaxSp = + peerStateParams->peerCap.peerMaxSp; + pTdlsPeerStateParams->peerCap.peerBuffStaSupport = + peerStateParams->peerCap.peerBuffStaSupport; + pTdlsPeerStateParams->peerCap.peerOffChanSupport = + peerStateParams->peerCap.peerOffChanSupport; + pTdlsPeerStateParams->peerCap.peerCurrOperClass = + peerStateParams->peerCap.peerCurrOperClass; + pTdlsPeerStateParams->peerCap.selfCurrOperClass = + peerStateParams->peerCap.selfCurrOperClass; + + num = 0; + for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) + { + chanId = peerStateParams->peerCap.peerChan[i]; + if (csrRoamIsChannelValid(pMac, chanId)) + { + pTdlsPeerStateParams->peerCap.peerChan[num].chanId = chanId; + pTdlsPeerStateParams->peerCap.peerChan[num].pwr = + csrGetCfgMaxTxPower(pMac, chanId); + + if (vos_nv_getChannelEnabledState(chanId) == NV_CHANNEL_DFS) + { + pTdlsPeerStateParams->peerCap.peerChan[num].dfsSet = + VOS_TRUE; + } + else + { + pTdlsPeerStateParams->peerCap.peerChan[num].dfsSet = + VOS_FALSE; + } + num++; + } + } + pTdlsPeerStateParams->peerCap.peerChanLen = num; + + pTdlsPeerStateParams->peerCap.peerOperClassLen = + peerStateParams->peerCap.peerOperClassLen; + for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++) + { + pTdlsPeerStateParams->peerCap.peerOperClass[i] = + peerStateParams->peerCap.peerOperClass[i]; + } + + pTdlsPeerStateParams->peerCap.prefOffChanNum = + peerStateParams->peerCap.prefOffChanNum; + pTdlsPeerStateParams->peerCap.prefOffChanBandwidth = + peerStateParams->peerCap.prefOffChanBandwidth; + + if (peerStateParams->peerCap.opClassForPrefOffChanIsSet) + { + pTdlsPeerStateParams->peerCap.opClassForPrefOffChan = + peerStateParams->peerCap.opClassForPrefOffChan; + } + else + { + /* redgm opclass table contains opclass for 40MHz low primary, + * 40MHz high primary and 20MHz. No support for 80MHz yet. So + * first we will check if bit for 40MHz is set and if so find + * matching opclass either with low primary or high primary + * (a channel would never be in both) and then search for opclass + * matching 20MHz, else for any BW. + */ + if (pTdlsPeerStateParams->peerCap.prefOffChanBandwidth & + (1 << BW_40_OFFSET_BIT)) + { + pTdlsPeerStateParams->peerCap.opClassForPrefOffChan = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsPeerStateParams->peerCap.prefOffChanNum, + BW40_LOW_PRIMARY); + if (!pTdlsPeerStateParams->peerCap.opClassForPrefOffChan) + { + pTdlsPeerStateParams->peerCap.opClassForPrefOffChan = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsPeerStateParams->peerCap.prefOffChanNum, + BW40_HIGH_PRIMARY); + } + } + else if (pTdlsPeerStateParams->peerCap.prefOffChanBandwidth & + (1 << BW_20_OFFSET_BIT)) + { + pTdlsPeerStateParams->peerCap.opClassForPrefOffChan = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsPeerStateParams->peerCap.prefOffChanNum, + BW20); + } + else + { + pTdlsPeerStateParams->peerCap.opClassForPrefOffChan = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsPeerStateParams->peerCap.prefOffChanNum, + BWALL); + } + } + vosMessage.type = WDA_UPDATE_TDLS_PEER_STATE; + vosMessage.reserved = 0; + vosMessage.bodyptr = pTdlsPeerStateParams; + + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + vos_mem_free(pTdlsPeerStateParams); + status = eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsChanSwitchReq + \brief API to send TDLS channel switch parameters to WMA. + + \param hHal - Umac handle. + \param chanSwitchParams- vdev, channel, offset, mode, peerMac + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +eHalStatus sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tSmeTdlsChanSwitchParams *chanSwitchParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tTdlsChanSwitchParams *pTdlsChanSwitchParams = NULL; + vos_msg_t vosMessage; + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + pTdlsChanSwitchParams = vos_mem_malloc(sizeof(*pTdlsChanSwitchParams)); + if (NULL == pTdlsChanSwitchParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate mem for tdls chan switch param")); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pTdlsChanSwitchParams, sizeof(*pTdlsChanSwitchParams)); + + switch (chanSwitchParams->tdls_off_ch_mode) + { + case ENABLE_CHANSWITCH: + pTdlsChanSwitchParams->tdlsSwMode = + WDA_TDLS_ENABLE_OFFCHANNEL; + break; + + case DISABLE_CHANSWITCH: + pTdlsChanSwitchParams->tdlsSwMode = + WDA_TDLS_DISABLE_OFFCHANNEL; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("invalid off channel command (%d)"), + chanSwitchParams->tdls_off_ch_mode); + vos_mem_free(pTdlsChanSwitchParams); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(&pTdlsChanSwitchParams->peerMacAddr, + &chanSwitchParams->peer_mac_addr, + sizeof(tSirMacAddr)); + pTdlsChanSwitchParams->vdevId = + chanSwitchParams->vdev_id; + pTdlsChanSwitchParams->tdlsOffCh = + chanSwitchParams->tdls_off_channel; + pTdlsChanSwitchParams->tdlsOffChBwOffset = + chanSwitchParams->tdls_off_ch_bw_offset; + pTdlsChanSwitchParams->is_responder= + chanSwitchParams->is_responder; + + switch (pTdlsChanSwitchParams->tdlsOffChBwOffset) + { + case (1 << BW_20_OFFSET_BIT): + pTdlsChanSwitchParams->operClass = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffCh, + BW20); + break; + case (1 << BW_40_OFFSET_BIT): + pTdlsChanSwitchParams->operClass = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffCh, + BW40_LOW_PRIMARY); + if (!pTdlsChanSwitchParams->operClass) + { + pTdlsChanSwitchParams->operClass = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffCh, + BW40_HIGH_PRIMARY); + } + break; + default: + pTdlsChanSwitchParams->operClass = + regdm_get_opclass_from_channel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffCh, + BWALL); + break; + }/* end switch */ + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Country Code=%s, Requested offset=%d, Selected Operating Class=%d"), + pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffChBwOffset, + pTdlsChanSwitchParams->operClass); + + vosMessage.type = WDA_TDLS_SET_OFFCHAN_MODE; + vosMessage.reserved = 0; + vosMessage.bodyptr = pTdlsChanSwitchParams; + + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Message Post failed status=%d"), vosStatus); + vos_mem_free(pTdlsChanSwitchParams); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} + +eHalStatus sme_GetLinkSpeed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq, void *plsContext, + void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, void *pContext) ) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if ( (NULL == pCallbackfn) && + (NULL == pMac->sme.pLinkSpeedIndCb)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Indication Call back did not registered", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + else if (NULL != pCallbackfn) + { + pMac->sme.pLinkSpeedCbContext = plsContext; + pMac->sme.pLinkSpeedIndCb = pCallbackfn; + } + /* serialize the req through MC thread */ + vosMessage.bodyptr = lsReq; + vosMessage.type = WDA_GET_LINK_SPEED; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Link Speed msg fail", __func__); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} +#endif /* FEATURE_WLAN_TDLS */ +/* --------------------------------------------------------------------------- + \fn sme_IsPmcBmps + \API to Check if PMC state is BMPS. + + \- return v_BOOL_t + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsPmcBmps(tHalHandle hHal) +{ + return (BMPS == pmcGetPmcState(hHal)); +} + + +eHalStatus sme_UpdateDfsSetting(tHalHandle hHal, tANI_U8 fUpdateEnableDFSChnlScan) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->scan.fEnableDFSChnlScan = fUpdateEnableDFSChnlScan; + sme_ReleaseGlobalLock( &pMac->sme ); + } + smsLog(pMac, LOG2, FL("exit status %d"), status); + + return (status); +} + +/* + * SME API to enable/disable WLAN driver initiated SSR + */ +void sme_UpdateEnableSSR(tHalHandle hHal, tANI_BOOLEAN enableSSR) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "SSR level is changed %d", enableSSR); + /* not serializing this messsage, as this is only going + * to set a variable in WDA/WDI + */ + WDA_SetEnableSSR(enableSSR); + sme_ReleaseGlobalLock(&pMac->sme); + } + return; +} + +/* + * SME API to stringify bonding mode. (hostapd convention) + */ + +static const char* sme_CBMode2String( tANI_U32 mode) +{ + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + return "HT20"; + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + return "HT40-"; /* lower secondary channel */ + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + return "HT40+"; /* upper secondary channel */ +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return "VHT80+40+"; /* upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return "VHT80+40-"; /* 1 lower and 2 upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return "VHT80-40+"; /* 2 lower and 1 upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return "VHT80-40-"; /* lower secondary channels */ +#endif + default: + VOS_ASSERT(0); + return "Unknown"; + } +} + +/* + * SME API to adjust bonding mode to regulatory, dfs nol .. etc. + * + */ +static VOS_STATUS sme_AdjustCBMode(tAniSirGlobal* pMac, + tSmeConfigParams *smeConfig, + tANI_U8 channel) +{ + + const tANI_U8 step = 4; + tANI_U8 i, startChan = channel, chanCnt = 0, chanBitmap = 0; + tANI_BOOLEAN violation = VOS_FALSE; + tANI_U32 newMode, mode; + + /* get the bonding mode */ + mode = (channel <= 14) ? smeConfig->csrConfig.channelBondingMode24GHz : + smeConfig->csrConfig.channelBondingMode5GHz; + newMode = mode; + + /* get the channels */ + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + startChan = channel; + chanCnt = 1; + break; + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + startChan = channel - step; + chanCnt = 2; + break; + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + startChan = channel; + chanCnt=2; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + startChan = channel; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + startChan = channel - step; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + startChan = channel - 2*step; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + startChan = channel - 3*step; + chanCnt = 4; + break; +#endif + default: + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* find violation; also map valid channels to a bitmap */ + for (i = 0; i < chanCnt; i++) + { + if (csrIsValidChannel(pMac, (startChan + (i * step))) == + VOS_STATUS_SUCCESS) + chanBitmap = chanBitmap | 1 << i; + else + violation = VOS_TRUE; + } + + /* no channels are valid */ + if (chanBitmap == 0) + { + /* never be in this case */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("channel %d %s is not supported"), + channel, + sme_CBMode2String(mode)); + return VOS_STATUS_E_INVAL; + } + + /* fix violation */ + if (violation) + { + const tANI_U8 lowerMask = 0x03, upperMask = 0x0c; + /* fall back to single channel in all exception cases */ + newMode = eCSR_INI_SINGLE_CHANNEL_CENTERED; + + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + /* fall thru */ + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + /* fall thru */ + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + if ((chanBitmap & lowerMask) == lowerMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + if ((chanBitmap & lowerMask) == lowerMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + if ((chanBitmap & upperMask) == upperMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + if ((chanBitmap & upperMask) == upperMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; +#endif + default: + return VOS_STATUS_E_NOSUPPORT; + break; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("bonding mode adjust: %s to %s"), + sme_CBMode2String(mode), + sme_CBMode2String(newMode)); + + } + + /* check for mode change */ + if (newMode != mode) + { + if (channel <= 14) + smeConfig->csrConfig.channelBondingMode24GHz = newMode; + else + smeConfig->csrConfig.channelBondingMode5GHz = newMode; + } + + return VOS_STATUS_SUCCESS; + +} + +/* + * SME API to determine the channel bonding mode + */ +VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, tANI_U8 channel) +{ + tSmeConfigParams smeConfig; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ( +#ifdef WLAN_FEATURE_11AC + eCSR_DOT11_MODE_11ac != eCsrPhyMode && + eCSR_DOT11_MODE_11ac_ONLY != eCsrPhyMode && +#endif + eCSR_DOT11_MODE_11n != eCsrPhyMode && + eCSR_DOT11_MODE_11n_ONLY != eCsrPhyMode && + + eCSR_DOT11_MODE_11a != eCsrPhyMode && + eCSR_DOT11_MODE_11a_ONLY != eCsrPhyMode && + + eCSR_DOT11_MODE_abg != eCsrPhyMode + ) + { + return VOS_STATUS_SUCCESS; + } + + /* If channel bonding mode is not required */ + if ( !pMac->roam.configParam.channelBondingMode5GHz + && !pMac->roam.configParam.channelBondingMode24GHz) { + return VOS_STATUS_SUCCESS; + } + + vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(pMac, &smeConfig); + +#ifdef WLAN_FEATURE_11AC + if ( eCSR_DOT11_MODE_11ac == eCsrPhyMode || + eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode ) + { + if (pMac->roam.configParam.channelBondingMode5GHz) { + if ( channel== 36 || channel == 52 || channel == 100 || + channel == 116 || channel == 149 || channel == 132) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + } + else if ( channel == 40 || channel == 56 || channel == 104 || + channel == 120 || channel == 153 || channel == 136) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + } + else if ( channel == 44 || channel == 60 || channel == 108 || + channel == 124 || channel == 157 || channel == 140) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + } + else if ( channel == 48 || channel == 64 || channel == 112 || + channel == 128 || channel == 144 || channel == 161 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + } + else if ( channel == 165 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } + /*TODO: Set HT40+ / HT40- for channel 5-7 based on ACS */ + if (pMac->roam.configParam.channelBondingMode24GHz) { + if (channel >= 1 && channel <= 5) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + else if (channel >= 6 && channel <= 13) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (channel ==14) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } +#endif + + if ( eCSR_DOT11_MODE_11n == eCsrPhyMode || + eCSR_DOT11_MODE_11n_ONLY == eCsrPhyMode ) + { + if (pMac->roam.configParam.channelBondingMode5GHz) { + if ( channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 153 || channel == 161 || channel == 144) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + } + else if ( channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 149 || channel == 157 || channel == 140) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + } + else if ( channel == 165 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } + +#ifdef QCA_HT_2040_COEX + /* if obss is enabled, the channel bonding mode is coming from hostapd, + so we don't need to hard code it here */ + if (!pMac->roam.configParam.obssEnabled) +#endif + if (pMac->roam.configParam.channelBondingMode24GHz) + { + if (channel >= 1 && channel <= 5) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + else if (channel >= 6 && channel <= 13) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (channel ==14) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } + + /* + for 802.11a phy mode, channel bonding should be zero. + From default config, it is set as PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + through csrChangeDefaultConfigParam function. We will override this + value here. + for 802.11g only phy mode also channel bonding should be zero. + */ + if ( eCSR_DOT11_MODE_11a == eCsrPhyMode || + eCSR_DOT11_MODE_11a_ONLY == eCsrPhyMode || + eCSR_DOT11_MODE_abg == eCsrPhyMode) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } else if ( eCSR_DOT11_MODE_11g_ONLY == eCsrPhyMode) + smeConfig.csrConfig.channelBondingMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + + sme_AdjustCBMode(pMac, &smeConfig, channel); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s cbmode selected=%d", (channel <= 14) ? "2G" : "5G", + (channel <= 14) ? smeConfig.csrConfig.channelBondingMode24GHz : + smeConfig.csrConfig.channelBondingMode5GHz); + + sme_UpdateConfig (pMac, &smeConfig); + return VOS_STATUS_SUCCESS; +} + +/*convert the ini value to the ENUM used in csr and MAC for CB state*/ +ePhyChanBondState sme_GetCBPhyStateFromCBIniValue(tANI_U32 cb_ini_value) +{ + return(csrConvertCBIniValueToPhyCBState(cb_ini_value)); +} +/*-------------------------------------------------------------------------- + + \brief sme_SetCurrDeviceMode() - Sets the current operating device mode. + \param hHal - The handle returned by macOpen. + \param currDeviceMode - Current operating device mode. + --------------------------------------------------------------------------*/ + +void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->sme.currDeviceMode = currDeviceMode; + return; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_HandoffRequest() - a wrapper function to Request a handoff + from CSR. + This is a synchronous call + \param hHal - The handle returned by macOpen + \param sessionId - Session Identifier + \param pHandoffInfo - info provided by HDD with the handoff request (namely: + BSSID, channel etc.) + \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_HandoffRequest(tHalHandle hHal, + tANI_U8 sessionId, + tCsrHandoffRequest *pHandoffInfo) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: invoked", __func__); + status = csrHandoffRequest(pMac, sessionId, pHandoffInfo); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} +#endif + +/* + * SME API to check if there is any infra station or + * P2P client is connected + */ +VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if(csrIsInfraConnected(pMac)) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; +} + + +#ifdef FEATURE_WLAN_LPHB +/* --------------------------------------------------------------------------- + \fn sme_LPHBConfigReq + \API to make configuration LPHB within FW. + \param hHal - The handle returned by macOpen + \param lphdReq - LPHB request argument by client + \param pCallbackfn - LPHB timeout notification callback function pointer + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_LPHBConfigReq +( + tHalHandle hHal, + tSirLPHBReq *lphdReq, + void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd *indParam) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) && + (NULL == pCallbackfn) && + (NULL == pMac->sme.pLphbIndCb)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Indication Call back did not registered", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + else if (NULL != pCallbackfn) + { + pMac->sme.pLphbIndCb = pCallbackfn; + } + + /* serialize the req through MC thread */ + vosMessage.bodyptr = lphdReq; + vosMessage.type = WDA_LPHB_CONF_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Config LPHB MSG fail", __func__); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +#endif /* FEATURE_WLAN_LPHB */ +/*-------------------------------------------------------------------------- + \brief sme_enable_disable_split_scan() - a wrapper function to set the split + scan parameter. + This is a synchronous call + \param hHal - The handle returned by macOpen + \return NONE. + \sa + --------------------------------------------------------------------------*/ +void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan, + tANI_U8 nNumP2PChan) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan; + pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: SCAN nNumStaChanCombinedConc : %d," + "nNumP2PChanCombinedConc : %d ", + __func__, nNumStaChan, nNumP2PChan); + + return; + +} + +/* --------------------------------------------------------------------------- + \fn sme_AddPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param addPeriodicTxPtrnParams - Pointer to the add pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_AddPeriodicTxPtrn(tHalHandle hHal, tSirAddPeriodicTxPtrn + *addPeriodicTxPtrnParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + vos_msg_t msg; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + msg.type = WDA_ADD_PERIODIC_TX_PTRN_IND; + msg.bodyptr = addPeriodicTxPtrnParams; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able " + "to post WDA_ADD_PERIODIC_TX_PTRN_IND to WDA!", + __func__); + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_DelPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param delPeriodicTxPtrnParams - Pointer to the delete pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_DelPeriodicTxPtrn(tHalHandle hHal, tSirDelPeriodicTxPtrn + *delPeriodicTxPtrnParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + vos_msg_t msg; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + msg.type = WDA_DEL_PERIODIC_TX_PTRN_IND; + msg.bodyptr = delPeriodicTxPtrnParams; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able " + "to post WDA_DEL_PERIODIC_TX_PTRN_IND to WDA!", + __func__); + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + + return status; +} + +void smeGetCommandQStatus( tHalHandle hHal ) +{ + tSmeCmd *pTempCmd = NULL; + tListElem *pEntry; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pMac is NULL", __func__); + return; + } + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if( pEntry ) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + } + smsLog( pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)", + (pTempCmd) ? pTempCmd->command : eSmeNoCommand ); + if(pTempCmd) + { + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + } //if(pTempCmd) + + smsLog( pMac, LOGE, "Currently smeCmdPendingList has %d commands", + csrLLCount(&pMac->sme.smeCmdPendingList)); + + smsLog( pMac, LOGE, "Currently roamCmdPendingList has %d commands", + csrLLCount(&pMac->roam.roamCmdPendingList)); + + return; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* --------------------------------------------------------------------------- + \fn sme_SetBatchScanReq + \brief API to set batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting set batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetBatchScanReq +( + tHalHandle hHal, tSirSetBatchScanReq *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, tSirSetBatchScanRsp *pRsp), + void *callbackContext +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if (!pMac) + { + return eHAL_STATUS_FAILURE; + } + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcSetBatchScanReq(hHal, pRequest, sessionId, callbackRoutine, + callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_TriggerBatchScanResultInd + \brief API to trigger batch scan result indications from FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to get batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting batch scan result indication from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_TriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, void *pRsp), + void *callbackContext +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcTriggerBatchScanResultInd(hHal, pRequest, sessionId, + callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + + +/* --------------------------------------------------------------------------- + \fn sme_StopBatchScanInd + \brief API to stop batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopBatchScanInd +( + tHalHandle hHal, tSirStopBatchScanInd *pRequest, tANI_U8 sessionId +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcStopBatchScanInd(hHal, pRequest, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + +#endif + +void sme_getRecoveryStats(tHalHandle hHal) { + tANI_U8 i; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Self Recovery Stats"); + for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) { + if (eSmeNoCommand != gSelfRecoveryStats.activeCmdStats[i].command) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "timestamp %llu: command 0x%0X: reason %d: session %d", + gSelfRecoveryStats.activeCmdStats[i].timestamp, + gSelfRecoveryStats.activeCmdStats[i].command, + gSelfRecoveryStats.activeCmdStats[i].reason, + gSelfRecoveryStats.activeCmdStats[i].sessionId); + } + } +} + +void sme_SaveActiveCmdStats(tHalHandle hHal) { + tSmeCmd *pTempCmd = NULL; + tListElem *pEntry; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 statsIndx = 0; + + if (NULL == pMac) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pMac is NULL", __func__); + return; + } + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (pEntry) { + pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + + if (pTempCmd) { + if (eSmeCsrCommandMask & pTempCmd->command) { + statsIndx = gSelfRecoveryStats.cmdStatsIndx; + gSelfRecoveryStats.activeCmdStats[statsIndx].command = + pTempCmd->command; + gSelfRecoveryStats.activeCmdStats[statsIndx].sessionId = + pTempCmd->sessionId; + gSelfRecoveryStats.activeCmdStats[statsIndx].timestamp = + vos_get_monotonic_boottime(); + if (eSmeCommandRoam == pTempCmd->command) { + gSelfRecoveryStats.activeCmdStats[statsIndx].reason = + pTempCmd->u.roamCmd.roamReason; + } else if (eSmeCommandScan == pTempCmd->command) { + gSelfRecoveryStats.activeCmdStats[statsIndx].reason = + pTempCmd->u.scanCmd.reason; + } else { + gSelfRecoveryStats.activeCmdStats[statsIndx].reason = 0xFF; + } + + gSelfRecoveryStats.cmdStatsIndx = + ((gSelfRecoveryStats.cmdStatsIndx + 1) & + (MAX_ACTIVE_CMD_STATS - 1)); + } + } + return; +} + +void activeListCmdTimeoutHandle(void *userData) +{ + if (NULL == userData) + return; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Active List command timeout Cmd List Count %d", __func__, + csrLLCount(&((tpAniSirGlobal) userData)->sme.smeCmdActiveList) ); + smeGetCommandQStatus((tHalHandle) userData); + + if (((tpAniSirGlobal)userData)->sme.enableSelfRecovery) { + sme_SaveActiveCmdStats((tHalHandle)userData); + vos_trigger_recovery(); + } else { + VOS_BUG(0); + } +} + +VOS_STATUS sme_notify_modem_power_state(tHalHandle hHal, tANI_U32 value) +{ + vos_msg_t msg; + tpSirModemPowerStateInd pRequestBuf; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + return VOS_STATUS_E_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirModemPowerStateInd)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for MODEM POWER STATE IND", + __func__); + return VOS_STATUS_E_FAILURE; + } + + pRequestBuf->param = value; + + msg.type = WDA_MODEM_POWER_STATE_IND; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_MODEM_POWER_STATE_IND message" + " to WDA", __func__); + vos_mem_free(pRequestBuf); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +#ifdef QCA_HT_2040_COEX +VOS_STATUS sme_notify_ht2040_mode(tHalHandle hHal, tANI_U16 staId, + v_MACADDR_t macAddrSTA, v_U8_t sessionId, tANI_U8 channel_type) +{ + vos_msg_t msg; + tUpdateVHTOpMode *pHtOpMode = NULL; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + return VOS_STATUS_E_FAILURE; + } + + pHtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode)); + if ( NULL == pHtOpMode ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for setting OP mode", + __func__); + return VOS_STATUS_E_FAILURE; + } + + switch (channel_type) + { + case eHT_CHAN_HT20: + pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ; + break; + + case eHT_CHAN_HT40MINUS: + case eHT_CHAN_HT40PLUS: + pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid OP mode", + __func__); + return VOS_STATUS_E_FAILURE; + } + + pHtOpMode->staId = staId, + vos_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes, + sizeof(tSirMacAddr)); + pHtOpMode->smesessionId = sessionId; + + msg.type = WDA_UPDATE_OP_MODE; + msg.reserved = 0; + msg.bodyptr = pHtOpMode; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_UPDATE_OP_MODE message" + " to WDA", __func__); + vos_mem_free(pHtOpMode); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Notifed FW about OP mode: %d for staId=%d", + __func__, pHtOpMode->opMode, staId); + + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetHT2040Mode + + \brief To update HT Operation beacon IE. + + \param hHal - The handle returned by macOPen + \param sessionId - session id + \param channel_type - indicates channel width + \param obssEnabled - OBSS enabled/disabled + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel_type, tANI_BOOLEAN obssEnabled) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + ePhyChanBondState cbMode; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Update HT operation beacon IE, channel_type=%d", + __func__, channel_type); + + switch (channel_type) + { + case eHT_CHAN_HT20: + cbMode = PHY_SINGLE_CHANNEL_CENTERED; + break; + case eHT_CHAN_HT40MINUS: + cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + case eHT_CHAN_HT40PLUS: + cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Error!!! Invalid HT20/40 mode !", + __func__); + return VOS_STATUS_E_FAILURE; + } + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) { + status = csrSetHT2040Mode(pMac, sessionId, cbMode, obssEnabled); + sme_ReleaseGlobalLock(&pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetPhyCBMode24G + + \brief Changes PHY channel bonding mode + + \param hHal - The handle returned by macOpen. + + \param cbMode new channel bonding mode which is to set + + \return eHalStatus SUCCESS. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetPhyCBMode24G(tHalHandle hHal, ePhyChanBondState phyCBMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return eHAL_STATUS_FAILURE; + } + + pMac->roam.configParam.channelBondingMode24GHz = phyCBMode; + + return eHAL_STATUS_SUCCESS; +} +#endif + +/* + * SME API to enable/disable idle mode powersave + * This should be called only if powersave offload + * is enabled + */ +VOS_STATUS sme_SetIdlePowersaveConfig(v_PVOID_t vosContext, tANI_U32 value) +{ + v_PVOID_t wdaContext = vos_get_context(VOS_MODULE_ID_WDA, vosContext); + + if (NULL == wdaContext) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: wdaContext is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + " Idle Ps Set Value %d", value); + + if (VOS_STATUS_SUCCESS != WDA_SetIdlePsConfig(wdaContext, value)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " Failed to Set Idle Ps Value %d", value); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +eHalStatus sme_ConfigEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcOffloadConfigEnablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +eHalStatus sme_ConfigDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcOffloadConfigDisablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +eHalStatus sme_PsOffloadEnablePowerSave (tHalHandle hHal, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS( status )) + { + status = PmcOffloadEnableStaModePowerSave(hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +eHalStatus sme_PsOffloadDisablePowerSave (tHalHandle hHal, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS( status )) + { + status = PmcOffloadDisableStaModePowerSave(hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +eHalStatus sme_PsOffloadEnableDeferredPowerSave (tHalHandle hHal, + tANI_U32 sessionId, + tANI_BOOLEAN isReassoc) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS( status )) + { + status = PmcOffloadEnableDeferredStaModePowerSave(hHal, sessionId, + isReassoc); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +eHalStatus sme_PsOffloadDisableDeferredPowerSave (tHalHandle hHal, + tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS( status )) + { + status = PmcOffloadDisableDeferredStaModePowerSave(hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +tANI_S16 sme_GetHTConfig(tHalHandle hHal, tANI_U8 session_id, tANI_U16 ht_capab) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id); + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pSession is NULL", __func__); + return -EIO; + } + switch (ht_capab) { + case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: + return pSession->htConfig.ht_rx_ldpc; + case WNI_CFG_HT_CAP_INFO_TX_STBC: + return pSession->htConfig.ht_tx_stbc; + case WNI_CFG_HT_CAP_INFO_RX_STBC: + return pSession->htConfig.ht_rx_stbc; + case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: + case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: + return pSession->htConfig.ht_sgi; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "invalid ht capability"); + return -EIO; + } +} + +int sme_UpdateHTConfig(tHalHandle hHal, tANI_U8 sessionId, tANI_U16 htCapab, + int value) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pSession is NULL", __func__); + return -EIO; + } + + if (eHAL_STATUS_SUCCESS != WDA_SetHTConfig(sessionId, htCapab, value)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to set ht capability in target"); + return -EIO; + } + + switch (htCapab) { + case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: + pSession->htConfig.ht_rx_ldpc = value; + break; + case WNI_CFG_HT_CAP_INFO_TX_STBC: + pSession->htConfig.ht_tx_stbc = value; + break; + case WNI_CFG_HT_CAP_INFO_RX_STBC: + pSession->htConfig.ht_rx_stbc = value; + break; + case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: + case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: + pSession->htConfig.ht_sgi = value; + break; + } + + return 0; +} + +#define HT20_SHORT_GI_MCS7_RATE 722 +/* --------------------------------------------------------------------------- + \fn sme_SendRateUpdateInd + \brief API to Update rate + \param hHal - The handle returned by macOpen + \param rateUpdateParams - Pointer to rate update params + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, + tSirRateUpdateInd *rateUpdateParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + vos_msg_t msg; + + + if (rateUpdateParams->mcastDataRate24GHz == + HT20_SHORT_GI_MCS7_RATE) + rateUpdateParams->mcastDataRate24GHzTxFlag = + eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; + else if (rateUpdateParams->reliableMcastDataRate == + HT20_SHORT_GI_MCS7_RATE) + rateUpdateParams->reliableMcastDataRateTxFlag = + eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + msg.type = WDA_RATE_UPDATE_IND; + msg.bodyptr = rateUpdateParams; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able " + "to post WDA_SET_RMC_RATE_IND to WDA!", + __func__); + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + + return status; +} + +eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, + tANI_U32 *regInfo1, tANI_U32 *regInfo2) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + tANI_U8 i; + eAniBoolean found = false; + + status = sme_AcquireGlobalLock(&pMac->sme); + *regInfo1 = 0; + *regInfo2 = 0; + if (HAL_STATUS_SUCCESS(status)) + { + for (i = 0 ; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) + { + if (pMac->scan.defaultPowerTable[i].chanId == chanId) + { + SME_SET_CHANNEL_REG_POWER(*regInfo1, + pMac->scan.defaultPowerTable[i].pwr); + + SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2, + pMac->scan.defaultPowerTable[i].pwr); + + + found = true; + break; + } + } + + if (!found) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +/* --------------------------------------------------------------------------- + \fn sme_auto_shutdown_cb + \brief Used to plug in callback function for receiving auto shutdown evt + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus +-------------------------------------------------------------------------*/ +eHalStatus sme_set_auto_shutdown_cb +( + tHalHandle hHal, + void (*pCallbackfn)(void) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Plug in Auto shutdown event callback", __func__); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if (NULL != pCallbackfn) + { + pMac->sme.pAutoShutdownNotificationCb = pCallbackfn; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +/* --------------------------------------------------------------------------- + \fn sme_set_auto_shutdown_timer + \API to set auto shutdown timer value in FW. + \param hHal - The handle returned by macOpen + \param timer_val - The auto shutdown timer value to be set + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_set_auto_shutdown_timer(tHalHandle hHal, tANI_U32 timer_val) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirAutoShutdownCmdParams *auto_sh_cmd; + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + auto_sh_cmd = (tSirAutoShutdownCmdParams *) + vos_mem_malloc(sizeof(tSirAutoShutdownCmdParams)); + if (auto_sh_cmd == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Request Buffer Alloc Fail", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + auto_sh_cmd->timer_val = timer_val; + + /* serialize the req through MC thread */ + vosMessage.bodyptr = auto_sh_cmd; + vosMessage.type = WDA_SET_AUTO_SHUTDOWN_TIMER_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Auto shutdown MSG fail", __func__); + vos_mem_free(auto_sh_cmd); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Posted Auto shutdown MSG", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +#endif + +#ifdef FEATURE_WLAN_CH_AVOID +/* --------------------------------------------------------------------------- + \fn sme_AddChAvoidCallback + \brief Used to plug in callback function + Which notify channel may not be used with SAP or P2PGO mode. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_AddChAvoidCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, void *indParam) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Plug in CH AVOID CB", __func__); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if (NULL != pCallbackfn) + { + pMac->sme.pChAvoidNotificationCb = pCallbackfn; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ChAvoidUpdateReq + \API to request channel avoidance update from FW. + \param hHal - The handle returned by macOpen + \param update_type - The udpate_type parameter of this request call + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_ChAvoidUpdateReq +( + tHalHandle hHal +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirChAvoidUpdateReq *cauReq; + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + cauReq = (tSirChAvoidUpdateReq *) + vos_mem_malloc(sizeof(tSirChAvoidUpdateReq)); + if (NULL == cauReq) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Request Buffer Alloc Fail", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + cauReq->reserved_param = 0; + + /* serialize the req through MC thread */ + vosMessage.bodyptr = cauReq; + vosMessage.type = WDA_CH_AVOID_UPDATE_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Ch Avoid Update MSG fail", __func__); + vos_mem_free(cauReq); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Posted Ch Avoid Update MSG", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +#endif /* FEATURE_WLAN_CH_AVOID */ + +/* ------------------------------------------------------------------------- + \fn sme_RoamChannelChangeReq + \brief API to Indicate Channel change to new target channel + \param hHal - The handle returned by macOpen + \param targetChannel - New Channel to move the SAP to. + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal, tCsrBssid bssid, + tANI_U8 targetChannel, eCsrPhyMode phyMode ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 cbMode; + + /* + * We are getting channel bonding mode from sapDfsInfor structure + * because we've implemented channel width fallback mechanism for DFS + * which will result in channel width changing dynamically. + */ + cbMode = pMac->sap.SapDfsInfo.new_cbMode; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + sme_SelectCBMode(hHal, phyMode, targetChannel); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + FL("sapdfs: channel bonding mode is [%d]"), cbMode); + status = csrRoamChannelChangeReq(pMac, bssid, targetChannel, + cbMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* ------------------------------------------------------------------------- + \fn sme_ProcessChannelChangeResp + \brief API to Indicate Channel change response message to SAP. + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac, + v_U16_t msg_type, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + eCsrRoamResult roamResult; + tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf; + tANI_U32 SessionId = pChnlParams->peSessionId; + + pRoamInfo.channelChangeRespEvent = + (tSirChanChangeResponse *)vos_mem_malloc( + sizeof(tSirChanChangeResponse)); + if (NULL == pRoamInfo.channelChangeRespEvent) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, "Channel Change Event Allocation Failed: %d\n", + status); + return status; + } + if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) + { + pRoamInfo.channelChangeRespEvent->sessionId = SessionId; + pRoamInfo.channelChangeRespEvent->newChannelNumber = + pChnlParams->channelNumber; + pRoamInfo.channelChangeRespEvent->secondaryChannelOffset = + pChnlParams->secondaryChannelOffset; + + if (pChnlParams->status == eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", + SessionId); + pRoamInfo.channelChangeRespEvent->channelChangeStatus = 1; + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", + SessionId); + pRoamInfo.channelChangeRespEvent->channelChangeStatus = 0; + roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; + } + + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, + eCSR_ROAM_SET_CHANNEL_RSP, roamResult); + + } + else + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n", + status); + } + return status; +} + +/* ------------------------------------------------------------------------- + \fn sme_RoamStartBeaconReq + \brief API to Indicate LIM to start Beacon Tx + \after SAP CAC Wait is completed. + \param hHal - The handle returned by macOpen + \param sessionId - session ID + \param dfsCacWaitStatus - CAC WAIT status flag + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, tCsrBssid bssid, + tANI_U8 dfsCacWaitStatus) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamStartBeaconReq( pMac, bssid, dfsCacWaitStatus); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* ------------------------------------------------------------------------- + \fn sme_RoamCsaIeRequest + \brief API to request CSA IE transmission from PE + \param hHal - The handle returned by macOpen + \param pDfsCsaReq - CSA IE request + \param bssid - SAP bssid + \return eHalStatus +---------------------------------------------------------------------------*/ +eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tCsrBssid bssid, + tANI_U8 targetChannel, tANI_U8 csaIeReqd) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamSendChanSwIERequest(pMac, bssid, targetChannel, + csaIeReqd); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_InitThermalInfo + \brief SME API to initialize the thermal mitigation parameters + \param hHal + \param thermalParam : thermal mitigation parameters + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_InitThermalInfo( tHalHandle hHal, + tSmeThermalParams thermalParam ) +{ + t_thermal_mgmt * pWdaParam; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pWdaParam = (t_thermal_mgmt *)vos_mem_malloc(sizeof(t_thermal_mgmt)); + if (NULL == pWdaParam) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: could not allocate tThermalMgmt", __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_zero((void*)pWdaParam, sizeof(t_thermal_mgmt)); + + pWdaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled; + pWdaParam->throttlePeriod = thermalParam.smeThrottlePeriod; + pWdaParam->thermalLevels[0].minTempThreshold = + thermalParam.smeThermalLevels[0].smeMinTempThreshold; + pWdaParam->thermalLevels[0].maxTempThreshold = + thermalParam.smeThermalLevels[0].smeMaxTempThreshold; + pWdaParam->thermalLevels[1].minTempThreshold = + thermalParam.smeThermalLevels[1].smeMinTempThreshold; + pWdaParam->thermalLevels[1].maxTempThreshold = + thermalParam.smeThermalLevels[1].smeMaxTempThreshold; + pWdaParam->thermalLevels[2].minTempThreshold = + thermalParam.smeThermalLevels[2].smeMinTempThreshold; + pWdaParam->thermalLevels[2].maxTempThreshold = + thermalParam.smeThermalLevels[2].smeMaxTempThreshold; + pWdaParam->thermalLevels[3].minTempThreshold = + thermalParam.smeThermalLevels[3].smeMinTempThreshold; + pWdaParam->thermalLevels[3].maxTempThreshold = + thermalParam.smeThermalLevels[3].smeMaxTempThreshold; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + msg.type = WDA_INIT_THERMAL_INFO_CMD; + msg.bodyptr = pWdaParam; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_THERMAL_INFO_CMD to WDA!", + __func__); + vos_mem_free(pWdaParam); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + vos_mem_free(pWdaParam); + return eHAL_STATUS_FAILURE; +} + +/* --------------------------------------------------------------------------- + \fn sme_InitThermalInfo + \brief SME API to set the thermal mitigation level + \param hHal + \param level : thermal mitigation level + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level ) +{ + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + u_int8_t *pLevel = vos_mem_malloc(sizeof(*pLevel)); + + pLevel = vos_mem_malloc(sizeof(*pLevel)); + if (NULL == pLevel) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: could not allocate pLevel", __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + *pLevel = level; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + msg.type = WDA_SET_THERMAL_LEVEL; + msg.reserved = 0; + msg.bodyptr = pLevel; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_THERMAL_LEVEL to WDA!", + __func__); + vos_mem_free(pLevel); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + vos_mem_free(pLevel); + return eHAL_STATUS_FAILURE; +} +/* --------------------------------------------------------------------------- + \fn sme_TxpowerLimit + \brief SME API to set txpower limits + \param hHal + \param psmetx : power limits for 2g/5g + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_TxpowerLimit(tHalHandle hHal, tSirTxPowerLimit *psmetx) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t vosMessage; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + vosMessage.type = WDA_TX_POWER_LIMIT; + vosMessage.reserved = 0; + vosMessage.bodyptr = psmetx; + + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_TX_POWER_LIMIT", + __func__); + status = eHAL_STATUS_FAILURE; + vos_mem_free(psmetx); + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} + +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->fEnableDebugLog = set_value; + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ApDisableIntraBssFwd + + \brief + SME will send message to WMA to set Intra BSS in txrx + + \param + + hHal - The handle returned by macOpen + + sessionId - session id ( vdev id) + + disablefwd - boolean value that indicate disable intrabss fwd disable + + \return eHalStatus +--------------------------------------------------------------------------- */ +eHalStatus sme_ApDisableIntraBssFwd(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN disablefwd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + int status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t vosMessage; + tpDisableIntraBssFwd pSapDisableIntraFwd = NULL; + + //Prepare the request to send to SME. + pSapDisableIntraFwd = vos_mem_malloc(sizeof(tDisableIntraBssFwd)); + if (NULL == pSapDisableIntraFwd) + { + smsLog(pMac, LOGP, "Memory Allocation Failure!!! %s", __func__); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_zero(pSapDisableIntraFwd, sizeof(tDisableIntraBssFwd)); + + pSapDisableIntraFwd->sessionId = sessionId; + pSapDisableIntraFwd->disableintrabssfwd = disablefwd; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = pSapDisableIntraFwd; + vosMessage.type = WDA_SET_SAP_INTRABSS_DIS; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + status = eHAL_STATUS_FAILURE; + vos_mem_free(pSapDisableIntraFwd); + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return (status); +} + +#ifdef WLAN_FEATURE_STATS_EXT + +/****************************************************************************** + \fn sme_StatsExtRegisterCallback + + \brief + a function called to register the callback that send vendor event for stats + ext + + \param callback - callback to be registered +******************************************************************************/ +void sme_StatsExtRegisterCallback(tHalHandle hHal, StatsExtCallback callback) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pMac->sme.StatsExtCallback = callback; +} + +/****************************************************************************** + \fn sme_StatsExtRequest + + \brief + a function called when HDD receives STATS EXT vendor command from userspace + + \param sessionID - vdevID for the stats ext request + + \param input - Stats Ext Request structure ptr + + \return eHalStatus +******************************************************************************/ +eHalStatus sme_StatsExtRequest(tANI_U8 session_id, tpStatsExtRequestReq input) +{ + vos_msg_t msg; + tpStatsExtRequest data; + size_t data_len; + + data_len = sizeof(tStatsExtRequest) + input->request_data_len; + data = vos_mem_malloc(data_len); + + if (data == NULL) { + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(data, data_len); + data->vdev_id = session_id; + data->request_data_len = input->request_data_len; + if (input->request_data_len) { + vos_mem_copy(data->request_data, + input->request_data, input->request_data_len); + } + + msg.type = WDA_STATS_EXT_REQUEST; + msg.reserved = 0; + msg.bodyptr = data; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, + &msg)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_STATS_EXT_REQUEST message to WDA", + __func__); + vos_mem_free(data); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** + \fn sme_StatsExtEvent + + \brief + a callback function called when SME received eWNI_SME_STATS_EXT_EVENT + response from WDA + + \param hHal - HAL handle for device + \param pMsg - Message body passed from WDA; includes NAN header + \return eHalStatus +******************************************************************************/ +eHalStatus sme_StatsExtEvent(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + if (NULL == pMsg) { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } else { + smsLog(pMac, LOG2, "SME: entering %s", __func__); + + if (pMac->sme.StatsExtCallback) { + pMac->sme.StatsExtCallback(pMac->hHdd, (tpStatsExtEvent)pMsg); + } + } + + return status; +} + +#endif + +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS roam scan mode + This function is called through dynamic setConfig callback function + to configure allowDFSChannelRoam. + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \param allowDFSChannelRoam - DFS roaming scan mode 0 (disable), + 1 (passive), 2 (active) + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS roaming scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, tANI_U8 sessionId, + v_U8_t allowDFSChannelRoam) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set AllowDFSChannelRoam Mode to " + "%d - old value is %d - roam state is %s", + allowDFSChannelRoam, + pMac->roam.configParam.allowDFSChannelRoam, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)); + pMac->roam.configParam.allowDFSChannelRoam = allowDFSChannelRoam; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_DFS_SCAN_MODE_CHANGED); + } +#endif + + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_GetDFSScanMode() - get DFS roam scan mode + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active) + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetDFSScanMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.allowDFSChannelRoam; +} + + +/*---------------------------------------------------------------------------- + \fn sme_ModifyAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pModifyIE - pointer to tModifyIE structure + \param updateType - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_ModifyAddIE(tHalHandle hHal, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamModifyAddIEs(pMac, pModifyIE, updateType); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + + +/*---------------------------------------------------------------------------- + \fn sme_UpdateAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pUpdateIE - pointer to structure tUpdateIE + \param updateType - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_UpdateAddIE(tHalHandle hHal, + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamUpdateAddIEs(pMac, pUpdateIE, updateType); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_staInMiddleOfRoaming + \brief This function returns TRUE if STA is in the middle of roaming state + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \- return TRUE or FALSE + -------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_staInMiddleOfRoaming(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN ret = FALSE; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + ret = csrNeighborMiddleOfRoaming(hHal, sessionId); + sme_ReleaseGlobalLock(&pMac->sme); + } + return ret; +} + +/* --------------------------------------------------------------------------- + \fn sme_PsOffloadIsStaInPowerSave + \brief This function returns TRUE if STA is in power save + \param hHal - HAL handle for device + \param sessionId - Session Identifier + \return TRUE or FALSE + -------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_PsOffloadIsStaInPowerSave(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN ret = FALSE; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + ret = pmcOffloadIsStaInPowerSave(pMac, sessionId); + sme_ReleaseGlobalLock(&pMac->sme); + } + return ret; +} + +VOS_STATUS sme_UpdateDSCPtoUPMapping( tHalHandle hHal, + sme_QosWmmUpType *dscpmapping, + v_U8_t sessionId ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U8_t i, j, peSessionId; + tCsrRoamSession *pCsrSession = NULL; + tpPESession pSession = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + if (pCsrSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session lookup fails for CSR session", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid session Id %u", __func__, sessionId); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + pSession = peFindSessionByBssid( pMac, + pCsrSession->connectedProfile.bssid, &peSessionId ); + + if (pSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session lookup fails for BSSID", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + if ( !pSession->QosMapSet.present ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: QOS Mapping IE not present", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + else + { + for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) + { + for (j = pSession->QosMapSet.dscp_range[i][0]; + j <= pSession->QosMapSet.dscp_range[i][1]; j++) + { + if ((pSession->QosMapSet.dscp_range[i][0] == 255) && + (pSession->QosMapSet.dscp_range[i][1] == 255)) + { + dscpmapping[j]= 0; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: User Priority %d is not used in mapping", + __func__, i); + break; + } + else + { + dscpmapping[j]= i; + } + } + } + for (i = 0; i< pSession->QosMapSet.num_dscp_exceptions; i++) + { + if (pSession->QosMapSet.dscp_exceptions[i][0] != 255) + { + dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0] ] = + pSession->QosMapSet.dscp_exceptions[i][1]; + } + } + } + } + sme_ReleaseGlobalLock( &pMac->sme); + return status; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_abortRoamScan + \brief API to abort current roam scan cycle by roam scan offload module. + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_abortRoamScan(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOGW, "entering function %s", __func__); + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + /* acquire the lock for the sme object */ + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + csrRoamOffloadScan(pMac, sessionId, ROAM_SCAN_OFFLOAD_ABORT_SCAN, + REASON_ROAM_ABORT_ROAM_SCAN); + /* release the lock for the sme object */ + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + + return(status); +} +#endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef FEATURE_WLAN_EXTSCAN +/* --------------------------------------------------------------------------- + \fn sme_GetValidChannelsByBand + \brief SME API to fetch all valid channels filtered by band + \param hHal + \param wifiBand: RF band information + \param aValidChannels: output array to store channel info + \param pNumChannels: output number of channels + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetValidChannelsByBand(tHalHandle hHal, + tANI_U8 wifiBand, + tANI_U32 *aValidChannels, + tANI_U8 *pNumChannels) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 numChannels = 0; + tANI_U8 i = 0; + tANI_U32 totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if (!aValidChannels || !pNumChannels) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Output channel list/NumChannels is NULL")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Invalid wifiBand (%d)"), wifiBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + + status = sme_GetCfgValidChannels(hHal, &chanList[0], + &totValidChannels); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get valid channel list (err=%d)"), status); + return status; + } + + switch (wifiBand) { + case WIFI_BAND_UNSPECIFIED: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("Unspecified wifiBand, " + "return all (%d) valid channels"), totValidChannels); + numChannels = totValidChannels; + for (i = 0; i < totValidChannels; i++) { + aValidChannels[i] = vos_chan_to_freq(chanList[i]); + } + break; + + case WIFI_BAND_BG: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("WIFI_BAND_BG (2.4 GHz)")); + for (i = 0; i < totValidChannels; i++) { + if (CSR_IS_CHANNEL_24GHZ(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + case WIFI_BAND_A: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A (5 GHz without DFS)")); + for (i = 0; i < totValidChannels; i++) { + if (CSR_IS_CHANNEL_5GHZ(chanList[i]) && + !CSR_IS_CHANNEL_DFS(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + case WIFI_BAND_ABG: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)")); + for (i = 0; i < totValidChannels; i++) { + if ((CSR_IS_CHANNEL_24GHZ(chanList[i]) || + CSR_IS_CHANNEL_5GHZ(chanList[i])) && + !CSR_IS_CHANNEL_DFS(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + case WIFI_BAND_A_DFS_ONLY: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A_DFS (5 GHz DFS only)")); + for (i = 0; i < totValidChannels; i++) { + if (CSR_IS_CHANNEL_5GHZ(chanList[i]) && + CSR_IS_CHANNEL_DFS(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + case WIFI_BAND_A_WITH_DFS: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)")); + for (i = 0; i < totValidChannels; i++) { + if (CSR_IS_CHANNEL_5GHZ(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + case WIFI_BAND_ABG_WITH_DFS: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz + 5 GHz with DFS)")); + for (i = 0; i < totValidChannels; i++) { + if (CSR_IS_CHANNEL_24GHZ(chanList[i]) || + CSR_IS_CHANNEL_5GHZ(chanList[i])) { + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + } + } + break; + + default: + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Unknown wifiBand (%d))"), wifiBand); + return eHAL_STATUS_INVALID_PARAMETER; + break; + } + *pNumChannels = numChannels; + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanGetCapabilities + \brief SME API to fetch extscan capabilities + \param hHal + \param pReq: extscan capabilities structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanGetCapabilities (tHalHandle hHal, + tSirGetExtScanCapabilitiesReqParams *pReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pReq; + vosMessage.type = WDA_EXTSCAN_GET_CAPABILITIES_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanStart + \brief SME API to issue extscan start + \param hHal + \param pStartCmd: extscan start structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanStart (tHalHandle hHal, + tSirWifiScanCmdReqParams *pStartCmd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pStartCmd; + vosMessage.type = WDA_EXTSCAN_START_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ExtScanStop + \brief SME API to issue extscan stop + \param hHal + \param pStopReq: extscan stop structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ExtScanStop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pStopReq; + vosMessage.type = WDA_EXTSCAN_STOP_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetBssHotlist + \brief SME API to set BSSID hotlist + \param hHal + \param pSetHotListReq: extscan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetBssHotlist (tHalHandle hHal, + tSirExtScanSetBssidHotListReqParams *pSetHotListReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pSetHotListReq; + vosMessage.type = WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ResetBssHotlist + \brief SME API to reset BSSID hotlist + \param hHal + \param pSetHotListReq: extscan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetBssHotlist (tHalHandle hHal, + tSirExtScanResetBssidHotlistReqParams *pResetReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pResetReq; + vosMessage.type = WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetSignificantChange + \brief SME API to set significant change + \param hHal + \param pSetSignificantChangeReq: extscan set significant change structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetSignificantChange (tHalHandle hHal, + tSirExtScanSetSigChangeReqParams *pSetSignificantChangeReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pSetSignificantChangeReq; + vosMessage.type = WDA_EXTSCAN_SET_SIGNF_CHANGE_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_ResetSignificantChange + \brief SME API to reset significant change + \param hHal + \param pResetReq: extscan reset significant change structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetSignificantChange (tHalHandle hHal, + tSirExtScanResetSignificantChangeReqParams *pResetReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pResetReq; + vosMessage.type = WDA_EXTSCAN_RESET_SIGNF_CHANGE_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_getCachedResults + \brief SME API to get cached results + \param hHal + \param pCachedResultsReq: extscan get cached results structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_getCachedResults (tHalHandle hHal, + tSirExtScanGetCachedResultsReqParams *pCachedResultsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pCachedResultsReq; + vosMessage.type = WDA_EXTSCAN_GET_CACHED_RESULTS_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, + void (*pExtScanIndCb)(void *, const tANI_U16, void *)) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + pMac->sme.pExtScanIndCb = pExtScanIndCb; + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsClearReq *clear_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pclearStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "statsClearReqMask = 0x%X", + pclearStatsReq->statsClearReqMask); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "stopReq = %u", pclearStatsReq->stopReq); + + clear_stats_req = vos_mem_malloc(sizeof(*clear_stats_req)); + + if (!clear_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_CLEAR_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *clear_stats_req = *pclearStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = clear_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_CLEAR_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_CLEAR_REQ", + __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsSetReq *set_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: MPDU Size = %u", __func__, + psetStatsReq->mpduSizeThreshold); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + " Aggressive Stats Collections = %u", + psetStatsReq->aggressiveStatisticsGathering); + + set_stats_req = vos_mem_malloc(sizeof(*set_stats_req)); + + if (!set_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_SET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *set_stats_req = *psetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = set_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_SET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_SET_REQ", + __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsGetReq *get_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "reqId = %u", pgetStatsReq->reqId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pgetStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Stats Type = %u", pgetStatsReq->paramIdMask); + + get_stats_req = vos_mem_malloc(sizeof(*get_stats_req)); + + if (!get_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_GET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *get_stats_req = *pgetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = get_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_GET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_GET_REQ", + __func__); + + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine; + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + } + + return(status); +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamOffloadEnabled() - enable/disable roam offload feaure + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + \param hHal - The handle returned by macOpen. + \param nRoamOffloadEnabled - The boolean to update with + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamOffloadEnabled(tHalHandle hHal, + v_BOOL_t nRoamOffloadEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: LFR3:gRoamOffloadEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isRoamOffloadEnabled, + nRoamOffloadEnabled); + pMac->roam.configParam.isRoamOffloadEnabled = nRoamOffloadEnabled; + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamKeyMgmtOffloadEnabled() - enable/disable key mgmt offload + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param sessionId - Session Identifier + \param nRoamKeyMgmtOffloadEnabled - The boolean to update with + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamKeyMgmtOffloadEnabled(tHalHandle hHal, + tANI_U8 sessionId, + v_BOOL_t nRoamKeyMgmtOffloadEnabled) + +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + if (CSR_IS_SESSION_VALID(pMac, sessionId)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: LFR3: KeyMgmtOffloadEnabled changed to %d", + __func__, + nRoamKeyMgmtOffloadEnabled); + status = csrRoamSetKeyMgmtOffload(pMac, + sessionId, + nRoamKeyMgmtOffloadEnabled); + } else { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetScanningMacOui + \brief SME API to set scanning mac oui + \param hHal + \param pScanMacOui: Scanning Mac Oui (input 3 bytes) + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetScanningMacOui(tHalHandle hHal, tSirScanMacOui *pScanMacOui) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pScanMacOui; + vosMessage.type = WDA_SET_SCAN_MAC_OUI_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Msg post Set Scan Mac OUI failed")); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +#endif + +/* --------------------------------------------------------------------------- + \fn sme_handle_dfS_chan_scan + \brief SME API to enable/disable DFS channel scan + \param hHal + \param dfs_flag: whether dfs needs to be enabled or disabled + \return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_handle_dfs_chan_scan(tHalHandle hHal, tANI_U8 dfs_flag) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + + if (eHAL_STATUS_SUCCESS == status) { + + pMac->scan.fEnableDFSChnlScan = dfs_flag; + + /* update the channel list to the firmware */ + status = csrUpdateChannelList(pMac); + + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status; +} + +/** + * sme_update_nss() - SME API to change the number for spatial streams (1 or 2) + * @hal: - Handle returned by macOpen + * @nss: - Number of spatial streams + * + * This function is used to update the number of spatial streams supported. + * + * Return: Success upon successfully changing nss else failure + * + */ +eHalStatus sme_update_nss(tHalHandle h_hal, uint8_t nss) +{ + eHalStatus status; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); + uint32_t i, value = 0; + union { + uint16_t cfg_value16; + tSirMacHTCapabilityInfo ht_cap_info; + } uHTCapabilityInfo; + tCsrRoamSession *csr_session; + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + + if (eHAL_STATUS_SUCCESS == status) { + mac_ctx->roam.configParam.enable2x2 = (nss == 1) ? 0 : 1; + + /* get the HT capability info*/ + ccmCfgGetInt(mac_ctx, WNI_CFG_HT_CAP_INFO, &value); + uHTCapabilityInfo.cfg_value16 = (0xFFFF & value); + + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { + if (CSR_IS_SESSION_VALID(mac_ctx, i)) { + csr_session = CSR_GET_SESSION(mac_ctx, i); + if (!csr_session) { + smsLog(mac_ctx, LOGE, + FL("Session does not exist for interface %d"), + i); + continue; + } + csr_session->htConfig.ht_tx_stbc = + uHTCapabilityInfo.ht_cap_info.txSTBC; + } + } + + sme_ReleaseGlobalLock(&mac_ctx->sme); + } + + return status; +} + +uint8_t sme_is_any_session_in_connected_state(tHalHandle h_hal) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); + eHalStatus status; + uint8_t ret = FALSE; + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (eHAL_STATUS_SUCCESS == status) { + ret = csrIsAnySessionInConnectState(mac_ctx); + sme_ReleaseGlobalLock(&mac_ctx->sme); + } + return ret; +} + +/** + * smeNeighborRoamIsHandoffInProgress() - Function to know if + * handoff is in progress + * @hal: Handle returned by macOpen + * @sessionId: sessionId of the STA session + * + * This function is a wrapper to call + * csrNeighborRoamIsHandoffInProgress to know if handoff is in + * progress + * + * Return: True or False + * + */ +bool smeNeighborRoamIsHandoffInProgress(tHalHandle hHal, tANI_U8 sessionId) +{ + return csrNeighborRoamIsHandoffInProgress(PMAC_STRUCT(hHal), sessionId); +} + +/** + * sme_disable_non_fcc_channel() - non-fcc channel disable request + * @hal: HAL pointer + * @fcc_constraint: true: disable, false; enable + * + * Return: eHalStatus. + */ +eHalStatus sme_disable_non_fcc_channel(tHalHandle hal, bool fcc_constraint) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal); + + status = sme_AcquireGlobalLock(&mac_ptr->sme); + + if (eHAL_STATUS_SUCCESS == status) { + + if (fcc_constraint != mac_ptr->scan.fcc_constraint) { + mac_ptr->scan.fcc_constraint = fcc_constraint; + + /* update the channel list to the firmware */ + status = csrUpdateChannelList(mac_ptr); + } + + sme_ReleaseGlobalLock(&mac_ptr->sme); + } + + return status; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c new file mode 100644 index 0000000000000..4c7c42e191dc0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c @@ -0,0 +1,625 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + \brief Definitions for SME FT APIs + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include + +/*-------------------------------------------------------------------------- + Initialize the FT context. + ------------------------------------------------------------------------*/ +void sme_FTOpen(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (NULL != pSession) { + /* Clean up the context */ + vos_mem_set(&pSession->ftSmeContext, sizeof(tftSMEContext), 0); + + pSession->ftSmeContext.pUsrCtx = vos_mem_malloc( + sizeof(tFTRoamCallbackUsrCtx)); + + if (NULL == pSession->ftSmeContext.pUsrCtx) { + smsLog(pMac, LOGE, FL("Memory allocation failure")); + return; + } + pSession->ftSmeContext.pUsrCtx->pMac = pMac; + pSession->ftSmeContext.pUsrCtx->sessionId = sessionId; + + status = + vos_timer_init(&pSession->ftSmeContext.preAuthReassocIntvlTimer, + VOS_TIMER_TYPE_SW, + sme_PreauthReassocIntvlTimerCallback, + (void *)pSession->ftSmeContext.pUsrCtx); + + if (eHAL_STATUS_SUCCESS != status) { + smsLog(pMac, LOGE, + FL("Preauth Reassoc interval Timer allocation failed")); + vos_mem_free(pSession->ftSmeContext.pUsrCtx); + pSession->ftSmeContext.pUsrCtx = NULL; + return; + } + } +} + +/*-------------------------------------------------------------------------- + Cleanup the SME FT Global context. + ------------------------------------------------------------------------*/ +void sme_FTClose(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = NULL; + + /* Clear the FT Context */ + sme_FTReset(hHal, sessionId); + + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL != pSession) + { + /* check if the timer is running */ + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( + &pSession->ftSmeContext.preAuthReassocIntvlTimer)) + { + vos_timer_stop(&pSession->ftSmeContext.preAuthReassocIntvlTimer); + } + + if (VOS_STATUS_SUCCESS != + vos_timer_destroy(&pSession->ftSmeContext.preAuthReassocIntvlTimer)) + { + smsLog(pMac, LOGE, FL("preAuthReAssocTimer destroy failed")); + } + + if (pSession->ftSmeContext.pUsrCtx != NULL) { + smsLog(pMac, LOG1, + FL("Freeing ftSmeContext.pUsrCtx and setting to NULL")); + vos_mem_free(pSession->ftSmeContext.pUsrCtx); + pSession->ftSmeContext.pUsrCtx = NULL; + } + } +} + +void sme_SetFTPreAuthState(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (pSession) + pSession->ftSmeContext.setFTPreAuthState = state; +} + +v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (pSession) + return pSession->ftSmeContext.setFTPreAuthState; + + return FALSE; +} + +/*-------------------------------------------------------------------------- + Each time the supplicant sends down the FT IEs to the driver. + This function is called in SME. This fucntion packages and sends + the FT IEs to PE. + ------------------------------------------------------------------------*/ +void sme_SetFTIEs(tHalHandle hHal, tANI_U32 sessionId, const tANI_U8 *ft_ies, + tANI_U16 ft_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession || NULL == ft_ies) + { + smsLog( pMac, LOGE, FL(" ft ies or pSession is NULL")); + return; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) return; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "FT IEs Req is received in state %d", + pSession->ftSmeContext.FTState); +#endif + + // Global Station FT State + switch(pSession->ftSmeContext.FTState) + { + case eFT_START_READY: + case eFT_AUTH_REQ_READY: + if ((pSession->ftSmeContext.auth_ft_ies) && + (pSession->ftSmeContext.auth_ft_ies_length)) + { + // Free the one we received last from the supplicant + vos_mem_free(pSession->ftSmeContext.auth_ft_ies); + pSession->ftSmeContext.auth_ft_ies_length = 0; + pSession->ftSmeContext.auth_ft_ies = NULL; + } + + // Save the FT IEs + pSession->ftSmeContext.auth_ft_ies = + vos_mem_malloc(ft_ies_length); + if ( NULL == pSession->ftSmeContext.auth_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for " + "auth_ft_ies")); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + pSession->ftSmeContext.auth_ft_ies_length = ft_ies_length; + vos_mem_copy((tANI_U8 *)pSession->ftSmeContext.auth_ft_ies, + ft_ies,ft_ies_length); + pSession->ftSmeContext.FTState = eFT_AUTH_REQ_READY; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "ft_ies_length=%d", ft_ies_length); +#endif + break; + + case eFT_AUTH_COMPLETE: + // We will need to re-start preauth. If we received FT IEs in + // eFT_PRE_AUTH_DONE state, it implies there was a rekey in + // our pre-auth state. Hence this implies we need Pre-auth again. + + // OK now inform SME we have no pre-auth list. + // Delete the pre-auth node locally. Set your self back to restart pre-auth + // TBD +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, + "Pre-auth done and now receiving---> AUTH REQ <---- in state %d", + pSession->ftSmeContext.FTState); + smsLog( pMac, LOG1, "Unhandled reception of FT IES in state %d", + pSession->ftSmeContext.FTState); +#endif + break; + + case eFT_REASSOC_REQ_WAIT: + // We are done with pre-auth, hence now waiting for + // reassoc req. This is the new FT Roaming in place + + // At this juncture we are ready to start sending Re-Assoc Req. +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "New Reassoc Req=%p in state %d", + ft_ies, pSession->ftSmeContext.FTState); +#endif + if ((pSession->ftSmeContext.reassoc_ft_ies) && + (pSession->ftSmeContext.reassoc_ft_ies_length)) + { + // Free the one we received last from the supplicant + vos_mem_free(pSession->ftSmeContext.reassoc_ft_ies); + pSession->ftSmeContext.reassoc_ft_ies_length = 0; + } + + // Save the FT IEs + pSession->ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length); + if ( NULL == pSession->ftSmeContext.reassoc_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for " + "reassoc_ft_ies")); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + pSession->ftSmeContext.reassoc_ft_ies_length = ft_ies_length; + vos_mem_copy((tANI_U8 *)pSession->ftSmeContext.reassoc_ft_ies, ft_ies, + ft_ies_length); + + pSession->ftSmeContext.FTState = eFT_SET_KEY_WAIT; +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "ft_ies_length=%d state=%d", ft_ies_length, + pSession->ftSmeContext.FTState); +#endif + + break; + + default: + smsLog( pMac, LOGE, FL(" Unhandled state=%d"), + pSession->ftSmeContext.FTState); + break; + } + sme_ReleaseGlobalLock( &pMac->sme ); +} + +eHalStatus sme_FTSendUpdateKeyInd(tHalHandle hHal, tANI_U32 sessionId, + tCsrRoamSetKey * pFTKeyInfo) +{ + tSirFTUpdateKeyInfo *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + tAniEdType tmpEdType; + tSirKeyMaterial *keymaterial = NULL; + tAniEdType edType; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + int i = 0; + + smsLog(pMac, LOG1, FL("keyLength %d"), pFTKeyInfo->keyLength); + + for (i=0; ikeyLength; i++) + smsLog(pMac, LOG1, FL("%02x"), pFTKeyInfo->Key[i]); +#endif + + if(pFTKeyInfo->keyLength > CSR_MAX_KEY_LEN) + { + smsLog( pMac, LOGE, "%s: invalid keyLength %d", __func__,pFTKeyInfo->keyLength); + return eHAL_STATUS_FAILURE; + } + + msgLen = sizeof(tSirFTUpdateKeyInfo); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_FT_UPDATE_KEY); + pMsg->length = pal_cpu_to_be16(msgLen); + + keymaterial = &pMsg->keyMaterial; + + keymaterial->length = pFTKeyInfo->keyLength; + + edType = csrTranslateEncryptTypeToEdType( pFTKeyInfo->encType ); + tmpEdType = pal_cpu_to_be32(edType); + keymaterial->edType = tmpEdType; + + // Set the pMsg->keyMaterial.length field (this length is defined as all + // data that follows the edType field + // in the tSirKeyMaterial keyMaterial; field). + // + // !!NOTE: This keyMaterial.length contains the length of a MAX size key, + // though the keyLength can be + // shorter than this max size. Is LIM interpreting this ok ? + keymaterial->numKeys = 1; + keymaterial->key[ 0 ].keyId = pFTKeyInfo->keyId; + keymaterial->key[ 0 ].unicast = (tANI_U8)eANI_BOOLEAN_TRUE; + keymaterial->key[ 0 ].keyDirection = pFTKeyInfo->keyDirection; + + vos_mem_copy(&keymaterial->key[ 0 ].keyRsc, pFTKeyInfo->keyRsc, CSR_MAX_RSC_LEN); + keymaterial->key[ 0 ].paeRole = pFTKeyInfo->paeRole; + + keymaterial->key[ 0 ].keyLength = pFTKeyInfo->keyLength; + + if ( pFTKeyInfo->keyLength && pFTKeyInfo->Key ) + { + vos_mem_copy(&keymaterial->key[ 0 ].key, pFTKeyInfo->Key, pFTKeyInfo->keyLength); + if(pFTKeyInfo->keyLength == 16) + { + smsLog(pMac, LOG1, + "SME Set Update Ind keyIdx (%d) encType(%d) key = " + "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", + pMsg->keyMaterial.key[0].keyId, (tAniEdType)pMsg->keyMaterial.edType, + pMsg->keyMaterial.key[0].key[0], pMsg->keyMaterial.key[0].key[1], + pMsg->keyMaterial.key[0].key[2], pMsg->keyMaterial.key[0].key[3], + pMsg->keyMaterial.key[0].key[4], pMsg->keyMaterial.key[0].key[5], + pMsg->keyMaterial.key[0].key[6], pMsg->keyMaterial.key[0].key[7], + pMsg->keyMaterial.key[0].key[8], pMsg->keyMaterial.key[0].key[9], + pMsg->keyMaterial.key[0].key[10], pMsg->keyMaterial.key[0].key[11], + pMsg->keyMaterial.key[0].key[12], pMsg->keyMaterial.key[0].key[13], + pMsg->keyMaterial.key[0].key[14], pMsg->keyMaterial.key[0].key[15]); + } + } + + vos_mem_copy( &pMsg->bssId[ 0 ], + &pFTKeyInfo->peerMac[ 0 ], + sizeof(tCsrBssid) ); + + pMsg->smeSessionId = sessionId; + + smsLog(pMac, LOG1, "BSSID = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pMsg->bssId)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return( status ); +} + +v_BOOL_t sme_GetFTPTKState(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) { + smsLog(pMac, LOGE, FL("pSession is NULL")); + return VOS_FALSE; + } + return pSession->ftSmeContext.setFTPTKState; +} + +void sme_SetFTPTKState(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) { + smsLog(pMac, LOGE, FL("pSession is NULL")); + return; + } + pSession->ftSmeContext.setFTPTKState = state; +} + +eHalStatus sme_FTUpdateKey(tHalHandle hHal, tANI_U32 sessionId, + tCsrRoamSetKey * pFTKeyInfo ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (!pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (pFTKeyInfo == NULL) + { + smsLog( pMac, LOGE, "%s: pFTKeyInfo is NULL", __func__); + return eHAL_STATUS_FAILURE; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + { + return eHAL_STATUS_FAILURE; + } + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "sme_FTUpdateKey is received in state %d", + pSession->ftSmeContext.FTState); +#endif + + // Global Station FT State + switch(pSession->ftSmeContext.FTState) + { + case eFT_SET_KEY_WAIT: + if (sme_GetFTPreAuthState(hHal, sessionId) == TRUE) + { + status = sme_FTSendUpdateKeyInd(pMac, sessionId, pFTKeyInfo); + if (status != 0 ) + { + smsLog( pMac, LOGE, "%s: Key set failure %d", __func__, + status); + pSession->ftSmeContext.setFTPTKState = FALSE; + status = eHAL_STATUS_FT_PREAUTH_KEY_FAILED; + } + else + { + pSession->ftSmeContext.setFTPTKState = TRUE; + status = eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS; + smsLog( pMac, LOG1, "%s: Key set success", __func__); + } + sme_SetFTPreAuthState(hHal, sessionId, FALSE); + } + + pSession->ftSmeContext.FTState = eFT_START_READY; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "%s: state changed to %d status %d", __func__, + pSession->ftSmeContext.FTState, status); +#endif + break; + + default: + smsLog( pMac, LOGW, "%s: Unhandled state=%d", __func__, + pSession->ftSmeContext.FTState); + status = eHAL_STATUS_FAILURE; + break; + } + sme_ReleaseGlobalLock( &pMac->sme ); + + return status; +} +/*-------------------------------------------------------------------------- + * + * HDD Interface to SME. SME now sends the Auth 2 and RIC IEs up to the supplicant. + * The supplicant will then proceed to send down the + * Reassoc Req. + * + *------------------------------------------------------------------------*/ +void sme_GetFTPreAuthResponse( tHalHandle hHal, tANI_U32 sessionId, tANI_U8 *ft_ies, + tANI_U32 ft_ies_ip_len, tANI_U16 *ft_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (!pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return; + } + + *ft_ies_length = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + return; + + /* All or nothing - proceed only if both BSSID and FT IE fit */ + if((ANI_MAC_ADDR_SIZE + + pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length) > ft_ies_ip_len) + { + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + + // hdd needs to pack the bssid also along with the + // auth response to supplicant + vos_mem_copy(ft_ies, pSession->ftSmeContext.preAuthbssId, ANI_MAC_ADDR_SIZE); + + // Copy the auth resp FTIEs + vos_mem_copy(&(ft_ies[ANI_MAC_ADDR_SIZE]), + pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies, + pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length); + + *ft_ies_length = ANI_MAC_ADDR_SIZE + + pSession->ftSmeContext.psavedFTPreAuthRsp->ft_ies_length; + + pSession->ftSmeContext.FTState = eFT_REASSOC_REQ_WAIT; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, FL(" Filled auth resp = %d"), *ft_ies_length); +#endif + sme_ReleaseGlobalLock( &pMac->sme ); + return; +} + +/*-------------------------------------------------------------------------- + * + * SME now sends the RIC IEs up to the supplicant. + * The supplicant will then proceed to send down the + * Reassoc Req. + * + *------------------------------------------------------------------------*/ +void sme_GetRICIEs(tHalHandle hHal, tANI_U32 sessionId, tANI_U8 *ric_ies, + tANI_U32 ric_ies_ip_len, tANI_U32 *ric_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (!pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return; + } + + *ric_ies_length = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + return; + + /* All or nothing */ + if (pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length > + ric_ies_ip_len) + { + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + + vos_mem_copy(ric_ies, pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies, + pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length); + + *ric_ies_length = pSession->ftSmeContext.psavedFTPreAuthRsp->ric_ies_length; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, FL(" Filled ric ies = %d"), *ric_ies_length); +#endif + + sme_ReleaseGlobalLock( &pMac->sme ); + return; +} + +/*-------------------------------------------------------------------------- + * + * Timer callback for the timer that is started between the preauth completion and + * reassoc request to the PE. In this interval, it is expected that the pre-auth response + * and RIC IEs are passed up to the WPA supplicant and received back the necessary FTIEs + * required to be sent in the reassoc request + * + *------------------------------------------------------------------------*/ +void sme_PreauthReassocIntvlTimerCallback(void *context) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tFTRoamCallbackUsrCtx *pUsrCtx = (tFTRoamCallbackUsrCtx *)context; + + if (pUsrCtx) { + csrNeighborRoamRequestHandoff(pUsrCtx->pMac, pUsrCtx->sessionId); + } +#endif + return; +} + +/*-------------------------------------------------------------------------- + Reset the FT context. + ------------------------------------------------------------------------*/ +void sme_FTReset(tHalHandle hHal, tANI_U32 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = NULL; + + if (pMac == NULL) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is NULL")); + return; + } + + pSession = CSR_GET_SESSION(pMac, sessionId); + if (NULL != pSession) { + if (pSession->ftSmeContext.auth_ft_ies != NULL) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog(pMac, LOG1, FL("Freeing FT Auth IE %p and setting to NULL"), + pSession->ftSmeContext.auth_ft_ies); +#endif + vos_mem_free(pSession->ftSmeContext.auth_ft_ies); + pSession->ftSmeContext.auth_ft_ies = NULL; + } + pSession->ftSmeContext.auth_ft_ies_length = 0; + + if (pSession->ftSmeContext.reassoc_ft_ies != NULL) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog(pMac, LOG1, + FL("Freeing FT Reassoc IE %p and setting to NULL"), + pSession->ftSmeContext.reassoc_ft_ies); +#endif + vos_mem_free(pSession->ftSmeContext.reassoc_ft_ies); + pSession->ftSmeContext.reassoc_ft_ies = NULL; + } + pSession->ftSmeContext.reassoc_ft_ies_length = 0; + + if (pSession->ftSmeContext.psavedFTPreAuthRsp != NULL) { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, FL("Freeing FtPreAuthRsp %p and setting to NULL"), + pSession->ftSmeContext.psavedFTPreAuthRsp); +#endif + vos_mem_free(pSession->ftSmeContext.psavedFTPreAuthRsp); + pSession->ftSmeContext.psavedFTPreAuthRsp = NULL; + } + pSession->ftSmeContext.setFTPreAuthState = VOS_FALSE; + pSession->ftSmeContext.setFTPTKState = VOS_FALSE; + + vos_mem_zero(pSession->ftSmeContext.preAuthbssId, ANI_MAC_ADDR_SIZE); + pSession->ftSmeContext.FTState = eFT_START_READY; + } +} + +/* End of File */ +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c new file mode 100644 index 0000000000000..c38d09a14cc47 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/************************************************************************ + smeTrace.c + + \brief implementation for trace related APIs + + \author Kiran Kumar Reddy CH L V + + ========================================================================*/ +#include "aniGlobal.h" //for tpAniSirGlobal +#include "smsDebug.h" +#include "macTrace.h" +#include "sme_Trace.h" +#include "smeInternal.h" +#ifndef SME_TRACE_RECORD +void smeTraceInit(tpAniSirGlobal pMac) +{ + return; +} +#endif +#ifdef SME_TRACE_RECORD + + +static tANI_U8* smeTraceGetRxMsgString( tANI_U32 code ) +{ + switch(code) + { + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_CONNECT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_REASSOC); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SIGNAL_POWER_EVENT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_BMPS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENTER_WOWL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXIT_WOWL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_KEY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMOVE_KEY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_STATS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_RSSI); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READREG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEREG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READMEM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_OPEN_SESSION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CLOSE_SESSION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SEND_ACTION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ); +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2); +#endif + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TXPOW); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TMLEVEL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CAPS_EXCH); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_CAP); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_DEFCCNV); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CURCC); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_RESET_PW5G); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RP5G); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_SCANCTRL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME); + + default: + return( "UNKNOWN" ); + break; + } +} +static tANI_U8* smeTraceGetCommandString( tANI_U32 command ) +{ + switch(command) + { + CASE_RETURN_STRING(eSmeNoCommand); + CASE_RETURN_STRING(eSmeDropCommand); + CASE_RETURN_STRING(eSmeCsrCommandMask); + CASE_RETURN_STRING(eSmeCommandScan); + CASE_RETURN_STRING(eSmeCommandRoam); + CASE_RETURN_STRING(eSmeCommandWmStatusChange); + CASE_RETURN_STRING(eSmeCommandSetKey); + CASE_RETURN_STRING(eSmeCommandRemoveKey); + CASE_RETURN_STRING(eSmeCommandAddStaSession); + CASE_RETURN_STRING(eSmeCommandDelStaSession); + CASE_RETURN_STRING(eSmePmcCommandMask); + CASE_RETURN_STRING(eSmeCommandEnterImps); + CASE_RETURN_STRING(eSmeCommandExitImps); + CASE_RETURN_STRING(eSmeCommandEnterBmps); + CASE_RETURN_STRING(eSmeCommandExitBmps); + CASE_RETURN_STRING(eSmeCommandEnterUapsd); + CASE_RETURN_STRING(eSmeCommandExitUapsd); + CASE_RETURN_STRING(eSmeCommandEnterWowl); + CASE_RETURN_STRING(eSmeCommandExitWowl); + CASE_RETURN_STRING(eSmeCommandEnterStandby); + CASE_RETURN_STRING(eSmeQosCommandMask); + CASE_RETURN_STRING(eSmeCommandAddTs); + CASE_RETURN_STRING(eSmeCommandDelTs); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(eSmeCommandOemDataReq); +#endif + CASE_RETURN_STRING(eSmeCommandRemainOnChannel); + CASE_RETURN_STRING(eSmeCommandNoAUpdate); + default: + return( "UNKNOWN" ); + break; + } +} +static void smeTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, + tANI_U16 recIndex) +{ + if (TRACE_CODE_SME_COMMAND == pRecord->code) + { + smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)", recIndex, + pRecord->time, pRecord->session, "SME COMMAND:", + smeTraceGetCommandString(pRecord->data), pRecord->data ); + } + else + { + smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)", recIndex, + pRecord->time, pRecord->session, "RX HDD MSG:", + smeTraceGetRxMsgString(pRecord->code), pRecord->data ); + } +} + +void smeTraceInit(tpAniSirGlobal pMac) +{ + vosTraceRegister(VOS_MODULE_ID_SME, (tpvosTraceCb)&smeTraceDump); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/external/wlan_nlink_common.h b/drivers/staging/qcacld-2.0/CORE/SVC/external/wlan_nlink_common.h new file mode 100644 index 0000000000000..3adac4e33b157 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/external/wlan_nlink_common.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + \file wlan_nlink_common.h + + Exports and types for the Netlink Service interface. This header file contains + message types and definitions that is shared between the user space service + (e.g. BTC service) and WLAN kernel module. + +===========================================================================*/ + +#ifndef WLAN_NLINK_COMMON_H__ +#define WLAN_NLINK_COMMON_H__ + +#include + +/*--------------------------------------------------------------------------- + * External Functions + *-------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + *-------------------------------------------------------------------------*/ +#define WLAN_NL_MAX_PAYLOAD 256 /* maximum size for netlink message*/ +#define WLAN_NLINK_PROTO_FAMILY NETLINK_USERSOCK +#define WLAN_NLINK_MCAST_GRP_ID 0x01 + +/*--------------------------------------------------------------------------- + * Type Declarations + *-------------------------------------------------------------------------*/ + +/* + * The following enum defines the target service within WLAN driver for which the + * message is intended for. Each service along with its counterpart + * in the user space, define a set of messages they recognize. + * Each of this message will have an header of type tAniMsgHdr defined below. + * Each Netlink message to/from a kernel module will contain only one + * message which is preceded by a tAniMsgHdr. The maximun size (in bytes) of + * a netlink message is assumed to be MAX_PAYLOAD bytes. + * + * +------------+-------+----------+----------+ + * |Netlink hdr | Align |tAniMsgHdr| msg body | + * +------------+-------+----------|----------+ + */ + +// Message Types +#define WLAN_BTC_QUERY_STATE_REQ 0x01 // BTC --> WLAN +#define WLAN_BTC_BT_EVENT_IND 0x02 // BTC --> WLAN +#define WLAN_BTC_QUERY_STATE_RSP 0x03 // WLAN --> BTC +#define WLAN_MODULE_UP_IND 0x04 // WLAN --> BTC +#define WLAN_MODULE_DOWN_IND 0x05 // WLAN --> BTC +#define WLAN_STA_ASSOC_DONE_IND 0x06 // WLAN --> BTC +#define WLAN_STA_DISASSOC_DONE_IND 0x07 // WLAN --> BTC + +// Special Message Type used by AMP, intercepted by send_btc_nlink_msg() and +// replaced by WLAN_STA_ASSOC_DONE_IND or WLAN_STA_DISASSOC_DONE_IND +#define WLAN_AMP_ASSOC_DONE_IND 0x10 + +// Special Message Type used by SoftAP, intercepted by send_btc_nlink_msg() and +// replaced by WLAN_STA_ASSOC_DONE_IND +#define WLAN_BTC_SOFTAP_BSS_START 0x11 +#define WLAN_SVC_FW_CRASHED_IND 0x100 +#define WLAN_SVC_LTE_COEX_IND 0x101 +#define WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND 0x102 +#define WLAN_SVC_DFS_CAC_START_IND 0x103 +#define WLAN_SVC_DFS_CAC_END_IND 0x104 +#define WLAN_SVC_DFS_RADAR_DETECT_IND 0x105 +#define WLAN_SVC_WLAN_STATUS_IND 0x106 +#define WLAN_SVC_WLAN_VERSION_IND 0x107 +#define WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND 0x108 +#define WLAN_SVC_WLAN_TP_IND 0x109 + +#define WLAN_SVC_MAX_SSID_LEN 32 +#define WLAN_SVC_MAX_BSSID_LEN 6 +#define WLAN_SVC_MAX_STR_LEN 16 +#define WLAN_SVC_MAX_NUM_CHAN 128 +#define WLAN_SVC_COUNTRY_CODE_LEN 3 + +// Event data for WLAN_BTC_QUERY_STATE_RSP & WLAN_STA_ASSOC_DONE_IND +typedef struct +{ + unsigned char channel; // 0 implies STA not associated to AP +} tWlanAssocData; + +#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */ + +typedef enum eAniNlModuleTypes { + ANI_NL_MSG_PUMAC = ANI_NL_MSG_BASE + 0x01,// PTT Socket App + ANI_NL_MSG_PTT = ANI_NL_MSG_BASE + 0x07,// Quarky GUI + WLAN_NL_MSG_BTC, + WLAN_NL_MSG_OEM, + WLAN_NL_MSG_SVC, + WLAN_NL_MSG_CNSS_DIAG = ANI_NL_MSG_BASE + 0x0B,//Value needs to be 27 + ANI_NL_MSG_LOG, + ANI_NL_MSG_MAX +} tAniNlModTypes, tWlanNlModTypes; + +#define WLAN_NL_MSG_BASE ANI_NL_MSG_BASE +#define WLAN_NL_MSG_MAX ANI_NL_MSG_MAX + +//All Netlink messages must contain this header +typedef struct sAniHdr { + unsigned short type; + unsigned short length; +} tAniHdr, tAniMsgHdr; + +struct wlan_status_data { + uint8_t lpss_support; + uint8_t is_on; + uint8_t vdev_id; + uint8_t is_connected; + int8_t rssi; + uint8_t ssid_len; + uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; + uint32_t vdev_mode; + uint32_t freq; + uint32_t numChannels; + uint8_t channel_list[WLAN_SVC_MAX_NUM_CHAN]; + uint8_t ssid[WLAN_SVC_MAX_SSID_LEN]; + uint8_t bssid[WLAN_SVC_MAX_BSSID_LEN]; +}; + +struct wlan_version_data { + uint32_t chip_id; + char chip_name[WLAN_SVC_MAX_STR_LEN]; + char chip_from[WLAN_SVC_MAX_STR_LEN]; + char host_version[WLAN_SVC_MAX_STR_LEN]; + char fw_version[WLAN_SVC_MAX_STR_LEN]; +}; + +struct wlan_dfs_info { + uint16_t channel; + uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; +}; + +#endif //WLAN_NLINK_COMMON_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_btc_svc.h b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_btc_svc.h new file mode 100644 index 0000000000000..7eee2dec25274 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_btc_svc.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_btc_svc.h + * + ******************************************************************************/ + +#ifndef WLAN_BTC_SVC_H +#define WLAN_BTC_SVC_H + +void send_btc_nlink_msg (int type, int dest_pid); +int btc_activate_service(void *pAdapter); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_logging_sock_svc.h b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_logging_sock_svc.h new file mode 100644 index 0000000000000..71b2386d33742 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_logging_sock_svc.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_logging_sock_svc.h + * + ******************************************************************************/ + +#ifndef WLAN_LOGGING_SOCK_SVC_H +#define WLAN_LOGGING_SOCK_SVC_H + +#include +#include +#include +#include +#include + +int wlan_logging_sock_init_svc(void); +int wlan_logging_sock_deinit_svc(void); +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf); +int wlan_logging_sock_deactivate_svc(void); +int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length); + +#endif /* WLAN_LOGGING_SOCK_SVC_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_nlink_srv.h b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_nlink_srv.h new file mode 100644 index 0000000000000..e48e936fa6299 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_nlink_srv.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_nlink_srv.h + * + * wlan_nlink_srv is used to RX/TX Netlink messages from user space to kernel + * modules and vice versa. Kernel modules must register a message handler for a + * message type so that the wlan_nlink_srv can invoke the corresponding msg handler + * whenever a Netlink message of a particular type has been received from an + * application. In the opposite direction, wlan_nlink_srv provides a mechanism + * which kernel modules can use to send Netlink messages to applications. + * + ******************************************************************************/ + +#ifndef WLAN_NLINK_SRV_H +#define WLAN_NLINK_SRV_H + +#include +#include +#include + +#define INVALID_PID -1 +#define NLINK_MAX_CALLBACKS (WLAN_NL_MSG_MAX - WLAN_NL_MSG_BASE) + +typedef int (* nl_srv_msg_callback)(struct sk_buff * skb); + +int nl_srv_init(void); +#ifdef WLAN_KD_READY_NOTIFIER +void nl_srv_exit(int dst_pid); +#else +void nl_srv_exit(void); +#endif /* WLAN_KD_READY_NOTIFIER */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); +int nl_srv_ucast(struct sk_buff * skb, int dst_pid, int flag); +int nl_srv_bcast(struct sk_buff * skb); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_ptt_sock_svc.h b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_ptt_sock_svc.h new file mode 100644 index 0000000000000..d14307244d510 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/inc/wlan_ptt_sock_svc.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_ptt_sock_svc.c + * + ******************************************************************************/ +#ifndef PTT_SOCK_SVC_H +#define PTT_SOCK_SVC_H +#include +#include +#include +#include +#include +#include +/* + * Quarky Message Format: + * The following is the messaging protocol between Quarky and PTT Socket App. + * The totalMsgLen is the length from Radio till msgBody. The value of Radio + * is always defaulted to 0. The MsgLen is the length from msgId till msgBody. + * The length of the msgBody varies with respect to the MsgId. Buffer space + * for MsgBody is already allocated in the received buffer. So in case of READ + * we just need to populate the values in the received message and send it + * back + * +------------+-------+-------+--------+-------+---------+ + * |TotalMsgLen | Radio | MsgId | MsgLen |Status |MsgBody | + * +------------+-------+-------|--------+-------+---------+ + * <------4----><--4---><---2--><---2---><---4--><---------> + */ +// PTT Socket App Message Ids +#define PTT_MSG_READ_REGISTER 0x3040 +#define PTT_MSG_WRITE_REGISTER 0x3041 +#define PTT_MSG_READ_MEMORY 0x3044 +#define PTT_MSG_WRITE_MEMORY 0x3045 +#define PTT_MSG_LOG_DUMP_DBG 0x32A1 +#define PTT_MSG_FTM_CMDS_TYPE 0x4040 +#define ANI_DRIVER_MSG_START 0x0001 +#define ANI_MSG_APP_REG_REQ (ANI_DRIVER_MSG_START + 0) +#define ANI_MSG_APP_REG_RSP (ANI_DRIVER_MSG_START + 1) +#define ANI_MSG_OEM_DATA_REQ (ANI_DRIVER_MSG_START + 2) +#define ANI_MSG_OEM_DATA_RSP (ANI_DRIVER_MSG_START + 3) +#define ANI_MSG_CHANNEL_INFO_REQ (ANI_DRIVER_MSG_START + 4) +#define ANI_MSG_CHANNEL_INFO_RSP (ANI_DRIVER_MSG_START + 5) +#define ANI_MSG_OEM_ERROR (ANI_DRIVER_MSG_START + 6) +#define ANI_MSG_PEER_STATUS_IND (ANI_DRIVER_MSG_START + 7) + +#define ANI_MAX_RADIOS 3 +#define ANI_NL_MSG_OK 0 +#define ANI_NL_MSG_ERROR -1 +#define ANI_NL_MSG_OVERHEAD (NLMSG_SPACE(tAniHdr + 4)) +/* + * Packet Format for READ_REGISTER & WRITE_REGISTER: + * TotalMsgLen : 4 bytes [value=20 bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Payload : 4 bytes +*/ +/* + * Packet Format for READ_MEMORY & WRITE_MEMORY : + * TotalMsgLen : 4 bytes [value= 20+LEN_PAYLOAD bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Length : 4 bytes [LEN_PAYLOAD] + * Payload : LEN_PAYLOAD bytes +*/ +int ptt_sock_activate_svc(void *pAdapter); +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid); + +/* + * Format of message exchanged between the PTT Socket App in userspace and the + * WLAN Driver, in either direction. Each msg will begin with this header and + * will followed by the Quarky message + */ +typedef struct sAniNlMsg { + struct nlmsghdr nlh; // Netlink Header + int radio; // unit number of the radio + tAniHdr wmsg; // Airgo Message Header +} tAniNlHdr; +typedef struct sAniAppRegReq { + tAniNlModTypes type; // module id + int pid; // process id +} tAniNlAppRegReq; +typedef struct sAniNlAppRegRsp { + struct nlmsghdr nlh; // NetLink Msg Header + int radio; // Radio unit + tAniHdr wniHdr; // Generic WNI msg header + tAniNlAppRegReq regReq; // The original request msg + int ret; // Return code +} tAniNlAppRegRsp; +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/src/btc/wlan_btc_svc.c b/drivers/staging/qcacld-2.0/CORE/SVC/src/btc/wlan_btc_svc.c new file mode 100644 index 0000000000000..7d4aeaf7538f8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/src/btc/wlan_btc_svc.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/****************************************************************************** + * wlan_btc_svc.c + * + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +// Global variables +static struct hdd_context_s *pHddCtx; + +static int gWiFiChannel; /* WiFi associated channel 1-13, or 0 (none) */ +static int gAmpChannel; /* AMP associated channel 1-13, or 0 (none) */ +static int gBtcDriverMode = WLAN_HDD_INFRA_STATION; /* Driver mode in BTC */ + + +// Forward declrarion +static int btc_msg_callback (struct sk_buff * skb); +/* + * Send a netlink message to the user space. + * Destination pid as zero implies broadcast + */ +void send_btc_nlink_msg (int type, int dest_pid) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tWlanAssocData *assocData; + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if(skb == NULL) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: alloc_skb failed\n"); + return; + } + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_BTC; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = type; + + /* Set BTC driver mode correctly based on received events type */ + if(type == WLAN_BTC_SOFTAP_BSS_START) + { + /* Event is SoftAP BSS Start set BTC driver mode to SoftAP */ + gBtcDriverMode = WLAN_HDD_SOFTAP; + } + if(type == WLAN_STA_ASSOC_DONE_IND) + { + /* Event is STA Assoc done set BTC driver mode to INFRA STA*/ + gBtcDriverMode = WLAN_HDD_INFRA_STATION; + } + + switch( type ) + { + case WLAN_STA_DISASSOC_DONE_IND: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "WiFi unassociated; gAmpChannel %d gWiFiChannel %d", gAmpChannel, gWiFiChannel); + + /* If AMP is using a channel (non-zero), no message sent. + Or, if WiFi wasn't using a channel before, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the WiFi channel in use (none) */ + if((gAmpChannel != 0) || (gWiFiChannel == 0)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gWiFiChannel = 0; + kfree_skb(skb); + return; + } + gWiFiChannel = 0; + + /* No Break: Fall into next cases */ + + case WLAN_MODULE_UP_IND: + case WLAN_MODULE_DOWN_IND: + aniHdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + break; + case WLAN_BTC_SOFTAP_BSS_START: + case WLAN_BTC_QUERY_STATE_RSP: + case WLAN_STA_ASSOC_DONE_IND: + aniHdr->length = sizeof(tWlanAssocData); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + sizeof(tWlanAssocData))); + assocData = ( tWlanAssocData *)((char*)aniHdr + sizeof(tAniMsgHdr)); + + assocData->channel = hdd_get_operating_channel( pHddCtx, gBtcDriverMode ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "New WiFi channel %d gAmpChannel %d gWiFiChannel %d", + assocData->channel, gAmpChannel, gWiFiChannel); + + /* If WiFi has finished associating */ + if(type == WLAN_STA_ASSOC_DONE_IND) + { + /* If AMP is using a channel (non-zero), no message sent. + Or, if the WiFi channel did not change, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the WiFi channel in use (1-13 or none, in assocData->channel) */ + if((gAmpChannel != 0) || (assocData->channel == gWiFiChannel)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gWiFiChannel = assocData->channel; + kfree_skb(skb); + return; + } + } + if(type == WLAN_BTC_SOFTAP_BSS_START) + { + /*Replace WLAN_BTC_SOFTAP_BSS_START by WLAN_STA_ASSOC_DONE_IND*/ + aniHdr->type = WLAN_STA_ASSOC_DONE_IND; + } + gWiFiChannel = assocData->channel; + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr)+ sizeof(tWlanAssocData)))); + break; + + case WLAN_AMP_ASSOC_DONE_IND: + + /* This is an overloaded type. It means that AMP is connected (dest_pid is channel 1-13), + or it means AMP is now disconnected (dest_pid is 0) */ + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "New AMP channel %d gAmpChannel %d gWiFiChannel %d", dest_pid, gAmpChannel, gWiFiChannel); + /* If WiFi is using a channel (non-zero), no message sent. + Or, if the AMP channel did not change, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the AMP channel in use (1-13 or none, in dest_pid) */ + if((gWiFiChannel != 0) || (dest_pid == gAmpChannel)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gAmpChannel = dest_pid; + kfree_skb(skb); + return; + } + + gAmpChannel = dest_pid; + + /* Fix overloaded parameters and finish message formatting */ + if(dest_pid != 0) + { + aniHdr->type = WLAN_STA_ASSOC_DONE_IND; + aniHdr->length = sizeof(tWlanAssocData); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + sizeof(tWlanAssocData))); + assocData = ( tWlanAssocData *)((char*)aniHdr + sizeof(tAniMsgHdr)); + assocData->channel = dest_pid; + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr)+ sizeof(tWlanAssocData)))); + } + else + { + aniHdr->type = WLAN_STA_DISASSOC_DONE_IND; + aniHdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + } + dest_pid = 0; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Attempt to send unknown nlink message %d\n", type); + kfree_skb(skb); + return; + } + if(dest_pid == 0) + (void)nl_srv_bcast(skb); + else + (void)nl_srv_ucast(skb, dest_pid, MSG_DONTWAIT); +} +/* + * Activate BTC handler. This will register a handler to receive + * netlink messages addressed to WLAN_NL_MSG_BTC from user space + */ +int btc_activate_service(void *pAdapter) +{ + pHddCtx = (struct hdd_context_s*)pAdapter; + + //Register the msg handler for msgs addressed to ANI_NL_MSG_BTC + nl_srv_register(WLAN_NL_MSG_BTC, btc_msg_callback); + return 0; +} +/* + * Callback function invoked by Netlink service for all netlink + * messages (from user space) addressed to WLAN_NL_MSG_BTC + */ +int btc_msg_callback (struct sk_buff * skb) +{ + struct nlmsghdr *nlh; + tAniMsgHdr *msg_hdr; + tSmeBtEvent *btEvent = NULL; + nlh = (struct nlmsghdr *)skb->data; + msg_hdr = NLMSG_DATA(nlh); + + /* Continue with parsing payload. */ + switch(msg_hdr->type) + { + case WLAN_BTC_QUERY_STATE_REQ: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "BTC: Received probe from BTC Service\n"); + send_btc_nlink_msg(WLAN_BTC_QUERY_STATE_RSP, nlh->nlmsg_pid); + break; + case WLAN_BTC_BT_EVENT_IND: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "BTC: Received Bluetooth event indication\n"); + if(msg_hdr->length != sizeof(tSmeBtEvent)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Size mismatch in BT event data\n"); + break; + } + btEvent = (tSmeBtEvent*)((char*)msg_hdr + sizeof(tAniMsgHdr)); + (void)sme_BtcSignalBtEvent(pHddCtx->hHal, btEvent); + break; + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Received Invalid Msg type [%d]\n", msg_hdr->type); + break; + } + return 0; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/drivers/staging/qcacld-2.0/CORE/SVC/src/logging/wlan_logging_sock_svc.c new file mode 100644 index 0000000000000..8183c6326ce00 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/src/logging/wlan_logging_sock_svc.c @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_logging_sock_svc.c + * + ******************************************************************************/ + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOGGING_TRACE(level, args...) \ + VOS_TRACE(VOS_MODULE_ID_HDD, level, ## args) + +/* Global variables */ + +#define ANI_NL_MSG_LOG_TYPE 89 +#define ANI_NL_MSG_READY_IND_TYPE 90 +#define MAX_LOGMSG_LENGTH 4096 + +struct log_msg { + struct list_head node; + unsigned int radio; + unsigned int index; + /* indicates the current filled log length in logbuf */ + unsigned int filled_length; + /* + * Buf to hold the log msg + * tAniHdr + log + */ + char logbuf[MAX_LOGMSG_LENGTH]; +}; + +struct wlan_logging { + /* Log Fatal and ERROR to console */ + bool log_fe_to_console; + /* Number of buffers to be used for logging */ + int num_buf; + /* Lock to synchronize access to shared logging resource */ + spinlock_t spin_lock; + /* Holds the free node which can be used for filling logs */ + struct list_head free_list; + /* Holds the filled nodes which needs to be indicated to APP */ + struct list_head filled_list; + /* Wait queue for Logger thread */ + wait_queue_head_t wait_queue; + /* Logger thread */ + struct task_struct *thread; + /* Logging thread sets this variable on exit */ + struct completion shutdown_comp; + /* Indicates to logger thread to exit */ + bool exit; + /* Holds number of dropped logs*/ + unsigned int drop_count; + /* current logbuf to which the log will be filled to */ + struct log_msg *pcur_node; + bool is_buffer_free; +}; + +static struct wlan_logging gwlan_logging; +static struct log_msg *gplog_msg; + +/* PID of the APP to log the message */ +static int gapp_pid = INVALID_PID; + +/* Utility function to send a netlink message to an application + * in user space + */ +static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, + int src_mod, int pid) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl = NULL; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = be16_to_cpu(wmsg->length); + static int nlmsg_seq; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "%s: invalid radio id [%d]", + __func__, radio); + return -EINVAL; + } + + payload_len = wmsg_length + sizeof(wnl->radio); + tot_msg_len = NLMSG_SPACE(payload_len); + skb = dev_alloc_skb(tot_msg_len); + if (skb == NULL) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "%s: dev_alloc_skb() failed for msg size[%d]", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "%s: nlmsg_put() failed for msg size[%d]", + __func__, tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + memcpy(&wnl->wmsg, wmsg, wmsg_length); + LOGGING_TRACE(VOS_TRACE_LEVEL_INFO, + "%s: Sending Msg Type [0x%X] to pid[%d]\n", + __func__, be16_to_cpu(wmsg->type), pid); + + err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); + return err; +} + +static void set_default_logtoapp_log_level(void) +{ + vos_trace_setValue(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ALL, + VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ALL, VOS_TRUE); +} + +static void clear_default_logtoapp_log_level(void) +{ + int module; + + for (module = 0; module < VOS_MODULE_ID_MAX; module++) { + vos_trace_setValue(module, VOS_TRACE_LEVEL_NONE, + VOS_FALSE); + vos_trace_setValue(module, VOS_TRACE_LEVEL_FATAL, + VOS_TRUE); + vos_trace_setValue(module, VOS_TRACE_LEVEL_ERROR, + VOS_TRUE); + } + + vos_trace_setValue(VOS_MODULE_ID_RSV3, VOS_TRACE_LEVEL_NONE, + VOS_FALSE); + vos_trace_setValue(VOS_MODULE_ID_RSV4, VOS_TRACE_LEVEL_NONE, + VOS_FALSE); +} + +/* Need to call this with spin_lock acquired */ +static int wlan_queue_logmsg_for_app(void) +{ + char *ptr; + int ret = 0; + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + ptr[gwlan_logging.pcur_node->filled_length] = '\0'; + + *(unsigned short *)(gwlan_logging.pcur_node->logbuf) = + ANI_NL_MSG_LOG_TYPE; + *(unsigned short *)(gwlan_logging.pcur_node->logbuf + 2) = + gwlan_logging.pcur_node->filled_length; + list_add_tail(&gwlan_logging.pcur_node->node, + &gwlan_logging.filled_list); + + if (!list_empty(&gwlan_logging.free_list)) { + /* Get buffer from free list */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + /* reset when free list is available. */ + gwlan_logging.is_buffer_free = FALSE; + } else if (!list_empty(&gwlan_logging.filled_list)) { + /* Get buffer from filled list */ + /* This condition will drop the packet from being + * indicated to app + */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.filled_list.next); + ++gwlan_logging.drop_count; + if (gapp_pid != INVALID_PID && !gwlan_logging.is_buffer_free) { + pr_info("%s: drop_count = %u index = %d filled_length = %d\n", + __func__, gwlan_logging.drop_count, + gwlan_logging.pcur_node->index, + gwlan_logging.pcur_node->filled_length); + /* print above logs only 1st time. */ + gwlan_logging.is_buffer_free = TRUE; + } + list_del_init(gwlan_logging.filled_list.next); + ret = 1; + } + + /* Reset the current node values */ + gwlan_logging.pcur_node->filled_length = 0; + return ret; +} + + +int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) +{ + /* Add the current time stamp */ + char *ptr; + char tbuf[50]; + int tlen; + int total_log_len; + unsigned int *pfilled_length; + bool wake_up_thread = false; + unsigned long flags; + u_int64_t ts; + + if (gapp_pid == INVALID_PID) { + /* + * This is to make sure that we print the logs to kmsg console + * when no logger app is running. This is also needed to + * log the initial messages during loading of driver where even + * if app is running it will not be able to + * register with driver immediately and start logging all the + * messages. + */ + pr_info("%s\n", to_be_sent); + } + + /* Format the Log time [Seconds.microseconds] */ + ts = adf_get_boottime(); + tlen = snprintf(tbuf, sizeof(tbuf), "[%s][%lu.%06lu] ", current->comm, + (unsigned long) (ts / VOS_TIMER_TO_SEC_UNIT), + (unsigned long) (ts % VOS_TIMER_TO_SEC_UNIT)); + + /* 1+1 indicate '\n'+'\0' */ + total_log_len = length + tlen + 1 + 1; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + // wlan logging svc resources are not yet initialized + if (!gwlan_logging.pcur_node) { + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + return -EIO; + } + + pfilled_length = &gwlan_logging.pcur_node->filled_length; + + /* Check if we can accomodate more log into current node/buffer */ + if ((MAX_LOGMSG_LENGTH - (*pfilled_length + sizeof(tAniNlHdr))) < + total_log_len) { + wake_up_thread = true; + wlan_queue_logmsg_for_app(); + pfilled_length = &gwlan_logging.pcur_node->filled_length; + } + + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + + /* Assumption here is that we receive logs which is always less than + * MAX_LOGMSG_LENGTH, where we can accomodate the + * tAniNlHdr + [context][timestamp] + log + * VOS_ASSERT if we cannot accomodate the the complete log into + * the available buffer. + * + * Continue and copy logs to the available length and discard the rest. + */ + if (MAX_LOGMSG_LENGTH < (sizeof(tAniNlHdr) + total_log_len)) { + VOS_ASSERT(0); + total_log_len = MAX_LOGMSG_LENGTH - sizeof(tAniNlHdr) - 2; + } + + memcpy(&ptr[*pfilled_length], tbuf, tlen); + memcpy(&ptr[*pfilled_length + tlen], to_be_sent, + min(length, (total_log_len - tlen))); + *pfilled_length += tlen + min(length, total_log_len - tlen); + ptr[*pfilled_length] = '\n'; + *pfilled_length += 1; + + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + /* Wakeup logger thread */ + if ((true == wake_up_thread)) { + /* If there is logger app registered wakeup the logging + * thread + */ + if (gapp_pid != INVALID_PID) + wake_up_interruptible(&gwlan_logging.wait_queue); + } + + if ((gapp_pid != INVALID_PID) + && gwlan_logging.log_fe_to_console + && ((VOS_TRACE_LEVEL_FATAL == log_level) + || (VOS_TRACE_LEVEL_ERROR == log_level))) { + pr_info("%s\n", to_be_sent); + } + + return 0; +} + +static int send_filled_buffers_to_user(void) +{ + int ret = -1; + struct log_msg *plog_msg; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + static int nlmsg_seq; + unsigned long flags; + static int rate_limit; + + while (!list_empty(&gwlan_logging.filled_list) + && !gwlan_logging.exit) { + + skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); + if (skb == NULL) { + if (!rate_limit) { + pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); + } + rate_limit = 1; + ret = -ENOMEM; + break; + } + rate_limit = 0; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + + plog_msg = (struct log_msg *) + (gwlan_logging.filled_list.next); + list_del_init(gwlan_logging.filled_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + /* 4 extra bytes for the radio idx */ + payload_len = plog_msg->filled_length + + sizeof(wnl->radio) + sizeof(tAniHdr); + + tot_msg_len = NLMSG_SPACE(payload_len); + nlh = nlmsg_put(skb, gapp_pid, nlmsg_seq++, + ANI_NL_MSG_LOG, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, + &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, + flags); + pr_err("%s: drop_count = %u\n", __func__, + ++gwlan_logging.drop_count); + pr_err("%s: nlmsg_put() failed for msg size[%d]\n", + __func__, tot_msg_len); + dev_kfree_skb(skb); + skb = NULL; + ret = -EINVAL; + continue; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = plog_msg->radio; + memcpy(&wnl->wmsg, plog_msg->logbuf, + plog_msg->filled_length + + sizeof(tAniHdr)); + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, + &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + ret = nl_srv_ucast(skb, gapp_pid, 0); + if (ret < 0) { + pr_err("%s: Send Failed %d drop_count = %u\n", + __func__, ret, ++gwlan_logging.drop_count); + skb = NULL; + gapp_pid = INVALID_PID; + clear_default_logtoapp_log_level(); + } else { + skb = NULL; + ret = 0; + } + } + + return ret; +} + +/** + * wlan_logging_thread() - The WLAN Logger thread + * @Arg - pointer to the HDD context + * + * This thread logs log message to App registered for the logs. + */ +static int wlan_logging_thread(void *Arg) +{ + int ret_wait_status = 0; + int ret = 0; + + set_user_nice(current, -2); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) + daemonize("wlan_logging_thread"); +#endif + + while (!gwlan_logging.exit) { + ret_wait_status = wait_event_interruptible( + gwlan_logging.wait_queue, + (!list_empty(&gwlan_logging.filled_list) + || gwlan_logging.exit)); + + if (ret_wait_status == -ERESTARTSYS) { + pr_err("%s: wait_event_interruptible returned -ERESTARTSYS", + __func__); + break; + } + + if (gwlan_logging.exit) { + pr_err("%s: Exiting the thread\n", __func__); + break; + } + + ret = send_filled_buffers_to_user(); + if (-ENOMEM == ret) { + msleep(200); + } + } + + pr_info("%s: Terminating\n", __func__); + + complete_and_exit(&gwlan_logging.shutdown_comp, 0); + + return 0; +} + +/* + * Process all the Netlink messages from Logger Socket app in user space + */ +static int wlan_logging_proc_sock_rx_msg(struct sk_buff *skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + int ret; + + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "%s: invalid radio id [%d]\n", + __func__, radio); + return -EINVAL; + } + + if (gapp_pid != INVALID_PID) { + if (wnl->nlh.nlmsg_pid > gapp_pid) { + gapp_pid = wnl->nlh.nlmsg_pid; + } + + spin_lock_bh(&gwlan_logging.spin_lock); + if (gwlan_logging.pcur_node->filled_length) { + wlan_queue_logmsg_for_app(); + } + spin_unlock_bh(&gwlan_logging.spin_lock); + wake_up_interruptible(&gwlan_logging.wait_queue); + } else { + /* This is to set the default levels (WLAN logging + * default values not the VOS trace default) when + * logger app is registered for the first time. + */ + gapp_pid = wnl->nlh.nlmsg_pid; + set_default_logtoapp_log_level(); + } + + ret = wlan_send_sock_msg_to_app(&wnl->wmsg, 0, + ANI_NL_MSG_LOG, wnl->nlh.nlmsg_pid); + if (ret < 0) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "wlan_send_sock_msg_to_app: failed"); + } + + return ret; +} + +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf) +{ + int i = 0; + unsigned long irq_flag; + + pr_info("%s: Initalizing FEConsoleLog = %d NumBuff = %d\n", + __func__, log_fe_to_console, num_buf); + + gapp_pid = INVALID_PID; + + gplog_msg = (struct log_msg *) vmalloc( + num_buf * sizeof(struct log_msg)); + if (!gplog_msg) { + pr_err("%s: Could not allocate memory\n", __func__); + return -ENOMEM; + } + + vos_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg))); + + gwlan_logging.log_fe_to_console = !!log_fe_to_console; + gwlan_logging.num_buf = num_buf; + + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + INIT_LIST_HEAD(&gwlan_logging.free_list); + INIT_LIST_HEAD(&gwlan_logging.filled_list); + + for (i = 0; i < num_buf; i++) { + list_add(&gplog_msg[i].node, &gwlan_logging.free_list); + gplog_msg[i].index = i; + } + gwlan_logging.pcur_node = (struct log_msg *) + (gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + + init_waitqueue_head(&gwlan_logging.wait_queue); + gwlan_logging.exit = false; + init_completion(&gwlan_logging.shutdown_comp); + gwlan_logging.thread = kthread_create(wlan_logging_thread, NULL, + "wlan_logging_thread"); + if (IS_ERR(gwlan_logging.thread)) { + pr_err("%s: Could not Create LogMsg Thread Controller", + __func__); + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + vfree(gplog_msg); + gplog_msg = NULL; + gwlan_logging.pcur_node = NULL; + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + return -ENOMEM; + } + wake_up_process(gwlan_logging.thread); + + nl_srv_register(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); + + pr_info("%s: Activated wlan_logging svc\n", __func__); + return 0; +} + +int wlan_logging_sock_deactivate_svc(void) +{ + unsigned long irq_flag; + + if (!gplog_msg) + return 0; + + nl_srv_unregister(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); + clear_default_logtoapp_log_level(); + gapp_pid = INVALID_PID; + + INIT_COMPLETION(gwlan_logging.shutdown_comp); + gwlan_logging.exit = true; + wake_up_interruptible(&gwlan_logging.wait_queue); + wait_for_completion(&gwlan_logging.shutdown_comp); + + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + vfree(gplog_msg); + gwlan_logging.pcur_node = NULL; + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + + pr_info("%s: Deactivate wlan_logging svc\n", __func__); + + return 0; +} + +int wlan_logging_sock_init_svc(void) +{ + spin_lock_init(&gwlan_logging.spin_lock); + gapp_pid = INVALID_PID; + gwlan_logging.pcur_node = NULL; + + return 0; +} + +int wlan_logging_sock_deinit_svc(void) +{ + gwlan_logging.pcur_node = NULL; + gapp_pid = INVALID_PID; + + return 0; +} +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/src/nlink/wlan_nlink_srv.c b/drivers/staging/qcacld-2.0/CORE/SVC/src/nlink/wlan_nlink_srv.c new file mode 100644 index 0000000000000..d212aeaaa3395 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/src/nlink/wlan_nlink_srv.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_nlink_srv.c +* +* This file contains the definitions specific to the wlan_nlink_srv +* +******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Global variables */ +static DEFINE_MUTEX(nl_srv_sem); +static struct sock *nl_srv_sock; +static nl_srv_msg_callback nl_srv_msg_handler[NLINK_MAX_CALLBACKS]; + +/* Forward declaration */ +static void nl_srv_rcv (struct sk_buff *sk); +static void nl_srv_rcv_skb (struct sk_buff *skb); +static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh); + +/* + * Initialize the netlink service. + * Netlink service is usable after this. + */ +int nl_srv_init(void) +{ + int retcode = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct netlink_kernel_cfg cfg = { + .groups = WLAN_NLINK_MCAST_GRP_ID, + .input = nl_srv_rcv + }; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + THIS_MODULE, +#endif + &cfg); +#else + nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, + WLAN_NLINK_MCAST_GRP_ID, nl_srv_rcv, NULL, THIS_MODULE); +#endif + + if (nl_srv_sock != NULL) { + memset(nl_srv_msg_handler, 0, sizeof(nl_srv_msg_handler)); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLINK: netlink_kernel_create failed"); + retcode = -ECONNREFUSED; + } + return retcode; +} + +/* + * Deinit the netlink service. + * Netlink service is unusable after this. + */ +#ifdef WLAN_KD_READY_NOTIFIER +void nl_srv_exit(int dst_pid) +#else +void nl_srv_exit(void) +#endif /* WLAN_KD_READY_NOTIFIER */ +{ + netlink_kernel_release(nl_srv_sock); +} + +/* + * Register a message handler for a specified module. + * Each module (e.g. WLAN_NL_MSG_BTC )will register a + * handler to handle messages addressed to it. + */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + msg_handler != NULL) + { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = msg_handler; + } + else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: nl_srv_register failed for msg_type %d", msg_type); + retcode = -EINVAL; + } + + return retcode; +} +/* + * Unregister the message handler for a specified module. + */ +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + (nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] == msg_handler)) + { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = NULL; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: nl_srv_unregister failed for msg_type %d", msg_type); + retcode = -EINVAL; + } + + return retcode; +} + +/* + * Unicast the message to the process in user space identfied + * by the dst-pid + */ +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag) +{ + int err; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + NETLINK_CB(skb).pid = 0; //sender's pid +#else + NETLINK_CB(skb).portid = 0; //sender's pid +#endif + NETLINK_CB(skb).dst_group = 0; //not multicast + + err = netlink_unicast(nl_srv_sock, skb, dst_pid, flag); + + if (err < 0) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: netlink_unicast to pid[%d] failed, ret[0x%X]", dst_pid, err); + + return err; +} + +/* + * Broadcast the message. Broadcast will return an error if + * there are no listeners + */ +int nl_srv_bcast(struct sk_buff *skb) +{ + int err; + int flags = GFP_KERNEL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + NETLINK_CB(skb).pid = 0; //sender's pid +#else + NETLINK_CB(skb).portid = 0; //sender's pid +#endif + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; //destination group + + err = netlink_broadcast(nl_srv_sock, skb, 0, WLAN_NLINK_MCAST_GRP_ID, flags); + + if (err < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: netlink_broadcast failed err = %d", err); + } + return err; +} + +/* + * Processes the Netlink socket input queue. + * Dequeue skb's from the socket input queue and process + * all the netlink messages in that skb, before moving + * to the next skb. + */ +static void nl_srv_rcv (struct sk_buff *sk) +{ + mutex_lock(&nl_srv_sem); + nl_srv_rcv_skb(sk); + mutex_unlock(&nl_srv_sem); +} + +/* + * Each skb could contain multiple Netlink messages. Process all the + * messages in one skb and discard malformed skb's silently. + */ +static void nl_srv_rcv_skb (struct sk_buff *skb) +{ + struct nlmsghdr * nlh; + + while (skb->len >= NLMSG_SPACE(0)) { + u32 rlen; + + nlh = (struct nlmsghdr *)skb->data; + + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "NLINK: Invalid " + "Netlink message: skb[%p], len[%d], nlhdr[%p], nlmsg_len[%d]", + skb, skb->len, nlh, nlh->nlmsg_len); + return; + } + + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + nl_srv_rcv_msg(skb, nlh); + skb_pull(skb, rlen); + } +} + +/* + * Process a netlink message. + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh) +{ + int type; + + /* Only requests are handled by kernel now */ + if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Req type [%x]", nlh->nlmsg_flags); + return; + } + + type = nlh->nlmsg_type; + + /* Unknown message */ + if (type < WLAN_NL_MSG_BASE || type >= WLAN_NL_MSG_MAX) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Msg type [%x]", type); + return; + } + + /* + * All the messages must at least carry the tAniMsgHdr + * Drop any message with invalid length + */ + if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr))) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received NL Msg with invalid len[%x]", nlh->nlmsg_len); + return; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "NLINK: Received NL msg type [%d]", type); + + // turn type into dispatch table offset + type -= WLAN_NL_MSG_BASE; + + // dispatch to handler + if (nl_srv_msg_handler[type] != NULL) { + (nl_srv_msg_handler[type])(skb); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: No handler for Netlink Msg [0x%X]", type); + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c b/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c new file mode 100644 index 0000000000000..2264d348786b7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_ptt_sock_svc.c + * + ******************************************************************************/ +#ifdef PTT_SOCK_SVC_ENABLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTT_SOCK_DEBUG +#ifdef PTT_SOCK_DEBUG +#define PTT_TRACE(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args) +#else +#define PTT_TRACE(level, args...) +#endif +// Global variables +static struct hdd_context_s *pAdapterHandle; + +#ifdef PTT_SOCK_DEBUG_VERBOSE +//Utility function to perform a hex dump +static void ptt_sock_dump_buf(const unsigned char * pbuf, int cnt) +{ + int i; + for (i = 0; i < cnt ; i++) { + if ((i%16)==0) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n%p:", pbuf); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", *pbuf); + pbuf++; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n"); +} +#endif +//Utility function to send a netlink message to an application in user space +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = be16_to_cpu(wmsg->length); + static int nlmsg_seq; + if (radio < 0 || radio > ANI_MAX_RADIOS) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]\n", + __func__, radio); + return -EINVAL; + } + payload_len = wmsg_length + 4; // 4 extra bytes for the radio idx + tot_msg_len = NLMSG_SPACE(payload_len); + if ((skb = dev_alloc_skb(tot_msg_len)) == NULL) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: dev_alloc_skb() failed for msg size[%d]\n", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, NLM_F_REQUEST); + if (NULL == nlh) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]\n", + __func__, tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + memcpy(&wnl->wmsg, wmsg, wmsg_length); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Sending Msg Type [0x%X] to pid[%d]\n", + __func__, be16_to_cpu(wmsg->type), pid); +#ifdef PTT_SOCK_DEBUG_VERBOSE + ptt_sock_dump_buf((const unsigned char *)skb->data, skb->len); +#endif + err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); + return err; +} +/* + * Process tregisteration request and send registration response messages + * to the PTT Socket App in user space + */ +static void ptt_sock_proc_reg_req(tAniHdr *wmsg, int radio) +{ + tAniNlAppRegReq *reg_req; + tAniNlAppRegRsp rspmsg; + reg_req = (tAniNlAppRegReq *)(wmsg + 1); + memset((char *)&rspmsg, 0, sizeof(rspmsg)); + /* send reg response message to the application */ + rspmsg.ret = ANI_NL_MSG_OK; + rspmsg.regReq.type = reg_req->type; + + /* Save the pid */ + pAdapterHandle->ptt_pid = reg_req->pid; + rspmsg.regReq.pid= reg_req->pid; + rspmsg.wniHdr.type = cpu_to_be16(ANI_MSG_APP_REG_RSP); + rspmsg.wniHdr.length = cpu_to_be16(sizeof(rspmsg)); + if (ptt_sock_send_msg_to_app((tAniHdr *)&rspmsg.wniHdr, radio, + ANI_NL_MSG_PUMAC, reg_req->pid) < 0) + { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Error sending ANI_MSG_APP_REG_RSP to pid[%d]\n", + __func__, reg_req->pid); + } +} +/* + * Process all the messages from the PTT Socket App in user space + */ +static void ptt_proc_pumac_msg(struct sk_buff * skb, tAniHdr *wmsg, int radio) +{ + u16 ani_msg_type = be16_to_cpu(wmsg->type); + switch(ani_msg_type) + { + case ANI_MSG_APP_REG_REQ: + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_MSG_APP_REG_REQ [0x%X]\n", + __func__, ani_msg_type); + ptt_sock_proc_reg_req(wmsg, radio); + break; + default: + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Received Unknown Msg Type[0x%X]\n", + __func__, ani_msg_type); + break; + } +} +/* + * Process all the Netlink messages from PTT Socket app in user space + */ +static int ptt_sock_rx_nlink_msg (struct sk_buff * skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + switch (type) { + case ANI_NL_MSG_PUMAC: // Message from the PTT socket APP + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_NL_MSG_PUMAC Msg [0x%X]\n", + __func__, type); + ptt_proc_pumac_msg(skb, &wnl->wmsg, radio); + break; + default: + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Unknown NL Msg [0x%X]\n",__func__, type); + break; + } + return 0; +} +int ptt_sock_activate_svc(void *pAdapter) +{ + pAdapterHandle = (struct hdd_context_s*)pAdapter; + pAdapterHandle->ptt_pid = INVALID_PID; + nl_srv_register(ANI_NL_MSG_PUMAC, ptt_sock_rx_nlink_msg); + nl_srv_register(ANI_NL_MSG_PTT, ptt_sock_rx_nlink_msg); + return 0; +} +#endif // PTT_SOCK_SVC_ENABLE diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/common/inc/wlan_qct_sys.h b/drivers/staging/qcacld-2.0/CORE/SYS/common/inc/wlan_qct_sys.h new file mode 100644 index 0000000000000..24f8e9e7be88a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/common/inc/wlan_qct_sys.h @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_QCT_SYS_H__ ) +#define WLAN_QCT_SYS_H__ + +/**=========================================================================== + + \file wlan_qct_sys.h + + \brief System module API + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + + \brief sysResponseCback() - SYS async resonse callback + + This is a protype for the callback function that SYS makes to various + modules in the system. + + \param pUserData - user data that is passed to the Callback function + when it is invoked. + + \return Nothing + + \sa sysMcStart(), sysMcThreadProbe(), sysTxThreadProbe() + + --------------------------------------------------------------------------*/ +typedef v_VOID_t ( * sysResponseCback ) ( v_VOID_t *pUserData ); + + + +typedef enum +{ + SYS_MSG_ID_MC_START, + SYS_MSG_ID_MC_THR_PROBE, + SYS_MSG_ID_MC_TIMER, + + SYS_MSG_ID_TX_THR_PROBE, + SYS_MSG_ID_TX_TIMER, + + SYS_MSG_ID_RX_TIMER, + + SYS_MSG_ID_MC_STOP, + SYS_MSG_ID_FTM_RSP, + +} SYS_MSG_ID; + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief sysBuildMessageHeader() - Build / initialize a SYS message header + + This function will initialize the SYS message header with the message type + and any internal fields needed for a new SYS message. This function sets + all but the message body, which is up to the caller to setup based on the + specific message being built. + + \note There are internal / reserved items in a SYS message that must be + set correctly for the message to be recognized as a SYS message by + the SYS message handlers. It is important for every SYS message to + be setup / built / initialized through this function. + + \param sysMsgId - a valid message ID for a SYS message. See the + SYS_MSG_ID enum for all the valid SYS message IDs. + + \param pMsg - pointer to the message structure to be setup. + + \return + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysBuildMessageHeader( SYS_MSG_ID sysMsgId, vos_msg_t *pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysOpen() - Open (initialize) the SYS module. + + This function opens the SYS modules. All SYS resources are allocated + as a result of this open call. + + \param pVosContext - pointer to the VOS Context (from which all other + context entities can be derived). + + \return VOS_STATUS_SUCCESS - the SYS module is open. All resources needed + for operation of the SYS modules are allocated and initialized. + + VOS_STATUS_E_RESOURCES - the SYS module open failed because needed + system resources are not available. + + VOS_STATUS_E_FAILURE - the SYS module open failed due to some + unknown reason. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysOpen( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysMcStart() - start the system Main Controller thread. + + This function starts the SYS (Main Controller) module. Starting this + module triggers the CFG download to the 'legacy' MAC software. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed the 'start' funciton. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + + \todo: We have not 'status' on the callback. How do we notify the + callback that there is a failure ? + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysMcStart( v_CONTEXT_t pVosContext, sysResponseCback userCallback, + v_VOID_t *pUserData ); + + +/*---------------------------------------------------------------------------- + + \brief sysStop() - Stop the SYS module. + + This function stops the SYS module. + + \todo: What else do we need to do on sysStop()? + + \param pVosContext - pointer to the VOS Context + + \return VOS_STATUS_SUCCESS - the SYS module is stopped. + + VOS_STATUS_E_FAILURE - the SYS module open failed to stop. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysStop( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysClose() - Close the SYS module. + + This function closes the SYS module. All resources allocated during + sysOpen() are free'd and returned to the system. The Sys module is unable + to operate until opened again through a call to sysOpen(). + + \param pVosContext - pointer to the VOS Context + + \return VOS_STATUS_SUCCESS - the SYS module is closed. + + VOS_STATUS_E_FAILURE - the SYS module open failed to close + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +VOS_STATUS sysClose( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysMcThreadProbe() - Probe the SYS Main Controller thread + + This function is called during initialization to 'probe' the Main Controller + thread. Probing means a specific message is posted to the SYS module to + assure the Main Controller thread is operating and processing messages + correctly. + + Following the successful 'probe' of the Main Controller thread, the + callback specified on this function is called to notify another entity + that the Main Controller is operational. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed probing the Main Controller thread. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + \todo: how do we tell the callback there is a failure? + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +v_VOID_t sysMcThreadProbe( v_CONTEXT_t pVosContex, sysResponseCback userCallback, + v_VOID_t *pUserData ); + +/*---------------------------------------------------------------------------- + + \brief sysTxThreadProbe() - Probe the Tx thread + + This function is called during initialization to 'probe' the Tx + thread. Probing means a specific message is posted to the SYS module to + assure the Tx is operating and processing messages correctly. + + Following the successful 'probe' of the Tx, the callback specified + on this function is called to notify another entity that the Tx thread + is operational. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed probing the Tx thread. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + \todo: how do we tell the callback there is a failure? + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +v_VOID_t sysTxThreadProbe( v_CONTEXT_t pVosContex, sysResponseCback userCallback, + v_VOID_t *pUserData ); + +/*---------------------------------------------------------------------------- + + \brief sysMcProcessMsg() - process SYS messages on the Main Controller thread + + This function processes SYS Messages on the Main Controller thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxProcessMsg() - process SYS messages on the Tx thread + + This function processes SYS Messages on the Tx thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxProcessMsg() - process SYS messages on the Rx thread + + This function processes SYS Messages on the Rx thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysMcFreeMsg() - free a message queue'd to the Main Controller thread + + This fnction will free a SYS Message that is pending in the main controller + thread queue. These messages are free'd when the message queue needs to be + purged, for example during a Reset of Shutdown of the system. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - the message to be free'd + + \return Nothing. + + --------------------------------------------------------------------------*/ +v_VOID_t sysMcFreeMsg( v_CONTEXT_t pVosContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxFreeMsg() - free a message queue'd to the Tx thread + + This fnction will free a SYS Message that is pending in the Tx + thread queue. These messages are free'd when the message queue needs to be + purged, for example during a Reset of Shutdown of the system. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - the message to be free'd + + \return Nothing. + + --------------------------------------------------------------------------*/ +v_VOID_t sysTxFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief wlan_sys_ftm() - FTM Cmd Response from halPhy + + This fnction is called by halPhy and carried the FTM command response. + This message is handled by SYS thread and finally the message will be convyed to used space + + + \param pttMsgBuffer - pointer to the pttMsgBuffer + + + \return Nothing. + + --------------------------------------------------------------------------*/ + +void wlan_sys_ftm(void *pMsgPtr); +void wlan_sys_probe(void); + + +#endif // WLAN_QCT_SYS_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/common/src/wlan_qct_sys.c b/drivers/staging/qcacld-2.0/CORE/SYS/common/src/wlan_qct_sys.c new file mode 100644 index 0000000000000..875851737f485 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/common/src/wlan_qct_sys.c @@ -0,0 +1,774 @@ +/* + * Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N S Y S T E M M O D U L E + + +DESCRIPTION + This file contains the system module that implements the 'exectution model' + in the Gen6 host software. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ----------------------------------------------------- +12/15/08 sho Resolved AMSS compiler errors and warnings when this + is being ported from WM +07/02/08 lac Added support for eWNI_SME_START_REQ/RSP in init seq +06/26/08 hba Added implementation of mbReceiveMBMsg() +06/26/08 lac Created module. + +===========================================================================*/ + + +#include +#include + +#include // needed for tSirRetStatus +#include // needed for tSirMbMsg +#include // needed for SIR_... message types +#include // needed for WNI_... message types +#include "aniGlobal.h" +#include "wlan_qct_wda.h" +#include "sme_Api.h" +#include "macInitApi.h" + +VOS_STATUS WLANFTM_McProcessMsg (v_VOID_t *message); + + + +// Cookie for SYS messages. Note that anyone posting a SYS Message has to +// write the COOKIE in the reserved field of the message. The SYS Module +// relies on this COOKIE +#define FTM_SYS_MSG_COOKIE 0xFACE + +#define SYS_MSG_COOKIE ( 0xFACE ) + +/* SYS stop timeout 30 seconds */ +#define SYS_STOP_TIMEOUT (30000) + +// need to define FIELD_OFFSET for non-WM platforms +#ifndef FIELD_OFFSET +#define FIELD_OFFSET(x,y) offsetof(x,y) +#endif + +VOS_STATUS sys_SendSmeStartReq( v_CONTEXT_t pVosContext ); + +// add this to the sys Context data... ? +typedef struct +{ + sysResponseCback mcStartCB; + v_VOID_t * mcStartUserData; + +} sysContextData; + + +static vos_event_t gStopEvt; + +VOS_STATUS sysBuildMessageHeader( SYS_MSG_ID sysMsgId, vos_msg_t *pMsg ) +{ + pMsg->type = sysMsgId; + pMsg->reserved = SYS_MSG_COOKIE; + + return( VOS_STATUS_SUCCESS ); +} + + +VOS_STATUS sysOpen( v_CONTEXT_t pVosContext ) +{ + return( VOS_STATUS_SUCCESS ); +} + + + +v_VOID_t sysStopCompleteCb +( + v_VOID_t *pUserData +) +{ + vos_event_t* pStopEvt = (vos_event_t *) pUserData; + VOS_STATUS vosStatus; +/*-------------------------------------------------------------------------*/ + + vosStatus = vos_event_set( pStopEvt ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + +} /* vos_sys_stop_complete_cback() */ + +VOS_STATUS sysStop( v_CONTEXT_t pVosContext ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t sysMsg; + + /* Initialize the stop event */ + vosStatus = vos_event_init( &gStopEvt ); + + if(! VOS_IS_STATUS_SUCCESS( vosStatus )) + { + return vosStatus; + } + + /* post a message to SYS module in MC to stop SME and MAC */ + sysBuildMessageHeader( SYS_MSG_ID_MC_STOP, &sysMsg ); + + // Save the user callback and user data + // finished. + sysMsg.callback = sysStopCompleteCb; + sysMsg.bodyptr = (void *) &gStopEvt; + + // post the message.. + vosStatus = vos_mq_post_message( VOS_MQ_ID_SYS, &sysMsg ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vosStatus = VOS_STATUS_E_BADMSG; + } + + vosStatus = vos_wait_single_event(&gStopEvt, SYS_STOP_TIMEOUT); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + + vosStatus = vos_event_destroy( &gStopEvt ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + + return( vosStatus ); +} + + +VOS_STATUS sysClose( v_CONTEXT_t pVosContext ) +{ + return( VOS_STATUS_SUCCESS ); +} + + + + + + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( push ) +#pragma pack( 1 ) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack( 1 ) +#endif + +typedef struct sPolFileVersion +{ + unsigned char MajorVersion; + unsigned char MinorVersion; + unsigned char Suffix; + unsigned char Build; + +} tPolFileVersion; + + +typedef struct sPolFileHeader +{ + tPolFileVersion FileVersion; + tPolFileVersion HWCapabilities; + unsigned int FileLength; + unsigned int NumDirectoryEntries; + +} tPolFileHeader; + + +typedef enum ePolFileDirTypes +{ + ePOL_DIR_TYPE_BOOTLOADER = 0, + ePOL_DIR_TYPE_STA_FIRMWARE, + ePOL_DIR_TYPE_AP_FIRMWARE, + ePOL_DIR_TYPE_DIAG_FIRMWARE, + ePOL_DIR_TYPE_STA_CONFIG, + ePOL_DIR_TYPE_AP_CONFIG + +} tPolFileDirTypes; + + +typedef struct sPolFileDirEntry +{ + unsigned int DirEntryType; + unsigned int DirEntryFileOffset; + unsigned int DirEntryLength; + +} tPolFileDirEntry; + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( pop ) +#endif + + +static unsigned short polFileChkSum( unsigned short *FileData, unsigned long NumWords ) +{ + unsigned long Sum; + + for ( Sum = 0; NumWords > 0; NumWords-- ) + { + Sum += *FileData++; + } + + Sum = (Sum >> 16) + (Sum & 0xffff); // add carry + Sum += (Sum >> 16); // maybe last unsigned short + + return( (unsigned short)( ~Sum ) ); +} + +v_BOOL_t sys_validateStaConfig( void *pImage, unsigned long cbFile, + void **ppStaConfig, v_SIZE_t *pcbStaConfig ) +{ + v_BOOL_t fFound = VOS_FALSE; + tPolFileHeader *pFileHeader = NULL; + tPolFileDirEntry *pDirEntry = NULL; + v_U32_t idx; + + do + { + // Compute the checksum before bothering to copy... + if ( polFileChkSum( ( v_U16_t *)pImage, cbFile / sizeof( v_U16_t ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to validate the checksum for CFG binary" ); + break; + } + + pFileHeader = (tPolFileHeader *)pImage; + + *ppStaConfig = NULL; + *pcbStaConfig = 0; + + pDirEntry = ( tPolFileDirEntry* ) ( pFileHeader + 1 ); + + for ( idx = 0; idx < pFileHeader->NumDirectoryEntries; ++idx ) + { + if ( ePOL_DIR_TYPE_STA_CONFIG == pDirEntry[ idx ].DirEntryType ) + { + *ppStaConfig = pDirEntry[ idx ].DirEntryFileOffset + ( v_U8_t * )pFileHeader; + + *pcbStaConfig = pDirEntry[ idx ].DirEntryLength; + + break; + } + + } // End iteration over the header's entries + + if ( NULL != *ppStaConfig ) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_LOW, + "Found the Station CFG in the CFG binary!!" ); + + fFound = VOS_TRUE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to find Station CFG in the CFG binary" ); + } + + } while( 0 ); + + VOS_ASSERT( VOS_TRUE == fFound ); + + return( fFound ); +} + + + + + + + + + + +VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_VOID_t *hHal; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + case SYS_MSG_ID_MC_START: + { + /* Handling for this message is not needed now so adding + *debug print and VOS_ASSERT*/ + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + " Received SYS_MSG_ID_MC_START message msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + VOS_ASSERT(0); + break; + } + + case SYS_MSG_ID_MC_STOP: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Processing SYS MC STOP" ); + + // get the HAL context... + hHal = vos_get_context( VOS_MODULE_ID_PE, pVosContext ); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal", __func__ ); + } + else + { + vosStatus = sme_Stop( hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + + vosStatus = macStop( hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + + ((sysResponseCback)pMsg->callback)((v_VOID_t *)pMsg->bodyptr); + + vosStatus = VOS_STATUS_SUCCESS; + } + break; + } + + // Process MC thread probe. Just callback to the + // function that is in the message. + case SYS_MSG_ID_MC_THR_PROBE: + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + " Received SYS_MSG_ID_MC_THR_PROBE message msgType = %d [0x%08x]", + pMsg->type, pMsg->type); + break; + } + + case SYS_MSG_ID_MC_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + timerCB(pMsg->bodyptr); + } + break; + } + case SYS_MSG_ID_FTM_RSP: + { + WLANFTM_McProcessMsg((v_VOID_t *)pMsg->bodyptr); + break; + } + + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysMcProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + + } // end if cookie set + else + { + // Process all 'legacy' messages + switch( pMsg->type ) + { + + default: + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified " + "MC message type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + if (pMsg->bodyptr) + vos_mem_free(pMsg->bodyptr); + break; + } + } // end switch on pMsg->type + } // end else + + return( vosStatus ); +} + + + + +VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + // Process TX thread probe. Just callback to the + // function that is in the message. + case SYS_MSG_ID_TX_THR_PROBE: + { + /* Handling for this message is not needed now so adding + * debug print and VOS_ASSERT*/ + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + " Received SYS_MSG_ID_TX_THR_PROBE message msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + VOS_ASSERT(0); + + break; + } + + case SYS_MSG_ID_TX_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + timerCB(pMsg->bodyptr); + } + break; + } + + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysTxProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + } // end if cookie set + else + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified TX message " + " type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + } // end else + + return( vosStatus ); +} + + +VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + case SYS_MSG_ID_RX_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + timerCB(pMsg->bodyptr); + } + break; + } + + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysRxProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + } // end if cookie set + else + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified RX message " + " type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + } // end else + + return( vosStatus ); +} + + +v_VOID_t sysMcFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ) +{ + return; +} + + +v_VOID_t sysTxFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ) +{ + return; +} + + +void +SysProcessMmhMsg +( + tpAniSirGlobal pMac, + tSirMsgQ* pMsg +) +{ + VOS_MQ_ID targetMQ = VOS_MQ_ID_SYS; +/*-------------------------------------------------------------------------*/ + /* + ** The body of this pMsg is a tSirMbMsg + ** Contrary to Gen4, we cannot free it here! + ** It is up to the callee to free it + */ + + + if (NULL == pMsg) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL Message Pointer"); + VOS_ASSERT(0); + return; + } + + + switch (pMsg->type) + { + /* + ** Following messages are routed to SYS + */ + case WNI_CFG_DNLD_REQ: + case WNI_CFG_DNLD_CNF: + case WDA_APP_SETUP_NTF: + case WDA_NIC_OPER_NTF: + case WDA_RESET_REQ: + case eWNI_SME_START_RSP: + { + /* Forward this message to the SYS module */ + targetMQ = VOS_MQ_ID_SYS; + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Handling for the Message ID %d is removed in SYS\r\n", + pMsg->type); + + VOS_ASSERT(0); + break; + } + + + /* + ** Following messages are routed to HAL + */ + case WNI_CFG_DNLD_RSP: + case WDA_INIT_START_REQ: + { + /* Forward this message to the HAL module */ + targetMQ = VOS_MQ_ID_WDA; + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Handling for the Message ID %d is removed as there is no HAL \r\n", + pMsg->type); + + VOS_ASSERT(0); + break; + } + + case eWNI_SME_START_REQ: + case WNI_CFG_GET_REQ: + case WNI_CFG_SET_REQ: + case WNI_CFG_SET_REQ_NO_RSP: + case eWNI_SME_SYS_READY_IND: + { + /* Forward this message to the PE module */ + targetMQ = VOS_MQ_ID_PE; + break; + } + + + case WNI_CFG_GET_RSP: + case WNI_CFG_SET_CNF: +/* case eWNI_SME_DISASSOC_RSP: + case eWNI_SME_STA_STAT_RSP: + case eWNI_SME_AGGR_STAT_RSP: + case eWNI_SME_GLOBAL_STAT_RSP: + case eWNI_SME_STAT_SUMM_RSP: + case eWNI_PMC_ENTER_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_IND: + case eWNI_PMC_ENTER_IMPS_RSP: + case eWNI_PMC_EXIT_IMPS_RSP: + case eWNI_PMC_ENTER_UAPSD_RSP: + case eWNI_PMC_EXIT_UAPSD_RSP: + case eWNI_PMC_ENTER_WOWL_RSP: + case eWNI_PMC_EXIT_WOWL_RSP: + case eWNI_SME_SWITCH_CHL_REQ: */ //Taken care by the check in default case + { + /* Forward this message to the SME module */ + targetMQ = VOS_MQ_ID_SME; + break; + } + + default: + { + + if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) && ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) ) + { + targetMQ = VOS_MQ_ID_SME; + break; + } + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Message of ID %d is not yet handled by SYS\r\n", + pMsg->type); + + VOS_ASSERT(0); + } + + } + + + /* + ** Post now the message to the appropriate module for handling + */ + if(VOS_STATUS_SUCCESS != vos_mq_post_message(targetMQ, (vos_msg_t*)pMsg)) + { + //Caller doesn't allocate memory for the pMsg. It allocate memory for bodyptr + /* free the mem and return */ + if(pMsg->bodyptr) + { + vos_mem_free( pMsg->bodyptr); + } + } + +} /* SysProcessMmhMsg() */ + +/*========================================================================== + FUNCTION WLAN_FTM_SYS_FTM + + DESCRIPTION + Called by VOSS to free a given FTM message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + + DEPENDENCIES + FTM must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to FTM's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: + + SIDE EFFECTS + NONE +============================================================================*/ + +void wlan_sys_ftm(void *pMsgPtr) +{ + vos_msg_t vosMessage; + + + + vosMessage.reserved = FTM_SYS_MSG_COOKIE; + vosMessage.type = SYS_MSG_ID_FTM_RSP; + vosMessage.bodyptr = pMsgPtr; + + vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage); + + return; +} + + + +void wlan_sys_probe(void) +{ + vos_msg_t vosMessage; + + vosMessage.reserved = FTM_SYS_MSG_COOKIE; + vosMessage.type = SYS_MSG_ID_MC_THR_PROBE; + vosMessage.bodyptr = NULL; + + vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage); + + return; +} diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/inc/palApi.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/inc/palApi.h new file mode 100644 index 0000000000000..5f85720934110 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/inc/palApi.h @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file palApi.h + + \brief Exports and types for the Platform Abstraction Layer interfaces. + + $Id$This file contains all the interfaces for thge Platform Abstration Layer + functions. It is intended to be included in all modules that are using + the PAL interfaces. + + ========================================================================== */ +#ifndef PALAPI_H__ +#define PALAPI_H__ + +#include "halTypes.h" + +/** + \mainpage Platform Abstraction Layer (PAL) + + \section intro Introduction + + palApi is the Platform Abstration Layer. + + This is the latest attempt to abstract the entire Platform, including the + hardware, chip, OS and Bus into a generic API. We are doing this to give + the MAC the ability to call + generic APIs that will allow the MAC to function in an abstract manner + with any Airgo chipset, on any supported OS (Windows and Linux for now) + across any system bus interface (PCI, PCIe, Cardbus, USB, etc.). + + \todo + - palReadRegister: register read + -# add an Open/Close abstraction to accomodate the PAL before the entire MAC is loaded. + -# Review with Linux folks to see this basic scructure works for them. + -# Figure out how to organize the directory structure + - palMemory: memory read/write + - include async versions of read/write register + - palTx: an abstraction for transmit frames that manages the Td and Tm rings + - palRx: an abstracion for receiving frames from a chip across any of the supported buses + - palInterrupt: abstract the interrupts into the HAL + + + \section impl_notes Implementation Notes + + \subsection subsection_codeStructure Code strucure + + */ + + +/** --------------------------------------------------------------------------- + + \fn palReadRegister + + \brief chip and bus agnostic funtion to read a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be read from the start + of register space. + + \param pRegValue - pointer to the memory where the register contents are written + + \return eHalStatus - status of the register read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 *pRegValue ); + + +/** --------------------------------------------------------------------------- + + \fn palWriteRegister + + \brief chip and bus agnostic funtion to write a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be read from the start + of register space. + + \param pRegValue - pointer to the value being written into the register + + \return eHalStatus - status of the register read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 regValue ); + +/** --------------------------------------------------------------------------- + + \fn palAsyncWriteRegister + + \brief chip and bus agnostic async funtion to write a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be written from the start + of register space. + + \param regValue - value being written into the register + + \return eHalStatus - status of the register write. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ + +eHalStatus palAsyncWriteRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 regValue ); + + +/** --------------------------------------------------------------------------- + + \fn palReadDeviceMemory + + \brief chip and bus agnostic funtion to read memory from the chip + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the + memory map (as exposed to the host) where the memory will be read from. + + \param pBuffer - pointer to a buffer where the memory will be placed in host + memory space after retreived from the chip. + + \param numBytes - the number of bytes to be read. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palWriteDeviceMemory + + \brief chip and bus agnostic funtion to write memory to the chip + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + + +/** --------------------------------------------------------------------------- + + \fn palAllocateMemory + + \brief OS agnostic funtion to allocate host memory. + + \note Host memory that needs to be shared between the host and the + device needs to be allocated with the palAllocateSharedMemory() + and free'd with palFreeSharedMemory() functions. + + \param hHdd - HDD context handle + + \param ppMemory - pointer to a void pointer where the address of the + memory allocated will be placed upon return from this function. + + \param numBytes - the number of bytes to allocate. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +#ifndef FEATURE_WLAN_PAL_MEM_DISABLE + +#ifdef MEMORY_DEBUG +#define palAllocateMemory(hHdd, ppMemory, numBytes) palAllocateMemory_debug(hHdd, ppMemory, numBytes, __FILE__, __LINE__) +eHalStatus palAllocateMemory_debug( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes, char* fileName, tANI_U32 lineNum ); +#else +eHalStatus palAllocateMemory( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes ); +#endif + + +/** --------------------------------------------------------------------------- + + \fn palFreeMemory + + \brief OS agnostic funtion to free host memory that was allocated with + palAllcoateMemory() calls. + + \note Host memory that needs to be shared between the host and the + device needs to be allocated with the palAllocateSharedMemory() + and free'd with palFreeSharedMemory() functions. + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be free'd. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +eHalStatus palFreeMemory( tHddHandle hHdd, void *pMemory ); + + + +/** --------------------------------------------------------------------------- + + \fn palFillMemory + + \brief OS agnostic funtion to fill host memory with a specified byte value + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be filled. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte to be written to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +eHalStatus palFillMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes, tANI_BYTE fillValue ); + +/** --------------------------------------------------------------------------- + + \fn palCopyMemory + + \brief OS agnostic funtion to copy host memory from one location to another + + \param hHdd - HDD context handle + + \param pSrc - pointer to source memory location (to copy from) + + \param pSrc - pointer to destination memory location (to copy to) + + \param numBytes - the number of bytes to be be copied. + + \return eHalStatus - status of the memory copy + + -------------------------------------------------------------------------------*/ +eHalStatus palCopyMemory( tHddHandle hHdd, void *pDst, const void *pSrc, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palFillMemory + + \brief OS agnostic funtion to fill host memory with a specified byte value + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be filled. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte to be written to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION +eHalStatus palZeroMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes ) +{ + return( palFillMemory( hHdd, pMemory, numBytes, 0 ) ); +} + + +/** --------------------------------------------------------------------------- + + \fn palEqualMemory + + \brief OS agnostic funtion to compare two pieces of memory, similar to + memcmp function in standard C. + + \param hHdd - HDD context handle + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return tANI_BOOLEAN - returns a boolean value that tells if the memory + locations are equal or now equal. + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN palEqualMemory( tHddHandle hHdd, void *pMemory1, void *pMemory2, tANI_U32 numBytes ); +#endif +/** --------------------------------------------------------------------------- + + \fn palFillDeviceMemory + + \brief OS agnostic funtion to fill device memory with a specified + 32bit value + + \param hHdd - HDD context handle + + \param memOffset - offset of the memory on the device to fill. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte pattern to fill into memory on the device + + \return eHalStatus - status of the register read. Note that this function + can fail. + + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR - length of the device memory is not + a multiple of 4 bytes. + + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED - memory address is not aligned on a + 4 byte boundary. + + \note return failure if the memOffset is not 32bit aligned and not a + multiple of 4 bytes (the device does not support anything else). + + -------------------------------------------------------------------------------*/ +eHalStatus palFillDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U32 numBytes, tANI_BYTE fillValue ); + + +/** --------------------------------------------------------------------------- + + \fn palZeroDeviceMemory + + \brief OS agnostic funtion to fill device memory with a specified byte value + + \param hHdd - HDD context handle + + \param memOffset - offset of the memory on the device to fill. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the 32bit pattern to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. + + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR - length of the device memory is not + a multiple of 4 bytes. + + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED - memory address is not aligned on a + 4 byte boundary. + + \note return failure if the memOffset is not 32bit aligned and not a + multiple of 4 bytes (the device does not support anything else). + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION +eHalStatus palZeroDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U32 numBytes ) +{ + return( palFillDeviceMemory( hHdd, memOffset, numBytes, 0 ) ); +} + +/*---------------------------------------------------------------------------------- + + Allocate a packet for sending through the Tx APIs. + + \param hHdd - HDD context handle + + \param frmType - Frame type + + \param size + + \param data - + + \param ppPacket - + + \return eHalStatus - +----------------------------------------------------------------------------------*/ +eHalStatus palPktAlloc(tHddHandle hHdd, eFrameType frmType, tANI_U16 size, void **data, void **ppPacket) ; + + +// This should return Ssome sort of status..... +void palPktFree( tHddHandle hHdd, eFrameType frmType, void* buf, void *pPacket); + + + +//PAL lock functions +//pHandle -- pointer to a caller allocated tPalSpinLockHandle object +eHalStatus palSpinLockAlloc( tHddHandle hHdd, tPalSpinLockHandle *pHandle ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockFree( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockTake( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockGive( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//PAL lock functions end + + +//This function send a message to MAC, +//pMsgBuf is a buffer allocated by caller. The actual structure varies base on message type +//The beginning of the buffer can always map to tSirMbMsg +//This function must take care of padding if it is required for the OS +eHalStatus palSendMBMessage(tHddHandle hHdd, void *pBuf); + +extern void palGetUnicastStats(tHddHandle hHdd, tANI_U32 *tx, tANI_U32 *rx); + + +/*---------------------------------------------------------------------------------- + this function is to return a tick count (one tick = ~10ms). It is used to calculate + time difference. + + \param hHdd - HDD context handle + + \return tick count. +----------------------------------------------------------------------------------*/ +tANI_U32 palGetTickCount(tHddHandle hHdd); + +/** --------------------------------------------------------------------------- + + \fn palReadRegMemory + + \brief chip and bus agnostic function to read memory from the PHY register space as memory + i.e. to read more than 4 bytes from the contiguous register space + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the + memory map (as exposed to the host) where the memory will be read from. + + \param pBuffer - pointer to a buffer where the memory will be placed in host + memory space after retreived from the chip. + + \param numBytes - the number of bytes to be read. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palAsyncWriteRegMemory + + \brief chip and bus agnostic function to write memory to the PHY register space as memory + i.e. to write more than 4 bytes from the contiguous register space. In USB interface, this + API does the write asynchronously. + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palAsyncWriteRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palWriteRegMemory + \brief chip and bus agnostic function to write memory to the PHY register space as memory + i.e. to write more than 4 bytes from the contiguous register space. The difference from the + above routine is, in USB interface, this routine performs the write synchronously where as + the above routine performs it asynchronously. + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + + +/** --------------------------------------------------------------------------- + + \fn palWaitRegVal + + \brief is a blocking function which reads the register and waits for the given number of iterations + until the read value matches the waitRegVal. The delay between is perIterWaitInNanoSec(in nanoseconds) + + \param hHdd - HDD context handle + + \param reg - address of the register to be read + + \param mask - mask to be applied for the read value + + \param waitRegVal - expected value from the register after applying the mask. + + \param perIterWaitInNanoSec - delay between the two iterations in nanoseconds + + \param numIter - max number of reads before the timeout + + \param pReadRegVal - the value read from the register + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWaitRegVal( tHddHandle hHdd, tANI_U32 reg, tANI_U32 mask, + tANI_U32 waitRegVal, tANI_U32 perIterWaitInNanoSec, + tANI_U32 numIter, tANI_U32 *pReadRegVal ); + +/** --------------------------------------------------------------------------- + + \fn palReadModifyWriteReg + + \brief chip and bus agnostic function to read a PHY register apply the given masks(AND and OR masks) + and writes back the new value to the register + + \param hHdd - HDD context handle + + \param reg - address of the register to be modified. + + \param andMask - The value read will be ANDed with this mask + + \parma orMask - The value after applying the andMask will be ORed with this value + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadModifyWriteReg( tHddHandle hHdd, tANI_U32 reg, tANI_U32 andMask, tANI_U32 orMask ); + +//PAL semaphore functions +eHalStatus palSemaphoreAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle, tANI_S32 count ); +eHalStatus palSemaphoreFree( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palSemaphoreTake( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palSemaphoreGive( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palMutexAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) ; +eHalStatus palMutexAllocLocked( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) ; + +//PAL irq/softirq +eAniBoolean pal_in_interrupt(void) ; +void pal_local_bh_disable(void) ; +void pal_local_bh_enable(void) ; + +//PAL byte swap +tANI_U32 pal_be32_to_cpu(tANI_U32 x) ; +tANI_U32 pal_cpu_to_be32(tANI_U32 x) ; +tANI_U16 pal_be16_to_cpu(tANI_U16 x) ; +tANI_U16 pal_cpu_to_be16(tANI_U16 x) ; + + +#if defined( ANI_LITTLE_BYTE_ENDIAN ) + +// Need to eliminate these and use the ani_cpu_to_le, etc. macros.... +ANI_INLINE_FUNCTION unsigned long i_htonl( unsigned long ul ) +{ + return( ( ( ul & 0x000000ff ) << 24 ) | + ( ( ul & 0x0000ff00 ) << 8 ) | + ( ( ul & 0x00ff0000 ) >> 8 ) | + ( ( ul & 0xff000000 ) >> 24 ) ); +} + +ANI_INLINE_FUNCTION unsigned short i_htons( unsigned short us ) +{ + return( ( ( us >> 8 ) & 0x00ff ) + ( ( us << 8 ) & 0xff00 ) ); +} + +ANI_INLINE_FUNCTION unsigned short i_ntohs( unsigned short us ) +{ + return( i_htons( us ) ); +} + +ANI_INLINE_FUNCTION unsigned long i_ntohl( unsigned long ul ) +{ + return( i_htonl( ul ) ); +} + +#endif //#if defined( ANI_LITTLE_BYTE_ENDIAN ) + + +/** --------------------------------------------------------------------------- + + \fn pal_set_U32 + + \brief Assign 32-bit unsigned value to a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param value - The value to assign to the byte array + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_set_U32(tANI_U8 *ptr, tANI_U32 value) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *(ptr) = ( tANI_U8 )( value >> 24 ); + *(ptr + 1) = ( tANI_U8 )( value >> 16 ); + *(ptr + 2) = ( tANI_U8 )( value >> 8 ); + *(ptr + 3) = ( tANI_U8 )( value ); +#else + *(ptr + 3) = ( tANI_U8 )( value >> 24 ); + *(ptr + 2) = ( tANI_U8 )( value >> 16 ); + *(ptr + 1) = ( tANI_U8 )( value >> 8 ); + *(ptr) = ( tANI_U8 )( value ); +#endif + + return (ptr + 4); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_set_U16 + + \brief Assign 16-bit unsigned value to a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param value - The value to assign to the byte array + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_set_U16(tANI_U8 *ptr, tANI_U16 value) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *(ptr) = ( tANI_U8 )( value >> 8 ); + *(ptr + 1) = ( tANI_U8 )( value ); +#else + *(ptr + 1) = ( tANI_U8 )( value >> 8 ); + *(ptr) = ( tANI_U8 )( value ); +#endif + + return (ptr + 2); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_get_U16 + + \brief Retrieve a 16-bit unsigned value from a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param pValue - Pointer to a caller allocated buffer for 16 bit value. Value is to assign + to this location. + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_get_U16(tANI_U8 *ptr, tANI_U16 *pValue) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *pValue = (((tANI_U16) (*ptr << 8)) | + ((tANI_U16) (*(ptr+1)))); +#else + *pValue = (((tANI_U16) (*(ptr+1) << 8)) | + ((tANI_U16) (*ptr))); +#endif + + return (ptr + 2); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_get_U32 + + \brief Retrieve a 32-bit unsigned value from a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param pValue - Pointer to a caller allocated buffer for 32 bit value. Value is to assign + to this location. + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_get_U32(tANI_U8 *ptr, tANI_U32 *pValue) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *pValue = ( (tANI_U32)(*(ptr) << 24) | + (tANI_U32)(*(ptr+1) << 16) | + (tANI_U32)(*(ptr+2) << 8) | + (tANI_U32)(*(ptr+3)) ); +#else + *pValue = ( (tANI_U32)(*(ptr+3) << 24) | + (tANI_U32)(*(ptr+2) << 16) | + (tANI_U32)(*(ptr+1) << 8) | + (tANI_U32)(*(ptr)) ); +#endif + + return (ptr + 4); +} + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/src/palApiComm.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/src/palApiComm.c new file mode 100644 index 0000000000000..146a45fbb2904 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/pal/src/palApiComm.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include // needed for tSirRetStatus +#include + +#include // needed for tSirMbMsg +#include "wlan_qct_wda.h" +#include "adf_nbuf.h" + +#ifndef FEATURE_WLAN_PAL_MEM_DISABLE + +#ifdef MEMORY_DEBUG +eHalStatus palAllocateMemory_debug( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes, char* fileName, tANI_U32 lineNum ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + *ppMemory = vos_mem_malloc_debug( numBytes, fileName, lineNum ); + + if ( NULL == *ppMemory ) + { + halStatus = eHAL_STATUS_FAILURE; + } + + return( halStatus ); +} +#else +eHalStatus palAllocateMemory( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + *ppMemory = vos_mem_malloc( numBytes ); + + if ( NULL == *ppMemory ) + { + halStatus = eHAL_STATUS_FAILURE; + } + + return( halStatus ); +} +#endif + + +eHalStatus palFreeMemory( tHddHandle hHdd, void *pMemory ) +{ + vos_mem_free( pMemory ); + + return( eHAL_STATUS_SUCCESS ); +} + +eHalStatus palFillMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes, tANI_BYTE fillValue ) +{ + vos_mem_set( pMemory, numBytes, fillValue ); + + return( eHAL_STATUS_SUCCESS ); +} + + +eHalStatus palCopyMemory( tHddHandle hHdd, void *pDst, const void *pSrc, tANI_U32 numBytes ) +{ + vos_mem_copy( pDst, pSrc, numBytes ); + + return( eHAL_STATUS_SUCCESS ); +} + + + +tANI_BOOLEAN palEqualMemory( tHddHandle hHdd, void *pMemory1, void *pMemory2, tANI_U32 numBytes ) +{ + return( vos_mem_compare( pMemory1, pMemory2, numBytes ) ); +} +#endif + +#define TX_PKT_MIN_HEADROOM 64 +eHalStatus palPktAlloc(tHddHandle hHdd, eFrameType frmType, tANI_U16 size, + void **data, void **ppPacket) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + adf_nbuf_t nbuf; + + nbuf = adf_nbuf_alloc(NULL, roundup(size+TX_PKT_MIN_HEADROOM, 4), + TX_PKT_MIN_HEADROOM, + sizeof(tANI_U32), FALSE); + + if (nbuf != NULL) { + adf_nbuf_put_tail(nbuf, size); + adf_nbuf_set_protocol(nbuf, ETH_P_CONTROL); + *ppPacket = nbuf; + *data = adf_nbuf_data(nbuf); + halStatus = eHAL_STATUS_SUCCESS; + } + + return halStatus; +} + +void palPktFree( tHddHandle hHdd, eFrameType frmType, void* buf, void *pPacket) +{ + adf_nbuf_free((adf_nbuf_t)pPacket); +} + +tANI_U32 palGetTickCount(tHddHandle hHdd) +{ + return( vos_timer_get_system_ticks() ); +} + + +tANI_U32 pal_be32_to_cpu(tANI_U32 x) +{ + return( x ); +} + +tANI_U32 pal_cpu_to_be32(tANI_U32 x) +{ + return(( x ) ); +} + +tANI_U16 pal_be16_to_cpu(tANI_U16 x) +{ + return( ( x ) ); +} + +tANI_U16 pal_cpu_to_be16(tANI_U16 x) +{ + return( ( x ) ); +} + + + +eHalStatus palSpinLockAlloc( tHddHandle hHdd, tPalSpinLockHandle *pHandle ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus; + vos_lock_t *pLock; + + do + { + pLock = vos_mem_malloc( sizeof( vos_lock_t ) ); + + if ( NULL == pLock ) break; + + vosStatus = vos_lock_init( pLock ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + vos_mem_free( pLock ); + break; + } + + *pHandle = (tPalSpinLockHandle)pLock; + halStatus = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( halStatus ); +} + + +eHalStatus palSpinLockFree( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_destroy( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if we successfully destroy the lock, free + // the memory and indicate success to the caller. + vos_mem_free( pLock ); + + halStatus = eHAL_STATUS_SUCCESS; + } + return( halStatus ); +} + + +eHalStatus palSpinLockTake( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_acquire( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if successfully acquire the lock, indicate success + // to the caller. + halStatus = eHAL_STATUS_SUCCESS; + } + + return( halStatus ); +} + + + + + +eHalStatus palSpinLockGive( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_release( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if successfully acquire the lock, indicate success + // to the caller. + halStatus = eHAL_STATUS_SUCCESS; + } + + return( halStatus ); +} + + +// Caller of this function MUST dynamically allocate memory for pBuf +// because this funciton will free the memory. +eHalStatus palSendMBMessage(tHddHandle hHdd, void *pBuf) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tSirRetStatus sirStatus; + v_CONTEXT_t vosContext; + v_VOID_t *hHal; + + vosContext = vos_get_global_context( VOS_MODULE_ID_HDD, hHdd ); + if (NULL == vosContext) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid vosContext", __func__); + } + else + { + hHal = vos_get_context( VOS_MODULE_ID_SME, vosContext ); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid hHal", __func__); + } + else + { + sirStatus = uMacPostCtrlMsg( hHal, pBuf ); + if ( eSIR_SUCCESS == sirStatus ) + { + halStatus = eHAL_STATUS_SUCCESS; + } + } + } + + vos_mem_free( pBuf ); + + return( halStatus ); +} + + + +//All semophore functions are no-op here +//PAL semaphore functions +//All functions MUST return success. If change needs to be made, please check all callers' logic +eHalStatus palSemaphoreAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle, tANI_S32 count ) +{ + (void)hHdd; + (void)pHandle; + (void)count; + if(pHandle) + { + *pHandle = NULL; + } + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreFree( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreTake( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreGive( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palMutexAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) +{ + (void)hHdd; + (void)pHandle; + + if(pHandle) + { + *pHandle = NULL; + } + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palMutexAllocLocked( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) +{ + (void)hHdd; + (void)pHandle; + + if(pHandle) + { + *pHandle = NULL; + } + return (eHAL_STATUS_SUCCESS); +} + + +eAniBoolean pal_in_interrupt(void) +{ + return (eANI_BOOLEAN_FALSE); +} + +void pal_local_bh_disable(void) +{ +} + +void pal_local_bh_enable(void) +{ +} diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/inc/VossWrapper.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/inc/VossWrapper.h new file mode 100644 index 0000000000000..5ce353040a1da --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/inc/VossWrapper.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __VOSS_WRAPPER_H +#define __VOSS_WRAPPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*=========================================================================== + @file VossWrapper.h + + @brief This header file contains the various structure definitions and + function prototypes for the RTOS abstraction layer, implemented for VOSS +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 12/15/08 sho Resolved warnings and errors from AMSS compiler when + this is ported to WM + 11/20/08 sho Renamed this to VossWrapper.h; remove all dependencies + on WM platform and allow this to work on all VOSS enabled + platforms + 06/24/08 tbh Modified the file to remove the dependecy on HDD files as + part of Gen6 bring up process. + 10/29/02 Neelay Das Created file. + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ + +#include "sirTypes.h" +#include "sirParams.h" +#include "sysDef.h" +#include "vos_timer.h" +#include "palApi.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_memory.h" + +/* Interlocked Compare Exchange related definitions */ + + + +/* Define basic constants for the ThreadX kernel. */ + +#define TX_NO_WAIT 0 +#define TX_WAIT_FOREVER 0xFFFFFFFFUL +#define TX_AUTO_ACTIVATE 1 +#define TX_NO_ACTIVATE 0 + + + +/* API return values. */ +#define TX_SUCCESS 0x00 +#define TX_QUEUE_FULL 0x01 +// ... +#define TX_NO_INSTANCE 0x0D +// ... +#define TX_TIMER_ERROR 0x15 +#define TX_TICK_ERROR 0x16 +// ... + + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +/* Following macro specifies the number of milliseconds which constitute 1 ThreadX timer tick. Used + for mimicking the ThreadX timer behaviour on VOSS. */ +// Use the same MACRO used by firmware modules to calculate TICKs from mSec +// Mismatch would cause worng timer value to be programmed +#define TX_MSECS_IN_1_TICK SYS_TICK_DUR_MS + +// Signature with which the TX_TIMER struct is initialized, when the timer is created +#define TX_AIRGO_TMR_SIGNATURE 0xDEADBEEF + +#ifdef TIMER_MANAGER +#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern_debug((v_PVOID_t)pMac, a, b, c, d, e, f, g, __FILE__, __LINE__) +#else +#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern((v_PVOID_t)pMac, a, b, c, d, e, f, g) +#endif + +/*--------------------------------------------------------------------*/ +/* Timer structure */ +/* This structure is used to implement ThreadX timer facility. Just */ +/* like ThreadX, timer expiration handler executes at the highest */ +/* possible priority level, i.e. DISPATCH_LEVEL. */ +/*--------------------------------------------------------------------*/ +typedef struct TX_TIMER_STRUCT +{ +#ifdef WLAN_DEBUG +#define TIMER_MAX_NAME_LEN 50 + char timerName[TIMER_MAX_NAME_LEN]; +#endif + v_ULONG_t tmrSignature; + v_VOID_t (*pExpireFunc)(v_PVOID_t, tANI_U32); + tANI_U32 expireInput; + v_ULONG_t initScheduleTimeInMsecs; + v_ULONG_t rescheduleTimeInMsecs; + vos_timer_t vosTimer; + + // Pointer to the MAC global structure, which stores the context for the NIC, + // for which this timer is supposed to operate. + v_PVOID_t pMac; + tANI_U8 sessionId; + +} TX_TIMER; + +#define TX_TIMER_VALID(timer) (timer.pMac != 0) + +extern v_ULONG_t tx_time_get(v_VOID_t); +extern v_UINT_t tx_timer_activate(TX_TIMER*); +extern v_UINT_t tx_timer_change(TX_TIMER*, v_ULONG_t, v_ULONG_t); +extern v_UINT_t tx_timer_change_context(TX_TIMER*, tANI_U32); +#ifdef TIMER_MANAGER +extern v_UINT_t tx_timer_create_intern_debug(v_PVOID_t, TX_TIMER*, char *, v_VOID_t(*)(v_PVOID_t, tANI_U32), + tANI_U32, v_ULONG_t, v_ULONG_t, v_ULONG_t, char* fileName, v_U32_t lineNum ); +#else +extern v_UINT_t tx_timer_create_intern(v_PVOID_t, TX_TIMER*, char *, v_VOID_t(*)(v_PVOID_t, tANI_U32), tANI_U32, v_ULONG_t, v_ULONG_t, v_ULONG_t); +#endif +extern v_UINT_t tx_timer_deactivate(TX_TIMER*); +extern v_UINT_t tx_timer_delete(TX_TIMER*); +extern v_BOOL_t tx_timer_running(TX_TIMER*); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/src/VossWrapper.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/src/VossWrapper.c new file mode 100644 index 0000000000000..56a5a72e60020 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/platform/src/VossWrapper.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file VossWrapper.c + + @brief This source file contains the various function definitions for the + RTOS abstraction layer, implemented for VOSS +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/31/09 sho Remove the use of vosTimerIsActive flag as it is not + thread-safe + 02/17/08 sho Fix the timer callback function to work when it is called + after the timer has stopped due to a race condition. + 02/10/08 sho Refactor the TX timer to use VOS timer directly instead + of using VOS utility timer + 12/15/08 sho Resolved errors and warnings from the AMSS compiler when + this is ported from WM + 11/20/08 sho Renamed this to VosWrapper.c; remove all dependencies on + WM platform and allow this to work on all VOSS enabled + platform + 06/24/08 tbh Modified the file to remove the dependecy on HDD files as + part of Gen6 bring up process. + 10/29/02 Neelay Das Created file. + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include "VossWrapper.h" + +#ifdef WLAN_DEBUG +#define TIMER_NAME (timer_ptr->timerName) +#else +#define TIMER_NAME "N/A" +#endif + +/**--------------------------------------------------------------------- + * tx_time_get() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return current system time in units of miliseconds + * + */ +v_ULONG_t tx_time_get( void ) +{ + return(vos_timer_get_system_ticks()); + +} //* tx_time_get() + + +/**--------------------------------------------------------------------- + * tx_timer_activate() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_activate(TX_TIMER *timer_ptr) +{ + VOS_STATUS status; + + // Uncomment the asserts, if the intention is to debug the occurence of the + // following anomalous cnditions. + + // Assert that the timer structure pointer passed, is not NULL + //dbgAssert(NULL != timer_ptr); + + // If the NIC is halting just spoof a successful timer activation, so that all + // the timers can be cleaned up. + + if(NULL == timer_ptr) + return TX_TIMER_ERROR; + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + + } + + // Check for an uninitialized timer + VOS_ASSERT(0 != strlen(TIMER_NAME)); + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s being activated\n", TIMER_NAME); + + status = vos_timer_start( &timer_ptr->vosTimer, + timer_ptr->initScheduleTimeInMsecs ); + + if (VOS_STATUS_SUCCESS == status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s now activated\n", TIMER_NAME); + return TX_SUCCESS; + } + else if (VOS_STATUS_E_ALREADY == status) + { + // starting timer fails because timer is already started; this is okay + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s is already running\n", TIMER_NAME); + return TX_SUCCESS; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Timer %s fails to activate\n", TIMER_NAME); + return TX_TIMER_ERROR; + } +} /*** tx_timer_activate() ***/ + + +/**--------------------------------------------------------------------- + * tx_timer_change() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_change(TX_TIMER *timer_ptr, + v_ULONG_t initScheduleTimeInTicks, v_ULONG_t rescheduleTimeInTicks) +{ + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + } + + // changes cannot be applied until timer stops running + if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer)) + { + timer_ptr->initScheduleTimeInMsecs = TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + return TX_SUCCESS; + } + else + { + return TX_TIMER_ERROR; + } +} /*** tx_timer_change() ***/ + +/**--------------------------------------------------------------------- + * tx_timer_change_context() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_change_context(TX_TIMER *timer_ptr, tANI_U32 expiration_input) +{ + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + } + + // changes cannot be applied until timer stops running + if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer)) + { + timer_ptr->expireInput = expiration_input; + return TX_SUCCESS; + } + else + { + return TX_TIMER_ERROR; + } +} /*** tx_timer_change() ***/ + + +/**--------------------------------------------------------------------- + * tx_main_timer_func() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return None. + * + */ +static v_VOID_t tx_main_timer_func( v_PVOID_t functionContext ) +{ + TX_TIMER *timer_ptr = (TX_TIMER *)functionContext; + + + if (NULL == timer_ptr) + { + VOS_ASSERT(0); + return; + } + + + if (NULL == timer_ptr->pExpireFunc) + { + VOS_ASSERT(0); + return; + } + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s triggered", TIMER_NAME); + + // Now call the actual timer function, taking the function pointer, + // from the timer structure. + (* timer_ptr->pExpireFunc)( timer_ptr->pMac, timer_ptr->expireInput ); + + // check if this needs to be rescheduled + if (0 != timer_ptr->rescheduleTimeInMsecs) + { + VOS_STATUS status; + status = vos_timer_start( &timer_ptr->vosTimer, + timer_ptr->rescheduleTimeInMsecs ); + timer_ptr->rescheduleTimeInMsecs = 0; + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN, + "Unable to reschedule timer %s; status=%d", TIMER_NAME, status); + } + } +} /*** tx_timer_change() ***/ + +#ifdef TIMER_MANAGER +v_UINT_t tx_timer_create_intern_debug( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr, + char *name_ptr, + v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ), + tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks, + v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate, + char* fileName, v_U32_t lineNum) +{ + VOS_STATUS status; + + if (NULL == expiration_function) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL timer expiration"); + VOS_ASSERT(0); + return TX_TIMER_ERROR; + } + + if(NULL == name_ptr) + { + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL name pointer for timer"); + VOS_ASSERT(0); + return TX_TIMER_ERROR; + } + if (!initScheduleTimeInTicks) + return TX_TICK_ERROR; + + if (!timer_ptr) + return TX_TIMER_ERROR; + + // Initialize timer structure + timer_ptr->pExpireFunc = expiration_function; + timer_ptr->expireInput = expiration_input; + timer_ptr->initScheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + timer_ptr->pMac = pMacGlobal; + + // Set the flag indicating that the timer was created + timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE; + +#ifdef WLAN_DEBUG + // Store the timer name + strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName)); +#endif // Store the timer name, for Debug build only + + status = vos_timer_init_debug( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW, + tx_main_timer_func, (v_PVOID_t)timer_ptr, fileName, lineNum); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Cannot create timer for %s\n", TIMER_NAME); + return TX_TIMER_ERROR; + } + + if(0 != rescheduleTimeInTicks) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Creating periodic timer for %s\n", TIMER_NAME); + } + + // Activate this timer if required + if (auto_activate) + { + tx_timer_activate(timer_ptr); + } + + return TX_SUCCESS; + +} //** tx_timer_create() ***/ +#else +v_UINT_t tx_timer_create_intern( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr, + char *name_ptr, + v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ), + tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks, + v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate ) +{ + VOS_STATUS status; + + if((NULL == name_ptr) || (NULL == expiration_function)) + return TX_TIMER_ERROR; + + if (!initScheduleTimeInTicks) + return TX_TICK_ERROR; + + if (!timer_ptr) + return TX_TIMER_ERROR; + + // Initialize timer structure + timer_ptr->pExpireFunc = expiration_function; + timer_ptr->expireInput = expiration_input; + timer_ptr->initScheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + timer_ptr->pMac = pMacGlobal; + + // Set the flag indicating that the timer was created + timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE; + +#ifdef WLAN_DEBUG + // Store the timer name + strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName)); +#endif // Store the timer name, for Debug build only + + status = vos_timer_init( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW, + tx_main_timer_func, (v_PVOID_t)timer_ptr ); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Cannot create timer for %s\n", TIMER_NAME); + return TX_TIMER_ERROR; + } + + if(0 != rescheduleTimeInTicks) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Creating periodic timer for %s\n", TIMER_NAME); + } + + // Activate this timer if required + if (auto_activate) + { + tx_timer_activate(timer_ptr); + } + + return TX_SUCCESS; + +} //** tx_timer_create() ***/ +#endif + + +/**--------------------------------------------------------------------- + * tx_timer_deactivate() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_deactivate(TX_TIMER *timer_ptr) +{ + VOS_STATUS vStatus; + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_deactivate() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + { + return TX_TIMER_ERROR; + } + + // if the timer is not running then we do not need to do anything here + vStatus = vos_timer_stop( &timer_ptr->vosTimer ); + if (VOS_STATUS_SUCCESS != vStatus) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_HIGH, + "Unable to stop timer %s; status =%d\n", + TIMER_NAME, vStatus); + } + + return TX_SUCCESS; + +} /*** tx_timer_deactivate() ***/ + +v_UINT_t tx_timer_delete( TX_TIMER *timer_ptr ) +{ + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_delete() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + { + return TX_TIMER_ERROR; + } + + vos_timer_destroy( &timer_ptr->vosTimer ); + return TX_SUCCESS; +} /*** tx_timer_delete() ***/ + + + +/**--------------------------------------------------------------------- + * tx_timer_running() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_BOOL_t tx_timer_running(TX_TIMER *timer_ptr) +{ + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_running() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + return VOS_FALSE; + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( &timer_ptr->vosTimer )) + { + return VOS_TRUE; + } + return VOS_FALSE; + +} /*** tx_timer_running() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDebug.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDebug.h new file mode 100644 index 0000000000000..8cf24f9d9a676 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDebug.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysGlobal.h contains the logDump utility for system module. + * Author: V. K. Kandarpa + * Date: 01/24/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __SYS_DEBUG_H__ +#define __SYS_DEBUG_H__ + +#include +# include "utilsApi.h" +# include "sirDebug.h" +# include "sirParams.h" + +void sysLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...); + +#endif // __SYS_DEBUG_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDef.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDef.h new file mode 100644 index 0000000000000..97b5b70d8a656 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysDef.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysDef.h contains the common definitions used to bring up + * Sirius system. + * Author: V. K. Kandarpa + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SYSDEF_H +#define __SYSDEF_H + +/// Sirius system level definitions +// NOTE: Do not program system timer tick duration to less than 1msec + +/// System timer tick duration in nanoseconds +#define SYS_TICK_DUR_NS 10000000 // 10ms +#define SYS_TICK_TO_MICRO_SECOND 10000 + +/// System timer tick duration in milliseconds +#define SYS_TICK_DUR_MS (SYS_TICK_DUR_NS/1000000) + +/// Clocks in a millisecond +#define SYS_CLOCKS_PER_MS 120000 // 120 MHz + +// In Milliseconds +#define SYS_ADD_BA_RSP_DUR 1000 + +/// System timer tick duration in clocks +#define SYS_TICK_DUR_CLK (SYS_TICK_DUR_MS * SYS_CLOCKS_PER_MS) + +/// Number of timer ticks in a second +#define SYS_TICKS_PER_SECOND (1000/SYS_TICK_DUR_MS) + +/// Macro to convert MS to Ticks +#define SYS_MS_TO_TICKS(x) ((x) / SYS_TICK_DUR_MS) + +/// Macro to convert Seconds to Ticks +#define SYS_SEC_TO_TICKS(x) ((x) * SYS_TICKS_PER_SECOND) + +/// Macro to convert Minutes to Ticks +#define SYS_MIN_TO_TICKS(x) (((x) * 60) * SYS_TICKS_PER_SECOND) + +/// MNT task processing interval in seconds +#define SYS_MNT_INTERVAL 60 + +/// MS to Time Units +#define SYS_MS_TO_TU(x) ((x * 1000) >> 10) + +/// TU to MS +#define SYS_TU_TO_MS(x) ((x << 10) / 1000) + +// --------- End of Windows & RTAI ----------- + +/// Message queue definitions + +/// gHalMsgQ +# define SYS_HAL_Q_SIZE 200 // Holds up to 25 messages + +/// gMMHhiPriorityMsgQ +# define SYS_MMH_HI_PRI_Q_SIZE 200 // Holds up to 25 messages + +/// gMMHprotocolMsgQ +# define SYS_MMH_PROT_Q_SIZE 400 // Holds up to 50 messages + +/// gMMHdebugMsgQ +# define SYS_MMH_DEBUG_Q_SIZE 800 // Holds up to 100 messages + +/// gMAINTmsgQ +# define SYS_MNT_Q_SIZE 200 // Holds up to 25 messages + +/// LIM Message Queue +# define SYS_LIM_Q_SIZE 400 // Holds up to 50 messages + +/// Scheduler Message Queue +# define SYS_SCH_Q_SIZE 800 // Holds up to 25 messages + +/// PMM Message Queue +# define SYS_PMM_Q_SIZE 800 // Holds up to 100 messages + +/// TX Message Queue +# define SYS_TX_Q_SIZE 2048 // Holds up to 400 messages + +/// RX Message Queue +# define SYS_RX_Q_SIZE 2048 // Holds up to 400 messages + +/// PTT Message Queue +# define SYS_NIM_PTT_Q_SIZE 200 // Holds up to 25 messages + +/// Semaphore definitions +// Data Semaphore + +# define SYS_DPH_SEM_INITIAL_CNT 0 + +// Transport Semaphore + +# define SYS_BBT_SEM_INITIAL_CNT 0 + +/// Thread definitions +// tHAL + +# define SYS_HAL_THREAD_ENTRY_FUNCTION halEntry +# define SYS_HAL_STACK_SIZE 8192 +# define SYS_HAL_THREAD_PRIORITY 2 + +// tDPH + +# define SYS_DPH_THREAD_ENTRY_FUNCTION dphEntry +# define SYS_DPH_STACK_SIZE 8192 +# define SYS_DPH_THREAD_PRIORITY 15 + +// tBBT + +# define SYS_BBT_THREAD_ENTRY_FUNCTION bbtEntry +# define SYS_BBT_STACK_SIZE 8192 +# define SYS_BBT_THREAD_PRIORITY 16 + +// tSCH + +# define SYS_SCH_STACK_SIZE 8192 +# define SYS_SCH_THREAD_PRIORITY 17 + +// tPMM + +# define SYS_PMM_STACK_SIZE 8192 +# define SYS_PMM_THREAD_PRIORITY 17 + +// tLIM + +# define SYS_LIM_THREAD_ENTRY_FUNCTION limEntry +# define SYS_LIM_STACK_SIZE 8192 +# define SYS_LIM_THREAD_PRIORITY 18 + +// tMAINT + +# define SYS_MNT_THREAD_ENTRY_FUNCTION mntEntry +# define SYS_MNT_STACK_SIZE 8192 +# define SYS_MNT_THREAD_PRIORITY 25 + +// tMMH + +# define SYS_MMH_THREAD_ENTRY_FUNCTION mmhEntry +# define SYS_MMH_STACK_SIZE 8192 +# define SYS_MMH_THREAD_PRIORITY 10 + +// tNIM_MNT_PKT_GEN + +# define SYS_NIM_PTT_THREAD_STACK_SIZE 8192 +# define SYS_NIM_PTT_THREAD_PRIORITY 28 + +#endif // __SYSDEF_H diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h new file mode 100644 index 0000000000000..82b06eb50e9c7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysEntryFunc.h contains module entry functions definitions + * Author: V. K. Kandarpa + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __SYS_ENTRY_FUNC_H +#define __SYS_ENTRY_FUNC_H + +#include "aniGlobal.h" + +extern tSirRetStatus sysInitGlobals(tpAniSirGlobal); +extern void sysBbtEntry(tANI_U32 dummy); +extern void sysSchEntry(tANI_U32 dummy); +extern void sysPmmEntry(tANI_U32 dummy); +extern void sysDphEntry(tANI_U32 dummy); +extern void sysLimEntry(tANI_U32 dummy); +extern void sysMmhEntry(tANI_U32 dummy); +extern void sysMntEntry(tANI_U32 dummy); +extern void sysHalEntry(tANI_U32 dummy); +extern void sysNimPttEntry(tANI_U32 dummy); + +#endif // __SYS_ENTRY_FUNC_H diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysStartup.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysStartup.h new file mode 100644 index 0000000000000..4eb50d1f5bcc2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/inc/sysStartup.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * + * sysStartup.h: System startup header file. + * Author: V. K. Kandarpa + * Date: 01/29/2002 + * + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ + +# ifndef __SYSSTARTUP_H +# define __SYSSTARTUP_H + +#include "sirParams.h" + +/* Defines */ + +/* Function */ + +extern void sysMACCleanup(void *); +extern tSirRetStatus sysBbtProcessMessageCore(struct sAniSirGlobal *, tpSirMsgQ, + tANI_U32, tANI_U32); + + +# endif /* __SYSSTARTUP_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/macInitApi.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/macInitApi.c new file mode 100644 index 0000000000000..21a0d5044ff4e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/macInitApi.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * macInitApi.c - This file has all the mac level init functions + * for all the defined threads at system level. + * Author: Dinesh Upadhyay + * Date: 04/23/2007 + * History:- + * Date: 04/08/2008 Modified by: Santosh Mandiganal + * Modification Information: Code to allocate and free the memory for DumpTable entry. + * -------------------------------------------------------------------------- + * + */ +/* Standard include files */ +#include "cfgApi.h" // cfgCleanup +#include "limApi.h" // limCleanup +#include "sirTypes.h" +#include "sysDebug.h" +#include "sysEntryFunc.h" +#include "macInitApi.h" +#if defined(ANI_LOGDUMP) +#include "logDump.h" +#endif //#if defined(ANI_LOGDUMP) + +#ifdef TRACE_RECORD +#include "macTrace.h" +#endif + +extern tSirRetStatus halDoCfgInit(tpAniSirGlobal pMac); +extern tSirRetStatus halProcessStartEvent(tpAniSirGlobal pMac); + + + + +tSirRetStatus macReset(tpAniSirGlobal pMac, tANI_U32 rc); + +tSirRetStatus macPreStart(tHalHandle hHal) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + +#if defined(ANI_LOGDUMP) + //logDumpInit must be called before any module starts + logDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + + return eSIR_SUCCESS; +} + +tSirRetStatus macStart(tHalHandle hHal, void* pHalMacStartParams) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + + if (NULL == pMac) + { + VOS_ASSERT(0); + status = eSIR_FAILURE; + return status; + } + + pMac->gDriverType = ((tHalMacStartParameters*)pHalMacStartParams)->driverType; + + sysLog(pMac, LOG2, FL("called\n")); + + do + { + pMac->pResetMsg = vos_mem_malloc(sizeof(tSirMbMsg)); + if ( NULL == pMac->pResetMsg ) + { + sysLog(pMac, LOGE, FL("pMac->pResetMsg is NULL\n")); + status = eSIR_FAILURE; + break; + } + else + { + vos_mem_set(pMac->pResetMsg, sizeof(tSirMbMsg), 0); + } + + if (pMac->gDriverType != eDRIVER_TYPE_MFG) + { + status = peStart(pMac); + } + + } while(0); + pMac->sys.abort = false; + + return status; +} + + +/** ------------------------------------------------------------- +\fn macStop +\brief this function will be called from HDD to stop MAC. This function will stop all the mac modules. +\ memory with global context will only be initialized not freed here. +\param tHalHandle hHal +\param tHalStopType +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus macStop(tHalHandle hHal, tHalStopType stopType) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + peStop(pMac); + cfgCleanup( pMac ); + // need to free memory if not called in reset context. + // in reset context this memory will be freed by HDD. + if(false == pMac->sys.abort) + { + vos_mem_free(pMac->pResetMsg); + pMac->pResetMsg = NULL; + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn macOpen +\brief this function will be called during init. This function is suppose to allocate all the +\ memory with the global context will be allocated here. +\param tHalHandle pHalHandle +\param tHddHandle hHdd +\param tHalOpenParameters* pHalOpenParams +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus macOpen(tHalHandle *pHalHandle, tHddHandle hHdd, tMacOpenParameters *pMacOpenParms) +{ + tpAniSirGlobal p_mac = NULL; + tSirRetStatus status = eSIR_SUCCESS; + uint8_t i =0; + bool mem_alloc_failed = false; + + if(pHalHandle == NULL) + return eSIR_FAILURE; + + /* + * Make sure this adapter is not already opened. (Compare pAdapter pointer in already + * allocated p_mac structures.) + * If it is opened just return pointer to previously allocated p_mac pointer. + * Or should this result in error? + */ + + /* Allocate p_mac */ + p_mac = vos_mem_malloc(sizeof(tAniSirGlobal)); + if (NULL == p_mac) + return eSIR_FAILURE; + + /* Initialize the p_mac structure */ + vos_mem_set(p_mac, sizeof(tAniSirGlobal), 0); + + /** Store the Driver type in pMac Global.*/ + //pMac->gDriverType = pMacOpenParms->driverType; + + /* + * Set various global fields of p_mac here + * (Could be platform dependant as some variables in p_mac are platform + * dependant) + */ + p_mac->hHdd = hHdd; + *pHalHandle = (tHalHandle)p_mac; + + { + /* Call various PE (and other layer init here) */ + if (eSIR_SUCCESS != logInit(p_mac)) { + vos_mem_free(p_mac); + return eSIR_FAILURE; + } + + /* Call routine to initialize CFG data structures */ + if (eSIR_SUCCESS != cfgInit(p_mac)) { + vos_mem_free(p_mac); + return eSIR_FAILURE; + } + + sysInitGlobals(p_mac); + } + + /* Set the Powersave Offload Capability to TRUE irrespective of + * INI param as it should be always enabled for qca-cld driver + */ + p_mac->psOffloadEnabled = TRUE; + + p_mac->scan.nextScanID = FIRST_SCAN_ID; + /* FW: 0 to 2047 and Host: 2048 to 4095 */ + p_mac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN-1; + + status = peOpen(p_mac, pMacOpenParms); + + if (eSIR_SUCCESS != status) { + vos_mem_free(p_mac); + sysLog(p_mac, LOGE, FL("macOpen failure\n")); + return status; + } + + for (i=0; idumpTableEntry[i] = vos_mem_malloc(sizeof(tDumpModuleEntry)); + if (NULL == p_mac->dumpTableEntry[i]) + { + mem_alloc_failed = eANI_BOOLEAN_TRUE; + break; + } + else + { + vos_mem_set(p_mac->dumpTableEntry[i], sizeof(tSirMbMsg), 0); + } + } + + if (mem_alloc_failed) + { + while (i>0) + { + i--; + vos_mem_free(p_mac->dumpTableEntry[i]); + } + + peClose(p_mac); + vos_mem_free(p_mac); + return eSIR_FAILURE; + } + + return status; +} + +/** ------------------------------------------------------------- +\fn macClose +\brief this function will be called in shutdown sequence from HDD. All the +\ allocated memory with global context will be freed here. +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +tSirRetStatus macClose(tHalHandle hHal) +{ + + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + uint8_t i =0; + + peClose(pMac); + pMac->psOffloadEnabled = FALSE; + + /* Call routine to free-up all CFG data structures */ + cfgDeInit(pMac); + + logDeinit(pMac); + + /* Free the DumpTableEntry */ + for(i=0; idumpTableEntry[i]); + } + + // Finally, de-allocate the global MAC datastructure: + vos_mem_free( pMac ); + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn macReset +\brief this function is called to send Reset message to HDD. Then HDD will start the reset process. +\param tpAniSirGlobal pMac +\param tANI_U32 rc +\return tSirRetStatus. + -------------------------------------------------------------*/ + +tSirRetStatus macReset(tpAniSirGlobal pMac, tANI_U32 rc) +{ + tSirRetStatus status = eSIR_SUCCESS; + sysLog(pMac, LOGE, FL("*************No-op. Need to call WDA reset function \n")); + return status; +} + +// ---------------------------------------------------------------------- +/** + * macSysResetReq + * + * FUNCTION: + * All MAC modules use this interface in case of an exception. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param tANI_U32 reset reason code + * @return tANI_U16 - returs the status. + */ + +void +macSysResetReq(tpAniSirGlobal pMac, tANI_U32 rc) +{ + sysLog(pMac, LOGE, FL("Reason Code = 0x%X\n"),rc); + + switch (rc) + { + case eSIR_STOP_BSS: + case eSIR_SME_BSS_RESTART: + case eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF: + case eSIR_CFB_FLAG_STUCK_EXCEPTION: + // FIXME + //macReset(pMac, rc); + break; + + case eSIR_EOF_SOF_EXCEPTION: + case eSIR_BMU_EXCEPTION: + case eSIR_CP_EXCEPTION: + case eSIR_LOW_PDU_EXCEPTION: + case eSIR_USER_TRIG_RESET: + case eSIR_AHB_HANG_EXCEPTION: + default: + macReset(pMac, rc); + break; + + } +} + +// ------------------------------------------------------------- +/** + * macSysResetReqFromHDD + * + * FUNCTION: + * This reset function gets invoked from the HDD to request a reset. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @return tANI_U16 - returs the status. + */ + +void +macSysResetReqFromHDD(void *pMac, tANI_U32 rc) +{ + macSysResetReq( (tpAniSirGlobal)pMac, rc ); +} diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/sysEntryFunc.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/sysEntryFunc.c new file mode 100644 index 0000000000000..01082e755fce6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/system/src/sysEntryFunc.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * sysEntryFunc.cc - This file has all the system level entry functions + * for all the defined threads at system level. + * Author: V. K. Kandarpa + * Date: 01/16/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ +/* Standard include files */ + +/* Application Specific include files */ +#include "sirCommon.h" +#include "aniGlobal.h" + + +#include "limApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "pmmApi.h" + +#include "sysDebug.h" +#include "sysDef.h" +#include "sysEntryFunc.h" +#include "sysStartup.h" +#include "limTrace.h" +#include "wlan_qct_wda.h" + +tSirRetStatus +postPTTMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg); + +#include "vos_types.h" +#include "vos_packet.h" + +#define MAX_DEAUTH_ALLOWED 5 +// --------------------------------------------------------------------------- +/** + * sysInitGlobals + * + * FUNCTION: + * Initializes system level global parameters + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param tpAniSirGlobal Sirius software parameter struct pointer + * @return None + */ + +tSirRetStatus +sysInitGlobals(tpAniSirGlobal pMac) +{ + + vos_mem_set((tANI_U8 *) &pMac->sys, sizeof(pMac->sys), 0); + + pMac->sys.gSysEnableScanMode = 1; + pMac->sys.gSysEnableLinkMonitorMode = 0; + schInitGlobals(pMac); + + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------------- +/** + * sysBbtProcessMessageCore + * + * FUNCTION: + * Process BBT messages + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param tpAniSirGlobal A pointer to MAC params instance + * @param pMsg message pointer + * @param tANI_U32 type + * @param tANI_U32 sub type + * @return None + */ +tSirRetStatus +sysBbtProcessMessageCore(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tANI_U32 type, + tANI_U32 subType) +{ + static tANI_U32 lastDeauthPacketTime = 0; + tSirRetStatus ret; + void* pBd; + tMgmtFrmDropReason dropReason; + vos_pkt_t *pVosPkt = (vos_pkt_t *)pMsg->bodyptr; + VOS_STATUS vosStatus = + WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&pBd, VOS_FALSE ); +#ifdef WLAN_FEATURE_11W + tANI_U8 sessionId; + tpPESession psessionEntry; + tpSirMacMgmtHdr pMacHdr; +#endif /* WLAN_FEATURE_11W */ + + pMac->sys.gSysBbtReceived++; + + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + goto fail; + } + + PELOG3(sysLog(pMac, LOG3, FL("Rx Mgmt Frame Subtype: %d\n"), subType); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, (tANI_U8 *)WDA_GET_RX_MAC_HEADER(pBd), WDA_GET_RX_MPDU_LEN(pBd)); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, WDA_GET_RX_MPDU_DATA(pBd), WDA_GET_RX_PAYLOAD_LEN(pBd));) + + pMac->sys.gSysFrameCount[type][subType]++; + + if(type == SIR_MAC_MGMT_FRAME) + { + if ((subType == SIR_MAC_MGMT_DEAUTH) && (pMac->sys.gSysFrameCount[type][subType] >= MAX_DEAUTH_ALLOWED)) + { + tANI_U32 timeNow = adf_os_ticks(); + tANI_U32 timeGap = adf_os_ticks_to_msecs(timeNow - + lastDeauthPacketTime); + if (timeGap < 1000) { +#ifdef WLAN_FEATURE_11W + pMacHdr = WDA_GET_RX_MAC_HEADER(pBd); + psessionEntry = peFindSessionByPeerSta(pMac, + pMacHdr->sa, &sessionId); + if(!psessionEntry) { + PELOGE(sysLog(pMac, LOGE, + FL("session does not exist for given STA [%pM]"), + pMacHdr->sa);); + goto fail; + } + if (!psessionEntry->limRmfEnabled) +#endif /* WLAN_FEATURE_11W */ + goto fail; + } + } + + if (subType == SIR_MAC_MGMT_DEAUTH) + { + tpSirMacMgmtHdr pMacHdr = WDA_GET_RX_MAC_HEADER(pBd); + PELOGE(sysLog( pMac, LOGE, + FL("DEAUTH frame allowed: " + "da: " MAC_ADDRESS_STR ", " + "sa: " MAC_ADDRESS_STR ", " + "bssid: " MAC_ADDRESS_STR ", " + "DEAUTH count so far: %d\n"), + MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(pMacHdr->sa), + MAC_ADDR_ARRAY(pMacHdr->bssId), + pMac->sys.gSysFrameCount[type][subType] );); + lastDeauthPacketTime = adf_os_ticks(); + } + + if( (dropReason = limIsPktCandidateForDrop(pMac, pBd, subType)) != eMGMT_DROP_NO_DROP) + { + PELOG1(sysLog(pMac, LOG1, FL("Mgmt Frame %d being dropped, reason: %d\n"), subType, dropReason);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_DROP, NO_SESSION, dropReason);) + goto fail; + } + //Post the message to PE Queue + ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg); + if (ret != eSIR_SUCCESS) + { + /* Print only one debug failure out of 512 failure messages */ + if(pMac->sys.gSysBbtReceived & 0x0200) + sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret); + goto fail; + } + pMac->sys.gSysBbtPostedToLim++; + } + else if (type == SIR_MAC_DATA_FRAME) + { +#ifdef FEATURE_WLAN_ESE + PELOGW(sysLog(pMac, LOGW, FL("IAPP Frame...\n"));); + //Post the message to PE Queue + ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg); + if (ret != eSIR_SUCCESS) + { + PELOGE(sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret);) + goto fail; + } + pMac->sys.gSysBbtPostedToLim++; +#endif + } + else + { + PELOG3(sysLog(pMac, LOG3, "BBT received Invalid type %d subType %d " + "LIM state %X. BD dump is:\n", + type, subType, limGetSmeState(pMac)); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, + (tANI_U8 *) pBd, WLANHAL_RX_BD_HEADER_SIZE);) + + goto fail; + } + + return eSIR_SUCCESS; + +fail: + + pMac->sys.gSysBbtDropped++; + return eSIR_FAILURE; +} + + +void sysLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SYS_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_SYS_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h new file mode 100644 index 0000000000000..aafb8ec5337b4 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 +#define DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 +/** + * \file dot11fdefs.h + * + * \brief C defines customizing our framesc-generated code + * + * + * + * + * 'framesc' generates code written in terms of a number of macros + * intended for customization. + * + * + */ + +#include "parserApi.h" + +// This controls how the "dot11f" code copies memory +#define DOT11F_MEMCPY(ctx, dst, src, len) \ + vos_mem_copy( ( tANI_U8* )( dst ), ( tANI_U8* )( src ), ( len ) ) + +// This controls how the "dot11f" code compares memory +#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \ + ( ! vos_mem_compare( ( tANI_U8* )( lhs ), ( tANI_U8* )( rhs ), ( len ) ) ) + +# if defined ( DBG ) && ( DBG != 0 ) + +# //define DOT11F_ENABLE_LOGGING +# //define DOT11F_DUMP_FRAMES +# define DOT11F_LOG_GATE ( 4 ) +# define FRAMES_SEV_FOR_FRAME(ctx, sig) \ + ( DOT11F_ASSOCREQUEST == (sig) ? 3 : 5 ) + + #if defined( DOT11F_ENABLE_LOGGING ) + +# define DOT11F_HAVE_LOG_MACROS + +# define FRAMES_LOG0(ctx, sev, fmt) \ + dot11fLog((ctx), (sev), (fmt)); + +# define FRAMES_LOG1(ctx, sev, fmt, p1) \ + dot11fLog((ctx), (sev), (fmt), (p1)); + +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + dot11fLog((ctx), (sev), (fmt), (p1), (p2)); + +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + dot11fLog((ctx), (sev), (fmt), (p1), (p2), (p3)); + +# define FRAMES_DUMP(ctx, sev, p, n) \ + sirDumpBuf((pCtx), SIR_DBG_MODULE_ID, (sev), (p), (n)); + + #endif //#if defined( DOT11F_ENABLE_LOGGING ) + +# else + +# undef DOT11F_ENABLE_LOGGING +# undef DOT11F_DUMP_FRAMES +# define DOT11F_LOG_GATE ( 1 ) + +# endif + + +// #define DOT11F_ENABLE_DBG_BREAK ( 1 ) + +// Local Variables: +// fill-column: 72 +// indent-tabs-mode: nil +// show-trailing-whitespace: t +// End: + +#endif // DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/utilsParser.h b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/utilsParser.h new file mode 100644 index 0000000000000..fa5ab19074928 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/inc/utilsParser.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file utilsParser.h contains the utility function protos + * used internally by the parser + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __UTILS_PARSE_H__ +#define __UTILS_PARSE_H__ + +#include +#include "sirApi.h" +#include "dot11f.h" +#include "utilsApi.h" + +void ConvertSSID (tpAniSirGlobal, tSirMacSSid*, tDot11fIESSID*); +void ConvertSuppRates (tpAniSirGlobal, tSirMacRateSet*, tDot11fIESuppRates*); +void ConvertFHParams (tpAniSirGlobal, tSirMacFHParamSet*, tDot11fIEFHParamSet*); +void ConvertExtSuppRates (tpAniSirGlobal, tSirMacRateSet*, tDot11fIEExtSuppRates*); +void ConvertQOSCaps (tpAniSirGlobal, tSirMacQosCapabilityIE*, tDot11fIEQOSCapsAp*); +void ConvertQOSCapsStation (tpAniSirGlobal, tSirMacQosCapabilityStaIE*, tDot11fIEQOSCapsStation*); +tSirRetStatus ConvertWPA (tpAniSirGlobal, tSirMacWpaInfo*, tDot11fIEWPA*); +tSirRetStatus ConvertWPAOpaque (tpAniSirGlobal, tSirMacWpaInfo*, tDot11fIEWPAOpaque*); +tSirRetStatus ConvertRSN (tpAniSirGlobal, tSirMacRsnInfo*, tDot11fIERSN*); +tSirRetStatus ConvertRSNOpaque (tpAniSirGlobal, tSirMacRsnInfo*, tDot11fIERSNOpaque*); +void ConvertPowerCaps (tpAniSirGlobal, tSirMacPowerCapabilityIE*, tDot11fIEPowerCaps*); +void ConvertSuppChannels (tpAniSirGlobal, tSirMacSupportedChannelIE*, tDot11fIESuppChannels*); +void ConvertCFParams (tpAniSirGlobal, tSirMacCfParamSet*, tDot11fIECFParams*); +void ConvertTIM (tpAniSirGlobal, tSirMacTim*, tDot11fIETIM*); +void ConvertCountry (tpAniSirGlobal, tSirCountryInformation*, tDot11fIECountry*); +void ConvertWMMParams (tpAniSirGlobal, tSirMacEdcaParamSetIE*, tDot11fIEWMMParams*); +void ConvertERPInfo (tpAniSirGlobal, tSirMacErpInfo*, tDot11fIEERPInfo*); +void ConvertEDCAParam (tpAniSirGlobal, tSirMacEdcaParamSetIE*, tDot11fIEEDCAParamSet*); +void ConvertTSPEC (tpAniSirGlobal, tSirMacTspecIE*, tDot11fIETSPEC*); +tSirRetStatus ConvertTCLAS (tpAniSirGlobal, tSirTclasInfo*, tDot11fIETCLAS*); +void ConvertWMMTSPEC (tpAniSirGlobal, tSirMacTspecIE*, tDot11fIEWMMTSPEC*); +tSirRetStatus ConvertWMMTCLAS (tpAniSirGlobal, tSirTclasInfo*, tDot11fIEWMMTCLAS*); +void ConvertTSDelay (tpAniSirGlobal, tSirMacTsDelayIE*, tDot11fIETSDelay*); +void ConvertSchedule (tpAniSirGlobal, tSirMacScheduleIE*, tDot11fIESchedule*); +void ConvertWMMSchedule (tpAniSirGlobal, tSirMacScheduleIE*, tDot11fIEWMMSchedule*); +tSirRetStatus ConvertWscOpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEWscIEOpaque*); +tSirRetStatus ConvertP2POpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEP2PIEOpaque*); +#ifdef WLAN_FEATURE_WFD +tSirRetStatus ConvertWFDOpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEWFDIEOpaque*); +#endif +void ConvertQosMapsetFrame(tpAniSirGlobal, tSirQosMapSet*, tDot11fIEQosMapSet*); + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c new file mode 100644 index 0000000000000..293b9b88fa1dd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c @@ -0,0 +1,46113 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * \file dot11f.c + * + * \brief Structures, functions & definitions for + * working with 802.11 Frames + * + * + * + * + * This file was automatically generated by 'framesc' + * Fri Jan 30 11:23:47 2015 from the following file(s): + * + * dot11f.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * + */ + +#if !defined ANI_OS_TYPE_OSX && !defined ANI_OS_TYPE_LINUX && !defined ANI_OS_TYPE_ANDROID +#include /* For memcpy */ +#include /* For _vsnprintf */ +#include /* For offsetof */ +#endif + +#include +#include +#include "dot11fdefs.h" +#include "dot11f.h" + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4244) +# pragma warning (disable: 4505) +# pragma warning (disable: 4702) +# pragma warning (disable: 4996) /* ... was declared deprecated */ +#endif /* Microsoft C/C++ */ + +typedef unsigned char tFRAMES_BOOL; +typedef void (*pfnGeneric_t)(void); + +typedef struct sFFDefn { + const char *name; + tANI_U32 offset; + tANI_U16 sig; + tANI_U8 size; +} tFFDefn; + +typedef struct sIEDefn { + tANI_U32 offset; + tANI_U32 presenceOffset; + tANI_U32 countOffset; + const char *name; + tANI_U16 arraybound; + tANI_U16 minSize; + tANI_U16 maxSize; + tANI_U16 sig; + unsigned char oui[5]; + unsigned char noui; + tANI_U8 eid; + tFRAMES_BOOL fMandatory; +} tIEDefn; + +#if !defined(countof) +#define countof(x) ( sizeof( (x) ) / sizeof( (x)[0] ) ) +#endif + +#if ! defined(DOT11F_MEMCPY) +# define DOT11F_MEMCPY(ctx, dst, src, len) \ + memcpy( (dst), (src), (len) ) \ + +#endif + +#if ! defined(DOT11F_MEMCMP) +# define DOT11F_MEMCMP(ctx, lhs, rhs, len) \ + memcmp( (lhs), (rhs), (len) ) \ + +#endif + +#ifndef DOT11F_HAVE_LOG_SEVERITIES +# define FRLOG_OFF ( 0 ) +# define FRLOGP ( 1 ) +# define FRLOGE ( 2 ) +# define FRLOGW ( 3 ) +# define FRLOG1 ( 4 ) +# define FRLOG2 ( 5 ) +# define FRLOG3 ( 6 ) +# define FRLOG4 ( 7 ) +#endif + +#define FRFL(x) x + +#ifdef DOT11F_ENABLE_LOGGING + +#ifndef DOT11F_HAVE_LOG_MACROS + +#include +#include + +#ifndef DOT11F_LOG_GATE +# define DOT11F_LOG_GATE FRLOGW +#endif // DOT11F_LOG_GATE + +#ifdef WIN32 + +#if defined ( _CONSOLE ) || defined ( _WINDOWS ) || defined ( _DLL ) || defined ( _LIB ) +#include +#define DBGPRINT OutputDebugStringA +#else /* Not User mode */ +#define DBGPRINT DbgPrint +#endif /* User mode */ + +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{ +#ifdef WLAN_DEBUG + va_list val; + char buffer[1024]; + (void)pCtx; + if ( nSev <= DOT11F_LOG_GATE ) + { + va_start(val, lpszFormat); + _vsnprintf(buffer, 1024, lpszFormat, val); + va_end(val); + DBGPRINT(buffer); + } +#endif +} +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +#ifdef WLAN_DEBUG + char buffer[35]; + int i, offset; + pCtx; + offset = 0; + if ( nSev > DOT11F_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + _snprintf(buffer, 35, "%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + DBGPRINT(buffer); + } + _snprintf(buffer, 35, "%08x: ", offset); + DBGPRINT(buffer); + for (i = 0; i < nBuf % 8; ++i) + { + _snprintf(buffer, 35, "%02x ", *pBuf); + ++pBuf; + DBGPRINT(buffer); + } + DBGPRINT("\n"); +#endif +} + +#elif defined OS_X /* Not WIN32 */ +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{// To fill in when needed using IOLog + +} + +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +} + +#elif defined LINUX + +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{ +#ifdef WLAN_DEBUG + va_list marker; + (void)pCtx; + if ( nSev <= DOT11F_LOG_GATE ) + { + va_start( marker, lpszFormat ); + vprintf(lpszFormat, marker); + va_end( marker ); + } +#endif +} + +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +#ifdef WLAN_DEBUG + char buffer[35]; + int i, offset; + (void)pCtx; + offset = 0; + if ( nSev > DOT11F_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + printf("%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + } + printf("%08x: ", offset); + for (i = 0; i < nBuf % 8; ++i) + { + printf("%02x ", *pBuf); + ++pBuf; + } + printf("\n"); +#endif +} + +#endif /* WIN32 */ + +#define FRAMES_LOG0(ctx, sev, fmt) \ + framesLog((ctx), (sev), (fmt)); +#define FRAMES_LOG1(ctx, sev, fmt, p1) \ + framesLog((ctx), (sev), (fmt), (p1)); +#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + framesLog((ctx), (sev), (fmt), (p1), (p2)); +#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + framesLog((ctx), (sev), (fmt), (p1), (p2), (p3)); +#define FRAMES_DUMP(ctx, sev, p, n) \ + framesDump((ctx), (sev), (p), (n)); +#ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +#endif + +#endif /* End DOT11F_HAVE_LOG_MACROS */ + +#else // ! DOT11F_ENABLE_LOGGING +# define FRAMES_LOG0(ctx, sev, fmt) +# define FRAMES_LOG1(ctx, sev, fmt, p1) +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) +# define FRAMES_DUMP(ctx, sev, p, n) +# ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +# endif +#endif // DOT11F_ENABLE_LOGGING + +#if defined( DOT11F_ENABLE_DBG_BREAK ) && defined ( WIN32 ) +# define FRAMES_DBG_BREAK() { _asm int 3 } +#else +# define FRAMES_DBG_BREAK() +#endif + +#if ! defined(DOT11F_PARAMETER_CHECK) +# if defined (DOT11F_HAVE_WIN32_API) + +# define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \ + if (!pBuf || IsBadReadPtr(pBuf, nBuf)) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pFrm || IsBadWritePtr(pFrm, nFrm)) return DOT11F_BAD_OUTPUT_BUFFER \ + +# define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \ + if (!pSrc || IsBadReadPtr(pSrc, 4)) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pBuf || IsBadWritePtr(pBuf, nBuf)) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (IsBadWritePtr(pnConsumed, 4)) return DOT11F_BAD_OUTPUT_BUFFER \ + +# else + +# define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \ + if (!pBuf) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pFrm) return DOT11F_BAD_OUTPUT_BUFFER \ + +# define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \ + if (!pSrc) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!pnConsumed) return DOT11F_BAD_OUTPUT_BUFFER \ + +# endif +#endif + +static void framesntohs(tpAniSirGlobal pCtx, + tANI_U16 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, ( tANI_U16* )pOut, pIn, 2); + } + else + { + *pOut = ( tANI_U16 )( *pIn << 8 ) | *( pIn + 1 ); + } +# else + if ( !fMsb ) + { + *pOut = ( tANI_U16 )( *pIn | ( *( pIn + 1 ) << 8 ) ); + } + else + { + DOT11F_MEMCPY(pCtx, ( tANI_U16* )pOut, pIn, 2); + } +# endif +} + +static void framesntohl(tpAniSirGlobal pCtx, + tANI_U32 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, ( tANI_U32* )pOut, pIn, 4); + } + else + { + *pOut = ( tANI_U32 )( *pIn << 24 ) | + ( *( pIn + 1 ) << 16 ) | + ( *( pIn + 2 ) << 8 ) | + ( *( pIn + 3 ) ); + } +# else + if ( !fMsb ) + { + *pOut = ( tANI_U32 )( *( pIn + 3 ) << 24 ) | + ( *( pIn + 2 ) << 16 ) | + ( *( pIn + 1 ) << 8 ) | + ( *( pIn ) ); + } + else + { + *pOut = * ( tANI_U32* )pIn; + } +# endif +} + +static void framesntohq(tpAniSirGlobal pCtx, + tDOT11F_U64 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + framesntohl( pCtx, &((*pOut)[0]), pIn, fMsb); + framesntohl( pCtx, &((*pOut)[1]), pIn + 4, fMsb); +# else + framesntohl( pCtx, &((*pOut)[1]), pIn, fMsb); + framesntohl( pCtx, &((*pOut)[0]), pIn + 4, fMsb); +# endif +} + +static void frameshtons(tpAniSirGlobal pCtx +, tANI_U8 *pOut, + tANI_U16 pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +# else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } +# endif +} + +static void frameshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +# else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } +# endif +} + +static void frameshtonq(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tDOT11F_U64 pIn, + tFRAMES_BOOL fMsb) +{ +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + frameshtonl( pCtx, pOut, pIn[0], fMsb); + frameshtonl( pCtx, pOut + 4, pIn[1], fMsb); +# else + frameshtonl( pCtx, pOut + 4, pIn[1], fMsb); + frameshtonl( pCtx, pOut, pIn[0], fMsb); +# endif +} +static const tIEDefn* FindIEDefn(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe; + + (void)pCtx; + + pIe = &(IEs[0]); + while (0xff != pIe->eid) + { + if (*pBuf == pIe->eid) + { + if (0 == pIe->noui) return pIe; + + if ( ( nBuf > (tANI_U32)(pIe->noui + 2) ) && + ( !DOT11F_MEMCMP(pCtx, pBuf + 2, pIe->oui, pIe->noui) ) ) + return pIe; + } + + ++pIe; + } + + return NULL; +} + +static tANI_U32 GetContainerIesLen(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U8 *pnConsumed, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe, *pIeFirst; + tANI_U8 *pBufRemaining = pBuf; + tANI_U8 len = 0; + + (void)pCtx; + + pIeFirst = &(IEs[0]); + + if( *pBufRemaining != pIeFirst->eid ) + return DOT11F_INTERNAL_ERROR; + len += *(pBufRemaining+1); + pBufRemaining += len + 2; + len += 2; + while ( len < nBuf ) + { + if( NULL == (pIe = FindIEDefn(pCtx, pBufRemaining, nBuf + len, IEs))) + break; + if( pIe->eid == pIeFirst->eid ) + break; + len += *(pBufRemaining + 1) + 2; + pBufRemaining += *(pBufRemaining + 1) + 2; + } + + *pnConsumed = len; + return DOT11F_PARSE_SUCCESS; + +} + + + +static tANI_U32 UnpackCore(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tFFDefn FFs[], + const tIEDefn IEs[], + tANI_U8 *pFrm, + size_t nFrm); +static tANI_U32 PackCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tFFDefn FFs[], + const tIEDefn IEs[]); +static tANI_U32 GetPackedSizeCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tIEDefn IEs[]); + + +tANI_U32 dot11fUnpackTlvCommonFunc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tANI_U8 *pDstPresent, tANI_U8 *pDstField) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)tlvlen; /* Shutup the compiler */ + + *pDstPresent = 1; + *pDstField = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvCommonFunc. */ + +tANI_U32 dot11fUnpackTlvCommonFunc2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tANI_U8 *pDstPresent, tANI_U16 *pDstState) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)tlvlen; /* Shutup the compiler */ + + *pDstPresent = 1; + framesntohs(pCtx, pDstState, pBuf, 1); + (void)pCtx; + return status; + +} /* End dot11fUnpackTlvCommonFunc2. */ + +void dot11fUnpackFfCommonFunc(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, tANI_U16 *pDstField) +{ + framesntohs(pCtx, pDstField, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfCommonFunc. */ + +tANI_U32 dot11fUnpackIeCommonFunc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, + tANI_U8 *pDstPresent , tANI_U8 *pDstField) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)ielen; + (void)pBuf; + if ((*pDstPresent)) status = DOT11F_DUPLICATE_IE; + *pDstPresent = 1; + *pDstField = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeComonFunc. */ +typedef struct sTLVDefn { + tANI_U32 offset; + tANI_U32 presenceOffset; + const char * name; + tANI_U16 sig; + tANI_U32 id; + tANI_U32 pec; + tANI_U32 minSize; + tANI_U32 maxSize; + tANI_U8 fMandatory; + tANI_U8 sType; + tANI_U8 sLen; + tANI_U8 fMsb; +} tTLVDefn; + +static const tTLVDefn* FindTLVDefn( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ] ) +{ + const tTLVDefn *pTlv; + tANI_U32 pec; + tANI_U16 id; + + pTlv = &( TLVs[ 0 ] ); + (void)pCtx; + if ( pTlv->sType == 2 ) + framesntohs( pCtx, &id, pBuf, 1 ); + else + id = *pBuf; + + while ( 0xffff != pTlv->id ) + { + if ( id == pTlv->id ) + { + if ( 0 == pTlv->pec ) return pTlv; + + if( nBuf > 5 ) + { + pec = ( ( * ( pBuf + 4 ) ) << 16 ) | + ( ( * ( pBuf + 5 ) ) << 8 ) | + * ( pBuf + 6 ); + if ( pec == pTlv->pec ) + { + return pTlv; + } + } + } + + ++pTlv; + } + + return NULL; +} + +static tANI_U32 UnpackTlvCore( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ], + tANI_U8 *pFrm, + size_t nFrm ); +static tANI_U32 PackTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tTLVDefn TLVs[], + tANI_U32 *pidx); +static tANI_U32 GetPackedSizeTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tTLVDefn TLVs[]); + +#define SigFfAID ( 0x0001 ) + +void dot11fUnpackFfAction(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfAction *pDst) +{ + pDst->action = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfAction. */ + +#define SigFfAction ( 0x0002 ) + +void dot11fUnpackFfAddBAParameterSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfAddBAParameterSet *pDst) +{ + tANI_U16 tmp0__; + framesntohs(pCtx, &tmp0__, pBuf, 0); + pDst->amsduSupported = tmp0__ >> 0 & 0x1; + pDst->policy = tmp0__ >> 1 & 0x1; + pDst->tid = tmp0__ >> 2 & 0xf; + pDst->bufferSize = tmp0__ >> 6 & 0x3ff; + (void)pCtx; +} /* End dot11fUnpackFfAddBAParameterSet. */ + +#define SigFfAddBAParameterSet ( 0x0003 ) + +#define SigFfAuthAlgo ( 0x0004 ) + +#define SigFfAuthSeqNo ( 0x0005 ) + +void dot11fUnpackFfBAStartingSequenceControl(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfBAStartingSequenceControl *pDst) +{ + tANI_U16 tmp1__; + framesntohs(pCtx, &tmp1__, pBuf, 0); + pDst->fragNumber = tmp1__ >> 0 & 0xf; + pDst->ssn = tmp1__ >> 4 & 0xfff; + (void)pCtx; +} /* End dot11fUnpackFfBAStartingSequenceControl. */ + +#define SigFfBAStartingSequenceControl ( 0x0006 ) + +#define SigFfBATimeout ( 0x0007 ) + +#define SigFfBeaconInterval ( 0x0008 ) + +void dot11fUnpackFfCapabilities(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCapabilities *pDst) +{ + tANI_U16 tmp2__; + framesntohs(pCtx, &tmp2__, pBuf, 0); + pDst->ess = tmp2__ >> 0 & 0x1; + pDst->ibss = tmp2__ >> 1 & 0x1; + pDst->cfPollable = tmp2__ >> 2 & 0x1; + pDst->cfPollReq = tmp2__ >> 3 & 0x1; + pDst->privacy = tmp2__ >> 4 & 0x1; + pDst->shortPreamble = tmp2__ >> 5 & 0x1; + pDst->pbcc = tmp2__ >> 6 & 0x1; + pDst->channelAgility = tmp2__ >> 7 & 0x1; + pDst->spectrumMgt = tmp2__ >> 8 & 0x1; + pDst->qos = tmp2__ >> 9 & 0x1; + pDst->shortSlotTime = tmp2__ >> 10 & 0x1; + pDst->apsd = tmp2__ >> 11 & 0x1; + pDst->rrm = tmp2__ >> 12 & 0x1; + pDst->dsssOfdm = tmp2__ >> 13 & 0x1; + pDst->delayedBA = tmp2__ >> 14 & 0x1; + pDst->immediateBA = tmp2__ >> 15 & 0x1; + (void)pCtx; +} /* End dot11fUnpackFfCapabilities. */ + +#define SigFfCapabilities ( 0x0009 ) + +void dot11fUnpackFfCategory(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCategory *pDst) +{ + pDst->category = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfCategory. */ + +#define SigFfCategory ( 0x000a ) + +void dot11fUnpackFfCurrentAPAddress(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCurrentAPAddress *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); + (void)pCtx; +} /* End dot11fUnpackFfCurrentAPAddress. */ + +#define SigFfCurrentAPAddress ( 0x000b ) + +void dot11fUnpackFfDelBAParameterSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfDelBAParameterSet *pDst) +{ + tANI_U16 tmp3__; + framesntohs(pCtx, &tmp3__, pBuf, 0); + pDst->reserved = tmp3__ >> 0 & 0x7ff; + pDst->initiator = tmp3__ >> 11 & 0x1; + pDst->tid = tmp3__ >> 12 & 0xf; + (void)pCtx; +} /* End dot11fUnpackFfDelBAParameterSet. */ + +#define SigFfDelBAParameterSet ( 0x000c ) + +void dot11fUnpackFfDialogToken(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfDialogToken *pDst) +{ + pDst->token = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfDialogToken. */ + +#define SigFfDialogToken ( 0x000d ) + +void dot11fUnpackFfLinkMargin(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfLinkMargin *pDst) +{ + pDst->linkMargin = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfLinkMargin. */ + +#define SigFfLinkMargin ( 0x000e ) + +#define SigFfListenInterval ( 0x000f ) + +void dot11fUnpackFfMaxTxPower(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfMaxTxPower *pDst) +{ + pDst->maxTxPower = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfMaxTxPower. */ + +#define SigFfMaxTxPower ( 0x0010 ) + +void dot11fUnpackFfNumOfRepetitions(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfNumOfRepetitions *pDst) +{ + framesntohs(pCtx, &pDst->repetitions, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfNumOfRepetitions. */ + +#define SigFfNumOfRepetitions ( 0x0011 ) + +void dot11fUnpackFfOperatingMode(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfOperatingMode *pDst) +{ + tANI_U8 tmp4__; + tmp4__ = *pBuf; + pDst->chanWidth = tmp4__ >> 0 & 0x3; + pDst->reserved = tmp4__ >> 2 & 0x3; + pDst->rxNSS = tmp4__ >> 4 & 0x7; + pDst->rxNSSType = tmp4__ >> 7 & 0x1; + (void)pCtx; +} /* End dot11fUnpackFfOperatingMode. */ + +#define SigFfOperatingMode ( 0x0012 ) + +void dot11fUnpackFfP2POUI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfP2POUI *pDst) +{ + framesntohl(pCtx, &pDst->oui, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfP2POUI. */ + +#define SigFfP2POUI ( 0x0013 ) + +void dot11fUnpackFfP2POUISubType(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfP2POUISubType *pDst) +{ + pDst->ouiSubtype = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfP2POUISubType. */ + +#define SigFfP2POUISubType ( 0x0014 ) + +void dot11fUnpackFfRCPI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRCPI *pDst) +{ + pDst->rcpi = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRCPI. */ + +#define SigFfRCPI ( 0x0015 ) + +void dot11fUnpackFfRSNI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRSNI *pDst) +{ + pDst->rsni = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRSNI. */ + +#define SigFfRSNI ( 0x0016 ) + +#define SigFfReason ( 0x0017 ) + +void dot11fUnpackFfRxAntennaId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRxAntennaId *pDst) +{ + pDst->antennaId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRxAntennaId. */ + +#define SigFfRxAntennaId ( 0x0018 ) + +void dot11fUnpackFfSMPowerModeSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfSMPowerModeSet *pDst) +{ + tANI_U8 tmp5__; + tmp5__ = *pBuf; + pDst->PowerSave_En = tmp5__ >> 0 & 0x1; + pDst->Mode = tmp5__ >> 1 & 0x1; + pDst->reserved = tmp5__ >> 2 & 0x3f; + (void)pCtx; +} /* End dot11fUnpackFfSMPowerModeSet. */ + +#define SigFfSMPowerModeSet ( 0x0019 ) + +#define SigFfStatus ( 0x001a ) + +void dot11fUnpackFfStatusCode(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfStatusCode *pDst) +{ + pDst->statusCode = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfStatusCode. */ + +#define SigFfStatusCode ( 0x001b ) + +void dot11fUnpackFfTPCEleID(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTPCEleID *pDst) +{ + pDst->TPCId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTPCEleID. */ + +#define SigFfTPCEleID ( 0x001c ) + +void dot11fUnpackFfTPCEleLen(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTPCEleLen *pDst) +{ + pDst->TPCLen = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTPCEleLen. */ + +#define SigFfTPCEleLen ( 0x001d ) + +void dot11fUnpackFfTSInfo(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTSInfo *pDst) +{ + tANI_U32 tmp6__; + framesntohl(pCtx, &tmp6__, pBuf, 0); + pDst->traffic_type = tmp6__ >> 0 & 0x1; + pDst->tsid = tmp6__ >> 1 & 0xf; + pDst->direction = tmp6__ >> 5 & 0x3; + pDst->access_policy = tmp6__ >> 7 & 0x3; + pDst->aggregation = tmp6__ >> 9 & 0x1; + pDst->psb = tmp6__ >> 10 & 0x1; + pDst->user_priority = tmp6__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp6__ >> 14 & 0x3; + pDst->schedule = tmp6__ >> 16 & 0x1; + pDst->unused = tmp6__ >> 17 & 0x7fff; + (void)pCtx; +} /* End dot11fUnpackFfTSInfo. */ + +#define SigFfTSInfo ( 0x001e ) + +void dot11fUnpackFfTimeStamp(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTimeStamp *pDst) +{ + framesntohq(pCtx, &pDst->timestamp, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfTimeStamp. */ + +#define SigFfTimeStamp ( 0x001f ) + +void dot11fUnpackFfTransactionId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTransactionId *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->transId, pBuf, 2); + (void)pCtx; +} /* End dot11fUnpackFfTransactionId. */ + +#define SigFfTransactionId ( 0x0020 ) + +void dot11fUnpackFfTxAntennaId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTxAntennaId *pDst) +{ + pDst->antennaId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTxAntennaId. */ + +#define SigFfTxAntennaId ( 0x0021 ) + +void dot11fUnpackFfTxPower(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTxPower *pDst) +{ + pDst->txPower = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTxPower. */ + +#define SigFfTxPower ( 0x0022 ) + +void dot11fUnpackFfVhtMembershipStatusArray(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfVhtMembershipStatusArray *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->membershipStatusArray, pBuf, 8); + (void)pCtx; +} /* End dot11fUnpackFfVhtMembershipStatusArray. */ + +#define SigFfVhtMembershipStatusArray ( 0x0023 ) + +void dot11fUnpackFfVhtUserPositionArray(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfVhtUserPositionArray *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->userPositionArray, pBuf, 16); + (void)pCtx; +} /* End dot11fUnpackFfVhtUserPositionArray. */ + +#define SigFfVhtUserPositionArray ( 0x0024 ) + +tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVAuthorizedMACs *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvAuthorizedMACs. */ + +#define SigTlvAuthorizedMACs ( 0x0001 ) + + +#define SigTlvRequestToEnroll ( 0x0002 ) + + +tANI_U32 dot11fUnpackTlvVersion2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVersion2 *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp7__; + pDst->present = 1; + tmp7__ = *pBuf; + pBuf += 1; + tlvlen -= 1; + pDst->minor = tmp7__ >> 0 & 0xf; + pDst->major = tmp7__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvVersion2. */ + +#define SigTlvVersion2 ( 0x0003 ) + + +#define SigTlvAPSetupLocked ( 0x0004 ) + + +#define SigTlvAssociationState ( 0x0005 ) + + +tANI_U32 dot11fUnpackTlvChannelList(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVChannelList *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->num_channelList = (tANI_U8)( tlvlen ); + if (tlvlen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvChannelList. */ + +#define SigTlvChannelList ( 0x0006 ) + + +#define SigTlvConfigMethods ( 0x0007 ) + + +#define SigTlvConfigurationError ( 0x0008 ) + + +tANI_U32 dot11fUnpackTlvConfigurationTimeout(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVConfigurationTimeout *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->GOConfigTimeout = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->CLConfigTimeout = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvConfigurationTimeout. */ + +#define SigTlvConfigurationTimeout ( 0x0009 ) + + +tANI_U32 dot11fUnpackTlvDeviceName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVDeviceName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvDeviceName. */ + +#define SigTlvDeviceName ( 0x000a ) + + +#define SigTlvDevicePasswordID ( 0x000b ) + + +tANI_U32 dot11fUnpackTlvExtendedListenTiming(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVExtendedListenTiming *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvExtendedListenTiming. */ + +#define SigTlvExtendedListenTiming ( 0x000c ) + + +#define SigTlvGOIntent ( 0x000d ) + + +tANI_U32 dot11fUnpackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVIntendedP2PInterfaceAddress *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PInterfaceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvIntendedP2PInterfaceAddress. */ + +#define SigTlvIntendedP2PInterfaceAddress ( 0x000e ) + + +#define SigTlvInvitationFlags ( 0x000f ) + + +tANI_U32 dot11fUnpackTlvListenChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVListenChannel *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvListenChannel. */ + +#define SigTlvListenChannel ( 0x0010 ) + + +tANI_U32 dot11fUnpackTlvManufacturer(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVManufacturer *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_name = (tANI_U8)( tlvlen ); + if (tlvlen > 64){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->name, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvManufacturer. */ + +#define SigTlvManufacturer ( 0x0011 ) + + +#define SigTlvMinorReasonCode ( 0x0012 ) + + +tANI_U32 dot11fUnpackTlvModelName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVModelName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvModelName. */ + +#define SigTlvModelName ( 0x0013 ) + + +tANI_U32 dot11fUnpackTlvModelNumber(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVModelNumber *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvModelNumber. */ + +#define SigTlvModelNumber ( 0x0014 ) + + +tANI_U32 dot11fUnpackTlvNoticeOfAbsence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVNoticeOfAbsence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->index = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->CTSWindowOppPS = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->num_NoADesc = (tANI_U8)( tlvlen ); + if (tlvlen > 36){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->NoADesc, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvNoticeOfAbsence. */ + +#define SigTlvNoticeOfAbsence ( 0x0015 ) + + +tANI_U32 dot11fUnpackTlvOperatingChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVOperatingChannel *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvOperatingChannel. */ + +#define SigTlvOperatingChannel ( 0x0016 ) + + +tANI_U32 dot11fUnpackTlvP2PCapability(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PCapability *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->deviceCapability = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->groupCapability = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PCapability. */ + +#define SigTlvP2PCapability ( 0x0017 ) + + +tANI_U32 dot11fUnpackTlvP2PDeviceId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PDeviceId *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PDeviceId. */ + +#define SigTlvP2PDeviceId ( 0x0018 ) + + + static const tTLVDefn TLVS_P2PDeviceInfo[] = { + {offsetof(tDot11fTLVP2PDeviceInfo, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackTlvP2PDeviceInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PDeviceInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->configMethod, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8); + pBuf += 8; + tlvlen -= (tANI_U8)8; + (void)pCtx; + status |= UnpackTlvCore(pCtx, + pBuf, + tlvlen, + TLVS_P2PDeviceInfo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackTlvP2PDeviceInfo. */ + +#define SigTlvP2PDeviceInfo ( 0x0019 ) + + +tANI_U32 dot11fUnpackTlvP2PGroupBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupBssid *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PGroupBssid, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupBssid. */ + +#define SigTlvP2PGroupBssid ( 0x001a ) + + +tANI_U32 dot11fUnpackTlvP2PGroupId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupId *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->deviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + pDst->num_ssid = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupId. */ + +#define SigTlvP2PGroupId ( 0x001b ) + + +tANI_U32 dot11fUnpackTlvP2PGroupInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_P2PClientInfoDesc = (tANI_U8)( tlvlen ); + DOT11F_MEMCPY(pCtx, pDst->P2PClientInfoDesc, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupInfo. */ + +#define SigTlvP2PGroupInfo ( 0x001c ) + + +#define SigTlvP2PStatus ( 0x001d ) + + +tANI_U32 dot11fUnpackTlvPrimaryDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVPrimaryDeviceType *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); + pBuf += 4; + tlvlen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvPrimaryDeviceType. */ + +#define SigTlvPrimaryDeviceType ( 0x001e ) + + +#define SigTlvRFBands ( 0x001f ) + + +tANI_U32 dot11fUnpackTlvRequestDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVRequestDeviceType *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); + pBuf += 4; + tlvlen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvRequestDeviceType. */ + +#define SigTlvRequestDeviceType ( 0x0020 ) + + +#define SigTlvRequestType ( 0x0021 ) + + +#define SigTlvResponseType ( 0x0022 ) + + +#define SigTlvSelectedRegistrar ( 0x0023 ) + + +#define SigTlvSelectedRegistrarConfigMethods ( 0x0024 ) + + +tANI_U32 dot11fUnpackTlvSerialNumber(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVSerialNumber *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvSerialNumber. */ + +#define SigTlvSerialNumber ( 0x0025 ) + + +tANI_U32 dot11fUnpackTlvUUID_E(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVUUID_E *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); + pBuf += 16; + tlvlen -= (tANI_U8)16; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvUUID_E. */ + +#define SigTlvUUID_E ( 0x0026 ) + + +tANI_U32 dot11fUnpackTlvUUID_R(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVUUID_R *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); + pBuf += 16; + tlvlen -= (tANI_U8)16; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvUUID_R. */ + +#define SigTlvUUID_R ( 0x0027 ) + + + static const tTLVDefn TLVS_VendorExtension[] = { + {offsetof(tDot11fTLVVendorExtension, Version2), offsetof(tDot11fTLVVersion2, present), "Version2", SigTlvVersion2, DOT11F_TLV_VERSION2, 0, 3, 3, 0, 1, 1, 1, }, + {offsetof(tDot11fTLVVendorExtension, AuthorizedMACs), offsetof(tDot11fTLVAuthorizedMACs, present), "AuthorizedMACs", SigTlvAuthorizedMACs, DOT11F_TLV_AUTHORIZEDMACS, 0, 8, 8, 0, 1, 1, 1, }, + {offsetof(tDot11fTLVVendorExtension, RequestToEnroll), offsetof(tDot11fTLVRequestToEnroll, present), "RequestToEnroll", SigTlvRequestToEnroll, DOT11F_TLV_REQUESTTOENROLL, 0, 3, 3, 0, 1, 1, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackTlvVendorExtension(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVendorExtension *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + (void)pCtx; + status |= UnpackTlvCore(pCtx, + pBuf, + tlvlen, + TLVS_VendorExtension, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackTlvVendorExtension. */ + +#define SigTlvVendorExtension ( 0x0028 ) + + +tANI_U32 dot11fUnpackTlvVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp8__; + pDst->present = 1; + tmp8__ = *pBuf; + pBuf += 1; + tlvlen -= 1; + pDst->minor = tmp8__ >> 0 & 0xf; + pDst->major = tmp8__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvVersion. */ + +#define SigTlvVersion ( 0x0029 ) + + +#define SigTlvWPSState ( 0x002a ) + + +tANI_U32 dot11fUnpackTlvP2PInterface(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PInterface *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PInterface. */ + +#define SigTlvP2PInterface ( 0x002b ) + + +#define SigTlvP2PManageability ( 0x002c ) + + +tANI_U32 dot11fUnpackIeAPName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAPName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_name = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->name, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAPName. */ + +#define SigIeAPName ( 0x0001 ) + + +tANI_U32 dot11fUnpackIeBPIndicator(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBPIndicator *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->indicator = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->type = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBPIndicator. */ + +#define SigIeBPIndicator ( 0x0002 ) + + +tANI_U32 dot11fUnpackIeCondensedCountryStr(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECondensedCountryStr *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2); + (void)pCtx; + return status; +} /* End dot11fUnpackIeCondensedCountryStr. */ + +#define SigIeCondensedCountryStr ( 0x0003 ) + + +tANI_U32 dot11fUnpackIeGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEGTK *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp9__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp9__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->keyId = tmp9__ >> 0 & 0x3; + pDst->reserved = tmp9__ >> 2 & 0x3feb; + pDst->keyLength = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + pDst->num_key = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->key, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeGTK. */ + +#define SigIeGTK ( 0x0004 ) + + +#define SigIeHCF ( 0x0005 ) + + +tANI_U32 dot11fUnpackIeIGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEIGTK *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->keyLength = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24); + (void)pCtx; + return status; +} /* End dot11fUnpackIeIGTK. */ + +#define SigIeIGTK ( 0x0006 ) + + +tANI_U32 dot11fUnpackIeLLAttr(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELLAttr *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->defer_threshold, pBuf, 1); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLLAttr. */ + +#define SigIeLLAttr ( 0x0007 ) + + +tANI_U32 dot11fUnpackIeLoadBalance(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELoadBalance *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->channel = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeLoadBalance. */ + +#define SigIeLoadBalance ( 0x0008 ) + + +tANI_U32 dot11fUnpackIeLoadInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELoadInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->num_stas, pBuf, 1); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->channel_util, pBuf, 1); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLoadInfo. */ + +#define SigIeLoadInfo ( 0x0009 ) + + +#define SigIePropAssocType ( 0x000a ) + + +tANI_U32 dot11fUnpackIePropCapability(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropCapability *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->capability, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropCapability. */ + +#define SigIePropCapability ( 0x000b ) + + +tANI_U32 dot11fUnpackIePropChannSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropChannSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->mode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->primary_channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->sub_band = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->channel_switch_count = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePropChannSwitchAnn. */ + +#define SigIePropChannSwitchAnn ( 0x000c ) + + +tANI_U32 dot11fUnpackIePropEDCAParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropEDCAParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp10__; + tANI_U8 tmp11__; + tANI_U8 tmp12__; + tANI_U8 tmp13__; + tANI_U8 tmp14__; + tANI_U8 tmp15__; + tANI_U8 tmp16__; + tANI_U8 tmp17__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->qos = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp10__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp10__ >> 0 & 0xf; + pDst->acbe_acm = tmp10__ >> 4 & 0x1; + pDst->acbe_aci = tmp10__ >> 5 & 0x3; + pDst->unused1 = tmp10__ >> 7 & 0x1; + tmp11__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_min = tmp11__ >> 0 & 0xf; + pDst->acbe_max = tmp11__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp12__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp12__ >> 0 & 0xf; + pDst->acbk_acm = tmp12__ >> 4 & 0x1; + pDst->acbk_aci = tmp12__ >> 5 & 0x3; + pDst->unused2 = tmp12__ >> 7 & 0x1; + tmp13__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_min = tmp13__ >> 0 & 0xf; + pDst->acbk_max = tmp13__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp14__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp14__ >> 0 & 0xf; + pDst->acvi_acm = tmp14__ >> 4 & 0x1; + pDst->acvi_aci = tmp14__ >> 5 & 0x3; + pDst->unused3 = tmp14__ >> 7 & 0x1; + tmp15__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_min = tmp15__ >> 0 & 0xf; + pDst->acvi_max = tmp15__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp16__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp16__ >> 0 & 0xf; + pDst->acvo_acm = tmp16__ >> 4 & 0x1; + pDst->acvo_aci = tmp16__ >> 5 & 0x3; + pDst->unused4 = tmp16__ >> 7 & 0x1; + tmp17__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_min = tmp17__ >> 0 & 0xf; + pDst->acvo_max = tmp17__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropEDCAParams. */ + +#define SigIePropEDCAParams ( 0x000d ) + + +tANI_U32 dot11fUnpackIePropQuietBSS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropQuietBSS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->quiet_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->quiet_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->quiet_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->quiet_offset, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropQuietBSS. */ + +#define SigIePropQuietBSS ( 0x000e ) + + +tANI_U32 dot11fUnpackIePropSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropSuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIePropSuppRates. */ + +#define SigIePropSuppRates ( 0x000f ) + + +tANI_U32 dot11fUnpackIeR0KH_ID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIER0KH_ID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_PMK_R0_ID = (tANI_U8)( ielen ); + if (ielen > 48){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->PMK_R0_ID, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeR0KH_ID. */ + +#define SigIeR0KH_ID ( 0x0010 ) + + +tANI_U32 dot11fUnpackIeR1KH_ID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIER1KH_ID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6); + (void)pCtx; + return status; +} /* End dot11fUnpackIeR1KH_ID. */ + +#define SigIeR1KH_ID ( 0x0011 ) + + +tANI_U32 dot11fUnpackIeTSFInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSFInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSFInfo. */ + +#define SigIeTSFInfo ( 0x0012 ) + + +tANI_U32 dot11fUnpackIeTaurus(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETaurus *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp18__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->baTIDBitmap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->baPolicy, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp18__, pBuf, 0); + pDst->baBufferSize = tmp18__ >> 0 & 0xfff; + pDst->rsvd = tmp18__ >> 12 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTaurus. */ + +#define SigIeTaurus ( 0x0013 ) + + +tANI_U32 dot11fUnpackIeTitan(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETitan *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->concat_tcid_bitmap = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->compression_tcid_bitmap = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->cb_state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->rev_fcs_state = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTitan. */ + +#define SigIeTitan ( 0x0014 ) + + +#define SigIeTriggerStaBgScan ( 0x0015 ) + + +tANI_U32 dot11fUnpackIeVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->chip_rev, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + pDst->card_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_build_version = (tANI_U8)( ielen ); + if (ielen > 20){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->build_version, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeVersion. */ + +#define SigIeVersion ( 0x0016 ) + + +tANI_U32 dot11fUnpackIeWDS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWDS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_wdsData = (tANI_U8)( ielen ); + if (ielen > 64){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->wdsData, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWDS. */ + +#define SigIeWDS ( 0x0017 ) + + +tANI_U32 dot11fUnpackIeAPChannelReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAPChannelReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_channelList = (tANI_U8)( ielen ); + if (ielen > 50){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAPChannelReport. */ + +#define SigIeAPChannelReport ( 0x0018 ) + + +tANI_U32 dot11fUnpackIeBcnReportingDetail(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBcnReportingDetail *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->reportingDetail = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBcnReportingDetail. */ + +#define SigIeBcnReportingDetail ( 0x0019 ) + + +tANI_U32 dot11fUnpackIeBeaconReportFrmBody(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBeaconReportFrmBody *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_reportedFields = (tANI_U8)( ielen ); + if (ielen > 224){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->reportedFields, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeBeaconReportFrmBody. */ + +#define SigIeBeaconReportFrmBody ( 0x001a ) + + +tANI_U32 dot11fUnpackIeBeaconReporting(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBeaconReporting *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->reportingCondition = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->threshold = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBeaconReporting. */ + +#define SigIeBeaconReporting ( 0x001b ) + + +tANI_U32 dot11fUnpackIeMeasurementPilot(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementPilot *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->measurementPilot = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vendorSpecific = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementPilot. */ + +#define SigIeMeasurementPilot ( 0x001c ) + + +tANI_U32 dot11fUnpackIeMultiBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMultiBssid *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->maxBSSIDIndicator = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vendorSpecific = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeMultiBssid. */ + +#define SigIeMultiBssid ( 0x001d ) + + +tANI_U32 dot11fUnpackIeRICData(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICData *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->Identifier = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->resourceDescCount = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->statusCode, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRICData. */ + +#define SigIeRICData ( 0x001e ) + + +tANI_U32 dot11fUnpackIeRICDescriptor(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICDescriptor *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->resourceType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_variableData = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->variableData, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRICDescriptor. */ + +#define SigIeRICDescriptor ( 0x001f ) + + +tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERRMEnabledCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp19__; + tANI_U8 tmp20__; + tANI_U8 tmp21__; + tANI_U8 tmp22__; + tANI_U8 tmp23__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp19__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->LinkMeasurement = tmp19__ >> 0 & 0x1; + pDst->NeighborRpt = tmp19__ >> 1 & 0x1; + pDst->parallel = tmp19__ >> 2 & 0x1; + pDst->repeated = tmp19__ >> 3 & 0x1; + pDst->BeaconPassive = tmp19__ >> 4 & 0x1; + pDst->BeaconActive = tmp19__ >> 5 & 0x1; + pDst->BeaconTable = tmp19__ >> 6 & 0x1; + pDst->BeaconRepCond = tmp19__ >> 7 & 0x1; + tmp20__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->FrameMeasurement = tmp20__ >> 0 & 0x1; + pDst->ChannelLoad = tmp20__ >> 1 & 0x1; + pDst->NoiseHistogram = tmp20__ >> 2 & 0x1; + pDst->statistics = tmp20__ >> 3 & 0x1; + pDst->LCIMeasurement = tmp20__ >> 4 & 0x1; + pDst->LCIAzimuth = tmp20__ >> 5 & 0x1; + pDst->TCMCapability = tmp20__ >> 6 & 0x1; + pDst->triggeredTCM = tmp20__ >> 7 & 0x1; + tmp21__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->APChanReport = tmp21__ >> 0 & 0x1; + pDst->RRMMIBEnabled = tmp21__ >> 1 & 0x1; + pDst->operatingChanMax = tmp21__ >> 2 & 0x7; + pDst->nonOperatinChanMax = tmp21__ >> 5 & 0x7; + tmp22__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->MeasurementPilot = tmp22__ >> 0 & 0x7; + pDst->MeasurementPilotEnabled = tmp22__ >> 3 & 0x1; + pDst->NeighborTSFOffset = tmp22__ >> 4 & 0x1; + pDst->RCPIMeasurement = tmp22__ >> 5 & 0x1; + pDst->RSNIMeasurement = tmp22__ >> 6 & 0x1; + pDst->BssAvgAccessDelay = tmp22__ >> 7 & 0x1; + tmp23__ = *pBuf; + pDst->BSSAvailAdmission = tmp23__ >> 0 & 0x1; + pDst->AntennaInformation = tmp23__ >> 1 & 0x1; + pDst->reserved = tmp23__ >> 2 & 0x3f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRRMEnabledCap. */ + +#define SigIeRRMEnabledCap ( 0x0020 ) + + +tANI_U32 dot11fUnpackIeRequestedInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERequestedInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_requested_eids = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->requested_eids, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRequestedInfo. */ + +#define SigIeRequestedInfo ( 0x0021 ) + + +tANI_U32 dot11fUnpackIeSSID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESSID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) + { + status = DOT11F_DUPLICATE_IE; + return status; + } + pDst->present = 1; + pDst->num_ssid = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSSID. */ + +#define SigIeSSID ( 0x0022 ) + + +tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESchedule *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp24__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp24__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->aggregation = tmp24__ >> 0 & 0x1; + pDst->tsid = tmp24__ >> 1 & 0xf; + pDst->direction = tmp24__ >> 5 & 0x3; + pDst->reserved = tmp24__ >> 7 & 0x1ff; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSchedule. */ + +#define SigIeSchedule ( 0x0023 ) + + +tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETCLAS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->user_priority = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_mask = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->info.IpParams.version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 6: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + break; + } + break; + case 2: + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeTCLAS. */ + +#define SigIeTCLAS ( 0x0024 ) + + +#define SigIeTCLASSPROC ( 0x0025 ) + + +tANI_U32 dot11fUnpackIeTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSDelay *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->delay, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSDelay. */ + +#define SigIeTSDelay ( 0x0026 ) + + +tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSPEC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp25__; + tANI_U8 tmp26__; + tANI_U16 tmp27__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp25__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->traffic_type = tmp25__ >> 0 & 0x1; + pDst->tsid = tmp25__ >> 1 & 0xf; + pDst->direction = tmp25__ >> 5 & 0x3; + pDst->access_policy = tmp25__ >> 7 & 0x3; + pDst->aggregation = tmp25__ >> 9 & 0x1; + pDst->psb = tmp25__ >> 10 & 0x1; + pDst->user_priority = tmp25__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp25__ >> 14 & 0x3; + tmp26__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->schedule = tmp26__ >> 0 & 0x1; + pDst->unused = tmp26__ >> 1 & 0x7f; + framesntohs(pCtx, &tmp27__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->size = tmp27__ >> 0 & 0x7fff; + pDst->fixed = tmp27__ >> 15 & 0x1; + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSPEC. */ + +#define SigIeTSPEC ( 0x0027 ) + + +tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMSchedule *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp28__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &tmp28__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->aggregation = tmp28__ >> 0 & 0x1; + pDst->tsid = tmp28__ >> 1 & 0xf; + pDst->direction = tmp28__ >> 5 & 0x3; + pDst->reserved = tmp28__ >> 7 & 0x1ff; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMSchedule. */ + +#define SigIeWMMSchedule ( 0x0028 ) + + +tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTCLAS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->user_priority = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_mask = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->info.IpParams.version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 6: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + break; + } + break; + case 2: + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTCLAS. */ + +#define SigIeWMMTCLAS ( 0x0029 ) + + +tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTCLASPROC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->processing = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTCLASPROC. */ + +#define SigIeWMMTCLASPROC ( 0x002a ) + + +tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTSDelay *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohl(pCtx, &pDst->delay, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTSDelay. */ + +#define SigIeWMMTSDelay ( 0x002b ) + + +tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTSPEC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp29__; + tANI_U8 tmp30__; + tANI_U16 tmp31__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &tmp29__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->traffic_type = tmp29__ >> 0 & 0x1; + pDst->tsid = tmp29__ >> 1 & 0xf; + pDst->direction = tmp29__ >> 5 & 0x3; + pDst->access_policy = tmp29__ >> 7 & 0x3; + pDst->aggregation = tmp29__ >> 9 & 0x1; + pDst->psb = tmp29__ >> 10 & 0x1; + pDst->user_priority = tmp29__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp29__ >> 14 & 0x3; + tmp30__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->tsinfo_rsvd = tmp30__ >> 0 & 0x7f; + pDst->burst_size_defn = tmp30__ >> 7 & 0x1; + framesntohs(pCtx, &tmp31__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->size = tmp31__ >> 0 & 0x7fff; + pDst->fixed = tmp31__ >> 15 & 0x1; + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTSPEC. */ + +#define SigIeWMMTSPEC ( 0x002c ) + + +tANI_U32 dot11fUnpackIeWiderBWChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWiderBWChanSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->newChanWidth = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newCenterChanFreq0 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newCenterChanFreq1 = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWiderBWChanSwitchAnn. */ + +#define SigIeWiderBWChanSwitchAnn ( 0x002d ) + + +tANI_U32 dot11fUnpackIeAID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->assocId, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAID. */ + +#define SigIeAID ( 0x002e ) + + + static const tFFDefn FFS_Airgo[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Airgo[ ] = { + {offsetof(tDot11fIEAirgo, PropSuppRates), offsetof(tDot11fIEPropSuppRates, present), 0, "PropSuppRates" , 0, 3, 14, SigIePropSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPSUPPRATES, 0, }, + {offsetof(tDot11fIEAirgo, APName), offsetof(tDot11fIEAPName, present), 0, "APName" , 0, 3, 34, SigIeAPName, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APNAME, 0, }, + {offsetof(tDot11fIEAirgo, HCF), offsetof(tDot11fIEHCF, present), 0, "HCF" , 0, 3, 3, SigIeHCF, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HCF, 0, }, + {offsetof(tDot11fIEAirgo, WDS), offsetof(tDot11fIEWDS, present), 0, "WDS" , 0, 2, 66, SigIeWDS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WDS, 0, }, + {offsetof(tDot11fIEAirgo, BPIndicator), offsetof(tDot11fIEBPIndicator, present), 0, "BPIndicator" , 0, 4, 4, SigIeBPIndicator, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BPINDICATOR, 0, }, + {offsetof(tDot11fIEAirgo, LoadInfo), offsetof(tDot11fIELoadInfo, present), 0, "LoadInfo" , 0, 6, 6, SigIeLoadInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LOADINFO, 0, }, + {offsetof(tDot11fIEAirgo, LoadBalance), offsetof(tDot11fIELoadBalance, present), 0, "LoadBalance" , 0, 9, 9, SigIeLoadBalance, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LOADBALANCE, 0, }, + {offsetof(tDot11fIEAirgo, PropAssocType), offsetof(tDot11fIEPropAssocType, present), 0, "PropAssocType" , 0, 3, 3, SigIePropAssocType, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPASSOCTYPE, 0, }, + {offsetof(tDot11fIEAirgo, LLAttr), offsetof(tDot11fIELLAttr, present), 0, "LLAttr" , 0, 6, 6, SigIeLLAttr, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LLATTR, 0, }, + {offsetof(tDot11fIEAirgo, PropCapability), offsetof(tDot11fIEPropCapability, present), 0, "PropCapability" , 0, 4, 4, SigIePropCapability, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPCAPABILITY, 0, }, + {offsetof(tDot11fIEAirgo, Version), offsetof(tDot11fIEVersion, present), 0, "Version" , 0, 7, 27, SigIeVersion, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VERSION, 0, }, + {offsetof(tDot11fIEAirgo, PropEDCAParams), offsetof(tDot11fIEPropEDCAParams, present), 0, "PropEDCAParams" , 0, 20, 20, SigIePropEDCAParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPEDCAPARAMS, 0, }, + {offsetof(tDot11fIEAirgo, Titan), offsetof(tDot11fIETitan, present), 0, "Titan" , 0, 6, 6, SigIeTitan, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TITAN, 0, }, + {offsetof(tDot11fIEAirgo, PropChannSwitchAnn), offsetof(tDot11fIEPropChannSwitchAnn, present), 0, "PropChannSwitchAnn" , 0, 6, 6, SigIePropChannSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPCHANNSWITCHANN, 0, }, + {offsetof(tDot11fIEAirgo, PropQuietBSS), offsetof(tDot11fIEPropQuietBSS, present), 0, "PropQuietBSS" , 0, 8, 8, SigIePropQuietBSS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPQUIETBSS, 0, }, + {offsetof(tDot11fIEAirgo, TriggerStaBgScan), offsetof(tDot11fIETriggerStaBgScan, present), 0, "TriggerStaBgScan" , 0, 3, 3, SigIeTriggerStaBgScan, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TRIGGERSTABGSCAN, 0, }, + {offsetof(tDot11fIEAirgo, Taurus), offsetof(tDot11fIETaurus, present), 0, "Taurus" , 0, 8, 8, SigIeTaurus, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TAURUS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeAirgo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAirgo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_Airgo, + IES_Airgo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeAirgo. */ + +#define SigIeAirgo ( 0x002f ) + + +tANI_U32 dot11fUnpackIeCFParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECFParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->cfp_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->cfp_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeCFParams. */ + +#define SigIeCFParams ( 0x0030 ) + + +tANI_U32 dot11fUnpackIeChallengeText(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEChallengeText *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_text = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeChallengeText. */ + +#define SigIeChallengeText ( 0x0031 ) + + +tANI_U32 dot11fUnpackIeChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEChanSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->switchMode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newChannel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->switchCount = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeChanSwitchAnn. */ + +#define SigIeChanSwitchAnn ( 0x0032 ) + + + static const tFFDefn FFS_ChannelSwitchWrapper[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ChannelSwitchWrapper[ ] = { + {offsetof(tDot11fIEChannelSwitchWrapper, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeChannelSwitchWrapper(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEChannelSwitchWrapper *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_ChannelSwitchWrapper, + IES_ChannelSwitchWrapper, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeChannelSwitchWrapper. */ + +#define SigIeChannelSwitchWrapper ( 0x0033 ) + + +tANI_U32 dot11fUnpackIeCountry(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECountry *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + if ( ! ielen ) + { + pDst->num_triplets = 0U; + return 0U; + } + else + { + pDst->num_triplets = (tANI_U8)( ielen / 3 ); + if (ielen > 84 * 3){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->triplets, pBuf, ( ielen ) ); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeCountry. */ + +#define SigIeCountry ( 0x0034 ) + + +#define SigIeDSParams ( 0x0035 ) + + +tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEEDCAParamSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp32__; + tANI_U8 tmp33__; + tANI_U8 tmp34__; + tANI_U8 tmp35__; + tANI_U8 tmp36__; + tANI_U8 tmp37__; + tANI_U8 tmp38__; + tANI_U8 tmp39__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->qos = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp32__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp32__ >> 0 & 0xf; + pDst->acbe_acm = tmp32__ >> 4 & 0x1; + pDst->acbe_aci = tmp32__ >> 5 & 0x3; + pDst->unused1 = tmp32__ >> 7 & 0x1; + tmp33__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_acwmin = tmp33__ >> 0 & 0xf; + pDst->acbe_acwmax = tmp33__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp34__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp34__ >> 0 & 0xf; + pDst->acbk_acm = tmp34__ >> 4 & 0x1; + pDst->acbk_aci = tmp34__ >> 5 & 0x3; + pDst->unused2 = tmp34__ >> 7 & 0x1; + tmp35__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_acwmin = tmp35__ >> 0 & 0xf; + pDst->acbk_acwmax = tmp35__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp36__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp36__ >> 0 & 0xf; + pDst->acvi_acm = tmp36__ >> 4 & 0x1; + pDst->acvi_aci = tmp36__ >> 5 & 0x3; + pDst->unused3 = tmp36__ >> 7 & 0x1; + tmp37__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_acwmin = tmp37__ >> 0 & 0xf; + pDst->acvi_acwmax = tmp37__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp38__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp38__ >> 0 & 0xf; + pDst->acvo_acm = tmp38__ >> 4 & 0x1; + pDst->acvo_aci = tmp38__ >> 5 & 0x3; + pDst->unused4 = tmp38__ >> 7 & 0x1; + tmp39__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_acwmin = tmp39__ >> 0 & 0xf; + pDst->acvo_acwmax = tmp39__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeEDCAParamSet. */ + +#define SigIeEDCAParamSet ( 0x0036 ) + + +tANI_U32 dot11fUnpackIeERPInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEERPInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp40__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp40__ = *pBuf; + pDst->non_erp_present = tmp40__ >> 0 & 0x1; + pDst->use_prot = tmp40__ >> 1 & 0x1; + pDst->barker_preamble = tmp40__ >> 2 & 0x1; + pDst->unused = tmp40__ >> 3 & 0x1f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeERPInfo. */ + +#define SigIeERPInfo ( 0x0037 ) + + +tANI_U32 dot11fUnpackIeESECckmOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESECckmOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 20){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESECckmOpaque. */ + +#define SigIeESECckmOpaque ( 0x0038 ) + + +tANI_U32 dot11fUnpackIeESERadMgmtCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESERadMgmtCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp41__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->mgmt_state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp41__ = *pBuf; + pDst->mbssid_mask = tmp41__ >> 0 & 0x7; + pDst->reserved = tmp41__ >> 3 & 0x1f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESERadMgmtCap. */ + +#define SigIeESERadMgmtCap ( 0x0039 ) + + +tANI_U32 dot11fUnpackIeESETrafStrmMet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETrafStrmMet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tsid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETrafStrmMet. */ + +#define SigIeESETrafStrmMet ( 0x003a ) + + +tANI_U32 dot11fUnpackIeESETrafStrmRateSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETrafStrmRateSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tsid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_tsrates = (tANI_U8)( ielen ); + if (ielen > 8){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->tsrates, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETrafStrmRateSet. */ + +#define SigIeESETrafStrmRateSet ( 0x003b ) + + +tANI_U32 dot11fUnpackIeESETxmitPower(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETxmitPower *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->power_limit = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETxmitPower. */ + +#define SigIeESETxmitPower ( 0x003c ) + + +tANI_U32 dot11fUnpackIeESEVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESEVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESEVersion. */ + +#define SigIeESEVersion ( 0x003d ) + + +tANI_U32 dot11fUnpackIeExtCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEExtCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + + if (!ielen) /* Check to ensure copying of ielen bytes */ + goto endUnpackIeExtCap; + pDst->num_bytes = (tANI_U8)( ielen ); + if (ielen > 9){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bytes, pBuf, ( ielen ) ); + +endUnpackIeExtCap: + (void)pCtx; + return status; +} /* End dot11fUnpackIeExtCap. */ + +#define SigIeExtCap ( 0x003e ) + + +#define SigIeExtChanSwitchAnn ( 0x003f ) + + +tANI_U32 dot11fUnpackIeExtSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEExtSuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIeExtSuppRates. */ + +#define SigIeExtSuppRates ( 0x0040 ) + + +tANI_U32 dot11fUnpackIeFHParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHParamSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->dwell_time, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->hop_set = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->hop_pattern = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->hop_index = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHParamSet. */ + +#define SigIeFHParamSet ( 0x0041 ) + + +tANI_U32 dot11fUnpackIeFHParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->radix = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->nchannels = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHParams. */ + +#define SigIeFHParams ( 0x0042 ) + + +tANI_U32 dot11fUnpackIeFHPattTable(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHPattTable *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->flag = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->nsets = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->modulus = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->offset = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_randtable = (tANI_U8)( ielen ); + if (ielen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->randtable, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHPattTable. */ + +#define SigIeFHPattTable ( 0x0043 ) + + + static const tFFDefn FFS_FTInfo[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_FTInfo[ ] = { + {offsetof(tDot11fIEFTInfo, R1KH_ID), offsetof(tDot11fIER1KH_ID, present), 0, "R1KH_ID" , 0, 8, 8, SigIeR1KH_ID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_R1KH_ID, 0, }, + {offsetof(tDot11fIEFTInfo, GTK), offsetof(tDot11fIEGTK, present), 0, "GTK" , 0, 18, 45, SigIeGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_GTK, 0, }, + {offsetof(tDot11fIEFTInfo, R0KH_ID), offsetof(tDot11fIER0KH_ID, present), 0, "R0KH_ID" , 0, 3, 50, SigIeR0KH_ID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_R0KH_ID, 0, }, + {offsetof(tDot11fIEFTInfo, IGTK), offsetof(tDot11fIEIGTK, present), 0, "IGTK" , 0, 35, 35, SigIeIGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IGTK, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeFTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFTInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp42__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp42__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->reserved = tmp42__ >> 0 & 0xff; + pDst->IECount = tmp42__ >> 8 & 0xff; + DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32); + pBuf += 32; + ielen -= (tANI_U8)32; + DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32); + pBuf += 32; + ielen -= (tANI_U8)32; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_FTInfo, + IES_FTInfo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeFTInfo. */ + +#define SigIeFTInfo ( 0x0044 ) + + +tANI_U32 dot11fUnpackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHT2040BSSCoexistence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp43__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp43__ = *pBuf; + pDst->infoRequest = tmp43__ >> 0 & 0x1; + pDst->fortyMHzIntolerant = tmp43__ >> 1 & 0x1; + pDst->twentyMHzBssWidthReq = tmp43__ >> 2 & 0x1; + pDst->obssScanExemptionReq = tmp43__ >> 3 & 0x1; + pDst->obssScanExemptionGrant = tmp43__ >> 4 & 0x1; + pDst->unused = tmp43__ >> 5 & 0x7; + (void)pCtx; + return status; +} /* End dot11fUnpackIeHT2040BSSCoexistence. */ + +#define SigIeHT2040BSSCoexistence ( 0x0045 ) + + +tANI_U32 dot11fUnpackIeHT2040BSSIntolerantReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHT2040BSSIntolerantReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->operatingClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_channelList = (tANI_U8)( ielen ); + if (ielen > 50){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHT2040BSSIntolerantReport. */ + +#define SigIeHT2040BSSIntolerantReport ( 0x0046 ) + + +tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHTCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp44__; + tANI_U8 tmp45__; + tANI_U16 tmp46__; + tANI_U32 tmp47__; + tANI_U8 tmp48__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp44__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->advCodingCap = tmp44__ >> 0 & 0x1; + pDst->supportedChannelWidthSet = tmp44__ >> 1 & 0x1; + pDst->mimoPowerSave = tmp44__ >> 2 & 0x3; + pDst->greenField = tmp44__ >> 4 & 0x1; + pDst->shortGI20MHz = tmp44__ >> 5 & 0x1; + pDst->shortGI40MHz = tmp44__ >> 6 & 0x1; + pDst->txSTBC = tmp44__ >> 7 & 0x1; + pDst->rxSTBC = tmp44__ >> 8 & 0x3; + pDst->delayedBA = tmp44__ >> 10 & 0x1; + pDst->maximalAMSDUsize = tmp44__ >> 11 & 0x1; + pDst->dsssCckMode40MHz = tmp44__ >> 12 & 0x1; + pDst->psmp = tmp44__ >> 13 & 0x1; + pDst->stbcControlFrame = tmp44__ >> 14 & 0x1; + pDst->lsigTXOPProtection = tmp44__ >> 15 & 0x1; + tmp45__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->maxRxAMPDUFactor = tmp45__ >> 0 & 0x3; + pDst->mpduDensity = tmp45__ >> 2 & 0x7; + pDst->reserved1 = tmp45__ >> 5 & 0x7; + DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &tmp46__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->pco = tmp46__ >> 0 & 0x1; + pDst->transitionTime = tmp46__ >> 1 & 0x3; + pDst->reserved2 = tmp46__ >> 3 & 0x1f; + pDst->mcsFeedback = tmp46__ >> 8 & 0x3; + pDst->reserved3 = tmp46__ >> 10 & 0x3f; + framesntohl(pCtx, &tmp47__, pBuf, 0); + pBuf += 4; + ielen -= 4; + pDst->txBF = tmp47__ >> 0 & 0x1; + pDst->rxStaggeredSounding = tmp47__ >> 1 & 0x1; + pDst->txStaggeredSounding = tmp47__ >> 2 & 0x1; + pDst->rxZLF = tmp47__ >> 3 & 0x1; + pDst->txZLF = tmp47__ >> 4 & 0x1; + pDst->implicitTxBF = tmp47__ >> 5 & 0x1; + pDst->calibration = tmp47__ >> 6 & 0x3; + pDst->explicitCSITxBF = tmp47__ >> 8 & 0x1; + pDst->explicitUncompressedSteeringMatrix = tmp47__ >> 9 & 0x1; + pDst->explicitBFCSIFeedback = tmp47__ >> 10 & 0x7; + pDst->explicitUncompressedSteeringMatrixFeedback = tmp47__ >> 13 & 0x7; + pDst->explicitCompressedSteeringMatrixFeedback = tmp47__ >> 16 & 0x7; + pDst->csiNumBFAntennae = tmp47__ >> 19 & 0x3; + pDst->uncompressedSteeringMatrixBFAntennae = tmp47__ >> 21 & 0x3; + pDst->compressedSteeringMatrixBFAntennae = tmp47__ >> 23 & 0x3; + pDst->reserved4 = tmp47__ >> 25 & 0x7f; + tmp48__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->antennaSelection = tmp48__ >> 0 & 0x1; + pDst->explicitCSIFeedbackTx = tmp48__ >> 1 & 0x1; + pDst->antennaIndicesFeedbackTx = tmp48__ >> 2 & 0x1; + pDst->explicitCSIFeedback = tmp48__ >> 3 & 0x1; + pDst->antennaIndicesFeedback = tmp48__ >> 4 & 0x1; + pDst->rxAS = tmp48__ >> 5 & 0x1; + pDst->txSoundingPPDUs = tmp48__ >> 6 & 0x1; + pDst->reserved5 = tmp48__ >> 7 & 0x1; + pDst->num_rsvd = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHTCaps. */ + +#define SigIeHTCaps ( 0x0047 ) + + +tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHTInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp49__; + tANI_U16 tmp50__; + tANI_U16 tmp51__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->primaryChannel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp49__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->secondaryChannelOffset = tmp49__ >> 0 & 0x3; + pDst->recommendedTxWidthSet = tmp49__ >> 2 & 0x1; + pDst->rifsMode = tmp49__ >> 3 & 0x1; + pDst->controlledAccessOnly = tmp49__ >> 4 & 0x1; + pDst->serviceIntervalGranularity = tmp49__ >> 5 & 0x7; + framesntohs(pCtx, &tmp50__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->opMode = tmp50__ >> 0 & 0x3; + pDst->nonGFDevicesPresent = tmp50__ >> 2 & 0x1; + pDst->transmitBurstLimit = tmp50__ >> 3 & 0x1; + pDst->obssNonHTStaPresent = tmp50__ >> 4 & 0x1; + pDst->reserved = tmp50__ >> 5 & 0x7ff; + framesntohs(pCtx, &tmp51__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->basicSTBCMCS = tmp51__ >> 0 & 0x7f; + pDst->dualCTSProtection = tmp51__ >> 7 & 0x1; + pDst->secondaryBeacon = tmp51__ >> 8 & 0x1; + pDst->lsigTXOPProtectionFullSupport = tmp51__ >> 9 & 0x1; + pDst->pcoActive = tmp51__ >> 10 & 0x1; + pDst->pcoPhase = tmp51__ >> 11 & 0x1; + pDst->reserved2 = tmp51__ >> 12 & 0xf; + DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + pDst->num_rsvd = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHTInfo. */ + +#define SigIeHTInfo ( 0x0048 ) + + +tANI_U32 dot11fUnpackIeIBSSParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEIBSSParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->atim, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeIBSSParams. */ + +#define SigIeIBSSParams ( 0x0049 ) + + +tANI_U32 dot11fUnpackIeLinkIdentifier(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELinkIdentifier *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLinkIdentifier. */ + +#define SigIeLinkIdentifier ( 0x004a ) + + +static const tFFDefn FFS_reportBeacon[ ] = { +{ NULL, 0, 0, 0,}, +}; + +static const tIEDefn IES_reportBeacon[ ] = { + {offsetof(tDot11fIEMeasurementReport, report.Beacon.BeaconReportFrmBody), offsetof(tDot11fIEBeaconReportFrmBody, present), 0, "BeaconReportFrmBody" , 0, 2, 226, SigIeBeaconReportFrmBody, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BEACONREPORTFRMBODY, 0, }, +{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, +}; + +tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp52__; + tANI_U8 tmp53__; + tANI_U8 tmp54__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->token = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp52__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->late = tmp52__ >> 0 & 0x1; + pDst->incapable = tmp52__ >> 1 & 0x1; + pDst->refused = tmp52__ >> 2 & 0x1; + pDst->unused = tmp52__ >> 3 & 0x1f; + pDst->type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if ( ! ielen ) + { + return 0U; + } + else + { + switch (pDst->type) + { + case 0: + pDst->report.Basic.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp53__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->report.Basic.bss = tmp53__ >> 0 & 0x1; + pDst->report.Basic.ofdm_preamble = tmp53__ >> 1 & 0x1; + pDst->report.Basic.unid_signal = tmp53__ >> 2 & 0x1; + pDst->report.Basic.rader = tmp53__ >> 3 & 0x1; + pDst->report.Basic.unmeasured = tmp53__ >> 4 & 0x1; + pDst->report.Basic.unused = tmp53__ >> 5 & 0x7; + break; + case 1: + pDst->report.CCA.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->report.CCA.cca_busy_fraction = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 2: + pDst->report.RPIHistogram.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->report.RPIHistogram.rpi0_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi1_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi2_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi3_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi4_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi5_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi6_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi7_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 5: + pDst->report.Beacon.regClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.Beacon.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp54__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->report.Beacon.condensed_PHY = tmp54__ >> 0 & 0x7f; + pDst->report.Beacon.reported_frame_type = tmp54__ >> 7 & 0x1; + pDst->report.Beacon.RCPI = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.Beacon.RSNI = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->report.Beacon.antenna_id = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_reportBeacon, + IES_reportBeacon, + ( tANI_U8* )pDst, + sizeof(*pDst)); + break; + } + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementReport. */ + +#define SigIeMeasurementReport ( 0x004b ) + + +static const tFFDefn FFS_measurement_requestBeacon[ ] = { +{ NULL, 0, 0, 0,}, +}; + +static const tIEDefn IES_measurement_requestBeacon[ ] = { + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.BeaconReporting), offsetof(tDot11fIEBeaconReporting, present), 0, "BeaconReporting" , 0, 4, 4, SigIeBeaconReporting, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BEACONREPORTING, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.BcnReportingDetail), offsetof(tDot11fIEBcnReportingDetail, present), 0, "BcnReportingDetail" , 0, 3, 3, SigIeBcnReportingDetail, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BCNREPORTINGDETAIL, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.RequestedInfo), offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo" , 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_REQUESTEDINFO, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.APChannelReport), offsetof(tDot11fIEAPChannelReport, present), offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.num_APChannelReport), "APChannelReport" , 2, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, +{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, +}; + +tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementRequest *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp55__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->measurement_token = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp55__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->parallel = tmp55__ >> 0 & 0x1; + pDst->enable = tmp55__ >> 1 & 0x1; + pDst->request = tmp55__ >> 2 & 0x1; + pDst->report = tmp55__ >> 3 & 0x1; + pDst->durationMandatory = tmp55__ >> 4 & 0x1; + pDst->unused = tmp55__ >> 5 & 0x7; + pDst->measurement_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->measurement_type) + { + case 0: + pDst->measurement_request.Basic.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->measurement_request.CCA.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 2: + pDst->measurement_request.RPIHistogram.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 5: + pDst->measurement_request.Beacon.regClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->measurement_request.Beacon.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->measurement_request.Beacon.meas_mode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_measurement_requestBeacon, + IES_measurement_requestBeacon, + ( tANI_U8* )pDst, + sizeof(*pDst)); + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementRequest. */ + +#define SigIeMeasurementRequest ( 0x004c ) + + +tANI_U32 dot11fUnpackIeMobilityDomain(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMobilityDomain *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp56__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->MDID, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp56__ = *pBuf; + pDst->overDSCap = tmp56__ >> 0 & 0x1; + pDst->resourceReqCap = tmp56__ >> 1 & 0x1; + pDst->reserved = tmp56__ >> 2 & 0x3f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeMobilityDomain. */ + +#define SigIeMobilityDomain ( 0x004d ) + + + static const tFFDefn FFS_NeighborReport[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReport[ ] = { + {offsetof(tDot11fIENeighborReport, TSFInfo), offsetof(tDot11fIETSFInfo, present), 0, "TSFInfo" , 0, 6, 6, SigIeTSFInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSFINFO, 0, }, + {offsetof(tDot11fIENeighborReport, CondensedCountryStr), offsetof(tDot11fIECondensedCountryStr, present), 0, "CondensedCountryStr" , 0, 4, 4, SigIeCondensedCountryStr, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CONDENSEDCOUNTRYSTR, 0, }, + {offsetof(tDot11fIENeighborReport, MeasurementPilot), offsetof(tDot11fIEMeasurementPilot, present), 0, "MeasurementPilot" , 0, 3, 258, SigIeMeasurementPilot, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTPILOT, 0, }, + {offsetof(tDot11fIENeighborReport, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fIENeighborReport, MultiBssid), offsetof(tDot11fIEMultiBssid, present), 0, "MultiBssid" , 0, 3, 258, SigIeMultiBssid, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MULTIBSSID, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIENeighborReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp57__; + tANI_U8 tmp58__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + tmp57__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->APReachability = tmp57__ >> 0 & 0x3; + pDst->Security = tmp57__ >> 2 & 0x1; + pDst->KeyScope = tmp57__ >> 3 & 0x1; + pDst->SpecMgmtCap = tmp57__ >> 4 & 0x1; + pDst->QosCap = tmp57__ >> 5 & 0x1; + pDst->apsd = tmp57__ >> 6 & 0x1; + pDst->rrm = tmp57__ >> 7 & 0x1; + tmp58__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->DelayedBA = tmp58__ >> 0 & 0x1; + pDst->ImmBA = tmp58__ >> 1 & 0x1; + pDst->MobilityDomain = tmp58__ >> 2 & 0x1; + pDst->reserved = tmp58__ >> 3 & 0x1f; + framesntohs(pCtx, &pDst->reserved1, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->PhyType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_NeighborReport, + IES_NeighborReport, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeNeighborReport. */ + +#define SigIeNeighborReport ( 0x004e ) + + +tANI_U32 dot11fUnpackIeOBSSScanParameters(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEOBSSScanParameters *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeOBSSScanParameters. */ + +#define SigIeOBSSScanParameters ( 0x004f ) + + +tANI_U32 dot11fUnpackIeOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEOperatingMode *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp59__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp59__ = *pBuf; + pDst->chanWidth = tmp59__ >> 0 & 0x3; + pDst->reserved = tmp59__ >> 2 & 0x3; + pDst->rxNSS = tmp59__ >> 4 & 0x7; + pDst->rxNSSType = tmp59__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeOperatingMode. */ + +#define SigIeOperatingMode ( 0x0050 ) + + + static const tTLVDefn TLVS_P2PAssocReq[ ] = { + {offsetof(tDot11fIEP2PAssocReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PAssocReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PAssocReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PAssocReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PAssocReq. */ + +#define SigIeP2PAssocReq ( 0x0051 ) + + + static const tTLVDefn TLVS_P2PAssocRes[ ] = { + {offsetof(tDot11fIEP2PAssocRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PAssocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PAssocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PAssocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PAssocRes. */ + +#define SigIeP2PAssocRes ( 0x0052 ) + + + static const tTLVDefn TLVS_P2PBeacon[ ] = { + {offsetof(tDot11fIEP2PBeacon, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeacon, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeacon, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PBeacon *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PBeacon,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PBeacon. */ + +#define SigIeP2PBeacon ( 0x0053 ) + + + static const tTLVDefn TLVS_P2PBeaconProbeRes[ ] = { + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PGroupInfo), offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo", SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PBeaconProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PBeaconProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PBeaconProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PBeaconProbeRes. */ + +#define SigIeP2PBeaconProbeRes ( 0x0054 ) + + + static const tTLVDefn TLVS_P2PDeAuth[ ] = { + {offsetof(tDot11fIEP2PDeAuth, MinorReasonCode), offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode", SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeAuth *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeAuth,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeAuth. */ + +#define SigIeP2PDeAuth ( 0x0055 ) + + + static const tTLVDefn TLVS_P2PDeviceDiscoverabilityReq[ ] = { + {offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeviceDiscoverabilityReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeviceDiscoverabilityReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeviceDiscoverabilityReq. */ + +#define SigIeP2PDeviceDiscoverabilityReq ( 0x0056 ) + + + static const tTLVDefn TLVS_P2PDeviceDiscoverabilityRes[ ] = { + {offsetof(tDot11fIEP2PDeviceDiscoverabilityRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeviceDiscoverabilityRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeviceDiscoverabilityRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeviceDiscoverabilityRes. */ + +#define SigIeP2PDeviceDiscoverabilityRes ( 0x0057 ) + + + static const tTLVDefn TLVS_P2PDisAssoc[ ] = { + {offsetof(tDot11fIEP2PDisAssoc, MinorReasonCode), offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode", SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDisAssoc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDisAssoc *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDisAssoc,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDisAssoc. */ + +#define SigIeP2PDisAssoc ( 0x0058 ) + + + static const tTLVDefn TLVS_P2PGONegCnf[ ] = { + {offsetof(tDot11fIEP2PGONegCnf, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegCnf *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegCnf,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegCnf. */ + +#define SigIeP2PGONegCnf ( 0x0059 ) + + + static const tTLVDefn TLVS_P2PGONegReq[ ] = { + {offsetof(tDot11fIEP2PGONegReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, GOIntent), offsetof(tDot11fTLVGOIntent, present), "GOIntent", SigTlvGOIntent, DOT11F_TLV_GOINTENT, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ListenChannel), offsetof(tDot11fTLVListenChannel, present), "ListenChannel", SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, IntendedP2PInterfaceAddress), offsetof(tDot11fTLVIntendedP2PInterfaceAddress, present), "IntendedP2PInterfaceAddress", SigTlvIntendedP2PInterfaceAddress, DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegReq. */ + +#define SigIeP2PGONegReq ( 0x005a ) + + + static const tTLVDefn TLVS_P2PGONegRes[ ] = { + {offsetof(tDot11fIEP2PGONegRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, GOIntent), offsetof(tDot11fTLVGOIntent, present), "GOIntent", SigTlvGOIntent, DOT11F_TLV_GOINTENT, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, IntendedP2PInterfaceAddress), offsetof(tDot11fTLVIntendedP2PInterfaceAddress, present), "IntendedP2PInterfaceAddress", SigTlvIntendedP2PInterfaceAddress, DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegRes. */ + +#define SigIeP2PGONegRes ( 0x005b ) + + + static const tTLVDefn TLVS_P2PGONegWPS[ ] = { + {offsetof(tDot11fIEP2PGONegWPS, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEP2PGONegWPS, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegWPS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegWPS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegWPS,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegWPS. */ + +#define SigIeP2PGONegWPS ( 0x005c ) + + +tANI_U32 dot11fUnpackIeP2PIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeP2PIEOpaque. */ + +#define SigIeP2PIEOpaque ( 0x005d ) + + + static const tTLVDefn TLVS_P2PInvitationReq[ ] = { + {offsetof(tDot11fIEP2PInvitationReq, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, InvitationFlags), offsetof(tDot11fTLVInvitationFlags, present), "InvitationFlags", SigTlvInvitationFlags, DOT11F_TLV_INVITATIONFLAGS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PGroupBssid), offsetof(tDot11fTLVP2PGroupBssid, present), "P2PGroupBssid", SigTlvP2PGroupBssid, DOT11F_TLV_P2PGROUPBSSID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PInvitationReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PInvitationReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PInvitationReq. */ + +#define SigIeP2PInvitationReq ( 0x005e ) + + + static const tTLVDefn TLVS_P2PInvitationRes[ ] = { + {offsetof(tDot11fIEP2PInvitationRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, P2PGroupBssid), offsetof(tDot11fTLVP2PGroupBssid, present), "P2PGroupBssid", SigTlvP2PGroupBssid, DOT11F_TLV_P2PGROUPBSSID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PInvitationRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PInvitationRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PInvitationRes. */ + +#define SigIeP2PInvitationRes ( 0x005f ) + + + static const tTLVDefn TLVS_P2PNoticeOfAbsence[ ] = { + {offsetof(tDot11fIEP2PNoticeOfAbsence, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PNoticeOfAbsence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PNoticeOfAbsence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PNoticeOfAbsence,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PNoticeOfAbsence. */ + +#define SigIeP2PNoticeOfAbsence ( 0x0060 ) + + + static const tTLVDefn TLVS_P2PPresenceResponse[ ] = { + {offsetof(tDot11fIEP2PPresenceResponse, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PPresenceResponse, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PPresenceResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PPresenceResponse *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PPresenceResponse,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PPresenceResponse. */ + +#define SigIeP2PPresenceResponse ( 0x0061 ) + + + static const tTLVDefn TLVS_P2PProbeReq[ ] = { + {offsetof(tDot11fIEP2PProbeReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, ListenChannel), offsetof(tDot11fTLVListenChannel, present), "ListenChannel", SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProbeReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProbeReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProbeReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProbeReq. */ + +#define SigIeP2PProbeReq ( 0x0062 ) + + + static const tTLVDefn TLVS_P2PProbeRes[ ] = { + {offsetof(tDot11fIEP2PProbeRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, P2PGroupInfo), offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo", SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProbeRes. */ + +#define SigIeP2PProbeRes ( 0x0063 ) + + + static const tTLVDefn TLVS_P2PProvisionDiscoveryReq[ ] = { + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProvisionDiscoveryReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProvisionDiscoveryReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProvisionDiscoveryReq. */ + +#define SigIeP2PProvisionDiscoveryReq ( 0x0064 ) + + + static const tTLVDefn TLVS_P2PWSCProvisionDiscoveryRes[ ] = { + {offsetof(tDot11fIEP2PWSCProvisionDiscoveryRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PWSCProvisionDiscoveryRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PWSCProvisionDiscoveryRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PWSCProvisionDiscoveryRes. */ + +#define SigIeP2PWSCProvisionDiscoveryRes ( 0x0065 ) + + +tANI_U32 dot11fUnpackIePTIControl(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPTIControl *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->sequence_control, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePTIControl. */ + +#define SigIePTIControl ( 0x0066 ) + + +tANI_U32 dot11fUnpackIePUBufferStatus(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPUBufferStatus *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp60__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp60__ = *pBuf; + pDst->ac_bk_traffic_aval = tmp60__ >> 0 & 0x1; + pDst->ac_be_traffic_aval = tmp60__ >> 1 & 0x1; + pDst->ac_vi_traffic_aval = tmp60__ >> 2 & 0x1; + pDst->ac_vo_traffic_aval = tmp60__ >> 3 & 0x1; + pDst->reserved = tmp60__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePUBufferStatus. */ + +#define SigIePUBufferStatus ( 0x0067 ) + + +tANI_U32 dot11fUnpackIePowerCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPowerCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->minTxPower = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->maxTxPower = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePowerCaps. */ + +#define SigIePowerCaps ( 0x0068 ) + + +tANI_U32 dot11fUnpackIePowerConstraints(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPowerConstraints *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->localPowerConstraints = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePowerConstraints. */ + +#define SigIePowerConstraints ( 0x0069 ) + + +tANI_U32 dot11fUnpackIeQBSSLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQBSSLoad *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->stacount, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->chautil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->avail, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQBSSLoad. */ + +#define SigIeQBSSLoad ( 0x006a ) + + +tANI_U32 dot11fUnpackIeQOSCapsAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQOSCapsAp *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp61__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp61__ = *pBuf; + pDst->count = tmp61__ >> 0 & 0xf; + pDst->qack = tmp61__ >> 4 & 0x1; + pDst->qreq = tmp61__ >> 5 & 0x1; + pDst->txopreq = tmp61__ >> 6 & 0x1; + pDst->reserved = tmp61__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeQOSCapsAp. */ + +#define SigIeQOSCapsAp ( 0x006b ) + + +tANI_U32 dot11fUnpackIeQOSCapsStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQOSCapsStation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp62__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp62__ = *pBuf; + pDst->acvo_uapsd = tmp62__ >> 0 & 0x1; + pDst->acvi_uapsd = tmp62__ >> 1 & 0x1; + pDst->acbk_uapsd = tmp62__ >> 2 & 0x1; + pDst->acbe_uapsd = tmp62__ >> 3 & 0x1; + pDst->qack = tmp62__ >> 4 & 0x1; + pDst->max_sp_length = tmp62__ >> 5 & 0x3; + pDst->more_data_ack = tmp62__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeQOSCapsStation. */ + +#define SigIeQOSCapsStation ( 0x006c ) + + +tANI_U32 dot11fUnpackIeQosMapSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQosMapSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_dscp_exceptions = (tANI_U8)( ielen ); + if (ielen > 60){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->dscp_exceptions, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQosMapSet. */ + +#define SigIeQosMapSet ( 0x006d ) + + +tANI_U32 dot11fUnpackIeQuiet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQuiet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->offset, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQuiet. */ + +#define SigIeQuiet ( 0x006e ) + + +tANI_U32 dot11fUnpackIeRCPIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERCPIIE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->rcpi = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRCPIIE. */ + +#define SigIeRCPIIE ( 0x006f ) + + + static const tFFDefn FFS_RICDataDesc[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RICDataDesc[ ] = { + {offsetof(tDot11fIERICDataDesc, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 1, }, + {offsetof(tDot11fIERICDataDesc, RICDescriptor), offsetof(tDot11fIERICDescriptor, present), 0, "RICDescriptor" , 0, 3, 258, SigIeRICDescriptor, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDESCRIPTOR, 0, }, + {offsetof(tDot11fIERICDataDesc, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 0, }, + {offsetof(tDot11fIERICDataDesc, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fIERICDataDesc, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fIERICDataDesc, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fIERICDataDesc, TSDelay), offsetof(tDot11fIETSDelay, present), 0, "TSDelay" , 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSDELAY, 0, }, + {offsetof(tDot11fIERICDataDesc, Schedule), offsetof(tDot11fIESchedule, present), 0, "Schedule" , 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SCHEDULE, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fIERICDataDesc, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTSDelay), offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay" , 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8}, 5, DOT11F_EID_WMMTSDELAY, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMSchedule), offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule" , 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9}, 5, DOT11F_EID_WMMSCHEDULE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeRICDataDesc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICDataDesc *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_RICDataDesc, + IES_RICDataDesc, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeRICDataDesc. */ + +#define SigIeRICDataDesc ( 0x0070 ) + + +tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSN *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + if ( ! ielen ) + { + pDst->pwise_cipher_suite_count = 0U; + pDst->akm_suite_count = 0U; + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->pwise_cipher_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->pwise_cipher_suites, pBuf, ( pDst->pwise_cipher_suite_count * 4 ) ); + pBuf += ( pDst->pwise_cipher_suite_count * 4 ); + ielen -= ( pDst->pwise_cipher_suite_count * 4 ); + if ( ! ielen ) + { + pDst->akm_suite_count = 0U; + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->akm_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) ); + pBuf += ( pDst->akm_suite_count * 4 ); + ielen -= ( pDst->akm_suite_count * 4 ); + if ( ! ielen ) + { + pDst->pmkid_count = 0U; + return 0U; + } + else + { + DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if ( ! ielen ) + { + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->pmkid_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->pmkid, pBuf, ( pDst->pmkid_count * 16 ) ); + pBuf += ( pDst->pmkid_count * 16 ); + ielen -= ( pDst->pmkid_count * 16 ); + if ( ! ielen ) + { + return 0U; + } + else + { + DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSN. */ + +#define SigIeRSN ( 0x0071 ) + + +tANI_U32 dot11fUnpackIeRSNIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSNIIE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->rsni = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSNIIE. */ + +#define SigIeRSNIIE ( 0x0072 ) + + +tANI_U32 dot11fUnpackIeRSNOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSNOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSNOpaque. */ + +#define SigIeRSNOpaque ( 0x0073 ) + + +tANI_U32 dot11fUnpackIeSuppChannels(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppChannels *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_bands = (tANI_U8)( ielen / 2 ); + if (ielen > 48 * 2){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bands, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppChannels. */ + +#define SigIeSuppChannels ( 0x0074 ) + + +tANI_U32 dot11fUnpackIeSuppOperatingClasses(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppOperatingClasses *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_classes = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->classes, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppOperatingClasses. */ + +#define SigIeSuppOperatingClasses ( 0x0075 ) + + +tANI_U32 dot11fUnpackIeSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppRates. */ + +#define SigIeSuppRates ( 0x0076 ) + + +tANI_U32 dot11fUnpackIeTIM(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETIM *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->dtim_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->dtim_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->bmpctl = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vbmp = (tANI_U8)( ielen ); + if (ielen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->vbmp, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTIM. */ + +#define SigIeTIM ( 0x0077 ) + + +tANI_U32 dot11fUnpackIeTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETPCReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tx_power = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->link_margin = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTPCReport. */ + +#define SigIeTPCReport ( 0x0078 ) + + +tANI_U32 dot11fUnpackIeTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETPCRequest *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTPCRequest. */ + +#define SigIeTPCRequest ( 0x0079 ) + + +tANI_U32 dot11fUnpackIeTimeoutInterval(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETimeoutInterval *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->timeoutType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTimeoutInterval. */ + +#define SigIeTimeoutInterval ( 0x007a ) + + +tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 tmp63__; + tANI_U16 tmp64__; + tANI_U16 tmp65__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &tmp63__, pBuf, 0); + pBuf += 4; + ielen -= 4; + pDst->maxMPDULen = tmp63__ >> 0 & 0x3; + pDst->supportedChannelWidthSet = tmp63__ >> 2 & 0x3; + pDst->ldpcCodingCap = tmp63__ >> 4 & 0x1; + pDst->shortGI80MHz = tmp63__ >> 5 & 0x1; + pDst->shortGI160and80plus80MHz = tmp63__ >> 6 & 0x1; + pDst->txSTBC = tmp63__ >> 7 & 0x1; + pDst->rxSTBC = tmp63__ >> 8 & 0x7; + pDst->suBeamFormerCap = tmp63__ >> 11 & 0x1; + pDst->suBeamformeeCap = tmp63__ >> 12 & 0x1; + pDst->csnofBeamformerAntSup = tmp63__ >> 13 & 0x7; + pDst->numSoundingDim = tmp63__ >> 16 & 0x7; + pDst->muBeamformerCap = tmp63__ >> 19 & 0x1; + pDst->muBeamformeeCap = tmp63__ >> 20 & 0x1; + pDst->vhtTXOPPS = tmp63__ >> 21 & 0x1; + pDst->htcVHTCap = tmp63__ >> 22 & 0x1; + pDst->maxAMPDULenExp = tmp63__ >> 23 & 0x7; + pDst->vhtLinkAdaptCap = tmp63__ >> 26 & 0x3; + pDst->rxAntPattern = tmp63__ >> 28 & 0x1; + pDst->txAntPattern = tmp63__ >> 29 & 0x1; + pDst->reserved1 = tmp63__ >> 30 & 0x3; + framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp64__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->rxHighSupDataRate = tmp64__ >> 0 & 0x1fff; + pDst->reserved2 = tmp64__ >> 13 & 0x7; + framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp65__, pBuf, 0); + pDst->txSupDataRate = tmp65__ >> 0 & 0x1fff; + pDst->reserved3 = tmp65__ >> 13 & 0x7; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTCaps. */ + +#define SigIeVHTCaps ( 0x007b ) + + +tANI_U32 dot11fUnpackIeVHTExtBssLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTExtBssLoad *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->muMIMOCapStaCount = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->ssUnderUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->FortyMHzUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->EightyMHzUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->OneSixtyMHzUtil = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTExtBssLoad. */ + +#define SigIeVHTExtBssLoad ( 0x007c ) + + +tANI_U32 dot11fUnpackIeVHTOperation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTOperation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->chanWidth = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->chanCenterFreqSeg1 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->chanCenterFreqSeg2 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTOperation. */ + +#define SigIeVHTOperation ( 0x007d ) + + +tANI_U32 dot11fUnpackIeVendor1IE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVendor1IE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVendor1IE. */ + +#define SigIeVendor1IE ( 0x007e ) + + +tANI_U32 dot11fUnpackIeVendor2IE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVendor2IE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVendor2IE. */ + +#define SigIeVendor2IE ( 0x007f ) + + +tANI_U32 dot11fUnpackIeVendor3IE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVendor3IE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVendor3IE. */ + +#define SigIeVendor3IE ( 0x0080 ) + + +tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWAPI *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp66__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->akm_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) ); + pBuf += ( pDst->akm_suite_count * 4 ); + ielen -= ( pDst->akm_suite_count * 4 ); + framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->unicast_cipher_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, ( pDst->unicast_cipher_suite_count * 4 ) ); + pBuf += ( pDst->unicast_cipher_suite_count * 4 ); + ielen -= ( pDst->unicast_cipher_suite_count * 4 ); + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &tmp66__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->preauth = tmp66__ >> 0 & 0x1; + pDst->reserved = tmp66__ >> 1 & 0x7fff; + if ( ! ielen ) + { + pDst->bkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->bkid_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->bkid_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bkid, pBuf, ( pDst->bkid_count * 16 ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWAPI. */ + +#define SigIeWAPI ( 0x0081 ) + + +tANI_U32 dot11fUnpackIeWAPIOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWAPIOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWAPIOpaque. */ + +#define SigIeWAPIOpaque ( 0x0082 ) + + +tANI_U32 dot11fUnpackIeWFATPC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWFATPC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->txPower = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->linkMargin = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWFATPC. */ + +#define SigIeWFATPC ( 0x0083 ) + + +tANI_U32 dot11fUnpackIeWFDIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWFDIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWFDIEOpaque. */ + +#define SigIeWFDIEOpaque ( 0x0084 ) + + +tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp67__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + tmp67__ = *pBuf; + pDst->reserved = tmp67__ >> 0 & 0xf; + pDst->qack = tmp67__ >> 4 & 0x1; + pDst->queue_request = tmp67__ >> 5 & 0x1; + pDst->txop_request = tmp67__ >> 6 & 0x1; + pDst->more_ack = tmp67__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMCaps. */ + +#define SigIeWMMCaps ( 0x0085 ) + + +tANI_U32 dot11fUnpackIeWMMInfoAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMInfoAp *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp68__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp68__ = *pBuf; + pDst->param_set_count = tmp68__ >> 0 & 0xf; + pDst->reserved = tmp68__ >> 4 & 0x7; + pDst->uapsd = tmp68__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMInfoAp. */ + +#define SigIeWMMInfoAp ( 0x0086 ) + + +tANI_U32 dot11fUnpackIeWMMInfoStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMInfoStation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp69__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp69__ = *pBuf; + pDst->acvo_uapsd = tmp69__ >> 0 & 0x1; + pDst->acvi_uapsd = tmp69__ >> 1 & 0x1; + pDst->acbk_uapsd = tmp69__ >> 2 & 0x1; + pDst->acbe_uapsd = tmp69__ >> 3 & 0x1; + pDst->reserved1 = tmp69__ >> 4 & 0x1; + pDst->max_sp_length = tmp69__ >> 5 & 0x3; + pDst->reserved2 = tmp69__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMInfoStation. */ + +#define SigIeWMMInfoStation ( 0x0087 ) + + +tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp70__; + tANI_U8 tmp71__; + tANI_U8 tmp72__; + tANI_U8 tmp73__; + tANI_U8 tmp74__; + tANI_U8 tmp75__; + tANI_U8 tmp76__; + tANI_U8 tmp77__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->qosInfo = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved2 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp70__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp70__ >> 0 & 0xf; + pDst->acbe_acm = tmp70__ >> 4 & 0x1; + pDst->acbe_aci = tmp70__ >> 5 & 0x3; + pDst->unused1 = tmp70__ >> 7 & 0x1; + tmp71__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_acwmin = tmp71__ >> 0 & 0xf; + pDst->acbe_acwmax = tmp71__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp72__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp72__ >> 0 & 0xf; + pDst->acbk_acm = tmp72__ >> 4 & 0x1; + pDst->acbk_aci = tmp72__ >> 5 & 0x3; + pDst->unused2 = tmp72__ >> 7 & 0x1; + tmp73__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_acwmin = tmp73__ >> 0 & 0xf; + pDst->acbk_acwmax = tmp73__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp74__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp74__ >> 0 & 0xf; + pDst->acvi_acm = tmp74__ >> 4 & 0x1; + pDst->acvi_aci = tmp74__ >> 5 & 0x3; + pDst->unused3 = tmp74__ >> 7 & 0x1; + tmp75__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_acwmin = tmp75__ >> 0 & 0xf; + pDst->acvi_acwmax = tmp75__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp76__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp76__ >> 0 & 0xf; + pDst->acvo_acm = tmp76__ >> 4 & 0x1; + pDst->acvo_aci = tmp76__ >> 5 & 0x3; + pDst->unused4 = tmp76__ >> 7 & 0x1; + tmp77__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_acwmin = tmp77__ >> 0 & 0xf; + pDst->acvo_acwmax = tmp77__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMParams. */ + +#define SigIeWMMParams ( 0x0088 ) + + +tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWPA *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + if ( ! ielen ) + { + pDst->multicast_cipher_present = 0U; + pDst->unicast_cipher_count = 0U; + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + pDst->multicast_cipher_present = 1U; + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + } + if ( ! ielen ) + { + pDst->unicast_cipher_count = 0U; + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->unicast_cipher_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->unicast_ciphers, pBuf, ( pDst->unicast_cipher_count * 4 ) ); + pBuf += ( pDst->unicast_cipher_count * 4 ); + ielen -= ( pDst->unicast_cipher_count * 4 ); + if ( ! ielen ) + { + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->auth_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->auth_suites, pBuf, ( pDst->auth_suite_count * 4 ) ); + pBuf += ( pDst->auth_suite_count * 4 ); + ielen -= ( pDst->auth_suite_count * 4 ); + if ( ! ielen ) + { + return 0U; + } + else + { + framesntohs(pCtx, &pDst->caps, pBuf, 0); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeWPA. */ + +#define SigIeWPA ( 0x0089 ) + + +tANI_U32 dot11fUnpackIeWPAOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWPAOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWPAOpaque. */ + +#define SigIeWPAOpaque ( 0x008a ) + + + static const tTLVDefn TLVS_WSC[ ] = { + {offsetof(tDot11fIEWSC, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, UUID_R), offsetof(tDot11fTLVUUID_R, present), "UUID_R", SigTlvUUID_R, DOT11F_TLV_UUID_R, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, AssociationState), offsetof(tDot11fTLVAssociationState, present), "AssociationState", SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ConfigurationError), offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError", SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RequestDeviceType), offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType", SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWSC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWSC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WSC,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWSC. */ + +#define SigIeWSC ( 0x008b ) + + + static const tTLVDefn TLVS_WscAssocReq[ ] = { + {offsetof(tDot11fIEWscAssocReq, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocReq, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocReq, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscAssocReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscAssocReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscAssocReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscAssocReq. */ + +#define SigIeWscAssocReq ( 0x008c ) + + + static const tTLVDefn TLVS_WscAssocRes[ ] = { + {offsetof(tDot11fIEWscAssocRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscAssocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscAssocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscAssocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscAssocRes. */ + +#define SigIeWscAssocRes ( 0x008d ) + + + static const tTLVDefn TLVS_WscBeacon[ ] = { + {offsetof(tDot11fIEWscBeacon, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscBeacon *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscBeacon,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscBeacon. */ + +#define SigIeWscBeacon ( 0x008e ) + + + static const tTLVDefn TLVS_WscBeaconProbeRes[ ] = { + {offsetof(tDot11fIEWscBeaconProbeRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscBeaconProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscBeaconProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscBeaconProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscBeaconProbeRes. */ + +#define SigIeWscBeaconProbeRes ( 0x008f ) + + +tANI_U32 dot11fUnpackIeWscIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWscIEOpaque. */ + +#define SigIeWscIEOpaque ( 0x0090 ) + + + static const tTLVDefn TLVS_WscProbeReq[ ] = { + {offsetof(tDot11fIEWscProbeReq, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, AssociationState), offsetof(tDot11fTLVAssociationState, present), "AssociationState", SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ConfigurationError), offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError", SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RequestDeviceType), offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType", SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscProbeReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscProbeReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscProbeReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscProbeReq. */ + +#define SigIeWscProbeReq ( 0x0091 ) + + + static const tTLVDefn TLVS_WscProbeRes[ ] = { + {offsetof(tDot11fIEWscProbeRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscProbeRes. */ + +#define SigIeWscProbeRes ( 0x0092 ) + + + static const tTLVDefn TLVS_WscReassocRes[ ] = { + {offsetof(tDot11fIEWscReassocRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscReassocRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscReassocRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscReassocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscReassocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscReassocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscReassocRes. */ + +#define SigIeWscReassocRes ( 0x0093 ) + + + static const tFFDefn FFS_AddBAReq[] = { + { "Category", offsetof(tDot11fAddBAReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddBAReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddBAReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "AddBAParameterSet", offsetof(tDot11fAddBAReq, AddBAParameterSet), SigFfAddBAParameterSet , DOT11F_FF_ADDBAPARAMETERSET_LEN, }, + { "BATimeout", offsetof(tDot11fAddBAReq, BATimeout), SigFfBATimeout , DOT11F_FF_BATIMEOUT_LEN, }, + { "BAStartingSequenceControl", offsetof(tDot11fAddBAReq, BAStartingSequenceControl), SigFfBAStartingSequenceControl , DOT11F_FF_BASTARTINGSEQUENCECONTROL_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddBAReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddBAReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBAReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddBAReq, IES_AddBAReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Unpacked the AddBAReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BAStartingSequenceControl:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("fragNumber (4): %d\n"), pFrm->BAStartingSequenceControl.fragNumber); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("ssn (12): %d\n"), pFrm->BAStartingSequenceControl.ssn); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBAReq. */ + + static const tFFDefn FFS_AddBARsp[] = { + { "Category", offsetof(tDot11fAddBARsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddBARsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddBARsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Status", offsetof(tDot11fAddBARsp, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AddBAParameterSet", offsetof(tDot11fAddBARsp, AddBAParameterSet), SigFfAddBAParameterSet , DOT11F_FF_ADDBAPARAMETERSET_LEN, }, + { "BATimeout", offsetof(tDot11fAddBARsp, BATimeout), SigFfBATimeout , DOT11F_FF_BATIMEOUT_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddBARsp[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddBARsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBARsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddBARsp, IES_AddBARsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Unpacked the AddBARsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBARsp. */ + + static const tFFDefn FFS_AddTSRequest[] = { + { "Category", offsetof(tDot11fAddTSRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddTSRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddTSRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddTSRequest[] = { + {offsetof(tDot11fAddTSRequest, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 1, }, + {offsetof(tDot11fAddTSRequest, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fAddTSRequest, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fAddTSRequest, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fAddTSRequest, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fAddTSRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddTSRequest, IES_AddTSRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Unpacked the AddTSRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSRequest. */ + + static const tFFDefn FFS_AddTSResponse[] = { + { "Category", offsetof(tDot11fAddTSResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddTSResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddTSResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Status", offsetof(tDot11fAddTSResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddTSResponse[] = { + {offsetof(tDot11fAddTSResponse, TSDelay), offsetof(tDot11fIETSDelay, present), 0, "TSDelay" , 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSDELAY, 1, }, + {offsetof(tDot11fAddTSResponse, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 1, }, + {offsetof(tDot11fAddTSResponse, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fAddTSResponse, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fAddTSResponse, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fAddTSResponse, Schedule), offsetof(tDot11fIESchedule, present), 0, "Schedule" , 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SCHEDULE, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTSDelay), offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay" , 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8}, 5, DOT11F_EID_WMMTSDELAY, 0, }, + {offsetof(tDot11fAddTSResponse, WMMSchedule), offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule" , 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9}, 5, DOT11F_EID_WMMSCHEDULE, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fAddTSResponse, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fAddTSResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddTSResponse, IES_AddTSResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Unpacked the AddTSResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSResponse. */ + + static const tFFDefn FFS_AssocRequest[] = { + { "Capabilities", offsetof(tDot11fAssocRequest, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "ListenInterval", offsetof(tDot11fAssocRequest, ListenInterval), SigFfListenInterval , DOT11F_FF_LISTENINTERVAL_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AssocRequest[] = { + {offsetof(tDot11fAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fAssocRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fAssocRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps" , 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCAPS, 0, }, + {offsetof(tDot11fAssocRequest, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fAssocRequest, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fAssocRequest, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque" , 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPAOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fAssocRequest, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fAssocRequest, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fAssocRequest, WscIEOpaque), offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque" , 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, WAPIOpaque), offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque" , 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPIOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fAssocRequest, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AssocRequest, IES_AssocRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Unpacked the AssocRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocRequest. */ + + static const tFFDefn FFS_AssocResponse[] = { + { "Capabilities", offsetof(tDot11fAssocResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "Status", offsetof(tDot11fAssocResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AID", offsetof(tDot11fAssocResponse, AID), SigFfAID , DOT11F_FF_AID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AssocResponse[] = { + {offsetof(tDot11fAssocResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fAssocResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fAssocResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE, present), 0, "RCPIIE" , 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RCPIIE, 0, }, + {offsetof(tDot11fAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE, present), 0, "RSNIIE" , 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNIIE, 0, }, + {offsetof(tDot11fAssocResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fAssocResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fAssocResponse, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fAssocResponse, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fAssocResponse, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fAssocResponse, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fAssocResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fAssocResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fAssocResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fAssocResponse, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAssocResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fAssocResponse, WscAssocRes), offsetof(tDot11fIEWscAssocRes, present), 0, "WscAssocRes" , 0, 6, 37, SigIeWscAssocRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCASSOCRES, 0, }, + {offsetof(tDot11fAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, }, + {offsetof(tDot11fAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AssocResponse, IES_AssocResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Unpacked the AssocResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WscAssocRes:\n")); + if (!pFrm->WscAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscAssocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscAssocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscAssocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscAssocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscAssocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocResponse. */ + + static const tFFDefn FFS_Authentication[] = { + { "AuthAlgo", offsetof(tDot11fAuthentication, AuthAlgo), SigFfAuthAlgo , DOT11F_FF_AUTHALGO_LEN, }, + { "AuthSeqNo", offsetof(tDot11fAuthentication, AuthSeqNo), SigFfAuthSeqNo , DOT11F_FF_AUTHSEQNO_LEN, }, + { "Status", offsetof(tDot11fAuthentication, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Authentication[] = { + {offsetof(tDot11fAuthentication, ChallengeText), offsetof(tDot11fIEChallengeText, present), 0, "ChallengeText" , 0, 3, 255, SigIeChallengeText, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHALLENGETEXT, 0, }, + {offsetof(tDot11fAuthentication, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fAuthentication, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAuthentication, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fAuthentication, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fAuthentication, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fAuthentication, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAuthentication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAuthentication *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Authentication, IES_Authentication, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Unpacked the Authentication:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthAlgo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthAlgo.algo, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthSeqNo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthSeqNo.no, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("ChallengeText:\n")); + if (!pFrm->ChallengeText.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_text: %d.\n"), pFrm->ChallengeText.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->ChallengeText.text, pFrm->ChallengeText.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAuthentication. */ + + static const tFFDefn FFS_Beacon[] = { + { "TimeStamp", offsetof(tDot11fBeacon, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fBeacon, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fBeacon, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon[] = { + {offsetof(tDot11fBeacon, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeacon, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeacon, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fBeacon, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeacon, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fBeacon, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fBeacon, TIM), offsetof(tDot11fIETIM, present), 0, "TIM" , 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, }, + {offsetof(tDot11fBeacon, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeacon, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fBeacon, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fBeacon, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeacon, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeacon, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeacon, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeacon, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeacon, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fBeacon, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fBeacon, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeacon, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp, present), 0, "QOSCapsAp" , 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSAP, 0, }, + {offsetof(tDot11fBeacon, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeacon, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeacon, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeacon, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeacon, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeacon, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeacon, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeacon, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeacon, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeacon, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeacon, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeacon, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeacon, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeacon, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeacon, WscBeacon), offsetof(tDot11fIEWscBeacon, present), 0, "WscBeacon" , 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACON, 0, }, + {offsetof(tDot11fBeacon, P2PBeacon), offsetof(tDot11fIEP2PBeacon, present), 0, "P2PBeacon" , 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACON, 0, }, + {offsetof(tDot11fBeacon, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeacon, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeacon, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeacon, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeacon, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeacon, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, }, + {offsetof(tDot11fBeacon, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, }, + {offsetof(tDot11fBeacon, Vendor3IE), offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE" , 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0}, 3, DOT11F_EID_VENDOR3IE, 0, }, + {offsetof(tDot11fBeacon, ChannelSwitchWrapper), offsetof(tDot11fIEChannelSwitchWrapper, present), 0, "ChannelSwitchWrapper" , 0, 2, 7, SigIeChannelSwitchWrapper, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, }, + {offsetof(tDot11fBeacon, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon, IES_Beacon, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Unpacked the Beacon:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon. */ + + static const tFFDefn FFS_Beacon1[] = { + { "TimeStamp", offsetof(tDot11fBeacon1, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fBeacon1, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fBeacon1, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon1[] = { + {offsetof(tDot11fBeacon1, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeacon1, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeacon1, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeacon1, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon1(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon1 *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon1, IES_Beacon1, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Unpacked the Beacon1:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon1. */ + + static const tFFDefn FFS_Beacon2[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon2[] = { + {offsetof(tDot11fBeacon2, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeacon2, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeacon2, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeacon2, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeacon2, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeacon2, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeacon2, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fBeacon2, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeacon2, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeacon2, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeacon2, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeacon2, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeacon2, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeacon2, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeacon2, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeacon2, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeacon2, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeacon2, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeacon2, WscBeacon), offsetof(tDot11fIEWscBeacon, present), 0, "WscBeacon" , 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACON, 0, }, + {offsetof(tDot11fBeacon2, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeacon2, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeacon2, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeacon2, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeacon2, P2PBeacon), offsetof(tDot11fIEP2PBeacon, present), 0, "P2PBeacon" , 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACON, 0, }, + {offsetof(tDot11fBeacon2, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeacon2, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeacon2, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeacon2, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeacon2, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, }, + {offsetof(tDot11fBeacon2, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, }, + {offsetof(tDot11fBeacon2, Vendor3IE), offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE" , 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0}, 3, DOT11F_EID_VENDOR3IE, 0, }, + {offsetof(tDot11fBeacon2, ChannelSwitchWrapper), offsetof(tDot11fIEChannelSwitchWrapper, present), 0, "ChannelSwitchWrapper" , 0, 2, 7, SigIeChannelSwitchWrapper, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, }, + {offsetof(tDot11fBeacon2, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon2 *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon2, IES_Beacon2, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Unpacked the Beacon2:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon2. */ + + static const tFFDefn FFS_BeaconIEs[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_BeaconIEs[] = { + {offsetof(tDot11fBeaconIEs, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeaconIEs, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeaconIEs, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fBeaconIEs, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, TIM), offsetof(tDot11fIETIM, present), 0, "TIM" , 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, }, + {offsetof(tDot11fBeaconIEs, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeaconIEs, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fBeaconIEs, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeaconIEs, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeaconIEs, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeaconIEs, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeaconIEs, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeaconIEs, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fBeaconIEs, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fBeaconIEs, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeaconIEs, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp, present), 0, "QOSCapsAp" , 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSAP, 0, }, + {offsetof(tDot11fBeaconIEs, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeaconIEs, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeaconIEs, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeaconIEs, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeaconIEs, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeaconIEs, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeaconIEs, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeaconIEs, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fBeaconIEs, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeaconIEs, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeaconIEs, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeaconIEs, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeaconIEs, WscBeaconProbeRes), offsetof(tDot11fIEWscBeaconProbeRes, present), 0, "WscBeaconProbeRes" , 0, 6, 319, SigIeWscBeaconProbeRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACONPROBERES, 0, }, + {offsetof(tDot11fBeaconIEs, P2PBeaconProbeRes), offsetof(tDot11fIEP2PBeaconProbeRes, present), 0, "P2PBeaconProbeRes" , 0, 6, 1150, SigIeP2PBeaconProbeRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACONPROBERES, 0, }, + {offsetof(tDot11fBeaconIEs, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeaconIEs, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeaconIEs, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeaconIEs, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, }, + {offsetof(tDot11fBeaconIEs, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, }, + {offsetof(tDot11fBeaconIEs, Vendor3IE), offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE" , 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0}, 3, DOT11F_EID_VENDOR3IE, 0, }, + {offsetof(tDot11fBeaconIEs, ChannelSwitchWrapper), offsetof(tDot11fIEChannelSwitchWrapper, present), 0, "ChannelSwitchWrapper" , 0, 2, 7, SigIeChannelSwitchWrapper, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeaconIEs *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_BeaconIEs, IES_BeaconIEs, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Unpacked the BeaconIEs:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WscBeaconProbeRes:\n")); + if (!pFrm->WscBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->WscBeaconProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPSState:\n")); + if (!pFrm->WscBeaconProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeaconProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeaconProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ResponseType:\n")); + if (!pFrm->WscBeaconProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("UUID_E:\n")); + if (!pFrm->WscBeaconProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Manufacturer:\n")); + if (!pFrm->WscBeaconProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->WscBeaconProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.Manufacturer.name, pFrm->WscBeaconProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelName:\n")); + if (!pFrm->WscBeaconProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelName.text, pFrm->WscBeaconProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelNumber:\n")); + if (!pFrm->WscBeaconProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelNumber.text, pFrm->WscBeaconProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SerialNumber:\n")); + if (!pFrm->WscBeaconProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.SerialNumber.text, pFrm->WscBeaconProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscBeaconProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->WscBeaconProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.DeviceName.text, pFrm->WscBeaconProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RFBands:\n")); + if (!pFrm->WscBeaconProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version2:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PBeaconProbeRes:\n")); + if (!pFrm->P2PBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PBeaconProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeaconProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeaconIEs. */ + + static const tFFDefn FFS_ChannelSwitch[] = { + { "Category", offsetof(tDot11fChannelSwitch, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fChannelSwitch, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ChannelSwitch[] = { + {offsetof(tDot11fChannelSwitch, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 1, }, + {offsetof(tDot11fChannelSwitch, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fChannelSwitch, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackChannelSwitch(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fChannelSwitch *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ChannelSwitch, IES_ChannelSwitch, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Unpacked the ChannelSwitch:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackChannelSwitch. */ + + static const tFFDefn FFS_DeAuth[] = { + { "Reason", offsetof(tDot11fDeAuth, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeAuth[] = { + {offsetof(tDot11fDeAuth, P2PDeAuth), offsetof(tDot11fIEP2PDeAuth, present), 0, "P2PDeAuth" , 0, 6, 10, SigIeP2PDeAuth, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEAUTH, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeAuth *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeAuth, IES_DeAuth, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Unpacked the DeAuth:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("P2PDeAuth:\n")); + if (!pFrm->P2PDeAuth.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDeAuth.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->P2PDeAuth.MinorReasonCode.minorReasonCode, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeAuth. */ + + static const tFFDefn FFS_DelBAInd[] = { + { "Category", offsetof(tDot11fDelBAInd, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDelBAInd, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DelBAParameterSet", offsetof(tDot11fDelBAInd, DelBAParameterSet), SigFfDelBAParameterSet , DOT11F_FF_DELBAPARAMETERSET_LEN, }, + { "Reason", offsetof(tDot11fDelBAInd, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DelBAInd[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDelBAInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelBAInd *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DelBAInd, IES_DelBAInd, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Unpacked the DelBAInd:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("DelBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("reserved (11): %d\n"), pFrm->DelBAParameterSet.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("initiator (1): %d\n"), pFrm->DelBAParameterSet.initiator); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("tid (4): %d\n"), pFrm->DelBAParameterSet.tid); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Reason.code, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelBAInd. */ + + static const tFFDefn FFS_DelTS[] = { + { "Category", offsetof(tDot11fDelTS, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDelTS, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TSInfo", offsetof(tDot11fDelTS, TSInfo), SigFfTSInfo , DOT11F_FF_TSINFO_LEN, }, + { "Reason", offsetof(tDot11fDelTS, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DelTS[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelTS *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DelTS, IES_DelTS, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Unpacked the DelTS:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("TSInfo:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("traffic_type (1): %d\n"), pFrm->TSInfo.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsid (4): %d\n"), pFrm->TSInfo.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("direction (2): %d\n"), pFrm->TSInfo.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("access_policy (2): %d\n"), pFrm->TSInfo.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("aggregation (1): %d\n"), pFrm->TSInfo.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("psb (1): %d\n"), pFrm->TSInfo.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("user_priority (3): %d\n"), pFrm->TSInfo.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSInfo.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("schedule (1): %d\n"), pFrm->TSInfo.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("unused (15): %d\n"), pFrm->TSInfo.unused); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Reason.code, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelTS. */ + + static const tFFDefn FFS_DeviceDiscoverabilityReq[] = { + { "Category", offsetof(tDot11fDeviceDiscoverabilityReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDeviceDiscoverabilityReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fDeviceDiscoverabilityReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fDeviceDiscoverabilityReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fDeviceDiscoverabilityReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeviceDiscoverabilityReq[] = { + {offsetof(tDot11fDeviceDiscoverabilityReq, P2PDeviceDiscoverabilityReq), offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, present), 0, "P2PDeviceDiscoverabilityReq" , 0, 6, 56, SigIeP2PDeviceDiscoverabilityReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEVICEDISCOVERABILITYREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeviceDiscoverabilityReq, IES_DeviceDiscoverabilityReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Unpacked the DeviceDiscoverabilityReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceDiscoverabilityReq:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* ) pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.ssid, pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityReq. */ + + static const tFFDefn FFS_DeviceDiscoverabilityRes[] = { + { "Category", offsetof(tDot11fDeviceDiscoverabilityRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDeviceDiscoverabilityRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fDeviceDiscoverabilityRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fDeviceDiscoverabilityRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fDeviceDiscoverabilityRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeviceDiscoverabilityRes[] = { + {offsetof(tDot11fDeviceDiscoverabilityRes, P2PDeviceDiscoverabilityRes), offsetof(tDot11fIEP2PDeviceDiscoverabilityRes, present), 0, "P2PDeviceDiscoverabilityRes" , 0, 6, 10, SigIeP2PDeviceDiscoverabilityRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEVICEDISCOVERABILITYRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeviceDiscoverabilityRes, IES_DeviceDiscoverabilityRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Unpacked the DeviceDiscoverabilityRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PDeviceDiscoverabilityRes:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.status, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityRes. */ + + static const tFFDefn FFS_Disassociation[] = { + { "Reason", offsetof(tDot11fDisassociation, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Disassociation[] = { + {offsetof(tDot11fDisassociation, P2PDisAssoc), offsetof(tDot11fIEP2PDisAssoc, present), 0, "P2PDisAssoc" , 0, 6, 10, SigIeP2PDisAssoc, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDISASSOC, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDisassociation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDisassociation *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Disassociation, IES_Disassociation, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Unpacked the Disassociation:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("P2PDisAssoc:\n")); + if (!pFrm->P2PDisAssoc.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDisAssoc.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->P2PDisAssoc.MinorReasonCode.minorReasonCode, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDisassociation. */ + + static const tFFDefn FFS_GODiscoverabilityReq[] = { + { "Category", offsetof(tDot11fGODiscoverabilityReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fGODiscoverabilityReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGODiscoverabilityReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGODiscoverabilityReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GODiscoverabilityReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGODiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGODiscoverabilityReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GODiscoverabilityReq, IES_GODiscoverabilityReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Unpacked the GODiscoverabilityReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGODiscoverabilityReq. */ + + static const tFFDefn FFS_GONegCnf[] = { + { "Category", offsetof(tDot11fGONegCnf, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegCnf, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegCnf, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegCnf, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegCnf, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegCnf[] = { + {offsetof(tDot11fGONegCnf, P2PGONegCnf), offsetof(tDot11fIEP2PGONegCnf, present), 0, "P2PGONegCnf" , 0, 6, 321, SigIeP2PGONegCnf, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGCNF, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegCnf *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegCnf, IES_GONegCnf, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Unpacked the GONegCnf:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGONegCnf:\n")); + if (!pFrm->P2PGONegCnf.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegCnf.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegCnf.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegCnf.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegCnf.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegCnf.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.ChannelList.channelList, pFrm->P2PGONegCnf.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegCnf.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.P2PGroupId.ssid, pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegCnf. */ + + static const tFFDefn FFS_GONegReq[] = { + { "Category", offsetof(tDot11fGONegReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegReq[] = { + {offsetof(tDot11fGONegReq, P2PGONegWPS), offsetof(tDot11fIEP2PGONegWPS, present), 0, "P2PGONegWPS" , 0, 6, 17, SigIeP2PGONegWPS, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PGONEGWPS, 1, }, + {offsetof(tDot11fGONegReq, P2PGONegReq), offsetof(tDot11fIEP2PGONegReq, present), 0, "P2PGONegReq" , 0, 6, 364, SigIeP2PGONegReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegReq, IES_GONegReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Unpacked the GONegReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegReq:\n")); + if (!pFrm->P2PGONegReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegReq.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ListenChannel:\n")); + if (!pFrm->P2PGONegReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PGONegReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.ChannelList.channelList, pFrm->P2PGONegReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_text: %d.\n"), pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.channel, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegReq. */ + + static const tFFDefn FFS_GONegRes[] = { + { "Category", offsetof(tDot11fGONegRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegRes[] = { + {offsetof(tDot11fGONegRes, P2PGONegWPS), offsetof(tDot11fIEP2PGONegWPS, present), 0, "P2PGONegWPS" , 0, 6, 17, SigIeP2PGONegWPS, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PGONEGWPS, 1, }, + {offsetof(tDot11fGONegRes, P2PGONegRes), offsetof(tDot11fIEP2PGONegRes, present), 0, "P2PGONegRes" , 0, 6, 394, SigIeP2PGONegRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegRes, IES_GONegRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Unpacked the GONegRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegRes:\n")); + if (!pFrm->P2PGONegRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegRes.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.ChannelList.channelList, pFrm->P2PGONegRes.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_text: %d.\n"), pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegRes.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegRes.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PGroupId.ssid, pFrm->P2PGONegRes.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegRes. */ + + static const tFFDefn FFS_HT2040BSSCoexistenceManagementActionFrame[] = { + { "Category", offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_HT2040BSSCoexistenceManagementActionFrame[] = { + {offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 1, }, + {offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, HT2040BSSIntolerantReport), offsetof(tDot11fIEHT2040BSSIntolerantReport, present), 0, "HT2040BSSIntolerantReport" , 0, 3, 53, SigIeHT2040BSSIntolerantReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSINTOLERANTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_HT2040BSSCoexistenceManagementActionFrame, IES_HT2040BSSCoexistenceManagementActionFrame, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Unpacked the HT2040BSSCoexistenceManagementActionFrame:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSIntolerantReport:\n")); + if (!pFrm->HT2040BSSIntolerantReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->HT2040BSSIntolerantReport.operatingClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("num_channelList: %d.\n"), pFrm->HT2040BSSIntolerantReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* ) pFrm->HT2040BSSIntolerantReport.channelList, pFrm->HT2040BSSIntolerantReport.num_channelList); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackHT2040BSSCoexistenceManagementActionFrame. */ + + static const tFFDefn FFS_InvitationReq[] = { + { "Category", offsetof(tDot11fInvitationReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fInvitationReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fInvitationReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fInvitationReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fInvitationReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_InvitationReq[] = { + {offsetof(tDot11fInvitationReq, P2PInvitationReq), offsetof(tDot11fIEP2PInvitationReq, present), 0, "P2PInvitationReq" , 0, 6, 385, SigIeP2PInvitationReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PINVITATIONREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_InvitationReq, IES_InvitationReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Unpacked the InvitationReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PInvitationReq:\n")); + if (!pFrm->P2PInvitationReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("InvitationFlags:\n")); + if (!pFrm->P2PInvitationReq.InvitationFlags.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.InvitationFlags.invitationFlags, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.ChannelList.channelList, pFrm->P2PInvitationReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PGroupId.ssid, pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_text: %d.\n"), pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationReq. */ + + static const tFFDefn FFS_InvitationRes[] = { + { "Category", offsetof(tDot11fInvitationRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fInvitationRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fInvitationRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fInvitationRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fInvitationRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_InvitationRes[] = { + {offsetof(tDot11fInvitationRes, P2PInvitationRes), offsetof(tDot11fIEP2PInvitationRes, present), 0, "P2PInvitationRes" , 0, 6, 289, SigIeP2PInvitationRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PINVITATIONRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_InvitationRes, IES_InvitationRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Unpacked the InvitationRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PInvitationRes:\n")); + if (!pFrm->P2PInvitationRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PInvitationRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationRes.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* ) pFrm->P2PInvitationRes.ChannelList.channelList, pFrm->P2PInvitationRes.ChannelList.num_channelList); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationRes. */ + + static const tFFDefn FFS_LinkMeasurementReport[] = { + { "Category", offsetof(tDot11fLinkMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fLinkMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fLinkMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "TPCEleID", offsetof(tDot11fLinkMeasurementReport, TPCEleID), SigFfTPCEleID , DOT11F_FF_TPCELEID_LEN, }, + { "TPCEleLen", offsetof(tDot11fLinkMeasurementReport, TPCEleLen), SigFfTPCEleLen , DOT11F_FF_TPCELELEN_LEN, }, + { "TxPower", offsetof(tDot11fLinkMeasurementReport, TxPower), SigFfTxPower , DOT11F_FF_TXPOWER_LEN, }, + { "LinkMargin", offsetof(tDot11fLinkMeasurementReport, LinkMargin), SigFfLinkMargin , DOT11F_FF_LINKMARGIN_LEN, }, + { "RxAntennaId", offsetof(tDot11fLinkMeasurementReport, RxAntennaId), SigFfRxAntennaId , DOT11F_FF_RXANTENNAID_LEN, }, + { "TxAntennaId", offsetof(tDot11fLinkMeasurementReport, TxAntennaId), SigFfTxAntennaId , DOT11F_FF_TXANTENNAID_LEN, }, + { "RCPI", offsetof(tDot11fLinkMeasurementReport, RCPI), SigFfRCPI , DOT11F_FF_RCPI_LEN, }, + { "RSNI", offsetof(tDot11fLinkMeasurementReport, RSNI), SigFfRSNI , DOT11F_FF_RSNI_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_LinkMeasurementReport[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackLinkMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_LinkMeasurementReport, IES_LinkMeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Unpacked the LinkMeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleID.TPCId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleLen:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleLen.TPCLen, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("LinkMargin:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->LinkMargin.linkMargin, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RCPI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RCPI.rcpi, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RSNI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RSNI.rsni, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementReport. */ + + static const tFFDefn FFS_LinkMeasurementRequest[] = { + { "Category", offsetof(tDot11fLinkMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fLinkMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fLinkMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "TxPower", offsetof(tDot11fLinkMeasurementRequest, TxPower), SigFfTxPower , DOT11F_FF_TXPOWER_LEN, }, + { "MaxTxPower", offsetof(tDot11fLinkMeasurementRequest, MaxTxPower), SigFfMaxTxPower , DOT11F_FF_MAXTXPOWER_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_LinkMeasurementRequest[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackLinkMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Unpacked the LinkMeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("MaxTxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MaxTxPower.maxTxPower, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementRequest. */ + + static const tFFDefn FFS_MeasurementReport[] = { + { "Category", offsetof(tDot11fMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_MeasurementReport[] = { + {offsetof(tDot11fMeasurementReport, MeasurementReport), offsetof(tDot11fIEMeasurementReport, present), 0, "MeasurementReport" , 0, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_MeasurementReport, IES_MeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Unpacked the MeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("MeasurementReport:\n")); + if (!pFrm->MeasurementReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport.late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport.incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport.refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport.unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.type, 1); + switch (pFrm->MeasurementReport.type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport.report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport.report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport.report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport.report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport.report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport.report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport.report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport.report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.parent_TSF, 4); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementReport. */ + + static const tFFDefn FFS_MeasurementRequest[] = { + { "Category", offsetof(tDot11fMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_MeasurementRequest[] = { + {offsetof(tDot11fMeasurementRequest, MeasurementRequest), offsetof(tDot11fIEMeasurementRequest, present), offsetof(tDot11fMeasurementRequest, num_MeasurementRequest), "MeasurementRequest" , 4, 16, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_MeasurementRequest, IES_MeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Unpacked the MeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementRequest. */ + + static const tFFDefn FFS_NeighborReportRequest[] = { + { "Category", offsetof(tDot11fNeighborReportRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fNeighborReportRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fNeighborReportRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReportRequest[] = { + {offsetof(tDot11fNeighborReportRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNeighborReportRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NeighborReportRequest, IES_NeighborReportRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Unpacked the NeighborReportRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportRequest. */ + + static const tFFDefn FFS_NeighborReportResponse[] = { + { "Category", offsetof(tDot11fNeighborReportResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fNeighborReportResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fNeighborReportResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReportResponse[] = { + {offsetof(tDot11fNeighborReportResponse, NeighborReport), offsetof(tDot11fIENeighborReport, present), offsetof(tDot11fNeighborReportResponse, num_NeighborReport), "NeighborReport" , 15, 15, 548, SigIeNeighborReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_NEIGHBORREPORT, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNeighborReportResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NeighborReportResponse, IES_NeighborReportResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Unpacked the NeighborReportResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_NeighborReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborReport[%d]:\n"), i); + if (!pFrm->NeighborReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].bssid, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APReachability (2): %d\n"), pFrm->NeighborReport[i].APReachability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Security (1): %d\n"), pFrm->NeighborReport[i].Security); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("KeyScope (1): %d\n"), pFrm->NeighborReport[i].KeyScope); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("SpecMgmtCap (1): %d\n"), pFrm->NeighborReport[i].SpecMgmtCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("QosCap (1): %d\n"), pFrm->NeighborReport[i].QosCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("apsd (1): %d\n"), pFrm->NeighborReport[i].apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("rrm (1): %d\n"), pFrm->NeighborReport[i].rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DelayedBA (1): %d\n"), pFrm->NeighborReport[i].DelayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ImmBA (1): %d\n"), pFrm->NeighborReport[i].ImmBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MobilityDomain (1): %d\n"), pFrm->NeighborReport[i].MobilityDomain); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (5): %d\n"), pFrm->NeighborReport[i].reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].reserved1, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].PhyType, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TSFInfo:\n")); + if (!pFrm->NeighborReport[i].TSFInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.TsfOffset, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.BeaconIntvl, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("CondensedCountryStr:\n")); + if (!pFrm->NeighborReport[i].CondensedCountryStr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].CondensedCountryStr.countryStr, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot:\n")); + if (!pFrm->NeighborReport[i].MeasurementPilot.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MeasurementPilot.measurementPilot, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MeasurementPilot.vendorSpecific, pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->NeighborReport[i].RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("parallel (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("repeated (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("statistics (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (6): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MultiBssid:\n")); + if (!pFrm->NeighborReport[i].MultiBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MultiBssid.maxBSSIDIndicator, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MultiBssid.vendorSpecific, pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportResponse. */ + + static const tFFDefn FFS_NoticeOfAbs[] = { + { "Category", offsetof(tDot11fNoticeOfAbs, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fNoticeOfAbs, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fNoticeOfAbs, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fNoticeOfAbs, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NoticeOfAbs[] = { + {offsetof(tDot11fNoticeOfAbs, P2PNoticeOfAbsence), offsetof(tDot11fIEP2PNoticeOfAbsence, present), 0, "P2PNoticeOfAbsence" , 0, 6, 47, SigIeP2PNoticeOfAbsence, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PNOTICEOFABSENCE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNoticeOfAbs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNoticeOfAbs *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NoticeOfAbs, IES_NoticeOfAbs, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Unpacked the NoticeOfAbs:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNoticeOfAbs. */ + + static const tFFDefn FFS_OperatingMode[] = { + { "Category", offsetof(tDot11fOperatingMode, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fOperatingMode, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "OperatingMode", offsetof(tDot11fOperatingMode, OperatingMode), SigFfOperatingMode , DOT11F_FF_OPERATINGMODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_OperatingMode[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fOperatingMode *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_OperatingMode, IES_OperatingMode, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Unpacked the OperatingMode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("OperatingMode:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackOperatingMode. */ + + static const tFFDefn FFS_PresenceReq[] = { + { "Category", offsetof(tDot11fPresenceReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fPresenceReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fPresenceReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fPresenceReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_PresenceReq[] = { + {offsetof(tDot11fPresenceReq, P2PNoticeOfAbsence), offsetof(tDot11fIEP2PNoticeOfAbsence, present), 0, "P2PNoticeOfAbsence" , 0, 6, 47, SigIeP2PNoticeOfAbsence, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PNOTICEOFABSENCE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackPresenceReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_PresenceReq, IES_PresenceReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Unpacked the PresenceReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceReq. */ + + static const tFFDefn FFS_PresenceRes[] = { + { "Category", offsetof(tDot11fPresenceRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fPresenceRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fPresenceRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fPresenceRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_PresenceRes[] = { + {offsetof(tDot11fPresenceRes, P2PPresenceResponse), offsetof(tDot11fIEP2PPresenceResponse, present), 0, "P2PPresenceResponse" , 0, 6, 51, SigIeP2PPresenceResponse, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPRESENCERESPONSE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackPresenceRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_PresenceRes, IES_PresenceRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Unpacked the PresenceRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PPresenceResponse:\n")); + if (!pFrm->P2PPresenceResponse.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PPresenceResponse.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PPresenceResponse.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* ) pFrm->P2PPresenceResponse.NoticeOfAbsence.NoADesc, pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceRes. */ + + static const tFFDefn FFS_ProbeRequest[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProbeRequest[] = { + {offsetof(tDot11fProbeRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fProbeRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fProbeRequest, RequestedInfo), offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo" , 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_REQUESTEDINFO, 0, }, + {offsetof(tDot11fProbeRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fProbeRequest, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fProbeRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fProbeRequest, WscProbeReq), offsetof(tDot11fIEWscProbeReq, present), 0, "WscProbeReq" , 0, 6, 286, SigIeWscProbeReq, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCPROBEREQ, 0, }, + {offsetof(tDot11fProbeRequest, WFATPC), offsetof(tDot11fIEWFATPC, present), 0, "WFATPC" , 0, 9, 9, SigIeWFATPC, {0, 80, 242, 8, 0}, 5, DOT11F_EID_WFATPC, 0, }, + {offsetof(tDot11fProbeRequest, P2PProbeReq), offsetof(tDot11fIEP2PProbeReq, present), 0, "P2PProbeReq" , 0, 6, 43, SigIeP2PProbeReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROBEREQ, 0, }, + {offsetof(tDot11fProbeRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProbeRequest, IES_ProbeRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Unpacked the ProbeRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestedInfo:\n")); + if (!pFrm->RequestedInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_requested_eids: %d.\n"), pFrm->RequestedInfo.num_requested_eids); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->RequestedInfo.requested_eids, pFrm->RequestedInfo.num_requested_eids); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WscProbeReq:\n")); + if (!pFrm->WscProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version:\n")); + if (!pFrm->WscProbeReq.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestType:\n")); + if (!pFrm->WscProbeReq.RequestType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestType.reqType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeReq.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeReq.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeReq.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RFBands:\n")); + if (!pFrm->WscProbeReq.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AssociationState:\n")); + if (!pFrm->WscProbeReq.AssociationState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.AssociationState.state, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigurationError:\n")); + if (!pFrm->WscProbeReq.ConfigurationError.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigurationError.error, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeReq.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeReq.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_name: %d.\n"), pFrm->WscProbeReq.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.Manufacturer.name, pFrm->WscProbeReq.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelName:\n")); + if (!pFrm->WscProbeReq.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelName.text, pFrm->WscProbeReq.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeReq.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelNumber.text, pFrm->WscProbeReq.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeReq.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.DeviceName.text, pFrm->WscProbeReq.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeReq.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version2:\n")); + if (!pFrm->WscProbeReq.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeReq.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.RequestToEnroll.req, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestDeviceType:\n")); + if (!pFrm->WscProbeReq.RequestDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.sub_category, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WFATPC:\n")); + if (!pFrm->WFATPC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.txPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.linkMargin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PProbeReq:\n")); + if (!pFrm->P2PProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PProbeReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ListenChannel:\n")); + if (!pFrm->P2PProbeReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PProbeReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeRequest. */ + + static const tFFDefn FFS_ProbeResponse[] = { + { "TimeStamp", offsetof(tDot11fProbeResponse, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fProbeResponse, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fProbeResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProbeResponse[] = { + {offsetof(tDot11fProbeResponse, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fProbeResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fProbeResponse, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fProbeResponse, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fProbeResponse, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fProbeResponse, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fProbeResponse, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fProbeResponse, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fProbeResponse, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fProbeResponse, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fProbeResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fProbeResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fProbeResponse, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fProbeResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fProbeResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fProbeResponse, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fProbeResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fProbeResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fProbeResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fProbeResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fProbeResponse, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fProbeResponse, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fProbeResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fProbeResponse, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fProbeResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fProbeResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fProbeResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fProbeResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fProbeResponse, WscProbeRes), offsetof(tDot11fIEWscProbeRes, present), 0, "WscProbeRes" , 0, 6, 319, SigIeWscProbeRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCPROBERES, 0, }, + {offsetof(tDot11fProbeResponse, P2PProbeRes), offsetof(tDot11fIEP2PProbeRes, present), 0, "P2PProbeRes" , 0, 6, 1141, SigIeP2PProbeRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROBERES, 0, }, + {offsetof(tDot11fProbeResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fProbeResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fProbeResponse, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fProbeResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fProbeResponse, Vendor1IE), offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE" , 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0}, 3, DOT11F_EID_VENDOR1IE, 0, }, + {offsetof(tDot11fProbeResponse, Vendor2IE), offsetof(tDot11fIEVendor2IE, present), 0, "Vendor2IE" , 0, 5, 5, SigIeVendor2IE, {0, 144, 76, 0, 0}, 3, DOT11F_EID_VENDOR2IE, 0, }, + {offsetof(tDot11fProbeResponse, Vendor3IE), offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE" , 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0}, 3, DOT11F_EID_VENDOR3IE, 0, }, + {offsetof(tDot11fProbeResponse, ChannelSwitchWrapper), offsetof(tDot11fIEChannelSwitchWrapper, present), 0, "ChannelSwitchWrapper" , 0, 2, 7, SigIeChannelSwitchWrapper, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, }, + {offsetof(tDot11fProbeResponse, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProbeResponse, IES_ProbeResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Unpacked the ProbeResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WscProbeRes:\n")); + if (!pFrm->WscProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->WscProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPSState:\n")); + if (!pFrm->WscProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APSetupLocked:\n")); + if (!pFrm->WscProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->WscProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.Manufacturer.name, pFrm->WscProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelName:\n")); + if (!pFrm->WscProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelName.text, pFrm->WscProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelNumber.text, pFrm->WscProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SerialNumber:\n")); + if (!pFrm->WscProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.SerialNumber.text, pFrm->WscProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.DeviceName.text, pFrm->WscProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RFBands:\n")); + if (!pFrm->WscProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PProbeRes:\n")); + if (!pFrm->P2PProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_NoADesc: %d.\n"), pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeResponse. */ + + static const tFFDefn FFS_ProvisionDiscoveryReq[] = { + { "Category", offsetof(tDot11fProvisionDiscoveryReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fProvisionDiscoveryReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fProvisionDiscoveryReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fProvisionDiscoveryReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fProvisionDiscoveryReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProvisionDiscoveryReq[] = { + {offsetof(tDot11fProvisionDiscoveryReq, P2PProvisionDiscoveryReq), offsetof(tDot11fIEP2PProvisionDiscoveryReq, present), 0, "P2PProvisionDiscoveryReq" , 0, 6, 107, SigIeP2PProvisionDiscoveryReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROVISIONDISCOVERYREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProvisionDiscoveryReq, IES_ProvisionDiscoveryReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Unpacked the ProvisionDiscoveryReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PProvisionDiscoveryReq:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_text: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PGroupId.ssid, pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryReq. */ + + static const tFFDefn FFS_ProvisionDiscoveryRes[] = { + { "Category", offsetof(tDot11fProvisionDiscoveryRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fProvisionDiscoveryRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fProvisionDiscoveryRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fProvisionDiscoveryRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fProvisionDiscoveryRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProvisionDiscoveryRes[] = { + {offsetof(tDot11fProvisionDiscoveryRes, P2PWSCProvisionDiscoveryRes), offsetof(tDot11fIEP2PWSCProvisionDiscoveryRes, present), 0, "P2PWSCProvisionDiscoveryRes" , 0, 6, 12, SigIeP2PWSCProvisionDiscoveryRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PWSCPROVISIONDISCOVERYRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProvisionDiscoveryRes, IES_ProvisionDiscoveryRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Unpacked the ProvisionDiscoveryRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2PWSCProvisionDiscoveryRes:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("ConfigMethods:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.methods, 2); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryRes. */ + + static const tFFDefn FFS_QosMapConfigure[] = { + { "Category", offsetof(tDot11fQosMapConfigure, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fQosMapConfigure, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_QosMapConfigure[] = { + {offsetof(tDot11fQosMapConfigure, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackQosMapConfigure(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fQosMapConfigure *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_QosMapConfigure, IES_QosMapConfigure, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Unpacked the QosMapConfigure:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackQosMapConfigure. */ + + static const tFFDefn FFS_RadioMeasurementReport[] = { + { "Category", offsetof(tDot11fRadioMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fRadioMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fRadioMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RadioMeasurementReport[] = { + {offsetof(tDot11fRadioMeasurementReport, MeasurementReport), offsetof(tDot11fIEMeasurementReport, present), offsetof(tDot11fRadioMeasurementReport, num_MeasurementReport), "MeasurementReport" , 4, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackRadioMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_RadioMeasurementReport, IES_RadioMeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Unpacked the RadioMeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("MeasurementReport[%d]:\n"), i); + if (!pFrm->MeasurementReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport[i].late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport[i].incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport[i].refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].type, 1); + switch (pFrm->MeasurementReport[i].type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport[i].report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport[i].report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport[i].report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.parent_TSF, 4); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementReport. */ + + static const tFFDefn FFS_RadioMeasurementRequest[] = { + { "Category", offsetof(tDot11fRadioMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fRadioMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fRadioMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "NumOfRepetitions", offsetof(tDot11fRadioMeasurementRequest, NumOfRepetitions), SigFfNumOfRepetitions , DOT11F_FF_NUMOFREPETITIONS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RadioMeasurementRequest[] = { + {offsetof(tDot11fRadioMeasurementRequest, MeasurementRequest), offsetof(tDot11fIEMeasurementRequest, present), offsetof(tDot11fRadioMeasurementRequest, num_MeasurementRequest), "MeasurementRequest" , 2, 16, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackRadioMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Unpacked the RadioMeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("NumOfRepetitions:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->NumOfRepetitions.repetitions, 2); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementRequest. */ + + static const tFFDefn FFS_ReAssocRequest[] = { + { "Capabilities", offsetof(tDot11fReAssocRequest, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "ListenInterval", offsetof(tDot11fReAssocRequest, ListenInterval), SigFfListenInterval , DOT11F_FF_LISTENINTERVAL_LEN, }, + { "CurrentAPAddress", offsetof(tDot11fReAssocRequest, CurrentAPAddress), SigFfCurrentAPAddress , DOT11F_FF_CURRENTAPADDRESS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ReAssocRequest[] = { + {offsetof(tDot11fReAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fReAssocRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fReAssocRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fReAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps" , 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fReAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fReAssocRequest, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fReAssocRequest, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fReAssocRequest, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fReAssocRequest, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fReAssocRequest, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fReAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque" , 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPAOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fReAssocRequest, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fReAssocRequest, WscIEOpaque), offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque" , 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WAPIOpaque), offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque" , 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPIOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fReAssocRequest, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fReAssocRequest, ESECckmOpaque), offsetof(tDot11fIEESECckmOpaque, present), 0, "ESECckmOpaque" , 0, 12, 26, SigIeESECckmOpaque, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESECCKMOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fReAssocRequest, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fReAssocRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {offsetof(tDot11fReAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fReAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ReAssocRequest, IES_ReAssocRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Unpacked the ReAssocRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("CurrentAPAddress:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->CurrentAPAddress.mac, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESECckmOpaque:\n")); + if (!pFrm->ESECckmOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->ESECckmOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESECckmOpaque.data, pFrm->ESECckmOpaque.num_data); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocRequest. */ + + static const tFFDefn FFS_ReAssocResponse[] = { + { "Capabilities", offsetof(tDot11fReAssocResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "Status", offsetof(tDot11fReAssocResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AID", offsetof(tDot11fReAssocResponse, AID), SigFfAID , DOT11F_FF_AID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ReAssocResponse[] = { + {offsetof(tDot11fReAssocResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fReAssocResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fReAssocResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fReAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE, present), 0, "RCPIIE" , 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RCPIIE, 0, }, + {offsetof(tDot11fReAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE, present), 0, "RSNIIE" , 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNIIE, 0, }, + {offsetof(tDot11fReAssocResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fReAssocResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fReAssocResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fReAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fReAssocResponse, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fReAssocResponse, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fReAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fReAssocResponse, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fReAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fReAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fReAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fReAssocResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fReAssocResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fReAssocResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fReAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fReAssocResponse, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fReAssocResponse, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {offsetof(tDot11fReAssocResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fReAssocResponse, WscReassocRes), offsetof(tDot11fIEWscReassocRes, present), 0, "WscReassocRes" , 0, 6, 37, SigIeWscReassocRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCREASSOCRES, 0, }, + {offsetof(tDot11fReAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, }, + {offsetof(tDot11fReAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fReAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fReAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fReAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackReAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ReAssocResponse, IES_ReAssocResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Unpacked the ReAssocResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WscReassocRes:\n")); + if (!pFrm->WscReassocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscReassocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscReassocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscReassocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscReassocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscReassocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocResponse. */ + + static const tFFDefn FFS_SMPowerSave[] = { + { "Category", offsetof(tDot11fSMPowerSave, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSMPowerSave, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "SMPowerModeSet", offsetof(tDot11fSMPowerSave, SMPowerModeSet), SigFfSMPowerModeSet , DOT11F_FF_SMPOWERMODESET_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SMPowerSave[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSMPowerSave(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSMPowerSave *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SMPowerSave, IES_SMPowerSave, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Unpacked the SMPowerSave:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("SMPowerModeSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("PowerSave_En (1): %d\n"), pFrm->SMPowerModeSet.PowerSave_En); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Mode (1): %d\n"), pFrm->SMPowerModeSet.Mode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("reserved (6): %d\n"), pFrm->SMPowerModeSet.reserved); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSMPowerSave. */ + + static const tFFDefn FFS_SaQueryReq[] = { + { "Category", offsetof(tDot11fSaQueryReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSaQueryReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TransactionId", offsetof(tDot11fSaQueryReq, TransactionId), SigFfTransactionId , DOT11F_FF_TRANSACTIONID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SaQueryReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSaQueryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SaQueryReq, IES_SaQueryReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Unpacked the SaQueryReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryReq. */ + + static const tFFDefn FFS_SaQueryRsp[] = { + { "Category", offsetof(tDot11fSaQueryRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSaQueryRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TransactionId", offsetof(tDot11fSaQueryRsp, TransactionId), SigFfTransactionId , DOT11F_FF_TRANSACTIONID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SaQueryRsp[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSaQueryRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SaQueryRsp, IES_SaQueryRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Unpacked the SaQueryRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryRsp. */ + + static const tFFDefn FFS_TDLSDisReq[] = { + { "Category", offsetof(tDot11fTDLSDisReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSDisReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSDisReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSDisReq[] = { + {offsetof(tDot11fTDLSDisReq, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSDisReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSDisReq, IES_TDLSDisReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Unpacked the TDLSDisReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisReq. */ + + static const tFFDefn FFS_TDLSDisRsp[] = { + { "Category", offsetof(tDot11fTDLSDisRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSDisRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSDisRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSDisRsp, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSDisRsp[] = { + {offsetof(tDot11fTDLSDisRsp, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fTDLSDisRsp, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSDisRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSDisRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSDisRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSDisRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSDisRsp, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSDisRsp, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSDisRsp, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSDisRsp, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSDisRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSDisRsp, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSDisRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSDisRsp, IES_TDLSDisRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Unpacked the TDLSDisRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisRsp. */ + + static const tFFDefn FFS_TDLSPeerTrafficInd[] = { + { "Category", offsetof(tDot11fTDLSPeerTrafficInd, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSPeerTrafficInd, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSPeerTrafficInd, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSPeerTrafficInd[] = { + {offsetof(tDot11fTDLSPeerTrafficInd, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSPeerTrafficInd, PTIControl), offsetof(tDot11fIEPTIControl, present), 0, "PTIControl" , 0, 5, 5, SigIePTIControl, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PTICONTROL, 0, }, + {offsetof(tDot11fTDLSPeerTrafficInd, PUBufferStatus), offsetof(tDot11fIEPUBufferStatus, present), 0, "PUBufferStatus" , 0, 3, 3, SigIePUBufferStatus, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PUBUFFERSTATUS, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficInd *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Unpacked the TDLSPeerTrafficInd:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PTIControl:\n")); + if (!pFrm->PTIControl.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.tid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.sequence_control, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PUBufferStatus:\n")); + if (!pFrm->PUBufferStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_bk_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_bk_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_be_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_be_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vi_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vi_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vo_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vo_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("reserved (4): %d\n"), pFrm->PUBufferStatus.reserved); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficInd. */ + + static const tFFDefn FFS_TDLSPeerTrafficRsp[] = { + { "Category", offsetof(tDot11fTDLSPeerTrafficRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSPeerTrafficRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSPeerTrafficRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSPeerTrafficRsp[] = { + {offsetof(tDot11fTDLSPeerTrafficRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Unpacked the TDLSPeerTrafficRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficRsp. */ + + static const tFFDefn FFS_TDLSSetupCnf[] = { + { "Category", offsetof(tDot11fTDLSSetupCnf, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupCnf, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Status", offsetof(tDot11fTDLSSetupCnf, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupCnf, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupCnf[] = { + {offsetof(tDot11fTDLSSetupCnf, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupCnf, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fTDLSSetupCnf, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupCnf, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupCnf, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fTDLSSetupCnf, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 0, }, + {offsetof(tDot11fTDLSSetupCnf, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fTDLSSetupCnf, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fTDLSSetupCnf, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupCnf *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupCnf, IES_TDLSSetupCnf, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Unpacked the TDLSSetupCnf:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupCnf. */ + + static const tFFDefn FFS_TDLSSetupReq[] = { + { "Category", offsetof(tDot11fTDLSSetupReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSSetupReq, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupReq[] = { + {offsetof(tDot11fTDLSSetupReq, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fTDLSSetupReq, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fTDLSSetupReq, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupReq, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSSetupReq, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSSetupReq, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSSetupReq, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fTDLSSetupReq, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupReq, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupReq, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSSetupReq, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupReq, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSSetupReq, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSSetupReq, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fTDLSSetupReq, AID), offsetof(tDot11fIEAID, present), 0, "AID" , 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, }, + {offsetof(tDot11fTDLSSetupReq, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupReq, IES_TDLSSetupReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Unpacked the TDLSSetupReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupReq. */ + + static const tFFDefn FFS_TDLSSetupRsp[] = { + { "Category", offsetof(tDot11fTDLSSetupRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Status", offsetof(tDot11fTDLSSetupRsp, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSSetupRsp, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupRsp[] = { + {offsetof(tDot11fTDLSSetupRsp, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fTDLSSetupRsp, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSSetupRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fTDLSSetupRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupRsp, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupRsp, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSSetupRsp, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSSetupRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 0, }, + {offsetof(tDot11fTDLSSetupRsp, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fTDLSSetupRsp, AID), offsetof(tDot11fIEAID, present), 0, "AID" , 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, }, + {offsetof(tDot11fTDLSSetupRsp, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupRsp, IES_TDLSSetupRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Unpacked the TDLSSetupRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupRsp. */ + + static const tFFDefn FFS_TDLSTeardown[] = { + { "Category", offsetof(tDot11fTDLSTeardown, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSTeardown, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Reason", offsetof(tDot11fTDLSTeardown, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSTeardown[] = { + {offsetof(tDot11fTDLSTeardown, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSTeardown, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSTeardown(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSTeardown *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSTeardown, IES_TDLSTeardown, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Unpacked the TDLSTeardown:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSTeardown. */ + + static const tFFDefn FFS_TPCReport[] = { + { "Category", offsetof(tDot11fTPCReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTPCReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTPCReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TPCReport[] = { + {offsetof(tDot11fTPCReport, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TPCReport, IES_TPCReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Unpacked the TPCReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCReport. */ + + static const tFFDefn FFS_TPCRequest[] = { + { "Category", offsetof(tDot11fTPCRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTPCRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTPCRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TPCRequest[] = { + {offsetof(tDot11fTPCRequest, TPCRequest), offsetof(tDot11fIETPCRequest, present), 0, "TPCRequest" , 0, 2, 2, SigIeTPCRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TPCRequest, IES_TPCRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Unpacked the TPCRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("TPCRequest:\n")); + if (!pFrm->TPCRequest.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Not present.\n")); + } + else + { + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCRequest. */ + + static const tFFDefn FFS_VHTGidManagementActionFrame[] = { + { "Category", offsetof(tDot11fVHTGidManagementActionFrame, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fVHTGidManagementActionFrame, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "VhtMembershipStatusArray", offsetof(tDot11fVHTGidManagementActionFrame, VhtMembershipStatusArray), SigFfVhtMembershipStatusArray , DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN, }, + { "VhtUserPositionArray", offsetof(tDot11fVHTGidManagementActionFrame, VhtUserPositionArray), SigFfVhtUserPositionArray , DOT11F_FF_VHTUSERPOSITIONARRAY_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_VHTGidManagementActionFrame[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fVHTGidManagementActionFrame *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Unpacked the VHTGidManagementActionFrame:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtMembershipStatusArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtMembershipStatusArray.membershipStatusArray, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtUserPositionArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtUserPositionArray.userPositionArray, 16); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackVHTGidManagementActionFrame. */ + + static const tFFDefn FFS_WMMAddTSRequest[] = { + { "Category", offsetof(tDot11fWMMAddTSRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMAddTSRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMAddTSRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMAddTSRequest, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMAddTSRequest[] = { + {offsetof(tDot11fWMMAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 1, }, + {offsetof(tDot11fWMMAddTSRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMAddTSRequest, IES_WMMAddTSRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Unpacked the WMMAddTSRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSRequest. */ + + static const tFFDefn FFS_WMMAddTSResponse[] = { + { "Category", offsetof(tDot11fWMMAddTSResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMAddTSResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMAddTSResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMAddTSResponse, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMAddTSResponse[] = { + {offsetof(tDot11fWMMAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fWMMAddTSResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMAddTSResponse, IES_WMMAddTSResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Unpacked the WMMAddTSResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSResponse. */ + + static const tFFDefn FFS_WMMDelTS[] = { + { "Category", offsetof(tDot11fWMMDelTS, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMDelTS, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMDelTS, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMDelTS, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMDelTS[] = { + {offsetof(tDot11fWMMDelTS, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMDelTS *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMDelTS, IES_WMMDelTS, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Unpacked the WMMDelTS:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMDelTS. */ + +static tANI_U32 UnpackCore(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tFFDefn FFs[], + const tIEDefn IEs[], + tANI_U8 *pFrm, + size_t nFrm) +{ + const tFFDefn *pFf; + const tIEDefn *pIe; + tANI_U8 *pBufRemaining; + tANI_U32 nBufRemaining, status; + tANI_U8 eid, len; + tFRAMES_BOOL *pfFound; + tANI_U32 countOffset = 0; + + DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm); + (void)nFrm; + + (void)pCtx; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pIe = &IEs[0]; + while (0xff != pIe->eid) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + *pfFound = 0U; + if (pIe->countOffset) + { + *( tANI_U16* )(pFrm + pIe->countOffset) = 0U; + } + ++pIe; + } + + pFf = &FFs[0]; + while (pFf->size) + { + if (pFf->size > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("Fixed field %s is %d b" + "ytes in size, but there are only %d bytes left i" + "n this frame.\n"), pFf->name, pFf->size, + nBufRemaining); + FRAMES_DBG_BREAK(); + return DOT11F_MISSING_FIXED_FIELD; + } + + switch (pFf->sig) + { + + case SigFfAID: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAID* )(pFrm + pFf->offset ))->associd)); + break; + case SigFfAction: + dot11fUnpackFfAction(pCtx, pBufRemaining, ( tDot11fFfAction* )(pFrm + pFf->offset )); + break; + case SigFfAddBAParameterSet: + dot11fUnpackFfAddBAParameterSet(pCtx, pBufRemaining, ( tDot11fFfAddBAParameterSet* )(pFrm + pFf->offset )); + break; + case SigFfAuthAlgo: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAuthAlgo* )(pFrm + pFf->offset ))->algo)); + break; + case SigFfAuthSeqNo: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAuthSeqNo* )(pFrm + pFf->offset ))->no)); + break; + case SigFfBAStartingSequenceControl: + dot11fUnpackFfBAStartingSequenceControl(pCtx, pBufRemaining, ( tDot11fFfBAStartingSequenceControl* )(pFrm + pFf->offset )); + break; + case SigFfBATimeout: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfBATimeout* )(pFrm + pFf->offset ))->timeout)); + break; + case SigFfBeaconInterval: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfBeaconInterval* )(pFrm + pFf->offset ))->interval)); + break; + case SigFfCapabilities: + dot11fUnpackFfCapabilities(pCtx, pBufRemaining, ( tDot11fFfCapabilities* )(pFrm + pFf->offset )); + break; + case SigFfCategory: + dot11fUnpackFfCategory(pCtx, pBufRemaining, ( tDot11fFfCategory* )(pFrm + pFf->offset )); + break; + case SigFfCurrentAPAddress: + dot11fUnpackFfCurrentAPAddress(pCtx, pBufRemaining, ( tDot11fFfCurrentAPAddress* )(pFrm + pFf->offset )); + break; + case SigFfDelBAParameterSet: + dot11fUnpackFfDelBAParameterSet(pCtx, pBufRemaining, ( tDot11fFfDelBAParameterSet* )(pFrm + pFf->offset )); + break; + case SigFfDialogToken: + dot11fUnpackFfDialogToken(pCtx, pBufRemaining, ( tDot11fFfDialogToken* )(pFrm + pFf->offset )); + break; + case SigFfLinkMargin: + dot11fUnpackFfLinkMargin(pCtx, pBufRemaining, ( tDot11fFfLinkMargin* )(pFrm + pFf->offset )); + break; + case SigFfListenInterval: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfListenInterval* )(pFrm + pFf->offset ))->interval)); + break; + case SigFfMaxTxPower: + dot11fUnpackFfMaxTxPower(pCtx, pBufRemaining, ( tDot11fFfMaxTxPower* )(pFrm + pFf->offset )); + break; + case SigFfNumOfRepetitions: + dot11fUnpackFfNumOfRepetitions(pCtx, pBufRemaining, ( tDot11fFfNumOfRepetitions* )(pFrm + pFf->offset )); + break; + case SigFfOperatingMode: + dot11fUnpackFfOperatingMode(pCtx, pBufRemaining, ( tDot11fFfOperatingMode* )(pFrm + pFf->offset )); + break; + case SigFfP2POUI: + dot11fUnpackFfP2POUI(pCtx, pBufRemaining, ( tDot11fFfP2POUI* )(pFrm + pFf->offset )); + break; + case SigFfP2POUISubType: + dot11fUnpackFfP2POUISubType(pCtx, pBufRemaining, ( tDot11fFfP2POUISubType* )(pFrm + pFf->offset )); + break; + case SigFfRCPI: + dot11fUnpackFfRCPI(pCtx, pBufRemaining, ( tDot11fFfRCPI* )(pFrm + pFf->offset )); + break; + case SigFfRSNI: + dot11fUnpackFfRSNI(pCtx, pBufRemaining, ( tDot11fFfRSNI* )(pFrm + pFf->offset )); + break; + case SigFfReason: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfReason* )(pFrm + pFf->offset ))->code)); + break; + case SigFfRxAntennaId: + dot11fUnpackFfRxAntennaId(pCtx, pBufRemaining, ( tDot11fFfRxAntennaId* )(pFrm + pFf->offset )); + break; + case SigFfSMPowerModeSet: + dot11fUnpackFfSMPowerModeSet(pCtx, pBufRemaining, ( tDot11fFfSMPowerModeSet* )(pFrm + pFf->offset )); + break; + case SigFfStatus: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfStatus* )(pFrm + pFf->offset ))->status)); + break; + case SigFfStatusCode: + dot11fUnpackFfStatusCode(pCtx, pBufRemaining, ( tDot11fFfStatusCode* )(pFrm + pFf->offset )); + break; + case SigFfTPCEleID: + dot11fUnpackFfTPCEleID(pCtx, pBufRemaining, ( tDot11fFfTPCEleID* )(pFrm + pFf->offset )); + break; + case SigFfTPCEleLen: + dot11fUnpackFfTPCEleLen(pCtx, pBufRemaining, ( tDot11fFfTPCEleLen* )(pFrm + pFf->offset )); + break; + case SigFfTSInfo: + dot11fUnpackFfTSInfo(pCtx, pBufRemaining, ( tDot11fFfTSInfo* )(pFrm + pFf->offset )); + break; + case SigFfTimeStamp: + dot11fUnpackFfTimeStamp(pCtx, pBufRemaining, ( tDot11fFfTimeStamp* )(pFrm + pFf->offset )); + break; + case SigFfTransactionId: + dot11fUnpackFfTransactionId(pCtx, pBufRemaining, ( tDot11fFfTransactionId* )(pFrm + pFf->offset )); + break; + case SigFfTxAntennaId: + dot11fUnpackFfTxAntennaId(pCtx, pBufRemaining, ( tDot11fFfTxAntennaId* )(pFrm + pFf->offset )); + break; + case SigFfTxPower: + dot11fUnpackFfTxPower(pCtx, pBufRemaining, ( tDot11fFfTxPower* )(pFrm + pFf->offset )); + break; + case SigFfVhtMembershipStatusArray: + dot11fUnpackFfVhtMembershipStatusArray(pCtx, pBufRemaining, ( tDot11fFfVhtMembershipStatusArray* )(pFrm + pFf->offset )); + break; + case SigFfVhtUserPositionArray: + dot11fUnpackFfVhtUserPositionArray(pCtx, pBufRemaining, ( tDot11fFfVhtUserPositionArray* )(pFrm + pFf->offset )); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I don'" + "t know about the FF signature %d-- this is most " + "likely a 'framesc' bug.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += pFf->size; + nBufRemaining -= pFf->size; + ++pFf; + } + + while (nBufRemaining) + { + if (1 == nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports " + "only one byte remaining after it's fixed fields.\n")); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + pIe = FindIEDefn(pCtx, pBufRemaining, nBufRemaining, IEs); + + eid = *pBufRemaining++; --nBufRemaining; + len = *pBufRemaining++; --nBufRemaining; + + if (pIe && pIe->noui) + { + if (pIe->noui > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports " + "length %d, but it has an OUI of %d bytes.\n"), + eid, len, pIe->noui); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += pIe->noui; + nBufRemaining -= pIe->noui; + len -= pIe->noui; + } + + if (len > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports length %" + "d, but there are only %d bytes remaining in this" + " frame.\n"), eid, len, nBufRemaining); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + if (pIe) + { + if (nBufRemaining < pIe->minSize - pIe->noui - 2U) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are onl" + "y %d bytes remaining in this frame.\n"), + pIe->name, pIe->minSize, nBufRemaining); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + else + { + if (len > pIe->maxSize - pIe->noui - 2U){ + FRAMES_LOG1(pCtx, FRLOGW, FRFL("The IE %s reports " + "an unexpectedly large size; it is presumably " + "more up-to-date than this parser, but this wa" + "rning may also indicate a corrupt frame.\n"), + pIe->name); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + } + + countOffset = ( (0 != pIe->arraybound) * ( *(tANI_U16* )(pFrm + pIe->countOffset))); + switch (pIe->sig) + { + case SigIeAPName: + status |= dot11fUnpackIeAPName(pCtx, pBufRemaining, len, ( tDot11fIEAPName* )(pFrm + pIe->offset + sizeof(tDot11fIEAPName)*countOffset) ); + break; + case SigIeBPIndicator: + status |= dot11fUnpackIeBPIndicator(pCtx, pBufRemaining, len, ( tDot11fIEBPIndicator* )(pFrm + pIe->offset + sizeof(tDot11fIEBPIndicator)*countOffset) ); + break; + case SigIeCondensedCountryStr: + status |= dot11fUnpackIeCondensedCountryStr(pCtx, pBufRemaining, len, ( tDot11fIECondensedCountryStr* )(pFrm + pIe->offset + sizeof(tDot11fIECondensedCountryStr)*countOffset) ); + break; + case SigIeGTK: + status |= dot11fUnpackIeGTK(pCtx, pBufRemaining, len, ( tDot11fIEGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEGTK)*countOffset) ); + break; + case SigIeHCF: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEHCF* )(pFrm + pIe->offset + sizeof( tDot11fIEHCF)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEHCF* )(pFrm + pIe->offset + sizeof(tDot11fIEHCF)*countOffset ) )->enabled) ); + break; + case SigIeIGTK: + status |= dot11fUnpackIeIGTK(pCtx, pBufRemaining, len, ( tDot11fIEIGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEIGTK)*countOffset) ); + break; + case SigIeLLAttr: + status |= dot11fUnpackIeLLAttr(pCtx, pBufRemaining, len, ( tDot11fIELLAttr* )(pFrm + pIe->offset + sizeof(tDot11fIELLAttr)*countOffset) ); + break; + case SigIeLoadBalance: + status |= dot11fUnpackIeLoadBalance(pCtx, pBufRemaining, len, ( tDot11fIELoadBalance* )(pFrm + pIe->offset + sizeof(tDot11fIELoadBalance)*countOffset) ); + break; + case SigIeLoadInfo: + status |= dot11fUnpackIeLoadInfo(pCtx, pBufRemaining, len, ( tDot11fIELoadInfo* )(pFrm + pIe->offset + sizeof(tDot11fIELoadInfo)*countOffset) ); + break; + case SigIePropAssocType: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEPropAssocType* )(pFrm + pIe->offset + sizeof( tDot11fIEPropAssocType)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEPropAssocType* )(pFrm + pIe->offset + sizeof(tDot11fIEPropAssocType)*countOffset ) )->type) ); + break; + case SigIePropCapability: + status |= dot11fUnpackIePropCapability(pCtx, pBufRemaining, len, ( tDot11fIEPropCapability* )(pFrm + pIe->offset + sizeof(tDot11fIEPropCapability)*countOffset) ); + break; + case SigIePropChannSwitchAnn: + status |= dot11fUnpackIePropChannSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEPropChannSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEPropChannSwitchAnn)*countOffset) ); + break; + case SigIePropEDCAParams: + status |= dot11fUnpackIePropEDCAParams(pCtx, pBufRemaining, len, ( tDot11fIEPropEDCAParams* )(pFrm + pIe->offset + sizeof(tDot11fIEPropEDCAParams)*countOffset) ); + break; + case SigIePropQuietBSS: + status |= dot11fUnpackIePropQuietBSS(pCtx, pBufRemaining, len, ( tDot11fIEPropQuietBSS* )(pFrm + pIe->offset + sizeof(tDot11fIEPropQuietBSS)*countOffset) ); + break; + case SigIePropSuppRates: + status |= dot11fUnpackIePropSuppRates(pCtx, pBufRemaining, len, ( tDot11fIEPropSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEPropSuppRates)*countOffset) ); + break; + case SigIeR0KH_ID: + status |= dot11fUnpackIeR0KH_ID(pCtx, pBufRemaining, len, ( tDot11fIER0KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER0KH_ID)*countOffset) ); + break; + case SigIeR1KH_ID: + status |= dot11fUnpackIeR1KH_ID(pCtx, pBufRemaining, len, ( tDot11fIER1KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER1KH_ID)*countOffset) ); + break; + case SigIeTSFInfo: + status |= dot11fUnpackIeTSFInfo(pCtx, pBufRemaining, len, ( tDot11fIETSFInfo* )(pFrm + pIe->offset + sizeof(tDot11fIETSFInfo)*countOffset) ); + break; + case SigIeTaurus: + status |= dot11fUnpackIeTaurus(pCtx, pBufRemaining, len, ( tDot11fIETaurus* )(pFrm + pIe->offset + sizeof(tDot11fIETaurus)*countOffset) ); + break; + case SigIeTitan: + status |= dot11fUnpackIeTitan(pCtx, pBufRemaining, len, ( tDot11fIETitan* )(pFrm + pIe->offset + sizeof(tDot11fIETitan)*countOffset) ); + break; + case SigIeTriggerStaBgScan: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + sizeof( tDot11fIETriggerStaBgScan)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + sizeof(tDot11fIETriggerStaBgScan)*countOffset ) )->enable) ); + break; + case SigIeVersion: + status |= dot11fUnpackIeVersion(pCtx, pBufRemaining, len, ( tDot11fIEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEVersion)*countOffset) ); + break; + case SigIeWDS: + status |= dot11fUnpackIeWDS(pCtx, pBufRemaining, len, ( tDot11fIEWDS* )(pFrm + pIe->offset + sizeof(tDot11fIEWDS)*countOffset) ); + break; + case SigIeAPChannelReport: + status |= dot11fUnpackIeAPChannelReport(pCtx, pBufRemaining, len, ( tDot11fIEAPChannelReport* )(pFrm + pIe->offset + sizeof(tDot11fIEAPChannelReport)*countOffset) ); + break; + case SigIeBcnReportingDetail: + status |= dot11fUnpackIeBcnReportingDetail(pCtx, pBufRemaining, len, ( tDot11fIEBcnReportingDetail* )(pFrm + pIe->offset + sizeof(tDot11fIEBcnReportingDetail)*countOffset) ); + break; + case SigIeBeaconReportFrmBody: + status |= dot11fUnpackIeBeaconReportFrmBody(pCtx, pBufRemaining, len, ( tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody)*countOffset) ); + break; + case SigIeBeaconReporting: + status |= dot11fUnpackIeBeaconReporting(pCtx, pBufRemaining, len, ( tDot11fIEBeaconReporting* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReporting)*countOffset) ); + break; + case SigIeMeasurementPilot: + status |= dot11fUnpackIeMeasurementPilot(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementPilot)*countOffset) ); + break; + case SigIeMultiBssid: + status |= dot11fUnpackIeMultiBssid(pCtx, pBufRemaining, len, ( tDot11fIEMultiBssid* )(pFrm + pIe->offset + sizeof(tDot11fIEMultiBssid)*countOffset) ); + break; + case SigIeRICData: + status |= dot11fUnpackIeRICData(pCtx, pBufRemaining, len, ( tDot11fIERICData* )(pFrm + pIe->offset + sizeof(tDot11fIERICData)*countOffset) ); + break; + case SigIeRICDescriptor: + status |= dot11fUnpackIeRICDescriptor(pCtx, pBufRemaining, len, ( tDot11fIERICDescriptor* )(pFrm + pIe->offset + sizeof(tDot11fIERICDescriptor)*countOffset) ); + break; + case SigIeRRMEnabledCap: + status |= dot11fUnpackIeRRMEnabledCap(pCtx, pBufRemaining, len, ( tDot11fIERRMEnabledCap* )(pFrm + pIe->offset + sizeof(tDot11fIERRMEnabledCap)*countOffset) ); + break; + case SigIeRequestedInfo: + status |= dot11fUnpackIeRequestedInfo(pCtx, pBufRemaining, len, ( tDot11fIERequestedInfo* )(pFrm + pIe->offset + sizeof(tDot11fIERequestedInfo)*countOffset) ); + break; + case SigIeSSID: + status |= dot11fUnpackIeSSID(pCtx, pBufRemaining, len, ( tDot11fIESSID* )(pFrm + pIe->offset + sizeof(tDot11fIESSID)*countOffset) ); + break; + case SigIeSchedule: + status |= dot11fUnpackIeSchedule(pCtx, pBufRemaining, len, ( tDot11fIESchedule* )(pFrm + pIe->offset + sizeof(tDot11fIESchedule)*countOffset) ); + break; + case SigIeTCLAS: + status |= dot11fUnpackIeTCLAS(pCtx, pBufRemaining, len, ( tDot11fIETCLAS* )(pFrm + pIe->offset + sizeof(tDot11fIETCLAS)*countOffset) ); + break; + case SigIeTCLASSPROC: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIETCLASSPROC* )(pFrm + pIe->offset + sizeof( tDot11fIETCLASSPROC)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIETCLASSPROC* )(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset ) )->processing) ); + break; + case SigIeTSDelay: + status |= dot11fUnpackIeTSDelay(pCtx, pBufRemaining, len, ( tDot11fIETSDelay* )(pFrm + pIe->offset + sizeof(tDot11fIETSDelay)*countOffset) ); + break; + case SigIeTSPEC: + status |= dot11fUnpackIeTSPEC(pCtx, pBufRemaining, len, ( tDot11fIETSPEC* )(pFrm + pIe->offset + sizeof(tDot11fIETSPEC)*countOffset) ); + break; + case SigIeWMMSchedule: + status |= dot11fUnpackIeWMMSchedule(pCtx, pBufRemaining, len, ( tDot11fIEWMMSchedule* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMSchedule)*countOffset) ); + break; + case SigIeWMMTCLAS: + status |= dot11fUnpackIeWMMTCLAS(pCtx, pBufRemaining, len, ( tDot11fIEWMMTCLAS* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTCLAS)*countOffset) ); + break; + case SigIeWMMTCLASPROC: + status |= dot11fUnpackIeWMMTCLASPROC(pCtx, pBufRemaining, len, ( tDot11fIEWMMTCLASPROC* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTCLASPROC)*countOffset) ); + break; + case SigIeWMMTSDelay: + status |= dot11fUnpackIeWMMTSDelay(pCtx, pBufRemaining, len, ( tDot11fIEWMMTSDelay* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTSDelay)*countOffset) ); + break; + case SigIeWMMTSPEC: + status |= dot11fUnpackIeWMMTSPEC(pCtx, pBufRemaining, len, ( tDot11fIEWMMTSPEC* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTSPEC)*countOffset) ); + break; + case SigIeWiderBWChanSwitchAnn: + status |= dot11fUnpackIeWiderBWChanSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEWiderBWChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEWiderBWChanSwitchAnn)*countOffset) ); + break; + case SigIeAID: + status |= dot11fUnpackIeAID(pCtx, pBufRemaining, len, ( tDot11fIEAID* )(pFrm + pIe->offset + sizeof(tDot11fIEAID)*countOffset) ); + break; + case SigIeAirgo: + status |= dot11fUnpackIeAirgo(pCtx, pBufRemaining, len, ( tDot11fIEAirgo* )(pFrm + pIe->offset + sizeof(tDot11fIEAirgo)*countOffset) ); + break; + case SigIeCFParams: + status |= dot11fUnpackIeCFParams(pCtx, pBufRemaining, len, ( tDot11fIECFParams* )(pFrm + pIe->offset + sizeof(tDot11fIECFParams)*countOffset) ); + break; + case SigIeChallengeText: + status |= dot11fUnpackIeChallengeText(pCtx, pBufRemaining, len, ( tDot11fIEChallengeText* )(pFrm + pIe->offset + sizeof(tDot11fIEChallengeText)*countOffset) ); + break; + case SigIeChanSwitchAnn: + status |= dot11fUnpackIeChanSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEChanSwitchAnn)*countOffset) ); + break; + case SigIeChannelSwitchWrapper: + status |= dot11fUnpackIeChannelSwitchWrapper(pCtx, pBufRemaining, len, ( tDot11fIEChannelSwitchWrapper* )(pFrm + pIe->offset + sizeof(tDot11fIEChannelSwitchWrapper)*countOffset) ); + break; + case SigIeCountry: + status |= dot11fUnpackIeCountry(pCtx, pBufRemaining, len, ( tDot11fIECountry* )(pFrm + pIe->offset + sizeof(tDot11fIECountry)*countOffset) ); + break; + case SigIeDSParams: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEDSParams* )(pFrm + pIe->offset + sizeof( tDot11fIEDSParams)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEDSParams* )(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset ) )->curr_channel) ); + break; + case SigIeEDCAParamSet: + status |= dot11fUnpackIeEDCAParamSet(pCtx, pBufRemaining, len, ( tDot11fIEEDCAParamSet* )(pFrm + pIe->offset + sizeof(tDot11fIEEDCAParamSet)*countOffset) ); + break; + case SigIeERPInfo: + status |= dot11fUnpackIeERPInfo(pCtx, pBufRemaining, len, ( tDot11fIEERPInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEERPInfo)*countOffset) ); + break; + case SigIeESECckmOpaque: + status |= dot11fUnpackIeESECckmOpaque(pCtx, pBufRemaining, len, ( tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEESECckmOpaque)*countOffset) ); + break; + case SigIeESERadMgmtCap: + status |= dot11fUnpackIeESERadMgmtCap(pCtx, pBufRemaining, len, ( tDot11fIEESERadMgmtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEESERadMgmtCap)*countOffset) ); + break; + case SigIeESETrafStrmMet: + status |= dot11fUnpackIeESETrafStrmMet(pCtx, pBufRemaining, len, ( tDot11fIEESETrafStrmMet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmMet)*countOffset) ); + break; + case SigIeESETrafStrmRateSet: + status |= dot11fUnpackIeESETrafStrmRateSet(pCtx, pBufRemaining, len, ( tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet)*countOffset) ); + break; + case SigIeESETxmitPower: + status |= dot11fUnpackIeESETxmitPower(pCtx, pBufRemaining, len, ( tDot11fIEESETxmitPower* )(pFrm + pIe->offset + sizeof(tDot11fIEESETxmitPower)*countOffset) ); + break; + case SigIeESEVersion: + status |= dot11fUnpackIeESEVersion(pCtx, pBufRemaining, len, ( tDot11fIEESEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEESEVersion)*countOffset) ); + break; + case SigIeExtCap: + status |= dot11fUnpackIeExtCap(pCtx, pBufRemaining, len, ( tDot11fIEExtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEExtCap)*countOffset) ); + break; + case SigIeExtChanSwitchAnn: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + sizeof( tDot11fIEExtChanSwitchAnn)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEExtChanSwitchAnn)*countOffset ) )->secondaryChannelOffset) ); + break; + case SigIeExtSuppRates: + status |= dot11fUnpackIeExtSuppRates(pCtx, pBufRemaining, len, ( tDot11fIEExtSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEExtSuppRates)*countOffset) ); + break; + case SigIeFHParamSet: + status |= dot11fUnpackIeFHParamSet(pCtx, pBufRemaining, len, ( tDot11fIEFHParamSet* )(pFrm + pIe->offset + sizeof(tDot11fIEFHParamSet)*countOffset) ); + break; + case SigIeFHParams: + status |= dot11fUnpackIeFHParams(pCtx, pBufRemaining, len, ( tDot11fIEFHParams* )(pFrm + pIe->offset + sizeof(tDot11fIEFHParams)*countOffset) ); + break; + case SigIeFHPattTable: + status |= dot11fUnpackIeFHPattTable(pCtx, pBufRemaining, len, ( tDot11fIEFHPattTable* )(pFrm + pIe->offset + sizeof(tDot11fIEFHPattTable)*countOffset) ); + break; + case SigIeFTInfo: + status |= dot11fUnpackIeFTInfo(pCtx, pBufRemaining, len, ( tDot11fIEFTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEFTInfo)*countOffset) ); + break; + case SigIeHT2040BSSCoexistence: + status |= dot11fUnpackIeHT2040BSSCoexistence(pCtx, pBufRemaining, len, ( tDot11fIEHT2040BSSCoexistence* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSCoexistence)*countOffset) ); + break; + case SigIeHT2040BSSIntolerantReport: + status |= dot11fUnpackIeHT2040BSSIntolerantReport(pCtx, pBufRemaining, len, ( tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport)*countOffset) ); + break; + case SigIeHTCaps: + status |= dot11fUnpackIeHTCaps(pCtx, pBufRemaining, len, ( tDot11fIEHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEHTCaps)*countOffset) ); + break; + case SigIeHTInfo: + status |= dot11fUnpackIeHTInfo(pCtx, pBufRemaining, len, ( tDot11fIEHTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEHTInfo)*countOffset) ); + break; + case SigIeIBSSParams: + status |= dot11fUnpackIeIBSSParams(pCtx, pBufRemaining, len, ( tDot11fIEIBSSParams* )(pFrm + pIe->offset + sizeof(tDot11fIEIBSSParams)*countOffset) ); + break; + case SigIeLinkIdentifier: + status |= dot11fUnpackIeLinkIdentifier(pCtx, pBufRemaining, len, ( tDot11fIELinkIdentifier* )(pFrm + pIe->offset + sizeof(tDot11fIELinkIdentifier)*countOffset) ); + break; + case SigIeMeasurementReport: + status |= dot11fUnpackIeMeasurementReport(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementReport* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementReport)*countOffset) ); + break; + case SigIeMeasurementRequest: + status |= dot11fUnpackIeMeasurementRequest(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementRequest* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementRequest)*countOffset) ); + break; + case SigIeMobilityDomain: + status |= dot11fUnpackIeMobilityDomain(pCtx, pBufRemaining, len, ( tDot11fIEMobilityDomain* )(pFrm + pIe->offset + sizeof(tDot11fIEMobilityDomain)*countOffset) ); + break; + case SigIeNeighborReport: + if (countOffset < MAX_SUPPORTED_NEIGHBOR_RPT) { + status |= dot11fUnpackIeNeighborReport(pCtx, pBufRemaining, len, ( tDot11fIENeighborReport* )(pFrm + pIe->offset + sizeof(tDot11fIENeighborReport)*countOffset) ); + } else { + status |= DOT11F_BUFFER_OVERFLOW; + } + break; + case SigIeOBSSScanParameters: + status |= dot11fUnpackIeOBSSScanParameters(pCtx, pBufRemaining, len, ( tDot11fIEOBSSScanParameters* )(pFrm + pIe->offset + sizeof(tDot11fIEOBSSScanParameters)*countOffset) ); + break; + case SigIeOperatingMode: + status |= dot11fUnpackIeOperatingMode(pCtx, pBufRemaining, len, ( tDot11fIEOperatingMode* )(pFrm + pIe->offset + sizeof(tDot11fIEOperatingMode)*countOffset) ); + break; + case SigIeP2PAssocReq: + status |= dot11fUnpackIeP2PAssocReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PAssocReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PAssocReq)*countOffset) ); + break; + case SigIeP2PAssocRes: + status |= dot11fUnpackIeP2PAssocRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PAssocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PAssocRes)*countOffset) ); + break; + case SigIeP2PBeacon: + status |= dot11fUnpackIeP2PBeacon(pCtx, pBufRemaining, len, ( tDot11fIEP2PBeacon* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PBeacon)*countOffset) ); + break; + case SigIeP2PBeaconProbeRes: + status |= dot11fUnpackIeP2PBeaconProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PBeaconProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PBeaconProbeRes)*countOffset) ); + break; + case SigIeP2PDeAuth: + status |= dot11fUnpackIeP2PDeAuth(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeAuth* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeAuth)*countOffset) ); + break; + case SigIeP2PDeviceDiscoverabilityReq: + status |= dot11fUnpackIeP2PDeviceDiscoverabilityReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityReq)*countOffset) ); + break; + case SigIeP2PDeviceDiscoverabilityRes: + status |= dot11fUnpackIeP2PDeviceDiscoverabilityRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityRes)*countOffset) ); + break; + case SigIeP2PDisAssoc: + status |= dot11fUnpackIeP2PDisAssoc(pCtx, pBufRemaining, len, ( tDot11fIEP2PDisAssoc* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDisAssoc)*countOffset) ); + break; + case SigIeP2PGONegCnf: + status |= dot11fUnpackIeP2PGONegCnf(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegCnf* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegCnf)*countOffset) ); + break; + case SigIeP2PGONegReq: + status |= dot11fUnpackIeP2PGONegReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegReq)*countOffset) ); + break; + case SigIeP2PGONegRes: + status |= dot11fUnpackIeP2PGONegRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegRes)*countOffset) ); + break; + case SigIeP2PGONegWPS: + status |= dot11fUnpackIeP2PGONegWPS(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegWPS* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegWPS)*countOffset) ); + break; + case SigIeP2PIEOpaque: + status |= dot11fUnpackIeP2PIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PIEOpaque)*countOffset) ); + break; + case SigIeP2PInvitationReq: + status |= dot11fUnpackIeP2PInvitationReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PInvitationReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PInvitationReq)*countOffset) ); + break; + case SigIeP2PInvitationRes: + status |= dot11fUnpackIeP2PInvitationRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PInvitationRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PInvitationRes)*countOffset) ); + break; + case SigIeP2PNoticeOfAbsence: + status |= dot11fUnpackIeP2PNoticeOfAbsence(pCtx, pBufRemaining, len, ( tDot11fIEP2PNoticeOfAbsence* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PNoticeOfAbsence)*countOffset) ); + break; + case SigIeP2PPresenceResponse: + status |= dot11fUnpackIeP2PPresenceResponse(pCtx, pBufRemaining, len, ( tDot11fIEP2PPresenceResponse* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PPresenceResponse)*countOffset) ); + break; + case SigIeP2PProbeReq: + status |= dot11fUnpackIeP2PProbeReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PProbeReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProbeReq)*countOffset) ); + break; + case SigIeP2PProbeRes: + status |= dot11fUnpackIeP2PProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProbeRes)*countOffset) ); + break; + case SigIeP2PProvisionDiscoveryReq: + status |= dot11fUnpackIeP2PProvisionDiscoveryReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PProvisionDiscoveryReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProvisionDiscoveryReq)*countOffset) ); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + status |= dot11fUnpackIeP2PWSCProvisionDiscoveryRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes)*countOffset) ); + break; + case SigIePTIControl: + status |= dot11fUnpackIePTIControl(pCtx, pBufRemaining, len, ( tDot11fIEPTIControl* )(pFrm + pIe->offset + sizeof(tDot11fIEPTIControl)*countOffset) ); + break; + case SigIePUBufferStatus: + status |= dot11fUnpackIePUBufferStatus(pCtx, pBufRemaining, len, ( tDot11fIEPUBufferStatus* )(pFrm + pIe->offset + sizeof(tDot11fIEPUBufferStatus)*countOffset) ); + break; + case SigIePowerCaps: + status |= dot11fUnpackIePowerCaps(pCtx, pBufRemaining, len, ( tDot11fIEPowerCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEPowerCaps)*countOffset) ); + break; + case SigIePowerConstraints: + status |= dot11fUnpackIePowerConstraints(pCtx, pBufRemaining, len, ( tDot11fIEPowerConstraints* )(pFrm + pIe->offset + sizeof(tDot11fIEPowerConstraints)*countOffset) ); + break; + case SigIeQBSSLoad: + status |= dot11fUnpackIeQBSSLoad(pCtx, pBufRemaining, len, ( tDot11fIEQBSSLoad* )(pFrm + pIe->offset + sizeof(tDot11fIEQBSSLoad)*countOffset) ); + break; + case SigIeQOSCapsAp: + status |= dot11fUnpackIeQOSCapsAp(pCtx, pBufRemaining, len, ( tDot11fIEQOSCapsAp* )(pFrm + pIe->offset + sizeof(tDot11fIEQOSCapsAp)*countOffset) ); + break; + case SigIeQOSCapsStation: + status |= dot11fUnpackIeQOSCapsStation(pCtx, pBufRemaining, len, ( tDot11fIEQOSCapsStation* )(pFrm + pIe->offset + sizeof(tDot11fIEQOSCapsStation)*countOffset) ); + break; + case SigIeQosMapSet: + status |= dot11fUnpackIeQosMapSet(pCtx, pBufRemaining, len, ( tDot11fIEQosMapSet* )(pFrm + pIe->offset + sizeof(tDot11fIEQosMapSet)*countOffset) ); + break; + case SigIeQuiet: + status |= dot11fUnpackIeQuiet(pCtx, pBufRemaining, len, ( tDot11fIEQuiet* )(pFrm + pIe->offset + sizeof(tDot11fIEQuiet)*countOffset) ); + break; + case SigIeRCPIIE: + status |= dot11fUnpackIeRCPIIE(pCtx, pBufRemaining, len, ( tDot11fIERCPIIE* )(pFrm + pIe->offset + sizeof(tDot11fIERCPIIE)*countOffset) ); + break; + case SigIeRICDataDesc: + //reset the pointers back since this is a container IE and it doesnt have its own EID and Len. + pBufRemaining -= 2; nBufRemaining += 2; + if ( pIe && pIe->noui ) + { + pBufRemaining -= pIe->noui; + nBufRemaining += pIe->noui; + len += pIe->noui; + } + status |= GetContainerIesLen(pCtx, pBufRemaining, nBufRemaining, &len, IES_RICDataDesc); + if (status != DOT11F_PARSE_SUCCESS && status != DOT11F_UNKNOWN_IES ) break; + status |= dot11fUnpackIeRICDataDesc(pCtx, pBufRemaining, len, ( tDot11fIERICDataDesc* )(pFrm + pIe->offset + sizeof(tDot11fIERICDataDesc)*countOffset) ); + break; + case SigIeRSN: + status |= dot11fUnpackIeRSN(pCtx, pBufRemaining, len, ( tDot11fIERSN* )(pFrm + pIe->offset + sizeof(tDot11fIERSN)*countOffset) ); + break; + case SigIeRSNIIE: + status |= dot11fUnpackIeRSNIIE(pCtx, pBufRemaining, len, ( tDot11fIERSNIIE* )(pFrm + pIe->offset + sizeof(tDot11fIERSNIIE)*countOffset) ); + break; + case SigIeRSNOpaque: + status |= dot11fUnpackIeRSNOpaque(pCtx, pBufRemaining, len, ( tDot11fIERSNOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIERSNOpaque)*countOffset) ); + break; + case SigIeSuppChannels: + status |= dot11fUnpackIeSuppChannels(pCtx, pBufRemaining, len, ( tDot11fIESuppChannels* )(pFrm + pIe->offset + sizeof(tDot11fIESuppChannels)*countOffset) ); + break; + case SigIeSuppOperatingClasses: + status |= dot11fUnpackIeSuppOperatingClasses(pCtx, pBufRemaining, len, ( tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + sizeof(tDot11fIESuppOperatingClasses)*countOffset) ); + break; + case SigIeSuppRates: + status |= dot11fUnpackIeSuppRates(pCtx, pBufRemaining, len, ( tDot11fIESuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIESuppRates)*countOffset) ); + break; + case SigIeTIM: + status |= dot11fUnpackIeTIM(pCtx, pBufRemaining, len, ( tDot11fIETIM* )(pFrm + pIe->offset + sizeof(tDot11fIETIM)*countOffset) ); + break; + case SigIeTPCReport: + status |= dot11fUnpackIeTPCReport(pCtx, pBufRemaining, len, ( tDot11fIETPCReport* )(pFrm + pIe->offset + sizeof(tDot11fIETPCReport)*countOffset) ); + break; + case SigIeTPCRequest: + status |= dot11fUnpackIeTPCRequest(pCtx, pBufRemaining, len, ( tDot11fIETPCRequest* )(pFrm + pIe->offset + sizeof(tDot11fIETPCRequest)*countOffset) ); + break; + case SigIeTimeoutInterval: + status |= dot11fUnpackIeTimeoutInterval(pCtx, pBufRemaining, len, ( tDot11fIETimeoutInterval* )(pFrm + pIe->offset + sizeof(tDot11fIETimeoutInterval)*countOffset) ); + break; + case SigIeVHTCaps: + status |= dot11fUnpackIeVHTCaps(pCtx, pBufRemaining, len, ( tDot11fIEVHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTCaps)*countOffset) ); + break; + case SigIeVHTExtBssLoad: + status |= dot11fUnpackIeVHTExtBssLoad(pCtx, pBufRemaining, len, ( tDot11fIEVHTExtBssLoad* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTExtBssLoad)*countOffset) ); + break; + case SigIeVHTOperation: + status |= dot11fUnpackIeVHTOperation(pCtx, pBufRemaining, len, ( tDot11fIEVHTOperation* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTOperation)*countOffset) ); + break; + case SigIeVendor1IE: + status |= dot11fUnpackIeVendor1IE(pCtx, pBufRemaining, len, ( tDot11fIEVendor1IE* )(pFrm + pIe->offset + sizeof(tDot11fIEVendor1IE)*countOffset) ); + break; + case SigIeVendor2IE: + status |= dot11fUnpackIeVendor2IE(pCtx, pBufRemaining, len, ( tDot11fIEVendor2IE* )(pFrm + pIe->offset + sizeof(tDot11fIEVendor2IE)*countOffset) ); + break; + case SigIeVendor3IE: + status |= dot11fUnpackIeVendor3IE(pCtx, pBufRemaining, len, ( tDot11fIEVendor3IE* )(pFrm + pIe->offset + sizeof(tDot11fIEVendor3IE)*countOffset) ); + break; + case SigIeWAPI: + status |= dot11fUnpackIeWAPI(pCtx, pBufRemaining, len, ( tDot11fIEWAPI* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPI)*countOffset) ); + break; + case SigIeWAPIOpaque: + status |= dot11fUnpackIeWAPIOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPIOpaque)*countOffset) ); + break; + case SigIeWFATPC: + status |= dot11fUnpackIeWFATPC(pCtx, pBufRemaining, len, ( tDot11fIEWFATPC* )(pFrm + pIe->offset + sizeof(tDot11fIEWFATPC)*countOffset) ); + break; + case SigIeWFDIEOpaque: + status |= dot11fUnpackIeWFDIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWFDIEOpaque)*countOffset) ); + break; + case SigIeWMMCaps: + status |= dot11fUnpackIeWMMCaps(pCtx, pBufRemaining, len, ( tDot11fIEWMMCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMCaps)*countOffset) ); + break; + case SigIeWMMInfoAp: + status |= dot11fUnpackIeWMMInfoAp(pCtx, pBufRemaining, len, ( tDot11fIEWMMInfoAp* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMInfoAp)*countOffset) ); + break; + case SigIeWMMInfoStation: + status |= dot11fUnpackIeWMMInfoStation(pCtx, pBufRemaining, len, ( tDot11fIEWMMInfoStation* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMInfoStation)*countOffset) ); + break; + case SigIeWMMParams: + status |= dot11fUnpackIeWMMParams(pCtx, pBufRemaining, len, ( tDot11fIEWMMParams* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMParams)*countOffset) ); + break; + case SigIeWPA: + status |= dot11fUnpackIeWPA(pCtx, pBufRemaining, len, ( tDot11fIEWPA* )(pFrm + pIe->offset + sizeof(tDot11fIEWPA)*countOffset) ); + break; + case SigIeWPAOpaque: + status |= dot11fUnpackIeWPAOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWPAOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWPAOpaque)*countOffset) ); + break; + case SigIeWSC: + status |= dot11fUnpackIeWSC(pCtx, pBufRemaining, len, ( tDot11fIEWSC* )(pFrm + pIe->offset + sizeof(tDot11fIEWSC)*countOffset) ); + break; + case SigIeWscAssocReq: + status |= dot11fUnpackIeWscAssocReq(pCtx, pBufRemaining, len, ( tDot11fIEWscAssocReq* )(pFrm + pIe->offset + sizeof(tDot11fIEWscAssocReq)*countOffset) ); + break; + case SigIeWscAssocRes: + status |= dot11fUnpackIeWscAssocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscAssocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscAssocRes)*countOffset) ); + break; + case SigIeWscBeacon: + status |= dot11fUnpackIeWscBeacon(pCtx, pBufRemaining, len, ( tDot11fIEWscBeacon* )(pFrm + pIe->offset + sizeof(tDot11fIEWscBeacon)*countOffset) ); + break; + case SigIeWscBeaconProbeRes: + status |= dot11fUnpackIeWscBeaconProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEWscBeaconProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscBeaconProbeRes)*countOffset) ); + break; + case SigIeWscIEOpaque: + status |= dot11fUnpackIeWscIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWscIEOpaque)*countOffset) ); + break; + case SigIeWscProbeReq: + status |= dot11fUnpackIeWscProbeReq(pCtx, pBufRemaining, len, ( tDot11fIEWscProbeReq* )(pFrm + pIe->offset + sizeof(tDot11fIEWscProbeReq)*countOffset) ); + break; + case SigIeWscProbeRes: + status |= dot11fUnpackIeWscProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEWscProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscProbeRes)*countOffset) ); + break; + case SigIeWscReassocRes: + status |= dot11fUnpackIeWscReassocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscReassocRes)*countOffset) ); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR" + ": I don't know about the IE signature %d" + "-- this is most likely a 'framesc' bug.\n"), + pIe->sig); + FRAMES_DBG_BREAK(); + return DOT11F_INTERNAL_ERROR; + } + if (pIe->arraybound) (++( *(tANI_U16*)(pFrm + pIe->countOffset) )); + } + + + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown IE %d" + " (length %d)\n"), eid, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - 2, len); + status |= DOT11F_UNKNOWN_IES; + } + + pBufRemaining += len; + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This IE extends past " + "the buffer as it was defined to us. This could" + "mean a corrupt frame, or just an incorrect leng" + "th parameter.\n")); + FRAMES_DBG_BREAK(); + status |= DOT11F_LAST_IE_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } + +MandatoryCheck: + pIe = &IEs[0]; + while (0xff != pIe->eid) + { + if (pIe->fMandatory) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandato" + "ry IE %s wasn't seen.\n"), + pIe->name); + FRAMES_DBG_BREAK(); + status |= DOT11F_MANDATORY_IE_MISSING; + } + + } + ++pIe; + } + + return status; +} /* End UnpackCore. */ + +static tANI_U32 UnpackTlvCore( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ], + tANI_U8 *pFrm, + size_t nFrm ) +{ + const tTLVDefn *pTlv; + tANI_U32 nBufRemaining, status, npec; + tANI_U16 id, len; + tANI_U8 *pBufRemaining, *pfFound; + + (void)pCtx; // Shutup the compiler + (void)nFrm; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + // While we have data... + while ( nBufRemaining ) + { + if ( 3 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL( "This frame reports " + "fewer three byte(s) remaining.\n" ) ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + npec = 0U; + + // Look for a matching TLV definition, + pTlv = FindTLVDefn( pCtx, pBufRemaining, nBufRemaining, TLVs ); + // consume the type, + if ( pTlv ) + { + if ( pTlv->sType == 2) + { + framesntohs(pCtx, &id, pBufRemaining, pTlv->fMsb); + pBufRemaining += 2; + nBufRemaining -= 2; + }else + { + id = *pBufRemaining; + pBufRemaining += 1; + nBufRemaining -= 1; + } + // & length, + if ( pTlv->sLen == 2) + { + framesntohs(pCtx, &len, pBufRemaining, pTlv->fMsb); + if ( 2 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL("This frame reports " + "fewer two byte(s) remaining.\n") ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 2; + nBufRemaining -= 2; + }else + { + len = *pBufRemaining; + pBufRemaining += 1; + nBufRemaining -= 1; + } + } + else + { + pBufRemaining += TLVs[0].sType; + nBufRemaining -= TLVs[0].sType; + framesntohs(pCtx, &len, pBufRemaining, (TLVs[0].sType == 2)); + if ( 2 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL("This frame reports " + "fewer two byte(s) remaining.\n") ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 2; + nBufRemaining -= 2; + } + + if ( pTlv && pTlv->pec ) + { + npec = 3U; + if ( 3 > nBufRemaining ) + { + FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length" + "%d, but it has a Private Enterprise Code (3 byte" + "s.\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes" + "of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 3; + nBufRemaining -= 3; + len -= 3; + } + + // Whether we found a hit or not, we can validate the reported + // length of this TLV: + if ( len > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %" + "d, but there are only %d bytes remaining in this f" + "rame.\n"), id, len, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL( "We've parsed %d bytes" + " of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + // Now, *if* we found a hit... + if ( pTlv ) + { + if ( len < pTlv->minSize - npec ) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but the size is only " + "%d bytes.\n"), + pTlv->name, pTlv->minSize, len ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + if ( nBufRemaining < pTlv->minSize - npec - (pTlv->sType + pTlv->sLen) ) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are only " + "%d bytes remaining in this frame.\n"), + pTlv->name, pTlv->minSize, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + else if ( len > pTlv->maxSize - npec - (pTlv->sType + pTlv->sLen) ) + { + FRAMES_LOG1( pCtx, FRLOGW, FRFL("The TLV %s reports " + "an illegally large size; this TLV is presumably" + "corrupt or otherwise invalid & will be skipped " + "ipped.\n"), pTlv->name ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + FRAMES_DBG_BREAK(); + status |= DOT11F_SKIPPED_BAD_TLV; + } + else + { + switch (pTlv->sig) + { + case SigTlvAuthorizedMACs: + status |= dot11fUnpackTlvAuthorizedMACs(pCtx, pBufRemaining, len, ( tDot11fTLVAuthorizedMACs* )(pFrm + pTlv->offset )); + break; + case SigTlvRequestToEnroll: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRequestToEnroll* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRequestToEnroll*)(pFrm + pTlv->offset ))->req)); + break; + case SigTlvVersion2: + status |= dot11fUnpackTlvVersion2(pCtx, pBufRemaining, len, ( tDot11fTLVVersion2* )(pFrm + pTlv->offset )); + break; + case SigTlvAPSetupLocked: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVAPSetupLocked* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVAPSetupLocked*)(pFrm + pTlv->offset ))->fLocked)); + break; + case SigTlvAssociationState: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVAssociationState* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVAssociationState*)(pFrm + pTlv->offset ))->state)); + break; + case SigTlvChannelList: + status |= dot11fUnpackTlvChannelList(pCtx, pBufRemaining, len, ( tDot11fTLVChannelList* )(pFrm + pTlv->offset )); + break; + case SigTlvConfigMethods: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVConfigMethods* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVConfigMethods*)(pFrm + pTlv->offset ))->methods)); + break; + case SigTlvConfigurationError: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVConfigurationError* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVConfigurationError*)(pFrm + pTlv->offset ))->error)); + break; + case SigTlvConfigurationTimeout: + status |= dot11fUnpackTlvConfigurationTimeout(pCtx, pBufRemaining, len, ( tDot11fTLVConfigurationTimeout* )(pFrm + pTlv->offset )); + break; + case SigTlvDeviceName: + status |= dot11fUnpackTlvDeviceName(pCtx, pBufRemaining, len, ( tDot11fTLVDeviceName* )(pFrm + pTlv->offset )); + break; + case SigTlvDevicePasswordID: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVDevicePasswordID* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVDevicePasswordID*)(pFrm + pTlv->offset ))->id)); + break; + case SigTlvExtendedListenTiming: + status |= dot11fUnpackTlvExtendedListenTiming(pCtx, pBufRemaining, len, ( tDot11fTLVExtendedListenTiming* )(pFrm + pTlv->offset )); + break; + case SigTlvGOIntent: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVGOIntent* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVGOIntent*)(pFrm + pTlv->offset ))->GOIntent)); + break; + case SigTlvIntendedP2PInterfaceAddress: + status |= dot11fUnpackTlvIntendedP2PInterfaceAddress(pCtx, pBufRemaining, len, ( tDot11fTLVIntendedP2PInterfaceAddress* )(pFrm + pTlv->offset )); + break; + case SigTlvInvitationFlags: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVInvitationFlags* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVInvitationFlags*)(pFrm + pTlv->offset ))->invitationFlags)); + break; + case SigTlvListenChannel: + status |= dot11fUnpackTlvListenChannel(pCtx, pBufRemaining, len, ( tDot11fTLVListenChannel* )(pFrm + pTlv->offset )); + break; + case SigTlvManufacturer: + status |= dot11fUnpackTlvManufacturer(pCtx, pBufRemaining, len, ( tDot11fTLVManufacturer* )(pFrm + pTlv->offset )); + break; + case SigTlvMinorReasonCode: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVMinorReasonCode* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVMinorReasonCode*)(pFrm + pTlv->offset ))->minorReasonCode)); + break; + case SigTlvModelName: + status |= dot11fUnpackTlvModelName(pCtx, pBufRemaining, len, ( tDot11fTLVModelName* )(pFrm + pTlv->offset )); + break; + case SigTlvModelNumber: + status |= dot11fUnpackTlvModelNumber(pCtx, pBufRemaining, len, ( tDot11fTLVModelNumber* )(pFrm + pTlv->offset )); + break; + case SigTlvNoticeOfAbsence: + status |= dot11fUnpackTlvNoticeOfAbsence(pCtx, pBufRemaining, len, ( tDot11fTLVNoticeOfAbsence* )(pFrm + pTlv->offset )); + break; + case SigTlvOperatingChannel: + status |= dot11fUnpackTlvOperatingChannel(pCtx, pBufRemaining, len, ( tDot11fTLVOperatingChannel* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PCapability: + status |= dot11fUnpackTlvP2PCapability(pCtx, pBufRemaining, len, ( tDot11fTLVP2PCapability* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PDeviceId: + status |= dot11fUnpackTlvP2PDeviceId(pCtx, pBufRemaining, len, ( tDot11fTLVP2PDeviceId* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PDeviceInfo: + status |= dot11fUnpackTlvP2PDeviceInfo(pCtx, pBufRemaining, len, ( tDot11fTLVP2PDeviceInfo* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupBssid: + status |= dot11fUnpackTlvP2PGroupBssid(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupBssid* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupId: + status |= dot11fUnpackTlvP2PGroupId(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupId* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupInfo: + status |= dot11fUnpackTlvP2PGroupInfo(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupInfo* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PStatus: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVP2PStatus* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVP2PStatus*)(pFrm + pTlv->offset ))->status)); + break; + case SigTlvPrimaryDeviceType: + status |= dot11fUnpackTlvPrimaryDeviceType(pCtx, pBufRemaining, len, ( tDot11fTLVPrimaryDeviceType* )(pFrm + pTlv->offset )); + break; + case SigTlvRFBands: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRFBands* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRFBands*)(pFrm + pTlv->offset ))->bands)); + break; + case SigTlvRequestDeviceType: + status |= dot11fUnpackTlvRequestDeviceType(pCtx, pBufRemaining, len, ( tDot11fTLVRequestDeviceType* )(pFrm + pTlv->offset )); + break; + case SigTlvRequestType: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRequestType* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRequestType*)(pFrm + pTlv->offset ))->reqType)); + break; + case SigTlvResponseType: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVResponseType* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVResponseType*)(pFrm + pTlv->offset ))->resType)); + break; + case SigTlvSelectedRegistrar: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVSelectedRegistrar* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVSelectedRegistrar*)(pFrm + pTlv->offset ))->selected)); + break; + case SigTlvSelectedRegistrarConfigMethods: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVSelectedRegistrarConfigMethods* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVSelectedRegistrarConfigMethods*)(pFrm + pTlv->offset ))->methods)); + break; + case SigTlvSerialNumber: + status |= dot11fUnpackTlvSerialNumber(pCtx, pBufRemaining, len, ( tDot11fTLVSerialNumber* )(pFrm + pTlv->offset )); + break; + case SigTlvUUID_E: + status |= dot11fUnpackTlvUUID_E(pCtx, pBufRemaining, len, ( tDot11fTLVUUID_E* )(pFrm + pTlv->offset )); + break; + case SigTlvUUID_R: + status |= dot11fUnpackTlvUUID_R(pCtx, pBufRemaining, len, ( tDot11fTLVUUID_R* )(pFrm + pTlv->offset )); + break; + case SigTlvVendorExtension: + status |= dot11fUnpackTlvVendorExtension(pCtx, pBufRemaining, len, ( tDot11fTLVVendorExtension* )(pFrm + pTlv->offset )); + break; + case SigTlvVersion: + status |= dot11fUnpackTlvVersion(pCtx, pBufRemaining, len, ( tDot11fTLVVersion* )(pFrm + pTlv->offset )); + break; + case SigTlvWPSState: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVWPSState* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVWPSState*)(pFrm + pTlv->offset ))->state)); + break; + case SigTlvP2PInterface: + status |= dot11fUnpackTlvP2PInterface(pCtx, pBufRemaining, len, ( tDot11fTLVP2PInterface* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PManageability: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVP2PManageability* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVP2PManageability*)(pFrm + pTlv->offset ))->manageability)); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I" + " don't know about the TLV signature %d-- thi" + "s is most likely a 'framesc' bug.\n"), + pTlv->sig); + FRAMES_DBG_BREAK(); + return DOT11F_INTERNAL_ERROR; + } // End switch on sig. + } // End if on length check. + + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d (" + "length %d)\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (pTlv->sType + pTlv->sLen), len); + status |= DOT11F_UNKNOWN_TLVS; + } + + // Advance to the next TLV + pBufRemaining += len; + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th" + "e buffer as it was defined to us. This could mean " + "a corrupt frame, or just an incorrect length parame" + "ter.\n")); + FRAMES_DBG_BREAK(); + status |= DOT11F_LAST_TLV_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } // End iteration over TLVs. + +MandatoryCheck: + pTlv = &TLVs[0]; + while (0xffff != pTlv->id) + { + if (pTlv->fMandatory) + { + pfFound = (tANI_U8*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory " + "TLV %s wasn't seen.\n"), + pTlv->name); + FRAMES_DBG_BREAK(); + status |= DOT11F_MANDATORY_TLV_MISSING; + } + + } + ++pTlv; + } + + return status; +} /* End UnpacTlvkCore. */ +tANI_U32 dot11fGetPackedIETCLAS(tpAniSirGlobal pCtx, tDot11fIETCLAS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->classifier_type) + { + case 0: + *pnNeeded += 6; + *pnNeeded += 6; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + switch (pIe->info.IpParams.version) + { + case 4: + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6: + *pnNeeded += 16; + *pnNeeded += 16; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 3; + break; + } + break; + case 2: + *pnNeeded += 2; + break; + } + break; + } + return status; +} /* End dot11fGetPackedIETCLAS. */ + +tANI_U32 dot11fGetPackedIEWMMTCLAS(tpAniSirGlobal pCtx, tDot11fIEWMMTCLAS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->classifier_type) + { + case 0: + *pnNeeded += 6; + *pnNeeded += 6; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + switch (pIe->info.IpParams.version) + { + case 4: + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6: + *pnNeeded += 16; + *pnNeeded += 16; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 3; + break; + } + break; + case 2: + *pnNeeded += 2; + break; + } + break; + } + return status; +} /* End dot11fGetPackedIEWMMTCLAS. */ + +tANI_U32 dot11fGetPackedIEAirgo(tpAniSirGlobal pCtx, tDot11fIEAirgo *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_Airgo); + break; + } + return status; +} /* End dot11fGetPackedIEAirgo. */ + +tANI_U32 dot11fGetPackedIEChannelSwitchWrapper(tpAniSirGlobal pCtx, tDot11fIEChannelSwitchWrapper *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_ChannelSwitchWrapper); + break; + } + return status; +} /* End dot11fGetPackedIEChannelSwitchWrapper. */ + +tANI_U32 dot11fGetPackedIECountry(tpAniSirGlobal pCtx, tDot11fIECountry *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 3; + if ( pIe->num_triplets ) + { + *pnNeeded += ( pIe->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIECountry. */ + +tANI_U32 dot11fGetPackedIEFTInfo(tpAniSirGlobal pCtx, tDot11fIEFTInfo *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 16; + *pnNeeded += 32; + *pnNeeded += 32; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_FTInfo); + break; + } + return status; +} /* End dot11fGetPackedIEFTInfo. */ + +tANI_U32 dot11fGetPackedIEMeasurementReport(tpAniSirGlobal pCtx, tDot11fIEMeasurementReport *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + if ( pIe->type ) + { + switch (pIe->type) + { + case 0: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 1: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 2: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 5: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 6; + *pnNeeded += 1; + *pnNeeded += 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_reportBeacon); + break; + } + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIEMeasurementReport. */ + +tANI_U32 dot11fGetPackedIEMeasurementRequest(tpAniSirGlobal pCtx, tDot11fIEMeasurementRequest *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->measurement_type) + { + case 0: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 2: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 5: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_measurement_requestBeacon); + break; + } + break; + } + return status; +} /* End dot11fGetPackedIEMeasurementRequest. */ + +tANI_U32 dot11fGetPackedIENeighborReport(tpAniSirGlobal pCtx, tDot11fIENeighborReport *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 6; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_NeighborReport); + break; + } + return status; +} /* End dot11fGetPackedIENeighborReport. */ + +tANI_U32 dot11fGetPackedIEP2PAssocReq(tpAniSirGlobal pCtx, tDot11fIEP2PAssocReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PAssocReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PAssocReq. */ + +tANI_U32 dot11fGetPackedIEP2PAssocRes(tpAniSirGlobal pCtx, tDot11fIEP2PAssocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PAssocRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PAssocRes. */ + +tANI_U32 dot11fGetPackedIEP2PBeacon(tpAniSirGlobal pCtx, tDot11fIEP2PBeacon *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PBeacon); + break; + } + return status; +} /* End dot11fGetPackedIEP2PBeacon. */ + +tANI_U32 dot11fGetPackedIEP2PBeaconProbeRes(tpAniSirGlobal pCtx, tDot11fIEP2PBeaconProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PBeaconProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PBeaconProbeRes. */ + +tANI_U32 dot11fGetPackedIEP2PDeAuth(tpAniSirGlobal pCtx, tDot11fIEP2PDeAuth *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeAuth); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeAuth. */ + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fIEP2PDeviceDiscoverabilityReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeviceDiscoverabilityReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fIEP2PDeviceDiscoverabilityRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeviceDiscoverabilityRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fGetPackedIEP2PDisAssoc(tpAniSirGlobal pCtx, tDot11fIEP2PDisAssoc *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDisAssoc); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDisAssoc. */ + +tANI_U32 dot11fGetPackedIEP2PGONegCnf(tpAniSirGlobal pCtx, tDot11fIEP2PGONegCnf *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegCnf); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegCnf. */ + +tANI_U32 dot11fGetPackedIEP2PGONegReq(tpAniSirGlobal pCtx, tDot11fIEP2PGONegReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegReq. */ + +tANI_U32 dot11fGetPackedIEP2PGONegRes(tpAniSirGlobal pCtx, tDot11fIEP2PGONegRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegRes. */ + +tANI_U32 dot11fGetPackedIEP2PGONegWPS(tpAniSirGlobal pCtx, tDot11fIEP2PGONegWPS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegWPS); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegWPS. */ + +tANI_U32 dot11fGetPackedIEP2PInvitationReq(tpAniSirGlobal pCtx, tDot11fIEP2PInvitationReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PInvitationReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PInvitationReq. */ + +tANI_U32 dot11fGetPackedIEP2PInvitationRes(tpAniSirGlobal pCtx, tDot11fIEP2PInvitationRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PInvitationRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PInvitationRes. */ + +tANI_U32 dot11fGetPackedIEP2PNoticeOfAbsence(tpAniSirGlobal pCtx, tDot11fIEP2PNoticeOfAbsence *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PNoticeOfAbsence); + break; + } + return status; +} /* End dot11fGetPackedIEP2PNoticeOfAbsence. */ + +tANI_U32 dot11fGetPackedIEP2PPresenceResponse(tpAniSirGlobal pCtx, tDot11fIEP2PPresenceResponse *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PPresenceResponse); + break; + } + return status; +} /* End dot11fGetPackedIEP2PPresenceResponse. */ + +tANI_U32 dot11fGetPackedIEP2PProbeReq(tpAniSirGlobal pCtx, tDot11fIEP2PProbeReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProbeReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProbeReq. */ + +tANI_U32 dot11fGetPackedIEP2PProbeRes(tpAniSirGlobal pCtx, tDot11fIEP2PProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProbeRes. */ + +tANI_U32 dot11fGetPackedIEP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fIEP2PProvisionDiscoveryReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProvisionDiscoveryReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProvisionDiscoveryReq. */ + +tANI_U32 dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fIEP2PWSCProvisionDiscoveryRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PWSCProvisionDiscoveryRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PWSCProvisionDiscoveryRes. */ + +tANI_U32 dot11fGetPackedIERICDataDesc(tpAniSirGlobal pCtx, tDot11fIERICDataDesc *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_RICDataDesc); + break; + } + return status; +} /* End dot11fGetPackedIERICDataDesc. */ + +tANI_U32 dot11fGetPackedIERSN(tpAniSirGlobal pCtx, tDot11fIERSN *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 4; + if ( pIe->pwise_cipher_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->pwise_cipher_suite_count * 4 ); + if ( pIe->akm_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->akm_suite_count * 4 ); + if ( pIe->RSN_Cap ) + { + *pnNeeded += 2; + } + else break; + if ( pIe->pmkid_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->pmkid_count * 16 ); + if ( pIe->gp_mgmt_cipher_suite ) + { + *pnNeeded += 4; + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIERSN. */ + +tANI_U32 dot11fGetPackedIEWAPI(tpAniSirGlobal pCtx, tDot11fIEWAPI *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += ( pIe->akm_suite_count * 4 ); + *pnNeeded += 2; + *pnNeeded += ( pIe->unicast_cipher_suite_count * 4 ); + *pnNeeded += 4; + *pnNeeded += 2; + if ( pIe->bkid_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->bkid_count * 16 ); + break; + } + return status; +} /* End dot11fGetPackedIEWAPI. */ + +tANI_U32 dot11fGetPackedIEWPA(tpAniSirGlobal pCtx, tDot11fIEWPA *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + if ( pIe->multicast_cipher_present ) + { + *pnNeeded += 4; + } + else break; + if ( pIe->unicast_cipher_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->unicast_cipher_count * 4 ); + if ( pIe->auth_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->auth_suite_count * 4 ); + if ( pIe->caps ) + { + *pnNeeded += 2; + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIEWPA. */ + +tANI_U32 dot11fGetPackedIEWSC(tpAniSirGlobal pCtx, tDot11fIEWSC *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WSC); + break; + } + return status; +} /* End dot11fGetPackedIEWSC. */ + +tANI_U32 dot11fGetPackedIEWscAssocReq(tpAniSirGlobal pCtx, tDot11fIEWscAssocReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscAssocReq); + break; + } + return status; +} /* End dot11fGetPackedIEWscAssocReq. */ + +tANI_U32 dot11fGetPackedIEWscAssocRes(tpAniSirGlobal pCtx, tDot11fIEWscAssocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscAssocRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscAssocRes. */ + +tANI_U32 dot11fGetPackedIEWscBeacon(tpAniSirGlobal pCtx, tDot11fIEWscBeacon *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscBeacon); + break; + } + return status; +} /* End dot11fGetPackedIEWscBeacon. */ + +tANI_U32 dot11fGetPackedIEWscBeaconProbeRes(tpAniSirGlobal pCtx, tDot11fIEWscBeaconProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscBeaconProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscBeaconProbeRes. */ + +tANI_U32 dot11fGetPackedIEWscProbeReq(tpAniSirGlobal pCtx, tDot11fIEWscProbeReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscProbeReq); + break; + } + return status; +} /* End dot11fGetPackedIEWscProbeReq. */ + +tANI_U32 dot11fGetPackedIEWscProbeRes(tpAniSirGlobal pCtx, tDot11fIEWscProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscProbeRes. */ + +tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal pCtx, tDot11fIEWscReassocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscReassocRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscReassocRes. */ + +tANI_U32 dot11fGetPackedAddBAReqSize(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 9; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddBAReq); + return status; +} /* End dot11fGetPackedAddBAReqSize. */ + +tANI_U32 dot11fGetPackedAddBARspSize(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 9; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddBARsp); + return status; +} /* End dot11fGetPackedAddBARspSize. */ + +tANI_U32 dot11fGetPackedAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddTSRequest); + return status; +} /* End dot11fGetPackedAddTSRequestSize. */ + +tANI_U32 dot11fGetPackedAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddTSResponse); + return status; +} /* End dot11fGetPackedAddTSResponseSize. */ + +tANI_U32 dot11fGetPackedAssocRequestSize(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AssocRequest); + return status; +} /* End dot11fGetPackedAssocRequestSize. */ + +tANI_U32 dot11fGetPackedAssocResponseSize(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AssocResponse); + return status; +} /* End dot11fGetPackedAssocResponseSize. */ + +tANI_U32 dot11fGetPackedAuthenticationSize(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Authentication); + return status; +} /* End dot11fGetPackedAuthenticationSize. */ + +tANI_U32 dot11fGetPackedBeaconSize(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon); + return status; +} /* End dot11fGetPackedBeaconSize. */ + +tANI_U32 dot11fGetPackedBeacon1Size(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon1); + return status; +} /* End dot11fGetPackedBeacon1Size. */ + +tANI_U32 dot11fGetPackedBeacon2Size(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon2); + return status; +} /* End dot11fGetPackedBeacon2Size. */ + +tANI_U32 dot11fGetPackedBeaconIEsSize(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_BeaconIEs); + return status; +} /* End dot11fGetPackedBeaconIEsSize. */ + +tANI_U32 dot11fGetPackedChannelSwitchSize(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ChannelSwitch); + return status; +} /* End dot11fGetPackedChannelSwitchSize. */ + +tANI_U32 dot11fGetPackedDeAuthSize(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeAuth); + return status; +} /* End dot11fGetPackedDeAuthSize. */ + +tANI_U32 dot11fGetPackedDelBAIndSize(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DelBAInd); + return status; +} /* End dot11fGetPackedDelBAIndSize. */ + +tANI_U32 dot11fGetPackedDelTSSize(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DelTS); + return status; +} /* End dot11fGetPackedDelTSSize. */ + +tANI_U32 dot11fGetPackedDeviceDiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeviceDiscoverabilityReq); + return status; +} /* End dot11fGetPackedDeviceDiscoverabilityReqSize. */ + +tANI_U32 dot11fGetPackedDeviceDiscoverabilityResSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeviceDiscoverabilityRes); + return status; +} /* End dot11fGetPackedDeviceDiscoverabilityResSize. */ + +tANI_U32 dot11fGetPackedDisassociationSize(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Disassociation); + return status; +} /* End dot11fGetPackedDisassociationSize. */ + +tANI_U32 dot11fGetPackedGODiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GODiscoverabilityReq); + return status; +} /* End dot11fGetPackedGODiscoverabilityReqSize. */ + +tANI_U32 dot11fGetPackedGONegCnfSize(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegCnf); + return status; +} /* End dot11fGetPackedGONegCnfSize. */ + +tANI_U32 dot11fGetPackedGONegReqSize(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegReq); + return status; +} /* End dot11fGetPackedGONegReqSize. */ + +tANI_U32 dot11fGetPackedGONegResSize(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegRes); + return status; +} /* End dot11fGetPackedGONegResSize. */ + +tANI_U32 dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_HT2040BSSCoexistenceManagementActionFrame); + return status; +} /* End dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize. */ + +tANI_U32 dot11fGetPackedInvitationReqSize(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_InvitationReq); + return status; +} /* End dot11fGetPackedInvitationReqSize. */ + +tANI_U32 dot11fGetPackedInvitationResSize(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_InvitationRes); + return status; +} /* End dot11fGetPackedInvitationResSize. */ + +tANI_U32 dot11fGetPackedLinkMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 11; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_LinkMeasurementReport); + return status; +} /* End dot11fGetPackedLinkMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedLinkMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_LinkMeasurementRequest); + return status; +} /* End dot11fGetPackedLinkMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_MeasurementReport); + return status; +} /* End dot11fGetPackedMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_MeasurementRequest); + return status; +} /* End dot11fGetPackedMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedNeighborReportRequestSize(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NeighborReportRequest); + return status; +} /* End dot11fGetPackedNeighborReportRequestSize. */ + +tANI_U32 dot11fGetPackedNeighborReportResponseSize(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NeighborReportResponse); + return status; +} /* End dot11fGetPackedNeighborReportResponseSize. */ + +tANI_U32 dot11fGetPackedNoticeOfAbsSize(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NoticeOfAbs); + return status; +} /* End dot11fGetPackedNoticeOfAbsSize. */ + +tANI_U32 dot11fGetPackedOperatingModeSize(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_OperatingMode); + return status; +} /* End dot11fGetPackedOperatingModeSize. */ + +tANI_U32 dot11fGetPackedPresenceReqSize(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_PresenceReq); + return status; +} /* End dot11fGetPackedPresenceReqSize. */ + +tANI_U32 dot11fGetPackedPresenceResSize(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_PresenceRes); + return status; +} /* End dot11fGetPackedPresenceResSize. */ + +tANI_U32 dot11fGetPackedProbeRequestSize(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProbeRequest); + return status; +} /* End dot11fGetPackedProbeRequestSize. */ + +tANI_U32 dot11fGetPackedProbeResponseSize(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProbeResponse); + return status; +} /* End dot11fGetPackedProbeResponseSize. */ + +tANI_U32 dot11fGetPackedProvisionDiscoveryReqSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProvisionDiscoveryReq); + return status; +} /* End dot11fGetPackedProvisionDiscoveryReqSize. */ + +tANI_U32 dot11fGetPackedProvisionDiscoveryResSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProvisionDiscoveryRes); + return status; +} /* End dot11fGetPackedProvisionDiscoveryResSize. */ + +tANI_U32 dot11fGetPackedQosMapConfigureSize(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_QosMapConfigure); + return status; +} /* End dot11fGetPackedQosMapConfigureSize. */ + +tANI_U32 dot11fGetPackedRadioMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RadioMeasurementReport); + return status; +} /* End dot11fGetPackedRadioMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedRadioMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RadioMeasurementRequest); + return status; +} /* End dot11fGetPackedRadioMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedReAssocRequestSize(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 10; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ReAssocRequest); + return status; +} /* End dot11fGetPackedReAssocRequestSize. */ + +tANI_U32 dot11fGetPackedReAssocResponseSize(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ReAssocResponse); + return status; +} /* End dot11fGetPackedReAssocResponseSize. */ + +tANI_U32 dot11fGetPackedSMPowerSaveSize(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SMPowerSave); + return status; +} /* End dot11fGetPackedSMPowerSaveSize. */ + +tANI_U32 dot11fGetPackedSaQueryReqSize(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SaQueryReq); + return status; +} /* End dot11fGetPackedSaQueryReqSize. */ + +tANI_U32 dot11fGetPackedSaQueryRspSize(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SaQueryRsp); + return status; +} /* End dot11fGetPackedSaQueryRspSize. */ + +tANI_U32 dot11fGetPackedTDLSDisReqSize(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSDisReq); + return status; +} /* End dot11fGetPackedTDLSDisReqSize. */ + +tANI_U32 dot11fGetPackedTDLSDisRspSize(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSDisRsp); + return status; +} /* End dot11fGetPackedTDLSDisRspSize. */ + +tANI_U32 dot11fGetPackedTDLSPeerTrafficIndSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSPeerTrafficInd); + return status; +} /* End dot11fGetPackedTDLSPeerTrafficIndSize. */ + +tANI_U32 dot11fGetPackedTDLSPeerTrafficRspSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSPeerTrafficRsp); + return status; +} /* End dot11fGetPackedTDLSPeerTrafficRspSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupCnfSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupCnf); + return status; +} /* End dot11fGetPackedTDLSSetupCnfSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupReqSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupReq); + return status; +} /* End dot11fGetPackedTDLSSetupReqSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupRspSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupRsp); + return status; +} /* End dot11fGetPackedTDLSSetupRspSize. */ + +tANI_U32 dot11fGetPackedTDLSTeardownSize(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSTeardown); + return status; +} /* End dot11fGetPackedTDLSTeardownSize. */ + +tANI_U32 dot11fGetPackedTPCReportSize(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TPCReport); + return status; +} /* End dot11fGetPackedTPCReportSize. */ + +tANI_U32 dot11fGetPackedTPCRequestSize(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TPCRequest); + return status; +} /* End dot11fGetPackedTPCRequestSize. */ + +tANI_U32 dot11fGetPackedVHTGidManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 26; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_VHTGidManagementActionFrame); + return status; +} /* End dot11fGetPackedVHTGidManagementActionFrameSize. */ + +tANI_U32 dot11fGetPackedWMMAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMAddTSRequest); + return status; +} /* End dot11fGetPackedWMMAddTSRequestSize. */ + +tANI_U32 dot11fGetPackedWMMAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMAddTSResponse); + return status; +} /* End dot11fGetPackedWMMAddTSResponseSize. */ + +tANI_U32 dot11fGetPackedWMMDelTSSize(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMDelTS); + return status; +} /* End dot11fGetPackedWMMDelTSSize. */ + +static tANI_U32 GetPackedSizeCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe; + tANI_U16 i, n; + tANI_U32 status; + tFRAMES_BOOL *pfFound; + tANI_U32 countOffset = 0; + tANI_U32 byteCount = 0; + tANI_U8 pIePresent = 0; + tANI_U32 offset = 0; + + status = DOT11F_PARSE_SUCCESS; + + (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */ + i=0; n=0; + pIe = &( IEs[0] ); + while ( 0xff != pIe->eid ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + if ( *pfFound ) + { + countOffset = ((0 == pIe->arraybound) ? 1 : (*( tANI_U16* )(pFrm + pIe->countOffset)) ); + for (i = 0U; i < countOffset; ++i) + { + *pnNeeded += 2U + pIe->noui; + byteCount = 0; + switch (pIe->sig) + { + case SigIeAPName: + offset = sizeof(tDot11fIEAPName); + byteCount = ((tDot11fIEAPName* )(pFrm + pIe->offset + sizeof(tDot11fIEAPName) * i ))->num_name; + pIePresent = ( (tDot11fIEAPName* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBPIndicator: + offset = sizeof(tDot11fIEBPIndicator); + byteCount = 2; + pIePresent = ( (tDot11fIEBPIndicator* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeCondensedCountryStr: + offset = sizeof(tDot11fIECondensedCountryStr); + byteCount = 2; + pIePresent = ( (tDot11fIECondensedCountryStr* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeGTK: + offset = sizeof(tDot11fIEGTK); + byteCount = ((tDot11fIEGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEGTK) * i ))->num_key + 11; + pIePresent = ( (tDot11fIEGTK* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHCF: + offset = sizeof(tDot11fIEHCF); + byteCount = 1; + pIePresent = ( (tDot11fIEHCF* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeIGTK: + offset = sizeof(tDot11fIEIGTK); + byteCount = 33; + pIePresent = ( (tDot11fIEIGTK* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLLAttr: + offset = sizeof(tDot11fIELLAttr); + byteCount = 4; + pIePresent = ( (tDot11fIELLAttr* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLoadBalance: + offset = sizeof(tDot11fIELoadBalance); + byteCount = 7; + pIePresent = ( (tDot11fIELoadBalance* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLoadInfo: + offset = sizeof(tDot11fIELoadInfo); + byteCount = 4; + pIePresent = ( (tDot11fIELoadInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropAssocType: + offset = sizeof(tDot11fIEPropAssocType); + byteCount = 1; + pIePresent = ( (tDot11fIEPropAssocType* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropCapability: + offset = sizeof(tDot11fIEPropCapability); + byteCount = 2; + pIePresent = ( (tDot11fIEPropCapability* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropChannSwitchAnn: + offset = sizeof(tDot11fIEPropChannSwitchAnn); + byteCount = 4; + pIePresent = ( (tDot11fIEPropChannSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropEDCAParams: + offset = sizeof(tDot11fIEPropEDCAParams); + byteCount = 18; + pIePresent = ( (tDot11fIEPropEDCAParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropQuietBSS: + offset = sizeof(tDot11fIEPropQuietBSS); + byteCount = 6; + pIePresent = ( (tDot11fIEPropQuietBSS* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropSuppRates: + offset = sizeof(tDot11fIEPropSuppRates); + byteCount = ((tDot11fIEPropSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEPropSuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIEPropSuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeR0KH_ID: + offset = sizeof(tDot11fIER0KH_ID); + byteCount = ((tDot11fIER0KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER0KH_ID) * i ))->num_PMK_R0_ID; + pIePresent = ( (tDot11fIER0KH_ID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeR1KH_ID: + offset = sizeof(tDot11fIER1KH_ID); + byteCount = 6; + pIePresent = ( (tDot11fIER1KH_ID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSFInfo: + offset = sizeof(tDot11fIETSFInfo); + byteCount = 4; + pIePresent = ( (tDot11fIETSFInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTaurus: + offset = sizeof(tDot11fIETaurus); + byteCount = 6; + pIePresent = ( (tDot11fIETaurus* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTitan: + offset = sizeof(tDot11fIETitan); + byteCount = 4; + pIePresent = ( (tDot11fIETitan* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTriggerStaBgScan: + offset = sizeof(tDot11fIETriggerStaBgScan); + byteCount = 1; + pIePresent = ( (tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVersion: + offset = sizeof(tDot11fIEVersion); + byteCount = ((tDot11fIEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEVersion) * i ))->num_build_version + 5; + pIePresent = ( (tDot11fIEVersion* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWDS: + offset = sizeof(tDot11fIEWDS); + byteCount = ((tDot11fIEWDS* )(pFrm + pIe->offset + sizeof(tDot11fIEWDS) * i ))->num_wdsData; + pIePresent = ( (tDot11fIEWDS* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAPChannelReport: + offset = sizeof(tDot11fIEAPChannelReport); + byteCount = ((tDot11fIEAPChannelReport* )(pFrm + pIe->offset + sizeof(tDot11fIEAPChannelReport) * i ))->num_channelList + 1; + pIePresent = ( (tDot11fIEAPChannelReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBcnReportingDetail: + offset = sizeof(tDot11fIEBcnReportingDetail); + byteCount = 1; + pIePresent = ( (tDot11fIEBcnReportingDetail* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBeaconReportFrmBody: + offset = sizeof(tDot11fIEBeaconReportFrmBody); + byteCount = ((tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody) * i ))->num_reportedFields; + pIePresent = ( (tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBeaconReporting: + offset = sizeof(tDot11fIEBeaconReporting); + byteCount = 2; + pIePresent = ( (tDot11fIEBeaconReporting* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMeasurementPilot: + offset = sizeof(tDot11fIEMeasurementPilot); + byteCount = ((tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementPilot) * i ))->num_vendorSpecific + 1; + pIePresent = ( (tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMultiBssid: + offset = sizeof(tDot11fIEMultiBssid); + byteCount = ((tDot11fIEMultiBssid* )(pFrm + pIe->offset + sizeof(tDot11fIEMultiBssid) * i ))->num_vendorSpecific + 1; + pIePresent = ( (tDot11fIEMultiBssid* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICData: + offset = sizeof(tDot11fIERICData); + byteCount = 4; + pIePresent = ( (tDot11fIERICData* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICDescriptor: + offset = sizeof(tDot11fIERICDescriptor); + byteCount = ((tDot11fIERICDescriptor* )(pFrm + pIe->offset + sizeof(tDot11fIERICDescriptor) * i ))->num_variableData + 1; + pIePresent = ( (tDot11fIERICDescriptor* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRRMEnabledCap: + offset = sizeof(tDot11fIERRMEnabledCap); + byteCount = 5; + pIePresent = ( (tDot11fIERRMEnabledCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRequestedInfo: + offset = sizeof(tDot11fIERequestedInfo); + byteCount = ((tDot11fIERequestedInfo* )(pFrm + pIe->offset + sizeof(tDot11fIERequestedInfo) * i ))->num_requested_eids; + pIePresent = ( (tDot11fIERequestedInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSSID: + offset = sizeof(tDot11fIESSID); + byteCount = ((tDot11fIESSID* )(pFrm + pIe->offset + sizeof(tDot11fIESSID) * i ))->num_ssid; + pIePresent = ( (tDot11fIESSID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSchedule: + offset = sizeof(tDot11fIESchedule); + byteCount = 14; + pIePresent = ( (tDot11fIESchedule* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTCLAS: + offset = sizeof(tDot11fIETCLAS); + status |= dot11fGetPackedIETCLAS(pCtx, ( tDot11fIETCLAS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeTCLASSPROC: + offset = sizeof(tDot11fIETCLASSPROC); + byteCount = 1; + pIePresent = ( (tDot11fIETCLASSPROC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSDelay: + offset = sizeof(tDot11fIETSDelay); + byteCount = 4; + pIePresent = ( (tDot11fIETSDelay* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSPEC: + offset = sizeof(tDot11fIETSPEC); + byteCount = 55; + pIePresent = ( (tDot11fIETSPEC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMSchedule: + offset = sizeof(tDot11fIEWMMSchedule); + byteCount = 15; + pIePresent = ( (tDot11fIEWMMSchedule* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTCLAS: + offset = sizeof(tDot11fIEWMMTCLAS); + status |= dot11fGetPackedIEWMMTCLAS(pCtx, ( tDot11fIEWMMTCLAS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWMMTCLASPROC: + offset = sizeof(tDot11fIEWMMTCLASPROC); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMTCLASPROC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTSDelay: + offset = sizeof(tDot11fIEWMMTSDelay); + byteCount = 5; + pIePresent = ( (tDot11fIEWMMTSDelay* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTSPEC: + offset = sizeof(tDot11fIEWMMTSPEC); + byteCount = 56; + pIePresent = ( (tDot11fIEWMMTSPEC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWiderBWChanSwitchAnn: + offset = sizeof(tDot11fIEWiderBWChanSwitchAnn); + byteCount = 3; + pIePresent = ( (tDot11fIEWiderBWChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAID: + offset = sizeof(tDot11fIEAID); + byteCount = 2; + pIePresent = ( (tDot11fIEAID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAirgo: + offset = sizeof(tDot11fIEAirgo); + status |= dot11fGetPackedIEAirgo(pCtx, ( tDot11fIEAirgo* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeCFParams: + offset = sizeof(tDot11fIECFParams); + byteCount = 6; + pIePresent = ( (tDot11fIECFParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeChallengeText: + offset = sizeof(tDot11fIEChallengeText); + byteCount = ((tDot11fIEChallengeText* )(pFrm + pIe->offset + sizeof(tDot11fIEChallengeText) * i ))->num_text; + pIePresent = ( (tDot11fIEChallengeText* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeChanSwitchAnn: + offset = sizeof(tDot11fIEChanSwitchAnn); + byteCount = 3; + pIePresent = ( (tDot11fIEChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeChannelSwitchWrapper: + offset = sizeof(tDot11fIEChannelSwitchWrapper); + status |= dot11fGetPackedIEChannelSwitchWrapper(pCtx, ( tDot11fIEChannelSwitchWrapper* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeCountry: + offset = sizeof(tDot11fIECountry); + status |= dot11fGetPackedIECountry(pCtx, ( tDot11fIECountry* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeDSParams: + offset = sizeof(tDot11fIEDSParams); + byteCount = 1; + pIePresent = ( (tDot11fIEDSParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeEDCAParamSet: + offset = sizeof(tDot11fIEEDCAParamSet); + byteCount = 18; + pIePresent = ( (tDot11fIEEDCAParamSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeERPInfo: + offset = sizeof(tDot11fIEERPInfo); + byteCount = 1; + pIePresent = ( (tDot11fIEERPInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESECckmOpaque: + offset = sizeof(tDot11fIEESECckmOpaque); + byteCount = ((tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEESECckmOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESERadMgmtCap: + offset = sizeof(tDot11fIEESERadMgmtCap); + byteCount = 2; + pIePresent = ( (tDot11fIEESERadMgmtCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETrafStrmMet: + offset = sizeof(tDot11fIEESETrafStrmMet); + byteCount = 4; + pIePresent = ( (tDot11fIEESETrafStrmMet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETrafStrmRateSet: + offset = sizeof(tDot11fIEESETrafStrmRateSet); + byteCount = ((tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet) * i ))->num_tsrates + 1; + pIePresent = ( (tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETxmitPower: + offset = sizeof(tDot11fIEESETxmitPower); + byteCount = 2; + pIePresent = ( (tDot11fIEESETxmitPower* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESEVersion: + offset = sizeof(tDot11fIEESEVersion); + byteCount = 1; + pIePresent = ( (tDot11fIEESEVersion* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtCap: + offset = sizeof(tDot11fIEExtCap); + byteCount = ((tDot11fIEExtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEExtCap) * i ))->num_bytes; + pIePresent = ( (tDot11fIEExtCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtChanSwitchAnn: + offset = sizeof(tDot11fIEExtChanSwitchAnn); + byteCount = 1; + pIePresent = ( (tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtSuppRates: + offset = sizeof(tDot11fIEExtSuppRates); + byteCount = ((tDot11fIEExtSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEExtSuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIEExtSuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHParamSet: + offset = sizeof(tDot11fIEFHParamSet); + byteCount = 5; + pIePresent = ( (tDot11fIEFHParamSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHParams: + offset = sizeof(tDot11fIEFHParams); + byteCount = 2; + pIePresent = ( (tDot11fIEFHParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHPattTable: + offset = sizeof(tDot11fIEFHPattTable); + byteCount = ((tDot11fIEFHPattTable* )(pFrm + pIe->offset + sizeof(tDot11fIEFHPattTable) * i ))->num_randtable + 4; + pIePresent = ( (tDot11fIEFHPattTable* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFTInfo: + offset = sizeof(tDot11fIEFTInfo); + status |= dot11fGetPackedIEFTInfo(pCtx, ( tDot11fIEFTInfo* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeHT2040BSSCoexistence: + offset = sizeof(tDot11fIEHT2040BSSCoexistence); + byteCount = 1; + pIePresent = ( (tDot11fIEHT2040BSSCoexistence* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHT2040BSSIntolerantReport: + offset = sizeof(tDot11fIEHT2040BSSIntolerantReport); + byteCount = ((tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport) * i ))->num_channelList + 1; + pIePresent = ( (tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHTCaps: + offset = sizeof(tDot11fIEHTCaps); + byteCount = ((tDot11fIEHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEHTCaps) * i ))->num_rsvd + 26; + pIePresent = ( (tDot11fIEHTCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHTInfo: + offset = sizeof(tDot11fIEHTInfo); + byteCount = ((tDot11fIEHTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEHTInfo) * i ))->num_rsvd + 22; + pIePresent = ( (tDot11fIEHTInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeIBSSParams: + offset = sizeof(tDot11fIEIBSSParams); + byteCount = 2; + pIePresent = ( (tDot11fIEIBSSParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLinkIdentifier: + offset = sizeof(tDot11fIELinkIdentifier); + byteCount = 18; + pIePresent = ( (tDot11fIELinkIdentifier* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMeasurementReport: + offset = sizeof(tDot11fIEMeasurementReport); + status |= dot11fGetPackedIEMeasurementReport(pCtx, ( tDot11fIEMeasurementReport* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeMeasurementRequest: + offset = sizeof(tDot11fIEMeasurementRequest); + status |= dot11fGetPackedIEMeasurementRequest(pCtx, ( tDot11fIEMeasurementRequest* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeMobilityDomain: + offset = sizeof(tDot11fIEMobilityDomain); + byteCount = 3; + pIePresent = ( (tDot11fIEMobilityDomain* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeNeighborReport: + offset = sizeof(tDot11fIENeighborReport); + status |= dot11fGetPackedIENeighborReport(pCtx, ( tDot11fIENeighborReport* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeOBSSScanParameters: + offset = sizeof(tDot11fIEOBSSScanParameters); + byteCount = 14; + pIePresent = ( (tDot11fIEOBSSScanParameters* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeOperatingMode: + offset = sizeof(tDot11fIEOperatingMode); + byteCount = 1; + pIePresent = ( (tDot11fIEOperatingMode* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeP2PAssocReq: + offset = sizeof(tDot11fIEP2PAssocReq); + status |= dot11fGetPackedIEP2PAssocReq(pCtx, ( tDot11fIEP2PAssocReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PAssocRes: + offset = sizeof(tDot11fIEP2PAssocRes); + status |= dot11fGetPackedIEP2PAssocRes(pCtx, ( tDot11fIEP2PAssocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PBeacon: + offset = sizeof(tDot11fIEP2PBeacon); + status |= dot11fGetPackedIEP2PBeacon(pCtx, ( tDot11fIEP2PBeacon* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PBeaconProbeRes: + offset = sizeof(tDot11fIEP2PBeaconProbeRes); + status |= dot11fGetPackedIEP2PBeaconProbeRes(pCtx, ( tDot11fIEP2PBeaconProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeAuth: + offset = sizeof(tDot11fIEP2PDeAuth); + status |= dot11fGetPackedIEP2PDeAuth(pCtx, ( tDot11fIEP2PDeAuth* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeviceDiscoverabilityReq: + offset = sizeof(tDot11fIEP2PDeviceDiscoverabilityReq); + status |= dot11fGetPackedIEP2PDeviceDiscoverabilityReq(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeviceDiscoverabilityRes: + offset = sizeof(tDot11fIEP2PDeviceDiscoverabilityRes); + status |= dot11fGetPackedIEP2PDeviceDiscoverabilityRes(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDisAssoc: + offset = sizeof(tDot11fIEP2PDisAssoc); + status |= dot11fGetPackedIEP2PDisAssoc(pCtx, ( tDot11fIEP2PDisAssoc* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegCnf: + offset = sizeof(tDot11fIEP2PGONegCnf); + status |= dot11fGetPackedIEP2PGONegCnf(pCtx, ( tDot11fIEP2PGONegCnf* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegReq: + offset = sizeof(tDot11fIEP2PGONegReq); + status |= dot11fGetPackedIEP2PGONegReq(pCtx, ( tDot11fIEP2PGONegReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegRes: + offset = sizeof(tDot11fIEP2PGONegRes); + status |= dot11fGetPackedIEP2PGONegRes(pCtx, ( tDot11fIEP2PGONegRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegWPS: + offset = sizeof(tDot11fIEP2PGONegWPS); + status |= dot11fGetPackedIEP2PGONegWPS(pCtx, ( tDot11fIEP2PGONegWPS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PIEOpaque: + offset = sizeof(tDot11fIEP2PIEOpaque); + byteCount = ((tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeP2PInvitationReq: + offset = sizeof(tDot11fIEP2PInvitationReq); + status |= dot11fGetPackedIEP2PInvitationReq(pCtx, ( tDot11fIEP2PInvitationReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PInvitationRes: + offset = sizeof(tDot11fIEP2PInvitationRes); + status |= dot11fGetPackedIEP2PInvitationRes(pCtx, ( tDot11fIEP2PInvitationRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PNoticeOfAbsence: + offset = sizeof(tDot11fIEP2PNoticeOfAbsence); + status |= dot11fGetPackedIEP2PNoticeOfAbsence(pCtx, ( tDot11fIEP2PNoticeOfAbsence* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PPresenceResponse: + offset = sizeof(tDot11fIEP2PPresenceResponse); + status |= dot11fGetPackedIEP2PPresenceResponse(pCtx, ( tDot11fIEP2PPresenceResponse* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProbeReq: + offset = sizeof(tDot11fIEP2PProbeReq); + status |= dot11fGetPackedIEP2PProbeReq(pCtx, ( tDot11fIEP2PProbeReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProbeRes: + offset = sizeof(tDot11fIEP2PProbeRes); + status |= dot11fGetPackedIEP2PProbeRes(pCtx, ( tDot11fIEP2PProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProvisionDiscoveryReq: + offset = sizeof(tDot11fIEP2PProvisionDiscoveryReq); + status |= dot11fGetPackedIEP2PProvisionDiscoveryReq(pCtx, ( tDot11fIEP2PProvisionDiscoveryReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + offset = sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes); + status |= dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(pCtx, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIePTIControl: + offset = sizeof(tDot11fIEPTIControl); + byteCount = 3; + pIePresent = ( (tDot11fIEPTIControl* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePUBufferStatus: + offset = sizeof(tDot11fIEPUBufferStatus); + byteCount = 1; + pIePresent = ( (tDot11fIEPUBufferStatus* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePowerCaps: + offset = sizeof(tDot11fIEPowerCaps); + byteCount = 2; + pIePresent = ( (tDot11fIEPowerCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePowerConstraints: + offset = sizeof(tDot11fIEPowerConstraints); + byteCount = 1; + pIePresent = ( (tDot11fIEPowerConstraints* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQBSSLoad: + offset = sizeof(tDot11fIEQBSSLoad); + byteCount = 5; + pIePresent = ( (tDot11fIEQBSSLoad* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQOSCapsAp: + offset = sizeof(tDot11fIEQOSCapsAp); + byteCount = 1; + pIePresent = ( (tDot11fIEQOSCapsAp* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQOSCapsStation: + offset = sizeof(tDot11fIEQOSCapsStation); + byteCount = 1; + pIePresent = ( (tDot11fIEQOSCapsStation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQosMapSet: + offset = sizeof(tDot11fIEQosMapSet); + byteCount = ((tDot11fIEQosMapSet* )(pFrm + pIe->offset + sizeof(tDot11fIEQosMapSet) * i ))->num_dscp_exceptions; + pIePresent = ( (tDot11fIEQosMapSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQuiet: + offset = sizeof(tDot11fIEQuiet); + byteCount = 6; + pIePresent = ( (tDot11fIEQuiet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRCPIIE: + offset = sizeof(tDot11fIERCPIIE); + byteCount = 1; + pIePresent = ( (tDot11fIERCPIIE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICDataDesc: + offset = sizeof(tDot11fIERICDataDesc); + pnNeeded -= 2 ; //Subtract the length and Oui as this is our container IE to group Ies and it doesnt have its own length and OUI. + status |= dot11fGetPackedIERICDataDesc(pCtx, ( tDot11fIERICDataDesc* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeRSN: + offset = sizeof(tDot11fIERSN); + status |= dot11fGetPackedIERSN(pCtx, ( tDot11fIERSN* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeRSNIIE: + offset = sizeof(tDot11fIERSNIIE); + byteCount = 1; + pIePresent = ( (tDot11fIERSNIIE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRSNOpaque: + offset = sizeof(tDot11fIERSNOpaque); + byteCount = ((tDot11fIERSNOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIERSNOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIERSNOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppChannels: + offset = sizeof(tDot11fIESuppChannels); + byteCount = ((tDot11fIESuppChannels* )(pFrm + pIe->offset + sizeof(tDot11fIESuppChannels) * i ))->num_bands * 2; + pIePresent = ( (tDot11fIESuppChannels* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppOperatingClasses: + offset = sizeof(tDot11fIESuppOperatingClasses); + byteCount = ((tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + sizeof(tDot11fIESuppOperatingClasses) * i ))->num_classes; + pIePresent = ( (tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppRates: + offset = sizeof(tDot11fIESuppRates); + byteCount = ((tDot11fIESuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIESuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIESuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTIM: + offset = sizeof(tDot11fIETIM); + byteCount = ((tDot11fIETIM* )(pFrm + pIe->offset + sizeof(tDot11fIETIM) * i ))->num_vbmp + 3; + pIePresent = ( (tDot11fIETIM* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTPCReport: + offset = sizeof(tDot11fIETPCReport); + byteCount = 2; + pIePresent = ( (tDot11fIETPCReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTPCRequest: + offset = sizeof(tDot11fIETPCRequest); + byteCount = 0; + pIePresent = ( (tDot11fIETPCRequest* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTimeoutInterval: + offset = sizeof(tDot11fIETimeoutInterval); + byteCount = 5; + pIePresent = ( (tDot11fIETimeoutInterval* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTCaps: + offset = sizeof(tDot11fIEVHTCaps); + byteCount = 12; + pIePresent = ( (tDot11fIEVHTCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTExtBssLoad: + offset = sizeof(tDot11fIEVHTExtBssLoad); + byteCount = 5; + pIePresent = ( (tDot11fIEVHTExtBssLoad* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTOperation: + offset = sizeof(tDot11fIEVHTOperation); + byteCount = 5; + pIePresent = ( (tDot11fIEVHTOperation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVendor1IE: + offset = sizeof(tDot11fIEVendor1IE); + byteCount = 0; + pIePresent = ( (tDot11fIEVendor1IE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVendor2IE: + offset = sizeof(tDot11fIEVendor2IE); + byteCount = 0; + pIePresent = ( (tDot11fIEVendor2IE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVendor3IE: + offset = sizeof(tDot11fIEVendor3IE); + byteCount = 0; + pIePresent = ( (tDot11fIEVendor3IE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWAPI: + offset = sizeof(tDot11fIEWAPI); + status |= dot11fGetPackedIEWAPI(pCtx, ( tDot11fIEWAPI* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWAPIOpaque: + offset = sizeof(tDot11fIEWAPIOpaque); + byteCount = ((tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPIOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWFATPC: + offset = sizeof(tDot11fIEWFATPC); + byteCount = 2; + pIePresent = ( (tDot11fIEWFATPC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWFDIEOpaque: + offset = sizeof(tDot11fIEWFDIEOpaque); + byteCount = ((tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWFDIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMCaps: + offset = sizeof(tDot11fIEWMMCaps); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMInfoAp: + offset = sizeof(tDot11fIEWMMInfoAp); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMInfoAp* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMInfoStation: + offset = sizeof(tDot11fIEWMMInfoStation); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMInfoStation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMParams: + offset = sizeof(tDot11fIEWMMParams); + byteCount = 19; + pIePresent = ( (tDot11fIEWMMParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWPA: + offset = sizeof(tDot11fIEWPA); + status |= dot11fGetPackedIEWPA(pCtx, ( tDot11fIEWPA* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWPAOpaque: + offset = sizeof(tDot11fIEWPAOpaque); + byteCount = ((tDot11fIEWPAOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWPAOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWPAOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWSC: + offset = sizeof(tDot11fIEWSC); + status |= dot11fGetPackedIEWSC(pCtx, ( tDot11fIEWSC* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscAssocReq: + offset = sizeof(tDot11fIEWscAssocReq); + status |= dot11fGetPackedIEWscAssocReq(pCtx, ( tDot11fIEWscAssocReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscAssocRes: + offset = sizeof(tDot11fIEWscAssocRes); + status |= dot11fGetPackedIEWscAssocRes(pCtx, ( tDot11fIEWscAssocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscBeacon: + offset = sizeof(tDot11fIEWscBeacon); + status |= dot11fGetPackedIEWscBeacon(pCtx, ( tDot11fIEWscBeacon* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscBeaconProbeRes: + offset = sizeof(tDot11fIEWscBeaconProbeRes); + status |= dot11fGetPackedIEWscBeaconProbeRes(pCtx, ( tDot11fIEWscBeaconProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscIEOpaque: + offset = sizeof(tDot11fIEWscIEOpaque); + byteCount = ((tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWscIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWscProbeReq: + offset = sizeof(tDot11fIEWscProbeReq); + status |= dot11fGetPackedIEWscProbeReq(pCtx, ( tDot11fIEWscProbeReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscProbeRes: + offset = sizeof(tDot11fIEWscProbeRes); + status |= dot11fGetPackedIEWscProbeRes(pCtx, ( tDot11fIEWscProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscReassocRes: + offset = sizeof(tDot11fIEWscReassocRes); + status |= dot11fGetPackedIEWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the IE signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pIe->sig); + return DOT11F_INTERNAL_ERROR; + }/*End of switch Case*/ + if( byteCount && pIePresent ) + *pnNeeded += byteCount; + } /*End of for loop*/ + } + ++pIe; + } + return status; + +} + +static tANI_U32 GetPackedSizeTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tTLVDefn TLVs[]) +{ + const tTLVDefn *pTlv; + tANI_U32 status; + tFRAMES_BOOL *pfFound; + tANI_U32 byteCount = 0; + tANI_U8 pTlvPresent = 0; + + status = DOT11F_PARSE_SUCCESS; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound ) + { + *pnNeeded += (pTlv->sType + pTlv->sLen); + if ( pTlv->pec ) *pnNeeded += 3U; + switch (pTlv->sig) + { + case SigTlvAuthorizedMACs: + byteCount = 6; + pTlvPresent = (( tDot11fTLVAuthorizedMACs* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestToEnroll: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRequestToEnroll* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVersion2: + byteCount = 1; + pTlvPresent = (( tDot11fTLVVersion2* )(pFrm + pTlv->offset))->present; + break; + case SigTlvAPSetupLocked: + byteCount = 1; + pTlvPresent = (( tDot11fTLVAPSetupLocked* )(pFrm + pTlv->offset))->present; + break; + case SigTlvAssociationState: + byteCount = 2; + pTlvPresent = (( tDot11fTLVAssociationState* )(pFrm + pTlv->offset))->present; + break; + case SigTlvChannelList: + byteCount = ((tDot11fTLVChannelList*)(pFrm + pTlv->offset))->num_channelList+3; + pTlvPresent = (( tDot11fTLVChannelList* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigMethods: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigMethods* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigurationError: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigurationError* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigurationTimeout: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigurationTimeout* )(pFrm + pTlv->offset))->present; + break; + case SigTlvDeviceName: + byteCount = ((tDot11fTLVDeviceName*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVDeviceName* )(pFrm + pTlv->offset))->present; + break; + case SigTlvDevicePasswordID: + byteCount = 2; + pTlvPresent = (( tDot11fTLVDevicePasswordID* )(pFrm + pTlv->offset))->present; + break; + case SigTlvExtendedListenTiming: + byteCount = 4; + pTlvPresent = (( tDot11fTLVExtendedListenTiming* )(pFrm + pTlv->offset))->present; + break; + case SigTlvGOIntent: + byteCount = 1; + pTlvPresent = (( tDot11fTLVGOIntent* )(pFrm + pTlv->offset))->present; + break; + case SigTlvIntendedP2PInterfaceAddress: + byteCount = 6; + pTlvPresent = (( tDot11fTLVIntendedP2PInterfaceAddress* )(pFrm + pTlv->offset))->present; + break; + case SigTlvInvitationFlags: + byteCount = 1; + pTlvPresent = (( tDot11fTLVInvitationFlags* )(pFrm + pTlv->offset))->present; + break; + case SigTlvListenChannel: + byteCount = 5; + pTlvPresent = (( tDot11fTLVListenChannel* )(pFrm + pTlv->offset))->present; + break; + case SigTlvManufacturer: + byteCount = ((tDot11fTLVManufacturer*)(pFrm + pTlv->offset))->num_name; + pTlvPresent = (( tDot11fTLVManufacturer* )(pFrm + pTlv->offset))->present; + break; + case SigTlvMinorReasonCode: + byteCount = 1; + pTlvPresent = (( tDot11fTLVMinorReasonCode* )(pFrm + pTlv->offset))->present; + break; + case SigTlvModelName: + byteCount = ((tDot11fTLVModelName*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVModelName* )(pFrm + pTlv->offset))->present; + break; + case SigTlvModelNumber: + byteCount = ((tDot11fTLVModelNumber*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVModelNumber* )(pFrm + pTlv->offset))->present; + break; + case SigTlvNoticeOfAbsence: + byteCount = ((tDot11fTLVNoticeOfAbsence*)(pFrm + pTlv->offset))->num_NoADesc+2; + pTlvPresent = (( tDot11fTLVNoticeOfAbsence* )(pFrm + pTlv->offset))->present; + break; + case SigTlvOperatingChannel: + byteCount = 5; + pTlvPresent = (( tDot11fTLVOperatingChannel* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PCapability: + byteCount = 2; + pTlvPresent = (( tDot11fTLVP2PCapability* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PDeviceId: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PDeviceId* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PDeviceInfo: + status = GetPackedSizeTlvCore(pCtx, ( tANI_U8* )pFrm + pTlv->offset, pnNeeded, TLVS_P2PDeviceInfo); + byteCount = 16; + pTlvPresent = (( tDot11fTLVP2PDeviceInfo* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupBssid: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PGroupBssid* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupId: + byteCount = ((tDot11fTLVP2PGroupId*)(pFrm + pTlv->offset))->num_ssid+6; + pTlvPresent = (( tDot11fTLVP2PGroupId* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupInfo: + byteCount = ((tDot11fTLVP2PGroupInfo*)(pFrm + pTlv->offset))->num_P2PClientInfoDesc; + pTlvPresent = (( tDot11fTLVP2PGroupInfo* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PStatus: + byteCount = 1; + pTlvPresent = (( tDot11fTLVP2PStatus* )(pFrm + pTlv->offset))->present; + break; + case SigTlvPrimaryDeviceType: + byteCount = 8; + pTlvPresent = (( tDot11fTLVPrimaryDeviceType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRFBands: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRFBands* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestDeviceType: + byteCount = 8; + pTlvPresent = (( tDot11fTLVRequestDeviceType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestType: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRequestType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvResponseType: + byteCount = 1; + pTlvPresent = (( tDot11fTLVResponseType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSelectedRegistrar: + byteCount = 1; + pTlvPresent = (( tDot11fTLVSelectedRegistrar* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSelectedRegistrarConfigMethods: + byteCount = 2; + pTlvPresent = (( tDot11fTLVSelectedRegistrarConfigMethods* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSerialNumber: + byteCount = ((tDot11fTLVSerialNumber*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVSerialNumber* )(pFrm + pTlv->offset))->present; + break; + case SigTlvUUID_E: + byteCount = 16; + pTlvPresent = (( tDot11fTLVUUID_E* )(pFrm + pTlv->offset))->present; + break; + case SigTlvUUID_R: + byteCount = 16; + pTlvPresent = (( tDot11fTLVUUID_R* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVendorExtension: + status = GetPackedSizeTlvCore(pCtx, ( tANI_U8* )pFrm + pTlv->offset, pnNeeded, TLVS_VendorExtension); + byteCount = 3; + pTlvPresent = (( tDot11fTLVVendorExtension* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVersion: + byteCount = 1; + pTlvPresent = (( tDot11fTLVVersion* )(pFrm + pTlv->offset))->present; + break; + case SigTlvWPSState: + byteCount = 1; + pTlvPresent = (( tDot11fTLVWPSState* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PInterface: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PInterface* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PManageability: + byteCount = 1; + pTlvPresent = (( tDot11fTLVP2PManageability* )(pFrm + pTlv->offset))->present; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the TLV signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pTlv->sig); + return DOT11F_INTERNAL_ERROR; + } + if(pTlvPresent) { + *pnNeeded += byteCount; + } + } + ++pTlv; + } + return status; +} +void dot11fPackFfAID(tpAniSirGlobal pCtx, + tDot11fFfAID *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->associd, 0); + (void)pCtx; +} /* End dot11fPackFfAID. */ + +void dot11fPackFfAction(tpAniSirGlobal pCtx, + tDot11fFfAction *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->action; + (void)pCtx; +} /* End dot11fPackFfAction. */ + +void dot11fPackFfAddBAParameterSet(tpAniSirGlobal pCtx, + tDot11fFfAddBAParameterSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp78__; + tmp78__ = 0U; + tmp78__ |= ( pSrc->amsduSupported << 0 ); + tmp78__ |= ( pSrc->policy << 1 ); + tmp78__ |= ( pSrc->tid << 2 ); + tmp78__ |= ( pSrc->bufferSize << 6 ); + frameshtons(pCtx, pBuf, tmp78__, 0); + (void)pCtx; +} /* End dot11fPackFfAddBAParameterSet. */ + +void dot11fPackFfAuthAlgo(tpAniSirGlobal pCtx, + tDot11fFfAuthAlgo *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->algo, 0); + (void)pCtx; +} /* End dot11fPackFfAuthAlgo. */ + +void dot11fPackFfAuthSeqNo(tpAniSirGlobal pCtx, + tDot11fFfAuthSeqNo *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->no, 0); + (void)pCtx; +} /* End dot11fPackFfAuthSeqNo. */ + +void dot11fPackFfBAStartingSequenceControl(tpAniSirGlobal pCtx, + tDot11fFfBAStartingSequenceControl *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp79__; + tmp79__ = 0U; + tmp79__ |= ( pSrc->fragNumber << 0 ); + tmp79__ |= ( pSrc->ssn << 4 ); + frameshtons(pCtx, pBuf, tmp79__, 0); + (void)pCtx; +} /* End dot11fPackFfBAStartingSequenceControl. */ + +void dot11fPackFfBATimeout(tpAniSirGlobal pCtx, + tDot11fFfBATimeout *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->timeout, 0); + (void)pCtx; +} /* End dot11fPackFfBATimeout. */ + +void dot11fPackFfBeaconInterval(tpAniSirGlobal pCtx, + tDot11fFfBeaconInterval *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->interval, 0); + (void)pCtx; +} /* End dot11fPackFfBeaconInterval. */ + +void dot11fPackFfCapabilities(tpAniSirGlobal pCtx, + tDot11fFfCapabilities *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp80__; + tmp80__ = 0U; + tmp80__ |= ( pSrc->ess << 0 ); + tmp80__ |= ( pSrc->ibss << 1 ); + tmp80__ |= ( pSrc->cfPollable << 2 ); + tmp80__ |= ( pSrc->cfPollReq << 3 ); + tmp80__ |= ( pSrc->privacy << 4 ); + tmp80__ |= ( pSrc->shortPreamble << 5 ); + tmp80__ |= ( pSrc->pbcc << 6 ); + tmp80__ |= ( pSrc->channelAgility << 7 ); + tmp80__ |= ( pSrc->spectrumMgt << 8 ); + tmp80__ |= ( pSrc->qos << 9 ); + tmp80__ |= ( pSrc->shortSlotTime << 10 ); + tmp80__ |= ( pSrc->apsd << 11 ); + tmp80__ |= ( pSrc->rrm << 12 ); + tmp80__ |= ( pSrc->dsssOfdm << 13 ); + tmp80__ |= ( pSrc->delayedBA << 14 ); + tmp80__ |= ( pSrc->immediateBA << 15 ); + frameshtons(pCtx, pBuf, tmp80__, 0); + (void)pCtx; +} /* End dot11fPackFfCapabilities. */ + +void dot11fPackFfCategory(tpAniSirGlobal pCtx, + tDot11fFfCategory *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->category; + (void)pCtx; +} /* End dot11fPackFfCategory. */ + +void dot11fPackFfCurrentAPAddress(tpAniSirGlobal pCtx, + tDot11fFfCurrentAPAddress *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6); + (void)pCtx; +} /* End dot11fPackFfCurrentAPAddress. */ + +void dot11fPackFfDelBAParameterSet(tpAniSirGlobal pCtx, + tDot11fFfDelBAParameterSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp81__; + tmp81__ = 0U; + tmp81__ |= ( pSrc->reserved << 0 ); + tmp81__ |= ( pSrc->initiator << 11 ); + tmp81__ |= ( pSrc->tid << 12 ); + frameshtons(pCtx, pBuf, tmp81__, 0); + (void)pCtx; +} /* End dot11fPackFfDelBAParameterSet. */ + +void dot11fPackFfDialogToken(tpAniSirGlobal pCtx, + tDot11fFfDialogToken *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->token; + (void)pCtx; +} /* End dot11fPackFfDialogToken. */ + +void dot11fPackFfLinkMargin(tpAniSirGlobal pCtx, + tDot11fFfLinkMargin *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->linkMargin; + (void)pCtx; +} /* End dot11fPackFfLinkMargin. */ + +void dot11fPackFfListenInterval(tpAniSirGlobal pCtx, + tDot11fFfListenInterval *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->interval, 0); + (void)pCtx; +} /* End dot11fPackFfListenInterval. */ + +void dot11fPackFfMaxTxPower(tpAniSirGlobal pCtx, + tDot11fFfMaxTxPower *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->maxTxPower; + (void)pCtx; +} /* End dot11fPackFfMaxTxPower. */ + +void dot11fPackFfNumOfRepetitions(tpAniSirGlobal pCtx, + tDot11fFfNumOfRepetitions *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->repetitions, 0); + (void)pCtx; +} /* End dot11fPackFfNumOfRepetitions. */ + +void dot11fPackFfOperatingMode(tpAniSirGlobal pCtx, + tDot11fFfOperatingMode *pSrc, + tANI_U8 *pBuf) +{ + tANI_U8 tmp82__; + tmp82__ = 0U; + tmp82__ |= ( pSrc->chanWidth << 0 ); + tmp82__ |= ( pSrc->reserved << 2 ); + tmp82__ |= ( pSrc->rxNSS << 4 ); + tmp82__ |= ( pSrc->rxNSSType << 7 ); + *pBuf = tmp82__; + (void)pCtx; +} /* End dot11fPackFfOperatingMode. */ + +void dot11fPackFfP2POUI(tpAniSirGlobal pCtx, + tDot11fFfP2POUI *pSrc, + tANI_U8 *pBuf) +{ + frameshtonl(pCtx, pBuf, pSrc->oui, 0); + (void)pCtx; +} /* End dot11fPackFfP2POUI. */ + +void dot11fPackFfP2POUISubType(tpAniSirGlobal pCtx, + tDot11fFfP2POUISubType *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->ouiSubtype; + (void)pCtx; +} /* End dot11fPackFfP2POUISubType. */ + +void dot11fPackFfRCPI(tpAniSirGlobal pCtx, + tDot11fFfRCPI *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->rcpi; + (void)pCtx; +} /* End dot11fPackFfRCPI. */ + +void dot11fPackFfRSNI(tpAniSirGlobal pCtx, + tDot11fFfRSNI *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->rsni; + (void)pCtx; +} /* End dot11fPackFfRSNI. */ + +void dot11fPackFfReason(tpAniSirGlobal pCtx, + tDot11fFfReason *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->code, 0); + (void)pCtx; +} /* End dot11fPackFfReason. */ + +void dot11fPackFfRxAntennaId(tpAniSirGlobal pCtx, + tDot11fFfRxAntennaId *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->antennaId; + (void)pCtx; +} /* End dot11fPackFfRxAntennaId. */ + +void dot11fPackFfSMPowerModeSet(tpAniSirGlobal pCtx, + tDot11fFfSMPowerModeSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U8 tmp83__; + tmp83__ = 0U; + tmp83__ |= ( pSrc->PowerSave_En << 0 ); + tmp83__ |= ( pSrc->Mode << 1 ); + tmp83__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp83__; + (void)pCtx; +} /* End dot11fPackFfSMPowerModeSet. */ + +void dot11fPackFfStatus(tpAniSirGlobal pCtx, + tDot11fFfStatus *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->status, 0); + (void)pCtx; +} /* End dot11fPackFfStatus. */ + +void dot11fPackFfStatusCode(tpAniSirGlobal pCtx, + tDot11fFfStatusCode *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->statusCode; + (void)pCtx; +} /* End dot11fPackFfStatusCode. */ + +void dot11fPackFfTPCEleID(tpAniSirGlobal pCtx, + tDot11fFfTPCEleID *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->TPCId; + (void)pCtx; +} /* End dot11fPackFfTPCEleID. */ + +void dot11fPackFfTPCEleLen(tpAniSirGlobal pCtx, + tDot11fFfTPCEleLen *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->TPCLen; + (void)pCtx; +} /* End dot11fPackFfTPCEleLen. */ + +void dot11fPackFfTSInfo(tpAniSirGlobal pCtx, + tDot11fFfTSInfo *pSrc, + tANI_U8 *pBuf) +{ + tANI_U32 tmp84__; + tmp84__ = 0U; + tmp84__ |= ( pSrc->traffic_type << 0 ); + tmp84__ |= ( pSrc->tsid << 1 ); + tmp84__ |= ( pSrc->direction << 5 ); + tmp84__ |= ( pSrc->access_policy << 7 ); + tmp84__ |= ( pSrc->aggregation << 9 ); + tmp84__ |= ( pSrc->psb << 10 ); + tmp84__ |= ( pSrc->user_priority << 11 ); + tmp84__ |= ( pSrc->tsinfo_ack_pol << 14 ); + tmp84__ |= ( pSrc->schedule << 16 ); + tmp84__ |= ( pSrc->unused << 17 ); + frameshtonl(pCtx, pBuf, tmp84__, 0); + (void)pCtx; +} /* End dot11fPackFfTSInfo. */ + +void dot11fPackFfTimeStamp(tpAniSirGlobal pCtx, + tDot11fFfTimeStamp *pSrc, + tANI_U8 *pBuf) +{ + frameshtonq(pCtx, pBuf, pSrc->timestamp, 0); + (void)pCtx; +} /* End dot11fPackFfTimeStamp. */ + +void dot11fPackFfTransactionId(tpAniSirGlobal pCtx, + tDot11fFfTransactionId *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->transId, 2); + (void)pCtx; +} /* End dot11fPackFfTransactionId. */ + +void dot11fPackFfTxAntennaId(tpAniSirGlobal pCtx, + tDot11fFfTxAntennaId *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->antennaId; + (void)pCtx; +} /* End dot11fPackFfTxAntennaId. */ + +void dot11fPackFfTxPower(tpAniSirGlobal pCtx, + tDot11fFfTxPower *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->txPower; + (void)pCtx; +} /* End dot11fPackFfTxPower. */ + +void dot11fPackFfVhtMembershipStatusArray(tpAniSirGlobal pCtx, + tDot11fFfVhtMembershipStatusArray *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->membershipStatusArray, 8); + (void)pCtx; +} /* End dot11fPackFfVhtMembershipStatusArray. */ + +void dot11fPackFfVhtUserPositionArray(tpAniSirGlobal pCtx, + tDot11fFfVhtUserPositionArray *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->userPositionArray, 16); + (void)pCtx; +} /* End dot11fPackFfVhtUserPositionArray. */ + +tANI_U32 dot11fPackTlvAuthorizedMACs(tpAniSirGlobal pCtx, + tDot11fTLVAuthorizedMACs *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 1; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAuthorizedMACs. */ + +tANI_U32 dot11fPackTlvRequestToEnroll(tpAniSirGlobal pCtx, + tDot11fTLVRequestToEnroll *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 3; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + *pBuf = pSrc->req; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestToEnroll. */ + +tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal pCtx, + tDot11fTLVVersion2 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp85__; + nNeeded += 3; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 0; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + tmp85__ = 0U; + tmp85__ |= ( pSrc->minor << 0 ); + tmp85__ |= ( pSrc->major << 4 ); + *pBuf = tmp85__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvVersion2. */ + +tANI_U32 dot11fPackTlvAPSetupLocked(tpAniSirGlobal pCtx, + tDot11fTLVAPSetupLocked *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4183, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->fLocked; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAPSetupLocked. */ + +tANI_U32 dot11fPackTlvAssociationState(tpAniSirGlobal pCtx, + tDot11fTLVAssociationState *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4098, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->state, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAssociationState. */ + +tANI_U32 dot11fPackTlvChannelList(tpAniSirGlobal pCtx, + tDot11fTLVChannelList *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_channelList + 6) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 11; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + pBuf += pSrc->num_channelList; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvChannelList. */ + +tANI_U32 dot11fPackTlvConfigMethods(tpAniSirGlobal pCtx, + tDot11fTLVConfigMethods *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4104, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->methods, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigMethods. */ + +tANI_U32 dot11fPackTlvConfigurationError(tpAniSirGlobal pCtx, + tDot11fTLVConfigurationError *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4105, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->error, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigurationError. */ + +tANI_U32 dot11fPackTlvConfigurationTimeout(tpAniSirGlobal pCtx, + tDot11fTLVConfigurationTimeout *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 5; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->GOConfigTimeout; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->CLConfigTimeout; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigurationTimeout. */ + +tANI_U32 dot11fPackTlvDeviceName(tpAniSirGlobal pCtx, + tDot11fTLVDeviceName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4113, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvDeviceName. */ + +tANI_U32 dot11fPackTlvDevicePasswordID(tpAniSirGlobal pCtx, + tDot11fTLVDevicePasswordID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4114, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->id, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvDevicePasswordID. */ + +tANI_U32 dot11fPackTlvExtendedListenTiming(tpAniSirGlobal pCtx, + tDot11fTLVExtendedListenTiming *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 7; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 8; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->availibilityPeriod, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->availibilityInterval, 0); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvExtendedListenTiming. */ + +tANI_U32 dot11fPackTlvGOIntent(tpAniSirGlobal pCtx, + tDot11fTLVGOIntent *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 4; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->GOIntent; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvGOIntent. */ + +tANI_U32 dot11fPackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal pCtx, + tDot11fTLVIntendedP2PInterfaceAddress *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 9; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PInterfaceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvIntendedP2PInterfaceAddress. */ + +tANI_U32 dot11fPackTlvInvitationFlags(tpAniSirGlobal pCtx, + tDot11fTLVInvitationFlags *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 18; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->invitationFlags; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvInvitationFlags. */ + +tANI_U32 dot11fPackTlvListenChannel(tpAniSirGlobal pCtx, + tDot11fTLVListenChannel *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 6; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvListenChannel. */ + +tANI_U32 dot11fPackTlvManufacturer(tpAniSirGlobal pCtx, + tDot11fTLVManufacturer *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_name + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4129, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->name ), pSrc->num_name); + *pnConsumed += pSrc->num_name; + pBuf += pSrc->num_name; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvManufacturer. */ + +tANI_U32 dot11fPackTlvMinorReasonCode(tpAniSirGlobal pCtx, + tDot11fTLVMinorReasonCode *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 1; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->minorReasonCode; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvMinorReasonCode. */ + +tANI_U32 dot11fPackTlvModelName(tpAniSirGlobal pCtx, + tDot11fTLVModelName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4131, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvModelName. */ + +tANI_U32 dot11fPackTlvModelNumber(tpAniSirGlobal pCtx, + tDot11fTLVModelNumber *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4132, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvModelNumber. */ + +tANI_U32 dot11fPackTlvNoticeOfAbsence(tpAniSirGlobal pCtx, + tDot11fTLVNoticeOfAbsence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_NoADesc + 5) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 12; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->index; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->CTSWindowOppPS; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->NoADesc ), pSrc->num_NoADesc); + *pnConsumed += pSrc->num_NoADesc; + pBuf += pSrc->num_NoADesc; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvNoticeOfAbsence. */ + +tANI_U32 dot11fPackTlvOperatingChannel(tpAniSirGlobal pCtx, + tDot11fTLVOperatingChannel *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 17; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvOperatingChannel. */ + +tANI_U32 dot11fPackTlvP2PCapability(tpAniSirGlobal pCtx, + tDot11fTLVP2PCapability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 2; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->deviceCapability; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->groupCapability; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PCapability. */ + +tANI_U32 dot11fPackTlvP2PDeviceId(tpAniSirGlobal pCtx, + tDot11fTLVP2PDeviceId *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 3; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PDeviceId. */ + +tANI_U32 dot11fPackTlvP2PDeviceInfo(tpAniSirGlobal pCtx, + tDot11fTLVP2PDeviceInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + tANI_U32 idx = 0; + nNeeded += 19; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 13; + pBuf += 1; nBuf -= 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->configMethod, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->primaryDeviceType, 8); + *pnConsumed += 8; + pBuf += 8; + status |= PackTlvCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + TLVS_P2PDeviceInfo, &idx); + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return status; +} /* End dot11fPackTlvP2PDeviceInfo. */ + +tANI_U32 dot11fPackTlvP2PGroupBssid(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupBssid *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 7; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PGroupBssid, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupBssid. */ + +tANI_U32 dot11fPackTlvP2PGroupId(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupId *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_ssid + 9) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 15; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->deviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->ssid ), pSrc->num_ssid); + *pnConsumed += pSrc->num_ssid; + pBuf += pSrc->num_ssid; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupId. */ + +tANI_U32 dot11fPackTlvP2PGroupInfo(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_P2PClientInfoDesc + 3) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 14; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->P2PClientInfoDesc ), pSrc->num_P2PClientInfoDesc); + *pnConsumed += pSrc->num_P2PClientInfoDesc; + pBuf += pSrc->num_P2PClientInfoDesc; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupInfo. */ + +tANI_U32 dot11fPackTlvP2PStatus(tpAniSirGlobal pCtx, + tDot11fTLVP2PStatus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 0; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PStatus. */ + +tANI_U32 dot11fPackTlvPrimaryDeviceType(tpAniSirGlobal pCtx, + tDot11fTLVPrimaryDeviceType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 12; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4180, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->primary_category, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->sub_category, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvPrimaryDeviceType. */ + +tANI_U32 dot11fPackTlvRFBands(tpAniSirGlobal pCtx, + tDot11fTLVRFBands *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4156, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->bands; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRFBands. */ + +tANI_U32 dot11fPackTlvRequestDeviceType(tpAniSirGlobal pCtx, + tDot11fTLVRequestDeviceType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 12; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4202, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->primary_category, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->sub_category, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestDeviceType. */ + +tANI_U32 dot11fPackTlvRequestType(tpAniSirGlobal pCtx, + tDot11fTLVRequestType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4154, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->reqType; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestType. */ + +tANI_U32 dot11fPackTlvResponseType(tpAniSirGlobal pCtx, + tDot11fTLVResponseType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4155, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->resType; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvResponseType. */ + +tANI_U32 dot11fPackTlvSelectedRegistrar(tpAniSirGlobal pCtx, + tDot11fTLVSelectedRegistrar *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4161, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->selected; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSelectedRegistrar. */ + +tANI_U32 dot11fPackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal pCtx, + tDot11fTLVSelectedRegistrarConfigMethods *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4179, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->methods, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSelectedRegistrarConfigMethods. */ + +tANI_U32 dot11fPackTlvSerialNumber(tpAniSirGlobal pCtx, + tDot11fTLVSerialNumber *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4162, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSerialNumber. */ + +tANI_U32 dot11fPackTlvUUID_E(tpAniSirGlobal pCtx, + tDot11fTLVUUID_E *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 20; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4167, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16); + *pnConsumed += 16; + pBuf += 16; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvUUID_E. */ + +tANI_U32 dot11fPackTlvUUID_R(tpAniSirGlobal pCtx, + tDot11fTLVUUID_R *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 20; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4168, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16); + *pnConsumed += 16; + pBuf += 16; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvUUID_R. */ + +tANI_U32 dot11fPackTlvVendorExtension(tpAniSirGlobal pCtx, + tDot11fTLVVendorExtension *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + tANI_U32 idx = 0; + nNeeded += 7; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4169, 1); + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->vendorId, 3); + *pnConsumed += 3; + pBuf += 3; + status |= PackTlvCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + TLVS_VendorExtension, &idx); + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return status; +} /* End dot11fPackTlvVendorExtension. */ + +tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal pCtx, + tDot11fTLVVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp86__; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4170, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + tmp86__ = 0U; + tmp86__ |= ( pSrc->minor << 0 ); + tmp86__ |= ( pSrc->major << 4 ); + *pBuf = tmp86__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvVersion. */ + +tANI_U32 dot11fPackTlvWPSState(tpAniSirGlobal pCtx, + tDot11fTLVWPSState *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4164, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->state; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvWPSState. */ + +tANI_U32 dot11fPackTlvP2PInterface(tpAniSirGlobal pCtx, + tDot11fTLVP2PInterface *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 16; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PInterface. */ + +tANI_U32 dot11fPackTlvP2PManageability(tpAniSirGlobal pCtx, + tDot11fTLVP2PManageability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 10; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->manageability; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PManageability. */ + +tANI_U32 dot11fPackIeAPName(tpAniSirGlobal pCtx, + tDot11fIEAPName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_name; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->name ), pSrc->num_name); + *pnConsumed += pSrc->num_name; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAPName. */ + +tANI_U32 dot11fPackIeBPIndicator(tpAniSirGlobal pCtx, + tDot11fIEBPIndicator *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->indicator; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->type; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBPIndicator. */ + +tANI_U32 dot11fPackIeCondensedCountryStr(tpAniSirGlobal pCtx, + tDot11fIECondensedCountryStr *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryStr, 2); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeCondensedCountryStr. */ + +tANI_U32 dot11fPackIeGTK(tpAniSirGlobal pCtx, + tDot11fIEGTK *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp87__; + nNeeded += (pSrc->num_key + 11); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp87__ = 0U; + tmp87__ |= ( pSrc->keyId << 0 ); + tmp87__ |= ( pSrc->reserved << 2 ); + frameshtons(pCtx, pBuf, tmp87__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + *pBuf = pSrc->keyLength; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSC, 8); + *pnConsumed += 8; + pBuf += 8; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->key ), pSrc->num_key); + *pnConsumed += pSrc->num_key; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeGTK. */ + +tANI_U32 dot11fPackIeHCF(tpAniSirGlobal pCtx, + tDot11fIEHCF *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->enabled; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHCF. */ + +tANI_U32 dot11fPackIeIGTK(tpAniSirGlobal pCtx, + tDot11fIEIGTK *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 33; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->keyID, 2); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->IPN, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->keyLength; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->key, 24); + *pnConsumed += 24; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeIGTK. */ + +tANI_U32 dot11fPackIeLLAttr(tpAniSirGlobal pCtx, + tDot11fIELLAttr *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 9; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->defer_threshold, 1); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLLAttr. */ + +tANI_U32 dot11fPackIeLoadBalance(tpAniSirGlobal pCtx, + tDot11fIELoadBalance *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 7; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 8; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->channel; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLoadBalance. */ + +tANI_U32 dot11fPackIeLoadInfo(tpAniSirGlobal pCtx, + tDot11fIELoadInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 6; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->num_stas, 1); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->channel_util, 1); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLoadInfo. */ + +tANI_U32 dot11fPackIePropAssocType(tpAniSirGlobal pCtx, + tDot11fIEPropAssocType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 7; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->type; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropAssocType. */ + +tANI_U32 dot11fPackIePropCapability(tpAniSirGlobal pCtx, + tDot11fIEPropCapability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 10; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->capability, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropCapability. */ + +tANI_U32 dot11fPackIePropChannSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEPropChannSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 15; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->mode; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->primary_channel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->sub_band; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel_switch_count; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropChannSwitchAnn. */ + +tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal pCtx, + tDot11fIEPropEDCAParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp88__; + tANI_U8 tmp89__; + tANI_U8 tmp90__; + tANI_U8 tmp91__; + tANI_U8 tmp92__; + tANI_U8 tmp93__; + tANI_U8 tmp94__; + tANI_U8 tmp95__; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 12; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->qos; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + pBuf += 1; + tmp88__ = 0U; + tmp88__ |= ( pSrc->acbe_aifsn << 0 ); + tmp88__ |= ( pSrc->acbe_acm << 4 ); + tmp88__ |= ( pSrc->acbe_aci << 5 ); + tmp88__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp88__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp89__ = 0U; + tmp89__ |= ( pSrc->acbe_min << 0 ); + tmp89__ |= ( pSrc->acbe_max << 4 ); + *pBuf = tmp89__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp90__ = 0U; + tmp90__ |= ( pSrc->acbk_aifsn << 0 ); + tmp90__ |= ( pSrc->acbk_acm << 4 ); + tmp90__ |= ( pSrc->acbk_aci << 5 ); + tmp90__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp90__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp91__ = 0U; + tmp91__ |= ( pSrc->acbk_min << 0 ); + tmp91__ |= ( pSrc->acbk_max << 4 ); + *pBuf = tmp91__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp92__ = 0U; + tmp92__ |= ( pSrc->acvi_aifsn << 0 ); + tmp92__ |= ( pSrc->acvi_acm << 4 ); + tmp92__ |= ( pSrc->acvi_aci << 5 ); + tmp92__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp92__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp93__ = 0U; + tmp93__ |= ( pSrc->acvi_min << 0 ); + tmp93__ |= ( pSrc->acvi_max << 4 ); + *pBuf = tmp93__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp94__ = 0U; + tmp94__ |= ( pSrc->acvo_aifsn << 0 ); + tmp94__ |= ( pSrc->acvo_acm << 4 ); + tmp94__ |= ( pSrc->acvo_aci << 5 ); + tmp94__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp94__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp95__ = 0U; + tmp95__ |= ( pSrc->acvo_min << 0 ); + tmp95__ |= ( pSrc->acvo_max << 4 ); + *pBuf = tmp95__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropEDCAParams. */ + +tANI_U32 dot11fPackIePropQuietBSS(tpAniSirGlobal pCtx, + tDot11fIEPropQuietBSS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 16; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->quiet_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->quiet_period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->quiet_duration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->quiet_offset, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropQuietBSS. */ + +tANI_U32 dot11fPackIePropSuppRates(tpAniSirGlobal pCtx, + tDot11fIEPropSuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 0; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropSuppRates. */ + +tANI_U32 dot11fPackIeR0KH_ID(tpAniSirGlobal pCtx, + tDot11fIER0KH_ID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_PMK_R0_ID; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->PMK_R0_ID ), pSrc->num_PMK_R0_ID); + *pnConsumed += pSrc->num_PMK_R0_ID; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeR0KH_ID. */ + +tANI_U32 dot11fPackIeR1KH_ID(tpAniSirGlobal pCtx, + tDot11fIER1KH_ID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->PMK_R1_ID, 6); + *pnConsumed += 6; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeR1KH_ID. */ + +tANI_U32 dot11fPackIeTSFInfo(tpAniSirGlobal pCtx, + tDot11fIETSFInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->TsfOffset, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->BeaconIntvl, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSFInfo. */ + +tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal pCtx, + tDot11fIETaurus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp96__; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 18; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->baTIDBitmap, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->baPolicy, 0); + *pnConsumed += 2; + pBuf += 2; + tmp96__ = 0U; + tmp96__ |= ( pSrc->baBufferSize << 0 ); + tmp96__ |= ( pSrc->rsvd << 12 ); + frameshtons(pCtx, pBuf, tmp96__, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + nBuf -= 2 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTaurus. */ + +tANI_U32 dot11fPackIeTitan(tpAniSirGlobal pCtx, + tDot11fIETitan *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 14; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->concat_tcid_bitmap; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->compression_tcid_bitmap; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->cb_state; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->rev_fcs_state; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTitan. */ + +tANI_U32 dot11fPackIeTriggerStaBgScan(tpAniSirGlobal pCtx, + tDot11fIETriggerStaBgScan *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 17; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->enable; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTriggerStaBgScan. */ + +tANI_U32 dot11fPackIeVersion(tpAniSirGlobal pCtx, + tDot11fIEVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_build_version + 5); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 11; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->chip_rev, 0); + *pnConsumed += 4; + pBuf += 4; + *pBuf = pSrc->card_type; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->build_version ), pSrc->num_build_version); + *pnConsumed += pSrc->num_build_version; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVersion. */ + +tANI_U32 dot11fPackIeWDS(tpAniSirGlobal pCtx, + tDot11fIEWDS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_wdsData; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->wdsData ), pSrc->num_wdsData); + *pnConsumed += pSrc->num_wdsData; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWDS. */ + +tANI_U32 dot11fPackIeAPChannelReport(tpAniSirGlobal pCtx, + tDot11fIEAPChannelReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_channelList + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 51; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAPChannelReport. */ + +tANI_U32 dot11fPackIeBcnReportingDetail(tpAniSirGlobal pCtx, + tDot11fIEBcnReportingDetail *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->reportingDetail; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBcnReportingDetail. */ + +tANI_U32 dot11fPackIeBeaconReportFrmBody(tpAniSirGlobal pCtx, + tDot11fIEBeaconReportFrmBody *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_reportedFields; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->reportedFields ), pSrc->num_reportedFields); + *pnConsumed += pSrc->num_reportedFields; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBeaconReportFrmBody. */ + +tANI_U32 dot11fPackIeBeaconReporting(tpAniSirGlobal pCtx, + tDot11fIEBeaconReporting *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->reportingCondition; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->threshold; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBeaconReporting. */ + +tANI_U32 dot11fPackIeMeasurementPilot(tpAniSirGlobal pCtx, + tDot11fIEMeasurementPilot *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vendorSpecific + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 66; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->measurementPilot; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vendorSpecific ), pSrc->num_vendorSpecific); + *pnConsumed += pSrc->num_vendorSpecific; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMeasurementPilot. */ + +tANI_U32 dot11fPackIeMultiBssid(tpAniSirGlobal pCtx, + tDot11fIEMultiBssid *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vendorSpecific + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 71; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->maxBSSIDIndicator; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vendorSpecific ), pSrc->num_vendorSpecific); + *pnConsumed += pSrc->num_vendorSpecific; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMultiBssid. */ + +tANI_U32 dot11fPackIeRICData(tpAniSirGlobal pCtx, + tDot11fIERICData *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 57; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->Identifier; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->resourceDescCount; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->statusCode, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRICData. */ + +tANI_U32 dot11fPackIeRICDescriptor(tpAniSirGlobal pCtx, + tDot11fIERICDescriptor *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_variableData + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 75; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->resourceType; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->variableData ), pSrc->num_variableData); + *pnConsumed += pSrc->num_variableData; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRICDescriptor. */ + +tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, + tDot11fIERRMEnabledCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp97__; + tANI_U8 tmp98__; + tANI_U8 tmp99__; + tANI_U8 tmp100__; + tANI_U8 tmp101__; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 70; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp97__ = 0U; + tmp97__ |= ( pSrc->LinkMeasurement << 0 ); + tmp97__ |= ( pSrc->NeighborRpt << 1 ); + tmp97__ |= ( pSrc->parallel << 2 ); + tmp97__ |= ( pSrc->repeated << 3 ); + tmp97__ |= ( pSrc->BeaconPassive << 4 ); + tmp97__ |= ( pSrc->BeaconActive << 5 ); + tmp97__ |= ( pSrc->BeaconTable << 6 ); + tmp97__ |= ( pSrc->BeaconRepCond << 7 ); + *pBuf = tmp97__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp98__ = 0U; + tmp98__ |= ( pSrc->FrameMeasurement << 0 ); + tmp98__ |= ( pSrc->ChannelLoad << 1 ); + tmp98__ |= ( pSrc->NoiseHistogram << 2 ); + tmp98__ |= ( pSrc->statistics << 3 ); + tmp98__ |= ( pSrc->LCIMeasurement << 4 ); + tmp98__ |= ( pSrc->LCIAzimuth << 5 ); + tmp98__ |= ( pSrc->TCMCapability << 6 ); + tmp98__ |= ( pSrc->triggeredTCM << 7 ); + *pBuf = tmp98__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp99__ = 0U; + tmp99__ |= ( pSrc->APChanReport << 0 ); + tmp99__ |= ( pSrc->RRMMIBEnabled << 1 ); + tmp99__ |= ( pSrc->operatingChanMax << 2 ); + tmp99__ |= ( pSrc->nonOperatinChanMax << 5 ); + *pBuf = tmp99__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp100__ = 0U; + tmp100__ |= ( pSrc->MeasurementPilot << 0 ); + tmp100__ |= ( pSrc->MeasurementPilotEnabled << 3 ); + tmp100__ |= ( pSrc->NeighborTSFOffset << 4 ); + tmp100__ |= ( pSrc->RCPIMeasurement << 5 ); + tmp100__ |= ( pSrc->RSNIMeasurement << 6 ); + tmp100__ |= ( pSrc->BssAvgAccessDelay << 7 ); + *pBuf = tmp100__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp101__ = 0U; + tmp101__ |= ( pSrc->BSSAvailAdmission << 0 ); + tmp101__ |= ( pSrc->AntennaInformation << 1 ); + tmp101__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp101__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRRMEnabledCap. */ + +tANI_U32 dot11fPackIeRequestedInfo(tpAniSirGlobal pCtx, + tDot11fIERequestedInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_requested_eids; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 10; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->requested_eids ), pSrc->num_requested_eids); + *pnConsumed += pSrc->num_requested_eids; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRequestedInfo. */ + +tANI_U32 dot11fPackIeSSID(tpAniSirGlobal pCtx, + tDot11fIESSID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_ssid; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 0; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->ssid ), pSrc->num_ssid); + *pnConsumed += pSrc->num_ssid; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSSID. */ + +tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal pCtx, + tDot11fIESchedule *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp102__; + nNeeded += 14; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 15; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp102__ = 0U; + tmp102__ |= ( pSrc->aggregation << 0 ); + tmp102__ |= ( pSrc->tsid << 1 ); + tmp102__ |= ( pSrc->direction << 5 ); + tmp102__ |= ( pSrc->reserved << 7 ); + frameshtons(pCtx, pBuf, tmp102__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_interval, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->spec_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSchedule. */ + +tANI_U32 dot11fPackIeTCLAS(tpAniSirGlobal pCtx, + tDot11fIETCLAS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIETCLAS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 14; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->user_priority; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_type; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_mask; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->info.IpParams.version; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4); + *pnConsumed += 4; + pBuf += 4; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.proto; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 6: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 16); + *pnConsumed += 16; + pBuf += 16; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3); + *pnConsumed += 3; + // fieldsEndFlag = 1 + break; + } + break; + case 2: + frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeTCLAS. */ + +tANI_U32 dot11fPackIeTCLASSPROC(tpAniSirGlobal pCtx, + tDot11fIETCLASSPROC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 44; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->processing; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTCLASSPROC. */ + +tANI_U32 dot11fPackIeTSDelay(tpAniSirGlobal pCtx, + tDot11fIETSDelay *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 43; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->delay, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSDelay. */ + +tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx, + tDot11fIETSPEC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp103__; + tANI_U8 tmp104__; + tANI_U16 tmp105__; + nNeeded += 55; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 13; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp103__ = 0U; + tmp103__ |= ( pSrc->traffic_type << 0 ); + tmp103__ |= ( pSrc->tsid << 1 ); + tmp103__ |= ( pSrc->direction << 5 ); + tmp103__ |= ( pSrc->access_policy << 7 ); + tmp103__ |= ( pSrc->aggregation << 9 ); + tmp103__ |= ( pSrc->psb << 10 ); + tmp103__ |= ( pSrc->user_priority << 11 ); + tmp103__ |= ( pSrc->tsinfo_ack_pol << 14 ); + frameshtons(pCtx, pBuf, tmp103__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp104__ = 0U; + tmp104__ |= ( pSrc->schedule << 0 ); + tmp104__ |= ( pSrc->unused << 1 ); + *pBuf = tmp104__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp105__ = 0U; + tmp105__ |= ( pSrc->size << 0 ); + tmp105__ |= ( pSrc->fixed << 15 ); + frameshtons(pCtx, pBuf, tmp105__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->burst_size, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->medium_time, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSPEC. */ + +tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal pCtx, + tDot11fIEWMMSchedule *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp106__; + nNeeded += 15; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp106__ = 0U; + tmp106__ |= ( pSrc->aggregation << 0 ); + tmp106__ |= ( pSrc->tsid << 1 ); + tmp106__ |= ( pSrc->direction << 5 ); + tmp106__ |= ( pSrc->reserved << 7 ); + frameshtons(pCtx, pBuf, tmp106__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_interval, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->spec_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMSchedule. */ + +tANI_U32 dot11fPackIeWMMTCLAS(tpAniSirGlobal pCtx, + tDot11fIEWMMTCLAS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWMMTCLAS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->user_priority; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_type; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_mask; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->info.IpParams.version; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4); + *pnConsumed += 4; + pBuf += 4; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.proto; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 6: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 10); + *pnConsumed += 10; + pBuf += 10; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 10); + *pnConsumed += 10; + pBuf += 10; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3); + *pnConsumed += 3; + // fieldsEndFlag = 1 + break; + } + break; + case 2: + frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWMMTCLAS. */ + +tANI_U32 dot11fPackIeWMMTCLASPROC(tpAniSirGlobal pCtx, + tDot11fIEWMMTCLASPROC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x7; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->processing; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTCLASPROC. */ + +tANI_U32 dot11fPackIeWMMTSDelay(tpAniSirGlobal pCtx, + tDot11fIEWMMTSDelay *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->delay, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTSDelay. */ + +tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx, + tDot11fIEWMMTSPEC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp107__; + tANI_U8 tmp108__; + tANI_U16 tmp109__; + nNeeded += 38; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp107__ = 0U; + tmp107__ |= ( pSrc->traffic_type << 0 ); + tmp107__ |= ( pSrc->tsid << 1 ); + tmp107__ |= ( pSrc->direction << 5 ); + tmp107__ |= ( pSrc->access_policy << 7 ); + tmp107__ |= ( pSrc->aggregation << 9 ); + tmp107__ |= ( pSrc->psb << 10 ); + tmp107__ |= ( pSrc->user_priority << 11 ); + tmp107__ |= ( pSrc->tsinfo_ack_pol << 14 ); + frameshtons(pCtx, pBuf, tmp107__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp108__ = 0U; + tmp108__ |= ( pSrc->tsinfo_rsvd << 0 ); + tmp108__ |= ( pSrc->burst_size_defn << 7 ); + *pBuf = tmp108__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp109__ = 0U; + tmp109__ |= ( pSrc->size << 0 ); + tmp109__ |= ( pSrc->fixed << 15 ); + frameshtons(pCtx, pBuf, tmp109__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->burst_size, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->medium_time, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTSPEC. */ + +tANI_U32 dot11fPackIeWiderBWChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEWiderBWChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 194; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->newChanWidth; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newCenterChanFreq0; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newCenterChanFreq1; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWiderBWChanSwitchAnn. */ + +tANI_U32 dot11fPackIeAID(tpAniSirGlobal pCtx, + tDot11fIEAID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 197; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->assocId, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAID. */ + +tANI_U32 dot11fPackIeAirgo(tpAniSirGlobal pCtx, + tDot11fIEAirgo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEAirgo(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xa; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf5; + ++pBuf; --nBuf; ++(*pnConsumed); + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_Airgo, + IES_Airgo); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeAirgo. */ + +tANI_U32 dot11fPackIeCFParams(tpAniSirGlobal pCtx, + tDot11fIECFParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->cfp_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->cfp_period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->cfp_maxduration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->cfp_durremaining, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeCFParams. */ + +tANI_U32 dot11fPackIeChallengeText(tpAniSirGlobal pCtx, + tDot11fIEChallengeText *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_text; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 16; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeChallengeText. */ + +tANI_U32 dot11fPackIeChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 37; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->switchMode; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newChannel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->switchCount; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeChanSwitchAnn. */ + +tANI_U32 dot11fPackIeChannelSwitchWrapper(tpAniSirGlobal pCtx, + tDot11fIEChannelSwitchWrapper *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEChannelSwitchWrapper(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 196; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_ChannelSwitchWrapper, + IES_ChannelSwitchWrapper); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeChannelSwitchWrapper. */ + +tANI_U32 dot11fPackIeCountry(tpAniSirGlobal pCtx, + tDot11fIECountry *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIECountry(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 7; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + if ( pSrc->num_triplets ) { + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeCountry. */ + +tANI_U32 dot11fPackIeDSParams(tpAniSirGlobal pCtx, + tDot11fIEDSParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->curr_channel; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeDSParams. */ + +tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, + tDot11fIEEDCAParamSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp110__; + tANI_U8 tmp111__; + tANI_U8 tmp112__; + tANI_U8 tmp113__; + tANI_U8 tmp114__; + tANI_U8 tmp115__; + tANI_U8 tmp116__; + tANI_U8 tmp117__; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 12; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->qos; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + pBuf += 1; + tmp110__ = 0U; + tmp110__ |= ( pSrc->acbe_aifsn << 0 ); + tmp110__ |= ( pSrc->acbe_acm << 4 ); + tmp110__ |= ( pSrc->acbe_aci << 5 ); + tmp110__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp110__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp111__ = 0U; + tmp111__ |= ( pSrc->acbe_acwmin << 0 ); + tmp111__ |= ( pSrc->acbe_acwmax << 4 ); + *pBuf = tmp111__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp112__ = 0U; + tmp112__ |= ( pSrc->acbk_aifsn << 0 ); + tmp112__ |= ( pSrc->acbk_acm << 4 ); + tmp112__ |= ( pSrc->acbk_aci << 5 ); + tmp112__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp112__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp113__ = 0U; + tmp113__ |= ( pSrc->acbk_acwmin << 0 ); + tmp113__ |= ( pSrc->acbk_acwmax << 4 ); + *pBuf = tmp113__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp114__ = 0U; + tmp114__ |= ( pSrc->acvi_aifsn << 0 ); + tmp114__ |= ( pSrc->acvi_acm << 4 ); + tmp114__ |= ( pSrc->acvi_aci << 5 ); + tmp114__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp114__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp115__ = 0U; + tmp115__ |= ( pSrc->acvi_acwmin << 0 ); + tmp115__ |= ( pSrc->acvi_acwmax << 4 ); + *pBuf = tmp115__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp116__ = 0U; + tmp116__ |= ( pSrc->acvo_aifsn << 0 ); + tmp116__ |= ( pSrc->acvo_acm << 4 ); + tmp116__ |= ( pSrc->acvo_aci << 5 ); + tmp116__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp116__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp117__ = 0U; + tmp117__ |= ( pSrc->acvo_acwmin << 0 ); + tmp117__ |= ( pSrc->acvo_acwmax << 4 ); + *pBuf = tmp117__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeEDCAParamSet. */ + +tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal pCtx, + tDot11fIEERPInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp118__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 42; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp118__ = 0U; + tmp118__ |= ( pSrc->non_erp_present << 0 ); + tmp118__ |= ( pSrc->use_prot << 1 ); + tmp118__ |= ( pSrc->barker_preamble << 2 ); + tmp118__ |= ( pSrc->unused << 3 ); + *pBuf = tmp118__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeERPInfo. */ + +tANI_U32 dot11fPackIeESECckmOpaque(tpAniSirGlobal pCtx, + tDot11fIEESECckmOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 156; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESECckmOpaque. */ + +tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal pCtx, + tDot11fIEESERadMgmtCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp119__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->mgmt_state; + *pnConsumed += 1; + pBuf += 1; + tmp119__ = 0U; + tmp119__ |= ( pSrc->mbssid_mask << 0 ); + tmp119__ |= ( pSrc->reserved << 3 ); + *pBuf = tmp119__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESERadMgmtCap. */ + +tANI_U32 dot11fPackIeESETrafStrmMet(tpAniSirGlobal pCtx, + tDot11fIEESETrafStrmMet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x7; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tsid; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->state; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->msmt_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETrafStrmMet. */ + +tANI_U32 dot11fPackIeESETrafStrmRateSet(tpAniSirGlobal pCtx, + tDot11fIEESETrafStrmRateSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_tsrates + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tsid; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->tsrates ), pSrc->num_tsrates); + *pnConsumed += pSrc->num_tsrates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETrafStrmRateSet. */ + +tANI_U32 dot11fPackIeESETxmitPower(tpAniSirGlobal pCtx, + tDot11fIEESETxmitPower *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 150; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->power_limit; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETxmitPower. */ + +tANI_U32 dot11fPackIeESEVersion(tpAniSirGlobal pCtx, + tDot11fIEESEVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x3; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESEVersion. */ + +tANI_U32 dot11fPackIeExtCap(tpAniSirGlobal pCtx, + tDot11fIEExtCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_bytes; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 127; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bytes ), pSrc->num_bytes); + *pnConsumed += pSrc->num_bytes; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtCap. */ + +tANI_U32 dot11fPackIeExtChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEExtChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 62; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->secondaryChannelOffset; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtChanSwitchAnn. */ + +tANI_U32 dot11fPackIeExtSuppRates(tpAniSirGlobal pCtx, + tDot11fIEExtSuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 50; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtSuppRates. */ + +tANI_U32 dot11fPackIeFHParamSet(tpAniSirGlobal pCtx, + tDot11fIEFHParamSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->dwell_time, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->hop_set; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->hop_pattern; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->hop_index; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHParamSet. */ + +tANI_U32 dot11fPackIeFHParams(tpAniSirGlobal pCtx, + tDot11fIEFHParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 8; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->radix; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->nchannels; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHParams. */ + +tANI_U32 dot11fPackIeFHPattTable(tpAniSirGlobal pCtx, + tDot11fIEFHPattTable *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_randtable + 4); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 9; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->flag; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->nsets; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->modulus; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->offset; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->randtable ), pSrc->num_randtable); + *pnConsumed += pSrc->num_randtable; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHPattTable. */ + +tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal pCtx, + tDot11fIEFTInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp120__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEFTInfo(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 55; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + tmp120__ = 0U; + tmp120__ |= ( pSrc->reserved << 0 ); + tmp120__ |= ( pSrc->IECount << 8 ); + frameshtons(pCtx, pBuf, tmp120__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->MIC, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->Anonce, 32); + *pnConsumed += 32; + pBuf += 32; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->Snonce, 32); + *pnConsumed += 32; + pBuf += 32; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_FTInfo, + IES_FTInfo); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeFTInfo. */ + +tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, + tDot11fIEHT2040BSSCoexistence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp121__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 72; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp121__ = 0U; + tmp121__ |= ( pSrc->infoRequest << 0 ); + tmp121__ |= ( pSrc->fortyMHzIntolerant << 1 ); + tmp121__ |= ( pSrc->twentyMHzBssWidthReq << 2 ); + tmp121__ |= ( pSrc->obssScanExemptionReq << 3 ); + tmp121__ |= ( pSrc->obssScanExemptionGrant << 4 ); + tmp121__ |= ( pSrc->unused << 5 ); + *pBuf = tmp121__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHT2040BSSCoexistence. */ + +tANI_U32 dot11fPackIeHT2040BSSIntolerantReport(tpAniSirGlobal pCtx, + tDot11fIEHT2040BSSIntolerantReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_channelList + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 73; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->operatingClass; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHT2040BSSIntolerantReport. */ + +tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, + tDot11fIEHTCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp122__; + tANI_U8 tmp123__; + tANI_U16 tmp124__; + tANI_U32 tmp125__; + tANI_U8 tmp126__; + nNeeded += (pSrc->num_rsvd + 26); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 45; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp122__ = 0U; + tmp122__ |= ( pSrc->advCodingCap << 0 ); + tmp122__ |= ( pSrc->supportedChannelWidthSet << 1 ); + tmp122__ |= ( pSrc->mimoPowerSave << 2 ); + tmp122__ |= ( pSrc->greenField << 4 ); + tmp122__ |= ( pSrc->shortGI20MHz << 5 ); + tmp122__ |= ( pSrc->shortGI40MHz << 6 ); + tmp122__ |= ( pSrc->txSTBC << 7 ); + tmp122__ |= ( pSrc->rxSTBC << 8 ); + tmp122__ |= ( pSrc->delayedBA << 10 ); + tmp122__ |= ( pSrc->maximalAMSDUsize << 11 ); + tmp122__ |= ( pSrc->dsssCckMode40MHz << 12 ); + tmp122__ |= ( pSrc->psmp << 13 ); + tmp122__ |= ( pSrc->stbcControlFrame << 14 ); + tmp122__ |= ( pSrc->lsigTXOPProtection << 15 ); + frameshtons(pCtx, pBuf, tmp122__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp123__ = 0U; + tmp123__ |= ( pSrc->maxRxAMPDUFactor << 0 ); + tmp123__ |= ( pSrc->mpduDensity << 2 ); + tmp123__ |= ( pSrc->reserved1 << 5 ); + *pBuf = tmp123__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16); + *pnConsumed += 16; + pBuf += 16; + tmp124__ = 0U; + tmp124__ |= ( pSrc->pco << 0 ); + tmp124__ |= ( pSrc->transitionTime << 1 ); + tmp124__ |= ( pSrc->reserved2 << 3 ); + tmp124__ |= ( pSrc->mcsFeedback << 8 ); + tmp124__ |= ( pSrc->reserved3 << 10 ); + frameshtons(pCtx, pBuf, tmp124__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp125__ = 0U; + tmp125__ |= ( pSrc->txBF << 0 ); + tmp125__ |= ( pSrc->rxStaggeredSounding << 1 ); + tmp125__ |= ( pSrc->txStaggeredSounding << 2 ); + tmp125__ |= ( pSrc->rxZLF << 3 ); + tmp125__ |= ( pSrc->txZLF << 4 ); + tmp125__ |= ( pSrc->implicitTxBF << 5 ); + tmp125__ |= ( pSrc->calibration << 6 ); + tmp125__ |= ( pSrc->explicitCSITxBF << 8 ); + tmp125__ |= ( pSrc->explicitUncompressedSteeringMatrix << 9 ); + tmp125__ |= ( pSrc->explicitBFCSIFeedback << 10 ); + tmp125__ |= ( pSrc->explicitUncompressedSteeringMatrixFeedback << 13 ); + tmp125__ |= ( pSrc->explicitCompressedSteeringMatrixFeedback << 16 ); + tmp125__ |= ( pSrc->csiNumBFAntennae << 19 ); + tmp125__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 ); + tmp125__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 ); + tmp125__ |= ( pSrc->reserved4 << 25 ); + frameshtonl(pCtx, pBuf, tmp125__, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4 ; + tmp126__ = 0U; + tmp126__ |= ( pSrc->antennaSelection << 0 ); + tmp126__ |= ( pSrc->explicitCSIFeedbackTx << 1 ); + tmp126__ |= ( pSrc->antennaIndicesFeedbackTx << 2 ); + tmp126__ |= ( pSrc->explicitCSIFeedback << 3 ); + tmp126__ |= ( pSrc->antennaIndicesFeedback << 4 ); + tmp126__ |= ( pSrc->rxAS << 5 ); + tmp126__ |= ( pSrc->txSoundingPPDUs << 6 ); + tmp126__ |= ( pSrc->reserved5 << 7 ); + *pBuf = tmp126__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rsvd ), pSrc->num_rsvd); + *pnConsumed += pSrc->num_rsvd; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHTCaps. */ + +tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx, + tDot11fIEHTInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp127__; + tANI_U16 tmp128__; + tANI_U16 tmp129__; + nNeeded += (pSrc->num_rsvd + 22); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 61; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->primaryChannel; + *pnConsumed += 1; + pBuf += 1; + tmp127__ = 0U; + tmp127__ |= ( pSrc->secondaryChannelOffset << 0 ); + tmp127__ |= ( pSrc->recommendedTxWidthSet << 2 ); + tmp127__ |= ( pSrc->rifsMode << 3 ); + tmp127__ |= ( pSrc->controlledAccessOnly << 4 ); + tmp127__ |= ( pSrc->serviceIntervalGranularity << 5 ); + *pBuf = tmp127__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp128__ = 0U; + tmp128__ |= ( pSrc->opMode << 0 ); + tmp128__ |= ( pSrc->nonGFDevicesPresent << 2 ); + tmp128__ |= ( pSrc->transmitBurstLimit << 3 ); + tmp128__ |= ( pSrc->obssNonHTStaPresent << 4 ); + tmp128__ |= ( pSrc->reserved << 5 ); + frameshtons(pCtx, pBuf, tmp128__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp129__ = 0U; + tmp129__ |= ( pSrc->basicSTBCMCS << 0 ); + tmp129__ |= ( pSrc->dualCTSProtection << 7 ); + tmp129__ |= ( pSrc->secondaryBeacon << 8 ); + tmp129__ |= ( pSrc->lsigTXOPProtectionFullSupport << 9 ); + tmp129__ |= ( pSrc->pcoActive << 10 ); + tmp129__ |= ( pSrc->pcoPhase << 11 ); + tmp129__ |= ( pSrc->reserved2 << 12 ); + frameshtons(pCtx, pBuf, tmp129__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->basicMCSSet, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rsvd ), pSrc->num_rsvd); + *pnConsumed += pSrc->num_rsvd; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHTInfo. */ + +tANI_U32 dot11fPackIeIBSSParams(tpAniSirGlobal pCtx, + tDot11fIEIBSSParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 6; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->atim, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeIBSSParams. */ + +tANI_U32 dot11fPackIeLinkIdentifier(tpAniSirGlobal pCtx, + tDot11fIELinkIdentifier *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 101; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->InitStaAddr, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RespStaAddr, 6); + *pnConsumed += 6; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLinkIdentifier. */ + +tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx, + tDot11fIEMeasurementReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp130__; + tANI_U8 tmp131__; + tANI_U8 tmp132__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEMeasurementReport(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 39; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->token; + *pnConsumed += 1; + pBuf += 1; + tmp130__ = 0U; + tmp130__ |= ( pSrc->late << 0 ); + tmp130__ |= ( pSrc->incapable << 1 ); + tmp130__ |= ( pSrc->refused << 2 ); + tmp130__ |= ( pSrc->unused << 3 ); + *pBuf = tmp130__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->type; + *pnConsumed += 1; + pBuf += 1; + if ( pSrc->type ) { + switch (pSrc->type) + { + case 0: + *pBuf = pSrc->report.Basic.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.Basic.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + tmp131__ = 0U; + tmp131__ |= ( pSrc->report.Basic.bss << 0 ); + tmp131__ |= ( pSrc->report.Basic.ofdm_preamble << 1 ); + tmp131__ |= ( pSrc->report.Basic.unid_signal << 2 ); + tmp131__ |= ( pSrc->report.Basic.rader << 3 ); + tmp131__ |= ( pSrc->report.Basic.unmeasured << 4 ); + tmp131__ |= ( pSrc->report.Basic.unused << 5 ); + *pBuf = tmp131__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + case 1: + *pBuf = pSrc->report.CCA.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.CCA.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.CCA.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->report.CCA.cca_busy_fraction; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 2: + *pBuf = pSrc->report.RPIHistogram.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.RPIHistogram.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.RPIHistogram.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->report.RPIHistogram.rpi0_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi1_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi2_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi3_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi4_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi5_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi6_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi7_density; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 5: + *pBuf = pSrc->report.Beacon.regClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.Beacon.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.Beacon.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + tmp132__ = 0U; + tmp132__ |= ( pSrc->report.Beacon.condensed_PHY << 0 ); + tmp132__ |= ( pSrc->report.Beacon.reported_frame_type << 7 ); + *pBuf = tmp132__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->report.Beacon.RCPI; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.Beacon.RSNI; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->report.Beacon.BSSID, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->report.Beacon.antenna_id; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->report.Beacon.parent_TSF, 0); + *pnConsumed += 4; + pBuf += 4; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_reportBeacon, + IES_reportBeacon); + break; + } + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeMeasurementReport. */ + +tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal pCtx, + tDot11fIEMeasurementRequest *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp133__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEMeasurementRequest(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 38; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->measurement_token; + *pnConsumed += 1; + pBuf += 1; + tmp133__ = 0U; + tmp133__ |= ( pSrc->parallel << 0 ); + tmp133__ |= ( pSrc->enable << 1 ); + tmp133__ |= ( pSrc->request << 2 ); + tmp133__ |= ( pSrc->report << 3 ); + tmp133__ |= ( pSrc->durationMandatory << 4 ); + tmp133__ |= ( pSrc->unused << 5 ); + *pBuf = tmp133__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->measurement_type; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->measurement_type) + { + case 0: + *pBuf = pSrc->measurement_request.Basic.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Basic.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Basic.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->measurement_request.CCA.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.CCA.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.CCA.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 2: + *pBuf = pSrc->measurement_request.RPIHistogram.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 5: + *pBuf = pSrc->measurement_request.Beacon.regClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->measurement_request.Beacon.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.randomization, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->measurement_request.Beacon.meas_mode; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Beacon.BSSID, 6); + *pnConsumed += 6; + pBuf += 6; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_measurement_requestBeacon, + IES_measurement_requestBeacon); + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeMeasurementRequest. */ + +tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal pCtx, + tDot11fIEMobilityDomain *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp134__; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 54; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->MDID, 0); + *pnConsumed += 2; + pBuf += 2; + tmp134__ = 0U; + tmp134__ |= ( pSrc->overDSCap << 0 ); + tmp134__ |= ( pSrc->resourceReqCap << 1 ); + tmp134__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp134__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMobilityDomain. */ + +tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx, + tDot11fIENeighborReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp135__; + tANI_U8 tmp136__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIENeighborReport(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 52; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + tmp135__ = 0U; + tmp135__ |= ( pSrc->APReachability << 0 ); + tmp135__ |= ( pSrc->Security << 2 ); + tmp135__ |= ( pSrc->KeyScope << 3 ); + tmp135__ |= ( pSrc->SpecMgmtCap << 4 ); + tmp135__ |= ( pSrc->QosCap << 5 ); + tmp135__ |= ( pSrc->apsd << 6 ); + tmp135__ |= ( pSrc->rrm << 7 ); + *pBuf = tmp135__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp136__ = 0U; + tmp136__ |= ( pSrc->DelayedBA << 0 ); + tmp136__ |= ( pSrc->ImmBA << 1 ); + tmp136__ |= ( pSrc->MobilityDomain << 2 ); + tmp136__ |= ( pSrc->reserved << 3 ); + *pBuf = tmp136__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->reserved1, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->PhyType; + *pnConsumed += 1; + pBuf += 1; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_NeighborReport, + IES_NeighborReport); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeNeighborReport. */ + +tANI_U32 dot11fPackIeOBSSScanParameters(tpAniSirGlobal pCtx, + tDot11fIEOBSSScanParameters *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 14; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 74; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->obssScanPassiveDwell, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActiveDwell, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->bssChannelWidthTriggerScanInterval, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanPassiveTotalPerChannel, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActiveTotalPerChannel, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->bssWidthChannelTransitionDelayFactor, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActivityThreshold, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeOBSSScanParameters. */ + +tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal pCtx, + tDot11fIEOperatingMode *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp137__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 199; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp137__ = 0U; + tmp137__ |= ( pSrc->chanWidth << 0 ); + tmp137__ |= ( pSrc->reserved << 2 ); + tmp137__ |= ( pSrc->rxNSS << 4 ); + tmp137__ |= ( pSrc->rxNSSType << 7 ); + *pBuf = tmp137__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeOperatingMode. */ + +tANI_U32 dot11fPackIeP2PAssocReq(tpAniSirGlobal pCtx, + tDot11fIEP2PAssocReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PAssocReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PAssocReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PAssocReq. */ + +tANI_U32 dot11fPackIeP2PAssocRes(tpAniSirGlobal pCtx, + tDot11fIEP2PAssocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PAssocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PAssocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PAssocRes. */ + +tANI_U32 dot11fPackIeP2PBeacon(tpAniSirGlobal pCtx, + tDot11fIEP2PBeacon *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PBeacon(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PBeacon+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PBeacon. */ + +tANI_U32 dot11fPackIeP2PBeaconProbeRes(tpAniSirGlobal pCtx, + tDot11fIEP2PBeaconProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PBeaconProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PBeaconProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PBeaconProbeRes. */ + +tANI_U32 dot11fPackIeP2PDeAuth(tpAniSirGlobal pCtx, + tDot11fIEP2PDeAuth *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeAuth(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeAuth+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeAuth. */ + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, + tDot11fIEP2PDeviceDiscoverabilityReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeviceDiscoverabilityReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeviceDiscoverabilityReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, + tDot11fIEP2PDeviceDiscoverabilityRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeviceDiscoverabilityRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeviceDiscoverabilityRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fPackIeP2PDisAssoc(tpAniSirGlobal pCtx, + tDot11fIEP2PDisAssoc *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDisAssoc(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDisAssoc+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDisAssoc. */ + +tANI_U32 dot11fPackIeP2PGONegCnf(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegCnf *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegCnf(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegCnf+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegCnf. */ + +tANI_U32 dot11fPackIeP2PGONegReq(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegReq. */ + +tANI_U32 dot11fPackIeP2PGONegRes(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegRes. */ + +tANI_U32 dot11fPackIeP2PGONegWPS(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegWPS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegWPS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegWPS+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegWPS. */ + +tANI_U32 dot11fPackIeP2PIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEP2PIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeP2PIEOpaque. */ + +tANI_U32 dot11fPackIeP2PInvitationReq(tpAniSirGlobal pCtx, + tDot11fIEP2PInvitationReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PInvitationReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PInvitationReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PInvitationReq. */ + +tANI_U32 dot11fPackIeP2PInvitationRes(tpAniSirGlobal pCtx, + tDot11fIEP2PInvitationRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PInvitationRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PInvitationRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PInvitationRes. */ + +tANI_U32 dot11fPackIeP2PNoticeOfAbsence(tpAniSirGlobal pCtx, + tDot11fIEP2PNoticeOfAbsence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PNoticeOfAbsence(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PNoticeOfAbsence+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PNoticeOfAbsence. */ + +tANI_U32 dot11fPackIeP2PPresenceResponse(tpAniSirGlobal pCtx, + tDot11fIEP2PPresenceResponse *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PPresenceResponse(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PPresenceResponse+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PPresenceResponse. */ + +tANI_U32 dot11fPackIeP2PProbeReq(tpAniSirGlobal pCtx, + tDot11fIEP2PProbeReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProbeReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProbeReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProbeReq. */ + +tANI_U32 dot11fPackIeP2PProbeRes(tpAniSirGlobal pCtx, + tDot11fIEP2PProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProbeRes. */ + +tANI_U32 dot11fPackIeP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, + tDot11fIEP2PProvisionDiscoveryReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProvisionDiscoveryReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProvisionDiscoveryReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProvisionDiscoveryReq. */ + +tANI_U32 dot11fPackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, + tDot11fIEP2PWSCProvisionDiscoveryRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PWSCProvisionDiscoveryRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PWSCProvisionDiscoveryRes. */ + +tANI_U32 dot11fPackIePTIControl(tpAniSirGlobal pCtx, + tDot11fIEPTIControl *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 105; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tid; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->sequence_control, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePTIControl. */ + +tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal pCtx, + tDot11fIEPUBufferStatus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp138__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 106; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp138__ = 0U; + tmp138__ |= ( pSrc->ac_bk_traffic_aval << 0 ); + tmp138__ |= ( pSrc->ac_be_traffic_aval << 1 ); + tmp138__ |= ( pSrc->ac_vi_traffic_aval << 2 ); + tmp138__ |= ( pSrc->ac_vo_traffic_aval << 3 ); + tmp138__ |= ( pSrc->reserved << 4 ); + *pBuf = tmp138__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePUBufferStatus. */ + +tANI_U32 dot11fPackIePowerCaps(tpAniSirGlobal pCtx, + tDot11fIEPowerCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 33; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->minTxPower; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->maxTxPower; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePowerCaps. */ + +tANI_U32 dot11fPackIePowerConstraints(tpAniSirGlobal pCtx, + tDot11fIEPowerConstraints *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 32; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->localPowerConstraints; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePowerConstraints. */ + +tANI_U32 dot11fPackIeQBSSLoad(tpAniSirGlobal pCtx, + tDot11fIEQBSSLoad *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 11; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->stacount, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->chautil; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->avail, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQBSSLoad. */ + +tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal pCtx, + tDot11fIEQOSCapsAp *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp139__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 46; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp139__ = 0U; + tmp139__ |= ( pSrc->count << 0 ); + tmp139__ |= ( pSrc->qack << 4 ); + tmp139__ |= ( pSrc->qreq << 5 ); + tmp139__ |= ( pSrc->txopreq << 6 ); + tmp139__ |= ( pSrc->reserved << 7 ); + *pBuf = tmp139__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQOSCapsAp. */ + +tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal pCtx, + tDot11fIEQOSCapsStation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp140__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 46; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp140__ = 0U; + tmp140__ |= ( pSrc->acvo_uapsd << 0 ); + tmp140__ |= ( pSrc->acvi_uapsd << 1 ); + tmp140__ |= ( pSrc->acbk_uapsd << 2 ); + tmp140__ |= ( pSrc->acbe_uapsd << 3 ); + tmp140__ |= ( pSrc->qack << 4 ); + tmp140__ |= ( pSrc->max_sp_length << 5 ); + tmp140__ |= ( pSrc->more_data_ack << 7 ); + *pBuf = tmp140__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQOSCapsStation. */ + +tANI_U32 dot11fPackIeQosMapSet(tpAniSirGlobal pCtx, + tDot11fIEQosMapSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_dscp_exceptions; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 110; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->dscp_exceptions ), pSrc->num_dscp_exceptions); + *pnConsumed += pSrc->num_dscp_exceptions; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQosMapSet. */ + +tANI_U32 dot11fPackIeQuiet(tpAniSirGlobal pCtx, + tDot11fIEQuiet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 40; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->duration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->offset, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQuiet. */ + +tANI_U32 dot11fPackIeRCPIIE(tpAniSirGlobal pCtx, + tDot11fIERCPIIE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 53; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->rcpi; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRCPIIE. */ + +tANI_U32 dot11fPackIeRICDataDesc(tpAniSirGlobal pCtx, + tDot11fIERICDataDesc *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIERICDataDesc(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_RICDataDesc, + IES_RICDataDesc); + break; + } + (void)pCtx; + return status; +} /* End dot11fPackIeRICDataDesc. */ + +tANI_U32 dot11fPackIeRSN(tpAniSirGlobal pCtx, + tDot11fIERSN *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIERSN(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 48; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_cipher_suite, 4); + *pnConsumed += 4; + pBuf += 4; + if ( pSrc->pwise_cipher_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->pwise_cipher_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->pwise_cipher_suites ), ( pSrc->pwise_cipher_suite_count * 4 )); + *pnConsumed += ( pSrc->pwise_cipher_suite_count * 4 ); + pBuf += ( pSrc->pwise_cipher_suite_count * 4 ); + if ( pSrc->akm_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->akm_suites ), ( pSrc->akm_suite_count * 4 )); + *pnConsumed += ( pSrc->akm_suite_count * 4 ); + pBuf += ( pSrc->akm_suite_count * 4 ); + if ( pSrc->RSN_Cap ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2); + *pnConsumed += 2; + pBuf += 2; + } + else break; + if ( pSrc->pmkid_count ) { + frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->pmkid ), ( pSrc->pmkid_count * 16 )); + *pnConsumed += ( pSrc->pmkid_count * 16 ); + pBuf += ( pSrc->pmkid_count * 16 ); + if ( pSrc->gp_mgmt_cipher_suite ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_mgmt_cipher_suite, 4); + *pnConsumed += 4; + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeRSN. */ + +tANI_U32 dot11fPackIeRSNIIE(tpAniSirGlobal pCtx, + tDot11fIERSNIIE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 65; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->rsni; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRSNIIE. */ + +tANI_U32 dot11fPackIeRSNOpaque(tpAniSirGlobal pCtx, + tDot11fIERSNOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 48; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRSNOpaque. */ + +tANI_U32 dot11fPackIeSuppChannels(tpAniSirGlobal pCtx, + tDot11fIESuppChannels *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_bands * 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 36; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bands ), ( pSrc->num_bands * 2 )); + *pnConsumed += ( pSrc->num_bands * 2 ); + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppChannels. */ + +tANI_U32 dot11fPackIeSuppOperatingClasses(tpAniSirGlobal pCtx, + tDot11fIESuppOperatingClasses *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_classes; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 59; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->classes ), pSrc->num_classes); + *pnConsumed += pSrc->num_classes; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppOperatingClasses. */ + +tANI_U32 dot11fPackIeSuppRates(tpAniSirGlobal pCtx, + tDot11fIESuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppRates. */ + +tANI_U32 dot11fPackIeTIM(tpAniSirGlobal pCtx, + tDot11fIETIM *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vbmp + 3); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 5; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->dtim_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->dtim_period; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->bmpctl; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vbmp ), pSrc->num_vbmp); + *pnConsumed += pSrc->num_vbmp; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTIM. */ + +tANI_U32 dot11fPackIeTPCReport(tpAniSirGlobal pCtx, + tDot11fIETPCReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 35; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tx_power; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->link_margin; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTPCReport. */ + +tANI_U32 dot11fPackIeTPCRequest(tpAniSirGlobal pCtx, + tDot11fIETPCRequest *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 0; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 34; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTPCRequest. */ + +tANI_U32 dot11fPackIeTimeoutInterval(tpAniSirGlobal pCtx, + tDot11fIETimeoutInterval *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 56; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->timeoutType; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->timeoutValue, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTimeoutInterval. */ + +tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx, + tDot11fIEVHTCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 tmp141__; + tANI_U16 tmp142__; + tANI_U16 tmp143__; + nNeeded += 12; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 191; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp141__ = 0U; + tmp141__ |= ( pSrc->maxMPDULen << 0 ); + tmp141__ |= ( pSrc->supportedChannelWidthSet << 2 ); + tmp141__ |= ( pSrc->ldpcCodingCap << 4 ); + tmp141__ |= ( pSrc->shortGI80MHz << 5 ); + tmp141__ |= ( pSrc->shortGI160and80plus80MHz << 6 ); + tmp141__ |= ( pSrc->txSTBC << 7 ); + tmp141__ |= ( pSrc->rxSTBC << 8 ); + tmp141__ |= ( pSrc->suBeamFormerCap << 11 ); + tmp141__ |= ( pSrc->suBeamformeeCap << 12 ); + tmp141__ |= ( pSrc->csnofBeamformerAntSup << 13 ); + tmp141__ |= ( pSrc->numSoundingDim << 16 ); + tmp141__ |= ( pSrc->muBeamformerCap << 19 ); + tmp141__ |= ( pSrc->muBeamformeeCap << 20 ); + tmp141__ |= ( pSrc->vhtTXOPPS << 21 ); + tmp141__ |= ( pSrc->htcVHTCap << 22 ); + tmp141__ |= ( pSrc->maxAMPDULenExp << 23 ); + tmp141__ |= ( pSrc->vhtLinkAdaptCap << 26 ); + tmp141__ |= ( pSrc->rxAntPattern << 28 ); + tmp141__ |= ( pSrc->txAntPattern << 29 ); + tmp141__ |= ( pSrc->reserved1 << 30 ); + frameshtonl(pCtx, pBuf, tmp141__, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4 ; + frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0); + *pnConsumed += 2; + pBuf += 2; + tmp142__ = 0U; + tmp142__ |= ( pSrc->rxHighSupDataRate << 0 ); + tmp142__ |= ( pSrc->reserved2 << 13 ); + frameshtons(pCtx, pBuf, tmp142__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0); + *pnConsumed += 2; + pBuf += 2; + tmp143__ = 0U; + tmp143__ |= ( pSrc->txSupDataRate << 0 ); + tmp143__ |= ( pSrc->reserved3 << 13 ); + frameshtons(pCtx, pBuf, tmp143__, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + nBuf -= 2 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTCaps. */ + +tANI_U32 dot11fPackIeVHTExtBssLoad(tpAniSirGlobal pCtx, + tDot11fIEVHTExtBssLoad *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 193; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->muMIMOCapStaCount; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->ssUnderUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->FortyMHzUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->EightyMHzUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->OneSixtyMHzUtil; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTExtBssLoad. */ + +tANI_U32 dot11fPackIeVHTOperation(tpAniSirGlobal pCtx, + tDot11fIEVHTOperation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 192; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->chanWidth; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->chanCenterFreqSeg1; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->chanCenterFreqSeg2; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTOperation. */ + +tANI_U32 dot11fPackIeVendor1IE(tpAniSirGlobal pCtx, + tDot11fIEVendor1IE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 0; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x10; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x18; + ++pBuf; ++(*pnConsumed); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVendor1IE. */ + +tANI_U32 dot11fPackIeVendor2IE(tpAniSirGlobal pCtx, + tDot11fIEVendor2IE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 0; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x90; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x4c; + ++pBuf; ++(*pnConsumed); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVendor2IE. */ + +tANI_U32 dot11fPackIeVendor3IE(tpAniSirGlobal pCtx, + tDot11fIEVendor3IE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 0; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x16; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x32; + ++pBuf; ++(*pnConsumed); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVendor3IE. */ + +tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal pCtx, + tDot11fIEWAPI *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp144__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWAPI(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 68; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->akm_suites ), ( pSrc->akm_suite_count * 4 )); + *pnConsumed += ( pSrc->akm_suite_count * 4 ); + pBuf += ( pSrc->akm_suite_count * 4 ); + frameshtons(pCtx, pBuf, pSrc->unicast_cipher_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->unicast_cipher_suites ), ( pSrc->unicast_cipher_suite_count * 4 )); + *pnConsumed += ( pSrc->unicast_cipher_suite_count * 4 ); + pBuf += ( pSrc->unicast_cipher_suite_count * 4 ); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4); + *pnConsumed += 4; + pBuf += 4; + tmp144__ = 0U; + tmp144__ |= ( pSrc->preauth << 0 ); + tmp144__ |= ( pSrc->reserved << 1 ); + frameshtons(pCtx, pBuf, tmp144__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + if ( pSrc->bkid_count ) { + frameshtons(pCtx, pBuf, pSrc->bkid_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bkid ), ( pSrc->bkid_count * 16 )); + *pnConsumed += ( pSrc->bkid_count * 16 ); + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWAPI. */ + +tANI_U32 dot11fPackIeWAPIOpaque(tpAniSirGlobal pCtx, + tDot11fIEWAPIOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 68; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWAPIOpaque. */ + +tANI_U32 dot11fPackIeWFATPC(tpAniSirGlobal pCtx, + tDot11fIEWFATPC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->txPower; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->linkMargin; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWFATPC. */ + +tANI_U32 dot11fPackIeWFDIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEWFDIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xa; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWFDIEOpaque. */ + +tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal pCtx, + tDot11fIEWMMCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp145__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x5; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp145__ = 0U; + tmp145__ |= ( pSrc->reserved << 0 ); + tmp145__ |= ( pSrc->qack << 4 ); + tmp145__ |= ( pSrc->queue_request << 5 ); + tmp145__ |= ( pSrc->txop_request << 6 ); + tmp145__ |= ( pSrc->more_ack << 7 ); + *pBuf = tmp145__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMCaps. */ + +tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal pCtx, + tDot11fIEWMMInfoAp *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp146__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp146__ = 0U; + tmp146__ |= ( pSrc->param_set_count << 0 ); + tmp146__ |= ( pSrc->reserved << 4 ); + tmp146__ |= ( pSrc->uapsd << 7 ); + *pBuf = tmp146__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMInfoAp. */ + +tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal pCtx, + tDot11fIEWMMInfoStation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp147__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp147__ = 0U; + tmp147__ |= ( pSrc->acvo_uapsd << 0 ); + tmp147__ |= ( pSrc->acvi_uapsd << 1 ); + tmp147__ |= ( pSrc->acbk_uapsd << 2 ); + tmp147__ |= ( pSrc->acbe_uapsd << 3 ); + tmp147__ |= ( pSrc->reserved1 << 4 ); + tmp147__ |= ( pSrc->max_sp_length << 5 ); + tmp147__ |= ( pSrc->reserved2 << 7 ); + *pBuf = tmp147__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMInfoStation. */ + +tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, + tDot11fIEWMMParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp148__; + tANI_U8 tmp149__; + tANI_U8 tmp150__; + tANI_U8 tmp151__; + tANI_U8 tmp152__; + tANI_U8 tmp153__; + tANI_U8 tmp154__; + tANI_U8 tmp155__; + nNeeded += 19; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->qosInfo; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved2; + *pnConsumed += 1; + pBuf += 1; + tmp148__ = 0U; + tmp148__ |= ( pSrc->acbe_aifsn << 0 ); + tmp148__ |= ( pSrc->acbe_acm << 4 ); + tmp148__ |= ( pSrc->acbe_aci << 5 ); + tmp148__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp148__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp149__ = 0U; + tmp149__ |= ( pSrc->acbe_acwmin << 0 ); + tmp149__ |= ( pSrc->acbe_acwmax << 4 ); + *pBuf = tmp149__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp150__ = 0U; + tmp150__ |= ( pSrc->acbk_aifsn << 0 ); + tmp150__ |= ( pSrc->acbk_acm << 4 ); + tmp150__ |= ( pSrc->acbk_aci << 5 ); + tmp150__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp150__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp151__ = 0U; + tmp151__ |= ( pSrc->acbk_acwmin << 0 ); + tmp151__ |= ( pSrc->acbk_acwmax << 4 ); + *pBuf = tmp151__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp152__ = 0U; + tmp152__ |= ( pSrc->acvi_aifsn << 0 ); + tmp152__ |= ( pSrc->acvi_acm << 4 ); + tmp152__ |= ( pSrc->acvi_aci << 5 ); + tmp152__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp152__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp153__ = 0U; + tmp153__ |= ( pSrc->acvi_acwmin << 0 ); + tmp153__ |= ( pSrc->acvi_acwmax << 4 ); + *pBuf = tmp153__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp154__ = 0U; + tmp154__ |= ( pSrc->acvo_aifsn << 0 ); + tmp154__ |= ( pSrc->acvo_acm << 4 ); + tmp154__ |= ( pSrc->acvo_aci << 5 ); + tmp154__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp154__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp155__ = 0U; + tmp155__ |= ( pSrc->acvo_acwmin << 0 ); + tmp155__ |= ( pSrc->acvo_acwmax << 4 ); + *pBuf = tmp155__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMParams. */ + +tANI_U32 dot11fPackIeWPA(tpAniSirGlobal pCtx, + tDot11fIEWPA *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWPA(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + if ( pSrc->multicast_cipher_present ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher, 4); + *pnConsumed += 4; + pBuf += 4; + } + else break; + if ( pSrc->unicast_cipher_count ) { + frameshtons(pCtx, pBuf, pSrc->unicast_cipher_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->unicast_ciphers ), ( pSrc->unicast_cipher_count * 4 )); + *pnConsumed += ( pSrc->unicast_cipher_count * 4 ); + pBuf += ( pSrc->unicast_cipher_count * 4 ); + if ( pSrc->auth_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->auth_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->auth_suites ), ( pSrc->auth_suite_count * 4 )); + *pnConsumed += ( pSrc->auth_suite_count * 4 ); + pBuf += ( pSrc->auth_suite_count * 4 ); + if ( pSrc->caps ) { + frameshtons(pCtx, pBuf, pSrc->caps, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWPA. */ + +tANI_U32 dot11fPackIeWPAOpaque(tpAniSirGlobal pCtx, + tDot11fIEWPAOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWPAOpaque. */ + +tANI_U32 dot11fPackIeWSC(tpAniSirGlobal pCtx, + tDot11fIEWSC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWSC(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WSC+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWSC. */ + +tANI_U32 dot11fPackIeWscAssocReq(tpAniSirGlobal pCtx, + tDot11fIEWscAssocReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscAssocReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscAssocReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscAssocReq. */ + +tANI_U32 dot11fPackIeWscAssocRes(tpAniSirGlobal pCtx, + tDot11fIEWscAssocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscAssocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscAssocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscAssocRes. */ + +tANI_U32 dot11fPackIeWscBeacon(tpAniSirGlobal pCtx, + tDot11fIEWscBeacon *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscBeacon(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscBeacon+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscBeacon. */ + +tANI_U32 dot11fPackIeWscBeaconProbeRes(tpAniSirGlobal pCtx, + tDot11fIEWscBeaconProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscBeaconProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscBeaconProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscBeaconProbeRes. */ + +tANI_U32 dot11fPackIeWscIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEWscIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWscIEOpaque. */ + +tANI_U32 dot11fPackIeWscProbeReq(tpAniSirGlobal pCtx, + tDot11fIEWscProbeReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscProbeReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscProbeReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscProbeReq. */ + +tANI_U32 dot11fPackIeWscProbeRes(tpAniSirGlobal pCtx, + tDot11fIEWscProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscProbeRes. */ + +tANI_U32 dot11fPackIeWscReassocRes(tpAniSirGlobal pCtx, + tDot11fIEWscReassocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscReassocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscReassocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscReassocRes. */ + +tANI_U32 dot11fPackAddBAReq(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddBAReq, IES_AddBAReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Packed the AddBAReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BAStartingSequenceControl:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("fragNumber (4): %d\n"), pFrm->BAStartingSequenceControl.fragNumber); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("ssn (12): %d\n"), pFrm->BAStartingSequenceControl.ssn); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBAReq. */ + +tANI_U32 dot11fPackAddBARsp(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddBARsp, IES_AddBARsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Packed the AddBARsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBARsp. */ + +tANI_U32 dot11fPackAddTSRequest(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddTSRequest, IES_AddTSRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Packed the AddTSRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSRequest. */ + +tANI_U32 dot11fPackAddTSResponse(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddTSResponse, IES_AddTSResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Packed the AddTSResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSResponse. */ + +tANI_U32 dot11fPackAssocRequest(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AssocRequest, IES_AssocRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Packed the AssocRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocRequest. */ + +tANI_U32 dot11fPackAssocResponse(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AssocResponse, IES_AssocResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Packed the AssocResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WscAssocRes:\n")); + if (!pFrm->WscAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscAssocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscAssocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscAssocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscAssocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscAssocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocResponse. */ + +tANI_U32 dot11fPackAuthentication(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Authentication, IES_Authentication); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Packed the Authentication:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthAlgo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthAlgo.algo, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthSeqNo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthSeqNo.no, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("ChallengeText:\n")); + if (!pFrm->ChallengeText.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_text: %d.\n"), pFrm->ChallengeText.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->ChallengeText.text, pFrm->ChallengeText.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAuthentication. */ + +tANI_U32 dot11fPackBeacon(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon, IES_Beacon); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Packed the Beacon:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon. */ + +tANI_U32 dot11fPackBeacon1(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon1, IES_Beacon1); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Packed the Beacon1:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon1. */ + +tANI_U32 dot11fPackBeacon2(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon2, IES_Beacon2); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Packed the Beacon2:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon2. */ + +tANI_U32 dot11fPackBeaconIEs(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_BeaconIEs, IES_BeaconIEs); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Packed the BeaconIEs:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WscBeaconProbeRes:\n")); + if (!pFrm->WscBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->WscBeaconProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPSState:\n")); + if (!pFrm->WscBeaconProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeaconProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeaconProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ResponseType:\n")); + if (!pFrm->WscBeaconProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("UUID_E:\n")); + if (!pFrm->WscBeaconProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Manufacturer:\n")); + if (!pFrm->WscBeaconProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->WscBeaconProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.Manufacturer.name, pFrm->WscBeaconProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelName:\n")); + if (!pFrm->WscBeaconProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelName.text, pFrm->WscBeaconProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelNumber:\n")); + if (!pFrm->WscBeaconProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelNumber.text, pFrm->WscBeaconProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SerialNumber:\n")); + if (!pFrm->WscBeaconProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.SerialNumber.text, pFrm->WscBeaconProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscBeaconProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->WscBeaconProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.DeviceName.text, pFrm->WscBeaconProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RFBands:\n")); + if (!pFrm->WscBeaconProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version2:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PBeaconProbeRes:\n")); + if (!pFrm->P2PBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PBeaconProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeaconProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeaconIEs. */ + +tANI_U32 dot11fPackChannelSwitch(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ChannelSwitch, IES_ChannelSwitch); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Packed the ChannelSwitch:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackChannelSwitch. */ + +tANI_U32 dot11fPackDeAuth(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeAuth, IES_DeAuth); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Packed the DeAuth:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("P2PDeAuth:\n")); + if (!pFrm->P2PDeAuth.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDeAuth.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->P2PDeAuth.MinorReasonCode.minorReasonCode, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeAuth. */ + +tANI_U32 dot11fPackDelBAInd(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DelBAInd, IES_DelBAInd); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Packed the DelBAInd:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("DelBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("reserved (11): %d\n"), pFrm->DelBAParameterSet.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("initiator (1): %d\n"), pFrm->DelBAParameterSet.initiator); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("tid (4): %d\n"), pFrm->DelBAParameterSet.tid); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelBAInd. */ + +tANI_U32 dot11fPackDelTS(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DelTS, IES_DelTS); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Packed the DelTS:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("TSInfo:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("traffic_type (1): %d\n"), pFrm->TSInfo.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsid (4): %d\n"), pFrm->TSInfo.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("direction (2): %d\n"), pFrm->TSInfo.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("access_policy (2): %d\n"), pFrm->TSInfo.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("aggregation (1): %d\n"), pFrm->TSInfo.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("psb (1): %d\n"), pFrm->TSInfo.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("user_priority (3): %d\n"), pFrm->TSInfo.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSInfo.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("schedule (1): %d\n"), pFrm->TSInfo.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("unused (15): %d\n"), pFrm->TSInfo.unused); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelTS. */ + +tANI_U32 dot11fPackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeviceDiscoverabilityReq, IES_DeviceDiscoverabilityReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Packed the DeviceDiscoverabilityReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceDiscoverabilityReq:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* ) pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.ssid, pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fPackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeviceDiscoverabilityRes, IES_DeviceDiscoverabilityRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Packed the DeviceDiscoverabilityRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PDeviceDiscoverabilityRes:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.status, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fPackDisassociation(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Disassociation, IES_Disassociation); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Packed the Disassociation:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("P2PDisAssoc:\n")); + if (!pFrm->P2PDisAssoc.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDisAssoc.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->P2PDisAssoc.MinorReasonCode.minorReasonCode, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDisassociation. */ + +tANI_U32 dot11fPackGODiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GODiscoverabilityReq, IES_GODiscoverabilityReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Packed the GODiscoverabilityReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGODiscoverabilityReq. */ + +tANI_U32 dot11fPackGONegCnf(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegCnf, IES_GONegCnf); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Packed the GONegCnf:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGONegCnf:\n")); + if (!pFrm->P2PGONegCnf.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegCnf.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegCnf.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegCnf.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegCnf.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegCnf.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.ChannelList.channelList, pFrm->P2PGONegCnf.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegCnf.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.P2PGroupId.ssid, pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegCnf. */ + +tANI_U32 dot11fPackGONegReq(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegReq, IES_GONegReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Packed the GONegReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegReq:\n")); + if (!pFrm->P2PGONegReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegReq.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ListenChannel:\n")); + if (!pFrm->P2PGONegReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PGONegReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.ChannelList.channelList, pFrm->P2PGONegReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_text: %d.\n"), pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegReq. */ + +tANI_U32 dot11fPackGONegRes(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegRes, IES_GONegRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Packed the GONegRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegRes:\n")); + if (!pFrm->P2PGONegRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegRes.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.ChannelList.channelList, pFrm->P2PGONegRes.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_text: %d.\n"), pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegRes.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegRes.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PGroupId.ssid, pFrm->P2PGONegRes.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegRes. */ + +tANI_U32 dot11fPackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_HT2040BSSCoexistenceManagementActionFrame, IES_HT2040BSSCoexistenceManagementActionFrame); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Packed the HT2040BSSCoexistenceManagementActionFrame:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSIntolerantReport:\n")); + if (!pFrm->HT2040BSSIntolerantReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->HT2040BSSIntolerantReport.operatingClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("num_channelList: %d.\n"), pFrm->HT2040BSSIntolerantReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* ) pFrm->HT2040BSSIntolerantReport.channelList, pFrm->HT2040BSSIntolerantReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackHT2040BSSCoexistenceManagementActionFrame. */ + +tANI_U32 dot11fPackInvitationReq(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_InvitationReq, IES_InvitationReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Packed the InvitationReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PInvitationReq:\n")); + if (!pFrm->P2PInvitationReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("InvitationFlags:\n")); + if (!pFrm->P2PInvitationReq.InvitationFlags.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.InvitationFlags.invitationFlags, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.ChannelList.channelList, pFrm->P2PInvitationReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PGroupId.ssid, pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_text: %d.\n"), pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationReq. */ + +tANI_U32 dot11fPackInvitationRes(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_InvitationRes, IES_InvitationRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Packed the InvitationRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PInvitationRes:\n")); + if (!pFrm->P2PInvitationRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PInvitationRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationRes.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* ) pFrm->P2PInvitationRes.ChannelList.channelList, pFrm->P2PInvitationRes.ChannelList.num_channelList); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationRes. */ + +tANI_U32 dot11fPackLinkMeasurementReport(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_LinkMeasurementReport, IES_LinkMeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Packed the LinkMeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleID.TPCId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleLen:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleLen.TPCLen, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("LinkMargin:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->LinkMargin.linkMargin, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RCPI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RCPI.rcpi, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RSNI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RSNI.rsni, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementReport. */ + +tANI_U32 dot11fPackLinkMeasurementRequest(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Packed the LinkMeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("MaxTxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MaxTxPower.maxTxPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementRequest. */ + +tANI_U32 dot11fPackMeasurementReport(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_MeasurementReport, IES_MeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Packed the MeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("MeasurementReport:\n")); + if (!pFrm->MeasurementReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport.late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport.incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport.refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport.unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.type, 1); + switch (pFrm->MeasurementReport.type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport.report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport.report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport.report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport.report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport.report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport.report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport.report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport.report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.parent_TSF, 4); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementReport. */ + +tANI_U32 dot11fPackMeasurementRequest(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_MeasurementRequest, IES_MeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Packed the MeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementRequest. */ + +tANI_U32 dot11fPackNeighborReportRequest(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NeighborReportRequest, IES_NeighborReportRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Packed the NeighborReportRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportRequest. */ + +tANI_U32 dot11fPackNeighborReportResponse(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NeighborReportResponse, IES_NeighborReportResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Packed the NeighborReportResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_NeighborReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborReport[%d]:\n"), i); + if (!pFrm->NeighborReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].bssid, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APReachability (2): %d\n"), pFrm->NeighborReport[i].APReachability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Security (1): %d\n"), pFrm->NeighborReport[i].Security); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("KeyScope (1): %d\n"), pFrm->NeighborReport[i].KeyScope); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("SpecMgmtCap (1): %d\n"), pFrm->NeighborReport[i].SpecMgmtCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("QosCap (1): %d\n"), pFrm->NeighborReport[i].QosCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("apsd (1): %d\n"), pFrm->NeighborReport[i].apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("rrm (1): %d\n"), pFrm->NeighborReport[i].rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DelayedBA (1): %d\n"), pFrm->NeighborReport[i].DelayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ImmBA (1): %d\n"), pFrm->NeighborReport[i].ImmBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MobilityDomain (1): %d\n"), pFrm->NeighborReport[i].MobilityDomain); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (5): %d\n"), pFrm->NeighborReport[i].reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].reserved1, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].PhyType, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TSFInfo:\n")); + if (!pFrm->NeighborReport[i].TSFInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.TsfOffset, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.BeaconIntvl, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("CondensedCountryStr:\n")); + if (!pFrm->NeighborReport[i].CondensedCountryStr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].CondensedCountryStr.countryStr, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot:\n")); + if (!pFrm->NeighborReport[i].MeasurementPilot.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MeasurementPilot.measurementPilot, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MeasurementPilot.vendorSpecific, pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->NeighborReport[i].RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("parallel (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("repeated (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("statistics (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (6): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MultiBssid:\n")); + if (!pFrm->NeighborReport[i].MultiBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MultiBssid.maxBSSIDIndicator, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MultiBssid.vendorSpecific, pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportResponse. */ + +tANI_U32 dot11fPackNoticeOfAbs(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NoticeOfAbs, IES_NoticeOfAbs); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Packed the NoticeOfAbs:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNoticeOfAbs. */ + +tANI_U32 dot11fPackOperatingMode(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_OperatingMode, IES_OperatingMode); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Packed the OperatingMode:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("OperatingMode:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackOperatingMode. */ + +tANI_U32 dot11fPackPresenceReq(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_PresenceReq, IES_PresenceReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Packed the PresenceReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceReq. */ + +tANI_U32 dot11fPackPresenceRes(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_PresenceRes, IES_PresenceRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Packed the PresenceRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PPresenceResponse:\n")); + if (!pFrm->P2PPresenceResponse.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PPresenceResponse.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PPresenceResponse.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* ) pFrm->P2PPresenceResponse.NoticeOfAbsence.NoADesc, pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceRes. */ + +tANI_U32 dot11fPackProbeRequest(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProbeRequest, IES_ProbeRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Packed the ProbeRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestedInfo:\n")); + if (!pFrm->RequestedInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_requested_eids: %d.\n"), pFrm->RequestedInfo.num_requested_eids); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->RequestedInfo.requested_eids, pFrm->RequestedInfo.num_requested_eids); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WscProbeReq:\n")); + if (!pFrm->WscProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version:\n")); + if (!pFrm->WscProbeReq.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestType:\n")); + if (!pFrm->WscProbeReq.RequestType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestType.reqType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeReq.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeReq.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeReq.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RFBands:\n")); + if (!pFrm->WscProbeReq.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AssociationState:\n")); + if (!pFrm->WscProbeReq.AssociationState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.AssociationState.state, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigurationError:\n")); + if (!pFrm->WscProbeReq.ConfigurationError.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigurationError.error, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeReq.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeReq.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_name: %d.\n"), pFrm->WscProbeReq.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.Manufacturer.name, pFrm->WscProbeReq.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelName:\n")); + if (!pFrm->WscProbeReq.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelName.text, pFrm->WscProbeReq.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeReq.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelNumber.text, pFrm->WscProbeReq.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeReq.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.DeviceName.text, pFrm->WscProbeReq.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeReq.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version2:\n")); + if (!pFrm->WscProbeReq.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeReq.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.RequestToEnroll.req, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestDeviceType:\n")); + if (!pFrm->WscProbeReq.RequestDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.sub_category, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WFATPC:\n")); + if (!pFrm->WFATPC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.txPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.linkMargin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PProbeReq:\n")); + if (!pFrm->P2PProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PProbeReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ListenChannel:\n")); + if (!pFrm->P2PProbeReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PProbeReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeRequest. */ + +tANI_U32 dot11fPackProbeResponse(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProbeResponse, IES_ProbeResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Packed the ProbeResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WscProbeRes:\n")); + if (!pFrm->WscProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->WscProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPSState:\n")); + if (!pFrm->WscProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APSetupLocked:\n")); + if (!pFrm->WscProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->WscProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.Manufacturer.name, pFrm->WscProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelName:\n")); + if (!pFrm->WscProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelName.text, pFrm->WscProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelNumber.text, pFrm->WscProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SerialNumber:\n")); + if (!pFrm->WscProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.SerialNumber.text, pFrm->WscProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.DeviceName.text, pFrm->WscProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RFBands:\n")); + if (!pFrm->WscProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PProbeRes:\n")); + if (!pFrm->P2PProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_NoADesc: %d.\n"), pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor1IE:\n")); + if (!pFrm->Vendor1IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor2IE:\n")); + if (!pFrm->Vendor2IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Vendor3IE:\n")); + if (!pFrm->Vendor3IE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelSwitchWrapper:\n")); + if (!pFrm->ChannelSwitchWrapper.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChannelSwitchWrapper.WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeResponse. */ + +tANI_U32 dot11fPackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProvisionDiscoveryReq, IES_ProvisionDiscoveryReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Packed the ProvisionDiscoveryReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PProvisionDiscoveryReq:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_text: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PGroupId.ssid, pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryReq. */ + +tANI_U32 dot11fPackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProvisionDiscoveryRes, IES_ProvisionDiscoveryRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Packed the ProvisionDiscoveryRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2PWSCProvisionDiscoveryRes:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("ConfigMethods:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.methods, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryRes. */ + +tANI_U32 dot11fPackQosMapConfigure(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_QosMapConfigure, IES_QosMapConfigure); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Packed the QosMapConfigure:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackQosMapConfigure. */ + +tANI_U32 dot11fPackRadioMeasurementReport(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RadioMeasurementReport, IES_RadioMeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Packed the RadioMeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("MeasurementReport[%d]:\n"), i); + if (!pFrm->MeasurementReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport[i].late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport[i].incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport[i].refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].type, 1); + switch (pFrm->MeasurementReport[i].type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport[i].report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport[i].report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport[i].report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.parent_TSF, 4); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementReport. */ + +tANI_U32 dot11fPackRadioMeasurementRequest(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Packed the RadioMeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("NumOfRepetitions:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->NumOfRepetitions.repetitions, 2); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementRequest. */ + +tANI_U32 dot11fPackReAssocRequest(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ReAssocRequest, IES_ReAssocRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Packed the ReAssocRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("CurrentAPAddress:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->CurrentAPAddress.mac, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESECckmOpaque:\n")); + if (!pFrm->ESECckmOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->ESECckmOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESECckmOpaque.data, pFrm->ESECckmOpaque.num_data); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocRequest. */ + +tANI_U32 dot11fPackReAssocResponse(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ReAssocResponse, IES_ReAssocResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Packed the ReAssocResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WscReassocRes:\n")); + if (!pFrm->WscReassocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscReassocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscReassocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscReassocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscReassocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscReassocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocResponse. */ + +tANI_U32 dot11fPackSMPowerSave(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SMPowerSave, IES_SMPowerSave); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Packed the SMPowerSave:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("SMPowerModeSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("PowerSave_En (1): %d\n"), pFrm->SMPowerModeSet.PowerSave_En); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Mode (1): %d\n"), pFrm->SMPowerModeSet.Mode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("reserved (6): %d\n"), pFrm->SMPowerModeSet.reserved); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSMPowerSave. */ + +tANI_U32 dot11fPackSaQueryReq(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SaQueryReq, IES_SaQueryReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Packed the SaQueryReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryReq. */ + +tANI_U32 dot11fPackSaQueryRsp(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SaQueryRsp, IES_SaQueryRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Packed the SaQueryRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryRsp. */ + +tANI_U32 dot11fPackTDLSDisReq(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSDisReq, IES_TDLSDisReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Packed the TDLSDisReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisReq. */ + +tANI_U32 dot11fPackTDLSDisRsp(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSDisRsp, IES_TDLSDisRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Packed the TDLSDisRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisRsp. */ + +tANI_U32 dot11fPackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Packed the TDLSPeerTrafficInd:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PTIControl:\n")); + if (!pFrm->PTIControl.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.tid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.sequence_control, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PUBufferStatus:\n")); + if (!pFrm->PUBufferStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_bk_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_bk_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_be_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_be_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vi_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vi_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vo_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vo_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("reserved (4): %d\n"), pFrm->PUBufferStatus.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficInd. */ + +tANI_U32 dot11fPackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Packed the TDLSPeerTrafficRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficRsp. */ + +tANI_U32 dot11fPackTDLSSetupCnf(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupCnf, IES_TDLSSetupCnf); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Packed the TDLSSetupCnf:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupCnf. */ + +tANI_U32 dot11fPackTDLSSetupReq(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupReq, IES_TDLSSetupReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Packed the TDLSSetupReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupReq. */ + +tANI_U32 dot11fPackTDLSSetupRsp(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupRsp, IES_TDLSSetupRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Packed the TDLSSetupRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupRsp. */ + +tANI_U32 dot11fPackTDLSTeardown(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSTeardown, IES_TDLSTeardown); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Packed the TDLSTeardown:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSTeardown. */ + +tANI_U32 dot11fPackTPCReport(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TPCReport, IES_TPCReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Packed the TPCReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCReport. */ + +tANI_U32 dot11fPackTPCRequest(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TPCRequest, IES_TPCRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Packed the TPCRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("TPCRequest:\n")); + if (!pFrm->TPCRequest.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCRequest. */ + +tANI_U32 dot11fPackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Packed the VHTGidManagementActionFrame:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtMembershipStatusArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtMembershipStatusArray.membershipStatusArray, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtUserPositionArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtUserPositionArray.userPositionArray, 16); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackVHTGidManagementActionFrame. */ + +tANI_U32 dot11fPackWMMAddTSRequest(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMAddTSRequest, IES_WMMAddTSRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Packed the WMMAddTSRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSRequest. */ + +tANI_U32 dot11fPackWMMAddTSResponse(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMAddTSResponse, IES_WMMAddTSResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Packed the WMMAddTSResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSResponse. */ + +tANI_U32 dot11fPackWMMDelTS(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMDelTS, IES_WMMDelTS); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Packed the WMMDelTS:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMDelTS. */ + +static tANI_U32 PackCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tFFDefn FFs[], + const tIEDefn IEs[]) +{ + const tFFDefn *pFf; + const tIEDefn *pIe; + tFRAMES_BOOL *pfFound; + tANI_U8 *pBufRemaining; + tANI_U16 i; + tANI_U32 nBufRemaining, status, len; + tANI_U32 countOffset = 0; + + (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */ + i=0; + + DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pFf = &( FFs[0] ); + while ( pFf->size ) + { + if ( pFf->size > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The Fixed Field %s req" + "uires %d bytes, but there are only %d remaining.\n"), + pFf->name, pFf->size, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + switch ( pFf->sig ) + { + case SigFfAID: + dot11fPackFfAID(pCtx, (tDot11fFfAID* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAction: + dot11fPackFfAction(pCtx, (tDot11fFfAction* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAddBAParameterSet: + dot11fPackFfAddBAParameterSet(pCtx, (tDot11fFfAddBAParameterSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAuthAlgo: + dot11fPackFfAuthAlgo(pCtx, (tDot11fFfAuthAlgo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAuthSeqNo: + dot11fPackFfAuthSeqNo(pCtx, (tDot11fFfAuthSeqNo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBAStartingSequenceControl: + dot11fPackFfBAStartingSequenceControl(pCtx, (tDot11fFfBAStartingSequenceControl* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBATimeout: + dot11fPackFfBATimeout(pCtx, (tDot11fFfBATimeout* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBeaconInterval: + dot11fPackFfBeaconInterval(pCtx, (tDot11fFfBeaconInterval* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCapabilities: + dot11fPackFfCapabilities(pCtx, (tDot11fFfCapabilities* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCategory: + dot11fPackFfCategory(pCtx, (tDot11fFfCategory* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCurrentAPAddress: + dot11fPackFfCurrentAPAddress(pCtx, (tDot11fFfCurrentAPAddress* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfDelBAParameterSet: + dot11fPackFfDelBAParameterSet(pCtx, (tDot11fFfDelBAParameterSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfDialogToken: + dot11fPackFfDialogToken(pCtx, (tDot11fFfDialogToken* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfLinkMargin: + dot11fPackFfLinkMargin(pCtx, (tDot11fFfLinkMargin* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfListenInterval: + dot11fPackFfListenInterval(pCtx, (tDot11fFfListenInterval* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfMaxTxPower: + dot11fPackFfMaxTxPower(pCtx, (tDot11fFfMaxTxPower* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfNumOfRepetitions: + dot11fPackFfNumOfRepetitions(pCtx, (tDot11fFfNumOfRepetitions* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfOperatingMode: + dot11fPackFfOperatingMode(pCtx, (tDot11fFfOperatingMode* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfP2POUI: + dot11fPackFfP2POUI(pCtx, (tDot11fFfP2POUI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfP2POUISubType: + dot11fPackFfP2POUISubType(pCtx, (tDot11fFfP2POUISubType* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRCPI: + dot11fPackFfRCPI(pCtx, (tDot11fFfRCPI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRSNI: + dot11fPackFfRSNI(pCtx, (tDot11fFfRSNI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfReason: + dot11fPackFfReason(pCtx, (tDot11fFfReason* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRxAntennaId: + dot11fPackFfRxAntennaId(pCtx, (tDot11fFfRxAntennaId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfSMPowerModeSet: + dot11fPackFfSMPowerModeSet(pCtx, (tDot11fFfSMPowerModeSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfStatus: + dot11fPackFfStatus(pCtx, (tDot11fFfStatus* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfStatusCode: + dot11fPackFfStatusCode(pCtx, (tDot11fFfStatusCode* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTPCEleID: + dot11fPackFfTPCEleID(pCtx, (tDot11fFfTPCEleID* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTPCEleLen: + dot11fPackFfTPCEleLen(pCtx, (tDot11fFfTPCEleLen* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTSInfo: + dot11fPackFfTSInfo(pCtx, (tDot11fFfTSInfo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTimeStamp: + dot11fPackFfTimeStamp(pCtx, (tDot11fFfTimeStamp* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTransactionId: + dot11fPackFfTransactionId(pCtx, (tDot11fFfTransactionId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTxAntennaId: + dot11fPackFfTxAntennaId(pCtx, (tDot11fFfTxAntennaId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTxPower: + dot11fPackFfTxPower(pCtx, (tDot11fFfTxPower* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfVhtMembershipStatusArray: + dot11fPackFfVhtMembershipStatusArray(pCtx, (tDot11fFfVhtMembershipStatusArray* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfVhtUserPositionArray: + dot11fPackFfVhtUserPositionArray(pCtx, (tDot11fFfVhtUserPositionArray* )(pSrc + pFf->offset), pBufRemaining); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the Fixed Field %d; this is most l" + "ikely a bug in 'framesg'.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += pFf->size; + nBufRemaining -= pFf->size; + *pnConsumed += pFf->size; + ++pFf; + + } + + pIe = &( IEs[0] ); + while ( 0xff != pIe->eid ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pIe->offset + + pIe->presenceOffset); + if ( *pfFound && pIe->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The IE %s takes at le" + "ast %d bytes, but there are only %d left in the b" + "uffer.\n"), pIe->name, pIe->minSize, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + + countOffset = ( (0 == pIe->arraybound) ? 1: *(tANI_U16* )(pSrc + pIe->countOffset) ); + for (i = 0; i < countOffset; ++i) + { + len = 0U; + switch ( pIe->sig ) + { + case SigIeAPName: + status |= dot11fPackIeAPName(pCtx, ( tDot11fIEAPName* )(pSrc + pIe->offset + sizeof(tDot11fIEAPName) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBPIndicator: + status |= dot11fPackIeBPIndicator(pCtx, ( tDot11fIEBPIndicator* )(pSrc + pIe->offset + sizeof(tDot11fIEBPIndicator) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCondensedCountryStr: + status |= dot11fPackIeCondensedCountryStr(pCtx, ( tDot11fIECondensedCountryStr* )(pSrc + pIe->offset + sizeof(tDot11fIECondensedCountryStr) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeGTK: + status |= dot11fPackIeGTK(pCtx, ( tDot11fIEGTK* )(pSrc + pIe->offset + sizeof(tDot11fIEGTK) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHCF: + status |= dot11fPackIeHCF(pCtx, ( tDot11fIEHCF* )(pSrc + pIe->offset + sizeof(tDot11fIEHCF) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeIGTK: + status |= dot11fPackIeIGTK(pCtx, ( tDot11fIEIGTK* )(pSrc + pIe->offset + sizeof(tDot11fIEIGTK) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLLAttr: + status |= dot11fPackIeLLAttr(pCtx, ( tDot11fIELLAttr* )(pSrc + pIe->offset + sizeof(tDot11fIELLAttr) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLoadBalance: + status |= dot11fPackIeLoadBalance(pCtx, ( tDot11fIELoadBalance* )(pSrc + pIe->offset + sizeof(tDot11fIELoadBalance) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLoadInfo: + status |= dot11fPackIeLoadInfo(pCtx, ( tDot11fIELoadInfo* )(pSrc + pIe->offset + sizeof(tDot11fIELoadInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropAssocType: + status |= dot11fPackIePropAssocType(pCtx, ( tDot11fIEPropAssocType* )(pSrc + pIe->offset + sizeof(tDot11fIEPropAssocType) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropCapability: + status |= dot11fPackIePropCapability(pCtx, ( tDot11fIEPropCapability* )(pSrc + pIe->offset + sizeof(tDot11fIEPropCapability) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropChannSwitchAnn: + status |= dot11fPackIePropChannSwitchAnn(pCtx, ( tDot11fIEPropChannSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEPropChannSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropEDCAParams: + status |= dot11fPackIePropEDCAParams(pCtx, ( tDot11fIEPropEDCAParams* )(pSrc + pIe->offset + sizeof(tDot11fIEPropEDCAParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropQuietBSS: + status |= dot11fPackIePropQuietBSS(pCtx, ( tDot11fIEPropQuietBSS* )(pSrc + pIe->offset + sizeof(tDot11fIEPropQuietBSS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropSuppRates: + status |= dot11fPackIePropSuppRates(pCtx, ( tDot11fIEPropSuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIEPropSuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeR0KH_ID: + status |= dot11fPackIeR0KH_ID(pCtx, ( tDot11fIER0KH_ID* )(pSrc + pIe->offset + sizeof(tDot11fIER0KH_ID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeR1KH_ID: + status |= dot11fPackIeR1KH_ID(pCtx, ( tDot11fIER1KH_ID* )(pSrc + pIe->offset + sizeof(tDot11fIER1KH_ID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSFInfo: + status |= dot11fPackIeTSFInfo(pCtx, ( tDot11fIETSFInfo* )(pSrc + pIe->offset + sizeof(tDot11fIETSFInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTaurus: + status |= dot11fPackIeTaurus(pCtx, ( tDot11fIETaurus* )(pSrc + pIe->offset + sizeof(tDot11fIETaurus) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTitan: + status |= dot11fPackIeTitan(pCtx, ( tDot11fIETitan* )(pSrc + pIe->offset + sizeof(tDot11fIETitan) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTriggerStaBgScan: + status |= dot11fPackIeTriggerStaBgScan(pCtx, ( tDot11fIETriggerStaBgScan* )(pSrc + pIe->offset + sizeof(tDot11fIETriggerStaBgScan) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVersion: + status |= dot11fPackIeVersion(pCtx, ( tDot11fIEVersion* )(pSrc + pIe->offset + sizeof(tDot11fIEVersion) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWDS: + status |= dot11fPackIeWDS(pCtx, ( tDot11fIEWDS* )(pSrc + pIe->offset + sizeof(tDot11fIEWDS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAPChannelReport: + status |= dot11fPackIeAPChannelReport(pCtx, ( tDot11fIEAPChannelReport* )(pSrc + pIe->offset + sizeof(tDot11fIEAPChannelReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBcnReportingDetail: + status |= dot11fPackIeBcnReportingDetail(pCtx, ( tDot11fIEBcnReportingDetail* )(pSrc + pIe->offset + sizeof(tDot11fIEBcnReportingDetail) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBeaconReportFrmBody: + status |= dot11fPackIeBeaconReportFrmBody(pCtx, ( tDot11fIEBeaconReportFrmBody* )(pSrc + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBeaconReporting: + status |= dot11fPackIeBeaconReporting(pCtx, ( tDot11fIEBeaconReporting* )(pSrc + pIe->offset + sizeof(tDot11fIEBeaconReporting) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementPilot: + status |= dot11fPackIeMeasurementPilot(pCtx, ( tDot11fIEMeasurementPilot* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementPilot) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMultiBssid: + status |= dot11fPackIeMultiBssid(pCtx, ( tDot11fIEMultiBssid* )(pSrc + pIe->offset + sizeof(tDot11fIEMultiBssid) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICData: + status |= dot11fPackIeRICData(pCtx, ( tDot11fIERICData* )(pSrc + pIe->offset + sizeof(tDot11fIERICData) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICDescriptor: + status |= dot11fPackIeRICDescriptor(pCtx, ( tDot11fIERICDescriptor* )(pSrc + pIe->offset + sizeof(tDot11fIERICDescriptor) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRRMEnabledCap: + status |= dot11fPackIeRRMEnabledCap(pCtx, ( tDot11fIERRMEnabledCap* )(pSrc + pIe->offset + sizeof(tDot11fIERRMEnabledCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRequestedInfo: + status |= dot11fPackIeRequestedInfo(pCtx, ( tDot11fIERequestedInfo* )(pSrc + pIe->offset + sizeof(tDot11fIERequestedInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSSID: + status |= dot11fPackIeSSID(pCtx, ( tDot11fIESSID* )(pSrc + pIe->offset + sizeof(tDot11fIESSID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSchedule: + status |= dot11fPackIeSchedule(pCtx, ( tDot11fIESchedule* )(pSrc + pIe->offset + sizeof(tDot11fIESchedule) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTCLAS: + status |= dot11fPackIeTCLAS(pCtx, ( tDot11fIETCLAS* )(pSrc + pIe->offset + sizeof(tDot11fIETCLAS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTCLASSPROC: + status |= dot11fPackIeTCLASSPROC(pCtx, ( tDot11fIETCLASSPROC* )(pSrc + pIe->offset + sizeof(tDot11fIETCLASSPROC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSDelay: + status |= dot11fPackIeTSDelay(pCtx, ( tDot11fIETSDelay* )(pSrc + pIe->offset + sizeof(tDot11fIETSDelay) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSPEC: + status |= dot11fPackIeTSPEC(pCtx, ( tDot11fIETSPEC* )(pSrc + pIe->offset + sizeof(tDot11fIETSPEC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMSchedule: + status |= dot11fPackIeWMMSchedule(pCtx, ( tDot11fIEWMMSchedule* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMSchedule) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTCLAS: + status |= dot11fPackIeWMMTCLAS(pCtx, ( tDot11fIEWMMTCLAS* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTCLAS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTCLASPROC: + status |= dot11fPackIeWMMTCLASPROC(pCtx, ( tDot11fIEWMMTCLASPROC* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTCLASPROC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTSDelay: + status |= dot11fPackIeWMMTSDelay(pCtx, ( tDot11fIEWMMTSDelay* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTSDelay) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTSPEC: + status |= dot11fPackIeWMMTSPEC(pCtx, ( tDot11fIEWMMTSPEC* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTSPEC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWiderBWChanSwitchAnn: + status |= dot11fPackIeWiderBWChanSwitchAnn(pCtx, ( tDot11fIEWiderBWChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEWiderBWChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAID: + status |= dot11fPackIeAID(pCtx, ( tDot11fIEAID* )(pSrc + pIe->offset + sizeof(tDot11fIEAID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAirgo: + status |= dot11fPackIeAirgo(pCtx, ( tDot11fIEAirgo* )(pSrc + pIe->offset + sizeof(tDot11fIEAirgo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCFParams: + status |= dot11fPackIeCFParams(pCtx, ( tDot11fIECFParams* )(pSrc + pIe->offset + sizeof(tDot11fIECFParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeChallengeText: + status |= dot11fPackIeChallengeText(pCtx, ( tDot11fIEChallengeText* )(pSrc + pIe->offset + sizeof(tDot11fIEChallengeText) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeChanSwitchAnn: + status |= dot11fPackIeChanSwitchAnn(pCtx, ( tDot11fIEChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeChannelSwitchWrapper: + status |= dot11fPackIeChannelSwitchWrapper(pCtx, ( tDot11fIEChannelSwitchWrapper* )(pSrc + pIe->offset + sizeof(tDot11fIEChannelSwitchWrapper) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCountry: + status |= dot11fPackIeCountry(pCtx, ( tDot11fIECountry* )(pSrc + pIe->offset + sizeof(tDot11fIECountry) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeDSParams: + status |= dot11fPackIeDSParams(pCtx, ( tDot11fIEDSParams* )(pSrc + pIe->offset + sizeof(tDot11fIEDSParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeEDCAParamSet: + status |= dot11fPackIeEDCAParamSet(pCtx, ( tDot11fIEEDCAParamSet* )(pSrc + pIe->offset + sizeof(tDot11fIEEDCAParamSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeERPInfo: + status |= dot11fPackIeERPInfo(pCtx, ( tDot11fIEERPInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEERPInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESECckmOpaque: + status |= dot11fPackIeESECckmOpaque(pCtx, ( tDot11fIEESECckmOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEESECckmOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESERadMgmtCap: + status |= dot11fPackIeESERadMgmtCap(pCtx, ( tDot11fIEESERadMgmtCap* )(pSrc + pIe->offset + sizeof(tDot11fIEESERadMgmtCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETrafStrmMet: + status |= dot11fPackIeESETrafStrmMet(pCtx, ( tDot11fIEESETrafStrmMet* )(pSrc + pIe->offset + sizeof(tDot11fIEESETrafStrmMet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETrafStrmRateSet: + status |= dot11fPackIeESETrafStrmRateSet(pCtx, ( tDot11fIEESETrafStrmRateSet* )(pSrc + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETxmitPower: + status |= dot11fPackIeESETxmitPower(pCtx, ( tDot11fIEESETxmitPower* )(pSrc + pIe->offset + sizeof(tDot11fIEESETxmitPower) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESEVersion: + status |= dot11fPackIeESEVersion(pCtx, ( tDot11fIEESEVersion* )(pSrc + pIe->offset + sizeof(tDot11fIEESEVersion) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtCap: + status |= dot11fPackIeExtCap(pCtx, ( tDot11fIEExtCap* )(pSrc + pIe->offset + sizeof(tDot11fIEExtCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtChanSwitchAnn: + status |= dot11fPackIeExtChanSwitchAnn(pCtx, ( tDot11fIEExtChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEExtChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtSuppRates: + status |= dot11fPackIeExtSuppRates(pCtx, ( tDot11fIEExtSuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIEExtSuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHParamSet: + status |= dot11fPackIeFHParamSet(pCtx, ( tDot11fIEFHParamSet* )(pSrc + pIe->offset + sizeof(tDot11fIEFHParamSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHParams: + status |= dot11fPackIeFHParams(pCtx, ( tDot11fIEFHParams* )(pSrc + pIe->offset + sizeof(tDot11fIEFHParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHPattTable: + status |= dot11fPackIeFHPattTable(pCtx, ( tDot11fIEFHPattTable* )(pSrc + pIe->offset + sizeof(tDot11fIEFHPattTable) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFTInfo: + status |= dot11fPackIeFTInfo(pCtx, ( tDot11fIEFTInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEFTInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHT2040BSSCoexistence: + status |= dot11fPackIeHT2040BSSCoexistence(pCtx, ( tDot11fIEHT2040BSSCoexistence* )(pSrc + pIe->offset + sizeof(tDot11fIEHT2040BSSCoexistence) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHT2040BSSIntolerantReport: + status |= dot11fPackIeHT2040BSSIntolerantReport(pCtx, ( tDot11fIEHT2040BSSIntolerantReport* )(pSrc + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHTCaps: + status |= dot11fPackIeHTCaps(pCtx, ( tDot11fIEHTCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEHTCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHTInfo: + status |= dot11fPackIeHTInfo(pCtx, ( tDot11fIEHTInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEHTInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeIBSSParams: + status |= dot11fPackIeIBSSParams(pCtx, ( tDot11fIEIBSSParams* )(pSrc + pIe->offset + sizeof(tDot11fIEIBSSParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLinkIdentifier: + status |= dot11fPackIeLinkIdentifier(pCtx, ( tDot11fIELinkIdentifier* )(pSrc + pIe->offset + sizeof(tDot11fIELinkIdentifier) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementReport: + status |= dot11fPackIeMeasurementReport(pCtx, ( tDot11fIEMeasurementReport* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementRequest: + status |= dot11fPackIeMeasurementRequest(pCtx, ( tDot11fIEMeasurementRequest* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementRequest) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMobilityDomain: + status |= dot11fPackIeMobilityDomain(pCtx, ( tDot11fIEMobilityDomain* )(pSrc + pIe->offset + sizeof(tDot11fIEMobilityDomain) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeNeighborReport: + status |= dot11fPackIeNeighborReport(pCtx, ( tDot11fIENeighborReport* )(pSrc + pIe->offset + sizeof(tDot11fIENeighborReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeOBSSScanParameters: + status |= dot11fPackIeOBSSScanParameters(pCtx, ( tDot11fIEOBSSScanParameters* )(pSrc + pIe->offset + sizeof(tDot11fIEOBSSScanParameters) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeOperatingMode: + status |= dot11fPackIeOperatingMode(pCtx, ( tDot11fIEOperatingMode* )(pSrc + pIe->offset + sizeof(tDot11fIEOperatingMode) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PAssocReq: + status |= dot11fPackIeP2PAssocReq(pCtx, ( tDot11fIEP2PAssocReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PAssocReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PAssocRes: + status |= dot11fPackIeP2PAssocRes(pCtx, ( tDot11fIEP2PAssocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PAssocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PBeacon: + status |= dot11fPackIeP2PBeacon(pCtx, ( tDot11fIEP2PBeacon* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PBeacon) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PBeaconProbeRes: + status |= dot11fPackIeP2PBeaconProbeRes(pCtx, ( tDot11fIEP2PBeaconProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PBeaconProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeAuth: + status |= dot11fPackIeP2PDeAuth(pCtx, ( tDot11fIEP2PDeAuth* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeAuth) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeviceDiscoverabilityReq: + status |= dot11fPackIeP2PDeviceDiscoverabilityReq(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeviceDiscoverabilityRes: + status |= dot11fPackIeP2PDeviceDiscoverabilityRes(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDisAssoc: + status |= dot11fPackIeP2PDisAssoc(pCtx, ( tDot11fIEP2PDisAssoc* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDisAssoc) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegCnf: + status |= dot11fPackIeP2PGONegCnf(pCtx, ( tDot11fIEP2PGONegCnf* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegCnf) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegReq: + status |= dot11fPackIeP2PGONegReq(pCtx, ( tDot11fIEP2PGONegReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegRes: + status |= dot11fPackIeP2PGONegRes(pCtx, ( tDot11fIEP2PGONegRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegWPS: + status |= dot11fPackIeP2PGONegWPS(pCtx, ( tDot11fIEP2PGONegWPS* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegWPS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PIEOpaque: + status |= dot11fPackIeP2PIEOpaque(pCtx, ( tDot11fIEP2PIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PInvitationReq: + status |= dot11fPackIeP2PInvitationReq(pCtx, ( tDot11fIEP2PInvitationReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PInvitationReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PInvitationRes: + status |= dot11fPackIeP2PInvitationRes(pCtx, ( tDot11fIEP2PInvitationRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PInvitationRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PNoticeOfAbsence: + status |= dot11fPackIeP2PNoticeOfAbsence(pCtx, ( tDot11fIEP2PNoticeOfAbsence* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PNoticeOfAbsence) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PPresenceResponse: + status |= dot11fPackIeP2PPresenceResponse(pCtx, ( tDot11fIEP2PPresenceResponse* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PPresenceResponse) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProbeReq: + status |= dot11fPackIeP2PProbeReq(pCtx, ( tDot11fIEP2PProbeReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProbeReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProbeRes: + status |= dot11fPackIeP2PProbeRes(pCtx, ( tDot11fIEP2PProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProvisionDiscoveryReq: + status |= dot11fPackIeP2PProvisionDiscoveryReq(pCtx, ( tDot11fIEP2PProvisionDiscoveryReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProvisionDiscoveryReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + status |= dot11fPackIeP2PWSCProvisionDiscoveryRes(pCtx, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePTIControl: + status |= dot11fPackIePTIControl(pCtx, ( tDot11fIEPTIControl* )(pSrc + pIe->offset + sizeof(tDot11fIEPTIControl) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePUBufferStatus: + status |= dot11fPackIePUBufferStatus(pCtx, ( tDot11fIEPUBufferStatus* )(pSrc + pIe->offset + sizeof(tDot11fIEPUBufferStatus) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePowerCaps: + status |= dot11fPackIePowerCaps(pCtx, ( tDot11fIEPowerCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEPowerCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePowerConstraints: + status |= dot11fPackIePowerConstraints(pCtx, ( tDot11fIEPowerConstraints* )(pSrc + pIe->offset + sizeof(tDot11fIEPowerConstraints) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQBSSLoad: + status |= dot11fPackIeQBSSLoad(pCtx, ( tDot11fIEQBSSLoad* )(pSrc + pIe->offset + sizeof(tDot11fIEQBSSLoad) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQOSCapsAp: + status |= dot11fPackIeQOSCapsAp(pCtx, ( tDot11fIEQOSCapsAp* )(pSrc + pIe->offset + sizeof(tDot11fIEQOSCapsAp) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQOSCapsStation: + status |= dot11fPackIeQOSCapsStation(pCtx, ( tDot11fIEQOSCapsStation* )(pSrc + pIe->offset + sizeof(tDot11fIEQOSCapsStation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQosMapSet: + status |= dot11fPackIeQosMapSet(pCtx, ( tDot11fIEQosMapSet* )(pSrc + pIe->offset + sizeof(tDot11fIEQosMapSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQuiet: + status |= dot11fPackIeQuiet(pCtx, ( tDot11fIEQuiet* )(pSrc + pIe->offset + sizeof(tDot11fIEQuiet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRCPIIE: + status |= dot11fPackIeRCPIIE(pCtx, ( tDot11fIERCPIIE* )(pSrc + pIe->offset + sizeof(tDot11fIERCPIIE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICDataDesc: + status |= dot11fPackIeRICDataDesc(pCtx, ( tDot11fIERICDataDesc* )(pSrc + pIe->offset + sizeof(tDot11fIERICDataDesc) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSN: + status |= dot11fPackIeRSN(pCtx, ( tDot11fIERSN* )(pSrc + pIe->offset + sizeof(tDot11fIERSN) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSNIIE: + status |= dot11fPackIeRSNIIE(pCtx, ( tDot11fIERSNIIE* )(pSrc + pIe->offset + sizeof(tDot11fIERSNIIE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSNOpaque: + status |= dot11fPackIeRSNOpaque(pCtx, ( tDot11fIERSNOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIERSNOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppChannels: + status |= dot11fPackIeSuppChannels(pCtx, ( tDot11fIESuppChannels* )(pSrc + pIe->offset + sizeof(tDot11fIESuppChannels) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppOperatingClasses: + status |= dot11fPackIeSuppOperatingClasses(pCtx, ( tDot11fIESuppOperatingClasses* )(pSrc + pIe->offset + sizeof(tDot11fIESuppOperatingClasses) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppRates: + status |= dot11fPackIeSuppRates(pCtx, ( tDot11fIESuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIESuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTIM: + status |= dot11fPackIeTIM(pCtx, ( tDot11fIETIM* )(pSrc + pIe->offset + sizeof(tDot11fIETIM) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTPCReport: + status |= dot11fPackIeTPCReport(pCtx, ( tDot11fIETPCReport* )(pSrc + pIe->offset + sizeof(tDot11fIETPCReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTPCRequest: + status |= dot11fPackIeTPCRequest(pCtx, ( tDot11fIETPCRequest* )(pSrc + pIe->offset + sizeof(tDot11fIETPCRequest) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTimeoutInterval: + status |= dot11fPackIeTimeoutInterval(pCtx, ( tDot11fIETimeoutInterval* )(pSrc + pIe->offset + sizeof(tDot11fIETimeoutInterval) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTCaps: + status |= dot11fPackIeVHTCaps(pCtx, ( tDot11fIEVHTCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTExtBssLoad: + status |= dot11fPackIeVHTExtBssLoad(pCtx, ( tDot11fIEVHTExtBssLoad* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTExtBssLoad) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTOperation: + status |= dot11fPackIeVHTOperation(pCtx, ( tDot11fIEVHTOperation* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTOperation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVendor1IE: + status |= dot11fPackIeVendor1IE(pCtx, ( tDot11fIEVendor1IE* )(pSrc + pIe->offset + sizeof(tDot11fIEVendor1IE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVendor2IE: + status |= dot11fPackIeVendor2IE(pCtx, ( tDot11fIEVendor2IE* )(pSrc + pIe->offset + sizeof(tDot11fIEVendor2IE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVendor3IE: + status |= dot11fPackIeVendor3IE(pCtx, ( tDot11fIEVendor3IE* )(pSrc + pIe->offset + sizeof(tDot11fIEVendor3IE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWAPI: + status |= dot11fPackIeWAPI(pCtx, ( tDot11fIEWAPI* )(pSrc + pIe->offset + sizeof(tDot11fIEWAPI) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWAPIOpaque: + status |= dot11fPackIeWAPIOpaque(pCtx, ( tDot11fIEWAPIOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWAPIOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWFATPC: + status |= dot11fPackIeWFATPC(pCtx, ( tDot11fIEWFATPC* )(pSrc + pIe->offset + sizeof(tDot11fIEWFATPC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWFDIEOpaque: + status |= dot11fPackIeWFDIEOpaque(pCtx, ( tDot11fIEWFDIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWFDIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMCaps: + status |= dot11fPackIeWMMCaps(pCtx, ( tDot11fIEWMMCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMInfoAp: + status |= dot11fPackIeWMMInfoAp(pCtx, ( tDot11fIEWMMInfoAp* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMInfoAp) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMInfoStation: + status |= dot11fPackIeWMMInfoStation(pCtx, ( tDot11fIEWMMInfoStation* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMInfoStation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMParams: + status |= dot11fPackIeWMMParams(pCtx, ( tDot11fIEWMMParams* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWPA: + status |= dot11fPackIeWPA(pCtx, ( tDot11fIEWPA* )(pSrc + pIe->offset + sizeof(tDot11fIEWPA) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWPAOpaque: + status |= dot11fPackIeWPAOpaque(pCtx, ( tDot11fIEWPAOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWPAOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWSC: + status |= dot11fPackIeWSC(pCtx, ( tDot11fIEWSC* )(pSrc + pIe->offset + sizeof(tDot11fIEWSC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscAssocReq: + status |= dot11fPackIeWscAssocReq(pCtx, ( tDot11fIEWscAssocReq* )(pSrc + pIe->offset + sizeof(tDot11fIEWscAssocReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscAssocRes: + status |= dot11fPackIeWscAssocRes(pCtx, ( tDot11fIEWscAssocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscAssocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscBeacon: + status |= dot11fPackIeWscBeacon(pCtx, ( tDot11fIEWscBeacon* )(pSrc + pIe->offset + sizeof(tDot11fIEWscBeacon) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscBeaconProbeRes: + status |= dot11fPackIeWscBeaconProbeRes(pCtx, ( tDot11fIEWscBeaconProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscBeaconProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscIEOpaque: + status |= dot11fPackIeWscIEOpaque(pCtx, ( tDot11fIEWscIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWscIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscProbeReq: + status |= dot11fPackIeWscProbeReq(pCtx, ( tDot11fIEWscProbeReq* )(pSrc + pIe->offset + sizeof(tDot11fIEWscProbeReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscProbeRes: + status |= dot11fPackIeWscProbeRes(pCtx, ( tDot11fIEWscProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscReassocRes: + status |= dot11fPackIeWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscReassocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the IE %d; this is most likely a b" + "ug in 'framesc'.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + } + + ++pIe; + + } + + return status; + +} + +static tANI_U32 PackTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tTLVDefn TLVs[], + tANI_U32 *pidx) +{ + const tTLVDefn *pTlv; + tFRAMES_BOOL *pfFound; + tANI_U8 *pBufRemaining; + tANI_U32 nBufRemaining, status, len; + + DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + (void)pCtx; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound && pTlv->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least" + " %d bytes, but there are only %d left in the buffer." + "\n"), pTlv->name, pTlv->minSize, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + len = 0U; + + if ( *pfFound ) { + switch ( pTlv->sig ) + { + case SigTlvAuthorizedMACs: + status |= dot11fPackTlvAuthorizedMACs(pCtx, ( tDot11fTLVAuthorizedMACs* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestToEnroll: + status |= dot11fPackTlvRequestToEnroll(pCtx, ( tDot11fTLVRequestToEnroll* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVersion2: + status |= dot11fPackTlvVersion2(pCtx, ( tDot11fTLVVersion2* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvAPSetupLocked: + status |= dot11fPackTlvAPSetupLocked(pCtx, ( tDot11fTLVAPSetupLocked* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvAssociationState: + status |= dot11fPackTlvAssociationState(pCtx, ( tDot11fTLVAssociationState* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvChannelList: + status |= dot11fPackTlvChannelList(pCtx, ( tDot11fTLVChannelList* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigMethods: + status |= dot11fPackTlvConfigMethods(pCtx, ( tDot11fTLVConfigMethods* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigurationError: + status |= dot11fPackTlvConfigurationError(pCtx, ( tDot11fTLVConfigurationError* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigurationTimeout: + status |= dot11fPackTlvConfigurationTimeout(pCtx, ( tDot11fTLVConfigurationTimeout* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvDeviceName: + status |= dot11fPackTlvDeviceName(pCtx, ( tDot11fTLVDeviceName* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvDevicePasswordID: + status |= dot11fPackTlvDevicePasswordID(pCtx, ( tDot11fTLVDevicePasswordID* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvExtendedListenTiming: + status |= dot11fPackTlvExtendedListenTiming(pCtx, ( tDot11fTLVExtendedListenTiming* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvGOIntent: + status |= dot11fPackTlvGOIntent(pCtx, ( tDot11fTLVGOIntent* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvIntendedP2PInterfaceAddress: + status |= dot11fPackTlvIntendedP2PInterfaceAddress(pCtx, ( tDot11fTLVIntendedP2PInterfaceAddress* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvInvitationFlags: + status |= dot11fPackTlvInvitationFlags(pCtx, ( tDot11fTLVInvitationFlags* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvListenChannel: + status |= dot11fPackTlvListenChannel(pCtx, ( tDot11fTLVListenChannel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvManufacturer: + status |= dot11fPackTlvManufacturer(pCtx, ( tDot11fTLVManufacturer* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvMinorReasonCode: + status |= dot11fPackTlvMinorReasonCode(pCtx, ( tDot11fTLVMinorReasonCode* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvModelName: + status |= dot11fPackTlvModelName(pCtx, ( tDot11fTLVModelName* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvModelNumber: + status |= dot11fPackTlvModelNumber(pCtx, ( tDot11fTLVModelNumber* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvNoticeOfAbsence: + status |= dot11fPackTlvNoticeOfAbsence(pCtx, ( tDot11fTLVNoticeOfAbsence* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvOperatingChannel: + status |= dot11fPackTlvOperatingChannel(pCtx, ( tDot11fTLVOperatingChannel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PCapability: + status |= dot11fPackTlvP2PCapability(pCtx, ( tDot11fTLVP2PCapability* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PDeviceId: + status |= dot11fPackTlvP2PDeviceId(pCtx, ( tDot11fTLVP2PDeviceId* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PDeviceInfo: + status |= dot11fPackTlvP2PDeviceInfo(pCtx, ( tDot11fTLVP2PDeviceInfo* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupBssid: + status |= dot11fPackTlvP2PGroupBssid(pCtx, ( tDot11fTLVP2PGroupBssid* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupId: + status |= dot11fPackTlvP2PGroupId(pCtx, ( tDot11fTLVP2PGroupId* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupInfo: + status |= dot11fPackTlvP2PGroupInfo(pCtx, ( tDot11fTLVP2PGroupInfo* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PStatus: + status |= dot11fPackTlvP2PStatus(pCtx, ( tDot11fTLVP2PStatus* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvPrimaryDeviceType: + status |= dot11fPackTlvPrimaryDeviceType(pCtx, ( tDot11fTLVPrimaryDeviceType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRFBands: + status |= dot11fPackTlvRFBands(pCtx, ( tDot11fTLVRFBands* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestDeviceType: + status |= dot11fPackTlvRequestDeviceType(pCtx, ( tDot11fTLVRequestDeviceType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestType: + status |= dot11fPackTlvRequestType(pCtx, ( tDot11fTLVRequestType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvResponseType: + status |= dot11fPackTlvResponseType(pCtx, ( tDot11fTLVResponseType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSelectedRegistrar: + status |= dot11fPackTlvSelectedRegistrar(pCtx, ( tDot11fTLVSelectedRegistrar* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSelectedRegistrarConfigMethods: + status |= dot11fPackTlvSelectedRegistrarConfigMethods(pCtx, ( tDot11fTLVSelectedRegistrarConfigMethods* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSerialNumber: + status |= dot11fPackTlvSerialNumber(pCtx, ( tDot11fTLVSerialNumber* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvUUID_E: + status |= dot11fPackTlvUUID_E(pCtx, ( tDot11fTLVUUID_E* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvUUID_R: + status |= dot11fPackTlvUUID_R(pCtx, ( tDot11fTLVUUID_R* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVendorExtension: + status |= dot11fPackTlvVendorExtension(pCtx, ( tDot11fTLVVendorExtension* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVersion: + status |= dot11fPackTlvVersion(pCtx, ( tDot11fTLVVersion* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvWPSState: + status |= dot11fPackTlvWPSState(pCtx, ( tDot11fTLVWPSState* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PInterface: + status |= dot11fPackTlvP2PInterface(pCtx, ( tDot11fTLVP2PInterface* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PManageability: + status |= dot11fPackTlvP2PManageability(pCtx, ( tDot11fTLVP2PManageability* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't " + "know about the TLV %d; this is most likely a bug in " + "'framesc'.\n"), pTlv->sig); + return DOT11F_INTERNAL_ERROR; + } + + } /* End if on *pfFound */ + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + ++pTlv; + if(len) ++*pidx; + } + + return status; + +} diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logApi.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logApi.c new file mode 100644 index 0000000000000..57636888a2499 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logApi.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * logApi.cc - Handles log messages for all the modules. + * Author: Kevin Nguyen + * Date: 02/27/02 + * History:- + * 02/11/02 Created. + * 03/12/02 Rearrange logDebug parameter list and add more params. + * -------------------------------------------------------------------- + * + */ + +#include +#include +#include +#include + +#include +#include "utilsGlobal.h" +#include "macInitApi.h" +#include "palApi.h" + +#include "vos_trace.h" + +#ifdef ANI_OS_TYPE_ANDROID +#include +#endif + + +// --------------------------------------------------------------------- +/** + * logInit() + * + * FUNCTION: + * This function is called to prepare the logging utility. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param tpAniSirGlobal Sirius software parameter strucutre pointer + * @return None + */ +tSirRetStatus +logInit(tpAniSirGlobal pMac) +{ + tANI_U32 i; + + // Add code to initialize debug level from CFG module + // For now, enable all logging + for (i = 0; i < LOG_ENTRY_NUM; i++) + { +#ifdef SIR_DEBUG + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = LOG1; +#else + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = LOGW; +#endif + } + return eSIR_SUCCESS; + +} /*** logInit() ***/ + +void +logDeinit(tpAniSirGlobal pMac) +{ + return; +} + +/** + * logDbg() + * + *FUNCTION: + * This function is called to log a debug message. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * None. + * + *NOTE: + * + * @param tpAniSirGlobal Sirius software parameter strucutre pointer + * @param ModId 8-bit modID + * @param debugLevel debugging level for this message + * @param pStr string parameter pointer + * @return None + */ + + +void logDbg(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr,...) +{ +#ifdef WLAN_DEBUG + if ( debugLevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( modId )] ) + return; + else + { + va_list marker; + + va_start( marker, pStr ); /* Initialize variable arguments. */ + + logDebug(pMac, modId, debugLevel, pStr, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + + VOS_TRACE_LEVEL getVosDebugLevel(tANI_U32 debugLevel) +{ + switch(debugLevel) + { + case LOGP: + return VOS_TRACE_LEVEL_FATAL; + case LOGE: + return VOS_TRACE_LEVEL_ERROR; + case LOGW: + return VOS_TRACE_LEVEL_WARN; + case LOG1: + return VOS_TRACE_LEVEL_INFO; + case LOG2: + return VOS_TRACE_LEVEL_INFO_HIGH; + case LOG3: + return VOS_TRACE_LEVEL_INFO_MED; + case LOG4: + return VOS_TRACE_LEVEL_INFO_LOW; + default: + return VOS_TRACE_LEVEL_INFO_LOW; + } +} + +static inline VOS_MODULE_ID getVosModuleId(tANI_U8 modId) +{ + switch(modId) + { + case SIR_HAL_MODULE_ID: + case SIR_PHY_MODULE_ID: + return VOS_MODULE_ID_WDA; + case SIR_PMM_MODULE_ID: + return VOS_MODULE_ID_PMC; + + case SIR_LIM_MODULE_ID: + case SIR_SCH_MODULE_ID: + case SIR_CFG_MODULE_ID: + case SIR_MNT_MODULE_ID: + case SIR_DPH_MODULE_ID: + case SIR_DBG_MODULE_ID: + return VOS_MODULE_ID_PE; + + case SIR_SYS_MODULE_ID: + return VOS_MODULE_ID_SYS; + + case SIR_SMS_MODULE_ID: + return VOS_MODULE_ID_SME; + + default: + return VOS_MODULE_ID_SYS; + } +} + +#define LOG_SIZE 256 +void logDebug(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr, va_list marker) +{ + VOS_TRACE_LEVEL vosDebugLevel; + VOS_MODULE_ID vosModuleId; + char logBuffer[LOG_SIZE]; + + vosDebugLevel = getVosDebugLevel(debugLevel); + vosModuleId = getVosModuleId(modId); + + vsnprintf(logBuffer, LOG_SIZE - 1, pStr, marker); + VOS_TRACE(vosModuleId, vosDebugLevel, "%s", logBuffer); + + // The caller must check loglevel + VOS_ASSERT( ( debugLevel <= pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( modId )] ) && ( LOGP != debugLevel ) ); +} /*** end logDebug() ***/ diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logDump.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logDump.c new file mode 100644 index 0000000000000..6ae4bd24f0318 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/logDump.c @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +logDump.c +*/ + +/* + * This file contains the utility functions to dump various + * MAC states and to enable/disable certain features during + * debugging. + * Author: Sandesh Goel + * Date: 02/27/02 + * History:- + * 02/11/02 Created. + * -------------------------------------------------------------------- + * + */ + +/* + * @note : Bytes is to print overflow message information. + */ + +#include "palTypes.h" + +#ifdef ANI_LOGDUMP + +#define MAX_OVERFLOW_MSG 400 +#define MAX_LOGDUMP_SIZE ((4*1024) - MAX_OVERFLOW_MSG) + +#if defined(ANI_OS_TYPE_ANDROID) + +#include + +#endif + + +#include "palApi.h" +#include "aniGlobal.h" +#include "sirCommon.h" +#include +#include + +#include +#include +#include +#include +#include +#include "limUtils.h" +#include "schApi.h" + +#include "pmmApi.h" +#include "limSerDesUtils.h" +#include "limAssocUtils.h" +#include "limSendMessages.h" +#include "limSecurityUtils.h" +//#include "halRadar.h" +#include "logDump.h" +#include "sysDebug.h" +#include "wlan_qct_wda.h" + +#define HAL_LOG_DUMP_CMD_START 0 + +/* Dump command id for Host modules starts from 300 onwards, + * hence do not extend the HAL commands beyond 300. + */ +#define HAL_LOG_DUMP_CMD_END 299 + +static int debug; + + void +logPrintf(tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4) +{ + static tANI_U8 buf[MAX_LOGDUMP_SIZE + MAX_OVERFLOW_MSG]; + tANI_U16 bufLen; + pMac->gCurrentLogSize = 0; + + bufLen = (tANI_U16)logRtaiDump(pMac, cmd, arg1, arg2, arg3, arg4, buf); +} + +/** + @brief: This function is used to Aggregate the formated buffer, this + also check the overflow condition and adds the overflow message + to the end of the log Dump buffer reserved of MAX_OVERFLOW_MSG size. + @param: tpAniSirGlobal pMac + @param: char *pBuf + @param: variable arguments... + @return: Returns the number of bytes added to the buffer. + Returns 0 incase of overflow. + + @note: Currently in windows we do not print the Aggregated buffer as there + is a limitation on the number of bytes that can be displayed by DbgPrint + So we print the buffer immediately and we would also aggregate where + the TestDbg might use this buffer to print out at the application level. + */ +int log_sprintf(tpAniSirGlobal pMac, char *pBuf, char *fmt, ...) +{ + tANI_S32 ret = 0; +#ifdef WLAN_DEBUG + + va_list args; + va_start(args, fmt); + + if (pMac->gCurrentLogSize >= MAX_LOGDUMP_SIZE) + return 0; + +#if defined (ANI_OS_TYPE_ANDROID) + ret = vsnprintf(pBuf, (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize), fmt, args); +#endif + + va_end(args); + + /* If an output error is encountered, a negative value is returned by vsnprintf */ + if (ret < 0) + return 0; + + + if ((tANI_U32) ret > (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize)) { + pBuf += (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize); + pMac->gCurrentLogSize = MAX_LOGDUMP_SIZE; + +#if defined (ANI_OS_TYPE_ANDROID) + ret = snprintf(pBuf, MAX_OVERFLOW_MSG, "\n-> ***********" + "\nOutput Exceeded the Buffer Size, message truncated!!\n<- ***********\n"); +#endif + /* If an output error is encountered, a negative value is returned by snprintf */ + if (ret < 0) + return 0; + + if (ret > MAX_OVERFLOW_MSG) + ret = MAX_OVERFLOW_MSG; + } + + pMac->gCurrentLogSize += ret; + + +#endif //for #ifdef WLAN_DEBUG + return ret; +} + + +char* dumpLOG( tpAniSirGlobal pMac, char *p ) +{ + tANI_U32 i; + + for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ ) { + p += log_sprintf(pMac, p, "[0x%2x]", i); + switch (i) + { + case SIR_HAL_MODULE_ID: p += log_sprintf( pMac, p, "HAL "); break; + case SIR_CFG_MODULE_ID: p += log_sprintf( pMac, p, "CFG "); break; + case SIR_LIM_MODULE_ID: p += log_sprintf( pMac, p, "LIM "); break; + case SIR_ARQ_MODULE_ID: p += log_sprintf( pMac, p, "ARQ "); break; + case SIR_SCH_MODULE_ID: p += log_sprintf( pMac, p, "SCH "); break; + case SIR_PMM_MODULE_ID: p += log_sprintf( pMac, p, "PMM "); break; + case SIR_MNT_MODULE_ID: p += log_sprintf( pMac, p, "MNT "); break; + case SIR_DBG_MODULE_ID: p += log_sprintf( pMac, p, "DBG "); break; + case SIR_DPH_MODULE_ID: p += log_sprintf( pMac, p, "DPH "); break; + case SIR_SYS_MODULE_ID: p += log_sprintf( pMac, p, "SYS "); break; + case SIR_PHY_MODULE_ID: p += log_sprintf( pMac, p, "PHY "); break; + case SIR_DVT_MODULE_ID: p += log_sprintf( pMac, p, "DVT "); break; + case SIR_SMS_MODULE_ID: p += log_sprintf( pMac, p, "SMS "); break; + default: p += log_sprintf( pMac, p, "UNK ", i); break; + } + + p += log_sprintf( pMac, p, + ": debug level is [0x%x] ", + pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID]); + + switch( pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] ) + { + case LOGOFF: p += log_sprintf( pMac, p, "LOG disabled\n"); break; + case LOGP: p += log_sprintf( pMac, p, "LOGP(Panic only)\n"); break; + case LOGE: p += log_sprintf( pMac, p, "LOGE(Errors only)\n"); break; + case LOGW: p += log_sprintf( pMac, p, "LOGW(Warnings)\n"); break; + case LOG1: p += log_sprintf( pMac, p, "LOG1(Minimal debug)\n"); break; + case LOG2: p += log_sprintf( pMac, p, "LOG2(Verbose)\n"); break; + case LOG3: p += log_sprintf( pMac, p, "LOG3(Very Verbose)\n"); break; + case LOG4: p += log_sprintf( pMac, p, "LOG4(Very Very Verbose)\n"); break; + default: p += log_sprintf( pMac, p, "Unknown\n"); break; + } + } + + return p; +} + +char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level ) +{ + tANI_U32 i; + + if((module > SIR_LAST_MODULE_ID || module < SIR_FIRST_MODULE_ID) && module != 0xff ) { + p += log_sprintf( pMac, p, "Invalid module id 0x%x\n", module ); + return p; + } + + if( 0xff == module ) { + for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ ) + pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] = level; + } else { + pMac->utils.gLogDbgLevel[module - SIR_FIRST_MODULE_ID] = level; + } + +#ifdef ANI_PHY_DEBUG + if (module == 0xff || module == SIR_PHY_MODULE_ID) { + pMac->hphy.phy.phyDebugLogLevel = level; + } +#endif + + return dumpLOG( pMac, p ); +} + +static void Log_getCfg(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ +#define CFG_CTL_INT 0x00080000 + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + tANI_U32 val; + + // Get integer parameter + if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId, &val) != eSIR_SUCCESS) + { + sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId); + } + else + { + sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) = %ld\n"), gCfgParamName[cfgId], cfgId, cfgId, val ); + } + } + else + { + tANI_U8 buf[CFG_MAX_STR_LEN] = {0} ; + tANI_U32 valueLen ; + + // Get string parameter + valueLen = CFG_MAX_STR_LEN ; + if (wlan_cfgGetStr(pMac, cfgId, buf, &valueLen) != eSIR_SUCCESS) + { + sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId); + } + else + { + sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) len=%ld\n"), gCfgParamName[cfgId], cfgId, cfgId, valueLen ); + sirDumpBuf(pMac, SIR_WDA_MODULE_ID, LOG1, buf, valueLen) ; + } + } + + return; +} + +static void Log_setCfg(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 val) +{ + sysLog(pMac, LOGE, FL("Set %s(0x%x) to value 0x%x\n"), + gCfgParamName[cfgId], cfgId, val); + + if (cfgSetInt(pMac, (tANI_U16)cfgId, val) != eSIR_SUCCESS) + sysLog(pMac, LOGE, FL("setting cfgId 0x%x to value 0x%x failed \n"), + cfgId, val); + return; +} + + +char * dump_cfg_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + Log_getCfg(pMac, (tANI_U16) arg1); + return p; +} + +char * dump_cfg_group_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 i, startId, endId; + + (void) arg3; (void) arg4; + + if (arg1 < CFG_PARAM_MAX_NUM) { + startId = arg1; + } else { + p += log_sprintf( pMac, p, "Start CFGID must be less than %d\n", CFG_PARAM_MAX_NUM); + return p; + } + + if ((arg2 == 0) || (arg2 > CFG_PARAM_MAX_NUM)) + arg2 = 30; + + endId = ((startId + arg2) < CFG_PARAM_MAX_NUM) ? (startId + arg2) : CFG_PARAM_MAX_NUM; + + for (i=startId; i < endId; i++) + Log_getCfg(pMac, (tANI_U16) i); + + return p; +} +char * dump_cfg_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg3; (void) arg4; + Log_setCfg(pMac, (tANI_U16) arg1, arg2); + return p; +} + +char * dump_log_level_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = setLOGLevel( pMac, p, arg1, arg2 ); + return p; +} + + +/* Initialize the index */ +void logDumpInit(tpAniSirGlobal pMac) +{ + pMac->dumpTablecurrentId = 0; + +} + +void logDumpRegisterTable( tpAniSirGlobal pMac, tDumpFuncEntry *pEntry, tANI_U32 nItems ) +{ + + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->nItems = nItems; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->mindumpid = pEntry->id; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->maxdumpid = (pEntry + (nItems-1))->id; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->dumpTable = pEntry; + pMac->dumpTablecurrentId++; +} + + +/* + * print nItems from the menu list ponted to by m + */ +static tANI_U32 print_menu(tpAniSirGlobal pMac, char *p, tANI_U32 startId) +{ + tANI_U32 currentId = 0; + tANI_U32 i, j; + tANI_S32 ret = 0; + tDumpFuncEntry *pEntry = NULL; + tANI_U32 nItems = 0; + + for(i = 0; i < pMac->dumpTablecurrentId; i++) { + pEntry = pMac->dumpTableEntry[i]->dumpTable; + nItems = pMac->dumpTableEntry[i]->nItems; + + for (j = 0; j < nItems; j++, pEntry++) { + if (pEntry->description == NULL) + continue; + + if (pEntry->id == 0) { + ret = log_sprintf( pMac,p, "---- %s\n", pEntry->description); + + if (ret <= 0) + break; + + p += ret; + continue; + } + + if (pEntry->id < startId) + continue; + + ret = log_sprintf(pMac, p, "%4d\t%s\n", pEntry->id, pEntry->description); + + if (ret <= 0) + break; + + currentId = pEntry->id; + p += ret; + } + + if (ret <= 0) + break; + } + + return currentId; +} + +int logRtaiDump( tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, tANI_U8 *pBuf) +{ + char *p = (char *)pBuf; + tANI_U32 i; + tANI_U32 nItems = 0; + tDumpFuncEntry *pEntry = NULL; + + pMac->gCurrentLogSize = 0; + if (debug) { + p += log_sprintf( pMac,p, "Cmd = %d Args (0x%x,0x%x,0x%x,0x%x)\n\n", + cmd, arg1, arg2, arg3, arg4); + } + + if( cmd == MAX_DUMP_CMD || cmd == 0 ) { + pMac->menuCurrent = print_menu(pMac, p, pMac->menuCurrent); + return pMac->gCurrentLogSize; + } + if(cmd <= HAL_LOG_DUMP_CMD_END) + { + WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, p); + } + else + { + for(i = 0; i < pMac->dumpTablecurrentId; i++) { + if( (cmd > pMac->dumpTableEntry[i]->mindumpid) && (cmd <= pMac->dumpTableEntry[i]->maxdumpid)) { + pEntry = pMac->dumpTableEntry[i]->dumpTable; + nItems = pMac->dumpTableEntry[i]->nItems; + break; + } else { + continue; + } + } + + if((nItems > 0) && (pEntry != NULL)) { + for (i = 0; i < nItems; i++, pEntry++) { + if( cmd == pEntry->id ) { + if ( pEntry->func != NULL ) { + pEntry->func(pMac, arg1, arg2, arg3, arg4, p); + } else { + p += log_sprintf( pMac,p, "Cmd not supported\n"); + } + break; + } + } + } else { + p += log_sprintf( pMac,p, "Cmd not found \n"); + } + } + if (debug) + p += log_sprintf( pMac,p, "Returned %d bytes\n", pMac->gCurrentLogSize); + + return pMac->gCurrentLogSize; + +} + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/macTrace.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/macTrace.c new file mode 100644 index 0000000000000..5b80f41643b6c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/macTrace.c @@ -0,0 +1,972 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file macTrace.c + + \brief implementation for trace related APIs + + \author Sunit Bhatia + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include "macTrace.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_wda_msg.h" +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_main.h" +#include "wlan_hdd_p2p.h" +#include "csrNeighborRoam.h" +#include "csrInternal.h" +#include "limGlobal.h" +#include "wlan_qct_tl.h" +#include "vos_memory.h" +#include "vos_trace.h" + +#ifdef TRACE_RECORD + +/* --------------------------------------------------------------------------- + \fn macTraceGetHDDWlanConnState + \function to get string equivalent of a value + from the enum eConnectionState. + + \param connState - the value from the enum + \return the string equivalent of connState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetHDDWlanConnState(tANI_U16 connState) +{ + switch(connState) + { + CASE_RETURN_STRING(eConnectionState_NotConnected); + CASE_RETURN_STRING(eConnectionState_Connecting); + CASE_RETURN_STRING(eConnectionState_Associated); + CASE_RETURN_STRING(eConnectionState_IbssDisconnected); + CASE_RETURN_STRING(eConnectionState_IbssConnected); + CASE_RETURN_STRING(eConnectionState_Disconnecting); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetP2PConnState + \function to get string equivalent of a value + from the enum tP2PConnectionStatus. + + \param connState - the value from the enum + \return the string equivalent of connState + ---------------------------------------------------------------------------*/ +#ifdef WLAN_FEATURE_P2P_DEBUG +tANI_U8* macTraceGetP2PConnState(tANI_U16 connState) +{ + switch(connState) + { + CASE_RETURN_STRING(P2P_NOT_ACTIVE); + CASE_RETURN_STRING(P2P_GO_NEG_PROCESS); + CASE_RETURN_STRING(P2P_GO_NEG_COMPLETED); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTING_STATE_1); + CASE_RETURN_STRING(P2P_GO_COMPLETED_STATE); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTED_STATE_1); + CASE_RETURN_STRING(P2P_CLIENT_DISCONNECTED_STATE); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTING_STATE_2); + CASE_RETURN_STRING(P2P_CLIENT_COMPLETED_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} +#endif + +/* --------------------------------------------------------------------------- + \fn macTraceGetNeighbourRoamState + \function to get string equivalent of a value + from the enum eCsrNeighborRoamState. + + \param neighbourRoamState - the value from the enum + \return the string equivalent of neighbourRoamState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetNeighbourRoamState(tANI_U16 neighbourRoamState) +{ + switch(neighbourRoamState) + { + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING); + #ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE); + #endif /* WLAN_FEATURE_VOWIFI_11R */ + CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetcsrRoamState + \function to get string equivalent of a value + from the enum eCsrRoamState. + + \param csrRoamState - the value from the enum + \return the string equivalent of csrRoamState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetcsrRoamState(tANI_U16 csrRoamState) +{ + switch(csrRoamState) + { + CASE_RETURN_STRING(eCSR_ROAMING_STATE_STOP); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_IDLE); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_SCANNING); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINING); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINED); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetcsrRoamSubState + \function to get string equivalent of a value + from the enum eCsrRoamSubState. + + \param csrRoamSubState - the value from the enum + \return the string equivalent of csrRoamSubState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetcsrRoamSubState(tANI_U16 csrRoamSubState) +{ + switch(csrRoamSubState) + { + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_NONE); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_START_BSS_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOIN_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_REASSOC_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_STOP_BSS_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_AUTH_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_CONFIG); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DEAUTH_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_FORCED); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetLimSmeState + \function to get string equivalent of a value + from the enum tLimSmeStates. + + \param limState - the value from the enum + \return the string equivalent of limState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetLimSmeState(tANI_U16 limState) +{ + switch(limState) + { + CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_SME_IDLE_STATE); + CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE); + CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE); + CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE); + CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetLimMlmState + \function to get string equivalent of a value + from the enum tLimMlmStates. + + \param mlmState - the value from the enum + \return the string equivalent of mlmState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetLimMlmState(tANI_U16 mlmState) +{ + switch(mlmState) + { + CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE); + CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE); + CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE); + CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE); + CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE); + CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE); + CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetTLState + \function to get string equivalent of a value + from the enum WLANTL_STAStateType. + + \param tlState - the value from the enum + \return the string equivalent of tlState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetTLState(tANI_U16 tlState) +{ + switch(tlState) + { + CASE_RETURN_STRING(WLANTL_STA_INIT); + CASE_RETURN_STRING(WLANTL_STA_CONNECTED); + CASE_RETURN_STRING(WLANTL_STA_AUTHENTICATED); + CASE_RETURN_STRING(WLANTL_STA_DISCONNECTED); + CASE_RETURN_STRING(WLANTL_STA_MAX_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetSmeMsgString( tANI_U16 smeMsg ) +{ + switch( smeMsg ) + { + CASE_RETURN_STRING(eWNI_SME_START_REQ); + CASE_RETURN_STRING(eWNI_SME_START_RSP); + CASE_RETURN_STRING(eWNI_SME_SYS_READY_IND); + CASE_RETURN_STRING(eWNI_SME_SCAN_REQ); + CASE_RETURN_STRING(eWNI_SME_SCAN_ABORT_IND); + CASE_RETURN_STRING(eWNI_SME_SCAN_RSP); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(eWNI_SME_OEM_DATA_REQ); + CASE_RETURN_STRING(eWNI_SME_OEM_DATA_RSP); +#endif + CASE_RETURN_STRING(eWNI_SME_JOIN_REQ); + CASE_RETURN_STRING(eWNI_SME_JOIN_RSP); + CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_REQ); + CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_RSP); + CASE_RETURN_STRING(eWNI_SME_REASSOC_REQ); + CASE_RETURN_STRING(eWNI_SME_REASSOC_RSP); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_REQ); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_RSP); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_REQ); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_RSP); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_IND); + CASE_RETURN_STRING(eWNI_SME_WM_STATUS_CHANGE_NTF); + CASE_RETURN_STRING(eWNI_SME_IBSS_NEW_PEER_IND); + CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_DEPARTED_IND); + CASE_RETURN_STRING(eWNI_SME_START_BSS_REQ); + CASE_RETURN_STRING(eWNI_SME_START_BSS_RSP); + CASE_RETURN_STRING(eWNI_SME_AUTH_IND); + CASE_RETURN_STRING(eWNI_SME_ASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_ASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_REASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_REASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_RSP); + CASE_RETURN_STRING(eWNI_SME_STOP_BSS_REQ); + CASE_RETURN_STRING(eWNI_SME_STOP_BSS_RSP); + CASE_RETURN_STRING(eWNI_SME_DEL_BA_PEER_IND); + CASE_RETURN_STRING(eWNI_SME_DEFINE_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_DEFINE_QOS_RSP); + CASE_RETURN_STRING(eWNI_SME_DELETE_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_DELETE_QOS_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_START_REQ); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_START_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_STOP_REQ); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_STOP_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_REPORT_IND); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_BSS_IND); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_REQ); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_RSP); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_IND); + CASE_RETURN_STRING(eWNI_SME_SET_WDS_INFO_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_WDS_INFO_RSP); + CASE_RETURN_STRING(eWNI_SME_WDS_INFO_IND); + CASE_RETURN_STRING(eWNI_SME_SET_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_REQ); + CASE_RETURN_STRING(eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_RSP); + CASE_RETURN_STRING(eWNI_SME_SELECT_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_SELECT_CHANNEL_RSP); + CASE_RETURN_STRING(eWNI_SME_SET_PROPRIETARY_IE_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_PROPRIETARY_IE_RSP); // #endif + CASE_RETURN_STRING(eWNI_SME_DISCARD_SKB_NTF); // Used to cleanup SKBs by HDD + CASE_RETURN_STRING(eWNI_SME_DEAUTH_CNF); + CASE_RETURN_STRING(eWNI_SME_MIC_FAILURE_IND); + CASE_RETURN_STRING(eWNI_SME_ADDTS_REQ); + CASE_RETURN_STRING(eWNI_SME_ADDTS_RSP); + CASE_RETURN_STRING(eWNI_SME_ADDTS_CNF); + CASE_RETURN_STRING(eWNI_SME_ADDTS_IND); + CASE_RETURN_STRING(eWNI_SME_DELTS_REQ); + CASE_RETURN_STRING(eWNI_SME_DELTS_RSP); + CASE_RETURN_STRING(eWNI_SME_DELTS_IND); + CASE_RETURN_STRING(eWNI_SME_SET_BACKGROUND_SCAN_MODE_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_PRIMARY_RSP); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_SECONDARY_RSP); + CASE_RETURN_STRING(eWNI_SME_PROBE_REQ); + CASE_RETURN_STRING(eWNI_SME_STA_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_STA_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_AGGR_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_AGGR_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_GLOBAL_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_GLOBAL_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_STAT_SUMM_REQ); + CASE_RETURN_STRING(eWNI_SME_STAT_SUMM_RSP); + CASE_RETURN_STRING(eWNI_SME_REMOVEKEY_REQ); + CASE_RETURN_STRING(eWNI_SME_REMOVEKEY_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_SCANNED_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_SCANNED_CHANNEL_RSP); + CASE_RETURN_STRING(eWNI_SME_SET_TX_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_TX_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_TX_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_TX_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_NOISE_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_NOISE_RSP); + CASE_RETURN_STRING(eWNI_SME_LOW_RSSI_IND); + CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_RSSI_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_ASSOC_STAS_REQ); + CASE_RETURN_STRING(eWNI_SME_TKIP_CNTR_MEAS_REQ); + CASE_RETURN_STRING(eWNI_SME_UPDATE_APWPSIE_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_WPSPBC_SESSION_REQ); + CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_SET_APWPARSNIEs_REQ); + CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_HIDE_SSID_REQ); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_IND); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RSP); + CASE_RETURN_STRING(eWNI_SME_MGMT_FRM_IND); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RDY_IND); + CASE_RETURN_STRING(eWNI_SME_SEND_ACTION_FRAME_IND); + CASE_RETURN_STRING(eWNI_SME_ACTION_FRAME_SEND_CNF); + CASE_RETURN_STRING(eWNI_SME_ABORT_REMAIN_ON_CHAN_IND); + CASE_RETURN_STRING(eWNI_SME_UPDATE_NOA); + CASE_RETURN_STRING(eWNI_SME_CLEAR_DFS_CHANNEL_LIST); + CASE_RETURN_STRING(eWNI_SME_CLEAR_LIM_SCAN_CACHE); + CASE_RETURN_STRING(eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER); + CASE_RETURN_STRING(eWNI_SME_GET_SNR_REQ); + CASE_RETURN_STRING(eWNI_SME_LINK_STATUS_IND); + + CASE_RETURN_STRING(eWNI_PMC_MSG_TYPES_BEGIN); + + //General Power Save Messages + CASE_RETURN_STRING(eWNI_PMC_PWR_SAVE_CFG); + + //BMPS Messages + CASE_RETURN_STRING(eWNI_PMC_ENTER_BMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_BMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_IND); + + //IMPS Messages. + CASE_RETURN_STRING(eWNI_PMC_ENTER_IMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_IMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_IMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_IMPS_RSP); + + //UAPSD Messages + CASE_RETURN_STRING(eWNI_PMC_ENTER_UAPSD_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_UAPSD_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_UAPSD_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_UAPSD_RSP); + + CASE_RETURN_STRING(eWNI_PMC_SMPS_STATE_IND); + CASE_RETURN_STRING(eWNI_PMC_WOWL_ADD_BCAST_PTRN); + CASE_RETURN_STRING(eWNI_PMC_WOWL_DEL_BCAST_PTRN); + CASE_RETURN_STRING(eWNI_PMC_ENTER_WOWL_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_WOWL_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_WOWL_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_WOWL_RSP); + +#ifdef WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP); +#endif // WLAN_FEATURE_PACKET_FILTERING +#if defined WLAN_FEATURE_VOWIFI + CASE_RETURN_STRING(eWNI_SME_RRM_MSG_TYPE_BEGIN); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND); + CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND); +#endif + CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_REQ); + CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_RSP); + CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_REQ); + CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_RSP); +#if defined WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_REQ); + CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_RSP); + CASE_RETURN_STRING(eWNI_SME_FT_UPDATE_KEY); + CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP); +#endif +#if defined FEATURE_WLAN_ESE + CASE_RETURN_STRING(eWNI_SME_ESE_ADJACENT_AP_REPORT); +#endif + CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_REQ); + CASE_RETURN_STRING(eWNI_SME_COEX_IND); +#ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(eWNI_SME_PREF_NETWORK_FOUND_IND); +#endif // FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(eWNI_SME_TX_PER_HIT_IND); + CASE_RETURN_STRING(eWNI_SME_CHANGE_COUNTRY_CODE); + CASE_RETURN_STRING(eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE); + CASE_RETURN_STRING(eWNI_SME_PRE_SWITCH_CHL_IND); + CASE_RETURN_STRING(eWNI_SME_POST_SWITCH_CHL_IND); + CASE_RETURN_STRING(eWNI_SME_MAX_ASSOC_EXCEEDED); + CASE_RETURN_STRING(eWNI_SME_BTAMP_LOG_LINK_IND);//to serialize the create/accpet LL req from HCI +#ifdef WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP); +#endif // WLAN_FEATURE_GTK_OFFLOAD +#ifdef WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(eWNI_SME_WAKE_REASON_IND); +#endif // WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(eWNI_SME_EXCLUDE_UNENCRYPTED); + CASE_RETURN_STRING(eWNI_SME_RSSI_IND); //RSSI indication from TL to be serialized on MC thread + CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); + CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_RSP); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + CASE_RETURN_STRING(eWNI_SME_ROAM_OFFLOAD_SYNCH_IND); +#endif + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + + +tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ) +{ + switch( wdaMsg ) + { + CASE_RETURN_STRING(WDA_APP_SETUP_NTF); + CASE_RETURN_STRING(WDA_NIC_OPER_NTF); + CASE_RETURN_STRING(WDA_INIT_START_REQ); + CASE_RETURN_STRING(WDA_RESET_REQ); + CASE_RETURN_STRING(WDA_HDD_ADDBA_REQ); + CASE_RETURN_STRING(WDA_HDD_ADDBA_RSP); + CASE_RETURN_STRING(WDA_DELETEBA_IND); + CASE_RETURN_STRING(WDA_BA_FAIL_IND); + CASE_RETURN_STRING(WDA_TL_FLUSH_AC_REQ); + CASE_RETURN_STRING(WDA_TL_FLUSH_AC_RSP); + + CASE_RETURN_STRING(WDA_ITC_MSG_TYPES_BEGIN); + CASE_RETURN_STRING(WDA_WDT_KAM_RSP); + CASE_RETURN_STRING(WDA_TIMER_TEMP_MEAS_REQ); + CASE_RETURN_STRING(WDA_TIMER_PERIODIC_STATS_COLLECT_REQ); + CASE_RETURN_STRING(WDA_CAL_REQ_NTF); + CASE_RETURN_STRING(WDA_MNT_OPEN_TPC_TEMP_MEAS_REQ); + CASE_RETURN_STRING(WDA_CCA_MONITOR_INTERVAL_TO); + CASE_RETURN_STRING(WDA_CCA_MONITOR_DURATION_TO); + CASE_RETURN_STRING(WDA_CCA_MONITOR_START); + CASE_RETURN_STRING(WDA_CCA_MONITOR_STOP); + CASE_RETURN_STRING(WDA_CCA_CHANGE_MODE); + CASE_RETURN_STRING(WDA_TIMER_WRAP_AROUND_STATS_COLLECT_REQ); + + CASE_RETURN_STRING(WDA_ADD_STA_REQ); + CASE_RETURN_STRING(WDA_ADD_STA_RSP); + CASE_RETURN_STRING(WDA_ADD_STA_SELF_RSP); + CASE_RETURN_STRING(WDA_DEL_STA_SELF_RSP); + CASE_RETURN_STRING(WDA_DELETE_STA_REQ); + CASE_RETURN_STRING(WDA_DELETE_STA_RSP); + CASE_RETURN_STRING(WDA_ADD_BSS_REQ); + CASE_RETURN_STRING(WDA_ADD_BSS_RSP); + CASE_RETURN_STRING(WDA_DELETE_BSS_REQ); + CASE_RETURN_STRING(WDA_DELETE_BSS_RSP); + CASE_RETURN_STRING(WDA_INIT_SCAN_REQ); + CASE_RETURN_STRING(WDA_INIT_SCAN_RSP); + CASE_RETURN_STRING(WDA_START_SCAN_REQ); + CASE_RETURN_STRING(WDA_START_SCAN_RSP); + CASE_RETURN_STRING(WDA_END_SCAN_REQ); + CASE_RETURN_STRING(WDA_END_SCAN_RSP); + CASE_RETURN_STRING(WDA_FINISH_SCAN_REQ); + CASE_RETURN_STRING(WDA_FINISH_SCAN_RSP); + CASE_RETURN_STRING(WDA_SEND_BEACON_REQ); + CASE_RETURN_STRING(WDA_SEND_BEACON_RSP); + + CASE_RETURN_STRING(WDA_INIT_CFG_REQ); + CASE_RETURN_STRING(WDA_INIT_CFG_RSP); + + CASE_RETURN_STRING(WDA_INIT_WM_CFG_REQ); + CASE_RETURN_STRING(WDA_INIT_WM_CFG_RSP); + + CASE_RETURN_STRING(WDA_SET_BSSKEY_REQ); + CASE_RETURN_STRING(WDA_SET_BSSKEY_RSP); + CASE_RETURN_STRING(WDA_SET_STAKEY_REQ); + CASE_RETURN_STRING(WDA_SET_STAKEY_RSP); + CASE_RETURN_STRING(WDA_DPU_STATS_REQ); + CASE_RETURN_STRING(WDA_DPU_STATS_RSP); + CASE_RETURN_STRING(WDA_GET_DPUINFO_REQ); + CASE_RETURN_STRING(WDA_GET_DPUINFO_RSP); + + CASE_RETURN_STRING(WDA_UPDATE_EDCA_PROFILE_IND); + + CASE_RETURN_STRING(WDA_UPDATE_STARATEINFO_REQ); + CASE_RETURN_STRING(WDA_UPDATE_STARATEINFO_RSP); + + CASE_RETURN_STRING(WDA_UPDATE_BEACON_IND); + CASE_RETURN_STRING(WDA_UPDATE_CF_IND); + CASE_RETURN_STRING(WDA_CHNL_SWITCH_REQ); + CASE_RETURN_STRING(WDA_ADD_TS_REQ); + CASE_RETURN_STRING(WDA_DEL_TS_REQ); + CASE_RETURN_STRING(WDA_SOFTMAC_TXSTAT_REPORT); + CASE_RETURN_STRING(WDA_MBOX_SENDMSG_COMPLETE_IND); + CASE_RETURN_STRING(WDA_EXIT_BMPS_REQ); + CASE_RETURN_STRING(WDA_EXIT_BMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_BMPS_IND); + CASE_RETURN_STRING(WDA_ENTER_BMPS_REQ); + CASE_RETURN_STRING(WDA_ENTER_BMPS_RSP); + CASE_RETURN_STRING(WDA_BMPS_STATUS_IND); + CASE_RETURN_STRING(WDA_MISSED_BEACON_IND); + + CASE_RETURN_STRING(WDA_CFG_RXP_FILTER_REQ); + CASE_RETURN_STRING(WDA_CFG_RXP_FILTER_RSP); + CASE_RETURN_STRING(WDA_SWITCH_CHANNEL_RSP); + CASE_RETURN_STRING(WDA_P2P_NOA_ATTR_IND); + CASE_RETURN_STRING(WDA_P2P_NOA_START_IND); + CASE_RETURN_STRING(WDA_PWR_SAVE_CFG); + + CASE_RETURN_STRING(WDA_REGISTER_PE_CALLBACK); + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_READREQUEST); + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_WRITEREQUEST); + + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_READRESPONSE); + CASE_RETURN_STRING(WDA_SOFTMAC_BULKREGWRITE_CONFIRM); + CASE_RETURN_STRING(WDA_SOFTMAC_BULKREGREAD_RESPONSE); + CASE_RETURN_STRING(WDA_SOFTMAC_HOSTMESG_MSGPROCESSRESULT); + + CASE_RETURN_STRING(WDA_ADDBA_REQ); + CASE_RETURN_STRING(WDA_ADDBA_RSP); + CASE_RETURN_STRING(WDA_DELBA_IND); + CASE_RETURN_STRING(WDA_DEL_BA_IND); + CASE_RETURN_STRING(WDA_MIC_FAILURE_IND); + + CASE_RETURN_STRING(WDA_DELBA_REQ); + CASE_RETURN_STRING(WDA_IBSS_STA_ADD); + CASE_RETURN_STRING(WDA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND); + CASE_RETURN_STRING(WDA_SET_LINK_STATE); + CASE_RETURN_STRING(WDA_SET_LINK_STATE_RSP); + CASE_RETURN_STRING(WDA_ENTER_IMPS_REQ); + CASE_RETURN_STRING(WDA_ENTER_IMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_IMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_IMPS_REQ); + CASE_RETURN_STRING(WDA_SOFTMAC_HOSTMESG_PS_STATUS_IND); + CASE_RETURN_STRING(WDA_POSTPONE_ENTER_IMPS_RSP); + CASE_RETURN_STRING(WDA_STA_STAT_REQ); + CASE_RETURN_STRING(WDA_GLOBAL_STAT_REQ); + CASE_RETURN_STRING(WDA_AGGR_STAT_REQ); + CASE_RETURN_STRING(WDA_STA_STAT_RSP); + CASE_RETURN_STRING(WDA_GLOBAL_STAT_RSP); + CASE_RETURN_STRING(WDA_AGGR_STAT_RSP); + CASE_RETURN_STRING(WDA_STAT_SUMM_REQ); + CASE_RETURN_STRING(WDA_STAT_SUMM_RSP); + CASE_RETURN_STRING(WDA_REMOVE_BSSKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_BSSKEY_RSP); + CASE_RETURN_STRING(WDA_REMOVE_STAKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_STAKEY_RSP); + CASE_RETURN_STRING(WDA_SET_STA_BCASTKEY_REQ); + CASE_RETURN_STRING(WDA_SET_STA_BCASTKEY_RSP); + CASE_RETURN_STRING(WDA_REMOVE_STA_BCASTKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_STA_BCASTKEY_RSP); + CASE_RETURN_STRING(WDA_ADD_TS_RSP); + CASE_RETURN_STRING(WDA_DPU_MIC_ERROR); + + CASE_RETURN_STRING(WDA_TIMER_BA_ACTIVITY_REQ); + CASE_RETURN_STRING(WDA_TIMER_CHIP_MONITOR_TIMEOUT); + CASE_RETURN_STRING(WDA_TIMER_TRAFFIC_ACTIVITY_REQ); + CASE_RETURN_STRING(WDA_TIMER_ADC_RSSI_STATS); +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(WDA_TSM_STATS_REQ); + CASE_RETURN_STRING(WDA_TSM_STATS_RSP); +#endif + CASE_RETURN_STRING(WDA_UPDATE_UAPSD_IND); + CASE_RETURN_STRING(WDA_SET_MIMOPS_REQ); + CASE_RETURN_STRING(WDA_SET_MIMOPS_RSP); + CASE_RETURN_STRING(WDA_SYS_READY_IND ); + CASE_RETURN_STRING(WDA_SET_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_SET_TX_POWER_RSP); + CASE_RETURN_STRING(WDA_GET_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_GET_NOISE_REQ ); + CASE_RETURN_STRING(WDA_SET_TX_PER_TRACKING_REQ); + + CASE_RETURN_STRING(WDA_TRANSMISSION_CONTROL_IND); + CASE_RETURN_STRING(WDA_INIT_RADAR_IND); + + CASE_RETURN_STRING(WDA_BEACON_PRE_IND ); + CASE_RETURN_STRING(WDA_ENTER_UAPSD_REQ); + CASE_RETURN_STRING(WDA_ENTER_UAPSD_RSP); + CASE_RETURN_STRING(WDA_EXIT_UAPSD_REQ ); + CASE_RETURN_STRING(WDA_EXIT_UAPSD_RSP ); + CASE_RETURN_STRING(WDA_BEACON_FILTER_IND); + CASE_RETURN_STRING(WDA_WOWL_ADD_BCAST_PTRN); + CASE_RETURN_STRING(WDA_WOWL_DEL_BCAST_PTRN); + CASE_RETURN_STRING(WDA_WOWL_ENTER_REQ); + CASE_RETURN_STRING(WDA_WOWL_ENTER_RSP); + CASE_RETURN_STRING(WDA_WOWL_EXIT_REQ ); + CASE_RETURN_STRING(WDA_WOWL_EXIT_RSP ); + CASE_RETURN_STRING(WDA_TX_COMPLETE_IND); + CASE_RETURN_STRING(WDA_TIMER_RA_COLLECT_AND_ADAPT); + CASE_RETURN_STRING(WDA_GET_STATISTICS_REQ); + CASE_RETURN_STRING(WDA_GET_STATISTICS_RSP); + CASE_RETURN_STRING(WDA_SET_KEY_DONE); + + CASE_RETURN_STRING(WDA_BTC_SET_CFG); + CASE_RETURN_STRING(WDA_SIGNAL_BT_EVENT); + CASE_RETURN_STRING(WDA_HANDLE_FW_MBOX_RSP); + CASE_RETURN_STRING(WDA_SEND_PROBE_RSP_TMPL); + CASE_RETURN_STRING(WDA_SIGNAL_BTAMP_EVENT); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(WDA_START_OEM_DATA_REQ ); + CASE_RETURN_STRING(WDA_START_OEM_DATA_RSP); + CASE_RETURN_STRING(WDA_FINISH_OEM_DATA_REQ); +#endif //SUPPORT_BEACON_FILTER + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_RSP); + CASE_RETURN_STRING(WDA_SEND_MSG_COMPLETE); + CASE_RETURN_STRING(WDA_SET_HOST_OFFLOAD); + CASE_RETURN_STRING(WDA_SET_KEEP_ALIVE); +#ifdef WLAN_NS_OFFLOAD + CASE_RETURN_STRING(WDA_SET_NS_OFFLOAD); +#endif //WLAN_NS_OFFLOAD + CASE_RETURN_STRING(WDA_ADD_STA_SELF_REQ); + CASE_RETURN_STRING(WDA_DEL_STA_SELF_REQ); + CASE_RETURN_STRING(WDA_SET_P2P_GO_NOA_REQ); + CASE_RETURN_STRING(WDA_TX_COMPLETE_TIMEOUT_IND); + CASE_RETURN_STRING(WDA_WLAN_SUSPEND_IND); + CASE_RETURN_STRING(WDA_WLAN_RESUME_REQ); +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT + CASE_RETURN_STRING(WDA_WLAN_EXT_WOW); + CASE_RETURN_STRING(WDA_WLAN_SET_APP_TYPE1_PARAMS); + CASE_RETURN_STRING(WDA_WLAN_SET_APP_TYPE2_PARAMS); +#endif + CASE_RETURN_STRING(WDA_MSG_TYPES_END); + CASE_RETURN_STRING(WDA_MMH_TXMB_READY_EVT); + CASE_RETURN_STRING(WDA_MMH_RXMB_DONE_EVT); + CASE_RETURN_STRING(WDA_MMH_MSGQ_NE_EVT); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(WDA_AGGR_QOS_REQ); + CASE_RETURN_STRING(WDA_AGGR_QOS_RSP); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + CASE_RETURN_STRING(WDA_FTM_CMD_REQ); + CASE_RETURN_STRING(WDA_FTM_CMD_RSP); +#ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(WDA_SET_PNO_REQ); + CASE_RETURN_STRING(WDA_SET_RSSI_FILTER_REQ); + CASE_RETURN_STRING(WDA_UPDATE_SCAN_PARAMS_REQ); + CASE_RETURN_STRING(WDA_SET_PNO_CHANGED_IND); + CASE_RETURN_STRING(WDA_SME_SCAN_CACHE_UPDATED); +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + CASE_RETURN_STRING(WDA_ROAM_SCAN_OFFLOAD_REQ); +#endif +#ifdef WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(WDA_WAKE_REASON_IND); +#endif // WLAN_WAKEUP_EVENTS +#ifdef WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(WDA_8023_MULTICAST_LIST_REQ); + CASE_RETURN_STRING(WDA_RECEIVE_FILTER_SET_FILTER_REQ); + CASE_RETURN_STRING(WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ); + CASE_RETURN_STRING(WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP); + CASE_RETURN_STRING(WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ); +#endif // WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(WDA_SET_POWER_PARAMS_REQ); +#ifdef WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_GETINFO_REQ); + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_GETINFO_RSP); +#endif //WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(WDA_SET_TM_LEVEL_REQ); +#ifdef WLAN_FEATURE_11AC + CASE_RETURN_STRING(WDA_UPDATE_OP_MODE); + CASE_RETURN_STRING(WDA_UPDATE_MEMBERSHIP); + CASE_RETURN_STRING(WDA_UPDATE_USERPOS); +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + CASE_RETURN_STRING(WDA_SET_BATCH_SCAN_REQ); + CASE_RETURN_STRING(WDA_TRIGGER_BATCH_SCAN_RESULT_IND); + CASE_RETURN_STRING(WDA_STOP_BATCH_SCAN_IND); +#endif + CASE_RETURN_STRING(WDA_START_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_STOP_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_UPDATE_CHAN_LIST_REQ); + CASE_RETURN_STRING(WDA_CLI_SET_CMD); +#ifndef REMOVE_PKT_LOG + CASE_RETURN_STRING(WDA_PKTLOG_ENABLE_REQ); +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + CASE_RETURN_STRING(WDA_SET_PLM_REQ); +#endif + CASE_RETURN_STRING(WDA_CONFIG_PARAM_UPDATE_REQ); + CASE_RETURN_STRING(WDA_RATE_UPDATE_IND); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(WDA_UPDATE_FW_TDLS_STATE); + CASE_RETURN_STRING(WDA_UPDATE_TDLS_PEER_STATE); +#endif + CASE_RETURN_STRING(WDA_ADD_PERIODIC_TX_PTRN_IND); + CASE_RETURN_STRING(WDA_TX_POWER_LIMIT); +#ifdef FEATURE_WLAN_LPHB + CASE_RETURN_STRING(WDA_LPHB_CONF_REQ); +#endif + CASE_RETURN_STRING(WDA_DHCP_START_IND); + CASE_RETURN_STRING(WDA_DHCP_STOP_IND); +#ifdef FEATURE_WLAN_CH_AVOID + CASE_RETURN_STRING(WDA_CH_AVOID_UPDATE_REQ); +#endif +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN + CASE_RETURN_STRING(WDA_SET_AUTO_SHUTDOWN_TIMER_REQ); +#endif + CASE_RETURN_STRING(WDA_INIT_THERMAL_INFO_CMD); + CASE_RETURN_STRING(WDA_SET_THERMAL_LEVEL); + CASE_RETURN_STRING(WDA_SET_SAP_INTRABSS_DIS); + CASE_RETURN_STRING(WDA_FW_STATS_IND); + CASE_RETURN_STRING(WDA_VDEV_STOP_IND); + CASE_RETURN_STRING(WDA_TBTT_UPDATE_IND); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + CASE_RETURN_STRING(WDA_ROAM_OFFLOAD_SYNCH_CNF); + CASE_RETURN_STRING(WDA_ROAM_OFFLOAD_SYNCH_FAIL); +#endif + CASE_RETURN_STRING(SIR_HAL_SET_BASE_MACADDR_IND); + CASE_RETURN_STRING(WDA_LINK_STATUS_GET_REQ); + default: + return((tANI_U8*) "UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ) +{ + switch( limMsg ) + { + CASE_RETURN_STRING(SIR_LIM_RETRY_INTERRUPT_MSG); + CASE_RETURN_STRING(SIR_BB_XPORT_MGMT_MSG ); + CASE_RETURN_STRING(SIR_LIM_INV_KEY_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_KEY_ID_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_REPLAY_THRES_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_TD_DUMMY_CALLBACK_MSG ); + CASE_RETURN_STRING(SIR_LIM_SCH_CLEAN_MSG ); + CASE_RETURN_STRING(SIR_LIM_RADAR_DETECT_IND); + CASE_RETURN_STRING(SIR_LIM_DEL_TS_IND); + CASE_RETURN_STRING(SIR_LIM_ADD_BA_IND ); + CASE_RETURN_STRING(SIR_LIM_DEL_BA_ALL_IND); + CASE_RETURN_STRING(SIR_LIM_DELETE_STA_CONTEXT_IND); + CASE_RETURN_STRING(SIR_LIM_DEL_BA_IND ); + CASE_RETURN_STRING(SIR_LIM_UPDATE_BEACON); + CASE_RETURN_STRING(SIR_LIM_MIN_CHANNEL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_MAX_CHANNEL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_JOIN_FAIL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_AUTH_FAIL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_AUTH_RSP_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_ASSOC_FAIL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_REASSOC_FAIL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_HEART_BEAT_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_CHANNEL_SCAN_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_PROBE_HB_FAILURE_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_ADDTS_RSP_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_LINK_TEST_DURATION_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_HASH_MISS_THRES_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_CNF_WAIT_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_KEEPALIVE_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_CHANNEL_SWITCH_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_QUIET_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_QUIET_BSS_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_WPS_OVERLAP_TIMEOUT); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(SIR_LIM_FT_PREAUTH_RSP_TIMEOUT); +#endif + CASE_RETURN_STRING(SIR_LIM_REMAIN_CHN_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE); +#ifdef WMM_APSD + CASE_RETURN_STRING(SIR_LIM_WMM_APSD_SP_START_MSG_TYPE ); + CASE_RETURN_STRING(SIR_LIM_WMM_APSD_SP_END_MSG_TYPE ); +#endif + CASE_RETURN_STRING(SIR_LIM_BEACON_GEN_IND ); + CASE_RETURN_STRING(SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT); +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(SIR_LIM_ESE_TSM_TIMEOUT); +#endif + CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ) +{ + switch( cfgMsg ) + { + CASE_RETURN_STRING(WNI_CFG_PARAM_UPDATE_IND); + CASE_RETURN_STRING(WNI_CFG_DNLD_REQ); + CASE_RETURN_STRING(WNI_CFG_DNLD_CNF); + CASE_RETURN_STRING(WNI_CFG_GET_RSP); + CASE_RETURN_STRING(WNI_CFG_SET_CNF); + CASE_RETURN_STRING(SIR_CFG_PARAM_UPDATE_IND); + CASE_RETURN_STRING(SIR_CFG_DOWNLOAD_COMPLETE_IND); + + CASE_RETURN_STRING(WNI_CFG_SET_REQ_NO_RSP); + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetInfoLogString( tANI_U16 infoLog ) +{ + switch( infoLog ) + { + CASE_RETURN_STRING(eLOG_NODROP_MISSED_BEACON_SCENARIO); + CASE_RETURN_STRING(eLOG_PROC_DEAUTH_FRAME_SCENARIO); + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetModuleString( tANI_U8 moduleId ) +{ + return ((tANI_U8*)"PE"); + //return gVosTraceInfo[moduleId].moduleNameStr; +} + +void macTraceReset(tpAniSirGlobal pMac) +{ +} + +void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U16 session, + tANI_U32 data) +{ + /* Today macTrace is being invoked by PE only, + * need to remove this function once PE is migrated to using new trace API. + */ + macTraceNew(pMac, VOS_MODULE_ID_PE, code, session, data); +} + +void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, + tANI_U16 session, tANI_U32 data) +{ + vos_trace(module, code, session, data); +} + +tANI_U8* macTraceMsgString(tpAniSirGlobal pMac, tANI_U32 msgType) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(msgType); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(msgType); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + return macTraceGetLimMsgString((tANI_U16)msgType); + else + return macTraceGetSmeMsgString((tANI_U16)msgType); + break; + case SIR_WDA_MODULE_ID: + return macTraceGetWdaMsgString((tANI_U16)msgType); + case SIR_CFG_MODULE_ID: + return macTraceGetCfgMsgString((tANI_U16)msgType); + default: + return ((tANI_U8*)"Unknown MsgType"); + } +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c new file mode 100644 index 0000000000000..60d07c0c7a8b3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/parserApi.c @@ -0,0 +1,5512 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file parserApi.cc contains the code for parsing + * 802.11 messages. + * Author: Pierre Vandwalle + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "sirApi.h" +#include "aniGlobal.h" +#include "parserApi.h" +#include "cfgApi.h" +#include "limUtils.h" +#include "utilsParser.h" +#include "limSerDesUtils.h" +#include "schApi.h" +#include "palApi.h" +#include "wmmApsd.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + + + +//////////////////////////////////////////////////////////////////////// +void dot11fLog(tpAniSirGlobal pMac, int loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + if( (tANI_U32)loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_DBG_MODULE_ID )] ) + { + return; + } + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_DBG_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + +void +swapBitField16(tANI_U16 in, tANI_U16 *out) +{ +# ifdef ANI_LITTLE_BIT_ENDIAN + *out = in; +# else // Big-Endian... + *out = ( ( in & 0x8000 ) >> 15 ) | + ( ( in & 0x4000 ) >> 13 ) | + ( ( in & 0x2000 ) >> 11 ) | + ( ( in & 0x1000 ) >> 9 ) | + ( ( in & 0x0800 ) >> 7 ) | + ( ( in & 0x0400 ) >> 5 ) | + ( ( in & 0x0200 ) >> 3 ) | + ( ( in & 0x0100 ) >> 1 ) | + ( ( in & 0x0080 ) << 1 ) | + ( ( in & 0x0040 ) << 3 ) | + ( ( in & 0x0020 ) << 5 ) | + ( ( in & 0x0010 ) << 7 ) | + ( ( in & 0x0008 ) << 9 ) | + ( ( in & 0x0004 ) << 11 ) | + ( ( in & 0x0002 ) << 13 ) | + ( ( in & 0x0001 ) << 15 ); +# endif // ANI_LITTLE_BIT_ENDIAN +} + +void +swapBitField32(tANI_U32 in, tANI_U32 *out) +{ +# ifdef ANI_LITTLE_BIT_ENDIAN + *out = in; +# else // Big-Endian... + *out = ( ( in & 0x80000000 ) >> 31 ) | + ( ( in & 0x40000000 ) >> 29 ) | + ( ( in & 0x20000000 ) >> 27 ) | + ( ( in & 0x10000000 ) >> 25 ) | + ( ( in & 0x08000000 ) >> 23 ) | + ( ( in & 0x04000000 ) >> 21 ) | + ( ( in & 0x02000000 ) >> 19 ) | + ( ( in & 0x01000000 ) >> 17 ) | + ( ( in & 0x00800000 ) >> 15 ) | + ( ( in & 0x00400000 ) >> 13 ) | + ( ( in & 0x00200000 ) >> 11 ) | + ( ( in & 0x00100000 ) >> 9 ) | + ( ( in & 0x00080000 ) >> 7 ) | + ( ( in & 0x00040000 ) >> 5 ) | + ( ( in & 0x00020000 ) >> 3 ) | + ( ( in & 0x00010000 ) >> 1 ) | + ( ( in & 0x00008000 ) << 1 ) | + ( ( in & 0x00004000 ) << 3 ) | + ( ( in & 0x00002000 ) << 5 ) | + ( ( in & 0x00001000 ) << 7 ) | + ( ( in & 0x00000800 ) << 9 ) | + ( ( in & 0x00000400 ) << 11 ) | + ( ( in & 0x00000200 ) << 13 ) | + ( ( in & 0x00000100 ) << 15 ) | + ( ( in & 0x00000080 ) << 17 ) | + ( ( in & 0x00000040 ) << 19 ) | + ( ( in & 0x00000020 ) << 21 ) | + ( ( in & 0x00000010 ) << 23 ) | + ( ( in & 0x00000008 ) << 25 ) | + ( ( in & 0x00000004 ) << 27 ) | + ( ( in & 0x00000002 ) << 29 ) | + ( ( in & 0x00000001 ) << 31 ); +# endif // ANI_LITTLE_BIT_ENDIAN +} + +inline static void __printWMMParams(tpAniSirGlobal pMac, tDot11fIEWMMParams *pWmm) +{ + limLog(pMac, LOG1, FL("WMM Parameters Received: \n")); + limLog(pMac, LOG1, FL("BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"), + pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci, pWmm->acbe_acwmin, pWmm->acbe_acwmax, pWmm->acbe_txoplimit); + + limLog(pMac, LOG1, FL("BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"), + pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci, pWmm->acbk_acwmin, pWmm->acbk_acwmax, pWmm->acbk_txoplimit); + + limLog(pMac, LOG1, FL("VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"), + pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci, pWmm->acvi_acwmin, pWmm->acvi_acwmax, pWmm->acvi_txoplimit); + + limLog(pMac, LOG1, FL("VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"), + pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci, pWmm->acvo_acwmin, pWmm->acvo_acwmax, pWmm->acvo_txoplimit); + + return; +} + +//////////////////////////////////////////////////////////////////////// +// Functions for populating "dot11f" style IEs + + +// return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie +// < 0, cannot find +int FindIELocation( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tANI_U8 EID) +{ + int idx, ieLen, bytesLeft; + int ret_val = -1; + + // Here's what's going on: 'rsnIe' looks like this: + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // other code records both the WPA & RSN IEs (including their EIDs & + // lengths) into the array 'rsnIEdata'. We may have: + + // With WAPI support, there may be 3 IEs here + // It can be only WPA IE, or only RSN IE or only WAPI IE + // Or two or all three of them with no particular ordering + + // The if/then/else statements that follow are here to figure out + // whether we have the WPA IE, and where it is if we *do* have it. + + //Save the first IE length + ieLen = pRsnIe->rsnIEdata[ 1 ] + 2; + idx = 0; + bytesLeft = pRsnIe->length; + + while( 1 ) + { + if ( EID == pRsnIe->rsnIEdata[ idx ] ) + { + //Found it + return (idx); + } + else if ( EID != pRsnIe->rsnIEdata[ idx ] && + // & if no more IE, + bytesLeft <= (tANI_U16)( ieLen ) ) + { + dot11fLog( pMac, LOG3, FL("No IE (%d) in FindIELocation.\n"), EID ); + return ret_val; + } + bytesLeft -= ieLen; + ieLen = pRsnIe->rsnIEdata[ idx + 1 ] + 2; + idx += ieLen; + } + + return ret_val; +} + + +tSirRetStatus +PopulateDot11fCapabilities(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpPESession psessionEntry) +{ + tANI_U16 cfg; + tSirRetStatus nSirStatus; + + nSirStatus = cfgGetCapabilityInfo( pMac, &cfg,psessionEntry ); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOGP, FL("Failed to retrieve the Capabilities b" + "itfield from CFG (%d).\n"), nSirStatus ); + return nSirStatus; + } + +#if 0 + if ( sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_11EQOS ) ) + { + SIR_MAC_CLEAR_CAPABILITY( cfg, QOS ); + } +#endif + swapBitField16( cfg, ( tANI_U16* )pDot11f ); + + return eSIR_SUCCESS; +} // End PopulateDot11fCapabilities. + +tSirRetStatus +PopulateDot11fCapabilities2(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + tANI_U16 cfg; + tSirRetStatus nSirStatus; + nSirStatus = cfgGetCapabilityInfo( pMac, &cfg ,psessionEntry); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOGP, FL("Failed to retrieve the Capabilities b" + "itfield from CFG (%d).\n"), nSirStatus ); + return nSirStatus; + } + + if ( ( NULL != pSta ) && pSta->aniPeer && + PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) + { + SIR_MAC_CLEAR_CAPABILITY( cfg, QOS ); + } + + swapBitField16( cfg, ( tANI_U16* )pDot11f ); + + return eSIR_SUCCESS; + +} // End PopulateDot11fCapabilities2. + +void +PopulateDot11fChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->switchMode = psessionEntry->gLimChannelSwitch.switchMode; + pDot11f->newChannel = psessionEntry->gLimChannelSwitch.primaryChannel; + pDot11f->switchCount = ( tANI_U8 ) psessionEntry->gLimChannelSwitch.switchCount; + + pDot11f->present = 1; +} // End PopulateDot11fChanSwitchAnn. + +void +PopulateDot11fExtChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEExtChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + //Has to be updated on the cb state basis + pDot11f->secondaryChannelOffset = + psessionEntry->gLimChannelSwitch.secondarySubBand; + + pDot11f->present = 1; +} + +void +PopulateDot11fChanSwitchWrapper(tpAniSirGlobal pMac, + tDot11fIEChannelSwitchWrapper *pDot11f, + tpPESession psessionEntry) +{ + /* + * The new country subelement is present only when + * 1. AP performs Extended Channel switching to new country. + * 2. New Operating Class table or a changed set of operating + * classes relative to the contents of the country element sent + * in the beacons. + * + * In the current scenario Channel Switch wrapper IE is included + * when we a radar is found and the AP does a channel change in + * the same regulatory domain(No country change or Operating class + * table). So, we do not need to include the New Country IE. + * + * Transmit Power Envlope Subelement is optional + * in Channel Switch Wrapper IE. So, not setting + * the TPE subelement. We include only WiderBWChanSwitchAnn. + */ + pDot11f->present = 1; + + /* + * Add the Wide Channel Bandwidth Sublement. + */ + pDot11f->WiderBWChanSwitchAnn.newChanWidth = + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth; + pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq0 = + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0; + pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq1 = + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1; + pDot11f->WiderBWChanSwitchAnn.present = 1; + +} + +#ifdef WLAN_FEATURE_11AC +void +PopulateDot11fWiderBWChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEWiderBWChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->present = 1; + pDot11f->newChanWidth = psessionEntry->gLimWiderBWChannelSwitch.newChanWidth; + pDot11f->newCenterChanFreq0 = psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0; + pDot11f->newCenterChanFreq1 = psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1; +} +#endif + +tSirRetStatus +PopulateDot11fCountry(tpAniSirGlobal pMac, + tDot11fIECountry *pDot11f, + tpPESession psessionEntry) +{ + tANI_U32 len, maxlen, codelen; + tANI_U16 item; + tSirRetStatus nSirStatus; + tSirRFBand rfBand; + tANI_U8 temp[CFG_MAX_STR_LEN], code[3]; + + if (psessionEntry->lim11dEnabled ) + { + limGetRfBand(pMac, &rfBand, psessionEntry); + if (rfBand == SIR_BAND_5_GHZ) + { + item = WNI_CFG_MAX_TX_POWER_5; + maxlen = WNI_CFG_MAX_TX_POWER_5_LEN; + } + else + { + item = WNI_CFG_MAX_TX_POWER_2_4; + maxlen = WNI_CFG_MAX_TX_POWER_2_4_LEN; + } + + CFG_GET_STR( nSirStatus, pMac, item, temp, len, maxlen ); + + if ( 3 > len ) + { + // no limit on tx power, cannot include the IE because at least + // one (channel,num,tx power) must be present + return eSIR_SUCCESS; + } + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_COUNTRY_CODE, + code, codelen, 3 ); + + vos_mem_copy( pDot11f->country, code, codelen ); + + if(len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) + { + dot11fLog( pMac, LOGE, FL("len:%d is out of bounds, resetting.\n"), len); + len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + } + + pDot11f->num_triplets = ( tANI_U8 ) ( len / 3 ); + vos_mem_copy( ( tANI_U8* )pDot11f->triplets, temp, len ); + + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // End PopulateDot11fCountry. + +tSirRetStatus +PopulateDot11fDSParams(tpAniSirGlobal pMac, + tDot11fIEDSParams *pDot11f, tANI_U8 channel, + tpPESession psessionEntry) +{ + if ((IS_24G_CH(channel)) || pMac->rrm.rrmPEContext.rrmEnable) + { + // .11b/g mode PHY => Include the DS Parameter Set IE: + pDot11f->curr_channel = channel; + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // End PopulateDot11fDSParams. + +#define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn)) + + +void +PopulateDot11fEDCAParamSet(tpAniSirGlobal pMac, + tDot11fIEEDCAParamSet *pDot11f, + tpPESession psessionEntry) +{ + + if ( psessionEntry->limQosEnabled ) + { + //change to bitwise operation, after this is fixed in frames. + pDot11f->qos = (tANI_U8)(0xf0 & (psessionEntry->gLimEdcaParamSetCount << 4) ); + + // Fill each EDCA parameter set in order: be, bk, vi, vo + pDot11f->acbe_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn) ); + pDot11f->acbe_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm ); + pDot11f->acbe_aci = ( 0x3 & SIR_MAC_EDCAACI_BESTEFFORT ); + pDot11f->acbe_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min ); + pDot11f->acbe_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max ); + pDot11f->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit; + + pDot11f->acbk_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn) ); + pDot11f->acbk_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm ); + pDot11f->acbk_aci = ( 0x3 & SIR_MAC_EDCAACI_BACKGROUND ); + pDot11f->acbk_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min ); + pDot11f->acbk_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max ); + pDot11f->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit; + + pDot11f->acvi_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn) ); + pDot11f->acvi_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm ); + pDot11f->acvi_aci = ( 0x3 & SIR_MAC_EDCAACI_VIDEO ); + pDot11f->acvi_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min ); + pDot11f->acvi_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max ); + pDot11f->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit; + + pDot11f->acvo_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn) ); + pDot11f->acvo_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm ); + pDot11f->acvo_aci = ( 0x3 & SIR_MAC_EDCAACI_VOICE ); + pDot11f->acvo_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min ); + pDot11f->acvo_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max ); + pDot11f->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit; + + pDot11f->present = 1; + } + +} // End PopluateDot11fEDCAParamSet. + +tSirRetStatus +PopulateDot11fERPInfo(tpAniSirGlobal pMac, + tDot11fIEERPInfo *pDot11f, + tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 val; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ == rfBand) + { + pDot11f->present = 1; + + val = psessionEntry->cfgProtection.fromllb; + if(!val ){ + dot11fLog( pMac, LOGE, FL("11B protection not enabled. Not populating ERP IE %d\n" ),val ); + return eSIR_SUCCESS; + } + + if (psessionEntry->gLim11bParams.protectionEnabled) + { + pDot11f->non_erp_present = 1; + pDot11f->use_prot = 1; + } + + if ( psessionEntry->gLimOlbcParams.protectionEnabled ) + { + //FIXME_PROTECTION: we should be setting non_erp present also. + //check the test plan first. + pDot11f->use_prot = 1; + } + + + if((psessionEntry->gLimNoShortParams.numNonShortPreambleSta) + || !psessionEntry->beaconParams.fShortPreamble){ + pDot11f->barker_preamble = 1; + + } + // if protection always flag is set, advertise protection enabled + // regardless of legacy stations presence + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_11G_PROTECTION_ALWAYS, val ); + + if ( val ) + { + pDot11f->use_prot = 1; + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fERPInfo. + +tSirRetStatus +PopulateDot11fExtSuppRates(tpAniSirGlobal pMac, tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f, + tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 nRates = 0; + tANI_U8 rates[WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN]; + + /* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL + else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for + sending mgmt frames (lile probe req) which need to go out before any session is present. + */ + if(POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum ) + { + if(psessionEntry != NULL) + { + nRates = psessionEntry->extRateSet.numRates; + vos_mem_copy( rates, psessionEntry->extRateSet.rate, + nRates); + } + else + { + dot11fLog( pMac, LOGE, FL("no session context exists while" + " populating Operational Rate Set\n")); + } + } + else if ( HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum ) + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + rates, nRates, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN ); + } + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 )nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fExtSuppRates. + +tSirRetStatus +PopulateDot11fExtSuppRates1(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f) +{ + tANI_U32 nRates; + tSirRetStatus nSirStatus; + tANI_U8 rates[SIR_MAC_MAX_NUMBER_OF_RATES]; + + if ( 14 < nChannelNum ) + { + pDot11f->present = 0; + return eSIR_SUCCESS; + } + + // N.B. I have *no* idea why we're calling 'wlan_cfgGetStr' with an argument + // of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done + // previously & I'm afraid to change it! + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 ) nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // PopulateDot11fExtSuppRates1. + +tSirRetStatus +PopulateDot11fHTCaps(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEHTCaps *pDot11f) +{ + tANI_U32 nCfgValue, nCfgLen; + tANI_U8 nCfgValue8; + tSirRetStatus nSirStatus; + tSirMacHTParametersInfo *pHTParametersInfo; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + tSirMacExtendedHTCapabilityInfo extHtCapInfo; + } uHTCapabilityInfo; + + tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; + tSirMacASCapabilityInfo *pASCapabilityInfo; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_CAP_INFO, nCfgValue ); + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave; + pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField; + pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA; + pDot11f->maximalAMSDUsize = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize; + pDot11f->dsssCckMode40MHz = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz; + pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp; + pDot11f->stbcControlFrame = uHTCapabilityInfo.htCapInfo.stbcControlFrame; + pDot11f->lsigTXOPProtection = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection; + + // All sessionized entries will need the check below + if (psessionEntry == NULL) // Only in case of NO session + { + pDot11f->supportedChannelWidthSet = uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet; + pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap; + pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC; + pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC; + pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz; + pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz; + } + else + { + pDot11f->advCodingCap = psessionEntry->htConfig.ht_rx_ldpc; + pDot11f->supportedChannelWidthSet = psessionEntry->htSupportedChannelWidthSet; + pDot11f->txSTBC = psessionEntry->htConfig.ht_tx_stbc; + pDot11f->rxSTBC = psessionEntry->htConfig.ht_rx_stbc; + if (psessionEntry->htConfig.ht_sgi) { + pDot11f->shortGI20MHz = + uHTCapabilityInfo.htCapInfo.shortGI20MHz; + pDot11f->shortGI40MHz = + uHTCapabilityInfo.htCapInfo.shortGI40MHz; + } + } + + /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is + eHT_CHANNEL_WIDTH_20MHZ */ + if(pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) + { + pDot11f->shortGI40MHz = 0; + } + + dot11fLog(pMac, LOG2, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d\n"), + pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave, pDot11f->greenField, + pDot11f->shortGI20MHz, pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz); + + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue ); + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + pHTParametersInfo = ( tSirMacHTParametersInfo* ) &nCfgValue8; + + pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; + pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; + pDot11f->reserved1 = pHTParametersInfo->reserved; + + dot11fLog( pMac, LOG2, FL( "AMPDU Param: %x\n" ), nCfgValue); + + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET, + pDot11f->supportedMCSSet, nCfgLen, + SIZE_OF_SUPPORTED_MCS_SET ); + + if (psessionEntry) + { + if (pMac->lteCoexAntShare && (IS_24G_CH(psessionEntry->currentOperChannel))) + { + if(!(IS_2X2_CHAIN(psessionEntry->chainMask))) + { + pDot11f->supportedMCSSet[1] = 0; + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + pDot11f->mimoPowerSave = psessionEntry->smpsMode; + } + } + } + } + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue ); + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; + pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; + pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; + + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_TX_BF_CAP, nCfgValue ); + + pTxBFCapabilityInfo = ( tSirMacTxBFCapabilityInfo* ) &nCfgValue; + pDot11f->txBF = pTxBFCapabilityInfo->txBF; + pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; + pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; + pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; + pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; + pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; + pDot11f->calibration = pTxBFCapabilityInfo->calibration; + pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; + pDot11f->explicitUncompressedSteeringMatrix = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; + pDot11f->explicitBFCSIFeedback = pTxBFCapabilityInfo->explicitBFCSIFeedback; + pDot11f->explicitUncompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; + pDot11f->explicitCompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; + pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; + pDot11f->uncompressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; + pDot11f->compressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_AS_CAP, nCfgValue ); + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + + pASCapabilityInfo = ( tSirMacASCapabilityInfo* ) &nCfgValue8; + pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; + pDot11f->explicitCSIFeedbackTx = pASCapabilityInfo->explicitCSIFeedbackTx; + pDot11f->antennaIndicesFeedbackTx = pASCapabilityInfo->antennaIndicesFeedbackTx; + pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; + pDot11f->antennaIndicesFeedback = pASCapabilityInfo->antennaIndicesFeedback; + pDot11f->rxAS = pASCapabilityInfo->rxAS; + pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fHTCaps. +#ifdef WLAN_FEATURE_11AC + +void limLogVHTCap(tpAniSirGlobal pMac, + tDot11fIEVHTCaps *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("maxMPDULen (2): %d\n"), pDot11f->maxMPDULen); + limLog(pMac, LOG1, FL("supportedChannelWidthSet (2): %d\n"), pDot11f->supportedChannelWidthSet); + limLog(pMac, LOG1, FL("ldpcCodingCap (1): %d\n"), pDot11f->ldpcCodingCap); + limLog(pMac, LOG1, FL("shortGI80MHz (1): %d\n"), pDot11f->shortGI80MHz); + limLog(pMac, LOG1, FL("shortGI160and80plus80MHz (1): %d\n"), pDot11f->shortGI160and80plus80MHz); + limLog(pMac, LOG1, FL("txSTBC (1): %d\n"), pDot11f->txSTBC); + limLog(pMac, LOG1, FL("rxSTBC (3): %d\n"), pDot11f->rxSTBC); + limLog(pMac, LOG1, FL("suBeamFormerCap (1): %d\n"), pDot11f->suBeamFormerCap); + limLog(pMac, LOG1, FL("suBeamformeeCap (1): %d\n"), pDot11f->suBeamformeeCap); + limLog(pMac, LOG1, FL("csnofBeamformerAntSup (3): %d\n"), pDot11f->csnofBeamformerAntSup); + limLog(pMac, LOG1, FL("numSoundingDim (3): %d\n"), pDot11f->numSoundingDim); + limLog(pMac, LOG1, FL("muBeamformerCap (1): %d\n"), pDot11f->muBeamformerCap); + limLog(pMac, LOG1, FL("muBeamformeeCap (1): %d\n"), pDot11f->muBeamformeeCap); + limLog(pMac, LOG1, FL("vhtTXOPPS (1): %d\n"), pDot11f->vhtTXOPPS); + limLog(pMac, LOG1, FL("htcVHTCap (1): %d\n"), pDot11f->htcVHTCap); + limLog(pMac, LOG1, FL("maxAMPDULenExp (3): %d\n"), pDot11f->maxAMPDULenExp); + limLog(pMac, LOG1, FL("vhtLinkAdaptCap (2): %d\n"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("rxAntPattern (1): %d\n"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("txAntPattern (1): %d\n"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("reserved1 (2): %d\n"), pDot11f->reserved1); + limLog(pMac, LOG1, FL("rxMCSMap (16): %d\n"), pDot11f->rxMCSMap); + limLog(pMac, LOG1, FL("rxHighSupDataRate (13): %d\n"), pDot11f->rxHighSupDataRate); + limLog(pMac, LOG1, FL("reserve (3): %d\n"), pDot11f->reserved2); + limLog(pMac, LOG1, FL("txMCSMap (16): %d\n"), pDot11f->txMCSMap); + limLog(pMac, LOG1, FL("txSupDataRate (13): %d\n"), pDot11f->txSupDataRate); + limLog(pMac, LOG1, FL("reserv (3): %d\n"), pDot11f->reserved3); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogVHTOperation(tpAniSirGlobal pMac, + tDot11fIEVHTOperation *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("chanWidth : %d\n"), pDot11f->chanWidth); + limLog(pMac, LOG1, FL("chanCenterFreqSeg1: %d\n"), pDot11f->chanCenterFreqSeg1); + limLog(pMac, LOG1, FL("chanCenterFreqSeg2: %d\n"), pDot11f->chanCenterFreqSeg2); + limLog(pMac, LOG1, FL("basicMCSSet: %d\n"), pDot11f->basicMCSSet); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogVHTExtBssLoad(tpAniSirGlobal pMac, + tDot11fIEVHTExtBssLoad *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("muMIMOCapStaCount : %d\n"), pDot11f->muMIMOCapStaCount); + limLog(pMac, LOG1, FL("ssUnderUtil: %d\n"), pDot11f->ssUnderUtil); + limLog(pMac, LOG1, FL("FortyMHzUtil: %d\n"), pDot11f->FortyMHzUtil); + limLog(pMac, LOG1, FL("EightyMHzUtil: %d\n"), pDot11f->EightyMHzUtil); + limLog(pMac, LOG1, FL("OneSixtyMHzUtil: %d\n"), pDot11f->OneSixtyMHzUtil); +#endif /* DUMP_MGMT_CNTNTS */ +} + + +void limLogOperatingMode( tpAniSirGlobal pMac, + tDot11fIEOperatingMode *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("ChanWidth : %d\n"), pDot11f->chanWidth); + limLog(pMac, LOG1, FL("reserved: %d\n"), pDot11f->reserved); + limLog(pMac, LOG1, FL("rxNSS: %d\n"), pDot11f->rxNSS); + limLog(pMac, LOG1, FL("rxNSS Type: %d\n"), pDot11f->rxNSSType); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogQosMapSet(tpAniSirGlobal pMac, tSirQosMapSet *pQosMapSet) +{ + tANI_U8 i; + limLog(pMac, LOG1, FL("num of dscp exceptions : %d"), + pQosMapSet->num_dscp_exceptions); + for (i = 0; i < pQosMapSet->num_dscp_exceptions; i++) + { + limLog(pMac, LOG1, FL("dscp value: %d"), + pQosMapSet->dscp_exceptions[i][0]); + limLog(pMac, LOG1, FL("User priority value: %d"), + pQosMapSet->dscp_exceptions[i][1]); + } + for (i = 0; i < 8; i++) + { + limLog(pMac, LOG1, FL("dscp low for up %d: %d"),i, + pQosMapSet->dscp_range[i][0]); + limLog(pMac, LOG1, FL("dscp high for up %d: %d"),i, + pQosMapSet->dscp_range[i][1]); + } +} + +tSirRetStatus +PopulateDot11fVHTCaps(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pDot11f) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MAX_MPDU_LENGTH, nCfgValue ); + pDot11f->maxMPDULen = (nCfgValue & 0x0003); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + nCfgValue ); + pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003); + + nCfgValue = 0; + //With VHT it suffices if we just examine HT + if (psessionEntry) + { + if (psessionEntry->htConfig.ht_rx_ldpc) + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP, + nCfgValue ); + + pDot11f->ldpcCodingCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + if (psessionEntry->htConfig.ht_sgi) + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ, + nCfgValue ); + + pDot11f->shortGI80MHz= (nCfgValue & 0x0001); + + nCfgValue = 0; + if (psessionEntry->htConfig.ht_sgi) + CFG_GET_INT( nStatus, pMac, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + nCfgValue ); + + pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001); + + nCfgValue = 0; + if (psessionEntry->htConfig.ht_tx_stbc) + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TXSTBC, nCfgValue ); + + pDot11f->txSTBC = (nCfgValue & 0x0001); + + nCfgValue = 0; + if (psessionEntry->htConfig.ht_rx_stbc) + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RXSTBC, nCfgValue ); + + pDot11f->rxSTBC = (nCfgValue & 0x0007); + + pDot11f->suBeamformeeCap = psessionEntry->txBFIniFeatureEnabled; + if (psessionEntry->txBFIniFeatureEnabled) { + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + nCfgValue ); + pDot11f->muBeamformeeCap = (nCfgValue & 0x0001); + } else { + pDot11f->muBeamformeeCap = 0; + } + } + else + { + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP, nCfgValue ); + pDot11f->ldpcCodingCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ, nCfgValue ); + pDot11f->shortGI80MHz= (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + nCfgValue ); + pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TXSTBC, nCfgValue ); + pDot11f->txSTBC = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RXSTBC, nCfgValue ); + pDot11f->rxSTBC = (nCfgValue & 0x0007); + + pDot11f->suBeamformeeCap = 0; + pDot11f->muBeamformeeCap = 0; + } + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SU_BEAMFORMER_CAP, nCfgValue ); + pDot11f->suBeamFormerCap = (nCfgValue & 0x0001); + + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + nCfgValue ); + pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS, + nCfgValue ); + pDot11f->numSoundingDim = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMER_CAP, nCfgValue ); + pDot11f->muBeamformerCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TXOP_PS, nCfgValue ); + pDot11f->vhtTXOPPS = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_HTC_VHTC_CAP, nCfgValue ); + pDot11f->htcVHTCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, nCfgValue ); + pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_LINK_ADAPTATION_CAP, nCfgValue ); + pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_ANT_PATTERN, nCfgValue ); + pDot11f->rxAntPattern = nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_ANT_PATTERN, nCfgValue ); + pDot11f->txAntPattern = nCfgValue; + + pDot11f->reserved1= 0; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_MCS_MAP, nCfgValue ); + pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + nCfgValue ); + pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF); + + pDot11f->reserved2= 0; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_MCS_MAP, nCfgValue ); + pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF); + if (psessionEntry) + { + if (pMac->lteCoexAntShare && (IS_24G_CH(psessionEntry->currentOperChannel))) + { + if(!(IS_2X2_CHAIN(psessionEntry->chainMask))) + { + pDot11f->txMCSMap |= DISABLE_NSS2_MCS; + pDot11f->rxMCSMap |= DISABLE_NSS2_MCS; + } + } + } + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + nCfgValue ); + pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF); + + pDot11f->reserved3= 0; + + limLogVHTCap(pMac, pDot11f); + + return eSIR_SUCCESS; + +} + +tSirRetStatus +PopulateDot11fVHTOperation(tpAniSirGlobal pMac, + tDot11fIEVHTOperation *pDot11f) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_WIDTH, nCfgValue ); + pDot11f->chanWidth = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + nCfgValue ); + pDot11f->chanCenterFreqSeg1 = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2, + nCfgValue ); + pDot11f->chanCenterFreqSeg2 = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_BASIC_MCS_SET,nCfgValue ); + pDot11f->basicMCSSet = (tANI_U16)nCfgValue; + + limLogVHTOperation(pMac,pDot11f); + + return eSIR_SUCCESS; + +} + +tSirRetStatus +PopulateDot11fVHTExtBssLoad(tpAniSirGlobal pMac, + tDot11fIEVHTExtBssLoad *pDot11f) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT, + nCfgValue ); + pDot11f->muMIMOCapStaCount = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SS_UNDER_UTIL,nCfgValue ); + pDot11f->ssUnderUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_40MHZ_UTILIZATION,nCfgValue ); + pDot11f->FortyMHzUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_80MHZ_UTILIZATION,nCfgValue ); + pDot11f->EightyMHzUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_160MHZ_UTILIZATION,nCfgValue ); + pDot11f->EightyMHzUtil = (tANI_U8)nCfgValue; + + limLogVHTExtBssLoad(pMac,pDot11f); + + return eSIR_SUCCESS; +} + +tSirRetStatus +PopulateDot11fExtCap(tpAniSirGlobal pMac, + tANI_BOOLEAN isVHTEnabled, + tDot11fIEExtCap *pDot11f, tpPESession psessionEntry) +{ + tANI_U32 val=0; + struct s_ext_cap *p_ext_cap; + + pDot11f->present = 1; + + if (psessionEntry->sap_dot11mc) { + PELOGE(limLog(pMac, LOG1, + FL("11MC support enabled"));) + pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; + } else { + if (eLIM_AP_ROLE != psessionEntry->limSystemRole) { + PELOGE(limLog(pMac, LOG1, + FL("11MC support enabled"));) + pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; + } else { + PELOGE(limLog(pMac, LOG1, + FL("11MC support disabled"));) + pDot11f->num_bytes = DOT11F_IE_EXTCAP_MIN_LEN; + } + } + + p_ext_cap = (struct s_ext_cap *)pDot11f->bytes; +#ifdef WLAN_FEATURE_11AC + if (isVHTEnabled == eANI_BOOLEAN_TRUE) + { + p_ext_cap->operModeNotification = 1; + } +#endif + + if (wlan_cfgGetInt(pMac, WNI_CFG_RTT3_ENABLE, &val) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve RTT3 Variable from DAT File \n"));) + return eSIR_FAILURE; + } + + if (val) // If set to true then set RTTv3 + { + p_ext_cap->fineTimingMeas = 1; + } + +#ifdef QCA_HT_2040_COEX + if (pMac->roam.configParam.obssEnabled) + { + p_ext_cap->bssCoexistMgmtSupport = 1; + } +#endif + return eSIR_SUCCESS; +} + +tSirRetStatus +PopulateDot11fOperatingMode(tpAniSirGlobal pMac, + tDot11fIEOperatingMode *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->present = 1; + + pDot11f->chanWidth = psessionEntry->gLimOperatingMode.chanWidth; + pDot11f->rxNSS = psessionEntry->gLimOperatingMode.rxNSS; + pDot11f->rxNSSType = psessionEntry->gLimOperatingMode.rxNSSType; + + return eSIR_SUCCESS; +} + +#endif +tSirRetStatus +PopulateDot11fHTInfo(tpAniSirGlobal pMac, + tDot11fIEHTInfo *pDot11f, + tpPESession psessionEntry ) +{ + tANI_U32 nCfgValue, nCfgLen; + tANI_U8 htInfoField1; + tANI_U16 htInfoField2; + tSirRetStatus nSirStatus; + tSirMacHTInfoField1 *pHTInfoField1; + tSirMacHTInfoField2 *pHTInfoField2; + union { + tANI_U16 nCfgValue16; + tSirMacHTInfoField3 infoField3; + }uHTInfoField; + union { + tANI_U16 nCfgValue16; + tSirMacHTInfoField2 infoField2; + }uHTInfoField2={0}; + + + #if 0 + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_CURRENT_CHANNEL, nCfgValue ); + #endif // TO SUPPORT BT-AMP + + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOG1, + FL("Invalid session entry in PopulateDot11fHTInfo()\n"));) + return eSIR_FAILURE; + } + + pDot11f->primaryChannel = psessionEntry->currentOperChannel; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD1, nCfgValue ); + + htInfoField1 = ( tANI_U8 ) nCfgValue; + + pHTInfoField1 = ( tSirMacHTInfoField1* ) &htInfoField1; + pHTInfoField1->rifsMode = psessionEntry->beaconParams.fRIFSMode; + pHTInfoField1->serviceIntervalGranularity = pMac->lim.gHTServiceIntervalGranularity; + + if (psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOG1, + FL("Keep the value retrieved from cfg for secondary channel offset and recommended Tx Width set\n"));) + } + else + { + pHTInfoField1->secondaryChannelOffset = psessionEntry->htSecondaryChannelOffset; + pHTInfoField1->recommendedTxWidthSet = psessionEntry->htRecommendedTxWidthSet; + } + + if((psessionEntry) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)){ + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, nCfgValue ); + + uHTInfoField2.nCfgValue16 = nCfgValue & 0xFFFF; // this is added for fixing CRs on MDM9K platform - 257951, 259577 + + uHTInfoField2.infoField2.opMode = psessionEntry->htOperMode; + uHTInfoField2.infoField2.nonGFDevicesPresent = psessionEntry->beaconParams.llnNonGFCoexist; + uHTInfoField2.infoField2.obssNonHTStaPresent = psessionEntry->beaconParams.gHTObssMode; /*added for Obss */ + + uHTInfoField2.infoField2.reserved = 0; + + }else{ + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, nCfgValue ); + + htInfoField2 = ( tANI_U16 ) nCfgValue; + + pHTInfoField2 = ( tSirMacHTInfoField2* ) &htInfoField2; + pHTInfoField2->opMode = pMac->lim.gHTOperMode; + pHTInfoField2->nonGFDevicesPresent = pMac->lim.gHTNonGFDevicesPresent; + pHTInfoField2->obssNonHTStaPresent = pMac->lim.gHTObssMode; /*added for Obss */ + + pHTInfoField2->reserved = 0; + } + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD3, nCfgValue ); + + + uHTInfoField.nCfgValue16 = nCfgValue & 0xFFFF; + + + uHTInfoField.infoField3.basicSTBCMCS = pMac->lim.gHTSTBCBasicMCS; + uHTInfoField.infoField3.dualCTSProtection = pMac->lim.gHTDualCTSProtection; + uHTInfoField.infoField3.secondaryBeacon = pMac->lim.gHTSecondaryBeacon; + uHTInfoField.infoField3.lsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport; + uHTInfoField.infoField3.pcoActive = pMac->lim.gHTPCOActive; + uHTInfoField.infoField3.pcoPhase = pMac->lim.gHTPCOPhase; + uHTInfoField.infoField3.reserved = 0; + + + pDot11f->secondaryChannelOffset = pHTInfoField1->secondaryChannelOffset; + pDot11f->recommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet; + pDot11f->rifsMode = pHTInfoField1->rifsMode; + pDot11f->controlledAccessOnly = pHTInfoField1->controlledAccessOnly; + pDot11f->serviceIntervalGranularity = pHTInfoField1->serviceIntervalGranularity; + + pDot11f->opMode = uHTInfoField2.infoField2.opMode; + pDot11f->nonGFDevicesPresent = uHTInfoField2.infoField2.nonGFDevicesPresent; + pDot11f->obssNonHTStaPresent = uHTInfoField2.infoField2.obssNonHTStaPresent; + pDot11f->reserved = uHTInfoField2.infoField2.reserved; + + + pDot11f->basicSTBCMCS = uHTInfoField.infoField3.basicSTBCMCS; + pDot11f->dualCTSProtection = uHTInfoField.infoField3.dualCTSProtection; + pDot11f->secondaryBeacon = uHTInfoField.infoField3.secondaryBeacon; + pDot11f->lsigTXOPProtectionFullSupport = uHTInfoField.infoField3.lsigTXOPProtectionFullSupport; + pDot11f->pcoActive = uHTInfoField.infoField3.pcoActive; + pDot11f->pcoPhase = uHTInfoField.infoField3.pcoPhase; + pDot11f->reserved2 = uHTInfoField.infoField3.reserved; + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_BASIC_MCS_SET, + pDot11f->basicMCSSet, nCfgLen, + SIZE_OF_BASIC_MCS_SET ); + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fHTInfo. + +void +PopulateDot11fIBSSParams(tpAniSirGlobal pMac, + tDot11fIEIBSSParams *pDot11f, tpPESession psessionEntry) +{ + tANI_U32 val = 0; + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + if(wlan_cfgGetInt(pMac, + WNI_CFG_IBSS_ATIM_WIN_SIZE, &val) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, + FL("could not retrieve IBSS ATIM WIN size"));) + } + pDot11f->present = 1; + // ATIM duration is always set to 0 + pDot11f->atim = val; + } + +} // End PopulateDot11fIBSSParams. + + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +PopulateDot11fMeasurementReport0(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport0. + +tSirRetStatus +PopulateDot11fMeasurementReport1(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport1. + +tSirRetStatus +PopulateDot11fMeasurementReport2(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport2. +#endif + +void +PopulateDot11fPowerCaps(tpAniSirGlobal pMac, + tDot11fIEPowerCaps *pCaps, + tANI_U8 nAssocType, + tpPESession psessionEntry) +{ + if (nAssocType == LIM_REASSOC) + { + pCaps->minTxPower = psessionEntry->pLimReAssocReq->powerCap.minTxPower; + pCaps->maxTxPower = psessionEntry->pLimReAssocReq->powerCap.maxTxPower; + }else + { + pCaps->minTxPower = psessionEntry->pLimJoinReq->powerCap.minTxPower; + pCaps->maxTxPower = psessionEntry->pLimJoinReq->powerCap.maxTxPower; + + } + + pCaps->present = 1; +} // End PopulateDot11fPowerCaps. + +tSirRetStatus +PopulateDot11fPowerConstraints(tpAniSirGlobal pMac, + tDot11fIEPowerConstraints *pDot11f) +{ + tANI_U32 cfg; + tSirRetStatus nSirStatus; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, cfg ); + + pDot11f->localPowerConstraints = ( tANI_U8 )cfg; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} // End PopulateDot11fPowerConstraints. + +void +PopulateDot11fQOSCapsAp(tpAniSirGlobal pMac, + tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry) +{ + pDot11f->count = psessionEntry->gLimEdcaParamSetCount; + pDot11f->reserved = 0; + pDot11f->txopreq = 0; + pDot11f->qreq = 0; + pDot11f->qack = 0; + pDot11f->present = 1; +} // End PopulatedDot11fQOSCaps. + +void +PopulateDot11fQOSCapsStation(tpAniSirGlobal pMac, + tDot11fIEQOSCapsStation *pDot11f) +{ + tANI_U32 val = 0; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max SP Length \n"));) + + pDot11f->more_data_ack = 0; + pDot11f->max_sp_length = (tANI_U8)val; + pDot11f->qack = 0; + + if (pMac->lim.gUapsdEnable) + { + pDot11f->acbe_uapsd = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acbk_uapsd = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acvi_uapsd = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acvo_uapsd = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + pDot11f->present = 1; +} // End PopulatedDot11fQOSCaps. + +tSirRetStatus +PopulateDot11fRSN(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSN *pDot11f) +{ + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_RSN ) ) ) + { + status = dot11fUnpackIeRSN( pMac, + pRsnIe->rsnIEdata + idx + 2, //EID, length + pRsnIe->rsnIEdata[ idx + 1 ], + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fRS" + "N (0x%08x).\n"), + status ); + return eSIR_FAILURE; + } + dot11fLog( pMac, LOG2, FL("dot11fUnpackIeRSN returned 0x%08x in " + "PopulateDot11fRSN.\n"), status ); + } + + } + + return eSIR_SUCCESS; +} // End PopulateDot11fRSN. + +tSirRetStatus PopulateDot11fRSNOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSNOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_RSN ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ]; + vos_mem_copy( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2, // EID, len + pRsnIe->rsnIEdata[ idx + 1 ] ); + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fRSNOpaque. + + + +#if defined(FEATURE_WLAN_WAPI) + +tSirRetStatus +PopulateDot11fWAPI(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPI *pDot11f) + { + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WAPI ) ) ) + { + status = dot11fUnpackIeWAPI( pMac, + pRsnIe->rsnIEdata + idx + 2, //EID, length + pRsnIe->rsnIEdata[ idx + 1 ], + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fWAPI (0x%08x).\n"), + status ); + return eSIR_FAILURE; + } + dot11fLog( pMac, LOG2, FL("dot11fUnpackIeRSN returned 0x%08x in " + "PopulateDot11fWAPI.\n"), status ); + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fWAPI. + +tSirRetStatus PopulateDot11fWAPIOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPIOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WAPI ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ]; + vos_mem_copy ( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2, // EID, len + pRsnIe->rsnIEdata[ idx + 1 ] ); + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fWAPIOpaque. + + +#endif //defined(FEATURE_WLAN_WAPI) + +void +PopulateDot11fSSID(tpAniSirGlobal pMac, + tSirMacSSid *pInternal, + tDot11fIESSID *pDot11f) +{ + pDot11f->present = 1; + pDot11f->num_ssid = pInternal->length; + if ( pInternal->length ) + { + vos_mem_copy( ( tANI_U8* )pDot11f->ssid, ( tANI_U8* )&pInternal->ssId, + pInternal->length ); + } +} // End PopulateDot11fSSID. + +tSirRetStatus +PopulateDot11fSSID2(tpAniSirGlobal pMac, + tDot11fIESSID *pDot11f) +{ + tANI_U32 nCfg; + tSirRetStatus nSirStatus; + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SSID, pDot11f->ssid, nCfg, 32 ); + pDot11f->num_ssid = ( tANI_U8 )nCfg; + pDot11f->present = 1; + return eSIR_SUCCESS; +} // End PopulateDot11fSSID2. + +void +PopulateDot11fSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIESchedule *pDot11f) +{ + pDot11f->aggregation = pSchedule->info.aggregation; + pDot11f->tsid = pSchedule->info.tsid; + pDot11f->direction = pSchedule->info.direction; + pDot11f->reserved = pSchedule->info.rsvd; + pDot11f->service_start_time = pSchedule->svcStartTime; + pDot11f->service_interval = pSchedule->svcInterval; + pDot11f->max_service_dur = pSchedule->maxSvcDuration; + pDot11f->spec_interval = pSchedule->specInterval; + + pDot11f->present = 1; +} // End PopulateDot11fSchedule. + +void +PopulateDot11fSuppChannels(tpAniSirGlobal pMac, + tDot11fIESuppChannels *pDot11f, + tANI_U8 nAssocType, + tpPESession psessionEntry) +{ + tANI_U8 i; + tANI_U8 *p; + + if (nAssocType == LIM_REASSOC) + { + p = ( tANI_U8* )psessionEntry->pLimReAssocReq->supportedChannels.channelList; + pDot11f->num_bands = psessionEntry->pLimReAssocReq->supportedChannels.numChnl; + }else + { + p = ( tANI_U8* )psessionEntry->pLimJoinReq->supportedChannels.channelList; + pDot11f->num_bands = psessionEntry->pLimJoinReq->supportedChannels.numChnl; + } + for ( i = 0U; i < pDot11f->num_bands; ++i, ++p) + { + pDot11f->bands[i][0] = *p; + pDot11f->bands[i][1] = 1; + } + + pDot11f->present = 1; + +} // End PopulateDot11fSuppChannels. + +tSirRetStatus +PopulateDot11fSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIESuppRates *pDot11f,tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 nRates; + tANI_U8 rates[SIR_MAC_MAX_NUMBER_OF_RATES]; + + /* Use the operational rates present in session entry whenever nChannelNum is set to OPERATIONAL + else use the supported rate set from CFG, which is fixed and does not change dynamically and is used for + sending mgmt frames (lile probe req) which need to go out before any session is present. + */ + if(POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum ) + { + #if 0 + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_OPERATIONAL_RATE_SET, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + #endif //TO SUPPORT BT-AMP + if(psessionEntry != NULL) + { + nRates = psessionEntry->rateSet.numRates; + vos_mem_copy( rates, psessionEntry->rateSet.rate, + nRates); + } + else + { + dot11fLog( pMac, LOGE, FL("no session context exists while populating Operational Rate Set\n")); + nRates = 0; + } + } + else if ( 14 >= nChannelNum ) + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11B, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + } + else + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + } + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 )nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fSuppRates. + +/** + * populate_dot11f_rates_tdls() - populate supported rates and + * extended supported rates IE. + * @p_mac gloabl - header. + * @p_supp_rates - pointer to supported rates IE + * @p_ext_supp_rates - pointer to extended supported rates IE + * + * This function populates the supported rates and extended supported + * rates IE based in the STA capability. If the number of rates + * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates + * IE is populated. + * + * Return: tSirRetStatus eSIR_SUCCESS on Success and eSIR_FAILURE + * on failure. + */ + +tSirRetStatus +populate_dot11f_rates_tdls(tpAniSirGlobal p_mac, + tDot11fIESuppRates *p_supp_rates, + tDot11fIEExtSuppRates *p_ext_supp_rates) +{ + tSirMacRateSet temp_rateset; + tSirMacRateSet temp_rateset2; + uint32_t val, i; + uint32_t self_dot11mode = 0; + + wlan_cfgGetInt(p_mac, WNI_CFG_DOT11_MODE, &self_dot11mode); + + /** + * Include 11b rates only when the device configured in + * auto, 11a/b/g or 11b_only + */ + if ((self_dot11mode == WNI_CFG_DOT11_MODE_ALL) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11A) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11AC) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11N) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11G) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11B) ) { + val = WNI_CFG_SUPPORTED_RATES_11B_LEN; + wlan_cfgGetStr(p_mac, WNI_CFG_SUPPORTED_RATES_11B, + (tANI_U8 *)&temp_rateset.rate, &val); + temp_rateset.numRates = (tANI_U8) val; + } + else { + temp_rateset.numRates = 0; + } + + /* Include 11a rates when the device configured in non-11b mode */ + if (!IS_DOT11_MODE_11B(self_dot11mode)) { + val = WNI_CFG_SUPPORTED_RATES_11A_LEN; + wlan_cfgGetStr(p_mac, WNI_CFG_SUPPORTED_RATES_11A, + (tANI_U8 *)&temp_rateset2.rate, &val); + temp_rateset2.numRates = (tANI_U8) val; + } else { + temp_rateset2.numRates = 0; + } + + if ((temp_rateset.numRates + temp_rateset2.numRates) > + SIR_MAC_MAX_NUMBER_OF_RATES) { + limLog(p_mac, LOGP, FL("more than %d rates in CFG"), + SIR_MAC_MAX_NUMBER_OF_RATES); + return eSIR_FAILURE; + } + + /** + * copy all rates in temp_rateset, + * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max + */ + for (i = 0; i < temp_rateset2.numRates; i++) + temp_rateset.rate[i + temp_rateset.numRates] = + temp_rateset2.rate[i]; + + temp_rateset.numRates += temp_rateset2.numRates; + + if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) { + p_supp_rates->num_rates = temp_rateset.numRates; + vos_mem_copy(p_supp_rates->rates, temp_rateset.rate, + p_supp_rates->num_rates); + p_supp_rates->present = 1; + } else { /* Populate extended capability as well */ + p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(p_supp_rates->rates, temp_rateset.rate, + p_supp_rates->num_rates); + p_supp_rates->present = 1; + + p_ext_supp_rates->num_rates = temp_rateset.numRates - + MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(p_ext_supp_rates->rates, + (tANI_U8 *)temp_rateset.rate + + MAX_NUM_SUPPORTED_RATES, + p_ext_supp_rates->num_rates); + p_ext_supp_rates->present = 1; + } + + return eSIR_SUCCESS; + +} /* End populate_dot11f_rates_tdls */ + +tSirRetStatus +PopulateDot11fTPCReport(tpAniSirGlobal pMac, + tDot11fIETPCReport *pDot11f, + tpPESession psessionEntry) +{ + tANI_U16 staid, txPower; + tSirRetStatus nSirStatus; + + nSirStatus = limGetMgmtStaid( pMac, &staid, psessionEntry); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOG1, FL("Failed to get the STAID in Populat" + "eDot11fTPCReport; limGetMgmtStaid " + "returned status %d.\n"), + nSirStatus ); + return eSIR_FAILURE; + } + + // FramesToDo: This function was "misplaced" in the move to Gen4_TVM... + // txPower = halGetRateToPwrValue( pMac, staid, pMac->lim.gLimCurrentChannelId, isBeacon ); + txPower = 0; + pDot11f->tx_power = ( tANI_U8 )txPower; + pDot11f->link_margin = 0; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} // End PopulateDot11fTPCReport. + + +void PopulateDot11fTSInfo(tSirMacTSInfo *pInfo, + tDot11fFfTSInfo *pDot11f) +{ + pDot11f->traffic_type = pInfo->traffic.trafficType; + pDot11f->tsid = pInfo->traffic.tsid; + pDot11f->direction = pInfo->traffic.direction; + pDot11f->access_policy = pInfo->traffic.accessPolicy; + pDot11f->aggregation = pInfo->traffic.aggregation; + pDot11f->psb = pInfo->traffic.psb; + pDot11f->user_priority = pInfo->traffic.userPrio; + pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy; + pDot11f->schedule = pInfo->schedule.schedule; +} // End PopulatedDot11fTSInfo. + +void PopulateDot11fWMM(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tDot11fIEWMMParams *pParams, + tDot11fIEWMMCaps *pCaps, + tpPESession psessionEntry) +{ + if ( psessionEntry->limWmeEnabled ) + { + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + //if ( ! sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_WME ) ) + { + PopulateDot11fWMMInfoAp( pMac, pInfo, psessionEntry ); + } + } + else + { + { + PopulateDot11fWMMParams( pMac, pParams, psessionEntry); + } + + if ( psessionEntry->limWsmEnabled ) + { + PopulateDot11fWMMCaps( pCaps ); + } + } + } +} // End PopulateDot11fWMM. + +void PopulateDot11fWMMCaps(tDot11fIEWMMCaps *pCaps) +{ + pCaps->version = SIR_MAC_OUI_VERSION_1; + pCaps->qack = 0; + pCaps->queue_request = 1; + pCaps->txop_request = 0; + pCaps->more_ack = 0; + pCaps->present = 1; +} // End PopulateDot11fWmmCaps. + +#ifdef FEATURE_WLAN_ESE +void PopulateDot11fReAssocTspec(tpAniSirGlobal pMac, tDot11fReAssocRequest *pReassoc, tpPESession psessionEntry) +{ + tANI_U8 numTspecs = 0, idx; + tTspecInfo *pTspec = NULL; + + numTspecs = psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs; + pTspec = &psessionEntry->pLimReAssocReq->eseTspecInfo.tspec[0]; + pReassoc->num_WMMTSPEC = numTspecs; + if (numTspecs) { + for (idx=0; idxtspec, &pReassoc->WMMTSPEC[idx]); + pTspec++; + } + } +} +#endif + +void PopulateDot11fWMMInfoAp(tpAniSirGlobal pMac, tDot11fIEWMMInfoAp *pInfo, + tpPESession psessionEntry) +{ + pInfo->version = SIR_MAC_OUI_VERSION_1; + + /* WMM Specification 3.1.3, 3.2.3 + * An IBSS staion shall always use its default WMM parameters. + */ + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + pInfo->param_set_count = 0; + pInfo->uapsd = 0; + } + else + { + pInfo->param_set_count = ( 0xf & psessionEntry->gLimEdcaParamSetCount ); + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + pInfo->uapsd = ( 0x1 & psessionEntry->apUapsdEnable ); + } + else + pInfo->uapsd = ( 0x1 & pMac->lim.gUapsdEnable ); + } + pInfo->present = 1; +} + +void PopulateDot11fWMMInfoStation(tpAniSirGlobal pMac, tDot11fIEWMMInfoStation *pInfo) +{ + tANI_U32 val = 0; + + pInfo->version = SIR_MAC_OUI_VERSION_1; + pInfo->acvo_uapsd = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + pInfo->acvi_uapsd = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + pInfo->acbk_uapsd = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + pInfo->acbe_uapsd = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max SP Length \n"));) + + pInfo->max_sp_length = (tANI_U8)val; + pInfo->present = 1; +} + +void PopulateDot11fWMMInfoStationPerSession(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEWMMInfoStation *pInfo) +{ + tANI_U32 val = 0; + + pInfo->version = SIR_MAC_OUI_VERSION_1; + pInfo->acvo_uapsd = LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask); + pInfo->acvi_uapsd = LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask); + pInfo->acbk_uapsd = LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask); + pInfo->acbe_uapsd = LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max SP Length \n"));) + + pInfo->max_sp_length = (tANI_U8)val; + pInfo->present = 1; +} + +void PopulateDot11fWMMParams(tpAniSirGlobal pMac, + tDot11fIEWMMParams *pParams, + tpPESession psessionEntry) +{ + pParams->version = SIR_MAC_OUI_VERSION_1; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + pParams->qosInfo = + (psessionEntry->apUapsdEnable << 7) | ((tANI_U8)(0x0f & psessionEntry->gLimEdcaParamSetCount)); + else + pParams->qosInfo = + (pMac->lim.gUapsdEnable << 7) | ((tANI_U8)(0x0f & psessionEntry->gLimEdcaParamSetCount)); + + // Fill each EDCA parameter set in order: be, bk, vi, vo + pParams->acbe_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn) ); + pParams->acbe_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm ); + pParams->acbe_aci = ( 0x3 & SIR_MAC_EDCAACI_BESTEFFORT ); + pParams->acbe_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min ); + pParams->acbe_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max ); + pParams->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit; + + pParams->acbk_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn) ); + pParams->acbk_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm ); + pParams->acbk_aci = ( 0x3 & SIR_MAC_EDCAACI_BACKGROUND ); + pParams->acbk_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min ); + pParams->acbk_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max ); + pParams->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + pParams->acvi_aifsn = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].aci.aifsn ); + else + pParams->acvi_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn) ); + + + + pParams->acvi_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm ); + pParams->acvi_aci = ( 0x3 & SIR_MAC_EDCAACI_VIDEO ); + pParams->acvi_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min ); + pParams->acvi_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max ); + pParams->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + pParams->acvo_aifsn = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].aci.aifsn ); + else + pParams->acvo_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn) ); + + pParams->acvo_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm ); + pParams->acvo_aci = ( 0x3 & SIR_MAC_EDCAACI_VOICE ); + pParams->acvo_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min ); + pParams->acvo_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max ); + pParams->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit; + + pParams->present = 1; + +} // End PopulateDot11fWMMParams. + +void PopulateDot11fWMMSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIEWMMSchedule *pDot11f) +{ + pDot11f->version = 1; + pDot11f->aggregation = pSchedule->info.aggregation; + pDot11f->tsid = pSchedule->info.tsid; + pDot11f->direction = pSchedule->info.direction; + pDot11f->reserved = pSchedule->info.rsvd; + pDot11f->service_start_time = pSchedule->svcStartTime; + pDot11f->service_interval = pSchedule->svcInterval; + pDot11f->max_service_dur = pSchedule->maxSvcDuration; + pDot11f->spec_interval = pSchedule->specInterval; + + pDot11f->present = 1; +} // End PopulateDot11fWMMSchedule. + +tSirRetStatus +PopulateDot11fWPA(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPA *pDot11f) +{ + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WPA ) ) ) + { + status = dot11fUnpackIeWPA( pMac, + pRsnIe->rsnIEdata + idx + 2 + 4, // EID, length, OUI + pRsnIe->rsnIEdata[ idx + 1 ] - 4, // OUI + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fWP" + "A (0x%08x).\n"), + status ); + return eSIR_FAILURE; + } + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fWPA. + + + +tSirRetStatus PopulateDot11fWPAOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPAOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WPA ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ] - 4; + vos_mem_copy( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2 + 4, // EID, len, OUI + pRsnIe->rsnIEdata[ idx + 1 ] - 4 ); // OUI + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fWPAOpaque. + +//////////////////////////////////////////////////////////////////////// + +tSirRetStatus +sirGetCfgPropCaps(tpAniSirGlobal pMac, tANI_U16 *caps) +{ +#if 0 + tANI_U32 val; + + *caps = 0; + if (wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, &val) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve PropFeature enabled flag\n")); + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_PROP_CAPABILITY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve PROP_CAPABLITY flag\n")); + return eSIR_FAILURE; + } + + *caps = (tANI_U16) val; +#endif + return eSIR_SUCCESS; +} + +tSirRetStatus +sirConvertProbeReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirProbeReq pProbeReq) +{ + tANI_U32 status; + tDot11fProbeRequest pr; + + // Ok, zero-init our [out] parameter, + vos_mem_set( (tANI_U8*)pProbeReq, sizeof(tSirProbeReq), 0); + + // delegate to the framesc-generated code, + status = dot11fUnpackProbeRequest(pMac, pFrame, nFrame, &pr); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Probe Request (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking a Probe Request (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... + if ( ! pr.SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!\n"));) + } + else + { + pProbeReq->ssidPresent = 1; + ConvertSSID( pMac, &pProbeReq->ssId, &pr.SSID ); + } + + if ( ! pr.SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + return eSIR_FAILURE; + } + else + { + pProbeReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pProbeReq->supportedRates, &pr.SuppRates ); + } + + if ( pr.ExtSuppRates.present ) + { + pProbeReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pProbeReq->extendedRates, &pr.ExtSuppRates ); + } + + if ( pr.HTCaps.present ) + { + vos_mem_copy( &pProbeReq->HTCaps, &pr.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pr.WscProbeReq.present ) + { + pProbeReq->wscIePresent = 1; + memcpy(&pProbeReq->probeReqWscIeInfo, &pr.WscProbeReq, sizeof(tDot11fIEWscProbeReq)); + } +#ifdef WLAN_FEATURE_11AC + if ( pr.VHTCaps.present ) + { + vos_mem_copy( &pProbeReq->VHTCaps, &pr.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } +#endif + + + if ( pr.P2PProbeReq.present ) + { + pProbeReq->p2pIePresent = 1; + } + + return eSIR_SUCCESS; + +} // End sirConvertProbeReqFrame2Struct. + +tSirRetStatus sirConvertProbeFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirProbeRespBeacon pProbeResp) +{ + tANI_U32 status; + tDot11fProbeResponse *pr; + + // Ok, zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pProbeResp, sizeof(tSirProbeRespBeacon), 0 ); + + pr = vos_mem_malloc(sizeof(tDot11fProbeResponse)); + if ( NULL == pr ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )pr, sizeof(tDot11fProbeResponse), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackProbeResponse( pMac, pFrame, nFrame, pr ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Probe Response (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + vos_mem_free(pr); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking a Probe Response (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... + + // Timestamp + vos_mem_copy( ( tANI_U8* )pProbeResp->timeStamp, ( tANI_U8* )&pr->TimeStamp, + sizeof(tSirMacTimeStamp) ); + + // Beacon Interval + pProbeResp->beaconInterval = pr->BeaconInterval.interval; + + // Capabilities + pProbeResp->capabilityInfo.ess = pr->Capabilities.ess; + pProbeResp->capabilityInfo.ibss = pr->Capabilities.ibss; + pProbeResp->capabilityInfo.cfPollable = pr->Capabilities.cfPollable; + pProbeResp->capabilityInfo.cfPollReq = pr->Capabilities.cfPollReq; + pProbeResp->capabilityInfo.privacy = pr->Capabilities.privacy; + pProbeResp->capabilityInfo.shortPreamble = pr->Capabilities.shortPreamble; + pProbeResp->capabilityInfo.pbcc = pr->Capabilities.pbcc; + pProbeResp->capabilityInfo.channelAgility = pr->Capabilities.channelAgility; + pProbeResp->capabilityInfo.spectrumMgt = pr->Capabilities.spectrumMgt; + pProbeResp->capabilityInfo.qos = pr->Capabilities.qos; + pProbeResp->capabilityInfo.shortSlotTime = pr->Capabilities.shortSlotTime; + pProbeResp->capabilityInfo.apsd = pr->Capabilities.apsd; + pProbeResp->capabilityInfo.rrm = pr->Capabilities.rrm; + pProbeResp->capabilityInfo.dsssOfdm = pr->Capabilities.dsssOfdm; + pProbeResp->capabilityInfo.delayedBA = pr->Capabilities.delayedBA; + pProbeResp->capabilityInfo.immediateBA = pr->Capabilities.immediateBA; + + if ( ! pr->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!\n"));) + } + else + { + pProbeResp->ssidPresent = 1; + ConvertSSID( pMac, &pProbeResp->ssId, &pr->SSID ); + } + + if ( ! pr->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + } + else + { + pProbeResp->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pProbeResp->supportedRates, &pr->SuppRates ); + } + + if ( pr->ExtSuppRates.present ) + { + pProbeResp->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pProbeResp->extendedRates, &pr->ExtSuppRates ); + } + + + if ( pr->CFParams.present ) + { + pProbeResp->cfPresent = 1; + ConvertCFParams( pMac, &pProbeResp->cfParamSet, &pr->CFParams ); + } + + if ( pr->Country.present ) + { + pProbeResp->countryInfoPresent = 1; + ConvertCountry( pMac, &pProbeResp->countryInfoParam, &pr->Country ); + } + + if ( pr->EDCAParamSet.present ) + { + pProbeResp->edcaPresent = 1; + ConvertEDCAParam( pMac, &pProbeResp->edcaParams, &pr->EDCAParamSet ); + } + + if ( pr->ChanSwitchAnn.present ) + { + pProbeResp->channelSwitchPresent = 1; + vos_mem_copy( &pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if ( pr->ExtChanSwitchAnn.present ) + { + pProbeResp->extChannelSwitchPresent = 1; + vos_mem_copy ( &pProbeResp->extChannelSwitchIE, &pr->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if( pr->TPCReport.present) + { + pProbeResp->tpcReportPresent = 1; + vos_mem_copy( &pProbeResp->tpcReport, &pr->TPCReport, sizeof(tDot11fIETPCReport)); + } + + if( pr->PowerConstraints.present) + { + pProbeResp->powerConstraintPresent = 1; + vos_mem_copy( &pProbeResp->localPowerConstraint, &pr->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } + + if ( pr->Quiet.present ) + { + pProbeResp->quietIEPresent = 1; + vos_mem_copy( &pProbeResp->quietIE, &pr->Quiet, sizeof(tDot11fIEQuiet) ); + } + + if ( pr->HTCaps.present ) + { + vos_mem_copy( &pProbeResp->HTCaps, &pr->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pr->HTInfo.present ) + { + vos_mem_copy( &pProbeResp->HTInfo, &pr->HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + + if ( pr->DSParams.present ) + { + pProbeResp->dsParamsPresent = 1; + pProbeResp->channelNumber = pr->DSParams.curr_channel; + } + else if(pr->HTInfo.present) + { + pProbeResp->channelNumber = pr->HTInfo.primaryChannel; + } + + if ( pr->RSNOpaque.present ) + { + pProbeResp->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pProbeResp->rsn, &pr->RSNOpaque ); + } + + if ( pr->WPA.present ) + { + pProbeResp->wpaPresent = 1; + ConvertWPA( pMac, &pProbeResp->wpa, &pr->WPA ); + } + + if ( pr->WMMParams.present ) + { + pProbeResp->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pProbeResp->edcaParams, &pr->WMMParams ); + PELOG1(limLog(pMac, LOG1, FL("WMM Parameter present in Probe Response Frame!\n")); + __printWMMParams(pMac, &pr->WMMParams);) + } + + if ( pr->WMMInfoAp.present ) + { + pProbeResp->wmeInfoPresent = 1; + PELOG1(limLog(pMac, LOG1, FL("WMM Information Element present in Probe Response Frame!\n"));) + } + + if ( pr->WMMCaps.present ) + { + pProbeResp->wsmCapablePresent = 1; + } + + + if ( pr->ERPInfo.present ) + { + pProbeResp->erpPresent = 1; + ConvertERPInfo( pMac, &pProbeResp->erpIEInfo, &pr->ERPInfo ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pr->MobilityDomain.present) + { + // MobilityDomain + pProbeResp->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pProbeResp->mdie[0]), (tANI_U8 *)&(pr->MobilityDomain.MDID), + sizeof(tANI_U16) ); + pProbeResp->mdie[2] = ((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain.resourceReqCap << 1)); +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG2, FL("mdie=%02x%02x%02x\n"), (unsigned int)pProbeResp->mdie[0], + (unsigned int)pProbeResp->mdie[1], (unsigned int)pProbeResp->mdie[2]); +#endif + } +#endif + +#if defined FEATURE_WLAN_ESE + if (pr->ESEVersion.present) { + pProbeResp->is_ese_ver_ie_present = 1; + } + if (pr->QBSSLoad.present) + { + vos_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad, sizeof(tDot11fIEQBSSLoad)); + } +#endif + if (pr->P2PProbeRes.present) + { + vos_mem_copy( &pProbeResp->P2PProbeRes, &pr->P2PProbeRes, + sizeof(tDot11fIEP2PProbeRes) ); + } +#ifdef WLAN_FEATURE_11AC + if ( pr->VHTCaps.present ) + { + vos_mem_copy( &pProbeResp->VHTCaps, &pr->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pr->VHTOperation.present ) + { + vos_mem_copy( &pProbeResp->VHTOperation, &pr->VHTOperation, sizeof( tDot11fIEVHTOperation) ); + } + if ( pr->VHTExtBssLoad.present ) + { + vos_mem_copy( &pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad, sizeof( tDot11fIEVHTExtBssLoad) ); + } +#endif + pProbeResp->Vendor1IEPresent = pr->Vendor1IE.present; + pProbeResp->Vendor2IEPresent = pr->Vendor2IE.present; + pProbeResp->Vendor3IEPresent = pr->Vendor3IE.present; + + vos_mem_free(pr); + return eSIR_SUCCESS; + +} // End sirConvertProbeFrame2Struct. + +tSirRetStatus +sirConvertAssocReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocReq pAssocReq) +{ + tDot11fAssocRequest *ar; + tANI_U32 status; + + ar = vos_mem_malloc(sizeof(tDot11fAssocRequest)); + if ( NULL == ar ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return eSIR_FAILURE; + } + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocReq, sizeof(tSirAssocReq), 0 ); + vos_mem_set( ( tANI_U8* )ar, sizeof( tDot11fAssocRequest ), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAssocRequest( pMac, pFrame, nFrame, ar ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Association Request (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + vos_mem_free(ar); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Assoication Request (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... + + // make sure this is seen as an assoc request + pAssocReq->reassocRequest = 0; + + // Capabilities + pAssocReq->capabilityInfo.ess = ar->Capabilities.ess; + pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss; + pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable; + pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq; + pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy; + pAssocReq->capabilityInfo.shortPreamble = ar->Capabilities.shortPreamble; + pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc; + pAssocReq->capabilityInfo.channelAgility = ar->Capabilities.channelAgility; + pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt; + pAssocReq->capabilityInfo.qos = ar->Capabilities.qos; + pAssocReq->capabilityInfo.shortSlotTime = ar->Capabilities.shortSlotTime; + pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd; + pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm; + pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm; + pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA; + pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA; + + // Listen Interval + pAssocReq->listenInterval = ar->ListenInterval.interval; + + // SSID + if ( ar->SSID.present ) + { + pAssocReq->ssidPresent = 1; + ConvertSSID( pMac, &pAssocReq->ssId, &ar->SSID ); + } + + // Supported Rates + if ( ar->SuppRates.present ) + { + pAssocReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocReq->supportedRates, &ar->SuppRates ); + } + + // Extended Supported Rates + if ( ar->ExtSuppRates.present ) + { + pAssocReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocReq->extendedRates, &ar->ExtSuppRates ); + } + + // QOS Capabilities: + if ( ar->QOSCapsStation.present ) + { + pAssocReq->qosCapabilityPresent = 1; + ConvertQOSCapsStation( pMac, &pAssocReq->qosCapability, &ar->QOSCapsStation ); + } + + // WPA + if ( ar->WPAOpaque.present ) + { + pAssocReq->wpaPresent = 1; + ConvertWPAOpaque( pMac, &pAssocReq->wpa, &ar->WPAOpaque ); + } + + // RSN + if ( ar->RSNOpaque.present ) + { + pAssocReq->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pAssocReq->rsn, &ar->RSNOpaque ); + } + + // WSC IE + if (ar->WscIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWscOpaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque); + } + + + if(ar->P2PIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertP2POpaque( pMac, &pAssocReq->addIE, &ar->P2PIEOpaque); + } +#ifdef WLAN_FEATURE_WFD + if(ar->WFDIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWFDOpaque( pMac, &pAssocReq->addIE, &ar->WFDIEOpaque); + } +#endif + + // Power Capabilities + if ( ar->PowerCaps.present ) + { + pAssocReq->powerCapabilityPresent = 1; + ConvertPowerCaps( pMac, &pAssocReq->powerCapability, &ar->PowerCaps ); + } + + // Supported Channels + if ( ar->SuppChannels.present ) + { + pAssocReq->supportedChannelsPresent = 1; + ConvertSuppChannels( pMac, &pAssocReq->supportedChannels, &ar->SuppChannels ); + } + + if ( ar->HTCaps.present ) + { + vos_mem_copy( &pAssocReq->HTCaps, &ar->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar->WMMInfoStation.present ) + { + pAssocReq->wmeInfoPresent = 1; + vos_mem_copy( &pAssocReq->WMMInfoStation, &ar->WMMInfoStation, + sizeof( tDot11fIEWMMInfoStation ) ); + + } + + + if ( ar->WMMCaps.present ) pAssocReq->wsmCapablePresent = 1; + + if ( ! pAssocReq->ssidPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without SSID IE.\n"));) + vos_mem_free(ar); + return eSIR_FAILURE; + } + + if ( !pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without supp rate IE.\n"));) + vos_mem_free(ar); + return eSIR_FAILURE; + } + +#ifdef WLAN_FEATURE_11AC + if ( ar->VHTCaps.present ) + { + vos_mem_copy( &pAssocReq->VHTCaps, &ar->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + limLog( pMac, LOGW, FL("Received Assoc Req with VHT Cap\n")); + limLogVHTCap( pMac, &pAssocReq->VHTCaps); + } + if ( ar->OperatingMode.present ) + { + vos_mem_copy( &pAssocReq->operMode, &ar->OperatingMode, sizeof (tDot11fIEOperatingMode)); + limLog( pMac, LOGW, FL("Received Assoc Req with Operating Mode IE\n")); + limLogOperatingMode( pMac, &pAssocReq->operMode); + } +#endif + if (ar->ExtCap.present) + { + struct s_ext_cap *p_ext_cap; + + vos_mem_copy(&pAssocReq->ExtCap.bytes, &ar->ExtCap.bytes, + ar->ExtCap.num_bytes); + + p_ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes; + limLog(pMac, LOG1, + FL("ExtCap is present, timingMeas: %d, fineTimingMeas: %d"), + p_ext_cap->timingMeas, p_ext_cap->fineTimingMeas); + } + vos_mem_free(ar); + return eSIR_SUCCESS; + +} // End sirConvertAssocReqFrame2Struct. + +tSirRetStatus +sirConvertAssocRespFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocRsp pAssocRsp) +{ + static tDot11fAssocResponse ar; + tANI_U32 status; + tANI_U8 cnt =0; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocRsp, sizeof(tSirAssocRsp), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAssocResponse( pMac, pFrame, nFrame, &ar); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Association Response (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Association Response (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAssocResponse' a 'tSirAssocRsp'... + + // Capabilities + pAssocRsp->capabilityInfo.ess = ar.Capabilities.ess; + pAssocRsp->capabilityInfo.ibss = ar.Capabilities.ibss; + pAssocRsp->capabilityInfo.cfPollable = ar.Capabilities.cfPollable; + pAssocRsp->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq; + pAssocRsp->capabilityInfo.privacy = ar.Capabilities.privacy; + pAssocRsp->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble; + pAssocRsp->capabilityInfo.pbcc = ar.Capabilities.pbcc; + pAssocRsp->capabilityInfo.channelAgility = ar.Capabilities.channelAgility; + pAssocRsp->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt; + pAssocRsp->capabilityInfo.qos = ar.Capabilities.qos; + pAssocRsp->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime; + pAssocRsp->capabilityInfo.apsd = ar.Capabilities.apsd; + pAssocRsp->capabilityInfo.rrm = ar.Capabilities.rrm; + pAssocRsp->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm; + pAssocRsp->capabilityInfo.delayedBA = ar.Capabilities.delayedBA; + pAssocRsp->capabilityInfo.immediateBA = ar.Capabilities.immediateBA; + + pAssocRsp->statusCode = ar.Status.status; + pAssocRsp->aid = ar.AID.associd; + +#ifdef WLAN_FEATURE_11W + if (ar.TimeoutInterval.present) { + pAssocRsp->TimeoutInterval.present = 1; + pAssocRsp->TimeoutInterval.timeoutType = + ar.TimeoutInterval.timeoutType; + pAssocRsp->TimeoutInterval.timeoutValue = + ar.TimeoutInterval.timeoutValue; + } +#endif + + if ( ! ar.SuppRates.present ) + { + pAssocRsp->suppRatesPresent = 0; + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + } + else + { + pAssocRsp->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocRsp->supportedRates, &ar.SuppRates ); + } + + if ( ar.ExtSuppRates.present ) + { + pAssocRsp->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocRsp->extendedRates, &ar.ExtSuppRates ); + } + + if ( ar.EDCAParamSet.present ) + { + pAssocRsp->edcaPresent = 1; + ConvertEDCAParam( pMac, &pAssocRsp->edca, &ar.EDCAParamSet ); + } + + + if ( ar.WMMParams.present ) + { + pAssocRsp->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pAssocRsp->edca, &ar.WMMParams); + limLog(pMac, LOG1, FL("WMM Parameter Element present in Association Response Frame!")); + __printWMMParams(pMac, &ar.WMMParams); + } + + if ( ar.HTCaps.present ) + { + vos_mem_copy( &pAssocRsp->HTCaps, &ar.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar.HTInfo.present ) + { + vos_mem_copy( &pAssocRsp->HTInfo, &ar.HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (ar.MobilityDomain.present) + { + // MobilityDomain + pAssocRsp->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pAssocRsp->mdie[0]), (tANI_U8 *)&(ar.MobilityDomain.MDID), + sizeof(tANI_U16) ); + pAssocRsp->mdie[2] = ((ar.MobilityDomain.overDSCap << 0) | (ar.MobilityDomain.resourceReqCap << 1)); +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("new mdie=%02x%02x%02x"), (unsigned int)pAssocRsp->mdie[0], + (unsigned int)pAssocRsp->mdie[1], (unsigned int)pAssocRsp->mdie[2]); +#endif + } + + if ( ar.FTInfo.present ) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("FT Info present %d %d %d"), ar.FTInfo.R0KH_ID.num_PMK_R0_ID, + ar.FTInfo.R0KH_ID.present, + ar.FTInfo.R1KH_ID.present); +#endif + pAssocRsp->ftinfoPresent = 1; + vos_mem_copy( &pAssocRsp->FTInfo, &ar.FTInfo, sizeof(tDot11fIEFTInfo) ); + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (ar.num_RICDataDesc) { + for (cnt=0; cnt < ar.num_RICDataDesc; cnt++) { + if (ar.RICDataDesc[cnt].present) { + vos_mem_copy( &pAssocRsp->RICData[cnt], &ar.RICDataDesc[cnt], + sizeof(tDot11fIERICDataDesc)); + } + } + pAssocRsp->num_RICData = ar.num_RICDataDesc; + pAssocRsp->ricPresent = TRUE; + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (ar.num_WMMTSPEC) { + pAssocRsp->num_tspecs = ar.num_WMMTSPEC; + for (cnt=0; cnt < ar.num_WMMTSPEC; cnt++) { + vos_mem_copy( &pAssocRsp->TSPECInfo[cnt], &ar.WMMTSPEC[cnt], + (sizeof(tDot11fIEWMMTSPEC)*ar.num_WMMTSPEC)); + } + pAssocRsp->tspecPresent = TRUE; + } + + if(ar.ESETrafStrmMet.present) + { + pAssocRsp->tsmPresent = 1; + vos_mem_copy(&pAssocRsp->tsmIE.tsid, + &ar.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( ar.VHTCaps.present ) + { + vos_mem_copy( &pAssocRsp->VHTCaps, &ar.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + limLog( pMac, LOG1, FL("Received Assoc Response with VHT Cap")); + limLogVHTCap(pMac, &pAssocRsp->VHTCaps); + } + if ( ar.VHTOperation.present ) + { + vos_mem_copy( &pAssocRsp->VHTOperation, &ar.VHTOperation, sizeof( tDot11fIEVHTOperation) ); + limLog( pMac, LOG1, FL("Received Assoc Response with VHT Operation")); + limLogVHTOperation(pMac, &pAssocRsp->VHTOperation); + } +#endif + + if (ar.ExtCap.present) + { + struct s_ext_cap *p_ext_cap; + + vos_mem_copy(&pAssocRsp->ExtCap.bytes, &ar.ExtCap.bytes, + ar.ExtCap.num_bytes); + p_ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes; + limLog(pMac, LOG1, + FL("ExtCap is present, timingMeas: %d, fineTimingMeas: %d"), + p_ext_cap->timingMeas, p_ext_cap->fineTimingMeas); + } + + if ( ar.QosMapSet.present ) + { + pAssocRsp->QosMapSet.present = 1; + ConvertQosMapsetFrame( pMac, &pAssocRsp->QosMapSet, &ar.QosMapSet); + limLog( pMac, LOG1, FL("Received Assoc Response with Qos Map Set")); + limLogQosMapSet(pMac, &pAssocRsp->QosMapSet); + } + + return eSIR_SUCCESS; + +} // End sirConvertAssocRespFrame2Struct. + +tSirRetStatus +sirConvertReassocReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocReq pAssocReq) +{ + static tDot11fReAssocRequest ar; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocReq, sizeof(tSirAssocReq), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackReAssocRequest( pMac, pFrame, nFrame, &ar ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Re-association Request (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... + + // make sure this is seen as a re-assoc request + pAssocReq->reassocRequest = 1; + + // Capabilities + pAssocReq->capabilityInfo.ess = ar.Capabilities.ess; + pAssocReq->capabilityInfo.ibss = ar.Capabilities.ibss; + pAssocReq->capabilityInfo.cfPollable = ar.Capabilities.cfPollable; + pAssocReq->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq; + pAssocReq->capabilityInfo.privacy = ar.Capabilities.privacy; + pAssocReq->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble; + pAssocReq->capabilityInfo.pbcc = ar.Capabilities.pbcc; + pAssocReq->capabilityInfo.channelAgility = ar.Capabilities.channelAgility; + pAssocReq->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt; + pAssocReq->capabilityInfo.qos = ar.Capabilities.qos; + pAssocReq->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime; + pAssocReq->capabilityInfo.apsd = ar.Capabilities.apsd; + pAssocReq->capabilityInfo.rrm = ar.Capabilities.rrm; + pAssocReq->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm; + pAssocReq->capabilityInfo.delayedBA = ar.Capabilities.delayedBA; + pAssocReq->capabilityInfo.immediateBA = ar.Capabilities.immediateBA; + + // Listen Interval + pAssocReq->listenInterval = ar.ListenInterval.interval; + + // SSID + if ( ar.SSID.present ) + { + pAssocReq->ssidPresent = 1; + ConvertSSID( pMac, &pAssocReq->ssId, &ar.SSID ); + } + + // Supported Rates + if ( ar.SuppRates.present ) + { + pAssocReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocReq->supportedRates, &ar.SuppRates ); + } + + // Extended Supported Rates + if ( ar.ExtSuppRates.present ) + { + pAssocReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocReq->extendedRates, + &ar.ExtSuppRates ); + } + + // QOS Capabilities: + if ( ar.QOSCapsStation.present ) + { + pAssocReq->qosCapabilityPresent = 1; + ConvertQOSCapsStation( pMac, &pAssocReq->qosCapability, &ar.QOSCapsStation ); + } + + // WPA + if ( ar.WPAOpaque.present ) + { + pAssocReq->wpaPresent = 1; + ConvertWPAOpaque( pMac, &pAssocReq->wpa, &ar.WPAOpaque ); + } + + // RSN + if ( ar.RSNOpaque.present ) + { + pAssocReq->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pAssocReq->rsn, &ar.RSNOpaque ); + } + + + // Power Capabilities + if ( ar.PowerCaps.present ) + { + pAssocReq->powerCapabilityPresent = 1; + ConvertPowerCaps( pMac, &pAssocReq->powerCapability, &ar.PowerCaps ); + } + + // Supported Channels + if ( ar.SuppChannels.present ) + { + pAssocReq->supportedChannelsPresent = 1; + ConvertSuppChannels( pMac, &pAssocReq->supportedChannels, &ar.SuppChannels ); + } + + if ( ar.HTCaps.present ) + { + vos_mem_copy( &pAssocReq->HTCaps, &ar.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar.WMMInfoStation.present ) + { + pAssocReq->wmeInfoPresent = 1; + vos_mem_copy( &pAssocReq->WMMInfoStation, &ar.WMMInfoStation, + sizeof( tDot11fIEWMMInfoStation ) ); + + } + + if ( ar.WMMCaps.present ) pAssocReq->wsmCapablePresent = 1; + + if ( ! pAssocReq->ssidPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without SSID IE.\n"));) + return eSIR_FAILURE; + } + + if ( ! pAssocReq->suppRatesPresent && ! pAssocReq->extendedRatesPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without supp rate IE.\n"));) + return eSIR_FAILURE; + } + + // Why no call to 'updateAssocReqFromPropCapability' here, like + // there is in 'sirConvertAssocReqFrame2Struct'? + + // WSC IE + if (ar.WscIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWscOpaque(pMac, &pAssocReq->addIE, &ar.WscIEOpaque); + } + + if(ar.P2PIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertP2POpaque( pMac, &pAssocReq->addIE, &ar.P2PIEOpaque); + } + +#ifdef WLAN_FEATURE_WFD + if(ar.WFDIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWFDOpaque( pMac, &pAssocReq->addIE, &ar.WFDIEOpaque); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( ar.VHTCaps.present ) + { + vos_mem_copy( &pAssocReq->VHTCaps, &ar.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( ar.OperatingMode.present ) + { + vos_mem_copy( &pAssocReq->operMode, &ar.OperatingMode, sizeof( tDot11fIEOperatingMode ) ); + limLog( pMac, LOGW, FL("Received Assoc Req with Operating Mode IE\n")); + limLogOperatingMode( pMac, &pAssocReq->operMode); + } +#endif + + if (ar.ExtCap.present) + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + &ar.ExtCap.bytes; + vos_mem_copy(&pAssocReq->ExtCap.bytes, &ar.ExtCap.bytes, + ar.ExtCap.num_bytes); + limLog(pMac, LOG1, + FL("ExtCap is present, timingMeas: %d, fineTimingMeas: %d"), + p_ext_cap->timingMeas, p_ext_cap->fineTimingMeas); + } + + return eSIR_SUCCESS; + +} // End sirConvertReassocReqFrame2Struct. + + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +tSirRetStatus +sirFillBeaconMandatoryIEforEseBcnReport(tpAniSirGlobal pMac, + tANI_U8 *pPayload, + const tANI_U32 nPayload, + tANI_U8 **outIeBuf, + tANI_U32 *pOutIeLen) +{ + tDot11fBeaconIEs *pBies = NULL; + tANI_U32 status = eHAL_STATUS_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe; + + /* To store how many bytes are required to be allocated + for Bcn report mandatory Ies */ + tANI_U16 numBytes = 0, freeBytes = 0; + tANI_U8 *pos = NULL; + + // Zero-init our [out] parameter, + vos_mem_set( (tANI_U8*)&eseBcnReportMandatoryIe, sizeof(eseBcnReportMandatoryIe), 0 ); + pBies = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pBies ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return eSIR_FAILURE; + } + // delegate to the framesc-generated code, + status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload); + vos_mem_free(pBies); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + } + + // & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... + if ( !pBies->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!\n"));) + } + else + { + eseBcnReportMandatoryIe.ssidPresent = 1; + ConvertSSID( pMac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID ); + /* 1 for EID, 1 for length and length bytes */ + numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length; + } + + if ( !pBies->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + } + else + { + eseBcnReportMandatoryIe.suppRatesPresent = 1; + ConvertSuppRates( pMac, &eseBcnReportMandatoryIe.supportedRates, &pBies->SuppRates ); + numBytes += 1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates; + } + + if ( pBies->FHParamSet.present) + { + eseBcnReportMandatoryIe.fhParamPresent = 1; + ConvertFHParams( pMac, &eseBcnReportMandatoryIe.fhParamSet, &pBies->FHParamSet ); + numBytes += 1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX; + } + + if ( pBies->DSParams.present ) + { + eseBcnReportMandatoryIe.dsParamsPresent = 1; + eseBcnReportMandatoryIe.dsParamSet.channelNumber = pBies->DSParams.curr_channel; + numBytes += 1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX; + } + + if ( pBies->CFParams.present ) + { + eseBcnReportMandatoryIe.cfPresent = 1; + ConvertCFParams( pMac, &eseBcnReportMandatoryIe.cfParamSet, &pBies->CFParams ); + numBytes += 1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX; + } + + if ( pBies->IBSSParams.present ) + { + eseBcnReportMandatoryIe.ibssParamPresent = 1; + eseBcnReportMandatoryIe.ibssParamSet.atim = pBies->IBSSParams.atim; + numBytes += 1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX; + } + + if ( pBies->TIM.present ) + { + eseBcnReportMandatoryIe.timPresent = 1; + eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count; + eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period; + eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl; + /* As per the ESE spec, May truncate and report first 4 octets only */ + numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN; + } + + if ( pBies->RRMEnabledCap.present ) + { + eseBcnReportMandatoryIe.rrmPresent = 1; + vos_mem_copy( &eseBcnReportMandatoryIe.rmEnabledCapabilities, &pBies->RRMEnabledCap, sizeof( tDot11fIERRMEnabledCap ) ); + numBytes += 1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; + } + + *outIeBuf = vos_mem_malloc(numBytes); + if (NULL == *outIeBuf) + { + limLog(pMac, LOGP, FL("Memory Allocation failure")); + vos_mem_free(pBies); + return eSIR_FAILURE; + } + pos = *outIeBuf; + *pOutIeLen = numBytes; + freeBytes = numBytes; + + /* Start filling the output Ie with Mandatory IE information */ + /* Fill SSID IE */ + if (eseBcnReportMandatoryIe.ssidPresent) + { + if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy SSID")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_SSID_EID; + pos++; + *pos = eseBcnReportMandatoryIe.ssId.length; + pos++; + vos_mem_copy(pos, + (tANI_U8*)eseBcnReportMandatoryIe.ssId.ssId, + eseBcnReportMandatoryIe.ssId.length); + pos += eseBcnReportMandatoryIe.ssId.length; + freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length); + } + + /* Fill Supported Rates IE */ + if (eseBcnReportMandatoryIe.suppRatesPresent) + { + if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy Rates IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_RATESET_EID; + pos++; + *pos = eseBcnReportMandatoryIe.supportedRates.numRates; + pos++; + vos_mem_copy(pos, + (tANI_U8*)eseBcnReportMandatoryIe.supportedRates.rate, + eseBcnReportMandatoryIe.supportedRates.numRates); + pos += eseBcnReportMandatoryIe.supportedRates.numRates; + freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates); + } + + /* Fill FH Parameter set IE */ + if (eseBcnReportMandatoryIe.fhParamPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy FHIE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_FH_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_FH_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, + (tANI_U8*)&eseBcnReportMandatoryIe.fhParamSet, + SIR_MAC_FH_PARAM_SET_EID_MAX); + pos += SIR_MAC_FH_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX); + } + + /* Fill DS Parameter set IE */ + if (eseBcnReportMandatoryIe.dsParamsPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy DS IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_DS_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_DS_PARAM_SET_EID_MAX; + pos++; + *pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber; + pos += SIR_MAC_DS_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX); + } + + /* Fill CF Parameter set */ + if (eseBcnReportMandatoryIe.cfPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy CF IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_CF_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_CF_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, + (tANI_U8*)&eseBcnReportMandatoryIe.cfParamSet, + SIR_MAC_CF_PARAM_SET_EID_MAX); + pos += SIR_MAC_CF_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX); + } + + /* Fill IBSS Parameter set IE */ + if (eseBcnReportMandatoryIe.ibssParamPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy IBSS IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_IBSS_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_IBSS_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, + (tANI_U8*)&eseBcnReportMandatoryIe.ibssParamSet.atim, + SIR_MAC_IBSS_PARAM_SET_EID_MAX); + pos += SIR_MAC_IBSS_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX); + } + + /* Fill TIM IE */ + if (eseBcnReportMandatoryIe.timPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy TIM IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_TIM_EID; + pos++; + *pos = SIR_MAC_TIM_EID_MIN; + pos++; + vos_mem_copy(pos, + (tANI_U8*)&eseBcnReportMandatoryIe.tim, + SIR_MAC_TIM_EID_MIN); + pos += SIR_MAC_TIM_EID_MIN; + freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN); + } + + /* Fill RM Capability IE */ + if (eseBcnReportMandatoryIe.rrmPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy RRM IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID; + pos++; + *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; + pos++; + vos_mem_copy(pos, + (tANI_U8*)&eseBcnReportMandatoryIe.rmEnabledCapabilities, + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); + freeBytes -= (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); + } + + if (freeBytes != 0) + { + limLog(pMac, LOGP, FL("Mismatch in allocation and copying of IE in Bcn Rep")); + retStatus = eSIR_FAILURE; + } + +err_bcnrep: + /* The message counter would not be incremented in case of + * returning failure and hence next time, this function gets + * called, it would be using the same msg ctr for a different + * BSS.So, it is good to clear the memory allocated for a BSS + * that is returning failure.On success, the caller would take + * care of freeing up the memory*/ + if (retStatus == eSIR_FAILURE) + { + vos_mem_free(*outIeBuf); + *outIeBuf = NULL; + } + + vos_mem_free(pBies); + return retStatus; +} + +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +tSirRetStatus +sirParseBeaconIE(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeaconStruct, + tANI_U8 *pPayload, + tANI_U32 nPayload) +{ + tDot11fBeaconIEs *pBies; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pBeaconStruct, sizeof(tSirProbeRespBeacon), 0 ); + + pBies = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pBies ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return eSIR_FAILURE; + } + // delegate to the framesc-generated code, + status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + vos_mem_free(pBies); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + } + + // & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... + if ( ! pBies->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!\n"));) + } + else + { + pBeaconStruct->ssidPresent = 1; + ConvertSSID( pMac, &pBeaconStruct->ssId, &pBies->SSID ); + } + + if ( ! pBies->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + } + else + { + pBeaconStruct->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pBeaconStruct->supportedRates, &pBies->SuppRates ); + } + + if ( pBies->ExtSuppRates.present ) + { + pBeaconStruct->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pBeaconStruct->extendedRates, &pBies->ExtSuppRates ); + } + + if ( pBies->CFParams.present ) + { + pBeaconStruct->cfPresent = 1; + ConvertCFParams( pMac, &pBeaconStruct->cfParamSet, &pBies->CFParams ); + } + + if ( pBies->TIM.present ) + { + pBeaconStruct->timPresent = 1; + ConvertTIM( pMac, &pBeaconStruct->tim, &pBies->TIM ); + } + + if ( pBies->Country.present ) + { + pBeaconStruct->countryInfoPresent = 1; + ConvertCountry( pMac, &pBeaconStruct->countryInfoParam, &pBies->Country ); + } + + // 11h IEs + if(pBies->TPCReport.present) + { + pBeaconStruct->tpcReportPresent = 1; + vos_mem_copy( &pBeaconStruct->tpcReport, + &pBies->TPCReport, + sizeof( tDot11fIETPCReport)); + } + + if(pBies->PowerConstraints.present) + { + pBeaconStruct->powerConstraintPresent = 1; + vos_mem_copy( &pBeaconStruct->localPowerConstraint, + &pBies->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } +#ifdef FEATURE_WLAN_ESE + if (pBies->ESEVersion.present) { + pBeaconStruct->is_ese_ver_ie_present = 1; + } + if(pBies->ESETxmitPower.present) + { + pBeaconStruct->eseTxPwr.present = 1; + pBeaconStruct->eseTxPwr.power_limit = pBies->ESETxmitPower.power_limit; + } + if (pBies->QBSSLoad.present) + { + vos_mem_copy( &pBeaconStruct->QBSSLoad, &pBies->QBSSLoad, sizeof(tDot11fIEQBSSLoad)); + } +#endif + + if ( pBies->EDCAParamSet.present ) + { + pBeaconStruct->edcaPresent = 1; + ConvertEDCAParam( pMac, &pBeaconStruct->edcaParams, &pBies->EDCAParamSet ); + } + + // QOS Capabilities: + if ( pBies->QOSCapsAp.present ) + { + pBeaconStruct->qosCapabilityPresent = 1; + ConvertQOSCaps( pMac, &pBeaconStruct->qosCapability, &pBies->QOSCapsAp ); + } + + + + if ( pBies->ChanSwitchAnn.present ) + { + pBeaconStruct->channelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->channelSwitchIE, &pBies->ChanSwitchAnn, + sizeof(tDot11fIEChanSwitchAnn)); + } + + if ( pBies->ExtChanSwitchAnn.present) + { + pBeaconStruct->extChannelSwitchPresent= 1; + vos_mem_copy( &pBeaconStruct->extChannelSwitchIE, &pBies->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn)); + } + + if ( pBies->Quiet.present ) + { + pBeaconStruct->quietIEPresent = 1; + vos_mem_copy( &pBeaconStruct->quietIE, &pBies->Quiet, sizeof(tDot11fIEQuiet) ); + } + + if ( pBies->HTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->HTCaps, &pBies->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pBies->HTInfo.present ) + { + vos_mem_copy( &pBeaconStruct->HTInfo, &pBies->HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + + if ( pBies->DSParams.present ) + { + pBeaconStruct->dsParamsPresent = 1; + pBeaconStruct->channelNumber = pBies->DSParams.curr_channel; + } + else if(pBies->HTInfo.present) + { + pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel; + } + + if ( pBies->RSN.present ) + { + pBeaconStruct->rsnPresent = 1; + ConvertRSN( pMac, &pBeaconStruct->rsn, &pBies->RSN ); + } + + if ( pBies->WPA.present ) + { + pBeaconStruct->wpaPresent = 1; + ConvertWPA( pMac, &pBeaconStruct->wpa, &pBies->WPA ); + } + + if ( pBies->WMMParams.present ) + { + pBeaconStruct->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pBeaconStruct->edcaParams, &pBies->WMMParams ); + } + + if ( pBies->WMMInfoAp.present ) + { + pBeaconStruct->wmeInfoPresent = 1; + } + + if ( pBies->WMMCaps.present ) + { + pBeaconStruct->wsmCapablePresent = 1; + } + + + if ( pBies->ERPInfo.present ) + { + pBeaconStruct->erpPresent = 1; + ConvertERPInfo( pMac, &pBeaconStruct->erpIEInfo, &pBies->ERPInfo ); + } + +#ifdef WLAN_FEATURE_11AC + if ( pBies->VHTCaps.present ) + { + pBeaconStruct->VHTCaps.present = 1; + vos_mem_copy( &pBeaconStruct->VHTCaps, &pBies->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pBies->VHTOperation.present ) + { + pBeaconStruct->VHTOperation.present = 1; + vos_mem_copy( &pBeaconStruct->VHTOperation, &pBies->VHTOperation, + sizeof( tDot11fIEVHTOperation) ); + } + if ( pBies->VHTExtBssLoad.present ) + { + pBeaconStruct->VHTExtBssLoad.present = 1; + vos_mem_copy( &pBeaconStruct->VHTExtBssLoad, &pBies->VHTExtBssLoad, + sizeof( tDot11fIEVHTExtBssLoad) ); + } + if( pBies->OperatingMode.present) + { + pBeaconStruct->OperatingMode.present = 1; + vos_mem_copy( &pBeaconStruct->OperatingMode, &pBies->OperatingMode, + sizeof( tDot11fIEOperatingMode) ); + } +#endif + + if( pBies->MobilityDomain.present) + { + pBeaconStruct->mdiePresent = 1; + vos_mem_copy( pBeaconStruct->mdie, &pBies->MobilityDomain.MDID, SIR_MDIE_SIZE); + } + + pBeaconStruct->Vendor1IEPresent = pBies->Vendor1IE.present; + pBeaconStruct->Vendor2IEPresent = pBies->Vendor2IE.present; + pBeaconStruct->Vendor3IEPresent = pBies->Vendor3IE.present; + + vos_mem_free(pBies); + return eSIR_SUCCESS; +} // End sirParseBeaconIE. + +tSirRetStatus +sirConvertBeaconFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirProbeRespBeacon pBeaconStruct) +{ + tDot11fBeacon *pBeacon; + tANI_U32 status, nPayload; + tANI_U8 *pPayload; + tpSirMacMgmtHdr pHdr; + tANI_U8 mappedRXCh; + tANI_U8 rfBand; + + pPayload = WDA_GET_RX_MPDU_DATA( pFrame ); + nPayload = WDA_GET_RX_PAYLOAD_LEN( pFrame ); + pHdr = WDA_GET_RX_MAC_HEADER( pFrame ); + mappedRXCh = WDA_GET_RX_CH( pFrame ); + rfBand = WDA_GET_RX_RFBAND( pFrame ); + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pBeaconStruct, sizeof(tSirProbeRespBeacon), 0 ); + + pBeacon = vos_mem_malloc(sizeof(tDot11fBeacon)); + if ( NULL == pBeacon ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )pBeacon, sizeof(tDot11fBeacon), 0 ); + + // get the MAC address out of the BD, + vos_mem_copy( pBeaconStruct->bssid, pHdr->sa, 6 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackBeacon( pMac, pPayload, nPayload, pBeacon ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + vos_mem_free(pBeacon); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"), + status, nPayload ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + } + + // & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... + // Timestamp + vos_mem_copy( ( tANI_U8* )pBeaconStruct->timeStamp, ( tANI_U8* )&pBeacon->TimeStamp, + sizeof(tSirMacTimeStamp) ); + + // Beacon Interval + pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval; + + // Capabilities + pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess; + pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss; + pBeaconStruct->capabilityInfo.cfPollable = pBeacon->Capabilities.cfPollable; + pBeaconStruct->capabilityInfo.cfPollReq = pBeacon->Capabilities.cfPollReq; + pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy; + pBeaconStruct->capabilityInfo.shortPreamble = pBeacon->Capabilities.shortPreamble; + pBeaconStruct->capabilityInfo.pbcc = pBeacon->Capabilities.pbcc; + pBeaconStruct->capabilityInfo.channelAgility = pBeacon->Capabilities.channelAgility; + pBeaconStruct->capabilityInfo.spectrumMgt = pBeacon->Capabilities.spectrumMgt; + pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos; + pBeaconStruct->capabilityInfo.shortSlotTime = pBeacon->Capabilities.shortSlotTime; + pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd; + pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm; + pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm; + pBeaconStruct->capabilityInfo.delayedBA = pBeacon->Capabilities.delayedBA; + pBeaconStruct->capabilityInfo.immediateBA = pBeacon->Capabilities.immediateBA; + + if ( ! pBeacon->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!\n"));) + } + else + { + pBeaconStruct->ssidPresent = 1; + ConvertSSID( pMac, &pBeaconStruct->ssId, &pBeacon->SSID ); + } + + if ( ! pBeacon->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!\n"));) + } + else + { + pBeaconStruct->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pBeaconStruct->supportedRates, &pBeacon->SuppRates ); + } + + if ( pBeacon->ExtSuppRates.present ) + { + pBeaconStruct->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pBeaconStruct->extendedRates, &pBeacon->ExtSuppRates ); + } + + + if ( pBeacon->CFParams.present ) + { + pBeaconStruct->cfPresent = 1; + ConvertCFParams( pMac, &pBeaconStruct->cfParamSet, &pBeacon->CFParams ); + } + + if ( pBeacon->TIM.present ) + { + pBeaconStruct->timPresent = 1; + ConvertTIM( pMac, &pBeaconStruct->tim, &pBeacon->TIM ); + } + + if ( pBeacon->Country.present ) + { + pBeaconStruct->countryInfoPresent = 1; + ConvertCountry( pMac, &pBeaconStruct->countryInfoParam, &pBeacon->Country ); + } + + // QOS Capabilities: + if ( pBeacon->QOSCapsAp.present ) + { + pBeaconStruct->qosCapabilityPresent = 1; + ConvertQOSCaps( pMac, &pBeaconStruct->qosCapability, &pBeacon->QOSCapsAp ); + } + + if ( pBeacon->EDCAParamSet.present ) + { + pBeaconStruct->edcaPresent = 1; + ConvertEDCAParam( pMac, &pBeaconStruct->edcaParams, &pBeacon->EDCAParamSet ); + } + + if ( pBeacon->ChanSwitchAnn.present ) + { + pBeaconStruct->channelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->channelSwitchIE, &pBeacon->ChanSwitchAnn, + sizeof(tDot11fIEChanSwitchAnn) ); + } + + if ( pBeacon->ExtChanSwitchAnn.present ) + { + pBeaconStruct->extChannelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->extChannelSwitchIE, &pBeacon->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if( pBeacon->TPCReport.present) + { + pBeaconStruct->tpcReportPresent = 1; + vos_mem_copy( &pBeaconStruct->tpcReport, &pBeacon->TPCReport, + sizeof(tDot11fIETPCReport)); + } + + if( pBeacon->PowerConstraints.present) + { + pBeaconStruct->powerConstraintPresent = 1; + vos_mem_copy( &pBeaconStruct->localPowerConstraint, &pBeacon->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } + + if ( pBeacon->Quiet.present ) + { + pBeaconStruct->quietIEPresent = 1; + vos_mem_copy( &pBeaconStruct->quietIE, &pBeacon->Quiet, sizeof(tDot11fIEQuiet)); + } + + if ( pBeacon->HTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->HTCaps, &pBeacon->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pBeacon->HTInfo.present ) + { + vos_mem_copy( &pBeaconStruct->HTInfo, &pBeacon->HTInfo, sizeof( tDot11fIEHTInfo) ); + + } + + if ( pBeacon->DSParams.present ) + { + pBeaconStruct->dsParamsPresent = 1; + pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel; + } + else if(pBeacon->HTInfo.present) + { + pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel; + } + else + { + if ((!rfBand) || IS_5G_BAND(rfBand)) + pBeaconStruct->channelNumber = limUnmapChannel(mappedRXCh); + else if (IS_24G_BAND(rfBand)) + pBeaconStruct->channelNumber = mappedRXCh; + else + { + /*Only 0, 1, 2 are expected values for RF band from FW + * if FW fixes are not present then rf band value will + * be 0, else either 1 or 2 are expected from FW, 3 is + * not expected from FW */ + PELOGE(limLog(pMac, LOGE, + FL("Channel info is not present in Beacon and" + " mapping is not done correctly"));) + pBeaconStruct->channelNumber = mappedRXCh; + } + } + + if ( pBeacon->RSN.present ) + { + pBeaconStruct->rsnPresent = 1; + ConvertRSN( pMac, &pBeaconStruct->rsn, &pBeacon->RSN ); + } + + if ( pBeacon->WPA.present ) + { + pBeaconStruct->wpaPresent = 1; + ConvertWPA( pMac, &pBeaconStruct->wpa, &pBeacon->WPA ); + } + + if ( pBeacon->WMMParams.present ) + { + pBeaconStruct->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pBeaconStruct->edcaParams, &pBeacon->WMMParams ); + PELOG1(limLog(pMac, LOG1, FL("WMM Parameter present in Beacon Frame!\n")); + __printWMMParams(pMac, &pBeacon->WMMParams); ) + } + + if ( pBeacon->WMMInfoAp.present ) + { + pBeaconStruct->wmeInfoPresent = 1; + PELOG1(limLog(pMac, LOG1, FL("WMM Info present in Beacon Frame!\n"));) + } + + if ( pBeacon->WMMCaps.present ) + { + pBeaconStruct->wsmCapablePresent = 1; + } + + if ( pBeacon->ERPInfo.present ) + { + pBeaconStruct->erpPresent = 1; + ConvertERPInfo( pMac, &pBeaconStruct->erpIEInfo, &pBeacon->ERPInfo ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pBeacon->MobilityDomain.present) + { + // MobilityDomain + pBeaconStruct->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pBeaconStruct->mdie[0]), + (tANI_U8 *)&(pBeacon->MobilityDomain.MDID), sizeof(tANI_U16) ); + pBeaconStruct->mdie[2] = ((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon->MobilityDomain.resourceReqCap << 1)); + + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (pBeacon->ESEVersion.present) { + pBeaconStruct->is_ese_ver_ie_present = 1; + } + if (pBeacon->ESETxmitPower.present) + { + /* copy ESE TPC info element */ + pBeaconStruct->eseTxPwr.present = 1; + vos_mem_copy( &pBeaconStruct->eseTxPwr, + &pBeacon->ESETxmitPower, + sizeof(tDot11fIEESETxmitPower)); + } + if (pBeacon->QBSSLoad.present) + { + vos_mem_copy(&pBeaconStruct->QBSSLoad, + &pBeacon->QBSSLoad, + sizeof(tDot11fIEQBSSLoad)); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( pBeacon->VHTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->VHTCaps, &pBeacon->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pBeacon->VHTOperation.present ) + { + vos_mem_copy( &pBeaconStruct->VHTOperation, &pBeacon->VHTOperation, + sizeof( tDot11fIEVHTOperation) ); + } + if ( pBeacon->VHTExtBssLoad.present ) + { + vos_mem_copy( &pBeaconStruct->VHTExtBssLoad, &pBeacon->VHTExtBssLoad, + sizeof( tDot11fIEVHTExtBssLoad) ); + } + if(pBeacon->OperatingMode.present) + { + vos_mem_copy( &pBeaconStruct->OperatingMode, &pBeacon->OperatingMode, + sizeof( tDot11fIEOperatingMode) ); + } + if(pBeacon->WiderBWChanSwitchAnn.present) + { + pBeaconStruct->WiderBWChanSwitchAnnPresent = 1; + vos_mem_copy( &pBeaconStruct->WiderBWChanSwitchAnn, &pBeacon->WiderBWChanSwitchAnn, + sizeof( tDot11fIEWiderBWChanSwitchAnn)); + } +#endif + + /* IBSS Peer Params */ + if(pBeacon->IBSSParams.present) + { + pBeaconStruct->IBSSParams.present = 1; + vos_mem_copy( &pBeaconStruct->IBSSParams, &pBeacon->IBSSParams, + sizeof( tDot11fIEIBSSParams )); + } + + pBeaconStruct->Vendor1IEPresent = pBeacon->Vendor1IE.present; + pBeaconStruct->Vendor2IEPresent = pBeacon->Vendor2IE.present; + pBeaconStruct->Vendor3IEPresent = pBeacon->Vendor3IE.present; + + vos_mem_free(pBeacon); + return eSIR_SUCCESS; + +} // End sirConvertBeaconFrame2Struct. + +tSirRetStatus +sirConvertAuthFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirMacAuthFrameBody pAuth) +{ + static tDot11fAuthentication auth; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAuth, sizeof(tSirMacAuthFrameBody), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAuthentication( pMac, pFrame, nFrame, &auth ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Authentication frame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... + pAuth->authAlgoNumber = auth.AuthAlgo.algo; + pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no; + pAuth->authStatusCode = auth.Status.status; + + if ( auth.ChallengeText.present ) + { + pAuth->type = SIR_MAC_CHALLENGE_TEXT_EID; + pAuth->length = auth.ChallengeText.num_text; + vos_mem_copy( pAuth->challengeText, auth.ChallengeText.text, auth.ChallengeText.num_text ); + } + + return eSIR_SUCCESS; + +} // End sirConvertAuthFrame2Struct. + +tSirRetStatus +sirConvertAddtsReq2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirAddtsReqInfo *pAddTs) +{ + tDot11fAddTSRequest addts = {{0}}; + tDot11fWMMAddTSRequest wmmaddts = {{0}}; + tANI_U8 j; + tANI_U16 i; + tANI_U32 status; + + if ( SIR_MAC_QOS_ADD_TS_REQ != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertAddtsReq2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAddTs, sizeof(tSirAddtsReqInfo), 0 ); + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackAddTSRequest( pMac, pFrame, nFrame, &addts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMAddTSRequest( pMac, pFrame, nFrame, &wmmaddts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertAddtsReq2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Add TS Request f" + "rame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Add TS Request frame (0x%08x," + "%d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAddTSRequest' or a + // 'tDot11WMMAddTSRequest' to a 'tSirMacAddtsReqInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pAddTs->dialogToken = addts.DialogToken.token; + + if ( addts.TSPEC.present ) + { + ConvertTSPEC( pMac, &pAddTs->tspec, &addts.TSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory TSPEC element missing in Add TS Request.\n") ); + return eSIR_FAILURE; + } + + if ( addts.num_TCLAS ) + { + pAddTs->numTclas = (tANI_U8)addts.num_TCLAS; + + for ( i = 0U; i < addts.num_TCLAS; ++i ) + { + if ( eSIR_SUCCESS != ConvertTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.TCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.\n") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.TCLASSPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.TCLASSPROC.processing; + } + + if ( addts.WMMTSPEC.present ) + { + pAddTs->wsmTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &addts.WMMTSPEC ); + } + + if ( addts.num_WMMTCLAS ) + { + j = (tANI_U8)(pAddTs->numTclas + addts.num_WMMTCLAS); + if ( SIR_MAC_TCLASIE_MAXNUM > j ) j = SIR_MAC_TCLASIE_MAXNUM; + + for ( i = pAddTs->numTclas; i < j; ++i ) + { + if ( eSIR_SUCCESS != ConvertWMMTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.WMMTCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.\n") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.WMMTCLASPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.WMMTCLASPROC.processing; + } + + if ( 1 < pAddTs->numTclas && ( ! pAddTs->tclasProcPresent ) ) + { + limLog( pMac, LOGE, FL("%d TCLAS IE but not TCLASPROC IE.\n"), + pAddTs->numTclas ); + return eSIR_FAILURE; + } + } + else + { + pAddTs->dialogToken = wmmaddts.DialogToken.token; + + if ( wmmaddts.WMMTSPEC.present ) + { + pAddTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &wmmaddts.WMMTSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!\n") ); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; + +} // End sirConvertAddtsReq2Struct. + +tSirRetStatus +sirConvertAddtsRsp2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirAddtsRspInfo *pAddTs) +{ + tDot11fAddTSResponse addts = {{0}}; + tDot11fWMMAddTSResponse wmmaddts = {{0}}; + tANI_U8 j; + tANI_U16 i; + tANI_U32 status; + + if ( SIR_MAC_QOS_ADD_TS_RSP != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertAddtsRsp2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAddTs, sizeof(tSirAddtsRspInfo), 0 ); + vos_mem_set( ( tANI_U8* )&addts, sizeof(tDot11fAddTSResponse), 0 ); + vos_mem_set( ( tANI_U8* )&wmmaddts, sizeof(tDot11fWMMAddTSResponse), 0 ); + + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackAddTSResponse( pMac, pFrame, nFrame, &addts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMAddTSResponse( pMac, pFrame, nFrame, &wmmaddts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertAddtsRsp2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Add TS Response f" + "rame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Add TS Response frame (0x%08x," + "%d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAddTSResponse' or a + // 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pAddTs->dialogToken = addts.DialogToken.token; + pAddTs->status = ( tSirMacStatusCodes )addts.Status.status; + + if ( addts.TSDelay.present ) + { + ConvertTSDelay( pMac, &pAddTs->delay, &addts.TSDelay ); + } + + // TS Delay is present iff status indicates its presence + if ( eSIR_MAC_TS_NOT_CREATED_STATUS == pAddTs->status && ! addts.TSDelay.present ) + { + limLog( pMac, LOGW, FL("Missing TSDelay IE.\n") ); + } + + if ( addts.TSPEC.present ) + { + ConvertTSPEC( pMac, &pAddTs->tspec, &addts.TSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory TSPEC element missing in Add TS Response.\n") ); + return eSIR_FAILURE; + } + + if ( addts.num_TCLAS ) + { + pAddTs->numTclas = (tANI_U8)addts.num_TCLAS; + + for ( i = 0U; i < addts.num_TCLAS; ++i ) + { + if ( eSIR_SUCCESS != ConvertTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.TCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.\n") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.TCLASSPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.TCLASSPROC.processing; + } +#ifdef FEATURE_WLAN_ESE + if(addts.ESETrafStrmMet.present) + { + pAddTs->tsmPresent = 1; + vos_mem_copy(&pAddTs->tsmIE.tsid, + &addts.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + if ( addts.Schedule.present ) + { + pAddTs->schedulePresent = 1; + ConvertSchedule( pMac, &pAddTs->schedule, &addts.Schedule ); + } + + if ( addts.WMMSchedule.present ) + { + pAddTs->schedulePresent = 1; + ConvertWMMSchedule( pMac, &pAddTs->schedule, &addts.WMMSchedule ); + } + + if ( addts.WMMTSPEC.present ) + { + pAddTs->wsmTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &addts.WMMTSPEC ); + } + + if ( addts.num_WMMTCLAS ) + { + j = (tANI_U8)(pAddTs->numTclas + addts.num_WMMTCLAS); + if ( SIR_MAC_TCLASIE_MAXNUM > j ) j = SIR_MAC_TCLASIE_MAXNUM; + + for ( i = pAddTs->numTclas; i < j; ++i ) + { + if ( eSIR_SUCCESS != ConvertWMMTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.WMMTCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.\n") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.WMMTCLASPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.WMMTCLASPROC.processing; + } + + if ( 1 < pAddTs->numTclas && ( ! pAddTs->tclasProcPresent ) ) + { + limLog( pMac, LOGE, FL("%d TCLAS IE but not TCLASPROC IE.\n"), + pAddTs->numTclas ); + return eSIR_FAILURE; + } + } + else + { + pAddTs->dialogToken = wmmaddts.DialogToken.token; + pAddTs->status = ( tSirMacStatusCodes )wmmaddts.StatusCode.statusCode; + + if ( wmmaddts.WMMTSPEC.present ) + { + pAddTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &wmmaddts.WMMTSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!\n") ); + return eSIR_FAILURE; + } + +#ifdef FEATURE_WLAN_ESE + if(wmmaddts.ESETrafStrmMet.present) + { + pAddTs->tsmPresent = 1; + vos_mem_copy(&pAddTs->tsmIE.tsid, + &wmmaddts.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + + } + + return eSIR_SUCCESS; + +} // End sirConvertAddtsRsp2Struct. + +tSirRetStatus +sirConvertDeltsReq2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirDeltsReqInfo *pDelTs) +{ + tDot11fDelTS delts = {{0}}; + tDot11fWMMDelTS wmmdelts = {{0}}; + tANI_U32 status; + + if ( SIR_MAC_QOS_DEL_TS_REQ != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pDelTs, sizeof(tSirDeltsReqInfo), 0 ); + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackDelTS( pMac, pFrame, nFrame, &delts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMDelTS( pMac, pFrame, nFrame, &wmmdelts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Del TS Request f" + "rame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Del TS Request frame (0x%08x," + "%d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fDelTSResponse' or a + // 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pDelTs->tsinfo.traffic.trafficType = (tANI_U16)delts.TSInfo.traffic_type; + pDelTs->tsinfo.traffic.tsid = (tANI_U16)delts.TSInfo.tsid; + pDelTs->tsinfo.traffic.direction = (tANI_U16)delts.TSInfo.direction; + pDelTs->tsinfo.traffic.accessPolicy = (tANI_U16)delts.TSInfo.access_policy; + pDelTs->tsinfo.traffic.aggregation = (tANI_U16)delts.TSInfo.aggregation; + pDelTs->tsinfo.traffic.psb = (tANI_U16)delts.TSInfo.psb; + pDelTs->tsinfo.traffic.userPrio = (tANI_U16)delts.TSInfo.user_priority; + pDelTs->tsinfo.traffic.ackPolicy = (tANI_U16)delts.TSInfo.tsinfo_ack_pol; + + pDelTs->tsinfo.schedule.schedule = (tANI_U8)delts.TSInfo.schedule; + } + else + { + if ( wmmdelts.WMMTSPEC.present ) + { + pDelTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pDelTs->tspec, &wmmdelts.WMMTSPEC ); + } + else + { + dot11fLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!\n") ); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; + +} // End sirConvertDeltsReq2Struct. + +tSirRetStatus +sirConvertQosMapConfigureFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirQosMapSet *pQosMapSet) +{ + tDot11fQosMapConfigure mapConfigure; + tANI_U32 status; + status = dot11fUnpackQosMapConfigure(pMac, pFrame, nFrame, &mapConfigure); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse Qos Map Configure frame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + pQosMapSet->present = mapConfigure.QosMapSet.present; + ConvertQosMapsetFrame(pMac->hHdd, pQosMapSet, &mapConfigure.QosMapSet); + limLogQosMapSet(pMac, pQosMapSet); + return eSIR_SUCCESS; +} + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +sirConvertTpcReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirMacTpcReqActionFrame pTpcReqFrame, + tANI_U32 nFrame) +{ + tDot11fTPCRequest req; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pTpcReqFrame, sizeof(tSirMacTpcReqActionFrame), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackTPCRequest( pMac, pFrame, nFrame, &req ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse a TPC Request frame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fTPCRequest' to a + // 'tSirMacTpcReqActionFrame'... + pTpcReqFrame->actionHeader.category = req.Category.category; + pTpcReqFrame->actionHeader.actionID = req.Action.action; + pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token; + if ( req.TPCRequest.present ) + { + pTpcReqFrame->type = DOT11F_EID_TPCREQUEST; + pTpcReqFrame->length = 0; + } + else + { + dot11fLog( pMac, LOGW, FL("!!!Rcv TPC Req of inalid type!\n") ); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End sirConvertTpcReqFrame2Struct. + + +tSirRetStatus +sirConvertMeasReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tANI_U32 nFrame) +{ + tDot11fMeasurementRequest mr; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pMeasReqFrame, sizeof(tpSirMacMeasReqActionFrame), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackMeasurementRequest( pMac, pFrame, nFrame, &mr ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse a Measurement Request frame (0x%08x, %d bytes):\n"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes):\n"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fMeasurementRequest' to a + // 'tpSirMacMeasReqActionFrame'... + pMeasReqFrame->actionHeader.category = mr.Category.category; + pMeasReqFrame->actionHeader.actionID = mr.Action.action; + pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token; + + if ( 0 == mr.num_MeasurementRequest ) + { + dot11fLog( pMac, LOGE, FL("Missing mandatory IE in Measurement Request Frame.\n") ); + return eSIR_FAILURE; + } + else if ( 1 < mr.num_MeasurementRequest ) + { + limLog( pMac, LOGW, FL("Warning: dropping extra Measurement Request IEs!") ); + } + + pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST; + pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN; + pMeasReqFrame->measReqIE.measToken = mr.MeasurementRequest[0].measurement_token; + pMeasReqFrame->measReqIE.measReqMode = ( mr.MeasurementRequest[0].reserved << 3 ) | + ( mr.MeasurementRequest[0].enable << 2 ) | + ( mr.MeasurementRequest[0].request << 1 ) | + ( mr.MeasurementRequest[0].report /*<< 0*/ ); + pMeasReqFrame->measReqIE.measType = mr.MeasurementRequest[0].measurement_type; + + pMeasReqFrame->measReqIE.measReqField.channelNumber = mr.MeasurementRequest[0].channel_no; + + vos_mem_copy( pMeasReqFrame->measReqIE.measReqField.measStartTime, + mr.MeasurementRequest[0].meas_start_time, 8 ); + + pMeasReqFrame->measReqIE.measReqField.measDuration = mr.MeasurementRequest[0].meas_duration; + + return eSIR_SUCCESS; + +} // End sirConvertMeasReqFrame2Struct. +#endif + + +void +PopulateDot11fTSPEC(tSirMacTspecIE *pOld, + tDot11fIETSPEC *pDot11f) +{ + pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; + pDot11f->tsid = pOld->tsinfo.traffic.tsid; + pDot11f->direction = pOld->tsinfo.traffic.direction; + pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; + pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; + pDot11f->psb = pOld->tsinfo.traffic.psb; + pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; + pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; + pDot11f->schedule = pOld->tsinfo.schedule.schedule; + /* As defined in IEEE 802.11-2007, section 7.3.2.30 + * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed + */ + pDot11f->size = ( pOld->nomMsduSz & 0x7fff ); + pDot11f->fixed = ( pOld->nomMsduSz & 0x8000 ) ? 1 : 0; + pDot11f->max_msdu_size = pOld->maxMsduSz; + pDot11f->min_service_int = pOld->minSvcInterval; + pDot11f->max_service_int = pOld->maxSvcInterval; + pDot11f->inactivity_int = pOld->inactInterval; + pDot11f->suspension_int = pOld->suspendInterval; + pDot11f->service_start_time = pOld->svcStartTime; + pDot11f->min_data_rate = pOld->minDataRate; + pDot11f->mean_data_rate = pOld->meanDataRate; + pDot11f->peak_data_rate = pOld->peakDataRate; + pDot11f->burst_size = pOld->maxBurstSz; + pDot11f->delay_bound = pOld->delayBound; + pDot11f->min_phy_rate = pOld->minPhyRate; + pDot11f->surplus_bw_allowance = pOld->surplusBw; + pDot11f->medium_time = pOld->mediumTime; + + pDot11f->present = 1; + +} // End PopulateDot11fTSPEC. + +void +PopulateDot11fWMMTSPEC(tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pDot11f) +{ + pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; + pDot11f->tsid = pOld->tsinfo.traffic.tsid; + pDot11f->direction = pOld->tsinfo.traffic.direction; + pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; + pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; + pDot11f->psb = pOld->tsinfo.traffic.psb; + pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; + pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; + pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn; + /* As defined in IEEE 802.11-2007, section 7.3.2.30 + * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed + */ + pDot11f->size = ( pOld->nomMsduSz & 0x7fff ); + pDot11f->fixed = ( pOld->nomMsduSz & 0x8000 ) ? 1 : 0; + pDot11f->max_msdu_size = pOld->maxMsduSz; + pDot11f->min_service_int = pOld->minSvcInterval; + pDot11f->max_service_int = pOld->maxSvcInterval; + pDot11f->inactivity_int = pOld->inactInterval; + pDot11f->suspension_int = pOld->suspendInterval; + pDot11f->service_start_time = pOld->svcStartTime; + pDot11f->min_data_rate = pOld->minDataRate; + pDot11f->mean_data_rate = pOld->meanDataRate; + pDot11f->peak_data_rate = pOld->peakDataRate; + pDot11f->burst_size = pOld->maxBurstSz; + pDot11f->delay_bound = pOld->delayBound; + pDot11f->min_phy_rate = pOld->minPhyRate; + pDot11f->surplus_bw_allowance = pOld->surplusBw; + pDot11f->medium_time = pOld->mediumTime; + + pDot11f->version = 1; + pDot11f->present = 1; + +} // End PopulateDot11fWMMTSPEC. + +#if defined(FEATURE_WLAN_ESE) +// Fill the ESE version currently supported +void PopulateDot11fESEVersion(tDot11fIEESEVersion *pESEVersion) +{ + pESEVersion->present = 1; + pESEVersion->version = ESE_VERSION_SUPPORTED; +} +// Fill the ESE ie for the station. +// The State is Normal (1) +// The MBSSID for station is set to 0. +void PopulateDot11fESERadMgmtCap(tDot11fIEESERadMgmtCap *pESERadMgmtCap) +{ + pESERadMgmtCap->present = 1; + pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL; + pESERadMgmtCap->mbssid_mask = 0; + pESERadMgmtCap->reserved = 0; +} +tSirRetStatus PopulateDot11fESECckmOpaque( tpAniSirGlobal pMac, + tpSirCCKMie pCCKMie, + tDot11fIEESECckmOpaque *pDot11f ) +{ + int idx; + if ( pCCKMie->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, (tpSirRSNie)pCCKMie, + DOT11F_EID_ESECCKMOPAQUE ) ) ) + { + pDot11f->present = 1; + // Dont include OUI + pDot11f->num_data = pCCKMie->cckmIEdata[ idx + 1 ] - 4; + vos_mem_copy ( pDot11f->data, + pCCKMie->cckmIEdata + idx + 2 + 4, //EID,len,OUI + pCCKMie->cckmIEdata[ idx + 1 ] - 4 ); // Skip OUI + } + } + return eSIR_SUCCESS; +} // End PopulateDot11fESECckmOpaque. + +void PopulateDot11TSRSIE(tpAniSirGlobal pMac, + tSirMacESETSRSIE *pOld, + tDot11fIEESETrafStrmRateSet *pDot11f, + tANI_U8 rate_length) +{ + pDot11f->tsid = pOld->tsid; + vos_mem_copy(pDot11f->tsrates, pOld->rates,rate_length); + pDot11f->num_tsrates = rate_length; + pDot11f->present = 1; +} +#endif + + +tSirRetStatus +PopulateDot11fTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pDot11f) +{ + pDot11f->user_priority = pOld->tclas.userPrio; + pDot11f->classifier_type = pOld->tclas.classifierType; + pDot11f->classifier_mask = pOld->tclas.classifierMask; + + switch ( pDot11f->classifier_type ) + { + case SIR_MAC_TCLASTYPE_ETHERNET: + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.source, + ( tANI_U8* )&pOld->tclasParams.eth.srcAddr, 6 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.dest, + ( tANI_U8* )&pOld->tclasParams.eth.dstAddr, 6 ); + pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; + break; + case SIR_MAC_TCLASTYPE_TCPUDPIP: + pDot11f->info.IpParams.version = pOld->version; + if ( SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version ) + { + vos_mem_copy( pDot11f->info.IpParams.params. + IpV4Params.source, + pOld->tclasParams.ipv4.srcIpAddr, 4 ); + vos_mem_copy( pDot11f->info.IpParams.params. + IpV4Params.dest, + pOld->tclasParams.ipv4.dstIpAddr, 4 ); + pDot11f->info.IpParams.params.IpV4Params.src_port = + pOld->tclasParams.ipv4.srcPort; + pDot11f->info.IpParams.params.IpV4Params.dest_port = + pOld->tclasParams.ipv4.dstPort; + pDot11f->info.IpParams.params.IpV4Params.DSCP = + pOld->tclasParams.ipv4.dscp; + pDot11f->info.IpParams.params.IpV4Params.proto = + pOld->tclasParams.ipv4.protocol; + pDot11f->info.IpParams.params.IpV4Params.reserved = + pOld->tclasParams.ipv4.rsvd; + } + else + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.source, + ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, 16 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, 16 ); + pDot11f->info.IpParams.params.IpV6Params.src_port = + pOld->tclasParams.ipv6.srcPort; + pDot11f->info.IpParams.params.IpV6Params.dest_port = + pOld->tclasParams.ipv6.dstPort; + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.flow_label, + ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, 3 ); + } + break; + case SIR_MAC_TCLASTYPE_8021DQ: + pDot11f->info.Params8021dq.tag_type = pOld->tclasParams.t8021dq.tag; + break; + default: + limLog( pMac, LOGE, FL("Bad TCLAS type %d in PopulateDot11fTCLAS.\n"), + pDot11f->classifier_type ); + return eSIR_FAILURE; + } + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fTCLAS. + +tSirRetStatus +PopulateDot11fWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pDot11f) +{ + pDot11f->version = 1; + pDot11f->user_priority = pOld->tclas.userPrio; + pDot11f->classifier_type = pOld->tclas.classifierType; + pDot11f->classifier_mask = pOld->tclas.classifierMask; + + switch ( pDot11f->classifier_type ) + { + case SIR_MAC_TCLASTYPE_ETHERNET: + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.source, + ( tANI_U8* )&pOld->tclasParams.eth.srcAddr, 6 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.dest, + ( tANI_U8* )&pOld->tclasParams.eth.dstAddr, 6 ); + pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; + break; + case SIR_MAC_TCLASTYPE_TCPUDPIP: + pDot11f->info.IpParams.version = pOld->version; + if ( SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version ) + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV4Params.source, + ( tANI_U8* )pOld->tclasParams.ipv4.srcIpAddr, 4 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV4Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv4.dstIpAddr, 4 ); + pDot11f->info.IpParams.params.IpV4Params.src_port = + pOld->tclasParams.ipv4.srcPort; + pDot11f->info.IpParams.params.IpV4Params.dest_port = + pOld->tclasParams.ipv4.dstPort; + pDot11f->info.IpParams.params.IpV4Params.DSCP = + pOld->tclasParams.ipv4.dscp; + pDot11f->info.IpParams.params.IpV4Params.proto = + pOld->tclasParams.ipv4.protocol; + pDot11f->info.IpParams.params.IpV4Params.reserved = + pOld->tclasParams.ipv4.rsvd; + } + else + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.source, + ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, 16 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, 16 ); + pDot11f->info.IpParams.params.IpV6Params.src_port = + pOld->tclasParams.ipv6.srcPort; + pDot11f->info.IpParams.params.IpV6Params.dest_port = + pOld->tclasParams.ipv6.dstPort; + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.flow_label, + ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, 3 ); + } + break; + case SIR_MAC_TCLASTYPE_8021DQ: + pDot11f->info.Params8021dq.tag_type = pOld->tclasParams.t8021dq.tag; + break; + default: + limLog( pMac, LOGE, FL("Bad TCLAS type %d in PopulateDot11fTCLAS.\n"), + pDot11f->classifier_type ); + return eSIR_FAILURE; + } + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fWMMTCLAS. + + +tSirRetStatus PopulateDot11fWsc(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + + tANI_U32 wpsState; + + pDot11f->Version.present = 1; + pDot11f->Version.major = 0x01; + pDot11f->Version.minor = 0x00; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_STATE, &wpsState) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_STATE ); + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8) wpsState; + + pDot11f->APSetupLocked.present = 0; + + pDot11f->SelectedRegistrar.present = 0; + + pDot11f->DevicePasswordID.present = 0; + + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + pDot11f->UUID_E.present = 0; + + pDot11f->RFBands.present = 0; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); + tANI_U32 devicepasswdId; + + + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; + + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_DEVICE_PASSWORD_ID, &devicepasswdId) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_DEVICE_PASSWORD_ID ); + + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = (tANI_U16) devicepasswdId; + + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pWscIeInfo->selectedRegistrarConfigMethods; + + // UUID_E and RF Bands are applicable only for dual band AP + + return eSIR_SUCCESS; +} + +tSirRetStatus DePopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + pDot11f->APSetupLocked.present = 0; + pDot11f->SelectedRegistrar.present = 0; + pDot11f->DevicePasswordID.present = 0; + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fProbeResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscProbeRes *pDot11f, tpPESession psessionEntry) +{ + + tSirWPSProbeRspIE *pSirWPSProbeRspIE; + + pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; + + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSProbeRspIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSProbeRspIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) + { + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8)pSirWPSProbeRspIE->wpsState; + } + else + pDot11f->WPSState.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) + { + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pSirWPSProbeRspIE->APSetupLocked; + } + else + pDot11f->APSetupLocked.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) + { + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pSirWPSProbeRspIE->SelectedRegistra; + } + else + pDot11f->SelectedRegistrar.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) + { + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = pSirWPSProbeRspIE->DevicePasswordID; + } + else + pDot11f->DevicePasswordID.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) + { + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pSirWPSProbeRspIE->SelectedRegistraCfgMethod; + } + else + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) + { + pDot11f->ResponseType.present = 1; + pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; + } + else + pDot11f->ResponseType.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) + { + pDot11f->UUID_E.present = 1; + vos_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E, WNI_CFG_WPS_UUID_LEN); + } + else + pDot11f->UUID_E.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) + { + pDot11f->Manufacturer.present = 1; + pDot11f->Manufacturer.num_name = pSirWPSProbeRspIE->Manufacture.num_name; + vos_mem_copy(pDot11f->Manufacturer.name, pSirWPSProbeRspIE->Manufacture.name, + pSirWPSProbeRspIE->Manufacture.num_name); + } + else + pDot11f->Manufacturer.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) + { + pDot11f->ModelName.present = 1; + pDot11f->ModelName.num_text = pSirWPSProbeRspIE->ModelName.num_text; + vos_mem_copy(pDot11f->ModelName.text, pSirWPSProbeRspIE->ModelName.text, + pDot11f->ModelName.num_text); + } + else + pDot11f->ModelName.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) + { + pDot11f->ModelNumber.present = 1; + pDot11f->ModelNumber.num_text = pSirWPSProbeRspIE->ModelNumber.num_text; + vos_mem_copy(pDot11f->ModelNumber.text, pSirWPSProbeRspIE->ModelNumber.text, + pDot11f->ModelNumber.num_text); + } + else + pDot11f->ModelNumber.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) + { + pDot11f->SerialNumber.present = 1; + pDot11f->SerialNumber.num_text = pSirWPSProbeRspIE->SerialNumber.num_text; + vos_mem_copy(pDot11f->SerialNumber.text, pSirWPSProbeRspIE->SerialNumber.text, + pDot11f->SerialNumber.num_text); + } + else + pDot11f->SerialNumber.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) + { + pDot11f->PrimaryDeviceType.present = 1; + vos_mem_copy(pDot11f->PrimaryDeviceType.oui, pSirWPSProbeRspIE->PrimaryDeviceOUI, + sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI)); + pDot11f->PrimaryDeviceType.primary_category = (tANI_U16)pSirWPSProbeRspIE->PrimaryDeviceCategory; + pDot11f->PrimaryDeviceType.sub_category = (tANI_U16)pSirWPSProbeRspIE->DeviceSubCategory; + } + else + pDot11f->PrimaryDeviceType.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) + { + pDot11f->DeviceName.present = 1; + pDot11f->DeviceName.num_text = pSirWPSProbeRspIE->DeviceName.num_text; + vos_mem_copy(pDot11f->DeviceName.text, pSirWPSProbeRspIE->DeviceName.text, + pDot11f->DeviceName.num_text); + } + else + pDot11f->DeviceName.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) + { + pDot11f->ConfigMethods.present = 1; + pDot11f->ConfigMethods.methods = pSirWPSProbeRspIE->ConfigMethod; + } + else + pDot11f->ConfigMethods.present = 0; + + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) + { + pDot11f->RFBands.present = 1; + pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand; + } + else + pDot11f->RFBands.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fAssocResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscAssocRes *pDot11f, tpPESession psessionEntry) +{ + tSirWPSProbeRspIE *pSirWPSProbeRspIE; + + pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSProbeRspIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSProbeRspIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) + { + pDot11f->ResponseType.present = 1; + pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; + } + else + pDot11f->ResponseType.present = 0; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fBeaconWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscBeacon *pDot11f, tpPESession psessionEntry) +{ + + tSirWPSBeaconIE *pSirWPSBeaconIE; + + pSirWPSBeaconIE = &psessionEntry->APWPSIEs.SirWPSBeaconIE; + + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSBeaconIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSBeaconIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) + { + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8)pSirWPSBeaconIE->wpsState; + } + else + pDot11f->WPSState.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) + { + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked; + } + else + pDot11f->APSetupLocked.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) + { + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pSirWPSBeaconIE->SelectedRegistra; + } + else + pDot11f->SelectedRegistrar.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) + { + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = pSirWPSBeaconIE->DevicePasswordID; + } + else + pDot11f->DevicePasswordID.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) + { + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pSirWPSBeaconIE->SelectedRegistraCfgMethod; + } + else + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) + { + pDot11f->UUID_E.present = 1; + vos_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E, WNI_CFG_WPS_UUID_LEN); + } + else + pDot11f->UUID_E.present = 0; + + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) + { + pDot11f->RFBands.present = 1; + pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand; + } + else + pDot11f->RFBands.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fWscInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + tANI_U32 cfgMethods; + tANI_U32 cfgStrLen; + tANI_U32 val; + tANI_U32 wpsVersion, wpsState; + + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_VERSION, &wpsVersion) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_VERSION ); + + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((wpsVersion & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (wpsVersion & 0x0F); + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_STATE, &wpsState) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_STATE ); + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8) wpsState; + + pDot11f->APSetupLocked.present = 0; + + pDot11f->SelectedRegistrar.present = 0; + + pDot11f->DevicePasswordID.present = 0; + + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + pDot11f->ResponseType.present = 1; + if ((pMac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) || + (pMac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)){ + pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X; + } + else{ + pDot11f->ResponseType.resType = RESP_TYPE_AP; + } + + /* UUID is a 16 byte long binary. Still use wlan_cfgGetStr to get it. */ + pDot11f->UUID_E.present = 1; + cfgStrLen = WNI_CFG_WPS_UUID_LEN; + if (wlan_cfgGetStr(pMac, + WNI_CFG_WPS_UUID, + pDot11f->UUID_E.uuid, + &cfgStrLen) != eSIR_SUCCESS) + { + *(pDot11f->UUID_E.uuid) = '\0'; + } + + pDot11f->Manufacturer.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_NAME, + pDot11f->Manufacturer.name, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->Manufacturer.num_name = 0; + *(pDot11f->Manufacturer.name) = '\0'; + } + else + { + pDot11f->Manufacturer.num_name = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->Manufacturer.name[cfgStrLen] = '\0'; + } + + pDot11f->ModelName.present = 1; + cfgStrLen = WNI_CFG_MODEL_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MODEL_NAME, + pDot11f->ModelName.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->ModelName.num_text = 0; + *(pDot11f->ModelName.text) = '\0'; + } + else + { + pDot11f->ModelName.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->ModelName.text[cfgStrLen] = '\0'; + } + + pDot11f->ModelNumber.present = 1; + cfgStrLen = WNI_CFG_MODEL_NUMBER_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MODEL_NUMBER, + pDot11f->ModelNumber.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->ModelNumber.num_text = 0; + *(pDot11f->ModelNumber.text) = '\0'; + } + else + { + pDot11f->ModelNumber.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->ModelNumber.text[cfgStrLen] = '\0'; + } + + pDot11f->SerialNumber.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_PRODUCT_VERSION, + pDot11f->SerialNumber.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->SerialNumber.num_text = 0; + *(pDot11f->SerialNumber.text) = '\0'; + } + else + { + pDot11f->SerialNumber.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->SerialNumber.text[cfgStrLen] = '\0'; + } + + pDot11f->PrimaryDeviceType.present = 1; + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device category failed\n")); + } + else + pDot11f->PrimaryDeviceType.primary_category = (tANI_U16) val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_PIMARY_DEVICE_OUI, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device OUI failed\n")); + } + else + { + *(pDot11f->PrimaryDeviceType.oui) = (tANI_U8)((val >> 24)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+1) = (tANI_U8)((val >> 16)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+2) = (tANI_U8)((val >> 8)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+3) = (tANI_U8)((val & 0xff)); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_DEVICE_SUB_CATEGORY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device sub category failed\n")); + } + else + pDot11f->PrimaryDeviceType.sub_category = (tANI_U16) val; + + pDot11f->DeviceName.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_PRODUCT_NAME, + pDot11f->DeviceName.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->DeviceName.num_text = 0; + *(pDot11f->DeviceName.text) = '\0'; + } + else + { + pDot11f->DeviceName.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->DeviceName.text[cfgStrLen] = '\0'; + } + + if (wlan_cfgGetInt(pMac, + WNI_CFG_WPS_CFG_METHOD, + &cfgMethods) != eSIR_SUCCESS) + { + pDot11f->ConfigMethods.present = 0; + pDot11f->ConfigMethods.methods = 0; + } + else + { + pDot11f->ConfigMethods.present = 1; + pDot11f->ConfigMethods.methods = (tANI_U16) (cfgMethods & 0x0000FFFF); + } + + pDot11f->RFBands.present = 0; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); + tANI_U32 devicepasswdId; + + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; + + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_DEVICE_PASSWORD_ID, &devicepasswdId) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_DEVICE_PASSWORD_ID ); + + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = (tANI_U16) devicepasswdId; + + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pWscIeInfo->selectedRegistrarConfigMethods; + + // UUID_E and RF Bands are applicable only for dual band AP + + return eSIR_SUCCESS; +} + +tSirRetStatus DePopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + pDot11f->APSetupLocked.present = 0; + pDot11f->SelectedRegistrar.present = 0; + pDot11f->DevicePasswordID.present = 0; + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fAssocResWscIE(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq) +{ + tDot11fIEWscAssocReq parsedWscAssocReq = { 0, }; + tANI_U8 *wscIe; + + + wscIe = limGetWscIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, pRcvdAssocReq->addIE.length); + if(wscIe != NULL) + { + // retreive WSC IE from given AssocReq + dot11fUnpackIeWscAssocReq( pMac, + wscIe + 2 + 4, // EID, length, OUI + wscIe[ 1 ] - 4, // length without OUI + &parsedWscAssocReq ); + pDot11f->present = 1; + // version has to be 0x10 + pDot11f->Version.present = 1; + pDot11f->Version.major = 0x1; + pDot11f->Version.minor = 0x0; + + pDot11f->ResponseType.present = 1; + + if ((parsedWscAssocReq.RequestType.reqType == REQ_TYPE_REGISTRAR) || + (parsedWscAssocReq.RequestType.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) + { + pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X; + } + else + { + pDot11f->ResponseType.resType = RESP_TYPE_AP; + } + // Version infomration should be taken from our capability as well as peers + // TODO: currently it takes from peers only + if(parsedWscAssocReq.VendorExtension.present && + parsedWscAssocReq.VendorExtension.Version2.present) + { + pDot11f->VendorExtension.present = 1; + pDot11f->VendorExtension.vendorId[0] = 0x00; + pDot11f->VendorExtension.vendorId[1] = 0x37; + pDot11f->VendorExtension.vendorId[2] = 0x2A; + pDot11f->VendorExtension.Version2.present = 1; + pDot11f->VendorExtension.Version2.major = parsedWscAssocReq.VendorExtension.Version2.major; + pDot11f->VendorExtension.Version2.minor = parsedWscAssocReq.VendorExtension.Version2.minor; + } + } + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11AssocResP2PIE(tpAniSirGlobal pMac, + tDot11fIEP2PAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq) +{ + tANI_U8 *p2pIe; + + p2pIe = limGetP2pIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, pRcvdAssocReq->addIE.length); + if(p2pIe != NULL) + { + pDot11f->present = 1; + pDot11f->P2PStatus.present = 1; + pDot11f->P2PStatus.status = eSIR_SUCCESS; + pDot11f->ExtendedListenTiming.present = 0; + } + return eSIR_SUCCESS; +} + +#if defined WLAN_FEATURE_VOWIFI + +tSirRetStatus PopulateDot11fWFATPC( tpAniSirGlobal pMac, + tDot11fIEWFATPC *pDot11f, tANI_U8 txPower, tANI_U8 linkMargin ) +{ + pDot11f->txPower = txPower; + pDot11f->linkMargin = linkMargin; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fBeaconReport( tpAniSirGlobal pMac, tDot11fIEMeasurementReport *pDot11f, tSirMacBeaconReport *pBeaconReport ) +{ + + pDot11f->report.Beacon.regClass = pBeaconReport->regClass; + pDot11f->report.Beacon.channel = pBeaconReport->channel; + vos_mem_copy( pDot11f->report.Beacon.meas_start_time, pBeaconReport->measStartTime, + sizeof(pDot11f->report.Beacon.meas_start_time) ); + pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration; + pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType; + pDot11f->report.Beacon.reported_frame_type = !pBeaconReport->bcnProbeRsp; + pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi; + pDot11f->report.Beacon.RSNI = pBeaconReport->rsni; + vos_mem_copy( pDot11f->report.Beacon.BSSID, pBeaconReport->bssid, sizeof(tSirMacAddr)); + pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId; + pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF; + + if( pBeaconReport->numIes ) + { + pDot11f->report.Beacon.BeaconReportFrmBody.present = 1; + vos_mem_copy( pDot11f->report.Beacon.BeaconReportFrmBody.reportedFields, + pBeaconReport->Ies, pBeaconReport->numIes ); + pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields = pBeaconReport->numIes; + } + + return eSIR_SUCCESS; + +} + +tSirRetStatus PopulateDot11fRRMIe( tpAniSirGlobal pMac, tDot11fIERRMEnabledCap *pDot11f, tpPESession psessionEntry ) +{ + tpRRMCaps pRrmCaps; + + pRrmCaps = rrmGetCapabilities( pMac, psessionEntry ); + + pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement ; + pDot11f->NeighborRpt = pRrmCaps->NeighborRpt ; + pDot11f->parallel = pRrmCaps->parallel ; + pDot11f->repeated = pRrmCaps->repeated ; + pDot11f->BeaconPassive = pRrmCaps->BeaconPassive ; + pDot11f->BeaconActive = pRrmCaps->BeaconActive ; + pDot11f->BeaconTable = pRrmCaps->BeaconTable ; + pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond ; + pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement ; + pDot11f->ChannelLoad = pRrmCaps->ChannelLoad ; + pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram ; + pDot11f->statistics = pRrmCaps->statistics ; + pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement ; + pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth ; + pDot11f->TCMCapability = pRrmCaps->TCMCapability ; + pDot11f->triggeredTCM = pRrmCaps->triggeredTCM ; + pDot11f->APChanReport = pRrmCaps->APChanReport ; + pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled ; + pDot11f->operatingChanMax = pRrmCaps->operatingChanMax ; + pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax ; + pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot ; + pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled ; + pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset ; + pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement ; + pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement ; + pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay ; + pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission ; + pDot11f->AntennaInformation = pRrmCaps->AntennaInformation ; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +void PopulateMDIE( tpAniSirGlobal pMac, + tDot11fIEMobilityDomain *pDot11f, tANI_U8 mdie[SIR_MDIE_SIZE] ) +{ + pDot11f->present = 1; + pDot11f->MDID = (tANI_U16)((mdie[1] << 8) | (mdie[0])); + + // Plugfest fix + pDot11f->overDSCap = (mdie[2] & 0x01); + pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01); + +} + +void PopulateFTInfo( tpAniSirGlobal pMac, + tDot11fIEFTInfo *pDot11f ) +{ + pDot11f->present = 1; + pDot11f->IECount = 0; //TODO: put valid data during reassoc. + //All other info is zero. + +} +#endif + +void PopulateDot11fAssocRspRates ( tpAniSirGlobal pMac, tDot11fIESuppRates *pSupp, + tDot11fIEExtSuppRates *pExt, tANI_U16 *_11bRates, tANI_U16 *_11aRates ) +{ + tANI_U8 num_supp = 0, num_ext = 0; + tANI_U8 i,j; + + for( i = 0 ; (i < SIR_NUM_11B_RATES && _11bRates[i]) ; i++, num_supp++ ) + { + pSupp->rates[num_supp] = (tANI_U8)_11bRates[i]; + } + for( j = 0 ; (j < SIR_NUM_11A_RATES && _11aRates[j]) ; j++ ) + { + if( num_supp < 8 ) + pSupp->rates[num_supp++] = (tANI_U8)_11aRates[j]; + else + pExt->rates[num_ext++] = (tANI_U8)_11aRates[j]; + } + + if( num_supp ) + { + pSupp->num_rates = num_supp; + pSupp->present = 1; + } + if( num_ext ) + { + pExt->num_rates = num_ext; + pExt->present = 1; + } +} + +void PopulateDot11fTimeoutInterval( tpAniSirGlobal pMac, + tDot11fIETimeoutInterval *pDot11f, + tANI_U8 type, tANI_U32 value ) +{ + pDot11f->present = 1; + pDot11f->timeoutType = type; + pDot11f->timeoutValue = value; +} +// parserApi.c ends here. diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/utilsApi.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/utilsApi.c new file mode 100644 index 0000000000000..6bdd50ee5ba67 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/utilsApi.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//================================================================== +// +// File: utilsApi.cc +// +// Description: Implemention of a few utility routines. +// +// Author: Neelay Das +// +//// +// Change gHistory: +// 12/15/2003 - NDA - Initial version. +// +//=================================================================== + + +#include "utilsApi.h" + + + + + +// ------------------------------------------------------------------- +/** + * sirDumpBuf() + * + * FUNCTION: + * This function is called to dump a buffer with a certain level + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf: buffer pointer + * @return None. + */ +void +sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size) +{ + tANI_U32 i; + + if (level > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(modId)]) + return; + + logDbg(pMac, modId, level, FL("Dumping %d bytes in host order\n"), size); + + for (i=0; (i+7)length = pNew->num_ssid; + vos_mem_copy( pOld->ssId, pNew->ssid, pNew->num_ssid ); +} + +void ConvertSuppRates(tpAniSirGlobal pMac, + tSirMacRateSet *pOld, + tDot11fIESuppRates *pNew) +{ + pOld->numRates = pNew->num_rates; + vos_mem_copy( pOld->rate, pNew->rates, pNew->num_rates ); +} + +void ConvertExtSuppRates(tpAniSirGlobal pMac, + tSirMacRateSet *pOld, + tDot11fIEExtSuppRates *pNew) +{ + pOld->numRates = pNew->num_rates; + vos_mem_copy( pOld->rate, pNew->rates, pNew->num_rates ); +} + + +void ConvertQOSCaps(tpAniSirGlobal pMac, + tSirMacQosCapabilityIE *pOld, + tDot11fIEQOSCapsAp *pNew) +{ + pOld->type = 46; + pOld->length = 1; + + pOld->qosInfo.count = pNew->count; +} + + +void ConvertQOSCapsStation(tpAniSirGlobal pMac, + tSirMacQosCapabilityStaIE *pOld, + tDot11fIEQOSCapsStation *pNew) +{ + pOld->type = 46; + pOld->length = 1; + + pOld->qosInfo.moreDataAck = pNew->more_data_ack; + pOld->qosInfo.maxSpLen = pNew->max_sp_length; + pOld->qosInfo.qack = pNew->qack; + pOld->qosInfo.acbe_uapsd = pNew->acbe_uapsd; + pOld->qosInfo.acbk_uapsd = pNew->acbk_uapsd; + pOld->qosInfo.acvi_uapsd = pNew->acvi_uapsd; + pOld->qosInfo.acvo_uapsd = pNew->acvo_uapsd; +} + +tSirRetStatus ConvertWPA(tpAniSirGlobal pMac, + tSirMacWpaInfo *pOld, + tDot11fIEWPA *pNew) +{ + // This is awful, I know, but the old code just rammed the IE into an + // array... + tANI_U8 buffer[257]; + tANI_U32 status, written = 0, nbuffer = 257; + status = dot11fPackIeWPA( pMac, pNew, buffer, nbuffer, &written ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOG2, FL("Failed to re-pack the WPA IE (0x%0x" + "8).\n"), status); + return eSIR_FAILURE; + } + + pOld->length = (tANI_U8)written - 2; + vos_mem_copy( pOld->info, buffer + 2, pOld->length ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertWPAOpaque( tpAniSirGlobal pMac, + tSirMacWpaInfo *pOld, + tDot11fIEWPAOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the OUI! + pOld->length = pNew->num_data + 4; + pOld->info[ 0 ] = 0x00; + pOld->info[ 1 ] = 0x50; + pOld->info[ 2 ] = 0xf2; + pOld->info[ 3 ] = 0x01; + vos_mem_copy( pOld->info + 4, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertWscOpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEWscIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x00; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0xf2; + pOld->addIEdata[ curAddIELen++ ] = 0x04; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertP2POpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEP2PIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0x6f; + pOld->addIEdata[ curAddIELen++ ] = 0x9A; + pOld->addIEdata[ curAddIELen++ ] = 0x09; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_WFD +tSirRetStatus ConvertWFDOpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEWFDIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0x6f; + pOld->addIEdata[ curAddIELen++ ] = 0x9A; + pOld->addIEdata[ curAddIELen++ ] = 0x0a; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} +#endif + +tSirRetStatus ConvertRSN(tpAniSirGlobal pMac, + tSirMacRsnInfo *pOld, + tDot11fIERSN *pNew) +{ + tANI_U8 buffer[257]; + tANI_U32 status, written = 0, nbuffer = 257; + status = dot11fPackIeRSN( pMac, pNew, buffer, nbuffer, &written ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOG2, FL("Failed to re-pack the RSN IE (0x%0x" + "8).\n"), status); + return eSIR_FAILURE; + } + + pOld->length = (tANI_U8)written - 2; + vos_mem_copy( pOld->info, buffer + 2, pOld->length ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertRSNOpaque( tpAniSirGlobal pMac, + tSirMacRsnInfo *pOld, + tDot11fIERSNOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. + pOld->length = pNew->num_data; + vos_mem_copy( pOld->info, pNew->data, pOld->length ); + + return eSIR_SUCCESS; +} + +void ConvertPowerCaps(tpAniSirGlobal pMac, + tSirMacPowerCapabilityIE *pOld, + tDot11fIEPowerCaps *pNew) +{ + pOld->type = 33; + pOld->length = 2; + pOld->minTxPower = pNew->minTxPower; + pOld->maxTxPower = pNew->maxTxPower; +} + +void ConvertSuppChannels(tpAniSirGlobal pMac, + tSirMacSupportedChannelIE *pOld, + tDot11fIESuppChannels *pNew) +{ + pOld->type = 36; + pOld->length = ( pNew->num_bands * 2 ); + vos_mem_copy( ( tANI_U8* )pOld->supportedChannels, ( tANI_U8* )pNew->bands, pOld->length ); +} + +void ConvertCFParams(tpAniSirGlobal pMac, + tSirMacCfParamSet *pOld, + tDot11fIECFParams *pNew) +{ + pOld->cfpCount = pNew->cfp_count; + pOld->cfpPeriod = pNew->cfp_period; + pOld->cfpMaxDuration = pNew->cfp_maxduration; + pOld->cfpDurRemaining = pNew->cfp_durremaining; +} + +void ConvertFHParams (tpAniSirGlobal pMac, + tSirMacFHParamSet *pOld, + tDot11fIEFHParamSet *pNew) +{ + pOld->dwellTime = pNew->dwell_time; + pOld->hopSet = pNew->hop_set; + pOld->hopPattern = pNew->hop_pattern; + pOld->hopIndex = pNew->hop_index; +} + +void ConvertTIM(tpAniSirGlobal pMac, + tSirMacTim *pOld, + tDot11fIETIM *pNew) +{ + pOld->dtimCount = pNew->dtim_count; + pOld->dtimPeriod = pNew->dtim_period; + pOld->bitmapControl = pNew->bmpctl; + pOld->bitmapLength = pNew->num_vbmp; + + vos_mem_copy( pOld->bitmap, pNew->vbmp, pNew->num_vbmp ); +} + +void ConvertCountry(tpAniSirGlobal pMac, + tSirCountryInformation *pOld, + tDot11fIECountry *pNew) +{ + int i; + + vos_mem_copy( pOld->countryString, pNew->country, COUNTRY_STRING_LENGTH ); + + pOld->numIntervals = pNew->num_triplets; + + for (i = 0; i < pNew->num_triplets; ++i) + { + pOld->channelTransmitPower[i].channelNumber = pNew->triplets[i][0]; + pOld->channelTransmitPower[i].numChannel = pNew->triplets[i][1]; + pOld->channelTransmitPower[i].maxTransmitPower = pNew->triplets[i][2]; + } +} + +void ConvertWMMParams(tpAniSirGlobal pMac, + tSirMacEdcaParamSetIE *pOld, + tDot11fIEWMMParams *pNew) +{ + pOld->type = 221; + pOld->length = 24; + + vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qosInfo, 1 ); + + pOld->acbe.aci.aifsn = pNew->acbe_aifsn; + pOld->acbe.aci.acm = pNew->acbe_acm; + pOld->acbe.aci.aci = pNew->acbe_aci; + pOld->acbe.cw.min = pNew->acbe_acwmin; + pOld->acbe.cw.max = pNew->acbe_acwmax; + pOld->acbe.txoplimit = pNew->acbe_txoplimit; + + pOld->acbk.aci.aifsn = pNew->acbk_aifsn; + pOld->acbk.aci.acm = pNew->acbk_acm; + pOld->acbk.aci.aci = pNew->acbk_aci; + pOld->acbk.cw.min = pNew->acbk_acwmin; + pOld->acbk.cw.max = pNew->acbk_acwmax; + pOld->acbk.txoplimit = pNew->acbk_txoplimit; + + pOld->acvi.aci.aifsn = pNew->acvi_aifsn; + pOld->acvi.aci.acm = pNew->acvi_acm; + pOld->acvi.aci.aci = pNew->acvi_aci; + pOld->acvi.cw.min = pNew->acvi_acwmin; + pOld->acvi.cw.max = pNew->acvi_acwmax; + pOld->acvi.txoplimit = pNew->acvi_txoplimit; + + pOld->acvo.aci.aifsn = pNew->acvo_aifsn; + pOld->acvo.aci.acm = pNew->acvo_acm; + pOld->acvo.aci.aci = pNew->acvo_aci; + pOld->acvo.cw.min = pNew->acvo_acwmin; + pOld->acvo.cw.max = pNew->acvo_acwmax; + pOld->acvo.txoplimit = pNew->acvo_txoplimit; +} + +void ConvertERPInfo(tpAniSirGlobal pMac, + tSirMacErpInfo *pOld, + tDot11fIEERPInfo *pNew) +{ + pOld->nonErpPresent = pNew->non_erp_present; + pOld->useProtection = pNew->use_prot; + pOld->barkerPreambleMode = pNew->barker_preamble; +} + +void ConvertEDCAParam(tpAniSirGlobal pMac, + tSirMacEdcaParamSetIE *pOld, + tDot11fIEEDCAParamSet *pNew) +{ + pOld->type = 12; + pOld->length = 20; + + vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qos, 1 ); + + pOld->acbe.aci.aifsn = pNew->acbe_aifsn; + pOld->acbe.aci.acm = pNew->acbe_acm; + pOld->acbe.aci.aci = pNew->acbe_aci; + pOld->acbe.cw.min = pNew->acbe_acwmin; + pOld->acbe.cw.max = pNew->acbe_acwmax; + pOld->acbe.txoplimit = pNew->acbe_txoplimit; + + pOld->acbk.aci.aifsn = pNew->acbk_aifsn; + pOld->acbk.aci.acm = pNew->acbk_acm; + pOld->acbk.aci.aci = pNew->acbk_aci; + pOld->acbk.cw.min = pNew->acbk_acwmin; + pOld->acbk.cw.max = pNew->acbk_acwmax; + pOld->acbk.txoplimit = pNew->acbk_txoplimit; + + pOld->acvi.aci.aifsn = pNew->acvi_aifsn; + pOld->acvi.aci.acm = pNew->acvi_acm; + pOld->acvi.aci.aci = pNew->acvi_aci; + pOld->acvi.cw.min = pNew->acvi_acwmin; + pOld->acvi.cw.max = pNew->acvi_acwmax; + pOld->acvi.txoplimit = pNew->acvi_txoplimit; + + pOld->acvo.aci.aifsn = pNew->acvo_aifsn; + pOld->acvo.aci.acm = pNew->acvo_acm; + pOld->acvo.aci.aci = pNew->acvo_aci; + pOld->acvo.cw.min = pNew->acvo_acwmin; + pOld->acvo.cw.max = pNew->acvo_acwmax; + pOld->acvo.txoplimit = pNew->acvo_txoplimit; + +} + +void ConvertTSPEC(tpAniSirGlobal pMac, + tSirMacTspecIE *pOld, + tDot11fIETSPEC *pNew) +{ + pOld->tsinfo.traffic.trafficType = (tANI_U16)pNew->traffic_type; + pOld->tsinfo.traffic.tsid = (tANI_U16)pNew->tsid; + pOld->tsinfo.traffic.direction = (tANI_U16)pNew->direction; + pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy; + pOld->tsinfo.traffic.aggregation = (tANI_U16)pNew->aggregation; + pOld->tsinfo.traffic.psb = (tANI_U16)pNew->psb; + pOld->tsinfo.traffic.userPrio = (tANI_U16)pNew->user_priority; + pOld->tsinfo.traffic.ackPolicy = (tANI_U16)pNew->tsinfo_ack_pol; + + pOld->tsinfo.schedule.schedule = (tANI_U8)pNew->schedule; + + pOld->nomMsduSz = pNew->size; + pOld->maxMsduSz = pNew->max_msdu_size; + pOld->minSvcInterval = pNew->min_service_int; + pOld->maxSvcInterval = pNew->max_service_int; + pOld->inactInterval = pNew->inactivity_int; + pOld->suspendInterval = pNew->suspension_int; + pOld->svcStartTime = pNew->service_start_time; + pOld->minDataRate = pNew->min_data_rate; + pOld->meanDataRate = pNew->mean_data_rate; + pOld->peakDataRate = pNew->peak_data_rate; + pOld->maxBurstSz = pNew->burst_size; + pOld->delayBound = pNew->delay_bound; + pOld->minPhyRate = pNew->min_phy_rate; + pOld->surplusBw = pNew->surplus_bw_allowance; + pOld->mediumTime = pNew->medium_time; +} + +tSirRetStatus ConvertTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pNew) +{ + tANI_U32 length = 0; + + if ( DOT11F_FAILED( dot11fGetPackedIETCLAS( pMac, pNew, &length ) ) ) + { + return eSIR_FAILURE; + } + + pOld->tclas.type = DOT11F_EID_TCLAS; + pOld->tclas.length = (tANI_U8)length; + pOld->tclas.userPrio = pNew->user_priority; + pOld->tclas.classifierType = pNew->classifier_type; + pOld->tclas.classifierMask = pNew->classifier_mask; + + switch ( pNew->classifier_type ) + { + case 0: + vos_mem_copy( pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 ); + vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 ); + pOld->tclasParams.eth.type = pNew->info.EthParams.type; + break; + case 1: + pOld->version = pNew->info.IpParams.version; + if ( 4 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv4.version = 4; + vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr, + pNew->info.IpParams.params.IpV4Params.source, 4 ); + vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr, + pNew->info.IpParams.params.IpV4Params.dest, 4 ); + pOld->tclasParams.ipv4.srcPort = pNew->info.IpParams.params.IpV4Params.src_port; + pOld->tclasParams.ipv4.dstPort = pNew->info.IpParams.params.IpV4Params.dest_port; + pOld->tclasParams.ipv4.dscp = pNew->info.IpParams.params.IpV4Params.DSCP; + pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto; + pOld->tclasParams.ipv4.rsvd = pNew->info.IpParams.params.IpV4Params.reserved; + } + else if ( 6 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv6.version = 6; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 ); + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 ); + pOld->tclasParams.ipv6.srcPort = pNew->info.IpParams.params.IpV6Params.src_port; + pOld->tclasParams.ipv6.dstPort = pNew->info.IpParams.params.IpV6Params.dest_port; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 ); + } + else + { + return eSIR_FAILURE; + } + break; + case 2: + pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type; + break; + default: + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +void ConvertWMMTSPEC(tpAniSirGlobal pMac, + tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pNew) +{ + pOld->tsinfo.traffic.trafficType = (tANI_U16)pNew->traffic_type; + pOld->tsinfo.traffic.tsid = (tANI_U16)pNew->tsid; + pOld->tsinfo.traffic.direction = (tANI_U16)pNew->direction; + pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy; + pOld->tsinfo.traffic.aggregation = (tANI_U16)pNew->aggregation; + pOld->tsinfo.traffic.psb = (tANI_U16)pNew->psb; + pOld->tsinfo.traffic.userPrio = (tANI_U16)pNew->user_priority; + pOld->tsinfo.traffic.ackPolicy = (tANI_U16)pNew->tsinfo_ack_pol; + pOld->nomMsduSz = (pNew->fixed << 15) | pNew->size; + pOld->maxMsduSz = pNew->max_msdu_size; + pOld->minSvcInterval = pNew->min_service_int; + pOld->maxSvcInterval = pNew->max_service_int; + pOld->inactInterval = pNew->inactivity_int; + pOld->suspendInterval = pNew->suspension_int; + pOld->svcStartTime = pNew->service_start_time; + pOld->minDataRate = pNew->min_data_rate; + pOld->meanDataRate = pNew->mean_data_rate; + pOld->peakDataRate = pNew->peak_data_rate; + pOld->maxBurstSz = pNew->burst_size; + pOld->delayBound = pNew->delay_bound; + pOld->minPhyRate = pNew->min_phy_rate; + pOld->surplusBw = pNew->surplus_bw_allowance; + pOld->mediumTime = pNew->medium_time; +} + +tSirRetStatus ConvertWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pNew) +{ + tANI_U32 length = 0; + + if ( DOT11F_FAILED( dot11fGetPackedIEWMMTCLAS( pMac, pNew, &length ) ) ) + { + return eSIR_FAILURE; + } + + pOld->tclas.type = DOT11F_EID_WMMTCLAS; + pOld->tclas.length = (tANI_U8)length; + pOld->tclas.userPrio = pNew->user_priority; + pOld->tclas.classifierType = pNew->classifier_type; + pOld->tclas.classifierMask = pNew->classifier_mask; + + switch ( pNew->classifier_type ) + { + case 0: + vos_mem_copy( pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 ); + vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 ); + pOld->tclasParams.eth.type = pNew->info.EthParams.type; + break; + case 1: + pOld->version = pNew->info.IpParams.version; + if ( 4 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv4.version = 4; + vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr, + pNew->info.IpParams.params.IpV4Params.source, 4 ); + vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr, + pNew->info.IpParams.params.IpV4Params.dest, 4 ); + pOld->tclasParams.ipv4.srcPort = pNew->info.IpParams.params.IpV4Params.src_port; + pOld->tclasParams.ipv4.dstPort = pNew->info.IpParams.params.IpV4Params.dest_port; + pOld->tclasParams.ipv4.dscp = pNew->info.IpParams.params.IpV4Params.DSCP; + pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto; + pOld->tclasParams.ipv4.rsvd = pNew->info.IpParams.params.IpV4Params.reserved; + } + else if ( 6 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv6.version = 6; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 ); + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 ); + pOld->tclasParams.ipv6.srcPort = pNew->info.IpParams.params.IpV6Params.src_port; + pOld->tclasParams.ipv6.dstPort = pNew->info.IpParams.params.IpV6Params.dest_port; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 ); + } + else + { + return eSIR_FAILURE; + } + break; + case 2: + pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type; + break; + default: + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +void ConvertTSDelay(tpAniSirGlobal pMac, + tSirMacTsDelayIE *pOld, + tDot11fIETSDelay *pNew) +{ + pOld->type = DOT11F_EID_TSDELAY; + pOld->length = 4U; + pOld->delay = pNew->delay; +} + +void ConvertSchedule(tpAniSirGlobal pMac, + tSirMacScheduleIE *pOld, + tDot11fIESchedule *pNew) +{ + pOld->type = DOT11F_EID_SCHEDULE; + pOld->length = DOT11F_IE_SCHEDULE_MIN_LEN; + + pOld->info.aggregation = pNew->aggregation; + pOld->info.tsid = pNew->tsid; + pOld->info.direction = pNew->direction; + + pOld->svcStartTime = pNew->service_start_time; + pOld->svcInterval = pNew->service_interval; + pOld->specInterval = pNew->spec_interval; +} + +void ConvertWMMSchedule(tpAniSirGlobal pMac, + tSirMacScheduleIE *pOld, + tDot11fIEWMMSchedule *pNew) +{ + pOld->type = DOT11F_EID_WMMSCHEDULE; + pOld->length = DOT11F_IE_WMMSCHEDULE_MIN_LEN; + + pOld->info.aggregation = pNew->aggregation; + pOld->info.tsid = pNew->tsid; + pOld->info.direction = pNew->direction; + + pOld->svcStartTime = pNew->service_start_time; + pOld->svcInterval = pNew->service_interval; + pOld->specInterval = pNew->spec_interval; +} + +/** + @brief : This functions converts the given buffer till given size to Big endian format assuming the + bus is 32 bit. The size should be four byte aligned. + @param : ptr to be converted, size + @return : void +*/ + +void ConverttoBigEndian(void *ptr, tANI_U16 size) +{ + tANI_U8 *temp_ptr; + tANI_U32 *dest_ptr; + + dest_ptr = (tANI_U32 *)ptr; + while(size) + { + temp_ptr = (tANI_U8 *) dest_ptr; + *dest_ptr = (temp_ptr[0] << 24) | (temp_ptr[1] << 16) | (temp_ptr[2] << 8) | temp_ptr[3]; + dest_ptr++; + size -= 4; + } +} + + +void CreateScanDataNullFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, + tANI_U8 pwrMgmt, tSirMacAddr bssid, tSirMacAddr selfMacAddr) +{ + + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = pwrMgmt; + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)&macMgmtHdr->da, + (void *)bssid, sizeof(tSirMacAddr)); + vos_mem_copy( (void *)&macMgmtHdr->sa, + (void *)selfMacAddr, sizeof(tSirMacAddr)); + vos_mem_copy( (void *)&macMgmtHdr->bssId, + (void *)bssid, sizeof(tSirMacAddr)); + + return; +} + + +void CreateScanCtsFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tSirMacAddr selfMac) +{ + macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + vos_mem_copy( (void *)macMgmtHdr->da, (void *)selfMac, sizeof(tSirMacAddr)); + + return; +} + +void ConvertQosMapsetFrame(tpAniSirGlobal pMac, tSirQosMapSet* Qos, tDot11fIEQosMapSet* dot11fIE) +{ + tANI_U8 i,j=0; + Qos->num_dscp_exceptions = (dot11fIE->num_dscp_exceptions - 16)/2; + for (i = 0; i < Qos->num_dscp_exceptions; i++) + { + Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j]; + j++; + Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j]; + j++; + } + for (i = 0; i < 8; i++) + { + Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j]; + j++; + Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j]; + j++; + } +} + +/** + @brief : This functions creates a DATA_NULL/CTS2SELF frame in Big endian format + @param : Global MAC structure, pointer to return the created packet, role which is Station/AP + @return : void +*/ + +void CreateInitScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role) +{ +#if 0 + tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable; + + if (role == eSYSTEM_STA_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 1; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 1; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)&macMgmtHdr->da, (void *)pSta[0].bssId, 6); + vos_mem_copy( &macMgmtHdr->sa, pSta[0].staAddr, 6); + vos_mem_copy( (void *)&macMgmtHdr->bssId, (void *)pSta[0].bssId, 6); + } + else if (role == eSYSTEM_AP_ROLE || role == eSYSTEM_STA_IN_IBSS_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].staAddr, 6); + } + return; +#endif +} + +/** + @brief : This functions creates a DATA_NULL frame in Big endian format + @param : Global MAC structure, pointer to return the created packet, role which is Station/AP + @return : void +*/ + + +void CreateFinishScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role) +{ +#if 0 + tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable; + + if (role == eSYSTEM_STA_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 1; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].bssId, 6); + vos_mem_copy( macMgmtHdr->sa, pSta[0].staAddr, 6); + vos_mem_copy( (void *)macMgmtHdr->bssId, (void *)pSta[0].bssId, 6); + + } + + return; +#endif +} + + +// utilsParser.c ends here. diff --git a/drivers/staging/qcacld-2.0/CORE/TL/inc/wlan_qct_tl.h b/drivers/staging/qcacld-2.0/CORE/TL/inc/wlan_qct_tl.h new file mode 100644 index 0000000000000..1051889d395bc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/TL/inc/wlan_qct_tl.h @@ -0,0 +1,3205 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef WLAN_QCT_WLANTL_H +#define WLAN_QCT_WLANTL_H + +/*=========================================================================== + + W L A N T R A N S P O R T L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan transport layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +01/08/10 lti Added TL Data Caching +10/15/09 rnair Modifying STADescType struct +10/06/09 rnair Adding support for WAPI +09/22/09 lti Add deregistration API for management client +02/02/09 sch Add Handoff support +12/09/08 lti Fixes for AMSS compilation +09/05/08 lti Fixes after QOS unit testing +08/06/08 lti Added QOS support +05/01/08 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +#include "sirApi.h" +#include "csrApi.h" +#include "sapApi.h" +#include "adf_nbuf.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_OFFSET 3 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_SIZE 3 + +/*Offset of the LLC/SNAP header*/ +#define WLANTL_LLC_SNAP_OFFSET 0 + +/*Size of the LLC/SNAP header*/ +#define WLANTL_LLC_SNAP_SIZE 8 + +/*============================================================================ + * GENERIC STRUCTURES - not belonging to TL + * TO BE MOVED TO A GLOBAL HEADER + ============================================================================*/ +/*Maximum number of ACs */ +#define WLANTL_MAX_AC 4 + +/* Maximum number of station supported by TL, including BC. */ +#define WLAN_MAX_STA_COUNT (HAL_NUM_STA) +#define WLAN_NON32_STA_COUNT 14 +/* The symbolic station ID return to HDD to specify the packet is bc/mc */ +#define WLAN_RX_BCMC_STA_ID (WLAN_MAX_STA_COUNT + 1) + +/* The symbolic station ID return to HDD to specify the packet is to soft-AP itself */ +#define WLAN_RX_SAP_SELF_STA_ID (WLAN_MAX_STA_COUNT + 2) + +/* Used by HDS systme. This station ID is used by TL to tell upper layer that + this packet is for WDS and not for a loopback for an associated station. */ +#define WLANTL_RX_WDS_STAID WLAN_MAX_STA_COUNT + +/* Station ID used for BC traffic. This value will be used when upper layer registers + the broadcast client or allocate station strcuture to keep per-station info.*/ +//#define WLANTL_BC_STA_ID 0x00 + + +#define WLANTL_MAX_TID 15 +/* Default RSSI average Alpha */ +#define WLANTL_HO_DEFAULT_ALPHA 5 +#define WLANTL_HO_TDLS_ALPHA 7 + +// Choose the largest possible value that can be accomodates in 8 bit signed +// variable. +#define SNR_HACK_BMPS (127) +/*-------------------------------------------------------------------------- + Access category enum used by TL + - order must be kept as these values are used to setup the AC mask + --------------------------------------------------------------------------*/ +typedef enum +{ + WLANTL_AC_BK = 0, + WLANTL_AC_BE = 1, + WLANTL_AC_VI = 2, + WLANTL_AC_VO = 3 +}WLANTL_ACEnumType; + +/*--------------------------------------------------------------------------- + STA Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Indicates a link to an AP*/ + WLAN_STA_INFRA = 0, + + /* AD-hoc link*/ + WLAN_STA_IBSS, + + /* BT-AMP link*/ + WLAN_STA_BT_AMP, + + /* SoftAP station */ + WLAN_STA_SOFTAP, + +#ifdef FEATURE_WLAN_TDLS + /* TDLS direct link */ + WLAN_STA_TDLS, /* 4 */ +#endif + + + /* Invalid link*/ + WLAN_STA_MAX + +}WLAN_STAType; + +/*--------------------------------------------------------------------------- + BAP Management frame type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* BT-AMP packet of type data */ + WLANTL_BT_AMP_TYPE_DATA = 0x0001, + + /* BT-AMP packet of type activity report */ + WLANTL_BT_AMP_TYPE_AR = 0x0002, + + /* BT-AMP packet of type security frame */ + WLANTL_BT_AMP_TYPE_SEC = 0x0003, + + /* BT-AMP packet of type Link Supervision request frame */ + WLANTL_BT_AMP_TYPE_LS_REQ = 0x0004, + + /* BT-AMP packet of type Link Supervision reply frame */ + WLANTL_BT_AMP_TYPE_LS_REP = 0x0005, + + /* Invalid Frame */ + WLANTL_BAP_INVALID_FRAME + +} WLANTL_BAPFrameEnumType; + +/* Type used to specify LWM threshold unit */ +typedef enum { + WLAN_LWM_THRESHOLD_BYTE = 0, + + WLAN_LWM_THRESHOLD_PACKET +} WLAN_LWM_Threshold_Type; + +/*--------------------------------------------------------------------------- + TL States +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Transition in this state made upon creation*/ + WLANTL_STA_INIT = 0, + + /* Transition happens after Assoc success if second level authentication + is needed*/ + WLANTL_STA_CONNECTED, + + /* Transition happens when second level auth is successful and keys are + properly installed */ + WLANTL_STA_AUTHENTICATED, + + /* Transition happens when connectivity is lost*/ + WLANTL_STA_DISCONNECTED, + + WLANTL_STA_MAX_STATE +}WLANTL_STAStateType; + + +/*--------------------------------------------------------------------------- + STA Descriptor Type +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA unique identifier, originating from HAL*/ + v_U8_t ucSTAId; + + /*STA MAC Address*/ + v_MACADDR_t vSTAMACAddress; + + /*BSSID for IBSS*/ + v_MACADDR_t vBSSIDforIBSS; + + /*Self MAC Address*/ + v_MACADDR_t vSelfMACAddress; + + /*Type of the STA*/ + WLAN_STAType wSTAType; + + /*flag for setting the state of the QOS for the link*/ + v_U8_t ucQosEnabled; + + /*enable FT in TL */ + v_U8_t ucSwFrameTXXlation; + v_U8_t ucSwFrameRXXlation; + + /*Flag for signaling TL if LLC header needs to be added for outgoing + packets*/ + v_U8_t ucAddRmvLLC; + + /*Flag for signaling if the privacy bit needs to be set*/ + v_U8_t ucProtectedFrame; + + /*DPU Signature used for unicast data - used for data caching*/ + v_U8_t ucUcastSig; + /*Flag to indicate if STA is a WAPI STA*/ + v_U8_t ucIsWapiSta; + +#ifdef FEATURE_WLAN_ESE + /*Flag to indicate if STA is a ESE STA*/ + v_U8_t ucIsEseSta; +#endif + + /*DPU Signature used for broadcast data - used for data caching*/ + v_U8_t ucBcastSig; + + /*Initial state at which the STA should be brought up to*/ + WLANTL_STAStateType ucInitState; + /* 1 means replay check is needed for the station, + 0 means replay check is not needed for the station*/ + v_BOOL_t ucIsReplayCheckValid; +}WLAN_STADescType; + +/*--------------------------------------------------------------------------- + TL Configuration +---------------------------------------------------------------------------*/ +typedef struct +{ + /*AC weight for WFQ*/ + v_U8_t ucAcWeights[WLANTL_MAX_AC]; + + /*Delayed trigger frame timmer: - used by TL to send trigger frames less + often when it has established that the App is suspended*/ + v_U32_t uDelayedTriggerFrmInt; + + /* Min Threshold for Processing Frames in TL */ + v_U8_t uMinFramesProcThres; + + /* Ip checksum offload */ + v_BOOL_t ip_checksum_offload; + + /* Rx processing in thread from TL shim */ + v_BOOL_t enable_rxthread; + + /* Re-order Aging Time */ + v_U16_t ucReorderAgingTime[WLANTL_MAX_AC]; +}WLANTL_ConfigInfoType; + +/*--------------------------------------------------------------------------- + TSPEC Direction Enum Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* uplink */ + WLANTL_TX_DIR = 0, + + /* downlink */ + WLANTL_RX_DIR = 1, + + /*bidirectional*/ + WLANTL_BI_DIR = 2, +}WLANTL_TSDirType; + +/*============================================================================ + * GENERIC STRUCTURES - END + ============================================================================*/ + + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + TL Error Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Generic error */ + WLANTL_ERROR = 0, + + /* No rx callback registered for data path */ + WLANTL_NO_RX_DATA_CB, + + /* No rx callback registered for management path*/ + WLANTL_NO_RX_MGMT_CB, + + /* Generic memory error*/ + WLANTL_MEM_ERROR, + + /* Bus error notified by BAL */ + WLANTL_BUS_ERROR + +}WLANTL_ErrorType; + +/*--------------------------------------------------------------------------- + STA priority type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* STA gets to tx every second round*/ + WLANTL_STA_PRI_VERY_LOW = -2, + + /* STA gets to tx every other round*/ + WLANTL_STA_PRI_LOW = -1, + + /* STA gets to tx each time */ + WLANTL_STA_PRI_NORMAL = 0, + + /* STA gets to tx twice each time*/ + WLANTL_STA_PRI_HIGH = 1, + + /* STA gets to tx three times each time*/ + WLANTL_STA_PRI_VERY_HIGH = 2 + +}WLANTL_STAPriorityType; + +/*--------------------------------------------------------------------------- + Meta information requested from HDD by TL +---------------------------------------------------------------------------*/ +typedef struct +{ + /* TID of the packet being sent */ + v_U8_t ucTID; + + /* UP of the packet being sent */ + v_U8_t ucUP; + + /* notifying TL if this is an EAPOL frame or not */ + v_U8_t ucIsEapol; +#ifdef FEATURE_WLAN_WAPI + /* notifying TL if this is a WAI frame or not */ + v_U8_t ucIsWai; +#endif + /* frame is 802.11 and it does not need translation */ + v_U8_t ucDisableFrmXtl; + + /* frame is broadcast */ + v_U8_t ucBcast; + + /* frame is multicast */ + v_U8_t ucMcast; + + /* frame type */ + v_U8_t ucType; + + /* timestamp */ + v_U16_t usTimeStamp; + + /* STA has more packets to send */ + v_BOOL_t bMorePackets; +}WLANTL_MetaInfoType; + +/*--------------------------------------------------------------------------- + Meta information provided by TL to HDD on rx path +---------------------------------------------------------------------------*/ +typedef struct +{ + /* UP of the packet being sent */ + v_U8_t ucUP; + /* Address 3 Index of the received packet */ + v_U16_t ucDesSTAId; + /*Rssi based on the received packet */ + v_S7_t rssiAvg; + #ifdef FEATURE_WLAN_TDLS + /* Packet received on direct link/AP link */ + v_U8_t isStaTdls; + #endif +}WLANTL_RxMetaInfoType; + + +/*--------------------------------------------------------------------------- + Handoff support and statistics defines and enum types +---------------------------------------------------------------------------*/ +/* Threshold crossed event type definitions */ +#define WLANTL_HO_THRESHOLD_NA 0x00 +#define WLANTL_HO_THRESHOLD_DOWN 0x01 +#define WLANTL_HO_THRESHOLD_UP 0x02 +#define WLANTL_HO_THRESHOLD_CROSS 0x04 + +/* Realtime traffic status */ +typedef enum +{ + WLANTL_HO_RT_TRAFFIC_STATUS_OFF, + WLANTL_HO_RT_TRAFFIC_STATUS_ON +} WLANTL_HO_RT_TRAFFIC_STATUS_TYPE; + +/* Non-Realtime traffic status */ +typedef enum +{ + WLANTL_HO_NRT_TRAFFIC_STATUS_OFF, + WLANTL_HO_NRT_TRAFFIC_STATUS_ON +} WLANTL_HO_NRT_TRAFFIC_STATUS_TYPE; + +/* Statistics type TL supported */ +typedef enum +{ + WLANTL_STATIC_TX_UC_FCNT, + WLANTL_STATIC_TX_MC_FCNT, + WLANTL_STATIC_TX_BC_FCNT, + WLANTL_STATIC_TX_UC_BCNT, + WLANTL_STATIC_TX_MC_BCNT, + WLANTL_STATIC_TX_BC_BCNT, + WLANTL_STATIC_RX_UC_FCNT, + WLANTL_STATIC_RX_MC_FCNT, + WLANTL_STATIC_RX_BC_FCNT, + WLANTL_STATIC_RX_UC_BCNT, + WLANTL_STATIC_RX_MC_BCNT, + WLANTL_STATIC_RX_BC_BCNT, + WLANTL_STATIC_RX_BCNT, + WLANTL_STATIC_RX_BCNT_CRC_OK, + WLANTL_STATIC_RX_RATE +} WLANTL_TRANSFER_STATIC_TYPE; + +/*--------------------------------------------------------------------------- + Handoff support and statistics structures +---------------------------------------------------------------------------*/ +typedef struct +{ + WLANTL_HO_RT_TRAFFIC_STATUS_TYPE rtTrafficStatus; + WLANTL_HO_NRT_TRAFFIC_STATUS_TYPE nrtTrafficStatus; +} WLANTL_HO_TRAFFIC_STATUS_TYPE; + +typedef tSap_SoftapStats WLANTL_TRANSFER_STA_TYPE; + +/* Under here not public items, just use for internal */ +/* 3 SME 1 HDD */ +#define WLANTL_MAX_AVAIL_THRESHOLD 5 +#define WLANTL_HS_NUM_CLIENT 2 +#define WLANTL_SINGLE_CLNT_THRESHOLD 4 + +/*---------------------------------------------------------------------------- + * TL callback types + *--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_TxCompCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* pFrameDataBuff, + VOS_STATUS wTxSTAtus ); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HDD + ---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_STAFetchPktCBType)( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo); + + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. This version of rx callback will have HDD + adapter pointer and received data buffer in adf_nbuf format. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + pDataBuff: pointer to the adf_nbuf data buffer that was received + (it may be a linked list) + ucSTAId: station id + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_STARxCBType)(v_PVOID_t pvosGCtx, + adf_nbuf_t pDataBuff, + v_U8_t ucSTAId); + +#ifdef QCA_LL_TX_FLOW_CT +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the TX Flow Control callback registered with TL. + + TL will call this to notify the client when TX resource condition + is chnaged + + PARAMETERS + + IN + adapterCtxt: pointer to device apapter context + resume_tx: Ressume OS TX Q + + RETURN VALUE + NONE + +----------------------------------------------------------------------------*/ +typedef void (*WLANTL_TxFlowControlCBType)(void *adapterCtxt, + v_BOOL_t resume_tx); +#endif /* QCA_LL_TX_FLOW_CT */ + +/*---------------------------------------------------------------------------- + INTERACTION WITH BAP + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL for BAP. + + The registered reception callback is being triggered by TL whenever a + frame was received and it was filtered as a non-data BT AMP packet. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + frameType: type of the frame to be indicated to BAP. + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_BAPRxCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_BAPFrameEnumType frameType); + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required inorder for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_FlushOpCompCBType)( v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status); +/*---------------------------------------------------------------------------- + INTERACTION WITH PE + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL for PE. + + Upon receipt of a management frame TL will call the registered receive + callback and forward this frame to the interested module, in our case PE. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management frame + received + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_MgmtFrmRxCBType)( v_PVOID_t pvosGCtx, + v_PVOID_t vosBuff); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HAL + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the fetch packet callback registered with TL. + + HAL calls this API when it wishes to suspend transmission for a + particular STA. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which the request is made; + a value of 0 assumes suspend on all active station + pfnSuspendTxCB: pointer to the suspend result notification in case the + call is asynchronous + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_SuspendCBType)( v_PVOID_t pvosGCtx, + v_U8_t* ucSTAId, + VOS_STATUS vosStatus); + + +/*========================================================================== + + DESCRIPTION + Traffic status changed callback function + Should be registered to let client know that traffic status is changed + REF WLANTL_RegGetTrafficStatus + + PARAMETERS + pAdapter Global handle pointer + trafficStatus RT and NRT current traffic status + pUserCtxt pre registered client context + + RETURN VALUE + VOS_STATUS + + SIDE EFFECTS + NONE + +============================================================================*/ +/* IF traffic status is changed, send notification to SME */ +typedef VOS_STATUS (*WLANTL_TrafficStatusChangedCBType) +( + v_PVOID_t pAdapter, + WLANTL_HO_TRAFFIC_STATUS_TYPE trafficStatus, + v_PVOID_t pUserCtxt +); + +/*========================================================================== + + DESCRIPTION + RSSI threshold crossed notification callback function + REF WLANTL_RegRSSIIndicationCB + + PARAMETERS + pAdapter Global handle pointer + rssiNotification Notification event type + pUserCtxt pre registered client context + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ +/* If RSSI realm is changed, send notification to Clients, SME, HDD */ +typedef VOS_STATUS (*WLANTL_RSSICrossThresholdCBType) +( + v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi +); + +typedef struct +{ + // Common for all types are requests + v_U16_t msgType; // message type is same as the request type + v_U16_t msgLen; // length of the entire request + v_U8_t sessionId; //sme Session Id + v_U8_t rssiNotification; + v_U8_t avgRssi; + v_PVOID_t tlCallback; + v_PVOID_t pAdapter; + v_PVOID_t pUserCtxt; +} WLANTL_TlIndicationReq; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_Open + + DESCRIPTION + Called by HDD at driver initialization. TL will initialize all its + internal resources and will wait for the call to start to register + with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pTLConfig: TL Configuration + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Open +( + v_PVOID_t pvosGCtx, + WLANTL_ConfigInfoType* pTLConfig +); + +/*========================================================================== + + FUNCTION WLANTL_Start + + DESCRIPTION + Called by HDD as part of the overall start procedure. TL will use this + call to register with BAL as a transport layer entity. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; see BAL API + for more info + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_Stop + + DESCRIPTION + Called by HDD to stop operation in TL, before close. TL will suspend all + frame transfer operation and will wait for the close request to clean up + its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_Close + + DESCRIPTION + Called by HDD during general driver close procedure. TL will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Close +( + v_PVOID_t pvosGCtx +); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HDD + ---------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_ConfigureSwFrameTXXlationForAll + + DESCRIPTION + Function to disable/enable frame translation for all association stations. + + DEPENDENCIES + + PARAMETERS + IN + pvosGCtx: VOS context + EnableFrameXlation TRUE means enable SW translation for all stations. + . + + RETURN VALUE + + void. + +============================================================================*/ +void +WLANTL_ConfigureSwFrameTXXlationForAll +( + v_PVOID_t pvosGCtx, + v_BOOL_t enableFrameXlation +); + +/*=========================================================================== + + FUNCTION WLANTL_RegisterSTAClient + + DESCRIPTION + + This function is used by HDD to register as a client for data services + with TL. HDD will call this API for each new station that it adds, + thus having the flexibility of registering different callback for each + STA it services. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + Restriction: + Main thread will have higher priority that Tx and Rx threads thus + guaranteeing that a station will be added before any data can be + received for it. (This enables TL to be lock free) + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pfnStARx: function pointer to the receive packet handler from HDD + pfnSTATxComp: function pointer to the transmit complete confirmation + handler from HDD + pfnSTAFetchPkt: function pointer to the packet retrieval routine in HDD + wSTADescType: STA Descriptor, contains information related to the + new added STA + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterSTAClient +( + v_PVOID_t pvosGCtx, + WLANTL_STARxCBType pfnSTARx, + WLANTL_TxCompCBType pfnSTATxComp, + WLANTL_STAFetchPktCBType pfnSTAFetchPkt, + WLAN_STADescType* wSTADescType , + v_S7_t rssi +); + +/*=========================================================================== + + FUNCTION WLANTL_ClearSTAClient + + DESCRIPTION + + HDD will call this API when it no longer needs data services for the + particular station. + + DEPENDENCIES + + A station must have been registered before the clear registration is + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA to be cleared + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ClearSTAClient +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +); + +/*=========================================================================== + + FUNCTION WLANTL_ChangeSTAState + + DESCRIPTION + + HDD will make this notification whenever a change occurs in the + connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + RESTRICTION: A station is being notified as authenticated before the + keys are installed in HW. This way if a frame is received + before the keys are installed DPU will drop that frame. + + Main thread has higher priority that Tx and Rx threads thus guaranteeing + the following: + - a station will be in assoc state in TL before TL receives any data + for it + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + tlSTAState: the new state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ChangeSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType tlSTAState, + v_BOOL_t roamSynchInProgress +); + +/*=========================================================================== + + FUNCTION WLANTL_STAPtkInstalled + + DESCRIPTION + + HDD will make this notification whenever PTK is installed for the STA + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA for which Pairwise key is + installed + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPtkInstalled +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +); +/*=========================================================================== + + FUNCTION WLANTL_GetSTAState + + DESCRIPTION + + Returns connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + ptlSTAState: the current state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +static inline VOS_STATUS +WLANTL_GetSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType *ptlSTAState +) +{ + return VOS_STATUS_SUCCESS; +} + +/*=========================================================================== + + FUNCTION WLANTL_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. + + DEPENDENCIES + + A station must have been registered before the packet pending + notification can be sent. + + RESTRICTION: TL will not count packets for pending notification. + HDD is expected to send the notification only when + non-empty event gets triggered. Worst case scenario + is that TL might end up making a call when Hdds + queues are actually empty. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + ucAC: access category of the non-empty queue + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPktPending +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAc +); + +/*=========================================================================== + + FUNCTION WLANTL_SendSTA_DataFrame + + DESCRIPTION + + HDD will call this API when there is a packet to be transmitted + + DEPENDENCIES + + A station must have been registered before sending packet to txrx layer + + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + buf: packet given by uppler layer for tx + + RETURN VALUE + + On success it will return NULL. On failure it will be the + passed buf pointer so that the caller will be able to free + up the buffer. + +============================================================================*/ +adf_nbuf_t WLANTL_SendSTA_DataFrame(v_PVOID_t pvosGCtx, v_U8_t ucSTAId, + adf_nbuf_t buf +#ifdef QCA_PKT_PROTO_TRACE + , v_U8_t proto_type +#endif /* QCA_PKT_PROTO_TRACE */ + ); + +#ifdef IPA_OFFLOAD +/*=========================================================================== + + FUNCTION WLANTL_SendIPA_DataFrame + + DESCRIPTION + + HDD will call this API when there is a packet to be transmitted from IPA + + DEPENDENCIES + + A station must have been registered before sending packet to txrx layer + + + PARAMETERS + + vos_ctx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + vdev: virtual device + buf: packet given by uppler layer for tx + + RETURN VALUE + + On success it will return NULL. On failure it will be the + passed buf pointer so that the caller will be able to free + up the buffer. + +============================================================================*/ +adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev, + adf_nbuf_t buf, v_U8_t interface_id); +#endif + + +/*========================================================================== + + FUNCTION WLANTL_SetSTAPriority + + DESCRIPTION + + TL exposes this API to allow upper layers a rough control over the + priority of transmission for a given station when supporting multiple + connections. + + DEPENDENCIES + + A station must have been registered before the change in priority can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that has to change priority + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SetSTAPriority +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAPriorityType tlSTAPri +); + +/*---------------------------------------------------------------------------- + INTERACTION WITH BAP + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_RegisterBAPClient + + DESCRIPTION + Called by SME to register itself as client for non-data BT-AMP packets. + + DEPENDENCIES + TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pfnTlBAPRxFrm: pointer to the receive processing routine for non-data + BT-AMP packets + pfnFlushOpCompleteCb: + pointer to the function that will inform BAP that the + flush operation is complete. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: BAL client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterBAPClient +( + v_PVOID_t pvosGCtx, + WLANTL_BAPRxCBType pfnTlBAPRx, + WLANTL_FlushOpCompCBType pfnFlushOpCompleteCb +); + + +/*========================================================================== + + FUNCTION WLANTL_TxBAPFrm + + DESCRIPTION + BAP calls this when it wants to send a frame to the module + + DEPENDENCIES + BAP must be registered with TL before this function can be called. + + RESTRICTION: BAP CANNOT push any packets to TL until it did not receive + a tx complete from the previous packet, that means BAP + sends one packet, wait for tx complete and then + sends another one + + If BAP sends another packet before TL manages to process the + previously sent packet call will end in failure + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAP's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the packet to be + transmitted + pMetaInfo: meta information about the packet + pfnTlBAPTxComp: pointer to a transmit complete routine for notifying + the result of the operation over the bus + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: BAL client was not yet registered + VOS_STATUS_E_BUSY: The previous BT-AMP packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxBAPFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_MetaInfoType* pMetaInfo, + WLANTL_TxCompCBType pfnTlBAPTxComp +); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH SME + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetRssi + + DESCRIPTION + TL will extract the RSSI information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puRssi: the average value of the RSSI + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_GetRssi +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_S7_t* puRssi, + v_PVOID_t pGetRssiReq +); +/*========================================================================== + + FUNCTION WLANTL_GetSnr + + DESCRIPTION + TL will extract the SNR information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puSnr: the average value of the SNR + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSnr +( + tANI_U8 ucSTAId, + tANI_S8* pSnr +); + +/*========================================================================== + + FUNCTION WLANTL_GetLinkQuality + + DESCRIPTION + TL will extract the LinkQuality information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puLinkQuality: the average value of the LinkQuality + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetLinkQuality +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t* puLinkQuality +); + +/*========================================================================== + + FUNCTION WLANTL_FlushStaTID + + DESCRIPTION + TL provides this API as an interface to SME (BAP) layer. TL inturn posts a + message to HAL. This API is called by the SME inorder to perform a flush + operation. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + ucTid: Tspec ID for the new BA session + + OUT + The response for this post is received in the main thread, via a response + message from HAL to TL. + + RETURN VALUE + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANTL_FlushStaTID +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid +); + +/*---------------------------------------------------------------------------- + INTERACTION WITH PE + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_RegisterMgmtFrmClient + + DESCRIPTION + Called by PE to register as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + pfnTlMgmtFrmRx: pointer to the receive processing routine for + management frames + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx, + WLANTL_MgmtFrmRxCBType pfnTlMgmtFrmRx +); + +/*========================================================================== + + FUNCTION WLANTL_DeRegisterMgmtFrmClient + + DESCRIPTION + Called by PE to deregister as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was never registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DeRegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_TxMgmtFrm + + DESCRIPTION + Called by PE when it want to send out a management frame. + HAL will also use this API for the few frames it sends out, they are not + management frames howevere it is accepted that an exception will be + allowed ONLY for the usage of HAL. + Generic data frames SHOULD NOT travel through this function. + + DEPENDENCIES + TL must be initialized before this API can be called. + + RESTRICTION: If PE sends another packet before TL manages to process the + previously sent packet call will end in failure + + Frames comming through here must be 802.11 frames, frame + translation in UMA will be automatically disabled. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context;a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management + frame to be transmitted + usFrmLen: the length of the frame to be transmitted; information + is already included in the vOSS buffer + wFrmType: the type of the frame being transmitted + tid: tid used to transmit this frame + pfnCompTxFunc: function pointer to the transmit complete routine + pvBDHeader: pointer to the BD header, if NULL it means it was not + yet constructed and it lies within TL's responsibility + to do so; if not NULL it is expected that it was + already packed inside the vos packet + ucAckResponse: flag notifying it an interrupt is needed for the + acknowledgement received when the frame is sent out + the air and ; the interrupt will be processed by HAL, + only one such frame can be pending in the system at + one time. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was not yet registered + VOS_STATUS_E_BUSY: The previous Mgmt packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxMgmtFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosFrmBuf, + v_U16_t usFrmLen, + v_U8_t ucFrmType, + v_U8_t tid, + WLANTL_TxCompCBType pfnCompTxFunc, + v_PVOID_t voosBDHeader, + v_U8_t ucAckResponse +); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HAL + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_ResetNotification + + DESCRIPTION + HAL notifies TL when the module is being reset. + Currently not used. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResetNotification +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_SuspendDataTx + + DESCRIPTION + HAL calls this API when it wishes to suspend transmission for a + particular STA. + + DEPENDENCIES + The STA for which the request is made must be first registered with + TL by HDD. + + RESTRICTION: In case of a suspend, the flag write and read will not be + locked: worst case scenario one more packet can get + through before the flag gets updated (we can make this + write atomic as well to guarantee consistency) + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station for which the request is made; + a value of NULL assumes suspend on all active station + pfnSuspendTxCB: pointer to the suspend result notification in case the + call is asynchronous + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SuspendDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* ucSTAId, + WLANTL_SuspendCBType pfnSuspendTx +); + +/*========================================================================== + + FUNCTION WLANTL_ResumeDataTx + + DESCRIPTION + Called by HAL to resume data transmission for a given STA. + + WARNING: If a station was individually suspended a global resume will + not resume that station + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station which is being resumed; NULL + translates into global resume + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResumeDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId +); + + +/*---------------------------------------------------------------------------- + CLIENT INDEPENDENT INTERFACE + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetTxPktCount + + DESCRIPTION + TL will provide the number of transmitted packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets tx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetTxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puTxPktCount +); + +/*========================================================================== + + FUNCTION WLANTL_GetRxPktCount + + DESCRIPTION + TL will provide the number of received packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets rx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetRxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puRxPktCount +); + +/*========================================================================== + VOSS SCHEDULER INTERACTION + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_McProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + main thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_TxProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + tx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + + +/*========================================================================== + FUNCTION WLANTL_EnableUAPSDForAC + + DESCRIPTION + Called by HDD to enable UAPSD in TL. TL is in charge for sending trigger + frames. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucACId: AC for which U-APSD is being enabled + ucTid TSpec Id + uServiceInt: service interval used by TL to send trigger frames + uSuspendInt: suspend interval used by TL to determine that an + app is idle and should start sending trigg frms less often + wTSDir: direction of TSpec + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_EnableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucACId, + v_U8_t ucTid, + v_U8_t ucUP, + v_U32_t uServiceInt, + v_U32_t uSuspendInt, + WLANTL_TSDirType wTSDir, + v_U8_t psb, + v_U32_t sessionId +); + + +/*========================================================================== + FUNCTION WLANTL_DisableUAPSDForAC + + DESCRIPTION + Called by HDD to disable UAPSD in TL. TL will stop sending trigger + frames. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucACId: AC for which U-APSD is being enabled + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DisableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucACId, + v_U32_t sessionId +); + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING +/*========================================================================== + FUNCTION WLANTL_RegRSSIIndicationCB + + DESCRIPTION Registration function to get notification if RSSI cross + threshold. + Client should register threshold, direction, and notification + callback function pointer + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + in crossCBFunction - Notification CB Function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID, + v_PVOID_t usrCtxt +); + +/*========================================================================== + FUNCTION WLANTL_DeregRSSIIndicationCB + + DESCRIPTION Remove specific threshold from list + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_DeregRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_BMPSRSSIRegionChangedNotification +( + v_PVOID_t pAdapter, + tpSirRSSINotification pRSSINotification +); + +/*========================================================================== + FUNCTION WLANTL_SetAlpha + + DESCRIPTION ALPLA is weight value to calculate AVG RSSI + avgRSSI = (ALPHA * historyRSSI) + ((10 - ALPHA) * newRSSI) + avgRSSI has (ALPHA * 10)% of history RSSI weight and + (10 - ALPHA)% of newRSSI weight + This portion is dynamically configurable. + Default is ? + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in valueAlpah - ALPHA + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_SetAlpha +( + v_PVOID_t pAdapter, + v_U8_t valueAlpha +); + +/*========================================================================== + FUNCTION WLANTL_RegGetTrafficStatus + + DESCRIPTION Registration function for traffic status monitoring + During measure period count data frames. + If frame count is larger then IDLE threshold set as traffic ON + or OFF. + And traffic status is changed send report to client with + registered callback function + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in idleThreshold - Traffic on or off threshold + in measurePeriod - Traffic state check period + in trfficStatusCB - traffic status changed notification + CB function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegGetTrafficStatus +( + v_PVOID_t pAdapter, + v_U32_t idleThreshold, + v_U32_t measurePeriod, + WLANTL_TrafficStatusChangedCBType trfficStatusCB, + v_PVOID_t usrCtxt +); +#endif +/*========================================================================== + FUNCTION WLANTL_GetStatistics + + DESCRIPTION Get traffic statistics for identified station + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + out statBuffer - traffic statistics buffer + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetStatistics +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STA_TYPE *statBuffer, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_ResetStatistics + + DESCRIPTION Reset statistics structure for identified station ID + Reset means set values as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetStatistics +( + v_PVOID_t pAdapter, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_GetSpecStatistic + + DESCRIPTION Get specific field within statistics structure for + identified station ID + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + out buffer - Statistic value + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U32_t *buffer, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_ResetSpecStatistic + + DESCRIPTION Reset specific field within statistics structure for + identified station ID + Reset means set as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U8_t STAid +); +/*=============================================================================== + FUNCTION WLANTL_IsReplayPacket + + DESCRIPTION This function does replay check for valid stations + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS currentReplayCounter current replay counter taken from RX BD + previousReplayCounter previous replay counter taken from TL CB + + RETRUN VOS_TRUE packet is a replay packet + VOS_FALSE packet is not a replay packet + + SIDE EFFECTS none + ===============================================================================*/ +v_BOOL_t WLANTL_IsReplayPacket +( + v_U64_t currentReplayCounter, + v_U64_t previousReplayCounter +); + +/*=============================================================================== + FUNCTION WLANTL_GetReplayCounterFromRxBD + + DESCRIPTION This function extracts 48-bit replay packet number from RX BD + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS pucRxHeader pointer to RX BD header + + RETRUN v_U64_t Packet number extarcted from RX BD + + SIDE EFFECTS none + ===============================================================================*/ +v_U64_t +WLANTL_GetReplayCounterFromRxBD +( + v_U8_t *pucRxBDHeader +); + + + +/* + DESCRIPTION + TL returns the weight currently maintained in TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + + OUT + pACWeights: Caller allocated memory for filling in weights + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_GetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +); + + +/* + DESCRIPTION + Change the weight currently maintained by TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pACWeights: Caller allocated memory contain the weights to use + + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_SetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +); + +/*========================================================================== + FUNCTION WLANTL_GetSoftAPStatistics + + DESCRIPTION Collect the cumulative statistics for all Softap stations + + DEPENDENCIES NONE + + PARAMETERS in pvosGCtx - Pointer to the global vos context + bReset - If set TL statistics will be cleared after reading + out statsSum - pointer to collected statistics + + RETURN VALUE VOS_STATUS_SUCCESS : if the Statistics are successfully extracted + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSoftAPStatistics(v_PVOID_t pAdapter, WLANTL_TRANSFER_STA_TYPE *statsSum, v_BOOL_t bReset); + +#ifdef __cplusplus + } +#endif + + + /*=========================================================================== + + FUNCTION WLANTL_AssocFailed + + DESCRIPTION + + This function is used by PE to notify TL that cache needs to flushed + when association is not successfully completed + + Internally, TL post a message to TX_Thread to serialize the request to + keep lock-free mechanism. + + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + ucSTAId: station id + + RETURN VALUE + + none + + SIDE EFFECTS + There may be race condition that PE call this API and send another association + request immediately with same staId before TX_thread can process the message. + + To avoid this, we might need PE to wait for TX_thread process the message, + but this is not currently implemented. + +============================================================================*/ +void WLANTL_AssocFailed(v_U8_t staId); + + +/*=============================================================================== + FUNCTION WLANTL_PostResNeeded + + DESCRIPTION This function posts message to TL to reserve BD/PDU memory + + DEPENDENCIES None + + PARAMETERS pvosGCtx + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_PostResNeeded(v_PVOID_t pvosGCtx); + +/*=========================================================================== + + FUNCTION WLANTL_Finish_ULA + + DESCRIPTION + This function is used by HDD to notify TL to finish Upper layer authentication + incase the last EAPOL packet is pending in the TL queue. + To avoid the race condition between sme set key and the last EAPOL packet + the HDD module calls this function just before calling the sme_RoamSetKey. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + callbackRoutine: HDD Callback function. + callbackContext : HDD userdata context. + + RETURN VALUE + + VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS WLANTL_Finish_ULA( void (*callbackRoutine) (void *callbackContext), + void *callbackContext); + +/*=============================================================================== + FUNCTION WLANTL_UpdateRssiBmps + + DESCRIPTION This function updates the TL's RSSI (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + rssi RSSI (BMPS mode) RSSI in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateRssiBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t rssi); + +/*=============================================================================== + FUNCTION WLANTL_UpdateSnrBmps + + DESCRIPTION This function updates the TL's SNR (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + snr SNR (BMPS mode) SNR in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateSnrBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t snr); + +/*========================================================================== + FUNCTION WLANTL_SetTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_SetTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_IsTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to know whether WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + 0: No WDA_DS_TX_START_XMIT msg pending + 1: Msg WDA_DS_TX_START_XMIT already pending in TL msg queue + + SIDE EFFECTS + +============================================================================*/ + +v_BOOL_t +WLANTL_IsTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_ClearTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that no WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_ClearTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_UpdateSTABssIdforIBSS + + DESCRIPTION + HDD will call this API to update the BSSID for this Station. + + DEPENDENCIES + The HDD Should registered the staID with TL before calling this function. + + PARAMETERS + + IN + pvosGCtx: Pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + IN + ucSTAId The Station ID for Bssid to be updated + IN + pBssid BSSID to be updated + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANTL_UpdateSTABssIdforIBSS +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t *pBssid +); + + + +/*=============================================================================== + FUNCTION WLANTL_UpdateLinkCapacity + + DESCRIPTION This function updates the STA's Link Capacity in TL + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + linkCapacity linkCapacity Link Capacity + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void +WLANTL_UpdateLinkCapacity +( + v_PVOID_t pvosGCtx, + v_U8_t staId, + v_U32_t linkCapacity); + +/*=========================================================================== + + FUNCTION WLANTL_GetSTALinkCapacity + + DESCRIPTION + + Returns Link Capacity of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + plinkCapacity: the current link capacity the connection to + the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +static inline VOS_STATUS +WLANTL_GetSTALinkCapacity +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t *plinkCapacity +) +{ + return VOS_STATUS_SUCCESS; +} +/*=========================================================================== + FUNCTION WLANTL_TxThreadDebugHandler + + DESCRIPTION + Printing TL Snapshot dump, processed under TxThread context, currently + information regarding the global TlCb struture. Dumps information related + to per active STA connection currently in use by TL. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + pvosGCtx: Pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS +============================================================================*/ + +v_VOID_t +WLANTL_TxThreadDebugHandler +( + v_PVOID_t *pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_TLDebugMessage + + DESCRIPTION + Post a TL Snapshot request, posts message in TxThread. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + displaySnapshot Boolean showing whether to dump the snapshot or not. + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +static inline v_VOID_t +WLANTL_TLDebugMessage +( + v_BOOL_t displaySnapshot +) +{ + +} + +void WLANTL_PauseUnPauseQs(void *vos_context, v_BOOL_t flag); + +#ifdef QCA_LL_TX_FLOW_CT +/*============================================================================= + FUNCTION WLANTL_GetTxResource + + DESCRIPTION + This function will query WLAN kernel driver TX resource availability. + Per STA/VDEV instance, if TX resource is not available, should back + pressure to OS NET layer. + + DEPENDENCIES + NONE + + PARAMETERS + IN + vos_context : Pointer to VOS global context + sta_id : STA/VDEV instance to query TX resource + low_watermark : Low threashold to block OS Q + high_watermark_offset : Offset to high watermark from low watermark + + RETURN VALUE + VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q + VOS_FALSE : TX resource is not enough, stop OS TX Q + + SIDE EFFECTS + +==============================================================================*/ +v_BOOL_t WLANTL_GetTxResource +( + void *vos_context, + v_U8_t sessionId, + unsigned int low_watermark, + unsigned int high_watermark_offset +); + +/*============================================================================= + FUNCTION WLANTL_TXFlowControlCb + + DESCRIPTION + This function will be called by TX resource management unit. + If TC resource management unit reserved enough resource for TX session, + Call this function to resume OS TX Q. + + PARAMETERS + IN + tlContext : Pointer to TL SHIM context + peer_idx : peer index belongs to virtual device + sessionId : STA/VDEV instance to query TX resource + resume_tx : Resume OS TX Q or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_TXFlowControlCb +( + void *tlContext, + v_U8_t sessionId, + v_BOOL_t resume_tx +); + +/*============================================================================= + FUNCTION WLANTL_RegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to enable TX flow control, should register Cb function + And needed information into TL SHIM + + PARAMETERS + IN + vos_ctx : Global OS context context + sta_id : STA/VDEV instance index + flowControl : Flow control callback function pointer + sessionId : VDEV ID + adpaterCtxt : VDEV os interface adapter context + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterTXFlowControl +( + void *vos_ctx, + WLANTL_TxFlowControlCBType flowControl, + v_U8_t sessionId, + void *adpaterCtxt +); + +/*============================================================================= + FUNCTION WLANTL_DeRegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to close TX flow control, should de-register Cb function + + PARAMETERS + IN + vos_ctx : Global OS context context + sessionId : VDEV instance index + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_DeRegisterTXFlowControl +( + void *vos_ctx, + v_U8_t sessionId +); + +/*============================================================================= + FUNCTION WLANTL_SetAdapterMaxQDepth + + DESCRIPTION + This function will be called by TL client. + Based on the adapter TX available bandwidth, set different TX Pause Q size + Low Bandwidth adapter will have less count of TX Pause Q size to prevent + reserve all TX descriptors which shared with FW. + High Bandwidth adapter will have more count of TX Pause Q size + + PARAMETERS + IN + vos_ctx : Global OS context context + sessionId : adapter instance index + max_q_depth : Max pause Q depth for adapter + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetAdapterMaxQDepth +( + void *vos_ctx, + v_U8_t sessionId, + int max_q_depth +); +#endif /* QCA_LL_TX_FLOW_CT */ + +#ifdef IPA_UC_OFFLOAD +/*============================================================================= + FUNCTION WLANTL_GetIpaUcResource + + DESCRIPTION + This function will be called by TL client. + Data path resource will be used by FW should be allocated within lower layer. + Shared resource information should be propagated to IPA. + To propagate resource information, client will use this API + + PARAMETERS + IN + vos_ctx : Global OS context context + ce_sr_base_paddr : Copy Engine Source Ring base address + ce_sr_ring_size : Copy Engine Source Ring size + ce_reg_paddr : Copy engine register address + tx_comp_ring_base_paddr : TX COMP ring base address + tx_comp_ring_size : TX COMP ring size + tx_num_alloc_buffer : Number of TX allocated buffer + rx_rdy_ring_base_paddr : RX ready ring base address + rx_rdy_ring_size : RX ready ring size + rx_proc_done_idx_paddr : RX process done index physical address + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_GetIpaUcResource(void *vos_ctx, + v_U32_t *ce_sr_base_paddr, + v_U32_t *ce_sr_ring_size, + v_U32_t *ce_reg_paddr, + v_U32_t *tx_comp_ring_base_paddr, + v_U32_t *tx_comp_ring_size, + v_U32_t *tx_num_alloc_buffer, + v_U32_t *rx_rdy_ring_base_paddr, + v_U32_t *rx_rdy_ring_size, + v_U32_t *rx_proc_done_idx_paddr); + +/*============================================================================= + FUNCTION WLANTL_SetUcDoorbellPaddr + + DESCRIPTION + This function will be called by TL client. + UC controller should provide doorbell register address to firmware + TL client will call this API to pass doorbell register address to firmware + + PARAMETERS + IN + vos_ctx : Global OS context context + ipa_tx_uc_doorbell_paddr : Micro Controller WLAN TX COMP doorbell regiser + ipa_rx_uc_doorbell_paddr : Micro Controller WLAN RX REDY doorbell regiser + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetUcDoorbellPaddr(void *vos_ctx, + v_U32_t ipa_tx_uc_doorbell_paddr, + v_U32_t ipa_rx_uc_doorbell_paddr); + +/*============================================================================= + FUNCTION WLANTL_SetUcActive + + DESCRIPTION + This function will be called by TL client. + Send Micro controller data path active or inactive notification to firmware + + PARAMETERS + IN + vos_ctx : Global OS context context + uc_active : Micro Controller data path is active or not + is_tx : Micro Controller WLAN TX data path is active or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_SetUcActive(void *vos_ctx, + v_BOOL_t uc_active, + v_BOOL_t is_tx +); + +/*============================================================================= + FUNCTION WLANTL_RegisterOPCbFnc + + DESCRIPTION + This function will be called by TL client. + + PARAMETERS + IN + vos_ctx : Global OS context context + func : callback function pointer + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterOPCbFnc(void *vos_ctx, + void (*func)(v_U8_t *op_msg, void *usr_ctxt), void *usr_ctxt); +#endif /* IPA_UC_OFFLOAD */ +#endif /* #ifndef WLAN_QCT_WLANTL_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/FWLOG/dbglog_host.c b/drivers/staging/qcacld-2.0/CORE/UTILS/FWLOG/dbglog_host.c new file mode 100644 index 0000000000000..82af3c2523a4e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/FWLOG/dbglog_host.c @@ -0,0 +1,4255 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* Host Debug log implementation */ + + +#include "athdefs.h" +#include "a_types.h" +#include "dbglog_host.h" +#include "wmi.h" +#include "wmi_unified_api.h" +#include "wma.h" +#include "ol_defines.h" +#include +#include "vos_diag_core_event.h" +#include "qwlan_version.h" +#include +#include +#include +#include + +#ifdef WLAN_OPEN_SOURCE +#include +#endif /* WLAN_OPEN_SOURCE */ +#include "wmi_unified_priv.h" + +#define CLD_DEBUGFS_DIR "cld" +#define DEBUGFS_BLOCK_NAME "dbglog_block" + +#define ATH_MODULE_NAME fwlog +#include +#define FWLOG_DEBUG ATH_DEBUG_MAKE_MODULE_MASK(0) + +#if defined(DEBUG) + +static bool appstarted = FALSE; +static bool senddriverstatus = FALSE; +static bool kd_nl_init = FALSE; +static int cnss_diag_pid = INVALID_PID; +static int get_version = 0; +static int gprint_limiter = 0; + +static ATH_DEBUG_MASK_DESCRIPTION g_fwlogDebugDescription[] = { + {FWLOG_DEBUG,"fwlog"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(fwlog, + "fwlog", + "Firmware Debug Log", + ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO | ATH_DEBUG_ERR, + ATH_DEBUG_DESCRIPTION_COUNT(g_fwlogDebugDescription), + g_fwlogDebugDescription); +#endif + +module_dbg_print mod_print[WLAN_MODULE_ID_MAX]; + +A_UINT32 dbglog_process_type = DBGLOG_PROCESS_NET_RAW; + +A_STATUS +wmi_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param, A_UINT32 val, + A_UINT32 *module_id_bitmap, A_UINT32 bitmap_len); + +const char *dbglog_get_module_str(A_UINT32 module_id) +{ + switch (module_id) { + case WLAN_MODULE_INF: + return "INF"; + case WLAN_MODULE_WMI: + return "WMI"; + case WLAN_MODULE_STA_PWRSAVE: + return "STA PS"; + case WLAN_MODULE_WHAL: + return "WHAL"; + case WLAN_MODULE_COEX: + return "COEX"; + case WLAN_MODULE_ROAM: + return "ROAM"; + case WLAN_MODULE_RESMGR_CHAN_MANAGER: + return "CHANMGR"; + case WLAN_MODULE_RESMGR: + return "RESMGR"; + case WLAN_MODULE_VDEV_MGR: + return "VDEV"; + case WLAN_MODULE_SCAN: + return "SCAN"; + case WLAN_MODULE_RATECTRL: + return "RC"; + case WLAN_MODULE_AP_PWRSAVE: + return "AP PS"; + case WLAN_MODULE_BLOCKACK: + return "BA"; + case WLAN_MODULE_MGMT_TXRX: + return "MGMT"; + case WLAN_MODULE_DATA_TXRX: + return "DATA"; + case WLAN_MODULE_HTT: + return "HTT"; + case WLAN_MODULE_HOST: + return "HOST"; + case WLAN_MODULE_BEACON: + return "BEACON"; + case WLAN_MODULE_OFFLOAD: + return "OFFLOAD"; + case WLAN_MODULE_WAL: + return "WAL"; + case WAL_MODULE_DE: + return "DE"; + case WLAN_MODULE_PCIELP: + return "PCIELP"; + case WLAN_MODULE_RTT: + return "RTT"; + case WLAN_MODULE_DCS: + return "DCS"; + case WLAN_MODULE_CACHEMGR: + return "CACHEMGR"; + case WLAN_MODULE_ANI: + return "ANI"; + case WLAN_MODULE_TEST: + return "TESTPOINT"; + case WLAN_MODULE_STA_SMPS: + return "STA_SMPS"; + case WLAN_MODULE_TDLS: + return "TDLS"; + case WLAN_MODULE_P2P: + return "P2P"; + case WLAN_MODULE_WOW: + return "WoW"; + case WLAN_MODULE_IBSS_PWRSAVE: + return "IBSS PS"; + case WLAN_MODULE_EXTSCAN: + return "ExtScan"; + case WLAN_MODULE_UNIT_TEST: + return "UNIT_TEST"; + case WLAN_MODULE_MLME: + return "MLME"; + case WLAN_MODULE_SUPPL: + return "SUPPLICANT"; + default: + return "UNKNOWN"; + } +} + +char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = +{ + { + "INF_MSG_START", + "INF_ASSERTION_FAILED", + "INF_TARGET_ID", + "INF_MSG_END" + }, + { + "WMI_DBGID_DEFINITION_START", + "WMI_CMD_RX_XTND_PKT_TOO_SHORT", + "WMI_EXTENDED_CMD_NOT_HANDLED", + "WMI_CMD_RX_PKT_TOO_SHORT", + "WMI_CALLING_WMI_EXTENSION_FN", + "WMI_CMD_NOT_HANDLED", + "WMI_IN_SYNC", + "WMI_TARGET_WMI_SYNC_CMD", + "WMI_SET_SNR_THRESHOLD_PARAMS", + "WMI_SET_RSSI_THRESHOLD_PARAMS", + "WMI_SET_LQ_TRESHOLD_PARAMS", + "WMI_TARGET_CREATE_PSTREAM_CMD", + "WMI_WI_DTM_INUSE", + "WMI_TARGET_DELETE_PSTREAM_CMD", + "WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD", + "WMI_TARGET_GET_BIT_RATE_CMD", + "WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS", + "WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD", + "WMI_TARGET_GET_TX_PWR_CMD", + "WMI_FREE_EVBUF_WMIBUF", + "WMI_FREE_EVBUF_DATABUF", + "WMI_FREE_EVBUF_BADFLAG", + "WMI_HTC_RX_ERROR_DATA_PACKET", + "WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX", + "WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT", + "WMI_SENDING_READY_EVENT", + "WMI_SETPOWER_MDOE_TO_MAXPERF", + "WMI_SETPOWER_MDOE_TO_REC", + "WMI_BSSINFO_EVENT_FROM", + "WMI_TARGET_GET_STATS_CMD", + "WMI_SENDING_SCAN_COMPLETE_EVENT", + "WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT ", + "WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT", + "WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT", + "WMI_SENDING_ERROR_REPORT_EVENT", + "WMI_SENDING_CAC_EVENT", + "WMI_TARGET_GET_ROAM_TABLE_CMD", + "WMI_TARGET_GET_ROAM_DATA_CMD", + "WMI_SENDING_GPIO_INTR_EVENT", + "WMI_SENDING_GPIO_ACK_EVENT", + "WMI_SENDING_GPIO_DATA_EVENT", + "WMI_CMD_RX", + "WMI_CMD_RX_XTND", + "WMI_EVENT_SEND", + "WMI_EVENT_SEND_XTND", + "WMI_CMD_PARAMS_DUMP_START", + "WMI_CMD_PARAMS_DUMP_END", + "WMI_CMD_PARAMS", + "WMI_EVENT_ALLOC_FAILURE", + "WMI_DBGID_DCS_PARAM_CMD", + "WMI_SEND_EVENT_WRONG_TLV", + "WMI_SEND_EVENT_NO_TLV_DEF", + "WMI_DBGID_DEFNITION_END", + }, + { + "PS_STA_DEFINITION_START", + "PS_STA_PM_ARB_REQUEST", + "PS_STA_DELIVER_EVENT", + "PS_STA_PSPOLL_SEQ_DONE", + "PS_STA_COEX_MODE", + "PS_STA_PSPOLL_ALLOW", + "PS_STA_SET_PARAM", + "PS_STA_SPECPOLL_TIMER_STARTED", + "PS_STA_SPECPOLL_TIMER_STOPPED", + }, + { + "WHAL_DBGID_DEFINITION_START", + "WHAL_ERROR_ANI_CONTROL", + "WHAL_ERROR_CHIP_TEST1", + "WHAL_ERROR_CHIP_TEST2", + "WHAL_ERROR_EEPROM_CHECKSUM", + "WHAL_ERROR_EEPROM_MACADDR", + "WHAL_ERROR_INTERRUPT_HIU", + "WHAL_ERROR_KEYCACHE_RESET", + "WHAL_ERROR_KEYCACHE_SET", + "WHAL_ERROR_KEYCACHE_TYPE", + "WHAL_ERROR_KEYCACHE_TKIPENTRY", + "WHAL_ERROR_KEYCACHE_WEPLENGTH", + "WHAL_ERROR_PHY_INVALID_CHANNEL", + "WHAL_ERROR_POWER_AWAKE", + "WHAL_ERROR_POWER_SET", + "WHAL_ERROR_RECV_STOPDMA", + "WHAL_ERROR_RECV_STOPPCU", + "WHAL_ERROR_RESET_CHANNF1", + "WHAL_ERROR_RESET_CHANNF2", + "WHAL_ERROR_RESET_PM", + "WHAL_ERROR_RESET_OFFSETCAL", + "WHAL_ERROR_RESET_RFGRANT", + "WHAL_ERROR_RESET_RXFRAME", + "WHAL_ERROR_RESET_STOPDMA", + "WHAL_ERROR_RESET_ERRID", + "WHAL_ERROR_RESET_ADCDCCAL1", + "WHAL_ERROR_RESET_ADCDCCAL2", + "WHAL_ERROR_RESET_TXIQCAL", + "WHAL_ERROR_RESET_RXIQCAL", + "WHAL_ERROR_RESET_CARRIERLEAK", + "WHAL_ERROR_XMIT_COMPUTE", + "WHAL_ERROR_XMIT_NOQUEUE", + "WHAL_ERROR_XMIT_ACTIVEQUEUE", + "WHAL_ERROR_XMIT_BADTYPE", + "WHAL_ERROR_XMIT_STOPDMA", + "WHAL_ERROR_INTERRUPT_BB_PANIC", + "WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW", + "WHAL_ERROR_QCU_HW_PAUSE_MISMATCH", + "WHAL_DBGID_DEFINITION_END", + }, + { + "COEX_DEBUGID_START", + "BTCOEX_DBG_MCI_1", + "BTCOEX_DBG_MCI_2", + "BTCOEX_DBG_MCI_3", + "BTCOEX_DBG_MCI_4", + "BTCOEX_DBG_MCI_5", + "BTCOEX_DBG_MCI_6", + "BTCOEX_DBG_MCI_7", + "BTCOEX_DBG_MCI_8", + "BTCOEX_DBG_MCI_9", + "BTCOEX_DBG_MCI_10", + "COEX_WAL_BTCOEX_INIT", + "COEX_WAL_PAUSE", + "COEX_WAL_RESUME", + "COEX_UPDATE_AFH", + "COEX_HWQ_EMPTY_CB", + "COEX_MCI_TIMER_HANDLER", + "COEX_MCI_RECOVER", + "ERROR_COEX_MCI_ISR", + "ERROR_COEX_MCI_GPM", + "COEX_ProfileType", + "COEX_LinkID", + "COEX_LinkState", + "COEX_LinkRole", + "COEX_LinkRate", + "COEX_VoiceType", + "COEX_TInterval", + "COEX_WRetrx", + "COEX_Attempts", + "COEX_PerformanceState", + "COEX_LinkType", + "COEX_RX_MCI_GPM_VERSION_QUERY", + "COEX_RX_MCI_GPM_VERSION_RESPONSE", + "COEX_RX_MCI_GPM_STATUS_QUERY", + "COEX_STATE_WLAN_VDEV_DOWN", + "COEX_STATE_WLAN_VDEV_START", + "COEX_STATE_WLAN_VDEV_CONNECTED", + "COEX_STATE_WLAN_VDEV_SCAN_STARTED", + "COEX_STATE_WLAN_VDEV_SCAN_END", + "COEX_STATE_WLAN_DEFAULT", + "COEX_CHANNEL_CHANGE", + "COEX_POWER_CHANGE", + "COEX_CONFIG_MGR", + "COEX_TX_MCI_GPM_BT_CAL_REQ", + "COEX_TX_MCI_GPM_BT_CAL_GRANT", + "COEX_TX_MCI_GPM_BT_CAL_DONE", + "COEX_TX_MCI_GPM_WLAN_CAL_REQ", + "COEX_TX_MCI_GPM_WLAN_CAL_GRANT", + "COEX_TX_MCI_GPM_WLAN_CAL_DONE", + "COEX_TX_MCI_GPM_BT_DEBUG", + "COEX_TX_MCI_GPM_VERSION_QUERY", + "COEX_TX_MCI_GPM_VERSION_RESPONSE", + "COEX_TX_MCI_GPM_STATUS_QUERY", + "COEX_TX_MCI_GPM_HALT_BT_GPM", + "COEX_TX_MCI_GPM_WLAN_CHANNELS", + "COEX_TX_MCI_GPM_BT_PROFILE_INFO", + "COEX_TX_MCI_GPM_BT_STATUS_UPDATE", + "COEX_TX_MCI_GPM_BT_UPDATE_FLAGS", + "COEX_TX_MCI_GPM_UNKNOWN", + "COEX_TX_MCI_SYS_WAKING", + "COEX_TX_MCI_LNA_TAKE", + "COEX_TX_MCI_LNA_TRANS", + "COEX_TX_MCI_SYS_SLEEPING", + "COEX_TX_MCI_REQ_WAKE", + "COEX_TX_MCI_REMOTE_RESET", + "COEX_TX_MCI_TYPE_UNKNOWN", + "COEX_WHAL_MCI_RESET", + "COEX_POLL_BT_CAL_DONE_TIMEOUT", + "COEX_WHAL_PAUSE", + "COEX_RX_MCI_GPM_BT_CAL_REQ", + "COEX_RX_MCI_GPM_BT_CAL_DONE", + "COEX_RX_MCI_GPM_BT_CAL_GRANT", + "COEX_WLAN_CAL_START", + "COEX_WLAN_CAL_RESULT", + "COEX_BtMciState", + "COEX_BtCalState", + "COEX_WlanCalState", + "COEX_RxReqWakeCount", + "COEX_RxRemoteResetCount", + "COEX_RESTART_CAL", + "COEX_SENDMSG_QUEUE", + "COEX_RESETSEQ_LNAINFO_TIMEOUT", + "COEX_MCI_ISR_IntRaw", + "COEX_MCI_ISR_Int1Raw", + "COEX_MCI_ISR_RxMsgRaw", + "COEX_WHAL_COEX_RESET", + "COEX_WAL_COEX_INIT", + "COEX_TXRX_CNT_LIMIT_ISR", + "COEX_CH_BUSY", + "COEX_REASSESS_WLAN_STATE", + "COEX_BTCOEX_WLAN_STATE_UPDATE", + "COEX_BT_NUM_OF_PROFILES", + "COEX_BT_NUM_OF_HID_PROFILES", + "COEX_BT_NUM_OF_ACL_PROFILES", + "COEX_BT_NUM_OF_HI_ACL_PROFILES", + "COEX_BT_NUM_OF_VOICE_PROFILES", + "COEX_WLAN_AGGR_LIMIT", + "COEX_BT_LOW_PRIO_BUDGET", + "COEX_BT_HI_PRIO_BUDGET", + "COEX_BT_IDLE_TIME", + "COEX_SET_COEX_WEIGHT", + "COEX_WLAN_WEIGHT_GROUP", + "COEX_BT_WEIGHT_GROUP", + "COEX_BT_INTERVAL_ALLOC", + "COEX_BT_SCHEME", + "COEX_BT_MGR", + "COEX_BT_SM_ERROR", + "COEX_SYSTEM_UPDATE", + "COEX_LOW_PRIO_LIMIT", + "COEX_HI_PRIO_LIMIT", + "COEX_BT_INTERVAL_START", + "COEX_WLAN_INTERVAL_START", + "COEX_NON_LINK_BUDGET", + "COEX_CONTENTION_MSG", + "COEX_SET_NSS", + "COEX_SELF_GEN_MASK", + "COEX_PROFILE_ERROR", + "COEX_WLAN_INIT", + "COEX_BEACON_MISS", + "COEX_BEACON_OK", + "COEX_BTCOEX_SCAN_ACTIVITY", + "COEX_SCAN_ACTIVITY", + "COEX_FORCE_QUIETTIME", + "COEX_BT_MGR_QUIETTIME", + "COEX_BT_INACTIVITY_TRIGGER", + "COEX_BT_INACTIVITY_REPORTED", + "COEX_TX_MCI_GPM_WLAN_PRIO", + "COEX_TX_MCI_GPM_BT_PAUSE_PROFILE", + "COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY", + "COEX_RX_MCI_GPM_BT_ACL_INACTIVITY_REPORT", + "COEX_GENERIC_ERROR", + "COEX_RX_RATE_THRESHOLD", + "COEX_RSSI", + "COEX_WLAN_VDEV_NOTIF_START", // 133 + "COEX_WLAN_VDEV_NOTIF_UP", // 134 + "COEX_WLAN_VDEV_NOTIF_DOWN", // 135 + "COEX_WLAN_VDEV_NOTIF_STOP", // 136 + "COEX_WLAN_VDEV_NOTIF_ADD_PEER", // 137 + "COEX_WLAN_VDEV_NOTIF_DELETE_PEER", // 138 + "COEX_WLAN_VDEV_NOTIF_CONNECTED_PEER", // 139 + "COEX_WLAN_VDEV_NOTIF_PAUSE", // 140 + "COEX_WLAN_VDEV_NOTIF_UNPAUSED", // 141 + "COEX_STATE_WLAN_VDEV_PEER_ADD", // 142 + "COEX_STATE_WLAN_VDEV_CONNECTED_PEER", // 143 + "COEX_STATE_WLAN_VDEV_DELETE_PEER", // 144 + "COEX_STATE_WLAN_VDEV_PAUSE", // 145 + "COEX_STATE_WLAN_VDEV_UNPAUSED", // 146 + "COEX_SCAN_CALLBACK", // 147 + "COEX_RC_SET_CHAINMASK", // 148 + "COEX_TX_MCI_GPM_WLAN_SET_BT_RXSS_THRES", // 149 + "COEX_TX_MCI_GPM_BT_RXSS_THRES_QUERY", // 150 + "COEX_BT_RXSS_THRES", // 151 + "COEX_BT_PROFILE_ADD_RMV", // 152 + "COEX_BT_SCHED_INFO", // 153 + "COEX_TRF_MGMT", // 154 + "COEX_SCHED_START", // 155 + "COEX_SCHED_RESULT", // 156 + "COEX_SCHED_ERROR", // 157 + "COEX_SCHED_PRE_OP", // 158 + "COEX_SCHED_POST_OP", // 159 + "COEX_RX_RATE", // 160 + "COEX_ACK_PRIORITY", // 161 + "COEX_STATE_WLAN_VDEV_UP", // 162 + "COEX_STATE_WLAN_VDEV_PEER_UPDATE", // 163 + "COEX_STATE_WLAN_VDEV_STOP", // 164 + "COEX_WLAN_PAUSE_PEER", // 165 + "COEX_WLAN_UNPAUSE_PEER", // 166 + "COEX_WLAN_PAUSE_INTERVAL_START", // 167 + "COEX_WLAN_POSTPAUSE_INTERVAL_START", // 168 + "COEX_TRF_FREERUN", // 169 + "COEX_TRF_SHAPE_PM", // 170 + "COEX_TRF_SHAPE_PSP", // 171 + "COEX_TRF_SHAPE_S_CTS", // 172 + "COEX_CHAIN_CONFIG", // 173 + "COEX_SYSTEM_MONITOR", // 174 + "COEX_SINGLECHAIN_INIT", // 175 + "COEX_MULTICHAIN_INIT", // 176 + "COEX_SINGLECHAIN_DBG_1", // 177 + "COEX_SINGLECHAIN_DBG_2", // 178 + "COEX_SINGLECHAIN_DBG_3", // 179 + "COEX_MULTICHAIN_DBG_1", // 180 + "COEX_MULTICHAIN_DBG_2", // 181 + "COEX_MULTICHAIN_DBG_3", // 182 + "COEX_PSP_TX_CB", // 183 + "COEX_PSP_RX_CB", // 184 + "COEX_PSP_STAT_1", // 185 + "COEX_PSP_SPEC_POLL", // 186 + "COEX_PSP_READY_STATE", // 187 + "COEX_PSP_TX_STATUS_STATE", // 188 + "COEX_PSP_RX_STATUS_STATE_1", // 189 + "COEX_PSP_NOT_READY_STATE", // 190 + "COEX_PSP_DISABLED_STATE", // 191 + "COEX_PSP_ENABLED_STATE", // 192 + "COEX_PSP_SEND_PSPOLL", // 193 + "COEX_PSP_MGR_ENTER", // 194 + "COEX_PSP_MGR_RESULT", // 195 + "COEX_PSP_NONWLAN_INTERVAL", // 196 + "COEX_PSP_STAT_2", // 197 + "COEX_PSP_RX_STATUS_STATE_2", // 198 + "COEX_PSP_ERROR", // 199 + "COEX_T2BT", // 200 + "COEX_BT_DURATION", // 201 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203 + "COEX_TX_MCI_GPM_SCAN_OP", // 204 + "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205 + "COEX_CTS2S_SEND", // 206 + "COEX_CTS2S_RESULT", // 207 + "COEX_ENTER_OCS", // 208 + "COEX_EXIT_OCS", // 209 + "COEX_UPDATE_OCS", // 210 + "COEX_STATUS_OCS", // 211 + "COEX_STATS_BT", // 212 + "COEX_MWS_WLAN_INIT", + "COEX_MWS_WBTMR_SYNC", + "COEX_MWS_TYPE2_RX", + "COEX_MWS_TYPE2_TX", + "COEX_MWS_WLAN_CHAVD", + "COEX_MWS_WLAN_CHAVD_INSERT", + "COEX_MWS_WLAN_CHAVD_MERGE", + "COEX_MWS_WLAN_CHAVD_RPT", + "COEX_MWS_CP_MSG_SEND", + "COEX_MWS_CP_ESCAPE", + "COEX_MWS_CP_UNFRAME", + "COEX_MWS_CP_SYNC_UPDATE", + "COEX_MWS_CP_SYNC", + "COEX_MWS_CP_WLAN_STATE_IND", + "COEX_MWS_CP_SYNCRESP_TIMEOUT", + "COEX_MWS_SCHEME_UPDATE", + "COEX_MWS_WLAN_EVENT", + "COEX_MWS_UART_UNESCAPE", + "COEX_MWS_UART_ENCODE_SEND", + "COEX_MWS_UART_RECV_DECODE", + "COEX_MWS_UL_HDL", + "COEX_MWS_REMOTE_EVENT", + "COEX_MWS_OTHER", + "COEX_MWS_ERROR", + "COEX_MWS_ANT_DIVERSITY", //237 + "COEX_P2P_GO", + "COEX_P2P_CLIENT", + "COEX_SCC_1", + "COEX_SCC_2", + "COEX_MCC_1", + "COEX_MCC_2", + "COEX_TRF_SHAPE_NOA", + "COEX_NOA_ONESHOT", + "COEX_NOA_PERIODIC", + "COEX_LE_1", + "COEX_LE_2", + "COEX_ANT_1", + "COEX_ANT_2", + "COEX_ENTER_NOA", + "COEX_EXIT_NOA", + "COEX_BT_SCAN_PROTECT", // 253 + "COEX_DEBUG_ID_END" // 254 + }, + { + "ROAM_DBGID_DEFINITION_START", + "ROAM_MODULE_INIT", + "ROAM_DEV_START", + "ROAM_CONFIG_RSSI_THRESH", + "ROAM_CONFIG_SCAN_PERIOD", + "ROAM_CONFIG_AP_PROFILE", + "ROAM_CONFIG_CHAN_LIST", + "ROAM_CONFIG_SCAN_PARAMS", + "ROAM_CONFIG_RSSI_CHANGE", + "ROAM_SCAN_TIMER_START", + "ROAM_SCAN_TIMER_EXPIRE", + "ROAM_SCAN_TIMER_STOP", + "ROAM_SCAN_STARTED", + "ROAM_SCAN_COMPLETE", + "ROAM_SCAN_CANCELLED", + "ROAM_CANDIDATE_FOUND", + "ROAM_RSSI_ACTIVE_SCAN", + "ROAM_RSSI_ACTIVE_ROAM", + "ROAM_RSSI_GOOD", + "ROAM_BMISS_FIRST_RECV", + "ROAM_DEV_STOP", + "ROAM_FW_OFFLOAD_ENABLE", + "ROAM_CANDIDATE_SSID_MATCH", + "ROAM_CANDIDATE_SECURITY_MATCH", + "ROAM_LOW_RSSI_INTERRUPT", + "ROAM_HIGH_RSSI_INTERRUPT", + "ROAM_SCAN_REQUESTED", + "ROAM_BETTER_CANDIDATE_FOUND", + "ROAM_BETTER_AP_EVENT", + "ROAM_CANCEL_LOW_PRIO_SCAN", + "ROAM_FINAL_BMISS_RECVD", + "ROAM_CONFIG_SCAN_MODE", + "ROAM_BMISS_FINAL_SCAN_ENABLE", + "ROAM_SUITABLE_AP_EVENT", + "ROAM_RSN_IE_PARSE_ERROR", + "ROAM_WPA_IE_PARSE_ERROR", + "ROAM_SCAN_CMD_FROM_HOST", + "ROAM_HO_SORT_CANDIDATE", + "ROAM_HO_SAVE_CANDIDATE", + "ROAM_HO_GET_CANDIDATE", + "ROAM_HO_OFFLOAD_SET_PARAM", + "ROAM_HO_SM", + "ROAM_HO_HTT_SAVED", + "ROAM_HO_SYNC_START", + "ROAM_HO_START", + "ROAM_HO_COMPLETE", + "ROAM_HO_STOP", + "ROAM_HO_HTT_FORWARD", + "ROAM_DBGID_DEFINITION_END" + }, + { + "RESMGR_CHMGR_DEFINITION_START", + "RESMGR_CHMGR_PAUSE_COMPLETE", + "RESMGR_CHMGR_CHANNEL_CHANGE", + "RESMGR_CHMGR_RESUME_COMPLETE", + "RESMGR_CHMGR_VDEV_PAUSE", + "RESMGR_CHMGR_VDEV_UNPAUSE", + "RESMGR_CHMGR_CTS2S_TX_COMP", + "RESMGR_CHMGR_CFEND_TX_COMP", + "RESMGR_CHMGR_DEFINITION_END" + }, + { + "RESMGR_DEFINITION_START", + "RESMGR_OCS_ALLOCRAM_SIZE", + "RESMGR_OCS_RESOURCES", + "RESMGR_LINK_CREATE", + "RESMGR_LINK_DELETE", + "RESMGR_OCS_CHREQ_CREATE", + "RESMGR_OCS_CHREQ_DELETE", + "RESMGR_OCS_CHREQ_START", + "RESMGR_OCS_CHREQ_STOP", + "RESMGR_OCS_SCHEDULER_INVOKED", + "RESMGR_OCS_CHREQ_GRANT", + "RESMGR_OCS_CHREQ_COMPLETE", + "RESMGR_OCS_NEXT_TSFTIME", + "RESMGR_OCS_TSF_TIMEOUT_US", + "RESMGR_OCS_CURR_CAT_WINDOW", + "RESMGR_OCS_CURR_CAT_WINDOW_REQ", + "RESMGR_OCS_CURR_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CHREQ_RESTART", + "RESMGR_OCS_CLEANUP_CH_ALLOCATORS", + "RESMGR_OCS_PURGE_CHREQ", + "RESMGR_OCS_CH_ALLOCATOR_FREE", + "RESMGR_OCS_RECOMPUTE_SCHEDULE", + "RESMGR_OCS_NEW_CAT_WINDOW_REQ", + "RESMGR_OCS_NEW_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CUR_CH_ALLOC", + "RESMGR_OCS_WIN_CH_ALLOC", + "RESMGR_OCS_SCHED_CH_CHANGE", + "RESMGR_OCS_CONSTRUCT_CAT_WIN", + "RESMGR_OCS_CHREQ_PREEMPTED", + "RESMGR_OCS_CH_SWITCH_REQ", + "RESMGR_OCS_CHANNEL_SWITCHED", + "RESMGR_OCS_CLEANUP_STALE_REQS", + "RESMGR_OCS_CHREQ_UPDATE", + "RESMGR_OCS_REG_NOA_NOTIF", + "RESMGR_OCS_DEREG_NOA_NOTIF", + "RESMGR_OCS_GEN_PERIODIC_NOA", + "RESMGR_OCS_RECAL_QUOTAS", + "RESMGR_OCS_GRANTED_QUOTA_STATS", + "RESMGR_OCS_ALLOCATED_QUOTA_STATS", + "RESMGR_OCS_REQ_QUOTA_STATS", + "RESMGR_OCS_TRACKING_TIME_FIRED", + "RESMGR_VC_ARBITRATE_ATTRIBUTES", + "RESMGR_OCS_LATENCY_STRICT_TIME_SLOT", + "RESMGR_OCS_CURR_TSF", + "RESMGR_OCS_QUOTA_REM", + "RESMGR_OCS_LATENCY_CASE_NO", + "RESMGR_OCS_WIN_CAT_DUR", + "RESMGR_VC_UPDATE_CUR_VC", + "RESMGR_VC_REG_UNREG_LINK", + "RESMGR_VC_PRINT_LINK", + "RESMGR_OCS_MISS_TOLERANCE", + "RESMGR_DYN_SCH_ALLOCRAM_SIZE", + "RESMGR_DYN_SCH_ENABLE", + "RESMGR_DYN_SCH_ACTIVE", + "RESMGR_DYN_SCH_CH_STATS_START", + "RESMGR_DYN_SCH_CH_SX_STATS", + "RESMGR_DYN_SCH_TOT_UTIL_PER", + "RESMGR_DYN_SCH_HOME_CH_QUOTA", + "RESMGR_OCS_REG_RECAL_QUOTA_NOTIF", + "RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF", + "RESMGR_DEFINITION_END" + }, + { + "VDEV_MGR_DEBID_DEFINITION_START", /* vdev Mgr */ + "VDEV_MGR_FIRST_BEACON_MISS_DETECTED", + "VDEV_MGR_FINAL_BEACON_MISS_DETECTED", + "VDEV_MGR_BEACON_IN_SYNC", + "VDEV_MGR_AP_KEEPALIVE_IDLE", + "VDEV_MGR_AP_KEEPALIVE_INACTIVE", + "VDEV_MGR_AP_KEEPALIVE_UNRESPONSIVE", + "VDEV_MGR_AP_TBTT_CONFIG", + "VDEV_MGR_FIRST_BCN_RECEIVED", + "VDEV_MGR_VDEV_START", + "VDEV_MGR_VDEV_UP", + "VDEV_MGR_PEER_AUTHORIZED", + "VDEV_MGR_OCS_HP_LP_REQ_POSTED", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP", + "VDEV_MGR_HP_START_TIME", + "VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE", + "VDEV_MGR_VDEV_PAUSE_FAIL", + "VDEV_MGR_GEN_PERIODIC_NOA", + "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP", + "VDEV_MGR_DEFINITION_END", + }, + { + "SCAN_START_COMMAND_FAILED", /* scan */ + "SCAN_STOP_COMMAND_FAILED", + "SCAN_EVENT_SEND_FAILED", + "SCAN_ENGINE_START", + "SCAN_ENGINE_CANCEL_COMMAND", + "SCAN_ENGINE_STOP_DUE_TO_TIMEOUT", + "SCAN_EVENT_SEND_TO_HOST", + "SCAN_FWLOG_EVENT_ADD", + "SCAN_FWLOG_EVENT_REM", + "SCAN_FWLOG_EVENT_PREEMPTED", + "SCAN_FWLOG_EVENT_RESTARTED", + "SCAN_FWLOG_EVENT_COMPLETED", + }, + { + "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl*/ + "RATECTRL_DBGID_ASSOC", + "RATECTRL_DBGID_NSS_CHANGE", + "RATECTRL_DBGID_CHAINMASK_ERR", + "RATECTRL_DBGID_UNEXPECTED_FRAME", + "RATECTRL_DBGID_WAL_RCQUERY", + "RATECTRL_DBGID_WAL_RCUPDATE", + "RATECTRL_DBGID_GTX_UPDATE", + "RATECTRL_DBGID_DEFINITION_END" + }, + { + "AP_PS_DBGID_DEFINITION_START", + "AP_PS_DBGID_UPDATE_TIM", + "AP_PS_DBGID_PEER_STATE_CHANGE", + "AP_PS_DBGID_PSPOLL", + "AP_PS_DBGID_PEER_CREATE", + "AP_PS_DBGID_PEER_DELETE", + "AP_PS_DBGID_VDEV_CREATE", + "AP_PS_DBGID_VDEV_DELETE", + "AP_PS_DBGID_SYNC_TIM", + "AP_PS_DBGID_NEXT_RESPONSE", + "AP_PS_DBGID_START_SP", + "AP_PS_DBGID_COMPLETED_EOSP", + "AP_PS_DBGID_TRIGGER", + "AP_PS_DBGID_DUPLICATE_TRIGGER", + "AP_PS_DBGID_UAPSD_RESPONSE", + "AP_PS_DBGID_SEND_COMPLETE", + "AP_PS_DBGID_SEND_N_COMPLETE", + "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA", + "AP_PS_DBGID_DELIVER_CAB", + }, + { + "" /* Block Ack */ + }, + /* Mgmt TxRx */ + { + "MGMT_TXRX_DBGID_DEFINITION_START", + "MGMT_TXRX_FORWARD_TO_HOST", + "MGMT_TXRX_DBGID_DEFINITION_END", + }, + { /* Data TxRx */ + "DATA_TXRX_DBGID_DEFINITION_START", + "DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO", + "DATA_TXRX_DBGID_DEFINITION_END", + }, + { "" /* HTT */ + }, + { "" /* HOST */ + }, + { "" /* BEACON */ + "BEACON_EVENT_SWBA_SEND_FAILED", + "BEACON_EVENT_EARLY_RX_BMISS_STATUS", + "BEACON_EVENT_EARLY_RX_SLEEP_SLOP", + "BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT", + "BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM", + "BEACON_EVENT_EARLY_RX_CLK_DRIFT", + "BEACON_EVENT_EARLY_RX_AP_DRIFT", + "BEACON_EVENT_EARLY_RX_BCN_TYPE", + }, + { /* Offload Mgr */ + "OFFLOAD_MGR_DBGID_DEFINITION_START", + "OFFLOADMGR_REGISTER_OFFLOAD", + "OFFLOADMGR_DEREGISTER_OFFLOAD", + "OFFLOADMGR_NO_REG_DATA_HANDLERS", + "OFFLOADMGR_NO_REG_EVENT_HANDLERS", + "OFFLOADMGR_REG_OFFLOAD_FAILED", + "OFFLOADMGR_DBGID_DEFINITION_END", + }, + { + "WAL_DBGID_DEFINITION_START", + "WAL_DBGID_FAST_WAKE_REQUEST", + "WAL_DBGID_FAST_WAKE_RELEASE", + "WAL_DBGID_SET_POWER_STATE", + "WAL_DBGID_MISSING", + "WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET", + "WAL_DBGID_CHANNEL_CHANGE", + "WAL_DBGID_VDEV_START", + "WAL_DBGID_VDEV_STOP", + "WAL_DBGID_VDEV_UP", + "WAL_DBGID_VDEV_DOWN", + "WAL_DBGID_SW_WDOG_RESET", + "WAL_DBGID_TX_SCH_REGISTER_TIDQ", + "WAL_DBGID_TX_SCH_UNREGISTER_TIDQ", + "WAL_DBGID_TX_SCH_TICKLE_TIDQ", + "WAL_DBGID_XCESS_FAILURES", + "WAL_DBGID_AST_ADD_WDS_ENTRY", + "WAL_DBGID_AST_DEL_WDS_ENTRY", + "WAL_DBGID_AST_WDS_ENTRY_PEER_CHG", + "WAL_DBGID_AST_WDS_SRC_LEARN_FAIL", + "WAL_DBGID_STA_KICKOUT", + "WAL_DBGID_BAR_TX_FAIL", + "WAL_DBGID_BAR_ALLOC_FAIL", + "WAL_DBGID_LOCAL_DATA_TX_FAIL", + "WAL_DBGID_SECURITY_PM4_QUEUED", + "WAL_DBGID_SECURITY_GM1_QUEUED", + "WAL_DBGID_SECURITY_PM4_SENT", + "WAL_DBGID_SECURITY_ALLOW_DATA", + "WAL_DBGID_SECURITY_UCAST_KEY_SET", + "WAL_DBGID_SECURITY_MCAST_KEY_SET", + "WAL_DBGID_SECURITY_ENCR_EN", + "WAL_DBGID_BB_WDOG_TRIGGERED", + "WAL_DBGID_RX_LOCAL_BUFS_LWM", + "WAL_DBGID_RX_LOCAL_DROP_LARGE_MGMT", + "WAL_DBGID_VHT_ILLEGAL_RATE_PHY_ERR_DETECTED", + "WAL_DBGID_DEV_RESET", + "WAL_DBGID_TX_BA_SETUP", + "WAL_DBGID_RX_BA_SETUP", + "WAL_DBGID_DEV_TX_TIMEOUT", + "WAL_DBGID_DEV_RX_TIMEOUT", + "WAL_DBGID_STA_VDEV_XRETRY", + "WAL_DBGID_DCS", + "WAL_DBGID_MGMT_TX_FAIL", + "WAL_DBGID_SET_M4_SENT_MANUALLY", + "WAL_DBGID_PROCESS_4_WAY_HANDSHAKE", + "WAL_DBGID_WAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DISCARD", + "WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS", + "WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS", + "WAL_DBGID_RESET_PCU_CYCLE_CNT", + "WAL_DBGID_SETUP_RSSI_INTERRUPTS", + "WAL_DBGID_BRSSI_CONFIG", + "WAL_DBGID_CURRENT_BRSSI_AVE", + "WAL_DBGID_BCN_TX_COMP", + "WAL_DBGID_SET_HW_CHAINMASK", + "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL", + "WAL_DBGID_GET_HW_CHAINMASK", + "WAL_DBGID_SMPS_DISABLE", + "WAL_DBGID_SMPS_ENABLE_HW_CNTRL", + "WAL_DBGID_SMPS_SWSEL_CHAINMASK", + "WAL_DBGID_DEFINITION_END", + }, + { + "" /* DE */ + }, + { + "" /* pcie lp */ + }, + { + /* RTT */ + "RTT_CALL_FLOW", + "RTT_REQ_SUB_TYPE", + "RTT_MEAS_REQ_HEAD", + "RTT_MEAS_REQ_BODY", + "", + "", + "RTT_INIT_GLOBAL_STATE", + "", + "RTT_REPORT", + "", + "RTT_ERROR_REPORT", + "RTT_TIMER_STOP", + "RTT_SEND_TM_FRAME", + "RTT_V3_RESP_CNT", + "RTT_V3_RESP_FINISH", + "RTT_CHANNEL_SWITCH_REQ", + "RTT_CHANNEL_SWITCH_GRANT", + "RTT_CHANNEL_SWITCH_COMPLETE", + "RTT_CHANNEL_SWITCH_PREEMPT", + "RTT_CHANNEL_SWITCH_STOP", + "RTT_TIMER_START", + }, + { /* RESOURCE */ + "RESOURCE_DBGID_DEFINITION_START", + "RESOURCE_PEER_ALLOC", + "RESOURCE_PEER_FREE", + "RESOURCE_PEER_ALLOC_WAL_PEER", + "RESOURCE_PEER_NBRHOOD_MGMT_ALLOC", + "RESOURCE_PEER_NBRHOOD_MGMT_INFO," + "RESOURCE_DBGID_DEFINITION_END", + }, + { /* DCS */ + "WLAN_DCS_DBGID_INIT", + "WLAN_DCS_DBGID_WMI_CWINT", + "WLAN_DCS_DBGID_TIMER", + "WLAN_DCS_DBGID_CMDG", + "WLAN_DCS_DBGID_CMDS", + "WLAN_DCS_DBGID_DINIT" + }, + { /* CACHEMGR */ + "" + }, + { /* ANI */ + "ANI_DBGID_POLL", + "ANI_DBGID_CONTROL", + "ANI_DBGID_OFDM_PARAMS", + "ANI_DBGID_CCK_PARAMS", + "ANI_DBGID_RESET", + "ANI_DBGID_RESTART", + "ANI_DBGID_OFDM_LEVEL", + "ANI_DBGID_CCK_LEVEL", + "ANI_DBGID_FIRSTEP", + "ANI_DBGID_CYCPWR", + "ANI_DBGID_MRC_CCK", + "ANI_DBGID_SELF_CORR_LOW", + "ANI_DBGID_ENABLE", + "ANI_DBGID_CURRENT_LEVEL", + "ANI_DBGID_POLL_PERIOD", + "ANI_DBGID_LISTEN_PERIOD", + "ANI_DBGID_OFDM_LEVEL_CFG", + "ANI_DBGID_CCK_LEVEL_CFG" + }, + { + "P2P_DBGID_DEFINITION_START", + "P2P_DEV_REGISTER", + "P2P_HANDLE_NOA", + "P2P_UPDATE_SCHEDULE_OPPS", + "P2P_UPDATE_SCHEDULE", + "P2P_UPDATE_START_TIME", + "P2P_UPDATE_START_TIME_DIFF_TSF32", + "P2P_UPDATE_START_TIME_FINAL", + "P2P_SETUP_SCHEDULE_TIMER", + "P2P_PROCESS_SCHEDULE_AFTER_CALC", + "P2P_PROCESS_SCHEDULE_STARTED_TIMER", + "P2P_CALC_SCHEDULES_FIRST_CALL_ALL_NEXT_EVENT", + "P2P_CALC_SCHEDULES_FIRST_VALUE", + "P2P_CALC_SCHEDULES_EARLIEST_NEXT_EVENT", + "P2P_CALC_SCHEDULES_SANITY_COUNT", + "P2P_CALC_SCHEDULES_CALL_ALL_NEXT_EVENT_FROM_WHILE_LOOP", + "P2P_CALC_SCHEDULES_TIMEOUT_1", + "P2P_CALC_SCHEDULES_TIMEOUT_2", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_EXPIRED", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_ACTIVE", + "P2P_FIND_NEXT_EVENT_REQ_NOT_STARTED", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE_NON_PERIODIC", + "P2P_FIND_NEXT_EVENT_IN_MID_OF_NOA", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE", + "P2P_SCHEDULE_TIMEOUT", + "P2P_CALC_SCHEDULES_ENTER", + "P2P_PROCESS_SCHEDULE_ENTER", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_AFTER_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_BEFORE_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_ENTER", + "P2P_FIND_NEXT_EVENT_ENTER", + "P2P_NOA_GO_PRESENT", + "P2P_NOA_GO_ABSENT", + "P2P_GO_NOA_NOTIF", + "P2P_GO_TBTT_OFFSET", + "P2P_GO_GET_NOA_INFO", + "P2P_GO_ADD_ONE_SHOT_NOA", + "P2P_GO_GET_NOA_IE", + "P2P_GO_BCN_TX_COMP", + "P2P_DBGID_DEFINITION_END", + }, + { + "CSA_DBGID_DEFINITION_START", + "CSA_OFFLOAD_POOL_INIT", + "CSA_OFFLOAD_REGISTER_VDEV", + "CSA_OFFLOAD_DEREGISTER_VDEV", + "CSA_DEREGISTER_VDEV_ERROR", + "CSA_OFFLOAD_BEACON_RECEIVED", + "CSA_OFFLOAD_BEACON_CSA_RECV", + "CSA_OFFLOAD_CSA_RECV_ERROR_IE", + "CSA_OFFLOAD_CSA_TIMER_ERROR", + "CSA_OFFLOAD_CSA_TIMER_EXP", + "CSA_OFFLOAD_WMI_EVENT_ERROR", + "CSA_OFFLOAD_WMI_EVENT_SENT", + "CSA_OFFLOAD_WMI_CHANSWITCH_RECV", + "CSA_DBGID_DEFINITION_END", + }, + { /* NLO offload */ + "" + }, + { + "WLAN_CHATTER_DBGID_DEFINITION_START", + "WLAN_CHATTER_ENTER", + "WLAN_CHATTER_EXIT", + "WLAN_CHATTER_FILTER_HIT", + "WLAN_CHATTER_FILTER_MISS", + "WLAN_CHATTER_FILTER_FULL", + "WLAN_CHATTER_FILTER_TM_ADJ", + "WLAN_CHATTER_BUFFER_FULL", + "WLAN_CHATTER_TIMEOUT", + "WLAN_CHATTER_DBGID_DEFINITION_END", + }, + { + "WOW_DBGID_DEFINITION_START", + "WOW_ENABLE_CMDID", + "WOW_RECV_DATA_PKT", + "WOW_WAKE_HOST_DATA", + "WOW_RECV_MGMT", + "WOW_WAKE_HOST_MGMT", + "WOW_RECV_EVENT", + "WOW_WAKE_HOST_EVENT", + "WOW_INIT", + "WOW_RECV_MAGIC_PKT", + "WOW_RECV_BITMAP_PATTERN", + "WOW_AP_VDEV_DISALLOW", + "WOW_STA_VDEV_DISALLOW", + "WOW_P2PGO_VDEV_DISALLOW", + "WOW_NS_OFLD_ENABLE", + "WOW_ARP_OFLD_ENABLE", + "WOW_NS_ARP_OFLD_DISABLE", + "WOW_NS_RECEIVED", + "WOW_NS_REPLIED", + "WOW_ARP_RECEIVED", + "WOW_ARP_REPLIED", + "WOW_DBGID_DEFINITION_END", + }, + { /* WAL VDEV */ + "" + }, + { /* WAL PDEV */ + "" + }, + { /* TEST */ + "TP_CHANGE_CHANNEL", + "TP_LOCAL_SEND", + }, + { /* STA SMPS */ + "STA_SMPS_DBGID_DEFINITION_START", + "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE", + "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_CREATE_STA_INSTANCE", + "STA_SMPS_DBGID_DELETE_STA_INSTANCE", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP", + "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME", + "STA_SMPS_DBGID_HOST_FORCED_MODE", + "STA_SMPS_DBGID_FW_FORCED_MODE", + "STA_SMPS_DBGID_RSSI_THRESHOLD_CROSSED", + "STA_SMPS_DBGID_SMPS_ACTION_FRAME_COMPLETION", + "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE", + "SMPS_DBGID_DEFINITION_END", + }, + { /* SWBMISS */ + "SWBMISS_DBGID_DEFINITION_START", + "SWBMISS_ENABLED", + "SWBMISS_DISABLED", + "SWBMISS_DBGID_DEFINITION_END", + }, + { /* WMMAC */ + "" + }, + { /* TDLS */ + "TDLS_DBGID_DEFINITION_START", + "TDLS_DBGID_VDEV_CREATE", + "TDLS_DBGID_VDEV_DELETE", + "TDLS_DBGID_ENABLED_PASSIVE", + "TDLS_DBGID_ENABLED_ACTIVE", + "TDLS_DBGID_DISABLED", + "TDLS_DBGID_CONNTRACK_TIMER", + "TDLS_DBGID_WAL_SET", + "TDLS_DBGID_WAL_GET", + "TDLS_DBGID_WAL_PEER_UPDATE_SET", + "TDLS_DBGID_WAL_PEER_UPDATE_EVT", + "TDLS_DBGID_WAL_VDEV_CREATE", + "TDLS_DBGID_WAL_VDEV_DELETE", + "TDLS_DBGID_WLAN_EVENT", + "TDLS_DBGID_WLAN_PEER_UPDATE_SET", + "TDLS_DBGID_PEER_EVT_DRP_THRESH", + "TDLS_DBGID_PEER_EVT_DRP_RATE", + "TDLS_DBGID_PEER_EVT_DRP_RSSI", + "TDLS_DBGID_PEER_EVT_DISCOVER", + "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", + }, + { /* HB */ + "WLAN_HB_DBGID_DEFINITION_START", + "WLAN_HB_DBGID_INIT", + "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_TCP_SEND_FAIL", + "WLAN_HB_DBGID_BSS_PEER_NULL", + "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_UDP_SEND_FAIL", + "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM", + "WLAN_HB_DBGID_WMI_CMD_INVALID_OP", + "WLAN_HB_DBGID_WOW_NOT_ENTERED", + "WLAN_HB_DBGID_ALLOC_SESS_FAIL", + "WLAN_HB_DBGID_CTX_NULL", + "WLAN_HB_DBGID_CHKSUM_ERR", + "WLAN_HB_DBGID_UDP_TX", + "WLAN_HB_DBGID_TCP_TX", + "WLAN_HB_DBGID_DEFINITION_END", + }, + { /* TXBF */ + "TXBFEE_DBGID_START", + "TXBFEE_DBGID_NDPA_RECEIVED", + "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE", + "TXBFER_DBGID_SEND_NDPA", + "TXBFER_DBGID_GET_NDPA_BUF_FAIL", + "TXBFER_DBGID_SEND_NDPA_FAIL", + "TXBFER_DBGID_GET_NDP_BUF_FAIL", + "TXBFER_DBGID_SEND_NDP_FAIL", + "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL", + "TXBFER_DBGID_SEND_BRPOLL_FAIL", + "TXBFER_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H", + "TXBFEE_DBGID_UPLOADH_CV_TAG", + "TXBFEE_DBGID_UPLOADH_H_TAG", + "TXBFEE_DBGID_CAPTUREH_RECEIVED", + "TXBFEE_DBGID_PACKET_IS_STEERED", + "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL", + "TXBFEE_DBGID_END", + }, + { /*BATCH SCAN*/ + }, + { /*THERMAL MGR*/ + "THERMAL_MGR_DBGID_DEFINITION_START", + "THERMAL_MGR_NEW_THRESH", + "THERMAL_MGR_THRESH_CROSSED", + "THERMAL_MGR_DBGID_DEFINITION END", + }, + { /* WLAN_MODULE_PHYERR_DFS */ + "" + }, + { + /* WLAN_MODULE_RMC */ + "RMC_DBGID_DEFINITION_START", + "RMC_CREATE_INSTANCE", + "RMC_DELETE_INSTANCE", + "RMC_LDR_SEL", + "RMC_NO_LDR", + "RMC_LDR_NOT_SEL", + "RMC_LDR_INF_SENT", + "RMC_PEER_ADD", + "RMC_PEER_DELETE", + "RMC_PEER_UNKNOWN", + "RMC_SET_MODE", + "RMC_SET_ACTION_PERIOD", + "RMC_ACRION_FRAME_RX", + "RMC_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_STATS */ + "WLAN_STATS_DBGID_DEFINITION_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_VDEV_EN_DIS", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_END", + "WLAN_STATS_DBGID_EST_LINKSPEED_CALC", + "WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN", + "WLAN_STATS_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_NAN */ + }, + { + /* WLAN_MODULE_IBSS_PWRSAVE */ + "IBSS_PS_DBGID_DEFINITION_START", + "IBSS_PS_DBGID_PEER_CREATE", + "IBSS_PS_DBGID_PEER_DELETE", + "IBSS_PS_DBGID_VDEV_CREATE", + "IBSS_PS_DBGID_VDEV_DELETE", + "IBSS_PS_DBGID_VDEV_EVENT", + "IBSS_PS_DBGID_PEER_EVENT", + "IBSS_PS_DBGID_DELIVER_CAB", + "IBSS_PS_DBGID_DELIVER_UC_DATA", + "IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR", + "IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_NULL_TX_COMPLETION", + "IBSS_PS_DBGID_ATIM_TIMER_START", + "IBSS_PS_DBGID_UC_ATIM_SEND", + "IBSS_PS_DBGID_BC_ATIM_SEND", + "IBSS_PS_DBGID_UC_TIMEOUT", + "IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED", + "IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED", + "IBSS_PS_DBGID_SET_PARAM", + "IBSS_PS_DBGID_HOST_TX_PAUSE", + "IBSS_PS_DBGID_HOST_TX_UNPAUSE", + "IBSS_PS_DBGID_PS_DESC_BIN_HWM", + "IBSS_PS_DBGID_PS_DESC_BIN_LWM", + "IBSS_PS_DBGID_PS_KICKOUT_PEER", + "IBSS_PS_DBGID_SET_PEER_PARAM", + "IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH", + "IBSS_PS_DBGID_RX_CHAINMASK_CHANGE", + }, + { + /* HIF UART Interface DBGIDs */ + "HIF_UART_DBGID_START", + "HIF_UART_DBGID_POWER_STATE", + "HIF_UART_DBGID_TXRX_FLOW", + "HIF_UART_DBGID_TXRX_CTRL_CHAR", + "HIF_UART_DBGID_TXRX_BUF_DUMP", + }, + { + /* LPI */ + "" + }, + { + /* EXTSCAN DBGIDs */ + "EXTSCAN_START", + "EXTSCAN_STOP", + "EXTSCAN_CLEAR_ENTRY_CONTENT", + "EXTSCAN_GET_FREE_ENTRY_SUCCESS", + "EXTSCAN_GET_FREE_ENTRY_INCONSISTENT", + "EXTSCAN_GET_FREE_ENTRY_NO_MORE_ENTRIES", + "EXTSCAN_CREATE_ENTRY_SUCCESS", + "EXTSCAN_CREATE_ENTRY_ERROR", + "EXTSCAN_SEARCH_SCAN_ENTRY_QUEUE", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_FOUND", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_NOT_FOUND", + "EXTSCAN_ADD_ENTRY", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT_FAILED", + "EXTSCAN_BUCKET_START_SCAN_CYCLE", + "EXTSCAN_BUCKET_PERIODIC_TIMER", + "EXTSCAN_SEND_START_STOP_EVENT", + "EXTSCAN_NOTIFY_WLAN_CHANGE", + "EXTSCAN_NOTIFY_WLAN_HOTLIST_MATCH", + "EXTSCAN_MAIN_RECEIVED_FRAME", + "EXTSCAN_MAIN_NO_SSID_IE", + "EXTSCAN_MAIN_MALFORMED_FRAME", + "EXTSCAN_FIND_BSSID_BY_REFERENCE", + "EXTSCAN_FIND_BSSID_BY_REFERENCE_ERROR", + "EXTSCAN_NOTIFY_TABLE_USAGE", + "EXTSCAN_FOUND_RSSI_ENTRY", + "EXTSCAN_BSSID_FOUND_RSSI_SAMPLE", + "EXTSCAN_BSSID_ADDED_RSSI_SAMPLE", + "EXTSCAN_BSSID_REPLACED_RSSI_SAMPLE", + "EXTSCAN_BSSID_TRANSFER_CURRENT_SAMPLES", + "EXTSCAN_BUCKET_PROCESS_SCAN_EVENT", + "EXTSCAN_BUCKET_CANNOT_FIND_BUCKET", + "EXTSCAN_START_SCAN_REQUEST_FAILED", + "EXTSCAN_BUCKET_STOP_CURRENT_SCANS", + "EXTSCAN_BUCKET_SCAN_STOP_REQUEST", + "EXTSCAN_BUCKET_PERIODIC_TIMER_ERROR", + "EXTSCAN_BUCKET_START_OPERATION", + "EXTSCAN_START_INTERNAL_ERROR", + "EXTSCAN_NOTIFY_HOTLIST_MATCH", + "EXTSCAN_CONFIG_HOTLIST_TABLE", + "EXTSCAN_CONFIG_WLAN_CHANGE_TABLE", + }, + { /* UNIT_TEST */ + "UNIT_TEST_GEN", + }, + { /* MLME */ + "MLME_DEBUG_CMN", + "MLME_IF", + "MLME_AUTH", + "MLME_REASSOC", + "MLME_DEAUTH", + "MLME_DISASSOC", + "MLME_ROAM", + "MLME_RETRY", + "MLME_TIMER", + "MLME_FRMPARSE", + }, + { /*SUPPLICANT */ + "SUPPL_INIT", + "SUPPL_RECV_EAPOL", + "SUPPL_RECV_EAPOL_TIMEOUT", + "SUPPL_SEND_EAPOL", + "SUPPL_MIC_MISMATCH", + "SUPPL_FINISH", + }, +}; + +int dbglog_module_log_enable(wmi_unified_t wmi_handle, A_UINT32 mod_id, + bool isenable) +{ + A_UINT32 val = 0; + + if (mod_id > WLAN_MODULE_ID_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("dbglog_module_log_enable: Invalid module id %d\n", + mod_id)); + return -EINVAL; + } + + WMI_DBGLOG_SET_MODULE_ID(val,mod_id); + if (isenable) { + /* set it to global module level */ + WMI_DBGLOG_SET_LOG_LEVEL(val,DBGLOG_INFO); + } else { + /* set it to ERROR level */ + WMI_DBGLOG_SET_LOG_LEVEL(val,DBGLOG_ERR); + } + wmi_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, val, NULL,0); + + return 0; +} + +int dbglog_vap_log_enable(wmi_unified_t wmi_handle, A_UINT16 vap_id, + bool isenable) +{ + if (vap_id > DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("dbglog_vap_log_enable:Invalid vap_id %d\n", + vap_id)); + return -EINVAL; + } + + wmi_config_debug_module_cmd(wmi_handle, + isenable ? WMI_DEBUG_LOG_PARAM_VDEV_ENABLE:WMI_DEBUG_LOG_PARAM_VDEV_DISABLE, vap_id, NULL,0 ); + + return 0; +} + +int dbglog_set_log_lvl(wmi_unified_t wmi_handle, DBGLOG_LOG_LVL log_lvl) +{ + A_UINT32 val = 0; + + if (log_lvl > DBGLOG_LVL_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("dbglog_set_log_lvl:Invalid log level %d\n", + log_lvl)); + return -EINVAL; + } + + WMI_DBGLOG_SET_MODULE_ID(val,WMI_DEBUG_LOG_MODULE_ALL); + WMI_DBGLOG_SET_LOG_LEVEL(val,log_lvl); + wmi_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, val, NULL,0); + + return 0; +} + +int dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, A_UINT32 mod_log_lvl) +{ + A_UINT32 val = 0; + /* set the global module level to log_lvl */ + WMI_DBGLOG_SET_MODULE_ID(val,(mod_log_lvl/10)); + WMI_DBGLOG_SET_LOG_LEVEL(val,(mod_log_lvl%10)); + wmi_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, val, NULL,0); + + return 0; +} + +A_STATUS +wmi_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param, A_UINT32 val, + A_UINT32 *module_id_bitmap, A_UINT32 bitmap_len) +{ + wmi_buf_t buf; + wmi_debug_log_config_cmd_fixed_param *configmsg; + A_STATUS status = A_OK; + int i; + int len; + int8_t *buf_ptr; + int32_t *module_id_bitmap_array; /* Used to fomr the second tlv*/ + + + ASSERT(bitmap_len < MAX_MODULE_ID_BITMAP_WORDS); + + /* Allocate size for 2 tlvs - including tlv hdr space for second tlv*/ + len = sizeof(wmi_debug_log_config_cmd_fixed_param) + WMI_TLV_HDR_SIZE + + (sizeof(int32_t) * MAX_MODULE_ID_BITMAP_WORDS); + buf = wmi_buf_alloc(wmi_handle, len); + if (buf == NULL) + return A_NO_MEMORY; + + configmsg = (wmi_debug_log_config_cmd_fixed_param *)(wmi_buf_data(buf)); + buf_ptr = (int8_t *)configmsg; + WMITLV_SET_HDR(&configmsg->tlv_header, + WMITLV_TAG_STRUC_wmi_debug_log_config_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_debug_log_config_cmd_fixed_param)); + configmsg->dbg_log_param = param; + configmsg->value = val; + /* Filling in the data part of second tlv -- should follow first tlv _ WMI_TLV_HDR_SIZE*/ + module_id_bitmap_array = (A_UINT32*)(buf_ptr + + sizeof(wmi_debug_log_config_cmd_fixed_param) + + WMI_TLV_HDR_SIZE); + WMITLV_SET_HDR(buf_ptr + sizeof(wmi_debug_log_config_cmd_fixed_param), + WMITLV_TAG_ARRAY_UINT32, + sizeof(A_UINT32) * MAX_MODULE_ID_BITMAP_WORDS); + if (module_id_bitmap) { + for(i=0;i TRUE) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("dbglog_report_enable:Invalid value %d\n", + isenable)); + return -EINVAL; + } + + if(isenable){ + /* set the vap enable bitmap */ + dbglog_set_vap_enable_bitmap(wmi_handle, 0xFFFF); + bitmap[0] = 0xFFFFFFFF; + bitmap[1] = 0x1F; + /* set the module level bitmap */ + dbglog_set_mod_enable_bitmap(wmi_handle, 0x0, bitmap, 2); + } else { + dbglog_set_vap_enable_bitmap(wmi_handle, bitmap[0]); + dbglog_set_mod_enable_bitmap(wmi_handle, DBGLOG_LVL_MAX, bitmap, 2); + } + return 0; +} + +static char * +dbglog_get_msg(A_UINT32 moduleid, A_UINT32 debugid) +{ + static char unknown_str[64]; + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS) { + char *str = DBG_MSG_ARR[moduleid][debugid]; + if (str && str[0] != '\0') { + return str; + } + } + + snprintf(unknown_str, sizeof(unknown_str), + "UNKNOWN %u:%u", + moduleid, debugid); + + return unknown_str; +} + +void +dbglog_printf( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, vap_id)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] ", timestamp)); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s\n", buf)); +} + +void +dbglog_printf_no_line_break( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, vap_id)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] ", timestamp)); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s", buf)); +} + +#define USE_NUMERIC 0 + +A_BOOL +dbglog_default_print_handler(A_UINT32 mod_id, A_UINT16 vap_id, A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + int i; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] vap-%u %s ( ", timestamp, vap_id, dbglog_get_msg(mod_id, dbg_id))); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (DBGLOG_PRINT_PREFIX "[%u] %s ( ", timestamp, dbglog_get_msg(mod_id, dbg_id))); + } + + for (i = 0; i < numargs; i++) { +#if USE_NUMERIC + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%u", args[i])); +#else + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%#x", args[i])); +#endif + if ((i + 1) < numargs) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (", ")); + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (" )\n")); + + return TRUE; +} + +#define DBGLOG_PARSE_ARGS_STRING_LENGTH (DBGLOG_NUM_ARGS_MAX * 11 + 10) +static int +dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) +{ + A_UINT32 timestamp; + A_UINT32 debugid; + A_UINT32 moduleid; + A_UINT16 numargs, curArgs; + A_UINT32 count = 0, totalWriteLen, writeLen; + char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH]; + char *dbgidString; + + while (count < length) { + + debugid = DBGLOG_GET_DBGID(buffer[count + 1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count + 1]); + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS && numargs <= DBGLOG_NUM_ARGS_MAX) { + + OS_MEMZERO(parseArgsString, sizeof(parseArgsString)); + totalWriteLen = 0; + + for (curArgs = 0; curArgs < numargs; curArgs++){ + // Using sprintf_s instead of sprintf, to avoid length overflow + writeLen = snprintf(parseArgsString + totalWriteLen, DBGLOG_PARSE_ARGS_STRING_LENGTH - totalWriteLen, "%x ", buffer[count + 2 + curArgs]); + totalWriteLen += writeLen; + } + + if (debugid < MAX_DBG_MSGS){ + dbgidString = DBG_MSG_ARR[moduleid][debugid]; + if (dbgidString != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("fw:%s(%x %x):%s\n", + dbgidString, + timestamp, buffer[count+1], + parseArgsString)); + } else { + /* host need sync with FW id */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "UNKNOWN", moduleid, debugid, + timestamp, buffer[count+1], + parseArgsString)); + } + } else if (debugid == DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG) { + /* specific debugid */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "DBGLOG_SM_MSG", moduleid, debugid, + timestamp, buffer[count+1], + parseArgsString)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "UNKNOWN", moduleid, debugid, + timestamp, buffer[count+1], + parseArgsString)); + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header*/ + } + + return 0; + +} + +#ifdef WLAN_OPEN_SOURCE +static int +dbglog_debugfs_raw_data(wmi_unified_t wmi_handle, const u_int8_t *buf, A_UINT32 length, A_UINT32 dropped) +{ + struct fwdebug *fwlog = (struct fwdebug *)&wmi_handle->dbglog; + struct dbglog_slot *slot; + struct sk_buff *skb; + size_t slot_len; + + if (WARN_ON(length > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; + + skb = alloc_skb(slot_len, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + slot = (struct dbglog_slot *) skb_put(skb, slot_len); + slot->diag_type = (A_UINT32)DIAG_TYPE_FW_DEBUG_MSG; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(length); + slot->dropped = cpu_to_le32(dropped); + memcpy(slot->payload, buf, length); + + /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */ + memset(slot->payload + length, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - length); + + spin_lock(&fwlog->fwlog_queue.lock); + + __skb_queue_tail(&fwlog->fwlog_queue, skb); + + complete(&fwlog->fwlog_completion); + + /* drop oldest entries */ + while (skb_queue_len(&fwlog->fwlog_queue) > + ATH6KL_FWLOG_MAX_ENTRIES) { + skb = __skb_dequeue(&fwlog->fwlog_queue); + kfree_skb(skb); + } + + spin_unlock(&fwlog->fwlog_queue.lock); + + return TRUE; +} +#endif /* WLAN_OPEN_SOURCE */ + +/* + * Package the data from the fw diag WMI event handler. + * Pass this data to cnss-diag service + */ +int +send_fw_diag_nl_data(wmi_unified_t wmi_handle, const u_int8_t *buffer, + A_UINT32 len, A_UINT32 event_type) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (cnss_diag_pid != INVALID_PID) + { + skb_out = nlmsg_new(len, 0); + if (!skb_out) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to allocate new skb\n")); + return -1; + } + nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, len, 0); + memcpy(nlmsg_data(nlh), buffer, len); + NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */ + + res = nl_srv_ucast(skb_out, cnss_diag_pid, MSG_DONTWAIT); + if (res < 0) + { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("nl_srv_ucast failed 0x%x \n", res)); + cnss_diag_pid = INVALID_PID; + return res; + } + } + return res; +} + +static int +send_diag_netlink_data(const u_int8_t *buffer, + A_UINT32 len, A_UINT32 cmd) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + struct dbglog_slot *slot; + size_t slot_len; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (cnss_diag_pid != INVALID_PID) { + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; + + skb_out = nlmsg_new(slot_len, 0); + if (!skb_out) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Failed to allocate new skb\n")); + return -1; + } + + nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, slot_len, 0); + slot = (struct dbglog_slot *) nlmsg_data(nlh); + slot->diag_type = cmd; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + /* Version mapped to get_version here */ + slot->dropped = get_version; + memcpy(slot->payload, buffer, len); + NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */ + + res = nl_srv_ucast(skb_out, cnss_diag_pid, MSG_DONTWAIT); + if (res < 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("nl_srv_ucast failed 0x%x \n", res)); + cnss_diag_pid = INVALID_PID; + return res; + } + } + return res; +} + + +int +dbglog_process_netlink_data(wmi_unified_t wmi_handle, const u_int8_t *buffer, + A_UINT32 len, A_UINT32 dropped) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + struct dbglog_slot *slot; + size_t slot_len; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (cnss_diag_pid != INVALID_PID) + { + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; + + skb_out = nlmsg_new(slot_len, 0); + if (!skb_out) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to allocate new skb\n")); + return -1; + } + + nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, slot_len, 0); + slot = (struct dbglog_slot *) nlmsg_data(nlh); + slot->diag_type = (A_UINT32)DIAG_TYPE_FW_DEBUG_MSG; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + slot->dropped = cpu_to_le32(dropped); + memcpy(slot->payload, buffer, len); + NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */ + + res = nl_srv_ucast(skb_out, cnss_diag_pid, MSG_DONTWAIT); + if (res < 0) + { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("nl_srv_ucast failed 0x%x \n", res)); + cnss_diag_pid = INVALID_PID; + return res; + } + } + return res; +} + +/* + * WMI diag data event handler, this function invoked as a CB + * when there DIAG_EVENT, DIAG_MSG, DIAG_DBG to be + * forwarded from the FW. This is the new implementation for + * replacement of fw_dbg and dbg messages + */ + +static int +diag_fw_handler(ol_scn_t scn, u_int8_t *data, u_int32_t datalen) +{ + + tp_wma_handle wma = (tp_wma_handle)scn; + wmitlv_cmd_param_info *param_buf; + u_int8_t *datap; + u_int32_t len = 0; + u_int32_t *buffer; + + if (!wma) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL Pointer assigned\n")); + return -1; + } + /* when fw asser occurs,host can't use TLV format. */ + if (wma->is_fw_assert) { + datap = data; + len = datalen; + wma->is_fw_assert = 0; + } else { + param_buf = (wmitlv_cmd_param_info *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Get NULL point message from FW\n")); + return -1; + } + + param_buf = (wmitlv_cmd_param_info *) data; + datap = param_buf->tlv_ptr; + len = param_buf->num_elements; + if (!get_version) { + buffer = (u_int32_t *)datap ; + buffer++; /* skip offset */ + if (WLAN_DIAG_TYPE_CONFIG == DIAG_GET_TYPE(*buffer)) { + buffer++; /* skip */ + if (DIAG_VERSION_INFO == DIAG_GET_ID(*buffer)) { + buffer++; /* skip */ + /* get payload */ + get_version = *buffer; + } + } + } + } + if (dbglog_process_type == DBGLOG_PROCESS_PRINT_RAW) { + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = TRUE; + } + return 0; + } + + if ( (dbglog_process_type == DBGLOG_PROCESS_NET_RAW) && + (cnss_diag_pid != 0)) { + return send_diag_netlink_data((A_UINT8 *)datap, + len, DIAG_TYPE_FW_MSG); + } + +#ifdef WLAN_OPEN_SOURCE + if (dbglog_process_type == DBGLOG_PROCESS_POOL_RAW) { + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = TRUE; + } + return 0; + } +#endif /* WLAN_OPEN_SOURCE */ + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = TRUE; + } + /* Always returns zero */ + return (0); +} + + +/* + * WMI diag data event handler, this function invoked as a CB + * when there DIAG_DATA to be forwarded from the FW. + */ + +int +fw_diag_data_event_handler(ol_scn_t scn, u_int8_t *data, u_int32_t datalen) +{ + + tp_wma_handle wma = (tp_wma_handle)scn; + struct wlan_diag_data *diag_data; + WMI_DIAG_DATA_CONTAINER_EVENTID_param_tlvs *param_buf; + wmi_diag_data_container_event_fixed_param *fixed_param; + u_int8_t *datap; + u_int32_t num_data=0; /* Total events */ + u_int32_t diag_data_len=0; /* each fw diag payload */ + u_int32_t diag_type=0; + u_int32_t i=0; + u_int32_t nl_data_len=0; /* diag hdr + payload */ + + param_buf = (WMI_DIAG_DATA_CONTAINER_EVENTID_param_tlvs *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Got NULL point message from FW\n")); + return -1; + } + + if (!wma) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL Pointer assigned\n")); + return -1; + } + + fixed_param = param_buf->fixed_param; + num_data = param_buf->num_bufp; + + datap = (u_int8_t *)param_buf->bufp; + + /* If cnss-diag service started triggered during the init of services */ + if (appstarted) { + for (i = 0; i < num_data; i++) { + diag_data = (struct wlan_diag_data *)datap; + diag_type = WLAN_DIAG_0_TYPE_GET(diag_data->word0); + diag_data_len = WLAN_DIAG_0_LEN_GET(diag_data->word0); + + /* Length of diag struct and len of payload */ + nl_data_len = sizeof(struct wlan_diag_data) + diag_data_len; +#if 0 + print_hex_dump_bytes("payload: ", DUMP_PREFIX_ADDRESS, + diag_data->payload, diag_data_len); +#endif + switch (diag_type) { + case DIAG_TYPE_FW_EVENT: + return send_fw_diag_nl_data((wmi_unified_t)wma->wmi_handle, + datap, nl_data_len, diag_type); + break; + case DIAG_TYPE_FW_LOG: + return send_fw_diag_nl_data((wmi_unified_t)wma->wmi_handle, + datap, nl_data_len, diag_type); + break; + } + /* Move to the next event and send to cnss-diag */ + datap += nl_data_len; + } + } + return 0; +} + + +int +dbglog_parse_debug_logs(ol_scn_t scn, u_int8_t *data, u_int32_t datalen) +{ + tp_wma_handle wma = (tp_wma_handle)scn; + A_UINT32 count; + A_UINT32 *buffer; + A_UINT32 timestamp; + A_UINT32 debugid; + A_UINT32 moduleid; + A_UINT16 vapid; + A_UINT16 numargs; + adf_os_size_t length; + A_UINT32 dropped; + WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; + u_int8_t *datap; + u_int32_t len; + + if (!wma) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL Pointer assigned\n")); + return -1; + } + /*when fw asser occurs,host can't use TLV format.*/ + if (wma->is_fw_assert) { + datap = data; + len = datalen; + wma->is_fw_assert = 0; + } else { + param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Get NULL point message from FW\n")); + return -1; + } + + datap = param_buf->bufp; + len = param_buf->num_bufp; + } + + dropped = *((A_UINT32 *)datap); + if (dropped > 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%d log buffers are dropped \n", dropped)); + } + datap += sizeof(dropped); + len -= sizeof(dropped); + + count = 0; + buffer = (A_UINT32 *)datap; + length = (len >> 2); + + if ( dbglog_process_type == DBGLOG_PROCESS_PRINT_RAW) { + return dbglog_print_raw_data(buffer, length); + } + + if ( dbglog_process_type == DBGLOG_PROCESS_NET_RAW) { + if(appstarted){ + return dbglog_process_netlink_data((wmi_unified_t)wma->wmi_handle, + (A_UINT8 *)buffer, + len, dropped); + } else { + return 0; + } + + } + +#ifdef WLAN_OPEN_SOURCE + if (dbglog_process_type == DBGLOG_PROCESS_POOL_RAW) { + return dbglog_debugfs_raw_data((wmi_unified_t)wma->wmi_handle, + (A_UINT8 *)buffer, len, dropped); + } +#endif /* WLAN_OPEN_SOURCE */ + + while ((count + 2) < length) { + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + debugid = DBGLOG_GET_DBGID(buffer[count + 1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); + vapid = DBGLOG_GET_VDEVID(buffer[count + 1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count + 1]); + + if ((count + 2 + numargs) > length) + return 0; + + if (moduleid >= WLAN_MODULE_ID_MAX) + return 0; + + if (mod_print[moduleid] == NULL) { + /* No module specific log registered use the default handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + } else { + if(!(mod_print[moduleid](moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)))) { + /* The message is not handled by the module specific handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header*/ + } + /* Always returns zero */ + return (0); +} + +void +dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn) +{ + if (!mod_print[mod_id]) { + mod_print[mod_id] = printfn; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("module print is already registered for this module %d\n", + mod_id)); + } +} + +void +dbglog_sm_print( + A_UINT32 timestamp, + A_UINT16 vap_id, + A_UINT16 numargs, + A_UINT32 *args, + const char *module_prefix, + const char *states[], A_UINT32 num_states, + const char *events[], A_UINT32 num_events) +{ + A_UINT8 type, arg1, arg2, arg3; + A_UINT32 extra, extra2, extra3; + + if (numargs != 4) { + return; + } + + type = (args[0] >> 24) & 0xff; + arg1 = (args[0] >> 16) & 0xff; + arg2 = (args[0] >> 8) & 0xff; + arg3 = (args[0] >> 0) & 0xff; + + extra = args[1]; + extra2 = args[2]; + extra3 = args[3]; + + switch (type) { + case 0: /* state transition */ + if (arg1 < num_states && arg2 < num_states) { + dbglog_printf(timestamp, vap_id, "%s: %s => %s (%#x, %#x, %#x)", + module_prefix, states[arg1], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u => %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 1: /* dispatch event */ + if (arg1 < num_states && arg2 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: %s < %s (%#x, %#x, %#x)", + module_prefix, states[arg1], events[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u < %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 2: /* warning */ + switch (arg1) { + case 0: /* unhandled event */ + if (arg2 < num_states && arg3 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %s in state %s (%#x, %#x, %#x)", + module_prefix, events[arg3], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %u in state %u (%#x, %#x, %#x)", + module_prefix, arg3, arg2, extra, extra2, extra3); + } + break; + default: + break; + + } + break; + } +} + +A_BOOL +dbglog_sta_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "ACTIVE", + "SLEEP_TXQ_FLUSH", + "SLEEP_TX_SENT", + "PAUSE", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TXQ_FLUSH", + "ACTIVE_TX_SENT", + "PAUSE_TXQ_FLUSH", + "PAUSE_TX_SENT", + "IDLE_TXQ_FLUSH", + "IDLE_TX_SENT", + }; + + static const char *events[] = { + "START", + "STOP", + "PAUSE", + "UNPAUSE", + "TIM", + "DTIM", + "SEND_COMPLETE", + "PRE_SEND", + "RX", + "HWQ_EMPTY", + "PAUSE_TIMEOUT", + "TXRX_INACTIVITY_TIMEOUT", + "PSPOLL_TIMEOUT", + "UAPSD_TIMEOUT", + "DELAYED_SLEEP_TIMEOUT", + "SEND_N_COMPLETE", + "TIDQ_PAUSE_COMPLETE", + "SEND_PSPOLL", + "SEND_SPEC_PSPOLL", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case PS_STA_PM_ARB_REQUEST: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, "PM ARB request flags=%x, last_time=%x %s: %s", + args[1], args[2], dbglog_get_module_str(args[0]), args[3] ? "SLEEP" : "WAKE"); + } + break; + case PS_STA_DELIVER_EVENT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, "STA PS: %s %s", + (args[0] == 0 ? "PAUSE_COMPLETE" : + (args[0] == 1 ? "UNPAUSE_COMPLETE" : + (args[0] == 2 ? "SLEEP" : + (args[0] == 3 ? "AWAKE" : "UNKNOWN")))), + (args[1] == 0 ? "SUCCESS" : + (args[1] == 1 ? "TXQ_FLUSH_TIMEOUT" : + (args[1] == 2 ? "NO_ACK" : + (args[1] == 3 ? "RX_LEAK_TIMEOUT" : + (args[1] == 4 ? "PSPOLL_UAPSD_BUSY_TIMEOUT" : "UNKNOWN")))))); + } + break; + case PS_STA_PSPOLL_SEQ_DONE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, "STA PS poll: queue=%u comp=%u rsp=%u rsp_dur=%u fc=%x qos=%x %s", + args[0], args[1], args[2], args[3], + (args[4] >> 16) & 0xffff, + (args[4] >> 8) & 0xff, + (args[4] & 0xff) == 0 ? "SUCCESS" : + (args[4] & 0xff) == 1 ? "NO_ACK" : + (args[4] & 0xff) == 2 ? "DROPPED" : + (args[4] & 0xff) == 3 ? "FILTERED" : + (args[4] & 0xff) == 4 ? "RSP_TIMEOUT" : "UNKNOWN"); + } + break; + case PS_STA_COEX_MODE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "STA PS COEX MODE %s", + args[0] ? "ENABLED" : "DISABLED"); + } + break; + case PS_STA_PSPOLL_ALLOW: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "STA PS-Poll %s flags=%x time=%u", + args[0] ? "ALLOW" : "DISALLOW", args[1], args[2]); + } + break; + case PS_STA_SET_PARAM: + if (numargs == 2) { + struct { + char *name; + int is_time_param; + } params[] = { + { "MAX_SLEEP_ATTEMPTS", 0 }, + { "DELAYED_SLEEP", 1 }, + { "TXRX_INACTIVITY", 1 }, + { "MAX_TX_BEFORE_WAKE", 0 }, + { "UAPSD_TIMEOUT", 1 }, + { "UAPSD_CONFIG", 0 }, + { "PSPOLL_RESPONSE_TIMEOUT", 1 }, + { "MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "RX_WAKE_POLICY", 0 }, + { "DELAYED_PAUSE_RX_LEAK", 1 }, + { "TXRX_INACTIVITY_BLOCKED_RETRY", 1 }, + { "SPEC_WAKE_INTERVAL", 1 }, + { "MAX_SPEC_NODATA_PSPOLL", 0 }, + { "ESTIMATED_PSPOLL_RESP_TIME", 1 }, + { "QPOWER_MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "QPOWER_ENABLE", 0 }, + }; + A_UINT32 param = args[0]; + A_UINT32 value = args[1]; + + if (param < ARRAY_LENGTH(params)) { + if (params[param].is_time_param) { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %u (us)", + params[param].name, value); + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %#x", + params[param].name, value); + } + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %x => %#x", + param, value); + } + } + break; + case PS_STA_SPECPOLL_TIMER_STARTED: + dbglog_printf(timestamp, vap_id, "SPEC Poll Timer Started: Beacon time Remaining:%d wakeup interval:%d", args[0], args[1]); + break; + case PS_STA_SPECPOLL_TIMER_STOPPED: + dbglog_printf(timestamp, vap_id, + "SPEC Poll Timer Stopped"); + break; + default: + return FALSE; + } + + return TRUE; +} +/* IBSS PS sub modules */ +enum wlan_ibss_ps_sub_module { + WLAN_IBSS_PS_SUB_MODULE_IBSS_NW_SM = 0, + WLAN_IBSS_PS_SUB_MODULE_IBSS_SELF_PS = 1, + WLAN_IBSS_PS_SUB_MODULE_IBSS_PEER_PS = 2, + WLAN_IBSS_PS_SUB_MODULE_MAX = 3, +}; + +#define WLAN_IBSS_PS_SUB_MODULE_OFFSET 0x1E + +A_BOOL +dbglog_ibss_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *nw_states[] = { + "WAIT_FOR_TBTT", + "ATIM_WINDOW_PRE_BCN", + "ATIM_WINDOW_POST_BCN", + "OUT_OF_ATIM_WINDOW", + "PAUSE_PENDING", + "PAUSED", + }; + + static const char *ps_states[] = { + "ACTIVE", + "SLEEP_TX_SEND", + "SLEEP_DOZE_PAUSE_PENDING", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TX_SEND", + "PAUSE_TX_SEND", + "PAUSED", + }; + + static const char *peer_ps_states[] = { + "ACTIVE", + "SLEEP_AWAKE", + "SLEEP_DOZE", + "PS_UNKNOWN", + }; + + static const char *events[] = { + "START", + "STOP", + "SWBA", + "TBTT", + "TX_BCN_CMP", + "SEND_COMPLETE", + "SEND_N_COMPLETE", + "PRE_SEND", + "RX", + "UC_INACTIVITY_TIMEOUT", + "BC_INACTIVITY_TIMEOUT", + "ATIM_WINDOW_BEGIN", + "ATIM_WINDOW_END", + "HWQ_EMPTY", + "UC_ATIM_RCVD", + "TRAFFIC_EXCHANGE_DONE", + "POWER_SAVE_STATE_CHANGE", + "NEW_PEER_JOIN", + "IBSS_VDEV_PAUSE_REQUEST", + "IBSS_VDEV_PAUSE_RESPONSE", + "IBSS_VDEV_PAUSE_TIMEOUT", + "IBSS_VDEV_UNPAUSE_REQUEST", + "PS_STATE_CHANGE", + }; + + enum wlan_ibss_ps_sub_module sub_module; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + sub_module = (args[1] >> WLAN_IBSS_PS_SUB_MODULE_OFFSET) & 0x3; + switch(sub_module) + { + case WLAN_IBSS_PS_SUB_MODULE_IBSS_NW_SM: + dbglog_sm_print(timestamp, vap_id, numargs, args, "IBSS PS NW", + nw_states, ARRAY_LENGTH(nw_states), events, + ARRAY_LENGTH(events)); + break; + case WLAN_IBSS_PS_SUB_MODULE_IBSS_SELF_PS: + dbglog_sm_print(timestamp, vap_id, numargs, args, + "IBSS PS Self", ps_states, ARRAY_LENGTH(ps_states), + events, ARRAY_LENGTH(events)); + break; + case WLAN_IBSS_PS_SUB_MODULE_IBSS_PEER_PS: + dbglog_sm_print(timestamp, vap_id, numargs, args, + "IBSS PS Peer", peer_ps_states, + ARRAY_LENGTH(peer_ps_states), events, + ARRAY_LENGTH(events)); + break; + default: + break; + } + break; + case IBSS_PS_DBGID_PEER_CREATE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: peer alloc failed for peer ID:%u", args[0]); + } else if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: create peer ID=%u", args[0]); + } + break; + case IBSS_PS_DBGID_PEER_DELETE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: delete peer ID=%u num_peers:%d num_sleeping_peers:%d ps_enabled_for_this_peer:%d", + args[0], args[1], args[2], args[3]); + } + break; + case IBSS_PS_DBGID_VDEV_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev alloc failed", + args[0]); + } else if (numargs == 0) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev created"); + } + break; + case IBSS_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "IBSS PS: vdev deleted"); + break; + + case IBSS_PS_DBGID_VDEV_EVENT: + if (numargs == 1) { + if (args[0] == 5) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event for peer add"); + } else if (args[0] == 7) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event for peer delete"); + } + else { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event %u", args[0]); + } + } + break; + + case IBSS_PS_DBGID_PEER_EVENT: + if (numargs == 4) { + if (args[0] == 0xFFFF) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: pre_send for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x20000) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: send_complete for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x10) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: send_n_complete for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x40) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: rx event for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: hw_q_empty for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } + } + break; + + case IBSS_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver CAB n_mpdu:%d send_flags:%0x tid_cur:%d q_depth_for_other_tid:%d", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_DELIVER_UC_DATA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver UC data peer:%d tid:%d n_mpdu:%d send_flags:%0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver UC data error peer:%d tid:%d allowed_tidmask:%0x, pending_tidmap:%0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: UC timer restart peer:%d timer_val:%0x", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: MC timer restart timer_val:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_NULL_TX_COMPLETION: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: null tx completion peer:%d tx_completion_status:%d flags:%0x", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_ATIM_TIMER_START: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: ATIM timer start tsf:%0x %0x tbtt:%0x %0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_UC_ATIM_SEND: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Send ATIM to peer:%d", + args[1]); + } else if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: no peers to send UC ATIM", + args[1]); + } + break; + + case IBSS_PS_DBGID_BC_ATIM_SEND: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: MC Data, num_of_peers:%d bc_atim_sent:%d", + args[1], args[0]); + } + break; + + case IBSS_PS_DBGID_UC_TIMEOUT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: UC timeout for peer:%d send_null:%d", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED: + dbglog_printf(timestamp, vap_id, "IBSS PS: allow power collapse"); + break; + + case IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED: + if (numargs == 0) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by INI"); + } else if(numargs == 1) { + dbglog_printf(timestamp, vap_id, "IBSS PS: power collapse not allowed since peer id:%d is not PS capable", + args[0]); + } else if(numargs == 2) { + dbglog_printf(timestamp, vap_id, "IBSS PS: power collapse not allowed - no peers in NW"); + } else if (numargs == 3) { + if (args[0] == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed, non-zero qdepth %d %d", + args[1], args[2]); + } else if (args[0] == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by peer:%d peer_flags:%0x", + args[1], args[2]); + } + } else if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by state m/c nw_cur_state:%d nw_next_state:%d ps_cur_state:%d flags:%0x", + args[1], args[2], args[3], args[4]); + } + break; + + case IBSS_PS_DBGID_SET_PARAM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Set Param ID:%0x Value:%0x", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_HOST_TX_PAUSE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Pausing host, vdev_map:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_HOST_TX_UNPAUSE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Unpausing host, vdev_map:%0x", + args[0]); + } + break; + case IBSS_PS_DBGID_PS_DESC_BIN_LWM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: LWM, vdev_map:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_PS_DESC_BIN_HWM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: HWM, vdev_map:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_PS_KICKOUT_PEER: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Kickout peer id:%d atim_fail_cnt:%d status:%d", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_SET_PEER_PARAM: + if(numargs == 3) { + dbglog_printf(timestamp, vap_id, "IBSS PS: Set Peer Id:%d Param ID:%0x Value:%0x", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH: + if(numargs == 4) { + if(args[0] == 0xDEAD) { + dbglog_printf(timestamp, vap_id, "IBSS PS: ATIM window length mismatch, our's:%d, peer id:%d, peer's:%d", + args[1], args[2], args[3]); + } else if(args[0] == 0xBEEF) { + dbglog_printf(timestamp, vap_id, "IBSS PS: Peer ATIM window length changed, peer id:%d, peer recorded atim window:%d new atim window:%d", + args[1], args[2], args[3]); + } + } + break; + + case IBSS_PS_DBGID_RX_CHAINMASK_CHANGE: + if(numargs == 2) { + if(args[1] == 0x1) { + dbglog_printf(timestamp, vap_id, "IBSS PS: Voting for low power chainmask from :%d", args[0]); + } else { + dbglog_printf(timestamp, vap_id, "IBSS PS: Voting for high power chainmask from :%d", args[0]); + } + } + break; + + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_ratectrl_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case RATECTRL_DBGID_ASSOC: + dbglog_printf(timestamp, vap_id, "RATE: ChainMask %d, phymode %d, ni_flags 0x%08x, vht_mcs_set 0x%04x, ht_mcs_set 0x%04x", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_NSS_CHANGE: + dbglog_printf(timestamp, vap_id, "RATE: NEW NSS %d\n", args[0]); + break; + case RATECTRL_DBGID_CHAINMASK_ERR: + dbglog_printf(timestamp, vap_id, "RATE: Chainmask ERR %d %d %d\n", + args[0], args[1], args[2]); + break; + case RATECTRL_DBGID_UNEXPECTED_FRAME: + dbglog_printf(timestamp, vap_id, "RATE: WARN1: rate %d flags 0x%08x\n", args[0], args[1]); + break; + case RATECTRL_DBGID_WAL_RCQUERY: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcquery [rix1 %d rix2 %d rix3 %d proberix %d ppduflag 0x%x] ", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_WAL_RCUPDATE: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ", + args[0], args[1]); + break; + case RATECTRL_DBGID_GTX_UPDATE: + { + switch (args[0]) { + case 255: + dbglog_printf(timestamp, vap_id, "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ", + args[1] >> 8, args[1] & 0xff, args[2], args[3], args[4]); + break; + case 254: + dbglog_printf(timestamp, vap_id, "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ", + args[1], args[2], args[3], args[4]); + break; + default: + dbglog_printf(timestamp, vap_id, "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ", + args[0], args[1], args[2], args[3], args[4], args[5]); + } + } + break; + } + return TRUE; +} + +A_BOOL dbglog_ani_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case ANI_DBGID_ENABLE: + dbglog_printf(timestamp, vap_id, + "ANI Enable: %d", args[0]); + break; + case ANI_DBGID_POLL: + dbglog_printf(timestamp, vap_id, + "ANI POLLING: AccumListenTime %d ListenTime %d ofdmphyerr %d cckphyerr %d", + args[0], args[1], args[2],args[3]); + break; + case ANI_DBGID_RESTART: + dbglog_printf(timestamp, vap_id,"ANI Restart"); + break; + case ANI_DBGID_CURRENT_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI CURRENT LEVEL ofdm level %d cck level %d",args[0],args[1]); + break; + case ANI_DBGID_OFDM_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE ofdm level %d firstep %d firstep_low %d cycpwr_thr %d self_corr_low %d", + args[0], args[1],args[2],args[3],args[4]); + break; + case ANI_DBGID_CCK_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE cck level %d firstep %d firstep_low %d mrc_cck %d", + args[0],args[1],args[2],args[3]); + break; + case ANI_DBGID_CONTROL: + dbglog_printf(timestamp, vap_id, + "ANI CONTROL ofdmlevel %d ccklevel %d\n", + args[0]); + + break; + case ANI_DBGID_OFDM_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI ofdm_control firstep %d cycpwr %d\n", + args[0],args[1]); + break; + case ANI_DBGID_CCK_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI cck_control mrc_cck %d barker_threshold %d\n", + args[0],args[1]); + break; + case ANI_DBGID_RESET: + dbglog_printf(timestamp, vap_id, + "ANI resetting resetflag %d resetCause %8x channel index %d", + args[0],args[1],args[2]); + break; + case ANI_DBGID_SELF_CORR_LOW: + dbglog_printf(timestamp, vap_id,"ANI self_corr_low %d",args[0]); + break; + case ANI_DBGID_FIRSTEP: + dbglog_printf(timestamp, vap_id,"ANI firstep %d firstep_low %d", + args[0],args[1]); + break; + case ANI_DBGID_MRC_CCK: + dbglog_printf(timestamp, vap_id,"ANI mrc_cck %d",args[0]); + break; + case ANI_DBGID_CYCPWR: + dbglog_printf(timestamp, vap_id,"ANI cypwr_thresh %d",args[0]); + break; + case ANI_DBGID_POLL_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure poll period to %d",args[0]); + break; + case ANI_DBGID_LISTEN_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure listen period to %d",args[0]); + break; + case ANI_DBGID_OFDM_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure ofdm level to %d",args[0]); + break; + case ANI_DBGID_CCK_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure cck level to %d",args[0]); + break; + default: + dbglog_printf(timestamp, vap_id,"ANI arg1 %d arg2 %d arg3 %d", + args[0],args[1],args[2]); + break; + } + return TRUE; +} + +A_BOOL +dbglog_ap_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case AP_PS_DBGID_UPDATE_TIM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: TIM update AID=%u %s", + args[0], args[1] ? "set" : "clear"); + } + break; + case AP_PS_DBGID_PEER_STATE_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u power save %s", + args[0], args[1] ? "enabled" : "disabled"); + } + break; + case AP_PS_DBGID_PSPOLL: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u pspoll response tid=%u flags=%x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_PEER_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: create peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_PEER_DELETE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: delete peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_VDEV_CREATE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev create"); + break; + case AP_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev delete"); + break; + case AP_PS_DBGID_SYNC_TIM: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u advertised=%#x buffered=%#x", args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_NEXT_RESPONSE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u select next response %s%s%s", args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending usp) " : "", + args[3] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_START_SP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u START SP tsf=%#x (%u)", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_COMPLETED_EOSP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u EOSP eosp_tsf=%#x trigger_tsf=%#x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u TRIGGER tsf=%#x %s%s", args[0], args[1], + args[2] ? "(usp active) " : "", + args[3] ? "(send_n in progress)" : ""); + } + break; + case AP_PS_DBGID_DUPLICATE_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u DUP TRIGGER tsf=%#x seq=%u ac=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_UAPSD_RESPONSE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u UAPSD response tid=%u, n_mpdu=%u flags=%#x max_sp=%u current_sp=%u", + args[0], args[1], args[2], args[3], (args[4] >> 16) & 0xffff, args[4] & 0xffff); + } + break; + case AP_PS_DBGID_SEND_COMPLETE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_COMPLETE fc=%#x qos=%#x %s%s", + args[0], args[1], args[2], + args[3] ? "(usp active) " : "", + args[4] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_SEND_N_COMPLETE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_N_COMPLETE %s%s", + args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u detected out-of-sync now=%u tx_waiting=%u txq_depth=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: CAB %s n_mpdus=%u, flags=%x, extra=%u", + (args[0] == 17) ? "MGMT" : "DATA", args[1], args[2], args[3]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_wal_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "WAIT", + "WAIT_FILTER", + "PAUSE", + "PAUSE_SEND_N", + "BLOCK", + }; + + static const char *events[] = { + "PAUSE", + "PAUSE_FILTER", + "UNPAUSE", + + "BLOCK", + "BLOCK_FILTER", + "UNBLOCK", + + "HWQ_EMPTY", + "ALLOW_N", + }; + +#define WAL_VDEV_TYPE(type) \ + (type == 0 ? "AP" : \ + (type == 1 ? "STA" : \ + (type == 2 ? "IBSS" : \ + (type == 2 ? "MONITOR" : \ + "UNKNOWN")))) + +#define WAL_SLEEP_STATE(state) \ + (state == 1 ? "NETWORK SLEEP" : \ + (state == 2 ? "AWAKE" : \ + (state == 3 ? "SYSTEM SLEEP" : \ + "UNKNOWN"))) + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "TID PAUSE", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case WAL_DBGID_SET_POWER_STATE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "WAL %s => %s, req_count=%u", + WAL_SLEEP_STATE(args[0]), WAL_SLEEP_STATE(args[1]), + args[2]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "WAL channel change (force reset) freq=%u, flags=%u mode=%u rx_ok=%u tx_ok=%u", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1], + args[2], args[3]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "WAL channel change freq=%u, mode=%u flags=%u rx_ok=1 tx_ok=1", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1]); + } + break; + case WAL_DBGID_VDEV_START: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "WAL %s vdev started", + WAL_VDEV_TYPE(args[0])); + } + break; + case WAL_DBGID_VDEV_STOP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev stopped", + WAL_VDEV_TYPE(args[0])); + break; + case WAL_DBGID_VDEV_UP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev up, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_VDEV_DOWN: + dbglog_printf(timestamp, vap_id, "WAL %s vdev down, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame desc_id=0x%x, seq=0x%x, type=0x%x, len=0x%x islocal=0x%x", + args[0], args[1], args[2], (args[3] & 0xffff0000) >> 16, args[3] & 0x0000ffff); + break; + case WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame completion desc_id=0x%x, status=0x%x, islocal=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame msdu_id=0x%x, seq=0x%x, type=0x%x, len=0x%x", + args[0], args[1], args[2], args[3]); + break; + case WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame completion desc_id=0x%x, status=0x%x, seq=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_RESET_PCU_CYCLE_CNT: + dbglog_printf(timestamp, vap_id, "WAL PCU cycle counter value at reset:%x", args[0]); + break; + case WAL_DBGID_TX_DISCARD: + dbglog_printf(timestamp, vap_id, "WAL Tx enqueue discard msdu_id=0x%x", args[0]); + break; + case WAL_DBGID_SET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK " + "pdev=%d, txchain=0x%x, rxchain=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL rxstop=%d, txstop=%d", + args[0], args[1]); + break; + case WAL_DBGID_GET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_GET_HW_CHAINMASK " + "txchain=0x%x, rxchain=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_DISABLE: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_DISABLE"); + break; + case WAL_DBGID_SMPS_ENABLE_HW_CNTRL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_ENABLE_HW_CNTRL low_pwr_mask=0x%x, high_pwr_mask=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_SWSEL_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_SWSEL_CHAINMASK low_pwr=0x%x, chain_mask=0x%x", + args[0], args[1]); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_scan_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "BSSCHAN", + "WAIT_FOREIGN_CHAN", + "FOREIGN_CHANNEL", + "TERMINATING" + }; + + static const char *events[] = { + "REQ", + "STOP", + "BSSCHAN", + "FOREIGN_CHAN", + "CHECK_ACTIVITY", + "REST_TIME_EXPIRE", + "DWELL_TIME_EXPIRE", + "PROBE_TIME_EXPIRE", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "SCAN", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_coex_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 * args) +{ + A_UINT8 i; + char * dbg_id_str; + + static const char * wlan_rx_xput_status[] = { + "WLAN_XPUT_NORMAL", + "WLAN_XPUT_UNDER_THRESH", + "WLAN_XPUT_CRITICAL", + "WLAN_XPUT_RECOVERY_TIMEOUT", + }; + + static const char * coex_sched_req[] = { + "SCHED_REQ_NEXT", + "SCHED_REQ_BT", + "SCHED_REQ_WLAN", + "SCHED_REQ_POSTPAUSE", + "SCHED_REQ_UNPAUSE", + }; + + static const char * coex_sched_type[] = { + "SCHED_NONE", + "SCHED_WLAN", + "SCHED_BT", + "SCHED_WLAN_PAUSE", + "SCHED_WLAN_POSTPAUSE", + "SCHED_WLAN_UNPAUSE", + "COEX_SCHED_MWS", + }; + + static const char * coex_trf_mgmt_type[] = { + "TRF_MGMT_FREERUN", + "TRF_MGMT_SHAPE_PM", + "TRF_MGMT_SHAPE_PSP", + "TRF_MGMT_SHAPE_S_CTS", + "TRF_MGMT_SHAPE_OCS", + "TRF_MGMT_SHAPE_FIXED_TIME", + "TRF_MGMT_SHAPE_NOA", + "TRF_MGMT_SHAPE_OCS_CRITICAL", + "TRF_MGMT_NONE", + }; + + static const char * coex_system_status[] = { + "ALL_OFF", + "BTCOEX_NOT_REQD", + "WLAN_IS_IDLE", + "EXECUTE_SCHEME", + "BT_FULL_CONCURRENCY", + "WLAN_SLEEPING", + "WLAN_IS_PAUSED", + "WAIT_FOR_NEXT_ACTION", + "SOC_WAKE", + }; + + static const char * wlan_rssi_type[] = { + "LOW_RSSI", + "MID_RSSI", + "HI_RSSI", + "INVALID_RSSI", + }; + + static const char * coex_bt_scheme[] = { + "IDLE_CTRL", + "ACTIVE_ASYNC_CTRL", + "PASSIVE_SYNC_CTRL", + "ACTIVE_SYNC_CTRL", + "DEFAULT_CTRL", + "CONCURRENCY_CTRL", + }; + + static const char * wal_peer_rx_rate_stats_event_sent[] = { + "PR_RX_EVT_SENT_NONE", + "PR_RX_EVT_SENT_LOWER", + "PR_RX_EVT_SENT_UPPER", + }; + + static const char * wlan_psp_stimulus[] = { + "ENTRY", + "EXIT", + "PS_READY", + "PS_NOT_READY", + "RX_MORE_DATA_RCVD", + "RX_NO_MORE_DATA_RCVD", + "TX_DATA_COMPLT", + "TX_COMPLT", + "TIM_SET", + "REQ", + "DONE_SUCCESS", + "DONE_NO_PS_POLL_ACK", + "DONE_RESPONSE_TMO", + "DONE_DROPPED", + "DONE_FILTERED", + "WLAN_START", + "NONWLAN_START", + "NONWLAN_INTVL_UPDATE", + "NULL_TX", + "NULL_TX_COMPLT", + "BMISS_FIRST", + "NULL_TX_FAIL", + "RX_NO_MORE_DATA_DATAFRM", + }; + + static const char * coex_pspoll_state[] = { + "STATE_DISABLED", + "STATE_NOT_READY", + "STATE_ENABLED", + "STATE_READY", + "STATE_TX_STATUS", + "STATE_RX_STATUS", + }; + + static const char * coex_scheduler_interval[] = { + "COEX_SCHED_NONWLAN_INT", + "COEX_SCHED_WLAN_INT", + }; + + static const char * wlan_weight[] = { + "BT_COEX_BASE", + "BT_COEX_LOW", + "BT_COEX_MID", + "BT_COEX_MID_NONSYNC", + "BT_COEX_HI_NONVOICE", + "BT_COEX_HI", + "BT_COEX_CRITICAL", + }; + + static const char * wlan_power_state[] = { + "SLEEP", + "AWAKE", + "FULL_SLEEP", + }; + + static const char * coex_psp_error_type[] = { + "DISABLED_STATE", + "VDEV_NULL", + "COEX_PSP_ENTRY", + "ZERO_INTERVAL", + "COEX_PSP_EXIT", + "READY_DISABLED", + "READY_NOT_DISABLED", + "POLL_PKT_DROPPED", + "SET_TIMER_PARAM", + }; + + static const char * wlan_phymode[] = { + "A", + "G", + "B", + "G_ONLY", + "NA_HT20", + "NG_HT20", + "NA_HT40", + "NG_HT40", + "AC_VHT20", + "AC_VHT40", + "AC_VHT80", + "AC_VHT20_2G", + "AC_VHT40_2G", + "AC_VHT80_2G", + "UNKNOWN", + }; + + static const char * wlan_curr_band[] = { + "2G", + "5G", + }; + + dbg_id_str = dbglog_get_msg(mod_id, dbg_id); + + switch (dbg_id) { + case COEX_SYSTEM_UPDATE: + if (numargs == 1 && args[0] < 9) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_system_status[args[0]]); + } else if (numargs >= 5 && args[0] < 9 && args[2] < 9) { + dbglog_printf(timestamp, vap_id, "%s: %s, WlanSysState(0x%x), %s, NumChains(%u), AggrLimit(%u)", + dbg_id_str, coex_system_status[args[0]], args[1], coex_trf_mgmt_type[args[2]], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_SCHED_START: + if (numargs >= 5 && args[0] < 5 && args[2] < 9 && args[3] < 4 && args[4] < 4) { + if (args[1] == 0xffffffff) { + dbglog_printf(timestamp, vap_id, "%s: %s, DETERMINE_DURATION, %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } else { + dbglog_printf(timestamp, vap_id, "%s: %s, IntvlDur(%u), %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], args[1], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } + } else { + return FALSE; + } + break; + case COEX_SCHED_RESULT: + if (numargs >= 5 && args[0] < 5 && args[1] < 9 && args[2] < 9) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, %s, CoexMgrPolicy(%u), IdleOverride(%u)", + dbg_id_str, coex_sched_req[args[0]], coex_trf_mgmt_type[args[1]], coex_trf_mgmt_type[args[2]], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_BT_SCHEME: + if (numargs >= 1 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_bt_scheme[args[0]]); + } else { + return FALSE; + } + break; + case COEX_TRF_FREERUN: + if (numargs >= 5 && args[0] < 7) { + dbglog_printf(timestamp, vap_id, "%s: %s, AllocatedBtIntvls(%u), BtIntvlCnt(%u), AllocatedWlanIntvls(%u), WlanIntvlCnt(%u)", + dbg_id_str, coex_sched_type[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_TRF_SHAPE_PM: // used by ocs now + if (numargs >= 3) { + dbglog_printf(timestamp, vap_id, "%s: IntvlLength(%u), BtDuration(%u), WlanDuration(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return FALSE; + } + break; + case COEX_SYSTEM_MONITOR: + if (numargs >= 5 && args[1] < 4 && args[4] < 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanRxCritical(%u), %s, MinDirectRxRate(%u), MonitorActiveNum(%u), %s", + dbg_id_str, args[0], wlan_rx_xput_status[args[1]], args[2], args[3], wlan_rssi_type[args[4]]); + } else { + return FALSE; + } + break; + case COEX_RX_RATE: + if (numargs >= 5 && args[4] < 3) { + dbglog_printf(timestamp, vap_id, "%s: NumUnderThreshPeers(%u), MinDirectRate(%u), LastRateSample(%u), DeltaT(%u), %s", + dbg_id_str, args[0], args[1], args[2], args[3], wal_peer_rx_rate_stats_event_sent[args[4]]); + } else { + return FALSE; + } + break; + case COEX_WLAN_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: WlanIntvlCnt(%u), Duration(%u), Weight(%u), BaseIdleOverride(%u), WeightMat[0](0x%x)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_WLAN_POSTPAUSE_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanPostPauseIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_BT_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: BtIntvlCnt(%u), Duration(%u), Weight(%u), BaseIdleOverride(%u), WeightMat[0](0x%x), ", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_POWER_CHANGE: + if (numargs >= 3 && args[1] < 3 && args[2] < 3) { + dbglog_printf(timestamp, vap_id, "%s: Event(0x%x) %s->%s", + dbg_id_str, args[0], wlan_power_state[args[1]], wlan_power_state[args[2]]); + } else { + return FALSE; + } + break; + case COEX_CHANNEL_CHANGE: + if (numargs >= 5 && args[3] < 2 && args[4] < 15) { + dbglog_printf(timestamp, vap_id, "%s: %uMhz->%uMhz, WlanSysState(0x%x), CurrBand(%s), PhyMode(%s)", + dbg_id_str, args[0], args[1], args[2], wlan_curr_band[args[3]], wlan_phymode[args[4]]); + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_ENTER: + if (numargs >= 5 && args[0] < 23 && args[1] < 6 && args[3] < 2) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, PsPollAvg(%u), %s, CurrT(%u)", + dbg_id_str, wlan_psp_stimulus[args[0]], coex_pspoll_state[args[1]], args[2], coex_scheduler_interval[args[3]], args[4]); + } else { + return FALSE; + } + break; + //Translate following into decimal + case COEX_SINGLECHAIN_DBG_1: + case COEX_SINGLECHAIN_DBG_2: + case COEX_SINGLECHAIN_DBG_3: + case COEX_MULTICHAIN_DBG_1: + case COEX_MULTICHAIN_DBG_2: + case COEX_MULTICHAIN_DBG_3: + case BTCOEX_DBG_MCI_1: + case BTCOEX_DBG_MCI_2: + case BTCOEX_DBG_MCI_3: + case BTCOEX_DBG_MCI_4: + case BTCOEX_DBG_MCI_5: + case BTCOEX_DBG_MCI_6: + case BTCOEX_DBG_MCI_7: + case BTCOEX_DBG_MCI_8: + case BTCOEX_DBG_MCI_9: + case BTCOEX_DBG_MCI_10: + + if (numargs > 0) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %u", + dbg_id_str, args[0]); + for (i = 1; i < numargs; i++) { + printk(", %u", args[i]); + } + printk("\n"); + } else { + return FALSE; + } + break; + case COEX_LinkID: + if (numargs >= 4) { + if (args[0]) { //Add profile + dbglog_printf(timestamp, vap_id, "%s Alloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } else { //Remove profile + dbglog_printf(timestamp, vap_id, "%s Dealloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, PsPollAvg(%u), EstimationOverrun(%u), EstimationUnderun(%u), NotReadyErr(%u)", + dbg_id_str, coex_pspoll_state[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_TRF_SHAPE_PSP: + if (numargs >= 5 && args[0] < 7 && args[1] < 7) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, Dur(%u), BtTriggerRecvd(%u), PspWlanCritical(%u)", + dbg_id_str, coex_sched_type[args[0]], wlan_weight[args[1]], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_SPEC_POLL: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: PsPollSpecEna(%u), Count(%u), NextTS(%u), AllowSpecPsPollTx(%u), Intvl(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_READY_STATE: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: T2NonWlan(%u), CoexSchedulerEndTS(%u), MoreData(%u), PSPRespExpectedTS(%u), NonWlanIdleT(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_NONWLAN_INTERVAL: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: NonWlanBaseIntvl(%u), NonWlanIdleT(%u), PSPSpecIntvl(%u), ApRespTimeout(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_PSP_ERROR: + if (numargs >= 1 && args[0] < 9) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %s", + dbg_id_str, coex_psp_error_type[args[0]]); + for (i = 1; i < numargs; i++) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (", %u", args[i])); + } + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("\n")); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_1: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: ApResp0(%u), ApResp1(%u), ApResp2(%u), ApResp3(%u), ApResp4(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_2: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: DataPt(%u), Max(%u), NextApRespIndex(%u), NumOfValidDataPts(%u), PsPollAvg(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_RX_STATUS_STATE_1: + if (numargs >= 5) { + if (args[2]) { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Overrun, RsOverrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } else { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Underrun, RsUnderrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } + } else { + return FALSE; + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_beacon_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "INIT", + "ADJUST_START", + "ADJUSTING", + "ADJUST_HOLD", + }; + + static const char *events[] = { + "ADJUST_START", + "ADJUST_RESTART", + "ADJUST_STOP", + "ADJUST_PAUSE", + "ADJUST_UNPAUSE", + "ADJUST_INC_SLOP_STEP", + "ADJUST_HOLD", + "ADJUST_HOLD_TIME_OUT", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "EARLY_RX", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case BEACON_EVENT_EARLY_RX_BMISS_STATUS: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "early_rx bmiss status:rcv=%d total=%d miss=%d", + args[0], args[1], args[2]); + } + break; + case BEACON_EVENT_EARLY_RX_SLEEP_SLOP: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx cont bmiss timeout,update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx skip bcn num:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CLK_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx clk drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_AP_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx ap drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_BCN_TYPE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx bcn type:%d", + args[0]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_data_txrx_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO: + dbglog_printf(timestamp, vap_id, "DATA RX seq=0x%x, len=0x%x, stored=0x%x, duperr=0x%x", + args[0], args[1], (args[2] & 0xffff0000) >> 16, args[2] & 0x0000ffff); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_smps_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "S_INACTIVE", + "S_STATIC", + "S_DYNAMIC", + "S_STALLED", + "S_INACTIVE_WAIT", + "S_STATIC_WAIT", + "S_DYNAMIC_WAIT", + }; + + static const char *events[] = { + "E_STOP", + "E_STOP_COMPL", + "E_START", + "E_STATIC", + "E_STATIC_COMPL", + "E_DYNAMIC", + "E_DYNAMIC_COMPL", + "E_STALL", + "E_RSSI_ABOVE_THRESH", + "E_RSSI_BELOW_THRESH", + "E_FORCED_NONE", + }; + switch(dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA_SMPS SM", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case STA_SMPS_DBGID_CREATE_PDEV_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create PDEV ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START: + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP: + break; + case STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME: + dbglog_printf(timestamp, vap_id, "STA_SMPS STA %#x Signal SMPS mode as %s; cb_flags %#x", + args[0], + (args[1] == 0 ? "DISABLED": + (args[1] == 0x1 ? "STATIC" : + (args[1] == 0x3 ? "DYNAMIC" : "UNKNOWN"))), + args[2]); + break; + case STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE " + "tx_mask %#x rx_mask %#x arb_dtim_mask %#x", + args[0], args[1], args[2]); + break; + case STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE cur_pwr_state %s new_pwr_state %s", + (args[0] == 0x1 ? "SLEEP": + (args[0] == 0x2 ? "AWAKE": + (args[0] == 0x3 ? "FULL_SLEEP" : "UNKNOWN"))), + (args[1] == 0x1 ? "SLEEP": + (args[1] == 0x2 ? "AWAKE": + (args[1] == 0x3 ? "FULL_SLEEP" : "UNKNOWN")))); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP " + "tx_mask %#x rx_mask %#x orig_rx %#x dtim_rx %#x", + args[0], args[1], args[2], args[3]); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE " + "tx_mask %#x rx_mask %#x orig_rx %#x", + args[0], args[1], args[2]); + break; + default: + dbglog_printf( + timestamp, + vap_id, + "STA_SMPS: UNKNOWN DBGID!"); + return FALSE; + } + + return TRUE; +} + + +A_BOOL +dbglog_p2p_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "DOZE", + "TX_BCN", + "CTWIN", + "OPPPS", + }; + + static const char *events[] = { + "ONESHOT_NOA", + "CTWINDOW", + "PERIODIC_NOA", + "IDLE", + "NOA_CHANGED", + "TBTT", + "TX_BCN_CMP", + "OPPPS_OK", + "OPPPS_CHANGED", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "P2P GO PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_pcielp_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "STOP", + "TX", + "RX", + "SLEEP", + "SUSPEND", + }; + + static const char *events[] = { + "VDEV_UP", + "ALL_VDEV_DOWN", + "AWAKE", + "SLEEP", + "TX_ACTIVITY", + "TX_INACTIVITY", + "TX_AC_CHANGE", + "SUSPEND", + "RESUME", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "PCIELP", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + + +#ifdef WLAN_OPEN_SOURCE +static int dbglog_block_open(struct inode *inode, struct file *file) +{ + struct fwdebug *fwlog = inode->i_private; + + if (fwlog->fwlog_open) + return -EBUSY; + + fwlog->fwlog_open = TRUE; + + file->private_data = inode->i_private; + return 0; +} + +static int dbglog_block_release(struct inode *inode, struct file *file) +{ + struct fwdebug *fwlog = inode->i_private; + + fwlog->fwlog_open = FALSE; + + return 0; +} + +static ssize_t dbglog_block_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct fwdebug *fwlog = file->private_data; + struct sk_buff *skb; + ssize_t ret_cnt; + size_t len = 0, not_copied; + char *buf; + int ret; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + spin_lock_bh(&fwlog->fwlog_queue.lock); + + if (skb_queue_len(&fwlog->fwlog_queue) == 0) { + /* we must init under queue lock */ + init_completion(&fwlog->fwlog_completion); + + spin_unlock_bh(&fwlog->fwlog_queue.lock); + + ret = wait_for_completion_interruptible( + &fwlog->fwlog_completion); + if (ret == -ERESTARTSYS) { + vfree(buf); + return ret; + } + + spin_lock_bh(&fwlog->fwlog_queue.lock); + } + + while ((skb = __skb_dequeue(&fwlog->fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&fwlog->fwlog_queue, skb); + break; + } + + memcpy(buf + len, skb->data, skb->len); + len += skb->len; + + kfree_skb(skb); + } + + spin_unlock_bh(&fwlog->fwlog_queue.lock); + + /* FIXME: what to do if len == 0? */ + not_copied = copy_to_user(user_buf, buf, len); + if (not_copied != 0) { + ret_cnt = -EFAULT; + goto out; + } + + *ppos = *ppos + len; + + ret_cnt = len; + +out: + vfree(buf); + + return ret_cnt; +} + +static const struct file_operations fops_dbglog_block = { + .open = dbglog_block_open, + .release = dbglog_block_release, + .read = dbglog_block_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +int dbglog_debugfs_init(wmi_unified_t wmi_handle) +{ + + wmi_handle->debugfs_phy = debugfs_create_dir(CLD_DEBUGFS_DIR, NULL); + if (!wmi_handle->debugfs_phy) + return -ENOMEM; + + debugfs_create_file(DEBUGFS_BLOCK_NAME, S_IRUSR, wmi_handle->debugfs_phy, &wmi_handle->dbglog, + &fops_dbglog_block); + + return TRUE; +} +int dbglog_debugfs_remove(wmi_unified_t wmi_handle) +{ + debugfs_remove_recursive(wmi_handle->debugfs_phy); + return TRUE; +} +#endif /* WLAN_OPEN_SOURCE */ + +static void +cnss_diag_event_report(A_UINT16 event_Id, A_UINT16 length, void *pPayload) +{ + A_UINT8 *pBuf, *pBuf1; + event_report_t *pEvent_report; + A_UINT16 total_len; + total_len = sizeof(event_report_t) + length; + pBuf = vos_mem_malloc(total_len); + if (!pBuf){ + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: vos_mem_malloc failed \n", __func__)); + return; + } + pBuf1 = pBuf; + pEvent_report = (event_report_t*)pBuf; + pEvent_report->diag_type = DIAG_TYPE_EVENTS; + pEvent_report->event_id = event_Id; + pEvent_report->length = length; + pBuf += sizeof(event_report_t); + memcpy(pBuf, pPayload, length); + send_diag_netlink_data((A_UINT8 *) pBuf1, total_len, DIAG_TYPE_HOST_MSG); + vos_mem_free((v_VOID_t*)pBuf1); + return; + +} + +static void cnss_diag_send_driver_loaded(void) +{ + if (appstarted) { + vos_event_wlan_bringup_status_payload_type wlan_bringup_status; + /* Send Driver up command */ + strlcpy(&wlan_bringup_status.driverVersion[0], QWLAN_VERSIONSTR, + sizeof(wlan_bringup_status.driverVersion)); + wlan_bringup_status.wlanStatus = DIAG_WLAN_DRIVER_LOADED; + cnss_diag_event_report(EVENT_WLAN_BRINGUP_STATUS, + sizeof(wlan_bringup_status), &wlan_bringup_status); + senddriverstatus = FALSE; + } + else + senddriverstatus = TRUE; +} + +static void cnss_diag_send_driver_unloaded(void) +{ + vos_event_wlan_bringup_status_payload_type wlan_bringup_status; + /* Send Driver down command */ + memset(&wlan_bringup_status, 0, + sizeof(vos_event_wlan_bringup_status_payload_type)); + wlan_bringup_status.wlanStatus = DIAG_WLAN_DRIVER_UNLOADED; + cnss_diag_event_report(EVENT_WLAN_BRINGUP_STATUS, + sizeof(wlan_bringup_status), &wlan_bringup_status); +} +/**--------------------------------------------------------------------------- + \brief cnss_diag_msg_callback() - Call back invoked by netlink service + + This function gets invoked by netlink service when a message is recevied + from the cnss-diag application in user-space. + + \param - + - skb - skb with netlink message + + \return - 0 for success, non zero for failure +--------------------------------------------------------------------------*/ +int cnss_diag_msg_callback(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + struct dbglog_slot *slot; + A_UINT8 *msg; + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Netlink header null \n", __func__)); + return -1; + } + + msg = NLMSG_DATA(nlh); + + /* This check added for backward compatability */ + if (!memcmp(msg, "Hello", 5)) { + appstarted = TRUE; + cnss_diag_pid = nlh->nlmsg_pid; + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("%s: registered pid %d \n", __func__, cnss_diag_pid)); + if (senddriverstatus) + cnss_diag_send_driver_loaded(); + return 0; + } + else + slot = (struct dbglog_slot *)msg; + switch (slot->diag_type) { + case DIAG_TYPE_CRASH_INJECT: + if (slot->length == 2) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("%s : DIAG_TYPE_CRASH_INJECT: %d %d\n", __func__, + slot->payload[0], slot->payload[1])); + process_wma_set_command_twoargs(0, + (int)GEN_PARAM_CRASH_INJECT, + slot->payload[0], + slot->payload[1], GEN_CMD); + } + else + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("crash_inject cmd error\n")); + break; + default: + break; + } + return 0; + +} +/**--------------------------------------------------------------------------- + \brief cnss_diag_notify_wlan_close() - Notify APP driver closed + + This function notifies the user cnss-diag app that wlan driver is closed. + + \param - + - None + + \return - 0 for success, non zero for failure +--------------------------------------------------------------------------*/ +int cnss_diag_notify_wlan_close() +{ + /* Send nl msg about the wlan close */ + if (0 != cnss_diag_pid) + { + cnss_diag_send_driver_unloaded(); + cnss_diag_pid = 0; + } + return 0; + +} +/**--------------------------------------------------------------------------- + \brief cnss_diag_activate_service() - Activate cnss_diag message handler + + This function registers a handler to receive netlink message from + an cnss-diag application process. + + \param - + - None + + \return - 0 for success, non zero for failure +--------------------------------------------------------------------------*/ +int cnss_diag_activate_service() +{ + int ret = 0; + + /* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */ + ret = nl_srv_register(WLAN_NL_MSG_CNSS_DIAG, cnss_diag_msg_callback); + if (ret == -EINVAL) + { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("CNSS-DIAG Registeration failed \n")); + return ret; + } + kd_nl_init = TRUE; + return 0; +} + +A_BOOL +dbglog_wow_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + + switch (dbg_id) { + case WOW_NS_OFLD_ENABLE: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "Enable NS offload, for sender %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\ + :%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8*)&args[0], *((A_UINT8*)&args[0]+1), *((A_UINT8*)&args[0]+2), *((A_UINT8*)&args[0]+3), + *(A_UINT8*)&args[1], *((A_UINT8*)&args[1]+1), *((A_UINT8*)&args[1]+2), *((A_UINT8*)&args[1]+3), + *(A_UINT8*)&args[2], *((A_UINT8*)&args[2]+1), *((A_UINT8*)&args[2]+2), *((A_UINT8*)&args[2]+3), + *(A_UINT8*)&args[3], *((A_UINT8*)&args[3]+1), *((A_UINT8*)&args[3]+2), *((A_UINT8*)&args[3]+3)); + } else { + return FALSE; + } + break; + case WOW_ARP_OFLD_ENABLE: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "Enable ARP offload, for sender %d.%d.%d.%d", + *(A_UINT8*)args, *((A_UINT8*)args+1), *((A_UINT8*)args+2), *((A_UINT8*)args+3)); + } else { + return FALSE; + } + break; + case WOW_NS_ARP_OFLD_DISABLE: + if (0 == numargs) { + dbglog_printf(timestamp, vap_id, "disable NS/ARP offload"); + } else { + return FALSE; + } + break; + case WOW_NS_RECEIVED: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "NS requested from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\ + :%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8*)&args[0], *((A_UINT8*)&args[0]+1), *((A_UINT8*)&args[0]+2), *((A_UINT8*)&args[0]+3), + *(A_UINT8*)&args[1], *((A_UINT8*)&args[1]+1), *((A_UINT8*)&args[1]+2), *((A_UINT8*)&args[1]+3), + *(A_UINT8*)&args[2], *((A_UINT8*)&args[2]+1), *((A_UINT8*)&args[2]+2), *((A_UINT8*)&args[2]+3), + *(A_UINT8*)&args[3], *((A_UINT8*)&args[3]+1), *((A_UINT8*)&args[3]+2), *((A_UINT8*)&args[3]+3)); + } else { + return FALSE; + } + break; + case WOW_NS_REPLIED: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "NS replied to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\ + :%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8*)&args[0], *((A_UINT8*)&args[0]+1), *((A_UINT8*)&args[0]+2), *((A_UINT8*)&args[0]+3), + *(A_UINT8*)&args[1], *((A_UINT8*)&args[1]+1), *((A_UINT8*)&args[1]+2), *((A_UINT8*)&args[1]+3), + *(A_UINT8*)&args[2], *((A_UINT8*)&args[2]+1), *((A_UINT8*)&args[2]+2), *((A_UINT8*)&args[2]+3), + *(A_UINT8*)&args[3], *((A_UINT8*)&args[3]+1), *((A_UINT8*)&args[3]+2), *((A_UINT8*)&args[3]+3)); + } else { + return FALSE; + } + break; + case WOW_ARP_RECEIVED: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "ARP requested from %d.%d.%d.%d", + *(A_UINT8*)args, *((A_UINT8*)args+1), *((A_UINT8*)args+2), *((A_UINT8*)args+3)); + } else { + return FALSE; + } + break; + break; + case WOW_ARP_REPLIED: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "ARP replied to %d.%d.%d.%d", + *(A_UINT8*)args, *((A_UINT8*)args+1), *((A_UINT8*)args+2), *((A_UINT8*)args+3)); + } else { + return FALSE; + } + break; + default: + return FALSE; + } + + return TRUE; +} + +int dbglog_parser_type_init(wmi_unified_t wmi_handle, int type) +{ + if(type >= DBGLOG_PROCESS_MAX){ + return A_ERROR; + } + + dbglog_process_type = type; + gprint_limiter = FALSE; + + return A_OK; +} + +int +dbglog_init(wmi_unified_t wmi_handle) +{ + int res = 0; + OS_MEMSET(mod_print, 0, sizeof(mod_print)); + + dbglog_reg_modprint(WLAN_MODULE_STA_PWRSAVE, dbglog_sta_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_AP_PWRSAVE, dbglog_ap_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WAL, dbglog_wal_print_handler); + dbglog_reg_modprint(WLAN_MODULE_SCAN, dbglog_scan_print_handler); + dbglog_reg_modprint(WLAN_MODULE_RATECTRL, dbglog_ratectrl_print_handler); + dbglog_reg_modprint(WLAN_MODULE_ANI, dbglog_ani_print_handler); + dbglog_reg_modprint(WLAN_MODULE_COEX, dbglog_coex_print_handler); + dbglog_reg_modprint(WLAN_MODULE_BEACON,dbglog_beacon_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WOW, dbglog_wow_print_handler); + dbglog_reg_modprint(WLAN_MODULE_DATA_TXRX,dbglog_data_txrx_print_handler); + dbglog_reg_modprint(WLAN_MODULE_STA_SMPS, dbglog_smps_print_handler); + dbglog_reg_modprint(WLAN_MODULE_P2P, dbglog_p2p_print_handler); + dbglog_reg_modprint(WLAN_MODULE_PCIELP, dbglog_pcielp_print_handler); + dbglog_reg_modprint(WLAN_MODULE_IBSS_PWRSAVE, + dbglog_ibss_powersave_print_handler); + + /* Register handler for F3 or debug messages */ + res = wmi_unified_register_event_handler(wmi_handle, WMI_DEBUG_MESG_EVENTID, + dbglog_parse_debug_logs); + if (res != 0) + return res; + + /* Register handler for FW diag events */ + res = wmi_unified_register_event_handler(wmi_handle, + WMI_DIAG_DATA_CONTAINER_EVENTID, + fw_diag_data_event_handler); + if (res != 0) + return res; + + /* Register handler for new FW diag Event, LOG, MSG combined */ + res = wmi_unified_register_event_handler(wmi_handle, WMI_DIAG_EVENTID, + diag_fw_handler); + if (res != 0) + return res; + + cnss_diag_send_driver_loaded(); +#ifdef WLAN_OPEN_SOURCE + /* Initialize the fw debug log queue */ + skb_queue_head_init(&wmi_handle->dbglog.fwlog_queue); + init_completion(&wmi_handle->dbglog.fwlog_completion); + + /* Initialize debugfs */ + dbglog_debugfs_init(wmi_handle); +#endif /* WLAN_OPEN_SOURCE */ + + return res; +} + +int +dbglog_deinit(wmi_unified_t wmi_handle) +{ + int res = 0; + +#ifdef WLAN_OPEN_SOURCE + /* DeInitialize the fw debug log queue */ + skb_queue_purge(&wmi_handle->dbglog.fwlog_queue); + complete(&wmi_handle->dbglog.fwlog_completion); + + /* Deinitialize the debugfs */ + dbglog_debugfs_remove(wmi_handle); +#endif /* WLAN_OPEN_SOURCE */ + + res = wmi_unified_unregister_event_handler(wmi_handle, WMI_DEBUG_MESG_EVENTID); + if(res != 0) + return res; + + kd_nl_init = FALSE; + return res; +} diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac.h b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac.h new file mode 100644 index 0000000000000..7d3f3c55cb73d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_AC_H_ +#define _PKTLOG_AC_H_ +#ifndef REMOVE_PKT_LOG + +#include "ol_if_athvar.h" +#include +#include +#include "osdep.h" +#include +#include +#include + +#define NO_REG_FUNCS 4 + +/* Locking interface for pktlog */ +#define PKTLOG_LOCK_INIT(_pl_info) spin_lock_init(&(_pl_info)->log_lock) +#define PKTLOG_LOCK_DESTROY(_pl_info) +#define PKTLOG_LOCK(_pl_info) spin_lock(&(_pl_info)->log_lock) +#define PKTLOG_UNLOCK(_pl_info) spin_unlock(&(_pl_info)->log_lock) + +#define PKTLOG_MODE_SYSTEM 1 +#define PKTLOG_MODE_ADAPTER 2 + +/* Opaque softc */ +struct ol_ath_generic_softc_t; +typedef struct ol_ath_generic_softc_t* ol_ath_generic_softc_handle; +extern void pktlog_disable_adapter_logging(struct ol_softc *scn); +extern int pktlog_alloc_buf(struct ol_softc *scn); +extern void pktlog_release_buf(struct ol_softc *scn); + +struct ol_pl_arch_dep_funcs { + void (*pktlog_init) (struct ol_softc *scn); + int (*pktlog_enable) (struct ol_softc *scn, + int32_t log_state); + int (*pktlog_setsize) (struct ol_softc *scn, + int32_t log_state); + int (*pktlog_disable) (struct ol_softc *scn); +}; + +struct ol_pl_os_dep_funcs { + int (*pktlog_attach) (struct ol_softc *scn); + void (*pktlog_detach) (struct ol_softc *scn); +}; + +struct ath_pktlog_wmi_params { + WMI_PKTLOG_EVENT pktlog_event; + WMI_CMD_ID cmd_id; +}; + +extern struct ol_pl_arch_dep_funcs ol_pl_funcs; +extern struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs; + +/* Pktlog handler to save the state of the pktlogs */ +struct ol_pktlog_dev_t { + struct ol_pl_arch_dep_funcs *pl_funcs; + struct ath_pktlog_info *pl_info; + ol_ath_generic_softc_handle scn; + char *name; + bool tgt_pktlog_enabled; + osdev_t sc_osdev; +}; + +#define PKTLOG_SYSCTL_SIZE 14 + +/* + * Linux specific pktlog state information + */ +struct ath_pktlog_info_lnx { + struct ath_pktlog_info info; + struct ctl_table sysctls[PKTLOG_SYSCTL_SIZE]; + struct proc_dir_entry *proc_entry; + struct ctl_table_header *sysctl_header; +}; + +#define PL_INFO_LNX(_pl_info) ((struct ath_pktlog_info_lnx *)(_pl_info)) + +extern struct ol_pktlog_dev_t ol_pl_dev; + +/* + * WDI related data and functions + * Callback function to the WDI events + */ +void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data); + +#define ol_pktlog_attach(_scn) \ + do { \ + if (g_ol_pl_os_dep_funcs) { \ + g_ol_pl_os_dep_funcs->pktlog_attach(_scn); \ + } \ + } while (0) + +#define ol_pktlog_detach(_scn) \ + do { \ + if (g_ol_pl_os_dep_funcs) { \ + g_ol_pl_os_dep_funcs->pktlog_detach(_scn); \ + } \ + } while (0) + +#else /* REMOVE_PKT_LOG */ +#define ol_pktlog_attach(_scn) ({ (void)_scn; }) +#define ol_pktlog_detach(_scn) ({ (void)_scn; }) +#endif /* REMOVE_PKT_LOG */ +#endif /* _PKTLOG_AC_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_api.h b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_api.h new file mode 100644 index 0000000000000..a30aaab2b07b9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_api.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * The file is used to define structures that are shared between + * kernel space and user space pktlog application. + */ + +#ifndef _PKTLOG_AC_API_ +#define _PKTLOG_AC_API_ +#ifndef REMOVE_PKT_LOG + +/** + * @typedef ol_pktlog_dev_handle + * @brief opaque handle for pktlog device object + */ +struct ol_pktlog_dev_t; +typedef struct ol_pktlog_dev_t* ol_pktlog_dev_handle; + +/** + * @typedef ol_softc_handle + * @brief opaque handle for ol_softc + */ +struct ol_softc; +typedef struct ol_softc* ol_softc_handle; + +/** + * @typedef net_device_handle + * @brief opaque handle linux phy device object + */ +struct net_device; +typedef struct net_device* net_device_handle; + +void ol_pl_set_name(ol_softc_handle scn, net_device_handle dev); + +void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle, + ol_softc_handle scn); + +/* Packet log state information */ +#ifndef _PKTLOG_INFO +#define _PKTLOG_INFO +struct ath_pktlog_info { + struct ath_pktlog_buf *buf; + u_int32_t log_state; + u_int32_t saved_state; + u_int32_t options; + + /* Size of buffer in bytes */ + int32_t buf_size; + spinlock_t log_lock; + + /* Threshold of TCP SACK packets for triggered stop */ + int sack_thr; + + /* # of tail packets to log after triggered stop */ + int tail_length; + + /* throuput threshold in bytes for triggered stop */ + u_int32_t thruput_thresh; + + /* (aggregated or single) packet size in bytes */ + u_int32_t pktlen; + + /* a temporary variable for counting TX throughput only */ + /* PER threshold for triggered stop, 10 for 10%, range [1, 99] */ + u_int32_t per_thresh; + + /* Phyerr threshold for triggered stop */ + u_int32_t phyerr_thresh; + + /* time period for counting trigger parameters, in milisecond */ + u_int32_t trigger_interval; + u_int32_t start_time_thruput; + u_int32_t start_time_per; +}; +#endif /* _PKTLOG_INFO */ +#else /* REMOVE_PKT_LOG */ +typedef void* ol_pktlog_dev_handle; +#define ol_pl_sethandle(pl_handle, scn) \ + do { \ + (void)pl_handle; \ + (void)scn; \ + } while (0) + +#define ol_pl_set_name(scn, dev) \ + do { \ + (void)scn; \ + (void)dev; \ + } while (0) + +#endif /* REMOVE_PKT_LOG */ +#endif /* _PKTLOG_AC_API_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_i.h b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_i.h new file mode 100644 index 0000000000000..99ee7cdf8a899 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/include/pktlog_ac_i.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_AC_I_ +#define _PKTLOG_AC_I_ +#ifndef REMOVE_PKT_LOG + +#include +#include + +#define PKTLOG_DEFAULT_BUFSIZE (1024 * 1024) +#define PKTLOG_DEFAULT_SACK_THR 3 +#define PKTLOG_DEFAULT_TAIL_LENGTH 100 +#define PKTLOG_DEFAULT_THRUPUT_THRESH (64 * 1024) +#define PKTLOG_DEFAULT_PER_THRESH 30 +#define PKTLOG_DEFAULT_PHYERR_THRESH 300 +#define PKTLOG_DEFAULT_TRIGGER_INTERVAL 500 +struct ath_pktlog_arg { + struct ath_pktlog_info *pl_info; + u_int32_t flags; + u_int16_t missed_cnt; + u_int16_t log_type; + size_t log_size; + u_int16_t timestamp; + char *buf; +}; + +void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg); +char *pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev, + struct ath_pktlog_info *pl_info, + size_t log_size, + struct ath_pktlog_hdr *pl_hdr); + +A_STATUS process_tx_info(struct ol_txrx_pdev_t *pdev, void *data); +A_STATUS process_rx_info(void *pdev, void *data); +A_STATUS process_rx_info_remote(void *pdev, adf_nbuf_t amsdu); +A_STATUS process_rate_find(void *pdev, void *data); +A_STATUS process_rate_update(void *pdev, void *data); + +#endif /* REMOVE_PKT_LOG */ +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c new file mode 100644 index 0000000000000..7d8d7138bdeed --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef REMOVE_PKT_LOG +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif +#ifndef __KERNEL__ +#define __KERNEL__ +#endif +/* + * Linux specific implementation of Pktlogs for 802.11ac + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define PKTLOG_TAG "ATH_PKTLOG" +#define PKTLOG_DEVNAME_SIZE 32 +#define MAX_WLANDEV 1 + +#define PKTLOG_PROC_DIR "ath_pktlog" + +/* Permissions for creating proc entries */ +#define PKTLOG_PROC_PERM 0444 +#define PKTLOG_PROCSYS_DIR_PERM 0555 +#define PKTLOG_PROCSYS_PERM 0644 + +#ifndef __MOD_INC_USE_COUNT +#define PKTLOG_MOD_INC_USE_COUNT \ + if (!try_module_get(THIS_MODULE)) { \ + printk(KERN_WARNING "try_module_get failed\n"); \ + } + +#define PKTLOG_MOD_DEC_USE_COUNT module_put(THIS_MODULE) +#else +#define PKTLOG_MOD_INC_USE_COUNT MOD_INC_USE_COUNT +#define PKTLOG_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT +#endif + +static struct ath_pktlog_info *g_pktlog_info; + +static struct proc_dir_entry *g_pktlog_pde; + +static int pktlog_attach(struct ol_softc *sc); +static void pktlog_detach(struct ol_softc *sc); +static int pktlog_open(struct inode *i, struct file *f); +static int pktlog_release(struct inode *i, struct file *f); +static int pktlog_mmap(struct file *f, struct vm_area_struct *vma); +static ssize_t pktlog_read(struct file *file, char *buf, size_t nbytes, + loff_t * ppos); + +static struct file_operations pktlog_fops = { + open:pktlog_open, + release:pktlog_release, + mmap:pktlog_mmap, + read:pktlog_read, +}; + +/* + * Linux implementation of helper functions + */ + +static struct ol_pktlog_dev_t *get_pl_handle(struct ol_softc *scn) +{ + if (!scn || !scn->pdev_txrx_handle) + return NULL; + return scn->pdev_txrx_handle->pl_dev; +} + +void ol_pl_set_name(ol_softc_handle scn, net_device_handle dev) +{ + if (scn && scn->pdev_txrx_handle->pl_dev && dev) + scn->pdev_txrx_handle->pl_dev->name = dev->name; +} + +void pktlog_disable_adapter_logging(struct ol_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = get_pl_handle(scn); + if (pl_dev) pl_dev->pl_info->log_state = 0; +} + +int pktlog_alloc_buf(struct ol_softc *scn) +{ + u_int32_t page_cnt; + unsigned long vaddr; + struct page *vpg; + struct ath_pktlog_info *pl_info; + + if (!scn || !scn->pdev_txrx_handle->pl_dev) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer " + "scn or scn->pdev_txrx_handle->pl_dev is null\n", + __func__); + return -EINVAL; + } + + pl_info = scn->pdev_txrx_handle->pl_dev->pl_info; + + page_cnt = (sizeof(*(pl_info->buf)) + pl_info->buf_size) / PAGE_SIZE; + + if ((pl_info->buf = vmalloc((page_cnt + 2) * PAGE_SIZE)) == NULL) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer " + "(%d pages)\n", __func__, page_cnt); + return -ENOMEM; + } + + pl_info->buf = (struct ath_pktlog_buf *) + (((unsigned long) (pl_info->buf) + PAGE_SIZE - 1) + & PAGE_MASK); + + for (vaddr = (unsigned long) (pl_info->buf); + vaddr < ((unsigned long) (pl_info->buf) + (page_cnt * PAGE_SIZE)); + vaddr += PAGE_SIZE) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) + vpg = vmalloc_to_page((const void *) vaddr); +#else + vpg = virt_to_page(pktlog_virt_to_logical((void *) vaddr)); +#endif + SetPageReserved(vpg); + } + + return 0; +} + +void pktlog_release_buf(struct ol_softc *scn) +{ + unsigned long page_cnt; + unsigned long vaddr; + struct page *vpg; + struct ath_pktlog_info *pl_info; + + if (!scn || !scn->pdev_txrx_handle->pl_dev) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer" + "scn or scn->pdev_txrx_handle->pl_dev is null\n", + __func__); + return; + } + + pl_info = scn->pdev_txrx_handle->pl_dev->pl_info; + + page_cnt = ((sizeof(*(pl_info->buf)) + pl_info->buf_size) / + PAGE_SIZE) + 1; + + for (vaddr = (unsigned long) (pl_info->buf); + vaddr < (unsigned long) (pl_info->buf) + (page_cnt * PAGE_SIZE); + vaddr += PAGE_SIZE) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) + vpg = vmalloc_to_page((const void *) vaddr); +#else + vpg = virt_to_page(pktlog_virt_to_logical((void *) vaddr)); +#endif + ClearPageReserved(vpg); + } + + vfree(pl_info->buf); + pl_info->buf = NULL; +} + +void +pktlog_cleanup(struct ath_pktlog_info *pl_info) +{ + pl_info->log_state = 0; + PKTLOG_LOCK_DESTROY(pl_info); +} + +/* sysctl procfs handler to enable pktlog */ +static int +ATH_SYSCTL_DECL(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, + ppos) +{ + int ret, enable; + ol_ath_generic_softc_handle scn; + struct ol_pktlog_dev_t *pl_dev; + + scn = (ol_ath_generic_softc_handle) ctl->extra1; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = get_pl_handle((struct ol_softc *)scn); + + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return -ENODEV; + } + + ctl->data = &enable; + ctl->maxlen = sizeof(enable); + + if (write) { + ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret == 0) + ret = pl_dev->pl_funcs->pktlog_enable( + (struct ol_softc *)scn, + enable); + else + printk(PKTLOG_TAG "%s:proc_dointvec failed\n", + __func__); + } else { + ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret) + printk(PKTLOG_TAG "%s:proc_dointvec failed\n", + __func__); + } + + ctl->data = NULL; + ctl->maxlen = 0; + + return ret; +} + +static int get_pktlog_bufsize(struct ol_pktlog_dev_t *pl_dev) +{ + return pl_dev->pl_info->buf_size; +} + +/* sysctl procfs handler to set/get pktlog size */ +static int +ATH_SYSCTL_DECL(ath_sysctl_pktlog_size, ctl, write, filp, buffer, lenp, + ppos) +{ + int ret, size; + ol_ath_generic_softc_handle scn; + struct ol_pktlog_dev_t *pl_dev; + + scn = (ol_ath_generic_softc_handle) ctl->extra1; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = get_pl_handle((struct ol_softc *)scn); + + if (!pl_dev) { + printk("%s: Invalid pktlog handle\n", __func__); + ASSERT(0); + return -ENODEV; + } + + ctl->data = &size; + ctl->maxlen = sizeof(size); + + if (write) { + ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret == 0) + ret = pl_dev->pl_funcs->pktlog_setsize( + (struct ol_softc *)scn, + size); + } else { + size = get_pktlog_bufsize(pl_dev); + ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + } + + ctl->data = NULL; + ctl->maxlen = 0; + + return ret; +} + +/* Register sysctl table */ +static int pktlog_sysctl_register(struct ol_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = get_pl_handle(scn); + struct ath_pktlog_info_lnx *pl_info_lnx; + char *proc_name; + + if (pl_dev) { + pl_info_lnx = PL_INFO_LNX(pl_dev->pl_info); + proc_name = pl_dev->name; + } else { + pl_info_lnx = PL_INFO_LNX(g_pktlog_info); + proc_name = PKTLOG_PROC_SYSTEM; + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) +#define set_ctl_name(a, b) /* nothing */ +#else +#define set_ctl_name(a, b) pl_info_lnx->sysctls[a].ctl_name = b +#endif + + /* + * Setup the sysctl table for creating the following sysctl entries: + * /proc/sys/PKTLOG_PROC_DIR//enable for enabling/disabling + * pktlog + * /proc/sys/PKTLOG_PROC_DIR//size for changing the buffer size + */ + memset(pl_info_lnx->sysctls, 0, sizeof(pl_info_lnx->sysctls)); + set_ctl_name(0, CTL_AUTO); + pl_info_lnx->sysctls[0].procname = PKTLOG_PROC_DIR; + pl_info_lnx->sysctls[0].mode = PKTLOG_PROCSYS_DIR_PERM; + pl_info_lnx->sysctls[0].child = &pl_info_lnx->sysctls[2]; + /* [1] is NULL terminator */ + set_ctl_name(2, CTL_AUTO); + pl_info_lnx->sysctls[2].procname = proc_name; + pl_info_lnx->sysctls[2].mode = PKTLOG_PROCSYS_DIR_PERM; + pl_info_lnx->sysctls[2].child = &pl_info_lnx->sysctls[4]; + /* [3] is NULL terminator */ + set_ctl_name(4, CTL_AUTO); + pl_info_lnx->sysctls[4].procname = "enable"; + pl_info_lnx->sysctls[4].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[4].proc_handler = ath_sysctl_pktlog_enable; + pl_info_lnx->sysctls[4].extra1 = scn; + + set_ctl_name(5, CTL_AUTO); + pl_info_lnx->sysctls[5].procname = "size"; + pl_info_lnx->sysctls[5].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[5].proc_handler = ath_sysctl_pktlog_size; + pl_info_lnx->sysctls[5].extra1 = scn; + + set_ctl_name(6, CTL_AUTO); + pl_info_lnx->sysctls[6].procname = "options"; + pl_info_lnx->sysctls[6].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[6].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[6].data = &pl_info_lnx->info.options; + pl_info_lnx->sysctls[6].maxlen = sizeof(pl_info_lnx->info.options); + + set_ctl_name(7, CTL_AUTO); + pl_info_lnx->sysctls[7].procname = "sack_thr"; + pl_info_lnx->sysctls[7].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[7].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[7].data = &pl_info_lnx->info.sack_thr; + pl_info_lnx->sysctls[7].maxlen = sizeof(pl_info_lnx->info.sack_thr); + + set_ctl_name(8, CTL_AUTO); + pl_info_lnx->sysctls[8].procname = "tail_length"; + pl_info_lnx->sysctls[8].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[8].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[8].data = &pl_info_lnx->info.tail_length; + pl_info_lnx->sysctls[8].maxlen = sizeof(pl_info_lnx->info.tail_length); + + set_ctl_name(9, CTL_AUTO); + pl_info_lnx->sysctls[9].procname = "thruput_thresh"; + pl_info_lnx->sysctls[9].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[9].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[9].data = &pl_info_lnx->info.thruput_thresh; + pl_info_lnx->sysctls[9].maxlen = + sizeof(pl_info_lnx->info.thruput_thresh); + + set_ctl_name(10, CTL_AUTO); + pl_info_lnx->sysctls[10].procname = "phyerr_thresh"; + pl_info_lnx->sysctls[10].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[10].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[10].data = &pl_info_lnx->info.phyerr_thresh; + pl_info_lnx->sysctls[10].maxlen = + sizeof(pl_info_lnx->info.phyerr_thresh); + + set_ctl_name(11, CTL_AUTO); + pl_info_lnx->sysctls[11].procname = "per_thresh"; + pl_info_lnx->sysctls[11].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[11].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[11].data = &pl_info_lnx->info.per_thresh; + pl_info_lnx->sysctls[11].maxlen = sizeof(pl_info_lnx->info.per_thresh); + + set_ctl_name(12, CTL_AUTO); + pl_info_lnx->sysctls[12].procname = "trigger_interval"; + pl_info_lnx->sysctls[12].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[12].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[12].data = &pl_info_lnx->info.trigger_interval; + pl_info_lnx->sysctls[12].maxlen = + sizeof(pl_info_lnx->info.trigger_interval); + /* [13] is NULL terminator */ + + /* and register everything */ + /* register_sysctl_table changed from 2.6.21 onwards */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) + pl_info_lnx->sysctl_header = + register_sysctl_table(pl_info_lnx->sysctls); +#else + pl_info_lnx->sysctl_header = + register_sysctl_table(pl_info_lnx->sysctls, 1); +#endif + if (!pl_info_lnx->sysctl_header) { + printk("%s: failed to register sysctls!\n", proc_name); + return -1; + } + + return 0; +} + +/* + * Initialize logging for system or adapter + * Parameter scn should be NULL for system wide logging + */ +static int pktlog_attach(struct ol_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info_lnx *pl_info_lnx; + char *proc_name; + struct proc_dir_entry *proc_entry; + + pl_dev = get_pl_handle(scn); + + if (pl_dev != NULL) { + pl_info_lnx = kmalloc(sizeof(*pl_info_lnx), GFP_KERNEL); + if (pl_info_lnx == NULL) { + printk(PKTLOG_TAG "%s:allocation failed for pl_info\n", + __func__); + return -ENOMEM; + } + pl_dev->pl_info = &pl_info_lnx->info; + pl_dev->name = WLANDEV_BASENAME; + proc_name = pl_dev->name; + if (!pl_dev->pl_funcs) + pl_dev->pl_funcs = &ol_pl_funcs; + + /* + * Valid for both direct attach and offload architecture + */ + pl_dev->pl_funcs->pktlog_init(scn); + } + else { + return -1; + } + + /* + * initialize log info + * might be good to move to pktlog_init + */ + /* pl_dev->tgt_pktlog_enabled = false; */ + pl_info_lnx->proc_entry = NULL; + pl_info_lnx->sysctl_header = NULL; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + proc_entry = proc_create_data(proc_name, PKTLOG_PROC_PERM, + g_pktlog_pde, &pktlog_fops, + &pl_info_lnx->info); + + if (proc_entry == NULL) { + printk(PKTLOG_TAG "%s: create_proc_entry failed for %s\n", + __func__, proc_name); + goto attach_fail1; + } +#else + proc_entry = create_proc_entry(proc_name, PKTLOG_PROC_PERM, + g_pktlog_pde); + + if (proc_entry == NULL) { + printk(PKTLOG_TAG "%s: create_proc_entry failed for %s\n", + __func__, proc_name); + goto attach_fail1; + } + + proc_entry->data = &pl_info_lnx->info; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) + proc_entry->owner = THIS_MODULE; +#endif + proc_entry->proc_fops = &pktlog_fops; +#endif + + pl_info_lnx->proc_entry = proc_entry; + + if (pktlog_sysctl_register(scn)) { + printk(PKTLOG_TAG "%s: sysctl register failed for %s\n", + __func__, proc_name); + goto attach_fail2; + } + return 0; + +attach_fail2: + remove_proc_entry(proc_name, g_pktlog_pde); + +attach_fail1: + if (pl_dev) + kfree(pl_dev->pl_info); + return -1; +} + +static void pktlog_sysctl_unregister(struct ol_pktlog_dev_t *pl_dev) +{ + struct ath_pktlog_info_lnx *pl_info_lnx; + + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return; + } + + pl_info_lnx = (pl_dev) ? PL_INFO_LNX(pl_dev->pl_info) : + PL_INFO_LNX(g_pktlog_info); + + if (pl_info_lnx->sysctl_header) { + unregister_sysctl_table(pl_info_lnx->sysctl_header); + pl_info_lnx->sysctl_header = NULL; + } +} + +static void pktlog_detach(struct ol_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = (struct ol_pktlog_dev_t *) + get_pl_handle(scn); + struct ath_pktlog_info *pl_info; + + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return; + } + + pl_info = pl_dev->pl_info; + remove_proc_entry(WLANDEV_BASENAME, g_pktlog_pde); + pktlog_sysctl_unregister(pl_dev); + pktlog_cleanup(pl_info); + + if (pl_info->buf) + pktlog_release_buf(scn); + + if (pl_dev) { + kfree(pl_info); + pl_dev->pl_info = NULL; + } +} + +static int pktlog_open(struct inode *i, struct file *f) +{ + PKTLOG_MOD_INC_USE_COUNT; + return 0; +} + +static int pktlog_release(struct inode *i, struct file *f) +{ + PKTLOG_MOD_DEC_USE_COUNT; + return 0; +} + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +static ssize_t +pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) +{ + size_t bufhdr_size; + size_t count = 0, ret_val = 0; + int rem_len; + int start_offset, end_offset; + int fold_offset, ppos_data, cur_rd_offset; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *) + PDE_DATA(file->f_dentry->d_inode); +#else + struct proc_dir_entry *proc_entry = PDE(file->f_dentry->d_inode); + struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *) + proc_entry->data; +#endif + struct ath_pktlog_buf *log_buf = pl_info->buf; + + if (log_buf == NULL) + return 0; + + if (*ppos == 0 && pl_info->log_state) { + pl_info->saved_state = pl_info->log_state; + pl_info->log_state = 0; + } + + bufhdr_size = sizeof(log_buf->bufhdr); + + /* copy valid log entries from circular buffer into user space */ + rem_len = nbytes; + count = 0; + + if (*ppos < bufhdr_size) { + count = MIN((bufhdr_size - *ppos), rem_len); + if (copy_to_user(buf, ((char *)&log_buf->bufhdr) + *ppos, + count)) + return -EFAULT; + rem_len -= count; + ret_val += count; + } + + start_offset = log_buf->rd_offset; + + if ((rem_len == 0) || (start_offset < 0)) + goto rd_done; + + fold_offset = -1; + cur_rd_offset = start_offset; + + /* Find the last offset and fold-offset if the buffer is folded */ + do { + struct ath_pktlog_hdr *log_hdr; + int log_data_offset; + + log_hdr = (struct ath_pktlog_hdr *) (log_buf->log_data + + cur_rd_offset); + + log_data_offset = cur_rd_offset + sizeof(struct ath_pktlog_hdr); + + if ((fold_offset == -1) + && ((pl_info->buf_size - log_data_offset) + <= log_hdr->size)) + fold_offset = log_data_offset - 1; + + PKTLOG_MOV_RD_IDX(cur_rd_offset, log_buf, pl_info->buf_size); + + if ((fold_offset == -1) && (cur_rd_offset == 0) + && (cur_rd_offset != log_buf->wr_offset)) + fold_offset = log_data_offset + log_hdr->size - 1; + + end_offset = log_data_offset + log_hdr->size - 1; + } while (cur_rd_offset != log_buf->wr_offset); + + ppos_data = *ppos + ret_val - bufhdr_size + start_offset; + + if (fold_offset == -1) { + if (ppos_data > end_offset) + goto rd_done; + + count = MIN(rem_len, (end_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, + count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } else { + if (ppos_data <= fold_offset) { + count = MIN(rem_len, (fold_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, + count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } + + if (rem_len == 0) + goto rd_done; + + ppos_data = + *ppos + ret_val - (bufhdr_size + + (fold_offset - start_offset + 1)); + + if (ppos_data <= end_offset) { + count = MIN(rem_len, (end_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, + count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } + } + +rd_done: + if ((ret_val < nbytes) && pl_info->saved_state) { + pl_info->log_state = pl_info->saved_state; + pl_info->saved_state = 0; + } + *ppos += ret_val; + + return ret_val; +} + +#ifndef VMALLOC_VMADDR +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) +/* Convert a kernel virtual address to a kernel logical address */ +static volatile void *pktlog_virt_to_logical(volatile void *addr) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) || \ + (defined(__i386__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11))) + pud_t *pud; +#endif + unsigned long vaddr, ret = 0UL; + + vaddr = VMALLOC_VMADDR((unsigned long) addr); + + pgd = pgd_offset_k(vaddr); + + if (!pgd_none(*pgd)) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) || \ + (defined(__i386__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11))) + pud = pud_offset(pgd, vaddr); + pmd = pmd_offset(pud, vaddr); +#else + pmd = pmd_offset(pgd, vaddr); +#endif + + if (!pmd_none(*pmd)) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ptep = pte_offset_map(pmd, vaddr); +#else + ptep = pte_offset(pmd, vaddr); +#endif + pte = *ptep; + + if (pte_present(pte)) { + ret = (unsigned long) + page_address(pte_page(pte)); + ret |= (vaddr & (PAGE_SIZE - 1)); + } + } + } + return (volatile void *)ret; +} +#endif + +/* vma operations for mapping vmalloced area to user space */ +static void pktlog_vopen(struct vm_area_struct *vma) +{ + PKTLOG_MOD_INC_USE_COUNT; +} + +static void pktlog_vclose(struct vm_area_struct *vma) +{ + PKTLOG_MOD_DEC_USE_COUNT; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) +int pktlog_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + unsigned long address = (unsigned long)vmf->virtual_address; + + if (address == 0UL) + return VM_FAULT_NOPAGE; + + if (vmf->pgoff > vma->vm_end) + return VM_FAULT_SIGBUS; + + get_page(virt_to_page((void *)address)); + vmf->page = virt_to_page((void *)address); + return VM_FAULT_MINOR; +} +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +struct page *pktlog_vmmap(struct vm_area_struct *vma, unsigned long addr, + int *type) +#else +struct page *pktlog_vmmap(struct vm_area_struct *vma, unsigned long addr, + int write_access) +#endif +{ + unsigned long offset, vaddr; + struct proc_dir_entry *proc_entry; + struct ath_pktlog_info *pl_info = + + proc_entry = PDE(vma->vm_file->f_dentry->d_inode); + pl_info = (struct ath_pktlog_info *)proc_entry->data; + + offset = addr - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT); + vaddr = (unsigned long) pktlog_virt_to_logical( + (void *)(pl_info->buf) + offset); + + if (vaddr == 0UL) { + printk(PKTLOG_TAG "%s: page fault out of range\n", __func__); + return ((struct page *) 0UL); + } + + /* increment the usage count of the page */ + get_page(virt_to_page((void*)vaddr)); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (type) + *type = VM_FAULT_MINOR; +#endif + + return virt_to_page((void *)vaddr); +} +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) */ + +static struct vm_operations_struct pktlog_vmops = { + open:pktlog_vopen, + close:pktlog_vclose, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) + fault:pktlog_fault, +#else + nopage:pktlog_vmmap, +#endif +}; + +static int pktlog_mmap(struct file *file, struct vm_area_struct *vma) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *) + PDE_DATA(file->f_dentry->d_inode); +#else + struct proc_dir_entry *proc_entry = PDE(file->f_dentry->d_inode); + struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *) + proc_entry->data; +#endif + + if (vma->vm_pgoff != 0) { + /* Entire buffer should be mapped */ + return -EINVAL; + } + + if (!pl_info->buf) { + printk(PKTLOG_TAG "%s: Log buffer unavailable\n", __func__); + return -ENOMEM; + } + + vma->vm_flags |= VM_LOCKED; + vma->vm_ops = &pktlog_vmops; + pktlog_vopen(vma); + return 0; +} + +int pktlogmod_init(void *context) +{ + int ret; + + /* create the proc directory entry */ + g_pktlog_pde = proc_mkdir(PKTLOG_PROC_DIR, NULL); + + if (g_pktlog_pde == NULL) { + printk(PKTLOG_TAG "%s: proc_mkdir failed\n", __func__); + return -1; + } + + /* Attach packet log */ + if ((ret = pktlog_attach((struct ol_softc *)context))) + goto attach_fail; + + return ret; + +attach_fail: + remove_proc_entry(PKTLOG_PROC_DIR, NULL); + g_pktlog_pde = NULL; + return ret; +} + +void pktlogmod_exit(void *context) +{ + struct ol_softc *scn = (struct ol_softc *)context; + struct ol_pktlog_dev_t *pl_dev = get_pl_handle(scn); + + if (!pl_dev || g_pktlog_pde == NULL) + return; + + /* + * Disable firmware side pktlog function + */ + if (pl_dev->tgt_pktlog_enabled) { + if (pl_dev->pl_funcs->pktlog_enable(scn, 0)) { + printk("%s: cannot disable pktlog in the target\n", + __func__); + } + } + + pktlog_detach(scn); + /* + * pdev kill needs to be implemented + */ + remove_proc_entry(PKTLOG_PROC_DIR, NULL); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c new file mode 100644 index 0000000000000..1bd434e7ffbad --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef REMOVE_PKT_LOG +#include "adf_os_mem.h" +#include "athdefs.h" +#include "pktlog_ac_i.h" +#include "vos_api.h" +#include "wlan_qct_wda.h" + +void pktlog_init(struct ol_softc *scn); +int pktlog_enable(struct ol_softc *scn, int32_t log_state); +int pktlog_setsize(struct ol_softc *scn, int32_t log_state); +int pktlog_disable(struct ol_softc *scn); + +wdi_event_subscribe PKTLOG_TX_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RX_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RX_REMOTE_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RCFIND_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER; + +struct ol_pl_arch_dep_funcs ol_pl_funcs = { + .pktlog_init = pktlog_init, + .pktlog_enable = pktlog_enable, + .pktlog_setsize = pktlog_setsize, + .pktlog_disable = pktlog_disable, /* valid for f/w disable */ +}; + +struct ol_pktlog_dev_t ol_pl_dev = { + .pl_funcs = &ol_pl_funcs, +}; + +void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle, + struct ol_softc *scn) +{ + ol_pl_dev.scn = (ol_ath_generic_softc_handle)scn; + *pl_handle = &ol_pl_dev; +} + +static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types, + WMI_CMD_ID cmd_id) +{ + vos_msg_t msg = {0}; + VOS_STATUS status; + struct ath_pktlog_wmi_params *param; + + param = vos_mem_malloc(sizeof(struct ath_pktlog_wmi_params)); + + if (!param) + return A_NO_MEMORY; + + param->cmd_id = cmd_id; + param->pktlog_event = event_types; + + msg.type = WDA_PKTLOG_ENABLE_REQ; + msg.bodyptr = param; + msg.bodyval = 0; + + status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg); + + if (status != VOS_STATUS_SUCCESS) { + vos_mem_free(param); + return A_ERROR; + } + + return A_OK; +} + +static inline A_STATUS +pktlog_enable_tgt(struct ol_softc *_scn, uint32_t log_state) +{ + uint32_t types = 0; + + if (log_state & ATH_PKTLOG_TX) + types |= WMI_PKTLOG_EVENT_TX; + + if (log_state & ATH_PKTLOG_RX) + types |= WMI_PKTLOG_EVENT_RX; + + if (log_state & ATH_PKTLOG_RCFIND) + types |= WMI_PKTLOG_EVENT_RCF; + + if (log_state & ATH_PKTLOG_RCUPDATE) + types |= WMI_PKTLOG_EVENT_RCU; + + return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID); +} + +static inline A_STATUS +wdi_pktlog_subscribe(struct ol_txrx_pdev_t *txrx_pdev, int32_t log_state) +{ + if (!txrx_pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (log_state & ATH_PKTLOG_TX) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_TX_SUBSCRIBER, + WDI_EVENT_TX_STATUS)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RX) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RX_SUBSCRIBER, + WDI_EVENT_RX_DESC)) { + return A_ERROR; + } + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCFIND) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCUPDATE) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { + return A_ERROR; + } + } + return A_OK; +} + +void +pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data) +{ + switch (event) { + case WDI_EVENT_TX_STATUS: + { + /* + * process TX message + */ + if (process_tx_info(pdev, log_data)) { + printk("Unable to process TX info\n"); + return; + } + break; + } + case WDI_EVENT_RX_DESC: + { + /* + * process RX message for local frames + */ + if (process_rx_info(pdev, log_data)) { + printk("Unable to process RX info\n"); + return; + } + break; + } + case WDI_EVENT_RX_DESC_REMOTE: + { + /* + * process RX message for remote frames + */ + if (process_rx_info_remote(pdev, log_data)) { + printk("Unable to process RX info\n"); + return; + } + break; + } + case WDI_EVENT_RATE_FIND: + { + /* + * process RATE_FIND message + */ + if (process_rate_find(pdev, log_data)) { + printk("Unable to process RC_FIND info\n"); + return; + } + break; + } + case WDI_EVENT_RATE_UPDATE: + { + /* + * process RATE_UPDATE message + */ + if (process_rate_update(pdev, log_data)) { + printk("Unable to process RC_UPDATE\n"); + return; + } + break; + } + default: + break; + } +} + +static inline A_STATUS +wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state) +{ + if (log_state & ATH_PKTLOG_TX) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_TX_SUBSCRIBER, + WDI_EVENT_TX_STATUS)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RX) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RX_SUBSCRIBER, + WDI_EVENT_RX_DESC)) { + return A_ERROR; + } + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCFIND) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCUPDATE) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { + return A_ERROR; + } + } + return A_OK; +} + +int +pktlog_disable(struct ol_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = scn->pdev_txrx_handle->pl_dev; + struct ath_pktlog_info *pl_info = pl_dev->pl_info; + struct ol_txrx_pdev_t *txrx_pdev = scn->pdev_txrx_handle; + + if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID)) { + printk("Failed to disable pktlog in target\n"); + return -1; + } + + if (wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) { + printk("Cannot unsubscribe pktlog from the WDI\n"); + return -1; + } + + return 0; +} + +void +pktlog_init(struct ol_softc *scn) +{ + struct ath_pktlog_info *pl_info; + + pl_info = scn->pdev_txrx_handle->pl_dev->pl_info; + + OS_MEMZERO(pl_info, sizeof(*pl_info)); + PKTLOG_LOCK_INIT(pl_info); + + pl_info->buf_size = PKTLOG_DEFAULT_BUFSIZE; + pl_info->buf = NULL; + pl_info->log_state = 0; + pl_info->sack_thr = PKTLOG_DEFAULT_SACK_THR; + pl_info->tail_length = PKTLOG_DEFAULT_TAIL_LENGTH; + pl_info->thruput_thresh = PKTLOG_DEFAULT_THRUPUT_THRESH; + pl_info->per_thresh = PKTLOG_DEFAULT_PER_THRESH; + pl_info->phyerr_thresh = PKTLOG_DEFAULT_PHYERR_THRESH; + pl_info->trigger_interval = PKTLOG_DEFAULT_TRIGGER_INTERVAL; + pl_info->pktlen = 0; + pl_info->start_time_thruput = 0; + pl_info->start_time_per = 0; + + PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RX_REMOTE_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RCFIND_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RCUPDATE_SUBSCRIBER.callback = pktlog_callback; +} + +int +pktlog_enable(struct ol_softc *scn, int32_t log_state) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct ol_txrx_pdev_t *txrx_pdev; + int error; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -1; + } + + txrx_pdev = scn->pdev_txrx_handle; + if (!txrx_pdev) { + printk("%s: Invalid txrx_pdev context\n", __func__); + ASSERT(0); + return -1; + } + + pl_dev = scn->pdev_txrx_handle->pl_dev; + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return -1; + } + + pl_info = pl_dev->pl_info; + pl_dev->sc_osdev = scn->sc_osdev; + + if (!pl_info) + return 0; + + if (log_state != 0 && !pl_dev->tgt_pktlog_enabled) { + if (pl_info->buf == NULL) { + error = pktlog_alloc_buf(scn); + + if (error != 0) + return error; + + if (!pl_info->buf) { + printk("%s: pktlog buf alloc failed\n", __func__); + ASSERT(0); + return -1; + } + } + + pl_info->buf->bufhdr.version = CUR_PKTLOG_VER; + pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM; + pl_info->buf->wr_offset = 0; + pl_info->buf->rd_offset = -1; + + pl_info->start_time_thruput = OS_GET_TIMESTAMP(); + pl_info->start_time_per = pl_info->start_time_thruput; + + /* WDI subscribe */ + if (wdi_pktlog_subscribe(txrx_pdev, log_state)) { + printk("Unable to subscribe to the WDI %s\n", + __func__); + return -1; + } + /* WMI command to enable pktlog on the firmware */ + if (pktlog_enable_tgt(scn, log_state)) { + printk("Device cannot be enabled, %s\n", __func__); + return -1; + } else { + pl_dev->tgt_pktlog_enabled = true; + } + } else if (!log_state && pl_dev->tgt_pktlog_enabled) { + pl_dev->pl_funcs->pktlog_disable(scn); + pl_dev->tgt_pktlog_enabled = false; + if (wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) { + printk("Cannot unsubscribe pktlog from the WDI\n"); + return -1; + } + } + + pl_info->log_state = log_state; + return 0; +} + +int +pktlog_setsize(struct ol_softc *scn, int32_t size) +{ + struct ol_pktlog_dev_t *pl_dev = scn->pdev_txrx_handle->pl_dev; + struct ath_pktlog_info *pl_info = pl_dev->pl_info; + + if (size < 0) + return -EINVAL; + + if (size == pl_info->buf_size) + return 0; + + if (pl_info->log_state) { + printk("Logging should be disabled before changing bufer size\n"); + return -EINVAL; + } + + if (pl_info->buf != NULL) + pktlog_release_buf(scn); + + if (size != 0) + pl_info->buf_size = size; + + return 0; +} +#endif /* REMOVE_PKT_LOG */ diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c new file mode 100644 index 0000000000000..bc6248de8acaf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_internal.c @@ -0,0 +1,592 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef REMOVE_PKT_LOG +#include "ol_txrx_types.h" +#include "ol_htt_tx_api.h" +#include "ol_tx_desc.h" +#include "adf_os_mem.h" +#include "htt.h" +#include "htt_internal.h" +#include "pktlog_ac_i.h" +#include "wma_api.h" + +#define TX_DESC_ID_LOW_MASK 0xffff +#define TX_DESC_ID_LOW_SHIFT 0 +#define TX_DESC_ID_HIGH_MASK 0xffff0000 +#define TX_DESC_ID_HIGH_SHIFT 16 + +void +pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg) +{ + struct ath_pktlog_buf *log_buf; + int32_t buf_size; + struct ath_pktlog_hdr *log_hdr; + int32_t cur_wr_offset; + char *log_ptr; + struct ath_pktlog_info *pl_info; + u_int16_t log_type; + size_t log_size; + uint32_t flags; + + if (!plarg) { + printk("Invalid parg in %s\n", __func__); + return; + } + + pl_info = plarg->pl_info; + log_type = plarg->log_type; + log_size = plarg->log_size; + log_buf = pl_info->buf; + flags = plarg->flags; + + if (!log_buf) { + printk("Invalid log_buf in %s\n", __func__); + return; + } + buf_size = pl_info->buf_size; + cur_wr_offset = log_buf->wr_offset; + /* Move read offset to the next entry if there is a buffer overlap */ + if (log_buf->rd_offset >= 0) { + if ((cur_wr_offset <= log_buf->rd_offset) + && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) > + log_buf->rd_offset) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, + buf_size); + } + } else { + log_buf->rd_offset = cur_wr_offset; + } + + log_hdr = (struct ath_pktlog_hdr *) (log_buf->log_data + cur_wr_offset); + log_hdr->log_type = log_type; + log_hdr->flags = flags; + log_hdr->size = (u_int16_t)log_size; + log_hdr->missed_cnt = plarg->missed_cnt; + log_hdr->timestamp = plarg->timestamp; + + cur_wr_offset += sizeof(*log_hdr); + + if ((buf_size - cur_wr_offset) < log_size) { + while ((cur_wr_offset <= log_buf->rd_offset) + && (log_buf->rd_offset < buf_size)) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, + buf_size); + } + cur_wr_offset = 0; + } + + while ((cur_wr_offset <= log_buf->rd_offset) + && (cur_wr_offset + log_size) > log_buf->rd_offset) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, + buf_size); + } + + log_ptr = &(log_buf->log_data[cur_wr_offset]); + cur_wr_offset += log_hdr->size; + + log_buf->wr_offset = ((buf_size - cur_wr_offset) >= + sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset : 0; + + plarg->buf = log_ptr; +} + +char * +pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev, + struct ath_pktlog_info *pl_info, + size_t log_size, + struct ath_pktlog_hdr *pl_hdr) +{ + struct ath_pktlog_arg plarg = {0,}; + uint8_t flags = 0; + + plarg.pl_info = pl_info; + plarg.log_type = pl_hdr->log_type; + plarg.log_size = log_size; + plarg.flags = pl_hdr->flags; + plarg.missed_cnt = pl_hdr->missed_cnt; + plarg.timestamp = pl_hdr->timestamp; + + if (flags & PHFLAGS_INTERRUPT_CONTEXT) { + /* + * We are already in interupt context, no need to make it + * intsafe. call the function directly. + */ + pktlog_getbuf_intsafe(&plarg); + } else { + PKTLOG_LOCK(pl_info); + pktlog_getbuf_intsafe(&plarg); + PKTLOG_UNLOCK(pl_info); + } + + return plarg.buf; +} + +static struct txctl_frm_hdr frm_hdr; + +static void process_ieee_hdr(void *data) +{ + uint8_t dir; + struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); + + frm_hdr.framectrl = *(u_int16_t *)(wh->i_fc); + frm_hdr.seqctrl = *(u_int16_t *)(wh->i_seq); + dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); + + if (dir == IEEE80211_FC1_DIR_TODS) { + frm_hdr.bssid_tail = (wh->i_addr1[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr1[IEEE80211_ADDR_LEN-1]); + frm_hdr.sa_tail = (wh->i_addr2[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr2[IEEE80211_ADDR_LEN-1]); + frm_hdr.da_tail = (wh->i_addr3[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr3[IEEE80211_ADDR_LEN-1]); + } else if (dir == IEEE80211_FC1_DIR_FROMDS) { + frm_hdr.bssid_tail = (wh->i_addr2[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr2[IEEE80211_ADDR_LEN-1]); + frm_hdr.sa_tail = (wh->i_addr3[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr3[IEEE80211_ADDR_LEN-1]); + frm_hdr.da_tail = (wh->i_addr1[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr1[IEEE80211_ADDR_LEN-1]); + } else { + frm_hdr.bssid_tail = (wh->i_addr3[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr3[IEEE80211_ADDR_LEN-1]); + frm_hdr.sa_tail = (wh->i_addr2[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr2[IEEE80211_ADDR_LEN-1]); + frm_hdr.da_tail = (wh->i_addr1[IEEE80211_ADDR_LEN-2] << 8) | + (wh->i_addr1[IEEE80211_ADDR_LEN-1]); + } +} + +A_STATUS +process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, + void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + + if (!txrx_pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + adf_os_assert(txrx_pdev->pl_dev); + adf_os_assert(data); + pl_dev = txrx_pdev->pl_dev; + + pl_tgt_hdr = (uint32_t *)data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> + ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pl_info = pl_dev->pl_info; + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { + /* Valid only for the TX CTL */ + process_ieee_hdr(data + sizeof(pl_hdr)); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { + A_UINT32 desc_id = (A_UINT32) + *((A_UINT32 *)(data + sizeof(pl_hdr))); + A_UINT32 vdev_id = desc_id; + + /* if the pkt log msg is for the bcn frame the vdev id + * is piggybacked in desc_id and the MSB of the desc ID + * would be set to FF + */ +#define BCN_DESC_ID 0xFF + if ((desc_id >> 24) == BCN_DESC_ID) { + void *data; + A_UINT32 buf_size; + + vdev_id &= 0x00FFFFFF; + data = wma_get_beacon_buffer_by_vdev_id(vdev_id, + &buf_size); + if (data) { + process_ieee_hdr(data); + adf_os_mem_free(data); + } + } else { + /* + * TODO: get the hdr content for mgmt frames from + * Tx mgmt desc pool + */ + } + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + struct ath_pktlog_txctl txctl_log; + size_t log_size = sizeof(txctl_log.priv); + + txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, + pl_info, + log_size, + &pl_hdr); + + if (!txctl_log.txdesc_hdr_ctl) { + printk("failed to get buf for txctl_log.txdesc_hdr_ctl\n"); + return A_ERROR; + } + + /* + * frm hdr is currently Valid only for local frames + * Add capability to include the fmr hdr for remote frames + */ + txctl_log.priv.frm_hdr = frm_hdr; + adf_os_assert(txctl_log.priv.txdesc_ctl); + adf_os_mem_copy((void *)&txctl_log.priv.txdesc_ctl, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + adf_os_assert(txctl_log.txdesc_hdr_ctl); + adf_os_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, + sizeof(txctl_log.priv)); + /* Add Protocol information and HT specific information */ + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); + adf_os_assert(txstat_log.ds_status); + adf_os_mem_copy(txstat_log.ds_status, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { + struct ath_pktlog_msdu_info pl_msdu_info; + uint32_t i; + uint32_t *htt_tx_desc; + size_t log_size; + struct ol_tx_desc_t *tx_desc; + uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; + uint16_t tx_desc_id; + uint32_t *msdu_id_info = (uint32_t *) + ((void *)data + + sizeof(struct ath_pktlog_hdr)); + uint32_t *msdu_id = (uint32_t *)((char *)msdu_id_info + + msdu_id_offset); + u_int8_t *addr, *vap_addr; + u_int8_t vdev_id; + adf_nbuf_t netbuf; + u_int32_t len; + + adf_os_mem_set(&pl_msdu_info, 0, sizeof(pl_msdu_info)); + + pl_msdu_info.num_msdu = *msdu_id_info; + pl_msdu_info.priv_size = sizeof(uint32_t) * + pl_msdu_info.num_msdu + + sizeof(uint32_t); + log_size = sizeof(pl_msdu_info.priv); + + for (i = 0; i < pl_msdu_info.num_msdu; i++) { + /* + * Handle big endianess + * Increment msdu_id once after retrieving + * lower 16 bits and uppper 16 bits + */ + if (!(i % 2)) { + tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) + >> TX_DESC_ID_LOW_SHIFT); + } else { + tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) + >> TX_DESC_ID_HIGH_SHIFT); + msdu_id += 1; + } + tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); + adf_os_assert(tx_desc); + netbuf = tx_desc->netbuf; + htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc; + adf_os_assert(htt_tx_desc); + + adf_nbuf_peek_header(netbuf, &addr, &len); + + if (len < (2 * IEEE80211_ADDR_LEN)) { + adf_os_print("TX frame does not have a valid" \ + " address\n"); + return -1; + } + /* Adding header information for the TX data frames */ + vdev_id = (u_int8_t)(*(htt_tx_desc + + HTT_TX_VDEV_ID_WORD) >> + HTT_TX_VDEV_ID_SHIFT) & + HTT_TX_VDEV_ID_MASK; + + vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); + + frm_hdr.da_tail = (addr[IEEE80211_ADDR_LEN-2] << 8) | + (addr[IEEE80211_ADDR_LEN-1]); + frm_hdr.sa_tail = + (addr[2 * IEEE80211_ADDR_LEN-2] << 8) | + (addr[2 * IEEE80211_ADDR_LEN-1]); + if (vap_addr) { + frm_hdr.bssid_tail = + (vap_addr[IEEE80211_ADDR_LEN-2] << 8) | + (vap_addr[IEEE80211_ADDR_LEN-1]); + } else { + frm_hdr.bssid_tail = 0x0000; + } + pl_msdu_info.priv.msdu_len[i] = *(htt_tx_desc + + HTT_TX_MSDU_LEN_DWORD) + & HTT_TX_MSDU_LEN_MASK; + /* + * Add more information per MSDU + * e.g., protocol information + */ + } + pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + adf_os_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + sizeof(pl_msdu_info.priv.msdu_id_info)); + adf_os_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, + sizeof(pl_msdu_info.priv)); + } + return A_OK; +} + +A_STATUS +process_rx_info_remote(void *pdev, adf_nbuf_t amsdu) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct htt_host_rx_desc_base *rx_desc; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_rx_info rxstat_log; + size_t log_size; + adf_nbuf_t msdu; + + if (!pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!amsdu) { + printk("Invalid data in %s\n", __func__); + return A_ERROR; + } + pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev; + pl_info = pl_dev->pl_info; + msdu = amsdu; + + while (msdu) { + rx_desc = (struct htt_host_rx_desc_base *)( + adf_nbuf_data(msdu)) - 1; + log_size = sizeof(*rx_desc) - + sizeof(struct htt_host_fw_desc_base); + + /* + * Construct the pktlog header pl_hdr + * Because desc is DMA'd to the host memory + */ + pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + pl_hdr.missed_cnt = 0; + pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; + pl_hdr.size = sizeof(*rx_desc) - + sizeof(struct htt_host_fw_desc_base); + pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + adf_os_mem_copy(rxstat_log.rx_desc, (void *)rx_desc + + sizeof(struct htt_host_fw_desc_base), + pl_hdr.size); + msdu = adf_nbuf_next(msdu); + } + return A_OK; +} + +A_STATUS +process_rx_info(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rx_info rxstat_log; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + printk("Invalid pdev in %s", __func__); + return A_ERROR; + } + pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev; + pl_info = pl_dev->pl_info; + pl_tgt_hdr = (uint32_t *)data; + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> + ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + adf_os_mem_copy(rxstat_log.rx_desc, + (void *)data + sizeof(struct ath_pktlog_hdr), + pl_hdr.size); + + return A_OK; +} + +A_STATUS +process_rate_find(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_rc_find rcf_log; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + adf_os_print("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!data) { + adf_os_print("Invalid data in %s\n", __func__); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *)data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> + ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev; + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + rcf_log.rcFind = (void *) pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + adf_os_mem_copy(rcf_log.rcFind, + ((char *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + return A_OK; +} + +A_STATUS +process_rate_update(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rc_update rcu_log; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!data) { + printk("Invalid data in %s\n", __func__); + return A_ERROR; + } + pl_tgt_hdr = (uint32_t *)data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> + ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev; + log_size = pl_hdr.size; + pl_info = pl_dev->pl_info; + + /* + * Will be uncommented when the rate control update + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + adf_os_mem_copy(rcu_log.txRateCtrl, + ((char *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + return A_OK; +} +#endif /*REMOVE_PKT_LOG*/ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/event_defs.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/event_defs.h new file mode 100644 index 0000000000000..be029188d0491 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/event_defs.h @@ -0,0 +1,1914 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef EVENT_DEFS_H +#define EVENT_DEFS_H + + +typedef enum +{ + EVENT_DROP_ID = 0, + + EVENT_BAND_CLASS_CHANGE = 0x0100, /* Includes band class as payload */ + EVENT_CDMA_CH_CHANGE, /* Includes cdma channel as payload */ + EVENT_BS_P_REV_CHANGE, /* Includes BS p_rev as payload */ + EVENT_P_REV_IN_USE_CHANGE, /* Includes p_rev_in_use as payload */ + EVENT_SID_CHANGE, /* Includes SID as payload */ + EVENT_NID_CHANGE, /* Includes NID as payload */ + EVENT_PZID_CHANGE, /* Includes PZID as payload */ + EVENT_PDE_SESSION_END, /* No payload */ + EVENT_OP_MODE_CHANGE, /* Includes operation mode as payload */ + EVENT_MESSAGE_RECEIVED, /* Includes channel and message ID as + payload */ + EVENT_MESSAGE_TRANSMITTED, /* Includes channel and message ID as + payload */ + EVENT_TIMER_EXPIRED, /* Includes timer ID as payload */ + EVENT_COUNTER_THRESHOLD, /* Includes counter ID as payload */ + EVENT_CALL_PROCESSING_STATE_CHANGE, /* Includes new state and old state as + payload */ + EVENT_CALL_CONTROL_INSTANTIATED, /* Includes con_ref as payload */ + EVENT_CALL_CONTROL_STATE_CHANGE, /* Includes con_ref, old substate and + new substate as payload */ + EVENT_CALL_CONTROL_TERMINATED, /* Includes con_ref as payload */ + EVENT_REG_ZONE_CHANGE, /* Includes reg_zone as payload */ + EVENT_SLOTTED_MODE_OPERATION, /* Includes enter/exit bit as payload */ + EVENT_QPCH_IN_USE, /* Includes enable/disable bit as payload */ + EVENT_IDLE_HANDOFF, /* Includes pn_offset as payload */ + EVENT_ACCESS_HANDOFF, /* Includes pn_offset as payload */ + EVENT_ACCESS_PROBE_HANDOFF, /* Includes pn_offset as payload */ + EVENT_SOFT_HANDOFF, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_FREQ_CHANGE, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_FRAME_OFFSET_CHANGE, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_DISJOINT_ASET, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_UNSUCCESSFUL_HARD_HANDOFF, /* No payload */ + EVENT_TMSI_ASSIGNED, /* Includes TMSI as payload */ + EVENT_SERVICE_NEGOTIATION_COMPLETED,/* No payload */ + EVENT_SO_NEGOTIATION_COMPLETED, /* No payload */ + EVENT_ENTER_CONTROL_HOLD_MODE, /* No payload */ + EVENT_EXIT_CONTROL_HOLD_MODE, /* No payload */ + EVENT_START_FWD_SUPP_BURST_ASSGN, /* Includes SCH rate as payload */ + EVENT_END_FWD_SUPP_BURST_ASSGN, /* No payload */ + EVENT_START_REV_SUPP_BURST_ASSGN, /* Includes SCH rate as payload */ + EVENT_END_REV_SUPP_BURST_ASSGN, /* No payload */ + EVENT_DTX, /* No payload */ + EVENT_T_ADD_ABORT, /* No payload */ + EVENT_CH_IND_CHANGE, /* Include ch_ind as payload */ + EVENT_TRANSMITTER_DISABLED, /* No payload */ + EVENT_TRANSMITTER_ENABLED, /* No payload */ + EVENT_SMS_RECEIVED, /* No payload */ + EVENT_SMS_SENT, /* No payload */ + EVENT_INACTIVITY_TIMER_EXPIRED, /* No payload */ + EVENT_DORMANT_TIMER_EXPIRED, /* No payload */ + EVENT_ACCESS_ATTEMPT_FAIL_MAX_PROBES_SENT, /* No payload */ + EVENT_ACCESS_ATTEMPT_FAIL_LOSS_OF_PC_OR_FCCC, /* No payload */ + EVENT_PCH_ACQUIRED, /* Includes pagech and pn_offset + as payload */ + EVENT_BCCH_ACQUIRED, /* Includes walsh code for BCCH and + pn_offset as payload */ + EVENT_FFCH_ACQUIRED, /* Payload: 14 bytes */ + EVENT_FDCCH_ACQUIRED, /* Payload: 14 bytes */ + EVENT_FFCH_PLUS_DCCH_ACQUIRED, /* No payload */ + EVENT_REGISTRATION_PERFORMED, /* Includes reg_type as payload */ + EVENT_NEW_SYSTEM_IDLE_HANDOFF, /* No payload */ + EVENT_SYSTEM_RESELECTION, /* Includes ecio and ps as payload */ + EVENT_RESCAN, /* No payload */ + EVENT_PROTOCOL_MISMATCH, /* No payload */ + EVENT_LOCK, /* No payload */ + EVENT_UNLOCK, /* No payload */ + EVENT_ACCESS_DENIED, /* No payload */ + EVENT_NDSS_OFF, /* No payload */ + EVENT_RELEASE, /* Payload: 1 byte */ + EVENT_ERROR, /* No payload */ + EVENT_REDIRECTION, /* No payload */ + EVENT_REGISTRATION_REJECTED, /* No payload */ + EVENT_WRONG_SYSTEM, /* No payload */ + EVENT_WRONG_NETWORK, /* No payload */ + EVENT_LOSS_OF_ACQ_AFTER_SLEEP, /* No payload */ + EVENT_POWER_DOWN, /* No payload */ + EVENT_CALL_RELEASE_REQUEST, /* No payload */ + EVENT_SERVICE_INACTIVE, /* No payload */ + EVENT_EXTENDED_RELEASE, /* No payload */ + + EVENT_HDR_MSG_RX, /* protocol, msg- 3 bytes */ + EVENT_HDR_RXMSG_IGNORED_STATE, /* protocol, msg- 3 bytes */ + EVENT_HDR_RXMSG_IGNORED_SEQ, /* protocol, msg- 3 bytes */ + EVENT_HDR_TXMSG_ACKED, /* protocol, msg- 3 bytes */ + EVENT_HDR_TXMSG_DROPPED, /* protocol, msg- 3 bytes */ + EVENT_HDR_STATE_CHANGE, /* protocol, from, to - 5 bytes */ + EVENT_HDR_ALMP_OBEYING_REDIRECTION, /* No payload */ + EVENT_HDR_ALMP_CONNECTION_CLOSED, /* No payload */ + EVENT_HDR_ALMP_T_SD_RESELECT, /* No payload */ + EVENT_HDR_ALMP_CONNECTION_OPENED, /* No payload */ + EVENT_HDR_HMP_QUEUED_MSG, /* protocol, msg- 3 bytes */ + EVENT_HDR_HMP_SENT_MSG, /* protocol, msg, chan, is_reliable - 5 bytes */ + EVENT_HDR_HMP_ABORTING_ACMAC_ACTIVATION, /* No payload */ + EVENT_HDR_IDLE_T_CONFIG_RSP, /* No payload */ + EVENT_HDR_IDLE_T_AT_SETUP, /* No payload */ + EVENT_HDR_IDLE_T_SUSPEND, /* No payload */ + EVENT_HDR_IDLE_CONNECTION_DENIED, /* No payload */ + EVENT_HDR_INIT_T_SYNC_ACQ, /* No payload */ + EVENT_HDR_INIT_PROTOCOL_MISMATCH, /* No payload */ + EVENT_HDR_OVHD_INFO_CURRENT, /* No payload */ + EVENT_HDR_OVHD_T_QC_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_T_SP_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_T_AP_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_IGNORED_MSG_UNEXPECTED_LINK, /* msg, exp_link.chan_num, + exp_link.pilot, rx_link.chan_num, + rx_link.pilot - 10 bytes */ + EVENT_HDR_OVHD_IGNORED_SP_MSG_DIFF_SEC_SIG, /* exp_sig, rx_sig - 8 bytes */ + EVENT_HDR_OVHD_IGNORED_AP_MSG_DIFF_ACC_SIG, /* exp_sig, rx_sig - 8 bytes */ + EVENT_HDR_OVHD_IGNORED_SP_MSG_DIFF_SEC_ID, /* No payload */ + EVENT_HDR_OVHD_SP_MSG_RX, /* No payload */ + EVENT_HDR_OVHD_AP_MSG_RX, /* No payload */ + EVENT_HDR_RUP_T_CONNECTION_SETUP, /* No payload */ + EVENT_HDR_SLP_MAX_RETRIES, /* msg - 2 bytes */ + EVENT_HDR_LMAC_ACQ_FAIL_PILOT, /* No payload */ + EVENT_HDR_LMAC_ACQ_SUCCESS, /* No payload */ + EVENT_HDR_LMAC_NETWORK_LOST, /* No payload */ + EVENT_HDR_LMAC_IDLE_HO, /* new_pilot - 2 bytes */ + EVENT_HDR_LMAC_CHAN_CHANGE_COMPLETE, /* No payload */ + EVENT_HDR_LMAC_ACCESS_HO_NEEDED, /* suggested_pilot - 2 bytes */ + EVENT_HDR_LMAC_ACCESS_HO_COMPLETE, /* new_pilot - 2 bytes */ + EVENT_HDR_LMAC_ACQUIRE, /* channel 2 bytes */ + EVENT_HDR_LMAC_CHANGING_CC_HASH, /* cc_hash - 1 byte */ + EVENT_HDR_LMAC_IDLE_CHAN_CHANGE, /* channel - 2 bytes */ + EVENT_HDR_CMAC_T_SUPERVISION, /* No payload */ + EVENT_HDR_AMAC_START_ACCESS, /* No payload */ + EVENT_HDR_AMAC_PROBING_STOPPED, /* No payload */ + EVENT_HDR_AMAC_ACCESS_COMPLETE, /* No payload */ + EVENT_HDR_AMAC_ACCESS_ABORTED, /* No payload */ + EVENT_HDR_AMAC_MAX_PROBES, /* No payload */ + EVENT_HDR_FMAC_DROP_PKT, /* No payload */ + EVENT_HDR_RMAC_T_RATE_LIMIT, /* No payload */ + EVENT_HDR_RMAC_TX_STARTED, /* No payload */ + EVENT_HDR_RMAC_TX_STOPPED, /* No payload */ + EVENT_HDR_SMP_T_KEEP_ALIVE, /* No payload */ + EVENT_HDR_AMP_ASSIGN_MSG_IGNORED_FRESH, /* No payload */ + EVENT_HDR_AMP_T_AT_RESPONSE, /* No payload */ + EVENT_HDR_AMP_T_DUAL_ADDRESS, /* No payload */ + EVENT_HDR_SCP_BEGIN_CONFIGURATION, /* No payload */ + EVENT_HDR_SCP_T_CONFIG_RSP, /* No payload */ + EVENT_HDR_SCP_T_AN_INIT_STATE, /* No payload */ + + EVENT_WCDMA_L1_STATE, /* l1_state - 1 byte */ + EVENT_WCDMA_IMSI, /* IMSI - 9 bytes */ + EVENT_GSM_L1_STATE, /* GSM l1_state - 1 byte */ + EVENT_RANDOM_ACCESS_REQUEST, /* GSM Random Access Request - 4 bytes */ + EVENT_HIGH_LEVEL_CALL_PROCESSING_STATE_CHANGE, /* Puma requested event */ + /* (same payload as CALL_PROCESSING_STATE_CHANGE) */ + EVENT_ENCRYPTION_FAILURE, /* Puma event, no payload */ + EVENT_ACCT_BLOCKED, /* Puma event, no payload */ + EVENT_COMMON_CHANNEL_MONITORED, /* Puma event, 1 byte payload */ + EVENT_SOFT_HANDOFF_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_FREQ_CHANGE_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_FRAME_OFFSET_CHANGE_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_DISJOINT_ASET_V2, /* Puma event, 14 byte payload */ + EVENT_WCDMA_NEW_REFERENCE_CELL, + EVENT_CALL_CONTROL_CONREF_CHANGE, /* Puma event, 2 byte payload */ + + EVENT_GPS_SESSION_BEGIN, + EVENT_GPS_SESSION_END, + EVENT_GPS_WAITING_ON_SA, + EVENT_GPS_PPM_START, + EVENT_GPS_PPM_RESULTS, + EVENT_GPS_PPM_END, + EVENT_GPS_VISIT_BEGIN, + EVENT_GPS_VISIT_END, + EVENT_GPS_CDMA_RESUMED_AFTER_GPS_VISIT, + EVENT_GPS_PD_SESSION_BEGIN, + EVENT_GPS_PD_SESSION_END, /* Payload: 1 byte PDSM substate */ + EVENT_GPS_IS801_RX, /* Payload, 1 byte msg_type */ + EVENT_GPS_IS801_TX, /* Payload: 1 byte msg_type */ + EVENT_POWERUP, + EVENT_WCDMA_ASET, + EVENT_CM_CALL_STATE, /* (1 byte payload: overall call state) */ + EVENT_CM_OPERATIONAL_MODE, /* (1 byte payload: op mode) */ + EVENT_CM_SYSTEM_MODE, /* (1 byte payload: sys_mode) */ + + EVENT_DEEP_SLEEP, /* no payload */ + EVENT_WAKEUP, /* unsigned long (4 bytes) payload */ + EVENT_ACQUISITION_MODE, /* unsigned char (1 byte) payload */ + EVENT_ACQUISITION_TYPE, /* unsigned char (1 byte) payload */ + EVENT_ACP_EXIT, /* unsigned char (1 byte) payload */ + EVENT_CDMA_EXIT, /* unsigned char (1 byte) payload */ + + EVENT_HDR_HYBRID_POWER_SAVE, /* No payload */ + EVENT_HDR_DEEP_SLEEP, /* No payload */ + EVENT_HDR_RESELECTION, /* No payload */ + EVENT_SAM_LOCK_GRANTED, /* +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +void vos_event_report_payload(v_U16_t event_Id, v_U16_t length, v_VOID_t *pPayload); +/*--------------------------------------------------------------------------- + Allocate an event payload holder +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_EVENT_DEF( payload_name, payload_type ) \ + payload_type(payload_name) + +/*--------------------------------------------------------------------------- + Report the event +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_EVENT_REPORT( payload_ptr, ev_id ) \ + do \ + { \ + vos_event_report_payload( ev_id, \ + sizeof( *(payload_ptr) ), \ + (void *)(payload_ptr) ); \ + \ + } while (0) + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_VOS_DIAG_EVENT_DEF( payload_name, payload_type ) +#define WLAN_VOS_DIAG_EVENT_REPORT( payload_ptr, ev_id ) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_DIAG_CORE_EVENT_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_diag_core_log.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_diag_core_log.h new file mode 100644 index 0000000000000..04f4c349d3a3b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_diag_core_log.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_DIAG_CORE_LOG_H ) +#define __I_VOS_DIAG_CORE_LOG_H + +/**========================================================================= + + \file i_vos_diag_core_event.h + + \brief android-specific definitions for vOSS DIAG logs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +//FIXME To be removed when DIAG support is added. This definiton should be +//picked from log.h file above. +typedef struct +{ + /* Specifies the length, in bytes of the entry, including this header. */ + v_U16_t len; + + /* Specifies the log code for the entry*/ + v_U16_t code; + + /*Time Stamp lo*/ + v_U32_t ts_lo; + + /*Time Stamp hi*/ + v_U32_t ts_hi; +}__packed log_hdr_type; + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void vos_log_set_code (v_VOID_t *ptr, v_U16_t code); +void vos_log_set_length (v_VOID_t *ptr, v_U16_t length); +void vos_log_set_timestamp (v_VOID_t *plog_hdr_ptr); +void vos_log_submit(v_VOID_t *plog_hdr_ptr); + +/*--------------------------------------------------------------------------- + Allocate an event payload holder +---------------------------------------------------------------------------*/ + +#define WLAN_VOS_DIAG_LOG_ALLOC( payload_ptr, payload_type, log_code ) \ + do \ + { \ + payload_ptr = ( payload_type *)vos_mem_malloc(sizeof(payload_type));\ + \ + if( payload_ptr ) \ + { \ + vos_mem_zero(payload_ptr, sizeof(payload_type)); \ + vos_log_set_code(payload_ptr, log_code); \ + vos_log_set_length(payload_ptr, sizeof(payload_type)); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Report the event +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_LOG_REPORT( payload_ptr ) \ + do \ + { \ + if( payload_ptr) \ + { \ + vos_log_submit( payload_ptr); \ + vos_mem_free(payload_ptr); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Free the payload +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_LOG_FREE( payload_ptr ) \ + do \ + { \ + if( payload_ptr) \ + { \ + vos_mem_free(payload_ptr); \ + } \ + } while (0) + + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_VOS_DIAG_LOG_ALLOC( payload_ptr, payload_type, log_code ) +#define WLAN_VOS_DIAG_LOG_REPORT( payload_ptr ) +#define WLAN_VOS_DIAG_LOG_FREE( payload_ptr ) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_DIAG_CORE_LOG_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_event.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_event.h new file mode 100644 index 0000000000000..ea6f457df6f27 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_event.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_EVENT_H ) +#define __I_VOS_EVENT_H + +/**========================================================================= + + \file i_vos_event.h + + \brief Linux-specific definitions for vOSS Events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define LINUX_EVENT_COOKIE 0x12341234 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef struct evt +{ + struct completion complete; + v_U32_t cookie; +} vos_event_t; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_EVENT_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_list.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_list.h new file mode 100644 index 0000000000000..119531c78c3ad --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_list.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_LIST_H ) +#define __I_VOS_LIST_H + +/**========================================================================= + + \file i_vos_list.h + + \brief Linux-specific definitions for vOSS lists + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct vos_linux_list_s +{ + struct list_head anchor; + v_SIZE_t count; + struct mutex lock; + v_U32_t cookie; +} vos_list_t; + +typedef struct list_head vos_list_node_t; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_LIST_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_lock.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_lock.h new file mode 100644 index 0000000000000..a8fc7f8871e99 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_lock.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_LOCK_H ) +#define __I_VOS_LOCK_H + +/**========================================================================= + + \file i_vos_lock.h + + \brief Linux-specific definitions for vOSS Locks + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct vos_lock_s +{ + struct mutex m_lock; + v_U32_t cookie; + int processID; + v_U32_t state; + v_U8_t refcount; +} vos_lock_t; + +typedef spinlock_t vos_spin_lock_t; + +#if defined CONFIG_CNSS +typedef struct wakeup_source vos_wake_lock_t; +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +typedef struct wake_lock vos_wake_lock_t; +#else +typedef int vos_wake_lock_t; +#endif + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_LOCK_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_packet.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_packet.h new file mode 100644 index 0000000000000..8fec979be8f3b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_packet.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_PACKET_H ) +#define __I_VOS_PACKET_H + +/**========================================================================= + + \file i_vos_packet.h + + \brief virtual Operating System Servies (vOSS) + + Network Protocol packet/buffer internal include file + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "adf_os_types.h" +/* + * Rx Packet Struct + * rssi field is normalized to -96 dBm as normal noise floor by adding + * -96 to snr. All the configured thresholds in the driver assume that + * noise floor is -96 dBm. + * rssi_raw field is signal strength of the received frame relative + * to the noise floor recorded in hardware. + */ +typedef struct +{ + u_int8_t channel; + u_int8_t snr; + u_int32_t rssi; + u_int32_t timestamp; + u_int8_t *mpdu_hdr_ptr; + u_int8_t *mpdu_data_ptr; + u_int32_t mpdu_len; + u_int32_t mpdu_hdr_len; + u_int32_t mpdu_data_len; + u_int8_t offloadScanLearn:1; + u_int8_t roamCandidateInd:1; + u_int8_t scan:1; + u_int8_t dpuFeedback; + u_int8_t sessionId; + u_int8_t scan_src:1; + u_int32_t rssi_raw; +}t_packetmeta, *tp_packetmeta; + +/* implementation specific vos packet type */ +struct vos_pkt_t +{ + /* Packet Meta Information */ + t_packetmeta pkt_meta; + + /* Pointer to Packet */ + void *pkt_buf; +}; + +#endif // !defined( __I_VOS_PACKET_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_timer.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_timer.h new file mode 100644 index 0000000000000..0c5f797dd2b00 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_timer.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TIMER_H ) +#define __I_VOS_TIMER_H + +/**========================================================================= + + \file i_vos_timer.h + + \brief Linux-specific definitions for vOSS packets + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef struct vos_timer_platform_s +{ + struct timer_list Timer; + int threadID; + v_U32_t cookie; + spinlock_t spinlock; + +} vos_timer_platform_t; + +/* + * TODOs: Need to add deferred timer implementation + * +*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_TIMER_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_trace.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_trace.h new file mode 100644 index 0000000000000..ce75a27bf8248 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_trace.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TRACE_H ) +#define __I_VOS_TRACE_H + +#if !defined(__printf) +#define __printf(a,b) +#endif + +/**========================================================================= + + \file i_vos_trace.h + + \brief Linux-specific definitions for VOSS trace + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/**---------------------------------------------------------------------------- + + \brief VOS_TRACE() / vos_trace_msg() - Trace / logging API + + Users wishing to add tracing information to their code should use + VOS_TRACE. VOS_TRACE() will compile into a call to vos_trace_msg() when + tracing is enabled. + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + --------------------------------------------------------------------------*/ +void __printf(3,4) vos_trace_msg( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + char *strFormat, ... ); + +void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + void *data, int buf_len ); + +void vos_trace_display(void); + +void vos_trace_setValue( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, v_U8_t on ); + + +// VOS_TRACE is the macro invoked to add trace messages to code. See the +// documenation for vos_trace_msg() for the parameters etc. for this function. +// +// NOTE: Code VOS_TRACE() macros into the source code. Do not code directly +// to the vos_trace_msg() function. +// +// NOTE 2: vos tracing is totally turned off if WLAN_DEBUG is *not* defined. +// This allows us to build 'performance' builds where we can measure performance +// without being bogged down by all the tracing in the code. +#if defined( WLAN_DEBUG ) +#define VOS_TRACE vos_trace_msg +#define VOS_TRACE_HEX_DUMP vos_trace_hex_dump +#else +#define VOS_TRACE(arg...) +#define VOS_TRACE_HEX_DUMP(arg...) +#endif + + +void __printf(3,4) vos_snprintf(char *strBuffer, unsigned int size, + char *strFormat, ...); +#define VOS_SNPRINTF vos_snprintf + +#ifdef VOS_ENABLE_TRACING + + +#define VOS_ASSERT( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS ASSERT in %s Line %d\n", __func__, __LINE__); \ + WARN_ON(1); \ + } \ + } while(0) + +#else + + + // This code will be used for compilation if tracing is to be compiled out + // of the code so these functions/macros are 'do nothing' + VOS_INLINE_FN void vos_trace_msg( VOS_MODULE_ID module, ... ){} + + #define VOS_ASSERT( _condition ) + +#endif + +#ifdef PANIC_ON_BUG + +#define VOS_BUG( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS BUG in %s Line %d\n", __func__, __LINE__); \ + BUG_ON(1); \ + } \ + } while(0) + +#else + +#define VOS_BUG( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS BUG in %s Line %d\n", __func__, __LINE__); \ + WARN_ON(1); \ + } \ + } while(0) + +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_types.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_types.h new file mode 100644 index 0000000000000..e4cde703e78ab --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/i_vos_types.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TYPES_H ) +#define __I_VOS_TYPES_H +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**========================================================================= + + \file i_vos_Types.h + + \brief virtual Operating System Servies (vOSS) Types + + Linux specific basic type definitions + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + */ + +// MACROs to help with compiler and OS specifics. +// \note: may need to get a little more sophisticated than this and define +// these to specific 'VERSIONS' of the compiler and OS. Until we have a +// need for that, lets go with this. +#if defined( _MSC_VER ) + +#define VOS_COMPILER_MSC +#define VOS_OS_WINMOBILE // assuming that if we build with MSC, OS is WinMobile + +#elif defined( __GNUC__ ) + +#define VOS_COMPILER_GNUC +#define VOS_OS_LINUX // assuming if building with GNUC, OS is Linux + +#endif + + +// VOS definitions (compiler specific) for Packing structures. Note that the +// Windows compiler defines a way to pack a 'range' of code in a file. To +// accomodate this, we have to include a file that has the packing #pragmas +// These files are called +// vos_pack_range_n_start.h where "n" is the packing aligment. For example, +// vos_pack_range_2_start.h is included in the file where you want to +// start packing on a 2 byte alignment. vos_pack_range_end.h is included +// in the file where you want to stop the packing. +// +// Other compilers allow packing individual strucutres so we have a series +// of macros that are added to the structure to define the packing attributes. +// For example, VOS_PACK_STRUCT_2 will add the attributes to pack an +// individual structure on a 2 byte boundary. +// +// So what does a coder have to do to properly pack a structure for all the +// supported compilers? You have to add two includes around *all* the +// structures you want packed the same way and you also have to add the +// VOS_PACK_STRUCT_n macros to the individual structures. +// +// For example to properly pack myStruct on a 2 byte boundary for all +// voss supported compilers, the following needs coded... +// +// +// #include +// +// typedef struct +// { +// unsigned char c; +// long int i; +// } myStruct VOS_PACK_STRUCT_2; +// +// +// note... you can include other structure definitions in here that have the +// same 2 byte packing +// +// #include + + +// /todo: not sure what the flag is to identify the Microsoft compiler for WinMobile +// Let's leave this out for now and just include the defintions for WinMobile. Need +// to address this when we move to support other operating systems. Probably best to +// define some of our own 'types' or preprocessor flags like VOS_COMPILER_TYPE, +// VOS_OS_TYPE, etc. and then all our code can base on those flags/types independent +// of the operating system, compiler, etc. +#if defined( VOS_COMPILER_MSC ) + + +#define VOS_INLINE_FN __inline + +// does nothing on Windows. packing individual structs is not +// supported on the Windows compiler. +#define VOS_PACK_STRUCT_1 +#define VOS_PACK_STRUCT_2 +#define VOS_PACK_STRUCT_4 +#define VOS_PACK_STRUCT_8 +#define VOS_PACK_STRUCT_16 + +#elif defined( VOS_COMPILER_GNUC ) + +#define VOS_INLINE_FN static inline + +#else +#error "Compiling with an unknown compiler!!" +#endif + + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// unsigned 8-bit types +typedef u8 v_U8_t; +typedef u8 v_UCHAR_t; +typedef u8 v_BYTE_t; + +/// unsigned 16-bit types +typedef u16 v_U16_t; +typedef unsigned short v_USHORT_t; + +/// unsigned 32-bit types +typedef u32 v_U32_t; +// typedef atomic_t v_U32AT_t; +typedef unsigned long v_ULONG_t; + +/// unsigned 64-bit types +typedef u64 v_U64_t; + +/// unsigned integer types +typedef unsigned int v_UINT_t; + +/// signed 8-bit types +typedef s8 v_S7_t; +typedef signed char v_SCHAR_t; + +/// signed 16-bit types +typedef s16 v_S15_t; +typedef signed short v_SSHORT_t; + +/// signed 32-bit types +typedef s32 v_S31_t; +typedef signed long v_SLONG_t; + +/// signed integer types +typedef signed int v_SINT_t; + +/// Boolean types +typedef unsigned char v_BOOL_t; + +/// void type +#define v_VOID_t void + +#endif // __I_VOSS_TYPES_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/log_codes.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/log_codes.h new file mode 100644 index 0000000000000..8b351db03538a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/log_codes.h @@ -0,0 +1,2080 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef LOG_CODES_H +#define LOG_CODES_H + +/*=========================================================================== + + Log Code Definitions + +General Description + This file contains log code definitions and is shared with the tools. + +===========================================================================*/ + +/* DO NOT MODIFY THIS FILE WITHOUT PRIOR APPROVAL +** +** Log codes, by design, are a tightly controlled set of values. +** Developers may not create log codes at will. +** +** Request new logs using the following process: +** +** 1. Send email to asw.diag.request requesting log codassignments. +** 2. Identify the log needed by name. +** 3. Provide a brief description for the log. +** +*/ + +/*=========================================================================== + + Edit History + +$Header: //source/qcom/qct/core/services/diag/api/inc/main/latest/log_codes.h#9 $ + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/30/09 dhao Consolidate log_codes_apps.h +07/30/09 dhao Add Last log code definition for Equip ID 11 +06/26/09 dhao Update format the macro +06/24/09 sar Reverted last change. +06/24/09 sar Added log code for LOG_MC_STM_C. +11/02/01 sfh Featurize common NAS log codes for UMTS. +10/30/01 sfh Added log code for LOG_GPS_FATPATH_INFO_C. +10/24/01 sfh Added updates for UMTS equipment ID and log codes. +06/27/01 lad Added multiple equipment ID support. +05/22/01 sfh Reserved log codes 158 - 168. +05/21/01 sfh Keep confusing XXX_BASE_C names for backwards compatibility. +05/16/01 sfh Reserved log code 155. +05/08/01 sfh Reserved log codes 150 - 154. +04/06/01 lad Added definitions of base IDs (such as LOG_WCDMA_BASE_C). + This is currently using temporary ID values in the 0x1000 + range. +02/23/01 lad Created file from DMSS log.h. Log codes only + +===========================================================================*/ +#include + +/* ------------------------------------------------------------------------- + * Data Declarations + * ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- + * Log equipment IDs. + * The most significant 4 bits of the 16 bit log code is the equipment ID. + * Orignally, the mobile was to have an ID, and base stations and other + * IDs. As QCT technology diversifies, new equipment IDs are assigned to new + * technology areas. 0x2000 and 0x3000 are reserved for legacy reasons, so + * the first + * addition starts at 0x4000. + * ------------------------------------------------------------------------- */ + +#define LOG_1X_BASE_C ((v_U16_t) 0x1000) +#define LOG_WCDMA_BASE_C ((v_U16_t) 0x4000) +#define LOG_GSM_BASE_C ((v_U16_t) 0x5000) +#define LOG_LBS_BASE_C ((v_U16_t) 0x6000) +#define LOG_UMTS_BASE_C ((v_U16_t) 0x7000) +#define LOG_TDMA_BASE_C ((v_U16_t) 0x8000) +#define LOG_DTV_BASE_C ((v_U16_t) 0xA000) +#define LOG_APPS_BASE_C ((v_U16_t) 0xB000) +#define LOG_LTE_BASE_C ((v_U16_t) (0xB000 + 0x0010)) +#define LOG_LTE_LAST_C ((v_U16_t) 0xB1FF) +#define LOG_WIMAX_BASE_C ((v_U16_t) 0xB400) +#define LOG_DSP_BASE_C ((v_U16_t) 0xC000) + +#define LOG_TOOLS_BASE_C ((v_U16_t) 0xF000) + +/* LOG_BASE_C is what was used before expanding the use of the equipment ID. + * TODO: Once all targets are using the "core" diag system, this should be + * ommitted. */ +#define LOG_BASE_C LOG_1X_BASE_C + +/* ------------------------------------------------------------------------- + * Log Codes + * These codes identify the kind of information contained in a log entry. + * They are used in conjunction with the 'code' field of the log entry + * header. The data types associated with each code are defined below. + * ------------------------------------------------------------------------- */ + +/* The upper 4 bits of the 16 bit log entry code specify which type + * of equipment created the log entry. */ + +/* 0 Mobile Station temporal analyzer entry */ +#define LOG_TA_C (0x0 + LOG_1X_BASE_C) + +/* 1 AGC values and closed loop power control entry */ +#define LOG_AGC_PCTL_C (0x1 + LOG_1X_BASE_C) + +/* 2 Forward link frame rates and types entry */ +#define LOG_F_MUX1_C (0x2 + LOG_1X_BASE_C) + +/* 3 Reverse link frame rates and types entry */ +#define LOG_R_MUX1_C (0x3 + LOG_1X_BASE_C) + +/* 4 Access channel message entry */ +#define LOG_AC_MSG_C (0x4 + LOG_1X_BASE_C) + +/* 5 Reverse link traffic channel message entry */ +#define LOG_R_TC_MSG_C (0x5 + LOG_1X_BASE_C) + +/* 6 Sync channel message entry */ +#define LOG_SC_MSG_C (0x6 + LOG_1X_BASE_C) + +/* 7 Paging channel message entry */ +#define LOG_PC_MSG_C (0x7 + LOG_1X_BASE_C) + +/* 8 Forward link traffic channel message entry */ +#define LOG_F_TC_MSG_C (0x8 + LOG_1X_BASE_C) + +/* 9 Forward link vocoder packet entry */ +#define LOG_VOC_FOR_C (0x9 + LOG_1X_BASE_C) + +/* 10 Reverse link vocoder packet entry */ +#define LOG_VOC_REV_C (0xA + LOG_1X_BASE_C) + +/* 11 Temporal analyzer finger info only */ +#define LOG_FING_C (0xB + LOG_1X_BASE_C) + +/* 12 Searcher pathlog info (Reused old SRCH logtype) */ +#define LOG_SRCH_C (0xC + LOG_1X_BASE_C) + +/* 13 Position and speed information read from ETAK */ +#define LOG_ETAK_C (0xD + LOG_1X_BASE_C) + +/* 14 Markov frame statistics */ +#define LOG_MAR_C (0xE + LOG_1X_BASE_C) + +/* 15 New and improved temporal analyzer searcher info */ +#define LOG_SRCH2_C (0xF + LOG_1X_BASE_C) + +/* 16 The Fujitsu handset information */ +#define LOG_HANDSET_C (0x10 + LOG_1X_BASE_C) + +/* 17 Vocoder bit error rate mask */ +#define LOG_ERRMASK_C (0x11 + LOG_1X_BASE_C) + +/* 18 Analog voice channel information */ +#define LOG_ANALOG_INFO_C (0x12 + LOG_1X_BASE_C) + +/* 19 Access probe information */ +#define LOG_ACC_INFO_C (0x13 + LOG_1X_BASE_C) + +/* 20 Position & speed info read from GPS receiver */ +#define LOG_GPS_C (0x14 + LOG_1X_BASE_C) + +/* 21 Test Command information */ +#define LOG_TEST_CMD_C (0x15 + LOG_1X_BASE_C) + +/* 22 Sparse (20ms) AGC / closed loop power control entry */ +#define LOG_S_AGC_PCTL_C (0x16 + LOG_1X_BASE_C) + +/* 23 Notification of a band class change */ +#define LOG_BAND_CHANGE_C (0x17 + LOG_1X_BASE_C) + +/* 24 DM debug messages, if being logged via log services */ +#define LOG_DBG_MSG_C (0x18 + LOG_1X_BASE_C) + +/* 25 General temporal analyzer entry */ +#define LOG_GENRL_TA_C (0x19 + LOG_1X_BASE_C) + +/* 26 General temporal analyzer w/supplemental channels */ +#define LOG_GENRL_TA_SUP_CH_C (0x1A + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI +#ifdef FEATURE_PLT +*/ + +/* 27 Decoder raw bits logging */ +#define LOG_PLT_C (0x1B + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI +#else +27 EFS Usage Info - No implementation as yet +#define LOG_EFS_INFO_C (0x1B + LOG_1X_BASE_C) +#endif +*/ + +/* 28 Analog Forward Channel */ +#define LOG_ANALOG_FORW_C (0x1C + LOG_1X_BASE_C) + +/* 29 Analog Reverse Channel */ +#define LOG_ANALOG_REVS_C (0x1D + LOG_1X_BASE_C) + +/* 30 Analog Handoff Entry */ +#define LOG_ANALOG_HANDOFF_C (0x1E + LOG_1X_BASE_C) + +/* 31 FM Slot Statistis entry */ +#define LOG_ANALOG_FMSLOT_C (0x1F + LOG_1X_BASE_C) + +/* 32 FOCC Word Sync Count entry */ +#define LOG_ANALOG_WS_COUNT_C (0x20 + LOG_1X_BASE_C) + +/* 33 */ +#define LOG_RLP_PACKET_C (0x21 + LOG_1X_BASE_C) + +/* 34 */ +#define LOG_ASYNC_TCP_SEG_C (0x22 + LOG_1X_BASE_C) + +/* 35 */ +#define LOG_PACKET_DATA_IP_PACKETS_C (0x23 + LOG_1X_BASE_C) + +/* 36 */ +#define LOG_FNBDT_MESSAGE_LOG_C (0x24 + LOG_1X_BASE_C) + +/* Begin IS-2000 LOG features */ + +/* 37 RLP RX Frames logging */ +#define LOG_RLP_RX_FRAMES_C (0x25 + LOG_1X_BASE_C) + +/* 38 RLP TX Frames logging */ +#define LOG_RLP_TX_FRAMES_C (0x26 + LOG_1X_BASE_C) + +/* 39 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD1_C (0x27 + LOG_1X_BASE_C) + +/* 40 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD2_C (0x28 + LOG_1X_BASE_C) + +/* 41 Forward Link Frame Types logging */ +#define LOG_FWD_FRAME_TYPES_C (0x29 + LOG_1X_BASE_C) + +/* 42 Reverse Link Frame Types logging */ +#define LOG_REV_FRAME_TYPES_C (0x2A + LOG_1X_BASE_C) + +/* 43 Fast Forward Power Control Parameters logging */ +#define LOG_FFWD_PCTRL_C (0x2B + LOG_1X_BASE_C) + +/* 44 Reverse Power Control Parameters logging */ +#define LOG_REV_PCTRL_C (0x2C + LOG_1X_BASE_C) + +/* 45 Searcher and Finger Information logging */ +#define LOG_SRCH_FING_INFO_C (0x2D + LOG_1X_BASE_C) + +/* 46 Service Configuration logging */ +#define LOG_SVC_CONFIG_C (0x2E + LOG_1X_BASE_C) + +/* 47 Active Set Configuration logging */ +#define LOG_ASET_CONFIG_C (0x2F + LOG_1X_BASE_C) + +/* 48 Quick Paging Channel logging */ +#define LOG_QPCH_C (0x30 + LOG_1X_BASE_C) + +/* 49 RLP Statistics logging */ +#define LOG_RLP_STAT_C (0x31 + LOG_1X_BASE_C) + +/* 50 Simple Test Data Service Option logging */ +#define LOG_STDSO_C (0x32 + LOG_1X_BASE_C) + +/* 51 Pilot Phase Measurement results logging */ +#define LOG_SRCH_PPM_RES_C (0x33 + LOG_1X_BASE_C) + +/* 52 Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_PPM_DB_C (0x34 + LOG_1X_BASE_C) + +/* 53 Pilot Phase Measurement search results logging */ +#define LOG_SRCH_PPM_C (0x35 + LOG_1X_BASE_C) + +/* 54 IS-801 forward link message */ +#define LOG_GPS_FWD_MSG_C (0x36 + LOG_1X_BASE_C) + +/* 55 IS-801 reverse link message */ +#define LOG_GPS_REV_MSG_C (0x37 + LOG_1X_BASE_C) + +/* 56 GPS search session statistics */ +#define LOG_GPS_STATS_MSG_C (0x38 + LOG_1X_BASE_C) + +/* 57 GPS search results */ +#define LOG_GPS_SRCH_PEAKS_MSG_C (0x39 + LOG_1X_BASE_C) + +/* 58 Factory Testmode logging */ +#define LOG_FTM_C (0x3A + LOG_1X_BASE_C) + +/* 59 Multiple Peak Logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_INFO_C (0x3B + LOG_1X_BASE_C) + +/* 60 Post processed search results logs */ +#define LOG_SRCH_GPS_POST_PROC_C (0x3C + LOG_1X_BASE_C) + +/* 61 FULL Test Data Service Option logging */ +#define LOG_FTDSO_C (0x3D + LOG_1X_BASE_C) + +/* 62 Bluetooth logging */ +#define LOG_BT_RESERVED_CODES_BASE_C (0x3E + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_BT_BASE_C LOG_BT_RESERVED_CODES_BASE_C + +/* 92 Bluetooth's last log code */ +#define LOG_BT_LAST_C (30 + LOG_BT_RESERVED_CODES_BASE_C) + +/* 93 HDR log codes */ +#define LOG_HDR_RESERVED_CODES_BASE_C (0x5D + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_HDR_BASE_C LOG_HDR_RESERVED_CODES_BASE_C + +/* 143 is HDR's last log code */ +#define LOG_HDR_LAST_C (50 + LOG_HDR_RESERVED_CODES_BASE_C) + +/* 144 IS2000 DCCH Forward link channel */ +#define LOG_FOR_DCCH_MSG_C (0x90 + LOG_1X_BASE_C) +#define LOG_DCCH_FWD_C LOG_FOR_DCCH_MSG_C + +/* 145 IS2000 DCCH Forward link channel */ +#define LOG_REV_DCCH_MSG_C (0x91 + LOG_1X_BASE_C) +#define LOG_DCCH_REV_C LOG_REV_DCCH_MSG_C + +/* 146 IS2000 DCCH Forward link channel */ +#define LOG_ZREX_C (0x92 + LOG_1X_BASE_C) + +/* 147 Active set info logging, similar to ASET_CONFIG, but simpler. */ +#define LOG_ASET_INFO_C (0x93 + LOG_1X_BASE_C) + +/* 148 Pilot Phase Measurement four-shoulder-search resutlts logging */ +#define LOG_SRCH_PPM_4SHOULDER_RES_C (0x94 + LOG_1X_BASE_C) + +/* 149 Extended Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_EXT_PPM_DB_C (0x95 + LOG_1X_BASE_C) + +/* 150 GPS Visit Parameters */ +#define LOG_GPS_VISIT_PARAMETERS_C (0x96 + LOG_1X_BASE_C) + +/* 151 GPS Measurement */ +#define LOG_GPS_MEASUREMENT_C (0x97 + LOG_1X_BASE_C) + +/* 152 UIM Data */ +#define LOG_UIM_DATA_C (0x98 + LOG_1X_BASE_C) + +/* 153 STDSO plus P2 */ +#define LOG_STDSO_P2_C (0x99 + LOG_1X_BASE_C) + +/* 154 FTDSO plus P2 */ +#define LOG_FTDSO_P2_C (0x9A + LOG_1X_BASE_C) + +/* 155 Search PPM Statistics */ +#define LOG_SRCH_PPM_STATS_C (0x9B + LOG_1X_BASE_C) + +/* 156 PPP Tx Frames */ +#define LOG_PPP_TX_FRAMES_C (0x9C + LOG_1X_BASE_C) + +/* 157 PPP Rx Frames */ +#define LOG_PPP_RX_FRAMES_C (0x9D + LOG_1X_BASE_C) + +/* 158-187 SSL reserved log codes */ +#define LOG_SSL_RESERVED_CODES_BASE_C (0x9E + LOG_1X_BASE_C) +#define LOG_SSL_LAST_C (29 + LOG_SSL_RESERVED_CODES_BASE_C) + +/* 188-199 Puma reserved log codes */ +/* 188 QPCH, version 2 */ +#define LOG_QPCH_VER_2_C (0xBC + LOG_1X_BASE_C) + +/* 189 Enhanced Access Probe */ +#define LOG_EA_PROBE_C (0xBD + LOG_1X_BASE_C) + +/* 190 BCCH Frame Information */ +#define LOG_BCCH_FRAME_INFO_C (0xBE + LOG_1X_BASE_C) + +/* 191 FCCCH Frame Information */ +#define LOG_FCCCH_FRAME_INFO_C (0xBF + LOG_1X_BASE_C) + +/* 192 FDCH Frame Information */ +#define LOG_FDCH_FRAME_INFO_C (0xC0 + LOG_1X_BASE_C) + +/* 193 RDCH Frame Information */ +#define LOG_RDCH_FRAME_INFO_C (0xC1 + LOG_1X_BASE_C) + +/* 194 FFPC Information */ +#define LOG_FFPC_INFO_C (0xC2 + LOG_1X_BASE_C) + +/* 195 RPC Information */ +#define LOG_RPC_INFO_C (0xC3 + LOG_1X_BASE_C) + +/* 196 Searcher and Finger Information */ +#define LOG_SRCH_FING_INFO_VER_2_C (0xC4 + LOG_1X_BASE_C) + +/* 197 Service Configuration, version 2 */ +#define LOG_SRV_CONFIG_VER_2_C (0xC5 + LOG_1X_BASE_C) + +/* 198 Active Set Information, version 2 */ +#define LOG_ASET_INFO_VER_2_C (0xC6 + LOG_1X_BASE_C) + +/* 199 Reduced Active Set */ +#define LOG_REDUCED_ASET_INFO_C (0xC7 + LOG_1X_BASE_C) + +/* 200 Search Triage Info */ +#define LOG_SRCH_TRIAGE_INFO_C (0xC8 + LOG_1X_BASE_C) + +/* 201 RDA Frame Information */ +#define LOG_RDA_FRAME_INFO_C (0xC9 + LOG_1X_BASE_C) + +/* 202 gpsOne fatpath information */ +#define LOG_GPS_FATPATH_INFO_C (0xCA + LOG_1X_BASE_C) + +/* 203 Extended AGC */ +#define LOG_EXTENDED_AGC_C (0xCB + LOG_1X_BASE_C) + +/* 204 Transmit AGC */ +#define LOG_TRANSMIT_AGC_C (0xCC + LOG_1X_BASE_C) + +/* 205 I/Q Offset registers */ +#define LOG_IQ_OFFSET_REGISTERS_C (0xCD + LOG_1X_BASE_C) + +/* 206 DACC I/Q Accumulator registers */ +#define LOG_DACC_IQ_ACCUMULATOR_C (0xCE + LOG_1X_BASE_C) + +/* 207 Register polling results */ +#define LOG_REGISTER_POLLING_RESULTS_C (0xCF + LOG_1X_BASE_C) + +/* 208 System arbitration module */ +#define LOG_AT_SAM_C (0xD0 + LOG_1X_BASE_C) + +/* 209 Diablo searcher finger log */ +#define LOG_DIABLO_SRCH_FING_INFO_C (0xD1 + LOG_1X_BASE_C) + +/* 210 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_C (0xD2 + LOG_1X_BASE_C) + +/* 211 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_HYBRID_C (0xD3 + LOG_1X_BASE_C) + +/* 212 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_C (0xD4 + LOG_1X_BASE_C) + +/* 213 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_HYBRID_C (0xD5 + LOG_1X_BASE_C) + +/* 214 log reserved for jpinos */ +#define LOG_BCCH_SIGNALING_C (0xD6 + LOG_1X_BASE_C) + +/* 215 log reserved for jpinos */ +#define LOG_REACH_SIGNALING_C (0xD7 + LOG_1X_BASE_C) + +/* 216 log reserved for jpinos */ +#define LOG_FCCCH_SIGNALING_C (0xD8 + LOG_1X_BASE_C) + +/* 217 RDA Frame Information 2 */ +#define LOG_RDA_FRAME_INFO_2_C (0xD9 + LOG_1X_BASE_C) + +/* 218 */ +#define LOG_GPS_BIT_EDGE_RESULTS_C (0xDA + LOG_1X_BASE_C) + +/* 219 */ +#define LOG_PE_DATA_C (0xDB + LOG_1X_BASE_C) + +/* 220 */ +#define LOG_PE_PARTIAL_DATA_C (0xDC + LOG_1X_BASE_C) + +/* 221 */ +#define LOG_GPS_SINGLE_PEAK_SRCH_RESULTS_C (0xDD + LOG_1X_BASE_C) + +/* 222 */ +#define LOG_SRCH4_SAMPRAM_C (0xDE + LOG_1X_BASE_C) + +/* 223 */ +#define HDR_AN_PPP_TX_FRAMES (0xDF + LOG_1X_BASE_C) + +/* 224 */ +#define HDR_AN_PPP_RX_FRAMES (0xE0 + LOG_1X_BASE_C) + +/* 225 */ +#define LOG_GPS_SCHEDULER_TRACE_C (0xE1 + LOG_1X_BASE_C) + +/* 226 */ +#define LOG_MPEG4_YUV_FRAME_C (0xE2 + LOG_1X_BASE_C) + +/* 227 */ +#define LOG_MPEG4_CLIP_STATS_C (0xE3 + LOG_1X_BASE_C) + +/* 228 */ +#define LOG_MPEG4_CLIP_STATS_VER2_C (0xE4 + LOG_1X_BASE_C) + +/* 226-241 MMEG reserved. */ +#define LOG_MPEG_RESERVED_CODES_BASE_C (0xF1 + LOG_1X_BASE_C) + +/* 242-274 BREW reserved log range */ +#define LOG_BREW_RESERVED_CODES_BASE_C (0xF2 + LOG_1X_BASE_C) +#define LOG_BREW_LAST_C (32 + LOG_BREW_RESERVED_CODES_BASE_C) + +/* 275-339 PPP Extended Frames */ +#define LOG_PPP_FRAMES_RESERVED_CODES_BASE_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_FRAMES_LAST_C (64 + LOG_PPP_FRAMES_RESERVED_CODES_BASE_C) + +#define LOG_PPP_EXT_FRAMED_RX_UM_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_RM_C (0x114 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_AN_C (0x115 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_FRAMED_TX_UM_C (0x123 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_RM_C (0x124 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_AN_C (0x125 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_RX_UM_C (0x133 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_RM_C (0x134 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_AN_C (0x135 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_TX_UM_C (0x143 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_RM_C (0x144 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_AN_C (0x145 + LOG_1X_BASE_C) + +/* 340 LOG_PE_DATA_EXT_C */ +#define LOG_PE_DATA_EXT_C (0x154 + LOG_1X_BASE_C) + +/* REX Subsystem logs */ +#define LOG_MEMDEBUG_C (0x155 + LOG_1X_BASE_C) +#define LOG_SYSPROFILE_C (0x156 + LOG_1X_BASE_C) +#define LOG_TASKPROFILE_C (0x157 + LOG_1X_BASE_C) +#define LOG_COREDUMP_C (0x158 + LOG_1X_BASE_C) + +/* 341-349 REX subsystem logs */ +#define LOG_REX_RESERVED_CODES_BASE_C (0x155 + LOG_1X_BASE_C) +#define LOG_REX_LAST_C (8 + LOG_REX_RESERVED_CODES_BASE_C) + +/* 350 LOG_PE_PARTIAL_DATA_EXT_C */ +#define LOG_PE_PARTIAL_DATA_EXT_C (0x15E + LOG_1X_BASE_C) + +/* 351 LOG_DIAG_STRESS_TEST_C */ +#define LOG_DIAG_STRESS_TEST_C (0x15F + LOG_1X_BASE_C) + +/* 352 LOG_WMS_READ_C */ +#define LOG_WMS_READ_C (0x160 + LOG_1X_BASE_C) + +/* 353 Search Triage Info Version 2 */ +#define LOG_SRCH_TRIAGE_INFO2_C (0x161 + LOG_1X_BASE_C) + +/* 354 RLP Rx FDCH Frames */ +#define LOG_RLP_RX_FDCH_FRAMES_C (0x162 + LOG_1X_BASE_C) + + +/* 355 RLP Tx FDCH Frames */ +#define LOG_RLP_TX_FDCH_FRAMES_C (0x163 + LOG_1X_BASE_C) + +/* 356-371 QTV subsystem logs */ +#define LOG_QTV_RESERVED_CODES_BASE_C (0x164 + LOG_1X_BASE_C) +#define LOG_QTV_LAST_C (15 + LOG_QTV_RESERVED_CODES_BASE_C) + +/* 372 Searcher 4 1X */ +#define LOG_SRCH4_1X_C (0x174 + LOG_1X_BASE_C) + +/* 373 Searcher sleep statistics */ +#define LOG_SRCH_SLEEP_STATS_C (0x175 + LOG_1X_BASE_C) + +/* 374 Service Configuration, version 3 */ +#define LOG_SRV_CONFIG_VER_3_C (0x176 + LOG_1X_BASE_C) + +/* 375 Searcher 4 HDR */ +#define LOG_SRCH4_HDR_C (0x177 + LOG_1X_BASE_C) + +/* 376 Searcher 4 AFLT */ +#define LOG_SRCH4_AFLT_C (0x178 + LOG_1X_BASE_C) + +/* 377 Enhanced Finger Information */ +#define LOG_ENH_FING_INFO_C (0x179 + LOG_1X_BASE_C) + +/* 378 DV Information */ +#define LOG_DV_INFO_C (0x17A + LOG_1X_BASE_C) + +/* 379 WMS set routes information */ +#define LOG_WMS_SET_ROUTES_C (0x17B + LOG_1X_BASE_C) + +/* 380 FTM Version 2 Logs */ +#define LOG_FTM_VER_2_C (0x17C + LOG_1X_BASE_C) + +/* 381 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_SIMPLIFIED_INFO_C (0x17D + LOG_1X_BASE_C) + +/* 382 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_VERBOSE_INFO_C (0x17E + LOG_1X_BASE_C) + +/* 383-403 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_2_C (0x17F + LOG_1X_BASE_C) +#define LOG_HDR_LAST_2_C (20 + LOG_HDR_RESERVED_CODES_BASE_2_C) + +/* RLP Rx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_RX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x194 + LOG_1X_BASE_C) + +/* RLP Tx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_TX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x195 + LOG_1X_BASE_C) + +/* RLP Rx internal details */ +#define LOG_RLP_RX_INTERNAL_DETAILS_C (0x196 + LOG_1X_BASE_C) + +/* RLP Tx internal details */ +#define LOG_RLP_TX_INTERNAL_DETAILS_C (0x197 + LOG_1X_BASE_C) + +/* MPEG4 Clip Statistics version 3 */ +#define LOG_MPEG4_CLIP_STATS_VER3_C (0x198 + LOG_1X_BASE_C) + +/* Mobile IP Performance */ +#define LOG_MOBILE_IP_PERFORMANCE_C (0x199 + LOG_1X_BASE_C) + +/* 410-430 Searcher reserved logs */ +#define LOG_SEARCHER_RESERVED_CODES_BASE_C (0x19A + LOG_1X_BASE_C) +#define LOG_SEARCHER_LAST_2_C (21 + LOG_SEARCHER_RESERVED_CODES_BASE_C) + +/* 432-480 QTV reserved logs */ +#define LOG_QTV2_RESERVED_CODES_BASE_C (0x1B0 + LOG_1X_BASE_C) +#define LOG_QTV2_LAST_C (48 + LOG_QTV2_RESERVED_CODES_BASE_C) + +#define LOG_QTV_PDS2_STATS (0x1B6 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_REQUEST (0x1B7 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_HEADER (0x1B8 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_PCKT (0x1B9 + LOG_1X_BASE_C) +#define LOG_QTV_CMX_AUDIO_INPUT_DATA_C (0x1BA + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_OPTIONS_C (0x1BB + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_GET_PARAMETER_C (0x1BC + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_SET_PARAMETER_C (0x1BD + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_BITSTREAM (0x1BE + LOG_1X_BASE_C) +#define LOG_ARM_VIDEO_DECODE_STATS (0x1BF + LOG_1X_BASE_C) +#define LOG_QTV_DSP_SLICE_BUFFER_C (0x1C0 + LOG_1X_BASE_C) +#define LOG_QTV_CMD_LOGGING_C (0x1C1 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_FRAME_PTS_INFO_C (0x1C2 + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_FRAME_DECODE_INFO_C (0x1C3 + LOG_1X_BASE_C) +#define LOG_QTV_RTCP_COMPOUND_RR_C (0x1C4 + LOG_1X_BASE_C) +#define LOG_QTV_FRAME_BUFFER_RELEASE_REASON_C (0x1C5 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_CHANNEL_SWITCH_FRAME_C (0x1C6 + LOG_1X_BASE_C) +#define LOG_QTV_RTP_DECRYPTED_PKT_C (0x1C7 + LOG_1X_BASE_C) +#define LOG_QTV_PCR_DRIFT_RATE_C (0x1C8 + LOG_1X_BASE_C) + +/* GPS PDSM logs */ +#define LOG_PDSM_POSITION_REPORT_CALLBACK_C (0x1E1 + LOG_1X_BASE_C) +#define LOG_PDSM_PD_EVENT_CALLBACK_C (0x1E2 + LOG_1X_BASE_C) +#define LOG_PDSM_PA_EVENT_CALLBACK_C (0x1E3 + LOG_1X_BASE_C) +#define LOG_PDSM_NOTIFY_VERIFY_REQUEST_C (0x1E4 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED1_C (0x1E5 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED2_C (0x1E6 + LOG_1X_BASE_C) + +/* Searcher Demodulation Status log */ +#define LOG_SRCH_DEMOD_STATUS_C (0x1E7 + LOG_1X_BASE_C) + +/* Searcher Call Statistics log */ +#define LOG_SRCH_CALL_STATISTICS_C (0x1E8 + LOG_1X_BASE_C) + +/* GPS MS-MPC Forward link */ +#define LOG_MS_MPC_FWD_LINK_C (0x1E9 + LOG_1X_BASE_C) + +/* GPS MS-MPC Reverse link */ +#define LOG_MS_MPC_REV_LINK_C (0x1EA + LOG_1X_BASE_C) + +/* Protocol Services Data */ +#define LOG_DATA_PROTOCOL_LOGGING_C (0x1EB + LOG_1X_BASE_C) + +/* MediaFLO reserved log codes */ +#define LOG_MFLO_RESERVED_CODES_BASE_C (0x1EC + LOG_1X_BASE_C) +#define LOG_MFLO_LAST_C (99 + LOG_MFLO_RESERVED_CODES_BASE_C) + +/* GPS demodulation tracking header info */ +#define LOG_GPS_DEMOD_TRACKING_HEADER_C (0x250 + LOG_1X_BASE_C) + +/* GPS demodulation tracking results */ +#define LOG_GPS_DEMOD_TRACKING_C (0x251 + LOG_1X_BASE_C) + +/* GPS bit edge logs from demod tracking */ +#define LOG_GPS_DEMOD_BIT_EDGE_C (0x252 + LOG_1X_BASE_C) + +/* GPS demodulation soft decisions */ +#define LOG_GPS_DEMOD_SOFT_DECISIONS_C (0x253 + LOG_1X_BASE_C) + +/* GPS post-processed demod tracking results */ +#define LOG_GPS_DEMOD_TRACKING_POST_PROC_C (0x254 + LOG_1X_BASE_C) + +/* GPS subframe log */ +#define LOG_GPS_DEMOD_SUBFRAME_C (0x255 + LOG_1X_BASE_C) + +/* F-CPCCH Quality Information */ +#define LOG_F_CPCCH_QUALITY_INFO_C (0x256 + LOG_1X_BASE_C) + +/* Reverse PDCCH/PDCH Frame Information */ +#define LOG_R_PDCCH_R_PDCH_FRAME_INFO_C (0x257 + LOG_1X_BASE_C) + +/* Forward G Channel Information */ +#define LOG_F_GCH_INFO_C (0x258 + LOG_1X_BASE_C) + +/* Forward G Channel Frame Information */ +#define LOG_F_GCH_FRAME_INFO_C (0x259 + LOG_1X_BASE_C) + +/* Forward RC Channel Information */ +#define LOG_F_RCCH_INFO_C (0x25A + LOG_1X_BASE_C) + +/* Forward ACK Channel Information */ +#define LOG_F_ACKCH_INFO_C (0x25B + LOG_1X_BASE_C) + +/* Forward ACK Channel ACKDA Information */ +#define LOG_F_ACKCH_ACKDA_C (0x25C + LOG_1X_BASE_C) + +/* Reverse REQ Channel Information */ +#define LOG_R_REQCH_INFO_C (0x25D + LOG_1X_BASE_C) + +/* Sleep Task Statistics */ +#define LOG_SLEEP_STATS_C (0x25E + LOG_1X_BASE_C) + +/* Sleep controller statistics 1X */ +#define LOG_1X_SLEEP_CONTROLLER_STATS_C (0x25F + LOG_1X_BASE_C) + +/* Sleep controller statistics HDR */ +#define LOG_HDR_SLEEP_CONTROLLER_STATS_C (0x260 + LOG_1X_BASE_C) + +/* Sleep controller statistics GSM */ +#define LOG_GSM_SLEEP_CONTROLLER_STATS_C (0x261 + LOG_1X_BASE_C) + +/* Sleep controller statistics WCDMA */ +#define LOG_WCDMA_SLEEP_CONTROLLER_STATS_C (0x262 + LOG_1X_BASE_C) + +/* Sleep task and controller reserved logs */ +#define LOG_SLEEP_APPS_STATS_C (0x263 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED2_C (0x264 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED3_C (0x265 + LOG_1X_BASE_C) + +/* DV Information placeholder channel logs */ +#define LOG_PDCCH_LO_SELECTED_C (0x266 + LOG_1X_BASE_C) +#define LOG_PDCCH_HI_SELECTED_C (0x267 + LOG_1X_BASE_C) +#define LOG_WALSH_SELECTED_C (0x268 + LOG_1X_BASE_C) +#define LOG_PDCH_BE_SELECTED_C (0x269 + LOG_1X_BASE_C) +#define LOG_PDCCH_LLR_SELECTED_C (0x26A + LOG_1X_BASE_C) +#define LOG_CQI_ACK_LO_SELECTED_C (0x26B + LOG_1X_BASE_C) +#define LOG_CQI_ACK_HI_SELECTED_C (0x26C + LOG_1X_BASE_C) +#define LOG_RL_GAIN_SELECTED_C (0x26D + LOG_1X_BASE_C) +#define LOG_PDCCH0_SNDA_SELECTED_C (0x26E + LOG_1X_BASE_C) +#define LOG_PDCCH1_SNDA_SELECTED_C (0x26F + LOG_1X_BASE_C) + +/* 624 WMS Message List */ +#define LOG_WMS_MESSAGE_LIST_C (0x270 + LOG_1X_BASE_C) + +/* 625 Multimode Generic SIM Driver Interface */ +#define LOG_MM_GENERIC_SIM_DRIVER_C (0x271 + LOG_1X_BASE_C) + +/* 626 Generic SIM Toolkit Task */ +#define LOG_GENERIC_SIM_TOOLKIT_TASK_C (0x272 + LOG_1X_BASE_C) + +/* 627 Call Manager Phone events log */ +#define LOG_CM_PH_EVENT_C (0x273 + LOG_1X_BASE_C) + +/* 628 WMS Set Message List */ +#define LOG_WMS_SET_MESSAGE_LIST_C (0x274 + LOG_1X_BASE_C) + +/* 629-704 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_3_C (0x275 + LOG_1X_BASE_C) +#define LOG_HDR_LAST_3_C (75 + LOG_HDR_RESERVED_CODES_BASE_3_C) + +/* 705 Call Manager call event log */ +#define LOG_CM_CALL_EVENT_C (0x2C1 + LOG_1X_BASE_C) + +/* 706-738 QVP reserved logs */ +#define LOG_QVP_RESERVED_CODES_BASE_C (0x2C2 + LOG_1X_BASE_C) +#define LOG_QVP_LAST_C (32 + LOG_QVP_RESERVED_CODES_BASE_C) + +/* 739 GPS PE Position Report log */ +#define LOG_GPS_PE_POSITION_REPORT_C (0x2E3 + LOG_1X_BASE_C) + +/* 740 GPS PE Position Report Extended log */ +#define LOG_GPS_PE_POSITION_REPORT_EXT_C (0x2E4 + LOG_1X_BASE_C) + +/* 741 log */ +#define LOG_MDDI_HOST_STATS_C (0x2E5 + LOG_1X_BASE_C) + +/* GPS Decoded Ephemeris */ +#define LOG_GPS_DECODED_EPHEMERIS_C (0x2E6 + LOG_1X_BASE_C) + +/* GPS Decoded Almanac */ +#define LOG_GPS_DECODED_ALMANAC_C (0x2E7 + LOG_1X_BASE_C) + +/* Transceiver Resource Manager */ +#define LOG_TRANSCEIVER_RESOURCE_MGR_C (0x2E8 + LOG_1X_BASE_C) + +/* GPS Position Engine Info */ +#define LOG_GPS_POSITION_ENGINE_INFO_C (0x2E9 + LOG_1X_BASE_C) + +/* 746-810 RAPTOR reserved log range */ +#define LOG_RAPTOR_RESERVED_CODES_BASE_C (0x2EA + LOG_1X_BASE_C) +#define LOG_RAPTOR_LAST_C (64 + LOG_RAPTOR_RESERVED_CODES_BASE_C) + +/* QOS Specification Logging */ + +/* QOS Requested Log */ +#define LOG_QOS_REQUESTED_C (0x32B + LOG_1X_BASE_C) + +/* QOS Granted Log */ +#define LOG_QOS_GRANTED_C (0x32C + LOG_1X_BASE_C) + +/* QOS State Log */ +#define LOG_QOS_STATE_C (0x32D + LOG_1X_BASE_C) + +#define LOG_QOS_MODIFIED_C (0x32E + LOG_1X_BASE_C) + +#define LOG_QDJ_ENQUEUE_C (0x32F + LOG_1X_BASE_C) +#define LOG_QDJ_DEQUEUE_C (0x330 + LOG_1X_BASE_C) +#define LOG_QDJ_UPDATE_C (0x331 + LOG_1X_BASE_C) +#define LOG_QDTX_ENCODER_C (0x332 + LOG_1X_BASE_C) +#define LOG_QDTX_DECODER_C (0x333 + LOG_1X_BASE_C) + +#define LOG_PORT_ASSIGNMENT_STATUS_C (0x334 + LOG_1X_BASE_C) + +/* Protocol Services reserved log codes */ +#define LOG_PS_RESERVED_CODES_BASE_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_LAST_C (25 + LOG_PS_RESERVED_C) + +#define LOG_PS_STAT_IP_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV4_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV6_C (0x336 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV4_C (0x337 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV6_C (0x338 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_TCP_C (0x339 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_UDP_C (0x33A + LOG_1X_BASE_C) + +/* Protocol Services describe all TCP instances */ +#define LOG_PS_STAT_DESC_ALL_TCP_INST_C (0x33B + LOG_1X_BASE_C) + +/* Protocol Services describe all memory pool instances */ +#define LOG_PS_STAT_DESC_ALL_MEM_POOL_INST_C (0x33C + LOG_1X_BASE_C) + +/* Protocol Services describe all IFACE instances */ +#define LOG_PS_STAT_DESC_ALL_IFACE_INST_C (0x33D + LOG_1X_BASE_C) + +/* Protocol Services describe all PPP instances */ +#define LOG_PS_STAT_DESC_ALL_PPP_INST_C (0x33E + LOG_1X_BASE_C) + +/* Protocol Services describe all ARP instances */ +#define LOG_PS_STAT_DESC_ALL_ARP_INST_C (0x33F + LOG_1X_BASE_C) + +/* Protocol Services describe delta instance */ +#define LOG_PS_STAT_DESC_DELTA_INST_C (0x340 + LOG_1X_BASE_C) + +/* Protocol Services instance TCP statistics */ +#define LOG_PS_STAT_TCP_INST_C (0x341 + LOG_1X_BASE_C) + +/* Protocol Services instance UDP statistics */ +#define LOG_PS_STAT_UDP_INST_C (0x342 + LOG_1X_BASE_C) + +/* Protocol Services instance PPP statistics */ +#define LOG_PS_STAT_PPP_INST_C (0x343 + LOG_1X_BASE_C) + +/* Protocol Services instance IFACE statistics */ +#define LOG_PS_STAT_IFACE_INST_C (0x344 + LOG_1X_BASE_C) + +/* Protocol Services instance memory statistics */ +#define LOG_PS_STAT_MEM_INST_C (0x345 + LOG_1X_BASE_C) + +/* Protocol Services instance flow statistics */ +#define LOG_PS_STAT_FLOW_INST_C (0x346 + LOG_1X_BASE_C) + +/* Protocol Services instance physical link statistics */ +#define LOG_PS_STAT_PHYS_LINK_INST_C (0x347 + LOG_1X_BASE_C) + +/* Protocol Services instance ARP statistics */ +#define LOG_PS_STAT_ARP_INST_C (0x348 + LOG_1X_BASE_C) + +/* Protocol Services instance LLC statistics */ +#define LOG_PS_STAT_LLC_INST_C (0x349 + LOG_1X_BASE_C) + +/* Protocol Services instance IPHC statistics */ +#define LOG_PS_STAT_IPHC_INST_C (0x34A + LOG_1X_BASE_C) + +/* Protocol Services instance ROHC statistics */ +#define LOG_PS_STAT_ROHC_INST_C (0x34B + LOG_1X_BASE_C) + +/* Protocol Services instance RSVP statistics */ +#define LOG_PS_STAT_RSVP_INST_C (0x34C + LOG_1X_BASE_C) + +/* Protocol Services describe all LLC instances */ +#define LOG_PS_STAT_DESC_ALL_LLC_INST_C (0x34D + LOG_1X_BASE_C) + +/* Protocol Services describe all RSVP instances */ +#define LOG_PS_STAT_DESC_ALL_RSVP_INST_C (0x34E + LOG_1X_BASE_C) + +/* Call Manager Serving System event log */ +#define LOG_CM_SS_EVENT_C (0x34F + LOG_1X_BASE_C) + +/* VcTcxo manager’s automatic frequency control log */ +#define LOG_TCXOMGR_AFC_DATA_C (0x350 + LOG_1X_BASE_C) + +/* Clock transactions and general clocks status log */ +#define LOG_CLOCK_C (0x351 + LOG_1X_BASE_C) + +/* GPS search processed peak results and their associated search parameters */ +#define LOG_GPS_PROCESSED_PEAK_C (0x352 + LOG_1X_BASE_C) + +#define LOG_MDSP_LOG_CHUNKS_C (0x353 + LOG_1X_BASE_C) + +/* Periodic RSSI update log */ +#define LOG_WLAN_RSSI_UPDATE_C (0x354 + LOG_1X_BASE_C) + +/* Periodic Link Layer statistics log */ +#define LOG_WLAN_LL_STAT_C (0x355 + LOG_1X_BASE_C) + +/* QOS Extended State Log */ +#define LOG_QOS_STATE_EX_C (0x356 + LOG_1X_BASE_C) + +/* Bluetooth host HCI transmitted data */ +#define LOG_BT_HOST_HCI_TX_C (0x357 + LOG_1X_BASE_C) + +/* Bluetooth host HCI received data */ +#define LOG_BT_HOST_HCI_RX_C (0x358 + LOG_1X_BASE_C) + +/* Internal - GPS PE Position Report Part 3 */ +#define LOG_GPS_PE_POSITION_REPORT_PART3_C (0x359 + LOG_1X_BASE_C) + +/* Extended log code which logs requested QoS */ +#define LOG_QOS_REQUESTED_EX_C (0x35A + LOG_1X_BASE_C) + +/* Extended log code which logs granted QoS */ +#define LOG_QOS_GRANTED_EX_C (0x35B + LOG_1X_BASE_C) + +/* Extended log code which logs modified QoS */ +#define LOG_QOS_MODIFIED_EX_C (0x35C + LOG_1X_BASE_C) + +/* Bus Monitor Profiling Info */ +#define LOG_BUS_MON_PROF_INFO_C (0x35D + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Search results */ +#define LOG_SRCH_PPM_RES_VER_2_C (0x35E + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Data Base */ +#define LOG_SRCH_PPM_DB_VER_2_C (0x35F + LOG_1X_BASE_C) + +/* Pilot Phase Measurement state machine */ +#define LOG_PPM_SM_C (0x360 + LOG_1X_BASE_C) + +/* Robust Header Compression - Compressor */ +#define LOG_ROHC_COMPRESSOR_C (0x361 + LOG_1X_BASE_C) + +/* Robust Header Compression - Decompressor */ +#define LOG_ROHC_DECOMPRESSOR_C (0x362 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Compressor */ +#define LOG_ROHC_FEEDBACK_COMPRESSOR_C (0x363 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Decompressor */ +#define LOG_ROHC_FEEDBACK_DECOMPRESSOR_C (0x364 + LOG_1X_BASE_C) + +/* Bluetooth HCI commands */ +#define LOG_BT_HCI_CMD_C (0x365 + LOG_1X_BASE_C) + +/* Bluetooth HCI events */ +#define LOG_BT_HCI_EV_C (0x366 + LOG_1X_BASE_C) + +/* Bluetooth HCI Transmitted ACL data */ +#define LOG_BT_HCI_TX_ACL_C (0x367 + LOG_1X_BASE_C) + +/* Bluetooth HCI Received ACL data */ +#define LOG_BT_HCI_RX_ACL_C (0x368 + LOG_1X_BASE_C) + +/* Bluetooth SOC H4 Deep Sleep */ +#define LOG_BT_SOC_H4DS_C (0x369 + LOG_1X_BASE_C) + +/* UMTS to CDMA Handover Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_MSG_C (0x36A + LOG_1X_BASE_C) + +/* Graphic Event Data */ +#define LOG_PROFILER_GRAPHIC_DATA_C (0x36B + LOG_1X_BASE_C) + +/* Audio Event Data */ +#define LOG_PROFILER_AUDIO_DATA_C (0x36C + LOG_1X_BASE_C) + +/* GPS Spectral Information */ +#define LOG_GPS_SPECTRAL_INFO_C (0x36D + LOG_1X_BASE_C) + +/* AHB Performance Monitor LOG data */ +#define LOG_APM_C (0x36E + LOG_1X_BASE_C) + +/* GPS Clock Report */ +#define LOG_CONVERGED_GPS_CLOCK_REPORT_C (0x36F + LOG_1X_BASE_C) + +/* GPS Position Report */ +#define LOG_CONVERGED_GPS_POSITION_REPORT_C (0x370 + LOG_1X_BASE_C) + +/* GPS Measurement Report */ +#define LOG_CONVERGED_GPS_MEASUREMENT_REPORT_C (0x371 + LOG_1X_BASE_C) + +/* GPS RF Status Report */ +#define LOG_CONVERGED_GPS_RF_STATUS_REPORT_C (0x372 + LOG_1X_BASE_C) + +/* VOIP To CDMA Handover Message - Obsoleted by 0x138B - 0x138D */ +#define LOG_VOIP_TO_CDMA_HANDOVER_MSG_C (0x373 + LOG_1X_BASE_C) + +/* GPS Prescribed Dwell Result */ +#define LOG_GPS_PRESCRIBED_DWELL_RESULT_C (0x374 + LOG_1X_BASE_C) + +/* CGPS IPC Data */ +#define LOG_CGPS_IPC_DATA_C (0x375 + LOG_1X_BASE_C) + +/* CGPS Non IPC Data */ +#define LOG_CGPS_NON_IPC_DATA_C (0x376 + LOG_1X_BASE_C) + +/* CGPS Session Report */ +#define LOG_CGPS_REP_EVT_LOG_PACKET_C (0x377 + LOG_1X_BASE_C) + +/* CGPS PDSM Get Position */ +#define LOG_CGPS_PDSM_GET_POSITION_C (0x378 + LOG_1X_BASE_C) + +/* CGPS PDSM Set Parameters */ +#define LOG_CGPS_PDSM_SET_PARAMETERS_C (0x379 + LOG_1X_BASE_C) + +/* CGPS PDSM End Session */ +#define LOG_CGPS_PDSM_END_SESSION_C (0x37A + LOG_1X_BASE_C) + +/* CGPS PDSM Notify Verify Response */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_RESP_C (0x37B + LOG_1X_BASE_C) + +/* CGPS PDSM Position Report Callback */ +#define LOG_CGPS_PDSM_POSITION_REPORT_CALLBACK_C (0x37C + LOG_1X_BASE_C) + +/* CGPS PDSM PD Event Callback */ +#define LOG_CGPS_PDSM_PD_EVENT_CALLBACK_C (0x37D + LOG_1X_BASE_C) + +/* CGPS PDSM PA Event Callback */ +#define LOG_CGPS_PDSM_PA_EVENT_CALLBACK_C (0x37E + LOG_1X_BASE_C) + +/* CGPS PDSM Notify Verify Request Callback */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_REQUEST_C (0x37F + LOG_1X_BASE_C) + +/* CGPS PDSM PD Command Error Callback */ +#define LOG_CGPS_PDSM_PD_CMD_ERR_CALLBACK_C (0x380 + LOG_1X_BASE_C) + +/* CGPS PDSM PA Command Error Callback */ +#define LOG_CGPS_PDSM_PA_CMD_ERR_CALLBACK_C (0x381 + LOG_1X_BASE_C) + +/* CGPS PDSM Position Error */ +#define LOG_CGPS_PDSM_POS_ERROR_C (0x382 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Position Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_POS_REPORT_C (0x383 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status NMEA Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_NMEA_REPORT_C (0x384 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Measurement Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x385 + LOG_1X_BASE_C) + +/* CGPS Report Server TX Packet */ +#define LOG_CGPS_REP_SVR_TX_LOG_PACKET_C (0x386 + LOG_1X_BASE_C) + +/* CGPS Report Server RX Packet */ +#define LOG_CGPS_REP_SVR_RX_LOG_PACKET_C (0x387 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Paging Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_PCH_MSG_C (0x388 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Traffic Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_TCH_MSG_C (0x389 + LOG_1X_BASE_C) + +/* Converged GPS IQ Report */ +#define LOG_CONVERGED_GPS_IQ_REPORT_C (0x38A + LOG_1X_BASE_C) + +/* VOIP To CDMA Paging Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_PCH_HANDOVER_MSG_C (0x38B + LOG_1X_BASE_C) + +/* VOIP To CDMA Access Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_ACH_HANDOVER_MSG_C (0x38C + LOG_1X_BASE_C) + +/* VOIP To CDMA Forward Traffic Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_FTC_HANDOVER_MSG_C (0x38D + LOG_1X_BASE_C) + +/* QMI reserved logs */ +#define LOG_QMI_RESERVED_CODES_BASE_C (0x38E + LOG_1X_BASE_C) +#define LOG_QMI_LAST_C (32 + LOG_QMI_RESERVED_CODES_BASE_C) + +/* QOS Info Code Update Log */ +#define LOG_QOS_INFO_CODE_UPDATE_C (0x3AF + LOG_1X_BASE_C) + +/* Transmit(Uplink) Vocoder PCM Packet Log */ +#define LOG_TX_PCM_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Audio Vocoder Data Paths */ +#define LOG_AUDVOC_DATA_PATHS_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Receive(Downlink) Vocoder PCM Packet Log */ +#define LOG_RX_PCM_PACKET_C (0x3B1 + LOG_1X_BASE_C) + +/* CRC of YUV frame log */ +#define LOG_DEC_CRC_FRAME_C (0x3B2 + LOG_1X_BASE_C) + +/* FLUTE Session Information */ +#define LOG_FLUTE_SESSION_INFO_C (0x3B3 + LOG_1X_BASE_C) + +/* FLUTE ADP File Information */ +#define LOG_FLUTE_ADP_FILE_INFO_C (0x3B4 + LOG_1X_BASE_C) + +/* FLUTE File Request Information */ +#define LOG_FLUTE_FILE_REQ_INFO_C (0x3B5 + LOG_1X_BASE_C) + +/* FLUTE FDT Instance Information */ +#define LOG_FLUTE_FDT_INST_C (0x3B6 + LOG_1X_BASE_C) + +/* FLUTE FDT Information */ +#define LOG_FLUTE_FDT_INFO_C (0x3B7 + LOG_1X_BASE_C) + +/* FLUTE File Log Packet Information */ +#define LOG_FLUTE_FILE_INFO_C (0x3B8 + LOG_1X_BASE_C) + +/* 3G 1X Parameter Overhead Information */ +#define LOG_VOIP_TO_CDMA_3G1X_PARAMETERS_C (0x3B9 + LOG_1X_BASE_C) + +/* CGPS ME Job Info */ +#define LOG_CGPS_ME_JOB_INFO_C (0x3BA + LOG_1X_BASE_C) + +/* CGPS ME SV Lists */ +#define LOG_CPGS_ME_SV_LISTS_C (0x3BB + LOG_1X_BASE_C) + +/* Flexible Profiling Status */ +#define LOG_PROFDIAG_GEN_STATUS_C (0x3BC + LOG_1X_BASE_C) + +/* Flexible Profiling Results */ +#define LOG_PROFDIAG_GEN_PROF_C (0x3BD + LOG_1X_BASE_C) + +/* FLUTE ADP File Content Log Packet Information */ +#define LOG_FLUTE_ADP_FILE_C (0x3BE + LOG_1X_BASE_C) + +/* FLUTE FDT Instance File Content Log Packet Information */ +#define LOG_FLUTE_FDT_INST_FILE_C (0x3BF + LOG_1X_BASE_C) + +/* FLUTE FDT Entries Information */ +#define LOG_FLUTE_FDT_ENTRIES_INFO_C (0x3C0 + LOG_1X_BASE_C) + +/* FLUTE File Contents Log Packet Information */ +#define LOG_FLUTE_FILE_C (0x3C1 + LOG_1X_BASE_C) + +/* CGPS ME Time-Transfer Info */ +#define LOG_CGPS_ME_TIME_TRANSFER_INFO_C (0x3C2 + LOG_1X_BASE_C) + +/* CGPS ME UMTS Time-Tagging Info */ +#define LOG_CGPS_ME_UMTS_TIME_TAGGING_INFO_C (0x3C3 + LOG_1X_BASE_C) + +/* CGPS ME Generic Time Estimate Put lnfo */ +#define LOG_CGPS_ME_TIME_EST_PUT_INFO_C (0x3C4 + LOG_1X_BASE_C) + +/* CGPS ME Generic Freq Estimate Put lnfo */ +#define LOG_CGPS_ME_FREQ_EST_PUT_INFO_C (0x3C5 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Report */ +#define LOG_CGPS_SLOW_CLOCK_REPORT_C (0x3C6 + LOG_1X_BASE_C) + +/* Converged GPS Medium Grid */ +#define LOG_CONVERGED_GPS_MEDIUM_GRID_C (0x3C7 + LOG_1X_BASE_C) + +/* Static information about the driver or device */ +#define LOG_SNSD_INFO_C (0x3C8 + LOG_1X_BASE_C) + +/* Dynamic state information about the device or driver */ +#define LOG_SNSD_STATE_C (0x3C9 + LOG_1X_BASE_C) + +/* Data from a driver */ +#define LOG_SNSD_DATA (0x3CA + LOG_1X_BASE_C) +#define LOG_SNSD_DATA_C (0x3CA + LOG_1X_BASE_C) + +/* CGPS Cell DB Cell Change Info */ +#define LOG_CGPS_CELLDB_CELL_CHANGE_INFO_C (0x3CB + LOG_1X_BASE_C) + +/* xScalar YUV frame log */ +#define LOG_DEC_XSCALE_YUV_FRAME_C (0x3CC + LOG_1X_BASE_C) + +/* CRC of xScaled YUV frame log */ +#define LOG_DEC_XSCALE_CRC_FRAME_C (0x3CD + LOG_1X_BASE_C) + +/* CGPS Frequency Estimate Report */ +#define LOG_CGPS_FREQ_EST_REPORT_C (0x3CE + LOG_1X_BASE_C) + +/* GPS DCME Srch Job Completed */ +#define LOG_GPS_DCME_SRCH_JOB_COMPLETED_C (0x3CF + LOG_1X_BASE_C) + +/* CGPS ME Fastscan results */ +#define LOG_CGPS_ME_FASTSCAN_RESULTS_C (0x3D0 + LOG_1X_BASE_C) + +/* XO frequency Estimation log */ +#define LOG_XO_FREQ_EST_C (0x3D1 + LOG_1X_BASE_C) + +/* Tcxomgr field calibration data */ +#define LOG_TCXOMGR_FIELD_CAL_C (0x3D2 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Attempt */ +#define LOG_UMBCP_CONNECTION_ATTEMPT_C (0x3D3 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Release */ +#define LOG_UMBCP_CONNECTION_RELEASE_C (0x3D4 + LOG_1X_BASE_C) + +/* UMB Call Processing Page Message */ +#define LOG_UMBCP_PAGE_MESSAGE_C (0x3D5 + LOG_1X_BASE_C) + +/* UMB Call Processing OVHD Information */ +#define LOG_UMBCP_OVHD_INFO_C (0x3D6 + LOG_1X_BASE_C) + +/* UMB Call Processing Session Attempt */ +#define LOG_UMBCP_SESSION_ATTEMPT_C (0x3D7 + LOG_1X_BASE_C) + +/* UMB Call Processing Route Information */ +#define LOG_UMBCP_ROUTE_INFO_C (0x3D8 + LOG_1X_BASE_C) + +/* UMB Call Processing State Information */ +#define LOG_UMBCP_STATE_INFO_C (0x3D9 + LOG_1X_BASE_C) + +/* UMB Call Processing SNP */ +#define LOG_UMBCP_SNP_C (0x3DA + LOG_1X_BASE_C) + +/* CGPS Session Early Exit Decision */ +#define LOG_CGPS_SESSION_EARLY_EXIT_DECISION_C (0x3DB + LOG_1X_BASE_C) + +/* GPS RF Linearity Status */ +#define LOG_CGPS_ME_RF_LINEARITY_INFO_C (0x3DC + LOG_1X_BASE_C) + +/* CGPS ME 5ms IQ Sums */ +#define LOG_CGPS_ME_5MS_IQ_SUMS_C (0x3DD + LOG_1X_BASE_C) + +/* CGPS ME 20ms IQ Sums */ +#define LOG_CPGS_ME_20MS_IQ_SUMS_C (0x3DE + LOG_1X_BASE_C) + +/* ROHC Compressor Statistics */ +#define LOG_ROHC_COMPRESSOR_STATS_C (0x3DF + LOG_1X_BASE_C) + +/* ROHC Decompressor Statistics */ +#define LOG_ROHC_DECOMPRESSOR_STATS_C (0x3E0 + LOG_1X_BASE_C) + +/* Sensors - Kalman filter information */ +#define LOG_SENSOR_KF_INFO_C (0x3E1 + LOG_1X_BASE_C) + +/* Sensors - Integrated measurements */ +#define LOG_SENSOR_INT_MEAS_C (0x3E2 + LOG_1X_BASE_C) + +/* Sensors - Bias calibration values */ +#define LOG_SENSOR_BIAS_CALIBRATION_C (0x3E3 + LOG_1X_BASE_C) + +/* Log codes 0x13E4-0x13E7 are not following standard log naming convention */ + +/* DTV ISDB-T Transport Stream Packets */ +#define LOG_DTV_ISDB_TS_PACKETS (0x3E4 + LOG_1X_BASE_C) + +/* DTV ISDB-T PES Packets */ +#define LOG_DTV_ISDB_PES_PACKETS (0x3E5 + LOG_1X_BASE_C) + +/* DTV ISDB-T Sections */ +#define LOG_DTV_ISDB_SECTIONS (0x3E6 + LOG_1X_BASE_C) + +/* DTV ISDB-T Buffering */ +#define LOG_DTV_ISDB_BUFFERING (0x3E7 + LOG_1X_BASE_C) + +/* WLAN System Acquisition and Handoff */ +#define LOG_WLAN_SYS_ACQ_HO_C (0x3E8 + LOG_1X_BASE_C) + +/* WLAN General Configurable Parameters */ +#define LOG_WLAN_GEN_CONFIG_PARAMS_C (0x3E9 + LOG_1X_BASE_C) + +/* UMB Physical Layer Channel and Interference Estimation */ +#define LOG_UMB_PHY_RX_DPICH_CIE_C (0x3EA + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (Low) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_LOW_C (0x3EB + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (High) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_HIGH_C (0x3EC + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Decoder */ +#define LOG_UMB_PHY_RX_DCH_DECODER_C (0x3ED + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Statistics */ +#define LOG_UMB_PHY_DCH_STATISTICS_C (0x3EE + LOG_1X_BASE_C) + +/* UMB Physical Layer CqiPich Processing */ +#define LOG_UMB_PHY_RX_CQIPICH_C (0x3EF + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CqiPich (High) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_HIGH_C (0x3F0 + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CquiPich (Low) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_LOW_C (0x3F1 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (High) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_HIGH_C (0x3F2 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (Low) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_LOW_C (0x3F3 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator */ +#define LOG_UMB_PHY_TX_PICH_CONFIG_C (0x3F4 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (High) */ +#define LOG_UMB_PHY_TX_ACK_HIGH_C (0x3F5 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (Low) */ +#define LOG_UMB_PHY_TX_ACK_LOW_C (0x3F6 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-PICH */ +#define LOG_UMB_PHY_TX_PICH_C (0x3F7 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACH (Access) */ +#define LOG_UMB_PHY_TX_ACH_C (0x3F8 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (High) */ +#define LOG_UMB_PHY_TX_ODCCH_HIGH_C (0x3F9 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (Low) */ +#define LOG_UMB_PHY_TX_ODCCH_LOW_C (0x3FA + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-CDCCH */ +#define LOG_UMB_PHY_TX_RCDCCH_CONFIG_C (0x3FB + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_NONFLSS_CQICH_C (0x3FC + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_FLSS_CQICH_C (0x3FD + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PACH sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PAHCH_C (0x3FE + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for REQ sent on RCDCCH */ +#define LOG_UMB_PHY_TX_REQCH_C (0x3FF + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PSD sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PSDCH_C (0x400 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-DCH */ +#define LOG_UMB_PHY_TX_DCH_C (0x401 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time/Frequency/RxPower Estimate */ +#define LOG_UMB_PHY_RX_TIME_FREQ_POWER_ESTIMATE_C (0x402 + LOG_1X_BASE_C) + +/* UMB Physical Layer FLCS Processing */ +#define LOG_UMB_PHY_RX_FLCS_PROCESSING_C (0x403 + LOG_1X_BASE_C) + +/* UMB Physical Layer PBCCH Processing */ +#define LOG_UMB_PHY_RX_PBCCH_PROCESSING_C (0x404 + LOG_1X_BASE_C) + +/* UMB Physical Layer SBCCH Processing */ +#define LOG_UMB_PHY_RX_SBCCH_PROCESSING_C (0x405 + LOG_1X_BASE_C) + +/* UMB Physical Layer QPCH Processing */ +#define LOG_UMB_PHY_RX_QPCH_PROCESSING_C (0x406 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble SBCCH/QPCH) */ +#define LOG_UMB_PHY_RX_SBCCH_DEMOD_C (0x407 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble PBCCH) */ +#define LOG_UMB_PHY_RX_PBCCH_DEMOD_C (0x408 + LOG_1X_BASE_C) + +/* UMB Physical Layer VCQI */ +#define LOG_UMB_PHY_RX_VCQI_C (0x409 + LOG_1X_BASE_C) + +/* UMB Physical Layer Acquisition Algorithm */ +#define LOG_UMB_PHY_RX_INITIAL_ACQUISITION_C (0x40A + LOG_1X_BASE_C) + +/* UMB Physical Layer Handoff Search Algorithm */ +#define LOG_UMB_PHY_RX_HANDOFF_SEARCH_C (0x40B + LOG_1X_BASE_C) + +/* UMB RF RFFE Configuration Info */ +#define LOG_UMB_AT_RFFE_CONFG_C (0x40C + LOG_1X_BASE_C) + +/* UMB RF Calibrated Values After Powerup */ +#define LOG_UMB_AT_RFFE_RX_CALIB_C (0x40D + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Acquisition Mode */ +#define LOG_UMB_AT_RFFE_RX_ACQ_C (0x40E + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Idle Mode */ +#define LOG_UMB_AT_RFFE_RX_IDLE_C (0x40F + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_C (0x410 + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode (FTM) */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_FTM_C (0x411 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Functionality */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_FUNCTIONALITY_C (0x412 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Response */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_RESPONSE_C (0x413 + LOG_1X_BASE_C) + +/* UMB RF RFFE TX Power Control */ +#define LOG_UMB_AT_RFFE_TX_BETA_SCALING_C (0x414 + LOG_1X_BASE_C) + +/* UMB Searcher Dump */ +#define LOG_UMB_SEARCHER_DUMP_C (0x415 + LOG_1X_BASE_C) + +/* UMB System Acquire */ +#define LOG_UMB_SYSTEM_ACQUIRE_C (0x416 + LOG_1X_BASE_C) + +/* UMB Set Maintenance */ +#define LOG_UMB_SET_MAINTENANCE_C (0x417 + LOG_1X_BASE_C) + +/* UMB QPCH */ +#define LOG_UMB_QPCH_C (0x418 + LOG_1X_BASE_C) + +/* UMB RLL Forward Partial RP Packet */ +#define LOG_UMB_RLL_FORWARD_PARTIAL_RP_C (0x419 + LOG_1X_BASE_C) + +/* UMB RLL Reverse Partial RP Packet */ +#define LOG_UMB_RLL_REVERSE_PARTIAL_RP_C (0x41A + LOG_1X_BASE_C) + +/* UMB RLL Forward Signal Packet */ +#define LOG_UMB_RLL_FORWARD_SIGNAL_C (0x41B + LOG_1X_BASE_C) + +/* UMB RLL Reverse Signal Packet */ +#define LOG_UMB_RLL_REVERSE_SIGNAL_C (0x41C + LOG_1X_BASE_C) + +/* UMB RLL Forward Statistics */ +#define LOG_UMB_RLL_FORWARD_STATS_C (0x41D + LOG_1X_BASE_C) + +/* UMB RLL Reverse Statistics */ +#define LOG_UMB_RLL_REVERSE_STATS_C (0x41E + LOG_1X_BASE_C) + +/* UMB RLL IRTP */ +#define LOG_UMB_RLL_IRTP_C (0x41F + LOG_1X_BASE_C) + +/* UMB AP Forward Link MAC Packets */ +#define LOG_UMB_AP_FL_MAC_PACKET_C (0x420 + LOG_1X_BASE_C) + +/* UMB AP Reverse Link MAC Packets */ +#define LOG_UMB_AP_RL_MAC_PACKET_C (0x421 + LOG_1X_BASE_C) + +/* GPS Performance Statistics log */ +#define LOG_CGPS_PERFORMANCE_STATS_C (0x422 + LOG_1X_BASE_C) + +/* UMB Searcher General Status */ +#define LOG_UMB_SRCH_GENERAL_STATUS_C (0x423 + LOG_1X_BASE_C) + +/* UMB Superframe Scheduler */ +#define LOG_UMB_SUPERFRAME_SCHEDULER_C (0x424 + LOG_1X_BASE_C) + +/* UMB Sector List */ +#define LOG_UMB_SECTOR_LIST_C (0x425 + LOG_1X_BASE_C) + +/* UMB MAC Access Attempt Command */ +#define LOG_UMB_MAC_ACCESS_ATTEMPT_CMD_C (0x426 + LOG_1X_BASE_C) + +/* UMB MAC Access Probe Information */ +#define LOG_UMB_MAC_ACCESS_PROBE_INFO_C (0x427 + LOG_1X_BASE_C) + +/* UMB MAC RTCMAC Package Information */ +#define LOG_UMB_MAC_RTCMAC_PKG_INFO_C (0x428 + LOG_1X_BASE_C) + +/* UMB MAC Super Frame Information */ +#define LOG_UMB_MAC_SI_INFO_C (0x429 + LOG_1X_BASE_C) + +/* UMB MAC Quick Channel Information */ +#define LOG_UMB_MAC_QCI_INFO_C (0x42A + LOG_1X_BASE_C) + +/* UMB MAC Paging Id List */ +#define LOG_UMB_MAC_PAGING_ID_LIST_C (0x42B + LOG_1X_BASE_C) + +/* UMB MAC Quick Paging Channel Information */ +#define LOG_UMB_MAC_QPCH_INFO_C (0x42C + LOG_1X_BASE_C) + +/* UMB MAC FTCMAC Information */ +#define LOG_UMB_MAC_FTCMAC_PKG_INFO_C (0x42D + LOG_1X_BASE_C) + +/* UMB MAC Access Grant Receiving */ +#define LOG_UMB_MAC_ACCESS_GRANT_C (0x42E + LOG_1X_BASE_C) + +/* UMB MAC Generic Debug Log */ +#define LOG_UMB_MAC_GEN_DEBUG_LOG_PKG_C (0x42F + LOG_1X_BASE_C) + +/* CGPS Frequency Bias Estimate */ +#define LOG_CGPS_MC_FREQ_BIAS_EST_C (0x430 + LOG_1X_BASE_C) + +/* UMB MAC Request Report Information Log */ +#define LOG_UMB_MAC_REQCH_REPORT_INFO_C (0x431 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Token Bucket Information Log */ +#define LOG_UMB_MAC_RLQOS_TOKEN_BUCKET_INFO_C (0x432 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Stream Information Log */ +#define LOG_UMB_MAC_RLQOS_STREAM_INFO_C (0x433 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Allotment Information Log */ +#define LOG_UMB_MAC_RLQOS_ALLOTMENT_INFO_C (0x434 + LOG_1X_BASE_C) + +/* UMB Searcher Recent State Machine Transactions */ +#define LOG_UMB_SRCH_STM_ACTIVITY_C (0x435 + LOG_1X_BASE_C) + +/* Performance Counters on ARM11 Profiling Information */ +#define LOG_ARM11_PERF_CNT_INFO_C (0x436 + LOG_1X_BASE_C) + +/* Protocol Services describe all flow instances */ +#define LOG_PS_STAT_DESC_ALL_FLOW_INST_C (0x437 + LOG_1X_BASE_C) + +/* Protocol Services describe all physical link instances */ +#define LOG_PS_STAT_DESC_ALL_PHYS_LINK_INST_C (0x438 + LOG_1X_BASE_C) + +/* Protocol Services describe all UDP instances */ +#define LOG_PS_STAT_DESC_ALL_UDP_INST_C (0x439 + LOG_1X_BASE_C) + +/* Searcher 4 Multi-Carrier HDR */ +#define LOG_SRCH4_MC_HDR_C (0x43A + LOG_1X_BASE_C) + +/* Protocol Services describe all IPHC instances */ +#define LOG_PS_STAT_DESC_ALL_IPHC_INST_C (0x43B + LOG_1X_BASE_C) + +/* Protocol Services describe all ROHC instances */ +#define LOG_PS_STAT_DESC_ALL_ROHC_INST_C (0x43C + LOG_1X_BASE_C) + +/* BCast security add program information */ +#define LOG_BCAST_SEC_ADD_PROGRAM_INFO_C (0x43D + LOG_1X_BASE_C) + +/* BCast security add program complete */ +#define LOG_BCAST_SEC_ADD_PROGRAM_COMPLETE_C (0x43E + LOG_1X_BASE_C) + +/* BCast security SDP parse */ +#define LOG_BCAST_SEC_SDP_PARSE_C (0x43F + LOG_1X_BASE_C) + +/* CGPS ME dynamic power optimization status */ +#define LOG_CGPS_ME_DPO_STATUS_C (0x440 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session start */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_START_C (0x441 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session stop */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_STOP_C (0x442 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session not started */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_NOT_STARTED_C (0x443 + LOG_1X_BASE_C) + +/* CGPS PDSM extern coarse position inject start */ +#define LOG_CGPS_PDSM_EXTERN_COARSE_POS_INJ_START_C (0x444 + LOG_1X_BASE_C) + +/* DTV ISDB-T TMCC information */ +#define LOG_DTV_ISDB_TMCC_C (0x445 + LOG_1X_BASE_C) + +/* RF development */ +#define LOG_RF_DEV_C (0x446 + LOG_1X_BASE_C) + +/* RF RFM API */ +#define LOG_RF_RFM_API_C (0x447 + LOG_1X_BASE_C) + +/* RF RFM state */ +#define LOG_RF_RFM_STATE_C (0x448 + LOG_1X_BASE_C) + +/* 1X RF Warmup */ +#define LOG_1X_RF_WARMUP_C (0x449 + LOG_1X_BASE_C) + +/* 1X RF power limiting */ +#define LOG_1X_RF_PWR_LMT_C (0x44A + LOG_1X_BASE_C) + +/* 1X RF state */ +#define LOG_1X_RF_STATE_C (0x44B + LOG_1X_BASE_C) + +/* 1X RF sleep */ +#define LOG_1X_RF_SLEEP_C (0x44C + LOG_1X_BASE_C) + +/* 1X RF TX state */ +#define LOG_1X_RF_TX_STATE_C (0x44D + LOG_1X_BASE_C) + +/* 1X RF IntelliCeiver state */ +#define LOG_1X_RF_INT_STATE_C (0x44E + LOG_1X_BASE_C) + +/* 1X RF RX ADC clock */ +#define LOG_1X_RF_RX_ADC_CLK_C (0x44F + LOG_1X_BASE_C) + +/* 1X RF LNA switch point */ +#define LOG_1X_RF_LNA_SWITCHP_C (0x450 + LOG_1X_BASE_C) + +/* 1X RF RX calibration */ +#define LOG_1X_RF_RX_CAL_C (0x451 + LOG_1X_BASE_C) + +/* 1X RF API */ +#define LOG_1X_RF_API_C (0x452 + LOG_1X_BASE_C) + +/* 1X RF RX PLL locking status */ +#define LOG_1X_RF_RX_PLL_LOCK_C (0x453 + LOG_1X_BASE_C) + +/* 1X RF voltage regulator */ +#define LOG_1X_RF_VREG_C (0x454 + LOG_1X_BASE_C) + +/* CGPS DIAG successful fix count */ +#define LOG_CGPS_DIAG_SUCCESSFUL_FIX_COUNT_C (0x455 + LOG_1X_BASE_C) + +/* CGPS MC track dynamic power optimization status */ +#define LOG_CGPS_MC_TRACK_DPO_STATUS_C (0x456 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated bits */ +#define LOG_CGPS_MC_SBAS_DEMOD_BITS_C (0x457 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated soft symbols */ +#define LOG_CGPS_MC_SBAS_DEMOD_SOFT_SYMBOLS_C (0x458 + LOG_1X_BASE_C) + +/* Data Services PPP configuration */ +#define LOG_DS_PPP_CONFIG_PARAMS_C (0x459 + LOG_1X_BASE_C) + +/* Data Services physical link configuration */ +#define LOG_DS_PHYS_LINK_CONFIG_PARAMS_C (0x45A + LOG_1X_BASE_C) + +/* Data Services PPP device configuration */ +#define LOG_PS_PPP_DEV_CONFIG_PARAMS_C (0x45B + LOG_1X_BASE_C) + +/* CGPS PDSM GPS state information */ +#define LOG_CGPS_PDSM_GPS_STATE_INFO_C (0x45C + LOG_1X_BASE_C) + +/* CGPS PDSM EXT status GPS state information */ +#define LOG_CGPS_PDSM_EXT_STATUS_GPS_STATE_INFO_C (0x45D + LOG_1X_BASE_C) + +/* CGPS ME Rapid Search Report */ +#define LOG_CGPS_ME_RAPID_SEARCH_REPORT_C (0x45E + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T session */ +#define LOG_CGPS_PDSM_XTRA_T_SESSION_C (0x45F + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T upload */ +#define LOG_CGPS_PDSM_XTRA_T_UPLOAD_C (0x460 + LOG_1X_BASE_C) + +/* CGPS Wiper Position Report */ +#define LOG_CGPS_WIPER_POSITION_REPORT_C (0x461 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Request Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_REQ_C (0x462 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Response Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_RSP_C (0x463 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_REQ_C (0x464 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_COMPLETE_C (0x465 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_REQ_C (0x466 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_COMPLETE_C (0x467 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_C (0x468 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_COMPLETE_C (0x469 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_C (0x46A + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_COMPLETE_C (0x46B + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_C (0x46C + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Verification Message */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_VERIFICATION_C (0x46D + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Parental Control Message */ +#define LOG_DTV_DVBH_SEC_SC_PARENTAL_CTRL_C (0x46E + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard STKM */ +#define LOG_DTV_DVBH_SEC_SC_STKM_C (0x46F + LOG_1X_BASE_C) + +/* Protocol Services Statistics Global Socket */ +#define LOG_PS_STAT_GLOBAL_SOCK_C (0x470 + LOG_1X_BASE_C) + +/* MCS Application Manager */ +#define LOG_MCS_APPMGR_C (0x471 + LOG_1X_BASE_C) + +/* MCS MSGR */ +#define LOG_MCS_MSGR_C (0x472 + LOG_1X_BASE_C) + +/* MCS QTF */ +#define LOG_MCS_QTF_C (0x473 + LOG_1X_BASE_C) + +/* Sensors Stationary Detector Output */ +#define LOG_STATIONARY_DETECTOR_OUTPUT_C (0x474 + LOG_1X_BASE_C) + +/* Print out the ppm data portion */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_PPM_C (0x475 + LOG_1X_BASE_C) + +/* GNSS Position Report */ +#define LOG_GNSS_POSITION_REPORT_C (0x476 + LOG_1X_BASE_C) + +/* GNSS GPS Measurement Report */ +#define LOG_GNSS_GPS_MEASUREMENT_REPORT_C (0x477 + LOG_1X_BASE_C) + +/* GNSS Clock Report */ +#define LOG_GNSS_CLOCK_REPORT_C (0x478 + LOG_1X_BASE_C) + +/* GNSS Demod Soft Decision */ +#define LOG_GNSS_DEMOD_SOFT_DECISIONS_C (0x479 + LOG_1X_BASE_C) + +/* GNSS ME 5MS IQ sum */ +#define LOG_GNSS_ME_5MS_IQ_SUMS_C (0x47A + LOG_1X_BASE_C) + +/* GNSS CD DB report */ +#define LOG_GNSS_CD_DB_REPORT_C (0x47B + LOG_1X_BASE_C) + +/* GNSS PE WLS position report */ +#define LOG_GNSS_PE_WLS_POSITION_REPORT_C (0x47C + LOG_1X_BASE_C) + +/* GNSS PE KF position report */ +#define LOG_GNSS_PE_KF_POSITION_REPORT_C (0x47D + LOG_1X_BASE_C) + +/* GNSS PRX RF HW status report */ +#define LOG_GNSS_PRX_RF_HW_STATUS_REPORT_C (0x47E + LOG_1X_BASE_C) + +/* GNSS DRX RF HW status report */ +#define LOG_GNSS_DRX_RF_HW_STATUS_REPORT_C (0x47F + LOG_1X_BASE_C) + +/* GNSS Glonass Measurement report */ +#define LOG_GNSS_GLONASS_MEASUREMENT_REPORT_C (0x480 + LOG_1X_BASE_C) + +/* GNSS GPS HBW RXD measurement */ +#define LOG_GNSS_GPS_HBW_RXD_MEASUREMENT_C (0x481 + LOG_1X_BASE_C) + +/* GNSS PDSM position report callback */ +#define LOG_GNSS_PDSM_POSITION_REPORT_CALLBACK_C (0x482 + LOG_1X_BASE_C) + +/* ISense Request String */ +#define LOG_ISENSE_REQUEST_STR_C (0x483 + LOG_1X_BASE_C) + +/* ISense Response String */ +#define LOG_ISENSE_RESPONSE_STR_C (0x484 + LOG_1X_BASE_C) + +/* Bluetooth SOC General Log Packet*/ +#define LOG_BT_SOC_GENERAL_C (0x485 + LOG_1X_BASE_C) + +/* QCRil Call Flow */ +#define LOG_QCRIL_CALL_FLOW_C (0x486 + LOG_1X_BASE_C) + +/* CGPS Wideband FFT stats */ +#define LOG_CGPS_WB_FFT_STATS_C (0x487 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Calibration Report*/ +#define LOG_CGPS_SLOW_CLOCK_CALIB_REPORT_C (0x488 + LOG_1X_BASE_C) + +/* SNS GPS TIMESTAMP */ +#define LOG_SNS_GPS_TIMESTAMP_C (0x489 + LOG_1X_BASE_C) + +/* GNSS Search Strategy Task Allocation */ +#define LOG_GNSS_SEARCH_STRATEGY_TASK_ALLOCATION_C (0x48A + LOG_1X_BASE_C) + +/* RF MC STM state */ +#define LOG_1XHDR_MC_STATE_C (0x48B + LOG_1X_BASE_C) + +/* Record in the Sparse Network DB */ +#define LOG_CGPS_SNDB_RECORD_C (0x48C + LOG_1X_BASE_C) + +/* Record removed from the DB */ +#define LOG_CGPS_SNDB_REMOVE_C (0x48D + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_GNSS_CC_PERFORMANCE_STATS_C (0x48E + LOG_1X_BASE_C) + +/* GNSS PDSM Set Paramerters */ +#define LOG_GNSS_PDSM_SET_PARAMETERS_C (0x48F + LOG_1X_BASE_C) + +/* GNSS PDSM PD Event Callback */ +#define LOG_GNSS_PDSM_PD_EVENT_CALLBACK_C (0x490 + LOG_1X_BASE_C) + +/* GNSS PDSM PA Event Callback */ +#define LOG_GNSS_PDSM_PA_EVENT_CALLBACK_C (0x491 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED2_C (0x492 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED3_C (0x493 + LOG_1X_BASE_C) + +/* GNSS PDSM EXT Status MEAS Report */ +#define LOG_GNSS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x494 + LOG_1X_BASE_C) + +/* GNSS SM Error */ +#define LOG_GNSS_SM_ERROR_C (0x495 + LOG_1X_BASE_C) + +/* WLAN Scan */ +#define LOG_WLAN_SCAN_C (0x496 + LOG_1X_BASE_C) + +/* WLAN IBSS */ +#define LOG_WLAN_IBSS_C (0x497 + LOG_1X_BASE_C) + +/* WLAN 802.11d*/ +#define LOG_WLAN_80211D_C (0x498 + LOG_1X_BASE_C) + +/* WLAN Handoff */ +#define LOG_WLAN_HANDOFF_C (0x499 + LOG_1X_BASE_C) + +/* WLAN QoS EDCA */ +#define LOG_WLAN_QOS_EDCA_C (0x49A + LOG_1X_BASE_C) + +/* WLAN Beacon Update */ +#define LOG_WLAN_BEACON_UPDATE_C (0x49B + LOG_1X_BASE_C) + +/* WLAN Power save wow add pattern */ +#define LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C (0x49C + LOG_1X_BASE_C) + +/* WLAN WCM link metrics */ +#define LOG_WLAN_WCM_LINKMETRICS_C (0x49D + LOG_1X_BASE_C) + +/* WLAN wps scan complete*/ +#define LOG_WLAN_WPS_SCAN_COMPLETE_C (0x49E + LOG_1X_BASE_C) + +/* WLAN WPS WSC Message */ +#define LOG_WLAN_WPS_WSC_MESSAGE_C (0x49F + LOG_1X_BASE_C) + +/* WLAN WPS credentials */ +#define LOG_WLAN_WPS_CREDENTIALS_C (0x4A0 + LOG_1X_BASE_C) + +/* WLAN Linklayer stat*/ +#define LOG_WLAN_LINKLAYER_STAT_C (0x4A1 + LOG_1X_BASE_C) + +/* WLAN Qos TSpec*/ +#define LOG_WLAN_QOS_TSPEC_C (0x4A2 + LOG_1X_BASE_C) + +/* PMIC Vreg Control */ +#define LOG_PM_VREG_CONTROL_C (0x4A3 + LOG_1X_BASE_C) + +/* PMIC Vreg Level */ +#define LOG_PM_VREG_LEVEL_C (0x4A4 + LOG_1X_BASE_C) + +/* PMIC Vreg State */ +#define LOG_PM_VREG_STATE_C (0x4A5 + LOG_1X_BASE_C) + +/* CGPS SM EPH Randomization info */ +#define LOG_CGPS_SM_EPH_RANDOMIZATION_INFO_C (0x4A6 + LOG_1X_BASE_C) + +/* Audio calibration data */ +#define LOG_QACT_DATA_C (0x4A7 + LOG_1X_BASE_C) + +/* Compass 2D Tracked Calibration Set */ +#define LOG_SNS_VCPS_2D_TRACKED_CAL_SET (0x4A8 + LOG_1X_BASE_C) + +/* Compass 3D Tracked Calibration Set */ +#define LOG_SNS_VCPS_3D_TRACKED_CAL_SET (0x4A9 + LOG_1X_BASE_C) + +/* Calibration metric */ +#define LOG_SNS_VCPS_CAL_METRIC (0x4AA + LOG_1X_BASE_C) + +/* Accelerometer distance */ +#define LOG_SNS_VCPS_ACCEL_DIST (0x4AB + LOG_1X_BASE_C) + +/* Plane update */ +#define LOG_SNS_VCPS_PLANE_UPDATE (0x4AC + LOG_1X_BASE_C) + +/* Location report */ +#define LOG_SNS_VCPS_LOC_REPORT (0x4AD + LOG_1X_BASE_C) + +/* CM Active subscription */ +#define LOG_CM_PH_EVENT_SUBSCRIPTION_PREF_INFO_C (0x4AE + LOG_1X_BASE_C) + +/* DSDS version of CM call event */ +#define LOG_CM_DS_CALL_EVENT_C (0x4AF + LOG_1X_BASE_C) + +/* Sensors ?MobiSens Output */ +#define LOG_MOBISENS_OUTPUT_C (0x4B0 + LOG_1X_BASE_C) + +/* Accelerometer Data */ +#define LOG_ACCEL_DATA_C (0x4B1 + LOG_1X_BASE_C) + +/* Accelerometer Compensated Data */ +#define LOG_ACCEL_COMP_DATA_C (0x4B2 + LOG_1X_BASE_C) + +/* Motion State Data */ +#define LOG_MOTION_STATE_DATA_C (0x4B3 + LOG_1X_BASE_C) + +/* Stationary Position Indicator */ +#define LOG_STAT_POS_IND_C (0x4B4 + LOG_1X_BASE_C) + +/* Motion State Features */ +#define LOG_MOTION_STATE_FEATURES_C (0x4B5 + LOG_1X_BASE_C) + +/* Motion State Hard Decision */ +#define LOG_MOTION_STATE_HARD_DECISION_C (0x4B6 + LOG_1X_BASE_C) + +/* Motion State Soft Decision */ +#define LOG_MOTION_STATE_SOFT_DECISION_C (0x4B7 + LOG_1X_BASE_C) + +/* Sensors Software Version */ +#define LOG_SENSORS_SOFTWARE_VERSION_C (0x4B8 + LOG_1X_BASE_C) + +/* MobiSens Stationary Position Indicator Log Packet */ +#define LOG_MOBISENS_SPI_C (0x4B9 + LOG_1X_BASE_C) + +/* XO calibration raw IQ data */ +#define LOG_XO_IQ_DATA_C (0x4BA + LOG_1X_BASE_C) + +/*DTV CMMB Control Tabl Updated*/ +#define LOG_DTV_CMMB_CONTROL_TABLE_UPDATE ((0x4BB) + LOG_1X_BASE_C) + +/*DTV CMMB Media API Buffering Status*/ +#define LOG_DTV_CMMB_MEDIA_BUFFERING_STATUS ((0x4BC) + LOG_1X_BASE_C) + +/*DTV CMMB *Emergency Broadcast Data*/ +#define LOG_DTV_CMMB_CONTROL_EMERGENCY_BCAST ((0x4BD) + LOG_1X_BASE_C) + +/*DTV CMMB EMM/ECM Data*/ +#define LOG_DTV_CMMB_CAS_EMM_ECM ((0x4BE) + LOG_1X_BASE_C) + +/*DTV CMMB HW Status*/ +#define LOG_DTV_CMMB_HW_PERFORMANCE ((0x4BF) + LOG_1X_BASE_C) + +/*DTV CMMB ESSG Program Indication Information*/ +#define LOG_DTV_CMMB_ESG_PROGRAM_INDICATION_INFORMATION ((0x4C0) + LOG_1X_BASE_C) + +/* Sensors ¨C binary output of converted sensor data */ +#define LOG_CONVERTED_SENSOR_DATA_C ((0x4C1) + LOG_1X_BASE_C) + +/* CM Subscription event */ +#define LOG_CM_SUBSCRIPTION_EVENT_C ((0x4C2) + LOG_1X_BASE_C) + +/* Sensor Ambient Light Data */ +#define LOG_SNS_ALS_DATA_C ((0x4C3) + LOG_1X_BASE_C) + +/*Sensor Ambient Light Adaptive Data */ +#define LOG_SNS_ALS_DATA_ADAPTIVE_C ((0x4C4) + LOG_1X_BASE_C) + +/*Sensor Proximity Distance Data */ +#define LOG_SNS_PRX_DIST_DATA_C ((0x4C5) + LOG_1X_BASE_C) + +/*Sensor Proximity Data */ +#define LOG_SNS_PRX_DATA_C ((0x4C6) + LOG_1X_BASE_C) + +#define LOG_GNSS_SBAS_REPORT_C ((0x4C7) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_MODEM_C ((0x4C8) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_APPS_C ((0x4C9) + LOG_1X_BASE_C) + +#define LOG_BLAST_TASKPROFILE_C ((0x4CA) + LOG_1X_BASE_C) + +#define LOG_BLAST_SYSPROFILE_C ((0x4CB) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_FTM_C ((0x4CC) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_C ((0x4CD) + LOG_1X_BASE_C) + +#define LOG_UIM_DS_DATA_C ((0x4CE) + LOG_1X_BASE_C) + +#define LOG_QMI_CALL_FLOW_C ((0x4CF) + LOG_1X_BASE_C) + +#define LOG_APR_MODEM_C ((0x4D0) + LOG_1X_BASE_C) + +#define LOG_APR_APPS_C ((0x4D1) + LOG_1X_BASE_C) + +#define LOG_APR_ADSP_C ((0x4D2) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_RAW_PACKET_C ((0x4D3) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_RAW_PACKET_C ((0x4D4) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_FRAME_PACKET_C ((0x4D5) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_FRAME_PACKET_C ((0x4D6) + LOG_1X_BASE_C) + +#define LOG_CGPS_PDSM_EXT_STATUS_POS_INJ_REQ_INFO_C ((0x4D7) + LOG_1X_BASE_C) + +#define LOG_TEMPERATURE_MONITOR_C ((0x4D8) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_REST_DETECT_C ((0x4D9) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_ORIENTATION_C ((0x4DA) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_FACING_C ((0x4DB) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_BASIC_C ((0x4DC) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_HINBYE_C ((0x4DD) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_MEASUREMENT_REPORT_C ((0x4DE) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_POSITION_REPORT_C ((0x4E0) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_SVPOLY_REPORT_C ((0x4E1) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRSYNC_C ((0x4E2) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_NOTIFY_C ((0x4E3) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_REGISTER_C ((0x4E4) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_BEGIN_C ((0x4E5) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_PPM_SUSPEND_C ((0x4E6) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_THROTTLED_C ((0x4E7) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_FIRED_C ((0x4E8) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_END_C ((0x4E9) + LOG_1X_BASE_C) + +#define LOG_TRSP_DATA_STALL_C ((0x801) + LOG_1X_BASE_C) + +/* The last defined DMSS log code */ +#define LOG_1X_LAST_C ((0x801) + LOG_1X_BASE_C) + + +/* This is only here for old (pre equipment ID update) logging code */ +#define LOG_LAST_C ( LOG_1X_LAST_C & 0xFFF ) + + +/* ------------------------------------------------------------------------- + * APPS LOG definition: + * The max number of 16 log codes is assigned for Apps. + * The last apps log code could be 0xB00F. + * Below definition is consolidated from log_codes_apps.h + * ------------------------------------------------------------------------- */ + +/* ======================== APPS Profiling ======================== */ +#define LOG_APPS_SYSPROFILE_C (0x01 + LOG_APPS_BASE_C) +#define LOG_APPS_TASKPROFILE_C (0x02 + LOG_APPS_BASE_C) + +/* The last defined APPS log code */ +/* Change it to (0x02 + LOG_LTE_LAST_C) to allow LTE log codes */ +#define LOG_APPS_LAST_C (0x02 + LOG_LTE_LAST_C) + +/* ------------------------------------------------------------------------- + * Log Equipment IDs. + * The number is represented by 4 bits. + * ------------------------------------------------------------------------- */ +typedef enum { + LOG_EQUIP_ID_OEM = 0, /* 3rd party OEM (licensee) use */ + LOG_EQUIP_ID_1X = 1, /* Traditional 1X line of products */ + LOG_EQUIP_ID_RSVD2 = 2, + LOG_EQUIP_ID_RSVD3 = 3, + LOG_EQUIP_ID_WCDMA = 4, + LOG_EQUIP_ID_GSM = 5, + LOG_EQUIP_ID_LBS = 6, + LOG_EQUIP_ID_UMTS = 7, + LOG_EQUIP_ID_TDMA = 8, + LOG_EQUIP_ID_BOA = 9, + LOG_EQUIP_ID_DTV = 10, + LOG_EQUIP_ID_APPS = 11, + LOG_EQUIP_ID_DSP = 12, + + LOG_EQUIP_ID_LAST_DEFAULT = LOG_EQUIP_ID_DSP + +} log_equip_id_enum_type; + +#define LOG_EQUIP_ID_MAX 0xF /* The equipment ID is 4 bits */ + +/* Note that these are the official values and are used by default in + diagtune.h. +*/ +#define LOG_EQUIP_ID_0_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_1_LAST_CODE_DEFAULT LOG_1X_LAST_C +#define LOG_EQUIP_ID_2_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_3_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_4_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_5_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_6_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_7_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_8_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_9_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_10_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_11_LAST_CODE_DEFAULT LOG_LTE_LAST_C +#define LOG_EQUIP_ID_12_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_13_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_14_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_15_LAST_CODE_DEFAULT 0 + +#endif /* LOG_CODES_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_api.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_api.h new file mode 100644 index 0000000000000..692bb071a3c42 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_api.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ +#if !defined( __VOS_API_H ) +#define __VOS_API_H + +/**========================================================================= + + \file vos_Api.h + + \brief virtual Operating System Services (vOSS) API + + Header file that inludes all the vOSS API definitions. + + ========================================================================*/ + /*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 06/23/08 hba Added vos_preOpen() + 05/18/08 lac Created module. +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +// one stop shopping. This brings in the entire vOSS API. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VOS_WDA_TIMEOUT 15000 + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/**-------------------------------------------------------------------------- + + \brief vos_preOpen() - PreOpen the vOSS Module + + The \a vos_preOpen() function allocates the Vos Context, but do not + initialize all the members. This overal initialization will happen + at vos_Open(). + The reason why we need vos_preOpen() is to get a minimum context + where to store BAL and SAL relative data, which happens before + vos_Open() is called. + + \param pVosContext: A pointer to where to store the VOS Context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext ); + +VOS_STATUS vos_preClose( v_CONTEXT_t *pVosContext ); + + +VOS_STATUS vos_preStart( v_CONTEXT_t vosContext ); + + +VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ); + + + +VOS_STATUS vos_start( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_stop( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_close( v_CONTEXT_t vosContext ); + +/* vos shutdown will not close control transport and will not handshake with Riva */ +VOS_STATUS vos_shutdown( v_CONTEXT_t vosContext ); + +/* the wda interface to shutdown */ +VOS_STATUS vos_wda_shutdown( v_CONTEXT_t vosContext ); + +/**--------------------------------------------------------------------------- + + \brief vos_get_context() - get context data area + + Each module in the system has a context / data area that is allocated + and maanged by voss. This API allows any user to get a pointer to its + allocated context data area from the VOSS global context. + + \param vosContext - the VOSS Global Context. + + \param moduleId - the module ID, who's context data are is being retrived. + + \return - pointer to the context data area. + + - NULL if the context data is not allocated for the module ID + specified + + --------------------------------------------------------------------------*/ +v_VOID_t *vos_get_context( VOS_MODULE_ID moduleId, + v_CONTEXT_t vosContext ); + + +/**--------------------------------------------------------------------------- + + \brief vos_get_global_context() - get VOSS global Context + + This API allows any user to get the VOS Global Context pointer from a + module context data area. + + \param moduleContext - the input module context pointer + + \param moduleId - the module ID who's context pointer is input in + moduleContext. + + \return - pointer to the VOSS global context + + - NULL if the function is unable to retreive the VOSS context. + + --------------------------------------------------------------------------*/ +v_CONTEXT_t vos_get_global_context( VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext ); + +v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); + +v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); + +v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); + +/**--------------------------------------------------------------------------- + + \brief vos_alloc_context() - allocate a context within the VOSS global Context + + This API allows any user to allocate a user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being allocated. + + \param ppModuleContext - pointer to location where the pointer to the + allocated context is returned. Note this + output pointer is valid only if the API + returns VOS_STATUS_SUCCESS + + \param size - the size of the context area to be allocated. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + allocated successfully. The pointer to the context area + can be found in *ppModuleContext. + \note This function returns VOS_STATUS_SUCCESS if the + module context was already allocated and the size + allocated matches the size on this call. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context allocated. + + VOS_STATUS_E_EXISTS - vos could allocate the requested context + because a context for this module ID already exists and it is + a *different* size that specified on this call. + + VOS_STATUS_E_NOMEM - vos could not allocate memory for the + requested context area. + + \sa vos_get_context(), vos_free_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_alloc_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t **ppModuleContext, v_SIZE_t size ); + + +/**--------------------------------------------------------------------------- + + \brief vos_free_context() - free an allocated a context within the + VOSS global Context + + This API allows a user to free the user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being free + + \param pModuleContext - pointer to module context area to be free'd. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + free'd. The pointer to the context area is not longer + available. + + VOS_STATUS_E_FAULT - pVosContext or pModuleContext are not + valid pointers. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context free'd. + + VOS_STATUS_E_EXISTS - vos could not free the requested + context area because a context for this module ID does not + exist in the global vos context. + + \sa vos_get_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_free_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t *pModuleContext ); + +v_BOOL_t vos_is_apps_power_collapse_allowed(void* pHddCtx); +void vos_abort_mac_scan(tANI_U8 sessionId); + +/** + @brief vos_wlanShutdown() - This API will shutdown WLAN driver + + This function is called when Riva subsystem crashes. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Called when Riva goes down, this will shutdown WLAN + driver without handshaking with Riva. + 2. re-init: Next API + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanShutdown(void); + +/** + @brief vos_wlanReInit() - This API will re-init WLAN driver + + This function is called when Riva subsystem reboots. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Previous API + 2. re-init: Called when Riva comes back after the crash. This will + re-initialize WLAN driver. In some cases re-open may be + referred instead of re-init. + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanReInit(void); + +VOS_STATUS vos_get_vdev_types(tVOS_CON_MODE mode, tANI_U32 *type, + tANI_U32 *subType); + +/** + @brief vos_wlanRestart() - This API will reload WLAN driver. + + This function is called if driver detects any fatal state which + can be recovered by a WLAN module reload ( Android framwork initiated ). + Note that this API will not initiate any RIVA subsystem restart. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanRestart(void); + +/** + @brief vos_fwDumpReq() + + This function is called to issue dump commands to Firmware + + @param + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + @return + NONE +*/ +v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4); + +v_VOID_t vos_flush_work(v_VOID_t *work); +v_VOID_t vos_flush_delayed_work(v_VOID_t *dwork); + +v_BOOL_t vos_is_packet_log_enabled(void); + +v_U64_t vos_get_monotonic_boottime(void); + +void vos_trigger_recovery(void); + +#ifdef FEATURE_WLAN_D0WOW +v_VOID_t vos_pm_control(v_BOOL_t vote); +#endif +#endif // if !defined __VOS_API_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_event.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_event.h new file mode 100644 index 0000000000000..5fa0526fb0bb3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_event.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_DIAG_CORE_EVENT_H ) +#define __VOS_DIAG_CORE_EVENT_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) DIAG Events + + Definitions for vOSS Events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_pack_align.h" +#include "i_vos_diag_core_event.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_SECURITY + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t authMode; + v_U8_t encryptionModeUnicast; + v_U8_t encryptionModeMulticast; + v_U8_t pmkIDMatch; + v_U8_t bssid[6]; + v_U8_t keyId; + v_U8_t status; +} vos_event_wlan_security_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_STATUS + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t ssid[6]; + v_U8_t bssType; + v_U8_t rssi; + v_U8_t channel; + v_U8_t qosCapability; + v_U8_t authType; + v_U8_t encryptionType; + v_U8_t reason; + v_U8_t reasonDisconnect; +} vos_event_wlan_status_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_HANDOFF + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t currentApBssid[6]; + v_U8_t currentApRssi; + v_U8_t candidateApBssid[6]; + v_U8_t candidateApRssi; +} vos_event_wlan_handoff_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_VCC + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t rssi; + v_U8_t txPer; + v_U8_t rxPer; + int linkQuality; +} vos_event_wlan_vcc_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_QOS + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t reasonCode; +} vos_event_wlan_qos_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_PE + ------------------------------------------------------------------------*/ +typedef struct +{ + char bssid[6]; + v_U16_t event_type; + v_U16_t sme_state; + v_U16_t mlm_state; + v_U16_t status; + v_U16_t reason_code; +} vos_event_wlan_pe_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucBaBufferSize; + v_U16_t usBaSSN; + v_U8_t fInitiator; +} vos_event_wlan_add_block_ack_success_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucReasonCode; + v_U8_t fInitiator; +} vos_event_wlan_add_block_ack_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucDeleteReasonCode; +} vos_event_wlan_add_block_ack_deleted_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucDeleteReasonCode; + v_U8_t ucFailReasonCode; +} vos_event_wlan_add_block_ack_delete_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BSS_PROTECTION + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t event_type; + v_U8_t prot_type; +} vos_event_wlan_bss_prot_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BRINGUP_STATUS + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U16_t wlanStatus; + char driverVersion[10]; +} vos_event_wlan_bringup_status_payload_type; + +VOS_PACK_START + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_POWERSAVE_GENERIC + ------------------------------------------------------------------------*/ +typedef VOS_PACK_PRE struct +{ + v_U8_t event_subtype; + v_U32_t imps_period; + v_U8_t full_power_request_reason; + v_U8_t pmc_current_state; + v_U8_t enable_disable_powersave_mode; + v_U8_t winmob_d_power_state; + v_U8_t dtim_period; + v_U16_t final_listen_intv; + v_U16_t bmps_auto_timer_duration; + v_U16_t bmps_period; +} VOS_PACK_POST vos_event_wlan_powersave_payload_type; + +VOS_PACK_END + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_POWERSAVE_WOW + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t event_subtype; + v_U8_t wow_type; + v_U8_t wow_magic_pattern[6]; + v_U8_t wow_del_ptrn_id; + v_U8_t wow_wakeup_cause; + v_U8_t wow_wakeup_cause_pbm_ptrn_id; +} vos_event_wlan_powersave_wow_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BTC + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t btAddr[6]; + v_U16_t connHandle; + v_U8_t connStatus; + v_U8_t linkType; + v_U8_t scoInterval; + v_U8_t scoWindow; + v_U8_t retransWindow; + v_U8_t mode; +} vos_event_wlan_btc_type; + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOS_DIAG_CORE_EVENT_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_log.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_log.h new file mode 100644 index 0000000000000..af887f34c92d9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_diag_core_log.h @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_DIAG_CORE_LOG_H ) +#define __VOS_DIAG_CORE_LOG_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) DIAG logs + + Definitions for vOSS Events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "i_vos_diag_core_log.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_LOG_MAX_NUM_SSID 21 +#define VOS_LOG_MAX_NUM_BSSID 21 +#define VOS_LOG_MAX_SSID_SIZE 32 +#define VOS_LOG_MAX_BSSID_SIZE 6 +#define VOS_LOG_MAX_NUM_CHANNEL 64 +#define VOS_LOG_MAX_NUM_HO_CANDIDATE_APS 20 +#define VOS_LOG_MAX_WOW_PTRN_SIZE 128 +#define VOS_LOG_MAX_WOW_PTRN_MASK_SIZE 16 + +/*--------------------------------------------------------------------------- + This packet contains the scan results of the recent scan operation + LOG_WLAN_SCAN_C 0x1496 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t numSsid; + v_U8_t ssid[VOS_LOG_MAX_NUM_SSID][VOS_LOG_MAX_SSID_SIZE]; + v_U8_t bssid[VOS_LOG_MAX_NUM_BSSID][VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t totalSsid; + v_U8_t minChnTime; + v_U8_t maxChnTime; + v_U16_t timeBetweenBgScan; + v_U8_t BSSMode; + v_U8_t numChannel; + v_U8_t channels[VOS_LOG_MAX_NUM_CHANNEL]; + v_U16_t status; +} vos_log_scan_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to IBSS connection setup + LOG_WLAN_IBSS_C 0x1497 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t channelSetting; + v_U8_t bssid[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t peerMacAddr[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t ssid[VOS_LOG_MAX_SSID_SIZE]; + v_U8_t operatingChannel; + v_U8_t beaconInterval; + v_U8_t status; +} vos_log_ibss_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to 802.11D + LOG_WLAN_80211D_C 0x1498 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t numChannel; + v_U8_t Channels[VOS_LOG_MAX_NUM_CHANNEL]; + v_U8_t TxPwr[VOS_LOG_MAX_NUM_CHANNEL]; + v_U8_t countryCode[3]; + v_U8_t supportMultipleDomain; +} vos_log_802_11d_pkt_type; + +/*--------------------------------------------------------------------------- +This is a log packet which contains below handoff information: +- Current AP + RSSI (if already associated) +- Candidate AP + RSSI (before association and when the list is updated) +- For each BSSID in candidate list, provide RSSI, QoS and security compatibility +LOG_WLAN_HANDOFF_C 0x1499 +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t ssid[9]; + v_U8_t bssid[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t channel_id; + v_U32_t qos_score; + v_U32_t sec_score; + v_U32_t rssi_score; + v_U32_t overall_score; + v_U32_t tx_per; /* represented as a % */ + v_U32_t rx_per; /* represented as a % */ + +} vos_log_ho_ap_info; + +typedef struct +{ + log_hdr_type hdr; + v_U32_t num_aps; + vos_log_ho_ap_info current_ap_info; + vos_log_ho_ap_info candidate_ap_info[VOS_LOG_MAX_NUM_HO_CANDIDATE_APS]; +} vos_log_ho_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to the EDCA parameters + advertised by the AP + LOG_WLAN_QOS_EDCA_C 0x149A +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t aci_be; + v_U8_t cw_be; + v_U16_t txoplimit_be; + v_U8_t aci_bk; + v_U8_t cw_bk; + v_U16_t txoplimit_bk; + v_U8_t aci_vi; + v_U8_t cw_vi; + v_U16_t txoplimit_vi; + v_U8_t aci_vo; + v_U8_t cw_vo; + v_U16_t txoplimit_vo; +} vos_log_qos_edca_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the total number of beacon received value + LOG_WLAN_BEACON_UPDATE_C 0x149B +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U32_t bcn_rx_cnt; +} vos_log_beacon_update_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to a WoW patern value when set + LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C 0x149C +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t pattern_id; + v_U8_t pattern_byte_offset; + v_U8_t pattern_size; + v_U8_t pattern[VOS_LOG_MAX_WOW_PTRN_SIZE]; + v_U8_t pattern_mask_size; + v_U8_t pattern_mask[VOS_LOG_MAX_WOW_PTRN_MASK_SIZE]; +} vos_log_powersave_wow_add_ptrn_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the PHY & MAC layer statistics sent by lower layer + _WLAN_LINKLAYER_STAT_C 0x14A1 +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U32_t retry_cnt[4]; + v_U32_t multiple_retry_cnt[4]; + v_U32_t tx_frm_cnt[4]; + v_U32_t rx_frm_cnt; + v_U32_t frm_dup_cnt; + v_U32_t fail_cnt[4]; + v_U32_t rts_fail_cnt; + v_U32_t ack_fail_cnt; + v_U32_t rts_succ_cnt; + v_U32_t rx_discard_cnt; + v_U32_t rx_error_cnt; + v_U32_t tx_byte_cnt; + +} summaryStatsInfo; + +typedef struct +{ + v_U32_t rx_frag_cnt; + v_U32_t promiscuous_rx_frag_cnt; + v_U32_t rx_input_sensitivity; + v_U32_t max_pwr; + v_U32_t sync_fail_cnt; + v_U32_t tx_rate; + +} globalClassAStatsInfo; + +typedef struct +{ + v_U32_t uc_rx_wep_unencrypted_frm_cnt; + v_U32_t uc_rx_mic_fail_cnt; + v_U32_t uc_tkip_icv_err; + v_U32_t uc_aes_ccmp_format_err; + v_U32_t uc_aes_ccmp_replay_cnt; + v_U32_t uc_aes_ccmp_decrpt_err; + v_U32_t uc_wep_undecryptable_cnt; + v_U32_t uc_wep_icv_err; + v_U32_t uc_rx_decrypt_succ_cnt; + v_U32_t uc_rx_decrypt_fail_cnt; + v_U32_t mcbc_rx_wep_unencrypted_frm_cnt; + v_U32_t mcbc_rx_mic_fail_cnt; + v_U32_t mcbc_tkip_icv_err; + v_U32_t mcbc_aes_ccmp_format_err; + v_U32_t mcbc_aes_ccmp_replay_cnt; + v_U32_t mcbc_aes_ccmp_decrpt_err; + v_U32_t mcbc_wep_undecryptable_cnt; + v_U32_t mcbc_wep_icv_err; + v_U32_t mcbc_rx_decrypt_succ_cnt; + v_U32_t mcbc_rx_decrypt_fail_cnt; + +} globalClassBStatsInfo; + +typedef struct +{ + v_U32_t rx_amsdu_cnt; + v_U32_t rx_ampdu_cnt; + v_U32_t tx_20_frm_cnt; + v_U32_t rx_20_frm_cnt; + v_U32_t rx_mpdu_in_ampdu_cnt; + v_U32_t ampdu_delimiter_crc_err; + +} globalClassCStatsInfo; + +typedef struct +{ + v_U32_t tx_uc_frm_cnt; + v_U32_t tx_mc_frm_cnt; + v_U32_t tx_bc_frm_cnt; + v_U32_t rx_uc_frm_cnt; + v_U32_t rx_mc_frm_cnt; + v_U32_t rx_bc_frm_cnt; + v_U32_t tx_uc_byte_cnt[4]; + v_U32_t tx_mc_byte_cnt; + v_U32_t tx_bc_byte_cnt; + v_U32_t rx_uc_byte_cnt[4]; + v_U32_t rx_mc_byte_cnt; + v_U32_t rx_bc_byte_cnt; + v_U32_t rx_byte_cnt; + v_U32_t num_rx_bytes_crc_ok; + v_U32_t rx_rate; + +} globalClassDStatsInfo; + +typedef struct +{ + v_U32_t tx_frag_cnt[4]; + v_U32_t tx_ampdu_cnt; + v_U32_t tx_mpdu_in_ampdu_cnt; +} perStaStatsInfo; + +typedef struct +{ + log_hdr_type hdr; + v_U8_t version; + v_U8_t reserved[3]; + v_U32_t stat_mask; + summaryStatsInfo summaryStats; + globalClassAStatsInfo globalClassAStats; + globalClassBStatsInfo globalClassBStats; + globalClassCStatsInfo globalClassCStats; + globalClassDStatsInfo globalClassDStats; + perStaStatsInfo perStaStats; +} vos_log_statistics_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the Tspec info negotiated with the AP for the + specific AC + LOG_WLAN_QOS_TSPEC_C 0x14A2 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t tsinfo[3]; + v_U16_t nominal_msdu_size; + v_U16_t maximum_msdu_size; + v_U32_t min_service_interval; + v_U32_t max_service_interval; + v_U32_t inactivity_interval; + v_U32_t suspension_interval; + v_U32_t svc_start_time; + v_U32_t min_data_rate; + v_U32_t mean_data_rate; + v_U32_t peak_data_rate; + v_U32_t max_burst_size; + v_U32_t delay_bound; + v_U32_t min_phy_rate; + v_U16_t surplus_bw_allowance; + v_U16_t medium_time; +} vos_log_qos_tspec_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains data information when stall detected + LOG_TRSP_DATA_STALL_C 0x1801 +---------------------------------------------------------------------------*/ + +typedef struct +{ + char channelName[4]; + v_U32_t numDesc; + v_U32_t numFreeDesc; + v_U32_t numRsvdDesc; + v_U32_t headDescOrder; + v_U32_t tailDescOrder; + v_U32_t ctrlRegVal; + v_U32_t statRegVal; + v_U32_t numValDesc; + v_U32_t numInvalDesc; +} vos_log_data_stall_channel_type; + +typedef struct +{ + log_hdr_type hdr; + v_U32_t PowerState; + v_U32_t numFreeBd; + vos_log_data_stall_channel_type dxeChannelInfo[4]; +} vos_log_data_stall_type; + +/*--------------------------------------------------------------------------- + This packet contains the rssi value from BSS descriptor + LOG_WLAN_RSSI_UPDATE_C 0x1354 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_S7_t rssi; +} vos_log_rssi_pkt_type; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOS_DIAG_CORE_LOG_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_event.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_event.h new file mode 100644 index 0000000000000..7a6395075ebb6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_event.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_EVENT_H ) +#define __VOS_EVENT_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) Events + + Definitions for vOSS Events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_types.h" +#include "i_vos_event.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + + \brief vos_event_init() - initialize a vOSS event + + The \a vos_lock_event() function initializes the specified event. Upon + successful initialization, the state of the event becomes initialized + and not 'signaled. + + An event must be initialized before it may be used in any other lock + functions. + + Attempting to initialize an already initialized event results in + a failure. + + \param lock - pointer to the opaque event object to initialize + + \return VOS_STATUS_SUCCESS - event was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the event + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the event + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by event, a previously + initialized, but not yet destroyed, event. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_init( vos_event_t *event ); + +/*-------------------------------------------------------------------------- + + \brief vos_event_set() - set a vOSS event + + The state of the specified event is set to 'signalled by calling + \a vos_event_set(). The state of the event remains signalled until an + explicit call to vos_event_reset(). + + Any threads waiting on the event as a result of a vos_event_wait() will + be unblocked and available to be scheduled for execution when the event + is signaled by a call to \a vos_event_set(). + + \param event - the event to set to the signalled state + + \return VOS_STATUS_SUCCESS - the event was successfully signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_set( vos_event_t * event ); + + +/*-------------------------------------------------------------------------- + + \brief vos_event_reset() - reset a vOSS event + + The state of the specified event is set to 'NOT signalled' by calling + \a vos_event_reset(). The state of the event remains NOT signalled until an + explicit call to vos_event_set(). + + This function sets the event to a NOT signalled state even if the event was + signalled multiple times before being signaled. + + \param event - the event to set to the NOT signalled state + + \return VOS_STATUS_SUCCESS - the event state was successfully change to + NOT signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_reset( vos_event_t * event ); + + +/*-------------------------------------------------------------------------- + + \brief vos_event_destroy() - Destroy a vOSS event + + The \a vos_event_destroy() function shall destroy the event object + referenced by event. After a successful return from \a vos_event_destroy() + the event object becomes, in effect, uninitialized. + + A destroyed event object can be reinitialized using vos_event_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS event functions to manipulate the lock such + as vos_event_set() will fail if the event is destroyed. Therefore, + don't use the event after it has been destroyed until it has + been re-initialized. + + \param event - the event object to be destroyed. + + \return VOS_STATUS_SUCCESS - event was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by event while it is still being + referenced (there are threads waiting on this event) + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_destroy( vos_event_t *event ); + +/*---------------------------------------------------------------------------- + + \brief vos_wait_single_event() - Waits for a single event to be set. + + This API waits for the event to be set. + + \param pEvent - pointer to an event to wait on. + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by the event being + set. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before the + event was set. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - pEvent is an invalid pointer. + + \sa vos_wait_multiple_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_single_event( vos_event_t *pEvent, v_U32_t timeout ); + +/*---------------------------------------------------------------------------- + + \brief vos_wait_multiple_events() - Waits for event(s) to be set. + + This API waits for any event in the input array of events to be + set. The caller is blocked waiting any event in the array to be + set or for the timeout to occur. + + If multiple events in the array are set, only one event is identified + in the return from this call as satisfying the wait condition. The + caller is responsible for calling \a vos_wait_events() again to find + the other events that are set. + + \param pEventList - pointer to an array of event pointers + + \param numEvents - Number of events + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \param pEventIndex - This is a pointer to the location where the index of + the event in the event array that satisfied the wait because + the event was set. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + VOS_STATUS_E_INVAL - At least one of the values specified in the + event array refers to an uninitialized event object. The invalid + event is identified by the index in *pEventIndex. Note that only + the first uninitialized event is detected when this error is + returned. + + VOS_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + VOS_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. + + \sa vos_wait_single_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_multiple_events( vos_event_t **pEventList, v_U8_t numEvents, + v_U32_t timeout, v_U8_t *pEventIndex ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOSS_EVENT_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_getBin.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_getBin.h new file mode 100644 index 0000000000000..fc5122ad4efde --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_getBin.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_GETBIN_H ) +#define __VOS_GETBIN_H + +/**========================================================================= + + \file vos_getBin.h + + \brief virtual Operating System Services (vOSS) binary APIs + + Binary retrieval definitions and APIs. + + These APIs allow components to retrieve binary contents (firmware, + configuration data, etc.) from a storage medium on the platform. + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/// Binary IDs +typedef enum +{ + /// Binary ID for firmware + VOS_BINARY_ID_FIRMWARE, + + /// Binary ID for Configuration data + VOS_BINARY_ID_CONFIG, + + /// Binary ID for country code to regulatory domain mapping + VOS_BINARY_ID_COUNTRY_INFO, + + /// Binary ID for Handoff Configuration data + VOS_BINARY_ID_HO_CONFIG, + + /// Binary ID for Dictionary Configuration data + VOS_BINARY_ID_DICT_CONFIG + +} VOS_BINARY_ID; + + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/**--------------------------------------------------------------------------- + + \brief vos_get_binary_blob() - get binary data from platform + + This API allows components to get binary data from the platform independent + of where the data is stored on the device. + +
    +
  • Firmware +
  • Configuration Data +
+ + \param binaryId - identifies the binary data to return to the caller. + + \param pBuffer - a pointer to the buffer where the binary data will be + retrieved. Memory for this buffer is allocated by the caller + and free'd by the caller. vOSS will fill this buffer with + raw binary data and update the *pBufferSize with the exact + size of the data that has been retreived. + + Input value of NULL is valid and will cause the API to return + the size of the binary data in *pBufferSize. + + \param pBufferSize - pointer to a variable that upon input contains the + size of the data buffer available at pBuffer. Upon success, this + variable is updated with the size of the binary data that was + retreived and written to the buffer at pBuffer. + + Input value of 0 is valid and will cause the API to return + the size of the binary data in *pBufferSize. + + \return VOS_STATUS_SUCCESS - the binary data has been successfully + retreived and written to the buffer. + + VOS_STATUS_E_INVAL - The value specified by binaryId does not + refer to a valid VOS Binary ID. + + VOS_STATUS_E_FAULT - pBufferSize is not a valid pointer to a + variable that the API can write to. + + VOS_STATUS_E_NOMEM - the memory referred to by pBuffer and + *pBufferSize is not big enough to contain the binary. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_get_binary_blob( VOS_BINARY_ID binaryId, + v_VOID_t *pBuffer, v_SIZE_t *pBufferSize ); + +/**---------------------------------------------------------------------------- + \brief vos_get_conparam()- function to read the insmod parameters +-----------------------------------------------------------------------------*/ +tVOS_CON_MODE vos_get_conparam( void ); +tVOS_CONCURRENCY_MODE vos_get_concurrency_mode( void ); +v_BOOL_t vos_concurrent_open_sessions_running(void); +v_BOOL_t vos_max_concurrent_connections_reached(void); +void vos_clear_concurrent_session_count(void); +v_BOOL_t vos_is_multiple_active_sta_sessions (void); +v_BOOL_t vos_is_sta_active_connection_exists (void); + +#ifdef WLAN_FEATURE_MBSSID +v_BOOL_t vos_concurrent_sap_sessions_running(v_VOID_t); +#endif +#endif // !defined __VOS_GETBIN_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_list.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_list.h new file mode 100644 index 0000000000000..98893c8adfd39 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_list.h @@ -0,0 +1,584 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_LIST_H ) +#define __VOS_LIST_H + +/**========================================================================= + + \file vos_list.h + + \brief virtual Operating System Services (vOSS) List APIs + + Definitions for vOSS Linked Lists API + + Lists are implemented as a doubly linked list. An item in a list can + be of any type as long as the datatype contains a field of type + vos_link_t. + + In general, a list is a doubly linked list of items with a pointer + to the front of the list and a pointer to the end of the list. The + list items contain a forward and back link. + + List Nodes + ============= =========================== + +-------+ + | Front |------------->+---------+ +---------+ + +-------+ | Next |---->| Next |---->NULL + | Back |-+ +---------+ +---------+ + +-------+ | NULL<----| Prev |<----| Prev | + | +---------+ +---------+ + | |User Data| |User Data| + | +---------+ +---------+ + | ^ + | | + +---------------------------------+ + + This linked list API is implemented with appropriate locking + mechanisms to assure operations on the list are thread safe. + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief vos_list_init() - initialize a vOS Linked List + + The \a vos_list_init() function initializes the specified linked list + 'object'. Upon successful initialization, the state of the list + becomes initialized and available for use through the other vos_list_xxx + APIs. + + A list must be initialized by calling vos_list_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized list results in + a failure. + + \param pList - pointer to the opaque list object to initialize + + \return VOS_STATUS_SUCCESS - list was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the list + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the list + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by list, a previously + initialized, but not yet destroyed, list. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_destroy() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_init( vos_list_t *pList ); + + +/**------------------------------------------------------------------------- + + \brief vos_list_destroy() - Destroy a vOSS List + + The \a vos_list_destroy() function shall destroy the list object + referenced by pList. After a successful return from \a vos_list_destroy() + the list object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_list_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS list functions to manipulate the list such + will fail if the list or has not been initialized or is destroyed. + Therefore, don't use the list after it has been destroyed until it has + been re-initialized. + + \param pLlist - pointer to the list object to be destroyed. + + \return VOS_STATUS_SUCCESS - list was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by pList that is still has + nodes. The list must be empty before it can be destroyed. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_destroy( vos_list_t *pList ); + +/*-------------------------------------------------------------------------- + + \brief vos_list_lock() - Lock a vOSS List + + The \a vos_list_lock() function shall lock the list object to prevent + other tasks from operating on this list. The list remains locked until + a call to vos_list_unlock() is made. + + Each list function already operate within a critical section. + However it is sometimes necessary to lock a list over a series of list + function calls. + + For example, when one needs to search a node on a list and insert another + node after it, one would want to lock this list for the entire process + in case another task attempts to manipulate this list. + + \param pLlist - pointer to the list object to be locked. + + \return VOS_STATUS_SUCCESS - list was successfully locked. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_unlock() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_lock( vos_list_t *pList ); + +/*-------------------------------------------------------------------------- + + \brief vos_list_unlock() - Unlock a vOSS List + + The \a vos_list_unlock() function shall unlock the list object to allow + other tasks to use this list. This function is only called when + the vos_list_lock() is previously called in the current task. + + \param pLlist - pointer to the list object to be unlocked. + + \return VOS_STATUS_SUCCESS - list was successfully unlocked. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_lock() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_unlock( vos_list_t *pList ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_front() - insert node at front of a linked list + + The vos_list_insert_front() API will insert a node at the front of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_front( vos_list_t *pList, vos_list_node_t *pNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_back() - insert node at back of a linked list + + The vos_list_insert_back() API will insert a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_back( vos_list_t *pList, vos_list_node_t *pNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_back_size() - insert node at back of a linked list and + return the size AFTER the enqueue. This size is determined in a race free + manner i.e. while the list is locked for the enqueue operation + + The vos_list_insert_back_size() API will insert a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_back_size( vos_list_t *pList, vos_list_node_t *pNode, v_SIZE_t *pSize ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_front() - remove node at front of a linked list + + The vos_list_remove_front() API will remove a node at the front of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_front( vos_list_t *pList, vos_list_node_t **ppNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_back() - remove node at back of a linked list + + The vos_list_remove_back() API will remove a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_back( vos_list_t *pList, vos_list_node_t **ppNode ); + + +/*---------------------------------------------------------------------------- + + \brief vos_list_size() - return the size of of a linked list + + The vos_list_size() API will return the number of nodes on the + given vOS List object. + + \param pList - Pointer to list object where the node will be counted + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return VOS_STATUS_SUCCESS - list size of the properly initialized + vos list object has been returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList or pSize are not valid pointers + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_size( vos_list_t *pList, v_SIZE_t *pSize ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_front() - peek at the node at front of a linked list + + The vos_list_peek_front() API will return a pointer to the node at the + front of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return VOS_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_front( vos_list_t *pList, vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_back() - peek at the node at back of a linked list + + The vos_list_peek_back() API will return a pointer to the node at the + back of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return VOS_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_peek_back(), vos_list_remove_back(), vos_list_peek_front(), + vos_list_remove_front() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_back( vos_list_t *pList, vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_next() - peek at the node after the specified node + + The vos_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_next( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_prev() - peek at the node before the specified node + + The vos_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_prev( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_before() - insert node at front of a specified + list node + + The vos_list_insert_before() API will insert a node onto a properly + initialized vOS List object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_before( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_after() - insert node behind a specified list node + + The vos_list_insert_after() API will insert a node onto a properly + initialized vOS List object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_after( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_node() - remove specified node from vOS list list + + The vos_list_remove_node() API will remove a specified node from the + properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + + VOS_STATUS_E_FAULT - pList or pNodeToRemove is not a valid pointer + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_node( vos_list_t *pList, vos_list_node_t *pNodeToRemove ); + + + +#endif // __VOS_LIST_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_lock.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_lock.h new file mode 100644 index 0000000000000..e26819b181a8a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_lock.h @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_LOCK_H ) +#define __VOS_LOCK_H + +/**========================================================================= + + \file vos_lock.h + + \brief virtual Operating System Servies (vOS) Locks + + Definitions for vOSS Locks + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "i_vos_lock.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief vos_lock_init() - initialize a vOSS lock + + The \a vos_lock_init() function initializes the specified lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - lock was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the lock + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the lock + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by lock, a previously + initialized, but not yet destroyed, lock. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_init( vos_lock_t *lock ); + +/*-------------------------------------------------------------------------- + + \brief vos_lock_acquire() - acquire a lock + + A lock object is acquired by calling \a vos_lock_acquire(). If the lock + is already locked, the calling thread shall block until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param lock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_acquire( vos_lock_t * lock ); + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_release() - release a lock + + The \a vos_lock_release() function shall release the lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param lock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_PERM - Operation is not permitted. The calling + thread does not own the lock. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_release( vos_lock_t *lock ); + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_destroy() - Destroy a vOSS Lock + + The \a vos_lock_destroy() function shall destroy the lock object + referenced by lock. After a successful return from \a vos_lock_destroy() + the lock object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_lock_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS lock functions to manipulate the lock such + as vos_lock_acquire() will fail if the lock is destroyed. Therefore, + don't use the lock after it has been destroyed until it has + been re-initialized. + + \param lock - the lock object to be destroyed. + + \return VOS_STATUS_SUCCESS - lock was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by lock while it is locked + or still referenced. + + VOS_STATUS_E_INVAL - The value specified by lock is invalid. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_destroy( vos_lock_t *lock ); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_init() - initializes a vOSS spin lock + + The vos_spin_lock_init() function initializes the specified spin lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_spin_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param pLock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - spin lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_init(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_acquire() - acquires a spin lock + + A lock object is acquired by calling \a vos_spin_lock_acquire(). If the lock + is already locked, the calling thread shall spin until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param pLock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_acquire(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the spin lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param pLock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_release(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_destroy() - releases resource of a lock + + \param pLock - pointer to a lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_destroy(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_init() - initializes a vOSS wake lock + + \param pLock - the wake lock to initialize + name - wakelock name + + \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_acquire() - acquires a wake lock + + \param pLock - the wake lock to acquire + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_timeout_acquire() - acquires a wake lock with a timeout + + \param pLock - the wake lock to acquire + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_timeout_acquire(vos_wake_lock_t *pLock, v_U32_t msec); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_release() - releases a wake lock + + \param pLock - the wake lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_destroy() - destroys a wake lock + + \param pLock - the wake lock to destroy + + \return VOS_STATUS_SUCCESS - the lock was successfully destroyed + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock); + +#endif // __VOSS_LOCK_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_memory.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_memory.h new file mode 100644 index 0000000000000..7b8d6a7b182d9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_memory.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_MEMORY_H ) +#define __VOS_MEMORY_H + +/**========================================================================= + + \file vos_memory.h + + \brief virtual Operating System Servies (vOSS) + + Memory management functions + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef MEMORY_DEBUG +v_VOID_t vos_mem_init(v_VOID_t); +v_VOID_t vos_mem_exit(v_VOID_t); +void vos_mem_clean(void); +#endif + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_mem_malloc() - vOSS Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +#define vos_mem_malloc(size) vos_mem_malloc_debug(size, __FILE__, __LINE__) +v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum); +#else +v_VOID_t * vos_mem_malloc( v_SIZE_t size ); +#endif + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_free() - vOSS Free Memory + + This function will free the memory pointed to by 'ptr'. + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_free( v_VOID_t *ptr ); + + +/*---------------------------------------------------------------------------- + + \fn vos_mem_set() - set (fill) memory with a specified byte value. + + \param pMemory - pointer to memory that will be set + + \param numBytes - the number of bytes to be set + + \param value - the byte set in memory + + \return - Nothing. + + \sa vos_mem_zero() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value ); + + +/*---------------------------------------------------------------------------- + + \fn vos_mem_zero() - zero out memory + + This function sets the memory location to all zeros, essentially clearing + the memory. + + \param pMemory - pointer to memory that will be set to zero + + \param numBytes - the number of bytes zero + + \param value - the byte set in memory + + \return - Nothing. + + \sa vos_mem_set() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes ); + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_copy() - Copy memory + + Copy host memory from one location to another, similar to memcpy in + standard C. Note this function does not specifically handle overlapping + source and destination memory locations. Calling this function with + overlapping source and destination memory locations will result in + unpredictable results. Use vos_mem_move() if the memory locations + for the source and destination are overlapping (or could be overlapping!) + + \param pDst - pointer to destination memory location (to copy to) + + \param pSrc - pointer to source memory location (to copy from) + + \param numBytes - number of bytes to copy. + + \return - Nothing + + \sa vos_mem_move() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ); + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_move() - Move memory + + Move host memory from one location to another, similar to memmove in + standard C. Note this function *does* handle overlapping + source and destination memory locations. + + \param pDst - pointer to destination memory location (to move to) + + \param pSrc - pointer to source memory location (to move from) + + \param numBytes - number of bytes to move. + + \return - Nothing + + \sa vos_mem_move() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ); + +/** --------------------------------------------------------------------------- + + \fn vos_mem_compare() + + \brief vos_mem_compare() - Memory compare + + Function to compare two pieces of memory, similar to memcmp function + in standard C. + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return v_BOOL_t - returns a boolean value that tells if the memory + locations are equal or not equal. + + -------------------------------------------------------------------------------*/ +v_BOOL_t vos_mem_compare( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ); + + +/** --------------------------------------------------------------------------- + + \fn vos_mem_compare2() + + \brief vos_mem_compare2() - Memory compare + + Function to compare two pieces of memory, similar to memcmp function + in standard C. + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return v_SINT_t - returns a boolean value that tells if the memory + locations are equal or not equal. + 0 -- equal + < 0 -- *pMemory1 is less than *pMemory2 + > 0 -- *pMemory1 is bigger than *pMemory2 + + -------------------------------------------------------------------------------*/ +v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ); + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. This memory will have special attributes making it DMA friendly i.e. + it will exist in contiguous, 32-byte aligned uncached memory. A normal + vos_mem_malloc does not yield memory with these attributes. + + NOTE: the special DMA friendly memory is very scarce and this API must be + used sparingly + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +#define vos_mem_dma_malloc(size) vos_mem_dma_malloc_debug(size, __FILE__, __LINE__) +v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum); +#else +v_VOID_t * vos_mem_dma_malloc( v_SIZE_t size ); +#endif + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_free() - vOSS DMA Free Memory + + This function will free special DMA friendly memory pointed to by 'ptr'. + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ); + +#ifdef DMA_DIRECT_ACCESS +/*---------------------------------------------------------------------------- + + \brief vos_mem_set_dma_ptr() - vOSS DMA memory poiter set by SAL + + This function will set DMA Physical memory pointer. + + + \param dmaBuffer - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_set_dma_ptr(unsigned char *dmaBuffer); +#endif /* DMA_DIRECT_ACCESS */ + +/* + * Function to check whether the current context is in + * irq context + */ +v_BOOL_t vos_is_in_irq_context(void); +#endif // __VOSS_LOCK_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_mq.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_mq.h new file mode 100644 index 0000000000000..878fe86de2352 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_mq.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_MQ_H ) +#define __VOS_MQ_H + +/**========================================================================= + + \file vos_mq.h + + \brief virtual Operating System Services (vOSS) message queue APIs + + Message Queue Definitions and API + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// vos Message Type. +/// This represnets a message that can be posted to another module through +/// the voss Message Queues. +/// +/// \note This is mapped directly to the tSirMsgQ for backward +/// compatibility with the legacy MAC code. + +typedef struct vos_msg_s +{ + v_U16_t type; + /* + * This field can be used as sequence number/dialog token for matching + * requests and responses. + */ + v_U16_t reserved; + /** + * Based on the type either a bodyptr pointer into + * memory or bodyval as a 32 bit data is used. + * bodyptr: is always a freeable pointer, one should always + * make sure that bodyptr is always freeable. + * + * Messages should use either bodyptr or bodyval; not both !!!. + */ + void *bodyptr; + + v_U32_t bodyval; + + /* + * Some messages provide a callback function. The function signature + * must be agreed upon between the two entities exchanging the message + */ + void *callback; + +} vos_msg_t; + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/// Message Queue IDs +typedef enum +{ + /// Message Queue ID for messages bound for SME + VOS_MQ_ID_SME = VOS_MODULE_ID_SME, + + /// Message Queue ID for messages bound for PE + VOS_MQ_ID_PE = VOS_MODULE_ID_PE, + + /// Message Queue ID for messages bound for WDA + VOS_MQ_ID_WDA = VOS_MODULE_ID_WDA, + + /// Message Queue ID for messages bound for TL + VOS_MQ_ID_TL = VOS_MODULE_ID_TL, + + /// Message Queue ID for messages bound for the SYS module + VOS_MQ_ID_SYS = VOS_MODULE_ID_SYS, + +} VOS_MQ_ID; + + +/**--------------------------------------------------------------------------- + + \brief vos_mq_post_message() - post a message to a message queue + + This API allows messages to be posted to a specific message queue. Messages + can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_mq_post_message( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + + +/**--------------------------------------------------------------------------- + + \brief vos_tx_mq_serialize() - serialize a message to the Tx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Tx execution flow can be posted only + to the following queue. + +
    +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_tx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + +/**--------------------------------------------------------------------------- + + \brief vos_rx_mq_serialize() - serialize a message to the Rx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Rx execution flow can be posted only + to the following queue. + +
    +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_rx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + + +#endif // if !defined __VOS_MQ_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_nvitem.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_nvitem.h new file mode 100644 index 0000000000000..9270fcf08e09c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_nvitem.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_NVITEM_H ) +#define __VOS_NVITEM_H + +/**========================================================================= + + \file vos_nvitem.h + + \brief virtual Operating System Services (vOSS): Non-Volatile storage API + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_status.h" +#include "wlan_nv.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_COUNTRY_CODE_LEN 2 +#define VOS_MAC_ADDRESS_LEN 6 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +// enum of regulatory doamains in WLAN +typedef enum +{ + REGDOMAIN_FCC, + REGDOMAIN_ETSI, + REGDOMAIN_JAPAN, + REGDOMAIN_WORLD, + REGDOMAIN_N_AMER_EXC_FCC, + REGDOMAIN_APAC, + REGDOMAIN_KOREA, + REGDOMAIN_HI_5GHZ, + REGDOMAIN_NO_5GHZ, + // add new regulatory domain here + REGDOMAIN_COUNT +} +v_REGDOMAIN_t; + +typedef enum +{ + COUNTRY_INIT, + COUNTRY_IE, + COUNTRY_USER, + COUNTRY_CELL_BASE, + //add new sources here + COUNTRY_QUERY, + COUNTRY_MAX = COUNTRY_QUERY +} +v_CountryInfoSource_t; + +typedef enum +{ + /* DFS Session refers to successful SAP session operating in DFS channel */ + DFS_CAC_NEVER_DONE, /* CAC was never done for this current ap / ap-ap */ + DFS_CAC_IN_PROGRESS, /* CAC is in progress for this DFS session */ + DFS_CAC_ALREADY_DONE, /* CAC already for SAP starting this DFS session */ +} +eDFS_CAC_STATUS; + +// country code type +typedef v_U8_t v_COUNTRYCODE_t[VOS_COUNTRY_CODE_LEN]; + +/**------------------------------------------------------------------------ + + \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of + a country given its country code + + The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of + a country given its country code. This is done from reading a cached + copy of the binary file. + + \param pRegDomain - pointer to regulatory domain + + \param countryCode - country code + + \param source - source of country code + + \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country + VOS_STATUS_E_FAULT - invalid pointer error + VOS_STATUS_E_EMPTY - country code table is empty + VOS_STATUS_E_EXISTS - given country code does not exist in table + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain, + const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source); + +/**------------------------------------------------------------------------ + + \brief vos_nv_getSupportedCountryCode() - get the list of supported + country codes + + The \a vos_nv_getSupportedCountryCode() encodes the list of supported + country codes with paddings in the provided buffer + + \param pBuffer - pointer to buffer where supported country codes + and paddings are encoded; this may be set to NULL + if user wishes to query the required buffer size to + get the country code list + + \param pBufferSize - this is the provided buffer size on input; + this is the required or consumed buffer size on output + + \return VOS_STATUS_SUCCESS - country codes are successfully encoded + VOS_STATUS_E_NOMEM - country codes are not encoded because either + the buffer is NULL or buffer size is + sufficient + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize, + v_SIZE_t paddingSize ); + +/**------------------------------------------------------------------------ + \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain + \return default regulatory domain + \sa + -------------------------------------------------------------------------*/ +v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void ); + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedChannels() - function to return the list of + supported channels + \param p20MhzChannels - list of 20 Mhz channels + \param pNum20MhzChannels - number of 20 Mhz channels + \param p40MhzChannels - list of 20 Mhz channels + \param pNum40MhzChannels - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels, + v_U8_t *p40MhzChannels, int *pNum40MhzChannels); + +/**------------------------------------------------------------------------ + \brief vos_nv_readDefaultCountryTable() - return the default Country table + \param table data - a union to return the default country table data in. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData ); + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelListWithPower() - function to return the list of + supported channels with the power limit info too. + \param pChannels20MHz - list of 20 Mhz channels + \param pNum20MHzChannelsFound - number of 20 Mhz channels + \param pChannels40MHz - list of 20 Mhz channels + \param pNum40MHzChannelsFound - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *pChannels20MHz /*[NUM_LEGIT_RF_CHANNELS] */, + tANI_U8 *pNum20MHzChannelsFound, + tChannelListWithPower *pChannels40MHz /*[NUM_CHAN_BOND_CHANNELS] */, + tANI_U8 *pNum40MHzChannelsFound + ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_open() - initialize the NV module + + The \a vos_nv_open() initializes the NV module. This function read the binary + file qcom_nv.bin for macaddress,country code,regulatory domain information and etc. + + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_open(void); + +/**------------------------------------------------------------------------ + + \brief vos_nv_close() - uninitialize the NV module + + The \a vos_nv_init() uninitializes the NV module. This function release the binary + file qcom_nv.bin data buffer. + + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_nv_close(void); + +/**------------------------------------------------------------------------ + \brief vos_nv_setRegDomain - + \param clientCtxt - Client Context, Not used for PRIMA + regId - Regulatory Domain ID + sendRegHint - send hint to cfg80211 + \return status set REG domain operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + v_BOOL_t sendRegHint); + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelEnabledState - + \param rfChannel - input channel number to know enabled state + \return eNVChannelEnabledType enabled state for channel + * enabled + * disabled + * DFS + \sa + -------------------------------------------------------------------------*/ +eNVChannelEnabledType vos_nv_getChannelEnabledState(v_U32_t rfChannel); + +#define VOS_IS_DFS_CH(channel) (vos_nv_getChannelEnabledState((channel)) == \ + NV_CHANNEL_DFS) + +VOS_STATUS vos_init_wiphy_from_nv_bin(void); +VOS_STATUS vos_init_wiphy_from_eeprom(void); +#endif // __VOS_NVITEM_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_pack_align.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_pack_align.h new file mode 100644 index 0000000000000..7da83bd8af200 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_pack_align.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_PACK_ALIGN_H ) +#define __VOS_PACK_ALIGN_H + +/**========================================================================= + + \file vos_pack_align.h + + \brief virtual Operating System Servies (vOS) pack and align primitives + + Definitions for platform independent means of packing and aligning + data structures + + ========================================================================*/ + +/* + + Place the macro VOS_PACK_START above a structure declaration to pack. We + are not going to allow modifying the pack size because pack size cannot be + specified in AMSS and GNU. Place the macro VOS_PACK_END below a structure + declaration to stop the pack. This requirement is necessitated by Windows + which need pragma based prolog and epilog. + + Pack-size > 1-byte is not supported since gcc and arm do not support that. + + Here are some examples + + 1. Pack-size 1-byte foo_t across all platforms + + VOS_PACK_START + typedef VOS_PACK_PRE struct foo_s { ... } VOS_PACK_POST foo_t; + VOS_PACK_END + + 2. 2-byte alignment for foo_t across all platforms + + typedef VOS_ALIGN_PRE(2) struct foo_s { ... } VOS_ALIGN_POST(2) foo_t; + + 3. Pack-size 1-byte and 2-byte alignment for foo_t across all platforms + + VOS_PACK_START + typedef VOS_PACK_PRE VOS_ALIGN_PRE(2) struct foo_s { ... } VOS_ALIGN_POST(2) VOS_PACK_POST foo_t; + VOS_PACK_END + +*/ + +#if defined __GNUC__ + + #define VOS_PACK_START + #define VOS_PACK_END + + #define VOS_PACK_PRE + #define VOS_PACK_POST __attribute__((__packed__)) + + #define VOS_ALIGN_PRE(__value) + #define VOS_ALIGN_POST(__value) __attribute__((__aligned__(__value))) + +#elif defined __arm + + #define VOS_PACK_START + #define VOS_PACK_END + + #define VOS_PACK_PRE __packed + #define VOS_PACK_POST + + #define VOS_ALIGN_PRE(__value) __align(__value) + #define VOS_ALIGN_POST(__value) + +#elif defined _MSC_VER + +#define VOS_PACK_START __pragma(pack(push,1)) +#define VOS_PACK_END __pragma(pack(pop)) + + #define VOS_PACK_PRE + #define VOS_PACK_POST + + #define VOS_ALIGN_PRE(__value) __declspec(align(__value)) + #define VOS_ALIGN_POST(__value) + +#else + + #error Unsupported compiler!!! + +#endif + +#endif // __VOSS_PACK_ALIGN_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_packet.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_packet.h new file mode 100644 index 0000000000000..a6121429fce63 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_packet.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_PKT_H ) +#define __VOS_PKT_H + +/**========================================================================= + + \file vos_packet.h + + \brief virtual Operating System Services (vOSS) network Packet APIs + + Network Protocol packet/buffer support interfaces + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +struct vos_pkt_t; +typedef struct vos_pkt_t vos_pkt_t; + + +#ifdef QCA_PKT_PROTO_TRACE +#include "adf_nbuf.h" + +#define VOS_PKT_TRAC_TYPE_EAPOL NBUF_PKT_TRAC_TYPE_EAPOL +#define VOS_PKT_TRAC_TYPE_DHCP NBUF_PKT_TRAC_TYPE_DHCP +#define VOS_PKT_TRAC_TYPE_MGMT_ACTION NBUF_PKT_TRAC_TYPE_MGMT_ACTION /* Managment action frame */ + +#define VOS_PKT_TRAC_DUMP_CMD 9999 + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_get_proto_type() - + Find protoco type from packet contents + + * skb Packet Pointer + * tracking_map packet type want to track + * dot11_type, frame type when the frame is in dot11 format + +---------------------------------------------------------------------------*/ +v_U8_t vos_pkt_get_proto_type +( + struct sk_buff *skb, + v_U8_t tracking_map, + v_BOOL_t dot11_type +); + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_trace_buf_update() - + Update storage buffer with interest event string + + * event_string Event String may packet type or outstanding event + +---------------------------------------------------------------------------*/ +void vos_pkt_trace_buf_update +( + char *event_string +); + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_trace_buf_dump() - + Dump stored information into kernel log + +---------------------------------------------------------------------------*/ +void vos_pkt_trace_buf_dump +( + void +); + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_proto_trace_init() - + Initialize protocol trace functionality, allocate required resource + +---------------------------------------------------------------------------*/ +void vos_pkt_proto_trace_init +( + void +); + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_proto_trace_close() - + Free required resource + +---------------------------------------------------------------------------*/ +void vos_pkt_proto_trace_close +( + void +); +#endif /* QCA_PKT_PROTO_TRACE */ + +/** + * vos_pkt_return_packet Free the voss Packet + * @ vos Packet + */ +VOS_STATUS vos_pkt_return_packet(vos_pkt_t *packet); + +/** + * vos_pkt_get_packet_length Returns the packet length + * @ vos Packet + */ +VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket, + v_U16_t *pPacketSize ); + +/* + * TODO: Remove later + * All the below difinitions are not + * required for Host Driver 2.0 + * once corresponding references are removed + * from HDD and other layers + * below code will be removed + */ +//The size of AMSDU frame per spec can be a max of 3839 bytes +// in BD/PDUs that means 30 (one BD = 128 bytes) +// we must add the size of the 802.11 header to that +#define VPKT_SIZE_BUFFER ((30 * 128) + 32) + +/// voss Packet Types +typedef enum +{ + /// voss Packet is used to transmit 802.11 Management frames. + VOS_PKT_TYPE_TX_802_11_MGMT, + + /// voss Packet is used to transmit 802.11 Data frames. + VOS_PKT_TYPE_TX_802_11_DATA, + + /// voss Packet is used to transmit 802.3 Data frames. + VOS_PKT_TYPE_TX_802_3_DATA, + + /// voss Packet contains Received data of an unknown frame type + VOS_PKT_TYPE_RX_RAW, + + /// Invalid sentinel value + VOS_PKT_TYPE_MAXIMUM + +} VOS_PKT_TYPE; + +/// user IDs. These IDs are needed on the vos_pkt_get/set_user_data_ptr() +/// to identify the user area in the voss Packet. +typedef enum +{ + VOS_PKT_USER_DATA_ID_TL =0, + VOS_PKT_USER_DATA_ID_BAL, + VOS_PKT_USER_DATA_ID_WDA, + VOS_PKT_USER_DATA_ID_HDD, + VOS_PKT_USER_DATA_ID_BAP, + VOS_PKT_USER_DATA_ID_BSL, + + VOS_PKT_USER_DATA_ID_MAX + +} VOS_PKT_USER_DATA_ID; + +typedef VOS_STATUS ( *vos_pkt_get_packet_callback )( vos_pkt_t *pPacket, + v_VOID_t *userData ); + +VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE pktType, + v_SIZE_t *vosFreeBuffer); +VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket, + v_VOID_t **ppOSPacket, + v_BOOL_t clearOSPacket ); +VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_VOID_t *pOSPacket, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ); +VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket, + v_VOID_t *pOSPacket ); +VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket, + v_TIME_t* pTstamp ); +VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket, + vos_pkt_t **ppChainedPacket, + v_BOOL_t unchainPacket ); +VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t **ppPacketData, + v_SIZE_t numBytes ); +VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_SIZE_t dataSize, + v_SIZE_t numPackets, + v_BOOL_t zeroBuffer, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ); +VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ); +VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ); +VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ); +v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t **ppUserData ); +v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t *pUserData ); +VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t *pOutputBuffer, + v_SIZE_t *pOutputBufferSize ); +#endif // !defined( __VOS_PKT_H ) diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_status.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_status.h new file mode 100644 index 0000000000000..663d626fb1512 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_status.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_STATUS_H ) +#define __VOS_STATUS_H + +/**========================================================================= + + \file vos_Status.h + + \brief virtual Operating System Services (vOSS) Status codes + + Basic status codes/definitions used by vOSS + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef enum +{ + /// Request succeeded! + VOS_STATUS_SUCCESS, + + /// Request failed because system resources (other than memory) to + /// fulfill request are not available. + VOS_STATUS_E_RESOURCES, + + /// Request failed because not enough memory is available to + /// fulfill the request. + VOS_STATUS_E_NOMEM, + + /// Request could not be fulfilled at this time. Try again later. + VOS_STATUS_E_AGAIN, + + /// Request failed because there of an invalid request. This is + /// typically the result of invalid parameters on the request. + VOS_STATUS_E_INVAL, + + /// Request failed because handling the request would cause a + /// system fault. This error is typically returned when an + /// invalid pointer to memory is detected. + VOS_STATUS_E_FAULT, + + /// Request refused becayse a request is already in progress and + /// another cannot be handled currently. + VOS_STATUS_E_ALREADY, + + /// Request failed because the message (type) is bad, invalid, or + /// not properly formatted. + VOS_STATUS_E_BADMSG, + + /// Request failed because device or resource is busy. + VOS_STATUS_E_BUSY, + + /// Request did not complete because it was canceled. + VOS_STATUS_E_CANCELED, + + /// Request did not complete because it was aborted. + VOS_STATUS_E_ABORTED, + + /// Request failed because the request is valid, though not supported + /// by the entity processing the request. + VOS_STATUS_E_NOSUPPORT, + + /// Operation is not permitted. + VOS_STATUS_E_PERM, + + /// Request failed because of an empty condition + VOS_STATUS_E_EMPTY, + + /// Existance failure. Operation could not be completed because + /// something exists or does not exist. + VOS_STATUS_E_EXISTS, + + /// Operation timed out + VOS_STATUS_E_TIMEOUT, + + /// Request failed for some unknown reason. Note don't use this + /// status unless nothing else applies + VOS_STATUS_E_FAILURE + +} VOS_STATUS; + +/// Macro to determine if a VOS_STATUS type is success. All callers +/// wanting to interpret VOS_STATUS should use this macro to check +/// for success to protect against the VOS_STATUS definitions +/// changing. +/// +/// Use like this... +/// +/// if ( VOS_STATUS_SUCCESS( vosStatus ) ) ... +/// +#define VOS_IS_STATUS_SUCCESS( status ) ( VOS_STATUS_SUCCESS == ( status ) ) + + + +#endif // if !defined __VOS_STATUS_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_threads.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_threads.h new file mode 100644 index 0000000000000..613152e1d0b31 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_threads.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_THREADS_H ) +#define __VOS_THREADS_H + +/**========================================================================= + + \file vos_threads.h + + \brief virtual Operating System Services (vOSS) Threading APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_sleep() - sleep + + The \a vos_sleep() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param msInterval - the number of milliseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep( v_U32_t msInterval ); + +/*---------------------------------------------------------------------------- + + \brief vos_sleep_us() - sleep + + The \a vos_sleep_us() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param usInterval - the number of microseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep_us( v_U32_t usInterval ); + + +/*---------------------------------------------------------------------------- + + \brief vos_busy_wait() - busy wait + + The \a vos_busy_wait() function places the current thread in busy wait + until the specified time out interval elapses. If the interval is greater + than 50us on WM, the behaviour is undefined. + + \param usInterval - the number of microseconds to busy wait. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_busy_wait( v_U32_t usInterval ); + +#endif // __VOS_THREADS_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_timer.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_timer.h new file mode 100644 index 0000000000000..96ecfd1934f96 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_timer.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TIMER_H ) +#define __VOS_TIMER_H + +/**========================================================================= + + \file vos_timer.h + + \brief virtual Operating System Servies (vOS) + + Definitions for vOSS Timer services + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include + +#ifdef TIMER_MANAGER +#include "wlan_hdd_dp_utils.h" +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_TIMER_STATE_COOKIE 0x12 +#define VOS_TIMER_TO_MS_UNIT 1000 +#define VOS_TIMER_TO_SEC_UNIT 1000000 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/// vos Timer callback function prototype (well, actually a prototype for +/// a pointer to this callback function) +typedef v_VOID_t ( *vos_timer_callback_t )( v_PVOID_t userData ); + +typedef enum +{ + /// pure software timer. No guarantee the apps processor will + /// awaken when these timers expire. + VOS_TIMER_TYPE_SW, + + /// These timers can awaken the Apps processor from power collapse + /// when these timers expire. + /// \todo I really dont like this name :-) + VOS_TIMER_TYPE_WAKE_APPS + +} VOS_TIMER_TYPE; + +typedef enum +{ + VOS_TIMER_STATE_UNUSED = VOS_TIMER_STATE_COOKIE, + VOS_TIMER_STATE_STOPPED, + VOS_TIMER_STATE_STARTING, + VOS_TIMER_STATE_RUNNING, +} VOS_TIMER_STATE; + +#ifdef TIMER_MANAGER +struct vos_timer_s; +typedef struct timer_node_s +{ + hdd_list_node_t pNode; + char* fileName; + unsigned int lineNum; + struct vos_timer_s *vosTimer; +}timer_node_t; +#endif + +typedef struct vos_timer_s +{ +#ifdef TIMER_MANAGER + timer_node_t *ptimerNode; +#endif + + vos_timer_platform_t platformInfo; + vos_timer_callback_t callback; + v_PVOID_t userData; + vos_lock_t lock; + VOS_TIMER_TYPE type; + VOS_TIMER_STATE state; +} vos_timer_t; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +void vos_timer_manager_init(void); +void vos_timer_exit(void); +#endif + +/*--------------------------------------------------------------------------- + + \brief vos_timer_getCurrentState() - Get the current state of the timer + + \param pTimer - the timer object + + \return timer state + + \sa + +---------------------------------------------------------------------------*/ +VOS_TIMER_STATE vos_timer_getCurrentState( vos_timer_t *pTimer ); + +/*-------------------------------------------------------------------------- + + \brief vos_timer_init() - Initialize a vOSS timer. + + This API initializes a vOS Timer object. + + The \a vos_timer_init() initializes a vOS Timer object. A timer must be + initialized by calling vos_timer_initialize() before it may be used in + any other timer functions. + + Attempting to initialize timer that is already initialized results in + a failure. A destroyed timer object can be re-initialized with a call to + \a vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer such + as vos_timer_set() will fail if the timer is not initialized or has + been destroyed. Therefore, don't use the timer after it has been + destroyed until it has been re-initialized. + + All callback will be executed within the VOS main thread unless it is + initialized from the Tx thread flow, in which case it will be executed + within the tx thread flow. + + \param timer - pointer to the opaque timer object to initialize + + \param timerType - specifies the type of timer. We have two different + timer types. +
    +
  1. VOS_TIMER_TYPE_SW - Pure software timer. The Apps processor + may not be awoken when this timer expires. +
  2. VOS_TIMER_TYPE_WAKE_APPS - The Apps processor will be awoken + from power collapse when this type of timer expires. +
+ + \param callback - the callback function to be called when the timer + expires. + + \param userData - a user data (or context) that is returned to the + callback function as a parameter when the timer expires. + + \return VOS_STATUS_SUCCESS - timer was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the timer + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the timer + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to initialize the object referenced by timer, a previously + initialized but not yet destroyed timer. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +#define vos_timer_init(timer, timerType, callback, userdata) \ + vos_timer_init_debug(timer, timerType, callback, userdata, __FILE__, __LINE__) + +VOS_STATUS vos_timer_init_debug( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData, + char* fileName, v_U32_t lineNum ); +#else +VOS_STATUS vos_timer_init( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData ); +#endif + +/*--------------------------------------------------------------------------- + + \brief vos_timer_destroy() - Destroy a vOSS Timer object + + The \a vos_timer_destroy() function shall destroy the timer object. + After a successful return from \a vos_timer_destroy() the timer + object becomes, in effect, uninitialized. + + A destroyed timer object can be re-initialized by calling + vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer, such + as vos_timer_set() will fail if the lock is destroyed. Therefore, + don't use the timer after it has been destroyed until it has + been re-initialized. + + \param timer - the timer object to be destroyed. + + \return VOS_STATUS_SUCCESS - timer was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by timer while it is still + still referenced. The timer must be stopped before it can be + destroyed. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_destroy( vos_timer_t *timer ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_start() - Start a vOSS Timer object + + The \a vos_timer_start() function starts a timer to expire after the + specified interval, thus running the timer callback function when + the interval expires. + + A timer only runs once (a one-shot timer). To re-start the + timer, vos_timer_start() has to be called after the timer runs + or has been cancelled. + + \param timer - the timer object to be started + + \param expirationTime - expiration time for the timer (in milliseconds) + The expiration time cannot be less than 10 ms. + + \return VOS_STATUS_SUCCESS - timer was successfully started. + + VOS_STATUS_E_ALREADY - The implementation has detected an attempt + to start a timer while it is already started. The timer must + be stopped or expire before it can be started again. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_start( vos_timer_t *timer, v_U32_t expirationTime ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_stop() - Stop a vOSS Timer + + The \a vos_timer_stop() function stops a timer that has been started but + has not expired, essentially cancelling the 'start' request. + + After a timer is stopped, it goes back to the state it was in after it + was created and can be started again via a call to vos_timer_start(). + + \param timer - the timer object to be stopped + + \return VOS_STATUS_SUCCESS - timer was successfully stopped. + + VOS_STATUS_E_EMPTY - The implementation has detected an attempt + to stop a timer that has not been started or has already + expired. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_stop( vos_timer_t *timer ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_ticks() - Get the system time in 10ms ticks + + The \a vos_timer_get_system_ticks() function returns the current number + of timer ticks in 10msec intervals. This function is suitable timestamping + and calculating time intervals by calculating the difference between two + timestamps. + + \returns - The current system tick count (in 10msec intervals). This + function cannot fail. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_ticks( v_VOID_t ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_time() - Get the system time in milliseconds + + The \a vos_timer_get_system_time() function returns the number of milliseconds + that have elapsed since the system was started + + \returns - The current system time in milliseconds. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_time( v_VOID_t ); + + + +#endif // #if !defined __VOSS_TIMER_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_trace.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_trace.h new file mode 100644 index 0000000000000..bcf674193d400 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_trace.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TRACE_H ) +#define __VOS_TRACE_H + +/**========================================================================= + + \file vos_trace.h + + \brief virtual Operating System Servies (vOS) + + Trace, logging, and debugging definitions and APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include // For VOS_MODULE_ID... +#include // For va_list... +#include +#include + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef enum +{ + // NONE means NO traces will be logged. This value is in place for the + // vos_trace_setlevel() to allow the user to turn off all traces. + VOS_TRACE_LEVEL_NONE = 0, + + // the following trace levels are the ones that 'callers' of VOS_TRACE() + // can specify in for the VOS_TRACE_LEVEL parameter. Traces are classified + // by severity (FATAL being more serious than INFO for example). + VOS_TRACE_LEVEL_FATAL, + VOS_TRACE_LEVEL_ERROR, + VOS_TRACE_LEVEL_WARN, + VOS_TRACE_LEVEL_INFO, + VOS_TRACE_LEVEL_INFO_HIGH, + VOS_TRACE_LEVEL_INFO_MED, + VOS_TRACE_LEVEL_INFO_LOW, + VOS_TRACE_LEVEL_DEBUG, + + // ALL means all trace levels will be active. This value is in place for the + // vos_trace_setlevel() to allow the user to turn ON all traces. + VOS_TRACE_LEVEL_ALL, + + + // not a real level. Used to identify the maximum number of + // VOS_TRACE_LEVELs defined. + VOS_TRACE_LEVEL_MAX + +} VOS_TRACE_LEVEL; + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define ASSERT_BUFFER_SIZE ( 512 ) + +// below definition is obsolete and is no longer being used in BMP and WM +// TODO: remove this once this is not used on Android +#define VOS_ENABLE_TRACING +#define MAX_VOS_TRACE_RECORDS 4000 +#define INVALID_VOS_TRACE_ADDR 0xffffffff +#define DEFAULT_VOS_TRACE_DUMP_COUNT 0 + +#include + +#ifdef TRACE_RECORD + +#define MTRACE(p) p +#define NO_SESSION 0xFF + +#else +#define MTRACE(p) { } + +#endif + +/*-------------------------------------------------------------------------- + Structure definition + ------------------------------------------------------------------------*/ +typedef struct svosTraceRecord +{ + v_U64_t time; + v_U8_t module; + v_U8_t code; + v_U16_t session; + v_U32_t data; + uint32_t pid; +}tvosTraceRecord, *tpvosTraceRecord; + +typedef struct svosTraceData +{ + // MTRACE logs are stored in ring buffer where head represents the position + // of first record, tail represents the position of last record added till + // now and num is the count of total record added. + v_U32_t head; + v_U32_t tail; + v_U32_t num; + v_U16_t numSinceLastDump; + + //Config for controlling the trace + v_U8_t enable; + v_U16_t dumpCount; //will dump after number of records reach this number. + +}tvosTraceData; + + +#define CASE_RETURN_STRING( str ) \ + case ( ( str ) ): return( (tANI_U8*)(#str) ); + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + + \brief vos_trace_setLevel() - Set the trace level for a particular module + + This is an external API that allows trace levels to be set for each module. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void vos_trace_setLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ); + +/**---------------------------------------------------------------------------- + + \brief vos_trace_getLevel() - Get the trace level + + This is an external API that returns a boolean value to signify if a + particular trace level is set for the specified module. + + \param level - trace level. A member of the VOS_TRACE_LEVEL enumeration + indicating the severity of the condition causing the trace + message to be issued. + + Note that individual trace levels are the only valid values + for this API. VOS_TRACE_LEVEL_NONE and VOS_TRACE_LEVEL_ALL + are not valid input and will return FALSE + + \return VOS_FALSE - the specified trace level for the specified module is OFF + + VOS_TRUE - the specified trace level for the specified module is ON + + \sa vos_trace_setLevel() + --------------------------------------------------------------------------*/ +v_BOOL_t vos_trace_getLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ); + +typedef void (*tpvosTraceCb) (void *pMac, tpvosTraceRecord, v_U16_t); +void vos_trace(v_U8_t module, v_U8_t code, v_U16_t session, v_U32_t data); +void vosTraceRegister(VOS_MODULE_ID, tpvosTraceCb); +VOS_STATUS vos_trace_spin_lock_init(void); +void vosTraceInit(void); +void vosTraceEnable(v_U32_t, v_U8_t enable); +void vosTraceDumpAll(void*, v_U8_t, v_U8_t, v_U32_t, v_U32_t); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_types.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_types.h new file mode 100644 index 0000000000000..3ba85554936e2 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_types.h @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TYPES_H ) +#define __VOS_TYPES_H +/**========================================================================= + \file vos_Types.h + + \brief virtual Operating System Servies (vOS) + + Basic type definitions + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "i_vos_types.h" +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +// macro to get maximum of two values. +#define VOS_MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) ) + +// macro to get minimum of two values +#define VOS_MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) ) + +// macro to get the ceiling of an integer division operation... +#define VOS_CEIL_DIV( _a, _b ) (( 0 != (_a) % (_b) ) ? ( (_a) / (_b) + 1 ) : ( (_a) / (_b) )) + +// macro to return the floor of an integer division operation +#define VOS_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) ) + +#define VOS_SWAP_U16(_x) \ + ( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) ) + +#define VOS_SWAP_U32(_x) \ + (( ( ( (_x) << 24 ) & 0xFF000000 ) | ( ( (_x) >> 24 ) & 0x000000FF ) ) | \ + ( ( ( (_x) << 8 ) & 0x00FF0000 ) | ( ( (_x) >> 8 ) & 0x0000FF00 ) )) + +// Endian operations for Big Endian and Small Endian modes +#ifdef ANI_LITTLE_BYTE_ENDIAN + +#define vos_cpu_to_be32(_x) VOS_SWAP_U32(_x) +#define vos_be32_to_cpu(_x) VOS_SWAP_U32(_x) +#define vos_cpu_to_be16(_x) VOS_SWAP_U16(_x) +#define vos_be16_to_cpu(_x) VOS_SWAP_U16(_x) +#define vos_cpu_to_le32(_x) (_x) +#define vos_le32_to_cpu(_x) (_x) +#define vos_cpu_to_le16(_x) (_x) +#define vos_le16_to_cpu(_x) (_x) + +#endif + +#ifdef ANI_BIG_BYTE_ENDIAN + +#define vos_cpu_to_be32(_x) (_x) +#define vos_be32_to_cpu(_x) (_x) +#define vos_cpu_to_be16(_x) (_x) +#define vos_be16_to_cpu(_x) (_x) +#define vos_cpu_to_le32(_x) VOS_SWAP_U32(_x) +#define vos_le32_to_cpu(_x) VOS_SWAP_U32(_x) +#define vos_cpu_to_le16(_x) VOS_SWAP_U16(_x) +#define vos_le16_to_cpu(_x) VOS_SWAP_U16(_x) + +#endif + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// Module IDs. These are generic IDs that identify the various modules +/// in the software system. +typedef enum +{ + VOS_MODULE_ID_BAP = 0, + VOS_MODULE_ID_TL = 1, + VOS_MODULE_ID_WDI = 2, + // 3 & 4 are unused for historical purposes + VOS_MODULE_ID_RSV3 = 3, + VOS_MODULE_ID_RSV4 = 4, + VOS_MODULE_ID_HDD = 5, + VOS_MODULE_ID_SME = 6, + VOS_MODULE_ID_PE = 7, + VOS_MODULE_ID_WDA = 8, + VOS_MODULE_ID_SYS = 9, + VOS_MODULE_ID_VOSS = 10, + VOS_MODULE_ID_SAP = 11, + VOS_MODULE_ID_HDD_SOFTAP = 12, + VOS_MODULE_ID_PMC = 13, + VOS_MODULE_ID_HDD_DATA = 14, + VOS_MODULE_ID_HDD_SAP_DATA = 15, + + VOS_MODULE_ID_HIF = 16, + VOS_MODULE_ID_HTC = 17, + VOS_MODULE_ID_TXRX = 18, + VOS_MODULE_ID_ADF = 19, + VOS_MODULE_ID_CFG = 20, + + // not a real module ID. This is used to identify the maxiumum + // number of VOS_MODULE_IDs and should always be at the END of + // this enum. If IDs are added, they need to go in front of this + VOS_MODULE_ID_MAX + +} VOS_MODULE_ID; + + +/// Concurrency role. These are generic IDs that identify the various roles +/// in the software system. +typedef enum +{ /*ON linux maintain 1-1 corespondence with device_mode_t in hdd*/ + VOS_STA_MODE=0, + VOS_STA_SAP_MODE=1, //to support softAp mode . This is misleading. It means AP MODE only. + //The constant name has historical reason + VOS_P2P_CLIENT_MODE, + VOS_P2P_GO_MODE, + VOS_MONITOR_MODE, + VOS_FTM_MODE = 5, + VOS_IBSS_MODE, + VOS_P2P_DEVICE_MODE, + VOS_MAX_NO_OF_MODE +} tVOS_CON_MODE; + +#ifdef WLAN_OPEN_P2P_INTERFACE +#define VOS_MAX_CONCURRENCY_PERSONA 4 // This should match with WLAN_MAX_INTERFACES +#else +#define VOS_MAX_CONCURRENCY_PERSONA 3 +#endif + +//This is a bit pattern to be set for each mode +//bit 0 - sta mode +//bit 1 - ap mode +//bit 2 - p2p client mode +//bit 3 - p2p go mode +typedef enum +{ + VOS_STA=1, + VOS_SAP=2, + VOS_STA_SAP=3, //to support sta, softAp mode . This means STA+AP mode + VOS_P2P_CLIENT=4, + VOS_P2P_GO=8, +} tVOS_CONCURRENCY_MODE; + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +typedef enum +{ + VOS_MCC_TO_SCC_SWITCH_DISABLE = 0, + VOS_MCC_TO_SCC_SWITCH_ENABLE, + VOS_MCC_TO_SCC_SWITCH_FORCE, + VOS_MCC_TO_SCC_SWITCH_MAX +} tVOS_MCC_TO_SCC_SWITCH_MODE; +#endif + +#if !defined( NULL ) +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +enum +{ + VOS_FALSE = 0, + VOS_TRUE = ( !VOS_FALSE ) +}; + +/// pointer to void types +typedef v_VOID_t *v_PVOID_t; + +/// "Size" type... +typedef v_UINT_t v_SIZE_t; + +/// 'Time' type +typedef v_ULONG_t v_TIME_t; + +// typedef for VOSS Context... +typedef v_VOID_t *v_CONTEXT_t; + + +/// MAC address data type and corresponding macros/functions to +/// manipulate MAC addresses... +/// Macro defining the size of a MAC Address... +#define VOS_MAC_ADDR_SIZE ( 6 ) + +typedef struct +{ + /// the bytes that make up the macAddress. + v_BYTE_t bytes[ VOS_MAC_ADDR_SIZE ]; + +} v_MACADDR_t; + + +/// This macro is used to initialize a vOSS MacAddress to the +/// broadcast MacAddress. It is used like this... +/// v_MACADDR_t macAddress = VOS_MAC_ADDR_BROADCAST_INITIALIZER; +#define VOS_MAC_ADDR_BROADCAST_INITIALIZER { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } + +/// This macro is used to initialize a vOSS MacAddress to zero +/// It is used like this... +/// v_MACADDR_t macAddress = VOS_MAC_ADDR_ZERO_INITIALIZER; +#define VOS_MAC_ADDR_ZERO_INITIALIZER { { 0, 0, 0, 0, 0, 0 } } + +#define VOS_IPV4_ADDR_SIZE ( 4 ) + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_equal() - compare two vOSS MacAddress + + This function returns a boolean that tells if a two vOSS MacAddress' + are equivalent. + + \param pMacAddr1 - pointer to one voss MacAddress to compare + \param pMacAddr2 - pointer to the other voss MacAddress to compare + + \return true - the MacAddress's are equal + not true - the MacAddress's are not equal + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_equal( v_MACADDR_t *pMacAddr1, + v_MACADDR_t *pMacAddr2 ) +{ + return ( 0 == memcmp( pMacAddr1, pMacAddr2, VOS_MAC_ADDR_SIZE ) ); +} + + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_zero() - check for a MacAddress of all zeros. + + This function returns a boolean that tells if a MacAddress is made up of + all zeros. + + \param pMacAddr - pointer to the v_MACADDR_t to check. + + \return true - the MacAddress is all Zeros + not true - the MacAddress is not all Zeros. + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_zero( v_MACADDR_t *pMacAddr ) +{ + v_MACADDR_t zeroMacAddr = VOS_MAC_ADDR_ZERO_INITIALIZER; + + return( vos_is_macaddr_equal( pMacAddr, &zeroMacAddr ) ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_zero_macaddr() - zero out a MacAddress + + This function zeros out a vOSS MacAddress type. + + \param pMacAddr - pointer to the v_MACADDR_t to zero. + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_zero_macaddr( v_MACADDR_t *pMacAddr ) +{ + memset( pMacAddr, 0, VOS_MAC_ADDR_SIZE ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_group() - check for a MacAddress is a 'group' address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "group" address. Group addresses have the 'group address bit' turned + on in the MacAddress. Group addresses are made up of Broadcast and + Multicast addresses. + + \param pMacAddr1 - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a Group address + not true - the input MacAddress is not a Group address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_group( v_MACADDR_t *pMacAddr ) +{ + return( pMacAddr->bytes[ 0 ] & 0x01 ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_broadcast() - check for a MacAddress is a broadcast address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "broadcast" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a broadcast address + not true - the input MacAddress is not a broadcast address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_broadcast( v_MACADDR_t *pMacAddr ) +{ + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + return( vos_is_macaddr_equal( pMacAddr, &broadcastMacAddr ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_multicast() - check for a MacAddress is a multicast address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "Multicast" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a Multicast address + not true - the input MacAddress is not a Multicast address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_multicast( v_MACADDR_t *pMacAddr ) +{ + return( vos_is_macaddr_group( pMacAddr ) && + !vos_is_macaddr_broadcast( pMacAddr ) ); +} + + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_directed() - check for a MacAddress is a directed address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "directed" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a directed address + not true - the input MacAddress is not a directed address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_directed( v_MACADDR_t *pMacAddr ) +{ + return( !vos_is_macaddr_group( pMacAddr ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_copy_macaddr() - copy a vOSS MacAddress + + This function copies a vOSS MacAddress into another vOSS MacAddress. + + \param pDst - pointer to the voss MacAddress to copy TO (the destination) + \param pSrc - pointer to the voss MacAddress to copy FROM (the source) + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_copy_macaddr( v_MACADDR_t *pDst, v_MACADDR_t *pSrc ) +{ + *pDst = *pSrc; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_set_macaddr_broadcast() - set a vOSS MacAddress to the 'broadcast' + + This function sets a vOSS MacAddress to the 'broadcast' MacAddress. Broadcast + MacAddress contains all 0xFF bytes. + + \param pMacAddr - pointer to the voss MacAddress to set to broadcast + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_set_macaddr_broadcast( v_MACADDR_t *pMacAddr ) +{ + memset( pMacAddr, 0xff, VOS_MAC_ADDR_SIZE ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_set() - set a variable atomically + + \param pTarget - pointer to the variable to set. + + \param value - the value to set in the variable. + + \return This function returns the value previously in the uintptr_t before + the new value is set. + + \sa vos_atomic_increment_U32(), vos_atomic_decrement_U32() + + --------------------------------------------------------------------------*/ +uintptr_t vos_atomic_set( uintptr_t *pTarget, uintptr_t value ); + + +// TODO: the below function is a stub to perform atomic set on a BYTE +// Clearly the function below is not an atomic function +VOS_INLINE_FN v_U8_t vos_atomic_set_U8( v_U8_t *pVariable, v_U8_t value ) +{ + if (pVariable == NULL) + { + return 0; + } + *pVariable = value; + return value; +} + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32() - Increment a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to increment. + + \return This function returns the value of the variable after the + increment occurs. + + \sa vos_atomic_decrement_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32( v_U32_t *pTarget ); + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32() - Decrement a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to decrement. + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32( v_U32_t *pTarget ); + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32_by_value() - Increment a U32 variable atomically + by a given value + + \param pTarget - pointer to the v_U32_t to decrement. + \param value - the value that needs to be added to target + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32_by_value( v_U32_t *pTarget, v_U32_t value ); + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32_by_value() - Decrement a U32 variable atomically + by a given value + + \param pTarget - pointer to the v_U32_t to decrement. + \param value - the value that needs to be substracted from target + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32_by_value( v_U32_t *pTarget, v_U32_t value ); + + +v_U32_t vos_get_skip_ssid_check(void); + +v_U32_t vos_get_skip_11e_check(void); + + + +#endif // if !defined __VOSS_TYPES_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_utils.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_utils.h new file mode 100644 index 0000000000000..f3f32dfc94dc7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/vos_utils.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __VOS_UTILS_H ) +#define __VOS_UTILS_H + +/**========================================================================= + + \file vos_utils.h + + \brief virtual Operating System Services (vOSS) utility APIs + + Various utility functions + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +//#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_DIGEST_SHA1_SIZE 20 +#define VOS_DIGEST_MD5_SIZE 16 +#define VOS_BAND_2GHZ 1 +#define VOS_BAND_5GHZ 2 + +#define VOS_24_GHZ_BASE_FREQ 2407 +#define VOS_5_GHZ_BASE_FREQ 5000 +#define VOS_24_GHZ_CHANNEL_14 14 +#define VOS_24_GHZ_CHANNEL_15 15 +#define VOS_24_GHZ_CHANNEL_27 27 +#define VOS_CHAN_SPACING_5MHZ 5 +#define VOS_CHAN_SPACING_20MHZ 20 +#define VOS_CHAN_14_FREQ 2484 +#define VOS_CHAN_15_FREQ 2512 +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv ); + +VOS_STATUS vos_crypto_deinit( v_U32_t hCryptProv ); + + + +/** + * vos_rand_get_bytes + + * FUNCTION: + * Returns cryptographically secure pseudo-random bytes. + * + * + * @param pbBuf - the caller allocated location where the bytes should be copied + * @param numBytes the number of bytes that should be generated and + * copied + * + * @return VOS_STATUS_SUCCSS if the operation succeeds +*/ +VOS_STATUS vos_rand_get_bytes( v_U32_t handle, v_U8_t *pbBuf, v_U32_t numBytes ); + + +/** + * vos_sha1_hmac_str + * + * FUNCTION: + * Generate the HMAC-SHA1 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant SHA1 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +VOS_STATUS vos_sha1_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *text, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *key, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_SHA1_SIZE]);/* caller digest to be filled in */ + +/** + * vos_md5_hmac_str + * + * FUNCTION: + * Generate the HMAC-MD5 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant MD5 HMAC (16B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +VOS_STATUS vos_md5_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *text, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *key, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_MD5_SIZE]);/* caller digest to be filled in */ + + + +VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *Encrypted, + v_U8_t *pKey); /* pointer to authentication key */ + + +VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *pDecrypted, + v_U8_t *pKey); /* pointer to authentication key */ + +v_U32_t vos_chan_to_freq(v_U8_t chan); +v_U8_t vos_freq_to_chan(v_U32_t freq); +v_U8_t vos_chan_to_band(v_U32_t chan); +#ifdef WLAN_FEATURE_11W +v_BOOL_t vos_is_mmie_valid(v_U8_t *key, v_U8_t *ipn, + v_U8_t* frm, v_U8_t* efrm); +v_BOOL_t vos_attach_mmie(v_U8_t *igtk, v_U8_t *ipn, u_int16_t key_id, + v_U8_t* frm, v_U8_t* efrm, u_int16_t frmLen); +v_U8_t vos_get_mmie_size(void); +#endif /* WLAN_FEATURE_11W */ +#endif // #if !defined __VOSS_UTILS_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wcnss_api.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wcnss_api.h new file mode 100644 index 0000000000000..71b561489cc7f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wcnss_api.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WCNSS_API_H_ +#define _WCNSS_API_H_ + + +/* + * Do nothing for non ISOC + */ +#define wcnss_wlan_get_drvdata(dev) NULL + +static inline void wcnss_wlan_register_pm_ops(void *dev, void *pm_ops) +{ +} + +static inline void wcnss_wlan_unregister_pm_ops(void *dev, void *pm_ops) +{ +} + +static inline void wcnss_register_thermal_mitigation(void *dev, void *tmnotify) +{ +} + +static inline void wcnss_unregister_thermal_mitigation(void *tm_notify) +{ +} + +static inline void wcnss_prevent_suspend(void) +{ +} + +static inline void wcnss_allow_suspend(void) +{ +} + +static inline unsigned int wcnss_get_serial_number(void) +{ + return 0; +} + +#if !defined(CONFIG_CNSS) && !defined(HIF_USB) && !defined(HIF_SDIO) +static inline void *wcnss_wlan_crypto_alloc_ahash(const char *alg_name, + unsigned int type, + unsigned int mask) +{ + return NULL; +} + +static inline int wcnss_wlan_crypto_ahash_digest(void *req) +{ + return 0; +} + +static inline void wcnss_wlan_crypto_free_ahash(void *tfm) +{ +} + +static inline int wcnss_wlan_crypto_ahash_setkey(void *tfm, + const u8 *key, + unsigned int keylen) +{ + return 0; +} + +static inline void *wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name, + u32 type, u32 mask) +{ + return NULL; +} + +static inline void wcnss_wlan_ablkcipher_request_free(void *req) +{ +} + +static inline void wcnss_wlan_crypto_free_ablkcipher(void *tfm) +{ +} +#endif /* !CONFIG_CNSS */ + +static inline int req_riva_power_on_lock(char *driver_name) +{ + return 0; +} + +static inline int free_riva_power_on_lock(char *driver_name) +{ + return 0; +} + + +#endif /* #ifndef _WCNSS_API_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wlan_hdd_misc.h b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wlan_hdd_misc.h new file mode 100644 index 0000000000000..8b94ccfadb82e --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/inc/wlan_hdd_misc.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_HDD_MISC_H +#define WLAN_HDD_MISC_H + +#ifdef MSM_PLATFORM +#define WLAN_INI_FILE "wlan/qca_cld/WCNSS_qcom_cfg.ini" +#define WLAN_CFG_FILE "wlan/qca_cld/WCNSS_cfg.dat" +#define WLAN_MAC_FILE "wlan/qca_cld/wlan_mac.bin" +#else +#define WLAN_INI_FILE "wlan/qcom_cfg.ini" +#define WLAN_CFG_FILE "wlan/cfg.dat" +#define WLAN_MAC_FILE "wlan/wlan_mac.bin" +#endif // MSM_PLATFORM + +VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize); + +VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, v_VOID_t *pBuffer, v_SIZE_t *pBufSize); + +tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ); + +#endif /* WLAN_HDD_MISC_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_api.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_api.c new file mode 100644 index 0000000000000..4aec7006d46b3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_api.c @@ -0,0 +1,2518 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_api.c + + \brief Stub file for all virtual Operating System Services (vOSS) APIs + + ========================================================================*/ + /*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/29/09 kanand Created module. +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "vos_sched.h" +#include +#include "sirTypes.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sme_Api.h" +#include "macInitApi.h" +#include "wlan_qct_sys.h" +#include "wlan_qct_tl.h" +#include "wlan_hdd_misc.h" +#include "i_vos_packet.h" +#include "vos_nvitem.h" +#include "wlan_qct_wda.h" +#include "wlan_hdd_main.h" +#include +#include "wlan_hdd_cfg80211.h" +#ifdef CONFIG_CNSS +#include +#endif + +#include "sapApi.h" +#include "vos_trace.h" + + +#ifdef WLAN_BTAMP_FEATURE +#include "bapApi.h" +#include "bapInternal.h" +#include "bap_hdd_main.h" +#endif //WLAN_BTAMP_FEATURE + +#include "bmi.h" +#include "ol_fw.h" +#include "ol_if_athvar.h" +#if defined(HIF_PCI) +#include "if_pci.h" +#elif defined(HIF_USB) +#include "if_usb.h" +#elif defined(HIF_SDIO) +#include "if_ath_sdio.h" +#endif +#include "wma.h" + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ +/* Approximate amount of time to wait for WDA to stop WDI */ +#define VOS_WDA_STOP_TIMEOUT WDA_STOP_TIMEOUT + +/* Approximate amount of time to wait for WDA to issue a DUMP req */ +#define VOS_WDA_RESP_TIMEOUT WDA_STOP_TIMEOUT + +/* Maximum number of vos message queue get wrapper failures to cause panic */ +#define VOS_WRAPPER_MAX_FAIL_COUNT (VOS_CORE_MAX_MESSAGES * 3) + +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ +static VosContextType gVosContext; +static pVosContextType gpVosContext; + +/* Debug variable to detect MC thread stuck */ +static atomic_t vos_wrapper_empty_count; + +/*--------------------------------------------------------------------------- + * Forward declaration + * ------------------------------------------------------------------------*/ +v_VOID_t vos_sys_probe_thread_cback ( v_VOID_t *pUserData ); + +v_VOID_t vos_core_return_msg(v_PVOID_t pVContext, pVosMsgWrapper pMsgWrapper); + +v_VOID_t vos_fetch_tl_cfg_parms ( WLANTL_ConfigInfoType *pTLConfig, + hdd_config_t * pConfig ); + + +/*--------------------------------------------------------------------------- + + \brief vos_preOpen() - PreOpen the vOSS Module + + The \a vos_preOpen() function allocates the Vos Context, but do not + initialize all the members. This overal initialization will happen + at vos_Open(). + The reason why we need vos_preOpen() is to get a minimum context + where to store BAL and SAL relative data, which happens before + vos_Open() is called. + + \param pVosContext: A pointer to where to store the VOS Context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_Open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext ) +{ + if ( pVosContext == NULL) + return VOS_STATUS_E_FAILURE; + + /* Allocate the VOS Context */ + *pVosContext = NULL; + gpVosContext = &gVosContext; + + if (NULL == gpVosContext) + { + /* Critical Error ...Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to allocate VOS Context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_RESOURCES; + } + + vos_mem_zero(gpVosContext, sizeof(VosContextType)); + + *pVosContext = gpVosContext; + + /* Initialize the spinlock */ + vos_trace_spin_lock_init(); + /* it is the right time to initialize MTRACE structures */ + #if defined(TRACE_RECORD) + vosTraceInit(); + #endif + + return VOS_STATUS_SUCCESS; + +} /* vos_preOpen()*/ + + +/*--------------------------------------------------------------------------- + + \brief vos_preClose() - PreClose the vOSS Module + + The \a vos_preClose() function frees the Vos Context. + + \param pVosContext: A pointer to where the VOS Context was stored + + + \return VOS_STATUS_SUCCESS - Always successful + + + \sa vos_preClose() + \sa vos_close() +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preClose( v_CONTEXT_t *pVosContext ) +{ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: De-allocating the VOS Context", __func__); + + if (( pVosContext == NULL) || (*pVosContext == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vOS Context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (gpVosContext != *pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Context mismatch", __func__); + return VOS_STATUS_E_FAILURE; + } + + *pVosContext = gpVosContext = NULL; + + return VOS_STATUS_SUCCESS; + +} /* vos_preClose()*/ + +#if defined (FEATURE_SECURE_FIRMWARE) && defined (FEATURE_FW_HASH_CHECK) +static inline void vos_fw_hash_check_config(struct ol_softc *scn, + hdd_context_t *pHddCtx) +{ + scn->enable_fw_hash_check = pHddCtx->cfg_ini->enable_fw_hash_check; +} +#elif defined (FEATURE_SECURE_FIRMWARE) +static inline void vos_fw_hash_check_config(struct ol_softc *scn, + hdd_context_t *pHddCtx) +{ + scn->enable_fw_hash_check = true; +} +#else +static inline void vos_fw_hash_check_config(struct ol_softc *scn, + hdd_context_t *pHddCtx) { } +#endif + +/*--------------------------------------------------------------------------- + + \brief vos_open() - Open the vOSS Module + + The \a vos_open() function opens the vOSS Scheduler + Upon successful initialization: + + - All VOS submodules should have been initialized + + - The VOS scheduler should have opened + + - All the WLAN SW components should have been opened. This includes + SYS, MAC, SME, WDA and TL. + + + \param hddContextSize: Size of the HDD context to allocate. + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_preOpen() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ) + +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int iter = 0; + tSirRetStatus sirStatus = eSIR_SUCCESS; + tMacOpenParameters macOpenParms; + WLANTL_ConfigInfoType TLConfig; + adf_os_device_t adf_ctx; + HTC_INIT_INFO htcInfo; + struct ol_softc *scn; + v_VOID_t *HTCHandle; + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + if (NULL == gpVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Trying to open VOSS without a PreOpen", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Initialize the timer module */ + vos_timer_module_init(); + + + /* Initialize the probe event */ + if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to init probeEvent", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if (vos_event_init( &(gpVosContext->wdaCompleteEvent) ) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to init wdaCompleteEvent", __func__); + VOS_ASSERT(0); + + goto err_probe_event; + } + + /* Initialize the free message queue */ + vStatus = vos_mq_init(&gpVosContext->freeVosMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to initialize VOS free message queue", __func__); + VOS_ASSERT(0); + goto err_wda_complete_event; + } + + for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++) + { + (gpVosContext->aMsgWrappers[iter]).pVosMsg = + &(gpVosContext->aMsgBuffers[iter]); + INIT_LIST_HEAD(&gpVosContext->aMsgWrappers[iter].msgNode); + vos_mq_put(&gpVosContext->freeVosMq, &(gpVosContext->aMsgWrappers[iter])); + } + + /* Now Open the VOS Scheduler */ + vStatus= vos_sched_open(gpVosContext, &gpVosContext->vosSched, + sizeof(VosSchedContext)); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open VOS Scheduler", __func__); + VOS_ASSERT(0); + goto err_msg_queue; + } + + pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext); + if((NULL == pHddCtx) || + (NULL == pHddCtx->cfg_ini)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Hdd Context is Null", __func__); + VOS_ASSERT(0); + goto err_sched_close; + } + + scn = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext); + if (!scn) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: scn is null!", __func__); + goto err_sched_close; + } + scn->enableuartprint = pHddCtx->cfg_ini->enablefwprint; + scn->enablefwlog = pHddCtx->cfg_ini->enablefwlog; + scn->enableFwSelfRecovery = pHddCtx->cfg_ini->enableFwSelfRecovery; + scn->max_no_of_peers = pHddCtx->cfg_ini->maxNumberOfPeers; +#ifdef WLAN_FEATURE_LPSS + scn->enablelpasssupport = pHddCtx->cfg_ini->enablelpasssupport; +#endif + + vos_fw_hash_check_config(scn, pHddCtx); + + /* Initialize BMI and Download firmware */ + if (bmi_download_firmware(scn)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: BMI failed to download target", __func__); + goto err_bmi_close; + } + htcInfo.pContext = gpVosContext->pHIFContext; + htcInfo.TargetFailure = ol_target_failure; + htcInfo.TargetSendSuspendComplete = wma_target_suspend_acknowledge; + adf_ctx = vos_get_context(VOS_MODULE_ID_ADF, gpVosContext); + + /* Create HTC */ + gpVosContext->htc_ctx = HTCCreate(htcInfo.pContext, &htcInfo, adf_ctx); + if (!gpVosContext->htc_ctx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to Create HTC", __func__); + goto err_bmi_close; + goto err_sched_close; + } + + if (bmi_done(scn)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto err_htc_close; + } + + /* + ** Need to open WDA first because it calls WDI_Init, which calls wpalOpen + ** The reason that is needed becasue vos_packet_open need to use PAL APIs + */ + + /*Open the WDA module */ + vos_mem_set(&macOpenParms, sizeof(macOpenParms), 0); + /* UMA is supported in hardware for performing the + ** frame translation 802.11 <-> 802.3 + */ + macOpenParms.frameTransRequired = 1; + macOpenParms.driverType = eDRIVER_TYPE_PRODUCTION; + macOpenParms.powersaveOffloadEnabled = + pHddCtx->cfg_ini->enablePowersaveOffload; + macOpenParms.staDynamicDtim = pHddCtx->cfg_ini->enableDynamicDTIM; + macOpenParms.staModDtim = pHddCtx->cfg_ini->enableModulatedDTIM; + macOpenParms.staMaxLIModDtim = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + macOpenParms.wowEnable = pHddCtx->cfg_ini->wowEnable; + macOpenParms.maxWoWFilters = pHddCtx->cfg_ini->maxWoWFilters; + /* Here olIniInfo is used to store ini status of arp offload + * ns offload and others. Currently 1st bit is used for arp + * off load and 2nd bit for ns offload currently, rest bits are unused + */ + if ( pHddCtx->cfg_ini->fhostArpOffload) + macOpenParms.olIniInfo = macOpenParms.olIniInfo | 0x1; + if ( pHddCtx->cfg_ini->fhostNSOffload) + macOpenParms.olIniInfo = macOpenParms.olIniInfo | 0x2; + /* + * Copy the DFS Phyerr Filtering Offload status. + * This parameter reflects the value of the + * dfsPhyerrFilterOffload flag as set in the ini. + */ + macOpenParms.dfsPhyerrFilterOffload = + pHddCtx->cfg_ini->fDfsPhyerrFilterOffload; + if (pHddCtx->cfg_ini->ssdp) + macOpenParms.ssdp = pHddCtx->cfg_ini->ssdp; +#ifdef FEATURE_WLAN_RA_FILTERING + macOpenParms.RArateLimitInterval = pHddCtx->cfg_ini->RArateLimitInterval; + macOpenParms.IsRArateLimitEnabled = pHddCtx->cfg_ini->IsRArateLimitEnabled; +#endif + + macOpenParms.apMaxOffloadPeers = pHddCtx->cfg_ini->apMaxOffloadPeers; + + macOpenParms.apMaxOffloadReorderBuffs = + pHddCtx->cfg_ini->apMaxOffloadReorderBuffs; + + macOpenParms.apDisableIntraBssFwd = pHddCtx->cfg_ini->apDisableIntraBssFwd; + + macOpenParms.dfsRadarPriMultiplier = pHddCtx->cfg_ini->dfsRadarPriMultiplier; + macOpenParms.reorderOffload = pHddCtx->cfg_ini->reorderOffloadSupport; + +#ifdef IPA_UC_OFFLOAD + /* IPA micro controller data path offload resource config item */ + macOpenParms.ucOffloadEnabled = pHddCtx->cfg_ini->IpaUcOffloadEnabled; + macOpenParms.ucTxBufCount = pHddCtx->cfg_ini->IpaUcTxBufCount; + macOpenParms.ucTxBufSize = pHddCtx->cfg_ini->IpaUcTxBufSize; + macOpenParms.ucRxIndRingCount = pHddCtx->cfg_ini->IpaUcRxIndRingCount; + macOpenParms.ucTxPartitionBase = pHddCtx->cfg_ini->IpaUcTxPartitionBase; +#endif /* IPA_UC_OFFLOAD */ + + vStatus = WDA_open( gpVosContext, gpVosContext->pHDDContext, + hdd_update_tgt_cfg, + hdd_dfs_indicate_radar, + &macOpenParms ); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open WDA module", __func__); + VOS_ASSERT(0); + goto err_htc_close; + } + + /* Number of peers limit differs in each chip version. If peer max + * limit configured in ini exceeds more than supported, WMA adjusts + * and keeps correct limit in macOpenParms.maxStation. So, make sure + * ini entry pHddCtx->cfg_ini->maxNumberOfPeers has adjusted value + */ + pHddCtx->cfg_ini->maxNumberOfPeers = macOpenParms.maxStation; + HTCHandle = vos_get_context(VOS_MODULE_ID_HTC, gpVosContext); + if (!HTCHandle) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HTCHandle is null!", __func__); + goto err_wda_close; + } + if (HTCWaitTarget(HTCHandle)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto err_wda_close; + } + + + /* Open the SYS module */ + vStatus = sysOpen(gpVosContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open SYS module", __func__); + VOS_ASSERT(0); + goto err_packet_close; + } + + + /* If we arrive here, both threads dispacthing messages correctly */ + + /* Now proceed to open the MAC */ + + /* UMA is supported in hardware for performing the + frame translation 802.11 <-> 802.3 */ + macOpenParms.frameTransRequired = 1; + + sirStatus = macOpen(&(gpVosContext->pMACContext), gpVosContext->pHDDContext, + &macOpenParms); + + if (eSIR_SUCCESS != sirStatus) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open MAC", __func__); + VOS_ASSERT(0); + goto err_nv_close; + } + + /* Now proceed to open the SME */ + vStatus = sme_Open(gpVosContext->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open SME", __func__); + VOS_ASSERT(0); + goto err_mac_close; + } + + /* Now proceed to open TL. Read TL config first */ + vos_fetch_tl_cfg_parms ( &TLConfig, + ((hdd_context_t*)(gpVosContext->pHDDContext))->cfg_ini); + + vStatus = WLANTL_Open(gpVosContext, &TLConfig); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open TL", __func__); + VOS_ASSERT(0); + goto err_sme_close; + } + +#ifdef IPA_UC_OFFLOAD + WLANTL_GetIpaUcResource(gpVosContext, + &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_base_paddr, + &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_ring_size, + &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_reg_paddr, + &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_base_paddr, + &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_size, + &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_num_alloc_buffer, + &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_base_paddr, + &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_size, + &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_proc_done_idx_paddr); +#endif /* IPA_UC_OFFLOAD */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS successfully Opened", __func__); + + *pVosContext = gpVosContext; + + return VOS_STATUS_SUCCESS; + + +err_sme_close: + sme_Close(gpVosContext->pMACContext); + +err_mac_close: + macClose(gpVosContext->pMACContext); + +err_nv_close: + + sysClose(gpVosContext); + +err_packet_close: +err_wda_close: + WDA_close(gpVosContext); + + wma_wmi_service_close(gpVosContext); + +err_htc_close: + if (gpVosContext->htc_ctx) { + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; + } + +err_bmi_close: + BMICleanup(scn); + +err_sched_close: + vos_sched_close(gpVosContext); + + +err_msg_queue: + vos_mq_deinit(&gpVosContext->freeVosMq); + +err_wda_complete_event: + vos_event_destroy( &gpVosContext->wdaCompleteEvent ); + +err_probe_event: + vos_event_destroy(&gpVosContext->ProbeEvent); + + return VOS_STATUS_E_FAILURE; + +} /* vos_open() */ + +/*--------------------------------------------------------------------------- + + \brief vos_preStart() - + + The \a vos_preStart() function to download CFG. + including: + - ccmStart + + - WDA: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_start + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preStart( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + v_VOID_t *scn; + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "vos prestart"); + + if (gpVosContext != pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Context mismatch", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (pVosContext->pMACContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (pVosContext->pWDAContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + scn = vos_get_context(VOS_MODULE_ID_HIF, gpVosContext); + if (!scn) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: scn is null!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* call macPreStart */ + vStatus = macPreStart(gpVosContext->pMACContext); + if ( !VOS_IS_STATUS_SUCCESS(vStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed at macPreStart "); + return VOS_STATUS_E_FAILURE; + } + + /* call ccmStart */ + ccmStart(gpVosContext->pMACContext); + + /* Reset wda wait event */ + vos_event_reset(&gpVosContext->wdaCompleteEvent); + + + /*call WDA pre start*/ + vStatus = WDA_preStart(gpVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed to WDA prestart"); + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Need to update time out of complete */ + vStatus = vos_wait_single_event( &gpVosContext->wdaCompleteEvent, + VOS_WDA_TIMEOUT ); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_preStart reporting other error", __func__); + } + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Test MC thread by posting a probe message to SYS", __func__); + wlan_sys_probe(); + + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + + vStatus = HTCStart(gpVosContext->htc_ctx); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed to Start HTC"); + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + vStatus = wma_wait_for_ready_event(gpVosContext->pWDAContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed to get ready event from target firmware"); + HTCSetTargetToSleep(scn); + ccmStop(gpVosContext->pMACContext); + HTCStop(gpVosContext->htc_ctx); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + + HTCSetTargetToSleep(scn); + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief vos_start() - Start the Libra SW Modules + + The \a vos_start() function starts all the components of the Libra SW + including: + - SAL/BAL, which in turn starts SSC + + - the MAC (HAL and PE) + + - SME + + - TL + + - SYS: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_preStart() + \sa vos_open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_start( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + tSirRetStatus sirStatus = eSIR_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + tHalMacStartParameters halStartParams; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Starting Libra SW", __func__); + + /* We support only one instance for now ...*/ + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: mismatch in context", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pMACContext == NULL) + || ( pVosContext->pTLContext == NULL)) + { + if (pVosContext->pWDAContext == NULL) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + else if (pVosContext->pMACContext == NULL) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context", __func__); + else + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: TL NULL context", __func__); + + return VOS_STATUS_E_FAILURE; + } + + + /* Start the WDA */ + vStatus = WDA_start(pVosContext); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start WDA", __func__); + return VOS_STATUS_E_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: WDA correctly started", __func__); + + /* Start the MAC */ + vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters)); + + /* Start the MAC */ + sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams); + + if (eSIR_SUCCESS != sirStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start MAC", __func__); + goto err_wda_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MAC correctly started", __func__); + + /* START SME */ + vStatus = sme_Start(pVosContext->pMACContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start SME", __func__); + goto err_mac_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: SME correctly started", __func__); + + /** START TL */ + vStatus = WLANTL_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start TL", __func__); + goto err_sme_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TL correctly started"); + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: VOSS Start is successful!!", __func__); + + return VOS_STATUS_SUCCESS; + + +err_sme_stop: + sme_Stop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET); + +err_mac_stop: + macStop( pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET ); + +err_wda_stop: + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + vStatus = WDA_stop( pVosContext, HAL_STOP_TYPE_RF_KILL); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vStatus ) ); + WDA_setNeedShutdown(vosContext); + } + else + { + vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), + VOS_WDA_TIMEOUT ); + if( vStatus != VOS_STATUS_SUCCESS ) + { + if( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Timeout occurred before WDA_stop complete", __func__); + + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: WDA_stop reporting other error", __func__); + } + VOS_ASSERT( 0 ); + WDA_setNeedShutdown(vosContext); + } + } + + return VOS_STATUS_E_FAILURE; + +} /* vos_start() */ + + +/* vos_stop function */ +VOS_STATUS vos_stop( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + + /* WDA_Stop is called before the SYS so that the processing of Riva + pending responces will not be handled during uninitialization of WLAN driver */ + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + + vosStatus = WDA_stop( vosContext, HAL_STOP_TYPE_RF_KILL ); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + WDA_setNeedShutdown(vosContext); + } + + hif_disable_isr(((VosContextType*)vosContext)->pHIFContext); + hif_reset_soc(((VosContextType*)vosContext)->pHIFContext); + + /* SYS STOP will stop SME and MAC */ + vosStatus = sysStop( vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = WLANTL_Stop( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + + +/* vos_close function */ +VOS_STATUS vos_close( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close BAP", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif // WLAN_BTAMP_FEATURE + + if (gpVosContext->htc_ctx) + { + HTCStop(gpVosContext->htc_ctx); + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; + } + + vosStatus = WLANTL_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + if ( TRUE == WDA_needShutdown(vosContext )) + { + /* if WDA stop failed, call WDA shutdown to cleanup WDA/WDI */ + vosStatus = WDA_shutdown( vosContext, VOS_TRUE ); + if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hdd_set_ssr_required( HDD_SSR_REQUIRED ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to shutdown WDA", __func__ ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + else + { + vosStatus = WDA_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + + vosStatus = wma_wmi_service_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close wma_wmi_service", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy wdaCompleteEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy ProbeEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_get_context() - get context data area + + Each module in the system has a context / data area that is allocated + and maanged by voss. This API allows any user to get a pointer to its + allocated context data area from the VOSS global context. + + \param vosContext - the VOSS Global Context. + + \param moduleId - the module ID, who's context data are is being retrived. + + \return - pointer to the context data area. + + - NULL if the context data is not allocated for the module ID + specified + + --------------------------------------------------------------------------*/ +v_VOID_t* vos_get_context( VOS_MODULE_ID moduleId, + v_CONTEXT_t pVosContext ) +{ + v_PVOID_t pModContext = NULL; + + if (pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context pointer is null", __func__); + return NULL; + } + + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pVosContext != gpVosContext", __func__); + return NULL; + } + + switch(moduleId) + { + case VOS_MODULE_ID_TL: + { + pModContext = gpVosContext->pTLContext; + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pModContext = gpVosContext->pBAPContext; + break; + } +#endif //WLAN_BTAMP_FEATURE + +#ifndef WLAN_FEATURE_MBSSID + case VOS_MODULE_ID_SAP: + { + pModContext = gpVosContext->pSAPContext; + break; + } +#endif + + case VOS_MODULE_ID_HDD_SOFTAP: + { + pModContext = gpVosContext->pHDDSoftAPContext; + break; + } + + case VOS_MODULE_ID_HDD: + { + pModContext = gpVosContext->pHDDContext; + break; + } + + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + { + /* + ** In all these cases, we just return the MAC Context + */ + pModContext = gpVosContext->pMACContext; + break; + } + + case VOS_MODULE_ID_WDA: + { + /* For WDA module */ + pModContext = gpVosContext->pWDAContext; + break; + } + + case VOS_MODULE_ID_VOSS: + { + /* For SYS this is VOS itself*/ + pModContext = gpVosContext; + break; + } + + + case VOS_MODULE_ID_HIF: + { + pModContext = gpVosContext->pHIFContext; + break; + } + + case VOS_MODULE_ID_HTC: + { + pModContext = gpVosContext->htc_ctx; + break; + } + + case VOS_MODULE_ID_ADF: + { + pModContext = gpVosContext->adf_ctx; + break; + } + + case VOS_MODULE_ID_TXRX: + { + pModContext = gpVosContext->pdev_txrx_ctx; + break; + } + + case VOS_MODULE_ID_CFG: + { + pModContext = gpVosContext->cfg_ctx; + break; + } + + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "does not have its context maintained by VOSS", __func__, moduleId); + VOS_ASSERT(0); + return NULL; + } + } + + if (pModContext == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "context is Null", __func__, moduleId); + } + + return pModContext; + +} /* vos_get_context()*/ + + +/**--------------------------------------------------------------------------- + + \brief vos_get_global_context() - get VOSS global Context + + This API allows any user to get the VOS Global Context pointer from a + module context data area. + + \param moduleContext - the input module context pointer + + \param moduleId - the module ID who's context pointer is input in + moduleContext. + + \return - pointer to the VOSS global context + + - NULL if the function is unable to retreive the VOSS context. + + --------------------------------------------------------------------------*/ +v_CONTEXT_t vos_get_global_context( VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext ) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + } + + return gpVosContext; + +} /* vos_get_global_context() */ + + +v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 1; + } + + return gpVosContext->isLogpInProgress; +} + +void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + hdd_context_t *pHddCtx = NULL; + + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + gpVosContext->isLogpInProgress = value; + + /* HDD uses it's own context variable to check if SSR in progress, + * instead of modifying all HDD APIs set the HDD context variable + * here */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, gpVosContext); + if (!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + pHddCtx->isLogpInProgress = value; +} + +v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 0; + } + + return gpVosContext->isLoadUnloadInProgress; +} + +void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + gpVosContext->isLoadUnloadInProgress = value; + +#ifdef CONFIG_CNSS + if (value) + cnss_set_driver_status(CNSS_LOAD_UNLOAD); + else + cnss_set_driver_status(CNSS_INITIALIZED); +#endif +} + +v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 1; + } + + return gpVosContext->isReInitInProgress; +} + +void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + + gpVosContext->isReInitInProgress = value; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_alloc_context() - allocate a context within the VOSS global Context + + This API allows any user to allocate a user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being allocated. + + \param ppModuleContext - pointer to location where the pointer to the + allocated context is returned. Note this + output pointer is valid only if the API + returns VOS_STATUS_SUCCESS + + \param size - the size of the context area to be allocated. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + allocated successfully. The pointer to the context area + can be found in *ppModuleContext. + \note This function returns VOS_STATUS_SUCCESS if the + module context was already allocated and the size + allocated matches the size on this call. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context allocated. + + VOS_STATUS_E_EXISTS - vos could allocate the requested context + because a context for this module ID already exists and it is + a *different* size that specified on this call. + + VOS_STATUS_E_NOMEM - vos could not allocate memory for the + requested context area. + + \sa vos_get_context(), vos_free_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_alloc_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t **ppModuleContext, v_SIZE_t size ) +{ + v_VOID_t ** pGpModContext = NULL; + + if ( pVosContext == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is null", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (( gpVosContext != pVosContext) || ( ppModuleContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: context mismatch or null param passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + switch(moduleID) + { + case VOS_MODULE_ID_TL: + { + pGpModContext = &(gpVosContext->pTLContext); + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pGpModContext = &(gpVosContext->pBAPContext); + break; + } +#endif //WLAN_BTAMP_FEATURE + +#ifndef WLAN_FEATURE_MBSSID + case VOS_MODULE_ID_SAP: + { + pGpModContext = &(gpVosContext->pSAPContext); + break; + } +#endif + + case VOS_MODULE_ID_WDA: + { + pGpModContext = &(gpVosContext->pWDAContext); + break; + } + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + case VOS_MODULE_ID_HDD: + case VOS_MODULE_ID_HDD_SOFTAP: + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i " + "does not have its context allocated by VOSS", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + } + + if ( NULL != *pGpModContext) + { + /* + ** Context has already been allocated! + ** Prevent double allocation + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Module ID %i context has already been allocated", + __func__, moduleID); + return VOS_STATUS_E_EXISTS; + } + + /* + ** Dynamically allocate the context for module + */ + + *ppModuleContext = kmalloc(size, GFP_KERNEL); + + + if ( *ppModuleContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Failed to " + "allocate Context for module ID %i", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + if (moduleID==VOS_MODULE_ID_TL) + { + vos_mem_zero(*ppModuleContext, size); + } + + *pGpModContext = *ppModuleContext; + + return VOS_STATUS_SUCCESS; + +} /* vos_alloc_context() */ + + +/**--------------------------------------------------------------------------- + + \brief vos_free_context() - free an allocated a context within the + VOSS global Context + + This API allows a user to free the user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being free + + \param pModuleContext - pointer to module context area to be free'd. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + free'd. The pointer to the context area is not longer + available. + + VOS_STATUS_E_FAULT - pVosContext or pModuleContext are not + valid pointers. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context free'd. + + VOS_STATUS_E_EXISTS - vos could not free the requested + context area because a context for this module ID does not + exist in the global vos context. + + \sa vos_get_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_free_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t *pModuleContext ) +{ + v_VOID_t ** pGpModContext = NULL; + + if (( pVosContext == NULL) || ( gpVosContext != pVosContext) || + ( pModuleContext == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or context mismatch", __func__); + return VOS_STATUS_E_FAILURE; + } + + + switch(moduleID) + { + case VOS_MODULE_ID_TL: + { + pGpModContext = &(gpVosContext->pTLContext); + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pGpModContext = &(gpVosContext->pBAPContext); + break; + } +#endif //WLAN_BTAMP_FEATURE + +#ifndef WLAN_FEATURE_MBSSID + case VOS_MODULE_ID_SAP: + { + pGpModContext = &(gpVosContext->pSAPContext); + break; + } +#endif + + case VOS_MODULE_ID_WDA: + { + pGpModContext = &(gpVosContext->pWDAContext); + break; + } + case VOS_MODULE_ID_HDD: + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + case VOS_MODULE_ID_HDD_SOFTAP: + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i " + "does not have its context allocated by VOSS", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + } + + if ( NULL == *pGpModContext) + { + /* + ** Context has not been allocated or freed already! + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "context has not been allocated or freed already", __func__,moduleID); + return VOS_STATUS_E_FAILURE; + } + + if (*pGpModContext != pModuleContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pGpModContext != pModuleContext", __func__); + return VOS_STATUS_E_FAILURE; + } + + if(pModuleContext != NULL) + kfree(pModuleContext); + + *pGpModContext = NULL; + + return VOS_STATUS_SUCCESS; + +} /* vos_free_context() */ + + +/**--------------------------------------------------------------------------- + + \brief vos_mq_post_message() - post a message to a message queue + + This API allows messages to be posted to a specific message queue. Messages + can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_mq_post_message( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + uint32_t debug_count; + + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + /// Message Queue ID for messages bound for SME + case VOS_MQ_ID_SME: + { + pTargetMq = &(gpVosContext->vosSched.smeMcMq); + break; + } + + /// Message Queue ID for messages bound for PE + case VOS_MQ_ID_PE: + { + pTargetMq = &(gpVosContext->vosSched.peMcMq); + break; + } + + /// Message Queue ID for messages bound for WDA + case VOS_MQ_ID_WDA: + { + pTargetMq = &(gpVosContext->vosSched.wdaMcMq); + break; + } + + /// Message Queue ID for messages bound for TL + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlMcMq); + break; + } + + /// Message Queue ID for messages bound for the SYS module + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysMcMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: Trying to queue msg into unknown MC Msg queue ID %d"), + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + VOS_ASSERT(NULL !=pTargetMq); + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) { + debug_count = atomic_inc_return(&vos_wrapper_empty_count); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Core run out of message wrapper %d", + __func__, debug_count); + + if (VOS_WRAPPER_MAX_FAIL_COUNT == debug_count) { + VOS_BUG(0); + } + + return VOS_STATUS_E_RESOURCES; + } + + atomic_set(&vos_wrapper_empty_count, 0); + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(MC_POST_EVENT_MASK, &gpVosContext->vosSched.mcEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.mcWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_mq_post_message()*/ + + +/**--------------------------------------------------------------------------- + + \brief vos_tx_mq_serialize() - serialize a message to the Tx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Tx execution flow can be posted only + to the following queue. + +
    +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_tx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + /// Message Queue ID for messages bound for SME + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlTxMq); + break; + } + + /// Message Queue ID for messages bound for the SYS module + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysTxMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to queue msg into unknown Tx Msg queue ID %d", + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: VOS Core run out of message wrapper", __func__); + + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(TX_POST_EVENT_MASK, &gpVosContext->vosSched.txEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.txWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_tx_mq_serialize()*/ + +/**--------------------------------------------------------------------------- + + \brief vos_rx_mq_serialize() - serialize a message to the Rx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Rx execution flow can be posted only + to the following queue. + +
    +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_rx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysRxMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to queue msg into unknown Rx Msg queue ID %d", + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Core run out of message wrapper", __func__); + + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(RX_POST_EVENT_MASK, &gpVosContext->vosSched.rxEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.rxWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_rx_mq_serialize()*/ + +v_VOID_t +vos_sys_probe_thread_cback +( + v_VOID_t *pUserData +) +{ + if (gpVosContext != pUserData) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pUserData", __func__); + return; + } + + if (vos_event_set(&gpVosContext->ProbeEvent)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + return; + } + +} /* vos_sys_probe_thread_cback() */ + +v_VOID_t vos_WDAComplete_cback +( + v_VOID_t *pUserData +) +{ + + if (gpVosContext != pUserData) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pUserData", __func__); + return; + } + + if (vos_event_set(&gpVosContext->wdaCompleteEvent)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + return; + } + +} /* vos_WDAComplete_cback() */ + +v_VOID_t vos_core_return_msg +( + v_PVOID_t pVContext, + pVosMsgWrapper pMsgWrapper +) +{ + pVosContextType pVosContext = (pVosContextType) pVContext; + + VOS_ASSERT( gpVosContext == pVosContext); + + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pVosContext", __func__); + return; + } + + VOS_ASSERT( NULL !=pMsgWrapper ); + + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper == NULL in function", __func__); + return; + } + + /* + ** Return the message on the free message queue + */ + INIT_LIST_HEAD(&pMsgWrapper->msgNode); + vos_mq_put(&pVosContext->freeVosMq, pMsgWrapper); + +} /* vos_core_return_msg() */ + + +/** + @brief vos_fetch_tl_cfg_parms() - this function will attempt to read the + TL config params from the registry + + @param pAdapter : [inout] pointer to TL config block + + @return + None + +*/ +v_VOID_t +vos_fetch_tl_cfg_parms +( + WLANTL_ConfigInfoType *pTLConfig, + hdd_config_t * pConfig +) +{ + if (pTLConfig == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s NULL ptr passed in!", __func__); + return; + } + + pTLConfig->ucAcWeights[0] = pConfig->WfqBkWeight; + pTLConfig->ucAcWeights[1] = pConfig->WfqBeWeight; + pTLConfig->ucAcWeights[2] = pConfig->WfqViWeight; + pTLConfig->ucAcWeights[3] = pConfig->WfqVoWeight; + pTLConfig->ucReorderAgingTime[0] = pConfig->BkReorderAgingTime;/*WLANTL_AC_BK*/ + pTLConfig->ucReorderAgingTime[1] = pConfig->BeReorderAgingTime;/*WLANTL_AC_BE*/ + pTLConfig->ucReorderAgingTime[2] = pConfig->ViReorderAgingTime;/*WLANTL_AC_VI*/ + pTLConfig->ucReorderAgingTime[3] = pConfig->VoReorderAgingTime;/*WLANTL_AC_VO*/ + pTLConfig->uDelayedTriggerFrmInt = pConfig->DelayedTriggerFrmInt; + pTLConfig->uMinFramesProcThres = pConfig->MinFramesProcThres; + pTLConfig->ip_checksum_offload = pConfig->enableIPChecksumOffload; + pTLConfig->enable_rxthread = pConfig->enableRxThread; + +} + +v_BOOL_t vos_is_apps_power_collapse_allowed(void* pHddCtx) +{ + return hdd_is_apps_power_collapse_allowed((hdd_context_t*) pHddCtx); +} + +void vos_abort_mac_scan(v_U8_t sessionId) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Global VOS context is Null", __func__); + return; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); + return; + } + + hdd_abort_mac_scan(pHddCtx, sessionId, eCSR_SCAN_ABORT_DEFAULT); + return; +} +/*--------------------------------------------------------------------------- + + \brief vos_shutdown() - shutdown VOS + + - All VOS submodules are closed. + + - All the WLAN SW components should have been opened. This includes + SYS, MAC, SME and TL. + + + \param vosContext: Global vos context + + + \return VOS_STATUS_SUCCESS - Operation successfull & vos is shutdown + + VOS_STATUS_E_FAILURE - Failure to close + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_shutdown(v_CONTEXT_t vosContext) +{ + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = (((pVosContextType)vosContext)->pMACContext); + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close BAP", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif // WLAN_BTAMP_FEATURE + + vosStatus = WLANTL_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + /* + * CAC timer will be initiated and started only when SAP starts on + * DFS channel and it will be stopped and destroyed immediately once the + * radar detected or timedout. So as per design CAC timer should be + * destroyed after stop. + */ + if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) { + vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0; + vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer); + } + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + if (TRUE == WDA_needShutdown(vosContext)) + { + /* If WDA stop failed, call WDA shutdown to cleanup WDA/WDI. */ + vosStatus = WDA_shutdown(vosContext, VOS_TRUE); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to shutdown WDA!", __func__); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + } + else + { + vosStatus = WDA_close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close WDA!", __func__); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + } + + if (gpVosContext->htc_ctx) + { + HTCStop(gpVosContext->htc_ctx); + HTCDestroy(gpVosContext->htc_ctx); + gpVosContext->htc_ctx = NULL; + } + + vosStatus = wma_wmi_service_close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close wma_wmi_service!", __func__); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy wdaCompleteEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy ProbeEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief vos_wda_shutdown() - VOS interface to wda shutdown + + - WDA/WDI shutdown + + \param vosContext: Global vos context + + + \return VOS_STATUS_SUCCESS - Operation successfull + + VOS_STATUS_E_FAILURE - Failure to close + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_wda_shutdown(v_CONTEXT_t vosContext) +{ + VOS_STATUS vosStatus; + vosStatus = WDA_shutdown(vosContext, VOS_FALSE); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to shutdown WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + return vosStatus; +} +/** + @brief vos_wlanShutdown() - This API will shutdown WLAN driver + + This function is called when Riva subsystem crashes. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Called when Riva goes down, this will shutdown WLAN + driver without handshaking with Riva. + 2. re-init: Next API + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanShutdown(void) +{ + VOS_STATUS vstatus; + vstatus = vos_watchdog_wlan_shutdown(); + return vstatus; +} +/** + @brief vos_wlanReInit() - This API will re-init WLAN driver + + This function is called when Riva subsystem reboots. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Previous API + 2. re-init: Called when Riva comes back after the crash. This will + re-initialize WLAN driver. In some cases re-open may be + referred instead of re-init. + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanReInit(void) +{ + VOS_STATUS vstatus; + vstatus = vos_watchdog_wlan_re_init(); + return vstatus; +} +/** + @brief vos_wlanRestart() - This API will reload WLAN driver. + + This function is called if driver detects any fatal state which + can be recovered by a WLAN module reload ( Android framwork initiated ). + Note that this API will not initiate any RIVA subsystem restart. + + The function wlan_hdd_restart_driver protects against re-entrant calls. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + VOS_STATUS_E_EMPTY - No configured interface + VOS_STATUS_E_ALREADY - Request already in progress + + +*/ +VOS_STATUS vos_wlanRestart(void) +{ + VOS_STATUS vstatus; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Check whether driver load unload is in progress */ + if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Driver load/unload is in progress, retry later.", __func__); + return VOS_STATUS_E_AGAIN; + } + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + if(!pVosContext) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Reload the driver */ + vstatus = wlan_hdd_restart_driver(pHddCtx); + return vstatus; +} + + +/** + @brief vos_fwDumpReq() + + This function is called to issue dump commands to Firmware + + @param + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + @return + NONE +*/ +v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4) +{ + WDA_HALDumpCmdReq(NULL, cmd, arg1, arg2, arg3, arg4, NULL); +} + +VOS_STATUS vos_get_vdev_types(tVOS_CON_MODE mode, tANI_U32 *type, + tANI_U32 *sub_type) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + *type = 0; + *sub_type = 0; + switch (mode) + { + case VOS_STA_MODE: + *type = WMI_VDEV_TYPE_STA; + break; + case VOS_STA_SAP_MODE: + *type = WMI_VDEV_TYPE_AP; + break; + case VOS_P2P_DEVICE_MODE: + *type = WMI_VDEV_TYPE_AP; + *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE; + break; + case VOS_P2P_CLIENT_MODE: + *type = WMI_VDEV_TYPE_STA; + *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT; + break; + case VOS_P2P_GO_MODE: + *type = WMI_VDEV_TYPE_AP; + *sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO; + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid device mode %d", mode); + status = VOS_STATUS_E_INVAL; + break; + } + return status; +} + +v_VOID_t vos_flush_work(v_VOID_t *work) +{ +#if defined (CONFIG_CNSS) + cnss_flush_work(work); +#elif defined (WLAN_OPEN_SOURCE) + cancel_work_sync(work); +#endif +} + +v_VOID_t vos_flush_delayed_work(v_VOID_t *dwork) +{ +#if defined (CONFIG_CNSS) + cnss_flush_delayed_work(dwork); +#elif defined (WLAN_OPEN_SOURCE) + cancel_delayed_work_sync(dwork); +#endif +} + +v_BOOL_t vos_is_packet_log_enabled(void) +{ + hdd_context_t *pHddCtx; + + pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext); + if((NULL == pHddCtx) || + (NULL == pHddCtx->cfg_ini)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Hdd Context is Null", __func__); + return FALSE; + } + + return pHddCtx->cfg_ini->enablePacketLog; +} + +void vos_trigger_recovery(void) +{ + pVosContextType vos_context; + tp_wma_handle wma_handle; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + vos_context = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + if (!vos_context) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VOS context is invald!"); + return; + } + + wma_handle = (tp_wma_handle)vos_get_context(VOS_MODULE_ID_WDA, + vos_context); + if (!wma_handle) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "WMA context is invald!"); + return; + } + + wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0); + + status = vos_wait_single_event(&wma_handle->recovery_event, + WMA_CRASH_INJECT_TIMEOUT); + + if (VOS_STATUS_SUCCESS != status) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "CRASH_INJECT command is timed out!"); +#ifdef CONFIG_CNSS + if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "LOGP is in progress, ignore!"); + return; + } + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + cnss_schedule_recovery_work(); +#endif + + return; + } +} + +v_U64_t vos_get_monotonic_boottime(void) +{ +#ifdef CONFIG_CNSS + struct timespec ts; + + cnss_get_monotonic_boottime(&ts); + return (((v_U64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000)); +#else + return adf_os_ticks_to_msecs(adf_os_ticks()); +#endif +} + +#ifdef FEATURE_WLAN_D0WOW +v_VOID_t vos_pm_control(v_BOOL_t vote) +{ +#ifdef CONFIG_CNSS + cnss_wlan_pm_control(vote); +#endif +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_diag.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_diag.c new file mode 100644 index 0000000000000..89de189ecf482 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_diag.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/*============================================================================ + FILE: vos_diag.c + + OVERVIEW: This source file contains definitions for vOS diag APIs + + DEPENDENCIES: +============================================================================*/ + +#include "vos_types.h" +#include "i_vos_diag_core_log.h" +#include "i_vos_diag_core_event.h" +#include "wlan_hdd_main.h" +#include "wlan_nlink_common.h" +#include "vos_sched.h" +#include "wlan_ptt_sock_svc.h" + + +#define PTT_MSG_DIAG_CMDS_TYPE 0x5050 + +#define DIAG_TYPE_LOGS 1 +#define DIAG_TYPE_EVENTS 2 + +#define DIAG_SWAP16(A) ((((tANI_U16)(A) & 0xff00) >> 8) | (((tANI_U16)(A) & 0x00ff) << 8)) + + + +typedef struct event_report_s +{ + v_U32_t diag_type; + v_U16_t event_id; + v_U16_t length; +} event_report_t; + + +/**--------------------------------------------------------------------------- + + \brief vos_log_set_code() - + + This function sets the logging code in the given log record. + + \param - ptr - Pointer to the log header type. + - code - log code. + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_set_code (v_VOID_t *ptr, v_U16_t code) +{ + if (ptr) + { + /* All log packets are required to start with 'log_header_type'. */ + ((log_hdr_type *) ptr)->code = code; + } + +} + +/**--------------------------------------------------------------------------- + + \brief vos_log_set_length() - + + This function sets the length field in the given log record. + + \param - ptr - Pointer to the log header type. + - length - log length. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_set_length (v_VOID_t *ptr, v_U16_t length) +{ + if(ptr) + { + /* All log packets are required to start with 'log_header_type'. */ + ((log_hdr_type *) ptr)->len = (v_U16_t) length; + } +} + +/**--------------------------------------------------------------------------- + + \brief vos_log_submit() - + + This function sends the log data to the ptt socket app only if it is registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_submit(v_VOID_t *plog_hdr_ptr) +{ + + log_hdr_type *pHdr = (log_hdr_type*) plog_hdr_ptr; + + tAniHdr *wmsg = NULL; + v_U8_t *pBuf; + struct hdd_context_s *pHddCtx; + v_CONTEXT_t pVosContext= NULL; + v_U16_t data_len; + v_U16_t total_len; + + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + /*Get the Hdd Context */ + pHddCtx = ((VosContextType*)(pVosContext))->pHDDContext; + + if ((pHddCtx->isLoadInProgress) || + (pHddCtx->isUnloadInProgress)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return; + } + + /* Send the log data to the ptt app only if it is registered with the wlan driver*/ + if(pHddCtx->ptt_pid) + { + data_len = pHdr->len; + + total_len = sizeof(tAniHdr)+sizeof(v_U32_t)+data_len; + + pBuf = (v_U8_t*)vos_mem_malloc(total_len); + + if(!pBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "vos_mem_malloc failed"); + return; + } + + vos_mem_zero((v_VOID_t*)pBuf,total_len); + + wmsg = (tAniHdr*)pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + + /* Diag Type events or log */ + *(v_U32_t*)pBuf = DIAG_TYPE_LOGS; + pBuf += sizeof(v_U32_t); + + + memcpy(pBuf, pHdr,data_len); + + if(pHddCtx->ptt_pid != INVALID_PID) + { + if( ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, pHddCtx->ptt_pid) < 0) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Ptt Socket error sending message to the app!!")); + vos_mem_free((v_VOID_t *)wmsg); + pHddCtx->ptt_pid = INVALID_PID; + return; + } + + } + vos_mem_free((v_VOID_t*)wmsg); + } + return; +} + +/**--------------------------------------------------------------------------- + + \brief vos_event_report_payload() - + + This function sends the event data to the ptt socket app only if it is registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_event_report_payload(v_U16_t event_Id, v_U16_t length, v_VOID_t *pPayload) +{ + + + tAniHdr *wmsg = NULL; + v_U8_t *pBuf; + struct hdd_context_s *pHddCtx; + v_CONTEXT_t pVosContext= NULL; + event_report_t *pEvent_report; + v_U16_t total_len; + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + /*Get the Hdd Context */ + pHddCtx = ((VosContextType*)(pVosContext))->pHDDContext; + + /* Send the log data to the ptt app only if it is registered with the wlan driver*/ + if(pHddCtx->ptt_pid != INVALID_PID) + { + total_len = sizeof(tAniHdr)+sizeof(event_report_t)+length; + + pBuf = (v_U8_t*)vos_mem_malloc(total_len); + + if(!pBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "vos_mem_malloc failed"); + return; + } + wmsg = (tAniHdr*)pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + pEvent_report = (event_report_t*)pBuf; + pEvent_report->diag_type = DIAG_TYPE_EVENTS; + pEvent_report->event_id = event_Id; + pEvent_report->length = length; + + pBuf += sizeof(event_report_t); + + memcpy(pBuf, pPayload,length); + + if( ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, pHddCtx->ptt_pid) < 0) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Ptt Socket error sending message to the app!!")); + vos_mem_free((v_VOID_t*)wmsg); + pHddCtx->ptt_pid = INVALID_PID; + return; + } + + vos_mem_free((v_VOID_t*)wmsg); + } + + return; + +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_event.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_event.c new file mode 100644 index 0000000000000..9c4481ad9733a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_event.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/*============================================================================ + FILE: vos_event.c + + OVERVIEW: This source file contains definitions for vOS event APIs + The five APIs mentioned in this file are used for + initializing, setting, resetting, destroying an event and + waiting on an occurance of an event among multiple events. + + DEPENDENCIES: +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_event.h" +#include "vos_trace.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + + \brief vos_event_init() - initializes a vOSS event + + The vos_event_init() function initializes the specified event. Upon + successful initialization, the state of the event becomes initialized + and not signaled. + + An event must be initialized before it may be used in any other event + functions. + + Attempting to initialize an already initialized event results in + a failure. + + \param lock - pointer to the opaque event object to initialize + + \return VOS_STATUS_SUCCESS - event was successfully initialized and + is ready to be used. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by event, a previously + initialized, but not yet destroyed, event. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be created due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the event + + ***VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the event + + \sa + + ( *** indicates return values do NOT exist yet ) + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_init ( vos_event_t* event ) +{ + + // Check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check for 'already initialized' event + if ( LINUX_EVENT_COOKIE == event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Initialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_BUSY; + } + + // initialize new event + init_completion(&event->complete); + event->cookie = LINUX_EVENT_COOKIE; + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_event_set() - sets a vOSS event + + The state of the specified event is set to 'signalled by calling + \a vos_event_set(). + + Any threads waiting on the event as a result of a vos_event_wait() will + be unblocked and available to be scheduled for execution when the event + is signaled by a call to \a vos_event_set(). + + \param event - the event to set to the signalled state + + \return VOS_STATUS_SUCCESS - the event was successfully signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + \sa + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_event_set ( vos_event_t* event ) +{ + + // Check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check if event refers to an initialized object + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + complete(&event->complete); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_event_reset() - resets a vOSS event - This function isn't required + for Linux. Therefore, it doesn't do much. + + The state of the specified event is set to 'NOT signalled' by calling + \a vos_event_reset(). The state of the event remains NOT signalled until an + explicit call to vos_event_set(). + + This function sets the event to a NOT signalled state even if the event was + signalled multiple times before being signaled. + + \param event - the event to set to the NOT signalled state + + \return VOS_STATUS_SUCCESS - the event state was successfully change to + NOT signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_reset ( vos_event_t* event ) +{ + + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check to make sure it is an 'already initialized' event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // (re)initialize event + INIT_COMPLETION(event->complete); + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_event_destroy() - Destroys a vOSS event - This function doesn't do + much in Linux. There is no need for the caller to explicitly destroy an event + after use. + + The os_event_destroy() function shall destroy the event object + referenced by event. After a successful return from \a vos_event_destroy() + the event object becomes, in effect, uninitialized. + + A destroyed event object can be reinitialized using vos_event_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS event functions to manipulate the lock such + as vos_event_set() will fail if the event is destroyed. Therefore, + don't use the event after it has been destroyed until it has + been re-initialized. + + \param event - the event object to be destroyed. + + \return VOS_STATUS_SUCCESS - event was successfully destroyed. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + ***VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by event while it is still being + referenced (there are threads waiting on this event) + \sa + + ( *** indicates return values do NOT exist yet ) + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_event_destroy ( vos_event_t* event ) +{ + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check to make sure it is an 'already initialized' event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // make sure nobody is waiting on the event + complete_all(&event->complete); + + // destroy the event + memset(event, 0, sizeof(vos_event_t)); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_wait_single_event() - Waits for a single event to be set. + + This API waits for the event to be set. + + \param pEvent - pointer to an event to wait on. + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by the event being + set. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before the + event was set. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - pEvent is an invalid pointer. + + \sa vos_wait_multiple_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_single_event ( vos_event_t* event, v_U32_t timeout) +{ + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s cannot be called from interrupt context!!!", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check if cookie is same as that of initialized event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (timeout) + { + long ret; + ret = + wait_for_completion_timeout(&event->complete, + msecs_to_jiffies(timeout)); + if ( 0 >= ret ) + { + return VOS_STATUS_E_TIMEOUT; + } + } + else + { + int ret; + ret = wait_for_completion_interruptible(&event->complete); + if ( 0 != ret ) + { + // negative means interrupted + return VOS_STATUS_E_TIMEOUT; + } + } + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_wait_multiple_events() - Waits for event(s) to be set. + This is a duplicate of vos_wait_events() function. It ends up calling + vos_wait_events() with the params passed in. + + This API waits for any event in the input array of events to be + set. The caller is blocked waiting any event in the array to be + set or for the timeout to occur. + + If multiple events in the array are set, only one event is identified + in the return from this call as satisfying the wait condition. The + caller is responsible for calling \a vos_wait_events() again to find + the other events that are set. + + \param pEventList - pointer to an array of event pointers + + \param numEvents - Number of events + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \param pEventIndex - This is a pointer to the location where the index of + the event in the event array that satisfied the wait because + the event was set. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + VOS_STATUS_E_INVAL - At least one of the values specified in the + event array refers to an uninitialized event object. The invalid + event is identified by the index in *pEventIndex. Note that only + the first uninitialized event is detected when this error is + returned. + + VOS_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + VOS_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. + + \sa vos_wait_single_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_multiple_events( vos_event_t **events, v_U8_t numEvents, + v_U32_t timeout, v_U8_t *pEventIndex ) +{ + // NO LONGER SUPPORTED + return VOS_STATUS_E_FAILURE; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_getBin.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_getBin.c new file mode 100644 index 0000000000000..3c90b19f020c9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_getBin.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + vos_getBin.c + \brief + Description... + ==============================================================================*/ +/* $HEADER$ */ +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include // for softmac direct file i/o +#include +#include +#include +#include +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ +extern tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ); + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + \brief vos_get_binary_blob() - get binary data from platform + This API allows components to get binary data from the platform independent + of where the data is stored on the device. +
    +
  • Firmware +
  • Configuration Data + \param binaryId - identifies the binary data to return to the caller. + raw binary data and update the *pBufferSize with the exact + size of the data that has been retreived. + the size of the binary data in *pBufferSize. + size of the data buffer available at pBuffer. Upon success, this + retreived and written to the buffer at pBuffer. + Input value of 0 is valid and will cause the API to return + the size of the binary data in *pBufferSize. + retreived and written to the buffer. + refer to a valid VOS Binary ID. + variable that the API can write to. + *pBufferSize is not big enough to contain the binary. + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS vos_get_binary_blob( VOS_BINARY_ID binaryId, + v_VOID_t *pBuffer, v_SIZE_t *pBufferSize ) +{ + VOS_STATUS VosSts = VOS_STATUS_SUCCESS; + char *pFileName; + + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL); + + // get the correct file name from binary Id + switch (binaryId) + { + case VOS_BINARY_ID_CONFIG: + pFileName = WLAN_CFG_FILE; + break; + default: + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Invalid binaryID"); + return VosSts; + } + if(0 == *pBufferSize ) + { + /* just a file size request. set the value and return VOS_STATUS_E_NOMEM*/ + VosSts = hdd_get_cfg_file_size(((VosContextType*)(pVosContext))->pHDDContext,pFileName,pBufferSize); + + if ( !VOS_IS_STATUS_SUCCESS( VosSts )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : vos_open failed",__func__); + + return VOS_STATUS_E_FAILURE; + } + VosSts = VOS_STATUS_E_NOMEM; + } + else + { + if(NULL != pBuffer) { + // read the contents into the buffer + VosSts = hdd_read_cfg_file(((VosContextType*)(pVosContext))->pHDDContext,pFileName,pBuffer,pBufferSize); + } + else { + VosSts = VOS_STATUS_E_FAILURE; + } + } + + return VosSts; +} + + +tVOS_CON_MODE vos_get_conparam( void ) +{ + tVOS_CON_MODE con_mode; + con_mode = hdd_get_conparam ( ); + return con_mode; +} +tVOS_CONCURRENCY_MODE vos_get_concurrency_mode( void ) +{ + tVOS_CONCURRENCY_MODE con_mode; + con_mode = hdd_get_concurrency_mode ( ); + return con_mode; +} + +v_BOOL_t vos_concurrent_open_sessions_running(void) +{ + v_U8_t i=0; + v_U8_t j=0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + for (i=0; i < VOS_MAX_NO_OF_MODE; i++) + { + j += pHddCtx->no_of_open_sessions[i]; + } + } + } + + return (j>1); +} + +#ifdef WLAN_FEATURE_MBSSID +v_BOOL_t vos_concurrent_sap_sessions_running(v_VOID_t) +{ + v_U8_t i=0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + i = pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]; + } + } + + return (i>1); +} +#endif + + +/**--------------------------------------------------------------------------- + * + * \brief vos_max_concurrent_connections_reached() + * + * This function checks for presence of concurrency where more than + * one connection exists and it returns TRUE if the max concurrency is + * reached. + * + * Example: + * STA + STA (wlan0 and wlan1 are connected) - returns TRUE + * STA + STA (wlan0 connected and wlan1 disconnected) - returns FALSE + * DUT with P2P-GO + P2P-CLIENT connection) - returns TRUE + * + * \param - None + * + * \return - VOS_TRUE or VOS_FALSE + * + * --------------------------------------------------------------------------*/ +v_BOOL_t vos_max_concurrent_connections_reached (void) +{ + v_U8_t i = 0, j = 0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + for (i = 0; i < VOS_MAX_NO_OF_MODE; i++) + j += pHddCtx->no_of_active_sessions[i]; + + return (j > (pHddCtx->cfg_ini->gMaxConcurrentActiveSessions - 1)); + } + } + + return VOS_FALSE; +} + +void vos_clear_concurrent_session_count(void) +{ + v_U8_t i = 0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + for (i = 0; i < VOS_MAX_NO_OF_MODE; i++) + pHddCtx->no_of_active_sessions[i] = 0; + } + } +} + +/**--------------------------------------------------------------------------- + * + * \brief vos_is_multiple_active_sta_sessions() + * + * This function checks for presence of multiple active sta connections + * and it returns TRUE if the more than 1 active sta connection exists. + * + * \param - None + * + * \return - TRUE or FALSE + * + * --------------------------------------------------------------------------*/ +v_BOOL_t vos_is_multiple_active_sta_sessions (void) +{ + hdd_context_t *pHddCtx; + v_U8_t j = 0; + + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + j = pHddCtx->no_of_active_sessions[VOS_STA_MODE]; + } + } + + return (j > 1); +} + +/**--------------------------------------------------------------------------- + * + * \brief vos_is_sta_active_connection_exists() + * + * This function checks for the presence of active sta connection + * and it returns TRUE if exists. + * + * \param - None + * + * \return - VOS_TRUE or VOS_FALSE + * + * --------------------------------------------------------------------------*/ +v_BOOL_t vos_is_sta_active_connection_exists (void) +{ + hdd_context_t *pHddCtx; + v_U8_t j = 0; + + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + j = pHddCtx->no_of_active_sessions[VOS_STA_MODE]; + } + } + + return (j ? VOS_TRUE : VOS_FALSE); +} + diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_list.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_list.c new file mode 100644 index 0000000000000..6032e74bf40c3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_list.c @@ -0,0 +1,931 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + + vos_list.c + + \brief + + Description... + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ +#define VOS_LIST_COOKIE 0xabadfeed + + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_init( vos_list_t *pList ) +{ + if ( pList == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie == VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: already initialized list", __func__); + return VOS_STATUS_E_BUSY; + } + + mutex_init(&pList->lock); + + INIT_LIST_HEAD( &pList->anchor ); + + pList->count = 0; + pList->cookie = VOS_LIST_COOKIE; + + return( VOS_STATUS_SUCCESS ); +} + + +VOS_STATUS vos_list_destroy( vos_list_t *pList ) +{ + int rc; + if (pList == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->count !=0 ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list length not equal to zero", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_BUSY; + } + + // clear the cookie. This indicates the list is destroyed. + pList->cookie = 0; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_insert_front( vos_list_t *pList, vos_list_node_t *pNode ) +{ + int rc; + + if ( ( pList == NULL) || ( pNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add( pNode, &pList->anchor ); + + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_list_insert_back( vos_list_t *pList, vos_list_node_t *pNode ) +{ + int rc; + + if ( ( pList == NULL) || ( pNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add_tail( pNode, &pList->anchor ); + + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_insert_back_size( vos_list_t *pList, vos_list_node_t *pNode, v_SIZE_t *pSize ) +{ + int rc; + if ( ( pList == NULL) || ( pNode == NULL) || (pSize == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add_tail( pNode, &pList->anchor ); + + pList->count++; + *pSize = pList->count; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_remove_front( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + // the assumption here is that pList is the head of the list (dummy + // node) and points to first and last element in circular linked list + if ( ( pList == NULL ) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty( &pList->anchor ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + + *ppNode = listptr; + + list_del(pList->anchor.next); + + pList->count--; + mutex_unlock(&pList->lock); + return VOS_STATUS_SUCCESS; +} + + + +VOS_STATUS vos_list_remove_back( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + // the assumption here is that pList is the head of the list (dummy node) and points to first and + // last element in circular linked list + if ( ( pList == NULL ) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty( &pList->anchor ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.prev; + + *ppNode = listptr; + + list_del(pList->anchor.prev); + + pList->count--; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_list_size( vos_list_t *pList, v_SIZE_t *pSize ) +{ + int rc; + if ( ( pList ==NULL) || ( pSize == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + *pSize = pList->count; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_front() - peek at the node at front of a linked list + + The vos_list_peek_front() API will return a pointer to the node at the + front of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return VOS_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_front( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + if ( ( pList == NULL) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + listptr = pList->anchor.next; + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_back() - peek at the node at back of a linked list + + The vos_list_peek_back() API will return a pointer to the node at the + back of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return VOS_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_peek_back(), vos_list_remove_back(), vos_list_peek_front(), + vos_list_remove_front() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_back( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + if ( ( pList == NULL) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + listptr = pList->anchor.prev; + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_next() - peek at the node after the specified node + + The vos_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - There is no 'next' node (the input node is + at the back of the list). + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_next( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + listptr = pNode->next; + if (listptr == &pList->anchor) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_prev() - peek at the node before the specified node + + The vos_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - There is no 'previous' node (the input node is + at the front of the list). + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_prev( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + listptr = pNode->prev; + + if (listptr == &pList->anchor) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_insert_before() - insert node at front of a specified + list node + + The vos_list_insert_before() API will insert a node onto a properly + initialized vOS List object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_before( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_add(pNodeToInsert, pNode); + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_list_insert_after() - insert node behind a specified list node + + The vos_list_insert_after() API will insert a node onto a properly + initialized vOS List object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_after( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_add_tail(pNodeToInsert, pNode); + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_remove_node() - remove specified node from vOS list list + + The vos_list_remove_node() API will remove a specified node from the + properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + + VOS_STATUS_E_FAULT - pList or pNodeToRemove is not a valid pointer + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_node( vos_list_t *pList, vos_list_node_t *pNodeToRemove ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL ) || ( pNodeToRemove == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNodeToRemove is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNodeToRemove) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_del(pNodeToRemove); + pList->count--; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_lock.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_lock.c new file mode 100644 index 0000000000000..be1137d8824eb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_lock.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: vos_lock.c + + OVERVIEW: This source file contains definitions for vOS lock APIs + The four APIs mentioned in this file are used for + initializing , acquiring, releasing and destroying a lock. + the lock are implemented using critical sections + + DEPENDENCIES: +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include "vos_lock.h" +#include "vos_memory.h" +#include "vos_trace.h" +#ifdef CONFIG_CNSS +#include +#endif + + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +#define LINUX_LOCK_COOKIE 0x12345678 +enum +{ + LOCK_RELEASED = 0x11223344, + LOCK_ACQUIRED, + LOCK_DESTROYED +}; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief vos_lock_init() - initializes a vOSS lock + + The vos_lock_init() function initializes the specified lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - lock was successfully initialized and + is ready to be used. + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the lock + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by lock, a previously + initialized, but not yet destroyed, lock. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the lock + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_init ( vos_lock_t *lock ) +{ + + //check for invalid pointer + if ( lock == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + return VOS_STATUS_E_FAULT; + } + // check for 'already initialized' lock + if ( LINUX_LOCK_COOKIE == lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: already initialized lock",__func__); + return VOS_STATUS_E_BUSY; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + + // initialize new lock + mutex_init( &lock->m_lock ); + lock->cookie = LINUX_LOCK_COOKIE; + lock->state = LOCK_RELEASED; + lock->processID = 0; + lock->refcount = 0; + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_lock_acquire() - acquires a lock + + A lock object is acquired by calling \a vos_lock_acquire(). If the lock + is already locked, the calling thread shall block until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param lock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_acquire ( vos_lock_t* lock ) +{ + int rc; + //Check for invalid pointer + if ( lock == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + // check if lock refers to an initialized object + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + if ((lock->processID == current->pid) && + (lock->state == LOCK_ACQUIRED)) + { + lock->refcount++; +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d %d", __func__, lock, current->pid, lock->refcount); +#endif + return VOS_STATUS_SUCCESS; + } + // Acquire a Lock + mutex_lock( &lock->m_lock ); + rc = mutex_is_locked( &lock->m_lock ); + if (rc == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock mutex (rc = %d)", __func__, rc); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d", __func__, lock, current->pid); +#endif + if ( LOCK_DESTROYED != lock->state ) + { + lock->processID = current->pid; + lock->refcount++; + lock->state = LOCK_ACQUIRED; + return VOS_STATUS_SUCCESS; + } + else + { + // lock is already destroyed + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Lock is already destroyed", __func__); + mutex_unlock(&lock->m_lock); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } +} + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param lock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_PERM - Operation is not permitted. The calling + thread does not own the lock. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_release ( vos_lock_t *lock ) +{ + //Check for invalid pointer + if ( lock == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check if lock refers to an uninitialized object + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // CurrentThread = GetCurrentThreadId(); + // Check thread ID of caller against thread ID + // of the thread which acquire the lock + if ( lock->processID != current->pid ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: current task pid does not match original task pid!!",__func__); +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: Lock held by=%d being released by=%d", __func__, lock->processID, current->pid); +#endif + + VOS_ASSERT(0); + return VOS_STATUS_E_PERM; + } + if ((lock->processID == current->pid) && + (lock->state == LOCK_ACQUIRED)) + { + if (lock->refcount > 0) lock->refcount--; + } +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d %d", __func__, lock, lock->processID, lock->refcount); +#endif + if (lock->refcount) return VOS_STATUS_SUCCESS; + + lock->processID = 0; + lock->refcount = 0; + lock->state = LOCK_RELEASED; + // Release a Lock + mutex_unlock( &lock->m_lock ); +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: Freeing lock %x %d %d", lock, lock->processID, lock->refcount); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_lock_destroy() - Destroys a vOSS Lock - probably not required + for Linux. It may not be required for the caller to destroy a lock after + usage. + + The \a vos_lock_destroy() function shall destroy the lock object + referenced by lock. After a successful return from \a vos_lock_destroy() + the lock object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_lock_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS lock functions to manipulate the lock such + as vos_lock_acquire() will fail if the lock is destroyed. Therefore, + don't use the lock after it has been destroyed until it has + been re-initialized. + + \param lock - the lock object to be destroyed. + + \return VOS_STATUS_SUCCESS - lock was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by lock while it is locked + or still referenced. + + VOS_STATUS_E_INVAL - The value specified by lock is invalid. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_destroy( vos_lock_t *lock ) +{ + //Check for invalid pointer + if ( NULL == lock ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock", __func__); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + + // check if lock is released + if (!mutex_trylock(&lock->m_lock)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: lock is not released", __func__); + return VOS_STATUS_E_BUSY; + } + lock->cookie = 0; + lock->state = LOCK_DESTROYED; + lock->processID = 0; + lock->refcount = 0; + + mutex_unlock(&lock->m_lock); + + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_init() - initializes a vOSS spin lock + + The vos_spin_lock_init() function initializes the specified spin lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_spin_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param pLock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - spin lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_spin_lock_init(vos_spin_lock_t *pLock) +{ + spin_lock_init(pLock); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_acquire() - acquires a spin lock + + A lock object is acquired by calling \a vos_spin_lock_acquire(). If the lock + is already locked, the calling thread shall spin until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param pLock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_acquire(vos_spin_lock_t *pLock) +{ + spin_lock(pLock); + return VOS_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the spin lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param pLock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_release(vos_spin_lock_t *pLock) +{ + spin_unlock(pLock); + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_destroy() - releases resource of a lock + + \param pLock - the pointer to a lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_destroy(vos_spin_lock_t *pLock) +{ + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_init() - initializes a vOSS wake lock + + \param pLock - the wake lock to initialize + name - wakelock name + + \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name) +{ +#if defined CONFIG_CNSS + cnss_pm_wake_lock_init(pLock, name); +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) + wake_lock_init(pLock, WAKE_LOCK_SUSPEND, name); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_acquire() - acquires a wake lock + + \param pLock - the wake lock to acquire + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock) +{ +#if defined CONFIG_CNSS + cnss_pm_wake_lock(pLock); +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) + wake_lock(pLock); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_timeout_acquire() - acquires a wake lock with a timeout + + \param pLock - the wake lock to acquire + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_timeout_acquire(vos_wake_lock_t *pLock, v_U32_t msec) +{ +#if defined CONFIG_CNSS + cnss_pm_wake_lock_timeout(pLock, msec); +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) + wake_lock_timeout(pLock, msecs_to_jiffies(msec)); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_release() - releases a wake lock + + \param pLock - the wake lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock) +{ +#if defined CONFIG_CNSS + cnss_pm_wake_lock_release(pLock); +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) + wake_unlock(pLock); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_destroy() - destroys a wake lock + + \param pLock - the wake lock to destroy + + \return VOS_STATUS_SUCCESS - the lock was successfully destroyed + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock) +{ +#if defined CONFIG_CNSS + cnss_pm_wake_lock_destroy(pLock); +#elif defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) + wake_lock_destroy(pLock); +#endif + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_memory.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_memory.c new file mode 100644 index 0000000000000..81637480f78da --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_memory.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file vos_memory.c + + @brief Virtual Operating System Services Memory API +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include "vos_memory.h" +#include "vos_trace.h" + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC +#ifdef CONFIG_CNSS +#include +#else +#include +#endif +#endif + + +#ifdef MEMORY_DEBUG +#include "wlan_hdd_dp_utils.h" + +hdd_list_t vosMemList; + +static v_U8_t WLAN_MEM_HEADER[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68 }; +static v_U8_t WLAN_MEM_TAIL[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87}; + +struct s_vos_mem_struct +{ + hdd_list_node_t pNode; + char* fileName; + unsigned int lineNum; + unsigned int size; + v_U8_t header[8]; +}; +#endif + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Type Declarations + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * External Function implementation + * ------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +void vos_mem_init() +{ + /* Initalizing the list with maximum size of 60000 */ + hdd_list_init(&vosMemList, 60000); + return; +} + +void vos_mem_clean() +{ + v_SIZE_t listSize; + hdd_list_size(&vosMemList, &listSize); + + if(listSize) + { + hdd_list_node_t* pNode; + VOS_STATUS vosStatus; + + struct s_vos_mem_struct* memStruct; + char* prev_mleak_file = ""; + unsigned int prev_mleak_lineNum = 0; + unsigned int prev_mleak_sz = 0; + unsigned int mleak_cnt = 0; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: List is not Empty. listSize %d ", __func__, (int)listSize); + + do + { + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_remove_front(&vosMemList, &pNode); + spin_unlock(&vosMemList.lock); + if(VOS_STATUS_SUCCESS == vosStatus) + { + memStruct = (struct s_vos_mem_struct*)pNode; + + /* Take care to log only once multiple memory leaks from + * the same place */ + if(strcmp(prev_mleak_file, memStruct->fileName) || + (prev_mleak_lineNum != memStruct->lineNum) || + (prev_mleak_sz != memStruct->size)) + { + if(mleak_cnt != 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%d Time Memory Leak@ File %s, @Line %d, size %d", + mleak_cnt, prev_mleak_file, prev_mleak_lineNum, + prev_mleak_sz); + } + prev_mleak_file = memStruct->fileName; + prev_mleak_lineNum = memStruct->lineNum; + prev_mleak_sz = memStruct->size; + mleak_cnt = 0; + } + mleak_cnt++; + + kfree((v_VOID_t*)memStruct); + } + }while(vosStatus == VOS_STATUS_SUCCESS); + + /* Print last memory leak from the module */ + if(mleak_cnt) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%d Time memory Leak@ File %s, @Line %d, size %d", + mleak_cnt, prev_mleak_file, prev_mleak_lineNum, + prev_mleak_sz); + } + + +#ifdef CONFIG_HALT_KMEMLEAK + BUG_ON(0); +#endif + } +} + +void vos_mem_exit() +{ + vos_mem_clean(); + hdd_list_destroy(&vosMemList); +} + +v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum) +{ + struct s_vos_mem_struct* memStruct; + v_VOID_t* memPtr = NULL; + v_SIZE_t new_size; + int flags = GFP_KERNEL; + unsigned long IrqFlags; + + + if (size > (1024*1024)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: called with arg > 1024K; passed in %d !!!", __func__,size); + return NULL; + } + + if (in_interrupt() || in_atomic()) + { + flags = GFP_ATOMIC; + } + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD) + { + v_VOID_t *pmem; + pmem = wcnss_prealloc_get(size); + if (NULL != pmem) + return pmem; + } +#endif + + new_size = size + sizeof(struct s_vos_mem_struct) + 8; + + memStruct = (struct s_vos_mem_struct*)kmalloc(new_size, flags); + + if(memStruct != NULL) + { + VOS_STATUS vosStatus; + + memStruct->fileName = fileName; + memStruct->lineNum = lineNum; + memStruct->size = size; + + vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); + vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL)); + + spin_lock_irqsave(&vosMemList.lock, IrqFlags); + vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode); + spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); + if(VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); + } + + memPtr = (v_VOID_t*)(memStruct + 1); + } + return memPtr; +} + +v_VOID_t vos_mem_free( v_VOID_t *ptr ) +{ + unsigned long IrqFlags; + + if (ptr != NULL) + { + VOS_STATUS vosStatus; + struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1; + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if (wcnss_prealloc_put(ptr)) + return; +#endif + + spin_lock_irqsave(&vosMemList.lock, IrqFlags); + vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode); + spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); + + if(VOS_STATUS_SUCCESS == vosStatus) + { + if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + VOS_BUG(0); + } + if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + VOS_BUG(0); + } + kfree((v_VOID_t*)memStruct); + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unallocated memory (double free?)", __func__); + VOS_BUG(0); + } + } +} +#else +v_VOID_t * vos_mem_malloc( v_SIZE_t size ) +{ + int flags = GFP_KERNEL; +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + v_VOID_t* pmem; +#endif + if (size > (1024*1024)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: called with arg > 1024K; passed in %d !!!", __func__,size); + return NULL; + } + if (in_interrupt() || irqs_disabled() || in_atomic()) + { + flags = GFP_ATOMIC; + } +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if(size > WCNSS_PRE_ALLOC_GET_THRESHOLD) + { + pmem = wcnss_prealloc_get(size); + if(NULL != pmem) + return pmem; + } +#endif + return kmalloc(size, flags); +} + +v_VOID_t vos_mem_free( v_VOID_t *ptr ) +{ + if (ptr == NULL) + return; + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if(wcnss_prealloc_put(ptr)) + return; +#endif + + kfree(ptr); +} +#endif + +v_BOOL_t vos_is_in_irq_context(void) +{ + if(in_interrupt()) + return VOS_TRUE; + else + return VOS_FALSE; +} + +v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value ) +{ + if (ptr == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__); + return; + } + memset(ptr, value, numBytes); +} + +v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where ptr can be NULL + return; + } + + if (ptr == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__); + return; + } + memset(ptr, 0, numBytes); + +} + +v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pDst or pSrc can be NULL + return; + } + + if ((pDst == NULL) || (pSrc==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, source:%p destination:%p", + __func__, pSrc, pDst); + VOS_ASSERT(0); + return; + } + memcpy(pDst, pSrc, numBytes); +} + +v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pDst or pSrc can be NULL + return; + } + + if ((pDst == NULL) || (pSrc==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, source:%p destination:%p", + __func__, pSrc, pDst); + VOS_ASSERT(0); + return; + } + memmove(pDst, pSrc, numBytes); +} + +v_BOOL_t vos_mem_compare( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pMemory1 or pMemory2 can be NULL + return VOS_TRUE; + } + + if ((pMemory1 == NULL) || (pMemory2==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, p1:%p p2:%p", + __func__, pMemory1, pMemory2); + VOS_ASSERT(0); + return VOS_FALSE; + } + return (memcmp(pMemory1, pMemory2, numBytes)?VOS_FALSE:VOS_TRUE); +} + + +v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ) + +{ + return( (v_SINT_t) memcmp( pMemory1, pMemory2, numBytes ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. This memory will have special attributes making it DMA friendly i.e. + it will exist in contiguous, 32-byte aligned uncached memory. A normal + vos_mem_malloc does not yield memory with these attributes. + + NOTE: the special DMA friendly memory is very scarce and this API must be + used sparingly + + On WM, there is nothing special about this memory. SDHC allocates the + DMA friendly buffer and copies the data into it + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum) +{ + struct s_vos_mem_struct* memStruct; + v_VOID_t* memPtr = NULL; + v_SIZE_t new_size; + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return NULL; + } + + new_size = size + sizeof(struct s_vos_mem_struct) + 8; + + memStruct = (struct s_vos_mem_struct*)kmalloc(new_size,GFP_KERNEL); + + if(memStruct != NULL) + { + VOS_STATUS vosStatus; + + memStruct->fileName = fileName; + memStruct->lineNum = lineNum; + memStruct->size = size; + + vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); + vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL)); + + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode); + spin_unlock(&vosMemList.lock); + if(VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); + } + + memPtr = (v_VOID_t*)(memStruct + 1); + } + + return memPtr; +} + +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ) +{ + if (ptr != NULL) + { + VOS_STATUS vosStatus; + struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1; + + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode); + spin_unlock(&vosMemList.lock); + + if(VOS_STATUS_SUCCESS == vosStatus) + { + if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + kfree((v_VOID_t*)memStruct); + } + } +} +#else +v_VOID_t* vos_mem_dma_malloc( v_SIZE_t size ) +{ + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return NULL; + } + return kmalloc(size, GFP_KERNEL); +} + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_free() - vOSS DMA Free Memory + + This function will free special DMA friendly memory pointed to by 'ptr'. + + On WM, there is nothing special about the memory being free'd. SDHC will + take care of free'ing the DMA friendly buffer + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ) +{ + if (ptr == NULL) + return; + kfree(ptr); +} +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_mq.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_mq.c new file mode 100644 index 0000000000000..b585064f39fbd --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_mq.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_mq.c + + \brief virtual Operating System Services (vOSS) message queue APIs + + Message Queue Definitions and API + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "vos_sched.h" +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + + \brief vos_mq_init() - Initialize the vOSS Scheduler + + The \a vos_mq_init() function initializes the Message queue. + + \param pMq - pointer to the message queue + + \return VOS_STATUS_SUCCESS - Message queue was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - Invalid parameter passed to the message + queue initialize function. + + \sa vos_mq_init() + +---------------------------------------------------------------------------*/ +__inline VOS_STATUS vos_mq_init(pVosMqType pMq) +{ + + /* Some quick sanity check*/ + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* + ** Now initialize the lock + */ + spin_lock_init(&pMq->mqLock); + + /* + ** Now initialize the List data structure + */ + INIT_LIST_HEAD(&pMq->mqList); + + return VOS_STATUS_SUCCESS; + +} /* vos_mq_init()*/ + +/*--------------------------------------------------------------------------- + + \brief vos_mq_deinit() - DeInitialize the vOSS Scheduler + + The \a vos_mq_init() function de-initializes the Message queue. + + \param pMq - pointer to the message queue + + \return None + + \sa vos_mq_deinit() + +---------------------------------------------------------------------------*/ +__inline void vos_mq_deinit(pVosMqType pMq) +{ + /* + ** Some quick sanity check + */ + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return ; + } + + /* we don't have to do anything with the embedded list or spinlock */ + +}/* vos_mq_deinit() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_mq_put() - Add a message to the message queue + + The \a vos_mq_put() function add a message to the Message queue. + + \param pMq - pointer to the message queue + + \param pMsgWrapper - Msg Wrapper containing the message + + \return None + + \sa vos_mq_put() + +---------------------------------------------------------------------------*/ +__inline void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper) +{ + unsigned long flags; + + /* + ** Some quick sanity check + */ + if ((pMq == NULL) || (pMsgWrapper == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return ; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + + list_add_tail(&pMsgWrapper->msgNode, &pMq->mqList); + + spin_unlock_irqrestore(&pMq->mqLock, flags); + +} /* vos_mq_put() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_mq_get() - Get a message with its wrapper from a message queue + + The \a vos_mq_get() function retrieve a message with its wrapper from + the Message queue. + + \param pMq - pointer to the message queue + + \return pointer to the Message Wrapper + + \sa vos_mq_get() + +---------------------------------------------------------------------------*/ +__inline pVosMsgWrapper vos_mq_get(pVosMqType pMq) +{ + pVosMsgWrapper pMsgWrapper = NULL; + + /* + ** Some quick sanity check + */ + struct list_head * listptr; + unsigned long flags; + + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return NULL; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + + if( list_empty(&pMq->mqList) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: VOS Message Queue is empty",__func__); + } + else + { + listptr = pMq->mqList.next; + pMsgWrapper = (pVosMsgWrapper)list_entry(listptr, VosMsgWrapper, msgNode); + list_del(pMq->mqList.next); + } + + spin_unlock_irqrestore(&pMq->mqLock, flags); + + return pMsgWrapper; + +} /* vos_mq_get() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_is_mq_empty() - Return if the MQ is empty + + The \a vos_is_mq_empty() returns true if the queue is empty + + \param pMq - pointer to the message queue + + \return pointer to the Message Wrapper + + \sa vos_mq_get() + +---------------------------------------------------------------------------*/ +__inline v_BOOL_t vos_is_mq_empty(pVosMqType pMq) +{ + v_BOOL_t state = VOS_FALSE; + unsigned long flags; + + /* + ** Some quick sanity check + */ + if (pMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return VOS_STATUS_E_FAILURE; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + state = list_empty(&pMq->mqList)?VOS_TRUE:VOS_FALSE; + spin_unlock_irqrestore(&pMq->mqLock, flags); + + return state; + +} /* vos_mq_get() */ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_nvitem.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_nvitem.c new file mode 100644 index 0000000000000..62013298a684b --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_nvitem.c @@ -0,0 +1,1771 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/*============================================================================ + FILE: vos_nvitem.c + OVERVIEW: This source file contains definitions for vOS NV Item APIs + DEPENDENCIES: NV, remote API client, WinCE REX +============================================================================*/ +/*============================================================================ + EDIT HISTORY FOR MODULE +============================================================================*/ +// the following is used to disable warning for having too many labels in +// the 'nv_items_enum_type' + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "aniGlobal.h" +#include "vos_nvitem.h" +#include "vos_trace.h" +#include "vos_api.h" +#include "wlan_hdd_misc.h" +#include "vos_sched.h" +#include "sme_Api.h" +#include "wlan_hdd_main.h" +#include +#include "regdomain.h" +#include "regdomain_common.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) +#define IEEE80211_CHAN_NO_80MHZ 1<<7 +#endif + +static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT; +/* true if init happens thru init time driver hint */ +static v_BOOL_t init_by_driver = VOS_FALSE; +/* true if init happens thru init time callback from regulatory core. + this should be set to true during driver reload */ +static v_BOOL_t init_by_reg_core = VOS_FALSE; + + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define MAX_COUNTRY_COUNT 300 +#define REG_WAIT_TIME 50 +/* + * This is a set of common rules used by our world regulatory domains. + * We have 12 world regulatory domains. To save space we consolidate + * the regulatory domains in 5 structures by frequency and change + * the flags on our reg_notifier() on a case by case basis. + */ + +/* Only these channels all allow active scan on all world regulatory domains */ +#define REG_RULE_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) + +/* We enable active scan on these a case by case basis by regulatory domain */ +#define REG_RULE_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) +#define REG_RULE_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) + +/* We allow IBSS on these on a case by case basis by regulatory domain */ +#define REG_RULE_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +#define REG_RULE_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +#define REG_RULE_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +#define REG_RULE_2GHZ_ALL REG_RULE_2GHZ_CH01_11, \ + REG_RULE_2GHZ_CH12_13, \ +REG_RULE_2GHZ_CH14 + +#define REG_RULE_5GHZ_ALL REG_RULE_5GHZ_5150_5350, \ + REG_RULE_5GHZ_5470_5850 + +/* This one skips what we call "mid band" */ +#define REG_RULE_5GHZ_NO_MIDBAND REG_RULE_5GHZ_5150_5350, \ + REG_RULE_5GHZ_5725_5850 +#define WORLD_SKU_MASK 0x00F0 +#define WORLD_SKU_PREFIX 0x0060 + +/* Can be used for: + * 0x60, 0x61, 0x62 */ +static const struct ieee80211_regdomain vos_world_regdom_60_61_62 = { + .n_reg_rules = 5, + .alpha2 = "99", + .reg_rules = { + REG_RULE_2GHZ_ALL, + REG_RULE_5GHZ_ALL, + } +}; + +/* Can be used by 0x63 and 0x65 */ +static const struct ieee80211_regdomain vos_world_regdom_63_65 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + REG_RULE_2GHZ_CH01_11, + REG_RULE_2GHZ_CH12_13, + REG_RULE_5GHZ_NO_MIDBAND, + } +}; + +/* Can be used by 0x64 only */ +static const struct ieee80211_regdomain vos_world_regdom_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + REG_RULE_2GHZ_CH01_11, + REG_RULE_5GHZ_NO_MIDBAND, + } +}; + +/* Can be used by 0x66 and 0x69 */ +static const struct ieee80211_regdomain vos_world_regdom_66_69 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + REG_RULE_2GHZ_CH01_11, + REG_RULE_5GHZ_ALL, + } +}; + +/* Can be used by 0x67, 0x68, 0x6A and 0x6C */ +static const struct ieee80211_regdomain vos_world_regdom_67_68_6A_6C = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + REG_RULE_2GHZ_CH01_11, + REG_RULE_2GHZ_CH12_13, + REG_RULE_5GHZ_ALL, + } +}; + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +// this wrapper structure is identical to nv_cmd_type except the +// data_ptr type is changed void* to avoid exceeding the debug information +// module size as there are too many elements within nv_items_type union + +// structure for code and regulatory domain of a single country +typedef struct +{ + v_U8_t regDomain; + v_COUNTRYCODE_t countryCode; +} CountryInfo_t; +// structure of table to map country code and regulatory domain +typedef struct +{ + v_U16_t countryCount; + CountryInfo_t countryInfo[MAX_COUNTRY_COUNT]; +} CountryInfoTable_t; +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +// cache of country info table; +// this is re-initialized from data on binary file +// loaded on driver initialization if available + + +static CountryInfoTable_t countryInfoTable = +{ + /* the first entry in the table is always the world domain */ + 138, + { + {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN + {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA + {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE + {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA + {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA + {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES + {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA + {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA + {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA + {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA + {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA + {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN + {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA + {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS + {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH + {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM + {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA + {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN + {REGDOMAIN_ETSI, {'B', 'L'}}, // + {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA + {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM + {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA + {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL + {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS + {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS + {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE + {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA + {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND + {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE + {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA + {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA + {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA + {REGDOMAIN_ETSI, {'C', 'S'}}, + {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS + {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC + {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY + {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK + {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC + {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA + {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR + {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA + {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT + {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN + {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND + {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE + {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM + {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA + {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA + {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA + {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND + {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE + {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE + {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA + {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM + {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY + {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA + {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND + {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL + {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA + {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF + {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD + {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY + {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA + {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN + {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN + {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA + {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA + {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF + {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF + {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT + {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN + {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON + {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN + {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA + {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA + {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG + {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA + {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO + {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO + {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA + {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO + {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS + {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE + {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA + {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS + {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI + {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO + {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA + {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA + {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA + {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS + {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY + {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL + {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND + {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN + {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA + {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU + {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA + {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA + {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES + {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN + {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND + {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO + {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED + {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL + {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY + {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR + {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION + {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA + {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA + {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA + {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA + {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA + {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN + {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE + {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA + {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA + {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR + {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC + {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND + {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA + {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY + {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO + {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA + {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF + {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE + {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA + {REGDOMAIN_FCC, {'U', 'S'}}, //USA + {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY + {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN + {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA + {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US + {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM + {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN + {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE + {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA + {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE + } +}; + +typedef struct nvEFSTable_s +{ + sHalNv halnv; +} nvEFSTable_t; + +static nvEFSTable_t *pnvEFSTable; + +const tRfChannelProps rfChannels[NUM_RF_CHANNELS] = +{ + //RF_SUBBAND_2_4_GHZ + //freq, chan#, band + { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1, + { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2, + { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3, + { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4, + { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5, + { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6, + { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7, + { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8, + { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9, + { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10, + { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11, + { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12, + { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13, + { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14, + { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240, + { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244, + { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248, + { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252, + { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208, + { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212, + { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216, + { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36, + { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40, + { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44, + { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48, + { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52, + { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56, + { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60, + { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64, + { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100, + { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104, + { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108, + { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112, + { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116, + { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120, + { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124, + { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128, + { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132, + { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136, + { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149, + { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153, + { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157, + { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161, + { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165, + { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3, + { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4, + { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5, + { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6, + { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7, + { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8, + { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9, + { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10, + { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11, + { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242, + { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246, + { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250, + { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210, + { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214, + { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38, + { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42, + { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46, + { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50, + { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54, + { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58, + { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62, + { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102, + { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106, + { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110, + { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114, + { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118, + { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122, + { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126, + { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130, + { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134, + { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138, +#ifdef FEATURE_WLAN_CH144 + { 5710, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142, +#endif /* FEATURE_WLAN_CH144 */ + { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151, + { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155, + { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159, + { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163, +}; + +extern const sHalNv nvDefaults; + +const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels; + +static inline bool is_wwr_sku(u16 regd) +{ + return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && + (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || + (regd == WORLD)); +} + +bool is_world_regd(u_int32_t regd) +{ + return is_wwr_sku(regd & ~WORLDWIDE_ROAMING_FLAG); +} + +static const struct ieee80211_regdomain *vos_default_world_regdomain(void) +{ + /* this is the most restrictive */ + return &vos_world_regdom_64; +} + +static const struct ieee80211_regdomain *vos_custom_world_regdomain(void) +{ + /* this is the most restrictive */ + return &vos_world_regdom_60_61_62; +} + +static const +struct ieee80211_regdomain *vos_world_regdomain(struct regulatory *reg) +{ + REG_DMN_PAIR_MAPPING *regpair; + regpair = (REG_DMN_PAIR_MAPPING *)reg->regpair; + switch (regpair->regDmnEnum) { + case 0x60: + case 0x61: + case 0x62: + return &vos_world_regdom_60_61_62; + case 0x63: + case 0x65: + return &vos_world_regdom_63_65; + case 0x64: + return &vos_world_regdom_64; + case 0x66: + case 0x69: + return &vos_world_regdom_66_69; + case 0x67: + case 0x68: + case 0x6A: + case 0x6C: + return &vos_world_regdom_67_68_6A_6C; + default: + WARN_ON(1); + return vos_default_world_regdomain(); + } +} + + +/* Frequency is one where radar detection is required */ +static bool vos_is_radar_freq(u16 center_freq) +{ + return (center_freq >= 5260 && center_freq <= 5700); +} + +/* + * N.B: These exception rules do not apply radar freqs. + * + * - We enable adhoc (or beaconing) if allowed by 11d + * - We enable active scan if the channel is allowed by 11d + * - If no country IE has been processed and a we determine we have + * received a beacon on a channel we can enable active scan and + * adhoc (or beaconing). + */ +static void +vos_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + + ch = &sband->channels[i]; + + if (vos_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq), + 0, ®_rule); +#else + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); +#endif + if (IS_ERR(reg_rule)) + continue; + /* + * If 11d had a rule for this channel ensure + * we enable adhoc/beaconing if it allows us to + * use it. Note that we would have disabled it + * by applying our static world regdomain by + * default during init, prior to calling our + * regulatory_hint(). + */ + if (!(reg_rule->flags & + NL80211_RRF_NO_IBSS)) + ch->flags &= + ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void +vos_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + if (!sband) + return; + + /* + * If no country IE has been received always enable active scan + * on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + * If a country IE has been received check its rule for this + * channel first before enabling active scan. The passive scan + * would have been enforced by the initial processing of our + * custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq), + 0, ®_rule); +#else + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); +#endif + + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq), + 0, ®_rule); +#else + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); +#endif + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ +static void vos_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!vos_is_radar_freq(ch->center_freq)) + continue; + /* We always enable radar detection/DFS on this + * frequency range. Additionally we also apply on + * this frequency range: + * - If STA mode does not yet have DFS supports disable + * active scanning + * - If adhoc mode does not support DFS yet then + * disable adhoc in the frequency. + * - If AP mode does not yet support radar detection/DFS + * do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void vos_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct regulatory *reg) +{ + REG_DMN_PAIR_MAPPING *regpair; + regpair = (REG_DMN_PAIR_MAPPING *)reg->regpair; + switch (regpair->regDmnEnum) { + case 0x60: + case 0x63: + case 0x66: + case 0x67: + case 0x6C: + vos_reg_apply_beaconing_flags(wiphy, initiator); + break; + case 0x68: + vos_reg_apply_beaconing_flags(wiphy, initiator); + vos_reg_apply_active_scan_flags(wiphy, initiator); + break; + } +} + +static int regd_init_wiphy(hdd_context_t *pHddCtx, struct regulatory *reg, + struct wiphy *wiphy) +{ + const struct ieee80211_regdomain *regd; + + if (pHddCtx->cfg_ini->fRegChangeDefCountry) { + regd = vos_custom_world_regdomain(); + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + } + else if (is_world_regd(reg->reg_domain)) + { + regd = vos_world_regdomain(reg); + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + } + else + { + regd = vos_default_world_regdomain(); + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; + } + wiphy_apply_custom_regulatory(wiphy, regd); + vos_reg_apply_radar_flags(wiphy); + vos_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +static int reg_init_from_eeprom(hdd_context_t *pHddCtx, struct regulatory *reg, + struct wiphy *wiphy) +{ + int ret_val = 0; + ret_val = regdmn_get_country_alpha2(reg); + if (ret_val) { + adf_os_print(KERN_ERR "Error in getting country code\n"); + return ret_val; + } + + reg->cc_src = COUNTRY_CODE_SET_BY_DRIVER; + + /* update default country code */ + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = + reg->alpha2[0]; + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = + reg->alpha2[1]; + + regd_init_wiphy(pHddCtx, reg, wiphy); + + return ret_val; +} + +static void vos_update_reg_info(hdd_context_t *pHddCtx) +{ + u_int32_t country_code; + country_code = regdmn_find_ctry_by_name(pHddCtx->reg.alpha2); + pHddCtx->reg.reg_domain = COUNTRY_ERD_FLAG; + pHddCtx->reg.reg_domain |= country_code; + regdmn_get_country_alpha2(&pHddCtx->reg); + return; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_open() - Open NV operation + Read NV bin file and prepare NV common structure + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_open(void) +{ + /* Allocate memory to global NV table */ + pnvEFSTable = (nvEFSTable_t *)vos_mem_malloc(sizeof(nvEFSTable_t)); + if ( NULL == pnvEFSTable ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + return VOS_STATUS_E_NOMEM; + } + + /*Copying the NV defaults */ + vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv)); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_nv_close(void) +{ + vos_mem_free(pnvEFSTable); + pnvEFSTable=NULL; + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedCountryCode() - get the list of supported + country codes + The \a vos_nv_getSupportedCountryCode() encodes the list of supported + country codes with paddings in the provided buffer + \param pBuffer - pointer to buffer where supported country codes + and paddings are encoded; this may be set to NULL + if user wishes to query the required buffer size to + get the country code list + \param pBufferSize - this is the provided buffer size on input; + this is the required or consumed buffer size on output + \return VOS_STATUS_SUCCESS - country codes are successfully encoded + VOS_STATUS_E_NOMEM - country codes are not encoded because either + the buffer is NULL or buffer size is + sufficient + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize, + v_SIZE_t paddingSize ) +{ + v_SIZE_t providedBufferSize = *pBufferSize; + int i; + // pBufferSize now points to the required buffer size + *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize ); + if ( NULL == pBuffer || providedBufferSize < *pBufferSize ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("Insufficient memory for country code list")); + return VOS_STATUS_E_NOMEM; + } + for (i = 0; i < countryInfoTable.countryCount; i++) + { + memcpy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN ); + pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize ); + } + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelListWithPower() - function to return the list of + supported channels with the power limit info too. + \param pChannels20MHz - list of 20 Mhz channels + \param pNum20MHzChannelsFound - number of 20 Mhz channels + \param pChannels40MHz - list of 20 Mhz channels + \param pNum40MHzChannelsFound - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */, + tANI_U8 *num20MHzChannelsFound, + tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */, + tANI_U8 *num40MHzChannelsFound + ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + int i, count; + + //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV + // or pass it as a parameter to NV from SME? + + if( channels20MHz && num20MHzChannelsFound ) + { + count = 0; + for( i = 0; i <= RF_CHAN_14; i++ ) + { + if( regChannels[i].enabled ) + { + channels20MHz[count].chanId = rfChannels[i].channelNum; + channels20MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + if( regChannels[i].enabled ) + { + channels20MHz[count].chanId = rfChannels[i].channelNum; + channels20MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + *num20MHzChannelsFound = (tANI_U8)count; + } + + if( channels40MHz && num40MHzChannelsFound ) + { + count = 0; + //center channels for 2.4 Ghz 40 MHz channels + for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ ) + { + + if( regChannels[i].enabled ) + { + channels40MHz[count].chanId = rfChannels[i].channelNum; + channels40MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + //center channels for 5 Ghz 40 MHz channels + for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ ) + { + + if( regChannels[i].enabled ) + { + channels40MHz[count].chanId = rfChannels[i].channelNum; + channels40MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + *num40MHzChannelsFound = (tANI_U8)count; + } + return (status); +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain + \return default regulatory domain + \sa + -------------------------------------------------------------------------*/ + +v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void ) +{ + return countryInfoTable.countryInfo[0].regDomain; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedChannels() - function to return the list of + supported channels + \param p20MhzChannels - list of 20 Mhz channels + \param pNum20MhzChannels - number of 20 Mhz channels + \param p40MhzChannels - list of 40 Mhz channels + \param pNum40MhzChannels - number of 40 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels, + v_U8_t *p40MhzChannels, int *pNum40MhzChannels) +{ + VOS_STATUS status = VOS_STATUS_E_INVAL; + int i, count = 0; + + if( p20MhzChannels && pNum20MhzChannels ) + { + if( *pNum20MhzChannels >= NUM_RF_CHANNELS ) + { + for( i = 0; i <= RF_CHAN_14; i++ ) + { + p20MhzChannels[count++] = rfChannels[i].channelNum; + } + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + p20MhzChannels[count++] = rfChannels[i].channelNum; + } + status = VOS_STATUS_SUCCESS; + } + *pNum20MhzChannels = count; + } + + return (status); +} + +/**------------------------------------------------------------------------ + \brief vos_nv_readDefaultCountryTable() - return the default Country table + \param table data - a union to return the default country table data in. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData ) +{ + + VOS_STATUS status = VOS_STATUS_SUCCESS; + memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry)); + pr_info("DefaultCountry is %c%c\n", + tableData->defaultCountryTable.countryCode[0], + tableData->defaultCountryTable.countryCode[1]); + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelEnabledState - + \param rfChannel - input channel enum to know evabled state + \return eNVChannelEnabledType enabled state for channel + * enabled + * disabled + * DFS + \sa + -------------------------------------------------------------------------*/ +eNVChannelEnabledType vos_nv_getChannelEnabledState +( + v_U32_t rfChannel +) +{ + v_U32_t channelLoop; + eRfChannels channelEnum = INVALID_RF_CHANNEL; + + for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) + { + if(rfChannels[channelLoop].channelNum == rfChannel) + { + channelEnum = (eRfChannels)channelLoop; + break; + } + } + + if(INVALID_RF_CHANNEL == channelEnum) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel); + return NV_CHANNEL_INVALID; + } + + return regChannels[channelEnum].enabled; +} + +/****************************************************************** + Add CRDA regulatory support +*******************************************************************/ + +static int bw20_ch_index_to_bw40_ch_index(int k) +{ + int m = -1; + if (k >= RF_CHAN_1 && k <= RF_CHAN_14) + { + m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ; + if (m > RF_CHAN_BOND_11) + m = RF_CHAN_BOND_11; + } + else if (k >= RF_CHAN_240 && k <= RF_CHAN_216) + { + m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ; + if (m > RF_CHAN_BOND_214) + m = RF_CHAN_BOND_214; + } + else if (k >= RF_CHAN_36 && k <= RF_CHAN_64) + { + m = k - RF_CHAN_36 + RF_CHAN_BOND_38; + if (m > RF_CHAN_BOND_62) + m = RF_CHAN_BOND_62; + } +#ifdef FEATURE_WLAN_CH144 + else if (k >= RF_CHAN_100 && k <= RF_CHAN_144) +#else + else if (k >= RF_CHAN_100 && k <= RF_CHAN_140) +#endif /* FEATURE_WLAN_CH144 */ + { + m = k - RF_CHAN_100 + RF_CHAN_BOND_102; +#ifdef FEATURE_WLAN_CH144 + if (m > RF_CHAN_BOND_142) + m = RF_CHAN_BOND_142; +#else + if (m > RF_CHAN_BOND_138) + m = RF_CHAN_BOND_138; +#endif /* FEATURE_WLAN_CH144 */ + } + else if (k >= RF_CHAN_149 && k <= RF_CHAN_165) + { + m = k - RF_CHAN_149 + RF_CHAN_BOND_151; + if (m > RF_CHAN_BOND_163) + m = RF_CHAN_BOND_163; + } + return m; +} + +static int create_linux_regulatory_entry(struct wiphy *wiphy, + v_U8_t nBandCapability); + +/**------------------------------------------------------------------------ + \brief vos_nv_setRegDomain - + \param clientCtxt - Client Context, Not used for PRIMA + regId - Regulatory Domain ID + sendRegHint - send hint to nl80211 + \return status set REG domain operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + v_BOOL_t sendRegHint) +{ + + if (regId >= REGDOMAIN_COUNT) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VOS set reg domain, invalid REG domain ID %d", regId); + return VOS_STATUS_E_INVAL; + } + + /* Set correct channel information based on REG Domain */ + regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels; + + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of + a country given its country code + The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of + a country given its country code. This is done from reading a cached + copy of the binary file. + \param pRegDomain - pointer to regulatory domain + \param countryCode - country code + \param source - source of the country code + \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country + VOS_STATUS_E_FAULT - invalid pointer error + VOS_STATUS_E_EMPTY - country code table is empty + VOS_STATUS_E_EXISTS - given country code does not exist in table + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain, + const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source) +{ + + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + int i; + + /* sanity checks */ + if (NULL == pRegDomain) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid reg domain pointer") ); + return VOS_STATUS_E_FAULT; + } + + *pRegDomain = REGDOMAIN_COUNT; + + if (NULL == country_code) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Country code array is NULL")); + return VOS_STATUS_E_FAULT; + } + + if (0 == countryInfoTable.countryCount) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Reg domain table is empty") ); + return VOS_STATUS_E_EMPTY; + } + + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_STATUS_E_FAULT; + } + + if (pHddCtx->isLogpInProgress) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + (" SSR in progress, return") ); + *pRegDomain = temp_reg_domain; + return VOS_STATUS_SUCCESS; + } + + wiphy = pHddCtx->wiphy; + + if (false == wiphy->registered) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("wiphy is not yet registered with the kernel") ); + return VOS_STATUS_E_FAULT; + } + + temp_reg_domain = REGDOMAIN_COUNT; + /* lookup the country in the local database */ + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == temp_reg_domain; i++) + { + if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + /* country code is found */ + /* record the temporary regulatory_domain as well */ + temp_reg_domain = countryInfoTable.countryInfo[i].regDomain; + break; + } + } + + if (REGDOMAIN_COUNT == temp_reg_domain) { + + /* the country was not found in the driver database */ + /* so we will return the REGDOMAIN_WORLD to SME/CSR */ + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Country does not map to any Regulatory domain")); + + temp_reg_domain = REGDOMAIN_WORLD; + } + + if (COUNTRY_QUERY == source) { + *pRegDomain = temp_reg_domain; + return VOS_STATUS_SUCCESS; + } + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("regdomain request")); + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + (" get country information from kernel db")); + + if ((COUNTRY_INIT == source) && (VOS_FALSE == init_by_reg_core)) { + init_by_driver = VOS_TRUE; + + if (('0' != country_code[0]) || ('0' != country_code[1])) { + INIT_COMPLETION(pHddCtx->reg_init); + regulatory_hint(wiphy, country_code); + wait_for_completion_timeout(&pHddCtx->reg_init, + msecs_to_jiffies(REG_WAIT_TIME)); + } + + } else if (COUNTRY_IE == source || COUNTRY_USER == source) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS) + regulatory_hint_user(country_code, NL80211_USER_REG_HINT_USER); +#else + regulatory_hint_user(country_code); +#endif + } + + *pRegDomain = temp_reg_domain; + return VOS_STATUS_SUCCESS; +} + + +/* create_linux_regulatory_entry to populate internal structures from wiphy */ +static int create_linux_regulatory_entry(struct wiphy *wiphy, + v_U8_t nBandCapability) +{ + int i, j, m; + int k = 0, n = 0; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + int err; +#endif + const struct ieee80211_reg_rule *reg_rule; + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 0; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pVosContext pointer") ); + } + + /* 20MHz channels */ + if (nBandCapability == eCSR_BAND_24) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "BandCapability is set to 2G only"); + + for (i = 0, m = 0; ibands[i] == NULL) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "error: wiphy->bands is NULL, i = %d", i); + continue; + } + + /* internal channels[] is one continous array for both 2G and 5G bands + m is internal starting channel index for each band */ + + if (i == 0) + m = 0; + else + m = wiphy->bands[i-1]->n_channels + m; + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + /* k = (m + j) is internal current channel index for 20MHz channel + n is internal channel index for corresponding 40MHz channel */ + + k = m + j; + n = bw20_ch_index_to_bw40_ch_index(k); + + if (n == -1) + return -1; + + /* If the regulatory rules for a country do not explicilty + * require a passive scan on a frequency, lift the passive + * scan restriction + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + reg_rule = freq_reg_info(wiphy, + MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq)); +#else + err = freq_reg_info(wiphy, + MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq), + 0, ®_rule); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + if (!IS_ERR(reg_rule)) +#else + if (0 == err) +#endif + { + if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { + + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Remove passive scan restriction for %u", + __func__, wiphy->bands[i]->channels[j].center_freq); + wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Remove no ibss restriction for %u", + __func__, wiphy->bands[i]->channels[j].center_freq); + wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_NO_IBSS; + } + + wiphy->bands[i]->channels[j].max_power = + (int) MBM_TO_DBM(reg_rule->power_rule.max_eirp); + } + } + + if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED) + { + if (pnvEFSTable == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "error: pnvEFSTable is NULL, probably not parsed nv.bin yet"); + return -1; + } + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled = + NV_CHANNEL_DISABLE; + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + + /* nv cannot distinguish between DFS and passive channels */ + else if (wiphy->bands[i]->channels[j].flags & + (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN)) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled = + NV_CHANNEL_DFS; + + /* max_power is in mBm = 100 * dBm */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)); + + /* Disable the center channel if neither HT40+ nor HT40- is allowed + */ + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == + IEEE80211_CHAN_NO_HT40 ) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + else + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DFS; + + /* 40MHz channel power is half of 20MHz (-3dB) ?? */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3); + } + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0) + { + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 1; + } + } + } + else /* Enable is only last flag we support */ + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain]. + channels[k].enabled = NV_CHANNEL_ENABLE; + + /* max_power is in dBm */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)); + + /* Disable the center channel if neither HT40+ nor HT40- is allowed + */ + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == + IEEE80211_CHAN_NO_HT40 ) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + else + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_ENABLE; + /* 40MHz channel power is half of 20MHz (-3dB) */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3); + } + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0) + { + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 1; + } + } + + } + + /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain + is real gain which should be provided by the real design */ + } + } + +#ifdef FEATURE_WLAN_CH144 + /* Disable RF_CHAN_144 entry if FW does not support channel 144. */ + if (pHddCtx && + (0 == (pHddCtx->reg.eeprom_rd_ext & (1 << WHAL_REG_EXT_FCC_CH_144)))) { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain]. + channels[RF_CHAN_144].enabled = NV_CHANNEL_DISABLE; + } +#endif + + if (k == 0) + return -1; + + return 0; +} + +/* + * Function: wlan_hdd_linux_reg_notifier + * This function is called from cfg80211 core to provide regulatory settings + * after new country is requested or intersected (init, user input or 11d) + * This function is used to create a CRDA regulatory settings entry into internal + * regulatory setting table. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#else +int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#endif +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + eCsrBand nBandCapability = eCSR_BAND_ALL; + v_COUNTRYCODE_t country_code; + int i,j; + v_BOOL_t isVHT80Allowed; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "cfg80211 reg notifier callback for country for initiator %d", request->initiator); + + if (TRUE == isWDresetInProgress()) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("SSR is in progress") ); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + if (pHddCtx->isUnloadInProgress || + pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading or SSR in Progress, Ignore!!!", __func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + sme_GetFreqBand(pHddCtx->hHal, &nBandCapability); + + /* first check if this callback is in response to the driver callback */ + + switch (request->initiator) + { + case NL80211_REGDOM_SET_BY_DRIVER: + + if ( VOS_TRUE == init_by_driver) + { + isVHT80Allowed = pHddCtx->isVHT80Allowed; + if (create_linux_regulatory_entry(wiphy, nBandCapability) == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" regulatory entry created")); + } + if (pHddCtx->isVHT80Allowed != isVHT80Allowed) + { + hdd_checkandupdate_phymode( pHddCtx); + } + break; + } + + /* we purposely want to fall thru since the processing is same + as other 2 conditions */ + + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + + /* first lookup the country in the local database */ + country_code[0] = request->alpha2[0]; + country_code[1] = request->alpha2[1]; + + pHddCtx->reg.alpha2[0] = request->alpha2[0]; + pHddCtx->reg.alpha2[1] = request->alpha2[1]; + + if (NL80211_REGDOM_SET_BY_CORE == request->initiator) + pHddCtx->reg.cc_src = COUNTRY_CODE_SET_BY_CORE; + else if (NL80211_REGDOM_SET_BY_DRIVER == request->initiator) + pHddCtx->reg.cc_src = COUNTRY_CODE_SET_BY_DRIVER; + else pHddCtx->reg.cc_src = COUNTRY_CODE_SET_BY_USER; + + vos_update_reg_info(pHddCtx); + vos_reg_apply_world_flags(wiphy, request->initiator, &pHddCtx->reg); + + temp_reg_domain = REGDOMAIN_COUNT; + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == temp_reg_domain; i++) + { + if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + /* country code is found */ + /* record the temporary regulatory_domain as well */ + temp_reg_domain = countryInfoTable.countryInfo[i].regDomain; + break; + } + } + + if (REGDOMAIN_COUNT == temp_reg_domain) + temp_reg_domain = REGDOMAIN_WORLD; + + isVHT80Allowed = pHddCtx->isVHT80Allowed; + if (create_linux_regulatory_entry(wiphy, + nBandCapability) == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" regulatory entry created")); + + } + if (pHddCtx->isVHT80Allowed != isVHT80Allowed) + { + hdd_checkandupdate_phymode( pHddCtx); + } + + if (NL80211_REGDOM_SET_BY_DRIVER == request->initiator) + complete(&pHddCtx->reg_init); + + + /* now pass the new country information to sme */ + if (request->alpha2[0] == '0' && request->alpha2[1] == '0') + { + sme_GenericChangeCountryCode(pHddCtx->hHal, country_code, + REGDOMAIN_COUNT); + } + else + { + sme_GenericChangeCountryCode(pHddCtx->hHal, country_code, + temp_reg_domain); + } + + if ((VOS_FALSE == init_by_driver) && + (request->initiator != NL80211_REGDOM_SET_BY_CORE)) + init_by_reg_core = VOS_TRUE; + + + /* send CTL info to firmware */ + regdmn_set_regval(&pHddCtx->reg); + default: + break; + } + + /* Mark channels 36-48 as passive for US CC */ + + if ((request->initiator == NL80211_REGDOM_SET_BY_DRIVER) || + (request->initiator == NL80211_REGDOM_SET_BY_CORE) || + (request->initiator == NL80211_REGDOM_SET_BY_USER)) + { + if (pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC && + wiphy->bands[IEEE80211_BAND_5GHZ]) + { + for (j=0; jbands[IEEE80211_BAND_5GHZ]->n_channels; j++) + { + // UNII-1 band channels are passive when domain is FCC. + if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) && + (request->alpha2[0]== 'U' && request->alpha2[1]=='S')) + { + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + } + } + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif +} + +/* initialize wiphy from EEPROM */ +VOS_STATUS vos_init_wiphy_from_eeprom(void) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (!pVosContext) + return VOS_STATUS_E_EXISTS; + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer")); + return VOS_STATUS_E_FAULT; + } + + wiphy = pHddCtx->wiphy; + + if (reg_init_from_eeprom(pHddCtx, &pHddCtx->reg, wiphy)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Error during regulatory init from EEPROM")); + return VOS_STATUS_E_FAULT; + } + + if (is_world_regd(pHddCtx->reg.reg_domain)) { + temp_reg_domain = REGDOMAIN_WORLD; + if (create_linux_regulatory_entry(wiphy, + pHddCtx->cfg_ini->nBandCapability) != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Error while creating regulatory entry")); + return VOS_STATUS_E_FAULT; + } + } + + init_completion(&pHddCtx->reg_init); + + /* send CTL info to firmware */ + regdmn_set_regval(&pHddCtx->reg); + + return VOS_STATUS_SUCCESS; +} + +/* initialize wiphy from NV.bin */ +VOS_STATUS vos_init_wiphy_from_nv_bin(void) +{ + int i, j, m; + int k = 0; + v_REGDOMAIN_t reg_domain; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_STATUS_E_FAULT; + } + + wiphy = pHddCtx->wiphy; + + /* Update regulatory structure in HDD */ + pHddCtx->reg.alpha2[0] = + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0]; + pHddCtx->reg.alpha2[1] = + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1]; + pHddCtx->reg.cc_src = COUNTRY_CODE_SET_BY_DRIVER; + + vos_update_reg_info(pHddCtx); + + if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0]) + && + ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1])) + { + /* default country is world roaming */ + + reg_domain = REGDOMAIN_WORLD; + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + } + else if (REGDOMAIN_WORLD == + pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) { + + reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain; + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + } + else { + + reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain; + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; + } + m = 0; + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (wiphy->bands[i] == NULL) + { + pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i); + continue; + } + + /* internal channels[] is one continous array for both 2G and 5G bands + m is internal starting channel index for each band */ + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + /* k = (m + j) is internal current channel index */ + k = m + j; + + if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_DISABLE) + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + + else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_DFS) { + + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + wiphy->bands[i]->channels[j].max_power = + (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100; + } + + else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_ENABLE) { + + wiphy->bands[i]->channels[j].max_power = + (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit)*100; + } + } + + m += wiphy->bands[i]->n_channels; + } + + return VOS_STATUS_SUCCESS; +} + diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_packet.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_packet.c new file mode 100644 index 0000000000000..ec4c17b39ee93 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_packet.c @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_packet.c + + \brief virtual Operating System Services (vOSS) network Packet APIs + + Network Protocol packet/buffer support interfaces + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "adf_nbuf.h" +#include "vos_memory.h" +#include "adf_os_mem.h" + +#ifdef QCA_PKT_PROTO_TRACE +/* Protocol specific packet tracking feature */ +#define VOS_PKT_TRAC_ETH_TYPE_OFFSET 12 +#define VOS_PKT_TRAC_IP_OFFSET 14 +#define VOS_PKT_TRAC_IP_HEADER_SIZE 20 +#define VOS_PKT_TRAC_DHCP_SRV_PORT 67 +#define VOS_PKT_TRAC_DHCP_CLI_PORT 68 +#define VOS_PKT_TRAC_EAPOL_ETH_TYPE 0x888E +#define VOS_PKT_TRAC_MAX_STRING_LEN 12 +#define VOS_PKT_TRAC_MAX_TRACE_BUF 50 +#define VOS_PKT_TRAC_MAX_STRING_BUF 64 + +/* protocol Storage Structure */ +typedef struct +{ + v_U32_t order; + v_TIME_t event_time; + char event_string[VOS_PKT_TRAC_MAX_STRING_LEN]; +} vos_pkt_proto_trace_t; + +vos_pkt_proto_trace_t *trace_buffer = NULL; +unsigned int trace_buffer_order = 0; +vos_spin_lock_t trace_buffer_lock; +#endif /* QCA_PKT_PROTO_TRACE */ + +/** + * vos_pkt_return_packet Free the voss Packet + * @ vos Packet + */ +VOS_STATUS vos_pkt_return_packet(vos_pkt_t *packet) +{ + // Validate the input parameter pointer + if (unlikely(packet == NULL)) { + return VOS_STATUS_E_INVAL; + } + + /* Free up the Adf nbuf */ + adf_nbuf_free(packet->pkt_buf); + + packet->pkt_buf = NULL; + + /* Free up the Rx packet */ + vos_mem_free(packet); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet + + This API returns the total length of the data in a voss Packet. + + \param pPacket - the voss Packet to get the packet length from. + + \param pPacketSize - location to return the total size of the data contained + in the voss Packet. + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket, + v_U16_t *pPacketSize ) +{ + // Validate the parameter pointers + if (unlikely((pPacket == NULL) || (pPacketSize == NULL)) || + (pPacket->pkt_buf == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // return the requested information + *pPacketSize = adf_nbuf_len(pPacket->pkt_buf); + return VOS_STATUS_SUCCESS; +} + +/* + * TODO: Remove below later since all the below + * definitions are not required for Host + * driver 2.0 (still references from HDD and + * other layers are yet to be removed) + */ +VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE pktType, + v_SIZE_t *vosFreeBuffer) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket, + v_VOID_t **ppOSPacket, + v_BOOL_t clearOSPacket ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_VOID_t *pOSPacket, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket, + v_VOID_t *pOSPacket ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket, + v_TIME_t* pTstamp ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket, + vos_pkt_t **ppChainedPacket, + v_BOOL_t unchainPacket ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t **ppPacketData, + v_SIZE_t numBytes ) +{ + return VOS_STATUS_SUCCESS; +} +VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_SIZE_t dataSize, + v_SIZE_t numPackets, + v_BOOL_t zeroBuffer, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + return VOS_STATUS_SUCCESS; +} + +v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t *pUserData ) +{ + return; +} + +v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t **ppUserData ) +{ + return; +} + +VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t *pOutputBuffer, + v_SIZE_t *pOutputBufferSize ) +{ + return VOS_STATUS_SUCCESS; +} + +#ifdef QCA_PKT_PROTO_TRACE +/*--------------------------------------------------------------------------- + + * brief vos_pkt_get_proto_type() - + Find protoco type from packet contents + + * skb Packet Pointer + * tracking_map packet type want to track + * dot11_type, type of dot11 frame + +---------------------------------------------------------------------------*/ +v_U8_t vos_pkt_get_proto_type +( + struct sk_buff *skb, + v_U8_t tracking_map, + v_U8_t dot11_type +) +{ + v_U8_t pkt_proto_type = 0; + v_U16_t ether_type; + v_U16_t SPort; + v_U16_t DPort; + + if (dot11_type) + { + if (dot11_type == (VOS_PKT_TRAC_TYPE_MGMT_ACTION & tracking_map)) + pkt_proto_type |= VOS_PKT_TRAC_TYPE_MGMT_ACTION; + + /* Protocol type map */ + return pkt_proto_type; + } + + /* EAPOL Tracking enabled */ + if (VOS_PKT_TRAC_TYPE_EAPOL & tracking_map) + { + ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_TRAC_ETH_TYPE_OFFSET)); + if (VOS_PKT_TRAC_EAPOL_ETH_TYPE == VOS_SWAP_U16(ether_type)) + { + pkt_proto_type |= VOS_PKT_TRAC_TYPE_EAPOL; + } + } + + /* DHCP Tracking enabled */ + if (VOS_PKT_TRAC_TYPE_DHCP & tracking_map) + { + SPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_TRAC_IP_OFFSET + + VOS_PKT_TRAC_IP_HEADER_SIZE)); + DPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_TRAC_IP_OFFSET + + VOS_PKT_TRAC_IP_HEADER_SIZE + sizeof(v_U16_t))); + if (((VOS_PKT_TRAC_DHCP_SRV_PORT == VOS_SWAP_U16(SPort)) && + (VOS_PKT_TRAC_DHCP_CLI_PORT == VOS_SWAP_U16(DPort))) || + ((VOS_PKT_TRAC_DHCP_CLI_PORT == VOS_SWAP_U16(SPort)) && + (VOS_PKT_TRAC_DHCP_SRV_PORT == VOS_SWAP_U16(DPort)))) + { + pkt_proto_type |= VOS_PKT_TRAC_TYPE_DHCP; + } + } + + /* Protocol type map */ + return pkt_proto_type; +} + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_trace_buf_update() - + Update storage buffer with interest event string + + * event_string Event String may packet type or outstanding event + +---------------------------------------------------------------------------*/ +void vos_pkt_trace_buf_update +( + char *event_string +) +{ + v_U32_t slot; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s %d, %s", __func__, __LINE__, event_string); + vos_spin_lock_acquire(&trace_buffer_lock); + slot = trace_buffer_order % VOS_PKT_TRAC_MAX_TRACE_BUF; + trace_buffer[slot].order = trace_buffer_order; + trace_buffer[slot].event_time = vos_timer_get_system_time(); + vos_mem_zero(trace_buffer[slot].event_string, + sizeof(trace_buffer[slot].event_string)); + vos_mem_copy(trace_buffer[slot].event_string, + event_string, + (VOS_PKT_TRAC_MAX_STRING_LEN < strlen(event_string))? + VOS_PKT_TRAC_MAX_STRING_LEN:strlen(event_string)); + trace_buffer_order++; + vos_spin_lock_release(&trace_buffer_lock); + + return; +} + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_trace_buf_dump() - + Dump stored information into kernel log + +---------------------------------------------------------------------------*/ +void vos_pkt_trace_buf_dump +( + void +) +{ + v_U32_t slot, idx; + + vos_spin_lock_acquire(&trace_buffer_lock); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "PACKET TRACE DUMP START Current Timestamp %u", + (unsigned int)vos_timer_get_system_time()); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "ORDER : TIME : EVT"); + if (VOS_PKT_TRAC_MAX_TRACE_BUF > trace_buffer_order) + { + for (slot = 0 ; slot < trace_buffer_order; slot++) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%5d :%12u : %s", + trace_buffer[slot].order, + (unsigned int)trace_buffer[slot].event_time, + trace_buffer[slot].event_string); + } + } + else + { + for (idx = 0 ; idx < VOS_PKT_TRAC_MAX_TRACE_BUF; idx++) + { + slot = (trace_buffer_order + idx) % VOS_PKT_TRAC_MAX_TRACE_BUF; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%5d :%12u : %s", + trace_buffer[slot].order, + (unsigned int)trace_buffer[slot].event_time, + trace_buffer[slot].event_string); + } + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "PACKET TRACE DUMP END"); + vos_spin_lock_release(&trace_buffer_lock); + + return; +} + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_proto_trace_init() - + Initialize protocol trace functionality, allocate required resource + +---------------------------------------------------------------------------*/ +void vos_pkt_proto_trace_init +( + void +) +{ + /* Init spin lock to protect global memory */ + vos_spin_lock_init(&trace_buffer_lock); + trace_buffer_order = 0; + trace_buffer = vos_mem_malloc( + VOS_PKT_TRAC_MAX_TRACE_BUF * sizeof(vos_pkt_proto_trace_t)); + vos_mem_zero((void *)trace_buffer, + VOS_PKT_TRAC_MAX_TRACE_BUF * sizeof(vos_pkt_proto_trace_t)); + + /* Register callback function to NBUF + * Lower layer event also will be reported to here */ + adf_nbuf_reg_trace_cb(vos_pkt_trace_buf_update); + return; +} + +/*--------------------------------------------------------------------------- + + * brief vos_pkt_proto_trace_close() - + Free required resource + +---------------------------------------------------------------------------*/ +void vos_pkt_proto_trace_close +( + void +) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s %d", __func__, __LINE__); + vos_mem_free(trace_buffer); + vos_spin_lock_destroy(&trace_buffer_lock); + + return; +} +#endif /* QCA_PKT_PROTO_TRACE */ diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.c new file mode 100644 index 0000000000000..401c6e2ab36a9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.c @@ -0,0 +1,2529 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file vos_sched.c + @brief VOS Scheduler Implementation +===========================================================================*/ +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- -------------------------------------------------------- +===========================================================================*/ +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vos_sched.h" +#include +#include "wlan_qct_wda.h" +#include "wlan_qct_pal_msg.h" +#include +#include +#include +#if defined(QCA_CONFIG_SMP) && defined(CONFIG_CNSS) +#include +#endif +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ +#define VOS_SCHED_THREAD_HEART_BEAT INFINITE +/* Milli seconds to delay SSR thread when an Entry point is Active */ +#define SSR_WAIT_SLEEP_TIME 200 +/* MAX iteration count to wait for Entry point to exit before + * we proceed with SSR in WD Thread + */ +#define MAX_SSR_WAIT_ITERATIONS 100 +#define MAX_SSR_PROTECT_LOG (16) + +static atomic_t ssr_protect_entry_count; + +struct ssr_protect { + const char* func; + bool free; + uint32_t pid; +}; + +static spinlock_t ssr_protect_lock; +static struct ssr_protect ssr_protect_log[MAX_SSR_PROTECT_LOG]; + +/*--------------------------------------------------------------------------- + * Type Declarations + * ------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ +static pVosSchedContext gpVosSchedContext; +static pVosWatchdogContext gpVosWatchdogContext; + +/*--------------------------------------------------------------------------- + * Forward declaration + * ------------------------------------------------------------------------*/ +static int VosMCThread(void *Arg); +static int VosWDThread(void *Arg); +static int VosTXThread(void *Arg); +static int VosRXThread(void *Arg); +#ifdef QCA_CONFIG_SMP +static int VosTlshimRxThread(void *arg); +static unsigned long affine_cpu = 0; +static VOS_STATUS vos_alloc_tlshim_pkt_freeq(pVosSchedContext pSchedContext); +#endif +void vos_sched_flush_rx_mqs(pVosSchedContext SchedContext); +extern v_VOID_t vos_core_return_msg(v_PVOID_t pVContext, pVosMsgWrapper pMsgWrapper); + + +#ifdef QCA_CONFIG_SMP +#define VOS_CORE_PER_CLUSTER 4 + +static int vos_set_cpus_allowed_ptr(struct task_struct *task, + unsigned long cpu) +{ +#ifdef WLAN_OPEN_SOURCE + return set_cpus_allowed_ptr(task, cpumask_of(cpu)); +#elif defined(CONFIG_CNSS) + return cnss_set_cpus_allowed_ptr(task, cpu); +#else + return 0; +#endif +} + +/** + * vos_sched_all_litl_cpu_mask - get cpu mask for all little cores + * @litl_mask: little core cpu mask pointer + * + * When RX thread should attach to little core, + * PERF mode + * low throughput required + * RX thread affinity should be any little cores. cpu mask also should + * any little core cpus. + * Will give all little core cpu mask for little core affinity + * + * Return: None + */ +void vos_sched_all_litl_cpu_mask(struct cpumask *litl_mask) +{ + unsigned char litl_core_count = 0; + cpumask_clear(litl_mask); + for (litl_core_count = 0; + litl_core_count < VOS_CORE_PER_CLUSTER; + litl_core_count++) { + cpumask_set_cpu(litl_core_count, litl_mask); + } + + return; +} + +/** + * vos_sched_find_attach_cpu - find available cores and attach to required core + * @pSchedContext: wlan scheduler context + * @high_throughput: high throughput is required or not + * + * Find current online cores. + * high troughput required and PERF core online, then attach to last PERF core + * low throughput required or only little cores online, the attach any little + * core + * + * Return: 0 success + * 1 fail + */ +static int vos_sched_find_attach_cpu(pVosSchedContext pSchedContext, + bool high_throughput) +{ + unsigned long *online_perf_cpu = NULL; + unsigned long *online_litl_cpu = NULL; + unsigned long cpus; + unsigned char perf_core_count = 0; + unsigned char litl_core_count = 0; +#ifdef WLAN_OPEN_SOURCE + struct cpumask litl_mask; +#endif + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_LOW, + "%s: num possible cpu %d", + __func__, num_possible_cpus()); + + /* Single cluster system, not need to handle this */ + if (num_possible_cpus() < VOS_CORE_PER_CLUSTER) + return 0; + + online_perf_cpu = vos_mem_malloc( + num_possible_cpus() * sizeof(unsigned long)); + if (!online_perf_cpu) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: perf cpu cache alloc fail", __func__); + return 1; + } + vos_mem_zero(online_perf_cpu, + num_possible_cpus() * sizeof(unsigned long)); + + online_litl_cpu = vos_mem_malloc( + num_possible_cpus() * sizeof(unsigned long)); + if (!online_litl_cpu) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: lttl cpu cache alloc fail", __func__); + vos_mem_free(online_perf_cpu); + return 1; + } + vos_mem_zero(online_litl_cpu, + num_possible_cpus() * sizeof(unsigned long)); + + /* Get Online perf CPU count */ + for_each_online_cpu(cpus) { + if (cpus >= VOS_CORE_PER_CLUSTER) { + online_perf_cpu[perf_core_count] = cpus; + perf_core_count++; + } else { + online_litl_cpu[litl_core_count] = cpus; + litl_core_count++; + } + } + + if ((!litl_core_count) && (!perf_core_count)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Both Cluster off, do nothing", __func__); + vos_mem_free(online_perf_cpu); + vos_mem_free(online_litl_cpu); + return 0; + } + + if ((high_throughput && perf_core_count) || (!litl_core_count)) { + /* Attach RX thread to PERF CPU */ + if (pSchedContext->rx_thread_cpu != + online_perf_cpu[perf_core_count - 1]) { + if (vos_set_cpus_allowed_ptr( + pSchedContext->TlshimRxThread, + online_perf_cpu[perf_core_count - 1])) { + VOS_TRACE(VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_ERROR, + "%s: rx thread perf core set fail", + __func__); + vos_mem_free(online_perf_cpu); + vos_mem_free(online_litl_cpu); + return 1; + } + pSchedContext->rx_thread_cpu = + online_perf_cpu[perf_core_count - 1]; + } + } else { +#ifdef WLAN_OPEN_SOURCE + /* Attach to any little core + * Final decision should made by scheduler */ + vos_sched_all_litl_cpu_mask(&litl_mask); + set_cpus_allowed_ptr(pSchedContext->TlshimRxThread, &litl_mask); + pSchedContext->rx_thread_cpu = 0; +#else + /* Attach RX thread to last little core CPU */ + if (pSchedContext->rx_thread_cpu != + online_litl_cpu[litl_core_count - 1]) { + if (vos_set_cpus_allowed_ptr( + pSchedContext->TlshimRxThread, + online_litl_cpu[litl_core_count - 1])) { + VOS_TRACE(VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_ERROR, + "%s: rx thread litl core set fail", + __func__); + vos_mem_free(online_perf_cpu); + vos_mem_free(online_litl_cpu); + return 1; + } + pSchedContext->rx_thread_cpu = + online_litl_cpu[litl_core_count - 1]; + } +#endif /* WLAN_OPEN_SOURCE */ + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_LOW, + "%s: NUM PERF CORE %d, HIGH TPUTR REQ %d, RX THRE CPU %lu", + __func__, perf_core_count, + (int)pSchedContext->high_throughput_required, + pSchedContext->rx_thread_cpu); + + vos_mem_free(online_perf_cpu); + vos_mem_free(online_litl_cpu); + return 0; +} + +/** + * vos_sched_handle_cpu_hot_plug - cpu hotplug event handler + * + * cpu hotplug indication handler + * will find online cores and will assign proper core based on perf requirement + * + * Return: 0 success + * 1 fail + */ +int vos_sched_handle_cpu_hot_plug(void) +{ + pVosSchedContext pSchedContext = get_vos_sched_ctxt(); + + if (!pSchedContext) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return 1; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL) || + (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL))) + return 0; + + vos_lock_acquire(&pSchedContext->affinity_lock); + if (vos_sched_find_attach_cpu(pSchedContext, + pSchedContext->high_throughput_required)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: handle hot plug fail", __func__); + vos_lock_release(&pSchedContext->affinity_lock); + return 1; + } + vos_lock_release(&pSchedContext->affinity_lock); + return 0; +} + +/** + * vos_sched_handle_throughput_req - cpu throughput requirement handler + * @high_tput_required: high throughput is required or not + * + * high or low throughput indication ahndler + * will find online cores and will assign proper core based on perf requirement + * + * Return: 0 success + * 1 fail + */ +int vos_sched_handle_throughput_req(bool high_tput_required) +{ + pVosSchedContext pSchedContext = get_vos_sched_ctxt(); + + if (!pSchedContext) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return 1; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL) || + (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL))) + return 0; + + vos_lock_acquire(&pSchedContext->affinity_lock); + pSchedContext->high_throughput_required = high_tput_required; + if (vos_sched_find_attach_cpu(pSchedContext, high_tput_required)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: handle throughput req fail", __func__); + vos_lock_release(&pSchedContext->affinity_lock); + return 1; + } + vos_lock_release(&pSchedContext->affinity_lock); + return 0; +} + +/** + * __vos_cpu_hotplug_notify - cpu core on-off notification handler + * @block: notifier block + * @state: state of core + * @hcpu: target cpu core + * + * pre-registered core status change notify callback function + * will handle only ONLINE, OFFLINE notification + * based on cpu architecture, rx thread affinity will be different + * + * Return: 0 success + * 1 fail + */ +static int __vos_cpu_hotplug_notify(struct notifier_block *block, + unsigned long state, void *hcpu) +{ + unsigned long cpu = (unsigned long) hcpu; + unsigned long pref_cpu = 0; + pVosSchedContext pSchedContext = get_vos_sched_ctxt(); + int i; + unsigned int multi_cluster; + unsigned int num_cpus; + + if ((NULL == pSchedContext) || (NULL == pSchedContext->TlshimRxThread)) + return NOTIFY_OK; + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL) || + (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL))) + return NOTIFY_OK; + + num_cpus = num_possible_cpus(); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_LOW, + "%s: RX CORE %d, STATE %d, NUM CPUS %d", + __func__, (int)affine_cpu, (int)state, num_cpus); + multi_cluster = (num_cpus > VOS_CORE_PER_CLUSTER)?1:0; + if ((multi_cluster) && + ((CPU_ONLINE == state) || (CPU_DEAD == state))) { + vos_sched_handle_cpu_hot_plug(); + return NOTIFY_OK; + } + + switch (state) { + case CPU_ONLINE: + if (affine_cpu != 0) + return NOTIFY_OK; + + for_each_online_cpu(i) { + if (i == 0) + continue; + pref_cpu = i; + break; + } + break; + case CPU_DEAD: + if (cpu != affine_cpu) + return NOTIFY_OK; + + affine_cpu = 0; + for_each_online_cpu(i) { + if (i == 0) + continue; + pref_cpu = i; + break; + } + } + + if (pref_cpu == 0) + return NOTIFY_OK; + + if (!vos_set_cpus_allowed_ptr(pSchedContext->TlshimRxThread, pref_cpu)) + affine_cpu = pref_cpu; + + return NOTIFY_OK; +} + +/** + * vos_cpu_hotplug_notify - cpu core on-off notification handler wrapper + * @block: notifier block + * @state: state of core + * @hcpu: target cpu core + * + * pre-registered core status change notify callback function + * will handle only ONLINE, OFFLINE notification + * based on cpu architecture, rx thread affinity will be different + * wrapper function + * + * Return: 0 success + * 1 fail + */ +static int vos_cpu_hotplug_notify(struct notifier_block *block, + unsigned long state, void *hcpu) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __vos_cpu_hotplug_notify(block, state, hcpu); + vos_ssr_unprotect(__func__); + + return ret; +} + +static struct notifier_block vos_cpu_hotplug_notifier = { + .notifier_call = vos_cpu_hotplug_notify, +}; +#endif + +/*--------------------------------------------------------------------------- + * External Function implementation + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + \brief vos_sched_open() - initialize the vOSS Scheduler + The \a vos_sched_open() function initializes the vOSS Scheduler + Upon successful initialization: + - All the message queues are initialized + - The Main Controller thread is created and ready to receive and + dispatch messages. + - The Tx thread is created and ready to receive and dispatch messages + + \param pVosContext - pointer to the global vOSS Context + \param pVosSchedContext - pointer to a previously allocated buffer big + enough to hold a scheduler context. + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the scheduler + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + \sa vos_sched_open() + -------------------------------------------------------------------------*/ +VOS_STATUS +vos_sched_open +( + v_PVOID_t pVosContext, + pVosSchedContext pSchedContext, + v_SIZE_t SchedCtxSize +) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; +/*-------------------------------------------------------------------------*/ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening the VOSS Scheduler",__func__); + // Sanity checks + if ((pVosContext == NULL) || (pSchedContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + return VOS_STATUS_E_FAILURE; + } + if (sizeof(VosSchedContext) != SchedCtxSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Incorrect VOS Sched Context size passed",__func__); + return VOS_STATUS_E_INVAL; + } + vos_mem_zero(pSchedContext, sizeof(VosSchedContext)); + pSchedContext->pVContext = pVosContext; + vStatus = vos_sched_init_mqs(pSchedContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize VOS Scheduler MQs",__func__); + return vStatus; + } + // Initialize the helper events and event queues + init_completion(&pSchedContext->McStartEvent); + init_completion(&pSchedContext->TxStartEvent); + init_completion(&pSchedContext->RxStartEvent); + init_completion(&pSchedContext->McShutdown); + init_completion(&pSchedContext->TxShutdown); + init_completion(&pSchedContext->RxShutdown); + init_completion(&pSchedContext->ResumeMcEvent); + init_completion(&pSchedContext->ResumeTxEvent); + init_completion(&pSchedContext->ResumeRxEvent); + + spin_lock_init(&pSchedContext->McThreadLock); + spin_lock_init(&pSchedContext->TxThreadLock); + spin_lock_init(&pSchedContext->RxThreadLock); +#ifdef QCA_CONFIG_SMP + spin_lock_init(&pSchedContext->TlshimRxThreadLock); +#endif + + init_waitqueue_head(&pSchedContext->mcWaitQueue); + pSchedContext->mcEventFlag = 0; + init_waitqueue_head(&pSchedContext->txWaitQueue); + pSchedContext->txEventFlag= 0; + init_waitqueue_head(&pSchedContext->rxWaitQueue); + pSchedContext->rxEventFlag= 0; + +#ifdef QCA_CONFIG_SMP + init_waitqueue_head(&pSchedContext->tlshimRxWaitQueue); + init_completion(&pSchedContext->TlshimRxStartEvent); + init_completion(&pSchedContext->SuspndTlshimRxEvent); + init_completion(&pSchedContext->ResumeTlshimRxEvent); + init_completion(&pSchedContext->TlshimRxShutdown); + pSchedContext->tlshimRxEvtFlg = 0; + spin_lock_init(&pSchedContext->TlshimRxQLock); + spin_lock_init(&pSchedContext->VosTlshimPktFreeQLock); + INIT_LIST_HEAD(&pSchedContext->tlshimRxQueue); + spin_lock_bh(&pSchedContext->VosTlshimPktFreeQLock); + INIT_LIST_HEAD(&pSchedContext->VosTlshimPktFreeQ); + if (vos_alloc_tlshim_pkt_freeq(pSchedContext) != VOS_STATUS_SUCCESS) + { + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); + return VOS_STATUS_E_FAILURE; + } + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); + register_hotcpu_notifier(&vos_cpu_hotplug_notifier); + pSchedContext->cpuHotPlugNotifier = &vos_cpu_hotplug_notifier; + vos_lock_init(&pSchedContext->affinity_lock); + pSchedContext->high_throughput_required = false; +#endif + + + /* + ** This initialization is critical as the threads will later access the + ** global contexts normally, + ** + ** I shall put some memory barrier here after the next piece of code but + ** I am keeping it simple for now. + */ + gpVosSchedContext = pSchedContext; + + //Create the VOSS Main Controller thread + pSchedContext->McThread = kthread_create(VosMCThread, pSchedContext, + "VosMCThread"); + if (IS_ERR(pSchedContext->McThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS Main Thread Controller",__func__); + goto MC_THREAD_START_FAILURE; + } + wake_up_process(pSchedContext->McThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Main Controller thread Created",__func__); + + pSchedContext->TxThread = kthread_create(VosTXThread, pSchedContext, + "VosTXThread"); + if (IS_ERR(pSchedContext->TxThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS TX Thread",__func__); + goto TX_THREAD_START_FAILURE; + } + wake_up_process(pSchedContext->TxThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + ("VOSS TX thread Created")); + + pSchedContext->RxThread = kthread_create(VosRXThread, pSchedContext, + "VosRXThread"); + if (IS_ERR(pSchedContext->RxThread)) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS RX Thread",__func__); + goto RX_THREAD_START_FAILURE; + + } + wake_up_process(pSchedContext->RxThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + ("VOSS RX thread Created")); + +#ifdef QCA_CONFIG_SMP + pSchedContext->TlshimRxThread = kthread_create(VosTlshimRxThread, + pSchedContext, + "VosTlshimRxThread"); + if (IS_ERR(pSchedContext->TlshimRxThread)) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS Tlshim RX Thread", __func__); + goto TLSHIM_RX_THREAD_START_FAILURE; + + } + wake_up_process(pSchedContext->TlshimRxThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + ("VOSS Tlshim RX thread Created")); +#endif + /* + ** Now make sure all threads have started before we exit. + ** Each thread should normally ACK back when it starts. + */ + wait_for_completion_interruptible(&pSchedContext->McStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS MC Thread has started",__func__); + wait_for_completion_interruptible(&pSchedContext->TxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Tx Thread has started",__func__); + wait_for_completion_interruptible(&pSchedContext->RxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Rx Thread has started",__func__); +#ifdef QCA_CONFIG_SMP + wait_for_completion_interruptible(&pSchedContext->TlshimRxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Tlshim Rx Thread has started", __func__); +#endif + /* + ** We're good now: Let's get the ball rolling!!! + */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Scheduler successfully Opened",__func__); + return VOS_STATUS_SUCCESS; + + +#ifdef QCA_CONFIG_SMP +TLSHIM_RX_THREAD_START_FAILURE: + //Try and force the Rx thread controller to exit + set_bit(RX_SHUTDOWN_EVENT_MASK, &pSchedContext->rxEventFlag); + set_bit(RX_POST_EVENT_MASK, &pSchedContext->rxEventFlag); + wake_up_interruptible(&pSchedContext->rxWaitQueue); + //Wait for RX to exit + wait_for_completion_interruptible(&pSchedContext->RxShutdown); +#endif +RX_THREAD_START_FAILURE: + //Try and force the Tx thread controller to exit + set_bit(MC_SHUTDOWN_EVENT_MASK, &pSchedContext->txEventFlag); + set_bit(MC_POST_EVENT_MASK, &pSchedContext->txEventFlag); + wake_up_interruptible(&pSchedContext->txWaitQueue); + //Wait for TX to exit + wait_for_completion_interruptible(&pSchedContext->TxShutdown); + +TX_THREAD_START_FAILURE: + //Try and force the Main thread controller to exit + set_bit(MC_SHUTDOWN_EVENT_MASK, &pSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT_MASK, &pSchedContext->mcEventFlag); + wake_up_interruptible(&pSchedContext->mcWaitQueue); + //Wait for MC to exit + wait_for_completion_interruptible(&pSchedContext->McShutdown); + +MC_THREAD_START_FAILURE: + //De-initialize all the message queues + vos_sched_deinit_mqs(pSchedContext); + + +#ifdef QCA_CONFIG_SMP + unregister_hotcpu_notifier(&vos_cpu_hotplug_notifier); + vos_free_tlshim_pkt_freeq(gpVosSchedContext); +#endif + + return VOS_STATUS_E_RESOURCES; + +} /* vos_sched_open() */ + +VOS_STATUS vos_watchdog_open +( + v_PVOID_t pVosContext, + pVosWatchdogContext pWdContext, + v_SIZE_t wdCtxSize +) +{ +/*-------------------------------------------------------------------------*/ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening the VOSS Watchdog module",__func__); + //Sanity checks + if ((pVosContext == NULL) || (pWdContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + return VOS_STATUS_E_FAILURE; + } + if (sizeof(VosWatchdogContext) != wdCtxSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Incorrect VOS Watchdog Context size passed",__func__); + return VOS_STATUS_E_INVAL; + } + vos_mem_zero(pWdContext, sizeof(VosWatchdogContext)); + pWdContext->pVContext = pVosContext; + gpVosWatchdogContext = pWdContext; + + //Initialize the helper events and event queues + init_completion(&pWdContext->WdStartEvent); + init_completion(&pWdContext->WdShutdown); + init_waitqueue_head(&pWdContext->wdWaitQueue); + pWdContext->wdEventFlag = 0; + + // Initialize the lock + spin_lock_init(&pWdContext->wdLock); + + //Create the Watchdog thread + pWdContext->WdThread = kthread_create(VosWDThread, pWdContext,"VosWDThread"); + + if (IS_ERR(pWdContext->WdThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create Watchdog thread",__func__); + return VOS_STATUS_E_RESOURCES; + } + else + { + wake_up_process(pWdContext->WdThread); + } + /* + ** Now make sure thread has started before we exit. + ** Each thread should normally ACK back when it starts. + */ + wait_for_completion_interruptible(&pWdContext->WdStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Watchdog Thread has started",__func__); + return VOS_STATUS_SUCCESS; +} /* vos_watchdog_open() */ +/*--------------------------------------------------------------------------- + \brief VosMcThread() - The VOSS Main Controller thread + The \a VosMcThread() is the VOSS main controller thread: + \param Arg - pointer to the global vOSS Sched Context + \return Thread exit code + \sa VosMcThread() + -------------------------------------------------------------------------*/ +static int +VosMCThread +( + void * Arg +) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + tpAniSirGlobal pMacContext = NULL; + tSirRetStatus macStatus = eSIR_SUCCESS; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + set_user_nice(current, -2); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("MC_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->McStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MC Thread %d (%s) starting up",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->mcWaitQueue, + test_bit(MC_POST_EVENT_MASK, &pSchedContext->mcEventFlag) || + test_bit(MC_SUSPEND_EVENT_MASK, &pSchedContext->mcEventFlag)); + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(MC_POST_EVENT_MASK, &pSchedContext->mcEventFlag); + + while(1) + { + // Check if MC needs to shutdown + if(test_bit(MC_SHUTDOWN_EVENT_MASK, &pSchedContext->mcEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MC thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if(test_bit(MC_SUSPEND_EVENT_MASK, &pSchedContext->mcEventFlag)) + { + clear_bit(MC_SUSPEND_EVENT_MASK, &pSchedContext->mcEventFlag); + + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->mc_sus_event_var); + } + break; + } + + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysMcMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysMcProcessMsg(pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing SYS message",__func__); + } + //return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check the WDA queue + if (!vos_is_mq_empty(&pSchedContext->wdaMcMq)) + { + // Service the WDA message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS WDA MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->wdaMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WDA_McProcessMsg( pSchedContext->pVContext, pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing WDA message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check the PE queue + if (!vos_is_mq_empty(&pSchedContext->peMcMq)) + { + // Service the PE message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS PE MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->peMcMq); + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + + /* Need some optimization*/ + pMacContext = vos_get_context(VOS_MODULE_ID_PE, pSchedContext->pVContext); + if (NULL == pMacContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "MAC Context not ready yet"); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + macStatus = peProcessMessages( pMacContext, (tSirMsgQ*)pMsgWrapper->pVosMsg); + if (eSIR_SUCCESS != macStatus) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing PE message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /** Check the SME queue **/ + if (!vos_is_mq_empty(&pSchedContext->smeMcMq)) + { + /* Service the SME message queue */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SME MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->smeMcMq); + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + + /* Need some optimization*/ + pMacContext = vos_get_context(VOS_MODULE_ID_SME, pSchedContext->pVContext); + if (NULL == pMacContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "MAC Context not ready yet"); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + vStatus = sme_ProcessMsg( (tHalHandle)pMacContext, pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing SME message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /** Check the TL queue **/ + if (!vos_is_mq_empty(&pSchedContext->tlMcMq)) + { + // Service the TL message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("Servicing the VOS TL MC Message queue")); + pMsgWrapper = vos_mq_get(&pSchedContext->tlMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WLANTL_McProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TL message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /* Check for any Suspend Indication */ + if(test_bit(MC_SUSPEND_EVENT_MASK, &pSchedContext->mcEventFlag)) + { + clear_bit(MC_SUSPEND_EVENT_MASK, &pSchedContext->mcEventFlag); + spin_lock(&pSchedContext->McThreadLock); + + /* Mc Thread Suspended */ + complete(&pHddCtx->mc_sus_event_var); + + INIT_COMPLETION(pSchedContext->ResumeMcEvent); + spin_unlock(&pSchedContext->McThreadLock); + + /* Wait foe Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeMcEvent); + } + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the MC thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: MC Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->McShutdown, 0); +} /* VosMCThread() */ + +v_BOOL_t isWDresetInProgress(void) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Reset is in Progress...",__func__); + if(gpVosWatchdogContext!=NULL) + { + return gpVosWatchdogContext->resetInProgress; + } + else + { + return FALSE; + } +} +/*--------------------------------------------------------------------------- + \brief VosWdThread() - The VOSS Watchdog thread + The \a VosWdThread() is the Watchdog thread: + \param Arg - pointer to the global vOSS Sched Context + \return Thread exit code + \sa VosMcThread() + -------------------------------------------------------------------------*/ +static int +VosWDThread +( + void * Arg +) +{ + pVosWatchdogContext pWdContext = (pVosWatchdogContext)Arg; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + int count = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + set_user_nice(current, -3); + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("WD_Thread"); +#endif + + /* + ** Ack back to the context from which the Watchdog thread has been + ** created. + */ + complete(&pWdContext->WdStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog Thread %d (%s) starting up",__func__, current->pid, current->comm); + + while(!shutdown) + { + // This implements the Watchdog execution model algorithm + retWaitStatus = wait_event_interruptible(pWdContext->wdWaitQueue, + test_bit(WD_POST_EVENT_MASK, &pWdContext->wdEventFlag)); + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(WD_POST_EVENT_MASK, &pWdContext->wdEventFlag); + while(1) + { + /* Check for any Active Entry Points + * If active, delay SSR until no entry point is active or + * delay until count is decremented to ZERO + */ + count = MAX_SSR_WAIT_ITERATIONS; + while (count) + { + if (!atomic_read(&ssr_protect_entry_count)) + { + /* no external threads are executing */ + break; + } + /* at least one external thread is executing */ + if (--count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Waiting for active entry points to exit", __func__); + msleep(SSR_WAIT_SLEEP_TIME); + } + } + /* at least one external thread is executing */ + if (!count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Continuing SSR when %d Entry points are still active", + __func__, atomic_read(&ssr_protect_entry_count)); + } + // Check if Watchdog needs to shutdown + if(test_bit(WD_SHUTDOWN_EVENT_MASK, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog thread signaled to shutdown", __func__); + + clear_bit(WD_SHUTDOWN_EVENT_MASK, &pWdContext->wdEventFlag); + shutdown = VOS_TRUE; + break; + } + /* subsystem restart: shutdown event handler */ + else if(test_bit(WD_WLAN_SHUTDOWN_EVENT_MASK, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread signaled to perform WLAN shutdown",__func__); + clear_bit(WD_WLAN_SHUTDOWN_EVENT_MASK, &pWdContext->wdEventFlag); + + //Perform WLAN shutdown + if(!pWdContext->resetInProgress) + { + pWdContext->resetInProgress = true; + vosStatus = hdd_wlan_shutdown(); + + if (! VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to shutdown WLAN",__func__); + VOS_ASSERT(0); + goto err_reset; + } + } + } + /* subsystem restart: re-init event handler */ + else if(test_bit(WD_WLAN_REINIT_EVENT_MASK, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread signaled to perform WLAN re-init",__func__); + clear_bit(WD_WLAN_REINIT_EVENT_MASK, &pWdContext->wdEventFlag); + + //Perform WLAN re-init + if(!pWdContext->resetInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Trying to do WLAN re-init when it is not shutdown !!",__func__); + } + vosStatus = hdd_wlan_re_init(NULL); + + if (! VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to re-init WLAN",__func__); + VOS_ASSERT(0); + goto err_reset; + } + pWdContext->resetInProgress = false; + } + else + { + //Unnecessary wakeup - Should never happen!! + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread woke up unnecessarily",__func__); + } + break; + } // while message loop processing + } // while shutdown + + // If we get here the Watchdog thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog Thread exiting !!!!", __func__); + complete_and_exit(&pWdContext->WdShutdown, 0); + +err_reset: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog Thread Failed to Reset, Exiting!!!!", __func__); + return 0; + +} /* VosMCThread() */ + +/*--------------------------------------------------------------------------- + \brief VosTXThread() - The VOSS Main Tx thread + The \a VosTxThread() is the VOSS main controller thread: + \param Arg - pointer to the global vOSS Sched Context + + \return Thread exit code + \sa VosTxThread() + -------------------------------------------------------------------------*/ +static int VosTXThread ( void * Arg ) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + set_user_nice(current, -1); + +#ifdef WLAN_FEATURE_11AC_HIGH_TP + set_wake_up_idle(true); +#endif + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Bad Args passed", __func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("TX_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->TxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX Thread %d (%s) starting up!",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->txWaitQueue, + test_bit(TX_POST_EVENT_MASK, &pSchedContext->txEventFlag) || + test_bit(TX_SUSPEND_EVENT_MASK, &pSchedContext->txEventFlag)); + + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(TX_POST_EVENT_MASK, &pSchedContext->txEventFlag); + + while(1) + { + if(test_bit(TX_SHUTDOWN_EVENT_MASK, &pSchedContext->txEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if(test_bit(TX_SUSPEND_EVENT_MASK, &pSchedContext->txEventFlag)) + { + clear_bit(TX_SUSPEND_EVENT_MASK, &pSchedContext->txEventFlag); + + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->tx_sus_event_var); + } + break; + } + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysTxMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS TX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysTxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysTxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX SYS message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check now the TL queue + if (!vos_is_mq_empty(&pSchedContext->tlTxMq)) + { + // Service the TL message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS TL TX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->tlTxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WLANTL_TxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX TL message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + /* Check for any Suspend Indication */ + if(test_bit(TX_SUSPEND_EVENT_MASK, &pSchedContext->txEventFlag)) + { + clear_bit(TX_SUSPEND_EVENT_MASK, &pSchedContext->txEventFlag); + spin_lock(&pSchedContext->TxThreadLock); + + /* Tx Thread Suspended */ + complete(&pHddCtx->tx_sus_event_var); + + INIT_COMPLETION(pSchedContext->ResumeTxEvent); + spin_unlock(&pSchedContext->TxThreadLock); + + /* Wait foe Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeTxEvent); + } + + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the TX thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->TxShutdown, 0); +} /* VosTxThread() */ + +/*--------------------------------------------------------------------------- + \brief VosRXThread() - The VOSS Main Rx thread + The \a VosRxThread() is the VOSS Rx controller thread: + \param Arg - pointer to the global vOSS Sched Context + + \return Thread exit code + \sa VosRxThread() + -------------------------------------------------------------------------*/ + +static int VosRXThread ( void * Arg ) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + + set_user_nice(current, -1); + +#ifdef WLAN_FEATURE_11AC_HIGH_TP + set_wake_up_idle(true); +#endif + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Bad Args passed", __func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("RX_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->RxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX Thread %d (%s) starting up!",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->rxWaitQueue, + test_bit(RX_POST_EVENT_MASK, &pSchedContext->rxEventFlag) || + test_bit(RX_SUSPEND_EVENT_MASK, &pSchedContext->rxEventFlag)); + + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(RX_POST_EVENT_MASK, &pSchedContext->rxEventFlag); + + while(1) + { + if(test_bit(RX_SHUTDOWN_EVENT_MASK, &pSchedContext->rxEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if(test_bit(RX_SUSPEND_EVENT_MASK, &pSchedContext->rxEventFlag)) + { + clear_bit(RX_SUSPEND_EVENT_MASK, &pSchedContext->rxEventFlag); + + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->rx_sus_event_var); + } + break; + } + + + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysRxMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS RX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysRxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysRxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX SYS message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + /* Check for any Suspend Indication */ + if(test_bit(RX_SUSPEND_EVENT_MASK, &pSchedContext->rxEventFlag)) + { + clear_bit(RX_SUSPEND_EVENT_MASK, &pSchedContext->rxEventFlag); + spin_lock(&pSchedContext->RxThreadLock); + + /* Rx Thread Suspended */ + complete(&pHddCtx->rx_sus_event_var); + + INIT_COMPLETION(pSchedContext->ResumeRxEvent); + spin_unlock(&pSchedContext->RxThreadLock); + + /* Wait for Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeRxEvent); + } + + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the RX thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->RxShutdown, 0); +} /* VosRxThread() */ + +#ifdef QCA_CONFIG_SMP +/*--------------------------------------------------------------------------- + \brief vos_free_tlshim_pkt_freeq() - Free voss buffer free queue + The \a vos_free_tlshim_pkt_freeq() does mem free of the buffers + available in free vos buffer queue which is used for Data rx processing + from Tlshim. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return Nothing + \sa vos_free_tlshim_pkt_freeq() + -------------------------------------------------------------------------*/ +void vos_free_tlshim_pkt_freeq(pVosSchedContext pSchedContext) +{ + struct VosTlshimPkt *pkt, *tmp; + + spin_lock_bh(&pSchedContext->VosTlshimPktFreeQLock); + list_for_each_entry_safe(pkt, tmp, &pSchedContext->VosTlshimPktFreeQ, list) { + list_del(&pkt->list); + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); + vos_mem_free(pkt); + spin_lock_bh(&pSchedContext->VosTlshimPktFreeQLock); + } + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); +} + +/*--------------------------------------------------------------------------- + \brief vos_alloc_tlshim_pkt_freeq() - Function to allocate free buffer queue + The \a vos_alloc_tlshim_pkt_freeq() allocates VOSS_MAX_TLSHIM_PKT + number of vos message buffers which are used for Rx data processing + from Tlshim. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return status of memory allocation + \sa vos_alloc_tlshim_pkt_freeq() + -------------------------------------------------------------------------*/ +static VOS_STATUS vos_alloc_tlshim_pkt_freeq(pVosSchedContext pSchedContext) +{ + struct VosTlshimPkt *pkt, *tmp; + int i; + + for (i = 0; i < VOSS_MAX_TLSHIM_PKT; i++) { + pkt = vos_mem_malloc(sizeof(*pkt)); + if (!pkt) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Vos packet allocation for tlshim thread failed", + __func__); + goto free; + } + memset(pkt, 0, sizeof(*pkt)); + list_add_tail(&pkt->list, &pSchedContext->VosTlshimPktFreeQ); + } + + return VOS_STATUS_SUCCESS; + +free: + list_for_each_entry_safe(pkt, tmp, &pSchedContext->VosTlshimPktFreeQ, list) { + list_del(&pkt->list); + vos_mem_free(pkt); + } + return VOS_STATUS_E_NOMEM; +} + +/*--------------------------------------------------------------------------- + \brief vos_free_tlshim_pkt() - API to release vos message to the freeq + The \a vos_free_tlshim_pkt() returns the vos message used for Rx data + to the free queue. + \param pSchedContext - pointer to the global vOSS Sched Context + \param pkt - Vos message buffer to be returned to free queue. + + \return Nothing + \sa vos_free_tlshim_pkt() + -------------------------------------------------------------------------*/ +void vos_free_tlshim_pkt(pVosSchedContext pSchedContext, + struct VosTlshimPkt *pkt) +{ + memset(pkt, 0, sizeof(*pkt)); + spin_lock_bh(&pSchedContext->VosTlshimPktFreeQLock); + list_add_tail(&pkt->list, &pSchedContext->VosTlshimPktFreeQ); + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); +} + +/*--------------------------------------------------------------------------- + \brief vos_alloc_tlshim_pkt() - API to return next available vos message + The \a vos_alloc_tlshim_pkt() returns next available vos message buffer + used for Rx Data processing. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return pointer to vos message buffer + \sa vos_alloc_tlshim_pkt() + -------------------------------------------------------------------------*/ +struct VosTlshimPkt *vos_alloc_tlshim_pkt(pVosSchedContext pSchedContext) +{ + struct VosTlshimPkt *pkt; + + spin_lock_bh(&pSchedContext->VosTlshimPktFreeQLock); + if (list_empty(&pSchedContext->VosTlshimPktFreeQ)) { + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); + return NULL; + } + pkt = list_first_entry(&pSchedContext->VosTlshimPktFreeQ, + struct VosTlshimPkt, list); + list_del(&pkt->list); + spin_unlock_bh(&pSchedContext->VosTlshimPktFreeQLock); + return pkt; +} + +/*--------------------------------------------------------------------------- + \brief vos_indicate_rxpkt() - API to Indicate rx data packet + The \a vos_indicate_rxpkt() enqueues the rx packet onto tlshimRxQueue + and notifies VosTlshimRxThread(). + \param Arg - pointer to the global vOSS Sched Context + \param pkt - Vos data message buffer + + \return Nothing + \sa vos_indicate_rxpkt() + -------------------------------------------------------------------------*/ +void vos_indicate_rxpkt(pVosSchedContext pSchedContext, + struct VosTlshimPkt *pkt) +{ + spin_lock_bh(&pSchedContext->TlshimRxQLock); + list_add_tail(&pkt->list, &pSchedContext->tlshimRxQueue); + spin_unlock_bh(&pSchedContext->TlshimRxQLock); + set_bit(RX_POST_EVENT_MASK, &pSchedContext->tlshimRxEvtFlg); + wake_up_interruptible(&pSchedContext->tlshimRxWaitQueue); +} + +/*--------------------------------------------------------------------------- + \brief vos_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta + The \a vos_drop_rxpkt_by_staid() drops queued packets for a station, to drop + all the pending packets the caller has to send WLAN_MAX_STA_COUNT as staId. + \param pSchedContext - pointer to the global vOSS Sched Context + \param staId - Station Id + + \return Nothing + \sa vos_drop_rxpkt_by_staid() + -------------------------------------------------------------------------*/ +void vos_drop_rxpkt_by_staid(pVosSchedContext pSchedContext, u_int16_t staId) +{ + struct list_head local_list; + struct VosTlshimPkt *pkt, *tmp; + adf_nbuf_t buf, next_buf; + + INIT_LIST_HEAD(&local_list); + spin_lock_bh(&pSchedContext->TlshimRxQLock); + if (list_empty(&pSchedContext->tlshimRxQueue)) { + spin_unlock_bh(&pSchedContext->TlshimRxQLock); + return; + } + list_for_each_entry_safe(pkt, tmp, &pSchedContext->tlshimRxQueue, list) { + if (pkt->staId == staId || staId == WLAN_MAX_STA_COUNT) + list_move_tail(&pkt->list, &local_list); + } + spin_unlock_bh(&pSchedContext->TlshimRxQLock); + + list_for_each_entry_safe(pkt, tmp, &local_list, list) { + list_del(&pkt->list); + buf = pkt->Rxpkt; + while (buf) { + next_buf = adf_nbuf_queue_next(buf); + adf_nbuf_free(buf); + buf = next_buf; + } + vos_free_tlshim_pkt(pSchedContext, pkt); + } +} + +/*--------------------------------------------------------------------------- + \brief vos_rx_from_queue() - Function to process pending Rx packets + The \a vos_rx_from_queue() traverses the pending buffer list and calling + the callback. This callback would essentially send the packet to HDD. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return Nothing + \sa vos_rx_from_queue() + -------------------------------------------------------------------------*/ +static void vos_rx_from_queue(pVosSchedContext pSchedContext) +{ + struct VosTlshimPkt *pkt; + u_int16_t sta_id; + + spin_lock_bh(&pSchedContext->TlshimRxQLock); + while (!list_empty(&pSchedContext->tlshimRxQueue)) { + pkt = list_first_entry(&pSchedContext->tlshimRxQueue, + struct VosTlshimPkt, list); + list_del(&pkt->list); + spin_unlock_bh(&pSchedContext->TlshimRxQLock); + sta_id = pkt->staId; + pkt->callback(pkt->context, pkt->Rxpkt, sta_id); + vos_free_tlshim_pkt(pSchedContext, pkt); + spin_lock_bh(&pSchedContext->TlshimRxQLock); + } + spin_unlock_bh(&pSchedContext->TlshimRxQLock); +} + +/*--------------------------------------------------------------------------- + \brief VosTlshimRxThread() - The VOSS Main Tlshim Rx thread + The \a VosTlshimRxThread() is the thread for Tlshim Data packet processing. + \param Arg - pointer to the global vOSS Sched Context + + \return Thread exit code + \sa VosTlshimRxThread() + -------------------------------------------------------------------------*/ +static int VosTlshimRxThread(void *arg) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)arg; + unsigned long pref_cpu = 0; + bool shutdown = false; + int status, i; + + set_user_nice(current, -1); +#ifdef MSM_PLATFORM + set_wake_up_idle(true); +#endif + + /* Find the available cpu core other than cpu 0 and + * bind the thread */ + for_each_online_cpu(i) { + if (i == 0) + continue; + pref_cpu = i; + break; + } + if (pref_cpu != 0 && (!vos_set_cpus_allowed_ptr(current, pref_cpu))) + affine_cpu = pref_cpu; + + if (!arg) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + + complete(&pSchedContext->TlshimRxStartEvent); + + while (!shutdown) { + status = wait_event_interruptible(pSchedContext->tlshimRxWaitQueue, + test_bit(RX_POST_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg) || + test_bit(RX_SUSPEND_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg)); + if (status == -ERESTARTSYS) + break; + + clear_bit(RX_POST_EVENT_MASK, &pSchedContext->tlshimRxEvtFlg); + while (true) { + if (test_bit(RX_SHUTDOWN_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg)) { + clear_bit(RX_SHUTDOWN_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg); + if (test_bit(RX_SUSPEND_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg)) { + clear_bit(RX_SUSPEND_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg); + complete(&pSchedContext->SuspndTlshimRxEvent); + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Shutting down tl shim Tlshim rx thread", __func__); + shutdown = true; + break; + } + vos_rx_from_queue(pSchedContext); + + if (test_bit(RX_SUSPEND_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg)) { + clear_bit(RX_SUSPEND_EVENT_MASK, + &pSchedContext->tlshimRxEvtFlg); + spin_lock(&pSchedContext->TlshimRxThreadLock); + complete(&pSchedContext->SuspndTlshimRxEvent); + INIT_COMPLETION(pSchedContext->ResumeTlshimRxEvent); + spin_unlock(&pSchedContext->TlshimRxThreadLock); + wait_for_completion_interruptible( + &pSchedContext->ResumeTlshimRxEvent); + } + break; + } + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Exiting VOSS Tlshim rx thread", __func__); + complete_and_exit(&pSchedContext->TlshimRxShutdown, 0); +} +#endif + +/*--------------------------------------------------------------------------- + \brief vos_sched_close() - Close the vOSS Scheduler + The \a vos_sched_closes() function closes the vOSS Scheduler + Upon successful closing: + - All the message queues are flushed + - The Main Controller thread is closed + - The Tx thread is closed + + \param pVosContext - pointer to the global vOSS Context + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + \sa vos_sched_close() +---------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_close ( v_PVOID_t pVosContext ) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: invoked", __func__); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return VOS_STATUS_E_FAILURE; + } + + // shut down MC Thread + set_bit(MC_SHUTDOWN_EVENT_MASK, &gpVosSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT_MASK, &gpVosSchedContext->mcEventFlag); + wake_up_interruptible(&gpVosSchedContext->mcWaitQueue); + //Wait for MC to exit + wait_for_completion(&gpVosSchedContext->McShutdown); + gpVosSchedContext->McThread = 0; + + // shut down TX Thread + set_bit(TX_SHUTDOWN_EVENT_MASK, &gpVosSchedContext->txEventFlag); + set_bit(TX_POST_EVENT_MASK, &gpVosSchedContext->txEventFlag); + wake_up_interruptible(&gpVosSchedContext->txWaitQueue); + //Wait for TX to exit + wait_for_completion(&gpVosSchedContext->TxShutdown); + gpVosSchedContext->TxThread = 0; + + // shut down RX Thread + set_bit(RX_SHUTDOWN_EVENT_MASK, &gpVosSchedContext->rxEventFlag); + set_bit(RX_POST_EVENT_MASK, &gpVosSchedContext->rxEventFlag); + wake_up_interruptible(&gpVosSchedContext->rxWaitQueue); + //Wait for RX to exit + wait_for_completion(&gpVosSchedContext->RxShutdown); + gpVosSchedContext->RxThread = 0; + + //Clean up message queues of TX and MC thread + vos_sched_flush_mc_mqs(gpVosSchedContext); + vos_sched_flush_tx_mqs(gpVosSchedContext); + vos_sched_flush_rx_mqs(gpVosSchedContext); + + //Deinit all the queues + vos_sched_deinit_mqs(gpVosSchedContext); + +#ifdef QCA_CONFIG_SMP + vos_lock_destroy(&gpVosSchedContext->affinity_lock); + // Shut down Tlshim Rx thread + set_bit(RX_SHUTDOWN_EVENT_MASK, &gpVosSchedContext->tlshimRxEvtFlg); + set_bit(RX_POST_EVENT_MASK, &gpVosSchedContext->tlshimRxEvtFlg); + wake_up_interruptible(&gpVosSchedContext->tlshimRxWaitQueue); + wait_for_completion(&gpVosSchedContext->TlshimRxShutdown); + gpVosSchedContext->TlshimRxThread = NULL; + vos_drop_rxpkt_by_staid(gpVosSchedContext, WLAN_MAX_STA_COUNT); + vos_free_tlshim_pkt_freeq(gpVosSchedContext); + unregister_hotcpu_notifier(&vos_cpu_hotplug_notifier); +#endif + return VOS_STATUS_SUCCESS; +} /* vox_sched_close() */ + +VOS_STATUS vos_watchdog_close ( v_PVOID_t pVosContext ) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: vos_watchdog closing now", __func__); + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosWatchdogContext is NULL",__func__); + return VOS_STATUS_E_FAILURE; + } + set_bit(WD_SHUTDOWN_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + //Wait for Watchdog thread to exit + wait_for_completion(&gpVosWatchdogContext->WdShutdown); + return VOS_STATUS_SUCCESS; +} /* vos_watchdog_close() */ + +/*--------------------------------------------------------------------------- + \brief vos_sched_init_mqs: Initialize the vOSS Scheduler message queues + The \a vos_sched_init_mqs() function initializes the vOSS Scheduler + message queues. + \param pVosSchedContext - pointer to the Scheduler Context. + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + \sa vos_sched_init_mqs() + -------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_init_mqs ( pVosSchedContext pSchedContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + // Now intialize all the message queues + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the WDA MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->wdaMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init WDA MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the PE MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->peMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init PE MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SME MC Message queue", __func__); + vStatus = vos_mq_init(&pSchedContext->smeMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SME MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the TL MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->tlMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init TL MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SYS MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->sysMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the TL Tx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->tlTxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init TL TX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SYS Tx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->sysTxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS TX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + vStatus = vos_mq_init(&pSchedContext->sysRxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS RX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + return VOS_STATUS_SUCCESS; +} /* vos_sched_init_mqs() */ + +/*--------------------------------------------------------------------------- + \brief vos_sched_deinit_mqs: Deinitialize the vOSS Scheduler message queues + The \a vos_sched_init_mqs() function deinitializes the vOSS Scheduler + message queues. + \param pVosSchedContext - pointer to the Scheduler Context. + \return None + \sa vos_sched_deinit_mqs() + -------------------------------------------------------------------------*/ +void vos_sched_deinit_mqs ( pVosSchedContext pSchedContext ) +{ + // Now de-intialize all message queues + // MC WDA + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the WDA MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->wdaMcMq); + //MC PE + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the PE MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->peMcMq); + //MC SME + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the SME MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->smeMcMq); + //MC TL + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the TL MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->tlMcMq); + //MC SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the SYS MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysMcMq); + + //Tx TL + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the TL Tx Message queue",__func__); + vos_mq_deinit(&pSchedContext->tlTxMq); + + //Tx SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the SYS Tx Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysTxMq); + + //Rx SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the SYS Rx Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysRxMq); +} /* vos_sched_deinit_mqs() */ + +/*------------------------------------------------------------------------- + this helper function flushes all the MC message queues + -------------------------------------------------------------------------*/ +void vos_sched_flush_mc_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + pVosContextType vosCtx; + + /* + ** Here each of the MC thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall be + ** freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + ("Flushing the MC Thread message queue") ); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + vosCtx = (pVosContextType)(pSchedContext->pVContext); + if (NULL == vosCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vosCtx is NULL", __func__); + return; + } + + /* Flush the SYS Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC SYS message type %d ",__func__, + pMsgWrapper->pVosMsg->type ); + sysMcFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the WDA Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->wdaMcMq) )) + { + if(pMsgWrapper->pVosMsg != NULL) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC WDA MSG message type %d", + __func__, pMsgWrapper->pVosMsg->type ); + if (pMsgWrapper->pVosMsg->bodyptr) { + vos_mem_free((v_VOID_t*)pMsgWrapper->pVosMsg->bodyptr); + } + + pMsgWrapper->pVosMsg->bodyptr = NULL; + pMsgWrapper->pVosMsg->bodyval = 0; + pMsgWrapper->pVosMsg->type = 0; + } + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + + /* Flush the PE Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->peMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC PE MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + peFreeMsg(vosCtx->pMACContext, (tSirMsgQ*)pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the SME Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->smeMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC SME MSG message type %d", __func__, + pMsgWrapper->pVosMsg->type ); + sme_FreeMsg(vosCtx->pMACContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the TL Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->tlMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC TL message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + WLANTL_McFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } +} /* vos_sched_flush_mc_mqs() */ + +/*------------------------------------------------------------------------- + This helper function flushes all the TX message queues + ------------------------------------------------------------------------*/ +void vos_sched_flush_tx_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + /* + ** Here each of the TX thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall + ** be freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Flushing the TX Thread message queue",__func__); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + /* Flush the SYS Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysTxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing TX SYS message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the TL Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->tlTxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing TX TL MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + WLANTL_TxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } +} /* vos_sched_flush_tx_mqs() */ +/*------------------------------------------------------------------------- + This helper function flushes all the RX message queues + ------------------------------------------------------------------------*/ +void vos_sched_flush_rx_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + /* + ** Here each of the RX thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall + ** be freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Flushing the RX Thread message queue",__func__); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysRxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing RX SYS MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + } + +}/* vos_sched_flush_rx_mqs() */ + +/*------------------------------------------------------------------------- + This helper function helps determine if thread id is of TX thread + ------------------------------------------------------------------------*/ +int vos_sched_is_tx_thread(int threadID) +{ + // Make sure that Vos Scheduler context has been initialized + VOS_ASSERT( NULL != gpVosSchedContext); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return 0; + } + return ((gpVosSchedContext->TxThread) && (threadID == gpVosSchedContext->TxThread->pid)); +} +/*------------------------------------------------------------------------- + This helper function helps determine if thread id is of RX thread + ------------------------------------------------------------------------*/ +int vos_sched_is_rx_thread(int threadID) +{ + // Make sure that Vos Scheduler context has been initialized + VOS_ASSERT( NULL != gpVosSchedContext); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return 0; + } + return ((gpVosSchedContext->RxThread) && (threadID == gpVosSchedContext->RxThread->pid)); +} +/*------------------------------------------------------------------------- + Helper function to get the scheduler context + ------------------------------------------------------------------------*/ +pVosSchedContext get_vos_sched_ctxt(void) +{ + //Make sure that Vos Scheduler context has been initialized + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + } + return (gpVosSchedContext); +} +/*------------------------------------------------------------------------- + Helper function to get the watchdog context + ------------------------------------------------------------------------*/ +pVosWatchdogContext get_vos_watchdog_ctxt(void) +{ + //Make sure that Vos Scheduler context has been initialized + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosWatchdogContext == NULL",__func__); + } + return (gpVosWatchdogContext); +} +/** + @brief vos_watchdog_wlan_shutdown() + + This function is called to shutdown WLAN driver during SSR. + Adapters are disabled, and the watchdog task will be signalled + to shutdown WLAN driver. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_watchdog_wlan_shutdown(void) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: WLAN driver is shutting down ", __func__); + if (NULL == gpVosWatchdogContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog not enabled. LOGP ignored.", __func__); + return VOS_STATUS_E_FAILURE; + } + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid HDD Context", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Take the lock here */ + spin_lock(&gpVosWatchdogContext->wdLock); + + /* reuse the existing 'reset in progress' */ + if (gpVosWatchdogContext->resetInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Shutdown already in Progress. Ignoring signaling Watchdog", + __func__); + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + return VOS_STATUS_E_FAILURE; + } + /* reuse the existing 'logp in progress', eventhough it is not + * exactly the same */ + else if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: shutdown/re-init already in Progress. Ignoring signaling Watchdog", + __func__); + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + return VOS_STATUS_E_FAILURE; + } + + /* Set the flags so that all future CMD53 and Wext commands get blocked right away */ + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + pHddCtx->isLogpInProgress = TRUE; + + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + + if ((pHddCtx->isLoadInProgress) || + (pHddCtx->isUnloadInProgress)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Load/unload in Progress. Ignoring signaling Watchdog", + __func__); + /* wcnss has crashed, and SSR has alredy been started by Kernel driver. + * So disable SSR from WLAN driver */ + hdd_set_ssr_required( HDD_SSR_DISABLED ); + return VOS_STATUS_E_FAILURE; + } + /* Update Riva Reset Statistics */ + pHddCtx->hddRivaResetStats++; +#ifdef CONFIG_HAS_EARLYSUSPEND + if(VOS_STATUS_SUCCESS != hdd_wlan_reset_initialization()) + { + VOS_ASSERT(0); + } +#endif + + set_bit(WD_WLAN_SHUTDOWN_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + + return VOS_STATUS_SUCCESS; +} + +/** + @brief vos_watchdog_wlan_re_init() + + This function is called to re-initialize WLAN driver, and this is + called when Riva SS reboots. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_watchdog_wlan_re_init(void) +{ + /* watchdog task is still running, it is not closed in shutdown */ + set_bit(WD_WLAN_REINIT_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT_MASK, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + + return VOS_STATUS_SUCCESS; +} + +/** + * vos_ssr_protect_init() - initialize ssr protection debug functionality + * + * Return: + * void + */ +void vos_ssr_protect_init(void) +{ + int i = 0; + + spin_lock_init(&ssr_protect_lock); + + while (i < MAX_SSR_PROTECT_LOG) { + ssr_protect_log[i].func = NULL; + ssr_protect_log[i].free = true; + ssr_protect_log[i].pid = 0; + i++; + } +} + +/** + * vos_print_external_threads() - print external threads stuck in driver + * + * Return: + * void + */ + +static void vos_print_external_threads(void) +{ + int i = 0; + unsigned long irq_flags; + + spin_lock_irqsave(&ssr_protect_lock, irq_flags); + + while (i < MAX_SSR_PROTECT_LOG) { + if (!ssr_protect_log[i].free) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PID %d is stuck at %s", ssr_protect_log[i].pid, + ssr_protect_log[i].func); + } + i++; + } + + spin_unlock_irqrestore(&ssr_protect_lock, irq_flags); +} + + +/** + @brief vos_ssr_protect() + + This function is called to keep track of active driver entry points + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_protect(const char *caller_func) +{ + int count; + int i = 0; + bool status = false; + unsigned long irq_flags; + + count = atomic_inc_return(&ssr_protect_entry_count); + + spin_lock_irqsave(&ssr_protect_lock, irq_flags); + + while (i < MAX_SSR_PROTECT_LOG) { + if (ssr_protect_log[i].free) { + ssr_protect_log[i].func = caller_func; + ssr_protect_log[i].free = false; + ssr_protect_log[i].pid = current->pid; + status = true; + break; + } + i++; + } + + spin_unlock_irqrestore(&ssr_protect_lock, irq_flags); + + if (!status) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Could not track PID %d call %s: log is full", + current->pid, caller_func); + +} + +/** + @brief vos_ssr_unprotect() + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_unprotect(const char *caller_func) +{ + int count; + int i = 0; + bool status = false; + unsigned long irq_flags; + + count = atomic_dec_return(&ssr_protect_entry_count); + + spin_lock_irqsave(&ssr_protect_lock, irq_flags); + + while (i < MAX_SSR_PROTECT_LOG) { + if (!ssr_protect_log[i].free) { + if ((ssr_protect_log[i].pid == current->pid) && + !strcmp(ssr_protect_log[i].func, caller_func)) { + ssr_protect_log[i].func = NULL; + ssr_protect_log[i].free = true; + ssr_protect_log[i].pid = 0; + status = true; + break; + } + } + i++; + } + + spin_unlock_irqrestore(&ssr_protect_lock, irq_flags); + + if (!status) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Untracked call %s", caller_func); +} + +/** + @brief vos_is_ssr_ready() + + This function will check if the calling execution can + proceed with SSR. + + @param + caller_func - Name of calling function. + @return + true or false +*/ +bool vos_is_ssr_ready(const char *caller_func) +{ + int count = MAX_SSR_WAIT_ITERATIONS; + + while (count) { + + if (!atomic_read(&ssr_protect_entry_count)) + break; + + if (--count) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Waiting for active entry points to exit", __func__); + msleep(SSR_WAIT_SLEEP_TIME); + } + } + /* at least one external thread is executing */ + if (!count) { + vos_print_external_threads(); + return false; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Allowing SSR for %s", caller_func); + + return true; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.h b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.h new file mode 100644 index 0000000000000..d372c03142551 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_sched.h @@ -0,0 +1,658 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_SCHED_H ) +#define __VOS_SCHED_H + +/**========================================================================= + + \file vos_sched.h + + \brief virtual Operating System Servies (vOSS) + + Definitions for some of the internal data type that is internally used + by the vOSS scheduler on Windows Mobile. + + This file defines a vOSS message queue on Win Mobile and give some + insights about how the scheduler implements the execution model supported + by vOSS. + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 09/15/08 lac Removed hardcoded #define for VOS_TRACE. + 06/12/08 hba Created module. + +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "i_vos_types.h" +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif +#include +#include +#include + +#define TX_POST_EVENT_MASK 0x001 +#define TX_SUSPEND_EVENT_MASK 0x002 +#define MC_POST_EVENT_MASK 0x001 +#define MC_SUSPEND_EVENT_MASK 0x002 +#define RX_POST_EVENT_MASK 0x001 +#define RX_SUSPEND_EVENT_MASK 0x002 +#define TX_SHUTDOWN_EVENT_MASK 0x010 +#define MC_SHUTDOWN_EVENT_MASK 0x010 +#define RX_SHUTDOWN_EVENT_MASK 0x010 +#define WD_POST_EVENT_MASK 0x001 +#define WD_SHUTDOWN_EVENT_MASK 0x002 +#define WD_CHIP_RESET_EVENT_MASK 0x004 +#define WD_WLAN_SHUTDOWN_EVENT_MASK 0x008 +#define WD_WLAN_REINIT_EVENT_MASK 0x010 + + + +/* +** Maximum number of messages in the system +** These are buffers to account for all current messages +** with some accounting of what we think is a +** worst-case scenario. Must be able to handle all +** incoming frames, as well as overhead for internal +** messaging +** +** Increased to 8000 to handle more RX frames +*/ +#define VOS_CORE_MAX_MESSAGES 8000 + +#ifdef QCA_CONFIG_SMP +/* +** Maximum number of vos messages to be allocated for +** Tlshim Rx thread. +*/ +#define VOSS_MAX_TLSHIM_PKT 4000 + +typedef void (*vos_tlshim_cb) (void *context, void *rxpkt, u_int16_t staid); +#endif + +/* +** vOSS Message queue definition. +*/ +typedef struct _VosMqType +{ + /* Lock use to synchronize access to this message queue */ + spinlock_t mqLock; + + /* List of vOS Messages waiting on this queue */ + struct list_head mqList; + +} VosMqType, *pVosMqType; + +#ifdef QCA_CONFIG_SMP +/* +** VOSS message wrapper for data rx from Tlshim. +*/ +typedef struct VosTlshimPkt +{ + struct list_head list; + + /* Tlshim context */ + void *context; + + /* Rx skb */ + void *Rxpkt; + + /* Station id to which this packet is destined */ + u_int16_t staId; + + /* Call back to further send this packet to tlshim layer */ + vos_tlshim_cb callback; + +} *pVosTlshimPkt; +#endif + +/* +** vOSS Scheduler context +** The scheduler context contains the following: +** ** the messages queues +** ** the handle to the tread +** ** pointer to the events that gracefully shutdown the MC and Tx threads +** +*/ +typedef struct _VosSchedContext +{ + /* Place holder to the VOSS Context */ + v_PVOID_t pVContext; + /* WDA Message queue on the Main thread*/ + VosMqType wdaMcMq; + + + + /* PE Message queue on the Main thread*/ + VosMqType peMcMq; + + /* SME Message queue on the Main thread*/ + VosMqType smeMcMq; + + /* TL Message queue on the Main thread */ + VosMqType tlMcMq; + + /* SYS Message queue on the Main thread */ + VosMqType sysMcMq; + + /* TL Message queue on the Tx thread */ + VosMqType tlTxMq; + + /* SYS Message queue on the Tx thread */ + VosMqType sysTxMq; + + VosMqType sysRxMq; + + /* Handle of Event for MC thread to signal startup */ + struct completion McStartEvent; + + /* Handle of Event for Tx thread to signal startup */ + struct completion TxStartEvent; + + /* Handle of Event for Rx thread to signal startup */ + struct completion RxStartEvent; + + struct task_struct* McThread; + + /* TX Thread handle */ + + struct task_struct* TxThread; + + /* RX Thread handle */ + struct task_struct* RxThread; + + + /* completion object for MC thread shutdown */ + struct completion McShutdown; + + /* completion object for Tx thread shutdown */ + struct completion TxShutdown; + + /* completion object for Rx thread shutdown */ + struct completion RxShutdown; + + /* Wait queue for MC thread */ + wait_queue_head_t mcWaitQueue; + + unsigned long mcEventFlag; + + /* Wait queue for Tx thread */ + wait_queue_head_t txWaitQueue; + + unsigned long txEventFlag; + + /* Wait queue for Rx thread */ + wait_queue_head_t rxWaitQueue; + + unsigned long rxEventFlag; + + /* Completion object to resume Mc thread */ + struct completion ResumeMcEvent; + + /* Completion object to resume Tx thread */ + struct completion ResumeTxEvent; + + /* Completion object to resume Rx thread */ + struct completion ResumeRxEvent; + + /* lock to make sure that McThread and TxThread Suspend/resume mechanism is in sync*/ + spinlock_t McThreadLock; + spinlock_t TxThreadLock; + spinlock_t RxThreadLock; +#ifdef QCA_CONFIG_SMP + spinlock_t TlshimRxThreadLock; + + /* Tlshim Rx thread handle */ + struct task_struct *TlshimRxThread; + + /* Handle of Event for Rx thread to signal startup */ + struct completion TlshimRxStartEvent; + + /* Completion object to suspend tlshim rx thread */ + struct completion SuspndTlshimRxEvent; + + /* Completion objext to resume tlshim rx thread */ + struct completion ResumeTlshimRxEvent; + + /* Completion object for Tlshim Rxthread shutdown */ + struct completion TlshimRxShutdown; + + /* Waitq for tlshim Rx thread */ + wait_queue_head_t tlshimRxWaitQueue; + + unsigned long tlshimRxEvtFlg; + + /* Rx buffer queue */ + struct list_head tlshimRxQueue; + + /* Spinlock to synchronize between tasklet and thread */ + spinlock_t TlshimRxQLock; + + /* Rx queue length */ + unsigned int TlshimRxQlen; + + /* Lock to synchronize free buffer queue access */ + spinlock_t VosTlshimPktFreeQLock; + + /* Free message queue for Tlshim Rx processing */ + struct list_head VosTlshimPktFreeQ; + + /* cpu hotplug notifier */ + struct notifier_block *cpuHotPlugNotifier; + + /* affinity lock */ + vos_lock_t affinity_lock; + + /* rx thread affinity cpu */ + unsigned long rx_thread_cpu; + + /* high throughput required */ + bool high_throughput_required; +#endif +} VosSchedContext, *pVosSchedContext; + +/* +** VOSS watchdog context +** The watchdog context contains the following: +** The messages queues and events +** The handle to the thread +** +*/ +typedef struct _VosWatchdogContext +{ + + /* Place holder to the VOSS Context */ + v_PVOID_t pVContext; + + /* Handle of Event for Watchdog thread to signal startup */ + struct completion WdStartEvent; + + /* Watchdog Thread handle */ + + struct task_struct* WdThread; + + /* completion object for Watchdog thread shutdown */ + struct completion WdShutdown; + + /* Wait queue for Watchdog thread */ + wait_queue_head_t wdWaitQueue; + + /* Event flag for events handled by Watchdog */ + unsigned long wdEventFlag; + + v_BOOL_t resetInProgress; + + /* Lock for preventing multiple reset being triggered simultaneously */ + spinlock_t wdLock; + +} VosWatchdogContext, *pVosWatchdogContext; + +/* +** vOSS Sched Msg Wrapper +** Wrapper messages so that they can be chained to their respective queue +** in the scheduler. +*/ +typedef struct _VosMsgWrapper +{ + /* Message node */ + struct list_head msgNode; + + /* the Vos message it is associated to */ + vos_msg_t *pVosMsg; + +} VosMsgWrapper, *pVosMsgWrapper; + + + +typedef struct _VosContextType +{ + /* Messages buffers */ + vos_msg_t aMsgBuffers[VOS_CORE_MAX_MESSAGES]; + + VosMsgWrapper aMsgWrappers[VOS_CORE_MAX_MESSAGES]; + + /* Free Message queue*/ + VosMqType freeVosMq; + + /* Scheduler Context */ + VosSchedContext vosSched; + + /* Watchdog Context */ + VosWatchdogContext vosWatchdog; + + /* HDD Module Context */ + v_VOID_t *pHDDContext; + + /* HDD SoftAP Module Context */ + v_VOID_t *pHDDSoftAPContext; + + /* TL Module Context */ + v_VOID_t *pTLContext; + + /* MAC Module Context */ + v_VOID_t *pMACContext; + + /* BAP Context */ + v_VOID_t *pBAPContext; + +#ifndef WLAN_FEATURE_MBSSID + /* SAP Context */ + v_VOID_t *pSAPContext; +#endif + + vos_event_t ProbeEvent; + + volatile v_U8_t isLogpInProgress; + + vos_event_t wdaCompleteEvent; + + /* WDA Context */ + v_VOID_t *pWDAContext; + + v_VOID_t *pHIFContext; + + v_VOID_t *htc_ctx; + + /* + * adf_ctx will be used by adf + * while allocating dma memory + * to access dev information. + */ + adf_os_device_t adf_ctx; + + v_VOID_t *pdev_txrx_ctx; + + /* Configuration handle used to get system configuration */ + v_VOID_t *cfg_ctx; + + volatile v_U8_t isLoadUnloadInProgress; + + /* SSR re-init in progress */ + volatile v_U8_t isReInitInProgress; + +} VosContextType, *pVosContextType; + + + +/*--------------------------------------------------------------------------- + Function declarations and documenation +---------------------------------------------------------------------------*/ + +#ifdef QCA_CONFIG_SMP +int vos_sched_handle_cpu_hot_plug(void); +int vos_sched_handle_throughput_req(bool high_tput_required); + +/*--------------------------------------------------------------------------- + \brief vos_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta + The \a vos_drop_rxpkt_by_staid() drops queued packets for a station, to drop + all the pending packets the caller has to send WLAN_MAX_STA_COUNT as staId. + \param pSchedContext - pointer to the global vOSS Sched Context + \param staId - Station Id + + \return Nothing + \sa vos_drop_rxpkt_by_staid() + -------------------------------------------------------------------------*/ +void vos_drop_rxpkt_by_staid(pVosSchedContext pSchedContext, u_int16_t staId); + +/*--------------------------------------------------------------------------- + \brief vos_indicate_rxpkt() - API to Indicate rx data packet + The \a vos_indicate_rxpkt() enqueues the rx packet onto tlshimRxQueue + and notifies VosTlshimRxThread(). + \param Arg - pointer to the global vOSS Sched Context + \param pkt - Vos data message buffer + + \return Nothing + \sa vos_indicate_rxpkt() + -------------------------------------------------------------------------*/ +void vos_indicate_rxpkt(pVosSchedContext pSchedContext, + struct VosTlshimPkt *pkt); + +/*--------------------------------------------------------------------------- + \brief vos_alloc_tlshim_pkt() - API to return next available vos message + The \a vos_alloc_tlshim_pkt() returns next available vos message buffer + used for Rx Data processing. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return pointer to vos message buffer + \sa vos_alloc_tlshim_pkt() + -------------------------------------------------------------------------*/ +struct VosTlshimPkt *vos_alloc_tlshim_pkt(pVosSchedContext pSchedContext); + +/*--------------------------------------------------------------------------- + \brief vos_free_tlshim_pkt() - API to release vos message to the freeq + The \a vos_free_tlshim_pkt() returns the vos message used for Rx data + to the free queue. + \param pSchedContext - pointer to the global vOSS Sched Context + \param pkt - Vos message buffer to be returned to free queue. + + \return Nothing + \sa vos_free_tlshim_pkt() + -------------------------------------------------------------------------*/ +void vos_free_tlshim_pkt(pVosSchedContext pSchedContext, + struct VosTlshimPkt *pkt); +/*--------------------------------------------------------------------------- + \brief vos_free_tlshim_pkt_freeq() - Free voss buffer free queue + The \a vos_free_tlshim_pkt_freeq() does mem free of the buffers + available in free vos buffer queue which is used for Data rx processing + from Tlshim. + \param pSchedContext - pointer to the global vOSS Sched Context + + \return Nothing + \sa vos_free_tlshim_pkt_freeq() + -------------------------------------------------------------------------*/ +void vos_free_tlshim_pkt_freeq(pVosSchedContext pSchedContext); +#else +static inline int vos_sched_handle_throughput_req( + bool high_tput_required) +{ + return 0; +} +#endif + +int vos_sched_is_tx_thread(int threadID); +int vos_sched_is_rx_thread(int threadID); +/*--------------------------------------------------------------------------- + + \brief vos_sched_open() - initialize the vOSS Scheduler + + The \a vos_sched_open() function initializes the vOSS Scheduler + Upon successful initialization: + + - All the message queues are initialized + + - The Main Controller thread is created and ready to receive and + dispatch messages. + + - The Tx thread is created and ready to receive and dispatch messages + + + \param pVosContext - pointer to the global vOSS Context + + \param pVosSchedContext - pointer to a previously allocated buffer big + enough to hold a scheduler context. + \ + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the scheduler + + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_sched_open() + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_open( v_PVOID_t pVosContext, + pVosSchedContext pSchedCxt, + v_SIZE_t SchedCtxSize); + +/*--------------------------------------------------------------------------- + + \brief vos_watchdog_open() - initialize the vOSS watchdog + + The \a vos_watchdog_open() function initializes the vOSS watchdog. Upon successful + initialization, the watchdog thread is created and ready to receive and process messages. + + + \param pVosContext - pointer to the global vOSS Context + + \param pWdContext - pointer to a previously allocated buffer big + enough to hold a watchdog context. + + \return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the Watchdog + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the Watchdog + + VOS_STATUS_E_INVAL - Invalid parameter passed to the Watchdog Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/ + + \sa vos_watchdog_open() + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_watchdog_open + +( + v_PVOID_t pVosContext, + pVosWatchdogContext pWdContext, + v_SIZE_t wdCtxSize +); + +/*--------------------------------------------------------------------------- + + \brief vos_sched_close() - Close the vOSS Scheduler + + The \a vos_sched_closes() function closes the vOSS Scheduler + Upon successful closing: + + - All the message queues are flushed + + - The Main Controller thread is closed + + - The Tx thread is closed + + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_sched_close() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_close( v_PVOID_t pVosContext); + +/*--------------------------------------------------------------------------- + + \brief vos_watchdog_close() - Close the vOSS Watchdog + + The \a vos_watchdog_close() function closes the vOSS Watchdog + Upon successful closing: + + - The Watchdog thread is closed + + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and + is ready to be used. + + VOS_STATUS_E_INVAL - Invalid parameter passed + + VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/ + + \sa vos_watchdog_close() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_watchdog_close ( v_PVOID_t pVosContext ); + +/* Helper routines provided to other VOS API's */ +VOS_STATUS vos_mq_init(pVosMqType pMq); +void vos_mq_deinit(pVosMqType pMq); +void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper); +pVosMsgWrapper vos_mq_get(pVosMqType pMq); +v_BOOL_t vos_is_mq_empty(pVosMqType pMq); +pVosSchedContext get_vos_sched_ctxt(void); +pVosWatchdogContext get_vos_watchdog_ctxt(void); +VOS_STATUS vos_sched_init_mqs (pVosSchedContext pSchedContext); +void vos_sched_deinit_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_mc_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_tx_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_rx_mqs (pVosSchedContext pSchedContext); +void clearWlanResetReason(void); + +void vos_timer_module_init( void ); +VOS_STATUS vos_watchdog_wlan_shutdown(void); +VOS_STATUS vos_watchdog_wlan_re_init(void); +v_BOOL_t isWDresetInProgress(void); +void vos_ssr_protect_init(void); +void vos_ssr_protect(const char *caller_func); +void vos_ssr_unprotect(const char *caller_func); +bool vos_is_ssr_ready(const char *caller_func); + +#define vos_wait_for_work_thread_completion(func) vos_is_ssr_ready(func) + +#endif // #if !defined __VOSS_SCHED_H diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_threads.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_threads.c new file mode 100644 index 0000000000000..afbc9e9888da8 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_threads.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_threads.c + + \brief virtual Operating System Services (vOSS) Threading APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_sleep() - sleep + + The \a vos_sleep() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param msInterval - the number of milliseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep( v_U32_t msInterval ) +{ + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return; + } + msleep_interruptible(msInterval); +} + +/*---------------------------------------------------------------------------- + + \brief vos_sleep_us() - sleep + + The \a vos_sleep_us() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param usInterval - the number of microseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep_us( v_U32_t usInterval ) +{ + unsigned long timeout = usecs_to_jiffies(usInterval) + 1; + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return; + } + while (timeout && !signal_pending(current)) + timeout = schedule_timeout_interruptible(timeout); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_busy_wait() - busy wait + + The \a vos_busy_wait() function places the current thread in busy wait + until the specified time out interval elapses. If the interval is greater + than 50us on WM, the behaviour is undefined. + + \param usInterval - the number of microseconds to busy wait. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_busy_wait( v_U32_t usInterval ) +{ + udelay(usInterval); +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_timer.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_timer.c new file mode 100644 index 0000000000000..9ea7e721a410c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_timer.c @@ -0,0 +1,880 @@ +/* + * Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_timer.c + + \brief virtual Operating System Servies (vOS) + + Definitions for vOSS Timer services + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include "wlan_qct_sys.h" +#include "vos_sched.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define LINUX_TIMER_COOKIE 0x12341234 +#define LINUX_INVALID_TIMER_COOKIE 0xfeedface +#define TMR_INVALID_ID ( 0 ) + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +static unsigned int persistentTimerCount; +static vos_lock_t persistentTimerCountLock; +// static sleep_okts_handle sleepClientHandle; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +// TBD: Need to add code for deferred timers implementation + +// clean up timer states after it has been deactivated +// check and try to allow sleep after a timer has been stopped or expired +static void tryAllowingSleep( VOS_TIMER_TYPE type ) +{ + if ( VOS_TIMER_TYPE_WAKE_APPS == type ) + { + // vos_lock_acquire( &persistentTimerCountLock ); + persistentTimerCount--; + if ( 0 == persistentTimerCount ) + { + // since the number of persistent timers has decreased from 1 to 0, + // the timer should allow sleep + //sleep_assert_okts( sleepClientHandle ); + } + //vos_lock_release( &persistentTimerCountLock ); + } +} + + +/*---------------------------------------------------------------------------- + + \brief vos_linux_timer_callback() - internal vos entry point which is + called when the timer interval expires + + This function in turn calls the vOS client callback and changes the + state of the timer from running (ACTIVE) to expired (INIT). + + + \param data - pointer to the timer control block which describes the + timer that expired + + \return nothing + + Note: function signature is defined by the Linux kernel. The fact + that the argument is "unsigned long" instead of "void *" is + unfortunately imposed upon us. But we can safely pass a pointer via + this parameter for LP32 and LP64 architectures. + + --------------------------------------------------------------------------*/ + +static void vos_linux_timer_callback (unsigned long data) +{ + vos_timer_t *timer = ( vos_timer_t *)data; + vos_msg_t msg; + VOS_STATUS vStatus; + unsigned long flags; + + vos_timer_callback_t callback=NULL; + v_PVOID_t userData=NULL; + int threadId; + VOS_TIMER_TYPE type=VOS_TIMER_TYPE_SW; + + VOS_ASSERT(timer); + + if (timer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s Null pointer passed in!",__func__); + return; + } + + threadId = timer->platformInfo.threadID; + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + // we are in this state because someone just started the timer, MM timer + // got started and expired, but the time content have not bee updated + // this is a rare race condition! + timer->state = VOS_TIMER_STATE_STOPPED; + vStatus = VOS_STATUS_E_ALREADY; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_E_ALREADY; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_EXISTS; + break; + case VOS_TIMER_STATE_RUNNING: + // need to go to stop state here because the call-back function may restart + // timer (to emulate periodic timer) + timer->state = VOS_TIMER_STATE_STOPPED; + // copy the relevant timer information to local variables; + // once we exist from this critical section, the timer content may be modified + // by other tasks + callback = timer->callback; + userData = timer->userData; + threadId = timer->platformInfo.threadID; + type = timer->type; + vStatus = VOS_STATUS_SUCCESS; + break; + default: + VOS_ASSERT(0); + vStatus = VOS_STATUS_E_FAULT; + break; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + if ( VOS_STATUS_SUCCESS != vStatus ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "TIMER callback called in a wrong state=%d", timer->state); + return; + } + + tryAllowingSleep( type ); + + if (callback == NULL) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: No TIMER callback, Could not enqueue timer to any queue", + __func__); + return; + } + // If timer has expired then call vos_client specific callback + if ( vos_sched_is_tx_thread( threadId ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on TX thread"); + + //Serialize to the Tx thread + sysBuildMessageHeader( SYS_MSG_ID_TX_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_tx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } + else if ( vos_sched_is_rx_thread( threadId ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on RX thread"); + + //Serialize to the Rx thread + sysBuildMessageHeader( SYS_MSG_ID_RX_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_rx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on MC thread"); + + // Serialize to the MC thread + sysBuildMessageHeader( SYS_MSG_ID_MC_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_mq_post_message( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Could not enqueue timer to any queue", __func__); + VOS_ASSERT(0); +} + +/*--------------------------------------------------------------------------- + + \brief vos_timer_getCurrentState() - Get the current state of the timer + + \param pTimer - the timer object + + \return timer state + + \sa + +---------------------------------------------------------------------------*/ +VOS_TIMER_STATE vos_timer_getCurrentState( vos_timer_t *pTimer ) +{ + if ( NULL == pTimer ) + { + VOS_ASSERT(0); + return VOS_TIMER_STATE_UNUSED; + } + + switch ( pTimer->state ) + { + case VOS_TIMER_STATE_STOPPED: + case VOS_TIMER_STATE_STARTING: + case VOS_TIMER_STATE_RUNNING: + case VOS_TIMER_STATE_UNUSED: + return pTimer->state; + default: + VOS_ASSERT(0); + return VOS_TIMER_STATE_UNUSED; + } +} + +/*---------------------------------------------------------------------------- + + \brief vos_timer_module_init() - Initializes a vOSS timer module. + + This API initializes the VOSS timer module. This needs to be called + exactly once prior to using any VOSS timers. + + \sa + + --------------------------------------------------------------------------*/ + +void vos_timer_module_init( void ) +{ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Initializing the VOSS timer module"); + vos_lock_init( &persistentTimerCountLock ); +} + +#ifdef TIMER_MANAGER +#include "wlan_hdd_dp_utils.h" + +hdd_list_t vosTimerList; + +static void vos_timer_clean(void); + +void vos_timer_manager_init() +{ + /* Initalizing the list with maximum size of 60000 */ + hdd_list_init(&vosTimerList, 1000); + return; +} + +static void vos_timer_clean() +{ + v_SIZE_t listSize; + unsigned long flags; + + hdd_list_size(&vosTimerList, &listSize); + + if (listSize) + { + hdd_list_node_t* pNode; + VOS_STATUS vosStatus; + + timer_node_t *ptimerNode; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: List is not Empty. listSize %d ", + __func__, (int)listSize); + + do + { + spin_lock_irqsave(&vosTimerList.lock, flags); + vosStatus = hdd_list_remove_front(&vosTimerList, &pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if (VOS_STATUS_SUCCESS == vosStatus) + { + ptimerNode = (timer_node_t*)pNode; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Timer Leak@ File %s, @Line %d", + ptimerNode->fileName, (int)ptimerNode->lineNum); + + vos_mem_free(ptimerNode); + } + } while (vosStatus == VOS_STATUS_SUCCESS); + } +} + +void vos_timer_exit() +{ + vos_timer_clean(); + hdd_list_destroy(&vosTimerList); +} +#endif + +/*-------------------------------------------------------------------------- + + \brief vos_timer_init() - Initialize a vOSS timer. + + This API initializes a vOS Timer object. + + The \a vos_timer_init() initializes a vOS Timer object. A timer must be + initialized by calling vos_timer_initialize() before it may be used in + any other timer functions. + + Attempting to initialize timer that is already initialized results in + a failure. A destroyed timer object can be re-initialized with a call to + \a vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer such + as vos_timer_set() will fail if the timer is not initialized or has + been destroyed. Therefore, don't use the timer after it has been + destroyed until it has been re-initialized. + + All callback will be executed within the VOS main thread unless it is + initialized from the Tx thread flow, in which case it will be executed + within the tx thread flow. + + \param timer - pointer to the opaque timer object to initialize + + \param timerType - specifies the type of timer. We have two different + timer types. +
      +
    1. VOS_TIMER_TYPE_SW - Pure software timer. The Apps processor + may not be awoken when this timer expires. +
    2. VOS_TIMER_TYPE_WAKE_APPS - The Apps processor will be awoken + from power collapse when this type of timer expires. +
    + + \param callback - the callback function to be called when the timer + expires. + + \param userData - a user data (or context) that is returned to the + callback function as a parameter when the timer expires. + + \return VOS_STATUS_SUCCESS - timer was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the timer + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the timer + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to initialize the object referenced by timer, a previously + initialized but not yet destroyed timer. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +VOS_STATUS vos_timer_init_debug( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData, + char* fileName, v_U32_t lineNum ) +{ + VOS_STATUS vosStatus; + unsigned long flags; + // Check for invalid pointer + if ((timer == NULL) || (callback == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + timer->ptimerNode = vos_mem_malloc(sizeof(timer_node_t)); + + if(timer->ptimerNode == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for timeNode",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + vos_mem_set(timer->ptimerNode, sizeof(timer_node_t), 0); + + timer->ptimerNode->fileName = fileName; + timer->ptimerNode->lineNum = lineNum; + timer->ptimerNode->vosTimer = timer; + + spin_lock_irqsave(&vosTimerList.lock, flags); + vosStatus = hdd_list_insert_front(&vosTimerList, &timer->ptimerNode->pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if(VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); + } + + // set the various members of the timer structure + // with arguments passed or with default values + spin_lock_init(&timer->platformInfo.spinlock); + if (VOS_TIMER_TYPE_SW == timerType) + init_timer_deferrable(&(timer->platformInfo.Timer)); + else + init_timer(&(timer->platformInfo.Timer)); + timer->platformInfo.Timer.function = vos_linux_timer_callback; + timer->platformInfo.Timer.data = (unsigned long)timer; + timer->callback = callback; + timer->userData = userData; + timer->type = timerType; + timer->platformInfo.cookie = LINUX_TIMER_COOKIE; + timer->platformInfo.threadID = 0; + timer->state = VOS_TIMER_STATE_STOPPED; + + return VOS_STATUS_SUCCESS; +} +#else +VOS_STATUS vos_timer_init( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData ) +{ + // Check for invalid pointer + if ((timer == NULL) || (callback == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // set the various members of the timer structure + // with arguments passed or with default values + spin_lock_init(&timer->platformInfo.spinlock); + if (VOS_TIMER_TYPE_SW == timerType) + init_timer_deferrable(&(timer->platformInfo.Timer)); + else + init_timer(&(timer->platformInfo.Timer)); + timer->platformInfo.Timer.function = vos_linux_timer_callback; + timer->platformInfo.Timer.data = (unsigned long)timer; + timer->callback = callback; + timer->userData = userData; + timer->type = timerType; + timer->platformInfo.cookie = LINUX_TIMER_COOKIE; + timer->platformInfo.threadID = 0; + timer->state = VOS_TIMER_STATE_STOPPED; + + return VOS_STATUS_SUCCESS; +} +#endif + + +/*--------------------------------------------------------------------------- + + \brief vos_timer_destroy() - Destroy a vOSS Timer object + + The \a vos_timer_destroy() function shall destroy the timer object. + After a successful return from \a vos_timer_destroy() the timer + object becomes, in effect, uninitialized. + + A destroyed timer object can be re-initialized by calling + vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer, such + as vos_timer_set() will fail if the lock is destroyed. Therefore, + don't use the timer after it has been destroyed until it has + been re-initialized. + + \param timer - the timer object to be destroyed. + + \return VOS_STATUS_SUCCESS - timer was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by timer while it is still + still referenced. The timer must be stopped before it can be + destroyed. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +VOS_STATUS vos_timer_destroy ( vos_timer_t *timer ) +{ + VOS_STATUS vStatus=VOS_STATUS_SUCCESS; + unsigned long flags; + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null timer pointer being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy uninitialized timer",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + spin_lock_irqsave(&vosTimerList.lock, flags); + vStatus = hdd_list_remove_node(&vosTimerList, &timer->ptimerNode->pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if(vStatus != VOS_STATUS_SUCCESS) + { + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + vos_mem_free(timer->ptimerNode); + + + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + vStatus = VOS_STATUS_E_BUSY; + break; + case VOS_TIMER_STATE_RUNNING: + /* Stop the timer first */ + del_timer(&(timer->platformInfo.Timer)); + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_ALREADY; + break; + default: + vStatus = VOS_STATUS_E_FAULT; + break; + } + + if ( VOS_STATUS_SUCCESS == vStatus ) + { + timer->platformInfo.cookie = LINUX_INVALID_TIMER_COOKIE; + timer->state = VOS_TIMER_STATE_UNUSED; + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + return vStatus; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy timer in state = %d",__func__, timer->state); + VOS_ASSERT(0); + + return vStatus; +} + +#else +VOS_STATUS vos_timer_destroy ( vos_timer_t *timer ) +{ + VOS_STATUS vStatus=VOS_STATUS_SUCCESS; + unsigned long flags; + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null timer pointer being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy uninitialized timer",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + vStatus = VOS_STATUS_E_BUSY; + break; + case VOS_TIMER_STATE_RUNNING: + /* Stop the timer first */ + del_timer(&(timer->platformInfo.Timer)); + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_ALREADY; + break; + default: + vStatus = VOS_STATUS_E_FAULT; + break; + } + + if ( VOS_STATUS_SUCCESS == vStatus ) + { + timer->platformInfo.cookie = LINUX_INVALID_TIMER_COOKIE; + timer->state = VOS_TIMER_STATE_UNUSED; + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + return vStatus; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy timer in state = %d",__func__, timer->state); + VOS_ASSERT(0); + + return vStatus; +} +#endif + +/*-------------------------------------------------------------------------- + + \brief vos_timer_start() - Start a vOSS Timer object + + The \a vos_timer_start() function starts a timer to expire after the + specified interval, thus running the timer callback function when + the interval expires. + + A timer only runs once (a one-shot timer). To re-start the + timer, vos_timer_start() has to be called after the timer runs + or has been cancelled. + + \param timer - the timer object to be started + + \param expirationTime - expiration time for the timer (in milliseconds) + + \return VOS_STATUS_SUCCESS - timer was successfully started. + + VOS_STATUS_E_ALREADY - The implementation has detected an attempt + to start a timer while it is already started. The timer must + be stopped or expire before it can be started again. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_start( vos_timer_t *timer, v_U32_t expirationTime ) +{ + unsigned long flags; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "Timer Addr inside voss_start : 0x%p ", timer ); + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Null timer pointer being passed", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot start uninitialized timer",__func__); + if ( LINUX_INVALID_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_ASSERT(0); + } + return VOS_STATUS_E_INVAL; + } + + // Check if timer has expiration time less than 10 ms + if ( expirationTime < 10 ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot start a " + "timer with expiration less than 10 ms", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // make sure the remainer of the logic isn't interrupted + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + // Ensure if the timer can be started + if ( VOS_TIMER_STATE_STOPPED != timer->state ) + { + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Cannot start timer in state = %d ",__func__, timer->state); + return VOS_STATUS_E_ALREADY; + } + + // Start the timer + mod_timer( &(timer->platformInfo.Timer), + jiffies + msecs_to_jiffies(expirationTime)); + + timer->state = VOS_TIMER_STATE_RUNNING; + + // Get the thread ID on which the timer is being started + timer->platformInfo.threadID = current->pid; + + if ( VOS_TIMER_TYPE_WAKE_APPS == timer->type ) + { + persistentTimerCount++; + if ( 1 == persistentTimerCount ) + { + // Since we now have one persistent timer, we need to disallow sleep + // sleep_negate_okts( sleepClientHandle ); + } + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_stop() - Stop a vOSS Timer + + The \a vos_timer_stop() function stops a timer that has been started but + has not expired, essentially cancelling the 'start' request. + + After a timer is stopped, it goes back to the state it was in after it + was created and can be started again via a call to vos_timer_start(). + + \param timer - the timer object to be stopped + + \return VOS_STATUS_SUCCESS - timer was successfully stopped. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_stop ( vos_timer_t *timer ) +{ + unsigned long flags; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Timer Addr inside voss_stop : 0x%p",__func__,timer ); + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Null timer pointer being passed", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot stop uninitialized timer",__func__); + if ( LINUX_INVALID_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_ASSERT(0); + } + return VOS_STATUS_E_INVAL; + } + + // Ensure the timer state is correct + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + if ( VOS_TIMER_STATE_RUNNING != timer->state ) + { + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Cannot stop timer in state = %d", + __func__, timer->state); + return VOS_STATUS_SUCCESS; + } + + timer->state = VOS_TIMER_STATE_STOPPED; + + del_timer(&(timer->platformInfo.Timer)); + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + tryAllowingSleep( timer->type ); + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_ticks() - Get the system time in 10ms ticks + + The \a vos_timer_get_system_ticks() function returns the current number + of timer ticks in 10msec intervals. This function is suitable timestamping + and calculating time intervals by calculating the difference between two + timestamps. + + \returns - The current system tick count (in 10msec intervals). This + function cannot fail. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_ticks( v_VOID_t ) +{ + return( jiffies_to_msecs(jiffies) / 10 ); +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_time() - Get the system time in milliseconds + + The \a vos_timer_get_system_time() function returns the number of milliseconds + that have elapsed since the system was started + + \returns - The current system time in milliseconds. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_time( v_VOID_t ) +{ + struct timeval tv; + do_gettimeofday(&tv); + return tv.tv_sec*1000 + tv.tv_usec/1000; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_trace.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_trace.c new file mode 100644 index 0000000000000..6139a32f4deb3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_trace.c @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_trace.c + + \brief virtual Operating System Servies (vOS) + + Trace, logging, and debugging definitions and APIs + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 09/16/08 hvm Adding ability to set multiple trace levels per component + 09/11/08 lac Added trace levels per component. Cleanup from review. + 08/14/08 vpai Particular modules and desired level can be selected + 06/20/08 vpai Created Module +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include "adf_os_time.h" +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define VOS_TRACE_BUFFER_SIZE ( 512 ) + +// macro to map vos trace levels into the bitmask +#define VOS_TRACE_LEVEL_TO_MODULE_BITMASK( _level ) ( ( 1 << (_level) ) ) + +typedef struct +{ + // Trace level for a module, as a bitmask. The bits in this mask + // are ordered by VOS_TRACE_LEVEL. For example, each bit represents + // one of the bits in VOS_TRACE_LEVEL that may be turned on to have + // traces at that level logged, i.e. if VOS_TRACE_LEVEL_ERROR is + // == 2, then if bit 2 (low order) is turned ON, then ERROR traces + // will be printed to the trace log. + // + // Note that all bits turned OFF means no traces. + v_U16_t moduleTraceLevel; + + // 3 character string name for the module + unsigned char moduleNameStr[ 4 ]; // 3 chars plus the NULL + +} moduleTraceInfo; + +#define VOS_DEFAULT_TRACE_LEVEL \ + ((1<= VOS_TRACE_LEVEL_MAX ) + { + pr_err("%s: Invalid trace level %d passed in!\n", __func__, level); + return; + } + + // Treat 'none' differently. NONE means we have to run off all + // the bits in the bit mask so none of the traces appear. Anything other + // than 'none' means we need to turn ON a bit in the bitmask. + if ( VOS_TRACE_LEVEL_NONE == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE; + } + else + { + // Set the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ); + } +} + +void vos_trace_setValue( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, v_U8_t on) +{ + // Make sure the caller is passing in a valid LEVEL. + if ( level < 0 || level >= VOS_TRACE_LEVEL_MAX ) + { + pr_err("%s: Invalid trace level %d passed in!\n", __func__, level); + return; + } + + // Make sure the caller is passing in a valid module. + if ( module < 0 || module >= VOS_MODULE_ID_MAX ) + { + pr_err("%s: Invalid module id %d passed in!\n", __func__, module); + return; + } + + // Treat 'none' differently. NONE means we have to turn off all + // the bits in the bit mask so none of the traces appear. + if ( VOS_TRACE_LEVEL_NONE == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE; + } + // Treat 'All' differently. All means we have to turn on all + // the bits in the bit mask so all of the traces appear. + else if ( VOS_TRACE_LEVEL_ALL == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = 0xFFFF; + } + + else + { + if (on) + // Set the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ); + else + // Clear the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel &= ~(VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level )); + } +} + + +v_BOOL_t vos_trace_getLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ) +{ + v_BOOL_t traceOn = VOS_FALSE; + + if ( ( VOS_TRACE_LEVEL_NONE == level ) || + ( VOS_TRACE_LEVEL_ALL == level ) || + ( level >= VOS_TRACE_LEVEL_MAX ) ) + { + traceOn = VOS_FALSE; + } + else + { + traceOn = ( level & gVosTraceInfo[ module ].moduleTraceLevel ) ? VOS_TRUE : VOS_FALSE; + } + + return( traceOn ); +} + +void vos_snprintf(char *strBuffer, unsigned int size, char *strFormat, ...) +{ + va_list val; + + va_start( val, strFormat ); + snprintf (strBuffer, size, strFormat, val); + va_end( val ); +} + +#ifdef VOS_ENABLE_TRACING + +/*---------------------------------------------------------------------------- + + \brief vos_trace_msg() - Externally called trace function + + Checks the level of severity and accordingly prints the trace messages + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +void vos_trace_msg( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, char *strFormat, ... ) +{ + char strBuffer[VOS_TRACE_BUFFER_SIZE]; + int n; + + // Print the trace message when the desired level bit is set in the module + // tracel level mask. + if ( gVosTraceInfo[ module ].moduleTraceLevel & VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) + { + // the trace level strings in an array. these are ordered in the same order + // as the trace levels are defined in the enum (see VOS_TRACE_LEVEL) so we + // can index into this array with the level and get the right string. The + // vos trace levels are... + // none, Fatal, Error, Warning, Info, InfoHigh, InfoMed, InfoLow, Debug + static const char * TRACE_LEVEL_STR[] = { " ", "F ", "E ", "W ", "I ", "IH", "IM", "IL", "D" }; + va_list val; + va_start(val, strFormat); + + // print the prefix string into the string buffer... + n = snprintf(strBuffer, VOS_TRACE_BUFFER_SIZE, "wlan: [%d:%2s:%3s] ", + in_interrupt() ? 0 : current->pid, + (char *) TRACE_LEVEL_STR[ level ], + (char *) gVosTraceInfo[ module ].moduleNameStr ); + + // print the formatted log message after the prefix string. + if ((n >= 0) && (n < VOS_TRACE_BUFFER_SIZE)) + { + vsnprintf(strBuffer + n, VOS_TRACE_BUFFER_SIZE - n, strFormat, val ); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_log_to_user(level, (char *)strBuffer, strlen(strBuffer)); +#else + pr_err("%s\n", strBuffer); +#endif + } + va_end(val); + } +} + +void vos_trace_display(void) +{ + VOS_MODULE_ID moduleId; + + pr_err(" 1)FATAL 2)ERROR 3)WARN 4)INFO 5)INFO_H 6)INFO_M 7)INFO_L 8)DEBUG\n"); + for (moduleId = 0; moduleId < VOS_MODULE_ID_MAX; ++moduleId) + { + pr_err("%2d)%s %s %s %s %s %s %s %s %s\n", + (int)moduleId, + gVosTraceInfo[moduleId].moduleNameStr, + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_FATAL)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_ERROR)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_WARN)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_HIGH)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_MED)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_LOW)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_DEBUG)) ? "X":" " + ); + } +} + +/*---------------------------------------------------------------------------- + + \brief vos_trace_hex_dump() - Externally called hex dump function + + Checks the level of severity and accordingly prints the trace messages + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param data - . The base address of the buffer to be logged. + + \param buf_len - . The size of the buffer to be logged. + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + void *data, int buf_len ) +{ + char *buf = (char *)data; + int i; + + if (!(gVosTraceInfo[module].moduleTraceLevel & + VOS_TRACE_LEVEL_TO_MODULE_BITMASK(level))) + return; + + for (i=0; (i+15)< buf_len; i+=16) + { + vos_trace_msg( module, level, + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + buf[i], + buf[i+1], + buf[i+2], + buf[i+3], + buf[i+4], + buf[i+5], + buf[i+6], + buf[i+7], + buf[i+8], + buf[i+9], + buf[i+10], + buf[i+11], + buf[i+12], + buf[i+13], + buf[i+14], + buf[i+15]); + } + + // Dump the bytes in the last line + for (; i < buf_len; i++) + { + vos_trace_msg( module, level, "%02x ", buf[i]); + } + +} + +#endif + +/*----------------------------------------------------------------------------- + \brief vosTraceEnable() - Enable MTRACE for specific modules whose bits are + set in bitmask and enable is true. if enable is false it disables MTRACE for + that module. set the bitmask according to enum value of the modules. + + this functions will be called when you issue ioctl as mentioned following + [iwpriv wlan0 setdumplog ]. + - Decimal number, i.e. 64 decimal value shows only SME module, + 128 decimal value shows only PE module, 192 decimal value shows PE and SME. + + \param - bitmask_of_moduleId - as explained above set bitmask according to + enum of the modules. + 32 [dec] = 0010 0000 [bin] + 64 [dec] = 0100 0000 [bin] + 128 [dec] = 1000 0000 [bin] + \param - enable - can be true or false. + True implies enabling MTRACE, false implies disabling MTRACE. + ---------------------------------------------------------------------------*/ +void vosTraceEnable(v_U32_t bitmask_of_moduleId, v_U8_t enable) +{ + int i; + if (bitmask_of_moduleId) + { + for (i = 0; i < VOS_MODULE_ID_MAX; i++) + { + if (((bitmask_of_moduleId >> i) & 1 )) + { + if (enable) + { + if (NULL != vostraceRestoreCBTable[i]) + { + vostraceCBTable[i] = vostraceRestoreCBTable[i]; + } + } + else + { + vostraceRestoreCBTable[i] = vostraceCBTable[i]; + vostraceCBTable[i] = NULL; + } + } + } + } + else + { + if (enable) + { + for (i = 0; i < VOS_MODULE_ID_MAX; i++) + { + if (NULL != vostraceRestoreCBTable[i]) + { + vostraceCBTable[i] = vostraceRestoreCBTable[i]; + } + } + } + else + { + for (i = 0; i < VOS_MODULE_ID_MAX; i++) + { + vostraceRestoreCBTable[i] = vostraceCBTable[i]; + vostraceCBTable[i] = NULL; + } + } + } +} + +/*----------------------------------------------------------------------------- + \brief vosTraceInit() - Initializes vos trace structures and variables. + + Called immediately after vos_preopen, so that we can start recording HDD + events ASAP. + ----------------------------------------------------------------------------*/ +void vosTraceInit() +{ + v_U8_t i; + gvosTraceData.head = INVALID_VOS_TRACE_ADDR; + gvosTraceData.tail = INVALID_VOS_TRACE_ADDR; + gvosTraceData.num = 0; + gvosTraceData.enable = TRUE; + gvosTraceData.dumpCount = DEFAULT_VOS_TRACE_DUMP_COUNT; + gvosTraceData.numSinceLastDump = 0; + + for (i=0; i MAX_VOS_TRACE_RECORDS) + { + gvosTraceData.num = MAX_VOS_TRACE_RECORDS; + } + + if (INVALID_VOS_TRACE_ADDR == gvosTraceData.head) + { + /* first record */ + gvosTraceData.head = 0; + gvosTraceData.tail = 0; + } + else + { + /* queue is not empty */ + v_U32_t tail = gvosTraceData.tail + 1; + + if (MAX_VOS_TRACE_RECORDS == tail) + { + tail = 0; + } + + if (gvosTraceData.head == tail) + { + /* full */ + if (MAX_VOS_TRACE_RECORDS == ++gvosTraceData.head) + { + gvosTraceData.head = 0; + } + } + + gvosTraceData.tail = tail; + } + + rec = &gvosTraceTbl[gvosTraceData.tail]; + rec->code = code; + rec->session = session; + rec->data = data; + rec->time = adf_get_boottime(); + rec->module = module; + rec->pid = (in_interrupt() ? 0 : current->pid); + gvosTraceData.numSinceLastDump ++; + spin_unlock_irqrestore(<raceLock, flags); +} + + +/*----------------------------------------------------------------------------- + \brief vos_trace_spin_lock_init() - Initializes the lock variable before use + + This function will be called from vos_preOpen, we will have lock available + to use ASAP. + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_trace_spin_lock_init() +{ + spin_lock_init(<raceLock); + + return VOS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------- + \brief vosTraceRegister() - Registers the call back functions to display the + messages in particular format mentioned in these call back functions. + + this functions should be called by interested module in their init part as + we will be ready to register as soon as modules are up. + + \param moduleID - enum value of module + \param vostraceCb - call back functions to display the messages in particular + format. + ----------------------------------------------------------------------------*/ +void vosTraceRegister(VOS_MODULE_ID moduleID, tpvosTraceCb vostraceCb) +{ + vostraceCBTable[moduleID] = vostraceCb; +} + +/*------------------------------------------------------------------------------ + \brief vosTraceDumpAll() - Dump data from ring buffer via call back functions + registered with VOSS + + This function will be called up on issueing ioctl call as mentioned following + [iwpriv wlan0 dumplog 0 0 ] + + - number lines to dump starting from tail to head. + + - if anybody wants to know how many messages were recorded + for particular module/s mentioned by setbit in bitmask from last messages. + it is optional, if you don't provide then it will dump everything from buffer. + + \param pMac - context of particular module + \param code - + \param session - + \param count - number of lines to dump starting from tail to head + ----------------------------------------------------------------------------*/ +void vosTraceDumpAll(void *pMac, v_U8_t code, v_U8_t session, + v_U32_t count, v_U32_t bitmask_of_module) +{ + tvosTraceRecord pRecord; + tANI_S32 i, tail; + + + if (!gvosTraceData.enable) + { + VOS_TRACE( VOS_MODULE_ID_SYS, + VOS_TRACE_LEVEL_ERROR, "Tracing Disabled"); + return; + } + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Total Records: %d, Head: %d, Tail: %d", + gvosTraceData.num, gvosTraceData.head, gvosTraceData.tail); + + /* Aquire the lock so that only one thread at a time can read the ring buffer */ + spin_lock(<raceLock); + + if (gvosTraceData.head != INVALID_VOS_TRACE_ADDR) + { + i = gvosTraceData.head; + tail = gvosTraceData.tail; + + if (count) + { + if (count > gvosTraceData.num) + { + count = gvosTraceData.num; + } + if (tail >= (count - 1)) + { + i = tail - count + 1; + } + else if (count != MAX_VOS_TRACE_RECORDS) + { + i = MAX_VOS_TRACE_RECORDS - ((count - 1) - tail); + } + } + + pRecord = gvosTraceTbl[i]; + /* right now we are not using numSinceLastDump member but in future + we might re-visit and use this member to track how many latest + messages got added while we were dumping from ring buffer */ + gvosTraceData.numSinceLastDump = 0; + spin_unlock(<raceLock); + for (;;) + { + if ((code == 0 || (code == pRecord.code)) && + (vostraceCBTable[pRecord.module] != NULL)) + { + if (0 == bitmask_of_module) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + else + { + if (bitmask_of_module & (1 << pRecord.module)) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + } + } + + if (i == tail) + { + break; + } + i += 1; + + spin_lock(<raceLock); + if (MAX_VOS_TRACE_RECORDS == i) + { + i = 0; + pRecord= gvosTraceTbl[0]; + } + else + { + pRecord = gvosTraceTbl[i]; + } + spin_unlock(<raceLock); + } + } + else + { + spin_unlock(<raceLock); + } +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_types.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_types.c new file mode 100644 index 0000000000000..b7182162ba11d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_types.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/**========================================================================= + + \file vos_Types.c + + \brief virtual Operating System Servies (vOS) + + Basic type definitions + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_trace.h" + +//#include "wlan_libra_config.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_set - set a variable atomically + + \param pTarget - pointer to the uintptr_t to set. + + \param value - the value to set in the uintptr_t variable. + + \return This function returns the value previously in the uintptr_t before + the new value is set. + + \sa vos_atomic_increment_U32(), vos_atomic_decrement_U32() + + --------------------------------------------------------------------------*/ +uintptr_t vos_atomic_set( uintptr_t *pTarget, uintptr_t value ) +{ + uintptr_t oldval; + unsigned long flags; + + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + oldval = *pTarget; + *pTarget = value; + local_irq_restore(flags); + // v_U32_t prev = atomic_read(pTarget); + // atomic_set(pTarget, value); + return oldval; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32() - Increment a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to increment. + + \return This function returns the value of the variable after the + increment occurs. + + \sa vos_atomic_decrement_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32( v_U32_t *pTarget ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + ++*pTarget; + local_irq_restore(flags); + return *pTarget; + // return atomic_inc_return(pTarget); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32() - Decrement a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to decrement. + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32( v_U32_t *pTarget ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + // return atomic_dec_return(pTarget); + local_irq_save(flags); + --*pTarget; + local_irq_restore(flags); + return (*pTarget); +} + +v_U32_t vos_atomic_increment_U32_by_value( v_U32_t *pTarget, v_U32_t value ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + *pTarget += value ; + local_irq_restore(flags); + return (*pTarget); +} + +v_U32_t vos_atomic_decrement_U32_by_value( v_U32_t *pTarget, v_U32_t value ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + *pTarget -= value ; + local_irq_restore(flags); + return (*pTarget); + +} + + +v_U32_t vos_get_skip_ssid_check(void) +{ +/**This is needed by only AMSS for interoperatability **/ + + return 1; +} + + +v_U32_t vos_get_skip_11e_check(void) +{ + /* this is needed only for AMSS for interopratability **/ + return 1; +} diff --git a/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_utils.c b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_utils.c new file mode 100644 index 0000000000000..9c29ec4f420e0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/VOSS/src/vos_utils.c @@ -0,0 +1,1226 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +/*============================================================================ + FILE: vos_utils.c + + OVERVIEW: This source file contains definitions for vOS crypto APIs + The four APIs mentioned in this file are used for + initializing, and de-initializing a crypto context, and + obtaining truly random data (for keys), as well as + SHA1 HMAC, and AES encrypt and decrypt routines. + + The routines include: + vos_crypto_init() - Initializes Crypto module + vos_crypto_deinit() - De-initializes Crypto module + vos_rand_get_bytes() - Generates random byte + vos_sha1_hmac_str() - Generate the HMAC-SHA1 of a string given a key + vos_encrypt_AES() - Generate AES Encrypted byte stream + vos_decrypt_AES() - Decrypts an AES Encrypted byte stream + + DEPENDENCIES: +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include "vos_trace.h" +#include "vos_utils.h" +#include "vos_memory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CNSS +#include +#endif + +#include "ieee80211_common.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define AAD_LEN 20 +#define IV_SIZE_AES_128 16 +#define CMAC_IPN_LEN 6 + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ +#ifndef CONFIG_CNSS +#if defined(WLAN_FEATURE_11W) && (defined(HIF_USB) || defined(HIF_SDIO)) +#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ + +static inline void xor_128(const u8 *a, const u8 *b, u8 *out) +{ + u8 i; + + for (i = 0; i < AES_BLOCK_SIZE; i++) + out[i] = a[i] ^ b[i]; +} + +static inline void leftshift_onebit(const u8 *input, u8 *output) +{ + int i, overflow = 0; + + for (i = (AES_BLOCK_SIZE - 1); i >= 0; i--) { + output[i] = input[i] << 1; + output[i] |= overflow; + overflow = (input[i] & 0x80) ? 1 : 0; + } + return; +} + +static void generate_subkey(struct crypto_cipher *tfm, u8 *k1, u8 *k2) +{ + u8 l[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; + u8 const_rb[AES_BLOCK_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; + u8 const_zero[AES_BLOCK_SIZE] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + crypto_cipher_encrypt_one(tfm, l, const_zero); + + if ((l[0] & 0x80) == 0) { /* If MSB(l) = 0, then k1 = l << 1 */ + leftshift_onebit(l, k1); + } else { /* Else k1 = ( l << 1 ) (+) Rb */ + leftshift_onebit(l, tmp); + xor_128(tmp, const_rb, k1); + } + + if ((k1[0] & 0x80) == 0) { + leftshift_onebit(k1, k2); + } else { + leftshift_onebit(k1, tmp); + xor_128(tmp, const_rb, k2); + } +} + +static inline void padding(u8 *lastb, u8 *pad, u16 length) +{ + u8 j; + + /* original last block */ + for (j = 0; j < AES_BLOCK_SIZE; j++) { + if (j < length) + pad[j] = lastb[j]; + else if (j == length) + pad[j] = 0x80; + else + pad[j] = 0x00; + } +} + +void cmac_calc_mic(struct crypto_cipher *tfm, u8 *m, + u16 length, u8 *mac) +{ + u8 x[AES_BLOCK_SIZE], y[AES_BLOCK_SIZE]; + u8 m_last[AES_BLOCK_SIZE], padded[AES_BLOCK_SIZE]; + u8 k1[AES_KEYSIZE_128], k2[AES_KEYSIZE_128]; + int cmpBlk; + int i, nBlocks = (length + 15)/AES_BLOCK_SIZE; + + generate_subkey(tfm, k1, k2); + + if (nBlocks == 0) { + nBlocks = 1; + cmpBlk = 0; + } else { + cmpBlk = ((length % AES_BLOCK_SIZE) == 0) ? 1 : 0; + } + + if (cmpBlk) { /* Last block is complete block */ + xor_128(&m[AES_BLOCK_SIZE * (nBlocks - 1)], k1, m_last); + } else { /* Last block is not complete block */ + padding(&m[AES_BLOCK_SIZE * (nBlocks - 1)], padded, + length % AES_BLOCK_SIZE); + xor_128(padded, k2, m_last); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + x[i] = 0; + + for (i = 0; i < (nBlocks - 1); i++) { + xor_128(x, &m[AES_BLOCK_SIZE * i], y); /* y = Mi (+) x */ + crypto_cipher_encrypt_one(tfm, x, y); /* x = AES-128(KEY, y) */ + } + + xor_128(x, m_last, y); + crypto_cipher_encrypt_one(tfm, x, y); + + memcpy(mac, x, CMAC_TLEN); +} +#endif +#endif + +/*-------------------------------------------------------------------------- + + \brief vos_crypto_init() - Initializes Crypto module + + The vos_crypto_init() function initializes Crypto module. + + \param phCryptProv - pointer to the Crypt handle + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + + // This implementation doesn't require a crypto context + *phCryptProv = 0; + uResult = VOS_STATUS_SUCCESS; + return ( uResult ); +} + +VOS_STATUS vos_crypto_deinit( v_U32_t hCryptProv ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + + // CryptReleaseContext succeeded + uResult = VOS_STATUS_SUCCESS; + + return ( uResult ); +} + +/*-------------------------------------------------------------------------- + + \brief vos_rand_get_bytes() - Generates random byte + + The vos_rand_get_bytes() function generate random bytes. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_rand_get_bytes( v_U32_t cryptHandle, v_U8_t *pbBuf, v_U32_t numBytes ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + + //check for invalid pointer + if ( NULL == pbBuf ) + { + uResult = VOS_STATUS_E_FAULT; + return ( uResult ); + } + + get_random_bytes( pbBuf, numBytes); + // "Random sequence generated." + uResult = VOS_STATUS_SUCCESS; + return ( uResult ); +} + + +#ifdef WLAN_FEATURE_11W +v_U8_t vos_get_mmie_size() +{ + return sizeof(struct ieee80211_mmie); +} + +/*-------------------------------------------------------------------------- + + \brief vos_increase_seq() - Increase the IPN aka Sequence number by one unit + + The vos_increase_seq() function increases the IPN by one unit. + + \param ipn - pointer to the IPN aka Sequence number [6 bytes] + + --------------------------------------------------------------------------*/ +static void +vos_increase_seq(v_U8_t *ipn) +{ + v_U64_t value = 0; + if (ipn) + { + value = (0xffffffffffff)& (*((v_U64_t *)ipn)); + value = value + 1; + vos_mem_copy(ipn, &value, IEEE80211_MMIE_IPNLEN); + } +} + +/*-------------------------------------------------------------------------- + + \brief vos_attach_mmie() - attches the complete MMIE at the end of frame + + The vos_attach_mmie() calculates the entire MMIE and attaches at the end + of Broadcast/Multicast robust management frames. + + \param igtk - pointer group key which will be used to calculate + the 8 byte MIC. + \param ipn - pointer ipn, it is also known as sequence number + \param key_id - key identication number + \param frm - pointer to the start of the frame. + \param efrm - pointer to the end of the frame. + \param frmLen - size of the entire frame. + + \return - this function will return VOS_TRUE on success and VOS_FALSE on + failure. + + --------------------------------------------------------------------------*/ + +v_BOOL_t +vos_attach_mmie(v_U8_t *igtk, v_U8_t *ipn, u_int16_t key_id, + v_U8_t* frm, v_U8_t* efrm, u_int16_t frmLen) +{ + struct ieee80211_mmie *mmie; + struct ieee80211_frame *wh; + v_U8_t aad[AAD_LEN], mic[CMAC_TLEN], *input = NULL; + v_U8_t previous_ipn[IEEE80211_MMIE_IPNLEN] = {0}; + v_U16_t nBytes = 0; + int ret = 0; + struct crypto_cipher *tfm; + + /* This is how received frame look like + * + * <------------frmLen----------------------------> + * + * +---------------+----------------------+-------+ + * | 802.11 HEADER | Management framebody | MMIE | + * +---------------+----------------------+-------+ + * ^ + * | + * efrm + * This is how MMIE from above frame look like + * + * + * <------------ 18 Bytes-----------------------------> + * +--------+---------+---------+-----------+---------+ + * |Element | Length | Key id | IPN | MIC | + * | id | | | | | + * +--------+---------+---------+-----------+---------+ + * Octet 1 1 2 6 8 + * + */ + + /* Check if frame is invalid length */ + if (((efrm - frm) != frmLen) || (frmLen < sizeof(*wh))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid frame length", __func__); + return VOS_FALSE; + } + mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie)); + + /* Copy Element id */ + mmie->element_id = IEEE80211_ELEMID_MMIE; + + /* Copy Length */ + mmie->length = sizeof(*mmie)-2; + + /* Copy Key id */ + mmie->key_id = key_id; + + /* + * In case of error, revert back to original IPN + * to do that copy the original IPN into previous_ipn + */ + vos_mem_copy(&previous_ipn[0], ipn, IEEE80211_MMIE_IPNLEN); + vos_increase_seq(ipn); + vos_mem_copy(mmie->sequence_number, ipn, IEEE80211_MMIE_IPNLEN); + + /* + * Calculate MIC and then copy + */ +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC); +#else + tfm = wcnss_wlan_crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC); +#endif + if (IS_ERR(tfm)) + { + ret = PTR_ERR(tfm); + tfm = NULL; + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, + "%s: crypto_alloc_cipher failed (%d)", __func__, ret); + goto err_tfm; + } + + ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, + "%s: crypto_cipher_setkey failed (%d)", __func__, ret); + goto err_tfm; + } + + /* Construct AAD */ + wh = (struct ieee80211_frame *)frm; + + /* Generate BIP AAD: FC(masked) || A1 || A2 || A3 */ + + /* FC type/subtype */ + aad[0] = wh->i_fc[0]; + /* Mask FC Retry, PwrMgt, MoreData flags to zero */ + aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT | + IEEE80211_FC1_MORE_DATA); + /* A1 || A2 || A3 */ + vos_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN); + + /* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */ + nBytes = AAD_LEN + (frmLen - sizeof(struct ieee80211_frame)); + input = (v_U8_t *)vos_mem_malloc(nBytes); + if (NULL == input) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation failed", __func__); + ret = VOS_STATUS_E_NOMEM; + goto err_tfm; + } + + /* + * Copy the AAD, Management frame body, and + * MMIE with 8 bit MIC zeroed out + */ + vos_mem_zero(input, nBytes); + vos_mem_copy(input, aad, AAD_LEN); + /* Copy Management Frame Body and MMIE without MIC*/ + vos_mem_copy(input+AAD_LEN, + (v_U8_t*)(efrm-(frmLen-sizeof(struct ieee80211_frame))), + nBytes - AAD_LEN - CMAC_TLEN); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + cmac_calc_mic(tfm, input, nBytes, mic); +#else + wcnss_wlan_cmac_calc_mic(tfm, input, nBytes, mic); +#endif + vos_mem_free(input); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X", + mic[0], mic[1], mic[2], mic[3], + mic[4], mic[5], mic[6], mic[7]); + vos_mem_copy(mmie->mic, mic, IEEE80211_MMIE_MICLEN); + + +err_tfm: + if (ret) + { + vos_mem_copy(ipn, previous_ipn, IEEE80211_MMIE_IPNLEN); + } + + if (tfm) +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_cipher(tfm); +#else + wcnss_wlan_crypto_free_cipher(tfm); +#endif + return !ret?VOS_TRUE:VOS_FALSE; +} + +v_BOOL_t vos_is_mmie_valid(v_U8_t *igtk, v_U8_t *ipn, + v_U8_t* frm, v_U8_t* efrm) +{ + struct ieee80211_mmie *mmie; + struct ieee80211_frame *wh; + v_U8_t *rx_ipn, aad[AAD_LEN], mic[CMAC_TLEN], *input; + v_U16_t nBytes = 0; + int ret = 0; + struct crypto_cipher *tfm; + + /* Check if frame is invalid length */ + if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Invalid frame length"); + return VOS_FALSE; + } + + mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie)); + + /* Check Element ID */ + if ((mmie->element_id != IEEE80211_ELEMID_MMIE) || + (mmie->length != (sizeof(*mmie)-2))) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "IE is not Mgmt MIC IE or Invalid length"); + /* IE is not Mgmt MIC IE or invalid length */ + return VOS_FALSE; + } + + /* Validate IPN */ + rx_ipn = mmie->sequence_number; + if (OS_MEMCMP(rx_ipn, ipn, CMAC_IPN_LEN) <= 0) + { + /* Replay error */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Replay error mmie ipn %02X %02X %02X %02X %02X %02X" + " drvr ipn %02X %02X %02X %02X %02X %02X", + rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4], rx_ipn[5], + ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]); + return VOS_FALSE; + } + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC); +#else + tfm = wcnss_wlan_crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC); +#endif + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + tfm = NULL; + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, + "crypto_alloc_cipher failed (%d)", ret); + goto err_tfm; + } + + ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, + "crypto_cipher_setkey failed (%d)", ret); + goto err_tfm; + } + + /* Construct AAD */ + wh = (struct ieee80211_frame *)frm; + + /* Generate BIP AAD: FC(masked) || A1 || A2 || A3 */ + + /* FC type/subtype */ + aad[0] = wh->i_fc[0]; + /* Mask FC Retry, PwrMgt, MoreData flags to zero */ + aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT | + IEEE80211_FC1_MORE_DATA); + /* A1 || A2 || A3 */ + vos_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN); + + /* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */ + nBytes = AAD_LEN + (efrm - (v_U8_t*)(wh+1)); + input = (v_U8_t *)vos_mem_malloc(nBytes); + if (NULL == input) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failed"); + ret = VOS_STATUS_E_NOMEM; + goto err_tfm; + } + + /* Copy the AAD, MMIE with 8 bit MIC zeroed out */ + vos_mem_zero(input, nBytes); + vos_mem_copy(input, aad, AAD_LEN); + vos_mem_copy(input+AAD_LEN, (v_U8_t*)(wh+1), nBytes - AAD_LEN - CMAC_TLEN); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + cmac_calc_mic(tfm, input, nBytes, mic); +#else + wcnss_wlan_cmac_calc_mic(tfm, input, nBytes, mic); +#endif + vos_mem_free(input); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X", + mic[0], mic[1], mic[2], mic[3], + mic[4], mic[5], mic[6], mic[7]); + + if (OS_MEMCMP(mic, mmie->mic, CMAC_TLEN) != 0) { + /* MMIE MIC mismatch */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "BC/MC MGMT frame MMIE MIC check Failed" + " rmic %02X %02X %02X %02X %02X %02X %02X %02X" + " cmic %02X %02X %02X %02X %02X %02X %02X %02X", + mmie->mic[0], mmie->mic[1], mmie->mic[2], mmie->mic[3], + mmie->mic[4], mmie->mic[5], mmie->mic[6], mmie->mic[7], + mic[0], mic[1], mic[2], mic[3], + mic[4], mic[5], mic[6], mic[7]); + return VOS_FALSE; + } + + /* Update IPN */ + vos_mem_copy(ipn, rx_ipn, CMAC_IPN_LEN); + +err_tfm: + if (tfm) +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_cipher(tfm); +#else + wcnss_wlan_crypto_free_cipher(tfm); +#endif + + return !ret?VOS_TRUE:VOS_FALSE; +} + +#endif /* WLAN_FEATURE_11W */ +/** + * vos_sha1_hmac_str + * + * FUNCTION: + * Generate the HMAC-SHA1 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant SHA1 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ + +struct hmac_sha1_result { + struct completion completion; + int err; +}; + +static void hmac_sha1_complete(struct crypto_async_request *req, int err) +{ + struct hmac_sha1_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + +int hmac_sha1(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize, + v_U8_t *output, v_U8_t outlen) +{ + int ret = 0; + struct crypto_ahash *tfm; + struct scatterlist sg; + struct ahash_request *req; + struct hmac_sha1_result tresult; + void *hash_buff = NULL; + + unsigned char hash_result[64]; + int i; + + memset(output, 0, outlen); + + init_completion(&tresult.completion); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_ahash("hmac(sha1)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); +#else + tfm = wcnss_wlan_crypto_alloc_ahash("hmac(sha1)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); +#endif + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(sha1)"); + ret = -ENOMEM; + goto err_req; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + hmac_sha1_complete, &tresult); + + hash_buff = kzalloc(psize, GFP_KERNEL); + if (!hash_buff) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff"); + ret = -ENOMEM; + goto err_hash_buf; + } + + memset(hash_result, 0, 64); + memcpy(hash_buff, plaintext, psize); + sg_init_one(&sg, hash_buff, psize); + + if (ksize) { + crypto_ahash_clear_flags(tfm, ~0); +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ret = crypto_ahash_setkey(tfm, key, ksize); +#else + ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize); +#endif + + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed"); + goto err_setkey; + } + } + + ahash_request_set_crypt(req, &sg, hash_result, psize); +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ret = crypto_ahash_digest(req); +#else + ret = wcnss_wlan_crypto_ahash_digest(req); +#endif + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret); + + switch (ret) { + case 0: + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible(&tresult.completion); + if (!ret && !tresult.err) { + INIT_COMPLETION(tresult.completion); + break; + } else { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed"); + if (!ret) + ret = tresult.err; + goto out; + } + default: + goto out; + } + +out: +err_setkey: + kfree(hash_buff); +err_hash_buf: + ahash_request_free(req); +err_req: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_ahash(tfm); +#else + wcnss_wlan_crypto_free_ahash(tfm); +#endif +err_tfm: + return ret; +} + +VOS_STATUS vos_sha1_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *pKey, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_SHA1_SIZE])/* caller digest to be filled in */ +{ + int ret = 0; + + ret = hmac_sha1( + pKey, //v_U8_t *key, + (v_U8_t) keyLen, //v_U8_t ksize, + (char *)pText, //char *plaintext, + (v_U8_t) textLen, //v_U8_t psize, + digest, //v_U8_t *output, + VOS_DIGEST_SHA1_SIZE //v_U8_t outlen + ); + + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_sha1() call failed"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +/** + * vos_md5_hmac_str + * + * FUNCTION: + * Generate the HMAC-MD5 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant MD5 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +struct hmac_md5_result { + struct completion completion; + int err; +}; + +static void hmac_md5_complete(struct crypto_async_request *req, int err) +{ + struct hmac_md5_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + +int hmac_md5(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize, + v_U8_t *output, v_U8_t outlen) +{ + int ret = 0; + struct crypto_ahash *tfm; + struct scatterlist sg; + struct ahash_request *req; + struct hmac_md5_result tresult = {.err = 0}; + void *hash_buff = NULL; + + unsigned char hash_result[64]; + int i; + + memset(output, 0, outlen); + + init_completion(&tresult.completion); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_ahash("hmac(md5)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); +#else + tfm = wcnss_wlan_crypto_alloc_ahash("hmac(md5)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); +#endif + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(md5)"); + ret = -ENOMEM; + goto err_req; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + hmac_md5_complete, &tresult); + + hash_buff = kzalloc(psize, GFP_KERNEL); + if (!hash_buff) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff"); + ret = -ENOMEM; + goto err_hash_buf; + } + + memset(hash_result, 0, 64); + memcpy(hash_buff, plaintext, psize); + sg_init_one(&sg, hash_buff, psize); + + if (ksize) { + crypto_ahash_clear_flags(tfm, ~0); +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ret = crypto_ahash_setkey(tfm, key, ksize); +#else + ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize); +#endif + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed"); + goto err_setkey; + } + } + + ahash_request_set_crypt(req, &sg, hash_result, psize); +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ret = crypto_ahash_digest(req); +#else + ret = wcnss_wlan_crypto_ahash_digest(req); +#endif + + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret); + + switch (ret) { + case 0: + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible(&tresult.completion); + if (!ret && !tresult.err) { + INIT_COMPLETION(tresult.completion); + break; + } else { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed"); + if (!ret) + ret = tresult.err; + goto out; + } + default: + goto out; + } + +out: +err_setkey: + kfree(hash_buff); +err_hash_buf: + ahash_request_free(req); +err_req: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_ahash(tfm); +#else + wcnss_wlan_crypto_free_ahash(tfm); +#endif +err_tfm: + return ret; +} + +VOS_STATUS vos_md5_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *pKey, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_MD5_SIZE])/* caller digest to be filled in */ +{ + int ret = 0; + + ret = hmac_md5( + pKey, //v_U8_t *key, + (v_U8_t) keyLen, //v_U8_t ksize, + (char *)pText, //char *plaintext, + (v_U8_t) textLen, //v_U8_t psize, + digest, //v_U8_t *output, + VOS_DIGEST_MD5_SIZE //v_U8_t outlen + ); + + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_md5() call failed"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + + +struct ecb_aes_result { + struct completion completion; + int err; +}; + +static void ecb_aes_complete(struct crypto_async_request *req, int err) +{ + struct ecb_aes_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + + +/*-------------------------------------------------------------------------- + + \brief vos_encrypt_AES() - Generate AES Encrypted byte stream + + The vos_encrypt_AES() function generates the encrypted byte stream for given text. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pPlainText, /* pointer to data stream */ + v_U8_t *pCiphertext, + v_U8_t *pKey) /* pointer to authentication key */ +{ + struct ecb_aes_result result; + struct ablkcipher_request *req; + struct crypto_ablkcipher *tfm; + int ret = 0; + char iv[IV_SIZE_AES_128]; + struct scatterlist sg_in; + struct scatterlist sg_out; + + init_completion(&result.completion); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); +#else + tfm = wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); +#endif + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ablkcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)"); + ret = -ENOMEM; + goto err_req; + } + + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + ecb_aes_complete, &result); + + + crypto_ablkcipher_clear_flags(tfm, ~0); + + ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed"); + goto err_setkey; + } + + memset(iv, 0, IV_SIZE_AES_128); + + sg_init_one(&sg_in, pPlainText, AES_BLOCK_SIZE); + + sg_init_one(&sg_out, pCiphertext, AES_BLOCK_SIZE); + + ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv); + + crypto_ablkcipher_encrypt(req); + + + +// ------------------------------------- +err_setkey: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ablkcipher_request_free(req); +#else + wcnss_wlan_ablkcipher_request_free(req); +#endif +err_req: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_ablkcipher(tfm); +#else + wcnss_wlan_crypto_free_ablkcipher(tfm); +#endif +err_tfm: + //return ret; + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_decrypt_AES() - Decrypts an AES Encrypted byte stream + + The vos_decrypt_AES() function decrypts the encrypted byte stream. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *pDecrypted, + v_U8_t *pKey) /* pointer to authentication key */ +{ +// VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + struct ecb_aes_result result; + struct ablkcipher_request *req; + struct crypto_ablkcipher *tfm; + int ret = 0; + char iv[IV_SIZE_AES_128]; + struct scatterlist sg_in; + struct scatterlist sg_out; + + init_completion(&result.completion); + +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + tfm = crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); +#else + tfm = wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); +#endif + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ablkcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)"); + ret = -ENOMEM; + goto err_req; + } + + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + ecb_aes_complete, &result); + + + crypto_ablkcipher_clear_flags(tfm, ~0); + + ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed"); + goto err_setkey; + } + + memset(iv, 0, IV_SIZE_AES_128); + + sg_init_one(&sg_in, pText, AES_BLOCK_SIZE); + + sg_init_one(&sg_out, pDecrypted, AES_BLOCK_SIZE); + + ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv); + + crypto_ablkcipher_decrypt(req); + + + +// ------------------------------------- +err_setkey: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + ablkcipher_request_free(req); +#else + wcnss_wlan_ablkcipher_request_free(req); +#endif +err_req: +#if !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO)) + crypto_free_ablkcipher(tfm); +#else + wcnss_wlan_crypto_free_ablkcipher(tfm); +#endif +err_tfm: + //return ret; + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +v_U32_t vos_chan_to_freq(v_U8_t chan) +{ + if (chan < VOS_24_GHZ_CHANNEL_14) // ch 0 - ch 13 + return VOS_24_GHZ_BASE_FREQ + chan * VOS_CHAN_SPACING_5MHZ; + else if (chan == VOS_24_GHZ_CHANNEL_14) // ch 14 + return VOS_CHAN_14_FREQ; + else if (chan < VOS_24_GHZ_CHANNEL_27) // ch 15 - ch 26 + return VOS_CHAN_15_FREQ + + (chan - VOS_24_GHZ_CHANNEL_15) * VOS_CHAN_SPACING_20MHZ; + else + return VOS_5_GHZ_BASE_FREQ + chan * VOS_CHAN_SPACING_5MHZ; +} + +v_U8_t vos_freq_to_chan(v_U32_t freq) +{ + v_U8_t chan; + + if (freq > VOS_24_GHZ_BASE_FREQ && freq < VOS_CHAN_14_FREQ) + chan = ((freq - VOS_24_GHZ_BASE_FREQ)/VOS_CHAN_SPACING_5MHZ); + else if (freq == VOS_CHAN_14_FREQ) + chan = VOS_24_GHZ_CHANNEL_14; + else if ((freq > VOS_24_GHZ_BASE_FREQ) && (freq < VOS_5_GHZ_BASE_FREQ)) + chan = (((freq - VOS_CHAN_15_FREQ)/VOS_CHAN_SPACING_20MHZ) + + VOS_24_GHZ_CHANNEL_15); + else + chan = (freq - VOS_5_GHZ_BASE_FREQ)/VOS_CHAN_SPACING_5MHZ; + return chan; +} + + +v_U8_t vos_chan_to_band(v_U32_t chan) +{ + if (chan <= VOS_24_GHZ_CHANNEL_14) + return VOS_BAND_2GHZ; + + return VOS_BAND_5GHZ; +} diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halMsgApi.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halMsgApi.h new file mode 100644 index 0000000000000..ec1306d610b99 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halMsgApi.h @@ -0,0 +1,1587 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _HALMSGAPI_H_ +#define _HALMSGAPI_H_ + +#include "halTypes.h" +#include "sirApi.h" +#include "sirParams.h" + +#define HAL_NUM_BSSID 2 +/* operMode in ADD BSS message */ +#define BSS_OPERATIONAL_MODE_AP 0 +#define BSS_OPERATIONAL_MODE_STA 1 +#define BSS_OPERATIONAL_MODE_IBSS 2 + +/* STA entry type in add sta message */ +#define STA_ENTRY_SELF 0 +#define STA_ENTRY_OTHER 1 +#define STA_ENTRY_BSSID 2 +#define STA_ENTRY_BCAST 3 //Special station id for transmitting broadcast frames. +#define STA_ENTRY_PEER STA_ENTRY_OTHER +#ifdef FEATURE_WLAN_TDLS +#define STA_ENTRY_TDLS_PEER 4 +#endif /* FEATURE_WLAN_TDLS */ + +#define STA_ENTRY_TRANSMITTER STA_ENTRY_SELF +#define STA_ENTRY_RECEIVER STA_ENTRY_OTHER + +#define HAL_STA_INVALID_IDX 0xFF +#define HAL_BSS_INVALID_IDX 0xFF + +#define HAL_BSSPERSONA_INVALID_IDX 0xFF + +#define WLAN_BSS_PROTECTION_ON 1 +#define WLAN_BSS_PROTECTION_OFF 0 + +/* Station index allocation after Broadcast station */ +#define HAL_MAX_NUM_BCAST_STATIONS 1 +#define HAL_MIN_BCAST_STA_INDEX ((HAL_MAX_NUM_BCAST_STATIONS>0)?0:HAL_STA_INVALID_IDX) +#define HAL_MAX_BCAST_STA_INDEX ((HAL_MAX_NUM_BCAST_STATIONS>0)?(HAL_MAX_NUM_BCAST_STATIONS - 1):HAL_STA_INVALID_IDX) +#define HAL_MIN_STA_INDEX ((HAL_MAX_BCAST_STA_INDEX!=HAL_STA_INVALID_IDX)?(HAL_MAX_BCAST_STA_INDEX+1):0) +#define HAL_MAX_STA_INDEX (HAL_NUM_STA) + +/* Compilation flags for enabling disabling selfSta and bcastSta per BSS */ +#define HAL_SELF_STA_PER_BSS 1 +#define HAL_BCAST_STA_PER_BSS 1 + +//invalid channel id. +#define HAL_INVALID_CHANNEL_ID 0 + +/* BSS index used when no BSS is associated with the station. For example, + * driver creates only one self station without valid BSS while scanning. + * Then this index is used to tell softmac that BSS is not valid. + */ +#define BSSIDX_INVALID 254 + +#define HAL_IS_VALID_BSS_INDEX(pMac, bssIdx) ((BSSIDX_INVALID != (bssIdx)) && ((bssIdx) < (pMac)->hal.memMap.maxBssids)) + +// Beacon structure +typedef __ani_attr_pre_packed struct sAniBeaconStruct +{ + tANI_U32 beaconLength; // Indicates the beacon length + tSirMacMgmtHdr macHdr; // MAC Header for beacon + // Beacon body follows here +} __ani_attr_packed tAniBeaconStruct, *tpAniBeaconStruct; + +// probeRsp template structure +typedef __ani_attr_pre_packed struct sAniProbeRspStruct +{ + tSirMacMgmtHdr macHdr; // MAC Header for probeRsp + // probeRsp body follows here +} __ani_attr_packed tAniProbeRspStruct, *tpAniProbeRspStruct; + + +// Per TC parameters +typedef struct +{ + tANI_U8 disableTx; + tANI_U8 disableRx; + tANI_U8 rxCompBA; // 1: expect to see frames with compressed BA coming from this peer MAC + tANI_U8 rxBApolicy; // immediate ACK or delayed ACK for frames from this peer MAC + tANI_U8 txCompBA; // 1: using compressed BA to send to this peer MAC + tANI_U8 txBApolicy; // immediate ACK or delayed ACK for frames to this peer MAC + tANI_U8 rxUseBA; + tANI_U8 txUseBA; + tANI_U8 rxBufferSize; + tANI_U8 txBufferSize; + tANI_U16 txBAWaitTimeout; + tANI_U16 rxBAWaitTimeout; +} tTCParams; + + +typedef struct +{ + // First two fields bssid and assocId are used to find staid for sta. + // BSSID of STA + tSirMacAddr bssId; + + // ASSOC ID, as assigned by PE/LIM. This needs to be assigned + // on a per BSS basis + tANI_U16 assocId; + + // Field to indicate if this is sta entry for itself STA adding entry for itself + // or remote (AP adding STA after successful association. + // This may or may not be required in production driver. + tANI_U8 staType; // 0 - Self, 1 other/remote, 2 - bssid + + tANI_U8 shortPreambleSupported; + + // MAC Address of STA + tSirMacAddr staMac; + + // Listen interval. + tANI_U16 listenInterval; + + // Support for 11e/WMM + tANI_U8 wmmEnabled; + + // + // U-APSD Flags: 1b per AC + // Encoded as follows: + // b7 b6 b5 b4 b3 b2 b1 b0 + // X X X X BE BK VI VO + // + tANI_U8 uAPSD; + + // Max SP Length + tANI_U8 maxSPLen; + + // 11n HT capable STA + tANI_U8 htCapable; + + // 11n Green Field preamble support + // 0 - Not supported, 1 - Supported + // Add it to RA related fields of sta entry in HAL + tANI_U8 greenFieldCapable; + + // TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz + tANI_U8 txChannelWidthSet; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState mimoPS; + + // RIFS mode: 0 - NA, 1 - Allowed + tANI_U8 rifsMode; + + // L-SIG TXOP Protection mechanism + // 0 - No Support, 1 - Supported + // SG - there is global field. + tANI_U8 lsigTxopProtection; + + // delayed ba support + tANI_U8 delBASupport; + // delayed ba support... TBD + +#ifdef ANI_DVT_DEBUG + //These 6 fields are used only by DVT driver to pass selected + //rates to Softmac through HAL. + tANI_U8 primaryRateIndex, secondaryRateIndex, tertiaryRateIndex; + tANI_U8 primaryRateIndex40, secondaryRateIndex40, tertiaryRateIndex40; +#endif + + // FIXME + //Add these fields to message + tANI_U8 us32MaxAmpduDuration; //in units of 32 us. + tANI_U8 maxAmpduSize; // 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k + tANI_U8 maxAmpduDensity; // 3 : 0~7 : 2^(11nAMPDUdensity -4) + tANI_U8 maxAmsduSize; // 1 : 3839 bytes, 0 : 7935 bytes + + // TC parameters + tTCParams staTCParams[STACFG_MAX_TC]; + + // Compression and Concat parameters for DPU + tANI_U16 deCompEnable; + tANI_U16 compEnable; + tANI_U16 concatSeqRmv; + tANI_U16 concatSeqIns; + + + //11n Parameters + + /** + HT STA should set it to 1 if it is enabled in BSS + HT STA should set it to 0 if AP does not support it. + This indication is sent to HAL and HAL uses this flag + to pickup up appropriate 40Mhz rates. + */ + tANI_U8 fDsssCckMode40Mhz; + + + //short GI support for 40Mhz packets + tANI_U8 fShortGI40Mhz; + + //short GI support for 20Mhz packets + tANI_U8 fShortGI20Mhz; + + + + /* + * All the legacy and airgo supported rates. + * These rates are the intersection of peer and self capabilities. + */ + tSirSupportedRates supportedRates; + + + + + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_ADD_STA_REQ is reported here + eHalStatus status; + // Station index; valid only when 'status' field value is eHAL_STATUS_SUCCESS + tANI_U8 staIdx; + + //BSSID of BSS to which the station is associated. + //This should be filled back in by HAL, and sent back to LIM as part of + //the response message, so LIM can cache it in the station entry of hash table. + //When station is deleted, LIM will make use of this bssIdx to delete + //BSS from hal tables and from softmac. + tANI_U8 bssIdx; + + /* this requires change in testDbg. I will change it later after coordinating with Diag team. + tANI_U8 fFwdTrigerSOSPtoHost; //trigger to start service period + tANI_U8 fFwdTrigerEOSPtoHost; //trigger to end service period + */ + + //HAL should update the existing STA entry, if this flag is set. + //PE will set this flag in case of reassoc, where we want to resue the + //the old staID and still return success. + tANI_U8 updateSta; + //A flag to indicate to HAL if the response message is required. + tANI_U8 respReqd; + + /* Robust Management Frame (RMF) enabled/disabled */ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU index*/ + tANI_U8 ucUcastSig; + + /*Broadcast DPU index*/ + tANI_U8 ucBcastSig; + + tANI_U8 sessionId; //PE session id for PE<->HAL interface + // HAL just sends back what it receives. + + /*if this is a P2P Capable Sta*/ + tANI_U8 p2pCapableSta; + + /*CSA offload enable flag */ + tANI_U8 csaOffloadEnable; + +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; + tANI_U8 vhtSupportedRxNss; + tANI_U8 vhtTxBFCapable; + tANI_U8 vhtTxMUBformeeCapable; + tANI_U8 enableVhtpAid; + tANI_U8 enableVhtGid; +#endif + tANI_U8 enableAmpduPs; + tANI_U8 enableHtSmps; + tANI_U8 htSmpsconfig; + + tANI_U8 htLdpcCapable; + tANI_U8 vhtLdpcCapable; + tANI_U8 smesessionId; + tANI_U8 wpa_rsn; + tANI_U16 capab_info; + tANI_U16 ht_caps; + tANI_U32 vht_caps; + tSirNwType nwType; + tPowerdBm maxTxPower; + /* + * Peer Atim Info, Valid only + * for IBSS Mode. + */ + tANI_U8 atimIePresent; + tANI_U32 peerAtimWindowLength; + tANI_U8 nonRoamReassoc; +} tAddStaParams, *tpAddStaParams; + + +typedef struct +{ + // Station index + tANI_U16 staIdx; + tANI_U16 templIdx; + tANI_U8 rateIdx; + + // The return status of SIR_HAL_UPDATE_STARATEINFO_REQ is reported here + eHalStatus status; + + //A flag to indicate to HAL if the response message is required. + tANI_U8 respReqd; + +} tUpdateTxCmdTemplParams, *tpUpdateTxCmdTemplParams; +//FIXME: change the structure name + + + + + + + + +typedef struct +{ + // index of STA to delete - this should be the same as the index returned + // as part of the AddSta + tANI_U16 staIdx; + tANI_U16 assocId; + eHalStatus status; // Status of SIR_HAL_DELETE_STA_REQ is reported here + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // PE session id now added to all HAL<->PE transacations + // HAL sends it back unmodified. + tANI_U8 smesessionId; + tANI_U8 staType; + tSirMacAddr staMac; +} tDeleteStaParams, * tpDeleteStaParams; + +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ +typedef struct +{ + tANI_U16 staIdx; + tAniEdType encType; // Encryption/Decryption type + tAniWepType wepType; // valid only for WEP + tANI_U8 defWEPIdx; // Default WEP key, valid only for static WEP, must between 0 and 3 + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; // valid only for non-static WEP encyrptions + tANI_U8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + tANI_U8 smesessionId; + tSirMacAddr peerMacAddr; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // status of SIR_HAL_SET_STAKEY_REQ is reported here + tANI_U8 sessionId; // PE session id for PE<->HAL interface + + // PE session id now added to all HAL<->PE transacations + // HAL sends back response with no modification + tANI_U8 sendRsp; +} tSetStaKeyParams, *tpSetStaKeyParams; + +typedef struct sLimMlmSetKeysReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; //Added For BT-AMP Support + tANI_U8 smesessionId; // Added for drivers based on wmi interface + tANI_U16 aid; + tAniEdType edType; // Encryption/Decryption type + tANI_U8 numKeys; + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; +} tLimMlmSetKeysReq, *tpLimMlmSetKeysReq; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ADD_BSS_REQ +// +typedef struct +{ + // MAC Address/BSSID + tSirMacAddr bssId; +#ifdef HAL_SELF_STA_PER_BSS + // Self Mac Address + tSirMacAddr selfMacAddr; +#endif + // BSS type + // FIXME - Is this reqd? Do we want to isolate BSS/IBSS parameters? + tSirBssType bssType; + + // AP - 0; STA - 1 ; + tANI_U8 operMode; + + // Network type - b/g/a/MixedMode/GreenField/Legacy + // TODO - This enum to be updated for HT support + // Review FIXME - Why is this needed? + tSirNwType nwType; + + tANI_U8 shortSlotTimeSupported; + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20Coexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + // Beacon Interval + tSirMacBeaconInterval beaconInterval; + + // DTIM period + tANI_U8 dtimPeriod; + + // CF Param Set + // Review FIXME - Does HAL need this? + tSirMacCfParamSet cfParamSet; + + // MAC Rate Set + // Review FIXME - Does HAL need this? + tSirMacRateSet rateSet; + + // 802.11n related HT parameters that are dynamic + + // Enable/Disable HT capabilities + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + // RMF enabled/disabled + tANI_U8 rmfEnabled; + + // HT Operating Mode + // Review FIXME - Does HAL need this? + tSirMacHTOperatingMode htOperMode; + + // Dual CTS Protection: 0 - Unused, 1 - Used + tANI_U8 dualCTSProtection; + + // TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz + tANI_U8 txChannelWidthSet; + + // Current Operating Channel + tANI_U8 currentOperChannel; + + // Current Extension Channel, if applicable + tANI_U8 currentExtChannel; + + // Add a STA entry for "itself" - + // On AP - Add the AP itself in an "STA context" + // On STA - Add the AP to which this STA is joining in an "STA context" + tAddStaParams staContext; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_ADD_BSS_REQ is reported here + eHalStatus status; + // BSS index allocated by HAL. + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U16 bssIdx; + + // Broadcast DPU descriptor index allocated by HAL and used for broadcast/multicast packets. + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U8 bcastDpuDescIndx; + + // DPU signature to be used for broadcast/multicast packets + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U8 bcastDpuSignature; + + // DPU descriptor index allocated by HAL, used for bcast/mcast management packets + tANI_U8 mgmtDpuDescIndx; + + // DPU signature to be used for bcast/mcast management packets + tANI_U8 mgmtDpuSignature; + + //HAL should update the existing BSS entry, if this flag is set. + //PE will set this flag in case of reassoc, where we want to resue the + //the old bssID and still return success. + tANI_U8 updateBss; + + // Add BSSID info for rxp filter in IBSS mode + tSirMacSSid ssId; + + //HAL will send the response message to LIM only when this flag is set. + //LIM will set this flag, whereas DVT will not set this flag. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // PE session id now added to all HAL<->PE transacations + // HAL Sends the sessionId unmodified. + +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm maxTxPower; //max power to be used after applying the power constraint, if any +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + tANI_U8 ucMaxProbeRespRetryLimit; //probe Response Max retries + tANI_U8 bHiddenSSIDEn; //To Enable Hidden ssid. + tANI_U8 bProxyProbeRespEn; //To Enable Disable FW Proxy Probe Resp + tANI_U8 halPersona; //Persona for the BSS can be STA,AP,GO,CLIENT value same as tVOS_CON_MODE + + //Spectrum Management Capability, 1 - Enabled, 0 - Disabled. + tANI_U8 bSpectrumMgtEnabled; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; +#endif + tANI_U8 reassocReq; // Set only during roaming reassociation + tANI_U16 chainMask; + tANI_U16 smpsMode; + tANI_U8 dot11_mode; + tANI_U8 nonRoamReassoc; +} tAddBssParams, * tpAddBssParams; + +typedef struct +{ + tANI_U8 bssIdx; + // The return status of SIR_HAL_DELETE_BSS_REQ is reported here + eHalStatus status; + //HAL will send the response message to LIM only when this flag is set. + //LIM will set this flag, whereas DVT will not set this flag. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL sends it back unmodified. + tSirMacAddr bssid; // Will be removed for PE-HAL integration + tANI_U8 smesessionId; +} tDeleteBssParams, * tpDeleteBssParams; + +// +// UAPSD AC mask: 1b per AC +// LSB 4 bits for delivery enabled setting. msb 4 bits for trigger enabled settings. +// Encoded as follows: +// b7 b6 b5 b4 b3 b2 b1 b0 +// BE BK VI VO BE BK VI VO + +typedef struct +{ + tANI_U8 staIdx; + tANI_U8 uapsdACMask; + tANI_U8 maxSpLen; +} tUpdateUapsdParams, * tpUpdateUapsdParams; + +typedef struct sSirScanEntry +{ + tANI_U8 bssIdx[HAL_NUM_BSSID]; + tANI_U8 activeBSScnt; +}tSirScanEntry, *ptSirScanEntry; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_INIT_SCAN_REQ +// +typedef struct { + + eHalSysMode scanMode; + + tSirMacAddr bssid; + + tANI_U8 notifyBss; + + tANI_U8 useNoA; + + // If this flag is set HAL notifies PE when SMAC returns status. + tANI_U8 notifyHost; + + tANI_U8 frameLength; + tANI_U8 frameType; // Data NULL or CTS to self + + // Indicates the scan duration (in ms) + tANI_U16 scanDuration; + + // For creation of CTS-to-Self and Data-NULL MAC packets + tSirMacMgmtHdr macMgmtHdr; + + tSirScanEntry scanEntry; + + // when this flag is set, HAL should check for link traffic prior to scan + tSirLinkTrafficCheck checkLinkTraffic; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_INIT_SCAN_REQ is reported here + eHalStatus status; + +} tInitScanParams, * tpInitScanParams; + +typedef enum eDelStaReasonCode{ + HAL_DEL_STA_REASON_CODE_KEEP_ALIVE = 0x1, + HAL_DEL_STA_REASON_CODE_TIM_BASED = 0x2, + HAL_DEL_STA_REASON_CODE_RA_BASED = 0x3, + HAL_DEL_STA_REASON_CODE_UNKNOWN_A2 = 0x4 +}tDelStaReasonCode; + +typedef enum eSmpsModeValue{ + STATIC_SMPS_MODE = 0x0, + DYNAMIC_SMPS_MODE = 0x1, + SMPS_MODE_RESERVED = 0x2, + SMPS_MODE_DISABLED = 0x3 +}tSmpsModeValue; + +// +// Msg header is used from tSirMsgQ +// Msg Type = SIR_LIM_DELETE_STA_CONTEXT_IND +// +typedef struct { + bool is_tdls; + tANI_U8 vdev_id; + tANI_U16 assocId; + tANI_U16 staId; + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies bssid from the sta table. + tSirMacAddr addr2; // + tANI_U16 reasonCode; // To unify the keepalive / unknown A2 / tim-based disa +} tDeleteStaContext, * tpDeleteStaContext; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_START_SCAN_REQ +// FIXME - Can we just use tSirMsgQ directly, instead of using this structure? +// +typedef struct { + + // Indicates the current scan channel + tANI_U8 scanChannel; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_START_SCAN_REQ is reported here + eHalStatus status; + +#if defined WLAN_FEATURE_VOWIFI + tANI_U32 startTSF[2]; + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. +#endif +} tStartScanParams, * tpStartScanParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_END_SCAN_REQ +// FIXME - Can we just use tSirMsgQ directly, instead of using this structure? +// +typedef struct { + + // Indicates the current scan channel + tANI_U8 scanChannel; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_END_SCAN_REQ is reported here + eHalStatus status; + +} tEndScanParams, * tpEndScanParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_FINISH_SCAN_REQ +// +typedef struct { + + // Identifies the operational state of the AP/STA. + // In case of the STA, only if the operState is non-zero will the rest of + // the parameters that follow be decoded + // In case of the AP, all parameters are valid + // + // 0 - Idle state, 1 - Link Established + + eHalSysMode scanMode; + + tSirMacAddr bssid; + + // Current operating channel + tANI_U8 currentOperChannel; + + // If 20/40 MHz is operational, this will indicate the 40 MHz extension + // channel in combination with the control channel + ePhyChanBondState cbState; + + // For an STA, indicates if a Data NULL frame needs to be sent + // to the AP with FrameControl.PwrMgmt bit set to 0 + tANI_U8 notifyBss; + + tANI_U8 notifyHost; + + tANI_U8 frameLength; + tANI_U8 frameType; // Data NULL or CTS to self + + // For creation of CTS-to-Self and Data-NULL MAC packets + tSirMacMgmtHdr macMgmtHdr; + + tSirScanEntry scanEntry; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_FINISH_SCAN_REQ is reported here + eHalStatus status; + +} tFinishScanParams, * tpFinishScanParams; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +typedef struct +{ + tSirMacAddr selfMacAddr; + eHalStatus status; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tStartOemDataReq, *tpStartOemDataReq; + +typedef struct +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tStartOemDataRsp, *tpStartOemDataRsp; +#endif + +typedef struct sBeaconGenStaInfo { + tANI_U16 assocId; + tANI_U32 staTxAckCnt; +}tBeaconGenStaInfo, *tpBeaconGenStaInfo; +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_LIM_BEACON_GEN_IND +// + +typedef struct sBeaconGenParams { + // Identifies the BSSID for which it is time to generate a beacon + tANI_U8 bssIdx; + tSirMacAddr bssId; +#ifdef FIXME_VOLANS + tANI_U8 numOfSta; /* Number of stations in power save, who have data pending*/ + tANI_U8 numOfStaWithoutData; /* Number of stations in power save, who don't have any data pending*/ + tANI_U8 fBroadcastTrafficPending ; + tANI_U8 dtimCount; +#endif + tANI_U8 rsvd[3]; /** Align the Structure to 4 bytes as unalligned access will happen if + the staInfo is being Accessed */ +/** NOTE: tBeaconGenStaInfo staInfo[xx]; Depending on the Number of STA in PS, Every time + this array is being allocated and piled up at the End*/ +} tBeaconGenParams, * tpBeaconGenParams; + +typedef struct { + tSirMacAddr bssId; + tANI_U8 *beacon; // Beacon data. + tANI_U32 beaconLength; //length of the template. + tANI_U32 timIeOffset; //TIM IE offset from the beginning of the template. + tANI_U16 p2pIeOffset; //P2P IE offset from the begining of the template +} tSendbeaconParams, * tpSendbeaconParams; + +typedef struct sSendProbeRespParams { + tSirMacAddr bssId; + tANI_U8 *pProbeRespTemplate; + tANI_U32 probeRespTemplateLen; + tANI_U32 ucProxyProbeReqValidIEBmap[8]; +} tSendProbeRespParams, * tpSendProbeRespParams; + +/* + * This is used by PE to create a set of WEP keys for a given BSS. + */ +typedef struct +{ + tANI_U8 bssIdx; + tAniEdType encType; + tANI_U8 numKeys; + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + tANI_U8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + tANI_U8 smesessionId; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // status of SIR_HAL_SET_BSSKEY_REQ is reported here + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL sends this unmodified in the response +} tSetBssKeyParams, *tpSetBssKeyParams; + +/* + * This is used by PE to Remove the key information on a given station. + */ +typedef struct +{ + tANI_U16 staIdx; + tAniEdType encType; // Encryption/Decryption type + tANI_U8 keyId; + tANI_BOOLEAN unicast; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // return status of SIR_HAL_REMOVE_STAKEY_REQ + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified +} tRemoveStaKeyParams, *tpRemoveStaKeyParams; + +/* + * This is used by PE to remove keys for a given BSS. + */ +typedef struct +{ + tANI_U8 bssIdx; + tAniEdType encType; + tANI_U8 keyId; + tANI_U8 wepType; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // return status of SIR_HAL_REMOVE_BSSKEY_REQ + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified +} tRemoveBssKeyParams, *tpRemoveBssKeyParams; + +typedef struct +{ + // index of STA to get the statistics from + tANI_U16 staIdx; + tANI_U8 encMode; + // The return status of SIR_HAL_DPU_STATS_REQ is reported here + eHalStatus status; + // The return statistics + tANI_U32 sendBlocks; + tANI_U32 recvBlocks; + tANI_U32 replays; + tANI_U8 micErrorCnt; + tANI_U32 protExclCnt; + tANI_U16 formatErrCnt; + tANI_U16 unDecryptableCnt; + tANI_U32 decryptErrCnt; + tANI_U32 decryptOkCnt; + +} tDpuStatsParams, * tpDpuStatsParams; + + +/* + * Get the DPU signature based on a given staId + */ +typedef struct +{ + tANI_U16 staIdx; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_SET_BSSKEY_REQ is reported here + eHalStatus status; + tANI_U8 dpuDescIndx; + tANI_U8 dpuSignature; +} tGetDpuParams, *tpGetDpuParams; + + + +//HAL MSG: SIR_HAL_UPDATE_BEACON_IND +typedef struct +{ + + tANI_U8 bssIdx; + + //shortPreamble mode. HAL should update all the STA rates when it + //receives this message + tANI_U8 fShortPreamble; + //short Slot time. + tANI_U8 fShortSlotTime; + //Beacon Interval + tANI_U16 beaconInterval; + //Protection related + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20MhzCoexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + tANI_U16 paramChangeBitmap; + tANI_U8 smeSessionId; +}tUpdateBeaconParams, *tpUpdateBeaconParams; + +#ifdef WLAN_FEATURE_11AC +typedef struct +{ + tANI_U16 opMode; + tANI_U16 staId; + tANI_U16 smesessionId; + tSirMacAddr peer_mac; +}tUpdateVHTOpMode, *tpUpdateVHTOpMode; + +typedef struct +{ + tANI_U16 rxNss; + tANI_U16 staId; + tANI_U16 smesessionId; + tSirMacAddr peer_mac; +}tUpdateRxNss, *tpUpdateRxNss; + +typedef struct +{ + tANI_U32 membership; + tANI_U16 staId; + tANI_U16 smesessionId; + tSirMacAddr peer_mac; +}tUpdateMembership, *tpUpdateMembership; + +typedef struct +{ + tANI_U32 userPos; + tANI_U16 staId; + tANI_U16 smesessionId; + tSirMacAddr peer_mac; +}tUpdateUserPos, *tpUpdateUserPos; + +#endif + +//HAL MSG: SIR_HAL_UPDATE_CF_IND +typedef struct +{ + + tANI_U8 bssIdx; + + /* + * cfpCount indicates how many DTIMs (including the current frame) appear before the next CFP start. + * A CFPCount of 0 indicates that the current DTIM marks the start of the CFP. + */ + tANI_U8 cfpCount; + + /* cfpPeriod indicates the number of DTIM intervals between the start of CFPs. */ + tANI_U8 cfpPeriod; + +}tUpdateCFParams, *tpUpdateCFParams; + + + +//HAL MSG: SIR_HAL_UPDATE_DTIM_IND +//This message not required, as Softmac is supposed to read these values from the beacon. +//PE should not look at TIM element + +/* +typedef struct +{ + tANI_U8 bssIdx; + + + //The DTIM Count field indicates how many beacons (including the current frame) appear before the next + // DTIM. A DTIM Count of 0 indicates that the current TIM is a DTIM. + // + tANI_U8 dtimCount; + + + // The DTIM Period field indicates the number of Beacon intervals between successive DTIMs. If all TIMs are + // DTIMs, the DTIM Period field has the value 1. The DTIM Period value 0 is reserved. + // + tANI_U8 dtimPeriod; + +}tUpdateDtimParams, *tpUpdateDtimParams; +*/ + + +//HAL MSG: SIR_HAL_CHNL_SWITCH_REQ +typedef struct +{ + tANI_U8 channelNumber; +#ifndef WLAN_FEATURE_VOWIFI + tANI_U8 localPowerConstraint; +#endif /* WLAN_FEATURE_VOWIFI */ + ePhyChanBondState secondaryChannelOffset; + tANI_U8 peSessionId; +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm maxTxPower; +#endif + tSirMacAddr selfStaMacAddr; + //the request has power constraints, this should be applied only to that session + /* VO Wifi comment: BSSID is needed to identify which session issued this request. As the + request has power constraints, this should be applied only to that session */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + tSirMacAddr bssId; + + eHalStatus status; + + tANI_U16 chainMask; + + tANI_U16 smpsMode; + + tANI_U8 isDfsChannel; + + tANI_U8 vhtCapable; + + tANI_U8 dot11_mode; +}tSwitchChannelParams, *tpSwitchChannelParams; + +typedef struct CSAOffloadParams { + tANI_U8 channel; + tANI_U8 switchmode; + tANI_U8 sec_chan_offset; + tANI_U8 new_ch_width; /* New channel width */ + tANI_U8 new_ch_freq_seg1; /* Channel Center frequency 1 */ + tANI_U8 new_ch_freq_seg2; /* Channel Center frequency 2 */ + tANI_U32 ies_present_flag; /* WMI_CSA_EVENT_IES_PRESENT_FLAG */ + tSirMacAddr bssId; +}*tpCSAOffloadParams, tCSAOffloadParams; + +typedef void (*tpSetLinkStateCallback)(tpAniSirGlobal pMac, void *msgParam, + bool status); + +typedef struct sLinkStateParams +{ + // SIR_HAL_SET_LINK_STATE + tSirMacAddr bssid; + tSirMacAddr selfMacAddr; + tSirLinkState state; + tpSetLinkStateCallback callback; + void *callbackArg; +#ifdef WLAN_FEATURE_VOWIFI_11R + int ft; + void * session; +#endif + v_BOOL_t status; +} tLinkStateParams, * tpLinkStateParams; + + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS + tSirMacTspecIE tspec; + eHalStatus status; + tANI_U8 sessionId; //PE session id for PE<->HAL interface +#ifdef FEATURE_WLAN_ESE + tANI_U16 tsm_interval; // TSM interval period passed from lim to wda +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 setRICparams; +#endif + uint8_t sme_session_id; +} tAddTsParams, *tpAddTsParams; + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS + tSirMacAddr bssId; //TO SUPPORT BT-AMP + tANI_U8 sessionId; + tANI_U8 userPrio; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tSirDeltsReqInfo delTsInfo; + tANI_U8 setRICparams; +#endif +} tDelTsParams, *tpDelTsParams; + +#ifdef WLAN_FEATURE_VOWIFI_11R + +#define HAL_QOS_NUM_TSPEC_MAX 2 +#define HAL_QOS_NUM_AC_MAX 4 + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS + tSirMacTspecIE tspec[HAL_QOS_NUM_AC_MAX]; + eHalStatus status[HAL_QOS_NUM_AC_MAX]; + tANI_U8 sessionId; //PE session id for PE<->HAL interface +}tAggrAddTsParams, *tpAggrAddTsParams; + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +typedef tSirRetStatus (*tHalMsgCallback)(tpAniSirGlobal pMac, tANI_U32 mesgId, void *mesgParam ); + + +typedef struct +{ + tANI_U16 bssIdx; + tANI_BOOLEAN highPerformance; + tSirMacEdcaParamRecord acbe; // best effort + tSirMacEdcaParamRecord acbk; // background + tSirMacEdcaParamRecord acvi; // video + tSirMacEdcaParamRecord acvo; // voice +} tEdcaParams, *tpEdcaParams; + +/* +* Function Prototypes +*/ + +eHalStatus halMsg_setPromiscMode(tpAniSirGlobal pMac); + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ADDBA_REQ +// +typedef struct sAddBAParams +{ + + // Station Index + tANI_U16 staIdx; + + // Peer MAC Address + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + // HAL will not interpret this object + tANI_U8 baDialogToken; + + // TID for which the BA is being setup + // This identifies the TC or TS of interest + tANI_U8 baTID; + + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // Indicates the number of buffers for this TID (baTID) + // NOTE - This is the requested buffer size. When this + // is processed by HAL and subsequently by HDD, it is + // possible that HDD may change this buffer size. Any + // change in the buffer size should be noted by PE and + // advertized appropriately in the ADDBA response + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // b0..b3 - Fragment Number - Always set to 0 + // b4..b15 - Starting Sequence Number of first MSDU + // for which this BA is setup + tANI_U16 baSSN; + + // ADDBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // + // Following parameters are for returning status from + // HAL to PE via response message. HAL does not read them + // + // The return status of SIR_HAL_ADDBA_REQ is reported + // in the SIR_HAL_ADDBA_RSP message + eHalStatus status; + + // Indicating to HAL whether a response message is required. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified + +} tAddBAParams, * tpAddBAParams; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_DELBA_IND +// +typedef struct sDelBAParams +{ + + // Station Index + tANI_U16 staIdx; + + // TID for which the BA session is being deleted + tANI_U8 baTID; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // FIXME - Do we need a response for this? + // Maybe just the IND/REQ will suffice? + // + // Following parameters are for returning status from + // HAL to PE via response message. HAL does not read them + // + // The return status of SIR_HAL_DELBA_REQ is reported + // in the SIR_HAL_DELBA_RSP message + //eHalStatus status; + +} tDelBAParams, * tpDelBAParams; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_SET_MIMOPS_REQ +// +typedef struct sSet_MIMOPS +{ + // Station Index + tANI_U16 staIdx; + + // MIMO Power Save State + tSirMacHTMIMOPowerSaveState htMIMOPSState; + // The return status of SIR_HAL_SET_MIMOPS_REQ is reported + // in the SIR_HAL_SET_MIMOPS_RSP message + eHalStatus status; + tANI_U8 fsendRsp; + + tSirMacAddr peerMac; + tANI_U8 sessionId; +} tSetMIMOPS, * tpSetMIMOPS; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_EXIT_BMPS_REQ +// +typedef struct sExitBmpsParams +{ + tANI_U8 sendDataNull; + eHalStatus status; + tANI_U8 bssIdx; +} tExitBmpsParams, *tpExitBmpsParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ENTER_UAPSD_REQ +// +typedef struct sUapsdParams +{ + tANI_U8 bkDeliveryEnabled:1; + tANI_U8 beDeliveryEnabled:1; + tANI_U8 viDeliveryEnabled:1; + tANI_U8 voDeliveryEnabled:1; + tANI_U8 bkTriggerEnabled:1; + tANI_U8 beTriggerEnabled:1; + tANI_U8 viTriggerEnabled:1; + tANI_U8 voTriggerEnabled:1; + eHalStatus status; + tANI_U8 bssIdx; +}tUapsdParams, *tpUapsdParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_EXIT_UAPSD_REQ +// +typedef struct sExitUapsdParams +{ + eHalStatus status; + tANI_U8 bssIdx; +}tExitUapsdParams, *tpExitUapsdParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_LIM_DEL_BA_IND +// +typedef struct sBADeleteParams +{ + + // Station Index + tANI_U16 staIdx; + + // Peer MAC Address, whose BA session has timed out + tSirMacAddr peerMacAddr; + + // TID for which a BA session timeout is being triggered + tANI_U8 baTID; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + tANI_U32 reasonCode; + + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies the sta bssid to this. +} tBADeleteParams, * tpBADeleteParams; + + +// Mesg Type = SIR_LIM_ADD_BA_IND +typedef struct sBaActivityInd +{ + tANI_U16 baCandidateCnt; + //baCandidateCnt is followed by BA Candidate List ( tAddBaCandidate) + + tSirMacAddr bssId; // TO SUPPORT BT-AMP +} tBaActivityInd, * tpBaActivityInd; + + +// Mesg Type = SIR_LIM_IBSS_PEER_INACTIVITY_IND +typedef struct sIbssPeerInactivityInd +{ + tANI_U8 bssIdx; + tANI_U8 staIdx; + tSirMacAddr staAddr; +}tIbssPeerInactivityInd, *tpIbssPeerInactivityInd; + + +typedef struct tHalIndCB +{ + + tHalMsgCallback pHalIndCB; + +}tHalIndCB,*tpHalIndCB; + +/** Max number of bytes required for stations bitmap aligned at 4 bytes boundary */ +#define HALMSG_NUMBYTES_STATION_BITMAP(x) (((x / 32) + ((x % 32)?1:0)) * 4) + +typedef struct sControlTxParams +{ + tANI_BOOLEAN stopTx; + /* Master flag to stop or resume all transmission, Once this flag is set, + * softmac doesnt look for any other details. + */ + tANI_U8 fCtrlGlobal; + /* If this flag is set, staBitmap[] is valid */ + tANI_U8 ctrlSta; + /* If this flag is set, bssBitmap and beaconBitmap is valid */ + tANI_U8 ctrlBss; + + /* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be + * stopped for resumed for transmission. + * This is 32 bit bitmap, not array of bytes. + */ + tANI_U32 bssBitmap; + /* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be + * stopped for resumed for beacon transmission. + */ + tANI_U32 beaconBitmap; + + /** + * Memory for the station bitmap will be allocated later based on + * the number of station supported. + */ +} tTxControlParams, * tpTxControlParams; + +typedef struct sEnterBmpsParams +{ + //TBTT value derived from the last beacon + tANI_U8 bssIdx; + tANI_U64 tbtt; + tANI_U8 dtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + tANI_U8 dtimPeriod; + + // For ESE and 11R Roaming + tANI_U8 bRssiFilterEnable; + tANI_U32 rssiFilterPeriod; + tANI_U32 numBeaconPerRssiAverage; + + eHalStatus status; + tANI_U8 respReqd; +}tEnterBmpsParams, *tpEnterBmpsParams; + +//BMPS response +typedef struct sEnterBmpsRspParams +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +}tEnterBmpsRspParams, *tpEnterBmpsRspParams; +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_SET_MAX_TX_POWER_REQ +// +typedef struct sMaxTxPowerParams +{ + tSirMacAddr bssId; // BSSID is needed to identify which session issued this request. As + //the request has power constraints, this should be applied only to that session + tSirMacAddr selfStaMacAddr; + //In request, + //power == MaxTx power to be used. + //In response, + //power == tx power used for management frames. + tPowerdBm power; + tVOS_CON_MODE dev_mode; +}tMaxTxPowerParams, *tpMaxTxPowerParams; + +typedef struct sMaxTxPowerPerBandParams +{ + eCsrBand bandInfo; + tPowerdBm power; +}tMaxTxPowerPerBandParams, *tpMaxTxPowerPerBandParams; + +typedef struct sAddStaSelfParams +{ + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; + tANI_U32 type; + tANI_U32 subType; + tANI_U8 sessionId; + tANI_U32 status; + tANI_U16 pkt_err_disconn_th; +}tAddStaSelfParams, *tpAddStaSelfParams; + +#ifdef FEATURE_WLAN_TDLS + +#define HAL_TDLS_MAX_SUPP_CHANNELS 128 +#define HAL_TDLS_MAX_SUPP_OPER_CLASSES 32 + +typedef struct { + tANI_U8 isPeerResponder; + tANI_U8 peerUapsdQueue; + tANI_U8 peerMaxSp; + tANI_U8 peerBuffStaSupport; + tANI_U8 peerOffChanSupport; + tANI_U8 peerCurrOperClass; + tANI_U8 selfCurrOperClass; + tANI_U8 peerChanLen; + tSirUpdateChanParam peerChan[HAL_TDLS_MAX_SUPP_CHANNELS]; + tANI_U8 peerOperClassLen; + tANI_U8 peerOperClass[HAL_TDLS_MAX_SUPP_OPER_CLASSES]; + tANI_U8 prefOffChanNum; + tANI_U8 prefOffChanBandwidth; + tANI_U8 opClassForPrefOffChan; +} tTdlsPeerCapParams; + +typedef struct sTdlsPeerStateParams +{ + tANI_U32 vdevId; + tSirMacAddr peerMacAddr; + tANI_U32 peerState; + tTdlsPeerCapParams peerCap; +}tTdlsPeerStateParams; + +typedef struct sTdlsChanSwitchParams +{ + tANI_U32 vdevId; + tSirMacAddr peerMacAddr; + tANI_U16 tdlsOffChBwOffset;/* Target Off Channel Bandwidth offset */ + tANI_U8 tdlsOffCh; /* Target Off Channel */ + tANI_U8 tdlsSwMode; /* TDLS Off Channel Mode */ + tANI_U8 operClass; /* Operating class corresponding to target channel */ + tANI_U8 is_responder;/* responder or initiator */ +}tTdlsChanSwitchParams; +#endif /* FEATURE_WLAN_TDLS */ + +typedef struct sAbortScanParams +{ + tANI_U8 SessionId; +}tAbortScanParams, *tpAbortScanParams; + +typedef struct sDelStaSelfParams +{ + tSirMacAddr selfMacAddr; + tANI_U8 sessionId; + tANI_U32 status; +}tDelStaSelfParams, *tpDelStaSelfParams; + +typedef struct sP2pPsParams +{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; + tANI_U8 sessionId; +}tP2pPsParams, *tpP2pPsParams; + +#define HAL_MAX_SUPP_CHANNELS 128 +#define HAL_MAX_SUPP_OPER_CLASSES 32 + +typedef struct sTdlsLinkEstablishParams +{ + tANI_U16 staIdx; + tANI_U8 isResponder; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufsta; + tANI_U8 isOffChannelSupported; + tANI_U8 peerCurrOperClass; + tANI_U8 selfCurrOperClass; + tANI_U8 validChannelsLen; + tANI_U8 validChannels[HAL_MAX_SUPP_CHANNELS]; + tANI_U8 validOperClassesLen; + tANI_U8 validOperClasses[HAL_MAX_SUPP_OPER_CLASSES]; + tANI_U32 status; +}tTdlsLinkEstablishParams, *tpTdlsLinkEstablishParams; + +typedef struct tHalHiddenSsidVdevRestart +{ + tANI_U8 ssidHidden; + tANI_U8 sessionId; +}tHalHiddenSsidVdevRestart,*tpHalHiddenSsidVdevRestart; + +static inline void halGetTxTSFtimer(tpAniSirGlobal pMac, + tSirMacTimeStamp *pTime) +{ +} + +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); + +/* Beacon Filtering data structures */ +typedef __ani_attr_pre_packed struct sBeaconFilterMsg +{ + tANI_U16 capabilityInfo; + tANI_U16 capabilityMask; + tANI_U16 beaconInterval; + tANI_U16 ieNum; + tANI_U8 bssIdx; + tANI_U8 reserved; +} __ani_attr_packed tBeaconFilterMsg, *tpBeaconFilterMsg; + +typedef __ani_attr_pre_packed struct sEidByteInfo +{ + tANI_U8 offset; + tANI_U8 value; + tANI_U8 bitMask; + tANI_U8 ref; +} __ani_attr_packed tEidByteInfo, *tpEidByteInfo; + + +/* The above structure would be followed by multiple of below mentioned +structure */ +typedef __ani_attr_pre_packed struct sBeaconFilterIe +{ + tANI_U8 elementId; + tANI_U8 checkIePresence; + tEidByteInfo byte; +} __ani_attr_packed tBeaconFilterIe, *tpBeaconFilterIe; + +typedef __ani_attr_pre_packed struct sRemBeaconFilterMsg +{ + tANI_U8 ucIeCount; + tANI_U8 ucRemIeId[1]; +} __ani_attr_packed tRemBeaconFilterMsg, *tpRemBeaconFilterMsg; + +typedef __ani_attr_pre_packed struct sDisableIntraBssFwd +{ + tANI_U16 sessionId; + tANI_BOOLEAN disableintrabssfwd; +} __ani_attr_packed tDisableIntraBssFwd, *tpDisableIntraBssFwd; + +#ifdef WLAN_FEATURE_STATS_EXT +typedef struct sStatsExtRequest +{ + tANI_U32 vdev_id; + tANI_U32 request_data_len; + tANI_U8 request_data[]; +} tStatsExtRequest, *tpStatsExtRequest; +#endif + +#ifdef WLAN_FEATURE_NAN +typedef struct sNanRequest +{ + tANI_U16 request_data_len; + tANI_U8 request_data[]; +} tNanRequest, *tpNanRequest; +#endif + +#endif /* _HALMSGAPI_H_ */ diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halTypes.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halTypes.h new file mode 100644 index 0000000000000..ba7c539a1fd66 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/halTypes.h @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file halTypes.h + + \brief This header captures types that must be shared in common with individual + module headers before inclusion into halCommonApi.h. + + $Id$========================================================================== */ + +#ifndef HALTYPES_H +#define HALTYPES_H +#ifndef WINXP_APPS_BUILD //TODO: this header dependency does not belong in this file + +#endif /* WINXP_APPS_BUILD */ + +#include "palTypes.h" +#include "wlan_nv.h" + +#define OFFSET_OF(structType,fldName) (&((structType*)0)->fldName) + +/** ------------------------------------------------------------------------- * + + \typedef tHalHandle + + \brief Handle to the HAL. The HAL handle is returned by the HAL after it + is opened (by calling halOpen). + + -------------------------------------------------------------------------- */ +typedef void *tHalHandle; + +// define a value for an invalid HAL handle..... +#define HAL_INVALID_HAL_HANDLE ( NULL ) + + +/** ------------------------------------------------------------------------- * + + \enum eHalStatus + + \brief Enumeration of all status codes returned by the higher level + HAL interface functions. + + -------------------------------------------------------------------------- */ +typedef enum +{ + eHAL_STATUS_SUCCESS, + + // general failure. This status applies to all failure that are not covered + // by more specific return codes. + eHAL_STATUS_FAILURE, + eHAL_STATUS_FAILED_ALLOC, + eHAL_STATUS_RESOURCES, + + // the HAL has not been opened and a HAL function is being attempted. + eHAL_STATUS_NOT_OPEN, + + // function failed due to the card being removed... + eHAL_STATUS_CARD_NOT_PRESENT, + + //halInterrupt status + eHAL_STATUS_INTERRUPT_ENABLED, + eHAL_STATUS_INTERRUPT_DISABLED, + eHAL_STATUS_NO_INTERRUPTS, + eHAL_STATUS_INTERRUPT_PRESENT, + eHAL_STATUS_ALL_INTERRUPTS_PROCESSED, + eHAL_STATUS_INTERRUPT_NOT_PROCESSED, //interrupt cleared but no Isr to process + + // a parameter on the PAL function call is not valid. + eHAL_STATUS_INVALID_PARAMETER, + + // the PAL has not been initialized... + eHAL_STATUS_NOT_INITIALIZED, + + // Error codes for PE-HAL message API + eHAL_STATUS_INVALID_STAIDX, + eHAL_STATUS_INVALID_BSSIDX, + eHAL_STATUS_STA_TABLE_FULL, // No space to add more STA, sta table full. + eHAL_STATUS_BSSID_TABLE_FULL, + eHAL_STATUS_DUPLICATE_BSSID, + eHAL_STATUS_DUPLICATE_STA, + eHAL_STATUS_BSSID_INVALID, + eHAL_STATUS_STA_INVALID, + eHAL_STATUS_INVALID_KEYID, + eHAL_STATUS_INVALID_SIGNATURE, + + //DXE + eHAL_STATUS_DXE_FAILED_NO_DESCS, + eHAL_STATUS_DXE_CHANNEL_NOT_CONFIG, // Channel not configured + eHAL_STATUS_DXE_CHANNEL_MISUSE, // Specified operation inconsistent w/ configuration + eHAL_STATUS_DXE_VIRTUAL_MEM_ALLOC_ERROR, // + eHAL_STATUS_DXE_SHARED_MEM_ALLOC_ERROR, // + eHAL_STATUS_DXE_INVALID_CHANNEL, + eHAL_STATUS_DXE_INVALID_CALLBACK, + eHAL_STATUS_DXE_INCONSISTENT_DESC_COUNT, + eHAL_STATUS_DXE_XFR_QUEUE_ERROR, + eHAL_STATUS_DXE_INVALID_BUFFER, + eHAL_STATUS_DXE_INCOMPLETE_PACKET, + eHAL_STATUS_DXE_INVALID_PARAMETER, + eHAL_STATUS_DXE_CH_ALREADY_CONFIGURED, + eHAL_STATUS_DXE_USB_INVALID_EP, + eHAL_STATUS_DXE_GEN_ERROR, + + + // status codes added for the ImageValidate library + eHAL_STATUS_E_NULL_VALUE, + eHAL_STATUS_E_FILE_NOT_FOUND, + eHAL_STATUS_E_FILE_INVALID_CONTENT, + eHAL_STATUS_E_MALLOC_FAILED, + eHAL_STATUS_E_FILE_READ_FAILED, + eHAL_STATUS_E_IMAGE_INVALID, + eHAL_STATUS_E_IMAGE_UNSUPPORTED, + + // status code returned by device memory calls when memory is + // not aligned correctly. + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED, // memory access is not aligned on a 4 byte boundary + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR, // memory access is not a multiple of 4 bytes + + // Generic status code to indicate network congestion. + eHAL_STATUS_NET_CONGESTION, + + // various status codes for Rx packet dropped conditions... Note the Min and Max + // enums that bracked the Rx Packet Dropped status codes. There is code that + // looks at the various packet dropped conditions so make sure these min / max + // enums remain accurate. + eHAL_STATUS_RX_PACKET_DROPPED, + eHAL_STATUS_RX_PACKET_DROPPED_MIN = eHAL_STATUS_RX_PACKET_DROPPED, + eHAL_STATUS_RX_PACKET_DROPPED_NULL_DATA, + eHAL_STATUS_RX_PACKET_DROPPED_WDS_FRAME, + eHAL_STATUS_RX_PACKET_DROPPED_FILTERED, + eHAL_STATUS_RX_PACKET_DROPPED_GROUP_FROM_SELF, + eHAL_STATUS_RX_PACKET_DROPPED_MAX = eHAL_STATUS_RX_PACKET_DROPPED_GROUP_FROM_SELF, + + // Status indicating that PMU did not power up and hence indicative of the fact that the clocks are not on + eHAL_STATUS_PMU_NOT_POWERED_UP, + + // Queuing code for BA message API + eHAL_STATUS_BA_ENQUEUED, // packets have been buffered in Host + eHAL_STATUS_BA_INVALID, + + // A-MPDU/BA related Error codes + eHAL_STATUS_BA_RX_BUFFERS_FULL, + eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED, + eHAL_STATUS_BA_RX_INVALID_SESSION_ID, + + // !!LAC - can we rework the code so these are not needed? + eHAL_STATUS_BA_RX_DROP_FRAME, + eHAL_STATUS_BA_RX_INDICATE_FRAME, + eHAL_STATUS_BA_RX_ENQUEUE_FRAME, + + // PMC return codes. + eHAL_STATUS_PMC_PENDING, + eHAL_STATUS_PMC_DISABLED, + eHAL_STATUS_PMC_NOT_NOW, + eHAL_STATUS_PMC_AC_POWER, + eHAL_STATUS_PMC_SYS_ERROR, + eHAL_STATUS_PMC_CANNOT_ENTER_IMPS, + eHAL_STATUS_PMC_ALREADY_IN_IMPS, + + eHAL_STATUS_HEARTBEAT_TMOUT, + eHAL_STATUS_NTH_BEACON_DELIVERY, + + //CSR + eHAL_STATUS_CSR_WRONG_STATE, + + // DPU + eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL, + eHAL_STATUS_DPU_MICKEY_TABLE_FULL, + + // HAL-FW messages + eHAL_STATUS_FW_MSG_FAILURE, // Error in Hal-FW message interface + eHAL_STATUS_FW_MSG_TIMEDOUT, + eHAL_STATUS_FW_MSG_INVALID, + eHAL_STATUS_FW_SEND_MSG_FAILED, + eHAL_STATUS_FW_PS_BUSY, + + eHAL_STATUS_TIMER_START_FAILED, + eHAL_STATUS_TIMER_STOP_FAILED, + + eHAL_STATUS_TL_SUSPEND_TIMEOUT, + + eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL, + + eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN, + +#ifdef WLAN_FEATURE_VOWIFI_11R + eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS, + eHAL_STATUS_FT_PREAUTH_KEY_FAILED, +#endif + //CMD not Queued in SME + eHAL_STATUS_CMD_NOT_QUEUED, + // not a real status. Just a way to mark the maximum in the enum. + eHAL_STATUS_MAX + +} eHalStatus; + +typedef enum +{ + HAL_STOP_TYPE_SYS_RESET, + HAL_STOP_TYPE_SYS_DEEP_SLEEP, + HAL_STOP_TYPE_RF_KILL, +}tHalStopType; + +// macro to check for SUCCESS value of the halStatus +#define HAL_STATUS_SUCCESS( variable ) ( eHAL_STATUS_SUCCESS == ( variable ) ) + +/// Bit value data structure +typedef enum sHalBitVal // For Bit operations +{ + eHAL_CLEAR, + eHAL_SET +}tHalBitVal; + +// ------------------------------------------------------------- +/// MMH APIs +enum { + eHI_PRI, + ePROT, + eDBG +}; + +/// System role definition on a per BSS +typedef enum eBssSystemRole +{ + eSYSTEM_UNKNOWN_ROLE, + eSYSTEM_AP_ROLE, + eSYSTEM_STA_IN_IBSS_ROLE, + eSYSTEM_STA_ROLE, + eSYSTEM_BTAMP_STA_ROLE, + eSYSTEM_BTAMP_AP_ROLE, + + eSYSTEM_LAST_ROLE, + eSYSTEM_MULTI_BSS_ROLE = eSYSTEM_LAST_ROLE +} tBssSystemRole; + + +// --------------------------------------- +// Channel Bonding Sideband configuration +// --------------------------------------- +typedef enum sHalCBsidebandType +{ + eHAL_SIDEBAND_CENTER=0, + eHAL_SIDEBAND_LOWER, + eHAL_SIDEBAND_UPPER, + eHAL_SIDEBAND_COPY +}tHalCBsidebandType; + + +/// HAL states +typedef enum { + eHAL_IDLE, + eHAL_INIT, + eHAL_CFG, //CFG download completed. + eHAL_STARTED, //halProcessStartEvent compelted. + eHAL_SYS_READY, //Sys_ready msg received from HDD. + eHAL_NORMAL, //Sys_ready msg received from HDD and halProcessStartEvent completed. +} tHAL_STATE; + + + + +// Type to define softmac mode (also system mode) +typedef enum +{ + //3- Promisc, 2 - Scan, 1 - Learn 0 - Normal + eHAL_SYS_MODE_NORMAL = 0, + eHAL_SYS_MODE_LEARN, + eHAL_SYS_MODE_SCAN, + eHAL_SYS_MODE_PROMISC, + eHAL_SYS_MODE_SUSPEND_LINK, + eHAL_SYS_MODE_ROAM_SCAN, + eHAL_SYS_MODE_ROAM_SUSPEND_LINK, +} eHalSysMode; + + + + +// HAL frame types. Used on the TxRx APIs and the +// corresponding PAL routines. +typedef enum { + + HAL_TXRX_FRM_RAW, + HAL_TXRX_FRM_ETH2, + HAL_TXRX_FRM_802_3, + HAL_TXRX_FRM_802_11_MGMT, + HAL_TXRX_FRM_802_11_CTRL, + HAL_TXRX_FRM_802_11_DATA, + HAL_TXRX_FRM_IGNORED, //This frame will be dropped + HAL_TXRX_FRM_MAX + +} eFrameType; + + +typedef enum +{ + ANI_TXDIR_IBSS = 0, + ANI_TXDIR_TODS, + ANI_TXDIR_FROMDS, + ANI_TXDIR_WDS + +} eFrameTxDir; + +typedef enum +{ + eRF_BAND_UNKNOWN = 0, + eRF_BAND_2_4_GHZ = 1, + eRF_BAND_5_GHZ = 2 +} eRfBandMode; + + +#ifndef __offsetof +#define __offsetof(type, field) ((tANI_U32)(&((type *)0)->field)) +#endif + +#ifndef offsetof +#define offsetof(type, field) __offsetof(type, field) +#endif + +#define HAL_MAX_TXPOWER_INVALID 127 + +/* These are the min/max tx power (non virtual rates) range + * supported by rome/prima hardware + */ +#define MIN_TX_PWR_CAP 8 +#define MAX_TX_PWR_CAP 22 + +/* Moving the miscellaneous defination required by UMAC are moved here from + * volansdefs.h */ +/* -------------------------------------------------------------------- + * Support definitions for taurus + * -------------------------------------------------------------------- + */ + +/* + * Volans supports 8 stations in hardware + * + * Volans without Virtual STA feature can only support 8 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 6 Soft AP Stations (hard) + * + * Volans with Virtual STA feature supports 14 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 2 General Purpose Stations to support Virtual STAs (hard) + * 10 Soft AP Stations (4 hard/6 virtual) + */ + +#define HAL_INVALID_BSSIDX (HAL_NUM_BSSID + 1) +#define HAL_NUM_UMA_DESC_ENTRIES 8 +#define MAX_NUM_OF_BACKOFFS 8 + +#define IS_VALID_BSSIDX(__x) \ + ((__x) < HAL_NUM_BSSID) + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define HAL_NUM_ASSOC_STA 32 +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) + +#define QWLANFW_MAX_NUM_VSTA HAL_NUM_VSTA +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA + 1) +#define QWLAN_VSTA_MIN_IDX HAL_NUM_HW_STA +#define QWLANFW_NUM_GPSTA HAL_NUM_GPSTA + + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#else +/*In prima 12 HW stations are supported including BCAST STA(staId 0) + and SELF STA(staId 1) so total ASSOC stations which can connect to Prima + SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. */ +#define HAL_NUM_STA 12 +#define HAL_NUM_ASSOC_STA 10 +#define HAL_NUM_HW_STA 12 +#endif + +/* + * From NOVA Mac Arch document + * Encryp. mode The encryption mode + * 000: Encryption functionality is not enabled + * 001: Encryption is set to WEP + * 010: Encryption is set to WEP 104 + * 011: Encryption is set to TKIP + * 100: Encryption is set to AES + * 101 - 111: Reserved for future + */ + +#define HAL_ENC_POLICY_NULL 0 +#define HAL_ENC_POLICY_WEP40 1 +#define HAL_ENC_POLICY_WEP104 2 +#define HAL_ENC_POLICY_TKIP 3 +#define HAL_ENC_POLICY_AES_CCM 4 + +#define STACFG_MAX_TC 8 + + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/palTypes.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/palTypes.h new file mode 100644 index 0000000000000..c5163e20027a0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/palTypes.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( PALTYPES_H__ ) +#define PALTYPES_H__ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file palTypes.h + + \brief Exports and types for the Platform Abstraction Layer typedefs. + These are common typedefs that can be used across Platforms (OS/compiler + and bus types). All common code should adhere to these common types. + + $Id$... description... + + ========================================================================== */ +#ifndef WINXP_APPS_BUILD +#include "vos_types.h" +#include "vos_api.h" +#endif /* WINXP_APPS_BUILD */ + +#include "halLegacyPalTypes.h" + +#ifndef MK_IMAGE_HDR + +// +// Validate the OS Type being built... +// + +#if defined(ANI_OS_TYPE_ANDROID) // ANDROID + +#if defined(ANI_OS_TYPE_QNX) +#error "more than one ANI_OS_TYPE_xxx is defined for this build" +#endif + +#elif defined( ANI_OS_TYPE_QNX ) // QNX + +#if defined(ANI_OS_TYPE_ANDROID) +#error "more than one ANI_OS_TYPE_xxx is defined for this build" +#endif + + +#elif !defined(ANI_OS_TYPE_ANDROID) && !defined(ANI_OS_TYPE_QNX) // NONE +#error "NONE of the ANI_OS_TYPE_xxx are defined for this build" +#endif + + +// +// Validate the compiler... +// +#if ( defined( ANI_COMPILER_TYPE_MSVC ) && defined( ANI_COMPILER_TYPE_GCC ) && defined( ANI_COMPILER_TYPE_RVCT ) ) +#error "more than one ANI_COMPILER_TYPE_xxx is defined for this build" + +#elif !( defined( ANI_COMPILER_TYPE_MSVC ) || defined( ANI_COMPILER_TYPE_GCC ) || defined( ANI_COMPILER_TYPE_RVCT ) ) +#error "NONE of the ANI_COMPILER_TYPE_xxx are defined for this build" + +#endif + + + +// some differences related to the compiler being used... +#if defined ( ANI_COMPILER_TYPE_GCC ) + +#define ANI_INLINE_FUNCTION static __inline__ + +#elif defined( ANI_COMPILER_TYPE_MSVC ) + +#define ANI_INLINE_FUNCTION __inline + +#elif defined( ANI_COMPILER_TYPE_RVCT ) + +#define ANI_INLINE_FUNCTION INLINE + +#else + +#error "invalid ANI_COMPILER_TYPE definition" + +#endif +#endif + + + + +// Common type definitions... + + +typedef tANI_U32 tANI_U32_OR_PTR; + +// Buffer address; could be virt or phys; could be 32- or 64-bit depending on compile option +typedef tANI_U32_OR_PTR tANI_BUFFER_ADDR; +// which boolean is the most usefule...or both ? + +typedef enum tagAniBoolean +{ + eANI_BOOLEAN_FALSE = 0, + eANI_BOOLEAN_TRUE, + + eANI_BOOLEAN_OFF = 0, + eANI_BOOLEAN_ON = 1, +} eAniBoolean; + + + +// +// MAC address data type... +// +// review the usefulness of this type. I suspect this type is not +// real useful unless we provide some 'helper' functions to manage +// the MAC addresses. +// +#define ANI_MAC_ADDR_SIZE ( 6 ) +typedef tANI_U8 tAniMacAddr[ ANI_MAC_ADDR_SIZE ]; + + + + + +/** ------------------------------------------------------------------------- * + + \typedef tHddHandle + + \brief Handle to the HDD. The HDD handle is given to the HAL from + the HDD on halOpen. The HDD handle is an input to all HDD/PAL function + calls and represents an opaque handle to the HDD instance that is tied + to the HAL instance, opened through halOpen. + + The HDD must be able to derive it's internal instance structure pointer + through this handle. hint hint... + + -------------------------------------------------------------------------- */ +typedef void *tHddHandle; +// define a value for an invalid HAL handle..... +#define HDD_INVALID_HDD_HANDLE ( NULL ) + + +// For packet classification routines +#define PAL_BIT_MASK(offset) (1 << (offset)) +#define PAL_PKT_FLD_DSCP_OFFSET 0 +#define PAL_PKT_FLD_8021P_OFFSET 1 + +#define PAL_PKT_FLD_DSCP_MASK PAL_BIT_MASK(PAL_PKT_FLD_DSCP_OFFSET) +#define PAL_PKT_FLD_8021P_MASK PAL_BIT_MASK(PAL_PKT_FLD_8021P_OFFSET) + + + +/* +This represent an object for a spin lock and it is platform dependant +*/ +//User of this variable must initialize it to PAL_INVALID_SPINLOCK_HANDLE in order for validation to work. +typedef void * tPalSpinLockHandle; + +#define PAL_INVALID_SPINLOCK_HANDLE (NULL) + +/* + * This represent an object for a semaphore and it is platform dependant + */ +typedef void * tPalSemaphoreHandle; + + +#define PAL_TICKS_PER_SECOND 100 + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/wlan_qct_hal.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/wlan_qct_hal.h new file mode 100644 index 0000000000000..7091d2e8dd30c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/legacy/wlan_qct_hal.h @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef WLAN_QCT_HAL_H +#define WLAN_QCT_HAL_H +#include "vos_status.h" +#include "halTypes.h" +#ifndef PALTYPES_H__ + + +/// unsigned 8-bit types +#define tANI_U8 v_U8_t + +/// unsigned 16-bit types +#define tANI_U16 v_U16_t + +/// unsigned 32-bit types +#define tANI_U32 v_U32_t + +/// signed 8-bit types +#define tANI_S8 v_S7_t + +/// signed 16-bit types +#define tANI_S16 v_S15_t + +/// signed 32-bit types +#define tANI_S32 v_S31_t + +#define eHalStatus VOS_STATUS + +#endif +#define QWLAN_HAL_DXE0_MASTERID 5 + +typedef struct sHalBdGeneric { + /* 0x00 */ + // ENDIAN BEGIN + tANI_U32 dpuRF : 8; + tANI_U32 dpuSignature:3; /* Signature on RA's DPU descriptor */ + tANI_U32 staSignature:3; + tANI_U32 reserved : 14; + tANI_U32 dpuNE : 1; + tANI_U32 dpuNC : 1; + tANI_U32 bdt : 2; /* BD type */ + // ENDIAN END + + /* 0x04 */ + // ENDIAN BEGIN + tANI_U32 reserved1:32; + // ENDIAN END + + + /* 0x08 */ + // ENDIAN BEGIN + tANI_U32 headPduIdx : 16; /* Head PDU index */ + tANI_U32 tailPduIdx : 16; /* Tail PDU index */ + // ENDIAN END + + /* 0x0c */ + // ENDIAN BEGIN + tANI_U32 mpduHeaderLength : 8; /* MPDU header length */ + tANI_U32 mpduHeaderOffset : 8; /* MPDU header start offset */ + tANI_U32 mpduDataOffset : 9; /* MPDU data start offset */ + tANI_U32 pduCount : 7; /* PDU count */ + // ENDIAN END + + /* 0x10 */ + // ENDIAN BEGIN + tANI_U32 mpduLength : 16; /* MPDU length */ + tANI_U32 reserved3:4; /* DPU compression feedback */ + tANI_U32 tid : 4; /* Traffic identifier, tid */ + tANI_U32 rateIndex : 8; + // ENDIAN END + + /* 0x14 */ + // ENDIAN BEGIN + tANI_U32 dpuDescIdx : 8; + tANI_U32 addr1Index : 8; //A1 index after RxP binary search + tANI_U32 addr2Index : 8; //A2 index after RxP binary search + tANI_U32 addr3Index : 8; //A3 index after RxP binary search + // ENDIAN END +//}__ani_attr_packed __ani_attr_aligned_4 tHalBdGeneric, *tpHalBdGeneric; +} tHalBdGeneric, *tpHalBdGeneric; + + +/* + * PDU without BD + */ + +typedef struct sHalPdu { + tANI_U8 payload[124]; + tANI_U32 nextPduIdx; /* LSB 16 bits */ +//} __ani_attr_packed __ani_attr_aligned_4 tHalPdu, *tpHalPdu; +} tHalPdu, *tpHalPdu; + +/* UAPSD parameters passed per AC to HAL from TL */ +typedef struct sUapsdInfo { + tANI_U8 staidx; // STA index + tANI_U8 ac; // Access Category + tANI_U8 up; // User Priority + tANI_U32 srvInterval; // Service Interval + tANI_U32 susInterval; // Suspend Interval + tANI_U32 delayInterval; // Delay Interval +} tUapsdInfo, tpUapsdInfo; + +#define HAL_TXBD_BDRATE_DEFAULT 0 +#define HAL_TXBD_BDRATE_FIRST 1 +#define HAL_TXBD_BDRATE_SECOND 2 +#define HAL_TXBD_BDRATE_THIRD 3 + +#define HAL_FRAME_TYPE_MASK 0x30 +#define HAL_FRAME_TYPE_OFFSET 0x4 +#define HAL_FRAME_SUBTYPE_MASK 0x0F + +#define HAL_TXBD_BD_SSN_FILL_HOST 0 +#define HAL_TXBD_BD_SSN_FILL_DPU_NON_QOS 1 +#define HAL_TXBD_BD_SSN_FILL_DPU_QOS 2 + +#define HAL_ACKPOLICY_ACK_REQUIRED 0 +#define HAL_ACKPOLICY_ACK_NOTREQUIRED 1 + +#define HAL_BDRATE_BCDATA_FRAME 1 +#define HAL_BDRATE_BCMGMT_FRAME 2 +#define HAL_BDRATE_CTRL_FRAME 3 + +/* Default values for FillTx BD */ +#define HAL_DEFAULT_UNICAST_ENABLED 1 +#define HAL_RMF_DISABLED 0 +#define HAL_RMF_ENABLED 1 +#define HAL_NO_ENCRYPTION_DISABLED 0 +#define HAL_NO_ENCRYPTION_ENABLED 1 + +#define WLANHAL_RX_BD_ADDR3_SELF_IDX 0 + +// Should not use tHalTxBd nor tHalRxBd. UMAC doesn't know these HAL structure. +#define WLANHAL_TX_BD_HEADER_SIZE 40 +#define WLANHAL_RX_BD_HEADER_SIZE 76 + + +#define WLANHAL_RX_BD_HEADER_OFFSET 0 + +#define WLANHAL_RX_BD_GET_MPDU_H_OFFSET( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduHeaderOffset) + +#define WLANHAL_RX_BD_GET_MPDU_D_OFFSET( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduDataOffset) + +#define WLANHAL_RX_BD_GET_MPDU_LEN( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduLength) + +#define WLANHAL_RX_BD_GET_MPDU_H_LEN( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduHeaderLength) + +#define WLANHAL_RX_BD_GET_FT( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->ft) + +#define WLANHAL_RX_BD_GET_LLC( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->llc) + +#define WLANHAL_RX_BD_GET_TID( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->tid) + +#define WLANHAL_RX_BD_GET_ASF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->asf) + +#define WLANHAL_RX_BD_GET_AEF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->aef) + +#define WLANHAL_RX_BD_GET_LSF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->lsf) + +#define WLANHAL_RX_BD_GET_ESF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->esf) + +#define WLANHAL_RX_BD_GET_STA_ID( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr2Index) +#define WLANHAL_RX_BD_GET_ADDR3_IDX( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr3Index) +#define WLANHAL_RX_BD_GET_ADDR1_IDX( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr1Index) + +#define WLANHAL_TX_BD_GET_TID( _pvBDHeader ) (((tpHalTxBd)_pvBDHeader)->tid) +#define WLANHAL_TX_BD_GET_STA_ID( _pvBDHeader ) (((tpHalTxBd)_pvBDHeader)->staIndex) + +#define WLANHAL_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->dpuSignature) + +#define WLANHAL_FC_RX_BD_REPORT_CONTENT_SIZE (2 * HAL_NUM_STA * sizeof(tANI_U8)) // size of fcSTATxQLen[HAL_NUM_STA]+fcSTACurTxRate[HAL_NUM_STA] +#define WLANHAL_FC_TX_BD_HEADER_SIZE sizeof(tHalFcTxBd) +#define WLANHAL_RX_BD_GET_FC( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fc) +#define WLANHAL_RX_BD_GET_RX_TIME_STAMP( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->mclkRxTimestamp) +#define WLANHAL_RX_BD_GET_STA_VALID_MASK( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAValidMask) +#define WLANHAL_RX_BD_GET_STA_PS_STATE( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAPwrSaveStateMask) +#define WLANHAL_RX_BD_GET_STA_TH_IND( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAThreshIndMask) +#define WLANHAL_RX_BD_GET_STA_TXQ_STATUS( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTATxQStatus) +#define WLANHAL_RX_BD_GET_STA_TXQ_LEN( _pvBDHeader, staIdx ) (((tpHalFcRxBd)_pvBDHeader)->fcSTATxQLen[staIdx]) +#define WLANHAL_RX_BD_GET_STA_CUR_TX_RATE( _pvBDHeader, staIdx ) (((tpHalFcRxBd)_pvBDHeader)->fcSTACurTxRate[staIdx]) + +#define WLANHAL_TX_BD_GET_RMF(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rmf) + +#define WLANHAL_TX_BD_GET_UB(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->ub) + +#define WLANHAL_RX_BD_GET_RMF(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rmf) + +#define WLANHAL_RX_BD_GET_UB(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->ub) + +#define WLANHAL_RX_BD_GET_RATEINDEX(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rateIndex) + +#define WLANHAL_RX_BD_GET_TIMESTAMP(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->mclkRxTimestamp) + +#define tHalFcRxBd halFcRxBd_type +#define tpHalFcRxBd phalFcRxBd_type +#define tHalFcTxBd halFcTxBd_type +#define tpHalFcTxBd pHalFcTxBd_type +#define tHalFcTxParams tFcTxParams_type +#define tHalFcRxParams tFcRxParams_type +#define tpHalFcTxParams pFcTxParams_type +#define tpHalFcRxParams pFcRxParams_type + +/*------------ RSSI and SNR Information extraction -------------*/ +#define WLANHAL_RX_BD_GET_RSSI0( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 24) & 0xff) +#define WLANHAL_RX_BD_GET_RSSI1( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 16) & 0xff) +#define WLANHAL_RX_BD_GET_RSSI2( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 0) & 0xff) +#define WLANHAL_RX_BD_GET_RSSI3( _pvBDHeader ) \ + ((((tpHalRxBd)_pvBDHeader)->phyStats0) & 0xff) + +// Get the average of the 4 values. +#define WLANHAL_GET_RSSI_AVERAGE( _pvBDHeader ) \ + (((WLANHAL_RX_BD_GET_RSSI0(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI1(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI2(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI3(_pvBDHeader))) / 4) + +// Get the SNR value from PHY Stats +#define WLANHAL_RX_BD_GET_SNR( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats1) >> 24) & 0xff) +/*-----------------------------------------------------------------*/ +#define WLANHAL_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->dpuSignature) + + +#define WLANHAL_TX_BD_SET_MPDU_DATA_OFFSET( _bd, _off ) (((tpHalTxBd)_bd)->mpduDataOffset = _off) + +#define WLANHAL_TX_BD_SET_MPDU_HEADER_OFFSET( _bd, _off ) (((tpHalTxBd)_bd)->mpduHeaderOffset = _off) + +#define WLANHAL_TX_BD_SET_MPDU_HEADER_LEN( _bd, _len ) (((tpHalTxBd)_bd)->mpduHeaderLength = _len) + +#define WLANHAL_TX_BD_SET_MPDU_LEN( _bd, _len ) (((tpHalTxBd)_bd)->mpduLength = _len) + +#define WLANHAL_RX_BD_GET_BA_OPCODE(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderOpcode) + +#define WLANHAL_RX_BD_GET_BA_FI(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderFwdIdx) + +#define WLANHAL_RX_BD_GET_BA_SI(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderSlotIdx) + +#define WLANHAL_RX_BD_GET_BA_CSN(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->currentPktSeqNo) + +#define WLANHAL_RX_BD_GET_BA_ESN(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->expectedPktSeqNo) + +#define WLANHAL_RX_BD_GET_RXP_FLAGS(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rxpFlags) + +#define WLANHAL_RX_BD_GET_TYPE_SUBTYPE(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->frameTypeSubtype) +#define WLANHAL_RX_BD_SET_TYPE_SUBTYPE( _bd, _typeSubtype ) (((tpHalRxBd)_bd)->frameTypeSubtype = _typeSubtype) + + +#define WLANHAL_RX_BD_ASF_SET 1 /*The value of the field when set and pkt is AMSDU*/ + +#define WLANHAL_RX_BD_FSF_SET 1 + +#define WLANHAL_RX_BD_LSF_SET 1 + +#define WLANHAL_RX_BD_AEF_SET 1 + + +#define WLANHAL_RX_BD_LLC_PRESENT 0 /*The value of the field when LLC is present*/ + +#define WLANHAL_RX_BD_FT_DONE 1 /* The value of the field when frame xtl was done*/ + +/*DPU_FEEDBACK_WPI_UNPROTECTED macro defined in volansdefs.h which is not available + for UMAC in prima so declared it here */ +#define DPU_FEEDBACK_WPI_UNPROTECTED 0x20 +#define WLANHAL_RX_IS_UNPROTECTED_WPI_FRAME(_pvBDHeader) \ + (DPU_FEEDBACK_WPI_UNPROTECTED == ((WDI_RxBdType *)_pvBDHeader)->dpuFeedback) + +/*========================================================================== + + FUNCTION WLANHAL_RxBD_GetFrameTypeSubType + + DESCRIPTION + Called by TL to retrieve the type/subtype of the received frame. + + DEPENDENCIES + TL should pass a valid RxBD buffer pointer. + + PARAMETERS + + IN + pvBDHeader: Void pointer to the RxBD buffer. + usFrmCtrl:the frame ctrl of the 802.11 header + + RETURN VALUE + A byte which contains both type and subtype info. LSB four bytes (b0 to b3) + is subtype and b5-b6 is type info. + + SIDE EFFECTS + +============================================================================*/ + +tANI_U8 WLANHAL_RxBD_GetFrameTypeSubType(v_PVOID_t _pvBDHeader, tANI_U16 usFrmCtrl); + + +#define HAL_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. +#define HAL_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. +#define HAL_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(LIBRA_WAPI_SUPPORT) +#define HAL_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + +#define HAL_TRIGGER_ENABLED_AC_MASK 0x10 //bit 4 for data frames belonging to trigger enabled AC +#define HAL_USE_NO_ACK_REQUESTED_MASK 0x20 + +#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames +#define HAL_USE_PEER_STA_REQUESTED_MASK 0x80 //bit 7 will be used to control frames for p2p interface + +#ifdef FEATURE_WLAN_TDLS +#define HAL_TDLS_PEER_STA_MASK 0x80 //bit 7 set for TDLS peer station +#endif + +/*========================================================================== + + FUNCTION WLANHAL_FillTxBd + + DESCRIPTION + Called by PE to register as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context;a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management + frame to be transmitted + usFrmLen: the length of the frame to be transmitted; information + is already included in the vOSS buffer + wFrmType: the type of the frame being transmitted + tid: tid used to transmit this frame + pfnCompTxFunc: function pointer to the transmit complete routine + voosBDHeader: pointer to the BD header + txFlag: can have appropriate bit setting as required + + #define HAL_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. + #define HAL_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. + #define HAL_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(FEATURE_WLAN_WAPI) + #define HAL_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + + uTimestamp: pkt timestamp + + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANHAL_FillTxBd(void *pAdapter, tANI_U8 typeSubtype, void *pDestMacAddr, void *pAddr2, + tANI_U8* ptid, tANI_U8 disableFrmXtl, void *pTxBd, tANI_U8 txFlag, tANI_U32 timeStamp); + +VOS_STATUS WLANHAL_FillFcTxBd(void *pVosGCtx, void *pFcParams, void *pFcTxBd); +/** To swap the report part of FC RxBD */ +void WLANHAL_SwapFcRxBd(tANI_U8 *pBd); + +/* To swap the data */ +void WLANHAL_Swap32Bytes(tANI_U8* pData, tANI_U32 size); + +/** To swap the RxBD */ +void WLANHAL_SwapRxBd(tANI_U8 *pBd); +void WLANHAL_RxAmsduBdFix(void *pVosGCtx,v_PVOID_t _pvBDHeader); + +#ifdef WLAN_PERF +tANI_U32 WLANHAL_TxBdFastFwd(void *pAdapter, tANI_U8 *pDestMac, tANI_U8 tid, tANI_U8 unicastDst, void *pTxBd, tANI_U16); +#endif + +VOS_STATUS WLANHAL_EnableUapsdAcParams(void* pVosGCtx, tANI_U8 staIdx, tUapsdInfo *pUapsdInfo); +VOS_STATUS WLANHAL_DisableUapsdAcParams(void* pVosGCtx, tANI_U8 staIdx, tANI_U8 ac); + +VOS_STATUS WLANHAL_EnableIdleBdPduInterrupt(void* pVosGCtx, tANI_U8 idleBdPduThreshold); + +#ifdef FEATURE_ON_CHIP_REORDERING +tANI_U8 WLANHAL_IsOnChipReorderingEnabledForTID(void* pVosGCtx, tANI_U8 staIdx, tANI_U8 tid); +#endif + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +v_BOOL_t WLANHAL_IsHwFrameTxTranslationCapable(v_PVOID_t pVosGCtx, tANI_U8 staIdx); +#endif + +#define tHalRxBd halRxBd_type +#define tpHalRxBd phalRxBd_type + +#define tHalTxBd halTxBd_type +#define tpHalTxBd pHalTxBd_type + +#ifdef BA_PARAM_STRUCTURE +#else +#define BA_PARAM_STRUCTURE +// +// HAL --> TL +// Messages indicating the setup and/or teardown of +// A-MPDU/BA sessions with a given peer HT MAC entity +// + +// +// A data structure identifying all of the variables +// in a typical A-MPDU/BA setup +// +typedef struct sBAParams +{ + + // A unique BA Session ID that has been assigned by HAL + // for the curent BA Session + tANI_U16 baSessionID; + + // TID for which the BA session has been setup + tANI_U8 baTID; + + // BA Buffer Size allocated for the current BA session //Should be deleted. needs TL change. use winSize instead + tANI_U8 baBufferSize; + + tANI_U16 SSN; + tANI_U8 winSize; + tANI_U8 STAID; + +} tBAParams, *tpBAParams; + +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_HDD_ADDBA_RSP +// +typedef struct sAddBARsp +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + //BA session ID + tANI_U16 baSessionID; + + tANI_U16 replyWinSize; +}tAddBARsp, *tpAddBARsp; + +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_ADDBA_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpAddBAInd +// +typedef struct sAddBAInd +{ + + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + tBAParams baSession; + +} tAddBAInd, *tpAddBAInd; + +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_DELBA_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpDelBAInd +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_BA_FAIL_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpDelBAInd +// +typedef struct sDelBAInd +{ + tANI_U8 staIdx; + + tANI_U8 baTID; + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + +} tDelBAInd, *tpDelBAInd; +#endif + +/*=============================================== + * + * TL <-> HAL structures + * + *=============================================== + */ +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_TL_FLUSH_AC_REQ +// +typedef struct sFlushACReq +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + +} tFlushACReq, *tpFlushACReq; + +// +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_TL_FLUSH_AC_RSP +// +typedef struct sFlushACRsp +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + + // status of the Flush operation + tANI_U8 status; +} tFlushACRsp, *tpFlushACRsp; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda.h new file mode 100644 index 0000000000000..89c0e35c742da --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda.h @@ -0,0 +1,1185 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef WLAN_QCT_WDA_H +#define WLAN_QCT_WDA_H + +/*=========================================================================== + + W L A N DEVICE ADAPTATION L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan adaptation layer for Prima + and Volans. + + For Volans this layer is actually a thin layer that maps all WDA messages and + functions to equivalent HAL messages and functions. The reason this layer was introduced + was to keep the UMAC identical across Prima and Volans. This layer provides the glue + between SME, PE , TL and HAL. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------- +10/05/2011 haparna Adding support for Keep Alive Feature +01/27/2011 rnair Adding WDA support for Volans. +12/08/2010 seokyoun Move down HAL interfaces from TL to WDA + for UMAC convergence btween Volans/Libra and Prima +08/25/2010 adwivedi WDA Context and exposed API's +=========================================================================== */ + +#include "aniGlobal.h" + +#include "wma_api.h" +#include "wma_stub.h" +#include "i_vos_packet.h" + +/* Add Include */ + +typedef enum +{ + WDA_INIT_STATE, + WDA_START_STATE, + WDA_READY_STATE, + WDA_PRE_ASSOC_STATE, + WDA_BA_UPDATE_TL_STATE, + WDA_BA_UPDATE_LIM_STATE, + WDA_STOP_STATE, + WDA_CLOSE_STATE +}WDA_state; + +typedef enum +{ + WDA_PROCESS_SET_LINK_STATE, + WDA_IGNORE_SET_LINK_STATE +}WDA_processSetLinkStateStatus; + +typedef enum +{ + WDA_DISABLE_BA, + WDA_ENABLE_BA +}WDA_BaEnableFlags; + +typedef enum +{ + WDA_INVALID_STA_INDEX, + WDA_VALID_STA_INDEX +}WDA_ValidStaIndex; +typedef enum +{ + eWDA_AUTH_TYPE_NONE, //never used + // MAC layer authentication types + eWDA_AUTH_TYPE_OPEN_SYSTEM, + // Upper layer authentication types + eWDA_AUTH_TYPE_WPA, + eWDA_AUTH_TYPE_WPA_PSK, + + eWDA_AUTH_TYPE_RSN, + eWDA_AUTH_TYPE_RSN_PSK, + eWDA_AUTH_TYPE_FT_RSN, + eWDA_AUTH_TYPE_FT_RSN_PSK, + eWDA_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + eWDA_AUTH_TYPE_WAPI_WAI_PSK, + eWDA_AUTH_TYPE_CCKM_WPA, + eWDA_AUTH_TYPE_CCKM_RSN, + eWDA_AUTH_TYPE_WPA_NONE, + eWDA_AUTH_TYPE_AUTOSWITCH, + eWDA_AUTH_TYPE_SHARED_KEY, + eWDA_NUM_OF_SUPPORT_AUTH_TYPE, + eWDA_AUTH_TYPE_FAILED = 0xff, + eWDA_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED, +}WDA_AuthType; + +#ifdef FEATURE_WLAN_TDLS +typedef enum +{ + WDA_TDLS_PEER_STATE_PEERING, + WDA_TDLS_PEER_STATE_CONNECTED, + WDA_TDLS_PEER_STATE_TEARDOWN, +} WDA_TdlsPeerState; +/* WMI_TDLS_SET_OFFCHAN_MODE_CMDID */ +typedef enum +{ + WDA_TDLS_ENABLE_OFFCHANNEL, + WDA_TDLS_DISABLE_OFFCHANNEL +}WDA_TdlsOffchanMode; +#endif /* FEATURE_WLAN_TDLS */ + +/*-------------------------------------------------------------------------- + Utilities + --------------------------------------------------------------------------*/ + +#define WDA_TLI_CEIL( _a, _b) (( 0 != (_a)%(_b))? (_a)/(_b) + 1: (_a)/(_b)) + + +#define IS_MCC_SUPPORTED 1 +#define IS_FEATURE_SUPPORTED_BY_FW(feat_enum_value) wma_getFwWlanFeatCaps(feat_enum_value) + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +#define IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE 1 +#else +#define IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE 0 +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE 1 +#else +#define IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE 0 +#endif + +#define IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE 1 + +#ifdef FEATURE_WLAN_TDLS +#define IS_ADVANCE_TDLS_ENABLE 0 +#endif + + +/*-------------------------------------------------------------------------- + Definitions for Data path APIs + --------------------------------------------------------------------------*/ + +/*As per 802.11 spec */ +#define WDA_TLI_MGMT_FRAME_TYPE 0x00 +#define WDA_TLI_CTRL_FRAME_TYPE 0x10 +#define WDA_TLI_DATA_FRAME_TYPE 0x20 + +/*802.3 header definitions*/ +#define WDA_TLI_802_3_HEADER_LEN 14 +/*802.11 header definitions - header len without QOS ctrl field*/ +#define WDA_TLI_802_11_HEADER_LEN 24 + +/*Determines the header len based on the disable xtl field*/ +#define WDA_TLI_MAC_HEADER_LEN( _dxtl) \ + ( ( 0 == _dxtl )? \ + WDA_TLI_802_3_HEADER_LEN:WDA_TLI_802_11_HEADER_LEN ) + +/* TX channel enum type: + + We have five types of TX packets so far and want to block/unblock each + traffic individually according to, for example, low resouce condition. + Define five TX channels for UMAC here. WDA can map these logical + channels to physical DXE channels if needed. +*/ +typedef enum +{ + WDA_TXFLOW_AC_BK = 0, + WDA_TXFLOW_AC_BE = 1, + WDA_TXFLOW_AC_VI = 2, + WDA_TXFLOW_AC_VO = 3, + WDA_TXFLOW_MGMT = 4, + WDA_TXFLOW_BAP = 1, /* BAP is sent as BE */ + WDA_TXFLOW_FC = 1, /* FC is sent as BE */ + WDA_TXFLOW_MAX +} WDA_TXFlowEnumType; + +#define WDA_TXFLOWMASK 0x1F /* 1~4bit:low priority ch / 5bit: high */ + +/* --------------------------------------------------------------------- + Libra and Volans specifics + + TODO Consider refactoring it and put it into two separate headers, + one for Prima and one for Volans + ----------------------------------------------------------------------*/ + +/* For backward compatability with SDIO. It's BAL header size for SDIO + interface. It's nothing for integrated SOC */ +#define WDA_DXE_HEADER_SIZE 0 + + +/*Minimum resources needed - arbitrary*/ + +/*DXE + SD*/ +#define WDA_WLAN_LIBRA_HEADER_LEN (20 + 8) + +#define WDA_TLI_BD_PDU_RESERVE_THRESHOLD 10 + + +# define WDA_TLI_MIN_RES_MF 1 +# define WDA_TLI_MIN_RES_BAP 2 +# define WDA_TLI_MIN_RES_DATA 3 + +# define WDA_NUM_STA 8 + +/* For backward compatability with SDIO. + + For SDIO interface, calculate the TX frame length and number of PDU + to transfter the frame. + + _vosBuff: IN VOS pakcet buffer pointer + _usPktLen: OUT VOS packet length in bytes + _uResLen: OUT Number of PDU to hold this VOS packet + _uTotalPktLen: OUT Totoal packet length including BAL header size + + For integrated SOC, _usPktLen and _uTotalPktLen is VOS pakcet length + which does include BD header length. _uResLen is hardcoded 2. + */ + +#ifdef WINDOWS_DT +#define WDA_TLI_PROCESS_FRAME_LEN( _vosBuff, _usPktLen, \ + _uResLen, _uTotalPktLen) \ + do \ + { \ + _usPktLen = wpalPacketGetFragCount((wpt_packet*)_vosBuff) + 1/*BD*/;\ + _uResLen = _usPktLen; \ + _uTotalPktLen = _usPktLen; \ + } \ + while ( 0 ) +#else /* WINDOWS_DT */ +#define WDA_TLI_PROCESS_FRAME_LEN( _vosBuff, _usPktLen, \ + _uResLen, _uTotalPktLen) \ + do \ + { \ + _usPktLen = 2; /* Need 1 descriptor per a packet + packet*/ \ + _uResLen = 2; /* Assume that we spends two DXE descriptor */ \ + _uTotalPktLen = _usPktLen; \ + } \ + while ( 0 ) +#endif /* WINDOWS_DT */ + + + +/*-------------------------------------------------------------------------- + Message Definitions + --------------------------------------------------------------------------*/ + +/* TX Tranmit request message. It serializes TX request to TX thread. + The message is processed in TL. +*/ +#define WDA_DS_TX_START_XMIT WLANTL_TX_START_XMIT +#define WDA_DS_FINISH_ULA WLANTL_FINISH_ULA + +#define VOS_TO_WPAL_PKT(_vos_pkt) ((wpt_packet*)_vos_pkt) + +#define WDA_TX_PACKET_FREED 0X0 + +/* Approximate amount of time to wait for WDA to stop WDI considering 1 pendig req too*/ +#define WDA_STOP_TIMEOUT ( (WDI_RESPONSE_TIMEOUT * 2) + WDI_SET_POWER_STATE_TIMEOUT + 5) +/*-------------------------------------------------------------------------- + Functions + --------------------------------------------------------------------------*/ +typedef void (*pWDATxRxCompFunc)( v_PVOID_t pContext, void *pData, + v_BOOL_t bFreeData ); + +//callback function for TX complete +//parameter 1 - global pMac pointer +//parameter 2 - txComplete status : 1- success, 0 - failure. +typedef eHalStatus (*pWDAAckFnTxComp)(tpAniSirGlobal, tANI_U32); + +/* generic callback for updating parameters from target to UMAC */ +typedef void (*wda_tgt_cfg_cb) (void *context, void *param); + +/* + * callback for Indicating Radar to HDD and disable Tx Queues + * to stop accepting data Tx packets from netif as radar is + * found on the current operating channel + */ +typedef void (*wda_dfs_radar_indication_cb) (void *context, void *param); + +typedef struct +{ + tANI_U16 ucValidStaIndex ; + /* + * each bit in ucUseBaBitmap represent BA is enabled or not for this tid + * tid0 ..bit0, tid1..bit1 and so on.. + */ + tANI_U8 ucUseBaBitmap ; + tANI_U8 bssIdx; + tANI_U32 framesTxed[STACFG_MAX_TC]; +}tWdaStaInfo, *tpWdaStaInfo ; + +/* group all the WDA timers into this structure */ +typedef struct +{ + /* BA activity check timer */ + TX_TIMER baActivityChkTmr ; + + /* Tx Complete Timeout timer */ + TX_TIMER TxCompleteTimer ; + + /* Traffic Stats timer */ + TX_TIMER trafficStatsTimer ; +}tWdaTimers ; +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDA_MAX_STA (41) +#else +#define WDA_MAX_STA (16) +#endif +typedef struct +{ + v_PVOID_t pVosContext; /* global VOSS context*/ + v_PVOID_t pWdiContext; /* WDI context */ + WDA_state wdaState ; /* WDA state tracking */ + v_PVOID_t wdaWdiCfgApiMsgParam ; /* WDI API paramter tracking */ + vos_event_t wdaWdiEvent; /* WDI API sync event */ + + /* Event to wait for tx completion */ + vos_event_t txFrameEvent; + + /* call back function for tx complete*/ + pWDATxRxCompFunc pTxCbFunc; + /* call back function for tx packet ack */ + pWDAAckFnTxComp pAckTxCbFunc; + tANI_U32 frameTransRequired; + tSirMacAddr macBSSID; /*BSSID of the network */ + tSirMacAddr macSTASelf; /*Self STA MAC*/ + + + tWdaStaInfo wdaStaInfo[WDA_MAX_STA]; + + tANI_U8 wdaMaxSta; + tWdaTimers wdaTimers; + + /* driver mode, PRODUCTION or FTM */ + tDriverType driverMode; + + /* FTM Command Request tracking */ + v_PVOID_t wdaFTMCmdReq; + + /* Event to wait for suspend data tx*/ + vos_event_t suspendDataTxEvent; + /* Status frm TL after suspend/resume Tx */ + tANI_U8 txStatus; + /* Flag set to true when TL suspend timesout.*/ + tANI_U8 txSuspendTimedOut; + + vos_event_t waitOnWdiIndicationCallBack; + + /* version information */ + tSirVersionType wcnssWlanCompiledVersion; + tSirVersionType wcnssWlanReportedVersion; + tSirVersionString wcnssSoftwareVersionString; + tSirVersionString wcnssHardwareVersionString; + + + tSirLinkState linkState; + /* set, when BT AMP session is going on */ + v_BOOL_t wdaAmpSessionOn; + v_U32_t VosPacketToFree; + v_BOOL_t needShutdown; + v_BOOL_t wdiFailed; + v_BOOL_t wdaTimersCreated; + + /* Event to wait for WDA stop on FTM mode */ + vos_event_t ftmStopDoneEvent; + +} tWDA_CbContext ; + +typedef struct +{ + v_PVOID_t pWdaContext; /* pointer to WDA context*/ + v_PVOID_t wdaMsgParam; /* PE parameter tracking */ + v_PVOID_t wdaWdiApiMsgParam; /* WDI API paramter tracking */ +} tWDA_ReqParams; + +typedef struct { + v_UINT_t param_id; + v_UINT_t param_value; + v_UINT_t param_sec_value; + v_UINT_t param_vdev_id; + v_UINT_t param_vp_dev; +} wda_cli_set_cmd_t; + +/* + * FUNCTION: WDA_MgmtDSTxPacket + * Forward TX management frame to WDI + */ + +VOS_STATUS WDA_TxPacket(void *pWDA, + void *pFrmBuf, + tANI_U16 frmLen, + eFrameType frmType, + eFrameTxDir txDir, + tANI_U8 tid, + pWDATxRxCompFunc pCompFunc, + void *pData, + pWDAAckFnTxComp pAckTxComp, + tANI_U8 txFlag, + tANI_U8 sessionId, + bool tdlsflag); + +/* + * FUNCTION: WDA_open + * open WDA context + */ + +VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext, + wda_tgt_cfg_cb pTgtUpdCB, + wda_dfs_radar_indication_cb radar_ind_cb, + tMacOpenParameters *pMacParams ) ; + +#define WDA_start wma_start +#define WDA_MapChannel wma_map_channel + +#define WDA_NVDownload_Start(x) ({ VOS_STATUS_SUCCESS; }) + +#define WDA_preStart wma_pre_start +#define WDA_stop wma_stop +#define WDA_close wma_close +#define WDA_shutdown wma_shutdown +#define WDA_setNeedShutdown wma_setneedshutdown +#define WDA_needShutdown wma_needshutdown +#define WDA_McProcessMsg wma_mc_process_msg + +#define DPU_FEEDBACK_UNPROTECTED_ERROR 0x0F + + +#define WDA_GET_RX_MAC_HEADER(pRxMeta) \ + (tpSirMacMgmtHdr)(((t_packetmeta *)pRxMeta)->mpdu_hdr_ptr) + +#define WDA_GET_RX_MPDUHEADER3A(pRxMeta) \ + (tpSirMacDataHdr3a)(((t_packetmeta *)pRxMeta)->mpdu_hdr_ptr) + +#define WDA_GET_RX_MPDU_HEADER_LEN(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->mpdu_hdr_len) + +#define WDA_GET_RX_MPDU_LEN(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->mpdu_len) + +#define WDA_GET_RX_PAYLOAD_LEN(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->mpdu_data_len) + +#define WDA_GET_RX_MAC_RATE_IDX(pRxMeta) 0 + +#define WDA_GET_RX_MPDU_DATA(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->mpdu_data_ptr) + +#define WDA_GET_RX_MPDU_HEADER_OFFSET(pRxMeta) 0 + +#define WDA_GET_RX_UNKNOWN_UCAST(pRxMeta) 0 + +#define WDA_GET_RX_CH(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->channel) + +#define WDA_IS_RX_BCAST(pRxMeta) 0 + +#define WDA_GET_RX_FT_DONE(pRxMeta) 0 + +#define WDA_GET_RX_DPU_FEEDBACK(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->dpuFeedback) + +#define WDA_GET_RX_BEACON_SENT(pRxMeta) 0 + +#define WDA_GET_RX_TSF_LATER(pRxMeta) 0 + +#define WDA_GET_RX_TIMESTAMP(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->timestamp) + +#define WDA_IS_RX_IN_SCAN(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->scan) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define WDA_GET_OFFLOADSCANLEARN(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->offloadScanLearn) +#define WDA_GET_ROAMCANDIDATEIND(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->roamCandidateInd) +#define WDA_GET_SESSIONID(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->sessionId) + +#endif + +#ifdef FEATURE_WLAN_EXTSCAN +#define WMA_IS_EXTSCAN_SCAN_SRC(pRxMeta) \ + ((((t_packetmeta *)pRxMeta)->scan_src) == WMI_MGMT_RX_HDR_EXTSCAN) +#endif /* FEATURE_WLAN_EXTSCAN */ + +#define WDA_GET_RX_SNR(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->snr) + +#define WDA_GetWcnssWlanCompiledVersion WMA_GetWcnssWlanCompiledVersion +#define WDA_GetWcnssWlanReportedVersion WMA_GetWcnssWlanReportedVersion +#define WDA_GetWcnssSoftwareVersion WMA_GetWcnssSoftwareVersion +#define WDA_GetWcnssHardwareVersion WMA_GetWcnssHardwareVersion + +#define WDA_GET_RX_RFBAND(pRxMeta) 0 + + +tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); + + +#define WDA_MAX_TXPOWER_INVALID HAL_MAX_TXPOWER_INVALID + +/* rssi value normalized to noise floor of -96 dBm */ +#define WDA_GET_RX_RSSI_NORMALIZED(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->rssi) + +/* raw rssi based on actual noise floor in hardware */ +#define WDA_GET_RX_RSSI_RAW(pRxMeta) \ + (((t_packetmeta *)pRxMeta)->rssi_raw) + +//WDA Messages to HAL messages Mapping +#if 0 +//Required by SME +//#define WDA_SIGNAL_BT_EVENT SIR_HAL_SIGNAL_BT_EVENT - this is defined in sirParams.h +//#define WDA_BTC_SET_CFG SIR_HAL_BTC_SET_CFG + +//Required by PE +#define WDA_HOST_MSG_START SIR_HAL_HOST_MSG_START +#define WDA_INITIAL_CAL_FAILED_NTF SIR_HAL_INITIAL_CAL_FAILED_NTF +#define WDA_SHUTDOWN_REQ SIR_HAL_SHUTDOWN_REQ +#define WDA_SHUTDOWN_CNF SIR_HAL_SHUTDOWN_CNF +#define WDA_RADIO_ON_OFF_IND SIR_HAL_RADIO_ON_OFF_IND +#define WDA_RESET_CNF SIR_HAL_RESET_CNF +#define WDA_SetRegDomain \ + (eHalStatus halPhySetRegDomain(tHalHandle hHal, eRegDomainId regDomain)) +#endif + +#define WDA_APP_SETUP_NTF SIR_HAL_APP_SETUP_NTF +#define WDA_NIC_OPER_NTF SIR_HAL_NIC_OPER_NTF +#define WDA_INIT_START_REQ SIR_HAL_INIT_START_REQ +#define WDA_RESET_REQ SIR_HAL_RESET_REQ +#define WDA_HDD_ADDBA_REQ SIR_HAL_HDD_ADDBA_REQ +#define WDA_HDD_ADDBA_RSP SIR_HAL_HDD_ADDBA_RSP +#define WDA_DELETEBA_IND SIR_HAL_DELETEBA_IND +#define WDA_BA_FAIL_IND SIR_HAL_BA_FAIL_IND +#define WDA_TL_FLUSH_AC_REQ SIR_TL_HAL_FLUSH_AC_REQ +#define WDA_TL_FLUSH_AC_RSP SIR_HAL_TL_FLUSH_AC_RSP + +#define WDA_MSG_TYPES_BEGIN SIR_HAL_MSG_TYPES_BEGIN +#define WDA_ITC_MSG_TYPES_BEGIN SIR_HAL_ITC_MSG_TYPES_BEGIN +#define WDA_RADAR_DETECTED_IND SIR_HAL_RADAR_DETECTED_IND +#define WDA_WDT_KAM_RSP SIR_HAL_WDT_KAM_RSP +#define WDA_TIMER_TEMP_MEAS_REQ SIR_HAL_TIMER_TEMP_MEAS_REQ +#define WDA_TIMER_PERIODIC_STATS_COLLECT_REQ SIR_HAL_TIMER_PERIODIC_STATS_COLLECT_REQ +#define WDA_CAL_REQ_NTF SIR_HAL_CAL_REQ_NTF +#define WDA_MNT_OPEN_TPC_TEMP_MEAS_REQ SIR_HAL_MNT_OPEN_TPC_TEMP_MEAS_REQ +#define WDA_CCA_MONITOR_INTERVAL_TO SIR_HAL_CCA_MONITOR_INTERVAL_TO +#define WDA_CCA_MONITOR_DURATION_TO SIR_HAL_CCA_MONITOR_DURATION_TO +#define WDA_CCA_MONITOR_START SIR_HAL_CCA_MONITOR_START +#define WDA_CCA_MONITOR_STOP SIR_HAL_CCA_MONITOR_STOP +#define WDA_CCA_CHANGE_MODE SIR_HAL_CCA_CHANGE_MODE +#define WDA_TIMER_WRAP_AROUND_STATS_COLLECT_REQ SIR_HAL_TIMER_WRAP_AROUND_STATS_COLLECT_REQ + +/* + * New Taurus related messages + */ +#define WDA_ADD_STA_REQ SIR_HAL_ADD_STA_REQ +#define WDA_ADD_STA_RSP SIR_HAL_ADD_STA_RSP +#define WDA_ADD_STA_SELF_RSP SIR_HAL_ADD_STA_SELF_RSP +#define WDA_DEL_STA_SELF_RSP SIR_HAL_DEL_STA_SELF_RSP +#define WDA_DELETE_STA_REQ SIR_HAL_DELETE_STA_REQ +#define WDA_DELETE_STA_RSP SIR_HAL_DELETE_STA_RSP +#define WDA_ADD_BSS_REQ SIR_HAL_ADD_BSS_REQ +#define WDA_ADD_BSS_RSP SIR_HAL_ADD_BSS_RSP +#define WDA_DELETE_BSS_REQ SIR_HAL_DELETE_BSS_REQ +#define WDA_DELETE_BSS_RSP SIR_HAL_DELETE_BSS_RSP +#define WDA_INIT_SCAN_REQ SIR_HAL_INIT_SCAN_REQ +#define WDA_INIT_SCAN_RSP SIR_HAL_INIT_SCAN_RSP +#define WDA_START_SCAN_REQ SIR_HAL_START_SCAN_REQ +#define WDA_START_SCAN_RSP SIR_HAL_START_SCAN_RSP +#define WDA_END_SCAN_REQ SIR_HAL_END_SCAN_REQ +#define WDA_END_SCAN_RSP SIR_HAL_END_SCAN_RSP +#define WDA_FINISH_SCAN_REQ SIR_HAL_FINISH_SCAN_REQ +#define WDA_FINISH_SCAN_RSP SIR_HAL_FINISH_SCAN_RSP +#define WDA_SEND_BEACON_REQ SIR_HAL_SEND_BEACON_REQ +#define WDA_SEND_BEACON_RSP SIR_HAL_SEND_BEACON_RSP +#define WDA_SEND_PROBE_RSP_TMPL SIR_HAL_SEND_PROBE_RSP_TMPL + +#define WDA_INIT_CFG_REQ SIR_HAL_INIT_CFG_REQ +#define WDA_INIT_CFG_RSP SIR_HAL_INIT_CFG_RSP + +#define WDA_INIT_WM_CFG_REQ SIR_HAL_INIT_WM_CFG_REQ +#define WDA_INIT_WM_CFG_RSP SIR_HAL_INIT_WM_CFG_RSP + +#define WDA_SET_BSSKEY_REQ SIR_HAL_SET_BSSKEY_REQ +#define WDA_SET_BSSKEY_RSP SIR_HAL_SET_BSSKEY_RSP +#define WDA_SET_STAKEY_REQ SIR_HAL_SET_STAKEY_REQ +#define WDA_SET_STAKEY_RSP SIR_HAL_SET_STAKEY_RSP +#define WDA_DPU_STATS_REQ SIR_HAL_DPU_STATS_REQ +#define WDA_DPU_STATS_RSP SIR_HAL_DPU_STATS_RSP +#define WDA_GET_DPUINFO_REQ SIR_HAL_GET_DPUINFO_REQ +#define WDA_GET_DPUINFO_RSP SIR_HAL_GET_DPUINFO_RSP + +#define WDA_UPDATE_EDCA_PROFILE_IND SIR_HAL_UPDATE_EDCA_PROFILE_IND + +#define WDA_UPDATE_STARATEINFO_REQ SIR_HAL_UPDATE_STARATEINFO_REQ +#define WDA_UPDATE_STARATEINFO_RSP SIR_HAL_UPDATE_STARATEINFO_RSP + +#define WDA_UPDATE_BEACON_IND SIR_HAL_UPDATE_BEACON_IND +#define WDA_UPDATE_CF_IND SIR_HAL_UPDATE_CF_IND +#define WDA_CHNL_SWITCH_REQ SIR_HAL_CHNL_SWITCH_REQ +#define WDA_ADD_TS_REQ SIR_HAL_ADD_TS_REQ +#define WDA_DEL_TS_REQ SIR_HAL_DEL_TS_REQ +#define WDA_SOFTMAC_TXSTAT_REPORT SIR_HAL_SOFTMAC_TXSTAT_REPORT + +#define WDA_MBOX_SENDMSG_COMPLETE_IND SIR_HAL_MBOX_SENDMSG_COMPLETE_IND +#define WDA_EXIT_BMPS_REQ SIR_HAL_EXIT_BMPS_REQ +#define WDA_EXIT_BMPS_RSP SIR_HAL_EXIT_BMPS_RSP +#define WDA_EXIT_BMPS_IND SIR_HAL_EXIT_BMPS_IND +#define WDA_ENTER_BMPS_REQ SIR_HAL_ENTER_BMPS_REQ +#define WDA_ENTER_BMPS_RSP SIR_HAL_ENTER_BMPS_RSP +#define WDA_BMPS_STATUS_IND SIR_HAL_BMPS_STATUS_IND +#define WDA_MISSED_BEACON_IND SIR_HAL_MISSED_BEACON_IND + +#define WDA_CFG_RXP_FILTER_REQ SIR_HAL_CFG_RXP_FILTER_REQ +#define WDA_CFG_RXP_FILTER_RSP SIR_HAL_CFG_RXP_FILTER_RSP + +#define WDA_SWITCH_CHANNEL_RSP SIR_HAL_SWITCH_CHANNEL_RSP +#define WDA_P2P_NOA_ATTR_IND SIR_HAL_P2P_NOA_ATTR_IND +#define WDA_P2P_NOA_START_IND SIR_HAL_P2P_NOA_START_IND +#define WDA_PWR_SAVE_CFG SIR_HAL_PWR_SAVE_CFG + +#define WDA_REGISTER_PE_CALLBACK SIR_HAL_REGISTER_PE_CALLBACK +#define WDA_SOFTMAC_MEM_READREQUEST SIR_HAL_SOFTMAC_MEM_READREQUEST +#define WDA_SOFTMAC_MEM_WRITEREQUEST SIR_HAL_SOFTMAC_MEM_WRITEREQUEST + +#define WDA_SOFTMAC_MEM_READRESPONSE SIR_HAL_SOFTMAC_MEM_READRESPONSE +#define WDA_SOFTMAC_BULKREGWRITE_CONFIRM SIR_HAL_SOFTMAC_BULKREGWRITE_CONFIRM +#define WDA_SOFTMAC_BULKREGREAD_RESPONSE SIR_HAL_SOFTMAC_BULKREGREAD_RESPONSE +#define WDA_SOFTMAC_HOSTMESG_MSGPROCESSRESULT SIR_HAL_SOFTMAC_HOSTMESG_MSGPROCESSRESULT + +#define WDA_ADDBA_REQ SIR_HAL_ADDBA_REQ +#define WDA_ADDBA_RSP SIR_HAL_ADDBA_RSP +#define WDA_DELBA_IND SIR_HAL_DELBA_IND +#define WDA_DEL_BA_IND SIR_HAL_DEL_BA_IND +#define WDA_MIC_FAILURE_IND SIR_HAL_MIC_FAILURE_IND + +//message from sme to initiate delete block ack session. +#define WDA_DELBA_REQ SIR_HAL_DELBA_REQ +#define WDA_IBSS_STA_ADD SIR_HAL_IBSS_STA_ADD +#define WDA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND +#define WDA_SET_LINK_STATE SIR_HAL_SET_LINK_STATE +#define WDA_SET_LINK_STATE_RSP SIR_HAL_SET_LINK_STATE_RSP +#define WDA_ENTER_IMPS_REQ SIR_HAL_ENTER_IMPS_REQ +#define WDA_ENTER_IMPS_RSP SIR_HAL_ENTER_IMPS_RSP +#define WDA_EXIT_IMPS_RSP SIR_HAL_EXIT_IMPS_RSP +#define WDA_EXIT_IMPS_REQ SIR_HAL_EXIT_IMPS_REQ +#define WDA_SOFTMAC_HOSTMESG_PS_STATUS_IND SIR_HAL_SOFTMAC_HOSTMESG_PS_STATUS_IND +#define WDA_POSTPONE_ENTER_IMPS_RSP SIR_HAL_POSTPONE_ENTER_IMPS_RSP +#define WDA_STA_STAT_REQ SIR_HAL_STA_STAT_REQ +#define WDA_GLOBAL_STAT_REQ SIR_HAL_GLOBAL_STAT_REQ +#define WDA_AGGR_STAT_REQ SIR_HAL_AGGR_STAT_REQ +#define WDA_STA_STAT_RSP SIR_HAL_STA_STAT_RSP +#define WDA_GLOBAL_STAT_RSP SIR_HAL_GLOBAL_STAT_RSP +#define WDA_AGGR_STAT_RSP SIR_HAL_AGGR_STAT_RSP +#define WDA_STAT_SUMM_REQ SIR_HAL_STAT_SUMM_REQ +#define WDA_STAT_SUMM_RSP SIR_HAL_STAT_SUMM_RSP +#define WDA_REMOVE_BSSKEY_REQ SIR_HAL_REMOVE_BSSKEY_REQ +#define WDA_REMOVE_BSSKEY_RSP SIR_HAL_REMOVE_BSSKEY_RSP +#define WDA_REMOVE_STAKEY_REQ SIR_HAL_REMOVE_STAKEY_REQ +#define WDA_REMOVE_STAKEY_RSP SIR_HAL_REMOVE_STAKEY_RSP +#define WDA_SET_STA_BCASTKEY_REQ SIR_HAL_SET_STA_BCASTKEY_REQ +#define WDA_SET_STA_BCASTKEY_RSP SIR_HAL_SET_STA_BCASTKEY_RSP +#define WDA_REMOVE_STA_BCASTKEY_REQ SIR_HAL_REMOVE_STA_BCASTKEY_REQ +#define WDA_REMOVE_STA_BCASTKEY_RSP SIR_HAL_REMOVE_STA_BCASTKEY_RSP +#define WDA_ADD_TS_RSP SIR_HAL_ADD_TS_RSP +#define WDA_DPU_MIC_ERROR SIR_HAL_DPU_MIC_ERROR +#define WDA_TIMER_BA_ACTIVITY_REQ SIR_HAL_TIMER_BA_ACTIVITY_REQ +#define WDA_TIMER_CHIP_MONITOR_TIMEOUT SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT +#define WDA_TIMER_TRAFFIC_ACTIVITY_REQ SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ +#define WDA_TIMER_ADC_RSSI_STATS SIR_HAL_TIMER_ADC_RSSI_STATS +#define WDA_TIMER_TRAFFIC_STATS_IND SIR_HAL_TRAFFIC_STATS_IND + +#ifdef WLAN_FEATURE_11W +#define WDA_EXCLUDE_UNENCRYPTED_IND SIR_HAL_EXCLUDE_UNENCRYPTED_IND +#endif + +#ifdef FEATURE_WLAN_ESE +#define WDA_TSM_STATS_REQ SIR_HAL_TSM_STATS_REQ +#define WDA_TSM_STATS_RSP SIR_HAL_TSM_STATS_RSP +#endif +#define WDA_UPDATE_PROBE_RSP_IE_BITMAP_IND SIR_HAL_UPDATE_PROBE_RSP_IE_BITMAP_IND +#define WDA_UPDATE_UAPSD_IND SIR_HAL_UPDATE_UAPSD_IND + +#define WDA_SET_MIMOPS_REQ SIR_HAL_SET_MIMOPS_REQ +#define WDA_SET_MIMOPS_RSP SIR_HAL_SET_MIMOPS_RSP +#define WDA_SYS_READY_IND SIR_HAL_SYS_READY_IND +#define WDA_SET_TX_POWER_REQ SIR_HAL_SET_TX_POWER_REQ +#define WDA_SET_TX_POWER_RSP SIR_HAL_SET_TX_POWER_RSP +#define WDA_GET_TX_POWER_REQ SIR_HAL_GET_TX_POWER_REQ +#define WDA_GET_NOISE_REQ SIR_HAL_GET_NOISE_REQ +#define WDA_SET_TX_PER_TRACKING_REQ SIR_HAL_SET_TX_PER_TRACKING_REQ + +/* Messages to support transmit_halt and transmit_resume */ +#define WDA_TRANSMISSION_CONTROL_IND SIR_HAL_TRANSMISSION_CONTROL_IND +/* Indication from LIM to HAL to Initialize radar interrupt */ +#define WDA_INIT_RADAR_IND SIR_HAL_INIT_RADAR_IND +/* Messages to support transmit_halt and transmit_resume */ + + +#define WDA_BEACON_PRE_IND SIR_HAL_BEACON_PRE_IND +#define WDA_ENTER_UAPSD_REQ SIR_HAL_ENTER_UAPSD_REQ +#define WDA_ENTER_UAPSD_RSP SIR_HAL_ENTER_UAPSD_RSP +#define WDA_EXIT_UAPSD_REQ SIR_HAL_EXIT_UAPSD_REQ +#define WDA_EXIT_UAPSD_RSP SIR_HAL_EXIT_UAPSD_RSP +#define WDA_BEACON_FILTER_IND SIR_HAL_BEACON_FILTER_IND +/// PE <-> HAL WOWL messages +#define WDA_WOWL_ADD_BCAST_PTRN SIR_HAL_WOWL_ADD_BCAST_PTRN +#define WDA_WOWL_DEL_BCAST_PTRN SIR_HAL_WOWL_DEL_BCAST_PTRN +#define WDA_WOWL_ENTER_REQ SIR_HAL_WOWL_ENTER_REQ +#define WDA_WOWL_ENTER_RSP SIR_HAL_WOWL_ENTER_RSP +#define WDA_WOWL_EXIT_REQ SIR_HAL_WOWL_EXIT_REQ +#define WDA_WOWL_EXIT_RSP SIR_HAL_WOWL_EXIT_RSP +#define WDA_TX_COMPLETE_IND SIR_HAL_TX_COMPLETE_IND +#define WDA_TIMER_RA_COLLECT_AND_ADAPT SIR_HAL_TIMER_RA_COLLECT_AND_ADAPT +/// PE <-> HAL statistics messages +#define WDA_GET_STATISTICS_REQ SIR_HAL_GET_STATISTICS_REQ +#define WDA_GET_STATISTICS_RSP SIR_HAL_GET_STATISTICS_RSP +#define WDA_SET_KEY_DONE SIR_HAL_SET_KEY_DONE + +/// PE <-> HAL BTC messages +#define WDA_BTC_SET_CFG SIR_HAL_BTC_SET_CFG +#define WDA_SIGNAL_BT_EVENT SIR_HAL_SIGNAL_BT_EVENT +#define WDA_HANDLE_FW_MBOX_RSP SIR_HAL_HANDLE_FW_MBOX_RSP +#define WDA_SIGNAL_BTAMP_EVENT SIR_HAL_SIGNAL_BTAMP_EVENT + +#ifdef FEATURE_OEM_DATA_SUPPORT +/* PE <-> HAL OEM_DATA RELATED MESSAGES */ +#define WDA_START_OEM_DATA_REQ SIR_HAL_START_OEM_DATA_REQ +#define WDA_START_OEM_DATA_RSP SIR_HAL_START_OEM_DATA_RSP +#define WDA_FINISH_OEM_DATA_REQ SIR_HAL_FINISH_OEM_DATA_REQ +#endif + +#define WDA_SET_MAX_TX_POWER_REQ SIR_HAL_SET_MAX_TX_POWER_REQ +#define WDA_SET_MAX_TX_POWER_RSP SIR_HAL_SET_MAX_TX_POWER_RSP +#define WDA_SET_TX_POWER_REQ SIR_HAL_SET_TX_POWER_REQ + +#define WDA_SET_MAX_TX_POWER_PER_BAND_REQ \ + SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ +#define WDA_SET_MAX_TX_POWER_PER_BAND_RSP \ + SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP + +#define WDA_SEND_MSG_COMPLETE SIR_HAL_SEND_MSG_COMPLETE + +/// PE <-> HAL Host Offload message +#define WDA_SET_HOST_OFFLOAD SIR_HAL_SET_HOST_OFFLOAD + +/// PE <-> HAL Keep Alive message +#define WDA_SET_KEEP_ALIVE SIR_HAL_SET_KEEP_ALIVE + +#ifdef WLAN_NS_OFFLOAD +#define WDA_SET_NS_OFFLOAD SIR_HAL_SET_NS_OFFLOAD +#endif //WLAN_NS_OFFLOAD +#define WDA_ADD_STA_SELF_REQ SIR_HAL_ADD_STA_SELF_REQ +#define WDA_DEL_STA_SELF_REQ SIR_HAL_DEL_STA_SELF_REQ + +#define WDA_SET_P2P_GO_NOA_REQ SIR_HAL_SET_P2P_GO_NOA_REQ +#define WDA_SET_TDLS_LINK_ESTABLISH_REQ SIR_HAL_TDLS_LINK_ESTABLISH_REQ +#define WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP + +#define WDA_TX_COMPLETE_TIMEOUT_IND (WDA_MSG_TYPES_END - 1) +#define WDA_WLAN_SUSPEND_IND SIR_HAL_WLAN_SUSPEND_IND +#define WDA_WLAN_RESUME_REQ SIR_HAL_WLAN_RESUME_REQ +#define WDA_MSG_TYPES_END SIR_HAL_MSG_TYPES_END + +#define WDA_MMH_TXMB_READY_EVT SIR_HAL_MMH_TXMB_READY_EVT +#define WDA_MMH_RXMB_DONE_EVT SIR_HAL_MMH_RXMB_DONE_EVT +#define WDA_MMH_MSGQ_NE_EVT SIR_HAL_MMH_MSGQ_NE_EVT + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WDA_AGGR_QOS_REQ SIR_HAL_AGGR_QOS_REQ +#define WDA_AGGR_QOS_RSP SIR_HAL_AGGR_QOS_RSP +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* FTM CMD MSG */ +#define WDA_FTM_CMD_REQ SIR_PTT_MSG_TYPES_BEGIN +#define WDA_FTM_CMD_RSP SIR_PTT_MSG_TYPES_END +#define WDA_CSA_OFFLOAD_EVENT SIR_CSA_OFFLOAD_EVENT + +#ifdef FEATURE_WLAN_SCAN_PNO +/*Requests sent to lower driver*/ +#define WDA_SET_PNO_REQ SIR_HAL_SET_PNO_REQ +#define WDA_SET_RSSI_FILTER_REQ SIR_HAL_SET_RSSI_FILTER_REQ +#define WDA_UPDATE_SCAN_PARAMS_REQ SIR_HAL_UPDATE_SCAN_PARAMS + +/*Indication comming from lower driver*/ +#define WDA_SET_PNO_CHANGED_IND SIR_HAL_SET_PNO_CHANGED_IND +#endif // FEATURE_WLAN_SCAN_PNO + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define WDA_SET_PLM_REQ SIR_HAL_SET_PLM_REQ +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define WDA_ROAM_SCAN_OFFLOAD_REQ SIR_HAL_ROAM_SCAN_OFFLOAD_REQ +#define WDA_ROAM_SCAN_OFFLOAD_RSP SIR_HAL_ROAM_SCAN_OFFLOAD_RSP +#define WDA_START_ROAM_CANDIDATE_LOOKUP_REQ SIR_HAL_START_ROAM_CANDIDATE_LOOKUP_REQ +#endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define WDA_ROAM_OFFLOAD_SYNCH_CNF SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF +#define WDA_ROAM_OFFLOAD_SYNCH_IND SIR_HAL_ROAM_OFFLOAD_SYNCH_IND +#define WDA_ROAM_OFFLOAD_SYNCH_FAIL SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL +#endif +#ifdef WLAN_WAKEUP_EVENTS +#define WDA_WAKE_REASON_IND SIR_HAL_WAKE_REASON_IND +#endif // WLAN_WAKEUP_EVENTS + +#ifdef WLAN_FEATURE_PACKET_FILTERING +#define WDA_8023_MULTICAST_LIST_REQ SIR_HAL_8023_MULTICAST_LIST_REQ +#define WDA_RECEIVE_FILTER_SET_FILTER_REQ SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ +#define WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ +#define WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP +#define WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ +#endif // WLAN_FEATURE_PACKET_FILTERING + +#define WDA_SET_POWER_PARAMS_REQ SIR_HAL_SET_POWER_PARAMS_REQ +#define WDA_DHCP_START_IND SIR_HAL_DHCP_START_IND +#define WDA_DHCP_STOP_IND SIR_HAL_DHCP_STOP_IND + +#define WDA_HIDDEN_SSID_VDEV_RESTART SIR_HAL_HIDE_SSID_VDEV_RESTART + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define WDA_GTK_OFFLOAD_REQ SIR_HAL_GTK_OFFLOAD_REQ +#define WDA_GTK_OFFLOAD_GETINFO_REQ SIR_HAL_GTK_OFFLOAD_GETINFO_REQ +#define WDA_GTK_OFFLOAD_GETINFO_RSP SIR_HAL_GTK_OFFLOAD_GETINFO_RSP +#endif //WLAN_FEATURE_GTK_OFFLOAD + +#define WDA_SET_TM_LEVEL_REQ SIR_HAL_SET_TM_LEVEL_REQ + +#ifdef WLAN_FEATURE_11AC +#define WDA_UPDATE_OP_MODE SIR_HAL_UPDATE_OP_MODE +#define WDA_UPDATE_RX_NSS SIR_HAL_UPDATE_RX_NSS +#define WDA_UPDATE_MEMBERSHIP SIR_HAL_UPDATE_MEMBERSHIP +#define WDA_UPDATE_USERPOS SIR_HAL_UPDATE_USERPOS +#endif + +#define WDA_GET_ROAM_RSSI_REQ SIR_HAL_GET_ROAM_RSSI_REQ +#define WDA_GET_ROAM_RSSI_RSP SIR_HAL_GET_ROAM_RSSI_RSP + +#ifdef WLAN_FEATURE_NAN +#define WDA_NAN_REQUEST SIR_HAL_NAN_REQUEST +#endif + +#define WDA_START_SCAN_OFFLOAD_REQ SIR_HAL_START_SCAN_OFFLOAD_REQ +#define WDA_START_SCAN_OFFLOAD_RSP SIR_HAL_START_SCAN_OFFLOAD_RSP +#define WDA_STOP_SCAN_OFFLOAD_REQ SIR_HAL_STOP_SCAN_OFFLOAD_REQ +#define WDA_STOP_SCAN_OFFLOAD_RSP SIR_HAL_STOP_SCAN_OFFLOAD_RSP +#define WDA_UPDATE_CHAN_LIST_REQ SIR_HAL_UPDATE_CHAN_LIST_REQ +#define WDA_UPDATE_CHAN_LIST_RSP SIR_HAL_UPDATE_CHAN_LIST_RSP +#define WDA_RX_SCAN_EVENT SIR_HAL_RX_SCAN_EVENT +#define WDA_IBSS_PEER_INACTIVITY_IND SIR_HAL_IBSS_PEER_INACTIVITY_IND + +#define WDA_CLI_SET_CMD SIR_HAL_CLI_SET_CMD +#define WDA_CLI_GET_CMD SIR_HAL_CLI_GET_CMD +#ifdef FEATURE_WLAN_SCAN_PNO +#define WDA_SME_SCAN_CACHE_UPDATED SIR_HAL_SME_SCAN_CACHE_UPDATED +#endif + +#ifndef REMOVE_PKT_LOG +#define WDA_PKTLOG_ENABLE_REQ SIR_HAL_PKTLOG_ENABLE_REQ +#endif + +#ifdef FEATURE_WLAN_LPHB +#define WDA_LPHB_CONF_REQ SIR_HAL_LPHB_CONF_IND +#define WDA_LPHB_WAIT_EXPIRE_IND SIR_HAL_LPHB_WAIT_EXPIRE_IND +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_CH_AVOID +#define WDA_CH_AVOID_UPDATE_REQ SIR_HAL_CH_AVOID_UPDATE_REQ +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef FEATURE_WLAN_AUTO_SHUTDOWN +#define WDA_SET_AUTO_SHUTDOWN_TIMER_REQ SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ +#endif + +#define WDA_ADD_PERIODIC_TX_PTRN_IND SIR_HAL_ADD_PERIODIC_TX_PTRN_IND +#define WDA_DEL_PERIODIC_TX_PTRN_IND SIR_HAL_DEL_PERIODIC_TX_PTRN_IND + +#define WDA_TX_POWER_LIMIT SIR_HAL_SET_TX_POWER_LIMIT + +#define WDA_RATE_UPDATE_IND SIR_HAL_RATE_UPDATE_IND + +#define WDA_INIT_THERMAL_INFO_CMD SIR_HAL_INIT_THERMAL_INFO_CMD +#define WDA_SET_THERMAL_LEVEL SIR_HAL_SET_THERMAL_LEVEL +#ifdef FEATURE_WLAN_BATCH_SCAN +#define WDA_SET_BATCH_SCAN_REQ SIR_HAL_SET_BATCH_SCAN_REQ +#define WDA_SET_BATCH_SCAN_RSP SIR_HAL_SET_BATCH_SCAN_RSP +#define WDA_STOP_BATCH_SCAN_IND SIR_HAL_STOP_BATCH_SCAN_IND +#define WDA_TRIGGER_BATCH_SCAN_RESULT_IND SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND +#endif + +#ifdef FEATURE_WLAN_TDLS +#define WDA_UPDATE_FW_TDLS_STATE SIR_HAL_UPDATE_FW_TDLS_STATE +#define WDA_UPDATE_TDLS_PEER_STATE SIR_HAL_UPDATE_TDLS_PEER_STATE +#define WDA_TDLS_SHOULD_DISCOVER SIR_HAL_TDLS_SHOULD_DISCOVER +#define WDA_TDLS_SHOULD_TEARDOWN SIR_HAL_TDLS_SHOULD_TEARDOWN +#define WDA_TDLS_PEER_DISCONNECTED SIR_HAL_TDLS_PEER_DISCONNECTED +#define WDA_TDLS_SET_OFFCHAN_MODE SIR_HAL_TDLS_SET_OFFCHAN_MODE +#endif +#define WDA_SET_SAP_INTRABSS_DIS SIR_HAL_SET_SAP_INTRABSS_DIS + +/* Message to Indicate Radar Presence on SAP Channel */ +#define WDA_DFS_RADAR_IND SIR_HAL_DFS_RADAR_IND + +/* Message to indicate beacon tx completion after beacon template update + * beacon offload case + */ +#define WDA_DFS_BEACON_TX_SUCCESS_IND SIR_HAL_BEACON_TX_SUCCESS_IND +#define WDA_FW_STATS_IND SIR_HAL_FW_STATS_IND +#define WDA_DISASSOC_TX_COMP SIR_HAL_DISASSOC_TX_COMP +#define WDA_DEAUTH_TX_COMP SIR_HAL_DEAUTH_TX_COMP +#define WDA_GET_LINK_SPEED SIR_HAL_GET_LINK_SPEED + +#define WDA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND + +#define WDA_VDEV_STOP_IND SIR_HAL_VDEV_STOP_IND + +#ifdef WLAN_FEATURE_STATS_EXT +#define WDA_STATS_EXT_REQUEST SIR_HAL_STATS_EXT_REQUEST +#endif + +#define WDA_VDEV_START_RSP_IND SIR_HAL_VDEV_START_RSP_IND + +#define WDA_ROAM_PREAUTH_IND SIR_HAL_ROAM_PREAUTH_IND + +#define WDA_TBTT_UPDATE_IND SIR_HAL_TBTT_UPDATE_IND + +#ifdef FEATURE_WLAN_EXTSCAN +#define WDA_EXTSCAN_GET_CAPABILITIES_REQ SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ +#define WDA_EXTSCAN_START_REQ SIR_HAL_EXTSCAN_START_REQ +#define WDA_EXTSCAN_STOP_REQ SIR_HAL_EXTSCAN_STOP_REQ +#define WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ +#define WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ +#define WDA_EXTSCAN_SET_SIGNF_CHANGE_REQ SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ +#define WDA_EXTSCAN_RESET_SIGNF_CHANGE_REQ SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ +#define WDA_EXTSCAN_GET_CACHED_RESULTS_REQ SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ + +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define WDA_LINK_LAYER_STATS_CLEAR_REQ SIR_HAL_LL_STATS_CLEAR_REQ +#define WDA_LINK_LAYER_STATS_SET_REQ SIR_HAL_LL_STATS_SET_REQ +#define WDA_LINK_LAYER_STATS_GET_REQ SIR_HAL_LL_STATS_GET_REQ +#define WDA_LINK_LAYER_STATS_RESULTS_RSP SIR_HAL_LL_STATS_RESULTS_RSP +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#define WDA_LINK_STATUS_GET_REQ SIR_HAL_LINK_STATUS_GET_REQ +#define WDA_GET_LINK_STATUS_RSP_IND SIR_HAL_GET_LINK_STATUS_RSP_IND + +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +#define WDA_WLAN_EXT_WOW SIR_HAL_CONFIG_EXT_WOW +#define WDA_WLAN_SET_APP_TYPE1_PARAMS SIR_HAL_CONFIG_APP_TYPE1_PARAMS +#define WDA_WLAN_SET_APP_TYPE2_PARAMS SIR_HAL_CONFIG_APP_TYPE2_PARAMS +#endif + +#define WDA_SET_SCAN_MAC_OUI_REQ SIR_HAL_SET_SCAN_MAC_OUI_REQ + +tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg); + +#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames + +#define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc,\ + pData, txFlag, sessionid) \ + (eHalStatus)( WDA_TxPacket(\ + vos_get_context(VOS_MODULE_ID_WDA,\ + vos_get_global_context(VOS_MODULE_ID_WDA, (hHal))),\ + (pFrmBuf),\ + (frmLen),\ + (frmType),\ + (txDir),\ + (tid),\ + (pCompFunc),\ + (pData),\ + (NULL), \ + (txFlag),\ + (sessionid),\ + (false)) ) + +#define halTxFrameWithTxComplete(hHal, pFrmBuf, frmLen, frmType, txDir, tid,\ + pCompFunc, pData, pCBackFnTxComp, txFlag, sessionid, tdlsflag) \ + (eHalStatus)( WDA_TxPacket(\ + vos_get_context(VOS_MODULE_ID_WDA,\ + vos_get_global_context(VOS_MODULE_ID_WDA, (hHal))),\ + (pFrmBuf),\ + (frmLen),\ + (frmType),\ + (txDir),\ + (tid),\ + (pCompFunc),\ + (pData),\ + (pCBackFnTxComp), \ + (txFlag),\ + (sessionid),\ + (tdlsflag)) ) + + +#define WDA_SetRegDomain WMA_SetRegDomain +#define WDA_SetHTConfig wma_set_htconfig +#define WDA_UpdateRssiBmps WMA_UpdateRssiBmps + +VOS_STATUS WDA_SetIdlePsConfig(void *wda_handle, tANI_U32 idle_ps); +VOS_STATUS WDA_notify_modem_power_state(void *wda_handle, tANI_U32 value); +static inline void WDA_UpdateSnrBmps(v_PVOID_t pvosGCtx, v_U8_t staId, + v_S7_t snr) +{ + +} + +static inline int WDA_GetSnr(tANI_U8 ucSTAId, tANI_S8* pSnr) +{ + return VOS_STATUS_SUCCESS; +} + +static inline void WDA_UpdateLinkCapacity(v_PVOID_t pvosGCtx, v_U8_t staId, + v_U32_t linkCapacity) +{ + +} + +/*========================================================================== + FUNCTION WDA_DS_PeekRxPacketInfo + + DESCRIPTION + Return RX metainfo pointer for for integrated SOC. + + Same function will return BD header pointer. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + pvDestMacAddr destination MAC address ponter + bSwap Want to swap BD header? For backward compatability + It does nothing for integrated SOC + OUT + *ppRxHeader RX metainfo pointer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_PeekRxPacketInfo +( + vos_pkt_t *vosDataBuff, + v_PVOID_t *ppRxHeader, + v_BOOL_t bSwap +); + + +#define WDA_HALDumpCmdReq WMA_HALDumpCmdReq + +#define WDA_featureCapsExchange WMA_featureCapsExchange +#define WDA_disableCapablityFeature WMA_disableCapablityFeature +#define WDA_getFwWlanFeatCaps wma_getFwWlanFeatCaps + +#define WDA_TransportChannelDebug(mac, disp_snapshot, \ + toggle_stall_detect) ({ \ + (void)mac; \ + (void)disp_snapshot; \ + (void)toggle_stall_detect; \ +}) + +#define WDA_TrafficStatsTimerActivate WMA_TrafficStatsTimerActivate +#define WDA_SetEnableSSR(enable_ssr) (void)enable_ssr +void WDA_TxAbort(v_U8_t vdev_id); + + +/* Powersave Offload Changes */ +typedef struct sUapsd_Params +{ + tANI_U8 bkDeliveryEnabled:1; + tANI_U8 beDeliveryEnabled:1; + tANI_U8 viDeliveryEnabled:1; + tANI_U8 voDeliveryEnabled:1; + tANI_U8 bkTriggerEnabled:1; + tANI_U8 beTriggerEnabled:1; + tANI_U8 viTriggerEnabled:1; + tANI_U8 voTriggerEnabled:1; +}tUapsd_Params, *tpUapsd_Params; + +/* Enable PowerSave Params */ +typedef struct sEnablePsParams +{ + tSirAddonPsReq psSetting; + + tUapsd_Params uapsdParams; + + tSirMacAddr bssid; + + /* SmeSession Id or Vdev Id */ + tANI_U32 sessionid; + + /* Beacon DTIM Period */ + tANI_U8 bcnDtimPeriod; + + /* success or failure */ + tANI_U32 status; +}tEnablePsParams, *tpEnablePsParams; + +/* Disable PowerSave Params */ +typedef struct sDisablePsParams +{ + tSirAddonPsReq psSetting; + + tSirMacAddr bssid; + + /* SmeSession Id or Vdev Id */ + tANI_U32 sessionid; + + /* success or failure */ + tANI_U32 status; +}tDisablePsParams, *tpDisablePsParams; + +/* Enable Uapsd Params */ +typedef struct sEnableUapsdParams +{ + tUapsd_Params uapsdParams; + + tSirMacAddr bssid; + + /* SmeSession Id or Vdev Id */ + tANI_U32 sessionid; + + /* success or failure */ + tANI_U32 status; +}tEnableUapsdParams, *tpEnableUapsdParams; + +/* Disable Uapsd Params */ +typedef struct sDisableUapsdParams +{ + tSirMacAddr bssid; + + /* SmeSession Id or Vdev Id */ + tANI_U32 sessionid; + + /* success or failure */ + tANI_U32 status; +}tDisableUapsdParams, *tpDisableUapsdParams; + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda_msg.h b/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda_msg.h new file mode 100644 index 0000000000000..970066fc5418f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/inc/wlan_qct_wda_msg.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_MSG_MAP_H +#define WLAN_QCT_MSG_MAP_H + +/*=========================================================================== + + W L A N DEVICE ADAPTATION L A Y E R + MSG MAPPING + + +DESCRIPTION + This file contains the external API exposed by the wlan adaptation layer +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------- +25/08/2010 adwivedi MAP WDA messages on Legacy HAL messages +=========================================================================== */ + +/* Add Include */ +#include "wlan_qct_pack_align.h" + + +#define WDA_CONFIG_PARAM_UPDATE_REQ SIR_CFG_PARAM_UPDATE_IND + +#define ALIGNED_WORD_SIZE 4 + +/* Config format required by HAL for each CFG item*/ +WPT_PACK_START +typedef WPT_PACK_PRE struct +{ + /* Cfg Id. The Id required by HAL is exported by HAL + * in shared header file between UMAC and HAL.*/ + tANI_U16 type; + + /* Length of the Cfg. This parameter is used to go to next cfg + * in the TLV format.*/ + tANI_U16 length; + + /* Padding bytes for unaligned address's */ + tANI_U16 padBytes; + + /* Reserve bytes for making cfgVal to align address */ + tANI_U16 reserved; + + /* Following the uCfgLen field there should be a 'uCfgLen' bytes + * containing the uCfgValue ; tANI_U8 uCfgValue[uCfgLen] */ +}WPT_PACK_POST tHalCfg, *tpHalCfg; +WPT_PACK_END + +/////#define WDA_UT +#ifdef WDA_UT +#define WDA_WDI_EVENT_MSG 0x00FF +void WDI_processEvent(void *wdiEventData, void *pUserData); +#endif + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.c b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.c new file mode 100644 index 0000000000000..eceff1f7c5edb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wlan_qct_wda_debug.c + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Adaptation + Layer for debugging APIs. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + + +#include "palTypes.h" +#include "wlan_qct_wda_debug.h" + +void wdaLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) { + va_list marker; + + if(loglevel > pMac->utils.gLogDbgLevel[WDA_DEBUG_LOGIDX]) + return; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_WDA_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ +} diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.h b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.h new file mode 100644 index 0000000000000..d741d7b21041c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_debug.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WDA_DEBUG_H__ +#define __WDA_DEBUG_H__ +#if !defined (ANI_OS_TYPE_ANDROID) +#include +#endif +#include + +#include "utilsApi.h" +#include "sirDebug.h" +#include "sirParams.h" +#define WDA_DEBUG_LOGIDX ( LOG_INDEX_FOR_MODULE(SIR_WDA_MODULE_ID) ) + + + +#ifdef WLAN_DEBUG + +#define WDALOGP(x0) x0 +#define WDALOGE(x0) x0 +#define WDALOGW(x0) x0 +#define WDALOG1(x0) x0 + +#ifdef HAL_DEBUG_LOG2 +#define WDALOG2(x0) x0 +#else + #define WDALOG2(x0) +#endif + +#ifdef HAL_DEBUG_LOG3 +#define WDALOG3(x0) x0 +#else + #define WDALOG3(x0) +#endif + +#ifdef HAL_DEBUG_LOG4 +#define WDALOG4(x0) x0 +#else + #define WDALOG4(x0) +#endif + +#define STR(x) x + +#else + +#define WDALOGP(x) x +#define WDALOGE(x) {} +#define WDALOGW(x) {} +#define WDALOG1(x) {} +#define WDALOG2(x) {} +#define WDALOG3(x) {} +#define WDALOG4(x) {} +#define STR(x) "" +#endif + +void wdaLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...); + +#endif // __WDA_DEBUG_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_legacy.c b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_legacy.c new file mode 100644 index 0000000000000..6ef18cf50206a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDA/src/wlan_qct_wda_legacy.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wlan_qct_wda_legacy.c + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Adaptation + Layer for the legacy functionalities that were part of the old HAL. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/* Standard include files */ +/* Application Specific include files */ +#include "limApi.h" +#include "pmmApi.h" +#include "cfgApi.h" +#include "wlan_qct_wda_debug.h" + +/* Locally used Defines */ + +#define HAL_MMH_MB_MSG_TYPE_MASK 0xFF00 + +// ------------------------------------------------------------- +/** + * wdaPostCtrlMsg + * + * FUNCTION: + * Posts WDA messages to MC thread + * + * LOGIC: + * + * ASSUMPTIONS:pl + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg pointer with message + * @return Success or Failure + */ + +tSirRetStatus +wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, (vos_msg_t *) pMsg)) + return eSIR_FAILURE; + else + return eSIR_SUCCESS; +} // halPostMsg() + +/** + * wdaPostCfgMsg + * + * FUNCTION: + * Posts MNT messages to gSirMntMsgQ + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg A pointer to the msg + * @return Success or Failure + */ + +tSirRetStatus +wdaPostCfgMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tSirRetStatus rc = eSIR_SUCCESS; + + do + { + // For Windows based MAC, instead of posting message to different + // queues we will call the handler routines directly + + cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr); + rc = eSIR_SUCCESS; + } while (0); + + return rc; +} // halMntPostMsg() + + +// ------------------------------------------------------------- +/** + * uMacPostCtrlMsg + * + * FUNCTION: + * Forwards the completely received message to the respective + * modules for further processing. + * + * LOGIC: + * + * ASSUMPTIONS: + * Freeing up of the message buffer is left to the destination module. + * + * NOTE: + * This function has been moved to the API file because for MAC running + * on Windows host, the host module will call this routine directly to + * send any mailbox messages. Making this function an API makes sure that + * outside world (any module outside MMH) only calls APIs to use MMH + * services and not an internal function. + * + * @param pMb A pointer to the maibox message + * @return NONE + */ + +tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pSirGlobal; + + + tSirMbMsg* pMbLocal; + msg.type = pMb->type; + msg.bodyval = 0; + + WDALOG3(wdaLog(pMac, LOG3, FL("msgType %d, msgLen %d" ), + pMb->type, pMb->msgLen)); + + // copy the message from host buffer to firmware buffer + // this will make sure that firmware allocates, uses and frees + // it's own buffers for mailbox message instead of working on + // host buffer + + // second parameter, 'wait option', to palAllocateMemory is ignored on Windows + pMbLocal = vos_mem_malloc(pMb->msgLen); + if ( NULL == pMbLocal ) + { + WDALOGE( wdaLog(pMac, LOGE, FL("Buffer Allocation failed!"))); + return eSIR_FAILURE; + } + + vos_mem_copy((void *)pMbLocal, (void *)pMb, pMb->msgLen); + msg.bodyptr = pMbLocal; + + switch (msg.type & HAL_MMH_MB_MSG_TYPE_MASK) + { + case WDA_MSG_TYPES_BEGIN: // Posts a message to the HAL MsgQ + wdaPostCtrlMsg(pMac, &msg); + break; + + case SIR_LIM_MSG_TYPES_BEGIN: // Posts a message to the LIM MsgQ + limPostMsgApi(pMac, &msg); + break; + + case SIR_CFG_MSG_TYPES_BEGIN: // Posts a message to the CFG MsgQ + wdaPostCfgMsg(pMac, &msg); + break; + + case SIR_PMM_MSG_TYPES_BEGIN: // Posts a message to the PMM MsgQ + pmmPostMessage(pMac, &msg); + break; + + case SIR_PTT_MSG_TYPES_BEGIN: + WDALOGW( wdaLog(pMac, LOGW, FL("%s:%d: message type = 0x%X"), + __func__, __LINE__, msg.type)); + vos_mem_free(msg.bodyptr); + break; + + + default: + WDALOGW( wdaLog(pMac, LOGW, FL("Unknown message type = " + "0x%X"), + msg.type)); + + // Release the memory. + vos_mem_free(msg.bodyptr); + break; + } + + return eSIR_SUCCESS; + +} // uMacPostCtrlMsg() diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/qwlanfw_defs.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/qwlanfw_defs.h new file mode 100644 index 0000000000000..1b1c7496145a0 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/qwlanfw_defs.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + * + * @file: wlan_defs.h + * + * @brief: This file defines the common typedefs + * + * @author: Gagan Jain + * + * + *=========================================================================*/ + +#ifndef __WLAN_DEFS_H__ +#define __WLAN_DEFS_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ +#include "wlan_qct_pal_type.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +typedef wpt_uint32 uint32; /* Unsigned 32 bit value */ + +typedef wpt_uint16 uint16; /* Unsigned 16 bit value */ + +typedef wpt_uint8 uint8; /* Unsigned 8 bit value */ + +typedef wpt_int32 int32; /* Signed 32 bit value */ + +typedef wpt_int16 int16; /* Signed 16 bit value */ + +typedef wpt_int8 int8; /* Signed 8 bit value */ + +typedef wpt_int64 int64; /* Signed 64 bit value */ + +typedef wpt_uint64 uint64; /* Unsigned 64 bit value */ + +typedef wpt_byte byte; /* byte type */ + +typedef wpt_boolean boolean; /* Boolean Type */ + +#endif //__WLAN_DEFS_H__ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi.h new file mode 100644 index 0000000000000..08e23c16673f6 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi.h @@ -0,0 +1,10325 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef WLAN_QCT_WDI_H +#define WLAN_QCT_WDI_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan transport layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/05/11 hap Adding support for Keep Alive +08/04/10 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pack_align.h" +#include "wlan_qct_wdi_cfg.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#ifdef __cplusplus + extern "C" { +#endif + +/* MAC ADDRESS LENGTH - per spec*/ +#define WDI_MAC_ADDR_LEN 6 + +/* IPv4 Address Length */ +#define WDI_IPV4_ADDR_LEN 4 + +/* Max number of 11b rates -> 1,2,5.5,11 */ +#define WDI_NUM_11B_RATES 4 + +/* Max number of 11g rates -> 6,9,12,18,24,36,48,54*/ +#define WDI_NUM_11A_RATES 8 + +/* Max number of legacy rates -> 72, 96, 108*/ +#define WDI_NUM_POLARIS_RATES 3 + +/* Max supported MCS set*/ +#define WDI_MAC_MAX_SUPPORTED_MCS_SET 16 + +/*Max number of Access Categories for QoS - per spec */ +#define WDI_MAX_NO_AC 4 + +/*Max. size for reserving the Beacon Template */ +#define WDI_BEACON_TEMPLATE_SIZE 0x180 + +#define WDI_WOWL_BCAST_PATTERN_MAX_SIZE 128 + +#define WDI_WOWL_BCAST_MAX_NUM_PATTERNS 16 + +#define WDI_MAX_SSID_SIZE 32 + +/* The shared memory between WDI and HAL is 4K so maximum data can be transferred +from WDI to HAL is 4K.This 4K should also include the Message header so sending 4K +of NV fragment is nt possbile.The next multiple of 1Kb is 3K */ + +#define FRAGMENT_SIZE 3072 + +/* Macro to find the total number fragments of the NV Image*/ +#define TOTALFRAGMENTS(x) (((x % FRAGMENT_SIZE) == 0) ? (x / FRAGMENT_SIZE):((x / FRAGMENT_SIZE) + 1)) + +/* Beacon Filter Length*/ +#define WDI_BEACON_FILTER_LEN 70 + +/* Coex Indication data size - should match WLAN_COEX_IND_DATA_SIZE */ +#define WDI_COEX_IND_DATA_SIZE (4) + +#define WDI_CIPHER_SEQ_CTR_SIZE 6 + +#define WDI_NUM_BSSID 2 + +/*Version string max length (including NUL) */ +#define WDI_VERSION_LENGTH 64 + + +/*WDI Response timeout - how long will WDI wait for a response from the device + - it should be large enough to allow any other failure mechanism to kick + in before we get to a timeout (ms units)*/ +#define WDI_RESPONSE_TIMEOUT 10000 + +/* SSR timeout - If Riva initiated SSR doesn't happen during this time, then the + * Apps initiated SSR will be performed */ +#define WDI_SSR_TIMEOUT 5000 + +#define WDI_SET_POWER_STATE_TIMEOUT 10000 /* in msec a very high upper limit */ + +/* Periodic Tx pattern offload feature */ +#define PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define MAXNUM_PERIODIC_TX_PTRNS 6 + +/*============================================================================ + * GENERIC STRUCTURES + +============================================================================*/ + +/*--------------------------------------------------------------------------- + WDI Version Information +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 revision; + wpt_uint8 version; + wpt_uint8 minor; + wpt_uint8 major; +} WDI_WlanVersionType; + +/*--------------------------------------------------------------------------- + WDI Device Capability +---------------------------------------------------------------------------*/ +typedef struct +{ + /*If this flag is true it means that the device can support 802.3/ETH2 to + 802.11 translation*/ + wpt_boolean bFrameXtlSupported; + + /*Maximum number of BSSes supported by the Device */ + wpt_uint8 ucMaxBSSSupported; + + /*Maximum number of stations supported by the Device */ + wpt_uint8 ucMaxSTASupported; +}WDI_DeviceCapabilityType; + +/*--------------------------------------------------------------------------- + WDI Channel Offset +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_SECONDARY_CHANNEL_OFFSET_NONE = 0, + WDI_SECONDARY_CHANNEL_OFFSET_UP = 1, + WDI_SECONDARY_CHANNEL_OFFSET_DOWN = 3, +#ifdef WLAN_FEATURE_11AC + WDI_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + WDI_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + WDI_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + WDI_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + WDI_SECONDARY_CHANNEL_OFFSET_MAX +}WDI_HTSecondaryChannelOffset; + +/*--------------------------------------------------------------------------- + WDI_MacFrameCtl + Frame control field format (2 bytes) +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 protVer :2; + wpt_uint8 type :2; + wpt_uint8 subType :4; + + wpt_uint8 toDS :1; + wpt_uint8 fromDS :1; + wpt_uint8 moreFrag :1; + wpt_uint8 retry :1; + wpt_uint8 powerMgmt :1; + wpt_uint8 moreData :1; + wpt_uint8 wep :1; + wpt_uint8 order :1; + +} WDI_MacFrameCtl; + +/*--------------------------------------------------------------------------- + WDI Sequence control field +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 fragNum : 4; + wpt_uint8 seqNumLo : 4; + wpt_uint8 seqNumHi : 8; +} WDI_MacSeqCtl; + +/*--------------------------------------------------------------------------- + Management header format +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_MacFrameCtl fc; + wpt_uint8 durationLo; + wpt_uint8 durationHi; + wpt_uint8 da[WDI_MAC_ADDR_LEN]; + wpt_uint8 sa[WDI_MAC_ADDR_LEN]; + wpt_macAddr bssId; + WDI_MacSeqCtl seqControl; +} WDI_MacMgmtHdr; + +/*--------------------------------------------------------------------------- + NV Blob management sturcture + ---------------------------------------------------------------------------*/ + +typedef struct +{ + /* NV image fragments count */ + wpt_uint16 usTotalFragment; + + /* NV fragment size */ + wpt_uint16 usFragmentSize; + + /* current fragment to be sent */ + wpt_uint16 usCurrentFragment; + +} WDI_NvBlobInfoParams; + + +/*--------------------------------------------------------------------------- + Data path enums memory pool resource + ---------------------------------------------------------------------------*/ + +typedef enum +{ + /* managment resource pool ID */ + WDI_MGMT_POOL_ID = 0, + /* Data resource pool ID */ + WDI_DATA_POOL_ID = 1 +}WDI_ResPoolType; + +/*============================================================================ + * GENERIC STRUCTURES - END + ============================================================================*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + WDI Status +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_STATUS_SUCCESS, /* Operation has completed successfully*/ + WDI_STATUS_SUCCESS_SYNC, /* Operation has completed successfully in a + synchronous way - no rsp will be generated*/ + WDI_STATUS_PENDING, /* Operation result is pending and will be + provided asynchronously through the Req Status + Callback */ + WDI_STATUS_E_FAILURE, /* Operation has ended in a generic failure*/ + WDI_STATUS_RES_FAILURE, /* Operation has ended in a resource failure*/ + WDI_STATUS_MEM_FAILURE, /* Operation has ended in a memory allocation + failure*/ + WDI_STATUS_E_NOT_ALLOWED, /* Operation is not allowed in the current state + of the driver*/ + WDI_STATUS_E_NOT_IMPLEMENT, /* Operation is not yet implemented*/ + + WDI_STATUS_DEV_INTERNAL_FAILURE, /*An internal error has occurred in the device*/ + WDI_STATUS_MAX + +}WDI_Status; + + +/*--------------------------------------------------------------------------- + WDI_ReqStatusCb + + DESCRIPTION + + This callback is invoked by DAL to deliver to UMAC the result of posting + a previous request for which the return status was PENDING. + + PARAMETERS + + IN + wdiStatus: response status received from the Control Transport + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReqStatusCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndEnumType + Types of indication that can be posted to UMAC by DAL +---------------------------------------------------------------------------*/ +typedef enum +{ + /*When RSSI monitoring is enabled of the Lower MAC and a threshold has been + passed. */ + WDI_RSSI_NOTIFICATION_IND, + + /*Link loss in the low MAC */ + WDI_MISSED_BEACON_IND, + + /*when hardware has signaled an unknown addr2 frames. The indication will + contain info from frames to be passed to the UMAC, this may use this info to + deauth the STA*/ + WDI_UNKNOWN_ADDR2_FRAME_RX_IND, + + /*MIC Failure detected by HW*/ + WDI_MIC_FAILURE_IND, + + /*Fatal Error Ind*/ + WDI_FATAL_ERROR_IND, + + /*Delete Station Ind*/ + WDI_DEL_STA_IND, + + /*Indication from Coex*/ + WDI_COEX_IND, + + /* Indication for Tx Complete */ + WDI_TX_COMPLETE_IND, + + /*.P2P_NOA_Attr_Indication */ + WDI_P2P_NOA_ATTR_IND, + + /* Preferred Network Found Indication */ + WDI_PREF_NETWORK_FOUND_IND, + + WDI_WAKE_REASON_IND, + + /* Tx PER Tracking Indication */ + WDI_TX_PER_HIT_IND, + + /* P2P_NOA_Start_Indication */ + WDI_P2P_NOA_START_IND, + + /* TDLS_Indication */ + WDI_TDLS_IND, + + /* LPHB Indication from FW to umac */ + WDI_LPHB_IND, + + /* IBSS Peer Inactivity Indication */ + WDI_IBSS_PEER_INACTIVITY_IND, + + /* Periodic Tx Pattern FW Indication */ + WDI_PERIODIC_TX_PTRN_FW_IND, + + /* LBP_Leader_Pick_New Indication */ + WDI_LBP_LEADER_PICK_NEW, + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*Batch scan result indication from FW*/ + WDI_BATCH_SCAN_RESULT_IND, +#endif + + WDI_TX_FAIL_IND, + + WDI_MAX_IND +}WDI_LowLevelIndEnumType; + + +/*--------------------------------------------------------------------------- + WDI_LowRSSIThIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Positive crossing of Rssi Thresh1*/ + wpt_uint32 bRssiThres1PosCross : 1; + /*Negative crossing of Rssi Thresh1*/ + wpt_uint32 bRssiThres1NegCross : 1; + /*Positive crossing of Rssi Thresh2*/ + wpt_uint32 bRssiThres2PosCross : 1; + /*Negative crossing of Rssi Thresh2*/ + wpt_uint32 bRssiThres2NegCross : 1; + /*Positive crossing of Rssi Thresh3*/ + wpt_uint32 bRssiThres3PosCross : 1; + /*Negative crossing of Rssi Thresh3*/ + wpt_uint32 bRssiThres3NegCross : 1; + + wpt_uint32 avgRssi : 8; + wpt_uint32 bReserved : 18; + +}WDI_LowRSSIThIndType; + + +/*--------------------------------------------------------------------------- + WDI_UnkAddr2FrmRxIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Rx Bd data of the unknown received addr2 frame.*/ + void* bufRxBd; + + /*Buffer Length*/ + wpt_uint16 usBufLen; +}WDI_UnkAddr2FrmRxIndType; + +/*--------------------------------------------------------------------------- + WDI_DeleteSTAIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*ASSOC ID, as assigned by UMAC*/ + wpt_uint16 usAssocId; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; + + /*BSSID of STA*/ + wpt_macAddr macBSSID; + + /*MAC ADDR of STA*/ + wpt_macAddr macADDR2; + + /* To unify the keepalive / unknown A2 / tim-based disa*/ + wpt_uint16 wptReasonCode; + +}WDI_DeleteSTAIndType; + +/*--------------------------------------------------------------------------- + WDI_MicFailureIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*current BSSID*/ + wpt_macAddr bssId; + + /*Source mac address*/ + wpt_macAddr macSrcAddr; + + /*Transmitter mac address*/ + wpt_macAddr macTaAddr; + + /*Destination mac address*/ + wpt_macAddr macDstAddr; + + /*Multicast flag*/ + wpt_uint8 ucMulticast; + + /*First byte of IV*/ + wpt_uint8 ucIV1; + + /*Key Id*/ + wpt_uint8 keyId; + + /*Sequence Number*/ + wpt_uint8 TSC[WDI_CIPHER_SEQ_CTR_SIZE]; + + /*receive address */ + wpt_macAddr macRxAddr; +}WDI_MicFailureIndType; + +/*--------------------------------------------------------------------------- + WDI_CoexIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 coexIndType; + wpt_uint32 coexIndData[WDI_COEX_IND_DATA_SIZE]; +} WDI_CoexIndType; + +/*--------------------------------------------------------------------------- + WDI_DHCPInd +---------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint8 device_mode; + wpt_uint8 macAddr[WDI_MAC_ADDR_LEN]; +}WDI_DHCPInd; + +/*--------------------------------------------------------------------------- + + WDI_MacSSid +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucLength; + wpt_uint8 sSSID[WDI_MAX_SSID_SIZE]; +} WDI_MacSSid; + +#ifdef FEATURE_WLAN_SCAN_PNO +/*--------------------------------------------------------------------------- + WDI_PrefNetworkFoundInd +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Network that was found with the highest RSSI*/ + WDI_MacSSid ssId; + /* Indicates the RSSI */ + wpt_uint8 rssi; + wpt_uint16 frameLength; + wpt_uint8 *pData; +} WDI_PrefNetworkFoundInd; +#endif // FEATURE_WLAN_SCAN_PNO + +/*--------------------------------------------------------------------------- + *WDI_P2pNoaAttrIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucIndex ; + wpt_uint8 ucOppPsFlag ; + wpt_uint16 usCtWin ; + + wpt_uint16 usNoa1IntervalCnt; + wpt_uint16 usRsvd1 ; + wpt_uint32 uslNoa1Duration; + wpt_uint32 uslNoa1Interval; + wpt_uint32 uslNoa1StartTime; + + wpt_uint16 usNoa2IntervalCnt; + wpt_uint16 usRsvd2; + wpt_uint32 uslNoa2Duration; + wpt_uint32 uslNoa2Interval; + wpt_uint32 uslNoa2StartTime; + + wpt_uint32 status; +}WDI_P2pNoaAttrIndType; + +/*--------------------------------------------------------------------------- + *WDI_P2pNoaStartIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 status; + wpt_uint32 bssIdx; +}WDI_P2pNoaStartIndType; + +/*--------------------------------------------------------------------------- + *WDI_TdlsIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 status; + wpt_uint16 assocId; + wpt_uint16 staIdx; + wpt_uint16 reasonCode; +}WDI_TdlsIndType; + +#ifdef WLAN_WAKEUP_EVENTS +/*--------------------------------------------------------------------------- + WDI_WakeReasonIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 ulReason; /* see tWakeReasonType */ + wpt_uint32 ulReasonArg; /* argument specific to the reason type */ + wpt_uint32 ulStoredDataLen; /* length of optional data stored in this message, in case + HAL truncates the data (i.e. data packets) this length + will be less than the actual length */ + wpt_uint32 ulActualDataLen; /* actual length of data */ + wpt_uint8 aDataStart[1]; /* variable length start of data (length == storedDataLen) + see specific wake type */ +} WDI_WakeReasonIndType; +#endif // WLAN_WAKEUP_EVENTS + +/*--------------------------------------------------------------------------- + WDI_MissedBeaconIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; /*bssidx on which beacon is missed*/ +} WDI_MissedBeaconIndType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI_LPHBTimeoutIndData +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint8 sessionIdx; + wpt_uint8 protocolType; /*TCP or UDP*/ + wpt_uint8 eventReason; +} WDI_LPHBTimeoutIndData; +#endif /* FEATURE_WLAN_LPHB */ + +/*----------------------------------------------------------------------------- +WDI_PeriodicTxPtrnFwIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint32 selfStaIdx; + wpt_uint32 status; + wpt_uint32 patternIdBitmap; +} WDI_PeriodicTxPtrnFwIndType; + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*--------------------------------------------------------------------------- + WDI_SetBatchScanReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 scanFrequency; /* how frequent to do scan default 30Sec*/ + wpt_uint32 numberOfScansToBatch; /* number of scans to batch */ + wpt_uint32 bestNetwork; /* best networks in terms of rssi */ + wpt_uint8 rfBand; /* band to scan : + 0 ->both Band, 1->2.4Ghz Only + and 2-> 5GHz Only */ + wpt_uint32 rtt; /* set if required to do RTT it is not + supported in current version */ +}WDI_SetBatchScanReqType; + +/*--------------------------------------------------------------------------- + WDI_SetBatchScanRspType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*max number of scans which FW can cache*/ + wpt_uint32 nScansToBatch; +}WDI_SetBatchScanRspType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBatchScanResultIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 param; +}WDI_TriggerBatchScanResultIndType; + +/*--------------------------------------------------------------------------- + WDI_StopBatchScanIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*max number of scans which FW can cache*/ + wpt_uint32 param; +}WDI_StopBatchScanIndType; + + +/*--------------------------------------------------------------------------- + * WDI_BatchScanResultIndType + *--------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 bssid[6]; /* BSSID */ + wpt_uint32 ssid[32]; /* SSID */ + wpt_uint32 ch; /* Channel */ + wpt_uint32 rssi; /* RSSI or Level */ + /* Timestamp when Network was found. Used to calculate age based on + timestamp in GET_RSP msg header */ + wpt_uint32 timestamp; +} tWDIBatchScanNetworkInfo, *tpWDIBatchScanNetworkInfo; + +typedef struct +{ + wpt_uint32 scanId; /*Scan List ID*/ + /*No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg*/ + wpt_uint32 numNetworksInScanList; + /*Variable data ptr: Number of AP in Scan List*/ + wpt_uint32 scanList[1]; +} tWDIBatchScanList, *tpWDIBatchScanList; + +typedef struct +{ + wpt_uint32 timestamp; + wpt_uint32 numScanLists; + wpt_boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + wpt_uint32 scanResults[1]; +} tWDIBatchScanResultParam, *tpWDIBatchScanResultParam; + +#endif + +/*--------------------------------------------------------------------------- + WDI_IbssPeerInactivityIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint8 staIdx; + wpt_macAddr staMacAddr; +}WDI_IbssPeerInactivityIndType; + +/*--------------------------------------------------------------------------- + WDI_TxRateFlags +-----------------------------------------------------------------------------*/ +typedef enum +{ + WDI_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + WDI_TX_RATE_HT20 = 0x2, /* HT20 rates */ + WDI_TX_RATE_HT40 = 0x4, /* HT40 rates */ + WDI_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + WDI_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + WDI_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + WDI_TX_RATE_VHT40 = 0x40, /* VHT 20 rates */ + WDI_TX_RATE_VHT80 = 0x80, /* VHT 20 rates */ + WDI_TX_RATE_VIRT = 0x100, /* Virtual Rate */ +} WDI_TxRateFlags; + +/*--------------------------------------------------------------------------- + WDI_RateUpdateIndParams +-----------------------------------------------------------------------------*/ +typedef struct +{ + /* 0 implies RA, positive value implies fixed rate, -1 implies ignore this + * param ucastDataRate can be used to control RA behavior of unicast data to + */ + wpt_int32 ucastDataRate; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags ucastDataRateTxFlag; + + /* BSSID - Optional. 00-00-00-00-00-00 implies apply to all BCAST STAs */ + wpt_macAddr bssid; + + /* + * 0 implies MCAST RA, positive value implies fixed rate, + * -1 implies ignore this param + */ + wpt_int32 reliableMcastDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags reliableMcastDataRateTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10, + * 0 implies ignore + */ + wpt_uint32 mcastDataRate24GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags mcastDataRate24GHzTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 5 GHz, + * unit Mbpsx10, 0 implies ignore + */ + wpt_uint32 mcastDataRate5GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags mcastDataRate5GHzTxFlag; + + /* + * Request status callback offered by UMAC - it is called if the current + * req has returned PENDING as status; it delivers the status of sending + * the message over the BUS + */ + WDI_ReqStatusCb wdiReqStatusCB; + + /* + * The user data passed in by UMAC, it will be sent back when the above + * function pointer will be called + */ + void *pUserData; + +} WDI_RateUpdateIndParams; + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndType + Inidcation type and information about the indication being carried + over +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Inidcation type*/ + WDI_LowLevelIndEnumType wdiIndicationType; + + /*Indication data*/ + union + { + /*RSSI Threshold Info for WDI_LOW_RSSI_IND*/ + WDI_LowRSSIThIndType wdiLowRSSIInfo; + + /*Addr2 Frame Info for WDI_UNKNOWN_ADDR2_FRAME_RX_IND*/ + WDI_UnkAddr2FrmRxIndType wdiUnkAddr2FrmInfo; + + /*MIC Failure info for WDI_MIC_FAILURE_IND*/ + WDI_MicFailureIndType wdiMICFailureInfo; + + /*Error code for WDI_FATAL_ERROR_IND*/ + wpt_uint16 usErrorCode; + + /*Delete STA Indication*/ + WDI_DeleteSTAIndType wdiDeleteSTAIndType; + + /*Coex Indication*/ + WDI_CoexIndType wdiCoexInfo; + + /* Tx Complete Indication */ + wpt_uint32 tx_complete_status; + + /* P2P NOA ATTR Indication */ + WDI_P2pNoaAttrIndType wdiP2pNoaAttrInfo; + WDI_P2pNoaStartIndType wdiP2pNoaStartInfo; + /* TDLS Indications */ + WDI_TdlsIndType wdiTdlsIndInfo; + + +#ifdef FEATURE_WLAN_SCAN_PNO + WDI_PrefNetworkFoundInd wdiPrefNetworkFoundInd; +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_WAKEUP_EVENTS + WDI_WakeReasonIndType wdiWakeReasonInd; +#endif // WLAN_WAKEUP_EVENTS + WDI_MissedBeaconIndType wdiMissedBeaconInd; + +#ifdef FEATURE_WLAN_LPHB + WDI_LPHBTimeoutIndData wdiLPHBTimeoutInd; +#endif /* FEATURE_WLAN_LPHB */ + + /* IBSS Peer Inactivity Indication */ + WDI_IbssPeerInactivityIndType wdiIbssPeerInactivityInd; + + /* Periodic TX Pattern FW Indication */ + WDI_PeriodicTxPtrnFwIndType wdiPeriodicTxPtrnFwInd; + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*batch scan result indication from FW*/ + void *pBatchScanResult; +#endif + + } wdiIndicationData; +}WDI_LowLevelIndType; + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndCBType + + DESCRIPTION + + This callback is invoked by DAL to deliver to UMAC certain indications + that has either received from the lower device or has generated itself. + + PARAMETERS + + IN + pwdiInd: information about the indication sent over + pUserData: user data provided by UMAC during registration + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_LowLevelIndCBType)(WDI_LowLevelIndType* pwdiInd, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_DriverType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_DRIVER_TYPE_PRODUCTION = 0, + WDI_DRIVER_TYPE_MFG = 1, + WDI_DRIVER_TYPE_DVT = 2 +} WDI_DriverType; + +/*--------------------------------------------------------------------------- + WDI_StartReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*This is a TLV formatted buffer containing all config values that can + be set through the DAL Interface + + The TLV is expected to be formatted like this: + + 0 7 15 31 .... + | CONFIG ID | CFG LEN | RESERVED | CFG BODY | + + Or from a C construct point of VU it would look like this: + + typedef struct WPT_PACK_POST + { + #ifdef WPT_BIG_ENDIAN + wpt_uint32 ucCfgId:8; + wpt_uint32 ucCfgLen:8; + wpt_uint32 usReserved:16; + #else + wpt_uint32 usReserved:16; + wpt_uint32 ucCfgLen:8; + wpt_uint32 ucCfgId:8; + #endif + + wpt_uint8 ucCfgBody[ucCfgLen]; + }WDI_ConfigType; + + Multiple such tuplets are to be placed in the config buffer. One for + each required configuration item: + + | TLV 1 | TLV2 | .... + + The buffer is expected to be a flat area of memory that can be manipulated + with standard memory routines. + + For more info please check paragraph 2.3.1 Config Structure from the + HAL LLD. + + For a list of accepted configuration list and IDs please look up + wlan_qct_dal_cfg.h + + */ + void* pConfigBuffer; + + /*Length of the config buffer above*/ + wpt_uint16 usConfigBufferLen; + + /*Production or FTM driver*/ + WDI_DriverType wdiDriverType; + + /*Should device enable frame translation */ + wpt_uint8 bFrameTransEnabled; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /*Indication callback given by UMAC to be called by the WLAN DAL when it + wishes to send something back independent of a request*/ + WDI_LowLevelIndCBType wdiLowLevelIndCB; + + /*The user data passed in by UMAC, it will be sent back when the indication + function pointer will be called */ + void* pIndUserData; +}WDI_StartReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_StartRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Max number of STA supported by the device*/ + wpt_uint8 ucMaxStations; + + /*Max number of BSS supported by the device*/ + wpt_uint8 ucMaxBssids; + + /*Version of the WLAN HAL API with which we were compiled*/ + WDI_WlanVersionType wlanCompiledVersion; + + /*Version of the WLAN HAL API that was reported*/ + WDI_WlanVersionType wlanReportedVersion; + + /*WCNSS Software version string*/ + wpt_uint8 wcnssSoftwareVersion[WDI_VERSION_LENGTH]; + + /*WCNSS Hardware version string*/ + wpt_uint8 wcnssHardwareVersion[WDI_VERSION_LENGTH]; +}WDI_StartRspParamsType; + + +/*--------------------------------------------------------------------------- + WDI_StopType +---------------------------------------------------------------------------*/ +typedef enum +{ + /*Device is being stopped due to a reset*/ + WDI_STOP_TYPE_SYS_RESET, + + /*Device is being stopped due to entering deep sleep*/ + WDI_STOP_TYPE_SYS_DEEP_SLEEP, + + /*Device is being stopped because the RF needs to shut off + (e.g.:Airplane mode)*/ + WDI_STOP_TYPE_RF_KILL +}WDI_StopType; + +/*--------------------------------------------------------------------------- + WDI_StopReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + + /*The reason for which the device is being stopped*/ + WDI_StopType wdiStopReason; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_StopReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_ScanMode +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_SCAN_MODE_NORMAL = 0, + WDI_SCAN_MODE_LEARN, + WDI_SCAN_MODE_SCAN, + WDI_SCAN_MODE_PROMISC, + WDI_SCAN_MODE_SUSPEND_LINK, + WDI_SCAN_MODE_ROAM_SCAN, + WDI_SCAN_MODE_ROAM_SUSPEND_LINK, + +} WDI_ScanMode; + +/*--------------------------------------------------------------------------- + WDI_ScanEntry +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx[WDI_NUM_BSSID]; + wpt_uint8 activeBSScnt; +}WDI_ScanEntry; + +/*--------------------------------------------------------------------------- + WDI_InitScanReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*LEARN - AP Role + SCAN - STA Role*/ + WDI_ScanMode wdiScanMode; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Whether BSS needs to be notified*/ + wpt_boolean bNotifyBSS; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + wpt_uint8 ucFrameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + wpt_uint8 ucFrameLength; + + /*Pointer to the MAC frame buffer. Used only if ucFrameLength is non-zero.*/ + WDI_MacMgmtHdr wdiMACMgmtHdr; + + /*Entry to hold number of active BSS to send NULL frames before + * initiating SCAN*/ + WDI_ScanEntry wdiScanEntry; + + /* Flag to enable/disable Single NOA*/ + wpt_boolean bUseNOA; + + /* Indicates the scan duration (in ms) */ + wpt_uint16 scanDuration; + +}WDI_InitScanReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_InitScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The info associated with the request that needs to be sent over to the + device*/ + WDI_InitScanReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_InitScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_StartScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to scan*/ + wpt_uint8 ucChannel; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_StartScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_StartScanRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the status of the operation */ + WDI_Status wdiStatus; + +#if defined WLAN_FEATURE_VOWIFI + wpt_uint32 aStartTSF[2]; + wpt_int8 ucTxMgmtPower; +#endif +}WDI_StartScanRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EndScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to stop scanning. Not used really. But retained + for symmetry with "start Scan" message. It can also help in error + check if needed.*/ + wpt_uint8 ucChannel; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EndScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_PhyChanBondState +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_PHY_SINGLE_CHANNEL_CENTERED = 0, + WDI_PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, + WDI_PHY_DOUBLE_CHANNEL_CENTERED = 2, + WDI_PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, +#ifdef WLAN_FEATURE_11AC + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + WDI_MAX_CB_STATE +} WDI_PhyChanBondState; + +/*--------------------------------------------------------------------------- + WDI_FinishScanReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*LEARN - AP Role + SCAN - STA Role*/ + WDI_ScanMode wdiScanMode; + + /*Operating channel to tune to.*/ + wpt_uint8 ucCurrentOperatingChannel; + + /*Channel Bonding state If 20/40 MHz is operational, this will indicate the + 40 MHz extension channel in combination with the control channel*/ + WDI_PhyChanBondState wdiCBState; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Whether BSS needs to be notified*/ + wpt_boolean bNotifyBSS; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + wpt_uint8 ucFrameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + wpt_uint8 ucFrameLength; + + /*Pointer to the MAC frame buffer. Used only if ucFrameLength is non-zero.*/ + WDI_MacMgmtHdr wdiMACMgmtHdr; + + /*Entry to hold number of active BSS to send NULL frames after SCAN*/ + WDI_ScanEntry wdiScanEntry; + +}WDI_FinishScanReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SwitchChReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to switch to.*/ + wpt_uint8 ucChannel; + + /*Local power constraint*/ + wpt_uint8 ucLocalPowerConstraint; + + /*Secondary channel offset */ + WDI_HTSecondaryChannelOffset wdiSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_VOWIFI + wpt_int8 cMaxTxPower; + + /*Self STA Mac address*/ + wpt_macAddr macSelfStaMacAddr; +#endif + /* VO Wifi comment: BSSID is needed to identify which session issued this request. As the + request has power constraints, this should be applied only to that session */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + wpt_macAddr macBSSId; + +}WDI_SwitchChReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SwitchChReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Channel Info*/ + WDI_SwitchChReqInfoType wdiChInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SwitchChReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_FinishScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Finish Scan request that will be sent down to the device*/ + WDI_FinishScanReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_FinishScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_JoinReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the BSSID to which STA is going to associate*/ + wpt_macAddr macBSSID; + + /*Indicates the MAC Address of the current Self STA*/ + wpt_macAddr macSTASelf; + + /*Indicates the link State determining the entity Type e.g. BTAMP-STA, STA etc.*/ + wpt_uint32 linkState; + + /*Indicates the channel to switch to.*/ + WDI_SwitchChReqInfoType wdiChannelInfo; + +}WDI_JoinReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_JoinReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_JoinReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_JoinReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_BssType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_INFRASTRUCTURE_MODE, + WDI_INFRA_AP_MODE, //Added for softAP support + WDI_IBSS_MODE, + WDI_BTAMP_STA_MODE, + WDI_BTAMP_AP_MODE, + WDI_BSS_AUTO_MODE, +}WDI_BssType; + +/*--------------------------------------------------------------------------- + WDI_NwType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_11A_NW_TYPE, + WDI_11B_NW_TYPE, + WDI_11G_NW_TYPE, + WDI_11N_NW_TYPE, +} WDI_NwType; + +/*--------------------------------------------------------------------------- + WDI_ConfigAction +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ADD_BSS, + WDI_UPDATE_BSS +} WDI_ConfigAction; + +/*--------------------------------------------------------------------------- + WDI_HTOperatingMode +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_HT_OP_MODE_PURE, + WDI_HT_OP_MODE_OVERLAP_LEGACY, + WDI_HT_OP_MODE_NO_LEGACY_20MHZ_HT, + WDI_HT_OP_MODE_MIXED + +} WDI_HTOperatingMode; + + +/*--------------------------------------------------------------------------- + WDI_STAEntryType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_STA_ENTRY_SELF, + WDI_STA_ENTRY_PEER, + WDI_STA_ENTRY_BSSID, + WDI_STA_ENTRY_BCAST, +#ifdef FEATURE_WLAN_TDLS + WDI_STA_ENTRY_TDLS_PEER, +#endif +}WDI_STAEntryType; + +/*--------------------------------------------------------------------------- + WDI_ConfigActionType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ADD_STA, + WDI_UPDATE_STA +} WDI_ConfigActionType; + +/*---------------------------------------------------------------------------- + Each station added has a rate mode which specifies the sta attributes + ----------------------------------------------------------------------------*/ +typedef enum +{ + WDI_RESERVED_1 = 0, + WDI_RESERVED_2, + WDI_RESERVED_3, + WDI_11b, + WDI_11bg, + WDI_11a, + WDI_11n, +} WDI_RateModeType; + +/*--------------------------------------------------------------------------- + WDI_SupportedRatesType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + WDI_RateModeType opRateMode; + + /* 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps */ + wpt_uint16 llbRates[WDI_NUM_11B_RATES]; + wpt_uint16 llaRates[WDI_NUM_11A_RATES]; + wpt_uint16 aLegacyRates[WDI_NUM_POLARIS_RATES]; + + /*Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + First 26 bits are reserved for those Titan rates and + the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved.*/ + wpt_uint32 uEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + wpt_uint8 aSupportedMCSSet[WDI_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + wpt_uint16 aRxHighestDataRate; + + +#ifdef WLAN_FEATURE_11AC + /*Indicates the Maximum MCS that can be received for each number + of spacial streams */ + wpt_uint16 vhtRxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to receive*/ + wpt_uint16 vhtRxHighestDataRate; + /*Indicates the Maximum MCS that can be transmitted for each number + of spacial streams */ + wpt_uint16 vhtTxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + wpt_uint16 vhtTxHighestDataRate; +#endif + +} WDI_SupportedRates; + +/*-------------------------------------------------------------------------- + WDI_HTMIMOPowerSaveState + Spatial Multiplexing(SM) Power Save mode + --------------------------------------------------------------------------*/ +typedef enum +{ + WDI_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + WDI_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + WDI_HT_MIMO_PS_NA = 2, // reserved + WDI_HT_MIMO_PS_NO_LIMIT = 3, // SM Power Save disabled +} WDI_HTMIMOPowerSaveState; + +/*--------------------------------------------------------------------------- + WDI_ConfigStaReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSSID of STA*/ + wpt_macAddr macBSSID; + + /*ASSOC ID, as assigned by UMAC*/ + wpt_uint16 usAssocId; + + /*Used for configuration of different HW modules.*/ + WDI_STAEntryType wdiSTAType; + + /*STA Index */ + wpt_uint8 staIdx; + + /*Short Preamble Supported.*/ + wpt_uint8 ucShortPreambleSupported; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*Listen interval of the STA*/ + wpt_uint16 usListenInterval; + + /*Support for 11e/WMM*/ + wpt_uint8 ucWMMEnabled; + + /*11n HT capable STA*/ + wpt_uint8 ucHTCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + wpt_uint8 ucTXChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed*/ + wpt_uint8 ucRIFSMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field*/ + wpt_uint8 ucLSIGTxopProtection; + + /*Max Ampdu Size supported by STA. Device programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + wpt_uint8 ucMaxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + wpt_uint8 ucMaxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + wpt_uint8 ucMaxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + wpt_uint8 ucShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + wpt_uint8 ucShortGI20Mhz; + + /*These rates are the intersection of peer and self capabilities.*/ + WDI_SupportedRates wdiSupportedRates; + + /*Robust Management Frame (RMF) enabled/disabled*/ + wpt_uint8 ucRMFEnabled; + + /* The unicast encryption type in the association */ + wpt_uint32 ucEncryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID.*/ + WDI_ConfigActionType wdiAction; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO + */ + wpt_uint8 ucAPSD; + + /*Max SP Length*/ + wpt_uint8 ucMaxSPLen; + + /*11n Green Field preamble support*/ + wpt_uint8 ucGreenFieldCapable; + + /*MIMO Power Save mode*/ + WDI_HTMIMOPowerSaveState wdiMIMOPS; + + /*Delayed BA Support*/ + wpt_uint8 ucDelayedBASupport; + + /*Max AMPDU duration in 32us*/ + wpt_uint8 us32MaxAmpduDuratio; + + /*HT STA should set it to 1 if it is enabled in BSS + HT STA should set it to 0 if AP does not support it. This indication is + sent to HAL and HAL uses this flag to pickup up appropriate 40Mhz rates. + */ + wpt_uint8 ucDsssCckMode40Mhz; + + wpt_uint8 ucP2pCapableSta; +#ifdef WLAN_FEATURE_11AC + wpt_uint8 ucVhtCapableSta; + wpt_uint8 ucVhtTxChannelWidthSet; + wpt_uint8 ucVhtTxBFEnabled; +#endif + + wpt_uint8 ucHtLdpcEnabled; + wpt_uint8 ucVhtLdpcEnabled; +}WDI_ConfigStaReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_RateSet + + 12 Bytes long because this structure can be used to represent rate + and extended rate set IEs + The parser assume this to be at least 12 +---------------------------------------------------------------------------*/ +#define WDI_RATESET_EID_MAX 12 + +typedef struct +{ + wpt_uint8 ucNumRates; + wpt_uint8 aRates[WDI_RATESET_EID_MAX]; +} WDI_RateSet; + +/*--------------------------------------------------------------------------- + WDI_AciAifsnType + access category record +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 rsvd : 1; + wpt_uint8 aci : 2; + wpt_uint8 acm : 1; + wpt_uint8 aifsn : 4; +} WDI_AciAifsnType; + +/*--------------------------------------------------------------------------- + WDI_CWType + contention window size +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 max : 4; + wpt_uint8 min : 4; +} WDI_CWType; + +/*--------------------------------------------------------------------------- + WDI_EdcaParamRecord +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Access Category Record*/ + WDI_AciAifsnType wdiACI; + + /*Contention WIndow Size*/ + WDI_CWType wdiCW; + + /*TX Oportunity Limit*/ + wpt_uint16 usTXOPLimit; +} WDI_EdcaParamRecord; + +/*--------------------------------------------------------------------------- + WDI_EDCAParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index*/ + wpt_uint8 ucBSSIdx; + + /*?*/ + wpt_boolean bHighPerformance; + + /*Best Effort*/ + WDI_EdcaParamRecord wdiACBE; + + /*Background*/ + WDI_EdcaParamRecord wdiACBK; + + /*Video*/ + WDI_EdcaParamRecord wdiACVI; + + /*Voice*/ + WDI_EdcaParamRecord acvo; // voice +} WDI_EDCAParamsType; + +/* operMode in ADD BSS message */ +#define WDI_BSS_OPERATIONAL_MODE_AP 0 +#define WDI_BSS_OPERATIONAL_MODE_STA 1 + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*BSS Index*/ + wpt_uint8 ucBSSIdx; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*BSS STA ID*/ + wpt_uint8 ucSTAIdx; + +#ifdef WLAN_FEATURE_VOWIFI + /*HAL fills in the tx power used for mgmt frames in this field */ + wpt_int8 ucTxMgmtPower; +#endif + +}WDI_ConfigBSSRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBSSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelBSSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBSSRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + wpt_uint8 ucBssIdx; + +}WDI_DelBSSRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigSTARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Idx allocated by HAL*/ + wpt_uint8 ucSTAIdx; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /* BSSID Index of BSS to which the station is associated */ + wpt_uint8 ucBssIdx; + + /* DPU Index - PTK */ + wpt_uint8 ucDpuIndex; + + /* Bcast DPU Index - GTK */ + wpt_uint8 ucBcastDpuIndex; + + /* Management DPU Index - IGTK - Why is it called bcastMgmtDpuIdx? */ + wpt_uint8 ucBcastMgmtDpuIdx; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /* IGTK DPU signature*/ + wpt_uint8 ucMgmtSig; + +}WDI_ConfigSTARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_PostAssocRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Parameters related to the BSS*/ + WDI_ConfigBSSRspParamsType bssParams; + + /*Parameters related to the self STA*/ + WDI_ConfigSTARspParamsType staParams; + +}WDI_PostAssocRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelSTAReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; +}WDI_DelSTARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EncryptType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ENCR_NONE, + WDI_ENCR_WEP40, + WDI_ENCR_WEP104, + WDI_ENCR_TKIP, + WDI_ENCR_CCMP, +#if defined(FEATURE_WLAN_WAPI) + WDI_ENCR_WPI, +#endif + WDI_ENCR_AES_128_CMAC +} WDI_EncryptType; + +/*--------------------------------------------------------------------------- + WDI_KeyDirectionType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_TX_ONLY, + WDI_RX_ONLY, + WDI_TX_RX, + WDI_TX_DEFAULT, + WDI_DONOT_USE_KEY_DIRECTION +} WDI_KeyDirectionType; + +#define WDI_MAX_ENCR_KEYS 4 +#define WDI_MAX_KEY_LENGTH 32 +#if defined(FEATURE_WLAN_WAPI) +#define WDI_MAX_KEY_RSC_LEN 16 +#define WDI_WAPI_KEY_RSC_LEN 16 +#else +#define WDI_MAX_KEY_RSC_LEN 8 +#endif + +typedef struct +{ + /* Key ID */ + wpt_uint8 keyId; + /* 0 for multicast */ + wpt_uint8 unicast; + /* Key Direction */ + WDI_KeyDirectionType keyDirection; + /* Usage is unknown */ + wpt_uint8 keyRsc[WDI_MAX_KEY_RSC_LEN]; + /* =1 for authenticator, =0 for supplicant */ + wpt_uint8 paeRole; + wpt_uint16 keyLength; + wpt_uint8 key[WDI_MAX_KEY_LENGTH]; + +}WDI_KeysType; + +/*--------------------------------------------------------------------------- + WDI_SetBSSKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Number of keys*/ + wpt_uint8 ucNumKeys; + + /*Array of keys.*/ + WDI_KeysType aKeys[WDI_MAX_ENCR_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + wpt_uint8 ucSingleTidRc; +}WDI_SetBSSKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetBSSKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_SetBSSKeyReqInfoType wdiBSSKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetBSSKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WepType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_WEP_STATIC, + WDI_WEP_DYNAMIC + +} WDI_WepType; + +/*--------------------------------------------------------------------------- + WDI_RemoveBSSKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Key Id*/ + wpt_uint8 ucKeyId; + + /*STATIC/DYNAMIC. Used in Nullifying in Key Descriptors for Static/Dynamic + keys*/ + WDI_WepType wdiWEPType; +}WDI_RemoveBSSKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemoveBSSKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_RemoveBSSKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemoveBSSKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetSTAKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*STATIC/DYNAMIC*/ + WDI_WepType wdiWEPType; + + /*Default WEP key, valid only for static WEP, must between 0 and 3.*/ + wpt_uint8 ucDefWEPIdx; + + /*Number of keys*/ + wpt_uint8 ucNumKeys; + + /*Array of keys.*/ + WDI_KeysType wdiKey[WDI_MAX_ENCR_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + wpt_uint8 ucSingleTidRc; +}WDI_SetSTAKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Peer BSSID*/ + wpt_macAddr macBSSID; + + /*Self MAC Address*/ + wpt_macAddr macSelfAddr; + + /*BSS Type*/ + WDI_BssType wdiBSSType; + + /*Operational Mode: AP =0, STA = 1*/ + wpt_uint8 ucOperMode; + + /*Network Type*/ + WDI_NwType wdiNWType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + wpt_uint8 ucShortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + wpt_uint8 ucllaCoexist; + + /*Co-exist with 11b STA*/ + wpt_uint8 ucllbCoexist; + + /*Co-exist with 11g STA*/ + wpt_uint8 ucllgCoexist; + + /*Coexistence with 11n STA*/ + wpt_uint8 ucHT20Coexist; + + /*Non GF coexist flag*/ + wpt_uint8 ucllnNonGFCoexist; + + /*TXOP protection support*/ + wpt_uint8 ucTXOPProtectionFullSupport; + + /*RIFS mode*/ + wpt_uint8 ucRIFSMode; + + /*Beacon Interval in TU*/ + wpt_uint16 usBeaconInterval; + + /*DTIM period*/ + wpt_uint8 ucDTIMPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + wpt_uint8 ucTXChannelWidthSet; + + /*Operating channel*/ + wpt_uint8 ucCurrentOperChannel; + + /*Extension channel for channel bonding*/ + wpt_uint8 ucCurrentExtChannel; + + /*Context of the station being added in HW.*/ + WDI_ConfigStaReqInfoType wdiSTAContext; + + /*SSID of the BSS*/ + WDI_MacSSid wdiSSID; + + /*HAL should update the existing BSS entry, if this flag is set. UMAC will + set this flag in case of RE-ASSOC, where we want to reuse the old BSSID*/ + WDI_ConfigAction wdiAction; + + /*Basic Rate Set*/ + WDI_RateSet wdiRateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + wpt_uint8 ucHTCapable; + + /* Enable/Disable OBSS protection */ + wpt_uint8 ucObssProtEnabled; + + /*RMF enabled/disabled*/ + wpt_uint8 ucRMFEnabled; + + /*Determines the current HT Operating Mode operating mode of the + 802.11n STA*/ + WDI_HTOperatingMode wdiHTOperMod; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + wpt_uint8 ucDualCTSProtection; + + /* Probe Response Max retries */ + wpt_uint8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + wpt_uint8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + wpt_uint8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + wpt_uint8 ucEDCAParamsValid; + + /*EDCA Parameters for BK*/ + WDI_EdcaParamRecord wdiBKEDCAParams; + + /*EDCA Parameters for BE*/ + WDI_EdcaParamRecord wdiBEEDCAParams; + + /*EDCA Parameters for VI*/ + WDI_EdcaParamRecord wdiVIEDCAParams; + + /*EDCA Parameters for VO*/ + WDI_EdcaParamRecord wdiVOEDCAParams; + +#ifdef WLAN_FEATURE_VOWIFI + /*max power to be used after applying the power constraint, if any */ + wpt_int8 cMaxTxPower; +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT, same as Connection Mode */ + wpt_uint8 ucPersona; + + /* Spectrum Mangement Indicator */ + wpt_uint8 bSpectrumMgtEn; + +#ifdef WLAN_FEATURE_VOWIFI_11R + wpt_uint8 bExtSetStaKeyParamValid; + WDI_SetSTAKeyReqInfoType wdiExtSetKeyParam; +#endif + +#ifdef WLAN_FEATURE_11AC + wpt_uint8 ucVhtCapableSta; + wpt_uint8 ucVhtTxChannelWidthSet; +#endif + +}WDI_ConfigBSSReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_PostAssocReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Config STA arguments.*/ + WDI_ConfigStaReqInfoType wdiSTAParams; + + /*Config BSS Arguments*/ + WDI_ConfigBSSReqInfoType wdiBSSParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_PostAssocReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_ConfigBSSReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigBSSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetSTAKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info*/ + WDI_SetSTAKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetSTAKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RemoveSTAKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Key Id*/ + wpt_uint8 ucKeyId; + + /*Whether to invalidate the Broadcast key or Unicast key. In case of WEP, + the same key is used for both broadcast and unicast.*/ + wpt_uint8 ucUnicast; +}WDI_RemoveSTAKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemoveSTAKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_RemoveSTAKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemoveSTAKeyReqParamsType; + +/*--------------------------------------------------------------------------- + QOS Parameters +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WDI_TSInfoTfc +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 ackPolicy:2; + wpt_uint16 userPrio:3; + wpt_uint16 psb:1; + wpt_uint16 aggregation : 1; + wpt_uint16 accessPolicy : 2; + wpt_uint16 direction : 2; + wpt_uint16 tsid : 4; + wpt_uint16 trafficType : 1; +} WDI_TSInfoTfc; + +/*--------------------------------------------------------------------------- + WDI_TSInfoSch +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 rsvd : 7; + wpt_uint8 schedule : 1; +} WDI_TSInfoSch; + +/*--------------------------------------------------------------------------- + WDI_TSInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_TSInfoTfc wdiTraffic; + WDI_TSInfoSch wdiSchedule; +} WDI_TSInfoType; + +/*--------------------------------------------------------------------------- + WDI_TspecIEType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucType; + wpt_uint8 ucLength; + WDI_TSInfoType wdiTSinfo; + wpt_uint16 usNomMsduSz; + wpt_uint16 usMaxMsduSz; + wpt_uint32 uMinSvcInterval; + wpt_uint32 uMaxSvcInterval; + wpt_uint32 uInactInterval; + wpt_uint32 uSuspendInterval; + wpt_uint32 uSvcStartTime; + wpt_uint32 uMinDataRate; + wpt_uint32 uMeanDataRate; + wpt_uint32 uPeakDataRate; + wpt_uint32 uMaxBurstSz; + wpt_uint32 uDelayBound; + wpt_uint32 uMinPhyRate; + wpt_uint16 usSurplusBw; + wpt_uint16 usMediumTime; +}WDI_TspecIEType; + +/*--------------------------------------------------------------------------- + WDI_AddTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint16 ucTspecIdx; + + /*Tspec IE negotiated OTA*/ + WDI_TspecIEType wdiTspecIE; + + /*UAPSD delivery and trigger enabled flags */ + wpt_uint8 ucUapsdFlags; + + /*SI for each AC*/ + wpt_uint8 ucServiceInterval[WDI_MAX_NO_AC]; + + /*Suspend Interval for each AC*/ + wpt_uint8 ucSuspendInterval[WDI_MAX_NO_AC]; + + /*DI for each AC*/ + wpt_uint8 ucDelayedInterval[WDI_MAX_NO_AC]; + +}WDI_AddTSReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TSpec Info */ + WDI_AddTSReqInfoType wdiTsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddTSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint16 ucTspecIdx; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; +}WDI_DelTSReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Del TSpec Info*/ + WDI_DelTSReqInfoType wdiDelTSInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelTSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateEDCAInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint16 ucBssIdx; + + /*EDCA params for BE*/ + WDI_EdcaParamRecord wdiEdcaBEInfo; + + /*EDCA params for BK*/ + WDI_EdcaParamRecord wdiEdcaBKInfo; + + /*EDCA params for VI*/ + WDI_EdcaParamRecord wdiEdcaVIInfo; + + /*EDCA params for VO*/ + WDI_EdcaParamRecord wdiEdcaVOInfo; + +}WDI_UpdateEDCAInfoType; + +/*--------------------------------------------------------------------------- + WDI_UpdateEDCAParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*EDCA Info */ + WDI_UpdateEDCAInfoType wdiEDCAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateEDCAParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBASessionReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /*The peer mac address*/ + wpt_macAddr macPeerAddr; + + /*TID for which BA was negotiated*/ + wpt_uint8 ucBaTID; + + /*Delayed or imediate */ + wpt_uint8 ucBaPolicy; + + /*The number of buffers for this TID (baTID)*/ + wpt_uint16 usBaBufferSize; + + /*BA timeout in TU's*/ + wpt_uint16 usBaTimeout; + + /*b0..b3 - Fragment Number - Always set to 0 + b4..b15 - Starting Sequence Number of first MSDU for which this BA is setup*/ + wpt_uint16 usBaSSN; + + /*Originator/Recipient*/ + wpt_uint8 ucBaDirection; + +}WDI_AddBASessionReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddBASessionReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Session Info Type*/ + WDI_AddBASessionReqinfoType wdiBASessionInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddBASessionReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBASessionRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /* Dialog token */ + wpt_uint8 ucBaDialogToken; + + /* TID for which the BA session has been setup */ + wpt_uint8 ucBaTID; + + /* BA Buffer Size allocated for the current BA session */ + wpt_uint8 ucBaBufferSize; + + /* BA session ID */ + wpt_uint16 usBaSessionID; + + /* Reordering Window buffer */ + wpt_uint8 ucWinSize; + + /*Station Index to id the sta */ + wpt_uint8 ucSTAIdx; + + /* Starting Sequence Number */ + wpt_uint16 usBaSSN; + +}WDI_AddBASessionRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /* Session Id */ + wpt_uint8 ucBaSessionID; + + /* Reorder Window Size */ + wpt_uint8 ucWinSize; + +#ifdef FEATURE_ON_CHIP_REORDERING + wpt_boolean bIsReorderingDoneOnChip; +#endif + +}WDI_AddBAReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Info Type*/ + WDI_AddBAReqinfoType wdiBAInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddBAReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_AddBARspinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /* Dialog token */ + wpt_uint8 ucBaDialogToken; + +}WDI_AddBARspinfoType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqCandidateType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* STA index */ + wpt_uint8 ucSTAIdx; + + /* TID bit map for the STA's*/ + wpt_uint8 ucTidBitmap; + +}WDI_TriggerBAReqCandidateType; + + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /* Session Id */ + wpt_uint8 ucBASessionID; + + /* Trigger BA Request candidate count */ + wpt_uint16 usBACandidateCnt; + + /* WDI_TriggerBAReqCandidateType followed by this*/ + +}WDI_TriggerBAReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Trigger Info Type*/ + WDI_TriggerBAReqinfoType wdiTriggerBAInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_TriggerBAReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBAInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 fBaEnable : 1; + wpt_uint16 startingSeqNum: 12; + wpt_uint16 reserved : 3; +}WDI_AddBAInfoType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspCandidateType +---------------------------------------------------------------------------*/ +#define STA_MAX_TC 8 + +typedef struct +{ + /* STA index */ + wpt_macAddr macSTA; + + /* BA Info */ + WDI_AddBAInfoType wdiBAInfo[STA_MAX_TC]; +}WDI_TriggerBARspCandidateType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /* Trigger BA response candidate count */ + wpt_uint16 usBaCandidateCnt; + + /* WDI_TriggerBARspCandidateType followed by this*/ + +}WDI_TriggerBARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /*TID for which BA was negotiated*/ + wpt_uint8 ucBaTID; + + /*Originator/Recipient*/ + wpt_uint8 ucBaDirection; + +}WDI_DelBAReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_DelBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Info */ + WDI_DelBAReqinfoType wdiBAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelBAReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_SwitchCHRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Indicates the channel that WLAN is on*/ + wpt_uint8 ucChannel; + +#ifdef WLAN_FEATURE_VOWIFI + /*HAL fills in the tx power used for mgmt frames in this field.*/ + wpt_int8 ucTxMgmtPower; +#endif + +}WDI_SwitchCHRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigSTAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_ConfigStaReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigSTAReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*shortPreamble mode. HAL should update all the STA rates when it + receives this message*/ + wpt_uint8 ucfShortPreamble; + /* short Slot time.*/ + wpt_uint8 ucfShortSlotTime; + /* Beacon Interval */ + wpt_uint16 usBeaconInterval; + /*Protection related */ + wpt_uint8 ucllaCoexist; + wpt_uint8 ucllbCoexist; + wpt_uint8 ucllgCoexist; + wpt_uint8 ucHt20MhzCoexist; + wpt_uint8 ucllnNonGFCoexist; + wpt_uint8 ucfLsigTXOPProtectionFullSupport; + wpt_uint8 ucfRIFSMode; + + wpt_uint16 usChangeBitmap; +}WDI_UpdateBeaconParamsInfoType; + +#ifdef WLAN_FEATURE_11AC +typedef struct +{ + wpt_uint16 opMode; + wpt_uint16 staId; +}WDI_UpdateVHTOpMode; +#endif + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Update Beacon Params Info*/ + WDI_UpdateBeaconParamsInfoType wdiUpdateBeaconParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateBeaconParamsType; + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsInfoType +---------------------------------------------------------------------------*/ + +typedef struct { + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /* Beacon data */ + wpt_uint8 beacon[WDI_BEACON_TEMPLATE_SIZE]; + + /* length of the template */ + wpt_uint32 beaconLength; + + /* TIM IE offset from the beginning of the template.*/ + wpt_uint32 timIeOffset; + + /* P2P IE offset from the beginning of the template */ + wpt_uint16 usP2PIeOffset; +} WDI_SendBeaconParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Send Beacon Params Info*/ + WDI_SendBeaconParamsInfoType wdiSendBeaconParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SendBeaconParamsType; + +/*--------------------------------------------------------------------------- + WDI_LinkStateType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_LINK_IDLE_STATE = 0, + WDI_LINK_PREASSOC_STATE = 1, + WDI_LINK_POSTASSOC_STATE = 2, + WDI_LINK_AP_STATE = 3, + WDI_LINK_IBSS_STATE = 4, + + // BT-AMP Case + WDI_LINK_BTAMP_PREASSOC_STATE = 5, + WDI_LINK_BTAMP_POSTASSOC_STATE = 6, + WDI_LINK_BTAMP_AP_STATE = 7, + WDI_LINK_BTAMP_STA_STATE = 8, + + // Reserved for HAL internal use + WDI_LINK_LEARN_STATE = 9, + WDI_LINK_SCAN_STATE = 10, + WDI_LINK_FINISH_SCAN_STATE = 11, + WDI_LINK_INIT_CAL_STATE = 12, + WDI_LINK_FINISH_CAL_STATE = 13, + WDI_LINK_LISTEN_STATE = 14, + WDI_LINK_SEND_ACTION_STATE = 15, + WDI_LINK_MAX = 0x7FFFFFFF +} WDI_LinkStateType; + +/*--------------------------------------------------------------------------- + WDI_SetLinkReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Link state*/ + WDI_LinkStateType wdiLinkState; + + /*BSSID of the BSS*/ + wpt_macAddr macSelfStaMacAddr; +}WDI_SetLinkReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetLinkReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetLinkReqInfoType wdiLinkInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetLinkReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; +}WDI_GetStatsParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get Stats Params Info*/ + WDI_GetStatsParamsInfoType wdiGetStatsParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_GetStatsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*message type is same as the request type*/ + wpt_uint16 usMsgType; + + /* length of the entire request, includes the pStatsBuf length too*/ + wpt_uint16 usMsgLen; + + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; + + /* The Stats buffer starts here and can be an aggregate of more than one statistics + * structure depending on statsMask.*/ +}WDI_GetStatsRspParamsType; + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; +}WDI_GetRoamRssiParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get Roam Rssi Params Info*/ + WDI_GetRoamRssiParamsInfoType wdiGetRoamRssiParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_GetRoamRssiReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* roam rssi requested */ + wpt_int8 rssi; + + /* The Stats buffer starts here and can be an aggregate of more than one statistics + * structure depending on statsMask.*/ +}WDI_GetRoamRssiRspParamsType; +#endif + +#ifdef FEATURE_WLAN_ESE +/*--------------------------------------------------------------------------- + WDI_TSMStatsParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucTid; + + wpt_macAddr bssid; +}WDI_TSMStatsParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_TSMStatsReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get TSM Stats Params Info*/ + WDI_TSMStatsParamsInfoType wdiTsmStatsParamsInfo; + + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_TSMStatsReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_TSMStatsRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the status of the operation */ + WDI_Status wdiStatus; + + wpt_uint16 UplinkPktQueueDly; + wpt_uint16 UplinkPktQueueDlyHist[4]; + wpt_uint32 UplinkPktTxDly; + wpt_uint16 UplinkPktLoss; + wpt_uint16 UplinkPktCount; + wpt_uint8 RoamingCount; + wpt_uint16 RoamingDly; +}WDI_TSMStatsRspParamsType; + + +#endif +/*--------------------------------------------------------------------------- + WDI_UpdateCfgReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*This is a TLV formatted buffer containing all config values that can + be set through the DAL Interface + + The TLV is expected to be formatted like this: + + 0 7 15 31 .... + | CONFIG ID | CFG LEN | RESERVED | CFG BODY | + + Or from a C construct point of VU it would look like this: + + typedef struct WPT_PACK_POST + { + #ifdef WPT_BIG_ENDIAN + wpt_uint32 ucCfgId:8; + wpt_uint32 ucCfgLen:8; + wpt_uint32 usReserved:16; + #else + wpt_uint32 usReserved:16; + wpt_uint32 ucCfgLen:8; + wpt_uint32 ucCfgId:8; + #endif + + wpt_uint8 ucCfgBody[ucCfgLen]; + }WDI_ConfigType; + + Multiple such tuplets are to be placed in the config buffer. One for + each required configuration item: + + | TLV 1 | TLV2 | .... + + The buffer is expected to be a flat area of memory that can be manipulated + with standard memory routines. + + For more info please check paragraph 2.3.1 Config Structure from the + HAL LLD. + + For a list of accepted configuration list and IDs please look up + wlan_qct_dal_cfg.h + */ + void* pConfigBuffer; + + /*Length of the config buffer above*/ + wpt_uint32 uConfigBufferLen; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateCfgReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspTemplateInfoType +---------------------------------------------------------------------------*/ +//Default Beacon template size +#define WDI_PROBE_RSP_TEMPLATE_SIZE 0x180 + +#define WDI_PROBE_REQ_BITMAP_IE_LEN 8 + +typedef struct +{ + /*BSSID for which the Probe Template is to be used*/ + wpt_macAddr macBSSID; + + /*Probe response template*/ + wpt_uint8 *pProbeRespTemplate[WDI_PROBE_RSP_TEMPLATE_SIZE]; + + /*Template Len*/ + wpt_uint32 uProbeRespTemplateLen; + + /*Bitmap for the IEs that are to be handled at SLM level*/ + wpt_uint32 uaProxyProbeReqValidIEBmap[WDI_PROBE_REQ_BITMAP_IE_LEN]; + +}WDI_UpdateProbeRspTemplateInfoType; + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_UpdateProbeRspTemplateInfoType wdiProbeRspTemplateInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateProbeRspTemplateParamsType; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadReqBlobInfo +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* Blob starting address*/ + void *pBlobAddress; + + /* Blob size */ + wpt_uint32 uBlobSize; + +}WDI_NvDownloadReqBlobInfo; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*NV Blob Info*/ + WDI_NvDownloadReqBlobInfo wdiBlobInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_NvDownloadReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadRspInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + +}WDI_NvDownloadRspInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + /*BSSID is needed to identify which session issued this request. As the request has + power constraints, this should be applied only to that session*/ + wpt_macAddr macBSSId; + + + wpt_macAddr macSelfStaMacAddr; + + /* In request power == MaxTxpower to be used.*/ + wpt_int8 ucPower; + +}WDI_SetMaxTxPowerInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint8 bssIdx; + /* In request power == MaxTxpower to be used.*/ + wpt_uint8 ucPower; + +}WDI_SetTxPowerInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetMaxTxPowerInfoType wdiMaxTxPowerInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetMaxTxPowerParamsType; + +/*--------------------------------------------------------------------------- + WDI_Band +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_BAND_ALL, + WDI_BAND_24, + WDI_BAND_5G, + WDI_BAND_MAX, +}eWDIBand; + +/*--------------------------------------------------------------------------- + WDI_MaxTxPowerPerBandInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + eWDIBand bandInfo; + /* In request power == MaxTxpower to be used.*/ + wpt_uint8 ucPower; +}WDI_MaxTxPowerPerBandInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerPerBandParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_MaxTxPowerPerBandInfoType wdiMaxTxPowerPerBandInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetMaxTxPowerPerBandParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetTxPowerInfoType wdiTxPowerInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTxPowerParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerRspMsg +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetMaxTxPowerRspMsg; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerPerBandRspMsg +---------------------------------------------------------------------------*/ +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetMaxTxPowerPerBandRspMsg; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerRspMsg +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetTxPowerRspMsg; + +typedef struct +{ + wpt_uint8 ucOpp_ps; + wpt_uint32 uCtWindow; + wpt_uint8 ucCount; + wpt_uint32 uDuration; + wpt_uint32 uInterval; + wpt_uint32 uSingle_noa_duration; + wpt_uint8 ucPsSelection; +}WDI_SetP2PGONOAReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetP2PGONOAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*P2P GO NOA Req*/ + WDI_SetP2PGONOAReqInfoType wdiP2PGONOAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetP2PGONOAReqParamsType; + +#define WDI_MAX_SUPP_CHANNELS 128 +#define WDI_MAX_SUPP_OPER_CLASSES 32 + +typedef struct +{ + wpt_uint16 uStaIdx; + wpt_uint8 uIsResponder; + wpt_uint8 uUapsdQueues; + wpt_uint8 uMaxSp; + wpt_uint8 uIsBufSta; + wpt_uint8 uIsOffChannelSupported; + wpt_uint8 peerCurrOperClass; + wpt_uint8 selfCurrOperClass; + wpt_uint8 validChannelsLen; + wpt_uint8 validChannels[WDI_MAX_SUPP_CHANNELS]; + wpt_uint8 validOperClassesLen; + wpt_uint8 validOperClasses[WDI_MAX_SUPP_OPER_CLASSES]; +}WDI_SetTDLSLinkEstablishReqInfoType; +/*--------------------------------------------------------------------------- + WDI_SetTDLSLinkEstablishReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TDLS Link Establish Req*/ + WDI_SetTDLSLinkEstablishReqInfoType wdiTDLSLinkEstablishInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTDLSLinkEstablishReqParamsType; + + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*STA Idx*/ + wpt_uint16 uStaIdx; +}WDI_SetTdlsLinkEstablishReqResp; + +/*--------------------------------------------------------------------------- + WDI_SetAddSTASelfParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Self Station MAC address*/ + wpt_macAddr selfMacAddr; + + /*Self STA device mode*/ + wpt_uint32 currDeviceMode; + + /*Status of the operation*/ + wpt_uint32 uStatus; +}WDI_AddSTASelfInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetAddSTASelfParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Add Sta Self Req */ + WDI_AddSTASelfInfoType wdiAddSTASelfInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddSTASelfReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_AddSTASelfRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Idx allocated by HAL*/ + wpt_uint8 ucSTASelfIdx; + + /* DPU Index (IGTK, PTK, GTK all same) */ + wpt_uint8 dpuIdx; + + /* DPU Signature */ + wpt_uint8 dpuSignature; + + /*Self STA Mac*/ + wpt_macAddr macSelfSta; + +}WDI_AddSTASelfRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfReqParamsType + Del Sta Self info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr selfMacAddr; + +}WDI_DelSTASelfInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfReqParamsType + Del Sta Self info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Del Sta Self Info Type */ + WDI_DelSTASelfInfoType wdiDelStaSelfInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelSTASelfReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ +// wpt_uint8 ucSTAIdx; +}WDI_DelSTASelfRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_UapsdInfoType + UAPSD parameters passed per AC to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; // STA index + wpt_uint8 ucAc; // Access Category + wpt_uint8 ucUp; // User Priority + wpt_uint32 uSrvInterval; // Service Interval + wpt_uint32 uSusInterval; // Suspend Interval + wpt_uint32 uDelayInterval; // Delay Interval +} WDI_UapsdInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetUapsdAcParamsReqParamsType + UAPSD parameters passed per AC to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter BMPS Info Type, same as tEnterBmpsParams */ + WDI_UapsdInfoType wdiUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetUapsdAcParamsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqinfoType + Enter BMPS parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + //TBTT value derived from the last beacon + wpt_uint8 ucBssIdx; + wpt_uint64 uTbtt; + wpt_uint8 ucDtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + wpt_uint8 ucDtimPeriod; + /* DXE physical addr to be passed down to RIVA. RIVA HAL will use it to program + DXE when DXE wakes up from power save*/ + unsigned int dxePhyAddr; + + // For ESE and 11R Roaming + wpt_uint32 rssiFilterPeriod; + wpt_uint32 numBeaconPerRssiAverage; + wpt_uint8 bRssiFilterEnable; +}WDI_EnterBmpsReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqParamsType + Enter BMPS parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter BMPS Info Type, same as tEnterBmpsParams */ + WDI_EnterBmpsReqinfoType wdiEnterBmpsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EnterBmpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqParamsType + Enter BMPS parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_EnterBmpsRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqinfoType + Exit BMPS parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSendDataNull; + wpt_uint8 bssIdx; +}WDI_ExitBmpsReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqParamsType + Exit BMPS parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Exit BMPS Info Type, same as tExitBmpsParams */ + WDI_ExitBmpsReqinfoType wdiExitBmpsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExitBmpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqParamsType + Exit BMPS parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_ExitBmpsRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdReqinfoType + Enter UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucBkDeliveryEnabled:1; + wpt_uint8 ucBeDeliveryEnabled:1; + wpt_uint8 ucViDeliveryEnabled:1; + wpt_uint8 ucVoDeliveryEnabled:1; + wpt_uint8 ucBkTriggerEnabled:1; + wpt_uint8 ucBeTriggerEnabled:1; + wpt_uint8 ucViTriggerEnabled:1; + wpt_uint8 ucVoTriggerEnabled:1; + wpt_uint8 bssIdx; +}WDI_EnterUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdRspParamsType + Enter UAPSD parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_EnterUapsdRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdReqinfoType + Enter UAPSD parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter UAPSD Info Type, same as tUapsdParams */ + WDI_EnterUapsdReqinfoType wdiEnterUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EnterUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdReqinfoType + Update UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; + wpt_uint8 ucUapsdACMask; + wpt_uint32 uMaxSpLen; +}WDI_UpdateUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdReqinfoType + Exit UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; +}WDI_ExitUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdReqParamsType + Exit UAPSD parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Exit UAPSD Info Type, same as tUapsdParams */ + WDI_ExitUapsdReqinfoType wdiExitUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExitUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdRspParamsType + Exit UAPSD parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_ExitUapsdRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdReqParamsType + Update UAPSD parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Update UAPSD Info Type, same as tUpdateUapsdParams */ + WDI_UpdateUapsdReqinfoType wdiUpdateUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigureRxpFilterReqParamsType + RXP filter parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucSetMcstBcstFilterSetting; + + /* Mcast Bcast Filters enable/disable*/ + wpt_uint8 ucSetMcstBcstFilter; +}WDI_RxpFilterReqParamsType; + +typedef struct +{ + /* Rxp Filter */ + WDI_RxpFilterReqParamsType wdiRxpFilterParam; + + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigureRxpFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_BeaconFilterInfoType + Beacon Filtering data structures passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 usCapabilityInfo; + wpt_uint16 usCapabilityMask; + wpt_uint16 usBeaconInterval; + wpt_uint16 usIeNum; + wpt_uint8 bssIdx; + wpt_uint8 reserved; +}WDI_BeaconFilterInfoType; + +/*--------------------------------------------------------------------------- + WDI_BeaconFilterReqParamsType + Beacon Filtering parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Beacon Filtering Info Type, same as tBeaconFilterMsg */ + WDI_BeaconFilterInfoType wdiBeaconFilterInfo; + /*Beacon Filter(s) follow the "usIeNum" field, hence the array to ease the + copy of params from WDA to WDI */ + wpt_uint8 aFilters[WDI_BEACON_FILTER_LEN]; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_BeaconFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterInfoType + Beacon Filtering data structures (to be reomoved) passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucIeCount; + wpt_uint8 ucRemIeId[1]; +}WDI_RemBeaconFilterInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterReqParamsType + Beacon Filtering parameters (to be reomoved)passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Beacon Filtering Info Type, same as tBeaconFilterMsg */ + WDI_RemBeaconFilterInfoType wdiBeaconFilterInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemBeaconFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RSSIThresholdsType + RSSI thresholds data structures (to be reomoved) passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_int8 ucRssiThreshold1 : 8; + wpt_int8 ucRssiThreshold2 : 8; + wpt_int8 ucRssiThreshold3 : 8; + wpt_uint8 bRssiThres1PosNotify : 1; + wpt_uint8 bRssiThres1NegNotify : 1; + wpt_uint8 bRssiThres2PosNotify : 1; + wpt_uint8 bRssiThres2NegNotify : 1; + wpt_uint8 bRssiThres3PosNotify : 1; + wpt_uint8 bRssiThres3NegNotify : 1; + wpt_uint8 bReserved10 : 2; +} WDI_RSSIThresholdsType; + +/*--------------------------------------------------------------------------- + WDI_SetRSSIThresholdsReqParamsType + RSSI thresholds parameters (to be reomoved)passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*RSSI thresholds Info Type, same as WDI_RSSIThresholds */ + WDI_RSSIThresholdsType wdiRSSIThresholdsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetRSSIThresholdsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_HostOffloadReqType + host offload info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +#ifdef WLAN_NS_OFFLOAD +typedef struct +{ + wpt_uint8 srcIPv6Addr[16]; + wpt_uint8 selfIPv6Addr[16]; + //Only support 2 possible Network Advertisement IPv6 address + wpt_uint8 targetIPv6Addr1[16]; + wpt_uint8 targetIPv6Addr2[16]; + wpt_uint8 selfMacAddr[6]; + wpt_uint8 srcIPv6AddrValid : 1; + wpt_uint8 targetIPv6Addr1Valid : 1; + wpt_uint8 targetIPv6Addr2Valid : 1; + wpt_uint8 slotIdx; +} WDI_NSOffloadParams; +#endif //WLAN_NS_OFFLOAD + +typedef struct +{ + wpt_uint8 ucOffloadType; + wpt_uint8 ucEnableOrDisable; + wpt_macAddr bssId; + union + { + wpt_uint8 aHostIpv4Addr [4]; + wpt_uint8 aHostIpv6Addr [16]; + } params; +} WDI_HostOffloadReqType; + +/*--------------------------------------------------------------------------- + WDI_HostOffloadReqParamsType + host offload info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Host offload Info Type, same as tHalHostOffloadReq */ + WDI_HostOffloadReqType wdiHostOffloadInfo; +#ifdef WLAN_NS_OFFLOAD + WDI_NSOffloadParams wdiNsOffloadParams; +#endif //WLAN_NS_OFFLOAD + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_HostOffloadReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_KeepAliveReqType + Keep Alive info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucPacketType; + wpt_uint32 ucTimePeriod; + wpt_uint8 aHostIpv4Addr[4]; + wpt_uint8 aDestIpv4Addr[4]; + wpt_uint8 aDestMacAddr[6]; + wpt_macAddr bssId; +} WDI_KeepAliveReqType; + +/*--------------------------------------------------------------------------- + WDI_KeepAliveReqParamsType + Keep Alive passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Keep Alive Info Type, same as tHalKeepAliveReq */ + WDI_KeepAliveReqType wdiKeepAliveInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_KeepAliveReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnInfoType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + wpt_uint8 ucPatternByteOffset; + wpt_uint8 ucPatternSize; // Non-Zero Pattern size + wpt_uint8 ucPattern[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + wpt_uint8 ucPatternMaskSize; // Non-zero pattern mask size + wpt_uint8 ucPatternMask[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + wpt_uint8 ucPatternExt[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern + wpt_uint8 ucPatternMaskExt[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern mask + wpt_macAddr bssId; +} WDI_WowlAddBcPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnReqParamsType + Wowl add ptrn info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl add ptrn Info Type, same as tpSirWowlAddBcastPtrn */ + WDI_WowlAddBcPtrnInfoType wdiWowlAddBcPtrnInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlAddBcPtrnReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnRspParamsType + Wowl add ptrn info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_WowlAddBcPtrnRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnInfoType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Pattern ID of the wakeup pattern to be deleted */ + wpt_uint8 ucPatternId; + wpt_macAddr bssId; +} WDI_WowlDelBcPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnReqParamsType + Wowl add ptrn info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_WowlDelBcastPtrn */ + WDI_WowlDelBcPtrnInfoType wdiWowlDelBcPtrnInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlDelBcPtrnReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnRspParamsType + Wowl Del ptrn info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_WowlDelBcPtrnRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterInfoType + Wowl enter info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Enables/disables magic packet filtering */ + wpt_uint8 ucMagicPktEnable; + + /* Magic pattern */ + wpt_macAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + wpt_uint8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + wpt_uint8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + wpt_uint8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + wpt_uint8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + wpt_uint8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + wpt_uint8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + wpt_uint8 ucWowMaxSleepUsec; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + wpt_uint8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + wpt_uint8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + wpt_uint8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + wpt_uint8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + wpt_uint8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +} WDI_WowlEnterInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterReqParamsType + Wowl enter info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_SmeWowlEnterParams */ + WDI_WowlEnterInfoType wdiWowlEnterInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlEnterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterRsqParamsType + Wowl enter info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response message*/ + WDI_Status status; + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +}WDI_WowlEnterRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitInfoType + Wowl exit info passed to WDA form UMAC + ---------------------------------------------------------------------------*/ +typedef struct +{ + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +} WDI_WowlExitInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitReqParamsType + Wowl exit info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_SmeWowlEnterParams */ + WDI_WowlExitInfoType wdiWowlExitInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlExitReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitRspParamsType + Wowl exit info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response message*/ + WDI_Status status; + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +}WDI_WowlExitRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigureAppsCpuWakeupStateReqParamsType + Apps Cpu Wakeup State parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Depicts the state of the Apps CPU */ + wpt_boolean bIsAppsAwake; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigureAppsCpuWakeupStateReqParamsType; +/*--------------------------------------------------------------------------- + WDI_FlushAcReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + // Message Type + wpt_uint16 usMesgType; + + // Message Length + wpt_uint16 usMesgLen; + + // Station Index. originates from HAL + wpt_uint8 ucSTAId; + + // TID for which the transmit queue is being flushed + wpt_uint8 ucTid; + +}WDI_FlushAcReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_FlushAcReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*AC Info */ + WDI_FlushAcReqinfoType wdiFlushAcInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_FlushAcReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventinfoType + BT-AMP Event Structure +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucBtAmpEventType; + +} WDI_BtAmpEventinfoType; + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BT AMP event Info */ + WDI_BtAmpEventinfoType wdiBtAmpEventInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_BtAmpEventParamsType; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 280 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1724 +#endif + +/*---------------------------------------------------------------------------- + WDI_oemDataReqInfoType +----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr selfMacAddr; + wpt_uint8 oemDataReq[OEM_DATA_REQ_SIZE]; +}WDI_oemDataReqInfoType; + +/*---------------------------------------------------------------------------- + WDI_oemDataReqParamsType +----------------------------------------------------------------------------*/ +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /*OEM DATA REQ Info */ + WDI_oemDataReqInfoType wdiOemDataReqInfo; + +}WDI_oemDataReqParamsType; + +/*---------------------------------------------------------------------------- + WDI_oemDataRspParamsType +----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 oemDataRsp[OEM_DATA_RSP_SIZE]; +}WDI_oemDataRspParamsType; + +#endif /* FEATURE_OEM_DATA_SUPPORT */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*--------------------------------------------------------------------------- + WDI_AggrAddTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint8 ucTspecIdx; + + /*Tspec IE negotiated OTA*/ + WDI_TspecIEType wdiTspecIE[WDI_MAX_NO_AC]; + + /*UAPSD delivery and trigger enabled flags */ + wpt_uint8 ucUapsdFlags; + + /*SI for each AC*/ + wpt_uint8 ucServiceInterval[WDI_MAX_NO_AC]; + + /*Suspend Interval for each AC*/ + wpt_uint8 ucSuspendInterval[WDI_MAX_NO_AC]; + + /*DI for each AC*/ + wpt_uint8 ucDelayedInterval[WDI_MAX_NO_AC]; + +}WDI_AggrAddTSReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_AggrAddTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TSpec Info */ + WDI_AggrAddTSReqInfoType wdiAggrTsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AggrAddTSReqParamsType; + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/*--------------------------------------------------------------------------- + WDI_FTMCommandReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* FTM Command Body length */ + wpt_uint32 bodyLength; + /* Actual FTM Command body */ + void *FTMCommandBody; +}WDI_FTMCommandReqType; + +/*--------------------------------------------------------------------------- + WDI_WlanSuspendInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucConfiguredMcstBcstFilterSetting; +}WDI_WlanSuspendInfoType; + +/*--------------------------------------------------------------------------- + WDI_SuspendParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_WlanSuspendInfoType wdiSuspendParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_SuspendParamsType; + +/*--------------------------------------------------------------------------- + WDI_TrafficStatsType - This is collected for each STA +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* TX stats */ + wpt_uint32 txBytesPushed; + wpt_uint32 txPacketsPushed; + + /* RX stats */ + wpt_uint32 rxBytesRcvd; + wpt_uint32 rxPacketsRcvd; + wpt_uint32 rxTimeTotal; +}WDI_TrafficStatsType; + +typedef struct +{ + WDI_TrafficStatsType *pTrafficStats; + wpt_uint32 length; + wpt_uint32 duration; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_TrafficStatsIndType; + +#ifdef WLAN_FEATURE_11W +typedef struct +{ + + wpt_boolean bExcludeUnencrypt; + wpt_macAddr bssid; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExcludeUnencryptIndType; +#endif + +/*--------------------------------------------------------------------------- + WDI_WlanResumeInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucConfiguredMcstBcstFilterSetting; +}WDI_WlanResumeInfoType; + +/*--------------------------------------------------------------------------- + WDI_ResumeParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_WlanResumeInfoType wdiResumeParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_ResumeParamsType; + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- + * WDI_GTK_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint32 ulFlags; /* optional flags */ + wpt_uint8 aKCK[16]; /* Key confirmation key */ + wpt_uint8 aKEK[16]; /* key encryption key */ + wpt_uint64 ullKeyReplayCounter; /* replay counter */ + wpt_macAddr bssId; +} WDI_GtkOffloadReqParams; + +typedef struct +{ + WDI_GtkOffloadReqParams gtkOffloadReqParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadReqMsg; + +/*--------------------------------------------------------------------------- + * WDI_GTK_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef struct +{ + /* success or failure */ + wpt_uint32 ulStatus; + /*BssIdx of the response */ + wpt_uint8 bssIdx; +} WDI_GtkOffloadRspParams; + +typedef struct +{ + WDI_GtkOffloadRspParams gtkOffloadRspParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadRspMsg; + + +/*--------------------------------------------------------------------------- +* WDI_GTK_OFFLOAD_GETINFO_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + /*BssIdx of the response */ + wpt_macAddr bssId; +} WDI_GtkOffloadGetInfoReqParams; + +typedef struct +{ + + WDI_GtkOffloadGetInfoReqParams WDI_GtkOffloadGetInfoReqParams; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadGetInfoReqMsg; + +/*--------------------------------------------------------------------------- +* WDI_GTK_OFFLOAD_GETINFO_RSP +*--------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 ulStatus; /* success or failure */ + wpt_uint64 ullKeyReplayCounter; /* current replay counter value */ + wpt_uint32 ulTotalRekeyCount; /* total rekey attempts */ + wpt_uint32 ulGTKRekeyCount; /* successful GTK rekeys */ + wpt_uint32 ulIGTKRekeyCount; /* successful iGTK rekeys */ + wpt_macAddr bssId; +} WDI_GtkOffloadGetInfoRspParams; + +typedef struct +{ + WDI_GtkOffloadGetInfoRspParams gtkOffloadGetInfoRspParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadGetInfoRspMsg; +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_SuspendResumeRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; +}WDI_SuspendResumeRspParamsType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI Low Power Heart Beat Config request + Copy from sirApi.h to avoid compile error +---------------------------------------------------------------------------*/ +#define WDI_LPHB_FILTER_LEN 64 + +typedef enum +{ + WDI_LPHB_SET_EN_PARAMS_INDID = 0x0001, + WDI_LPHB_SET_TCP_PARAMS_INDID, + WDI_LPHB_SET_TCP_PKT_FILTER_INDID, + WDI_LPHB_SET_UDP_PARAMS_INDID, + WDI_LPHB_SET_UDP_PKT_FILTER_INDID, + WDI_LPHB_SET_NETWORK_INFO_INDID, +} WDI_LPHBIndType; + +typedef struct +{ + wpt_uint8 enable; + wpt_uint8 item; + wpt_uint8 session; +} WDI_LPHBEnableStruct; + +typedef struct +{ + wpt_uint32 srv_ip; + wpt_uint32 dev_ip; + wpt_uint16 src_port; + wpt_uint16 dst_port; + wpt_uint16 timeout; + wpt_uint8 session; + wpt_uint8 gateway_mac[WDI_MAC_ADDR_LEN]; + wpt_uint16 timePeriodSec; // in seconds + wpt_uint32 tcpSn; +} WDI_LPHBTcpParamStruct; + +typedef struct +{ + wpt_uint16 length; + wpt_uint8 offset; + wpt_uint8 session; + wpt_uint8 filter[WDI_LPHB_FILTER_LEN]; +} WDI_LPHBTcpFilterStruct; + +typedef struct +{ + wpt_uint32 srv_ip; + wpt_uint32 dev_ip; + wpt_uint16 src_port; + wpt_uint16 dst_port; + wpt_uint16 interval; + wpt_uint16 timeout; + wpt_uint8 session; + wpt_uint8 gateway_mac[WDI_MAC_ADDR_LEN]; +} WDI_LPHBUdpParamStruct; + +typedef struct +{ + wpt_uint16 length; + wpt_uint8 offset; + wpt_uint8 session; + wpt_uint8 filter[WDI_LPHB_FILTER_LEN]; +} WDI_LPHBUdpFilterStruct; + +typedef struct +{ + wpt_uint16 cmd; + wpt_uint16 dummy; + union + { + WDI_LPHBEnableStruct lphbEnableReq; + WDI_LPHBTcpParamStruct lphbTcpParamReq; + WDI_LPHBTcpFilterStruct lphbTcpFilterReq; + WDI_LPHBUdpParamStruct lphbUdpParamReq; + WDI_LPHBUdpFilterStruct lphbUdpFilterReq; + } params; +} WDI_LPHBReq; +#endif /* FEATURE_WLAN_LPHB */ + +/*--------------------------------------------------------------------------- + WDI_AuthType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_AUTH_TYPE_ANY = 0, + + WDI_AUTH_TYPE_NONE, + WDI_AUTH_TYPE_OPEN_SYSTEM, + WDI_AUTH_TYPE_SHARED_KEY, + + WDI_AUTH_TYPE_WPA, + WDI_AUTH_TYPE_WPA_PSK, + WDI_AUTH_TYPE_WPA_NONE, + + WDI_AUTH_TYPE_RSN, + WDI_AUTH_TYPE_RSN_PSK, + WDI_AUTH_TYPE_FT_RSN, + WDI_AUTH_TYPE_FT_RSN_PSK, + WDI_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + WDI_AUTH_TYPE_WAPI_WAI_PSK, + WDI_AUTH_TYPE_MAX = 0xFFFFFFFF /*expanding the type to UINT32*/ + +}WDI_AuthType; + +/*--------------------------------------------------------------------------- + WDI_EdType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ED_ANY = 0, + WDI_ED_NONE, + WDI_ED_WEP40, + WDI_ED_WEP104, + WDI_ED_TKIP, + WDI_ED_CCMP, + WDI_ED_WPI, + WDI_ED_AES_128_CMAC, + WDI_ED_MAX = 0xFFFFFFFF /*expanding the type to UINT32*/ +} WDI_EdType; + +#ifdef FEATURE_WLAN_SCAN_PNO + +/*Max number of channels for a given network supported by PNO*/ +#define WDI_PNO_MAX_NETW_CHANNELS 26 + +/*Max number of channels for a given network supported by PNO*/ +#define WDI_PNO_MAX_NETW_CHANNELS_EX 60 + +/*The max number of programable networks for PNO*/ +#define WDI_PNO_MAX_SUPP_NETWORKS 16 + +/*The max number of scan timers programable in Riva*/ +#define WDI_PNO_MAX_SCAN_TIMERS 10 + +#define WDI_PNO_MAX_PROBE_SIZE 450 + +/*--------------------------------------------------------------------------- + WDI_PNOMode +---------------------------------------------------------------------------*/ +typedef enum +{ + /*Network offload is to start immediately*/ + WDI_PNO_MODE_IMMEDIATE, + + /*Network offload is to start on host suspend*/ + WDI_PNO_MODE_ON_SUSPEND, + + /*Network offload is to start on host resume*/ + WDI_PNO_MODE_ON_RESUME, + WDI_PNO_MODE_MAX = 0xFFFFFFFF +} WDI_PNOMode; + +/* SSID broadcast type */ +typedef enum +{ + WDI_BCAST_UNKNOWN = 0, + WDI_BCAST_NORMAL = 1, + WDI_BCAST_HIDDEN = 2, + + WDI_BCAST_TYPE_MAX = 0xFFFFFFFF +} WDI_SSIDBcastType; + +/*--------------------------------------------------------------------------- + WDI_NetworkType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The SSID of the preferred network*/ + WDI_MacSSid ssId; + + /*The authentication method of the preferred network*/ + WDI_AuthType wdiAuth; + + /*The encryption method of the preferred network*/ + WDI_EdType wdiEncryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + WDI_SSIDBcastType wdiBcastNetworkType; + + /*channel count - 0 for all channels*/ + wpt_uint8 ucChannelCount; + + /*the actual channels*/ + wpt_uint8 aChannels[WDI_PNO_MAX_NETW_CHANNELS_EX]; + + /*rssi threshold that a network must meet to be considered, 0 - for any*/ + wpt_uint8 rssiThreshold; +} WDI_NetworkType; + + +/*--------------------------------------------------------------------------- + WDI_ScanTimer +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The timer value*/ + wpt_uint32 uTimerValue; + + /*The amount of time we should be repeating the interval*/ + wpt_uint32 uTimerRepeat; +} WDI_ScanTimer; + +/*--------------------------------------------------------------------------- + WDI_ScanTimersType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The number of value pair intervals present in the array*/ + wpt_uint8 ucScanTimersCount; + + /*The time-repeat value pairs*/ + WDI_ScanTimer aTimerValues[WDI_PNO_MAX_SCAN_TIMERS]; +} WDI_ScanTimersType; + +/*--------------------------------------------------------------------------- + WDI_PNOScanReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enable or disable PNO feature*/ + wpt_uint8 bEnable; + + /*PNO mode requested*/ + WDI_PNOMode wdiModePNO; + + /*Network count*/ + wpt_uint8 ucNetworksCount; + + /*The networks to look for*/ + WDI_NetworkType aNetworks[WDI_PNO_MAX_SUPP_NETWORKS]; + + /*Scan timer intervals*/ + WDI_ScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + wpt_uint16 us24GProbeSize; + wpt_uint8 a24GProbeTemplate[WDI_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + wpt_uint16 us5GProbeSize; + wpt_uint8 a5GProbeTemplate[WDI_PNO_MAX_PROBE_SIZE]; +} WDI_PNOScanReqType; + +/*--------------------------------------------------------------------------- + WDI_PNOScanReqParamsType + PNO info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* PNO Info Type, same as tPrefNetwListParams */ + WDI_PNOScanReqType wdiPNOScanInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_PNOScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetRssiFilterReqParamsType + PNO info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* RSSI Threshold */ + wpt_uint8 rssiThreshold; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_SetRssiFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Is 11d enabled*/ + wpt_uint8 b11dEnabled; + + /*Was UMAc able to find the regulatory domain*/ + wpt_uint8 b11dResolved; + + /*Number of channel allowed in the regulatory domain*/ + wpt_uint8 ucChannelCount; + + /*The actual channels allowed in the regulatory domain*/ + wpt_uint8 aChannels[WDI_PNO_MAX_NETW_CHANNELS_EX]; + + /*Passive min channel time*/ + wpt_uint16 usPassiveMinChTime; + + /*Passive max channel time*/ + wpt_uint16 usPassiveMaxChTime; + + /*Active min channel time*/ + wpt_uint16 usActiveMinChTime; + + /*Active max channel time*/ + wpt_uint16 usActiveMaxChTime; + + /*channel bonding info*/ + wpt_uint8 cbState; +} WDI_UpdateScanParamsInfo; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfoType + UpdateScanParams info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* PNO Info Type, same as tUpdateScanParams */ + WDI_UpdateScanParamsInfo wdiUpdateScanParamsInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_UpdateScanParamsInfoType; +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#define WDI_ROAM_SCAN_MAX_CHANNELS 80 +#define WDI_ROAM_SCAN_MAX_PROBE_SIZE 450 +#define WDI_ROAM_SCAN_RESERVED_BYTES 61 + +typedef struct +{ + /*The SSID of the preferred network*/ + WDI_MacSSid ssId; + wpt_uint8 currAPbssid[WDI_MAC_ADDR_LEN]; + + /*The authentication method of the preferred network*/ + WDI_AuthType authentication; + + /*The encryption method of the preferred network*/ + WDI_EdType encryption; + WDI_EdType mcencryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + //WDI_SSIDBcastType wdiBcastNetworkType; + + /*channel count - 0 for all channels*/ + wpt_uint8 ChannelCount; + + /*the actual channels*/ + wpt_uint8 ChannelCache[WDI_ROAM_SCAN_MAX_CHANNELS]; + +} WDI_RoamNetworkType; + +typedef struct WDIMobilityDomainInfo +{ + wpt_uint8 mdiePresent; + wpt_uint16 mobilityDomain; +} WDI_MobilityDomainInfo; + +/*--------------------------------------------------------------------------- + WDI_RoamOffloadScanInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_boolean RoamScanOffloadEnabled; + wpt_boolean MAWCEnabled; + wpt_uint8 LookupThreshold; + wpt_uint8 RoamRssiDiff; + wpt_uint8 ChannelCacheType; + wpt_uint8 Command; + wpt_uint8 StartScanReason; + wpt_uint16 NeighborScanTimerPeriod; + wpt_uint16 NeighborRoamScanRefreshPeriod; + wpt_uint16 NeighborScanChannelMinTime; + wpt_uint16 NeighborScanChannelMaxTime; + wpt_uint16 EmptyRefreshScanPeriod; + wpt_uint8 ValidChannelCount; + wpt_uint8 ValidChannelList[WDI_ROAM_SCAN_MAX_CHANNELS]; + wpt_boolean IsESEEnabled; + /*Probe template for 2.4GHz band*/ + wpt_uint16 us24GProbeSize; + wpt_uint8 a24GProbeTemplate[WDI_ROAM_SCAN_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + wpt_uint16 us5GProbeSize; + wpt_uint8 a5GProbeTemplate[WDI_ROAM_SCAN_MAX_PROBE_SIZE]; + /*LFR BG Scan will currently look for only one network to which it is initially connected. + * As per requirement, later, the following structure can be used as an array of networks.*/ + WDI_RoamNetworkType ConnectedNetwork; + WDI_MobilityDomainInfo MDID; + wpt_uint8 nProbes; + wpt_uint16 HomeAwayTime; + wpt_uint8 ReservedBytes[WDI_ROAM_SCAN_RESERVED_BYTES]; +} WDI_RoamOffloadScanInfo; + +typedef struct +{ + /* Start Roam Candidate Lookup Offload Back Ground Info Type */ + WDI_RoamOffloadScanInfo wdiRoamOffloadScanInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RoamScanOffloadReqParamsType; +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Ignore DTIM */ + wpt_uint32 uIgnoreDTIM; + + /*DTIM Period*/ + wpt_uint32 uDTIMPeriod; + + /* Listen Interval */ + wpt_uint32 uListenInterval; + + /* Broadcast Multicas Filter */ + wpt_uint32 uBcastMcastFilter; + + /* Beacon Early Termination */ + wpt_uint32 uEnableBET; + + /* Beacon Early Termination Interval */ + wpt_uint32 uBETInterval; + + /* MAX LI for modulated DTIM */ + wpt_uint32 uMaxLIModulatedDTIM; + +} WDI_SetPowerParamsInfo; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfoType + UpdateScanParams info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Power params Info Type, same as tSetPowerParamsReq */ + WDI_SetPowerParamsInfo wdiSetPowerParamsInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetPowerParamsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingConfType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + wpt_uint8 ucTxPerTrackingPeriod; /* Check period, unit is sec. */ + wpt_uint8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. */ + wpt_uint32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +} WDI_TxPerTrackingParamType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingReqParamsType + Tx PER Tracking parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Configurations for Tx PER Tracking */ + WDI_TxPerTrackingParamType wdiTxPerTrackingParam; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTxPerTrackingReqParamsType; + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + Packet Filtering Parameters +---------------------------------------------------------------------------*/ + +#define WDI_IPV4_ADDR_LEN 4 +#define WDI_MAC_ADDR_LEN 6 +#define WDI_MAX_FILTER_TEST_DATA_LEN 8 +#define WDI_MAX_NUM_MULTICAST_ADDRESS 240 +#define WDI_MAX_NUM_FILTERS 20 +#define WDI_MAX_NUM_TESTS_PER_FILTER 10 + +// +// Receive Filter Parameters +// +typedef enum +{ + WDI_RCV_FILTER_TYPE_INVALID, + WDI_RCV_FILTER_TYPE_FILTER_PKT, + WDI_RCV_FILTER_TYPE_BUFFER_PKT, + WDI_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}WDI_ReceivePacketFilterType; + +typedef enum +{ + WDI_FILTER_HDR_TYPE_INVALID, + WDI_FILTER_HDR_TYPE_MAC, + WDI_FILTER_HDR_TYPE_ARP, + WDI_FILTER_HDR_TYPE_IPV4, + WDI_FILTER_HDR_TYPE_IPV6, + WDI_FILTER_HDR_TYPE_UDP, + WDI_FILTER_HDR_TYPE_MAX +}WDI_RcvPktFltProtocolType; + +typedef enum +{ + WDI_FILTER_CMP_TYPE_INVALID, + WDI_FILTER_CMP_TYPE_EQUAL, + WDI_FILTER_CMP_TYPE_MASK_EQUAL, + WDI_FILTER_CMP_TYPE_NOT_EQUAL, + WDI_FILTER_CMP_TYPE_MASK_NOT_EQUAL, + WDI_FILTER_CMP_TYPE_MAX +}WDI_RcvPktFltCmpFlagType; + +typedef struct +{ + WDI_RcvPktFltProtocolType protocolLayer; + WDI_RcvPktFltCmpFlagType cmpFlag; +/* Length of the data to compare */ + wpt_uint16 dataLength; +/* from start of the respective frame header */ + wpt_uint8 dataOffset; + wpt_uint8 reserved; /* Reserved field */ +/* Data to compare */ + wpt_uint8 compareData[WDI_MAX_FILTER_TEST_DATA_LEN]; +/* Mask to be applied on the received packet data before compare */ + wpt_uint8 dataMask[WDI_MAX_FILTER_TEST_DATA_LEN]; +}WDI_RcvPktFilterFieldParams; + +typedef struct +{ + wpt_uint8 filterId; + wpt_uint8 filterType; + wpt_uint32 numFieldParams; + wpt_uint32 coalesceTime; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; + WDI_RcvPktFilterFieldParams paramsData[1]; + +}WDI_RcvPktFilterCfgType; + +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + // Variable length packet filter field params + WDI_RcvPktFilterCfgType wdiPktFilterCfg; +} WDI_SetRcvPktFilterReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Set Receive Filter + */ + wpt_uint8 bssIdx; +} WDI_SetRcvPktFilterRspParamsType; + +// +// Filter Packet Match Count Parameters +// +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /* BSSID of the Match count + */ + wpt_macAddr bssId; +} WDI_RcvFltPktMatchCntReqParamsType; + +typedef struct +{ + wpt_uint8 filterId; + wpt_uint32 matchCnt; +} WDI_RcvFltPktMatchCnt; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; + +} WDI_RcvFltPktMatchCntRspParamsType; + +// +// Receive Filter Clear Parameters +// +typedef struct +{ + wpt_uint32 status; /* only valid for response message */ + wpt_uint8 filterId; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; +}WDI_RcvFltPktClearParam; + +typedef struct +{ + WDI_RcvFltPktClearParam filterClearParam; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RcvFltPktClearReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; + +} WDI_RcvFltPktClearRspParamsType; + +// +// Multicast Address List Parameters +// +typedef struct +{ + wpt_uint32 ulMulticastAddrCnt; + wpt_macAddr multicastAddr[WDI_MAX_NUM_MULTICAST_ADDRESS]; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; +} WDI_RcvFltMcAddrListType; + +typedef struct +{ + WDI_RcvFltMcAddrListType mcAddrList; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RcvFltPktSetMcListReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; +} WDI_RcvFltPktSetMcListRspParamsType; + +#endif // WLAN_FEATURE_PACKET_FILTERING + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*command*/ + wpt_uint32 command; + + /*Arguments*/ + wpt_uint32 argument1; + wpt_uint32 argument2; + wpt_uint32 argument3; + wpt_uint32 argument4; + +}WDI_HALDumpCmdReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*NV Blob Info*/ + WDI_HALDumpCmdReqInfoType wdiHALDumpCmdInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_HALDumpCmdReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /* length of the buffer */ + wpt_uint16 usBufferLen; + + /* Buffer */ + wpt_uint8 *pBuffer; +}WDI_HALDumpCmdRspParamsType; + + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 tmMode; + wpt_uint16 tmLevel; + void* pUserData; +}WDI_SetTmLevelReqType; + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelRspType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_Status wdiStatus; + void* pUserData; +}WDI_SetTmLevelRspType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI_LPHBConfigParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + void* pLphsConfIndData; +}WDI_LPHBConfigParamsType; +#endif /* FEATURE_WLAN_LPHB */ + +/*--------------------------------------------------------------------------- + WDI_AddPeriodicTxPtrnInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* MAC Address for the adapter */ + wpt_macAddr macAddr; + + wpt_uint8 ucPtrnId; // Pattern ID + wpt_uint16 ucPtrnSize; // Pattern size + wpt_uint32 usPtrnIntervalMs; // In msec + wpt_uint8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} WDI_AddPeriodicTxPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelPeriodicTxPtrnInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* MAC Address for the adapter */ + wpt_macAddr macAddr; + + /* Bitmap of pattern IDs that needs to be deleted */ + wpt_uint32 ucPatternIdBitmap; +} WDI_DelPeriodicTxPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_AddPeriodicTxPtrnParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_AddPeriodicTxPtrnInfoType wdiAddPeriodicTxPtrnParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_AddPeriodicTxPtrnParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelPeriodicTxPtrnParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_DelPeriodicTxPtrnInfoType wdiDelPeriodicTxPtrnParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_DelPeriodicTxPtrnParamsType; + + +/*---------------------------------------------------------------------------- + * WDI callback types + *--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start response from + the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StartRspCb)(WDI_StartRspParamsType* pwdiRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Stop response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StopRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received an Init Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_InitScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a StartScan response + from the underlying device. + + PARAMETERS + + IN + wdiParams: response params received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StartScanRspCb)(WDI_StartScanRspParamsType* wdiParams, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a End Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EndScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Finish Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FinishScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Join response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_JoinRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Config BSS response + from the underlying device. + + PARAMETERS + + IN + wdiConfigBSSRsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigBSSRspCb)( + WDI_ConfigBSSRspParamsType* pwdiConfigBSSRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del BSS response from + the underlying device. + + PARAMETERS + + IN + wdiDelBSSRsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelBSSRspCb)(WDI_DelBSSRspParamsType* pwdiDelBSSRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Post Assoc response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_PostAssocRspCb)( + WDI_PostAssocRspParamsType* pwdiPostAssocRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del STA response from + the underlying device. + + PARAMETERS + + IN + wdiDelSTARsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelSTARspCb)(WDI_DelSTARspParamsType* pwdiDelSTARsp, + void* pUserData); + + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set BSS Key response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBSSKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Remove BSS Key + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemoveBSSKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set STA Key response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetSTAKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Remove STA Key + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemoveSTAKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +#ifdef FEATURE_WLAN_ESE +/*--------------------------------------------------------------------------- + WDI_TsmRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a TSM Stats response from the underlying device. + + PARAMETERS + + IN + pTSMStats: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_TsmRspCb)(WDI_TSMStatsRspParamsType *pTSMStats, + void* pUserData); +#endif + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add TS response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddTsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del TS response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelTsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received an Update EDCA Params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateEDCAParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add BA response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddBASessionRspCb)( + WDI_AddBASessionRspParamsType* wdiAddBASessionRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del BA response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelBARspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Switch Ch response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SwitchChRspCb)(WDI_SwitchCHRspParamsType* pwdiSwitchChRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Config STA response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigSTARspCb)( + WDI_ConfigSTARspParamsType* pwdiConfigSTARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set Link State + response from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetLinkStateRspCb)( WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Get Stats response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GetStatsRspCb)(WDI_GetStatsRspParamsType* pwdiGetStatsRsp, + void* pUserData); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Get Roam Rssi response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GetRoamRssiRspCb)(WDI_GetRoamRssiRspParamsType* pwdiGetRoamRssiRsp, + void* pUserData); +#endif + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Cfg response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateCfgRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_AddBARspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a ADD BA response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddBARspCb)(WDI_AddBARspinfoType* wdiAddBARsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a ADD BA response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_TriggerBARspCb)(WDI_TriggerBARspParamsType* wdiTriggerBARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Beacon Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateBeaconParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Send Beacon Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SendBeaconParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetMaxTxPowerRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set max Tx Power response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetMaxTxPowerRspCb)(WDI_SetMaxTxPowerRspMsg *wdiSetMaxTxPowerRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetMaxTxPowerPerBandRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a + set max Tx Power Per Band response from the underlying device. + + PARAMETERS + + IN + wdiSetMaxTxPowerPerBandRsp: response status received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetMaxTxPowerPerBandRspCb)(WDI_SetMaxTxPowerPerBandRspMsg + *wdiSetMaxTxPowerPerBandRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetTxPowerRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set max Tx Power response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetTxPowerRspCb)(WDI_SetTxPowerRspMsg *wdiSetTxPowerRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspTemplateRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Probe RSP Template + Update response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateProbeRspTemplateRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetP2PGONOAReqParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a P2P GO NOA Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetP2PGONOAReqParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetTDLSLinkEstablishReqParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a TDLS Link Establish Req response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTDLSLinkEstablishReqParamsRspCb)(WDI_SetTdlsLinkEstablishReqResp * + wdiSetTdlsLinkEstablishReqRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetPwrSaveCfgCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set Power Save CFG + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetPwrSaveCfgCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetUapsdAcParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set UAPSD params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetUapsdAcParamsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterImpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Enter IMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterImpsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitImpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Exit IMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitImpsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a enter BMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterBmpsRspCb)(WDI_EnterBmpsRspParamsType *pwdiEnterBmpsRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a exit BMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitBmpsRspCb)( WDI_ExitBmpsRspParamsType *pwdiExitBmpsRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a enter UAPSD response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterUapsdRspCb)( WDI_EnterUapsdRspParamsType *pwdiEnterUapsdRspParam, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a exit UAPSD response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitUapsdRspCb)(WDI_ExitUapsdRspParamsType *pwidExitUapsdRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a update UAPSD params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateUapsdParamsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ConfigureRxpFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a config RXP filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigureRxpFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetBeaconFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set beacon filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBeaconFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a remove beacon filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemBeaconFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetRSSIThresholdsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set RSSI thresholds + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetRSSIThresholdsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_HostOffloadCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a host offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HostOffloadCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_KeepAliveCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Keep Alive + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_KeepAliveCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl add Bcast ptrn + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlAddBcPtrnCb)( WDI_WowlAddBcPtrnRspParamsType *pwdiWowlAddBcPtrnParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl delete Bcast ptrn + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlDelBcPtrnCb)( WDI_WowlDelBcPtrnRspParamsType *pwdiWowlDelBcstPtrRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlEnterReqCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl enter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlEnterReqCb)( WDI_WowlEnterRspParamsType *pwdiwowlEnterRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlExitReqCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl exit + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlExitReqCb)( WDI_WowlExitRspParamsType *pwdiWowlExitRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ConfigureAppsCpuWakeupStateCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a config Apps Cpu Wakeup + State response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigureAppsCpuWakeupStateCb)(WDI_Status wdiStatus, + void* pUserData); +/*--------------------------------------------------------------------------- + WDI_NvDownloadRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a NV Download response + from the underlying device. + + PARAMETERS + + IN + wdiStatus:response status received from HAL + pUserData:user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_NvDownloadRspCb)(WDI_NvDownloadRspInfoType* wdiNvDownloadRsp, + void* pUserData); +/*--------------------------------------------------------------------------- + WDI_FlushAcRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Flush AC response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FlushAcRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Bt AMP event response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_BtAmpEventRspCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/*--------------------------------------------------------------------------- + WDI_oemDataRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start oem data response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_oemDataRspCb)(WDI_oemDataRspParamsType* wdiOemDataRspParams, + void* pUserData); + +#endif + +/*--------------------------------------------------------------------------- + WDI_HostResumeEventRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Bt AMP event response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HostResumeEventRspCb)( + WDI_SuspendResumeRspParamsType *resumeRspParams, + void* pUserData); + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*--------------------------------------------------------------------------- + WDI_AggrAddTsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Aggregated Add TS + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AggrAddTsRspCb)(WDI_Status wdiStatus, + void* pUserData); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/*--------------------------------------------------------------------------- + WDI_FTMCommandRspCb + + DESCRIPTION + + FTM Command response CB + + PARAMETERS + + IN + ftmCMDRspdata: FTM response data from HAL + pUserData: user data + + + RETURN VALUE + NONE +---------------------------------------------------------------------------*/ +typedef void (*WDI_FTMCommandRspCb)(void *ftmCMDRspdata, + void *pUserData); + +/*--------------------------------------------------------------------------- + WDI_AddSTASelfParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add Sta Self Params + response from the underlying device. + + PARAMETERS + + IN + wdiAddSelfSTARsp: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddSTASelfParamsRspCb)( + WDI_AddSTASelfRspParamsType* pwdiAddSelfSTARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a host offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelSTASelfRspCb) +( +WDI_DelSTASelfRspParamsType* wdiDelStaSelfRspParams, +void* pUserData +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/*--------------------------------------------------------------------------- + WDI_PNOScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set PNO + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_PNOScanCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_PNOScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set PNO + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RssiFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Scan Params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateScanParamsCb)(WDI_Status wdiStatus, + void* pUserData); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*--------------------------------------------------------------------------- + WDI_RoamOffloadScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start Roam Candidate Lookup Req + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RoamOffloadScanCb)(WDI_Status wdiStatus, + void* pUserData); + +#endif +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Tx PER Tracking + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTxPerTrackingRspCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + WDI_8023MulticastListCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a 8023 Multicast List + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_8023MulticastListCb)( + WDI_RcvFltPktSetMcListRspParamsType *pwdiRcvFltPktSetMcListRspInfo, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ReceiveFilterSetFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Receive Filter Set Filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReceiveFilterSetFilterCb)( + WDI_SetRcvPktFilterRspParamsType *pwdiSetRcvPktFilterRspInfo, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_FilterMatchCountCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Do PC Filter Match Count + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FilterMatchCountCb)( + WDI_RcvFltPktMatchCntRspParamsType *pwdiRcvFltPktMatchRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ReceiveFilterClearFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Receive Filter Clear Filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReceiveFilterClearFilterCb)( + WDI_RcvFltPktClearRspParamsType *pwdiRcvFltPktClearRspParamsType, + void* pUserData); +#endif // WLAN_FEATURE_PACKET_FILTERING + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a HAL DUMP Command +response from + the HAL layer. + + PARAMETERS + + IN + wdiHalDumpCmdRsp: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HALDumpCmdRspCb)(WDI_HALDumpCmdRspParamsType* wdiHalDumpCmdRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetPowerParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set Power Param + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetPowerParamsCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- + WDI_GtkOffloadCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a GTK offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GtkOffloadCb)( WDI_GtkOffloadRspParams *pwdiGtkOffloadRsparams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_GtkOffloadGetInfoCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a GTK offload + information response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GtkOffloadGetInfoCb)( WDI_GtkOffloadGetInfoRspParams *pwdiGtkOffloadGetInfoRsparams, + void* pUserData); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set New TM Level + done response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTmLevelCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_featureCapsExchangeCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a HAL Feature Capbility + Exchange Response the HAL layer. This callback is put to mantain code + similarity and is not being used right now. + + PARAMETERS + + IN + wdiFeatCapRspParams: response parameters received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_featureCapsExchangeCb)(void* wdiFeatCapRspParams, + void* pUserData); + +#ifdef WLAN_FEATURE_11AC +typedef void (*WDI_UpdateVHTOpModeCb)(WDI_Status wdiStatus, + void* pUserData); +#endif + +#ifdef FEATURE_WLAN_LPHB +typedef void (*WDI_LphbCfgCb)(WDI_Status wdiStatus, + void* pUserData); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*--------------------------------------------------------------------------- + WDI_SetBatchScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a get batch scan + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBatchScanCb)(void *pData, WDI_SetBatchScanRspType *pRsp); + +#endif + + + +/*======================================================================== + * Function Declarations and Documentation + ==========================================================================*/ + +/*======================================================================== + + INITIALIZATION APIs + +==========================================================================*/ + +/** + @brief WDI_Init is used to initialize the DAL. + + DAL will allocate all the resources it needs. It will open PAL, it will also + open both the data and the control transport which in their turn will open + DXE/SMD or any other drivers that they need. + + @param pOSContext: pointer to the OS context provided by the UMAC + will be passed on to PAL on Open + ppWDIGlobalCtx: output pointer of Global Context + pWdiDevCapability: output pointer of device capability + + @return Result of the function call +*/ +WDI_Status +WDI_Init +( + void* pOSContext, + void** ppWDIGlobalCtx, + WDI_DeviceCapabilityType* pWdiDevCapability, + unsigned int driverType +); + +/** + @brief WDI_Start will be called when the upper MAC is ready to + commence operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Start + message to the lower RIVA sub-system if the SMD channel + has been fully opened and the RIVA subsystem is up. + + If the RIVA sub-system is not yet up and running DAL + will queue the request for Open and will wait for the + SMD notification before attempting to send down the + message to HAL. + + WDI_Init must have been called. + + @param wdiStartParams: the start parameters as specified by + the Device Interface + + wdiStartRspCb: callback for passing back the response of + the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Start +( + WDI_StartReqParamsType* pwdiStartParams, + WDI_StartRspCb wdiStartRspCb, + void* pUserData +); + + +/** + @brief WDI_Stop will be called when the upper MAC is ready to + stop any operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Stop + message to the lower RIVA sub-system if the DAL Core is + in started state. + + In state BUSY this request will be queued. + + Request will not be accepted in any other state. + + WDI_Start must have been called. + + @param wdiStopParams: the stop parameters as specified by + the Device Interface + + wdiStopRspCb: callback for passing back the response of + the stop operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Stop +( + WDI_StopReqParamsType* pwdiStopParams, + WDI_StopRspCb wdiStopRspCb, + void* pUserData +); + +/** + @brief WDI_Close will be called when the upper MAC no longer + needs to interract with DAL. DAL will free its control + block. + + It is only accepted in state STOPPED. + + WDI_Stop must have been called. + + @param none + + @see WDI_Stop + @return Result of the function call +*/ +WDI_Status +WDI_Close +( + void +); + + +/** + @brief WDI_Shutdown will be called during 'SSR shutdown' operation. + This will do most of the WDI stop & close + operations without doing any handshake with Riva + + This will also make sure that the control transport + will NOT be closed. + + This request will not be queued. + + + WDI_Start must have been called. + + @param closeTransport: Close control channel if this is set + + @return Result of the function call +*/ +WDI_Status +WDI_Shutdown +( + wpt_boolean closeTransport +); + +/*======================================================================== + + SCAN APIs + +==========================================================================*/ + +/** + @brief WDI_InitScanReq will be called when the upper MAC wants + the WLAN Device to get ready for a scan procedure. Upon + the call of this API the WLAN DAL will pack and send a + HAL Init Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiInitScanParams: the init scan parameters as specified + by the Device Interface + + wdiInitScanRspCb: callback for passing back the response + of the init scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_InitScanReq +( + WDI_InitScanReqParamsType* pwdiInitScanParams, + WDI_InitScanRspCb wdiInitScanRspCb, + void* pUserData +); + +/** + @brief WDI_StartScanReq will be called when the upper MAC + wishes to change the Scan channel on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiStartScanParams: the start scan parameters as + specified by the Device Interface + + wdiStartScanRspCb: callback for passing back the + response of the start scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_StartScanReq +( + WDI_StartScanReqParamsType* pwdiStartScanParams, + WDI_StartScanRspCb wdiStartScanRspCb, + void* pUserData +); + + +/** + @brief WDI_EndScanReq will be called when the upper MAC is + wants to end scanning for a particular channel that it + had set before by calling Scan Start on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL End Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_StartScanReq must have been called. + + @param wdiEndScanParams: the end scan parameters as specified + by the Device Interface + + wdiEndScanRspCb: callback for passing back the response + of the end scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_StartScanReq + @return Result of the function call +*/ +WDI_Status +WDI_EndScanReq +( + WDI_EndScanReqParamsType* pwdiEndScanParams, + WDI_EndScanRspCb wdiEndScanRspCb, + void* pUserData +); + + +/** + @brief WDI_FinishScanReq will be called when the upper MAC has + completed the scan process on the WLAN Device. Upon the + call of this API the WLAN DAL will pack and send a HAL + Finish Scan Request request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiFinishScanParams: the finish scan parameters as + specified by the Device Interface + + wdiFinishScanRspCb: callback for passing back the + response of the finish scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_FinishScanReq +( + WDI_FinishScanReqParamsType* pwdiFinishScanParams, + WDI_FinishScanRspCb wdiFinishScanRspCb, + void* pUserData +); + +/*======================================================================== + + ASSOCIATION APIs + +==========================================================================*/ + +/** + @brief WDI_JoinReq will be called when the upper MAC is ready + to start an association procedure to a BSS. Upon the + call of this API the WLAN DAL will pack and send a HAL + Join request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiJoinParams: the join parameters as specified by + the Device Interface + + wdiJoinRspCb: callback for passing back the response of + the join operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_JoinReq +( + WDI_JoinReqParamsType* pwdiJoinParams, + WDI_JoinRspCb wdiJoinRspCb, + void* pUserData +); + +/** + @brief WDI_ConfigBSSReq will be called when the upper MAC + wishes to configure the newly acquired or in process of + being acquired BSS to the HW . Upon the call of this API + the WLAN DAL will pack and send a HAL Config BSS request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiConfigBSSParams: the config BSS parameters as + specified by the Device Interface + + wdiConfigBSSRspCb: callback for passing back the + response of the config BSS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_ConfigBSSReq +( + WDI_ConfigBSSReqParamsType* pwdiConfigBSSParams, + WDI_ConfigBSSRspCb wdiConfigBSSRspCb, + void* pUserData +); + +/** + @brief WDI_DelBSSReq will be called when the upper MAC is + dissasociating from the BSS and wishes to notify HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Del BSS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq or WDI_PostAssocReq must have been called. + + @param wdiDelBSSParams: the del BSS parameters as specified by + the Device Interface + + wdiDelBSSRspCb: callback for passing back the response + of the del bss operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq, WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBSSReq +( + WDI_DelBSSReqParamsType* pwdiDelBSSParams, + WDI_DelBSSRspCb wdiDelBSSRspCb, + void* pUserData +); + +/** + @brief WDI_PostAssocReq will be called when the upper MAC has + associated to a BSS and wishes to configure HW for + associated state. Upon the call of this API the WLAN DAL + will pack and send a HAL Post Assoc request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiPostAssocReqParams: the assoc parameters as specified + by the Device Interface + + wdiPostAssocRspCb: callback for passing back the + response of the post assoc operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_PostAssocReq +( + WDI_PostAssocReqParamsType* pwdiPostAssocReqParams, + WDI_PostAssocRspCb wdiPostAssocRspCb, + void* pUserData +); + +/** + @brief WDI_DelSTAReq will be called when the upper MAC when an + association with another STA has ended and the station + must be deleted from HW. Upon the call of this API the + WLAN DAL will pack and send a HAL Del STA request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiDelSTAParams: the Del STA parameters as specified by + the Device Interface + + wdiDelSTARspCb: callback for passing back the response + of the del STA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTAReq +( + WDI_DelSTAReqParamsType* pwdiDelSTAParams, + WDI_DelSTARspCb wdiDelSTARspCb, + void* pUserData +); + +/*======================================================================== + + SECURITY APIs + +==========================================================================*/ + +/** + @brief WDI_SetBSSKeyReq will be called when the upper MAC ito + install a BSS encryption key on the HW. Upon the call of + this API the WLAN DAL will pack and send a HAL Start + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetBSSKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetBSSKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetBSSKeyReq +( + WDI_SetBSSKeyReqParamsType* pwdiSetBSSKeyParams, + WDI_SetBSSKeyRspCb wdiSetBSSKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveBSSKeyReq will be called when the upper MAC to + uninstall a BSS key from HW. Upon the call of this API + the WLAN DAL will pack and send a HAL Remove BSS Key + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetBSSKeyReq must have been called. + + @param wdiRemoveBSSKeyParams: the remove BSS key parameters as + specified by the Device Interface + + wdiRemoveBSSKeyRspCb: callback for passing back the + response of the remove BSS key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetBSSKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveBSSKeyReq +( + WDI_RemoveBSSKeyReqParamsType* pwdiRemoveBSSKeyParams, + WDI_RemoveBSSKeyRspCb wdiRemoveBSSKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_SetSTAKeyReq will be called when the upper MAC is + ready to install a STA(ast) encryption key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Set STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetSTAKeyParams: the set STA key parameters as + specified by the Device Interface + + wdiSetSTAKeyRspCb: callback for passing back the + response of the set STA key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTAKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveSTAKeyReq will be called when the upper MAC + wants to unistall a previously set STA key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Remove STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTAKeyReq must have been called. + + @param wdiRemoveSTAKeyParams: the remove STA key parameters as + specified by the Device Interface + + wdiRemoveSTAKeyRspCb: callback for passing back the + response of the remove STA key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTAKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTAKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTAKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb, + void* pUserData +); + +/** + @brief WDI_SetSTABcastKeyReq will be called when the upper MAC + wants to install a STA Bcast encryption key on the HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiSetSTABcastKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetSTABcastKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTABcastKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTABcastKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTABcastKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveSTABcastKeyReq will be called when the upper + MAC to uninstall a STA Bcast key from HW. Upon the call + of this API the WLAN DAL will pack and send a HAL Remove + STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTABcastKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTABcastKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTABcastKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTABcastKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_SetTxPowerReq will be called when the upper + MAC wants to set Tx Power to HW. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiSetTxPowerParams: set TS Power parameters + BSSID and target TX Power with dbm included + + wdiReqStatusCb: callback for passing back the response + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPowerReq +( + WDI_SetTxPowerParamsType* pwdiSetTxPowerParams, + WDA_SetTxPowerRspCb wdiReqStatusCb, + void* pUserData +); + +/** + @brief WDI_SetMaxTxPowerReq will be called when the upper + MAC wants to set Max Tx Power to HW. Upon the + call of this API the WLAN DAL will pack and send a HAL + Remove STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerReq +( + WDI_SetMaxTxPowerParamsType* pwdiSetMaxTxPowerParams, + WDA_SetMaxTxPowerRspCb wdiReqStatusCb, + void* pUserData +); + +/** + @brief WDI_SetMaxTxPowerPerBandReq will be called when the upper + MAC wants to set Max Tx Power to HW for specific band. Upon the + call of this API the WLAN DAL will pack and send a HAL + Set Max Tx Power Per Band request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param WDI_SetMaxTxPowerPerBandParamsType: Max Tx Per Band Info + + WDA_SetMaxTxPowerPerBandRspCb: This callback is invoked by DAL + when it has received a set max Tx Power Per Band response from + the underlying device. + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerPerBandReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerPerBandReq +( + WDI_SetMaxTxPowerPerBandParamsType* pwdiSetMaxTxPowerPerBandParams, + WDA_SetMaxTxPowerPerBandRspCb wdiReqStatusCb, + void* pUserData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief WDI_TSMStatsReq will be called by the upper MAC to fetch + Traffic Stream metrics. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_TSMStatsReq +( + WDI_TSMStatsReqParamsType* pwdiTsmStatsReqParams, + WDI_TsmRspCb wdiTsmStatsRspCb, + void* pUserData +); + + +#endif + +/*======================================================================== + + QoS and BA APIs + +==========================================================================*/ + +/** + @brief WDI_AddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddTSReq +( + WDI_AddTSReqParamsType* pwdiAddTsReqParams, + WDI_AddTsRspCb wdiAddTsRspCb, + void* pUserData +); + + + +/** + @brief WDI_DelTSReq will be called when the upper MAC has ended + admission on a specific AC. This is to inform HW that + QoS traffic parameters must be rest. Upon the call of + this API the WLAN DAL will pack and send a HAL Del TS + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddTSReq must have been called. + + @param wdiDelTsReqParams: the del TS parameters as specified by + the Device Interface + + wdiDelTsRspCb: callback for passing back the response of + the del TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddTSReq + @return Result of the function call +*/ +WDI_Status +WDI_DelTSReq +( + WDI_DelTSReqParamsType* pwdiDelTsReqParams, + WDI_DelTsRspCb wdiDelTsRspCb, + void* pUserData +); + + + +/** + @brief WDI_UpdateEDCAParams will be called when the upper MAC + wishes to update the EDCA parameters used by HW for QoS + data traffic. Upon the call of this API the WLAN DAL + will pack and send a HAL Update EDCA Params request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiUpdateEDCAParams: the start parameters as specified + by the Device Interface + + wdiUpdateEDCAParamsRspCb: callback for passing back the + response of the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateEDCAParams +( + WDI_UpdateEDCAParamsType* pwdiUpdateEDCAParams, + WDI_UpdateEDCAParamsRspCb wdiUpdateEDCAParamsRspCb, + void* pUserData +); + + + +/** + @brief WDI_AddBASessionReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBASessionReq +( + WDI_AddBASessionReqParamsType* pwdiAddBASessionReqParams, + WDI_AddBASessionRspCb wdiAddBASessionRspCb, + void* pUserData +); + + +/** + @brief WDI_DelBAReq will be called when the upper MAC wants to + inform HW that it has deleted a previously created BA + session. Upon the call of this API the WLAN DAL will + pack and send a HAL Del BA request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddBAReq must have been called. + + @param wdiDelBAReqParams: the del BA parameters as specified by + the Device Interface + + wdiDelBARspCb: callback for passing back the response of + the del BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBAReq +( + WDI_DelBAReqParamsType* pwdiDelBAReqParams, + WDI_DelBARspCb wdiDelBARspCb, + void* pUserData +); + +/** + @brief WDI_UpdateBeaconParamsReq will be called when the upper MAC wants to + inform HW that there is a change in the beacon parameters + Upon the call of this API the WLAN DAL will + pack and send a UpdateBeacon Params message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_UpdateBeaconParamsReq must have been called. + + @param WDI_UpdateBeaconParamsType: the Update Beacon parameters as specified by + the Device Interface + + WDI_UpdateBeaconParamsRspCb: callback for passing back the response of + the Update Beacon Params operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_UpdateBeaconParamsReq +( + WDI_UpdateBeaconParamsType * pwdiUpdateBeaconParams, + WDI_UpdateBeaconParamsRspCb wdiUpdateBeaconParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_SendBeaconParamsReq will be called when the upper MAC wants to + update the beacon template to be transmitted as BT MAP STA/IBSS/Soft AP + Upon the call of this API the WLAN DAL will + pack and send the beacon Template message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SendBeaconParamsReq must have been called. + + @param WDI_SendBeaconParamsType: the Update Beacon parameters as specified by + the Device Interface + + WDI_SendBeaconParamsRspCb: callback for passing back the response of + the Send Beacon Params operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_SendBeaconParamsReq +( + WDI_SendBeaconParamsType* pwdiSendBeaconParams, + WDI_SendBeaconParamsRspCb wdiSendBeaconParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_UpdateProbeRspTemplateReq will be called when the + upper MAC wants to update the probe response template to + be transmitted as Soft AP + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_UpdateProbeRspTemplateReq +( + WDI_UpdateProbeRspTemplateParamsType* pwdiUpdateProbeRspParams, + WDI_UpdateProbeRspTemplateRspCb wdiSendBeaconParamsRspCb, + void* pUserData +); + +/** + @brief WDI_SetP2PGONOAReq will be called when the + upper MAC wants to send Notice of Absence + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_SetP2PGONOAReq +( + WDI_SetP2PGONOAReqParamsType* pwdiP2PGONOAReqParams, + WDI_SetP2PGONOAReqParamsRspCb wdiP2PGONOAReqParamsRspCb, + void* pUserData +); + +/** + @brief WDI_SetTDLSLinkEstablishReq will be called when the + upper MAC wants to send TDLS Link Establish Request Parameters + Upon the call of this API the WLAN DAL will + pack and send the TDLS Link Establish Request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiTDLSLinkEstablishReqParams: TDLS Peer Parameters + for Link Establishment (Used for PUAPSD , TDLS Off Channel ...) + + wdiTDLSLinkEstablishReqRspCb: callback for passing back the + response of the TDLS Link Establish request received + from the device + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SetTDLSLinkEstablishReq +( + WDI_SetTDLSLinkEstablishReqParamsType* pwdiTDLSLinkEstablishReqParams, + WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqRspCb, + void* pUserData +); + +/*======================================================================== + + Power Save APIs + +==========================================================================*/ + +/** + @brief WDI_SetPwrSaveCfgReq will be called when the upper MAC + wants to set the power save related configurations of + the WLAN Device. Upon the call of this API the WLAN DAL + will pack and send a HAL Update CFG request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param pwdiPowerSaveCfg: the power save cfg parameters as + specified by the Device Interface + + wdiSetPwrSaveCfgCb: callback for passing back the + response of the set power save cfg operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SetPwrSaveCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiPowerSaveCfg, + WDI_SetPwrSaveCfgCb wdiSetPwrSaveCfgCb, + void* pUserData +); + +/** + @brief WDI_EnterImpsReq will be called when the upper MAC to + request the device to get into IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Enter + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiEnterImpsRspCb: callback for passing back the + response of the Enter IMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_EnterImpsReq +( + WDI_EnterImpsRspCb wdiEnterImpsRspCb, + void* pUserData +); + +/** + @brief WDI_ExitImpsReq will be called when the upper MAC to + request the device to get out of IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + + @param wdiExitImpsRspCb: callback for passing back the response + of the Exit IMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ExitImpsReq +( + WDI_ExitImpsRspCb wdiExitImpsRspCb, + void* pUserData +); + +/** + @brief WDI_EnterBmpsReq will be called when the upper MAC to + request the device to get into BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiEnterBmpsReqParams: the Enter BMPS parameters as + specified by the Device Interface + + wdiEnterBmpsRspCb: callback for passing back the + response of the Enter BMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterBmpsReq +( + WDI_EnterBmpsReqParamsType *pwdiEnterBmpsReqParams, + WDI_EnterBmpsRspCb wdiEnterBmpsRspCb, + void* pUserData +); + +/** + @brief WDI_ExitBmpsReq will be called when the upper MAC to + request the device to get out of BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Exit BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiExitBmpsReqParams: the Exit BMPS parameters as + specified by the Device Interface + + wdiExitBmpsRspCb: callback for passing back the response + of the Exit BMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitBmpsReq +( + WDI_ExitBmpsReqParamsType *pwdiExitBmpsReqParams, + WDI_ExitBmpsRspCb wdiExitBmpsRspCb, + void* pUserData +); + +/** + @brief WDI_EnterUapsdReq will be called when the upper MAC to + request the device to get into UAPSD power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter UAPSD request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + WDI_SetUapsdAcParamsReq must have been called. + + @param pwdiEnterUapsdReqParams: the Enter UAPSD parameters as + specified by the Device Interface + + wdiEnterUapsdRspCb: callback for passing back the + response of the Enter UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq, WDI_SetUapsdAcParamsReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterUapsdReq +( + WDI_EnterUapsdReqParamsType *pwdiEnterUapsdReqParams, + WDI_EnterUapsdRspCb wdiEnterUapsdRspCb, + void* pUserData +); + +/** + @brief WDI_ExitUapsdReq will be called when the upper MAC to + request the device to get out of UAPSD power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + UAPSD request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiExitUapsdRspCb: callback for passing back the + response of the Exit UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitUapsdReq +( + WDI_ExitUapsdReqParamsType *pwdiExitUapsdReqParams, + WDI_ExitUapsdRspCb wdiExitUapsdRspCb, + void* pUserData +); + +/** + @brief WDI_UpdateUapsdParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations + of an associated STA (while acting as an AP) to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq must have been called. + + @param pwdiUpdateUapsdReqParams: the UAPSD parameters + as specified by the Device Interface + + wdiUpdateUapsdParamsCb: callback for passing back the + response of the update UAPSD params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateUapsdParamsReq +( + WDI_UpdateUapsdReqParamsType *pwdiUpdateUapsdReqParams, + WDI_UpdateUapsdParamsCb wdiUpdateUapsdParamsCb, + void* pUserData +); + +/** + @brief WDI_SetUapsdAcParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations before + requesting for enter UAPSD power state to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Set UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetUapsdAcParamsReq +( + WDI_SetUapsdAcParamsReqParamsType* pwdiPowerSaveCfg, + WDI_SetUapsdAcParamsCb wdiSetUapsdAcParamsCb, + void* pUserData +); + +/** + @brief WDI_ConfigureRxpFilterReq will be called when the upper + MAC wants to set/reset the RXP filters for received pkts + (MC, BC etc.). Upon the call of this API the WLAN DAL will pack + and send a HAL configure RXP filter request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureRxpFilterReqParams: the RXP + filter as specified by the Device + Interface + + wdiConfigureRxpFilterCb: callback for passing back the + response of the configure RXP filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureRxpFilterReq +( + WDI_ConfigureRxpFilterReqParamsType *pwdiConfigureRxpFilterReqParams, + WDI_ConfigureRxpFilterCb wdiConfigureRxpFilterCb, + void* pUserData +); + +/** + @brief WDI_SetBeaconFilterReq will be called when the upper MAC + wants to set the beacon filters while in power save. + Upon the call of this API the WLAN DAL will pack and + send a Beacon filter request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the set beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetBeaconFilterReq +( + WDI_BeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_SetBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +); + +/** + @brief WDI_RemBeaconFilterReq will be called when the upper MAC + wants to remove the beacon filter for perticular IE + while in power save. Upon the call of this API the WLAN + DAL will pack and send a remove Beacon filter request + message to the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the remove beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_RemBeaconFilterReq +( + WDI_RemBeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_RemBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +); + +/** + @brief WDI_SetRSSIThresholdsReq will be called when the upper + MAC wants to set the RSSI thresholds related + configurations while in power save. Upon the call of + this API the WLAN DAL will pack and send a HAL Set RSSI + thresholds request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetRSSIThresholdsReq +( + WDI_SetRSSIThresholdsReqParamsType* pwdiRSSIThresholdsParams, + WDI_SetRSSIThresholdsCb wdiSetRSSIThresholdsCb, + void* pUserData +); + +/** + @brief WDI_HostOffloadReq will be called when the upper MAC + wants to set the filter to minimize unnecessary host + wakeup due to broadcast traffic while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL host offload request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiHostOffloadParams: the host offload as specified + by the Device Interface + + wdiHostOffloadCb: callback for passing back the response + of the host offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_HostOffloadReq +( + WDI_HostOffloadReqParamsType* pwdiHostOffloadParams, + WDI_HostOffloadCb wdiHostOffloadCb, + void* pUserData +); + +/** + @brief WDI_KeepAliveReq will be called when the upper MAC + wants to set the filter to send NULL or unsolicited ARP responses + and minimize unnecessary host wakeups due to while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL Keep Alive request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiKeepAliveParams: the Keep Alive as specified + by the Device Interface + + wdiKeepAliveCb: callback for passing back the response + of the Keep Alive operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_KeepAliveReq +( + WDI_KeepAliveReqParamsType* pwdiKeepAliveParams, + WDI_KeepAliveCb wdiKeepAliveCb, + void* pUserData +); + +/** + @brief WDI_WowlAddBcPtrnReq will be called when the upper MAC + wants to set the Wowl Bcast ptrn to minimize unnecessary + host wakeup due to broadcast traffic while in power + save. Upon the call of this API the WLAN DAL will pack + and send a HAL Wowl Bcast ptrn request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlAddBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlAddBcPtrnCb: callback for passing back the + response of the add Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlAddBcPtrnReq +( + WDI_WowlAddBcPtrnReqParamsType* pwdiWowlAddBcPtrnParams, + WDI_WowlAddBcPtrnCb wdiWowlAddBcPtrnCb, + void* pUserData +); + +/** + @brief WDI_WowlDelBcPtrnReq will be called when the upper MAC + wants to clear the Wowl Bcast ptrn. Upon the call of + this API the WLAN DAL will pack and send a HAL delete + Wowl Bcast ptrn request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlAddBcPtrnReq must have been called. + + @param pwdiWowlDelBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlDelBcPtrnCb: callback for passing back the + response of the del Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlAddBcPtrnReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlDelBcPtrnReq +( + WDI_WowlDelBcPtrnReqParamsType* pwdiWowlDelBcPtrnParams, + WDI_WowlDelBcPtrnCb wdiWowlDelBcPtrnCb, + void* pUserData +); + +/** + @brief WDI_WowlEnterReq will be called when the upper MAC + wants to enter the Wowl state to minimize unnecessary + host wakeup while in power save. Upon the call of this + API the WLAN DAL will pack and send a HAL Wowl enter + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlEnterReqParams: the Wowl enter info as + specified by the Device Interface + + wdiWowlEnterReqCb: callback for passing back the + response of the enter Wowl operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlEnterReq +( + WDI_WowlEnterReqParamsType* pwdiWowlEnterParams, + WDI_WowlEnterReqCb wdiWowlEnterCb, + void* pUserData +); + +/** + @brief WDI_WowlExitReq will be called when the upper MAC + wants to exit the Wowl state. Upon the call of this API + the WLAN DAL will pack and send a HAL Wowl exit request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlEnterReq must have been called. + + @param pwdiWowlExitReqParams: the Wowl exit info as + specified by the Device Interface + + wdiWowlExitReqCb: callback for passing back the response + of the exit Wowl operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlEnterReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlExitReq +( + WDI_WowlExitReqParamsType* pwdiWowlExitParams, + WDI_WowlExitReqCb wdiWowlExitCb, + void* pUserData +); + +/** + @brief WDI_ConfigureAppsCpuWakeupStateReq will be called when + the upper MAC wants to dynamically adjusts the listen + interval based on the WLAN/MSM activity. Upon the call + of this API the WLAN DAL will pack and send a HAL + configure Apps Cpu Wakeup State request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureAppsCpuWakeupStateReqParams: the + Apps Cpu Wakeup State as specified by the + Device Interface + + wdiConfigureAppsCpuWakeupStateCb: callback for passing + back the response of the configure Apps Cpu Wakeup State + operation received from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureAppsCpuWakeupStateReq +( + WDI_ConfigureAppsCpuWakeupStateReqParamsType *pwdiConfigureAppsCpuWakeupStateReqParams, + WDI_ConfigureAppsCpuWakeupStateCb wdiConfigureAppsCpuWakeupStateCb, + void* pUserData +); +/** + @brief WDI_FlushAcReq will be called when the upper MAC wants + to to perform a flush operation on a given AC. Upon the + call of this API the WLAN DAL will pack and send a HAL + Flush AC request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFlushAcReqParams: the Flush AC parameters as + specified by the Device Interface + + wdiFlushAcRspCb: callback for passing back the response + of the Flush AC operation received from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_FlushAcReq +( + WDI_FlushAcReqParamsType* pwdiFlushAcReqParams, + WDI_FlushAcRspCb wdiFlushAcRspCb, + void* pUserData +); + +/** + @brief WDI_BtAmpEventReq will be called when the upper MAC + wants to notify the lower mac on a BT AMP event. This is + to inform BTC-SLM that some BT AMP event occurred. Upon + the call of this API the WLAN DAL will pack and send a + HAL BT AMP event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiBtAmpEventReqParams: the BT AMP event parameters as + specified by the Device Interface + + wdiBtAmpEventRspCb: callback for passing back the + response of the BT AMP event operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_BtAmpEventReq +( + WDI_BtAmpEventParamsType* pwdiBtAmpEventReqParams, + WDI_BtAmpEventRspCb wdiBtAmpEventRspCb, + void* pUserData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief WDI_Start oem data Req will be called when the upper MAC + wants to notify the lower mac on a oem data Req event.Upon + the call of this API the WLAN DAL will pack and send a + HAL OEM Data Req event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pWdiOemDataReqParams: the oem data req parameters as + specified by the Device Interface + + wdiStartOemDataRspCb: callback for passing back the + response of the Oem Data Req received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StartOemDataReq +( + WDI_oemDataReqParamsType* pWdiOemDataReqParams, + WDI_oemDataRspCb wdiOemDataRspCb, + void* pUserData +); +#endif + +/*======================================================================== + + CONTROL APIs + +==========================================================================*/ +/** + @brief WDI_SwitchChReq will be called when the upper MAC wants + the WLAN HW to change the current channel of operation. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiSwitchChReqParams: the switch ch parameters as + specified by the Device Interface + + wdiSwitchChRspCb: callback for passing back the response + of the switch ch operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SwitchChReq +( + WDI_SwitchChReqParamsType* pwdiSwitchChReqParams, + WDI_SwitchChRspCb wdiSwitchChRspCb, + void* pUserData +); + + + +/** + @brief WDI_ConfigSTAReq will be called when the upper MAC + wishes to add or update a STA in HW. Upon the call of + this API the WLAN DAL will pack and send a HAL Start + message request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiConfigSTAReqParams: the config STA parameters as + specified by the Device Interface + + wdiConfigSTARspCb: callback for passing back the + response of the config STA operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ConfigSTAReq +( + WDI_ConfigSTAReqParamsType* pwdiConfigSTAReqParams, + WDI_ConfigSTARspCb wdiConfigSTARspCb, + void* pUserData +); + +/** + @brief WDI_SetLinkStateReq will be called when the upper MAC + wants to change the state of an ongoing link. Upon the + call of this API the WLAN DAL will pack and send a HAL + Start message request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiSetLinkStateReqParams: the set link state parameters + as specified by the Device Interface + + wdiSetLinkStateRspCb: callback for passing back the + response of the set link state operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinStartReq + @return Result of the function call +*/ +WDI_Status +WDI_SetLinkStateReq +( + WDI_SetLinkReqParamsType* pwdiSetLinkStateReqParams, + WDI_SetLinkStateRspCb wdiSetLinkStateRspCb, + void* pUserData +); + + +/** + @brief WDI_GetStatsReq will be called when the upper MAC wants + to get statistics (MIB counters) from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetStatsReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetStatsRspCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetStatsReq +( + WDI_GetStatsReqParamsType* pwdiGetStatsReqParams, + WDI_GetStatsRspCb wdiGetStatsRspCb, + void* pUserData +); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief WDI_GetRoamRssiReq will be called when the upper MAC wants + to get roam rssi from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetRoamRssiReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetRoamRssispCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetRoamRssiReq +( + WDI_GetRoamRssiReqParamsType* pwdiGetRoamRssiReqParams, + WDI_GetRoamRssiRspCb wdiGetRoamRssiRspCb, + void* pUserData +); +#endif + +/** + @brief WDI_UpdateCfgReq will be called when the upper MAC when + it wishes to change the configuration of the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update CFG request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiUpdateCfgReqParams: the update cfg parameters as + specified by the Device Interface + + wdiUpdateCfgsRspCb: callback for passing back the + response of the update cfg operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_UpdateCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiUpdateCfgReqParams, + WDI_UpdateCfgRspCb wdiUpdateCfgsRspCb, + void* pUserData +); + +/** + @brief WDI_NvDownloadReq will be called by the UMAC to dowload the NV blob + to the NV memory. + + @param wdiNvDownloadReqParams: the NV Download parameters as specified by + the Device Interface + + wdiNvDownloadRspCb: callback for passing back the response of + the NV Download operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_NvDownloadReq +( + WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams, + WDI_NvDownloadRspCb wdiNvDownloadRspCb, + void* pUserData +); +/** + @brief WDI_AddBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBAReq +( + WDI_AddBAReqParamsType* pwdiAddBAReqParams, + WDI_AddBARspCb wdiAddBARspCb, + void* pUserData +); + +/** + @brief WDI_TriggerBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_TriggerBAReq +( + WDI_TriggerBAReqParamsType* pwdiTriggerBAReqParams, + WDI_TriggerBARspCb wdiTriggerBARspCb, + void* pUserData +); + + +/** + @brief WDI_IsHwFrameTxTranslationCapable checks to see if HW + frame xtl is enabled for a particular STA. + + WDI_PostAssocReq must have been called. + + @param uSTAIdx: STA index + + @see WDI_PostAssocReq + @return Result of the function call +*/ +wpt_boolean WDI_IsHwFrameTxTranslationCapable +( + wpt_uint8 uSTAIdx +); + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief WDI_AggrAddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation for 11r. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Aggregated Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAggrAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAggrAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AggrAddTSReq +( + WDI_AggrAddTSReqParamsType* pwdiAddTsReqParams, + WDI_AggrAddTsRspCb wdiAggrAddTsRspCb, + void* pUserData +); +#endif /* WLAN_FEATURE_VOWIFI_11R */ +/** + @brief WDI_STATableInit - Initializes the STA tables. + Allocates the necesary memory. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ + +WDI_Status WDI_StubRunTest +( + wpt_uint8 ucTestNo +); + +/** + @brief WDI_FTMCommandReq - + Route FTMRequest Command to HAL + + @param ftmCommandReq: FTM request command body + @param ftmCommandRspCb: Response CB + @param pUserData: User data will be included with CB + + @return Result of the function call +*/ +WDI_Status WDI_FTMCommandReq +( + WDI_FTMCommandReqType *ftmCommandReq, + WDI_FTMCommandRspCb ftmCommandRspCb, + void *pUserData +); + +/** + @brief WDI_HostResumeReq will be called + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiResumeReqParams: as specified by + the Device Interface + + wdiResumeReqRspCb: callback for passing back the response of + the Resume Req received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_HostResumeReq +( + WDI_ResumeParamsType* pwdiResumeReqParams, + WDI_HostResumeEventRspCb wdiResumeReqRspCb, + void* pUserData +); + +/** + @brief WDI_GetAvailableResCount - Function to get the available resource + for data and managemnt frames. + + @param pContext: pointer to the WDI context + @param wdiResPool: type of resource pool requesting + @see + @return Result of the function call +*/ + +wpt_uint32 WDI_GetAvailableResCount +( + void *pContext, + WDI_ResPoolType wdiResPool +); + +/** + @brief WDI_SetAddSTASelfReq will be called when the + UMAC wanted to add self STA while opening any new session + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiAddSTASelfParams: the add self sta parameters as + specified by the Device Interface + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_AddSTASelfReq +( + WDI_AddSTASelfReqParamsType* pwdiAddSTASelfReqParams, + WDI_AddSTASelfParamsRspCb wdiAddSTASelfReqParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_DelSTASelfReq will be called . + + @param WDI_DelSTASelfReqParamsType + + WDI_DelSTASelfRspCb: callback for passing back the + response of the del sta self operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTASelfReq +( + WDI_DelSTASelfReqParamsType* pwdiDelStaSelfParams, + WDI_DelSTASelfRspCb wdiDelStaSelfRspCb, + void* pUserData +); + +/** + @brief WDI_HostSuspendInd + + Suspend Indication from the upper layer will be sent + down to HAL + + @param WDI_SuspendParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_HostSuspendInd +( + WDI_SuspendParamsType* pwdiSuspendIndParams +); + +/** + @brief WDI_TrafficStatsInd + + Traffic Stats from the upper layer will be sent + down to HAL + + @param WDI_TrafficStatsIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_TrafficStatsInd +( + WDI_TrafficStatsIndType *pWdiTrafficStatsIndParams +); + +#ifdef WLAN_FEATURE_11W +/** + @brief WDI_ExcludeUnencryptedInd + Register with HAL to receive/drop unencrypted frames + + @param WDI_ExcludeUnencryptIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_ExcludeUnencryptedInd +( + WDI_ExcludeUnencryptIndType *pWdiExcUnencParams +); +#endif + +/** + @brief WDI_AddPeriodicTxPtrnInd + + @param WDI_AddPeriodicTxPtrnParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_AddPeriodicTxPtrnInd +( + WDI_AddPeriodicTxPtrnParamsType *addPeriodicTxPtrnParams +); + +/** + @brief WDI_DelPeriodicTxPtrnInd + + @param WDI_DelPeriodicTxPtrnParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_DelPeriodicTxPtrnInd +( + WDI_DelPeriodicTxPtrnParamsType *delPeriodicTxPtrnParams +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + @brief WDI_SetPreferredNetworkList + + @param pwdiPNOScanReqParams: the Set PNO as specified + by the Device Interface + + wdiPNOScanCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetPreferredNetworkReq +( + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams, + WDI_PNOScanCb wdiPNOScanCb, + void* pUserData +); + +/** + @brief WDI_SetRssiFilterReq + + @param pwdiRssiFilterReqParams: the Set RSSI Filter as + specified by the Device Interface + + wdiRssiFilterCb: callback for passing back the response + of the Set RSSI Filter operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetRssiFilterReq +( + WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams, + WDI_RssiFilterCb wdiRssiFilterCb, + void* pUserData +); + +/** + @brief WDI_UpdateScanParams + + @param pwdiUpdateScanParamsInfoType: the Update Scan Params as specified + by the Device Interface + + wdiUpdateScanParamsCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateScanParamsReq +( + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParamsInfoType, + WDI_UpdateScanParamsCb wdiUpdateScanParamsCb, + void* pUserData +); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + @brief WDI_RoamScanOffloadReq + + @param pwdiRoamScanOffloadReqParams: Start Roam Candidate Lookup Req as specified + by the Device Interface + + wdiRoamOffloadScanCb: callback for passing back the response + of the Start Roam Candidate Lookup operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_RoamScanOffloadReq +( + WDI_RoamScanOffloadReqParamsType *pwdiRoamScanOffloadReqParams, + WDI_RoamOffloadScanCb wdiRoamOffloadScancb, + void* pUserData +); +#endif + +/** + @brief WDI_SetTxPerTrackingReq will be called when the upper MAC + wants to set the Tx Per Tracking configurations. + Upon the call of this API the WLAN DAL will pack + and send a HAL Set Tx Per Tracking request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + @param wdiSetTxPerTrackingConf: the Set Tx PER Tracking configurations as + specified by the Device Interface + + wdiSetTxPerTrackingCb: callback for passing back the + response of the set Tx PER Tracking configurations operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPerTrackingReq +( + WDI_SetTxPerTrackingReqParamsType* pwdiSetTxPerTrackingReqParams, + WDI_SetTxPerTrackingRspCb pwdiSetTxPerTrackingRspCb, + void* pUserData +); + +/** + @brief WDI_SetTmLevelReq + If HW Thermal condition changed, driver should react based on new + HW thermal condition. + + @param pwdiSetTmLevelReq: New thermal condition information + + pwdiSetTmLevelRspCb: callback + + usrData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTmLevelReq +( + WDI_SetTmLevelReqType *pwdiSetTmLevelReq, + WDI_SetTmLevelCb pwdiSetTmLevelRspCb, + void *usrData +); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/** + @brief WDI_8023MulticastListReq + + @param pwdiRcvFltPktSetMcListReqInfo: the Set 8023 Multicast + List as specified by the Device Interface + + wdi8023MulticastListCallback: callback for passing back + the response of the Set 8023 Multicast List operation + received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_8023MulticastListReq +( + WDI_RcvFltPktSetMcListReqParamsType* pwdiRcvFltPktSetMcListReqInfo, + WDI_8023MulticastListCb wdi8023MulticastListCallback, + void* pUserData +); + +/** + @brief WDI_ReceiveFilterSetFilterReq + + @param pwdiSetRcvPktFilterReqInfo: the Set Receive Filter as + specified by the Device Interface + + wdiReceiveFilterSetFilterReqCallback: callback for + passing back the response of the Set Receive Filter + operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ReceiveFilterSetFilterReq +( + WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo, + WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterReqCallback, + void* pUserData +); + +/** + @brief WDI_PCFilterMatchCountReq + + @param pwdiRcvFltPktMatchCntReqInfo: get D0 PC Filter Match + Count + + wdiPCFilterMatchCountCallback: callback for passing back + the response of the D0 PC Filter Match Count operation + received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_FilterMatchCountReq +( + WDI_RcvFltPktMatchCntReqParamsType* pwdiRcvFltPktMatchCntReqInfo, + WDI_FilterMatchCountCb wdiFilterMatchCountCallback, + void* pUserData +); + +/** + @brief WDI_ReceiveFilterClearFilterReq + + @param pwdiRcvFltPktClearReqInfo: the Clear Filter as + specified by the Device Interface + + wdiReceiveFilterClearFilterCallback: callback for + passing back the response of the Clear Filter + operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ReceiveFilterClearFilterReq +( + WDI_RcvFltPktClearReqParamsType* pwdiRcvFltPktClearReqInfo, + WDI_ReceiveFilterClearFilterCb wdiReceiveFilterClearFilterCallback, + void* pUserData +); +#endif // WLAN_FEATURE_PACKET_FILTERING + +/** + @brief WDI_HALDumpCmdReq + Post HAL DUMP Command Event + + @param halDumpCmdReqParams: Hal Dump Command Body + @param halDumpCmdRspCb: callback for passing back the + response + @param pUserData: Client Data + + @see + @return Result of the function call +*/ +WDI_Status WDI_HALDumpCmdReq( + WDI_HALDumpCmdReqParamsType *halDumpCmdReqParams, + WDI_HALDumpCmdRspCb halDumpCmdRspCb, + void *pUserData +); + + +/** + @brief WDI_SetPowerParamsReq + + @param pwdiPowerParamsReqParams: the Set Power Params as + specified by the Device Interface + + wdiPowerParamsCb: callback for passing back the response + of the Set Power Params operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetPowerParamsReq +( + WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams, + WDI_SetPowerParamsCb wdiPowerParamsCb, + void* pUserData +); +/** + @brief WDI_dhcpStartInd + Forward the DHCP Start event + + @param + + wdiDHCPInd: device mode and MAC address is passed + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_dhcpStartInd +( + WDI_DHCPInd *wdiDHCPInd +); +/** + @brief WDI_dhcpStopReq + Forward the DHCP Stop event + + @param + + wdiDHCPInd: device mode and MAC address is passed + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_dhcpStopInd +( + WDI_DHCPInd *wdiDHCPInd +); + +/** + @brief WDI_RateUpdateInd will be called when the upper MAC + requests the device to update rates. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiRateUpdateIndParams + + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_RateUpdateInd +( + WDI_RateUpdateIndParams *wdiRateUpdateIndParams +); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/** + @brief WDI_GTKOffloadReq will be called when the upper MAC + wants to set GTK Rekey Counter while in power save. Upon + the call of this API the WLAN DAL will pack and send a + HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadParams: the GTK offload as specified + by the Device Interface + + wdiGtkOffloadCb: callback for passing back the response + of the GTK offload operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadReq +( + WDI_GtkOffloadReqMsg* pwdiGtkOffloadReqMsg, + WDI_GtkOffloadCb wdiGtkOffloadCb, + void* pUserData +); + +/** + @brief WDI_GTKOffloadGetInfoReq will be called when the upper + MAC wants to get GTK Rekey Counter while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadGetInfoReqMsg: the GTK Offload + Information Message as specified by the + Device Interface + + wdiGtkOffloadGetInfoCb: callback for passing back the + response of the GTK offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadGetInfoReq +( + WDI_GtkOffloadGetInfoReqMsg* pwdiGtkOffloadGetInfoReqMsg, + WDI_GtkOffloadGetInfoCb wdiGtkOffloadGetInfoCb, + void* pUserData +); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/** + @brief WDI_featureCapsExchangeReq + Post feature capability bitmap exchange event. + Host will send its own capability to FW in this req and + expect FW to send its capability back as a bitmap in Response + + @param + + wdiFeatCapsExcRspCb: callback called on getting the response. + It is kept to mantain similarity between WDI reqs and if needed, can + be used in future. Currently, It is set to NULL + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_featureCapsExchangeReq +( + WDI_featureCapsExchangeCb wdiFeatureCapsExchangeCb, + void* pUserData +); + +/** + @brief Disable Active mode offload in Host + + @param void + @see + @return void +*/ +void +WDI_disableCapablityFeature(wpt_uint8 feature_index); + + +/** + @brief WDI_getHostWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by Host or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in host + any non-zero value - if the feature is SUPPORTED in host. +*/ +wpt_uint8 WDI_getHostWlanFeatCaps(wpt_uint8 feat_enum_value); + +/** + @brief WDI_getFwWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by FW or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap + in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in FW + any non-zero value - if the feature is SUPPORTED in FW. +*/ +static inline wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value) +{ + return 1; +} + +/** + @brief WDI_GetWcnssCompiledApiVersion - Function to get wcnss compiled + api version + + @param WDI_WlanVersionType: Wlan version structure + @see + @return none +*/ + +void WDI_GetWcnssCompiledApiVersion +( + WDI_WlanVersionType *pWcnssApiVersion +); + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_UpdateVHTOpModeReq +( + WDI_UpdateVHTOpMode *pData, + WDI_UpdateVHTOpModeCb wdiUpdateVHTOpModeCb, + void* pUserData +); + +#endif + +/** + @brief WDI_TransportChannelDebug - + Display DXE Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + @param displaySnapshot : Display DXE snapshot option + @param enableStallDetect : Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + @see + @return none +*/ +void WDI_TransportChannelDebug +( + wpt_boolean displaySnapshot, + wpt_boolean toggleStallDetect +); + +/** + @brief WDI_SsrTimerCB + Callback function for SSR timer, if this is called then the graceful + shutdown for Riva did not happen. + + @param pUserData : user data to timer + + @see + @return none +*/ +void +WDI_SsrTimerCB +( + void *pUserData +); + +/** + @brief WDI_SetEnableSSR - + This API is called to enable/disable SSR on WDI timeout. + + @param enableSSR : enable/disable SSR + + @see + @return none +*/ +void WDI_SetEnableSSR(wpt_boolean enableSSR); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_LPHBConfReq + This API is called to config FW LPHB rule + + @param lphbconfParam : LPHB rule should config to FW + usrData : Client context + lphbCfgCb : Configuration status callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_LPHBConfReq +( + void *lphbconfParam, + void *usrData, + WDI_LphbCfgCb lphbCfgCb +); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_SetBatchScanReq + This API is called to set batch scan request in FW + + @param pBatchScanReqParam : pointer to set batch scan re param + usrData : Client context + setBatchScanRspCb : set batch scan resp callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_SetBatchScanReq +( + void *pBatchScanReqParam, + void *usrData, + WDI_SetBatchScanCb setBatchScanRspCb +); + +/** + @brief WDI_StopBatchScanInd + + @param none + + @see + + @return Status of the request +*/ +WDI_Status +WDI_StopBatchScanInd(WDI_StopBatchScanIndType *pWdiReq); + +/** + @brief WDI_TriggerBatchScanResultInd + This API is called to pull batch scan result from FW + + @param pBatchScanReqParam : pointer to trigger batch scan ind param + usrData : Client context + setBatchScanRspCb : get batch scan resp callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_TriggerBatchScanResultInd(WDI_TriggerBatchScanResultIndType *pWdiReq); + + +#endif /*FEATURE_WLAN_BATCH_SCAN*/ + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WDI_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h new file mode 100644 index 0000000000000..400e3a1a31d19 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h @@ -0,0 +1,1291 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_BD_H +#define WLAN_QCT_WDI_BD_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + B D H E A D E R D E F I N I T I O N + + +DESCRIPTION + This file contains the internal BD definition exposed by the DAL Control + Path Core module to be used by the DAL Data Path Core. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" + + +/*========================================================================= + BD STRUCTURE Defines + =========================================================================*/ +/*--------------------------------------------------------------------------- + WDI_RxBdType - The format of the RX BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + This routing flag indicates the WQ number to which the DPU will push the + frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** This is DPU sig inserted by RXP. Signature on RA's DPU descriptor */ + wpt_uint32 dpuSignature:3; + + /** When set Sta is authenticated. SW needs to set bit + addr2_auth_extract_enable in rxp_config2 register. Then RXP will use bit 3 + in DPU sig to say whether STA is authenticated or not. In this case only + lower 2bits of DPU Sig is valid */ + wpt_uint32 stAuF:1; + + /** When set address2 is not valid */ + wpt_uint32 A2HF:1; + + /** When set it indicates TPE has sent the Beacon frame */ + wpt_uint32 bsf:1; + + /** This bit filled by rxp when set indicates if the current tsf is smaller + than received tsf */ + wpt_uint32 rtsf:1; + +#ifdef WCN_PRONTO_CSU + /** No valid header found during parsing. Therefore no checksum was validated */ + wpt_uint32 csuNoValHd:1; + + /** 0 = CSU did not verify TCP/UDP (Transport Layer TL) checksum; 1 = CSU verified TCP/UDP checksum */ + wpt_uint32 csuVerifiedTLChksum:1; + + /** 0 = CSU did not verify IP checksum; 1 = CSU verified IP checksum */ + wpt_uint32 csuVerifiedIPChksum:1; + + /** 0 = BD field checksum is not valid; 1 = BD field checksum is valid */ + wpt_uint32 csuChksumValid:1; + + /** 0 = No TCP/UDP checksum error; 1 = Has TCP/UDP checksum error */ + wpt_uint32 csuTLChksumError:1; + + /** 0 = No IPv4/IPv6 checksum error; 1 = Has IPv4/IPv6 checksum error */ + wpt_uint32 csuIPChksumError:1; +#else /*WCN_PRONTO*/ + /** These two fields are used by SW to carry the Rx Channel number and SCAN bit in RxBD*/ + wpt_uint32 rxChannel:4; + wpt_uint32 scanLearn:1; + wpt_uint32 reserved0:1; +#endif /*WCN_PRONTO*/ + + /** LLC Removed + This bit is only used in Libra rsvd for Virgo1.0/Virgo2.0 + Filled by ADU when it is set LLC is removed from packet */ + wpt_uint32 llcr:1; + + wpt_uint32 umaByPass:1; + + /** This bit is only available in Virgo2.0/libra it is reserved in Virgo1.0 + Robust Management frame. This bit indicates to DPU that the packet is a + robust management frame which requires decryption(this bit is only valid for + management unicast encrypted frames) + 1 - Needs decryption + 0 - No decryption required */ + wpt_uint32 rmf:1; + + /** + This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is only valid when RMF bit is 1 */ + wpt_uint32 ub:1; + + /** This is the KEY ID extracted from WEP packets and is used for determine + the RX Key Index to use in the DPU Descriptror. + This field is 2bits for virgo 1.0 + And 3 bits in virgo2.0 and Libra + In virgo2.0/libra it is 3bits for the BC/MC packets */ + wpt_uint32 rxKeyId:3; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + /** + This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit is filled by RXP and modified by ADU + This bit indicates to ADU/UMA module that the packet requires 802.11n to + 802.3 frame translation. Once ADU/UMA is done with translation they + overwrite it with 1'b0/1'b1 depending on how the translation resulted + When used by ADU + 0 - No frame translation required + 1 - Frame Translation required + When used by SW + 0 - Frame translation not done, MPDU header offset points to 802.11 header.. + 1 - Frame translation done ; hence MPDU header offset will point to a + 802.3 header */ + wpt_uint32 ft:1; + + /** (Only used by the DPU) + BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; + +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 rxKeyId:3; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; + wpt_uint32 umaByPass:1; + wpt_uint32 llcr:1; + +#ifdef WCN_PRONTO_CSU + wpt_uint32 csuIPChksumError:1; + wpt_uint32 csuTLChksumError:1; + wpt_uint32 csuChksumValid:1; + wpt_uint32 csuVerifiedIPChksum:1; + wpt_uint32 csuVerifiedTLChksum:1; + wpt_uint32 csuNoValHd:1; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:1; + wpt_uint32 scanLearn:1; + wpt_uint32 rxChannel:4; +#endif /*WCN_PRONTO*/ + + wpt_uint32 rtsf:1; + wpt_uint32 bsf:1; + wpt_uint32 A2HF:1; + wpt_uint32 stAuF:1; + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is used for AMSDU this is the PDU index of the PDU which is the + one before last PDU; for all non AMSDU frames, this field SHALL be 0. + Used in ADU (for AMSDU deaggregation) */ + wpt_uint32 penultimatePduIdx:16; + +#ifdef WCN_PRONTO + wpt_uint32 aduFeedback:7; + wpt_uint32 dpuMagicPacket: 1; +#else + wpt_uint32 aduFeedback:8; +#endif //WCN_PRONTO + + /** DPU feedback */ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; +#ifdef WCN_PRONTO + wpt_uint32 dpuMagicPacket: 1; + wpt_uint32 aduFeedback:7; +#else + wpt_uint32 aduFeedback:8; +#endif //WCN_PRONTO + wpt_uint32 penultimatePduIdx:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** In case PDUs are linked to the BD, this field indicates the index of + the first PDU linked to the BD. When PDU count is zero, this field has an + undefined value. */ + wpt_uint32 headPduIdx:16; + + /** In case PDUs are linked to the BD, this field indicates the index of + the last PDU. When PDU count is zero, this field has an undefined value.*/ + wpt_uint32 tailPduIdx:16; + +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** The start byte number of the MPDU header. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** The start byte number of the MPDU data. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. Note that this offset can point all the way into the first + linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** The number of PDUs linked to the BD. + This field should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length does not include FCS field. */ + wpt_uint32 mpduLength:16; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 offloadScanLearn:1; + wpt_uint32 roamCandidateInd:1; +#else + wpt_uint32 reserved22:2; +#endif + +#ifdef WCN_PRONTO + wpt_uint32 reserved3: 1; + wpt_uint32 rxDXEPriorityRouting:1; +#else + wpt_uint32 reserved3:2; +#endif //WCN_PRONTO + + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, + this field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 reserved4:8; +#else + wpt_uint32 reserved4:8; + wpt_uint32 tid:4; +#ifdef WCN_PRONTO + wpt_uint32 rxDXEPriorityRouting:1; + wpt_uint32 reserved3: 1; +#else + wpt_uint32 reserved3:2; +#endif //WCN_PRONTO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 roamCandidateInd:1; + wpt_uint32 offloadScanLearn:1; +#else + wpt_uint32 reserved22:2; +#endif + + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + The DPU descriptor index is used to calculate where in memory the DPU can + find the DPU descriptor related to this frame. The DPU calculates the + address by multiplying this index with the DPU descriptor size and adding + the DPU descriptors base address. The DPU descriptor contains information + specifying the encryption and compression type and contains references to + where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** The result from the binary address search on the ADDR1 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr1Index:8; + + /** The result from the binary address search on the ADDR2 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr2Index:8; + + /** The result from the binary address search on the ADDR3 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr3Index:8; +#else + wpt_uint32 addr3Index:8; + wpt_uint32 addr2Index:8; + wpt_uint32 addr1Index:8; + wpt_uint32 dpuDescIdx:8; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Indicates Rate Index of packet received */ + wpt_uint32 rateIndex:9; + + /** An overview of RXP status information related to receiving the frame.*/ + wpt_uint32 rxpFlags:23; + +#else + + wpt_uint32 rxpFlags:23; /* RxP flags*/ + wpt_uint32 rateIndex:9; + +#endif + /* 0x1c, 20 */ + /** The PHY can be programmed to put all the PHY STATS received from the + PHY when receiving a frame in the BD. */ + wpt_uint32 phyStats0; /* PHY status word 0*/ + wpt_uint32 phyStats1; /* PHY status word 1*/ + + /* 0x24 */ + /** The value of the TSF[31:0] bits at the moment that the RXP start + receiving a frame from the PHY RX. */ + wpt_uint32 mclkRxTimestamp; /* Rx timestamp, microsecond based*/ + + /* 0x28~0x38 */ + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd4to23[5]; /* PMI cmd rcvd from RxP */ + + /* 0x3c */ +#ifdef WCN_PRONTO +#ifdef WPT_BIG_BYTE_ENDIAN + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd24to25:16; + + /* 16-bit CSU Checksum value for the fragmented receive frames */ + wpt_uint32 csuChecksum:16; +#else + wpt_uint32 csuChecksum:16; + wpt_uint32 pmiCmd24to25:16; +#endif +#else /*WCN_PRONTO*/ + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd24to25; +#endif /*WCN_PRONTO*/ + + /* 0x40 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Gives commands to software upon which host will perform some commands. + Please refer to following RPE document for description of all different + values for this field. */ + wpt_uint32 reorderOpcode:4; + + wpt_uint32 reserved6:12; + + /** Filled by RPE to Indicate to the host up to which slot the host needs + to forward the packets to upper Mac layer. This field mostly used for AMDPU + packets */ + wpt_uint32 reorderFwdIdx:6; + + /** Filled by RPE which indicates to the host which one of slots in the + available 64 slots should the host Queue the packet. This field only + applied to AMPDU packets. */ + wpt_uint32 reorderSlotIdx:6; + +#ifdef WCN_PRONTO + wpt_uint32 reserved7: 2; + wpt_uint32 outOfOrderForward: 1; + wpt_uint32 reorderEnable: 1; +#else + wpt_uint32 reserved7:4; +#endif //WCN_PRONTO + +#else + +#ifdef WCN_PRONTO + wpt_uint32 reorderEnable: 1; + wpt_uint32 outOfOrderForward: 1; + wpt_uint32 reserved7: 2; +#else + wpt_uint32 reserved7:4; +#endif //WCN_PRONTO + wpt_uint32 reorderSlotIdx:6; + wpt_uint32 reorderFwdIdx:6; + wpt_uint32 reserved6:12; + wpt_uint32 reorderOpcode:4; +#endif + + /* 0x44 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** reserved8 from a hardware perspective. + Used by SW to propogate frame type/subtype information */ + wpt_uint32 frameTypeSubtype:6; + wpt_uint32 rfBand:2; + + /** Filled RPE gives the current sequence number in bitmap */ + wpt_uint32 currentPktSeqNo:12; + + /** Filled by RPE which gives the sequence number of next expected packet + in bitmap */ + wpt_uint32 expectedPktSeqNo:12; +#else + wpt_uint32 expectedPktSeqNo:12; + wpt_uint32 currentPktSeqNo:12; + wpt_uint32 rfBand:2; + wpt_uint32 frameTypeSubtype:6; +#endif + + /* 0x48 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** When set it is the AMSDU subframe */ + wpt_uint32 asf:1; + + /** When set it is the First subframe of the AMSDU packet */ + wpt_uint32 esf:1; + + /** When set it is the last subframe of the AMSDU packet */ + wpt_uint32 lsf:1; + + /** When set it indicates an Errored AMSDU packet */ + wpt_uint32 aef:1; + + wpt_uint32 reserved9:4; + + /** It gives the order in which the AMSDU packet is processed + Basically this is a number which increments by one for every AMSDU frame + received. Mainly for debugging purpose. */ + wpt_uint32 processOrder:4; + + /** It is the order of the subframe of AMSDU that is processed by ADU. + This is reset to 0 when ADU deaggregates the first subframe from a new + AMSDU and increments by 1 for every new subframe deaggregated within the + AMSDU, after it reaches 4'hf it stops incrementing. That means host should + not rely on this field as index for subframe queuing. Theoretically there + can be way more than 16 subframes in an AMSDU. This is only used for debug + purpose, SW should use LSF and FSF bits to determine first and last + subframes. */ + wpt_uint32 sybFrameIdx:4; + + /** Filled by ADU this is the total AMSDU size */ + wpt_uint32 totalMsduSize:16; +#else + wpt_uint32 totalMsduSize:16; + wpt_uint32 sybFrameIdx:4; + wpt_uint32 processOrder:4; + wpt_uint32 reserved9:4; + wpt_uint32 aef:1; + wpt_uint32 lsf:1; + wpt_uint32 esf:1; + wpt_uint32 asf:1; +#endif + +} WDI_RxBdType; + +/*--------------------------------------------------------------------------- + WDI_RxFcBdType - The format of the RX special flow control BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + This routing flag indicates the WQ number to which the DPU will push the + frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** This is DPU sig inserted by RXP. Signature on RA's DPU descriptor */ + wpt_uint32 dpuSignature:3; + + /** When set Sta is authenticated. SW needs to set bit + addr2_auth_extract_enable in rxp_config2 register. Then RXP will use bit 3 + in DPU sig to say whether STA is authenticated or not. In this case only + lower 2bits of DPU Sig is valid */ + wpt_uint32 stAuF:1; + + /** When set address2 is not valid */ + wpt_uint32 A2HF:1; + + /** When set it indicates TPE has sent the Beacon frame */ + wpt_uint32 bsf:1; + + /** This bit filled by rxp when set indicates if the current tsf is smaller + than received tsf */ + wpt_uint32 rtsf:1; + + /** These two fields are used by SW to carry the Rx Channel number and SCAN bit in RxBD*/ + wpt_uint32 rxChannel:4; + wpt_uint32 scanLearn:1; + + wpt_uint32 reserved0:1; + + /** LLC Removed + This bit is only used in Libra rsvd for Virgo1.0/Virgo2.0 + Filled by ADU when it is set LLC is removed from packet */ + wpt_uint32 llcr:1; + + wpt_uint32 umaByPass:1; + + /** This bit is only available in Virgo2.0/libra it is reserved in Virgo1.0 + Robust Management frame. This bit indicates to DPU that the packet is a + robust management frame which requires decryption(this bit is only valid for + management unicast encrypted frames) + 1 - Needs decryption + 0 - No decryption required */ + wpt_uint32 rmf:1; + + /** + This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is only valid when RMF bit is 1 */ + wpt_uint32 ub:1; + + /** This is the KEY ID extracted from WEP packets and is used for determine + the RX Key Index to use in the DPU Descriptror. + This field is 2bits for virgo 1.0 + And 3 bits in virgo2.0 and Libra + In virgo2.0/libra it is 3bits for the BC/MC packets */ + wpt_uint32 rxKeyId:3; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + /** + This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit is filled by RXP and modified by ADU + This bit indicates to ADU/UMA module that the packet requires 802.11n to + 802.3 frame translation. Once ADU/UMA is done with translation they + overwrite it with 1'b0/1'b1 depending on how the translation resulted + When used by ADU + 0 - No frame translation required + 1 - Frame Translation required + When used by SW + 0 - Frame translation not done, MPDU header offset points to 802.11 header.. + 1 - Frame translation done ; hence MPDU header offset will point to a + 802.3 header */ + wpt_uint32 ft:1; + + /** (Only used by the DPU) + BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; + +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 rxKeyId:3; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; + wpt_uint32 reserved1:1; + wpt_uint32 llc:1; + wpt_uint32 reserved0:1; + wpt_uint32 scanLearn:1; + wpt_uint32 rxChannel:4; + wpt_uint32 rtsf:1; + wpt_uint32 bsf:1; + wpt_uint32 A2HF:1; + wpt_uint32 stAuF:1; + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is used for AMSDU this is the PDU index of the PDU which is the + one before last PDU; for all non AMSDU frames, this field SHALL be 0. + Used in ADU (for AMSDU deaggregation) */ + wpt_uint32 penultimatePduIdx:16; + + wpt_uint32 aduFeedback:8; + + /** DPU feedback */ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; + wpt_uint32 aduFeedback:8; + wpt_uint32 penultimatePduIdx:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** In case PDUs are linked to the BD, this field indicates the index of + the first PDU linked to the BD. When PDU count is zero, this field has an + undefined value. */ + wpt_uint32 headPduIdx:16; + + /** In case PDUs are linked to the BD, this field indicates the index of + the last PDU. When PDU count is zero, this field has an undefined value.*/ + wpt_uint32 tailPduIdx:16; + +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** The start byte number of the MPDU header. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** The start byte number of the MPDU data. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. Note that this offset can point all the way into the first + linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** The number of PDUs linked to the BD. + This field should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length does not include FCS field. */ + wpt_uint32 mpduLength:16; + + wpt_uint32 reserved3:4; + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, + this field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 reserved4:7; + wpt_uint32 fc:1; //if set then its special flow control BD. +#else + wpt_uint32 fc:1; //if set then its special flow control BD. + wpt_uint32 reserved4:7; + wpt_uint32 tid:4; + wpt_uint32 reserved3:4; + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + The DPU descriptor index is used to calculate where in memory the DPU can + find the DPU descriptor related to this frame. The DPU calculates the + address by multiplying this index with the DPU descriptor size and adding + the DPU descriptors base address. The DPU descriptor contains information + specifying the encryption and compression type and contains references to + where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** The result from the binary address search on the ADDR1 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr1Index:8; + + /** The result from the binary address search on the ADDR2 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr2Index:8; + + /** The result from the binary address search on the ADDR3 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr3Index:8; +#else + wpt_uint32 addr3Index:8; + wpt_uint32 addr2Index:8; + wpt_uint32 addr1Index:8; + wpt_uint32 dpuDescIdx:8; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Indicates Rate Index of packet received */ + wpt_uint32 rateIndex:9; + + /** An overview of RXP status information related to receiving the frame.*/ + wpt_uint32 rxpFlags:23; + +#else + + wpt_uint32 rxpFlags:23; /* RxP flags*/ + wpt_uint32 rateIndex:9; + +#endif + /* 0x1c, 20 */ + /** The PHY can be programmed to put all the PHY STATS received from the + PHY when receiving a frame in the BD. */ + wpt_uint32 phyStats0; /* PHY status word 0*/ + wpt_uint32 phyStats1; /* PHY status word 1*/ + + /* 0x24 */ + /** The value of the TSF[31:0] bits at the moment that the RXP start + receiving a frame from the PHY RX. */ + wpt_uint32 mclkRxTimestamp; /* Rx timestamp, microsecond based*/ + + /* 0x28 - 0x2c*/ +#ifdef WPT_BIG_BYTE_ENDIAN + /** One bit per STA. Bit X for STA id X, X=0~7. When set, corresponding STA is valid in FW's STA table.*/ + wpt_uint32 fcSTAValidMask:16; + /** One bit per STA. Bit X for STA id X, X=0~7. Valid only when corresponding bit in fcSTAValisMask is set.*/ + wpt_uint32 fcSTAPwrSaveStateMask:16; + /** One bit per STA. Bit X for STA id X, X=0~7. Valid only when corresponding bit in fcSTAValisMask is set. + When set, corresponding fcSTAThreshEnableMask bit in previous flow control request packet frame was enabled + AND the STA TxQ length is lower than configured fcSTAThresh value. */ + wpt_uint32 fcSTAThreshIndMask:16; + /** Bit 0 unit: 1=BD count(Libra SoftAP project default). 0=packet count. Bit 7-1: Reserved */ + wpt_uint32 fcSTATxQStatus:16; +#else + wpt_uint32 fcSTATxQStatus:16; + wpt_uint32 fcSTAThreshIndMask:16; + wpt_uint32 fcSTAPwrSaveStateMask:16; + wpt_uint32 fcSTAValidMask:16; +#endif + /* 0x30 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 fcStaTxDisabledBitmap:16; + wpt_uint32 reserved5:16; +#else + wpt_uint32 reserved5:16; + wpt_uint32 fcStaTxDisabledBitmap:16; +#endif + + // with HAL_NUM_STA as 12 + /* 0x34 to 0x3A*/ + wpt_uint32 fcSTATxQLen[12]; // one byte per STA. + wpt_uint32 fcSTACurTxRate[12]; // current Tx rate for each sta. + +} WDI_FcRxBdType; //flow control BD + +/*--------------------------------------------------------------------------- + WDI_TxBdType - The format of the TX BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** (Only used by the DPU) This routing flag indicates the WQ number to + which the DPU will push the frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** DPU signature. Filled by Host in Virgo 1.0 but by ADU in Virgo 2.0 */ + wpt_uint32 dpuSignature:3; + +#ifdef WCN_PRONTO + /** Reserved */ + wpt_uint32 reserved0:2; + + /** Set to '1' to terminate the current AMPDU session. Added based on the + request for WiFi Display */ + wpt_uint32 terminateAMPDU:1; + + /** Bssid index to indicate ADU to use which of the 4 default MAC address + to use while 802.3 to 802.11 translation in case search in ADU UMA table + fails. The default MAC address should be appropriately programmed in the + uma_tx_default_wmacaddr_u(_1,_2,_3) and uma_tx_default_wmacaddr_l(_1,_2,_3) + registers */ + wpt_uint32 umaBssidIdx:2; + + /** Set to 1 to enable uma filling the BD when FT is not enabled. + Ignored when FT is enabled. */ + wpt_uint32 umaBDEnable:1; + + /** (Only used by the CSU) + 0: No action + 1: Host will indicate TCP/UPD header start location and provide pseudo header value in BD. + */ + wpt_uint32 csuSWMode:1; + + /** Enable/Disable CSU on TX direction. + 0: Disable Checksum Unit (CSU) for Transmit. + 1: Enable + */ + wpt_uint32 csuTXEnable:1; + + /** Enable/Disable Transport layer Checksum in CSU + 0: Disable TCP UDP checksum generation for TX. + 1: Enable TCP UDP checksum generation for TX. + */ + wpt_uint32 csuEnableTLCksum:1; + + /** Enable/Disable IP layer Checksum in CSU + 0: Disable IPv4/IPv6 checksum generation for TX + 1: Enable IPv4/IPv6 checksum generation for TX + */ + wpt_uint32 csuEnableIPCksum:1; + + /** Filled by CSU to indicate whether transport layer Checksum is generated by CSU or not + 0: TCP/UDP checksum is being generated for TX. + 1: TCP/UDP checksum is NOT being generated for TX. + */ + wpt_uint32 csuTLCksumGenerated:1; + + /** Filled by CSU in error scenario + 1: No valid header found during parsing. Therefore no checksum was validated. + 0: Valid header found + */ + wpt_uint32 csuNoValidHeader:1; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:12; +#endif /*WCN_PRONTO*/ + + /** Only available in Virgo 2.0 and reserved in Virgo 1.0. + This bit indicates to DPU that the packet is a robust management frame + which requires encryption(this bit is only valid for certain management + frames) + 1 - Needs encryption + 0 - No encrytion required + It is only set when Privacy bit=1 AND type/subtype=Deauth, Action, + Disassoc. Otherwise it should always be 0. */ + wpt_uint32 rmf:1; + + /** This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is valid only if RMF bit is set */ + wpt_uint32 ub:1; + + wpt_uint32 reserved1:1; + + /** This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This bit indicates TPE has to assert the TX complete interrupt. + 0 - no interrupt + 1 - generate interrupt */ + wpt_uint32 txComplete1:1; + wpt_uint32 fwTxComplete0:1; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + + /** This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit indicates to ADU/UMA module that the packet requires 802.11n + to 802.3 frame translation. When used by ADU + 0 - No frame translation required + 1 - Frame Translation required */ + wpt_uint32 ft:1; + + /** BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 fwTxComplete0:1; + wpt_uint32 txComplete1:1; + wpt_uint32 reserved1:1; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; +#ifdef WCN_PRONTO + wpt_uint32 csuNoValidHeader:1; + wpt_uint32 csuTLCksumGenerated:1; + wpt_uint32 csuEnableIPCksum:1; + wpt_uint32 csuEnableTLCksum:1; + wpt_uint32 csuTXEnable:1; + wpt_uint32 csuSWMode:1; + wpt_uint32 umaBDEnable:1; + wpt_uint32 umaBssidIdx:2; + wpt_uint32 terminateAMPDU:1; + wpt_uint32 reserved0:2; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:12; +#endif /*WCN_PRONTO*/ + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved2:16; /* MUST BE 0 otherwise triggers BMU error*/ + wpt_uint32 aduFeedback:8; + + /* DPU feedback in Tx path.*/ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; + wpt_uint32 aduFeedback:8; + wpt_uint32 reserved2:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields. In case PDUs are linked to the BD, this field + indicates the index of the first PDU linked to the BD. When PDU count is + zero, this field has an undefined value. */ + wpt_uint32 headPduIdx:16; + + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields.In case PDUs are linked to the BD, this field + indicates the index of the last PDU. When PDU count is zero, this field + has an undefined value. */ + wpt_uint32 tailPduIdx:16; +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The start byte number of the MPDU header. The byte numbering + is done in the BE format. Word 0x0, bits [31:24] has byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The start byte number of the MPDU data. The byte numbering + is done in the BE format. Word 0x0, bits [31:24] has byte index 0. + Note that this offset can point all the way into the first linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields. The number of PDUs linked to the BD. This field + should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/LibraMPDU length.This covers MPDU header length + MPDU data length. + This does not include FCS. For single frame transmission, PSDU size is + mpduLength + 4.*/ + wpt_uint32 mpduLength:16; + + wpt_uint32 reserved3:2; + /** Sequence number insertion by DPU + 00: Leave sequence number as is, as filled by host + 01: DPU to insert non TID based sequence number (If it is not TID based, + then how does DPU know what seq to fill? Is this the non-Qos/Mgmt sequence + number? + 10: DPU to insert a sequence number based on TID. + 11: Reserved */ + wpt_uint32 bd_ssn:2; + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, this + field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 reserved4:8; + +#else + wpt_uint32 reserved4:8; + wpt_uint32 tid:4; + wpt_uint32 bd_ssn:2; + wpt_uint32 reserved3:2; + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** (Only used by the DPU) + This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. The DPU descriptor index is used to calculate where in + memory the DPU can find the DPU descriptor related to this frame. The DPU + calculates the address by multiplying this index with the DPU descriptor + size and adding the DPU descriptors base address. The DPU descriptor + contains information specifying the encryption and compression type and + contains references to where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. The STAid of the RA address */ + wpt_uint32 staIndex:8; + + /** A field passed on to TPE which influences the ACK policy to be used for + this frame + 00 - Iack + 01,10,11 - No Ack */ + wpt_uint32 ap:2; + + /** Overwrite option for the transmit rate + 00: Use rate programmed in the TPE STA descriptor + 01: Use TPE BD rate 1 + 10: Use TPE BD rate 2 + 11: Delayed Use TPE BD rate 3 */ + wpt_uint32 bdRate:2; + + /** + This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. Queue ID */ + wpt_uint32 queueId:5; + + wpt_uint32 reserved5:7; +#else + wpt_uint32 reserved5:7; + wpt_uint32 queueId:5; + wpt_uint32 bdRate:2; + wpt_uint32 ap:2; + wpt_uint32 staIndex:8; + wpt_uint32 dpuDescIdx:8; +#endif + + wpt_uint32 txBdSignature; + + /* 0x1C */ + wpt_uint32 reserved6; + /* 0x20 */ + /* Timestamp filled by DXE. Timestamp for current transfer */ + wpt_uint32 dxeH2BStartTimestamp; + + /* 0x24 */ + /* Timestamp filled by DXE. Timestamp for previous transfer */ + wpt_uint32 dxeH2BEndTimestamp; + +#ifdef WCN_PRONTO +#ifdef WPT_BIG_BYTE_ENDIAN + /** 10 bit value to indicate the start of TCP UDP frame relative to + * the first IP frame header */ + wpt_uint32 csuTcpUdpStartOffset:10; + + /** 16 bit pseudo header for TCP UDP used by CSU to generate TCP/UDP + * frame checksum */ + wpt_uint32 csuPseudoHeaderCksum:16; + + wpt_uint32 reserved7:6; +#else + wpt_uint32 reserved7:6; + wpt_uint32 csuPseudoHeaderCksum:16; + wpt_uint32 csuTcpUdpStartOffset:10; +#endif +#endif /*WCN_PRONTO*/ + +} WDI_TxBdType; + +/*--------------------------------------------------------------------------- + WDI_RxDeFragBdType - The format of the RX BD Defragmented +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved1:30; + wpt_uint32 bdt:2; +#else + wpt_uint32 bdt:2; + wpt_uint32 reserved1:30; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved2:24; + wpt_uint32 dpuFeedBack:8; +#else + wpt_uint32 dpuFeedBack:8; + wpt_uint32 reserved2:24; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved3:16; + wpt_uint32 frag0BdIdx:16; +#else + wpt_uint32 frag0BdIdx:16; + wpt_uint32 reserved3:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved4:16; + wpt_uint32 frag1BdIdx:16; +#else + wpt_uint32 frag1BdIdx:16; + wpt_uint32 reserved4:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag2BdIdx:16; + wpt_uint32 reserved5:16; +#else + wpt_uint32 frag2BdIdx:16; + wpt_uint32 reserved5:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved6:16; + wpt_uint32 frag3BdIdx:16; +#else + wpt_uint32 frag3BdIdx:16; + wpt_uint32 reserved6:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved7:16; + wpt_uint32 frag4BdIdx:16; +#else + wpt_uint32 frag4BdIdx:16; + wpt_uint32 reserved7:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved8:16; + wpt_uint32 frag5BdIdx:16; +#else + wpt_uint32 frag5BdIdx:16; + wpt_uint32 reserved8:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved9:16; + wpt_uint32 frag6BdIdx:16; +#else + wpt_uint32 frag6BdIdx:16; + wpt_uint32 reserved9:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved10:16; + wpt_uint32 frag7BdIdx:16; +#else + wpt_uint32 frag7BdIdx:16; + wpt_uint32 reserved10:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved11:16; + wpt_uint32 frag8BdIdx:16; +#else + wpt_uint32 frag8BdIdx:16; + wpt_uint32 reserved11:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved12:16; + wpt_uint32 frag9BdIdx:16; +#else + wpt_uint32 frag9BdIdx:16; + wpt_uint32 reserved12:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved13:16; + wpt_uint32 frag10BdIdx:16; +#else + wpt_uint32 frag10BdIdx:16; + wpt_uint32 reserved13:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved14:16; + wpt_uint32 frag11BdIdx:16; +#else + wpt_uint32 frag11BdIdx:16; + wpt_uint32 reserved14:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved15:16; + wpt_uint32 frag12BdIdx:16; +#else + wpt_uint32 frag12BdIdx:16; + wpt_uint32 reserved15:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved16:16; + wpt_uint32 frag13BdIdx:16; +#else + wpt_uint32 frag13BdIdx:16; + wpt_uint32 reserved16:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag14BdIdx:16; + wpt_uint32 reserved17:16; +#else + wpt_uint32 frag14BdIdx:16; + wpt_uint32 reserved17:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag15BdIdx:16; + wpt_uint32 reserved18:16; +#else + wpt_uint32 frag15BdIdx:16; + wpt_uint32 reserved18:16; +#endif + +} WDI_RxDeFragBdType; + +#endif /*WLAN_QCT_WDI_BD_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h new file mode 100644 index 0000000000000..df53d15a04124 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_CFG_H +#define WLAN_QCT_WDI_CFG_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + C O N F I G U R A T I O N D E F I N E S + E X T E R N A L A P I + +DESCRIPTION + This file contains the configuration defines to be used by the UMAC for + setting up the config parameters in DAL. + + !! The values in here should be an identical match of the HAL defines + by the same name !! +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +/*------------------------------------------------------------------------- + Preprocessor definitions and constants +-------------------------------------------------------------------------*/ +#define WDI_MAX_CFG_LENGTH 0x06 + +/*------------------------------------------------------------------------- + Configuration Parameter IDs +-------------------------------------------------------------------------*/ +#define WDI_CFG_STA_ID 0 +#define WDI_CFG_CURRENT_TX_ANTENNA 1 +#define WDI_CFG_CURRENT_RX_ANTENNA 2 +#define WDI_CFG_LOW_GAIN_OVERRIDE 3 +#define WDI_CFG_POWER_STATE_PER_CHAIN 4 +#define WDI_CFG_CAL_PERIOD 5 +#define WDI_CFG_CAL_CONTROL 6 +#define WDI_CFG_PROXIMITY 7 +#define WDI_CFG_NETWORK_DENSITY 8 +#define WDI_CFG_MAX_MEDIUM_TIME 9 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU 10 +#define WDI_CFG_RTS_THRESHOLD 11 +#define WDI_CFG_SHORT_RETRY_LIMIT 12 +#define WDI_CFG_LONG_RETRY_LIMIT 13 +#define WDI_CFG_FRAGMENTATION_THRESHOLD 14 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO 15 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE 16 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO 17 +#define WDI_CFG_FIXED_RATE 18 +#define WDI_CFG_RETRYRATE_POLICY 19 +#define WDI_CFG_RETRYRATE_SECONDARY 20 +#define WDI_CFG_RETRYRATE_TERTIARY 21 +#define WDI_CFG_FORCE_POLICY_PROTECTION 22 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ 23 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ 24 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ 25 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ 26 +#define WDI_CFG_MAX_BA_SESSIONS 27 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT 28 +#define WDI_CFG_PS_ENABLE_BCN_FILTER 29 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE 31 +#define WDI_CFG_STATS_PERIOD 32 +#define WDI_CFG_CFP_MAX_DURATION 33 + +/*------------------------------------------------------------------------- + Configuration Parameter min, max, defaults +-------------------------------------------------------------------------*/ + +/* WDI_CFG_CURRENT_TX_ANTENNA */ +#define WDI_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define WDI_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define WDI_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +/* WDI_CFG_CURRENT_RX_ANTENNA */ +#define WDI_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define WDI_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define WDI_CFG_CURRENT_RX_ANTENNA_STADEF 1 + +/* WDI_CFG_LOW_GAIN_OVERRIDE */ +#define WDI_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define WDI_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define WDI_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +/* WDI_CFG_POWER_STATE_PER_CHAIN */ +#define WDI_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define WDI_CFG_POWER_STATE_PER_CHAIN_STADEF 785 +#define WDI_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define WDI_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define WDI_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define WDI_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +/* WDI_CFG_CAL_PERIOD */ +#define WDI_CFG_CAL_PERIOD_STAMIN 2 +#define WDI_CFG_CAL_PERIOD_STAMAX 10 +#define WDI_CFG_CAL_PERIOD_STADEF 5 + +/* WDI_CFG_CAL_CONTROL */ +#define WDI_CFG_CAL_CONTROL_STAMIN 0 +#define WDI_CFG_CAL_CONTROL_STAMAX 1 +#define WDI_CFG_CAL_CONTROL_STADEF 0 + +/* WDI_CFG_PROXIMITY */ +#define WDI_CFG_PROXIMITY_STAMIN 0 +#define WDI_CFG_PROXIMITY_STAMAX 1 +#define WDI_CFG_PROXIMITY_STADEF 0 +#define WDI_CFG_PROXIMITY_OFF 0 +#define WDI_CFG_PROXIMITY_ON 1 + +/* WDI_CFG_NETWORK_DENSITY */ +#define WDI_CFG_NETWORK_DENSITY_STAMIN 0 +#define WDI_CFG_NETWORK_DENSITY_STAMAX 3 +#define WDI_CFG_NETWORK_DENSITY_STADEF 3 +#define WDI_CFG_NETWORK_DENSITY_LOW 0 +#define WDI_CFG_NETWORK_DENSITY_MEDIUM 1 +#define WDI_CFG_NETWORK_DENSITY_HIGH 2 +#define WDI_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +/* WDI_CFG_MAX_MEDIUM_TIME */ +#define WDI_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define WDI_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define WDI_CFG_MAX_MEDIUM_TIME_STADEF 1024 + +/* WDI_CFG_MAX_MPDUS_IN_AMPDU */ +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +/* WDI_CFG_RTS_THRESHOLD */ +#define WDI_CFG_RTS_THRESHOLD_STAMIN 0 +#define WDI_CFG_RTS_THRESHOLD_STAMAX 2347 +#define WDI_CFG_RTS_THRESHOLD_STADEF 2347 + +/* WDI_CFG_SHORT_RETRY_LIMIT */ +#define WDI_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define WDI_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define WDI_CFG_SHORT_RETRY_LIMIT_STADEF 6 + +/* WDI_CFG_LONG_RETRY_LIMIT */ +#define WDI_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define WDI_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define WDI_CFG_LONG_RETRY_LIMIT_STADEF 6 + +/* WDI_CFG_FRAGMENTATION_THRESHOLD */ +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +/* WDI_CFG_DYNAMIC_THRESHOLD_ZERO */ +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 2 + +/* WDI_CFG_DYNAMIC_THRESHOLD_ONE */ +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 4 + +/* WDI_CFG_DYNAMIC_THRESHOLD_TWO */ +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 6 + +/* WDI_CFG_FIXED_RATE */ +#define WDI_CFG_FIXED_RATE_STAMIN 0 +#define WDI_CFG_FIXED_RATE_STAMAX 31 +#define WDI_CFG_FIXED_RATE_STADEF 0 +#define WDI_CFG_FIXED_RATE_AUTO 0 +#define WDI_CFG_FIXED_RATE_1MBPS 1 +#define WDI_CFG_FIXED_RATE_2MBPS 2 +#define WDI_CFG_FIXED_RATE_5_5MBPS 3 +#define WDI_CFG_FIXED_RATE_11MBPS 4 +#define WDI_CFG_FIXED_RATE_6MBPS 5 +#define WDI_CFG_FIXED_RATE_9MBPS 6 +#define WDI_CFG_FIXED_RATE_12MBPS 7 +#define WDI_CFG_FIXED_RATE_18MBPS 8 +#define WDI_CFG_FIXED_RATE_24MBPS 9 +#define WDI_CFG_FIXED_RATE_36MBPS 10 +#define WDI_CFG_FIXED_RATE_48MBPS 11 +#define WDI_CFG_FIXED_RATE_54MBPS 12 +#define WDI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define WDI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define WDI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define WDI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define WDI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define WDI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define WDI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define WDI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define WDI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define WDI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define WDI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define WDI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define WDI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define WDI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define WDI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define WDI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define WDI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO 29 +#define WDI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO 30 +#define WDI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO 31 + +/* WDI_CFG_RETRYRATE_POLICY */ +#define WDI_CFG_RETRYRATE_POLICY_STAMIN 0 +#define WDI_CFG_RETRYRATE_POLICY_STAMAX 255 +#define WDI_CFG_RETRYRATE_POLICY_STADEF 4 +#define WDI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define WDI_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define WDI_CFG_RETRYRATE_POLICY_RESERVED 2 +#define WDI_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define WDI_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define WDI_CFG_RETRYRATE_POLICY_MAX 5 + +/* WDI_CFG_RETRYRATE_SECONDARY */ +#define WDI_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define WDI_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define WDI_CFG_RETRYRATE_SECONDARY_STADEF 0 + +/* WDI_CFG_RETRYRATE_TERTIARY */ +#define WDI_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define WDI_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define WDI_CFG_RETRYRATE_TERTIARY_STADEF 0 + +/* WDI_CFG_FORCE_POLICY_PROTECTION */ +#define WDI_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define WDI_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define WDI_CFG_FORCE_POLICY_PROTECTION_STADEF 5 +#define WDI_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define WDI_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define WDI_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define WDI_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define WDI_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define WDI_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +/* WDI_CFG_FIXED_RATE_MULTICAST_24GHZ */ +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX 31 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF 1 + +/* WDI_CFG_FIXED_RATE_MULTICAST_5GHZ */ +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX 31 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF 5 + +/* WDI_CFG_DEFAULT_RATE_INDEX_24GHZ */ +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX 31 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF 1 + +/* WDI_CFG_DEFAULT_RATE_INDEX_5GHZ */ +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX 11 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF 5 + +/* WDI_CFG_MAX_BA_SESSIONS */ +#define WDI_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define WDI_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define WDI_CFG_MAX_BA_SESSIONS_STADEF 16 + +/* WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT */ +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +/* WDI_CFG_PS_ENABLE_BCN_FILTER */ +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +/* WDI_CFG_PS_ENABLE_RSSI_MONITOR */ +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 1 + +/* WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +/* WDI_CFG_STATS_PERIOD */ +#define WDI_CFG_STATS_PERIOD_STAMIN 1 +#define WDI_CFG_STATS_PERIOD_STAMAX 10 +#define WDI_CFG_STATS_PERIOD_STADEF 10 + +/* WDI_CFG_CFP_MAX_DURATION */ +#define WDI_CFG_CFP_PERIOD_STAMIN 0 +#define WDI_CFG_CFP_PERIOD_STAMAX 255 +#define WDI_CFG_CFP_PERIOD_STADEF 1 + +#endif /*WLAN_QCT_WDI_CFG_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h new file mode 100644 index 0000000000000..07f737a4b4fe5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef WLAN_QCT_WDI_DP_H +#define WLAN_QCT_WDI_DP_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + D A T A P A T H + + +DESCRIPTION + This file contains the internal API exposed by the DAL Control Path Core + module to be used by the DAL Data Path Core. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_bd.h" + +/*========================================================================= + BD Macro Defines +=========================================================================*/ + +/*-------------------------------------------------------------------------- + BD Definitions used by the DAL data path +--------------------------------------------------------------------------*/ +#define WDI_TXBD_BDRATE_DEFAULT 0 +#define WDI_TXBD_BDRATE_FIRST 1 +#define WDI_TXBD_BDRATE_SECOND 2 +#define WDI_TXBD_BDRATE_THIRD 3 + +#define WDI_FRAME_TYPE_MASK 0x30 +#define WDI_FRAME_TYPE_OFFSET 0x4 +#define WDI_FRAME_SUBTYPE_MASK 0x0F + +#define WDI_TXBD_BD_SSN_FILL_HOST 0 +#define WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS 1 +#define WDI_TXBD_BD_SSN_FILL_DPU_QOS 2 + +#define WDI_ACKPOLICY_ACK_REQUIRED 0 +#define WDI_ACKPOLICY_ACK_NOTREQUIRED 1 + +#define WDI_BDRATE_BCDATA_FRAME 1 +#define WDI_BDRATE_BCMGMT_FRAME 2 +#define WDI_BDRATE_CTRL_FRAME 3 + +/* Default values for FillTx BD */ +#define WDI_DEFAULT_UNICAST_ENABLED 1 +#define WDI_RMF_DISABLED 0 +#define WDI_RMF_ENABLED 1 +#define WDI_NO_ENCRYPTION_DISABLED 0 +#define WDI_NO_ENCRYPTION_ENABLED 1 + +#define WDI_RX_BD_ADDR3_SELF_IDX 0 + +#define WDI_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. +#define WDI_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. +#define WDI_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(LIBRA_WAPI_SUPPORT) +#define WDI_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + +#define WDI_TRIGGER_ENABLED_AC_MASK 0x10 //bit 4 for data frames belonging to trigger enabled AC +#define WDI_USE_NO_ACK_REQUESTED_MASK 0x20 + +#define WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames + +#ifdef FEATURE_WLAN_TDLS +#define HAL_TDLS_PEER_STA_MASK 0x80 //bit 7 set for TDLS peer station +#endif + +/*Macro for getting the size of the TX BD*/ +#define WDI_TX_BD_HEADER_SIZE sizeof(WDI_TxBdType) + +/*Macro for getting the size of the RX BD*/ +#define WDI_RX_BD_HEADER_SIZE sizeof(WDI_RxBdType) + +#define WDI_RX_BD_HEADER_OFFSET 0 + +#define WDI_DPU_FEEDBACK_OFFSET 1 + +// Frame Type definitions + +#define WDI_MAC_MGMT_FRAME 0x0 +#define WDI_MAC_CTRL_FRAME 0x1 +#define WDI_MAC_DATA_FRAME 0x2 + +// Data frame subtype definitions +#define WDI_MAC_DATA_DATA 0 +#define WDI_MAC_DATA_DATA_ACK 1 +#define WDI_MAC_DATA_DATA_POLL 2 +#define WDI_MAC_DATA_DATA_ACK_POLL 3 +#define WDI_MAC_DATA_NULL 4 +#define WDI_MAC_DATA_NULL_ACK 5 +#define WDI_MAC_DATA_NULL_POLL 6 +#define WDI_MAC_DATA_NULL_ACK_POLL 7 +#define WDI_MAC_DATA_QOS_DATA 8 +#define WDI_MAC_DATA_QOS_DATA_ACK 9 +#define WDI_MAC_DATA_QOS_DATA_POLL 10 +#define WDI_MAC_DATA_QOS_DATA_ACK_POLL 11 +#define WDI_MAC_DATA_QOS_NULL 12 +#define WDI_MAC_DATA_QOS_NULL_ACK 13 +#define WDI_MAC_DATA_QOS_NULL_POLL 14 +#define WDI_MAC_DATA_QOS_NULL_ACK_POLL 15 + +#define WDI_MAC_FRAME_SUBTYPE_START 0 +#define WDI_MAC_FRAME_SUBTYPE_END 16 + +#define WDI_MAC_DATA_QOS_MASK 8 +#define WDI_MAC_DATA_NULL_MASK 4 +#define WDI_MAC_DATA_POLL_MASK 2 +#define WDI_MAC_DATA_ACK_MASK 1 + +// Management frame subtype definitions + +#define WDI_MAC_MGMT_ASSOC_REQ 0x0 +#define WDI_MAC_MGMT_ASSOC_RSP 0x1 +#define WDI_MAC_MGMT_REASSOC_REQ 0x2 +#define WDI_MAC_MGMT_REASSOC_RSP 0x3 +#define WDI_MAC_MGMT_PROBE_REQ 0x4 +#define WDI_MAC_MGMT_PROBE_RSP 0x5 +#define WDI_MAC_MGMT_BEACON 0x8 +#define WDI_MAC_MGMT_ATIM 0x9 +#define WDI_MAC_MGMT_DISASSOC 0xA +#define WDI_MAC_MGMT_AUTH 0xB +#define WDI_MAC_MGMT_DEAUTH 0xC +#define WDI_MAC_MGMT_ACTION 0xD +#define WDI_MAC_MGMT_RESERVED15 0xF + +// Action frame categories + +#define WDI_MAC_ACTION_SPECTRUM_MGMT 0 +#define WDI_MAC_ACTION_QOS_MGMT 1 +#define WDI_MAC_ACTION_DLP 2 +#define WDI_MAC_ACTION_BLKACK 3 +#define WDI_MAC_ACTION_HT 7 +#define WDI_MAC_ACTION_WME 17 + +// QoS management action codes + +#define WDI_MAC_QOS_ADD_TS_REQ 0 +#define WDI_MAC_QOS_ADD_TS_RSP 1 +#define WDI_MAC_QOS_DEL_TS_REQ 2 +#define WDI_MAC_QOS_SCHEDULE 3 +// and these are proprietary +#define WDI_MAC_QOS_DEF_BA_REQ 4 +#define WDI_MAC_QOS_DEF_BA_RSP 5 +#define WDI_MAC_QOS_DEL_BA_REQ 6 +#define WDI_MAC_QOS_DEL_BA_RSP 7 + +#ifdef WLAN_PERF +/* TxBD signature fields + * serial(8): a monotonically increasing serial # whenever there is a Add/Del STA or Add/Del Key event + * macHash(16): Hash value of DA + * tid(4): TID + * ucast(1): Unicast or Broadcast data frame + */ +#define WDI_TXBD_SIG_SERIAL_OFFSET 0 +#define WDI_TXBD_SIG_TID_OFFSET 8 +#define WDI_TXBD_SIG_UCAST_DATA_OFFSET 9 +#define WDI_TXBD_SIG_MACADDR_HASH_OFFSET 16 +#define WDI_TXBD_SIG_MGMT_MAGIC 0xbdbdbdbd + +#endif + +/*-------------------------------------------------------------------------- + BD header macros - used by the data path to get or set various values + inside the packet BD +--------------------------------------------------------------------------*/ +#define WDI_RX_BD_GET_MPDU_H_OFFSET( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduHeaderOffset) + +#define WDI_RX_BD_GET_MPDU_D_OFFSET( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduDataOffset) + +#define WDI_RX_BD_GET_MPDU_LEN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduLength) + +#define WDI_RX_BD_GET_MPDU_H_LEN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduHeaderLength) + + +#define WDI_RX_BD_GET_FT( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->ft) + +#define WDI_RX_BD_GET_DPU_FEEDBACK( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuFeedback) + +#define WDI_RX_BD_GET_RX_CHANNEL( _pvBDHeader ) \ + (( (((WDI_RxBdType*)_pvBDHeader)->reserved0) << 4) | (((WDI_RxBdType*)_pvBDHeader)->rxChannel)) + +#define WDI_FRAME_TYPE_MASK 0x30 +#define WDI_FRAME_TYPE_OFFSET 0x4 +#define WDI_FRAME_SUBTYPE_MASK 0x0F + +#define WDI_RX_BD_GET_SUBTYPE( _pvBDHeader ) ((((WDI_RxBdType*)_pvBDHeader)->frameTypeSubtype) & WDI_FRAME_SUBTYPE_MASK) + +#define WDI_RX_BD_GET_TYPE( _pvBDHeader ) (((((WDI_RxBdType*)_pvBDHeader)->frameTypeSubtype) & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET) + +#define WDI_RX_BD_GET_RTSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rtsf) + +#define WDI_RX_BD_GET_BSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->bsf) + +#define WDI_RX_BD_GET_SCAN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->scanLearn) + +#define WDI_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuSignature) + +#define WDI_RX_BD_GET_NE( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuNE) + +#define WDI_RX_BD_GET_LLCR( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->llcr) + +#define WDI_RX_BD_GET_TIMESTAMP( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mclkRxTimestamp) + +#define WDI_RX_BD_GET_RXPFLAGS( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rxpFlags) + +#define WDI_RX_BD_GET_RATEINDEX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rateIndex) + +#define WDI_RX_BD_GET_AMSDU_SIZE( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->totalMsduSize) + +#define WDI_RX_BD_GET_LLC( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->llc) + +#define WDI_RX_BD_GET_TID( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->tid) + +#define WDI_RX_BD_GET_RFBAND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rfBand) + +#define WDI_RX_BD_GET_ASF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->asf) + +#define WDI_RX_BD_GET_AEF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->aef) + +#define WDI_RX_BD_GET_LSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->lsf) + +#define WDI_RX_BD_GET_ESF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->esf) + +#define WDI_RX_BD_GET_STA_ID( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr2Index) +#define WDI_RX_BD_GET_UB( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->ub) +#define WDI_RX_BD_GET_ADDR3_IDX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr3Index) +#define WDI_RX_BD_GET_ADDR1_IDX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr1Index) + +#define WDI_TX_BD_GET_TID( _pvBDHeader ) (((WDI_TxBdType*)_pvBDHeader)->tid) +#define WDI_TX_BD_GET_STA_ID( _pvBDHeader ) (((WDI_TxBdType*)_pvBDHeader)->staIndex) + +#define WDI_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuSignature) + +//flow control related. +#define WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fcStaTxDisabledBitmap) +#define WDI_RX_FC_BD_GET_FC( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fc) +#define WDI_RX_FC_BD_GET_STA_VALID_MASK( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fcSTAValidMask) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +//LFR scan related +#define WDI_RX_BD_GET_OFFLOADSCANLEARN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->offloadScanLearn) +#define WDI_RX_BD_GET_ROAMCANDIDATEIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->roamCandidateInd) +#endif + +/*------------ RSSI and SNR Information extraction -------------*/ +#define WDI_RX_BD_GET_RSSI0( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 24) & 0xff) +#define WDI_RX_BD_GET_RSSI1( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 16) & 0xff) +#define WDI_RX_BD_GET_RSSI2( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 0) & 0xff) +#define WDI_RX_BD_GET_RSSI3( _pvBDHeader ) \ + ((((WDI_RxBdType*)_pvBDHeader)->phyStats0) & 0xff) + +// Get the average of the 4 values. +#define WDI_GET_RSSI_AVERAGE( _pvBDHeader ) \ + (((WDI_RX_BD_GET_RSSI0(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI1(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI2(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI3(_pvBDHeader))) / 4) + +// Get the SNR value from PHY Stats +#define WDI_RX_BD_GET_SNR( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats1) >> 24) & 0xff) +/*-----------------------------------------------------------------*/ + +#define WDI_TX_BD_SET_MPDU_DATA_OFFSET( _bd, _off ) (((WDI_TxBdType*)_bd)->mpduDataOffset = _off) + +#define WDI_TX_BD_SET_MPDU_HEADER_OFFSET( _bd, _off ) (((WDI_TxBdType*)_bd)->mpduHeaderOffset = _off) + +#define WDI_TX_BD_SET_MPDU_HEADER_LEN( _bd, _len ) (((WDI_TxBdType*)_bd)->mpduHeaderLength = _len) + +#define WDI_TX_BD_SET_MPDU_LEN( _bd, _len ) (((WDI_TxBdType*)_bd)->mpduLength = _len) + +#define WDI_RX_BD_GET_BA_OPCODE(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderOpcode) + +#define WDI_RX_BD_GET_BA_FI(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderFwdIdx) + +#define WDI_RX_BD_GET_BA_SI(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderSlotIdx) + +#define WDI_RX_BD_GET_BA_CSN(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->currentPktSeqNo) + +#define WDI_RX_BD_GET_BA_ESN(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->expectedPktSeqNo) + +#define WDI_RX_BD_GET_RXP_FLAGS(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->rxpFlags) + +#define WDI_RX_BD_GET_PMICMD_20TO23(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->pmiCmd4to23[4]) + +#define WDI_RX_BD_GET_PMICMD_24TO25(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->pmiCmd24to25) + +#ifdef WLAN_FEATURE_11W +#define WDI_RX_BD_GET_RMF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rmf) +#endif + +#define WDI_RX_BD_ASF_SET 1 /*The value of the field when set and pkt is AMSDU*/ + +#define WDI_RX_BD_FSF_SET 1 + +#define WDI_RX_BD_LSF_SET 1 + +#define WDI_RX_BD_AEF_SET 1 + + +#define WDI_RX_BD_LLC_PRESENT 0 /*The value of the field when LLC is present*/ + +#define WDI_RX_BD_FT_DONE 1 /* The value of the field when frame xtl was done*/ + +/*========================================================================= + API Definition +=========================================================================*/ + + +/** + @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path + to retrieve the type/subtype of the received frame. + + @param pvBDHeader: Void pointer to the RxBD buffer. + usFrmCtrl: the frame ctrl of the 802.11 header + + @return A byte which contains both type and subtype info. LSB four bytes + (b0 to b3)is subtype and b5-b6 is type info. +*/ + +wpt_uint8 +WDI_RxBD_GetFrameTypeSubType +( + void* _pvBDHeader, + wpt_uint16 usFrmCtrl +); + + +/** + @brief WDI_FillTxBd - Called by the data path to fill the TX BD + + @param pWDICtx: Context to the WDI + ucTypeSubtype: of the frame + pDestMacAddr: destination MAC address + pTid: pointer to the TID (in/out value in case DAL Ctrl causes + a TID downgrade - not done for now) + ucDisableFrmXtl: set to 1 if this frame is not to be translated by HW + pTxBd: pointer to the TX BD + ucTxFlag: can have appropriate bit setting as required + ucProtMgmtFrame: for management frames, whether the frame is + protected (protect bit is set in FC) + uTimestamp: pkt timestamp + + + @return success or not +*/ + +WDI_Status +WDI_FillTxBd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucTypeSubtype, + void* pDestMacAddr, + void* pAddr2, + wpt_uint8* pTid, + wpt_uint8 ucDisableFrmXtl, + void* pTxBd, + wpt_uint32 ucTxFlag, + wpt_uint8 ucProtMgmtFrame, + wpt_uint32 uTimeStamp, + wpt_uint8* staIndex +); + +/** + @brief WDI_SwapRxBd swaps the RX BD. + + + @param pBd - pointer to the BD (in/out) + + @return None +*/ +void +WDI_SwapRxBd +( + wpt_uint8 *pBd +); + +/** + @brief WDI_SwapTxBd - Swaps the TX BD + + @param pBd - pointer to the BD (in/out) + + @return none +*/ +void +WDI_SwapTxBd +( + wpt_uint8 *pBd +); + +/** + @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU + + + @param pWDICtx: Context to the WDI + pBDHeader - pointer to the BD header + + @return None +*/ +void +WDI_RxAmsduBdFix +( + WDI_ControlBlockType* pWDICtx, + void* pBDHeader +); + +#ifdef WLAN_PERF +/** + @brief WDI_TxBdFastFwd - evaluates if a frame can be fast + forwarded + + @param pWDICtx: Context to the WDI + pDestMac: Destination MAC + ucTid: packet TID pBDHeader + ucUnicastDst: is packet unicast + pTxBd: pointer to the BD header + usMpduLength: len + + @return 1 - if the frame can be fast fwd-ed ; 0 if not +*/ +wpt_uint32 +WDI_TxBdFastFwd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pDestMac, + wpt_uint8 ucTid, + wpt_uint8 ucUnicastDst, + void* pTxBd, + wpt_uint16 usMpduLength); +#endif /*WLAN_PERF*/ + +/** + @brief WDI_DP_UtilsInit - Intializes the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsInit +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_DP_UtilsExit - Clears the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsExit +( + WDI_ControlBlockType* pWDICtx +); + +#endif /*WLAN_QCT_WDI_DP_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_i.h new file mode 100644 index 0000000000000..6f15947d4a5d9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_i.h @@ -0,0 +1,5589 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef WLAN_QCT_WDI_I_H +#define WLAN_QCT_WDI_I_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + D A T A P A T H + + +DESCRIPTION + This file contains the internal API exposed by the DAL Control Path Core + module to be used by the DAL Data Path Core. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/05/11 hap Adding support for Keep Alive +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_list.h" +#include "wlan_qct_pal_sync.h" +#include "wlan_qct_pal_timer.h" +#include "wlan_qct_wdi_cts.h" +#include "wlan_qct_wdi_bd.h" + +#include "wlan_hal_msg.h" +#include "wlan_status_code.h" +#include "wlan_qct_dev_defs.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*Assert macro - redefined for WDI so it is more flexible in disabling*/ +#define WDI_ASSERT(_cond) WPAL_ASSERT(_cond) + +/*Error codes that can be returned by WDI - the HAL Error codes are not + propagated outside WDI because they are too explicit when refering to RIVA + HW errors - they are masked under dev internal failure*/ +#define WDI_ERR_BASIC_OP_FAILURE 0 +#define WDI_ERR_TRANSPORT_FAILURE 1 +#define WDI_ERR_INVALID_RSP_FMT 2 +#define WDI_ERR_RSP_TIMEOUT 3 +#define WDI_ERR_DEV_INTERNAL_FAILURE 4 + +/*In prima 12 HW stations are supported including BCAST STA(staId 0) + and SELF STA(staId 1) so total ASSOC stations which can connect to Prima + SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. */ + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDI_MAX_SUPPORTED_STAS 41 +#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 32 +#else +#define WDI_MAX_SUPPORTED_STAS 12 +#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 11 +#endif +#define WDI_MAX_SUPPORTED_BSS 5 + +/* Control transport channel size*/ +#define WDI_CT_CHANNEL_SIZE 4096 + +/*Invalid BSS index ! TO DO: Must come from the HAL header file*/ +#define WDI_BSS_INVALID_IDX 0xFF + +#define WDI_FTM_MAX_RECEIVE_BUFFER 6500 + +/*--------------------------------------------------------------------------- + DAL Control Path Main States +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Transition in this state made upon creation and when a close request is + received*/ + WDI_INIT_ST = 0, + + /* Transition happens after a Start response was received from HAL (as a + result of a previously sent HAL Request)*/ + WDI_STARTED_ST, + + /* Transition happens when a Stop request was received */ + WDI_STOPPED_ST, + + /* Transition happens when a request is being sent down to HAL and we are + waiting for the response */ + WDI_BUSY_ST, + + /* Transition happens when 'SSR' shutdown request is recieved.*/ + WDI_SHUTDOWN_ST, + + WDI_MAX_ST +}WDI_MainStateType; + + +/*--------------------------------------------------------------------------- + DAL Control Path Scan States +---------------------------------------------------------------------------*/ +typedef enum +{ + /*The flag will be set to this state when init is called. Once the flag has + this value the only two scanning API calls allowed are Scan Start and + Scan Finished*/ + WDI_SCAN_INITIALIZED_ST = 0, + + /*The flag will be set to this value once the Start Scan API is called. + When the flag has this value only Scan End API will be allowed. */ + WDI_SCAN_STARTED_ST = 1, + + /*The flag will be set to this value when End Scan API is called. When the + flag is set to this value the only two Scan APIs allowed are Start and + Finish. */ + WDI_SCAN_ENDED_ST = 2, + + /*The flag will be set to this value in the beginning before init is called + and after the Finish API is called. No other scan APIs will be allowed + in this state until Scan Init is called again. */ + WDI_SCAN_FINISHED_ST = 3, + + WDI_SCAN_MAX_ST +}WDI_ScanStateType; + +/*--------------------------------------------------------------------------- + WLAN DAL BSS Session Type - used to allow simulatneous association + and keep track of each associated session + ---------------------------------------------------------------------------*/ +#define WDI_MAX_BSS_SESSIONS 10 + +typedef enum +{ + /*Init state*/ + WDI_ASSOC_INIT_ST, + + /*Joining State*/ + WDI_ASSOC_JOINING_ST, + + /*Associated state*/ + WDI_ASSOC_POST_ST, + + WDI_ASSOC_MAX_ST +}WDI_AssocStateType; + +/*--------------------------------------------------------------------------- + WLAN DAL Supported Request Types + ---------------------------------------------------------------------------*/ +typedef enum +{ + /*WLAN DAL START Request*/ + WDI_START_REQ = 0, + + /*WLAN DAL STOP Request*/ + WDI_STOP_REQ = 1, + + /*WLAN DAL STOP Request*/ + WDI_CLOSE_REQ = 2, + + + /*SCAN*/ + /*WLAN DAL Init Scan Request*/ + WDI_INIT_SCAN_REQ = 3, + + /*WLAN DAL Start Scan Request*/ + WDI_START_SCAN_REQ = 4, + + /*WLAN DAL End Scan Request*/ + WDI_END_SCAN_REQ = 5, + + /*WLAN DAL Finish Scan Request*/ + WDI_FINISH_SCAN_REQ = 6, + + + /*ASSOCIATION*/ + /*WLAN DAL Join Request*/ + WDI_JOIN_REQ = 7, + + /*WLAN DAL Config BSS Request*/ + WDI_CONFIG_BSS_REQ = 8, + + /*WLAN DAL Del BSS Request*/ + WDI_DEL_BSS_REQ = 9, + + /*WLAN DAL Post Assoc Request*/ + WDI_POST_ASSOC_REQ = 10, + + /*WLAN DAL Del STA Request*/ + WDI_DEL_STA_REQ = 11, + + /*Security*/ + /*WLAN DAL Set BSS Key Request*/ + WDI_SET_BSS_KEY_REQ = 12, + + /*WLAN DAL Remove BSS Key Request*/ + WDI_RMV_BSS_KEY_REQ = 13, + + /*WLAN DAL Set STA Key Request*/ + WDI_SET_STA_KEY_REQ = 14, + + /*WLAN DAL Remove STA Key Request*/ + WDI_RMV_STA_KEY_REQ = 15, + + /*QOS and BA*/ + /*WLAN DAL Add TSpec Request*/ + WDI_ADD_TS_REQ = 16, + + /*WLAN DAL Delete TSpec Request*/ + WDI_DEL_TS_REQ = 17, + + /*WLAN DAL Update EDCA Params Request*/ + WDI_UPD_EDCA_PRMS_REQ = 18, + + /*WLAN DAL Add BA Session Request*/ + WDI_ADD_BA_SESSION_REQ = 19, + + /*WLAN DAL Delete BA Request*/ + WDI_DEL_BA_REQ = 20, + + /* Miscellaneous Control */ + /*WLAN DAL Channel Switch Request*/ + WDI_CH_SWITCH_REQ = 21, + + /*WLAN DAL Config STA Request*/ + WDI_CONFIG_STA_REQ = 22, + + /*WLAN DAL Set Link State Request*/ + WDI_SET_LINK_ST_REQ = 23, + + /*WLAN DAL Get Stats Request*/ + WDI_GET_STATS_REQ = 24, + + /*WLAN DAL Update Config Request*/ + WDI_UPDATE_CFG_REQ = 25, + + /* WDI ADD BA Request */ + WDI_ADD_BA_REQ = 26, + + /* WDI Trigger BA Request */ + WDI_TRIGGER_BA_REQ = 27, + + /*WLAN DAL Update Beacon Params Request*/ + WDI_UPD_BCON_PRMS_REQ = 28, + + /*WLAN DAL Send Beacon template Request*/ + WDI_SND_BCON_REQ = 29, + + /*WLAN DAL Send Probe Response Template Request*/ + WDI_UPD_PROBE_RSP_TEMPLATE_REQ = 30, + + /*WLAN DAL Set STA Bcast Key Request*/ + WDI_SET_STA_BCAST_KEY_REQ = 31, + + /*WLAN DAL Remove STA Bcast Key Request*/ + WDI_RMV_STA_BCAST_KEY_REQ = 32, + + /*WLAN DAL Set Max Tx Power Request*/ + WDI_SET_MAX_TX_POWER_REQ = 33, + + /* WLAN DAL P2P GO Notice Of Absence Request */ + WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ = 34, + + /*WLAN DAL Enter IMPS Request*/ + WDI_ENTER_IMPS_REQ = 35, + + /*WLAN DAL Exit IMPS Request*/ + WDI_EXIT_IMPS_REQ = 36, + + /*WLAN DAL Enter BMPS Request*/ + WDI_ENTER_BMPS_REQ = 37, + + /*WLAN DAL Exit BMPS Request*/ + WDI_EXIT_BMPS_REQ = 38, + + /*WLAN DAL Enter UAPSD Request*/ + WDI_ENTER_UAPSD_REQ = 39, + + /*WLAN DAL Exit UAPSD Request*/ + WDI_EXIT_UAPSD_REQ = 40, + + /*WLAN DAL Set UAPSD Param Request*/ + WDI_SET_UAPSD_PARAM_REQ = 41, + + /*WLAN DAL Update UAPSD Param (SoftAP mode) Request*/ + WDI_UPDATE_UAPSD_PARAM_REQ = 42, + + /*WLAN DAL Configure RXP filter Request*/ + WDI_CONFIGURE_RXP_FILTER_REQ = 43, + + /*WLAN DAL Configure Beacon filter Request*/ + WDI_SET_BEACON_FILTER_REQ = 44, + + /*WLAN DAL Remove Beacon filter Request*/ + WDI_REM_BEACON_FILTER_REQ = 45, + + /*WLAN DAL Set RSSI thresholds Request*/ + WDI_SET_RSSI_THRESHOLDS_REQ = 46, + + /*WLAN DAL host offload Request*/ + WDI_HOST_OFFLOAD_REQ = 47, + + /*WLAN DAL add wowl bc ptrn Request*/ + WDI_WOWL_ADD_BC_PTRN_REQ = 48, + + /*WLAN DAL delete wowl bc ptrn Request*/ + WDI_WOWL_DEL_BC_PTRN_REQ = 49, + + /*WLAN DAL enter wowl Request*/ + WDI_WOWL_ENTER_REQ = 50, + + /*WLAN DAL exit wowl Request*/ + WDI_WOWL_EXIT_REQ = 51, + + /*WLAN DAL Configure Apps CPU Wakeup state Request*/ + WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 52, + + /* WLAN NV Download Request */ + WDI_NV_DOWNLOAD_REQ = 53, + /*WLAN DAL Flush AC Request*/ + WDI_FLUSH_AC_REQ = 54, + + /*WLAN DAL BT AMP event Request*/ + WDI_BTAMP_EVENT_REQ = 55, + /*WLAN DAL Aggregated Add TSpec Request*/ + WDI_AGGR_ADD_TS_REQ = 56, + + WDI_ADD_STA_SELF_REQ = 57, + + WDI_DEL_STA_SELF_REQ = 58, + + /* WLAN FTM Command request */ + WDI_FTM_CMD_REQ = 59, + + /*WLAN START OEM_DATA MEAS Request*/ + WDI_START_OEM_DATA_REQ = 60, + /* WLAN host resume request */ + WDI_HOST_RESUME_REQ = 61, + + WDI_KEEP_ALIVE_REQ = 62, + + /* Set PNO */ + WDI_SET_PREF_NETWORK_REQ = 63, + + /*RSSI Filter Request*/ + WDI_SET_RSSI_FILTER_REQ = 64, + + /* Update Scan Parameters*/ + WDI_UPDATE_SCAN_PARAMS_REQ = 65, + + WDI_SET_TX_PER_TRACKING_REQ = 66, + + WDI_8023_MULTICAST_LIST_REQ = 67, + WDI_RECEIVE_FILTER_SET_FILTER_REQ = 68, + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ = 69, + WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ = 70, + + /*This is temp fix. Should be removed once + * Host and Riva code is in sync*/ + WDI_INIT_SCAN_CON_REQ = 71, + + /* WLAN HAL DUMP Command request */ + WDI_HAL_DUMP_CMD_REQ = 72, + + /* WLAN DAL Shutdown Request */ + WDI_SHUTDOWN_REQ = 73, + + /*Set power parameters on the device*/ + WDI_SET_POWER_PARAMS_REQ = 74, + + /* Traffic Stream Metrics statistic request */ + WDI_TSM_STATS_REQ = 75, + /* GTK Rekey Offload */ + WDI_GTK_OFFLOAD_REQ = 76, + WDI_GTK_OFFLOAD_GETINFO_REQ = 77, + + /*Set Thermal Migration level to RIVA*/ + WDI_SET_TM_LEVEL_REQ = 78, + + /* Send a capability exchange message to HAL */ + WDI_FEATURE_CAPS_EXCHANGE_REQ = 79, + +#ifdef WLAN_FEATURE_11AC + /* Send a capability exchange message to HAL */ + WDI_UPDATE_VHT_OP_MODE_REQ = 80, +#endif + + /*WLAN DAL Get Roam Rssi Request*/ + WDI_GET_ROAM_RSSI_REQ = 81, + + /*WLAN DAL Set Tx Power Request*/ + WDI_SET_TX_POWER_REQ = 82, + WDI_ROAM_SCAN_OFFLOAD_REQ = 83, + + WDI_TDLS_LINK_ESTABLISH_REQ = 84, + + /* WLAN FW LPHB config request */ + WDI_LPHB_CFG_REQ = 85, + + /* WLAN FW set batch scan request */ + WDI_SET_BATCH_SCAN_REQ = 86, + + /*WLAN DAL Set Max Tx Power Per band Request*/ + WDI_SET_MAX_TX_POWER_PER_BAND_REQ = 87, + + WDI_MAX_REQ, + + /*Send a suspend Indication down to HAL*/ + WDI_HOST_SUSPEND_IND = WDI_MAX_REQ , + + /* Send a traffic stats indication to HAL */ + WDI_TRAFFIC_STATS_IND, + + /* DHCP Start Indication */ + WDI_DHCP_START_IND, + + /* DHCP Stop Indication */ + WDI_DHCP_STOP_IND, + + /* Drop/Receive unencrypted frames indication to HAL */ + WDI_EXCLUDE_UNENCRYPTED_IND, + + /* Send an add periodic Tx pattern indication to HAL */ + WDI_ADD_PERIODIC_TX_PATTERN_IND, + + /* Send a delete periodic Tx pattern indicationto HAL */ + WDI_DEL_PERIODIC_TX_PATTERN_IND, + + /* Send Rate Update Indication */ + WDI_RATE_UPDATE_IND, + + /*Send stop batch scan indication to FW*/ + WDI_STOP_BATCH_SCAN_IND, + /*Send stop batch scan indication to FW*/ + WDI_TRIGGER_BATCH_SCAN_RESULT_IND, + + /*Keep adding the indications to the max request + such that we keep them sepparate */ + + WDI_MAX_UMAC_IND +}WDI_RequestEnumType; + +/*--------------------------------------------------------------------------- + WLAN DAL Supported Response Types + ---------------------------------------------------------------------------*/ +typedef enum +{ + /*WLAN DAL START Response*/ + WDI_START_RESP = 0, + + /*WLAN DAL STOP Response*/ + WDI_STOP_RESP = 1, + + /*WLAN DAL STOP Response*/ + WDI_CLOSE_RESP = 2, + + /*SCAN*/ + /*WLAN DAL Init Scan Response*/ + WDI_INIT_SCAN_RESP = 3, + + /*WLAN DAL Start Scan Response*/ + WDI_START_SCAN_RESP = 4, + + /*WLAN DAL End Scan Response*/ + WDI_END_SCAN_RESP = 5, + + /*WLAN DAL Finish Scan Response*/ + WDI_FINISH_SCAN_RESP = 6, + + + /*ASSOCIATION*/ + /*WLAN DAL Join Response*/ + WDI_JOIN_RESP = 7, + + /*WLAN DAL Config BSS Response*/ + WDI_CONFIG_BSS_RESP = 8, + + /*WLAN DAL Del BSS Response*/ + WDI_DEL_BSS_RESP = 9, + + /*WLAN DAL Post Assoc Response*/ + WDI_POST_ASSOC_RESP = 10, + + /*WLAN DAL Del STA Response*/ + WDI_DEL_STA_RESP = 11, + + /*WLAN DAL Set BSS Key Response*/ + WDI_SET_BSS_KEY_RESP = 12, + + /*WLAN DAL Remove BSS Key Response*/ + WDI_RMV_BSS_KEY_RESP = 13, + + /*WLAN DAL Set STA Key Response*/ + WDI_SET_STA_KEY_RESP = 14, + + /*WLAN DAL Remove STA Key Response*/ + WDI_RMV_STA_KEY_RESP = 15, + + /*WLAN DAL Add TSpec Response*/ + WDI_ADD_TS_RESP = 16, + + /*WLAN DAL Delete TSpec Response*/ + WDI_DEL_TS_RESP = 17, + + /*WLAN DAL Update EDCA Params Response*/ + WDI_UPD_EDCA_PRMS_RESP = 18, + + /*WLAN DAL Add BA Session Response*/ + WDI_ADD_BA_SESSION_RESP = 19, + + /*WLAN DAL Delete BA Response*/ + WDI_DEL_BA_RESP = 20, + + /*WLAN DAL Channel Switch Response*/ + WDI_CH_SWITCH_RESP = 21, + + /*WLAN DAL Config STA Response*/ + WDI_CONFIG_STA_RESP = 22, + + /*WLAN DAL Set Link State Response*/ + WDI_SET_LINK_ST_RESP = 23, + + /*WLAN DAL Get Stats Response*/ + WDI_GET_STATS_RESP = 24, + + /*WLAN DAL Update Config Response*/ + WDI_UPDATE_CFG_RESP = 25, + + /* WDI ADD BA Response */ + WDI_ADD_BA_RESP = 26, + + /* WDI Trigger BA Response */ + WDI_TRIGGER_BA_RESP = 27, + + /*WLAN DAL Update beacon params Response*/ + WDI_UPD_BCON_PRMS_RESP = 28, + + /*WLAN DAL Send beacon template Response*/ + WDI_SND_BCON_RESP = 29, + + /*WLAN DAL Update Probe Response Template Response*/ + WDI_UPD_PROBE_RSP_TEMPLATE_RESP = 30, + + /*WLAN DAL Set STA Key Response*/ + WDI_SET_STA_BCAST_KEY_RESP = 31, + + /*WLAN DAL Remove STA Key Response*/ + WDI_RMV_STA_BCAST_KEY_RESP = 32, + + /*WLAN DAL Set Max Tx Power Response*/ + WDI_SET_MAX_TX_POWER_RESP = 33, + + /*WLAN DAL Enter IMPS Response*/ + WDI_ENTER_IMPS_RESP = 34, + + /*WLAN DAL Exit IMPS Response*/ + WDI_EXIT_IMPS_RESP = 35, + + /*WLAN DAL Enter BMPS Response*/ + WDI_ENTER_BMPS_RESP = 36, + + /*WLAN DAL Exit BMPS Response*/ + WDI_EXIT_BMPS_RESP = 37, + + /*WLAN DAL Enter UAPSD Response*/ + WDI_ENTER_UAPSD_RESP = 38, + + /*WLAN DAL Exit UAPSD Response*/ + WDI_EXIT_UAPSD_RESP = 39, + + /*WLAN DAL Set UAPSD Param Response*/ + WDI_SET_UAPSD_PARAM_RESP = 40, + + /*WLAN DAL Update UAPSD Param (SoftAP mode) Response*/ + WDI_UPDATE_UAPSD_PARAM_RESP = 41, + + /*WLAN DAL Configure RXP filter Response*/ + WDI_CONFIGURE_RXP_FILTER_RESP = 42, + + /*WLAN DAL Set Beacon filter Response*/ + WDI_SET_BEACON_FILTER_RESP = 43, + + /*WLAN DAL Remove Beacon filter Response*/ + WDI_REM_BEACON_FILTER_RESP = 44, + + /*WLAN DAL Set RSSI thresholds Response*/ + WDI_SET_RSSI_THRESHOLDS_RESP = 45, + + /*WLAN DAL Set RSSI thresholds Response*/ + WDI_HOST_OFFLOAD_RESP = 46, + + /*WLAN DAL add wowl bc ptrn Response*/ + WDI_WOWL_ADD_BC_PTRN_RESP = 47, + + /*WLAN DAL delete wowl bc ptrn Response*/ + WDI_WOWL_DEL_BC_PTRN_RESP = 48, + + /*WLAN DAL enter wowl Response*/ + WDI_WOWL_ENTER_RESP = 49, + + /*WLAN DAL exit wowl Response*/ + WDI_WOWL_EXIT_RESP = 50, + + /*WLAN DAL Configure Apps CPU Wakeup state Response*/ + WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP = 51, + + /* WLAN NV Download responce */ + WDI_NV_DOWNLOAD_RESP = 52, + + /*WLAN DAL Flush AC Response*/ + WDI_FLUSH_AC_RESP = 53, + + /*WLAN DAL Flush AC Response*/ + WDI_BTAMP_EVENT_RESP = 54, + + /*WLAN DAL Add Aggregated TSpec Response*/ + WDI_AGGR_ADD_TS_RESP = 55, + + /*Add Self STA Response*/ + WDI_ADD_STA_SELF_RESP = 56, + + /*Delete Self STA Response*/ + WDI_DEL_STA_SELF_RESP = 57, + + /*WLAN START OEM_DATA Response*/ + WDI_START_OEM_DATA_RESP = 58, + + /* WLAN host resume request */ + WDI_HOST_RESUME_RESP = 59, + + /* WLAN DAL P2P GO Notice Of Absence Response */ + WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP = 60, + + /* FTM Response from HAL */ + WDI_FTM_CMD_RESP = 61, + + /*Keep alive response */ + WDI_KEEP_ALIVE_RESP = 62, + + /* Set PNO Response */ + WDI_SET_PREF_NETWORK_RESP = 63, + + /* Set RSSI Filter Response */ + WDI_SET_RSSI_FILTER_RESP = 64, + + /* Update Scan Parameters Resp */ + WDI_UPDATE_SCAN_PARAMS_RESP = 65, + + //Tx PER Tracking + WDI_SET_TX_PER_TRACKING_RESP = 66, + + + + /* Packet Filtering Response */ + WDI_8023_MULTICAST_LIST_RESP = 67, + + WDI_RECEIVE_FILTER_SET_FILTER_RESP = 68, + + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP = 69, + + WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP = 70, + + + /* WLAN HAL DUMP Command Response */ + WDI_HAL_DUMP_CMD_RESP = 71, + + /* WLAN Shutdown Response */ + WDI_SHUTDOWN_RESP = 72, + + /*Set power parameters response */ + WDI_SET_POWER_PARAMS_RESP = 73, + + WDI_TSM_STATS_RESP = 74, + /* GTK Rekey Offload */ + WDI_GTK_OFFLOAD_RESP = 75, + WDI_GTK_OFFLOAD_GETINFO_RESP = 76, + + WDI_SET_TM_LEVEL_RESP = 77, + + /* FW sends its capability bitmap as a response */ + WDI_FEATURE_CAPS_EXCHANGE_RESP = 78, + +#ifdef WLAN_FEATURE_11AC + WDI_UPDATE_VHT_OP_MODE_RESP = 79, +#endif + + /* WLAN DAL Get Roam Rssi Response*/ + WDI_GET_ROAM_RSSI_RESP = 80, + + WDI_SET_TX_POWER_RESP = 81, + WDI_ROAM_SCAN_OFFLOAD_RESP = 82, + + WDI_TDLS_LINK_ESTABLISH_REQ_RESP = 83, + + /* WLAN FW LPHB Config response */ + WDI_LPHB_CFG_RESP = 84, + + WDI_SET_BATCH_SCAN_RESP = 85, + + WDI_SET_MAX_TX_POWER_PER_BAND_RSP = 86, + + /*------------------------------------------------------------------------- + Indications + !! Keep these last in the enum if possible + -------------------------------------------------------------------------*/ + WDI_HAL_IND_MIN , + /*When RSSI monitoring is enabled of the Lower MAC and a threshold has been + passed. */ + WDI_HAL_RSSI_NOTIFICATION_IND = WDI_HAL_IND_MIN, + + /*Link loss in the low MAC */ + WDI_HAL_MISSED_BEACON_IND = WDI_HAL_IND_MIN + 1, + + /*When hardware has signaled an unknown addr2 frames. The indication will + contain info from frames to be passed to the UMAC, this may use this info to + deauth the STA*/ + WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = WDI_HAL_IND_MIN + 2, + + /*MIC Failure detected by HW*/ + WDI_HAL_MIC_FAILURE_IND = WDI_HAL_IND_MIN + 3, + + /*Fatal Error Ind*/ + WDI_HAL_FATAL_ERROR_IND = WDI_HAL_IND_MIN + 4, + + /*Received when the RIVA SW decides to autonomously delete an associate + station (e.g. Soft AP TIM based dissassoc) */ + WDI_HAL_DEL_STA_IND = WDI_HAL_IND_MIN + 5, + + /*Coex indication*/ + WDI_HAL_COEX_IND = WDI_HAL_IND_MIN + 6, + + /* Tx Complete Indication */ + WDI_HAL_TX_COMPLETE_IND = WDI_HAL_IND_MIN + 7, + + WDI_HAL_P2P_NOA_ATTR_IND = WDI_HAL_IND_MIN + 8, + + /* Preferred Network Found Indication */ + WDI_HAL_PREF_NETWORK_FOUND_IND = WDI_HAL_IND_MIN + 9, + + /* Wakeup Reason Indication */ + WDI_HAL_WAKE_REASON_IND = WDI_HAL_IND_MIN + 10, + + /* Tx PER Hit Indication */ + WDI_HAL_TX_PER_HIT_IND = WDI_HAL_IND_MIN + 11, + + /* NOA Start Indication from FW to Host */ + WDI_HAL_P2P_NOA_START_IND = WDI_HAL_IND_MIN + 12, + + /* TDLS Indication from FW to Host */ + WDI_HAL_TDLS_IND = WDI_HAL_IND_MIN + 13, + + /* LPHB timeout indication */ + WDI_HAL_LPHB_IND = WDI_HAL_IND_MIN + 14, + + /* IBSS Peer Inactivity Indication from FW to Host */ + WDI_HAL_IBSS_PEER_INACTIVITY_IND = WDI_HAL_IND_MIN + 15, + + /* Periodic Tx Pattern Indication from FW to Host */ + WDI_HAL_PERIODIC_TX_PTRN_FW_IND = WDI_HAL_IND_MIN + 16, + + WDI_BATCHSCAN_RESULT_IND = WDI_HAL_IND_MIN + 17, + + WDI_MAX_RESP +}WDI_ResponseEnumType; + +typedef struct +{ + /*Flag that marks a session as being in use*/ + wpt_boolean bInUse; + + /*Flag that keeps track if a series of assoc requests for this BSS are + currently pending in the queue or processed + - the flag is set to true when the Join request ends up being queued + - and reset to false when the Pending queue is empty */ + wpt_boolean bAssocReqQueued; + + /*BSSID of the session*/ + wpt_macAddr macBSSID; + + /*BSS Index associated with this BSSID*/ + wpt_uint8 ucBSSIdx; + + /*Associated state of the current BSS*/ + WDI_AssocStateType wdiAssocState; + + /*WDI Pending Request Queue*/ + wpt_list wptPendingQueue; + + /*DPU Information for this BSS*/ + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + + /*RMF enabled/disabled*/ + wpt_uint8 ucRmfEnabled; + + /*Bcast STA ID associated with this BSS session */ + wpt_uint8 bcastStaIdx; + + /*The type of the BSS in the session */ + WDI_BssType wdiBssType; +}WDI_BSSSessionType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSRspInfoType +---------------------------------------------------------------------------*/ +typedef WPT_PACK_PRE struct +{ + /*BSS index allocated by HAL*/ + wpt_uint8 ucBSSIdx; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Broadcast DPU descriptor index allocated by HAL and used for + broadcast/multicast packets.*/ + wpt_uint8 ucBcastDpuDescIndx; + + /*DPU signature to be used for broadcast/multicast packets*/ + wpt_uint8 ucBcastDpuSignature; + + /*DPU descriptor index allocated by HAL, used for bcast/mcast management + packets*/ + wpt_uint8 ucMgmtDpuDescIndx; + + /*DPU signature to be used for bcast/mcast management packets*/ + wpt_uint8 ucMgmtDpuSignature; + + /*Status of the request received from HAL */ + eHalStatus halStatus; +}WPT_PACK_POST WDI_ConfigBSSRspInfoType; + + +/*--------------------------------------------------------------------------- + WDI_PostAssocRspInfoType +---------------------------------------------------------------------------*/ +typedef WPT_PACK_PRE struct +{ + /*STA Index allocated by HAL.*/ + wpt_uint16 usSTAIdx; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*HAL Status */ + eHalStatus halStatus; +}WPT_PACK_POST WDI_PostAssocRspInfoType; + +/*--------------------------------------------------------------------------- + WLAN DAL FSM Event Info Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*Events can be linked in a list - put a node in front for that, it will be + used by wpt to link them*/ + wpt_list_node wptListNode; + + /*Request Received */ + WDI_RequestEnumType wdiRequest; + + /*Response Received */ + WDI_ResponseEnumType wdiResponse; + + /*Data associated with the request */ + void* pEventData; + + /*Data Size*/ + wpt_uint32 uEventDataSize; + + /*Callback function for receiving the response to the event*/ + void* pCBfnc; + + /*User data to be sent along with the CB function call*/ + void* pUserData; +}WDI_EventInfoType; + +/*--------------------------------------------------------------------------- + WLAN DAL Session Index Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*Events can be linked in a list - put a node in front for that, it will be + used by wpt to link them*/ + wpt_list_node wptListNode; + + /*Session id for the new association to be processed*/ + wpt_uint8 ucIndex; + +}WDI_NextSessionIdType; + +#define WDI_CONTROL_BLOCK_MAGIC 0x67736887 /* WDIC in little endian */ +/*--------------------------------------------------------------------------- + WLAN DAL Control Block Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*magic number so callbacks can validate their context pointers*/ + wpt_uint32 magic; + + /*Ptr to the OS Context received from the UMAC*/ + void* pOSContext; + + /*Ptr to the PAL Context received from PAL*/ + void* pPALContext; + + /*Ptr to the Datapath Context received from PAL*/ + void* pDPContext; + + /*Ptr to the Datapath Transport Driver Context received from PAL*/ + void* pDTDriverContext; + + /*Hanlde to the control transport service*/ + WCTS_HandleType wctsHandle; + + /*Flag that keeps track if CT is Opened or not*/ + wpt_boolean bCTOpened; + + /*The global state of the DAL Control Path*/ + WDI_MainStateType uGlobalState; + + /*Flag to keep track of the expected state transition after processing + of a response */ + WDI_MainStateType ucExpectedStateTransition; + + /*Main Synchronization Object for the WDI CB*/ + wpt_mutex wptMutex; + + /*WDI response timer*/ + wpt_timer wptResponseTimer; + + /*WDI Pending Request Queue*/ + wpt_list wptPendingQueue; +#if 0 + /*The state of the DAL during a scanning procedure*/ + WDI_ScanStateType uScanState; + + /*Flag that keeps track if a Scan is currently in progress*/ + wpt_boolean bScanInProgress; +#endif + /*Flag that keeps track if an Association is currently in progress*/ + wpt_boolean bAssociationInProgress; + + /*Array of simultaneous BSS Sessions*/ + WDI_BSSSessionType aBSSSessions[WDI_MAX_BSS_SESSIONS]; + + /*WDI Pending Association Session Id Queue - it keeps track of the + order in which queued assoc requests came in*/ + wpt_list wptPendingAssocSessionIdQueue; + + /*! TO DO : - group these in a union, only one cached req can exist at a + time */ + + /*Cached post assoc request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a station if needed */ + WDI_PostAssocReqParamsType wdiCachedPostAssocReq; + + /*Cached config sta request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a station if needed */ + WDI_ConfigSTAReqParamsType wdiCachedConfigStaReq; + + /*Cached config sta request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a BSS if needed */ + WDI_ConfigBSSReqParamsType wdiCachedConfigBssReq; + + /*Cached set link state request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to delete a BSS if needed */ + WDI_SetLinkReqParamsType wdiCacheSetLinkStReq; + + /*Cached add STA self request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save the self STA in the table */ + WDI_AddSTASelfReqParamsType wdiCacheAddSTASelfReq; + + /*Current session being handled*/ + wpt_uint8 ucCurrentBSSSesIdx; + + /*Pointer to the response CB of the pending request*/ + void* pfncRspCB; + + /*Pointer to the user data to be sent along with the response CB*/ + void* pRspCBUserData; + + /*The expected response from HAL*/ + WDI_ResponseEnumType wdiExpectedResponse; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pReqStatusUserData; + + /*Indication callback given by UMAC to be called by the WLAN DAL when it + wishes to send something back independent of a request*/ + WDI_LowLevelIndCBType wdiLowLevelIndCB; + + /*The user data passed in by UMAC, it will be sent back when the indication + function pointer will be called */ + void* pIndUserData; + + /*Cached start response parameters*/ + WDI_StartRspParamsType wdiCachedStartRspParams; + + /* Information related to NV Image*/ + WDI_NvBlobInfoParams wdiNvBlobInfo; + + /*STA Table Information*/ + /*Max number of stations allowed by device */ + wpt_uint8 ucMaxStations; + + /*Max number of BSSes allowed by device */ + wpt_uint8 ucMaxBssids; + + /* Global BSS and STA table - Memory is allocated when needed.*/ + void* staTable; + +#ifndef HAL_SELF_STA_PER_BSS + /*Index of the Self STA */ + wpt_uint8 ucSelfStaId; + + /* Self STA DPU Index */ + wpt_uint16 usSelfStaDpuId; + + /*Self STA Mac*/ + wpt_macAddr macSelfSta; +#endif + + /*Is frame translation enabled */ + wpt_uint8 bFrameTransEnabled; + + /*AMSDU BD Fix Mask - used by the Fixing routine for Data Path */ + WDI_RxBdType wdiRxAmsduBdFixMask; + + /*First AMSDU BD - used by the Fixing routine for Data Path */ + WDI_RxBdType wdiRxAmsduFirstBdCache; + + /*This must be incremented on sta change */ + wpt_uint32 uBdSigSerialNum; + + /* dpu routing flag + ! TO DO: - must be set/reset when PS is enabled for UAPSD */ + wpt_uint8 ucDpuRF; + /* Event to wait for when WCTS is told to perform an action */ + wpt_event wctsActionEvent; + /* Event to wait for ACK from DXE after the power state is set */ + wpt_event setPowerStateEvent; + /* DXE physical addr to be passed down to RIVA. RIVA HAL will use it to program + DXE when DXE wakes up from power save*/ + unsigned int dxePhyAddr; + + /*NV download request parameters */ + WDI_NvDownloadReqParamsType wdiCachedNvDownloadReq; + + /* Driver Type */ + tDriverType driverMode; + + /* Statically allocated FTM Response Buffer */ + wpt_uint8 ucFTMCommandRspBuffer[WDI_FTM_MAX_RECEIVE_BUFFER]; + + /*Driver in BMPS state*/ + wpt_boolean bInBmps; + + /*version of the PNO implementation in RIVA*/ + wpt_uint8 wdiPNOVersion; + + /*SSR timer*/ + wpt_timer ssrTimer; + + /*Version of the WLAN HAL API received on start resp*/ + WDI_WlanVersionType wlanVersion; + + /*timestamp when we start response timer*/ + wpt_uint32 uTimeStampRspTmrStart; + + /*timestamp when we get response timer event*/ + wpt_uint32 uTimeStampRspTmrExp; + + /* enable/disable SSR on WDI timeout */ + wpt_boolean bEnableSSR; +}WDI_ControlBlockType; + + + + +/*--------------------------------------------------------------------------- + + DESCRIPTION + WLAN DAL Request Processing function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_ReqProcFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + + +/*--------------------------------------------------------------------------- + + DESCRIPTION + WLAN DAL Response Processing function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_RspProcFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + + + + +/*========================================================================== + MAIN DAL FSM Definitions and Declarations +==========================================================================*/ + +/*--------------------------------------------------------------------------- + DAL Control Path Main FSM + ---------------------------------------------------------------------------*/ +#define WDI_STATE_TRANSITION(_pctx, _st) (_pctx->uGlobalState = _st) + + + +/*--------------------------------------------------------------------------- + DAL Main Event type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Start request received from UMAC */ + WDI_START_EVENT = 0, + + /* Stop request received from UMAC */ + WDI_STOP_EVENT = 1, + + /* HAL request received from UMAC*/ + WDI_REQUEST_EVENT = 2, + + /* HAL Response received from device */ + WDI_RESPONSE_EVENT = 3, + + /* Close request received from UMAC */ + WDI_CLOSE_EVENT = 4, + + /* Shutdown request received from UMAC */ + WDI_SHUTDOWN_EVENT = 5, + + WDI_MAX_EVENT + +}WDI_MainEventType; + +/*--------------------------------------------------------------------------- + + DESCRIPTION + Main DAL state machine function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_MainFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + +/*--------------------------------------------------------------------------- + MAIN DAL FSM Entry type +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_MainFuncType pfnMainTbl[WDI_MAX_EVENT]; +} WDI_MainFsmEntryType; + +/*Macro to check for valid session id*/ +#define WDI_VALID_SESSION_IDX(_idx) ( _idx < WDI_MAX_BSS_SESSIONS ) + +/*========================================================================== + + DAL INTERNAL FUNCTION DECLARATION + +==========================================================================*/ + +/** + @brief Helper routine for retrieving the PAL Context from WDI - + can be used by CTS, DTS, DXE and othe DAL internals + + @param None + + @see + @return pointer to the context +*/ +void* WDI_GET_PAL_CTX( void ); + +/*--------------------------------------------------------------------------- + MAIN DAL FSM Function Declarations +---------------------------------------------------------------------------*/ +/** + @brief WDI_PostMainEvent - Posts an event to the Main FSM + + + @param pWDICtx: pointer to the WLAN DAL context + wdiEV: event posted to the main DAL FSM + pEventData: pointer to the event information + structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_PostMainEvent +( + WDI_ControlBlockType* pWDICtx, + WDI_MainEventType wdiEV, + WDI_EventInfoType* pEventData + +); + +/*-------------------------------------------------------------------------- + INIT State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStart +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Response function for state INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRspInit +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Close function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainClose +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*-------------------------------------------------------------------------- + STARTED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Stop function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + uEventDataSize: size of the data sent in event + pCBfnc: cb function for event response + pUserData: user data + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Request function for state started + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Response function for all states except INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*-------------------------------------------------------------------------- + STOPPED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Stop function for state STOPPED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStopped +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +/*-------------------------------------------------------------------------- + BUSY State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Stop function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Request function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Close function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainCloseBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Shutdown function for INIT & STARTED states + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdown +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Shutdown function for BUSY state + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdownBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*======================================================================== + Main DAL Control Path Request Processing API +========================================================================*/ + +/** + @brief Process Start Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Stop Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Close Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Shutdown Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Init Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Start Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process End Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Finish Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Join Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config BSS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BSS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Post Assoc Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set BSS Key Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove BSS Key Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update EDCA Params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief Process TSM Stats Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTSMStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Channel Switch Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Config STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set Link State Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Get Stats Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief Process Get Roam rssi Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Get Roam Rssi Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif + + +/** + @brief Process Update Cfg Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Trigger BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon template Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process NV blob download function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Per Band Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerPerBandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process P2P Notice Of Absence Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process TDLS Link Establish Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsLinkEstablishReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter BMPS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit BMPS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter UAPSD Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit UAPSD Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set UAPSD params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process update UAPSD params Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure RXP filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process remove beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresholdsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Keep Alive Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Wowl add bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl delete bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl enter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl exit Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure Apps Cpu Wakeup State Request function + (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Flush AC Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Process Start Oem Data Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Host Resume Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process BT AMP event Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add STA self Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del Sta Self Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set Tx Per Tracking configurations Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Power Params Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Thermal Mitigation level Changed request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLPHBConfReq - + LPHB configuration request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return esult of the function call +*/ +WDI_Status WDI_ProcessLPHBConfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_ProcessSetBatchScanReq - + Send set batch scan configuration request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return success or failure +*/ +WDI_Status WDI_ProcessSetBatchScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessGetBatchScanReq - + Send get batch scan request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return success or failure +*/ +WDI_Status WDI_ProcessGetBatchScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_BATCH_SCAN */ + + +/*========================================================================= + Indications +=========================================================================*/ + +/** + @brief Process Suspend Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostSuspendInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief DHCP Start Event Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief DHCP Stop Event Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStopInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Traffic Stats Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTrafficStatsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_11W +/** + @brief Process Exclude Unencrypted Indications function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExcludeUnencryptInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Add Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Delete Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief Process stop batch scan indications function + It is called when Main FSM allows it + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call + */ + WDI_Status + WDI_ProcessStopBatchScanInd + ( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +/** + @brief This API is called to trigger batch scan results from FW + It is called when Main FSM allows it + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call + */ + WDI_Status + WDI_ProcessTriggerBatchScanResultInd + ( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +#endif + +/*======================================================================== + Main DAL Control Path Response Processing API +========================================================================*/ + + +/** + @brief Process Start Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Stop Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Close Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Shutdown Rsp function + There is no shutdown response comming from HAL + - function just kept for simmetry + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Init Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Start Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process End Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Finish Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Join Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config BSS Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BSS Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Post Assoc Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del STA Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set STA Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update EDCA Parameters Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief Process TSM stats Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTsmStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif + + +/** + @brief Process Channel Switch Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config STA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set Link State Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Get Stats Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Update Cfg Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Send Beacon template Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Probe Resp Template Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + /** + @brief Process Set Max Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Per Band Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerPerBandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief Process Set Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief Process TDLS Link Establish Req Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLinkEstablishReqRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Nv download(called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process P2P Group Owner Notice Of Absense Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process update UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure RXP filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process remove beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresoldsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Keep Alive Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process wowl add ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl delete ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl enter Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl exit Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure Apps CPU wakeup State Rsp function + (called when a response is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process Flush AC Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process BT AMP event Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process ADD SELF STA Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief WDI_ProcessDelSTASelfRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Start Oem Data Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + + /** + @brief WDI_ProcessHostResumeRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set tx per tracking Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Power Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set TM Level Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*========================================================================== + Indications from HAL + ==========================================================================*/ +/** + @brief Process Low RSSI Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLowRSSIInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Missed Beacon Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMissedBeaconInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Unk Addr Frame Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUnkAddrFrameInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process MIC Failure Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMicFailureInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Fatal Failure Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFatalErrorInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Delete STA Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Coex Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCoexInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tx Complete Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxCompleteInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tdls Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Noa Start Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Noa Attr Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaAttrInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tx Per Hit Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxPerHitInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLphbInd - + This function will be invoked when FW detects low power + heart beat failure + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLphbInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +/** + @brief Process Periodic Tx Pattern Fw Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPeriodicTxPtrnFwInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief Process Aggrgated Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + @brief WDI_ProcessFTMCommandReq + Process FTM Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessFTMCommandRsp + Process FTM Command Response from HAL, simply route to HDD FTM + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief WDI_ProcessHALDumpCmdReq + Process Hal Dump Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessHALDumpCmdRsp + Process Hal Dump Command Response from HAL, simply route to HDD FTM + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessIbssPeerInactivityInd + Process peer inactivity indication coming from HAL. + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInactivityInd + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/*======================================================================== + Internal Helper Routines +========================================================================*/ + +/** + @brief WDI_CleanCB - internal helper routine used to clean the + WDI Main Control Block + + @param pWDICtx - pointer to the control block + + @return Result of the function call +*/ +WDI_Status +WDI_CleanCB +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Main FSM Close function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Get message helper function - it allocates memory for a + message that is to be sent to HAL accross the bus and + prefixes it with a send message header + + @param pWDICtx: pointer to the WLAN DAL context + wdiReqType: type of the request being sent + uBufferLen: message buffer len + pMsgBuffer: resulting allocated buffer + puDataOffset: offset in the buffer where the caller + can start copying its message data + puBufferSize: the resulting buffer size (offset+buff + len) + + @see + @return Result of the function call +*/ +WDI_Status +WDI_GetMessageBuffer +( + WDI_ControlBlockType* pWDICtx, + WDI_RequestEnumType wdiReqType, + wpt_uint16 usBufferLen, + wpt_uint8** pMsgBuffer, + wpt_uint16* pusDataOffset, + wpt_uint16* pusBufferSize +); + +/** + @brief WDI_DetectedDeviceError - called internally by DAL when + it has detected a failure in the device + + @param pWDICtx: pointer to the WLAN DAL context + usErrorCode: error code detected by WDI or received + from HAL + + @see + @return None +*/ +void +WDI_DetectedDeviceError +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usErrorCode +); + +/*========================================================================= + QUEUE SUPPORT UTILITY FUNCTIONS +=========================================================================*/ + +/** + @brief Utility function used by the DAL Core to help queue a + request that cannot be processed right away. + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueuePendingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Utility function used by the DAL Core to clear any + pending requests - all req cb will be called with + failure and the queue will be emptied. + @param + + pWDICtx: - pointer to the WDI control block + + @see + @return Result of the operation +*/ +WDI_Status +WDI_ClearPendingRequests +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief This callback is invoked by the wpt when a timer that + we started on send message has expire - this should + never happen - it means device is stuck and cannot + reply - trigger catastrophic failure + @param + + pUserData: the callback data of the user (ptr to WDI CB) + + @see + @return None +*/ +void +WDI_ResponseTimerCB +( + void *pUserData +); + +/*========================================================================== + CONTRL TRANSPORT INTERACTION + + Callback function registered with the control transport - for receiving + notifications and packets +==========================================================================*/ +/** + @brief This callback is invoked by the control transport + when it wishes to send up a notification like the ones + mentioned above. + + @param + + wctsHandle: handle to the control transport service + wctsEvent: the event being notified + wctsNotifyCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_NotifyMsgCTSCB +( + WCTS_HandleType wctsHandle, + WCTS_NotifyEventType wctsEvent, + void* wctsNotifyCBData +); + +/** + @brief This callback is invoked by the control transport + when it wishes to send up a packet received over the + bus. + + @param + + wctsHandle: handle to the control transport service + pMsg: the packet + uLen: the packet length + wctsRxMsgCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_RXMsgCTSCB +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen, + void* wctsRxMsgCBData +); + +/** + @brief Process response helper function + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessResponse +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Send message helper function - sends a message over the + bus using the control tranport and saves some info in + the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + + uSendSize size of the buffer to be sent + pRspCb: response callback - save in the WDI + CB + pUserData: user data associated with the + callback + wdiExpectedResponse: the code of the response that is + expected to be rx-ed for this request + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendMsg +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 uSendSize, + void* pRspCb, + void* pUserData, + WDI_ResponseEnumType wdiExpectedResponse +); + + +/** + @brief Send indication helper function - sends a message over + the bus using the control transport and saves some info + in the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + usSendSize: size of the buffer to be sent + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendIndication +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 usSendSize +); + +/** + @brief Utility function used by the DAL Core to help dequeue + and schedule for execution a pending request + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeuePendingReq +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pEventData: pointer to the evnt info that needs to be queued + macBSSID: bssid + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueNewAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData, + wpt_macAddr macBSSID +); + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pSession: - session in which to queue + pEventData: pointer to the event info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* pSession, + WDI_EventInfoType* pEventData +); + +/** + @brief Utility function used by the DAL Core to help dequeue + an association request that was pending + The request will be queued up in front of the main + pending queue for immediate processing + @param + + pWDICtx: - pointer to the WDI control block + + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeueAssocRequest +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Helper routine used to init the BSS Sessions in the WDI control block + + + @param pWDICtx: pointer to the WLAN DAL context + + @see +*/ +void +WDI_ResetAssocSessions +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Helper routine used to find an empty session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindEmptySession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to get the total count of active + sessions + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: pointer to BSSID. If NULL, get all the session. + If not NULL, count ActiveSession by excluding (TRUE) or including (FALSE) skipBSSID. + skipBSSID: if TRUE, get all the sessions except matching to macBSSID. If FALSE, get all session. + This argument is ignored if macBSSID is NULL. + @see + @return Number of sessions in use +*/ +wpt_uint8 +WDI_GetActiveSessionsCount +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + wpt_boolean skipBSSID +); + +/** + @brief Helper routine used to delete session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +void +WDI_DeleteSession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: BSSID of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSession +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + WDI_BSSSessionType** ppSession +); + + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + usBssIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usBssIdx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + usBssIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usBssIdx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + @param pContext: pointer to the WLAN DAL context + @param pDPContext: pointer to the Datapath context + + @see + @return +*/ +void +WDI_DS_AssignDatapathContext +( + void *pContext, + void *pDPContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + + @see + @return pointer to Datapath context +*/ +void * +WDI_DS_GetDatapathContext +( + void *pContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + @param pDTDriverContext: pointer to the Transport Driver context + + @see + @return void +*/ +void +WDT_AssignTransportDriverContext +( + void *pContext, + void *pDTDriverContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return pointer to datapath context +*/ +void * +WDT_GetTransportDriverContext +( + void *pContext +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + @brief Process Set Preferred Network List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set RSSI Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Scan Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Preferred Network Found Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPrefNetworkFoundInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process PNO Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process RSSI Filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Scan Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + @brief Process Start Roam Candidate Lookup Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process Start Roam Candidate Lookup Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/** + @brief Process 8023 Multicast List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Set Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process D0 PC Filter Match Count Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Clear Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process 8023 Multicast List Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Set Filter Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process D0 PC Filter Match Count Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Clear Filter Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/** + @brief Process set GTK Offload Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process GTK Offload Get Information Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGtkOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process GTK Offload Get Information Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +WDI_Status +WDI_ProcessWakeReasonInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_WAKEUP_EVENTS + +/** + @brief Process Host-FW Capability Exchange Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Host-FW Capability Exchange Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_ProcessUpdateVHTOpModeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessUpdateVHTOpModeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * @brief WDI_wdiEdTypeEncToEdTypeEnc - + * The firmware expects the Encryption type to be in EdType. + * This function converts the WdiEdType encryption to EdType. + * @param tEdType : EdType to which the encryption needs to be converted. + * @param WDI_EdType : wdiEdType passed from the upper layer. + * @see + * @return none + * */ +void +WDI_wdiEdTypeEncToEdTypeEnc +( + tEdType *EdType, + WDI_EdType wdiEdType +); +#endif + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLphbCfgRsp - + LPHB configuration response from FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessLphbCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +/** + @brief Process Rate Update Indication and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRateUpdateInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_ProcessSetBatchScanRsp - + Process set batch scan response from FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetBatchScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process batch scan response from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBatchScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* FEATURE_WLAN_BATCH_SCAN */ + +#endif /*WLAN_QCT_WDI_I_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h new file mode 100644 index 0000000000000..039a3c09cb460 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_DAL_STA_H +#define WLAN_QCT_DAL_STA_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + S T A T I O N M G M T + + +DESCRIPTION + This file contains the internal API exposed by the STA Management entity to + be used by the DAL Control Path Core . +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_api.h" + +/*---------------------------------------------------------------------------- + Preprocesor definitions and macros + -------------------------------------------------------------------------*/ +/*Invalid station index */ +#define WDI_STA_INVALID_IDX 0xFF + +/*---------------------------------------------------------------------------- + WDI_AddStaParams + -------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; + wpt_uint8 ucWmmEnabled; + wpt_uint8 ucHTCapable; + + /* MAC Address of STA */ + wpt_macAddr staMacAddr; + + /*MAC Address of the BSS*/ + wpt_macAddr macBSSID; + + /* Field to indicate if this is sta entry for itself STA adding entry for itself + or remote (AP adding STA after successful association. + This may or may not be required in production driver. + 0 - Self, 1 other/remote, 2 - bssid */ + wpt_uint8 ucStaType; + + + /*DPU Information*/ + wpt_uint8 dpuIndex; // DPU table index + wpt_uint8 dpuSig; // DPU signature + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + + + /*RMF enabled/disabled*/ + wpt_uint8 ucRmfEnabled; + + /* Index into the BSS Session table */ + wpt_uint8 ucBSSIdx; + +}WDI_AddStaParams; + +/*---------------------------------------------------------------------------- + WDI_StaStruct + -------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr staAddr; // Sta Addr + + wpt_uint8 valid:1; // Used/free flag + wpt_uint8 rmfEnabled:1; + wpt_uint8 htEnabled:1; + + /* 11e or WMM enabled, flag used for header length*/ + wpt_uint8 qosEnabled:1; + + wpt_uint8 bssIdx; // BSS Index + wpt_uint8 staId; + + wpt_macAddr macBSSID; + // Field to indicate if this is sta entry for itself STA adding entry for itself + // or remote (AP adding STA after successful association. + // This may or may not be required in production driver. + // 0 - Self, 1 other/remote, 2 - bssid + wpt_uint8 ucStaType; + + + /*DPU Information*/ + wpt_uint8 dpuIndex; // DPU table index + wpt_uint8 dpuSig; // DPU signature + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + +} WDI_StaStruct; + +/** + @brief WDI_STATableInit - Initializes the STA tables. + Allocates the necesary memory. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status WDI_STATableInit +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableStart - resets the max and number values of + STAtions + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStart +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableStop - clears the sta table + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStop +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableClose - frees the resources used by the STA + table. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableClose +( + WDI_ControlBlockType* pWDICtx +); + + +/** + @brief WDI_STATableAddSta - Function to Add Station + + + @param pWDICtx: pointer to the WLAN DAL context + pwdiParam: station parameters + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableAddSta +( + WDI_ControlBlockType* pWDICtx, + WDI_AddStaParams* pwdiParam +); + +/** + @brief WDI_STATableDelSta - Function to Delete a Station + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station to be deleted + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableDelSta +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx +); + +/** + @brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS + + + @param pWDICtx: pointer to the WLAN DAL context + bssIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableBSSDelSta +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucBssIdx +); + +/** + @brief WDI_STATableGetStaBSSIDAddr - Gets the BSSID associated + with this station + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pmacBSSID: out BSSID for this STA + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaBSSIDAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr* pmacBSSID +); +/** + @brief WDI_STATableGetStaQosEnabled - Gets is qos is enabled + for a sta + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: out qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* qosEnabled +); + +/** + @brief WDI_STATableSetStaQosEnabled - set qos mode for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 qosEnabled +); + +/** + @brief WDI_STATableGetStaType - get sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pStaType: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* pStaType +); + +/** + @brief WDI_STATableSetStaType - sets sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + staType: sta type + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 staType +); + + +/** + @brief WDI_STATableFindStaidByAddr - Given a station mac address, search + for the corresponding station index from the Station Table. + + @param pWDICtx: WDI Context pointer + staAddr: station address + pucStaId: output station id + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableFindStaidByAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr staAddr, + wpt_uint8* pucStaId +); + +/** + @brief WDI_STATableGetStaAddr - get station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8** pStaAddr +); + +/** + @brief WDI_STATableSetStaAddr - set station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr staAddr +); + +/** + @brief WDI_STATableSetBSSID - set station corresponding BSSID + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSID +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr macBSSID +); + +/** + @brief WDI_STATableSetBSSIdx - set station corresponding BSS index + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + bssIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 ucBSSIdx +); + +#endif /*WLAN_QCT_WDI_STA_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h b/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h new file mode 100644 index 0000000000000..fcd868fceaa83 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_WTI_DS_H ) +#define __WLAN_QCT_WTI_DS_H + +/**========================================================================= + * + * \file wlan_qct_wdi_ds.h + * + * \brief define Dataservice API + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API exposed by the + * wlan device abstarction layer module. + * + */ + + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_wdi.h" + + +typedef struct +{ + wpt_uint32 txFlags; + wpt_uint8 ac; + wpt_uint8 isEapol:1; //0 - not eapol 1 - eapol + wpt_uint8 isWai:1; //WAPI 0 - not WAI 1 WAI + wpt_uint8 fdisableFrmXlt:1; //0 - Let ADU do FT. 1 - bypass ADU FT + wpt_uint8 qosEnabled:1; //0 - non-Qos 1 - Qos + wpt_uint8 fenableWDS:1; //0 - not WDS 1 WDS + wpt_uint8 reserved1:3; + wpt_uint8 typeSubtype; + wpt_uint8 fUP; + wpt_uint8 fSTAMACAddress[6]; + wpt_uint8 addr2MACAddress[6]; + wpt_uint8 frmType; + wpt_uint8 fStaType; + wpt_uint8 fProtMgmtFrame; + wpt_uint16 fPktlen; + wpt_status txCompleteStatus; + wpt_uint8 staIdx; +} WDI_DS_TxMetaInfoType; + + +typedef enum +{ + WDI_DS_OPCODE_INVALID = 0, + WDI_DS_OPCODE_QCUR_FWDBUF = 1, + WDI_DS_OPCODE_FWDBUF_FWDCUR = 2, + WDI_DS_OPCODE_QCUR = 3, + WDI_DS_OPCODE_FWDBUF_QUEUECUR = 4, + WDI_DS_OPCODE_FWDBUF_DROPCUR = 5, + WDI_DS_OPCODE_FWDALL_DROPCUR = 6, + WDI_DS_OPCODE_FWDALL_QCUR = 7, + WDI_DS_OPCODE_TEARDOWN = 8, + WDI_DS_OPCODE_DROPCUR = 9, + WDI_DS_OPCODE_MAX +}WDI_DS_BAOpCodeEnumType; + +typedef struct +{ + wpt_uint8 staId; + wpt_uint8 addr3Idx; + wpt_uint8 rxChannel; + wpt_uint8 type:2; + wpt_uint8 subtype:4; + wpt_uint8 rfBand:2; + + wpt_uint16 rtsf:1; //For beacon only. 1 ~V Riva TSF is bigger(later) than the one received + wpt_uint16 bsf:1; //1 Riva sends the last beacon, 0 not. + wpt_uint16 unknownUcastPkt:1; //1 ~V unicast frame received with unknown A2 + wpt_uint16 scan:1; //1 frame received in scan state. 0 not. + wpt_uint16 dpuSig:3; //DPU signature + wpt_uint16 ft:1; //0~Wframe translation is not done. 1~Wdone + wpt_uint16 ne:1; //1 ~V frame is not encrypted OTA. This is for WAPI~Rs WAI packet. + wpt_uint16 llcr:1; // Has the LLC been stripped by H/W + wpt_uint16 bcast:1; //0 ~V unicast frame 1 ~V broadcast/multicast frame + wpt_uint16 tid:4; + wpt_uint16 reserved1:1; + wpt_uint8 dpuFeedback; + wpt_int8 snr; + + wpt_uint32 currentPktSeqNo:12; /*current sequence number */ + wpt_uint32 ampdu_reorderOpcode:4; + wpt_uint32 ampdu_reorderSlotIdx:6; + wpt_uint32 ampdu_reorderFwdIdx:6; + wpt_uint32 reserved3:4; + + wpt_uint16 amsdu_size; + wpt_uint32 amsdu_asf:1; + wpt_uint32 amsdu_esf:1; + wpt_uint32 amsdu_lsf:1; + wpt_uint32 amsdu_aef:1; + wpt_uint32 reserved2:4; + + wpt_uint8 *mpduHeaderPtr; + wpt_uint8 *mpduDataPtr; + wpt_uint32 mpduLength; + wpt_uint32 mpduHeaderLength; + + wpt_uint32 rateIndex; + wpt_uint32 rxpFlags; + wpt_uint32 mclkRxTimestamp; + + //Flow control frames + wpt_uint8 fc; + wpt_uint32 fcSTATxQStatus:16; + wpt_uint32 fcSTAThreshIndMask:16; + wpt_uint32 fcSTAPwrSaveStateMask:16; + wpt_uint32 fcSTAValidMask:16; + + wpt_uint16 fcStaTxDisabledBitmap; + wpt_uint8 fcSTATxQLen[12]; // one byte per STA. + wpt_uint8 fcSTACurTxRate[12]; // current Tx rate for each sta. + + wpt_uint64 replayCount; + + wpt_uint32 rssi0; + wpt_uint32 rssi1; + +#ifdef WLAN_FEATURE_11W + wpt_uint32 rmf:1; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 offloadScanLearn; + wpt_uint32 roamCandidateInd; +#endif + wpt_uint32 sessionId; +} WDI_DS_RxMetaInfoType; + +typedef struct sPktMetaInfo +{ + union + { + WDI_DS_TxMetaInfoType txMetaInfo; + WDI_DS_RxMetaInfoType rxMetaInfo; + } u; +} WDI_DS_MetaInfoType; + +WPT_STATIC WPT_INLINE WDI_DS_RxMetaInfoType* WDI_DS_ExtractRxMetaData (wpt_packet *pFrame) +{ + WDI_DS_RxMetaInfoType * pRxMetadata = + &((WDI_DS_MetaInfoType *)WPAL_PACKET_GET_METAINFO_POINTER(pFrame))->u.rxMetaInfo; + return pRxMetadata; +} + + +WPT_STATIC WPT_INLINE WDI_DS_TxMetaInfoType* WDI_DS_ExtractTxMetaData (wpt_packet *pFrame) +{ + WDI_DS_TxMetaInfoType * pTxMetadata = + &((WDI_DS_MetaInfoType *)WPAL_PACKET_GET_METAINFO_POINTER(pFrame))->u.txMetaInfo; + return pTxMetadata; +} + + +typedef void (*WDI_DS_TxCompleteCallback)(void *pContext, wpt_packet *pFrame); +typedef void (*WDI_DS_RxPacketCallback) (void *pContext, wpt_packet *pFrame); +typedef void (*WDI_DS_TxFlowControlCallback)(void *pContext, wpt_uint8 ac_mask); + + + +/* DAL registration function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * pfnTxCompleteCallback:Callback function that is to be invoked to return + * packets which have been transmitted. + * pfnRxPacketCallback:Callback function that is to be invoked to deliver + * packets which have been received + * pfnTxFlowControlCallback:Callback function that is to be invoked to + * indicate/clear congestion. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +WDI_Status WDI_DS_Register( void *pContext, + WDI_DS_TxCompleteCallback pfnTxCompleteCallback, + WDI_DS_RxPacketCallback pfnRxPacketCallback, + WDI_DS_TxFlowControlCallback pfnTxFlowControlCallback, + void *pCallbackContext); + + + +/* DAL Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * pFrame:Refernce to PAL frame. + * more: Does the invokee have more than one packet pending? + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxPacket(void *pContext, + wpt_packet *pFrame, + wpt_boolean more); + + +/* DAL Transmit Complete function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * ucTxResReq:TX resource number required by TL + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxComplete(void *pContext, wpt_uint32 ucTxResReq); + +/* DAL Suspend Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxSuspend(void *pContext); + + +/* DAL Resume Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxResume(void *pContext); + +/* DAL Get Reserved resource by STA + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * wdiResPool: MemPool, MGMT ot DATA + * staId: STA ID + * Return Value: Number of reserved resouce count + * + */ +wpt_uint32 WDI_DS_GetReservedResCountPerSTA(void *pContext, + WDI_ResPoolType wdiResPool, + wpt_uint8 staId); + +/* DAL ADD STA into memPool + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: SUCCESS or FAIL + * + */ +WDI_Status WDI_DS_AddSTAMemPool(void *pContext, wpt_uint8 staIndex); + +/* DAL Remove STA from memPool + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: SUCCESS or FAIL + * + */ +WDI_Status WDI_DS_DelSTAMemPool(void *pContext, wpt_uint8 staIndex); + +/* DAL Set STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_SetStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx); + +/* DAL Get STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_GetStaIdxFromBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 *staIdx); + +/* DAL Clear STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_ClearStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx); + +/* @brief: WDI_DS_GetTrafficStats + * This function should be invoked to fetch the current stats + * Parameters: + * pStats:Pointer to the collected stats + * len: length of buffer pointed to by pStats + * Return Status: None + */ +void WDI_DS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len); + +/* @brief: WDI_DS_DeactivateTrafficStats + * This function should be invoked to deactivate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_DeactivateTrafficStats(void); + +/* @brief: WDI_DS_ActivateTrafficStats + * This function should be invoked to activate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_ActivateTrafficStats(void); + +/* @brief: WDI_DS_ClearTrafficStats + * This function should be invoked to clear all past stats + * Parameters: None + * Return Status: None + */ +void WDI_DS_ClearTrafficStats(void); + +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h b/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h new file mode 100644 index 0000000000000..79d17cfa313b9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_WDI_DS_I_H ) +#define __WLAN_QCT_WDI_DS_I_H + +/**========================================================================= + * + * \file wlan_qct_wdi_ds_i.h + * + * \brief define Dataservice API + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API exposed by the + * wlan device abstarction layer module. + * + */ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_dxe.h" + + +#define WDI_DS_MAX_CHUNK_SIZE 128 +#define WDI_802_11_MAX_HEADER_LEN 40 + + +/*The number of resources (BD headers) available for the HI priority DXE + channel + DXE will use 1 descriptor for the BD header and 1 for the data => + This is true for LA but not EA. EA sends down 3~4 MDL chain per a packet. + Now we set it the same with free DXE decriptor number*/ +#define WDI_DS_HI_PRI_RES_NUM (WLANDXE_HI_PRI_RES_NUM) + +/*The number of resources (BD headers) available for the Low priority DXE + channel - see above +*/ +#define WDI_DS_LO_PRI_RES_NUM (WLANDXE_LO_PRI_RES_NUM) + +/*The number of BD headers available in the system for Tx must match the number + of DXE descriptors available for actual transmission, otherwise we have to + manage two diffrent level of resource pools*/ + +#define WDI_MAC_ADDR_SIZE ( 6 ) +/*802.3 header definitions*/ +#define WDI_802_3_HEADER_LEN 14 +/* Offset of DA field in a 802.3 header*/ +#define WDI_802_3_HEADER_DA_OFFSET 0 +/*802.11 header definitions - header len without QOS ctrl field*/ +#define WDI_802_11_HEADER_LEN 24 +/*802.11 header length + QOS ctrl field*/ +#define WDI_MPDU_HEADER_LEN 26 +/*802.11 header definitions*/ +#define WDI_802_11_MAX_HEADER_LEN 40 +/*802.11 header definitions - qos ctrl field len*/ +#define WDI_802_11_HEADER_QOS_CTL 2 +/*802.11 ADDR4 MAC addr field len */ +#define WDI_802_11_HEADER_ADDR4_LEN WDI_MAC_ADDR_SIZE + + + + + +typedef enum +{ + DTI_TRACE_LEVEL_FATAL, + DTI_TRACE_LEVEL_ERROR, + DTI_TRACE_LEVEL_WARN, + DTI_TRACE_LEVEL_INFO + +} DTI_TRACE_LEVEL; + +WPT_STATIC WPT_INLINE void DTI_TRACE ( DTI_TRACE_LEVEL level, ...) { }; + +/* !!! MAX NUM STA is not identified yet, 16 is correct value, + but need to get from correct common def + This should be identified ASAP */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDI_DS_MAX_STA_ID 41 +#else +#define WDI_DS_MAX_STA_ID 16 +#endif +/* !!! MAX NUM SUPPORTED BSS is not identified yet, 2 is correct value, + but need to get from correct common def + This should be identified ASAP */ +#define WDI_DS_MAX_SUPPORTED_BSS 2 + +#define WDI_DS_INDEX_INVALID 0xFF + +/* Mem Pool resorce count per STA data type */ +typedef struct { + wpt_uint8 validIdx; + wpt_uint8 STAIndex; + wpt_uint32 numChunkReservedBySTA; + /* Mutex, is not needed for counter operation + since all TX Data frame operations will happen only TX thread + All of the TX data frame operations are serialized, no pre-emption will happen + This is just for place holder */ + wpt_mutex resourceCountLock; +} WDI_DS_BdMemPoolSTAType; + +typedef struct { + void *pVirtBaseAddress; + void *pPhysBaseAddress; + wpt_uint32 poolSize; + wpt_uint32 numChunks; + wpt_uint32 chunkSize; + wpt_uint32* AllocationBitmap; + WDI_DS_BdMemPoolSTAType numChunkSTA[WDI_DS_MAX_STA_ID + 1]; +} WDI_DS_BdMemPoolType; + +/* STA index associated with BSS index data type */ +typedef struct +{ + wpt_uint8 isUsed; + wpt_uint8 bssIdx; + wpt_uint8 staIdx; +} WDI_DS_staIdxPerBssIdxType; + +WDI_Status WDI_DS_MemPoolCreate(WDI_DS_BdMemPoolType *memPool, wpt_uint8 chunkSize, wpt_uint8 numChunks); +void *WDI_DS_MemPoolAlloc(WDI_DS_BdMemPoolType *memPool, void **pPhysAddress, WDI_ResPoolType wdiResPool); +void WDI_DS_MemPoolFree(WDI_DS_BdMemPoolType *memPool, void *pVirtAddress, void *pPhysAddress); +void WDI_DS_MemPoolDestroy(WDI_DS_BdMemPoolType *memPool); + +typedef struct +{ + void *pcontext; + void *pCallbackContext; + wpt_uint8 suspend; + WDI_DS_BdMemPoolType mgmtMemPool; + WDI_DS_BdMemPoolType dataMemPool; + WDI_DS_RxPacketCallback receiveFrameCB; + WDI_DS_TxCompleteCallback txCompleteCB; + WDI_DS_TxFlowControlCallback txResourceCB; + WDI_DS_staIdxPerBssIdxType staIdxPerBssIdxTable[WDI_DS_MAX_SUPPORTED_BSS]; +} WDI_DS_ClientDataType; + +WPT_STATIC WPT_INLINE void WDI_GetBDPointers(wpt_packet *pFrame, void **pVirt, void **pPhys) +{ + *pVirt = WPAL_PACKET_GET_BD_POINTER(pFrame); + *pPhys = WPAL_PACKET_GET_BD_PHYS(pFrame); +} + + +WPT_STATIC WPT_INLINE void WDI_SetBDPointers(wpt_packet *pFrame, void *pVirt, void *pPhys) +{ + WPAL_PACKET_SET_BD_POINTER(pFrame, pVirt); + WPAL_PACKET_SET_BD_PHYS(pFrame, pPhys); +} + + +void +WDI_DS_PrepareBDHeader ( + wpt_packet* palPacket, + wpt_uint8 ucDisableHWFrmXtl, + wpt_uint8 alignment +); + +/** + @brief Returns the available number of resources (BD headers) + available for TX + + @param pMemPool: pointer to the BD memory pool + + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_GetAvailableResCount(WDI_DS_BdMemPoolType *pMemPool); + +/** + @brief WDI_DS_GetreservedResCountPerSTA + Returns the Reserved number of resources (BD headers) + available for TX + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_MemPoolGetRsvdResCountPerSTA(WDI_DS_BdMemPoolType *pMemPool, wpt_uint8 staId); + +/** + @brief WDI_DS_MemPoolAddSTA + Add NEW STA into mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolAddSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex); + +/** + @brief WDI_DS_MemPoolAddSTA + Remove STA from mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolDelSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex); + +/** + @brief Increase reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolIncreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId); + +/** + @brief Decrease reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolDecreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h b/drivers/staging/qcacld-2.0/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h new file mode 100644 index 0000000000000..bc58ccf5fafcb --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_CTS_H +#define WLAN_QCT_WDI_CTS_H + +/*=========================================================================== + + W L A N C O N T R O L T R A N S P O R T S E R V I C E + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan control transport + service module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/04/10 mss Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_pal_type.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/* Control Transport Service Handle Type*/ +typedef void* WCTS_HandleType; + +/*--------------------------------------------------------------------------- + WCTS_NotifyEventType + ---------------------------------------------------------------------------*/ +typedef enum +{ + WCTS_EVENT_OPEN, + WCTS_EVENT_CLOSE, + WCTS_EVENT_MAX +} WCTS_NotifyEventType; + +/*---------------------------------------------------------------------------- + * WDI callback types + *--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WCTS_NotifyCBType + + DESCRIPTION + + This callback is invoked by the control transport when it wishes to send + up a notification like the ones mentioned above. + + PARAMETERS + + IN + wctsHandle: handle to the control transport service + wctsEvent: the event being notified + wctsNotifyCBData: the callback data of the user + + + RETURN VALUE + None +---------------------------------------------------------------------------*/ +typedef void (*WCTS_NotifyCBType) (WCTS_HandleType wctsHandle, + WCTS_NotifyEventType wctsEvent, + void* wctsNotifyCBData); + +/*--------------------------------------------------------------------------- + WCTS_RxMsgCBType + + DESCRIPTION + + This callback is invoked by the control transport when it wishes to send + up a packet received over the bus. Upon return of Rx callback, the ownership + of the message belongs to the CT and this one is free to deallocate any + buffer that was used to get this message. If WDI wishes to maintain the + information beyond the lifetime of the call, it must make a copy of it. + + PARAMETERS + + IN + wctsHandle: handle to the control transport service + pMsg: the packet + uLen: the packet length + wctsRxMsgCBData: the callback data of the user + + + RETURN VALUE + None +---------------------------------------------------------------------------*/ +typedef void (*WCTS_RxMsgCBType) (WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen, + void* wctsRxMsgCBData); + +/*--------------------------------------------------------------------------- + WCTS Transport Callbacks holder type + ---------------------------------------------------------------------------*/ +typedef struct +{ + WCTS_NotifyCBType wctsNotifyCB; + void* wctsNotifyCBData; + WCTS_RxMsgCBType wctsRxMsgCB; + void* wctsRxMsgCBData; +} WCTS_TransportCBsType; + +/*======================================================================== + * Function Declarations and Documentation + ==========================================================================*/ +/** + @brief This function is used by the DAL Core to initialize the Control + Transport for processing. It must be called prior to calling any + other APIs of the Control Transport. + + + @param szName: unique name for the channel that is to be opened + uSize: size of the channel that must be opened (should fit the + largest size of packet that the Dal Core wishes to send) + wctsCBs: a list of callbacks that the CT needs to use to send + notification and messages back to DAL + + @see + @return A handle that must be used for further communication with the CTS. + This is an opaque structure for the caller and it will be used in + all communications to and from the CTS. + +*/ +WCTS_HandleType +WCTS_OpenTransport +( + const wpt_uint8* szName, + wpt_uint32 uSize, + WCTS_TransportCBsType* wctsCBs +); + +/** + @brief This function is used by the DAL Core to to close the + Control Transport when its services are no longer + needed. Full close notification will be receive + asynchronously on the notification callback + registered on Open + + + @param wctsHandlehandle: received upon open + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_CloseTransport +( + WCTS_HandleType wctsHandle +); + +/** + @brief This function is used by the DAL Core to to send a + message over to the WLAN sub-system. + + Once a buffer has been passed into the Send Message + API, CT takes full ownership of it and it is responsible for + freeing the associated resources. (This prevents a memcpy in + case of a deffered write) + + The messages transported through the CT on both RX and TX are + flat memory buffers that can be accessed and manipulated + through standard memory functions. + + @param wctsHandlehandle: received upon open + pMsg: the message to be sent + uLen: the length of the message + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_SendMessage +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen +); + +/** + @brief This helper function is used to clean up the pending + messages in the transport queue + + @param wctsHandlehandle: transport handle + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_ClearPendingQueue +( + WCTS_HandleType wctsHandle +); +#endif /* #ifndef WLAN_QCT_WDI_CTS_H */ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h b/drivers/staging/qcacld-2.0/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h new file mode 100644 index 0000000000000..edbf2eb6a873f --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_QCT_DTS_H +#define __WLAN_QCT_DTS_H + +#include "wlan_qct_wdi.h" + +/**========================================================================= + * + * \file wlan_qct_wdi_dts.h + * + * \brief define Datas Trnasport Service API + * + * WLAN Device Abstraction layer interface for Transport drivers (SDIO/DXE) + * DESCRIPTION + * This file contains the API exposed by the + * wlan device abstarction layer module for abstracting DXE/SDIO. + * + * + * Example usage for DXE. + * ---------------------- + * On Platform init + * DAL will then invoke WDTS_open + * + * On DAL init + * DAL will invike WDTS_start + * + * On transmit: + * DAL will invoke WDTS_TxPacket API + * + * On transmit complete: + * DXE will serialize into TX thread + * In TX thread it will invoke + * + * On receive: + * DXE will serialize into RX thread + * In TX thread it will invoke WDTS_RXPacket API + * + * On DXE ring full: + * DXE will serialize into TX thread + * In TX thread it will invoke WDTS_OOResourceNotification API + */ + +typedef enum +{ + WDTS_CHANNEL_TX_LOW_PRI, + WDTS_CHANNEL_TX_HIGH_PRI, + WDTS_CHANNEL_RX_LOW_PRI, + WDTS_CHANNEL_RX_HIGH_PRI, + WDTS_CHANNEL_MAX +} WDTS_ChannelType; + +typedef enum +{ + WDTS_POWER_STATE_FULL, + WDTS_POWER_STATE_IMPS, + WDTS_POWER_STATE_BMPS, + WDTS_POWER_STATE_DOWN, + WDTS_POWER_STATE_MAX +} WDTS_PowerStateType; + + +typedef wpt_status (*WDTS_TxCompleteCbType)(void *pContext, wpt_packet *pFrame, wpt_status status); +typedef wpt_status (*WDTS_RxFrameReadyCbType) (void *pContext, wpt_packet *pFrame, WDTS_ChannelType channel); +typedef wpt_status (*WDTS_LowResourceCbType)(void *pContext, WDTS_ChannelType channel, wpt_boolean on); +typedef void (*WDTS_SetPSCbType)(wpt_status status, unsigned int dxePhyAddr); +/* DTS Set power state ACK callback. + * This callback function should be invoked by the DTS to notify WDI that set + * power state request is complete. + * Parameters: + * status: status of the set operation + * pUserData:Cookie that should be passed back to the caller along with the callback. + * Return Value: None. + * + */ +typedef void (*WDTS_SetPowerStateCbType)(wpt_status status, + unsigned int dxePhyAddr, + void* pUserData); + +typedef struct { + void * (*open)(void); + wpt_status (*start) (void *pContext); + wpt_status (*register_client)(void *pContext, WDTS_RxFrameReadyCbType, + WDTS_TxCompleteCbType, WDTS_LowResourceCbType, void *clientData); + wpt_status (*xmit) (void *pContext, wpt_packet *packet, WDTS_ChannelType channel); + wpt_status (*txComplete) (void *pContext, wpt_uint32 ucTxResReq); + wpt_status (*setPowerState) (void *pContext, WDTS_PowerStateType powerState, + WDTS_SetPSCbType cBack); + void (*channelDebug)(wpt_boolean displaySnapshot, + wpt_boolean enableStallDetect); + wpt_status (*stop) (void *pContext); + wpt_status (*close) (void *pContext); + wpt_uint32 (*getFreeTxDataResNumber) (void *pContext); +} WDTS_TransportDriverTrype; + +typedef struct { + WDTS_SetPowerStateCbType cback; + void* pUserData; +} WDTS_SetPowerStateCbInfoType; + +/* Tx/Rx stats function + * This function should be invoked to fetch the current stats + * Parameters: + * pStats:Pointer to the collected stats + * len: length of buffer pointed to by pStats + * Return Status: None + */ +void WDTS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len); + +/* WDTS_DeactivateTrafficStats + * This function should be invoked to suspend traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDTS_DeactivateTrafficStats(void); + +/* WDTS_ActivateTrafficStats + * This function should be invoked to activate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDTS_ActivateTrafficStats(void); + +/* WDTS_ClearTrafficStats + * This function should be invoked to clear all past stats + * Parameters: None + * Return Status: None + */ +void WDTS_ClearTrafficStats(void); + +/* DTS open function. + * On open the transport device should initialize itself. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + + */ +wpt_status WDTS_openTransport( void *pContext); + + + + +/* DTS start function. + * On start the transport device should start running. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_startTransport( void *pContext); + + + + +/* DTS Tx packet function. + * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * pFrame:Refernce to PAL frame. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame); + +/* DTS Tx Complete function. + * This function should be invoked by the DAL Dataservice to notify tx completion to DXE/SDIO. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * ucTxResReq:TX resource number required by TL + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_CompleteTx(void *pContext, wpt_uint32 ucTxResReq); + +/* DTS Set power state function. + * This function should be invoked by the DAL to notify the WLAN device power state. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * powerState:Power state of the WLAN device. + * Return Value: SUCCESS Set successfully in DXE control blk. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_SetPowerState(void *pContext, WDTS_PowerStateType powerState, + WDTS_SetPowerStateCbType cback); + +/* DTS Transport Channel Debug + * Display DXE Channel debugging information + * User may request to display DXE channel snapshot + * Or if host driver detects any abnormal stcuk may display + * Parameters: + * displaySnapshot : Display DXE snapshot option + * enableStallDetect : Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + * Return Value: NONE + * + */ +void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_boolean toggleStallDetect); + +/* DTS Stop function. + * Stop Transport driver, ie DXE, SDIO + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_Stop(void *pContext); + +/* DTS Close function. + * Close Transport driver, ie DXE, SDIO + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_Close(void *pContext); + +/* Get free TX data descriptor number from DXE + * Parameters: + * pContext: Cookie that should be passed back to the caller along with the callback. + * Return Value: number of free descriptors for TX data channel + * + */ +wpt_uint32 WDTS_GetFreeTxDataResNumber(void *pContext); + +/* API to fill Rate Info based on the mac efficiency passed to it + * macEff si used to caclulate mac throughput based on each rate index/PHY rate. + * This is eventually used by MAS to calculate RX stats periodically sent to FW + * The start and end Rate Index are the other arguments to this API - the new mac + * efficiency passed to this API (Arg1) is only applied between startRateIndex (arg2) and endRateIndex (arg3). + */ +void WDTS_FillRateInfo(wpt_uint8 macEff, wpt_int16 startRateIndex, wpt_int16 endRateIndex); +#endif diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_list.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_list.h new file mode 100644 index 0000000000000..92bee82f95bb5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_list.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_LIST_H ) +#define __WLAN_QCT_OS_LIST_H + +/**========================================================================= + + \file wlan_qct_pal_list.h + + \brief define linked list PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent. It is with VOSS support. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +//Include vos_list.h here. For non-VOSS PAL, it needs to provide its own definition. +#include "vos_list.h" + +typedef vos_list_t wpt_list; +typedef vos_list_node_t wpt_list_node; + +#define WPAL_LIST_STATUS_BASIC_CHECK(status) ( VOS_IS_STATUS_SUCCESS(status) ? \ + eWLAN_PAL_STATUS_SUCCESS : eWLAN_PAL_STATUS_E_FAILURE ) + +#define WPAL_LIST_IS_VOS_STATUS_BUSY(status) (VOS_STATUS_E_BUSY == (status)) +#define WPAL_LIST_STATUS_BUSY_CHECK(status) ( VOS_IS_STATUS_SUCCESS(status) ? \ + eWLAN_PAL_STATUS_SUCCESS : (WPAL_LIST_IS_VOS_STATUS_BUSY(status) ? \ + eWLAN_PAL_STATUS_E_BUSY : eWLAN_PAL_STATUS_E_FAILURE) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_init() - initialize a wpt_list Linked List + + The \a wpal_list_init() function initializes the specified linked list + 'object'. Upon successful initialization, the state of the list + becomes initialized and available for use through the other wpt_list_xxx + APIs. + + A list must be initialized by calling wpal_list_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized list results in + a failure. + + \param pList - pointer to the opaque list object to initialize + + \return eWLAN_PAL_STATUS_SUCCESS - list was successfully initialized and + is ready to be used. + + eWLAN_PAL_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the list + + eWLAN_PAL_STATUS_E_NOMEM - insufficient memory exists to initialize + the list + + eWLAN_PAL_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by list, a previously + initialized, but not yet destroyed, list. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +#define wpal_list_init(pList) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_init( (vos_list_t *)(pList) ) ) + + +/**------------------------------------------------------------------------- + + \brief wpal_list_destroy() - Destroy a wpt_list List + + The \a wpal_list_destroy() function shall destroy the list object + referenced by pList. After a successful return from \a wpal_list_destroy() + the list object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using wpal_list_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to wpt_list functions to manipulate the list such + will fail if the list or has not been initialized or is destroyed. + Therefore, don't use the list after it has been destroyed until it has + been re-initialized. + + \param pLlist - pointer to the list object to be destroyed. + + \return eWLAN_PAL_STATUS_SUCCESS - list was successfully destroyed. + + eWLAN_PAL_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by pList that is still has + nodes. The list must be empty before it can be destroyed. + + eWLAN_PAL_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer. + \sa + + ----------------------------------------------------------------------------*/ +#define wpal_list_destroy(pList) \ + WPAL_LIST_STATUS_BUSY_CHECK( vos_list_destroy( (vos_list_t *)(pList) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_front() - insert node at front of a linked list + + The wpal_list_insert_front() API will insert a node at the front of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_front( wpt_list *pList, wpt_list_node *pNode ); +#define wpal_list_insert_front(pList, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_front( (vos_list_t *)(pList), (vos_list_node_t *)(pNode) ) ) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_back() - insert node at back of a linked list + + The wpal_list_insert_back() API will insert a node at the back of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return eWLAN_PAL__STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_back( wpt_list *pList, wpt_list_node *pNode ); +#define wpal_list_insert_back(pList, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_back( (vos_list_t *)(pList), (vos_list_node_t *)(pNode) ) ) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_front() - remove node at front of a linked list + + The wpal_list_remove_front() API will remove a node at the front of + a properly initialized wpt_ist object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the front of the list. + + eWLAN_PAL_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + eWLAN_PAL_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_front( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_remove_front(pList, ppNode) \ + ((wpt_status)vos_list_remove_front( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) )) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_back() - remove node at back of a linked list + + The wpal_list_remove_back() API will remove a node at the back of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the back of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_back( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_remove_back(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_remove_back( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + + +/*---------------------------------------------------------------------------- + + \brief wpal_list_size() - return the size of of a linked list + + The wpal_list_size() API will return the number of nodes on the + given wpt_list object. + + \param pList - Pointer to list object where the node will be counted + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return eWLAN_PAL_STATUS_SUCCESS - list size of the properly initialized + wpt_list object has been returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_size( wpt_list *pList, wpt_uint32 *pSize ); +#define wpal_list_size(pList, pSize) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_size( (vos_list_t *)(pList), (v_SIZE_t *)(pSize) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_front() - peek at the node at front of a linked list + + The wpal_list_peek_front() API will return a pointer to the node at the + front of a properly initialized wpt_list object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + eWLAN_PAL_STATUS_E_Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_front( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_peek_front(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_front( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_back() - peek at the node at back of a linked list + + The wpal_list_peek_back() API will return a pointer to the node at the + back of a properly initialized wpt_list object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_back( wpal_list *pList, wpt_list_node **ppNode ); +#define wpal_list_peek_back(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_back( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_next() - peek at the node after the specified node + + The wpal_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized wpt_list object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_next( wpt_list *pList, wpt_list_node *pNode, +// wpt_list_node **ppNode ); +#define wpal_list_peek_next(pList, pNode, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_next( (vos_list_t *)(pList), (vos_list_node_t *)(pNode), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_prev() - peek at the node before the specified node + + The wpal_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized wpt_list object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_prev( wpt_list *pList, wpt_list_node *pNode, +// wpt_list_node **ppNode ); +#define wpal_list_peek_prev(pList, pNode, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_prev( (vos_list_t *)(pList), (vos_list_node_t *)(pNode), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_before() - insert node at front of a specified + list node + + The wpal_list_insert_before() API will insert a node onto a properly + initialized wpt_list object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_before( wpt_list *pList, +// wpt_list_node *pNodeToInsert, +// wpt_list_node *pNode ); +#define wpal_list_insert_before(pList, pNodeToInsert, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_before( (vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToInsert), (vos_list_node_t *)(pNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_after() - insert node behind a specified list node + + The wpal_list_insert_after() API will insert a node onto a properly + initialized wpt_list object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_after( wpt_list *pList, +// wpt_list_node *pNodeToInsert, +// wpt_list_node *pNode ); +#define wpal_list_insert_after(pList, pNodeToInsert, pNode) \ + (WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_after((vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToInsert), (vos_list_node_t *)(pNode) )) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_node() - remove specified node from wpt_list list + + The wpal_list_remove_node() API will remove a specified node from the + properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_node( wpt_list *pList, wpt_list_node *pNodeToRemove ); +#define wpal_list_remove_node(pList, pNodeToRemove) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_remove_node( (vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToRemove) ) ) + + +#endif // __WLAN_QCT_OS_LIST_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_status.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_status.h new file mode 100644 index 0000000000000..8b425532ffb6a --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_status.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_STATUS_H ) +#define __WLAN_QCT_OS_STATUS_H + +/**========================================================================= + + \file wlan_qct_os_status.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent(Windows XP). + + ========================================================================*/ + +#include "vos_status.h" + +/** + * \brief Macros to derive PAL STATUS from the VOS STATUS + */ + +#define WPAL_IS_VOS_STATUS_E_RESOURCES(status) ( VOS_STATUS_E_RESOURCES == (status)) +#define WPAL_IS_VOS_STATUS_E_NOMEM(status) ( VOS_STATUS_E_NOMEM == (status)) +#define WPAL_IS_VOS_STATUS_E_INVAL(status) ( VOS_STATUS_E_INVAL == (status)) +#define WPAL_IS_VOS_STATUS_E_FAULT(status) ( VOS_STATUS_E_FAULT == (status)) +#define WPAL_IS_VOS_STATUS_E_BUSY(status) ( VOS_STATUS_E_BUSY == (status)) +#define WPAL_IS_VOS_STATUS_E_CANCELED(status) ( VOS_STATUS_E_CANCELED == (status)) +#define WPAL_IS_VOS_STATUS_E_ABORTED(status) ( VOS_STATUS_E_ABORTED == (status)) +#define WPAL_IS_VOS_STATUS_E_NOSUPPORT(status) ( VOS_STATUS_E_NOSUPPORT == (status)) +#define WPAL_IS_VOS_STATUS_E_EMPTY(status) ( VOS_STATUS_E_EMPTY == (status)) +#define WPAL_IS_VOS_STATUS_E_EXISTS(status) ( VOS_STATUS_E_EXISTS == (status)) +#define WPAL_IS_VOS_STATUS_E_TIMEOUT(status) ( VOS_STATUS_E_TIMEOUT == (status)) + + +#define WPAL_STATUS_E_TIMEOUT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_TIMEOUT(status)? eWLAN_PAL_STATUS_E_TIMEOUT : eWLAN_PAL_STATUS_E_FAILURE ) + +#define WPAL_STATUS_E_EXISTS_CHECK(status) ( WPAL_IS_VOS_STATUS_E_EXISTS(status)? eWLAN_PAL_STATUS_E_EXISTS : WPAL_STATUS_E_TIMEOUT_CHECK(status) ) + +#define WPAL_STATUS_E_EMPTY_CHECK(status) ( WPAL_IS_VOS_STATUS_E_EMPTY(status)? eWLAN_PAL_STATUS_E_EMPTY : WPAL_STATUS_E_EXISTS_CHECK(status) ) + +#define WPAL_STATUS_E_NOSUPPORT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_NOSUPPORT(status)? eWLAN_PAL_STATUS_E_NOSUPPORT : WPAL_STATUS_E_EMPTY_CHECK(status) ) + +#define WPAL_STATUS_E_ABORTED_CHECK(status) ( WPAL_IS_VOS_STATUS_E_ABORTED(status)? eWLAN_PAL_STATUS_E_ABORTED : WPAL_STATUS_E_NOSUPPORT_CHECK(status) ) + +#define WPAL_STATUS_E_CANCELED_CHECK(status) ( WPAL_IS_VOS_STATUS_E_CANCELED(status)? eWLAN_PAL_STATUS_E_CANCELED : WPAL_STATUS_E_ABORTED_CHECK(status) ) + +#define WPAL_STATUS_E_BUSY_CHECK(status) ( WPAL_IS_VOS_STATUS_E_BUSY(status)? eWLAN_PAL_STATUS_E_BUSY : WPAL_STATUS_E_CANCELED_CHECK(status) ) + +#define WPAL_STATUS_E_FAULT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_FAULT(status)? eWLAN_PAL_STATUS_E_FAULT : WPAL_STATUS_E_BUSY_CHECK(status) ) + +#define WPAL_STATUS_E_INVAL_CHECK(status) ( WPAL_IS_VOS_STATUS_E_INVAL(status)? eWLAN_PAL_STATUS_E_INVAL : WPAL_STATUS_E_FAULT_CHECK(status) ) + +#define WPAL_STATUS_E_NOMEM_CHECK(status) ( WPAL_IS_VOS_STATUS_E_NOMEM(status)? eWLAN_PAL_STATUS_E_NOMEM : WPAL_STATUS_E_INVAL_CHECK(status) ) + +#define WPAL_STATUS_E_RESOURCES_CHECK(status) ( WPAL_IS_VOS_STATUS_E_RESOURCES(status)? eWLAN_PAL_STATUS_E_RESOURCES : WPAL_STATUS_E_NOMEM_CHECK(status) ) + +#define WPAL_VOS_TO_WPAL_STATUS(status) ( VOS_IS_STATUS_SUCCESS(status)? eWLAN_PAL_STATUS_SUCCESS : WPAL_STATUS_E_RESOURCES_CHECK(status) ) + +#endif // __WLAN_QCT_OS_STATUS_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h new file mode 100644 index 0000000000000..fc80fa258ec34 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_SYNC_H ) +#define __WLAN_QCT_OS_SYNC_H + +/**========================================================================= + + \file wlan_qct_os_sync.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent(LA). + + ========================================================================*/ + +#include "vos_event.h" +#include "vos_lock.h" + +/*Reuse the vos lock and vos event*/ +typedef vos_lock_t wpt_mutex; +typedef vos_event_t wpt_event; + + +#endif // __WLAN_QCT_OS_SYNC_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h new file mode 100644 index 0000000000000..f3e51dea66aae --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_TIMER_H ) +#define __WLAN_QCT_OS_TIMER_H + +/**========================================================================= + + \file wlan_qct_os_timer.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent (Linux Android). + + ========================================================================*/ + +#include "vos_timer.h" + +typedef struct +{ + vos_timer_t timerObj; +} wpt_os_timer; + + +#endif // __WLAN_QCT_OS_TIMER_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_type.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_type.h new file mode 100644 index 0000000000000..bd62d67393db1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_os_type.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_TYPE_H ) +#define __WLAN_QCT_OS_TYPE_H + +/**========================================================================= + + \file wlan_qct_pal_type.h + + \brief define basi types PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform dependent. This is for Linux/Android + + ========================================================================*/ + +#include + +typedef u32 wpt_uint32; + +typedef s32 wpt_int32; + +typedef u16 wpt_uint16; + +typedef s16 wpt_int16; + +typedef u8 wpt_uint8; + +typedef wpt_uint8 wpt_byte; + +typedef s8 wpt_int8; + +typedef wpt_uint8 wpt_boolean; + +typedef u64 wpt_uint64; + +typedef s64 wpt_int64; + +#define WPT_INLINE __inline__ +#define WPT_STATIC static + + +#endif // __WLAN_QCT_OS_TYPE_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h new file mode 100644 index 0000000000000..bdb358c54e6ba --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PACK_ALIGN_H ) +#define __WLAN_QCT_PACK_ALIGN_H + +/**========================================================================= + + \file wlan_pack_align.h + + \brief pack and align primitives + + Definitions for platform independent means of packing and aligning + data structures + + ========================================================================*/ + +/* + + Place the macro WPT_PACK_START above a structure declaration to pack. We + are not going to allow modifying the pack size because pack size cannot be + specified in AMSS and GNU. Place the macro WPT_PACK_END below a structure + declaration to stop the pack. This requirement is necessitated by Windows + which need pragma based prolog and epilog. + + Pack-size > 1-byte is not supported since gcc and arm do not support that. + + Here are some examples + + 1. Pack-size 1-byte foo_t across all platforms + + WPT_PACK_START + typedef WPT_PACK_PRE struct foo_s { ... } WPT_PACK_POST foo_t; + WPT_PACK_END + + 2. 2-byte alignment for foo_t across all platforms + + typedef WPT_ALIGN_PRE(2) struct foo_s { ... } WPT_ALIGN_POST(2) foo_t; + + 3. Pack-size 1-byte and 2-byte alignment for foo_t across all platforms + + WPT_PACK_START + typedef WPT_PACK_PRE WPT_ALIGN_PRE(2) struct foo_s { ... } WPT_ALIGN_POST(2) WPT_PACK_POST foo_t; + WPT_PACK_END + +*/ + +#if defined __GNUC__ + + #define WPT_PACK_START + #define WPT_PACK_END + + #define WPT_PACK_PRE + #define WPT_PACK_POST __attribute__((__packed__)) + + #define WPT_ALIGN_PRE(__value) + #define WPT_ALIGN_POST(__value) __attribute__((__aligned__(__value))) + +#elif defined __arm + + #define WPT_PACK_START + #define WPT_PACK_END + + #define WPT_PACK_PRE __packed + #define WPT_PACK_POST + + #define WPT_ALIGN_PRE(__value) __align(__value) + #define WPT_ALIGN_POST(__value) + +#elif defined _MSC_VER + +#define WPT_PACK_START __pragma(pack(push,1)) +#define WPT_PACK_END __pragma(pack(pop)) + + #define WPT_PACK_PRE + #define WPT_PACK_POST + + #define WPT_ALIGN_PRE(__value) __declspec(align(__value)) + #define WPT_ALIGN_POST(__value) + +#else + + #error Unsupported compiler!!! + +#endif + +#endif // __WLAN_QCT_PACK_ALIGN_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h new file mode 100644 index 0000000000000..c3822481aa22c --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_API_H ) +#define __WLAN_QCT_PAL_API_H + +/**========================================================================= + + \file wlan_qct_pal_api.h + + \brief define general APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +#ifdef MEMORY_DEBUG +#include "vos_memory.h" +#endif /* MEMORY_DEBUG */ + +/*********************************MACRO**********************/ + +// macro to get maximum of two values. +#define WPAL_MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) ) + +// macro to get minimum of two values +#define WPAL_MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) ) + +// macro to get the ceiling of an integer division operation... +#define WPAL_CEIL_DIV( _a, _b ) (( 0 != (_a) % (_b) ) ? ( (_a) / (_b) + 1 ) : ( (_a) / (_b) )) + +// macro to return the floor of an integer division operation +#define WPAL_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) ) + +#define WPAL_SWAP_U16(_x) \ + ( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) ) + +#define WPAL_SWAP_U32(_x) \ + (( ( ( (_x) << 24 ) & 0xFF000000 ) | ( ( (_x) >> 24 ) & 0x000000FF ) ) | \ + ( ( ( (_x) << 8 ) & 0x00FF0000 ) | ( ( (_x) >> 8 ) & 0x0000FF00 ) )) + +// Endian operations for Big Endian and Small Endian modes +#ifndef ANI_BIG_BYTE_ENDIAN + +//This portion is for little-endian cpu +#define WPAL_CPU_TO_BE32(_x) WPAL_SWAP_U32(_x) +#define WPAL_BE32_TO_CPU(_x) WPAL_SWAP_U32(_x) +#define WPAL_CPU_TO_BE16(_x) WPAL_SWAP_U16(_x) +#define WPAL_BE16_TO_CPU(_x) WPAL_SWAP_U16(_x) +#define WPAL_CPU_TO_LE32(_x) (_x) +#define WPAL_LE32_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_LE16(_x) (_x) +#define WPAL_LE16_TO_CPU(_x) (_x) + +#else //#ifndef ANI_BIG_BYTE_ENDIAN + +//This portion is for big-endian cpu +#define WPAL_CPU_TO_BE32(_x) (_x) +#define WPAL_BE32_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_BE16(_x) (_x) +#define WPAL_BE16_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_LE32(_x) WPAL_SWAP_U32(_x) +#define WPAL_LE32_TO_CPU(_x) WPAL_SWAP_U32(_x) +#define WPAL_CPU_TO_LE16(_x) WPAL_SWAP_U16(_x) +#define WPAL_LE16_TO_CPU(_x) WPAL_SWAP_U16(_x) + +#endif //#ifndef ANI_BIG_BYTE_ENDIAN + + +/*********************************Generic API*******************************/ +/*--------------------------------------------------------------------------- + wpalOpen - Initialize PAL + Param: + ppPalContext – pointer to a caller allocated pointer. It is opaque to caller. + Caller save the returned pointer for future use when calling + PAL APIs. If this is NULL, it means that PAL doesn't need it. + pOSContext - Pointer to a context that is OS specific. This is NULL is a + particular PAL doesn't use it for that OS. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalOpen(void **ppPalContext, void *pOSContext); + +/*--------------------------------------------------------------------------- + wpalClose - Release PAL + Param: + pPalContext – pointer returned from wpalOpen. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalClose(void *pPalContext); + + +/*********************************Memory API********************************/ +#ifdef MEMORY_DEBUG +/* For Memory Debugging, Hook up PAL memory API to VOS memory API */ +#define wpalMemoryAllocate vos_mem_malloc +#define wpalMemoryFree vos_mem_free +#else + +/*--------------------------------------------------------------------------- + wpalMemoryAllocate - Allocate memory + Param: + size – number of bytes to allocate + Return: + A pointer to the allocated memory. + NULL – fail to allocate memory +---------------------------------------------------------------------------*/ +void *wpalMemoryAllocate(wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalMemoryFree - Free allocated memory + Param: + pv – pointer to buffer to be freed + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryFree(void *pv); +#endif /* MEMORY_DEBUG */ + +/*--------------------------------------------------------------------------- + wpalMemoryCopy - copy memory + Param: + dest – address which data is copied to + src – address which data is copied from + size – number of bytes to copy + Return: + eWLAN_PAL_STATUS_SUCCESS + eWLAN_PAL_STATUS_INVALID_PARAM +---------------------------------------------------------------------------*/ +wpt_status wpalMemoryCopy(void * dest, void * src, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalMemoryCompare - compare memory + Param: + buf1 – address of buffer1 + buf2 – address of buffer2 + size – number of bytes to compare + Return: + eWLAN_PAL_TRUE – if two buffers have same content + eWLAN_PAL_FALSE – not match +---------------------------------------------------------------------------*/ +wpt_boolean wpalMemoryCompare(void * buf1, void * buf2, wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalMemoryZero - Zero memory + Param: + buf – address of buffer to be zero + size – number of bytes to zero + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryZero(void *buf, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalMemoryFill - Fill memory with one pattern + Param: + buf – address of buffer to be zero + size – number of bytes to zero + bFill - one byte of data to fill in (size) bytes from the start of the buffer + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryFill(void *buf, wpt_uint32 size, wpt_byte bFill); + + +/*--------------------------------------------------------------------------- + wpalDmaMemoryAllocate - Allocate memory ready for DMA. Aligned at 4-byte + Param: + pPalContext - PAL context pointer + size – number of bytes to allocate + ppPhysicalAddr – Physical address of the buffer if allocation succeeds + Return: + A pointer to the allocated memory (virtual address). + NULL – fail to allocate memory +-----------------------------------------------------------------------------*/ +void *wpalDmaMemoryAllocate(wpt_uint32 size, void **ppPhysicalAddr); + +/*--------------------------------------------------------------------------- + wpalDmaMemoryFree - Free memory ready for DMA + Param: + pPalContext - PAL context pointer + pv – address for the buffer to be freed + Return: + None +---------------------------------------------------------------------------*/ +void wpalDmaMemoryFree(void *pv); + + + +/*--------------------------------------------------------------------------- + wpalDbgReadRegister - Read register from the WiFi BB chip + Param: + regAddr - register address + pregValue - return value from register if success + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +static inline wpt_status wpalDbgReadRegister(wpt_uint32 regAddr, wpt_uint32 *pregValue) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalDbgWriteRegister - Write a value to the register in the WiFi BB chip + Param: + regAddr - register address + regValue - value to be written + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +static inline wpt_status wpalDbgWriteRegister(wpt_uint32 regAddr, + wpt_uint32 regValue) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalDbgReadMemory - Read memory from WiFi BB chip space + Param: + memAddr - address of memory + buf - output + len - length to be read + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +static inline wpt_status wpalDbgReadMemory(wpt_uint32 memAddr, wpt_uint8 *buf, + wpt_uint32 len) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalDbgWriteMemory - Write a value to the memory in the WiFi BB chip space + Param: + memAddr - memory address + buf - vlaue to be written + len - length of buf + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +static inline wpt_status wpalDbgWriteMemory(wpt_uint32 memAddr, wpt_uint8 *buf, + wpt_uint32 len) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Shutdown WLAN driver + + This API is requied by SSR, call in to 'VOS shutdown' to shutdown WLAN + driver when Riva crashes. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverShutdown(void); + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Re-init WLAN driver + + This API is requied by SSR, call in to 'VOS re-init' to re-init WLAN + driver. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverReInit(void); + +/*--------------------------------------------------------------------------- + wpalRivaSubystemRestart - Initiate Riva SSR + + This API is called by WLAN driver to initiate Riva SSR + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalRivaSubystemRestart(void); + +/*--------------------------------------------------------------------------- + wpalWlanReload - Initiate WLAN Driver reload + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWlanReload(void); + +/*--------------------------------------------------------------------------- + wpalWcnssResetIntr - Trigger the reset FIQ to Riva + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWcnssResetIntr(void); + +/*--------------------------------------------------------------------------- + wpalFwDumpReq - Trigger the dump commands to Firmware + + Param: + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalFwDumpReq(wpt_uint32 cmd, wpt_uint32 arg1, wpt_uint32 arg2, + wpt_uint32 arg3, wpt_uint32 arg4); +/*--------------------------------------------------------------------------- + wpalDevicePanic - Trigger Device Panic + Trigger device panic to help debug + + Param: + NONE + + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalDevicePanic(void); +#endif // __WLAN_QCT_PAL_API_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h new file mode 100644 index 0000000000000..9ad2126e1c554 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_PAL_DEVICE_H +#define WLAN_QCT_PAL_DEVICE_H +/* ==================================================================================================================== + + @file wlan_qct_pal_device.h + + @brief + This file contains the external API exposed by WLAN PAL Device specific functionalities + + * ==================================================================================================================*/ + +/* ==================================================================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order + + When Who What, Where, Why + --------- -------- ------------------------------------------------------------------------------- + FEB/07/11 sch Create module + * ==================================================================================================================*/ + +/* ==================================================================================================================== + INCLUDE FILES FOR MODULES + * ==================================================================================================================*/ +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +/* ==================================================================================================================== + PREPROCESSORS AND DEFINITIONS + * ==================================================================================================================*/ +#define DXE_INTERRUPT_TX_COMPLE 0x02 +#define DXE_INTERRUPT_RX_READY 0x04 +#define WPAL_ISR_CLIENT_MAX 0x08 + +#define WPAL_SMSM_WLAN_TX_ENABLE 0x00000400 +#define WPAL_SMSM_WLAN_TX_RINGS_EMPTY 0x00000200 + +/* ==================================================================================================================== + @ Function Name + wpalIsrType + + @ Description + DXE ISR functio prototype + DXE should register ISR function into platform + + @ Parameters + pVoid pDXEContext : DXE module control block + + @ Return + NONE + * ==================================================================================================================*/ +typedef void (* wpalIsrType)(void *usrCtxt); + +/* ==================================================================================================================== + GLOBAL FUNCTIONS + * ==================================================================================================================*/ +/* ==================================================================================================================== + @ Function Name + + @ Description + + @ Arguments + + @ Return value + + @ Note + + * ==================================================================================================================*/ +wpt_status wpalDeviceInit +( + void *deviceCB +); + +/* ==================================================================================================================== + @ Function Name + + @ Description + + @ Arguments + + @ Return value + + @ Note + + * ==================================================================================================================*/ +wpt_status wpalDeviceClose +( + void *deviceC +); + +/* ========================================================================== + CLIENT SERVICE EXPOSE FUNCTIONS GENERIC + * =========================================================================*/ +/** + @brief wpalRegisterInterrupt provides a mechansim for client + to register support for a given interrupt + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can register to support one of these. It is expected that the core + DXE implementation will invoke this API twice, once for each interrupt. + + @param intType: Enumeration of the interrupt type (TX or RX) + @param callbackFunction: ISR function pointer + @param usrCtxt: User context passed back whenever the + callbackFunction is invoked + + @return SUCCESS if the registration was successful +*/ +wpt_status wpalRegisterInterrupt +( + wpt_uint32 intType, + wpalIsrType callbackFunction, + void *usrCtxt +); + +/** + @brief wpalUnRegisterInterrupt provides a mechansim for client + to un-register for a given interrupt + + When DXE stop, remove registered information from PAL + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return NONE +*/ + +void wpalUnRegisterInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalEnableInterrupt provides a mechansim for a client + to request that a given interrupt be enabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer allows a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was enabled +*/ +wpt_status wpalEnableInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalDisableInterrupt provides a mechansim for a client + to request that a given interrupt be disabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer not allow a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was disabled +*/ +wpt_status wpalDisableInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalWriteRegister provides a mechansim for a client + to write data into a hardware data register + + @param address: Physical memory address of the register + @param data: Data value to be written + + @return SUCCESS if the data was successfully written +*/ +static inline wpt_status wpalReadRegister +( + wpt_uint32 address, + wpt_uint32 *data +) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalReadRegister provides a mechansim for a client + to read data from a hardware data register + + @param address: Physical memory address of the register + @param data: Return location for value that is read + + @return SUCCESS if the data was successfully read +*/ +static inline wpt_status wpalWriteRegister +( + wpt_uint32 address, + wpt_uint32 data +) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalReadDeviceMemory provides a mechansim for a client + to read data from the hardware address space + + @param address: Start address of physical memory to be read + @param d_buffer: Virtual destination address to which the + data will be written + @param len: Number of bytes of data to be read + + @return SUCCESS if the data was successfully read +*/ +static inline wpt_status wpalReadDeviceMemory +( + wpt_uint32 address, + wpt_uint8 *DestBuffer, + wpt_uint32 len +) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalWriteDeviceMemory provides a mechansim for a client + to write data into the hardware address space + + @param address: Start address of physical memory to be written + @param s_buffer: Virtual source address from which the data will + be read + @param len: Number of bytes of data to be written + + @return SUCCESS if the data was successfully written +*/ +static inline wpt_status wpalWriteDeviceMemory +( + wpt_uint32 address, + wpt_uint8 *srcBuffer, + wpt_uint32 len +) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalNotifySmsm provides a mechansim for a client to + notify SMSM to start DXE engine and/or condition of Tx + ring buffer + + @param clrSt: bit(s) to be cleared on the MASK + @param setSt: bit(s) to be set on the MASK + + @return SUCCESS if the operation is successful +*/ +wpt_status wpalNotifySmsm +( + wpt_uint32 clrSt, + wpt_uint32 setSt +); + +/** + @brief wpalActivateRxInterrupt activates wpalRxIsr + + @param NONE + + @return NONE +*/ +void wpalActivateRxInterrupt(void); + +/** + @brief wpalInactivateRxInterrupt inactivates wpalRxIsr + + @param NONE + + @return NONE +*/ +void wpalInactivateRxInterrupt(void); + +#endif /* WLAN_QCT_PAL_DEVICE_H*/ diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h new file mode 100644 index 0000000000000..716fbd5658822 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_LIST_H ) +#define __WLAN_QCT_PAL_LIST_H + +/**========================================================================= + + \file wlan_qct_pal_list.h + + \brief define linked list PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + ========================================================================*/ + +#include "wlan_qct_os_list.h" + + +#endif // __WLAN_QCT_PAL_LIST_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h new file mode 100644 index 0000000000000..d69b82a815b5d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_MSG_H ) +#define __WLAN_QCT_PAL_MSG_H + +/**========================================================================= + + \file wlan_qct_pal_msg.h + + \brief define general message APIs PAL exports to support legacy UMAC. + wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent. Only work with legacy UMAC. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +typedef struct swpt_msg wpt_msg; + +typedef void (*wpal_msg_callback)(wpt_msg *pMsg); + +struct swpt_msg +{ + wpt_uint16 type; + wpt_uint16 reserved; + void *ptr; + wpt_uint32 val; + wpal_msg_callback callback; + void *pContext; +}; + + +/*--------------------------------------------------------------------------- + wpalPostCtrlMsg – Post a message to control context so it can + be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostCtrlMsg(void *pPalContext, wpt_msg *pMsg); + + +/*--------------------------------------------------------------------------- + wpalPostTxMsg – Post a message to TX context so it can be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostTxMsg(void *pPalContext, wpt_msg *pMsg); + +/*--------------------------------------------------------------------------- + wpalPostRxMsg – Post a message to RX context so it can be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostRxMsg(void *pPalContext, wpt_msg *pMsg); + + + +#endif // __WLAN_QCT_PAL_API_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h new file mode 100644 index 0000000000000..ed7f5f163848d --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2011-2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_PACKET_H ) +#define __WLAN_QCT_PAL_PACKET_H + +/**========================================================================= + + \file wlan_qct_pal_packet.h + + \brief define PAL packet. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "vos_types.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +// The size of the data buffer in vos/pal packets +// Explanation: +// MTU size = 1500 bytes +// Max number of BD/PDUs required to hold payload of 1500 = +// 12 PDUs (124 bytes each) + 1 BD (12 bytes for payload) = +// 13 BD/PDUs = 13 x 128 = 1664 bytes +// +// In case of A-MSDU with each MSDU having payload of 1500 bytes: +// 1st MSDU = requires 13 BD/PDUs as per the above equation. +// 2nd MSDU = HW inserts an extra BD to hold the information of the 2nd +// MSDU and the payload portion of this BD is unused which means to cover +// 1500 bytes we require 13 PDUs. +// So 13 PDUs + 1 BD = 14 BD/PDUs = 1792 bytes. +// +// HOWEVER +// In case of A-MSDU with errors, the ADU will push to the host up to +// 2346 bytes. If that is the 2nd or later MSDU the worst case is: +// 1 Prepended BD/PDU +// 1 BD/PDU containing the 1st 4 bytes of the delimiter +// 1 BD/PDU containing the last 10 bytes of the delimiter +// plus the first 114 of the payload +// 18 BD/PDUs containing the remaining 2232 bytes of the payload +// 2346 - 114 = 2232; 2232 / 124 = 18 +// So 21 BD/PDUs are required + +//The size of AMSDU frame per spec can be a max of 3839 bytes +// in BD/PDUs that means 30 (one BD = 128 bytes) +// we must add the size of the 802.11 header to that +#define VPKT_SIZE_BUFFER ((30 * 128) + 32) + +/* Transport channel count to report DIAG */ +#define WPT_NUM_TRPT_CHANNEL 4 +/* Transport channel name string size */ +#define WPT_TRPT_CHANNEL_NAME 4 + +typedef enum +{ + ///Packet is used to transmit 802.11 Management frames. + eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT, + ///Packet is used to transmit 802.11 Data frames. + eWLAN_PAL_PKT_TYPE_TX_802_11_DATA, + ///Packet is used to transmit 802.3 Data frames. + eWLAN_PAL_PKT_TYPE_TX_802_3_DATA, + ///Packet contains Received data of an unknown frame type + eWLAN_PAL_PKT_TYPE_RX_RAW +} wpt_packet_type; + + +typedef struct swpt_packet +{ + /* + Pointer to a buffer for BD for TX packets + For RX packets. The pBD MUST set to NULL. + PAL packet shall set the pointer point to the start of the flat buffer + where the BD starts. + */ + void *pBD; + //Physical address for pBD for DMA-able devices + void *pBDPhys; + //OS dependent strucutre used only by OS specific code. + void *pOSStruct; + void *pktMetaInfo; + wpt_packet_type pktType; + //The number of bytes pBD uses. It MUST be set to 0 for RX packets + wpt_uint16 BDLength; + + //Internal data for PAL packet implementation usage only + void *pInternalData; +} wpt_packet; + +typedef struct swpt_iterator +{ + void *pNext; + void *pCur; + void *pContext; +} wpt_iterator; + +/* Each specific channel dedicated information should be logged */ +typedef struct +{ + char channelName[WPT_TRPT_CHANNEL_NAME]; + v_U32_t numDesc; + v_U32_t numFreeDesc; + v_U32_t numRsvdDesc; + v_U32_t headDescOrder; + v_U32_t tailDescOrder; + v_U32_t ctrlRegVal; + v_U32_t statRegVal; + v_U32_t numValDesc; + v_U32_t numInvalDesc; +} wpt_log_data_stall_channel_type; + +/* Transport log context */ +typedef struct +{ + v_U32_t PowerState; + v_U32_t numFreeBd; + wpt_log_data_stall_channel_type dxeChannelInfo[WPT_NUM_TRPT_CHANNEL]; +} wpt_log_data_stall_type; + +//pPkt is a pointer to wpt_packet +#define WPAL_PACKET_SET_BD_POINTER(pPkt, pBd) ( (pPkt)->pBD = (pBd) ) +#define WPAL_PACKET_GET_BD_POINTER(pPkt) ( (pPkt)->pBD ) +//Access the physical address of BD +#define WPAL_PACKET_SET_BD_PHYS(pPkt, pBdPhys) ( (pPkt)->pBDPhys = (pBdPhys) ) +#define WPAL_PACKET_GET_BD_PHYS(pPkt) ( (pPkt)->pBDPhys ) +#define WPAL_PACKET_SET_BD_LENGTH(pPkt, len) ( (pPkt)->BDLength = (len) ) +#define WPAL_PACKET_GET_BD_LENGTH(pPkt) ( (pPkt)->BDLength ) +#define WPAL_PACKET_SET_METAINFO_POINTER(pPkt, p) ( (pPkt)->pktMetaInfo = (p) ) +#define WPAL_PACKET_GET_METAINFO_POINTER(pPkt) ( (pPkt)->pktMetaInfo ) +#define WPAL_PACKET_SET_TYPE(pPkt, type) ( (pPkt)->pktType = (type) ) +#define WPAL_PACKET_GET_TYPE(pPkt) ( (pPkt)->pktType ) +#define WPAL_PACKET_SET_OS_STRUCT_POINTER(pPkt, pStruct) ( (pPkt)->pOSStruct = (pStruct) ) +#define WPAL_PACKET_GET_OS_STRUCT_POINTER(pPkt) ( (pPkt)->pOSStruct ) +#define WPAL_PACKET_IS_FLAT_BUF(pktType) ( (eWLAN_PAL_PKT_TYPE_RX_RAW == (pktType)) || \ + (eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == (pktType)) ) + +/* RX RAW packet alloc fail due to out of resource CB function type */ +typedef void ( *wpalPacketLowPacketCB )( wpt_packet *pPacket, void *usrData ); + + +/*--------------------------------------------------------------------------- + wpalPacketInit – Initialize all wpt_packet related objects. Allocate memory for wpt_packet. + Allocate memory for TX management frames and RX frames. + For our legacy UMAC, it is not needed because vos_packet contains wpt_packet. + Param: + pPalContext – A context PAL uses?? + Return: + eWLAN_PAL_STATUS_SUCCESS -- success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketInit(void *pPalContext); + +/*--------------------------------------------------------------------------- + wpalPacketClose – Free all allocated resource by wpalPacketInit. + For our legacy UMAC, it is not needed because vos_packet contains pal_packet. + Param: + pPalContext – A context PAL uses?? + Return: + eWLAN_PAL_STATUS_SUCCESS -- success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketClose(void *pPalContext); + + +/*--------------------------------------------------------------------------- + wpalPacketAlloc – Allocate a wpt_packet from PAL. + Param: + pPalContext – A context PAL uses?? + pktType – specify the type of wpt_packet to allocate + nPktSize - specify the maximum size of the packet buffer. + Return: + A pointer to the wpt_packet. NULL means fail. +---------------------------------------------------------------------------*/ +wpt_packet * wpalPacketAlloc(wpt_packet_type pktType, wpt_uint32 nPktSize, + wpalPacketLowPacketCB rxLowCB, void *usrdata); + +/*--------------------------------------------------------------------------- + wpalPacketFree – Free a wpt_packet chain for one particular type. + Packet type is carried in wpt_packet structure. + Param: + pPalContext – A context PAL uses?? + pPkt - pointer to a packet to be freed. + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketFree(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalPacketGetLength – Get number of bytes in a wpt_packet. + Param: + pPalContext – PAL context returned from PAL open + pPkt - pointer to a packet to be freed. + Return: + Length of the data include layer-2 headers. For example, if the frame is 802.3, + the length includes the ethernet header. +---------------------------------------------------------------------------*/ +wpt_uint32 wpalPacketGetLength(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimHead – Move the starting offset and reduce packet length. + The function can only be used with raw packets, + whose buffer is one piece and allocated by WLAN driver. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take off the head. + Return: + eWPAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimHead(wpt_packet *pPkt, wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimTail – reduce the length of the packet. The function can + only be used with raw packets, whose buffer is one piece and + allocated by WLAN driver. This also reduce the length of the packet. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take of the packet length + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimTail(wpt_packet *pPkt, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalPacketGetRawBuf – Return the starting buffer's virtual address for the RAW flat buffer + It is inline in hope of faster implementation for certain platform. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +extern wpt_uint8 *wpalPacketGetRawBuf(wpt_packet *pPkt); + + +/*--------------------------------------------------------------------------- + wpalPacketSetRxLength – Set the valid data length on a RX packet. This function must + be called once per RX packet per receiving. It indicates the available data length from + the start of the buffer. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +extern wpt_status wpalPacketSetRxLength(wpt_packet *pPkt, wpt_uint32 len); + + +/*--------------------------------------------------------------------------- + wpalIteratorInit – Initialize an interator by updating pCur to first item. + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorInit(wpt_iterator *pIter, wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalIteratorNext – Get the address for the next item + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + ppAddr – Caller allocated pointer to return the address of the item. For DMA-able devices, this is the physical address of the item. + pLen – To return the number of bytes in the item. + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorNext(wpt_iterator *pIter, wpt_packet *pPacket, void **ppAddr, wpt_uint32 *pLen); + + +/*--------------------------------------------------------------------------- + wpalLockPacketForTransfer – Packet must be locked before transfer can begin, + the lock will ensure that the DMA engine has access to the data packet + in a cache coherent manner + + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalLockPacketForTransfer( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalUnlockPacket – Once the transfer has been completed the packet should + be unlocked so that normal operation may resume + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalUnlockPacket( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalPacketGetFragCount – Get count of memory chains (fragments) + in a packet + Param: + pPacket – pointer to a wpt_packet + + Return: + memory fragment count in a packet +---------------------------------------------------------------------------*/ +wpt_int32 wpalPacketGetFragCount(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalIsPacketLocked – Check whether the Packet is locked for DMA. + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS + eWLAN_PAL_STATUS_E_FAILURE + eWLAN_PAL_STATUS_E_INVAL +---------------------------------------------------------------------------*/ +wpt_status wpalIsPacketLocked( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalGetNumRxRawPacket Query available RX RAW total buffer count + param: + numRxResource pointer of queried value + + return: + eWLAN_PAL_STATUS_SUCCESS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxRawPacket(wpt_uint32 *numRxResource); + +/*--------------------------------------------------------------------------- + wpalPacketStallUpdateInfo – Update each channel information when stall + detected, also power state and free resource count + + Param: + powerState ? WLAN system power state when stall detected + numFreeBd ? Number of free resource count in HW + channelInfo ? Each channel specific information when stall happen + channelNum ? Channel number update information + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallUpdateInfo +( + v_U32_t *powerState, + v_U32_t *numFreeBd, + wpt_log_data_stall_channel_type *channelInfo, + v_U8_t channelNum +); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/*--------------------------------------------------------------------------- + wpalPacketStallDumpLog – Trigger to send log packet to DIAG + Updated transport system information will be sent to DIAG + + Param: + NONE + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallDumpLog +( + void +); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#endif // __WLAN_QCT_PAL_PACKET_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h new file mode 100644 index 0000000000000..43b4e93b88faf --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_STATUS_H ) +#define __WLAN_QCT_PAL_STATUS_H + +/**========================================================================= + + \file wlan_qct_pal_status.h + + \brief define status PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + ========================================================================*/ + +typedef enum +{ + /// Request succeeded! + eWLAN_PAL_STATUS_SUCCESS, + + /// Request failed because system resources (other than memory) to + /// fulfill request are not available. + eWLAN_PAL_STATUS_E_RESOURCES, + + /// Request failed because not enough memory is available to + /// fulfill the request. + eWLAN_PAL_STATUS_E_NOMEM, + + /// Request failed because there of an invalid request. This is + /// typically the result of invalid parameters on the request. + eWLAN_PAL_STATUS_E_INVAL, + + /// Request failed because handling the request would cause a + /// system fault. This error is typically returned when an + /// invalid pointer to memory is detected. + eWLAN_PAL_STATUS_E_FAULT, + + /// Request failed because device or resource is busy. + eWLAN_PAL_STATUS_E_BUSY, + + /// Request did not complete because it was canceled. + eWLAN_PAL_STATUS_E_CANCELED, + + /// Request did not complete because it was aborted. + eWLAN_PAL_STATUS_E_ABORTED, + + /// Request failed because the request is valid, though not supported + /// by the entity processing the request. + eWLAN_PAL_STATUS_E_NOSUPPORT, + + /// Request failed because of an empty condition + eWLAN_PAL_STATUS_E_EMPTY, + + /// Existance failure. Operation could not be completed because + /// something exists or does not exist. + eWLAN_PAL_STATUS_E_EXISTS, + + /// Operation timed out + eWLAN_PAL_STATUS_E_TIMEOUT, + + /// Request failed for some unknown reason. Note don't use this + /// status unless nothing else applies + eWLAN_PAL_STATUS_E_FAILURE, +} wpt_status; + + +#define WLAN_PAL_IS_STATUS_SUCCESS(status) ( eWLAN_PAL_STATUS_SUCCESS == (status) ) + +#endif // __WLAN_QCT_PAL_STATUS_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h new file mode 100644 index 0000000000000..d0055cc4d0cf1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_SYNC_H ) +#define __WLAN_QCT_PAL_SYNC_H + +/**========================================================================= + + \file wlan_pal_sync.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_os_sync.h" + + +#define WLAN_PAL_WAIT_INFINITE 0xFFFFFFFF + +/*--------------------------------------------------------------------------- + wpalMutexInit – initialize a mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexInit(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexDelete – invalidate a mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexDelete(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexAcquire – acquire a mutex object. It is blocked until the object is acquired. + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexAcquire(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexRelease – Release a held mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexRelease(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalEventInit – initialize an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventInit(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventDelete – invalidate an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventDelete(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventWait – Wait on an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + timeout – timerout value at unit of milli-seconds. 0xffffffff means infinite wait + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventWait(wpt_event *pEvent, wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalEventSet – Set an event object to signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventSet(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventReset – Set an event object to non-signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventReset(wpt_event *pEvent); + + +#endif // __WLAN_QCT_PAL_SYNC_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h new file mode 100644 index 0000000000000..1b6964e3750bc --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_TIMER_H ) +#define __WLAN_QCT_PAL_TIMER_H + +/**========================================================================= + + \file wlan_qct_pal_timer.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_os_timer.h" + + +typedef VOS_TIMER_STATE WPAL_TIMER_STATE; + +typedef void (*wpal_timer_callback)(void *pUserData); + +typedef struct +{ + wpt_os_timer timer; + wpal_timer_callback callback; + void *pUserData; +} wpt_timer; + + +/*--------------------------------------------------------------------------- + wpalTimerInit - initialize a wpt_timer object + Param: + pTimer - a pointer to caller allocated wpt_timer object + callback - A callback function + pUserData - A pointer to data pass as parameter of the callback function. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerInit(wpt_timer * pTimer, wpal_timer_callback callback, void *pUserData); + +/*--------------------------------------------------------------------------- + wpalTimerDelete - invalidate a wpt_timer object + Param: + pTimer - a pointer to caller allocated wpt_timer object + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerDelete(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalTimerStart - start a wpt_timer object with a timeout value + Param: + pTimer - a pointer to caller allocated wpt_timer object + timeout - timeout value of the timer. In unit of milli-seconds. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStart(wpt_timer * pTimer, wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalTimerStop - stop a wpt_timer object. Stop doesn’t guarantee the timer handler is not called if it is already timeout. + Param: + pTimer - a pointer to caller allocated wpt_timer object + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStop(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalTimerGetCurStatus - Get the current status of timer + + pTimer - a pointer to caller allocated wpt_timer object + + return + WPAL_TIMER_STATE +---------------------------------------------------------------------------*/ +WPAL_TIMER_STATE wpalTimerGetCurStatus(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalGetSystemTime - Get the system time in milliseconds + + return + current time in milliseconds +---------------------------------------------------------------------------*/ +wpt_uint32 wpalGetSystemTime(void); + +/*--------------------------------------------------------------------------- + wpalSleep - sleep for a specified interval + Param: + timeout - amount of time to sleep. In unit of milli-seconds. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalSleep(wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalBusyWait - Thread busy wait with specified usec + Param: + usecDelay - amount of time to wait. In unit of micro-seconds. + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalBusyWait(wpt_uint32 usecDelay); + +#endif // __WLAN_QCT_PAL_TIMER_H diff --git a/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h new file mode 100644 index 0000000000000..9864060a0cb15 --- /dev/null +++ b/drivers/staging/qcacld-2.0/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_TYPE_H ) +#define __WLAN_QCT_PAL_TYPE_H + +/**========================================================================= + + \file wlan_qct_pal_type.h + + \brief define basic types PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + ========================================================================*/ +#include "wlan_qct_os_type.h" + +typedef wpt_uint8 wpt_macAddr[6]; + +enum +{ + eWLAN_PAL_FALSE = 0, + eWLAN_PAL_TRUE = 1, +}; + +typedef enum +{ + eWLAN_MODULE_DAL, + eWLAN_MODULE_DAL_CTRL, + eWLAN_MODULE_DAL_DATA, + eWLAN_MODULE_PAL, + + //Always the last one + eWLAN_MODULE_COUNT +} wpt_moduleid; + + +typedef struct +{ + //BIT order is most likely little endian. + //This structure is for netowkr-order byte array (or big-endian byte order) +#ifndef WLAN_PAL_BIG_ENDIAN_BIT + wpt_byte protVer :2; + wpt_byte type :2; + wpt_byte subType :4; + + wpt_byte toDS :1; + wpt_byte fromDS :1; + wpt_byte moreFrag :1; + wpt_byte retry :1; + wpt_byte powerMgmt :1; + wpt_byte moreData :1; + wpt_byte wep :1; + wpt_byte order :1; + +#else + + wpt_byte subType :4; + wpt_byte type :2; + wpt_byte protVer :2; + + wpt_byte order :1; + wpt_byte wep :1; + wpt_byte moreData :1; + wpt_byte powerMgmt :1; + wpt_byte retry :1; + wpt_byte moreFrag :1; + wpt_byte fromDS :1; + wpt_byte toDS :1; + +#endif + +} wpt_FrameCtrl; + +typedef struct +{ + /* Frame control field */ + wpt_FrameCtrl frameCtrl; + /* Duration ID */ + wpt_uint16 usDurationId; + /* Address 1 field */ + wpt_macAddr vA1; + /* Address 2 field */ + wpt_macAddr vA2; + /* Address 3 field */ + wpt_macAddr vA3; + /* Sequence control field */ + wpt_uint16 sSeqCtrl; + /* Optional A4 address */ + wpt_macAddr optvA4; + /* Optional QOS control field */ + wpt_uint16 usQosCtrl; +}wpt_80211Header; + +typedef struct +{ + wpt_macAddr dest; + wpt_macAddr sec; + wpt_uint16 lenOrType; +} wpt_8023Header; + + +#endif // __WLAN_QCT_PAL_TYPE_H diff --git a/drivers/staging/qcacld-2.0/Kbuild b/drivers/staging/qcacld-2.0/Kbuild new file mode 100644 index 0000000000000..a6337dd8f2324 --- /dev/null +++ b/drivers/staging/qcacld-2.0/Kbuild @@ -0,0 +1,1310 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +ifeq ($(CONFIG_CLD_HL_SDIO_CORE), y) + CONFIG_QCA_WIFI_SDIO := 1 +endif + +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) + CONFIG_ROME_IF = sdio +endif + +ifndef CONFIG_ROME_IF + #use pci as default interface + CONFIG_ROME_IF = pci +endif + +ifeq ($(KERNEL_BUILD),1) + # These are provided in external module based builds + # Need to explicitly define for Kernel-based builds + MODNAME := wlan + WLAN_ROOT := drivers/staging/qcacld-2.0 + WLAN_OPEN_SOURCE := 1 +endif + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + + #Flag to enable BlueTooth AMP feature + CONFIG_PRIMA_WLAN_BTAMP := n + + #Flag to enable Legacy Fast Roaming3(LFR3) + CONFIG_QCACLD_WLAN_LFR3 := y + + #JB kernel has PMKSA patches, hence enabling this flag + CONFIG_PRIMA_WLAN_OKC := y + + # JB kernel has CPU enablement patches, so enable + ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_PRIMA_WLAN_11AC_HIGH_TP := y + endif + ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_PRIMA_WLAN_11AC_HIGH_TP := n + endif + ifeq ($(CONFIG_ROME_IF),sdio) + CONFIG_PRIMA_WLAN_11AC_HIGH_TP := n + endif + #Flag to enable TDLS feature + CONFIG_QCOM_TDLS := y + + #Flag to enable Fast Transition (11r) feature + CONFIG_QCOM_VOWIFI_11R := y + + ifneq ($(CONFIG_QCA_CLD_WLAN),) + ifeq ($(CONFIG_CNSS),y) + #Flag to enable Protected Managment Frames (11w) feature + CONFIG_WLAN_FEATURE_11W := y + #Flag to enable LTE CoEx feature + CONFIG_QCOM_LTE_COEX := y + #Flag to enable LPSS feature + CONFIG_WLAN_FEATURE_LPSS := y + endif + endif + + + #Flag to enable Protected Managment Frames (11w) feature + ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_WLAN_FEATURE_11W := y + endif + ifeq ($(CONFIG_ROME_IF),sdio) + CONFIG_WLAN_FEATURE_11W := y + endif + + #Flag to enable NAN + CONFIG_FEATURE_NAN := y + + #Flag to enable Linux QCMBR feature as default feature + ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_LINUX_QCMBR :=y + endif +endif + +# To enable ESE upload, dependent config +# CONFIG_QCOM_ESE must be enabled. +CONFIG_QCOM_ESE := y +CONFIG_QCOM_ESE_UPLOAD := y + +# Feature flags which are not (currently) configurable via Kconfig + +#Whether to build debug version +BUILD_DEBUG_VERSION := 1 + +#Enable this flag to build driver in diag version +BUILD_DIAG_VERSION := 1 + +#Do we panic on bug? default is to warn +PANIC_ON_BUG := 1 + +#Re-enable wifi on WDI timeout +RE_ENABLE_WIFI_ON_WDI_TIMEOUT := 0 + +#Enable OS specific ADF abstraction +CONFIG_ADF_SUPPORT := 1 + +#Enable OL debug and wmi unified functions +CONFIG_ATH_PERF_PWR_OFFLOAD := 1 + +#Disable packet log +CONFIG_REMOVE_PKT_LOG := 0 + +#Enable 11AC TX +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_ATH_11AC_TXCOMPACT := 1 +endif +ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_ATH_11AC_TXCOMPACT := 0 +endif +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) +CONFIG_ATH_11AC_TXCOMPACT := 0 +endif + +#Enable per vdev Tx desc pool +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_PER_VDEV_TX_DESC_POOL := 0 +endif +ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_PER_VDEV_TX_DESC_POOL := 1 +endif +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) + CONFIG_PER_VDEV_TX_DESC_POOL := 0 +endif + + +#Enable OS specific IRQ abstraction +CONFIG_ATH_SUPPORT_SHARED_IRQ := 1 + +#Enable message based HIF instead of RAW access in BMI +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) +CONFIG_HIF_MESSAGE_BASED := 0 +else +CONFIG_HIF_MESSAGE_BASED := 1 +endif + +#Enable PCI specific APIS (dma, etc) +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_HIF_PCI := 1 +endif +#Enable USB specific APIS +ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_HIF_USB := 1 +endif + +#Enable pci read/write config functions +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_ATH_PCI := 1 +endif +ifeq ($(CONFIG_ROME_IF),usb) +#CONFIG_ATH_PCI := 1 +endif + +#Enable IBSS support on CLD +CONFIG_QCA_IBSS_SUPPORT := 1 + +#Enable power management suspend/resume functionality to PCI +CONFIG_ATH_BUS_PM := 1 + +#Enable dword alignment for IP header +CONFIG_IP_HDR_ALIGNMENT := 0 + +#Enable FLOWMAC module support +CONFIG_ATH_SUPPORT_FLOWMAC_MODULE := 0 + +#Enable spectral support +CONFIG_ATH_SUPPORT_SPECTRAL := 0 + +#Enable HOST statistics support +CONFIG_SUPPORT_HOST_STATISTICS := 0 + +#Enable WDI Event support +CONFIG_WDI_EVENT_ENABLE := 1 + +#Endianess selection +CONFIG_LITTLE_ENDIAN := 1 + +#Enable TX reclaim support +CONFIG_TX_CREDIT_RECLAIM_SUPPORT := 0 + +#Enable FTM support +CONFIG_QCA_WIFI_FTM := 1 + +#Enable Checksum Offload +CONFIG_CHECKSUM_OFFLOAD := 1 + +#Enable GTK offload +CONFIG_GTK_OFFLOAD := 1 + +#Enable EXT WOW +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_EXT_WOW := 1 +endif + +#Set this to 1 to catch erroneous Target accesses during debug. +CONFIG_ATH_PCIE_ACCESS_DEBUG := 0 + +#Enable IPA offload +ifeq ($(CONFIG_IPA), y) +CONFIG_IPA_OFFLOAD := 1 +CONFIG_IPA_UC_OFFLOAD := 1 +endif + +#Enable Signed firmware support for split binary format +CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT := 0 + +#Enable single firmware binary format +CONFIG_QCA_SINGLE_BINARY_SUPPORT := 0 + +#Enable collecting target RAM dump after kernel panic +CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC := 1 + +#Flag to enable/disable secure firmware feature +CONFIG_FEATURE_SECURE_FIRMWARE := 0 + +#Flag to enable Stats Ext implementation +CONFIG_FEATURE_STATS_EXT := 1 + + +ifeq ($(CONFIG_CFG80211),y) +HAVE_CFG80211 := 1 +else +ifeq ($(CONFIG_CFG80211),m) +HAVE_CFG80211 := 1 +else +HAVE_CFG80211 := 0 +endif +endif + +############ COMMON ############ +COMMON_DIR := CORE/SERVICES/COMMON +COMMON_INC := -I$(WLAN_ROOT)/$(COMMON_DIR) + +############ ADF ############## +ADF_DIR := $(COMMON_DIR)/adf +ADF_INC := -I$(WLAN_ROOT)/$(ADF_DIR) \ + -I$(WLAN_ROOT)/$(ADF_DIR)/linux \ + -I$(WLAN_ROOT)/$(COMMON_DIR)/asf + +ADF_OBJS := $(ADF_DIR)/adf_nbuf.o \ + $(ADF_DIR)/adf_os_lock.o \ + $(ADF_DIR)/adf_os_mem.o \ + $(ADF_DIR)/linux/adf_os_defer_pvt.o \ + $(ADF_DIR)/linux/adf_os_lock_pvt.o + +############ BAP ############ +BAP_DIR := CORE/BAP +BAP_INC_DIR := $(BAP_DIR)/inc +BAP_SRC_DIR := $(BAP_DIR)/src + +BAP_INC := -I$(WLAN_ROOT)/$(BAP_INC_DIR) \ + -I$(WLAN_ROOT)/$(BAP_SRC_DIR) + +BAP_OBJS := $(BAP_SRC_DIR)/bapApiData.o \ + $(BAP_SRC_DIR)/bapApiDebug.o \ + $(BAP_SRC_DIR)/bapApiExt.o \ + $(BAP_SRC_DIR)/bapApiHCBB.o \ + $(BAP_SRC_DIR)/bapApiInfo.o \ + $(BAP_SRC_DIR)/bapApiLinkCntl.o \ + $(BAP_SRC_DIR)/bapApiLinkSupervision.o \ + $(BAP_SRC_DIR)/bapApiStatus.o \ + $(BAP_SRC_DIR)/bapApiTimer.o \ + $(BAP_SRC_DIR)/bapModule.o \ + $(BAP_SRC_DIR)/bapRsn8021xAuthFsm.o \ + $(BAP_SRC_DIR)/bapRsn8021xPrf.o \ + $(BAP_SRC_DIR)/bapRsn8021xSuppRsnFsm.o \ + $(BAP_SRC_DIR)/bapRsnAsfPacket.o \ + $(BAP_SRC_DIR)/bapRsnSsmAesKeyWrap.o \ + $(BAP_SRC_DIR)/bapRsnSsmEapol.o \ + $(BAP_SRC_DIR)/bapRsnSsmReplayCtr.o \ + $(BAP_SRC_DIR)/bapRsnTxRx.o \ + $(BAP_SRC_DIR)/btampFsm.o \ + $(BAP_SRC_DIR)/btampHCI.o + +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) +############ HIF ############ +HIF_DIR := CORE/SERVICES/HIF +HIF_DIR_OBJS := $(HIF_DIR)/ath_procfs.o + +HIF_COMMON_DIR := CORE/SERVICES/HIF/common +HIF_COMMON_OBJS := $(HIF_COMMON_DIR)/hif_bmi_reg_access.o \ + $(HIF_COMMON_DIR)/hif_diag_reg_access.o + +HIF_SDIO_DIR := CORE/SERVICES/HIF/sdio +HIF_SDIO_OBJS := $(HIF_SDIO_DIR)/hif_sdio_send.o \ + $(HIF_SDIO_DIR)/hif_sdio_dev.o \ + $(HIF_SDIO_DIR)/hif_sdio.o \ + $(HIF_SDIO_DIR)/hif_sdio_recv.o \ + $(HIF_SDIO_DIR)/regtable.o \ + +HIF_SDIO_LINUX_DIR := $(HIF_SDIO_DIR)/linux +HIF_SDIO_LINUX_OBJS := $(HIF_SDIO_LINUX_DIR)/if_ath_sdio.o + + +HIF_SDIO_NATIVE_DIR := $(HIF_SDIO_LINUX_DIR)/native_sdio +HIF_SDIO_NATIVE_INC_DIR := $(HIF_SDIO_NATIVE_DIR)/include +HIF_SDIO_NATIVE_SRC_DIR := $(HIF_SDIO_NATIVE_DIR)/src + +HIF_SDIO_NATIVE_OBJS := $(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \ + $(HIF_SDIO_NATIVE_SRC_DIR)/hif_scatter.o + +HIF_INC := -I$(WLAN_ROOT)/$(HIF_COMMON_DIR) \ + -I$(WLAN_ROOT)/$(HIF_SDIO_DIR) \ + -I$(WLAN_ROOT)/$(HIF_SDIO_LINUX_DIR) \ + -I$(WLAN_ROOT)/$(HIF_SDIO_NATIVE_INC_DIR) \ + -I$(WLAN_ROOT)/$(HIF_SDIO_NATIVE_SRC_DIR) + +HIF_OBJS := $(HIF_DIR_OBJS) \ + $(HIF_COMMON_OBJS) \ + $(HIF_SDIO_OBJS) \ + $(HIF_SDIO_LINUX_OBJS) \ + $(HIF_SDIO_NATIVE_OBJS) +endif + +############ HDD ############ +HDD_DIR := CORE/HDD +HDD_INC_DIR := $(HDD_DIR)/inc +HDD_SRC_DIR := $(HDD_DIR)/src + +HDD_INC := -I$(WLAN_ROOT)/$(HDD_INC_DIR) \ + -I$(WLAN_ROOT)/$(HDD_SRC_DIR) + +HDD_OBJS := $(HDD_SRC_DIR)/bap_hdd_main.o \ + $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ + $(HDD_SRC_DIR)/wlan_hdd_cfg.o \ + $(HDD_SRC_DIR)/wlan_hdd_debugfs.o \ + $(HDD_SRC_DIR)/wlan_hdd_dev_pwr.o \ + $(HDD_SRC_DIR)/wlan_hdd_dp_utils.o \ + $(HDD_SRC_DIR)/wlan_hdd_early_suspend.o \ + $(HDD_SRC_DIR)/wlan_hdd_ftm.o \ + $(HDD_SRC_DIR)/wlan_hdd_hostapd.o \ + $(HDD_SRC_DIR)/wlan_hdd_main.o \ + $(HDD_SRC_DIR)/wlan_hdd_mib.o \ + $(HDD_SRC_DIR)/wlan_hdd_oemdata.o \ + $(HDD_SRC_DIR)/wlan_hdd_scan.o \ + $(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \ + $(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \ + $(HDD_SRC_DIR)/wlan_hdd_trace.o \ + $(HDD_SRC_DIR)/wlan_hdd_wext.o \ + $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ + $(HDD_SRC_DIR)/wlan_hdd_wowl.o + +ifeq ($(CONFIG_IPA_OFFLOAD), 1) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ipa.o +endif + +ifeq ($(HAVE_CFG80211),1) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \ + $(HDD_SRC_DIR)/wlan_hdd_p2p.o +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o +endif + +############ EPPING ############ +EPPING_DIR := CORE/EPPING +EPPING_INC_DIR := $(EPPING_DIR)/inc +EPPING_SRC_DIR := $(EPPING_DIR)/src + +EPPING_INC := -I$(WLAN_ROOT)/$(EPPING_INC_DIR) + +EPPING_OBJS := $(EPPING_SRC_DIR)/epping_main.o \ + $(EPPING_SRC_DIR)/epping_txrx.o \ + $(EPPING_SRC_DIR)/epping_tx.o \ + $(EPPING_SRC_DIR)/epping_rx.o \ + $(EPPING_SRC_DIR)/epping_helper.o \ + + +############ MAC ############ +MAC_DIR := CORE/MAC +MAC_INC_DIR := $(MAC_DIR)/inc +MAC_SRC_DIR := $(MAC_DIR)/src + +MAC_INC := -I$(WLAN_ROOT)/$(MAC_INC_DIR) \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/dph \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/include \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/include \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/lim + +MAC_CFG_OBJS := $(MAC_SRC_DIR)/cfg/cfgApi.o \ + $(MAC_SRC_DIR)/cfg/cfgDebug.o \ + $(MAC_SRC_DIR)/cfg/cfgParamName.o \ + $(MAC_SRC_DIR)/cfg/cfgProcMsg.o \ + $(MAC_SRC_DIR)/cfg/cfgSendMsg.o + +MAC_DPH_OBJS := $(MAC_SRC_DIR)/dph/dphHashTable.o + +MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/limAIDmgmt.o \ + $(MAC_SRC_DIR)/pe/lim/limAdmitControl.o \ + $(MAC_SRC_DIR)/pe/lim/limApi.o \ + $(MAC_SRC_DIR)/pe/lim/limAssocUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limDebug.o \ + $(MAC_SRC_DIR)/pe/lim/limFT.o \ + $(MAC_SRC_DIR)/pe/lim/limIbssPeerMgmt.o \ + $(MAC_SRC_DIR)/pe/lim/limLinkMonitoringAlgo.o \ + $(MAC_SRC_DIR)/pe/lim/limLogDump.o \ + $(MAC_SRC_DIR)/pe/lim/limP2P.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessActionFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAssocReqFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAssocRspFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAuthFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessBeaconFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessCfgUpdates.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessDeauthFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessDisassocFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMessageQueue.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMlmReqMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMlmRspMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessProbeReqFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessProbeRspFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessSmeReqMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limPropExtsUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limRoamingAlgo.o \ + $(MAC_SRC_DIR)/pe/lim/limScanResultUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSecurityUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSendManagementFrames.o \ + $(MAC_SRC_DIR)/pe/lim/limSendMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limSendSmeRspMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limSerDesUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSession.o \ + $(MAC_SRC_DIR)/pe/lim/limSessionUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSmeReqUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limStaHashApi.o \ + $(MAC_SRC_DIR)/pe/lim/limTimerUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limTrace.o \ + $(MAC_SRC_DIR)/pe/lim/limUtils.o + +ifeq ($(CONFIG_QCOM_ESE),y) +ifneq ($(CONFIG_QCOM_ESE_UPLOAD),y) +MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessEseFrame.o +endif +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o +endif + +MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \ + $(MAC_SRC_DIR)/pe/pmm/pmmApi.o \ + $(MAC_SRC_DIR)/pe/pmm/pmmDebug.o + +MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/schApi.o \ + $(MAC_SRC_DIR)/pe/sch/schBeaconGen.o \ + $(MAC_SRC_DIR)/pe/sch/schBeaconProcess.o \ + $(MAC_SRC_DIR)/pe/sch/schDebug.o \ + $(MAC_SRC_DIR)/pe/sch/schMessage.o + +MAC_RRM_OBJS := $(MAC_SRC_DIR)/pe/rrm/rrmApi.o + +MAC_OBJS := $(MAC_CFG_OBJS) \ + $(MAC_DPH_OBJS) \ + $(MAC_LIM_OBJS) \ + $(MAC_PMM_OBJS) \ + $(MAC_SCH_OBJS) \ + $(MAC_RRM_OBJS) + +############ SAP ############ +SAP_DIR := CORE/SAP +SAP_INC_DIR := $(SAP_DIR)/inc +SAP_SRC_DIR := $(SAP_DIR)/src + +SAP_INC := -I$(WLAN_ROOT)/$(SAP_INC_DIR) \ + -I$(WLAN_ROOT)/$(SAP_SRC_DIR) + +SAP_OBJS := $(SAP_SRC_DIR)/sapApiLinkCntl.o \ + $(SAP_SRC_DIR)/sapChSelect.o \ + $(SAP_SRC_DIR)/sapFsm.o \ + $(SAP_SRC_DIR)/sapModule.o + +############ DFS ############ 350 +DFS_DIR := CORE/SERVICES/DFS +DFS_INC_DIR := $(DFS_DIR)/inc +DFS_SRC_DIR := $(DFS_DIR)/src + +DFS_INC := -I$(WLAN_ROOT)/$(DFS_INC_DIR) \ + -I$(WLAN_ROOT)/$(DFS_SRC_DIR) + +DFS_OBJS := $(DFS_SRC_DIR)/dfs_bindetects.o \ + $(DFS_SRC_DIR)/dfs.o \ + $(DFS_SRC_DIR)/dfs_debug.o\ + $(DFS_SRC_DIR)/dfs_fcc_bin5.o\ + $(DFS_SRC_DIR)/dfs_init.o\ + $(DFS_SRC_DIR)/dfs_misc.o\ + $(DFS_SRC_DIR)/dfs_nol.o\ + $(DFS_SRC_DIR)/dfs_phyerr_tlv.o\ + $(DFS_SRC_DIR)/dfs_process_phyerr.o\ + $(DFS_SRC_DIR)/dfs_process_radarevent.o\ + $(DFS_SRC_DIR)/dfs_staggered.o + +############ SME ############ +SME_DIR := CORE/SME +SME_INC_DIR := $(SME_DIR)/inc +SME_SRC_DIR := $(SME_DIR)/src + +SME_INC := -I$(WLAN_ROOT)/$(SME_INC_DIR) \ + -I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr + +SME_CCM_OBJS := $(SME_SRC_DIR)/ccm/ccmApi.o \ + $(SME_SRC_DIR)/ccm/ccmLogDump.o + +SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csrApiRoam.o \ + $(SME_SRC_DIR)/csr/csrApiScan.o \ + $(SME_SRC_DIR)/csr/csrCmdProcess.o \ + $(SME_SRC_DIR)/csr/csrLinkList.o \ + $(SME_SRC_DIR)/csr/csrLogDump.o \ + $(SME_SRC_DIR)/csr/csrNeighborRoam.o \ + $(SME_SRC_DIR)/csr/csrUtil.o + +ifeq ($(CONFIG_QCOM_ESE),y) +ifneq ($(CONFIG_QCOM_ESE_UPLOAD),y) +SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrEse.o +endif +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o +endif + +SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \ + $(SME_SRC_DIR)/pmc/pmc.o \ + $(SME_SRC_DIR)/pmc/pmcLogDump.o + +SME_QOS_OBJS := $(SME_SRC_DIR)/QoS/sme_Qos.o + +SME_CMN_OBJS := $(SME_SRC_DIR)/sme_common/sme_Api.o \ + $(SME_SRC_DIR)/sme_common/sme_FTApi.o \ + $(SME_SRC_DIR)/sme_common/sme_Trace.o + +SME_BTC_OBJS := $(SME_SRC_DIR)/btc/btcApi.o + +SME_OEM_DATA_OBJS := $(SME_SRC_DIR)/oemData/oemDataApi.o + +SME_P2P_OBJS = $(SME_SRC_DIR)/p2p/p2p_Api.o + +SME_RRM_OBJS := $(SME_SRC_DIR)/rrm/sme_rrm.o + +ifeq ($(CONFIG_FEATURE_NAN),y) +SME_NAN_OBJS = $(SME_SRC_DIR)/nan/nan_Api.o +endif + +SME_OBJS := $(SME_BTC_OBJS) \ + $(SME_CCM_OBJS) \ + $(SME_CMN_OBJS) \ + $(SME_CSR_OBJS) \ + $(SME_OEM_DATA_OBJS) \ + $(SME_P2P_OBJS) \ + $(SME_PMC_OBJS) \ + $(SME_QOS_OBJS) \ + $(SME_RRM_OBJS) \ + $(SME_NAN_OBJS) + +############ SVC ############ +SVC_DIR := CORE/SVC +SVC_INC_DIR := $(SVC_DIR)/inc +SVC_SRC_DIR := $(SVC_DIR)/src + +SVC_INC := -I$(WLAN_ROOT)/$(SVC_INC_DIR) \ + -I$(WLAN_ROOT)/$(SVC_DIR)/external + +BTC_SRC_DIR := $(SVC_SRC_DIR)/btc +BTC_OBJS := $(BTC_SRC_DIR)/wlan_btc_svc.o + +NLINK_SRC_DIR := $(SVC_SRC_DIR)/nlink +NLINK_OBJS := $(NLINK_SRC_DIR)/wlan_nlink_srv.o + +PTT_SRC_DIR := $(SVC_SRC_DIR)/ptt +PTT_OBJS := $(PTT_SRC_DIR)/wlan_ptt_sock_svc.o + +WLAN_LOGGING_SRC_DIR := $(SVC_SRC_DIR)/logging +WLAN_LOGGING_OBJS := $(WLAN_LOGGING_SRC_DIR)/wlan_logging_sock_svc.o + +SVC_OBJS := $(BTC_OBJS) \ + $(NLINK_OBJS) \ + $(PTT_OBJS) \ + $(WLAN_LOGGING_OBJS) + +############ SYS ############ +SYS_DIR := CORE/SYS + +SYS_INC := -I$(WLAN_ROOT)/$(SYS_DIR)/common/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/pal/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/platform/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/system/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/utils/inc + +SYS_COMMON_SRC_DIR := $(SYS_DIR)/common/src +SYS_LEGACY_SRC_DIR := $(SYS_DIR)/legacy/src +SYS_OBJS := $(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \ + $(SYS_LEGACY_SRC_DIR)/pal/src/palApiComm.o \ + $(SYS_LEGACY_SRC_DIR)/platform/src/VossWrapper.o \ + $(SYS_LEGACY_SRC_DIR)/system/src/macInitApi.o \ + $(SYS_LEGACY_SRC_DIR)/system/src/sysEntryFunc.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/dot11f.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/logApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/logDump.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/macTrace.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/parserApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/utilsApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/utilsParser.o + +############ TL ############ +TL_DIR := CORE/TL +TL_INC_DIR := $(TL_DIR)/inc + +TL_INC := -I$(WLAN_ROOT)/$(TL_INC_DIR) + +############ VOSS ############ +VOSS_DIR := CORE/VOSS +VOSS_INC_DIR := $(VOSS_DIR)/inc +VOSS_SRC_DIR := $(VOSS_DIR)/src + +VOSS_INC := -I$(WLAN_ROOT)/$(VOSS_INC_DIR) \ + -I$(WLAN_ROOT)/$(VOSS_SRC_DIR) + +VOSS_OBJS := $(VOSS_SRC_DIR)/vos_api.o \ + $(VOSS_SRC_DIR)/vos_event.o \ + $(VOSS_SRC_DIR)/vos_getBin.o \ + $(VOSS_SRC_DIR)/vos_list.o \ + $(VOSS_SRC_DIR)/vos_lock.o \ + $(VOSS_SRC_DIR)/vos_memory.o \ + $(VOSS_SRC_DIR)/vos_mq.o \ + $(VOSS_SRC_DIR)/vos_nvitem.o \ + $(VOSS_SRC_DIR)/vos_packet.o \ + $(VOSS_SRC_DIR)/vos_sched.o \ + $(VOSS_SRC_DIR)/vos_threads.o \ + $(VOSS_SRC_DIR)/vos_timer.o \ + $(VOSS_SRC_DIR)/vos_trace.o \ + $(VOSS_SRC_DIR)/vos_types.o \ + $(VOSS_SRC_DIR)/vos_utils.o + +ifeq ($(BUILD_DIAG_VERSION),1) +VOSS_OBJS += $(VOSS_SRC_DIR)/vos_diag.o +endif + +########### BMI ########### +BMI_DIR := CORE/SERVICES/BMI + +BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR) + +BMI_OBJS := $(BMI_DIR)/bmi.o \ + $(BMI_DIR)/ol_fw.o + +########### WMI ########### +WMI_DIR := CORE/SERVICES/WMI + +WMI_INC := -I$(WLAN_ROOT)/$(WMI_DIR) + +WMI_OBJS := $(WMI_DIR)/wmi_unified.o \ + $(WMI_DIR)/wmi_tlv_helper.o + +########### FWLOG ########### +FWLOG_DIR := CORE/UTILS/FWLOG + +FWLOG_INC := -I$(WLAN_ROOT)/$(FWLOG_DIR) + +FWLOG_OBJS := $(FWLOG_DIR)/dbglog_host.o + +############ TLSHIM ############ +TLSHIM_DIR := CORE/CLD_TXRX/TLSHIM +TLSHIM_INC := -I$(WLAN_ROOT)/$(TLSHIM_DIR) + +TLSHIM_OBJS := $(TLSHIM_DIR)/tl_shim.o + +############ TXRX ############ +TXRX_DIR := CORE/CLD_TXRX/TXRX +TXRX_INC := -I$(WLAN_ROOT)/$(TXRX_DIR) + +TXRX_OBJS := $(TXRX_DIR)/ol_txrx.o \ + $(TXRX_DIR)/ol_cfg.o \ + $(TXRX_DIR)/ol_rx.o \ + $(TXRX_DIR)/ol_rx_fwd.o \ + $(TXRX_DIR)/ol_txrx.o \ + $(TXRX_DIR)/ol_rx_defrag.o \ + $(TXRX_DIR)/ol_tx_desc.o \ + $(TXRX_DIR)/ol_tx_classify.o \ + $(TXRX_DIR)/ol_tx.o \ + $(TXRX_DIR)/ol_rx_reorder_timeout.o \ + $(TXRX_DIR)/ol_rx_reorder.o \ + $(TXRX_DIR)/ol_rx_pn.o \ + $(TXRX_DIR)/ol_tx_queue.o \ + $(TXRX_DIR)/ol_txrx_peer_find.o \ + $(TXRX_DIR)/ol_txrx_event.o \ + $(TXRX_DIR)/ol_txrx_encap.o \ + $(TXRX_DIR)/ol_tx_send.o \ + $(TXRX_DIR)/ol_tx_sched.o + +############ PKTLOG ############ +PKTLOG_DIR := CORE/UTILS/PKTLOG +PKTLOG_INC := -I$(WLAN_ROOT)/$(PKTLOG_DIR)/include + +PKTLOG_OBJS := $(PKTLOG_DIR)/pktlog_ac.o \ + $(PKTLOG_DIR)/pktlog_internal.o \ + $(PKTLOG_DIR)/linux_ac.o + +############ HTT ############ +HTT_DIR := CORE/CLD_TXRX/HTT +HTT_INC := -I$(WLAN_ROOT)/$(HTT_DIR) + +HTT_OBJS := $(HTT_DIR)/htt_tx.o \ + $(HTT_DIR)/htt.o \ + $(HTT_DIR)/htt_t2h.o \ + $(HTT_DIR)/htt_h2t.o \ + $(HTT_DIR)/htt_fw_stats.o \ + $(HTT_DIR)/htt_rx.o + +############## HTC ########## +HTC_DIR := CORE/SERVICES/HTC +HTC_INC := -I$(WLAN_ROOT)/$(HTC_DIR) + +HTC_OBJS := $(HTC_DIR)/htc.o \ + $(HTC_DIR)/htc_send.o \ + $(HTC_DIR)/htc_recv.o \ + $(HTC_DIR)/htc_services.o + +ifneq ($(CONFIG_QCA_WIFI_SDIO), 1) +########### HIF ########### +HIF_DIR := CORE/SERVICES/HIF +ifeq ($(CONFIG_HIF_PCI), 1) +HIF_PCIE_DIR := $(HIF_DIR)/PCIe + +HIF_INC := -I$(WLAN_ROOT)/$(HIF_PCIE_DIR) + +HIF_OBJS := $(HIF_DIR)/ath_procfs.o + +HIF_PCIE_OBJS := $(HIF_PCIE_DIR)/copy_engine.o \ + $(HIF_PCIE_DIR)/hif_pci.o \ + $(HIF_PCIE_DIR)/if_pci.o \ + $(HIF_PCIE_DIR)/regtable.o \ + $(HIF_PCIE_DIR)/mp_dev.o + +HIF_OBJS += $(HIF_PCIE_OBJS) +endif +ifeq ($(CONFIG_HIF_USB), 1) +HIF_USB_DIR := $(HIF_DIR)/USB + +HIF_INC := -I$(WLAN_ROOT)/$(HIF_USB_DIR) + +HIF_OBJS := $(HIF_DIR)/ath_procfs.o + +HIF_USB_OBJS := $(HIF_USB_DIR)/usbdrv.o \ + $(HIF_USB_DIR)/hif_usb.o \ + $(HIF_USB_DIR)/if_usb.o \ + $(HIF_USB_DIR)/regtable.o + +HIF_OBJS += $(HIF_USB_OBJS) +endif +endif + +############ WMA ############ +WMA_DIR := CORE/SERVICES/WMA + +WMA_INC := -I$(WLAN_ROOT)/$(WMA_DIR) + +WMA_OBJS := $(WMA_DIR)/regdomain.o \ + $(WMA_DIR)/wlan_nv.o \ + $(WMA_DIR)/wma.o \ + $(WMA_DIR)/wma_dfs_interface.o + + +############ WDA ############ +WDA_DIR := CORE/WDA +WDA_INC_DIR := $(WDA_DIR)/inc +WDA_SRC_DIR := $(WDA_DIR)/src + +WDA_INC := -I$(WLAN_ROOT)/$(WDA_INC_DIR) \ + -I$(WLAN_ROOT)/$(WDA_INC_DIR)/legacy \ + -I$(WLAN_ROOT)/$(WDA_SRC_DIR) + +WDA_OBJS := $(WDA_SRC_DIR)/wlan_qct_wda_debug.o \ + $(WDA_SRC_DIR)/wlan_qct_wda_legacy.o + +############ WDI ############ +WDI_DIR := CORE/WDI + +WDI_CP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/CP/inc/ + +WDI_DP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/DP/inc/ + +WDI_TRP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/CTS/inc/ \ + -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/DTS/inc/ + +WDI_WPAL_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/WPAL/inc + +WDI_INC := $(WDI_CP_INC) \ + $(WDI_DP_INC) \ + $(WDI_TRP_INC) \ + $(WDI_WPAL_INC) + +WCNSS_INC := -I$(WLAN_ROOT)/wcnss/inc + +LINUX_INC := -Iinclude/linux + +INCS := $(BAP_INC) \ + $(HDD_INC) \ + $(EPPING_INC) \ + $(LINUX_INC) \ + $(MAC_INC) \ + $(WCNSS_INC) \ + $(SAP_INC) \ + $(SME_INC) \ + $(SVC_INC) \ + $(SYS_INC) \ + $(TL_INC) \ + $(VOSS_INC) \ + $(WDA_INC) \ + $(WDI_INC) \ + $(DFS_INC) + +INCS += $(WMA_INC) \ + $(COMMON_INC) \ + $(WMI_INC) \ + $(FWLOG_INC) \ + $(ADF_INC) \ + $(TLSHIM_INC) \ + $(TXRX_INC) \ + $(PKTLOG_INC) \ + $(HTT_INC) \ + $(HTC_INC) \ + $(DFS_INC) + +INCS += $(HIF_INC) \ + $(BMI_INC) + +ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) +INCS += $(PKTLOG_INC) +endif + +OBJS := $(BAP_OBJS) \ + $(HDD_OBJS) \ + $(EPPING_OBJS) \ + $(MAC_OBJS) \ + $(SAP_OBJS) \ + $(SME_OBJS) \ + $(SVC_OBJS) \ + $(SYS_OBJS) \ + $(VOSS_OBJS) \ + $(WDA_OBJS) \ + $(DFS_OBJS) + +OBJS += $(WMA_OBJS) \ + $(TLSHIM_OBJS) \ + $(TXRX_OBJS) \ + $(WMI_OBJS) \ + $(FWLOG_OBJS) \ + $(HTC_OBJS) \ + $(ADF_OBJS) \ + $(DFS_OBJS) + +OBJS += $(HIF_OBJS) \ + $(BMI_OBJS) \ + $(HTT_OBJS) + +ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) +OBJS += $(PKTLOG_OBJS) +endif + +EXTRA_CFLAGS += $(INCS) + +CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DQC_WLAN_CHIPSET_QCA_CLD \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DANI_LOGDUMP \ + -DWLAN_PERF \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ \ + -DHAL_SELF_STA_PER_BSS=1 \ + -DWLAN_FEATURE_VOWIFI_11R \ + -DWLAN_FEATURE_NEIGHBOR_ROAMING \ + -DWLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG \ + -DWLAN_FEATURE_VOWIFI_11R_DEBUG \ + -DFEATURE_WLAN_WAPI \ + -DFEATURE_OEM_DATA_SUPPORT\ + -DSOFTAP_CHANNEL_RANGE \ + -DWLAN_AP_STA_CONCURRENCY \ + -DFEATURE_WLAN_SCAN_PNO \ + -DWLAN_FEATURE_PACKET_FILTERING \ + -DWLAN_FEATURE_VOWIFI \ + -DWLAN_FEATURE_11AC \ + -DWLAN_FEATURE_P2P_DEBUG \ + -DWLAN_ENABLE_AGEIE_ON_SCAN_RESULTS \ + -DWLANTL_DEBUG\ + -DWLAN_NS_OFFLOAD \ + -DWLAN_ACTIVEMODE_OFFLOAD_FEATURE \ + -DWLAN_FEATURE_HOLD_RX_WAKELOCK \ + -DWLAN_SOFTAP_VSTA_FEATURE \ + -DWLAN_FEATURE_ROAM_SCAN_OFFLOAD \ + -DWLAN_FEATURE_GTK_OFFLOAD \ + -DWLAN_WAKEUP_EVENTS \ + -DFEATURE_WLAN_RA_FILTERING\ + -DWLAN_KD_READY_NOTIFIER \ + -DWLAN_NL80211_TESTMODE \ + -DFEATURE_WLAN_BATCH_SCAN \ + -DFEATURE_WLAN_LPHB \ + -DFEATURE_WLAN_PAL_TIMER_DISABLE \ + -DFEATURE_WLAN_PAL_MEM_DISABLE \ + -DQCA_SUPPORT_TX_THROTTLE \ + -DWMI_INTERFACE_EVENT_LOGGING \ + -DATH_SUPPORT_WAPI \ + -DWLAN_FEATURE_LINK_LAYER_STATS \ + -DWLAN_LOGGING_SOCK_SVC_ENABLE \ + -DFEATURE_WLAN_EXTSCAN \ + -DQCA_LL_TX_FLOW_CT \ + -DFEATURE_WLAN_LFR \ + -DFEATURE_WLAN_CH144 + +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) +CDEFINES += -DCONFIG_HL_SUPPORT \ + -DCONFIG_AR6320_SUPPORT \ + -DSDIO_3_0 \ + -DHIF_SDIO \ + -DCONFIG_ATH_PROCFS_DIAG_SUPPORT +endif + +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) +CDEFINES += -DFEATURE_WLAN_FORCE_SAP_SCC +endif + +ifeq ($(CONFIG_ARCH_MSM), y) +CDEFINES += -DMSM_PLATFORM +endif + +CDEFINES += -DOSIF_NEED_RX_PEER_ID \ + -DQCA_SUPPORT_TXRX_LOCAL_PEER_ID +ifeq ($(CONFIG_ROME_IF),pci) +CDEFINES += -DQCA_LL_TX_FLOW_CT \ + -DQCA_SUPPORT_TXRX_VDEV_PAUSE_LL \ + -DQCA_SUPPORT_TXRX_VDEV_LL_TXQ +endif + +ifeq ($(CONFIG_DEBUG_LL),y) +CDEFINES += -DQCA_PKT_PROTO_TRACE +endif + +ifneq ($(CONFIG_QCA_CLD_WLAN),) +CDEFINES += -DWCN_PRONTO +CDEFINES += -DWCN_PRONTO_V1 +endif + +ifeq ($(BUILD_DEBUG_VERSION),1) +CDEFINES += -DWLAN_DEBUG \ + -DTRACE_RECORD \ + -DLIM_TRACE_RECORD \ + -DSME_TRACE_RECORD \ + -DHDD_TRACE_RECORD \ + -DPE_DEBUG_LOGW \ + -DPE_DEBUG_LOGE \ + -DDEBUG +endif + +ifeq ($(CONFIG_SLUB_DEBUG_ON),y) +CDEFINES += -DTIMER_MANAGER +CDEFINES += -DMEMORY_DEBUG +endif + +ifeq ($(HAVE_CFG80211),1) +CDEFINES += -DWLAN_FEATURE_P2P +CDEFINES += -DWLAN_FEATURE_WFD +ifeq ($(CONFIG_QCOM_VOWIFI_11R),y) +CDEFINES += -DKERNEL_SUPPORT_11R_CFG80211 +CDEFINES += -DUSE_80211_WMMTSPEC_FOR_RIC +endif +endif + +ifeq ($(CONFIG_QCOM_ESE),y) +CDEFINES += -DFEATURE_WLAN_ESE +CDEFINES += -DQCA_COMPUTE_TX_DELAY +CDEFINES += -DQCA_COMPUTE_TX_DELAY_PER_TID +ifeq ($(CONFIG_QCOM_ESE_UPLOAD),y) +CDEFINES += -DFEATURE_WLAN_ESE_UPLOAD +endif +endif + +#normally, TDLS negative behavior is not needed +ifeq ($(CONFIG_QCOM_TDLS),y) +CDEFINES += -DFEATURE_WLAN_TDLS +ifeq ($(BUILD_DEBUG_VERSION),1) +CDEFINES += -DWLAN_FEATURE_TDLS_DEBUG +endif +CDEFINES += -DCONFIG_TDLS_IMPLICIT +#CDEFINES += -DFEATURE_WLAN_TDLS_NEGATIVE +#Code under FEATURE_WLAN_TDLS_INTERNAL is ported from volans, This code +#is not tested only verifed that it compiles. This is not required for +#supplicant based implementation +#CDEFINES += -DFEATURE_WLAN_TDLS_INTERNAL +endif + +ifeq ($(CONFIG_PRIMA_WLAN_BTAMP),y) +CDEFINES += -DWLAN_BTAMP_FEATURE +endif + +ifeq ($(CONFIG_QCACLD_WLAN_LFR3),y) +CDEFINES += -DWLAN_FEATURE_ROAM_OFFLOAD +endif + +ifeq ($(CONFIG_PRIMA_WLAN_OKC),y) +CDEFINES += -DFEATURE_WLAN_OKC +endif + +ifeq ($(CONFIG_PRIMA_WLAN_11AC_HIGH_TP),y) +CDEFINES += -DWLAN_FEATURE_11AC_HIGH_TP +endif + +ifeq ($(BUILD_DIAG_VERSION),1) +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_LIM +ifeq ($(CONFIG_HIF_PCI), 1) +CDEFINES += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT +endif +endif + +ifeq ($(CONFIG_HIF_USB), 1) +CDEFINES += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT +CDEFINES += -DQCA_SUPPORT_OL_RX_REORDER_TIMEOUT +CDEFINES += -DCONFIG_ATH_PCIE_MAX_PERF=0 -DCONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD=0 -DCONFIG_DISABLE_CDC_MAX_PERF_WAR=0 +CDEFINES += -DQCA_TX_HTT2_SUPPORT +endif + +# enable the MAC Address auto-generation feature +CDEFINES += -DWLAN_AUTOGEN_MACADDR_FEATURE + +ifeq ($(CONFIG_WLAN_FEATURE_11W),y) +CDEFINES += -DWLAN_FEATURE_11W +endif + +ifeq ($(CONFIG_QCOM_LTE_COEX),y) +CDEFINES += -DFEATURE_WLAN_CH_AVOID +endif + +ifeq ($(CONFIG_WLAN_FEATURE_LPSS),y) +CDEFINES += -DWLAN_FEATURE_LPSS +endif + +ifeq ($(PANIC_ON_BUG),1) +CDEFINES += -DPANIC_ON_BUG +endif + +ifeq ($(RE_ENABLE_WIFI_ON_WDI_TIMEOUT),1) +CDEFINES += -DWDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT +endif + +ifeq ($(WLAN_OPEN_SOURCE), 1) +CDEFINES += -DWLAN_OPEN_SOURCE +endif + +ifeq ($(CONFIG_FEATURE_STATS_EXT), 1) +CDEFINES += -DWLAN_FEATURE_STATS_EXT +endif + +ifeq ($(CONFIG_FEATURE_NAN),y) +CDEFINES += -DWLAN_FEATURE_NAN +endif + +ifeq ($(CONFIG_QCA_IBSS_SUPPORT), 1) +CDEFINES += -DQCA_IBSS_SUPPORT +endif + +#Enable the OS specific ADF abstraction +ifeq ($(CONFIG_ADF_SUPPORT), 1) +CDEFINES += -DADF_SUPPORT +endif + +#Enable OL debug and wmi unified functions +ifeq ($(CONFIG_ATH_PERF_PWR_OFFLOAD), 1) +CDEFINES += -DATH_PERF_PWR_OFFLOAD +endif + +#Disable packet log +ifeq ($(CONFIG_REMOVE_PKT_LOG), 1) +CDEFINES += -DREMOVE_PKT_LOG +endif + +#Enable 11AC TX +ifeq ($(CONFIG_ATH_11AC_TXCOMPACT), 1) +CDEFINES += -DATH_11AC_TXCOMPACT +endif + +#Enable per vdev Tx desc pool +ifeq ($(CONFIG_PER_VDEV_TX_DESC_POOL), 1) +CDEFINES += -DCONFIG_PER_VDEV_TX_DESC_POOL +endif + +#Enable OS specific IRQ abstraction +ifeq ($(CONFIG_ATH_SUPPORT_SHARED_IRQ), 1) +CDEFINES += -DATH_SUPPORT_SHARED_IRQ +endif + +#Enable message based HIF instead of RAW access in BMI +ifeq ($(CONFIG_HIF_MESSAGE_BASED), 1) +CDEFINES += -DHIF_MESSAGE_BASED +endif + +#Enable PCI specific APIS (dma, etc) +ifeq ($(CONFIG_HIF_PCI), 1) +CDEFINES += -DHIF_PCI +endif + +#Enable USB specific APIS +ifeq ($(CONFIG_HIF_USB), 1) +CDEFINES += -DHIF_USB +CDEFINES += -DCONFIG_HL_SUPPORT +endif + +#Enable FW logs through ini +CDEFINES += -DCONFIG_FW_LOGS_BASED_ON_INI + +#Enable pci read/write config functions +ifeq ($(CONFIG_ATH_PCI), 1) +CDEFINES += -DATH_PCI +endif + +#Enable power management suspend/resume functionality +ifeq ($(CONFIG_ATH_BUS_PM), 1) +CDEFINES += -DATH_BUS_PM +endif + +#Enable dword alignment for IP header +ifeq ($(CONFIG_IP_HDR_ALIGNMENT), 1) +CDEFINES += -DPERE_IP_HDR_ALIGNMENT_WAR +endif + +#Enable FLOWMAC module support +ifeq ($(CONFIG_ATH_SUPPORT_FLOWMAC_MODULE), 1) +CDEFINES += -DATH_SUPPORT_FLOWMAC_MODULE +endif + +#Enable spectral support +ifeq ($(CONFIG_ATH_SUPPORT_SPECTRAL), 1) +CDEFINES += -DATH_SUPPORT_SPECTRAL +endif + +#Enable WDI Event support +ifeq ($(CONFIG_WDI_EVENT_ENABLE), 1) +CDEFINES += -DWDI_EVENT_ENABLE +endif + +#Endianess selection +ifeq ($(CONFIG_LITTLE_ENDIAN), 1) +AH_LITTLE_ENDIAN=1234 +CDEFINES += -DAH_BYTE_ORDER=$(AH_LITTLE_ENDIAN) +else +AH_BIG_ENDIAN=4321 +CDEFINES += -DAH_BYTE_ORDER=$(AH_BIG_ENDIAN) +CDEFINES += -DBIG_ENDIAN_HOST +endif + +#Enable TX reclaim support +ifeq ($(CONFIG_TX_CREDIT_RECLAIM_SUPPORT), 1) +CDEFINES += -DTX_CREDIT_RECLAIM_SUPPORT +endif + +#Enable FTM support +ifeq ($(CONFIG_QCA_WIFI_FTM), 1) +CDEFINES += -DQCA_WIFI_FTM +endif + +#Enable Checksum Offload support +ifeq ($(CONFIG_CHECKSUM_OFFLOAD), 1) +CDEFINES += -DCHECKSUM_OFFLOAD +endif + +#Enable Checksum Offload support +ifeq ($(CONFIG_IPA_OFFLOAD), 1) +CDEFINES += -DIPA_OFFLOAD -DHDD_IPA_USE_IPA_RM_TIMER +endif + +ifneq ($(CONFIG_ARCH_MDM9630), y) +ifeq ($(CONFIG_IPA_UC_OFFLOAD), 1) +CDEFINES += -DIPA_UC_OFFLOAD +endif +endif + +#Enable GTK Offload +ifeq ($(CONFIG_GTK_OFFLOAD), 1) +CDEFINES += -DWLAN_FEATURE_GTK_OFFLOAD +CDEFINES += -DIGTK_OFFLOAD +endif + +#Enable GTK Offload +ifeq ($(CONFIG_EXT_WOW), 1) +CDEFINES += -DWLAN_FEATURE_EXTWOW_SUPPORT +endif + +#Mark it as SMP Kernel +ifeq ($(CONFIG_SMP),y) +CDEFINES += -DQCA_CONFIG_SMP +endif + +#Enable Channel Matrix restriction for all targets +CDEFINES += -DWLAN_ENABLE_CHNL_MATRIX_RESTRICTION + +#features specific to mdm9630 +ifeq ($(CONFIG_ARCH_MDM9630), y) + +#enable MCC TO SCC switch +CDEFINES += -DFEATURE_WLAN_MCC_TO_SCC_SWITCH + +#enable wlan auto shutdown feature for mdm9630 +CDEFINES += -DFEATURE_WLAN_AUTO_SHUTDOWN + +#enable for MBSSID +CDEFINES += -DWLAN_FEATURE_MBSSID + +#Green AP feature +CDEFINES += -DFEATURE_GREEN_AP + +#Enable 4address scheme for mdm9630 +CDEFINES += -DFEATURE_WLAN_STA_4ADDR_SCHEME + +#Disable STA-AP Mode DFS support +CDEFINES += -DFEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + +#Enable OBSS feature for mdm9630 +CDEFINES += -DQCA_HT_2040_COEX + +else + +#Open P2P device interface only for non-MDM9630 platform +CDEFINES += -DWLAN_OPEN_P2P_INTERFACE + +#Enable 2.4 GHz social channels in 5 GHz only mode for p2p usage +CDEFINES += -DWLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY + +#Enable RX Full re-order OL feature only "LL and NON-MDM platform" +ifeq ($(CONFIG_HIF_PCI), 1) +CDEFINES += -DWLAN_FEATURE_RX_FULL_REORDER_OL +endif +endif + +#Enable Signed firmware support for split binary format +ifeq ($(CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT), 1) +CDEFINES += -DQCA_SIGNED_SPLIT_BINARY_SUPPORT +endif + +#Enable single firmware binary format +ifeq ($(CONFIG_QCA_SINGLE_BINARY_SUPPORT), 1) +CDEFINES += -DQCA_SINGLE_BINARY_SUPPORT +endif + +#Enable collecting target RAM dump after kernel panic +ifeq ($(CONFIG_TARGET_RAMDUMP_AFTER_KERNEL_PANIC), 1) +CDEFINES += -DTARGET_RAMDUMP_AFTER_KERNEL_PANIC +endif + +#Enable/disable secure firmware feature +ifeq ($(CONFIG_FEATURE_SECURE_FIRMWARE), 1) +CDEFINES += -DFEATURE_SECURE_FIRMWARE +endif + +#Enable/disable FW hash check for secure firmware feature +ifeq ($(CONFIG_CLD_DEBUG), y) +CDEFINES += -DFEATURE_FW_HASH_CHECK +endif + +ifeq ($(CONFIG_ATH_PCIE_ACCESS_DEBUG), 1) +CDEFINES += -DCONFIG_ATH_PCIE_ACCESS_DEBUG +endif + +#Flag to enable/disable WLAN D0-WOW +ifeq ($(CONFIG_PCI_MSM), y) +CDEFINES += -DFEATURE_WLAN_D0WOW +endif + +# Some kernel include files are being moved. Check to see if +# the old version of the files are present + +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/mach-msm/include/mach/msm_smd.h),) +CDEFINES += -DEXISTS_MSM_SMD +endif + +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/mach-msm/include/mach/msm_smsm.h),) +CDEFINES += -DEXISTS_MSM_SMSM +endif + +# Enable feature support fo Linux version QCMBR +ifeq ($(CONFIG_LINUX_QCMBR),y) +CDEFINES += -DLINUX_QCMBR +endif + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# WLAN driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif + +# Module information used by KBuild framework +obj-$(CONFIG_QCA_CLD_WLAN) += $(MODNAME).o +$(MODNAME)-y := $(OBJS) diff --git a/drivers/staging/qcacld-2.0/Kconfig b/drivers/staging/qcacld-2.0/Kconfig new file mode 100644 index 0000000000000..523e444e8cd61 --- /dev/null +++ b/drivers/staging/qcacld-2.0/Kconfig @@ -0,0 +1,48 @@ +comment "Qualcomm Atheros CLD WLAN module" + +config QCA_CLD_WLAN + + tristate "Qualcomm Atheros CLD WLAN module" + default n + help + Add support for the Qualcomm Atheros CLD WLAN module + +if QCA_CLD_WLAN != n + +config QCACLD_WLAN_LFR3 + bool "Enable the WLAN Legacy Fast Roaming feature Version 3" + default n + +config PRIMA_WLAN_OKC + bool "Enable the Prima WLAN Opportunistic Key Caching feature" + default n + +config PRIMA_WLAN_11AC_HIGH_TP + bool "Enable the Prima WLAN 802.11ac High Throughput option (depends upon kernel support)" + default n + +config WLAN_FEATURE_11W + bool "Enable the WLAN 802.11w Protected Management Frames feature" + default n + +config WLAN_FEATURE_LPSS + bool "Enable the WLAN LPSS feature" + default n + +config QCOM_VOWIFI_11R + bool "Enable Fast Transition (11r) feature" + default n + +config FEATURE_NAN + bool "Enable NAN feature" + default n + +config QCOM_TDLS + bool "Enable TDLS feature" + default n + +config QCOM_LTE_COEX + bool "Enable QCOM LTE Coex feature" + default n + +endif # QCA_CLD_WLAN diff --git a/drivers/staging/qcacld-2.0/Makefile b/drivers/staging/qcacld-2.0/Makefile new file mode 100644 index 0000000000000..c05b00f26c57e --- /dev/null +++ b/drivers/staging/qcacld-2.0/Makefile @@ -0,0 +1,28 @@ +KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + +KBUILD_OPTIONS := WLAN_ROOT=$(PWD) +KBUILD_OPTIONS += MODNAME=wlan + +# Determine if the driver license is Open source or proprietary +# This is determined under the assumption that LICENSE doesn't change. +# Please change here if driver license text changes. +LICENSE_FILE ?= $(PWD)/$(WLAN_ROOT)/CORE/HDD/src/wlan_hdd_main.c +WLAN_OPEN_SOURCE = $(shell if grep -q "MODULE_LICENSE(\"Dual BSD/GPL\")" \ + $(LICENSE_FILE); then echo 1; else echo 0; fi) + +#By default build for CLD +WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m +KBUILD_OPTIONS += CONFIG_QCA_WIFI_ISOC=0 +KBUILD_OPTIONS += CONFIG_QCA_WIFI_2_0=1 +KBUILD_OPTIONS += $(WLAN_SELECT) +KBUILD_OPTIONS += WLAN_OPEN_SOURCE=$(WLAN_OPEN_SOURCE) +KBUILD_OPTIONS += $(KBUILD_EXTRA) # Extra config if any + +all: + $(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS) + +modules_install: + $(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install + +clean: + $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean diff --git a/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_cfg.dat b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_cfg.dat new file mode 100755 index 0000000000000..a54459f648691 Binary files /dev/null and b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_cfg.dat differ diff --git a/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.ini b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.ini new file mode 100755 index 0000000000000..2316ca72ae21d --- /dev/null +++ b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.ini @@ -0,0 +1,652 @@ +# This file allows user to override the factory + +# defaults for the WLAN Driver + + +# Enable IMPS or not +gEnableImps=1 + +# Enable/Disable Idle Scan + +gEnableIdleScan=0 + + +# Increase sleep duration (seconds) during IMPS +# 0 implies no periodic wake up from IMPS. Periodic wakeup is +# unnecessary if Idle Scan is disabled. +gImpsModSleepTime=0 + + +# Enable BMPS or not +gEnableBmps=1 + +# Enable suspend or not + +# 1: Enable standby, 2: Enable Deep sleep, 3: Enable Mcast/Bcast Filter + +gEnableSuspend=3 + + +# Phy Mode (auto, b, g, n, etc) +# Valid values are 0-9, with 0 = Auto, 4 = 11n, 9 = 11ac +# 1 = 11abg, 2 = 11b, 3 = 11g, 5 = 11g only, 6 = 11n only +# 7 = 11b only 8 = 11ac only. +gDot11Mode=0 + + +# CSR Roaming Enable(1) Disable(0) + +gRoamingTime=0 + + +# Assigned MAC Addresses - This will be used until NV items are in place + +# Each byte of MAC address is represented in Hex format as XX + +Intf0MacAddress=000AF58989FF +Intf1MacAddress=000AF58989FE +Intf2MacAddress=000AF58989FD + +Intf3MacAddress=000AF58989FC + + +# UAPSD service interval for VO,VI, BE, BK traffic + +InfraUapsdVoSrvIntv=0 + +InfraUapsdViSrvIntv=0 + +InfraUapsdBeSrvIntv=0 + +InfraUapsdBkSrvIntv=0 + +# Flag to allow STA send AddTspec even when ACM is Off +gAddTSWhenACMIsOff=1 + +# Make 1x1 the default antenna configuration + +gNumRxAnt=1 + + +# Beacon filtering frequency (unit in beacon intervals) + +gNthBeaconFilter=50 + + +# Enable WAPI or not + +# WAPIIsEnabled=0 + + +# Flags to filter Mcast abd Bcast RX packets. + +# Value 0: No filtering, 1: Filter all Multicast. + +# 2: Filter all Broadcast. 3: Filter all Mcast abd Bcast + +McastBcastFilter=3 + + +#Flag to enable HostARPOffload feature or not + +hostArpOffload=1 + +#Flag to enable TCPChkSumOffld feature or not + +gEnableTCPChkSumOffld=0 + +#Flag to enable HostNSOffload feature or not + +hostNSOffload=1 + +#Flag to enable IPChkSumOffld feature or not + +gEnableIPChecksumOffload=0 + +#SoftAP Related Parameters + +# AP MAc addr + +gAPMacAddr=000AF589dcab + + +# 802.11n Protection flag + +gEnableApProt=1 + + +#Enable OBSS protection + +gEnableApOBSSProt=1 + + +#Enable/Disable UAPSD for SoftAP + +gEnableApUapsd=1 + + +# Fixed Rate + +gFixedRate=0 + + +# Maximum Tx power + +# gTxPowerCap=30 + + +# Fragmentation Threshold + +# gFragmentationThreshold=2346 + + +# RTS threshold + +RTSThreshold=1048576 + + +# Intra-BSS forward + +gDisableIntraBssFwd=0 + + +# WMM Enable/Disable + +WmmIsEnabled=0 + + +# 802.11d support + +g11dSupportEnabled=0 + +# 802.11h support + +g11hSupportEnabled=1 + +# DFS Master Capability +gEnableDFSMasterCap=1 + +# ESE Support and fast transition +EseEnabled=1 +ImplicitQosIsEnabled=0 +gNeighborScanTimerPeriod=200 + +gNeighborLookupThreshold=76 +gNeighborReassocThreshold=81 + +gNeighborScanChannelMinTime=20 +gNeighborScanChannelMaxTime=30 +gMaxNeighborReqTries=3 + +# Legacy (non-ESE, non-802.11r) Fast Roaming Support +# To enable, set FastRoamEnabled=1 +# To disable, set FastRoamEnabled=0 +FastRoamEnabled=1 + +#Check if the AP to which we are roaming is better than current AP in terms of RSSI. +#Checking is disabled if set to Zero.Otherwise it will use this value as to how better +#the RSSI of the new/roamable AP should be for roaming +RoamRssiDiff=3 + +# If the RSSI of any available candidate is better than currently associated +# AP by at least gImmediateRoamRssiDiff, then being to roam immediately (without +# registering for reassoc threshold). +# NOTE: Value of 0 means that we would register for reassoc threshold. +gImmediateRoamRssiDiff=10 + +# To enable, set gRoamIntraBand=1 (Roaming within band) +# To disable, set gRoamIntraBand=0 (Roaming across band) +gRoamIntraBand=0 + +# SAP Country code + +# Default Country Code is 2 bytes, 3rd byte is optional indoor or out door. + +# Example + +# US Indoor, USI + +# Korea Outdoor, KRO + +# Japan without optional byte, JP + +# France without optional byte, FR + +#gAPCntryCode=USI + + +#Short Guard Interval Enable/disable + +gShortGI20Mhz=1 + +gShortGI40Mhz=1 + + +#Auto Shutdown Value in seconds. A value of 0 means Auto shutoff is disabled + +gAPAutoShutOff=0 + +#Auto Shutdown wlan : Value in Seconds. 0 means disabled. Max 1 day = 86400 sec +gWlanAutoShutdown = 0 + + +# SAP auto channel selection configuration + +# 0 = disable auto channel selection + +# 1 = enable auto channel selection, channel provided by supplicant will be ignored + +gApAutoChannelSelection=0 + + +# Listen Energy Detect Mode Configuration + +# Valid values 0-128 + +# 128 means disable Energy Detect feature + +# 0-9 are threshold code and 7 is recommended value from system if feature is to be enabled. + +# 10-128 are reserved. + +# The EDET threshold mapping is as follows in 3dB step: + +# 0 = -60 dBm + +# 1 = -63 dBm + +# 2 = -66 dBm + +# ... + +# 7 = -81 dBm + +# 8 = -84 dBm + +# 9 = -87 dBm + +# Note: Any of these settings are valid. Setting 0 would yield the highest power saving (in a noisy environment) at the cost of more range. The range impact is approximately #calculated as: + +# + +# Range Loss (dB) = EDET threshold level (dBm) + 97 dBm. + +# + +gEnablePhyAgcListenMode=128 + + +#Preferred channel to start BT AMP AP mode (0 means, any channel) + +BtAmpPreferredChannel=0 + + +#Preferred band (both or 2.4 only or 5 only) + +BandCapability=0 + + +#Beacon Early Termination (1 = enable the BET feature, 0 = disable) + +enableBeaconEarlyTermination=0 + +beaconEarlyTerminationWakeInterval=3 + + +#Bluetooth Alternate Mac Phy (1 = enable the BT AMP feature, 0 = disable) + +gEnableBtAmp=0 + + +#SOFTAP Channel Range selection + +gAPChannelSelectStartChannel=1 + +gAPChannelSelectEndChannel=11 + + +#SOFTAP Channel Range selection Operating band + +# 0:2.4GHZ 1: LOW-5GHZ 2:MID-5GHZ 3:HIGH-5GHZ 4: 4.9HZ BAND + +gAPChannelSelectOperatingBand=0 + + +#Channel Bonding +gChannelBondingMode5GHz=1 + + +#Enable Keep alive with non-zero period value + +gStaKeepAlivePeriod = 30 + +#Say gGoKeepAlivePeriod(5 seconds) and gGoLinkMonitorPeriod(10 seconds). +#For every 10 seconds DUT send Qos Null frame(i.e., Keep Alive frame if link is idle for last 10 seconds.) +#For both active and power save clients. + +#Power save clients: DUT set TIM bit from 10th second onwards and till client honors TIM bit. +#If doesn't honor for 5 seconds then DUT remove client. + +#Active clients: DUT send Qos Null frame for 10th seconds onwards if it is not success still we try on +#11th second if not tries on 12th and so on till 15th second. Hence before disconnection DUT will send 5 NULL frames. +#Hence in any case DUT will detect client got removed in (10+5) seconds. i.e., (gGoKeepAlivePeriod + gGoLinkMonitorPeriod).. + +#gGoLinkMonitorPeriod/ gApLinkMonitorPeriod is period where link is idle and it is period +#where we send NULL frame. + +gApLinkMonitorPeriod = 30 + +gGoLinkMonitorPeriod = 10 + +#gGoKeepAlivePeriod/gApKeepAlivePeriod is time to spend to check whether frame are succeed to send or not. +#Hence total effective detection time is gGoLinkMonitorPeriod+ gGoKeepAlivePeriod/gApLinkMonitorPeriod+ gApKeepAlivePeriod. + + +gGoKeepAlivePeriod = 3 + +gApKeepAlivePeriod = 10 + + +#If set will start with active scan after driver load, otherwise will start with + +#passive scan to find out the domain + +gEnableBypass11d=1 + + +#If set to 0, will not scan DFS channels + +gEnableDFSChnlScan=1 + + +gVhtChannelWidth=2 +gEnableLogp=1 + + +# Enable Automatic Tx Power control + +gEnableAutomaticTxPowerControl=1 + +# 0 for OLPC 1 for CLPC and SCPC +gEnableCloseLoop=1 + +#Data Inactivity Timeout when in powersave (in ms) +gDataInactivityTimeout=200 + +# VHT Tx/Rx MCS values +# Valid values are 0,1,2. If commented out, the default value is 0. +# 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 +gVhtRxMCS=2 +gVhtTxMCS=2 + +# VHT Tx/Rx MCS values for 2x2 +# Valid values are 0,1,2. If commented out, the default value is 0. +# 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 +gEnable2x2=1 +gVhtRxMCS2x2=2 +gVhtTxMCS2x2=2 + +# Set txchainmask and rxchainmask +# These parameters are used only if gEnable2x2 is 0 +# Valid values are 1,2 +# Set gSetTxChainmask1x1=1 or gSetRxChainmask1x1=1 to select chain0. +# Set gSetTxChainmask1x1=2 or gSetRxChainmask1x1=2 to select chain1. +gSetTxChainmask1x1=1 +gSetRxChainmask1x1=1 + +# Scan Timing Parameters +# gPassiveMaxChannelTime=110 +# gPassiveMinChannelTime=60 +gActiveMaxChannelTime=80 +gActiveMinChannelTime=40 + +#If set to 0, MCC is not allowed. +gEnableMCCMode=1 + +# MCC to SCC Switch mode: 0-Disable 1-Enable 2-Force SCC if same band +gWlanMccToSccSwitchMode = 0 + +# 1=enable STBC; 0=disable STBC +gEnableRXSTBC=1 + +# 1=enable tx STBC; 0=disable +gEnableTXSTBC=1 + +# 1=enable rx LDPC; 0=disable +gEnableRXLDPC=1 + +#Enable/Disable Tx beamforming +gTxBFEnable=1 + +# Enable Tx beamforming in VHT20MHz +# Valid values are 0,1. If commented out, the default value is 0. +# 0=disable, 1=enable +gEnableTxBFin20MHz=1 + +# Enable Active mode offload +gEnableActiveModeOffload=1 + +#Enable Scan Results Aging based on timer +#Timer value is in seconds +#If Set to 0 it will not enable the feature +gScanAgingTime=0 + +#Enable Scan Results Aging based on number of scans +gScanResultAgeCount=1 + +#Enable Power saving mechanism Based on Android Framework +#If set to 0 Driver internally control the Power saving mechanism +#If set to 1 Android Framwrok control the Power saving mechanism +isAndroidPsEn=0 + +#Enable thermal mitigation +gThermalMitigationEnable=0 + +gEnableFastRoamInConcurrency=1 + +#List of Country codes for which 11ac needs to be disabled +#Each country code must be delimited by comma(,) +gListOfNon11acCountryCode=RU,UA,ZA + +#Maxium Channel time in msec +gMaxMediumTime = 6000 + +# 802.11K support +gRrmEnable=1 +gRrmOperChanMax=8 +gRrmNonOperChanMax=8 +gRrmRandIntvl=100 + +#Scan offload +gEnableDirectedScanOffload=1 + +#FlexConnect Power Factor +#Default is set to 0 (disable) +gFlexConnectPowerFactor=0 + +#Disable split scan, the FW will take care of it +gNumChanCombinedConc=60 + +#Enable Power Save offload +gEnablePowerSaveOffload=2 + +#Enable firmware uart print +gEnablefwprint=0 + +#Enable firmware log +gEnablefwlog=1 + +#IPA config +gIPAEnable=0x00 +gIPADescSize=800 +gIPAPreFilterEnable=1 +gIPARMEnable=1 +gIPAIPv6Enable=1 + +#P2P Listen offload +gEnableP2pListenOffload=1 + +# Maximum Receive AMPDU size (VHT only. Valid values: 0->8k 1->16k 2->32k 3->64k 4->128k) +gVhtAmpduLenExponent=7 + +# Maximum MPDU length (VHT only. Valid values: 0->3895 octets, 1->7991 octets, 2->11454 octets) +gVhtMpduLen=2 + +# Maximum number of wow filters required +#gMaxWoWFilters=22 + +# WOW Enable/Disable. +# 0 - Disable both magic pattern match and pattern byte match. +# 1 - Enable magic pattern match on all interfaces. +# 2 - Enable pattern byte match on all interfaces. +# 3 - Enable both magic patter and pattern byte match on all interfaces. +# Default value of gEnableWoW is 3. +# gEnableWoW=0 + +# Enable or Disable MCC Adaptive Scheduler at the FW +# 1=Enable (default), 0=Disable +gEnableMCCAdaptiveScheduler=1 + +#Enable or Disable p2p device address administered +isP2pDeviceAddrAdministrated=1 + +#Enable Rx thread +gEnableRxThread=1 + +# Set Thermal Power limit +TxPower2g=10 +TxPower5g=10 + +# Remove Overlap channel restriction +gEnableOverLapCh=0 + +#Enable VHT on 2.4Ghz +gEnableVhtFor24GHzBand=1 + +#Enable or Disable 5G early beacon termination +gEnable5gEBT=1 + +#Maximum number of offload peers supported +# gMaxOffloadPeers=2 + +# controlling the following offload patterns +# through ini parameter. Default value is 1 +# to disable set it to zero. ssdp = 0 +# Setup multicast pattern for mDNS 224.0.0.251, +# SSDP 239.255.255.250 and LLMNR 224.0.0.252 + + +ssdp = 0 + +#Enable Memory Deep Sleep +gEnableMemDeepSleep=1 + +#Disable/Enable Strict FCC Regulatory +# 0 to disable, 1 to enable +gEnableStrictRegulatoryForFCC=0 + +#Disable packet log feature +gEnablePacketLog=0 + +# Bus bandwidth threshold values in terms of number of packets +gBusBandwidthHighThreshold=2000 +gBusBandwidthMediumThreshold=500 +gBusBandwidthLowThreshold=150 + +# Bus bandwidth compute timeout value in ms +gBusBandwidthComputeInterval=100 + +# Regulatory Setting; 0=STRICT; 1=CUSTOM +gRegulatoryChangeCountry=1 +# RA filtering rate limit param, the current value would not +# help if the lifetime in RA is less than 3*60=3min. Then +# we need to change it, though it is uncommon. +# gRAFilterEnable=0 +gRArateLimitInterval=60 + +# Maximum number of concurrent connections +gMaxConcurrentActiveSessions=2 + +# Disable/Enable GreenAP +# 0 to disable, 1 to enable, default: 1 +gEnableGreenAp=1 + +# Radar PRI multiplier +gDFSradarMappingPriMultiplier=4 + +gPNOScanSupport=0 + +# Enable/Disable RX full reorder offload +gReorderOffloadSupported=1 + +#Enable/Disable LPASS support +# 0 to disable, 1 to enable +gEnableLpassSupport=0 + +# Whether userspace country code setting shld have priority +gCountryCodePriority=1 + +# Enable(1)/Disable(0) SIFS burst +gEnableSifsBurst=1 + +# Enable or Disable Multi-user MIMO +# 1=Enable (default), 0=Disable +gEnableMuBformee=1 + +# Enable/Disable channel avoidance for SAP in SCC scenario +# 0 - disable +# 1 - enable +gSapSccChanAvoidance=0 + +# Inactivity time (in ms) to end TX Service Period while in IBSS power save mode +gIbssTxSpEndInactivityTime=10 + +# Enable/Disable Roaming Offload Support (a.k.a Key Management Offload) +# 0 to disable, 1 to enable +gRoamOffloadEnabled=0 + +# Enable support for TDLS +# 0 - disable +# 1 - enable +gEnableTDLSSupport=1 + +# Enable support for Implicit Trigger of TDLS. That is, wlan driver shall +# initiate TDLS Discovery towards a peer whenever setup criteria (throughput +# and RSSI) is met and then will initiate teardown when teardown criteria +# (idle packet count and RSSI) is met. +# 0 - disable +# 1 - enable +gEnableTDLSImplicitTrigger=1 + +# Enable TDLS External Control. That is, user space application has to +# first configure a peer MAC in wlan driver towards which TDLS is desired. +# Device will establish TDLS only towards those configured peers whenever +# TDLS criteria (throughput and RSSI threshold) is met and teardown TDLS +# when teardown criteria (idle packet count and RSSI) is met. However, +# device will accept TDLS connection if it is initiated from any other peer, +# even if that peer is not configured. +# 0 - disable +# 1 - enable +# For TDLS External Control, Implicit Trigger must also be enabled. +gTDLSExternalControl=1 + +# Enable support for TDLS off-channel operation +# 0 - disable +# 1 - enable +# TDLS off-channel operation will be invoked when there is only one +# TDLS connection. +gEnableTDLSOffChannel=1 + +gEnableSelfRecovery=1 + +# Enable or Disable Random MAC (Spoofing) +# 1=Enable, 0=Disable (default) +gEnableMacAddrSpoof=0 + +# Enable to check FW hash if secure FW feature is enabled. It's for defconfig +# builds only since it will be ignored in performance/release builds. +gEnableFWHashCheck=1 +END + +# Note: Configuration parser would not read anything past the END marker + diff --git a/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.usb.ini b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.usb.ini new file mode 100644 index 0000000000000..65117c9b825ee --- /dev/null +++ b/drivers/staging/qcacld-2.0/firmware_bin/WCNSS_qcom_cfg.usb.ini @@ -0,0 +1,518 @@ +# This file allows user to override the factory + +# defaults for the WLAN Driver + + +# Enable IMPS or not +gEnableImps=1 + +# Enable/Disable Idle Scan + +gEnableIdleScan=0 + + +# Increase sleep duration (seconds) during IMPS +# 0 implies no periodic wake up from IMPS. Periodic wakeup is +# unnecessary if Idle Scan is disabled. +gImpsModSleepTime=0 + + +# Enable BMPS or not +gEnableBmps=1 + +# Enable suspend or not + +# 1: Enable standby, 2: Enable Deep sleep, 3: Enable Mcast/Bcast Filter + +gEnableSuspend=3 + + +# Phy Mode (auto, b, g, n, etc) +# Valid values are 0-9, with 0 = Auto, 4 = 11n, 9 = 11ac +# 1 = 11abg, 2 = 11b, 3 = 11g, 5 = 11g only, 6 = 11n only +# 7 = 11b only 8 = 11ac only. +gDot11Mode=0 + + +# CSR Roaming Enable(1) Disable(0) + +gRoamingTime=0 + + +# Assigned MAC Addresses - This will be used until NV items are in place + +# Each byte of MAC address is represented in Hex format as XX + +Intf0MacAddress=000AF58989FF +Intf1MacAddress=000AF58989FE +Intf2MacAddress=000AF58989FD + +Intf3MacAddress=000AF58989FC + + +# UAPSD service interval for VO,VI, BE, BK traffic + +InfraUapsdVoSrvIntv=0 + +InfraUapsdViSrvIntv=0 + +InfraUapsdBeSrvIntv=0 + +InfraUapsdBkSrvIntv=0 + +# Flag to allow STA send AddTspec even when ACM is Off +gAddTSWhenACMIsOff=1 + +# Make 1x1 the default antenna configuration + +gNumRxAnt=1 + + +# Beacon filtering frequency (unit in beacon intervals) + +gNthBeaconFilter=50 + + +# Enable WAPI or not + +# WAPIIsEnabled=0 + + +# Flags to filter Mcast abd Bcast RX packets. + +# Value 0: No filtering, 1: Filter all Multicast. + +# 2: Filter all Broadcast. 3: Filter all Mcast abd Bcast + +McastBcastFilter=3 + + +#Flag to enable HostARPOffload feature or not + +hostArpOffload=1 + +#Flag to enable TCPChkSumOffld feature or not + +gEnableTCPChkSumOffld=1 + +#Flag to enable HostNSOffload feature or not + +hostNSOffload=1 + +#Flag to enable IPChkSumOffld feature or not + +gEnableIPChecksumOffload=0 + +#SoftAP Related Parameters + +# AP MAc addr + +gAPMacAddr=000AF589dcab + + +# 802.11n Protection flag + +gEnableApProt=1 + + +#Disable OBSS protection + +gEnableApOBSSProt=0 + + +#Enable/Disable UAPSD for SoftAP + +gEnableApUapsd=1 + + +# Fixed Rate + +gFixedRate=0 + + +# Maximum Tx power + +# gTxPowerCap=30 + + +# Fragmentation Threshold + +# gFragmentationThreshold=2346 + + +# RTS threshold + +RTSThreshold=192000 + + +# Intra-BSS forward + +gDisableIntraBssFwd=0 + + +# WMM Enable/Disable + +WmmIsEnabled=0 + + +# 802.11d support + +g11dSupportEnabled=1 + +# 802.11h support + +g11hSupportEnabled=1 + +# ESE Support and fast transition +EseEnabled=0 +ImplicitQosIsEnabled=0 +gNeighborScanTimerPeriod=200 + +gNeighborLookupThreshold=76 +gNeighborReassocThreshold=81 + +gNeighborScanChannelMinTime=20 +gNeighborScanChannelMaxTime=30 +gMaxNeighborReqTries=3 + +# Legacy (non-ESE, non-802.11r) Fast Roaming Support +# To enable, set FastRoamEnabled=1 +# To disable, set FastRoamEnabled=0 +FastRoamEnabled=1 + +#Check if the AP to which we are roaming is better than current AP in terms of RSSI. +#Checking is disabled if set to Zero.Otherwise it will use this value as to how better +#the RSSI of the new/roamable AP should be for roaming +RoamRssiDiff=3 + +# If the RSSI of any available candidate is better than currently associated +# AP by at least gImmediateRoamRssiDiff, then being to roam immediately (without +# registering for reassoc threshold). +# NOTE: Value of 0 means that we would register for reassoc threshold. +gImmediateRoamRssiDiff=10 + +# To enable, set gRoamIntraBand=1 (Roaming within band) +# To disable, set gRoamIntraBand=0 (Roaming across band) +gRoamIntraBand=0 + +# SAP Country code + +# Default Country Code is 2 bytes, 3rd byte is optional indoor or out door. + +# Example + +# US Indoor, USI + +# Korea Outdoor, KRO + +# Japan without optional byte, JP + +# France without optional byte, FR + +#gAPCntryCode=USI + + +#Short Guard Interval Enable/disable + +gShortGI20Mhz=1 + +gShortGI40Mhz=1 + + +#Auto Shutdown Value in seconds. A value of 0 means Auto shutoff is disabled + +gAPAutoShutOff=0 + + +# SAP auto channel selection configuration + +# 0 = disable auto channel selection + +# 1 = enable auto channel selection, channel provided by supplicant will be ignored + +gApAutoChannelSelection=0 + + +# Listen Energy Detect Mode Configuration + +# Valid values 0-128 + +# 128 means disable Energy Detect feature + +# 0-9 are threshold code and 7 is recommended value from system if feature is to be enabled. + +# 10-128 are reserved. + +# The EDET threshold mapping is as follows in 3dB step: + +# 0 = -60 dBm + +# 1 = -63 dBm + +# 2 = -66 dBm + +# ... + +# 7 = -81 dBm + +# 8 = -84 dBm + +# 9 = -87 dBm + +# Note: Any of these settings are valid. Setting 0 would yield the highest power saving (in a noisy environment) at the cost of more range. The range impact is approximately #calculated as: + +# + +# Range Loss (dB) = EDET threshold level (dBm) + 97 dBm. + +# + +gEnablePhyAgcListenMode=128 + + +#Preferred channel to start BT AMP AP mode (0 means, any channel) + +BtAmpPreferredChannel=0 + + +#Preferred band (both or 2.4 only or 5 only) + +BandCapability=0 + + +#Beacon Early Termination (1 = enable the BET feature, 0 = disable) + +enableBeaconEarlyTermination=0 + +beaconEarlyTerminationWakeInterval=3 + + +#Bluetooth Alternate Mac Phy (1 = enable the BT AMP feature, 0 = disable) + +gEnableBtAmp=0 + + +#SOFTAP Channel Range selection + +gAPChannelSelectStartChannel=1 + +gAPChannelSelectEndChannel=11 + + +#SOFTAP Channel Range selection Operating band + +# 0:2.4GHZ 1: LOW-5GHZ 2:MID-5GHZ 3:HIGH-5GHZ 4: 4.9HZ BAND + +gAPChannelSelectOperatingBand=0 + + +#Channel Bonding +gChannelBondingMode5GHz=1 + + +#Enable Keep alive with non-zero period value + +gStaKeepAlivePeriod = 30 + +#Say gGoKeepAlivePeriod(5 seconds) and gGoLinkMonitorPeriod(10 seconds). +#For every 10 seconds DUT send Qos Null frame(i.e., Keep Alive frame if link is idle for last 10 seconds.) +#For both active and power save clients. + +#Power save clients: DUT set TIM bit from 10th second onwards and till client honors TIM bit. +#If doesn't honor for 5 seconds then DUT remove client. + +#Active clients: DUT send Qos Null frame for 10th seconds onwards if it is not success still we try on +#11th second if not tries on 12th and so on till 15th second. Hence before disconnection DUT will send 5 NULL frames. +#Hence in any case DUT will detect client got removed in (10+5) seconds. i.e., (gGoKeepAlivePeriod + gGoLinkMonitorPeriod).. + +#gGoLinkMonitorPeriod/ gApLinkMonitorPeriod is period where link is idle and it is period +#where we send NULL frame. + +#gApLinkMonitorPeriod = 10 + +#gGoLinkMonitorPeriod = 10 + +#gGoKeepAlivePeriod/gApKeepAlivePeriod is time to spend to check whether frame are succeed to send or not. +#Hence total effective detection time is gGoLinkMonitorPeriod+ gGoKeepAlivePeriod/gApLinkMonitorPeriod+ gApKeepAlivePeriod. + + +gGoKeepAlivePeriod = 20 + +gApKeepAlivePeriod = 20 + + +#If set will start with active scan after driver load, otherwise will start with + +#passive scan to find out the domain + +gEnableBypass11d=1 + + +#If set to 0, will not scan DFS channels + +gEnableDFSChnlScan=1 + + +gVhtChannelWidth=2 +gEnableLogp=1 + + +# Enable Automatic Tx Power control + +gEnableAutomaticTxPowerControl=1 + +# 0 for OLPC 1 for CLPC and SCPC +gEnableCloseLoop=1 + +#Data Inactivity Timeout when in powersave (in ms) +gDataInactivityTimeout=200 + +# VHT Tx/Rx MCS values +# Valid values are 0,1,2. If commented out, the default value is 0. +# 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 +gVhtRxMCS=0 +gVhtTxMCS=2 + +# VHT Tx/Rx MCS values for 2x2 +# Valid values are 0,1,2. If commented out, the default value is 0. +# 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 +gEnable2x2=1 +gVhtRxMCS2x2=0 +gVhtTxMCS2x2=2 + +# Scan Timing Parameters +# gPassiveMaxChannelTime=110 +# gPassiveMinChannelTime=60 +# gActiveMaxChannelTime=40 +# gActiveMinChannelTime=20 + +#If set to 0, MCC is not allowed. +gEnableMCCMode=1 + +# 1=enable STBC; 0=disable STBC +gEnableRXSTBC=1 + +# 1=enable tx STBC; 0=disable +gEnableTXSTBC=1 + +# 1=enable rx LDPC; 0=disable +gEnableRXLDPC=1 + +# Enable Active mode offload +gEnableActiveModeOffload=1 + +#Enable Scan Results Aging based on timer +#Timer value is in seconds +#If Set to 0 it will not enable the feature +gScanAgingTime=0 + +#Enable Power saving mechanism Based on Android Framework +#If set to 0 Driver internally control the Power saving mechanism +#If set to 1 Android Framwrok control the Power saving mechanism +isAndroidPsEn=0 + +#disable LDPC in STA mode if the AP is TXBF capable +gDisableLDPCWithTxbfAP=1 + +#Enable thermal mitigation +gThermalMitigationEnable=1 +gThermalTempMinLevel1=90 +gThermalTempMaxLevel0=100 +gThrottlePeriod=100 + +gEnableFastRoamInConcurrency=1 + +#List of Country codes for which 11ac needs to be disabled +#Each country code must be delimited by comma(,) +gListOfNon11acCountryCode=RU,UA,ZA + +#Maxium Channel time in msec +gMaxMediumTime = 6000 + +# 802.11K support +gRrmEnable=1 +gRrmOperChanMax=8 +gRrmNonOperChanMax=8 +gRrmRandIntvl=100 + +#Scan offload +gEnableDirectedScanOffload=1 + +#FlexConnect Power Factor +#Default is set to 0 (disable) +gFlexConnectPowerFactor=0 + +#Disable split scan, the FW will take care of it +gNumChanCombinedConc=60 + +#Enable Power Save offload +gEnablePowerSaveOffload=1 + +#Enable firmware uart print +gEnablefwprint=0 + +#Enable firmware log +gEnablefwlog=1 + +#IPA config +gIPAEnable=1 +gIPADescSize=800 +gIPAPreFilterEnable=1 +gIPARMEnable=1 + +#P2P Listen offload +gEnableP2pListenOffload=1 + +# Maximum Receive AMPDU size (VHT only. Valid values: 0->8k 1->16k 2->32k 3->64k 4->128k) +gVhtAmpduLenExponent=7 + +# Maximum MPDU length (VHT only. Valid values: 0->3895 octets, 1->7991 octets, 2->11454 octets) +gVhtMpduLen=0 + +# Maximum number of wow filters required +#gMaxWoWFilters=22 + +# WOW Enable/Disable. +# 0 - Disable both magic pattern match and pattern byte match. +# 1 - Enable magic pattern match on all interfaces. +# 2 - Enable pattern byte match on all interfaces. +# 3 - Enable both magic patter and pattern byte match on all interfaces. +# Default value of gEnableWoW is 3. +# gEnableWoW=0 + +# Enable or Disable MCC Adaptive Scheduler at the FW +# 1=Enable (default), 0=Disable +gEnableMCCAdaptiveScheduler=1 + +#Enable or Disable p2p device address administered +isP2pDeviceAddrAdministrated=0 + +#Disable scan_pno by default +gPNOScanSupport=0 + +#Enable TDLS +gEnableTDLSSupport=1 + +# Regulatory Setting; 0=STRICT; 1=CUSTOM +gRegulatoryChangeCountry=1 + +# Disable FW log function by default +gFwDebugLogType=0 +gFwDebugModuleLoglevel=0,0 + +# Enable or Disable Rx thread +# 1=Enable (default), 0=Disable +gEnableRxThread=0 + +# Enable or Disable FW self-recovery +# Currently, It's for USB only. +# 1=Enable, 0=Disable (default) +gEnableFwSelfRecovery=0 + +# Enable or Disable SAP suspend +# 1=Enable (default), 0=Disable +gEnableSapSuspend=0 +END + +# Note: Configuration parser would not read anything past the END marker + diff --git a/drivers/staging/qcacld-2.0/tools/Makefile.am b/drivers/staging/qcacld-2.0/tools/Makefile.am new file mode 100644 index 0000000000000..683a3d942e0ca --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/Makefile.am @@ -0,0 +1,11 @@ +# Makefile.am - Automake script for qcacld-tools + +ACLOCAL_AMFLAGS = -I m4 + +dirs : + +dirs = fwdebuglog +dirs += athdiag +dirs += pktlog + +SUBDIRS = $(dirs) diff --git a/drivers/staging/qcacld-2.0/tools/athdiag/Android.mk b/drivers/staging/qcacld-2.0/tools/athdiag/Android.mk new file mode 100644 index 0000000000000..9cda732d17d1d --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/athdiag/Android.mk @@ -0,0 +1,8 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := athdiag +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_SHARED_LIBRARIES := libc libcutils +LOCAL_SRC_FILES := athdiag.c +include $(BUILD_EXECUTABLE) diff --git a/drivers/staging/qcacld-2.0/tools/athdiag/Makefile b/drivers/staging/qcacld-2.0/tools/athdiag/Makefile new file mode 100644 index 0000000000000..4aea1b8e24e77 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/athdiag/Makefile @@ -0,0 +1,12 @@ + +CC := $(ATH_CROSS_COMPILE_TYPE)gcc +TARGET_TYPE ?= AR9888 +TARGET_VERS ?= v2 + +all: + $(CC) -g3 -Wall \ + -I ../../CORE/SERVICES/COMMON/ \ + athdiag.c -o athdiag + +clean: + rm -f athdiag diff --git a/drivers/staging/qcacld-2.0/tools/athdiag/Makefile.am b/drivers/staging/qcacld-2.0/tools/athdiag/Makefile.am new file mode 100644 index 0000000000000..cdfaafa1df075 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/athdiag/Makefile.am @@ -0,0 +1,15 @@ +AM_CFLAGS = -Wall + +TARGET_TYPE ?= AR9888 +TARGET_VERS ?= v2 + +if DEBUG +AM_CFLAGS += -g +else +AM_CFLAGS += -O2 +endif + +AM_CFLAGS += -I $(top_srcdir)/../CORE/SERVICES/COMMON/ + +athdiag_SOURCES = athdiag.c +bin_PROGRAMS = athdiag diff --git a/drivers/staging/qcacld-2.0/tools/athdiag/athdiag.c b/drivers/staging/qcacld-2.0/tools/athdiag/athdiag.c new file mode 100644 index 0000000000000..a1bcb0f4294af --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/athdiag/athdiag.c @@ -0,0 +1,1250 @@ +/* + * Copyright (c) "2012,2014" The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * $ATH_LICENSE_HOSTSDK0_C$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "apb_athr_wlan_map.h" +#include "rtc_soc_reg.h" +#include "efuse_reg.h" + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* + * This is a user-level agent which provides diagnostic read/write + * access to Target space. This may be used + * to collect information for analysis + * to read/write Target registers + * etc. + */ + +#define DIAG_READ_TARGET 1 +#define DIAG_WRITE_TARGET 2 +#define DIAG_READ_WORD 3 +#define DIAG_WRITE_WORD 4 +#define DIAG_DUMP_TARGET 5 + + +#define ADDRESS_FLAG 0x0001 +#define LENGTH_FLAG 0x0002 +#define PARAM_FLAG 0x0004 +#define FILE_FLAG 0x0008 +#define UNUSED0x010 0x0010 +#define AND_OP_FLAG 0x0020 +#define BITWISE_OP_FLAG 0x0040 +#define QUIET_FLAG 0x0080 +#define OTP_FLAG 0x0100 +#define HEX_FLAG 0x0200 +/* dump file mode,x: hex mode; other binary mode. */ +#define UNUSED0x400 0x0400 +#define DEVICE_FLAG 0x0800 +#define TARGET_FLAG 0x1000 +#define PATH_FLAG 0x2000 + +/* Limit malloc size when reading/writing file */ +#define MAX_BUF (8*1024) + +#define DUMP_DRAM_START_ADDR 0x400000 +#define DUMP_DRAM_LEN 0x50000 + +#define PEREGRINE_REG_PART1_START_ADDR 0x4000 +#define PEREGRINE_REG_PART1_LEN 0x2000 +#define PEREGRINE_REG_PART2_START_ADDR 0x8000 +#define PEREGRINE_REG_PART2_LEN 0x58000 + +#define AR6320V1_REG_PART1_START_ADDR 0x0 /*RTC_SOC_BASE_ADDRESS*/ +#define AR6320V1_REG_PART1_LEN (0x800 - 0x0) /*WLAN_MBOX_BASE_ADDRESS - RTC_SOC_BASE_ADDRESS*/ +#define AR6320V1_REG_PART2_START_ADDR 0x27000 /*STEREO_BASE_ADDRESS*/ +#define AR6320V1_REG_PART2_LEN (0x60000 - 0x27000) /*USB_BASE_ADDRESS - STEREO_BASE_ADDRESS*/ + +/* For Rome version 2.x */ + +#define AR6320V2_DRAM_START_ADDR 0x400000 // dram start +#define AR6320V2_DUMP_DRAM_LEN 0x70000 // dram length +#define AR6320V2_IRAM_START_ADDR 0x980000 // iram start +#define AR6320V2_IRAM_LEN 0x38000 // iram length +#define AR6320V2_AXI_START_ADDR 0xa0000 // axi start +#define AR6320V2_AXI_LEN 0x18000 // axi length + +/* For Rome version 3.x */ + +#define AR6320V3_DRAM_START_ADDR 0x400000 // dram start +#define AR6320V3_DUMP_DRAM_LEN 0xa8000 // dram length +#define AR6320V3_IRAM_START_ADDR 0x980000 // iram start +#define AR6320V3_IRAM_LEN 0x38000 // iram length +#define AR6320V3_AXI_START_ADDR 0xa0000 // axi start +#define AR6320V3_AXI_LEN 0x18000 // axi length + +struct ath_target_reg_info { + A_UINT32 reg_start; + A_UINT32 reg_len; + const char *reg_info; + const char *save_file; +}; + +static const struct ath_target_reg_info reg_ar9888_v2[] = { + {DUMP_DRAM_START_ADDR, DUMP_DRAM_LEN, "DRAM", "fwdump_prgr_v2_dram"}, + {PEREGRINE_REG_PART1_START_ADDR, PEREGRINE_REG_PART1_LEN, "REG_PART1", "fwdump_prgr_v2_reg1"}, + {PEREGRINE_REG_PART2_START_ADDR, PEREGRINE_REG_PART2_LEN, "REG_PART2", "fwdump_prgr_v2_reg2"}, + {0, 0, 0, 0} +}; + +static const struct ath_target_reg_info reg_ar6320_v1[] = { + {DUMP_DRAM_START_ADDR, DUMP_DRAM_LEN, "DRAM", "fwdump_rome_v1_dram"}, + {AR6320V1_REG_PART1_START_ADDR, AR6320V1_REG_PART1_LEN, "REG_PART1", "fwdump_rome_v1_reg1"}, + {AR6320V1_REG_PART2_START_ADDR, AR6320V1_REG_PART2_LEN, "REG_PART2", "fwdump_rome_v1_reg2"}, + {0, 0, 0, 0} +}; + +static const struct ath_target_reg_info reg_ar6320_v2[] = { + {AR6320V2_DRAM_START_ADDR, AR6320V2_DUMP_DRAM_LEN, "DRAM", "fwdump_rome_v2_dram"}, + {AR6320V2_IRAM_START_ADDR, AR6320V2_IRAM_LEN, "IRAM", "fwdump_rome_v2_iram"}, + {AR6320V2_AXI_START_ADDR, AR6320V2_AXI_LEN, "AXI", "fwdump_rome_v2_axi" }, + {0, 0, 0, 0} +}; + +static const struct ath_target_reg_info reg_ar6320_v3[] = { + {AR6320V3_DRAM_START_ADDR, AR6320V3_DUMP_DRAM_LEN, "DRAM", "fwdump_rome_v3_dram"}, + {AR6320V3_IRAM_START_ADDR, AR6320V3_IRAM_LEN, "IRAM", "fwdump_rome_v3_iram"}, + {AR6320V3_AXI_START_ADDR, AR6320V3_AXI_LEN, "AXI" , "fwdump_rome_v3_axi" }, + {0x800, 0x10, "REG", "reg800"}, + {0x820, 0xC, "REG", "reg820"}, + {0x830, 0xC4, "REG", "reg830"}, + {0x90C, 0x10, "REG", "reg90C"}, + {0xA14, 0x4, "REG", "regA14"}, + {0xA84, 0x10, "REG", "regA84"}, + {0xAA8, 0x2C, "REG", "regAA8"}, + {0xADC, 0x64, "REG", "regADC"}, + {0x1000, 0xA4, "REG", "reg1000"}, + {0x10BC, 0x60, "REG", "reg10BC"}, + {0x1134, 0x4, "REG", "reg1134"}, + {0x1144, 0x8, "REG", "reg1144"}, + {0x1150, 0xC, "REG", "reg1150"}, + {0x1160, 0x18, "REG", "reg1160"}, + {0x1240, 0x20, "REG", "reg1240"}, + {0x2000, 0x7C, "REG", "reg2000"}, + {0x3000, 0x14, "REG", "reg3000"}, + {0x4000, 0x14, "REG", "reg4000"}, + {0x5000, 0x124, "REG", "reg5000"}, + {0x6000, 0x40, "REG", "reg6000"}, + {0x6080, 0x4C, "REG", "reg6080"}, + {0x6100, 0x1C, "REG", "reg6100"}, + {0x6140, 0x98, "REG", "reg6140"}, + {0x6200, 0x38, "REG", "reg6200"}, + {0x6240, 0x4C, "REG", "reg6240"}, + {0x62C0, 0x2C, "REG", "reg62C0"}, + {0x6380, 0x68, "REG", "reg6380"}, + {0x6400, 0x40, "REG", "reg6400"}, + {0x6480, 0x4C, "REG", "reg6480"}, + {0x6500, 0x1C, "REG", "reg6500"}, + {0x6540, 0x40, "REG", "reg6540"}, + {0x6600, 0x38, "REG", "reg6600"}, + {0x6640, 0x4C, "REG", "reg6640"}, + {0x66C0, 0x2C, "REG", "reg66C0"}, + {0x6780, 0x68, "REG", "reg6780"}, + {0x7080, 0xC, "REG", "reg7080"}, + {0x70C0, 0x8, "REG", "reg70C0"}, + {0x7400, 0x1C, "REG", "reg7400"}, + {0x7440, 0x14, "REG", "reg7440"}, + {0x7800, 0x18, "REG", "reg7800"}, + {0x8000, 0x4, "REG", "reg8000"}, + {0x8010, 0x54, "REG", "reg8010"}, + {0x8080, 0x4, "REG", "reg8080"}, + {0x80A0, 0x4, "REG", "reg80A0"}, + {0x80C0, 0x4, "REG", "reg80C0"}, + {0x80E0, 0x14, "REG", "reg80E0"}, + {0x8100, 0x4, "REG", "reg8100"}, + {0x8110, 0x1C, "REG", "reg8110"}, + {0x9000, 0x4, "REG", "reg9000"}, + {0x9800, 0x2C, "REG", "reg9800"}, + {0x9830, 0x8, "REG", "reg9830"}, + {0x9840, 0x2C, "REG", "reg9840"}, + {0x9870, 0x28, "REG", "reg9870"}, + {0x9A00, 0x200, "REG", "reg9A00"}, + {0xD580, 0x1C, "REG", "regD580"}, + {0xF000, 0xE0, "REG", "regF000"}, + {0xF140, 0x50, "REG", "regF140"}, + {0xF250, 0xC, "REG", "regF250"}, + {0xF260, 0x8, "REG", "regF260"}, + {0xF26C, 0x3C, "REG", "regF26C"}, + {0x10008, 0x4, "REG", "reg10008"}, + {0x10014, 0x4, "REG", "reg10014"}, + {0x1001C, 0x4, "REG", "reg1001C"}, + {0x10024, 0x4, "REG", "reg10024"}, + {0x10030, 0x4, "REG", "reg10030"}, + {0x10040, 0x14, "REG", "reg10040"}, + {0x10058, 0x24, "REG", "reg10058"}, + {0x10080, 0x44, "REG", "reg10080"}, + {0x100C8, 0x4C, "REG", "reg100C8"}, + {0x1012C, 0x4, "REG", "reg1012C"}, + {0x10138, 0xC, "REG", "reg10138"}, + {0x10200, 0x20, "REG", "reg10200"}, + {0x10230, 0x20, "REG", "reg10230"}, + {0x10260, 0x20, "REG", "reg10260"}, + {0x10290, 0x20, "REG", "reg10290"}, + {0x102C0, 0x1C, "REG", "reg102C0"}, + {0x102E0, 0x14, "REG", "reg102E0"}, + {0x102FC, 0x80, "REG", "reg102FC"}, + {0x10380, 0x10, "REG", "reg10380"}, + {0x10800, 0x28, "REG", "reg10800"}, + {0x10840, 0x4, "REG", "reg10840"}, + {0x10880, 0x4, "REG", "reg10880"}, + {0x108C0, 0x28, "REG", "reg108C0"}, + {0x10900, 0x28, "REG", "reg10900"}, + {0x10940, 0x4, "REG", "reg10940"}, + {0x10980, 0x4, "REG", "reg10980"}, + {0x109C0, 0x28, "REG", "reg109C0"}, + {0x10A00, 0x28, "REG", "reg10A00"}, + {0x10A40, 0x10, "REG", "reg10A40"}, + {0x11000, 0x28, "REG", "reg11000"}, + {0x11030, 0x4, "REG", "reg11030"}, + {0x11038, 0x30, "REG", "reg11038"}, + {0x11070, 0x4, "REG", "reg11070"}, + {0x11078, 0x30, "REG", "reg11078"}, + {0x110B0, 0x4, "REG", "reg110B0"}, + {0x110B8, 0x30, "REG", "reg110B8"}, + {0x110F0, 0x4, "REG", "reg110F0"}, + {0x110F8, 0x30, "REG", "reg110F8"}, + {0x11138, 0xC, "REG", "reg11138"}, + {0x11178, 0x8, "REG", "reg11178"}, + {0x111B8, 0x8, "REG", "reg111B8"}, + {0x111F8, 0x8, "REG", "reg111F8"}, + {0x11238, 0x4, "REG", "reg11238"}, + {0x11270, 0x4, "REG", "reg11270"}, + {0x11278, 0x4, "REG", "reg11278"}, + {0x112B0, 0x4, "REG", "reg112B0"}, + {0x112B8, 0x4, "REG", "reg112B8"}, + {0x112F0, 0x4, "REG", "reg112F0"}, + {0x112F8, 0x4, "REG", "reg112F8"}, + {0x11338, 0x4, "REG", "reg11338"}, + {0x11378, 0x4, "REG", "reg11378"}, + {0x113B8, 0x4, "REG", "reg113B8"}, + {0x113F8, 0x4, "REG", "reg113F8"}, + {0x11438, 0x8, "REG", "reg11438"}, + {0x11478, 0x8, "REG", "reg11478"}, + {0x114B8, 0x4, "REG", "reg114B8"}, + {0x114F8, 0x4, "REG", "reg114F8"}, + {0x11538, 0x4, "REG", "reg11538"}, + {0x11578, 0x4, "REG", "reg11578"}, + {0x115B8, 0x4, "REG", "reg115B8"}, + {0x115F8, 0x4, "REG", "reg115F8"}, + {0x11638, 0x4, "REG", "reg11638"}, + {0x11678, 0x4, "REG", "reg11678"}, + {0x116B8, 0x4, "REG", "reg116B8"}, + {0x116F8, 0x4, "REG", "reg116F8"}, + {0x11738, 0x4, "REG", "reg11738"}, + {0x11778, 0x4, "REG", "reg11778"}, + {0x117B8, 0x4, "REG", "reg117B8"}, + {0x117F8, 0x4, "REG", "reg117F8"}, + {0x17000, 0x1C, "REG", "reg17000"}, + {0x17020, 0x8C, "REG", "reg17020"}, + {0x18000, 0x50, "REG", "reg18000"}, + {0x18054, 0x20, "REG", "reg18054"}, + {0x18080, 0x54, "REG", "reg18080"}, + {0x180DC, 0x28, "REG", "reg180DC"}, + {0x18108, 0x34, "REG", "reg18108"}, + {0x18144, 0x4, "REG", "reg18144"}, + {0x18168, 0xC, "REG", "reg18168"}, + {0x18178, 0x8, "REG", "reg18178"}, + {0x181C8, 0x18, "REG", "reg181C8"}, + {0x181E4, 0x4, "REG", "reg181E4"}, + {0x181EC, 0x20, "REG", "reg181EC"}, + {0x1825C, 0x24, "REG", "reg1825C"}, + {0x18284, 0xC, "REG", "reg18284"}, + {0x18294, 0xC, "REG", "reg18294"}, + {0x18300, 0x4, "REG", "reg18300"}, + {0x18314, 0xC, "REG", "reg18314"}, + {0x18328, 0x28, "REG", "reg18328"}, + {0x1835C, 0x10, "REG", "reg1835C"}, + {0x18370, 0x20, "REG", "reg18370"}, + {0x18398, 0x14, "REG", "reg18398"}, + {0x183BC, 0x1C, "REG", "reg183BC"}, + {0x183DC, 0x18, "REG", "reg183DC"}, + {0x18400, 0x2F4, "REG", "reg18400"}, + {0x186F8, 0x24, "REG", "reg186F8"}, + {0x18720, 0x70, "REG", "reg18720"}, + {0x19800, 0x30, "REG", "reg19800"}, + {0x19834, 0xC, "REG", "reg19834"}, + {0x19880, 0x1C, "REG", "reg19880"}, + {0x198A4, 0xC, "REG", "reg198A4"}, + {0x198BC, 0x44, "REG", "reg198BC"}, + {0x19C00, 0x88, "REG", "reg19C00"}, + {0x19D00, 0x20, "REG", "reg19D00"}, + {0x19E00, 0x7C, "REG", "reg19E00"}, + {0x19E80, 0x14, "REG", "reg19E80"}, + {0x19E98, 0x14, "REG", "reg19E98"}, + {0x19EB0, 0xC, "REG", "reg19EB0"}, + {0x19F70, 0x4, "REG", "reg19F70"}, + {0x19F80, 0xC, "REG", "reg19F80"}, + {0x19FA0, 0x14, "REG", "reg19FA0"}, + {0x19FC0, 0x18, "REG", "reg19FC0"}, + {0x1A000, 0x200, "REG", "reg1A000"}, + {0x1A204, 0xC, "REG", "reg1A204"}, + {0x1A228, 0x4, "REG", "reg1A228"}, + {0x1A230, 0x18, "REG", "reg1A230"}, + {0x1A250, 0x20, "REG", "reg1A250"}, + {0x1A280, 0x10, "REG", "reg1A280"}, + {0x1A2A0, 0x4, "REG", "reg1A2A0"}, + {0x1A2C0, 0x2C, "REG", "reg1A2C0"}, + {0x1A300, 0xBC, "REG", "reg1A300"}, + {0x1A3F0, 0x4, "REG", "reg1A3F0"}, + {0x1A3F8, 0x3C, "REG", "reg1A3F8"}, + {0x1A438, 0xC, "REG", "reg1A438"}, + {0x1A448, 0x20, "REG", "reg1A448"}, + {0x1A580, 0xC, "REG", "reg1A580"}, + {0x1A644, 0x10, "REG", "reg1A644"}, + {0x1A670, 0x28, "REG", "reg1A670"}, + {0x1A6AC, 0x4, "REG", "reg1A6AC"}, + {0x1A6D0, 0x4, "REG", "reg1A6D0"}, + {0x1A6EC, 0x20, "REG", "reg1A6EC"}, + {0x1A710, 0x28, "REG", "reg1A710"}, + {0x1A7C0, 0x10, "REG", "reg1A7C0"}, + {0x1A7D4, 0x4, "REG", "reg1A7D4"}, + {0x1A7DC, 0x8, "REG", "reg1A7DC"}, + {0x1A7F0, 0x8, "REG", "reg1A7F0"}, + {0x1A888, 0x14, "REG", "reg1A888"}, + {0x1A8A8, 0x4, "REG", "reg1A8A8"}, + {0x1A8C0, 0x1C, "REG", "reg1A8C0"}, + {0x1A8F0, 0xC, "REG", "reg1A8F0"}, + {0x1AE04, 0x4, "REG", "reg1AE04"}, + {0x1AE18, 0xC, "REG", "reg1AE18"}, + {0x1AF80, 0xC, "REG", "reg1AF80"}, + {0x1AFA0, 0x14, "REG", "reg1AFA0"}, + {0x1B000, 0x200, "REG", "reg1B000"}, + {0x1B284, 0x4, "REG", "reg1B284"}, + {0x1B2D0, 0x8, "REG", "reg1B2D0"}, + {0x1B2DC, 0x10, "REG", "reg1B2DC"}, + {0x1B300, 0x40, "REG", "reg1B300"}, + {0x1B374, 0x4, "REG", "reg1B374"}, + {0x1B380, 0x4, "REG", "reg1B380"}, + {0x1B388, 0x4, "REG", "reg1B388"}, + {0x1B404, 0x4, "REG", "reg1B404"}, + {0x1B420, 0x8, "REG", "reg1B420"}, + {0x1B440, 0x4, "REG", "reg1B440"}, + {0x1B448, 0x4, "REG", "reg1B448"}, + {0x1B450, 0x8, "REG", "reg1B450"}, + {0x1B45C, 0xC, "REG", "reg1B45C"}, + {0x1B584, 0x8, "REG", "reg1B584"}, + {0x1B68C, 0x4, "REG", "reg1B68C"}, + {0x1B6AC, 0x4, "REG", "reg1B6AC"}, + {0x1B7F0, 0x8, "REG", "reg1B7F0"}, + {0x1C800, 0x400, "REG", "reg1C800"}, + {0x1CE00, 0x4, "REG", "reg1CE00"}, + {0x1CF80, 0x4, "REG", "reg1CF80"}, + {0x1D200, 0x600, "REG", "reg1D200"}, + {0x1E000, 0x2014, "REG", "reg1E000"}, + {0x20100, 0x24, "REG", "reg20100"}, + {0x21400, 0x3A8, "REG", "reg21400"}, + {0x21800, 0x3A8, "REG", "reg21800"}, + {0x21C00, 0x3A8, "REG", "reg21C00"}, + {0x22000, 0x3A8, "REG", "reg22000"}, + {0x22400, 0x3A8, "REG", "reg22400"}, + {0x22800, 0x3A8, "REG", "reg22800"}, + {0x22C00, 0x3A8, "REG", "reg22C00"}, + {0x23000, 0x3A8, "REG", "reg23000"}, + {0x24000, 0x34, "REG", "reg24000"}, + {0x26000, 0x64, "REG", "reg26000"}, + {0x27000, 0x24, "REG", "reg27000"}, + {0x34000, 0xC, "REG", "reg34000"}, + {0x34400, 0x5C, "REG", "reg34400"}, + {0x34800, 0x5C, "REG", "reg34800"}, + {0x34C00, 0x5C, "REG", "reg34C00"}, + {0x35000, 0x5C, "REG", "reg35000"}, + {0x35400, 0x5C, "REG", "reg35400"}, + {0x35800, 0x5C, "REG", "reg35800"}, + {0x35C00, 0x5C, "REG", "reg35C00"}, + {0x36000, 0x5C, "REG", "reg36000"}, + {0x38000, 0x64, "REG", "reg38000"}, + {0x38070, 0x70, "REG", "reg38070"}, + {0x3A000, 0x74, "REG", "reg3A000"}, + {0x40000, 0xA4, "REG", "reg40000"}, + {0x80000, 0xC, "REG", "reg80000"}, + {0x80010, 0x10, "REG", "reg80010"}, + {0, 0, 0, 0} +}; + +#define INVALID_TARGET_INDEX 0xffff +#define MIN_TARGET_INDEX 0 +#define MAX_TARGET_INDEX 4 + +struct ath_target_info { + const char *name; + const struct ath_target_reg_info *reg_info; +}; + +static const struct ath_target_info target_info[] = { + {"AR9888_v2", reg_ar9888_v2}, + {"AR6320_v1", reg_ar6320_v1}, + {"AR6320_v2", reg_ar6320_v2}, + {"AR6320_v3", reg_ar6320_v3}, +}; + + + +unsigned int flag; +const char *progname; +const char commands[] = +"commands and options:\n\ +--get --address=\n\ +--set --address= --[value|param]=\n\ + --or=\n\ + --and=\n\ +--read --address= --length= --file=\n\ +--write --address= --file=\n\ + --[value|param]=\n\ +--otp --read --address= --length= --file=\n\ +--otp --write --address= --file=\n\ +--dump --target= [--hex] [--path=]\n\ +--quiet\n\ +--device= (if not default)\n\ +The options can also be given in the abbreviated form --option=x or -o x.\n\ +The options can be given in any order."; + +#define A_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) + +#define quiet() (flag & QUIET_FLAG) +#define nqprintf(args...) if (!quiet()) {printf(args);} +#define min(x,y) ((x) < (y) ? (x) : (y)) + +void ReadTargetRange(int dev, A_UINT32 address, A_UINT8 *buffer, + A_UINT32 length); +void ReadTargetWord(int dev, A_UINT32 address, A_UINT32 *buffer); +void WriteTargetRange(int dev, A_UINT32 address, A_UINT8 *buffer, + A_UINT32 length); +void WriteTargetWord(int dev, A_UINT32 address, A_UINT32 value); +int ValidWriteOTP(int dev, A_UINT32 address, A_UINT8 *buffer, A_UINT32 length); + +static inline void * +MALLOC(int nbytes) +{ + void *p= malloc(nbytes); + + if (!p) + { + fprintf(stderr, "err -Cannot allocate memory\n"); + } + + return p; +} + +void +usage(void) +{ + fprintf(stderr, "usage:\n%s ", progname); + fprintf(stderr, "%s\n", commands); + exit(-1); +} + +void +list_supported_target_names() +{ + int i, target_num = sizeof(target_info)/sizeof(target_info[0]); + + fprintf(stderr, "supported target parameter as follow:\n"); + for (i = 0; i < target_num; i++) { + fprintf(stderr, "\t--target=%s\n", target_info[i].name); + } +} + +void +ReadTargetRange(int dev, A_UINT32 address, A_UINT8 *buffer, A_UINT32 length) +{ + int nbyte; + unsigned int remaining; + + (void)lseek(dev, address, SEEK_SET); + + remaining = length; + while (remaining) { + nbyte = read(dev, buffer, (size_t)remaining); + if (nbyte <= 0) { + fprintf(stderr, "err %s failed (nbyte=%d, address=0x%x" + " remaining=%d).\n", + __FUNCTION__, nbyte, address, remaining); + exit(1); + } + + remaining -= nbyte; + buffer += nbyte; + address += nbyte; + } +} + +void +ReadTargetWord(int dev, A_UINT32 address, A_UINT32 *buffer) +{ + ReadTargetRange(dev, address, (A_UINT8 *)buffer, sizeof(*buffer)); +} + +void +ReadTargetOTP(int dev, A_UINT32 offset, A_UINT8 *buffer, A_UINT32 length) +{ + A_UINT32 status_mask; + A_UINT32 otp_status, i; + + /* Enable OTP reads */ + WriteTargetWord(dev, RTC_SOC_BASE_ADDRESS+OTP_OFFSET, OTP_VDD12_EN_SET(1)); + status_mask = OTP_STATUS_VDD12_EN_READY_SET(1); + do { + ReadTargetWord(dev, RTC_SOC_BASE_ADDRESS+OTP_STATUS_OFFSET, + &otp_status); + } while ((otp_status & OTP_STATUS_VDD12_EN_READY_MASK) != status_mask); + + /* Conservatively set OTP read timing */ + WriteTargetWord(dev, EFUSE_BASE_ADDRESS+RD_STROBE_PW_REG_OFFSET, 6); + + /* Read data from OTP */ + for (i=0; iINvalid; 1-->valid + */ +int +ValidWriteOTP(int dev, A_UINT32 offset, A_UINT8 *buffer, A_UINT32 length) +{ + A_UINT32 i; + A_UINT8 *otp_contents; + + otp_contents = MALLOC(length); + if (otp_contents == NULL) + return 0; + ReadTargetOTP(dev, offset, otp_contents, length); + + for (i=0; i= MAX_TARGET_INDEX) + return; + + buffer = (A_UINT8 *)MALLOC(MAX_BUF); + if (buffer == NULL) + return; + + reg_info = target_info[target_idx].reg_info; + while ((reg_info->reg_start != 0) || (reg_info->reg_len != 0)) { + memset(filename, 0, sizeof(filename)); + snprintf(filename, sizeof(filename), "%s%s", pathname, + reg_info->save_file); + snprintf(tempfn, sizeof(tempfn), "%s", filename); + if(flag & HEX_FLAG) { + snprintf(filename, sizeof(filename), "%s.txt", tempfn); + } else { + snprintf(filename, sizeof(filename), "%s.bin", tempfn); + } + + if ((dump_fd = fopen(filename, "wb+")) == NULL) { + fprintf(stderr, "err %s cannot create/open output file (%s)\n", + __FUNCTION__, filename); + reg_info++; + continue; + } + + remaining = length = reg_info->reg_len; + address = reg_info->reg_start; + if(flag & HEX_FLAG) { + fprintf(dump_fd,"target mem dump area[0x%08x - 0x%08x]",address, + address+length); + } + + nqprintf("DIAG Read Target (address: 0x%x, length: 0x%x, filename: %s)\n", + address, length, filename); + + while (remaining) { + length = (remaining > MAX_BUF) ? MAX_BUF : remaining; + ReadTargetRange(dev, address, buffer, length); + if(flag & HEX_FLAG) { + for(i=0; i 15) { + /* auto-detect possibly successful */ + devicename[nbytes-1]='\0'; /* replace \n with 0 */ + } else { + snprintf(devicename, sizeof(devicename), "%s", + "unknown_DIAG_device"); + } + } + } + + dev = open(devicename, O_RDWR); + if (dev >= 0) { + break; /* successfully opened diag special file */ + } else { + fprintf(stderr, "err %s failed (%d) to open DIAG file (%s)\n", + __FUNCTION__, errno, devicename); + exit(1); + } + } + + switch(cmd) + { + case DIAG_READ_TARGET: + if ((flag & (ADDRESS_FLAG | LENGTH_FLAG | FILE_FLAG)) == + (ADDRESS_FLAG | LENGTH_FLAG | FILE_FLAG)) + { + if ((dump_fd = fopen(filename, "wb+")) == NULL) + { + fprintf(stderr, "err %s cannot create/open output file (%s)\n", + __FUNCTION__, filename); + exit(1); + } + + buffer = (A_UINT8 *)MALLOC(MAX_BUF); + if (buffer == NULL) { + fclose(dump_fd); + close(dev); + exit(1); + } + nqprintf( + "DIAG Read Target (address: 0x%x, length: %d," + " filename: %s)\n", address, length, filename); + { + unsigned int remaining = length; + + if(flag & HEX_FLAG) + { + if (flag & OTP_FLAG) { + fprintf(dump_fd,"target otp dump area" + " [0x%08x - 0x%08x]",address,address+length); + } else { + fprintf(dump_fd,"target mem dump area" + " [0x%08x - 0x%08x]",address,address+length); + } + } + while (remaining) + { + length = (remaining > MAX_BUF) ? MAX_BUF : remaining; + if (flag & OTP_FLAG) { + ReadTargetOTP(dev, address, buffer, length); + } else { + ReadTargetRange(dev, address, buffer, length); + } + if(flag & HEX_FLAG) + { + for(i=0;i<(int)length;i+=4) + { + if(i%16 == 0) + fprintf(dump_fd,"\n0x%08x:\t",address+i); + fprintf(dump_fd,"0x%08x\t",*(A_UINT32*)(buffer+i)); + } + } + else + { + fwrite(buffer,1 , length, dump_fd); + } + remaining -= length; + address += length; + } + } + fclose(dump_fd); + free(buffer); + } else { + usage(); + } + break; + + case DIAG_WRITE_TARGET: + if (!(flag & ADDRESS_FLAG)) + { + usage(); /* no address specified */ + } + if (!(flag & (FILE_FLAG | PARAM_FLAG))) + { + usage(); /* no data specified */ + } + if ((flag & FILE_FLAG) && (flag & PARAM_FLAG)) + { + usage(); /* too much data specified */ + } + + if (flag & FILE_FLAG) + { + struct stat filestat; + unsigned int file_length; + + if ((fd = open(filename, O_RDONLY)) < 0) + { + fprintf(stderr, "err %s Could not open file" + " (%s)\n", __FUNCTION__, filename); + exit(1); + } + memset(&filestat, '\0', sizeof(struct stat)); + buffer = (A_UINT8 *)MALLOC(MAX_BUF); + if (buffer == NULL) { + close(fd); + exit(1); + } + fstat(fd, &filestat); + file_length = filestat.st_size; + if (file_length == 0) { + fprintf(stderr, "err %s Zero length input file" + " (%s)\n", __FUNCTION__, filename); + exit(1); + } + + if (flag & LENGTH_FLAG) { + if (length > file_length) { + fprintf(stderr, "err %s file %s: length (%d)" + " too short (%d)\n", __FUNCTION__, + filename, file_length, length); + exit(1); + } + } else { + length = file_length; + } + + nqprintf( + "DIAG Write Target (address: 0x%x, filename: %s," + " length: %d)\n", address, filename, length); + + } + else + { /* PARAM_FLAG */ + nqprintf( + "DIAG Write Word (address: 0x%x, value: 0x%x)\n", + address, param); + length = sizeof(param); + buffer = (A_UINT8 *)¶m; + fd = -1; + } + + /* + * Write length bytes of data to memory/OTP. + * Data is either present in buffer OR + * needs to be read from fd in MAX_BUF chunks. + * + * Within the kernel, the implementation of + * DIAG_WRITE_TARGET further limits the size + * of each transfer over the interconnect. + */ + { + unsigned int remaining; + unsigned int otp_check_address = address; + + if (flag & OTP_FLAG) { + /* Validate OTP write before committing anything */ + remaining = length; + while (remaining) + { + int nbyte; + + length = (remaining > MAX_BUF) ? MAX_BUF : remaining; + if (fd > 0) + { + nbyte = read(fd, buffer, length); + if (nbyte != (int)length) { + fprintf(stderr, "err %s read from file failed" + " (%d)\n", __FUNCTION__, nbyte); + exit(1); + } + } + + if ((flag & OTP_FLAG) && !ValidWriteOTP(dev, + otp_check_address, buffer, length)) + { + exit(1); + } + + remaining -= length; + otp_check_address += length; + } + (void)lseek(fd, 0, SEEK_SET); + } + + remaining = length; + while (remaining) + { + int nbyte; + + length = (remaining > MAX_BUF) ? MAX_BUF : remaining; + if (fd > 0) + { + nbyte = read(fd, buffer, length); + if (nbyte != (int)length) { + fprintf(stderr, "err %s read from file failed" + " (%d)\n", __FUNCTION__, nbyte); + exit(1); + } + } + + if (flag & OTP_FLAG) { + WriteTargetOTP(dev, address, buffer, length); + } else { + WriteTargetRange(dev, address, buffer, length); + } + + remaining -= length; + address += length; + } + } + + if (flag & FILE_FLAG) { + free(buffer); + close(fd); + } + + break; + + case DIAG_READ_WORD: + if ((flag & (ADDRESS_FLAG)) == (ADDRESS_FLAG)) + { + nqprintf("DIAG Read Word (address: 0x%x)\n", address); + ReadTargetWord(dev, address, ¶m); + + if (quiet()) { + printf("0x%x\n", param); + } else { + printf("Value in target at 0x%x: 0x%x (%d)\n", + address, param, param); + } + } + else usage(); + break; + + case DIAG_WRITE_WORD: + if ((flag & (ADDRESS_FLAG | PARAM_FLAG)) == (ADDRESS_FLAG | PARAM_FLAG)) + { + A_UINT32 origvalue = 0; + + if (flag & BITWISE_OP_FLAG) { + /* first read */ + ReadTargetWord(dev, address, &origvalue); + param = origvalue; + + /* now modify */ + if (flag & AND_OP_FLAG) { + param &= bitwise_mask; + } else { + param |= bitwise_mask; + } + /* fall through to write out the parameter */ + } + + if (flag & BITWISE_OP_FLAG) { + if (quiet()) { + printf("0x%x\n", origvalue); + } else { + printf("DIAG Bit-Wise (%s) modify Word (address: 0x%x," + " orig:0x%x, new: 0x%x, mask:0x%X)\n", + (flag & AND_OP_FLAG) ? "AND" : "OR", address, + origvalue, param, bitwise_mask ); + } + } else{ + nqprintf("DIAG Write Word (address: 0x%x, param:" + " 0x%x)\n", address, param); + } + + WriteTargetWord(dev, address, param); + } + else usage(); + break; + + case DIAG_DUMP_TARGET: + if (!(flag & TARGET_FLAG)) { + list_supported_target_names(); + usage(); /* no target specified */ + } + + if (!(flag & PATH_FLAG)) { + memset(pathname, '\0', sizeof(filename)); + if (getcwd(pathname, sizeof(pathname)-1) != NULL) + printf("%s\n",pathname); + snprintf(tempfn, sizeof(tempfn), "%s", pathname); + snprintf(pathname, sizeof(pathname), "%s/", tempfn); + } + + DumpTargetMem(dev, target_idx, pathname); + break; + + default: + usage(); + } + + exit (0); +} diff --git a/drivers/staging/qcacld-2.0/tools/configure.ac b/drivers/staging/qcacld-2.0/tools/configure.ac new file mode 100644 index 0000000000000..8508cd9e69d6d --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/configure.ac @@ -0,0 +1,68 @@ +# -*- Autoconf -*- + +# configure.ac -- Autoconf script for qcacld-tools +# + +# Process this file with autoconf to produce a configure script + +# Requires autoconf tool later than 2.61 +AC_PREREQ(2.61) +# Initialize the qcacld-tools package version 1.0.0 +AC_INIT([qcacld-tools],1.0.0) +# Does not strictly follow GNU Coding standards +AM_INIT_AUTOMAKE([foreign]) +# Disables auto rebuilding of configure, Makefile.ins +AM_MAINTAINER_MODE +# defines some macros variable to be included by source +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_LIBTOOL +AC_PROG_AWK +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + +# Checks for libraries. +PKG_CHECK_MODULES([DIAG], [diag]) +AC_SUBST([DIAG_CFLAGS]) +AC_SUBST([DIAG_LIBS]) + +AC_ARG_ENABLE([debug], + [ --enable-debug Turn on debugging], + [case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; + esac],[debug=false]) +AM_CONDITIONAL([DEBUG], [test x$debug = xtrue]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_HEADER_STDC +AC_C_INLINE +AC_TYPE_INT64_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +AC_FUNC_MALLOC + +AC_CONFIG_FILES([ \ + Makefile \ + fwdebuglog/Makefile \ + athdiag/Makefile \ + pktlog/Makefile \ + ]) +AC_OUTPUT + diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/Android.mk b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Android.mk new file mode 100644 index 0000000000000..ff8560d8dc0a5 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Android.mk @@ -0,0 +1,45 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := cld-fwlog-record +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_SHARED_LIBRARIES := libc libcutils +LOCAL_SRC_FILES := cld-fwlog-record.c +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_MODULE := cld-fwlog-netlink +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/diag/include \ +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc \ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../wlan/utils/asf/inc \ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_SHARED_LIBRARIES := libc libcutils libdiag libhardware_legacy +LOCAL_SRC_FILES := cld-fwlog-netlink.c parser.c nan-parser.c cld-diag-parser.c +LOCAL_CFLAGS += -DCONFIG_ANDROID_LOG +LOCAL_CFLAGS += -DANDROID +LOCAL_LDLIBS += -llog +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_MODULE := cnss_diag +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/diag/include \ +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc \ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../wlan/utils/asf/inc \ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_SHARED_LIBRARIES := libc libcutils libdiag libhardware_legacy +LOCAL_SRC_FILES := cld-fwlog-netlink.c parser.c nan-parser.c cld-diag-parser.c +LOCAL_CFLAGS += -DCONFIG_ANDROID_LOG +LOCAL_CFLAGS += -DANDROID +LOCAL_LDLIBS += -llog +include $(BUILD_EXECUTABLE) + + +include $(CLEAR_VARS) +LOCAL_MODULE := cld-fwlog-parser +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_SHARED_LIBRARIES := libc libcutils +LOCAL_SRC_FILES := cld-fwlog-parser.c +include $(BUILD_EXECUTABLE) diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile new file mode 100644 index 0000000000000..ac1c922e18364 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile @@ -0,0 +1,21 @@ +CC := $(ATH_CROSS_COMPILE_TYPE)gcc +TARGET_TYPE ?= AR9888 +TARGET_VERS ?= v2 + +all: + $(CC) -g3 -Wall \ + -I ../../CORE/SERVICES/COMMON/ \ + -I ../../CORE/SERVICES/HIF/ \ + cld-fwlog-record.c -o cld-fwlog-record + $(CC) -g3 -Wall \ + -I ../../CORE/SERVICES/COMMON/ \ + -I ../../CORE/SERVICES/HIF/ \ + cld-fwlog-netlink.c parser.c nan-parser.c -o cld-fwlog-netlink + $(CC) -g3 -Wall \ + -I ../../CORE/SERVICES/COMMON/ \ + -I ../../CORE/SERVICES/HIF/ \ + cld-fwlog-parser.c -o cld-fwlog-parser +clean: + rm -f cld-fwlog-record + rm -f cld-fwlog-parser + rm -f cld-fwlog-netlink diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile.am b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile.am new file mode 100644 index 0000000000000..fd885c289c8ef --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/Makefile.am @@ -0,0 +1,21 @@ +AM_CFLAGS = -Wall \ + $(DIAG_CFLAGS) + +if DEBUG +AM_CFLAGS += -g +else +AM_CFLAGS += -O2 +endif + +AM_CFLAGS += -I $(top_srcdir)/../CORE/SERVICES/COMMON/ + +cld_fwlog_record_SOURCES = cld-fwlog-record.c + +cnss_diag_SOURCES = cld-fwlog-netlink.c parser.c +cnss_diag_LDADD = $(DIAG_LIBS) + +cld_fwlog_parser_SOURCES = cld-fwlog-parser.c + +bin_PROGRAMS = cld_fwlog_record +bin_PROGRAMS += cnss_diag +bin_PROGRAMS += cld_fwlog_parser diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.c new file mode 100644 index 0000000000000..944293b395930 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.c @@ -0,0 +1,1211 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cld-diag-parser.h" + +typedef struct diag_entry{ + uint32_t id; + boolean isUsed; + + /* database - userspace */ + char *format; + char *pack; + + /* runtime message - generated by target */ + char *msg; + uint32_t msg_len; +}diag_entry; + +typedef struct file_header { + int32_t file_version; + int32_t n_entries; + int32_t n_usedEntries; + int32_t hash; +}file_header; + +static diag_entry *gdiag_db = NULL; +static file_header *gdiag_header = NULL; +static int32_t gisdiag_init = FALSE; +static int gdiag_sock_fd = 0, goptionflag = 0; +#ifdef CONFIG_ANDROID_LOG +#define debug_printf(...) do { \ + if (goptionflag & DEBUG_FLAG) \ + __android_log_print(ANDROID_LOG_INFO, FWDEBUG_NAME, __VA_ARGS__); \ +} while(0) +#endif + +/* + * macros to safely extract 8, 16, 32, or 64-bit values from byte buffer + */ +#define GET_8(v, msg, msg_len) do { \ + if (msg_len < sizeof(uint8_t)) { \ + goto msg_error; \ + } \ + v = *msg; \ + msg += sizeof(uint8_t); \ + msg_len -= sizeof(uint8_t); \ +} while (0) + +#define _GET_LE16(a) ( \ + (((uint16_t)(a)[1]) << 8) | \ + ((uint16_t)(a)[0])) +#define GET_LE16(v, msg, msg_len) do { \ + if (msg_len < sizeof(uint16_t)) { \ + goto msg_error; \ + } \ + v = _GET_LE16(msg); \ + msg += sizeof(uint16_t); \ + msg_len -= sizeof(uint16_t); \ +} while (0) + +#define _GET_LE32(a) ( \ + (((uint32_t)(a)[3]) << 24) | \ + (((uint32_t)(a)[2]) << 16) | \ + (((uint32_t)(a)[1]) << 8) | \ + ((uint32_t)(a)[0])) +#define GET_LE32(v, msg, msg_len) do { \ + if (msg_len < sizeof(uint32_t)) { \ + goto msg_error; \ + } \ + v = _GET_LE32(msg); \ + msg += sizeof(uint32_t); \ + msg_len -= sizeof(uint32_t); \ +} while (0) + +#define _GET_LE64(a) ( \ + (((uint64_t)(a)[7]) << 56) | \ + (((uint64_t)(a)[6]) << 48) | \ + (((uint64_t)(a)[5]) << 40) | \ + (((uint64_t)(a)[4]) << 32) | \ + (((uint64_t)(a)[3]) << 24) | \ + (((uint64_t)(a)[2]) << 16) | \ + (((uint64_t)(a)[1]) << 8) | \ + ((uint64_t)(a)[0])) +#define GET_LE64(v, msg, msg_len) do { \ + if (msg_len < sizeof(uint64_t)) { \ + goto msg_error; \ + } \ + v = _GET_LE64(msg); \ + msg += sizeof(uint64_t); \ + msg_len -= sizeof(uint64_t); \ +} while (0) + +/* + * pack_printf derived from Rome FW's cmnos_vprintf + * + */ + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +static int _cvt(uint64_t val, char *buf, long radix, char *digits) +{ + char temp[80]; + char *cp = temp; + int32_t length = 0; + + if (val == 0) { + /* Special case */ + *cp++ = '0'; + } else { + while (val) { + *cp++ = digits[val % (int)radix]; + val /= (int)radix; + } + } + while (cp != temp) { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); +} + +/* Return successive characters in a format string. */ +char fmt_next_char(const char **fmtptr) +{ + char ch; + + ch = **fmtptr; + + if (ch != '\0') { + (*fmtptr)++; + } + + return ch; +} + +static int +pack_printf( + void (*putc)(char **pbs, char *be, char c), + char **pbuf_start, + char *buf_end, + const char *fmt, + const char *pack, + uint8_t *msg, + uint32_t msg_len) +{ + char buf[sizeof(long long)*8]; + char c, sign, *cp=buf; + int32_t left_prec, right_prec, zero_fill, pad, pad_on_right, + i, islong, islonglong; + long long val = 0; + int32_t res = 0, length = 0; + + while ((c = fmt_next_char(&fmt)) != '\0') { + if (c == '%') { + c = fmt_next_char(&fmt); + left_prec = right_prec = pad_on_right = islong = islonglong = 0; + if (c == '-') { + c = fmt_next_char(&fmt); + pad_on_right++; + } + if (c == '0') { + zero_fill = 1; + c = fmt_next_char(&fmt); + } else { + zero_fill = 0; + } + while (is_digit(c)) { + left_prec = (left_prec * 10) + (c - '0'); + c = fmt_next_char(&fmt); + } + if (c == '.') { + c = fmt_next_char(&fmt); + zero_fill++; + while (is_digit(c)) { + right_prec = (right_prec * 10) + (c - '0'); + c = fmt_next_char(&fmt); + } + } else { + right_prec = left_prec; + } + sign = '\0'; + if (c == 'l') { + /* 'long' qualifier */ + c = fmt_next_char(&fmt); + islong = 1; + if (c == 'l') { + /* long long qualifier */ + c = fmt_next_char(&fmt); + islonglong = 1; + } + } + /* Fetch value [numeric descriptors only] */ + switch (c) { + case 'p': + islong = 1; + case 'd': + case 'D': + case 'x': + case 'X': + case 'u': + case 'U': + case 'b': + case 'B': + switch (fmt_next_char(&pack)) { + case 'b': + GET_8(val, msg, msg_len); + break; + case 'h': + GET_LE16(val, msg, msg_len); + break; + case 'i': + case 'I': + GET_LE32(val, msg, msg_len); + break; + case 'q': + GET_LE64(val, msg, msg_len); + break; + default: + c = 0; + break; + } + if ((c == 'd') || (c == 'D')) { + if (val < 0) { + sign = '-'; + val = -val; + } + } else { + /* Mask to unsigned, sized quantity */ + if (!islonglong) { + if (islong) { + val &= ((long long)1 << (sizeof(long) * 8)) - 1; + } else{ + val &= ((long long)1 << (sizeof(int) * 8)) - 1; + } + } + } + break; + default: + break; + } + /* Process output */ + switch (c) { + case 'p': /* Pointer */ + (*putc)(pbuf_start, buf_end,'0'); + (*putc)(pbuf_start, buf_end,'x'); + zero_fill = 1; + left_prec = sizeof(unsigned long)*2; + case 'd': + case 'D': + case 'u': + case 'U': + case 'x': + case 'X': + switch (c) { + case 'd': + case 'D': + case 'u': + case 'U': + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'p': + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; + } + cp = buf; + break; + case 's': + case 'S': + cp = NULL; /* TODO string literals not supported yet */ + if (cp == NULL) { + cp = ""; + } + length = 0; + while (cp[length] != '\0') length++; + break; + case 'c': + case 'C': + switch (fmt_next_char(&pack)) { + case 'b': + GET_8(c, msg, msg_len); + break; + case 'h': + GET_LE16(c, msg, msg_len); + break; + case 'i': + case 'I': + GET_LE32(c, msg, msg_len); + break; + case 'q': + GET_LE64(c, msg, msg_len); + break; + default: + c = 0; + break; + } + (*putc)(pbuf_start, buf_end,c); + res++; + continue; + case 'b': + case 'B': + length = left_prec; + if (left_prec == 0) { + if (islonglong) + length = sizeof(long long)*8; + else if (islong) + length = sizeof(long)*8; + else + length = sizeof(uint32_t)*8; + } + for (i = 0; i < length-1; i++) { + buf[i] = ((val & ((long long)1< 0) { + (*putc)(pbuf_start, buf_end,c); + res++; + } + } + if (sign != '\0') { + (*putc)(pbuf_start, buf_end,sign); + res++; + } + while (length-- > 0) { + c = *cp++; + (*putc)(pbuf_start, buf_end,c); + res++; + } + if (pad_on_right) { + while (pad-- > 0) { + (*putc)(pbuf_start, buf_end,' '); + res++; + } + } + } else { + (*putc)(pbuf_start, buf_end,c); + res++; + } + } + (*putc)(pbuf_start, buf_end, '\0'); +msg_error: + return (res); +} + +static void +format_pack( const char *pack, char *buf, uint32_t buflen) +{ + char c; + uint32_t num = 0, index = 0, i = 0; + boolean isfound = 0; + memset(buf, 0 , buflen); + while ((c = fmt_next_char(&pack)) != '\0') { + if (index >= buflen -1) + break; + while (is_digit(c)) { + num = (i++ * 10) + (c - '0'); + c = fmt_next_char(&pack); + isfound = TRUE; + } + if (isfound) { + while (num--) { + buf[index++] = c; + if (index >= buflen -1) + break; + } + num = 0; + i = 0; + } + else + buf[index++] = c; + } + buf[index] = '\0'; +} + +static int +diag_printf(const char *buf, uint16_t vdevid, uint16_t level, + uint32_t optionflag, uint32_t timestamp, FILE *log_out) +{ + char pbuf[512]; + if (vdevid < DBGLOG_MAX_VDEVID) + snprintf(pbuf, 512, "FWMSG: [%u] vap-%u %s", timestamp, vdevid, buf); + else + snprintf(pbuf, 512, "FWMSG: [%u] %s", timestamp, buf); + + if (optionflag & QXDM_FLAG) { + switch(level) { + case DBGLOG_VERBOSE: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_LOW, "%s", pbuf); + break; + case DBGLOG_INFO: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_MED , "%s", pbuf); + break; + case DBGLOG_INFO_LVL_1: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_MED , "%s", pbuf); + break; + case DBGLOG_INFO_LVL_2: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_MED , "%s", pbuf); + break; + case DBGLOG_WARN: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_HIGH, "%s", pbuf); + break; + case DBGLOG_ERR: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_HIGH, "%s", pbuf); + break; + case DBGLOG_LVL_MAX: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_FATAL, "%s", pbuf); + break; + default: + MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_FATAL, "%s", pbuf); + break; + } + } else if (optionflag & CONSOLE_FLAG) { + android_printf("%s\n", pbuf); + } + else if (optionflag & LOGFILE_FLAG) { + if (log_out) + return fprintf(log_out, "%s\n", pbuf); + } + return 0; +} + +/* + * database initialization + */ +static void +diag_create_db(uint32_t n_entries) +{ + gdiag_header = calloc(1, sizeof(*gdiag_header)); + if (!gdiag_header) + return; + gdiag_header->n_entries = n_entries; + gdiag_db = calloc(gdiag_header->n_entries, sizeof(*gdiag_db)); + if (!gdiag_db) + return; + /* hash */ + gdiag_header->hash = (gdiag_header->n_entries % 2 == 0) ? \ + gdiag_header->n_entries / 2 : \ + (gdiag_header->n_entries + 1) / 2; +} + +/* + * database free + */ +static void +diag_free_db() +{ + int32_t count = 0; + if (gdiag_db && gdiag_header) { + for (count = 0; count < gdiag_header->n_entries; count++) { + if (gdiag_db[count].isUsed){ + if (gdiag_db[count].format) + free(gdiag_db[count].format); + if (gdiag_db[count].pack) + free(gdiag_db[count].pack); + } + } + } + if (gdiag_db) + free(gdiag_db); + gdiag_db = NULL; + if (gdiag_header) + free(gdiag_header); + gdiag_header = NULL; + gisdiag_init = FALSE; +} + +/* + * insert into database + */ +static int32_t +diag_insert_db(char *format, char *pack, int32_t id) +{ + /* Double Hashing */ + int32_t i = id % gdiag_header->n_entries; + int32_t j = gdiag_header->hash - (id % gdiag_header->hash); + if (gdiag_header->n_entries == gdiag_header->n_usedEntries) { + debug_printf("db is full"); + return 0; + } + /* search */ + while (gdiag_db[i].isUsed) { + i = (i + j)%gdiag_header->n_entries; + } + + gdiag_db[i].id = id; + gdiag_db[i].format = format; + gdiag_db[i].pack = pack; + gdiag_db[i].isUsed = TRUE; + gdiag_header->n_usedEntries++; + return 1; +} + +/* + * parser looks up entry at runtime based on 'id' extracted from FW + * message + */ +static diag_entry* +diag_find_by_id( uint32_t id) +{ + boolean isfound = FALSE; + int32_t count = 0; + int32_t i = id % gdiag_header->n_entries; + int32_t j = gdiag_header->hash - (id % gdiag_header->hash); + if (gdiag_header->n_usedEntries == 0) { + return NULL; + } + while (gdiag_db[i].isUsed != 0 && count <= gdiag_header->n_entries) { + if (gdiag_db[i].id == id) { + isfound = TRUE; + break; + } + i = (i + j) % gdiag_header->n_entries; + count++; + } + if (!isfound) { + debug_printf("Not found in data base\n"); + return NULL; + } + return &gdiag_db[i]; +} + +/* user supply their own function to build string in temporary + * buffer + */ +static void dbg_write_char(char **pbuf_start, char *buf_end, char c) +{ + if ( *pbuf_start < buf_end) { + *(*pbuf_start) = c; + ++(*pbuf_start); + } +} + +static uint32_t +get_numberofentries() +{ + FILE* fd; + char line[1024]; + int32_t n_entries = 0, i = 0; + boolean isfound = FALSE; + if ((fd = fopen(DB_FILE_PATH, "r")) == NULL) { + diag_printf("[Error] : While opening the file\n", + 0, 4, goptionflag, 0, NULL); + return 0; + } + while ( fgets (line, sizeof(line), fd) != NULL ) { + n_entries++; + } + /* Decrement 1 for version and the last line /r/n */ + n_entries-= 2; + + /* check if n_entries is prime number else change to prime number */ + while (1) { + for (i = 2; i 2) + break; + isfound = FALSE; + /* Increment n_entries and check is it prime number */ + n_entries++; + } + fclose(fd); + debug_printf( "Number of entries is %d\n", n_entries); + return n_entries; +} + +static uint32_t +parse_dbfile() +{ + FILE* fd; + uint32_t n_entries = 0; + uint32_t id = 0; + char line[1024], *p = NULL, *pack = NULL, *format = NULL; + char pbuf[128], *q = NULL; + char *save; + n_entries = get_numberofentries( ); + diag_create_db(n_entries ); + n_entries = 0; + /*Open the data.msc file*/ + if ((fd = fopen(DB_FILE_PATH , "r")) == NULL) { + diag_printf("[Error] : While opening the file\n", + 0, 4, goptionflag, 0, NULL); + return 0; + } + memset(line, 0 , sizeof(line)); + while ( fgets (line, sizeof(line), fd) != NULL ) { + n_entries++; + if (n_entries == 1) { + /* Parse for the version */ + p = strstr(line, "VERSION:"); + if (p) { + p += strlen("VERSION:"); + gdiag_header->file_version = atoi(p); + } + else { + fclose(fd); + return 0; + } + } + else { + p = strtok_r(line, ",", &save); + if (p) + id = atoi(p); + else + continue; + + p = strtok_r(NULL, ",", &save); + if (p) + pack = strdup(p); + else + continue; + + p = strtok_r(NULL, "\r", &save); + if (p) { + format = strdup(p); + if (format) { + /* Check for CR */ + p = strstr(format, "\r"); + if (p) + *p = '\0'; + else { + p = strstr(format, "\n"); + if (p) + *p = '\0'; + } + } + } + else { + /* Else CASE for pack specifier is 0 */ + if (pack) { + /* Check for CR */ + p = strstr(pack, "\r"); + if (p) + *p = '\0'; + else { + p = strstr(pack, "\n"); + if (p) + *p = '\0'; + } + format = pack; + pack = NULL; + } + } + /* Go through the pack specifier, to find pack with number */ + if (pack) { + q = pack; + format_pack(pack, pbuf, sizeof(pbuf)); + pack = strdup(pbuf); + free(q); + } + if (!diag_insert_db(format, pack, id)) { + fclose(fd); + return 0; + } + } + memset(line, 0 , sizeof(line)); + } + fclose(fd); + return n_entries; +} + +int +cnssdiag_register_kernel_logging(int sock_fd, struct nlmsghdr *nlh) +{ + tAniNlHdr *wnl; + tAniNlAppRegReq *regReq; + int regMsgLen = 0; + + if (!nlh) + return -1; + /* Only the msg header is being carried */ + nlh->nlmsg_len = aniNlAlign(sizeof(tAniNlHdr)); + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_HOST_MSG; + nlh->nlmsg_flags = NLM_F_REQUEST; + nlh->nlmsg_seq++; + wnl = (tAniNlHdr *)nlh; + wnl->radio = 0; + wnl->wmsg.length = sizeof(tAniHdr); + wnl->wmsg.type = ANI_NL_MSG_LOG_REG_TYPE; + if (sendto(sock_fd, (char*)wnl, nlh->nlmsg_len,0,NULL, 0) < 0) { + debug_printf("%s: HOST_MSG:Failed to send message over NL" + " errno:%d - %s\n", + __func__, errno, strerror(errno)); + return -1; + } + + regMsgLen = aniNlLen(sizeof(tAniNlAppRegReq)); + nlh->nlmsg_len = aniNlAlign(sizeof(tAniNlHdr)) + regMsgLen; + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_HOST_EVENT_LOG; + nlh->nlmsg_flags = NLM_F_REQUEST; + nlh->nlmsg_seq++; + wnl = (tAniNlHdr *)nlh; + wnl->radio = 0; + wnl->wmsg.length = regMsgLen; + wnl->wmsg.type = htons(ANI_NL_MSG_LOG_REG_TYPE); + regReq = (tAniNlAppRegReq *)(wnl + 1); + regReq->pid = getpid(); + if (sendto(sock_fd, (char*)wnl, nlh->nlmsg_len,0,NULL, 0) < 0) { + debug_printf("%s: EVENT_LOG:Failed to send message over NL" + " errno:%d - %s\n", + __func__, errno, strerror(errno)); + return -1; + } + return 0; +} + +static int32_t +sendcnss_cmd(int sock_fd, int32_t cmd, int len, uint8_t *buf) +{ + struct dbglog_slot *slot; + struct sockaddr_nl src_addr, dest_addr; + struct nlmsghdr *nlh = NULL; + struct msghdr msg; + struct iovec iov; + int32_t ret, slot_len = 0; + + slot_len = sizeof(struct dbglog_slot) + len; + char *slot_buf = NULL; + slot_buf = malloc(slot_len); + if (slot_buf == NULL) { + fprintf(stderr, "Cannot allocate slot memory \n"); + return -1; + } + slot = (struct dbglog_slot *)slot_buf; + memset(slot, 0 , sizeof(struct dbglog_slot)); + slot->diag_type = cmd; + slot->length = len; + memcpy(slot->payload, buf, len); + + memset(&dest_addr, 0, sizeof(dest_addr)); + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; /* For Linux Kernel */ + dest_addr.nl_groups = 0; /* unicast */ + + nlh = malloc(NLMSG_SPACE(slot_len)); + if (nlh == NULL) { + fprintf(stderr, "Cannot allocate memory \n"); + free(slot_buf); + return -1; + } + memset(nlh, 0, NLMSG_SPACE(slot_len)); + nlh->nlmsg_len = NLMSG_SPACE(slot_len); + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_DIAG; + nlh->nlmsg_flags = NLM_F_REQUEST; + + memcpy(NLMSG_DATA(nlh), slot_buf, slot_len); + free(slot_buf); + + memset(&msg, 0, sizeof(msg)); + iov.iov_base = (void *)nlh; + iov.iov_len = nlh->nlmsg_len; + msg.msg_name = (void *)&dest_addr; + msg.msg_namelen = sizeof(dest_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ret = sendmsg(sock_fd, &msg, 0); + free(nlh); + return ret; +} + + +void +diag_initialize(int sock_fd, uint32_t optionflag) +{ + uint32_t ret; + goptionflag = optionflag; + diag_free_db(); + ret = parse_dbfile(); + if (ret > 1) + gisdiag_init = TRUE; + gdiag_sock_fd = sock_fd; +} + +void +process_diaghost_msg(uint8_t *datap, uint16_t len) +{ + uint8_t *payload; + len; + event_report_t *pEvent_report =(event_report_t *)datap ; + if (!pEvent_report) + return; + debug_printf("\n %s diag_type = %d event_id =%d\n", + __func__, pEvent_report->diag_type, + pEvent_report->event_id); + if (pEvent_report->diag_type == DIAG_TYPE_EVENTS) { + payload = datap + sizeof(event_report_t); + wlan_bringup_t *pwlan_bringup_status = (wlan_bringup_t *)payload ; + event_report_payload(pEvent_report->event_id, + pEvent_report->length, payload); + } +} + +uint32_t +process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records, int32_t version, + int sock_fd) +{ + uint32_t count = 0, index = 0; + uint32_t timestamp = 0; + uint32_t diagid = 0, id = 0; + uint32_t moduleid = 0, res = 0; + uint32_t num_buf = 0, payloadlen = 0; + uint16_t vdevid = 0, vdevlevel = 0; + uint16_t numargs = 0; + uint32_t *buffer; + uint32_t header1 = 0, header2 = 0; + int32_t lrecord = 0; + char *payload; + char buf[BUF_SIZ], payload_buf[BUF_SIZ]; + char *start = buf; + int32_t hashInd = 0, i =0, j =0; + diag_entry *entry = NULL; + int ret = 0, total_dump_len = 0; + uint8_t *debugp = datap; + char dump_buffer[BUF_SIZ]; + + if (optionflag & DEBUG_FLAG) { + memset(dump_buffer, 0, sizeof(dump_buffer)); + debug_printf("process_diagfw_msg hex dump start len %d", len); + for (i = 0; i < len; i++) { + ret = snprintf(dump_buffer + j, BUF_SIZ - j, "0x%x ", debugp[i]); + j += ret; + if (!(i % 16) && (i!=0)) { + total_dump_len += 16; + debug_printf("%s", dump_buffer); + memset(dump_buffer, 0, sizeof(dump_buffer)); + j = 0; + } + } + if (total_dump_len != len) + debug_printf("%s", dump_buffer); + debug_printf("process_diagfw_msg hex dump end"); + } + + if (!gisdiag_init) { + /* If cnss_diag is started if WIFI already ON, + * then turn on event not received hence + * before throwing out error initialize again + */ + diag_initialize(sock_fd, optionflag); + if (!gisdiag_init) { + diag_printf("**ERROR** Diag not Initialized", + 0, 4, optionflag, 0, NULL); + return -1; + } + + } + buffer = (uint32_t *)datap ; + buffer ++; /* increment 1 to skip dropped */ + num_buf = len - 4; + debug_printf("\n --%s-- %d\n", __FUNCTION__, optionflag); + + while (num_buf > count) { + + header1 = *(buffer + index); + header2 = *(buffer + 1 + index); + payload = (char *)(buffer + 2 + index); + diagid = DIAG_GET_TYPE(header1); + timestamp = DIAG_GET_TIME_STAMP(header1); + payloadlen = 0; + debug_printf("\n diagid = %d timestamp = %d" + " header1 = %x heade2 = %x\n", + diagid, timestamp, header1, header2); + switch (diagid) { + case WLAN_DIAG_TYPE_EVENT: + { + id = DIAG_GET_ID(header2); + payloadlen = DIAG_GET_PAYLEN16(header2); + debug_printf("DIAG_TYPE_FW_EVENT: id = %d" + " payloadlen = %d \n", id, payloadlen); + if (optionflag & QXDM_FLAG) { + if (payloadlen) + event_report_payload(id, payloadlen, payload); + else + event_report(id); + } + } + break; + case WLAN_DIAG_TYPE_LOG: + { + id = DIAG_GET_ID(header2); + payloadlen = DIAG_GET_PAYLEN16(header2); + debug_printf("DIAG_TYPE_FW_LOG: id = %d" + " payloadlen = %d \n", id, payloadlen); + if (optionflag & QXDM_FLAG) { + /* Allocate a log buffer */ + uint8_t *logbuff = (uint8_t*) log_alloc(id, + sizeof(log_hdr_type)+payloadlen); + if ( logbuff != NULL ) { + /* Copy the log data */ + memcpy(logbuff + sizeof(log_hdr_type), payload, + payloadlen); + /* Commit the log buffer */ + log_commit(logbuff); + } + else + debug_printf("log_alloc failed for len = %d ", payloadlen); + } + } + break; + case WLAN_DIAG_TYPE_MSG: + { + id = DIAG_GET_ID(header2); + payloadlen = DIAG_GET_PAYLEN(header2); + vdevid = DIAG_GET_VDEVID(header2); + vdevlevel = DIAG_GET_VDEVLEVEL(header2); + memset(buf, 0, BUF_SIZ); + memset(payload_buf, 0, BUF_SIZ); + debug_printf(" DIAG_TYPE_FW_DEBUG_MSG: " + " vdevid %d vdevlevel %d payloadlen = %d id = %d\n", + vdevid, vdevlevel, payloadlen, id); + if (gdiag_header->file_version != version) { + snprintf(buf, BUF_SIZ, "**ERROR**" + " Data.msc Version %d doesn't match" + " with Firmware version %d id = %d", + gdiag_header->file_version, version, id); + diag_printf(buf, 0, 4, optionflag, 0, NULL); + break; + } + entry = diag_find_by_id(id); + if (entry) { + if ((payloadlen > 0) && (entry->format && entry->pack)) { + debug_printf("entry->format = %s pack = %s\n", + entry->format, entry->pack); + if (payloadlen < BUF_SIZ) + memcpy(payload_buf, payload, payloadlen); + else + memcpy(payload_buf, payload, BUF_SIZ); + /* Sending with BUF_SIZ to pack_printf + * because some times payloadlen received + * doesnt match with the pack specifier, in + * that case just print the zero + */ + entry->msg_len = BUF_SIZ; + entry->msg = payload_buf; + start = buf; + pack_printf( + dbg_write_char, + &start, + start + sizeof(buf), + entry->format, + entry->pack, + (uint8_t*)entry->msg, + entry->msg_len + ); + } + else if (entry->format) + strlcpy(buf, entry->format, strlen(entry->format)); + + debug_printf("\n buf = %s \n", buf); + if (optionflag & LOGFILE_FLAG) { + lrecord = *record; + lrecord++; + if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) + printf("%d: %s\n", lrecord, buf); + + res = diag_printf( + buf, vdevid, vdevlevel, optionflag, timestamp, log_out + ); + //fseek(log_out, lrecord * res, SEEK_SET); + if (lrecord == max_records) { + lrecord = 0; + fseek(log_out, lrecord * res, SEEK_SET); + } + *record = lrecord; + } + if (optionflag & (CONSOLE_FLAG | QXDM_FLAG)) + diag_printf( + buf, vdevid, vdevlevel, optionflag, timestamp, NULL + ); + } + else { + switch (id) { + case DIAG_WLAN_MODULE_STA_PWRSAVE: + case DIAG_WLAN_MODULE_WAL: + case DIAG_NAN_MODULE_ID: + case DIAG_WLAN_MODULE_IBSS_PWRSAVE: + if (!diag_msg_handler(id, payload, vdevid, timestamp)) { + snprintf(buf, BUF_SIZ, + "****WARNING****, undefined moduleid = %d no t" + " found", moduleid); + diag_printf(buf, 0, 4, optionflag, timestamp, NULL); + } + break; + default: + snprintf(buf, BUF_SIZ, + "****WARNING****, FWMSG ID %d not found", id); + diag_printf(buf, 0, 4, optionflag, timestamp, NULL); + printf( "NOT found id = %d\n", id); + } + } + } + break; + default: + diag_printf(" ****WARNING**** WRONG DIAG ID", 0, + 4, optionflag, timestamp, NULL); + return 0; + } + count += payloadlen + 8; + index = count >> 2; + debug_printf("Loope end:id = %d payloadlen = %d count = %d index = %d\n", + id, payloadlen, count, index); + } + + return (0); +} + +/* +WLAN trigger command from QXDM + +1) SSR + send_data 75 41 7 0 1 0 253 len id val1 val 2 + id is subsystem id value +2) log level + send_data 75 41 7 0 2 0 253 1 25 + +75 - DIAG_SUBSYS_CMD_F +41 - DIAG_SUBSYS_WLAN +0007 - CNSS_WLAN_DIAG +1 - CMD type +FC00 - VS Command OpCode + +*/ + +PACK(void *) cnss_wlan_handle(PACK(void *)req_pkt, uint16_t pkt_len) +{ + PACK(void *)rsp = NULL; + uint8_t *pkt_ptr = (uint8_t *)req_pkt + 4; + uint16_t p_len, p_opcode; + int32_t ret = 0, i = 0; + char cmd[BUF_SIZ] = {0}; + + /* Allocate the same length as the request + */ + rsp = diagpkt_subsys_alloc( DIAG_SUBSYS_WLAN, CNSS_WLAN_DIAG, pkt_len); + if (rsp != NULL && pkt_len > 3) + { + p_len = *(pkt_ptr+3); /* VS Command packet length */ + p_opcode = (*(pkt_ptr+2) << 8) | *(pkt_ptr+1); + debug_printf( + "%s : p_len: %d, pkt_len -8: %d, p_opcode:%.04x cmd = %d\n", + __func__, p_len, pkt_len -8, p_opcode, *pkt_ptr + ); + if (p_len !=(pkt_len - 8) || ( p_opcode != 0xFD00)) { + debug_printf("%s:Error in p_len or p_opcode ", __func__ ); + return rsp; + } + memcpy(rsp, req_pkt, pkt_len); + if (*pkt_ptr == CNSS_WLAN_SSR_TYPE && p_len > 1) { + /* get ID */ + i = *(pkt_ptr+4); + p_len--; + /* Restart for subsystem id */ + memset(cmd, 0x00, BUF_SIZ); + snprintf(cmd, sizeof(cmd), RESTART_LEVEL, i); + debug_printf("%s: cmd = %s\n", __func__, cmd); + if ((ret = system(cmd))){ + if (ret < 0) { + debug_printf("%s: error with subsystem id\n", __func__); + return rsp; + } + } + if (gdiag_sock_fd > 0) { + sendcnss_cmd(gdiag_sock_fd, DIAG_TYPE_CRASH_INJECT, + p_len, (pkt_ptr + 5) + ); + debug_printf("%s: Success with crash inject \n", __func__); + } + } else + debug_printf("%s:Error in Command ", __func__ ); + } + else + debug_printf("%s:Allocate response buffer error", __func__ ); + return rsp; +} + +void process_cnss_host_message(tAniNlHdr *wnl, int32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records) +{ + char *wlanLog = (char *)&wnl->wmsg.length + sizeof(wnl->wmsg.length); + char *charCache = NULL ; + if (!wlanLog) + return; + + /* Assuming every kmsg is terminated by a '\n' character,split the + * wlanLog buffer received from the driver and log individual messages + */ + while((charCache = strchr(wlanLog, '\n'))!= NULL) { + *charCache = '\0'; + if (optionflag & QXDM_FLAG) { + WLAN_LOG_TO_DIAG(MSG_SSID_WLAN_RESERVED_10, MSG_LEGACY_MED, + wlanLog); + } + else if (optionflag & LOGFILE_FLAG) { + int32_t lrecord = 0; + uint32_t res = 0; + lrecord = *record; + lrecord++; + if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) + printf("%d: %s\n", lrecord, wlanLog); + res = fprintf(log_out, "%s\n", wlanLog); + if (lrecord == max_records) { + lrecord = 0; + fseek(log_out, lrecord * res, SEEK_SET); + } + *record = lrecord; + } + else if (optionflag & CONSOLE_FLAG) { + android_printf("%s\n", wlanLog); + } + wlanLog = ++charCache; + } +} + +void process_cnss_host_diag_events_log(char *pData, int32_t optionflag) +{ + uint32_t diag_type = 0; + + if (optionflag & QXDM_FLAG) { + if (pData) { + diag_type = *(uint32_t*) pData; + pData += sizeof(uint32_t); + } + if (diag_type == DIAG_TYPE_LOGS) { + log_hdr_type *pHdr = (log_hdr_type*)pData; + if (log_status(pHdr->code)) + { + log_set_timestamp(pHdr); + log_submit(pHdr); + } + } + else if (diag_type == DIAG_TYPE_EVENTS) { + uint16_t event_id; + uint16_t length; + event_id = *(uint16_t*)pData; + pData += sizeof(uint16_t); + length = *(uint16_t*)pData; + pData += sizeof(uint16_t); + event_report_payload(event_id,length,pData); + } + } +} diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.h b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.h new file mode 100644 index 0000000000000..533b033dd83ae --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-diag-parser.h @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _CLD_DIAG_PARSER_H +#define _CLD_DIAG_PARSER_H + +#define FEATURE_LOG_EXPOSED_HEADER + +#include +#ifndef __KERNEL__ +#include +#include +#endif // __KERNEL__ +#include "event.h" +#include "msg.h" +#include "log.h" +#include "diag_lsm.h" +#include "diagpkt.h" +#include "diagcmd.h" +#include "diag.h" + +/* KERNEL DEFS START */ +#define DBGLOG_MAX_VDEVID 15 /* 0-15 */ +#define DBGLOG_TIMESTAMP_OFFSET 0 +#define DBGLOG_TIMESTAMP_MASK 0xFFFFFFFF /* Bit 0-15. Contains bit + 8-23 of the LF0 timer */ +#define DBGLOG_DBGID_OFFSET 0 +#define DBGLOG_DBGID_MASK 0x000003FF /* Bit 0-9 */ +#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */ + +#define DBGLOG_MODULEID_OFFSET 10 +#define DBGLOG_MODULEID_MASK 0x0003FC00 /* Bit 10-17 */ +#define DBGLOG_MODULEID_NUM_MAX 32 /* Upper limit is width of mask */ + +#define DBGLOG_VDEVID_OFFSET 18 +#define DBGLOG_VDEVID_MASK 0x03FC0000 /* Bit 20-25*/ +#define DBGLOG_VDEVID_NUM_MAX 16 + +#define DBGLOG_NUM_ARGS_OFFSET 26 +#define DBGLOG_NUM_ARGS_MASK 0xFC000000 /* Bit 26-31 */ +#define DBGLOG_NUM_ARGS_MAX 5 /* it is limited bcoz of limitations + with Xtensa tool */ + +#define DBGLOG_LOG_BUFFER_SIZE 1500 +#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90 + +#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE + +#define DBGLOG_GET_DBGID(arg) \ + ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET) + +#define DBGLOG_GET_MODULEID(arg) \ + ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET) + +#define DBGLOG_GET_VDEVID(arg) \ + ((arg & DBGLOG_VDEVID_MASK) >> DBGLOG_VDEVID_OFFSET) + +#define DBGLOG_GET_NUMARGS(arg) \ + ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET) + +#define DBGLOG_GET_TIME_STAMP(arg) \ + ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET) + + +#define DIAG_FWID_OFFSET 24 +#define DIAG_FWID_MASK 0xFF000000 /* Bit 24-31 */ + +#define DIAG_TIMESTAMP_OFFSET 0 +#define DIAG_TIMESTAMP_MASK 0x00FFFFFF /* Bit 0-23 */ + +#define DIAG_ID_OFFSET 16 +#define DIAG_ID_MASK 0xFFFF0000 /* Bit 16-31 */ + +#define DIAG_VDEVID_OFFSET 11 +#define DIAG_VDEVID_MASK 0x0000F800 /* Bit 11-15 */ +#define DIAG_VDEVID_NUM_MAX 16 + +#define DIAG_VDEVLEVEL_OFFSET 8 +#define DIAG_VDEVLEVEL_MASK 0x00000700 /* Bit 8-10 */ + +#define DIAG_PAYLEN_OFFSET 0 +#define DIAG_PAYLEN_MASK 0x000000FF /* Bit 0-7 */ + +#define DIAG_PAYLEN_OFFSET16 0 +#define DIAG_PAYLEN_MASK16 0x0000FFFF /* Bit 0-16 */ + +#define DIAG_GET_TYPE(arg) \ + ((arg & DIAG_FWID_MASK) >> DIAG_FWID_OFFSET) + +#define DIAG_GET_TIME_STAMP(arg) \ + ((arg & DIAG_TIMESTAMP_MASK) >> DIAG_TIMESTAMP_OFFSET) + +#define DIAG_GET_ID(arg) \ + ((arg & DIAG_ID_MASK) >> DIAG_ID_OFFSET) + +#define DIAG_GET_VDEVID(arg) \ + ((arg & DIAG_VDEVID_MASK) >> DIAG_VDEVID_OFFSET) + +#define DIAG_GET_VDEVLEVEL(arg) \ + ((arg & DIAG_VDEVLEVEL_MASK) >> DIAG_VDEVLEVEL_OFFSET) + +#define DIAG_GET_PAYLEN(arg) \ + ((arg & DIAG_PAYLEN_MASK) >> DIAG_PAYLEN_OFFSET) + +#define DIAG_GET_PAYLEN16(arg) \ + ((arg & DIAG_PAYLEN_MASK16) >> DIAG_PAYLEN_OFFSET16) + +#define LOGFILE_FLAG 0x01 +#define CONSOLE_FLAG 0x02 +#define QXDM_FLAG 0x04 +#define SILENT_FLAG 0x08 +#define DEBUG_FLAG 0x10 + +#define INIT_WITH_SLEEP 10 +#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 + +#define HDRLEN 16 +#define RECLEN (HDRLEN + ATH6KL_FWLOG_PAYLOAD_SIZE) +#define SIZEOF_NL_MSG_LOAD 28 /* sizeof nlmsg and load length */ +#define SIZEOF_NL_MSG_UNLOAD 28 /* sizeof nlmsg and Unload length */ +#define DIAG_TYPE_LOGS 1 +#define DIAG_TYPE_EVENTS 2 +/* General purpose MACROS to handle the WNI Netlink msgs */ +#define ANI_NL_MASK 3 + +/* Debug Log levels*/ + +typedef enum { + DBGLOG_VERBOSE = 0, + DBGLOG_INFO, + DBGLOG_INFO_LVL_1, + DBGLOG_INFO_LVL_2, + DBGLOG_WARN, + DBGLOG_ERR, + DBGLOG_LVL_MAX +}DBGLOG_LOG_LVL; + +enum cnss_diag_type { + DIAG_TYPE_FW_EVENT, /* send fw event- to diag*/ + DIAG_TYPE_FW_LOG, /* send log event- to diag*/ + DIAG_TYPE_FW_DEBUG_MSG, /* send dbg message- to diag*/ + DIAG_TYPE_INIT_REQ, /* cnss_diag nitialization- from diag */ + DIAG_TYPE_FW_MSG, /* fw msg command-to diag */ + DIAG_TYPE_HOST_MSG, /* host command-to diag */ + DIAG_TYPE_CRASH_INJECT, /*crash inject-from diag */ + DIAG_TYPE_DBG_LEVEL, /* DBG LEVEL-from diag */ +}; + +enum wlan_diag_frame_type { + WLAN_DIAG_TYPE_CONFIG, + WLAN_DIAG_TYPE_EVENT, + WLAN_DIAG_TYPE_LOG, + WLAN_DIAG_TYPE_MSG, + WLAN_DIAG_TYPE_LEGACY_MSG, +}; + +/* + * The following enum defines the target kernel module for which the netlink + * message is intended for. Each kernel module along with its counterpart + * in the user space, will then define a set of messages they recognize. + * Each of this message will have an header of type tAniHdr define below. + * Each Netlink message to/from a kernel module will contain only one + * message which is preceded by a tAniHdr. + * + * +------------+-------+-------+----------+ + * |Netlink hdr | Align |tAniHdr| msg body | + * +------------+-------+-------|----------+ + */ +#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */ +typedef enum eAniNlModuleTypes { + ANI_NL_MSG_NETSIM = ANI_NL_MSG_BASE,// NetSim Messages (to the server) + ANI_NL_MSG_PUMAC, // Messages for/from the Upper MAC driver + ANI_NL_MSG_WNS, // Messages for the Wireless Networking + // Services module(s) + ANI_NL_MSG_MACSW, // Messages from MAC + ANI_NL_MSG_ES, // Messages from ES + ANI_NL_MSG_WSM, // Message from the WSM in user space + ANI_NL_MSG_DVT, // Message from the DVT application + ANI_NL_MSG_PTT, // Message from the PTT application + ANI_NL_MSG_MAC_CLONE, //Message from the Mac clone App + ANI_NL_MSG_LOG = ANI_NL_MSG_BASE + 0x0C, // Message for WLAN logging + ANI_NL_MSG_MAX +} tAniNlModTypes; + +struct dbglog_slot { + unsigned int diag_type; + unsigned int timestamp; + unsigned int length; + unsigned int dropped; + /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */ + u_int8_t payload[0]; +}__packed; + +typedef struct event_report_s { + unsigned int diag_type; + unsigned short event_id; + unsigned short length; +} event_report_t; + +typedef struct wlan_bringup_s { + unsigned short wlanStatus; + char driverVersion[10]; +} wlan_bringup_t; + +//All Netlink messages must contain this header +typedef struct sAniHdr { + unsigned short type; + unsigned short length; +} tAniHdr, tAniMsgHdr; + +/* + * This msg hdr will always follow tAniHdr in all the messages exchanged + * between the Applications in userspace the Pseudo Driver, in either + * direction. + */ +typedef struct sAniNlMsg { + struct nlmsghdr nlh; // Netlink Header + int radio; // unit number of the radio + tAniHdr wmsg; // Airgo Message Header +} tAniNlHdr; + +typedef struct sAniAppRegReq { + tAniNlModTypes type; /* The module id that the application is + registering for */ + int pid; /* Pid returned in the nl_sockaddr structure + in the call getsockbyname after the + application opens and binds a netlink + socket */ +} tAniNlAppRegReq; + +static inline unsigned int get_32(const unsigned char *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +static inline unsigned int aniNlAlign(unsigned int len) +{ + return ((len + ANI_NL_MASK) & ~ANI_NL_MASK); +} + +/* + * Determines the aligned length of the WNI MSG including the hdr + * for a given payload of length 'len'. + */ +static inline unsigned int aniNlLen(unsigned int len) +{ + return (aniNlAlign(sizeof(tAniHdr)) + len); +} + +/* KERNEL DEFS END */ + +#ifdef CONFIG_ANDROID_LOG +#include + +#define FWDEBUG_LOG_NAME "ROME" +#define FWDEBUG_NAME "ROME_DEBUG" +#define android_printf(...) \ + __android_log_print(ANDROID_LOG_INFO, FWDEBUG_LOG_NAME, __VA_ARGS__); +#else +#define android_printf printf +#endif + +#define WLAN_NL_MSG_CNSS_DIAG 27 /* Msg type between user space/wlan driver */ +#define WLAN_NL_MSG_CNSS_HOST_MSG 28 +#define WLAN_NL_MSG_CNSS_HOST_EVENT_LOG 17 +#define CNSS_WLAN_DIAG 0x07 +#define CNSS_WLAN_SSR_TYPE 0x01 +#define CNSS_WLAN_LEVEL_TYPE 0x02 +/* NL messgage Carries actual Logs from Driver */ +#define ANI_NL_MSG_LOG_HOST_MSG_TYPE 89 +#define ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE 0x5050 +/* NL message Registration Req/Response to and from Driver */ +#define ANI_NL_MSG_LOG_REG_TYPE 0x0001 +#define MAX_MSG_SIZE 50000 +#define DIAG_MSG_MAX_LEN 4096 +#define DIAG_MSG_OVERHEAD_LEN 48 +/* PKT SIZE for intf */ +#define MAX_PKT_SIZE 8192 + +/* SPECIAL DIAG HANDLING */ +#define DIAG_WLAN_MODULE_STA_PWRSAVE 34292 +#define DIAG_WLAN_MODULE_WAL 42996 +#define DIAG_NAN_MODULE_ID 56820 +#define DIAG_WLAN_MODULE_IBSS_PWRSAVE 57332 + +#define RESTART_LEVEL \ + "echo related > /sys/bus/msm_subsys/devices/subsys%d/restart_level" +#define DB_FILE_PATH "/firmware/image/Data.msc" +#define BUF_SIZ 256 + +#define WLAN_LOG_TO_DIAG(xx_ss_id, xx_ss_mask, xx_fmt) \ + do { \ + if (xx_ss_mask & (MSG_BUILD_MASK_ ## xx_ss_id)) { \ + msg_const_type xx_msg = { \ + {__LINE__, (xx_ss_id), (xx_ss_mask)}, (NULL), msg_file}; \ + xx_msg.fmt = xx_fmt; \ + msg_send (&xx_msg); \ + } \ + } while (0); \ + +/* General purpose MACROS to handle the WNI Netlink msgs */ +#define ANI_NL_MASK 3 + + +PACK(void *)cnss_wlan_handle(PACK(void *)req_pkt, uint16_t pkt_len); + +static const diagpkt_user_table_entry_type cnss_wlan_tbl[] = +{ /* susbsys_cmd_code lo = 7 , susbsys_cmd_code hi = 7, call back function */ + {CNSS_WLAN_DIAG, CNSS_WLAN_DIAG,cnss_wlan_handle}, +}; + +int32_t parser_init(); + +int32_t +dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped); + +void +diag_initialize(int sock_fd, uint32_t optionflag); + +void +process_diaghost_msg(uint8_t *datap, uint16_t len); + +uint32_t +process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records, int32_t version, + int sock_fd); + +int +diag_msg_handler(uint32_t id, char *payload, uint16_t vdevid, uint32_t timestamp); + +int +cnssdiag_register_kernel_logging(int sock_fd, struct nlmsghdr *nlh); + +void process_cnss_host_message(tAniNlHdr *wnl, int32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records); + +void process_cnss_host_diag_events_log(char *pData, int32_t optionflag); + +#endif + diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-netlink.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-netlink.c new file mode 100644 index 0000000000000..31c88bae873b1 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-netlink.c @@ -0,0 +1,759 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ANDROID +#include +#endif +#include +#include +#include +#include +#include "event.h" +#include "msg.h" +#include "log.h" + +#include "diag_lsm.h" +#include "diagpkt.h" +#include "diagcmd.h" +#include "diag.h" +#include "cld-diag-parser.h" + +#define CNSS_INTF "wlan0" + +#ifdef ANDROID +/* CAPs needed + * CAP_NET_RAW : Use RAW and packet socket + * CAP_NET_ADMIN : NL broadcast receive + */ +const uint32_t capabilities = (1 << CAP_NET_RAW) | (1 << CAP_NET_ADMIN); + +/* Groups needed + * AID_INET : Open INET socket + * AID_NET_ADMIN : Handle NL socket + * AID_QCOM_DIAG : Access DIAG debugfs + * AID_WIFI : WIFI Operation + */ +const gid_t groups[] = {AID_INET, AID_NET_ADMIN, AID_QCOM_DIAG, AID_WIFI}; +#endif + +const char options[] = +"Options:\n\ +-f, --logfile= [Mandotory]\n\ +-r, --reclimit= [Optional]\n\ +-c, --console (prints the logs in the console)\n\ +-s, --silent (No print will come when logging)\n\ +-q, --qxdm (prints the logs in the qxdm)\n\ +-d, --debug (more prints in logcat, check logcat -s ROME_DEBUG, example to use: -q -d or -c -d)\n\ +The options can also be given in the abbreviated form --option=x or -o x. The options can be given in any order"; + +struct sockaddr_nl src_addr, dest_addr; +struct nlmsghdr *nlh = NULL; +struct iovec iov; +static int sock_fd = -1; +struct msghdr msg; + +static FILE *fwlog_res; +FILE *log_out = NULL; +const char *fwlog_res_file; +static int cnss_sock = -1; +int32_t max_records; +int32_t record = 0; +const char *progname; +char dbglogoutfile[PATH_MAX]; +int32_t optionflag = 0; +int32_t rec_limit = 100000000; /* Million records is a good default */ +boolean isDriverLoaded = FALSE; + +static void +usage(void) +{ + fprintf(stderr, "Usage:\n%s options\n", progname); + fprintf(stderr, "%s\n", options); + exit(-1); +} + +static uint32_t get_le32(const uint8_t *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +static size_t reorder(FILE *log_in, FILE *log_out) +{ + uint8_t buf[RECLEN]; + size_t res; + uint32_t timestamp = 0, min_timestamp = -1; + int32_t pos = 0, min_pos = 0; + struct dbglog_slot *slot; + uint32_t length = 0; + + pos = 0; + while ((res = fread(buf, RECLEN, 1, log_in)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((uint8_t *)&slot->timestamp); + length = get_le32((uint8_t *)&slot->length); + if (timestamp < min_timestamp) { + min_timestamp = timestamp; + min_pos = pos; + } + pos++; + } + printf("First record at position %d\n", min_pos); + + fseek(log_in, min_pos * RECLEN, SEEK_SET); + while ((res = fread(buf, RECLEN, 1, log_in)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((uint8_t *)&slot->timestamp); + length = get_le32((uint8_t *)&slot->length); + printf("Read record timestamp=%u length=%u\n", + timestamp, length); + if (fwrite(buf, RECLEN, res, log_out) != res) + perror("fwrite"); + } + + fseek(log_in, 0, SEEK_SET); + pos = min_pos; + while (pos > 0 && (res = fread(buf, RECLEN, 1, log_out)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((uint8_t *)&slot->timestamp); + length = get_le32((uint8_t *)&slot->length); + pos--; + printf("Read record timestamp=%u length=%u\n", + timestamp, length); + if (fwrite(buf, RECLEN, res, log_out) != res) + perror("fwrite"); + } + + return 0; +} + +#ifdef ANDROID +/* + * Lower the privileges for security reason + * the service will run only in system or diag mode + * + */ +int32_t +cnssdiagservice_cap_handle(void) +{ + int32_t i; + int32_t err; + + struct __user_cap_header_struct cap_header_data; + cap_user_header_t cap_header = &cap_header_data; + struct __user_cap_data_struct cap_data_data; + cap_user_data_t cap_data = &cap_data_data; + + cap_header->pid = 0; + cap_header->version = _LINUX_CAPABILITY_VERSION; + memset(cap_data, 0, sizeof(cap_data_data)); + + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) + { + printf("%d PR_SET_KEEPCAPS error:%s", __LINE__, strerror(errno)); + exit(1); + } + + if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) + { + printf("setgroups error %s", strerror(errno)); + return -1; + } + + if (setgid(AID_SYSTEM)) + { + printf("SET GID error %s", strerror(errno)); + return -1; + } + + if (setuid(AID_SYSTEM)) + { + printf("SET UID %s", strerror(errno)); + return -1; + } + + /* Assign correct CAP */ + cap_data->effective = capabilities; + cap_data->permitted = capabilities; + /* Set the capabilities */ + if (capset(cap_header, cap_data) < 0) + { + printf("%d failed capset error:%s", __LINE__, strerror(errno)); + return -1; + } + return 0; +} +#endif + +static void cleanup(void) { + if (sock_fd) + close(sock_fd); + + fwlog_res = fopen(fwlog_res_file, "w"); + + if (fwlog_res == NULL) { + perror("Failed to open reorder fwlog file"); + fclose(log_out); + return; + } + + reorder(log_out, fwlog_res); + + fclose(fwlog_res); + fclose(log_out); +} + +static void stop(int32_t signum) +{ + signum; /* Avoid warning */ + if(optionflag & LOGFILE_FLAG){ + printf("Recording stopped\n"); + cleanup(); + } + exit(0); +} + + +void process_cnss_log_file(uint8_t *dbgbuf) +{ + uint16_t length = 0; + uint32_t dropped = 0; + uint32_t timestamp = 0; + uint32_t res =0; + struct dbglog_slot *slot = (struct dbglog_slot *)dbgbuf; + fseek(log_out, record * RECLEN, SEEK_SET); + record++; + timestamp = get_le32((uint8_t *)&slot->timestamp); + length = get_le32((uint8_t *)&slot->length); + dropped = get_le32((uint8_t *)&slot->dropped); + if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) { + /* don't like this have to fix it */ + printf("Read record %d timestamp=%u length=%u fw dropped=%u\n", + record, timestamp, length, dropped); + } + if ((res = fwrite(dbgbuf, RECLEN, 1, log_out)) != 1){ + perror("fwrite"); + return; + } + fflush(log_out); + if (record == max_records) + record = 0; +} +/* + * Process FW debug, FW event and FW log messages + * Read the payload and process accordingly. + * + */ +void process_cnss_diag_msg(tAniNlHdr *wnl) +{ + uint8_t *dbgbuf; + uint8_t *eventbuf = (uint8_t *)NLMSG_DATA(wnl); + uint16_t diag_type = 0; + uint32_t event_id = 0; + uint16_t length = 0; + struct dbglog_slot *slot; + uint32_t dropped = 0; + + dbgbuf = eventbuf; + + diag_type = *(uint16_t *)eventbuf; + eventbuf += sizeof(uint16_t); + + length = *(uint16_t *)eventbuf; + eventbuf += sizeof(uint16_t); + + if (wnl->nlh.nlmsg_type == WLAN_NL_MSG_CNSS_HOST_MSG + && (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_MSG_TYPE)) { + process_cnss_host_message(wnl, optionflag, log_out, &record, max_records); + } else if (wnl->nlh.nlmsg_type == WLAN_NL_MSG_CNSS_HOST_EVENT_LOG + && (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE)) { + process_cnss_host_diag_events_log((char *)((char *)&wnl->wmsg.length + + sizeof(wnl->wmsg.length)), optionflag); + } else { + if (diag_type == DIAG_TYPE_FW_EVENT) { + eventbuf += sizeof(uint32_t); + event_id = *(uint32_t *)eventbuf; + eventbuf += sizeof(uint32_t); + if (optionflag & QXDM_FLAG) { + if (length) + event_report_payload(event_id, length, eventbuf); + else + event_report(event_id); + } + } else if (diag_type == DIAG_TYPE_FW_LOG) { + /* Do nothing for now */ + } else if (diag_type == DIAG_TYPE_FW_DEBUG_MSG) { + slot =(struct dbglog_slot *)dbgbuf; + length = get_le32((uint8_t *)&slot->length); + dropped = get_le32((uint8_t *)&slot->dropped); + if (optionflag & LOGFILE_FLAG) + process_cnss_log_file(dbgbuf); + else if (optionflag & (CONSOLE_FLAG | QXDM_FLAG)) + dbglog_parse_debug_logs(&slot->payload[0], length, dropped); + } else if (diag_type == DIAG_TYPE_FW_MSG) { + uint32_t version = 0; + slot = (struct dbglog_slot *)dbgbuf; + length = get_32((uint8_t *)&slot->length); + version = get_le32((uint8_t *)&slot->dropped); + process_diagfw_msg(&slot->payload[0], length, optionflag, log_out, + &record, max_records, version, sock_fd); + } else if (diag_type == DIAG_TYPE_HOST_MSG) { + slot = (struct dbglog_slot *)dbgbuf; + length = get_32((uint8_t *)&slot->length); + process_diaghost_msg(slot->payload, length); + } else { + /* Do nothing for now */ + } + } + +} + +/* + * Open the socket and bind the socket with src + * address. Return the socket fd if sucess. + * + */ +static int32_t create_nl_socket() +{ + int32_t ret; + int32_t sock_fd; + + sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK); + if (sock_fd < 0) { + fprintf(stderr, "Socket creation failed sock_fd 0x%x \n", sock_fd); + return -1; + } + + memset(&src_addr, 0, sizeof(src_addr)); + src_addr.nl_family = AF_NETLINK; + src_addr.nl_groups = 0x01; + src_addr.nl_pid = getpid(); /* self pid */ + + ret = bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)); + if (ret < 0) + { + close(sock_fd); + return ret; + } + return sock_fd; +} + +static int initialize(int32_t sock_fd) +{ + char *mesg = "Hello"; + + memset(&dest_addr, 0, sizeof(dest_addr)); + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; /* For Linux Kernel */ + dest_addr.nl_groups = 0; /* unicast */ + + if (nlh) { + free(nlh); + nlh = NULL; + } + nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSG_SIZE)); + if (nlh == NULL) { + fprintf(stderr, "Cannot allocate memory \n"); + close(sock_fd); + return -1; + } + memset(nlh, 0, NLMSG_SPACE(MAX_MSG_SIZE)); + nlh->nlmsg_len = NLMSG_SPACE(MAX_MSG_SIZE); + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_DIAG; + nlh->nlmsg_flags = NLM_F_REQUEST; + + memcpy(NLMSG_DATA(nlh), mesg, strlen(mesg)); + + iov.iov_base = (void *)nlh; + iov.iov_len = nlh->nlmsg_len; + msg.msg_name = (void *)&dest_addr; + msg.msg_namelen = sizeof(dest_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + if (sendmsg(sock_fd, &msg, 0) < 0) { + android_printf("%s error ", __func__); + return -1; + } + return 1; +} + +static int +cnss_read_ifname(struct nlmsghdr *h, size_t len) +{ + struct ifinfomsg *ifi; + int attrlen, nlmsg_len, rta_len; + struct rtattr *attr; + + if (!h) { + android_printf("%s null error ", __func__); + return 0; + } + + if (len < sizeof(*ifi)) { + android_printf("%s len error ", __func__); + return 0; + } + + ifi = NLMSG_DATA(h); + + nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); + + attrlen = h->nlmsg_len - nlmsg_len; + if (attrlen < 0) + return 0; + + attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); + + rta_len = RTA_ALIGN(sizeof(struct rtattr)); + while (RTA_OK(attr, attrlen)) { + char ifname[IFNAMSIZ + 1]; + + if (attr->rta_type == IFLA_IFNAME) { + int n = attr->rta_len - rta_len; + if (n < 0) + break; + + memset(ifname, 0, sizeof(ifname)); + + if ((size_t) n > sizeof(ifname)) + n = sizeof(ifname); + memcpy(ifname, ((char *) attr) + rta_len, n); + if (strcmp(ifname, CNSS_INTF) == 0) + return 1; + else + return 0; + } + + attr = RTA_NEXT(attr, attrlen); + } + return 0; +} + +static int cnss_intf_receive(int sock) +{ + char buf[MAX_PKT_SIZE]; + int left, sleep_cnt = 0; + struct sockaddr_nl from; + socklen_t fromlen; + struct nlmsghdr *h; + + fromlen = sizeof(from); + while ( 1 ) { + left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr *) &from, &fromlen); + if (left < 0) { + return -1; + } + + h = (struct nlmsghdr *) buf; + while (left >= (int) sizeof(*h)) { + int len, plen; + + len = h->nlmsg_len; + plen = len - sizeof(*h); + if (len > left || plen < 0) { + break; + } + + switch (h->nlmsg_type) { + case RTM_NEWLINK: + if (cnss_read_ifname(h, plen)) { + if (!isDriverLoaded) { + isDriverLoaded = TRUE; + sleep_cnt = 0; + while ( 1 ) { + if (initialize(sock_fd) < 0) { + android_printf("%s error retrying", + __func__); + sleep_cnt++; + sleep(1); + /* DONT LOOP EVER */ + if (sleep_cnt >= INIT_WITH_SLEEP) + break; + else + continue; + } + diag_initialize(sock_fd, optionflag); + cnssdiag_register_kernel_logging(sock_fd, nlh); + break; + } + } + + } + break; + case RTM_DELLINK: + if (cnss_read_ifname(h, plen)) { + isDriverLoaded = FALSE; + } + break; + } + + len = NLMSG_ALIGN(len); + left -= len; + h = (struct nlmsghdr *) ((char *) h + len); + } + } + return 0; +} + +static int cnss_intf_init() +{ + struct sockaddr_nl local; + cnss_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (cnss_sock < 0) { + return -1; + } + + memset(&local, 0, sizeof(local)); + local.nl_family = AF_NETLINK; + local.nl_groups = RTMGRP_LINK; + if (bind(cnss_sock, (struct sockaddr *) &local, sizeof(local)) < 0) { + close(cnss_sock); + return -1; + } + return 1; +} + +static inline void* cnss_intf_wait_receive(void * arg) +{ + arg; /* Avoid warning */ + fd_set fds; + int oldfd, ret; + int sock; + + cnss_intf_init(); + sock = cnss_sock; + + if (sock < 0) { + android_printf("%s error Netlink Socket Not Available", __func__); + return NULL; + } + while ( 1 ) { + /* Initialize fds */ + FD_ZERO(&fds); + FD_SET(sock, &fds); + oldfd = sock; + + /* Wait for some trigger event */ + ret = select(oldfd + 1, &fds, NULL, NULL, NULL); + + if (ret < 0) { + /* Error Occurred */ + android_printf("%s error Netlink select fail", __func__); + return NULL; + } else if (!ret) { + android_printf("%s error Select on Netlink Socket Timed Out", + __func__); + /* Timeout Occurred */ + return NULL; + } + + /* Check if any event is available for us */ + if (FD_ISSET(sock, &fds)) { + cnss_intf_receive(sock); + } + } + return NULL; +} + +static inline boolean is_interface(const char *interface, int len) +{ + struct ifreq ifr; + int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); + memset(&ifr, 0, sizeof(ifr)); + if (interface) { + strlcpy(ifr.ifr_name, interface, len); + } + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return FALSE; + } + close(sock); + return TRUE; +} + +int32_t main(int32_t argc, char *argv[]) +{ + int res =0; + uint8_t *eventbuf = NULL; + uint8_t *dbgbuf = NULL; + int32_t c; + struct dbglog_slot *slot; + int cnss_intf_len = strlen(CNSS_INTF) + 1; + pthread_t thd_id; + + progname = argv[0]; + uint16_t diag_type = 0; + int32_t option_index = 0; + static struct option long_options[] = { + {"logfile", 1, NULL, 'f'}, + {"reclimit", 1, NULL, 'r'}, + {"console", 0, NULL, 'c'}, + {"qxdm", 0, NULL, 'q'}, + {"silent", 0, NULL, 's'}, + {"debug", 0, NULL, 'd'}, + { 0, 0, 0, 0} + }; + + while (1) { + c = getopt_long (argc, argv, "f:scqdr:", long_options, &option_index); + if (c == -1) break; + + switch (c) { + case 'f': + memset(dbglogoutfile, 0, PATH_MAX); + memcpy(dbglogoutfile, optarg, strlen(optarg)); + optionflag |= LOGFILE_FLAG; + break; + + case 'c': + optionflag |= CONSOLE_FLAG; + break; + + case 'q': + optionflag |= QXDM_FLAG; + break; + + case 'r': + rec_limit = strtoul(optarg, NULL, 0); + break; + + case 's': + optionflag |= SILENT_FLAG; + break; + + case 'd': + optionflag |= DEBUG_FLAG; + break; + default: + usage(); + } + } + + if (!(optionflag & (LOGFILE_FLAG | CONSOLE_FLAG | QXDM_FLAG | SILENT_FLAG + | DEBUG_FLAG))) { + usage(); + return -1; + } + + if (optionflag & QXDM_FLAG) { + /* Intialize the fd required for diag APIs */ + if (TRUE != Diag_LSM_Init(NULL)) + { + perror("Failed on Diag_LSM_Init\n"); + return -1; + } + /* Register CALLABACK for QXDM input data */ + DIAGPKT_DISPATCH_TABLE_REGISTER(DIAG_SUBSYS_WLAN, cnss_wlan_tbl); +#ifdef ANDROID + if(cnssdiagservice_cap_handle()) { + printf("Cap bouncing failed EXIT!!!"); + exit(1); + } +#endif + } + + pthread_create(&thd_id, NULL, &cnss_intf_wait_receive, NULL); + + sock_fd = create_nl_socket(); + if (sock_fd < 0) { + fprintf(stderr, "Socket creation failed sock_fd 0x%x \n", sock_fd); + return -1; + } + + if (is_interface(CNSS_INTF, cnss_intf_len)) { + initialize(sock_fd); + cnssdiag_register_kernel_logging(sock_fd, nlh); + } + + signal(SIGINT, stop); + signal(SIGTERM, stop); + + if (optionflag & LOGFILE_FLAG) { + + if (rec_limit < RECLEN) { + fprintf(stderr, "Too small maximum length (has to be >= %d)\n", + RECLEN); + close(sock_fd); + free(nlh); + return -1; + } + max_records = rec_limit; + printf("Storing last %d records\n", max_records); + + log_out = fopen(dbglogoutfile, "w"); + if (log_out == NULL) { + perror("Failed to create output file"); + close(sock_fd); + free(nlh); + return -1; + } + + fwlog_res_file = "./reorder"; + } + + + parser_init(); + + while ( 1 ) { + if ((res = recvmsg(sock_fd, &msg, 0)) < 0) + continue; + if ((res >= (int)sizeof(struct dbglog_slot)) || + (nlh->nlmsg_type == WLAN_NL_MSG_CNSS_HOST_EVENT_LOG)) { + process_cnss_diag_msg((tAniNlHdr *)nlh); + memset(nlh,0,NLMSG_SPACE(MAX_MSG_SIZE)); + } else { + /* Ignore other messages that might be broadcast */ + continue; + } + } + /* Release the handle to Diag*/ + Diag_LSM_DeInit(); + if (optionflag & LOGFILE_FLAG) + cleanup(); + close(sock_fd); + free(nlh); + return 0; +} diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-parser.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-parser.c new file mode 100644 index 0000000000000..e62469f67bd6f --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-parser.c @@ -0,0 +1,2782 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "dbglog.h" +#include "dbglog_id.h" +#include "dbglog_host.h" + +#include "a_debug.h" +#include "ol_defines.h" +#include "ah_osdep.h" + +static unsigned int get_le32(const unsigned char *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +static FILE *log_in; + +unsigned char buf[RECLEN]; + +#define MAX_DBG_MSGS 256 + +module_dbg_print mod_print[WLAN_MODULE_ID_MAX]; + +const char *dbglog_get_module_str(A_UINT32 module_id) +{ + switch (module_id) { + case WLAN_MODULE_INF: + return "INF"; + case WLAN_MODULE_WMI: + return "WMI"; + case WLAN_MODULE_STA_PWRSAVE: + return "STA PS"; + case WLAN_MODULE_WHAL: + return "WHAL"; + case WLAN_MODULE_COEX: + return "COEX"; + case WLAN_MODULE_ROAM: + return "ROAM"; + case WLAN_MODULE_RESMGR_CHAN_MANAGER: + return "CHANMGR"; + case WLAN_MODULE_RESMGR: + return "RESMGR"; + case WLAN_MODULE_VDEV_MGR: + return "VDEV"; + case WLAN_MODULE_SCAN: + return "SCAN"; + case WLAN_MODULE_RATECTRL: + return "RC"; + case WLAN_MODULE_AP_PWRSAVE: + return "AP PS"; + case WLAN_MODULE_BLOCKACK: + return "BA"; + case WLAN_MODULE_MGMT_TXRX: + return "MGMT"; + case WLAN_MODULE_DATA_TXRX: + return "DATA"; + case WLAN_MODULE_HTT: + return "HTT"; + case WLAN_MODULE_HOST: + return "HOST"; + case WLAN_MODULE_BEACON: + return "BEACON"; + case WLAN_MODULE_OFFLOAD: + return "OFFLOAD"; + case WLAN_MODULE_WAL: + return "WAL"; + case WAL_MODULE_DE: + return "DE"; + case WLAN_MODULE_PCIELP: + return "PCIELP"; + case WLAN_MODULE_RTT: + return "RTT"; + case WLAN_MODULE_DCS: + return "DCS"; + case WLAN_MODULE_CACHEMGR: + return "CACHEMGR"; + case WLAN_MODULE_ANI: + return "ANI"; + case WLAN_MODULE_TEST: + return "TESTPOINT"; + case WLAN_MODULE_STA_SMPS: + return "STA_SMPS"; + case WLAN_MODULE_TDLS: + return "TDLS"; + case WLAN_MODULE_P2P: + return "P2P"; + case WLAN_MODULE_WOW: + return "WoW"; + case WLAN_MODULE_IBSS_PWRSAVE: + return "IBSS PS"; + case WLAN_MODULE_EXTSCAN: + return "ExtScan"; + case WLAN_MODULE_UNIT_TEST: + return "UNIT_TEST"; + case WLAN_MODULE_MLME: + return "MLME"; + case WLAN_MODULE_SUPPL: + return "SUPPLICANT"; + default: + return "UNKNOWN"; + } +} + +char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = +{ + { + "INF_MSG_START", + "INF_ASSERTION_FAILED", + "INF_TARGET_ID", + "INF_MSG_END" + }, + { + "WMI_DBGID_DEFINITION_START", + "WMI_CMD_RX_XTND_PKT_TOO_SHORT", + "WMI_EXTENDED_CMD_NOT_HANDLED", + "WMI_CMD_RX_PKT_TOO_SHORT", + "WMI_CALLING_WMI_EXTENSION_FN", + "WMI_CMD_NOT_HANDLED", + "WMI_IN_SYNC", + "WMI_TARGET_WMI_SYNC_CMD", + "WMI_SET_SNR_THRESHOLD_PARAMS", + "WMI_SET_RSSI_THRESHOLD_PARAMS", + "WMI_SET_LQ_TRESHOLD_PARAMS", + "WMI_TARGET_CREATE_PSTREAM_CMD", + "WMI_WI_DTM_INUSE", + "WMI_TARGET_DELETE_PSTREAM_CMD", + "WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD", + "WMI_TARGET_GET_BIT_RATE_CMD", + "WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS", + "WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD", + "WMI_TARGET_GET_TX_PWR_CMD", + "WMI_FREE_EVBUF_WMIBUF", + "WMI_FREE_EVBUF_DATABUF", + "WMI_FREE_EVBUF_BADFLAG", + "WMI_HTC_RX_ERROR_DATA_PACKET", + "WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX", + "WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT", + "WMI_SENDING_READY_EVENT", + "WMI_SETPOWER_MDOE_TO_MAXPERF", + "WMI_SETPOWER_MDOE_TO_REC", + "WMI_BSSINFO_EVENT_FROM", + "WMI_TARGET_GET_STATS_CMD", + "WMI_SENDING_SCAN_COMPLETE_EVENT", + "WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT ", + "WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT", + "WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT", + "WMI_SENDING_ERROR_REPORT_EVENT", + "WMI_SENDING_CAC_EVENT", + "WMI_TARGET_GET_ROAM_TABLE_CMD", + "WMI_TARGET_GET_ROAM_DATA_CMD", + "WMI_SENDING_GPIO_INTR_EVENT", + "WMI_SENDING_GPIO_ACK_EVENT", + "WMI_SENDING_GPIO_DATA_EVENT", + "WMI_CMD_RX", + "WMI_CMD_RX_XTND", + "WMI_EVENT_SEND", + "WMI_EVENT_SEND_XTND", + "WMI_CMD_PARAMS_DUMP_START", + "WMI_CMD_PARAMS_DUMP_END", + "WMI_CMD_PARAMS", + "WMI_EVENT_ALLOC_FAILURE", + "WMI_DBGID_DCS_PARAM_CMD", + "WMI_SEND_EVENT_WRONG_TLV", + "WMI_SEND_EVENT_NO_TLV_DEF", + "WMI_DBGID_DEFNITION_END", + }, + { + "PS_STA_DEFINITION_START", + "PS_STA_PM_ARB_REQUEST", + "PS_STA_DELIVER_EVENT", + "PS_STA_PSPOLL_SEQ_DONE", + "PS_STA_COEX_MODE", + "PS_STA_PSPOLL_ALLOW", + "PS_STA_SET_PARAM", + "PS_STA_SPECPOLL_TIMER_STARTED", + "PS_STA_SPECPOLL_TIMER_STOPPED", + }, + { + "WHAL_DBGID_DEFINITION_START", + "WHAL_ERROR_ANI_CONTROL", + "WHAL_ERROR_CHIP_TEST1", + "WHAL_ERROR_CHIP_TEST2", + "WHAL_ERROR_EEPROM_CHECKSUM", + "WHAL_ERROR_EEPROM_MACADDR", + "WHAL_ERROR_INTERRUPT_HIU", + "WHAL_ERROR_KEYCACHE_RESET", + "WHAL_ERROR_KEYCACHE_SET", + "WHAL_ERROR_KEYCACHE_TYPE", + "WHAL_ERROR_KEYCACHE_TKIPENTRY", + "WHAL_ERROR_KEYCACHE_WEPLENGTH", + "WHAL_ERROR_PHY_INVALID_CHANNEL", + "WHAL_ERROR_POWER_AWAKE", + "WHAL_ERROR_POWER_SET", + "WHAL_ERROR_RECV_STOPDMA", + "WHAL_ERROR_RECV_STOPPCU", + "WHAL_ERROR_RESET_CHANNF1", + "WHAL_ERROR_RESET_CHANNF2", + "WHAL_ERROR_RESET_PM", + "WHAL_ERROR_RESET_OFFSETCAL", + "WHAL_ERROR_RESET_RFGRANT", + "WHAL_ERROR_RESET_RXFRAME", + "WHAL_ERROR_RESET_STOPDMA", + "WHAL_ERROR_RESET_ERRID", + "WHAL_ERROR_RESET_ADCDCCAL1", + "WHAL_ERROR_RESET_ADCDCCAL2", + "WHAL_ERROR_RESET_TXIQCAL", + "WHAL_ERROR_RESET_RXIQCAL", + "WHAL_ERROR_RESET_CARRIERLEAK", + "WHAL_ERROR_XMIT_COMPUTE", + "WHAL_ERROR_XMIT_NOQUEUE", + "WHAL_ERROR_XMIT_ACTIVEQUEUE", + "WHAL_ERROR_XMIT_BADTYPE", + "WHAL_ERROR_XMIT_STOPDMA", + "WHAL_ERROR_INTERRUPT_BB_PANIC", + "WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW", + "WHAL_ERROR_QCU_HW_PAUSE_MISMATCH", + "WHAL_DBGID_DEFINITION_END", + }, + { + "COEX_DEBUGID_START", + "BTCOEX_DBG_MCI_1", + "BTCOEX_DBG_MCI_2", + "BTCOEX_DBG_MCI_3", + "BTCOEX_DBG_MCI_4", + "BTCOEX_DBG_MCI_5", + "BTCOEX_DBG_MCI_6", + "BTCOEX_DBG_MCI_7", + "BTCOEX_DBG_MCI_8", + "BTCOEX_DBG_MCI_9", + "BTCOEX_DBG_MCI_10", + "COEX_WAL_BTCOEX_INIT", + "COEX_WAL_PAUSE", + "COEX_WAL_RESUME", + "COEX_UPDATE_AFH", + "COEX_HWQ_EMPTY_CB", + "COEX_MCI_TIMER_HANDLER", + "COEX_MCI_RECOVER", + "ERROR_COEX_MCI_ISR", + "ERROR_COEX_MCI_GPM", + "COEX_ProfileType", + "COEX_LinkID", + "COEX_LinkState", + "COEX_LinkRole", + "COEX_LinkRate", + "COEX_VoiceType", + "COEX_TInterval", + "COEX_WRetrx", + "COEX_Attempts", + "COEX_PerformanceState", + "COEX_LinkType", + "COEX_RX_MCI_GPM_VERSION_QUERY", + "COEX_RX_MCI_GPM_VERSION_RESPONSE", + "COEX_RX_MCI_GPM_STATUS_QUERY", + "COEX_STATE_WLAN_VDEV_DOWN", + "COEX_STATE_WLAN_VDEV_START", + "COEX_STATE_WLAN_VDEV_CONNECTED", + "COEX_STATE_WLAN_VDEV_SCAN_STARTED", + "COEX_STATE_WLAN_VDEV_SCAN_END", + "COEX_STATE_WLAN_DEFAULT", + "COEX_CHANNEL_CHANGE", + "COEX_POWER_CHANGE", + "COEX_CONFIG_MGR", + "COEX_TX_MCI_GPM_BT_CAL_REQ", + "COEX_TX_MCI_GPM_BT_CAL_GRANT", + "COEX_TX_MCI_GPM_BT_CAL_DONE", + "COEX_TX_MCI_GPM_WLAN_CAL_REQ", + "COEX_TX_MCI_GPM_WLAN_CAL_GRANT", + "COEX_TX_MCI_GPM_WLAN_CAL_DONE", + "COEX_TX_MCI_GPM_BT_DEBUG", + "COEX_TX_MCI_GPM_VERSION_QUERY", + "COEX_TX_MCI_GPM_VERSION_RESPONSE", + "COEX_TX_MCI_GPM_STATUS_QUERY", + "COEX_TX_MCI_GPM_HALT_BT_GPM", + "COEX_TX_MCI_GPM_WLAN_CHANNELS", + "COEX_TX_MCI_GPM_BT_PROFILE_INFO", + "COEX_TX_MCI_GPM_BT_STATUS_UPDATE", + "COEX_TX_MCI_GPM_BT_UPDATE_FLAGS", + "COEX_TX_MCI_GPM_UNKNOWN", + "COEX_TX_MCI_SYS_WAKING", + "COEX_TX_MCI_LNA_TAKE", + "COEX_TX_MCI_LNA_TRANS", + "COEX_TX_MCI_SYS_SLEEPING", + "COEX_TX_MCI_REQ_WAKE", + "COEX_TX_MCI_REMOTE_RESET", + "COEX_TX_MCI_TYPE_UNKNOWN", + "COEX_WHAL_MCI_RESET", + "COEX_POLL_BT_CAL_DONE_TIMEOUT", + "COEX_WHAL_PAUSE", + "COEX_RX_MCI_GPM_BT_CAL_REQ", + "COEX_RX_MCI_GPM_BT_CAL_DONE", + "COEX_RX_MCI_GPM_BT_CAL_GRANT", + "COEX_WLAN_CAL_START", + "COEX_WLAN_CAL_RESULT", + "COEX_BtMciState", + "COEX_BtCalState", + "COEX_WlanCalState", + "COEX_RxReqWakeCount", + "COEX_RxRemoteResetCount", + "COEX_RESTART_CAL", + "COEX_SENDMSG_QUEUE", + "COEX_RESETSEQ_LNAINFO_TIMEOUT", + "COEX_MCI_ISR_IntRaw", + "COEX_MCI_ISR_Int1Raw", + "COEX_MCI_ISR_RxMsgRaw", + "COEX_WHAL_COEX_RESET", + "COEX_WAL_COEX_INIT", + "COEX_TXRX_CNT_LIMIT_ISR", + "COEX_CH_BUSY", + "COEX_REASSESS_WLAN_STATE", + "COEX_BTCOEX_WLAN_STATE_UPDATE", + "COEX_BT_NUM_OF_PROFILES", + "COEX_BT_NUM_OF_HID_PROFILES", + "COEX_BT_NUM_OF_ACL_PROFILES", + "COEX_BT_NUM_OF_HI_ACL_PROFILES", + "COEX_BT_NUM_OF_VOICE_PROFILES", + "COEX_WLAN_AGGR_LIMIT", + "COEX_BT_LOW_PRIO_BUDGET", + "COEX_BT_HI_PRIO_BUDGET", + "COEX_BT_IDLE_TIME", + "COEX_SET_COEX_WEIGHT", + "COEX_WLAN_WEIGHT_GROUP", + "COEX_BT_WEIGHT_GROUP", + "COEX_BT_INTERVAL_ALLOC", + "COEX_BT_SCHEME", + "COEX_BT_MGR", + "COEX_BT_SM_ERROR", + "COEX_SYSTEM_UPDATE", + "COEX_LOW_PRIO_LIMIT", + "COEX_HI_PRIO_LIMIT", + "COEX_BT_INTERVAL_START", + "COEX_WLAN_INTERVAL_START", + "COEX_NON_LINK_BUDGET", + "COEX_CONTENTION_MSG", + "COEX_SET_NSS", + "COEX_SELF_GEN_MASK", + "COEX_PROFILE_ERROR", + "COEX_WLAN_INIT", + "COEX_BEACON_MISS", + "COEX_BEACON_OK", + "COEX_BTCOEX_SCAN_ACTIVITY", + "COEX_SCAN_ACTIVITY", + "COEX_FORCE_QUIETTIME", + "COEX_BT_MGR_QUIETTIME", + "COEX_BT_INACTIVITY_TRIGGER", + "COEX_BT_INACTIVITY_REPORTED", + "COEX_TX_MCI_GPM_WLAN_PRIO", + "COEX_TX_MCI_GPM_BT_PAUSE_PROFILE", + "COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY", + "COEX_RX_MCI_GPM_BT_ACL_INACTIVITY_REPORT", + "COEX_GENERIC_ERROR", + "COEX_RX_RATE_THRESHOLD", + "COEX_RSSI", + "COEX_WLAN_VDEV_NOTIF_START", // 133 + "COEX_WLAN_VDEV_NOTIF_UP", // 134 + "COEX_WLAN_VDEV_NOTIF_DOWN", // 135 + "COEX_WLAN_VDEV_NOTIF_STOP", // 136 + "COEX_WLAN_VDEV_NOTIF_ADD_PEER", // 137 + "COEX_WLAN_VDEV_NOTIF_DELETE_PEER", // 138 + "COEX_WLAN_VDEV_NOTIF_CONNECTED_PEER", // 139 + "COEX_WLAN_VDEV_NOTIF_PAUSE", // 140 + "COEX_WLAN_VDEV_NOTIF_UNPAUSED", // 141 + "COEX_STATE_WLAN_VDEV_PEER_ADD", // 142 + "COEX_STATE_WLAN_VDEV_CONNECTED_PEER", // 143 + "COEX_STATE_WLAN_VDEV_DELETE_PEER", // 144 + "COEX_STATE_WLAN_VDEV_PAUSE", // 145 + "COEX_STATE_WLAN_VDEV_UNPAUSED", // 146 + "COEX_SCAN_CALLBACK", // 147 + "COEX_RC_SET_CHAINMASK", // 148 + "COEX_TX_MCI_GPM_WLAN_SET_BT_RXSS_THRES", // 149 + "COEX_TX_MCI_GPM_BT_RXSS_THRES_QUERY", // 150 + "COEX_BT_RXSS_THRES", // 151 + "COEX_BT_PROFILE_ADD_RMV", // 152 + "COEX_BT_SCHED_INFO", // 153 + "COEX_TRF_MGMT", // 154 + "COEX_SCHED_START", // 155 + "COEX_SCHED_RESULT", // 156 + "COEX_SCHED_ERROR", // 157 + "COEX_SCHED_PRE_OP", // 158 + "COEX_SCHED_POST_OP", // 159 + "COEX_RX_RATE", // 160 + "COEX_ACK_PRIORITY", // 161 + "COEX_STATE_WLAN_VDEV_UP", // 162 + "COEX_STATE_WLAN_VDEV_PEER_UPDATE", // 163 + "COEX_STATE_WLAN_VDEV_STOP", // 164 + "COEX_WLAN_PAUSE_PEER", // 165 + "COEX_WLAN_UNPAUSE_PEER", // 166 + "COEX_WLAN_PAUSE_INTERVAL_START", // 167 + "COEX_WLAN_POSTPAUSE_INTERVAL_START", // 168 + "COEX_TRF_FREERUN", // 169 + "COEX_TRF_SHAPE_PM", // 170 + "COEX_TRF_SHAPE_PSP", // 171 + "COEX_TRF_SHAPE_S_CTS", // 172 + "COEX_CHAIN_CONFIG", // 173 + "COEX_SYSTEM_MONITOR", // 174 + "COEX_SINGLECHAIN_INIT", // 175 + "COEX_MULTICHAIN_INIT", // 176 + "COEX_SINGLECHAIN_DBG_1", // 177 + "COEX_SINGLECHAIN_DBG_2", // 178 + "COEX_SINGLECHAIN_DBG_3", // 179 + "COEX_MULTICHAIN_DBG_1", // 180 + "COEX_MULTICHAIN_DBG_2", // 181 + "COEX_MULTICHAIN_DBG_3", // 182 + "COEX_PSP_TX_CB", // 183 + "COEX_PSP_RX_CB", // 184 + "COEX_PSP_STAT_1", // 185 + "COEX_PSP_SPEC_POLL", // 186 + "COEX_PSP_READY_STATE", // 187 + "COEX_PSP_TX_STATUS_STATE", // 188 + "COEX_PSP_RX_STATUS_STATE_1", // 189 + "COEX_PSP_NOT_READY_STATE", // 190 + "COEX_PSP_DISABLED_STATE", // 191 + "COEX_PSP_ENABLED_STATE", // 192 + "COEX_PSP_SEND_PSPOLL", // 193 + "COEX_PSP_MGR_ENTER", // 194 + "COEX_PSP_MGR_RESULT", // 195 + "COEX_PSP_NONWLAN_INTERVAL", // 196 + "COEX_PSP_STAT_2", // 197 + "COEX_PSP_RX_STATUS_STATE_2", // 198 + "COEX_PSP_ERROR", // 199 + "COEX_T2BT", // 200 + "COEX_BT_DURATION", // 201 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203 + "COEX_TX_MCI_GPM_SCAN_OP", // 204 + "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205 + "COEX_CTS2S_SEND", // 206 + "COEX_CTS2S_RESULT", // 207 + "COEX_ENTER_OCS", // 208 + "COEX_EXIT_OCS", // 209 + "COEX_UPDATE_OCS", // 210 + "COEX_STATUS_OCS", // 211 + "COEX_STATS_BT", // 212 + "COEX_MWS_WLAN_INIT", + "COEX_MWS_WBTMR_SYNC", + "COEX_MWS_TYPE2_RX", + "COEX_MWS_TYPE2_TX", + "COEX_MWS_WLAN_CHAVD", + "COEX_MWS_WLAN_CHAVD_INSERT", + "COEX_MWS_WLAN_CHAVD_MERGE", + "COEX_MWS_WLAN_CHAVD_RPT", + "COEX_MWS_CP_MSG_SEND", + "COEX_MWS_CP_ESCAPE", + "COEX_MWS_CP_UNFRAME", + "COEX_MWS_CP_SYNC_UPDATE", + "COEX_MWS_CP_SYNC", + "COEX_MWS_CP_WLAN_STATE_IND", + "COEX_MWS_CP_SYNCRESP_TIMEOUT", + "COEX_MWS_SCHEME_UPDATE", + "COEX_MWS_WLAN_EVENT", + "COEX_MWS_UART_UNESCAPE", + "COEX_MWS_UART_ENCODE_SEND", + "COEX_MWS_UART_RECV_DECODE", + "COEX_MWS_UL_HDL", + "COEX_MWS_REMOTE_EVENT", + "COEX_MWS_OTHER", + "COEX_MWS_ERROR", + "COEX_MWS_ANT_DIVERSITY", //237 + "COEX_P2P_GO", + "COEX_P2P_CLIENT", + "COEX_SCC_1", + "COEX_SCC_2", + "COEX_MCC_1", + "COEX_MCC_2", + "COEX_TRF_SHAPE_NOA", + "COEX_NOA_ONESHOT", + "COEX_NOA_PERIODIC", + "COEX_LE_1", + "COEX_LE_2", + "COEX_ANT_1", + "COEX_ANT_2", + "COEX_ENTER_NOA", + "COEX_EXIT_NOA", + "COEX_BT_SCAN_PROTECT", // 253 + "COEX_DEBUG_ID_END" // 254 + }, + { + "ROAM_DBGID_DEFINITION_START", + "ROAM_MODULE_INIT", + "ROAM_DEV_START", + "ROAM_CONFIG_RSSI_THRESH", + "ROAM_CONFIG_SCAN_PERIOD", + "ROAM_CONFIG_AP_PROFILE", + "ROAM_CONFIG_CHAN_LIST", + "ROAM_CONFIG_SCAN_PARAMS", + "ROAM_CONFIG_RSSI_CHANGE", + "ROAM_SCAN_TIMER_START", + "ROAM_SCAN_TIMER_EXPIRE", + "ROAM_SCAN_TIMER_STOP", + "ROAM_SCAN_STARTED", + "ROAM_SCAN_COMPLETE", + "ROAM_SCAN_CANCELLED", + "ROAM_CANDIDATE_FOUND", + "ROAM_RSSI_ACTIVE_SCAN", + "ROAM_RSSI_ACTIVE_ROAM", + "ROAM_RSSI_GOOD", + "ROAM_BMISS_FIRST_RECV", + "ROAM_DEV_STOP", + "ROAM_FW_OFFLOAD_ENABLE", + "ROAM_CANDIDATE_SSID_MATCH", + "ROAM_CANDIDATE_SECURITY_MATCH", + "ROAM_LOW_RSSI_INTERRUPT", + "ROAM_HIGH_RSSI_INTERRUPT", + "ROAM_SCAN_REQUESTED", + "ROAM_BETTER_CANDIDATE_FOUND", + "ROAM_BETTER_AP_EVENT", + "ROAM_CANCEL_LOW_PRIO_SCAN", + "ROAM_FINAL_BMISS_RECVD", + "ROAM_CONFIG_SCAN_MODE", + "ROAM_BMISS_FINAL_SCAN_ENABLE", + "ROAM_SUITABLE_AP_EVENT", + "ROAM_RSN_IE_PARSE_ERROR", + "ROAM_WPA_IE_PARSE_ERROR", + "ROAM_SCAN_CMD_FROM_HOST", + "ROAM_HO_SORT_CANDIDATE", + "ROAM_HO_SAVE_CANDIDATE", + "ROAM_HO_GET_CANDIDATE", + "ROAM_HO_OFFLOAD_SET_PARAM", + "ROAM_HO_SM", + "ROAM_HO_HTT_SAVED", + "ROAM_HO_SYNC_START", + "ROAM_HO_START", + "ROAM_HO_COMPLETE", + "ROAM_HO_STOP", + "ROAM_HO_HTT_FORWARD", + "ROAM_DBGID_DEFINITION_END" + }, + { + "RESMGR_CHMGR_DEFINITION_START", + "RESMGR_CHMGR_PAUSE_COMPLETE", + "RESMGR_CHMGR_CHANNEL_CHANGE", + "RESMGR_CHMGR_RESUME_COMPLETE", + "RESMGR_CHMGR_VDEV_PAUSE", + "RESMGR_CHMGR_VDEV_UNPAUSE", + "RESMGR_CHMGR_CTS2S_TX_COMP", + "RESMGR_CHMGR_CFEND_TX_COMP", + "RESMGR_CHMGR_DEFINITION_END" + }, + { + "RESMGR_DEFINITION_START", + "RESMGR_OCS_ALLOCRAM_SIZE", + "RESMGR_OCS_RESOURCES", + "RESMGR_LINK_CREATE", + "RESMGR_LINK_DELETE", + "RESMGR_OCS_CHREQ_CREATE", + "RESMGR_OCS_CHREQ_DELETE", + "RESMGR_OCS_CHREQ_START", + "RESMGR_OCS_CHREQ_STOP", + "RESMGR_OCS_SCHEDULER_INVOKED", + "RESMGR_OCS_CHREQ_GRANT", + "RESMGR_OCS_CHREQ_COMPLETE", + "RESMGR_OCS_NEXT_TSFTIME", + "RESMGR_OCS_TSF_TIMEOUT_US", + "RESMGR_OCS_CURR_CAT_WINDOW", + "RESMGR_OCS_CURR_CAT_WINDOW_REQ", + "RESMGR_OCS_CURR_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CHREQ_RESTART", + "RESMGR_OCS_CLEANUP_CH_ALLOCATORS", + "RESMGR_OCS_PURGE_CHREQ", + "RESMGR_OCS_CH_ALLOCATOR_FREE", + "RESMGR_OCS_RECOMPUTE_SCHEDULE", + "RESMGR_OCS_NEW_CAT_WINDOW_REQ", + "RESMGR_OCS_NEW_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CUR_CH_ALLOC", + "RESMGR_OCS_WIN_CH_ALLOC", + "RESMGR_OCS_SCHED_CH_CHANGE", + "RESMGR_OCS_CONSTRUCT_CAT_WIN", + "RESMGR_OCS_CHREQ_PREEMPTED", + "RESMGR_OCS_CH_SWITCH_REQ", + "RESMGR_OCS_CHANNEL_SWITCHED", + "RESMGR_OCS_CLEANUP_STALE_REQS", + "RESMGR_OCS_CHREQ_UPDATE", + "RESMGR_OCS_REG_NOA_NOTIF", + "RESMGR_OCS_DEREG_NOA_NOTIF", + "RESMGR_OCS_GEN_PERIODIC_NOA", + "RESMGR_OCS_RECAL_QUOTAS", + "RESMGR_OCS_GRANTED_QUOTA_STATS", + "RESMGR_OCS_ALLOCATED_QUOTA_STATS", + "RESMGR_OCS_REQ_QUOTA_STATS", + "RESMGR_OCS_TRACKING_TIME_FIRED", + "RESMGR_VC_ARBITRATE_ATTRIBUTES", + "RESMGR_OCS_LATENCY_STRICT_TIME_SLOT", + "RESMGR_OCS_CURR_TSF", + "RESMGR_OCS_QUOTA_REM", + "RESMGR_OCS_LATENCY_CASE_NO", + "RESMGR_OCS_WIN_CAT_DUR", + "RESMGR_VC_UPDATE_CUR_VC", + "RESMGR_VC_REG_UNREG_LINK", + "RESMGR_VC_PRINT_LINK", + "RESMGR_OCS_MISS_TOLERANCE", + "RESMGR_DYN_SCH_ALLOCRAM_SIZE", + "RESMGR_DYN_SCH_ENABLE", + "RESMGR_DYN_SCH_ACTIVE", + "RESMGR_DYN_SCH_CH_STATS_START", + "RESMGR_DYN_SCH_CH_SX_STATS", + "RESMGR_DYN_SCH_TOT_UTIL_PER", + "RESMGR_DYN_SCH_HOME_CH_QUOTA", + "RESMGR_OCS_REG_RECAL_QUOTA_NOTIF", + "RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF", + "RESMGR_DEFINITION_END" + }, + { + "VDEV_MGR_DEBID_DEFINITION_START", /* vdev Mgr */ + "VDEV_MGR_FIRST_BEACON_MISS_DETECTED", + "VDEV_MGR_FINAL_BEACON_MISS_DETECTED", + "VDEV_MGR_BEACON_IN_SYNC", + "VDEV_MGR_AP_KEEPALIVE_IDLE", + "VDEV_MGR_AP_KEEPALIVE_INACTIVE", + "VDEV_MGR_AP_KEEPALIVE_UNRESPONSIVE", + "VDEV_MGR_AP_TBTT_CONFIG", + "VDEV_MGR_FIRST_BCN_RECEIVED", + "VDEV_MGR_VDEV_START", + "VDEV_MGR_VDEV_UP", + "VDEV_MGR_PEER_AUTHORIZED", + "VDEV_MGR_OCS_HP_LP_REQ_POSTED", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP", + "VDEV_MGR_HP_START_TIME", + "VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE", + "VDEV_MGR_VDEV_PAUSE_FAIL", + "VDEV_MGR_GEN_PERIODIC_NOA", + "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP", + "VDEV_MGR_DEFINITION_END", + }, + { + "SCAN_START_COMMAND_FAILED", /* scan */ + "SCAN_STOP_COMMAND_FAILED", + "SCAN_EVENT_SEND_FAILED", + "SCAN_ENGINE_START", + "SCAN_ENGINE_CANCEL_COMMAND", + "SCAN_ENGINE_STOP_DUE_TO_TIMEOUT", + "SCAN_EVENT_SEND_TO_HOST", + "SCAN_FWLOG_EVENT_ADD", + "SCAN_FWLOG_EVENT_REM", + "SCAN_FWLOG_EVENT_PREEMPTED", + "SCAN_FWLOG_EVENT_RESTARTED", + "SCAN_FWLOG_EVENT_COMPLETED", + }, + { + "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl*/ + "RATECTRL_DBGID_ASSOC", + "RATECTRL_DBGID_NSS_CHANGE", + "RATECTRL_DBGID_CHAINMASK_ERR", + "RATECTRL_DBGID_UNEXPECTED_FRAME", + "RATECTRL_DBGID_WAL_RCQUERY", + "RATECTRL_DBGID_WAL_RCUPDATE", + "RATECTRL_DBGID_GTX_UPDATE", + "RATECTRL_DBGID_DEFINITION_END" + }, + { + "AP_PS_DBGID_DEFINITION_START", + "AP_PS_DBGID_UPDATE_TIM", + "AP_PS_DBGID_PEER_STATE_CHANGE", + "AP_PS_DBGID_PSPOLL", + "AP_PS_DBGID_PEER_CREATE", + "AP_PS_DBGID_PEER_DELETE", + "AP_PS_DBGID_VDEV_CREATE", + "AP_PS_DBGID_VDEV_DELETE", + "AP_PS_DBGID_SYNC_TIM", + "AP_PS_DBGID_NEXT_RESPONSE", + "AP_PS_DBGID_START_SP", + "AP_PS_DBGID_COMPLETED_EOSP", + "AP_PS_DBGID_TRIGGER", + "AP_PS_DBGID_DUPLICATE_TRIGGER", + "AP_PS_DBGID_UAPSD_RESPONSE", + "AP_PS_DBGID_SEND_COMPLETE", + "AP_PS_DBGID_SEND_N_COMPLETE", + "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA", + "AP_PS_DBGID_DELIVER_CAB", + }, + { + "" /* Block Ack */ + }, + /* Mgmt TxRx */ + { + "MGMT_TXRX_DBGID_DEFINITION_START", + "MGMT_TXRX_FORWARD_TO_HOST", + "MGMT_TXRX_DBGID_DEFINITION_END", + }, + { /* Data TxRx */ + "DATA_TXRX_DBGID_DEFINITION_START", + "DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO", + "DATA_TXRX_DBGID_DEFINITION_END", + }, + { "" /* HTT */ + }, + { "" /* HOST */ + }, + { "" /* BEACON */ + "BEACON_EVENT_SWBA_SEND_FAILED", + "BEACON_EVENT_EARLY_RX_BMISS_STATUS", + "BEACON_EVENT_EARLY_RX_SLEEP_SLOP", + "BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT", + "BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM", + "BEACON_EVENT_EARLY_RX_CLK_DRIFT", + "BEACON_EVENT_EARLY_RX_AP_DRIFT", + "BEACON_EVENT_EARLY_RX_BCN_TYPE", + }, + { /* Offload Mgr */ + "OFFLOAD_MGR_DBGID_DEFINITION_START", + "OFFLOADMGR_REGISTER_OFFLOAD", + "OFFLOADMGR_DEREGISTER_OFFLOAD", + "OFFLOADMGR_NO_REG_DATA_HANDLERS", + "OFFLOADMGR_NO_REG_EVENT_HANDLERS", + "OFFLOADMGR_REG_OFFLOAD_FAILED", + "OFFLOADMGR_DBGID_DEFINITION_END", + }, + { + "WAL_DBGID_DEFINITION_START", + "WAL_DBGID_FAST_WAKE_REQUEST", + "WAL_DBGID_FAST_WAKE_RELEASE", + "WAL_DBGID_SET_POWER_STATE", + "WAL_DBGID_MISSING", + "WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET", + "WAL_DBGID_CHANNEL_CHANGE", + "WAL_DBGID_VDEV_START", + "WAL_DBGID_VDEV_STOP", + "WAL_DBGID_VDEV_UP", + "WAL_DBGID_VDEV_DOWN", + "WAL_DBGID_SW_WDOG_RESET", + "WAL_DBGID_TX_SCH_REGISTER_TIDQ", + "WAL_DBGID_TX_SCH_UNREGISTER_TIDQ", + "WAL_DBGID_TX_SCH_TICKLE_TIDQ", + "WAL_DBGID_XCESS_FAILURES", + "WAL_DBGID_AST_ADD_WDS_ENTRY", + "WAL_DBGID_AST_DEL_WDS_ENTRY", + "WAL_DBGID_AST_WDS_ENTRY_PEER_CHG", + "WAL_DBGID_AST_WDS_SRC_LEARN_FAIL", + "WAL_DBGID_STA_KICKOUT", + "WAL_DBGID_BAR_TX_FAIL", + "WAL_DBGID_BAR_ALLOC_FAIL", + "WAL_DBGID_LOCAL_DATA_TX_FAIL", + "WAL_DBGID_SECURITY_PM4_QUEUED", + "WAL_DBGID_SECURITY_GM1_QUEUED", + "WAL_DBGID_SECURITY_PM4_SENT", + "WAL_DBGID_SECURITY_ALLOW_DATA", + "WAL_DBGID_SECURITY_UCAST_KEY_SET", + "WAL_DBGID_SECURITY_MCAST_KEY_SET", + "WAL_DBGID_SECURITY_ENCR_EN", + "WAL_DBGID_BB_WDOG_TRIGGERED", + "WAL_DBGID_RX_LOCAL_BUFS_LWM", + "WAL_DBGID_RX_LOCAL_DROP_LARGE_MGMT", + "WAL_DBGID_VHT_ILLEGAL_RATE_PHY_ERR_DETECTED", + "WAL_DBGID_DEV_RESET", + "WAL_DBGID_TX_BA_SETUP", + "WAL_DBGID_RX_BA_SETUP", + "WAL_DBGID_DEV_TX_TIMEOUT", + "WAL_DBGID_DEV_RX_TIMEOUT", + "WAL_DBGID_STA_VDEV_XRETRY", + "WAL_DBGID_DCS", + "WAL_DBGID_MGMT_TX_FAIL", + "WAL_DBGID_SET_M4_SENT_MANUALLY", + "WAL_DBGID_PROCESS_4_WAY_HANDSHAKE", + "WAL_DBGID_WAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DISCARD", + "WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS", + "WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS", + "WAL_DBGID_RESET_PCU_CYCLE_CNT", + "WAL_DBGID_SETUP_RSSI_INTERRUPTS", + "WAL_DBGID_BRSSI_CONFIG", + "WAL_DBGID_CURRENT_BRSSI_AVE", + "WAL_DBGID_BCN_TX_COMP", + "WAL_DBGID_SET_HW_CHAINMASK", + "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL", + "WAL_DBGID_GET_HW_CHAINMASK", + "WAL_DBGID_SMPS_DISABLE", + "WAL_DBGID_SMPS_ENABLE_HW_CNTRL", + "WAL_DBGID_SMPS_SWSEL_CHAINMASK", + "WAL_DBGID_DEFINITION_END", + }, + { + "" /* DE */ + }, + { + "" /* pcie lp */ + }, + { + /* RTT */ + "RTT_CALL_FLOW", + "RTT_REQ_SUB_TYPE", + "RTT_MEAS_REQ_HEAD", + "RTT_MEAS_REQ_BODY", + "", + "", + "RTT_INIT_GLOBAL_STATE", + "", + "RTT_REPORT", + "", + "RTT_ERROR_REPORT", + "RTT_TIMER_STOP", + "RTT_SEND_TM_FRAME", + "RTT_V3_RESP_CNT", + "RTT_V3_RESP_FINISH", + "RTT_CHANNEL_SWITCH_REQ", + "RTT_CHANNEL_SWITCH_GRANT", + "RTT_CHANNEL_SWITCH_COMPLETE", + "RTT_CHANNEL_SWITCH_PREEMPT", + "RTT_CHANNEL_SWITCH_STOP", + "RTT_TIMER_START", + }, + { /* RESOURCE */ + "RESOURCE_DBGID_DEFINITION_START", + "RESOURCE_PEER_ALLOC", + "RESOURCE_PEER_FREE", + "RESOURCE_PEER_ALLOC_WAL_PEER", + "RESOURCE_DBGID_DEFINITION_END", + }, + { /* DCS */ + "WLAN_DCS_DBGID_INIT", + "WLAN_DCS_DBGID_WMI_CWINT", + "WLAN_DCS_DBGID_TIMER", + "WLAN_DCS_DBGID_CMDG", + "WLAN_DCS_DBGID_CMDS", + "WLAN_DCS_DBGID_DINIT" + }, + { /* CACHEMGR */ + "" + }, + { /* ANI */ + "ANI_DBGID_POLL", + "ANI_DBGID_CONTROL", + "ANI_DBGID_OFDM_PARAMS", + "ANI_DBGID_CCK_PARAMS", + "ANI_DBGID_RESET", + "ANI_DBGID_RESTART", + "ANI_DBGID_OFDM_LEVEL", + "ANI_DBGID_CCK_LEVEL", + "ANI_DBGID_FIRSTEP", + "ANI_DBGID_CYCPWR", + "ANI_DBGID_MRC_CCK", + "ANI_DBGID_SELF_CORR_LOW", + "ANI_DBGID_ENABLE", + "ANI_DBGID_CURRENT_LEVEL", + "ANI_DBGID_POLL_PERIOD", + "ANI_DBGID_LISTEN_PERIOD", + "ANI_DBGID_OFDM_LEVEL_CFG", + "ANI_DBGID_CCK_LEVEL_CFG" + }, + { + "P2P_DBGID_DEFINITION_START", + "P2P_DEV_REGISTER", + "P2P_HANDLE_NOA", + "P2P_UPDATE_SCHEDULE_OPPS", + "P2P_UPDATE_SCHEDULE", + "P2P_UPDATE_START_TIME", + "P2P_UPDATE_START_TIME_DIFF_TSF32", + "P2P_UPDATE_START_TIME_FINAL", + "P2P_SETUP_SCHEDULE_TIMER", + "P2P_PROCESS_SCHEDULE_AFTER_CALC", + "P2P_PROCESS_SCHEDULE_STARTED_TIMER", + "P2P_CALC_SCHEDULES_FIRST_CALL_ALL_NEXT_EVENT", + "P2P_CALC_SCHEDULES_FIRST_VALUE", + "P2P_CALC_SCHEDULES_EARLIEST_NEXT_EVENT", + "P2P_CALC_SCHEDULES_SANITY_COUNT", + "P2P_CALC_SCHEDULES_CALL_ALL_NEXT_EVENT_FROM_WHILE_LOOP", + "P2P_CALC_SCHEDULES_TIMEOUT_1", + "P2P_CALC_SCHEDULES_TIMEOUT_2", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_EXPIRED", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_ACTIVE", + "P2P_FIND_NEXT_EVENT_REQ_NOT_STARTED", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE_NON_PERIODIC", + "P2P_FIND_NEXT_EVENT_IN_MID_OF_NOA", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE", + "P2P_SCHEDULE_TIMEOUT", + "P2P_CALC_SCHEDULES_ENTER", + "P2P_PROCESS_SCHEDULE_ENTER", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_AFTER_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_BEFORE_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_ENTER", + "P2P_FIND_NEXT_EVENT_ENTER", + "P2P_NOA_GO_PRESENT", + "P2P_NOA_GO_ABSENT", + "P2P_GO_NOA_NOTIF", + "P2P_GO_TBTT_OFFSET", + "P2P_GO_GET_NOA_INFO", + "P2P_GO_ADD_ONE_SHOT_NOA", + "P2P_GO_GET_NOA_IE", + "P2P_GO_BCN_TX_COMP", + "P2P_DBGID_DEFINITION_END", + }, + { + "CSA_DBGID_DEFINITION_START", + "CSA_OFFLOAD_POOL_INIT", + "CSA_OFFLOAD_REGISTER_VDEV", + "CSA_OFFLOAD_DEREGISTER_VDEV", + "CSA_DEREGISTER_VDEV_ERROR", + "CSA_OFFLOAD_BEACON_RECEIVED", + "CSA_OFFLOAD_BEACON_CSA_RECV", + "CSA_OFFLOAD_CSA_RECV_ERROR_IE", + "CSA_OFFLOAD_CSA_TIMER_ERROR", + "CSA_OFFLOAD_CSA_TIMER_EXP", + "CSA_OFFLOAD_WMI_EVENT_ERROR", + "CSA_OFFLOAD_WMI_EVENT_SENT", + "CSA_OFFLOAD_WMI_CHANSWITCH_RECV", + "CSA_DBGID_DEFINITION_END", + }, + { /* NLO offload */ + "" + }, + { + "WLAN_CHATTER_DBGID_DEFINITION_START", + "WLAN_CHATTER_ENTER", + "WLAN_CHATTER_EXIT", + "WLAN_CHATTER_FILTER_HIT", + "WLAN_CHATTER_FILTER_MISS", + "WLAN_CHATTER_FILTER_FULL", + "WLAN_CHATTER_FILTER_TM_ADJ", + "WLAN_CHATTER_BUFFER_FULL", + "WLAN_CHATTER_TIMEOUT", + "WLAN_CHATTER_DBGID_DEFINITION_END", + }, + { + "WOW_DBGID_DEFINITION_START", + "WOW_ENABLE_CMDID", + "WOW_RECV_DATA_PKT", + "WOW_WAKE_HOST_DATA", + "WOW_RECV_MGMT", + "WOW_WAKE_HOST_MGMT", + "WOW_RECV_EVENT", + "WOW_WAKE_HOST_EVENT", + "WOW_INIT", + "WOW_RECV_MAGIC_PKT", + "WOW_RECV_BITMAP_PATTERN", + "WOW_DBGID_DEFINITION_END", + }, + { /* WAL_VDEV */ + "" + }, + { /* WAL_PDEV */ + "" + }, + { /* TEST */ + "TP_CHANGE_CHANNEL", + "TP_LOCAL_SEND", + }, + { /* STA SMPS */ + "STA_SMPS_DBGID_DEFINITION_START", + "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE", + "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_CREATE_STA_INSTANCE", + "STA_SMPS_DBGID_DELETE_STA_INSTANCE", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP", + "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME", + "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE", + "SMPS_DBGID_DEFINITION_END", + }, + { /* SWBMISS */ + "SWBMISS_DBGID_DEFINITION_START", + "SWBMISS_ENABLED", + "SWBMISS_DISABLED", + "SWBMISS_DBGID_DEFINITION_END", + }, + { /* WMMAC */ + "" + }, + { /* TDLS */ + "TDLS_DBGID_DEFINITION_START", + "TDLS_DBGID_VDEV_CREATE", + "TDLS_DBGID_VDEV_DELETE", + "TDLS_DBGID_ENABLED_PASSIVE", + "TDLS_DBGID_ENABLED_ACTIVE", + "TDLS_DBGID_DISABLED", + "TDLS_DBGID_CONNTRACK_TIMER", + "TDLS_DBGID_WAL_SET", + "TDLS_DBGID_WAL_GET", + "TDLS_DBGID_WAL_PEER_UPDATE_SET", + "TDLS_DBGID_WAL_PEER_UPDATE_EVT", + "TDLS_DBGID_WAL_VDEV_CREATE", + "TDLS_DBGID_WAL_VDEV_DELETE", + "TDLS_DBGID_WLAN_EVENT", + "TDLS_DBGID_WLAN_PEER_UPDATE_SET", + "TDLS_DBGID_PEER_EVT_DRP_THRESH", + "TDLS_DBGID_PEER_EVT_DRP_RATE", + "TDLS_DBGID_PEER_EVT_DRP_RSSI", + "TDLS_DBGID_PEER_EVT_DISCOVER", + "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", + }, + { /* HB */ + "WLAN_HB_DBGID_DEFINITION_START", + "WLAN_HB_DBGID_INIT", + "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_TCP_SEND_FAIL", + "WLAN_HB_DBGID_BSS_PEER_NULL", + "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_UDP_SEND_FAIL", + "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM", + "WLAN_HB_DBGID_WMI_CMD_INVALID_OP", + "WLAN_HB_DBGID_WOW_NOT_ENTERED", + "WLAN_HB_DBGID_ALLOC_SESS_FAIL", + "WLAN_HB_DBGID_CTX_NULL", + "WLAN_HB_DBGID_CHKSUM_ERR", + "WLAN_HB_DBGID_UDP_TX", + "WLAN_HB_DBGID_TCP_TX", + "WLAN_HB_DBGID_DEFINITION_END", + }, + { /* TXBF */ + "TXBFEE_DBGID_START", + "TXBFEE_DBGID_NDPA_RECEIVED", + "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE", + "TXBFER_DBGID_SEND_NDPA", + "TXBFER_DBGID_GET_NDPA_BUF_FAIL", + "TXBFER_DBGID_SEND_NDPA_FAIL", + "TXBFER_DBGID_GET_NDP_BUF_FAIL", + "TXBFER_DBGID_SEND_NDP_FAIL", + "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL", + "TXBFER_DBGID_SEND_BRPOLL_FAIL", + "TXBFER_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H", + "TXBFEE_DBGID_UPLOADH_CV_TAG", + "TXBFEE_DBGID_UPLOADH_H_TAG", + "TXBFEE_DBGID_CAPTUREH_RECEIVED", + "TXBFEE_DBGID_PACKET_IS_STEERED", + "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL", + "TXBFEE_DBGID_END", + }, + { /*BATCH SCAN*/ + }, + { /*THERMAL MGR*/ + "THERMAL_MGR_DBGID_DEFINITION_START", + "THERMAL_MGR_NEW_THRESH", + "THERMAL_MGR_THRESH_CROSSED", + "THERMAL_MGR_DBGID_DEFINITION END", + }, + { /* WLAN_MODULE_PHYERR_DFS */ + "" + }, + { + /* WLAN_MODULE_RMC */ + "RMC_DBGID_DEFINITION_START", + "RMC_CREATE_INSTANCE", + "RMC_DELETE_INSTANCE", + "RMC_LDR_SEL", + "RMC_NO_LDR", + "RMC_LDR_NOT_SEL", + "RMC_LDR_INF_SENT", + "RMC_PEER_ADD", + "RMC_PEER_DELETE", + "RMC_PEER_UNKNOWN", + "RMC_SET_MODE", + "RMC_SET_ACTION_PERIOD", + "RMC_ACRION_FRAME_RX", + "RMC_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_STATS */ + "WLAN_STATS_DBGID_DEFINITION_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_VDEV_EN_DIS", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_END", + "WLAN_STATS_DBGID_EST_LINKSPEED_CALC", + "WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN", + "WLAN_STATS_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_NAN */ + }, + { + /* WLAN_MODULE_IBSS_PWRSAVE */ + "IBSS_PS_DBGID_DEFINITION_START", + "IBSS_PS_DBGID_PEER_CREATE", + "IBSS_PS_DBGID_PEER_DELETE", + "IBSS_PS_DBGID_VDEV_CREATE", + "IBSS_PS_DBGID_VDEV_DELETE", + "IBSS_PS_DBGID_VDEV_EVENT", + "IBSS_PS_DBGID_PEER_EVENT", + "IBSS_PS_DBGID_DELIVER_CAB", + "IBSS_PS_DBGID_DELIVER_UC_DATA", + "IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR", + "IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_NULL_TX_COMPLETION", + "IBSS_PS_DBGID_ATIM_TIMER_START", + "IBSS_PS_DBGID_UC_ATIM_SEND", + "IBSS_PS_DBGID_BC_ATIM_SEND", + "IBSS_PS_DBGID_UC_TIMEOUT", + "IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED", + "IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED", + "IBSS_PS_DBGID_SET_PARAM", + "IBSS_PS_DBGID_HOST_TX_PAUSE", + "IBSS_PS_DBGID_HOST_TX_UNPAUSE", + "IBSS_PS_DBGID_PS_DESC_BIN_HWM", + "IBSS_PS_DBGID_PS_DESC_BIN_LWM", + "IBSS_PS_DBGID_PS_KICKOUT_PEER", + "IBSS_PS_DBGID_SET_PEER_PARAM", + "IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH", + }, + { + /* HIF UART Interface DBGIDs */ + "HIF_UART_DBGID_START", + "HIF_UART_DBGID_POWER_STATE", + "HIF_UART_DBGID_TXRX_FLOW", + "HIF_UART_DBGID_TXRX_CTRL_CHAR", + "HIF_UART_DBGID_TXRX_BUF_DUMP", + }, + { + /* LPI */ + "" + }, + { + /* EXTSCAN DBGIDs */ + "EXTSCAN_START", + "EXTSCAN_STOP", + "EXTSCAN_CLEAR_ENTRY_CONTENT", + "EXTSCAN_GET_FREE_ENTRY_SUCCESS", + "EXTSCAN_GET_FREE_ENTRY_INCONSISTENT", + "EXTSCAN_GET_FREE_ENTRY_NO_MORE_ENTRIES", + "EXTSCAN_CREATE_ENTRY_SUCCESS", + "EXTSCAN_CREATE_ENTRY_ERROR", + "EXTSCAN_SEARCH_SCAN_ENTRY_QUEUE", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_FOUND", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_NOT_FOUND", + "EXTSCAN_ADD_ENTRY", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT_FAILED", + "EXTSCAN_BUCKET_START_SCAN_CYCLE", + "EXTSCAN_BUCKET_PERIODIC_TIMER", + "EXTSCAN_SEND_START_STOP_EVENT", + "EXTSCAN_NOTIFY_WLAN_CHANGE", + "EXTSCAN_NOTIFY_WLAN_HOTLIST_MATCH", + "EXTSCAN_MAIN_RECEIVED_FRAME", + "EXTSCAN_MAIN_NO_SSID_IE", + "EXTSCAN_MAIN_MALFORMED_FRAME", + "EXTSCAN_FIND_BSSID_BY_REFERENCE", + "EXTSCAN_FIND_BSSID_BY_REFERENCE_ERROR", + "EXTSCAN_NOTIFY_TABLE_USAGE", + "EXTSCAN_FOUND_RSSI_ENTRY", + "EXTSCAN_BSSID_FOUND_RSSI_SAMPLE", + "EXTSCAN_BSSID_ADDED_RSSI_SAMPLE", + "EXTSCAN_BSSID_REPLACED_RSSI_SAMPLE", + "EXTSCAN_BSSID_TRANSFER_CURRENT_SAMPLES", + "EXTSCAN_BUCKET_PROCESS_SCAN_EVENT", + "EXTSCAN_BUCKET_CANNOT_FIND_BUCKET", + "EXTSCAN_START_SCAN_REQUEST_FAILED", + "EXTSCAN_BUCKET_STOP_CURRENT_SCANS", + "EXTSCAN_BUCKET_SCAN_STOP_REQUEST", + "EXTSCAN_BUCKET_PERIODIC_TIMER_ERROR", + "EXTSCAN_BUCKET_START_OPERATION", + "EXTSCAN_START_INTERNAL_ERROR", + "EXTSCAN_NOTIFY_HOTLIST_MATCH", + "EXTSCAN_CONFIG_HOTLIST_TABLE", + "EXTSCAN_CONFIG_WLAN_CHANGE_TABLE", + }, + { /* UNIT_TEST */ + "UNIT_TEST_GEN", + }, + { /* MLME */ + "MLME_DEBUG_CMN", + "MLME_IF", + "MLME_AUTH", + "MLME_REASSOC", + "MLME_DEAUTH", + "MLME_DISASSOC", + "MLME_ROAM", + "MLME_RETRY", + "MLME_TIMER", + "MLME_FRMPARSE", + }, + { /*SUPPLICANT */ + "SUPPL_INIT", + "SUPPL_RECV_EAPOL", + "SUPPL_RECV_EAPOL_TIMEOUT", + "SUPPL_SEND_EAPOL", + "SUPPL_MIC_MISMATCH", + "SUPPL_FINISH", + }, +}; + +static char * +dbglog_get_msg(A_UINT32 moduleid, A_UINT32 debugid) +{ + static char unknown_str[64]; + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS) { + char *str = DBG_MSG_ARR[moduleid][debugid]; + if (str && str[0] != '\0') { + return str; + } + } + + snprintf(unknown_str, sizeof(unknown_str), + "UNKNOWN %u:%u", + moduleid, debugid); + + return unknown_str; +} + +void +dbglog_printf( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + printf(DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, vap_id); + } else { + printf(DBGLOG_PRINT_PREFIX "[%u] ", timestamp); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + printf("%s\n", buf); +} + +void +dbglog_printf_no_line_break( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + printf(DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, vap_id); + } else { + printf(DBGLOG_PRINT_PREFIX "[%u] ", timestamp); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + printf("%s", buf); +} + +#define USE_NUMERIC 0 + +A_BOOL +dbglog_default_print_handler(A_UINT32 mod_id, A_UINT16 vap_id, A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + int i; + + if (vap_id < DBGLOG_MAX_VDEVID) { + printf(DBGLOG_PRINT_PREFIX "[%u] vap-%u %s ( ", timestamp, vap_id, dbglog_get_msg(mod_id, dbg_id)); + } else { + printf(DBGLOG_PRINT_PREFIX "[%u] %s ( ", timestamp, dbglog_get_msg(mod_id, dbg_id)); + } + + for (i = 0; i < numargs; i++) { +#if USE_NUMERIC + printf("%u", args[i]); +#else + printf("%#x", args[i]); +#endif + if ((i + 1) < numargs) { + printf(", "); + } + } + printf(" )\n"); + + return TRUE; +} + +static int +dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped) +{ + A_UINT32 count=0; + A_UINT32 timestamp=0; + A_UINT32 debugid=0; + A_UINT32 moduleid=0; + A_UINT16 vapid=0; + A_UINT16 numargs=0; + A_UINT32 *buffer; + A_UINT32 length = len >> 2; + + buffer = (A_UINT32 *)datap; + length = (len >> 2); + + if(dropped > 0) + printf("%d log buffer got dropped in firmware \n", dropped); + + while ((count + 2) < length) { + + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + debugid = DBGLOG_GET_DBGID(buffer[count+1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count+1]); + vapid = DBGLOG_GET_VDEVID(buffer[count+1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count+1]); + + if ((count + 2 + numargs) > length) + return 0; + + if (moduleid >= WLAN_MODULE_ID_MAX) + return 0; + + if (mod_print[moduleid] == NULL) { + /* No module specific log registered use the default handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + } else { + if(!(mod_print[moduleid](moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)))) { + /* The message is not handled by the module specific handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header*/ + } + /* Always returns zero */ + return (0); +} + +void +dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn) +{ + if (!mod_print[mod_id]) { + mod_print[mod_id] = printfn; + } else { + printf("module print is already registered for this module %d\n", + mod_id); + } +} + +void +dbglog_sm_print( + A_UINT32 timestamp, + A_UINT16 vap_id, + A_UINT16 numargs, + A_UINT32 *args, + const char *module_prefix, + const char *states[], A_UINT32 num_states, + const char *events[], A_UINT32 num_events) +{ + A_UINT8 type, arg1, arg2, arg3; + A_UINT32 extra, extra2, extra3; + + if (numargs != 4) { + return; + } + + type = (args[0] >> 24) & 0xff; + arg1 = (args[0] >> 16) & 0xff; + arg2 = (args[0] >> 8) & 0xff; + arg3 = (args[0] >> 0) & 0xff; + + extra = args[1]; + extra2 = args[2]; + extra3 = args[3]; + + switch (type) { + case 0: /* state transition */ + if (arg1 < num_states && arg2 < num_states) { + dbglog_printf(timestamp, vap_id, "%s: %s => %s (%#x, %#x, %#x)", + module_prefix, states[arg1], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u => %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 1: /* dispatch event */ + if (arg1 < num_states && arg2 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: %s < %s (%#x, %#x, %#x)", + module_prefix, states[arg1], events[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u < %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 2: /* warning */ + switch (arg1) { + case 0: /* unhandled event */ + if (arg2 < num_states && arg3 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %s in state %s (%#x, %#x, %#x)", + module_prefix, events[arg3], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %u in state %u (%#x, %#x, %#x)", + module_prefix, arg3, arg2, extra, extra2, extra3); + } + break; + default: + break; + + } + break; + } +} + +A_BOOL +dbglog_sta_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "ACTIVE", + "SLEEP_TXQ_FLUSH", + "SLEEP_TX_SENT", + "PAUSE", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TXQ_FLUSH", + "ACTIVE_TX_SENT", + "PAUSE_TXQ_FLUSH", + "PAUSE_TX_SENT", + "IDLE_TXQ_FLUSH", + "IDLE_TX_SENT", + }; + + static const char *events[] = { + "START", + "STOP", + "PAUSE", + "UNPAUSE", + "TIM", + "DTIM", + "SEND_COMPLETE", + "PRE_SEND", + "RX", + "HWQ_EMPTY", + "PAUSE_TIMEOUT", + "TXRX_INACTIVITY_TIMEOUT", + "PSPOLL_TIMEOUT", + "UAPSD_TIMEOUT", + "DELAYED_SLEEP_TIMEOUT", + "SEND_N_COMPLETE", + "TIDQ_PAUSE_COMPLETE", + "SEND_PSPOLL", + "SEND_SPEC_PSPOLL", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case PS_STA_PM_ARB_REQUEST: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, "PM ARB request flags=%x, last_time=%x %s: %s", + args[1], args[2], dbglog_get_module_str(args[0]), args[3] ? "SLEEP" : "WAKE"); + } + break; + case PS_STA_DELIVER_EVENT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, "STA PS: %s %s", + (args[0] == 0 ? "PAUSE_COMPLETE" : + (args[0] == 1 ? "UNPAUSE_COMPLETE" : + (args[0] == 2 ? "SLEEP" : + (args[0] == 3 ? "AWAKE" : "UNKNOWN")))), + (args[1] == 0 ? "SUCCESS" : + (args[1] == 1 ? "TXQ_FLUSH_TIMEOUT" : + (args[1] == 2 ? "NO_ACK" : + (args[1] == 3 ? "RX_LEAK_TIMEOUT" : + (args[1] == 4 ? "PSPOLL_UAPSD_BUSY_TIMEOUT" : "UNKNOWN")))))); + } + break; + case PS_STA_PSPOLL_SEQ_DONE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, "STA PS poll: queue=%u comp=%u rsp=%u rsp_dur=%u fc=%x qos=%x %s", + args[0], args[1], args[2], args[3], + (args[4] >> 16) & 0xffff, + (args[4] >> 8) & 0xff, + (args[4] & 0xff) == 0 ? "SUCCESS" : + (args[4] & 0xff) == 1 ? "NO_ACK" : + (args[4] & 0xff) == 2 ? "DROPPED" : + (args[4] & 0xff) == 3 ? "FILTERED" : + (args[4] & 0xff) == 4 ? "RSP_TIMEOUT" : "UNKNOWN"); + } + break; + case PS_STA_COEX_MODE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "STA PS COEX MODE %s", + args[0] ? "ENABLED" : "DISABLED"); + } + break; + case PS_STA_PSPOLL_ALLOW: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "STA PS-Poll %s flags=%x time=%u", + args[0] ? "ALLOW" : "DISALLOW", args[1], args[2]); + } + break; + case PS_STA_SET_PARAM: + if (numargs == 2) { + struct { + char *name; + int is_time_param; + } params[] = { + { "MAX_SLEEP_ATTEMPTS", 0 }, + { "DELAYED_SLEEP", 1 }, + { "TXRX_INACTIVITY", 1 }, + { "MAX_TX_BEFORE_WAKE", 0 }, + { "UAPSD_TIMEOUT", 1 }, + { "UAPSD_CONFIG", 0 }, + { "PSPOLL_RESPONSE_TIMEOUT", 1 }, + { "MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "RX_WAKE_POLICY", 0 }, + { "DELAYED_PAUSE_RX_LEAK", 1 }, + { "TXRX_INACTIVITY_BLOCKED_RETRY", 1 }, + { "SPEC_WAKE_INTERVAL", 1 }, + { "MAX_SPEC_NODATA_PSPOLL", 0 }, + { "ESTIMATED_PSPOLL_RESP_TIME", 1 }, + { "QPOWER_MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "QPOWER_ENABLE", 0 }, + }; + A_UINT32 param = args[0]; + A_UINT32 value = args[1]; + + if (param < ARRAY_LENGTH(params)) { + if (params[param].is_time_param) { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %u (us)", + params[param].name, value); + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %#x", + params[param].name, value); + } + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %x => %#x", + param, value); + } + } + break; + case PS_STA_SPECPOLL_TIMER_STARTED: + dbglog_printf(timestamp, vap_id, "SPEC Poll Timer Started: Beacon time Remaining:%d wakeup interval:%d", args[0], args[1]); + break; + case PS_STA_SPECPOLL_TIMER_STOPPED: + dbglog_printf(timestamp, vap_id, + "SPEC Poll Timer Stopped"); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_ratectrl_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case RATECTRL_DBGID_ASSOC: + dbglog_printf(timestamp, vap_id, "RATE: ChainMask %d, phymode %d, ni_flags 0x%08x, vht_mcs_set 0x%04x, ht_mcs_set 0x%04x", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_NSS_CHANGE: + dbglog_printf(timestamp, vap_id, "RATE: NEW NSS %d\n", args[0]); + break; + case RATECTRL_DBGID_CHAINMASK_ERR: + dbglog_printf(timestamp, vap_id, "RATE: Chainmask ERR %d %d %d\n", + args[0], args[1], args[2]); + break; + case RATECTRL_DBGID_UNEXPECTED_FRAME: + dbglog_printf(timestamp, vap_id, "RATE: WARN1: rate %d flags 0x%08x\n", args[0], args[1]); + break; + case RATECTRL_DBGID_WAL_RCQUERY: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcquery [rix1 %d rix2 %d rix3 %d proberix %d ppduflag 0x%x] ", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_WAL_RCUPDATE: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ", + args[0], args[1]); + break; + case RATECTRL_DBGID_GTX_UPDATE: + { + switch (args[0]) { + case 255: + dbglog_printf(timestamp, vap_id, "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ", + args[1] >> 8, args[1] & 0xff, args[2], args[3], args[4]); + break; + case 254: + dbglog_printf(timestamp, vap_id, "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ", + args[1], args[2], args[3], args[4]); + break; + default: + dbglog_printf(timestamp, vap_id, "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ", + args[0], args[1], args[2], args[3], args[4], args[5]); + } + } + break; + } + return TRUE; +} + +A_BOOL dbglog_ani_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case ANI_DBGID_ENABLE: + dbglog_printf(timestamp, vap_id, + "ANI Enable: %d", args[0]); + break; + case ANI_DBGID_POLL: + dbglog_printf(timestamp, vap_id, + "ANI POLLING: AccumListenTime %d ListenTime %d ofdmphyerr %d cckphyerr %d", + args[0], args[1], args[2],args[3]); + break; + case ANI_DBGID_RESTART: + dbglog_printf(timestamp, vap_id,"ANI Restart"); + break; + case ANI_DBGID_CURRENT_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI CURRENT LEVEL ofdm level %d cck level %d",args[0],args[1]); + break; + case ANI_DBGID_OFDM_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE ofdm level %d firstep %d firstep_low %d cycpwr_thr %d self_corr_low %d", + args[0], args[1],args[2],args[3],args[4]); + break; + case ANI_DBGID_CCK_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE cck level %d firstep %d firstep_low %d mrc_cck %d", + args[0],args[1],args[2],args[3]); + break; + case ANI_DBGID_CONTROL: + dbglog_printf(timestamp, vap_id, + "ANI CONTROL ofdmlevel %d ccklevel %d\n", + args[0]); + + break; + case ANI_DBGID_OFDM_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI ofdm_control firstep %d cycpwr %d\n", + args[0],args[1]); + break; + case ANI_DBGID_CCK_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI cck_control mrc_cck %d barker_threshold %d\n", + args[0],args[1]); + break; + case ANI_DBGID_RESET: + dbglog_printf(timestamp, vap_id, + "ANI resetting resetflag %d resetCause %8x channel index %d", + args[0],args[1],args[2]); + break; + case ANI_DBGID_SELF_CORR_LOW: + dbglog_printf(timestamp, vap_id,"ANI self_corr_low %d",args[0]); + break; + case ANI_DBGID_FIRSTEP: + dbglog_printf(timestamp, vap_id,"ANI firstep %d firstep_low %d", + args[0],args[1]); + break; + case ANI_DBGID_MRC_CCK: + dbglog_printf(timestamp, vap_id,"ANI mrc_cck %d",args[0]); + break; + case ANI_DBGID_CYCPWR: + dbglog_printf(timestamp, vap_id,"ANI cypwr_thresh %d",args[0]); + break; + case ANI_DBGID_POLL_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure poll period to %d",args[0]); + break; + case ANI_DBGID_LISTEN_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure listen period to %d",args[0]); + break; + case ANI_DBGID_OFDM_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure ofdm level to %d",args[0]); + break; + case ANI_DBGID_CCK_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure cck level to %d",args[0]); + break; + default: + dbglog_printf(timestamp, vap_id,"ANI arg1 %d arg2 %d arg3 %d", + args[0],args[1],args[2]); + break; + } + return TRUE; +} + +A_BOOL +dbglog_ap_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case AP_PS_DBGID_UPDATE_TIM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: TIM update AID=%u %s", + args[0], args[1] ? "set" : "clear"); + } + break; + case AP_PS_DBGID_PEER_STATE_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u power save %s", + args[0], args[1] ? "enabled" : "disabled"); + } + break; + case AP_PS_DBGID_PSPOLL: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u pspoll response tid=%u flags=%x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_PEER_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: create peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_PEER_DELETE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: delete peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_VDEV_CREATE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev create"); + break; + case AP_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev delete"); + break; + case AP_PS_DBGID_SYNC_TIM: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u advertised=%#x buffered=%#x", args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_NEXT_RESPONSE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u select next response %s%s%s", args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending usp) " : "", + args[3] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_START_SP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u START SP tsf=%#x (%u)", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_COMPLETED_EOSP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u EOSP eosp_tsf=%#x trigger_tsf=%#x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u TRIGGER tsf=%#x %s%s", args[0], args[1], + args[2] ? "(usp active) " : "", + args[3] ? "(send_n in progress)" : ""); + } + break; + case AP_PS_DBGID_DUPLICATE_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u DUP TRIGGER tsf=%#x seq=%u ac=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_UAPSD_RESPONSE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u UAPSD response tid=%u, n_mpdu=%u flags=%#x max_sp=%u current_sp=%u", + args[0], args[1], args[2], args[3], (args[4] >> 16) & 0xffff, args[4] & 0xffff); + } + break; + case AP_PS_DBGID_SEND_COMPLETE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_COMPLETE fc=%#x qos=%#x %s%s", + args[0], args[1], args[2], + args[3] ? "(usp active) " : "", + args[4] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_SEND_N_COMPLETE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_N_COMPLETE %s%s", + args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u detected out-of-sync now=%u tx_waiting=%u txq_depth=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: CAB %s n_mpdus=%u, flags=%x, extra=%u", + (args[0] == 17) ? "MGMT" : "DATA", args[1], args[2], args[3]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_wal_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "WAIT", + "WAIT_FILTER", + "PAUSE", + "PAUSE_SEND_N", + "BLOCK", + }; + + static const char *events[] = { + "PAUSE", + "PAUSE_FILTER", + "UNPAUSE", + + "BLOCK", + "BLOCK_FILTER", + "UNBLOCK", + + "HWQ_EMPTY", + "ALLOW_N", + }; + +#define WAL_VDEV_TYPE(type) \ + (type == 0 ? "AP" : \ + (type == 1 ? "STA" : \ + (type == 2 ? "IBSS" : \ + (type == 2 ? "MONITOR" : \ + "UNKNOWN")))) + +#define WAL_SLEEP_STATE(state) \ + (state == 1 ? "NETWORK SLEEP" : \ + (state == 2 ? "AWAKE" : \ + (state == 3 ? "SYSTEM SLEEP" : \ + "UNKNOWN"))) + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "TID PAUSE", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case WAL_DBGID_SET_POWER_STATE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "WAL %s => %s, req_count=%u", + WAL_SLEEP_STATE(args[0]), WAL_SLEEP_STATE(args[1]), + args[2]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "WAL channel change (force reset) freq=%u, flags=%u mode=%u rx_ok=%u tx_ok=%u", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1], + args[2], args[3]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "WAL channel change freq=%u, mode=%u flags=%u rx_ok=1 tx_ok=1", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1]); + } + break; + case WAL_DBGID_VDEV_START: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "WAL %s vdev started", + WAL_VDEV_TYPE(args[0])); + } + break; + case WAL_DBGID_VDEV_STOP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev stopped", + WAL_VDEV_TYPE(args[0])); + break; + case WAL_DBGID_VDEV_UP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev up, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_VDEV_DOWN: + dbglog_printf(timestamp, vap_id, "WAL %s vdev down, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame desc_id=0x%x, seq=0x%x, type=0x%x, len=0x%x islocal=0x%x", + args[0], args[1], args[2], (args[3] & 0xffff0000) >> 16, args[3] & 0x0000ffff); + break; + case WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame completion desc_id=0x%x, status=0x%x, islocal=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame msdu_id=0x%x, seq=0x%x, type=0x%x, len=0x%x", + args[0], args[1], args[2], args[3]); + break; + case WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame completion desc_id=0x%x, status=0x%x, seq=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_RESET_PCU_CYCLE_CNT: + dbglog_printf(timestamp, vap_id, "WAL PCU cycle counter value at reset:%x", args[0]); + break; + case WAL_DBGID_TX_DISCARD: + dbglog_printf(timestamp, vap_id, "WAL Tx enqueue discard msdu_id=0x%x", args[0]); + break; + case WAL_DBGID_SET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK " + "pdev=%d, txchain=0x%x, rxchain=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL rxstop=%d, txstop=%d", + args[0], args[1]); + break; + case WAL_DBGID_GET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_GET_HW_CHAINMASK " + "txchain=0x%x, rxchain=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_DISABLE: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_DISABLE"); + break; + case WAL_DBGID_SMPS_ENABLE_HW_CNTRL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_ENABLE_HW_CNTRL low_pwr_mask=0x%x, high_pwr_mask=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_SWSEL_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_SWSEL_CHAINMASK low_pwr=0x%x, chain_mask=0x%x", + args[0], args[1]); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_scan_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "BSSCHAN", + "WAIT_FOREIGN_CHAN", + "FOREIGN_CHANNEL", + "TERMINATING" + }; + + static const char *events[] = { + "REQ", + "STOP", + "BSSCHAN", + "FOREIGN_CHAN", + "CHECK_ACTIVITY", + "REST_TIME_EXPIRE", + "DWELL_TIME_EXPIRE", + "PROBE_TIME_EXPIRE", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "SCAN", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_coex_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 * args) +{ + A_UINT8 i; + char * dbg_id_str; + + static const char * wlan_rx_xput_status[] = { + "WLAN_XPUT_NORMAL", + "WLAN_XPUT_UNDER_THRESH", + "WLAN_XPUT_CRITICAL", + "WLAN_XPUT_RECOVERY_TIMEOUT", + }; + + static const char * coex_sched_req[] = { + "SCHED_REQ_NEXT", + "SCHED_REQ_BT", + "SCHED_REQ_WLAN", + "SCHED_REQ_POSTPAUSE", + "SCHED_REQ_UNPAUSE", + }; + + static const char * coex_sched_type[] = { + "SCHED_NONE", + "SCHED_WLAN", + "SCHED_BT", + "SCHED_WLAN_PAUSE", + "SCHED_WLAN_POSTPAUSE", + "SCHED_WLAN_UNPAUSE", + }; + + static const char * coex_trf_mgmt_type[] = { + "TRF_MGMT_FREERUN", + "TRF_MGMT_SHAPE_PM", + "TRF_MGMT_SHAPE_PSP", + "TRF_MGMT_SHAPE_S_CTS", + }; + + static const char * coex_system_status[] = { + "BT_OFF", + "BTCOEX_NOT_REQD", + "WLAN_IS_IDLE", + "EXECUTE_SCHEME", + "BT_FULL_CONCURRENCY", + "WLAN_SLEEPING", + "WLAN_IS_PAUSED", + "WAIT_FOR_NEXT_ACTION", + }; + + static const char * wlan_rssi_type[] = { + "LOW_RSSI", + "MID_RSSI", + "HI_RSSI", + "INVALID_RSSI", + }; + + static const char * coex_bt_scheme[] = { + "IDLE_CTRL", + "ACTIVE_ASYNC_CTRL", + "PASSIVE_SYNC_CTRL", + "ACTIVE_SYNC_CTRL", + "DEFAULT_CTRL", + "CONCURRENCY_CTRL", + }; + + static const char * wal_peer_rx_rate_stats_event_sent[] = { + "PR_RX_EVT_SENT_NONE", + "PR_RX_EVT_SENT_LOWER", + "PR_RX_EVT_SENT_UPPER", + }; + + static const char * wlan_psp_stimulus[] = { + "ENTRY", + "EXIT", + "PS_READY", + "PS_NOT_READY", + "RX_MORE_DATA_RCVD", + "RX_NO_MORE_DATA_RCVD", + "TX_DATA_COMPLT", + "TX_COMPLT", + "TIM_SET", + "REQ", + "DONE_SUCCESS", + "DONE_NO_PS_POLL_ACK", + "DONE_RESPONSE_TMO", + "DONE_DROPPED", + "DONE_FILTERED", + "WLAN_START", + "NONWLAN_START", + "NONWLAN_INTVL_UPDATE", + "NULL_TX", + "NULL_TX_COMPLT", + "BMISS_FIRST", + "NULL_TX_FAIL", + "RX_NO_MORE_DATA_DATAFRM", + }; + + static const char * coex_pspoll_state[] = { + "STATE_DISABLED", + "STATE_NOT_READY", + "STATE_ENABLED", + "STATE_READY", + "STATE_TX_STATUS", + "STATE_RX_STATUS", + }; + + static const char * coex_scheduler_interval[] = { + "COEX_SCHED_NONWLAN_INT", + "COEX_SCHED_WLAN_INT", + }; + + static const char * wlan_weight[] = { + "BT_COEX_BASE", + "BT_COEX_LOW", + "BT_COEX_MID", + "BT_COEX_MID_NONSYNC", + "BT_COEX_HI_NONVOICE", + "BT_COEX_HI", + "BT_COEX_CRITICAL", + }; + + static const char * coex_psp_error_type[] = { + "DISABLED_STATE", + "VDEV_NULL", + "COEX_PSP_ENTRY", + "ZERO_INTERVAL", + "COEX_PSP_EXIT", + "READY_DISABLED", + "READY_NOT_DISABLED", + "POLL_PKT_DROPPED", + "SET_TIMER_PARAM", + }; + + dbg_id_str = dbglog_get_msg(mod_id, dbg_id); + + switch (dbg_id) { + case COEX_SYSTEM_UPDATE: + if (numargs >= 1 && args[0] < 8) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_system_status[args[0]]); + } else { + return FALSE; + } + break; + case COEX_SCHED_START: + if (numargs >= 5 && args[0] < 5 && args[2] < 4 && args[3] < 4 && args[4] < 4) { + if (args[1] == 0xffffffff) { + dbglog_printf(timestamp, vap_id, "%s: %s, DETERMINE_DURATION, %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } else { + dbglog_printf(timestamp, vap_id, "%s: %s, IntvlDur(%u), %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], args[1], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } + } else { + return FALSE; + } + break; + case COEX_SCHED_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, CoexMgrPolicy(%u), WlanIsIdleOverride(%u), HidConcurTxOverride(%u), minRSSI(%u)", + dbg_id_str, coex_sched_type[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_BT_SCHEME: + if (numargs >= 1 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_bt_scheme[args[0]]); + } else { + return FALSE; + } + break; + case COEX_TRF_FREERUN: + case COEX_TRF_SHAPE_PM: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, AllocatedBtIntvls(%u), BtIntvlCnt(%u), AllocatedWlanIntvls(%u), WlanIntvlCnt(%u)", + dbg_id_str, coex_sched_type[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_SYSTEM_MONITOR: + if (numargs >= 5 && args[1] < 4 && args[4] < 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanRxCritical(%u), %s, MinDirectRxRate(%u), XputMonitorActiveNum(%u), %s", + dbg_id_str, args[0], wlan_rx_xput_status[args[1]], args[2], args[3], wlan_rssi_type[args[4]]); + } else { + return FALSE; + } + break; + case COEX_RX_RATE: + if (numargs >= 5 && args[4] < 3) { + dbglog_printf(timestamp, vap_id, "%s: NumUnderThreshPeers(%u), MinDirectRate(%u), LastRateSample(%u), DeltaT(%u), %s", + dbg_id_str, args[0], args[1], args[2], args[3], wal_peer_rx_rate_stats_event_sent[args[4]]); + } else { + return FALSE; + } + break; + case COEX_WLAN_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_WLAN_POSTPAUSE_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanPostPauseIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_BT_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: BtIntvlCnt(%u), HidConcurrentTxOverride(%u), EnableBtBwLimit(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_ENTER: + if (numargs >= 5 && args[0] < 23 && args[1] < 6 && args[3] < 2) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, PsPollAvg(%u), %s, CurrT(%u)", + dbg_id_str, wlan_psp_stimulus[args[0]], coex_pspoll_state[args[1]], args[2], coex_scheduler_interval[args[3]], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, PsPollAvg(%u), EstimationOverrun(%u), EstimationUnderun(%u), NotReadyErr(%u)", + dbg_id_str, coex_pspoll_state[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_TRF_SHAPE_PSP: + if (numargs == 2 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, CurrT(%u)", + dbg_id_str, coex_pspoll_state[args[0]], args[1]); + } else if (numargs >= 5 && args[0] < 6 && args[1] < 7) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, Dur(%u), WlanOverride(%u), PrioritizeWlanDuringCollis(%u)", + dbg_id_str, coex_sched_type[args[0]], wlan_weight[args[1]], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_SPEC_POLL: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: PsPollSpecEna(%u), Count(%u), NextTS(%u), AllowSpecPsPollTx(%u), Intvl(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_READY_STATE: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: T2BT(%u), CoexSchedulerEndTS(%u), MoreData(%u), PSPRespExpectedTS(%u), NonWlanIdleT(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_NONWLAN_INTERVAL: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: NonWlanBaseIntvl(%u), NonWlanIdleT(%u), PSPSpecIntvl(%u), ApRespTimeout(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_PSP_ERROR: + if (numargs >= 1 && args[0] < 9) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %s", + dbg_id_str, coex_psp_error_type[args[0]]); + for (i = 1; i < numargs; i++) { + printf(", %u", args[i]); + } + printf("\n"); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_1: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: ApResp0(%u), ApResp1(%u), ApResp2(%u), ApResp3(%u), ApResp4(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_2: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: DataPt(%u), Max(%u), NextApRespIndex(%u), NumOfValidDataPts(%u), PsPollAvg(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_RX_STATUS_STATE_1: + if (numargs >= 5) { + if (args[2]) { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Overrun, RsOverrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } else { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Underrun, RsUnderrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } + } else { + return FALSE; + } + break; + //Translate following into decimal + case COEX_SINGLECHAIN_DBG_1: + case COEX_SINGLECHAIN_DBG_2: + case COEX_SINGLECHAIN_DBG_3: + case COEX_MULTICHAIN_DBG_1: + case COEX_MULTICHAIN_DBG_2: + case COEX_MULTICHAIN_DBG_3: + if (numargs > 0) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %u", + dbg_id_str, args[0]); + for (i = 1; i < numargs; i++) { + printf(", %u", args[i]); + } + printf("\n"); + } else { + return FALSE; + } + break; + case COEX_LinkID: + if (numargs >= 4) { + if (args[0]) { //Add profile + dbglog_printf(timestamp, vap_id, "%s Alloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } else { //Remove profile + dbglog_printf(timestamp, vap_id, "%s Dealloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } + } else { + return FALSE; + } + break; + case COEX_BT_DURATION: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "%s: Result(%u), NumOfValidSchedMsgs(%u) PrioLowerLimit(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return FALSE; + } + break; + case COEX_T2BT: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "%s: Result(%u), BtTime1(%u), PrioLowerLimit(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return FALSE; + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_beacon_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "INIT", + "ADJUST_START", + "ADJUSTING", + "ADJUST_HOLD", + }; + + static const char *events[] = { + "ADJUST_START", + "ADJUST_RESTART", + "ADJUST_STOP", + "ADJUST_PAUSE", + "ADJUST_UNPAUSE", + "ADJUST_INC_SLOP_STEP", + "ADJUST_HOLD", + "ADJUST_HOLD_TIME_OUT", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "EARLY_RX", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case BEACON_EVENT_EARLY_RX_BMISS_STATUS: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "early_rx bmiss status:rcv=%d total=%d miss=%d", + args[0], args[1], args[2]); + } + break; + case BEACON_EVENT_EARLY_RX_SLEEP_SLOP: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx cont bmiss timeout,update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx skip bcn num:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CLK_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx clk drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_AP_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx ap drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_BCN_TYPE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx bcn type:%d", + args[0]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_data_txrx_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO: + dbglog_printf(timestamp, vap_id, "DATA RX seq=0x%x, len=0x%x, stored=0x%x, duperr=0x%x", + args[0], args[1], (args[2] & 0xffff0000) >> 16, args[2] & 0x0000ffff); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_smps_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "S_INACTIVE", + "S_STATIC", + "S_DYNAMIC", + "S_STALLED", + "S_INACTIVE_WAIT", + "S_STATIC_WAIT", + "S_DYNAMIC_WAIT", + }; + + static const char *events[] = { + "E_STOP", + "E_STOP_COMPL", + "E_START", + "E_STATIC", + "E_STATIC_COMPL", + "E_DYNAMIC", + "E_DYNAMIC_COMPL", + "E_STALL", + "E_RSSI_ABOVE_THRESH", + "E_RSSI_BELOW_THRESH", + "E_FORCED_NONE", + }; + + switch(dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA_SMPS SM", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case STA_SMPS_DBGID_CREATE_PDEV_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create PDEV ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START: + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP: + break; + case STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME: + dbglog_printf(timestamp, vap_id, "STA_SMPS STA %#x Signal SMPS mode as %s; cb_flags %#x", + args[0], + (args[1] == 0 ? "DISABLED": + (args[1] == 0x1 ? "STATIC" : + (args[1] == 0x3 ? "DYNAMIC" : "UNKNOWN"))), + args[2]); + break; + case STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE " + "tx_mask %#x rx_mask %#x arb_dtim_mask %#x", + args[0], args[1], args[2]); + break; + case STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE cur_pwr_state %s new_pwr_state %s", + (args[0] == 0x1 ? "SLEEP": + (args[0] == 0x2 ? "AWAKE": + (args[0] == 0x3 ? "FULL_SLEEP" : "UNKNOWN"))), + (args[1] == 0x1 ? "SLEEP": + (args[1] == 0x2 ? "AWAKE": + (args[1] == 0x3 ? "FULL_SLEEP" : "UNKNOWN")))); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP " + "tx_mask %#x rx_mask %#x orig_rx %#x dtim_rx %#x", + args[0], args[1], args[2], args[3]); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE " + "tx_mask %#x rx_mask %#x orig_rx %#x", + args[0], args[1], args[2]); + break; + default: + dbglog_printf( + timestamp, + vap_id, + "STA_SMPS: UNKNOWN DBGID!"); + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_p2p_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "DOZE", + "TX_BCN", + "CTWIN", + "OPPPS", + }; + + static const char *events[] = { + "ONESHOT_NOA", + "CTWINDOW", + "PERIODIC_NOA", + "IDLE", + "NOA_CHANGED", + "TBTT", + "TX_BCN_CMP", + "OPPPS_OK", + "OPPPS_CHANGED", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "P2P GO PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_pcielp_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "STOP", + "TX", + "RX", + "SLEEP", + "SUSPEND", + }; + + static const char *events[] = { + "VDEV_UP", + "ALL_VDEV_DOWN", + "AWAKE", + "SLEEP", + "TX_ACTIVITY", + "TX_INACTIVITY", + "TX_AC_CHANGE", + "SUSPEND", + "RESUME", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "PCIELP", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +int main(int argc, char *argv[]) +{ + int res; + struct dbglog_slot *slot; + unsigned int dropped = 0; + unsigned int length = 0; + unsigned int record_num = 0; + + if (argc != 2) { + fprintf(stderr, "usage:\n" + "%s \\\n" + "for example:\n" + "ath6kl-fwlog-parser /tmp/cld-fwlog\n", + argv[0]); + return -1; + } + + /* Registering parser */ + dbglog_reg_modprint(WLAN_MODULE_STA_PWRSAVE, dbglog_sta_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_AP_PWRSAVE, dbglog_ap_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WAL, dbglog_wal_print_handler); + dbglog_reg_modprint(WLAN_MODULE_SCAN, dbglog_scan_print_handler); + dbglog_reg_modprint(WLAN_MODULE_RATECTRL, dbglog_ratectrl_print_handler); + dbglog_reg_modprint(WLAN_MODULE_ANI, dbglog_ani_print_handler); + dbglog_reg_modprint(WLAN_MODULE_COEX, dbglog_coex_print_handler); + dbglog_reg_modprint(WLAN_MODULE_BEACON,dbglog_beacon_print_handler); + dbglog_reg_modprint(WLAN_MODULE_DATA_TXRX,dbglog_data_txrx_print_handler); + dbglog_reg_modprint(WLAN_MODULE_STA_SMPS, dbglog_smps_print_handler); + + log_in = fopen(argv[1], "r"); + if (log_in == NULL) { + perror("Failed to open input file"); + return -1; + } + + + while ((res = fread(buf, RECLEN, 1, log_in)) == 1) { + slot =(struct dbglog_slot *)buf; + length = get_le32((unsigned char *)&slot->length); + dropped = get_le32((unsigned char *)&slot->dropped); + record_num++; + fprintf(stderr, "Length %d Dropped %d record_num %d\n", + length, dropped, record_num); + dbglog_parse_debug_logs(slot->payload, length, dropped); + } + + fclose(log_in); + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-record.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-record.c new file mode 100644 index 0000000000000..03f75a6b19b1a --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/cld-fwlog-record.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include +#include +#include +#include +#include + +#include +#include +#include "dbglog_host.h" + +static FILE *fwlog_in; +static FILE *fwlog_res; +static FILE *log_out; +const char *fwlog_res_file; +unsigned char buf[RECLEN]; +int max_records; +int record; + +static unsigned int get_le32(const unsigned char *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +static size_t capture(FILE *out_log, FILE *in_log) +{ + size_t res; + struct dbglog_slot *slot; + unsigned int length = 0, timestamp = 0, dropped = 0; + + + while ((res = fread(buf, RECLEN, 1, in_log)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((unsigned char *)&slot->timestamp); + length = get_le32((unsigned char *)&slot->length); + dropped = get_le32((unsigned char *)&slot->dropped); + printf("Read record timestamp=%u length=%u no. fw dropped=%u\n", + timestamp, length, dropped); + fseek(out_log, record * RECLEN, SEEK_SET); + if (fwrite(buf, RECLEN, res, out_log) != res) + perror("fwrite"); + record++; + if (record == max_records) + record = 0; + } + + return res; +} + +static size_t reorder(FILE *log_in, FILE *log_out) +{ + unsigned char buf[RECLEN]; + size_t res; + unsigned int timestamp, min_timestamp = -1; + int pos = 0, min_pos = 0; + struct dbglog_slot *slot; + unsigned int length = 0; + + pos = 0; + while ((res = fread(buf, RECLEN, 1, log_in)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((unsigned char *)&slot->timestamp); + if (timestamp < min_timestamp) { + min_timestamp = timestamp; + min_pos = pos; + } + pos++; + } + printf("First record at position %d\n", min_pos); + + fseek(log_in, min_pos * RECLEN, SEEK_SET); + while ((res = fread(buf, RECLEN, 1, log_in)) == 1) { + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((unsigned char *)&slot->timestamp); + length = get_le32((unsigned char *)&slot->length); + printf("Read record timestamp=%u length=%u\n", + timestamp, length); + if (fwrite(buf, RECLEN, res, log_out) != res) + perror("fwrite"); + } + + fseek(log_in, 0, SEEK_SET); + pos = min_pos; + while (pos > 0 && (res = fread(buf, RECLEN, 1, log_out)) == 1) { + pos--; + slot = (struct dbglog_slot *)buf; + timestamp = get_le32((unsigned char *)&slot->timestamp); + length = get_le32((unsigned char *)&slot->length); + printf("Read record timestamp=%u length=%u\n", + timestamp, length); + if (fwrite(buf, RECLEN, res, log_out) != res) + perror("fwrite"); + } + + return 0; +} + +static void cleanup(void) { + fclose(fwlog_in); + + fwlog_res = fopen(fwlog_res_file, "w"); + + if (fwlog_res == NULL) { + perror("Failed to open reorder fwlog file"); + fclose(log_out); + return; + } + + reorder(log_out, fwlog_res); + + fclose(fwlog_res); + fclose(log_out); +} + +static void stop(int signum) +{ + printf("Recording stopped\n"); + cleanup(); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int max_len; + size_t res; + + if (argc != 4) { + fprintf(stderr, "usage:\n" + "%s \\\n" + " \n" + "for example:\n" + "cld-fwlog-record /sys/kernel/debug" + "/cld/dbglog_block \\\n" + " /tmp/cld-fwlog 1000000\n", + argv[0]); + return -1; + } + + max_len = atoi(argv[3]); + if (max_len < RECLEN) { + fprintf(stderr, "Too small maximum length (has to be >= %d)\n", + RECLEN); + return -1; + } + max_records = max_len / RECLEN; + printf("Storing last %d records\n", max_records); + + fwlog_in = fopen(argv[1], "r"); + if (fwlog_in == NULL) { + perror("Failed to open fwlog_block file"); + return -1; + } + + log_out = fopen(argv[2], "w"); + if (log_out == NULL) { + perror("Failed to create output file"); + fclose(fwlog_in); + return -1; + } + + fwlog_res_file = "./reorder"; + + signal(SIGINT, stop); + signal(SIGTERM, stop); + + res = capture(log_out, fwlog_in); + + printf("Incomplete read: %d bytes\n", (int) res); + + cleanup(); + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/nan-parser.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/nan-parser.c new file mode 100644 index 0000000000000..5f00bd867a8f9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/nan-parser.c @@ -0,0 +1,4598 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "dbglog.h" +#include "dbglog_id.h" +#include "dbglog_host.h" +#include "msg.h" +#include "msgcfg.h" +#include "diag_lsm.h" +#include "log.h" + +#include "a_debug.h" +#include "ol_defines.h" +#include "ah_osdep.h" + +extern void +dbglog_printf( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...); + +extern void +dbglog_sm_print( + A_UINT32 timestamp, + A_UINT16 vap_id, + A_UINT16 numargs, + A_UINT32 *args, + const char *module_prefix, + const char *states[], A_UINT32 num_states, + const char *events[], A_UINT32 num_events); + +static const char * +dbglog_get_nan_role_str( + A_UINT8 nan_role); + +static const char * +dbglog_get_nan_chan_type( + A_UINT32 type); + +static const char * +dbglog_get_nan_tlv_type_str( + A_UINT16 tlv_type); + +#define MAX_DBG_MSGS 256 + +/* NAN DBGIDs */ +#define NAN_DBGID_START 0 + +/* Debug IDs for debug logs. 3 args max, not fixed. */ +#define NAN_DBGID_DBG_LOG_BASE 1 +#define NAN_DBGID_FUNC_BEGIN NAN_DBGID_DBG_LOG_BASE +#define NAN_DBGID_FUNC_END 2 +#define NAN_DBGID_MAIN_DEBUG 3 +#define NAN_DBGID_MAC_DEBUG 4 +#define NAN_DBGID_BLOOM_FILTER_DEBUG 5 +#define NAN_DBGID_MAC_ADDR 6 +#define NAN_DBGID_PARAM_UPDATED 7 +#define NAN_DBGID_NULL_PTR 8 +#define NAN_DBGID_INVALID_FUNC_ARG 9 +#define NAN_DBGID_INVALID_MSG_PARAM 10 +#define NAN_DBGID_MISSING_MSG_PARAM 11 +#define NAN_DBGID_DEPRECATED_MSG_PARAM 12 +#define NAN_DBGID_UNSUPPORTED_MSG_PARAM 13 +#define NAN_DBGID_INVALID_PKT_DATA 14 +#define NAN_DBGID_LOG_PKT_DATA 15 +#define NAN_DBGID_INVALID_VALUE 16 +#define NAN_DBGID_INVALID_OPERATION 17 +#define NAN_DBGID_INVALID_STATE 18 +#define NAN_DBGID_FUNCTION_ENABLED 19 +#define NAN_DBGID_FUNCTION_DISABLED 20 +#define NAN_DBGID_INVALID_FUNCTION_STATE 21 +#define NAN_DBGID_READ_ERROR 22 +#define NAN_DBGID_WRITE_ERROR 23 +#define NAN_DBGID_RECEIVE_ERROR 24 +#define NAN_DBGID_TRANSMIT_ERROR 25 +#define NAN_DBGID_PARSE_ERROR 26 +#define NAN_DBGID_RES_ALLOC_ERROR 27 +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_DBG_LOG_LAST 28 + +/* Debug IDs for event logs. */ + +#define NAN_DBGID_EVT_BASE NAN_DBGID_DBG_LOG_LAST +/* args: */ +#define NAN_DBGID_NAN_ENABLED (NAN_DBGID_EVT_BASE + 0) +/* args: */ +#define NAN_DBGID_NAN_DISABLED (NAN_DBGID_EVT_BASE + 1) +/* args: */ +#define NAN_DBGID_CONFIG_RESTORED (NAN_DBGID_EVT_BASE + 2) +/* args: framesQueued */ +#define NAN_DBGID_SDF_QUEUED (NAN_DBGID_EVT_BASE + 3) +/* args: old, new */ +#define NAN_DBGID_TW_CHANGED (NAN_DBGID_EVT_BASE + 4) +/* args: */ +#define NAN_DBGID_DW_START (NAN_DBGID_EVT_BASE + 5) +/* args: busyDiff */ +#define NAN_DBGID_DW_END (NAN_DBGID_EVT_BASE + 6) +/* args: oldClusterId, newClusterId */ +#define NAN_DBGID_CLUSTER_ID_CHANGED (NAN_DBGID_EVT_BASE + 7) +/* args: cmd, buffer, length */ +#define NAN_DBGID_WMI_CMD_RECEIVED (NAN_DBGID_EVT_BASE + 8) +/* args: pEventPkt, pEventBuf, eventSize, dataSize */ +#define NAN_DBGID_WMI_EVT_SENT (NAN_DBGID_EVT_BASE + 9) +/* args: type length, readLen */ +#define NAN_DBGID_TLV_READ (NAN_DBGID_EVT_BASE + 10) +/* args: type length, writeLen */ +#define NAN_DBGID_TLV_WRITE (NAN_DBGID_EVT_BASE + 11) +/* args: handle */ +#define NAN_DBGID_PUBSUB_UPDATED (NAN_DBGID_EVT_BASE + 12) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_DEFERRED (NAN_DBGID_EVT_BASE + 13) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_PENDING (NAN_DBGID_EVT_BASE + 14) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVED (NAN_DBGID_EVT_BASE + 15) +/* args: handle, status, value */ +#define NAN_DBGID_PUBSUB_PROCESSED (NAN_DBGID_EVT_BASE + 16) +/* args: handle, sid1, sid2, svcCtrl, length */ +#define NAN_DBGID_PUBSUB_MATCHED (NAN_DBGID_EVT_BASE + 17) +/* args: handle, flags */ +#define NAN_DBGID_PUBSUB_PREPARED (NAN_DBGID_EVT_BASE + 18) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_TRANSMIT (NAN_DBGID_EVT_BASE + 19) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_RECEIVED (NAN_DBGID_EVT_BASE + 20) +/* args: subscribeHandle, matchHandle, oldTimeout, newTimeout */ +#define NAN_DBGID_SUBSCRIBE_UNMATCH_TIMEOUT_UPDATE (NAN_DBGID_EVT_BASE + 21) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_NEW (NAN_DBGID_EVT_BASE + 22) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_REPEAT (NAN_DBGID_EVT_BASE + 23) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_EXPIRED (NAN_DBGID_EVT_BASE + 24) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp */ +#define NAN_DBGID_SUBSCRIBE_MATCH_LOG (NAN_DBGID_EVT_BASE + 25) +/* args: sid1, sid2 */ +#define NAN_DBGID_SERVICE_ID_CREATED (NAN_DBGID_EVT_BASE + 26) +/* args: size */ +#define NAN_DBGID_SD_ATTR_BUILT (NAN_DBGID_EVT_BASE + 27) +/* args: offset */ +#define NAN_DBGID_SERVICE_RSP_OFFSET (NAN_DBGID_EVT_BASE + 28) +/* args: offset */ +#define NAN_DBGID_SERVICE_INFO_OFFSET (NAN_DBGID_EVT_BASE + 29) +/* args: chan, interval, start_time */ +#define NAN_DBGID_CHREQ_CREATE (NAN_DBGID_EVT_BASE + 30) +/* args: start_time, status */ +#define NAN_DBGID_CHREQ_UPDATE (NAN_DBGID_EVT_BASE + 31) +/* args: chan, interval, status */ +#define NAN_DBGID_CHREQ_REMOVE (NAN_DBGID_EVT_BASE + 32) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_GRANT (NAN_DBGID_EVT_BASE + 33) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_END (NAN_DBGID_EVT_BASE + 34) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_ERROR (NAN_DBGID_EVT_BASE + 35) +/* args: type, length, timestamp, rssi */ +#define NAN_DBGID_RX_CALLBACK (NAN_DBGID_EVT_BASE + 36) +/* args: type, handle, bufp, status, timestamp */ +#define NAN_DBGID_TX_COMPLETE (NAN_DBGID_EVT_BASE + 37) +/* args: tsf, tsf */ +#define NAN_DBGID_TSF_TIMEOUT (NAN_DBGID_EVT_BASE + 38) +/* args: clusterId, clusterStart */ +#define NAN_DBGID_SYNC_START (NAN_DBGID_EVT_BASE + 39) +/* args: clusterId */ +#define NAN_DBGID_SYNC_STOP (NAN_DBGID_EVT_BASE + 40) +/* args: enable, scanType, rval */ +#define NAN_DBGID_NAN_SCAN (NAN_DBGID_EVT_BASE + 41) +/* args: scanType */ +#define NAN_DBGID_NAN_SCAN_COMPLETE (NAN_DBGID_EVT_BASE + 42) +/* args: masterPref */ +#define NAN_DBGID_MPREF_CHANGE (NAN_DBGID_EVT_BASE + 43) +/* args: masterPref, randFactor */ +#define NAN_DBGID_WARMUP_EXPIRE (NAN_DBGID_EVT_BASE + 44) +/* args: randFactor */ +#define NAN_DBGID_RANDOM_FACTOR_EXPIRE (NAN_DBGID_EVT_BASE + 45) +/* args: tsf, tsf */ +#define NAN_DBGID_DW_SKIP (NAN_DBGID_EVT_BASE + 46) +/* args: type, tsfDiff */ +#define NAN_DBGID_DB_SKIP (NAN_DBGID_EVT_BASE + 47) +/* args: TBD */ +#define NAN_DBGID_BEACON_RX (NAN_DBGID_EVT_BASE + 48) +/* args: TBD */ +#define NAN_DBGID_BEACON_TX (NAN_DBGID_EVT_BASE + 49) +/* args: clusterId */ +#define NAN_DBGID_CLUSTER_MERGE (NAN_DBGID_EVT_BASE + 50) +/* args: cmd, status, value */ +#define NAN_DBGID_TEST_CMD_EXEC (NAN_DBGID_EVT_BASE + 51) +/* args: tsfHi, tsfLo, age */ +#define NAN_DBGID_APPLY_BEACON_TSF (NAN_DBGID_EVT_BASE + 52) +/* args: behindFlag, diff */ +#define NAN_DBGID_TSF_UPDATE (NAN_DBGID_EVT_BASE + 53) +/* args: argc==4 (rawTsfHi, rawTsfLo, nanTsfHi, nanTsfLo), argc==2(offsetHi, offsetLo) */ +#define NAN_DBGID_SET_TSF (NAN_DBGID_EVT_BASE + 54) +/* args: rankHi, rankLo, mp, rf*/ +#define NAN_DBGID_NEW_MASTERRANK (NAN_DBGID_EVT_BASE + 55) +/* args: amRankHi, amRankLo, mp, rf */ +#define NAN_DBGID_NEW_ANCHORMASTER (NAN_DBGID_EVT_BASE + 56) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_UPDATE (NAN_DBGID_EVT_BASE + 57) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_EXPIRED (NAN_DBGID_EVT_BASE + 58) +/* args: reason, transitionsToAM */ +#define NAN_DBGID_BECOMING_ANCHORMASTER (NAN_DBGID_EVT_BASE + 59) +/* args: oldRole, newRole */ +#define NAN_DBGID_ROLE_CHANGE (NAN_DBGID_EVT_BASE + 60) +/* args: oldRole, newRole */ +#define NAN_DBGID_SYNC_BEACON_DW_STATS (NAN_DBGID_EVT_BASE + 61) +/* args: attrId */ +#define NAN_DBGID_RX_UNSUPPORTED_SDF_ATTR_ID (NAN_DBGID_EVT_BASE + 62) +/* args: handle, sid1, sid2, svcCtrl, length */ +#define NAN_DBGID_PUBSUB_MATCHED_SKIPPED_SSI (NAN_DBGID_EVT_BASE + 63) +/* args: offset */ +#define NAN_DBGID_MATCH_FILTER_OFFSET (NAN_DBGID_EVT_BASE + 64) +/* args: tsSize, n, twIndex */ +#define NAN_DBGID_TW_PARAMS (NAN_DBGID_EVT_BASE + 65) +/* args: */ +#define NAN_DBGID_BEACON_SENDER (NAN_DBGID_EVT_BASE + 66) +/* args: */ +#define NAN_DBGID_SPARE_67 (NAN_DBGID_EVT_BASE + 67) +/* args: */ +#define NAN_DBGID_SPARE_68 (NAN_DBGID_EVT_BASE + 68) +/* args: */ +#define NAN_DBGID_SPARE_69 (NAN_DBGID_EVT_BASE + 69) +/* args: */ +#define NAN_DBGID_SPARE_70 (NAN_DBGID_EVT_BASE + 70) +/* args: */ +#define NAN_DBGID_SPARE_71 (NAN_DBGID_EVT_BASE + 71) +/* args: */ +#define NAN_DBGID_SPARE_72 (NAN_DBGID_EVT_BASE + 72) +/* args: */ +#define NAN_DBGID_SPARE_73 (NAN_DBGID_EVT_BASE + 73) +/* args: */ +#define NAN_DBGID_SPARE_74 (NAN_DBGID_EVT_BASE + 74) +/* args: */ +#define NAN_DBGID_SPARE_75 (NAN_DBGID_EVT_BASE + 75) + +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_EVT_LOG_LAST (NAN_DBGID_EVT_BASE + 76) + +/* Debug IDs for message logs. */ +#define NAN_DBGID_API_MSG_BASE NAN_DBGID_EVT_LOG_LAST +#define NAN_DBGID_API_MSG_HEADER (NAN_DBGID_API_MSG_BASE + 0) +#define NAN_DBGID_API_MSG_DATA (NAN_DBGID_API_MSG_BASE + 1) +#define NAN_DBGID_API_MSG_LAST (NAN_DBGID_API_MSG_BASE + 2) + +/* Debug IDs for packet logs. */ +#define NAN_DBGID_OTA_PKT_BASE NAN_DBGID_API_MSG_LAST +#define NAN_DBGID_OTA_PKT_HEADER (NAN_DBGID_OTA_PKT_BASE + 0) +#define NAN_DBGID_OTA_PKT_DATA (NAN_DBGID_OTA_PKT_BASE + 1) +#define NAN_DBGID_OTA_PKT_LAST (NAN_DBGID_OTA_PKT_BASE + 2) + +#define NAN_DBGID_END NAN_DBGID_OTA_PKT_LAST + +static char *DBG_MSG_ARR[MAX_DBG_MSGS] = +{ + /* Start */ + "NAN debug ID start", + + /* Debug log IDs */ + "NAN function begin", + "NAN function end", + "NAN main debug", + "NAN MAC debug", + "NAN bloom filter debug", + "NAN MAC address", + "NAN param updated", + "NAN NULL pointer", + "NAN invalid function argument", + "NAN invalid message parameter", + "NAN missing message parameter", + "NAN deprecated message parameter", + "NAN unsupported message parameter", + "NAN invalid packet data", + "NAN log packet data", + "NAN invalid value", + "NAN invalid operation", + "NAN invalid state", + "NAN function enabled", + "NAN function disable", + "NAN invalid funtion state", + "NAN read error", + "NAN write error", + "NAN receive error", + "NAN transmit error", + "NAN parse error", + "NAN resource allocation error", + + /* Event log IDs */ + "NAN enabled", + "NAN disabled", + "NAN config restored", + "NAN SDF queued", + "NAN TW changed", + "NAN DW start", + "NAN DW end", + "NAN cluster ID changed", + "NAN WMI command received", + "NAN WMI event sent", + "NAN TLV read", + "NAN TLV write", + "NAN pub/sub updated", + "NAN pub/sub remove deferred", + "NAN pub/sub remove pending", + "NAN pub/sub removed", + "NAN pub/sub processed", + "NAN pub/sub matched", + "NAN pub/sub prepared", + "NAN pub/sub follow-up transmit", + "NAN pub/sub follow-up received", + "NAN subscribe unmatch timeout update", + "NAN subscribe match new", + "NAN subscribe match repeat", + "NAN subscribe match expired", + "NAN subscribe match log", + "NAN service ID created", + "NAN SD attribute built", + "NAN service response offset", + "NAN service info offset", + "NAN channel request create", + "NAN channel request update", + "NAN channel request remove", + "NAN channel request grant", + "NAN channel request end", + "NAN channel request error", + "NAN rx callback", + "NAN tx complete", + "NAN TSF timeout", + "NAN sync start", + "NAN sync stop", + "NAN scan", + "NAN scan complete", + "NAN master preference changed", + "NAN warm-up timer expired", + "NAN random factor timer expired", + "NAN DW skip", + "NAN DB skip", + "NAN beacon rx", + "NAN beacon tx", + "NAN cluster merge", + "NAN test command exec", + "NAN apply beacon tsf", + "NAN tsf update", + "NAN set tsf", + "NAN new master rank", + "NAN new anchor master device", + "NAN anchor master record update", + "NAN anchor master record expired", + "NAN becoming anchor master", + "NAN role change", + "NAN sync beacon stats", + "NAN received unsupported attribute id", + "NAN pub/sub matched/skipped", + "NAN match filter offset", + "NAN TW params", + "NAN beacon sender", + "NAN spare 67", + "NAN spare 68", + "NAN spare 69", + "NAN spare 70", + "NAN spare 71", + "NAN spare 72", + "NAN spare 73", + "NAN spare 74", + "NAN spare 75", + + /* Message log IDs */ + "NAN API message header", + "NAN API Message data", + + /* Packet log IDs */ + "NAN OTA packet", + "NAN OTA packet data", + + /* End */ + "NAN End" +}; + +#define CHARS_PER_DATA_BYTE 3 +#define BYTES_PER_ARG sizeof(A_UINT32) +#define CHARS_PER_ARG (CHARS_PER_DATA_BYTE * BYTES_PER_ARG) +#define STR_INDEX(arg_idx, byte_idx) \ + (((arg_idx) * CHARS_PER_ARG) + ((byte_idx) * CHARS_PER_DATA_BYTE)) + +#define NAN_SUBSCRIBE_HANDLE_OFFSET 128 + +#define PUBSUB_STR(handle) \ + (((handle) < NAN_SUBSCRIBE_HANDLE_OFFSET) ? "publish" : "subscribe") + +#define BOOL_STR(value) ((value) ? "TRUE" : "FALSE") + +typedef enum +{ + NAN_MODULE_ID_ATTR, + NAN_MODULE_ID_BEACON, + NAN_MODULE_ID_BEACON_IE, + NAN_MODULE_ID_BLOOM_FILTER, + NAN_MODULE_ID_MAIN, + NAN_MODULE_ID_CLUSTER_SM, + NAN_MODULE_ID_CRC, + NAN_MODULE_ID_CTRL, + NAN_MODULE_ID_DE_IF, + NAN_MODULE_ID_LOG, + NAN_MODULE_ID_MAC, + NAN_MODULE_ID_PUBLISH, + NAN_MODULE_ID_RX, + NAN_MODULE_ID_SUBSCRIBE, + NAN_MODULE_ID_SYNC, + NAN_MODULE_ID_TIME, + NAN_MODULE_ID_TLV, + NAN_MODULE_ID_UTIL, + NAN_MODULE_ID_LAST +} tNanModuleId; + +static A_BOOL +dbglog_nan_debug_print_handler( + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *modules[] = + { + "wlan_nan_attr.c", + "wlan_nan_beacon.c", + "wlan_nan_beacon_ie.c", + "wlan_nan_bloom_filter.c", + "wlan_nan.c", + "wlan_nan_cluster_sm.c", + "wlan_nan_crc.c", + "wlan_nan_ctrl.c", + "wlan_nan_de_if.c", + "wlan_nan_log.c", + "wlan_nan_mac.c", + "wlan_nan_publish.c", + "wlan_nan_rx.c", + "wlan_nan_subscribe.c", + "wlan_nan_sched.c", + "wlan_nan_sync.c", + "wlan_nan_time.c", + "wlan_nan_tlv.c", + "wlan_nan_util.c" + }; + + char str[64] = { 0 }; + A_UINT16 arg_idx; + + /* + * Start at 2 here and subtract 2 below because arg[0] specifies the NAN + * module ID and args[1] specifies the line number within the module. + */ + for (arg_idx=2; arg_idx < numargs; ++arg_idx) + { + snprintf(&str[(arg_idx-2)*11], sizeof(&str[(arg_idx-2)*11]), + "0x%08X ", args[arg_idx]); + } + + if (args[0] < NAN_MODULE_ID_LAST) + { + dbglog_printf(timestamp, vap_id, "%s, line %u: %s, %s", + modules[args[0]], args[1], DBG_MSG_ARR[dbg_id], &str[0]); + } + else + { + dbglog_printf(timestamp, vap_id, "Unknown module %u, line %u: %s, %s", + args[0], args[1], DBG_MSG_ARR[dbg_id], &str[0]); + } + + return TRUE; +} + +static A_BOOL +dbglog_nan_event_print_handler( + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + + switch (dbg_id) + { + case NAN_DBGID_NAN_ENABLED: + dbglog_printf(timestamp, vap_id, "%s", DBG_MSG_ARR[dbg_id]); + break; + + case NAN_DBGID_NAN_DISABLED: + dbglog_printf(timestamp, vap_id, "%s", DBG_MSG_ARR[dbg_id]); + break; + + case NAN_DBGID_CONFIG_RESTORED: + dbglog_printf(timestamp, vap_id, "%s", DBG_MSG_ARR[dbg_id]); + break; + + case NAN_DBGID_SDF_QUEUED: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s, frames queued %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_TW_CHANGED: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s, old %u, new %u", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_DW_START: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "[==================> %s (%s)", + DBG_MSG_ARR[dbg_id], args[0] ? "secondary" : "primary"); + break; + + case NAN_DBGID_DW_END: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "<==================] %s (%s)", + DBG_MSG_ARR[dbg_id], args[0] ? "secondary" : "primary"); + break; + + case NAN_DBGID_CLUSTER_ID_CHANGED: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s, 0x%04X -> 0x%04X", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_WMI_CMD_RECEIVED: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, cmd 0x%08X, buffer 0x%08X, length %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_WMI_EVT_SENT: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, pEventPkt 0x%08X, pEventBuf 0x%08X, event size %u, data size %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_TLV_READ: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s, type %s (%u), read length %u", + DBG_MSG_ARR[dbg_id], dbglog_get_nan_tlv_type_str(args[0]), args[0], + args[1]); + break; + + case NAN_DBGID_TLV_WRITE: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, type %s (%u), length %u, write length %u", + DBG_MSG_ARR[dbg_id], dbglog_get_nan_tlv_type_str(args[0]), args[0], + args[1], args[2]); + break; + + case NAN_DBGID_PUBSUB_UPDATED: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "NAN %s %u updated", + PUBSUB_STR(args[0]), args[0]); + break; + + case NAN_DBGID_PUBSUB_REMOVE_DEFERRED: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "NAN %s %u remove deferred", + PUBSUB_STR(args[0]), args[0]); + break; + + case NAN_DBGID_PUBSUB_REMOVE_PENDING: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "NAN %s %u remove pending", + PUBSUB_STR(args[0]), args[0]); + break; + + case NAN_DBGID_PUBSUB_REMOVED: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "NAN %s %u removed", + PUBSUB_STR(args[0]), args[0]); + break; + + case NAN_DBGID_PUBSUB_PROCESSED: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "NAN %s %u processed, status %u, value %u", + PUBSUB_STR(args[0]), args[0], args[1], args[2]); + break; + + case NAN_DBGID_PUBSUB_MATCHED: + if (numargs != 5) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "NAN %s %u matched, instance id %u, requestor id %u, " + "svc id %02X:%02X:%02X:%02X:%02X:%02X, svcCtrl 0x%02X, len %u", + PUBSUB_STR(args[0]), args[0], + (args[2] & 0xFF), ((args[2] >> 8) & 0xFF), + ((args[1] >> 24) & 0xFF), ((args[1] >> 16) & 0xFF), + ((args[1] >> 8) & 0xFF), (args[1] & 0xFF), + ((args[2] >> 24) & 0xFF), ((args[2] >> 16) & 0xFF), + args[3], args[4]); + break; + + case NAN_DBGID_PUBSUB_PREPARED: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "NAN %s %u prepared, flags %X", + PUBSUB_STR(args[0]), args[0], args[1]); + break; + + case NAN_DBGID_PUBSUB_FOLLOWUP_TRANSMIT: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "NAN %s %u follow-up transmit, MAC address " + "%02X:%02X:%02X:%02X:%02X:%02X", + PUBSUB_STR(args[0]), args[0], + ((args[1] >> 24) & 0xFF), ((args[1] >> 16) & 0xFF), + ((args[1] >> 8) & 0xFF), (args[1] & 0xFF), + ((args[2] >> 24) & 0xFF), ((args[2] >> 16) & 0xFF)); + break; + + case NAN_DBGID_PUBSUB_FOLLOWUP_RECEIVED: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "NAN %s %u follow-up received, MAC address " + "%02X:%02X:%02X:%02X:%02X:%02X", + PUBSUB_STR(args[0]), args[0], + ((args[1] >> 24) & 0xFF), ((args[1] >> 16) & 0xFF), + ((args[1] >> 8) & 0xFF), (args[1] & 0xFF), + ((args[2] >> 24) & 0xFF), ((args[2] >> 16) & 0xFF)); + break; + + case NAN_DBGID_SUBSCRIBE_UNMATCH_TIMEOUT_UPDATE: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, handle %u, match handle %u, old timeout %u, new timeout %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_SUBSCRIBE_MATCH_NEW: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, handle %u, match handle %u, timestamp %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_SUBSCRIBE_MATCH_REPEAT: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, handle %u, match handle %u, timestamp %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_SUBSCRIBE_MATCH_EXPIRED: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, handle %u, match handle %u, match timestamp %u, timestamp %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_SUBSCRIBE_MATCH_LOG: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s, handle %u, match handle %u, match timestamp %u, timestamp %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_SERVICE_ID_CREATED: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s %02X:%02X:%02X:%02X:%02X:%02X", DBG_MSG_ARR[dbg_id], + ((args[0] >> 24) & 0xFF), ((args[0] >> 16) & 0xFF), + ((args[0] >> 8) & 0xFF), (args[0] & 0xFF), + ((args[1] >> 24) & 0xFF), ((args[1] >> 16) & 0xFF)); + break; + + case NAN_DBGID_SD_ATTR_BUILT: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s, size %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_SERVICE_RSP_OFFSET: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_SERVICE_INFO_OFFSET: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_CHREQ_CREATE: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: chan %u, interval %u, start_time 0x%08X, duration %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_CHREQ_UPDATE: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: chan %u, interval %u, start_time 0x%08X, duration %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_CHREQ_REMOVE: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: chan %u, interval %u, status %d", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_CHREQ_GRANT: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: chan %u, %s, tsfLo 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], dbglog_get_nan_chan_type(args[1]), + args[2]); + break; + + case NAN_DBGID_CHREQ_END: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: chan %u, %s, tsfLo 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], dbglog_get_nan_chan_type(args[1]), + args[2]); + break; + + case NAN_DBGID_CHREQ_ERROR: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: chan %u, %s, tsfLo 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], dbglog_get_nan_chan_type(args[1]), + args[2]); + break; + + case NAN_DBGID_RX_CALLBACK: + if (numargs != 5) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: type 0x%X, length %u, timestamp 0x%08X, rssi %d, freq %d", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3], args[4]); + break; + + case NAN_DBGID_TX_COMPLETE: + if (numargs != 5) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: type 0x%X, handle %u, bufp %u, status %u, timestamp 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3], args[4]); + break; + + case NAN_DBGID_TSF_TIMEOUT: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: tsfLo 0x%X, usecs %u", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_SYNC_START: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: %s clusterId 0x%04x", + DBG_MSG_ARR[dbg_id], (args[1] ? "**STARTING**" : "**JOINING**"), + args[0]); + break; + + case NAN_DBGID_SYNC_STOP: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: stopping clusterId 0x%04x", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_NAN_SCAN: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: enable %u, type %u, rval %d", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_NAN_SCAN_COMPLETE: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: scan type %u completed", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_MPREF_CHANGE: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: new value=%u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_WARMUP_EXPIRE: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: masterPref=%u, randomFactor=%u", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_RANDOM_FACTOR_EXPIRE: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: new randomFactor=%u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_DW_SKIP: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: tsfLo 0x%08X, tsfDiff 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_DB_SKIP: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: reason %x, tsfDiff 0x%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_BEACON_RX: + /* args: TBD */ + if (numargs == 5) + { + A_UINT8 ctl = (args[0] >> 24) & 0xFF; + if (ctl == 0) + { + A_UINT8 mac[6]; + + mac[0] = args[0] & 0xFF; + mac[1] = (args[0] >> 8) & 0xFF; + mac[2] = args[1] & 0xFF; + mac[3] = (args[1] >> 8) & 0xFF; + mac[4] = (args[1] >> 16) & 0xFF; + mac[5] = (args[1] >> 24) & 0xFF; + + dbglog_printf(timestamp, vap_id, + "NAN Beacon from %02x:%02x:%02x:%02x:%02x:%02x, clusterId 0x%04x, " + "RSSI %d, TS 0x%08lx_%08lx", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + (args[2] >> 16) & 0xFFFF, + args[2] & 0xFF, + args[3], + args[4]); + } + else if (ctl == 1) + { + dbglog_printf(timestamp, vap_id, + " - Times: NAN TSF 0x%08lx_%08lx, hwRxTs 0x%08lx, statusFlags 0x%08lx", + args[1], + args[2], + args[3], + args[4]); + } + else if (ctl == 2) + { + dbglog_printf(timestamp, vap_id, + " - Attrs: [mpref=%d randf=%d], [amRank=0x%08lx_%08lx amHC=%d amBTT=%08lx]", + args[0] & 0xFF, + (args[0] >> 8) & 0xFF, + args[1], + args[2], + args[3], + args[4]); + } + else if (ctl == 3) + { + dbglog_printf(timestamp, vap_id, + " - AvgRssi: %u, numSamples=%u [%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u]", + (args[0]) & 0xFF, + (args[0] >> 8) & 0xFF, + (args[1]) & 0xFF, + (args[1] >> 8) & 0xFF, + (args[1] >> 16) & 0xFF, + (args[1] >> 24) & 0xFF, + (args[2]) & 0xFF, + (args[2] >> 8) & 0xFF, + (args[2] >> 16) & 0xFF, + (args[2] >> 24) & 0xFF, + (args[3]) & 0xFF, + (args[3] >> 8) & 0xFF, + (args[3] >> 16) & 0xFF, + (args[3] >> 24) & 0xFF, + (args[4]) & 0xFF, + (args[4] >> 8) & 0xFF, + (args[4] >> 16) & 0xFF, + (args[4] >> 24) & 0xFF); + } + else + { + dbglog_printf(timestamp, vap_id, "%s, unknown ctl value: %d", + DBG_MSG_ARR[dbg_id], ctl); + return FALSE; + } + } + else + { + char str[64] = { 0 }; + A_UINT16 i; + for (i=0; i < numargs; ++i) + { + snprintf(&str[i*9], sizeof(&str[i*9]), "%08X ", args[i]); + } + dbglog_printf(timestamp, vap_id, "%s: numargs %u, %s", + DBG_MSG_ARR[dbg_id], numargs, str); + } + break; + + case NAN_DBGID_BEACON_TX: + /* args: TBD */ + { + char str[64] = { 0 }; + A_UINT16 i; + for (i=0; i < numargs; ++i) + { + snprintf(&str[i*9], sizeof(&str[i*9]), "%08X ", args[i]); + } + dbglog_printf(timestamp, vap_id, "%s: numargs %u, %s", + DBG_MSG_ARR[dbg_id], numargs, str); + } + break; + + case NAN_DBGID_CLUSTER_MERGE: + if (numargs != 5) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: **MERGING** to clusterId 0x%04x [amRank=0x%08lx_%08lx, TS=%08lx_%08lx]", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3], args[4]); + break; + + case NAN_DBGID_TEST_CMD_EXEC: + if (numargs == 1) + { + dbglog_printf(timestamp, vap_id, "%s: cmd %u", + DBG_MSG_ARR[dbg_id], args[0]); + } + else if (numargs == 2) + { + dbglog_printf(timestamp, vap_id, "%s: cmd %u, status %d", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + } + else if (numargs == 3) + { + dbglog_printf(timestamp, vap_id, "%s: cmd %u, status %d, value %u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + } + else + { + dbglog_printf(timestamp, vap_id, "%s: too many args %u", + DBG_MSG_ARR[dbg_id], numargs); + return FALSE; + } + break; + + case NAN_DBGID_APPLY_BEACON_TSF: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: timestamp=0x%08X_%08X, age=%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_TSF_UPDATE: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: diff %c%d", + DBG_MSG_ARR[dbg_id], args[0] ? '-' : '+', args[1]); + break; + + case NAN_DBGID_SET_TSF: + if (numargs == 4) + { + dbglog_printf(timestamp, vap_id, + "%s: raw 0x%08X_%08X, nan 0x%08X_%08x", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + } + else if (numargs == 2) + { + dbglog_printf(timestamp, vap_id, "%s: offset 0x%08X_%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + } + else + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + break; + + case NAN_DBGID_NEW_MASTERRANK: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "%s: our rank is 0x%08X_%08x (mp=%d, rf=%d)", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + break; + + case NAN_DBGID_NEW_ANCHORMASTER: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + { + A_UINT8 mac[6]; + + mac[0] = args[1] & 0xFF; + mac[1] = (args[1] >> 8) & 0xFF; + mac[2] = (args[1] >> 16) & 0xFF; + mac[3] = (args[1] >> 24) & 0xFF; + mac[4] = args[0] & 0xFF; + mac[5] = (args[0] >> 8) & 0xFF; + dbglog_printf(timestamp, vap_id, + "%s: %02x:%02x:%02x:%02x:%02x:%02x, rank is 0x%08X_%08x (mp=%d, rf=%d)", + DBG_MSG_ARR[dbg_id], mac[0], mac[1], mac[2], mac[3], mac[4], + mac[5], args[0], args[1], args[2], args[3]); + } + break; + + case NAN_DBGID_ANCHORMASTER_RECORD_UPDATE: + if (numargs == 4) + { + dbglog_printf(timestamp, vap_id, + "%s: rank=0x%08X_%08x HC=%d BTT=0x%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + } + else if (numargs == 3) + { + dbglog_printf(timestamp, vap_id, + "%s: rank=0x%08X_%08x BTT=0x%08X (*Last*)", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + } + else + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + break; + + case NAN_DBGID_ANCHORMASTER_RECORD_EXPIRED: + if (numargs == 4) + { + dbglog_printf(timestamp, vap_id, + "%s: rank=0x%08X_%08x HC=%d BTT=0x%08X", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3]); + } + else if (numargs == 5) + { + dbglog_printf(timestamp, vap_id, + "%s: rank=0x%08X_%08x HC=%d BTT=0x%08X ==> Setting HC to %d", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2], args[3], args[4]); + } + else + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + break; + + case NAN_DBGID_BECOMING_ANCHORMASTER: + if (numargs != 2) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: reason=%d, transitionsToAM=%d", + DBG_MSG_ARR[dbg_id], args[0], args[1]); + break; + + case NAN_DBGID_ROLE_CHANGE: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: oldRole=%s, newRole=%s %s", + DBG_MSG_ARR[dbg_id], + dbglog_get_nan_role_str(args[0]), + dbglog_get_nan_role_str(args[1]), + args[2] ? "(**FORCED**)" : ""); + break; + + case NAN_DBGID_SYNC_BEACON_DW_STATS: + if (numargs != 4) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + { + A_UINT16 c1_close, c1_middle, c1_poor; + A_UINT16 c2_close, c2_middle, c2_poor; + c1_close = args[1] >> 16, + c2_close = args[1] & 0xFFFF, + c1_middle = args[2] >> 16, + c2_middle = args[2] & 0xFFFF, + c1_poor = args[3] >> 16, + c2_poor = args[3] & 0xFFFF, + + dbglog_printf(timestamp, vap_id, + "%s: total rx %d, c1=(%d/%d/%d) c1=(%d/%d/%d)", + DBG_MSG_ARR[dbg_id], args[0], c1_close, c1_middle, c1_poor, + c2_close, c2_middle, c2_poor); + } + break; + + case NAN_DBGID_RX_UNSUPPORTED_SDF_ATTR_ID: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_PUBSUB_MATCHED_SKIPPED_SSI: + if (numargs != 5) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg(s)", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, + "NAN %s %u matched and skipped because SSI is required, " + "instance id %u, requestor id %u, " + "svc id %02X:%02X:%02X:%02X:%02X:%02X, svcCtrl 0x%02X, len%u", + PUBSUB_STR(args[0]), args[0], + (args[2] & 0xFF), ((args[2] >> 8) && 0xFF), + ((args[1] >> 24) & 0xFF), ((args[1] >> 16) & 0xFF), + ((args[1] >> 8) & 0xFF), (args[1] & 0xFF), + ((args[2] >> 24) & 0xFF), ((args[2] >> 16) & 0xFF), + args[3], args[4]); + break; + + case NAN_DBGID_MATCH_FILTER_OFFSET: + if (numargs != 1) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s %u", + DBG_MSG_ARR[dbg_id], args[0]); + break; + + case NAN_DBGID_TW_PARAMS: + if (numargs != 3) + { + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + dbglog_printf(timestamp, vap_id, "%s: twSize=%u, n=%u, twIndex=%u", + DBG_MSG_ARR[dbg_id], args[0], args[1], args[2]); + break; + + case NAN_DBGID_BEACON_SENDER: + if (numargs == 1) + { + dbglog_printf(timestamp, vap_id, "%s: failed, reason %x", + DBG_MSG_ARR[dbg_id], args[0]); + } + else if (numargs == 3) + { + dbglog_printf(timestamp, vap_id, "%s: %s idx=%u sender 0x%08x", + DBG_MSG_ARR[dbg_id], args[0] ? "alloc" : "reclaim", args[1], args[2]); + } + else + { + + dbglog_printf(timestamp, vap_id, "%s, missing arg", + DBG_MSG_ARR[dbg_id]); + return FALSE; + } + break; + + default: + dbglog_printf(timestamp, vap_id, + "NAN unknown event id %u (should never reach this case)", dbg_id); + return FALSE; + } + + return TRUE; +} + +/* NAN message IDs */ +typedef enum +{ + NAN_MSG_ID_ERROR_RSP = 0, + NAN_MSG_ID_CONFIGURATION_REQ = 1, + NAN_MSG_ID_CONFIGURATION_RSP = 2, + NAN_MSG_ID_PUBLISH_SERVICE_REQ = 3, + NAN_MSG_ID_PUBLISH_SERVICE_RSP = 4, + NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ = 5, + NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP = 6, + NAN_MSG_ID_PUBLISH_REPLIED_IND = 7, + NAN_MSG_ID_PUBLISH_TERMINATED_IND = 8, + NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ = 9, + NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP = 10, + NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ = 11, + NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP = 12, + NAN_MSG_ID_SUBSCRIBE_MATCH_IND = 13, + NAN_MSG_ID_SUBSCRIBE_UNMATCH_IND = 14, + NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND = 15, + NAN_MSG_ID_DE_EVENT_IND = 16, + NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ = 17, + NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP = 18, + NAN_MSG_ID_FOLLOWUP_IND = 19, + NAN_MSG_ID_STATS_REQ = 20, + NAN_MSG_ID_STATS_RSP = 21, + NAN_MSG_ID_ENABLE_REQ = 22, + NAN_MSG_ID_ENABLE_RSP = 23, + NAN_MSG_ID_DISABLE_REQ = 24, + NAN_MSG_ID_DISABLE_RSP = 25, + NAN_MSG_ID_DISABLE_IND = 26, + NAN_MSG_ID_TCA_REQ = 27, + NAN_MSG_ID_TCA_RSP = 28, + NAN_MSG_ID_TCA_IND = 29, + NAN_MSG_ID_BCN_SDF_PAYLOAD_REQ = 30, + NAN_MSG_ID_BCN_SDF_PAYLOAD_RSP = 31, + NAN_MSG_ID_BCN_SDF_PAYLOAD_IND = 32, + NAN_MSG_ID_LAST +} tNanMsgId; + +/* NAN Event ID Codes */ +typedef enum +{ + NAN_EVENT_ID_FIRST = 0, + NAN_EVENT_ID_SELF_STA_MAC_ADDR = NAN_EVENT_ID_FIRST, + NAN_EVENT_ID_STARTED_CLUSTER, + NAN_EVENT_ID_JOINED_CLUSTER, + NAN_EVENT_ID_LAST +} tNanEventId; + +/* NAN Statistics Request ID Codes */ +typedef enum +{ + NAN_STATS_ID_FIRST = 0, + NAN_STATS_ID_DE_PUBLISH = NAN_STATS_ID_FIRST, + NAN_STATS_ID_DE_SUBSCRIBE, + NAN_STATS_ID_DE_MAC, + NAN_STATS_ID_DE_TIMING_SYNC, + NAN_STATS_ID_DE_DW, + NAN_STATS_ID_DE, + NAN_STATS_ID_LAST +} tNanStatsId; + +typedef enum +{ + NAN_TLV_TYPE_FIRST = 0, + + /* Service Discovery Frame types */ + NAN_TLV_TYPE_SDF_FIRST = NAN_TLV_TYPE_FIRST, + NAN_TLV_TYPE_SERVICE_NAME = NAN_TLV_TYPE_SDF_FIRST, + NAN_TLV_TYPE_SDF_MATCH_FILTER, + NAN_TLV_TYPE_TX_MATCH_FILTER, + NAN_TLV_TYPE_RX_MATCH_FILTER, + NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, + NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO, + NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, + NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE, + NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE, + NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE, + NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE, + NAN_TLV_TYPE_SDF_LAST = 4095, + + /* Configuration types */ + NAN_TLV_TYPE_CONFIG_FIRST = 4096, + NAN_TLV_TYPE_24G_SUPPORT = NAN_TLV_TYPE_CONFIG_FIRST, + NAN_TLV_TYPE_24G_BEACON, + NAN_TLV_TYPE_24G_SDF, + NAN_TLV_TYPE_24G_RSSI_CLOSE, + NAN_TLV_TYPE_24G_RSSI_MIDDLE, + NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, + NAN_TLV_TYPE_5G_SUPPORT, + NAN_TLV_TYPE_5G_BEACON, + NAN_TLV_TYPE_5G_SDF, + NAN_TLV_TYPE_5G_RSSI_CLOSE, + NAN_TLV_TYPE_5G_RSSI_MIDDLE, + NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, + NAN_TLV_TYPE_SID_BEACON, + NAN_TLV_TYPE_HOP_COUNT_LIMIT, + NAN_TLV_TYPE_MASTER_PREFERENCE, + NAN_TLV_TYPE_CLUSTER_ID_LOW, + NAN_TLV_TYPE_CLUSTER_ID_HIGH, + NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, + NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, + NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, + NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, + NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, + NAN_TLV_TYPE_DEBUGGING_FLAGS, + NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, + NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, + NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, + NAN_TLV_TYPE_HOP_COUNT_FORCE, + NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + NAN_TLV_TYPE_CONFIG_LAST = 8191, + + + /* Attributes types */ + NAN_TLV_TYPE_ATTRS_FIRST = 8192, + NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP = NAN_TLV_TYPE_ATTRS_FIRST, + NAN_TLV_TYPE_WLAN_MESH_ID, + NAN_TLV_TYPE_MAC_ADDRESS, + NAN_TLV_TYPE_RECEIVED_RSSI_VALUE, + NAN_TLV_TYPE_CLUSTER_ATTRIBUTE, + NAN_TLV_TYPE_ATTRS_LAST = 12287, + + /* Event types */ + NAN_TLV_TYPE_EVENTS_FIRST = 12288, + NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS = NAN_TLV_TYPE_EVENTS_FIRST, + NAN_TLV_TYPE_EVENT_STARTED_CLUSTER, + NAN_TLV_TYPE_EVENT_JOINED_CLUSTER, + NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS, + NAN_TLV_TYPE_EVENTS_LAST = 16383, + + /* Thrshold Cross Alerts types */ + NAN_TLV_TYPE_TCA_FIRST = 16384, + NAN_TLV_TYPE_CLUSTER_SIZE_REQ = NAN_TLV_TYPE_TCA_FIRST, + NAN_TLV_TYPE_CLUSTER_SIZE_RSP, + NAN_TLV_TYPE_TCA_LAST = 20479, + + /* Statistics types */ + NAN_TLV_TYPE_STATS_FIRST = 32768, + NAN_TLV_TYPE_DE_PUBLISH_STATS = NAN_TLV_TYPE_STATS_FIRST, + NAN_TLV_TYPE_DE_SUBSCRIBE_STATS, + NAN_TLV_TYPE_DE_MAC_STATS, + NAN_TLV_TYPE_DE_TIMING_SYNC_STATS, + NAN_TLV_TYPE_DE_DW_STATS, + NAN_TLV_TYPE_DE_STATS, + NAN_TLV_TYPE_STATS_LAST, + + NAN_TLV_TYPE_LAST = 65535 +} tNanTlvType; + +/* NAN Miscellaneous Constants */ +#define NAN_TTL_INFINITE 0 +#define NAN_REPLY_COUNT_INFINITE 0 + +/* NAN Publish Types */ +typedef enum +{ + NAN_PUBLISH_TYPE_UNSOLICITED = 0, + NAN_PUBLISH_TYPE_SOLICITED, + NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED, + NAN_PUBLISH_TYPE_LAST, +} tNanPublishType; + +/* NAN Transmit Types */ +typedef enum +{ + NAN_TX_TYPE_BROADCAST = 0, + NAN_TX_TYPE_UNICAST, + NAN_TX_TYPE_LAST +} tNanTxType; + +/* NAN Subscribe Type Bit */ +#define NAN_SUBSCRIBE_TYPE_PASSIVE 0 +#define NAN_SUBSCRIBE_TYPE_ACTIVE 1 + +/* NAN Service Response Filter Attribute Bit */ +#define NAN_SRF_ATTR_BLOOM_FILTER 0 +#define NAN_SRF_ATTR_PARTIAL_MAC_ADDR 1 + +/* NAN Service Response Filter Include Bit */ +#define NAN_SRF_INCLUDE_DO_NOT_RESPOND 0 +#define NAN_SRF_INCLUDE_RESPOND 1 + +/* NAN Match Algorithms */ +typedef enum +{ + NAN_MATCH_ALG_FIRST = 0, + NAN_MATCH_ALG_MATCH_ONCE = NAN_MATCH_ALG_FIRST, + NAN_MATCH_ALG_MATCH_CONTINUOUS, + NAN_MATCH_ALG_LAST +} tNanMatchAlg; + + +/* NAN Transmit Priorities */ +typedef enum +{ + NAN_TX_PRIORITY_LOW = 0, + NAN_TX_PRIORITY_NORMAL, + NAN_TX_PRIORITY_HIGH, + NAN_TX_PRIORITY_LAST +} tNanTxPriority; + +/* NAN TLV Maximum Lengths */ +#define NAN_MAX_SERVICE_NAME_LEN 255 +#define NAN_MAX_MATCH_FILTER_LEN 255 +#define NAN_MAX_SERVICE_SPECIFIC_INFO_LEN 255 +#define NAN_MAX_GROUP_KEY_LEN 32 +#define NAN_MAX_EXT_SERVICE_SPECIFIC_INFO_LEN 1024 +#define NAN_MAX_TLV_LEN NAN_MAX_EXT_SERVICE_SPECIFIC_INFO_LEN + +/* NAN Confguration 5G Channel Access Bit */ +#define NAN_5G_CHANNEL_ACCESS_UNSUPPORTED 0 +#define NAN_5G_CHANNEL_ACCESS_SUPPORTED 1 + +/* NAN Configuration Service IDs Enclosure Bit */ +#define NAN_SIDS_NOT_ENCLOSED_IN_BEACONS 0 +#define NAN_SIBS_ENCLOSED_IN_BECAONS 1 + +/* NAN Configuration Priority */ +#define NAN_CFG_PRIORITY_SERVICE_DISCOVERY 0 +#define NAN_CFG_PRIORITY_DATA_CONNECTION 1 + +/* NAN Configuration 5G Channel Usage */ +#define NAN_5G_CHANNEL_USAGE_SYNC_AND_DISCOVERY 0 +#define NAN_5G_CHANNEL_USAGE_DISCOVERY_ONLY 1 + +/* NAN Configuration TX_Beacon Content */ +#define NAN_TX_BEACON_CONTENT_OLD_AM_INFO 0 +#define NAN_TX_BEACON_CONTENT_UPDATED_AM_INFO 1 + +/* NAN Configuration Miscellaneous Constants */ +#define NAN_MAC_INTERFACE_PERIODICITY_MIN 30 +#define NAN_MAC_INTERFACE_PERIODICITY_MAX 255 + +#define NAN_DW_RANDOM_TIME_MIN 120 +#define NAN_DW_RANDOM_TIME_MAX 240 + +#define NAN_INITIAL_SCAN_MIN_IDEAL_PERIOD 200 +#define NAN_INITIAL_SCAN_MAX_IDEAL_PERIOD 300 + +#define NAN_ONGOING_SCAN_MIN_PERIOD 10 +#define NAN_ONGOING_SCAN_MAX_PERIOD 30 + +#define NAN_HOP_COUNT_LIMIT 5 + +#define NAN_WINDOW_DW 0 +#define NAN_WINDOW_FAW 1 + +/* TCA IDs */ +typedef enum +{ + NAN_TCA_ID_FIRST = 0, + NAN_TCA_ID_CLUSTER_SIZE = NAN_TCA_ID_FIRST, + NAN_TCA_ID_LAST +} tNanTcaId; + +/* NAN Status Codes */ +typedef enum +{ + NAN_STATUS_SUCCESS = 0, + NAN_STATUS_TIMEOUT, + NAN_STATUS_DE_FAILURE, + NAN_STATUS_INVALID_MSG_VERSION, + NAN_STATUS_INVALID_MSG_LEN, + NAN_STATUS_INVALID_MSG_ID, + NAN_STATUS_INVALID_HANDLE, + NAN_STATUS_NO_SPACE_AVAILABLE, + NAN_STATUS_INVALID_PUBLISH_TYPE, + NAN_STATUS_INVALID_TX_TYPE, + NAN_STATUS_INVALID_MATCH_ALGORITHM, + NAN_STATUS_DISABLE_IN_PROGRESS, + NAN_STATUS_INVALID_TLV_LEN, + NAN_STATUS_INVALID_TLV_TYPE, + NAN_STATUS_MISSING_TLV_TYPE, + NAN_STATUS_INVALID_TOTAL_TLVS_LEN, + NAN_STATUS_INVALID_MATCH_HANDLE, + NAN_STATUS_INVALID_TLV_VALUE, + NAN_STATUS_INVALID_TX_PRIORITY, + NAN_STATUS_INVALID_CONN_MAP, + + /* Config */ + NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096, + NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE, + NAN_STATUS_INVALID_HOP_COUNT_LIMIT, + NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE, + NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE, + NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE, + NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD, + NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE, + NAN_STATUS_INVALID_SCAN_CHANNEL, + NAN_STATUS_INVALID_POST_NAN_CONN_CAP_BITMAP, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_NUM_CHAN, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_AVAIL_INT_DURATION, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_CLASS, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_CHANNEL, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_AVAIL_INT_BITMAP, + NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_MAP_ID, + NAN_STATUS_INVALID_POST_DISC_CONN_TYPE, + NAN_STATUS_INVALID_POST_DISC_DEVICE_ROLE, + NAN_STATUS_INVALID_POST_DISC_AVAIL_INT_DURATION, + NAN_STATUS_MISSING_FURTHER_AVAIL_MAP, + + /* Terminated reasons */ + NAN_TERMINATED_REASON_INVALID = 8192, + NAN_TERMINATED_REASON_TIMEOUT, + NAN_TERMINATED_REASON_USER_REQUEST, + NAN_TERMINATED_REASON_FAILURE, + NAN_TERMINATED_REASON_COUNT_REACHED, + NAN_TERMINATED_REASON_DE_SHUTDOWN, + NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS, + NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED, + NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED, + NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY, + + NAN_STATUS_LAST +} tNanStatusType; + +typedef enum +{ + NAN_ROLE_INVALID = 0, + NAN_ROLE_NON_MASTER_NON_SYNC = 1, + NAN_ROLE_NON_MASTER_SYNC = 2, + NAN_ROLE_MASTER = 3 +} tNanRole; + +static const char * +dbglog_get_nan_msg_id_str( + A_UINT16 msg_id) +{ + switch (msg_id) + { + case NAN_MSG_ID_ERROR_RSP: + return "Error Rsp"; + case NAN_MSG_ID_CONFIGURATION_REQ: + return "Configuration Req"; + case NAN_MSG_ID_CONFIGURATION_RSP: + return "Configuration Rsp"; + case NAN_MSG_ID_PUBLISH_SERVICE_REQ: + return "Publish Service Req"; + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + return "Publish Service Rsp"; + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ: + return "Publish Service Cancel Req"; + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + return "Publish Service Cancel Rsp"; + case NAN_MSG_ID_PUBLISH_REPLIED_IND: + return "Publish Replied Ind"; + case NAN_MSG_ID_PUBLISH_TERMINATED_IND: + return "Publish Terminated Ind"; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ: + return "Subscribe Service Req"; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + return "Subscribe Service Rsp"; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ: + return "Subscribe Service Cancel Req"; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + return "Subscribe Service Cancel Rsp"; + case NAN_MSG_ID_SUBSCRIBE_MATCH_IND: + return "Subscribe Match Ind"; + case NAN_MSG_ID_SUBSCRIBE_UNMATCH_IND: + return "Subscribe Unmatch Ind"; + case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND: + return "Subscribe Terminated Ind"; + case NAN_MSG_ID_DE_EVENT_IND: + return "DE Event Ind"; + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ: + return "Transmit Followup Req"; + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + return "Transmit Followup Rsp"; + case NAN_MSG_ID_FOLLOWUP_IND: + return "Followup Ind"; + case NAN_MSG_ID_STATS_REQ: + return "Stats Req"; + case NAN_MSG_ID_STATS_RSP: + return "Stats Rsp"; + case NAN_MSG_ID_ENABLE_REQ: + return "Enable Req"; + case NAN_MSG_ID_ENABLE_RSP: + return "Enable Rsp"; + case NAN_MSG_ID_DISABLE_REQ: + return "Disable Req"; + case NAN_MSG_ID_DISABLE_RSP: + return "Disable Rsp"; + case NAN_MSG_ID_DISABLE_IND: + return "Disable Ind"; + case NAN_MSG_ID_TCA_REQ: + return "TCA Req"; + case NAN_MSG_ID_TCA_RSP: + return "TCA Rsp"; + case NAN_MSG_ID_TCA_IND: + return "TCA Ind"; + case NAN_MSG_ID_BCN_SDF_PAYLOAD_REQ: + return "BCN/SDF Payload Req"; + case NAN_MSG_ID_BCN_SDF_PAYLOAD_RSP: + return "BCN/SDF Payload Rsp"; + case NAN_MSG_ID_BCN_SDF_PAYLOAD_IND: + return "BCN/SDF Payload Ind"; + default: + return "Unknown Msg"; + } +} + +static const char * +dbglog_get_nan_status_str( + A_UINT32 status) +{ + switch (status) + { + case NAN_STATUS_SUCCESS: + return "Success"; + case NAN_STATUS_TIMEOUT: + return "Timeout"; + case NAN_STATUS_DE_FAILURE: + return "DE Failure"; + case NAN_STATUS_INVALID_MSG_VERSION: + return "Invalid Msg Version"; + case NAN_STATUS_INVALID_MSG_LEN: + return "Invalid Msg Len"; + case NAN_STATUS_INVALID_MSG_ID: + return "Invalid Msg Id"; + case NAN_STATUS_INVALID_HANDLE: + return "Invalid Handle"; + case NAN_STATUS_NO_SPACE_AVAILABLE: + return "No Space Available"; + case NAN_STATUS_INVALID_PUBLISH_TYPE: + return "Invalid Publish Type"; + case NAN_STATUS_INVALID_TX_TYPE: + return "Invalid Tx Type"; + case NAN_STATUS_INVALID_MATCH_ALGORITHM: + return "Invalid Match Algorithm"; + case NAN_STATUS_DISABLE_IN_PROGRESS: + return "Disable In Progress"; + case NAN_STATUS_INVALID_TLV_LEN: + return "Invalid TLV Len"; + case NAN_STATUS_INVALID_TLV_TYPE: + return "Invalid TLV Type"; + case NAN_STATUS_MISSING_TLV_TYPE: + return "Missing TLV Type"; + case NAN_STATUS_INVALID_TOTAL_TLVS_LEN: + return "Invalid Total TLVs Len"; + case NAN_STATUS_INVALID_TLV_VALUE: + return "Invalid TLV Value"; + case NAN_STATUS_INVALID_MATCH_HANDLE: + return "Invalid Match Handle"; + case NAN_STATUS_INVALID_TX_PRIORITY: + return "Invalid Tx Priority"; + case NAN_STATUS_INVALID_CONN_MAP: + return "Invalid Connection Capability Map"; + + /* Config */ + case NAN_STATUS_INVALID_RSSI_CLOSE_VALUE: + return "Invalid RSSI Close Value"; + case NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE: + return "Invalid RSSI Middle Value"; + case NAN_STATUS_INVALID_HOP_COUNT_LIMIT: + return "Hop Count Limit"; + case NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE: + return "Invalid Master Preference Value"; + case NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE: + return "Invalid Low Cluster ID Value"; + case NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE: + return "Invalid High Cluster ID Value"; + case NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD: + return "Invalid Background Scan Period"; + case NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE: + return "Invalid RSSI Proximity Value"; + case NAN_STATUS_INVALID_SCAN_CHANNEL: + return "Invalid Scan Channel"; + case NAN_STATUS_INVALID_POST_NAN_CONN_CAP_BITMAP: + return "Invalid Connection Capability Bitmap"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_NUM_CHAN: + return "Invalid Further Availability Map Num Channels"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_AVAIL_INT_DURATION: + return "Invalid Further Availability Map Availability Interval Duration"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_CLASS: + return "Invalid Further Availability Map Class"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_CHANNEL: + return "Invalid Further Availability Map Channel"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_AVAIL_INT_BITMAP: + return "Invalid Further Availability Map Bitmap"; + case NAN_STATUS_INVALID_FURTHER_AVAIL_MAP_MAP_ID: + return "Invalid Further Availability Map Map_ID"; + case NAN_STATUS_INVALID_POST_DISC_CONN_TYPE: + return "Invalid Post-Discovery Connection Type"; + case NAN_STATUS_INVALID_POST_DISC_DEVICE_ROLE: + return "Invalid Post-Discovery Device Role"; + case NAN_STATUS_INVALID_POST_DISC_AVAIL_INT_DURATION: + return "Invalid Post-Discovery Availability Interval Duration"; + case NAN_STATUS_MISSING_FURTHER_AVAIL_MAP: + return "Missing Further Availability Map"; + + /* Terminated reasons */ + case NAN_TERMINATED_REASON_INVALID: + return "Invalid"; + case NAN_TERMINATED_REASON_TIMEOUT: + return "Timeout"; + case NAN_TERMINATED_REASON_USER_REQUEST: + return "User Request"; + case NAN_TERMINATED_REASON_FAILURE: + return "Failure"; + case NAN_TERMINATED_REASON_COUNT_REACHED: + return "Count Reached"; + case NAN_TERMINATED_REASON_DE_SHUTDOWN: + return "DE Shutdown"; + case NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS: + return "Disable In Progress"; + case NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED: + return "Post-Discovery Attribute Expired"; + case NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED: + return "Post-Discovery Attribute Length Exceeded"; + case NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY: + return "Further Availability Map Empty"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_event_id_str( + A_UINT8 event_id) +{ + switch (event_id) + { + case NAN_EVENT_ID_SELF_STA_MAC_ADDR: + return "Self-Station MAC Addr"; + case NAN_EVENT_ID_STARTED_CLUSTER: + return "Started Cluster"; + case NAN_EVENT_ID_JOINED_CLUSTER: + return "Joined Cluster"; + default: + return "Unknown"; + } +} + +const char * +dbglog_get_nan_stats_id_str( + A_UINT8 stats_id) +{ + switch (stats_id) + { + case NAN_STATS_ID_DE_PUBLISH: + return "DE Publish"; + case NAN_STATS_ID_DE_SUBSCRIBE: + return "DE Subscribe"; + case NAN_STATS_ID_DE_MAC: + return "DE MAC"; + case NAN_STATS_ID_DE_TIMING_SYNC: + return "DE Timing Sync"; + case NAN_STATS_ID_DE_DW: + return "DE DW"; + case NAN_STATS_ID_DE: + return "DE"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_tlv_type_str( + A_UINT16 tlv_type) +{ + switch (tlv_type) + { + case NAN_TLV_TYPE_SERVICE_NAME: + return "Service Name"; + case NAN_TLV_TYPE_SDF_MATCH_FILTER: + return "SDF Match Filter"; + case NAN_TLV_TYPE_TX_MATCH_FILTER: + return "Tx Match Filter"; + case NAN_TLV_TYPE_RX_MATCH_FILTER: + return "Rx Match Filter"; + case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: + return "Service Specific Info"; + case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO: + return "Extended Service Specific Info"; + case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT: + return "VSA Transmit"; + case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE: + return "VSA Receive"; + case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE: + return "Post-NAN Capabilities Receive"; + case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE: + return "Post-NAN Discovery Receive"; + case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE: + return "Bcn/SDF Payload Receive"; + + // Config TLVs + case NAN_TLV_TYPE_24G_SUPPORT: + return "2.4G Support Enabled"; + case NAN_TLV_TYPE_24G_BEACON: + return "2.4G Beacon Support"; + case NAN_TLV_TYPE_24G_SDF: + return "2.4G SDF Support"; + case NAN_TLV_TYPE_24G_RSSI_CLOSE: + return "2.4G RSSI Close"; + case NAN_TLV_TYPE_24G_RSSI_MIDDLE: + return "2.4G RSSI Middle"; + case NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY: + return "2.4G RSSI Close Proximity"; + case NAN_TLV_TYPE_5G_SUPPORT: + return "5G Support Enabled"; + case NAN_TLV_TYPE_5G_BEACON: + return "5G Beacon Support"; + case NAN_TLV_TYPE_5G_SDF: + return "5G SDF Support"; + case NAN_TLV_TYPE_5G_RSSI_CLOSE: + return "5G RSSI Close"; + case NAN_TLV_TYPE_5G_RSSI_MIDDLE: + return "5G RSSI Middle"; + case NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY: + return "5G RSSI Close Proximity"; + case NAN_TLV_TYPE_SID_BEACON: + return "SID Beacon"; + case NAN_TLV_TYPE_HOP_COUNT_LIMIT: + return "Hop Count Limit"; + case NAN_TLV_TYPE_MASTER_PREFERENCE: + return "Master Preference"; + case NAN_TLV_TYPE_CLUSTER_ID_LOW: + return "Cluster ID Low"; + case NAN_TLV_TYPE_CLUSTER_ID_HIGH: + return "Cluster ID High"; + case NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE: + return "RSSI Averaging Window Size"; + case NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID: + return "Cluster OUI NetworkID"; + case NAN_TLV_TYPE_SOURCE_MAC_ADDRESS: + return "Source MAC Addr"; + case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF: + return "Cluster Attribute in SDF"; + case NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS: + return "Social Channel Scan Params"; + case NAN_TLV_TYPE_DEBUGGING_FLAGS: + return "Debugging Flags"; + case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT: + return "Post-NAN Capabilities Transmit"; + case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT: + return "Post-NAN Discovery Transmit"; + case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP: + return "Further Availability Map"; + case NAN_TLV_TYPE_HOP_COUNT_FORCE: + return "Hop Count Force"; + case NAN_TLV_TYPE_RANDOM_FACTOR_FORCE: + return "Random Factor Force"; + + + case NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP: + return "Availability Intervals Map"; + case NAN_TLV_TYPE_WLAN_MESH_ID: + return "WLAN Mesh ID"; + case NAN_TLV_TYPE_MAC_ADDRESS: + return "MAC Addr"; + case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: + return "Recevied RSSI Value"; + case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE: + return "Cluster Attr"; + + case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS: + return "Self MAC Addr"; + case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER: + return "Start Cluster Addr"; + case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER: + return "Joined Cluster Addr"; + case NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS: + return "Cluster Scan Results"; + + case NAN_TLV_TYPE_CLUSTER_SIZE_REQ: + return "TCA Cluster Size Req"; + case NAN_TLV_TYPE_CLUSTER_SIZE_RSP: + return "TCA Cluster Size Rsp"; + + case NAN_TLV_TYPE_DE_PUBLISH_STATS: + return "DE Publish Stats"; + case NAN_TLV_TYPE_DE_SUBSCRIBE_STATS: + return "DE Subscribe Stats"; + case NAN_TLV_TYPE_DE_MAC_STATS: + return "DE MAC Stats"; + case NAN_TLV_TYPE_DE_TIMING_SYNC_STATS: + return "DE Timing Sync Stats"; + case NAN_TLV_TYPE_DE_DW_STATS: + return "DE DW Stats"; + case NAN_TLV_TYPE_DE_STATS: + return "DE Stats"; + + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_publish_type_str( + A_UINT32 publish_type) +{ + switch (publish_type) + { + case NAN_PUBLISH_TYPE_UNSOLICITED: + return "Unsolicited"; + case NAN_PUBLISH_TYPE_SOLICITED: + return "Solicited"; + case NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED: + return "Unsolicited/Solicitted"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_tx_type_str( + A_UINT32 tx_type) +{ + switch (tx_type) + { + case NAN_TX_TYPE_BROADCAST: + return "Broadcast"; + case NAN_TX_TYPE_UNICAST: + return "Unicast"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_subscribe_type_str( + A_UINT8 subscribe_type) +{ + switch (subscribe_type) + { + case NAN_SUBSCRIBE_TYPE_PASSIVE: + return "Passive"; + case NAN_SUBSCRIBE_TYPE_ACTIVE: + return "Active"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_srf_attr_str( + A_UINT8 srf_attr) +{ + switch (srf_attr) + { + case NAN_SRF_ATTR_BLOOM_FILTER: + return "Bloom Filter"; + case NAN_SRF_ATTR_PARTIAL_MAC_ADDR: + return "Partial MAC Addr"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_src_include_bit_str( + A_UINT8 src_include_bit) +{ + switch (src_include_bit) + { + case NAN_SRF_INCLUDE_DO_NOT_RESPOND: + return "Do Not Respond"; + case NAN_SRF_INCLUDE_RESPOND: + return "Respond"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_match_alg_str( + A_UINT8 match_alg) +{ + switch (match_alg) + { + case NAN_MATCH_ALG_MATCH_ONCE: + return "Match Once"; + case NAN_MATCH_ALG_MATCH_CONTINUOUS: + return "Match Continuous"; + default: + return "Unknown"; + } +} + + +static const char * +dbglog_get_nan_tx_priority_str( + A_UINT32 tx_priority) +{ + switch (tx_priority) + { + case NAN_TX_PRIORITY_LOW: + return "Low"; + case NAN_TX_PRIORITY_NORMAL: + return "Normal"; + case NAN_TX_PRIORITY_HIGH: + return "High"; + default: + return "Unknown"; + } +} + +static const char * +dbglog_get_nan_window_str( + A_UINT8 window) +{ + switch (window) + { + case NAN_WINDOW_DW: + return "DW"; + case NAN_WINDOW_FAW: + return "FAW"; + default: + return "Unknown"; + } +} + + +static const char * +dbglog_get_nan_role_str( + A_UINT8 nan_role) +{ + switch (nan_role) + { + case NAN_ROLE_NON_MASTER_NON_SYNC: + return "NON-MASTER-NON-SYNC"; + case NAN_ROLE_NON_MASTER_SYNC: + return "NON-MASTER-SYNC"; + case NAN_ROLE_MASTER: + return "MASTER"; + case NAN_ROLE_INVALID: + break; + default: + break; + } + return "Unknown"; +} + +static const char * +dbglog_get_nan_chan_type( + A_UINT32 type) +{ + switch (type) + { + case 1: + return "Primary DW"; + case 2: + return "Primary DiscBcn"; + case 3: + return "Secondary DW"; + case 4: + return "Secondary DiscBcn"; + default: + break; + } + return "Invalid/Unknown"; +} + +/* + * NOTE: Use the following convenience macros with care!!! + * + * They expect that certain variables are present and also have specific uses, + * e.g. within switch case statements. + */ +#define GET_TYPE (args[0] >> 16) +#define GET_LENGTH (args[0] & 0xFFFFu) + +#define CHECK_TYPE(param_max, type) \ + if ((param_idx < (param_max)) && ((type) != NAN_TLV_TYPE_LAST)) \ + { \ + dbglog_printf(timestamp, vap_id, \ + " %s: unexpected type %u for parameter index %u", \ + __func__, (type), param_idx); \ + return; \ + } + +#define CHECK_LENGTH(rx_length, exp_length) \ + if ((rx_length) != (exp_length)) \ + { \ + dbglog_printf(timestamp, vap_id, \ + " %s: invalid size (%u vs. %u) for parameter index %u", \ + __func__, (rx_length), (exp_length), param_idx); \ + break; \ + } + +#define LOG_UNKNOWN_PARAM() \ + dbglog_printf(timestamp, vap_id, \ + " %s: unknown parameter with index %u, numargs %u", \ + __func__, param_idx, numargs); + +#if 1 +#define VAR64BIT(__lo, __hi) \ + (A_UINT64)((A_UINT64)(__lo & 0xFFFFFFFFull) | \ + (A_UINT64)(__hi & 0xFFFFFFFFull) << 32) +#endif + +static void +dbglog_nan_tlv_print_handler( + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + + if (type == NAN_TLV_TYPE_LAST) + { + dbglog_printf(timestamp, vap_id, + " %s: unexpected type %u for parameter index %u", + __func__, type); + return; + } + + char str[128] = { 0 }; + A_UINT16 arg_idx; + A_UINT16 byte_idx; + A_UINT16 shift; + A_UINT16 byteCount = 0; + + /* TLV data starts at args[1]. */ + for (arg_idx=1; arg_idx < numargs; ++arg_idx) + { + for (byte_idx=0, shift=24; byte_idx < 4; ++byte_idx, shift -= 8) + { + if (byteCount < length) + { + byteCount++; + snprintf(&str[STR_INDEX((arg_idx-1), byte_idx)], + sizeof(&str[STR_INDEX((arg_idx-1), byte_idx)]),"%02X ", + ((args[arg_idx] >> shift) & 0xFF)); + } + } + } + + dbglog_printf(timestamp, vap_id, " %s: %s", + dbglog_get_nan_tlv_type_str(type), str ); +} + +static void +dbglog_nan_error_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_configuration_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_configuration_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_publish_service_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(9, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " ttl: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " period: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " replyIndFlag: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " publishType: %s (%u)", + dbglog_get_nan_publish_type_str(args[1]), args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " txType: %s (%u)", + dbglog_get_nan_tx_type_str(args[1]), args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " useRssi: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " otaFlag: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " count: %u", args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " connMap: 0x%04X", args[1]); + // FIXME: decode this further. + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_publish_service_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_publish_service_cancel_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + LOG_UNKNOWN_PARAM(); +} + +static void +dbglog_nan_publish_service_cancel_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_publish_replied_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_publish_terminated_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " reason: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_subscribe_service_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(12, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " ttl: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " period: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " subscribeType: %s (%u)", + dbglog_get_nan_subscribe_type_str(args[1]), args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " srfAttr: %s (%u)", + dbglog_get_nan_srf_attr_str(args[1]), args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " srfInclude: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " srfSend: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " ssiRequired: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " matchAlg: %s (%u)", + dbglog_get_nan_match_alg_str(args[1]), args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " count: %u", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " useRssi: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " otaFlag: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " connMap: 0x%04X", args[1]); + // FIXME: decode this further. + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_subscribe_service_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_subscribe_service_cancel_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + LOG_UNKNOWN_PARAM(); +} + +static void +dbglog_nan_subscribe_service_cancel_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_subscribe_match_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " matchHandle: %u", args[1]); + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_subscribe_unmatch_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " matchHandle: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_subscribe_terminated_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " reason: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_de_event_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_transmit_followup_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " txPriority: %s (%u)", + dbglog_get_nan_tx_priority_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " window: %s (%u)", + dbglog_get_nan_window_str(args[1]), args[1]); + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_transmit_followup_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_followup_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, " window: %s (%u)", + dbglog_get_nan_window_str(args[1]), args[1]); + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_stats_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, + " statsId: %s (%u)", + dbglog_get_nan_stats_id_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " clear: %s (%u)", + BOOL_STR(args[1]), args[1]); + break; + + default: + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); + break; + } +} + +static void +dbglog_nan_publish_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(15, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishServiceReqMsgs: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishServiceRspMsgs: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishServiceCancelReqMsgs: %u", args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishServiceCancelRspMsgs: %u", args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishRepliedIndMsgs: %u", args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validPublishTerminatedIndMsgs: %u", args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validActiveSubscribes: %u", args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validMatches: %u", args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validFollowups: %u", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidPublishServiceReqMsgs: %u", args[1]); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidPublishServiceCancelReqMsgs: %u", args[1]); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidActiveSubscribes: %u", args[1]); + break; + + case 12: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidMatches: %u", args[1]); + break; + + case 13: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidFollowups: %u", args[1]); + break; + + case 14: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " publishCount: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_subscribe_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(17, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeServiceReqMsgs: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeServiceRspMsgs: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeServiceCancelReqMsgs: %u", args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeServiceCancelRspMsgs: %u", args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeTerminatedIndMsgs: %u", args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeMatchIndMsgs: %u", args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSubscribeUnmatchIndMsgs: %u", args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validSolicitedPublishes: %u", args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validMatches: %u", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validFollowups: %u", args[1]); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidSubscribeServiceReqMsgs: %u", args[1]); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidSubscribeServiceCancelReqMsgs: %u", args[1]); + break; + + case 12: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidSolicitedPublishes: %u", args[1]); + break; + + case 13: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidMatches: %u", args[1]); + break; + + case 14: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidFollowups: %u", args[1]); + break; + + case 15: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " subscribeCount: %u", args[1]); + break; + + case 16: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " bloomFilterIndex: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_mac_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(25, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validFrames: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validActionFrames: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validBeaconFrames: %u", args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " ignoredActionFrames: %u", args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " ignoredBeaconFrames: %u", args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidFrames: %u", args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidActionFrames: %u", args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidBeaconFrames: %u", args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidMacHeaders: %u", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidPafHeaders: %u", args[1]); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " nonNanBeaconFrames: %u", args[1]); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " earlyActionFrames: %u", args[1]); + break; + + case 12: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " inDwActionFrames: %u", args[1]); + break; + + case 13: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " lateActionFrames: %u", args[1]); + break; + + case 14: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " framesQueued: %u", args[1]); + break; + + case 15: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " totalTRSpUpdates: %u", args[1]); + break; + + case 16: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " completeByTRSp: %u", args[1]); + break; + + case 17: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " completeByTp75DW: %u", args[1]); + break; + + case 18: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " completeByTendDW: %u", args[1]); + break; + + case 19: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " lateActionFramesTx: %u", args[1]); + break; + + case 20: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " twIncreases: %u", args[1]); + break; + + case 21: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " twDecreases: %u", args[1]); + break; + + case 22: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " twChanges: %u", args[1]); + break; + + case 23: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " twHighwater: %u", args[1]); + break; + + case 24: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " bloomFilterIndex: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_timing_sync_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(36, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " currTsf: 0x%08lx_%08lx", args[2], args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " myRank: 0x%08lx_%08lx", args[2], args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " currAmRank: 0x%08lx_%08lx", args[2], args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " lastAmRank: 0x%08lx_%08lx", args[2], args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " currAmBTT: 0x%08lx", args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " lastAmBTT: 0x%08lx", args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, + " currAmHopCount: %u", args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, + " currRole: %s (%u)", + dbglog_get_nan_role_str(args[1]), args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, + " clusterId: 0x%04x", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " timeSpentInCurrRole: 0x%08lx_%08lx, %lu seconds", + args[2], args[1], (A_UINT32) (VAR64BIT(args[1], args[2])/1000000ull)); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " totalTimeSpentAsMaster: 0x%08lx_%08lx, %lu seconds", + args[2], args[1], (A_UINT32) (VAR64BIT(args[1], args[2])/1000000ull)); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " totalTimeSpentAsNonMasterSync: 0x%08lx_%08lx, %lu seconds", + args[2], args[1], (A_UINT32) (VAR64BIT(args[1], args[2])/1000000ull)); + break; + + case 12: + CHECK_LENGTH(length, sizeof(A_UINT64)); + dbglog_printf(timestamp, vap_id, + " totalTimeSpentAsNonMasterNonSync: 0x%08lx_%08lx, %lu seconds", + args[2], args[1], (A_UINT32) (VAR64BIT(args[1], args[2])/1000000ull)); + break; + + case 13: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " transitionsToAnchorMaster: %u", args[1]); + break; + + case 14: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " transitionsToMaster: %u", args[1]); + break; + + case 15: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " transitionsToNonMasterSync: %u", args[1]); + break; + + case 16: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " transitionsToNonMasterNonSync: %u", args[1]); + break; + + case 17: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrUpdateCount: %u", args[1]); + break; + + case 18: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrUpdateRankChangedCount: %u", args[1]); + break; + + case 19: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrUpdateBTTChangedCount: %u", args[1]); + break; + + case 20: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrUpdateHcChangedCount: %u", args[1]); + break; + + case 21: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrUpdateNewDeviceCount: %u", args[1]); + break; + + case 22: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amrExpireCount: %u", args[1]); + break; + + case 23: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " mergeCount: %u", args[1]); + break; + + case 24: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconsAboveHcLimit: %u", args[1]); + break; + + case 25: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconsBelowRssiThresh: %u", args[1]); + break; + + case 26: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconsIgnoredNoSpace: %u", args[1]); + break; + + case 27: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconsForOurCluster: %u", args[1]); + break; + + case 28: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconsForOtherCluster: %u", args[1]); + break; + + case 29: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconCancelRequests: %u", args[1]); + break; + + case 30: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconCancelFailures: %u", args[1]); + break; + + case 31: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconUpdateRequests: %u", args[1]); + break; + + case 32: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " beaconUpdateFailures: %u", args[1]); + break; + + case 33: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " syncBeaconTxAttempts: %u", args[1]); + break; + + case 34: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " syncBeaconTxFailures: %u", args[1]); + break; + + case 35: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " discBeaconTxAttempts: %u", args[1]); + break; + + case 36: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " discBeaconTxFailures: %u", args[1]); + break; + + case 37: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " amHopCountExpireCount: %u", args[1]); + break; + + case 38: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " reserved: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_dw_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + /* DW stats are the same as MAC stats. */ + dbglog_nan_mac_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_de_stats_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(23, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validErrorRspMsgs: %u", args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validTransmitFollowupReqMsgs: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validTransmitFollowupRspMsgs: %u", args[1]); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validFollowupIndMsgs: %u", args[1]); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validConfigurationReqMsgs: %u", args[1]); + break; + + case 5: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validConfigurationRspMsgs: %u", args[1]); + break; + + case 6: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validStatsReqMsgs: %u", args[1]); + break; + + case 7: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validStatsRspMsgs: %u", args[1]); + break; + + case 8: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validEnableReqMsgs: %u", args[1]); + break; + + case 9: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validEnableRspMsgs: %u", args[1]); + break; + + case 10: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validDisableReqMsgs: %u", args[1]); + break; + + case 11: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validDisableRspMsgs: %u", args[1]); + break; + + case 12: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validDisableIndMsgs: %u", args[1]); + break; + + case 13: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validEventIndMsgs: %u", args[1]); + break; + + case 14: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validTcaReqMsgs: %u", args[1]); + break; + + case 15: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validTcaRspMsgs: %u", args[1]); + break; + + case 16: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validTcaIndMsgs: %u", args[1]); + break; + + case 17: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidTransmitFollowupReqMsgs: %u", args[1]); + break; + + case 18: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidConfigurationReqMsgs: %u", args[1]); + break; + + case 19: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidStatsReqMsgs: %u", args[1]); + break; + + case 20: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidEnableReqMsgs: %u", args[1]); + break; + + case 21: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidDisableReqMsgs: %u", args[1]); + break; + + case 22: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidTcaReqMsgs: %u", args[1]); + break; + + case 23: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validBcnSdfPayloadReqMsgs: %u", args[1]); + break; + + case 24: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validBcnSdfPayloadRspMsgs: %u", args[1]); + break; + + case 25: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " validBcnSdfPayloadIndMsgs: %u", args[1]); + break; + + case 26: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, + " invalidBcnSdfPayloadReqMsgs: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_stats_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static A_UINT8 stats_id = NAN_STATS_ID_LAST; + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + //CHECK_TYPE(3, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_UINT8)); + dbglog_printf(timestamp, vap_id, + " statsId: %s (%u)", + dbglog_get_nan_stats_id_str(args[1]), args[1]); + stats_id = (A_UINT8)args[1]; + break; + + default: + if (NAN_STATS_ID_LAST == stats_id) + { + dbglog_printf(timestamp, vap_id, "Stats ID not set yet"); + break; + } + + /* -3 for the status, length, and stats ID already processed. */ + param_idx -= 3; + + switch (stats_id) + { + case NAN_STATS_ID_DE_PUBLISH: + dbglog_nan_publish_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_STATS_ID_DE_SUBSCRIBE: + dbglog_nan_subscribe_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_STATS_ID_DE_MAC: + dbglog_nan_mac_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_STATS_ID_DE_TIMING_SYNC: + dbglog_nan_timing_sync_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_STATS_ID_DE_DW: + dbglog_nan_dw_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_STATS_ID_DE: + dbglog_nan_de_stats_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + default: + dbglog_printf(timestamp, vap_id, "Invalid stats id %u", stats_id); + break; + } + break; + } +} + +static void +dbglog_nan_enable_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_enable_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_disable_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + LOG_UNKNOWN_PARAM(); +} + +static void +dbglog_nan_disable_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_disable_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " reason: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_tca_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(5, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " tcaTlv: %s (%u)", + dbglog_get_nan_tlv_type_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " rising: %s", BOOL_STR(args[1])); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " falling: %s", BOOL_STR(args[1])); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " clear: %s", BOOL_STR(args[1])); + break; + + case 4: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, " threshold: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_tca_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(2, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_tca_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(4, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " tcaTlv: %s (%u)", + dbglog_get_nan_tlv_type_str(args[1]), args[1]); + break; + + case 1: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " rising: %s", BOOL_STR(args[1])); + break; + + case 2: + CHECK_LENGTH(length, sizeof(A_BOOL)); + dbglog_printf(timestamp, vap_id, " falling: %s", BOOL_STR(args[1])); + break; + + case 3: + CHECK_LENGTH(length, sizeof(A_UINT32)); + dbglog_printf(timestamp, vap_id, " value: %u", args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + +static void +dbglog_nan_bcn_sdf_payload_req_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + //A_UINT16 type = GET_TYPE; + //A_UINT16 length = GET_LENGTH; + //CHECK_TYPE(0, type); + + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static void +dbglog_nan_bcn_sdf_payload_rsp_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + A_UINT16 type = GET_TYPE; + A_UINT16 length = GET_LENGTH; + CHECK_TYPE(1, type); + + switch (param_idx) + { + case 0: + CHECK_LENGTH(length, sizeof(A_UINT16)); + dbglog_printf(timestamp, vap_id, " status: %s (%u)", + dbglog_get_nan_status_str(args[1]), args[1]); + break; + + default: + LOG_UNKNOWN_PARAM(); + break; + } +} + + + +static void +dbglog_nan_bcn_sdf_payload_ind_msg_print_handler( + A_UINT32 param_idx, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + //A_UINT16 type = GET_TYPE; + //A_UINT16 length = GET_LENGTH; + //CHECK_TYPE(0, type); + + dbglog_nan_tlv_print_handler(vap_id, dbg_id, timestamp, numargs, args); +} + +static A_BOOL +dbglog_nan_api_msg_print_handler( + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static A_UINT32 msg_id = NAN_MSG_ID_LAST; + static A_UINT32 param_idx = 0; + + if (dbg_id == NAN_DBGID_API_MSG_HEADER) + { + param_idx = 0; + msg_id = args[0]; + + if (args[0] < NAN_MSG_ID_LAST) + { + dbglog_printf(timestamp, vap_id, + "NAN %s/%u (version %u, id %u, length %u, handle %u, " + "transaction id %u)", + dbglog_get_nan_msg_id_str(args[0]), args[0], + args[1], args[0], args[2], args[3], args[4]); + } + else + { + dbglog_printf(timestamp, vap_id, + "NAN unknown msg %u (version %u, length %u, handle %u, " + "transaction id %u)", + args[0], args[1], args[2], args[3], args[4]); + } + return TRUE; + } + else if (dbg_id == NAN_DBGID_API_MSG_DATA) + { + switch (msg_id) + { + case NAN_MSG_ID_ERROR_RSP: + dbglog_nan_error_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_CONFIGURATION_REQ: + dbglog_nan_configuration_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_CONFIGURATION_RSP: + dbglog_nan_configuration_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_SERVICE_REQ: + dbglog_nan_publish_service_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + dbglog_nan_publish_service_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ: + dbglog_nan_publish_service_cancel_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + dbglog_nan_publish_service_cancel_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_REPLIED_IND: + dbglog_nan_publish_replied_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_PUBLISH_TERMINATED_IND: + dbglog_nan_publish_terminated_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ: + dbglog_nan_subscribe_service_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + dbglog_nan_subscribe_service_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ: + dbglog_nan_subscribe_service_cancel_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + dbglog_nan_subscribe_service_cancel_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_MATCH_IND: + dbglog_nan_subscribe_match_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_UNMATCH_IND: + dbglog_nan_subscribe_unmatch_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND: + dbglog_nan_subscribe_terminated_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_DE_EVENT_IND: + dbglog_nan_de_event_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ: + dbglog_nan_transmit_followup_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + dbglog_nan_transmit_followup_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_FOLLOWUP_IND: + dbglog_nan_followup_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_STATS_REQ: + dbglog_nan_stats_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_STATS_RSP: + dbglog_nan_stats_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_ENABLE_REQ: + dbglog_nan_enable_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_ENABLE_RSP: + dbglog_nan_enable_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_DISABLE_REQ: + dbglog_nan_disable_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_DISABLE_RSP: + dbglog_nan_disable_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_DISABLE_IND: + dbglog_nan_disable_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_TCA_REQ: + dbglog_nan_tca_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_TCA_RSP: + dbglog_nan_tca_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_TCA_IND: + dbglog_nan_tca_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_BCN_SDF_PAYLOAD_REQ: + dbglog_nan_bcn_sdf_payload_req_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_BCN_SDF_PAYLOAD_RSP: + dbglog_nan_bcn_sdf_payload_rsp_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + case NAN_MSG_ID_BCN_SDF_PAYLOAD_IND: + dbglog_nan_bcn_sdf_payload_ind_msg_print_handler( + param_idx, vap_id, dbg_id, timestamp, numargs, args); + break; + + + default: + LOG_UNKNOWN_PARAM(); + break; + } + + param_idx++; + return TRUE; + } + else + { + return FALSE; + } +} + +static A_BOOL +dbglog_nan_ota_pkt_print_handler( + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + if (dbg_id == NAN_DBGID_OTA_PKT_HEADER) + { + dbglog_printf(timestamp, vap_id, "%s %s, length %u", + DBG_MSG_ARR[dbg_id], + (args[0] ? "transmitted" : "received"), args[1]); + return TRUE; + } + + if (dbg_id == NAN_DBGID_OTA_PKT_DATA) + { + char str[128]; + A_UINT16 arg_idx; + A_UINT16 byte_idx; + A_UINT16 shift; + + for (arg_idx=0; arg_idx < numargs; ++arg_idx) + { + for (byte_idx=0, shift=24; byte_idx < 4; ++byte_idx, shift -= 8) + { + snprintf(&str[STR_INDEX(arg_idx, byte_idx)], + sizeof(&str[STR_INDEX(arg_idx, byte_idx)]), "%02X ", + ((args[arg_idx] >> shift) & 0xFF)); + } + } + + dbglog_printf(timestamp, vap_id, "%s: %s", DBG_MSG_ARR[dbg_id], str); + return TRUE; + } + + return FALSE; +} + +A_BOOL +dbglog_nan_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + if ((dbg_id >= NAN_DBGID_DBG_LOG_BASE) && + (dbg_id < NAN_DBGID_DBG_LOG_LAST)) + { + return dbglog_nan_debug_print_handler( + vap_id, dbg_id, timestamp, numargs, args); + } + else if ((dbg_id >= NAN_DBGID_EVT_BASE) && + (dbg_id < NAN_DBGID_EVT_LOG_LAST)) + { + return dbglog_nan_event_print_handler( + vap_id, dbg_id, timestamp, numargs, args); + } + else if ((dbg_id >= NAN_DBGID_API_MSG_BASE) && + (dbg_id < NAN_DBGID_API_MSG_LAST)) + { + return dbglog_nan_api_msg_print_handler( + vap_id, dbg_id, timestamp, numargs, args); + } + else if ((dbg_id >= NAN_DBGID_OTA_PKT_BASE) && + (dbg_id < NAN_DBGID_OTA_PKT_LAST)) + { + return dbglog_nan_ota_pkt_print_handler( + vap_id, dbg_id, timestamp, numargs, args); + } + else if (dbg_id == DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG) + { + static const char *states[] = + { + "IDLE", + "WAIT", + "STARTING", + "JOINING", + "ACTIVE", + "MERGING" + }; + + static const char *events[] = + { + "NONE", + "STARTSM", + "STOPSM", + "BEACON_RECVD", + "WAIT_TIMEOUT", + "START_TIMEOUT", + "DELAYED_START", + "BGSCAN_TIMEOUT", + "SCAN_TIMEOUT", + "SCAN_COMPLETE", + "CLUSTER_MERGE", + "UNKNOWN" + }; + + dbglog_sm_print(timestamp, vap_id, numargs, args, "NAN Cluster SM", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + return TRUE; + } + + return FALSE; +} + diff --git a/drivers/staging/qcacld-2.0/tools/fwdebuglog/parser.c b/drivers/staging/qcacld-2.0/tools/fwdebuglog/parser.c new file mode 100644 index 0000000000000..cad613d3fc7bd --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/fwdebuglog/parser.c @@ -0,0 +1,2839 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "dbglog.h" +#include "dbglog_id.h" +#include "dbglog_host.h" +#include "msg.h" +#include "msgcfg.h" +#include "diag_lsm.h" +#include "log.h" + +#include "a_debug.h" +#include "ol_defines.h" +#include "ah_osdep.h" + + +#ifdef CONFIG_ANDROID_LOG + +#include + +#define FWDEBUG_LOG_NAME "ROME" +#define FWDEBUG_NAME "ROME_DEBUG" +#define android_printf(...) \ + __android_log_print(ANDROID_LOG_INFO, FWDEBUG_LOG_NAME, __VA_ARGS__); + +#define debug_printf(...) do { \ + if (optionflag & DEBUG_FLAG) \ + __android_log_print(ANDROID_LOG_INFO, FWDEBUG_NAME, __VA_ARGS__); \ +} while(0) +#else +#define android_printf printf +#define debug_printf(...) do {} while(0); +#endif + +#define qxdm_log(buf) MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_HIGH, "%s", buf); + +unsigned char buf[RECLEN]; +extern int optionflag; +extern int32_t max_records; +extern int32_t record; +extern FILE *log_out; + +#define MAX_DBG_MSGS 256 + +module_dbg_print mod_print[WLAN_MODULE_ID_MAX]; + +void +diag_print_legacy_logs(const char *buf) +{ + uint32_t res; + + if (optionflag & QXDM_FLAG) { + qxdm_log(buf); + } + + if (optionflag & LOGFILE_FLAG) { + record++; + if (log_out) + fprintf(log_out, "%s\n", buf); + else + return; + if (record == max_records) { + record = 0; + fseek(log_out, record, SEEK_SET); + } + } + if (optionflag & CONSOLE_FLAG) { + android_printf("%s\n", buf); + } +} + +int +diag_msg_handler(uint32_t id, char *payload, uint16_t vdevid, + uint32_t timestamp) +{ + uint32_t moduleid = 0; + moduleid = (id >> 9) & 0x3F; + if (moduleid >= WLAN_MODULE_ID_MAX) + return 0; + if (mod_print[moduleid] != NULL) { + if (!(mod_print[moduleid](moduleid, vdevid, + DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG, + timestamp, 4, ( uint32_t *)payload))) { + return 0; + } + return 1; + } + return 0; +} + +extern A_BOOL +dbglog_nan_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args); + +const char *dbglog_get_module_str(A_UINT32 module_id) +{ + switch (module_id) { + case WLAN_MODULE_INF: + return "INF"; + case WLAN_MODULE_WMI: + return "WMI"; + case WLAN_MODULE_STA_PWRSAVE: + return "STA PS"; + case WLAN_MODULE_WHAL: + return "WHAL"; + case WLAN_MODULE_COEX: + return "COEX"; + case WLAN_MODULE_ROAM: + return "ROAM"; + case WLAN_MODULE_RESMGR_CHAN_MANAGER: + return "CHANMGR"; + case WLAN_MODULE_RESMGR: + return "RESMGR"; + case WLAN_MODULE_VDEV_MGR: + return "VDEV"; + case WLAN_MODULE_SCAN: + return "SCAN"; + case WLAN_MODULE_RATECTRL: + return "RC"; + case WLAN_MODULE_AP_PWRSAVE: + return "AP PS"; + case WLAN_MODULE_BLOCKACK: + return "BA"; + case WLAN_MODULE_MGMT_TXRX: + return "MGMT"; + case WLAN_MODULE_DATA_TXRX: + return "DATA"; + case WLAN_MODULE_HTT: + return "HTT"; + case WLAN_MODULE_HOST: + return "HOST"; + case WLAN_MODULE_BEACON: + return "BEACON"; + case WLAN_MODULE_OFFLOAD: + return "OFFLOAD"; + case WLAN_MODULE_WAL: + return "WAL"; + case WAL_MODULE_DE: + return "DE"; + case WLAN_MODULE_PCIELP: + return "PCIELP"; + case WLAN_MODULE_RTT: + return "RTT"; + case WLAN_MODULE_DCS: + return "DCS"; + case WLAN_MODULE_CACHEMGR: + return "CACHEMGR"; + case WLAN_MODULE_ANI: + return "ANI"; + case WLAN_MODULE_TEST: + return "TESTPOINT"; + case WLAN_MODULE_STA_SMPS: + return "STA_SMPS"; + case WLAN_MODULE_TDLS: + return "TDLS"; + case WLAN_MODULE_P2P: + return "P2P"; + case WLAN_MODULE_WOW: + return "WoW"; + case WLAN_MODULE_IBSS_PWRSAVE: + return "IBSS PS"; + case WLAN_MODULE_EXTSCAN: + return "ExtScan"; + case WLAN_MODULE_UNIT_TEST: + return "UNIT_TEST"; + case WLAN_MODULE_MLME: + return "MLME"; + case WLAN_MODULE_SUPPL: + return "SUPPLICANT"; + default: + return "UNKNOWN"; + } +} + +char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = +{ + { + "INF_MSG_START", + "INF_ASSERTION_FAILED", + "INF_TARGET_ID", + "INF_MSG_END" + }, + { + "WMI_DBGID_DEFINITION_START", + "WMI_CMD_RX_XTND_PKT_TOO_SHORT", + "WMI_EXTENDED_CMD_NOT_HANDLED", + "WMI_CMD_RX_PKT_TOO_SHORT", + "WMI_CALLING_WMI_EXTENSION_FN", + "WMI_CMD_NOT_HANDLED", + "WMI_IN_SYNC", + "WMI_TARGET_WMI_SYNC_CMD", + "WMI_SET_SNR_THRESHOLD_PARAMS", + "WMI_SET_RSSI_THRESHOLD_PARAMS", + "WMI_SET_LQ_TRESHOLD_PARAMS", + "WMI_TARGET_CREATE_PSTREAM_CMD", + "WMI_WI_DTM_INUSE", + "WMI_TARGET_DELETE_PSTREAM_CMD", + "WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD", + "WMI_TARGET_GET_BIT_RATE_CMD", + "WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS", + "WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD", + "WMI_TARGET_GET_TX_PWR_CMD", + "WMI_FREE_EVBUF_WMIBUF", + "WMI_FREE_EVBUF_DATABUF", + "WMI_FREE_EVBUF_BADFLAG", + "WMI_HTC_RX_ERROR_DATA_PACKET", + "WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX", + "WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT", + "WMI_SENDING_READY_EVENT", + "WMI_SETPOWER_MDOE_TO_MAXPERF", + "WMI_SETPOWER_MDOE_TO_REC", + "WMI_BSSINFO_EVENT_FROM", + "WMI_TARGET_GET_STATS_CMD", + "WMI_SENDING_SCAN_COMPLETE_EVENT", + "WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT ", + "WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT", + "WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT", + "WMI_SENDING_ERROR_REPORT_EVENT", + "WMI_SENDING_CAC_EVENT", + "WMI_TARGET_GET_ROAM_TABLE_CMD", + "WMI_TARGET_GET_ROAM_DATA_CMD", + "WMI_SENDING_GPIO_INTR_EVENT", + "WMI_SENDING_GPIO_ACK_EVENT", + "WMI_SENDING_GPIO_DATA_EVENT", + "WMI_CMD_RX", + "WMI_CMD_RX_XTND", + "WMI_EVENT_SEND", + "WMI_EVENT_SEND_XTND", + "WMI_CMD_PARAMS_DUMP_START", + "WMI_CMD_PARAMS_DUMP_END", + "WMI_CMD_PARAMS", + "WMI_EVENT_ALLOC_FAILURE", + "WMI_DBGID_DCS_PARAM_CMD", + "WMI_SEND_EVENT_WRONG_TLV", + "WMI_SEND_EVENT_NO_TLV_DEF", + "WMI_DBGID_DEFNITION_END", + }, + { + "PS_STA_DEFINITION_START", + "PS_STA_PM_ARB_REQUEST", + "PS_STA_DELIVER_EVENT", + "PS_STA_PSPOLL_SEQ_DONE", + "PS_STA_COEX_MODE", + "PS_STA_PSPOLL_ALLOW", + "PS_STA_SET_PARAM", + "PS_STA_SPECPOLL_TIMER_STARTED", + "PS_STA_SPECPOLL_TIMER_STOPPED", + }, + { + "WHAL_DBGID_DEFINITION_START", + "WHAL_ERROR_ANI_CONTROL", + "WHAL_ERROR_CHIP_TEST1", + "WHAL_ERROR_CHIP_TEST2", + "WHAL_ERROR_EEPROM_CHECKSUM", + "WHAL_ERROR_EEPROM_MACADDR", + "WHAL_ERROR_INTERRUPT_HIU", + "WHAL_ERROR_KEYCACHE_RESET", + "WHAL_ERROR_KEYCACHE_SET", + "WHAL_ERROR_KEYCACHE_TYPE", + "WHAL_ERROR_KEYCACHE_TKIPENTRY", + "WHAL_ERROR_KEYCACHE_WEPLENGTH", + "WHAL_ERROR_PHY_INVALID_CHANNEL", + "WHAL_ERROR_POWER_AWAKE", + "WHAL_ERROR_POWER_SET", + "WHAL_ERROR_RECV_STOPDMA", + "WHAL_ERROR_RECV_STOPPCU", + "WHAL_ERROR_RESET_CHANNF1", + "WHAL_ERROR_RESET_CHANNF2", + "WHAL_ERROR_RESET_PM", + "WHAL_ERROR_RESET_OFFSETCAL", + "WHAL_ERROR_RESET_RFGRANT", + "WHAL_ERROR_RESET_RXFRAME", + "WHAL_ERROR_RESET_STOPDMA", + "WHAL_ERROR_RESET_ERRID", + "WHAL_ERROR_RESET_ADCDCCAL1", + "WHAL_ERROR_RESET_ADCDCCAL2", + "WHAL_ERROR_RESET_TXIQCAL", + "WHAL_ERROR_RESET_RXIQCAL", + "WHAL_ERROR_RESET_CARRIERLEAK", + "WHAL_ERROR_XMIT_COMPUTE", + "WHAL_ERROR_XMIT_NOQUEUE", + "WHAL_ERROR_XMIT_ACTIVEQUEUE", + "WHAL_ERROR_XMIT_BADTYPE", + "WHAL_ERROR_XMIT_STOPDMA", + "WHAL_ERROR_INTERRUPT_BB_PANIC", + "WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW", + "WHAL_ERROR_QCU_HW_PAUSE_MISMATCH", + "WHAL_DBGID_DEFINITION_END", + }, + { + "COEX_DEBUGID_START", + "BTCOEX_DBG_MCI_1", + "BTCOEX_DBG_MCI_2", + "BTCOEX_DBG_MCI_3", + "BTCOEX_DBG_MCI_4", + "BTCOEX_DBG_MCI_5", + "BTCOEX_DBG_MCI_6", + "BTCOEX_DBG_MCI_7", + "BTCOEX_DBG_MCI_8", + "BTCOEX_DBG_MCI_9", + "BTCOEX_DBG_MCI_10", + "COEX_WAL_BTCOEX_INIT", + "COEX_WAL_PAUSE", + "COEX_WAL_RESUME", + "COEX_UPDATE_AFH", + "COEX_HWQ_EMPTY_CB", + "COEX_MCI_TIMER_HANDLER", + "COEX_MCI_RECOVER", + "ERROR_COEX_MCI_ISR", + "ERROR_COEX_MCI_GPM", + "COEX_ProfileType", + "COEX_LinkID", + "COEX_LinkState", + "COEX_LinkRole", + "COEX_LinkRate", + "COEX_VoiceType", + "COEX_TInterval", + "COEX_WRetrx", + "COEX_Attempts", + "COEX_PerformanceState", + "COEX_LinkType", + "COEX_RX_MCI_GPM_VERSION_QUERY", + "COEX_RX_MCI_GPM_VERSION_RESPONSE", + "COEX_RX_MCI_GPM_STATUS_QUERY", + "COEX_STATE_WLAN_VDEV_DOWN", + "COEX_STATE_WLAN_VDEV_START", + "COEX_STATE_WLAN_VDEV_CONNECTED", + "COEX_STATE_WLAN_VDEV_SCAN_STARTED", + "COEX_STATE_WLAN_VDEV_SCAN_END", + "COEX_STATE_WLAN_DEFAULT", + "COEX_CHANNEL_CHANGE", + "COEX_POWER_CHANGE", + "COEX_CONFIG_MGR", + "COEX_TX_MCI_GPM_BT_CAL_REQ", + "COEX_TX_MCI_GPM_BT_CAL_GRANT", + "COEX_TX_MCI_GPM_BT_CAL_DONE", + "COEX_TX_MCI_GPM_WLAN_CAL_REQ", + "COEX_TX_MCI_GPM_WLAN_CAL_GRANT", + "COEX_TX_MCI_GPM_WLAN_CAL_DONE", + "COEX_TX_MCI_GPM_BT_DEBUG", + "COEX_TX_MCI_GPM_VERSION_QUERY", + "COEX_TX_MCI_GPM_VERSION_RESPONSE", + "COEX_TX_MCI_GPM_STATUS_QUERY", + "COEX_TX_MCI_GPM_HALT_BT_GPM", + "COEX_TX_MCI_GPM_WLAN_CHANNELS", + "COEX_TX_MCI_GPM_BT_PROFILE_INFO", + "COEX_TX_MCI_GPM_BT_STATUS_UPDATE", + "COEX_TX_MCI_GPM_BT_UPDATE_FLAGS", + "COEX_TX_MCI_GPM_UNKNOWN", + "COEX_TX_MCI_SYS_WAKING", + "COEX_TX_MCI_LNA_TAKE", + "COEX_TX_MCI_LNA_TRANS", + "COEX_TX_MCI_SYS_SLEEPING", + "COEX_TX_MCI_REQ_WAKE", + "COEX_TX_MCI_REMOTE_RESET", + "COEX_TX_MCI_TYPE_UNKNOWN", + "COEX_WHAL_MCI_RESET", + "COEX_POLL_BT_CAL_DONE_TIMEOUT", + "COEX_WHAL_PAUSE", + "COEX_RX_MCI_GPM_BT_CAL_REQ", + "COEX_RX_MCI_GPM_BT_CAL_DONE", + "COEX_RX_MCI_GPM_BT_CAL_GRANT", + "COEX_WLAN_CAL_START", + "COEX_WLAN_CAL_RESULT", + "COEX_BtMciState", + "COEX_BtCalState", + "COEX_WlanCalState", + "COEX_RxReqWakeCount", + "COEX_RxRemoteResetCount", + "COEX_RESTART_CAL", + "COEX_SENDMSG_QUEUE", + "COEX_RESETSEQ_LNAINFO_TIMEOUT", + "COEX_MCI_ISR_IntRaw", + "COEX_MCI_ISR_Int1Raw", + "COEX_MCI_ISR_RxMsgRaw", + "COEX_WHAL_COEX_RESET", + "COEX_WAL_COEX_INIT", + "COEX_TXRX_CNT_LIMIT_ISR", + "COEX_CH_BUSY", + "COEX_REASSESS_WLAN_STATE", + "COEX_BTCOEX_WLAN_STATE_UPDATE", + "COEX_BT_NUM_OF_PROFILES", + "COEX_BT_NUM_OF_HID_PROFILES", + "COEX_BT_NUM_OF_ACL_PROFILES", + "COEX_BT_NUM_OF_HI_ACL_PROFILES", + "COEX_BT_NUM_OF_VOICE_PROFILES", + "COEX_WLAN_AGGR_LIMIT", + "COEX_BT_LOW_PRIO_BUDGET", + "COEX_BT_HI_PRIO_BUDGET", + "COEX_BT_IDLE_TIME", + "COEX_SET_COEX_WEIGHT", + "COEX_WLAN_WEIGHT_GROUP", + "COEX_BT_WEIGHT_GROUP", + "COEX_BT_INTERVAL_ALLOC", + "COEX_BT_SCHEME", + "COEX_BT_MGR", + "COEX_BT_SM_ERROR", + "COEX_SYSTEM_UPDATE", + "COEX_LOW_PRIO_LIMIT", + "COEX_HI_PRIO_LIMIT", + "COEX_BT_INTERVAL_START", + "COEX_WLAN_INTERVAL_START", + "COEX_NON_LINK_BUDGET", + "COEX_CONTENTION_MSG", + "COEX_SET_NSS", + "COEX_SELF_GEN_MASK", + "COEX_PROFILE_ERROR", + "COEX_WLAN_INIT", + "COEX_BEACON_MISS", + "COEX_BEACON_OK", + "COEX_BTCOEX_SCAN_ACTIVITY", + "COEX_SCAN_ACTIVITY", + "COEX_FORCE_QUIETTIME", + "COEX_BT_MGR_QUIETTIME", + "COEX_BT_INACTIVITY_TRIGGER", + "COEX_BT_INACTIVITY_REPORTED", + "COEX_TX_MCI_GPM_WLAN_PRIO", + "COEX_TX_MCI_GPM_BT_PAUSE_PROFILE", + "COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY", + "COEX_RX_MCI_GPM_BT_ACL_INACTIVITY_REPORT", + "COEX_GENERIC_ERROR", + "COEX_RX_RATE_THRESHOLD", + "COEX_RSSI", + "COEX_WLAN_VDEV_NOTIF_START", // 133 + "COEX_WLAN_VDEV_NOTIF_UP", // 134 + "COEX_WLAN_VDEV_NOTIF_DOWN", // 135 + "COEX_WLAN_VDEV_NOTIF_STOP", // 136 + "COEX_WLAN_VDEV_NOTIF_ADD_PEER", // 137 + "COEX_WLAN_VDEV_NOTIF_DELETE_PEER", // 138 + "COEX_WLAN_VDEV_NOTIF_CONNECTED_PEER", // 139 + "COEX_WLAN_VDEV_NOTIF_PAUSE", // 140 + "COEX_WLAN_VDEV_NOTIF_UNPAUSED", // 141 + "COEX_STATE_WLAN_VDEV_PEER_ADD", // 142 + "COEX_STATE_WLAN_VDEV_CONNECTED_PEER", // 143 + "COEX_STATE_WLAN_VDEV_DELETE_PEER", // 144 + "COEX_STATE_WLAN_VDEV_PAUSE", // 145 + "COEX_STATE_WLAN_VDEV_UNPAUSED", // 146 + "COEX_SCAN_CALLBACK", // 147 + "COEX_RC_SET_CHAINMASK", // 148 + "COEX_TX_MCI_GPM_WLAN_SET_BT_RXSS_THRES", // 149 + "COEX_TX_MCI_GPM_BT_RXSS_THRES_QUERY", // 150 + "COEX_BT_RXSS_THRES", // 151 + "COEX_BT_PROFILE_ADD_RMV", // 152 + "COEX_BT_SCHED_INFO", // 153 + "COEX_TRF_MGMT", // 154 + "COEX_SCHED_START", // 155 + "COEX_SCHED_RESULT", // 156 + "COEX_SCHED_ERROR", // 157 + "COEX_SCHED_PRE_OP", // 158 + "COEX_SCHED_POST_OP", // 159 + "COEX_RX_RATE", // 160 + "COEX_ACK_PRIORITY", // 161 + "COEX_STATE_WLAN_VDEV_UP", // 162 + "COEX_STATE_WLAN_VDEV_PEER_UPDATE", // 163 + "COEX_STATE_WLAN_VDEV_STOP", // 164 + "COEX_WLAN_PAUSE_PEER", // 165 + "COEX_WLAN_UNPAUSE_PEER", // 166 + "COEX_WLAN_PAUSE_INTERVAL_START", // 167 + "COEX_WLAN_POSTPAUSE_INTERVAL_START", // 168 + "COEX_TRF_FREERUN", // 169 + "COEX_TRF_SHAPE_PM", // 170 + "COEX_TRF_SHAPE_PSP", // 171 + "COEX_TRF_SHAPE_S_CTS", // 172 + "COEX_CHAIN_CONFIG", // 173 + "COEX_SYSTEM_MONITOR", // 174 + "COEX_SINGLECHAIN_INIT", // 175 + "COEX_MULTICHAIN_INIT", // 176 + "COEX_SINGLECHAIN_DBG_1", // 177 + "COEX_SINGLECHAIN_DBG_2", // 178 + "COEX_SINGLECHAIN_DBG_3", // 179 + "COEX_MULTICHAIN_DBG_1", // 180 + "COEX_MULTICHAIN_DBG_2", // 181 + "COEX_MULTICHAIN_DBG_3", // 182 + "COEX_PSP_TX_CB", // 183 + "COEX_PSP_RX_CB", // 184 + "COEX_PSP_STAT_1", // 185 + "COEX_PSP_SPEC_POLL", // 186 + "COEX_PSP_READY_STATE", // 187 + "COEX_PSP_TX_STATUS_STATE", // 188 + "COEX_PSP_RX_STATUS_STATE_1", // 189 + "COEX_PSP_NOT_READY_STATE", // 190 + "COEX_PSP_DISABLED_STATE", // 191 + "COEX_PSP_ENABLED_STATE", // 192 + "COEX_PSP_SEND_PSPOLL", // 193 + "COEX_PSP_MGR_ENTER", // 194 + "COEX_PSP_MGR_RESULT", // 195 + "COEX_PSP_NONWLAN_INTERVAL", // 196 + "COEX_PSP_STAT_2", // 197 + "COEX_PSP_RX_STATUS_STATE_2", // 198 + "COEX_PSP_ERROR", // 199 + "COEX_T2BT", // 200 + "COEX_BT_DURATION", // 201 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202 + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203 + "COEX_TX_MCI_GPM_SCAN_OP", // 204 + "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205 + "COEX_CTS2S_SEND", // 206 + "COEX_CTS2S_RESULT", // 207 + "COEX_ENTER_OCS", // 208 + "COEX_EXIT_OCS", // 209 + "COEX_UPDATE_OCS", // 210 + "COEX_STATUS_OCS", // 211 + "COEX_STATS_BT", // 212 + "COEX_MWS_WLAN_INIT", + "COEX_MWS_WBTMR_SYNC", + "COEX_MWS_TYPE2_RX", + "COEX_MWS_TYPE2_TX", + "COEX_MWS_WLAN_CHAVD", + "COEX_MWS_WLAN_CHAVD_INSERT", + "COEX_MWS_WLAN_CHAVD_MERGE", + "COEX_MWS_WLAN_CHAVD_RPT", + "COEX_MWS_CP_MSG_SEND", + "COEX_MWS_CP_ESCAPE", + "COEX_MWS_CP_UNFRAME", + "COEX_MWS_CP_SYNC_UPDATE", + "COEX_MWS_CP_SYNC", + "COEX_MWS_CP_WLAN_STATE_IND", + "COEX_MWS_CP_SYNCRESP_TIMEOUT", + "COEX_MWS_SCHEME_UPDATE", + "COEX_MWS_WLAN_EVENT", + "COEX_MWS_UART_UNESCAPE", + "COEX_MWS_UART_ENCODE_SEND", + "COEX_MWS_UART_RECV_DECODE", + "COEX_MWS_UL_HDL", + "COEX_MWS_REMOTE_EVENT", + "COEX_MWS_OTHER", + "COEX_MWS_ERROR", + "COEX_MWS_ANT_DIVERSITY", //237 + "COEX_P2P_GO", + "COEX_P2P_CLIENT", + "COEX_SCC_1", + "COEX_SCC_2", + "COEX_MCC_1", + "COEX_MCC_2", + "COEX_TRF_SHAPE_NOA", + "COEX_NOA_ONESHOT", + "COEX_NOA_PERIODIC", + "COEX_LE_1", + "COEX_LE_2", + "COEX_ANT_1", + "COEX_ANT_2", + "COEX_ENTER_NOA", + "COEX_EXIT_NOA", + "COEX_BT_SCAN_PROTECT", // 253 + "COEX_DEBUG_ID_END" // 254 + }, + { + "ROAM_DBGID_DEFINITION_START", + "ROAM_MODULE_INIT", + "ROAM_DEV_START", + "ROAM_CONFIG_RSSI_THRESH", + "ROAM_CONFIG_SCAN_PERIOD", + "ROAM_CONFIG_AP_PROFILE", + "ROAM_CONFIG_CHAN_LIST", + "ROAM_CONFIG_SCAN_PARAMS", + "ROAM_CONFIG_RSSI_CHANGE", + "ROAM_SCAN_TIMER_START", + "ROAM_SCAN_TIMER_EXPIRE", + "ROAM_SCAN_TIMER_STOP", + "ROAM_SCAN_STARTED", + "ROAM_SCAN_COMPLETE", + "ROAM_SCAN_CANCELLED", + "ROAM_CANDIDATE_FOUND", + "ROAM_RSSI_ACTIVE_SCAN", + "ROAM_RSSI_ACTIVE_ROAM", + "ROAM_RSSI_GOOD", + "ROAM_BMISS_FIRST_RECV", + "ROAM_DEV_STOP", + "ROAM_FW_OFFLOAD_ENABLE", + "ROAM_CANDIDATE_SSID_MATCH", + "ROAM_CANDIDATE_SECURITY_MATCH", + "ROAM_LOW_RSSI_INTERRUPT", + "ROAM_HIGH_RSSI_INTERRUPT", + "ROAM_SCAN_REQUESTED", + "ROAM_BETTER_CANDIDATE_FOUND", + "ROAM_BETTER_AP_EVENT", + "ROAM_CANCEL_LOW_PRIO_SCAN", + "ROAM_FINAL_BMISS_RECVD", + "ROAM_CONFIG_SCAN_MODE", + "ROAM_BMISS_FINAL_SCAN_ENABLE", + "ROAM_SUITABLE_AP_EVENT", + "ROAM_RSN_IE_PARSE_ERROR", + "ROAM_WPA_IE_PARSE_ERROR", + "ROAM_SCAN_CMD_FROM_HOST", + "ROAM_HO_SORT_CANDIDATE", + "ROAM_HO_SAVE_CANDIDATE", + "ROAM_HO_GET_CANDIDATE", + "ROAM_HO_OFFLOAD_SET_PARAM", + "ROAM_HO_SM", + "ROAM_HO_HTT_SAVED", + "ROAM_HO_SYNC_START", + "ROAM_HO_START", + "ROAM_HO_COMPLETE", + "ROAM_HO_STOP", + "ROAM_HO_HTT_FORWARD", + "ROAM_DBGID_DEFINITION_END" + }, + { + "RESMGR_CHMGR_DEFINITION_START", + "RESMGR_CHMGR_PAUSE_COMPLETE", + "RESMGR_CHMGR_CHANNEL_CHANGE", + "RESMGR_CHMGR_RESUME_COMPLETE", + "RESMGR_CHMGR_VDEV_PAUSE", + "RESMGR_CHMGR_VDEV_UNPAUSE", + "RESMGR_CHMGR_CTS2S_TX_COMP", + "RESMGR_CHMGR_CFEND_TX_COMP", + "RESMGR_CHMGR_DEFINITION_END" + }, + { + "RESMGR_DEFINITION_START", + "RESMGR_OCS_ALLOCRAM_SIZE", + "RESMGR_OCS_RESOURCES", + "RESMGR_LINK_CREATE", + "RESMGR_LINK_DELETE", + "RESMGR_OCS_CHREQ_CREATE", + "RESMGR_OCS_CHREQ_DELETE", + "RESMGR_OCS_CHREQ_START", + "RESMGR_OCS_CHREQ_STOP", + "RESMGR_OCS_SCHEDULER_INVOKED", + "RESMGR_OCS_CHREQ_GRANT", + "RESMGR_OCS_CHREQ_COMPLETE", + "RESMGR_OCS_NEXT_TSFTIME", + "RESMGR_OCS_TSF_TIMEOUT_US", + "RESMGR_OCS_CURR_CAT_WINDOW", + "RESMGR_OCS_CURR_CAT_WINDOW_REQ", + "RESMGR_OCS_CURR_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CHREQ_RESTART", + "RESMGR_OCS_CLEANUP_CH_ALLOCATORS", + "RESMGR_OCS_PURGE_CHREQ", + "RESMGR_OCS_CH_ALLOCATOR_FREE", + "RESMGR_OCS_RECOMPUTE_SCHEDULE", + "RESMGR_OCS_NEW_CAT_WINDOW_REQ", + "RESMGR_OCS_NEW_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CUR_CH_ALLOC", + "RESMGR_OCS_WIN_CH_ALLOC", + "RESMGR_OCS_SCHED_CH_CHANGE", + "RESMGR_OCS_CONSTRUCT_CAT_WIN", + "RESMGR_OCS_CHREQ_PREEMPTED", + "RESMGR_OCS_CH_SWITCH_REQ", + "RESMGR_OCS_CHANNEL_SWITCHED", + "RESMGR_OCS_CLEANUP_STALE_REQS", + "RESMGR_OCS_CHREQ_UPDATE", + "RESMGR_OCS_REG_NOA_NOTIF", + "RESMGR_OCS_DEREG_NOA_NOTIF", + "RESMGR_OCS_GEN_PERIODIC_NOA", + "RESMGR_OCS_RECAL_QUOTAS", + "RESMGR_OCS_GRANTED_QUOTA_STATS", + "RESMGR_OCS_ALLOCATED_QUOTA_STATS", + "RESMGR_OCS_REQ_QUOTA_STATS", + "RESMGR_OCS_TRACKING_TIME_FIRED", + "RESMGR_VC_ARBITRATE_ATTRIBUTES", + "RESMGR_OCS_LATENCY_STRICT_TIME_SLOT", + "RESMGR_OCS_CURR_TSF", + "RESMGR_OCS_QUOTA_REM", + "RESMGR_OCS_LATENCY_CASE_NO", + "RESMGR_OCS_WIN_CAT_DUR", + "RESMGR_VC_UPDATE_CUR_VC", + "RESMGR_VC_REG_UNREG_LINK", + "RESMGR_VC_PRINT_LINK", + "RESMGR_OCS_MISS_TOLERANCE", + "RESMGR_DYN_SCH_ALLOCRAM_SIZE", + "RESMGR_DYN_SCH_ENABLE", + "RESMGR_DYN_SCH_ACTIVE", + "RESMGR_DYN_SCH_CH_STATS_START", + "RESMGR_DYN_SCH_CH_SX_STATS", + "RESMGR_DYN_SCH_TOT_UTIL_PER", + "RESMGR_DYN_SCH_HOME_CH_QUOTA", + "RESMGR_OCS_REG_RECAL_QUOTA_NOTIF", + "RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF", + "RESMGR_DEFINITION_END" + }, + { + "VDEV_MGR_DEBID_DEFINITION_START", /* vdev Mgr */ + "VDEV_MGR_FIRST_BEACON_MISS_DETECTED", + "VDEV_MGR_FINAL_BEACON_MISS_DETECTED", + "VDEV_MGR_BEACON_IN_SYNC", + "VDEV_MGR_AP_KEEPALIVE_IDLE", + "VDEV_MGR_AP_KEEPALIVE_INACTIVE", + "VDEV_MGR_AP_KEEPALIVE_UNRESPONSIVE", + "VDEV_MGR_AP_TBTT_CONFIG", + "VDEV_MGR_FIRST_BCN_RECEIVED", + "VDEV_MGR_VDEV_START", + "VDEV_MGR_VDEV_UP", + "VDEV_MGR_PEER_AUTHORIZED", + "VDEV_MGR_OCS_HP_LP_REQ_POSTED", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP", + "VDEV_MGR_HP_START_TIME", + "VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE", + "VDEV_MGR_VDEV_PAUSE_FAIL", + "VDEV_MGR_GEN_PERIODIC_NOA", + "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP", + "VDEV_MGR_DEFINITION_END", + }, + { + "SCAN_START_COMMAND_FAILED", /* scan */ + "SCAN_STOP_COMMAND_FAILED", + "SCAN_EVENT_SEND_FAILED", + "SCAN_ENGINE_START", + "SCAN_ENGINE_CANCEL_COMMAND", + "SCAN_ENGINE_STOP_DUE_TO_TIMEOUT", + "SCAN_EVENT_SEND_TO_HOST", + "SCAN_FWLOG_EVENT_ADD", + "SCAN_FWLOG_EVENT_REM", + "SCAN_FWLOG_EVENT_PREEMPTED", + "SCAN_FWLOG_EVENT_RESTARTED", + "SCAN_FWLOG_EVENT_COMPLETED", + }, + { + "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl*/ + "RATECTRL_DBGID_ASSOC", + "RATECTRL_DBGID_NSS_CHANGE", + "RATECTRL_DBGID_CHAINMASK_ERR", + "RATECTRL_DBGID_UNEXPECTED_FRAME", + "RATECTRL_DBGID_WAL_RCQUERY", + "RATECTRL_DBGID_WAL_RCUPDATE", + "RATECTRL_DBGID_GTX_UPDATE", + "RATECTRL_DBGID_DEFINITION_END" + }, + { + "AP_PS_DBGID_DEFINITION_START", + "AP_PS_DBGID_UPDATE_TIM", + "AP_PS_DBGID_PEER_STATE_CHANGE", + "AP_PS_DBGID_PSPOLL", + "AP_PS_DBGID_PEER_CREATE", + "AP_PS_DBGID_PEER_DELETE", + "AP_PS_DBGID_VDEV_CREATE", + "AP_PS_DBGID_VDEV_DELETE", + "AP_PS_DBGID_SYNC_TIM", + "AP_PS_DBGID_NEXT_RESPONSE", + "AP_PS_DBGID_START_SP", + "AP_PS_DBGID_COMPLETED_EOSP", + "AP_PS_DBGID_TRIGGER", + "AP_PS_DBGID_DUPLICATE_TRIGGER", + "AP_PS_DBGID_UAPSD_RESPONSE", + "AP_PS_DBGID_SEND_COMPLETE", + "AP_PS_DBGID_SEND_N_COMPLETE", + "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA", + "AP_PS_DBGID_DELIVER_CAB", + }, + { + "" /* Block Ack */ + }, + /* Mgmt TxRx */ + { + "MGMT_TXRX_DBGID_DEFINITION_START", + "MGMT_TXRX_FORWARD_TO_HOST", + "MGMT_TXRX_DBGID_DEFINITION_END", + }, + { /* Data TxRx */ + "DATA_TXRX_DBGID_DEFINITION_START", + "DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO", + "DATA_TXRX_DBGID_DEFINITION_END", + }, + { "" /* HTT */ + }, + { "" /* HOST */ + }, + { "" /* BEACON */ + "BEACON_EVENT_SWBA_SEND_FAILED", + "BEACON_EVENT_EARLY_RX_BMISS_STATUS", + "BEACON_EVENT_EARLY_RX_SLEEP_SLOP", + "BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT", + "BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM", + "BEACON_EVENT_EARLY_RX_CLK_DRIFT", + "BEACON_EVENT_EARLY_RX_AP_DRIFT", + "BEACON_EVENT_EARLY_RX_BCN_TYPE", + }, + { /* Offload Mgr */ + "OFFLOAD_MGR_DBGID_DEFINITION_START", + "OFFLOADMGR_REGISTER_OFFLOAD", + "OFFLOADMGR_DEREGISTER_OFFLOAD", + "OFFLOADMGR_NO_REG_DATA_HANDLERS", + "OFFLOADMGR_NO_REG_EVENT_HANDLERS", + "OFFLOADMGR_REG_OFFLOAD_FAILED", + "OFFLOADMGR_DBGID_DEFINITION_END", + }, + { + "WAL_DBGID_DEFINITION_START", + "WAL_DBGID_FAST_WAKE_REQUEST", + "WAL_DBGID_FAST_WAKE_RELEASE", + "WAL_DBGID_SET_POWER_STATE", + "WAL_DBGID_MISSING", + "WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET", + "WAL_DBGID_CHANNEL_CHANGE", + "WAL_DBGID_VDEV_START", + "WAL_DBGID_VDEV_STOP", + "WAL_DBGID_VDEV_UP", + "WAL_DBGID_VDEV_DOWN", + "WAL_DBGID_SW_WDOG_RESET", + "WAL_DBGID_TX_SCH_REGISTER_TIDQ", + "WAL_DBGID_TX_SCH_UNREGISTER_TIDQ", + "WAL_DBGID_TX_SCH_TICKLE_TIDQ", + "WAL_DBGID_XCESS_FAILURES", + "WAL_DBGID_AST_ADD_WDS_ENTRY", + "WAL_DBGID_AST_DEL_WDS_ENTRY", + "WAL_DBGID_AST_WDS_ENTRY_PEER_CHG", + "WAL_DBGID_AST_WDS_SRC_LEARN_FAIL", + "WAL_DBGID_STA_KICKOUT", + "WAL_DBGID_BAR_TX_FAIL", + "WAL_DBGID_BAR_ALLOC_FAIL", + "WAL_DBGID_LOCAL_DATA_TX_FAIL", + "WAL_DBGID_SECURITY_PM4_QUEUED", + "WAL_DBGID_SECURITY_GM1_QUEUED", + "WAL_DBGID_SECURITY_PM4_SENT", + "WAL_DBGID_SECURITY_ALLOW_DATA", + "WAL_DBGID_SECURITY_UCAST_KEY_SET", + "WAL_DBGID_SECURITY_MCAST_KEY_SET", + "WAL_DBGID_SECURITY_ENCR_EN", + "WAL_DBGID_BB_WDOG_TRIGGERED", + "WAL_DBGID_RX_LOCAL_BUFS_LWM", + "WAL_DBGID_RX_LOCAL_DROP_LARGE_MGMT", + "WAL_DBGID_VHT_ILLEGAL_RATE_PHY_ERR_DETECTED", + "WAL_DBGID_DEV_RESET", + "WAL_DBGID_TX_BA_SETUP", + "WAL_DBGID_RX_BA_SETUP", + "WAL_DBGID_DEV_TX_TIMEOUT", + "WAL_DBGID_DEV_RX_TIMEOUT", + "WAL_DBGID_STA_VDEV_XRETRY", + "WAL_DBGID_DCS", + "WAL_DBGID_MGMT_TX_FAIL", + "WAL_DBGID_SET_M4_SENT_MANUALLY", + "WAL_DBGID_PROCESS_4_WAY_HANDSHAKE", + "WAL_DBGID_WAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DISCARD", + "WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS", + "WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS", + "WAL_DBGID_RESET_PCU_CYCLE_CNT", + "WAL_DBGID_SETUP_RSSI_INTERRUPTS", + "WAL_DBGID_BRSSI_CONFIG", + "WAL_DBGID_CURRENT_BRSSI_AVE", + "WAL_DBGID_BCN_TX_COMP", + "WAL_DBGID_SET_HW_CHAINMASK", + "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL", + "WAL_DBGID_GET_HW_CHAINMASK", + "WAL_DBGID_SMPS_DISABLE", + "WAL_DBGID_SMPS_ENABLE_HW_CNTRL", + "WAL_DBGID_SMPS_SWSEL_CHAINMASK", + "WAL_DBGID_DEFINITION_END", + }, + { + "" /* DE */ + }, + { + "" /* pcie lp */ + }, + { + /* RTT */ + "RTT_CALL_FLOW", + "RTT_REQ_SUB_TYPE", + "RTT_MEAS_REQ_HEAD", + "RTT_MEAS_REQ_BODY", + "", + "", + "RTT_INIT_GLOBAL_STATE", + "", + "RTT_REPORT", + "", + "RTT_ERROR_REPORT", + "RTT_TIMER_STOP", + "RTT_SEND_TM_FRAME", + "RTT_V3_RESP_CNT", + "RTT_V3_RESP_FINISH", + "RTT_CHANNEL_SWITCH_REQ", + "RTT_CHANNEL_SWITCH_GRANT", + "RTT_CHANNEL_SWITCH_COMPLETE", + "RTT_CHANNEL_SWITCH_PREEMPT", + "RTT_CHANNEL_SWITCH_STOP", + "RTT_TIMER_START", + }, + { /* RESOURCE */ + "RESOURCE_DBGID_DEFINITION_START", + "RESOURCE_PEER_ALLOC", + "RESOURCE_PEER_FREE", + "RESOURCE_PEER_ALLOC_WAL_PEER", + "RESOURCE_DBGID_DEFINITION_END", + }, + { /* DCS */ + "WLAN_DCS_DBGID_INIT", + "WLAN_DCS_DBGID_WMI_CWINT", + "WLAN_DCS_DBGID_TIMER", + "WLAN_DCS_DBGID_CMDG", + "WLAN_DCS_DBGID_CMDS", + "WLAN_DCS_DBGID_DINIT" + }, + { /* CACHEMGR */ + "" + }, + { /* ANI */ + "ANI_DBGID_POLL", + "ANI_DBGID_CONTROL", + "ANI_DBGID_OFDM_PARAMS", + "ANI_DBGID_CCK_PARAMS", + "ANI_DBGID_RESET", + "ANI_DBGID_RESTART", + "ANI_DBGID_OFDM_LEVEL", + "ANI_DBGID_CCK_LEVEL", + "ANI_DBGID_FIRSTEP", + "ANI_DBGID_CYCPWR", + "ANI_DBGID_MRC_CCK", + "ANI_DBGID_SELF_CORR_LOW", + "ANI_DBGID_ENABLE", + "ANI_DBGID_CURRENT_LEVEL", + "ANI_DBGID_POLL_PERIOD", + "ANI_DBGID_LISTEN_PERIOD", + "ANI_DBGID_OFDM_LEVEL_CFG", + "ANI_DBGID_CCK_LEVEL_CFG" + }, + { + "P2P_DBGID_DEFINITION_START", + "P2P_DEV_REGISTER", + "P2P_HANDLE_NOA", + "P2P_UPDATE_SCHEDULE_OPPS", + "P2P_UPDATE_SCHEDULE", + "P2P_UPDATE_START_TIME", + "P2P_UPDATE_START_TIME_DIFF_TSF32", + "P2P_UPDATE_START_TIME_FINAL", + "P2P_SETUP_SCHEDULE_TIMER", + "P2P_PROCESS_SCHEDULE_AFTER_CALC", + "P2P_PROCESS_SCHEDULE_STARTED_TIMER", + "P2P_CALC_SCHEDULES_FIRST_CALL_ALL_NEXT_EVENT", + "P2P_CALC_SCHEDULES_FIRST_VALUE", + "P2P_CALC_SCHEDULES_EARLIEST_NEXT_EVENT", + "P2P_CALC_SCHEDULES_SANITY_COUNT", + "P2P_CALC_SCHEDULES_CALL_ALL_NEXT_EVENT_FROM_WHILE_LOOP", + "P2P_CALC_SCHEDULES_TIMEOUT_1", + "P2P_CALC_SCHEDULES_TIMEOUT_2", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_EXPIRED", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_ACTIVE", + "P2P_FIND_NEXT_EVENT_REQ_NOT_STARTED", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE_NON_PERIODIC", + "P2P_FIND_NEXT_EVENT_IN_MID_OF_NOA", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE", + "P2P_SCHEDULE_TIMEOUT", + "P2P_CALC_SCHEDULES_ENTER", + "P2P_PROCESS_SCHEDULE_ENTER", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_AFTER_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_BEFORE_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_ENTER", + "P2P_FIND_NEXT_EVENT_ENTER", + "P2P_NOA_GO_PRESENT", + "P2P_NOA_GO_ABSENT", + "P2P_GO_NOA_NOTIF", + "P2P_GO_TBTT_OFFSET", + "P2P_GO_GET_NOA_INFO", + "P2P_GO_ADD_ONE_SHOT_NOA", + "P2P_GO_GET_NOA_IE", + "P2P_GO_BCN_TX_COMP", + "P2P_DBGID_DEFINITION_END", + }, + { + "CSA_DBGID_DEFINITION_START", + "CSA_OFFLOAD_POOL_INIT", + "CSA_OFFLOAD_REGISTER_VDEV", + "CSA_OFFLOAD_DEREGISTER_VDEV", + "CSA_DEREGISTER_VDEV_ERROR", + "CSA_OFFLOAD_BEACON_RECEIVED", + "CSA_OFFLOAD_BEACON_CSA_RECV", + "CSA_OFFLOAD_CSA_RECV_ERROR_IE", + "CSA_OFFLOAD_CSA_TIMER_ERROR", + "CSA_OFFLOAD_CSA_TIMER_EXP", + "CSA_OFFLOAD_WMI_EVENT_ERROR", + "CSA_OFFLOAD_WMI_EVENT_SENT", + "CSA_OFFLOAD_WMI_CHANSWITCH_RECV", + "CSA_DBGID_DEFINITION_END", + }, + { /* NLO offload */ + "" + }, + { + "WLAN_CHATTER_DBGID_DEFINITION_START", + "WLAN_CHATTER_ENTER", + "WLAN_CHATTER_EXIT", + "WLAN_CHATTER_FILTER_HIT", + "WLAN_CHATTER_FILTER_MISS", + "WLAN_CHATTER_FILTER_FULL", + "WLAN_CHATTER_FILTER_TM_ADJ", + "WLAN_CHATTER_BUFFER_FULL", + "WLAN_CHATTER_TIMEOUT", + "WLAN_CHATTER_DBGID_DEFINITION_END", + }, + { + "WOW_DBGID_DEFINITION_START", + "WOW_ENABLE_CMDID", + "WOW_RECV_DATA_PKT", + "WOW_WAKE_HOST_DATA", + "WOW_RECV_MGMT", + "WOW_WAKE_HOST_MGMT", + "WOW_RECV_EVENT", + "WOW_WAKE_HOST_EVENT", + "WOW_INIT", + "WOW_RECV_MAGIC_PKT", + "WOW_RECV_BITMAP_PATTERN", + "WOW_DBGID_DEFINITION_END", + }, + { /* WAL_VDEV */ + "" + }, + { /* WAL_PDEV */ + "" + }, + { /* TEST */ + "TP_CHANGE_CHANNEL", + "TP_LOCAL_SEND", + }, + { /* STA SMPS */ + "STA_SMPS_DBGID_DEFINITION_START", + "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE", + "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_CREATE_STA_INSTANCE", + "STA_SMPS_DBGID_DELETE_STA_INSTANCE", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP", + "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME", + "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE", + "SMPS_DBGID_DEFINITION_END", + }, + { /* SWBMISS */ + "SWBMISS_DBGID_DEFINITION_START", + "SWBMISS_ENABLED", + "SWBMISS_DISABLED", + "SWBMISS_DBGID_DEFINITION_END", + }, + { /* WMMAC */ + "" + }, + { /* TDLS */ + "TDLS_DBGID_DEFINITION_START", + "TDLS_DBGID_VDEV_CREATE", + "TDLS_DBGID_VDEV_DELETE", + "TDLS_DBGID_ENABLED_PASSIVE", + "TDLS_DBGID_ENABLED_ACTIVE", + "TDLS_DBGID_DISABLED", + "TDLS_DBGID_CONNTRACK_TIMER", + "TDLS_DBGID_WAL_SET", + "TDLS_DBGID_WAL_GET", + "TDLS_DBGID_WAL_PEER_UPDATE_SET", + "TDLS_DBGID_WAL_PEER_UPDATE_EVT", + "TDLS_DBGID_WAL_VDEV_CREATE", + "TDLS_DBGID_WAL_VDEV_DELETE", + "TDLS_DBGID_WLAN_EVENT", + "TDLS_DBGID_WLAN_PEER_UPDATE_SET", + "TDLS_DBGID_PEER_EVT_DRP_THRESH", + "TDLS_DBGID_PEER_EVT_DRP_RATE", + "TDLS_DBGID_PEER_EVT_DRP_RSSI", + "TDLS_DBGID_PEER_EVT_DISCOVER", + "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", + }, + { /* HB */ + "WLAN_HB_DBGID_DEFINITION_START", + "WLAN_HB_DBGID_INIT", + "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_TCP_SEND_FAIL", + "WLAN_HB_DBGID_BSS_PEER_NULL", + "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_UDP_SEND_FAIL", + "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM", + "WLAN_HB_DBGID_WMI_CMD_INVALID_OP", + "WLAN_HB_DBGID_WOW_NOT_ENTERED", + "WLAN_HB_DBGID_ALLOC_SESS_FAIL", + "WLAN_HB_DBGID_CTX_NULL", + "WLAN_HB_DBGID_CHKSUM_ERR", + "WLAN_HB_DBGID_UDP_TX", + "WLAN_HB_DBGID_TCP_TX", + "WLAN_HB_DBGID_DEFINITION_END", + }, + { /* TXBF */ + "TXBFEE_DBGID_START", + "TXBFEE_DBGID_NDPA_RECEIVED", + "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE", + "TXBFER_DBGID_SEND_NDPA", + "TXBFER_DBGID_GET_NDPA_BUF_FAIL", + "TXBFER_DBGID_SEND_NDPA_FAIL", + "TXBFER_DBGID_GET_NDP_BUF_FAIL", + "TXBFER_DBGID_SEND_NDP_FAIL", + "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL", + "TXBFER_DBGID_SEND_BRPOLL_FAIL", + "TXBFER_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H", + "TXBFEE_DBGID_UPLOADH_CV_TAG", + "TXBFEE_DBGID_UPLOADH_H_TAG", + "TXBFEE_DBGID_CAPTUREH_RECEIVED", + "TXBFEE_DBGID_PACKET_IS_STEERED", + "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL", + "TXBFEE_DBGID_END", + }, + { /*BATCH SCAN*/ + }, + { /*THERMAL MGR*/ + "THERMAL_MGR_DBGID_DEFINITION_START", + "THERMAL_MGR_NEW_THRESH", + "THERMAL_MGR_THRESH_CROSSED", + "THERMAL_MGR_DBGID_DEFINITION END", + }, + { /* WLAN_MODULE_PHYERR_DFS */ + "" + }, + { + /* WLAN_MODULE_RMC */ + "RMC_DBGID_DEFINITION_START", + "RMC_CREATE_INSTANCE", + "RMC_DELETE_INSTANCE", + "RMC_LDR_SEL", + "RMC_NO_LDR", + "RMC_LDR_NOT_SEL", + "RMC_LDR_INF_SENT", + "RMC_PEER_ADD", + "RMC_PEER_DELETE", + "RMC_PEER_UNKNOWN", + "RMC_SET_MODE", + "RMC_SET_ACTION_PERIOD", + "RMC_ACRION_FRAME_RX", + "RMC_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_STATS */ + "WLAN_STATS_DBGID_DEFINITION_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_VDEV_EN_DIS", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_END", + "WLAN_STATS_DBGID_EST_LINKSPEED_CALC", + "WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN", + "WLAN_STATS_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_NAN */ + }, + { + /* WLAN_MODULE_IBSS_PWRSAVE */ + "IBSS_PS_DBGID_DEFINITION_START", + "IBSS_PS_DBGID_PEER_CREATE", + "IBSS_PS_DBGID_PEER_DELETE", + "IBSS_PS_DBGID_VDEV_CREATE", + "IBSS_PS_DBGID_VDEV_DELETE", + "IBSS_PS_DBGID_VDEV_EVENT", + "IBSS_PS_DBGID_PEER_EVENT", + "IBSS_PS_DBGID_DELIVER_CAB", + "IBSS_PS_DBGID_DELIVER_UC_DATA", + "IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR", + "IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_NULL_TX_COMPLETION", + "IBSS_PS_DBGID_ATIM_TIMER_START", + "IBSS_PS_DBGID_UC_ATIM_SEND", + "IBSS_PS_DBGID_BC_ATIM_SEND", + "IBSS_PS_DBGID_UC_TIMEOUT", + "IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED", + "IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED", + "IBSS_PS_DBGID_SET_PARAM", + "IBSS_PS_DBGID_HOST_TX_PAUSE", + "IBSS_PS_DBGID_HOST_TX_UNPAUSE", + "IBSS_PS_DBGID_PS_DESC_BIN_HWM", + "IBSS_PS_DBGID_PS_DESC_BIN_LWM", + "IBSS_PS_DBGID_PS_KICKOUT_PEER", + "IBSS_PS_DBGID_SET_PEER_PARAM", + "IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH", + }, + { + /* HIF UART Interface DBGIDs */ + "HIF_UART_DBGID_START", + "HIF_UART_DBGID_POWER_STATE", + "HIF_UART_DBGID_TXRX_FLOW", + "HIF_UART_DBGID_TXRX_CTRL_CHAR", + "HIF_UART_DBGID_TXRX_BUF_DUMP", + }, + { + /* LPI */ + "" + }, + { + /* EXTSCAN DBGIDs */ + "EXTSCAN_START", + "EXTSCAN_STOP", + "EXTSCAN_CLEAR_ENTRY_CONTENT", + "EXTSCAN_GET_FREE_ENTRY_SUCCESS", + "EXTSCAN_GET_FREE_ENTRY_INCONSISTENT", + "EXTSCAN_GET_FREE_ENTRY_NO_MORE_ENTRIES", + "EXTSCAN_CREATE_ENTRY_SUCCESS", + "EXTSCAN_CREATE_ENTRY_ERROR", + "EXTSCAN_SEARCH_SCAN_ENTRY_QUEUE", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_FOUND", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_NOT_FOUND", + "EXTSCAN_ADD_ENTRY", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT_FAILED", + "EXTSCAN_BUCKET_START_SCAN_CYCLE", + "EXTSCAN_BUCKET_PERIODIC_TIMER", + "EXTSCAN_SEND_START_STOP_EVENT", + "EXTSCAN_NOTIFY_WLAN_CHANGE", + "EXTSCAN_NOTIFY_WLAN_HOTLIST_MATCH", + "EXTSCAN_MAIN_RECEIVED_FRAME", + "EXTSCAN_MAIN_NO_SSID_IE", + "EXTSCAN_MAIN_MALFORMED_FRAME", + "EXTSCAN_FIND_BSSID_BY_REFERENCE", + "EXTSCAN_FIND_BSSID_BY_REFERENCE_ERROR", + "EXTSCAN_NOTIFY_TABLE_USAGE", + "EXTSCAN_FOUND_RSSI_ENTRY", + "EXTSCAN_BSSID_FOUND_RSSI_SAMPLE", + "EXTSCAN_BSSID_ADDED_RSSI_SAMPLE", + "EXTSCAN_BSSID_REPLACED_RSSI_SAMPLE", + "EXTSCAN_BSSID_TRANSFER_CURRENT_SAMPLES", + "EXTSCAN_BUCKET_PROCESS_SCAN_EVENT", + "EXTSCAN_BUCKET_CANNOT_FIND_BUCKET", + "EXTSCAN_START_SCAN_REQUEST_FAILED", + "EXTSCAN_BUCKET_STOP_CURRENT_SCANS", + "EXTSCAN_BUCKET_SCAN_STOP_REQUEST", + "EXTSCAN_BUCKET_PERIODIC_TIMER_ERROR", + "EXTSCAN_BUCKET_START_OPERATION", + "EXTSCAN_START_INTERNAL_ERROR", + "EXTSCAN_NOTIFY_HOTLIST_MATCH", + "EXTSCAN_CONFIG_HOTLIST_TABLE", + "EXTSCAN_CONFIG_WLAN_CHANGE_TABLE", + }, + { /* UNIT_TEST */ + "UNIT_TEST_GEN", + }, + { /* MLME */ + "MLME_DEBUG_CMN", + "MLME_IF", + "MLME_AUTH", + "MLME_REASSOC", + "MLME_DEAUTH", + "MLME_DISASSOC", + "MLME_ROAM", + "MLME_RETRY", + "MLME_TIMER", + "MLME_FRMPARSE", + }, + { /*SUPPLICANT */ + "SUPPL_INIT", + "SUPPL_RECV_EAPOL", + "SUPPL_RECV_EAPOL_TIMEOUT", + "SUPPL_SEND_EAPOL", + "SUPPL_MIC_MISMATCH", + "SUPPL_FINISH", + }, +}; + +static char * +dbglog_get_msg(A_UINT32 moduleid, A_UINT32 debugid) +{ + static char unknown_str[64]; + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS) { + char *str = DBG_MSG_ARR[moduleid][debugid]; + if (str && str[0] != '\0') { + return str; + } + } + + snprintf(unknown_str, sizeof(unknown_str), + "UNKNOWN %u:%u", + moduleid, debugid); + + return unknown_str; +} + +void +dbglog_printf( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + int j; + + if (vap_id < DBGLOG_MAX_VDEVID) { + j = snprintf(buf, sizeof(buf), DBGLOG_PRINT_PREFIX + "[%u] vap-%u ", timestamp, vap_id); + } else { + j = snprintf(buf, sizeof(buf), DBGLOG_PRINT_PREFIX + "[%u] ", timestamp); + } + + va_start(ap, fmt); + vsnprintf(buf+j, sizeof(buf)-j, fmt, ap); + va_end(ap); + + diag_print_legacy_logs(buf); +} + +void +dbglog_printf_no_line_break( + A_UINT32 timestamp, + A_UINT16 vap_id, + const char *fmt, ...) +{ + char buf[128]; + va_list ap; + int j; + + if (vap_id < DBGLOG_MAX_VDEVID) { + j = snprintf(buf, sizeof(buf), DBGLOG_PRINT_PREFIX + "[%u] vap-%u ", timestamp, vap_id); + } else { + j = snprintf(buf, sizeof(buf), DBGLOG_PRINT_PREFIX + "[%u] ", timestamp); + } + + va_start(ap, fmt); + vsnprintf(buf+j, sizeof(buf)-j, fmt, ap); + va_end(ap); + + diag_print_legacy_logs(buf); +} + +#define USE_NUMERIC 0 + +A_BOOL +dbglog_default_print_handler(A_UINT32 mod_id, A_UINT16 vap_id, A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + int i, j; + char tempbuf[RECLEN]; + + if (vap_id < DBGLOG_MAX_VDEVID) { + j = snprintf(tempbuf, sizeof(tempbuf), DBGLOG_PRINT_PREFIX + "[%u] vap-%u %s ( ", timestamp, vap_id, + dbglog_get_msg(mod_id, dbg_id)); + } else { + j = snprintf(tempbuf, sizeof(tempbuf), DBGLOG_PRINT_PREFIX + "[%u] %s ( ", timestamp, + dbglog_get_msg(mod_id, dbg_id)); + } + + for (i = 0; i < numargs; i++) { +#if USE_NUMERIC + j += snprintf(tempbuf+j, sizeof(tempbuf)-j, "%u", args[i]); +#else + j += snprintf(tempbuf+j, sizeof(tempbuf)-j, "%#x,", args[i]); +#endif + if ((i + 1) < numargs) { + j += snprintf(tempbuf+j, sizeof(tempbuf)-j, ","); + } + } + snprintf(tempbuf+j, sizeof(tempbuf)-j, ")\n"); + + diag_print_legacy_logs(buf); + return TRUE; +} + +int +dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped) +{ + A_UINT32 count=0; + A_UINT32 timestamp=0; + A_UINT32 debugid=0; + A_UINT32 moduleid=0; + A_UINT16 vapid=0; + A_UINT16 numargs=0; + A_UINT32 *buffer; + A_UINT32 length = len >> 2; + + if(dropped > 0) + debug_printf("%d log buffer got dropped in firmware\n", dropped); + + buffer = (A_UINT32 *)datap; + length = (len >> 2); + + while ((count + 2) < length) { + + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + debugid = DBGLOG_GET_DBGID(buffer[count+1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count+1]); + vapid = DBGLOG_GET_VDEVID(buffer[count+1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count+1]); + + if ((count + 2 + numargs) > length) + return 0; + + if (moduleid >= WLAN_MODULE_ID_MAX) + return 0; + + if (mod_print[moduleid] == NULL) { + /* No module specific log registered use the default handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + } else { + if(!(mod_print[moduleid](moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)))) { + /* The message is not handled by the module specific handler*/ + dbglog_default_print_handler(moduleid, vapid, debugid, timestamp, + numargs, + (((A_UINT32 *)buffer) + 2 + count)); + + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header*/ + } + /* Always returns zero */ + return (0); +} + +void +dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn) +{ + if (!mod_print[mod_id]) { + mod_print[mod_id] = printfn; + } else { + debug_printf("module print is already registered for this module %d\n", + mod_id); + } +} + +void +dbglog_sm_print( + A_UINT32 timestamp, + A_UINT16 vap_id, + A_UINT16 numargs, + A_UINT32 *args, + const char *module_prefix, + const char *states[], A_UINT32 num_states, + const char *events[], A_UINT32 num_events) +{ + A_UINT8 type, arg1, arg2, arg3; + A_UINT32 extra, extra2, extra3; + + if (numargs != 4) { + return; + } + + type = (args[0] >> 24) & 0xff; + arg1 = (args[0] >> 16) & 0xff; + arg2 = (args[0] >> 8) & 0xff; + arg3 = (args[0] >> 0) & 0xff; + + extra = args[1]; + extra2 = args[2]; + extra3 = args[3]; + + switch (type) { + case 0: /* state transition */ + if (arg1 < num_states && arg2 < num_states) { + dbglog_printf(timestamp, vap_id, "%s: %s => %s (%#x, %#x, %#x)", + module_prefix, states[arg1], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u => %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 1: /* dispatch event */ + if (arg1 < num_states && arg2 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: %s < %s (%#x, %#x, %#x)", + module_prefix, states[arg1], events[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: %u < %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, extra3); + } + break; + case 2: /* warning */ + switch (arg1) { + case 0: /* unhandled event */ + if (arg2 < num_states && arg3 < num_events) { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %s in state %s (%#x, %#x, %#x)", + module_prefix, events[arg3], states[arg2], extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, "%s: unhandled event %u in state %u (%#x, %#x, %#x)", + module_prefix, arg3, arg2, extra, extra2, extra3); + } + break; + default: + break; + + } + break; + } +} + +A_BOOL +dbglog_sta_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "ACTIVE", + "SLEEP_TXQ_FLUSH", + "SLEEP_TX_SENT", + "PAUSE", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TXQ_FLUSH", + "ACTIVE_TX_SENT", + "PAUSE_TXQ_FLUSH", + "PAUSE_TX_SENT", + "IDLE_TXQ_FLUSH", + "IDLE_TX_SENT", + }; + + static const char *events[] = { + "START", + "STOP", + "PAUSE", + "UNPAUSE", + "TIM", + "DTIM", + "SEND_COMPLETE", + "PRE_SEND", + "RX", + "HWQ_EMPTY", + "PAUSE_TIMEOUT", + "TXRX_INACTIVITY_TIMEOUT", + "PSPOLL_TIMEOUT", + "UAPSD_TIMEOUT", + "DELAYED_SLEEP_TIMEOUT", + "SEND_N_COMPLETE", + "TIDQ_PAUSE_COMPLETE", + "SEND_PSPOLL", + "SEND_SPEC_PSPOLL", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case PS_STA_PM_ARB_REQUEST: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, "PM ARB request flags=%x, last_time=%x %s: %s", + args[1], args[2], dbglog_get_module_str(args[0]), args[3] ? "SLEEP" : "WAKE"); + } + break; + case PS_STA_DELIVER_EVENT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, "STA PS: %s %s", + (args[0] == 0 ? "PAUSE_COMPLETE" : + (args[0] == 1 ? "UNPAUSE_COMPLETE" : + (args[0] == 2 ? "SLEEP" : + (args[0] == 3 ? "AWAKE" : "UNKNOWN")))), + (args[1] == 0 ? "SUCCESS" : + (args[1] == 1 ? "TXQ_FLUSH_TIMEOUT" : + (args[1] == 2 ? "NO_ACK" : + (args[1] == 3 ? "RX_LEAK_TIMEOUT" : + (args[1] == 4 ? "PSPOLL_UAPSD_BUSY_TIMEOUT" : "UNKNOWN")))))); + } + break; + case PS_STA_PSPOLL_SEQ_DONE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, "STA PS poll: queue=%u comp=%u rsp=%u rsp_dur=%u fc=%x qos=%x %s", + args[0], args[1], args[2], args[3], + (args[4] >> 16) & 0xffff, + (args[4] >> 8) & 0xff, + (args[4] & 0xff) == 0 ? "SUCCESS" : + (args[4] & 0xff) == 1 ? "NO_ACK" : + (args[4] & 0xff) == 2 ? "DROPPED" : + (args[4] & 0xff) == 3 ? "FILTERED" : + (args[4] & 0xff) == 4 ? "RSP_TIMEOUT" : "UNKNOWN"); + } + break; + case PS_STA_COEX_MODE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "STA PS COEX MODE %s", + args[0] ? "ENABLED" : "DISABLED"); + } + break; + case PS_STA_PSPOLL_ALLOW: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "STA PS-Poll %s flags=%x time=%u", + args[0] ? "ALLOW" : "DISALLOW", args[1], args[2]); + } + break; + case PS_STA_SET_PARAM: + if (numargs == 2) { + struct { + char *name; + int is_time_param; + } params[] = { + { "MAX_SLEEP_ATTEMPTS", 0 }, + { "DELAYED_SLEEP", 1 }, + { "TXRX_INACTIVITY", 1 }, + { "MAX_TX_BEFORE_WAKE", 0 }, + { "UAPSD_TIMEOUT", 1 }, + { "UAPSD_CONFIG", 0 }, + { "PSPOLL_RESPONSE_TIMEOUT", 1 }, + { "MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "RX_WAKE_POLICY", 0 }, + { "DELAYED_PAUSE_RX_LEAK", 1 }, + { "TXRX_INACTIVITY_BLOCKED_RETRY", 1 }, + { "SPEC_WAKE_INTERVAL", 1 }, + { "MAX_SPEC_NODATA_PSPOLL", 0 }, + { "ESTIMATED_PSPOLL_RESP_TIME", 1 }, + { "QPOWER_MAX_PSPOLL_BEFORE_WAKE", 0 }, + { "QPOWER_ENABLE", 0 }, + }; + A_UINT32 param = args[0]; + A_UINT32 value = args[1]; + + if (param < ARRAY_LENGTH(params)) { + if (params[param].is_time_param) { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %u (us)", + params[param].name, value); + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %s => %#x", + params[param].name, value); + } + } else { + dbglog_printf(timestamp, vap_id, "STA PS SET_PARAM %x => %#x", + param, value); + } + } + break; + case PS_STA_SPECPOLL_TIMER_STARTED: + dbglog_printf(timestamp, vap_id, "SPEC Poll Timer Started: Beacon time Remaining:%d wakeup interval:%d", args[0], args[1]); + break; + case PS_STA_SPECPOLL_TIMER_STOPPED: + dbglog_printf(timestamp, vap_id, + "SPEC Poll Timer Stopped"); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_ratectrl_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case RATECTRL_DBGID_ASSOC: + dbglog_printf(timestamp, vap_id, "RATE: ChainMask %d, phymode %d, ni_flags 0x%08x, vht_mcs_set 0x%04x, ht_mcs_set 0x%04x", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_NSS_CHANGE: + dbglog_printf(timestamp, vap_id, "RATE: NEW NSS %d\n", args[0]); + break; + case RATECTRL_DBGID_CHAINMASK_ERR: + dbglog_printf(timestamp, vap_id, "RATE: Chainmask ERR %d %d %d\n", + args[0], args[1], args[2]); + break; + case RATECTRL_DBGID_UNEXPECTED_FRAME: + dbglog_printf(timestamp, vap_id, "RATE: WARN1: rate %d flags 0x%08x\n", args[0], args[1]); + break; + case RATECTRL_DBGID_WAL_RCQUERY: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcquery [rix1 %d rix2 %d rix3 %d proberix %d ppduflag 0x%x] ", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_WAL_RCUPDATE: + dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ", + args[0], args[1]); + break; + case RATECTRL_DBGID_GTX_UPDATE: + { + switch (args[0]) { + case 255: + dbglog_printf(timestamp, vap_id, "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ", + args[1] >> 8, args[1] & 0xff, args[2], args[3], args[4]); + break; + case 254: + dbglog_printf(timestamp, vap_id, "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ", + args[1], args[2], args[3], args[4]); + break; + default: + dbglog_printf(timestamp, vap_id, "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ", + args[0], args[1], args[2], args[3], args[4], args[5]); + } + } + break; + + } + return TRUE; +} + +A_BOOL dbglog_ani_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case ANI_DBGID_ENABLE: + dbglog_printf(timestamp, vap_id, + "ANI Enable: %d", args[0]); + break; + case ANI_DBGID_POLL: + dbglog_printf(timestamp, vap_id, + "ANI POLLING: AccumListenTime %d ListenTime %d ofdmphyerr %d cckphyerr %d", + args[0], args[1], args[2],args[3]); + break; + case ANI_DBGID_RESTART: + dbglog_printf(timestamp, vap_id,"ANI Restart"); + break; + case ANI_DBGID_CURRENT_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI CURRENT LEVEL ofdm level %d cck level %d",args[0],args[1]); + break; + case ANI_DBGID_OFDM_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE ofdm level %d firstep %d firstep_low %d cycpwr_thr %d self_corr_low %d", + args[0], args[1],args[2],args[3],args[4]); + break; + case ANI_DBGID_CCK_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE cck level %d firstep %d firstep_low %d mrc_cck %d", + args[0],args[1],args[2],args[3]); + break; + case ANI_DBGID_CONTROL: + dbglog_printf(timestamp, vap_id, + "ANI CONTROL ofdmlevel %d ccklevel %d\n", + args[0]); + + break; + case ANI_DBGID_OFDM_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI ofdm_control firstep %d cycpwr %d\n", + args[0],args[1]); + break; + case ANI_DBGID_CCK_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI cck_control mrc_cck %d barker_threshold %d\n", + args[0],args[1]); + break; + case ANI_DBGID_RESET: + dbglog_printf(timestamp, vap_id, + "ANI resetting resetflag %d resetCause %8x channel index %d", + args[0],args[1],args[2]); + break; + case ANI_DBGID_SELF_CORR_LOW: + dbglog_printf(timestamp, vap_id,"ANI self_corr_low %d",args[0]); + break; + case ANI_DBGID_FIRSTEP: + dbglog_printf(timestamp, vap_id,"ANI firstep %d firstep_low %d", + args[0],args[1]); + break; + case ANI_DBGID_MRC_CCK: + dbglog_printf(timestamp, vap_id,"ANI mrc_cck %d",args[0]); + break; + case ANI_DBGID_CYCPWR: + dbglog_printf(timestamp, vap_id,"ANI cypwr_thresh %d",args[0]); + break; + case ANI_DBGID_POLL_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure poll period to %d",args[0]); + break; + case ANI_DBGID_LISTEN_PERIOD: + dbglog_printf(timestamp, vap_id,"ANI Configure listen period to %d",args[0]); + break; + case ANI_DBGID_OFDM_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure ofdm level to %d",args[0]); + break; + case ANI_DBGID_CCK_LEVEL_CFG: + dbglog_printf(timestamp, vap_id,"ANI Configure cck level to %d",args[0]); + break; + default: + dbglog_printf(timestamp, vap_id,"ANI arg1 %d arg2 %d arg3 %d", + args[0],args[1],args[2]); + break; + } + return TRUE; +} + +A_BOOL +dbglog_ap_powersave_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case AP_PS_DBGID_UPDATE_TIM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: TIM update AID=%u %s", + args[0], args[1] ? "set" : "clear"); + } + break; + case AP_PS_DBGID_PEER_STATE_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u power save %s", + args[0], args[1] ? "enabled" : "disabled"); + } + break; + case AP_PS_DBGID_PSPOLL: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u pspoll response tid=%u flags=%x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_PEER_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: create peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_PEER_DELETE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: delete peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_VDEV_CREATE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev create"); + break; + case AP_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev delete"); + break; + case AP_PS_DBGID_SYNC_TIM: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u advertised=%#x buffered=%#x", args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_NEXT_RESPONSE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u select next response %s%s%s", args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending usp) " : "", + args[3] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_START_SP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u START SP tsf=%#x (%u)", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_COMPLETED_EOSP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u EOSP eosp_tsf=%#x trigger_tsf=%#x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u TRIGGER tsf=%#x %s%s", args[0], args[1], + args[2] ? "(usp active) " : "", + args[3] ? "(send_n in progress)" : ""); + } + break; + case AP_PS_DBGID_DUPLICATE_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u DUP TRIGGER tsf=%#x seq=%u ac=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_UAPSD_RESPONSE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u UAPSD response tid=%u, n_mpdu=%u flags=%#x max_sp=%u current_sp=%u", + args[0], args[1], args[2], args[3], (args[4] >> 16) & 0xffff, args[4] & 0xffff); + } + break; + case AP_PS_DBGID_SEND_COMPLETE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_COMPLETE fc=%#x qos=%#x %s%s", + args[0], args[1], args[2], + args[3] ? "(usp active) " : "", + args[4] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_SEND_N_COMPLETE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_N_COMPLETE %s%s", + args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u detected out-of-sync now=%u tx_waiting=%u txq_depth=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: CAB %s n_mpdus=%u, flags=%x, extra=%u", + (args[0] == 17) ? "MGMT" : "DATA", args[1], args[2], args[3]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_wal_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "WAIT", + "WAIT_FILTER", + "PAUSE", + "PAUSE_SEND_N", + "BLOCK", + }; + + static const char *events[] = { + "PAUSE", + "PAUSE_FILTER", + "UNPAUSE", + + "BLOCK", + "BLOCK_FILTER", + "UNBLOCK", + + "HWQ_EMPTY", + "ALLOW_N", + }; + +#define WAL_VDEV_TYPE(type) \ + (type == 0 ? "AP" : \ + (type == 1 ? "STA" : \ + (type == 2 ? "IBSS" : \ + (type == 2 ? "MONITOR" : \ + "UNKNOWN")))) + +#define WAL_SLEEP_STATE(state) \ + (state == 1 ? "NETWORK SLEEP" : \ + (state == 2 ? "AWAKE" : \ + (state == 3 ? "SYSTEM SLEEP" : \ + "UNKNOWN"))) + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "TID PAUSE", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case WAL_DBGID_SET_POWER_STATE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "WAL %s => %s, req_count=%u", + WAL_SLEEP_STATE(args[0]), WAL_SLEEP_STATE(args[1]), + args[2]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "WAL channel change (force reset) freq=%u, flags=%u mode=%u rx_ok=%u tx_ok=%u", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1], + args[2], args[3]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "WAL channel change freq=%u, mode=%u flags=%u rx_ok=1 tx_ok=1", + args[0] & 0x0000ffff, (args[0] & 0xffff0000) >> 16, args[1]); + } + break; + case WAL_DBGID_VDEV_START: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "WAL %s vdev started", + WAL_VDEV_TYPE(args[0])); + } + break; + case WAL_DBGID_VDEV_STOP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev stopped", + WAL_VDEV_TYPE(args[0])); + break; + case WAL_DBGID_VDEV_UP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev up, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_VDEV_DOWN: + dbglog_printf(timestamp, vap_id, "WAL %s vdev down, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame desc_id=0x%x, seq=0x%x, type=0x%x, len=0x%x islocal=0x%x", + args[0], args[1], args[2], (args[3] & 0xffff0000) >> 16, args[3] & 0x0000ffff); + break; + case WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Mgmt frame completion desc_id=0x%x, status=0x%x, islocal=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame msdu_id=0x%x, seq=0x%x, type=0x%x, len=0x%x", + args[0], args[1], args[2], args[3]); + break; + case WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS: + dbglog_printf(timestamp, vap_id, "WAL Tx Data frame completion desc_id=0x%x, status=0x%x, seq=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_RESET_PCU_CYCLE_CNT: + dbglog_printf(timestamp, vap_id, "WAL PCU cycle counter value at reset:%x", args[0]); + break; + case WAL_DBGID_TX_DISCARD: + dbglog_printf(timestamp, vap_id, "WAL Tx enqueue discard msdu_id=0x%x", args[0]); + break; + case WAL_DBGID_SET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK " + "pdev=%d, txchain=0x%x, rxchain=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL: rxstop=%d, txstop=%d", + args[0], args[1]); + break; + case WAL_DBGID_GET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_GET_HW_CHAINMASK " + "txchain=0x%x, rxchain=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_DISABLE: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_DISABLE"); + break; + case WAL_DBGID_SMPS_ENABLE_HW_CNTRL: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_ENABLE_HW_CNTRL low_pwr_mask=0x%x, high_pwr_mask=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_SWSEL_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_SWSEL_CHAINMASK low_pwr=0x%x, chain_mask=0x%x", + args[0], args[1]); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_scan_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "BSSCHAN", + "WAIT_FOREIGN_CHAN", + "FOREIGN_CHANNEL", + "TERMINATING" + }; + + static const char *events[] = { + "REQ", + "STOP", + "BSSCHAN", + "FOREIGN_CHAN", + "CHECK_ACTIVITY", + "REST_TIME_EXPIRE", + "DWELL_TIME_EXPIRE", + "PROBE_TIME_EXPIRE", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "SCAN", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_coex_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 * args) +{ + A_UINT8 i, j = 0; + char * dbg_id_str; + + static const char * wlan_rx_xput_status[] = { + "WLAN_XPUT_NORMAL", + "WLAN_XPUT_UNDER_THRESH", + "WLAN_XPUT_CRITICAL", + "WLAN_XPUT_RECOVERY_TIMEOUT", + }; + + static const char * coex_sched_req[] = { + "SCHED_REQ_NEXT", + "SCHED_REQ_BT", + "SCHED_REQ_WLAN", + "SCHED_REQ_POSTPAUSE", + "SCHED_REQ_UNPAUSE", + }; + + static const char * coex_sched_type[] = { + "SCHED_NONE", + "SCHED_WLAN", + "SCHED_BT", + "SCHED_WLAN_PAUSE", + "SCHED_WLAN_POSTPAUSE", + "SCHED_WLAN_UNPAUSE", + }; + + static const char * coex_trf_mgmt_type[] = { + "TRF_MGMT_FREERUN", + "TRF_MGMT_SHAPE_PM", + "TRF_MGMT_SHAPE_PSP", + "TRF_MGMT_SHAPE_S_CTS", + }; + + static const char * coex_system_status[] = { + "BT_OFF", + "BTCOEX_NOT_REQD", + "WLAN_IS_IDLE", + "EXECUTE_SCHEME", + "BT_FULL_CONCURRENCY", + "WLAN_SLEEPING", + "WLAN_IS_PAUSED", + "WAIT_FOR_NEXT_ACTION", + }; + + static const char * wlan_rssi_type[] = { + "LOW_RSSI", + "MID_RSSI", + "HI_RSSI", + "INVALID_RSSI", + }; + + static const char * coex_bt_scheme[] = { + "IDLE_CTRL", + "ACTIVE_ASYNC_CTRL", + "PASSIVE_SYNC_CTRL", + "ACTIVE_SYNC_CTRL", + "DEFAULT_CTRL", + "CONCURRENCY_CTRL", + }; + + static const char * wal_peer_rx_rate_stats_event_sent[] = { + "PR_RX_EVT_SENT_NONE", + "PR_RX_EVT_SENT_LOWER", + "PR_RX_EVT_SENT_UPPER", + }; + + static const char * wlan_psp_stimulus[] = { + "ENTRY", + "EXIT", + "PS_READY", + "PS_NOT_READY", + "RX_MORE_DATA_RCVD", + "RX_NO_MORE_DATA_RCVD", + "TX_DATA_COMPLT", + "TX_COMPLT", + "TIM_SET", + "REQ", + "DONE_SUCCESS", + "DONE_NO_PS_POLL_ACK", + "DONE_RESPONSE_TMO", + "DONE_DROPPED", + "DONE_FILTERED", + "WLAN_START", + "NONWLAN_START", + "NONWLAN_INTVL_UPDATE", + "NULL_TX", + "NULL_TX_COMPLT", + "BMISS_FIRST", + "NULL_TX_FAIL", + "RX_NO_MORE_DATA_DATAFRM", + }; + + static const char * coex_pspoll_state[] = { + "STATE_DISABLED", + "STATE_NOT_READY", + "STATE_ENABLED", + "STATE_READY", + "STATE_TX_STATUS", + "STATE_RX_STATUS", + }; + + static const char * coex_scheduler_interval[] = { + "COEX_SCHED_NONWLAN_INT", + "COEX_SCHED_WLAN_INT", + }; + + static const char * wlan_weight[] = { + "BT_COEX_BASE", + "BT_COEX_LOW", + "BT_COEX_MID", + "BT_COEX_MID_NONSYNC", + "BT_COEX_HI_NONVOICE", + "BT_COEX_HI", + "BT_COEX_CRITICAL", + }; + + static const char * coex_psp_error_type[] = { + "DISABLED_STATE", + "VDEV_NULL", + "COEX_PSP_ENTRY", + "ZERO_INTERVAL", + "COEX_PSP_EXIT", + "READY_DISABLED", + "READY_NOT_DISABLED", + "POLL_PKT_DROPPED", + "SET_TIMER_PARAM", + }; + + dbg_id_str = dbglog_get_msg(mod_id, dbg_id); + + switch (dbg_id) { + case COEX_SYSTEM_UPDATE: + if (numargs >= 1 && args[0] < 8) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_system_status[args[0]]); + } else { + return FALSE; + } + break; + case COEX_SCHED_START: + if (numargs >= 5 && args[0] < 5 && args[2] < 4 && args[3] < 4 && args[4] < 4) { + if (args[1] == 0xffffffff) { + dbglog_printf(timestamp, vap_id, "%s: %s, DETERMINE_DURATION, %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } else { + dbglog_printf(timestamp, vap_id, "%s: %s, IntvlDur(%u), %s, %s, %s", + dbg_id_str, coex_sched_req[args[0]], args[1], coex_trf_mgmt_type[args[2]], wlan_rx_xput_status[args[3]], wlan_rssi_type[args[4]]); + } + } else { + return FALSE; + } + break; + case COEX_SCHED_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, CoexMgrPolicy(%u), WlanIsIdleOverride(%u), HidConcurTxOverride(%u), minRSSI(%u)", + dbg_id_str, coex_sched_type[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_BT_SCHEME: + if (numargs >= 1 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, coex_bt_scheme[args[0]]); + } else { + return FALSE; + } + break; + case COEX_TRF_FREERUN: + case COEX_TRF_SHAPE_PM: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, AllocatedBtIntvls(%u), BtIntvlCnt(%u), AllocatedWlanIntvls(%u), WlanIntvlCnt(%u)", + dbg_id_str, coex_sched_type[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_SYSTEM_MONITOR: + if (numargs >= 5 && args[1] < 4 && args[4] < 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanRxCritical(%u), %s, MinDirectRxRate(%u), XputMonitorActiveNum(%u), %s", + dbg_id_str, args[0], wlan_rx_xput_status[args[1]], args[2], args[3], wlan_rssi_type[args[4]]); + } else { + return FALSE; + } + break; + case COEX_RX_RATE: + if (numargs >= 5 && args[4] < 3) { + dbglog_printf(timestamp, vap_id, "%s: NumUnderThreshPeers(%u), MinDirectRate(%u), LastRateSample(%u), DeltaT(%u), %s", + dbg_id_str, args[0], args[1], args[2], args[3], wal_peer_rx_rate_stats_event_sent[args[4]]); + } else { + return FALSE; + } + break; + case COEX_WLAN_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_WLAN_POSTPAUSE_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: WlanPostPauseIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_BT_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: BtIntvlCnt(%u), HidConcurrentTxOverride(%u), EnableBtBwLimit(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_ENTER: + if (numargs >= 5 && args[0] < 23 && args[1] < 6 && args[3] < 2) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, PsPollAvg(%u), %s, CurrT(%u)", + dbg_id_str, wlan_psp_stimulus[args[0]], coex_pspoll_state[args[1]], args[2], coex_scheduler_interval[args[3]], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_MGR_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, PsPollAvg(%u), EstimationOverrun(%u), EstimationUnderun(%u), NotReadyErr(%u)", + dbg_id_str, coex_pspoll_state[args[0]], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_TRF_SHAPE_PSP: + if (numargs == 2 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s, CurrT(%u)", + dbg_id_str, coex_pspoll_state[args[0]], args[1]); + } else if (numargs >= 5 && args[0] < 6 && args[1] < 7) { + dbglog_printf(timestamp, vap_id, "%s: %s, %s, Dur(%u), WlanOverride(%u), PrioritizeWlanDuringCollis(%u)", + dbg_id_str, coex_sched_type[args[0]], wlan_weight[args[1]], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_SPEC_POLL: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: PsPollSpecEna(%u), Count(%u), NextTS(%u), AllowSpecPsPollTx(%u), Intvl(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_READY_STATE: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: T2BT(%u), CoexSchedulerEndTS(%u), MoreData(%u), PSPRespExpectedTS(%u), NonWlanIdleT(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_NONWLAN_INTERVAL: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, "%s: NonWlanBaseIntvl(%u), NonWlanIdleT(%u), PSPSpecIntvl(%u), ApRespTimeout(%u)", + dbg_id_str, args[0], args[1], args[2], args[3]); + } else { + return FALSE; + } + break; + case COEX_PSP_ERROR: + if (numargs >= 1 && args[0] < 9) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %s", + dbg_id_str, coex_psp_error_type[args[0]]); + for (i = 1; i < numargs; i++) { + j += snprintf(buf + j, sizeof(buf) - j, ", %u", args[i]); + } + diag_print_legacy_logs(buf); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_1: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: ApResp0(%u), ApResp1(%u), ApResp2(%u), ApResp3(%u), ApResp4(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_STAT_2: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, "%s: DataPt(%u), Max(%u), NextApRespIndex(%u), NumOfValidDataPts(%u), PsPollAvg(%u)", + dbg_id_str, args[0], args[1], args[2], args[3], args[4]); + } else { + return FALSE; + } + break; + case COEX_PSP_RX_STATUS_STATE_1: + if (numargs >= 5) { + if (args[2]) { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Overrun, RsOverrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } else { + dbglog_printf(timestamp, vap_id, "%s: RsExpectedTS(%u), RespActualTS(%u), Underrun, RsUnderrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], args[3], args[4]); + } + } else { + return FALSE; + } + break; + //Translate following into decimal + case COEX_SINGLECHAIN_DBG_1: + case COEX_SINGLECHAIN_DBG_2: + case COEX_SINGLECHAIN_DBG_3: + case COEX_MULTICHAIN_DBG_1: + case COEX_MULTICHAIN_DBG_2: + case COEX_MULTICHAIN_DBG_3: + if (numargs > 0) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %u", + dbg_id_str, args[0]); + for (i = 1; i < numargs; i++) { + j += snprintf(buf + j, sizeof(buf) - j, ", %u", args[i]); + } + diag_print_legacy_logs(buf); + } else { + return FALSE; + } + break; + case COEX_LinkID: + if (numargs >= 4) { + if (args[0]) { //Add profile + dbglog_printf(timestamp, vap_id, "%s Alloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } else { //Remove profile + dbglog_printf(timestamp, vap_id, "%s Dealloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], args[3]); + } + } else { + return FALSE; + } + break; + case COEX_BT_DURATION: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "%s: Result(%u), NumOfValidSchedMsgs(%u) PrioLowerLimit(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return FALSE; + } + break; + case COEX_T2BT: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, "%s: Result(%u), BtTime1(%u), PrioLowerLimit(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return FALSE; + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_beacon_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "INIT", + "ADJUST_START", + "ADJUSTING", + "ADJUST_HOLD", + }; + + static const char *events[] = { + "ADJUST_START", + "ADJUST_RESTART", + "ADJUST_STOP", + "ADJUST_PAUSE", + "ADJUST_UNPAUSE", + "ADJUST_INC_SLOP_STEP", + "ADJUST_HOLD", + "ADJUST_HOLD_TIME_OUT", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "EARLY_RX", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case BEACON_EVENT_EARLY_RX_BMISS_STATUS: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "early_rx bmiss status:rcv=%d total=%d miss=%d", + args[0], args[1], args[2]); + } + break; + case BEACON_EVENT_EARLY_RX_SLEEP_SLOP: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx cont bmiss timeout,update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx skip bcn num:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CLK_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx clk drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_AP_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx ap drift:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_BCN_TYPE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx skip bcn num:%d", + args[0]); + } + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_data_txrx_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + switch (dbg_id) { + case DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO: + dbglog_printf(timestamp, vap_id, "DATA RX seq=0x%x, len=0x%x, stored=0x%x, duperr=0x%x", + args[0], args[1], (args[2] & 0xffff0000) >> 16, args[2] & 0x0000ffff); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL dbglog_smps_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "S_INACTIVE", + "S_STATIC", + "S_DYNAMIC", + "S_STALLED", + "S_INACTIVE_WAIT", + "S_STATIC_WAIT", + "S_DYNAMIC_WAIT", + }; + + static const char *events[] = { + "E_STOP", + "E_STOP_COMPL", + "E_START", + "E_STATIC", + "E_STATIC_COMPL", + "E_DYNAMIC", + "E_DYNAMIC_COMPL", + "E_STALL", + "E_RSSI_ABOVE_THRESH", + "E_RSSI_BELOW_THRESH", + "E_FORCED_NONE", + }; + + switch(dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA_SMPS SM", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + case STA_SMPS_DBGID_CREATE_PDEV_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create PDEV ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete Virtual Chan ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START: + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP: + break; + case STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME: + dbglog_printf(timestamp, vap_id, "STA_SMPS STA %#x Signal SMPS mode as %s; cb_flags %#x", + args[0], + (args[1] == 0 ? "DISABLED": + (args[1] == 0x1 ? "STATIC" : + (args[1] == 0x3 ? "DYNAMIC" : "UNKNOWN"))), + args[2]); + break; + case STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE " + "tx_mask %#x rx_mask %#x arb_dtim_mask %#x", + args[0], args[1], args[2]); + break; + case STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE cur_pwr_state %s new_pwr_state %s", + (args[0] == 0x1 ? "SLEEP": + (args[0] == 0x2 ? "AWAKE": + (args[0] == 0x3 ? "FULL_SLEEP" : "UNKNOWN"))), + (args[1] == 0x1 ? "SLEEP": + (args[1] == 0x2 ? "AWAKE": + (args[1] == 0x3 ? "FULL_SLEEP" : "UNKNOWN")))); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP " + "tx_mask %#x rx_mask %#x orig_rx %#x dtim_rx %#x", + args[0], args[1], args[2], args[3]); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE: + dbglog_printf(timestamp, vap_id, "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE " + "tx_mask %#x rx_mask %#x orig_rx %#x", + args[0], args[1], args[2]); + break; + default: + dbglog_printf( + timestamp, + vap_id, + "STA_SMPS: UNKNOWN DBGID!"); + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_p2p_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "DOZE", + "TX_BCN", + "CTWIN", + "OPPPS", + }; + + static const char *events[] = { + "ONESHOT_NOA", + "CTWINDOW", + "PERIODIC_NOA", + "IDLE", + "NOA_CHANGED", + "TBTT", + "TX_BCN_CMP", + "OPPPS_OK", + "OPPPS_CHANGED", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "P2P GO PS", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +A_BOOL +dbglog_pcielp_print_handler( + A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, + A_UINT32 *args) +{ + static const char *states[] = { + "STOP", + "TX", + "RX", + "SLEEP", + "SUSPEND", + }; + + static const char *events[] = { + "VDEV_UP", + "ALL_VDEV_DOWN", + "AWAKE", + "SLEEP", + "TX_ACTIVITY", + "TX_INACTIVITY", + "TX_AC_CHANGE", + "SUSPEND", + "RESUME", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "PCIELP", + states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events)); + break; + default: + return FALSE; + } + + return TRUE; +} + +int parser_init() +{ + /* Registering parser */ + dbglog_reg_modprint(WLAN_MODULE_STA_PWRSAVE, dbglog_sta_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_AP_PWRSAVE, dbglog_ap_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WAL, dbglog_wal_print_handler); + dbglog_reg_modprint(WLAN_MODULE_SCAN, dbglog_scan_print_handler); + dbglog_reg_modprint(WLAN_MODULE_RATECTRL, dbglog_ratectrl_print_handler); + dbglog_reg_modprint(WLAN_MODULE_ANI, dbglog_ani_print_handler); + dbglog_reg_modprint(WLAN_MODULE_COEX, dbglog_coex_print_handler); + dbglog_reg_modprint(WLAN_MODULE_BEACON,dbglog_beacon_print_handler); + dbglog_reg_modprint(WLAN_MODULE_DATA_TXRX,dbglog_data_txrx_print_handler); + dbglog_reg_modprint(WLAN_MODULE_STA_SMPS, dbglog_smps_print_handler); + dbglog_reg_modprint(WLAN_MODULE_P2P, dbglog_p2p_print_handler); + dbglog_reg_modprint(WLAN_MODULE_PCIELP, dbglog_pcielp_print_handler); + dbglog_reg_modprint(WLAN_MODULE_NAN, dbglog_nan_print_handler); + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/tools/pktlog/Android.mk b/drivers/staging/qcacld-2.0/tools/pktlog/Android.mk new file mode 100644 index 0000000000000..9cf7c4b9d807a --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/pktlog/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +PKTLOGCONF_INC := $(LOCAL_PATH)/../../CORE/SERVICES/COMMON +LOCAL_MODULE := pktlogconf +LOCAL_C_INCLUDES := $(PKTLOGCONF_INC) +LOCAL_SRC_FILES := pktlogconf.c +include $(BUILD_EXECUTABLE) diff --git a/drivers/staging/qcacld-2.0/tools/pktlog/Makefile b/drivers/staging/qcacld-2.0/tools/pktlog/Makefile new file mode 100644 index 0000000000000..76a1cdf103194 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/pktlog/Makefile @@ -0,0 +1,12 @@ +CC = gcc +CORE_DIR := $(shell pwd)/../../CORE +PKTLOG_INCLUDE := -I$(CORE_DIR)/UTILS/PKTLOG/include \ + -I$(CORE_DIR)/SERVICES/COMMON + +all: pktlogconf + +pktlogconf: + $(CC) pktlogconf.c $(PKTLOG_INCLUDE) -o pktlogconf + +clean: + rm -f pktlogconf diff --git a/drivers/staging/qcacld-2.0/tools/pktlog/Makefile.am b/drivers/staging/qcacld-2.0/tools/pktlog/Makefile.am new file mode 100644 index 0000000000000..98d11070191c7 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/pktlog/Makefile.am @@ -0,0 +1,16 @@ +AM_CFLAGS = -Wall + +TARGET_TYPE ?= AR9888 +TARGET_VERS ?= v2 + +if DEBUG +AM_CFLAGS += -g +else +AM_CFLAGS += -O2 +endif + +AM_CFLAGS += -I $(top_srcdir)/../CORE/SERVICES/COMMON/ \ + -I $(top_srcdir)/../CORE/UTILS/PKTLOG/include + +pktlogconf_SOURCES = pktlogconf.c +bin_PROGRAMS = pktlogconf diff --git a/drivers/staging/qcacld-2.0/tools/pktlog/pktlogconf.c b/drivers/staging/qcacld-2.0/tools/pktlog/pktlogconf.c new file mode 100644 index 0000000000000..1cfbcc44fd6e9 --- /dev/null +++ b/drivers/staging/qcacld-2.0/tools/pktlog/pktlogconf.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2010,2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#include +#include +#include +#include +#include +#include +#include "pktlog_ac_fmt.h" + + +int pktlog_enable(char *sysctl_name, unsigned filter) +{ + FILE *fp; + + fp = fopen(sysctl_name, "w"); + + printf("Open status of the pktlog_enable:%p %s\n", fp, sysctl_name); + if (fp != NULL) { + fprintf(fp, "%i", filter); + fclose(fp); + return 0; + } + return -1; +} + +int +pktlog_options(char *sysctl_options, unsigned long options) +{ + FILE *fp; + + fp = fopen(sysctl_options, "w"); + if (fp == NULL) + return -1; + + fprintf(fp, "%lu", options); + fclose(fp); + return 0; +} + +int pktlog_size(char *sysctl_size, char *sysctl_enable, int size) +{ + FILE *fp; + + /* Make sure logging is disabled before changing size */ + fp = fopen(sysctl_enable, "w"); + + if (fp == NULL) { + fprintf(stderr, "Open failed on enable sysctl\n"); + return -1; + } + fprintf(fp, "%i", 0); + fclose(fp); + + fp = fopen(sysctl_size, "w"); + + if (fp != NULL) { + fprintf(fp, "%i", size); + fclose(fp); + return 0; + } + return -1; +} + +void usage() +{ + fprintf(stderr, + "Packet log configuration\n" + "usage: pktlogconf [-a adapter] [-e[event-list]] [-d] [-s log-size] [-t -k -l]\n" + " [-b -p -i] \n" + " -h show this usage\n" + " -a configures packet logging for specific 'adapter';\n" + " configures system-wide logging if this option is\n" + " not specified\n" + " -d disable packet logging\n" + " -e enable logging events listed in the 'event-list'\n" + " event-list is an optional comma separated list of one or more\n" + " of the following: rx tx rcf rcu ani (eg., pktlogconf -erx,rcu,tx)\n" + " -s change the size of log-buffer to \"log-size\" bytes\n" + " -t enable logging of TCP headers\n" + " -k enable triggered stop by a threshold number of TCP SACK packets\n" + " -l change the number of packets to log after triggered stop\n" + " -b enable triggered stop by a throuput threshold\n" + " -p enable triggered stop by a PER threshold\n" +// not implemented +// " -y enable triggered stop by a threshold number of Phyerrs\n" + " -i change the time period of counting throughput/PER\n" + ); + + exit(-1); +} + + +int main(int argc, char *argv[]) +{ + int c; + int size = -1, tail_length = -1, sack_thr = -1; + int thruput_thresh = -1, per_thresh = -1, phyerr_thresh = -1, trigger_interval = -1; + unsigned long filter = 0, options = 0; + char fstr[24]; + char ad_name[24]; + char sysctl_size[128]; + char sysctl_enable[128]; + char sysctl_options[128]; + char sysctl_sack_thr[128]; + char sysctl_tail_length[128]; + char sysctl_thruput_thresh[128]; + char sysctl_phyerr_thresh[128]; + char sysctl_per_thresh[128]; + char sysctl_trigger_interval[128]; + int opt_a=0, opt_d = 0, opt_e = 0, fflag=0; + + + for (;;) { + c = getopt(argc, argv, "s:e::a:d:tk:l:b:p:i:"); + + if (c < 0) + break; + + switch (c) { + case 't': + options |= ATH_PKTLOG_PROTO; + break; + case 'k': /* triggered stop after # of TCP SACK packets are seen */ + options |= ATH_PKTLOG_TRIGGER_SACK; + sack_thr = atoi(optarg); + break; + case 'l': /* # of tail packets to log after triggered stop */ + tail_length = atoi(optarg); + break; + case 's': + size = atoi(optarg); + break; + case 'e': + if (opt_d) { + usage(); + exit(-1); + } + opt_e = 1; + if (optarg) { + fflag = 1; + snprintf(fstr, sizeof(fstr), "%s", optarg); + fstr[sizeof(fstr) - 1] = '\0'; + } + break; + case 'a': + opt_a = 1; + snprintf(ad_name, sizeof(ad_name), "%s", optarg); + ad_name[sizeof(ad_name) - 1] = '\0'; + printf("Option a:%s\n", ad_name); + break; + case 'd': + snprintf(ad_name, sizeof(ad_name), "%s", optarg); + printf("adname:%s\n", ad_name); + if (opt_e) { + usage(); + exit(-1); + } + opt_d = 1; + break; + case 'b': /* triggered stop after throughput drop below this threshold */ + options |= ATH_PKTLOG_TRIGGER_THRUPUT; + thruput_thresh = atoi(optarg); + break; + case 'p': /* triggered stop after PER increase over this threshold */ + options |= ATH_PKTLOG_TRIGGER_PER; + per_thresh = atoi(optarg); + break; + case 'y': /* triggered stop after # of phyerrs are seen */ + options |= ATH_PKTLOG_TRIGGER_PHYERR; + phyerr_thresh = atoi(optarg); + break; + case 'i': /* time period of counting trigger statistics */ + trigger_interval = atoi(optarg); + break; + default: + usage(); + } + } + + /* + * This protection is needed since system wide logging is not supported yet + */ + if (opt_e) { + if (!opt_a) { + printf("Please enter the adapter\n"); + usage(); + exit(-1); + } + } + + if (opt_a) { + snprintf(sysctl_enable, sizeof(sysctl_enable), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/enable", ad_name); + snprintf(sysctl_size, sizeof(sysctl_size), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/size", ad_name); + snprintf(sysctl_options, sizeof(sysctl_options), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/options", ad_name); + snprintf(sysctl_sack_thr, sizeof(sysctl_sack_thr), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/sack_thr", ad_name); + snprintf(sysctl_tail_length, sizeof(sysctl_tail_length), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/tail_length", ad_name); + snprintf(sysctl_thruput_thresh, sizeof(sysctl_thruput_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/thruput_thresh", ad_name); + snprintf(sysctl_per_thresh, sizeof(sysctl_per_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/per_thresh", ad_name); + snprintf(sysctl_phyerr_thresh, sizeof(sysctl_phyerr_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/phyerr_thresh", ad_name); + snprintf(sysctl_trigger_interval, sizeof(sysctl_trigger_interval), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/trigger_interval", ad_name); + } else { + snprintf(sysctl_enable, sizeof(sysctl_enable), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/enable"); + snprintf(sysctl_size, sizeof(sysctl_size), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/size"); + snprintf(sysctl_options, sizeof(sysctl_options), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/options"); + snprintf(sysctl_sack_thr, sizeof(sysctl_sack_thr), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/sack_thr"); + snprintf(sysctl_tail_length, sizeof(sysctl_tail_length), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/tail_length"); + snprintf(sysctl_thruput_thresh, sizeof(sysctl_thruput_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/thruput_thresh"); + snprintf(sysctl_per_thresh, sizeof(sysctl_per_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/per_thresh"); + snprintf(sysctl_phyerr_thresh, sizeof(sysctl_phyerr_thresh), + "/proc/sys/" PKTLOG_PROC_DIR "/" PKTLOG_PROC_SYSTEM "/phyerr_thresh"); + snprintf(sysctl_trigger_interval, sizeof(sysctl_trigger_interval), + "/proc/sys/" PKTLOG_PROC_DIR "/" + PKTLOG_PROC_SYSTEM "/trigger_interval"); + } + + if (opt_d) { + /* + * Need to be removed + * Must disbale the entire system + * However doing the above does not work for individual adapter logging + * Needs fix + */ + snprintf(sysctl_enable, sizeof(sysctl_enable), + "/proc/sys/" PKTLOG_PROC_DIR "/%s/enable", ad_name); + printf("sysctl_enable: %s\n", sysctl_options); + pktlog_options(sysctl_options, 0); + pktlog_enable(sysctl_enable, 0); + printf("Called _pktlog_enable with parameter %d\n", (int) 0); + return 0; + } + + if (sack_thr > 0) { + if (options & ATH_PKTLOG_PROTO) { + if (pktlog_size(sysctl_sack_thr, sysctl_enable, sack_thr) != 0) { + fprintf(stderr, "pktlogconf: log sack_thr setting failed\n"); + exit(-1); + } + if (pktlog_size(sysctl_tail_length, sysctl_enable, tail_length) != 0) { + fprintf(stderr, "pktlogconf: log tail_length setting failed\n"); + exit(-1); + } + } else { + usage(); + exit(-1); + } + } + + if (thruput_thresh > 0) { + if (pktlog_size(sysctl_thruput_thresh, sysctl_enable, thruput_thresh) != 0) { + fprintf(stderr, "pktlogconf: log thruput_thresh setting failed\n"); + exit(-1); + } + } + if (per_thresh > 0) { + if (pktlog_size(sysctl_per_thresh, sysctl_enable, per_thresh) != 0) { + fprintf(stderr, "pktlogconf: log per_thresh setting failed\n"); + exit(-1); + } + } + if (phyerr_thresh > 0) { + if (pktlog_size(sysctl_phyerr_thresh, sysctl_enable, phyerr_thresh) != 0) { + fprintf(stderr, "pktlogconf: log phyerr_thresh setting failed\n"); + exit(-1); + } + } + if (trigger_interval > 0) { + if (pktlog_size(sysctl_trigger_interval, sysctl_enable, trigger_interval) != 0) { + fprintf(stderr, "pktlogconf: log trigger_interval setting failed\n"); + exit(-1); + } + } + + if (fflag) { + if (strstr(fstr, "rx")) + filter |= ATH_PKTLOG_RX; + if (strstr(fstr, "tx")) + filter |= ATH_PKTLOG_TX; + if (strstr(fstr, "rcf")) + filter |= ATH_PKTLOG_RCFIND; + if (strstr(fstr, "rcu")) + filter |= ATH_PKTLOG_RCUPDATE; + if (strstr(fstr, "ani")) + filter |= ATH_PKTLOG_ANI; + if (strstr(fstr, "text")) + filter |= ATH_PKTLOG_TEXT; + + printf("_pktlog_filter:%lu\n", filter); + if (filter == 0) + usage(); + } else { + filter = ATH_PKTLOG_ANI | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_RCFIND | + ATH_PKTLOG_RX | ATH_PKTLOG_TX | ATH_PKTLOG_TEXT; + printf("_pktlog_filter:%lu\n", filter); + } + + if (size >= 0) + if (pktlog_size(sysctl_size, sysctl_enable, size) != 0) { + fprintf(stderr, "pktlogconf: log size setting failed\n"); + exit(-1); + } + + if (opt_e) { + if (pktlog_enable(sysctl_enable, filter) != 0) { + fprintf(stderr, "pktlogconf: log filter setting failed\n"); + exit(-1); + } + if (pktlog_options(sysctl_options, options) != 0) { + fprintf(stderr, "pktlogconf: options setting failed\n"); + exit(-1); + } + } + + return 0; +} diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/halCompiler.h b/drivers/staging/qcacld-2.0/wcnss/inc/halCompiler.h new file mode 100644 index 0000000000000..2c4762d3139ab --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/halCompiler.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: aniCompiler.h + * + * @brief: This file tries to abstract the differences among compilers. + * Supported compilers are: + * ARM RVCT compiler + * + * @author: Kumar Anand + * + * + *=========================================================================*/ +#ifndef __ANI_COMPILER_ABSTRACT_H +#define __ANI_COMPILER_ABSTRACT_H + +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + * 3. Intel C/C++ Compiler + * + * How to detect icc : __INTEL_COMPILER, __ICC (legacy), __ECC (legacy) + * How to detect icc version : + * __INTEL_COMPILER, __ICC, __ECC (700 = 7.0, 900 = 9.0, ...) + * + * 4. Other compilers (not supported) + * + * Borland : __BORLANDC__ + * Greenhills : __ghs + * Metrowerks : __MWERKS__ + * SGI MIPSpro : __sgi + */ + +/* + * Packing directives : These are used to force compiler to pack bits and + * bytes in the data structure. C standard does not regulate this strictly, + * and many things are to compiler implementation. Many compilers support + * compiler specific directives or options that allow different packing + * and alignment. + * + * Alignment directives : Compiler may think packed data structures have + * no specific alignment requirement. Then compiler may generate multiple + * byte accesses to access two byte or four bytes data structures. This + * affects on performance especially for RISC systems. If some data + * structure is located on specific alignment always, alignment directives + * help compiler generate more efficient codes. + */ + +#undef __ANI_COMPILER_PRAGMA_PACK_STACK +#undef __ANI_COMPILER_PRAGMA_PACK + +#if defined(_MSC_VER) +#define __ANI_COMPILER_PRAGMA_PACK_STACK 1 +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#define PACKED +#define PACKED_POST +#define ALIGN(__value) +#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#define PACKED +#define PACKED_POST +#define ALIGN(__value) +#elif defined(__GNUC__) +#define __ani_attr_pre_packed +#define __ani_attr_packed __attribute__((packed)) +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#ifndef PACKED +#define PACKED +#endif +#ifndef PACKED_POST +#define PACKED_POST __attribute__((packed)) +#endif +#ifndef ALIGN +#define ALIGN(__value) __attribute__((aligned(__value))) +#endif +#elif defined(ANI_COMPILER_TYPE_RVCT) +/* Nothing defined so far */ + +/* + * RIVA 1.2 and Pronto uses ARMCT5.1 compiler and it throws lot of warning when __align() is used in structure definitions. + * __attribute__((aligned())) is GNU compiler attribute that is accepted by ARM compiler and resolves the warnings. + */ +#if (__ARMCC_VERSION > 400000) +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#define PACKED __packed +#define PACKED_POST +#define ALIGN(__value) __align(__value) +#define PREPACK __packed +#define POSTPACK +#else +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __align(2) +#define __ani_attr_aligned_4 __align(4) +#define __ani_attr_aligned_8 __align(8) +#define __ani_attr_aligned_16 __align(16) +#define __ani_attr_aligned_32 __align(32) +#define PACKED __packed +#define PACKED_POST +#define ALIGN(__value) __align(__value) +#endif + +#else +#error "Unknown compiler" +#endif + +#ifndef PACKED_PRE +#define PACKED_PRE __ani_attr_pre_packed +#endif + +#ifndef ALIGN_4 +#define ALIGN_4 __ani_attr_aligned_4 +#endif + +#endif //__ANI_COMPILER_ABSTRACT_H + diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/halLegacyPalTypes.h b/drivers/staging/qcacld-2.0/wcnss/inc/halLegacyPalTypes.h new file mode 100644 index 0000000000000..3dd3f3354f3b3 --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/halLegacyPalTypes.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __LEGACYPALTYPES_H__ ) +#define __LEGACYPALTYPES_H__ + +/*========================================================================== + * + * @file: halLegacyPalTypes.h + * + * @brief: Exports and types for the Platform Abstraction Layer typedefs. + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#include "qwlanfw_defs.h" + +/* Common type definitions */ +typedef uint8 tANI_U8; +typedef int8 tANI_S8; +typedef uint16 tANI_U16; +typedef int16 tANI_S16; +typedef uint32 tANI_U32; +typedef int32 tANI_S32; + +#ifndef BUILD_QWPTTSTATIC +typedef uint64 tANI_U64; +#endif + +typedef byte tANI_BYTE; +typedef boolean tANI_BOOLEAN; +typedef uint32 tANI_TIMESTAMP; + +#endif /*__LEGACYPALTYPES_H__*/ diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_cfg.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_cfg.h new file mode 100644 index 0000000000000..ceca24ceef10f --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_cfg.h @@ -0,0 +1,941 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: wlan_hal_cfg.h + * + * @brief: Exports and types WLAN HAL configuration + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#ifndef __WLAN_HAL_CFG_H__ +#define __WLAN_HAL_CFG_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ +#include "qwlanfw_defs.h" + +/*------------------------------------------------------------------------- + Preprocessor definitions and constants +-------------------------------------------------------------------------*/ +/* RIVA API version in format W.X.Y.Z is converted to a UINT32 integer */ +#define WLAN_HAL_CONSTRUCT_API_VERSION(W,X,Y,Z) (((W)<<24)+((X)<<16)+((Y)<<8)+(Z)) +#define IS_VERSION_BEFORE_VOWIFI(VER_FROM_HOST) \ + ((VER_FROM_HOST)<=WLAN_HAL_CONSTRUCT_API_VERSION(0,0,2,0))?1:0 + +/*------------------------------------------------------------------------- + Configuration Parameter IDs +-------------------------------------------------------------------------*/ +#define QWLAN_HAL_CFG_STA_ID 0 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA 1 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA 2 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE 3 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN 4 +#define QWLAN_HAL_CFG_CAL_PERIOD 5 +#define QWLAN_HAL_CFG_CAL_CONTROL 6 +#define QWLAN_HAL_CFG_PROXIMITY 7 +#define QWLAN_HAL_CFG_NETWORK_DENSITY 8 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME 9 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU 10 +#define QWLAN_HAL_CFG_RTS_THRESHOLD 11 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT 12 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT 13 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD 14 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO 15 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE 16 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO 17 +#define QWLAN_HAL_CFG_FIXED_RATE 18 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY 19 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY 20 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY 21 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION 22 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ 23 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ 24 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ 25 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ 26 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS 27 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT 28 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER 29 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE 31 +#define QWLAN_HAL_CFG_STATS_PERIOD 32 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION 33 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED 34 +#define QWLAN_HAL_CFG_DTIM_PERIOD 35 +#define QWLAN_HAL_CFG_EDCA_WMM_ACBK 36 +#define QWLAN_HAL_CFG_EDCA_WMM_ACBE 37 +#define QWLAN_HAL_CFG_EDCA_WMM_ACVO 38 +#define QWLAN_HAL_CFG_EDCA_WMM_ACVI 39 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH 40 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS 41 +#define QWLAN_HAL_CFG_RPE_POLLING_THRESHOLD 42 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG 43 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG 44 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG 45 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG 46 +#define QWLAN_HAL_CFG_NO_OF_ONCHIP_REORDER_SESSIONS 47 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL 48 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD 49 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER 50 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL 51 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD 52 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD 53 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE 54 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM 55 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM 56 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE 57 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT 58 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN 59 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI 60 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS 61 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI 62 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS 63 +#define QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE 64 +#define QWLAN_HAL_CFG_VALID_RADAR_CHANNEL_LIST 65 +#define QWLAN_HAL_CFG_TX_POWER_24_20 66 +#define QWLAN_HAL_CFG_TX_POWER_24_40 67 +#define QWLAN_HAL_CFG_TX_POWER_50_20 68 +#define QWLAN_HAL_CFG_TX_POWER_50_40 69 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING 70 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL 71 +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4 72 +#define QCOM_WLAN_CFG_MAX_TX_POWER_5 73 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD 74 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP 75 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE 76 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK 77 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS 78 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT 79 +#define QWLAN_HAL_CFG_WCNSS_API_VERSION 80 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT 81 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT 82 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST 83 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT 84 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT 85 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT 86 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT 87 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN 88 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN 89 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN 90 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN 91 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT 92 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN 93 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC 94 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP 95 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO 96 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER 97 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT 98 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION 99 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER 100 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT 101 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT 102 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER 103 +#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE 104 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER 105 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT 106 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT 107 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE 108 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK 109 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME 110 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP 111 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY 112 +#define QWLAN_HAL_CFG_ATH_DISABLE 113 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR 114 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE 115 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE 116 +#define QWLAN_HAL_CFG_MWS_COEX_V1_WAN_FREQ 117 +#define QWLAN_HAL_CFG_MWS_COEX_V1_WLAN_FREQ 118 +#define QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG 119 +#define QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG2 120 +#define QWLAN_HAL_CFG_MWS_COEX_V2_WAN_FREQ 121 +#define QWLAN_HAL_CFG_MWS_COEX_V2_WLAN_FREQ 122 +#define QWLAN_HAL_CFG_MWS_COEX_V2_CONFIG 123 +#define QWLAN_HAL_CFG_MWS_COEX_V2_CONFIG2 124 +#define QWLAN_HAL_CFG_MWS_COEX_V3_WAN_FREQ 125 +#define QWLAN_HAL_CFG_MWS_COEX_V3_WLAN_FREQ 126 +#define QWLAN_HAL_CFG_MWS_COEX_V3_CONFIG 127 +#define QWLAN_HAL_CFG_MWS_COEX_V3_CONFIG2 128 +#define QWLAN_HAL_CFG_MWS_COEX_V4_WAN_FREQ 129 +#define QWLAN_HAL_CFG_MWS_COEX_V4_WLAN_FREQ 130 +#define QWLAN_HAL_CFG_MWS_COEX_V4_CONFIG 131 +#define QWLAN_HAL_CFG_MWS_COEX_V4_CONFIG2 132 +#define QWLAN_HAL_CFG_MWS_COEX_V5_WAN_FREQ 133 +#define QWLAN_HAL_CFG_MWS_COEX_V5_WLAN_FREQ 134 +#define QWLAN_HAL_CFG_MWS_COEX_V5_CONFIG 135 +#define QWLAN_HAL_CFG_MWS_COEX_V5_CONFIG2 136 +#define QWLAN_HAL_CFG_MWS_COEX_V6_WAN_FREQ 137 +#define QWLAN_HAL_CFG_MWS_COEX_V6_WLAN_FREQ 138 +#define QWLAN_HAL_CFG_MWS_COEX_V6_CONFIG 139 +#define QWLAN_HAL_CFG_MWS_COEX_V6_CONFIG2 140 +#define QWLAN_HAL_CFG_MWS_COEX_V7_WAN_FREQ 141 +#define QWLAN_HAL_CFG_MWS_COEX_V7_WLAN_FREQ 142 +#define QWLAN_HAL_CFG_MWS_COEX_V7_CONFIG 143 +#define QWLAN_HAL_CFG_MWS_COEX_V7_CONFIG2 144 +#define QWLAN_HAL_CFG_MWS_COEX_V8_WAN_FREQ 145 +#define QWLAN_HAL_CFG_MWS_COEX_V8_WLAN_FREQ 146 +#define QWLAN_HAL_CFG_MWS_COEX_V8_CONFIG 147 +#define QWLAN_HAL_CFG_MWS_COEX_V8_CONFIG2 148 +#define QWLAN_HAL_CFG_MWS_COEX_V9_WAN_FREQ 149 +#define QWLAN_HAL_CFG_MWS_COEX_V9_WLAN_FREQ 150 +#define QWLAN_HAL_CFG_MWS_COEX_V9_CONFIG 151 +#define QWLAN_HAL_CFG_MWS_COEX_V9_CONFIG2 152 +#define QWLAN_HAL_CFG_MWS_COEX_V10_WAN_FREQ 153 +#define QWLAN_HAL_CFG_MWS_COEX_V10_WLAN_FREQ 154 +#define QWLAN_HAL_CFG_MWS_COEX_V10_CONFIG 155 +#define QWLAN_HAL_CFG_MWS_COEX_V10_CONFIG2 156 +#define QWLAN_HAL_CFG_MWS_COEX_MODEM_BACKOFF 157 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG1 158 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG2 159 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG3 160 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG4 161 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG5 162 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG6 163 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF 164 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT 165 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN 166 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN 167 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN 168 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN 169 +#define QWLAN_HAL_CFG_RMCAST_FIXED_RATE 170 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO 171 +#define QWLAN_HAL_CFG_MAX_PARAMS 172 + + +/* Total number of Integer CFGs. This is used while allocating the memory for TLV */ +#define QWLAN_HAL_CFG_INTEGER_PARAM 172 + +/*------------------------------------------------------------------------- + Configuration Parameter min, max, defaults +-------------------------------------------------------------------------*/ + +/* QWLAN_HAL_CFG_STA_ID*/ +#define QWLAN_HAL_CFG_STA_ID_STADEF "000AF5898989" +#define QCOM_WLAN_CFG_STA_ID_LEN 6 + +/* QWLAN_HAL_CFG_CURRENT_TX_ANTENNA */ +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +/* QWLAN_HAL_CFG_CURRENT_RX_ANTENNA */ +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STADEF 1 + +/* QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE */ +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +/* QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN */ +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STADEF 785 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +/* QWLAN_HAL_CFG_CAL_PERIOD */ +#define QWLAN_HAL_CFG_CAL_PERIOD_STAMIN 2 +#define QWLAN_HAL_CFG_CAL_PERIOD_STAMAX 10 +#define QWLAN_HAL_CFG_CAL_PERIOD_STADEF 5 + +/* QWLAN_HAL_CFG_CAL_CONTROL */ +#define QWLAN_HAL_CFG_CAL_CONTROL_STAMIN 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_STAMAX 1 +#define QWLAN_HAL_CFG_CAL_CONTROL_STADEF 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_CAL_ON 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_CAL_OFF 1 + +/* QWLAN_HAL_CFG_PROXIMITY */ +#define QWLAN_HAL_CFG_PROXIMITY_STAMIN 0 +#define QWLAN_HAL_CFG_PROXIMITY_STAMAX 1 +#define QWLAN_HAL_CFG_PROXIMITY_STADEF 0 +#define QWLAN_HAL_CFG_PROXIMITY_OFF 0 +#define QWLAN_HAL_CFG_PROXIMITY_ON 1 + +/* QWLAN_HAL_CFG_NETWORK_DENSITY */ +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STAMIN 0 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STAMAX 3 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STADEF 3 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_LOW 0 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_MEDIUM 1 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_HIGH 2 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +/* QWLAN_HAL_CFG_MAX_MEDIUM_TIME */ +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STADEF 1024 + +/* QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU */ +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +/* QWLAN_HAL_CFG_RTS_THRESHOLD */ +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STAMAX 2347 +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STADEF 2347 + +/* QWLAN_HAL_CFG_SHORT_RETRY_LIMIT */ +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STADEF 15 + +/* QWLAN_HAL_CFG_LONG_RETRY_LIMIT */ +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STADEF 15 + +/* QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD */ +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 5 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 10 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 15 + +#define QWLAN_HAL_CFG_FIXED_RATE_AUTO 0 +#define QWLAN_HAL_CFG_FIXED_RATE_1MBPS 1 +#define QWLAN_HAL_CFG_FIXED_RATE_2MBPS 2 +#define QWLAN_HAL_CFG_FIXED_RATE_5_5MBPS 3 +#define QWLAN_HAL_CFG_FIXED_RATE_11MBPS 4 +#define QWLAN_HAL_CFG_FIXED_RATE_6MBPS 5 +#define QWLAN_HAL_CFG_FIXED_RATE_9MBPS 6 +#define QWLAN_HAL_CFG_FIXED_RATE_12MBPS 7 +#define QWLAN_HAL_CFG_FIXED_RATE_18MBPS 8 +#define QWLAN_HAL_CFG_FIXED_RATE_24MBPS 9 +#define QWLAN_HAL_CFG_FIXED_RATE_36MBPS 10 +#define QWLAN_HAL_CFG_FIXED_RATE_48MBPS 11 +#define QWLAN_HAL_CFG_FIXED_RATE_54MBPS 12 +#define QWLAN_HAL_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define QWLAN_HAL_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define QWLAN_HAL_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define QWLAN_HAL_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define QWLAN_HAL_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define QWLAN_HAL_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define QWLAN_HAL_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define QWLAN_HAL_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define QWLAN_HAL_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define QWLAN_HAL_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define QWLAN_HAL_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define QWLAN_HAL_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define QWLAN_HAL_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define QWLAN_HAL_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define QWLAN_HAL_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define QWLAN_HAL_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define QWLAN_HAL_CFG_FIXED_RATE_13_5MBPS_MCS0_40MHZ_SIMO 29 +#define QWLAN_HAL_CFG_FIXED_RATE_27MBPS_MCS1_40MHZ_SIMO 30 +#define QWLAN_HAL_CFG_FIXED_RATE_40_5MBPS_MCS2_40MHZ_SIMO 31 +#define QWLAN_HAL_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO 32 +#define QWLAN_HAL_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO 33 +#define QWLAN_HAL_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO 34 +#define QWLAN_HAL_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO 35 +#define QWLAN_HAL_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO 36 +#define QWLAN_HAL_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#define QWLAN_HAL_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#define QWLAN_HAL_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#define QWLAN_HAL_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#define QWLAN_HAL_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#define QWLAN_HAL_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#define QWLAN_HAL_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#define QWLAN_HAL_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +/* QWLAN_HAL_CFG_FIXED_RATE + * Follwing rates in user configuration are mapped to TPE rates + * Mapping is defined in the gHalUserFixedRateCfgToTpeRateTable + */ +#define QWLAN_HAL_CFG_FIXED_RATE_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_STAMAX 226 +#define QWLAN_HAL_CFG_FIXED_RATE_STADEF QWLAN_HAL_CFG_FIXED_RATE_AUTO + +/* QWLAN_HAL_CFG_RMCAST_FIXED_RATE + * Follwing rates in user configuration are mapped to TPE rates + * Mapping is defined in the gHalUserFixedRateCfgToTpeRateTable + */ +#define QWLAN_HAL_CFG_RMCAST_FIXED_RATE_STAMIN 0 +#define QWLAN_HAL_CFG_RMCAST_FIXED_RATE_STAMAX 226 +#define QWLAN_HAL_CFG_RMCAST_FIXED_RATE_STADEF QWLAN_HAL_CFG_FIXED_RATE_24MBPS + +/* QWLAN_HAL_CFG_RETRYRATE_POLICY */ +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STADEF 4 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_RESERVED 2 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_MAX 5 + +/* QWLAN_HAL_CFG_RETRYRATE_SECONDARY */ +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STADEF 0 + +/* QWLAN_HAL_CFG_RETRYRATE_TERTIARY */ +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STADEF 0 + +/* QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION */ +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STADEF 5 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +/* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ */ +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_1MBPS + +/* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ */ +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_6MBPS + +/* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ */ +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_1MBPS + +/* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ */ +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_6MBPS + +/* QWLAN_HAL_CFG_MAX_BA_SESSIONS */ +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STADEF 40 + +/* QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT */ +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +/* QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT */ +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STAMIN 0 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STADEF 300 + +/* QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER */ +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +/* QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR */ +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 1 + +/* QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +/* QWLAN_HAL_CFG_STATS_PERIOD */ +#define QWLAN_HAL_CFG_STATS_PERIOD_STAMIN 1 +#define QWLAN_HAL_CFG_STATS_PERIOD_STAMAX 10 +#define QWLAN_HAL_CFG_STATS_PERIOD_STADEF 10 + +/* QWLAN_HAL_CFG_CFP_MAX_DURATION */ +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STAMIN 0 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STAMAX 65535 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STADEF 30000 + +/* QWLAN_HAL_CFG_FRAME_TRANS_ENABLED */ +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STAMIN 0 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STAMAX 1 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STADEF 0 + +/* QWLAN_HAL_CFG_DTIM_PERIOD */ +#define QWLAN_HAL_CFG_DTIM_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_DTIM_PERIOD_STAMAX 65535 +#define QWLAN_HAL_CFG_DTIM_PERIOD_STADEF 1 + +/* QWLAN_HAL_CFG_BA_THRESHOLD_HIGH */ +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STAMIN 0 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STAMAX 65535 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STADEF 1 + +/* QWLAN_HAL_CFG_MAX_BA_BUFFERS */ +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STAMAX 2560 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STADEF 2560 + + + +/* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G + * Cwmin and Cwmax are two bytes each, MSB first. So Cwmax of [03 FF] is + * equivalent to 0x03ff = 1023*/ +#define QWLAN_HAL_CFG_EDCA_PROFILE_ACM_IDX 0 /* byte[0] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_AIFSN_IDX 1 /* byte[1] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMINA_IDX 2 /* byte[2] & byte [3] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXA_IDX 4 /* byte[4] & byte [5] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPA_IDX 6 /* byte[6] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMINB_IDX 7 /* byte[7] & byte [8] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXB_IDX 9 /* byte[9] & byte [10] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPB_IDX 11 /* byte[11]*/ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMING_IDX 12 /* byte[12] & byte [13] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXG_IDX 14 /* byte[14] & byte [15] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPG_IDX 16 /* byte[16]*/ +#define QWLAN_HAL_CFG_EDCA_PARAM_MAX_LEN 20 + +/* QWLAN_HAL_CFG_EDCA_WMM_ACBK */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACBK_DEFAULT "0007000F03FF00001F03FF00000F03FF00" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACBE */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACBE_DEFAULT "0003000F03FF00001F03FF00000F03FF00" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACVI */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACVI_DEFAULT "00020007000F5E000F001FBC0007000F5E" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACVO */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACVO_DEFAULT "0002000300072F0007000F66000300072F" + + +/* QWLAN_HAL_CFG_RPE_POLLING_THRESHOLD */ +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STAMIN 0 +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STAMAX 65535 +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF 30 + +/* QWLAN_HAL_CFG_NO_OF_ONCHIP_REORDER_SESSIONS */ +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN 0 +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX 2 +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF 1 + +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STAMIN 0 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STAMAX 65535 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STADEF 1 + +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STAMAX 65535 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STADEF 40 + +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STAMIN 0 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STAMAX 255 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STADEF 10 + +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STAMIN 0 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STAMAX 255 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STADEF 0 + +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STAMAX 10 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STADEF 10 + +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STAMAX 255 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STADEF 20 + +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STAMIN 0 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STAMAX 1 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STADEF 0 + +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STAMIN 0 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STAMAX 1 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STADEF 0 + +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STADEF 0 + +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STADEF 0 + +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN 0 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX 80 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF 0 + +/* QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE */ +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STAMIN 0 +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STAMAX 1 +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STADEF 1 + +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STAMAX 1 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STADEF 0 + +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STAMAX 7 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STADEF 3 + +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN 5 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX 255 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF 10 + +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STAMAX 7 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STADEF 5 + +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN 5 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX 255 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF 15 + +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN 0 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX 3 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STADEF 0 + +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STAMIN 1 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STAMAX 255 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STADEF 5 + +/*Values to be added in hexadecimal*/ +/* QWLAN_HAL_CFG_VALID_RADAR_LIST */ +#define QWLAN_HAL_CFG_VALID_RADAR_CHANNEL_LIST_DEFAULT "36" +#define QWLAN_HAL_CFG_RADAR_CHANNEL_LIST_LEN 20 + +/* QWLAN_HAL_CFG_TX_POWER_24_20 */ +#define QWLAN_WLAN_TX_POWER_24_20_DEFAULT 299 +#define QWLAN_WLAN_TX_POWER_24_20_MIN 299 +#define QWLAN_WLAN_TX_POWER_24_20_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_24_40 */ +#define QWLAN_WLAN_TX_POWER_24_40_DEFAULT 300 +#define QWLAN_WLAN_TX_POWER_24_40_MIN 299 +#define QWLAN_WLAN_TX_POWER_24_40_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_50_20 */ +#define QWLAN_WLAN_TX_POWER_50_20_DEFAULT 301 +#define QWLAN_WLAN_TX_POWER_50_20_MIN 299 +#define QWLAN_WLAN_TX_POWER_50_20_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_50_40 */ +#define QWLAN_WLAN_TX_POWER_50_40_DEFAULT 302 +#define QWLAN_WLAN_TX_POWER_50_40_MIN 299 +#define QWLAN_WLAN_TX_POWER_50_40_MAX 299 + +/* QCOM_WLAN_CFG_MAX_TX_POWER_2_4 */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4_LEN 128 +/* byte[0] = 0x01 = First Channel; byte[1] = 0x0E = 14 = MaxChannels; byte[2] = 0x14 = 20 = Tx Power (dBm) */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4_DEFAULT "010E14" + +/* QCOM_WLAN_CFG_MAX_TX_POWER_5 */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_5_LEN 128 +/* byte[0] = 0x24 = 36 = First Channel; byte[1] = 0x82 = 130 = MaxChannels; byte[2] = 0x14 = 20 = Tx Power (dBm) */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_5_DEFAULT "248214" + + +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX 65535 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF 0 + +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_DEF 0 + +/* QWLAN_HAL_CFG_BTC_EXECUTION_MODE */ +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_MIN 0 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_MAX 5 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_DEF 0 + +/* QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK */ +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_MAX 255 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_DEF 0 + +/* QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS */ +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_MIN 0 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_MAX 255 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_DEF 15 + +/* QWLAN_HAL_CFG_WCNSS_API_VERSION */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_MIN 0 /* equivalent to 0.0.0.0 */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_MAX 4294967295U /* equivalent to 255.255.255.255 */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_DEF 0 /* equivalent to 0.0.0.0 */ + +/* QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT */ +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_MIN 1 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_MAX 255 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_DEF 20 + +/* QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT */ +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_MIN 1 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_MAX 255 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_DEF 20 + +/* QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST */ +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_DEF 120000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_DEF 30000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT */ +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_MIN 25000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_DEF 250000 + +/* QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN */ +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_MIN 15000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_DEF 45000 + +/* QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC */ +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_MIN 0 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_MAX 100 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_DEF 1 + +/* QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP */ +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_MAX 1 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_DEF 1 + +/* QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO */ +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_MAX 1 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER */ +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_DEF 0 + +/* QWLAN_HAL_CFG_MAX_ASSOC_LIMIT */ +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_MIN 10 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_MAX 32 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_DEF 10 + +/* QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION */ +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER */ +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT */ +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_DEF 0 + +/* QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT */ +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_MIN 3 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_MAX 30 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_DEF 10 + +/* QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT */ +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_MIN 3 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_MAX 30 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_DEF 10 + +/*QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER*/ +/*This value is multiplied to ChannelDwellTime + *i.e If value is 300 then ChannelDwellTime is (3*ChannelDwelltime)*/ +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_MIN 0 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_MAX 300 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_DEF 300 + +/* QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE */ +#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER */ +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT */ +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_DEF 0 + +/* QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT */ +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STAMIN 1 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STADEF 20 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_MAX 1 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_MASK */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_MAX 0xf +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX 10 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_MIN 10 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_MAX 20 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_DEF 10 + +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_DEF 60000 + +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_DEF 90000 + +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_DEF 60000 + +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_DEF 90000 + +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_MIN 0 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_MAX 1 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_DEF 0 + +/* QWLAN_HAL_CFG_ANTENNA_DIVERSITY */ +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_DEF 0 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_MIN 0 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_MAX 3 + +#define QWLAN_HAL_CFG_ATH_DEF 0 +#define QWLAN_HAL_CFG_ATH_MIN 0 +#define QWLAN_HAL_CFG_ATH_MAX 1 + +/* QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR */ +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_DEF 0 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_MIN 0 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_MAX 9 + +/* QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_RX_DRAIN_FEATURE */ +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_DEF 1 + +/* QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE */ +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_MIN 0 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_MAX 1 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_DEF 0 + +/* QWLAN_HAL_CFG_MWS_COEX_XXXX */ +#define QWLAN_HAL_CFG_MWS_COEX_DEF 0 +#define QWLAN_HAL_CFG_MWS_COEX_MIN 0 +#define QWLAN_HAL_CFG_MWS_COEX_MAX 0xFFFFFFFF +#define QWLAN_HAL_CFG_MWS_COEX_MAX_VICTIM 10 +#define QWLAN_HAL_CFG_MWS_COEX_MAX_CONFIG 6 + +/* QWLAN_HAL_CFG_SAR_POWER_BACKOFF */ +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_DEF 13 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_MIN 1 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_MAX 21 + +#endif //__WLAN_HAL_CFG_H__ + + diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_msg.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_msg.h new file mode 100644 index 0000000000000..cbaecdc487127 --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_hal_msg.h @@ -0,0 +1,7081 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: wlan_hal_msg.h + * + * @brief: Exports and types for messages sent to HAL from WDI + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#ifndef _WLAN_HAL_MSG_H_ +#define _WLAN_HAL_MSG_H_ + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" +#include "wlan_qct_dev_defs.h" +#include "wlan_nv.h" + +/*--------------------------------------------------------------------------- + API VERSIONING INFORMATION + + The RIVA API is versioned as MAJOR.MINOR.VERSION.REVISION + The MAJOR is incremented for major product/architecture changes + (and then MINOR/VERSION/REVISION are zeroed) + The MINOR is incremented for minor product/architecture changes + (and then VERSION/REVISION are zeroed) + The VERSION is incremented if a significant API change occurs + (and then REVISION is zeroed) + The REVISION is incremented if an insignificant API change occurs + or if a new API is added + All values are in the range 0..255 (ie they are 8-bit values) + ---------------------------------------------------------------------------*/ +#define WLAN_HAL_VER_MAJOR 1 +#define WLAN_HAL_VER_MINOR 5 +#define WLAN_HAL_VER_VERSION 1 +#define WLAN_HAL_VER_REVISION 2 + +/*--------------------------------------------------------------------------- + Commom Type definitons + ---------------------------------------------------------------------------*/ + +//This is to force compiler to use the maximum of an int ( 4 bytes ) +#define WLAN_HAL_MAX_ENUM_SIZE 0x7FFFFFFF +#define WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE 0x7FFF + +//Max no. of transmit categories +#define STACFG_MAX_TC 8 + +//The maximum value of access category +#define WLAN_HAL_MAX_AC 4 + +typedef tANI_U8 tSirMacAddr[6]; +typedef tANI_U8 tHalIpv4Addr[4]; + +#define HAL_MAC_ADDR_LEN 6 +#define HAL_IPV4_ADDR_LEN 4 + +#define WALN_HAL_STA_INVALID_IDX 0xFF +#define WLAN_HAL_BSS_INVALID_IDX 0xFF + +//Default Beacon template size +#define BEACON_TEMPLATE_SIZE 0x180 + + +//Max Tx Data Rate samples +#define MAX_TX_RATE_SAMPLES 10 +//Max Beacon Rssi samples +#define MAX_BCN_RSSI_SAMPLES 10 + +//Param Change Bitmap sent to HAL +#define PARAM_BCN_INTERVAL_CHANGED (1 << 0) +#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) +#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2) +#define PARAM_llACOEXIST_CHANGED (1 << 3) +#define PARAM_llBCOEXIST_CHANGED (1 << 4) +#define PARAM_llGCOEXIST_CHANGED (1 << 5) +#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6) +#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7) +#define PARAM_RIFS_MODE_CHANGED (1<<8) +#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9) +#define PARAM_OBSS_MODE_CHANGED (1<<10) +#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED|PARAM_SHORT_PREAMBLE_CHANGED|PARAM_SHORT_SLOT_TIME_CHANGED|PARAM_llACOEXIST_CHANGED |PARAM_llBCOEXIST_CHANGED|\ + PARAM_llGCOEXIST_CHANGED|PARAM_HT20MHZCOEXIST_CHANGED|PARAM_NON_GF_DEVICES_PRESENT_CHANGED|PARAM_RIFS_MODE_CHANGED|PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED| PARAM_OBSS_MODE_CHANGED) + +/*Dump command response Buffer size*/ +#define DUMPCMD_RSP_BUFFER 500 + +/*Version string max length (including NUL) */ +#define WLAN_HAL_VERSION_LENGTH 64 + +#define WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE 450 +#define WLAN_HAL_ROAM_SCAN_MAX_CHANNELS NUM_RF_CHANNELS +#define WLAN_HAL_ROAM_SCAN_RESERVED_BYTES 56 + +/* Message types for messages exchanged between WDI and HAL */ +typedef enum +{ + //Init/De-Init + WLAN_HAL_START_REQ = 0, + WLAN_HAL_START_RSP = 1, + WLAN_HAL_STOP_REQ = 2, + WLAN_HAL_STOP_RSP = 3, + + //Scan + WLAN_HAL_INIT_SCAN_REQ = 4, + WLAN_HAL_INIT_SCAN_RSP = 5, + WLAN_HAL_START_SCAN_REQ = 6, + WLAN_HAL_START_SCAN_RSP = 7 , + WLAN_HAL_END_SCAN_REQ = 8, + WLAN_HAL_END_SCAN_RSP = 9, + WLAN_HAL_FINISH_SCAN_REQ = 10, + WLAN_HAL_FINISH_SCAN_RSP = 11, + + // HW STA configuration/deconfiguration + WLAN_HAL_CONFIG_STA_REQ = 12, + WLAN_HAL_CONFIG_STA_RSP = 13, + WLAN_HAL_DELETE_STA_REQ = 14, + WLAN_HAL_DELETE_STA_RSP = 15, + WLAN_HAL_CONFIG_BSS_REQ = 16, + WLAN_HAL_CONFIG_BSS_RSP = 17, + WLAN_HAL_DELETE_BSS_REQ = 18, + WLAN_HAL_DELETE_BSS_RSP = 19, + + //Infra STA asscoiation + WLAN_HAL_JOIN_REQ = 20, + WLAN_HAL_JOIN_RSP = 21, + WLAN_HAL_POST_ASSOC_REQ = 22, + WLAN_HAL_POST_ASSOC_RSP = 23, + + //Security + WLAN_HAL_SET_BSSKEY_REQ = 24, + WLAN_HAL_SET_BSSKEY_RSP = 25, + WLAN_HAL_SET_STAKEY_REQ = 26, + WLAN_HAL_SET_STAKEY_RSP = 27, + WLAN_HAL_RMV_BSSKEY_REQ = 28, + WLAN_HAL_RMV_BSSKEY_RSP = 29, + WLAN_HAL_RMV_STAKEY_REQ = 30, + WLAN_HAL_RMV_STAKEY_RSP = 31, + + //Qos Related + WLAN_HAL_ADD_TS_REQ = 32, + WLAN_HAL_ADD_TS_RSP = 33, + WLAN_HAL_DEL_TS_REQ = 34, + WLAN_HAL_DEL_TS_RSP = 35, + WLAN_HAL_UPD_EDCA_PARAMS_REQ = 36, + WLAN_HAL_UPD_EDCA_PARAMS_RSP = 37, + WLAN_HAL_ADD_BA_REQ = 38, + WLAN_HAL_ADD_BA_RSP = 39, + WLAN_HAL_DEL_BA_REQ = 40, + WLAN_HAL_DEL_BA_RSP = 41, + + WLAN_HAL_CH_SWITCH_REQ = 42, + WLAN_HAL_CH_SWITCH_RSP = 43, + WLAN_HAL_SET_LINK_ST_REQ = 44, + WLAN_HAL_SET_LINK_ST_RSP = 45, + WLAN_HAL_GET_STATS_REQ = 46, + WLAN_HAL_GET_STATS_RSP = 47, + WLAN_HAL_UPDATE_CFG_REQ = 48, + WLAN_HAL_UPDATE_CFG_RSP = 49, + + WLAN_HAL_MISSED_BEACON_IND = 50, + WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = 51, + WLAN_HAL_MIC_FAILURE_IND = 52, + WLAN_HAL_FATAL_ERROR_IND = 53, + WLAN_HAL_SET_KEYDONE_MSG = 54, + + //NV Interface + WLAN_HAL_DOWNLOAD_NV_REQ = 55, + WLAN_HAL_DOWNLOAD_NV_RSP = 56, + + WLAN_HAL_ADD_BA_SESSION_REQ = 57, + WLAN_HAL_ADD_BA_SESSION_RSP = 58, + WLAN_HAL_TRIGGER_BA_REQ = 59, + WLAN_HAL_TRIGGER_BA_RSP = 60, + WLAN_HAL_UPDATE_BEACON_REQ = 61, + WLAN_HAL_UPDATE_BEACON_RSP = 62, + WLAN_HAL_SEND_BEACON_REQ = 63, + WLAN_HAL_SEND_BEACON_RSP = 64, + + WLAN_HAL_SET_BCASTKEY_REQ = 65, + WLAN_HAL_SET_BCASTKEY_RSP = 66, + WLAN_HAL_DELETE_STA_CONTEXT_IND = 67, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ = 68, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP = 69, + + // PTT interface support + WLAN_HAL_PROCESS_PTT_REQ = 70, + WLAN_HAL_PROCESS_PTT_RSP = 71, + + // BTAMP related events + WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ = 72, + WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP = 73, + WLAN_HAL_TL_HAL_FLUSH_AC_REQ = 74, + WLAN_HAL_TL_HAL_FLUSH_AC_RSP = 75, + + WLAN_HAL_ENTER_IMPS_REQ = 76, + WLAN_HAL_EXIT_IMPS_REQ = 77, + WLAN_HAL_ENTER_BMPS_REQ = 78, + WLAN_HAL_EXIT_BMPS_REQ = 79, + WLAN_HAL_ENTER_UAPSD_REQ = 80, + WLAN_HAL_EXIT_UAPSD_REQ = 81, + WLAN_HAL_UPDATE_UAPSD_PARAM_REQ = 82, + WLAN_HAL_CONFIGURE_RXP_FILTER_REQ = 83, + WLAN_HAL_ADD_BCN_FILTER_REQ = 84, + WLAN_HAL_REM_BCN_FILTER_REQ = 85, + WLAN_HAL_ADD_WOWL_BCAST_PTRN = 86, + WLAN_HAL_DEL_WOWL_BCAST_PTRN = 87, + WLAN_HAL_ENTER_WOWL_REQ = 88, + WLAN_HAL_EXIT_WOWL_REQ = 89, + WLAN_HAL_HOST_OFFLOAD_REQ = 90, + WLAN_HAL_SET_RSSI_THRESH_REQ = 91, + WLAN_HAL_GET_RSSI_REQ = 92, + WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ = 93, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 94, + + WLAN_HAL_ENTER_IMPS_RSP = 95, + WLAN_HAL_EXIT_IMPS_RSP = 96, + WLAN_HAL_ENTER_BMPS_RSP = 97, + WLAN_HAL_EXIT_BMPS_RSP = 98, + WLAN_HAL_ENTER_UAPSD_RSP = 99, + WLAN_HAL_EXIT_UAPSD_RSP = 100, + WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP = 101, + WLAN_HAL_UPDATE_UAPSD_PARAM_RSP = 102, + WLAN_HAL_CONFIGURE_RXP_FILTER_RSP = 103, + WLAN_HAL_ADD_BCN_FILTER_RSP = 104, + WLAN_HAL_REM_BCN_FILTER_RSP = 105, + WLAN_HAL_SET_RSSI_THRESH_RSP = 106, + WLAN_HAL_HOST_OFFLOAD_RSP = 107, + WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP = 108, + WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP = 109, + WLAN_HAL_ENTER_WOWL_RSP = 110, + WLAN_HAL_EXIT_WOWL_RSP = 111, + WLAN_HAL_RSSI_NOTIFICATION_IND = 112, + WLAN_HAL_GET_RSSI_RSP = 113, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP = 114, + + //11k related events + WLAN_HAL_SET_MAX_TX_POWER_REQ = 115, + WLAN_HAL_SET_MAX_TX_POWER_RSP = 116, + + //11R related msgs + WLAN_HAL_AGGR_ADD_TS_REQ = 117, + WLAN_HAL_AGGR_ADD_TS_RSP = 118, + + //P2P WLAN_FEATURE_P2P + WLAN_HAL_SET_P2P_GONOA_REQ = 119, + WLAN_HAL_SET_P2P_GONOA_RSP = 120, + + //WLAN Dump commands + WLAN_HAL_DUMP_COMMAND_REQ = 121, + WLAN_HAL_DUMP_COMMAND_RSP = 122, + + //OEM_DATA FEATURE SUPPORT + WLAN_HAL_START_OEM_DATA_REQ = 123, + WLAN_HAL_START_OEM_DATA_RSP = 124, + + //ADD SELF STA REQ and RSP + WLAN_HAL_ADD_STA_SELF_REQ = 125, + WLAN_HAL_ADD_STA_SELF_RSP = 126, + + //DEL SELF STA SUPPORT + WLAN_HAL_DEL_STA_SELF_REQ = 127, + WLAN_HAL_DEL_STA_SELF_RSP = 128, + + // Coex Indication + WLAN_HAL_COEX_IND = 129, + + // Tx Complete Indication + WLAN_HAL_OTA_TX_COMPL_IND = 130, + + //Host Suspend/resume messages + WLAN_HAL_HOST_SUSPEND_IND = 131, + WLAN_HAL_HOST_RESUME_REQ = 132, + WLAN_HAL_HOST_RESUME_RSP = 133, + + WLAN_HAL_SET_TX_POWER_REQ = 134, + WLAN_HAL_SET_TX_POWER_RSP = 135, + WLAN_HAL_GET_TX_POWER_REQ = 136, + WLAN_HAL_GET_TX_POWER_RSP = 137, + + WLAN_HAL_P2P_NOA_ATTR_IND = 138, + + WLAN_HAL_ENABLE_RADAR_DETECT_REQ = 139, + WLAN_HAL_ENABLE_RADAR_DETECT_RSP = 140, + WLAN_HAL_GET_TPC_REPORT_REQ = 141, + WLAN_HAL_GET_TPC_REPORT_RSP = 142, + WLAN_HAL_RADAR_DETECT_IND = 143, + WLAN_HAL_RADAR_DETECT_INTR_IND = 144, + WLAN_HAL_KEEP_ALIVE_REQ = 145, + WLAN_HAL_KEEP_ALIVE_RSP = 146, + + /*PNO messages*/ + WLAN_HAL_SET_PREF_NETWORK_REQ = 147, + WLAN_HAL_SET_PREF_NETWORK_RSP = 148, + WLAN_HAL_SET_RSSI_FILTER_REQ = 149, + WLAN_HAL_SET_RSSI_FILTER_RSP = 150, + WLAN_HAL_UPDATE_SCAN_PARAM_REQ = 151, + WLAN_HAL_UPDATE_SCAN_PARAM_RSP = 152, + WLAN_HAL_PREF_NETW_FOUND_IND = 153, + + WLAN_HAL_SET_TX_PER_TRACKING_REQ = 154, + WLAN_HAL_SET_TX_PER_TRACKING_RSP = 155, + WLAN_HAL_TX_PER_HIT_IND = 156, + + WLAN_HAL_8023_MULTICAST_LIST_REQ = 157, + WLAN_HAL_8023_MULTICAST_LIST_RSP = 158, + + WLAN_HAL_SET_PACKET_FILTER_REQ = 159, + WLAN_HAL_SET_PACKET_FILTER_RSP = 160, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_REQ = 161, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_RSP = 162, + WLAN_HAL_CLEAR_PACKET_FILTER_REQ = 163, + WLAN_HAL_CLEAR_PACKET_FILTER_RSP = 164, + /*This is temp fix. Should be removed once + * Host and Riva code is in sync*/ + WLAN_HAL_INIT_SCAN_CON_REQ = 165, + + WLAN_HAL_SET_POWER_PARAMS_REQ = 166, + WLAN_HAL_SET_POWER_PARAMS_RSP = 167, + + WLAN_HAL_TSM_STATS_REQ = 168, + WLAN_HAL_TSM_STATS_RSP = 169, + + // wake reason indication (WOW) + WLAN_HAL_WAKE_REASON_IND = 170, + // GTK offload support + WLAN_HAL_GTK_OFFLOAD_REQ = 171, + WLAN_HAL_GTK_OFFLOAD_RSP = 172, + WLAN_HAL_GTK_OFFLOAD_GETINFO_REQ = 173, + WLAN_HAL_GTK_OFFLOAD_GETINFO_RSP = 174, + + WLAN_HAL_FEATURE_CAPS_EXCHANGE_REQ = 175, + WLAN_HAL_FEATURE_CAPS_EXCHANGE_RSP = 176, + WLAN_HAL_EXCLUDE_UNENCRYPTED_IND = 177, + + WLAN_HAL_SET_THERMAL_MITIGATION_REQ = 178, + WLAN_HAL_SET_THERMAL_MITIGATION_RSP = 179, + + WLAN_HAL_UPDATE_VHT_OP_MODE_REQ = 182, + WLAN_HAL_UPDATE_VHT_OP_MODE_RSP = 183, + + WLAN_HAL_P2P_NOA_START_IND = 184, + + WLAN_HAL_GET_ROAM_RSSI_REQ = 185, + WLAN_HAL_GET_ROAM_RSSI_RSP = 186, + + WLAN_HAL_CLASS_B_STATS_IND = 187, + WLAN_HAL_DEL_BA_IND = 188, + WLAN_HAL_DHCP_START_IND = 189, + WLAN_HAL_DHCP_STOP_IND = 190, + WLAN_ROAM_SCAN_OFFLOAD_REQ = 191, + WLAN_ROAM_SCAN_OFFLOAD_RSP = 192, + WLAN_HAL_WIFI_PROXIMITY_REQ = 193, + WLAN_HAL_WIFI_PROXIMITY_RSP = 194, + + WLAN_HAL_START_SPECULATIVE_PS_POLLS_REQ = 195, + WLAN_HAL_START_SPECULATIVE_PS_POLLS_RSP = 196, + WLAN_HAL_STOP_SPECULATIVE_PS_POLLS_IND = 197, + + WLAN_HAL_TDLS_LINK_ESTABLISHED_REQ = 198, + WLAN_HAL_TDLS_LINK_ESTABLISHED_RSP = 199, + WLAN_HAL_TDLS_LINK_TEARDOWN_REQ = 200, + WLAN_HAL_TDLS_LINK_TEARDOWN_RSP = 201, + WLAN_HAL_TDLS_IND = 202, + WLAN_HAL_IBSS_PEER_INACTIVITY_IND = 203, + + /* Scan Offload APIs */ + WLAN_HAL_START_SCAN_OFFLOAD_REQ = 204, + WLAN_HAL_START_SCAN_OFFLOAD_RSP = 205, + WLAN_HAL_STOP_SCAN_OFFLOAD_REQ = 206, + WLAN_HAL_STOP_SCAN_OFFLOAD_RSP = 207, + WLAN_HAL_UPDATE_CHANNEL_LIST_REQ = 208, + WLAN_HAL_UPDATE_CHANNEL_LIST_RSP = 209, + WLAN_HAL_OFFLOAD_SCAN_EVENT_IND = 210, + + /* APIs to offload TCP/UDP Heartbeat handshakes */ + WLAN_HAL_LPHB_CFG_REQ = 211, + WLAN_HAL_LPHB_CFG_RSP = 212, + WLAN_HAL_LPHB_IND = 213, + + WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND = 214, + WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND = 215, + WLAN_HAL_PERIODIC_TX_PTRN_FW_IND = 216, + + // Events to set Per-Band Tx Power Limit + WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ = 217, + WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP = 218, + + /* Reliable Multicast using Leader Based Protocol */ + WLAN_HAL_LBP_LEADER_REQ = 219, + WLAN_HAL_LBP_LEADER_RSP = 220, + WLAN_HAL_LBP_UPDATE_IND = 221, + + /* Batchscan */ + WLAN_HAL_BATCHSCAN_SET_REQ = 222, + WLAN_HAL_BATCHSCAN_SET_RSP = 223, + WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND = 224, + WLAN_HAL_BATCHSCAN_RESULT_IND = 225, + WLAN_HAL_BATCHSCAN_STOP_IND = 226, + + WLAN_HAL_GET_IBSS_PEER_INFO_REQ = 227, + WLAN_HAL_GET_IBSS_PEER_INFO_RSP = 228, + + WLAN_HAL_RATE_UPDATE_IND = 229, + + /* Tx Fail for weak link notification */ + WLAN_HAL_TX_FAIL_MONITOR_IND = 230, + WLAN_HAL_TX_FAIL_IND = 231, + + /* Multi-hop IP routing offload */ + WLAN_HAL_IP_FORWARD_TABLE_UPDATE_IND = 232, + + WLAN_HAL_MSG_MAX = WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE +}tHalHostMsgType; + +/* Enumeration for Version */ +typedef enum +{ + WLAN_HAL_MSG_VERSION0 = 0, + WLAN_HAL_MSG_VERSION1 = 1, + WLAN_HAL_MSG_WCNSS_CTRL_VERSION = 0x7FFF, /*define as 2 bytes data*/ + WLAN_HAL_MSG_VERSION_MAX_FIELD = WLAN_HAL_MSG_WCNSS_CTRL_VERSION +}tHalHostMsgVersion; + +/* Enumeration for Boolean - False/True, On/Off */ +typedef enum tagAniBoolean +{ + eANI_BOOLEAN_FALSE = 0, + eANI_BOOLEAN_TRUE, + eANI_BOOLEAN_OFF = 0, + eANI_BOOLEAN_ON = 1, + eANI_BOOLEAN_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +} eAniBoolean; + +typedef enum +{ + eDRIVER_TYPE_PRODUCTION = 0, + eDRIVER_TYPE_MFG = 1, + eDRIVER_TYPE_DVT = 2, + eDRIVER_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tDriverType; + +typedef enum +{ + HAL_STOP_TYPE_SYS_RESET, + HAL_STOP_TYPE_SYS_DEEP_SLEEP, + HAL_STOP_TYPE_RF_KILL, + HAL_STOP_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tHalStopType; + +typedef enum +{ + eHAL_SYS_MODE_NORMAL, + eHAL_SYS_MODE_LEARN, + eHAL_SYS_MODE_SCAN, + eHAL_SYS_MODE_PROMISC, + eHAL_SYS_MODE_SUSPEND_LINK, + eHAL_SYS_MODE_ROAM_SCAN, + eHAL_SYS_MODE_ROAM_SUSPEND_LINK, + eHAL_SYS_MODE_OEM_DATA, + eHAL_SYS_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} eHalSysMode; + +typedef enum +{ + PHY_SINGLE_CHANNEL_CENTERED = 0, // 20MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, // 40MHz IF bandwidth with lower 20MHz supporting the primary channel + PHY_DOUBLE_CHANNEL_CENTERED = 2, // 40MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, // 40MHz IF bandwidth with higher 20MHz supporting the primary channel +#ifdef WLAN_FEATURE_11AC + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + PHY_CHANNEL_BONDING_STATE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}ePhyChanBondState; + +// Spatial Multiplexing(SM) Power Save mode +typedef enum eSirMacHTMIMOPowerSaveState +{ + eSIR_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + eSIR_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + eSIR_HT_MIMO_PS_NA = 2, // reserved + eSIR_HT_MIMO_PS_NO_LIMIT = 3, // SM Power Save disabled + eSIR_HT_MIMO_PS_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirMacHTMIMOPowerSaveState; + +/* each station added has a rate mode which specifies the sta attributes */ +typedef enum eStaRateMode { + eSTA_TAURUS = 0, + eSTA_TITAN, + eSTA_POLARIS, + eSTA_11b, + eSTA_11bg, + eSTA_11a, + eSTA_11n, +#ifdef WLAN_FEATURE_11AC + eSTA_11ac, +#endif + eSTA_INVALID_RATE_MODE = WLAN_HAL_MAX_ENUM_SIZE +} tStaRateMode, *tpStaRateMode; + +#define SIR_NUM_11B_RATES 4 //1,2,5.5,11 +#define SIR_NUM_11A_RATES 8 //6,9,12,18,24,36,48,54 +#define SIR_NUM_POLARIS_RATES 3 //72,96,108 + +#define SIR_MAC_MAX_SUPPORTED_MCS_SET 16 + + +typedef enum eSirBssType +{ + eSIR_INFRASTRUCTURE_MODE, + eSIR_INFRA_AP_MODE, //Added for softAP support + eSIR_IBSS_MODE, + eSIR_BTAMP_STA_MODE, //Added for BT-AMP support + eSIR_BTAMP_AP_MODE, //Added for BT-AMP support + eSIR_AUTO_MODE, + eSIR_DONOT_USE_BSS_TYPE = WLAN_HAL_MAX_ENUM_SIZE +} tSirBssType; + +typedef enum eSirNwType +{ + eSIR_11A_NW_TYPE, + eSIR_11B_NW_TYPE, + eSIR_11G_NW_TYPE, + eSIR_11N_NW_TYPE, + eSIR_DONOT_USE_NW_TYPE = WLAN_HAL_MAX_ENUM_SIZE +} tSirNwType; + +typedef tANI_U16 tSirMacBeaconInterval; + +#define SIR_MAC_RATESET_EID_MAX 12 + +typedef enum eSirMacHTOperatingMode +{ + eSIR_HT_OP_MODE_PURE, // No Protection + eSIR_HT_OP_MODE_OVERLAP_LEGACY, // Overlap Legacy device present, protection is optional + eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT, // No legacy device, but 20 MHz HT present + eSIR_HT_OP_MODE_MIXED, // Protection is required + eSIR_HT_OP_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirMacHTOperatingMode; + +/// Encryption type enum used with peer +typedef enum eAniEdType +{ + eSIR_ED_NONE, + eSIR_ED_WEP40, + eSIR_ED_WEP104, + eSIR_ED_TKIP, + eSIR_ED_CCMP, + eSIR_ED_WPI, + eSIR_ED_AES_128_CMAC, + eSIR_ED_NOT_IMPLEMENTED = WLAN_HAL_MAX_ENUM_SIZE +} tAniEdType; + +#define WLAN_MAX_KEY_RSC_LEN 16 +#define WLAN_WAPI_KEY_RSC_LEN 16 + +/// MAX key length when ULA is used +#define SIR_MAC_MAX_KEY_LENGTH 32 +#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4 + +/// Enum to specify whether key is used +/// for TX only, RX only or both +typedef enum eAniKeyDirection +{ + eSIR_TX_ONLY, + eSIR_RX_ONLY, + eSIR_TX_RX, + eSIR_TX_DEFAULT, + eSIR_DONOT_USE_KEY_DIRECTION = WLAN_HAL_MAX_ENUM_SIZE +} tAniKeyDirection; + +typedef enum eAniWepType +{ + eSIR_WEP_STATIC, + eSIR_WEP_DYNAMIC, + eSIR_WEP_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tAniWepType; + +typedef enum eSriLinkState { + + eSIR_LINK_IDLE_STATE = 0, + eSIR_LINK_PREASSOC_STATE = 1, + eSIR_LINK_POSTASSOC_STATE = 2, + eSIR_LINK_AP_STATE = 3, + eSIR_LINK_IBSS_STATE = 4, + + /* BT-AMP Case */ + eSIR_LINK_BTAMP_PREASSOC_STATE = 5, + eSIR_LINK_BTAMP_POSTASSOC_STATE = 6, + eSIR_LINK_BTAMP_AP_STATE = 7, + eSIR_LINK_BTAMP_STA_STATE = 8, + + /* Reserved for HAL Internal Use */ + eSIR_LINK_LEARN_STATE = 9, + eSIR_LINK_SCAN_STATE = 10, + eSIR_LINK_FINISH_SCAN_STATE = 11, + eSIR_LINK_INIT_CAL_STATE = 12, + eSIR_LINK_FINISH_CAL_STATE = 13, +#ifdef WLAN_FEATURE_P2P + eSIR_LINK_LISTEN_STATE = 14, + eSIR_LINK_SEND_ACTION_STATE = 15, +#endif + eSIR_LINK_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirLinkState; + +typedef enum +{ + HAL_SUMMARY_STATS_INFO = 0x00000001, + HAL_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + HAL_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + HAL_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + HAL_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + HAL_PER_STA_STATS_INFO = 0x00000020 +}eHalStatsMask; + +/* BT-AMP events type */ +typedef enum +{ + BTAMP_EVENT_CONNECTION_START, + BTAMP_EVENT_CONNECTION_STOP, + BTAMP_EVENT_CONNECTION_TERMINATED, + BTAMP_EVENT_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE, //This and beyond are invalid values +} tBtAmpEventType; + +//*************************************************************** + + +/*******************PE Statistics*************************/ +typedef enum +{ + PE_SUMMARY_STATS_INFO = 0x00000001, + PE_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + PE_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + PE_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + PE_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + PE_PER_STA_STATS_INFO = 0x00000020, + PE_STATS_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE //This and beyond are invalid values +}ePEStatsMask; + +/*--------------------------------------------------------------------------- + Message definitons - All the messages below need to be packed + ---------------------------------------------------------------------------*/ + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack(push, 1) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack(1) +#else +#endif + +/// Definition for HAL API Version. +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 revision; + tANI_U8 version; + tANI_U8 minor; + tANI_U8 major; +} tWcnssWlanVersion, *tpWcnssWlanVersion; + +/// Definition for Encryption Keys +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 keyId; + tANI_U8 unicast; // 0 for multicast + tAniKeyDirection keyDirection; + tANI_U8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + tANI_U8 paeRole; // =1 for authenticator,=0 for supplicant + tANI_U16 keyLength; + tANI_U8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tSirKeys, *tpSirKeys; + + +//SetStaKeyParams Moving here since it is shared by configbss/setstakey msgs +typedef PACKED_PRE struct PACKED_POST +{ + /*STA Index*/ + tANI_U16 staIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*STATIC/DYNAMIC - valid only for WEP*/ + tAniWepType wepType; + + /*Default WEP key, valid only for static WEP, must between 0 and 3.*/ + tANI_U8 defWEPIdx; + + /* valid only for non-static WEP encyrptions */ + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + tANI_U8 singleTidRc; + +} tSetStaKeyParams, *tpSetStaKeyParams; + + + +/* 4-byte control message header used by HAL*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalHostMsgType msgType:16; + tHalHostMsgVersion msgVersion:16; + tANI_U32 msgLen; +} tHalMsgHeader, *tpHalMsgHeader; + +/* Config format required by HAL for each CFG item*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Cfg Id. The Id required by HAL is exported by HAL + * in shared header file between UMAC and HAL.*/ + tANI_U16 uCfgId; + + /* Length of the Cfg. This parameter is used to go to next cfg + * in the TLV format.*/ + tANI_U16 uCfgLen; + + /* Padding bytes for unaligned address's */ + tANI_U16 uCfgPadBytes; + + /* Reserve bytes for making cfgVal to align address */ + tANI_U16 uCfgReserve; + + /* Following the uCfgLen field there should be a 'uCfgLen' bytes + * containing the uCfgValue ; tANI_U8 uCfgValue[uCfgLen] */ +} tHalCfg, *tpHalCfg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST sHalMacStartParameters +{ + /* Drive Type - Production or FTM etc */ + tDriverType driverType; + + /*Length of the config buffer*/ + tANI_U32 uConfigBufferLen; + + /* Following this there is a TLV formatted buffer of length + * "uConfigBufferLen" bytes containing all config values. + * The TLV is expected to be formatted like this: + * 0 15 31 31+CFG_LEN-1 length-1 + * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| + */ +} tHalMacStartParameters, *tpHalMacStartParameters; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalMacStartReqMsg messages should be + * header.msgLen = sizeof(tHalMacStartReqMsg) + uConfigBufferLen */ + tHalMsgHeader header; + tHalMacStartParameters startReqParams; +} tHalMacStartReqMsg, *tpHalMacStartReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST sHalMacStartRspParameters +{ + /*success or failure */ + tANI_U16 status; + + /*Max number of STA supported by the device*/ + tANI_U8 ucMaxStations; + + /*Max number of BSS supported by the device*/ + tANI_U8 ucMaxBssids; + + /*API Version */ + tWcnssWlanVersion wcnssWlanVersion; + + /*CRM build information */ + tANI_U8 wcnssCrmVersionString[WLAN_HAL_VERSION_LENGTH]; + + /*hardware/chipset/misc version information */ + tANI_U8 wcnssWlanVersionString[WLAN_HAL_VERSION_LENGTH]; + +} tHalMacStartRspParams, *tpHalMacStartRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStartRspParams startRspParams; +} tHalMacStartRspMsg, *tpHalMacStartRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_STOP_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*The reason for which the device is being stopped*/ + tHalStopType reason; + +}tHalMacStopReqParams, *tpHalMacStopReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStopReqParams stopReqParams; +} tHalMacStopReqMsg, *tpHalMacStopReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_STOP_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalMacStopRspParams, *tpHalMacStopRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStopRspParams stopRspParams; +} tHalMacStopRspMsg, *tpHalMacStopRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_UPDATE_CFG_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Length of the config buffer. Allows UMAC to update multiple CFGs */ + tANI_U32 uConfigBufferLen; + + /* Following this there is a TLV formatted buffer of length + * "uConfigBufferLen" bytes containing all config values. + * The TLV is expected to be formatted like this: + * 0 15 31 31+CFG_LEN-1 length-1 + * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| + */ +} tHalUpdateCfgReqParams, *tpHalUpdateCfgReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalUpdateCfgReqMsg messages should be + * header.msgLen = sizeof(tHalUpdateCfgReqMsg) + uConfigBufferLen */ + tHalMsgHeader header; + tHalUpdateCfgReqParams updateCfgReqParams; +} tHalUpdateCfgReqMsg, *tpHalUpdateCfgReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_UPDATE_CFG_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + +}tHalUpdateCfgRspParams, *tpHalUpdateCfgRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalUpdateCfgRspParams updateCfgRspParams; +} tHalUpdateCfgRspMsg, *tpHalUpdateCfgRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_INIT_SCAN_REQ +---------------------------------------------------------------------------*/ + +/// Frame control field format (2 bytes) +typedef __ani_attr_pre_packed struct sSirMacFrameCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 subType :4; + tANI_U8 type :2; + tANI_U8 protVer :2; + + tANI_U8 order :1; + tANI_U8 wep :1; + tANI_U8 moreData :1; + tANI_U8 powerMgmt :1; + tANI_U8 retry :1; + tANI_U8 moreFrag :1; + tANI_U8 fromDS :1; + tANI_U8 toDS :1; + +#else + + tANI_U8 protVer :2; + tANI_U8 type :2; + tANI_U8 subType :4; + + tANI_U8 toDS :1; + tANI_U8 fromDS :1; + tANI_U8 moreFrag :1; + tANI_U8 retry :1; + tANI_U8 powerMgmt :1; + tANI_U8 moreData :1; + tANI_U8 wep :1; + tANI_U8 order :1; + +#endif + +} __ani_attr_packed tSirMacFrameCtl, *tpSirMacFrameCtl; + +/// Sequence control field +typedef __ani_attr_pre_packed struct sSirMacSeqCtl +{ + tANI_U8 fragNum : 4; + tANI_U8 seqNumLo : 4; + tANI_U8 seqNumHi : 8; +} __ani_attr_packed tSirMacSeqCtl, *tpSirMacSeqCtl; + +/// Management header format +typedef __ani_attr_pre_packed struct sSirMacMgmtHdr +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U8 bssId[6]; + tSirMacSeqCtl seqControl; +} __ani_attr_packed tSirMacMgmtHdr, *tpSirMacMgmtHdr; + +/// Scan Entry to hold active BSS idx's +typedef __ani_attr_pre_packed struct sSirScanEntry +{ + tANI_U8 bssIdx[HAL_NUM_BSSID]; + tANI_U8 activeBSScnt; +}__ani_attr_packed tSirScanEntry, *ptSirScanEntry; + +typedef PACKED_PRE struct PACKED_POST { + + /*LEARN - AP Role + SCAN - STA Role*/ + eHalSysMode scanMode; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /* Following the framelength there is a MAC frame buffer if frameLength + is non-zero. */ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + +} tInitScanParams, * tpInitScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tInitScanParams initScanParams; +} tHalInitScanReqMsg, *tpHalInitScanReqMsg; + +typedef PACKED_PRE struct PACKED_POST { + + /*LEARN - AP Role + SCAN - STA Role*/ + eHalSysMode scanMode; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /* Following the framelength there is a MAC frame buffer if frameLength + is non-zero. */ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + + /* Single NoA usage in Scanning */ + tANI_U8 useNoA; + + /* Indicates the scan duration (in ms) */ + tANI_U16 scanDuration; + +} tInitScanConParams, * tpInitScanConParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tInitScanConParams initScanParams; +} tHalInitScanConReqMsg, *tpHalInitScanConReqMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_INIT_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalInitScanRspParams, *tpHalInitScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalInitScanRspParams initScanRspParams; +} tHalInitScanRspMsg, *tpHalInitScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the channel to scan*/ + tANI_U8 scanChannel; + + } tStartScanParams, * tpStartScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartScanParams startScanParams; +} tHalStartScanReqMsg, *tpHalStartScanReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + tANI_U32 startTSF[2]; + tPowerdBm txMgmtPower; + +}tHalStartScanRspParams, *tpHalStartScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStartScanRspParams startScanRspParams; +} tHalStartScanRspMsg, *tpHalStartScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_END_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the channel to stop scanning. Not used really. But retained + for symmetry with "start Scan" message. It can also help in error + check if needed.*/ + tANI_U8 scanChannel; + +} tEndScanParams, *tpEndScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEndScanParams endScanParams; +} tHalEndScanReqMsg, *tpHalEndScanReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_END_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalEndScanRspParams, *tpHalEndScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEndScanRspParams endScanRspParams; +} tHalEndScanRspMsg, *tpHalEndScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_FINISH_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Identifies the operational state of the AP/STA + * LEARN - AP Role SCAN - STA Role */ + eHalSysMode scanMode; + + /*Operating channel to tune to.*/ + tANI_U8 currentOperChannel; + + /*Channel Bonding state If 20/40 MHz is operational, this will indicate the + 40 MHz extension channel in combination with the control channel*/ + ePhyChanBondState cbState; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /*Following the framelength there is a MAC frame buffer if frameLength + is non-zero.*/ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + +} tFinishScanParams, *tpFinishScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tFinishScanParams finishScanParams; +} tHalFinishScanReqMsg, *tpHalFinishScanReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_FINISH_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalFinishScanRspParams, *tpHalFinishScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFinishScanRspParams finishScanRspParams; +} tHalFinishScanRspMsg, *tpHalFinishScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_STA_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + tANI_U16 reserved; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + +} tSirSupportedRates, *tpSirSupportedRates; + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSSID of STA*/ + tSirMacAddr bssId; + + /*ASSOC ID, as assigned by UMAC*/ + tANI_U16 assocId; + + /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ + tANI_U8 staType; + + /*Short Preamble Supported.*/ + tANI_U8 shortPreambleSupported; + + /*MAC Address of STA*/ + tSirMacAddr staMac; + + /*Listen interval of the STA*/ + tANI_U16 listenInterval; + + /*Support for 11e/WMM*/ + tANI_U8 wmmEnabled; + + /*11n HT capable STA*/ + tANI_U8 htCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed */ + tANI_U8 rifsMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field */ + tANI_U8 lsigTxopProtection; + + /*Max Ampdu Size supported by STA. TPE programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + tANI_U8 maxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + tANI_U8 maxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + tANI_U8 maxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + tANI_U8 fShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + tANI_U8 fShortGI20Mhz; + + /*Robust Management Frame (RMF) enabled/disabled*/ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID. 0 = Add, 1 = Update*/ + tANI_U8 action; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /*Max SP Length*/ + tANI_U8 maxSPLen; + + /*11n Green Field preamble support + 0 - Not supported, 1 - Supported */ + tANI_U8 greenFieldCapable; + + /*MIMO Power Save mode*/ + tSirMacHTMIMOPowerSaveState mimoPS; + + /*Delayed BA Support*/ + tANI_U8 delayedBASupport; + + /*Max AMPDU duration in 32us*/ + tANI_U8 us32MaxAmpduDuration; + + /*HT STA should set it to 1 if it is enabled in BSS. HT STA should set + it to 0 if AP does not support it. This indication is sent to HAL and + HAL uses this flag to pickup up appropriate 40Mhz rates.*/ + tANI_U8 fDsssCckMode40Mhz; + + /* Valid STA Idx when action=Update. Set to 0xFF when invalid! + Retained for backward compalibity with existing HAL code*/ + tANI_U8 staIdx; + + /* BSSID of BSS to which station is associated. Set to 0xFF when invalid. + Retained for backward compalibity with existing HAL code*/ + tANI_U8 bssIdx; + + tANI_U8 p2pCapableSta; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*These rates are the intersection of peer and self capabilities.*/ + tSirSupportedRates supportedRates; + +} tConfigStaParams, *tpConfigStaParams; + +/*------------------------------------------------------------------------ + * WLAN_HAL_CONFIG_STA_REQ + * ----------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + tANI_U16 reserved; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + + /* Indicates the Maximum MCS that can be received for each number + * of spacial streams */ + tANI_U16 vhtRxMCSMap; + + /*Indicate the highest VHT data rate that the STA is able to receive*/ + tANI_U16 vhtRxHighestDataRate; + + /* Indicates the Maximum MCS that can be transmitted for each number + * of spacial streams */ + tANI_U16 vhtTxMCSMap; + + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + tANI_U16 vhtTxHighestDataRate; + +} tSirSupportedRates_V1, *tpSirSupportedRates_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSSID of STA*/ + tSirMacAddr bssId; + + /*ASSOC ID, as assigned by UMAC*/ + tANI_U16 assocId; + + /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ + tANI_U8 staType; + + /*Short Preamble Supported.*/ + tANI_U8 shortPreambleSupported; + + /*MAC Address of STA*/ + tSirMacAddr staMac; + + /*Listen interval of the STA*/ + tANI_U16 listenInterval; + + /*Support for 11e/WMM*/ + tANI_U8 wmmEnabled; + + /*11n HT capable STA*/ + tANI_U8 htCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed */ + tANI_U8 rifsMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field */ + tANI_U8 lsigTxopProtection; + + /*Max Ampdu Size supported by STA. TPE programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + tANI_U8 maxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + tANI_U8 maxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + tANI_U8 maxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + tANI_U8 fShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + tANI_U8 fShortGI20Mhz; + + /*Robust Management Frame (RMF) enabled/disabled*/ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID. 0 = Add, 1 = Update*/ + tANI_U8 action; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /*Max SP Length*/ + tANI_U8 maxSPLen; + + /*11n Green Field preamble support + 0 - Not supported, 1 - Supported */ + tANI_U8 greenFieldCapable; + + /*MIMO Power Save mode*/ + tSirMacHTMIMOPowerSaveState mimoPS; + + /*Delayed BA Support*/ + tANI_U8 delayedBASupport; + + /*Max AMPDU duration in 32us*/ + tANI_U8 us32MaxAmpduDuration; + + /*HT STA should set it to 1 if it is enabled in BSS. HT STA should set + it to 0 if AP does not support it. This indication is sent to HAL and + HAL uses this flag to pickup up appropriate 40Mhz rates.*/ + tANI_U8 fDsssCckMode40Mhz; + + /* Valid STA Idx when action=Update. Set to 0xFF when invalid! + Retained for backward compalibity with existing HAL code*/ + tANI_U8 staIdx; + + /* BSSID of BSS to which station is associated. Set to 0xFF when invalid. + Retained for backward compalibity with existing HAL code*/ + tANI_U8 bssIdx; + + tANI_U8 p2pCapableSta; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 htLdpcEnabled:1; + tANI_U8 vhtLdpcEnabled:1; + tANI_U8 vhtTxBFEnabled:1; + tANI_U8 reserved:5; + + /*These rates are the intersection of peer and self capabilities.*/ + tSirSupportedRates_V1 supportedRates; + + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; + +} tConfigStaParams_V1, *tpConfigStaParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + PACKED_PRE union PACKED_POST { + tConfigStaParams configStaParams; + tConfigStaParams_V1 configStaParams_V1; + } uStaParams; +} tConfigStaReqMsg, *tpConfigStaReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_STA_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Station index; valid only when 'status' field value SUCCESS */ + tANI_U8 staIdx; + + /* BSSID Index of BSS to which the station is associated */ + tANI_U8 bssIdx; + + /* DPU Index for PTK */ + tANI_U8 dpuIndex; + + /* DPU Index for GTK */ + tANI_U8 bcastDpuIndex; + + /*DPU Index for IGTK */ + tANI_U8 bcastMgmtDpuIdx; + + /*PTK DPU signature*/ + tANI_U8 ucUcastSig; + + /*GTK DPU isignature*/ + tANI_U8 ucBcastSig; + + /* IGTK DPU signature*/ + tANI_U8 ucMgmtSig; + + tANI_U8 p2pCapableSta; + +}tConfigStaRspParams, *tpConfigStaRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigStaRspParams configStaRspParams; +}tConfigStaRspMsg, *tpConfigStaRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_STA_REQ +---------------------------------------------------------------------------*/ + +/* Delete STA Request params */ +typedef PACKED_PRE struct PACKED_POST +{ + /* Index of STA to delete */ + tANI_U8 staIdx; +} tDeleteStaParams, *tpDeleteStaParams; + +/* Delete STA Request message*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaParams delStaParams; +} tDeleteStaReqMsg, *tpDeleteStaReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_STA_RSP +---------------------------------------------------------------------------*/ + +/* Delete STA Response Params */ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Index of STA deleted */ + tANI_U8 staId; +} tDeleteStaRspParams, *tpDeleteStaRspParams; + +/* Delete STA Response message*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaRspParams delStaRspParams; +} tDeleteStaRspMsg, *tpDeleteStaRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_BSS_REQ +---------------------------------------------------------------------------*/ + +//12 Bytes long because this structure can be used to represent rate +//and extended rate set IEs. The parser assume this to be at least 12 +typedef __ani_attr_pre_packed struct sSirMacRateSet +{ + tANI_U8 numRates; + tANI_U8 rate[SIR_MAC_RATESET_EID_MAX]; +} __ani_attr_packed tSirMacRateSet; + +// access category record +typedef __ani_attr_pre_packed struct sSirMacAciAifsn +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 1; + tANI_U8 aci : 2; + tANI_U8 acm : 1; + tANI_U8 aifsn : 4; +#else + tANI_U8 aifsn : 4; + tANI_U8 acm : 1; + tANI_U8 aci : 2; + tANI_U8 rsvd : 1; +#endif +} __ani_attr_packed tSirMacAciAifsn; + +// contention window size +typedef __ani_attr_pre_packed struct sSirMacCW +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 max : 4; + tANI_U8 min : 4; +#else + tANI_U8 min : 4; + tANI_U8 max : 4; +#endif +} __ani_attr_packed tSirMacCW; + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamRecord +{ + tSirMacAciAifsn aci; + tSirMacCW cw; + tANI_U16 txoplimit; +} __ani_attr_packed tSirMacEdcaParamRecord; + +typedef __ani_attr_pre_packed struct sSirMacSSid +{ + tANI_U8 length; + tANI_U8 ssId[32]; +} __ani_attr_packed tSirMacSSid; + +// Concurrency role. These are generic IDs that identify the various roles +// in the software system. +typedef enum { + HAL_STA_MODE=0, + HAL_STA_SAP_MODE=1, // to support softAp mode . This is misleading. It means AP MODE only. + HAL_P2P_CLIENT_MODE, + HAL_P2P_GO_MODE, + HAL_MONITOR_MODE, +} tHalConMode; + +//This is a bit pattern to be set for each mode +//bit 0 - sta mode +//bit 1 - ap mode +//bit 2 - p2p client mode +//bit 3 - p2p go mode +typedef enum +{ + HAL_STA=1, + HAL_SAP=2, + HAL_STA_SAP=3, //to support sta, softAp mode . This means STA+AP mode + HAL_P2P_CLIENT=4, + HAL_P2P_GO=8, + HAL_MAX_CONCURRENCY_PERSONA=4 +} tHalConcurrencyMode; + +// IFACE PERSONA for different Operating modes +typedef enum +{ + HAL_IFACE_UNKNOWN, + HAL_IFACE_STA_MODE, + HAL_IFACE_P2P_MODE, + HAL_IFACE_MAX +} tHalIfacePersona; + +typedef PACKED_PRE struct PACKED_POST +{ + /* BSSID */ + tSirMacAddr bssId; + + /* Self Mac Address */ + tSirMacAddr selfMacAddr; + + /* BSS type */ + tSirBssType bssType; + + /*Operational Mode: AP =0, STA = 1*/ + tANI_U8 operMode; + + /*Network Type*/ + tSirNwType nwType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + tANI_U8 shortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + tANI_U8 llaCoexist; + + /*Co-exist with 11b STA*/ + tANI_U8 llbCoexist; + + /*Co-exist with 11g STA*/ + tANI_U8 llgCoexist; + + /*Coexistence with 11n STA*/ + tANI_U8 ht20Coexist; + + /*Non GF coexist flag*/ + tANI_U8 llnNonGFCoexist; + + /*TXOP protection support*/ + tANI_U8 fLsigTXOPProtectionFullSupport; + + /*RIFS mode*/ + tANI_U8 fRIFSMode; + + /*Beacon Interval in TU*/ + tSirMacBeaconInterval beaconInterval; + + /*DTIM period*/ + tANI_U8 dtimPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*Operating channel*/ + tANI_U8 currentOperChannel; + + /*Extension channel for channel bonding*/ + tANI_U8 currentExtChannel; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*HAL should update the existing BSS entry, if this flag is set. + UMAC will set this flag in case of reassoc, where we want to resue the + the old BSSID and still return success 0 = Add, 1 = Update*/ + tANI_U8 action; + + /* MAC Rate Set */ + tSirMacRateSet rateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + /*RMF enabled/disabled*/ + tANI_U8 rmfEnabled; + + /*HT Operating Mode operating mode of the 802.11n STA*/ + tSirMacHTOperatingMode htOperMode; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + tANI_U8 dualCTSProtection; + + /* Probe Response Max retries */ + tANI_U8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + tANI_U8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + tANI_U8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + tANI_U8 edcaParamsValid; + + /*EDCA Parameters for Best Effort Access Category*/ + tSirMacEdcaParamRecord acbe; + + /*EDCA Parameters forBackground Access Category*/ + tSirMacEdcaParamRecord acbk; + + /*EDCA Parameters for Video Access Category*/ + tSirMacEdcaParamRecord acvi; + + /*EDCA Parameters for Voice Access Category*/ + tSirMacEdcaParamRecord acvo; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT value same as tHalConMode */ + tANI_U8 halPersona; + + tANI_U8 bSpectrumMgtEnable; + + /*HAL fills in the tx power used for mgmt frames in txMgmtPower*/ + tANI_S8 txMgmtPower; + /*maxTxPower has max power to be used after applying the power constraint if any */ + tANI_S8 maxTxPower; + /*Context of the station being added in HW + Add a STA entry for "itself" - + On AP - Add the AP itself in an "STA context" + On STA - Add the AP to which this STA is joining in an "STA context" */ + tConfigStaParams staContext; +} tConfigBssParams, * tpConfigBssParams; + + +/*-------------------------------------------------------------------------- + * WLAN_HAL_CONFIG_BSS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* BSSID */ + tSirMacAddr bssId; + + /* Self Mac Address */ + tSirMacAddr selfMacAddr; + + /* BSS type */ + tSirBssType bssType; + + /*Operational Mode: AP =0, STA = 1*/ + tANI_U8 operMode; + + /*Network Type*/ + tSirNwType nwType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + tANI_U8 shortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + tANI_U8 llaCoexist; + + /*Co-exist with 11b STA*/ + tANI_U8 llbCoexist; + + /*Co-exist with 11g STA*/ + tANI_U8 llgCoexist; + + /*Coexistence with 11n STA*/ + tANI_U8 ht20Coexist; + + /*Non GF coexist flag*/ + tANI_U8 llnNonGFCoexist; + + /*TXOP protection support*/ + tANI_U8 fLsigTXOPProtectionFullSupport; + /*RIFS mode*/ + tANI_U8 fRIFSMode; + + /*Beacon Interval in TU*/ + tSirMacBeaconInterval beaconInterval; + + /*DTIM period*/ + tANI_U8 dtimPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*Operating channel*/ + tANI_U8 currentOperChannel; + + /*Extension channel for channel bonding*/ + tANI_U8 currentExtChannel; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*HAL should update the existing BSS entry, if this flag is set. + UMAC will set this flag in case of reassoc, where we want to resue the + the old BSSID and still return success 0 = Add, 1 = Update*/ + tANI_U8 action; + + /* MAC Rate Set */ + tSirMacRateSet rateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + /*RMF enabled/disabled*/ + tANI_U8 rmfEnabled; + + /*HT Operating Mode operating mode of the 802.11n STA*/ + tSirMacHTOperatingMode htOperMode; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + tANI_U8 dualCTSProtection; + + /* Probe Response Max retries */ + tANI_U8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + tANI_U8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + tANI_U8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + tANI_U8 edcaParamsValid; + + /*EDCA Parameters for Best Effort Access Category*/ + tSirMacEdcaParamRecord acbe; + + /*EDCA Parameters forBackground Access Category*/ + tSirMacEdcaParamRecord acbk; + + /*EDCA Parameters for Video Access Category*/ + tSirMacEdcaParamRecord acvi; + + /*EDCA Parameters for Voice Access Category*/ + tSirMacEdcaParamRecord acvo; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT value same as tHalConMode */ + tANI_U8 halPersona; + + tANI_U8 bSpectrumMgtEnable; + + /*HAL fills in the tx power used for mgmt frames in txMgmtPower*/ + tANI_S8 txMgmtPower; + /*maxTxPower has max power to be used after applying the power constraint if any */ + tANI_S8 maxTxPower; + /*Context of the station being added in HW + Add a STA entry for "itself" - + On AP - Add the AP itself in an "STA context" + On STA - Add the AP to which this STA is joining in an "STA context" */ + tConfigStaParams_V1 staContext; + + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; +} tConfigBssParams_V1, * tpConfigBssParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + PACKED_PRE union PACKED_POST { + tConfigBssParams configBssParams; + tConfigBssParams_V1 configBssParams_V1; + }uBssParams; +} tConfigBssReqMsg, *tpConfigBssReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_BSS_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* BSS index allocated by HAL */ + tANI_U8 bssIdx; + + /* DPU descriptor index for PTK */ + tANI_U8 dpuDescIndx; + + /* PTK DPU signature */ + tANI_U8 ucastDpuSignature; + + /* DPU descriptor index for GTK*/ + tANI_U8 bcastDpuDescIndx; + + /* GTK DPU signature */ + tANI_U8 bcastDpuSignature; + + /*DPU descriptor for IGTK*/ + tANI_U8 mgmtDpuDescIndx; + + /* IGTK DPU signature */ + tANI_U8 mgmtDpuSignature; + + /* Station Index for BSS entry*/ + tANI_U8 bssStaIdx; + + /* Self station index for this BSS */ + tANI_U8 bssSelfStaIdx; + + /* Bcast station for buffering bcast frames in AP role */ + tANI_U8 bssBcastStaIdx; + + /*MAC Address of STA(PEER/SELF) in staContext of configBSSReq*/ + tSirMacAddr staMac; + + /*HAL fills in the tx power used for mgmt frames in this field. */ + tANI_S8 txMgmtPower; + +} tConfigBssRspParams, * tpConfigBssRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigBssRspParams configBssRspParams; +} tConfigBssRspMsg, *tpConfigBssRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_BSS_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* BSS index to be deleted */ + tANI_U8 bssIdx; + +} tDeleteBssParams, *tpDeleteBssParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteBssParams deleteBssParams; +} tDeleteBssReqMsg, *tpDeleteBssReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_BSS_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* BSS index that has been deleted */ + tANI_U8 bssIdx; + +} tDeleteBssRspParams, *tpDeleteBssRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteBssRspParams deleteBssRspParams; +} tDeleteBssRspMsg, *tpDeleteBssRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_JOIN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the BSSID to which STA is going to associate*/ + tSirMacAddr bssId; + + /*Indicates the channel to switch to.*/ + tANI_U8 ucChannel; + + /* Self STA MAC */ + tSirMacAddr selfStaMacAddr; + + /*Local power constraint*/ + tANI_U8 ucLocalPowerConstraint; + + /*Secondary channel offset */ + ePhyChanBondState secondaryChannelOffset; + + /*link State*/ + tSirLinkState linkState; + + /* Max TX power */ + tANI_S8 maxTxPower; + +} tHalJoinReqParams, *tpHalJoinReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalJoinReqParams joinReqParams; +} tHalJoinReqMsg, *tpHalJoinReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_JOIN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* HAL fills in the tx power used for mgmt frames in this field */ + tPowerdBm txMgmtPower; + +}tHalJoinRspParams, *tpHalJoinRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalJoinRspParams joinRspParams; +}tHalJoinRspMsg, *tpHalJoinRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_POST_ASSOC_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tConfigStaParams configStaParams; + tConfigBssParams configBssParams; +} tPostAssocReqParams, *tpPostAssocReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPostAssocReqParams postAssocReqParams; +} tPostAssocReqMsg, *tpPostAssocReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_POST_ASSOC_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tConfigStaRspParams configStaRspParams; + tConfigBssRspParams configBssRspParams; +} tPostAssocRspParams, *tpPostAssocRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPostAssocRspParams postAssocRspParams; +} tPostAssocRspMsg, *tpPostAssocRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_BSSKEY_REQ +---------------------------------------------------------------------------*/ + +/* + * This is used by PE to create a set of WEP keys for a given BSS. + */ +typedef PACKED_PRE struct PACKED_POST +{ + /*BSS Index of the BSS*/ + tANI_U8 bssIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Number of keys*/ + tANI_U8 numKeys; + + /*Array of keys.*/ + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + tANI_U8 singleTidRc; +} tSetBssKeyParams, *tpSetBssKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetBssKeyParams setBssKeyParams; +} tSetBssKeyReqMsg, *tpSetBssKeyReqMsg; + +/* tagged version of set bss key */ +typedef PACKED_PRE struct PACKED_POST +{ + tSetBssKeyReqMsg Msg; + uint32 Tag; +} tSetBssKeyReqMsgTagged; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_BSSKEY_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tSetBssKeyRspParams, *tpSetBssKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetBssKeyRspParams setBssKeyRspParams; +} tSetBssKeyRspMsg, *tpSetBssKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_STAKEY_REQ, +---------------------------------------------------------------------------*/ + +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetStaKeyParams setStaKeyParams; +} tSetStaKeyReqMsg, *tpSetStaKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_STAKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tSetStaKeyRspParams, *tpSetStaKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetStaKeyRspParams setStaKeyRspParams; +} tSetStaKeyRspMsg, *tpSetStaKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_BSSKEY_REQ, +---------------------------------------------------------------------------*/ +/* + * This is used by PE to remove keys for a given BSS. + */ +typedef PACKED_PRE struct PACKED_POST + +{ + /*BSS Index of the BSS*/ + tANI_U8 bssIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Key Id*/ + tANI_U8 keyId; + + /*STATIC/DYNAMIC. Used in Nullifying in Key Descriptors for Static/Dynamic keys*/ + tAniWepType wepType; + +} tRemoveBssKeyParams, *tpRemoveBssKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveBssKeyParams removeBssKeyParams; +} tRemoveBssKeyReqMsg, *tpRemoveBssKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_BSSKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tRemoveBssKeyRspParams, *tpRemoveBssKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveBssKeyRspParams removeBssKeyRspParams; +} tRemoveBssKeyRspMsg, *tpRemoveBssKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_STAKEY_REQ, +---------------------------------------------------------------------------*/ +/* + * This is used by PE to Remove the key information on a given station. + */ +typedef PACKED_PRE struct PACKED_POST +{ + /*STA Index*/ + tANI_U16 staIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Key Id*/ + tANI_U8 keyId; + + /*Whether to invalidate the Broadcast key or Unicast key. In case of WEP, + the same key is used for both broadcast and unicast.*/ + tANI_BOOLEAN unicast; + +} tRemoveStaKeyParams, *tpRemoveStaKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveStaKeyParams removeStaKeyParams; +} tRemoveStaKeyReqMsg, *tpRemoveStaKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_STAKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tRemoveStaKeyRspParams, *tpRemoveStaKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveStaKeyRspParams removeStaKeyRspParams; +} tRemoveStaKeyRspMsg, *tpRemoveStaKeyRspMsg; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#ifdef QCA_WIFI_2_0 +#define OEM_DATA_REQ_SIZE 280 +#else +#define OEM_DATA_REQ_SIZE 134 +#endif +#endif + +#ifndef OEM_DATA_RSP_SIZE +#ifdef QCA_WIFI_2_0 +#define OEM_DATA_RSP_SIZE 1724 +#else +#define OEM_DATA_RSP_SIZE 1968 +#endif +#endif + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_REQ +--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tStartOemDataReqParams, *tpStartOemDataReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataReqParams startOemDataReqParams; +} tStartOemDataReqMsg, *tpStartOemDataReqMsg; + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_RSP +--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tStartOemDataRspParams, *tpStartOemDataRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataRspParams startOemDataRspParams; +} tStartOemDataRspMsg, *tpStartOemDataRspMsg; + +#endif + + + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Channel number */ + tANI_U8 channelNumber; + + /* Local power constraint */ + tANI_U8 localPowerConstraint; + + /*Secondary channel offset */ + ePhyChanBondState secondaryChannelOffset; + + //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm txMgmtPower; + + /* Max TX power */ + tPowerdBm maxTxPower; + + /* Self STA MAC */ + tSirMacAddr selfStaMacAddr; + + /*VO WIFI comment: BSSID needed to identify session. As the request has power constraints, + this should be applied only to that session*/ + /* Since MTU timing and EDCA are sessionized, this struct needs to be sessionized and + * bssid needs to be out of the VOWifi feature flag */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + tSirMacAddr bssId; + +}tSwitchChannelParams, *tpSwitchChannelParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelParams switchChannelParams; +} tSwitchChannelReqMsg, *tpSwitchChannelReqMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Status */ + tANI_U32 status; + + /* Channel number - same as in request*/ + tANI_U8 channelNumber; + + /* HAL fills in the tx power used for mgmt frames in this field */ + tPowerdBm txMgmtPower; + + /* BSSID needed to identify session - same as in request*/ + tSirMacAddr bssId; + +}tSwitchChannelRspParams, *tpSwitchChannelRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelRspParams switchChannelRspParams; +} tSwitchChannelRspMsg, *tpSwitchChannelRspMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_UPD_EDCA_PARAMS_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSS Index*/ + tANI_U16 bssIdx; + + /* Best Effort */ + tSirMacEdcaParamRecord acbe; + + /* Background */ + tSirMacEdcaParamRecord acbk; + + /* Video */ + tSirMacEdcaParamRecord acvi; + + /* Voice */ + tSirMacEdcaParamRecord acvo; + +} tEdcaParams, *tpEdcaParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEdcaParams edcaParams; +} tUpdateEdcaParamsReqMsg, *tpUpdateEdcaParamsReqMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_UPD_EDCA_PARAMS_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tEdcaRspParams, *tpEdcaRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEdcaRspParams edcaRspParams; +} tUpdateEdcaParamsRspMsg, *tpUpdateEdcaParamsRspMsg; + + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST + +{ + /* Index of STA to which the statistics */ + tANI_U16 staIdx; + + /* Encryption mode */ + tANI_U8 encMode; + + /* status */ + tANI_U32 status; + + /* Statistics */ + tANI_U32 sendBlocks; + tANI_U32 recvBlocks; + tANI_U32 replays; + tANI_U8 micErrorCnt; + tANI_U32 protExclCnt; + tANI_U16 formatErrCnt; + tANI_U16 unDecryptableCnt; + tANI_U32 decryptErrCnt; + tANI_U32 decryptOkCnt; +} tDpuStatsParams, * tpDpuStatsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Valid STA Idx for per STA stats request */ + tANI_U32 staId; + + /* Categories of stats requested as specified in eHalStatsMask*/ + tANI_U32 statsMask; +}tHalStatsReqParams, *tpHalStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsReqParams statsReqParams; +} tHalStatsReqMsg, *tpHalStatsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_STATS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 retry_cnt[4]; //Total number of packets(per AC) that were successfully transmitted with retries + tANI_U32 multiple_retry_cnt[4]; //The number of MSDU packets and MMPDU frames per AC that the 802.11 + // station successfully transmitted after more than one retransmission attempt + + tANI_U32 tx_frm_cnt[4]; //Total number of packets(per AC) that were successfully transmitted + //(with and without retries, including multi-cast, broadcast) + tANI_U32 rx_frm_cnt; //Total number of packets that were successfully received + //(after appropriate filter rules including multi-cast, broadcast) + tANI_U32 frm_dup_cnt; //Total number of duplicate frames received successfully + tANI_U32 fail_cnt[4]; //Total number packets(per AC) failed to transmit + tANI_U32 rts_fail_cnt; //Total number of RTS/CTS sequence failures for transmission of a packet + tANI_U32 ack_fail_cnt; //Total number packets failed transmit because of no ACK from the remote entity + tANI_U32 rts_succ_cnt; //Total number of RTS/CTS sequence success for transmission of a packet + tANI_U32 rx_discard_cnt; //The sum of the receive error count and dropped-receive-buffer error count. + //HAL will provide this as a sum of (FCS error) + (Fail get BD/PDU in HW) + tANI_U32 rx_error_cnt; //The receive error count. HAL will provide the RxP FCS error global counter. + tANI_U32 tx_byte_cnt; //The sum of the transmit-directed byte count, transmit-multicast byte count + //and transmit-broadcast byte count. HAL will sum TPE UC/MC/BCAST global counters + //to provide this. +}tAniSummaryStatsInfo, *tpAniSummaryStatsInfo; + + +// defines tx_rate_flags +typedef enum eTxRateInfo +{ + eHAL_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + eHAL_TX_RATE_HT20 = 0x2, /* HT20 rates */ + eHAL_TX_RATE_HT40 = 0x4, /* HT40 rates */ + eHAL_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + eHAL_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + eHAL_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + eHAL_TX_RATE_VHT40 = 0x40, /* VHT 20 rates */ + eHAL_TX_RATE_VHT80 = 0x80, /* VHT 20 rates */ + eHAL_TX_RATE_VIRT = 0x100, /* Virtual Rate */ + eHAL_TX_RATE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tTxrateinfoflags, tTxRateInfoFlags; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames + tANI_U32 promiscuous_rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames when a promiscuous packet filter was enabled + tANI_U32 rx_input_sensitivity; //The receiver input sensitivity referenced to a FER of 8% at an MPDU length + //of 1024 bytes at the antenna connector. Each element of the array shall correspond + //to a supported rate and the order shall be the same as the supporteRates parameter. + tANI_U32 max_pwr; //The maximum transmit power in dBm upto one decimal. + //for eg: if it is 10.5dBm, the value would be 105 + tANI_U32 sync_fail_cnt; //Number of times the receiver failed to synchronize with the incoming signal + //after detecting the sync in the preamble of the transmitted PLCP protocol data unit. + + tANI_U32 tx_rate; //Legacy transmit rate, in units of 500 kbit/sec, for the most + //recently transmitted frame + tANI_U32 mcs_index; //mcs index for HT20 and HT40 rates + tANI_U32 tx_rate_flags; //to differentiate between HT20 and + //HT40 rates; short and long guard interval +}tAniGlobalClassAStatsInfo, *tpAniGlobalClassAStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_wep_unencrypted_frm_cnt; //The number of unencrypted received MPDU frames that the MAC layer discarded when + //the IEEE 802.11 dot11ExcludeUnencrypted management information base (MIB) object + //is enabled + tANI_U32 rx_mic_fail_cnt; //The number of received MSDU packets that that the 802.11 station discarded + //because of MIC failures + tANI_U32 tkip_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a TKIP ICV error + tANI_U32 aes_ccmp_format_err; //The number of received MPDU frames that the 802.11 discarded because of an + //invalid AES-CCMP format + tANI_U32 aes_ccmp_replay_cnt; //The number of received MPDU frames that the 802.11 station discarded because of + //the AES-CCMP replay protection procedure + tANI_U32 aes_ccmp_decrpt_err; //The number of received MPDU frames that the 802.11 station discarded because of + //errors detected by the AES-CCMP decryption algorithm + tANI_U32 wep_undecryptable_cnt; //The number of encrypted MPDU frames received for which a WEP decryption key was + //not available on the 802.11 station + tANI_U32 wep_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a WEP ICV error + tANI_U32 rx_decrypt_succ_cnt; //The number of received encrypted packets that the 802.11 station successfully + //decrypted + tANI_U32 rx_decrypt_fail_cnt; //The number of encrypted packets that the 802.11 station failed to decrypt + +}tAniGlobalSecurityStats, *tpAniGlobalSecurityStats; + +typedef PACKED_PRE struct PACKED_POST +{ + tAniGlobalSecurityStats ucStats; + tAniGlobalSecurityStats mcbcStats; +}tAniGlobalClassBStatsInfo, *tpAniGlobalClassBStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_amsdu_cnt; //This counter shall be incremented for a received A-MSDU frame with the stations + //MAC address in the address 1 field or an A-MSDU frame with a group address in the + //address 1 field + tANI_U32 rx_ampdu_cnt; //This counter shall be incremented when the MAC receives an AMPDU from the PHY + tANI_U32 tx_20_frm_cnt; //This counter shall be incremented when a Frame is transmitted only on the + //primary channel + tANI_U32 rx_20_frm_cnt; //This counter shall be incremented when a Frame is received only on the primary channel + tANI_U32 rx_mpdu_in_ampdu_cnt; //This counter shall be incremented by the number of MPDUs received in the A-MPDU + //when an A-MPDU is received + tANI_U32 ampdu_delimiter_crc_err; //This counter shall be incremented when an MPDU delimiter has a CRC error when this + //is the first CRC error in the received AMPDU or when the previous delimiter has been + //decoded correctly +}tAniGlobalClassCStatsInfo, *tpAniGlobalClassCStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 tx_frag_cnt[4]; //The number of MPDU frames that the 802.11 station transmitted and acknowledged + //through a received 802.11 ACK frame + tANI_U32 tx_ampdu_cnt; //This counter shall be incremented when an A-MPDU is transmitted + tANI_U32 tx_mpdu_in_ampdu_cnt; //This counter shall increment by the number of MPDUs in the AMPDU when an A-MPDU + //is transmitted +}tAniPerStaStatsInfo, *tpAniPerStaStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* STA Idx */ + tANI_U32 staId; + + /* Categories of STATS being returned as per eHalStatsMask*/ + tANI_U32 statsMask; + + /* message type is same as the request type */ + tANI_U16 msgType; + + /* length of the entire request, includes the pStatsBuf length too */ + tANI_U16 msgLen; + +} tHalStatsRspParams, *tpHalStatsRspParams; + + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsRspParams statsRspParams; +} tHalStatsRspMsg, *tpHalStatsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_LINK_ST_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssid; + tSirLinkState state; + tSirMacAddr selfMacAddr; +} tLinkStateParams, *tpLinkStateParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tLinkStateParams linkStateParams; +} tSetLinkStateReqMsg, *tpSetLinkStateReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_LINK_ST_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tLinkStateRspParams, *tpLinkStateRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tLinkStateRspParams linkStateRspParams; +} tSetLinkStateRspMsg, *tpSetLinkStateRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_TS_REQ + *--------------------------------------------------------------------------*/ + +/* TSPEC Params */ +typedef __ani_attr_pre_packed struct sSirMacTSInfoTfc +{ + tANI_U16 trafficType : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 accessPolicy : 2; + tANI_U16 aggregation : 1; + tANI_U16 psb : 1; + tANI_U16 userPrio : 3; + tANI_U16 ackPolicy : 2; +} __ani_attr_packed tSirMacTSInfoTfc; + +/* Flag to schedule the traffic type */ +typedef __ani_attr_pre_packed struct sSirMacTSInfoSch +{ + tANI_U8 schedule : 1; + tANI_U8 rsvd : 7; +} __ani_attr_packed tSirMacTSInfoSch; + +/* Traffic and scheduling info */ +typedef __ani_attr_pre_packed struct sSirMacTSInfo +{ + tSirMacTSInfoTfc traffic; + tSirMacTSInfoSch schedule; +} __ani_attr_packed tSirMacTSInfo; + +/* Information elements */ +typedef __ani_attr_pre_packed struct sSirMacTspecIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacTSInfo tsinfo; + tANI_U16 nomMsduSz; + tANI_U16 maxMsduSz; + tANI_U32 minSvcInterval; + tANI_U32 maxSvcInterval; + tANI_U32 inactInterval; + tANI_U32 suspendInterval; + tANI_U32 svcStartTime; + tANI_U32 minDataRate; + tANI_U32 meanDataRate; + tANI_U32 peakDataRate; + tANI_U32 maxBurstSz; + tANI_U32 delayBound; + tANI_U32 minPhyRate; + tANI_U16 surplusBw; + tANI_U16 mediumTime; +}__ani_attr_packed tSirMacTspecIE; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS */ + tANI_U16 tspecIdx; + + /* To program TPE with required parameters */ + tSirMacTspecIE tspec; + + /* U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /* These parameters are for all the access categories */ + tANI_U32 srvInterval[WLAN_HAL_MAX_AC]; // Service Interval + tANI_U32 susInterval[WLAN_HAL_MAX_AC]; // Suspend Interval + tANI_U32 delayInterval[WLAN_HAL_MAX_AC]; // Delay Interval + +} tAddTsParams, *tpAddTsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddTsParams addTsParams; +} tAddTsReqMsg, *tpAddTsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_TS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tAddTsRspParams, *tpAddTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddTsRspParams addTsRspParams; +} tAddTsRspMsg, *tpAddTsRspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_TS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS */ + tANI_U16 tspecIdx; + + /* To lookup station id using the mac address */ + tSirMacAddr bssId; + +} tDelTsParams, *tpDelTsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelTsParams delTsParams; +} tDelTsReqMsg, *tpDelTsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_TS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tDelTsRspParams, *tpDelTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelTsRspParams delTsRspParams; +} tDelTsRspMsg, *tpDelTsRspMsg; + +/* End of TSpec Parameters */ + +/* Start of BLOCK ACK related Parameters */ + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_SESSION_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* Peer MAC Address */ + tSirMacAddr peerMacAddr; + + /* ADDBA Action Frame dialog token + HAL will not interpret this object */ + tANI_U8 baDialogToken; + + /* TID for which the BA is being setup + This identifies the TC or TS of interest */ + tANI_U8 baTID; + + /* 0 - Delayed BA (Not supported) + 1 - Immediate BA */ + tANI_U8 baPolicy; + + /* Indicates the number of buffers for this TID (baTID) + NOTE - This is the requested buffer size. When this + is processed by HAL and subsequently by HDD, it is + possible that HDD may change this buffer size. Any + change in the buffer size should be noted by PE and + advertized appropriately in the ADDBA response */ + tANI_U16 baBufferSize; + + /* BA timeout in TU's 0 means no timeout will occur */ + tANI_U16 baTimeout; + + /* b0..b3 - Fragment Number - Always set to 0 + b4..b15 - Starting Sequence Number of first MSDU + for which this BA is setup */ + tANI_U16 baSSN; + + /* ADDBA direction + 1 - Originator + 0 - Recipient */ + tANI_U8 baDirection; +} tAddBASessionParams, *tpAddBASessionParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBASessionParams addBASessionParams; +}tAddBASessionReqMsg, *tpAddBASessionReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_SESSION_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Dialog token */ + tANI_U8 baDialogToken; + + /* TID for which the BA session has been setup */ + tANI_U8 baTID; + + /* BA Buffer Size allocated for the current BA session */ + tANI_U8 baBufferSize; + + tANI_U8 baSessionID; + + /* Reordering Window buffer */ + tANI_U8 winSize; + + /*Station Index to id the sta */ + tANI_U8 STAID; + + /* Starting Sequence Number */ + tANI_U16 SSN; +} tAddBASessionRspParams, *tpAddBASessionRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBASessionRspParams addBASessionRspParams; +} tAddBASessionRspMsg, *tpAddBASessionRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Session Id */ + tANI_U8 baSessionID; + + /* Reorder Window Size */ + tANI_U8 winSize; + +#ifdef FEATURE_ON_CHIP_REORDERING + tANI_BOOLEAN isReorderingDoneOnChip; +#endif +} tAddBAParams, *tpAddBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBAParams addBAParams; +} tAddBAReqMsg, *tpAddBAReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Dialog token */ + tANI_U8 baDialogToken; + +} tAddBARspParams, *tpAddBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBARspParams addBARspParams; +} tAddBARspMsg, *tpAddBARspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TRIGGER_BA_REQ + *--------------------------------------------------------------------------*/ + + +typedef struct sAddBaInfo +{ + tANI_U16 fBaEnable : 1; + tANI_U16 startingSeqNum: 12; + tANI_U16 reserved : 3; +}tAddBaInfo, *tpAddBaInfo; + +typedef struct sTriggerBaRspCandidate +{ + tSirMacAddr staAddr; + tAddBaInfo baInfo[STACFG_MAX_TC]; +}tTriggerBaRspCandidate, *tpTriggerBaRspCandidate; + +typedef struct sTriggerBaCandidate +{ + tANI_U8 staIdx; + tANI_U8 tidBitmap; +}tTriggerBaReqCandidate, *tptTriggerBaReqCandidate; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Session Id */ + tANI_U8 baSessionID; + + /* baCandidateCnt is followed by trigger BA + * Candidate List(tTriggerBaCandidate) + */ + tANI_U16 baCandidateCnt; + +} tTriggerBAParams, *tpTriggerBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTriggerBAParams triggerBAParams; +} tTriggerBAReqMsg, *tpTriggerBAReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TRIGGER_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + + /* TO SUPPORT BT-AMP */ + tSirMacAddr bssId; + + /* success or failure */ + tANI_U32 status; + + /* baCandidateCnt is followed by trigger BA + * Rsp Candidate List(tTriggerRspBaCandidate) + */ + tANI_U16 baCandidateCnt; + + +} tTriggerBARspParams, *tpTriggerBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTriggerBARspParams triggerBARspParams; +} tTriggerBARspMsg, *tpTriggerBARspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_BA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TID for which the BA session is being deleted */ + tANI_U8 baTID; + + /* DELBA direction + 1 - Originator + 0 - Recipient */ + tANI_U8 baDirection; +} tDelBAParams, *tpDelBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelBAParams delBAParams; +} tDelBAReqMsg, *tpDelBAReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tDelBARspParams, *tpDelBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelBARspParams delBARspParams; +} tDelBARspMsg, *tpDelBARspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TSM_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Traffic Id */ + tANI_U8 tsmTID; + + tSirMacAddr bssId; +} tTsmStatsParams, *tpTsmStatsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTsmStatsParams tsmStatsParams; +} tTsmStatsReqMsg, *tpTsmStatsReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TSM_STATS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Uplink Packet Queue delay */ + tANI_U16 UplinkPktQueueDly; + + /* Uplink Packet Queue delay histogram */ + tANI_U16 UplinkPktQueueDlyHist[4]; + + /* Uplink Packet Transmit delay */ + tANI_U32 UplinkPktTxDly; + + /* Uplink Packet loss */ + tANI_U16 UplinkPktLoss; + + /* Uplink Packet count */ + tANI_U16 UplinkPktCount; + + /* Roaming count */ + tANI_U8 RoamingCount; + + /* Roaming Delay */ + tANI_U16 RoamingDly; +} tTsmStatsRspParams, *tpTsmStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTsmStatsRspParams tsmStatsRspParams; +} tTsmStatsRspMsg, *tpTsmStatsRspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_KEYDONE_MSG + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*bssid of the keys */ + tANI_U8 bssidx; + tANI_U8 encType; +} tSetKeyDoneParams, *tpSetKeyDoneParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetKeyDoneParams setKeyDoneParams; +} tSetKeyDoneMsg, *tpSetKeyDoneMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DOWNLOAD_NV_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Fragment sequence number of the NV Image. Note that NV Image might not + * fit into one message due to size limitation of the SMD channel FIFO. UMAC + * can hence choose to chop the NV blob into multiple fragments starting with + * seqeunce number 0, 1, 2 etc. The last fragment MUST be indicated by + * marking the isLastFragment field to 1. Note that all the NV blobs would be + * concatenated together by HAL without any padding bytes in between.*/ + tANI_U16 fragNumber; + + /* Is this the last fragment? When set to 1 it indicates that no more fragments + * will be sent by UMAC and HAL can concatenate all the NV blobs rcvd & proceed + * with the parsing. HAL would generate a WLAN_HAL_DOWNLOAD_NV_RSP to the + * WLAN_HAL_DOWNLOAD_NV_REQ after it receives each fragment */ + tANI_U16 isLastFragment; + + /* NV Image size (number of bytes) */ + tANI_U32 nvImgBufferSize; + + /* Following the 'nvImageBufferSize', there should be nvImageBufferSize + * bytes of NV Image i.e. uint8[nvImageBufferSize] */ +} tHalNvImgDownloadReqParams, *tpHalNvImgDownloadReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalNvImgDownloadReqMsg messages should be + * header.msgLen = sizeof(tHalNvImgDownloadReqMsg) + nvImgBufferSize */ + tHalMsgHeader header; + tHalNvImgDownloadReqParams nvImageReqParams; +} tHalNvImgDownloadReqMsg, *tpHalNvImgDownloadReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DOWNLOAD_NV_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure. HAL would generate a WLAN_HAL_DOWNLOAD_NV_RSP + * after each fragment */ + tANI_U32 status; +} tHalNvImgDownloadRspParams, *tpHalNvImgDownloadRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalNvImgDownloadRspParams nvImageRspParams; +} tHalNvImgDownloadRspMsg, *tpHalNvImgDownloadRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_STORE_NV_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* NV Item */ + eNvTable tableID; + + /* Size of NV Blob */ + tANI_U32 nvBlobSize; + + /* Following the 'nvBlobSize', there should be nvBlobSize bytes of + * NV blob i.e. uint8[nvBlobSize] */ +} tHalNvStoreParams, *tpHalNvStoreParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalNvStoreInd messages should be + * header.msgLen = sizeof(tHalNvStoreInd) + nvBlobSize */ + tHalMsgHeader header; + tHalNvStoreParams nvStoreParams; +} tHalNvStoreInd, *tpHalNvStoreInd; + +/* End of Block Ack Related Parameters */ + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MIC_FAILURE_IND + *--------------------------------------------------------------------------*/ + +#define SIR_CIPHER_SEQ_CTR_SIZE 6 + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr srcMacAddr; //address used to compute MIC + tSirMacAddr taMacAddr; //transmitter address + tSirMacAddr dstMacAddr; + tANI_U8 multicast; + tANI_U8 IV1; // first byte of IV + tANI_U8 keyId; // second byte of IV + tANI_U8 TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + tSirMacAddr rxMacAddr; // receive address +} tSirMicFailureInfo, *tpSirMicFailureInfo; + +/* Definition for MIC failure indication + MAC reports this each time a MIC failure occures on Rx TKIP packet + */ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssId; // BSSID + tSirMicFailureInfo info; +} tSirMicFailureInd, *tpSirMicFailureInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirMicFailureInd micFailureInd; +} tMicFailureIndMsg, *tpMicFailureIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 opMode; + tANI_U16 staId; +}tUpdateVHTOpMode, *tpUpdateVHTOpMode; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateVHTOpMode updateVhtOpMode; +} tUpdateVhtOpModeReqMsg, *tpUpdateVhtOpModeReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tUpdateVhtOpModeParamsRsp, *tpUpdateVhtOpModeParamsRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateVhtOpModeParamsRsp updateVhtOpModeRspParam; +} tUpdateVhtOpModeParamsRspMsg, *tpUpdateVhtOpModeParamsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_BEACON_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + + tANI_U8 bssIdx; + + //shortPreamble mode. HAL should update all the STA rates when it + //receives this message + tANI_U8 fShortPreamble; + //short Slot time. + tANI_U8 fShortSlotTime; + //Beacon Interval + tANI_U16 beaconInterval; + //Protection related + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20MhzCoexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + tANI_U16 paramChangeBitmap; +}tUpdateBeaconParams, *tpUpdateBeaconParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateBeaconParams updateBeaconParam; +} tUpdateBeaconReqMsg, *tpUpdateBeaconReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_BEACON_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tUpdateBeaconRspParams, *tpUpdateBeaconRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateBeaconRspParams updateBeaconRspParam; +} tUpdateBeaconRspMsg, *tpUpdateBeaconRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SEND_BEACON_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 beaconLength; //length of the template. + tANI_U8 beacon[BEACON_TEMPLATE_SIZE]; // Beacon data. + tSirMacAddr bssId; + tANI_U32 timIeOffset; //TIM IE offset from the beginning of the template. + tANI_U16 p2pIeOffset; //P2P IE offset from the begining of the template +}tSendBeaconParams, *tpSendBeaconParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendBeaconParams sendBeaconParam; +}tSendBeaconReqMsg, *tpSendBeaconReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SEND_BEACON_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tSendBeaconRspParams, *tpSendBeaconRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendBeaconRspParams sendBeaconRspParam; +} tSendBeaconRspMsg, *tpSendBeaconRspMsg; + +#ifdef FEATURE_5GHZ_BAND + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENABLE_RADAR_DETECT_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr BSSID; + tANI_U8 channel; +}tSirEnableRadarInfoType, *tptSirEnableRadarInfoType; + + +typedef PACKED_PRE struct PACKED_POST +{ + /* Link Parameters */ + tSirEnableRadarInfoType EnableRadarInfo; +}tEnableRadarReqParams, *tpEnableRadarReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEnableRadarReqParams enableRadarReqParams; +}tEnableRadarReqMsg, *tpEnableRadarReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENABLE_RADAR_DETECT_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Link Parameters */ + tSirMacAddr BSSID; + /* success or failure */ + tANI_U32 status; +}tEnableRadarRspParams, *tpEnableRadarRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEnableRadarRspParams enableRadarRspParams; +}tEnableRadarRspMsg, *tpEnableRadarRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_RADAR_DETECT_INTR_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 radarDetChannel; +}tRadarDetectIntrIndParams, *tpRadarDetectIntrIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRadarDetectIntrIndParams radarDetectIntrIndParams; +}tRadarDetectIntrIndMsg, *tptRadarDetectIntrIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_RADAR_DETECT_IND + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*channel number in which the RADAR detected*/ + tANI_U8 channelNumber; + + /*RADAR pulse width*/ + tANI_U16 radarPulseWidth; // in usecond + + /*Number of RADAR pulses */ + tANI_U16 numRadarPulse; +}tRadarDetectIndParams,*tpRadarDetectIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRadarDetectIndParams radarDetectIndParams; +}tRadarDetectIndMsg, *tptRadarDetectIndMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_GET_TPC_REPORT_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr sta; + tANI_U8 dialogToken; + tANI_U8 txpower; +}tSirGetTpcReportReqParams, *tpSirGetTpcReportReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirGetTpcReportReqParams getTpcReportReqParams; +}tSirGetTpcReportReqMsg, *tpSirGetTpcReportReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_TPC_REPORT_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSirGetTpcReportRspParams, *tpSirGetTpcReportRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirGetTpcReportRspParams getTpcReportRspParams; +}tSirGetTpcReportRspMsg, *tpSirGetTpcReportRspMsg; + +#endif + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 pProbeRespTemplate[BEACON_TEMPLATE_SIZE]; + tANI_U32 probeRespTemplateLen; + tANI_U32 ucProxyProbeReqValidIEBmap[8]; + tSirMacAddr bssId; + +}tSendProbeRespReqParams, *tpSendProbeRespReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendProbeRespReqParams sendProbeRespReqParams ; +}tSendProbeRespReqMsg, *tpSendProbeRespReqMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSendProbeRespRspParams, *tpSendProbeRespRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendProbeRespRspParams sendProbeRespRspParams; +}tSendProbeRespRspMsg, *tpSendProbeRespRspMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSendUnkownFrameRxIndParams, *tpSendUnkownFrameRxIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendUnkownFrameRxIndParams sendUnkownFrameRxIndParams; +}tSendUnkownFrameRxIndMsg, *tpSendUnkownFrameRxIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_DELETE_STA_CONTEXT_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 assocId; + tANI_U16 staId; + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies bssid from the sta table. + tSirMacAddr addr2; // + tANI_U16 reasonCode; // To unify the keepalive / unknown A2 / tim-based disa + +}tDeleteStaContextParams, *tpDeleteStaContextParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaContextParams deleteStaContextParams; +}tDeleteStaContextIndMsg, *tpDeleteStaContextIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 assocId; + tANI_U8 staIdx; + tANI_U8 bssIdx; + tANI_U8 uReasonCode; + tANI_U32 uStatus; +} tIndicateDelSta, *tpIndicateDelSta; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tBtAmpEventType btAmpEventType; + +}tBtAmpEventParams, *tpBtAmpEventParams; + + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBtAmpEventParams btAmpEventParams; +}tBtAmpEventMsg, *tpBtAmpEventMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tBtAmpEventRspParams, *tpBtAmpEventRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBtAmpEventRspParams btAmpEventRspParams; +}tBtAmpEventRsp, *tpBtAmpEventRsp; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_TL_HAL_FLUSH_AC_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + +}tTlHalFlushAcParams, *tpTlHalFlushAcParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTlHalFlushAcParams tlHalFlushAcParam; +}tTlHalFlushAcReq, *tpTlHalFlushAcReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_TL_HAL_FLUSH_AC_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + + /* success or failure */ + tANI_U32 status; +}tTlHalFlushAcRspParams, *tpTlHalFlushAcRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTlHalFlushAcRspParams tlHalFlushAcRspParam; +}tTlHalFlushAcRspMsg, *tpTlHalFlushAcRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_IMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalEnterImpsReqMsg, *tpHalEnterImpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_IMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalExitImpsReqMsg, *tpHalExitImpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_BMPS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; + //TBTT value derived from the last beacon +#ifndef BUILD_QWPTTSTATIC + tANI_U64 tbtt; +#endif + tANI_U8 dtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + tANI_U8 dtimPeriod; + + // For ESE and 11R Roaming + tANI_U32 rssiFilterPeriod; + tANI_U32 numBeaconPerRssiAverage; + tANI_U8 bRssiFilterEnable; + +} tHalEnterBmpsReqParams, *tpHalEnterBmpsReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterBmpsReqParams enterBmpsReq; +} tHalEnterBmpsReqMsg, *tpHalEnterBmpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_BMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 sendDataNull; + tANI_U8 bssIdx; +} tHalExitBmpsReqParams, *tpHalExitBmpsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitBmpsReqParams exitBmpsReqParams; +} tHalExitBmpsReqMsg, *tpHalExitBmpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MISSED_BEACON_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; +} tHalMissedBeaconIndParams, *tpHalMissedBeaconIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMissedBeaconIndParams missedBeaconIndParams; +} tHalMissedBeaconIndMsg, *tpHalMissedBeaconIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BCN_FILTER_REQ + *--------------------------------------------------------------------------*/ +/* Beacon Filtering data structures */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 offset; + tANI_U8 value; + tANI_U8 bitMask; + tANI_U8 ref; +} tEidByteInfo, *tpEidByteInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 capabilityInfo; + tANI_U16 capabilityMask; + tANI_U16 beaconInterval; + tANI_U16 ieNum; + tANI_U8 bssIdx; + tANI_U8 reserved; +} tBeaconFilterMsg, *tpBeaconFilterMsg; + +/* The above structure would be followed by multiple of below mentioned structure */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 elementId; + tANI_U8 checkIePresence; + tEidByteInfo byte; +} tBeaconFilterIe, *tpBeaconFilterIe; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBeaconFilterMsg addBcnFilterParams; +} tHalAddBcnFilterReqMsg, *tpHalAddBcnFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_REM_BCN_FILTER_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucIeCount; + tANI_U8 ucRemIeId[1]; +} tRemBeaconFilterMsg, *tpRemBeaconFilterMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemBeaconFilterMsg remBcnFilterParams; +} tHalRemBcnFilterReqMsg, *tpHalRemBcnFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +#define HAL_IPV4_ARP_REPLY_OFFLOAD 0 +#define HAL_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 +#define HAL_IPV6_NS_OFFLOAD 2 +#define HAL_IPV6_ADDR_LEN 16 +#define HAL_MAC_ADDR_LEN 6 +#define HAL_OFFLOAD_DISABLE 0 +#define HAL_OFFLOAD_ENABLE 1 +#define HAL_OFFLOAD_BCAST_FILTER_ENABLE 0x2 +#define HAL_OFFLOAD_MCAST_FILTER_ENABLE 0x4 +#define HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE (HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_BCAST_FILTER_ENABLE) +#define HAL_OFFLOAD_IPV6NS_AND_MCAST_FILTER_ENABLE (HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_MCAST_FILTER_ENABLE) + +typedef PACKED_PRE struct PACKED_POST _tHalNSOffloadParams +{ + tANI_U8 srcIPv6Addr[HAL_IPV6_ADDR_LEN]; + tANI_U8 selfIPv6Addr[HAL_IPV6_ADDR_LEN]; + //Only support 2 possible Network Advertisement IPv6 address + tANI_U8 targetIPv6Addr1[HAL_IPV6_ADDR_LEN]; + tANI_U8 targetIPv6Addr2[HAL_IPV6_ADDR_LEN]; + tANI_U8 selfMacAddr[HAL_MAC_ADDR_LEN]; + tANI_U8 srcIPv6AddrValid : 1; + tANI_U8 targetIPv6Addr1Valid : 1; + tANI_U8 targetIPv6Addr2Valid : 1; + tANI_U8 reserved1 : 5; + tANI_U8 reserved2; //make it DWORD aligned + tANI_U8 bssIdx; + tANI_U32 slotIndex; // slot index for this offload +} tHalNSOffloadParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 offloadType; + tANI_U8 enableOrDisable; + PACKED_PRE union PACKED_POST + { + tANI_U8 hostIpv4Addr [4]; + tANI_U8 hostIpv6Addr [HAL_IPV6_ADDR_LEN]; + } params; +} tHalHostOffloadReq, *tpHalHostOffloadReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostOffloadReq hostOffloadParams; + tHalNSOffloadParams nsOffloadParams; +} tHalHostOffloadReqMsg, *tpHalHostOffloadReqMsg; + + +#ifdef FEATURE_WLAN_LPHB +typedef enum +{ + WIFI_HB_SET_ENABLE = 0x0001, + WIFI_HB_SET_TCP_PARAMS = 0x0002, + WIFI_HB_SET_TCP_PKT_FILTER = 0x0003, + WIFI_HB_SET_UDP_PARAMS = 0x0004, + WIFI_HB_SET_UDP_PKT_FILTER = 0x0005, + WIFI_HB_SET_NETWORK_INFO = 0x0006, +}tLowPowerHeartBeatCmdType ; + +#define MAX_FLITER_SIZE 64 +/*--------------------------------------------------------------------------- + *FEATURE_WLAN_LPHB REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + uint32 hostIpv4Addr; + uint32 destIpv4Addr; + uint16 hostPort; + uint16 destPort; + uint16 timeOutSec; // in seconds + tSirMacAddr gatewayMacAddr; + uint16 timePeriodSec; // in seconds + uint32 tcpSn; +} tlowPowerHeartBeatParamsTcpStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 hostIpv4Addr; + uint32 destIpv4Addr; + uint16 hostPort; + uint16 destPort; + uint16 timePeriodSec;// in seconds + uint16 timeOutSec; // in seconds + tSirMacAddr gatewayMacAddr; +} tlowPowerHeartBeatParamsUdpStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 offset; + uint32 filterLength; + uint8 filter[MAX_FLITER_SIZE]; +} tlowPowerHeartBeatFilterStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 heartBeatEnable; + uint8 heartBeatType; //TCP or UDP +} tlowPowerHeartBeatEnableStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 dummy; +} tlowPowerHeartBeatNetworkInfoStruct; + + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 sessionIdx; + uint16 lowPowerHeartBeatCmdType; + PACKED_PRE union PACKED_PRO + { + tlowPowerHeartBeatEnableStruct control; + tlowPowerHeartBeatFilterStruct tcpUdpFilter; + tlowPowerHeartBeatParamsTcpStruct tcpParams; + tlowPowerHeartBeatParamsUdpStruct udpParams; + tlowPowerHeartBeatNetworkInfoStruct info; + }options; +} tHalLowPowerHeartBeatReq, *tpHalLowPowerHeartBeatReq; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatReq lowPowerHeartBeatParams; +} tHalLowPowerHeartBeatReqMsg, *tpHalLowPowerHeartBeatReqMsg; + +/*--------------------------------------------------------------------------- + * FEATURE_WLAN_LPHB RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + uint8 sessionIdx; + uint32 status; + uint16 lowPowerHeartBeatCmdType; +}tHalLowPowerHeartBeatRspParams, *tpHalLowPowerHeartBeatRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatRspParams lowPowerHeartBeatRspParams; +}tHalLowPowerHeartBeatRspMsg, *tpHalLowPowerHeartBeatRspMsg; + + +/*--------------------------------------------------------------------------- + * FEATURE_WLAN_LPHB IND + *--------------------------------------------------------------------------*/ +#define WIFI_HB_EVENT_TCP_RX_TIMEOUT 0x0001 +#define WIFI_HB_EVENT_UDP_RX_TIMEOUT 0x0002 + +#define WIFI_LPHB_EVENT_REASON_TIMEOUT 0x01 +#define WIFI_LPHB_EVENT_REASON_FW_ON_MONITOR 0x02 +#define WIFI_LPHB_EVENT_REASON_FW_OFF_MONITOR 0x03 + + +#define WIFI_LPHB_PROTO_UDP 0x01 +#define WIFI_LPHB_PROTO_TCP 0x02 + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 bssIdx; + uint8 sessionIdx; + uint8 protocolType; /*TCP or UDP*/ + uint8 eventReason; + +}tHalLowPowerHeartBeatIndParam,*tpHalLowPowerHeartBeatIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatIndParam lowPowerHeartBeatIndParams; +}tHalLowPowerHeartBeatIndMsg, *tpHalLowPowerHeartBeatIndMsg; + +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_SET_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Scan Frerquency - default to 30Sec*/ + tANI_U32 scanInterval; + tANI_U32 numScan2Batch; + tANI_U32 bestNetworks; + tANI_U8 rfBand; + tANI_U8 rtt; +} tHalBatchScanSetParams, *tpHalBatchScanSetParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanSetParams batchScanParams; +} tHalBatchScanSetReqMsg, *tpHalBatchScanSetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_SET_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 supportedMscan; +} tHalBatchScanSetRspParam, *tpHalBatchScanSetRspParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanSetRspParam setBatchScanRspParam; +} tHalBatchScanSetRspMsg, *tpHalBatchScanSetRspMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_BATCHSCAN_STOP_IND +*--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 param; +} tHalBatchScanStopIndParam, *tpHalBatchScanStopIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanStopIndParam param; +} tHalBatchScanStopIndMsg, *tpHalBatchScanStopIndMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND +*--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 param; +} tHalBatchScanTriggerResultParam, *tpHalBatchScanTriggerResultParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanTriggerResultParam param; +} tHalBatchScanTriggerResultIndMsg, *tpHalBatchScanTriggerResultIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_GET_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssid[6]; /* BSSID */ + tANI_U8 ssid[32]; /* SSID */ + tANI_U8 ch; /* Channel */ + tANI_U8 rssi; /* RSSI or Level */ + /* Timestamp when Network was found. Used to calculate age based on timestamp in GET_RSP msg header */ + tANI_U32 timestamp; +} tHalBatchScanNetworkInfo, *tpHalBatchScanNetworkInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 scanId; /* Scan List ID. */ + /* No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg */ + tANI_U32 numNetworksInScanList; + /* Variable data ptr: Number of AP in Scan List */ + /* following numNetworkInScanList is data of type tHalBatchScanNetworkInfo + * of sizeof(tHalBatchScanNetworkInfo) * numNetworkInScanList */ + tANI_U8 scanList[1]; +} tHalBatchScanList, *tpHalBatchScanList; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 timestamp; + tANI_U32 numScanLists; + boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + /* following isLastResult is data of type tHalBatchScanList + * of sizeof(tHalBatchScanList) * numScanLists*/ + tANI_U8 scanResults[1]; +} tHalBatchScanResultIndParam, *tpHalBatchScanResultIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanResultIndParam resultIndMsgParam; +} tHalBatchScanResultIndMsg, *tpHalBatchScanResultIndMsg; + +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_KEEP_ALIVE_REQ + *--------------------------------------------------------------------------*/ +/* Packet Types. */ +#define HAL_KEEP_ALIVE_NULL_PKT 1 +#define HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 + +/* Enable or disable keep alive */ +#define HAL_KEEP_ALIVE_DISABLE 0 +#define HAL_KEEP_ALIVE_ENABLE 1 + +/* Keep Alive request. */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 packetType; + tANI_U32 timePeriod; + tHalIpv4Addr hostIpv4Addr; + tHalIpv4Addr destIpv4Addr; + tSirMacAddr destMacAddr; + tANI_U8 bssIdx; +} tHalKeepAliveReq, *tpHalKeepAliveReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalKeepAliveReq KeepAliveParams; +} tHalKeepAliveReqMsg, *tpHalKeepAliveReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_RSSI_THRESH_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_S8 ucRssiThreshold1 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold3 : 8; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bReserved10 : 2; +} tHalRSSIThresholds, *tpHalRSSIThresholds; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRSSIThresholds rssiThreshParams; +} tHalRSSIThresholdReqMsg, *tpHalRSSIThresholdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_UAPSD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bkDeliveryEnabled:1; + tANI_U8 beDeliveryEnabled:1; + tANI_U8 viDeliveryEnabled:1; + tANI_U8 voDeliveryEnabled:1; + tANI_U8 bkTriggerEnabled:1; + tANI_U8 beTriggerEnabled:1; + tANI_U8 viTriggerEnabled:1; + tANI_U8 voTriggerEnabled:1; + tANI_U8 bssIdx; +} tUapsdReqParams, *tpUapsdReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdReqParams enterUapsdParams; +} tHalEnterUapsdReqMsg, *tpHalEnterUapsdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_UAPSD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 bssIdx; +} tHalExitUapsdReqMsg, *tpHalExitUapsdReqMsg; + +#define HAL_PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define HAL_MAXNUM_PERIODIC_TX_PTRNS 6 +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 selfStaIdx:8; + tANI_U32 ucPtrnId:8; // Pattern ID + tANI_U32 usPtrnSize:16; // Non-Zero Pattern size + tANI_U32 uPtrnIntervalMs; // In msec + tANI_U8 ucPattern[HAL_PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} tHalAddPeriodicTxPtrn, *tpHalAddPeriodicTxPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddPeriodicTxPtrn ptrnParams; +} tHalAddPeriodicTxPtrnIndMsg, *tpHalAddPeriodicTxPtrnIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 selfStaIdx:8; + tANI_U32 rsvd:24; + /* Bitmap of pattern IDs that needs to be deleted */ + tANI_U32 uPatternIdBitmap; +} tHalDelPeriodicTxPtrn, *tpHalDelPeriodicTxPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDelPeriodicTxPtrn ptrnParams; +} tHalDelPeriodicTxPtrnIndMsg, *tpHalDelPeriodicTxPtrnIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_PERIODIC_TX_PTRN_FW_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Type of Failure indication */ + tANI_U32 bssIdx:8; + tANI_U32 selfStaIdx:8; + tANI_U32 rsvd:16; + tANI_U32 status; + tANI_U32 patternIdBitmap; +} tHalPeriodicTxPtrnFwInd, *tpHalPeriodicTxPtrnFwInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalPeriodicTxPtrnFwInd fwIndParams; +} tHalPeriodicTxPtrnFwIndMsg, *tpHalPeriodicTxPtrnFwIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_WOWL_BCAST_PTRN + *--------------------------------------------------------------------------*/ +#define HAL_WOWL_BCAST_PATTERN_MAX_SIZE 128 +#define HAL_WOWL_BCAST_MAX_NUM_PATTERNS 16 + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + tANI_U8 ucPatternByteOffset; + tANI_U8 ucPatternSize; // Non-Zero Pattern size + tANI_U8 ucPattern[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + tANI_U8 ucPatternMaskSize; // Non-zero pattern mask size + tANI_U8 ucPatternMask[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + tANI_U8 ucPatternExt[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern + tANI_U8 ucPatternMaskExt[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern mask + tANI_U8 bssIdx; +} tHalWowlAddBcastPtrn, *tpHalWowlAddBcastPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlAddBcastPtrn ptrnParams; +} tHalWowlAddBcastPtrnReqMsg, *tpHalWowlAddBcastPtrnReqMsg; + + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_WOWL_BCAST_PTRN + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Pattern ID of the wakeup pattern to be deleted */ + tANI_U8 ucPatternId; + tANI_U8 bssIdx; +} tHalWowlDelBcastPtrn, *tpHalWowlDelBcastPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlDelBcastPtrn ptrnParams; +} tHalWowlDelBcastPtrnReqMsg, *tpHalWowlDelBcastPtrnReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_WOWL_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + tANI_U8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + tANI_U8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + tANI_U8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + tANI_U8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + tANI_U8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + tANI_U8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + tANI_U8 ucWowMaxSleepUsec; + + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; + + tANI_U8 bssIdx; + +} tHalWowlEnterParams, *tpHalWowlEnterParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlEnterParams enterWowlParams; +} tHalWowlEnterReqMsg, *tpHalWowlEnterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_WOWL_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; + +} tHalWowlExitParams, *tpHalWowlExitParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlExitParams exitWowlParams; +} tHalWowlExitReqMsg, *tpHalWowlExitReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_RSSI_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalGetRssiReqMsg, *tpHalGetRssiReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Valid STA Idx for per STA stats request */ + tANI_U32 staId; + +}tHalRoamRssiReqParams, *tpHalRoamRssiReqParams; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_ROAM_RSSI_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRoamRssiReqParams roamRssiReqParams; +} tHalGetRoamRssiReqMsg, *tpHalGetRoamRssiReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 staidx; // STA index + tANI_U8 ac; // Access Category + tANI_U8 up; // User Priority + tANI_U32 srvInterval; // Service Interval + tANI_U32 susInterval; // Suspend Interval + tANI_U32 delayInterval; // Delay Interval +} tUapsdInfo, tpUapsdInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdInfo enableUapsdAcParams; +} tHalSetUapsdAcParamsReqMsg, *tpHalSetUapsdAcParamsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_RXP_FILTER_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 setMcstBcstFilterSetting; + tANI_U8 setMcstBcstFilter; +} tHalConfigureRxpFilterReqParams, tpHalConfigureRxpFilterReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureRxpFilterReqParams configureRxpFilterReqParams; +} tHalConfigureRxpFilterReqMsg, *tpHalConfigureRxpFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_IMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalEnterImpsRspParams, *tpHalEnterImpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterImpsRspParams enterImpsRspParams; +} tHalEnterImpsRspMsg, *tpHalEnterImpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_IMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalExitImpsRspParams, *tpHalExitImpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitImpsRspParams exitImpsRspParams; +} tHalExitImpsRspMsg, *tpHalExitImpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_BMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalEnterBmpsRspParams, *tpHalEnterBmpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterBmpsRspParams enterBmpsRspParams; +} tHalEnterBmpsRspMsg, *tpHalEnterBmpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_BMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitBmpsRspParams, *tpHalExitBmpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitBmpsRspParams exitBmpsRspParams; +} tHalExitBmpsRspMsg, *tpHalExitBmpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_UAPSD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +}tUapsdRspParams, *tpUapsdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdRspParams enterUapsdRspParams; +} tHalEnterUapsdRspMsg, *tpHalEnterUapsdRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_UAPSD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitUapsdRspParams, *tpHalExitUapsdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitUapsdRspParams exitUapsdRspParams; +} tHalExitUapsdRspMsg, *tpHalExitUapsdRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_RSSI_NOTIFICATION_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 bRssiThres1PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres3NegCross : 1; + tANI_U32 avgRssi : 8; + tANI_U32 uBssIdx : 8; + tANI_U32 isBTCoexCompromise : 1; + tANI_U32 bReserved : 9; +} tHalRSSINotification, *tpHalRSSINotification; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRSSINotification rssiNotificationParams; +} tHalRSSINotificationIndMsg, *tpHalRSSINotificationIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_RSSI_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_S8 rssi; +} tHalGetRssiParams, *tpHalGetRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalGetRssiParams rssiRspParams; +} tHalGetRssiRspMsg, *tpHalGetRssiRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_ROAM_RSSI_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + tANI_U8 staId; + tANI_S8 rssi; +} tHalGetRoamRssiParams, *tpHalGetRoamRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalGetRoamRssiParams roamRssiRspParams; +} tHalGetRoamRssiRspMsg, *tpHalGetRoamRssiRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_WOWL_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalEnterWowlRspParams, *tpHalEnterWowlRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterWowlRspParams enterWowlRspParams; +} tHalWowlEnterRspMsg, *tpHalWowlEnterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_WOWL_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitWowlRspParams, *tpHalExitWowlRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitWowlRspParams exitWowlRspParams; +} tHalWowlExitRspMsg, *tpHalWowlExitRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BCN_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalAddBcnFilterRspParams, *tpHalAddBcnFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddBcnFilterRspParams addBcnFilterRspParams; +} tHalAddBcnFilterRspMsg, *tpHalAddBcnFilterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_REM_BCN_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalRemBcnFilterRspParams, *tpHalRemBcnFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRemBcnFilterRspParams remBcnFilterRspParams; +} tHalRemBcnFilterRspMsg, *tpHalRemBcnFilterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalAddWowlBcastPtrnRspParams, *tpHalAddWowlBcastPtrnRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddWowlBcastPtrnRspParams addWowlBcastPtrnRspParams; +} tHalAddWowlBcastPtrnRspMsg, *tpHalAddWowlBcastPtrnRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalDelWowlBcastPtrnRspParams, *tpHalDelWowlBcastPtrnRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDelWowlBcastPtrnRspParams delWowlBcastRspParams; +} tHalDelWowlBcastPtrnRspMsg, *tpHalDelWowlBcastPtrnRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalHostOffloadRspParams, *tpHalHostOffloadRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostOffloadRspParams hostOffloadRspParams; +} tHalHostOffloadRspMsg, *tpHalHostOffloadRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_KEEP_ALIVE_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalKeepAliveRspParams, *tpHalKeepAliveRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalKeepAliveRspParams keepAliveRspParams; +} tHalKeepAliveRspMsg, *tpHalKeepAliveRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_RSSI_THRESH_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalSetRssiThreshRspParams, *tpHalSetRssiThreshRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetRssiThreshRspParams setRssiThreshRspParams; +} tHalSetRssiThreshRspMsg, *tpHalSetRssiThreshRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalSetUapsdAcParamsRspParams, *tpHalSetUapsdAcParamsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetUapsdAcParamsRspParams setUapsdAcParamsRspParams; +} tHalSetUapsdAcParamsRspMsg, *tpHalSetUapsdAcParamsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_RXP_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalConfigureRxpFilterRspParams, *tpHalConfigureRxpFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureRxpFilterRspParams configureRxpFilterRspParams; +} tHalConfigureRxpFilterRspMsg, *tpHalConfigureRxpFilterRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_MAX_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssId; // BSSID is needed to identify which session issued this request. As + //the request has power constraints, this should be applied only to that session + tSirMacAddr selfStaMacAddr; + //In request, + //power == MaxTx power to be used. + tPowerdBm power; + +}tSetMaxTxPwrParams, *tpSetMaxTxPwrParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrParams setMaxTxPwrParams; +}tSetMaxTxPwrReq, *tpSetMaxTxPwrReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_MAX_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + //power == tx power used for management frames. + tPowerdBm power; + + /* success or failure */ + tANI_U32 status; +}tSetMaxTxPwrRspParams, *tpSetMaxTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrRspParams setMaxTxPwrRspParams; +}tSetMaxTxPwrRspMsg, *tpSetMaxTxPwrRspMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ + *--------------------------------------------------------------------------*/ + +/* Band types for WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ between WDI and HAL */ +typedef enum +{ + WLAN_HAL_SET_MAX_TX_POWER_BAND_ALL = 0, + // For 2.4GHz or 5GHz bands + WLAN_HAL_SET_MAX_TX_POWER_BAND_2_4_GHZ, + WLAN_HAL_SET_MAX_TX_POWER_BAND_5_0_GHZ, + // End of valid enums + WLAN_HAL_SET_MAX_TX_POWER_BAND_MAX = WLAN_HAL_MAX_ENUM_SIZE, +}tHalSetMaxTxPwrBandInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalSetMaxTxPwrBandInfo bandInfo; // 2_4_GHZ or 5_0_GHZ + tPowerdBm power; // In request, power == MaxTx power to be used. +}tSetMaxTxPwrPerBandParams, *tpSetMaxTxPwrPerBandParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrPerBandParams setMaxTxPwrPerBandParams; +}tSetMaxTxPwrPerBandReq, *tpSetMaxTxPwrPerBandReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + //power == tx power used for management frames. + tPowerdBm power; + + /* success or failure */ + tANI_U32 status; +}tSetMaxTxPwrPerBandRspParams, *tpSetMaxTxPwrPerBandRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrPerBandRspParams setMaxTxPwrPerBandRspParams; +}tSetMaxTxPwrPerBandRspMsg, *tpSetMaxTxPwrPerBandRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* TX Power in milli watts */ + tANI_U32 txPower; + tANI_U8 bssIdx; +}tSetTxPwrReqParams, *tpSetTxPwrReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetTxPwrReqParams setTxPwrReqParams; +}tSetTxPwrReqMsg, *tpSetTxPwrReqMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSetTxPwrRspParams, *tpSetTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetTxPwrRspParams setTxPwrRspParams; +}tSetTxPwrRspMsg, *tpSetTxPwrRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_GET_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 staId; +}tGetTxPwrReqParams, *tpGetTxPwrReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetTxPwrReqParams getTxPwrReqParams; +}tGetTxPwrReqMsg, *tpGetTxPwrReqMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_GET_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + /* TX Power in milli watts */ + tANI_U32 txPower; +}tGetTxPwrRspParams, *tpGetTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetTxPwrRspParams getTxPwrRspParams; +}tGetTxPwrRspMsg, *tpGetTxPwrRspMsg; + +#ifdef WLAN_FEATURE_P2P +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_P2P_GONOA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; +}tSetP2PGONOAParams, *tpSetP2PGONOAParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetP2PGONOAParams setP2PGONOAParams; +}tSetP2PGONOAReq, *tpSetP2PGONOAReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_P2P_GONOA_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSetP2PGONOARspParams, *tpSetP2PGONOARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetP2PGONOARspParams setP2PGONOARspParams; +}tSetP2PGONOARspMsg, *tpSetP2PGONOARspMsg; +#endif + +/*--------------------------------------------------------------------------- + *WLAN_HAL_ADD_SELF_STA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U32 status; +}tAddStaSelfParams, *tpAddStaSelfParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U32 status; + tHalIfacePersona iface_persona; +}tAddStaSelfParams_V1, *tpAddStaSelfParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + PACKED_PRE union PACKED_POST { + tAddStaSelfParams addStaSelfParams; + tAddStaSelfParams_V1 addStaSelfParams_V1; + }uAddStaSelfParams; +}tAddStaSelfReq, *tpAddStaSelfReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_ADD_SELF_STA_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + /*Self STA Index */ + tANI_U8 selfStaIdx; + + /* DPU Index (IGTK, PTK, GTK all same) */ + tANI_U8 dpuIdx; + + /* DPU Signature */ + tANI_U8 dpuSignature; + +}tAddStaSelfRspParams, *tpAddStaSelfRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddStaSelfRspParams addStaSelfRspParams; +}tAddStaSelfRspMsg, *tpAddStaSelfRspMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_DEL_STA_SELF_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + +}tDelStaSelfParams, *tpDelStaSelfParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelStaSelfParams delStaSelfParams; +} tDelStaSelfReqMsg, *tpDelStaSelfReqMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_DEL_STA_SELF_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + tSirMacAddr selfMacAddr; +}tDelStaSelfRspParams, *tpDelStaSelfRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelStaSelfRspParams delStaSelfRspParams; +} tDelStaSelfRspMsg, *tpDelStaSelfRspMsg; + + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*--------------------------------------------------------------------------- + *WLAN_HAL_AGGR_ADD_TS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS */ + /* This will carry the bitmap with the bit positions representing different AC.s*/ + tANI_U16 tspecIdx; + + /* Tspec info per AC To program TPE with required parameters */ + tSirMacTspecIE tspec[WLAN_HAL_MAX_AC]; + + /* U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /* These parameters are for all the access categories */ + tANI_U32 srvInterval[WLAN_HAL_MAX_AC]; // Service Interval + tANI_U32 susInterval[WLAN_HAL_MAX_AC]; // Suspend Interval + tANI_U32 delayInterval[WLAN_HAL_MAX_AC]; // Delay Interval + +}tAggrAddTsParams, *tpAggrAddTsParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAggrAddTsParams aggrAddTsParam; +}tAggrAddTsReq, *tpAggrAddTsReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_AGGR_ADD_TS_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status0; + /* FIXME PRIMA for future use for 11R */ + tANI_U32 status1; +}tAggrAddTsRspParams, *tpAggrAddTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAggrAddTsRspParams aggrAddTsRspParam; +}tAggrAddTsRspMsg, *tpAggrAddTsRspMsg; + +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 isAppsCpuAwake; +} tHalConfigureAppsCpuWakeupStateReqParams, *tpHalConfigureAppsCpuWakeupStatReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureAppsCpuWakeupStateReqParams appsStateReqParams; +} tHalConfigureAppsCpuWakeupStateReqMsg, *tpHalConfigureAppsCpuWakeupStateReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalConfigureAppsCpuWakeupStateRspParams, *tpHalConfigureAppsCpuWakeupStateRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureAppsCpuWakeupStateRspParams appsStateRspParams; +} tHalConfigureAppsCpuWakeupStateRspMsg, *tpHalConfigureAppsCpuWakeupStateRspMsg; +/*--------------------------------------------------------------------------- + * WLAN_HAL_DUMP_COMMAND_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 argument1; + tANI_U32 argument2; + tANI_U32 argument3; + tANI_U32 argument4; + tANI_U32 argument5; + +}tHalDumpCmdReqParams,*tpHalDumpCmdReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDumpCmdReqParams dumpCmdReqParams; +} tHalDumpCmdReqMsg, *tpHalDumpCmdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DUMP_COMMAND_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + /*Length of the responce message*/ + tANI_U32 rspLength; + /*FiXME: Currently considering the the responce will be less than 100bytes */ + tANI_U8 rspBuffer[DUMPCMD_RSP_BUFFER]; + +} tHalDumpCmdRspParams, *tpHalDumpCmdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDumpCmdRspParams dumpCmdRspParams; +} tHalDumpCmdRspMsg, *tpHalDumpCmdRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_COEX_IND + *-------------------------------------------------------------------------*/ +#define WLAN_COEX_IND_DATA_SIZE (4) +#define WLAN_COEX_IND_TYPE_DISABLE_HB_MONITOR (0) +#define WLAN_COEX_IND_TYPE_ENABLE_HB_MONITOR (1) +#define WLAN_COEX_IND_TYPE_SCANS_ARE_COMPROMISED_BY_COEX (2) +#define WLAN_COEX_IND_TYPE_SCANS_ARE_NOT_COMPROMISED_BY_COEX (3) +#define WLAN_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 (4) +#define WLAN_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4 (5) + +typedef PACKED_PRE struct PACKED_POST +{ + /*Coex Indication Type*/ + tANI_U32 coexIndType; + + /*Coex Indication Data*/ + tANI_U32 coexIndData[WLAN_COEX_IND_DATA_SIZE]; +}tCoexIndParams,*tpCoexIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tCoexIndParams coexIndParams; +}tCoexIndMsg, *tpCoexIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_OTA_TX_COMPL_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Tx Complete Indication Success or Failure*/ + tANI_U32 status; +}tTxComplParams,*tpTxComplParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTxComplParams txComplParams; +}tTxComplIndMsg, *tpTxComplIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_SUSPEND_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 configuredMcstBcstFilterSetting; + tANI_U32 activeSessionCount; +}tHalWlanHostSuspendIndParam,*tpHalWlanHostSuspendIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanHostSuspendIndParam suspendIndParams; +}tHalWlanHostSuspendIndMsg, *tpHalWlanHostSuspendIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXCLUDE_UNENCRYTED_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_BOOLEAN bDot11ExcludeUnencrypted; + tSirMacAddr bssId; +}tHalWlanExcludeUnEncryptedIndParam,*tpHalWlanExcludeUnEncryptedIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanExcludeUnEncryptedIndParam excludeUnEncryptedIndParams; +}tHalWlanExcludeUnEncrptedIndMsg, *tpHalWlanExcludeUnEncrptedIndMsg; + +#ifdef WLAN_FEATURE_P2P +/*--------------------------------------------------------------------------- + *WLAN_HAL_NOA_ATTR_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 index ; + tANI_U8 oppPsFlag ; + tANI_U16 ctWin ; + + tANI_U16 uNoa1IntervalCnt; + tANI_U16 bssIdx; + tANI_U32 uNoa1Duration; + tANI_U32 uNoa1Interval; + tANI_U32 uNoa1StartTime; + + tANI_U16 uNoa2IntervalCnt; + tANI_U16 rsvd2; + tANI_U32 uNoa2Duration; + tANI_U32 uNoa2Interval; + tANI_U32 uNoa2StartTime; + + tANI_U32 status; +}tNoaAttrIndParams, *tpNoaAttrIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tNoaAttrIndParams noaAttrIndParams; +}tNoaAttrIndMsg, *tpNoaAttrIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_NOA_START_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 bssIdx; +}tNoaStartIndParams, *tpNoaStartIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tNoaStartIndParams noaStartIndParams; +}tNoaStartIndMsg, tpNoaStartIndMsg; +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_RESUME_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 configuredMcstBcstFilterSetting; +}tHalWlanHostResumeReqParam,*tpHalWlanHostResumeReqParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanHostResumeReqParam resumeReqParams; +}tHalWlanHostResumeReqMsg, *tpHalWlanHostResumeReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_RESUME_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalHostResumeRspParams, *tpHalHostResumeRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostResumeRspParams hostResumeRspParams; +} tHalHostResumeRspMsg, *tpHalHostResumeRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 staIdx; + // Peer MAC Address, whose BA session has timed out + tSirMacAddr peerMacAddr; + // TID for which a BA session timeout is being triggered + tANI_U8 baTID; + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + tANI_U32 reasonCode; + tSirMacAddr bssId; // TO SUPPORT BT-AMP +} tHalWlanDelBaIndMsg, *tpHalWlanDelBaIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanDelBaIndMsg hostdelBaParam; +} tHalDelBAIndMsg, *tpHalDelBAIndMsg; + +/*--------------------------------------------------------------------------- + *PNO Messages + *-------------------------------------------------------------------------*/ +/* Max number of channels that a network can be found on*/ +/* WLAN_HAL_PNO_MAX_NETW_CHANNELS and WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX should + * be changed at same time + */ +#define WLAN_HAL_PNO_MAX_NETW_CHANNELS 60 + +/*Max number of channels that a network can be found on*/ +#define WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX 60 + +/*Maximum numbers of networks supported by PNO*/ +#define WLAN_HAL_PNO_MAX_SUPP_NETWORKS 16 + +/*The number of scan time intervals that can be programmed into PNO*/ +#define WLAN_HAL_PNO_MAX_SCAN_TIMERS 10 + +/*Maximum size of the probe template*/ +#define WLAN_HAL_PNO_MAX_PROBE_SIZE 450 + +/*Type of PNO enabling + Immediate - scanning will start immediately and PNO procedure will + be repeated based on timer + Suspend - scanning will start at suspend + Resume - scanning will start on system resume + Delay - start the scan timer to trigger PNO scan + */ +typedef enum +{ + ePNO_MODE_IMMEDIATE, + ePNO_MODE_ON_SUSPEND, + ePNO_MODE_ON_RESUME, + ePNO_MODE_DELAY, + ePNO_MODE_PROXIMITY, // FEATURE_WIFI_PROXIMITY + ePNO_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} ePNOMode; + +/*Authentication type*/ +typedef enum +{ + eAUTH_TYPE_ANY = 0, + eAUTH_TYPE_OPEN_SYSTEM = 1, + + // Upper layer authentication types + eAUTH_TYPE_WPA = 2, + eAUTH_TYPE_WPA_PSK = 3, + + eAUTH_TYPE_RSN = 4, + eAUTH_TYPE_RSN_PSK = 5, + eAUTH_TYPE_FT_RSN = 6, + eAUTH_TYPE_FT_RSN_PSK = 7, + eAUTH_TYPE_WAPI_WAI_CERTIFICATE = 8, + eAUTH_TYPE_WAPI_WAI_PSK = 9, + eAUTH_TYPE_CCKM_WPA = 10, + eAUTH_TYPE_CCKM_RSN = 11, + + eAUTH_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE + +}tAuthType; + +/* Encryption type */ +typedef enum eEdType +{ + eED_ANY = 0, + eED_NONE = 1, + eED_WEP = 2, + eED_TKIP = 3, + eED_CCMP = 4, + eED_WPI = 5, + + eED_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tEdType; + +/* SSID broadcast type */ +typedef enum eSSIDBcastType +{ + eBCAST_UNKNOWN = 0, + eBCAST_NORMAL = 1, + eBCAST_HIDDEN = 2, + + eBCAST_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSSIDBcastType; + +/* + The network description for which PNO will have to look for +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*Authentication type for the network*/ + tAuthType authentication; + + /*Encryption type for the network*/ + tEdType encryption; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Indicates the RSSI threshold for the network to be considered*/ + tANI_U8 rssiThreshold; +}tNetworkType; + +typedef PACKED_PRE struct PACKED_POST +{ + /*How much it should wait */ + tANI_U32 uTimerValue; + + /*How many times it should repeat that wait value + 0 - keep using this timer until PNO is disabled*/ + tANI_U32 uTimerRepeat; + + /*e.g: 2 3 + 4 0 + - it will wait 2s between consecutive scans for 3 times + - after that it will wait 4s between consecutive scans until disabled*/ +}tScanTimer; + +/* + The network parameters to be sent to the PNO algorithm +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*set to 0 if you wish for PNO to use its default telescopic timer*/ + tANI_U8 ucScanTimersCount; + + /*A set value represents the amount of time that PNO will wait between + two consecutive scan procedures + If the desired is for a uniform timer that fires always at the exact same + interval - one single value is to be set + If there is a desire for a more complex - telescopic like timer multiple + values can be set - once PNO reaches the end of the array it will + continue scanning at intervals presented by the last value*/ + tScanTimer aTimerValues[WLAN_HAL_PNO_MAX_SCAN_TIMERS]; + +}tScanTimersType; + +typedef PACKED_PRE struct PACKED_POST { + + /*Enable PNO*/ + tANI_U32 enable; + + /*Immediate, On Suspend, On Resume*/ + ePNOMode modePNO; + + /*Number of networks sent for PNO*/ + tANI_U32 ucNetworksCount; + + /*The networks that PNO needs to look for*/ + tNetworkType aNetworks[WLAN_HAL_PNO_MAX_SUPP_NETWORKS]; + + /*The scan timers required for PNO*/ + tScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + +} tPrefNetwListParams, * tpPrefNetwListParams; + +/* + Preferred network list request +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPrefNetwListParams prefNetwListParams; +} tSetPrefNetwListReq, *tpSetPrefNetwListReq; + + +/* + The network description for which PNO will have to look for +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*Authentication type for the network*/ + tAuthType authentication; + + /*Encryption type for the network*/ + tEdType encryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + tSSIDBcastType bcastNetworkType; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Indicates the RSSI threshold for the network to be considered*/ + tANI_U8 rssiThreshold; +}tNetworkTypeNew; + +typedef PACKED_PRE struct PACKED_POST { + + /*Enable PNO*/ + tANI_U32 enable; + + /*Immediate, On Suspend, On Resume*/ + ePNOMode modePNO; + + /*Number of networks sent for PNO*/ + tANI_U32 ucNetworksCount; + + /*The networks that PNO needs to look for*/ + tNetworkTypeNew aNetworks[WLAN_HAL_PNO_MAX_SUPP_NETWORKS]; + + /*The scan timers required for PNO*/ + tScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + +} tPrefNetwListParamsNew, * tpPrefNetwListParamsNew; + +/* + Preferred network list request new +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPrefNetwListParamsNew prefNetwListParams; +} tSetPrefNetwListReqNew, *tpSetPrefNetwListReqNew; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacSSid ssId; + tANI_U8 currAPbssid[HAL_MAC_ADDR_LEN]; + tANI_U32 authentication; + tEdType encryption; + tEdType mcencryption; + tANI_U8 ChannelCount; + tANI_U8 ChannelCache[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; +}tRoamNetworkType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +}tMobilityDomainInfo; + +typedef PACKED_PRE struct PACKED_POST { + eAniBoolean RoamScanOffloadEnabled; + tANI_S8 LookupThreshold; + tANI_U8 RoamRssiDiff; + tANI_U8 ChannelCacheType; + tANI_U8 Command; + tANI_U8 StartScanReason; + tANI_U16 NeighborScanTimerPeriod; + tANI_U16 NeighborRoamScanRefreshPeriod; + tANI_U16 NeighborScanChannelMinTime; + tANI_U16 NeighborScanChannelMaxTime; + tANI_U16 EmptyRefreshScanPeriod; + tANI_U8 ValidChannelCount; + tANI_U8 ValidChannelList[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; + eAniBoolean IsESEEnabled; + + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE]; + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE]; + /* Add Reserved bytes */ + tANI_U8 nProbes; + tANI_U16 HomeAwayTime; + eAniBoolean MAWCEnabled; + tANI_S8 RxSensitivityThreshold; + tANI_U8 ReservedBytes[WLAN_HAL_ROAM_SCAN_RESERVED_BYTES]; + tRoamNetworkType ConnectedNetwork; + tMobilityDomainInfo MDID; +} tRoamCandidateListParams, * tpRoamCandidateListParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRoamCandidateListParams RoamScanOffloadNetwListParams; +} tSetRoamScanOffloadReq, *tpRoamScanOffloadReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + /* status of the request - just to indicate that PNO has acknowledged + * the request and will start scanning */ + tANI_U32 status; +} tSetRoamOffloadScanResp, *tpSetRoamOffloadScanResp; +#endif + +/* + Preferred network list response +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + /* status of the request - just to indicate that PNO has acknowledged + * the request and will start scanning*/ + tANI_U32 status; +} tSetPrefNetwListResp, *tpSetPrefNetwListResp; + +/* + Preferred network indication parameters +*/ +typedef PACKED_PRE struct PACKED_POST { + + /*Network that was found with the highest RSSI*/ + tSirMacSSid ssId; + + /*Indicates the RSSI */ + tANI_U8 rssi; + + //The MPDU frame length of a beacon or probe rsp. data is the start of the frame + tANI_U16 frameLength; + +} tPrefNetwFoundParams, * tpPrefNetwFoundParams; + +/* + Preferred network found indication +*/ +typedef PACKED_PRE struct PACKED_POST { + + tHalMsgHeader header; + tPrefNetwFoundParams prefNetwFoundParams; +} tPrefNetwFoundInd, *tpPrefNetwFoundInd; + + +typedef PACKED_PRE struct PACKED_POST { + + /*RSSI Threshold*/ + tANI_U8 ucRssiThreshold; + +} tRssiFilterParams, * tpRssiFilterParams; + +/* + RSSI Filter request +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRssiFilterParams prefRSSIFilterParams; +} tSetRssiFilterReq, *tpSetRssiFilterReq; + +/* + Set RSSI filter resp +*/ +typedef PACKED_PRE struct PACKED_POST{ + tHalMsgHeader header; + /*status of the request */ + tANI_U32 status; +} tSetRssiFilterResp, *tpSetRssiFilterResp; +/* + Update scan params +*/ +typedef PACKED_PRE struct PACKED_POST +{ + + /*Host setting for 11d*/ + tANI_U8 b11dEnabled; + + /*Lets PNO know that host has determined the regulatory domain*/ + tANI_U8 b11dResolved; + + /*Channels on which PNO is allowed to scan*/ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Minimum channel time*/ + tANI_U16 usActiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usActiveMaxChTime; + + /*Minimum channel time*/ + tANI_U16 usPassiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usPassiveMaxChTime; + + /*Cb State*/ + ePhyChanBondState cbState; + +} tUpdateScanParams, * tpUpdateScanParams; + +/* + Update scan params +*/ +typedef PACKED_PRE struct PACKED_POST +{ + + /*Host setting for 11d*/ + tANI_U8 b11dEnabled; + + /*Lets PNO know that host has determined the regulatory domain*/ + tANI_U8 b11dResolved; + + /*Channels on which PNO is allowed to scan*/ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX]; + + /*Minimum channel time*/ + tANI_U16 usActiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usActiveMaxChTime; + + /*Minimum channel time*/ + tANI_U16 usPassiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usPassiveMaxChTime; + + /*Cb State*/ + ePhyChanBondState cbState; + +} tUpdateScanParamsEx, * tpUpdateScanParamsEx; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tUpdateScanParams scanParams; +} tUpdateScanParamsReq, *tpUpdateScanParamsReq; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tUpdateScanParamsEx scanParams; +} tUpdateScanParamsReqEx, *tpUpdateScanParamsReqEx; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + + /*status of the request */ + tANI_U32 status; + +} tUpdateScanParamsResp, *tpUpdateScanParamsResp; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_TX_PER_TRACKING_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + tANI_U8 ucTxPerTrackingPeriod; /* Check period, unit is sec. */ + tANI_U8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. */ + tANI_U32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +} tHalTxPerTrackingReqParam, *tpHalTxPerTrackingReqParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTxPerTrackingReqParam txPerTrackingParams; +} tHalSetTxPerTrackingReqMsg, *tpHalSetTxPerTrackingReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_TX_PER_TRACKING_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalTxPerTrackingRspParams, *tpHalTxPerTrackingRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTxPerTrackingRspParams txPerTrackingRspParams; +} tHalSetTxPerTrackingRspMsg, *tpHalSetTxPerTrackingRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TX_PER_HIT_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +}tTxPerHitIndMsg, *tpTxPerHitIndMsg; + +/*--------------------------------------------------------------------------- + *******************Packet Filtering Definitions Begin******************* + *--------------------------------------------------------------------------*/ +#define HAL_PROTOCOL_DATA_LEN 8 +#define HAL_MAX_NUM_MULTICAST_ADDRESS 240 +#define HAL_MAX_NUM_FILTERS 20 +#define HAL_MAX_CMP_PER_FILTER 10 + +typedef enum +{ + HAL_RCV_FILTER_TYPE_INVALID, + HAL_RCV_FILTER_TYPE_FILTER_PKT, + HAL_RCV_FILTER_TYPE_BUFFER_PKT, + HAL_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}tHalReceivePacketFilterType; + +typedef enum +{ + HAL_FILTER_PROTO_TYPE_INVALID, + HAL_FILTER_PROTO_TYPE_MAC, + HAL_FILTER_PROTO_TYPE_ARP, + HAL_FILTER_PROTO_TYPE_IPV4, + HAL_FILTER_PROTO_TYPE_IPV6, + HAL_FILTER_PROTO_TYPE_UDP, + HAL_FILTER_PROTO_TYPE_MAX +}tHalRcvPktFltProtocolType; + +typedef enum +{ + HAL_FILTER_CMP_TYPE_INVALID, + HAL_FILTER_CMP_TYPE_EQUAL, + HAL_FILTER_CMP_TYPE_MASK_EQUAL, + HAL_FILTER_CMP_TYPE_NOT_EQUAL, + HAL_FILTER_CMP_TYPE_MAX +}tHalRcvPktFltCmpFlagType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 protocolLayer; + tANI_U8 cmpFlag; + tANI_U16 dataLength; /* Length of the data to compare */ + tANI_U8 dataOffset; /* from start of the respective frame header */ + tANI_U8 reserved; /* Reserved field */ + tANI_U8 compareData[HAL_PROTOCOL_DATA_LEN]; /* Data to compare */ + tANI_U8 dataMask[HAL_PROTOCOL_DATA_LEN]; /* Mask to be applied on the received packet data before compare */ +}tHalRcvPktFilterParams, *tpHalRcvPktFilterParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U8 filterType; + tANI_U8 numParams; + tANI_U32 coalesceTime; + tHalRcvPktFilterParams paramsData[1]; +}tHalRcvPktFilterCfgType, *tpHalRcvPktFilterCfgType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U8 filterType; + tANI_U8 numParams; + tANI_U32 coleasceTime; + tANI_U8 bssIdx; + tHalRcvPktFilterParams paramsData[1]; +}tHalSessionizedRcvPktFilterCfgType, *tpHalSessionizedRcvPktFilterCfgType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvPktFilterCfgType pktFilterCfg; +} tHalSetRcvPktFilterReqMsg, *tpHalSetRcvPktFilterReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 dataOffset; /* from start of the respective frame header */ + tANI_U32 cMulticastAddr; + tSirMacAddr multicastAddr[HAL_MAX_NUM_MULTICAST_ADDRESS]; + tANI_U8 bssIdx; +} tHalRcvFltMcAddrListType, *tpHalRcvFltMcAddrListType; + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalSetPktFilterRspParams, *tpHalSetPktFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetPktFilterRspParams pktFilterRspParams; +} tHalSetPktFilterRspMsg, *tpHalSetPktFilterRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; +} tHalRcvFltPktMatchCntReqParams, *tpHalRcvFltPktMatchCntReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktMatchCntReqParams pktMatchCntReqParams; +} tHalRcvFltPktMatchCntReqMsg, *tpHalRcvFltPktMatchCntReqMsg; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U32 matchCnt; +} tHalRcvFltPktMatchCnt; +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + tANI_U32 matchCnt; + tHalRcvFltPktMatchCnt filterMatchCnt[HAL_MAX_NUM_FILTERS]; + tANI_U8 bssIdx; +} tHalRcvFltPktMatchRspParams, *tptHalRcvFltPktMatchRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktMatchRspParams fltPktMatchRspParams; +} tHalRcvFltPktMatchCntRspMsg, *tpHalRcvFltPktMatchCntRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; /* only valid for response message */ + tANI_U8 filterId; + tANI_U8 bssIdx; +}tHalRcvFltPktClearParam, *tpHalRcvFltPktClearParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktClearParam filterClearParam; +} tHalRcvFltPktClearReqMsg, *tpHalRcvFltPktClearReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktClearParam filterClearParam; +} tHalRcvFltPktClearRspMsg, *tpHalRcvFltPktClearRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U8 bssIdx; +}tHalRcvFltPktSetMcListRspType, *tpHalRcvFltPktSetMcListRspType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltMcAddrListType mcAddrList; +} tHalRcvFltPktSetMcListReqMsg, *tpHalRcvFltPktSetMcListReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktSetMcListRspType rspParam; +} tHalRcvFltPktSetMcListRspMsg, *tpHalRcvFltPktSetMcListRspMsg; + + +/*--------------------------------------------------------------------------- + *******************Packet Filtering Definitions End******************* + *--------------------------------------------------------------------------*/ + +/* + * There are two versions of this message + * Version 1 : Base version + * Current version : Base version + Max LI modulated DTIM + */ +typedef PACKED_PRE struct PACKED_POST +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /*DTIM Period*/ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicast Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; +}tSetPowerParamsVer1Type, *tpSetPowerParamsVer1Type; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetPowerParamsVer1Type powerParams; +} tSetPowerParamsVer1ReqMsg, *tpSetPowerParamsVer1ReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /*DTIM Period*/ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicast Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; + + /* MAX LI for modulated DTIM */ + tANI_U32 uMaxLIModulatedDTIM; +}tSetPowerParamsType, *tpSetPowerParamsType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetPowerParamsType powerParams; +} tSetPowerParamsReqMsg, *tpSetPowerParamsReqMsg; + +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + + /*status of the request */ + tANI_U32 status; + +} tSetPowerParamsResp, *tpSetPowerParamsResp; + +/*--------------------------------------------------------------------------- + ****************Capability bitmap exchange definitions and macros starts************* + *--------------------------------------------------------------------------*/ + +typedef enum { + MCC = 0, + P2P = 1, + DOT11AC = 2, + SLM_SESSIONIZATION = 3, + DOT11AC_OPMODE = 4, + SAP32STA = 5, + TDLS = 6, + P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7, + WLANACTIVE_OFFLOAD = 8, + BEACON_OFFLOAD = 9, + SCAN_OFFLOAD = 10, + ROAM_OFFLOAD = 11, + BCN_MISS_OFFLOAD = 12, + STA_POWERSAVE = 13, + STA_ADVANCED_PWRSAVE = 14, + AP_UAPSD = 15, + AP_DFS = 16, + BLOCKACK = 17, + PHY_ERR = 18, + BCN_FILTER = 19, + RTT = 20, + RATECTRL = 21, + WOW = 22, + WLAN_ROAM_SCAN_OFFLOAD = 23, + SPECULATIVE_PS_POLL = 24, + SCAN_SCH = 25, + IBSS_HEARTBEAT_OFFLOAD = 26, + WLAN_SCAN_OFFLOAD = 27, + WLAN_PERIODIC_TX_PTRN = 28, + ADVANCE_TDLS = 29, + BATCH_SCAN = 30, + FW_IN_TX_PATH = 31, + EXTENDED_NSOFFLOAD_SLOT = 32, + MCS8_9_IN_2_4G = 34, + MAX_FEATURE_SUPPORTED = 128, +} placeHolderInCapBitmap; + +typedef PACKED_PRE struct PACKED_POST{ + + tANI_U32 featCaps[4]; +} tWlanFeatCaps, *tpWlanFeatCaps; + +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tWlanFeatCaps wlanFeatCaps; + +} tWlanFeatCapsMsg, *tpWlanFeatCapsMsg; + +#define IS_MCC_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(MCC))) +#define IS_SLM_SESSIONIZATION_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(SLM_SESSIONIZATION))) +#define IS_FEATURE_SUPPORTED_BY_HOST(featEnumValue) (!!halMsg_GetHostWlanFeatCaps(featEnumValue)) +#define IS_WLANACTIVE_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLANACTIVE_OFFLOAD))) +#define IS_WLAN_ROAM_SCAN_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLAN_ROAM_SCAN_OFFLOAD))) +#define IS_IBSS_HEARTBEAT_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(IBSS_HEARTBEAT_OFFLOAD))) +#define IS_SCAN_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLAN_SCAN_OFFLOAD))) + +tANI_U8 halMsg_GetHostWlanFeatCaps(tANI_U8 feat_enum_value); + +#define setFeatCaps(a,b) { tANI_U32 arr_index, bit_index; \ + if ((b)<=127) { \ + arr_index = (b)/32; \ + bit_index = (b)%32; \ + if(arr_index < 4) \ + (a)->featCaps[arr_index] |= (1<featCaps[arr_index] & (1<featCaps[arr_index] &= ~(1<FW + WLAN_HAL_LEADER_CANCELED, //Host-->FW + WLAN_HAL_LEADER_PICK_NEW, //FW-->Host + WLAN_HAL_LEADER_IND_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tLbpUpdateIndType; + +typedef enum +{ + WLAN_HAL_LBP_LEADER_ROLE, + WLAN_HAL_LBP_TRANSMITTER_ROLE, + WLAN_HAL_LBP_ROLE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tLbpRoleType; + +typedef PACKED_PRE struct PACKED_POST +{ + tLbpUpdateIndType indication; + + /* Role of the entity generating this indication */ + tLbpRoleType role; + + /* MAC address of MCAST Transmitter (source) */ + tSirMacAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + tSirMacAddr mcastGroup; + + /* MAC address of MCAST Receiver Leader */ + tSirMacAddr mcastLeader; + + /* Candidate list for indication = WLAN_HAL_LEADER_PICK_NEW */ + tSirMacAddr leader[HAL_NUM_MAX_LEADERS]; +} tHalLbpUpdateIndParams, *tpHalLbpUpdateIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLbpUpdateIndParams leaderIndParams; +} tHalLbpUpdateInd, *tpHalLbpUpdateInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 staIdx; // Station Idx; + tANI_U32 txRate; // Legacy transmit rate, in units of 500 kbit/sec, + // for the most recently transmitted frame + tANI_U32 mcsIndex; // mcs index for HT20 and HT40 rates + tANI_U32 txRateFlags; // to differentiate between HT20 and + // HT40 rates; short and long guard interval + tANI_S8 rssi; // RSSI of the last received beacon +}tHalIbssPeerParams, *tpHalIbssPeerParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; // success or failure + tANI_U8 numOfPeers; // Number of Peers for + // which stats are being reported + tHalIbssPeerParams ibssPeerParams[1]; // Stats of peer in IBSS +}tHalIbssPeerInfoRspParams, *tpHalIbssPeerInfoRspParams; + +// WLAN_HAL_GET_IBSS_PEER_INFO_RSP +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalIbssPeerInfoRspParams ibssPeerInfoRspParams; +}tHalIbssPeerInfoRsp, *tpHalIbssPeerInfoRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; // Bss Index + tANI_BOOLEAN allPeerInfoReqd; // If set, all IBSS peers stats are reported + tANI_U8 staIdx; // If allPeerInfoReqd is not set, + // only stats of peer with + // staIdx is reported +}tHalIbssPeerInfoReqParams, *tpHalIbssPeerInfoReqParams; + +// WLAN_HAL_GET_IBSS_PEER_INFO_REQ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalIbssPeerInfoReqParams ibssPeerInfoReqParams; +}tHalIbssPeerInfoReq, *tpHalIbssPeerInfoReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RATE_UPDATE_IND + *-------------------------------------------------------------------------*/ + typedef PACKED_PRE struct PACKED_POST +{ + /* 0 implies UCAST RA, positive value implies fixed rate, -1 implies ignore this param */ + tANI_S32 ucastDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags ucastDataRateTxFlag; + + /* BSSID - Optional. 00-00-00-00-00-00 implies apply to all BCAST STAs */ + tSirMacAddr bssid; + + /* 0 implies MCAST RA, positive value implies fixed rate, -1 implies ignore */ + tANI_S32 reliableMcastDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags reliableMcastDataRateTxFlag; + + /* Default (non-reliable) MCAST(or BCAST) fixed rate in 2.4 GHz, 0 implies ignore */ + tANI_U32 mcastDataRate24GHz; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags mcastDataRate24GHzTxFlag; + + /* Default (non-reliable) MCAST(or BCAST) fixed rate in 5 GHz, 0 implies ignore */ + tANI_U32 mcastDataRate5GHz; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags mcastDataRate5GHzTxFlag; + +} tHalRateUpdateParams, *tpHalRateUpdateParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRateUpdateParams halRateUpdateParams; +} tHalRateUpdateInd, * tpHalRateUpdateInd; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_TX_FAIL_IND +*--------------------------------------------------------------------------*/ +// Northbound indication from FW to host on weak link detection +typedef PACKED_PRE struct PACKED_POST +{ + // Sequence number increases by 1 whenever the device driver + // sends a notification event. This is cleared as 0 when the + // JOIN IBSS commamd is issued + tANI_U16 seqNo; + tANI_U16 staId; + tANI_U8 macAddr[HAL_MAC_ADDR_LEN]; +} tHalTXFailIndParams, *tpHalTXFailIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTXFailIndParams txFailIndParams; +} tHalTXFailIndMsg, *tpHalTXFailIndMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_TX_FAIL_MONITOR_IND +*--------------------------------------------------------------------------*/ +// Southbound message from Host to monitor the Tx failures +typedef PACKED_PRE struct PACKED_POST +{ + // tx_fail_count = 0 should disable the TX Fail monitor, non-zero value should enable it. + tANI_U8 tx_fail_count; +} tTXFailMonitorInfo, *tpTXFailMonitorInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTXFailMonitorInfo txFailMonitor; +} tTXFailMonitorInd, *tpTXFailMonitorInd; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_IP_FORWARD_TABLE_UPDATE_IND +*--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 destIpv4Addr[HAL_IPV4_ADDR_LEN]; + tANI_U8 nextHopMacAddr[HAL_MAC_ADDR_LEN]; +} tDestIpNextHopMacPair; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 numEntries; + tDestIpNextHopMacPair destIpMacPair[1]; +} tWlanIpForwardTableUpdateIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tWlanIpForwardTableUpdateIndParam ipForwardTableParams; +} tWlanIpForwardTableUpdateInd; + +/*--------------------------------------------------------------------------- + *-------------------------------------------------------------------------*/ + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack(pop) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#else +#endif + +#endif /* _WLAN_HAL_MSG_H_ */ + diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_nv.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_nv.h new file mode 100644 index 0000000000000..475a6eae039bc --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_nv.h @@ -0,0 +1,820 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file wlan_nv.h + + \brief Types for NV implementation + Anything that needs to be publicly available should + be in this file + + $Id$========================================================================== */ + +#if !defined( __WLAN_NV_H ) +#define __WLAN_NV_H + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" + +//From HAL/inc/halNv.h +typedef enum +{ + //Common Nv Fields + NV_COMMON_PRODUCT_ID, // 0 + NV_COMMON_PRODUCT_BANDS, // 1 + NV_COMMON_NUM_OF_TX_CHAINS, // 2 + NV_COMMON_NUM_OF_RX_CHAINS, // 3 + NV_COMMON_MAC_ADDR, // 4 + NV_COMMON_MFG_SERIAL_NUMBER, // 5 + NV_COMMON_WLAN_NV_REV_ID, // 6 + NV_COMMON_COUPLER_TYPE, // 7 + NV_COMMON_NV_VERSION, // 8 + NV_COMMON_RESERVED, // 9 + + NUM_NV_FIELDS, + NV_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ + +}eNvField; + + +#define NV_FIELD_MAC_ADDR_SIZE 6 +#define NV_FIELD_MFG_SN_SIZE 40 +typedef enum +{ + PRODUCT_BAND_11_B_G = 0, //Gen6.0 is only this setting + PRODUCT_BAND_11_A_B_G = 1, + PRODUCT_BAND_11_A = 2, + + NUM_PRODUCT_BANDS, + NUM_PRODUCT_BANDS_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eNvProductBands; //NV_COMMON_PRODUCT_BANDS + +#define EXTERNAL_PA 1 +#define INTERNAL_PA 0 + +#define EXTERNAL_LNA 1 +#define INTERNAL_LNA 0 + +#define EXTERNAL_COUPLER 1 +#define INTERNAL_COUPLER 0 + +#define EXTERNAL_PDET 1 +#define INTERNAL_PDET 0 + +#define DPD_ENABLED 1 +#define DPD_DISABLED 0 + +#define TPC_MODE_OPEN_LOOP 0 +#define TPC_MODE_SCPC 1 +#define TPC_MODE_CLPC_MODE2 2 +#define TPC_MODE_CLPC_MODE3 3 + +#define PA_POLARITY_TX_UNUSED 0 +#define PA_POLARITY_TX_POSITIVE 1 +#define PA_POLARITY_TX_NEGATIVE 2 +#define PA_POLARITY_RX_UNUSED 0 +#define PA_POLARITY_RX_POSITIVE 1 +#define PA_POLARITY_RX_NEGATIVE 2 + +#define NV_VERSION_INVALID 0xFF +#define NV_VERSION_11N_11AC_COUPER_TYPE 0 +#define NV_VERSION_11N_11AC_FW_CONFIG 1 +#define NV_VERSION_LPDC_FW_CONFIG 2 +#ifdef FEATURE_WLAN_CH144 +#define NV_VERSION_CH144_CONFIG 3 +#endif /* FEATURE_WLAN_CH144 */ + +#ifdef WCN_PRONTO +#ifdef FEATURE_WLAN_CH144 +#define WLAN_NV_VERSION NV_VERSION_CH144_CONFIG +#else +#define WLAN_NV_VERSION NV_VERSION_LPDC_FW_CONFIG +#endif /* FEATURE_WLAN_CH144 */ +#else //WCN_PRONTO +#define WLAN_NV_VERSION NV_VERSION_11N_11AC_FW_CONFIG +#endif //WCN_PRONTO + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 macAddr1[NV_FIELD_MAC_ADDR_SIZE]; /* Default, not change name for compatibility */ + uint8 macAddr2[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr3[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr4[NV_FIELD_MAC_ADDR_SIZE]; +} sMacAddr; + +typedef PACKED_PRE union PACKED_POST +{ + //common NV fields + uint16 productId; + uint8 productBands; + uint8 wlanNvRevId; + uint8 numOfTxChains; + uint8 numOfRxChains; + sMacAddr macAddr; + uint8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + uint8 couplerType; + uint8 nvVersion; +} uNvFields; + + +//format of common part of nv +typedef PACKED_PRE struct PACKED_POST +{ + //always ensure fields are aligned to 32-bit boundaries + uint16 productId; + uint8 productBands; + uint8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: WCN3660 + + uint8 numOfTxChains; + uint8 numOfRxChains; + uint8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; /* Default, not change name for compatibility */ + uint8 macAddr2[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr3[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr4[NV_FIELD_MAC_ADDR_SIZE]; + uint8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + uint8 couplerType; + uint8 nvVersion; +} sNvFields; + + +//From wlanfw/inc/halPhyTypes.h + +typedef int8 tPowerdBm; //power in signed 8-bit integer, no decimal places + +typedef PACKED_PRE union PACKED_POST +{ + uint32 measurement; //measured values can be passed to pttApi, but are maintained to 2 decimal places internally + int16 reported; //used internally only - reported values only maintain 2 decimals places +}uAbsPwrPrecision; + +typedef enum +{ + PHY_TX_CHAIN_0 = 0, + + NUM_PHY_MAX_TX_CHAINS = 1, + PHY_MAX_TX_CHAINS = NUM_PHY_MAX_TX_CHAINS, + PHY_ALL_TX_CHAINS, + + //possible tx chain combinations + PHY_NO_TX_CHAINS, + PHY_TX_CHAIN_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}ePhyTxChains; + +//From wlanfw/inc/halRfTypes.h + +typedef enum +{ + REG_DOMAIN_FCC, + REG_DOMAIN_ETSI, + REG_DOMAIN_JAPAN, + REG_DOMAIN_WORLD, + REG_DOMAIN_N_AMER_EXC_FCC, + REG_DOMAIN_APAC, + REG_DOMAIN_KOREA, + REG_DOMAIN_HI_5GHZ, + REG_DOMAIN_NO_5GHZ, + + NUM_REG_DOMAINS, + NUM_REG_DOMAINS_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eRegDomainId; + +typedef enum +{ + RF_SUBBAND_2_4_GHZ = 0, + RF_SUBBAND_5_LOW_GHZ = 1, //Low & Mid U-NII + RF_SUBBAND_5_MID_GHZ = 2, //ETSI + RF_SUBBAND_5_HIGH_GHZ = 3, //High U-NII + RF_SUBBAND_4_9_GHZ = 4, //Japanese + + + NUM_RF_SUBBANDS, + + MAX_RF_SUBBANDS, + INVALID_RF_SUBBAND, + + RF_BAND_2_4_GHZ = 0, + RF_BAND_5_GHZ = 1, + NUM_RF_BANDS, + BOTH_RF_BANDS, + RF_SUBBAND_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eRfSubBand; + +typedef enum +{ + //2.4GHz Band + RF_CHAN_1 = 0, + RF_CHAN_2, + RF_CHAN_3, + RF_CHAN_4, + RF_CHAN_5, + RF_CHAN_6, + RF_CHAN_7, + RF_CHAN_8, + RF_CHAN_9, + RF_CHAN_10, + RF_CHAN_11, + RF_CHAN_12, + RF_CHAN_13, + RF_CHAN_14, + + //4.9GHz Band + RF_CHAN_240, + RF_CHAN_244, + RF_CHAN_248, + RF_CHAN_252, + RF_CHAN_208, + RF_CHAN_212, + RF_CHAN_216, + + //5GHz Low & Mid U-NII Band + RF_CHAN_36, + RF_CHAN_40, + RF_CHAN_44, + RF_CHAN_48, + RF_CHAN_52, + RF_CHAN_56, + RF_CHAN_60, + RF_CHAN_64, + + //5GHz Mid Band - ETSI & FCC + RF_CHAN_100, + RF_CHAN_104, + RF_CHAN_108, + RF_CHAN_112, + RF_CHAN_116, + RF_CHAN_120, + RF_CHAN_124, + RF_CHAN_128, + RF_CHAN_132, + RF_CHAN_136, + RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band + RF_CHAN_149, + RF_CHAN_153, + RF_CHAN_157, + RF_CHAN_161, + RF_CHAN_165, + + //CHANNEL BONDED CHANNELS + RF_CHAN_BOND_3, + RF_CHAN_BOND_4, + RF_CHAN_BOND_5, + RF_CHAN_BOND_6, + RF_CHAN_BOND_7, + RF_CHAN_BOND_8, + RF_CHAN_BOND_9, + RF_CHAN_BOND_10, + RF_CHAN_BOND_11, + RF_CHAN_BOND_242, //4.9GHz Band + RF_CHAN_BOND_246, + RF_CHAN_BOND_250, + RF_CHAN_BOND_210, + RF_CHAN_BOND_214, + RF_CHAN_BOND_38, //5GHz Low & Mid U-NII Band + RF_CHAN_BOND_42, + RF_CHAN_BOND_46, + RF_CHAN_BOND_50, + RF_CHAN_BOND_54, + RF_CHAN_BOND_58, + RF_CHAN_BOND_62, + RF_CHAN_BOND_102, //5GHz Mid Band - ETSI & FCC + RF_CHAN_BOND_106, + RF_CHAN_BOND_110, + RF_CHAN_BOND_114, + RF_CHAN_BOND_118, + RF_CHAN_BOND_122, + RF_CHAN_BOND_126, + RF_CHAN_BOND_130, + RF_CHAN_BOND_134, + RF_CHAN_BOND_138, +#ifdef FEATURE_WLAN_CH144 + RF_CHAN_BOND_142, +#endif /* FEATURE_WLAN_CH144 */ + RF_CHAN_BOND_151, //5GHz High U-NII Band + RF_CHAN_BOND_155, + RF_CHAN_BOND_159, + RF_CHAN_BOND_163, + + NUM_RF_CHANNELS, + + MIN_2_4GHZ_CHANNEL = RF_CHAN_1, + MAX_2_4GHZ_CHANNEL = RF_CHAN_14, + + MIN_5GHZ_CHANNEL = RF_CHAN_240, + MAX_5GHZ_CHANNEL = RF_CHAN_165, + NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1), + + MIN_20MHZ_RF_CHANNEL = RF_CHAN_1, + MAX_20MHZ_RF_CHANNEL = RF_CHAN_165, + NUM_20MHZ_RF_CHANNELS = (MAX_20MHZ_RF_CHANNEL - MIN_20MHZ_RF_CHANNEL + 1), + + MIN_40MHZ_RF_CHANNEL = RF_CHAN_BOND_3, + MAX_40MHZ_RF_CHANNEL = RF_CHAN_BOND_163, + NUM_40MHZ_RF_CHANNELS = (MAX_40MHZ_RF_CHANNEL - MIN_40MHZ_RF_CHANNEL + 1), + + MIN_CB_2_4GHZ_CHANNEL = RF_CHAN_BOND_3, + MAX_CB_2_4GHZ_CHANNEL = RF_CHAN_BOND_11, + + MIN_CB_5GHZ_CHANNEL = RF_CHAN_BOND_242, + MAX_CB_5GHZ_CHANNEL = RF_CHAN_BOND_163, + + NUM_TPC_2_4GHZ_CHANNELS = 14, + NUM_TPC_5GHZ_CHANNELS = NUM_5GHZ_CHANNELS, + + INVALID_RF_CHANNEL = 0xBAD, + RF_CHANNEL_INVALID_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +}eRfChannels; + +typedef enum +{ + RF_CHAN_1_1 = RF_CHAN_1, + RF_CHAN_2_1 = RF_CHAN_2, + RF_CHAN_3_1 = RF_CHAN_3, + RF_CHAN_4_1 = RF_CHAN_4, + RF_CHAN_5_1 = RF_CHAN_5, + RF_CHAN_6_1 = RF_CHAN_6, + RF_CHAN_7_1 = RF_CHAN_7, + RF_CHAN_8_1 = RF_CHAN_8, + RF_CHAN_9_1 = RF_CHAN_9, + RF_CHAN_10_1 = RF_CHAN_10, + RF_CHAN_11_1 = RF_CHAN_11, + RF_CHAN_12_1 = RF_CHAN_12, + RF_CHAN_13_1 = RF_CHAN_13, + RF_CHAN_14_1 = RF_CHAN_14, +// The above params are used for scripts. + NUM_2_4GHZ_CHANNELS, +}eRfChannels_2_4GHz; + +enum +{ + NV_CHANNEL_DISABLE, + NV_CHANNEL_ENABLE, + NV_CHANNEL_DFS, + NV_CHANNEL_INVALID +}; +typedef uint8 eNVChannelEnabledType; + +typedef PACKED_PRE struct PACKED_POST +{ + eNVChannelEnabledType enabled; + tPowerdBm pwrLimit; +}sRegulatoryChannel; + +typedef PACKED_PRE struct PACKED_POST +{ + sRegulatoryChannel channels[NUM_RF_CHANNELS]; + uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + uAbsPwrPrecision gnRatePowerOffset[NUM_RF_CHANNELS]; +}ALIGN_4 sRegulatoryDomains; + +typedef PACKED_PRE struct PACKED_POST +{ + int16 bRssiOffset[NUM_RF_CHANNELS]; + int16 gnRssiOffset[NUM_RF_CHANNELS]; +}ALIGN_4 sRssiChannelOffsets; + +typedef PACKED_PRE struct PACKED_POST +{ + uint16 targetFreq; //number in MHz + uint16 channelNum; //channel number as in the eRfChannels enumeration + eRfSubBand band; //band that this channel belongs to +}tRfChannelProps; + +typedef enum +{ + MODE_802_11B = 0, + MODE_802_11AG = 1, + MODE_802_11N = 2, + NUM_802_11_MODES, + MODE_802_11_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +} e80211Modes; + +#define HW_CAL_VALUES_VALID_BMAP_UNUSED 0 //Value +//Bit mask +#define HW_VAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_2G_MASK 0x1 +#define HW_VAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_5G_MASK 0x2 +#define HW_VAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_xLNA_5G_MASK 0x4 +#define HW_VAL_VALUES_VALID_TXBBF_SEL_9MHZ_MASK 0x8 +#define HW_VAL_VALUES_VALID_CUSTOM_TCXO_REG8_MASK 0x10 +#define HW_VAL_VALUES_VALID_CUSTOM_TCXO_REG9_MASK 0x20 + +//From wlanfw/inc/halPhyCalMemory.h +typedef PACKED_PRE struct PACKED_POST +{ + uint16 psSlpTimeOvrHd2G; + uint16 psSlpTimeOvrHd5G; + + uint16 psSlpTimeOvrHdxLNA5G; + uint8 nv_TxBBFSel9MHz : 1; + uint8 hwParam1 : 7; + uint8 hwParam2; + + uint16 custom_tcxo_reg8; + uint16 custom_tcxo_reg9; + + uint32 hwParam3; + uint32 hwParam4; + uint32 hwParam5; + uint32 hwParam6; + uint32 hwParam7; + uint32 hwParam8; + uint32 hwParam9; + uint32 hwParam10; + uint32 hwParam11; +}sCalData; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 validBmap; //use eNvCalID + sCalData calData; +}sHwCalValues; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 txFirFilterMode; +}sTxBbFilterMode; + +typedef PACKED_PRE struct PACKED_POST +{ + int16 ofdmPwrOffset; + int16 rsvd; +}sOfdmCmdPwrOffset; + +//From wlanfw/inc/halPhyCfg.h +typedef uint8 tTpcLutValue; + +#define MAX_TPC_CAL_POINTS (8) + +typedef uint8 tPowerDetect; //7-bit power detect reading + +typedef PACKED_PRE struct PACKED_POST +{ + tPowerDetect pwrDetAdc; //= SENSED_PWR register, which reports the 8-bit ADC + // the stored ADC value gets shifted to 7-bits as the index to the LUT + tPowerDetect adjustedPwrDet; //7-bit value that goes into the LUT at the LUT[pwrDet] location + //MSB set if extraPrecision.hi8_adjustedPwrDet is used +}tTpcCaldPowerPoint; + +typedef tTpcCaldPowerPoint tTpcCaldPowerTable[NUM_PHY_MAX_TX_CHAINS][MAX_TPC_CAL_POINTS]; + +typedef PACKED_PRE struct PACKED_POST +{ + tTpcCaldPowerTable empirical; //calibrated power points +}tTpcConfig; + +//From wlanfw/inc/phyTxPower.h +#ifndef TPC_MEM_POWER_LUT_DEPTH +#define TPC_MEM_POWER_LUT_DEPTH 256 +#endif + +typedef tTpcLutValue tTpcPowerTable[NUM_PHY_MAX_TX_CHAINS][TPC_MEM_POWER_LUT_DEPTH]; + +typedef PACKED_PRE struct PACKED_POST +{ + tTpcConfig *pwrSampled; //points to CLPC data in calMemory +}tPhyTxPowerBand; + +//From halPhyRates.h +typedef enum +{ + //802.11b Rates + HAL_PHY_RATE_11B_LONG_1_MBPS, + HAL_PHY_RATE_11B_LONG_2_MBPS, + HAL_PHY_RATE_11B_LONG_5_5_MBPS, + HAL_PHY_RATE_11B_LONG_11_MBPS, + HAL_PHY_RATE_11B_SHORT_2_MBPS, + HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + HAL_PHY_RATE_11B_SHORT_11_MBPS, + + //Spica_Virgo 11A 20MHz Rates + HAL_PHY_RATE_11A_6_MBPS, + HAL_PHY_RATE_11A_9_MBPS, + HAL_PHY_RATE_11A_12_MBPS, + HAL_PHY_RATE_11A_18_MBPS, + HAL_PHY_RATE_11A_24_MBPS, + HAL_PHY_RATE_11A_36_MBPS, + HAL_PHY_RATE_11A_48_MBPS, + HAL_PHY_RATE_11A_54_MBPS, + + // 11A 20MHz Rates + HAL_PHY_RATE_11A_DUP_6_MBPS, + HAL_PHY_RATE_11A_DUP_9_MBPS, + HAL_PHY_RATE_11A_DUP_12_MBPS, + HAL_PHY_RATE_11A_DUP_18_MBPS, + HAL_PHY_RATE_11A_DUP_24_MBPS, + HAL_PHY_RATE_11A_DUP_36_MBPS, + HAL_PHY_RATE_11A_DUP_48_MBPS, + HAL_PHY_RATE_11A_DUP_54_MBPS, + + //MCS Index #0-7 (20/40MHz) + HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_13_MBPS, + HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_26_MBPS, + HAL_PHY_RATE_MCS_1NSS_39_MBPS, + HAL_PHY_RATE_MCS_1NSS_52_MBPS, + HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_65_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + //MCS Index #8-15 (20/40MHz) + HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATURE_11AC + /*11A duplicate 80MHz Rates*/ + HAL_PHY_RATE_11AC_DUP_6_MBPS, + HAL_PHY_RATE_11AC_DUP_9_MBPS, + HAL_PHY_RATE_11AC_DUP_12_MBPS, + HAL_PHY_RATE_11AC_DUP_18_MBPS, + HAL_PHY_RATE_11AC_DUP_24_MBPS, + HAL_PHY_RATE_11AC_DUP_36_MBPS, + HAL_PHY_RATE_11AC_DUP_48_MBPS, + HAL_PHY_RATE_11AC_DUP_54_MBPS, + + /*11AC rate 20MHZ Normal GI*/ + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS, +#ifdef WCN_PRONTO + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + + /*11AC rate 20MHZ Shortl GI*/ + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + + /*11AC rates 40MHZ normal GI*/ + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS , + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + + /*11AC rates 40MHZ short GI*/ + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS , + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + /*11AC rates 80 MHZ normal GI*/ + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS , + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + + /*11AC rates 80 MHZ short GI*/ + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS , + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif //WLAN_FEATURE_11AC + + NUM_HAL_PHY_RATES, + HAL_PHY_RATE_INVALID, + MIN_RATE_INDEX = 0, + MAX_RATE_INDEX = NUM_HAL_PHY_RATES - 1, + HAL_PHY_RATE_INVALID_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +}eHalPhyRates; + +#define NUM_RATE_POWER_GROUPS NUM_HAL_PHY_RATES //total number of rate power groups including the CB_RATE_POWER_OFFSET +typedef uAbsPwrPrecision tRateGroupPwr[NUM_HAL_PHY_RATES]; + +//From halNvTables.h +#define NV_FIELD_COUNTRY_CODE_SIZE 3 +typedef PACKED_PRE struct PACKED_POST +{ + uint8 regDomain; //from eRegDomainId + uint8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; // string identifier +}sDefaultCountry; + + +#define GF_PA_BIAS_SELECT_MASK 0X7 //(3 bits) +#define TSMC_PA_BIAS_SELECT_MASK 0x7 //(3 bits) + +#define GF_PA_BIAS_SELECT_1 0X0 +#define GF_PA_BIAS_SELECT_2 0X1 + +#define TSMC_PA_BIAS_SELECT_1 0X0 +#define TSMC_PA_BIAS_SELECT_2 0X1 +#define TSMC_PA_BIAS_SELECT_3 0x2 + + +#define EXT_PA_CTRL_POLARITY_DEFAULT 0X0 +#define EXT_PA_CTRL_POLARITY_VALID 0X80 + +#define EXT_PA_CTRL0_POLARITY_MASK 0X3 +#define EXT_PA_CTRL0_POLARITY_OFFSET 0X0 +#define EXT_PA_CTRL1_POLARITY_MASK 0XC +#define EXT_PA_CTRL1_POLARITY_OFFSET 0X2 + +#define EXT_PA_CTRL_POLARITY_ZERO 0X1 +#define EXT_PA_CTRL_POLARITY_ONE 0X2 + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 skuID; + uint8 tpcMode2G; + uint8 tpcMode5G; + uint8 configItem1; + + uint8 xPA2G; + uint8 xPA5G; + uint8 extPaCtrl0Polarity; + uint8 extPaCtrl1Polarity; + + uint8 xLNA2G; + uint8 xLNA5G; + uint8 xCoupler2G; + uint8 xCoupler5G; + + uint8 xPdet2G; + uint8 xPdet5G; + uint8 enableDPD2G; + uint8 enableDPD5G; + + uint8 pdadcSelect2G; + uint8 pdadcSelect5GLow; + uint8 pdadcSelect5GMid; + uint8 pdadcSelect5GHigh; + + uint32 configItem2; + uint32 configItem3; + uint32 configItem4; +}sFwConfig; + + +#define NUM_RF_VR_RATE 13 +typedef uAbsPwrPrecision tRateGroupPwrVR[NUM_RF_VR_RATE]; + +typedef PACKED_PRE union PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsets rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 uNvTables; + +//From halPhy.h +typedef tPowerdBm tChannelPwrLimit; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 chanId; + tChannelPwrLimit pwr; +} ALIGN_4 tChannelListWithPower; + +//From HAL/inc/halNvTables.h +typedef enum +{ + NV_FIELDS_IMAGE = 0, //contains all fields + + NV_TABLE_RATE_POWER_SETTINGS = 2, + NV_TABLE_REGULATORY_DOMAINS = 3, + NV_TABLE_DEFAULT_COUNTRY = 4, + NV_TABLE_TPC_POWER_TABLE = 5, + NV_TABLE_TPC_PDADC_OFFSETS = 6, + NV_TABLE_HW_CAL_VALUES = 7, + NV_TABLE_RSSI_CHANNEL_OFFSETS = 9, + NV_TABLE_CAL_MEMORY = 10, //cal memory structure from halPhyCalMemory.h preceded by status + NV_TABLE_FW_CONFIG = 11, + NV_TABLE_ANTENNA_PATH_LOSS = 12, + NV_TABLE_PACKET_TYPE_POWER_LIMITS = 13, + NV_TABLE_OFDM_CMD_PWR_OFFSET = 14, + NV_TABLE_TX_BB_FILTER_MODE = 15, + NV_TABLE_VIRTUAL_RATE = 18, + + NUM_NV_TABLE_IDS, + NV_ALL_TABLES = 0xFFF, + NV_BINARY_IMAGE = 0x1000, + NV_MAX_TABLE = 0x7FFFFFFF /* define as 4 bytes data */ +}eNvTable; + +typedef PACKED_PRE struct PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsets rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 sNvTables; + +typedef PACKED_PRE struct PACKED_POST +{ + sNvFields fields; + sNvTables tables; +}ALIGN_4 sHalNv; + +extern const sHalNv nvDefaults; + +#endif + diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_phy.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_phy.h new file mode 100644 index 0000000000000..8cd416cb15cbe --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_phy.h @@ -0,0 +1,917 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_PHY_H +#define WLAN_PHY_H +/*============================================================================ +@file wlan_phy.h + +Contains definitions of all PHY related structures that aree needed by FTM/PTT + +============================================================================*/ +#include + +/* Currently this structure holds the information about the current calibration mode. +In future, if anymore info is needed, that can be added here */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 currentCalibration; +} sCalibrationInfo; + +typedef PACKED_PRE struct PACKED_POST { + tANI_S16 I; //ADC sample of PHY_I_RAIL + tANI_S16 Q; //ADC sample of PHY_Q_RAIL +}tIQSamples; + +typedef tIQSamples tIQAdc; +typedef tIQSamples tIQDac; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 maxGainIndex; + tANI_U8 topGainDb; + tANI_U8 bottomGainDb; + tANI_U8 unused[1]; +}tAsicAgc; + +#define TXFIR_MEM QWLAN_TXFIR_TXCAL_MEM0_MREG +#define TXFIR_MEM_GAIN_MULT (16) //bytes per gain +#define TXFIR_MEM_PER_CHAIN (16 * TXFIR_MEM_GAIN_MULT) //# of gains per chain * bytes per gain + +typedef tIQAdc tTxCarrierError; + +#define ONE_MICROSECOND (160) +#define DEFAULT_INTERFRAME_SPACE (ONE_MICROSECOND * 10) //10 microseconds + +typedef enum { + PHYDBG_TX_IDLE = 0, + PHYDBG_TX_START = 1, + PHYDBG_TX_WARMUP = 2, + PHYDBG_TX_INFD = 3, + PHYDBG_TX_CMD = 4, + PHYDBG_TX_SVC = 5, + PHYDBG_TX_PYLDF = 6, + PHYDBG_TX_PYLDR = 7, + PHYDBG_TX_CRC = 8, + PHYDBG_TX_FLUSH = 9, + PHYDBG_TX_TXDONEWAIT = 10, + PHYDBG_TX_TIFWAIT = 11 +} ePhyDbgTxStatus; + +typedef enum { + PHYDBG_PREAMBLE_OFDM, + PHYDBG_PREAMBLE_GREENFIELD, + PHYDBG_PREAMBLE_MIXED, + PHYDBG_PREAMBLE_SHORTB, + PHYDBG_PREAMBLE_LONGB, + + PHYDBG_LDPC_PREAMBLE_OFDM = 0x10, + PHYDBG_LDPC_PREAMBLE_GREENFIELD = 0x11, + PHYDBG_LDPC_PREAMBLE_MIXED = 0x12 +} ePhyDbgPreamble; + + +//grab ram +#ifdef VERIFY_HALPHY_SIMV_MODEL +#define GRAB_RAM_DBLOCK_SIZE (256) //number of samples in full capture +#else +#define GRAB_RAM_DBLOCK_SIZE (1024) //number of samples in full capture +#endif + +#define MAX_REQUESTED_GRAB_RAM_SAMPLES 256 //only allow 256 samples at a time +#define GRAB_RAM_BUFFER_DEPTH (4*1024) //maximum grab ram size in full capture +#define LAST_GRAB_RAM_SAMPLE_INDEX (GRAB_RAM_BUFFER_DEPTH - 1) + + +typedef PACKED_PRE struct PACKED_POST { + tIQAdc rx0; +} tGrabRamSample; + + +enum { + GRABRAM_RAWADC = 0, + GRABRAM_POSTIQ +}; +typedef tANI_U32 eGrabRamSampleType; + +typedef tANI_S8 tANI_S6; +typedef tANI_S16 tANI_S9; +typedef tANI_S16 tANI_S10; +typedef tANI_S16 tANI_S12; +typedef tANI_U16 tANI_U10; + + + +//convert float to a format that preserves enough accuracy to be used by driver +typedef tANI_S16 t2Decimal; +#define CONVERT_TO_2DECIMAL_PLACES(x) (x * 100) +#define CONVERT_FROM_2DECIMAL_PLACES(x) (x / 100) + +#ifndef PTT_FLOAT +#define PTT_FLOAT tANI_U32 // driver code can't include float, +//so this reserves space in our structures to allow floating point measurements +#endif + +typedef enum +{ + PHY_RX_CHAIN_0 = 0, + + PHY_MAX_RX_CHAINS = 1, + PHY_ALL_RX_CHAINS, + PHY_NO_RX_CHAINS +}ePhyRxChains; + +typedef enum +{ + PHY_I_RAIL = 0, + PHY_Q_RAIL = 1, + PHY_NUM_IQ_RAILS +}ePhyIQ; + +//[RY] extend total gain steps to 24 + +enum +{ + TX_GAIN_STEP_0, + TX_GAIN_STEP_1, + TX_GAIN_STEP_2, + TX_GAIN_STEP_3, + TX_GAIN_STEP_4, + TX_GAIN_STEP_5, + TX_GAIN_STEP_6, + TX_GAIN_STEP_7, + TX_GAIN_STEP_8, + TX_GAIN_STEP_9, + TX_GAIN_STEP_10, + TX_GAIN_STEP_11, + TX_GAIN_STEP_12, + TX_GAIN_STEP_13, + TX_GAIN_STEP_14, + TX_GAIN_STEP_15, + TX_GAIN_STEP_16, + TX_GAIN_STEP_17, + TX_GAIN_STEP_18, + TX_GAIN_STEP_19, + TX_GAIN_STEP_20, + TX_GAIN_STEP_21, + TX_GAIN_STEP_22, + TX_GAIN_STEP_23, + TX_GAIN_STEP_24, + TX_GAIN_STEP_25, + TX_GAIN_STEP_26, + TX_GAIN_STEP_27, + TX_GAIN_STEP_28, + TX_GAIN_STEP_29, + TX_GAIN_STEP_30, + TX_GAIN_STEP_31, + + RX_GAIN_STEP_0 = 0, + RX_GAIN_STEP_1, + RX_GAIN_STEP_2, + RX_GAIN_STEP_3, + RX_GAIN_STEP_4, + RX_GAIN_STEP_5, + RX_GAIN_STEP_6, + RX_GAIN_STEP_7, + RX_GAIN_STEP_8, + RX_GAIN_STEP_9, + RX_GAIN_STEP_10, + RX_GAIN_STEP_11, + RX_GAIN_STEP_12, + RX_GAIN_STEP_13, + RX_GAIN_STEP_14, + RX_GAIN_STEP_15, + + NUM_TX_GAIN_STEPS = 32, + MAX_TX_GAIN_STEP = TX_GAIN_STEP_31, + + NUM_RX_GAIN_STEPS = 16, + MAX_RX_GAIN_STEP = RX_GAIN_STEP_15, +}; +typedef tANI_U32 eGainSteps; + + +//[RY] new for PRIMA +#define DPD_RESPONSE_SIZE 128 +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 dpdCalFailCnt; //Count for number of times DPD cal failed. + tANI_U8 dpdCalSuccessCnt; //Count for number of times DPD cal passed. + tANI_U8 dpdColdBootRepeatCalStatus; + tANI_U8 dpdLastIteration; + tANI_S16 dpd_threshold[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_aoffset[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_again[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_poffset[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_pgain[DPD_RESPONSE_SIZE]; + tANI_S32 dpd_sample[20]; + tANI_U8 dpd_try; + tANI_U8 band; +}sDPDcorrectionCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sDPDcorrectionCalValues dpd[PHY_MAX_TX_CHAINS]; +}sTxChainsDPDCalValues; + + +//[RY] RX IQ correction coefficients Memory +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 coeff_i[5]; + tANI_S9 coeff_q[5]; +}sIQCalValues; + +//[RY], added for RIVA +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 iq_ampimb_coeff; + tANI_S16 txloleakage_i; // raw data is 6-bit 2's compliment + tANI_S16 txloleakage_q; // raw data is 6-bit 2's compliment +}sTXIQCalValues; + +//[RY], added for RIVA +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 iqphaseimb_coeff_i[5]; + tANI_S9 iqphaseimb_coeff_q[5]; +}sTXIQPhaseImbCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sIQCalValues iq[PHY_MAX_RX_CHAINS]; +}sRxChainsIQCalValues; + +//[RY] change for PRIMA +typedef PACKED_PRE struct PACKED_POST { + sTXIQCalValues iq[PHY_MAX_TX_CHAINS]; + sTXIQPhaseImbCalValues iqImb[PHY_MAX_TX_CHAINS]; +}sTxChainsIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 co_i[3]; + tANI_S9 co_q[3]; +}sHKIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sHKIQCalValues co[PHY_MAX_TX_CHAINS]; +}sTxChainsHKIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 lna_code; //wlan_lna_5g_control1,wl_5g_lna_load_ctune + tANI_U8 gm_code; //wlan_rxgm_5g_control4,wlgm_ctune +}sLnaBandCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sLnaBandCalValues lnaCode[PHY_MAX_RX_CHAINS]; +}sTxChainsLnaBandCalValues; + +typedef tANI_U16 t_mW; //milliWatts +typedef tANI_U8 tPwrTemplateIndex; //5-bit number used as the index into the tx gain tables + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 txPowerAdc[PHY_MAX_TX_CHAINS]; +}sTxChainsPowerAdcReadings; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 agcGain; +}tRxGain; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 rx[PHY_MAX_RX_CHAINS]; +}sRxChainsData; + +typedef sRxChainsData sRxChainsRssi; +typedef sRxChainsData sRxChainsAgcDisable; + +typedef PACKED_PRE struct PACKED_POST { + tANI_BOOLEAN rx[PHY_MAX_RX_CHAINS]; +}sRxChainsBoolean; + +typedef sRxChainsBoolean sRxChainsAgcEnable; + +#define NUM_AGC_GAINS 64 +typedef tRxGain sAgcGainLut[NUM_AGC_GAINS]; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_S6 iLo; + tANI_S6 qLo; +}sTxFirLoCorrect; + +typedef tIQAdc sTxLoCorrectBB[PHY_MAX_TX_CHAINS][NUM_TX_GAIN_STEPS]; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 txIqLoCache[PHY_MAX_TX_CHAINS][NUM_TX_GAIN_STEPS][4]; + tANI_U32 spatialRotation; +}tAsicTxFir; + +//Tx Power Config +//A collection of selected calibrated power points at selected frequencies. +//The algorithm does not need to know any particulars about which frequencies or cal points, +// just the linearized adjustments at the selected calibration points +#define MAX_TPC_CHANNELS (NUM_RF_CHANNELS) +#define START_TPC_CHANNEL (2412) +#define END_TPC_CHANNEL (2484) + +#define MAX_PWR_LUT_DBM (24) +#define MIN_PWR_LUT_DBM (8) + + +/* The reason that MAX_PWR_LUT_DBM_2DEC_PLACES is not simply (MAX_PWR_LUT_DBM * 100) is due to the fact + that we are interpolating the 5-bit power template index from this range compared to a LUT range of 0 to 127. + There is an expectation that this power range is evenly divided in 0.5dBm steps. + We expect that a commanded 13dBm would yield a power template index of 10, where a power template index of 0 would represent 8dBm. + If we used an even 2400 to represent the max power, then the calculation for 13dBm actually returns 9: + (127 - 0)*((1300 - 800)/(2400 - 800))+0 = 39.6875 = 39. When shifted to 5 bits, =9. Not what we wanted. + What we need to do is find the 2-decimal place power that corresponds as closely as possible to the 127 in the 0 to 127 range. + For the 800 to 2400 range, that comes out to 2386.5, so 2386. So again for a commanded power of 13dBm: + (127 - 0)*((1300 - 800)/(2386 - 800))+0 = 40.0378 = 40. When shifted to 5-bits, = 10, which is what we wanted. + +*/ + +#define MIN_PWR_LUT_DBM_2DEC_PLACES (MIN_PWR_LUT_DBM * 100) +#define MAX_PWR_LUT_DBM_2DEC_PLACES ((MAX_PWR_LUT_DBM * 100) - (1 + (100 * (MAX_PWR_LUT_DBM - MIN_PWR_LUT_DBM))/TPC_MEM_POWER_LUT_DEPTH)) + +//macro provides a quick conversion of dbm value between MIN_PWR_LUT_DBM and MAX_PWR_LUT_DBM to a power template index(0 to 31) +//based on convention, which may not hold true in the future. +#define CONVERT_DBM_GINDEX(dbm) (((dbm - MIN_PWR_LUT_DBM) * 32) / (MAX_PWR_LUT_DBM - MIN_PWR_LUT_DBM)) + +typedef tANI_U8 tTxGainCombo; //7-bit gain value used to get the power measurement + +typedef PACKED_PRE struct PACKED_POST +{ + tPowerDetect min; + tPowerDetect max; +}tPwrTemplateRange; + + + +/* + The following union affords backward compatibility with txGain usage with band-specific tTpcConfig tables. + Due to my finding that 7-bits is not enough precision, we need to reuse the txGain space as extra precision bits + for the adjustedPwrDet. My spreadsheet shows that we need at least 4 bits more precision. + To know which usage, the MSB of adjustedPwrDet can be set to signify the extra precision in place of the txGain, which isn't used anyway. + We just need to be careful not to interpret a pre-existing table's txGain as extra precision. +*/ + + typedef union + { + tTxGainCombo txGain; //7-bit gain used to measure the pwrDetAdc value + tANI_U8 hi8_adjustedPwrDet; //if the MSB is set in adjustedPwrDet, then these are extra bits of precision + }uExtraLutBits; + + +typedef PACKED_PRE struct PACKED_POST +{ + t2Decimal min; //sometimes used for comparing chain powers + t2Decimal max; //sometimes used for comparing chain powers +}tPowerdBmRange; //absolute power measurement precision maintained to two decimal places + + +typedef tANI_U16 tRfADCVal; +typedef tRfADCVal tTempADCVal; + +typedef PACKED_PRE struct PACKED_POST +{ + tRfADCVal pdadc_offset; + tANI_U8 reserved[2]; +}tTpcParams; + + +//these definitions used as indexing to power per channel per rate table stored in NV +#define CB_RATE_POWER_OFFSET 0 +#define CB_RATE_POWER_OFFSET_LAST_INDEX 60 //last index where we would apply the CB_RATE_POWER_OFFSET + +/* TX Power Calibration & Report Types */ + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U8 temperatureAdc; //= 5 bit temperature measured at time sample was taken + tANI_U8 txGain; //= 7 bit gain value used to get the power measurement + tANI_U8 pwrDetAdc; //= 8 bit ADC power detect value + tANI_U8 reserved; + uAbsPwrPrecision absPowerMeasured; //= dBm measurement, will be truncated to two decimal places + }tTpcCalPoint; + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U16 numTpcCalPoints; + tANI_U16 reserved; + tTpcCalPoint chain[MAX_TPC_CAL_POINTS]; + }tTpcChainData; + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U16 freq; //frequency in MHz + tANI_U16 reserved; + tTpcChainData empirical[PHY_MAX_TX_CHAINS]; //TPC samples passed in + }tTpcFreqData; + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U8 numChannels; + tANI_U8 reserved[3]; + tTpcFreqData calValues[MAX_TPC_CHANNELS]; + }sTpcFreqCalTable; + + +typedef PACKED_PRE struct PACKED_POST { + tPowerDetect lut; //7-bit value in the power Lookup Table + tANI_U8 reserved[3]; + + uAbsPwrPrecision abs; //LUT value conversion to absolute dBm +}tTxPowerLutOutput; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 gain; //8-bit coarse(bits 4-7) & fine(bits 0-3) gain commanded for the current index + tPowerDetect adc; //8-bit power ADC sampled during the packet preamble + tANI_U16 rawAdc; //11-bit power raw ADC sampled + + tTxPowerLutOutput indexMinMatch; //minimum LUT matching power that satisfies the power template index setting + tTxPowerLutOutput indexMaxMatch; //maximum LUT matching power that satisfies the power template index setting + tTxPowerLutOutput output; //output power values corresponding to power ADC index +}tTxChainPower; + +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +typedef enum +{ + RF_CAL_TONE_28NEG, + RF_CAL_TONE_24NEG, + RF_CAL_TONE_20NEG, + RF_CAL_TONE_16NEG, + RF_CAL_TONE_12NEG, + RF_CAL_TONE_8NEG, + RF_CAL_TONE_4NEG, + RF_CAL_TONE_4POS, + RF_CAL_TONE_8POS, + RF_CAL_TONE_12POS, + RF_CAL_TONE_16POS, + RF_CAL_TONE_20POS, + RF_CAL_TONE_24POS, + RF_CAL_TONE_28POS, + + NUM_RF_TONES, + + MIN_RF_TONE = RF_CAL_TONE_28NEG, + MAX_RF_TONE = RF_CAL_TONE_28POS +}eRfTones; + +typedef tANI_U8 tDcoCorrect; +typedef tANI_S8 tIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + tDcoCorrect IDcoCorrect; + tDcoCorrect QDcoCorrect; + tANI_U8 dcRange; +}tRxDcoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tRxDcoCorrect dco[PHY_MAX_RX_CHAINS]; +}tRxChainsDcoCorrections; + +typedef PACKED_PRE struct PACKED_POST { + tIm2Correct ICorrect; + tIm2Correct QCorrect; +}tRxIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + tRxIm2Correct dco[PHY_MAX_RX_CHAINS]; +}tRxChainsIm2Corrections; + +typedef PACKED_PRE struct PACKED_POST { + tDcoCorrect IDcoCorrect; + tDcoCorrect QDcoCorrect; +}tTxLoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tTxLoCorrect txLo[PHY_MAX_TX_CHAINS]; +}sTxChainsLoCorrections; + + +//tDcoCorrect is needed to define rf specific structures + +#define NUM_RF_RX_GAIN_STEPS (128) +#define MAX_RF_RX_GAIN_STEP (NUM_RF_RX_GAIN_STEPS - 1) + +#define NUM_RF_TX_GAIN_STEPS (16) +#define MAX_RF_TX_GAIN_STEP (NUM_RF_TX_GAIN_STEPS - 1) + +#define RF_AGC_GAIN_LUT_DEPTH (128) +#define NUM_RF_DCO_VALUES (128) //There are only 32 DCO values, but our algorithm it makes more sense for us to access these by AGC gain index +#define MAX_RF_DCO_VALUE (NUM_RF_DCO_VALUES - 1) + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 gainReg1; //GEMINI_REG_RX_GC_0 (lna + mix + tia + bq1 + bq2 + pga) +}tRfRxGain; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 bbf_gain_cnt; + tANI_U16 bbf_lin_adj; + tANI_U16 lo_mix_da_gain_cntl; + tANI_U16 pa_gain_cntl; + tANI_U16 da_pa_bias_1_cnt; + tANI_U16 da_pa_bias_2_cntl; +}tRfTxGain; + +typedef PACKED_PRE struct PACKED_POST +{ + //TODO:define this struct for Gemini + tANI_U8 rxIf; + tANI_U8 txIf; + tANI_U8 txRf; + tANI_U8 reserved; +}sRfSpecificFilterSettings; + +typedef sRfSpecificFilterSettings sRfChannelFilterSettings[NUM_RF_CHANNELS]; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 hdet_ctl_ext_atten; + tANI_U8 hdet_dcoc_code; + tANI_U8 hdet_dcoc_ib_rcal_en; + tANI_U8 hdet_dcoc_ib_scal_en; +}sRfNvCalValues; //stored in QFUSE + + + +typedef enum +{ + SYNTH_UNLOCKED, + SYNTH_LOCK +}eRfSynthLock; + +typedef enum +{ + TEMP_SENSOR_PA, + TEMP_SENSOR_RX +}eRfTempSensor; + +typedef enum +{ + TEMPERATURE_BIN_0, //-30 to 5 C + TEMPERATURE_BIN_1, //5 to 45 C + TEMPERATURE_BIN_2, //45 to 85 C + TEMPERATURE_BIN_3, //85 to 125 C + NUM_TEMPERATURE_BINS +}eTemperatureBins; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 hdetDcocCode; + tANI_U16 hdetDcoOffset; +}sRfHdetCalValues; + +#define TPC_TXPWR_ENABLE_MASK QWLAN_TPC_TXPWR_ENABLE_EN_MASK + + +#define TPC_MEM_TX0_PWR_LUT_OFFSET QWLAN_TPC_POWERDET0_RAM_MREG +#define TPC_MEM_TX1_PWR_LUT_OFFSET QWLAN_TPC_POWERDET1_RAM_MREG +#define TPC_MEM_TX2_PWR_LUT_OFFSET QWLAN_TPC_POWERDET2_RAM_MREG +#define TPC_MEM_TX3_PWR_LUT_OFFSET QWLAN_TPC_POWERDET3_RAM_MREG +#define TPC_MEM_TX0_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT0_MREG +#define TPC_MEM_TX1_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT1_MREG +#define TPC_MEM_TX2_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT2_MREG +#define TPC_MEM_TX3_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT3_MREG + +//these masks are the same for both chains +#define TPC_POWERDET_MASK QWLAN_TPC_POWERDET0_RAM_POWER_MASK +#define TPC_GAIN_RF_MASK QWLAN_TPC_GAIN_LUT0_RF_GAIN_MASK +#define TPC_GAIN_RF_OFFSET QWLAN_TPC_GAIN_LUT0_RF_GAIN_OFFSET +#define TPC_GAIN_DIG_MASK QWLAN_TPC_GAIN_LUT0_DIG_GAIN_MASK + + +#define TPC_MEM_GAIN_LUT_DEPTH 32 + + +#define TPC_ADC_CTRL_REG QWLAN_TPC_ADC_CTRL_GET_ADC_REG +#define TPC_ADC_GET_MASK QWLAN_TPC_ADC_CTRL_GET_ADC_GET_ADC_MASK + +#define TPC_ADC_FAILED_MASK QWLAN_TPC_ADC_STATUS_FAILED_MASK +#define TPC_ADC_BUSY_P_MASK QWLAN_TPC_ADC_STATUS_BUSY_P_MASK +#define TPC_ADC_BUSY_T_MASK QWLAN_TPC_ADC_STATUS_BUSY_T_MASK + + +#define MSK_1 0x1 +#define MSK_2 0x3 +#define MSK_3 0x7 +#define MSK_4 0xF +#define MSK_5 0x1F +#define MSK_6 0x3F +#define MSK_7 0x7F +#define MSK_8 0xFF +#define MSK_9 0x1FF +#define MSK_10 0x3FF +#define MSK_11 0x7FF +#define MSK_12 0xFFF +#define MSK_13 0x1FFF +#define MSK_14 0x3FFF +#define MSK_15 0x7FFF +#define MSK_16 0xFFFF +#define MSK_17 0x1FFFF +#define MSK_18 0x3FFFF +#define MSK_19 0x7FFFF +#define MSK_20 0xFFFFF +#define MSK_21 0x1FFFFF +#define MSK_22 0x3FFFFF +#define MSK_23 0x7FFFFF +#define MSK_24 0xFFFFFF +#define MSK_25 0x1FFFFFF +#define MSK_26 0x3FFFFFF +#define MSK_27 0x7FFFFFF +#define MSK_28 0xFFFFFFF +#define MSK_29 0x1FFFFFFF +#define MSK_30 0x3FFFFFFF +#define MSK_31 0x7FFFFFFF +#define MSK_32 0xFFFFFFFF + + +#define COARSE_GAIN_MASK MSK_4 +#define COARSE_GAIN_OFFSET 4 +#define FINE_GAIN_MASK MSK_4 //the upper most bit overlaps the coarse gain and should not be used for TPC LUT data +#define FINE_GAIN_OFFSET 0 + +typedef enum +{ + TPC_COARSE_TXPWR_0, + TPC_COARSE_TXPWR_1, + TPC_COARSE_TXPWR_2, + TPC_COARSE_TXPWR_3, + TPC_COARSE_TXPWR_4, + TPC_COARSE_TXPWR_5, + TPC_COARSE_TXPWR_6, + TPC_COARSE_TXPWR_7, + TPC_COARSE_TXPWR_8, + TPC_COARSE_TXPWR_9, + TPC_COARSE_TXPWR_10, + TPC_COARSE_TXPWR_11, + TPC_COARSE_TXPWR_12, + TPC_COARSE_TXPWR_13, + TPC_COARSE_TXPWR_14, + TPC_COARSE_TXPWR_15, + TPC_COARSE_TXPWR_16, + TPC_COARSE_TXPWR_17, + TPC_COARSE_TXPWR_18, + TPC_COARSE_TXPWR_19, + TPC_COARSE_TXPWR_20, + TPC_COARSE_TXPWR_21, + TPC_COARSE_TXPWR_22, + TPC_COARSE_TXPWR_23, + TPC_COARSE_TXPWR_24, + TPC_COARSE_TXPWR_25, + TPC_COARSE_TXPWR_26, + TPC_COARSE_TXPWR_27, + TPC_COARSE_TXPWR_28, + TPC_COARSE_TXPWR_29, + TPC_COARSE_TXPWR_30, + TPC_COARSE_TXPWR_31, + NUM_TPC_COARSE_STEPS = TPC_COARSE_TXPWR_31 - TPC_COARSE_TXPWR_0 + 1, + MIN_TPC_COARSE_TXPWR = TPC_COARSE_TXPWR_0, + MAX_TPC_COARSE_TXPWR = TPC_COARSE_TXPWR_31 +}eTxCoarseGain; //refers to the external RF power adjustment + +typedef enum +{ + TPC_FINE_TXPWR_0, + TPC_FINE_TXPWR_1, + TPC_FINE_TXPWR_2, + TPC_FINE_TXPWR_3, + TPC_FINE_TXPWR_4, + TPC_FINE_TXPWR_5, + TPC_FINE_TXPWR_6, + TPC_FINE_TXPWR_7, + TPC_FINE_TXPWR_8, + TPC_FINE_TXPWR_9, + TPC_FINE_TXPWR_10, + TPC_FINE_TXPWR_11, + TPC_FINE_TXPWR_12, + TPC_FINE_TXPWR_13, + TPC_FINE_TXPWR_14, + TPC_FINE_TXPWR_15, + MIN_TPC_FINE_TXPWR = TPC_FINE_TXPWR_0, + MAX_TPC_FINE_TXPWR = TPC_FINE_TXPWR_15 +}eTxFineGain; //refers to the internal TxFIR power adjustment + +typedef PACKED_PRE struct PACKED_POST { + eTxCoarseGain coarsePwr; + eTxFineGain finePwr; +}tTxGain; + +//for 30second periodic interrupt, do this every 5 minutes +#define HAL_PHY_PERIODIC_CAL_ITER_LIMIT 10 + +typedef enum +{ + //these show which rx and tx chains are enabled, other chains are disable accordingly + //Production modes + PHY_CHAIN_SEL_R0_T0_ON, + + PHY_CHAIN_SEL_BT_R0_T0_ON, //simultaneous bluetooth receive enabled + + + //test modes + PHY_CHAIN_SEL_R0_ON, + PHY_CHAIN_SEL_T0_ON, + PHY_CHAIN_SEL_NO_RX_TX, + + MAX_PHY_CHAIN_SEL, + INVALID_PHY_CHAIN_SEL, + PHY_MAX_CHAIN_SELECT = 0x7FFFFFFF /* define as 4 bytes data */ +}ePhyChainSelect; + +typedef enum +{ +#ifdef CHANNEL_BONDED_CAPABLE + + PHY_CCA_40MHZ_SOURCE = 0, +#endif + + PHY_CCA_20MHZ_SOURCE = 1 +}ePhyCCASource; + +typedef enum +{ + PHY_CCA_FORCED_ON = 0, + PHY_CCA_ED = 1, + PHY_CCA_CD = 2, + PHY_CCA_CD_AND_CS = 3, + PHY_CCA_ED_AND_CD = 4, + PHY_CCA_ED_OR_CD = 5, + PHY_CCA_ED_AND_CD_AND_CS = 6, + PHY_CCA_ED_OR_CD_AND_CS = 7, + PHY_CCA_SEC_ED40_AND_NOR_PKTDET40_PKTDET20 = 8, + PHY_CCA_SEC_BUSY = 9 +}ePhyCCAMode; + +typedef enum +{ + PHY_RX_DISABLE_NONE = 0, + PHY_RX_DISABLE_11AG = 0x00000001, + PHY_RX_DISABLE_11B = 0x00000002, + PHY_RX_DISABLE_11N40 = 0x00000004, + PHY_RX_DISABLE_11AC80 = 0x00000008, + + PHY_RX_DISABLE_11ABG = (PHY_RX_DISABLE_11AG | PHY_RX_DISABLE_11B), + PHY_RX_DISABLE_ALL_TYPES = (PHY_RX_DISABLE_11B | PHY_RX_DISABLE_11AG | + PHY_RX_DISABLE_11N40 | PHY_RX_DISABLE_11AC80), +}ePhyRxDisabledPktTypes; + + +// Enum for network density setting. +typedef enum +{ + PHY_NW_DENSITY_LOW = 0, + PHY_NW_DENSITY_MED, + PHY_NW_DENSITY_HIGH, + PHY_NW_DENSITY_ADAPTIVE +} ePhyNwDensity; + + +typedef enum +{ + ALL_CALS, //RxDco 1st, TxLO 2nd + RX_DCO_CAL_ONLY, + RX_IM2_CAL_ONLY, + RX_DCO_IM2_CAL, + TX_LO_CAL_ONLY, + RX_IQ_CAL_ONLY, + TX_IQ_CAL_ONLY, + HKDAC_TX_IQ_CAL_ONLY, + NO_CALS = 0xFF +}eCalSelection; + + +//supports testing of closed-loop power control +typedef enum +{ + FORCE_CLOSED_LOOP_GAIN = 0, //phyDbg pkt gen only uses gain index 0 when we are taking measurements with the closed-loop gain + FORCE_POWER_TEMPLATE_INDEX = 1, //only use forced power template index + FIXED_POWER_DBM = 2, //only use to specify fixed power, ignoring rate/channel/reg limits + REGULATORY_POWER_LIMITS = 3, //use production power Lut settings limited by power limit table per channel + RATE_POWER_NON_LIMITED = 4, //use power specified per rate and channel group, but don't limit power by channel + POWER_INDX_SRC_MAX_VAL = 0x7FFFFFFF, //dummy val to set enum to 4 bytes +}ePowerTempIndexSource; + +#define BIT_0 0x00000001 +#define BIT_1 0x00000002 +#define BIT_2 0x00000004 +#define BIT_3 0x00000008 +#define BIT_4 0x00000010 +#define BIT_5 0x00000020 +#define BIT_6 0x00000040 +#define BIT_7 0x00000080 +#define BIT_8 0x00000100 +#define BIT_9 0x00000200 +#define BIT_10 0x00000400 +#define BIT_11 0x00000800 +#define BIT_12 0x00001000 +#define BIT_13 0x00002000 +#define BIT_14 0x00004000 +#define BIT_15 0x00008000 +#define BIT_16 0x00010000 +#define BIT_17 0x00020000 +#define BIT_18 0x00040000 +#define BIT_19 0x00080000 +#define BIT_20 0x00100000 +#define BIT_21 0x00200000 +#define BIT_22 0x00400000 +#define BIT_23 0x00800000 +#define BIT_24 0x01000000 +#define BIT_25 0x02000000 +#define BIT_26 0x04000000 +#define BIT_27 0x08000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +#define WFM_CLK_80 BIT_3 +#define WFM_START BIT_0 +#define WFM_STOP BIT_1 + +#define WFM_MEM_I_DATA_MASK (0x7FF) +#define WFM_MEM_Q_DATA_OFFSET (0xB) +#define WFM_MEM_Q_DATA_MASK (0x3FF800) + +typedef enum +{ + WAVE_SINGLE_SHOT = 0, + WAVE_CONTINUOUS = BIT_2 +}eWaveMode; + +typedef enum +{ + RATE_240 = 0, + RATE_160 = 1, + RATE_120 = 2, + RATE_80 = 3, + RATE_40 = 4, + RATE_20 = 5, +}eWaveRate; + +#define MAX_TONE_AMPLITUDE (2^11) // peak to peak + +#define MAX_TEST_WAVEFORM_SAMPLES 500 + +#define NUM_RX_IMB_CAL_TONES 4 + +#define CAL_WFM_TX_TONE_8_START_IDX 0 +#define CAL_WFM_TX_TONE_8_STOP_IDX 255 +#define CAL_WFM_TX_TONE_MINUS_8_START_IDX 256 +#define CAL_WFM_TX_TONE_MINUS_8_STOP_IDX 511 +#define CAL_WFM_RX_TONE_START_IDX 512 +#define CAL_WFM_RX_TONE_STOP_IDX 767 + +#define B_RATE_CAL_ADJUSTMENT -150 +#define GN_RATE_BANDEDGE_ADJUSTMENT -100 + +#define TPC_INDEX_WIFI_DIRECT 0 +#define TPC_INDEX_LOW_POWER 1 +#define MIN_TPC_GAIN_INDEX 0 //Index 0 used for Wifi Direct +#define TPC_GAIN_LUT_PWR_SLOPE 2 +#define MAX_TPC_GAIN_LUT_DBM (22) +#define MIN_TPC_GAIN_LUT_DBM (6) + +#define MAX_TPC_GAIN_LUT_DBM_2DEC_PLACES (MAX_TPC_GAIN_LUT_DBM * 100) +#define MIN_TPC_GAIN_LUT_DBM_2DEC_PLACES (MIN_TPC_GAIN_LUT_DBM * 100) + +typedef enum +{ + RF_BANDWIDTH_20MHZ = 20, + RF_BANDWIDTH_40MHZ = 40, + RF_BANDWIDTH_80MHZ = 80, + RF_MIN_BANDWIDTH = RF_BANDWIDTH_20MHZ, + RF_MAX_BANDWIDTH = RF_BANDWIDTH_80MHZ, + RF_BANDWIDTH_INVALID = 0x7FFFFFFF +}eRfBandwidth; + +#endif /* WLAN_PHY_H */ diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_qct_dev_defs.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_qct_dev_defs.h new file mode 100644 index 0000000000000..1f2e55304dada --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_qct_dev_defs.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * + * @file: wlan_qct_dev_defs.h + * + * @brief: This file contains the hardware related definitions. + * + */ + +#ifndef __WLAN_QCT_DEV_DEFS_H +#define __WLAN_QCT_DEV_DEFS_H + + +/* -------------------------------------------------------------------- + * HW definitions for WLAN Chip + * -------------------------------------------------------------------- + */ + +#ifdef WCN_PRONTO + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +//supports both V1 and V2 +#define HAL_NUM_ASSOC_STA 32 // HAL_NUM_STA - No of GP STAs - 2 (1 self Sta + 1 Bcast Sta) +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 + +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_UMA_DESC_ENTRIES HAL_NUM_HW_STA // or HAL_NUM_STA + +#define HAL_NUM_BSSID 2 +#define HAL_NUM_STA_WITHOUT_VSTA 12 +#define HAL_NUM_STA_INCLUDING_VSTA 32 + +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) +#define QWLANFW_MAX_NUM_VSTA (HAL_NUM_VSTA) +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA+1) +#define QWLAN_VSTA_MIN_IDX (HAL_NUM_HW_STA) +#define QWLANFW_NUM_GPSTA (HAL_NUM_GPSTA) + +// For Pronto +#define HAL_NUM_STA_WITHOUT_VSTA_PRONTO_V1 9 +#define HAL_NUM_STA_WITHOUT_VSTA_PRONTO_V2 (HAL_NUM_STA_WITHOUT_VSTA) + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + +#define GET_VSTA_INDEX_FOR_STA_INDEX(__idx) ((__idx) - QWLAN_VSTA_MIN_IDX) + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#define HAL_NUM_STA_INCLUDING_VSTA 32 + +#elif WCN_PRONTO_V1 + +/* In Pronto 1.0 TPE descriptor size is increased to 1K per station + * but not the cMEM allocated for hardware descriptors. Due to this + * memory limitation the number of stations are limited to 9 and BSS + * to 2 respectively. + * + * In Pronto 2.0, TPE descriptor size is reverted + * back to 512 bytes and hence more stations and BSSs can be supported + * from Pronto 2.0 + * + * In Pronto 1.0, 9 HW stations are supported including BCAST STA(staId 0) + * and SELF STA(staId 1). So total ASSOC stations which can connect to + * Pronto 1.0 Softap = 9 - 1(self sta) - 1(Bcast sta) = 7 stations + */ +#define HAL_NUM_HW_STA 9 +#define HAL_NUM_STA (HAL_NUM_HW_STA) +#define HAL_NUM_BSSID 2 +#define HAL_NUM_UMA_DESC_ENTRIES 9 +#define HAL_NUM_ASSOC_STA 7 + + +#else /* WCN_PRONTO_V1 */ + +#define HAL_NUM_HW_STA 14 +#define HAL_NUM_STA (HAL_NUM_HW_STA) +#define HAL_NUM_BSSID 4 +#define HAL_NUM_UMA_DESC_ENTRIES 14 +#define HAL_NUM_ASSOC_STA 12 + + +#endif /* WCN_PRONTO_V1 and WLAN_SOFTAP_VSTA_FEATURE*/ +#else /* WCN_PRONTO */ + +/* + * Riva supports 16 stations in hardware + * + * Riva without Virtual STA feature can only support 12 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 10 Soft AP Stations (hard) + * + * Riva with Virtual STA feature supports 38 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 4 General Purpose Stations to support Virtual STAs (hard) + * 32 Soft AP Stations (10 hard/22 virtual) + * + * To support concurrency with Vsta, number of stations are increased to 41 (from 38). + * 1 for the second interface. + * 1 for reserving an infra peer STA index (hard) for the other interface. + * 1 for P2P device role. + */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define HAL_NUM_ASSOC_STA 32 +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) + +#define QWLANFW_MAX_NUM_VSTA HAL_NUM_VSTA +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA+1) +#define QWLAN_VSTA_MIN_IDX HAL_NUM_HW_STA +#define QWLANFW_NUM_GPSTA HAL_NUM_GPSTA + + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + +#define GET_VSTA_INDEX_FOR_STA_INDEX(__idx) ((__idx) - QWLAN_VSTA_MIN_IDX) + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#define HAL_NUM_STA_INCLUDING_VSTA 32 +#define HAL_NUM_STA_WITHOUT_VSTA 12 + +#else +#define HAL_NUM_STA 12 +#define HAL_NUM_ASSOC_STA 10 +#define HAL_NUM_HW_STA 12 +#endif + +#define HAL_NUM_BSSID 2 +#define HAL_NUM_UMA_DESC_ENTRIES HAL_NUM_HW_STA + +#endif /* WCN_PRONTO */ + +#ifdef FEATURE_WLAN_TDLS +#define CXM_TDLS_MAX_NUM_STA 32 +#endif + +#define HAL_INVALID_BSSIDX HAL_NUM_BSSID + +#define MAX_NUM_OF_BACKOFFS 8 +#define HAL_MAX_ASSOC_ID HAL_NUM_STA + +#define WLANHAL_TX_BD_HEADER_SIZE 40 //FIXME_PRIMA - Revisit +#define WLANHAL_RX_BD_HEADER_SIZE 76 + +/* + * From NOVA Mac Arch document + * Encryp. mode The encryption mode + * 000: Encryption functionality is not enabled + * 001: Encryption is set to WEP + * 010: Encryption is set to WEP 104 + * 011: Encryption is set to TKIP + * 100: Encryption is set to AES + * 101 - 111: Reserved for future + */ + +#define HAL_ENC_POLICY_NULL 0 +#define HAL_ENC_POLICY_WEP40 1 +#define HAL_ENC_POLICY_WEP104 2 +#define HAL_ENC_POLICY_TKIP 3 +#define HAL_ENC_POLICY_AES_CCM 4 + +/* --------------------------------------------------------------------- */ +/* BMU */ +/* --------------------------------------------------------------------- */ + +/* + * BMU WQ assignment, as per Prima Programmer's Guide - FIXME_PRIMA: Revisit + * + */ + +typedef enum sBmuWqId { + + /* ====== In use WQs ====== */ + + /* BMU */ + BMUWQ_BMU_IDLE_BD = 0, + BMUWQ_BMU_IDLE_PDU = 1, + + /* RxP */ + BMUWQ_RXP_UNKNWON_ADDR = 2, /* currently unhandled by HAL */ + + /* DPU RX */ + BMUWQ_DPU_RX = 3, + + /* DPU TX */ + BMUWQ_DPU_TX = 6, + + /* Firmware */ + BMUWQ_FW_TRANSMIT = 12, /* DPU Tx->FW Tx */ + BMUWQ_FW_RECV = 7, /* DPU Rx->FW Rx */ + + BMUWQ_FW_RPE_RECV = 16, /* RXP/RPE Rx->FW Rx */ + FW_SCO_WQ = BMUWQ_FW_RPE_RECV, + + /* DPU Error */ + BMUWQ_DPU_ERROR_WQ = 8, + + /* DXE RX */ + BMUWQ_DXE_RX = 11, + + BMUWQ_DXE_RX_HI = 4, + + /* ADU/UMA */ + BMUWQ_ADU_UMA_TX = 23, + BMUWQ_ADU_UMA_RX = 24, + + /* BMU BTQM */ + BMUWQ_BTQM = 25, + + /* Special WQ for BMU to dropping all frames coming to this WQ ID */ + BMUWQ_SINK = 255, + +#ifdef WCN_PRONTO + BMUWQ_BMU_CMEM_IDLE_BD = 27, + /* Total BMU WQ count in Pronto */ + BMUWQ_NUM = 28, + + //WQs 17 through 22 are enabled in Pronto. So, set not supported mask to 0. + BMUWQ_NOT_SUPPORTED_MASK = 0x0, +#else + /* Total BMU WQ count in Prima */ + BMUWQ_NUM = 27, + + //Prima has excluded support for WQs 17 through 22. + BMUWQ_NOT_SUPPORTED_MASK = 0x7e0000, +#endif //WCN_PRONTO + + + /* Aliases */ + BMUWQ_BTQM_TX_MGMT = BMUWQ_BTQM, + BMUWQ_BTQM_TX_DATA = BMUWQ_BTQM, + BMUWQ_BMU_WQ2 = BMUWQ_RXP_UNKNWON_ADDR, + BMUWQ_FW_DPU_TX = 5, + + //WQ where all the frames with addr1/addr2/addr3 with value 254/255 go to. + BMUWQ_FW_RECV_EXCEPTION = 14, //using BMUWQ_FW_MESSAGE WQ for this purpose. + + //WQ where all frames with unknown Addr2 filter exception cases frames will pushed if FW wants host to + //send deauth to the sender. + BMUWQ_HOST_RX_UNKNOWN_ADDR2_FRAMES = 15, //using BMUWQ_FW_DXECH2_0 for this purpose. + + /* ====== Unused/Reserved WQ ====== */ + + /* ADU/UMA Error WQ */ + BMUWQ_ADU_UMA_TX_ERROR_WQ = 13, /* Not in use by HAL */ + BMUWQ_ADU_UMA_RX_ERROR_WQ = 10, /* Not in use by HAL */ + + /* DPU Error WQ2 */ + BMUWQ_DPU_ERROR_WQ2 = 9, /* Not in use by HAL */ + + /* FW WQs */ + //This WQ is being used for RXP to push in frames in exception cases ( addr1/add2/addr3 254/255) + //BMUWQ_FW_MESG = 14, /* DxE Tx->FW, Not in use by FW */ + //BMUWQ_FW_DXECH2_0 = 15, /* BD/PDU<->MEM conversion using DxE CH2. Not in use by FW */ + BMUWQ_FW_DXECH2_1 = 16, /* BD/PDU<->MEM conversion using DxE CH2. Not in use by FW */ + + /* NDPA Addr3 workaround */ + BMUWQ_RXP_DEFAULT_PUSH_WQ = 17, +/* These WQs are not supported in Volans + BMUWQ_BMU_WQ17 = 17, + BMUWQ_BMU_WQ18 = 18, + BMUWQ_BMU_WQ19 = 19, + BMUWQ_BMU_WQ20 = 20, + BMUWQ_BMU_WQ21 = 21, + BMUWQ_BMU_WQ22 = 22 +*/ +} tBmuWqId; + +typedef enum +{ + BTQM_QID0 = 0, + BTQM_QID1, + BTQM_QID2, + BTQM_QID3, + BTQM_QID4, + BTQM_QID5, + BTQM_QID6, + BTQM_QID7, + BTQM_QID8, + BTQM_QID9, + BTQM_QID10, + + BTQM_QUEUE_TX_TID_0 = BTQM_QID0, + BTQM_QUEUE_TX_TID_1, + BTQM_QUEUE_TX_TID_2, + BTQM_QUEUE_TX_TID_3, + BTQM_QUEUE_TX_TID_4, + BTQM_QUEUE_TX_TID_5, + BTQM_QUEUE_TX_TID_6, + BTQM_QUEUE_TX_TID_7, + + + /* Queue Id <-> BO + */ + BTQM_QUEUE_TX_nQOS = BTQM_QID8, + BTQM_QUEUE_SELF_STA_BCAST_MGMT = BTQM_QID10, + BTQM_QUEUE_SELF_STA_UCAST_MGMT = BTQM_QID9, + BTQM_QUEUE_SELF_STA_UCAST_DATA = BTQM_QID9, + BTQM_QUEUE_NULL_FRAME = BTQM_QID9, + BTQM_QUEUE_SELF_STA_PROBE_RSP = BTQM_QID9, + BTQM_QUEUE_TX_AC_BE = BTQM_QUEUE_TX_TID_0, + BTQM_QUEUE_TX_AC_BK = BTQM_QUEUE_TX_TID_2, + BTQM_QUEUE_TX_AC_VI = BTQM_QUEUE_TX_TID_4, + BTQM_QUEUE_TX_AC_VO = BTQM_QUEUE_TX_TID_6 +}tBtqmQId; + +#define STACFG_MAX_TC 8 + +/* --------------------------------------------------------------------- */ +/* BD type*/ +/* --------------------------------------------------------------------- */ +#define HWBD_TYPE_GENERIC 0 /* generic BD format */ +#define HWBD_TYPE_FRAG 1 /* fragmentation BD format*/ + +/*---------------------------------------------------------------------- */ +/* HW Tx power */ +/*---------------------------------------------------------------------- */ +#ifdef WLAN_HAL_PRIMA + #define WLAN_SOC_PRIMA_MAX_TX_POWER 22 + #define WLAN_SOC_PRIMA_MIN_TX_POWER 6 +#else + /* add more platforms here */ + #define WLAN_SOC_PRIMA_MAX_TX_POWER 22 + #define WLAN_SOC_PRIMA_MIN_TX_POWER 6 +#endif //#ifdef WCN_PRIMA + +#endif /* __WLAN_QCT_DEV_DEFS_H */ diff --git a/drivers/staging/qcacld-2.0/wcnss/inc/wlan_status_code.h b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_status_code.h new file mode 100644 index 0000000000000..9b452253e2e0f --- /dev/null +++ b/drivers/staging/qcacld-2.0/wcnss/inc/wlan_status_code.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + * + * @file: wlan_status_code.h + * + * @brief: Common header file containing all the status codes + * All status codes have been consolidated into one enum + * + * @author: Kumar Anand + * + *=========================================================================*/ + +#ifndef __WLAN_STATUS_CODE_H__ +#define __WLAN_STATUS_CODE_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/* This is to force compiler to use the maximum of an int ( 4 bytes ) */ +#define WLAN_STATUS_MAX_ENUM_SIZE 0x7FFFFFFF + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +typedef enum +{ + /* PAL Request succeeded!*/ + PAL_STATUS_SUCCESS = 0, + + /* HAL Request succeeded!*/ + eHAL_STATUS_SUCCESS = 0, + + /* Request failed because there of an invalid request. This is + typically the result of invalid parameters on the request*/ + PAL_STATUS_INVAL, + + /* Request refused because a request is already in place and + another cannot be handled currently */ + PAL_STATUS_ALREADY, + + /* Request failed because of an empty condition */ + PAL_STATUS_EMPTY, + + /* Request failed for some unknown reason. */ + PAL_STATUS_FAILURE, + + /* HAL general failure */ + eHAL_STATUS_FAILURE, + + /* Invalid Param*/ + eHAL_STATUS_INVALID_PARAMETER, + + /* Invalid Station Index*/ + eHAL_STATUS_INVALID_STAIDX, + + /* DPU descriptor table full*/ + eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL, + + /* No interrupts */ + eHAL_STATUS_NO_INTERRUPTS, + + /* Interrupt present */ + eHAL_STATUS_INTERRUPT_PRESENT, + + /* Stable Table is full */ + eHAL_STATUS_STA_TABLE_FULL, + + /* Duplicate Station found */ + eHAL_STATUS_DUPLICATE_STA, + + /* BSSID is invalid */ + eHAL_STATUS_BSSID_INVALID, + + /* STA is invalid */ + eHAL_STATUS_STA_INVALID, + + /* BSSID is is duplicate */ + eHAL_STATUS_DUPLICATE_BSSID, + + /* BSS Idx is invalid */ + eHAL_STATUS_INVALID_BSSIDX, + + /* BSSID Table is full */ + eHAL_STATUS_BSSID_TABLE_FULL, + + /* Invalid DPU signature*/ + eHAL_STATUS_INVALID_SIGNATURE, + + /* Invalid key Id */ + eHAL_STATUS_INVALID_KEYID, + + /* Already on requested channel */ + eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN, + + /* UMA descriptor table is full */ + eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL, + + /* MIC Key table is full */ + eHAL_STATUS_DPU_MICKEY_TABLE_FULL, + + /* A-MPDU/BA related Error codes */ + eHAL_STATUS_BA_RX_BUFFERS_FULL, + eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED, + eHAL_STATUS_BA_RX_INVALID_SESSION_ID, + + eHAL_STATUS_TIMER_START_FAILED, + eHAL_STATUS_TIMER_STOP_FAILED, + eHAL_STATUS_FAILED_ALLOC, + + /* Scan failure codes */ + eHAL_STATUS_NOTIFY_BSS_FAIL, + + /* Self STA not deleted as reference count is not zero */ + eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO, + + /* Self STA not added as entry already exists*/ + eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO, + + /* Message from SLM has failure status */ + eHAL_STATUS_FW_SEND_MSG_FAILED, + + /* BSS disconnect status : beacon miss */ + eHAL_STATUS_BSS_DISCONN_BEACON_MISS, + /* BSS disconnect status : deauth */ + eHAL_STATUS_BSS_DISCONN_DEAUTH, + /* BSS disconnect status : disassoc */ + eHAL_STATUS_BSS_DISCONN_DISASSOC, + + /* Data abort happened in PHY sw */ + eHAL_STATUS_PHY_DATA_ABORT, + + /* Invalid NV field */ + eHAL_STATUS_PHY_INVALID_NV_FIELD, + + /* WLAN boot test failed */ + eHAL_STATUS_WLAN_BOOT_TEST_FAILURE, + + /* Max status value */ + eHAL_STATUS_MAX_VALUE = WLAN_STATUS_MAX_ENUM_SIZE + +} palStatus, eHalStatus; + +/* Helper Macros */ +#define PAL_IS_STATUS_SUCCESS(status) (PAL_STATUS_SUCCESS == (status)) +#define HAL_STATUS_SUCCESS( status ) (eHAL_STATUS_SUCCESS == (status)) + +#endif //__WLAN_STATUS_CODE_H__ diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c index d1e399743861a..ead9bae81c6c4 100644 --- a/drivers/thermal/msm_thermal.c +++ b/drivers/thermal/msm_thermal.c @@ -2990,7 +2990,9 @@ static int hotplug_notify(enum thermal_trip_type type, int temp, void *data) pr_info_ratelimited("%s reach temp threshold: %d\n", cpu_node->sensor_type, temp); - +#ifdef VENDOR_EDIT + pr_debug("%s reach temp threshold: %d\n", cpu_node->sensor_type, temp); +#endif if (!(msm_thermal_info.core_control_mask & BIT(cpu_node->cpu))) return 0; switch (type) { diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c index ab4ff682095a8..cddacb3cd5834 100644 --- a/drivers/tty/serial/msm_serial_hs_lite.c +++ b/drivers/tty/serial/msm_serial_hs_lite.c @@ -1963,6 +1963,14 @@ static int __init msm_serial_hsl_init(void) { int ret; +//add by jiachenghui for unregister uart driver by cmdline, 2015-4-23 +#ifdef VENDOR_EDIT + printk("msm_serial_hsl_init:%d\n",console_set_on_cmdline); + if(!console_set_on_cmdline) + return -EPERM; +#endif +//end add by jiachenghui for unregister uart driver by cmdline, 2015-4-23 + ret = uart_register_driver(&msm_hsl_uart_driver); if (unlikely(ret)) return ret; diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c old mode 100644 new mode 100755 index 6c21037d3f6e5..3ed9992fec483 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -77,7 +77,11 @@ module_param(override_phy_init, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(override_phy_init, "Override HSPHY Init Seq"); /* Enable Proprietary charger detection */ +#ifdef VENDOR_EDIT +static bool prop_chg_detect=1; +#else static bool prop_chg_detect; +#endif module_param(prop_chg_detect, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(prop_chg_detect, "Enable Proprietary charger detection"); @@ -1454,7 +1458,7 @@ static void dwc3_chg_detect_work(struct work_struct *w) mdwc->ext_chg_active = true; } } - dev_dbg(mdwc->dev, "chg_type = %s\n", + dev_err(mdwc->dev, "chg_type = %s\n", chg_to_string(mdwc->charger.chg_type)); mdwc->charger.notify_detection_complete(mdwc->otg_xceiv->otg, &mdwc->charger); @@ -2388,7 +2392,8 @@ static int dwc3_msm_power_set_property_usb(struct power_supply *psy, if (mdwc->charger.chg_type != DWC3_INVALID_CHARGER) mdwc->chg_state = USB_CHG_STATE_DETECTED; - dev_dbg(mdwc->dev, "%s: charger type: %s\n", __func__, + + dev_info(mdwc->dev, "%s: charger type: %s\n", __func__, chg_to_string(mdwc->charger.chg_type)); break; case POWER_SUPPLY_PROP_HEALTH: diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c old mode 100644 new mode 100755 index cfa3c19443ea9..aaf6d354b5a02 --- a/drivers/usb/dwc3/dwc3_otg.c +++ b/drivers/usb/dwc3/dwc3_otg.c @@ -25,6 +25,61 @@ #include "debug.h" #include "xhci.h" +//add by jiachenghui for otg switch, 2015-5-6 +#ifdef VENDOR_EDIT +#include +#include +int otg_switch; +struct dwc3_otg *gdotg;//add by jch for otg swith retest id,2015-6-5 +#if 0 + static ssize_t proc_otg_switch_all_read(struct file *f, char __user *buf,size_t count, loff_t *ppos) +{ + char values[] = { '0' + otg_switch, '\n' }; + printk("OTG: the otg switch is:%d\n",otg_switch); + return simple_read_from_buffer(buf, count, ppos, values, sizeof(values)); + +} + +static ssize_t proc_otg_switch_all_write(struct file *f, const char __user *buf, size_t count, loff_t *ppos) +{ + char temp[1] = {0}; + + if (copy_from_user(temp, buf, 1)) + return -EFAULT; + + sscanf(temp, "%d", &otg_switch); + + if (!strncasecmp(&temp[0], "0", 1)) { + printk("OTG: disable!\n"); + //cancel_delayed_work_sync(&dotg->sm_work); + }else if (!strncasecmp(&temp[0], "1", 1)){ + printk("OTG: enable!\n"); + //INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work); + } + + printk("OTG:write the otg switch to :%d\n",otg_switch); + return count; +} + +static const struct file_operations otg_knob_fops = { + .open = simple_open, + .read = proc_otg_switch_all_read, + .write = proc_otg_switch_all_write, +}; +#endif + +static inline int oem_test_id(int nr, const volatile unsigned long *addr) +{ + if (0 == otg_switch) { + //printk("OTG test id is disable!\n"); + return 1; + } else { + return test_bit(nr, addr); + } +} +#endif +//end add by jiachenghui for otg switch, 2015-5-6 + #define VBUS_REG_CHECK_DELAY (msecs_to_jiffies(1000)) #define MAX_INVALID_CHRGR_RETRY 3 static int max_chgr_retry_count = MAX_INVALID_CHRGR_RETRY; @@ -406,35 +461,43 @@ static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA) if (dotg->charger->charging_disabled) return 0; - +#ifndef VENDOR_EDIT if (dotg->charger->chg_type != DWC3_INVALID_CHARGER) { dev_dbg(phy->dev, "SKIP setting power supply type again,chg_type = %d\n", dotg->charger->chg_type); goto skip_psy_type; } - +#endif if (dotg->charger->chg_type == DWC3_SDP_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_CDP_CHARGER) - power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; +#ifdef VENDOR_EDIT + power_supply_type = POWER_SUPPLY_TYPE_USB; else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || + dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER || + dotg->charger->chg_type == DWC3_FLOATED_CHARGER) + power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; +#else + power_supply_type = POWER_SUPPLY_TYPE_USB_CDP; +else if (dotg->charger->chg_type == DWC3_DCP_CHARGER || dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER) power_supply_type = POWER_SUPPLY_TYPE_USB_DCP; +#endif else power_supply_type = POWER_SUPPLY_TYPE_UNKNOWN; power_supply_set_supply_type(dotg->psy, power_supply_type); - +#ifndef VENDOR_EDIT skip_psy_type: - +#endif if (dotg->charger->chg_type == DWC3_CDP_CHARGER) mA = DWC3_IDEV_CHG_MAX; if (dotg->charger->max_power == mA) return 0; - dev_info(phy->dev, "Avail curr from USB = %u\n", mA); + dev_err(phy->dev, "Avail curr from USB = %u\n", mA); if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) { /* Disable charging */ @@ -523,7 +586,13 @@ static void dwc3_otg_sm_work(struct work_struct *w) } /* Switch to A or B-Device according to ID / BSV */ + //add by jiachenghui for otg switch, 2015-5-8 + #ifdef VENDOR_EDIT + if (!oem_test_id(ID, &dotg->inputs)) { + #else + //end add by jiachenghui for otg switch, 2015-5-8 if (!test_bit(ID, &dotg->inputs)) { + #endif//add by jiachenghui for otg switch, 2015-5-8 dev_dbg(phy->dev, "!id\n"); phy->state = OTG_STATE_A_IDLE; work = 1; @@ -540,7 +609,13 @@ static void dwc3_otg_sm_work(struct work_struct *w) break; case OTG_STATE_B_IDLE: + //add by jiachenghui for otg switch, 2015-5-8 + #ifdef VENDOR_EDIT + if (!oem_test_id(ID, &dotg->inputs)) { + #else + //end add by jiachenghui for otg switch, 2015-5-8 if (!test_bit(ID, &dotg->inputs)) { + #endif//add by jiachenghui for otg switch, 2015-5-8 dev_dbg(phy->dev, "!id\n"); phy->state = OTG_STATE_A_IDLE; work = 1; @@ -564,7 +639,11 @@ static void dwc3_otg_sm_work(struct work_struct *w) dwc3_otg_set_power(phy, dcp_max_current); dbg_event(0xFF, "PROPCHG put", 0); + #ifdef VENDOR_EDIT //yangfangbiao@oneplus.cn, 20150613 + //do nothing ,do not need to let system suspend + #else pm_runtime_put_sync(phy->dev); + #endif break; case DWC3_CDP_CHARGER: dwc3_otg_set_power(phy, @@ -575,6 +654,7 @@ static void dwc3_otg_sm_work(struct work_struct *w) work = 1; break; case DWC3_SDP_CHARGER: + dwc3_otg_set_power(phy,DWC3_SDP_CHG_MAX); dwc3_otg_start_peripheral(&dotg->otg, 1); phy->state = OTG_STATE_B_PERIPHERAL; @@ -595,9 +675,13 @@ static void dwc3_otg_sm_work(struct work_struct *w) */ if (dotg->charger_retry_count == max_chgr_retry_count) { + #ifdef VENDOR_EDIT //yangfb add to set charge current to FLOATED_CHARGER ,20150805 + dwc3_otg_set_power(phy, DWC3_IDEV_CHG_MAX); + #else dwc3_otg_set_power(phy, 0); + #endif dbg_event(0xFF, "FLCHG put", 0); - pm_runtime_put_sync(phy->dev); + //pm_runtime_put_sync(phy->dev); ////do nothing ,do not need to let system suspend break; } charger->start_detection(dotg->charger, @@ -641,8 +725,15 @@ static void dwc3_otg_sm_work(struct work_struct *w) break; case OTG_STATE_B_PERIPHERAL: + //add by jiachenghui for otg switch, 2015-5-8 + #ifdef VENDOR_EDIT + if (!test_bit(B_SESS_VLD, &dotg->inputs) || + !oem_test_id(ID, &dotg->inputs)) { + #else + //end add by jiachenghui for otg switch, 2015-5-8 if (!test_bit(B_SESS_VLD, &dotg->inputs) || !test_bit(ID, &dotg->inputs)) { + #endif//add by jiachenghui for otg switch, 2015-5-8 dev_dbg(phy->dev, "!id || !bsv\n"); dwc3_otg_start_peripheral(&dotg->otg, 0); phy->state = OTG_STATE_B_IDLE; @@ -658,7 +749,13 @@ static void dwc3_otg_sm_work(struct work_struct *w) case OTG_STATE_A_IDLE: /* Switch to A-Device*/ + //add by jiachenghui for otg switch, 2015-5-8 + #ifdef VENDOR_EDIT + if (oem_test_id(ID, &dotg->inputs)) { + #else + //end add by jiachenghui for otg switch, 2015-5-8 if (test_bit(ID, &dotg->inputs)) { + #endif//add by jiachenghui for otg switch, 2015-5-8 dev_dbg(phy->dev, "id\n"); phy->state = OTG_STATE_B_IDLE; dotg->vbus_retry_count = 0; @@ -698,7 +795,13 @@ static void dwc3_otg_sm_work(struct work_struct *w) break; case OTG_STATE_A_HOST: + //add by jiachenghui for otg switch, 2015-5-8 + #ifdef VENDOR_EDIT + if (oem_test_id(ID, &dotg->inputs)) { + #else + //end add by jiachenghui for otg switch, 2015-5-8 if (test_bit(ID, &dotg->inputs)) { + #endif//add by jiachenghui for otg switch, 2015-5-8 dev_dbg(phy->dev, "id\n"); dwc3_otg_start_host(&dotg->otg, 0); phy->state = OTG_STATE_B_IDLE; @@ -721,16 +824,158 @@ static void dwc3_otg_sm_work(struct work_struct *w) queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay); } +//add by jch for otg swith retest id,2015-6-5 +#ifdef VENDOR_EDIT + +static void oem_ext_event_notify(struct usb_otg *otg,enum dwc3_ext_events event,enum dwc3_id_state id) +{ + static bool init; + struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); + struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv; + struct usb_phy *phy = dotg->otg.phy; + int ret = 0; + + /* Flush processing any pending events before handling new ones */ + if (init) + flush_delayed_work(&dotg->sm_work); + + if (event == DWC3_EVENT_PHY_RESUME) { + if (!pm_runtime_status_suspended(phy->dev)) + dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n"); + + dev_dbg(phy->dev, "ext PHY_RESUME event received\n"); + /* ext_xceiver would have taken h/w out of LPM by now */ + ret = pm_runtime_get(phy->dev); + dbg_event(0xFF, "PhyRes get", ret); + if (ret == -EACCES) { + /* pm_runtime_get may fail during system + resume with -EACCES error */ + pm_runtime_disable(phy->dev); + pm_runtime_set_active(phy->dev); + pm_runtime_enable(phy->dev); + } else if (ret < 0) { + dev_warn(phy->dev, "pm_runtime_get failed!\n"); + } + } else if (event == DWC3_EVENT_XCEIV_STATE) { + if (pm_runtime_status_suspended(phy->dev) || + atomic_read(&phy->dev->power.usage_count) == 0) { + dev_dbg(phy->dev, "ext XCEIV_STATE while runtime_status=%d\n", + phy->dev->power.runtime_status); + ret = pm_runtime_get(phy->dev); + dbg_event(0xFF, "Xceiv get", ret); + if (ret < 0) + dev_warn(phy->dev, "pm_runtime_get failed!!\n"); + } + if (id == DWC3_ID_FLOAT) { + dev_dbg(phy->dev, "XCVR: ID set\n"); + set_bit(ID, &dotg->inputs); + } else { + dev_dbg(phy->dev, "XCVR: ID clear\n"); + clear_bit(ID, &dotg->inputs); + } + + if (ext_xceiv->bsv) { + dev_dbg(phy->dev, "XCVR: BSV set\n"); + set_bit(B_SESS_VLD, &dotg->inputs); + } else { + dev_dbg(phy->dev, "XCVR: BSV clear\n"); + clear_bit(B_SESS_VLD, &dotg->inputs); + } + + if (!init) { + init = true; + if (!work_busy(&dotg->sm_work.work)) + queue_delayed_work(system_nrt_wq, + &dotg->sm_work, 0); + + complete(&dotg->dwc3_xcvr_vbus_init); + dev_dbg(phy->dev, "XCVR: BSV init complete\n"); + return; + } + + queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0); + } +} + + +void enable_otg_event(bool enable ) +{ + struct dwc3_ext_xceiv *ext_xceiv = gdotg->ext_xceiv; + struct usb_phy *otg_xceiv = gdotg->otg.phy; + enum dwc3_id_state id; + if(!ext_xceiv->id){ + if (enable== true) { + id = DWC3_ID_GROUND; + } else { + id = DWC3_ID_FLOAT; + } + + if (otg_xceiv) + oem_ext_event_notify(otg_xceiv->otg, DWC3_EVENT_XCEIV_STATE,id); + } +} + static ssize_t proc_otg_switch_all_read(struct file *f, char __user *buf,size_t count, loff_t *ppos) +{ + char values[] = { '0' + otg_switch, '\n' }; + printk("OTG: the otg switch is:%d\n",otg_switch); + return simple_read_from_buffer(buf, count, ppos, values, sizeof(values)); + +} + +static ssize_t proc_otg_switch_all_write(struct file *f, const char __user *buf, size_t count, loff_t *ppos) +{ + char temp[1] = {0}; + + if (copy_from_user(temp, buf, 1)) + return -EFAULT; + + sscanf(temp, "%d", &otg_switch); + + if (!strncasecmp(&temp[0], "0", 1)) { + printk("OTG: disable!\n"); + enable_otg_event(false); + }else if (!strncasecmp(&temp[0], "1", 1)){ + printk("OTG: enable!\n"); + enable_otg_event(true); + } + + printk("OTG:write the otg switch to :%d\n",otg_switch); + return count; +} + +static const struct file_operations otg_knob_fops = { + .open = simple_open, + .read = proc_otg_switch_all_read, + .write = proc_otg_switch_all_write, +}; +#endif +//end add by jch for otg swith retest id,2015-6-5 + /** * dwc3_otg_init - Initializes otg related registers * @dwc: Pointer to out controller context structure * * Returns 0 on success otherwise negative errno. */ + int dwc3_otg_init(struct dwc3 *dwc) { struct dwc3_otg *dotg; +//add by jiachenghui for otg switch, 2015-5-6 +#ifdef VENDOR_EDIT + static struct proc_dir_entry *proc_otg_dir = NULL; + otg_switch = 0; + proc_otg_dir = proc_mkdir("otg_config", NULL); + if (!proc_otg_dir) { + printk("OTG:%s: unable to create otg_config directory\n", __func__); + } + if (!proc_create("otg_switch", ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ), proc_otg_dir,&otg_knob_fops)){ + printk(KERN_ERR "OTG: creat otg_switch fail!\n"); + } +#endif +//end add by jiachenghui for otg switch, 2015-5-6 + dev_dbg(dwc->dev, "dwc3_otg_init\n"); /* Allocate and init otg instance */ @@ -763,6 +1008,12 @@ int dwc3_otg_init(struct dwc3 *dwc) init_completion(&dotg->dwc3_xcvr_vbus_init); INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work); +//add by jch for otg swith retest id,2015-6-5 +#ifdef VENDOR_EDIT + gdotg = dotg;//add by jch for otg swith retest id,2015-6-5 +#endif +//end add by jch for otg swith retest id,2015-6-5 + dbg_event(0xFF, "OTGInit get", 0); pm_runtime_get(dwc->dev); diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h old mode 100644 new mode 100755 index ed9e182a6fdd0..2cd162dd81ca5 --- a/drivers/usb/dwc3/dwc3_otg.h +++ b/drivers/usb/dwc3/dwc3_otg.h @@ -24,7 +24,7 @@ #define DWC3_IDEV_CHG_MAX 1500 #define DWC3_HVDCP_CHG_MAX 1800 - +#define DWC3_SDP_CHG_MAX 500 /* * Module param to override current drawn for DCP charger * Declared in dwc3-msm module diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c old mode 100644 new mode 100755 index bf788f7def97d..3059471f81abb --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2955,7 +2955,7 @@ void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend) static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) { u32 reg; - struct dwc3_otg *dotg = dwc->dotg; +// struct dwc3_otg *dotg = dwc->dotg; dev_vdbg(dwc->dev, "%s\n", __func__); @@ -3000,8 +3000,10 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_gadget_usb3_phy_suspend(dwc, false); +#if 0 if (dotg && dotg->otg.phy) usb_phy_set_power(dotg->otg.phy, 0); +#endif if (dwc->gadget.speed != USB_SPEED_UNKNOWN) dwc3_disconnect_gadget(dwc); diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c old mode 100644 new mode 100755 index d9dc7ae57e021..cafcedd722348 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -651,9 +651,27 @@ static int functionfs_ready_callback(struct ffs_data *ffs) /* Save dev in case the adb function will get disabled */ config->dev = dev; +#ifndef VENDOR_EDIT//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 if (config->enabled) android_enable(dev); +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#else + if (config->enabled){ + ret = android_enable(dev); + if (ret) { + pr_err("%s: failed to enable android, err:%d\n", __func__,ret); + functionfs_unbind(ffs); + config->dev = NULL; + config->opened = false; + config->data = NULL; + if (dev) + mutex_unlock(&dev->mutex); + return ret; + } + } +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 mutex_unlock(&dev->mutex); return 0; @@ -2427,9 +2445,15 @@ static int mass_storage_function_init(struct android_usb_function *f, return -ENOMEM; } +#ifndef VENDOR_EDIT//add by jiachenghui for USB VID customized & cdrom,2015-05-25 config->fsg.nluns = 1; snprintf(name[0], MAX_LUN_NAME, "lun"); config->fsg.luns[0].removable = 1; +//add by jiachenghui for USB VID customized & cdrom,2015-05-25 +#else + config->fsg.nluns = 0; +#endif +//add by jiachenghui for USB VID customized & cdrom,2015-05-25 if (dev->pdata && dev->pdata->cdrom) { config->fsg.luns[config->fsg.nluns].cdrom = 1; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c old mode 100644 new mode 100755 index 241973ef40dca..c15a3ceebdaae --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1844,7 +1844,7 @@ composite_suspend(struct usb_gadget *gadget) cdev->suspended = 1; - usb_gadget_vbus_draw(gadget, 2); + //usb_gadget_vbus_draw(gadget, 2); } static void diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c old mode 100644 new mode 100755 index e9659dd634f0c..5c6c6f7d9f55e --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -937,7 +937,8 @@ static ssize_t ffs_epfile_io(struct file *file, error: kfree(data); if (ret < 0) - pr_err("Error: returning %zd value\n", ret); + pr_err_ratelimited("%s(): Error: returning %zd value\n", + __func__, ret); return ret; } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 9ec55e9b5e2b7..12495189ee853 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -1351,12 +1351,257 @@ static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh) return 8; } + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 +#ifdef VENDOR_EDIT +static void _lba_to_msf(u8 *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static int _read_toc_raw(struct fsg_common *common, struct fsg_buffhd *bh) +{ + struct fsg_lun *curlun = common->curlun; + int msf = common->cmnd[1] & 0x02; + u8 *buf = (u8 *) bh->buf; + + u8 *q; + int len; + + q = buf + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* first track */ + *q++ = 0x00; /* disk type */ + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa1; + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* last track */ + *q++ = 0x00; + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa2; /* lead-out */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + if (msf) { + *q++ = 0; /* reserved */ + _lba_to_msf(q, curlun->num_sectors); + q += 3; + } else { + put_unaligned_be32(curlun->num_sectors, q); + q += 4; + } + + *q++ = 1; /* session number */ + *q++ = 0x14; /* ADR, control */ + *q++ = 0; /* track number */ + *q++ = 1; /* point */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + if (msf) { + *q++ = 0; + _lba_to_msf(q, 0); + q += 3; + } else { + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + + len = q - buf; + put_unaligned_be16(len - 2, buf); + + return len; +} + +static void cd_data_to_raw(u8 *buf, int lba) +{ + /* sync bytes */ + buf[0] = 0x00; + memset(buf + 1, 0xff, 10); + buf[11] = 0x00; + buf += 12; + /* MSF */ + _lba_to_msf(buf, lba); + buf[3] = 0x01; /* mode 1 data */ + buf += 4; + /* data */ + buf += 2048; + /* XXX: ECC not computed */ + memset(buf, 0, 288); +} + +static int do_read_cd(struct fsg_common *common) +{ + struct fsg_lun *curlun = common->curlun; + u32 lba; + struct fsg_buffhd *bh; + int rc; + u32 amount_left; + loff_t file_offset, file_offset_tmp; + unsigned int amount; + unsigned int partial_page; + ssize_t nread; + + u32 nb_sectors, transfer_request; + + nb_sectors = (common->cmnd[6] << 16) | + (common->cmnd[7] << 8) | common->cmnd[8]; + lba = get_unaligned_be32(&common->cmnd[2]); + + if (nb_sectors == 0) + return 0; + + if (lba >= curlun->num_sectors) { + curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + return -EINVAL; + } + + transfer_request = common->cmnd[9]; + if ((transfer_request & 0xf8) == 0xf8) { + file_offset = ((loff_t) lba) << 11; + /* read all data - 2352 byte */ + amount_left = 2352; + } else { + file_offset = ((loff_t) lba) << 9; + /* Carry out the file reads */ + amount_left = common->data_size_from_cmnd; + } + + if (unlikely(amount_left == 0)) + return -EIO; /* No default reply */ + + for (;;) { + + /* Figure out how much we need to read: + * Try to read the remaining amount. + * But don't read more than the buffer size. + * And don't try to read past the end of the file. + * Finally, if we're not at a page boundary, don't read past + * the next page. + * If this means reading 0 then we were asked to read past + * the end of file. */ + amount = min(amount_left, FSG_BUFLEN); + amount = min((loff_t) amount, + curlun->file_length - file_offset); + partial_page = file_offset & (PAGE_CACHE_SIZE - 1); + if (partial_page > 0) + amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - + partial_page); + + /* Wait for the next buffer to become available */ + bh = common->next_buffhd_to_fill; + while (bh->state != BUF_STATE_EMPTY) { + rc = sleep_thread(common); + if (rc) + return rc; + } + + /* If we were asked to read past the end of file, + * end with an empty buffer. */ + if (amount == 0) { + curlun->sense_data = + SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; + bh->inreq->length = 0; + bh->state = BUF_STATE_FULL; + break; + } + + /* Perform the read */ + file_offset_tmp = file_offset; + if ((transfer_request & 0xf8) == 0xf8) { + nread = vfs_read(curlun->filp, + ((char __user *)bh->buf)+16, + amount, &file_offset_tmp); + } else { + nread = vfs_read(curlun->filp, + (char __user *)bh->buf, + amount, &file_offset_tmp); + } + VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, + (int) nread); + if (signal_pending(current)) + return -EINTR; + + if (nread < 0) { + LDBG(curlun, "error in file read: %d\n", + (int) nread); + nread = 0; + } else if (nread < amount) { + LDBG(curlun, "partial file read: %d/%u\n", + (int) nread, amount); + nread -= (nread & 511); /* Round down to a block */ + } + file_offset += nread; + amount_left -= nread; + common->residue -= nread; + bh->inreq->length = nread; + bh->state = BUF_STATE_FULL; + + /* If an error occurred, report it and its position */ + if (nread < amount) { + curlun->sense_data = SS_UNRECOVERED_READ_ERROR; + curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; + break; + } + + if (amount_left == 0) + break; /* No more left to read */ + + /* Send this buffer and go read some more */ + if (!start_in_transfer(common, bh)) + /* Don't know what to do if common->fsg is NULL */ + return -EIO; + common->next_buffhd_to_fill = bh->next; + } + + if ((transfer_request & 0xf8) == 0xf8) + cd_data_to_raw(bh->buf, lba); + + return -EIO; /* No default reply */ +} +#endif +//end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 + static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) { struct fsg_lun *curlun = common->curlun; int msf = common->cmnd[1] & 0x02; int start_track = common->cmnd[6]; u8 *buf = (u8 *)bh->buf; + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 + #ifdef VENDOR_EDIT + int format = (common->cmnd[9] & 0xC0) >> 6; +#endif +//end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ start_track > 1) { @@ -1364,6 +1609,12 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) return -EINVAL; } + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 + #ifdef VENDOR_EDIT + if (format == 2) + return _read_toc_raw(common, bh); +#endif +//end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 memset(buf, 0, 20); buf[1] = (20-2); /* TOC data length */ buf[2] = 1; /* First track number */ @@ -1376,6 +1627,7 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) buf[14] = 0xAA; /* Lead-out track number */ store_cdrom_address(&buf[16], msf, curlun->num_sectors); return 20; + } static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) @@ -2137,13 +2389,36 @@ static int do_scsi_command(struct fsg_common *common) goto unknown_cmnd; common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]); + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 +#ifdef VENDOR_EDIT + reply = check_command(common, 10, DATA_DIR_TO_HOST, + (0xf<<6) | (1<<1), 1, + "READ TOC"); +#else /* original */ + //end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 reply = check_command(common, 10, DATA_DIR_TO_HOST, (7<<6) | (1<<1), 1, "READ TOC"); +#endif//add by jiachenghui for cdrom suport MAC OSX,2015-06-30 if (reply == 0) reply = do_read_toc(common, bh); break; + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 +#ifdef VENDOR_EDIT + case READ_CD: + common->data_size_from_cmnd = ((common->cmnd[6] << 16) + | (common->cmnd[7] << 8) + | (common->cmnd[8])) << 9; + reply = check_command(common, 12, DATA_DIR_TO_HOST, + (0xf<<2) | (7<<7), 1, + "READ CD"); + if (reply == 0) + reply = do_read_cd(common); + break; +#endif + //end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 + case READ_FORMAT_CAPACITIES: common->data_size_from_cmnd = get_unaligned_be16(&common->cmnd[7]); @@ -2807,6 +3082,7 @@ static struct device_attribute dev_attr_ro_cdrom = static struct device_attribute dev_attr_file_nonremovable = __ATTR(file, 0644, fsg_show_file, fsg_store_file); +static DEVICE_ATTR(cdrom, 0644, fsg_show_cdrom, fsg_store_cdrom); #ifdef CONFIG_USB_MSC_PROFILING static DEVICE_ATTR(perf, 0644, fsg_show_perf, fsg_store_perf); #endif @@ -2889,6 +3165,10 @@ static int create_lun_device(struct fsg_common *common, if (rc) goto error_luns; + rc = device_create_file(&curlun->dev, &dev_attr_cdrom); + if (rc) + goto error_luns; + #ifdef CONFIG_USB_MSC_PROFILING rc = device_create_file(&curlun->dev, &dev_attr_perf); if (rc) @@ -3009,6 +3289,12 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, : "File-CD Gadget"), i); +//add by jiachenghui for cdrom inquiry strings customized ,2015-06-03 +#ifdef VENDOR_EDIT + snprintf(common->inquiry_string, sizeof common->inquiry_string, "%s", "OnePlus Device Driver"); +#endif +//add by jiachenghui for cdrom inquiry strings customized ,2015-06-03 + /* * Some peripheral controllers are known not to be able to * halt bulk endpoints correctly. If one of them is present, @@ -3089,6 +3375,7 @@ static void fsg_common_release(struct kref *ref) #ifdef CONFIG_USB_MSC_PROFILING device_remove_file(&lun->dev, &dev_attr_perf); #endif + device_remove_file(&lun->dev, &dev_attr_cdrom); device_remove_file(&lun->dev, &dev_attr_nofua); device_remove_file(&lun->dev, lun->cdrom diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c old mode 100644 new mode 100755 index 5a06296aaded6..f48f1213c0476 --- a/drivers/usb/gadget/f_mtp.c +++ b/drivers/usb/gadget/f_mtp.c @@ -36,7 +36,12 @@ #include #include +#ifdef VENDOR_EDIT +#define MTP_BULK_BUFFER_SIZE 65536 +#else #define MTP_BULK_BUFFER_SIZE 16384 +#endif /* VENDOR_EDIT */ + #define INTR_BUFFER_SIZE 28 /* String IDs */ diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c old mode 100644 new mode 100755 index 42a30903d4fd9..34302c79022bd --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1470,7 +1470,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (0 == (u8) w_value) { value = 0; dev->current_config = 0; - usb_gadget_vbus_draw(gadget, 8 /* mA */ ); + //usb_gadget_vbus_draw(gadget, 8 /* mA */ ); // user mode expected to disable endpoints } else { u8 config, power; diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index f197a950da8f1..2fa3ff113e269 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -596,6 +596,73 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr) } } + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 +#ifndef VENDOR_EDIT +/** + * fsg_get_toc() - Builds a TOC with required format @format. + * @curlun: The LUN for which the TOC has to be built + * @msf: Min Sec Frame format or LBA format for address + * @format: TOC format code + * @buf: the buffer into which the TOC is built + * + * Builds a Table of Content which can be used as data for READ_TOC command. + * The TOC simulates a single session, single track CD-ROM mode 1 disc. + * + * Returns number of bytes written to @buf, -EINVAL if format not supported. + */ +static int fsg_get_toc(struct fsg_lun *curlun, int msf, int format, u8 *buf) +{ + int i, len; + switch (format) { + case 0: + /* Formatted TOC */ + len = 4 + 2*8; /* 4 byte header + 2 descriptors */ + memset(buf, 0, len); + buf[1] = len - 2; /* TOC Length excludes length field */ + buf[2] = 1; /* First track number */ + buf[3] = 1; /* Last track number */ + buf[5] = 0x16; /* Data track, copying allowed */ + buf[6] = 0x01; /* Only track is number 1 */ + store_cdrom_address(&buf[8], msf, 0); + + buf[13] = 0x16; /* Lead-out track is data */ + buf[14] = 0xAA; /* Lead-out track number */ + store_cdrom_address(&buf[16], msf, curlun->num_sectors); + return len; + break; + case 2: + /* Raw TOC */ + len = 4 + 3*11; /* 4 byte header + 3 descriptors */ + memset(buf, 0, len); /* Header + A0, A1 & A2 descriptors */ + buf[1] = len - 2; /* TOC data length */ + buf[2] = 1; /* First complete session */ + buf[3] = 1; /* Last complete session */ + + buf += 4; + /* fill in A0, A1 and A2 points */ + for (i = 0; i < 3; i++) { + buf[0] = 1; /* Session number */ + buf[1] = 0x16; /* Data track, copying allowed */ + /* 2 - Track number 0 -> TOC */ + buf[3] = 0xA0 + i; /* A0, A1, A2 point */ + /* 4, 5, 6 - Min, sec, frame is zero */ + buf[8] = 1; /* Pmin: last track number */ + buf += 11; /* go to next track descriptor */ + } + buf -= 11; /* go back to A2 descriptor */ + + /* For A2, 7, 8, 9, 10 - zero, Pmin, Psec, Pframe of Lead out */ + store_cdrom_address(&buf[7], msf, curlun->num_sectors); + return len; + break; + default: + /* Multi-session, PMA, ATIP, CD-TEXT not supported/required */ + return -EINVAL; + break; + } +} +#endif +//end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 /*-------------------------------------------------------------------------*/ @@ -774,3 +841,40 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, up_write(filesem); return (rc < 0 ? rc : count); } + +static ssize_t fsg_show_cdrom (struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return sprintf(buf, "%d\n", curlun->cdrom); +} + +static ssize_t fsg_store_cdrom(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t rc; + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + unsigned cdrom; + + rc = kstrtouint(buf, 2, &cdrom); + if (rc) + return rc; + + /* + * Allow the cdrom status to change only while the + * backing file is closed. + */ + down_read(filesem); + if (fsg_lun_is_open(curlun)) { + LDBG(curlun, "cdrom status change prevented\n"); + rc = -EBUSY; + } else { + curlun->cdrom = cdrom; + LDBG(curlun, "cdrom status set to %d\n", curlun->cdrom); + rc = count; + } + up_read(filesem); + return rc; +} diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c index 2f6bf93cdd887..768fbb4c91cca 100644 --- a/drivers/usb/gadget/u_bam_data.c +++ b/drivers/usb/gadget/u_bam_data.c @@ -112,12 +112,22 @@ struct bam_data_ch_info { unsigned int rx_flow_control_enable; unsigned int rx_flow_control_triggered; /* used for RNDIS/ECM network inteface based design */ +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT atomic_t is_net_interface_up; +#else + atomic_t pipe_connect_notified; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 bool tx_req_dequeued; }; static struct work_struct *rndis_conn_w; +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT static bool is_ipa_rndis_net_on; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 enum u_bam_data_event_type { U_BAM_DATA_DISCONNECT_E = 0, @@ -752,13 +762,26 @@ static void bam2bam_free_rx_skb_idle_list(struct bam_data_port *port) */ static void bam_data_ipa_disconnect(struct bam_data_ch_info *d) { +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT pr_debug("%s(): is_net_interface_up:%d\n", __func__, atomic_read(&d->is_net_interface_up)); +#else + pr_debug("%s(): pipe_connect_notified:%d\n", + __func__, atomic_read(&d->pipe_connect_notified)); +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 /* * Check if is_net_interface_up is set to 1, then perform disconnect * part and set is_net_interface_up to zero. */ +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT if (atomic_xchg(&d->is_net_interface_up, 0) == 1) { + #else + if (atomic_xchg(&d->pipe_connect_notified, 0) == 1) { +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 void *priv; if (d->func_type == USB_FUNC_ECM) { priv = ecm_qc_get_ipa_priv(); @@ -766,7 +789,11 @@ static void bam_data_ipa_disconnect(struct bam_data_ch_info *d) } else if (d->func_type == USB_FUNC_RNDIS) { priv = rndis_qc_get_ipa_priv(); rndis_ipa_pipe_disconnect_notify(priv); +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT is_ipa_rndis_net_on = false; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 } pr_debug("%s(): net interface is disconnected.\n", __func__); } @@ -1136,8 +1163,17 @@ static void bam2bam_data_connect_work(struct work_struct *w) __func__, ret); return; } +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT is_ipa_rndis_net_on = true; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 } +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifdef VENDOR_EDIT + atomic_set(&d->pipe_connect_notified, 1); +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 } else { /* transport type is USB_GADGET_XPORT_BAM2BAM */ /* Upadate BAM specific attributes in usb_request */ usb_bam_reset_complete(); @@ -1224,7 +1260,12 @@ void bam_data_start_rx_tx(u8 port_num) * cable disconnect i.e. bam_data_disconnect() API even not as part * of any error happen in this API further. */ +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT atomic_set(&d->is_net_interface_up, 1); +#endif +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 + if (!port->port_usb || !port->port_usb->in->driver_data || !port->port_usb->out->driver_data) { pr_err("%s: Can't start tx, rx, ep not enabled", __func__); @@ -1297,18 +1338,50 @@ static int bam2bam_data_port_alloc(int portno) void u_bam_data_start_rndis_ipa(void) { +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifdef VENDOR_EDIT + int port_num; + struct bam_data_port *port; + struct bam_data_ch_info *d; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 pr_debug("%s\n", __func__); +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifdef VENDOR_EDIT + port_num = u_bam_data_func_to_port(USB_FUNC_RNDIS, + RNDIS_QC_ACTIVE_PORT); + port = bam2bam_data_ports[port_num]; + if (!port) { + pr_err("%s: port is NULL", __func__); + return; + } + d = &port->data_ch; + if (!atomic_read(&d->pipe_connect_notified)) { + //usb_gadget_autopm_get_noresume(port->gadget); + queue_work(bam_data_wq, &port->connect_w); + } +#else +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 if (!is_ipa_rndis_net_on) queue_work(bam_data_wq, rndis_conn_w); +#endif//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 else pr_debug("%s: Transfers already started?\n", __func__); } void u_bam_data_stop_rndis_ipa(void) { +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifdef VENDOR_EDIT + int port_num; + struct bam_data_port *port; + struct bam_data_ch_info *d; +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 pr_debug("%s\n", __func__); +#ifndef VENDOR_EDIT//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 if (is_ipa_rndis_net_on) { int port_num = u_bam_data_func_to_port(USB_FUNC_RNDIS, RNDIS_QC_ACTIVE_PORT); @@ -1317,6 +1390,23 @@ void u_bam_data_stop_rndis_ipa(void) rndis_ipa_reset_trigger(); bam_data_stop_endless_tx(port); if (port->is_ipa_connected) +#else//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 + port_num = u_bam_data_func_to_port(USB_FUNC_RNDIS, + RNDIS_QC_ACTIVE_PORT); + port = bam2bam_data_ports[port_num]; + if (!port) { + pr_err("%s: port is NULL", __func__); + return; + } + + d = &port->data_ch; + + if (atomic_read(&d->pipe_connect_notified)) { + rndis_ipa_reset_trigger(); + bam_data_stop_endless_tx(port); + bam_data_stop_endless_rx(port); +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 queue_work(bam_data_wq, &port->disconnect_w); } } @@ -1449,6 +1539,21 @@ void bam_data_disconnect(struct data_port *gr, enum function_type func, } if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) { +//add by jiachenghui for usb fail after rndis click some times, 2015-7-8 +#ifndef VENDOR_EDIT + void *priv; + if (d->func_type == USB_FUNC_ECM) { + priv = ecm_qc_get_ipa_priv(); + ecm_ipa_disconnect(priv); + } else if (d->func_type == USB_FUNC_RNDIS) { + priv = rndis_qc_get_ipa_priv(); + rndis_ipa_pipe_disconnect_notify(priv); + is_ipa_rndis_net_on = false; + } else if (d->func_type == USB_FUNC_MBIM) { + teth_bridge_disconnect(d->ipa_params.src_client); + } +#endif +//end add by jiachenghui for usb fail after rndis click some times, 2015-7-8 port->last_event = U_BAM_DATA_DISCONNECT_E; queue_work(bam_data_wq, &port->disconnect_w); } else { diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 1fcc6864cf3b3..bbd653f12452d 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -203,7 +203,9 @@ module_param(u_ether_rx_pending_thld, uint, S_IRUGO | S_IWUSR); #define xprintk(d, level, fmt, args...) \ printk(level "%s: " fmt , (d)->net->name , ## args) - +//add by jiachenghui for usb debug test +#undef DEBUG +//end add by jiachenghui for usb debug test #ifdef DEBUG #undef DEBUG #define DBG(dev, fmt, args...) \ diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e3a9fb5bd2ffa..7dee0e728c5dc 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1042,7 +1042,24 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) done: return ret; } - +/*ykl add debug log*/ +#ifdef VENDOR_EDIT +void debug_blank(int blank,int start) +{ + if(start) + { + if(blank == FB_BLANK_UNBLANK) + printk("blank on start\n"); + else if(blank == FB_BLANK_POWERDOWN) + printk("blank off start\n"); + }else{ + if(blank == FB_BLANK_UNBLANK) + printk("blank on end\n"); + else if(blank == FB_BLANK_POWERDOWN) + printk("blank off end\n"); + } +} +#endif int fb_blank(struct fb_info *info, int blank) { @@ -1054,7 +1071,10 @@ fb_blank(struct fb_info *info, int blank) event.info = info; event.data = ␣ - +/*ykl add debug log*/ +#ifdef VENDOR_EDIT + debug_blank(blank,1); +#endif early_ret = fb_notifier_call_chain(FB_EARLY_EVENT_BLANK, &event); if (info->fbops->fb_blank) @@ -1070,6 +1090,10 @@ fb_blank(struct fb_info *info, int blank) if (!early_ret) fb_notifier_call_chain(FB_R_EARLY_EVENT_BLANK, &event); } +/*ykl add debug log*/ +#ifdef VENDOR_EDIT + debug_blank(blank,0); +#endif return ret; } diff --git a/drivers/video/msm/mdss/Kconfig b/drivers/video/msm/mdss/Kconfig index 3029d0ef7498b..f1cb76dadd4de 100644 --- a/drivers/video/msm/mdss/Kconfig +++ b/drivers/video/msm/mdss/Kconfig @@ -62,3 +62,10 @@ config FB_MSM_MDSS_XLOG_DEBUG features to: Dump MDSS registers during driver errors, panic driver during fatal errors and enable some display-driver logging into an internal buffer (this avoids logging overhead). + +config FB_MSM_MDSS_KCAL_CTRL + depends on FB_MSM_MDSS + bool "MDSS color control" + ---help--- + Enable sysfs for post-processing control of mdss-mdp5 display + controllers in MDSS. diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile index 718e4618b89ac..212fbbcf21fc5 100644 --- a/drivers/video/msm/mdss/Makefile +++ b/drivers/video/msm/mdss/Makefile @@ -51,3 +51,5 @@ obj-$(CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL) += qpic_panel_ili_qvga.o obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o mdss_util.o obj-$(CONFIG_COMPAT) += mdss_compat_utils.o + +obj-$(CONFIG_FB_MSM_MDSS_KCAL_CTRL) += mdss_mdp_kcal_ctrl.o diff --git a/drivers/video/msm/mdss/mdss_debug_xlog.c b/drivers/video/msm/mdss/mdss_debug_xlog.c old mode 100644 new mode 100755 index 7ba5ad7e43bf6..8bb1db9669fbc --- a/drivers/video/msm/mdss/mdss_debug_xlog.c +++ b/drivers/video/msm/mdss/mdss_debug_xlog.c @@ -27,7 +27,7 @@ #else #define XLOG_DEFAULT_ENABLE 0 #endif - +//according the qualcomm need dump in RAM #define XLOG_DEFAULT_PANIC 1 #define XLOG_DEFAULT_REGDUMP 0x2 /* dump in RAM */ #define XLOG_DEFAULT_DBGBUSDUMP 0x3 /* dump in LOG & RAM */ @@ -450,8 +450,22 @@ static void mdss_xlog_dump_array(struct mdss_debug_base *blk_arr[], mdss_dump_debug_bus(mdss_dbg_xlog.enable_dbgbus_dump, &mdss_dbg_xlog.dbgbus_dump); +#ifndef VENDOR_EDIT //guozhiming add for test + + if (dead && mdss_dbg_xlog.panic_on_err) + { + panic(name); + } +#else + if (dead && mdss_dbg_xlog.panic_on_err) - panic(name); + { + char i; + for(i=0;i<100;i++) + printk(KERN_ERR"check find the display error\n"); + //panic(name); + } +#endif } static void xlog_debug_work(struct work_struct *work) diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c old mode 100644 new mode 100755 index 38af1dd597945..00e25632e8f36 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -31,6 +31,12 @@ #define XO_CLK_RATE 19200000 +#ifdef VENDOR_EDIT/*guozhiming@oem_display add for the RF WLAN mode using*/ +#include + +//static int rf_wlan_test_mode=0; + +#endif static struct dsi_drv_cm_data shared_ctrl_data; static int mdss_dsi_pinctrl_set_state(struct mdss_dsi_ctrl_pdata *ctrl_pdata, @@ -73,6 +79,7 @@ static int mdss_dsi_labibb_vreg_init(struct platform_device *pdev) return 0; } +extern int syna_use_gesture; static int mdss_dsi_labibb_vreg_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) { @@ -97,21 +104,24 @@ static int mdss_dsi_labibb_vreg_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, regulator_disable(ctrl->lab); return rc; } + mdelay(20); } else { - rc = regulator_disable(ctrl->lab); - if (rc) { - pr_err("%s: disable failed for lab regulator\n", - __func__); - return rc; - } - - rc = regulator_disable(ctrl->ibb); - if (rc) { - pr_err("%s: disable failed for ibb regulator\n", - __func__); - return rc; - } + if (!syna_use_gesture){ + rc = regulator_disable(ctrl->lab); + if (rc) { + pr_err("%s: disable failed for lab regulator\n", + __func__); + return rc; + } + + rc = regulator_disable(ctrl->ibb); + if (rc) { + pr_err("%s: disable failed for ibb regulator\n", + __func__); + return rc; + } + } } return 0; @@ -148,6 +158,9 @@ static int mdss_dsi_regulator_init(struct platform_device *pdev) return rc; } +#ifdef VENDOR_EDIT +extern int vendor_lcd_power_on(struct mdss_panel_data *pdata, int enable); +#endif static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) { @@ -155,6 +168,8 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; int i = 0; + pr_err("%s\n",__func__); //for debug + if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); ret = -EINVAL; @@ -164,6 +179,25 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); +#ifdef VENDOR_EDIT + if (ctrl_pdata->panel_bias_vreg) { + pr_debug("%s: Disabling panel bias vreg. ndx = %d\n", + __func__, ctrl_pdata->ndx); + if (mdss_dsi_labibb_vreg_ctrl(ctrl_pdata, false)) + pr_err("Unable to disable bias vreg\n"); + /* Add delay recommended by panel specs */ + udelay(5000); + } +#endif + +#ifdef VENDOR_EDIT + + if (ctrl_pdata->use_external_ic_power){ + + vendor_lcd_power_on(pdata, 0); + } +#endif + ret = mdss_dsi_panel_reset(pdata, 0); if (ret) { pr_warn("%s: Panel reset failed. rc=%d\n", __func__, ret); @@ -172,7 +206,7 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) if (mdss_dsi_pinctrl_set_state(ctrl_pdata, false)) pr_debug("reset disable: pinctrl not enabled\n"); - +#ifndef VENDOR_EDIT if (ctrl_pdata->panel_bias_vreg) { pr_debug("%s: Disabling panel bias vreg. ndx = %d\n", __func__, ctrl_pdata->ndx); @@ -181,7 +215,7 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata) /* Add delay recommended by panel specs */ udelay(2000); } - +#endif for (i = DSI_MAX_PM - 1; i >= 0; i--) { /* * Core power module will be disabled when the @@ -207,11 +241,12 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; int i = 0; + pr_err("%s\n",__func__);//for debug + if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } - ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); @@ -232,7 +267,7 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) } } if (ctrl_pdata->panel_bias_vreg) { - pr_debug("%s: Enable panel bias vreg. ndx = %d\n", + pr_err("%s: Enable panel bias vreg. ndx = %d\n", __func__, ctrl_pdata->ndx); if (mdss_dsi_labibb_vreg_ctrl(ctrl_pdata, true)) pr_err("Unable to configure bias vreg\n"); @@ -242,6 +277,16 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) i--; +#ifdef VENDOR_EDIT //gzm@oem add 2015-07-04 for EVT2 DVT PVT + if (!pdata->panel_info.cont_splash_enabled) + { + if (ctrl_pdata->use_external_ic_power){ + + vendor_lcd_power_on(pdata, 1); + } + } +#endif + /* * If continuous splash screen feature is enabled, then we need to * request all the GPIOs that have already been configured in the @@ -252,7 +297,6 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) !pdata->panel_info.mipi.lp11_init) { if (mdss_dsi_pinctrl_set_state(ctrl_pdata, true)) pr_debug("reset enable: pinctrl not enabled\n"); - ret = mdss_dsi_panel_reset(pdata, 1); if (ret) pr_err("%s: Panel reset failed. rc=%d\n", @@ -724,7 +768,14 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) goto end; } - ret = mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_ON); + #ifdef VENDOR_EDIT /*guozhiming add for RF and WLAN mode */ + if((get_boot_mode() !=MSM_BOOT_MODE__RF)&&(get_boot_mode() !=MSM_BOOT_MODE__WLAN)) + ret = mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_ON); + #else + { + ret = mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_ON); + } + #endif if (ret) { pr_err("%s:Panel power on failed. rc=%d\n", __func__, ret); return ret; @@ -766,9 +817,20 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) if (mipi->lp11_init) { if (mdss_dsi_pinctrl_set_state(ctrl_pdata, true)) pr_debug("reset enable: pinctrl not enabled\n"); + #ifdef VENDOR_EDIT + if (syna_use_gesture) + msleep(25); + else + msleep(15); mdss_dsi_panel_reset(pdata, 1); + if (syna_use_gesture) + msleep(30); + #else + mdss_dsi_panel_reset(pdata, 1); + #endif } + if (mipi->init_delay) usleep(mipi->init_delay); @@ -1761,6 +1823,10 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) ctrl_pdata->panel_bias_vreg = of_property_read_bool( pdev->dev.of_node, "qcom,dsi-panel-bias-vreg"); +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 -04-23 new modify + ctrl_pdata->use_external_ic_power = of_property_read_bool( + pdev->dev.of_node, "qcom,use_external_ic_power"); + #endif /* DSI panels can be different between controllers */ rc = mdss_dsi_get_panel_cfg(panel_cfg, ctrl_pdata); if (!rc) @@ -2085,32 +2151,56 @@ int dsi_panel_device_register(struct device_node *pan_node, if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) pr_err("%s:%d, TE gpio not specified\n", __func__, __LINE__); - +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 -04-23 new modify + ctrl_pdata->lcd_esd_te_check = of_get_named_gpio(ctrl_pdev->dev.of_node, + "qcom,platform-esd-te-gpio", 0); + if (!gpio_is_valid(ctrl_pdata->lcd_esd_te_check)) + pr_err("%s:%d, LCD ESD TE gpio not specified\n", + __func__, __LINE__); + + ctrl_pdata->lcd_lm3630_bl = of_get_named_gpio(ctrl_pdev->dev.of_node, + "qcom,lm3630-bklight-en-gpio", 0); + if (!gpio_is_valid(ctrl_pdata->lcd_lm3630_bl)) + pr_err("%s:%d, lm3630 gpio not specified\n", + __func__, __LINE__); + + ctrl_pdata->lcd_tps65132_en = of_get_named_gpio(ctrl_pdev->dev.of_node, + "qcom,lcd-poweron-en-gpio", 0); + if (!gpio_is_valid(ctrl_pdata->lcd_tps65132_en)) + pr_err("%s:%d, lcd 5v gpio not specified\n", + __func__, __LINE__); + + ctrl_pdata->lcd_tps65132_en_n = of_get_named_gpio(ctrl_pdev->dev.of_node, + "qcom,lcd-poweron-en-n-gpio", 0); + if (!gpio_is_valid(ctrl_pdata->lcd_tps65132_en_n)) + pr_err("%s:%d, lcd -5v gpio not specified\n", + __func__, __LINE__); +#endif ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, - "qcom,platform-bklight-en-gpio", 0); + "qcom,platform-bklight-en-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio)) pr_info("%s: bklt_en gpio not specified\n", __func__); ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, - "qcom,platform-reset-gpio", 0); + "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) pr_err("%s:%d, reset gpio not specified\n", - __func__, __LINE__); + __func__, __LINE__); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( - ctrl_pdev->dev.of_node, - "qcom,platform-mode-gpio", 0); + ctrl_pdev->dev.of_node, + "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", - __func__, __LINE__); + __func__, __LINE__); } else { ctrl_pdata->mode_gpio = -EINVAL; } ctrl_pdata->timing_db_mode = of_property_read_bool( - ctrl_pdev->dev.of_node, "qcom,timing-db-mode"); + ctrl_pdev->dev.of_node, "qcom,timing-db-mode"); if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); @@ -2191,8 +2281,8 @@ int dsi_panel_device_register(struct device_node *pan_node, return rc; } } + if (pinfo->cont_splash_enabled){ - if (pinfo->cont_splash_enabled) { rc = mdss_dsi_panel_power_ctrl(&(ctrl_pdata->panel_data), MDSS_PANEL_POWER_ON); if (rc) { diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h old mode 100644 new mode 100755 index c6eeb7d25aa3b..91b0dfae16c29 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -150,6 +150,10 @@ enum dsi_pm_type { #define DSI_CMD_DST_FORMAT_RGB565 6 #define DSI_CMD_DST_FORMAT_RGB666 7 #define DSI_CMD_DST_FORMAT_RGB888 8 +#ifdef VENDOR_EDIT //qualcomm modify for lcd crash 2015-04-18 + +#define DSI_INTR_DESJEW_MASK BIT(31) +#endif #define DSI_INTR_DESJEW_MASK BIT(31) #define DSI_INTR_DYNAMIC_REFRESH_MASK BIT(29) @@ -164,6 +168,18 @@ enum dsi_pm_type { #define DSI_INTR_CMD_MDP_DONE BIT(8) #define DSI_INTR_CMD_DMA_DONE_MASK BIT(1) #define DSI_INTR_CMD_DMA_DONE BIT(0) + +#ifdef VENDOR_EDIT //qualcomm modify for lcd crash 2015-04-18 +#define DSI_INTR_MASK_ALL \ + (DSI_INTR_DESJEW_MASK | \ + DSI_INTR_DYNAMIC_REFRESH_MASK | \ + DSI_INTR_ERROR_MASK | \ + DSI_INTR_BTA_DONE_MASK | \ + DSI_INTR_VIDEO_DONE_MASK | \ + DSI_INTR_CMD_MDP_DONE_MASK | \ + DSI_INTR_CMD_DMA_DONE_MASK) +#endif + /* Update this if more interrupt masks are added in future chipsets */ #define DSI_INTR_TOTAL_MASK 0x2222AA02 @@ -351,7 +367,13 @@ struct mdss_dsi_ctrl_pdata { bool panel_bias_vreg; bool dsi_irq_line; atomic_t te_irq_ready; - + #ifdef VENDOR_EDIT //gzm@oem add 2015-03-26 + int lcd_esd_te_check; + bool use_external_ic_power; + int lcd_lm3630_bl; + int lcd_tps65132_en; + int lcd_tps65132_en_n; + #endif bool cmd_clk_ln_recovery_en; bool cmd_sync_wait_broadcast; bool cmd_sync_wait_trigger; @@ -368,6 +390,9 @@ struct mdss_dsi_ctrl_pdata { struct mdss_intf_recovery *recovery; struct dsi_panel_cmds on_cmds; + #ifdef VENDOR_EDIT + struct dsi_panel_cmds on_cmds_shoushi; + #endif struct dsi_panel_cmds post_dms_on_cmds; struct dsi_panel_cmds off_cmds; struct dsi_panel_cmds status_cmds; diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index c84c09cfd3a92..771d9b91d67e4 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -29,7 +29,8 @@ #include "mdss_debug.h" #define VSYNC_PERIOD 17 -#define DMA_TX_TIMEOUT 200 +//#define DMA_TX_TIMEOUT 200 +#define DMA_TX_TIMEOUT 400 //qualcomm add patch for the lcd 2015-04-18 #define DMA_TPG_FIFO_LEN 64 struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX]; @@ -2004,6 +2005,10 @@ void mdss_dsi_cmd_mdp_start(struct mdss_dsi_ctrl_pdata *ctrl) spin_unlock_irqrestore(&ctrl->mdp_lock, flag); } +#if 0 +#ifdef VENDOR_EDIT //qualcomm modify for lcd crash 2015-04-18 + +//qualcomm provide patch 2015-04-18 static int mdss_dsi_mdp_busy_tout_check(struct mdss_dsi_ctrl_pdata *ctrl) { unsigned long flag; @@ -2034,7 +2039,55 @@ static int mdss_dsi_mdp_busy_tout_check(struct mdss_dsi_ctrl_pdata *ctrl) stop_hs_clk = true; } tout = 0; /* recovered */ - } + } + + spin_unlock_irqrestore(&ctrl->mdp_lock, flag); + + if (stop_hs_clk) + mdss_dsi_stop_hs_clk_lane(ctrl); + + complete_all(&ctrl->mdp_comp); + + mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0); + + return tout; +} +#endif +#endif +//qualcomm modify for lcd crash 2015-04-22 + +static int mdss_dsi_mdp_busy_tout_check(struct mdss_dsi_ctrl_pdata *ctrl) + { + unsigned long flag; + u32 isr; + bool stop_hs_clk = false; + int tout = 1; + + /* + * two possible scenario: + * 1) DSI_INTR_CMD_MDP_DONE set but isr not fired + * 2) DSI_INTR_CMD_MDP_DONE set and cleared (isr fired) + * but event_thread not wakeup + */ + mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1); + spin_lock_irqsave(&ctrl->mdp_lock, flag); + + isr = MIPI_INP(ctrl->ctrl_base + 0x0110); + if (isr & DSI_INTR_CMD_MDP_DONE) { + WARN(1, "INTR_CMD_MDP_DONE set but isr not fired\n"); + isr &= DSI_INTR_MASK_ALL; + isr |= DSI_INTR_CMD_MDP_DONE; /* clear this isr only */ + MIPI_OUTP(ctrl->ctrl_base + 0x0110, isr); + mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM); + ctrl->mdp_busy = false; + complete_all(&ctrl->mdp_comp); + if (ctrl->cmd_clk_ln_recovery_en && + ctrl->panel_mode == DSI_CMD_MODE) { + /* has hs_lane_recovery do the work */ + stop_hs_clk = true; + } + tout = 0; /* recovered */ + } spin_unlock_irqrestore(&ctrl->mdp_lock, flag); @@ -2294,7 +2347,12 @@ static int dsi_event_thread(void *data) u32 arg; int ret; + #ifndef VENDOR_EDIT //qualcomm modify for lcd crash 2015-04-18 param.sched_priority = 16; + #else + param.sched_priority = 17; + #endif + ret = sched_setscheduler_nocheck(current, SCHED_FIFO, ¶m); if (ret) pr_err("%s: set priority failed\n", __func__); diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c old mode 100644 new mode 100755 index 4dbe11a1a85b4..fe7abe12ff3cd --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -23,10 +23,111 @@ #include #include "mdss_dsi.h" +#include "mdss_mdp.h" + +#ifdef CONFIG_POWERSUSPEND +#include +#endif #define DT_CMD_HDR 6 #define MIN_REFRESH_RATE 30 + +#ifdef VENDOR_EDIT +#include + +/* guizhiming Add for set cabc 2015-04-01 */ +struct dsi_panel_cmds cabc_off_sequence; +struct dsi_panel_cmds cabc_user_interface_image_sequence; +struct dsi_panel_cmds cabc_still_image_sequence; +struct dsi_panel_cmds cabc_video_image_sequence; +struct dsi_panel_cmds oa_sequence; +enum +{ + CABC_CLOSE = 0, + CABC_LOW_MODE, + CABC_MIDDLE_MODE, + CABC_HIGH_MODE, + +}; +int cabc_mode = CABC_MIDDLE_MODE; //defaoult mode level 2 in dtsi file +struct mdss_dsi_ctrl_pdata *panel_data; +static bool flag_lcd_off = false; +static DEFINE_MUTEX(cabc_mutex); + +#endif + +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 + +#include +#define ESD_TE_Check_On +#ifdef ESD_TE_Check_On +#include +static int irq; +unsigned long flags; +static int te_state; +static struct class * mdss_lcd; +static struct device * dev_lcd; +static struct switch_dev display_switch; +static struct delayed_work techeck_work; +DEFINE_SPINLOCK(te_state_lock); +static struct completion te_comp; + +static irqreturn_t TE_irq_thread_fn(int irq, void *dev_id) +{ + complete(&te_comp); + return IRQ_HANDLED; +} + +static int operate_display_switch(void) +{ + int ret = 0; + + printk(KERN_ERR"%s:state=%d.\n", __func__, te_state); + spin_lock_irqsave(&te_state_lock, flags); + if(te_state) + te_state = 0; + else + te_state = 1; + spin_unlock_irqrestore(&te_state_lock, flags); + + switch_set_state(&display_switch, te_state); + return ret; +} + +static ssize_t attr_mdss_dispswitch(struct device *dev, + struct device_attribute *attr, char *buf) +{ + printk(KERN_ERR" @@@@ attr_mdss_dispswitch \n"); + operate_display_switch(); + + return 0; +} + +static struct device_attribute mdss_lcd_attrs[] = { + __ATTR(dispswitch, S_IRUGO, attr_mdss_dispswitch, NULL), + __ATTR_NULL, +}; + +static void techeck_work_func( struct work_struct *work ) +{ + int ret = 0; + //pr_err("techeck_work_func\n"); + INIT_COMPLETION(te_comp); + enable_irq(irq); + ret = wait_for_completion_killable_timeout(&te_comp, msecs_to_jiffies(100)); + if(ret == 0) { + disable_irq(irq); + operate_display_switch(); + return; + } + //pr_err("ret = %d\n", ret); + disable_irq(irq); + schedule_delayed_work(&techeck_work, msecs_to_jiffies(2000)); +} +#endif +#endif /*EDIT*/ + DEFINE_LED_TRIGGER(bl_led_trigger); void mdss_dsi_panel_pwm_cfg(struct mdss_dsi_ctrl_pdata *ctrl) @@ -71,10 +172,10 @@ static void mdss_dsi_panel_bklt_pwm(struct mdss_dsi_ctrl_pdata *ctrl, int level) pr_debug("%s: bklt_ctrl=%d pwm_period=%d pwm_gpio=%d pwm_lpg_chan=%d\n", __func__, ctrl->bklt_ctrl, ctrl->pwm_period, - ctrl->pwm_pmic_gpio, ctrl->pwm_lpg_chan); + ctrl->pwm_pmic_gpio, ctrl->pwm_lpg_chan); pr_debug("%s: ndx=%d level=%d duty=%d\n", __func__, - ctrl->ndx, level, duty); + ctrl->ndx, level, duty); if (ctrl->pwm_period >= USEC_PER_SEC) { ret = pwm_config_us(ctrl->pwm_bl, duty, ctrl->pwm_period); @@ -99,7 +200,7 @@ static void mdss_dsi_panel_bklt_pwm(struct mdss_dsi_ctrl_pdata *ctrl, int level) ret = pwm_enable(ctrl->pwm_bl); if (ret) pr_err("%s: pwm_enable() failed err=%d\n", __func__, - ret); + ret); ctrl->pwm_enabled = 1; } } @@ -140,7 +241,7 @@ u32 mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0, } static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl, - struct dsi_panel_cmds *pcmds) + struct dsi_panel_cmds *pcmds) { struct dcs_cmd_req cmdreq; struct mdss_panel_info *pinfo; @@ -205,25 +306,25 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) { rc = gpio_request(ctrl_pdata->disp_en_gpio, - "disp_enable"); + "disp_enable"); if (rc) { pr_err("request disp_en gpio failed, rc=%d\n", - rc); + rc); goto disp_en_gpio_err; } } rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", - rc); + rc); goto rst_gpio_err; - } + } if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { rc = gpio_request(ctrl_pdata->bklt_en_gpio, - "bklt_enable"); + "bklt_enable"); if (rc) { pr_err("request bklt gpio failed, rc=%d\n", - rc); + rc); goto bklt_en_gpio_err; } } @@ -231,7 +332,7 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode"); if (rc) { pr_err("request panel mode gpio failed,rc=%d\n", - rc); + rc); goto mode_gpio_err; } } @@ -244,11 +345,131 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) gpio_free(ctrl_pdata->rst_gpio); rst_gpio_err: if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) - gpio_free(ctrl_pdata->disp_en_gpio); + gpio_free(ctrl_pdata->disp_en_gpio); disp_en_gpio_err: return rc; } +#ifdef VENDOR_EDIT //gzm@oem add 2015-04-23 for EVT2 + +static int lcd_power_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) +{ + + int rc = 0; + + if (ctrl_pdata->use_external_ic_power) + { + //printk(KERN_ERR"@@@@@@@@@@@@@@@@ eeeeeeeeeeee\n"); + rc = gpio_request(ctrl_pdata->lcd_tps65132_en, "lcd_5v_en"); + if (rc) { + pr_err("request lcd 5v en gpio failed, rc=%d\n", + rc); + return rc; + } + + rc = gpio_request(ctrl_pdata->lcd_tps65132_en_n, "lcd_5v_en_n"); + if (rc) { + pr_err("request lcd -5v en gpio failed, rc=%d\n", + rc); + goto lcd_5v_n_gpio_err; + + } + } + + return rc; + +lcd_5v_n_gpio_err: + if (ctrl_pdata->use_external_ic_power) + { + if (gpio_is_valid(ctrl_pdata->lcd_tps65132_en)) + gpio_free(ctrl_pdata->lcd_tps65132_en); + } + return rc; +} +#endif + +extern int syna_use_gesture; + +#ifdef VENDOR_EDIT //gzm@oem add 2015-07-04 for EVT2 DVT PVT + +int vendor_lcd_power_on(struct mdss_panel_data *pdata, int enable) +{ + + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct mdss_panel_info *pinfo = NULL; + int rc = 0; + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + if (ctrl_pdata->use_external_ic_power) + { + + if (!gpio_is_valid(ctrl_pdata->lcd_tps65132_en)) { + pr_debug("%s:%d, lcd tps65132 5v en line not configured\n", + __func__, __LINE__); + return rc; + } + + if (!gpio_is_valid(ctrl_pdata->lcd_tps65132_en_n)) { + pr_debug("%s:%d, lcd tps65132 -5v en line not configured\n", + __func__, __LINE__); + return rc; + } + } + + pr_debug("%s: enable = %d\n", __func__, enable); + pinfo = &(ctrl_pdata->panel_data.panel_info); + + if (enable) { + rc = lcd_power_request_gpios(ctrl_pdata); + if (rc) { + pr_err("gpio request failed\n"); + return rc; + } + + if (ctrl_pdata->use_external_ic_power) + { + gpio_set_value((ctrl_pdata->lcd_tps65132_en), 1); + mdelay(2); + gpio_set_value((ctrl_pdata->lcd_tps65132_en_n), 1); + + } + + } + + else{ + + if (!syna_use_gesture) + { + if (ctrl_pdata->use_external_ic_power) + { + gpio_set_value((ctrl_pdata->lcd_tps65132_en_n), 0); + mdelay(5); + gpio_set_value((ctrl_pdata->lcd_tps65132_en), 0); + mdelay(5); + } + + } + if (ctrl_pdata->use_external_ic_power) + { + + gpio_free(ctrl_pdata->lcd_tps65132_en); + gpio_free(ctrl_pdata->lcd_tps65132_en_n); + } + } + return rc; + +} + +#endif + + + int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) { struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; @@ -261,19 +482,18 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_debug("%s:%d, reset line not configured\n", - __func__, __LINE__); + __func__, __LINE__); } if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_debug("%s:%d, reset line not configured\n", - __func__, __LINE__); + __func__, __LINE__); return rc; } - pr_debug("%s: enable = %d\n", __func__, enable); pinfo = &(ctrl_pdata->panel_data.panel_info); @@ -287,13 +507,28 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_set_value((ctrl_pdata->disp_en_gpio), 1); +#ifdef VENDOR_EDIT + //ykl do hw reset when use gesture resume + //if (!syna_use_gesture)/*GZM add for the */ + //{ + for (i = 0; i < pdata->panel_info.rst_seq_len; ++i) { + gpio_set_value((ctrl_pdata->rst_gpio), + pdata->panel_info.rst_seq[i]); + if (pdata->panel_info.rst_seq[++i]) + usleep(pinfo->rst_seq[i] * 1000); + } + //} +#else + for (i = 0; i < pdata->panel_info.rst_seq_len; ++i) { gpio_set_value((ctrl_pdata->rst_gpio), - pdata->panel_info.rst_seq[i]); + pdata->panel_info.rst_seq[i]); if (pdata->panel_info.rst_seq[++i]) usleep(pinfo->rst_seq[i] * 1000); } +#endif + if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) gpio_set_value((ctrl_pdata->bklt_en_gpio), 1); } @@ -306,10 +541,14 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) } if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) { pr_debug("%s: Panel Not properly turned OFF\n", - __func__); + __func__); ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT; pr_debug("%s: Reset panel done\n", __func__); } + + if((get_boot_mode() == MSM_BOOT_MODE__RF)||(get_boot_mode() == MSM_BOOT_MODE__WLAN)) + gpio_set_value((ctrl_pdata->rst_gpio), 0); + } else { if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { gpio_set_value((ctrl_pdata->bklt_en_gpio), 0); @@ -319,8 +558,18 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) gpio_set_value((ctrl_pdata->disp_en_gpio), 0); gpio_free(ctrl_pdata->disp_en_gpio); } - gpio_set_value((ctrl_pdata->rst_gpio), 0); + #ifdef VENDOR_EDIT + if (!syna_use_gesture) + { + gpio_set_value((ctrl_pdata->rst_gpio), 0); + + } + #endif + if((get_boot_mode() == MSM_BOOT_MODE__RF)||(get_boot_mode() == MSM_BOOT_MODE__WLAN)) + gpio_set_value((ctrl_pdata->rst_gpio), 0); + gpio_free(ctrl_pdata->rst_gpio); + if (gpio_is_valid(ctrl_pdata->mode_gpio)) gpio_free(ctrl_pdata->mode_gpio); } @@ -334,7 +583,7 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) * (column/page) dcs commands. */ static int mdss_dsi_roi_merge(struct mdss_dsi_ctrl_pdata *ctrl, - struct mdss_rect *roi) + struct mdss_rect *roi) { struct mdss_panel_info *l_pinfo; struct mdss_rect *l_roi; @@ -382,7 +631,7 @@ static struct dsi_cmd_desc set_col_page_addr_cmd[] = { }; static void mdss_dsi_send_col_page_addr(struct mdss_dsi_ctrl_pdata *ctrl, - struct mdss_rect *roi, int unicast) + struct mdss_rect *roi, int unicast) { struct dcs_cmd_req cmdreq; @@ -427,7 +676,7 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, } ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); pinfo = &pdata->panel_info; p_roi = &pinfo->roi; @@ -459,7 +708,7 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, if (c_roi->w == 0 || c_roi->h == 0) { /* no new frame update */ pr_debug("%s: ctrl=%d, no partial roi set\n", - __func__, ctrl->ndx); + __func__, ctrl->ndx); return 0; } @@ -473,7 +722,7 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, if (!mdss_dsi_sync_wait_enable(ctrl)) { if (pinfo->dcs_cmd_by_left) ctrl = mdss_dsi_get_ctrl_by_index( - DSI_CTRL_LEFT); + DSI_CTRL_LEFT); mdss_dsi_send_col_page_addr(ctrl, &roi, 0); } else { /* @@ -522,7 +771,7 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, } static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, - int mode) + int mode) { struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mipi_panel_info *mipi; @@ -539,7 +788,7 @@ static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, return; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); if (mode == DSI_CMD_MODE) pcmds = &ctrl_pdata->video2cmd; @@ -552,7 +801,7 @@ static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, } static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, - u32 bl_level) + u32 bl_level) { struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_dsi_ctrl_pdata *sctrl = NULL; @@ -563,7 +812,7 @@ static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); /* * Some backlight controllers specify a minimum duty cycle @@ -575,57 +824,146 @@ static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, bl_level = pdata->panel_info.bl_min; switch (ctrl_pdata->bklt_ctrl) { - case BL_WLED: - led_trigger_event(bl_led_trigger, bl_level); - break; - case BL_PWM: - mdss_dsi_panel_bklt_pwm(ctrl_pdata, bl_level); - break; - case BL_DCS_CMD: - if (!mdss_dsi_sync_wait_enable(ctrl_pdata)) { - mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); + case BL_WLED: + led_trigger_event(bl_led_trigger, bl_level); + break; + case BL_PWM: + mdss_dsi_panel_bklt_pwm(ctrl_pdata, bl_level); + break; + case BL_DCS_CMD: + if (!mdss_dsi_sync_wait_enable(ctrl_pdata)) { + mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); + break; + } + /* + * DCS commands to update backlight are usually sent at + * the same time to both the controllers. However, if + * sync_wait is enabled, we need to ensure that the + * dcs commands are first sent to the non-trigger + * controller so that when the commands are triggered, + * both controllers receive it at the same time. + */ + sctrl = mdss_dsi_get_other_ctrl(ctrl_pdata); + if (mdss_dsi_sync_wait_trigger(ctrl_pdata)) { + if (sctrl) + mdss_dsi_panel_bklt_dcs(sctrl, bl_level); + mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); + } else { + mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); + if (sctrl) + mdss_dsi_panel_bklt_dcs(sctrl, bl_level); + } + break; + default: + pr_err("%s: Unknown bl_ctrl configuration\n", + __func__); break; - } - /* - * DCS commands to update backlight are usually sent at - * the same time to both the controllers. However, if - * sync_wait is enabled, we need to ensure that the - * dcs commands are first sent to the non-trigger - * controller so that when the commands are triggered, - * both controllers receive it at the same time. - */ - sctrl = mdss_dsi_get_other_ctrl(ctrl_pdata); - if (mdss_dsi_sync_wait_trigger(ctrl_pdata)) { - if (sctrl) - mdss_dsi_panel_bklt_dcs(sctrl, bl_level); - mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); - } else { - mdss_dsi_panel_bklt_dcs(ctrl_pdata, bl_level); - if (sctrl) - mdss_dsi_panel_bklt_dcs(sctrl, bl_level); - } - break; - default: - pr_err("%s: Unknown bl_ctrl configuration\n", - __func__); - break; } } +#ifdef VENDOR_EDIT /*guozhiming add for CABC adjust backlight*/ + +int set_cabc(int level) +{ + int ret = 0; + + printk(KERN_ERR" %s : %d \n",__func__,level); + mutex_lock(&cabc_mutex); + + if(flag_lcd_off == true) + { + printk(KERN_ERR "lcd is off,don't allow to set cabc\n"); + cabc_mode = level; + mutex_unlock(&cabc_mutex); + return 0; + } + mdss_dsi_clk_ctrl(panel_data, DSI_ALL_CLKS, 1); + switch(level) + { + case 0: + printk(KERN_ERR" CABC level=0\n"); + mdss_dsi_panel_cmds_send(panel_data, &cabc_off_sequence); + cabc_mode = CABC_CLOSE; + break; + case 1: + printk(KERN_ERR" CABC level=1\n"); + mdss_dsi_panel_cmds_send(panel_data, &cabc_user_interface_image_sequence); + cabc_mode = CABC_LOW_MODE; + break; + case 2: + printk(KERN_ERR" CABC level=2\n"); + mdss_dsi_panel_cmds_send(panel_data, &cabc_still_image_sequence); + cabc_mode = CABC_MIDDLE_MODE; + break; + case 3: + printk(KERN_ERR" CABC level=3\n"); + mdss_dsi_panel_cmds_send(panel_data, &cabc_video_image_sequence); + cabc_mode = CABC_HIGH_MODE; + break; + default: + pr_err("%s Leavel %d is not supported!\n",__func__,level); + ret = -1; + break; + } + mdss_dsi_clk_ctrl(panel_data, DSI_ALL_CLKS, 0); + mutex_unlock(&cabc_mutex); + return ret; + +} + +static int set_cabc_resume_mode(int mode) +{ + int ret=0; + + if (panel_data == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + printk("%s : %d yxr \n",__func__,mode); + switch(mode) + { + case 0: + mdss_dsi_panel_cmds_send(panel_data, &cabc_off_sequence); + break; + case 1: + mdss_dsi_panel_cmds_send(panel_data, &cabc_user_interface_image_sequence); + break; + case 2: + mdss_dsi_panel_cmds_send(panel_data, &cabc_still_image_sequence); + break; + case 3: + mdss_dsi_panel_cmds_send(panel_data, &cabc_video_image_sequence); + break; + default: + pr_err("%s %d is not supported!\n",__func__,mode); + ret = -1; + break; + } + return ret; +} + +#endif /*VENDOR_EDIT*/ + static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) { struct mdss_dsi_ctrl_pdata *ctrl = NULL; struct mdss_panel_info *pinfo; struct dsi_panel_cmds *on_cmds; + struct dsi_panel_cmds *on_cmds_shoushi; + //char rx_buf[32] = {0x0}; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } +#ifdef CONFIG_POWERSUSPEND + set_power_suspend_state_panel_hook(POWER_SUSPEND_INACTIVE); +#endif + pinfo = &pdata->panel_info; ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); @@ -635,14 +973,60 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) } on_cmds = &ctrl->on_cmds; + on_cmds_shoushi = &ctrl->on_cmds_shoushi; if ((pinfo->mipi.dms_mode == DYNAMIC_MODE_SWITCH_IMMEDIATE) && (pinfo->mipi.boot_mode != pinfo->mipi.mode)) on_cmds = &ctrl->post_dms_on_cmds; +#ifndef VENDOR_EDIT + memset(rx_buf, 0, sizeof(rx_buf)); + mdss_debug_enable_clock(1); + mdss_dsi_panel_cmd_read(ctrl, 0x0A, 0, NULL, rx_buf, 1); + printk("%s: before wake up Reg 0A: 0x%02x\n", __func__, rx_buf[0]); + mdss_debug_enable_clock(0); + if (on_cmds->cmd_cnt) + { + printk(KERN_ERR"Send the lcd initial cmd \n"); mdss_dsi_panel_cmds_send(ctrl, on_cmds); + } + + memset(rx_buf, 0, sizeof(rx_buf)); + mdss_debug_enable_clock(1); + mdss_dsi_panel_cmd_read(ctrl, 0x0A, 0, NULL, rx_buf, 1); + printk("%s: after wake up Reg 0A 0x%02x\n", __func__, rx_buf[0]); + memset(rx_buf, 0, sizeof(rx_buf)); + mdss_dsi_panel_cmd_read(ctrl, 0x0E, 0, NULL, rx_buf, 1); + printk("%s: TE Reg 0E 0x%02x\n", __func__, rx_buf[0]); + mdss_debug_enable_clock(0); +#else + if (on_cmds->cmd_cnt) + mdss_dsi_panel_cmds_send(ctrl, on_cmds); + +#endif + +#ifdef VENDOR_EDIT + /* Liqiu@oem.cn, 2015/05/02 add for resume cabc */ + if(cabc_mode != CABC_MIDDLE_MODE){ + set_cabc_resume_mode(cabc_mode); + } +#endif /*VENDOR_EDIT*/ +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 +#ifdef ESD_TE_Check_On + if((get_boot_mode() != MSM_BOOT_MODE__RF)&&(get_boot_mode() != MSM_BOOT_MODE__WLAN)) + { + schedule_delayed_work(&techeck_work, msecs_to_jiffies(5000)); + } +#endif +#endif /*VENDOR_EDIT*/ + +#ifdef VENDOR_EDIT //gzm@oem add 2015-04-01 for cabc function + mutex_lock(&cabc_mutex); + flag_lcd_off = false; + mutex_unlock(&cabc_mutex); +#endif end: pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK; pr_debug("%s:-\n", __func__); @@ -653,15 +1037,34 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) { struct mdss_dsi_ctrl_pdata *ctrl = NULL; struct mdss_panel_info *pinfo; +// char rx_buf[32] = {0x0}; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } +#ifdef VENDOR_EDIT + //LiQiu@oem.cn add 2015-04-29 + mutex_lock(&cabc_mutex); + flag_lcd_off = true; + mutex_unlock(&cabc_mutex); +#endif + +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 + +#ifdef ESD_TE_Check_On + if((get_boot_mode() != MSM_BOOT_MODE__RF)&&(get_boot_mode() != MSM_BOOT_MODE__WLAN)) + { + cancel_delayed_work_sync(&techeck_work); + } +#endif + +#endif/*VENDOR_EDIT*/ + pinfo = &pdata->panel_info; ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); @@ -670,9 +1073,25 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) goto end; } +// memset(rx_buf, 0, sizeof(rx_buf)); +// mdss_debug_enable_clock(1); +// mdss_dsi_panel_cmd_read(ctrl, 0x0A, 0, NULL, rx_buf, 1); +// printk("%s: before sleep Reg 0A 0x%02x\n", __func__, rx_buf[0]); +// mdss_debug_enable_clock(0); + if (ctrl->off_cmds.cmd_cnt) mdss_dsi_panel_cmds_send(ctrl, &ctrl->off_cmds); +// memset(rx_buf, 0, sizeof(rx_buf)); +// mdss_debug_enable_clock(1); +// mdss_dsi_panel_cmd_read(ctrl, 0x0A, 0, NULL, rx_buf, 1); +// printk("%s: after sleep Reg 0A 0x%02x\n", __func__, rx_buf[0]); +// mdss_debug_enable_clock(0); + +#ifdef CONFIG_POWERSUSPEND + set_power_suspend_state_panel_hook(POWER_SUSPEND_ACTIVE); +#endif + end: pinfo->blank_state = MDSS_PANEL_BLANK_BLANK; pr_debug("%s:-\n", __func__); @@ -680,7 +1099,7 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) } static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, - int enable) + int enable) { struct mdss_dsi_ctrl_pdata *ctrl = NULL; struct mdss_panel_info *pinfo; @@ -692,10 +1111,10 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, pinfo = &pdata->panel_info; ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); + panel_data); pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, - enable); + enable); /* Any panel specific low power commands/config */ if (enable) @@ -781,7 +1200,7 @@ static int mdss_dsi_parse_dcs_cmds(struct device_node *np, dchdr->dlen = ntohs(dchdr->dlen); if (dchdr->dlen > len) { pr_err("%s: dtsi cmd=%x error, len=%d", - __func__, dchdr->dtype, dchdr->dlen); + __func__, dchdr->dtype, dchdr->dlen); goto exit_free; } bp += sizeof(*dchdr); @@ -798,7 +1217,7 @@ static int mdss_dsi_parse_dcs_cmds(struct device_node *np, } pcmds->cmds = kzalloc(cnt * sizeof(struct dsi_cmd_desc), - GFP_KERNEL); + GFP_KERNEL); if (!pcmds->cmds) goto exit_free; @@ -830,7 +1249,7 @@ static int mdss_dsi_parse_dcs_cmds(struct device_node *np, } pr_debug("%s: dcs_cmd=%x len=%d, cmd_cnt=%d link_state=%d\n", __func__, - pcmds->buf[0], pcmds->blen, pcmds->cmd_cnt, pcmds->link_state); + pcmds->buf[0], pcmds->blen, pcmds->cmd_cnt, pcmds->link_state); return 0; @@ -841,74 +1260,74 @@ static int mdss_dsi_parse_dcs_cmds(struct device_node *np, int mdss_panel_get_dst_fmt(u32 bpp, char mipi_mode, u32 pixel_packing, - char *dst_format) + char *dst_format) { int rc = 0; switch (bpp) { - case 3: - *dst_format = DSI_CMD_DST_FORMAT_RGB111; - break; - case 8: - *dst_format = DSI_CMD_DST_FORMAT_RGB332; - break; - case 12: - *dst_format = DSI_CMD_DST_FORMAT_RGB444; - break; - case 16: - switch (mipi_mode) { - case DSI_VIDEO_MODE: - *dst_format = DSI_VIDEO_DST_FORMAT_RGB565; + case 3: + *dst_format = DSI_CMD_DST_FORMAT_RGB111; break; - case DSI_CMD_MODE: - *dst_format = DSI_CMD_DST_FORMAT_RGB565; + case 8: + *dst_format = DSI_CMD_DST_FORMAT_RGB332; break; - default: - *dst_format = DSI_VIDEO_DST_FORMAT_RGB565; + case 12: + *dst_format = DSI_CMD_DST_FORMAT_RGB444; break; - } - break; - case 18: - switch (mipi_mode) { - case DSI_VIDEO_MODE: - if (pixel_packing == 0) - *dst_format = DSI_VIDEO_DST_FORMAT_RGB666; - else - *dst_format = DSI_VIDEO_DST_FORMAT_RGB666_LOOSE; - break; - case DSI_CMD_MODE: - *dst_format = DSI_CMD_DST_FORMAT_RGB666; - break; - default: - if (pixel_packing == 0) - *dst_format = DSI_VIDEO_DST_FORMAT_RGB666; - else - *dst_format = DSI_VIDEO_DST_FORMAT_RGB666_LOOSE; + case 16: + switch (mipi_mode) { + case DSI_VIDEO_MODE: + *dst_format = DSI_VIDEO_DST_FORMAT_RGB565; + break; + case DSI_CMD_MODE: + *dst_format = DSI_CMD_DST_FORMAT_RGB565; + break; + default: + *dst_format = DSI_VIDEO_DST_FORMAT_RGB565; + break; + } break; - } - break; - case 24: - switch (mipi_mode) { - case DSI_VIDEO_MODE: - *dst_format = DSI_VIDEO_DST_FORMAT_RGB888; + case 18: + switch (mipi_mode) { + case DSI_VIDEO_MODE: + if (pixel_packing == 0) + *dst_format = DSI_VIDEO_DST_FORMAT_RGB666; + else + *dst_format = DSI_VIDEO_DST_FORMAT_RGB666_LOOSE; + break; + case DSI_CMD_MODE: + *dst_format = DSI_CMD_DST_FORMAT_RGB666; + break; + default: + if (pixel_packing == 0) + *dst_format = DSI_VIDEO_DST_FORMAT_RGB666; + else + *dst_format = DSI_VIDEO_DST_FORMAT_RGB666_LOOSE; + break; + } break; - case DSI_CMD_MODE: - *dst_format = DSI_CMD_DST_FORMAT_RGB888; + case 24: + switch (mipi_mode) { + case DSI_VIDEO_MODE: + *dst_format = DSI_VIDEO_DST_FORMAT_RGB888; + break; + case DSI_CMD_MODE: + *dst_format = DSI_CMD_DST_FORMAT_RGB888; + break; + default: + *dst_format = DSI_VIDEO_DST_FORMAT_RGB888; + break; + } break; default: - *dst_format = DSI_VIDEO_DST_FORMAT_RGB888; + rc = -EINVAL; break; - } - break; - default: - rc = -EINVAL; - break; } return rc; } static int mdss_dsi_parse_fbc_params(struct device_node *np, - struct mdss_panel_info *panel_info) + struct mdss_panel_info *panel_info) { int rc, fbc_enabled = 0; u32 tmp; @@ -923,7 +1342,7 @@ static int mdss_dsi_parse_fbc_params(struct device_node *np, &tmp); panel_info->fbc.comp_mode = (!rc ? tmp : 0); panel_info->fbc.qerr_enable = of_property_read_bool(np, - "qcom,mdss-dsi-fbc-quant-error"); + "qcom,mdss-dsi-fbc-quant-error"); rc = of_property_read_u32(np, "qcom,mdss-dsi-fbc-bias", &tmp); panel_info->fbc.cd_bias = (!rc ? tmp : 0); panel_info->fbc.pat_enable = of_property_read_bool(np, @@ -974,7 +1393,7 @@ static int mdss_dsi_parse_fbc_params(struct device_node *np, } static void mdss_panel_parse_te_params(struct device_node *np, - struct mdss_panel_info *panel_info) + struct mdss_panel_info *panel_info) { u32 tmp; @@ -1022,12 +1441,12 @@ static int mdss_dsi_parse_reset_seq(struct device_node *np, num /= sizeof(u32); if (!data || !num || num > MDSS_DSI_RST_SEQ_LEN || num % 2) { pr_debug("%s:%d, error reading %s, length found = %d\n", - __func__, __LINE__, name, num); + __func__, __LINE__, name, num); } else { rc = of_property_read_u32_array(np, name, tmp, num); if (rc) pr_debug("%s:%d, error reading %s, rc = %d\n", - __func__, __LINE__, name, rc); + __func__, __LINE__, name, rc); else { for (i = 0; i < num; ++i) rst_seq[i] = tmp[i]; @@ -1040,9 +1459,9 @@ static int mdss_dsi_parse_reset_seq(struct device_node *np, static int mdss_dsi_gen_read_status(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { if (!mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, - ctrl_pdata->status_value, 0)) { + ctrl_pdata->status_value, 0)) { pr_err("%s: Read back value from panel is incorrect\n", - __func__); + __func__); return -EINVAL; } else { return 1; @@ -1052,20 +1471,20 @@ static int mdss_dsi_gen_read_status(struct mdss_dsi_ctrl_pdata *ctrl_pdata) static int mdss_dsi_nt35596_read_status(struct mdss_dsi_ctrl_pdata *ctrl_pdata) { if (!mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, - ctrl_pdata->status_value, 0)) { + ctrl_pdata->status_value, 0)) { ctrl_pdata->status_error_count = 0; pr_err("%s: Read back value from panel is incorrect\n", - __func__); + __func__); return -EINVAL; } else { if (!mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, - ctrl_pdata->status_value, 3)) { + ctrl_pdata->status_value, 3)) { ctrl_pdata->status_error_count = 0; } else { if (mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, - ctrl_pdata->status_value, 4) || - mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, - ctrl_pdata->status_value, 5)) + ctrl_pdata->status_value, 4) || + mdss_dsi_cmp_panel_reg(ctrl_pdata->status_buf, + ctrl_pdata->status_value, 5)) ctrl_pdata->status_error_count = 0; else ctrl_pdata->status_error_count++; @@ -1073,8 +1492,8 @@ static int mdss_dsi_nt35596_read_status(struct mdss_dsi_ctrl_pdata *ctrl_pdata) ctrl_pdata->max_status_error_count) { ctrl_pdata->status_error_count = 0; pr_err("%s: Read value bad. Error_cnt = %i\n", - __func__, - ctrl_pdata->status_error_count); + __func__, + ctrl_pdata->status_error_count); return -EINVAL; } } @@ -1116,14 +1535,14 @@ static void mdss_dsi_parse_roi_alignment(struct device_node *np, } static void mdss_dsi_parse_dms_config(struct device_node *np, - struct mdss_dsi_ctrl_pdata *ctrl) + struct mdss_dsi_ctrl_pdata *ctrl) { struct mdss_panel_info *pinfo = &ctrl->panel_data.panel_info; const char *data; bool dms_enabled; dms_enabled = of_property_read_bool(np, - "qcom,dynamic-mode-switch-enabled"); + "qcom,dynamic-mode-switch-enabled"); if (!dms_enabled) { pinfo->mipi.dms_mode = DYNAMIC_MODE_SWITCH_DISABLED; @@ -1139,34 +1558,34 @@ static void mdss_dsi_parse_dms_config(struct device_node *np, pr_debug("%s: default dms suspend/resume\n", __func__); mdss_dsi_parse_dcs_cmds(np, &ctrl->video2cmd, - "qcom,video-to-cmd-mode-switch-commands", NULL); + "qcom,video-to-cmd-mode-switch-commands", NULL); mdss_dsi_parse_dcs_cmds(np, &ctrl->cmd2video, - "qcom,cmd-to-video-mode-switch-commands", NULL); + "qcom,cmd-to-video-mode-switch-commands", NULL); mdss_dsi_parse_dcs_cmds(np, &ctrl->post_dms_on_cmds, - "qcom,mdss-dsi-post-mode-switch-on-command", - "qcom,mdss-dsi-post-mode-switch-on-command-state"); + "qcom,mdss-dsi-post-mode-switch-on-command", + "qcom,mdss-dsi-post-mode-switch-on-command-state"); if (pinfo->mipi.dms_mode == DYNAMIC_MODE_SWITCH_IMMEDIATE && - !ctrl->post_dms_on_cmds.cmd_cnt) { + !ctrl->post_dms_on_cmds.cmd_cnt) { pr_warn("%s: No post dms on cmd specified\n", __func__); pinfo->mipi.dms_mode = DYNAMIC_MODE_SWITCH_DISABLED; } if (!ctrl->video2cmd.cmd_cnt || !ctrl->cmd2video.cmd_cnt) { pr_warn("%s: No commands specified for dynamic switch\n", - __func__); + __func__); pinfo->mipi.dms_mode = DYNAMIC_MODE_SWITCH_DISABLED; } exit: pr_info("%s: dynamic switch feature enabled: %d\n", __func__, - pinfo->mipi.dms_mode); + pinfo->mipi.dms_mode); return; } static void mdss_dsi_parse_esd_params(struct device_node *np, - struct mdss_dsi_ctrl_pdata *ctrl) + struct mdss_dsi_ctrl_pdata *ctrl) { u32 tmp; int rc; @@ -1175,28 +1594,28 @@ static void mdss_dsi_parse_esd_params(struct device_node *np, struct mdss_panel_info *pinfo = &ctrl->panel_data.panel_info; pinfo->esd_check_enabled = of_property_read_bool(np, - "qcom,esd-check-enabled"); + "qcom,esd-check-enabled"); if (!pinfo->esd_check_enabled) return; mdss_dsi_parse_dcs_cmds(np, &ctrl->status_cmds, "qcom,mdss-dsi-panel-status-command", - "qcom,mdss-dsi-panel-status-command-state"); + "qcom,mdss-dsi-panel-status-command-state"); rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-status-read-length", - &tmp); + &tmp); ctrl->status_cmds_rlen = (!rc ? tmp : 1); rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-max-error-count", - &tmp); + &tmp); ctrl->max_status_error_count = (!rc ? tmp : 0); ctrl->status_value = kzalloc(sizeof(u32) * ctrl->status_cmds_rlen, - GFP_KERNEL); + GFP_KERNEL); if (!ctrl->status_value) { pr_err("%s: Error allocating memory for status buffer\n", - __func__); + __func__); pinfo->esd_check_enabled = false; return; } @@ -1208,8 +1627,8 @@ static void mdss_dsi_parse_esd_params(struct device_node *np, memset(ctrl->status_value, 0, ctrl->status_cmds_rlen); } else { rc = of_property_read_u32_array(np, - "qcom,mdss-dsi-panel-status-value", - ctrl->status_value, tmp); + "qcom,mdss-dsi-panel-status-value", + ctrl->status_value, tmp); if (rc) { pr_debug("%s: Error reading panel status values\n", __func__); @@ -1252,7 +1671,7 @@ static void mdss_dsi_parse_esd_params(struct device_node *np, } static int mdss_dsi_parse_panel_features(struct device_node *np, - struct mdss_dsi_ctrl_pdata *ctrl) + struct mdss_dsi_ctrl_pdata *ctrl) { struct mdss_panel_info *pinfo; @@ -1264,10 +1683,10 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, pinfo = &ctrl->panel_data.panel_info; pinfo->cont_splash_enabled = of_property_read_bool(np, - "qcom,cont-splash-enabled"); + "qcom,cont-splash-enabled"); pinfo->partial_update_supported = of_property_read_bool(np, - "qcom,partial-update-enabled"); + "qcom,partial-update-enabled"); if (pinfo->mipi.mode == DSI_CMD_MODE) { pinfo->partial_update_enabled = pinfo->partial_update_supported; pr_info("%s: partial_update_enabled=%d\n", __func__, @@ -1275,28 +1694,28 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr; if (pinfo->partial_update_enabled) { pinfo->partial_update_roi_merge = - of_property_read_bool(np, - "qcom,partial-update-roi-merge"); + of_property_read_bool(np, + "qcom,partial-update-roi-merge"); } pinfo->dcs_cmd_by_left = of_property_read_bool(np, - "qcom,dcs-cmd-by-left"); + "qcom,dcs-cmd-by-left"); } pinfo->ulps_feature_enabled = of_property_read_bool(np, - "qcom,ulps-enabled"); + "qcom,ulps-enabled"); pr_info("%s: ulps feature %s\n", __func__, - (pinfo->ulps_feature_enabled ? "enabled" : "disabled")); + (pinfo->ulps_feature_enabled ? "enabled" : "disabled")); pinfo->ulps_suspend_enabled = of_property_read_bool(np, - "qcom,suspend-ulps-enabled"); + "qcom,suspend-ulps-enabled"); pr_info("%s: ulps during suspend feature %s", __func__, - (pinfo->ulps_suspend_enabled ? "enabled" : "disabled")); + (pinfo->ulps_suspend_enabled ? "enabled" : "disabled")); mdss_dsi_parse_dms_config(np, ctrl); pinfo->panel_ack_disabled = of_property_read_bool(np, - "qcom,panel-ack-disabled"); + "qcom,panel-ack-disabled"); mdss_dsi_parse_esd_params(np, ctrl); @@ -1307,8 +1726,8 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, if (ctrl->disp_en_gpio <= 0) { ctrl->disp_en_gpio = of_get_named_gpio( - np, - "qcom,5v-boost-gpio", 0); + np, + "qcom,5v-boost-gpio", 0); if (!gpio_is_valid(ctrl->disp_en_gpio)) pr_err("%s:%d, Disp_en gpio not specified\n", @@ -1319,7 +1738,7 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, } static void mdss_dsi_parse_panel_horizintal_line_idle(struct device_node *np, - struct mdss_dsi_ctrl_pdata *ctrl) + struct mdss_dsi_ctrl_pdata *ctrl) { const u32 *src; int i, len, cnt; @@ -1358,7 +1777,7 @@ static void mdss_dsi_parse_panel_horizintal_line_idle(struct device_node *np, } pr_debug("%s: horizontal_idle_cnt=%d\n", __func__, - ctrl->horizontal_idle_cnt); + ctrl->horizontal_idle_cnt); } static int mdss_dsi_set_refresh_rate_range(struct device_node *pan_node, @@ -1402,7 +1821,7 @@ static int mdss_dsi_set_refresh_rate_range(struct device_node *pan_node, } static void mdss_dsi_parse_dfps_config(struct device_node *pan_node, - struct mdss_dsi_ctrl_pdata *ctrl_pdata) + struct mdss_dsi_ctrl_pdata *ctrl_pdata) { const char *data; bool dynamic_fps; @@ -1446,7 +1865,7 @@ static void mdss_dsi_parse_dfps_config(struct device_node *pan_node, } static int mdss_panel_parse_dt(struct device_node *np, - struct mdss_dsi_ctrl_pdata *ctrl_pdata) + struct mdss_dsi_ctrl_pdata *ctrl_pdata) { u32 tmp; int rc, i, len; @@ -1457,7 +1876,7 @@ static int mdss_panel_parse_dt(struct device_node *np, rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-width", &tmp); if (rc) { pr_err("%s:%d, panel width not specified\n", - __func__, __LINE__); + __func__, __LINE__); return -EINVAL; } pinfo->xres = (!rc ? tmp : 640); @@ -1465,16 +1884,16 @@ static int mdss_panel_parse_dt(struct device_node *np, rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-height", &tmp); if (rc) { pr_err("%s:%d, panel height not specified\n", - __func__, __LINE__); + __func__, __LINE__); return -EINVAL; } pinfo->yres = (!rc ? tmp : 480); rc = of_property_read_u32(np, - "qcom,mdss-pan-physical-width-dimension", &tmp); + "qcom,mdss-pan-physical-width-dimension", &tmp); pinfo->physical_width = (!rc ? tmp : 0); rc = of_property_read_u32(np, - "qcom,mdss-pan-physical-height-dimension", &tmp); + "qcom,mdss-pan-physical-height-dimension", &tmp); pinfo->physical_height = (!rc ? tmp : 0); rc = of_property_read_u32(np, "qcom,mdss-dsi-h-left-border", &tmp); pinfo->lcdc.border_left = (!rc ? tmp : 0); @@ -1483,7 +1902,7 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->lcdc.border_right = tmp; pinfo->lcdc.xres_pad = (pinfo->lcdc.border_left + - pinfo->lcdc.border_right); + pinfo->lcdc.border_right); rc = of_property_read_u32(np, "qcom,mdss-dsi-v-top-border", &tmp); pinfo->lcdc.border_top = (!rc ? tmp : 0); @@ -1492,7 +1911,7 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->lcdc.border_bottom = tmp; pinfo->lcdc.yres_pad = (pinfo->lcdc.border_top + - pinfo->lcdc.border_bottom); + pinfo->lcdc.border_bottom); rc = of_property_read_u32(np, "qcom,mdss-dsi-bpp", &tmp); if (rc) { @@ -1512,16 +1931,16 @@ static int mdss_panel_parse_dt(struct device_node *np, else pinfo->mipi.pixel_packing = 0; rc = mdss_panel_get_dst_fmt(pinfo->bpp, - pinfo->mipi.mode, pinfo->mipi.pixel_packing, - &(pinfo->mipi.dst_format)); + pinfo->mipi.mode, pinfo->mipi.pixel_packing, + &(pinfo->mipi.dst_format)); if (rc) { pr_debug("%s: problem determining dst format. Set Default\n", - __func__); + __func__); pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888; } pdest = of_get_property(np, - "qcom,mdss-dsi-panel-destination", NULL); + "qcom,mdss-dsi-panel-destination", NULL); if (pdest) { if (strlen(pdest) != 9) { @@ -1534,7 +1953,7 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->pdest = DISPLAY_2; else { pr_debug("%s: incorrect pdest. Set Default\n", - __func__); + __func__); pinfo->pdest = DISPLAY_1; } } else { @@ -1557,10 +1976,10 @@ static int mdss_panel_parse_dt(struct device_node *np, rc = of_property_read_u32(np, "qcom,mdss-dsi-v-pulse-width", &tmp); pinfo->lcdc.v_pulse_width = (!rc ? tmp : 2); rc = of_property_read_u32(np, - "qcom,mdss-dsi-underflow-color", &tmp); + "qcom,mdss-dsi-underflow-color", &tmp); pinfo->lcdc.underflow_clr = (!rc ? tmp : 0xff); rc = of_property_read_u32(np, - "qcom,mdss-dsi-border-color", &tmp); + "qcom,mdss-dsi-border-color", &tmp); pinfo->lcdc.border_clr = (!rc ? tmp : 0); data = of_get_property(np, "qcom,mdss-dsi-panel-orientation", NULL); if (data) { @@ -1578,16 +1997,16 @@ static int mdss_panel_parse_dt(struct device_node *np, if (data) { if (!strncmp(data, "bl_ctrl_wled", 12)) { led_trigger_register_simple("bkl-trigger", - &bl_led_trigger); + &bl_led_trigger); pr_debug("%s: SUCCESS-> WLED TRIGGER register\n", - __func__); + __func__); ctrl_pdata->bklt_ctrl = BL_WLED; } else if (!strncmp(data, "bl_ctrl_pwm", 11)) { ctrl_pdata->bklt_ctrl = BL_PWM; ctrl_pdata->pwm_pmi = of_property_read_bool(np, "qcom,mdss-dsi-bl-pwm-pmi"); rc = of_property_read_u32(np, - "qcom,mdss-dsi-bl-pmic-pwm-frequency", &tmp); + "qcom,mdss-dsi-bl-pmic-pwm-frequency", &tmp); if (rc) { pr_err("%s:%d, Error, panel pwm_period\n", __func__, __LINE__); @@ -1598,14 +2017,14 @@ static int mdss_panel_parse_dt(struct device_node *np, ctrl_pdata->pwm_bl = of_pwm_get(np, NULL); if (IS_ERR(ctrl_pdata->pwm_bl)) { pr_err("%s: Error, pwm device\n", - __func__); + __func__); ctrl_pdata->pwm_bl = NULL; return -EINVAL; } } else { rc = of_property_read_u32(np, - "qcom,mdss-dsi-bl-pmic-bank-select", - &tmp); + "qcom,mdss-dsi-bl-pmic-bank-select", + &tmp); if (rc) { pr_err("%s:%d, Error, lpg channel\n", __func__, __LINE__); @@ -1613,15 +2032,15 @@ static int mdss_panel_parse_dt(struct device_node *np, } ctrl_pdata->pwm_lpg_chan = tmp; tmp = of_get_named_gpio(np, - "qcom,mdss-dsi-pwm-gpio", 0); + "qcom,mdss-dsi-pwm-gpio", 0); ctrl_pdata->pwm_pmic_gpio = tmp; pr_debug("%s: Configured PWM bklt ctrl\n", - __func__); + __func__); } } else if (!strncmp(data, "bl_ctrl_dcs", 11)) { ctrl_pdata->bklt_ctrl = BL_DCS_CMD; pr_debug("%s: Configured DCS_CMD bklt ctrl\n", - __func__); + __func__); } } rc = of_property_read_u32(np, "qcom,mdss-brightness-max-level", &tmp); @@ -1636,26 +2055,26 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->mipi.interleave_mode = (!rc ? tmp : 0); pinfo->mipi.vsync_enable = of_property_read_bool(np, - "qcom,mdss-dsi-te-check-enable"); + "qcom,mdss-dsi-te-check-enable"); pinfo->mipi.hw_vsync_mode = of_property_read_bool(np, - "qcom,mdss-dsi-te-using-te-pin"); + "qcom,mdss-dsi-te-using-te-pin"); rc = of_property_read_u32(np, - "qcom,mdss-dsi-h-sync-pulse", &tmp); + "qcom,mdss-dsi-h-sync-pulse", &tmp); pinfo->mipi.pulse_mode_hsa_he = (!rc ? tmp : false); pinfo->mipi.hfp_power_stop = of_property_read_bool(np, - "qcom,mdss-dsi-hfp-power-mode"); + "qcom,mdss-dsi-hfp-power-mode"); pinfo->mipi.hsa_power_stop = of_property_read_bool(np, - "qcom,mdss-dsi-hsa-power-mode"); + "qcom,mdss-dsi-hsa-power-mode"); pinfo->mipi.hbp_power_stop = of_property_read_bool(np, - "qcom,mdss-dsi-hbp-power-mode"); + "qcom,mdss-dsi-hbp-power-mode"); pinfo->mipi.last_line_interleave_en = of_property_read_bool(np, - "qcom,mdss-dsi-last-line-interleave"); + "qcom,mdss-dsi-last-line-interleave"); pinfo->mipi.bllp_power_stop = of_property_read_bool(np, - "qcom,mdss-dsi-bllp-power-mode"); + "qcom,mdss-dsi-bllp-power-mode"); pinfo->mipi.eof_bllp_power_stop = of_property_read_bool( - np, "qcom,mdss-dsi-bllp-eof-power-mode"); + np, "qcom,mdss-dsi-bllp-eof-power-mode"); pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE; data = of_get_property(np, "qcom,mdss-dsi-traffic-mode", NULL); if (data) { @@ -1665,21 +2084,21 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->mipi.traffic_mode = DSI_BURST_MODE; } rc = of_property_read_u32(np, - "qcom,mdss-dsi-te-dcs-command", &tmp); + "qcom,mdss-dsi-te-dcs-command", &tmp); pinfo->mipi.insert_dcs_cmd = - (!rc ? tmp : 1); + (!rc ? tmp : 1); rc = of_property_read_u32(np, - "qcom,mdss-dsi-wr-mem-continue", &tmp); + "qcom,mdss-dsi-wr-mem-continue", &tmp); pinfo->mipi.wr_mem_continue = - (!rc ? tmp : 0x3c); + (!rc ? tmp : 0x3c); rc = of_property_read_u32(np, - "qcom,mdss-dsi-wr-mem-start", &tmp); + "qcom,mdss-dsi-wr-mem-start", &tmp); pinfo->mipi.wr_mem_start = - (!rc ? tmp : 0x2c); + (!rc ? tmp : 0x2c); rc = of_property_read_u32(np, - "qcom,mdss-dsi-te-pin-select", &tmp); + "qcom,mdss-dsi-te-pin-select", &tmp); pinfo->mipi.te_sel = - (!rc ? tmp : 1); + (!rc ? tmp : 1); rc = of_property_read_u32(np, "qcom,mdss-dsi-virtual-channel-id", &tmp); pinfo->mipi.vc = (!rc ? tmp : 0); pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB; @@ -1697,13 +2116,13 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->mipi.rgb_swap = DSI_RGB_SWAP_GBR; } pinfo->mipi.data_lane0 = of_property_read_bool(np, - "qcom,mdss-dsi-lane-0-state"); + "qcom,mdss-dsi-lane-0-state"); pinfo->mipi.data_lane1 = of_property_read_bool(np, - "qcom,mdss-dsi-lane-1-state"); + "qcom,mdss-dsi-lane-1-state"); pinfo->mipi.data_lane2 = of_property_read_bool(np, - "qcom,mdss-dsi-lane-2-state"); + "qcom,mdss-dsi-lane-2-state"); pinfo->mipi.data_lane3 = of_property_read_bool(np, - "qcom,mdss-dsi-lane-3-state"); + "qcom,mdss-dsi-lane-3-state"); rc = of_property_read_u32(np, "qcom,mdss-dsi-t-clk-pre", &tmp); pinfo->mipi.t_clk_pre = (!rc ? tmp : 0x24); @@ -1711,9 +2130,9 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->mipi.t_clk_post = (!rc ? tmp : 0x03); pinfo->mipi.rx_eot_ignore = of_property_read_bool(np, - "qcom,mdss-dsi-rx-eot-ignore"); + "qcom,mdss-dsi-rx-eot-ignore"); pinfo->mipi.tx_eot_append = of_property_read_bool(np, - "qcom,mdss-dsi-tx-eot-append"); + "qcom,mdss-dsi-tx-eot-append"); rc = of_property_read_u32(np, "qcom,mdss-dsi-stream", &tmp); pinfo->mipi.stream = (!rc ? tmp : 0); @@ -1735,42 +2154,54 @@ static int mdss_panel_parse_dt(struct device_node *np, data = of_get_property(np, "qcom,mdss-dsi-panel-timings", &len); if ((!data) || (len != 12)) { pr_err("%s:%d, Unable to read Phy timing settings", - __func__, __LINE__); + __func__, __LINE__); goto error; } for (i = 0; i < len; i++) pinfo->mipi.dsi_phy_db.timing[i] = data[i]; pinfo->mipi.lp11_init = of_property_read_bool(np, - "qcom,mdss-dsi-lp11-init"); + "qcom,mdss-dsi-lp11-init"); rc = of_property_read_u32(np, "qcom,mdss-dsi-init-delay-us", &tmp); pinfo->mipi.init_delay = (!rc ? tmp : 0); mdss_dsi_parse_roi_alignment(np, pinfo); mdss_dsi_parse_trigger(np, &(pinfo->mipi.mdp_trigger), - "qcom,mdss-dsi-mdp-trigger"); + "qcom,mdss-dsi-mdp-trigger"); mdss_dsi_parse_trigger(np, &(pinfo->mipi.dma_trigger), - "qcom,mdss-dsi-dma-trigger"); + "qcom,mdss-dsi-dma-trigger"); mdss_dsi_parse_lane_swap(np, &(pinfo->mipi.dlane_swap)); mdss_dsi_parse_fbc_params(np, pinfo); mdss_panel_parse_te_params(np, pinfo); +#ifdef VENDOR_EDIT /*guozhiming add for CABC function 2015-04-01*/ + mdss_dsi_parse_dcs_cmds(np, &cabc_off_sequence, + "qcom,mdss-dsi-cabc-off-command", "qcom,mdss-dsi-off-command-state"); + mdss_dsi_parse_dcs_cmds(np, &cabc_user_interface_image_sequence, + "qcom,mdss-dsi-cabc-ui-command", "qcom,mdss-dsi-off-command-state"); + mdss_dsi_parse_dcs_cmds(np, &cabc_still_image_sequence, + "qcom,mdss-dsi-cabc-still-image-command", "qcom,mdss-dsi-off-command-state"); + mdss_dsi_parse_dcs_cmds(np, &cabc_video_image_sequence, + "qcom,mdss-dsi-cabc-video-command", "qcom,mdss-dsi-off-command-state"); + mdss_dsi_parse_dcs_cmds(np, &oa_sequence, "qcom,mdss-dsi-on-command-oa", "qcom,mdss-dsi-on-command-state"); +#endif mdss_dsi_parse_reset_seq(np, pinfo->rst_seq, &(pinfo->rst_seq_len), - "qcom,mdss-dsi-reset-sequence"); + "qcom,mdss-dsi-reset-sequence"); mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->on_cmds, - "qcom,mdss-dsi-on-command", "qcom,mdss-dsi-on-command-state"); - + "qcom,mdss-dsi-on-command", "qcom,mdss-dsi-on-command-state"); + mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->on_cmds_shoushi, + "qcom,mdss-dsi-on-command_shoushi", "qcom,mdss-dsi-on-command-state"); mdss_dsi_parse_dcs_cmds(np, &ctrl_pdata->off_cmds, - "qcom,mdss-dsi-off-command", "qcom,mdss-dsi-off-command-state"); + "qcom,mdss-dsi-off-command", "qcom,mdss-dsi-off-command-state"); pinfo->mipi.force_clk_lane_hs = of_property_read_bool(np, - "qcom,mdss-dsi-force-clock-lane-hs"); + "qcom,mdss-dsi-force-clock-lane-hs"); rc = mdss_dsi_parse_panel_features(np, ctrl_pdata); if (rc) { @@ -1789,12 +2220,19 @@ static int mdss_panel_parse_dt(struct device_node *np, } int mdss_dsi_panel_init(struct device_node *node, - struct mdss_dsi_ctrl_pdata *ctrl_pdata, - bool cmd_cfg_cont_splash) + struct mdss_dsi_ctrl_pdata *ctrl_pdata, + bool cmd_cfg_cont_splash) { int rc = 0; static const char *panel_name; struct mdss_panel_info *pinfo; +#ifdef VENDOR_EDIT + static const char *panel_manufacture; + static const char *panel_version; + static const char *backlight_manufacture; + static const char *backlight_version; + panel_data = ctrl_pdata; +#endif if (!node || !ctrl_pdata) { pr_err("%s: Invalid arguments\n", __func__); @@ -1808,7 +2246,7 @@ int mdss_dsi_panel_init(struct device_node *node, panel_name = of_get_property(node, "qcom,mdss-dsi-panel-name", NULL); if (!panel_name) { pr_info("%s:%d, Panel name not specified\n", - __func__, __LINE__); + __func__, __LINE__); } else { pr_info("%s: Panel Name = %s\n", __func__, panel_name); strlcpy(&pinfo->panel_name[0], panel_name, MDSS_MAX_PANEL_LEN); @@ -1822,12 +2260,67 @@ int mdss_dsi_panel_init(struct device_node *node, if (!cmd_cfg_cont_splash) pinfo->cont_splash_enabled = false; pr_info("%s: Continuous splash %s\n", __func__, - pinfo->cont_splash_enabled ? "enabled" : "disabled"); + pinfo->cont_splash_enabled ? "enabled" : "disabled"); pinfo->dynamic_switch_pending = false; pinfo->is_lpm_mode = false; pinfo->esd_rdy = false; +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 + +#ifdef ESD_TE_Check_On + if((get_boot_mode() !=MSM_BOOT_MODE__RF)&&(get_boot_mode() !=MSM_BOOT_MODE__WLAN)) + { + init_completion(&te_comp); + gpio_request(986,"lcd_esd_te_check"); + gpio_direction_input(986); + irq = gpio_to_irq(986); + rc = request_threaded_irq(irq, TE_irq_thread_fn, NULL, + IRQF_TRIGGER_RISING, "LCD_TE",NULL); + if (rc < 0) { + pr_err("Unable to register IRQ handler\n"); + return -ENODEV; + } + disable_irq(irq); + INIT_DELAYED_WORK(&techeck_work, techeck_work_func ); + schedule_delayed_work(&techeck_work, msecs_to_jiffies(30000)); + display_switch.name = "dispswitch"; + + rc = switch_dev_register(&display_switch); + if (rc) + { + pr_err("Unable to register display switch device\n"); + return rc; + } + /*dir: /sys/class/mdss_lcd/lcd_control*/ + mdss_lcd = class_create(THIS_MODULE,"mdss_lcd"); + mdss_lcd->dev_attrs = mdss_lcd_attrs; + device_create(mdss_lcd,dev_lcd,0,NULL,"lcd_control"); + } +#endif + + +#ifdef VENDOR_EDIT //gzm@oem add 2015-03-28 + panel_manufacture = of_get_property(node, "qcom,mdss-dsi-panel-manufacture", NULL); + if (!panel_manufacture) + pr_info("%s:%d, panel manufacture not specified\n", __func__, __LINE__); + else + pr_info("%s: Panel Manufacture = %s\n", __func__, panel_manufacture); + panel_version = of_get_property(node, "qcom,mdss-dsi-panel-version", NULL); + if (!panel_version) + pr_info("%s:%d, panel version not specified\n", __func__, __LINE__); + else + pr_info("%s: Panel Version = %s\n", __func__, panel_version); + + backlight_version = of_get_property(node, "qcom,mdss-dsi-backlight-version", NULL); + backlight_manufacture =of_get_property(node, "qcom,mdss-dsi-backlight-manufacture", NULL); + + push_component_info(LCD, (char *)panel_version, (char *)panel_manufacture); + push_component_info(BACKLIGHT, (char *)backlight_version, (char *)backlight_manufacture); +#endif + + +#endif /*VENDOR_EDIT*/ ctrl_pdata->on = mdss_dsi_panel_on; ctrl_pdata->off = mdss_dsi_panel_off; ctrl_pdata->low_power_config = mdss_dsi_panel_low_power_config; diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c old mode 100644 new mode 100755 index 1be29687d6963..6376f04f23d08 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -54,6 +54,7 @@ #include "mdss_mdp_splash_logo.h" #define CREATE_TRACE_POINTS #include "mdss_debug.h" +#include "mdss_mdp.h" #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER #define MDSS_FB_NUM 3 @@ -246,6 +247,10 @@ static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev, { struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent); int bl_lvl; + #ifdef VENDOR_EDIT + /*ykl add for debug lcd issue*/ + static int count = 1; + #endif if (mfd->boot_notification_led) { led_trigger_event(mfd->boot_notification_led, 0); @@ -255,6 +260,15 @@ static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev, if (value > mfd->panel_info->brightness_max) value = mfd->panel_info->brightness_max; + #ifdef VENDOR_EDIT /*ykl add for debug lcd issue*/ + if(count || !value){ + printk("--------backlight level = %d---------\n",value); + count = 0; + } + + if(!value) + count = 1; + #endif /* This maps android backlight level 0 to 255 into driver backlight level 0 to bl_max with rounding */ MDSS_BRIGHT_TO_BL(bl_lvl, value, mfd->panel_info->bl_max, @@ -745,6 +759,114 @@ static ssize_t mdss_fb_get_dfps_mode(struct device *dev, return ret; } +#ifdef VENDOR_EDIT/* guozhiming@oem Add for set cabc function 2015-04-01 */ + +extern int set_cabc(int level); +extern int cabc_mode; + +static ssize_t mdss_get_cabc(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + return sprintf(buf, "%d\n", cabc_mode); + +} + +static ssize_t mdss_set_cabc(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int level = 0; + sscanf(buf, "%du", &level); + set_cabc(level); + return count; +} + +#endif /*VENDOR_EDIT*/ + +static int pcc_r = 32768, pcc_g = 32768, pcc_b = 32768; +static ssize_t mdss_get_rgb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 copyback = 0; + struct mdp_pcc_cfg_data pcc_cfg; + + memset(&pcc_cfg, 0, sizeof(struct mdp_pcc_cfg_data)); + + pcc_cfg.block = MDP_LOGICAL_BLOCK_DISP_0; + pcc_cfg.ops = MDP_PP_OPS_READ; + + mdss_mdp_pcc_config(&pcc_cfg, ©back); + + /* We disable pcc when using default values and reg + * are zeroed on pp resume, so ignore empty values. + */ + if (pcc_cfg.r.r && pcc_cfg.g.g && pcc_cfg.b.b) { + pcc_r = pcc_cfg.r.r; + pcc_g = pcc_cfg.g.g; + pcc_b = pcc_cfg.b.b; + } + + return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", pcc_r, pcc_g, pcc_b); +} + +/* + * simple color temperature interface using polynomial color correction + * + * input values are r/g/b adjustments from 0-32768 representing 0 -> 1 + * + * example adjustment @ 3500K: + * 1.0000 / 0.5515 / 0.2520 = 32768 / 25828 / 17347 + * + * reference chart: + * http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html + */ +static ssize_t mdss_set_rgb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + uint32_t r = 0, g = 0, b = 0; + struct mdp_pcc_cfg_data pcc_cfg; + u32 copyback = 0; + int ret; + + if (count > 19) + return -EINVAL; + + sscanf(buf, "%d %d %d", &r, &g, &b); + + if (r < 0 || r > 32768) + return -EINVAL; + if (g < 0 || g > 32768) + return -EINVAL; + if (b < 0 || b > 32768) + return -EINVAL; + + pr_info("%s: r=%d g=%d b=%d", __func__, r, g, b); + + memset(&pcc_cfg, 0, sizeof(struct mdp_pcc_cfg_data)); + + pcc_cfg.block = MDP_LOGICAL_BLOCK_DISP_0; + if (r == 32768 && g == 32768 && b == 32768) + pcc_cfg.ops = MDP_PP_OPS_DISABLE; + else + pcc_cfg.ops = MDP_PP_OPS_ENABLE; + pcc_cfg.ops |= MDP_PP_OPS_WRITE; + pcc_cfg.r.r = r; + pcc_cfg.g.g = g; + pcc_cfg.b.b = b; + + ret = mdss_mdp_pcc_config(&pcc_cfg, ©back); + if (ret != 0) + return ret; + + pcc_r = r; + pcc_g = g; + pcc_b = b; + + return count; +} + static DEVICE_ATTR(msm_fb_type, S_IRUGO, mdss_fb_get_type, NULL); static DEVICE_ATTR(msm_fb_split, S_IRUGO | S_IWUSR, mdss_fb_show_split, mdss_fb_store_split); @@ -761,6 +883,12 @@ static DEVICE_ATTR(msm_fb_panel_status, S_IRUGO | S_IWUSR, mdss_fb_get_panel_status, mdss_fb_force_panel_dead); static DEVICE_ATTR(msm_fb_dfps_mode, S_IRUGO | S_IWUSR, mdss_fb_get_dfps_mode, mdss_fb_change_dfps_mode); +#ifdef VENDOR_EDIT +/* guozhiming@oem Add for set cabc function 2015-04-01 */ +static DEVICE_ATTR(cabc, S_IRUGO|S_IWUSR, mdss_get_cabc, mdss_set_cabc); +#endif /*VENDOR_EDIT*/ +static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR | S_IWGRP, mdss_get_rgb, mdss_set_rgb); + static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_type.attr, &dev_attr_msm_fb_split.attr, @@ -772,6 +900,11 @@ static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_thermal_level.attr, &dev_attr_msm_fb_panel_status.attr, &dev_attr_msm_fb_dfps_mode.attr, + #ifdef VENDOR_EDIT + /* guozhiming@oem Add for set cabc function 2015-04-01*/ + &dev_attr_cabc.attr, + #endif /*VENDOR_EDIT*/ + &dev_attr_rgb.attr, NULL, }; @@ -1225,7 +1358,10 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) u32 temp = bkl_lvl; bool ad_bl_notify_needed = false; bool bl_notify_needed = false; +#ifdef VENDOR_EDIT + long long unsigned a,b,c; +#endif if ((((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER) || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) || mfd->panel_info->cont_splash_enabled) { @@ -1259,6 +1395,22 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) if (mfd->bl_level != bkl_lvl) bl_notify_needed = true; pr_debug("backlight sent to panel :%d\n", temp); +#ifdef VENDOR_EDIT + if(0 != temp) + { + if(temp <= 3680) + { + a = 869565 * temp; + b = a/1000000; + temp = b; + }else{ + a = 215663 * temp; + b = a/100000; + c = b - 4736; + temp = c; + } + } +#endif //guozhiming modify for the backlight 20mA pdata->set_backlight(pdata, temp); mfd->bl_level = bkl_lvl; mfd->bl_level_scaled = temp; @@ -1538,7 +1690,11 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, switch (blank_mode) { case FB_BLANK_UNBLANK: pr_debug("unblank called. cur pwr state=%d\n", cur_power_state); + #ifdef VENDOR_EDIT /*ykl add for debug lcd issue*/ + printk("display power on start\n"); ret = mdss_fb_blank_unblank(mfd); + printk("display power on end \n"); + #endif break; case BLANK_FLAG_ULP: req_power_state = MDSS_PANEL_POWER_LP2; @@ -1572,7 +1728,11 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info, default: req_power_state = MDSS_PANEL_POWER_OFF; pr_debug("blank powerdown called\n"); + #ifdef VENDOR_EDIT /*ykl add for debug lcd issue*/ + printk("display power off start\n"); ret = mdss_fb_blank_blank(mfd, req_power_state); + printk("display power off end \n"); + #endif break; } @@ -3775,15 +3935,15 @@ int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd, if (ret) goto exit; - if ((!mfd->op_enable) || (mdss_fb_is_power_off(mfd))) { - ret = -EPERM; - goto exit; - } - if (mfd->mdp.get_sync_fnc) sync_pt_data = mfd->mdp.get_sync_fnc(mfd, &buf_sync); - if (!sync_pt_data) + if (!sync_pt_data) { + if ((!mfd->op_enable) || (mdss_fb_is_power_off(mfd))) { + ret = -EPERM; + goto exit; + } sync_pt_data = &mfd->mdp_sync_pt_data; + } ret = mdss_fb_handle_buf_sync_ioctl(sync_pt_data, &buf_sync); diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 47db73ea18e55..37014bf6d5eea 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1134,7 +1134,7 @@ int mdss_iommu_init(struct mdss_data_type *mdata) return 0; } -static void mdss_debug_enable_clock(int on) +void mdss_debug_enable_clock(int on) { if (on) mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); @@ -1504,6 +1504,7 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, SPRINT("dma_pipes=%d\n", mdata->ndma_pipes); SPRINT("blending_stages=%d\n", mdata->max_target_zorder); SPRINT("cursor_pipes=%d\n", mdata->ncursor_pipes); + SPRINT("max_cursor_size=%d\n", mdata->max_cursor_size); SPRINT("smp_count=%d\n", mdata->smp_mb_cnt); SPRINT("smp_size=%d\n", mdata->smp_mb_size); SPRINT("smp_mb_per_pipe=%d\n", mdata->smp_mb_per_pipe); diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h old mode 100644 new mode 100755 index 727cfbab3c242..6e4ea912725ef --- a/drivers/video/msm/mdss/mdss_mdp.h +++ b/drivers/video/msm/mdss/mdss_mdp.h @@ -27,9 +27,6 @@ #include "mdss_fb.h" #define MDSS_MDP_DEFAULT_INTR_MASK 0 -#define MDSS_MDP_CURSOR_WIDTH 64 -#define MDSS_MDP_CURSOR_HEIGHT 64 -#define MDSS_MDP_CURSOR_SIZE (MDSS_MDP_CURSOR_WIDTH*MDSS_MDP_CURSOR_WIDTH*4) #define MDSS_MDP_PIXEL_RAM_SIZE (50 * 1024) #define PHASE_STEP_SHIFT 21 @@ -268,6 +265,7 @@ struct mdss_mdp_ctl { struct mdss_mdp_mixer *mixer_right; struct mutex lock; struct mutex offlock; + struct mutex flush_lock; struct mutex *shared_lock; spinlock_t spin_lock; @@ -400,6 +398,7 @@ struct pp_hist_col_info { spinlock_t hist_lock; char __iomem *base; u32 intr_shift; + u32 disp_num;//qualcomm provide patch in 2015-07-03 }; struct mdss_mdp_ad { @@ -857,6 +856,11 @@ static inline u32 left_lm_w_from_mfd(struct msm_fb_data_type *mfd) return width; } +static inline u32 mdss_mdp_get_cursor_frame_size(struct mdss_data_type *mdata) +{ + return mdata->max_cursor_size * mdata->max_cursor_size * 4; +} + irqreturn_t mdss_mdp_isr(int irq, void *ptr); int mdss_iommu_attach(struct mdss_data_type *mdata); int mdss_iommu_dettach(struct mdss_data_type *mdata); @@ -1117,5 +1121,6 @@ int mdss_mdp_cmd_set_autorefresh_mode(struct mdss_mdp_ctl *ctl, int frame_cnt); int mdss_mdp_ctl_cmd_autorefresh_enable(struct mdss_mdp_ctl *ctl, int frame_cnt); +void mdss_debug_enable_clock(int on); #endif /* MDSS_MDP_H */ diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index 028c286ed2f40..d131fdbdfe25a 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -1615,6 +1615,7 @@ static struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata, ctl->mdata = mdata; mutex_init(&ctl->lock); mutex_init(&ctl->offlock); + mutex_init(&ctl->flush_lock); spin_lock_init(&ctl->spin_lock); BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head); pr_debug("alloc ctl_num=%d\n", ctl->num); @@ -2805,8 +2806,15 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl) { u32 status = 1; int cnt = 20; - struct mdss_mdp_mixer *mixer = ctl->mixer_left; - + /*qualcomm's patch avoid mdss crash 2015.6.27*/ + // struct mdss_mdp_mixer *mixer = ctl->mixer_left; + struct mdss_mdp_mixer *mixer; + if (!ctl) { + pr_err("ctl not initialized\n"); + return -EINVAL; + } + mixer = ctl->mixer_left; + /*end*/ mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_SW_RESET, 1); /* @@ -2828,9 +2836,14 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl) if (mixer) { mdss_mdp_pipe_reset(mixer); + + /*qualcomm's patch avoid mdss crash 2015.6.27*/ + //if (ctl->mfd->split_mode == MDP_DUAL_LM_SINGLE_DISPLAY) + //mdss_mdp_pipe_reset(ctl->mixer_right); + if (ctl->mfd &&(ctl->mfd->split_mode == MDP_DUAL_LM_SINGLE_DISPLAY)) + mdss_mdp_pipe_reset(ctl->mixer_right); + /*end*/ - if (ctl->mfd->split_mode == MDP_DUAL_LM_SINGLE_DISPLAY) - mdss_mdp_pipe_reset(ctl->mixer_right); } return 0; @@ -3345,8 +3358,7 @@ int mdss_mdp_mixer_pipe_update(struct mdss_mdp_pipe *pipe, pr_debug("pnum=%x mixer=%d stage=%d\n", pipe->num, mixer->num, pipe->mixer_stage); - if (mutex_lock_interruptible(&ctl->lock)) - return -EINTR; + mutex_lock(&ctl->flush_lock); if (params_changed) { mixer->params_changed++; @@ -3387,7 +3399,7 @@ int mdss_mdp_mixer_pipe_update(struct mdss_mdp_pipe *pipe, else /* RGB/VIG 0-2 pipes */ ctl->flush_bits |= BIT(pipe->num); - mutex_unlock(&ctl->lock); + mutex_unlock(&ctl->flush_lock); return 0; } @@ -3661,6 +3673,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, bool is_bw_released; int split_enable; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + u32 ctl_flush_bits = 0, sctl_flush_bits = 0; if (!ctl) { pr_err("display function not set\n"); @@ -3678,6 +3691,8 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, sctl = mdss_mdp_get_split_ctl(ctl); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); + mutex_lock(&ctl->flush_lock); + /* * We could have released the bandwidth if there were no transactions * pending, so we want to re-calculate the bandwidth in this situation @@ -3731,6 +3746,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, sctl->opmode); sctl->flush_bits |= BIT(17); + sctl_flush_bits = sctl->flush_bits; } ATRACE_END("mixer_programming"); } @@ -3752,9 +3768,14 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, if (sctl && ctl->split_flush_en) { ctl->flush_bits |= sctl->flush_bits; sctl->flush_bits = 0; + sctl_flush_bits = sctl->flush_bits; } + ctl_flush_bits = ctl->flush_bits; + ATRACE_END("postproc_programming"); + mutex_unlock(&ctl->flush_lock); + ATRACE_BEGIN("frame_ready"); mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_CFG_DONE); if (commit_cb) @@ -3851,14 +3872,14 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_bwcpanic_ctrl(mdata, true); ATRACE_BEGIN("flush_kickoff"); - mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl->flush_bits); - if (sctl && sctl->flush_bits) { + mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, ctl_flush_bits); + if (sctl && sctl_flush_bits) { mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH, - sctl->flush_bits); + sctl_flush_bits); sctl->flush_bits = 0; } wmb(); - ctl->flush_reg_data = ctl->flush_bits; + ctl->flush_reg_data = ctl_flush_bits; ctl->flush_bits = 0; mdss_mdp_mixer_update_pipe_map(ctl, MDSS_MDP_MIXER_MUX_LEFT); @@ -3935,8 +3956,8 @@ int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id) mdata = mdss_mdp_get_mdata(); for (i = 0; i < mdata->nctl; i++) { ctl = mdata->ctl_off + i; - if ((mdss_mdp_ctl_is_power_on(ctl)) && (ctl->mfd) && - (ctl->mfd->index == fb_num)) { + if ((mdss_mdp_ctl_is_power_on(ctl) || mdata->handoff_pending) && + (ctl->mfd) && (ctl->mfd->index == fb_num)) { if (ctl->mixer_left) { mixer_id[mixer_cnt] = ctl->mixer_left->num; mixer_cnt++; diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 445b5adf80eed..2155c8354e13d 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -233,15 +233,18 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_SYNC_CONFIG_HEIGHT, te ? te->sync_cfg_height : 0); + //(ctx->ctl->height -1)); mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_VSYNC_INIT_VAL, te ? te->vsync_init_val : 0); mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_RD_PTR_IRQ, te ? te->rd_ptr_irq : 0); + //(ctx->ctl->height - ctx->ctl->height * 55 / 1000 - 1)); mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_START_POS, te ? te->start_pos : 0); + //(ctx->ctl->height - ctx->ctl->height * 55 / 1000)); /* 5% accuracy error */ mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_SYNC_THRESH, te ? ((te->sync_threshold_continue << 16) | @@ -249,7 +252,6 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, mdss_mdp_pingpong_write(pingpong_base, MDSS_MDP_REG_PP_SYNC_WRCOUNT, te ? (te->start_pos + te->sync_threshold_start + 1) : 0); - return 0; } @@ -1214,7 +1216,10 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) } mutex_lock(&ctl->offlock); + #ifndef VENDOR_EDIT + //add Patch from Qualcomm 2015-04-22 for fix "Display can not power on after receive a Weixin message in power off state" issue. if (__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) { + if (mdss_panel_is_power_on_lp(panel_power_state)) { /* * If we are transitioning from interactive to low @@ -1230,6 +1235,23 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) turn_off_clocks = true; panel_off = true; } + #else +if (mdss_panel_is_power_off(panel_power_state)) { + /* Transition to display off */ + send_panel_events = true; + turn_off_clocks = true; + panel_off = true; + } else if (__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) { + /* + * If we are transitioning from interactive to low + * power, then we need to send events to the interface + * so that the panel can be configured in low power + * mode. + */ + send_panel_events = true; + if (mdss_panel_is_power_on_ulp(panel_power_state)) + turn_off_clocks = true; + #endif } else { if (mdss_panel_is_power_on_ulp(panel_power_state)) { /* diff --git a/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c b/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c new file mode 100644 index 0000000000000..a73efc32434b0 --- /dev/null +++ b/drivers/video/msm/mdss/mdss_mdp_kcal_ctrl.c @@ -0,0 +1,693 @@ + +/* + * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2013, LGE Inc. All rights reserved + * Copyright (c) 2014 savoca + * Copyright (c) 2014 Paul Reioux + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) && defined(CONFIG_FB) +#include +#include +#include +#elif defined(CONFIG_FB) +#include +#include +#endif + +#include "mdss_mdp.h" + +#define DEF_PCC 0x100 +#define DEF_PA 0xff +#define PCC_ADJ 0x80 + +struct kcal_lut_data { +#if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) && defined(CONFIG_FB) + struct mmi_notifier panel_nb; +#elif defined(CONFIG_FB) + struct device dev; + struct notifier_block panel_nb; +#endif + bool queue_changes; + int red; + int green; + int blue; + int minimum; + int enable; + int invert; + int sat; + int hue; + int val; + int cont; +}; + +static uint32_t igc_inverted[IGC_LUT_ENTRIES] = { + 267390960, 266342368, 265293776, 264245184, + 263196592, 262148000, 261099408, 260050816, + 259002224, 257953632, 256905040, 255856448, + 254807856, 253759264, 252710672, 251662080, + 250613488, 249564896, 248516304, 247467712, + 246419120, 245370528, 244321936, 243273344, + 242224752, 241176160, 240127568, 239078976, + 238030384, 236981792, 235933200, 234884608, + 233836016, 232787424, 231738832, 230690240, + 229641648, 228593056, 227544464, 226495872, + 225447280, 224398688, 223350096, 222301504, + 221252912, 220204320, 219155728, 218107136, + 217058544, 216009952, 214961360, 213912768, + 212864176, 211815584, 210766992, 209718400, + 208669808, 207621216, 206572624, 205524032, + 204475440, 203426848, 202378256, 201329664, + 200281072, 199232480, 198183888, 197135296, + 196086704, 195038112, 193989520, 192940928, + 191892336, 190843744, 189795152, 188746560, + 187697968, 186649376, 185600784, 184552192, + 183503600, 182455008, 181406416, 180357824, + 179309232, 178260640, 177212048, 176163456, + 175114864, 174066272, 173017680, 171969088, + 170920496, 169871904, 168823312, 167774720, + 166726128, 165677536, 164628944, 163580352, + 162531760, 161483168, 160434576, 159385984, + 158337392, 157288800, 156240208, 155191616, + 154143024, 153094432, 152045840, 150997248, + 149948656, 148900064, 147851472, 146802880, + 145754288, 144705696, 143657104, 142608512, + 141559920, 140511328, 139462736, 138414144, + 137365552, 136316960, 135268368, 134219776, + 133171184, 132122592, 131074000, 130025408, + 128976816, 127928224, 126879632, 125831040, + 124782448, 123733856, 122685264, 121636672, + 120588080, 119539488, 118490896, 117442304, + 116393712, 115345120, 114296528, 113247936, + 112199344, 111150752, 110102160, 109053568, + 108004976, 106956384, 105907792, 104859200, + 103810608, 102762016, 101713424, 100664832, + 99616240, 98567648, 97519056, 96470464, + 95421872, 94373280, 93324688, 92276096, + 91227504, 90178912, 89130320, 88081728, + 87033136, 85984544, 84935952, 83887360, + 82838768, 81790176, 80741584, 79692992, + 78644400, 77595808, 76547216, 75498624, + 74450032, 73401440, 72352848, 71304256, + 70255664, 69207072, 68158480, 67109888, + 66061296, 65012704, 63964112, 62915520, + 61866928, 60818336, 59769744, 58721152, + 57672560, 56623968, 55575376, 54526784, + 53478192, 52429600, 51381008, 50332416, + 49283824, 48235232, 47186640, 46138048, + 45089456, 44040864, 42992272, 41943680, + 40895088, 39846496, 38797904, 37749312, + 36700720, 35652128, 34603536, 33554944, + 32506352, 31457760, 30409168, 29360576, + 28311984, 27263392, 26214800, 25166208, + 24117616, 23069024, 22020432, 20971840, + 19923248, 18874656, 17826064, 16777472, + 15728880, 14680288, 13631696, 12583104, + 11534512, 10485920, 9437328, 8388736, + 7340144, 6291552, 5242960, 4194368, + 3145776, 2097184, 1048592, 0 +}; + +static uint32_t igc_rgb[IGC_LUT_ENTRIES] = { + 4080, 4064, 4048, 4032, 4016, 4000, 3984, 3968, 3952, 3936, 3920, 3904, + 3888, 3872, 3856, 3840, 3824, 3808, 3792, 3776, 3760, 3744, 3728, 3712, + 3696, 3680, 3664, 3648, 3632, 3616, 3600, 3584, 3568, 3552, 3536, 3520, + 3504, 3488, 3472, 3456, 3440, 3424, 3408, 3392, 3376, 3360, 3344, 3328, + 3312, 3296, 3280, 3264, 3248, 3232, 3216, 3200, 3184, 3168, 3152, 3136, + 3120, 3104, 3088, 3072, 3056, 3040, 3024, 3008, 2992, 2976, 2960, 2944, + 2928, 2912, 2896, 2880, 2864, 2848, 2832, 2816, 2800, 2784, 2768, 2752, + 2736, 2720, 2704, 2688, 2672, 2656, 2640, 2624, 2608, 2592, 2576, 2560, + 2544, 2528, 2512, 2496, 2480, 2464, 2448, 2432, 2416, 2400, 2384, 2368, + 2352, 2336, 2320, 2304, 2288, 2272, 2256, 2240, 2224, 2208, 2192, 2176, + 2160, 2144, 2128, 2112, 2096, 2080, 2064, 2048, 2032, 2016, 2000, 1984, + 1968, 1952, 1936, 1920, 1904, 1888, 1872, 1856, 1840, 1824, 1808, 1792, + 1776, 1760, 1744, 1728, 1712, 1696, 1680, 1664, 1648, 1632, 1616, 1600, + 1584, 1568, 1552, 1536, 1520, 1504, 1488, 1472, 1456, 1440, 1424, 1408, + 1392, 1376, 1360, 1344, 1328, 1312, 1296, 1280, 1264, 1248, 1232, 1216, + 1200, 1184, 1168, 1152, 1136, 1120, 1104, 1088, 1072, 1056, 1040, 1024, + 1008, 992, 976, 960, 944, 928, 912, 896, 880, 864, 848, 832, + 816, 800, 784, 768, 752, 736, 720, 704, 688, 672, 656, 640, + 624, 608, 592, 576, 560, 544, 528, 512, 496, 480, 464, 448, + 432, 416, 400, 384, 368, 352, 336, 320, 304, 288, 272, 256, + 240, 224, 208, 192, 176, 160, 144, 128, 112, 96, 80, 64, + 48, 32, 16, 0 +}; + +static bool mdss_mdp_kcal_is_panel_on(void) +{ + int i; + struct mdss_mdp_ctl *ctl; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + + for (i = 0; i < mdata->nctl; i++) { + ctl = mdata->ctl_off + i; + if (mdss_mdp_ctl_is_power_on(ctl)) + return true; + } + + return false; +} + +static void mdss_mdp_kcal_update_pcc(struct kcal_lut_data *lut_data) +{ + u32 copyback = 0; + struct mdp_pcc_cfg_data pcc_config; + + memset(&pcc_config, 0, sizeof(struct mdp_pcc_cfg_data)); + + pcc_config.block = MDP_LOGICAL_BLOCK_DISP_0; + pcc_config.ops = lut_data->enable ? + MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE : + MDP_PP_OPS_WRITE | MDP_PP_OPS_DISABLE; + pcc_config.r.r = lut_data->red * PCC_ADJ; + pcc_config.g.g = lut_data->green * PCC_ADJ; + pcc_config.b.b = lut_data->blue * PCC_ADJ; + + mdss_mdp_pcc_config(&pcc_config, ©back); +} + +static void mdss_mdp_kcal_read_pcc(struct kcal_lut_data *lut_data) +{ + u32 copyback = 0; + struct mdp_pcc_cfg_data pcc_config; + + memset(&pcc_config, 0, sizeof(struct mdp_pcc_cfg_data)); + + pcc_config.block = MDP_LOGICAL_BLOCK_DISP_0; + pcc_config.ops = MDP_PP_OPS_READ; + + mdss_mdp_pcc_config(&pcc_config, ©back); + + /* LiveDisplay disables pcc when using default values and regs + * are zeroed on pp resume, so throw these values out. + */ + if (!pcc_config.r.r && !pcc_config.g.g && !pcc_config.b.b) + return; + + lut_data->red = pcc_config.r.r / PCC_ADJ; + lut_data->green = pcc_config.g.g / PCC_ADJ; + lut_data->blue = pcc_config.b.b / PCC_ADJ; +} + +static void mdss_mdp_kcal_update_pa(struct kcal_lut_data *lut_data) +{ + u32 copyback = 0; + struct mdp_pa_cfg_data pa_config; + struct mdp_pa_v2_cfg_data pa_v2_config; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + + if (mdata->mdp_rev < MDSS_MDP_HW_REV_103) { + memset(&pa_config, 0, sizeof(struct mdp_pa_cfg_data)); + + pa_config.block = MDP_LOGICAL_BLOCK_DISP_0; + pa_config.pa_data.flags = lut_data->enable ? + MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE : + MDP_PP_OPS_WRITE | MDP_PP_OPS_DISABLE; + pa_config.pa_data.hue_adj = lut_data->hue; + pa_config.pa_data.sat_adj = lut_data->sat; + pa_config.pa_data.val_adj = lut_data->val; + pa_config.pa_data.cont_adj = lut_data->cont; + + mdss_mdp_pa_config(&pa_config, ©back); + } else { + memset(&pa_v2_config, 0, sizeof(struct mdp_pa_v2_cfg_data)); + + pa_v2_config.block = MDP_LOGICAL_BLOCK_DISP_0; + pa_v2_config.pa_v2_data.flags = lut_data->enable ? + MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE : + MDP_PP_OPS_WRITE | MDP_PP_OPS_DISABLE; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_HUE_ENABLE; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_HUE_MASK; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_SAT_ENABLE; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_SAT_MASK; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_VAL_ENABLE; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_VAL_MASK; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_CONT_ENABLE; + pa_v2_config.pa_v2_data.flags |= MDP_PP_PA_CONT_MASK; + pa_v2_config.pa_v2_data.global_hue_adj = lut_data->hue; + pa_v2_config.pa_v2_data.global_sat_adj = lut_data->sat; + pa_v2_config.pa_v2_data.global_val_adj = lut_data->val; + pa_v2_config.pa_v2_data.global_cont_adj = lut_data->cont; + + mdss_mdp_pa_v2_config(&pa_v2_config, ©back); + } +} + +static void mdss_mdp_kcal_update_igc(struct kcal_lut_data *lut_data) +{ + u32 copyback = 0, copy_from_kernel = 1; + struct mdp_igc_lut_data igc_config; + + memset(&igc_config, 0, sizeof(struct mdp_igc_lut_data)); + + igc_config.block = MDP_LOGICAL_BLOCK_DISP_0; + igc_config.ops = lut_data->invert && lut_data->enable ? + MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE : + MDP_PP_OPS_WRITE | MDP_PP_OPS_DISABLE; + igc_config.len = IGC_LUT_ENTRIES; + igc_config.c0_c1_data = igc_inverted; + igc_config.c2_data = igc_rgb; + + mdss_mdp_igc_lut_config(&igc_config, ©back, copy_from_kernel); +} + +static void mdss_mdp_kcal_check_pcc(struct kcal_lut_data *lut_data) +{ + lut_data->red = lut_data->red < lut_data->minimum ? + lut_data->minimum : lut_data->red; + lut_data->green = lut_data->green < lut_data->minimum ? + lut_data->minimum : lut_data->green; + lut_data->blue = lut_data->blue < lut_data->minimum ? + lut_data->minimum : lut_data->blue; +} + +static ssize_t kcal_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int kcal_r, kcal_g, kcal_b, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = sscanf(buf, "%d %d %d", &kcal_r, &kcal_g, &kcal_b); + if ((r != 3) || (kcal_r < 1 || kcal_r > 256) || + (kcal_g < 1 || kcal_g > 256) || (kcal_b < 1 || kcal_b > 256)) + return -EINVAL; + + lut_data->red = kcal_r; + lut_data->green = kcal_g; + lut_data->blue = kcal_b; + + mdss_mdp_kcal_check_pcc(lut_data); + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pcc(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + if (mdss_mdp_kcal_is_panel_on() && lut_data->enable) + mdss_mdp_kcal_read_pcc(lut_data); + + return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", + lut_data->red, lut_data->green, lut_data->blue); +} + +static ssize_t kcal_min_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_min, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_min); + if ((r) || (kcal_min < 1 || kcal_min > 256)) + return -EINVAL; + + lut_data->minimum = kcal_min; + + mdss_mdp_kcal_check_pcc(lut_data); + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pcc(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_min_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->minimum); +} + +static ssize_t kcal_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_enable, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_enable); + if ((r) || (kcal_enable != 0 && kcal_enable != 1) || + (lut_data->enable == kcal_enable)) + return -EINVAL; + + lut_data->enable = kcal_enable; + + if (mdss_mdp_kcal_is_panel_on()) { + mdss_mdp_kcal_update_pcc(lut_data); + mdss_mdp_kcal_update_pa(lut_data); + mdss_mdp_kcal_update_igc(lut_data); + } else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->enable); +} + +static ssize_t kcal_invert_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_invert, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_invert); + if ((r) || (kcal_invert != 0 && kcal_invert != 1) || + (lut_data->invert == kcal_invert)) + return -EINVAL; + + lut_data->invert = kcal_invert; + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_igc(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_invert_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + /* IGC lut does not support reading regs in kernel space yet */ + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->invert); +} + +static ssize_t kcal_sat_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_sat, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_sat); + if ((r) || ((kcal_sat < 224 || kcal_sat > 383) && kcal_sat != 128)) + return -EINVAL; + + lut_data->sat = kcal_sat; + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pa(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_sat_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->sat); +} + +static ssize_t kcal_hue_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_hue, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_hue); + if ((r) || (kcal_hue < 0 || kcal_hue > 1536)) + return -EINVAL; + + lut_data->hue = kcal_hue; + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pa(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_hue_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->hue); +} + +static ssize_t kcal_val_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_val, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_val); + if ((r) || (kcal_val < 128 || kcal_val > 383)) + return -EINVAL; + + lut_data->val = kcal_val; + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pa(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_val_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->val); +} + +static ssize_t kcal_cont_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int kcal_cont, r; + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + r = kstrtoint(buf, 10, &kcal_cont); + if ((r) || (kcal_cont < 128 || kcal_cont > 383)) + return -EINVAL; + + lut_data->cont = kcal_cont; + + if (mdss_mdp_kcal_is_panel_on()) + mdss_mdp_kcal_update_pa(lut_data); + else + lut_data->queue_changes = true; + + return count; +} + +static ssize_t kcal_cont_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", lut_data->cont); +} + +static DEVICE_ATTR(kcal, S_IWUSR | S_IRUGO, kcal_show, kcal_store); +static DEVICE_ATTR(kcal_min, S_IWUSR | S_IRUGO, kcal_min_show, kcal_min_store); +static DEVICE_ATTR(kcal_enable, S_IWUSR | S_IRUGO, kcal_enable_show, + kcal_enable_store); +static DEVICE_ATTR(kcal_invert, S_IWUSR | S_IRUGO, kcal_invert_show, + kcal_invert_store); +static DEVICE_ATTR(kcal_sat, S_IWUSR | S_IRUGO, kcal_sat_show, kcal_sat_store); +static DEVICE_ATTR(kcal_hue, S_IWUSR | S_IRUGO, kcal_hue_show, kcal_hue_store); +static DEVICE_ATTR(kcal_val, S_IWUSR | S_IRUGO, kcal_val_show, kcal_val_store); +static DEVICE_ATTR(kcal_cont, S_IWUSR | S_IRUGO, kcal_cont_show, + kcal_cont_store); + +static int mdss_mdp_kcal_update_queue(struct device *dev) +{ + struct kcal_lut_data *lut_data = dev_get_drvdata(dev); + + if (lut_data->queue_changes) { + mdss_mdp_kcal_update_pcc(lut_data); + mdss_mdp_kcal_update_pa(lut_data); + mdss_mdp_kcal_update_igc(lut_data); + lut_data->queue_changes = false; + } + + return 0; +} + +#if defined(CONFIG_FB) && !defined(CONFIG_MMI_PANEL_NOTIFICATIONS) +static int fb_notifier_callback(struct notifier_block *nb, + unsigned long event, void *data) +{ + int *blank; + struct fb_event *evdata = data; + struct kcal_lut_data *lut_data = + container_of(nb, struct kcal_lut_data, panel_nb); + + if (evdata && evdata->data && event == FB_EVENT_BLANK) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) + mdss_mdp_kcal_update_queue(&lut_data->dev); + } + + return 0; +} +#endif + +static int kcal_ctrl_probe(struct platform_device *pdev) +{ + int ret; + struct kcal_lut_data *lut_data; + + lut_data = devm_kzalloc(&pdev->dev, sizeof(*lut_data), GFP_KERNEL); + if (!lut_data) { + pr_err("%s: failed to allocate memory for lut_data\n", + __func__); + return -ENOMEM; + } + + platform_set_drvdata(pdev, lut_data); + + lut_data->enable = 0x1; + lut_data->red = DEF_PCC; + lut_data->green = DEF_PCC; + lut_data->blue = DEF_PCC; + lut_data->minimum = 0x23; + lut_data->invert = 0x0; + lut_data->hue = 0x0; + lut_data->sat = DEF_PA; + lut_data->val = DEF_PA; + lut_data->cont = DEF_PA; + + lut_data->queue_changes = false; + + mdss_mdp_kcal_update_pcc(lut_data); + mdss_mdp_kcal_update_pa(lut_data); + mdss_mdp_kcal_update_igc(lut_data); + +#if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) + lut_data->panel_nb.display_on = mdss_mdp_kcal_update_queue; + lut_data->panel_nb.dev = &pdev->dev; + ret = mmi_panel_register_notifier(&lut_data->panel_nb); + if (ret) { + pr_err("%s: unable to register MMI notifier\n", __func__); + return ret; + } +#elif defined(CONFIG_FB) + lut_data->dev = pdev->dev; + lut_data->panel_nb.notifier_call = fb_notifier_callback; + ret = fb_register_client(&lut_data->panel_nb); + if (ret) { + pr_err("%s: unable to register fb notifier\n", __func__); + return ret; + } +#endif + + ret = device_create_file(&pdev->dev, &dev_attr_kcal); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_min); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_enable); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_invert); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_sat); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_hue); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_val); + ret |= device_create_file(&pdev->dev, &dev_attr_kcal_cont); + if (ret) { + pr_err("%s: unable to create sysfs entries\n", __func__); + goto out_notifier; + } + + return 0; + +out_notifier: +#if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) + mmi_panel_unregister_notifier(&lut_data->panel_nb); +#elif defined(CONFIG_FB) + fb_unregister_client(&lut_data->panel_nb); +#endif + return ret; +} + +static int kcal_ctrl_remove(struct platform_device *pdev) +{ + struct kcal_lut_data *lut_data = platform_get_drvdata(pdev); + + device_remove_file(&pdev->dev, &dev_attr_kcal); + device_remove_file(&pdev->dev, &dev_attr_kcal_min); + device_remove_file(&pdev->dev, &dev_attr_kcal_enable); + device_remove_file(&pdev->dev, &dev_attr_kcal_invert); + device_remove_file(&pdev->dev, &dev_attr_kcal_sat); + device_remove_file(&pdev->dev, &dev_attr_kcal_hue); + device_remove_file(&pdev->dev, &dev_attr_kcal_val); + device_remove_file(&pdev->dev, &dev_attr_kcal_cont); + +#if defined(CONFIG_MMI_PANEL_NOTIFICATIONS) + mmi_panel_unregister_notifier(&lut_data->panel_nb); +#elif defined(CONFIG_FB) + fb_unregister_client(&lut_data->panel_nb); +#endif + + return 0; +} + +static struct platform_driver kcal_ctrl_driver = { + .probe = kcal_ctrl_probe, + .remove = kcal_ctrl_remove, + .driver = { + .name = "kcal_ctrl", + }, +}; + +static struct platform_device kcal_ctrl_device = { + .name = "kcal_ctrl", +}; + +static int __init kcal_ctrl_init(void) +{ + if (platform_driver_register(&kcal_ctrl_driver)) + return -ENODEV; + + if (platform_device_register(&kcal_ctrl_device)) + return -ENODEV; + + pr_info("%s: registered\n", __func__); + + return 0; +} + +static void __exit kcal_ctrl_exit(void) +{ + platform_device_unregister(&kcal_ctrl_device); + platform_driver_unregister(&kcal_ctrl_driver); +} + +late_initcall(kcal_ctrl_init); +module_exit(kcal_ctrl_exit); diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 3f22c5cd6deb5..8b0aac44b8565 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -616,7 +616,9 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, return -EOVERFLOW; } - if (IS_RIGHT_MIXER_OV(req->flags, req->dst_rect.x, left_lm_w)) + if (IS_RIGHT_MIXER_OV(req->flags, req->dst_rect.x, left_lm_w) + && !(req->pipe_type == MDSS_MDP_PIPE_TYPE_CURSOR + && is_split_lm(mfd))) mixer_mux = MDSS_MDP_MIXER_MUX_RIGHT; else mixer_mux = MDSS_MDP_MIXER_MUX_LEFT; @@ -759,7 +761,8 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, goto exit_fail; } - if (pipe->mixer_left != mixer) { + if ((pipe->mixer_left != mixer) && + (pipe->type != MDSS_MDP_PIPE_TYPE_CURSOR)) { if (!mixer->ctl || (mixer->ctl->mfd != mfd)) { pr_err("Can't switch mixer %d->%d pnum %d!\n", pipe->mixer_left->num, mixer->num, @@ -846,7 +849,10 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, * staging, same pipe will be stagged on both layer mixers. */ if (mdata->has_src_split) { - if ((mixer_mux == MDSS_MDP_MIXER_MUX_LEFT) && + if ((pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR) && + is_split_lm(mfd)) { + pipe->src_split_req = true; + } else if ((mixer_mux == MDSS_MDP_MIXER_MUX_LEFT) && ((req->dst_rect.x + req->dst_rect.w) > mixer->width)) { if (req->dst_rect.x >= mixer->width) { pr_err("%pS: err dst_x can't lie in right half", @@ -3054,6 +3060,31 @@ void mdss_mdp_curor_pipe_cleanup(struct msm_fb_data_type *mfd, int cursor_pipe) } } +int mdss_mdp_cursor_flush(struct msm_fb_data_type *mfd, + struct mdss_mdp_pipe *pipe, int cursor_pipe) +{ + struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); + struct mdss_mdp_ctl *ctl = mdp5_data->ctl; + struct mdss_mdp_ctl *sctl = NULL; + u32 flush_bits = BIT(22 + pipe->num - MDSS_MDP_SSPP_CURSOR0); + + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); + + mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits); + if ((!ctl->split_flush_en) && pipe->mixer_right) { + sctl = mdss_mdp_get_split_ctl(ctl); + if (!sctl) { + pr_err("not able to get the other ctl\n"); + return -ENODEV; + } + mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits); + } + + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); + + return 0; +} + int mdss_mdp_cursor_pipe_setup(struct msm_fb_data_type *mfd, struct mdp_overlay *req, int cursor_pipe) { struct mdss_mdp_pipe *pipe; @@ -3092,12 +3123,23 @@ int mdss_mdp_cursor_pipe_setup(struct msm_fb_data_type *mfd, ret = -ENOMEM; goto done; } - mdp5_data->cursor_ndx[cursor_pipe] = pipe->ndx; buf->p[0].addr = cursor_addr; - buf->p[0].len = MDSS_MDP_CURSOR_SIZE; + buf->p[0].len = mdss_mdp_get_cursor_frame_size(mdata); buf->num_planes = 1; + buf->state = MDP_BUF_STATE_ACTIVE; + if (!(req->flags & MDP_SOLID_FILL)) + ret = mdss_mdp_pipe_queue_data(pipe, buf); + else + ret = mdss_mdp_pipe_queue_data(pipe, NULL); + + if (ret) { + pr_err("cursor pipe queue data failed in async mode\n"); + return ret; + } + + ret = mdss_mdp_cursor_flush(mfd, pipe, cursor_pipe); done: if (ret && mdp5_data->cursor_ndx[cursor_pipe] == MSMFB_NEW_REQUEST) mdss_mdp_overlay_release(mfd, pipe->ndx); @@ -3112,14 +3154,16 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, struct mdss_mdp_mixer *mixer; struct fb_image *img = &cursor->image; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - struct mdp_overlay req; + struct mdp_overlay *req = NULL; struct mdss_rect roi; int ret = 0; - u32 xres = mfd->fbi->var.xres; - u32 yres = mfd->fbi->var.yres; + struct fb_var_screeninfo *var = &mfd->fbi->var; + u32 xres = var->xres; + u32 yres = var->yres; u32 start_x = img->dx; u32 start_y = img->dy; u32 left_lm_w = left_lm_w_from_mfd(mfd); + u32 cursor_frame_size = mdss_mdp_get_cursor_frame_size(mdata); ret = mutex_lock_interruptible(&mdp5_data->ov_lock); if (ret) @@ -3144,7 +3188,7 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, if (!mfd->cursor_buf && (cursor->set & FB_CUR_SETIMAGE)) { mfd->cursor_buf = dma_alloc_coherent(&mfd->pdev->dev, - MDSS_MDP_CURSOR_SIZE, (dma_addr_t *) + cursor_frame_size, (dma_addr_t *) &mfd->cursor_buf_phys, GFP_KERNEL); if (!mfd->cursor_buf) { pr_err("can't allocate cursor buffer\n"); @@ -3154,10 +3198,10 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, ret = msm_iommu_map_contig_buffer(mfd->cursor_buf_phys, mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE), - 0, MDSS_MDP_CURSOR_SIZE, SZ_4K, 0, + 0, cursor_frame_size, SZ_4K, 0, &(mfd->cursor_buf_iova)); if (IS_ERR_VALUE(ret)) { - dma_free_coherent(&mfd->pdev->dev, MDSS_MDP_CURSOR_SIZE, + dma_free_coherent(&mfd->pdev->dev, cursor_frame_size, mfd->cursor_buf, (dma_addr_t) mfd->cursor_buf_phys); pr_err("unable to map cursor buffer to iommu(%d)\n", @@ -3169,13 +3213,6 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, mixer->cursor_hoty = 0; } - if ((img->width > MDSS_MDP_CURSOR_WIDTH) || - (img->height > MDSS_MDP_CURSOR_HEIGHT) || - (img->depth != 32) || (start_x >= xres) || (start_y >= yres)) { - ret = -EINVAL; - goto done; - } - pr_debug("mixer=%d enable=%x set=%x\n", mixer->num, cursor->enable, cursor->set); @@ -3210,24 +3247,37 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, roi.w = min(xres - start_x, img->width - roi.x); roi.h = min(yres - start_y, img->height - roi.y); - memset(&req, 0, sizeof(struct mdp_overlay)); - req.pipe_type = PIPE_TYPE_CURSOR; - req.z_order = HW_CURSOR_STAGE(mdata); + if ((roi.w > mdata->max_cursor_size) || + (roi.h > mdata->max_cursor_size) || + (img->depth != 32) || (start_x >= xres) || (start_y >= yres)) { + ret = -EINVAL; + goto done; + } - req.src.width = img->width; - req.src.height = img->height; - req.src.format = MDP_ARGB_8888; + req = kzalloc(sizeof(struct mdp_overlay), GFP_KERNEL); + if (!req) { + pr_err("not able to allocate memory for cursor req\n"); + ret = -ENOMEM; + goto done; + } + + req->pipe_type = PIPE_TYPE_CURSOR; + req->z_order = HW_CURSOR_STAGE(mdata); - mdss_mdp_set_rect(&req.src_rect, roi.x, roi.y, img->width, img->height); - mdss_mdp_set_rect(&req.dst_rect, start_x, start_y, roi.w, roi.h); + req->src.width = img->width; + req->src.height = img->height; + req->src.format = mfd->fb_imgType; - req.bg_color = img->bg_color; - req.alpha = (img->fg_color & 0xff000000) >> 24; - if (req.alpha == 0xff) - req.blend_op = BLEND_OP_OPAQUE; + mdss_mdp_set_rect(&req->src_rect, roi.x, roi.y, roi.w, roi.h); + mdss_mdp_set_rect(&req->dst_rect, start_x, start_y, roi.w, roi.h); + + req->bg_color = img->bg_color; + req->alpha = (img->fg_color >> ((32 - var->transp.offset) - 8)) & 0xff; + if (req->alpha) + req->blend_op = BLEND_OP_PREMULTIPLIED; else - req.blend_op = BLEND_OP_COVERAGE; - req.transp_mask = (img->bg_color & 0xffffff); + req->blend_op = BLEND_OP_COVERAGE; + req->transp_mask = img->bg_color & ~(0xff << var->transp.offset); if (mfd->cursor_buf && (cursor->set & FB_CUR_SETIMAGE)) { ret = copy_from_user(mfd->cursor_buf, img->data, @@ -3241,32 +3291,59 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd, mixer->cursor_hoty = 0; } - if (start_x + roi.w <= left_lm_w) { - ret = mdss_mdp_cursor_pipe_setup(mfd, &req, CURSOR_PIPE_LEFT); - mdss_mdp_curor_pipe_cleanup(mfd, CURSOR_PIPE_RIGHT); + /* + * When source split is enabled, only CURSOR_PIPE_LEFT is used, + * with both mixers of the pipe staged all the time. + * When source split is disabled, 2 pipes are staged, with one + * pipe containing the actual data and another one a transparent + * solid fill when the data falls only in left or right dsi. + * Both are done to support async cursor functionality. + */ + if (mdata->has_src_split || (!is_split_lm(mfd)) + || (mdata->ncursor_pipes == 1)) { + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_LEFT); + } else if ((start_x + roi.w) <= left_lm_w) { + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_LEFT); + if (ret) + goto done; + req->bg_color = 0; + req->flags |= MDP_SOLID_FILL; + req->dst_rect.x = left_lm_w; + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_RIGHT); } else if (start_x >= left_lm_w) { - ret = mdss_mdp_cursor_pipe_setup(mfd, &req, CURSOR_PIPE_RIGHT); - mdss_mdp_curor_pipe_cleanup(mfd, CURSOR_PIPE_LEFT); - } else { - mdss_mdp_set_rect(&req.dst_rect, start_x, start_y, - (left_lm_w - start_x), roi.h); - mdss_mdp_set_rect(&req.src_rect, 0, 0, (left_lm_w - - start_x), img->height); - ret = mdss_mdp_cursor_pipe_setup(mfd, &req, CURSOR_PIPE_LEFT); + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_RIGHT); if (ret) goto done; - - mdss_mdp_set_rect(&req.dst_rect, left_lm_w, start_y, ((start_x + - roi.w) - left_lm_w), roi.h); - mdss_mdp_set_rect(&req.src_rect, (left_lm_w - start_x), 0, - (img->width - (left_lm_w - start_x)), - img->height); - ret = mdss_mdp_cursor_pipe_setup(mfd, &req, CURSOR_PIPE_RIGHT); + req->bg_color = 0; + req->flags |= MDP_SOLID_FILL; + req->dst_rect.x = 0; + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_LEFT); + } else if ((start_x <= left_lm_w) && ((start_x + roi.w) >= left_lm_w)) { + mdss_mdp_set_rect(&req->dst_rect, start_x, start_y, + (left_lm_w - start_x), roi.h); + mdss_mdp_set_rect(&req->src_rect, 0, 0, (left_lm_w - + start_x), roi.h); + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_LEFT); if (ret) goto done; + + mdss_mdp_set_rect(&req->dst_rect, left_lm_w, start_y, ((start_x + + roi.w) - left_lm_w), roi.h); + mdss_mdp_set_rect(&req->src_rect, (left_lm_w - start_x), 0, + (roi.w - (left_lm_w - start_x)), roi.h); + ret = mdss_mdp_cursor_pipe_setup(mfd, req, CURSOR_PIPE_RIGHT); + } else { + pr_err("Invalid case for cursor pipe setup\n"); + ret = -EINVAL; } done: + if (ret) { + mdss_mdp_curor_pipe_cleanup(mfd, CURSOR_PIPE_LEFT); + mdss_mdp_curor_pipe_cleanup(mfd, CURSOR_PIPE_RIGHT); + } + + kfree(req); mutex_unlock(&mdp5_data->ov_lock); return ret; } @@ -3287,6 +3364,7 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd, u32 start_x = img->dx; u32 start_y = img->dy; u32 left_lm_w = left_lm_w_from_mfd(mfd); + u32 cursor_frame_size = mdss_mdp_get_cursor_frame_size(mdata); mixer_left = mdss_mdp_mixer_get(mdp5_data->ctl, MDSS_MDP_MIXER_MUX_DEFAULT); @@ -3300,7 +3378,7 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd, } if (!mfd->cursor_buf && (cursor->set & FB_CUR_SETIMAGE)) { - mfd->cursor_buf = dma_alloc_coherent(NULL, MDSS_MDP_CURSOR_SIZE, + mfd->cursor_buf = dma_alloc_coherent(NULL, cursor_frame_size, (dma_addr_t *) &mfd->cursor_buf_phys, GFP_KERNEL); if (!mfd->cursor_buf) { @@ -3310,10 +3388,10 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd, ret = msm_iommu_map_contig_buffer(mfd->cursor_buf_phys, mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE), - 0, MDSS_MDP_CURSOR_SIZE, SZ_4K, 0, + 0, cursor_frame_size, SZ_4K, 0, &(mfd->cursor_buf_iova)); if (IS_ERR_VALUE(ret)) { - dma_free_coherent(NULL, MDSS_MDP_CURSOR_SIZE, + dma_free_coherent(NULL, cursor_frame_size, mfd->cursor_buf, (dma_addr_t) mfd->cursor_buf_phys); pr_err("unable to map cursor buffer to iommu(%d)\n", @@ -3322,8 +3400,8 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd, } } - if ((img->width > MDSS_MDP_CURSOR_WIDTH) || - (img->height > MDSS_MDP_CURSOR_HEIGHT) || + if ((img->width > mdata->max_cursor_size) || + (img->height > mdata->max_cursor_size) || (img->depth != 32) || (start_x >= xres) || (start_y >= yres)) return -EINVAL; diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index 3bcd4d5091095..ea0e4121da339 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -1788,10 +1788,13 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, if (params_changed) { pipe->params_changed = 0; - ret = mdss_mdp_pipe_pp_setup(pipe, &opmode); - if (ret) { - pr_err("pipe pp setup error for pnum=%d\n", pipe->num); - goto done; + if (pipe->type != MDSS_MDP_PIPE_TYPE_CURSOR) { + ret = mdss_mdp_pipe_pp_setup(pipe, &opmode); + if (ret) { + pr_err("pipe pp setup error for pnum=%d\n", + pipe->num); + goto done; + } } ret = mdss_mdp_image_setup(pipe, src_data); @@ -1811,10 +1814,10 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_VIG_OP_MODE, opmode); - mdss_mdp_pipe_panic_signal_ctrl(pipe, true); - - mdss_mdp_set_ot_limit_pipe(pipe); - + if (pipe->type != MDSS_MDP_PIPE_TYPE_CURSOR) { + mdss_mdp_pipe_panic_signal_ctrl(pipe, true); + mdss_mdp_set_ot_limit_pipe(pipe); + } } if (src_data == NULL) { diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c old mode 100644 new mode 100755 index 1d35623d2c71e..c2ed5d510933b --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -3612,6 +3612,7 @@ int mdss_mdp_hist_start(struct mdp_histogram_start_req *req) goto hist_stop_clk; } hist_info = &mdss_pp_res->dspp_hist[dspp_num]; + hist_info->disp_num = PP_BLOCK(req->block);//qualcomm provide patch in 2015-07-03 add ret = pp_hist_enable(hist_info, req); mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_HIST_COL; @@ -3665,19 +3666,21 @@ static int pp_hist_stop_wrapper(struct msm_fb_data_type *mfd) int mdss_mdp_hist_stop(u32 block) { int i, ret = 0; - u32 dspp_num, disp_num; + + //u32 dspp_num, disp_num; /*qualcomm provide patch in 2015-07-03*/ + u32 disp_num; struct pp_hist_col_info *hist_info; - u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; + //u32 mixer_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];/*qualcomm provide patch in 2015-07-03*/ struct mdss_mdp_pipe *pipe; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - +/* if ((PP_BLOCK(block) < MDP_LOGICAL_BLOCK_DISP_0) || (PP_BLOCK(block) >= MDP_BLOCK_MAX)) return -EINVAL; - +*/ //qualcomm provide patch in 2015-07-03 if (!mdata) return -EPERM; - + /* disp_num = PP_BLOCK(block) - MDP_LOGICAL_BLOCK_DISP_0; mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id); @@ -3693,6 +3696,7 @@ int mdss_mdp_hist_stop(u32 block) ret = -EPERM; goto hist_stop_exit; } + */ //qualcomm provide patch in 2015-07-03 mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); if (PP_LOCAT(block) == MDSS_PP_SSPP_CFG) { i = MDSS_PP_ARG_MASK & block; @@ -3720,6 +3724,7 @@ int mdss_mdp_hist_stop(u32 block) goto hist_stop_clk; } } else if (PP_LOCAT(block) == MDSS_PP_DSPP_CFG) { +/* for (i = 0; i < mixer_cnt; i++) { dspp_num = mixer_id[i]; if (dspp_num >= mdata->ndspp) { @@ -3727,17 +3732,41 @@ int mdss_mdp_hist_stop(u32 block) pr_warn("Invalid dspp num %d\n", dspp_num); goto hist_stop_clk; } + hist_info = &mdss_pp_res->dspp_hist[dspp_num]; +*///qualcomm provide patch in 2015-07-03 + +/********************************************************/ + if ((PP_BLOCK(block) < MDP_LOGICAL_BLOCK_DISP_0) || + (PP_BLOCK(block) >= MDP_BLOCK_MAX)) { + pr_err("Invalid logical disp block %d\n", + PP_BLOCK(block)); + ret = -EINVAL; + goto hist_stop_clk; + } + disp_num = PP_BLOCK(block); + for (i = 0; i < mdata->ndspp; i++) { + hist_info = &mdss_pp_res->dspp_hist[i]; + if (disp_num != hist_info->disp_num) + continue; + ret = pp_hist_disable(hist_info); + hist_info->disp_num = 0; +/****************qualcomm provide patch in 2015-07-03*********************/ + ret = pp_hist_disable(hist_info); + hist_info->disp_num = 0; + if (ret) goto hist_stop_clk; - mdss_pp_res->pp_disp_flags[disp_num] |= - PP_FLAGS_DIRTY_HIST_COL; + // mdss_pp_res->pp_disp_flags[disp_num] |= + // PP_FLAGS_DIRTY_HIST_COL; //qualcomm provide patch in 2015-07-03 + mdss_pp_res->pp_disp_flags[i] |= + PP_FLAGS_DIRTY_HIST_COL; } } hist_stop_clk: mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); -hist_stop_exit: +//hist_stop_exit: //qualcomm provide patch in 2015-07-03 return ret; } diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c index 0e6561fb685f7..c7183782ab9dc 100644 --- a/drivers/video/msm/mdss/mdss_mdp_rotator.c +++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c @@ -627,6 +627,7 @@ static void mdss_mdp_rotator_commit_wq_handler(struct work_struct *work) pr_err("rotator queue failed\n"); if (rot->rot_sync_pt_data) { + //atomic_inc(&rot->rot_sync_pt_data->commit_cnt); mdss_fb_signal_timeline(rot->rot_sync_pt_data); } else { pr_err("rot_sync_pt_data is NULL\n"); diff --git a/fs/Kconfig b/fs/Kconfig index dc3ec4cb406ee..37748801426b9 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -39,6 +39,7 @@ source "fs/gfs2/Kconfig" source "fs/ocfs2/Kconfig" source "fs/btrfs/Kconfig" source "fs/nilfs2/Kconfig" +source "fs/f2fs/Kconfig" endif # BLOCK @@ -94,6 +95,10 @@ menu "DOS/FAT/NT Filesystems" source "fs/fat/Kconfig" source "fs/ntfs/Kconfig" +#ifdef VENDOR_EDIT +source "fs/exfat/Kconfig" +#endif + endmenu endif # BLOCK @@ -214,7 +219,6 @@ source "fs/pstore/Kconfig" source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" -source "fs/f2fs/Kconfig" source "fs/efivarfs/Kconfig" endif # MISC_FILESYSTEMS diff --git a/fs/Makefile b/fs/Makefile index adb8947b94af0..6d8c9515433b3 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -127,5 +127,9 @@ obj-$(CONFIG_CEPH_FS) += ceph/ obj-$(CONFIG_PSTORE) += pstore/ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +#ifdef VENDOR_EDIT +obj-$(CONFIG_EXFAT_FS) += exfat/ +#endif + # Patched by YAFFS obj-$(CONFIG_YAFFS_FS) += yaffs2/ diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f71ec125290db..1da2446bf6b00 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -2102,7 +2102,6 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size, break; case 2: dst[dst_byte_offset++] |= (src_byte); - dst[dst_byte_offset] = 0; current_bit_offset = 0; break; } diff --git a/fs/exec.c b/fs/exec.c index dd6aa61c85486..acbd7ac2deda4 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1265,6 +1265,53 @@ static int check_unsafe_exec(struct linux_binprm *bprm) return res; } +static void bprm_fill_uid(struct linux_binprm *bprm) +{ + struct inode *inode; + unsigned int mode; + kuid_t uid; + kgid_t gid; + + /* clear any previous set[ug]id data from a previous binary */ + bprm->cred->euid = current_euid(); + bprm->cred->egid = current_egid(); + + if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) + return; + + if (current->no_new_privs) + return; + + inode = file_inode(bprm->file); + mode = ACCESS_ONCE(inode->i_mode); + if (!(mode & (S_ISUID|S_ISGID))) + return; + + /* Be careful if suid/sgid is set */ + mutex_lock(&inode->i_mutex); + + /* reload atomically mode/uid/gid now that lock held */ + mode = inode->i_mode; + uid = inode->i_uid; + gid = inode->i_gid; + mutex_unlock(&inode->i_mutex); + + /* We ignore suid/sgid if there are no mappings for them in the ns */ + if (!kuid_has_mapping(bprm->cred->user_ns, uid) || + !kgid_has_mapping(bprm->cred->user_ns, gid)) + return; + + if (mode & S_ISUID) { + bprm->per_clear |= PER_CLEAR_ON_SETID; + bprm->cred->euid = uid; + } + + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + bprm->per_clear |= PER_CLEAR_ON_SETID; + bprm->cred->egid = gid; + } +} + /* * Fill the binprm structure from the inode. * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes @@ -1273,39 +1320,12 @@ static int check_unsafe_exec(struct linux_binprm *bprm) */ int prepare_binprm(struct linux_binprm *bprm) { - umode_t mode; - struct inode * inode = file_inode(bprm->file); int retval; - mode = inode->i_mode; if (bprm->file->f_op == NULL) return -EACCES; - /* clear any previous set[ug]id data from a previous binary */ - bprm->cred->euid = current_euid(); - bprm->cred->egid = current_egid(); - - if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && - !current->no_new_privs && - kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && - kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { - /* Set-uid? */ - if (mode & S_ISUID) { - bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->euid = inode->i_uid; - } - - /* Set-gid? */ - /* - * If setgid is set but no group execute bit then this - * is a candidate for mandatory locking, not a setgid - * executable. - */ - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { - bprm->per_clear |= PER_CLEAR_ON_SETID; - bprm->cred->egid = inode->i_gid; - } - } + bprm_fill_uid(bprm); /* fill in binprm security blob */ retval = security_bprm_set_creds(bprm); diff --git a/fs/exfat/Kconfig b/fs/exfat/Kconfig new file mode 100755 index 0000000000000..e2862a978c5e6 --- /dev/null +++ b/fs/exfat/Kconfig @@ -0,0 +1,27 @@ +config EXFAT_FS + tristate + default y + select NLS + select NLS_UTF8 + help + If you want to use the exFAT file systems, then you must say Y or M here + to inlucde exFAT support. + +config EXFAT_VIRTUAL_XATTR + bool "Virtual xattr support for exFAT filesystem" + default n + depends on EXFAT_FS + help + Modification of exFAT filesystem for virtual xattr + +config EXFAT_VIRTUAL_XATTR_SELINUX_LABEL + string "Default string for SELinux label" + depends on EXFAT_FS && EXFAT_VIRTUAL_XATTR + default "u:object_r:sdcard_external:s0" + help + Set this to the default string for SELinux label. + +config EXFAT_SUPPORT_STLOG + bool "Enable storage log" + default y + depends on EXFAT_FS && PROC_STLOG diff --git a/fs/exfat/Makefile b/fs/exfat/Makefile new file mode 100755 index 0000000000000..f4ffef4b7a0bd --- /dev/null +++ b/fs/exfat/Makefile @@ -0,0 +1,15 @@ + +obj-y += exfat_core.o exfat_fs.o + +exfat_fs-y := exfat_super.o + +exfat_core-y := exfat.o exfat_api.o exfat_blkdev.o exfat_cache.o \ + exfat_data.o exfat_global.o exfat_nls.o \ + exfat_oal.o exfat_upcase.o exfat_xattr.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean + diff --git a/fs/exfat/exfat.c b/fs/exfat/exfat.c new file mode 100755 index 0000000000000..6f62ed9ef63e3 --- /dev/null +++ b/fs/exfat/exfat.c @@ -0,0 +1,5046 @@ +/* Some of the source code in this file came from "linux/fs/fat/misc.c". */ +/* + * linux/fs/fat/misc.c + * + * Written 1992,1993 by Werner Almesberger + * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980 + * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) + */ + +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_blkdev.h" +#include "exfat_cache.h" +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat_super.h" +#include "exfat.h" + +#include + +#define THERE_IS_MBR 0 + +#if (THERE_IS_MBR == 1) +#include "exfat_part.h" +#endif + +#define DELAYED_SYNC 0 + +#define ELAPSED_TIME 0 + +#if (ELAPSED_TIME == 1) +#include + +static UINT32 __t1, __t2; +static UINT32 get_current_msec(void) +{ + struct timeval tm; + do_gettimeofday(&tm); + return (UINT32)(tm.tv_sec*1000000 + tm.tv_usec); +} +#define TIME_START() do {__t1 = get_current_msec(); } while (0) +#define TIME_END() do {__t2 = get_current_msec(); } while (0) +#define PRINT_TIME(n) do {printk("[EXFAT] Elapsed time %d = %d (usec)\n", n, (__t2 - __t1)); } while (0) +#else +#define TIME_START() +#define TIME_END() +#define PRINT_TIME(n) +#endif + +static void __set_sb_dirty(struct super_block *sb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + sb->s_dirt = 1; +#else + struct exfat_sb_info *sbi = EXFAT_SB(sb); + sbi->s_dirt = 1; +#endif +} + +extern UINT8 uni_upcase[]; + +static UINT8 name_buf[MAX_PATH_LENGTH *MAX_CHARSET_SIZE]; + +static INT8 *reserved_names[] = { + "AUX ", "CON ", "NUL ", "PRN ", + "COM1 ", "COM2 ", "COM3 ", "COM4 ", + "COM5 ", "COM6 ", "COM7 ", "COM8 ", "COM9 ", + "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ", + "LPT5 ", "LPT6 ", "LPT7 ", "LPT8 ", "LPT9 ", + NULL +}; + +static UINT8 free_bit[] = { + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, + 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, + 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, + 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, + 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, + 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, + 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +static UINT8 used_bit[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, + 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, + 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, + 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, + 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, + 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, + 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +INT32 ffsInit(void) +{ + INT32 ret; + + ret = bdev_init(); + if (ret) + return ret; + + ret = fs_init(); + if (ret) + return ret; + + return FFS_SUCCESS; +} + +INT32 ffsShutdown(void) +{ + INT32 ret; + ret = fs_shutdown(); + if (ret) + return ret; + + ret = bdev_shutdown(); + if (ret) + return ret; + + return FFS_SUCCESS; +} + +INT32 ffsMountVol(struct super_block *sb, INT32 drv) +{ + INT32 i, ret; +#if (THERE_IS_MBR == 1) + MBR_SECTOR_T *p_mbr; + PART_ENTRY_T *p_pte; +#endif + PBR_SECTOR_T *p_pbr; + struct buffer_head *tmp_bh = NULL; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + p_fs->drv = drv; + p_fs->dev_ejected = FALSE; + + if (bdev_open(sb)) + return FFS_MEDIAERR; + + if (p_bd->sector_size < sb->s_blocksize) + return FFS_MEDIAERR; + if (p_bd->sector_size > sb->s_blocksize) + sb_set_blocksize(sb, p_bd->sector_size); + + if (sector_read(sb, 0, &tmp_bh, 1) != FFS_SUCCESS) + return FFS_MEDIAERR; + +#if (THERE_IS_MBR == 1) + if (buf[0] != 0xEB) { + p_mbr = (MBR_SECTOR_T *) tmp_bh->b_data; + + if (GET16_A(p_mbr->signature) != MBR_SIGNATURE) { + brelse(tmp_bh); + bdev_close(sb); + return FFS_FORMATERR; + } + + p_pte = (PART_ENTRY_T *) p_mbr->partition + 0; + p_fs->PBR_sector = GET32(p_pte->start_sector); + p_fs->num_sectors = GET32(p_pte->num_sectors); + + if (p_fs->num_sectors == 0) { + brelse(tmp_bh); + bdev_close(sb); + return FFS_ERROR; + } + + if (sector_read(sb, p_fs->PBR_sector, &tmp_bh, 1) != FFS_SUCCESS) { + bdev_close(sb); + return FFS_MEDIAERR; + } + } else { +#endif + p_fs->PBR_sector = 0; +#if (THERE_IS_MBR == 1) + } +#endif + + p_pbr = (PBR_SECTOR_T *) tmp_bh->b_data; + + if (GET16_A(p_pbr->signature) != PBR_SIGNATURE) { + brelse(tmp_bh); + bdev_close(sb); + return FFS_FORMATERR; + } + + for (i = 0; i < 53; i++) + if (p_pbr->bpb[i]) + break; + + ret = FFS_FORMATERR; + if (i >= 53) + ret = exfat_mount(sb, p_pbr); + + brelse(tmp_bh); + + if (ret) { + bdev_close(sb); + return ret; + } + + if (p_fs->vol_type == EXFAT) { + ret = load_alloc_bitmap(sb); + if (ret) { + bdev_close(sb); + return ret; + } + ret = load_upcase_table(sb); + if (ret) { + free_alloc_bitmap(sb); + bdev_close(sb); + return ret; + } + } + + if (p_fs->dev_ejected) { + if (p_fs->vol_type == EXFAT) { + free_upcase_table(sb); + free_alloc_bitmap(sb); + } + bdev_close(sb); + return FFS_MEDIAERR; + } + + return FFS_SUCCESS; +} + +INT32 ffsUmountVol(struct super_block *sb) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); + + if (p_fs->vol_type == EXFAT) { + free_upcase_table(sb); + free_alloc_bitmap(sb); + } + + FAT_release_all(sb); + buf_release_all(sb); + + bdev_close(sb); + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsGetVolInfo(struct super_block *sb, VOL_INFO_T *info) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_fs->used_clusters == (UINT32) ~0) + p_fs->used_clusters = p_fs->fs_func->count_used_clusters(sb); + + info->FatType = p_fs->vol_type; + info->ClusterSize = p_fs->cluster_size; + info->NumClusters = p_fs->num_clusters - 2; + info->UsedClusters = p_fs->used_clusters; + info->FreeClusters = info->NumClusters - info->UsedClusters; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsSyncVol(struct super_block *sb, INT32 do_sync) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + fs_sync(sb, do_sync); + fs_set_vol_flags(sb, VOL_CLEAN); + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid) +{ + INT32 ret, dentry, num_entries; + CHAIN_T dir; + UNI_NAME_T uni_name; + DOS_NAME_T dos_name; + DENTRY_T *ep, *ep2; + ENTRY_SET_CACHE_T *es=NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + PRINTK("ffsLookupFile entered\n"); + + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + return ret; + + ret = get_num_entries_and_dos_name(sb, &dir, &uni_name, &num_entries, &dos_name); + if (ret) + return ret; + + dentry = p_fs->fs_func->find_dir_entry(sb, &dir, &uni_name, num_entries, &dos_name, TYPE_ALL); + if (dentry < -1) + return FFS_NOTFOUND; + + fid->dir.dir = dir.dir; + fid->dir.size = dir.size; + fid->dir.flags = dir.flags; + fid->entry = dentry; + + if (dentry == -1) { + fid->type = TYPE_DIR; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + fid->attr = ATTR_SUBDIR; + fid->flags = 0x01; + fid->size = 0; + fid->start_clu = p_fs->root_dir; + } else { + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &dir, dentry, ES_2_ENTRIES, &ep); + if (!es) + return FFS_MEDIAERR; + ep2 = ep+1; + } else { + ep = get_entry_in_dir(sb, &dir, dentry, NULL); + if (!ep) + return FFS_MEDIAERR; + ep2 = ep; + } + + fid->type = p_fs->fs_func->get_entry_type(ep); + fid->rwoffset = 0; + fid->hint_last_off = -1; + fid->attr = p_fs->fs_func->get_entry_attr(ep); + + fid->size = p_fs->fs_func->get_entry_size(ep2); + if ((fid->type == TYPE_FILE) && (fid->size == 0)) { + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->start_clu = CLUSTER_32(~0); + } else { + fid->flags = p_fs->fs_func->get_entry_flag(ep2); + fid->start_clu = p_fs->fs_func->get_entry_clu0(ep2); + } + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + } + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + PRINTK("ffsLookupFile exited successfully\n"); + + return FFS_SUCCESS; +} + +INT32 ffsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid) +{ + INT32 ret; + CHAIN_T dir; + UNI_NAME_T uni_name; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + return ret; + + fs_set_vol_flags(sb, VOL_DIRTY); + ret = create_file(inode, &dir, &uni_name, mode, fid); + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return ret; +} + +INT32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount) +{ + INT32 offset, sec_offset, clu_offset; + UINT32 clu, LogSector; + UINT64 oneblkread, read_bytes; + struct buffer_head *tmp_bh = NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (fid->type != TYPE_FILE) + return FFS_PERMISSIONERR; + + if (fid->rwoffset > fid->size) + fid->rwoffset = fid->size; + + if (count > (fid->size - fid->rwoffset)) + count = fid->size - fid->rwoffset; + + if (count == 0) { + if (rcount != NULL) + *rcount = 0; + return FFS_EOF; + } + + read_bytes = 0; + + while (count > 0) { + clu_offset = (INT32)(fid->rwoffset >> p_fs->cluster_size_bits); + clu = fid->start_clu; + + if (fid->flags == 0x03) { + clu += clu_offset; + } else { + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu = fid->hint_last_clu; + } + + while (clu_offset > 0) { + if (FAT_read(sb, clu, &clu) == -1) + return FFS_MEDIAERR; + + clu_offset--; + } + } + + fid->hint_last_off = (INT32)(fid->rwoffset >> p_fs->cluster_size_bits); + fid->hint_last_clu = clu; + + offset = (INT32)(fid->rwoffset & (p_fs->cluster_size-1)); + sec_offset = offset >> p_bd->sector_size_bits; + offset &= p_bd->sector_size_mask; + + LogSector = START_SECTOR(clu) + sec_offset; + + oneblkread = (UINT64)(p_bd->sector_size - offset); + if (oneblkread > count) + oneblkread = count; + + if ((offset == 0) && (oneblkread == p_bd->sector_size)) { + if (sector_read(sb, LogSector, &tmp_bh, 1) != FFS_SUCCESS) + goto err_out; + MEMCPY(((INT8 *) buffer)+read_bytes, ((INT8 *) tmp_bh->b_data), (INT32) oneblkread); + } else { + if (sector_read(sb, LogSector, &tmp_bh, 1) != FFS_SUCCESS) + goto err_out; + MEMCPY(((INT8 *) buffer)+read_bytes, ((INT8 *) tmp_bh->b_data)+offset, (INT32) oneblkread); + } + count -= oneblkread; + read_bytes += oneblkread; + fid->rwoffset += oneblkread; + } + brelse(tmp_bh); + +err_out: + if (rcount != NULL) + *rcount = read_bytes; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount) +{ + INT32 modified = FALSE, offset, sec_offset, clu_offset; + INT32 num_clusters, num_alloc, num_alloced = (INT32) ~0; + UINT32 clu, last_clu, LogSector, sector; + UINT64 oneblkwrite, write_bytes; + CHAIN_T new_clu; + TIMESTAMP_T tm; + DENTRY_T *ep, *ep2; + ENTRY_SET_CACHE_T *es = NULL; + struct buffer_head *tmp_bh = NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + UINT8 tz_utc = EXFAT_SB(sb)->options.tz_utc; + + if (fid->type != TYPE_FILE) + return FFS_PERMISSIONERR; + + if (fid->rwoffset > fid->size) + fid->rwoffset = fid->size; + + if (count == 0) { + if (wcount != NULL) + *wcount = 0; + return FFS_SUCCESS; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + if (fid->size == 0) + num_clusters = 0; + else + num_clusters = (INT32)((fid->size-1) >> p_fs->cluster_size_bits) + 1; + + write_bytes = 0; + + while (count > 0) { + clu_offset = (INT32)(fid->rwoffset >> p_fs->cluster_size_bits); + clu = last_clu = fid->start_clu; + + if (fid->flags == 0x03) { + if ((clu_offset > 0) && (clu != CLUSTER_32(~0))) { + last_clu += clu_offset - 1; + + if (clu_offset == num_clusters) + clu = CLUSTER_32(~0); + else + clu += clu_offset; + } + } else { + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu = fid->hint_last_clu; + } + + while ((clu_offset > 0) && (clu != CLUSTER_32(~0))) { + last_clu = clu; + if (FAT_read(sb, clu, &clu) == -1) + return FFS_MEDIAERR; + + clu_offset--; + } + } + + if (clu == CLUSTER_32(~0)) { + num_alloc = (INT32)((count-1) >> p_fs->cluster_size_bits) + 1; + new_clu.dir = (last_clu == CLUSTER_32(~0)) ? CLUSTER_32(~0) : last_clu+1; + new_clu.size = 0; + new_clu.flags = fid->flags; + + num_alloced = p_fs->fs_func->alloc_cluster(sb, num_alloc, &new_clu); + if (num_alloced == 0) + break; + else if (num_alloced < 0) + return FFS_MEDIAERR; + + if (last_clu == CLUSTER_32(~0)) { + if (new_clu.flags == 0x01) + fid->flags = 0x01; + fid->start_clu = new_clu.dir; + modified = TRUE; + } else { + if (new_clu.flags != fid->flags) { + exfat_chain_cont_cluster(sb, fid->start_clu, num_clusters); + fid->flags = 0x01; + modified = TRUE; + } + if (new_clu.flags == 0x01) + FAT_write(sb, last_clu, new_clu.dir); + } + + num_clusters += num_alloced; + clu = new_clu.dir; + } + + fid->hint_last_off = (INT32)(fid->rwoffset >> p_fs->cluster_size_bits); + fid->hint_last_clu = clu; + + offset = (INT32)(fid->rwoffset & (p_fs->cluster_size-1)); + sec_offset = offset >> p_bd->sector_size_bits; + offset &= p_bd->sector_size_mask; + + LogSector = START_SECTOR(clu) + sec_offset; + + oneblkwrite = (UINT64)(p_bd->sector_size - offset); + if (oneblkwrite > count) + oneblkwrite = count; + + if ((offset == 0) && (oneblkwrite == p_bd->sector_size)) { + if (sector_read(sb, LogSector, &tmp_bh, 0) != FFS_SUCCESS) + goto err_out; + MEMCPY(((INT8 *) tmp_bh->b_data), ((INT8 *) buffer)+write_bytes, (INT32) oneblkwrite); + if (sector_write(sb, LogSector, tmp_bh, 0) != FFS_SUCCESS) { + brelse(tmp_bh); + goto err_out; + } + } else { + if ((offset > 0) || ((fid->rwoffset+oneblkwrite) < fid->size)) { + if (sector_read(sb, LogSector, &tmp_bh, 1) != FFS_SUCCESS) + goto err_out; + } else { + if (sector_read(sb, LogSector, &tmp_bh, 0) != FFS_SUCCESS) + goto err_out; + } + + MEMCPY(((INT8 *) tmp_bh->b_data)+offset, ((INT8 *) buffer)+write_bytes, (INT32) oneblkwrite); + if (sector_write(sb, LogSector, tmp_bh, 0) != FFS_SUCCESS) { + brelse(tmp_bh); + goto err_out; + } + } + + count -= oneblkwrite; + write_bytes += oneblkwrite; + fid->rwoffset += oneblkwrite; + + fid->attr |= ATTR_ARCHIVE; + + if (fid->size < fid->rwoffset) { + fid->size = fid->rwoffset; + modified = TRUE; + } + } + + brelse(tmp_bh); + + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_ALL_ENTRIES, &ep); + if (es == NULL) + goto err_out; + ep2 = ep+1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + goto err_out; + ep2 = ep; + } + + p_fs->fs_func->set_entry_time(ep, tm_current(&tm, tz_utc), TM_MODIFY); + p_fs->fs_func->set_entry_attr(ep, fid->attr); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + + if (modified) { + if (p_fs->fs_func->get_entry_flag(ep2) != fid->flags) + p_fs->fs_func->set_entry_flag(ep2, fid->flags); + + if (p_fs->fs_func->get_entry_size(ep2) != fid->size) + p_fs->fs_func->set_entry_size(ep2, fid->size); + + if (p_fs->fs_func->get_entry_clu0(ep2) != fid->start_clu) + p_fs->fs_func->set_entry_clu0(ep2, fid->start_clu); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + } + + if (p_fs->vol_type == EXFAT) { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + +err_out: + if (wcount != NULL) + *wcount = write_bytes; + + if (num_alloced == 0) + return FFS_FULL; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size) +{ + INT32 num_clusters; + UINT32 last_clu = CLUSTER_32(0), sector; + CHAIN_T clu; + TIMESTAMP_T tm; + DENTRY_T *ep, *ep2; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + ENTRY_SET_CACHE_T *es=NULL; + UINT8 tz_utc = EXFAT_SB(sb)->options.tz_utc; + + if (fid->type != TYPE_FILE) + return FFS_PERMISSIONERR; + + if (fid->size != old_size) { + printk(KERN_ERR "[EXFAT] truncate : can't skip it because of " + "size-mismatch(old:%lld->fid:%lld).\n" + ,old_size, fid->size); + } + + if (old_size <= new_size) + return FFS_SUCCESS; + + fs_set_vol_flags(sb, VOL_DIRTY); + + clu.dir = fid->start_clu; + clu.size = (INT32)((old_size-1) >> p_fs->cluster_size_bits) + 1; + clu.flags = fid->flags; + + if (new_size > 0) { + num_clusters = (INT32)((new_size-1) >> p_fs->cluster_size_bits) + 1; + + if (clu.flags == 0x03) { + clu.dir += num_clusters; + } else { + while (num_clusters > 0) { + last_clu = clu.dir; + if (FAT_read(sb, clu.dir, &(clu.dir)) == -1) + return FFS_MEDIAERR; + num_clusters--; + } + } + + clu.size -= num_clusters; + } + + fid->size = new_size; + fid->attr |= ATTR_ARCHIVE; + if (new_size == 0) { + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->start_clu = CLUSTER_32(~0); + } + + if (fid->dir.dir != DIR_DELETED) { + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_ALL_ENTRIES, &ep); + if (es == NULL) + return FFS_MEDIAERR; + ep2 = ep+1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + return FFS_MEDIAERR; + ep2 = ep; + } + + p_fs->fs_func->set_entry_time(ep, tm_current(&tm, tz_utc), TM_MODIFY); + p_fs->fs_func->set_entry_attr(ep, fid->attr); + + p_fs->fs_func->set_entry_size(ep2, new_size); + if (new_size == 0) { + p_fs->fs_func->set_entry_flag(ep2, 0x01); + p_fs->fs_func->set_entry_clu0(ep2, CLUSTER_32(0)); + } + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + } + + if (last_clu != CLUSTER_32(0)) { + if (fid->flags == 0x01) + FAT_write(sb, last_clu, CLUSTER_32(~0)); + } + + p_fs->fs_func->free_cluster(sb, &clu, 0); + + fid->hint_last_off = -1; + if (fid->rwoffset > fid->size) { + fid->rwoffset = fid->size; + } + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +static void update_parent_info( FILE_ID_T *fid, struct inode *parent_inode) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(parent_inode->i_sb)->fs_info); + FILE_ID_T *parent_fid = &(EXFAT_I(parent_inode)->fid); + + if (unlikely((parent_fid->flags != fid->dir.flags) + || (parent_fid->size != (fid->dir.size<cluster_size_bits)) + || (parent_fid->start_clu != fid->dir.dir))) { + + fid->dir.dir = parent_fid->start_clu; + fid->dir.flags = parent_fid->flags; + fid->dir.size = ((parent_fid->size + (p_fs->cluster_size-1)) + >> p_fs->cluster_size_bits); + } +} + +INT32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry) +{ + INT32 ret; + INT32 dentry; + CHAIN_T olddir, newdir; + CHAIN_T *p_dir=NULL; + UNI_NAME_T uni_name; + DENTRY_T *ep; + struct super_block *sb = old_parent_inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + UINT8 *new_path = (UINT8 *) new_dentry->d_name.name; + struct inode *new_inode = new_dentry->d_inode; + int num_entries; + FILE_ID_T *new_fid = NULL; + UINT32 new_entry_type = TYPE_UNUSED; + INT32 new_entry=0; + + if ((new_path == NULL) || (STRLEN(new_path) == 0)) + return FFS_ERROR; + + update_parent_info(fid, old_parent_inode); + + olddir.dir = fid->dir.dir; + olddir.size = fid->dir.size; + olddir.flags = fid->dir.flags; + + dentry = fid->entry; + + if (p_fs->vol_type != EXFAT) { + if ((olddir.dir != p_fs->root_dir) && (dentry < 2)) + return FFS_PERMISSIONERR; + } + + ep = get_entry_in_dir(sb, &olddir, dentry, NULL); + if (!ep) + return FFS_MEDIAERR; + + if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) + return FFS_PERMISSIONERR; + + if (new_inode) { + ret = FFS_MEDIAERR; + new_fid = &EXFAT_I(new_inode)->fid; + + update_parent_info(new_fid, new_parent_inode); + + p_dir = &(new_fid->dir); + new_entry = new_fid->entry; + ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); + if (!ep) + goto out; + + new_entry_type = p_fs->fs_func->get_entry_type(ep); + + if (new_entry_type == TYPE_DIR) { + CHAIN_T new_clu; + new_clu.dir = new_fid->start_clu; + new_clu.size = (INT32)((new_fid->size-1) >> p_fs->cluster_size_bits) + 1; + new_clu.flags = new_fid->flags; + + if (!is_dir_empty(sb, &new_clu)) + return FFS_FILEEXIST; + } + } + + if (STRLEN(new_path) >= MAX_NAME_LENGTH) + return FFS_NAMETOOLONG; + + + ret = resolve_path(new_parent_inode, new_path, &newdir, &uni_name); + if (ret) + return ret; + + fs_set_vol_flags(sb, VOL_DIRTY); + + if (olddir.dir == newdir.dir) + ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name, fid); + else + ret = move_file(new_parent_inode, &olddir, dentry, &newdir, &uni_name, fid); + + if ((ret == FFS_SUCCESS) && new_inode) { + ep = get_entry_in_dir(sb, p_dir, new_entry, NULL); + if (!ep) + goto out; + + num_entries = p_fs->fs_func->count_ext_entries(sb, p_dir, new_entry, ep); + if (num_entries < 0) + goto out; + p_fs->fs_func->delete_dir_entry(sb, p_dir, new_entry, 0, num_entries+1); + if (new_entry_type == TYPE_DIR) { + CHAIN_T new_clu_to_free; + new_clu_to_free.dir = new_fid->start_clu; + new_clu_to_free.size = (INT32)((new_fid->size-1) >> p_fs->cluster_size_bits) + 1; + new_clu_to_free.flags = new_fid->flags; + + p_fs->fs_func->free_cluster(sb, &new_clu_to_free, 1); + + new_fid->size = 0; + new_fid->start_clu = CLUSTER_32(~0); + new_fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + } + + new_fid->dir.dir = DIR_DELETED; + + } +out: +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return ret; +} + +INT32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid) +{ + INT32 dentry; + CHAIN_T dir, clu_to_free; + DENTRY_T *ep; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + dir.dir = fid->dir.dir; + dir.size = fid->dir.size; + dir.flags = fid->dir.flags; + + dentry = fid->entry; + + ep = get_entry_in_dir(sb, &dir, dentry, NULL); + if (!ep) + return FFS_MEDIAERR; + + if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) + return FFS_PERMISSIONERR; + + fs_set_vol_flags(sb, VOL_DIRTY); + + remove_file(inode, &dir, dentry); + + clu_to_free.dir = fid->start_clu; + clu_to_free.size = (INT32)((fid->size-1) >> p_fs->cluster_size_bits) + 1; + clu_to_free.flags = fid->flags; + + p_fs->fs_func->free_cluster(sb, &clu_to_free, 0); + + + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + fid->flags = (p_fs->vol_type == EXFAT)? 0x03: 0x01; + fid->dir.dir = DIR_DELETED; + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsSetAttr(struct inode *inode, UINT32 attr) +{ + UINT32 type, sector; + DENTRY_T *ep; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + UINT8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + ENTRY_SET_CACHE_T *es = NULL; + + if (fid->attr == attr) { + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + + if (fid->dir.dir == DIR_DELETED) + return FFS_SUCCESS; + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + } + + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_ALL_ENTRIES, &ep); + if (es == NULL) + return FFS_MEDIAERR; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + return FFS_MEDIAERR; + } + + type = p_fs->fs_func->get_entry_type(ep); + + if (((type == TYPE_FILE) && (attr & ATTR_SUBDIR)) || + ((type == TYPE_DIR) && (!(attr & ATTR_SUBDIR)))) { + INT32 err; + if (p_fs->dev_ejected) + err = FFS_MEDIAERR; + else + err = FFS_ERROR; + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + return err; + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + fid->attr = attr; + p_fs->fs_func->set_entry_attr(ep, attr); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info) +{ + UINT32 sector; + INT32 count; + CHAIN_T dir; + UNI_NAME_T uni_name; + TIMESTAMP_T tm; + DENTRY_T *ep, *ep2; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + ENTRY_SET_CACHE_T *es=NULL; + UINT8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + + PRINTK("ffsGetStat entered\n"); + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + info->Attr = ATTR_SUBDIR; + MEMSET((INT8 *) &info->CreateTimestamp, 0, sizeof(DATE_TIME_T)); + MEMSET((INT8 *) &info->ModifyTimestamp, 0, sizeof(DATE_TIME_T)); + MEMSET((INT8 *) &info->AccessTimestamp, 0, sizeof(DATE_TIME_T)); + STRCPY(info->ShortName, "."); + STRCPY(info->Name, "."); + + dir.dir = p_fs->root_dir; + dir.flags = 0x01; + + if (p_fs->root_dir == CLUSTER_32(0)) + info->Size = p_fs->dentries_in_root << DENTRY_SIZE_BITS; + else + info->Size = count_num_clusters(sb, &dir) << p_fs->cluster_size_bits; + + count = count_dos_name_entries(sb, &dir, TYPE_DIR); + if (count < 0) + return FFS_MEDIAERR; + info->NumSubdirs = count; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + } + + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_2_ENTRIES, &ep); + if (es == NULL) + return FFS_MEDIAERR; + ep2 = ep+1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + return FFS_MEDIAERR; + ep2 = ep; + buf_lock(sb, sector); + } + + info->Attr = p_fs->fs_func->get_entry_attr(ep); + + p_fs->fs_func->get_entry_time(ep, &tm, TM_CREATE); + info->CreateTimestamp.Year = tm.year; + info->CreateTimestamp.Month = tm.mon; + info->CreateTimestamp.Day = tm.day; + info->CreateTimestamp.Hour = tm.hour; + info->CreateTimestamp.Minute = tm.min; + info->CreateTimestamp.Second = tm.sec; + info->CreateTimestamp.MilliSecond = 0; + + p_fs->fs_func->get_entry_time(ep, &tm, TM_MODIFY); + info->ModifyTimestamp.Year = tm.year; + info->ModifyTimestamp.Month = tm.mon; + info->ModifyTimestamp.Day = tm.day; + info->ModifyTimestamp.Hour = tm.hour; + info->ModifyTimestamp.Minute = tm.min; + info->ModifyTimestamp.Second = tm.sec; + info->ModifyTimestamp.MilliSecond = 0; + + MEMSET((INT8 *) &info->AccessTimestamp, 0, sizeof(DATE_TIME_T)); + + *(uni_name.name) = 0x0; + p_fs->fs_func->get_uni_name_from_ext_entry(sb, &(fid->dir), fid->entry, uni_name.name); + if (*(uni_name.name) == 0x0) + get_uni_name_from_dos_entry(sb, (DOS_DENTRY_T *) ep, &uni_name, 0x1); + nls_uniname_to_cstring(sb, info->Name, &uni_name); + + if (p_fs->vol_type == EXFAT) { + info->NumSubdirs = 2; + } else { + buf_unlock(sb, sector); + get_uni_name_from_dos_entry(sb, (DOS_DENTRY_T *) ep, &uni_name, 0x0); + nls_uniname_to_cstring(sb, info->ShortName, &uni_name); + info->NumSubdirs = 0; + } + + info->Size = p_fs->fs_func->get_entry_size(ep2); + + if (p_fs->vol_type == EXFAT) + release_entry_set(es); + + if (is_dir) { + dir.dir = fid->start_clu; + dir.flags = 0x01; + + if (info->Size == 0) + info->Size = (UINT64) count_num_clusters(sb, &dir) << p_fs->cluster_size_bits; + + count = count_dos_name_entries(sb, &dir, TYPE_DIR); + if (count < 0) + return FFS_MEDIAERR; + info->NumSubdirs += count; + } + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + PRINTK("ffsGetStat exited successfully\n"); + return FFS_SUCCESS; +} + +INT32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info) +{ + UINT32 sector; + TIMESTAMP_T tm; + DENTRY_T *ep, *ep2; + ENTRY_SET_CACHE_T *es=NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + UINT8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0; + + if (fid->dir.dir == DIR_DELETED) + return FFS_SUCCESS; + + if (is_dir) { + if ((fid->dir.dir == p_fs->root_dir) && + (fid->entry == -1)) { + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + return FFS_SUCCESS; + } + } + + fs_set_vol_flags(sb, VOL_DIRTY); + + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_ALL_ENTRIES, &ep); + if (es == NULL) + return FFS_MEDIAERR; + ep2 = ep+1; + } else { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + return FFS_MEDIAERR; + ep2 = ep; + } + + + p_fs->fs_func->set_entry_attr(ep, info->Attr); + + tm.sec = info->CreateTimestamp.Second; + tm.min = info->CreateTimestamp.Minute; + tm.hour = info->CreateTimestamp.Hour; + tm.day = info->CreateTimestamp.Day; + tm.mon = info->CreateTimestamp.Month; + tm.year = info->CreateTimestamp.Year; + p_fs->fs_func->set_entry_time(ep, &tm, TM_CREATE); + + tm.sec = info->ModifyTimestamp.Second; + tm.min = info->ModifyTimestamp.Minute; + tm.hour = info->ModifyTimestamp.Hour; + tm.day = info->ModifyTimestamp.Day; + tm.mon = info->ModifyTimestamp.Month; + tm.year = info->ModifyTimestamp.Year; + p_fs->fs_func->set_entry_time(ep, &tm, TM_MODIFY); + + + p_fs->fs_func->set_entry_size(ep2, info->Size); + + if (p_fs->vol_type != EXFAT) { + buf_modify(sb, sector); + } else { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu) +{ + INT32 num_clusters, num_alloced, modified = FALSE; + UINT32 last_clu, sector; + CHAIN_T new_clu; + DENTRY_T *ep; + ENTRY_SET_CACHE_T *es = NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + + fid->rwoffset = (INT64)(clu_offset) << p_fs->cluster_size_bits; + + if (EXFAT_I(inode)->mmu_private == 0) + num_clusters = 0; + else + num_clusters = (INT32)((EXFAT_I(inode)->mmu_private-1) >> p_fs->cluster_size_bits) + 1; + + *clu = last_clu = fid->start_clu; + + if (fid->flags == 0x03) { + if ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { + last_clu += clu_offset - 1; + + if (clu_offset == num_clusters) + *clu = CLUSTER_32(~0); + else + *clu += clu_offset; + } + } else { + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + *clu = fid->hint_last_clu; + } + + while ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) { + last_clu = *clu; + if (FAT_read(sb, *clu, clu) == -1) + return FFS_MEDIAERR; + clu_offset--; + } + } + + if (*clu == CLUSTER_32(~0)) { + fs_set_vol_flags(sb, VOL_DIRTY); + + new_clu.dir = (last_clu == CLUSTER_32(~0)) ? CLUSTER_32(~0) : last_clu+1; + new_clu.size = 0; + new_clu.flags = fid->flags; + + num_alloced = p_fs->fs_func->alloc_cluster(sb, 1, &new_clu); + if (num_alloced < 0) + return FFS_MEDIAERR; + else if (num_alloced == 0) + return FFS_FULL; + + if (last_clu == CLUSTER_32(~0)) { + if (new_clu.flags == 0x01) + fid->flags = 0x01; + fid->start_clu = new_clu.dir; + modified = TRUE; + } else { + if (new_clu.flags != fid->flags) { + exfat_chain_cont_cluster(sb, fid->start_clu, num_clusters); + fid->flags = 0x01; + modified = TRUE; + } + if (new_clu.flags == 0x01) + FAT_write(sb, last_clu, new_clu.dir); + } + + num_clusters += num_alloced; + *clu = new_clu.dir; + + if (fid->dir.dir != DIR_DELETED) { + if (p_fs->vol_type == EXFAT) { + es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry, ES_ALL_ENTRIES, &ep); + if (es == NULL) + return FFS_MEDIAERR; + ep++; + } + + if (modified) { + if (p_fs->vol_type != EXFAT) { + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, §or); + if (!ep) + return FFS_MEDIAERR; + } + + if (p_fs->fs_func->get_entry_flag(ep) != fid->flags) + p_fs->fs_func->set_entry_flag(ep, fid->flags); + + if (p_fs->fs_func->get_entry_clu0(ep) != fid->start_clu) + p_fs->fs_func->set_entry_clu0(ep, fid->start_clu); + + if (p_fs->vol_type != EXFAT) + buf_modify(sb, sector); + } + + if (p_fs->vol_type == EXFAT) { + update_dir_checksum_with_entry_set(sb, es); + release_entry_set(es); + } + } + + inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9); + } + + fid->hint_last_off = (INT32)(fid->rwoffset >> p_fs->cluster_size_bits); + fid->hint_last_clu = *clu; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid) +{ + INT32 ret; + CHAIN_T dir; + UNI_NAME_T uni_name; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + PRINTK("ffsCreateDir entered\n"); + + ret = resolve_path(inode, path, &dir, &uni_name); + if (ret) + return ret; + + fs_set_vol_flags(sb, VOL_DIRTY); + + ret = create_dir(inode, &dir, &uni_name, fid); + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return ret; +} + +INT32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry) +{ + INT32 i, dentry, clu_offset; + INT32 dentries_per_clu, dentries_per_clu_bits = 0; + UINT32 type, sector; + CHAIN_T dir, clu; + UNI_NAME_T uni_name; + TIMESTAMP_T tm; + DENTRY_T *ep; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + + if (fid->type != TYPE_DIR) + return FFS_PERMISSIONERR; + + if (fid->entry == -1) { + dir.dir = p_fs->root_dir; + dir.flags = 0x01; + } else { + dir.dir = fid->start_clu; + dir.size = (INT32)(fid->size >> p_fs->cluster_size_bits); + dir.flags = fid->flags; + } + + dentry = (INT32) fid->rwoffset; + + if (dir.dir == CLUSTER_32(0)) { + dentries_per_clu = p_fs->dentries_in_root; + + if (dentry == dentries_per_clu) { + clu.dir = CLUSTER_32(~0); + } else { + clu.dir = dir.dir; + clu.size = dir.size; + clu.flags = dir.flags; + } + } else { + dentries_per_clu = p_fs->dentries_per_clu; + dentries_per_clu_bits = my_log2(dentries_per_clu); + + clu_offset = dentry >> dentries_per_clu_bits; + clu.dir = dir.dir; + clu.size = dir.size; + clu.flags = dir.flags; + + if (clu.flags == 0x03) { + clu.dir += clu_offset; + clu.size -= clu_offset; + } else { + if ((clu_offset > 0) && (fid->hint_last_off > 0) && + (clu_offset >= fid->hint_last_off)) { + clu_offset -= fid->hint_last_off; + clu.dir = fid->hint_last_clu; + } + + while (clu_offset > 0) { + if (FAT_read(sb, clu.dir, &(clu.dir)) == -1) + return FFS_MEDIAERR; + + clu_offset--; + } + } + } + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + if (dir.dir == CLUSTER_32(0)) + i = dentry % dentries_per_clu; + else + i = dentry & (dentries_per_clu-1); + + for ( ; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, §or); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) + break; + + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + buf_lock(sb, sector); + dir_entry->Attr = p_fs->fs_func->get_entry_attr(ep); + + p_fs->fs_func->get_entry_time(ep, &tm, TM_CREATE); + dir_entry->CreateTimestamp.Year = tm.year; + dir_entry->CreateTimestamp.Month = tm.mon; + dir_entry->CreateTimestamp.Day = tm.day; + dir_entry->CreateTimestamp.Hour = tm.hour; + dir_entry->CreateTimestamp.Minute = tm.min; + dir_entry->CreateTimestamp.Second = tm.sec; + dir_entry->CreateTimestamp.MilliSecond = 0; + + p_fs->fs_func->get_entry_time(ep, &tm, TM_MODIFY); + dir_entry->ModifyTimestamp.Year = tm.year; + dir_entry->ModifyTimestamp.Month = tm.mon; + dir_entry->ModifyTimestamp.Day = tm.day; + dir_entry->ModifyTimestamp.Hour = tm.hour; + dir_entry->ModifyTimestamp.Minute = tm.min; + dir_entry->ModifyTimestamp.Second = tm.sec; + dir_entry->ModifyTimestamp.MilliSecond = 0; + + MEMSET((INT8 *) &dir_entry->AccessTimestamp, 0, sizeof(DATE_TIME_T)); + + *(uni_name.name) = 0x0; + p_fs->fs_func->get_uni_name_from_ext_entry(sb, &dir, dentry, uni_name.name); + if (*(uni_name.name) == 0x0) + get_uni_name_from_dos_entry(sb, (DOS_DENTRY_T *) ep, &uni_name, 0x1); + nls_uniname_to_cstring(sb, dir_entry->Name, &uni_name); + buf_unlock(sb, sector); + + if (p_fs->vol_type == EXFAT) { + ep = get_entry_in_dir(sb, &clu, i+1, NULL); + if (!ep) + return FFS_MEDIAERR; + } else { + get_uni_name_from_dos_entry(sb, (DOS_DENTRY_T *) ep, &uni_name, 0x0); + nls_uniname_to_cstring(sb, dir_entry->ShortName, &uni_name); + } + + dir_entry->Size = p_fs->fs_func->get_entry_size(ep); + + if (dir.dir == CLUSTER_32(0)) { + } else { + fid->hint_last_off = dentry >> dentries_per_clu_bits; + fid->hint_last_clu = clu.dir; + } + + fid->rwoffset = (INT64) ++dentry; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; + } + + if (dir.dir == CLUSTER_32(0)) + break; + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &(clu.dir)) == -1) + return FFS_MEDIAERR; + } + } + + *(dir_entry->Name) = '\0'; + + fid->rwoffset = (INT64) ++dentry; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid) +{ + INT32 dentry; + CHAIN_T dir, clu_to_free; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + dir.dir = fid->dir.dir; + dir.size = fid->dir.size; + dir.flags = fid->dir.flags; + + dentry = fid->entry; + + if (p_fs->vol_type != EXFAT) { + if ((dir.dir != p_fs->root_dir) && (dentry < 2)) + return FFS_PERMISSIONERR; + } + + clu_to_free.dir = fid->start_clu; + clu_to_free.size = (INT32)((fid->size-1) >> p_fs->cluster_size_bits) + 1; + clu_to_free.flags = fid->flags; + + if (!is_dir_empty(sb, &clu_to_free)) + return FFS_FILEEXIST; + + fs_set_vol_flags(sb, VOL_DIRTY); + + remove_file(inode, &dir, dentry); + + p_fs->fs_func->free_cluster(sb, &clu_to_free, 1); + + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + fid->flags = (p_fs->vol_type == EXFAT)? 0x03: 0x01; + fid->dir.dir = DIR_DELETED; + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + +INT32 ffsRemoveEntry(struct inode *inode, FILE_ID_T *fid) +{ + INT32 dentry; + CHAIN_T dir; + DENTRY_T *ep; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + dir.dir = fid->dir.dir; + dir.size = fid->dir.size; + dir.flags = fid->dir.flags; + + dentry = fid->entry; + + ep = get_entry_in_dir(sb, &dir, dentry, NULL); + if (!ep) + return FFS_MEDIAERR; + + if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) + return FFS_PERMISSIONERR; + + fs_set_vol_flags(sb, VOL_DIRTY); + + remove_file(inode, &dir, dentry); + + fid->dir.dir = DIR_DELETED; + +#if (DELAYED_SYNC == 0) + fs_sync(sb, 0); + fs_set_vol_flags(sb, VOL_CLEAN); +#endif + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + return FFS_SUCCESS; +} + + +INT32 fs_init(void) +{ + if (sizeof(DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(DOS_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(EXT_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(FILE_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(STRM_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(NAME_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(BMAP_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(CASE_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + if (sizeof(VOLM_DENTRY_T) != DENTRY_SIZE) { + return FFS_ALIGNMENTERR; + } + + return FFS_SUCCESS; +} + +INT32 fs_shutdown(void) +{ + return FFS_SUCCESS; +} + +void fs_set_vol_flags(struct super_block *sb, UINT32 new_flag) +{ + PBR_SECTOR_T *p_pbr; + BPBEX_T *p_bpb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_fs->vol_flag == new_flag) + return; + + p_fs->vol_flag = new_flag; + + if (p_fs->vol_type == EXFAT) { + if (p_fs->pbr_bh == NULL) { + if (sector_read(sb, p_fs->PBR_sector, &(p_fs->pbr_bh), 1) != FFS_SUCCESS) + return; + } + + p_pbr = (PBR_SECTOR_T *) p_fs->pbr_bh->b_data; + p_bpb = (BPBEX_T *) p_pbr->bpb; + SET16(p_bpb->vol_flags, (UINT16) new_flag); + + if ((new_flag == VOL_DIRTY) && (!buffer_dirty(p_fs->pbr_bh))) + sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 1); + else + sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 0); + } +} + +void fs_sync(struct super_block *sb, INT32 do_sync) +{ + if (do_sync) + bdev_sync(sb); +} + +void fs_error(struct super_block *sb) +{ + struct exfat_mount_options *opts = &EXFAT_SB(sb)->options; + + if (opts->errors == EXFAT_ERRORS_PANIC) + panic("[EXFAT] Filesystem panic from previous error\n"); + else if ((opts->errors == EXFAT_ERRORS_RO) && !(sb->s_flags & MS_RDONLY)) { + sb->s_flags |= MS_RDONLY; + printk(KERN_ERR "[EXFAT] Filesystem has been set read-only\n"); + ST_LOG("[EXFAT] Filesystem has been set read-only\n"); + } +} + +INT32 clear_cluster(struct super_block *sb, UINT32 clu) +{ + UINT32 s, n; + INT32 ret = FFS_SUCCESS; + struct buffer_head *tmp_bh = NULL; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (clu == CLUSTER_32(0)) { + s = p_fs->root_start_sector; + n = p_fs->data_start_sector; + } else { + s = START_SECTOR(clu); + n = s + p_fs->sectors_per_clu; + } + + for ( ; s < n; s++) { + if ((ret = sector_read(sb, s, &tmp_bh, 0)) != FFS_SUCCESS) + return ret; + + MEMSET((INT8 *) tmp_bh->b_data, 0x0, p_bd->sector_size); + if ((ret = sector_write(sb, s, tmp_bh, 0)) !=FFS_SUCCESS) + break; + } + + brelse(tmp_bh); + return ret; +} + +INT32 fat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain) +{ + INT32 i, num_clusters = 0; + UINT32 new_clu, last_clu = CLUSTER_32(~0), read_clu; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + new_clu = p_chain->dir; + if (new_clu == CLUSTER_32(~0)) + new_clu = p_fs->clu_srch_ptr; + else if (new_clu >= p_fs->num_clusters) + new_clu = 2; + + __set_sb_dirty(sb); + + p_chain->dir = CLUSTER_32(~0); + + for (i = 2; i < p_fs->num_clusters; i++) { + if (FAT_read(sb, new_clu, &read_clu) != 0) + return -1; + + if (read_clu == CLUSTER_32(0)) { + if(FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0) + return -1; + num_clusters++; + + if (p_chain->dir == CLUSTER_32(~0)) + p_chain->dir = new_clu; + else { + if(FAT_write(sb, last_clu, new_clu) < 0) + return -1; + } + + last_clu = new_clu; + + if ((--num_alloc) == 0) { + p_fs->clu_srch_ptr = new_clu; + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters += num_clusters; + + return(num_clusters); + } + } + if ((++new_clu) >= p_fs->num_clusters) + new_clu = 2; + } + + p_fs->clu_srch_ptr = new_clu; + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters += num_clusters; + + return(num_clusters); +} + +INT32 exfat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain) +{ + INT32 num_clusters = 0; + UINT32 hint_clu, new_clu, last_clu = CLUSTER_32(~0); + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + hint_clu = p_chain->dir; + if (hint_clu == CLUSTER_32(~0)) { + hint_clu = test_alloc_bitmap(sb, p_fs->clu_srch_ptr-2); + if (hint_clu == CLUSTER_32(~0)) + return 0; + } else if (hint_clu >= p_fs->num_clusters) { + hint_clu = 2; + p_chain->flags = 0x01; + } + + __set_sb_dirty(sb); + + p_chain->dir = CLUSTER_32(~0); + + while ((new_clu = test_alloc_bitmap(sb, hint_clu-2)) != CLUSTER_32(~0)) { + if (new_clu != hint_clu) { + if (p_chain->flags == 0x03) { + exfat_chain_cont_cluster(sb, p_chain->dir, num_clusters); + p_chain->flags = 0x01; + } + } + + if (set_alloc_bitmap(sb, new_clu-2) != FFS_SUCCESS) + return -1; + + num_clusters++; + + if (p_chain->flags == 0x01) { + if(FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0) + return -1; + } + + if (p_chain->dir == CLUSTER_32(~0)) { + p_chain->dir = new_clu; + } else { + if (p_chain->flags == 0x01) { + if(FAT_write(sb, last_clu, new_clu) < 0) + return -1; + } + } + last_clu = new_clu; + + if ((--num_alloc) == 0) { + p_fs->clu_srch_ptr = hint_clu; + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters += num_clusters; + + p_chain->size += num_clusters; + return(num_clusters); + } + + hint_clu = new_clu + 1; + if (hint_clu >= p_fs->num_clusters) { + hint_clu = 2; + + if (p_chain->flags == 0x03) { + exfat_chain_cont_cluster(sb, p_chain->dir, num_clusters); + p_chain->flags = 0x01; + } + } + } + + p_fs->clu_srch_ptr = hint_clu; + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters += num_clusters; + + p_chain->size += num_clusters; + return(num_clusters); +} + +void fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse) +{ + INT32 num_clusters = 0; + UINT32 clu, prev; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + INT32 i; + UINT32 sector; + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return; + __set_sb_dirty(sb); + clu = p_chain->dir; + + if (p_chain->size <= 0) + return; + + do { + if (p_fs->dev_ejected) + break; + + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) { + buf_release(sb, sector+i); + } + } + + prev = clu; + if (FAT_read(sb, clu, &clu) == -1) + break; + + if (FAT_write(sb, prev, CLUSTER_32(0)) < 0) + break; + num_clusters++; + + } while (clu != CLUSTER_32(~0)); + + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters -= num_clusters; +} + +void exfat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse) +{ + INT32 num_clusters = 0; + UINT32 clu; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + INT32 i; + UINT32 sector; + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return; + + if (p_chain->size <= 0) { + printk(KERN_ERR "[EXFAT] free_cluster : skip free-req clu:%u, " + "because of zero-size truncation\n" + ,p_chain->dir); + return; + } + + __set_sb_dirty(sb); + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + do { + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) { + buf_release(sb, sector+i); + } + } + + if (clr_alloc_bitmap(sb, clu-2) != FFS_SUCCESS) + break; + clu++; + + num_clusters++; + } while (num_clusters < p_chain->size); + } else { + do { + if (p_fs->dev_ejected) + break; + + if (do_relse) { + sector = START_SECTOR(clu); + for (i = 0; i < p_fs->sectors_per_clu; i++) { + buf_release(sb, sector+i); + } + } + + if (clr_alloc_bitmap(sb, clu-2) != FFS_SUCCESS) + break; + + if (FAT_read(sb, clu, &clu) == -1) + break; + num_clusters++; + } while ((clu != CLUSTER_32(0)) && (clu != CLUSTER_32(~0))); + } + + if (p_fs->used_clusters != (UINT32) ~0) + p_fs->used_clusters -= num_clusters; +} + +UINT32 find_last_cluster(struct super_block *sb, CHAIN_T *p_chain) +{ + UINT32 clu, next; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + clu += p_chain->size - 1; + } else { + while((FAT_read(sb, clu, &next) == 0) && (next != CLUSTER_32(~0))) { + if (p_fs->dev_ejected) + break; + clu = next; + } + } + + return(clu); +} + +INT32 count_num_clusters(struct super_block *sb, CHAIN_T *p_chain) +{ + INT32 i, count = 0; + UINT32 clu; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0))) + return 0; + + clu = p_chain->dir; + + if (p_chain->flags == 0x03) { + count = p_chain->size; + } else { + for (i = 2; i < p_fs->num_clusters; i++) { + count++; + if (FAT_read(sb, clu, &clu) != 0) + return 0; + if (clu == CLUSTER_32(~0)) + break; + } + } + + return(count); +} + +INT32 fat_count_used_clusters(struct super_block *sb) +{ + INT32 i, count = 0; + UINT32 clu; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = 2; i < p_fs->num_clusters; i++) { + if (FAT_read(sb, i, &clu) != 0) + break; + if (clu != CLUSTER_32(0)) + count++; + } + + return(count); +} + +INT32 exfat_count_used_clusters(struct super_block *sb) +{ + INT32 i, map_i, map_b, count = 0; + UINT8 k; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + map_i = map_b = 0; + + for (i = 2; i < p_fs->num_clusters; i += 8) { + k = *(((UINT8 *) p_fs->vol_amap[map_i]->b_data) + map_b); + count += used_bit[k]; + + if ((++map_b) >= p_bd->sector_size) { + map_i++; + map_b = 0; + } + } + + if ((p_fs->num_clusters - 2) < (UINT32)count) + count = p_fs->num_clusters - 2; + + return(count); +} + +void exfat_chain_cont_cluster(struct super_block *sb, UINT32 chain, INT32 len) +{ + if (len == 0) + return; + + while (len > 1) { + if (FAT_write(sb, chain, chain+1) < 0) + break; + chain++; + len--; + } + FAT_write(sb, chain, CLUSTER_32(~0)); +} + +INT32 load_alloc_bitmap(struct super_block *sb) +{ + INT32 i, j, ret; + UINT32 map_size; + UINT32 type, sector; + CHAIN_T clu; + BMAP_DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu.dir = p_fs->root_dir; + clu.flags = 0x01; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < p_fs->dentries_per_clu; i++) { + ep = (BMAP_DENTRY_T *) get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((DENTRY_T *) ep); + + if (type == TYPE_UNUSED) + break; + if (type != TYPE_BITMAP) + continue; + + if (ep->flags == 0x0) { + p_fs->map_clu = GET32_A(ep->start_clu); + map_size = (UINT32) GET64_A(ep->size); + + p_fs->map_sectors = ((map_size-1) >> p_bd->sector_size_bits) + 1; + + p_fs->vol_amap = (struct buffer_head **) MALLOC(sizeof(struct buffer_head *) * p_fs->map_sectors); + if (p_fs->vol_amap == NULL) + return FFS_MEMORYERR; + + sector = START_SECTOR(p_fs->map_clu); + + for (j = 0; j < p_fs->map_sectors; j++) { + p_fs->vol_amap[j] = NULL; + ret = sector_read(sb, sector+j, &(p_fs->vol_amap[j]), 1); + if (ret != FFS_SUCCESS) { + i=0; + while (i < j) + brelse(p_fs->vol_amap[i++]); + + FREE(p_fs->vol_amap); + p_fs->vol_amap = NULL; + return ret; + } + } + + p_fs->pbr_bh = NULL; + return FFS_SUCCESS; + } + } + + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return FFS_MEDIAERR; + } + + return FFS_FORMATERR; +} + +void free_alloc_bitmap(struct super_block *sb) +{ + INT32 i; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + brelse(p_fs->pbr_bh); + + for (i = 0; i < p_fs->map_sectors; i++) { + __brelse(p_fs->vol_amap[i]); + } + + FREE(p_fs->vol_amap); + p_fs->vol_amap = NULL; +} + +INT32 set_alloc_bitmap(struct super_block *sb, UINT32 clu) +{ + INT32 i, b; + UINT32 sector; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + i = clu >> (p_bd->sector_size_bits + 3); + b = clu & ((p_bd->sector_size << 3) - 1); + + sector = START_SECTOR(p_fs->map_clu) + i; + + Bitmap_set((UINT8 *) p_fs->vol_amap[i]->b_data, b); + + return (sector_write(sb, sector, p_fs->vol_amap[i], 0)); +} + +INT32 clr_alloc_bitmap(struct super_block *sb, UINT32 clu) +{ + INT32 i, b; + UINT32 sector; +#if EXFAT_CONFIG_DISCARD + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_mount_options *opts = &sbi->options; + int ret; +#endif + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + i = clu >> (p_bd->sector_size_bits + 3); + b = clu & ((p_bd->sector_size << 3) - 1); + + sector = START_SECTOR(p_fs->map_clu) + i; + + Bitmap_clear((UINT8 *) p_fs->vol_amap[i]->b_data, b); + + return (sector_write(sb, sector, p_fs->vol_amap[i], 0)); + +#if EXFAT_CONFIG_DISCARD + if (opts->discard) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + ret = sb_issue_discard(sb, START_SECTOR(clu), (1 << p_fs->sectors_per_clu_bits)); +#else + ret = sb_issue_discard(sb, START_SECTOR(clu), (1 << p_fs->sectors_per_clu_bits), GFP_NOFS, 0); +#endif + if (ret == -EOPNOTSUPP) { + printk(KERN_WARNING "discard not supported by device, disabling"); + opts->discard = 0; + } + } +#endif +} + +UINT32 test_alloc_bitmap(struct super_block *sb, UINT32 clu) +{ + INT32 i, map_i, map_b; + UINT32 clu_base, clu_free; + UINT8 k, clu_mask; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu_base = (clu & ~(0x7)) + 2; + clu_mask = (1 << (clu - clu_base + 2)) - 1; + + map_i = clu >> (p_bd->sector_size_bits + 3); + map_b = (clu >> 3) & p_bd->sector_size_mask; + + for (i = 2; i < p_fs->num_clusters; i += 8) { + k = *(((UINT8 *) p_fs->vol_amap[map_i]->b_data) + map_b); + if (clu_mask > 0) { + k |= clu_mask; + clu_mask = 0; + } + if (k < 0xFF) { + clu_free = clu_base + free_bit[k]; + if (clu_free < p_fs->num_clusters) + return(clu_free); + } + clu_base += 8; + + if (((++map_b) >= p_bd->sector_size) || (clu_base >= p_fs->num_clusters)) { + if ((++map_i) >= p_fs->map_sectors) { + clu_base = 2; + map_i = 0; + } + map_b = 0; + } + } + + return(CLUSTER_32(~0)); +} + +void sync_alloc_bitmap(struct super_block *sb) +{ + INT32 i; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_fs->vol_amap == NULL) + return; + + for (i = 0; i < p_fs->map_sectors; i++) { + sync_dirty_buffer(p_fs->vol_amap[i]); + } +} + +INT32 __load_upcase_table(struct super_block *sb, UINT32 sector, UINT32 num_sectors, UINT32 utbl_checksum) +{ + INT32 i, ret = FFS_ERROR; + UINT32 j; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + struct buffer_head *tmp_bh = NULL; + + UINT8 skip = FALSE; + UINT32 index = 0; + UINT16 uni = 0; + UINT16 **upcase_table; + + UINT32 checksum = 0; + + upcase_table = p_fs->vol_utbl = (UINT16 **) MALLOC(UTBL_COL_COUNT * sizeof(UINT16 *)); + if(upcase_table == NULL) + return FFS_MEMORYERR; + MEMSET(upcase_table, 0, UTBL_COL_COUNT * sizeof(UINT16 *)); + + num_sectors += sector; + + while(sector < num_sectors) { + ret = sector_read(sb, sector, &tmp_bh, 1); + if (ret != FFS_SUCCESS) { + PRINTK("sector read (0x%X)fail\n", sector); + goto error; + } + sector++; + + for(i = 0; i < p_bd->sector_size && index <= 0xFFFF; i += 2) { + uni = GET16(((UINT8 *) tmp_bh->b_data)+i); + + checksum = ((checksum & 1) ? 0x80000000 : 0 ) + (checksum >> 1) + *(((UINT8 *) tmp_bh->b_data)+i); + checksum = ((checksum & 1) ? 0x80000000 : 0 ) + (checksum >> 1) + *(((UINT8 *) tmp_bh->b_data)+(i+1)); + + if(skip) { + PRINTK("skip from 0x%X ", index); + index += uni; + PRINTK("to 0x%X (amount of 0x%X)\n", index, uni); + skip = FALSE; + } else if(uni == index) + index++; + else if(uni == 0xFFFF) + skip = TRUE; + else { + UINT16 col_index = get_col_index(index); + + if(upcase_table[col_index]== NULL) { + PRINTK("alloc = 0x%X\n", col_index); + upcase_table[col_index] = (UINT16 *) MALLOC(UTBL_ROW_COUNT * sizeof(UINT16)); + if(upcase_table[col_index] == NULL) { + ret = FFS_MEMORYERR; + goto error; + } + + for(j = 0 ; j < UTBL_ROW_COUNT ; j++) + upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; + } + + upcase_table[col_index][get_row_index(index)] = uni; + index++; + } + } + } + if(index >= 0xFFFF && utbl_checksum == checksum) { + if(tmp_bh) + brelse(tmp_bh); + return FFS_SUCCESS; + } + ret = FFS_ERROR; +error: + if(tmp_bh) + brelse(tmp_bh); + free_upcase_table(sb); + return ret; +} + +INT32 __load_default_upcase_table(struct super_block *sb) +{ + INT32 i, ret = FFS_ERROR; + UINT32 j; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + UINT8 skip = FALSE; + UINT32 index = 0; + UINT16 uni = 0; + UINT16 **upcase_table; + + upcase_table = p_fs->vol_utbl = (UINT16 **) MALLOC(UTBL_COL_COUNT * sizeof(UINT16 *)); + if(upcase_table == NULL) + return FFS_MEMORYERR; + MEMSET(upcase_table, 0, UTBL_COL_COUNT * sizeof(UINT16 *)); + + for(i = 0; index <= 0xFFFF && i < NUM_UPCASE*2; i += 2) { + uni = GET16(uni_upcase + i); + if(skip) { + PRINTK("skip from 0x%X ", index); + index += uni; + PRINTK("to 0x%X (amount of 0x%X)\n", index, uni); + skip = FALSE; + } else if(uni == index) + index++; + else if(uni == 0xFFFF) + skip = TRUE; + else { + UINT16 col_index = get_col_index(index); + + if(upcase_table[col_index]== NULL) { + PRINTK("alloc = 0x%X\n", col_index); + upcase_table[col_index] = (UINT16 *) MALLOC(UTBL_ROW_COUNT * sizeof(UINT16)); + if(upcase_table[col_index] == NULL) { + ret = FFS_MEMORYERR; + goto error; + } + + for(j = 0 ; j < UTBL_ROW_COUNT ; j++) + upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j; + } + + upcase_table[col_index][get_row_index(index)] = uni; + index ++; + } + } + + if(index >= 0xFFFF) + return FFS_SUCCESS; + +error: + free_upcase_table(sb); + return ret; +} + +INT32 load_upcase_table(struct super_block *sb) +{ + INT32 i; + UINT32 tbl_clu, tbl_size; + UINT32 type, sector, num_sectors; + CHAIN_T clu; + CASE_DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + clu.dir = p_fs->root_dir; + clu.flags = 0x01; + + if (p_fs->dev_ejected) + return FFS_MEDIAERR; + + while (clu.dir != CLUSTER_32(~0)) { + for (i = 0; i < p_fs->dentries_per_clu; i++) { + ep = (CASE_DENTRY_T *) get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((DENTRY_T *) ep); + + if (type == TYPE_UNUSED) + break; + if (type != TYPE_UPCASE) + continue; + + tbl_clu = GET32_A(ep->start_clu); + tbl_size = (UINT32) GET64_A(ep->size); + + sector = START_SECTOR(tbl_clu); + num_sectors = ((tbl_size-1) >> p_bd->sector_size_bits) + 1; + if(__load_upcase_table(sb, sector, num_sectors, GET32_A(ep->checksum)) != FFS_SUCCESS) + break; + else + return FFS_SUCCESS; + } + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return FFS_MEDIAERR; + } + return __load_default_upcase_table(sb); +} + +void free_upcase_table(struct super_block *sb) +{ + UINT32 i; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + UINT16 **upcase_table; + + upcase_table = p_fs->vol_utbl; + for(i = 0 ; i < UTBL_COL_COUNT ; i ++) + FREE(upcase_table[i]); + + FREE(p_fs->vol_utbl); + + p_fs->vol_utbl = NULL; +} + +UINT32 fat_get_entry_type(DENTRY_T *p_entry) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + + if (*(ep->name) == 0x0) + return TYPE_UNUSED; + + else if (*(ep->name) == 0xE5) + return TYPE_DELETED; + + else if (ep->attr == ATTR_EXTEND) + return TYPE_EXTEND; + + else if ((ep->attr & (ATTR_SUBDIR|ATTR_VOLUME)) == ATTR_VOLUME) + return TYPE_VOLUME; + + else if ((ep->attr & (ATTR_SUBDIR|ATTR_VOLUME)) == ATTR_SUBDIR) + return TYPE_DIR; + + return TYPE_FILE; +} + +UINT32 exfat_get_entry_type(DENTRY_T *p_entry) +{ + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + + if (ep->type == 0x0) { + return TYPE_UNUSED; + } else if (ep->type < 0x80) { + return TYPE_DELETED; + } else if (ep->type == 0x80) { + return TYPE_INVALID; + } else if (ep->type < 0xA0) { + if (ep->type == 0x81) { + return TYPE_BITMAP; + } else if (ep->type == 0x82) { + return TYPE_UPCASE; + } else if (ep->type == 0x83) { + return TYPE_VOLUME; + } else if (ep->type == 0x85) { + if (GET16_A(ep->attr) & ATTR_SUBDIR) + return TYPE_DIR; + else + return TYPE_FILE; + } + return TYPE_CRITICAL_PRI; + } else if (ep->type < 0xC0) { + if (ep->type == 0xA0) { + return TYPE_GUID; + } else if (ep->type == 0xA1) { + return TYPE_PADDING; + } else if (ep->type == 0xA2) { + return TYPE_ACLTAB; + } + return TYPE_BENIGN_PRI; + } else if (ep->type < 0xE0) { + if (ep->type == 0xC0) { + return TYPE_STREAM; + } else if (ep->type == 0xC1) { + return TYPE_EXTEND; + } else if (ep->type == 0xC2) { + return TYPE_ACL; + } + return TYPE_CRITICAL_SEC; + } + + return TYPE_BENIGN_SEC; +} + +void fat_set_entry_type(DENTRY_T *p_entry, UINT32 type) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + + if (type == TYPE_UNUSED) + *(ep->name) = 0x0; + + else if (type == TYPE_DELETED) + *(ep->name) = 0xE5; + + else if (type == TYPE_EXTEND) + ep->attr = ATTR_EXTEND; + + else if (type == TYPE_DIR) + ep->attr = ATTR_SUBDIR; + + else if (type == TYPE_FILE) + ep->attr = ATTR_ARCHIVE; + + else if (type == TYPE_SYMLINK) + ep->attr = ATTR_ARCHIVE | ATTR_SYMLINK; +} + +void exfat_set_entry_type(DENTRY_T *p_entry, UINT32 type) +{ + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + + if (type == TYPE_UNUSED) { + ep->type = 0x0; + } else if (type == TYPE_DELETED) { + ep->type &= ~0x80; + } else if (type == TYPE_STREAM) { + ep->type = 0xC0; + } else if (type == TYPE_EXTEND) { + ep->type = 0xC1; + } else if (type == TYPE_BITMAP) { + ep->type = 0x81; + } else if (type == TYPE_UPCASE) { + ep->type = 0x82; + } else if (type == TYPE_VOLUME) { + ep->type = 0x83; + } else if (type == TYPE_DIR) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_SUBDIR); + } else if (type == TYPE_FILE) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_ARCHIVE); + } else if (type == TYPE_SYMLINK) { + ep->type = 0x85; + SET16_A(ep->attr, ATTR_ARCHIVE | ATTR_SYMLINK); + } +} + +UINT32 fat_get_entry_attr(DENTRY_T *p_entry) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + return((UINT32) ep->attr); +} + +UINT32 exfat_get_entry_attr(DENTRY_T *p_entry) +{ + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + return((UINT32) GET16_A(ep->attr)); +} + +void fat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + ep->attr = (UINT8) attr; +} + +void exfat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr) +{ + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + SET16_A(ep->attr, (UINT16) attr); +} + +UINT8 fat_get_entry_flag(DENTRY_T *p_entry) +{ + return 0x01; +} + +UINT8 exfat_get_entry_flag(DENTRY_T *p_entry) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + return(ep->flags); +} + +void fat_set_entry_flag(DENTRY_T *p_entry, UINT8 flags) +{ +} + +void exfat_set_entry_flag(DENTRY_T *p_entry, UINT8 flags) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + ep->flags = flags; +} + +UINT32 fat_get_entry_clu0(DENTRY_T *p_entry) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + return((GET32_A(ep->start_clu_hi) << 16) | GET16_A(ep->start_clu_lo)); +} + +UINT32 exfat_get_entry_clu0(DENTRY_T *p_entry) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + return(GET32_A(ep->start_clu)); +} + +void fat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu)); + SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16)); +} + +void exfat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + SET32_A(ep->start_clu, start_clu); +} + +UINT64 fat_get_entry_size(DENTRY_T *p_entry) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + return((UINT64) GET32_A(ep->size)); +} + +UINT64 exfat_get_entry_size(DENTRY_T *p_entry) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + return(GET64_A(ep->valid_size)); +} + +void fat_set_entry_size(DENTRY_T *p_entry, UINT64 size) +{ + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + SET32_A(ep->size, (UINT32) size); +} + +void exfat_set_entry_size(DENTRY_T *p_entry, UINT64 size) +{ + STRM_DENTRY_T *ep = (STRM_DENTRY_T *) p_entry; + SET64_A(ep->valid_size, size); + SET64_A(ep->size, size); +} + +void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode) +{ + UINT16 t = 0x00, d = 0x21; + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + + switch (mode) { + case TM_CREATE: + t = GET16_A(ep->create_time); + d = GET16_A(ep->create_date); + break; + case TM_MODIFY: + t = GET16_A(ep->modify_time); + d = GET16_A(ep->modify_date); + break; + } + + tp->sec = (t & 0x001F) << 1; + tp->min = (t >> 5) & 0x003F; + tp->hour = (t >> 11); + tp->day = (d & 0x001F); + tp->mon = (d >> 5) & 0x000F; + tp->year = (d >> 9); +} + +void exfat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode) +{ + UINT16 t = 0x00, d = 0x21; + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + + switch (mode) { + case TM_CREATE: + t = GET16_A(ep->create_time); + d = GET16_A(ep->create_date); + break; + case TM_MODIFY: + t = GET16_A(ep->modify_time); + d = GET16_A(ep->modify_date); + break; + case TM_ACCESS: + t = GET16_A(ep->access_time); + d = GET16_A(ep->access_date); + break; + } + + tp->sec = (t & 0x001F) << 1; + tp->min = (t >> 5) & 0x003F; + tp->hour = (t >> 11); + tp->day = (d & 0x001F); + tp->mon = (d >> 5) & 0x000F; + tp->year = (d >> 9); +} + +void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode) +{ + UINT16 t, d; + DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry; + + t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1); + d = (tp->year << 9) | (tp->mon << 5) | tp->day; + + switch (mode) { + case TM_CREATE: + SET16_A(ep->create_time, t); + SET16_A(ep->create_date, d); + break; + case TM_MODIFY: + SET16_A(ep->modify_time, t); + SET16_A(ep->modify_date, d); + break; + } +} + +void exfat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode) +{ + UINT16 t, d; + FILE_DENTRY_T *ep = (FILE_DENTRY_T *) p_entry; + + t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1); + d = (tp->year << 9) | (tp->mon << 5) | tp->day; + + switch (mode) { + case TM_CREATE: + SET16_A(ep->create_time, t); + SET16_A(ep->create_date, d); + break; + case TM_MODIFY: + SET16_A(ep->modify_time, t); + SET16_A(ep->modify_date, d); + break; + case TM_ACCESS: + SET16_A(ep->access_time, t); + SET16_A(ep->access_date, d); + break; + } +} + +INT32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, + UINT32 start_clu, UINT64 size) +{ + UINT32 sector; + DOS_DENTRY_T *dos_ep; + UINT8 tz_utc = EXFAT_SB(sb)->options.tz_utc; + + dos_ep = (DOS_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, §or); + if (!dos_ep) + return FFS_MEDIAERR; + + init_dos_entry(dos_ep, type, start_clu, tz_utc); + buf_modify(sb, sector); + + return FFS_SUCCESS; +} + +INT32 exfat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, + UINT32 start_clu, UINT64 size) +{ + UINT32 sector; + UINT8 flags; + FILE_DENTRY_T *file_ep; + STRM_DENTRY_T *strm_ep; + UINT8 tz_utc = EXFAT_SB(sb)->options.tz_utc; + + flags = (type == TYPE_FILE) ? 0x01 : 0x03; + + file_ep = (FILE_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, §or); + if (!file_ep) + return FFS_MEDIAERR; + + strm_ep = (STRM_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry+1, §or); + if (!strm_ep) + return FFS_MEDIAERR; + + init_file_entry(file_ep, type, tz_utc); + buf_modify(sb, sector); + + init_strm_entry(strm_ep, flags, start_clu, size); + buf_modify(sb, sector); + + return FFS_SUCCESS; +} + +INT32 fat_init_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, + UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname) +{ + INT32 i; + UINT32 sector; + UINT8 chksum; + UINT16 *uniname = p_uniname->name; + DOS_DENTRY_T *dos_ep; + EXT_DENTRY_T *ext_ep; + + dos_ep = (DOS_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, §or); + if (!dos_ep) + return FFS_MEDIAERR; + + dos_ep->lcase = p_dosname->name_case; + MEMCPY(dos_ep->name, p_dosname->name, DOS_NAME_LENGTH); + buf_modify(sb, sector); + + if ((--num_entries) > 0) { + chksum = calc_checksum_1byte((void *) dos_ep->name, DOS_NAME_LENGTH, 0); + + for (i = 1; i < num_entries; i++) { + ext_ep = (EXT_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry-i, §or); + if (!ext_ep) + return FFS_MEDIAERR; + + init_ext_entry(ext_ep, i, chksum, uniname); + buf_modify(sb, sector); + uniname += 13; + } + + ext_ep = (EXT_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry-i, §or); + if (!ext_ep) + return FFS_MEDIAERR; + + init_ext_entry(ext_ep, i+0x40, chksum, uniname); + buf_modify(sb, sector); + } + + return FFS_SUCCESS; +} + +INT32 exfat_init_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, + UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname) +{ + INT32 i; + UINT32 sector; + UINT16 *uniname = p_uniname->name; + FILE_DENTRY_T *file_ep; + STRM_DENTRY_T *strm_ep; + NAME_DENTRY_T *name_ep; + + file_ep = (FILE_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, §or); + if (!file_ep) + return FFS_MEDIAERR; + + file_ep->num_ext = (UINT8)(num_entries - 1); + buf_modify(sb, sector); + + strm_ep = (STRM_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry+1, §or); + if (!strm_ep) + return FFS_MEDIAERR; + + strm_ep->name_len = p_uniname->name_len; + SET16_A(strm_ep->name_hash, p_uniname->name_hash); + buf_modify(sb, sector); + + for (i = 2; i < num_entries; i++) { + name_ep = (NAME_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry+i, §or); + if (!name_ep) + return FFS_MEDIAERR; + + init_name_entry(name_ep, uniname); + buf_modify(sb, sector); + uniname += 15; + } + + update_dir_checksum(sb, p_dir, entry); + + return FFS_SUCCESS; +} + +void init_dos_entry(DOS_DENTRY_T *ep, UINT32 type, UINT32 start_clu, UINT8 tz_utc) +{ + TIMESTAMP_T tm, *tp; + + fat_set_entry_type((DENTRY_T *) ep, type); + SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu)); + SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16)); + SET32_A(ep->size, 0); + + tp = tm_current(&tm, tz_utc); + fat_set_entry_time((DENTRY_T *) ep, tp, TM_CREATE); + fat_set_entry_time((DENTRY_T *) ep, tp, TM_MODIFY); + SET16_A(ep->access_date, 0); + ep->create_time_ms = 0; +} + +void init_ext_entry(EXT_DENTRY_T *ep, INT32 order, UINT8 chksum, UINT16 *uniname) +{ + INT32 i; + UINT8 end = FALSE; + + fat_set_entry_type((DENTRY_T *) ep, TYPE_EXTEND); + ep->order = (UINT8) order; + ep->sysid = 0; + ep->checksum = chksum; + SET16_A(ep->start_clu, 0); + + for (i = 0; i < 10; i += 2) { + if (!end) { + SET16(ep->unicode_0_4+i, *uniname); + if (*uniname == 0x0) + end = TRUE; + else + uniname++; + } else { + SET16(ep->unicode_0_4+i, 0xFFFF); + } + } + + for (i = 0; i < 12; i += 2) { + if (!end) { + SET16_A(ep->unicode_5_10+i, *uniname); + if (*uniname == 0x0) + end = TRUE; + else + uniname++; + } else { + SET16_A(ep->unicode_5_10+i, 0xFFFF); + } + } + + for (i = 0; i < 4; i += 2) { + if (!end) { + SET16_A(ep->unicode_11_12+i, *uniname); + if (*uniname == 0x0) + end = TRUE; + else + uniname++; + } else { + SET16_A(ep->unicode_11_12+i, 0xFFFF); + } + } +} + +void init_file_entry(FILE_DENTRY_T *ep, UINT32 type, UINT8 tz_utc) +{ + TIMESTAMP_T tm, *tp; + + exfat_set_entry_type((DENTRY_T *) ep, type); + + tp = tm_current(&tm, tz_utc); + exfat_set_entry_time((DENTRY_T *) ep, tp, TM_CREATE); + exfat_set_entry_time((DENTRY_T *) ep, tp, TM_MODIFY); + exfat_set_entry_time((DENTRY_T *) ep, tp, TM_ACCESS); + ep->create_time_ms = 0; + ep->modify_time_ms = 0; + ep->access_time_ms = 0; +} + +void init_strm_entry(STRM_DENTRY_T *ep, UINT8 flags, UINT32 start_clu, UINT64 size) +{ + exfat_set_entry_type((DENTRY_T *) ep, TYPE_STREAM); + ep->flags = flags; + SET32_A(ep->start_clu, start_clu); + SET64_A(ep->valid_size, size); + SET64_A(ep->size, size); +} + +void init_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname) +{ + INT32 i; + + exfat_set_entry_type((DENTRY_T *) ep, TYPE_EXTEND); + ep->flags = 0x0; + + for (i = 0; i < 30; i++, i++) { + SET16_A(ep->unicode_0_14+i, *uniname); + if (*uniname == 0x0) + break; + uniname++; + } +} + +void fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries) +{ + INT32 i; + UINT32 sector; + DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = num_entries-1; i >= order; i--) { + ep = get_entry_in_dir(sb, p_dir, entry-i, §or); + if (!ep) + return; + + p_fs->fs_func->set_entry_type(ep, TYPE_DELETED); + buf_modify(sb, sector); + } +} + +void exfat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries) +{ + INT32 i; + UINT32 sector; + DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = order; i < num_entries; i++) { + ep = get_entry_in_dir(sb, p_dir, entry+i, §or); + if (!ep) + return; + + p_fs->fs_func->set_entry_type(ep, TYPE_DELETED); + buf_modify(sb, sector); + } +} + +void update_dir_checksum(struct super_block *sb, CHAIN_T *p_dir, INT32 entry) +{ + INT32 i, num_entries; + UINT32 sector; + UINT16 chksum; + FILE_DENTRY_T *file_ep; + DENTRY_T *ep; + + file_ep = (FILE_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, §or); + if (!file_ep) + return; + + buf_lock(sb, sector); + + num_entries = (INT32) file_ep->num_ext + 1; + chksum = calc_checksum_2byte((void *) file_ep, DENTRY_SIZE, 0, CS_DIR_ENTRY); + + for (i = 1; i < num_entries; i++) { + ep = get_entry_in_dir(sb, p_dir, entry+i, NULL); + if (!ep) { + buf_unlock(sb, sector); + return; + } + + chksum = calc_checksum_2byte((void *) ep, DENTRY_SIZE, chksum, CS_DEFAULT); + } + + SET16_A(file_ep->checksum, chksum); + buf_modify(sb, sector); + buf_unlock(sb, sector); +} + +void update_dir_checksum_with_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es) +{ + DENTRY_T *ep; + UINT16 chksum = 0; + INT32 chksum_type = CS_DIR_ENTRY, i; + + ep = (DENTRY_T *)&(es->__buf); + for (i=0; i < es->num_entries; i++) { + PRINTK ("update_dir_checksum_with_entry_set ep %p\n", ep); + chksum = calc_checksum_2byte((void *) ep, DENTRY_SIZE, chksum, chksum_type); + ep++; + chksum_type = CS_DEFAULT; + } + + ep = (DENTRY_T *)&(es->__buf); + SET16_A(((FILE_DENTRY_T *)ep)->checksum, chksum); + write_whole_entry_set(sb, es); +} + +static INT32 _walk_fat_chain (struct super_block *sb, CHAIN_T *p_dir, INT32 byte_offset, UINT32 *clu) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + INT32 clu_offset; + UINT32 cur_clu; + + clu_offset = byte_offset >> p_fs->cluster_size_bits; + cur_clu = p_dir->dir; + + if (p_dir->flags == 0x03) { + cur_clu += clu_offset; + } else { + while (clu_offset > 0) { + if (FAT_read(sb, cur_clu, &cur_clu) == -1) + return FFS_MEDIAERR; + clu_offset--; + } + } + + if (clu) + *clu = cur_clu; + return FFS_SUCCESS; +} +INT32 find_location(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector, INT32 *offset) +{ + INT32 off, ret; + UINT32 clu=0; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + off = entry << DENTRY_SIZE_BITS; + + if (p_dir->dir == CLUSTER_32(0)) { + *offset = off & p_bd->sector_size_mask; + *sector = off >> p_bd->sector_size_bits; + *sector += p_fs->root_start_sector; + } else { + ret =_walk_fat_chain(sb, p_dir, off, &clu); + if (ret != FFS_SUCCESS) + return ret; + + off &= p_fs->cluster_size - 1; + + *offset = off & p_bd->sector_size_mask; + *sector = off >> p_bd->sector_size_bits; + *sector += START_SECTOR(clu); + } + return FFS_SUCCESS; +} + +DENTRY_T *get_entry_with_sector(struct super_block *sb, UINT32 sector, INT32 offset) +{ + UINT8 *buf; + + buf = buf_getblk(sb, sector); + + if (buf == NULL) + return NULL; + + return((DENTRY_T *)(buf + offset)); +} + +DENTRY_T *get_entry_in_dir(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector) +{ + INT32 off; + UINT32 sec; + UINT8 *buf; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_fs->dev_ejected) + return NULL; + + BUG_ON(p_dir->dir == DIR_DELETED); + + if (find_location(sb, p_dir, entry, &sec, &off) != FFS_SUCCESS) + return NULL; + + buf = buf_getblk(sb, sec); + + if (buf == NULL) + return NULL; + + if (sector != NULL) + *sector = sec; + return((DENTRY_T *)(buf + off)); +} + +#define ES_MODE_STARTED 0 +#define ES_MODE_GET_FILE_ENTRY 1 +#define ES_MODE_GET_STRM_ENTRY 2 +#define ES_MODE_GET_NAME_ENTRY 3 +#define ES_MODE_GET_CRITICAL_SEC_ENTRY 4 +ENTRY_SET_CACHE_T *get_entry_set_in_dir (struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, DENTRY_T **file_ep) +{ + INT32 off, ret, byte_offset; + UINT32 clu=0; + UINT32 sec, entry_type; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + ENTRY_SET_CACHE_T *es = NULL; + DENTRY_T *ep, *pos; + UINT8 *buf; + UINT8 num_entries; + INT32 mode = ES_MODE_STARTED; + + if (p_fs->dev_ejected) + return NULL; + + BUG_ON(p_dir->dir == DIR_DELETED); + + PRINTK("get_entry_set_in_dir entered\n"); + PRINTK("p_dir dir %u flags %x size %d\n", p_dir->dir, p_dir->flags, p_dir->size); + + byte_offset = entry << DENTRY_SIZE_BITS; + ret =_walk_fat_chain(sb, p_dir, byte_offset, &clu); + if (ret != FFS_SUCCESS) + return NULL; + + + byte_offset &= p_fs->cluster_size - 1; + + off = byte_offset & p_bd->sector_size_mask; + sec = byte_offset >> p_bd->sector_size_bits; + sec += START_SECTOR(clu); + + buf = buf_getblk(sb, sec); + if (buf == NULL) + goto err_out; + + + ep = (DENTRY_T *)(buf + off); + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type != TYPE_FILE) + && (entry_type != TYPE_DIR)) + goto err_out; + + if (type == ES_ALL_ENTRIES) + num_entries = ((FILE_DENTRY_T *)ep)->num_ext+1; + else + num_entries = type; + + PRINTK("trying to malloc %x bytes for %d entries\n", offsetof(ENTRY_SET_CACHE_T, __buf) + (num_entries) * sizeof(DENTRY_T), num_entries); + es = MALLOC(offsetof(ENTRY_SET_CACHE_T, __buf) + (num_entries) * sizeof(DENTRY_T)); + if (es == NULL) + goto err_out; + + es->num_entries = num_entries; + es->sector = sec; + es->offset = off; + es->alloc_flag = p_dir->flags; + + pos = (DENTRY_T *) &(es->__buf); + + while(num_entries) { + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) + goto err_out; + + switch(mode) { + case ES_MODE_STARTED: + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) + mode = ES_MODE_GET_FILE_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_FILE_ENTRY: + if (entry_type == TYPE_STREAM) + mode = ES_MODE_GET_STRM_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_STRM_ENTRY: + if (entry_type == TYPE_EXTEND) + mode = ES_MODE_GET_NAME_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_NAME_ENTRY: + if (entry_type == TYPE_EXTEND) + break; + else if (entry_type == TYPE_STREAM) + goto err_out; + else if (entry_type & TYPE_CRITICAL_SEC) + mode = ES_MODE_GET_CRITICAL_SEC_ENTRY; + else + goto err_out; + break; + case ES_MODE_GET_CRITICAL_SEC_ENTRY: + if ((entry_type == TYPE_EXTEND) || (entry_type == TYPE_STREAM)) + goto err_out; + else if ((entry_type & TYPE_CRITICAL_SEC) != TYPE_CRITICAL_SEC) + goto err_out; + break; + } + + COPY_DENTRY(pos, ep); + + if (--num_entries == 0) + break; + + if (((off + DENTRY_SIZE) & p_bd->sector_size_mask) < (off & p_bd->sector_size_mask)) { + if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { + if (es->alloc_flag == 0x03) { + clu++; + } else { + if (FAT_read(sb, clu, &clu) == -1) + goto err_out; + } + sec = START_SECTOR(clu); + } else { + sec++; + } + buf = buf_getblk(sb, sec); + if (buf == NULL) + goto err_out; + off = 0; + ep = (DENTRY_T *)(buf); + } else { + ep++; + off += DENTRY_SIZE; + } + pos++; + } + + if (file_ep) + *file_ep = (DENTRY_T *)&(es->__buf); + + PRINTK("es sec %u offset %d flags %d, num_entries %u buf ptr %p\n", + es->sector, es->offset, es->alloc_flag, es->num_entries, &(es->__buf)); + PRINTK("get_entry_set_in_dir exited %p\n", es); + return es; +err_out: + PRINTK("get_entry_set_in_dir exited NULL (es %p)\n", es); + if (es) + FREE(es); + return NULL; +} + +void release_entry_set (ENTRY_SET_CACHE_T *es) +{ + PRINTK("release_entry_set %p\n", es); + FREE(es); +} + + +static INT32 __write_partial_entries_in_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es, UINT32 sec, INT32 off, UINT32 count) +{ + INT32 num_entries, buf_off = (off - es->offset); + UINT32 remaining_byte_in_sector, copy_entries; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + UINT32 clu; + UINT8 *buf, *esbuf = (UINT8 *)&(es->__buf); + + PRINTK("__write_partial_entries_in_entry_set entered\n"); + PRINTK("es %p sec %u off %d count %d\n", es, sec, off, count); + num_entries = count; + + while(num_entries) { + remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off; + copy_entries = MIN(remaining_byte_in_sector>> DENTRY_SIZE_BITS , num_entries); + buf = buf_getblk(sb, sec); + if (buf == NULL) + goto err_out; + PRINTK("es->buf %p buf_off %u\n", esbuf, buf_off); + PRINTK("copying %d entries from %p to sector %u\n", copy_entries, (esbuf + buf_off), sec); + MEMCPY(buf + off, esbuf + buf_off, copy_entries << DENTRY_SIZE_BITS); + buf_modify(sb, sec); + num_entries -= copy_entries; + + if (num_entries) { + if (IS_LAST_SECTOR_IN_CLUSTER(sec)) { + clu = GET_CLUSTER_FROM_SECTOR(sec); + if (es->alloc_flag == 0x03) { + clu++; + } else { + if (FAT_read(sb, clu, &clu) == -1) + goto err_out; + } + sec = START_SECTOR(clu); + } else { + sec++; + } + off = 0; + buf_off += copy_entries << DENTRY_SIZE_BITS; + } + } + + PRINTK("__write_partial_entries_in_entry_set exited successfully\n"); + return FFS_SUCCESS; +err_out: + PRINTK("__write_partial_entries_in_entry_set failed\n"); + return FFS_ERROR; +} + +INT32 write_whole_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es) +{ + return (__write_partial_entries_in_entry_set(sb, es, es->sector,es->offset, es->num_entries)); +} + +INT32 write_partial_entries_in_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es, DENTRY_T *ep, UINT32 count) +{ + INT32 ret, byte_offset, off; + UINT32 clu=0, sec; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + CHAIN_T dir; + + if (ep + count > ((DENTRY_T *)&(es->__buf)) + es->num_entries) + return FFS_ERROR; + + dir.dir = GET_CLUSTER_FROM_SECTOR(es->sector); + dir.flags = es->alloc_flag; + dir.size = 0xffffffff; + + byte_offset = (es->sector - START_SECTOR(dir.dir)) << p_bd->sector_size_bits; + byte_offset += (INT32)((unsigned long)ep - (unsigned long)&(es->__buf)) + es->offset; + + ret =_walk_fat_chain(sb, &dir, byte_offset, &clu); + if (ret != FFS_SUCCESS) + return ret; + byte_offset &= p_fs->cluster_size - 1; + off = byte_offset & p_bd->sector_size_mask; + sec = byte_offset >> p_bd->sector_size_bits; + sec += START_SECTOR(clu); + return (__write_partial_entries_in_entry_set(sb, es, sec, off, count)); +} + +INT32 search_deleted_or_unused_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 num_entries) +{ + INT32 i, dentry, num_empty = 0; + INT32 dentries_per_clu; + UINT32 type; + CHAIN_T clu; + DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + if (p_fs->hint_uentry.dir == p_dir->dir) { + if (p_fs->hint_uentry.entry == -1) + return -1; + + clu.dir = p_fs->hint_uentry.clu.dir; + clu.size = p_fs->hint_uentry.clu.size; + clu.flags = p_fs->hint_uentry.clu.flags; + + dentry = p_fs->hint_uentry.entry; + } else { + p_fs->hint_uentry.entry = -1; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + dentry = 0; + } + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + if (p_dir->dir == CLUSTER_32(0)) + i = dentry % dentries_per_clu; + else + i = dentry & (dentries_per_clu-1); + + for ( ; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -1; + + type = p_fs->fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) { + num_empty++; + if (p_fs->hint_uentry.entry == -1) { + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = dentry; + + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = clu.size; + p_fs->hint_uentry.clu.flags = clu.flags; + } + } else if (type == TYPE_DELETED) { + num_empty++; + } else { + num_empty = 0; + } + + if (num_empty >= num_entries) { + p_fs->hint_uentry.dir = CLUSTER_32(~0); + p_fs->hint_uentry.entry = -1; + + if (p_fs->vol_type == EXFAT) + return(dentry - (num_entries-1)); + else + return(dentry); + } + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return -1; + } + } + + return -1; +} + +INT32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, INT32 num_entries) +{ + INT32 ret, dentry; + UINT32 last_clu, sector; + UINT64 size = 0; + CHAIN_T clu; + DENTRY_T *ep = NULL; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + + if (p_dir->dir == CLUSTER_32(0)) + return(search_deleted_or_unused_entry(sb, p_dir, num_entries)); + + while ((dentry = search_deleted_or_unused_entry(sb, p_dir, num_entries)) < 0) { + if (p_fs->dev_ejected) + break; + + if (p_fs->vol_type == EXFAT) { + if (p_dir->dir != p_fs->root_dir) { + size = i_size_read(inode); + } + } + + last_clu = find_last_cluster(sb, p_dir); + clu.dir = last_clu + 1; + clu.size = 0; + clu.flags = p_dir->flags; + + ret = p_fs->fs_func->alloc_cluster(sb, 1, &clu); + if (ret < 1) + return -1; + + if (clear_cluster(sb, clu.dir) != FFS_SUCCESS) + return -1; + + if (clu.flags != p_dir->flags) { + exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size); + p_dir->flags = 0x01; + p_fs->hint_uentry.clu.flags = 0x01; + } + if (clu.flags == 0x01) + if(FAT_write(sb, last_clu, clu.dir) < 0) + return -1; + + if (p_fs->hint_uentry.entry == -1) { + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = p_dir->size << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); + + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = 0; + p_fs->hint_uentry.clu.flags = clu.flags; + } + p_fs->hint_uentry.clu.size++; + p_dir->size++; + + if (p_fs->vol_type == EXFAT) { + if (p_dir->dir != p_fs->root_dir) { + size += p_fs->cluster_size; + + ep = get_entry_in_dir(sb, &(fid->dir), fid->entry+1, §or); + if (!ep) + return -1; + p_fs->fs_func->set_entry_size(ep, size); + p_fs->fs_func->set_entry_flag(ep, p_dir->flags); + buf_modify(sb, sector); + + update_dir_checksum(sb, &(fid->dir), fid->entry); + } + } + + i_size_write(inode, i_size_read(inode)+p_fs->cluster_size); + EXFAT_I(inode)->mmu_private += p_fs->cluster_size; + EXFAT_I(inode)->fid.size += p_fs->cluster_size; + EXFAT_I(inode)->fid.flags = p_dir->flags; + inode->i_blocks += 1 << (p_fs->cluster_size_bits - 9); + } + + return(dentry); +} + +INT32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type) +{ + INT32 i, dentry = 0, lossy = FALSE, len; + INT32 order = 0, is_feasible_entry = TRUE, has_ext_entry = FALSE; + INT32 dentries_per_clu; + UINT32 entry_type; + UINT16 entry_uniname[14], *uniname = NULL, unichar; + CHAIN_T clu; + DENTRY_T *ep; + DOS_DENTRY_T *dos_ep; + EXT_DENTRY_T *ext_ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == p_fs->root_dir) { + if ((!nls_uniname_cmp(sb, p_uniname->name, (UINT16 *) UNI_CUR_DIR_NAME)) || + (!nls_uniname_cmp(sb, p_uniname->name, (UINT16 *) UNI_PAR_DIR_NAME))) + return -1; + } + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -2; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) { + if ((type == TYPE_ALL) || (type == entry_type)) { + if (is_feasible_entry && has_ext_entry) + return(dentry); + + dos_ep = (DOS_DENTRY_T *) ep; + if ((!lossy) && (!nls_dosname_cmp(sb, p_dosname->name, dos_ep->name))) + return(dentry); + } + is_feasible_entry = TRUE; + has_ext_entry = FALSE; + } else if (entry_type == TYPE_EXTEND) { + if (is_feasible_entry) { + ext_ep = (EXT_DENTRY_T *) ep; + if (ext_ep->order > 0x40) { + order = (INT32)(ext_ep->order - 0x40); + uniname = p_uniname->name + 13 * (order-1); + } else { + order = (INT32) ext_ep->order; + uniname -= 13; + } + + len = extract_uni_name_from_ext_entry(ext_ep, entry_uniname, order); + + unichar = *(uniname+len); + *(uniname+len) = 0x0; + + if (nls_uniname_cmp(sb, uniname, entry_uniname)) { + is_feasible_entry = FALSE; + } + + *(uniname+len) = unichar; + } + has_ext_entry = TRUE; + } else if (entry_type == TYPE_UNUSED) { + return -2; + } else { + is_feasible_entry = TRUE; + has_ext_entry = FALSE; + } + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return -2; + } + + return -2; +} + +INT32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type) +{ + INT32 i, dentry = 0, num_ext_entries = 0, len; + INT32 order = 0, is_feasible_entry = FALSE; + INT32 dentries_per_clu, num_empty = 0; + UINT32 entry_type; + UINT16 entry_uniname[16], *uniname = NULL, unichar; + CHAIN_T clu; + DENTRY_T *ep; + FILE_DENTRY_T *file_ep; + STRM_DENTRY_T *strm_ep; + NAME_DENTRY_T *name_ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == p_fs->root_dir) { + if ((!nls_uniname_cmp(sb, p_uniname->name, (UINT16 *) UNI_CUR_DIR_NAME)) || + (!nls_uniname_cmp(sb, p_uniname->name, (UINT16 *) UNI_PAR_DIR_NAME))) + return -1; + } + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + p_fs->hint_uentry.dir = p_dir->dir; + p_fs->hint_uentry.entry = -1; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++, dentry++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -2; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) { + is_feasible_entry = FALSE; + + if (p_fs->hint_uentry.entry == -1) { + num_empty++; + + if (num_empty == 1) { + p_fs->hint_uentry.clu.dir = clu.dir; + p_fs->hint_uentry.clu.size = clu.size; + p_fs->hint_uentry.clu.flags = clu.flags; + } + if ((num_empty >= num_entries) || (entry_type == TYPE_UNUSED)) { + p_fs->hint_uentry.entry = dentry - (num_empty-1); + } + } + + if (entry_type == TYPE_UNUSED) { + return -2; + } + } else { + num_empty = 0; + + if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) { + if ((type == TYPE_ALL) || (type == entry_type)) { + file_ep = (FILE_DENTRY_T *) ep; + num_ext_entries = file_ep->num_ext; + is_feasible_entry = TRUE; + } else { + is_feasible_entry = FALSE; + } + } else if (entry_type == TYPE_STREAM) { + if (is_feasible_entry) { + strm_ep = (STRM_DENTRY_T *) ep; + if ((p_uniname->name_hash == GET16_A(strm_ep->name_hash)) && + (p_uniname->name_len == strm_ep->name_len)) { + order = 1; + } else { + is_feasible_entry = FALSE; + } + } + } else if (entry_type == TYPE_EXTEND) { + if (is_feasible_entry) { + name_ep = (NAME_DENTRY_T *) ep; + + if ((++order) == 2) + uniname = p_uniname->name; + else + uniname += 15; + + len = extract_uni_name_from_name_entry(name_ep, entry_uniname, order); + + unichar = *(uniname+len); + *(uniname+len) = 0x0; + + if (nls_uniname_cmp(sb, uniname, entry_uniname)) { + is_feasible_entry = FALSE; + } else if (order == num_ext_entries) { + p_fs->hint_uentry.dir = CLUSTER_32(~0); + p_fs->hint_uentry.entry = -1; + return(dentry - (num_ext_entries)); + } + + *(uniname+len) = unichar; + } + } else { + is_feasible_entry = FALSE; + } + } + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return -2; + } + } + + return -2; +} + +INT32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry) +{ + INT32 count = 0; + UINT8 chksum; + DOS_DENTRY_T *dos_ep = (DOS_DENTRY_T *) p_entry; + EXT_DENTRY_T *ext_ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + chksum = calc_checksum_1byte((void *) dos_ep->name, DOS_NAME_LENGTH, 0); + + for (entry--; entry >= 0; entry--) { + ext_ep = (EXT_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, NULL); + if (!ext_ep) + return -1; + + if ((p_fs->fs_func->get_entry_type((DENTRY_T *) ext_ep) == TYPE_EXTEND) && + (ext_ep->checksum == chksum)) { + count++; + if (ext_ep->order > 0x40) + return(count); + } else { + return(count); + } + } + + return(count); +} + +INT32 exfat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry) +{ + INT32 i, count = 0; + UINT32 type; + FILE_DENTRY_T *file_ep = (FILE_DENTRY_T *) p_entry; + DENTRY_T *ext_ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (i = 0, entry++; i < file_ep->num_ext; i++, entry++) { + ext_ep = get_entry_in_dir(sb, p_dir, entry, NULL); + if (!ext_ep) + return -1; + + type = p_fs->fs_func->get_entry_type(ext_ep); + if ((type == TYPE_EXTEND) || (type == TYPE_STREAM)) { + count++; + } else { + return(count); + } + } + + return(count); +} + +INT32 count_dos_name_entries(struct super_block *sb, CHAIN_T *p_dir, UINT32 type) +{ + INT32 i, count = 0; + INT32 dentries_per_clu; + UINT32 entry_type; + CHAIN_T clu; + DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return -1; + + entry_type = p_fs->fs_func->get_entry_type(ep); + + if (entry_type == TYPE_UNUSED) + return(count); + if (!(type & TYPE_CRITICAL_PRI) && !(type & TYPE_BENIGN_PRI)) + continue; + + if ((type == TYPE_ALL) || (type == entry_type)) + count++; + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return -1; + } + } + + return(count); +} + +BOOL is_dir_empty(struct super_block *sb, CHAIN_T *p_dir) +{ + INT32 i, count = 0; + INT32 dentries_per_clu; + UINT32 type; + CHAIN_T clu; + DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.size = p_dir->size; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + break; + + type = p_fs->fs_func->get_entry_type(ep); + + if (type == TYPE_UNUSED) + return TRUE; + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + if (p_dir->dir == CLUSTER_32(0)) { + return FALSE; + } else { + if (p_fs->vol_type == EXFAT) + return FALSE; + if ((p_dir->dir == p_fs->root_dir) || ((++count) > 2)) + return FALSE; + } + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (clu.flags == 0x03) { + if ((--clu.size) > 0) + clu.dir++; + else + clu.dir = CLUSTER_32(~0); + } else { + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + break; + } + } + + return TRUE; +} + +INT32 get_num_entries_and_dos_name(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 *entries, DOS_NAME_T *p_dosname) +{ + INT32 ret, num_entries, lossy = FALSE; + INT8 **r; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + num_entries = p_fs->fs_func->calc_num_entries(p_uniname); + if (num_entries == 0) + return FFS_INVALIDPATH; + + if (p_fs->vol_type != EXFAT) { + nls_uniname_to_dosname(sb, p_dosname, p_uniname, &lossy); + + if (lossy) { + ret = fat_generate_dos_name(sb, p_dir, p_dosname); + if (ret) + return ret; + } else { + for (r = reserved_names; *r; r++) { + if (!STRNCMP((void *) p_dosname->name, *r, 8)) + return FFS_INVALIDPATH; + } + + if (p_dosname->name_case != 0xFF) + num_entries = 1; + } + + if (num_entries > 1) + p_dosname->name_case = 0x0; + } + + *entries = num_entries; + + return FFS_SUCCESS; +} + +void get_uni_name_from_dos_entry(struct super_block *sb, DOS_DENTRY_T *ep, UNI_NAME_T *p_uniname, UINT8 mode) +{ + DOS_NAME_T dos_name; + + if (mode == 0x0) + dos_name.name_case = 0x0; + else + dos_name.name_case = ep->lcase; + + MEMCPY(dos_name.name, ep->name, DOS_NAME_LENGTH); + nls_dosname_to_uniname(sb, p_uniname, &dos_name); +} + +void fat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname) +{ + INT32 i; + EXT_DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + for (entry--, i = 1; entry >= 0; entry--, i++) { + ep = (EXT_DENTRY_T *) get_entry_in_dir(sb, p_dir, entry, NULL); + if (!ep) + return; + + if (p_fs->fs_func->get_entry_type((DENTRY_T *) ep) == TYPE_EXTEND) { + extract_uni_name_from_ext_entry(ep, uniname, i); + if (ep->order > 0x40) + return; + } else { + return; + } + + uniname += 13; + } +} + +void exfat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname) +{ + INT32 i; + DENTRY_T *ep; + ENTRY_SET_CACHE_T *es; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep); + if (es == NULL || es->num_entries < 3) { + if(es) { + release_entry_set(es); + } + return; + } + + ep += 2; + + for (i = 2; i < es->num_entries; i++, ep++) { + if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND) { + extract_uni_name_from_name_entry((NAME_DENTRY_T *)ep, uniname, i); + } else { + goto out; + } + uniname += 15; + } + +out: + release_entry_set(es); +} + +INT32 extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, UINT16 *uniname, INT32 order) +{ + INT32 i, len = 0; + + for (i = 0; i < 10; i += 2) { + *uniname = GET16(ep->unicode_0_4+i); + if (*uniname == 0x0) + return(len); + uniname++; + len++; + } + + if (order < 20) { + for (i = 0; i < 12; i += 2) { + *uniname = GET16_A(ep->unicode_5_10+i); + if (*uniname == 0x0) + return(len); + uniname++; + len++; + } + } else { + for (i = 0; i < 8; i += 2) { + *uniname = GET16_A(ep->unicode_5_10+i); + if (*uniname == 0x0) + return(len); + uniname++; + len++; + } + *uniname = 0x0; + return(len); + } + + for (i = 0; i < 4; i += 2) { + *uniname = GET16_A(ep->unicode_11_12+i); + if (*uniname == 0x0) + return(len); + uniname++; + len++; + } + + *uniname = 0x0; + return(len); + +} + +INT32 extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname, INT32 order) +{ + INT32 i, len = 0; + + for (i = 0; i < 30; i += 2) { + *uniname = GET16_A(ep->unicode_0_14+i); + if (*uniname == 0x0) + return(len); + uniname++; + len++; + } + + *uniname = 0x0; + return(len); + +} + +INT32 fat_generate_dos_name(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname) +{ + INT32 i, j, count = 0, count_begin = FALSE; + INT32 dentries_per_clu; + UINT32 type; + UINT8 bmap[128]; + CHAIN_T clu; + DOS_DENTRY_T *ep; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + Bitmap_clear_all(bmap, 128); + Bitmap_set(bmap, 0); + + if (p_dir->dir == CLUSTER_32(0)) + dentries_per_clu = p_fs->dentries_in_root; + else + dentries_per_clu = p_fs->dentries_per_clu; + + clu.dir = p_dir->dir; + clu.flags = p_dir->flags; + + while (clu.dir != CLUSTER_32(~0)) { + if (p_fs->dev_ejected) + break; + + for (i = 0; i < dentries_per_clu; i++) { + ep = (DOS_DENTRY_T *) get_entry_in_dir(sb, &clu, i, NULL); + if (!ep) + return FFS_MEDIAERR; + + type = p_fs->fs_func->get_entry_type((DENTRY_T *) ep); + + if (type == TYPE_UNUSED) + break; + if ((type != TYPE_FILE) && (type != TYPE_DIR)) + continue; + + count = 0; + count_begin = FALSE; + + for (j = 0; j < 8; j++) { + if (ep->name[j] == ' ') + break; + + if (ep->name[j] == '~') { + count_begin = TRUE; + } else if (count_begin) { + if ((ep->name[j] >= '0') && (ep->name[j] <= '9')) { + count = count * 10 + (ep->name[j] - '0'); + } else { + count = 0; + count_begin = FALSE; + } + } + } + + if ((count > 0) && (count < 1024)) + Bitmap_set(bmap, count); + } + + if (p_dir->dir == CLUSTER_32(0)) + break; + + if (FAT_read(sb, clu.dir, &(clu.dir)) != 0) + return FFS_MEDIAERR; + } + + count = 0; + for (i = 0; i < 128; i++) { + if (bmap[i] != 0xFF) { + for (j = 0; j < 8; j++) { + if (Bitmap_test(&(bmap[i]), j) == 0) { + count = (i << 3) + j; + break; + } + } + if (count != 0) + break; + } + } + + if ((count == 0) || (count >= 1024)) + return FFS_FILEEXIST; + else + fat_attach_count_to_dos_name(p_dosname->name, count); + + return FFS_SUCCESS; +} + +void fat_attach_count_to_dos_name(UINT8 *dosname, INT32 count) +{ + INT32 i, j, length; + INT8 str_count[6]; + + str_count[0] = '~'; + str_count[1] = '\0'; + my_itoa(&(str_count[1]), count); + length = STRLEN(str_count); + + i = j = 0; + while (j <= (8 - length)) { + i = j; + if (dosname[j] == ' ') + break; + if (dosname[j] & 0x80) + j += 2; + else + j++; + } + + for (j = 0; j < length; i++, j++) + dosname[i] = (UINT8) str_count[j]; + + if (i == 7) + dosname[7] = ' '; + +} + +INT32 fat_calc_num_entries(UNI_NAME_T *p_uniname) +{ + INT32 len; + + len = p_uniname->name_len; + if (len == 0) + return 0; + + return((len-1) / 13 + 2); + +} + +INT32 exfat_calc_num_entries(UNI_NAME_T *p_uniname) +{ + INT32 len; + + len = p_uniname->name_len; + if (len == 0) + return 0; + + return((len-1) / 15 + 3); + +} + +UINT8 calc_checksum_1byte(void *data, INT32 len, UINT8 chksum) +{ + INT32 i; + UINT8 *c = (UINT8 *) data; + + for (i = 0; i < len; i++, c++) + chksum = (((chksum & 1) << 7) | ((chksum & 0xFE) >> 1)) + *c; + + return(chksum); +} + +UINT16 calc_checksum_2byte(void *data, INT32 len, UINT16 chksum, INT32 type) +{ + INT32 i; + UINT8 *c = (UINT8 *) data; + + switch (type) { + case CS_DIR_ENTRY: + for (i = 0; i < len; i++, c++) { + if ((i == 2) || (i == 3)) + continue; + chksum = (((chksum & 1) << 15) | ((chksum & 0xFFFE) >> 1)) + (UINT16) *c; + } + break; + default + : + for (i = 0; i < len; i++, c++) { + chksum = (((chksum & 1) << 15) | ((chksum & 0xFFFE) >> 1)) + (UINT16) *c; + } + } + + return(chksum); +} + +UINT32 calc_checksum_4byte(void *data, INT32 len, UINT32 chksum, INT32 type) +{ + INT32 i; + UINT8 *c = (UINT8 *) data; + + switch (type) { + case CS_PBR_SECTOR: + for (i = 0; i < len; i++, c++) { + if ((i == 106) || (i == 107) || (i == 112)) + continue; + chksum = (((chksum & 1) << 31) | ((chksum & 0xFFFFFFFE) >> 1)) + (UINT32) *c; + } + break; + default + : + for (i = 0; i < len; i++, c++) { + chksum = (((chksum & 1) << 31) | ((chksum & 0xFFFFFFFE) >> 1)) + (UINT32) *c; + } + } + + return(chksum); +} + + +INT32 resolve_path(struct inode *inode, UINT8 *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname) +{ + INT32 lossy = FALSE; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + + if (STRLEN(path) >= (MAX_NAME_LENGTH * MAX_CHARSET_SIZE)) + return(FFS_INVALIDPATH); + + STRCPY(name_buf, path); + + nls_cstring_to_uniname(sb, p_uniname, name_buf, &lossy); + if (lossy) + return(FFS_INVALIDPATH); + + fid->size = i_size_read(inode); + + p_dir->dir = fid->start_clu; + p_dir->size = (INT32)(fid->size >> p_fs->cluster_size_bits); + p_dir->flags = fid->flags; + + return(FFS_SUCCESS); +} + + +static FS_FUNC_T fat_fs_func = { + .alloc_cluster = fat_alloc_cluster, + .free_cluster = fat_free_cluster, + .count_used_clusters = fat_count_used_clusters, + + .init_dir_entry = fat_init_dir_entry, + .init_ext_entry = fat_init_ext_entry, + .find_dir_entry = fat_find_dir_entry, + .delete_dir_entry = fat_delete_dir_entry, + .get_uni_name_from_ext_entry = fat_get_uni_name_from_ext_entry, + .count_ext_entries = fat_count_ext_entries, + .calc_num_entries = fat_calc_num_entries, + + .get_entry_type = fat_get_entry_type, + .set_entry_type = fat_set_entry_type, + .get_entry_attr = fat_get_entry_attr, + .set_entry_attr = fat_set_entry_attr, + .get_entry_flag = fat_get_entry_flag, + .set_entry_flag = fat_set_entry_flag, + .get_entry_clu0 = fat_get_entry_clu0, + .set_entry_clu0 = fat_set_entry_clu0, + .get_entry_size = fat_get_entry_size, + .set_entry_size = fat_set_entry_size, + .get_entry_time = fat_get_entry_time, + .set_entry_time = fat_set_entry_time, +}; + + +INT32 fat16_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr) +{ + INT32 num_reserved, num_root_sectors; + BPB16_T *p_bpb = (BPB16_T *) p_pbr->bpb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + num_root_sectors = GET16(p_bpb->num_root_entries) << DENTRY_SIZE_BITS; + num_root_sectors = ((num_root_sectors-1) >> p_bd->sector_size_bits) + 1; + + p_fs->sectors_per_clu = p_bpb->sectors_per_clu; + p_fs->sectors_per_clu_bits = my_log2(p_bpb->sectors_per_clu); + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET16(p_bpb->num_fat_sectors); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->FAT2_start_sector + p_fs->num_FAT_sectors; + p_fs->data_start_sector = p_fs->root_start_sector + num_root_sectors; + + p_fs->num_sectors = GET16(p_bpb->num_sectors); + if (p_fs->num_sectors == 0) + p_fs->num_sectors = GET32(p_bpb->num_huge_sectors); + + num_reserved = p_fs->data_start_sector - p_fs->PBR_sector; + p_fs->num_clusters = ((p_fs->num_sectors - num_reserved) >> p_fs->sectors_per_clu_bits) + 2; + + if (p_fs->num_clusters < FAT12_THRESHOLD) + p_fs->vol_type = FAT12; + else + p_fs->vol_type = FAT16; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = 0; + p_fs->dentries_in_root = GET16(p_bpb->num_root_entries); + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); + + p_fs->vol_flag = VOL_CLEAN; + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = (UINT32) ~0; + + p_fs->fs_func = &fat_fs_func; + + return FFS_SUCCESS; +} + +INT32 fat32_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr) +{ + INT32 num_reserved; + BPB32_T *p_bpb = (BPB32_T *) p_pbr->bpb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + p_fs->sectors_per_clu = p_bpb->sectors_per_clu; + p_fs->sectors_per_clu_bits = my_log2(p_bpb->sectors_per_clu); + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET32(p_bpb->num_fat32_sectors); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->FAT2_start_sector + p_fs->num_FAT_sectors; + p_fs->data_start_sector = p_fs->root_start_sector; + + p_fs->num_sectors = GET32(p_bpb->num_huge_sectors); + num_reserved = p_fs->data_start_sector - p_fs->PBR_sector; + + p_fs->num_clusters = ((p_fs->num_sectors-num_reserved) >> p_fs->sectors_per_clu_bits) + 2; + + p_fs->vol_type = FAT32; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = GET32(p_bpb->root_cluster); + p_fs->dentries_in_root = 0; + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); + + p_fs->vol_flag = VOL_CLEAN; + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = (UINT32) ~0; + + p_fs->fs_func = &fat_fs_func; + + return FFS_SUCCESS; +} + +static FS_FUNC_T exfat_fs_func = { + .alloc_cluster = exfat_alloc_cluster, + .free_cluster = exfat_free_cluster, + .count_used_clusters = exfat_count_used_clusters, + + .init_dir_entry = exfat_init_dir_entry, + .init_ext_entry = exfat_init_ext_entry, + .find_dir_entry = exfat_find_dir_entry, + .delete_dir_entry = exfat_delete_dir_entry, + .get_uni_name_from_ext_entry = exfat_get_uni_name_from_ext_entry, + .count_ext_entries = exfat_count_ext_entries, + .calc_num_entries = exfat_calc_num_entries, + + .get_entry_type = exfat_get_entry_type, + .set_entry_type = exfat_set_entry_type, + .get_entry_attr = exfat_get_entry_attr, + .set_entry_attr = exfat_set_entry_attr, + .get_entry_flag = exfat_get_entry_flag, + .set_entry_flag = exfat_set_entry_flag, + .get_entry_clu0 = exfat_get_entry_clu0, + .set_entry_clu0 = exfat_set_entry_clu0, + .get_entry_size = exfat_get_entry_size, + .set_entry_size = exfat_set_entry_size, + .get_entry_time = exfat_get_entry_time, + .set_entry_time = exfat_set_entry_time, +}; + +INT32 exfat_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr) +{ + BPBEX_T *p_bpb = (BPBEX_T *) p_pbr->bpb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bpb->num_fats == 0) + return FFS_FORMATERR; + + p_fs->sectors_per_clu = 1 << p_bpb->sectors_per_clu_bits; + p_fs->sectors_per_clu_bits = p_bpb->sectors_per_clu_bits; + p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits + p_bd->sector_size_bits; + p_fs->cluster_size = 1 << p_fs->cluster_size_bits; + + p_fs->num_FAT_sectors = GET32(p_bpb->fat_length); + + p_fs->FAT1_start_sector = p_fs->PBR_sector + GET32(p_bpb->fat_offset); + if (p_bpb->num_fats == 1) + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector; + else + p_fs->FAT2_start_sector = p_fs->FAT1_start_sector + p_fs->num_FAT_sectors; + + p_fs->root_start_sector = p_fs->PBR_sector + GET32(p_bpb->clu_offset); + p_fs->data_start_sector = p_fs->root_start_sector; + + p_fs->num_sectors = GET64(p_bpb->vol_length); + p_fs->num_clusters = GET32(p_bpb->clu_count) + 2; + + p_fs->vol_type = EXFAT; + p_fs->vol_id = GET32(p_bpb->vol_serial); + + p_fs->root_dir = GET32(p_bpb->root_cluster); + p_fs->dentries_in_root = 0; + p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS); + + p_fs->vol_flag = (UINT32) GET16(p_bpb->vol_flags); + p_fs->clu_srch_ptr = 2; + p_fs->used_clusters = (UINT32) ~0; + + p_fs->fs_func = &exfat_fs_func; + + return FFS_SUCCESS; +} + +INT32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid) +{ + INT32 ret, dentry, num_entries; + UINT64 size; + CHAIN_T clu; + DOS_NAME_T dos_name, dot_name; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries, &dos_name); + if (ret) + return ret; + + dentry = find_empty_entry(inode, p_dir, num_entries); + if (dentry < 0) + return FFS_FULL; + + clu.dir = CLUSTER_32(~0); + clu.size = 0; + clu.flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + + ret = p_fs->fs_func->alloc_cluster(sb, 1, &clu); + if (ret < 0) + return FFS_MEDIAERR; + else if(ret == 0) + return FFS_FULL; + + ret = clear_cluster(sb, clu.dir); + if (ret != FFS_SUCCESS) + return ret; + + if (p_fs->vol_type == EXFAT) { + size = p_fs->cluster_size; + } else { + size = 0; + + dot_name.name_case = 0x0; + MEMCPY(dot_name.name, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH); + + ret = p_fs->fs_func->init_dir_entry(sb, &clu, 0, TYPE_DIR, clu.dir, 0); + if (ret != FFS_SUCCESS) + return ret; + + ret = p_fs->fs_func->init_ext_entry(sb, &clu, 0, 1, NULL, &dot_name); + if (ret != FFS_SUCCESS) + return ret; + + MEMCPY(dot_name.name, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH); + + if (p_dir->dir == p_fs->root_dir) + ret = p_fs->fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR, CLUSTER_32(0), 0); + else + ret = p_fs->fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR, p_dir->dir, 0); + + if (ret != FFS_SUCCESS) + return ret; + + ret = p_fs->fs_func->init_ext_entry(sb, &clu, 1, 1, NULL, &dot_name); + if (ret != FFS_SUCCESS) + return ret; + } + + ret = p_fs->fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir, size); + if (ret != FFS_SUCCESS) + return ret; + + ret = p_fs->fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fid->dir.dir = p_dir->dir; + fid->dir.size = p_dir->size; + fid->dir.flags = p_dir->flags; + fid->entry = dentry; + + fid->attr = ATTR_SUBDIR; + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->size = size; + fid->start_clu = clu.dir; + + fid->type= TYPE_DIR; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + return FFS_SUCCESS; +} + +INT32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, UINT8 mode, FILE_ID_T *fid) +{ + INT32 ret, dentry, num_entries; + DOS_NAME_T dos_name; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries, &dos_name); + if (ret) + return ret; + + dentry = find_empty_entry(inode, p_dir, num_entries); + if (dentry < 0) + return FFS_FULL; + + ret = p_fs->fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_FILE | mode, CLUSTER_32(0), 0); + if (ret != FFS_SUCCESS) + return ret; + + ret = p_fs->fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + fid->dir.dir = p_dir->dir; + fid->dir.size = p_dir->size; + fid->dir.flags = p_dir->flags; + fid->entry = dentry; + + fid->attr = ATTR_ARCHIVE | mode; + fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01; + fid->size = 0; + fid->start_clu = CLUSTER_32(~0); + + fid->type= TYPE_FILE; + fid->rwoffset = 0; + fid->hint_last_off = -1; + + return FFS_SUCCESS; +} + +void remove_file(struct inode *inode, CHAIN_T *p_dir, INT32 entry) +{ + INT32 num_entries; + UINT32 sector; + DENTRY_T *ep; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + ep = get_entry_in_dir(sb, p_dir, entry, §or); + if (!ep) + return; + + buf_lock(sb, sector); + + num_entries = p_fs->fs_func->count_ext_entries(sb, p_dir, entry, ep); + if (num_entries < 0) { + buf_unlock(sb, sector); + return; + } + num_entries++; + + buf_unlock(sb, sector); + + p_fs->fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries); +} + +INT32 rename_file(struct inode *inode, CHAIN_T *p_dir, INT32 oldentry, UNI_NAME_T *p_uniname, FILE_ID_T *fid) +{ + INT32 ret, newentry = -1, num_old_entries, num_new_entries; + UINT32 sector_old, sector_new; + DOS_NAME_T dos_name; + DENTRY_T *epold, *epnew; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + epold = get_entry_in_dir(sb, p_dir, oldentry, §or_old); + if (!epold) + return FFS_MEDIAERR; + + buf_lock(sb, sector_old); + + num_old_entries = p_fs->fs_func->count_ext_entries(sb, p_dir, oldentry, epold); + if (num_old_entries < 0) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + num_old_entries++; + + ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_new_entries, &dos_name); + if (ret) { + buf_unlock(sb, sector_old); + return ret; + } + + if (num_old_entries < num_new_entries) { + newentry = find_empty_entry(inode, p_dir, num_new_entries); + if (newentry < 0) { + buf_unlock(sb, sector_old); + return FFS_FULL; + } + + epnew = get_entry_in_dir(sb, p_dir, newentry, §or_new); + if (!epnew) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + + MEMCPY((void *) epnew, (void *) epold, DENTRY_SIZE); + if (p_fs->fs_func->get_entry_type(epnew) == TYPE_FILE) { + p_fs->fs_func->set_entry_attr(epnew, p_fs->fs_func->get_entry_attr(epnew) | ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_new); + buf_unlock(sb, sector_old); + + if (p_fs->vol_type == EXFAT) { + epold = get_entry_in_dir(sb, p_dir, oldentry+1, §or_old); + buf_lock(sb, sector_old); + epnew = get_entry_in_dir(sb, p_dir, newentry+1, §or_new); + + if (!epold || !epnew) { + buf_unlock(sb, sector_old); + return FFS_MEDIAERR; + } + + MEMCPY((void *) epnew, (void *) epold, DENTRY_SIZE); + buf_modify(sb, sector_new); + buf_unlock(sb, sector_old); + } + + ret = p_fs->fs_func->init_ext_entry(sb, p_dir, newentry, num_new_entries, p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + p_fs->fs_func->delete_dir_entry(sb, p_dir, oldentry, 0, num_old_entries); + fid->entry = newentry; + } else { + if (p_fs->fs_func->get_entry_type(epold) == TYPE_FILE) { + p_fs->fs_func->set_entry_attr(epold, p_fs->fs_func->get_entry_attr(epold) | ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_old); + buf_unlock(sb, sector_old); + + ret = p_fs->fs_func->init_ext_entry(sb, p_dir, oldentry, num_new_entries, p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + p_fs->fs_func->delete_dir_entry(sb, p_dir, oldentry, num_new_entries, num_old_entries); + } + + return FFS_SUCCESS; +} + +INT32 move_file(struct inode *inode, CHAIN_T *p_olddir, INT32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid) +{ + INT32 ret, newentry, num_new_entries, num_old_entries; + UINT32 sector_mov, sector_new; + CHAIN_T clu; + DOS_NAME_T dos_name; + DENTRY_T *epmov, *epnew; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + epmov = get_entry_in_dir(sb, p_olddir, oldentry, §or_mov); + if (!epmov) + return FFS_MEDIAERR; + + if (p_fs->fs_func->get_entry_type(epmov) == TYPE_DIR && + p_fs->fs_func->get_entry_clu0(epmov) == p_newdir->dir) + return FFS_INVALIDPATH; + + buf_lock(sb, sector_mov); + + num_old_entries = p_fs->fs_func->count_ext_entries(sb, p_olddir, oldentry, epmov); + if (num_old_entries < 0) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + num_old_entries++; + + ret = get_num_entries_and_dos_name(sb, p_newdir, p_uniname, &num_new_entries, &dos_name); + if (ret) { + buf_unlock(sb, sector_mov); + return ret; + } + + newentry = find_empty_entry(inode, p_newdir, num_new_entries); + if (newentry < 0) { + buf_unlock(sb, sector_mov); + return FFS_FULL; + } + + epnew = get_entry_in_dir(sb, p_newdir, newentry, §or_new); + if (!epnew) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + + MEMCPY((void *) epnew, (void *) epmov, DENTRY_SIZE); + if (p_fs->fs_func->get_entry_type(epnew) == TYPE_FILE) { + p_fs->fs_func->set_entry_attr(epnew, p_fs->fs_func->get_entry_attr(epnew) | ATTR_ARCHIVE); + fid->attr |= ATTR_ARCHIVE; + } + buf_modify(sb, sector_new); + buf_unlock(sb, sector_mov); + + if (p_fs->vol_type == EXFAT) { + epmov = get_entry_in_dir(sb, p_olddir, oldentry+1, §or_mov); + buf_lock(sb, sector_mov); + epnew = get_entry_in_dir(sb, p_newdir, newentry+1, §or_new); + if (!epmov || !epnew) { + buf_unlock(sb, sector_mov); + return FFS_MEDIAERR; + } + + MEMCPY((void *) epnew, (void *) epmov, DENTRY_SIZE); + buf_modify(sb, sector_new); + buf_unlock(sb, sector_mov); + } else if (p_fs->fs_func->get_entry_type(epnew) == TYPE_DIR) { + clu.dir = p_fs->fs_func->get_entry_clu0(epnew); + clu.flags = 0x01; + + epnew = get_entry_in_dir(sb, &clu, 1, §or_new); + if (!epnew) + return FFS_MEDIAERR; + + if (p_newdir->dir == p_fs->root_dir) + p_fs->fs_func->set_entry_clu0(epnew, CLUSTER_32(0)); + else + p_fs->fs_func->set_entry_clu0(epnew, p_newdir->dir); + buf_modify(sb, sector_new); + } + + ret = p_fs->fs_func->init_ext_entry(sb, p_newdir, newentry, num_new_entries, p_uniname, &dos_name); + if (ret != FFS_SUCCESS) + return ret; + + p_fs->fs_func->delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries); + + fid->dir.dir = p_newdir->dir; + fid->dir.size = p_newdir->size; + fid->dir.flags = p_newdir->flags; + + fid->entry = newentry; + + return FFS_SUCCESS; +} + +INT32 sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 read) +{ + INT32 ret = FFS_MEDIAERR; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((sec >= (p_fs->PBR_sector+p_fs->num_sectors)) && (p_fs->num_sectors > 0)) { + PRINT("[EXFAT] sector_read: out of range error! (sec = %d)\n", sec); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_read(sb, sec, bh, 1, read); + if (ret != FFS_SUCCESS) { + fs_error(sb); + p_fs->dev_ejected = TRUE; + } + } + + return ret; +} + +INT32 sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 sync) +{ + INT32 ret = FFS_MEDIAERR; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (sec >= (p_fs->PBR_sector+p_fs->num_sectors) && (p_fs->num_sectors > 0)) { + PRINT("[EXFAT] sector_write: out of range error! (sec = %d)\n", sec); + fs_error(sb); + return ret; + } + + if (bh == NULL) { + PRINT("[EXFAT] sector_write: bh is NULL!\n"); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_write(sb, sec, bh, 1, sync); + if (ret != FFS_SUCCESS) { + fs_error(sb); + p_fs->dev_ejected = TRUE; + } + } + + return ret; +} + +INT32 multi_sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 num_secs, INT32 read) +{ + INT32 ret = FFS_MEDIAERR; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (((sec+num_secs) > (p_fs->PBR_sector+p_fs->num_sectors)) && (p_fs->num_sectors > 0)) { + PRINT("[EXFAT] multi_sector_read: out of range error! (sec = %d, num_secs = %d)\n", sec, num_secs); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_read(sb, sec, bh, num_secs, read); + if (ret != FFS_SUCCESS) { + fs_error(sb); + p_fs->dev_ejected = TRUE; + } + } + + return ret; +} + +INT32 multi_sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 num_secs, INT32 sync) +{ + INT32 ret = FFS_MEDIAERR; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((sec+num_secs) > (p_fs->PBR_sector+p_fs->num_sectors) && (p_fs->num_sectors > 0)) { + PRINT("[EXFAT] multi_sector_write: out of range error! (sec = %d, num_secs = %d)\n", sec, num_secs); + fs_error(sb); + return ret; + } + if (bh == NULL) { + PRINT("[EXFAT] multi_sector_write: bh is NULL!\n"); + fs_error(sb); + return ret; + } + + if (!p_fs->dev_ejected) { + ret = bdev_write(sb, sec, bh, num_secs, sync); + if (ret != FFS_SUCCESS) { + fs_error(sb); + p_fs->dev_ejected = TRUE; + } + } + + return ret; +} diff --git a/fs/exfat/exfat.h b/fs/exfat/exfat.h new file mode 100755 index 0000000000000..392ab5dffc94e --- /dev/null +++ b/fs/exfat/exfat.h @@ -0,0 +1,601 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_H +#define _EXFAT_H + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_blkdev.h" +#include "exfat_cache.h" +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat_cache.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if EXFAT_CONFIG_KERNEL_DEBUG +#define EXFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) +#define EXFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) + +#define EXFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 +#define EXFAT_DEBUGFLAGS_ERROR_RW 0x02 +#endif + +#define MAX_VOLUME 4 + +#define DENTRY_SIZE 32 +#define DENTRY_SIZE_BITS 5 + +#define PBR_SIGNATURE 0xAA55 +#define EXT_SIGNATURE 0xAA550000 +#define VOL_LABEL "NO NAME " +#define OEM_NAME "MSWIN4.1" +#define STR_FAT12 "FAT12 " +#define STR_FAT16 "FAT16 " +#define STR_FAT32 "FAT32 " +#define STR_EXFAT "EXFAT " +#define VOL_CLEAN 0x0000 +#define VOL_DIRTY 0x0002 + +#define FAT12_THRESHOLD 4087 +#define FAT16_THRESHOLD 65527 +#define FAT32_THRESHOLD 268435457 +#define EXFAT_THRESHOLD 268435457 + +#define TYPE_UNUSED 0x0000 +#define TYPE_DELETED 0x0001 +#define TYPE_INVALID 0x0002 +#define TYPE_CRITICAL_PRI 0x0100 +#define TYPE_BITMAP 0x0101 +#define TYPE_UPCASE 0x0102 +#define TYPE_VOLUME 0x0103 +#define TYPE_DIR 0x0104 +#define TYPE_FILE 0x011F +#define TYPE_SYMLINK 0x015F +#define TYPE_CRITICAL_SEC 0x0200 +#define TYPE_STREAM 0x0201 +#define TYPE_EXTEND 0x0202 +#define TYPE_ACL 0x0203 +#define TYPE_BENIGN_PRI 0x0400 +#define TYPE_GUID 0x0401 +#define TYPE_PADDING 0x0402 +#define TYPE_ACLTAB 0x0403 +#define TYPE_BENIGN_SEC 0x0800 +#define TYPE_ALL 0x0FFF + +#define TM_CREATE 0 +#define TM_MODIFY 1 +#define TM_ACCESS 2 + +#define CS_DIR_ENTRY 0 +#define CS_PBR_SECTOR 1 +#define CS_DEFAULT 2 + +#define DIR_DELETED 0xFFFF0321 + +#define CLUSTER_16(x) ((UINT16)(x)) +#define CLUSTER_32(x) ((UINT32)(x)) + +#define START_SECTOR(x) \ + ( (((x)-2) << p_fs->sectors_per_clu_bits) + p_fs->data_start_sector ) + +#define IS_LAST_SECTOR_IN_CLUSTER(sec) \ + ( (((sec) - p_fs->data_start_sector + 1) & ((1 << p_fs->sectors_per_clu_bits) -1)) == 0) + +#define GET_CLUSTER_FROM_SECTOR(sec) \ + ((((sec) - p_fs->data_start_sector) >> p_fs->sectors_per_clu_bits) +2) + +#define GET16(p_src) \ + ( ((UINT16)(p_src)[0]) | (((UINT16)(p_src)[1]) << 8) ) +#define GET32(p_src) \ + ( ((UINT32)(p_src)[0]) | (((UINT32)(p_src)[1]) << 8) | \ + (((UINT32)(p_src)[2]) << 16) | (((UINT32)(p_src)[3]) << 24) ) +#define GET64(p_src) \ + ( ((UINT64)(p_src)[0]) | (((UINT64)(p_src)[1]) << 8) | \ + (((UINT64)(p_src)[2]) << 16) | (((UINT64)(p_src)[3]) << 24) | \ + (((UINT64)(p_src)[4]) << 32) | (((UINT64)(p_src)[5]) << 40) | \ + (((UINT64)(p_src)[6]) << 48) | (((UINT64)(p_src)[7]) << 56) ) + + +#define SET16(p_dst,src) \ + do { \ + (p_dst)[0]=(UINT8)(src); \ + (p_dst)[1]=(UINT8)(((UINT16)(src)) >> 8); \ + } while (0) +#define SET32(p_dst,src) \ + do { \ + (p_dst)[0]=(UINT8)(src); \ + (p_dst)[1]=(UINT8)(((UINT32)(src)) >> 8); \ + (p_dst)[2]=(UINT8)(((UINT32)(src)) >> 16); \ + (p_dst)[3]=(UINT8)(((UINT32)(src)) >> 24); \ + } while (0) +#define SET64(p_dst,src) \ + do { \ + (p_dst)[0]=(UINT8)(src); \ + (p_dst)[1]=(UINT8)(((UINT64)(src)) >> 8); \ + (p_dst)[2]=(UINT8)(((UINT64)(src)) >> 16); \ + (p_dst)[3]=(UINT8)(((UINT64)(src)) >> 24); \ + (p_dst)[4]=(UINT8)(((UINT64)(src)) >> 32); \ + (p_dst)[5]=(UINT8)(((UINT64)(src)) >> 40); \ + (p_dst)[6]=(UINT8)(((UINT64)(src)) >> 48); \ + (p_dst)[7]=(UINT8)(((UINT64)(src)) >> 56); \ + } while (0) + +#if (FFS_CONFIG_LITTLE_ENDIAN == 1) +#define GET16_A(p_src) (*((UINT16 *)(p_src))) +#define GET32_A(p_src) (*((UINT32 *)(p_src))) +#define GET64_A(p_src) (*((UINT64 *)(p_src))) +#define SET16_A(p_dst,src) *((UINT16 *)(p_dst)) = (UINT16)(src) +#define SET32_A(p_dst,src) *((UINT32 *)(p_dst)) = (UINT32)(src) +#define SET64_A(p_dst,src) *((UINT64 *)(p_dst)) = (UINT64)(src) +#else +#define GET16_A(p_src) GET16(p_src) +#define GET32_A(p_src) GET32(p_src) +#define GET64_A(p_src) GET64(p_src) +#define SET16_A(p_dst,src) SET16(p_dst, src) +#define SET32_A(p_dst,src) SET32(p_dst, src) +#define SET64_A(p_dst,src) SET64(p_dst, src) +#endif + +#define HIGH_INDEX_BIT (8) +#define HIGH_INDEX_MASK (0xFF00) +#define LOW_INDEX_BIT (16-HIGH_INDEX_BIT) +#define UTBL_ROW_COUNT (1<> LOW_INDEX_BIT; + } + static inline UINT16 get_row_index(UINT16 i) + { + return i & ~HIGH_INDEX_MASK; + } + + typedef struct { + UINT8 jmp_boot[3]; + UINT8 oem_name[8]; + UINT8 bpb[109]; + UINT8 boot_code[390]; + UINT8 signature[2]; + } PBR_SECTOR_T; + + typedef struct { + UINT8 sector_size[2]; + UINT8 sectors_per_clu; + UINT8 num_reserved[2]; + UINT8 num_fats; + UINT8 num_root_entries[2]; + UINT8 num_sectors[2]; + UINT8 media_type; + UINT8 num_fat_sectors[2]; + UINT8 sectors_in_track[2]; + UINT8 num_heads[2]; + UINT8 num_hid_sectors[4]; + UINT8 num_huge_sectors[4]; + + UINT8 phy_drv_no; + UINT8 reserved; + UINT8 ext_signature; + UINT8 vol_serial[4]; + UINT8 vol_label[11]; + UINT8 vol_type[8]; + } BPB16_T; + + typedef struct { + UINT8 sector_size[2]; + UINT8 sectors_per_clu; + UINT8 num_reserved[2]; + UINT8 num_fats; + UINT8 num_root_entries[2]; + UINT8 num_sectors[2]; + UINT8 media_type; + UINT8 num_fat_sectors[2]; + UINT8 sectors_in_track[2]; + UINT8 num_heads[2]; + UINT8 num_hid_sectors[4]; + UINT8 num_huge_sectors[4]; + UINT8 num_fat32_sectors[4]; + UINT8 ext_flags[2]; + UINT8 fs_version[2]; + UINT8 root_cluster[4]; + UINT8 fsinfo_sector[2]; + UINT8 backup_sector[2]; + UINT8 reserved[12]; + + UINT8 phy_drv_no; + UINT8 ext_reserved; + UINT8 ext_signature; + UINT8 vol_serial[4]; + UINT8 vol_label[11]; + UINT8 vol_type[8]; + } BPB32_T; + + typedef struct { + UINT8 reserved1[53]; + UINT8 vol_offset[8]; + UINT8 vol_length[8]; + UINT8 fat_offset[4]; + UINT8 fat_length[4]; + UINT8 clu_offset[4]; + UINT8 clu_count[4]; + UINT8 root_cluster[4]; + UINT8 vol_serial[4]; + UINT8 fs_version[2]; + UINT8 vol_flags[2]; + UINT8 sector_size_bits; + UINT8 sectors_per_clu_bits; + UINT8 num_fats; + UINT8 phy_drv_no; + UINT8 perc_in_use; + UINT8 reserved2[7]; + } BPBEX_T; + + typedef struct { + UINT8 signature1[4]; + UINT8 reserved1[480]; + UINT8 signature2[4]; + UINT8 free_cluster[4]; + UINT8 next_cluster[4]; + UINT8 reserved2[14]; + UINT8 signature3[2]; + } FSI_SECTOR_T; + + typedef struct { + UINT8 dummy[32]; + } DENTRY_T; + + typedef struct { + UINT8 name[DOS_NAME_LENGTH]; + UINT8 attr; + UINT8 lcase; + UINT8 create_time_ms; + UINT8 create_time[2]; + UINT8 create_date[2]; + UINT8 access_date[2]; + UINT8 start_clu_hi[2]; + UINT8 modify_time[2]; + UINT8 modify_date[2]; + UINT8 start_clu_lo[2]; + UINT8 size[4]; + } DOS_DENTRY_T; + + typedef struct { + UINT8 order; + UINT8 unicode_0_4[10]; + UINT8 attr; + UINT8 sysid; + UINT8 checksum; + UINT8 unicode_5_10[12]; + UINT8 start_clu[2]; + UINT8 unicode_11_12[4]; + } EXT_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 num_ext; + UINT8 checksum[2]; + UINT8 attr[2]; + UINT8 reserved1[2]; + UINT8 create_time[2]; + UINT8 create_date[2]; + UINT8 modify_time[2]; + UINT8 modify_date[2]; + UINT8 access_time[2]; + UINT8 access_date[2]; + UINT8 create_time_ms; + UINT8 modify_time_ms; + UINT8 access_time_ms; + UINT8 reserved2[9]; + } FILE_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 flags; + UINT8 reserved1; + UINT8 name_len; + UINT8 name_hash[2]; + UINT8 reserved2[2]; + UINT8 valid_size[8]; + UINT8 reserved3[4]; + UINT8 start_clu[4]; + UINT8 size[8]; + } STRM_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 flags; + UINT8 unicode_0_14[30]; + } NAME_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 flags; + UINT8 reserved[18]; + UINT8 start_clu[4]; + UINT8 size[8]; + } BMAP_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 reserved1[3]; + UINT8 checksum[4]; + UINT8 reserved2[12]; + UINT8 start_clu[4]; + UINT8 size[8]; + } CASE_DENTRY_T; + + typedef struct { + UINT8 type; + UINT8 label_len; + UINT8 unicode_0_10[22]; + UINT8 reserved[8]; + } VOLM_DENTRY_T; + + typedef struct { + UINT32 dir; + INT32 entry; + CHAIN_T clu; + } UENTRY_T; + + typedef struct __FS_STRUCT_T { + UINT32 mounted; + struct super_block *sb; + struct semaphore v_sem; + } FS_STRUCT_T; + + typedef struct { + INT32 (*alloc_cluster)(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); + void (*free_cluster)(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); + INT32 (*count_used_clusters)(struct super_block *sb); + + INT32 (*init_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, + UINT32 start_clu, UINT64 size); + INT32 (*init_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, + UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); + INT32 (*find_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); + void (*delete_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 offset, INT32 num_entries); + void (*get_uni_name_from_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); + INT32 (*count_ext_entries)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); + INT32 (*calc_num_entries)(UNI_NAME_T *p_uniname); + + UINT32 (*get_entry_type)(DENTRY_T *p_entry); + void (*set_entry_type)(DENTRY_T *p_entry, UINT32 type); + UINT32 (*get_entry_attr)(DENTRY_T *p_entry); + void (*set_entry_attr)(DENTRY_T *p_entry, UINT32 attr); + UINT8 (*get_entry_flag)(DENTRY_T *p_entry); + void (*set_entry_flag)(DENTRY_T *p_entry, UINT8 flag); + UINT32 (*get_entry_clu0)(DENTRY_T *p_entry); + void (*set_entry_clu0)(DENTRY_T *p_entry, UINT32 clu0); + UINT64 (*get_entry_size)(DENTRY_T *p_entry); + void (*set_entry_size)(DENTRY_T *p_entry, UINT64 size); + void (*get_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + void (*set_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + } FS_FUNC_T; + + typedef struct __FS_INFO_T { + UINT32 drv; + UINT32 vol_type; + UINT32 vol_id; + + UINT32 num_sectors; + UINT32 num_clusters; + UINT32 cluster_size; + UINT32 cluster_size_bits; + UINT32 sectors_per_clu; + UINT32 sectors_per_clu_bits; + + UINT32 PBR_sector; + UINT32 FAT1_start_sector; + UINT32 FAT2_start_sector; + UINT32 root_start_sector; + UINT32 data_start_sector; + UINT32 num_FAT_sectors; + + UINT32 root_dir; + UINT32 dentries_in_root; + UINT32 dentries_per_clu; + + UINT32 vol_flag; + struct buffer_head *pbr_bh; + + UINT32 map_clu; + UINT32 map_sectors; + struct buffer_head **vol_amap; + + UINT16 **vol_utbl; + + UINT32 clu_srch_ptr; + UINT32 used_clusters; + UENTRY_T hint_uentry; + + UINT32 dev_ejected; + + FS_FUNC_T *fs_func; + + BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE]; + BUF_CACHE_T FAT_cache_lru_list; + BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; + + BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE]; + BUF_CACHE_T buf_cache_lru_list; + BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; + } FS_INFO_T; + +#define ES_2_ENTRIES 2 +#define ES_3_ENTRIES 3 +#define ES_ALL_ENTRIES 0 + + typedef struct { + UINT32 sector; + INT32 offset; + INT32 alloc_flag; + UINT32 num_entries; + + void *__buf; + } ENTRY_SET_CACHE_T; + + INT32 ffsInit(void); + INT32 ffsShutdown(void); + + INT32 ffsMountVol(struct super_block *sb, INT32 drv); + INT32 ffsUmountVol(struct super_block *sb); + INT32 ffsCheckVol(struct super_block *sb); + INT32 ffsGetVolInfo(struct super_block *sb, VOL_INFO_T *info); + INT32 ffsSyncVol(struct super_block *sb, INT32 do_sync); + + INT32 ffsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid); + INT32 ffsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid); + INT32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount); + INT32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount); + INT32 ffsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size); + INT32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry); + INT32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid); + INT32 ffsSetAttr(struct inode *inode, UINT32 attr); + INT32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info); + INT32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info); + INT32 ffsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu); + + INT32 ffsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid); + INT32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_ent); + INT32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid); + INT32 ffsRemoveEntry(struct inode *inode, FILE_ID_T *fid); + + INT32 fs_init(void); + INT32 fs_shutdown(void); + void fs_set_vol_flags(struct super_block *sb, UINT32 new_flag); + void fs_sync(struct super_block *sb, INT32 do_sync); + void fs_error(struct super_block *sb); + + INT32 clear_cluster(struct super_block *sb, UINT32 clu); + INT32 fat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); + INT32 exfat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); + void fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); + void exfat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); + UINT32 find_last_cluster(struct super_block *sb, CHAIN_T *p_chain); + INT32 count_num_clusters(struct super_block *sb, CHAIN_T *dir); + INT32 fat_count_used_clusters(struct super_block *sb); + INT32 exfat_count_used_clusters(struct super_block *sb); + void exfat_chain_cont_cluster(struct super_block *sb, UINT32 chain, INT32 len); + + INT32 load_alloc_bitmap(struct super_block *sb); + void free_alloc_bitmap(struct super_block *sb); + INT32 set_alloc_bitmap(struct super_block *sb, UINT32 clu); + INT32 clr_alloc_bitmap(struct super_block *sb, UINT32 clu); + UINT32 test_alloc_bitmap(struct super_block *sb, UINT32 clu); + void sync_alloc_bitmap(struct super_block *sb); + + INT32 load_upcase_table(struct super_block *sb); + void free_upcase_table(struct super_block *sb); + + UINT32 fat_get_entry_type(DENTRY_T *p_entry); + UINT32 exfat_get_entry_type(DENTRY_T *p_entry); + void fat_set_entry_type(DENTRY_T *p_entry, UINT32 type); + void exfat_set_entry_type(DENTRY_T *p_entry, UINT32 type); + UINT32 fat_get_entry_attr(DENTRY_T *p_entry); + UINT32 exfat_get_entry_attr(DENTRY_T *p_entry); + void fat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr); + void exfat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr); + UINT8 fat_get_entry_flag(DENTRY_T *p_entry); + UINT8 exfat_get_entry_flag(DENTRY_T *p_entry); + void fat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag); + void exfat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag); + UINT32 fat_get_entry_clu0(DENTRY_T *p_entry); + UINT32 exfat_get_entry_clu0(DENTRY_T *p_entry); + void fat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu); + void exfat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu); + UINT64 fat_get_entry_size(DENTRY_T *p_entry); + UINT64 exfat_get_entry_size(DENTRY_T *p_entry); + void fat_set_entry_size(DENTRY_T *p_entry, UINT64 size); + void exfat_set_entry_size(DENTRY_T *p_entry, UINT64 size); + void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + void exfat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + void exfat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); + INT32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size); + INT32 exfat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size); + INT32 fat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); + INT32 exfat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); + void init_dos_entry(DOS_DENTRY_T *ep, UINT32 type, UINT32 start_clu, UINT8 tz_utc); + void init_ext_entry(EXT_DENTRY_T *ep, INT32 order, UINT8 chksum, UINT16 *uniname); + void init_file_entry(FILE_DENTRY_T *ep, UINT32 type, UINT8 tz_utc); + void init_strm_entry(STRM_DENTRY_T *ep, UINT8 flags, UINT32 start_clu, UINT64 size); + void init_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname); + void fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries); + void exfat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries); + + INT32 find_location(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector, INT32 *offset); + DENTRY_T *get_entry_with_sector(struct super_block *sb, UINT32 sector, INT32 offset); + DENTRY_T *get_entry_in_dir(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector); + ENTRY_SET_CACHE_T *get_entry_set_in_dir (struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, DENTRY_T **file_ep); + void release_entry_set (ENTRY_SET_CACHE_T *es); + INT32 write_whole_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es); + INT32 write_partial_entries_in_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es, DENTRY_T *ep, UINT32 count); + INT32 search_deleted_or_unused_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 num_entries); + INT32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, INT32 num_entries); + INT32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); + INT32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); + INT32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); + INT32 exfat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); + INT32 count_dos_name_entries(struct super_block *sb, CHAIN_T *p_dir, UINT32 type); + void update_dir_checksum(struct super_block *sb, CHAIN_T *p_dir, INT32 entry); + void update_dir_checksum_with_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es); + BOOL is_dir_empty(struct super_block *sb, CHAIN_T *p_dir); + + INT32 get_num_entries_and_dos_name(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 *entries, DOS_NAME_T *p_dosname); + void get_uni_name_from_dos_entry(struct super_block *sb, DOS_DENTRY_T *ep, UNI_NAME_T *p_uniname, UINT8 mode); + void fat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); + void exfat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); + INT32 extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, UINT16 *uniname, INT32 order); + INT32 extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname, INT32 order); + INT32 fat_generate_dos_name(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname); + void fat_attach_count_to_dos_name(UINT8 *dosname, INT32 count); + INT32 fat_calc_num_entries(UNI_NAME_T *p_uniname); + INT32 exfat_calc_num_entries(UNI_NAME_T *p_uniname); + UINT8 calc_checksum_1byte(void *data, INT32 len, UINT8 chksum); + UINT16 calc_checksum_2byte(void *data, INT32 len, UINT16 chksum, INT32 type); + UINT32 calc_checksum_4byte(void *data, INT32 len, UINT32 chksum, INT32 type); + + INT32 resolve_path(struct inode *inode, UINT8 *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname); + INT32 resolve_name(UINT8 *name, UINT8 **arg); + + INT32 fat16_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); + INT32 fat32_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); + INT32 exfat_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); + INT32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid); + INT32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, UINT8 mode, FILE_ID_T *fid); + void remove_file(struct inode *inode, CHAIN_T *p_dir, INT32 entry); + INT32 rename_file(struct inode *inode, CHAIN_T *p_dir, INT32 old_entry, UNI_NAME_T *p_uniname, FILE_ID_T *fid); + INT32 move_file(struct inode *inode, CHAIN_T *p_olddir, INT32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid); + + INT32 sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 read); + INT32 sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 sync); + INT32 multi_sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 num_secs, INT32 read); + INT32 multi_sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 num_secs, INT32 sync); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fs/exfat/exfat_api.c b/fs/exfat/exfat_api.c new file mode 100755 index 0000000000000..02bb3caa9509c --- /dev/null +++ b/fs/exfat/exfat_api.c @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include "exfat_version.h" +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_part.h" +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat_super.h" +#include "exfat.h" + +extern FS_STRUCT_T fs_struct[]; + +extern struct semaphore z_sem; + +INT32 FsInit(void) +{ + INT32 i; + + for (i = 0; i < MAX_DRIVE; i++) { + fs_struct[i].mounted = FALSE; + fs_struct[i].sb = NULL; + sm_init(&(fs_struct[i].v_sem)); + } + + return(ffsInit()); +} + +INT32 FsShutdown(void) +{ + INT32 i; + + for (i = 0; i < MAX_DRIVE; i++) { + if (!fs_struct[i].mounted) continue; + + ffsUmountVol(fs_struct[i].sb); + } + + return(ffsShutdown()); +} + +INT32 FsMountVol(struct super_block *sb) +{ + INT32 err, drv; + + sm_P(&z_sem); + + for (drv = 0; drv < MAX_DRIVE; drv++) { + if (!fs_struct[drv].mounted) break; + } + + if (drv >= MAX_DRIVE) return(FFS_ERROR); + + sm_P(&(fs_struct[drv].v_sem)); + + err = buf_init(sb); + if (!err) { + err = ffsMountVol(sb, drv); + } + + sm_V(&(fs_struct[drv].v_sem)); + + if (!err) { + fs_struct[drv].mounted = TRUE; + fs_struct[drv].sb = sb; + } else { + buf_shutdown(sb); + } + + sm_V(&z_sem); + + return(err); +} + +INT32 FsUmountVol(struct super_block *sb) +{ + INT32 err; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&z_sem); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsUmountVol(sb); + buf_shutdown(sb); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + fs_struct[p_fs->drv].mounted = FALSE; + fs_struct[p_fs->drv].sb = NULL; + + sm_V(&z_sem); + + return(err); +} + +INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info) +{ + INT32 err; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (info == NULL) return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsGetVolInfo(sb, info); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsSyncVol(struct super_block *sb, INT32 do_sync) +{ + INT32 err; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsSyncVol(sb, do_sync); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) + return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsLookupFile(inode, path, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) + return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsCreateFile(inode, path, mode, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + if (buffer == NULL) return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsReadFile(inode, fid, buffer, count, rcount); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + if (buffer == NULL) return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsWriteFile(inode, fid, buffer, count, wcount); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size); + + err = ffsTruncateFile(inode, old_size, new_size); + + PRINTK("FsTruncateFile exitted (%d)\n", err); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry) +{ + INT32 err; + struct super_block *sb = old_parent_inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsRemoveFile(inode, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsSetAttr(struct inode *inode, UINT32 attr) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsSetAttr(inode, attr); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsGetStat(inode, info); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info); + + err = ffsSetStat(inode, info); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + PRINTK("FsWriteStat exited (%d)\n", err); + + return(err); +} + +INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (clu == NULL) return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsMapCluster(inode, clu_offset, clu); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) + return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsCreateDir(inode, path, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (dir_entry == NULL) return(FFS_ERROR); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsReadDir(inode, dir_entry); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsRemoveDir(inode, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + +INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid) +{ + INT32 err; + struct super_block *sb = inode->i_sb; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (fid == NULL) return(FFS_INVALIDFID); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + err = ffsRemoveEntry(inode, fid); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return(err); +} + + + +EXPORT_SYMBOL(FsMountVol); +EXPORT_SYMBOL(FsUmountVol); +EXPORT_SYMBOL(FsGetVolInfo); +EXPORT_SYMBOL(FsSyncVol); +EXPORT_SYMBOL(FsLookupFile); +EXPORT_SYMBOL(FsCreateFile); +EXPORT_SYMBOL(FsReadFile); +EXPORT_SYMBOL(FsWriteFile); +EXPORT_SYMBOL(FsTruncateFile); +EXPORT_SYMBOL(FsMoveFile); +EXPORT_SYMBOL(FsRemoveFile); +EXPORT_SYMBOL(FsSetAttr); +EXPORT_SYMBOL(FsReadStat); +EXPORT_SYMBOL(FsWriteStat); +EXPORT_SYMBOL(FsMapCluster); +EXPORT_SYMBOL(FsCreateDir); +EXPORT_SYMBOL(FsReadDir); +EXPORT_SYMBOL(FsRemoveDir); +EXPORT_SYMBOL(FsRemoveEntry); + +#if EXFAT_CONFIG_KERNEL_DEBUG +INT32 FsReleaseCache(struct super_block *sb) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&(fs_struct[p_fs->drv].v_sem)); + + FAT_release_all(sb); + buf_release_all(sb); + + sm_V(&(fs_struct[p_fs->drv].v_sem)); + + return 0; +} + +EXPORT_SYMBOL(FsReleaseCache); +#endif + +static int __init init_exfat_core(void) +{ + int err; + + printk(KERN_INFO "exFAT: Core Version %s\n", EXFAT_VERSION); + + err = FsInit(); + if (err) { + if (err == FFS_MEMORYERR) + return -ENOMEM; + else + return -EIO; + } + + return 0; +} + +static void __exit exit_exfat_core(void) +{ + FsShutdown(); +} + +module_init(init_exfat_core); +module_exit(exit_exfat_core); + +MODULE_LICENSE("GPL"); diff --git a/fs/exfat/exfat_api.h b/fs/exfat/exfat_api.h new file mode 100755 index 0000000000000..c0752fc242161 --- /dev/null +++ b/fs/exfat/exfat_api.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_API_H +#define _EXFAT_API_H + +#include "exfat_config.h" +#include "exfat_global.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXFAT_SUPER_MAGIC (0x2011BAB0L) +#define EXFAT_ROOT_INO 1 + +#define FAT12 0x01 +#define FAT16 0x0E +#define FAT32 0x0C +#define EXFAT 0x07 + +#define MAX_CHARSET_SIZE 3 +#define MAX_PATH_DEPTH 15 +#define MAX_NAME_LENGTH 256 +#define MAX_PATH_LENGTH 260 +#define DOS_NAME_LENGTH 11 +#define DOS_PATH_LENGTH 80 + +#define ATTR_NORMAL 0x0000 +#define ATTR_READONLY 0x0001 +#define ATTR_HIDDEN 0x0002 +#define ATTR_SYSTEM 0x0004 +#define ATTR_VOLUME 0x0008 +#define ATTR_SUBDIR 0x0010 +#define ATTR_ARCHIVE 0x0020 +#define ATTR_SYMLINK 0x0040 +#define ATTR_EXTEND 0x000F +#define ATTR_RWMASK 0x007E + +#define FM_REGULAR 0x00 +#define FM_SYMLINK 0x40 + +#define FFS_SUCCESS 0 +#define FFS_MEDIAERR 1 +#define FFS_FORMATERR 2 +#define FFS_MOUNTED 3 +#define FFS_NOTMOUNTED 4 +#define FFS_ALIGNMENTERR 5 +#define FFS_SEMAPHOREERR 6 +#define FFS_INVALIDPATH 7 +#define FFS_INVALIDFID 8 +#define FFS_NOTFOUND 9 +#define FFS_FILEEXIST 10 +#define FFS_PERMISSIONERR 11 +#define FFS_NOTOPENED 12 +#define FFS_MAXOPENED 13 +#define FFS_FULL 14 +#define FFS_EOF 15 +#define FFS_DIRBUSY 16 +#define FFS_MEMORYERR 17 +#define FFS_NAMETOOLONG 18 +#define FFS_ERROR 19 + + typedef struct { + UINT16 Year; + UINT16 Month; + UINT16 Day; + UINT16 Hour; + UINT16 Minute; + UINT16 Second; + UINT16 MilliSecond; + } DATE_TIME_T; + + typedef struct { + UINT32 Offset; + UINT32 Size; + } PART_INFO_T; + + typedef struct { + UINT32 SecSize; + UINT32 DevSize; + } DEV_INFO_T; + + typedef struct { + UINT32 FatType; + UINT32 ClusterSize; + UINT32 NumClusters; + UINT32 FreeClusters; + UINT32 UsedClusters; + } VOL_INFO_T; + + typedef struct { + UINT32 dir; + INT32 size; + UINT8 flags; + } CHAIN_T; + + typedef struct { + CHAIN_T dir; + INT32 entry; + UINT32 type; + UINT32 attr; + UINT32 start_clu; + UINT64 size; + UINT8 flags; + INT64 rwoffset; + INT32 hint_last_off; + UINT32 hint_last_clu; + } FILE_ID_T; + + typedef struct { + INT8 Name[MAX_NAME_LENGTH *MAX_CHARSET_SIZE]; + INT8 ShortName[DOS_NAME_LENGTH + 2]; + UINT32 Attr; + UINT64 Size; + UINT32 NumSubdirs; + DATE_TIME_T CreateTimestamp; + DATE_TIME_T ModifyTimestamp; + DATE_TIME_T AccessTimestamp; + } DIR_ENTRY_T; + + INT32 FsInit(void); + INT32 FsShutdown(void); + + INT32 FsMountVol(struct super_block *sb); + INT32 FsUmountVol(struct super_block *sb); + INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info); + INT32 FsSyncVol(struct super_block *sb, INT32 do_sync); + + INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid); + INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid); + INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount); + INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount); + INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size); + INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry); + INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid); + INT32 FsSetAttr(struct inode *inode, UINT32 attr); + INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info); + INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info); + INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu); + + INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid); + INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry); + INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid); + INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid); + + INT32 FsReleaseCache(struct super_block *sb); +#ifdef __cplusplus +} +#endif +#endif diff --git a/fs/exfat/exfat_blkdev.c b/fs/exfat/exfat_blkdev.c new file mode 100755 index 0000000000000..51f71093c50fd --- /dev/null +++ b/fs/exfat/exfat_blkdev.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_blkdev.h" +#include "exfat_data.h" +#include "exfat_api.h" +#include "exfat_super.h" + +INT32 bdev_init(void) +{ + return(FFS_SUCCESS); +} + +INT32 bdev_shutdown(void) +{ + return(FFS_SUCCESS); +} + +INT32 bdev_open(struct super_block *sb) +{ + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_bd->opened) return(FFS_SUCCESS); + + p_bd->sector_size = bdev_logical_block_size(sb->s_bdev); + p_bd->sector_size_bits = my_log2(p_bd->sector_size); + p_bd->sector_size_mask = p_bd->sector_size - 1; + p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> p_bd->sector_size_bits; + + p_bd->opened = TRUE; + + return(FFS_SUCCESS); +} + +INT32 bdev_close(struct super_block *sb) +{ + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (!p_bd->opened) return(FFS_SUCCESS); + + p_bd->opened = FALSE; + return(FFS_SUCCESS); +} + +INT32 bdev_read(struct super_block *sb, UINT32 secno, struct buffer_head **bh, UINT32 num_secs, INT32 read) +{ + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); +#if EXFAT_CONFIG_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); +#endif + + if (!p_bd->opened) return(FFS_MEDIAERR); + + if (*bh) __brelse(*bh); + + if (read) + *bh = __bread(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits); + else + *bh = __getblk(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits); + + if (*bh) return(FFS_SUCCESS); + + WARN(!p_fs->dev_ejected, + "[EXFAT] No bh, device seems wrong or to be ejected.\n"); + + return(FFS_MEDIAERR); +} + +INT32 bdev_write(struct super_block *sb, UINT32 secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync) +{ + INT32 count; + struct buffer_head *bh2; + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); +#if EXFAT_CONFIG_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); +#endif + + if (!p_bd->opened) return(FFS_MEDIAERR); + + if (secno == bh->b_blocknr) { + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + if (sync && (sync_dirty_buffer(bh) != 0)) + return (FFS_MEDIAERR); + } else { + count = num_secs << p_bd->sector_size_bits; + + bh2 = __getblk(sb->s_bdev, secno, count); + + if (bh2 == NULL) + goto no_bh; + + lock_buffer(bh2); + MEMCPY(bh2->b_data, bh->b_data, count); + set_buffer_uptodate(bh2); + mark_buffer_dirty(bh2); + unlock_buffer(bh2); + if (sync && (sync_dirty_buffer(bh2) != 0)) { + __brelse(bh2); + goto no_bh; + } + __brelse(bh2); + } + + return(FFS_SUCCESS); + +no_bh: + WARN(!p_fs->dev_ejected, + "[EXFAT] No bh, device seems wrong or to be ejected.\n"); + + return (FFS_MEDIAERR); +} + +INT32 bdev_sync(struct super_block *sb) +{ + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); +#if EXFAT_CONFIG_KERNEL_DEBUG + struct exfat_sb_info *sbi = EXFAT_SB(sb); + long flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); +#endif + + if (!p_bd->opened) return(FFS_MEDIAERR); + + return sync_blockdev(sb->s_bdev); +} diff --git a/fs/exfat/exfat_blkdev.h b/fs/exfat/exfat_blkdev.h new file mode 100755 index 0000000000000..302996683a08b --- /dev/null +++ b/fs/exfat/exfat_blkdev.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_BLKDEV_H +#define _EXFAT_BLKDEV_H + +#include "exfat_config.h" +#include "exfat_global.h" + +#ifdef __cplusplus +extern "C" { +#endif + typedef struct __BD_INFO_T { + INT32 sector_size; + INT32 sector_size_bits; + INT32 sector_size_mask; + INT32 num_sectors; + BOOL opened; + } BD_INFO_T; + + INT32 bdev_init(void); + INT32 bdev_shutdown(void); + INT32 bdev_open(struct super_block *sb); + INT32 bdev_close(struct super_block *sb); + INT32 bdev_read(struct super_block *sb, UINT32 secno, struct buffer_head **bh, UINT32 num_secs, INT32 read); + INT32 bdev_write(struct super_block *sb, UINT32 secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync); + INT32 bdev_sync(struct super_block *sb); +#ifdef __cplusplus +} +#endif +#endif diff --git a/fs/exfat/exfat_cache.c b/fs/exfat/exfat_cache.c new file mode 100755 index 0000000000000..82f90abd3efb0 --- /dev/null +++ b/fs/exfat/exfat_cache.c @@ -0,0 +1,740 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" + +#include "exfat_cache.h" +#include "exfat_super.h" +#include "exfat.h" + +extern FS_STRUCT_T fs_struct[]; + +#define sm_P(s) +#define sm_V(s) + +static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content); +static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content); + +static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec); +static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec); +static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp); +static void FAT_cache_remove_hash(BUF_CACHE_T *bp); + +static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec); + +static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec); +static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec); +static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp); +static void buf_cache_remove_hash(BUF_CACHE_T *bp); + +static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list); +static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list); +static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list); +static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list); + +INT32 buf_init(struct super_block *sb) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + INT32 i; + + p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list; + + for (i = 0; i < FAT_CACHE_SIZE; i++) { + p_fs->FAT_cache_array[i].drv = -1; + p_fs->FAT_cache_array[i].sec = ~0; + p_fs->FAT_cache_array[i].flag = 0; + p_fs->FAT_cache_array[i].buf_bh = NULL; + p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL; + push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list); + } + + p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list; + + for (i = 0; i < BUF_CACHE_SIZE; i++) { + p_fs->buf_cache_array[i].drv = -1; + p_fs->buf_cache_array[i].sec = ~0; + p_fs->buf_cache_array[i].flag = 0; + p_fs->buf_cache_array[i].buf_bh = NULL; + p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL; + push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list); + } + + for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) { + p_fs->FAT_cache_hash_list[i].drv = -1; + p_fs->FAT_cache_hash_list[i].sec = ~0; + p_fs->FAT_cache_hash_list[i].hash_next = p_fs->FAT_cache_hash_list[i].hash_prev = &(p_fs->FAT_cache_hash_list[i]); + } + + for (i = 0; i < FAT_CACHE_SIZE; i++) { + FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i])); + } + + for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) { + p_fs->buf_cache_hash_list[i].drv = -1; + p_fs->buf_cache_hash_list[i].sec = ~0; + p_fs->buf_cache_hash_list[i].hash_next = p_fs->buf_cache_hash_list[i].hash_prev = &(p_fs->buf_cache_hash_list[i]); + } + + for (i = 0; i < BUF_CACHE_SIZE; i++) { + buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i])); + } + + return(FFS_SUCCESS); +} + +INT32 buf_shutdown(struct super_block *sb) +{ + return(FFS_SUCCESS); +} + +INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content) +{ + INT32 ret; + + sm_P(&f_sem); + + ret = __FAT_read(sb, loc, content); + + sm_V(&f_sem); + + return(ret); +} + +INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content) +{ + INT32 ret; + + sm_P(&f_sem); + + ret = __FAT_write(sb, loc, content); + + sm_V(&f_sem); + + return(ret); +} + +static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content) +{ + INT32 off; + UINT32 sec, _content; + UINT8 *fat_sector, *fat_entry; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_fs->vol_type == FAT12) { + sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); + off = (loc + (loc >> 1)) & p_bd->sector_size_mask; + + if (off == (p_bd->sector_size-1)) { + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + _content = (UINT32) fat_sector[off]; + + fat_sector = FAT_getblk(sb, ++sec); + if (!fat_sector) + return -1; + + _content |= (UINT32) fat_sector[0] << 8; + } else { + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + _content = GET16(fat_entry); + } + + if (loc & 1) _content >>= 4; + + _content &= 0x00000FFF; + + if (_content >= CLUSTER_16(0x0FF8)) { + *content = CLUSTER_32(~0); + return 0; + } else { + *content = CLUSTER_32(_content); + return 0; + } + } else if (p_fs->vol_type == FAT16) { + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1)); + off = (loc << 1) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if + (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + + _content = GET16_A(fat_entry); + + _content &= 0x0000FFFF; + + if (_content >= CLUSTER_16(0xFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } else { + *content = CLUSTER_32(_content); + return 0; + } + } else if (p_fs->vol_type == FAT32) { + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + + _content = GET32_A(fat_entry); + + _content &= 0x0FFFFFFF; + + if (_content >= CLUSTER_32(0x0FFFFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } else { + *content = CLUSTER_32(_content); + return 0; + } + } else { + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + _content = GET32_A(fat_entry); + + if (_content >= CLUSTER_32(0xFFFFFFF8)) { + *content = CLUSTER_32(~0); + return 0; + } else { + *content = CLUSTER_32(_content); + return 0; + } + } + + *content = CLUSTER_32(~0); + return 0; +} + +static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content) +{ + INT32 off; + UINT32 sec; + UINT8 *fat_sector, *fat_entry; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + + if (p_fs->vol_type == FAT12) { + + content &= 0x00000FFF; + + sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); + off = (loc + (loc >> 1)) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + if (loc & 1) { + + content <<= 4; + + if (off == (p_bd->sector_size-1)) { + fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F)); + FAT_modify(sb, sec); + + fat_sector = FAT_getblk(sb, ++sec); + if (!fat_sector) + return -1; + + fat_sector[0] = (UINT8)(content >> 8); + } else { + fat_entry = &(fat_sector[off]); + content |= GET16(fat_entry) & 0x000F; + + SET16(fat_entry, content); + } + } else { + fat_sector[off] = (UINT8)(content); + + if (off == (p_bd->sector_size-1)) { + fat_sector[off] = (UINT8)(content); + FAT_modify(sb, sec); + + fat_sector = FAT_getblk(sb, ++sec); + fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8)); + } else { + fat_entry = &(fat_sector[off]); + content |= GET16(fat_entry) & 0xF000; + + SET16(fat_entry, content); + } + } + } + + else if (p_fs->vol_type == FAT16) { + + content &= 0x0000FFFF; + + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1)); + off = (loc << 1) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + + SET16_A(fat_entry, content); + } + + else if (p_fs->vol_type == FAT32) { + + content &= 0x0FFFFFFF; + + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + + content |= GET32_A(fat_entry) & 0xF0000000; + + SET32_A(fat_entry, content); + } + + else { + + sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); + off = (loc << 2) & p_bd->sector_size_mask; + + fat_sector = FAT_getblk(sb, sec); + if (!fat_sector) + return -1; + + fat_entry = &(fat_sector[off]); + + SET32_A(fat_entry, content); + } + + FAT_modify(sb, sec); + return 0; +} + +UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = FAT_cache_find(sb, sec); + if (bp != NULL) { + move_to_mru(bp, &p_fs->FAT_cache_lru_list); + return(bp->buf_bh->b_data); + } + + bp = FAT_cache_get(sb, sec); + + FAT_cache_remove_hash(bp); + + bp->drv = p_fs->drv; + bp->sec = sec; + bp->flag = 0; + + FAT_cache_insert_hash(sb, bp); + + if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) { + FAT_cache_remove_hash(bp); + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + bp->buf_bh = NULL; + + move_to_lru(bp, &p_fs->FAT_cache_lru_list); + return NULL; + } + + return(bp->buf_bh->b_data); +} + +void FAT_modify(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + + bp = FAT_cache_find(sb, sec); + if (bp != NULL) { + sector_write(sb, sec, bp->buf_bh, 0); + } +} + +void FAT_release_all(struct super_block *sb) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&f_sem); + + bp = p_fs->FAT_cache_lru_list.next; + while (bp != &p_fs->FAT_cache_lru_list) { + if (bp->drv == p_fs->drv) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if(bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + } + bp = bp->next; + } + + sm_V(&f_sem); +} + +void FAT_sync(struct super_block *sb) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&f_sem); + + bp = p_fs->FAT_cache_lru_list.next; + while (bp != &p_fs->FAT_cache_lru_list) { + if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { + sync_dirty_buffer(bp->buf_bh); + bp->flag &= ~(DIRTYBIT); + } + bp = bp->next; + } + + sm_V(&f_sem); +} + +static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec) +{ + INT32 off; + BUF_CACHE_T *bp, *hp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1); + + hp = &(p_fs->FAT_cache_hash_list[off]); + for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { + if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { + + WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. " + "It will make system panic.\n"); + + touch_buffer(bp->buf_bh); + return(bp); + } + } + return(NULL); +} + +static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = p_fs->FAT_cache_lru_list.prev; + + + move_to_mru(bp, &p_fs->FAT_cache_lru_list); + return(bp); +} + +static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp) +{ + INT32 off; + BUF_CACHE_T *hp; + FS_INFO_T *p_fs; + + p_fs = &(EXFAT_SB(sb)->fs_info); + off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1); + + hp = &(p_fs->FAT_cache_hash_list[off]); + bp->hash_next = hp->hash_next; + bp->hash_prev = hp; + hp->hash_next->hash_prev = bp; + hp->hash_next = bp; +} + +static void FAT_cache_remove_hash(BUF_CACHE_T *bp) +{ + (bp->hash_prev)->hash_next = bp->hash_next; + (bp->hash_next)->hash_prev = bp->hash_prev; +} + +UINT8 *buf_getblk(struct super_block *sb, UINT32 sec) +{ + UINT8 *buf; + + sm_P(&b_sem); + + buf = __buf_getblk(sb, sec); + + sm_V(&b_sem); + + return(buf); +} + +static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = buf_cache_find(sb, sec); + if (bp != NULL) { + move_to_mru(bp, &p_fs->buf_cache_lru_list); + return(bp->buf_bh->b_data); + } + + bp = buf_cache_get(sb, sec); + + buf_cache_remove_hash(bp); + + bp->drv = p_fs->drv; + bp->sec = sec; + bp->flag = 0; + + buf_cache_insert_hash(sb, bp); + + if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) { + buf_cache_remove_hash(bp); + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + bp->buf_bh = NULL; + + move_to_lru(bp, &p_fs->buf_cache_lru_list); + return NULL; + } + + return(bp->buf_bh->b_data); + +} + +void buf_modify(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + + sm_P(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp != NULL)) { + sector_write(sb, sec, bp->buf_bh, 0); + } + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec); + + sm_V(&b_sem); +} + +void buf_lock(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + + sm_P(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp != NULL)) bp->flag |= LOCKBIT; + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec); + + sm_V(&b_sem); +} + +void buf_unlock(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + + sm_P(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT); + + WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec); + + sm_V(&b_sem); +} + +void buf_release(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&b_sem); + + bp = buf_cache_find(sb, sec); + if (likely(bp != NULL)) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if(bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + + move_to_lru(bp, &p_fs->buf_cache_lru_list); + } + + sm_V(&b_sem); +} + +void buf_release_all(struct super_block *sb) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&b_sem); + + bp = p_fs->buf_cache_lru_list.next; + while (bp != &p_fs->buf_cache_lru_list) { + if (bp->drv == p_fs->drv) { + bp->drv = -1; + bp->sec = ~0; + bp->flag = 0; + + if(bp->buf_bh) { + __brelse(bp->buf_bh); + bp->buf_bh = NULL; + } + } + bp = bp->next; + } + + sm_V(&b_sem); +} + +void buf_sync(struct super_block *sb) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + sm_P(&b_sem); + + bp = p_fs->buf_cache_lru_list.next; + while (bp != &p_fs->buf_cache_lru_list) { + if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { + sync_dirty_buffer(bp->buf_bh); + bp->flag &= ~(DIRTYBIT); + } + bp = bp->next; + } + + sm_V(&b_sem); +} + +static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec) +{ + INT32 off; + BUF_CACHE_T *bp, *hp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1); + + hp = &(p_fs->buf_cache_hash_list[off]); + for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { + if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { + touch_buffer(bp->buf_bh); + return(bp); + } + } + return(NULL); +} + +static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec) +{ + BUF_CACHE_T *bp; + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + bp = p_fs->buf_cache_lru_list.prev; + while (bp->flag & LOCKBIT) bp = bp->prev; + + + move_to_mru(bp, &p_fs->buf_cache_lru_list); + return(bp); +} + +static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp) +{ + INT32 off; + BUF_CACHE_T *hp; + FS_INFO_T *p_fs; + + p_fs = &(EXFAT_SB(sb)->fs_info); + off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1); + + hp = &(p_fs->buf_cache_hash_list[off]); + bp->hash_next = hp->hash_next; + bp->hash_prev = hp; + hp->hash_next->hash_prev = bp; + hp->hash_next = bp; +} + +static void buf_cache_remove_hash(BUF_CACHE_T *bp) +{ + (bp->hash_prev)->hash_next = bp->hash_next; + (bp->hash_next)->hash_prev = bp->hash_prev; +} + +static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list) +{ + bp->next = list->next; + bp->prev = list; + list->next->prev = bp; + list->next = bp; +} + +static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list) +{ + bp->prev = list->prev; + bp->next = list; + list->prev->next = bp; + list->prev = bp; +} + +static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list) +{ + bp->prev->next = bp->next; + bp->next->prev = bp->prev; + push_to_mru(bp, list); +} + +static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list) +{ + bp->prev->next = bp->next; + bp->next->prev = bp->prev; + push_to_lru(bp, list); +} diff --git a/fs/exfat/exfat_cache.h b/fs/exfat/exfat_cache.h new file mode 100755 index 0000000000000..7674509598eda --- /dev/null +++ b/fs/exfat/exfat_cache.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_CACHE_H +#define _EXFAT_CACHE_H + +#include "exfat_config.h" +#include "exfat_global.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOCKBIT 0x01 +#define DIRTYBIT 0x02 + + typedef struct __BUF_CACHE_T { + struct __BUF_CACHE_T *next; + struct __BUF_CACHE_T *prev; + struct __BUF_CACHE_T *hash_next; + struct __BUF_CACHE_T *hash_prev; + INT32 drv; + UINT32 sec; + UINT32 flag; + struct buffer_head *buf_bh; + } BUF_CACHE_T; + + INT32 buf_init(struct super_block *sb); + INT32 buf_shutdown(struct super_block *sb); + INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content); + INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content); + UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec); + void FAT_modify(struct super_block *sb, UINT32 sec); + void FAT_release_all(struct super_block *sb); + void FAT_sync(struct super_block *sb); + UINT8 *buf_getblk(struct super_block *sb, UINT32 sec); + void buf_modify(struct super_block *sb, UINT32 sec); + void buf_lock(struct super_block *sb, UINT32 sec); + void buf_unlock(struct super_block *sb, UINT32 sec); + void buf_release(struct super_block *sb, UINT32 sec); + void buf_release_all(struct super_block *sb); + void buf_sync(struct super_block *sb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fs/exfat/exfat_config.h b/fs/exfat/exfat_config.h new file mode 100755 index 0000000000000..e831666e8f141 --- /dev/null +++ b/fs/exfat/exfat_config.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_CONFIG_H +#define _EXFAT_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define OS_NONOS 1 +#define OS_LINUX 2 + +#define FFS_CONFIG_OS OS_LINUX + +#define FFS_CONFIG_LITTLE_ENDIAN 1 +#define FFS_CONFIG_LEGACY_32BIT_API 0 +#define FFS_CONFIG_LEGACY_32BIT_API 0 +#define FFS_CONFIG_SUPPORT_CP1250 1 +#define FFS_CONFIG_SUPPORT_CP1251 1 +#define FFS_CONFIG_SUPPORT_CP1252 1 +#define FFS_CONFIG_SUPPORT_CP1253 1 +#define FFS_CONFIG_SUPPORT_CP1254 1 +#define FFS_CONFIG_SUPPORT_CP1255 1 +#define FFS_CONFIG_SUPPORT_CP1256 1 +#define FFS_CONFIG_SUPPORT_CP1257 1 +#define FFS_CONFIG_SUPPORT_CP1258 1 +#define FFS_CONFIG_SUPPORT_CP874 1 +#define FFS_CONFIG_SUPPORT_CP932 1 +#define FFS_CONFIG_SUPPORT_CP936 1 +#define FFS_CONFIG_SUPPORT_CP949 1 +#define FFS_CONFIG_SUPPORT_CP950 1 +#define FFS_CONFIG_SUPPORT_UTF8 1 +#define EXFAT_CONFIG_DISCARD 1 +#define EXFAT_CONFIG_KERNEL_DEBUG 1 +#define EXFAT_CONFIG_DEBUG_MSG 0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fs/exfat/exfat_data.c b/fs/exfat/exfat_data.c new file mode 100755 index 0000000000000..6c58eac84bafb --- /dev/null +++ b/fs/exfat/exfat_data.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_blkdev.h" +#include "exfat_cache.h" +#include "exfat_nls.h" +#include "exfat_super.h" +#include "exfat.h" + +FS_STRUCT_T fs_struct[MAX_DRIVE]; + +DECLARE_MUTEX(f_sem); +BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE]; +BUF_CACHE_T FAT_cache_lru_list; +BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; + +DECLARE_MUTEX(b_sem); +BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE]; +BUF_CACHE_T buf_cache_lru_list; +BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; diff --git a/fs/exfat/exfat_data.h b/fs/exfat/exfat_data.h new file mode 100755 index 0000000000000..27ca835c22c48 --- /dev/null +++ b/fs/exfat/exfat_data.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_DATA_H +#define _EXFAT_DATA_H +#include "exfat_config.h" +#include "exfat_global.h" +#ifdef __cplusplus +extern "C" { +#endif +#define MAX_DEVICE 2 +#define MAX_DRIVE 2 +#define MAX_OPEN 20 +#define MAX_DENTRY 512 +#define FAT_CACHE_SIZE 128 +#define FAT_CACHE_HASH_SIZE 64 +#define BUF_CACHE_SIZE 256 +#define BUF_CACHE_HASH_SIZE 64 +#define DEFAULT_CODEPAGE 437 +#define DEFAULT_IOCHARSET "utf8" +#ifdef __cplusplus +} +#endif +#endif diff --git a/fs/exfat/exfat_global.c b/fs/exfat/exfat_global.c new file mode 100755 index 0000000000000..89934f9d2b26d --- /dev/null +++ b/fs/exfat/exfat_global.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "exfat_config.h" +#include "exfat_global.h" + +INT32 __wstrchr(UINT16 *str, UINT16 wchar) +{ + while (*str) { + if (*(str++) == wchar) return(1); + } + return(0); +} + +INT32 __wstrlen(UINT16 *str) +{ + INT32 length = 0; + + while (*(str++)) length++; + return(length); +} + +#define BITMAP_LOC(v) ((v) >> 3) +#define BITMAP_SHIFT(v) ((v) & 0x07) + +void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize) +{ + MEMSET(bitmap, 0xFF, mapsize); +} + +void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize) +{ + MEMSET(bitmap, 0x0, mapsize); +} + +INT32 Bitmap_test(UINT8 *bitmap, INT32 i) +{ + UINT8 data; + + data = bitmap[BITMAP_LOC(i)]; + if ((data >> BITMAP_SHIFT(i)) & 0x01) return(1); + return(0); +} + +void Bitmap_set(UINT8 *bitmap, INT32 i) +{ + bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i)); +} + +void Bitmap_clear(UINT8 *bitmap, INT32 i) +{ + bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i)); +} + +void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits) +{ + INT32 i; + + for (i = 0; i < nbits; i++) { + Bitmap_set(bitmap, offset+i); + } +} + +void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits) +{ + INT32 i; + + for (i = 0; i < nbits; i++) { + Bitmap_clear(bitmap, offset+i); + } +} + +void my_itoa(INT8 *buf, INT32 v) +{ + INT32 mod[10]; + INT32 i; + + for (i = 0; i < 10; i++) { + mod[i] = (v % 10); + v = v / 10; + if (v == 0) break; + } + + if (i == 10) + i--; + + for (; i >= 0; i--) { + *buf = (UINT8) ('0' + mod[i]); + buf++; + } + *buf = '\0'; +} + +INT32 my_log2(UINT32 v) +{ + UINT32 bits = 0; + + while (v > 1) { + if (v & 0x01) return(-1); + v >>= 1; + bits++; + } + return(bits); +} diff --git a/fs/exfat/exfat_global.h b/fs/exfat/exfat_global.h new file mode 100755 index 0000000000000..2d2f280ab8e99 --- /dev/null +++ b/fs/exfat/exfat_global.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_GLOBAL_H +#define _EXFAT_GLOBAL_H + +#include +#include +#include +#include +#include +#include "exfat_config.h" + +#ifdef CONFIG_EXFAT_SUPPORT_STLOG +#include +#else +#define ST_LOG(fmt,...) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef OK +#define OK 0 +#endif +#ifndef FAIL +#define FAIL 1 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + typedef char INT8; + typedef short INT16; + typedef int INT32; + typedef long long INT64; + typedef unsigned char UINT8; + typedef unsigned short UINT16; + typedef unsigned int UINT32; + typedef unsigned long long UINT64; + typedef unsigned char BOOL; + +#ifdef MALLOC +#undef MALLOC +#endif +#ifdef FREE +#undef FREE +#endif +#ifdef MEMSET +#undef MEMSET +#endif +#ifdef MEMCPY +#undef MEMCPY +#endif +#ifdef MEMCMP +#undef MEMCMP +#endif + +#define MALLOC(size) kmalloc(size, GFP_KERNEL) +#define FREE(mem) if (mem) kfree(mem) +#define MEMSET(mem, value, size) memset(mem, value, size) +#define MEMCPY(dest, src, size) memcpy(dest, src, size) +#define MEMCMP(mem1, mem2, size) memcmp(mem1, mem2, size) +#define COPY_DENTRY(dest, src) memcpy(dest, src, sizeof(DENTRY_T)) + +#define STRCPY(dest, src) strcpy(dest, src) +#define STRNCPY(dest, src, n) strncpy(dest, src, n) +#define STRCAT(str1, str2) strcat(str1, str2) +#define STRCMP(str1, str2) strcmp(str1, str2) +#define STRNCMP(str1, str2, n) strncmp(str1, str2, n) +#define STRLEN(str) strlen(str) + + INT32 __wstrchr(UINT16 *str, UINT16 wchar); + INT32 __wstrlen(UINT16 *str); + +#define WSTRCHR(str, wchar) __wstrchr(str, wchar) +#define WSTRLEN(str) __wstrlen(str) + +#if EXFAT_CONFIG_DEBUG_MSG +#define PRINTK(...) \ + do { \ + printk("[EXFAT] " __VA_ARGS__); \ + } while(0) +#else +#define PRINTK(...) +#endif + + void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize); + void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize); + INT32 Bitmap_test(UINT8 *bitmap, INT32 i); + void Bitmap_set(UINT8 *bitmap, INT32 i); + void Bitmap_clear(UINT8 *bitmpa, INT32 i); + void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits); + void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits); + + void my_itoa(INT8 *buf, INT32 v); + INT32 my_log2(UINT32 v); + +#ifdef PRINT +#undef PRINT +#endif + +#define PRINT printk +#ifdef __cplusplus +} +#endif +#endif diff --git a/fs/exfat/exfat_nls.c b/fs/exfat/exfat_nls.c new file mode 100755 index 0000000000000..6a8c8e4170847 --- /dev/null +++ b/fs/exfat/exfat_nls.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" + +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat_super.h" +#include "exfat.h" + +#include + +static UINT16 bad_dos_chars[] = { + 0x002B, 0x002C, 0x003B, 0x003D, 0x005B, 0x005D, + 0xFF0B, 0xFF0C, 0xFF1B, 0xFF1D, 0xFF3B, 0xFF3D, + 0 +}; + +static UINT16 bad_uni_chars[] = { + 0x0022, 0x002A, 0x002F, 0x003A, + 0x003C, 0x003E, 0x003F, 0x005C, 0x007C, + 0 +}; + +static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy); +static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy); + +UINT16 nls_upper(struct super_block *sb, UINT16 a) +{ + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + + if (EXFAT_SB(sb)->options.casesensitive) + return(a); + if ((p_fs->vol_utbl)[get_col_index(a)] != NULL) + return (p_fs->vol_utbl)[get_col_index(a)][get_row_index(a)]; + else + return a; +} + +INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b) +{ + return(STRNCMP((void *) a, (void *) b, DOS_NAME_LENGTH)); +} + +INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b) +{ + INT32 i; + + for (i = 0; i < MAX_NAME_LENGTH; i++, a++, b++) { + if (nls_upper(sb, *a) != nls_upper(sb, *b)) return(1); + if (*a == 0x0) return(0); + } + return(0); +} + +void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy) +{ + INT32 i, j, len, lossy = FALSE; + UINT8 buf[MAX_CHARSET_SIZE]; + UINT8 lower = 0, upper = 0; + UINT8 *dosname = p_dosname->name; + UINT16 *uniname = p_uniname->name; + UINT16 *p, *last_period; + struct nls_table *nls = EXFAT_SB(sb)->nls_disk; + + for (i = 0; i < DOS_NAME_LENGTH; i++) { + *(dosname+i) = ' '; + } + + if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_CUR_DIR_NAME)) { + *(dosname) = '.'; + p_dosname->name_case = 0x0; + if (p_lossy != NULL) *p_lossy = FALSE; + return; + } + + if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_PAR_DIR_NAME)) { + *(dosname) = '.'; + *(dosname+1) = '.'; + p_dosname->name_case = 0x0; + if (p_lossy != NULL) *p_lossy = FALSE; + return; + } + + last_period = NULL; + for (p = uniname; *p; p++) { + if (*p == (UINT16) '.') last_period = p; + } + + i = 0; + while (i < DOS_NAME_LENGTH) { + if (i == 8) { + if (last_period == NULL) break; + + if (uniname <= last_period) { + if (uniname < last_period) lossy = TRUE; + uniname = last_period + 1; + } + } + + if (*uniname == (UINT16) '\0') { + break; + } else if (*uniname == (UINT16) ' ') { + lossy = TRUE; + } else if (*uniname == (UINT16) '.') { + if (uniname < last_period) lossy = TRUE; + else i = 8; + } else if (WSTRCHR(bad_dos_chars, *uniname)) { + lossy = TRUE; + *(dosname+i) = '_'; + i++; + } else { + len = convert_uni_to_ch(nls, buf, *uniname, &lossy); + + if (len > 1) { + if ((i >= 8) && ((i+len) > DOS_NAME_LENGTH)) { + break; + } + if ((i < 8) && ((i+len) > 8)) { + i = 8; + continue; + } + + lower = 0xFF; + + for (j = 0; j < len; j++, i++) { + *(dosname+i) = *(buf+j); + } + } else { + if ((*buf >= 'a') && (*buf <= 'z')) { + *(dosname+i) = *buf - ('a' - 'A'); + + if (i < 8) lower |= 0x08; + else lower |= 0x10; + } else if ((*buf >= 'A') && (*buf <= 'Z')) { + *(dosname+i) = *buf; + + if (i < 8) upper |= 0x08; + else upper |= 0x10; + } else { + *(dosname+i) = *buf; + } + i++; + } + } + + uniname++; + } + + if (*dosname == 0xE5) *dosname = 0x05; + if (*uniname != 0x0) lossy = TRUE; + + if (upper & lower) p_dosname->name_case = 0xFF; + else p_dosname->name_case = lower; + + if (p_lossy != NULL) *p_lossy = lossy; +} + +void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname) +{ + INT32 i = 0, j, n = 0; + UINT8 buf[DOS_NAME_LENGTH+2]; + UINT8 *dosname = p_dosname->name; + UINT16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_disk; + + if (*dosname == 0x05) { + *buf = 0xE5; + i++; + n++; + } + + for ( ; i < 8; i++, n++) { + if (*(dosname+i) == ' ') break; + + if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x08)) + *(buf+n) = *(dosname+i) + ('a' - 'A'); + else + *(buf+n) = *(dosname+i); + } + if (*(dosname+8) != ' ') { + *(buf+n) = '.'; + n++; + } + + for (i = 8; i < DOS_NAME_LENGTH; i++, n++) { + if (*(dosname+i) == ' ') break; + + if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x10)) + *(buf+n) = *(dosname+i) + ('a' - 'A'); + else + *(buf+n) = *(dosname+i); + } + *(buf+n) = '\0'; + + i = j = 0; + while (j < (MAX_NAME_LENGTH-1)) { + if (*(buf+i) == '\0') break; + + i += convert_ch_to_uni(nls, uniname, (buf+i), NULL); + + uniname++; + j++; + } + + *uniname = (UINT16) '\0'; +} + +void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname) +{ + INT32 i, j, len; + UINT8 buf[MAX_CHARSET_SIZE]; + UINT16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + i = 0; + while (i < (MAX_NAME_LENGTH-1)) { + if (*uniname == (UINT16) '\0') break; + + len = convert_uni_to_ch(nls, buf, *uniname, NULL); + + if (len > 1) { + for (j = 0; j < len; j++) + *p_cstring++ = (INT8) *(buf+j); + } else { + *p_cstring++ = (INT8) *buf; + } + + uniname++; + i++; + } + + *p_cstring = '\0'; +} + +void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy) +{ + INT32 i, j, lossy = FALSE; + UINT8 *end_of_name; + UINT16 upname[MAX_NAME_LENGTH]; + UINT16 *uniname = p_uniname->name; + struct nls_table *nls = EXFAT_SB(sb)->nls_io; + + end_of_name = p_cstring + STRLEN((INT8 *) p_cstring); + + while (*(--end_of_name) == ' ') { + if (end_of_name < p_cstring) break; + } + *(++end_of_name) = '\0'; + + if (STRCMP((INT8 *) p_cstring, ".") && STRCMP((INT8 *) p_cstring, "..")) { + while (*(--end_of_name) == '.') { + if (end_of_name < p_cstring) break; + } + *(++end_of_name) = '\0'; + } + + if (*p_cstring == '\0') + lossy = TRUE; + + i = j = 0; + while (j < (MAX_NAME_LENGTH-1)) { + if (*(p_cstring+i) == '\0') break; + + i += convert_ch_to_uni(nls, uniname, (UINT8 *)(p_cstring+i), &lossy); + + if ((*uniname < 0x0020) || WSTRCHR(bad_uni_chars, *uniname)) + lossy = TRUE; + + *(upname+j) = nls_upper(sb, *uniname); + + uniname++; + j++; + } + + if (*(p_cstring+i) != '\0') + lossy = TRUE; + *uniname = (UINT16) '\0'; + + p_uniname->name_len = j; + p_uniname->name_hash = calc_checksum_2byte((void *) upname, j<<1, 0, CS_DEFAULT); + + if (p_lossy != NULL) + *p_lossy = lossy; +} + +static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy) +{ + int len; + + *uni = 0x0; + + if (ch[0] < 0x80) { + *uni = (UINT16) ch[0]; + return(1); + } + + if ((len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni)) < 0) { + printk("%s: fail to use nls \n", __func__); + if (lossy != NULL) + *lossy = TRUE; + *uni = (UINT16) '_'; + if (!strcmp(nls->charset, "utf8")) return(1); + else return(2); + } + + return(len); +} + +static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy) +{ + int len; + + ch[0] = 0x0; + + if (uni < 0x0080) { + ch[0] = (UINT8) uni; + return(1); + } + + if ((len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE)) < 0) { + printk("%s: fail to use nls \n", __func__); + if (lossy != NULL) *lossy = TRUE; + ch[0] = '_'; + return(1); + } + + return(len); + +} diff --git a/fs/exfat/exfat_nls.h b/fs/exfat/exfat_nls.h new file mode 100755 index 0000000000000..8a01d2697ac0d --- /dev/null +++ b/fs/exfat/exfat_nls.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_NLS_H +#define _EXFAT_NLS_H + +#include + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUM_UPCASE 2918 + +#define DOS_CUR_DIR_NAME ". " +#define DOS_PAR_DIR_NAME ".. " + +#if (FFS_CONFIG_LITTLE_ENDIAN == 1) +#define UNI_CUR_DIR_NAME ".\0" +#define UNI_PAR_DIR_NAME ".\0.\0" +#else +#define UNI_CUR_DIR_NAME "\0." +#define UNI_PAR_DIR_NAME "\0.\0." +#endif + + +typedef struct { + UINT8 name[DOS_NAME_LENGTH]; + UINT8 name_case; +} DOS_NAME_T; + +typedef struct { + UINT16 name[MAX_NAME_LENGTH]; + UINT16 name_hash; + UINT8 name_len; +} UNI_NAME_T; + +UINT16 nls_upper(struct super_block *sb, UINT16 a); +INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b); +INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b); +void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy); +void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); +void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname); +void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/fs/exfat/exfat_oal.c b/fs/exfat/exfat_oal.c new file mode 100755 index 0000000000000..b2172b50d1487 --- /dev/null +++ b/fs/exfat/exfat_oal.c @@ -0,0 +1,147 @@ +/* Some of the source code in this file came from "linux/fs/fat/misc.c". */ +/* + * linux/fs/fat/misc.c + * + * Written 1992,1993 by Werner Almesberger + * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980 + * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) + */ + +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_api.h" +#include "exfat_oal.h" + +DECLARE_MUTEX(z_sem); + +INT32 sm_init(struct semaphore *sm) +{ + sema_init(sm, 1); + return(0); +} + +INT32 sm_P(struct semaphore *sm) +{ + down(sm); + return 0; +} + +void sm_V(struct semaphore *sm) +{ + up(sm); +} + +extern struct timezone sys_tz; + +#define UNIX_SECS_1980 315532800L + +#if BITS_PER_LONG == 64 +#define UNIX_SECS_2108 4354819200L +#endif + +#define DAYS_DELTA_DECADE (365 * 10 + 2) +#define NO_LEAP_YEAR_2100 (120) +#define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != NO_LEAP_YEAR_2100) + +#define SECS_PER_MIN (60) +#define SECS_PER_HOUR (60 * SECS_PER_MIN) +#define SECS_PER_DAY (24 * SECS_PER_HOUR) + +#define MAKE_LEAP_YEAR(leap_year, year) \ + do { \ + if (unlikely(year > NO_LEAP_YEAR_2100)) \ + leap_year = ((year + 3) / 4) - 1; \ + else \ + leap_year = ((year + 3) / 4); \ + } while(0) + + + +static time_t accum_days_in_year[] = { + 0, 0, 31, 59, 90,120,151,181,212,243,273,304,334, 0, 0, 0, +}; + + +TIMESTAMP_T *tm_current(TIMESTAMP_T *tp, UINT8 tz_utc) +{ + struct timespec ts = CURRENT_TIME_SEC; + time_t second = ts.tv_sec; + time_t day, leap_day, month, year; + + if (!tz_utc) + second -= sys_tz.tz_minuteswest * SECS_PER_MIN; + + if (second < UNIX_SECS_1980) { + tp->sec = 0; + tp->min = 0; + tp->hour = 0; + tp->day = 1; + tp->mon = 1; + tp->year = 0; + return(tp); + } +#if BITS_PER_LONG == 64 + if (second >= UNIX_SECS_2108) { + tp->sec = 59; + tp->min = 59; + tp->hour = 23; + tp->day = 31; + tp->mon = 12; + tp->year = 127; + return(tp); + } +#endif + + day = second / SECS_PER_DAY - DAYS_DELTA_DECADE; + year = day / 365; + + MAKE_LEAP_YEAR(leap_day, year); + if (year * 365 + leap_day > day) + year--; + + MAKE_LEAP_YEAR(leap_day, year); + + day -= year * 365 + leap_day; + + if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) { + month = 2; + } else { + if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3]) + day--; + for (month = 1; month < 12; month++) { + if (accum_days_in_year[month + 1] > day) + break; + } + } + day -= accum_days_in_year[month]; + + tp->sec = second % SECS_PER_MIN; + tp->min = (second / SECS_PER_MIN) % 60; + tp->hour = (second / SECS_PER_HOUR) % 24; + tp->day = day + 1; + tp->mon = month; + tp->year = year; + + return(tp); +} diff --git a/fs/exfat/exfat_oal.h b/fs/exfat/exfat_oal.h new file mode 100755 index 0000000000000..642ef00821b91 --- /dev/null +++ b/fs/exfat/exfat_oal.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_OAL_H +#define _EXFAT_OAL_H + +#include "exfat_config.h" +#include "exfat_global.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + UINT16 sec; + UINT16 min; + UINT16 hour; + UINT16 day; + UINT16 mon; + UINT16 year; + } TIMESTAMP_T; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) +#define DECLARE_MUTEX(m) DEFINE_SEMAPHORE(m) +#endif + + INT32 sm_init(struct semaphore *sm); + INT32 sm_P(struct semaphore *sm); + void sm_V(struct semaphore *sm); + + TIMESTAMP_T *tm_current(TIMESTAMP_T *tm, UINT8 tz_utc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fs/exfat/exfat_part.h b/fs/exfat/exfat_part.h new file mode 100755 index 0000000000000..cc6db65cbe7b4 --- /dev/null +++ b/fs/exfat/exfat_part.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_PART_H +#define _EXFAT_PART_H + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MBR_SIGNATURE 0xAA55 + typedef struct { + UINT8 boot_code[446]; + UINT8 partition[64]; + UINT8 signature[2]; + } MBR_SECTOR_T; + + typedef struct { + UINT8 def_boot; + UINT8 bgn_chs[3]; + UINT8 sys_type; + UINT8 end_chs[3]; + UINT8 start_sector[4]; + UINT8 num_sectors[4]; + } PART_ENTRY_T; + + INT32 ffsSetPartition(INT32 dev, INT32 num_vol, PART_INFO_T *vol_spec); + INT32 ffsGetPartition(INT32 dev, INT32 *num_vol, PART_INFO_T *vol_spec); + INT32 ffsGetDevInfo(INT32 dev, DEV_INFO_T *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fs/exfat/exfat_super.c b/fs/exfat/exfat_super.c new file mode 100755 index 0000000000000..2bfa7300b770f --- /dev/null +++ b/fs/exfat/exfat_super.c @@ -0,0 +1,2416 @@ +/* Some of the source code in this file came from "linux/fs/fat/file.c","linux/fs/fat/inode.c" and "linux/fs/fat/misc.c". */ +/* + * linux/fs/fat/file.c + * + * Written 1992,1993 by Werner Almesberger + * + * regular file handling primitives for fat-based filesystems + */ + +/* + * linux/fs/fat/inode.c + * + * Written 1992,1993 by Werner Almesberger + * VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner + * Rewritten for the constant inumbers support by Al Viro + * + * Fixes: + * + * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0 + */ + +/* + * linux/fs/fat/misc.c + * + * Written 1992,1993 by Werner Almesberger + * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980 + * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) + */ + +/* + * linux/fs/vfat/namei.c + * + * Written 1992,1993 by Werner Almesberger + * + * Windows95/Windows NT compatible extended MSDOS filesystem + * by Gordon Chaffee Copyright (C) 1995. Send bug reports for the + * VFAT filesystem to . Specify + * what file operation caused you trouble and if you can duplicate + * the problem, send a script that demonstrates it. + * + * Short name translation 1999, 2001 by Wolfram Pienkoss + * + * Support Multibyte characters and cleanup by + * OGAWA Hirofumi + */ + +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exfat_version.h" +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_blkdev.h" +#include "exfat_cache.h" +#include "exfat_part.h" +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat.h" + +#include "exfat_super.h" + +static struct kmem_cache *exfat_inode_cachep; + +static int exfat_default_codepage = DEFAULT_CODEPAGE; +static char exfat_default_iocharset[] = DEFAULT_IOCHARSET; + +extern struct timezone sys_tz; + +#define CHECK_ERR(x) BUG_ON(x) +#define ELAPSED_TIME 0 + +#if (ELAPSED_TIME == 1) +#include + +static UINT32 __t1, __t2; +static UINT32 get_current_msec(void) +{ + struct timeval tm; + do_gettimeofday(&tm); + return((UINT32)(tm.tv_sec*1000000 + tm.tv_usec)); +} +#define TIME_START() do {__t1 = get_current_msec();} while (0) +#define TIME_END() do {__t2 = get_current_msec();} while (0) +#define PRINT_TIME(n) do {printk("[EXFAT] Elapsed time %d = %d (usec)\n", n, (__t2 - __t1));} while (0) +#else +#define TIME_START() +#define TIME_END() +#define PRINT_TIME(n) +#endif + +#define UNIX_SECS_1980 315532800L + +#if BITS_PER_LONG == 64 +#define UNIX_SECS_2108 4354819200L +#endif +#define DAYS_DELTA_DECADE (365 * 10 + 2) +#define NO_LEAP_YEAR_2100 (120) +#define IS_LEAP_YEAR(y) (!((y) & 0x3) && (y) != NO_LEAP_YEAR_2100) + +#define SECS_PER_MIN (60) +#define SECS_PER_HOUR (60 * SECS_PER_MIN) +#define SECS_PER_DAY (24 * SECS_PER_HOUR) + +#define MAKE_LEAP_YEAR(leap_year, year) \ + do { \ + if (unlikely(year > NO_LEAP_YEAR_2100)) \ + leap_year = ((year + 3) / 4) - 1; \ + else \ + leap_year = ((year + 3) / 4); \ + } while(0) + +static time_t accum_days_in_year[] = { + 0, 0, 31, 59, 90,120,151,181,212,243,273,304,334, 0, 0, 0, +}; + +static void _exfat_truncate(struct inode *inode, loff_t old_size); + +void exfat_time_fat2unix(struct exfat_sb_info *sbi, struct timespec *ts, + DATE_TIME_T *tp) +{ + time_t year = tp->Year; + time_t ld; + + MAKE_LEAP_YEAR(ld, year); + + if (IS_LEAP_YEAR(year) && (tp->Month) > 2) + ld++; + + ts->tv_sec = tp->Second + tp->Minute * SECS_PER_MIN + + tp->Hour * SECS_PER_HOUR + + (year * 365 + ld + accum_days_in_year[(tp->Month)] + + (tp->Day - 1) + DAYS_DELTA_DECADE) * SECS_PER_DAY; + + if(!sbi->options.tz_utc) + ts->tv_sec += sys_tz.tz_minuteswest * SECS_PER_MIN; + + ts->tv_nsec = 0; +} + +void exfat_time_unix2fat(struct exfat_sb_info *sbi, struct timespec *ts, + DATE_TIME_T *tp) +{ + time_t second = ts->tv_sec; + time_t day, month, year; + time_t ld; + + if (!sbi->options.tz_utc) + second -= sys_tz.tz_minuteswest * SECS_PER_MIN; + + if (second < UNIX_SECS_1980) { + tp->Second = 0; + tp->Minute = 0; + tp->Hour = 0; + tp->Day = 1; + tp->Month = 1; + tp->Year = 0; + return; + } +#if (BITS_PER_LONG == 64) + if (second >= UNIX_SECS_2108) { + tp->Second = 59; + tp->Minute = 59; + tp->Hour = 23; + tp->Day = 31; + tp->Month = 12; + tp->Year = 127; + return; + } +#endif + day = second / SECS_PER_DAY - DAYS_DELTA_DECADE; + year = day / 365; + MAKE_LEAP_YEAR(ld, year); + if (year * 365 + ld > day) + year--; + + MAKE_LEAP_YEAR(ld, year); + day -= year * 365 + ld; + + if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) { + month = 2; + } else { + if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3]) + day--; + for (month = 1; month < 12; month++) { + if (accum_days_in_year[month + 1] > day) + break; + } + } + day -= accum_days_in_year[month]; + + tp->Second = second % SECS_PER_MIN; + tp->Minute = (second / SECS_PER_MIN) % 60; + tp->Hour = (second / SECS_PER_HOUR) % 24; + tp->Day = day + 1; + tp->Month = month; + tp->Year = year; +} + +static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +static int exfat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +#else +static long exfat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#endif +static int exfat_sync_inode(struct inode *inode); +static struct inode *exfat_build_inode(struct super_block *sb, FILE_ID_T *fid, loff_t i_pos); +static void exfat_detach(struct inode *inode); +static void exfat_attach(struct inode *inode, loff_t i_pos); +static inline unsigned long exfat_hash(loff_t i_pos); +static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc); +static void exfat_write_super(struct super_block *sb); + +static void __lock_super(struct super_block *sb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + lock_super(sb); +#else + struct exfat_sb_info *sbi = EXFAT_SB(sb); + mutex_lock(&sbi->s_lock); +#endif +} + +static void __unlock_super(struct super_block *sb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + unlock_super(sb); +#else + struct exfat_sb_info *sbi = EXFAT_SB(sb); + mutex_unlock(&sbi->s_lock); +#endif +} + +static int __is_sb_dirty(struct super_block *sb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + return sb->s_dirt; +#else + struct exfat_sb_info *sbi = EXFAT_SB(sb); + return sbi->s_dirt; +#endif +} + +static void __set_sb_clean(struct super_block *sb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + sb->s_dirt = 0; +#else + struct exfat_sb_info *sbi = EXFAT_SB(sb); + sbi->s_dirt = 0; +#endif +} + +static void exfat_msg(struct super_block *sb, const char *level, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + struct block_device *bdev = sb->s_bdev; + dev_t bd_dev = bdev ? bdev->bd_dev : 0; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + printk("%s[EXFAT] (%s[%d:%d]): %pV\n", level, + sb->s_id, MAJOR(bd_dev), MINOR(bd_dev), &vaf); + va_end(args); +} + +static void exfat_mnt_msg(struct super_block *sb, int mount, int prev_err, const char *msg) +{ + exfat_msg(sb, KERN_INFO, "%s %s", + msg, prev_err ? "(with previous I/O errors)" : ""); + ST_LOG("[EXFAT] (%s[%d:%d]):%s %s",sb->s_id, MAJOR(sb->s_dev),MINOR(sb->s_dev), + msg, prev_err ? "(with previous I/O errors)" : ""); +} + + +static int __exfat_revalidate(struct dentry *dentry) +{ + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) +static int exfat_revalidate(struct dentry *dentry, unsigned int flags) +#else +static int exfat_revalidate(struct dentry *dentry, struct nameidata *nd) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) + if (flags & LOOKUP_RCU) + return -ECHILD; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00) + if (nd && nd->flags & LOOKUP_RCU) + return -ECHILD; +#endif + + if (dentry->d_inode) + return 1; + return __exfat_revalidate(dentry); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) +static int exfat_revalidate_ci(struct dentry *dentry, unsigned int flags) +#else +static int exfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) + if (flags & LOOKUP_RCU) + return -ECHILD; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00) + unsigned int flags; + + if (nd && nd->flags & LOOKUP_RCU) + return -ECHILD; + + flags = nd ? nd->flags : 0; +#else + flags = nd ? nd->flags : 0; +#endif + + if (dentry->d_inode) + return 1; + + if (!flags) + return 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00) + if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) + return 0; +#else + if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) { + if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) + return 0; + } +#endif + + return __exfat_revalidate(dentry); +} + +static unsigned int __exfat_striptail_len(unsigned int len, const char *name) +{ + while (len && name[len - 1] == '.') + len--; + return len; +} + +static unsigned int exfat_striptail_len(const struct qstr *qstr) +{ + return __exfat_striptail_len(qstr->len, qstr->name); +} + +static int exfat_d_hash(const struct dentry *dentry, const struct inode *inode, + struct qstr *qstr) +{ + qstr->hash = full_name_hash(qstr->name, exfat_striptail_len(qstr)); + return 0; +} + +static int exfat_d_hashi(const struct dentry *dentry, const struct inode *inode, + struct qstr *qstr) +{ + struct nls_table *t = EXFAT_SB(dentry->d_sb)->nls_io; + const unsigned char *name; + unsigned int len; + unsigned long hash; + + name = qstr->name; + len = exfat_striptail_len(qstr); + + hash = init_name_hash(); + while (len--) + hash = partial_name_hash(nls_tolower(t, *name++), hash); + qstr->hash = end_name_hash(hash); + + return 0; +} + +static int exfat_cmpi(const struct dentry *parent, const struct inode *pinode, + const struct dentry *dentry, const struct inode *inode, + unsigned int len, const char *str, const struct qstr *name) +{ + struct nls_table *t = EXFAT_SB(parent->d_sb)->nls_io; + unsigned int alen, blen; + + alen = exfat_striptail_len(name); + blen = __exfat_striptail_len(len, str); + if (alen == blen) { + if (nls_strnicmp(t, name->name, str, alen) == 0) + return 0; + } + return 1; +} + +static int exfat_cmp(const struct dentry *parent, const struct inode *pinode, + const struct dentry *dentry, const struct inode *inode, + unsigned int len, const char *str, const struct qstr *name) +{ + unsigned int alen, blen; + + alen = exfat_striptail_len(name); + blen = __exfat_striptail_len(len, str); + if (alen == blen) { + if (strncmp(name->name, str, alen) == 0) + return 0; + } + return 1; +} + +static const struct dentry_operations exfat_ci_dentry_ops = { + .d_revalidate = exfat_revalidate_ci, + .d_hash = exfat_d_hashi, + .d_compare = exfat_cmpi, +}; + +static const struct dentry_operations exfat_dentry_ops = { + .d_revalidate = exfat_revalidate, + .d_hash = exfat_d_hash, + .d_compare = exfat_cmp, +}; + +static int exfat_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + FS_INFO_T *p_fs = &(sbi->fs_info); + BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); + DIR_ENTRY_T de; + unsigned long inum; + loff_t cpos; + int err = 0; + + __lock_super(sb); + + cpos = filp->f_pos; + if ((p_fs->vol_type == EXFAT) || (inode->i_ino == EXFAT_ROOT_INO)) { + while (cpos < 2) { + if (inode->i_ino == EXFAT_ROOT_INO) + inum = EXFAT_ROOT_INO; + else if (cpos == 0) + inum = inode->i_ino; + else + inum = parent_ino(filp->f_path.dentry); + + if (filldir(dirent, "..", cpos+1, cpos, inum, DT_DIR) < 0) + goto out; + cpos++; + filp->f_pos++; + } + if (cpos == 2) { + cpos = 0; + } + } + if (cpos & (DENTRY_SIZE - 1)) { + err = -ENOENT; + goto out; + } + +get_new: + EXFAT_I(inode)->fid.size = i_size_read(inode); + EXFAT_I(inode)->fid.rwoffset = cpos >> DENTRY_SIZE_BITS; + + err = FsReadDir(inode, &de); + if (err) { + if (err == FFS_MEDIAERR) { + cpos += 1 << p_bd->sector_size_bits; + cpos &= ~((1 << p_bd->sector_size_bits)-1); + } + + err = -EIO; + goto end_of_dir; + } + + cpos = EXFAT_I(inode)->fid.rwoffset << DENTRY_SIZE_BITS; + + if (!de.Name[0]) + goto end_of_dir; + + if (!memcmp(de.ShortName, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH)) { + inum = inode->i_ino; + } else if (!memcmp(de.ShortName, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH)) { + inum = parent_ino(filp->f_path.dentry); + } else { + loff_t i_pos = ((loff_t) EXFAT_I(inode)->fid.start_clu << 32) | + ((EXFAT_I(inode)->fid.rwoffset-1) & 0xffffffff); + + struct inode *tmp = exfat_iget(sb, i_pos); + if (tmp) { + inum = tmp->i_ino; + iput(tmp); + } else { + inum = iunique(sb, EXFAT_ROOT_INO); + } + } + + if (filldir(dirent, de.Name, strlen(de.Name), cpos-1, inum, + (de.Attr & ATTR_SUBDIR) ? DT_DIR : DT_REG) < 0) + goto out; + + filp->f_pos = cpos; + goto get_new; + +end_of_dir: + filp->f_pos = cpos; +out: + __unlock_super(sb); + return err; +} + +static int exfat_ioctl_volume_id(struct inode *dir) +{ + struct super_block *sb = dir->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + FS_INFO_T *p_fs = &(sbi->fs_info); + + return p_fs->vol_id; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +static int exfat_generic_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +#else +static long exfat_generic_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +#endif +{ +#if EXFAT_CONFIG_KERNEL_DEBUG +#if !(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) + struct inode *inode = filp->f_dentry->d_inode; +#endif + unsigned int flags; +#endif + + switch (cmd) { + case EXFAT_IOCTL_GET_VOLUME_ID: + return exfat_ioctl_volume_id(inode); +#if EXFAT_CONFIG_KERNEL_DEBUG + case EXFAT_IOC_GET_DEBUGFLAGS: { + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + flags = sbi->debug_flags; + return put_user(flags, (int __user *)arg); + } + case EXFAT_IOC_SET_DEBUGFLAGS: { + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (get_user(flags, (int __user *) arg)) + return -EFAULT; + + __lock_super(sb); + sbi->debug_flags = flags; + __unlock_super(sb); + + return 0; + } +#endif + default: + return -ENOTTY; + } +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +static int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) +#else +static int exfat_file_fsync(struct file *filp, int datasync) +#endif +{ + struct inode *inode = filp->f_mapping->host; + struct super_block *sb = inode->i_sb; + int res, err; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) + res = generic_file_fsync(filp, start, end, datasync); +#else + res = generic_file_fsync(filp, datasync); +#endif + err = FsSyncVol(sb, 1); + + return res ? res : err; +} + + +const struct file_operations exfat_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .readdir = exfat_readdir, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) + .ioctl = exfat_generic_ioctl, +#else + .unlocked_ioctl = exfat_generic_ioctl, +#endif + .fsync = exfat_file_fsync, +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) +static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, + bool excl) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) +static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, + struct nameidata *nd) +#else +static int exfat_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +#endif +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct timespec ts; + FILE_ID_T fid; + loff_t i_pos; + int err; + + __lock_super(sb); + + PRINTK("exfat_create entered\n"); + + ts = CURRENT_TIME_SEC; + + err = FsCreateFile(dir, (UINT8 *) dentry->d_name.name, FM_REGULAR, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else if (err == FFS_NAMETOOLONG) + err = -ENAMETOOLONG; + else + err = -EIO; + goto out; + } + dir->i_version++; + dir->i_ctime = dir->i_mtime = dir->i_atime = ts; + if (IS_DIRSYNC(dir)) + (void) exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + inode->i_version++; + inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + + dentry->d_time = dentry->d_parent->d_inode->i_version; + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + PRINTK("exfat_create exited\n"); + return err; +} + +static int exfat_find(struct inode *dir, struct qstr *qname, + FILE_ID_T *fid) +{ + int err; + + if (qname->len == 0) + return -ENOENT; + + err = FsLookupFile(dir, (UINT8 *) qname->name, fid); + if (err) + return -ENOENT; + + return 0; +} + +static int exfat_d_anon_disconn(struct dentry *dentry) +{ + return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) +static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags) +#else +static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +#endif +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct dentry *alias; + int err; + FILE_ID_T fid; + loff_t i_pos; + UINT64 ret; + mode_t i_mode; + + __lock_super(sb); + PRINTK("exfat_lookup entered\n"); + err = exfat_find(dir, &dentry->d_name, &fid); + if (err) { + if (err == -ENOENT) { + inode = NULL; + goto out; + } + goto error; + } + + i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff); + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto error; + } + + i_mode = inode->i_mode; + if (S_ISLNK(i_mode)) { + EXFAT_I(inode)->target = MALLOC(i_size_read(inode)+1); + if (!EXFAT_I(inode)->target) { + err = -ENOMEM; + goto error; + } + FsReadFile(dir, &fid, EXFAT_I(inode)->target, i_size_read(inode), &ret); + *(EXFAT_I(inode)->target + i_size_read(inode)) = '\0'; + } + + alias = d_find_alias(inode); + if (alias && !exfat_d_anon_disconn(alias)) { + CHECK_ERR(d_unhashed(alias)); + if (!S_ISDIR(i_mode)) + d_move(alias, dentry); + iput(inode); + __unlock_super(sb); + PRINTK("exfat_lookup exited 1\n"); + return alias; + } else { + dput(alias); + } +out: + __unlock_super(sb); + dentry->d_time = dentry->d_parent->d_inode->i_version; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) + dentry->d_op = sb->s_root->d_op; + dentry = d_splice_alias(inode, dentry); + if (dentry) { + dentry->d_op = sb->s_root->d_op; + dentry->d_time = dentry->d_parent->d_inode->i_version; + } +#else + dentry = d_splice_alias(inode, dentry); + if (dentry) + dentry->d_time = dentry->d_parent->d_inode->i_version; +#endif + PRINTK("exfat_lookup exited 2\n"); + return dentry; + +error: + __unlock_super(sb); + PRINTK("exfat_lookup exited 3\n"); + return ERR_PTR(err); +} + +static int exfat_unlink(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct super_block *sb = dir->i_sb; + struct timespec ts; + int err; + + __lock_super(sb); + + PRINTK("exfat_unlink entered\n"); + + ts = CURRENT_TIME_SEC; + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = FsRemoveEntry(dir, &(EXFAT_I(inode)->fid)); + if (err) { + if (err == FFS_PERMISSIONERR) + err = -EPERM; + else + err = -EIO; + goto out; + } + dir->i_version++; + dir->i_mtime = dir->i_atime = ts; + if (IS_DIRSYNC(dir)) + (void) exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = ts; + exfat_detach(inode); + +out: + __unlock_super(sb); + PRINTK("exfat_unlink exited\n"); + return err; +} + +static int exfat_symlink(struct inode *dir, struct dentry *dentry, const char *target) +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct timespec ts; + FILE_ID_T fid; + loff_t i_pos; + int err; + UINT64 len = (UINT64) strlen(target); + UINT64 ret; + + __lock_super(sb); + + PRINTK("exfat_symlink entered\n"); + + ts = CURRENT_TIME_SEC; + + err = FsCreateFile(dir, (UINT8 *) dentry->d_name.name, FM_SYMLINK, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + + err = FsWriteFile(dir, &fid, (char *) target, len, &ret); + + if (err) { + FsRemoveFile(dir, &fid); + + if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + + dir->i_version++; + dir->i_ctime = dir->i_mtime = dir->i_atime = ts; + if (IS_DIRSYNC(dir)) + (void) exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + + i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + inode->i_version++; + inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + + EXFAT_I(inode)->target = MALLOC(len+1); + if (!EXFAT_I(inode)->target) { + err = -ENOMEM; + goto out; + } + MEMCPY(EXFAT_I(inode)->target, target, len+1); + + dentry->d_time = dentry->d_parent->d_inode->i_version; + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + PRINTK("exfat_symlink exited\n"); + return err; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) +static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +#else +static int exfat_mkdir(struct inode *dir, struct dentry *dentry, int mode) +#endif +{ + struct super_block *sb = dir->i_sb; + struct inode *inode; + struct timespec ts; + FILE_ID_T fid; + loff_t i_pos; + int err; + + __lock_super(sb); + + PRINTK("exfat_mkdir entered\n"); + + ts = CURRENT_TIME_SEC; + + err = FsCreateDir(dir, (UINT8 *) dentry->d_name.name, &fid); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_FULL) + err = -ENOSPC; + else if (err == FFS_NAMETOOLONG) + err = -ENAMETOOLONG; + else + err = -EIO; + goto out; + } + dir->i_version++; + dir->i_ctime = dir->i_mtime = dir->i_atime = ts; + if (IS_DIRSYNC(dir)) + (void) exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + inc_nlink(dir); + + i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff); + + inode = exfat_build_inode(sb, &fid, i_pos); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + inode->i_version++; + inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + + dentry->d_time = dentry->d_parent->d_inode->i_version; + d_instantiate(dentry, inode); + +out: + __unlock_super(sb); + PRINTK("exfat_mkdir exited\n"); + return err; +} + +static int exfat_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct super_block *sb = dir->i_sb; + struct timespec ts; + int err; + + __lock_super(sb); + + PRINTK("exfat_rmdir entered\n"); + + ts = CURRENT_TIME_SEC; + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = FsRemoveDir(dir, &(EXFAT_I(inode)->fid)); + if (err) { + if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -ENOTEMPTY; + else if (err == FFS_NOTFOUND) + err = -ENOENT; + else if (err == FFS_DIRBUSY) + err = -EBUSY; + else + err = -EIO; + goto out; + } + dir->i_version++; + dir->i_mtime = dir->i_atime = ts; + if (IS_DIRSYNC(dir)) + (void) exfat_sync_inode(dir); + else + mark_inode_dirty(dir); + drop_nlink(dir); + + clear_nlink(inode); + inode->i_mtime = inode->i_atime = ts; + exfat_detach(inode); + remove_inode_hash(inode); + +out: + __unlock_super(sb); + PRINTK("exfat_rmdir exited\n"); + return err; +} + +static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct inode *old_inode, *new_inode; + struct super_block *sb = old_dir->i_sb; + struct timespec ts; + loff_t i_pos; + int err; + + __lock_super(sb); + + PRINTK("exfat_rename entered\n"); + + old_inode = old_dentry->d_inode; + new_inode = new_dentry->d_inode; + + ts = CURRENT_TIME_SEC; + + EXFAT_I(old_inode)->fid.size = i_size_read(old_inode); + + err = FsMoveFile(old_dir, &(EXFAT_I(old_inode)->fid), new_dir, new_dentry); + if (err) { + if (err == FFS_PERMISSIONERR) + err = -EPERM; + else if (err == FFS_INVALIDPATH) + err = -EINVAL; + else if (err == FFS_FILEEXIST) + err = -EEXIST; + else if (err == FFS_NOTFOUND) + err = -ENOENT; + else if (err == FFS_FULL) + err = -ENOSPC; + else + err = -EIO; + goto out; + } + new_dir->i_version++; + new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime = ts; + if (IS_DIRSYNC(new_dir)) + (void) exfat_sync_inode(new_dir); + else + mark_inode_dirty(new_dir); + + i_pos = ((loff_t) EXFAT_I(old_inode)->fid.dir.dir << 32) | + (EXFAT_I(old_inode)->fid.entry & 0xffffffff); + + exfat_detach(old_inode); + exfat_attach(old_inode, i_pos); + if (IS_DIRSYNC(new_dir)) + (void) exfat_sync_inode(old_inode); + else + mark_inode_dirty(old_inode); + + if ((S_ISDIR(old_inode->i_mode)) && (old_dir != new_dir)) { + drop_nlink(old_dir); + if (!new_inode) inc_nlink(new_dir); + } + + old_dir->i_version++; + old_dir->i_ctime = old_dir->i_mtime = ts; + if (IS_DIRSYNC(old_dir)) + (void) exfat_sync_inode(old_dir); + else + mark_inode_dirty(old_dir); + + if (new_inode) { + exfat_detach(new_inode); + drop_nlink(new_inode); + if (S_ISDIR(new_inode->i_mode)) + drop_nlink(new_inode); + new_inode->i_ctime = ts; + } + +out: + __unlock_super(sb); + PRINTK("exfat_rename exited\n"); + return err; +} + +static int exfat_cont_expand(struct inode *inode, loff_t size) +{ + struct address_space *mapping = inode->i_mapping; + loff_t start = i_size_read(inode), count = size - i_size_read(inode); + int err, err2; + + if ((err = generic_cont_expand_simple(inode, size)) != 0) + return err; + + inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + mark_inode_dirty(inode); + + if (IS_SYNC(inode)) { + err = filemap_fdatawrite_range(mapping, start, start + count - 1); + err2 = sync_mapping_buffers(mapping); + err = (err)?(err):(err2); + err2 = write_inode_now(inode, 1); + err = (err)?(err):(err2); + if (!err) { + err = filemap_fdatawait_range(mapping, start, start + count - 1); + } + } + return err; +} + +static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode) +{ + mode_t allow_utime = sbi->options.allow_utime; + + if (current_fsuid() != inode->i_uid) { + if (in_group_p(inode->i_gid)) + allow_utime >>= 3; + if (allow_utime & MAY_WRITE) + return 1; + } + + return 0; +} + +static int exfat_sanitize_mode(const struct exfat_sb_info *sbi, + struct inode *inode, umode_t *mode_ptr) +{ + mode_t i_mode, mask, perm; + + i_mode = inode->i_mode; + + if (S_ISREG(i_mode) || S_ISLNK(i_mode)) + mask = sbi->options.fs_fmask; + else + mask = sbi->options.fs_dmask; + + perm = *mode_ptr & ~(S_IFMT | mask); + + if ((perm & (S_IRUGO | S_IXUGO)) != (i_mode & (S_IRUGO|S_IXUGO))) + return -EPERM; + + if (exfat_mode_can_hold_ro(inode)) { + if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) + return -EPERM; + } else { + if ((perm & S_IWUGO) != (S_IWUGO & ~mask)) + return -EPERM; + } + + *mode_ptr &= S_IFMT | perm; + + return 0; +} + +static int exfat_setattr(struct dentry *dentry, struct iattr *attr) +{ + + struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb); + struct inode *inode = dentry->d_inode; + unsigned int ia_valid; + int error; + loff_t old_size; + + PRINTK("exfat_setattr entered\n"); + + if ((attr->ia_valid & ATTR_SIZE) + && (attr->ia_size > i_size_read(inode))) { + error = exfat_cont_expand(inode, attr->ia_size); + if (error || attr->ia_valid == ATTR_SIZE) + return error; + attr->ia_valid &= ~ATTR_SIZE; + } + + ia_valid = attr->ia_valid; + + if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) + && exfat_allow_set_time(sbi, inode)) { + attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET); + } + + error = inode_change_ok(inode, attr); + attr->ia_valid = ia_valid; + if (error) { + return error; + } + + if (((attr->ia_valid & ATTR_UID) && + (attr->ia_uid != sbi->options.fs_uid)) || + ((attr->ia_valid & ATTR_GID) && + (attr->ia_gid != sbi->options.fs_gid)) || + ((attr->ia_valid & ATTR_MODE) && + (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | S_IRWXUGO)))) { + return -EPERM; + } + + if (attr->ia_valid & ATTR_MODE) { + if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) + attr->ia_valid &= ~ATTR_MODE; + } + + EXFAT_I(inode)->fid.size = i_size_read(inode); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) + if (attr->ia_valid) + error = inode_setattr(inode, attr); +#else + if (attr->ia_valid & ATTR_SIZE) { + old_size = i_size_read(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + down_write(&EXFAT_I(inode)->truncate_lock); + truncate_setsize(inode, attr->ia_size); + _exfat_truncate(inode, old_size); + up_write(&EXFAT_I(inode)->truncate_lock); +#else + truncate_setsize(inode, attr->ia_size); + _exfat_truncate(inode, old_size); +#endif + } + setattr_copy(inode, attr); + mark_inode_dirty(inode); +#endif + + + PRINTK("exfat_setattr exited\n"); + return error; +} + +static int exfat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + + PRINTK("exfat_getattr entered\n"); + + generic_fillattr(inode, stat); + stat->blksize = EXFAT_SB(inode->i_sb)->fs_info.cluster_size; + + PRINTK("exfat_getattr exited\n"); + return 0; +} + +const struct inode_operations exfat_dir_inode_operations = { + .create = exfat_create, + .lookup = exfat_lookup, + .unlink = exfat_unlink, + .symlink = exfat_symlink, + .mkdir = exfat_mkdir, + .rmdir = exfat_rmdir, + .rename = exfat_rename, + .setattr = exfat_setattr, + .getattr = exfat_getattr, +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + .setxattr = exfat_setxattr, + .getxattr = exfat_getxattr, + .listxattr = exfat_listxattr, + .removexattr = exfat_removexattr, +#endif +}; + +static void *exfat_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct exfat_inode_info *ei = EXFAT_I(dentry->d_inode); + nd_set_link(nd, (char *)(ei->target)); + return NULL; +} + +const struct inode_operations exfat_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = exfat_follow_link, +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + .setxattr = exfat_setxattr, + .getxattr = exfat_getxattr, + .listxattr = exfat_listxattr, + .removexattr = exfat_removexattr, +#endif +}; + +static int exfat_file_release(struct inode *inode, struct file *filp) +{ + struct super_block *sb = inode->i_sb; + + EXFAT_I(inode)->fid.size = i_size_read(inode); + FsSyncVol(sb, 0); + return 0; +} + +const struct file_operations exfat_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .mmap = generic_file_mmap, + .release = exfat_file_release, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) + .ioctl = exfat_generic_ioctl, + .fsync = exfat_file_fsync, +#else + .unlocked_ioctl = exfat_generic_ioctl, + .fsync = generic_file_fsync, +#endif + .splice_read = generic_file_splice_read, +}; + +static void _exfat_truncate(struct inode *inode, loff_t old_size) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + FS_INFO_T *p_fs = &(sbi->fs_info); + int err; + + __lock_super(sb); + + if (EXFAT_I(inode)->mmu_private > i_size_read(inode)) + EXFAT_I(inode)->mmu_private = i_size_read(inode); + + if (EXFAT_I(inode)->fid.start_clu == 0) goto out; + + err = FsTruncateFile(inode, old_size, i_size_read(inode)); + if (err) goto out; + + inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + if (IS_DIRSYNC(inode)) + (void) exfat_sync_inode(inode); + else + mark_inode_dirty(inode); + + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) + & ~((loff_t)p_fs->cluster_size - 1)) >> 9; +out: + __unlock_super(sb); +} + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) +static void exfat_truncate(struct inode *inode) +{ + _exfat_truncate(inode, i_size_read(inode)); +} +#endif + +const struct inode_operations exfat_file_inode_operations = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) + .truncate = exfat_truncate, +#endif + .setattr = exfat_setattr, + .getattr = exfat_getattr, +#ifdef CONFIG_EXFAT_VIRTUAL_XATTR + .setxattr = exfat_setxattr, + .getxattr = exfat_getxattr, + .listxattr = exfat_listxattr, + .removexattr = exfat_removexattr, +#endif +}; + +static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys, + unsigned long *mapped_blocks, int *create) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + FS_INFO_T *p_fs = &(sbi->fs_info); + BD_INFO_T *p_bd = &(sbi->bd_info); + const unsigned long blocksize = sb->s_blocksize; + const unsigned char blocksize_bits = sb->s_blocksize_bits; + sector_t last_block; + int err, clu_offset, sec_offset; + unsigned int cluster; + + *phys = 0; + *mapped_blocks = 0; + + if ((p_fs->vol_type == FAT12) || (p_fs->vol_type == FAT16)) { + if (inode->i_ino == EXFAT_ROOT_INO) { + if (sector < (p_fs->dentries_in_root >> (p_bd->sector_size_bits-DENTRY_SIZE_BITS))) { + *phys = sector + p_fs->root_start_sector; + *mapped_blocks = 1; + } + return 0; + } + } + + last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits; + if (sector >= last_block) { + if (*create == 0) return 0; + } else { + *create = 0; + } + + clu_offset = sector >> p_fs->sectors_per_clu_bits; + sec_offset = sector & (p_fs->sectors_per_clu - 1); + + EXFAT_I(inode)->fid.size = i_size_read(inode); + + err = FsMapCluster(inode, clu_offset, &cluster); + + if (err) { + if (err == FFS_FULL) + return -ENOSPC; + else + return -EIO; + } else if (cluster != CLUSTER_32(~0)) { + *phys = START_SECTOR(cluster) + sec_offset; + *mapped_blocks = p_fs->sectors_per_clu - sec_offset; + } + + return 0; +} + +static int exfat_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + struct super_block *sb = inode->i_sb; + unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; + int err; + unsigned long mapped_blocks; + sector_t phys; + + __lock_super(sb); + + err = exfat_bmap(inode, iblock, &phys, &mapped_blocks, &create); + if (err) { + __unlock_super(sb); + return err; + } + + if (phys) { + max_blocks = min(mapped_blocks, max_blocks); + if (create) { + EXFAT_I(inode)->mmu_private += max_blocks << sb->s_blocksize_bits; + set_buffer_new(bh_result); + } + map_bh(bh_result, sb, phys); + } + + bh_result->b_size = max_blocks << sb->s_blocksize_bits; + __unlock_super(sb); + + return 0; +} + +static int exfat_readpage(struct file *file, struct page *page) +{ + int ret; + ret = mpage_readpage(page, exfat_get_block); + return ret; +} + +static int exfat_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + int ret; + ret = mpage_readpages(mapping, pages, nr_pages, exfat_get_block); + return ret; +} + +static int exfat_writepage(struct page *page, struct writeback_control *wbc) +{ + int ret; + ret = block_write_full_page(page, exfat_get_block, wbc); + return ret; +} + +static int exfat_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + int ret; + ret = mpage_writepages(mapping, wbc, exfat_get_block); + return ret; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) +static void exfat_write_failed(struct address_space *mapping, loff_t to) +{ + struct inode *inode = mapping->host; + if (to > i_size_read(inode)) { + truncate_pagecache(inode, to, i_size_read(inode)); + EXFAT_I(inode)->fid.size = i_size_read(inode); + _exfat_truncate(inode, i_size_read(inode)); + } +} +#endif + + +static int exfat_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + int ret; + *pagep = NULL; + ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + exfat_get_block, + &EXFAT_I(mapping->host)->mmu_private); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + if (ret < 0) + exfat_write_failed(mapping, pos+len); +#endif + return ret; +} + +static int exfat_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *pagep, void *fsdata) +{ + struct inode *inode = mapping->host; + FILE_ID_T *fid = &(EXFAT_I(inode)->fid); + int err; + + err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + if (err < len) + exfat_write_failed(mapping, pos+len); +#endif + + if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) { + inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; + fid->attr |= ATTR_ARCHIVE; + mark_inode_dirty(inode); + } + return err; +} + +static ssize_t exfat_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, + loff_t offset, unsigned long nr_segs) +{ + struct inode *inode = iocb->ki_filp->f_mapping->host; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + struct address_space *mapping = iocb->ki_filp->f_mapping; +#endif + ssize_t ret; + + if (rw == WRITE) { + if (EXFAT_I(inode)->mmu_private < (offset + iov_length(iov, nr_segs))) + return 0; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + ret = blockdev_direct_IO(rw, iocb, inode, iov, + offset, nr_segs, exfat_get_block); +#else + ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, + offset, nr_segs, exfat_get_block, NULL); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34) + if ((ret < 0) && (rw & WRITE)) + exfat_write_failed(mapping, offset+iov_length(iov, nr_segs)); +#endif + return ret; + +} + +static sector_t _exfat_bmap(struct address_space *mapping, sector_t block) +{ + sector_t blocknr; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + down_read(&EXFAT_I(mapping->host)->truncate_lock); + blocknr = generic_block_bmap(mapping, block, exfat_get_block); + up_read(&EXFAT_I(mapping->host)->truncate_lock); +#else + down_read(&mapping->host->i_alloc_sem); + blocknr = generic_block_bmap(mapping, block, exfat_get_block); + up_read(&mapping->host->i_alloc_sem); +#endif + + return blocknr; +} + +const struct address_space_operations exfat_aops = { + .readpage = exfat_readpage, + .readpages = exfat_readpages, + .writepage = exfat_writepage, + .writepages = exfat_writepages, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) + .sync_page = block_sync_page, +#endif + .write_begin = exfat_write_begin, + .write_end = exfat_write_end, + .direct_IO = exfat_direct_IO, + .bmap = _exfat_bmap +}; + +static inline unsigned long exfat_hash(loff_t i_pos) +{ + return hash_32(i_pos, EXFAT_HASH_BITS); +} + +static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos) { + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *info; + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + struct inode *inode = NULL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) + struct hlist_node *node; + + spin_lock(&sbi->inode_hash_lock); + hlist_for_each_entry(info, node, head, i_hash_fat) { +#else + spin_lock(&sbi->inode_hash_lock); + hlist_for_each_entry(info, head, i_hash_fat) { +#endif + CHECK_ERR(info->vfs_inode.i_sb != sb); + + if (i_pos != info->i_pos) + continue; + inode = igrab(&info->vfs_inode); + if (inode) + break; + } + spin_unlock(&sbi->inode_hash_lock); + return inode; +} + +static void exfat_attach(struct inode *inode, loff_t i_pos) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos); + + spin_lock(&sbi->inode_hash_lock); + EXFAT_I(inode)->i_pos = i_pos; + hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head); + spin_unlock(&sbi->inode_hash_lock); +} + +static void exfat_detach(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + spin_lock(&sbi->inode_hash_lock); + hlist_del_init(&EXFAT_I(inode)->i_hash_fat); + EXFAT_I(inode)->i_pos = 0; + spin_unlock(&sbi->inode_hash_lock); +} + +static int exfat_fill_inode(struct inode *inode, FILE_ID_T *fid) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + FS_INFO_T *p_fs = &(sbi->fs_info); + DIR_ENTRY_T info; + + memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(FILE_ID_T)); + + FsReadStat(inode, &info); + + EXFAT_I(inode)->i_pos = 0; + EXFAT_I(inode)->target = NULL; + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + inode->i_version++; + inode->i_generation = get_seconds(); + + if (info.Attr & ATTR_SUBDIR) { + inode->i_generation &= ~1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + set_nlink(inode,info.NumSubdirs); +#else + inode->i_nlink = info.NumSubdirs; +#endif + } else if (info.Attr & ATTR_SYMLINK) { + inode->i_generation |= 1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO); + inode->i_op = &exfat_symlink_inode_operations; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); + } else { + inode->i_generation |= 1; + inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO); + inode->i_op = &exfat_file_inode_operations; + inode->i_fop = &exfat_file_operations; + inode->i_mapping->a_ops = &exfat_aops; + inode->i_mapping->nrpages = 0; + + i_size_write(inode, info.Size); + EXFAT_I(inode)->mmu_private = i_size_read(inode); + } + exfat_save_attr(inode, info.Attr); + + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) + & ~((loff_t)p_fs->cluster_size - 1)) >> 9; + + exfat_time_fat2unix(sbi, &inode->i_mtime, &info.ModifyTimestamp); + exfat_time_fat2unix(sbi, &inode->i_ctime, &info.CreateTimestamp); + exfat_time_fat2unix(sbi, &inode->i_atime, &info.AccessTimestamp); + + return 0; +} + +static struct inode *exfat_build_inode(struct super_block *sb, + FILE_ID_T *fid, loff_t i_pos) { + struct inode *inode; + int err; + + inode = exfat_iget(sb, i_pos); + if (inode) + goto out; + inode = new_inode(sb); + if (!inode) { + inode = ERR_PTR(-ENOMEM); + goto out; + } + inode->i_ino = iunique(sb, EXFAT_ROOT_INO); + inode->i_version = 1; + err = exfat_fill_inode(inode, fid); + if (err) { + iput(inode); + inode = ERR_PTR(err); + goto out; + } + exfat_attach(inode, i_pos); + insert_inode_hash(inode); +out: + return inode; +} + +static int exfat_sync_inode(struct inode *inode) +{ + return exfat_write_inode(inode, NULL); +} + +static struct inode *exfat_alloc_inode(struct super_block *sb) { + struct exfat_inode_info *ei; + + ei = kmem_cache_alloc(exfat_inode_cachep, GFP_NOFS); + if (!ei) + return NULL; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + init_rwsem(&ei->truncate_lock); +#endif + + return &ei->vfs_inode; +} + +static void exfat_destroy_inode(struct inode *inode) +{ + FREE(EXFAT_I(inode)->target); + EXFAT_I(inode)->target = NULL; + + kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode)); +} + +static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + DIR_ENTRY_T info; + + if (inode->i_ino == EXFAT_ROOT_INO) + return 0; + + info.Attr = exfat_make_attr(inode); + info.Size = i_size_read(inode); + + exfat_time_unix2fat(sbi, &inode->i_mtime, &info.ModifyTimestamp); + exfat_time_unix2fat(sbi, &inode->i_ctime, &info.CreateTimestamp); + exfat_time_unix2fat(sbi, &inode->i_atime, &info.AccessTimestamp); + + FsWriteStat(inode, &info); + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +static void exfat_delete_inode(struct inode *inode) +{ + truncate_inode_pages(&inode->i_data, 0); + clear_inode(inode); +} + +static void exfat_clear_inode(struct inode *inode) +{ + exfat_detach(inode); + remove_inode_hash(inode); +} +#else +static void exfat_evict_inode(struct inode *inode) +{ + truncate_inode_pages(&inode->i_data, 0); + + if (!inode->i_nlink) { + loff_t old_size = i_size_read(inode); + i_size_write(inode, 0); + EXFAT_I(inode)->fid.size = old_size; + FsTruncateFile(inode, old_size, 0); + } + + invalidate_inode_buffers(inode); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,00) + end_writeback(inode); +#else + clear_inode(inode); +#endif + exfat_detach(inode); + + remove_inode_hash(inode); +} +#endif + + +static void exfat_put_super(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int err; + + exfat_mnt_msg(sb, 0, 0, "trying to unmount..."); + + if (__is_sb_dirty(sb)) + exfat_write_super(sb); + + err = FsUmountVol(sb); + + if (sbi->nls_disk) { + unload_nls(sbi->nls_disk); + sbi->nls_disk = NULL; + sbi->options.codepage = exfat_default_codepage; + } + if (sbi->nls_io) { + unload_nls(sbi->nls_io); + sbi->nls_io = NULL; + } + if (sbi->options.iocharset != exfat_default_iocharset) { + kfree(sbi->options.iocharset); + sbi->options.iocharset = exfat_default_iocharset; + } + + sb->s_fs_info = NULL; + kfree(sbi); + + exfat_mnt_msg(sb, 0, err, "unmounted successfully!"); +} + +static void exfat_write_super(struct super_block *sb) +{ + __lock_super(sb); + + __set_sb_clean(sb); + + if (!(sb->s_flags & MS_RDONLY)) + FsSyncVol(sb, 1); + + __unlock_super(sb); +} + +static int exfat_sync_fs(struct super_block *sb, int wait) +{ + int err = 0; + + if (__is_sb_dirty(sb)) { + __lock_super(sb); + __set_sb_clean(sb); + err = FsSyncVol(sb, 1); + __unlock_super(sb); + } + + return err; +} + +static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *sb = dentry->d_sb; + u64 id = huge_encode_dev(sb->s_bdev->bd_dev); + FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); + VOL_INFO_T info; + + if (p_fs->used_clusters == (UINT32) ~0) { + if (FFS_MEDIAERR == FsGetVolInfo(sb, &info)) + return -EIO; + + } else { + info.FatType = p_fs->vol_type; + info.ClusterSize = p_fs->cluster_size; + info.NumClusters = p_fs->num_clusters - 2; + info.UsedClusters = p_fs->used_clusters; + info.FreeClusters = info.NumClusters - info.UsedClusters; + + if (p_fs->dev_ejected) + printk("[EXFAT] called statfs with previous I/O error.\n"); + } + + buf->f_type = sb->s_magic; + buf->f_bsize = info.ClusterSize; + buf->f_blocks = info.NumClusters; + buf->f_bfree = info.FreeClusters; + buf->f_bavail = info.FreeClusters; + buf->f_fsid.val[0] = (u32)id; + buf->f_fsid.val[1] = (u32)(id >> 32); + buf->f_namelen = 260; + + return 0; +} + +static int exfat_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) +static int exfat_show_options(struct seq_file *m, struct dentry *root) +{ + struct exfat_sb_info *sbi = EXFAT_SB(root->d_sb); +#else +static int exfat_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + struct exfat_sb_info *sbi = EXFAT_SB(mnt->mnt_sb); +#endif + struct exfat_mount_options *opts = &sbi->options; + FS_INFO_T *p_fs = &(sbi->fs_info); + + if (opts->fs_uid != 0) + seq_printf(m, ",uid=%u", opts->fs_uid); + if (opts->fs_gid != 0) + seq_printf(m, ",gid=%u", opts->fs_gid); + seq_printf(m, ",fmask=%04o", opts->fs_fmask); + seq_printf(m, ",dmask=%04o", opts->fs_dmask); + if (opts->allow_utime) + seq_printf(m, ",allow_utime=%04o", opts->allow_utime); + if (sbi->nls_disk) + seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); + if (sbi->nls_io) + seq_printf(m, ",iocharset=%s", sbi->nls_io->charset); + seq_printf(m, ",namecase=%u", opts->casesensitive); + if (opts->tz_utc) + seq_puts(m, ",tz=UTC"); + if (opts->errors == EXFAT_ERRORS_CONT) + seq_puts(m, ",errors=continue"); + else if (opts->errors == EXFAT_ERRORS_PANIC) + seq_puts(m, ",errors=panic"); + else + seq_puts(m, ",errors=remount-ro"); +#if EXFAT_CONFIG_DISCARD + if (opts->discard) + seq_printf(m, ",discard"); +#endif + if (p_fs->dev_ejected) + seq_puts(m, ",ejected"); + return 0; +} + +const struct super_operations exfat_sops = { + .alloc_inode = exfat_alloc_inode, + .destroy_inode = exfat_destroy_inode, + .write_inode = exfat_write_inode, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) + .delete_inode = exfat_delete_inode, + .clear_inode = exfat_clear_inode, +#else + .evict_inode = exfat_evict_inode, +#endif + .put_super = exfat_put_super, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,00) + .write_super = exfat_write_super, +#endif + .sync_fs = exfat_sync_fs, + .statfs = exfat_statfs, + .remount_fs = exfat_remount, + .show_options = exfat_show_options, +}; + +enum { + Opt_uid, + Opt_gid, + Opt_umask, + Opt_dmask, + Opt_fmask, + Opt_allow_utime, + Opt_codepage, + Opt_charset, + Opt_namecase, + Opt_debug, + Opt_tz_utc, + Opt_err_cont, + Opt_err_panic, + Opt_err_ro, + Opt_err, +#if EXFAT_CONFIG_DISCARD + Opt_discard, +#endif +}; + +static const match_table_t exfat_tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_umask, "umask=%o"}, + {Opt_dmask, "dmask=%o"}, + {Opt_fmask, "fmask=%o"}, + {Opt_allow_utime, "allow_utime=%o"}, + {Opt_codepage, "codepage=%u"}, + {Opt_charset, "iocharset=%s"}, + {Opt_namecase, "namecase=%u"}, + {Opt_debug, "debug"}, + {Opt_tz_utc, "tz=UTC"}, + {Opt_err_cont, "errors=continue"}, + {Opt_err_panic, "errors=panic"}, + {Opt_err_ro, "errors=remount-ro"}, +#if EXFAT_CONFIG_DISCARD + {Opt_discard, "discard"}, +#endif + {Opt_err, NULL} +}; + +static int parse_options(char *options, int silent, int *debug, + struct exfat_mount_options *opts) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + int option; + char *iocharset; + + opts->fs_uid = current_uid(); + opts->fs_gid = current_gid(); + opts->fs_fmask = opts->fs_dmask = current->fs->umask; + opts->allow_utime = (unsigned short) -1; + opts->codepage = exfat_default_codepage; + opts->iocharset = exfat_default_iocharset; + opts->casesensitive = 0; + opts->tz_utc = 0; + opts->errors = EXFAT_ERRORS_RO; +#if EXFAT_CONFIG_DISCARD + opts->discard = 0; +#endif + *debug = 0; + + if (!options) + goto out; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + if (!*p) + continue; + + token = match_token(p, exfat_tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return 0; + opts->fs_uid = option; + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return 0; + opts->fs_gid = option; + break; + case Opt_umask: + case Opt_dmask: + case Opt_fmask: + if (match_octal(&args[0], &option)) + return 0; + if (token != Opt_dmask) + opts->fs_fmask = option; + if (token != Opt_fmask) + opts->fs_dmask = option; + break; + case Opt_allow_utime: + if (match_octal(&args[0], &option)) + return 0; + opts->allow_utime = option & (S_IWGRP | S_IWOTH); + break; + case Opt_codepage: + if (match_int(&args[0], &option)) + return 0; + opts->codepage = option; + break; + case Opt_charset: + if (opts->iocharset != exfat_default_iocharset) + kfree(opts->iocharset); + iocharset = match_strdup(&args[0]); + if (!iocharset) + return -ENOMEM; + opts->iocharset = iocharset; + break; + case Opt_namecase: + if (match_int(&args[0], &option)) + return 0; + opts->casesensitive = option; + break; + case Opt_tz_utc: + opts->tz_utc = 1; + break; + case Opt_err_cont: + opts->errors = EXFAT_ERRORS_CONT; + break; + case Opt_err_panic: + opts->errors = EXFAT_ERRORS_PANIC; + break; + case Opt_err_ro: + opts->errors = EXFAT_ERRORS_RO; + break; + case Opt_debug: + *debug = 1; + break; +#if EXFAT_CONFIG_DISCARD + case Opt_discard: + opts->discard = 1; + break; +#endif + default: + if (!silent) { + printk(KERN_ERR "[EXFAT] Unrecognized mount option %s or missing value\n", p); + } + return -EINVAL; + } + } + +out: + if (opts->allow_utime == (unsigned short) -1) + opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); + + return 0; +} + +static void exfat_hash_init(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + int i; + + spin_lock_init(&sbi->inode_hash_lock); + for (i = 0; i < EXFAT_HASH_SIZE; i++) + INIT_HLIST_HEAD(&sbi->inode_hashtable[i]); +} + +static int exfat_read_root(struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct timespec ts; + FS_INFO_T *p_fs = &(sbi->fs_info); + DIR_ENTRY_T info; + + ts = CURRENT_TIME_SEC; + + EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir; + EXFAT_I(inode)->fid.dir.flags = 0x01; + EXFAT_I(inode)->fid.entry = -1; + EXFAT_I(inode)->fid.start_clu = p_fs->root_dir; + EXFAT_I(inode)->fid.flags = 0x01; + EXFAT_I(inode)->fid.type = TYPE_DIR; + EXFAT_I(inode)->fid.rwoffset = 0; + EXFAT_I(inode)->fid.hint_last_off = -1; + + EXFAT_I(inode)->target = NULL; + + FsReadStat(inode, &info); + + inode->i_uid = sbi->options.fs_uid; + inode->i_gid = sbi->options.fs_gid; + inode->i_version++; + inode->i_generation = 0; + inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, S_IRWXUGO); + inode->i_op = &exfat_dir_inode_operations; + inode->i_fop = &exfat_dir_operations; + + i_size_write(inode, info.Size); + inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) + & ~((loff_t)p_fs->cluster_size - 1)) >> 9; + EXFAT_I(inode)->i_pos = ((loff_t) p_fs->root_dir << 32) | 0xffffffff; + EXFAT_I(inode)->mmu_private = i_size_read(inode); + + exfat_save_attr(inode, ATTR_SUBDIR); + inode->i_mtime = inode->i_atime = inode->i_ctime = ts; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + set_nlink(inode,info.NumSubdirs + 2); +#else + inode->i_nlink = info.NumSubdirs + 2; +#endif + + return 0; +} + +static void setup_dops(struct super_block *sb) +{ + if (EXFAT_SB(sb)->options.casesensitive == 0) + sb->s_d_op = &exfat_ci_dentry_ops; + else + sb->s_d_op = &exfat_dentry_ops; +} + + +static int exfat_fill_super(struct super_block *sb, void *data, int silent) +{ + struct inode *root_inode = NULL; + struct exfat_sb_info *sbi; + int debug, ret; + long error; + char buf[50]; + + exfat_mnt_msg(sb, 1, 0, "trying to mount..."); + + sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL); + if (!sbi) { + exfat_mnt_msg(sb, 1, 0, "failed to mount! (ENOMEM)"); + return -ENOMEM; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) + mutex_init(&sbi->s_lock); +#endif + sb->s_fs_info = sbi; + + sb->s_flags |= MS_NODIRATIME; + sb->s_magic = EXFAT_SUPER_MAGIC; + sb->s_op = &exfat_sops; + + error = parse_options(data, silent, &debug, &sbi->options); + if (error) + goto out_fail; + + setup_dops(sb); + + error = -EIO; + sb_min_blocksize(sb, 512); + sb->s_maxbytes = 0x7fffffffffffffffLL; + + ret = FsMountVol(sb); + if (ret) { + if (!silent) + printk(KERN_ERR "[EXFAT] FsMountVol failed\n"); + + goto out_fail; + } + + exfat_hash_init(sb); + + error = -EINVAL; + sprintf(buf, "cp%d", sbi->options.codepage); + sbi->nls_disk = load_nls(buf); + if (!sbi->nls_disk) { + printk(KERN_ERR "[EXFAT] Codepage %s not found\n", buf); + goto out_fail2; + } + + sbi->nls_io = load_nls(sbi->options.iocharset); + if (!sbi->nls_io) { + printk(KERN_ERR "[EXFAT] IO charset %s not found\n", + sbi->options.iocharset); + goto out_fail2; + } + + error = -ENOMEM; + root_inode = new_inode(sb); + if (!root_inode) + goto out_fail2; + root_inode->i_ino = EXFAT_ROOT_INO; + root_inode->i_version = 1; + error = exfat_read_root(root_inode); + if (error < 0) + goto out_fail2; + error = -ENOMEM; + exfat_attach(root_inode, EXFAT_I(root_inode)->i_pos); + insert_inode_hash(root_inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + sb->s_root = d_make_root(root_inode); +#else + sb->s_root = d_alloc_root(root_inode); +#endif + if (!sb->s_root) { + printk(KERN_ERR "[EXFAT] Getting the root inode failed\n"); + goto out_fail2; + } + + exfat_mnt_msg(sb, 1, 0, "mounted successfully!"); + + return 0; + +out_fail2: + FsUmountVol(sb); +out_fail: + exfat_mnt_msg(sb, 1, 0, "failed to mount!"); + + if (root_inode) + iput(root_inode); + if (sbi->nls_io) + unload_nls(sbi->nls_io); + if (sbi->nls_disk) + unload_nls(sbi->nls_disk); + if (sbi->options.iocharset != exfat_default_iocharset) + kfree(sbi->options.iocharset); + sb->s_fs_info = NULL; + kfree(sbi); + return error; +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +static int exfat_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data, struct vfsmount *mnt) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, exfat_fill_super, mnt); +} +#else +static struct dentry *exfat_fs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) { + return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super); +} +#endif + +static void init_once(void *foo) +{ + struct exfat_inode_info *ei = (struct exfat_inode_info *)foo; + + INIT_HLIST_NODE(&ei->i_hash_fat); + inode_init_once(&ei->vfs_inode); +} + +static int __init exfat_init_inodecache(void) +{ + exfat_inode_cachep = kmem_cache_create("exfat_inode_cache", + sizeof(struct exfat_inode_info), + 0, (SLAB_RECLAIM_ACCOUNT| + SLAB_MEM_SPREAD), + init_once); + if (exfat_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + +static void __exit exfat_destroy_inodecache(void) +{ + kmem_cache_destroy(exfat_inode_cachep); +} + +#if EXFAT_CONFIG_KERNEL_DEBUG +static void exfat_debug_kill_sb(struct super_block *sb) +{ + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct block_device *bdev = sb->s_bdev; + + long flags; + + if (sbi) { + flags = sbi->debug_flags; + + if (flags & EXFAT_DEBUGFLAGS_INVALID_UMOUNT) { + FsReleaseCache(sb); + invalidate_bdev(bdev); + } + } + + kill_block_super(sb); +} +#endif + +static struct file_system_type exfat_fs_type = { + .owner = THIS_MODULE, + .name = "exfat", +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + .get_sb = exfat_get_sb, +#else + .mount = exfat_fs_mount, +#endif +#if EXFAT_CONFIG_KERNEL_DEBUG + .kill_sb = exfat_debug_kill_sb, +#else + .kill_sb = kill_block_super, +#endif + .fs_flags = FS_REQUIRES_DEV, +}; + +static int __init init_exfat_fs(void) +{ + int err; + + printk(KERN_INFO "exFAT: FS Version %s\n", EXFAT_VERSION); + + err = exfat_init_inodecache(); + if (err) return err; + + return register_filesystem(&exfat_fs_type); +} + +static void __exit exit_exfat_fs(void) +{ + exfat_destroy_inodecache(); + unregister_filesystem(&exfat_fs_type); +} + +module_init(init_exfat_fs); +module_exit(exit_exfat_fs); + +MODULE_LICENSE("GPL"); diff --git a/fs/exfat/exfat_super.h b/fs/exfat/exfat_super.h new file mode 100755 index 0000000000000..7b74ed0f4272b --- /dev/null +++ b/fs/exfat/exfat_super.h @@ -0,0 +1,158 @@ +/* Some of the source code in this file came from "linux/fs/fat/fat.h". */ + +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EXFAT_LINUX_H +#define _EXFAT_LINUX_H + +#include +#include +#include +#include +#include +#include + +#include "exfat_config.h" +#include "exfat_global.h" +#include "exfat_data.h" +#include "exfat_oal.h" + +#include "exfat_blkdev.h" +#include "exfat_cache.h" +#include "exfat_part.h" +#include "exfat_nls.h" +#include "exfat_api.h" +#include "exfat.h" + +#define EXFAT_ERRORS_CONT 1 +#define EXFAT_ERRORS_PANIC 2 +#define EXFAT_ERRORS_RO 3 + +#define EXFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) + +struct exfat_mount_options { + uid_t fs_uid; + gid_t fs_gid; + unsigned short fs_fmask; + unsigned short fs_dmask; + unsigned short allow_utime; + unsigned short codepage; + char *iocharset; + unsigned char casesensitive; + unsigned char tz_utc; + unsigned char errors; +#if EXFAT_CONFIG_DISCARD + unsigned char discard; +#endif +}; + +#define EXFAT_HASH_BITS 8 +#define EXFAT_HASH_SIZE (1UL << EXFAT_HASH_BITS) + +struct exfat_sb_info { + FS_INFO_T fs_info; + BD_INFO_T bd_info; + + struct exfat_mount_options options; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00) + int s_dirt; + struct mutex s_lock; +#endif + struct nls_table *nls_disk; + struct nls_table *nls_io; + + struct inode *fat_inode; + + spinlock_t inode_hash_lock; + struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; +#if EXFAT_CONFIG_KERNEL_DEBUG + long debug_flags; +#endif +}; + +struct exfat_inode_info { + FILE_ID_T fid; + char *target; + loff_t mmu_private; + loff_t i_pos; + struct hlist_node i_hash_fat; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00) + struct rw_semaphore truncate_lock; +#endif + struct inode vfs_inode; +}; + +#define EXFAT_SB(sb) ((struct exfat_sb_info *)((sb)->s_fs_info)) + +static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) { + return container_of(inode, struct exfat_inode_info, vfs_inode); +} + +static inline int exfat_mode_can_hold_ro(struct inode *inode) +{ + struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); + + if (S_ISDIR(inode->i_mode)) + return 0; + + if ((~sbi->options.fs_fmask) & S_IWUGO) + return 1; + return 0; +} + +static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi, + u32 attr, mode_t mode) +{ + if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) + mode &= ~S_IWUGO; + + if (attr & ATTR_SUBDIR) + return (mode & ~sbi->options.fs_dmask) | S_IFDIR; + else if (attr & ATTR_SYMLINK) + return (mode & ~sbi->options.fs_dmask) | S_IFLNK; + else + return (mode & ~sbi->options.fs_fmask) | S_IFREG; +} + +static inline u32 exfat_make_attr(struct inode *inode) +{ + if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO)) + return ((EXFAT_I(inode)->fid.attr) | ATTR_READONLY); + else + return (EXFAT_I(inode)->fid.attr); +} + +static inline void exfat_save_attr(struct inode *inode, u32 attr) +{ + if (exfat_mode_can_hold_ro(inode)) + EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK; + else + EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY); +} + +/* exfat_xattr.c */ +extern int exfat_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); +extern ssize_t exfat_getxattr(struct dentry *dentry, const char *name, + void *value, size_t size); +extern ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size); +extern int exfat_removexattr(struct dentry *dentry, const char *name); + +#endif diff --git a/fs/exfat/exfat_upcase.c b/fs/exfat/exfat_upcase.c new file mode 100755 index 0000000000000..7378a157b08b6 --- /dev/null +++ b/fs/exfat/exfat_upcase.c @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "exfat_config.h" +#include "exfat_global.h" + +#include "exfat_nls.h" + +UINT8 uni_upcase[NUM_UPCASE<<1] = { + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00, + 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, + 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, + 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, + 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, + 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, + 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, + 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, + 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, + 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, + 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, + 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, 0x00, + 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, + 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, + 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xF7, 0x00, + 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0x78, 0x01, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, + 0x08, 0x01, 0x08, 0x01, 0x0A, 0x01, 0x0A, 0x01, 0x0C, 0x01, 0x0C, 0x01, 0x0E, 0x01, 0x0E, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, + 0x18, 0x01, 0x18, 0x01, 0x1A, 0x01, 0x1A, 0x01, 0x1C, 0x01, 0x1C, 0x01, 0x1E, 0x01, 0x1E, 0x01, + 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, + 0x28, 0x01, 0x28, 0x01, 0x2A, 0x01, 0x2A, 0x01, 0x2C, 0x01, 0x2C, 0x01, 0x2E, 0x01, 0x2E, 0x01, + 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, + 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3B, 0x01, 0x3B, 0x01, 0x3D, 0x01, 0x3D, 0x01, 0x3F, 0x01, + 0x3F, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, + 0x47, 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4A, 0x01, 0x4C, 0x01, 0x4C, 0x01, 0x4E, 0x01, 0x4E, 0x01, + 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, + 0x58, 0x01, 0x58, 0x01, 0x5A, 0x01, 0x5A, 0x01, 0x5C, 0x01, 0x5C, 0x01, 0x5E, 0x01, 0x5E, 0x01, + 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, + 0x68, 0x01, 0x68, 0x01, 0x6A, 0x01, 0x6A, 0x01, 0x6C, 0x01, 0x6C, 0x01, 0x6E, 0x01, 0x6E, 0x01, + 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, + 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7B, 0x01, 0x7B, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7F, 0x01, + 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, + 0x87, 0x01, 0x89, 0x01, 0x8A, 0x01, 0x8B, 0x01, 0x8B, 0x01, 0x8D, 0x01, 0x8E, 0x01, 0x8F, 0x01, + 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, 0x94, 0x01, 0xF6, 0x01, 0x96, 0x01, 0x97, 0x01, + 0x98, 0x01, 0x98, 0x01, 0x3D, 0x02, 0x9B, 0x01, 0x9C, 0x01, 0x9D, 0x01, 0x20, 0x02, 0x9F, 0x01, + 0xA0, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA2, 0x01, 0xA4, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA7, 0x01, + 0xA7, 0x01, 0xA9, 0x01, 0xAA, 0x01, 0xAB, 0x01, 0xAC, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xAF, 0x01, + 0xAF, 0x01, 0xB1, 0x01, 0xB2, 0x01, 0xB3, 0x01, 0xB3, 0x01, 0xB5, 0x01, 0xB5, 0x01, 0xB7, 0x01, + 0xB8, 0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBB, 0x01, 0xBC, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xF7, 0x01, + 0xC0, 0x01, 0xC1, 0x01, 0xC2, 0x01, 0xC3, 0x01, 0xC4, 0x01, 0xC5, 0x01, 0xC4, 0x01, 0xC7, 0x01, + 0xC8, 0x01, 0xC7, 0x01, 0xCA, 0x01, 0xCB, 0x01, 0xCA, 0x01, 0xCD, 0x01, 0xCD, 0x01, 0xCF, 0x01, + 0xCF, 0x01, 0xD1, 0x01, 0xD1, 0x01, 0xD3, 0x01, 0xD3, 0x01, 0xD5, 0x01, 0xD5, 0x01, 0xD7, 0x01, + 0xD7, 0x01, 0xD9, 0x01, 0xD9, 0x01, 0xDB, 0x01, 0xDB, 0x01, 0x8E, 0x01, 0xDE, 0x01, 0xDE, 0x01, + 0xE0, 0x01, 0xE0, 0x01, 0xE2, 0x01, 0xE2, 0x01, 0xE4, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE6, 0x01, + 0xE8, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEA, 0x01, 0xEC, 0x01, 0xEC, 0x01, 0xEE, 0x01, 0xEE, 0x01, + 0xF0, 0x01, 0xF1, 0x01, 0xF2, 0x01, 0xF1, 0x01, 0xF4, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF7, 0x01, + 0xF8, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFA, 0x01, 0xFC, 0x01, 0xFC, 0x01, 0xFE, 0x01, 0xFE, 0x01, + 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, + 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x0A, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0E, 0x02, 0x0E, 0x02, + 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, + 0x18, 0x02, 0x18, 0x02, 0x1A, 0x02, 0x1A, 0x02, 0x1C, 0x02, 0x1C, 0x02, 0x1E, 0x02, 0x1E, 0x02, + 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, + 0x28, 0x02, 0x28, 0x02, 0x2A, 0x02, 0x2A, 0x02, 0x2C, 0x02, 0x2C, 0x02, 0x2E, 0x02, 0x2E, 0x02, + 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, + 0x38, 0x02, 0x39, 0x02, 0x65, 0x2C, 0x3B, 0x02, 0x3B, 0x02, 0x3D, 0x02, 0x66, 0x2C, 0x3F, 0x02, + 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, + 0x48, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x4A, 0x02, 0x4C, 0x02, 0x4C, 0x02, 0x4E, 0x02, 0x4E, 0x02, + 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8A, 0x01, + 0x58, 0x02, 0x8F, 0x01, 0x5A, 0x02, 0x90, 0x01, 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02, + 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, + 0x97, 0x01, 0x96, 0x01, 0x6A, 0x02, 0x62, 0x2C, 0x6C, 0x02, 0x6D, 0x02, 0x6E, 0x02, 0x9C, 0x01, + 0x70, 0x02, 0x71, 0x02, 0x9D, 0x01, 0x73, 0x02, 0x74, 0x02, 0x9F, 0x01, 0x76, 0x02, 0x77, 0x02, + 0x78, 0x02, 0x79, 0x02, 0x7A, 0x02, 0x7B, 0x02, 0x7C, 0x02, 0x64, 0x2C, 0x7E, 0x02, 0x7F, 0x02, + 0xA6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xA9, 0x01, 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, + 0xAE, 0x01, 0x44, 0x02, 0xB1, 0x01, 0xB2, 0x01, 0x45, 0x02, 0x8D, 0x02, 0x8E, 0x02, 0x8F, 0x02, + 0x90, 0x02, 0x91, 0x02, 0xB7, 0x01, 0x93, 0x02, 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, + 0x98, 0x02, 0x99, 0x02, 0x9A, 0x02, 0x9B, 0x02, 0x9C, 0x02, 0x9D, 0x02, 0x9E, 0x02, 0x9F, 0x02, + 0xA0, 0x02, 0xA1, 0x02, 0xA2, 0x02, 0xA3, 0x02, 0xA4, 0x02, 0xA5, 0x02, 0xA6, 0x02, 0xA7, 0x02, + 0xA8, 0x02, 0xA9, 0x02, 0xAA, 0x02, 0xAB, 0x02, 0xAC, 0x02, 0xAD, 0x02, 0xAE, 0x02, 0xAF, 0x02, + 0xB0, 0x02, 0xB1, 0x02, 0xB2, 0x02, 0xB3, 0x02, 0xB4, 0x02, 0xB5, 0x02, 0xB6, 0x02, 0xB7, 0x02, + 0xB8, 0x02, 0xB9, 0x02, 0xBA, 0x02, 0xBB, 0x02, 0xBC, 0x02, 0xBD, 0x02, 0xBE, 0x02, 0xBF, 0x02, + 0xC0, 0x02, 0xC1, 0x02, 0xC2, 0x02, 0xC3, 0x02, 0xC4, 0x02, 0xC5, 0x02, 0xC6, 0x02, 0xC7, 0x02, + 0xC8, 0x02, 0xC9, 0x02, 0xCA, 0x02, 0xCB, 0x02, 0xCC, 0x02, 0xCD, 0x02, 0xCE, 0x02, 0xCF, 0x02, + 0xD0, 0x02, 0xD1, 0x02, 0xD2, 0x02, 0xD3, 0x02, 0xD4, 0x02, 0xD5, 0x02, 0xD6, 0x02, 0xD7, 0x02, + 0xD8, 0x02, 0xD9, 0x02, 0xDA, 0x02, 0xDB, 0x02, 0xDC, 0x02, 0xDD, 0x02, 0xDE, 0x02, 0xDF, 0x02, + 0xE0, 0x02, 0xE1, 0x02, 0xE2, 0x02, 0xE3, 0x02, 0xE4, 0x02, 0xE5, 0x02, 0xE6, 0x02, 0xE7, 0x02, + 0xE8, 0x02, 0xE9, 0x02, 0xEA, 0x02, 0xEB, 0x02, 0xEC, 0x02, 0xED, 0x02, 0xEE, 0x02, 0xEF, 0x02, + 0xF0, 0x02, 0xF1, 0x02, 0xF2, 0x02, 0xF3, 0x02, 0xF4, 0x02, 0xF5, 0x02, 0xF6, 0x02, 0xF7, 0x02, + 0xF8, 0x02, 0xF9, 0x02, 0xFA, 0x02, 0xFB, 0x02, 0xFC, 0x02, 0xFD, 0x02, 0xFE, 0x02, 0xFF, 0x02, + 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, + 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, 0x03, 0x0C, 0x03, 0x0D, 0x03, 0x0E, 0x03, 0x0F, 0x03, + 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, + 0x18, 0x03, 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, 0x1C, 0x03, 0x1D, 0x03, 0x1E, 0x03, 0x1F, 0x03, + 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, + 0x28, 0x03, 0x29, 0x03, 0x2A, 0x03, 0x2B, 0x03, 0x2C, 0x03, 0x2D, 0x03, 0x2E, 0x03, 0x2F, 0x03, + 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, + 0x38, 0x03, 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 0x3F, 0x03, + 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, + 0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 0x4B, 0x03, 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03, + 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, + 0x58, 0x03, 0x59, 0x03, 0x5A, 0x03, 0x5B, 0x03, 0x5C, 0x03, 0x5D, 0x03, 0x5E, 0x03, 0x5F, 0x03, + 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, + 0x68, 0x03, 0x69, 0x03, 0x6A, 0x03, 0x6B, 0x03, 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 0x6F, 0x03, + 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, + 0x78, 0x03, 0x79, 0x03, 0x7A, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, 0x7E, 0x03, 0x7F, 0x03, + 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, + 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 0x8B, 0x03, 0x8C, 0x03, 0x8D, 0x03, 0x8E, 0x03, 0x8F, 0x03, + 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, + 0xA0, 0x03, 0xA1, 0x03, 0xA2, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, + 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, + 0xB0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, + 0xA0, 0x03, 0xA1, 0x03, 0xA3, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, + 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x8C, 0x03, 0x8E, 0x03, 0x8F, 0x03, 0xCF, 0x03, + 0xD0, 0x03, 0xD1, 0x03, 0xD2, 0x03, 0xD3, 0x03, 0xD4, 0x03, 0xD5, 0x03, 0xD6, 0x03, 0xD7, 0x03, + 0xD8, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDA, 0x03, 0xDC, 0x03, 0xDC, 0x03, 0xDE, 0x03, 0xDE, 0x03, + 0xE0, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE2, 0x03, 0xE4, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE6, 0x03, + 0xE8, 0x03, 0xE8, 0x03, 0xEA, 0x03, 0xEA, 0x03, 0xEC, 0x03, 0xEC, 0x03, 0xEE, 0x03, 0xEE, 0x03, + 0xF0, 0x03, 0xF1, 0x03, 0xF9, 0x03, 0xF3, 0x03, 0xF4, 0x03, 0xF5, 0x03, 0xF6, 0x03, 0xF7, 0x03, + 0xF7, 0x03, 0xF9, 0x03, 0xFA, 0x03, 0xFA, 0x03, 0xFC, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, + 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, + 0x68, 0x04, 0x68, 0x04, 0x6A, 0x04, 0x6A, 0x04, 0x6C, 0x04, 0x6C, 0x04, 0x6E, 0x04, 0x6E, 0x04, + 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, + 0x78, 0x04, 0x78, 0x04, 0x7A, 0x04, 0x7A, 0x04, 0x7C, 0x04, 0x7C, 0x04, 0x7E, 0x04, 0x7E, 0x04, + 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, + 0x88, 0x04, 0x89, 0x04, 0x8A, 0x04, 0x8A, 0x04, 0x8C, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x8E, 0x04, + 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, + 0x98, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9A, 0x04, 0x9C, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0x9E, 0x04, + 0xA0, 0x04, 0xA0, 0x04, 0xA2, 0x04, 0xA2, 0x04, 0xA4, 0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA6, 0x04, + 0xA8, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAA, 0x04, 0xAC, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xAE, 0x04, + 0xB0, 0x04, 0xB0, 0x04, 0xB2, 0x04, 0xB2, 0x04, 0xB4, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB6, 0x04, + 0xB8, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBA, 0x04, 0xBC, 0x04, 0xBC, 0x04, 0xBE, 0x04, 0xBE, 0x04, + 0xC0, 0x04, 0xC1, 0x04, 0xC1, 0x04, 0xC3, 0x04, 0xC3, 0x04, 0xC5, 0x04, 0xC5, 0x04, 0xC7, 0x04, + 0xC7, 0x04, 0xC9, 0x04, 0xC9, 0x04, 0xCB, 0x04, 0xCB, 0x04, 0xCD, 0x04, 0xCD, 0x04, 0xC0, 0x04, + 0xD0, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD2, 0x04, 0xD4, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD6, 0x04, + 0xD8, 0x04, 0xD8, 0x04, 0xDA, 0x04, 0xDA, 0x04, 0xDC, 0x04, 0xDC, 0x04, 0xDE, 0x04, 0xDE, 0x04, + 0xE0, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE2, 0x04, 0xE4, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE6, 0x04, + 0xE8, 0x04, 0xE8, 0x04, 0xEA, 0x04, 0xEA, 0x04, 0xEC, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xEE, 0x04, + 0xF0, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF2, 0x04, 0xF4, 0x04, 0xF4, 0x04, 0xF6, 0x04, 0xF6, 0x04, + 0xF8, 0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFA, 0x04, 0xFC, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0xFE, 0x04, + 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, + 0x08, 0x05, 0x08, 0x05, 0x0A, 0x05, 0x0A, 0x05, 0x0C, 0x05, 0x0C, 0x05, 0x0E, 0x05, 0x0E, 0x05, + 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, + 0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, 0x1C, 0x05, 0x1D, 0x05, 0x1E, 0x05, 0x1F, 0x05, + 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, + 0x28, 0x05, 0x29, 0x05, 0x2A, 0x05, 0x2B, 0x05, 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05, + 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, + 0x58, 0x05, 0x59, 0x05, 0x5A, 0x05, 0x5B, 0x05, 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05, + 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xFF, 0xFF, + 0xF6, 0x17, 0x63, 0x2C, 0x7E, 0x1D, 0x7F, 0x1D, 0x80, 0x1D, 0x81, 0x1D, 0x82, 0x1D, 0x83, 0x1D, + 0x84, 0x1D, 0x85, 0x1D, 0x86, 0x1D, 0x87, 0x1D, 0x88, 0x1D, 0x89, 0x1D, 0x8A, 0x1D, 0x8B, 0x1D, + 0x8C, 0x1D, 0x8D, 0x1D, 0x8E, 0x1D, 0x8F, 0x1D, 0x90, 0x1D, 0x91, 0x1D, 0x92, 0x1D, 0x93, 0x1D, + 0x94, 0x1D, 0x95, 0x1D, 0x96, 0x1D, 0x97, 0x1D, 0x98, 0x1D, 0x99, 0x1D, 0x9A, 0x1D, 0x9B, 0x1D, + 0x9C, 0x1D, 0x9D, 0x1D, 0x9E, 0x1D, 0x9F, 0x1D, 0xA0, 0x1D, 0xA1, 0x1D, 0xA2, 0x1D, 0xA3, 0x1D, + 0xA4, 0x1D, 0xA5, 0x1D, 0xA6, 0x1D, 0xA7, 0x1D, 0xA8, 0x1D, 0xA9, 0x1D, 0xAA, 0x1D, 0xAB, 0x1D, + 0xAC, 0x1D, 0xAD, 0x1D, 0xAE, 0x1D, 0xAF, 0x1D, 0xB0, 0x1D, 0xB1, 0x1D, 0xB2, 0x1D, 0xB3, 0x1D, + 0xB4, 0x1D, 0xB5, 0x1D, 0xB6, 0x1D, 0xB7, 0x1D, 0xB8, 0x1D, 0xB9, 0x1D, 0xBA, 0x1D, 0xBB, 0x1D, + 0xBC, 0x1D, 0xBD, 0x1D, 0xBE, 0x1D, 0xBF, 0x1D, 0xC0, 0x1D, 0xC1, 0x1D, 0xC2, 0x1D, 0xC3, 0x1D, + 0xC4, 0x1D, 0xC5, 0x1D, 0xC6, 0x1D, 0xC7, 0x1D, 0xC8, 0x1D, 0xC9, 0x1D, 0xCA, 0x1D, 0xCB, 0x1D, + 0xCC, 0x1D, 0xCD, 0x1D, 0xCE, 0x1D, 0xCF, 0x1D, 0xD0, 0x1D, 0xD1, 0x1D, 0xD2, 0x1D, 0xD3, 0x1D, + 0xD4, 0x1D, 0xD5, 0x1D, 0xD6, 0x1D, 0xD7, 0x1D, 0xD8, 0x1D, 0xD9, 0x1D, 0xDA, 0x1D, 0xDB, 0x1D, + 0xDC, 0x1D, 0xDD, 0x1D, 0xDE, 0x1D, 0xDF, 0x1D, 0xE0, 0x1D, 0xE1, 0x1D, 0xE2, 0x1D, 0xE3, 0x1D, + 0xE4, 0x1D, 0xE5, 0x1D, 0xE6, 0x1D, 0xE7, 0x1D, 0xE8, 0x1D, 0xE9, 0x1D, 0xEA, 0x1D, 0xEB, 0x1D, + 0xEC, 0x1D, 0xED, 0x1D, 0xEE, 0x1D, 0xEF, 0x1D, 0xF0, 0x1D, 0xF1, 0x1D, 0xF2, 0x1D, 0xF3, 0x1D, + 0xF4, 0x1D, 0xF5, 0x1D, 0xF6, 0x1D, 0xF7, 0x1D, 0xF8, 0x1D, 0xF9, 0x1D, 0xFA, 0x1D, 0xFB, 0x1D, + 0xFC, 0x1D, 0xFD, 0x1D, 0xFE, 0x1D, 0xFF, 0x1D, 0x00, 0x1E, 0x00, 0x1E, 0x02, 0x1E, 0x02, 0x1E, + 0x04, 0x1E, 0x04, 0x1E, 0x06, 0x1E, 0x06, 0x1E, 0x08, 0x1E, 0x08, 0x1E, 0x0A, 0x1E, 0x0A, 0x1E, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0E, 0x1E, 0x0E, 0x1E, 0x10, 0x1E, 0x10, 0x1E, 0x12, 0x1E, 0x12, 0x1E, + 0x14, 0x1E, 0x14, 0x1E, 0x16, 0x1E, 0x16, 0x1E, 0x18, 0x1E, 0x18, 0x1E, 0x1A, 0x1E, 0x1A, 0x1E, + 0x1C, 0x1E, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x20, 0x1E, 0x20, 0x1E, 0x22, 0x1E, 0x22, 0x1E, + 0x24, 0x1E, 0x24, 0x1E, 0x26, 0x1E, 0x26, 0x1E, 0x28, 0x1E, 0x28, 0x1E, 0x2A, 0x1E, 0x2A, 0x1E, + 0x2C, 0x1E, 0x2C, 0x1E, 0x2E, 0x1E, 0x2E, 0x1E, 0x30, 0x1E, 0x30, 0x1E, 0x32, 0x1E, 0x32, 0x1E, + 0x34, 0x1E, 0x34, 0x1E, 0x36, 0x1E, 0x36, 0x1E, 0x38, 0x1E, 0x38, 0x1E, 0x3A, 0x1E, 0x3A, 0x1E, + 0x3C, 0x1E, 0x3C, 0x1E, 0x3E, 0x1E, 0x3E, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x42, 0x1E, 0x42, 0x1E, + 0x44, 0x1E, 0x44, 0x1E, 0x46, 0x1E, 0x46, 0x1E, 0x48, 0x1E, 0x48, 0x1E, 0x4A, 0x1E, 0x4A, 0x1E, + 0x4C, 0x1E, 0x4C, 0x1E, 0x4E, 0x1E, 0x4E, 0x1E, 0x50, 0x1E, 0x50, 0x1E, 0x52, 0x1E, 0x52, 0x1E, + 0x54, 0x1E, 0x54, 0x1E, 0x56, 0x1E, 0x56, 0x1E, 0x58, 0x1E, 0x58, 0x1E, 0x5A, 0x1E, 0x5A, 0x1E, + 0x5C, 0x1E, 0x5C, 0x1E, 0x5E, 0x1E, 0x5E, 0x1E, 0x60, 0x1E, 0x60, 0x1E, 0x62, 0x1E, 0x62, 0x1E, + 0x64, 0x1E, 0x64, 0x1E, 0x66, 0x1E, 0x66, 0x1E, 0x68, 0x1E, 0x68, 0x1E, 0x6A, 0x1E, 0x6A, 0x1E, + 0x6C, 0x1E, 0x6C, 0x1E, 0x6E, 0x1E, 0x6E, 0x1E, 0x70, 0x1E, 0x70, 0x1E, 0x72, 0x1E, 0x72, 0x1E, + 0x74, 0x1E, 0x74, 0x1E, 0x76, 0x1E, 0x76, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x7A, 0x1E, 0x7A, 0x1E, + 0x7C, 0x1E, 0x7C, 0x1E, 0x7E, 0x1E, 0x7E, 0x1E, 0x80, 0x1E, 0x80, 0x1E, 0x82, 0x1E, 0x82, 0x1E, + 0x84, 0x1E, 0x84, 0x1E, 0x86, 0x1E, 0x86, 0x1E, 0x88, 0x1E, 0x88, 0x1E, 0x8A, 0x1E, 0x8A, 0x1E, + 0x8C, 0x1E, 0x8C, 0x1E, 0x8E, 0x1E, 0x8E, 0x1E, 0x90, 0x1E, 0x90, 0x1E, 0x92, 0x1E, 0x92, 0x1E, + 0x94, 0x1E, 0x94, 0x1E, 0x96, 0x1E, 0x97, 0x1E, 0x98, 0x1E, 0x99, 0x1E, 0x9A, 0x1E, 0x9B, 0x1E, + 0x9C, 0x1E, 0x9D, 0x1E, 0x9E, 0x1E, 0x9F, 0x1E, 0xA0, 0x1E, 0xA0, 0x1E, 0xA2, 0x1E, 0xA2, 0x1E, + 0xA4, 0x1E, 0xA4, 0x1E, 0xA6, 0x1E, 0xA6, 0x1E, 0xA8, 0x1E, 0xA8, 0x1E, 0xAA, 0x1E, 0xAA, 0x1E, + 0xAC, 0x1E, 0xAC, 0x1E, 0xAE, 0x1E, 0xAE, 0x1E, 0xB0, 0x1E, 0xB0, 0x1E, 0xB2, 0x1E, 0xB2, 0x1E, + 0xB4, 0x1E, 0xB4, 0x1E, 0xB6, 0x1E, 0xB6, 0x1E, 0xB8, 0x1E, 0xB8, 0x1E, 0xBA, 0x1E, 0xBA, 0x1E, + 0xBC, 0x1E, 0xBC, 0x1E, 0xBE, 0x1E, 0xBE, 0x1E, 0xC0, 0x1E, 0xC0, 0x1E, 0xC2, 0x1E, 0xC2, 0x1E, + 0xC4, 0x1E, 0xC4, 0x1E, 0xC6, 0x1E, 0xC6, 0x1E, 0xC8, 0x1E, 0xC8, 0x1E, 0xCA, 0x1E, 0xCA, 0x1E, + 0xCC, 0x1E, 0xCC, 0x1E, 0xCE, 0x1E, 0xCE, 0x1E, 0xD0, 0x1E, 0xD0, 0x1E, 0xD2, 0x1E, 0xD2, 0x1E, + 0xD4, 0x1E, 0xD4, 0x1E, 0xD6, 0x1E, 0xD6, 0x1E, 0xD8, 0x1E, 0xD8, 0x1E, 0xDA, 0x1E, 0xDA, 0x1E, + 0xDC, 0x1E, 0xDC, 0x1E, 0xDE, 0x1E, 0xDE, 0x1E, 0xE0, 0x1E, 0xE0, 0x1E, 0xE2, 0x1E, 0xE2, 0x1E, + 0xE4, 0x1E, 0xE4, 0x1E, 0xE6, 0x1E, 0xE6, 0x1E, 0xE8, 0x1E, 0xE8, 0x1E, 0xEA, 0x1E, 0xEA, 0x1E, + 0xEC, 0x1E, 0xEC, 0x1E, 0xEE, 0x1E, 0xEE, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF2, 0x1E, 0xF2, 0x1E, + 0xF4, 0x1E, 0xF4, 0x1E, 0xF6, 0x1E, 0xF6, 0x1E, 0xF8, 0x1E, 0xF8, 0x1E, 0xFA, 0x1E, 0xFB, 0x1E, + 0xFC, 0x1E, 0xFD, 0x1E, 0xFE, 0x1E, 0xFF, 0x1E, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, + 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, + 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, + 0x1C, 0x1F, 0x1D, 0x1F, 0x16, 0x1F, 0x17, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, + 0x1C, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, + 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, + 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, + 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, + 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, + 0x4C, 0x1F, 0x4D, 0x1F, 0x46, 0x1F, 0x47, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, + 0x4C, 0x1F, 0x4D, 0x1F, 0x4E, 0x1F, 0x4F, 0x1F, 0x50, 0x1F, 0x59, 0x1F, 0x52, 0x1F, 0x5B, 0x1F, + 0x54, 0x1F, 0x5D, 0x1F, 0x56, 0x1F, 0x5F, 0x1F, 0x58, 0x1F, 0x59, 0x1F, 0x5A, 0x1F, 0x5B, 0x1F, + 0x5C, 0x1F, 0x5D, 0x1F, 0x5E, 0x1F, 0x5F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, + 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, + 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, + 0xCA, 0x1F, 0xCB, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, + 0xFA, 0x1F, 0xFB, 0x1F, 0x7E, 0x1F, 0x7F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, + 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, + 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, + 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, + 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, + 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, + 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xB2, 0x1F, 0xBC, 0x1F, + 0xB4, 0x1F, 0xB5, 0x1F, 0xB6, 0x1F, 0xB7, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, + 0xBC, 0x1F, 0xBD, 0x1F, 0xBE, 0x1F, 0xBF, 0x1F, 0xC0, 0x1F, 0xC1, 0x1F, 0xC2, 0x1F, 0xC3, 0x1F, + 0xC4, 0x1F, 0xC5, 0x1F, 0xC6, 0x1F, 0xC7, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, 0xCA, 0x1F, 0xCB, 0x1F, + 0xC3, 0x1F, 0xCD, 0x1F, 0xCE, 0x1F, 0xCF, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xD2, 0x1F, 0xD3, 0x1F, + 0xD4, 0x1F, 0xD5, 0x1F, 0xD6, 0x1F, 0xD7, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, + 0xDC, 0x1F, 0xDD, 0x1F, 0xDE, 0x1F, 0xDF, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xE2, 0x1F, 0xE3, 0x1F, + 0xE4, 0x1F, 0xEC, 0x1F, 0xE6, 0x1F, 0xE7, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, + 0xEC, 0x1F, 0xED, 0x1F, 0xEE, 0x1F, 0xEF, 0x1F, 0xF0, 0x1F, 0xF1, 0x1F, 0xF2, 0x1F, 0xF3, 0x1F, + 0xF4, 0x1F, 0xF5, 0x1F, 0xF6, 0x1F, 0xF7, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xFA, 0x1F, 0xFB, 0x1F, + 0xF3, 0x1F, 0xFD, 0x1F, 0xFE, 0x1F, 0xFF, 0x1F, 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, + 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x09, 0x20, 0x0A, 0x20, 0x0B, 0x20, + 0x0C, 0x20, 0x0D, 0x20, 0x0E, 0x20, 0x0F, 0x20, 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, + 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, 0x18, 0x20, 0x19, 0x20, 0x1A, 0x20, 0x1B, 0x20, + 0x1C, 0x20, 0x1D, 0x20, 0x1E, 0x20, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, + 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, 0x28, 0x20, 0x29, 0x20, 0x2A, 0x20, 0x2B, 0x20, + 0x2C, 0x20, 0x2D, 0x20, 0x2E, 0x20, 0x2F, 0x20, 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, + 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, 0x38, 0x20, 0x39, 0x20, 0x3A, 0x20, 0x3B, 0x20, + 0x3C, 0x20, 0x3D, 0x20, 0x3E, 0x20, 0x3F, 0x20, 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, + 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, 0x48, 0x20, 0x49, 0x20, 0x4A, 0x20, 0x4B, 0x20, + 0x4C, 0x20, 0x4D, 0x20, 0x4E, 0x20, 0x4F, 0x20, 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, + 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, 0x58, 0x20, 0x59, 0x20, 0x5A, 0x20, 0x5B, 0x20, + 0x5C, 0x20, 0x5D, 0x20, 0x5E, 0x20, 0x5F, 0x20, 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, + 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, 0x68, 0x20, 0x69, 0x20, 0x6A, 0x20, 0x6B, 0x20, + 0x6C, 0x20, 0x6D, 0x20, 0x6E, 0x20, 0x6F, 0x20, 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, + 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, 0x78, 0x20, 0x79, 0x20, 0x7A, 0x20, 0x7B, 0x20, + 0x7C, 0x20, 0x7D, 0x20, 0x7E, 0x20, 0x7F, 0x20, 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, + 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x8A, 0x20, 0x8B, 0x20, + 0x8C, 0x20, 0x8D, 0x20, 0x8E, 0x20, 0x8F, 0x20, 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, + 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, 0x98, 0x20, 0x99, 0x20, 0x9A, 0x20, 0x9B, 0x20, + 0x9C, 0x20, 0x9D, 0x20, 0x9E, 0x20, 0x9F, 0x20, 0xA0, 0x20, 0xA1, 0x20, 0xA2, 0x20, 0xA3, 0x20, + 0xA4, 0x20, 0xA5, 0x20, 0xA6, 0x20, 0xA7, 0x20, 0xA8, 0x20, 0xA9, 0x20, 0xAA, 0x20, 0xAB, 0x20, + 0xAC, 0x20, 0xAD, 0x20, 0xAE, 0x20, 0xAF, 0x20, 0xB0, 0x20, 0xB1, 0x20, 0xB2, 0x20, 0xB3, 0x20, + 0xB4, 0x20, 0xB5, 0x20, 0xB6, 0x20, 0xB7, 0x20, 0xB8, 0x20, 0xB9, 0x20, 0xBA, 0x20, 0xBB, 0x20, + 0xBC, 0x20, 0xBD, 0x20, 0xBE, 0x20, 0xBF, 0x20, 0xC0, 0x20, 0xC1, 0x20, 0xC2, 0x20, 0xC3, 0x20, + 0xC4, 0x20, 0xC5, 0x20, 0xC6, 0x20, 0xC7, 0x20, 0xC8, 0x20, 0xC9, 0x20, 0xCA, 0x20, 0xCB, 0x20, + 0xCC, 0x20, 0xCD, 0x20, 0xCE, 0x20, 0xCF, 0x20, 0xD0, 0x20, 0xD1, 0x20, 0xD2, 0x20, 0xD3, 0x20, + 0xD4, 0x20, 0xD5, 0x20, 0xD6, 0x20, 0xD7, 0x20, 0xD8, 0x20, 0xD9, 0x20, 0xDA, 0x20, 0xDB, 0x20, + 0xDC, 0x20, 0xDD, 0x20, 0xDE, 0x20, 0xDF, 0x20, 0xE0, 0x20, 0xE1, 0x20, 0xE2, 0x20, 0xE3, 0x20, + 0xE4, 0x20, 0xE5, 0x20, 0xE6, 0x20, 0xE7, 0x20, 0xE8, 0x20, 0xE9, 0x20, 0xEA, 0x20, 0xEB, 0x20, + 0xEC, 0x20, 0xED, 0x20, 0xEE, 0x20, 0xEF, 0x20, 0xF0, 0x20, 0xF1, 0x20, 0xF2, 0x20, 0xF3, 0x20, + 0xF4, 0x20, 0xF5, 0x20, 0xF6, 0x20, 0xF7, 0x20, 0xF8, 0x20, 0xF9, 0x20, 0xFA, 0x20, 0xFB, 0x20, + 0xFC, 0x20, 0xFD, 0x20, 0xFE, 0x20, 0xFF, 0x20, 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, + 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, 0x08, 0x21, 0x09, 0x21, 0x0A, 0x21, 0x0B, 0x21, + 0x0C, 0x21, 0x0D, 0x21, 0x0E, 0x21, 0x0F, 0x21, 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, + 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, 0x18, 0x21, 0x19, 0x21, 0x1A, 0x21, 0x1B, 0x21, + 0x1C, 0x21, 0x1D, 0x21, 0x1E, 0x21, 0x1F, 0x21, 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, + 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, 0x28, 0x21, 0x29, 0x21, 0x2A, 0x21, 0x2B, 0x21, + 0x2C, 0x21, 0x2D, 0x21, 0x2E, 0x21, 0x2F, 0x21, 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, + 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, 0x38, 0x21, 0x39, 0x21, 0x3A, 0x21, 0x3B, 0x21, + 0x3C, 0x21, 0x3D, 0x21, 0x3E, 0x21, 0x3F, 0x21, 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, + 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, 0x48, 0x21, 0x49, 0x21, 0x4A, 0x21, 0x4B, 0x21, + 0x4C, 0x21, 0x4D, 0x21, 0x32, 0x21, 0x4F, 0x21, 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, + 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, 0x58, 0x21, 0x59, 0x21, 0x5A, 0x21, 0x5B, 0x21, + 0x5C, 0x21, 0x5D, 0x21, 0x5E, 0x21, 0x5F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, + 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, + 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, + 0x83, 0x21, 0xFF, 0xFF, 0x4B, 0x03, 0xB6, 0x24, 0xB7, 0x24, 0xB8, 0x24, 0xB9, 0x24, 0xBA, 0x24, + 0xBB, 0x24, 0xBC, 0x24, 0xBD, 0x24, 0xBE, 0x24, 0xBF, 0x24, 0xC0, 0x24, 0xC1, 0x24, 0xC2, 0x24, + 0xC3, 0x24, 0xC4, 0x24, 0xC5, 0x24, 0xC6, 0x24, 0xC7, 0x24, 0xC8, 0x24, 0xC9, 0x24, 0xCA, 0x24, + 0xCB, 0x24, 0xCC, 0x24, 0xCD, 0x24, 0xCE, 0x24, 0xCF, 0x24, 0xFF, 0xFF, 0x46, 0x07, 0x00, 0x2C, + 0x01, 0x2C, 0x02, 0x2C, 0x03, 0x2C, 0x04, 0x2C, 0x05, 0x2C, 0x06, 0x2C, 0x07, 0x2C, 0x08, 0x2C, + 0x09, 0x2C, 0x0A, 0x2C, 0x0B, 0x2C, 0x0C, 0x2C, 0x0D, 0x2C, 0x0E, 0x2C, 0x0F, 0x2C, 0x10, 0x2C, + 0x11, 0x2C, 0x12, 0x2C, 0x13, 0x2C, 0x14, 0x2C, 0x15, 0x2C, 0x16, 0x2C, 0x17, 0x2C, 0x18, 0x2C, + 0x19, 0x2C, 0x1A, 0x2C, 0x1B, 0x2C, 0x1C, 0x2C, 0x1D, 0x2C, 0x1E, 0x2C, 0x1F, 0x2C, 0x20, 0x2C, + 0x21, 0x2C, 0x22, 0x2C, 0x23, 0x2C, 0x24, 0x2C, 0x25, 0x2C, 0x26, 0x2C, 0x27, 0x2C, 0x28, 0x2C, + 0x29, 0x2C, 0x2A, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2C, 0x2E, 0x2C, 0x5F, 0x2C, 0x60, 0x2C, + 0x60, 0x2C, 0x62, 0x2C, 0x63, 0x2C, 0x64, 0x2C, 0x65, 0x2C, 0x66, 0x2C, 0x67, 0x2C, 0x67, 0x2C, + 0x69, 0x2C, 0x69, 0x2C, 0x6B, 0x2C, 0x6B, 0x2C, 0x6D, 0x2C, 0x6E, 0x2C, 0x6F, 0x2C, 0x70, 0x2C, + 0x71, 0x2C, 0x72, 0x2C, 0x73, 0x2C, 0x74, 0x2C, 0x75, 0x2C, 0x75, 0x2C, 0x77, 0x2C, 0x78, 0x2C, + 0x79, 0x2C, 0x7A, 0x2C, 0x7B, 0x2C, 0x7C, 0x2C, 0x7D, 0x2C, 0x7E, 0x2C, 0x7F, 0x2C, 0x80, 0x2C, + 0x80, 0x2C, 0x82, 0x2C, 0x82, 0x2C, 0x84, 0x2C, 0x84, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x88, 0x2C, + 0x88, 0x2C, 0x8A, 0x2C, 0x8A, 0x2C, 0x8C, 0x2C, 0x8C, 0x2C, 0x8E, 0x2C, 0x8E, 0x2C, 0x90, 0x2C, + 0x90, 0x2C, 0x92, 0x2C, 0x92, 0x2C, 0x94, 0x2C, 0x94, 0x2C, 0x96, 0x2C, 0x96, 0x2C, 0x98, 0x2C, + 0x98, 0x2C, 0x9A, 0x2C, 0x9A, 0x2C, 0x9C, 0x2C, 0x9C, 0x2C, 0x9E, 0x2C, 0x9E, 0x2C, 0xA0, 0x2C, + 0xA0, 0x2C, 0xA2, 0x2C, 0xA2, 0x2C, 0xA4, 0x2C, 0xA4, 0x2C, 0xA6, 0x2C, 0xA6, 0x2C, 0xA8, 0x2C, + 0xA8, 0x2C, 0xAA, 0x2C, 0xAA, 0x2C, 0xAC, 0x2C, 0xAC, 0x2C, 0xAE, 0x2C, 0xAE, 0x2C, 0xB0, 0x2C, + 0xB0, 0x2C, 0xB2, 0x2C, 0xB2, 0x2C, 0xB4, 0x2C, 0xB4, 0x2C, 0xB6, 0x2C, 0xB6, 0x2C, 0xB8, 0x2C, + 0xB8, 0x2C, 0xBA, 0x2C, 0xBA, 0x2C, 0xBC, 0x2C, 0xBC, 0x2C, 0xBE, 0x2C, 0xBE, 0x2C, 0xC0, 0x2C, + 0xC0, 0x2C, 0xC2, 0x2C, 0xC2, 0x2C, 0xC4, 0x2C, 0xC4, 0x2C, 0xC6, 0x2C, 0xC6, 0x2C, 0xC8, 0x2C, + 0xC8, 0x2C, 0xCA, 0x2C, 0xCA, 0x2C, 0xCC, 0x2C, 0xCC, 0x2C, 0xCE, 0x2C, 0xCE, 0x2C, 0xD0, 0x2C, + 0xD0, 0x2C, 0xD2, 0x2C, 0xD2, 0x2C, 0xD4, 0x2C, 0xD4, 0x2C, 0xD6, 0x2C, 0xD6, 0x2C, 0xD8, 0x2C, + 0xD8, 0x2C, 0xDA, 0x2C, 0xDA, 0x2C, 0xDC, 0x2C, 0xDC, 0x2C, 0xDE, 0x2C, 0xDE, 0x2C, 0xE0, 0x2C, + 0xE0, 0x2C, 0xE2, 0x2C, 0xE2, 0x2C, 0xE4, 0x2C, 0xE5, 0x2C, 0xE6, 0x2C, 0xE7, 0x2C, 0xE8, 0x2C, + 0xE9, 0x2C, 0xEA, 0x2C, 0xEB, 0x2C, 0xEC, 0x2C, 0xED, 0x2C, 0xEE, 0x2C, 0xEF, 0x2C, 0xF0, 0x2C, + 0xF1, 0x2C, 0xF2, 0x2C, 0xF3, 0x2C, 0xF4, 0x2C, 0xF5, 0x2C, 0xF6, 0x2C, 0xF7, 0x2C, 0xF8, 0x2C, + 0xF9, 0x2C, 0xFA, 0x2C, 0xFB, 0x2C, 0xFC, 0x2C, 0xFD, 0x2C, 0xFE, 0x2C, 0xFF, 0x2C, 0xA0, 0x10, + 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, + 0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10, + 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, + 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, + 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xFF, 0xFF, 0x1B, 0xD2, 0x21, 0xFF, + 0x22, 0xFF, 0x23, 0xFF, 0x24, 0xFF, 0x25, 0xFF, 0x26, 0xFF, 0x27, 0xFF, 0x28, 0xFF, 0x29, 0xFF, + 0x2A, 0xFF, 0x2B, 0xFF, 0x2C, 0xFF, 0x2D, 0xFF, 0x2E, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0x31, 0xFF, + 0x32, 0xFF, 0x33, 0xFF, 0x34, 0xFF, 0x35, 0xFF, 0x36, 0xFF, 0x37, 0xFF, 0x38, 0xFF, 0x39, 0xFF, + 0x3A, 0xFF, 0x5B, 0xFF, 0x5C, 0xFF, 0x5D, 0xFF, 0x5E, 0xFF, 0x5F, 0xFF, 0x60, 0xFF, 0x61, 0xFF, + 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, 0x66, 0xFF, 0x67, 0xFF, 0x68, 0xFF, 0x69, 0xFF, + 0x6A, 0xFF, 0x6B, 0xFF, 0x6C, 0xFF, 0x6D, 0xFF, 0x6E, 0xFF, 0x6F, 0xFF, 0x70, 0xFF, 0x71, 0xFF, + 0x72, 0xFF, 0x73, 0xFF, 0x74, 0xFF, 0x75, 0xFF, 0x76, 0xFF, 0x77, 0xFF, 0x78, 0xFF, 0x79, 0xFF, + 0x7A, 0xFF, 0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0xFF, 0x7E, 0xFF, 0x7F, 0xFF, 0x80, 0xFF, 0x81, 0xFF, + 0x82, 0xFF, 0x83, 0xFF, 0x84, 0xFF, 0x85, 0xFF, 0x86, 0xFF, 0x87, 0xFF, 0x88, 0xFF, 0x89, 0xFF, + 0x8A, 0xFF, 0x8B, 0xFF, 0x8C, 0xFF, 0x8D, 0xFF, 0x8E, 0xFF, 0x8F, 0xFF, 0x90, 0xFF, 0x91, 0xFF, + 0x92, 0xFF, 0x93, 0xFF, 0x94, 0xFF, 0x95, 0xFF, 0x96, 0xFF, 0x97, 0xFF, 0x98, 0xFF, 0x99, 0xFF, + 0x9A, 0xFF, 0x9B, 0xFF, 0x9C, 0xFF, 0x9D, 0xFF, 0x9E, 0xFF, 0x9F, 0xFF, 0xA0, 0xFF, 0xA1, 0xFF, + 0xA2, 0xFF, 0xA3, 0xFF, 0xA4, 0xFF, 0xA5, 0xFF, 0xA6, 0xFF, 0xA7, 0xFF, 0xA8, 0xFF, 0xA9, 0xFF, + 0xAA, 0xFF, 0xAB, 0xFF, 0xAC, 0xFF, 0xAD, 0xFF, 0xAE, 0xFF, 0xAF, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, + 0xB2, 0xFF, 0xB3, 0xFF, 0xB4, 0xFF, 0xB5, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB8, 0xFF, 0xB9, 0xFF, + 0xBA, 0xFF, 0xBB, 0xFF, 0xBC, 0xFF, 0xBD, 0xFF, 0xBE, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF, + 0xC2, 0xFF, 0xC3, 0xFF, 0xC4, 0xFF, 0xC5, 0xFF, 0xC6, 0xFF, 0xC7, 0xFF, 0xC8, 0xFF, 0xC9, 0xFF, + 0xCA, 0xFF, 0xCB, 0xFF, 0xCC, 0xFF, 0xCD, 0xFF, 0xCE, 0xFF, 0xCF, 0xFF, 0xD0, 0xFF, 0xD1, 0xFF, + 0xD2, 0xFF, 0xD3, 0xFF, 0xD4, 0xFF, 0xD5, 0xFF, 0xD6, 0xFF, 0xD7, 0xFF, 0xD8, 0xFF, 0xD9, 0xFF, + 0xDA, 0xFF, 0xDB, 0xFF, 0xDC, 0xFF, 0xDD, 0xFF, 0xDE, 0xFF, 0xDF, 0xFF, 0xE0, 0xFF, 0xE1, 0xFF, + 0xE2, 0xFF, 0xE3, 0xFF, 0xE4, 0xFF, 0xE5, 0xFF, 0xE6, 0xFF, 0xE7, 0xFF, 0xE8, 0xFF, 0xE9, 0xFF, + 0xEA, 0xFF, 0xEB, 0xFF, 0xEC, 0xFF, 0xED, 0xFF, 0xEE, 0xFF, 0xEF, 0xFF, 0xF0, 0xFF, 0xF1, 0xFF, + 0xF2, 0xFF, 0xF3, 0xFF, 0xF4, 0xFF, 0xF5, 0xFF, 0xF6, 0xFF, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xFF, + 0xFA, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF +}; diff --git a/fs/exfat/exfat_version.h b/fs/exfat/exfat_version.h new file mode 100755 index 0000000000000..cf653815a7a65 --- /dev/null +++ b/fs/exfat/exfat_version.h @@ -0,0 +1 @@ +#define EXFAT_VERSION "1.2.12" diff --git a/fs/exfat/exfat_xattr.c b/fs/exfat/exfat_xattr.c new file mode 100755 index 0000000000000..470333e362776 --- /dev/null +++ b/fs/exfat/exfat_xattr.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include "exfat.h" + +#ifndef CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL +#define CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL ("undefined") +#endif + +static const char default_xattr[] = CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL; + +int exfat_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + return 0; +} + +ssize_t exfat_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { + if (size > strlen(default_xattr)+1 && value) + strcpy(value, default_xattr); + return strlen(default_xattr); +} + +ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size) { + return 0; +} + +int exfat_removexattr(struct dentry *dentry, const char *name) { + return 0; +} + + diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index fd27e7e6326e6..05f0f663f14ca 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -1,5 +1,5 @@ config F2FS_FS - tristate "F2FS filesystem support (EXPERIMENTAL)" + tristate "F2FS filesystem support" depends on BLOCK help F2FS is based on Log-structured File System (LFS), which supports @@ -23,7 +23,7 @@ config F2FS_STAT_FS mounted as f2fs. Each file shows the whole f2fs information. /sys/kernel/debug/f2fs/status includes: - - major file system information managed by f2fs currently + - major filesystem information managed by f2fs currently - average SIT information about whole segments - current memory footprint consumed by f2fs. @@ -51,3 +51,33 @@ config F2FS_FS_POSIX_ACL Linux website . If you don't know what Access Control Lists are, say N + +config F2FS_FS_SECURITY + bool "F2FS Security Labels" + depends on F2FS_FS_XATTR + help + Security labels provide an access control facility to support Linux + Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO + Linux. This option enables an extended attribute handler for file + security labels in the f2fs filesystem, so that it requires enabling + the extended attribute support in advance. + + If you are not using a security module, say N. + +config F2FS_CHECK_FS + bool "F2FS consistency checking feature" + depends on F2FS_FS + help + Enables BUG_ONs which check the filesystem consistency in runtime. + + If you want to improve the performance, say N. + +config F2FS_IO_TRACE + bool "F2FS IO tracer" + depends on F2FS_FS + depends on FUNCTION_TRACER + help + F2FS IO trace is based on a function trace, which gathers process + information and block IO patterns in the filesystem level. + + If unsure, say N. diff --git a/fs/f2fs/Makefile b/fs/f2fs/Makefile index 27a0820340b9f..d92397731db84 100644 --- a/fs/f2fs/Makefile +++ b/fs/f2fs/Makefile @@ -1,7 +1,8 @@ obj-$(CONFIG_F2FS_FS) += f2fs.o -f2fs-y := dir.o file.o inode.o namei.o hash.o super.o +f2fs-y := dir.o file.o inode.o namei.o hash.o super.o inline.o f2fs-y += checkpoint.o gc.o data.o node.o segment.o recovery.o f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o +f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 44abc2f286e00..5b952c05903f4 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -17,9 +17,6 @@ #include "xattr.h" #include "acl.h" -#define get_inode_mode(i) ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ - (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) - static inline size_t f2fs_acl_size(int count) { if (count <= 4) { @@ -65,7 +62,7 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size) if (count == 0) return NULL; - acl = posix_acl_alloc(count, GFP_KERNEL); + acl = posix_acl_alloc(count, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); @@ -119,7 +116,7 @@ static void *f2fs_acl_to_disk(const struct posix_acl *acl, size_t *size) int i; f2fs_acl = kmalloc(sizeof(struct f2fs_acl_header) + acl->a_count * - sizeof(struct f2fs_acl_entry), GFP_KERNEL); + sizeof(struct f2fs_acl_entry), GFP_NOFS); if (!f2fs_acl) return ERR_PTR(-ENOMEM); @@ -165,7 +162,8 @@ static void *f2fs_acl_to_disk(const struct posix_acl *acl, size_t *size) return ERR_PTR(-EINVAL); } -struct posix_acl *f2fs_get_acl(struct inode *inode, int type) +static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type, + struct page *dpage) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT; @@ -183,12 +181,13 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) if (type == ACL_TYPE_ACCESS) name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; - retval = f2fs_getxattr(inode, name_index, "", NULL, 0); + retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage); if (retval > 0) { - value = kmalloc(retval, GFP_KERNEL); + value = kmalloc(retval, GFP_F2FS_ZERO); if (!value) return ERR_PTR(-ENOMEM); - retval = f2fs_getxattr(inode, name_index, "", value, retval); + retval = f2fs_getxattr(inode, name_index, "", value, + retval, dpage); } if (retval > 0) @@ -205,7 +204,13 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) return acl; } -static int f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl) +struct posix_acl *f2fs_get_acl(struct inode *inode, int type) +{ + return __f2fs_get_acl(inode, type, NULL); +} + +static int f2fs_set_acl(struct inode *inode, int type, + struct posix_acl *acl, struct page *ipage) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct f2fs_inode_info *fi = F2FS_I(inode); @@ -245,30 +250,31 @@ static int f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (acl) { value = f2fs_acl_to_disk(acl, &size); if (IS_ERR(value)) { - cond_clear_inode_flag(fi, FI_ACL_MODE); + clear_inode_flag(fi, FI_ACL_MODE); return (int)PTR_ERR(value); } } - error = f2fs_setxattr(inode, name_index, "", value, size); + error = f2fs_setxattr(inode, name_index, "", value, size, ipage, 0); kfree(value); if (!error) set_cached_acl(inode, type, acl); - cond_clear_inode_flag(fi, FI_ACL_MODE); + clear_inode_flag(fi, FI_ACL_MODE); return error; } -int f2fs_init_acl(struct inode *inode, struct inode *dir) +int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage, + struct page *dpage) { - struct posix_acl *acl = NULL; struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct posix_acl *acl = NULL; int error = 0; if (!S_ISLNK(inode->i_mode)) { if (test_opt(sbi, POSIX_ACL)) { - acl = f2fs_get_acl(dir, ACL_TYPE_DEFAULT); + acl = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); if (IS_ERR(acl)) return PTR_ERR(acl); } @@ -276,19 +282,19 @@ int f2fs_init_acl(struct inode *inode, struct inode *dir) inode->i_mode &= ~current_umask(); } - if (test_opt(sbi, POSIX_ACL) && acl) { + if (!test_opt(sbi, POSIX_ACL) || !acl) + goto cleanup; - if (S_ISDIR(inode->i_mode)) { - error = f2fs_set_acl(inode, ACL_TYPE_DEFAULT, acl); - if (error) - goto cleanup; - } - error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); - if (error < 0) - return error; - if (error > 0) - error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl); + if (S_ISDIR(inode->i_mode)) { + error = f2fs_set_acl(inode, ACL_TYPE_DEFAULT, acl, ipage); + if (error) + goto cleanup; } + error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); + if (error < 0) + return error; + if (error > 0) + error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, ipage); cleanup: posix_acl_release(acl); return error; @@ -313,7 +319,8 @@ int f2fs_acl_chmod(struct inode *inode) error = posix_acl_chmod(&acl, GFP_KERNEL, mode); if (error) return error; - error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl); + + error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, NULL); posix_acl_release(acl); return error; } @@ -388,7 +395,7 @@ static int f2fs_xattr_set_acl(struct dentry *dentry, const char *name, acl = NULL; } - error = f2fs_set_acl(inode, type, acl); + error = f2fs_set_acl(inode, type, acl, NULL); release_and_out: posix_acl_release(acl); diff --git a/fs/f2fs/acl.h b/fs/f2fs/acl.h index 80f430674417a..b4ba6866822ea 100644 --- a/fs/f2fs/acl.h +++ b/fs/f2fs/acl.h @@ -36,9 +36,10 @@ struct f2fs_acl_header { #ifdef CONFIG_F2FS_FS_POSIX_ACL -extern struct posix_acl *f2fs_get_acl(struct inode *inode, int type); -extern int f2fs_acl_chmod(struct inode *inode); -extern int f2fs_init_acl(struct inode *inode, struct inode *dir); +extern struct posix_acl *f2fs_get_acl(struct inode *, int); +extern int f2fs_acl_chmod(struct inode *); +extern int f2fs_init_acl(struct inode *, struct inode *, struct page *, + struct page *); #else #define f2fs_check_acl NULL #define f2fs_get_acl NULL @@ -49,7 +50,8 @@ static inline int f2fs_acl_chmod(struct inode *inode) return 0; } -static inline int f2fs_init_acl(struct inode *inode, struct inode *dir) +static inline int f2fs_init_acl(struct inode *inode, struct inode *dir, + struct page *ipage, struct page *dpage) { return 0; } diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index b1de01da1a409..7b20cf0643380 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -20,17 +20,18 @@ #include "f2fs.h" #include "node.h" #include "segment.h" +#include "trace.h" #include -static struct kmem_cache *orphan_entry_slab; -static struct kmem_cache *inode_entry_slab; +static struct kmem_cache *ino_entry_slab; +struct kmem_cache *inode_entry_slab; /* * We guarantee no failure on the returned page. */ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) { - struct address_space *mapping = sbi->meta_inode->i_mapping; + struct address_space *mapping = META_MAPPING(sbi); struct page *page = NULL; repeat: page = grab_cache_page(mapping, index); @@ -38,9 +39,7 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) cond_resched(); goto repeat; } - - /* We wait writeback only inside grab_meta_page() */ - wait_on_page_writeback(page); + f2fs_wait_on_page_writeback(page, META); SetPageUptodate(page); return page; } @@ -50,8 +49,13 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) */ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) { - struct address_space *mapping = sbi->meta_inode->i_mapping; + struct address_space *mapping = META_MAPPING(sbi); struct page *page; + struct f2fs_io_info fio = { + .type = META, + .rw = READ_SYNC | REQ_META | REQ_PRIO, + .blk_addr = index, + }; repeat: page = grab_cache_page(mapping, index); if (!page) { @@ -61,11 +65,11 @@ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) if (PageUptodate(page)) goto out; - if (f2fs_readpage(sbi, page, index, READ_SYNC)) + if (f2fs_submit_page_bio(sbi, page, &fio)) goto repeat; lock_page(page); - if (page->mapping != mapping) { + if (unlikely(page->mapping != mapping)) { f2fs_put_page(page, 1); goto repeat; } @@ -74,54 +78,170 @@ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) return page; } +static inline bool is_valid_blkaddr(struct f2fs_sb_info *sbi, + block_t blkaddr, int type) +{ + switch (type) { + case META_NAT: + break; + case META_SIT: + if (unlikely(blkaddr >= SIT_BLK_CNT(sbi))) + return false; + break; + case META_SSA: + if (unlikely(blkaddr >= MAIN_BLKADDR(sbi) || + blkaddr < SM_I(sbi)->ssa_blkaddr)) + return false; + break; + case META_CP: + if (unlikely(blkaddr >= SIT_I(sbi)->sit_base_addr || + blkaddr < __start_cp_addr(sbi))) + return false; + break; + case META_POR: + if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || + blkaddr < MAIN_BLKADDR(sbi))) + return false; + break; + default: + BUG(); + } + + return true; +} + +/* + * Readahead CP/NAT/SIT/SSA pages + */ +int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type) +{ + block_t prev_blk_addr = 0; + struct page *page; + block_t blkno = start; + struct f2fs_io_info fio = { + .type = META, + .rw = READ_SYNC | REQ_META | REQ_PRIO + }; + + for (; nrpages-- > 0; blkno++) { + + if (!is_valid_blkaddr(sbi, blkno, type)) + goto out; + + switch (type) { + case META_NAT: + if (unlikely(blkno >= + NAT_BLOCK_OFFSET(NM_I(sbi)->max_nid))) + blkno = 0; + /* get nat block addr */ + fio.blk_addr = current_nat_addr(sbi, + blkno * NAT_ENTRY_PER_BLOCK); + break; + case META_SIT: + /* get sit block addr */ + fio.blk_addr = current_sit_addr(sbi, + blkno * SIT_ENTRY_PER_BLOCK); + if (blkno != start && prev_blk_addr + 1 != fio.blk_addr) + goto out; + prev_blk_addr = fio.blk_addr; + break; + case META_SSA: + case META_CP: + case META_POR: + fio.blk_addr = blkno; + break; + default: + BUG(); + } + + page = grab_cache_page(META_MAPPING(sbi), fio.blk_addr); + if (!page) + continue; + if (PageUptodate(page)) { + f2fs_put_page(page, 1); + continue; + } + + f2fs_submit_page_mbio(sbi, page, &fio); + f2fs_put_page(page, 0); + } +out: + f2fs_submit_merged_bio(sbi, META, READ); + return blkno - start; +} + +void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) +{ + struct page *page; + bool readahead = false; + + page = find_get_page(META_MAPPING(sbi), index); + if (!page || (page && !PageUptodate(page))) + readahead = true; + f2fs_put_page(page, 0); + + if (readahead) + ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR); +} + static int f2fs_write_meta_page(struct page *page, struct writeback_control *wbc) { - struct inode *inode = page->mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_P_SB(page); - /* Should not write any meta pages, if any IO error was occurred */ - if (wbc->for_reclaim || - is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)) { - dec_page_count(sbi, F2FS_DIRTY_META); - wbc->pages_skipped++; - set_page_dirty(page); - return AOP_WRITEPAGE_ACTIVATE; - } + trace_f2fs_writepage(page, META); - wait_on_page_writeback(page); + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) + goto redirty_out; + if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0)) + goto redirty_out; + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; + f2fs_wait_on_page_writeback(page, META); write_meta_page(sbi, page); dec_page_count(sbi, F2FS_DIRTY_META); unlock_page(page); + + if (wbc->for_reclaim) + f2fs_submit_merged_bio(sbi, META, WRITE); return 0; + +redirty_out: + redirty_page_for_writepage(wbc, page); + return AOP_WRITEPAGE_ACTIVATE; } static int f2fs_write_meta_pages(struct address_space *mapping, struct writeback_control *wbc) { - struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); - struct block_device *bdev = sbi->sb->s_bdev; - long written; + struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + long diff, written; - if (wbc->for_kupdate) - return 0; + trace_f2fs_writepages(mapping->host, wbc, META); - if (get_pages(sbi, F2FS_DIRTY_META) == 0) - return 0; + /* collect a number of dirty meta pages and write together */ + if (wbc->for_kupdate || + get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META)) + goto skip_write; /* if mounting is failed, skip writing node pages */ mutex_lock(&sbi->cp_mutex); - written = sync_meta_pages(sbi, META, bio_get_nr_vecs(bdev)); + diff = nr_pages_to_write(sbi, META, wbc); + written = sync_meta_pages(sbi, META, wbc->nr_to_write); mutex_unlock(&sbi->cp_mutex); - wbc->nr_to_write -= written; + wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); + return 0; + +skip_write: + wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_META); return 0; } long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, long nr_to_write) { - struct address_space *mapping = sbi->meta_inode->i_mapping; + struct address_space *mapping = META_MAPPING(sbi); pgoff_t index = 0, end = LONG_MAX; struct pagevec pvec; long nwritten = 0; @@ -136,20 +256,33 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY, min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); - if (nr_pages == 0) + if (unlikely(nr_pages == 0)) break; for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; + lock_page(page); - BUG_ON(page->mapping != mapping); - BUG_ON(!PageDirty(page)); - clear_page_dirty_for_io(page); - if (f2fs_write_meta_page(page, &wbc)) { + + if (unlikely(page->mapping != mapping)) { +continue_unlock: + unlock_page(page); + continue; + } + if (!PageDirty(page)) { + /* someone wrote it for us */ + goto continue_unlock; + } + + if (!clear_page_dirty_for_io(page)) + goto continue_unlock; + + if (mapping->a_ops->writepage(page, &wbc)) { unlock_page(page); break; } - if (nwritten++ >= nr_to_write) + nwritten++; + if (unlikely(nwritten >= nr_to_write)) break; } pagevec_release(&pvec); @@ -157,20 +290,21 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, } if (nwritten) - f2fs_submit_bio(sbi, type, nr_to_write == LONG_MAX); + f2fs_submit_merged_bio(sbi, type, WRITE); return nwritten; } static int f2fs_set_meta_page_dirty(struct page *page) { - struct address_space *mapping = page->mapping; - struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); + trace_f2fs_set_page_dirty(page, META); SetPageUptodate(page); if (!PageDirty(page)) { __set_page_dirty_nobuffers(page); - inc_page_count(sbi, F2FS_DIRTY_META); + inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); + SetPagePrivate(page); + f2fs_trace_pid(page); return 1; } return 0; @@ -180,102 +314,170 @@ const struct address_space_operations f2fs_meta_aops = { .writepage = f2fs_write_meta_page, .writepages = f2fs_write_meta_pages, .set_page_dirty = f2fs_set_meta_page_dirty, + .invalidatepage = f2fs_invalidate_page, + .releasepage = f2fs_release_page, }; -int check_orphan_space(struct f2fs_sb_info *sbi) +static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { - unsigned int max_orphans; - int err = 0; + struct inode_management *im = &sbi->im[type]; + struct ino_entry *e; +retry: + if (radix_tree_preload(GFP_NOFS)) { + cond_resched(); + goto retry; + } - /* - * considering 512 blocks in a segment 5 blocks are needed for cp - * and log segment summaries. Remaining blocks are used to keep - * orphan entries with the limitation one reserved segment - * for cp pack we can have max 1020*507 orphan entries - */ - max_orphans = (sbi->blocks_per_seg - 5) * F2FS_ORPHANS_PER_BLOCK; - mutex_lock(&sbi->orphan_inode_mutex); - if (sbi->n_orphans >= max_orphans) - err = -ENOSPC; - mutex_unlock(&sbi->orphan_inode_mutex); - return err; + spin_lock(&im->ino_lock); + + e = radix_tree_lookup(&im->ino_root, ino); + if (!e) { + e = kmem_cache_alloc(ino_entry_slab, GFP_ATOMIC); + if (!e) { + spin_unlock(&im->ino_lock); + radix_tree_preload_end(); + goto retry; + } + if (radix_tree_insert(&im->ino_root, ino, e)) { + spin_unlock(&im->ino_lock); + kmem_cache_free(ino_entry_slab, e); + radix_tree_preload_end(); + goto retry; + } + memset(e, 0, sizeof(struct ino_entry)); + e->ino = ino; + + list_add_tail(&e->list, &im->ino_list); + if (type != ORPHAN_INO) + im->ino_num++; + } + spin_unlock(&im->ino_lock); + radix_tree_preload_end(); } -void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) +static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { - struct list_head *head, *this; - struct orphan_inode_entry *new = NULL, *orphan = NULL; - - mutex_lock(&sbi->orphan_inode_mutex); - head = &sbi->orphan_inode_list; - list_for_each(this, head) { - orphan = list_entry(this, struct orphan_inode_entry, list); - if (orphan->ino == ino) - goto out; - if (orphan->ino > ino) - break; - orphan = NULL; + struct inode_management *im = &sbi->im[type]; + struct ino_entry *e; + + spin_lock(&im->ino_lock); + e = radix_tree_lookup(&im->ino_root, ino); + if (e) { + list_del(&e->list); + radix_tree_delete(&im->ino_root, ino); + im->ino_num--; + spin_unlock(&im->ino_lock); + kmem_cache_free(ino_entry_slab, e); + return; } -retry: - new = kmem_cache_alloc(orphan_entry_slab, GFP_ATOMIC); - if (!new) { - cond_resched(); - goto retry; + spin_unlock(&im->ino_lock); +} + +void add_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) +{ + /* add new dirty ino entry into list */ + __add_ino_entry(sbi, ino, type); +} + +void remove_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) +{ + /* remove dirty ino entry from list */ + __remove_ino_entry(sbi, ino, type); +} + +/* mode should be APPEND_INO or UPDATE_INO */ +bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) +{ + struct inode_management *im = &sbi->im[mode]; + struct ino_entry *e; + + spin_lock(&im->ino_lock); + e = radix_tree_lookup(&im->ino_root, ino); + spin_unlock(&im->ino_lock); + return e ? true : false; +} + +void release_dirty_inode(struct f2fs_sb_info *sbi) +{ + struct ino_entry *e, *tmp; + int i; + + for (i = APPEND_INO; i <= UPDATE_INO; i++) { + struct inode_management *im = &sbi->im[i]; + + spin_lock(&im->ino_lock); + list_for_each_entry_safe(e, tmp, &im->ino_list, list) { + list_del(&e->list); + radix_tree_delete(&im->ino_root, e->ino); + kmem_cache_free(ino_entry_slab, e); + im->ino_num--; + } + spin_unlock(&im->ino_lock); } - new->ino = ino; +} + +int acquire_orphan_inode(struct f2fs_sb_info *sbi) +{ + struct inode_management *im = &sbi->im[ORPHAN_INO]; + int err = 0; - /* add new_oentry into list which is sorted by inode number */ - if (orphan) - list_add(&new->list, this->prev); + spin_lock(&im->ino_lock); + if (unlikely(im->ino_num >= sbi->max_orphans)) + err = -ENOSPC; else - list_add_tail(&new->list, head); + im->ino_num++; + spin_unlock(&im->ino_lock); - sbi->n_orphans++; -out: - mutex_unlock(&sbi->orphan_inode_mutex); + return err; +} + +void release_orphan_inode(struct f2fs_sb_info *sbi) +{ + struct inode_management *im = &sbi->im[ORPHAN_INO]; + + spin_lock(&im->ino_lock); + f2fs_bug_on(sbi, im->ino_num == 0); + im->ino_num--; + spin_unlock(&im->ino_lock); +} + +void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) +{ + /* add new orphan ino entry into list */ + __add_ino_entry(sbi, ino, ORPHAN_INO); } void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) { - struct list_head *this, *next, *head; - struct orphan_inode_entry *orphan; - - mutex_lock(&sbi->orphan_inode_mutex); - head = &sbi->orphan_inode_list; - list_for_each_safe(this, next, head) { - orphan = list_entry(this, struct orphan_inode_entry, list); - if (orphan->ino == ino) { - list_del(&orphan->list); - kmem_cache_free(orphan_entry_slab, orphan); - sbi->n_orphans--; - break; - } - } - mutex_unlock(&sbi->orphan_inode_mutex); + /* remove orphan entry from orphan list */ + __remove_ino_entry(sbi, ino, ORPHAN_INO); } static void recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) { struct inode *inode = f2fs_iget(sbi->sb, ino); - BUG_ON(IS_ERR(inode)); + f2fs_bug_on(sbi, IS_ERR(inode)); clear_nlink(inode); /* truncate all the data during iput */ iput(inode); } -int recover_orphan_inodes(struct f2fs_sb_info *sbi) +void recover_orphan_inodes(struct f2fs_sb_info *sbi) { - block_t start_blk, orphan_blkaddr, i, j; + block_t start_blk, orphan_blocks, i, j; if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) - return 0; + return; - sbi->por_doing = 1; - start_blk = __start_cp_addr(sbi) + 1; - orphan_blkaddr = __start_sum_addr(sbi) - 1; + set_sbi_flag(sbi, SBI_POR_DOING); - for (i = 0; i < orphan_blkaddr; i++) { + start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); + orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); + + ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP); + + for (i = 0; i < orphan_blocks; i++) { struct page *page = get_meta_page(sbi, start_blk + i); struct f2fs_orphan_block *orphan_blk; @@ -288,30 +490,42 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi) } /* clear Orphan Flag */ clear_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG); - sbi->por_doing = 0; - return 0; + clear_sbi_flag(sbi, SBI_POR_DOING); + return; } static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) { - struct list_head *head, *this, *next; + struct list_head *head; struct f2fs_orphan_block *orphan_blk = NULL; - struct page *page = NULL; unsigned int nentries = 0; - unsigned short index = 1; + unsigned short index; unsigned short orphan_blocks; + struct page *page = NULL; + struct ino_entry *orphan = NULL; + struct inode_management *im = &sbi->im[ORPHAN_INO]; - orphan_blocks = (unsigned short)((sbi->n_orphans + - (F2FS_ORPHANS_PER_BLOCK - 1)) / F2FS_ORPHANS_PER_BLOCK); + orphan_blocks = GET_ORPHAN_BLOCKS(im->ino_num); - mutex_lock(&sbi->orphan_inode_mutex); - head = &sbi->orphan_inode_list; + for (index = 0; index < orphan_blocks; index++) + grab_meta_page(sbi, start_blk + index); + + index = 1; + spin_lock(&im->ino_lock); + head = &im->ino_list; /* loop for each orphan inode entry and write them in Jornal block */ - list_for_each_safe(this, next, head) { - struct orphan_inode_entry *orphan; + list_for_each_entry(orphan, head, list) { + if (!page) { + page = find_get_page(META_MAPPING(sbi), start_blk++); + f2fs_bug_on(sbi, !page); + orphan_blk = + (struct f2fs_orphan_block *)page_address(page); + memset(orphan_blk, 0, sizeof(*orphan_blk)); + f2fs_put_page(page, 0); + } - orphan = list_entry(this, struct orphan_inode_entry, list); + orphan_blk->ino[nentries++] = cpu_to_le32(orphan->ino); if (nentries == F2FS_ORPHANS_PER_BLOCK) { /* @@ -325,29 +539,20 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) set_page_dirty(page); f2fs_put_page(page, 1); index++; - start_blk++; nentries = 0; page = NULL; } - if (page) - goto page_exist; + } - page = grab_meta_page(sbi, start_blk); - orphan_blk = (struct f2fs_orphan_block *)page_address(page); - memset(orphan_blk, 0, sizeof(*orphan_blk)); -page_exist: - orphan_blk->ino[nentries++] = cpu_to_le32(orphan->ino); + if (page) { + orphan_blk->blk_addr = cpu_to_le16(index); + orphan_blk->blk_count = cpu_to_le16(orphan_blocks); + orphan_blk->entry_count = cpu_to_le32(nentries); + set_page_dirty(page); + f2fs_put_page(page, 1); } - if (!page) - goto end; - orphan_blk->blk_addr = cpu_to_le16(index); - orphan_blk->blk_count = cpu_to_le16(orphan_blocks); - orphan_blk->entry_count = cpu_to_le32(nentries); - set_page_dirty(page); - f2fs_put_page(page, 1); -end: - mutex_unlock(&sbi->orphan_inode_mutex); + spin_unlock(&im->ino_lock); } static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, @@ -357,8 +562,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, unsigned long blk_size = sbi->blocksize; struct f2fs_checkpoint *cp_block; unsigned long long cur_version = 0, pre_version = 0; - unsigned int crc = 0; size_t crc_offset; + __u32 crc = 0; /* Read the 1st cp block in this CP pack */ cp_page_1 = get_meta_page(sbi, cp_addr); @@ -369,11 +574,11 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, if (crc_offset >= blk_size) goto invalid_cp1; - crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); + crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); if (!f2fs_crc_valid(crc, cp_block, crc_offset)) goto invalid_cp1; - pre_version = le64_to_cpu(cp_block->checkpoint_ver); + pre_version = cur_cp_version(cp_block); /* Read the 2nd cp block in this CP pack */ cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; @@ -384,11 +589,11 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, if (crc_offset >= blk_size) goto invalid_cp2; - crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); + crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); if (!f2fs_crc_valid(crc, cp_block, crc_offset)) goto invalid_cp2; - cur_version = le64_to_cpu(cp_block->checkpoint_ver); + cur_version = cur_cp_version(cp_block); if (cur_version == pre_version) { *version = cur_version; @@ -410,8 +615,11 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) unsigned long blk_size = sbi->blocksize; unsigned long long cp1_version = 0, cp2_version = 0; unsigned long long cp_start_blk_no; + unsigned int cp_blks = 1 + __cp_payload(sbi); + block_t cp_blk_no; + int i; - sbi->ckpt = kzalloc(blk_size, GFP_KERNEL); + sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL); if (!sbi->ckpt) return -ENOMEM; /* @@ -422,7 +630,8 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version); /* The second checkpoint pack should start at the next segment */ - cp_start_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); + cp_start_blk_no += ((unsigned long long)1) << + le32_to_cpu(fsb->log_blocks_per_seg); cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version); if (cp1 && cp2) { @@ -441,6 +650,23 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) cp_block = (struct f2fs_checkpoint *)page_address(cur_page); memcpy(sbi->ckpt, cp_block, blk_size); + if (cp_blks <= 1) + goto done; + + cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); + if (cur_page == cp2) + cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); + + for (i = 1; i < cp_blks; i++) { + void *sit_bitmap_ptr; + unsigned char *ckpt = (unsigned char *)sbi->ckpt; + + cur_page = get_meta_page(sbi, cp_blk_no + i); + sit_bitmap_ptr = page_address(cur_page); + memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); + f2fs_put_page(cur_page, 1); + } +done: f2fs_put_page(cp1, 1); f2fs_put_page(cp2, 1); return 0; @@ -450,95 +676,127 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) return -EINVAL; } -void set_dirty_dir_page(struct inode *inode, struct page *page) +static int __add_dirty_inode(struct inode *inode, struct inode_entry *new) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct list_head *head = &sbi->dir_inode_list; - struct dir_inode_entry *new; - struct list_head *this; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - if (!S_ISDIR(inode->i_mode)) + if (is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) + return -EEXIST; + + set_inode_flag(F2FS_I(inode), FI_DIRTY_DIR); + F2FS_I(inode)->dirty_dir = new; + list_add_tail(&new->list, &sbi->dir_inode_list); + stat_inc_dirty_dir(sbi); + return 0; +} + +void update_dirty_page(struct inode *inode, struct page *page) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct inode_entry *new; + int ret = 0; + + if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode)) return; -retry: - new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS); - if (!new) { - cond_resched(); - goto retry; + + if (!S_ISDIR(inode->i_mode)) { + inode_inc_dirty_pages(inode); + goto out; } + + new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); new->inode = inode; INIT_LIST_HEAD(&new->list); spin_lock(&sbi->dir_inode_lock); - list_for_each(this, head) { - struct dir_inode_entry *entry; - entry = list_entry(this, struct dir_inode_entry, list); - if (entry->inode == inode) { - kmem_cache_free(inode_entry_slab, new); - goto out; - } - } - list_add_tail(&new->list, head); - sbi->n_dirty_dirs++; + ret = __add_dirty_inode(inode, new); + inode_inc_dirty_pages(inode); + spin_unlock(&sbi->dir_inode_lock); - BUG_ON(!S_ISDIR(inode->i_mode)); + if (ret) + kmem_cache_free(inode_entry_slab, new); out: - inc_page_count(sbi, F2FS_DIRTY_DENTS); - inode_inc_dirty_dents(inode); SetPagePrivate(page); + f2fs_trace_pid(page); +} + +void add_dirty_dir_inode(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct inode_entry *new = + f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); + int ret = 0; + + new->inode = inode; + INIT_LIST_HEAD(&new->list); + spin_lock(&sbi->dir_inode_lock); + ret = __add_dirty_inode(inode, new); spin_unlock(&sbi->dir_inode_lock); + + if (ret) + kmem_cache_free(inode_entry_slab, new); } void remove_dirty_dir_inode(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct list_head *head = &sbi->dir_inode_list; - struct list_head *this; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct inode_entry *entry; if (!S_ISDIR(inode->i_mode)) return; spin_lock(&sbi->dir_inode_lock); - if (atomic_read(&F2FS_I(inode)->dirty_dents)) - goto out; - - list_for_each(this, head) { - struct dir_inode_entry *entry; - entry = list_entry(this, struct dir_inode_entry, list); - if (entry->inode == inode) { - list_del(&entry->list); - kmem_cache_free(inode_entry_slab, entry); - sbi->n_dirty_dirs--; - break; - } + if (get_dirty_pages(inode) || + !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) { + spin_unlock(&sbi->dir_inode_lock); + return; } -out: + + entry = F2FS_I(inode)->dirty_dir; + list_del(&entry->list); + F2FS_I(inode)->dirty_dir = NULL; + clear_inode_flag(F2FS_I(inode), FI_DIRTY_DIR); + stat_dec_dirty_dir(sbi); spin_unlock(&sbi->dir_inode_lock); + kmem_cache_free(inode_entry_slab, entry); + + /* Only from the recovery routine */ + if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) { + clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT); + iput(inode); + } } void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) { - struct list_head *head = &sbi->dir_inode_list; - struct dir_inode_entry *entry; + struct list_head *head; + struct inode_entry *entry; struct inode *inode; retry: + if (unlikely(f2fs_cp_error(sbi))) + return; + spin_lock(&sbi->dir_inode_lock); + + head = &sbi->dir_inode_list; if (list_empty(head)) { spin_unlock(&sbi->dir_inode_lock); return; } - entry = list_entry(head->next, struct dir_inode_entry, list); + entry = list_entry(head->next, struct inode_entry, list); inode = igrab(entry->inode); spin_unlock(&sbi->dir_inode_lock); if (inode) { - filemap_flush(inode->i_mapping); + filemap_fdatawrite(inode->i_mapping); iput(inode); } else { /* * We should submit bio, since it exists several * wribacking dentry pages in the freeing inode. */ - f2fs_submit_bio(sbi, DATA, true); + f2fs_submit_merged_bio(sbi, DATA, WRITE); + cond_resched(); } goto retry; } @@ -546,7 +804,7 @@ void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) /* * Freeze all the FS-operations for checkpoint. */ -static void block_operations(struct f2fs_sb_info *sbi) +static int block_operations(struct f2fs_sb_info *sbi) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, @@ -554,54 +812,93 @@ static void block_operations(struct f2fs_sb_info *sbi) .for_reclaim = 0, }; struct blk_plug plug; + int err = 0; blk_start_plug(&plug); retry_flush_dents: - mutex_lock_all(sbi); - + f2fs_lock_all(sbi); /* write all the dirty dentry pages */ if (get_pages(sbi, F2FS_DIRTY_DENTS)) { - mutex_unlock_all(sbi); + f2fs_unlock_all(sbi); sync_dirty_dir_inodes(sbi); + if (unlikely(f2fs_cp_error(sbi))) { + err = -EIO; + goto out; + } goto retry_flush_dents; } /* - * POR: we should ensure that there is no dirty node pages + * POR: we should ensure that there are no dirty node pages * until finishing nat/sit flush. */ retry_flush_nodes: - mutex_lock(&sbi->node_write); + down_write(&sbi->node_write); if (get_pages(sbi, F2FS_DIRTY_NODES)) { - mutex_unlock(&sbi->node_write); + up_write(&sbi->node_write); sync_node_pages(sbi, 0, &wbc); + if (unlikely(f2fs_cp_error(sbi))) { + f2fs_unlock_all(sbi); + err = -EIO; + goto out; + } goto retry_flush_nodes; } +out: blk_finish_plug(&plug); + return err; } static void unblock_operations(struct f2fs_sb_info *sbi) { - mutex_unlock(&sbi->node_write); - mutex_unlock_all(sbi); + up_write(&sbi->node_write); + f2fs_unlock_all(sbi); } -static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) +static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi) +{ + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&sbi->cp_wait, &wait, TASK_UNINTERRUPTIBLE); + + if (!get_pages(sbi, F2FS_WRITEBACK)) + break; + + io_schedule(); + } + finish_wait(&sbi->cp_wait, &wait); +} + +static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - nid_t last_nid = 0; + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); + struct f2fs_nm_info *nm_i = NM_I(sbi); + unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num; + nid_t last_nid = nm_i->next_scan_nid; block_t start_blk; struct page *cp_page; unsigned int data_sum_blocks, orphan_blocks; - unsigned int crc32 = 0; + __u32 crc32 = 0; void *kaddr; int i; + int cp_payload_blks = __cp_payload(sbi); + + /* + * This avoids to conduct wrong roll-forward operations and uses + * metapages, so should be called prior to sync_meta_pages below. + */ + discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); /* Flush all the NAT/SIT pages */ - while (get_pages(sbi, F2FS_DIRTY_META)) + while (get_pages(sbi, F2FS_DIRTY_META)) { sync_meta_pages(sbi, META, LONG_MAX); + if (unlikely(f2fs_cp_error(sbi))) + return; + } next_free_nid(sbi, &last_nid); @@ -612,7 +909,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi)); ckpt->valid_block_count = cpu_to_le64(valid_user_blocks(sbi)); ckpt->free_segment_count = cpu_to_le32(free_segments(sbi)); - for (i = 0; i < 3; i++) { + for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { ckpt->cur_node_segno[i] = cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_NODE)); ckpt->cur_node_blkoff[i] = @@ -620,7 +917,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ckpt->alloc_type[i + CURSEG_HOT_NODE] = curseg_alloc_type(sbi, i + CURSEG_HOT_NODE); } - for (i = 0; i < 3; i++) { + for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { ckpt->cur_data_segno[i] = cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_DATA)); ckpt->cur_data_blkoff[i] = @@ -634,38 +931,50 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ckpt->next_free_nid = cpu_to_le32(last_nid); /* 2 cp + n data seg summary + orphan inode blocks */ - data_sum_blocks = npages_for_summary_flush(sbi); - if (data_sum_blocks < 3) + data_sum_blocks = npages_for_summary_flush(sbi, false); + if (data_sum_blocks < NR_CURSEG_DATA_TYPE) set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); else clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); - orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) - / F2FS_ORPHANS_PER_BLOCK; - ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks); + orphan_blocks = GET_ORPHAN_BLOCKS(orphan_num); + ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + + orphan_blocks); - if (is_umount) { + if (__remain_node_summaries(cpc->reason)) + ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ + cp_payload_blks + data_sum_blocks + + orphan_blocks + NR_CURSEG_NODE_TYPE); + else + ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + + cp_payload_blks + data_sum_blocks + + orphan_blocks); + + if (cpc->reason == CP_UMOUNT) set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); - ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); - } else { + else clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); - ckpt->cp_pack_total_block_count = cpu_to_le32(2 + - data_sum_blocks + orphan_blocks); - } - if (sbi->n_orphans) + if (cpc->reason == CP_FASTBOOT) + set_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); + else + clear_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); + + if (orphan_num) set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); else clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); + if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) + set_ckpt_flags(ckpt, CP_FSCK_FLAG); + /* update SIT/NAT bitmap */ get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); - *(__le32 *)((unsigned char *)ckpt + - le32_to_cpu(ckpt->checksum_offset)) + *((__le32 *)((unsigned char *)ckpt + + le32_to_cpu(ckpt->checksum_offset))) = cpu_to_le32(crc32); start_blk = __start_cp_addr(sbi); @@ -673,18 +982,26 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* write out checkpoint buffer at block 0 */ cp_page = grab_meta_page(sbi, start_blk++); kaddr = page_address(cp_page); - memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); + memcpy(kaddr, ckpt, F2FS_BLKSIZE); set_page_dirty(cp_page); f2fs_put_page(cp_page, 1); - if (sbi->n_orphans) { + for (i = 1; i < 1 + cp_payload_blks; i++) { + cp_page = grab_meta_page(sbi, start_blk++); + kaddr = page_address(cp_page); + memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, F2FS_BLKSIZE); + set_page_dirty(cp_page); + f2fs_put_page(cp_page, 1); + } + + if (orphan_num) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; } write_data_summaries(sbi, start_blk); start_blk += data_sum_blocks; - if (is_umount) { + if (__remain_node_summaries(cpc->reason)) { write_node_summaries(sbi, start_blk); start_blk += NR_CURSEG_NODE_TYPE; } @@ -692,16 +1009,18 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* writeout checkpoint block */ cp_page = grab_meta_page(sbi, start_blk); kaddr = page_address(cp_page); - memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); + memcpy(kaddr, ckpt, F2FS_BLKSIZE); set_page_dirty(cp_page); f2fs_put_page(cp_page, 1); /* wait for previous submitted node/meta pages writeback */ - while (get_pages(sbi, F2FS_WRITEBACK)) - congestion_wait(BLK_RW_ASYNC, HZ / 50); + wait_on_all_pages_writeback(sbi); - filemap_fdatawait_range(sbi->node_inode->i_mapping, 0, LONG_MAX); - filemap_fdatawait_range(sbi->meta_inode->i_mapping, 0, LONG_MAX); + if (unlikely(f2fs_cp_error(sbi))) + return; + + filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LONG_MAX); + filemap_fdatawait_range(META_MAPPING(sbi), 0, LONG_MAX); /* update user_block_counts */ sbi->last_valid_block_count = sbi->total_valid_block_count; @@ -710,69 +1029,101 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* Here, we only have one bio having CP pack */ sync_meta_pages(sbi, META_FLUSH, LONG_MAX); - if (!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) { - clear_prefree_segments(sbi); - F2FS_RESET_SB_DIRT(sbi); - } + /* wait for previous submitted meta pages writeback */ + wait_on_all_pages_writeback(sbi); + + release_dirty_inode(sbi); + + if (unlikely(f2fs_cp_error(sbi))) + return; + + clear_prefree_segments(sbi); + clear_sbi_flag(sbi, SBI_IS_DIRTY); } /* - * We guarantee that this checkpoint procedure should not fail. + * We guarantee that this checkpoint procedure will not fail. */ -void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) +void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); unsigned long long ckpt_ver; - trace_f2fs_write_checkpoint(sbi->sb, is_umount, "start block_ops"); - mutex_lock(&sbi->cp_mutex); - block_operations(sbi); - trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops"); + if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) && + (cpc->reason == CP_FASTBOOT || cpc->reason == CP_SYNC)) + goto out; + if (unlikely(f2fs_cp_error(sbi))) + goto out; + if (f2fs_readonly(sbi->sb)) + goto out; + + trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops"); + + if (block_operations(sbi)) + goto out; - f2fs_submit_bio(sbi, DATA, true); - f2fs_submit_bio(sbi, NODE, true); - f2fs_submit_bio(sbi, META, true); + trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops"); + + f2fs_submit_merged_bio(sbi, DATA, WRITE); + f2fs_submit_merged_bio(sbi, NODE, WRITE); + f2fs_submit_merged_bio(sbi, META, WRITE); /* * update checkpoint pack index * Increase the version number so that * SIT entries and seg summaries are written at correct place */ - ckpt_ver = le64_to_cpu(ckpt->checkpoint_ver); + ckpt_ver = cur_cp_version(ckpt); ckpt->checkpoint_ver = cpu_to_le64(++ckpt_ver); /* write cached NAT/SIT entries to NAT/SIT area */ flush_nat_entries(sbi); - flush_sit_entries(sbi); + flush_sit_entries(sbi, cpc); /* unlock all the fs_lock[] in do_checkpoint() */ - do_checkpoint(sbi, is_umount); + do_checkpoint(sbi, cpc); unblock_operations(sbi); - mutex_unlock(&sbi->cp_mutex); + stat_inc_cp_count(sbi->stat_info); - trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint"); + if (cpc->reason == CP_RECOVERY) + f2fs_msg(sbi->sb, KERN_NOTICE, + "checkpoint: version = %llx", ckpt_ver); +out: + mutex_unlock(&sbi->cp_mutex); + trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); } -void init_orphan_info(struct f2fs_sb_info *sbi) +void init_ino_entry_info(struct f2fs_sb_info *sbi) { - mutex_init(&sbi->orphan_inode_mutex); - INIT_LIST_HEAD(&sbi->orphan_inode_list); - sbi->n_orphans = 0; + int i; + + for (i = 0; i < MAX_INO_ENTRY; i++) { + struct inode_management *im = &sbi->im[i]; + + INIT_RADIX_TREE(&im->ino_root, GFP_ATOMIC); + spin_lock_init(&im->ino_lock); + INIT_LIST_HEAD(&im->ino_list); + im->ino_num = 0; + } + + sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_TYPE - __cp_payload(sbi)) * + F2FS_ORPHANS_PER_BLOCK; } int __init create_checkpoint_caches(void) { - orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry", - sizeof(struct orphan_inode_entry), NULL); - if (unlikely(!orphan_entry_slab)) + ino_entry_slab = f2fs_kmem_cache_create("f2fs_ino_entry", + sizeof(struct ino_entry)); + if (!ino_entry_slab) return -ENOMEM; - inode_entry_slab = f2fs_kmem_cache_create("f2fs_dirty_dir_entry", - sizeof(struct dir_inode_entry), NULL); - if (unlikely(!inode_entry_slab)) { - kmem_cache_destroy(orphan_entry_slab); + inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry", + sizeof(struct inode_entry)); + if (!inode_entry_slab) { + kmem_cache_destroy(ino_entry_slab); return -ENOMEM; } return 0; @@ -780,6 +1131,6 @@ int __init create_checkpoint_caches(void) void destroy_checkpoint_caches(void) { - kmem_cache_destroy(orphan_entry_slab); + kmem_cache_destroy(ino_entry_slab); kmem_cache_destroy(inode_entry_slab); } diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 91ff93b0b0f40..dbbab45a20f63 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -22,106 +22,291 @@ #include "f2fs.h" #include "node.h" #include "segment.h" +#include "trace.h" #include +static struct kmem_cache *extent_tree_slab; +static struct kmem_cache *extent_node_slab; + +static void f2fs_read_end_io(struct bio *bio, int err) +{ + struct bio_vec *bvec; + int i; + + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; + + if (!err) { + SetPageUptodate(page); + } else { + ClearPageUptodate(page); + SetPageError(page); + } + unlock_page(page); + } + bio_put(bio); +} + +static void f2fs_write_end_io(struct bio *bio, int err) +{ + struct f2fs_sb_info *sbi = bio->bi_private; + struct bio_vec *bvec; + int i; + + bio_for_each_segment_all(bvec, bio, i) { + struct page *page = bvec->bv_page; + + if (unlikely(err)) { + set_page_dirty(page); + set_bit(AS_EIO, &page->mapping->flags); + f2fs_stop_checkpoint(sbi); + } + end_page_writeback(page); + dec_page_count(sbi, F2FS_WRITEBACK); + } + + if (!get_pages(sbi, F2FS_WRITEBACK) && + !list_empty(&sbi->cp_wait.task_list)) + wake_up(&sbi->cp_wait); + + bio_put(bio); +} + +/* + * Low-level block read/write IO operations. + */ +static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr, + int npages, bool is_read) +{ + struct bio *bio; + + /* No failure on bio allocation */ + bio = bio_alloc(GFP_NOIO, npages); + + bio->bi_bdev = sbi->sb->s_bdev; + bio->bi_sector = SECTOR_FROM_BLOCK(blk_addr); + bio->bi_end_io = is_read ? f2fs_read_end_io : f2fs_write_end_io; + bio->bi_private = sbi; + + return bio; +} + +static void __submit_merged_bio(struct f2fs_bio_info *io) +{ + struct f2fs_io_info *fio = &io->fio; + + if (!io->bio) + return; + + if (is_read_io(fio->rw)) + trace_f2fs_submit_read_bio(io->sbi->sb, fio, io->bio); + else + trace_f2fs_submit_write_bio(io->sbi->sb, fio, io->bio); + + submit_bio(fio->rw, io->bio); + io->bio = NULL; +} + +void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, + enum page_type type, int rw) +{ + enum page_type btype = PAGE_TYPE_OF_BIO(type); + struct f2fs_bio_info *io; + + io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype]; + + down_write(&io->io_rwsem); + + /* change META to META_FLUSH in the checkpoint procedure */ + if (type >= META_FLUSH) { + io->fio.type = META_FLUSH; + if (test_opt(sbi, NOBARRIER)) + io->fio.rw = WRITE_FLUSH | REQ_META | REQ_PRIO; + else + io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO; + } + __submit_merged_bio(io); + up_write(&io->io_rwsem); +} + +/* + * Fill the locked page with data located in the block address. + * Return unlocked page. + */ +int f2fs_submit_page_bio(struct f2fs_sb_info *sbi, struct page *page, + struct f2fs_io_info *fio) +{ + struct bio *bio; + + trace_f2fs_submit_page_bio(page, fio); + f2fs_trace_ios(page, fio, 0); + + /* Allocate a new bio */ + bio = __bio_alloc(sbi, fio->blk_addr, 1, is_read_io(fio->rw)); + + if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) { + bio_put(bio); + f2fs_put_page(page, 1); + return -EFAULT; + } + + submit_bio(fio->rw, bio); + return 0; +} + +void f2fs_submit_page_mbio(struct f2fs_sb_info *sbi, struct page *page, + struct f2fs_io_info *fio) +{ + enum page_type btype = PAGE_TYPE_OF_BIO(fio->type); + struct f2fs_bio_info *io; + bool is_read = is_read_io(fio->rw); + + io = is_read ? &sbi->read_io : &sbi->write_io[btype]; + + verify_block_addr(sbi, fio->blk_addr); + + down_write(&io->io_rwsem); + + if (!is_read) + inc_page_count(sbi, F2FS_WRITEBACK); + + if (io->bio && (io->last_block_in_bio != fio->blk_addr - 1 || + io->fio.rw != fio->rw)) + __submit_merged_bio(io); +alloc_new: + if (io->bio == NULL) { + int bio_blocks = MAX_BIO_BLOCKS(sbi); + + io->bio = __bio_alloc(sbi, fio->blk_addr, bio_blocks, is_read); + io->fio = *fio; + } + + if (bio_add_page(io->bio, page, PAGE_CACHE_SIZE, 0) < + PAGE_CACHE_SIZE) { + __submit_merged_bio(io); + goto alloc_new; + } + + io->last_block_in_bio = fio->blk_addr; + f2fs_trace_ios(page, fio, 0); + + up_write(&io->io_rwsem); + trace_f2fs_submit_page_mbio(page, fio); +} + /* * Lock ordering for the change of data block address: * ->data_page * ->node_page * update block addresses in the node page */ -static void __set_data_blkaddr(struct dnode_of_data *dn, block_t new_addr) +void set_data_blkaddr(struct dnode_of_data *dn) { struct f2fs_node *rn; __le32 *addr_array; struct page *node_page = dn->node_page; unsigned int ofs_in_node = dn->ofs_in_node; - wait_on_page_writeback(node_page); + f2fs_wait_on_page_writeback(node_page, NODE); - rn = (struct f2fs_node *)page_address(node_page); + rn = F2FS_NODE(node_page); /* Get physical address of data block */ addr_array = blkaddr_in_node(rn); - addr_array[ofs_in_node] = cpu_to_le32(new_addr); + addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr); set_page_dirty(node_page); } int reserve_new_block(struct dnode_of_data *dn) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - if (is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)) + if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) return -EPERM; - if (!inc_valid_block_count(sbi, dn->inode, 1)) + if (unlikely(!inc_valid_block_count(sbi, dn->inode, 1))) return -ENOSPC; trace_f2fs_reserve_new_block(dn->inode, dn->nid, dn->ofs_in_node); - __set_data_blkaddr(dn, NEW_ADDR); dn->data_blkaddr = NEW_ADDR; + set_data_blkaddr(dn); + mark_inode_dirty(dn->inode); sync_inode_page(dn); return 0; } -static int check_extent_cache(struct inode *inode, pgoff_t pgofs, - struct buffer_head *bh_result) +int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index) +{ + bool need_put = dn->inode_page ? false : true; + int err; + + err = get_dnode_of_data(dn, index, ALLOC_NODE); + if (err) + return err; + + if (dn->data_blkaddr == NULL_ADDR) + err = reserve_new_block(dn); + if (err || need_put) + f2fs_put_dnode(dn); + return err; +} + +static void f2fs_map_bh(struct super_block *sb, pgoff_t pgofs, + struct extent_info *ei, struct buffer_head *bh_result) +{ + unsigned int blkbits = sb->s_blocksize_bits; + size_t max_size = bh_result->b_size; + size_t mapped_size; + + clear_buffer_new(bh_result); + map_bh(bh_result, sb, ei->blk + pgofs - ei->fofs); + mapped_size = (ei->fofs + ei->len - pgofs) << blkbits; + bh_result->b_size = min(max_size, mapped_size); +} + +static bool lookup_extent_info(struct inode *inode, pgoff_t pgofs, + struct extent_info *ei) { struct f2fs_inode_info *fi = F2FS_I(inode); - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); pgoff_t start_fofs, end_fofs; block_t start_blkaddr; - read_lock(&fi->ext.ext_lock); + read_lock(&fi->ext_lock); if (fi->ext.len == 0) { - read_unlock(&fi->ext.ext_lock); - return 0; + read_unlock(&fi->ext_lock); + return false; } - sbi->total_hit_ext++; + stat_inc_total_hit(inode->i_sb); + start_fofs = fi->ext.fofs; end_fofs = fi->ext.fofs + fi->ext.len - 1; - start_blkaddr = fi->ext.blk_addr; + start_blkaddr = fi->ext.blk; if (pgofs >= start_fofs && pgofs <= end_fofs) { - unsigned int blkbits = inode->i_sb->s_blocksize_bits; - size_t count; - - clear_buffer_new(bh_result); - map_bh(bh_result, inode->i_sb, - start_blkaddr + pgofs - start_fofs); - count = end_fofs - pgofs + 1; - if (count < (UINT_MAX >> blkbits)) - bh_result->b_size = (count << blkbits); - else - bh_result->b_size = UINT_MAX; - - sbi->read_hit_ext++; - read_unlock(&fi->ext.ext_lock); - return 1; + *ei = fi->ext; + stat_inc_read_hit(inode->i_sb); + read_unlock(&fi->ext_lock); + return true; } - read_unlock(&fi->ext.ext_lock); - return 0; + read_unlock(&fi->ext_lock); + return false; } -void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn) +static bool update_extent_info(struct inode *inode, pgoff_t fofs, + block_t blkaddr) { - struct f2fs_inode_info *fi = F2FS_I(dn->inode); - pgoff_t fofs, start_fofs, end_fofs; + struct f2fs_inode_info *fi = F2FS_I(inode); + pgoff_t start_fofs, end_fofs; block_t start_blkaddr, end_blkaddr; + int need_update = true; - BUG_ON(blk_addr == NEW_ADDR); - fofs = start_bidx_of_node(ofs_of_node(dn->node_page)) + dn->ofs_in_node; - - /* Update the page address in the parent node */ - __set_data_blkaddr(dn, blk_addr); - - write_lock(&fi->ext.ext_lock); + write_lock(&fi->ext_lock); start_fofs = fi->ext.fofs; end_fofs = fi->ext.fofs + fi->ext.len - 1; - start_blkaddr = fi->ext.blk_addr; - end_blkaddr = fi->ext.blk_addr + fi->ext.len - 1; + start_blkaddr = fi->ext.blk; + end_blkaddr = fi->ext.blk + fi->ext.len - 1; /* Drop and initialize the matched extent */ if (fi->ext.len == 1 && fofs == start_fofs) @@ -129,24 +314,24 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn) /* Initial extent */ if (fi->ext.len == 0) { - if (blk_addr != NULL_ADDR) { + if (blkaddr != NULL_ADDR) { fi->ext.fofs = fofs; - fi->ext.blk_addr = blk_addr; + fi->ext.blk = blkaddr; fi->ext.len = 1; } goto end_update; } /* Front merge */ - if (fofs == start_fofs - 1 && blk_addr == start_blkaddr - 1) { + if (fofs == start_fofs - 1 && blkaddr == start_blkaddr - 1) { fi->ext.fofs--; - fi->ext.blk_addr--; + fi->ext.blk--; fi->ext.len++; goto end_update; } /* Back merge */ - if (fofs == end_fofs + 1 && blk_addr == end_blkaddr + 1) { + if (fofs == end_fofs + 1 && blkaddr == end_blkaddr + 1) { fi->ext.len++; goto end_update; } @@ -158,33 +343,597 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn) fi->ext.len = fofs - start_fofs; } else { fi->ext.fofs = fofs + 1; - fi->ext.blk_addr = start_blkaddr + - fofs - start_fofs + 1; + fi->ext.blk = start_blkaddr + fofs - start_fofs + 1; fi->ext.len -= fofs - start_fofs + 1; } - goto end_update; + } else { + need_update = false; } - write_unlock(&fi->ext.ext_lock); - return; + /* Finally, if the extent is very fragmented, let's drop the cache. */ + if (fi->ext.len < F2FS_MIN_EXTENT_LEN) { + fi->ext.len = 0; + set_inode_flag(fi, FI_NO_EXTENT); + need_update = true; + } end_update: - write_unlock(&fi->ext.ext_lock); - sync_inode_page(dn); + write_unlock(&fi->ext_lock); + return need_update; +} + +static struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_info *ei, + struct rb_node *parent, struct rb_node **p) +{ + struct extent_node *en; + + en = kmem_cache_alloc(extent_node_slab, GFP_ATOMIC); + if (!en) + return NULL; + + en->ei = *ei; + INIT_LIST_HEAD(&en->list); + + rb_link_node(&en->rb_node, parent, p); + rb_insert_color(&en->rb_node, &et->root); + et->count++; + atomic_inc(&sbi->total_ext_node); + return en; +} + +static void __detach_extent_node(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + rb_erase(&en->rb_node, &et->root); + et->count--; + atomic_dec(&sbi->total_ext_node); + + if (et->cached_en == en) + et->cached_en = NULL; +} + +static struct extent_tree *__find_extent_tree(struct f2fs_sb_info *sbi, + nid_t ino) +{ + struct extent_tree *et; + + down_read(&sbi->extent_tree_lock); + et = radix_tree_lookup(&sbi->extent_tree_root, ino); + if (!et) { + up_read(&sbi->extent_tree_lock); + return NULL; + } + atomic_inc(&et->refcount); + up_read(&sbi->extent_tree_lock); + + return et; +} + +static struct extent_tree *__grab_extent_tree(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et; + nid_t ino = inode->i_ino; + + down_write(&sbi->extent_tree_lock); + et = radix_tree_lookup(&sbi->extent_tree_root, ino); + if (!et) { + et = f2fs_kmem_cache_alloc(extent_tree_slab, GFP_NOFS); + f2fs_radix_tree_insert(&sbi->extent_tree_root, ino, et); + memset(et, 0, sizeof(struct extent_tree)); + et->ino = ino; + et->root = RB_ROOT; + et->cached_en = NULL; + rwlock_init(&et->lock); + atomic_set(&et->refcount, 0); + et->count = 0; + sbi->total_ext_tree++; + } + atomic_inc(&et->refcount); + up_write(&sbi->extent_tree_lock); + + return et; +} + +static struct extent_node *__lookup_extent_tree(struct extent_tree *et, + unsigned int fofs) +{ + struct rb_node *node = et->root.rb_node; + struct extent_node *en; + + if (et->cached_en) { + struct extent_info *cei = &et->cached_en->ei; + + if (cei->fofs <= fofs && cei->fofs + cei->len > fofs) + return et->cached_en; + } + + while (node) { + en = rb_entry(node, struct extent_node, rb_node); + + if (fofs < en->ei.fofs) { + node = node->rb_left; + } else if (fofs >= en->ei.fofs + en->ei.len) { + node = node->rb_right; + } else { + et->cached_en = en; + return en; + } + } + return NULL; +} + +static struct extent_node *__try_back_merge(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + struct extent_node *prev; + struct rb_node *node; + + node = rb_prev(&en->rb_node); + if (!node) + return NULL; + + prev = rb_entry(node, struct extent_node, rb_node); + if (__is_back_mergeable(&en->ei, &prev->ei)) { + en->ei.fofs = prev->ei.fofs; + en->ei.blk = prev->ei.blk; + en->ei.len += prev->ei.len; + __detach_extent_node(sbi, et, prev); + return prev; + } + return NULL; +} + +static struct extent_node *__try_front_merge(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + struct extent_node *next; + struct rb_node *node; + + node = rb_next(&en->rb_node); + if (!node) + return NULL; + + next = rb_entry(node, struct extent_node, rb_node); + if (__is_front_mergeable(&en->ei, &next->ei)) { + en->ei.len += next->ei.len; + __detach_extent_node(sbi, et, next); + return next; + } + return NULL; +} + +static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_info *ei, + struct extent_node **den) +{ + struct rb_node **p = &et->root.rb_node; + struct rb_node *parent = NULL; + struct extent_node *en; + + while (*p) { + parent = *p; + en = rb_entry(parent, struct extent_node, rb_node); + + if (ei->fofs < en->ei.fofs) { + if (__is_front_mergeable(ei, &en->ei)) { + f2fs_bug_on(sbi, !den); + en->ei.fofs = ei->fofs; + en->ei.blk = ei->blk; + en->ei.len += ei->len; + *den = __try_back_merge(sbi, et, en); + return en; + } + p = &(*p)->rb_left; + } else if (ei->fofs >= en->ei.fofs + en->ei.len) { + if (__is_back_mergeable(ei, &en->ei)) { + f2fs_bug_on(sbi, !den); + en->ei.len += ei->len; + *den = __try_front_merge(sbi, et, en); + return en; + } + p = &(*p)->rb_right; + } else { + f2fs_bug_on(sbi, 1); + } + } + + return __attach_extent_node(sbi, et, ei, parent, p); +} + +static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, + struct extent_tree *et, bool free_all) +{ + struct rb_node *node, *next; + struct extent_node *en; + unsigned int count = et->count; + + node = rb_first(&et->root); + while (node) { + next = rb_next(node); + en = rb_entry(node, struct extent_node, rb_node); + + if (free_all) { + spin_lock(&sbi->extent_lock); + if (!list_empty(&en->list)) + list_del_init(&en->list); + spin_unlock(&sbi->extent_lock); + } + + if (free_all || list_empty(&en->list)) { + __detach_extent_node(sbi, et, en); + kmem_cache_free(extent_node_slab, en); + } + node = next; + } + + return count - et->count; +} + +static void f2fs_init_extent_tree(struct inode *inode, + struct f2fs_extent *i_ext) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et; + struct extent_node *en; + struct extent_info ei; + + if (le32_to_cpu(i_ext->len) < F2FS_MIN_EXTENT_LEN) + return; + + et = __grab_extent_tree(inode); + + write_lock(&et->lock); + if (et->count) + goto out; + + set_extent_info(&ei, le32_to_cpu(i_ext->fofs), + le32_to_cpu(i_ext->blk), le32_to_cpu(i_ext->len)); + + en = __insert_extent_tree(sbi, et, &ei, NULL); + if (en) { + et->cached_en = en; + + spin_lock(&sbi->extent_lock); + list_add_tail(&en->list, &sbi->extent_list); + spin_unlock(&sbi->extent_lock); + } +out: + write_unlock(&et->lock); + atomic_dec(&et->refcount); +} + +static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, + struct extent_info *ei) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et; + struct extent_node *en; + + trace_f2fs_lookup_extent_tree_start(inode, pgofs); + + et = __find_extent_tree(sbi, inode->i_ino); + if (!et) + return false; + + read_lock(&et->lock); + en = __lookup_extent_tree(et, pgofs); + if (en) { + *ei = en->ei; + spin_lock(&sbi->extent_lock); + if (!list_empty(&en->list)) + list_move_tail(&en->list, &sbi->extent_list); + spin_unlock(&sbi->extent_lock); + stat_inc_read_hit(sbi->sb); + } + stat_inc_total_hit(sbi->sb); + read_unlock(&et->lock); + + trace_f2fs_lookup_extent_tree_end(inode, pgofs, en); + + atomic_dec(&et->refcount); + return en ? true : false; +} + +static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs, + block_t blkaddr) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et; + struct extent_node *en = NULL, *en1 = NULL, *en2 = NULL, *en3 = NULL; + struct extent_node *den = NULL; + struct extent_info ei, dei; + unsigned int endofs; + + trace_f2fs_update_extent_tree(inode, fofs, blkaddr); + + et = __grab_extent_tree(inode); + + write_lock(&et->lock); + + /* 1. lookup and remove existing extent info in cache */ + en = __lookup_extent_tree(et, fofs); + if (!en) + goto update_extent; + + dei = en->ei; + __detach_extent_node(sbi, et, en); + + /* 2. if extent can be split more, split and insert the left part */ + if (dei.len > 1) { + /* insert left part of split extent into cache */ + if (fofs - dei.fofs >= F2FS_MIN_EXTENT_LEN) { + set_extent_info(&ei, dei.fofs, dei.blk, + fofs - dei.fofs); + en1 = __insert_extent_tree(sbi, et, &ei, NULL); + } + + /* insert right part of split extent into cache */ + endofs = dei.fofs + dei.len - 1; + if (endofs - fofs >= F2FS_MIN_EXTENT_LEN) { + set_extent_info(&ei, fofs + 1, + fofs - dei.fofs + dei.blk, endofs - fofs); + en2 = __insert_extent_tree(sbi, et, &ei, NULL); + } + } + +update_extent: + /* 3. update extent in extent cache */ + if (blkaddr) { + set_extent_info(&ei, fofs, blkaddr, 1); + en3 = __insert_extent_tree(sbi, et, &ei, &den); + } + + /* 4. update in global extent list */ + spin_lock(&sbi->extent_lock); + if (en && !list_empty(&en->list)) + list_del(&en->list); + /* + * en1 and en2 split from en, they will become more and more smaller + * fragments after splitting several times. So if the length is smaller + * than F2FS_MIN_EXTENT_LEN, we will not add them into extent tree. + */ + if (en1) + list_add_tail(&en1->list, &sbi->extent_list); + if (en2) + list_add_tail(&en2->list, &sbi->extent_list); + if (en3) { + if (list_empty(&en3->list)) + list_add_tail(&en3->list, &sbi->extent_list); + else + list_move_tail(&en3->list, &sbi->extent_list); + } + if (den && !list_empty(&den->list)) + list_del(&den->list); + spin_unlock(&sbi->extent_lock); + + /* 5. release extent node */ + if (en) + kmem_cache_free(extent_node_slab, en); + if (den) + kmem_cache_free(extent_node_slab, den); + + write_unlock(&et->lock); + atomic_dec(&et->refcount); +} + +void f2fs_preserve_extent_tree(struct inode *inode) +{ + struct extent_tree *et; + struct extent_info *ext = &F2FS_I(inode)->ext; + bool sync = false; + + if (!test_opt(F2FS_I_SB(inode), EXTENT_CACHE)) + return; + + et = __find_extent_tree(F2FS_I_SB(inode), inode->i_ino); + if (!et) { + if (ext->len) { + ext->len = 0; + update_inode_page(inode); + } + return; + } + + read_lock(&et->lock); + if (et->count) { + struct extent_node *en; + + if (et->cached_en) { + en = et->cached_en; + } else { + struct rb_node *node = rb_first(&et->root); + + if (!node) + node = rb_last(&et->root); + en = rb_entry(node, struct extent_node, rb_node); + } + + if (__is_extent_same(ext, &en->ei)) + goto out; + + *ext = en->ei; + sync = true; + } else if (ext->len) { + ext->len = 0; + sync = true; + } +out: + read_unlock(&et->lock); + atomic_dec(&et->refcount); + + if (sync) + update_inode_page(inode); +} + +void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) +{ + struct extent_tree *treevec[EXT_TREE_VEC_SIZE]; + struct extent_node *en, *tmp; + unsigned long ino = F2FS_ROOT_INO(sbi); + struct radix_tree_iter iter; + void **slot; + unsigned int found; + unsigned int node_cnt = 0, tree_cnt = 0; + + if (!test_opt(sbi, EXTENT_CACHE)) + return; + + if (available_free_memory(sbi, EXTENT_CACHE)) + return; + + spin_lock(&sbi->extent_lock); + list_for_each_entry_safe(en, tmp, &sbi->extent_list, list) { + if (!nr_shrink--) + break; + list_del_init(&en->list); + } + spin_unlock(&sbi->extent_lock); + + down_read(&sbi->extent_tree_lock); + while ((found = radix_tree_gang_lookup(&sbi->extent_tree_root, + (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { + unsigned i; + + ino = treevec[found - 1]->ino + 1; + for (i = 0; i < found; i++) { + struct extent_tree *et = treevec[i]; + + atomic_inc(&et->refcount); + write_lock(&et->lock); + node_cnt += __free_extent_tree(sbi, et, false); + write_unlock(&et->lock); + atomic_dec(&et->refcount); + } + } + up_read(&sbi->extent_tree_lock); + + down_write(&sbi->extent_tree_lock); + radix_tree_for_each_slot(slot, &sbi->extent_tree_root, &iter, + F2FS_ROOT_INO(sbi)) { + struct extent_tree *et = (struct extent_tree *)*slot; + + if (!atomic_read(&et->refcount) && !et->count) { + radix_tree_delete(&sbi->extent_tree_root, et->ino); + kmem_cache_free(extent_tree_slab, et); + sbi->total_ext_tree--; + tree_cnt++; + } + } + up_write(&sbi->extent_tree_lock); + + trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt); +} + +void f2fs_destroy_extent_tree(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et; + unsigned int node_cnt = 0; + + if (!test_opt(sbi, EXTENT_CACHE)) + return; + + et = __find_extent_tree(sbi, inode->i_ino); + if (!et) + goto out; + + /* free all extent info belong to this extent tree */ + write_lock(&et->lock); + node_cnt = __free_extent_tree(sbi, et, true); + write_unlock(&et->lock); + + atomic_dec(&et->refcount); + + /* try to find and delete extent tree entry in radix tree */ + down_write(&sbi->extent_tree_lock); + et = radix_tree_lookup(&sbi->extent_tree_root, inode->i_ino); + if (!et) { + up_write(&sbi->extent_tree_lock); + goto out; + } + f2fs_bug_on(sbi, atomic_read(&et->refcount) || et->count); + radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); + kmem_cache_free(extent_tree_slab, et); + sbi->total_ext_tree--; + up_write(&sbi->extent_tree_lock); +out: + trace_f2fs_destroy_extent_tree(inode, node_cnt); return; } +void f2fs_init_extent_cache(struct inode *inode, struct f2fs_extent *i_ext) +{ + if (test_opt(F2FS_I_SB(inode), EXTENT_CACHE)) + f2fs_init_extent_tree(inode, i_ext); + + write_lock(&F2FS_I(inode)->ext_lock); + get_extent_info(&F2FS_I(inode)->ext, *i_ext); + write_unlock(&F2FS_I(inode)->ext_lock); +} + +static bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs, + struct extent_info *ei) +{ + if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) + return false; + + if (test_opt(F2FS_I_SB(inode), EXTENT_CACHE)) + return f2fs_lookup_extent_tree(inode, pgofs, ei); + + return lookup_extent_info(inode, pgofs, ei); +} + +void f2fs_update_extent_cache(struct dnode_of_data *dn) +{ + struct f2fs_inode_info *fi = F2FS_I(dn->inode); + pgoff_t fofs; + + f2fs_bug_on(F2FS_I_SB(dn->inode), dn->data_blkaddr == NEW_ADDR); + + if (is_inode_flag_set(fi, FI_NO_EXTENT)) + return; + + fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + + dn->ofs_in_node; + + if (test_opt(F2FS_I_SB(dn->inode), EXTENT_CACHE)) + return f2fs_update_extent_tree(dn->inode, fofs, + dn->data_blkaddr); + + if (update_extent_info(dn->inode, fofs, dn->data_blkaddr)) + sync_inode_page(dn); +} + struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct address_space *mapping = inode->i_mapping; struct dnode_of_data dn; struct page *page; + struct extent_info ei; int err; + struct f2fs_io_info fio = { + .type = DATA, + .rw = sync ? READ_SYNC : READA, + }; + + /* + * If sync is false, it needs to check its block allocation. + * This is need and triggered by two flows: + * gc and truncate_partial_data_page. + */ + if (!sync) + goto search; page = find_get_page(mapping, index); if (page && PageUptodate(page)) return page; f2fs_put_page(page, 0); +search: + if (f2fs_lookup_extent_cache(inode, index, &ei)) { + dn.data_blkaddr = ei.blk + index - ei.fofs; + goto got_it; + } set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, index, LOOKUP_NODE); @@ -196,9 +945,10 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) return ERR_PTR(-ENOENT); /* By fallocate(), there is no cached page, but with NEW_ADDR */ - if (dn.data_blkaddr == NEW_ADDR) + if (unlikely(dn.data_blkaddr == NEW_ADDR)) return ERR_PTR(-EINVAL); +got_it: page = grab_cache_page(mapping, index); if (!page) return ERR_PTR(-ENOMEM); @@ -208,11 +958,14 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) return page; } - err = f2fs_readpage(sbi, page, dn.data_blkaddr, - sync ? READ_SYNC : READA); + fio.blk_addr = dn.data_blkaddr; + err = f2fs_submit_page_bio(F2FS_I_SB(inode), page, &fio); + if (err) + return ERR_PTR(err); + if (sync) { wait_on_page_locked(page); - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 0); return ERR_PTR(-EIO); } @@ -227,41 +980,65 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) */ struct page *get_lock_data_page(struct inode *inode, pgoff_t index) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct address_space *mapping = inode->i_mapping; struct dnode_of_data dn; struct page *page; + struct extent_info ei; int err; + struct f2fs_io_info fio = { + .type = DATA, + .rw = READ_SYNC, + }; +repeat: + page = grab_cache_page(mapping, index); + if (!page) + return ERR_PTR(-ENOMEM); + + if (f2fs_lookup_extent_cache(inode, index, &ei)) { + dn.data_blkaddr = ei.blk + index - ei.fofs; + goto got_it; + } set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, index, LOOKUP_NODE); - if (err) + if (err) { + f2fs_put_page(page, 1); return ERR_PTR(err); + } f2fs_put_dnode(&dn); - if (dn.data_blkaddr == NULL_ADDR) + if (unlikely(dn.data_blkaddr == NULL_ADDR)) { + f2fs_put_page(page, 1); return ERR_PTR(-ENOENT); -repeat: - page = grab_cache_page(mapping, index); - if (!page) - return ERR_PTR(-ENOMEM); + } +got_it: if (PageUptodate(page)) return page; - BUG_ON(dn.data_blkaddr == NEW_ADDR); - BUG_ON(dn.data_blkaddr == NULL_ADDR); + /* + * A new dentry page is allocated but not able to be written, since its + * new inode page couldn't be allocated due to -ENOSPC. + * In such the case, its blkaddr can be remained as NEW_ADDR. + * see, f2fs_add_link -> get_new_data_page -> init_inode_metadata. + */ + if (dn.data_blkaddr == NEW_ADDR) { + zero_user_segment(page, 0, PAGE_CACHE_SIZE); + SetPageUptodate(page); + return page; + } - err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC); + fio.blk_addr = dn.data_blkaddr; + err = f2fs_submit_page_bio(F2FS_I_SB(inode), page, &fio); if (err) return ERR_PTR(err); lock_page(page); - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); return ERR_PTR(-EIO); } - if (page->mapping != mapping) { + if (unlikely(page->mapping != mapping)) { f2fs_put_page(page, 1); goto repeat; } @@ -272,34 +1049,28 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index) * Caller ensures that this data page is never allocated. * A new zero-filled data page is allocated in the page cache. * - * Also, caller should grab and release a mutex by calling mutex_lock_op() and - * mutex_unlock_op(). + * Also, caller should grab and release a rwsem by calling f2fs_lock_op() and + * f2fs_unlock_op(). + * Note that, ipage is set only by make_empty_dir. */ -struct page *get_new_data_page(struct inode *inode, pgoff_t index, - bool new_i_size) +struct page *get_new_data_page(struct inode *inode, + struct page *ipage, pgoff_t index, bool new_i_size) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct address_space *mapping = inode->i_mapping; struct page *page; struct dnode_of_data dn; int err; - set_new_dnode(&dn, inode, NULL, NULL, 0); - err = get_dnode_of_data(&dn, index, ALLOC_NODE); + set_new_dnode(&dn, inode, ipage, NULL, 0); + err = f2fs_reserve_block(&dn, index); if (err) return ERR_PTR(err); - - if (dn.data_blkaddr == NULL_ADDR) { - if (reserve_new_block(&dn)) { - f2fs_put_dnode(&dn); - return ERR_PTR(-ENOSPC); - } - } - f2fs_put_dnode(&dn); repeat: page = grab_cache_page(mapping, index); - if (!page) - return ERR_PTR(-ENOMEM); + if (!page) { + err = -ENOMEM; + goto put_err; + } if (PageUptodate(page)) return page; @@ -308,15 +1079,22 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index, zero_user_segment(page, 0, PAGE_CACHE_SIZE); SetPageUptodate(page); } else { - err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC); + struct f2fs_io_info fio = { + .type = DATA, + .rw = READ_SYNC, + .blk_addr = dn.data_blkaddr, + }; + err = f2fs_submit_page_bio(F2FS_I_SB(inode), page, &fio); if (err) - return ERR_PTR(err); + goto put_err; + lock_page(page); - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); - return ERR_PTR(-EIO); + err = -EIO; + goto put_err; } - if (page->mapping != mapping) { + if (unlikely(page->mapping != mapping)) { f2fs_put_page(page, 1); goto repeat; } @@ -325,142 +1103,274 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index, if (new_i_size && i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) { i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT)); - mark_inode_dirty_sync(inode); + /* Only the directory inode sets new_i_size */ + set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); } return page; + +put_err: + f2fs_put_dnode(&dn); + return ERR_PTR(err); } -static void read_end_io(struct bio *bio, int err) +static int __allocate_data_block(struct dnode_of_data *dn) { - const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); + struct f2fs_inode_info *fi = F2FS_I(dn->inode); + struct f2fs_summary sum; + struct node_info ni; + int seg = CURSEG_WARM_DATA; + pgoff_t fofs; - do { - struct page *page = bvec->bv_page; + if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) + return -EPERM; - if (--bvec >= bio->bi_io_vec) - prefetchw(&bvec->bv_page->flags); + dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node); + if (dn->data_blkaddr == NEW_ADDR) + goto alloc; - if (uptodate) { - SetPageUptodate(page); - } else { - ClearPageUptodate(page); - SetPageError(page); - } - unlock_page(page); - } while (bvec >= bio->bi_io_vec); - kfree(bio->bi_private); - bio_put(bio); -} + if (unlikely(!inc_valid_block_count(sbi, dn->inode, 1))) + return -ENOSPC; -/* - * Fill the locked page with data located in the block address. - * Return unlocked page. - */ -int f2fs_readpage(struct f2fs_sb_info *sbi, struct page *page, - block_t blk_addr, int type) -{ - struct block_device *bdev = sbi->sb->s_bdev; - struct bio *bio; +alloc: + get_node_info(sbi, dn->nid, &ni); + set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); - trace_f2fs_readpage(page, blk_addr, type); + if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page) + seg = CURSEG_DIRECT_IO; - down_read(&sbi->bio_sem); + allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr, + &sum, seg); - /* Allocate a new bio */ - bio = f2fs_bio_alloc(bdev, 1); + /* direct IO doesn't use extent cache to maximize the performance */ + set_data_blkaddr(dn); - /* Initialize the bio */ - bio->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); - bio->bi_end_io = read_end_io; + /* update i_size */ + fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + + dn->ofs_in_node; + if (i_size_read(dn->inode) < ((fofs + 1) << PAGE_CACHE_SHIFT)) + i_size_write(dn->inode, ((fofs + 1) << PAGE_CACHE_SHIFT)); - if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) { - kfree(bio->bi_private); - bio_put(bio); - up_read(&sbi->bio_sem); - f2fs_put_page(page, 1); - return -EFAULT; + return 0; +} + +static void __allocate_data_blocks(struct inode *inode, loff_t offset, + size_t count) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct dnode_of_data dn; + u64 start = F2FS_BYTES_TO_BLK(offset); + u64 len = F2FS_BYTES_TO_BLK(count); + bool allocated; + u64 end_offset; + + while (len) { + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); + + /* When reading holes, we need its node page */ + set_new_dnode(&dn, inode, NULL, NULL, 0); + if (get_dnode_of_data(&dn, start, ALLOC_NODE)) + goto out; + + allocated = false; + end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); + + while (dn.ofs_in_node < end_offset && len) { + block_t blkaddr; + + blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) { + if (__allocate_data_block(&dn)) + goto sync_out; + allocated = true; + } + len--; + start++; + dn.ofs_in_node++; + } + + if (allocated) + sync_inode_page(&dn); + + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); } + return; - submit_bio(type, bio); - up_read(&sbi->bio_sem); - return 0; +sync_out: + if (allocated) + sync_inode_page(&dn); + f2fs_put_dnode(&dn); +out: + f2fs_unlock_op(sbi); + return; } /* - * This function should be used by the data read flow only where it - * does not check the "create" flag that indicates block allocation. - * The reason for this special functionality is to exploit VFS readahead - * mechanism. + * get_data_block() now supported readahead/bmap/rw direct_IO with mapped bh. + * If original data blocks are allocated, then give them to blockdev. + * Otherwise, + * a. preallocate requested block addresses + * b. do not use extent cache for better performance + * c. give the block addresses to blockdev */ -static int get_data_block_ro(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) +static int __get_data_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create, bool fiemap) { unsigned int blkbits = inode->i_sb->s_blocksize_bits; unsigned maxblocks = bh_result->b_size >> blkbits; struct dnode_of_data dn; - pgoff_t pgofs; - int err; + int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA; + pgoff_t pgofs, end_offset; + int err = 0, ofs = 1; + struct extent_info ei; + bool allocated = false; /* Get the page offset from the block offset(iblock) */ pgofs = (pgoff_t)(iblock >> (PAGE_CACHE_SHIFT - blkbits)); - if (check_extent_cache(inode, pgofs, bh_result)) { - trace_f2fs_get_data_block(inode, iblock, bh_result, 0); - return 0; + if (f2fs_lookup_extent_cache(inode, pgofs, &ei)) { + f2fs_map_bh(inode->i_sb, pgofs, &ei, bh_result); + goto out; } + if (create) + f2fs_lock_op(F2FS_I_SB(inode)); + /* When reading holes, we need its node page */ set_new_dnode(&dn, inode, NULL, NULL, 0); - err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE_RA); + err = get_dnode_of_data(&dn, pgofs, mode); if (err) { - trace_f2fs_get_data_block(inode, iblock, bh_result, err); - return (err == -ENOENT) ? 0 : err; + if (err == -ENOENT) + err = 0; + goto unlock_out; } + if (dn.data_blkaddr == NEW_ADDR && !fiemap) + goto put_out; - /* It does not support data allocation */ - BUG_ON(create); - - if (dn.data_blkaddr != NEW_ADDR && dn.data_blkaddr != NULL_ADDR) { - int i; - unsigned int end_offset; + if (dn.data_blkaddr != NULL_ADDR) { + clear_buffer_new(bh_result); + map_bh(bh_result, inode->i_sb, dn.data_blkaddr); + } else if (create) { + err = __allocate_data_block(&dn); + if (err) + goto put_out; + allocated = true; + set_buffer_new(bh_result); + map_bh(bh_result, inode->i_sb, dn.data_blkaddr); + } else { + goto put_out; + } - end_offset = IS_INODE(dn.node_page) ? - ADDRS_PER_INODE : - ADDRS_PER_BLOCK; + end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); + bh_result->b_size = (((size_t)1) << blkbits); + dn.ofs_in_node++; + pgofs++; + +get_next: + if (dn.ofs_in_node >= end_offset) { + if (allocated) + sync_inode_page(&dn); + allocated = false; + f2fs_put_dnode(&dn); + + set_new_dnode(&dn, inode, NULL, NULL, 0); + err = get_dnode_of_data(&dn, pgofs, mode); + if (err) { + if (err == -ENOENT) + err = 0; + goto unlock_out; + } + if (dn.data_blkaddr == NEW_ADDR && !fiemap) + goto put_out; - clear_buffer_new(bh_result); + end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); + } - /* Give more consecutive addresses for the read ahead */ - for (i = 0; i < end_offset - dn.ofs_in_node; i++) - if (((datablock_addr(dn.node_page, - dn.ofs_in_node + i)) - != (dn.data_blkaddr + i)) || maxblocks == i) - break; - map_bh(bh_result, inode->i_sb, dn.data_blkaddr); - bh_result->b_size = (i << blkbits); + if (maxblocks > (bh_result->b_size >> blkbits)) { + block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + if (blkaddr == NULL_ADDR && create) { + err = __allocate_data_block(&dn); + if (err) + goto sync_out; + allocated = true; + set_buffer_new(bh_result); + blkaddr = dn.data_blkaddr; + } + /* Give more consecutive addresses for the readahead */ + if (blkaddr == (bh_result->b_blocknr + ofs)) { + ofs++; + dn.ofs_in_node++; + pgofs++; + bh_result->b_size += (((size_t)1) << blkbits); + goto get_next; + } } +sync_out: + if (allocated) + sync_inode_page(&dn); +put_out: f2fs_put_dnode(&dn); - trace_f2fs_get_data_block(inode, iblock, bh_result, 0); - return 0; +unlock_out: + if (create) + f2fs_unlock_op(F2FS_I_SB(inode)); +out: + trace_f2fs_get_data_block(inode, iblock, bh_result, err); + return err; +} + +static int get_data_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + return __get_data_block(inode, iblock, bh_result, create, false); +} + +static int get_data_block_fiemap(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + return __get_data_block(inode, iblock, bh_result, create, true); +} + +int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len) +{ + return generic_block_fiemap(inode, fieinfo, + start, len, get_data_block_fiemap); } static int f2fs_read_data_page(struct file *file, struct page *page) { - return mpage_readpage(page, get_data_block_ro); + struct inode *inode = page->mapping->host; + int ret = -EAGAIN; + + trace_f2fs_readpage(page, DATA); + + /* If the file has inline data, try to read it directly */ + if (f2fs_has_inline_data(inode)) + ret = f2fs_read_inline_data(inode, page); + if (ret == -EAGAIN) + ret = mpage_readpage(page, get_data_block); + + return ret; } static int f2fs_read_data_pages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { - return mpage_readpages(mapping, pages, nr_pages, get_data_block_ro); + struct inode *inode = file->f_mapping->host; + + /* If the file has inline data, skip readpages */ + if (f2fs_has_inline_data(inode)) + return 0; + + return mpage_readpages(mapping, pages, nr_pages, get_data_block); } -int do_write_data_page(struct page *page) +int do_write_data_page(struct page *page, struct f2fs_io_info *fio) { struct inode *inode = page->mapping->host; - block_t old_blk_addr, new_blk_addr; struct dnode_of_data dn; int err = 0; @@ -469,11 +1379,13 @@ int do_write_data_page(struct page *page) if (err) return err; - old_blk_addr = dn.data_blkaddr; + fio->blk_addr = dn.data_blkaddr; /* This page is already truncated */ - if (old_blk_addr == NULL_ADDR) + if (fio->blk_addr == NULL_ADDR) { + ClearPageUptodate(page); goto out_writepage; + } set_page_writeback(page); @@ -481,14 +1393,20 @@ int do_write_data_page(struct page *page) * If current allocation needs SSR, * it had better in-place writes for updated data. */ - if (old_blk_addr != NEW_ADDR && !is_cold_data(page) && - need_inplace_update(inode)) { - rewrite_data_page(F2FS_SB(inode->i_sb), page, - old_blk_addr); + if (unlikely(fio->blk_addr != NEW_ADDR && + !is_cold_data(page) && + need_inplace_update(inode))) { + rewrite_data_page(page, fio); + set_inode_flag(F2FS_I(inode), FI_UPDATE_WRITE); + trace_f2fs_do_write_data_page(page, IPU); } else { - write_data_page(inode, page, &dn, - old_blk_addr, &new_blk_addr); - update_extent_cache(new_blk_addr, &dn); + write_data_page(page, &dn, fio); + set_data_blkaddr(&dn); + f2fs_update_extent_cache(&dn); + trace_f2fs_do_write_data_page(page, OPU); + set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); + if (page->index == 0) + set_inode_flag(F2FS_I(inode), FI_FIRST_BLOCK_WRITTEN); } out_writepage: f2fs_put_dnode(&dn); @@ -499,13 +1417,19 @@ static int f2fs_write_data_page(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); loff_t i_size = i_size_read(inode); const pgoff_t end_index = ((unsigned long long) i_size) >> PAGE_CACHE_SHIFT; - unsigned offset; + unsigned offset = 0; bool need_balance_fs = false; int err = 0; + struct f2fs_io_info fio = { + .type = DATA, + .rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC : WRITE, + }; + + trace_f2fs_writepage(page, DATA); if (page->index < end_index) goto write; @@ -515,55 +1439,66 @@ static int f2fs_write_data_page(struct page *page, * this page does not have to be written to disk. */ offset = i_size & (PAGE_CACHE_SIZE - 1); - if ((page->index >= end_index + 1) || !offset) { - if (S_ISDIR(inode->i_mode)) { - dec_page_count(sbi, F2FS_DIRTY_DENTS); - inode_dec_dirty_dents(inode); - } + if ((page->index >= end_index + 1) || !offset) goto out; - } zero_user_segment(page, offset, PAGE_CACHE_SIZE); write: - if (sbi->por_doing) { - err = AOP_WRITEPAGE_ACTIVATE; + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) + goto redirty_out; + if (f2fs_is_drop_cache(inode)) + goto out; + if (f2fs_is_volatile_file(inode) && !wbc->for_reclaim && + available_free_memory(sbi, BASE_CHECK)) goto redirty_out; - } /* Dentry blocks are controlled by checkpoint */ if (S_ISDIR(inode->i_mode)) { - dec_page_count(sbi, F2FS_DIRTY_DENTS); - inode_dec_dirty_dents(inode); - err = do_write_data_page(page); - } else { - int ilock = mutex_lock_op(sbi); - err = do_write_data_page(page); - mutex_unlock_op(sbi, ilock); - need_balance_fs = true; + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; + err = do_write_data_page(page, &fio); + goto done; } - if (err == -ENOENT) + + /* we should bypass data pages to proceed the kworkder jobs */ + if (unlikely(f2fs_cp_error(sbi))) { + SetPageError(page); goto out; - else if (err) + } + + if (!wbc->for_reclaim) + need_balance_fs = true; + else if (has_not_enough_free_secs(sbi, 0)) goto redirty_out; - if (wbc->for_reclaim) - f2fs_submit_bio(sbi, DATA, true); + err = -EAGAIN; + f2fs_lock_op(sbi); + if (f2fs_has_inline_data(inode)) + err = f2fs_write_inline_data(inode, page); + if (err == -EAGAIN) + err = do_write_data_page(page, &fio); + f2fs_unlock_op(sbi); +done: + if (err && err != -ENOENT) + goto redirty_out; clear_cold_data(page); out: + inode_dec_dirty_pages(inode); + if (err) + ClearPageUptodate(page); unlock_page(page); if (need_balance_fs) f2fs_balance_fs(sbi); + if (wbc->for_reclaim) + f2fs_submit_merged_bio(sbi, DATA, WRITE); return 0; redirty_out: - wbc->pages_skipped++; - set_page_dirty(page); - return err; + redirty_page_for_writepage(wbc, page); + return AOP_WRITEPAGE_ACTIVATE; } -#define MAX_DESIRED_PAGES_WP 4096 - static int __f2fs_writepage(struct page *page, struct writeback_control *wbc, void *data) { @@ -577,34 +1512,49 @@ static int f2fs_write_data_pages(struct address_space *mapping, struct writeback_control *wbc) { struct inode *inode = mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - bool locked = false; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); int ret; - long excess_nrtw = 0, desired_nrtw; + long diff; + + trace_f2fs_writepages(mapping->host, wbc, DATA); /* deal with chardevs and other special file */ if (!mapping->a_ops->writepage) return 0; - if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) { - desired_nrtw = MAX_DESIRED_PAGES_WP; - excess_nrtw = desired_nrtw - wbc->nr_to_write; - wbc->nr_to_write = desired_nrtw; - } + if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE && + get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) && + available_free_memory(sbi, DIRTY_DENTS)) + goto skip_write; + + /* during POR, we don't need to trigger writepage at all. */ + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) + goto skip_write; + + diff = nr_pages_to_write(sbi, DATA, wbc); - if (!S_ISDIR(inode->i_mode)) { - mutex_lock(&sbi->writepages); - locked = true; - } ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); - if (locked) - mutex_unlock(&sbi->writepages); - f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); + + f2fs_submit_merged_bio(sbi, DATA, WRITE); remove_dirty_dir_inode(inode); - wbc->nr_to_write -= excess_nrtw; + wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); return ret; + +skip_write: + wbc->pages_skipped += get_dirty_pages(inode); + return 0; +} + +static void f2fs_write_failed(struct address_space *mapping, loff_t to) +{ + struct inode *inode = mapping->host; + + if (to > inode->i_size) { + truncate_pagecache(inode, 0, inode->i_size); + truncate_blocks(inode, inode->i_size, true); + } } static int f2fs_write_begin(struct file *file, struct address_space *mapping, @@ -612,42 +1562,69 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) { struct inode *inode = mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct page *page; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct page *page, *ipage; pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; struct dnode_of_data dn; int err = 0; - int ilock; - /* for nobh_write_end */ - *fsdata = NULL; + trace_f2fs_write_begin(inode, pos, len, flags); f2fs_balance_fs(sbi); + + /* + * We should check this at this moment to avoid deadlock on inode page + * and #0 page. The locking rule for inline_data conversion should be: + * lock_page(page #0) -> lock_page(inode_page) + */ + if (index != 0) { + err = f2fs_convert_inline_inode(inode); + if (err) + goto fail; + } repeat: page = grab_cache_page_write_begin(mapping, index, flags); - if (!page) - return -ENOMEM; + if (!page) { + err = -ENOMEM; + goto fail; + } + *pagep = page; - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); - set_new_dnode(&dn, inode, NULL, NULL, 0); - err = get_dnode_of_data(&dn, index, ALLOC_NODE); - if (err) - goto err; + /* check inline_data */ + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + err = PTR_ERR(ipage); + goto unlock_fail; + } - if (dn.data_blkaddr == NULL_ADDR) - err = reserve_new_block(&dn); + set_new_dnode(&dn, inode, ipage, ipage, 0); - f2fs_put_dnode(&dn); + if (f2fs_has_inline_data(inode)) { + if (pos + len <= MAX_INLINE_DATA) { + read_inline_data(page, ipage); + set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); + sync_inode_page(&dn); + goto put_next; + } + err = f2fs_convert_inline_page(&dn, page); + if (err) + goto put_fail; + } + err = f2fs_reserve_block(&dn, index); if (err) - goto err; - - mutex_unlock_op(sbi, ilock); + goto put_fail; +put_next: + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); if ((len == PAGE_CACHE_SIZE) || PageUptodate(page)) return 0; + f2fs_wait_on_page_writeback(page, DATA); + if ((pos & PAGE_CACHE_MASK) >= i_size_read(inode)) { unsigned start = pos & (PAGE_CACHE_SIZE - 1); unsigned end = start + len; @@ -660,15 +1637,22 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, if (dn.data_blkaddr == NEW_ADDR) { zero_user_segment(page, 0, PAGE_CACHE_SIZE); } else { - err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC); + struct f2fs_io_info fio = { + .type = DATA, + .rw = READ_SYNC, + .blk_addr = dn.data_blkaddr, + }; + err = f2fs_submit_page_bio(sbi, page, &fio); if (err) - return err; + goto fail; + lock_page(page); - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); - return -EIO; + err = -EIO; + goto fail; } - if (page->mapping != mapping) { + if (unlikely(page->mapping != mapping)) { f2fs_put_page(page, 1); goto repeat; } @@ -678,39 +1662,115 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, clear_cold_data(page); return 0; -err: - mutex_unlock_op(sbi, ilock); +put_fail: + f2fs_put_dnode(&dn); +unlock_fail: + f2fs_unlock_op(sbi); f2fs_put_page(page, 1); +fail: + f2fs_write_failed(mapping, pos + len); return err; } -static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb, +static int f2fs_write_end(struct file *file, + struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + struct inode *inode = page->mapping->host; + + trace_f2fs_write_end(inode, pos, len, copied); + + set_page_dirty(page); + + if (pos + copied > i_size_read(inode)) { + i_size_write(inode, pos + copied); + mark_inode_dirty(inode); + update_inode_page(inode); + } + + f2fs_put_page(page, 1); + return copied; +} + +static int check_direct_IO(struct inode *inode, int rw, const struct iovec *iov, loff_t offset, unsigned long nr_segs) +{ + unsigned blocksize_mask = inode->i_sb->s_blocksize - 1; + int i; + + if (rw == READ) + return 0; + + if (offset & blocksize_mask) + return -EINVAL; + + for (i = 0; i < nr_segs; i++) + if (iov[i].iov_len & blocksize_mask) + return -EINVAL; + return 0; +} + +static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, loff_t offset, + unsigned long nr_segs) { struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + size_t count = iov_length(iov, nr_segs); + int err; - if (rw == WRITE) + /* we don't need to use inline_data strictly */ + if (f2fs_has_inline_data(inode)) { + err = f2fs_convert_inline_inode(inode); + if (err) + return err; + } + + if (check_direct_IO(inode, rw, iov, offset, nr_segs)) return 0; - /* Needs synchronization with the cleaner */ - return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, - get_data_block_ro); + trace_f2fs_direct_IO_enter(inode, offset, count, rw); + + if (rw & WRITE) + __allocate_data_blocks(inode, offset, count); + + err = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, + get_data_block); + if (err < 0 && (rw & WRITE)) + f2fs_write_failed(mapping, offset + count); + + trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); + + return err; } -static void f2fs_invalidate_data_page(struct page *page, unsigned long offset) +void f2fs_invalidate_page(struct page *page, unsigned long offset) { struct inode *inode = page->mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - if (S_ISDIR(inode->i_mode) && PageDirty(page)) { - dec_page_count(sbi, F2FS_DIRTY_DENTS); - inode_dec_dirty_dents(inode); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + + if (inode->i_ino >= F2FS_ROOT_INO(sbi) && (offset % PAGE_CACHE_SIZE)) + return; + + if (PageDirty(page)) { + if (inode->i_ino == F2FS_META_INO(sbi)) + dec_page_count(sbi, F2FS_DIRTY_META); + else if (inode->i_ino == F2FS_NODE_INO(sbi)) + dec_page_count(sbi, F2FS_DIRTY_NODES); + else + inode_dec_dirty_pages(inode); } ClearPagePrivate(page); } -static int f2fs_release_data_page(struct page *page, gfp_t wait) +int f2fs_release_page(struct page *page, gfp_t wait) { + /* If this is dirty page, keep PagePrivate */ + if (PageDirty(page)) + return 0; + ClearPagePrivate(page); return 1; } @@ -720,10 +1780,20 @@ static int f2fs_set_data_page_dirty(struct page *page) struct address_space *mapping = page->mapping; struct inode *inode = mapping->host; + trace_f2fs_set_page_dirty(page, DATA); + SetPageUptodate(page); + + if (f2fs_is_atomic_file(inode)) { + register_inmem_page(inode, page); + return 1; + } + + mark_inode_dirty(inode); + if (!PageDirty(page)) { __set_page_dirty_nobuffers(page); - set_dirty_dir_page(inode, page); + update_dirty_page(inode, page); return 1; } return 0; @@ -731,7 +1801,46 @@ static int f2fs_set_data_page_dirty(struct page *page) static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) { - return generic_block_bmap(mapping, block, get_data_block_ro); + struct inode *inode = mapping->host; + + /* we don't need to use inline_data strictly */ + if (f2fs_has_inline_data(inode)) { + int err = f2fs_convert_inline_inode(inode); + if (err) + return err; + } + return generic_block_bmap(mapping, block, get_data_block); +} + +void init_extent_cache_info(struct f2fs_sb_info *sbi) +{ + INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO); + init_rwsem(&sbi->extent_tree_lock); + INIT_LIST_HEAD(&sbi->extent_list); + spin_lock_init(&sbi->extent_lock); + sbi->total_ext_tree = 0; + atomic_set(&sbi->total_ext_node, 0); +} + +int __init create_extent_cache(void) +{ + extent_tree_slab = f2fs_kmem_cache_create("f2fs_extent_tree", + sizeof(struct extent_tree)); + if (!extent_tree_slab) + return -ENOMEM; + extent_node_slab = f2fs_kmem_cache_create("f2fs_extent_node", + sizeof(struct extent_node)); + if (!extent_node_slab) { + kmem_cache_destroy(extent_tree_slab); + return -ENOMEM; + } + return 0; +} + +void destroy_extent_cache(void) +{ + kmem_cache_destroy(extent_node_slab); + kmem_cache_destroy(extent_tree_slab); } const struct address_space_operations f2fs_dblock_aops = { @@ -740,10 +1849,10 @@ const struct address_space_operations f2fs_dblock_aops = { .writepage = f2fs_write_data_page, .writepages = f2fs_write_data_pages, .write_begin = f2fs_write_begin, - .write_end = nobh_write_end, + .write_end = f2fs_write_end, .set_page_dirty = f2fs_set_data_page_dirty, - .invalidatepage = f2fs_invalidate_data_page, - .releasepage = f2fs_release_data_page, + .invalidatepage = f2fs_invalidate_page, + .releasepage = f2fs_release_page, .direct_IO = f2fs_direct_IO, .bmap = f2fs_bmap, }; diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 8d9943786c318..f5388f37217e0 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -24,37 +24,45 @@ #include "gc.h" static LIST_HEAD(f2fs_stat_list); -static struct dentry *debugfs_root; +static struct dentry *f2fs_debugfs_root; static DEFINE_MUTEX(f2fs_stat_mutex); static void update_general_status(struct f2fs_sb_info *sbi) { - struct f2fs_stat_info *si = sbi->stat_info; + struct f2fs_stat_info *si = F2FS_STAT(sbi); int i; - /* valid check of the segment numbers */ + /* validation check of the segment numbers */ si->hit_ext = sbi->read_hit_ext; si->total_ext = sbi->total_hit_ext; + si->ext_tree = sbi->total_ext_tree; + si->ext_node = atomic_read(&sbi->total_ext_node); si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); si->ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS); si->ndirty_dirs = sbi->n_dirty_dirs; si->ndirty_meta = get_pages(sbi, F2FS_DIRTY_META); + si->inmem_pages = get_pages(sbi, F2FS_INMEM_PAGES); + si->wb_pages = get_pages(sbi, F2FS_WRITEBACK); si->total_count = (int)sbi->user_block_count / sbi->blocks_per_seg; si->rsvd_segs = reserved_segments(sbi); si->overp_segs = overprovision_segments(sbi); si->valid_count = valid_user_blocks(sbi); si->valid_node_count = valid_node_count(sbi); si->valid_inode_count = valid_inode_count(sbi); + si->inline_inode = atomic_read(&sbi->inline_inode); + si->inline_dir = atomic_read(&sbi->inline_dir); si->utilization = utilization(sbi); si->free_segs = free_segments(sbi); si->free_secs = free_sections(sbi); si->prefree_count = prefree_segments(sbi); si->dirty_count = dirty_segments(sbi); - si->node_pages = sbi->node_inode->i_mapping->nrpages; - si->meta_pages = sbi->meta_inode->i_mapping->nrpages; + si->node_pages = NODE_MAPPING(sbi)->nrpages; + si->meta_pages = META_MAPPING(sbi)->nrpages; si->nats = NM_I(sbi)->nat_cnt; - si->sits = SIT_I(sbi)->dirty_sentries; + si->dirty_nats = NM_I(sbi)->dirty_nat_cnt; + si->sits = MAIN_SEGS(sbi); + si->dirty_sits = SIT_I(sbi)->dirty_sentries; si->fnids = NM_I(sbi)->fcnt; si->bg_gc = sbi->bg_gc; si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg) @@ -76,6 +84,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->segment_count[i] = sbi->segment_count[i]; si->block_count[i] = sbi->block_count[i]; } + + si->inplace_count = atomic_read(&sbi->inplace_count); } /* @@ -83,9 +93,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) */ static void update_sit_info(struct f2fs_sb_info *sbi) { - struct f2fs_stat_info *si = sbi->stat_info; + struct f2fs_stat_info *si = F2FS_STAT(sbi); unsigned int blks_per_sec, hblks_per_sec, total_vblocks, bimodal, dist; - struct sit_info *sit_i = SIT_I(sbi); unsigned int segno, vblocks; int ndirty = 0; @@ -93,8 +102,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi) total_vblocks = 0; blks_per_sec = sbi->segs_per_sec * (1 << sbi->log_blocks_per_seg); hblks_per_sec = blks_per_sec / 2; - mutex_lock(&sit_i->sentry_lock); - for (segno = 0; segno < TOTAL_SEGS(sbi); segno += sbi->segs_per_sec) { + for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) { vblocks = get_valid_blocks(sbi, segno, sbi->segs_per_sec); dist = abs(vblocks - hblks_per_sec); bimodal += dist * dist; @@ -104,8 +112,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi) ndirty++; } } - mutex_unlock(&sit_i->sentry_lock); - dist = TOTAL_SECS(sbi) * hblks_per_sec * hblks_per_sec / 100; + dist = MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec / 100; si->bimodal = bimodal / dist; if (si->dirty_count) si->avg_vblocks = total_vblocks / ndirty; @@ -118,8 +125,9 @@ static void update_sit_info(struct f2fs_sb_info *sbi) */ static void update_mem_info(struct f2fs_sb_info *sbi) { - struct f2fs_stat_info *si = sbi->stat_info; + struct f2fs_stat_info *si = F2FS_STAT(sbi); unsigned npages; + int i; if (si->base_mem) goto get_cache; @@ -133,17 +141,18 @@ static void update_mem_info(struct f2fs_sb_info *sbi) /* build sit */ si->base_mem += sizeof(struct sit_info); - si->base_mem += TOTAL_SEGS(sbi) * sizeof(struct seg_entry); - si->base_mem += f2fs_bitmap_size(TOTAL_SEGS(sbi)); - si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * TOTAL_SEGS(sbi); + si->base_mem += MAIN_SEGS(sbi) * sizeof(struct seg_entry); + si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi)); + si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi); + si->base_mem += SIT_VBLOCK_MAP_SIZE; if (sbi->segs_per_sec > 1) - si->base_mem += TOTAL_SECS(sbi) * sizeof(struct sec_entry); + si->base_mem += MAIN_SECS(sbi) * sizeof(struct sec_entry); si->base_mem += __bitmap_size(sbi, SIT_BITMAP); /* build free segmap */ si->base_mem += sizeof(struct free_segmap_info); - si->base_mem += f2fs_bitmap_size(TOTAL_SEGS(sbi)); - si->base_mem += f2fs_bitmap_size(TOTAL_SECS(sbi)); + si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi)); + si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi)); /* build curseg */ si->base_mem += sizeof(struct curseg_info) * NR_CURSEG_TYPE; @@ -151,36 +160,52 @@ static void update_mem_info(struct f2fs_sb_info *sbi) /* build dirty segmap */ si->base_mem += sizeof(struct dirty_seglist_info); - si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(TOTAL_SEGS(sbi)); - si->base_mem += f2fs_bitmap_size(TOTAL_SECS(sbi)); + si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(MAIN_SEGS(sbi)); + si->base_mem += f2fs_bitmap_size(MAIN_SECS(sbi)); - /* buld nm */ + /* build nm */ si->base_mem += sizeof(struct f2fs_nm_info); si->base_mem += __bitmap_size(sbi, NAT_BITMAP); +get_cache: + si->cache_mem = 0; + /* build gc */ - si->base_mem += sizeof(struct f2fs_gc_kthread); + if (sbi->gc_thread) + si->cache_mem += sizeof(struct f2fs_gc_kthread); + + /* build merge flush thread */ + if (SM_I(sbi)->cmd_control_info) + si->cache_mem += sizeof(struct flush_cmd_control); -get_cache: /* free nids */ - si->cache_mem = NM_I(sbi)->fcnt; - si->cache_mem += NM_I(sbi)->nat_cnt; - npages = sbi->node_inode->i_mapping->nrpages; - si->cache_mem += npages << PAGE_CACHE_SHIFT; - npages = sbi->meta_inode->i_mapping->nrpages; - si->cache_mem += npages << PAGE_CACHE_SHIFT; - si->cache_mem += sbi->n_orphans * sizeof(struct orphan_inode_entry); - si->cache_mem += sbi->n_dirty_dirs * sizeof(struct dir_inode_entry); + si->cache_mem += NM_I(sbi)->fcnt * sizeof(struct free_nid); + si->cache_mem += NM_I(sbi)->nat_cnt * sizeof(struct nat_entry); + si->cache_mem += NM_I(sbi)->dirty_nat_cnt * + sizeof(struct nat_entry_set); + si->cache_mem += si->inmem_pages * sizeof(struct inmem_pages); + si->cache_mem += sbi->n_dirty_dirs * sizeof(struct inode_entry); + for (i = 0; i <= UPDATE_INO; i++) + si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry); + si->cache_mem += sbi->total_ext_tree * sizeof(struct extent_tree); + si->cache_mem += atomic_read(&sbi->total_ext_node) * + sizeof(struct extent_node); + + si->page_mem = 0; + npages = NODE_MAPPING(sbi)->nrpages; + si->page_mem += npages << PAGE_CACHE_SHIFT; + npages = META_MAPPING(sbi)->nrpages; + si->page_mem += npages << PAGE_CACHE_SHIFT; } static int stat_show(struct seq_file *s, void *v) { - struct f2fs_stat_info *si, *next; + struct f2fs_stat_info *si; int i = 0; int j; mutex_lock(&f2fs_stat_mutex); - list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) { + list_for_each_entry(si, &f2fs_stat_list, stat_list) { char devname[BDEVNAME_SIZE]; update_general_status(si->sbi); @@ -200,6 +225,10 @@ static int stat_show(struct seq_file *s, void *v) seq_printf(s, "Other: %u)\n - Data: %u\n", si->valid_node_count - si->valid_inode_count, si->valid_count - si->valid_node_count); + seq_printf(s, " - Inline_data Inode: %u\n", + si->inline_inode); + seq_printf(s, " - Inline_dentry Inode: %u\n", + si->inline_dir); seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n", si->main_area_segs, si->main_area_sections, si->main_area_zones); @@ -233,41 +262,52 @@ static int stat_show(struct seq_file *s, void *v) si->dirty_count); seq_printf(s, " - Prefree: %d\n - Free: %d (%d)\n\n", si->prefree_count, si->free_segs, si->free_secs); + seq_printf(s, "CP calls: %d\n", si->cp_count); seq_printf(s, "GC calls: %d (BG: %d)\n", si->call_count, si->bg_gc); - seq_printf(s, " - data segments : %d\n", si->data_segs); - seq_printf(s, " - node segments : %d\n", si->node_segs); - seq_printf(s, "Try to move %d blocks\n", si->tot_blks); - seq_printf(s, " - data blocks : %d\n", si->data_blks); - seq_printf(s, " - node blocks : %d\n", si->node_blks); + seq_printf(s, " - data segments : %d (%d)\n", + si->data_segs, si->bg_data_segs); + seq_printf(s, " - node segments : %d (%d)\n", + si->node_segs, si->bg_node_segs); + seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks, + si->bg_data_blks + si->bg_node_blks); + seq_printf(s, " - data blocks : %d (%d)\n", si->data_blks, + si->bg_data_blks); + seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks, + si->bg_node_blks); seq_printf(s, "\nExtent Hit Ratio: %d / %d\n", si->hit_ext, si->total_ext); - seq_printf(s, "\nBalancing F2FS Async:\n"); - seq_printf(s, " - nodes %4d in %4d\n", + seq_printf(s, "\nExtent Tree Count: %d\n", si->ext_tree); + seq_printf(s, "\nExtent Node Count: %d\n", si->ext_node); + seq_puts(s, "\nBalancing F2FS Async:\n"); + seq_printf(s, " - inmem: %4d, wb: %4d\n", + si->inmem_pages, si->wb_pages); + seq_printf(s, " - nodes: %4d in %4d\n", si->ndirty_node, si->node_pages); - seq_printf(s, " - dents %4d in dirs:%4d\n", + seq_printf(s, " - dents: %4d in dirs:%4d\n", si->ndirty_dent, si->ndirty_dirs); - seq_printf(s, " - meta %4d in %4d\n", + seq_printf(s, " - meta: %4d in %4d\n", si->ndirty_meta, si->meta_pages); - seq_printf(s, " - NATs %5d > %lu\n", - si->nats, NM_WOUT_THRESHOLD); - seq_printf(s, " - SITs: %5d\n - free_nids: %5d\n", - si->sits, si->fnids); - seq_printf(s, "\nDistribution of User Blocks:"); - seq_printf(s, " [ valid | invalid | free ]\n"); - seq_printf(s, " ["); + seq_printf(s, " - NATs: %9d/%9d\n - SITs: %9d/%9d\n", + si->dirty_nats, si->nats, si->dirty_sits, si->sits); + seq_printf(s, " - free_nids: %9d\n", + si->fnids); + seq_puts(s, "\nDistribution of User Blocks:"); + seq_puts(s, " [ valid | invalid | free ]\n"); + seq_puts(s, " ["); for (j = 0; j < si->util_valid; j++) - seq_printf(s, "-"); - seq_printf(s, "|"); + seq_putc(s, '-'); + seq_putc(s, '|'); for (j = 0; j < si->util_invalid; j++) - seq_printf(s, "-"); - seq_printf(s, "|"); + seq_putc(s, '-'); + seq_putc(s, '|'); for (j = 0; j < si->util_free; j++) - seq_printf(s, "-"); - seq_printf(s, "]\n\n"); + seq_putc(s, '-'); + seq_puts(s, "]\n\n"); + seq_printf(s, "IPU: %u blocks\n", si->inplace_count); seq_printf(s, "SSR: %u blocks in %u segments\n", si->block_count[SSR], si->segment_count[SSR]); seq_printf(s, "LFS: %u blocks in %u segments\n", @@ -280,9 +320,14 @@ static int stat_show(struct seq_file *s, void *v) /* memory footprint */ update_mem_info(si->sbi); - seq_printf(s, "\nMemory: %u KB = static: %u + cached: %u\n", - (si->base_mem + si->cache_mem) >> 10, - si->base_mem >> 10, si->cache_mem >> 10); + seq_printf(s, "\nMemory: %u KB\n", + (si->base_mem + si->cache_mem + si->page_mem) >> 10); + seq_printf(s, " - static: %u KB\n", + si->base_mem >> 10); + seq_printf(s, " - cached: %u KB\n", + si->cache_mem >> 10); + seq_printf(s, " - paged : %u KB\n", + si->page_mem >> 10); } mutex_unlock(&f2fs_stat_mutex); return 0; @@ -305,11 +350,10 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); struct f2fs_stat_info *si; - sbi->stat_info = kzalloc(sizeof(struct f2fs_stat_info), GFP_KERNEL); - if (!sbi->stat_info) + si = kzalloc(sizeof(struct f2fs_stat_info), GFP_KERNEL); + if (!si) return -ENOMEM; - si = sbi->stat_info; si->all_area_segs = le32_to_cpu(raw_super->segment_count); si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit); si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat); @@ -319,6 +363,11 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) si->main_area_zones = si->main_area_sections / le32_to_cpu(raw_super->secs_per_zone); si->sbi = sbi; + sbi->stat_info = si; + + atomic_set(&sbi->inline_inode, 0); + atomic_set(&sbi->inline_dir, 0); + atomic_set(&sbi->inplace_count, 0); mutex_lock(&f2fs_stat_mutex); list_add_tail(&si->stat_list, &f2fs_stat_list); @@ -329,25 +378,36 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { - struct f2fs_stat_info *si = sbi->stat_info; + struct f2fs_stat_info *si = F2FS_STAT(sbi); mutex_lock(&f2fs_stat_mutex); list_del(&si->stat_list); mutex_unlock(&f2fs_stat_mutex); - kfree(sbi->stat_info); + kfree(si); } void __init f2fs_create_root_stats(void) { - debugfs_root = debugfs_create_dir("f2fs", NULL); - if (debugfs_root) - debugfs_create_file("status", S_IRUGO, debugfs_root, - NULL, &stat_fops); + struct dentry *file; + + f2fs_debugfs_root = debugfs_create_dir("f2fs", NULL); + if (!f2fs_debugfs_root) + return; + + file = debugfs_create_file("status", S_IRUGO, f2fs_debugfs_root, + NULL, &stat_fops); + if (!file) { + debugfs_remove(f2fs_debugfs_root); + f2fs_debugfs_root = NULL; + } } void f2fs_destroy_root_stats(void) { - debugfs_remove_recursive(debugfs_root); - debugfs_root = NULL; + if (!f2fs_debugfs_root) + return; + + debugfs_remove_recursive(f2fs_debugfs_root); + f2fs_debugfs_root = NULL; } diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 1ac6b93036b7a..a08e088ca99a3 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -13,6 +13,7 @@ #include "f2fs.h" #include "node.h" #include "acl.h" +#include "xattr.h" static unsigned long dir_blocks(struct inode *inode) { @@ -20,12 +21,12 @@ static unsigned long dir_blocks(struct inode *inode) >> PAGE_CACHE_SHIFT; } -static unsigned int dir_buckets(unsigned int level) +static unsigned int dir_buckets(unsigned int level, int dir_level) { - if (level < MAX_DIR_HASH_DEPTH / 2) - return 1 << level; + if (level + dir_level < MAX_DIR_HASH_DEPTH / 2) + return 1 << (level + dir_level); else - return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1); + return MAX_DIR_BUCKETS; } static unsigned int bucket_blocks(unsigned int level) @@ -36,7 +37,7 @@ static unsigned int bucket_blocks(unsigned int level) return 4; } -static unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { +unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { [F2FS_FT_UNKNOWN] = DT_UNKNOWN, [F2FS_FT_REG_FILE] = DT_REG, [F2FS_FT_DIR] = DT_DIR, @@ -58,25 +59,25 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, }; -static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) +void set_de_type(struct f2fs_dir_entry *de, umode_t mode) { - umode_t mode = inode->i_mode; de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; } -static unsigned long dir_block_index(unsigned int level, unsigned int idx) +static unsigned long dir_block_index(unsigned int level, + int dir_level, unsigned int idx) { unsigned long i; unsigned long bidx = 0; for (i = 0; i < level; i++) - bidx += dir_buckets(i) * bucket_blocks(i); + bidx += dir_buckets(i, dir_level) * bucket_blocks(i); bidx += idx * bucket_blocks(level); return bidx; } -static bool early_match_name(const char *name, size_t namelen, - f2fs_hash_t namehash, struct f2fs_dir_entry *de) +static bool early_match_name(size_t namelen, f2fs_hash_t namehash, + struct f2fs_dir_entry *de) { if (le16_to_cpu(de->name_len) != namelen) return false; @@ -88,62 +89,90 @@ static bool early_match_name(const char *name, size_t namelen, } static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, - const char *name, size_t namelen, int *max_slots, - f2fs_hash_t namehash, struct page **res_page) + struct qstr *name, int *max_slots, + struct page **res_page) { + struct f2fs_dentry_block *dentry_blk; struct f2fs_dir_entry *de; - unsigned long bit_pos, end_pos, next_pos; - struct f2fs_dentry_block *dentry_blk = kmap(dentry_page); - int slots; + struct f2fs_dentry_ptr d; - bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, 0); - while (bit_pos < NR_DENTRY_IN_BLOCK) { - de = &dentry_blk->dentry[bit_pos]; - slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - - if (early_match_name(name, namelen, namehash, de)) { - if (!memcmp(dentry_blk->filename[bit_pos], - name, namelen)) { - *res_page = dentry_page; - goto found; - } + dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page); + + make_dentry_ptr(&d, (void *)dentry_blk, 1); + de = find_target_dentry(name, max_slots, &d); + + if (de) + *res_page = dentry_page; + else + kunmap(dentry_page); + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs has occurred. + */ + f2fs_bug_on(F2FS_P_SB(dentry_page), d.max < 0); + return de; +} + +struct f2fs_dir_entry *find_target_dentry(struct qstr *name, int *max_slots, + struct f2fs_dentry_ptr *d) +{ + struct f2fs_dir_entry *de; + unsigned long bit_pos = 0; + f2fs_hash_t namehash = f2fs_dentry_hash(name); + int max_len = 0; + + if (max_slots) + *max_slots = 0; + while (bit_pos < d->max) { + if (!test_bit_le(bit_pos, d->bitmap)) { + bit_pos++; + max_len++; + continue; } - next_pos = bit_pos + slots; - bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, next_pos); - if (bit_pos >= NR_DENTRY_IN_BLOCK) - end_pos = NR_DENTRY_IN_BLOCK; - else - end_pos = bit_pos; - if (*max_slots < end_pos - next_pos) - *max_slots = end_pos - next_pos; + + de = &d->dentry[bit_pos]; + if (early_match_name(name->len, namehash, de) && + !memcmp(d->filename[bit_pos], name->name, name->len)) + goto found; + + if (max_slots && max_len > *max_slots) + *max_slots = max_len; + max_len = 0; + + /* remain bug on condition */ + if (unlikely(!de->name_len)) + d->max = -1; + + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); } de = NULL; - kunmap(dentry_page); found: + if (max_slots && max_len > *max_slots) + *max_slots = max_len; return de; } static struct f2fs_dir_entry *find_in_level(struct inode *dir, - unsigned int level, const char *name, size_t namelen, + unsigned int level, struct qstr *name, f2fs_hash_t namehash, struct page **res_page) { - int s = GET_DENTRY_SLOTS(namelen); + int s = GET_DENTRY_SLOTS(name->len); unsigned int nbucket, nblock; unsigned int bidx, end_block; struct page *dentry_page; struct f2fs_dir_entry *de = NULL; bool room = false; - int max_slots = 0; + int max_slots; - BUG_ON(level > MAX_DIR_HASH_DEPTH); + f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH); - nbucket = dir_buckets(level); + nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); nblock = bucket_blocks(level); - bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket); + bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, + le32_to_cpu(namehash) % nbucket); end_block = bidx + nblock; for (; bidx < end_block; bidx++) { @@ -154,8 +183,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, continue; } - de = find_in_block(dentry_page, name, namelen, - &max_slots, namehash, res_page); + de = find_in_block(dentry_page, name, &max_slots, res_page); if (de) break; @@ -181,28 +209,25 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, struct qstr *child, struct page **res_page) { - const char *name = child->name; - size_t namelen = child->len; unsigned long npages = dir_blocks(dir); struct f2fs_dir_entry *de = NULL; f2fs_hash_t name_hash; unsigned int max_depth; unsigned int level; - if (namelen > F2FS_NAME_LEN) - return NULL; + *res_page = NULL; + + if (f2fs_has_inline_dentry(dir)) + return find_in_inline_dir(dir, child, res_page); if (npages == 0) return NULL; - *res_page = NULL; - - name_hash = f2fs_dentry_hash(name, namelen); + name_hash = f2fs_dentry_hash(child); max_depth = F2FS_I(dir)->i_current_depth; for (level = 0; level < max_depth; level++) { - de = find_in_level(dir, level, name, - namelen, name_hash, res_page); + de = find_in_level(dir, level, child, name_hash, res_page); if (de) break; } @@ -215,9 +240,12 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) { - struct page *page = NULL; - struct f2fs_dir_entry *de = NULL; - struct f2fs_dentry_block *dentry_blk = NULL; + struct page *page; + struct f2fs_dir_entry *de; + struct f2fs_dentry_block *dentry_blk; + + if (f2fs_has_inline_dentry(dir)) + return f2fs_parent_inline_dir(dir, p); page = get_lock_data_page(dir, 0); if (IS_ERR(page)) @@ -239,7 +267,7 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) de = f2fs_find_entry(dir, qstr, &page); if (de) { res = le32_to_cpu(de->ino); - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); } @@ -249,184 +277,247 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, struct page *page, struct inode *inode) { + enum page_type type = f2fs_has_inline_dentry(dir) ? NODE : DATA; lock_page(page); - wait_on_page_writeback(page); + f2fs_wait_on_page_writeback(page, type); de->ino = cpu_to_le32(inode->i_ino); - set_de_type(de, inode); - kunmap(page); + set_de_type(de, inode->i_mode); + f2fs_dentry_kunmap(dir, page); set_page_dirty(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME; mark_inode_dirty(dir); - /* update parent inode number before releasing dentry page */ - F2FS_I(inode)->i_pino = dir->i_ino; - f2fs_put_page(page, 1); } -void init_dent_inode(const struct qstr *name, struct page *ipage) +static void init_dent_inode(const struct qstr *name, struct page *ipage) { - struct f2fs_node *rn; - - if (IS_ERR(ipage)) - return; + struct f2fs_inode *ri; - wait_on_page_writeback(ipage); + f2fs_wait_on_page_writeback(ipage, NODE); /* copy name info. to this inode page */ - rn = (struct f2fs_node *)page_address(ipage); - rn->i.i_namelen = cpu_to_le32(name->len); - memcpy(rn->i.i_name, name->name, name->len); + ri = F2FS_INODE(ipage); + ri->i_namelen = cpu_to_le32(name->len); + memcpy(ri->i_name, name->name, name->len); set_page_dirty(ipage); } -static int make_empty_dir(struct inode *inode, struct inode *parent) +int update_dent_inode(struct inode *inode, const struct qstr *name) { - struct page *dentry_page; - struct f2fs_dentry_block *dentry_blk; - struct f2fs_dir_entry *de; - void *kaddr; + struct page *page; - dentry_page = get_new_data_page(inode, 0, true); - if (IS_ERR(dentry_page)) - return PTR_ERR(dentry_page); + page = get_node_page(F2FS_I_SB(inode), inode->i_ino); + if (IS_ERR(page)) + return PTR_ERR(page); + + init_dent_inode(name, page); + f2fs_put_page(page, 1); - kaddr = kmap_atomic(dentry_page); - dentry_blk = (struct f2fs_dentry_block *)kaddr; + return 0; +} + +void do_make_empty_dir(struct inode *inode, struct inode *parent, + struct f2fs_dentry_ptr *d) +{ + struct f2fs_dir_entry *de; - de = &dentry_blk->dentry[0]; + de = &d->dentry[0]; de->name_len = cpu_to_le16(1); de->hash_code = 0; de->ino = cpu_to_le32(inode->i_ino); - memcpy(dentry_blk->filename[0], ".", 1); - set_de_type(de, inode); + memcpy(d->filename[0], ".", 1); + set_de_type(de, inode->i_mode); - de = &dentry_blk->dentry[1]; + de = &d->dentry[1]; de->hash_code = 0; de->name_len = cpu_to_le16(2); de->ino = cpu_to_le32(parent->i_ino); - memcpy(dentry_blk->filename[1], "..", 2); - set_de_type(de, inode); + memcpy(d->filename[1], "..", 2); + set_de_type(de, parent->i_mode); + + test_and_set_bit_le(0, (void *)d->bitmap); + test_and_set_bit_le(1, (void *)d->bitmap); +} + +static int make_empty_dir(struct inode *inode, + struct inode *parent, struct page *page) +{ + struct page *dentry_page; + struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_ptr d; - test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); - test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); - kunmap_atomic(kaddr); + if (f2fs_has_inline_dentry(inode)) + return make_empty_inline_dir(inode, parent, page); + + dentry_page = get_new_data_page(inode, page, 0, true); + if (IS_ERR(dentry_page)) + return PTR_ERR(dentry_page); + + dentry_blk = kmap_atomic(dentry_page); + + make_dentry_ptr(&d, (void *)dentry_blk, 1); + do_make_empty_dir(inode, parent, &d); + + kunmap_atomic(dentry_blk); set_page_dirty(dentry_page); f2fs_put_page(dentry_page, 1); return 0; } -static int init_inode_metadata(struct inode *inode, - struct inode *dir, const struct qstr *name) +struct page *init_inode_metadata(struct inode *inode, struct inode *dir, + const struct qstr *name, struct page *dpage) { + struct page *page; + int err; + if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { - int err; - err = new_inode_page(inode, name); - if (err) - return err; + page = new_inode_page(inode); + if (IS_ERR(page)) + return page; if (S_ISDIR(inode->i_mode)) { - err = make_empty_dir(inode, dir); - if (err) { - remove_inode_page(inode); - return err; - } + err = make_empty_dir(inode, dir, page); + if (err) + goto error; } - err = f2fs_init_acl(inode, dir); - if (err) { - remove_inode_page(inode); - return err; - } + err = f2fs_init_acl(inode, dir, page, dpage); + if (err) + goto put_error; + + err = f2fs_init_security(inode, dir, name, page); + if (err) + goto put_error; } else { - struct page *ipage; - ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); - if (IS_ERR(ipage)) - return PTR_ERR(ipage); - set_cold_node(inode, ipage); - init_dent_inode(name, ipage); - f2fs_put_page(ipage, 1); + page = get_node_page(F2FS_I_SB(dir), inode->i_ino); + if (IS_ERR(page)) + return page; + + set_cold_node(inode, page); } + + if (name) + init_dent_inode(name, page); + + /* + * This file should be checkpointed during fsync. + * We lost i_pino from now on. + */ if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { + file_lost_pino(inode); + /* + * If link the tmpfile to alias through linkat path, + * we should remove this inode from orphan list. + */ + if (inode->i_nlink == 0) + remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino); inc_nlink(inode); - update_inode_page(inode); } - return 0; + return page; + +put_error: + f2fs_put_page(page, 1); +error: + /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ + truncate_inode_pages(&inode->i_data, 0); + truncate_blocks(inode, 0, false); + remove_dirty_dir_inode(inode); + remove_inode_page(inode); + return ERR_PTR(err); } -static void update_parent_metadata(struct inode *dir, struct inode *inode, +void update_parent_metadata(struct inode *dir, struct inode *inode, unsigned int current_depth) { - bool need_dir_update = false; - - if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { + if (inode && is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { if (S_ISDIR(inode->i_mode)) { inc_nlink(dir); - need_dir_update = true; + set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); } clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); } dir->i_mtime = dir->i_ctime = CURRENT_TIME; + mark_inode_dirty(dir); + if (F2FS_I(dir)->i_current_depth != current_depth) { F2FS_I(dir)->i_current_depth = current_depth; - need_dir_update = true; + set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); } - if (need_dir_update) - update_inode_page(dir); - else - mark_inode_dirty(dir); - - if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) + if (inode && is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) clear_inode_flag(F2FS_I(inode), FI_INC_LINK); } -static int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) +int room_for_filename(const void *bitmap, int slots, int max_slots) { int bit_start = 0; int zero_start, zero_end; next: - zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - bit_start); - if (zero_start >= NR_DENTRY_IN_BLOCK) - return NR_DENTRY_IN_BLOCK; + zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start); + if (zero_start >= max_slots) + return max_slots; - zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - zero_start); + zero_end = find_next_bit_le(bitmap, max_slots, zero_start); if (zero_end - zero_start >= slots) return zero_start; bit_start = zero_end + 1; - if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) - return NR_DENTRY_IN_BLOCK; + if (zero_end + 1 >= max_slots) + return max_slots; goto next; } +void f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *d, + const struct qstr *name, f2fs_hash_t name_hash, + unsigned int bit_pos) +{ + struct f2fs_dir_entry *de; + int slots = GET_DENTRY_SLOTS(name->len); + int i; + + de = &d->dentry[bit_pos]; + de->hash_code = name_hash; + de->name_len = cpu_to_le16(name->len); + memcpy(d->filename[bit_pos], name->name, name->len); + de->ino = cpu_to_le32(ino); + set_de_type(de, mode); + for (i = 0; i < slots; i++) + test_and_set_bit_le(bit_pos + i, (void *)d->bitmap); +} + /* - * Caller should grab and release a mutex by calling mutex_lock_op() and - * mutex_unlock_op(). + * Caller should grab and release a rwsem by calling f2fs_lock_op() and + * f2fs_unlock_op(). */ -int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode) +int __f2fs_add_link(struct inode *dir, const struct qstr *name, + struct inode *inode, nid_t ino, umode_t mode) { unsigned int bit_pos; unsigned int level; unsigned int current_depth; unsigned long bidx, block; f2fs_hash_t dentry_hash; - struct f2fs_dir_entry *de; unsigned int nbucket, nblock; size_t namelen = name->len; struct page *dentry_page = NULL; struct f2fs_dentry_block *dentry_blk = NULL; + struct f2fs_dentry_ptr d; int slots = GET_DENTRY_SLOTS(namelen); + struct page *page = NULL; int err = 0; - int i; - dentry_hash = f2fs_dentry_hash(name->name, name->len); + if (f2fs_has_inline_dentry(dir)) { + err = f2fs_add_inline_entry(dir, name, inode, ino, mode); + if (!err || err != -EAGAIN) + return err; + else + err = 0; + } + + dentry_hash = f2fs_dentry_hash(name); level = 0; current_depth = F2FS_I(dir)->i_current_depth; if (F2FS_I(dir)->chash == dentry_hash) { @@ -435,25 +526,27 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in } start: - if (current_depth == MAX_DIR_HASH_DEPTH) + if (unlikely(current_depth == MAX_DIR_HASH_DEPTH)) return -ENOSPC; /* Increase the depth, if required */ if (level == current_depth) ++current_depth; - nbucket = dir_buckets(level); + nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); nblock = bucket_blocks(level); - bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); + bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, + (le32_to_cpu(dentry_hash) % nbucket)); for (block = bidx; block <= (bidx + nblock - 1); block++) { - dentry_page = get_new_data_page(dir, block, true); + dentry_page = get_new_data_page(dir, NULL, block, true); if (IS_ERR(dentry_page)) return PTR_ERR(dentry_page); dentry_blk = kmap(dentry_page); - bit_pos = room_for_filename(dentry_blk, slots); + bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, + slots, NR_DENTRY_IN_BLOCK); if (bit_pos < NR_DENTRY_IN_BLOCK) goto add_dentry; @@ -465,55 +558,115 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in ++level; goto start; add_dentry: - err = init_inode_metadata(inode, dir, name); - if (err) - goto fail; + f2fs_wait_on_page_writeback(dentry_page, DATA); - wait_on_page_writeback(dentry_page); + if (inode) { + down_write(&F2FS_I(inode)->i_sem); + page = init_inode_metadata(inode, dir, name, NULL); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto fail; + } + } + + make_dentry_ptr(&d, (void *)dentry_blk, 1); + f2fs_update_dentry(ino, mode, &d, name, dentry_hash, bit_pos); - de = &dentry_blk->dentry[bit_pos]; - de->hash_code = dentry_hash; - de->name_len = cpu_to_le16(namelen); - memcpy(dentry_blk->filename[bit_pos], name->name, name->len); - de->ino = cpu_to_le32(inode->i_ino); - set_de_type(de, inode); - for (i = 0; i < slots; i++) - test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); set_page_dirty(dentry_page); - update_parent_metadata(dir, inode, current_depth); + if (inode) { + /* we don't need to mark_inode_dirty now */ + F2FS_I(inode)->i_pino = dir->i_ino; + update_inode(inode, page); + f2fs_put_page(page, 1); + } - /* update parent inode number before releasing dentry page */ - F2FS_I(inode)->i_pino = dir->i_ino; + update_parent_metadata(dir, inode, current_depth); fail: + if (inode) + up_write(&F2FS_I(inode)->i_sem); + + if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { + update_inode_page(dir); + clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); + } kunmap(dentry_page); f2fs_put_page(dentry_page, 1); return err; } +int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) +{ + struct page *page; + int err = 0; + + down_write(&F2FS_I(inode)->i_sem); + page = init_inode_metadata(inode, dir, NULL, NULL); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto fail; + } + /* we don't need to mark_inode_dirty now */ + update_inode(inode, page); + f2fs_put_page(page, 1); + + clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); +fail: + up_write(&F2FS_I(inode)->i_sem); + return err; +} + +void f2fs_drop_nlink(struct inode *dir, struct inode *inode, struct page *page) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + + down_write(&F2FS_I(inode)->i_sem); + + if (S_ISDIR(inode->i_mode)) { + drop_nlink(dir); + if (page) + update_inode(dir, page); + else + update_inode_page(dir); + } + inode->i_ctime = CURRENT_TIME; + + drop_nlink(inode); + if (S_ISDIR(inode->i_mode)) { + drop_nlink(inode); + i_size_write(inode, 0); + } + up_write(&F2FS_I(inode)->i_sem); + update_inode_page(inode); + + if (inode->i_nlink == 0) + add_orphan_inode(sbi, inode->i_ino); + else + release_orphan_inode(sbi); +} + /* - * It only removes the dentry from the dentry page,corresponding name + * It only removes the dentry from the dentry page, corresponding name * entry in name page does not need to be touched during deletion. */ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, - struct inode *inode) + struct inode *dir, struct inode *inode) { struct f2fs_dentry_block *dentry_blk; unsigned int bit_pos; - struct address_space *mapping = page->mapping; - struct inode *dir = mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); - void *kaddr = page_address(page); int i; + if (f2fs_has_inline_dentry(dir)) + return f2fs_delete_inline_entry(dentry, page, dir, inode); + lock_page(page); - wait_on_page_writeback(page); + f2fs_wait_on_page_writeback(page, DATA); - dentry_blk = (struct f2fs_dentry_block *)kaddr; - bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry; + dentry_blk = page_address(page); + bit_pos = dentry - dentry_blk->dentry; for (i = 0; i < slots; i++) - test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); + clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); /* Let's check and deallocate this dentry page */ bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, @@ -524,32 +677,15 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, dir->i_ctime = dir->i_mtime = CURRENT_TIME; - if (inode && S_ISDIR(inode->i_mode)) { - drop_nlink(dir); - update_inode_page(dir); - } else { - mark_inode_dirty(dir); - } - - if (inode) { - inode->i_ctime = CURRENT_TIME; - drop_nlink(inode); - if (S_ISDIR(inode->i_mode)) { - drop_nlink(inode); - i_size_write(inode, 0); - } - update_inode_page(inode); - - if (inode->i_nlink == 0) - add_orphan_inode(sbi, inode->i_ino); - } + if (inode) + f2fs_drop_nlink(dir, inode, NULL); if (bit_pos == NR_DENTRY_IN_BLOCK) { truncate_hole(dir, page->index, page->index + 1); clear_page_dirty_for_io(page); + ClearPagePrivate(page); ClearPageUptodate(page); - dec_page_count(sbi, F2FS_DIRTY_DENTS); - inode_dec_dirty_dents(dir); + inode_dec_dirty_pages(dir); } f2fs_put_page(page, 1); } @@ -559,11 +695,13 @@ bool f2fs_empty_dir(struct inode *dir) unsigned long bidx; struct page *dentry_page; unsigned int bit_pos; - struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_block *dentry_blk; unsigned long nblock = dir_blocks(dir); + if (f2fs_has_inline_dentry(dir)) + return f2fs_empty_inline_dir(dir); + for (bidx = 0; bidx < nblock; bidx++) { - void *kaddr; dentry_page = get_lock_data_page(dir, bidx); if (IS_ERR(dentry_page)) { if (PTR_ERR(dentry_page) == -ENOENT) @@ -572,8 +710,7 @@ bool f2fs_empty_dir(struct inode *dir) return false; } - kaddr = kmap_atomic(dentry_page); - dentry_blk = (struct f2fs_dentry_block *)kaddr; + dentry_blk = kmap_atomic(dentry_page); if (bidx == 0) bit_pos = 2; else @@ -581,7 +718,7 @@ bool f2fs_empty_dir(struct inode *dir) bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_pos); - kunmap_atomic(kaddr); + kunmap_atomic(dentry_blk); f2fs_put_page(dentry_page, 1); @@ -591,63 +728,81 @@ bool f2fs_empty_dir(struct inode *dir) return true; } +bool f2fs_fill_dentries(struct file *file, void *dirent, filldir_t filldir, + struct f2fs_dentry_ptr *d, unsigned int n, unsigned int bit_pos) +{ + unsigned int start_bit_pos = bit_pos; + unsigned char d_type; + struct f2fs_dir_entry *de = NULL; + unsigned char *types = f2fs_filetype_table; + int over; + + while (bit_pos < d->max) { + d_type = DT_UNKNOWN; + bit_pos = find_next_bit_le(d->bitmap, d->max, bit_pos); + if (bit_pos >= d->max) + break; + + de = &d->dentry[bit_pos]; + if (types && de->file_type < F2FS_FT_MAX) + d_type = types[de->file_type]; + + over = filldir(dirent, d->filename[bit_pos], + le16_to_cpu(de->name_len), + (n * d->max) + bit_pos, + le32_to_cpu(de->ino), d_type); + if (over) { + file->f_pos += bit_pos - start_bit_pos; + return true; + } + + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); + } + return false; +} + static int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) { unsigned long pos = file->f_pos; + unsigned int bit_pos = 0; struct inode *inode = file_inode(file); unsigned long npages = dir_blocks(inode); - unsigned char *types = NULL; - unsigned int bit_pos = 0, start_bit_pos = 0; - int over = 0; struct f2fs_dentry_block *dentry_blk = NULL; - struct f2fs_dir_entry *de = NULL; struct page *dentry_page = NULL; + struct file_ra_state *ra = &file->f_ra; + struct f2fs_dentry_ptr d; unsigned int n = 0; - unsigned char d_type = DT_UNKNOWN; - int slots; - types = f2fs_filetype_table; + if (f2fs_has_inline_dentry(inode)) + return f2fs_read_inline_dir(file, dirent, filldir); + bit_pos = (pos % NR_DENTRY_IN_BLOCK); n = (pos / NR_DENTRY_IN_BLOCK); - for ( ; n < npages; n++) { + /* readahead for multi pages of dir */ + if (npages - n > 1 && !ra_has_index(ra, n)) + page_cache_sync_readahead(inode->i_mapping, ra, file, n, + min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); + + for (; n < npages; n++) { dentry_page = get_lock_data_page(inode, n); if (IS_ERR(dentry_page)) continue; - start_bit_pos = bit_pos; dentry_blk = kmap(dentry_page); - while (bit_pos < NR_DENTRY_IN_BLOCK) { - d_type = DT_UNKNOWN; - bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - bit_pos); - if (bit_pos >= NR_DENTRY_IN_BLOCK) - break; - - de = &dentry_blk->dentry[bit_pos]; - if (types && de->file_type < F2FS_FT_MAX) - d_type = types[de->file_type]; - - over = filldir(dirent, - dentry_blk->filename[bit_pos], - le16_to_cpu(de->name_len), - (n * NR_DENTRY_IN_BLOCK) + bit_pos, - le32_to_cpu(de->ino), d_type); - if (over) { - file->f_pos += bit_pos - start_bit_pos; - goto success; - } - slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - bit_pos += slots; - } + + make_dentry_ptr(&d, (void *)dentry_blk, 1); + + if (f2fs_fill_dentries(file, dirent, filldir, &d, n, bit_pos)) + goto stop; + bit_pos = 0; file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK; kunmap(dentry_page); f2fs_put_page(dentry_page, 1); dentry_page = NULL; } -success: +stop: if (dentry_page && !IS_ERR(dentry_page)) { kunmap(dentry_page); f2fs_put_page(dentry_page, 1); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 20aab02f2a427..1ab49c6dd24ef 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -17,6 +17,22 @@ #include #include #include +#include +#include + +#ifdef CONFIG_F2FS_CHECK_FS +#define f2fs_bug_on(sbi, condition) BUG_ON(condition) +#define f2fs_down_write(x, y) down_write_nest_lock(x, y) +#else +#define f2fs_bug_on(sbi, condition) \ + do { \ + if (unlikely(condition)) { \ + WARN_ON(1); \ + set_sbi_flag(sbi, SBI_NEED_FSCK); \ + } \ + } while (0) +#define f2fs_down_write(x, y) down_write(x) +#endif /* * For mount options @@ -28,6 +44,13 @@ #define F2FS_MOUNT_XATTR_USER 0x00000010 #define F2FS_MOUNT_POSIX_ACL 0x00000020 #define F2FS_MOUNT_DISABLE_EXT_IDENTIFY 0x00000040 +#define F2FS_MOUNT_INLINE_XATTR 0x00000080 +#define F2FS_MOUNT_INLINE_DATA 0x00000100 +#define F2FS_MOUNT_INLINE_DENTRY 0x00000200 +#define F2FS_MOUNT_FLUSH_MERGE 0x00000400 +#define F2FS_MOUNT_NOBARRIER 0x00000800 +#define F2FS_MOUNT_FASTBOOT 0x00001000 +#define F2FS_MOUNT_EXTENT_CACHE 0x00002000 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) @@ -37,21 +60,35 @@ typecheck(unsigned long long, b) && \ ((long long)((a) - (b)) > 0)) -typedef u64 block_t; +typedef u32 block_t; /* + * should not change u32, since it is the on-disk block + * address format, __le32. + */ typedef u32 nid_t; struct f2fs_mount_info { unsigned int opt; }; -static inline __u32 f2fs_crc32(void *buff, size_t len) +#define CRCPOLY_LE 0xedb88320 + +static inline __u32 f2fs_crc32(void *buf, size_t len) { - return crc32_le(F2FS_SUPER_MAGIC, buff, len); + unsigned char *p = (unsigned char *)buf; + __u32 crc = F2FS_SUPER_MAGIC; + int i; + + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } + return crc; } -static inline bool f2fs_crc_valid(__u32 blk_crc, void *buff, size_t buff_size) +static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size) { - return f2fs_crc32(buff, buff_size) == blk_crc; + return f2fs_crc32(buf, buf_size) == blk_crc; } /* @@ -62,23 +99,76 @@ enum { SIT_BITMAP }; -/* for the list of orphan inodes */ -struct orphan_inode_entry { +enum { + CP_UMOUNT, + CP_FASTBOOT, + CP_SYNC, + CP_RECOVERY, + CP_DISCARD, +}; + +#define DEF_BATCHED_TRIM_SECTIONS 32 +#define BATCHED_TRIM_SEGMENTS(sbi) \ + (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) + +struct cp_control { + int reason; + __u64 trim_start; + __u64 trim_end; + __u64 trim_minlen; + __u64 trimmed; +}; + +/* + * For CP/NAT/SIT/SSA readahead + */ +enum { + META_CP, + META_NAT, + META_SIT, + META_SSA, + META_POR, +}; + +/* for the list of ino */ +enum { + ORPHAN_INO, /* for orphan ino list */ + APPEND_INO, /* for append ino list */ + UPDATE_INO, /* for update ino list */ + MAX_INO_ENTRY, /* max. list */ +}; + +struct ino_entry { struct list_head list; /* list head */ nid_t ino; /* inode number */ }; -/* for the list of directory inodes */ -struct dir_inode_entry { +/* + * for the list of directory inodes or gc inodes. + * NOTE: there are two slab users for this structure, if we add/modify/delete + * fields in structure for one of slab users, it may affect fields or size of + * other one, in this condition, it's better to split both of slab and related + * data structure. + */ +struct inode_entry { struct list_head list; /* list head */ struct inode *inode; /* vfs inode pointer */ }; +/* for the list of blockaddresses to be discarded */ +struct discard_entry { + struct list_head list; /* list head */ + block_t blkaddr; /* block address to be discarded */ + int len; /* # of consecutive blocks of the discard */ +}; + /* for the list of fsync inodes, used only during recovery */ struct fsync_inode_entry { struct list_head list; /* list head */ struct inode *inode; /* vfs inode pointer */ - block_t blkaddr; /* block address locating the last inode */ + block_t blkaddr; /* block address locating the last fsync */ + block_t last_dentry; /* block address locating the last dentry */ + block_t last_inode; /* block address locating the last inode */ }; #define nats_in_cursum(sum) (le16_to_cpu(sum->n_nats)) @@ -89,6 +179,9 @@ struct fsync_inode_entry { #define sit_in_journal(sum, i) (sum->sit_j.entries[i].se) #define segno_in_journal(sum, i) (sum->sit_j.entries[i].segno) +#define MAX_NAT_JENTRIES(sum) (NAT_JOURNAL_ENTRIES - nats_in_cursum(sum)) +#define MAX_SIT_JENTRIES(sum) (SIT_JOURNAL_ENTRIES - sits_in_cursum(sum)) + static inline int update_nats_in_cursum(struct f2fs_summary_block *rs, int i) { int before = nats_in_cursum(rs); @@ -103,11 +196,27 @@ static inline int update_sits_in_cursum(struct f2fs_summary_block *rs, int i) return before; } +static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, + int type) +{ + if (type == NAT_JOURNAL) + return size <= MAX_NAT_JENTRIES(sum); + return size <= MAX_SIT_JENTRIES(sum); +} + /* * ioctl commands */ -#define F2FS_IOC_GETFLAGS FS_IOC_GETFLAGS -#define F2FS_IOC_SETFLAGS FS_IOC_SETFLAGS +#define F2FS_IOC_GETFLAGS FS_IOC_GETFLAGS +#define F2FS_IOC_SETFLAGS FS_IOC_SETFLAGS +#define F2FS_IOC_GETVERSION FS_IOC_GETVERSION + +#define F2FS_IOCTL_MAGIC 0xf5 +#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) +#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) +#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) +#define F2FS_IOC_RELEASE_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 4) +#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* @@ -120,86 +229,183 @@ static inline int update_sits_in_cursum(struct f2fs_summary_block *rs, int i) /* * For INODE and NODE manager */ -#define XATTR_NODE_OFFSET (-1) /* - * store xattrs to one node block per - * file keeping -1 as its node offset to - * distinguish from index node blocks. - */ +/* for directory operations */ +struct f2fs_dentry_ptr { + const void *bitmap; + struct f2fs_dir_entry *dentry; + __u8 (*filename)[F2FS_SLOT_LEN]; + int max; +}; + +static inline void make_dentry_ptr(struct f2fs_dentry_ptr *d, + void *src, int type) +{ + if (type == 1) { + struct f2fs_dentry_block *t = (struct f2fs_dentry_block *)src; + d->max = NR_DENTRY_IN_BLOCK; + d->bitmap = &t->dentry_bitmap; + d->dentry = t->dentry; + d->filename = t->filename; + } else { + struct f2fs_inline_dentry *t = (struct f2fs_inline_dentry *)src; + d->max = NR_INLINE_DENTRY; + d->bitmap = &t->dentry_bitmap; + d->dentry = t->dentry; + d->filename = t->filename; + } +} + +/* + * XATTR_NODE_OFFSET stores xattrs to one node block per file keeping -1 + * as its node offset to distinguish from index node blocks. + * But some bits are used to mark the node block. + */ +#define XATTR_NODE_OFFSET ((((unsigned int)-1) << OFFSET_BIT_SHIFT) \ + >> OFFSET_BIT_SHIFT) enum { ALLOC_NODE, /* allocate a new node page if needed */ LOOKUP_NODE, /* look up a node without readahead */ LOOKUP_NODE_RA, /* * look up a node with readahead called - * by get_datablock_ro. + * by get_data_block. */ }; #define F2FS_LINK_MAX 32000 /* maximum link count per file */ +#define MAX_DIR_RA_PAGES 4 /* maximum ra pages of dir */ + +/* vector size for gang look-up from extent cache that consists of radix tree */ +#define EXT_TREE_VEC_SIZE 64 + /* for in-memory extent cache entry */ +#define F2FS_MIN_EXTENT_LEN 64 /* minimum extent length */ + +/* number of extent info in extent cache we try to shrink */ +#define EXTENT_CACHE_SHRINK_NUMBER 128 + struct extent_info { - rwlock_t ext_lock; /* rwlock for consistency */ - unsigned int fofs; /* start offset in a file */ - u32 blk_addr; /* start block address of the extent */ - unsigned int len; /* length of the extent */ + unsigned int fofs; /* start offset in a file */ + u32 blk; /* start block address of the extent */ + unsigned int len; /* length of the extent */ +}; + +struct extent_node { + struct rb_node rb_node; /* rb node located in rb-tree */ + struct list_head list; /* node in global extent list of sbi */ + struct extent_info ei; /* extent info */ +}; + +struct extent_tree { + nid_t ino; /* inode number */ + struct rb_root root; /* root of extent info rb-tree */ + struct extent_node *cached_en; /* recently accessed extent node */ + rwlock_t lock; /* protect extent info rb-tree */ + atomic_t refcount; /* reference count of rb-tree */ + unsigned int count; /* # of extent node in rb-tree*/ }; /* * i_advise uses FADVISE_XXX_BIT. We can add additional hints later. */ #define FADVISE_COLD_BIT 0x01 -#define FADVISE_CP_BIT 0x02 +#define FADVISE_LOST_PINO_BIT 0x02 + +#define DEF_DIR_LEVEL 0 struct f2fs_inode_info { struct inode vfs_inode; /* serve a vfs inode */ unsigned long i_flags; /* keep an inode flags for ioctl */ unsigned char i_advise; /* use to give file attribute hints */ + unsigned char i_dir_level; /* use for dentry level for large dir */ unsigned int i_current_depth; /* use only in directory structure */ unsigned int i_pino; /* parent inode number */ umode_t i_acl_mode; /* keep file acl mode temporarily */ /* Use below internally in f2fs*/ unsigned long flags; /* use to pass per-file flags */ - atomic_t dirty_dents; /* # of dirty dentry pages */ + struct rw_semaphore i_sem; /* protect fi info */ + atomic_t dirty_pages; /* # of dirty pages */ f2fs_hash_t chash; /* hash value of given file name */ unsigned int clevel; /* maximum level of given file name */ nid_t i_xattr_nid; /* node id that contains xattrs */ + unsigned long long xattr_ver; /* cp version of xattr modification */ struct extent_info ext; /* in-memory extent cache entry */ + rwlock_t ext_lock; /* rwlock for single extent cache */ + struct inode_entry *dirty_dir; /* the pointer of dirty dir */ + + struct radix_tree_root inmem_root; /* radix tree for inmem pages */ + struct list_head inmem_pages; /* inmemory pages managed by f2fs */ + struct mutex inmem_lock; /* lock for inmemory pages */ }; static inline void get_extent_info(struct extent_info *ext, struct f2fs_extent i_ext) { - write_lock(&ext->ext_lock); ext->fofs = le32_to_cpu(i_ext.fofs); - ext->blk_addr = le32_to_cpu(i_ext.blk_addr); + ext->blk = le32_to_cpu(i_ext.blk); ext->len = le32_to_cpu(i_ext.len); - write_unlock(&ext->ext_lock); } static inline void set_raw_extent(struct extent_info *ext, struct f2fs_extent *i_ext) { - read_lock(&ext->ext_lock); i_ext->fofs = cpu_to_le32(ext->fofs); - i_ext->blk_addr = cpu_to_le32(ext->blk_addr); + i_ext->blk = cpu_to_le32(ext->blk); i_ext->len = cpu_to_le32(ext->len); - read_unlock(&ext->ext_lock); +} + +static inline void set_extent_info(struct extent_info *ei, unsigned int fofs, + u32 blk, unsigned int len) +{ + ei->fofs = fofs; + ei->blk = blk; + ei->len = len; +} + +static inline bool __is_extent_same(struct extent_info *ei1, + struct extent_info *ei2) +{ + return (ei1->fofs == ei2->fofs && ei1->blk == ei2->blk && + ei1->len == ei2->len); +} + +static inline bool __is_extent_mergeable(struct extent_info *back, + struct extent_info *front) +{ + return (back->fofs + back->len == front->fofs && + back->blk + back->len == front->blk); +} + +static inline bool __is_back_mergeable(struct extent_info *cur, + struct extent_info *back) +{ + return __is_extent_mergeable(back, cur); +} + +static inline bool __is_front_mergeable(struct extent_info *cur, + struct extent_info *front) +{ + return __is_extent_mergeable(cur, front); } struct f2fs_nm_info { block_t nat_blkaddr; /* base disk address of NAT */ nid_t max_nid; /* maximum possible node ids */ + nid_t available_nids; /* maximum available node ids */ nid_t next_scan_nid; /* the next nid to be scanned */ + unsigned int ram_thresh; /* control the memory footprint */ /* NAT cache management */ struct radix_tree_root nat_root;/* root of the nat entry cache */ - rwlock_t nat_tree_lock; /* protect nat_tree_lock */ - unsigned int nat_cnt; /* the # of cached nat entries */ + struct radix_tree_root nat_set_root;/* root of the nat set cache */ + struct rw_semaphore nat_tree_lock; /* protect nat_tree_lock */ struct list_head nat_entries; /* cached nat entry list (clean) */ - struct list_head dirty_nat_entries; /* cached nat entry list (dirty) */ + unsigned int nat_cnt; /* the # of cached nat entries */ + unsigned int dirty_nat_cnt; /* total num of nat entries in set */ /* free node ids management */ + struct radix_tree_root free_nid_root;/* root of the free_nid cache */ struct list_head free_nid_list; /* a list for free nids */ spinlock_t free_nid_list_lock; /* protect free nid list */ unsigned int fcnt; /* the number of free node id */ @@ -259,7 +465,21 @@ enum { CURSEG_HOT_NODE, /* direct node blocks of directory files */ CURSEG_WARM_NODE, /* direct node blocks of normal files */ CURSEG_COLD_NODE, /* indirect node blocks */ - NO_CHECK_TYPE + NO_CHECK_TYPE, + CURSEG_DIRECT_IO, /* to use for the direct IO path */ +}; + +struct flush_cmd { + struct completion wait; + struct llist_node llnode; + int ret; +}; + +struct flush_cmd_control { + struct task_struct *f2fs_issue_flush; /* flush thread */ + wait_queue_head_t flush_wait_queue; /* waiting queue for wake-up */ + struct llist_head issue_list; /* list for command issue */ + struct llist_node *dispatch_list; /* list for command dispatch */ }; struct f2fs_sm_info { @@ -268,9 +488,6 @@ struct f2fs_sm_info { struct dirty_seglist_info *dirty_info; /* dirty segment information */ struct curseg_info *curseg_array; /* active segment information */ - struct list_head wblist_head; /* list of under-writeback pages */ - spinlock_t wblist_lock; /* lock for checkpoint */ - block_t seg0_blkaddr; /* block address of 0'th segment */ block_t main_blkaddr; /* start block address of main area */ block_t ssa_blkaddr; /* start block address of SSA area */ @@ -279,16 +496,28 @@ struct f2fs_sm_info { unsigned int main_segments; /* # of segments in main area */ unsigned int reserved_segments; /* # of reserved segments */ unsigned int ovp_segments; /* # of overprovision segments */ -}; -/* - * For directory operation - */ -#define NODE_DIR1_BLOCK (ADDRS_PER_INODE + 1) -#define NODE_DIR2_BLOCK (ADDRS_PER_INODE + 2) -#define NODE_IND1_BLOCK (ADDRS_PER_INODE + 3) -#define NODE_IND2_BLOCK (ADDRS_PER_INODE + 4) -#define NODE_DIND_BLOCK (ADDRS_PER_INODE + 5) + /* a threshold to reclaim prefree segments */ + unsigned int rec_prefree_segments; + + /* for small discard management */ + struct list_head discard_list; /* 4KB discard list */ + int nr_discards; /* # of discards in the list */ + int max_discards; /* max. discards to be issued */ + + /* for batched trimming */ + unsigned int trim_sections; /* # of sections to trim */ + + struct list_head sit_entry_set; /* sit entry set list */ + + unsigned int ipu_policy; /* in-place-update policy */ + unsigned int min_ipu_util; /* in-place-update threshold */ + unsigned int min_fsync_blocks; /* threshold for fsync */ + + /* for flush command control */ + struct flush_cmd_control *cmd_control_info; + +}; /* * For superblock @@ -304,19 +533,12 @@ enum count_type { F2FS_DIRTY_DENTS, F2FS_DIRTY_NODES, F2FS_DIRTY_META, + F2FS_INMEM_PAGES, NR_COUNT_TYPE, }; /* - * Uses as sbi->fs_lock[NR_GLOBAL_LOCKS]. - * The checkpoint procedure blocks all the locks in this fs_lock array. - * Some FS operations grab free locks, and if there is no free lock, - * then wait to grab a lock in a round-robin manner. - */ -#define NR_GLOBAL_LOCKS 8 - -/* - * The below are the page types of bios used in submti_bio(). + * The below are the page types of bios used in submit_bio(). * The available types are: * DATA User data pages. It operates as async mode. * NODE Node pages. It operates as async mode. @@ -326,19 +548,56 @@ enum count_type { * with waiting the bio's completion * ... Only can be used with META. */ +#define PAGE_TYPE_OF_BIO(type) ((type) > META ? META : (type)) enum page_type { DATA, NODE, META, NR_PAGE_TYPE, META_FLUSH, + INMEM, /* the below types are used by tracepoints only. */ + INMEM_DROP, + IPU, + OPU, +}; + +struct f2fs_io_info { + enum page_type type; /* contains DATA/NODE/META/META_FLUSH */ + int rw; /* contains R/RS/W/WS with REQ_META/REQ_PRIO */ + block_t blk_addr; /* block address to be written */ +}; + +#define is_read_io(rw) (((rw) & 1) == READ) +struct f2fs_bio_info { + struct f2fs_sb_info *sbi; /* f2fs superblock */ + struct bio *bio; /* bios to merge */ + sector_t last_block_in_bio; /* last block number */ + struct f2fs_io_info fio; /* store buffered io info. */ + struct rw_semaphore io_rwsem; /* blocking op for bio */ +}; + +/* for inner inode cache management */ +struct inode_management { + struct radix_tree_root ino_root; /* ino entry array */ + spinlock_t ino_lock; /* for ino entry lock */ + struct list_head ino_list; /* inode list head */ + unsigned long ino_num; /* number of entries */ +}; + +/* For s_flag in struct f2fs_sb_info */ +enum { + SBI_IS_DIRTY, /* dirty flag for checkpoint */ + SBI_IS_CLOSE, /* specify unmounting */ + SBI_NEED_FSCK, /* need fsck.f2fs to fix */ + SBI_POR_DOING, /* recovery is doing or not */ }; struct f2fs_sb_info { struct super_block *sb; /* pointer to VFS super block */ + struct proc_dir_entry *s_proc; /* proc entry */ struct buffer_head *raw_super_buf; /* buffer head of raw sb */ struct f2fs_super_block *raw_super; /* raw super block pointer */ - int s_dirty; /* dirty flag for checkpoint */ + int s_flag; /* flags for sbi */ /* for node-related operations */ struct f2fs_nm_info *nm_info; /* node manager */ @@ -346,32 +605,37 @@ struct f2fs_sb_info { /* for segment-related operations */ struct f2fs_sm_info *sm_info; /* segment manager */ - struct bio *bio[NR_PAGE_TYPE]; /* bios to merge */ - sector_t last_block_in_bio[NR_PAGE_TYPE]; /* last block number */ - struct rw_semaphore bio_sem; /* IO semaphore */ + + /* for bio operations */ + struct f2fs_bio_info read_io; /* for read bios */ + struct f2fs_bio_info write_io[NR_PAGE_TYPE]; /* for write bios */ /* for checkpoint */ struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ struct inode *meta_inode; /* cache meta blocks */ struct mutex cp_mutex; /* checkpoint procedure lock */ - struct mutex fs_lock[NR_GLOBAL_LOCKS]; /* blocking FS operations */ - struct mutex node_write; /* locking node writes */ - struct mutex writepages; /* mutex for writepages() */ - unsigned char next_lock_num; /* round-robin global locks */ - int por_doing; /* recovery is doing or not */ - int on_build_free_nids; /* build_free_nids is doing */ - - /* for orphan inode management */ - struct list_head orphan_inode_list; /* orphan inode list */ - struct mutex orphan_inode_mutex; /* for orphan inode list */ - unsigned int n_orphans; /* # of orphan inodes */ + struct rw_semaphore cp_rwsem; /* blocking FS operations */ + struct rw_semaphore node_write; /* locking node writes */ + wait_queue_head_t cp_wait; + + struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ + + /* for orphan inode, use 0'th array */ + unsigned int max_orphans; /* max orphan inodes */ /* for directory inode management */ struct list_head dir_inode_list; /* dir inode list */ spinlock_t dir_inode_lock; /* for dir inode list lock */ - unsigned int n_dirty_dirs; /* # of dir inodes */ - /* basic file system units */ + /* for extent tree cache */ + struct radix_tree_root extent_tree_root;/* cache extent cache entries */ + struct rw_semaphore extent_tree_lock; /* locking extent radix tree */ + struct list_head extent_list; /* lru list for shrinker */ + spinlock_t extent_lock; /* locking extent lru list */ + int total_ext_tree; /* extent tree count */ + atomic_t total_ext_node; /* extent info count */ + + /* basic filesystem units */ unsigned int log_sectors_per_block; /* log2 sectors per block */ unsigned int log_blocksize; /* log2 block size */ unsigned int blocksize; /* block size */ @@ -387,6 +651,7 @@ struct f2fs_sb_info { unsigned int total_valid_node_count; /* valid node block count */ unsigned int total_valid_inode_count; /* valid inode count */ int active_logs; /* # of active logs */ + int dir_level; /* directory level */ block_t user_block_count; /* # of user blocks */ block_t total_valid_block_count; /* # of valid blocks */ @@ -402,17 +667,30 @@ struct f2fs_sb_info { struct f2fs_gc_kthread *gc_thread; /* GC thread */ unsigned int cur_victim_sec; /* current victim section num */ + /* maximum # of trials to find a victim segment for SSR and GC */ + unsigned int max_victim_search; + /* * for stat information. * one is for the LFS mode, and the other is for the SSR mode. */ +#ifdef CONFIG_F2FS_STAT_FS struct f2fs_stat_info *stat_info; /* FS status information */ unsigned int segment_count[2]; /* # of allocated segments */ unsigned int block_count[2]; /* # of allocated blocks */ - unsigned int last_victim[2]; /* last victim segment # */ + atomic_t inplace_count; /* # of inplace update */ int total_hit_ext, read_hit_ext; /* extent cache hit ratio */ + atomic_t inline_inode; /* # of inline_data inodes */ + atomic_t inline_dir; /* # of inline_dentry inodes */ int bg_gc; /* background gc calls */ + unsigned int n_dirty_dirs; /* # of dir inodes */ +#endif + unsigned int last_victim[2]; /* last victim segment # */ spinlock_t stat_lock; /* lock for stat operations */ + + /* For sysfs suppport */ + struct kobject s_kobj; + struct completion s_kobj_unregister; }; /* @@ -428,6 +706,21 @@ static inline struct f2fs_sb_info *F2FS_SB(struct super_block *sb) return sb->s_fs_info; } +static inline struct f2fs_sb_info *F2FS_I_SB(struct inode *inode) +{ + return F2FS_SB(inode->i_sb); +} + +static inline struct f2fs_sb_info *F2FS_M_SB(struct address_space *mapping) +{ + return F2FS_I_SB(mapping->host); +} + +static inline struct f2fs_sb_info *F2FS_P_SB(struct page *page) +{ + return F2FS_M_SB(page->mapping); +} + static inline struct f2fs_super_block *F2FS_RAW_SUPER(struct f2fs_sb_info *sbi) { return (struct f2fs_super_block *)(sbi->raw_super); @@ -438,6 +731,16 @@ static inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi) return (struct f2fs_checkpoint *)(sbi->ckpt); } +static inline struct f2fs_node *F2FS_NODE(struct page *page) +{ + return (struct f2fs_node *)page_address(page); +} + +static inline struct f2fs_inode *F2FS_INODE(struct page *page) +{ + return &((struct f2fs_node *)page_address(page))->i; +} + static inline struct f2fs_nm_info *NM_I(struct f2fs_sb_info *sbi) { return (struct f2fs_nm_info *)(sbi->nm_info); @@ -463,14 +766,34 @@ static inline struct dirty_seglist_info *DIRTY_I(struct f2fs_sb_info *sbi) return (struct dirty_seglist_info *)(SM_I(sbi)->dirty_info); } -static inline void F2FS_SET_SB_DIRT(struct f2fs_sb_info *sbi) +static inline struct address_space *META_MAPPING(struct f2fs_sb_info *sbi) +{ + return sbi->meta_inode->i_mapping; +} + +static inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi) +{ + return sbi->node_inode->i_mapping; +} + +static inline bool is_sbi_flag_set(struct f2fs_sb_info *sbi, unsigned int type) +{ + return sbi->s_flag & (0x01 << type); +} + +static inline void set_sbi_flag(struct f2fs_sb_info *sbi, unsigned int type) +{ + sbi->s_flag |= (0x01 << type); +} + +static inline void clear_sbi_flag(struct f2fs_sb_info *sbi, unsigned int type) { - sbi->s_dirty = 1; + sbi->s_flag &= ~(0x01 << type); } -static inline void F2FS_RESET_SB_DIRT(struct f2fs_sb_info *sbi) +static inline unsigned long long cur_cp_version(struct f2fs_checkpoint *cp) { - sbi->s_dirty = 0; + return le64_to_cpu(cp->checkpoint_ver); } static inline bool is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f) @@ -493,40 +816,46 @@ static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f) cp->ckpt_flags = cpu_to_le32(ckpt_flags); } -static inline void mutex_lock_all(struct f2fs_sb_info *sbi) +static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) { - int i = 0; - for (; i < NR_GLOBAL_LOCKS; i++) - mutex_lock(&sbi->fs_lock[i]); + down_read(&sbi->cp_rwsem); } -static inline void mutex_unlock_all(struct f2fs_sb_info *sbi) +static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi) { - int i = 0; - for (; i < NR_GLOBAL_LOCKS; i++) - mutex_unlock(&sbi->fs_lock[i]); + up_read(&sbi->cp_rwsem); } -static inline int mutex_lock_op(struct f2fs_sb_info *sbi) +static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) { - unsigned char next_lock = sbi->next_lock_num % NR_GLOBAL_LOCKS; - int i = 0; + f2fs_down_write(&sbi->cp_rwsem, &sbi->cp_mutex); +} - for (; i < NR_GLOBAL_LOCKS; i++) - if (mutex_trylock(&sbi->fs_lock[i])) - return i; +static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) +{ + up_write(&sbi->cp_rwsem); +} + +static inline int __get_cp_reason(struct f2fs_sb_info *sbi) +{ + int reason = CP_SYNC; - mutex_lock(&sbi->fs_lock[next_lock]); - sbi->next_lock_num++; - return next_lock; + if (test_opt(sbi, FASTBOOT)) + reason = CP_FASTBOOT; + if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) + reason = CP_UMOUNT; + return reason; } -static inline void mutex_unlock_op(struct f2fs_sb_info *sbi, int ilock) +static inline bool __remain_node_summaries(int reason) { - if (ilock < 0) - return; - BUG_ON(ilock >= NR_GLOBAL_LOCKS); - mutex_unlock(&sbi->fs_lock[ilock]); + return (reason == CP_UMOUNT || reason == CP_FASTBOOT); +} + +static inline bool __exist_node_summaries(struct f2fs_sb_info *sbi) +{ + return (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) || + is_set_ckpt_flags(F2FS_CKPT(sbi), CP_FASTBOOT_FLAG)); } /* @@ -534,8 +863,9 @@ static inline void mutex_unlock_op(struct f2fs_sb_info *sbi, int ilock) */ static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) { - WARN_ON((nid >= NM_I(sbi)->max_nid)); - if (nid >= NM_I(sbi)->max_nid) + if (unlikely(nid < F2FS_ROOT_INO(sbi))) + return -EINVAL; + if (unlikely(nid >= NM_I(sbi)->max_nid)) return -EINVAL; return 0; } @@ -548,9 +878,14 @@ static inline int check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) static inline int F2FS_HAS_BLOCKS(struct inode *inode) { if (F2FS_I(inode)->i_xattr_nid) - return (inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS + 1); + return inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS + 1; else - return (inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS); + return inode->i_blocks > F2FS_DEFAULT_ALLOCATED_BLOCKS; +} + +static inline bool f2fs_has_xattr_block(unsigned int ofs) +{ + return ofs == XATTR_NODE_OFFSET; } static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, @@ -561,7 +896,7 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, spin_lock(&sbi->stat_lock); valid_block_count = sbi->total_valid_block_count + (block_t)count; - if (valid_block_count > sbi->user_block_count) { + if (unlikely(valid_block_count > sbi->user_block_count)) { spin_unlock(&sbi->stat_lock); return false; } @@ -572,28 +907,29 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, return true; } -static inline int dec_valid_block_count(struct f2fs_sb_info *sbi, +static inline void dec_valid_block_count(struct f2fs_sb_info *sbi, struct inode *inode, blkcnt_t count) { spin_lock(&sbi->stat_lock); - BUG_ON(sbi->total_valid_block_count < (block_t) count); - BUG_ON(inode->i_blocks < count); + f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count); + f2fs_bug_on(sbi, inode->i_blocks < count); inode->i_blocks -= count; sbi->total_valid_block_count -= (block_t)count; spin_unlock(&sbi->stat_lock); - return 0; } static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type) { atomic_inc(&sbi->nr_pages[count_type]); - F2FS_SET_SB_DIRT(sbi); + set_sbi_flag(sbi, SBI_IS_DIRTY); } -static inline void inode_inc_dirty_dents(struct inode *inode) +static inline void inode_inc_dirty_pages(struct inode *inode) { - atomic_inc(&F2FS_I(inode)->dirty_dents); + atomic_inc(&F2FS_I(inode)->dirty_pages); + if (S_ISDIR(inode->i_mode)) + inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); } static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type) @@ -601,9 +937,15 @@ static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type) atomic_dec(&sbi->nr_pages[count_type]); } -static inline void inode_dec_dirty_dents(struct inode *inode) +static inline void inode_dec_dirty_pages(struct inode *inode) { - atomic_dec(&F2FS_I(inode)->dirty_dents); + if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode)) + return; + + atomic_dec(&F2FS_I(inode)->dirty_pages); + + if (S_ISDIR(inode->i_mode)) + dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); } static inline int get_pages(struct f2fs_sb_info *sbi, int count_type) @@ -611,6 +953,11 @@ static inline int get_pages(struct f2fs_sb_info *sbi, int count_type) return atomic_read(&sbi->nr_pages[count_type]); } +static inline int get_dirty_pages(struct inode *inode) +{ + return atomic_read(&F2FS_I(inode)->dirty_pages); +} + static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type) { unsigned int pages_per_sec = sbi->segs_per_sec * @@ -621,11 +968,7 @@ static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type) static inline block_t valid_user_blocks(struct f2fs_sb_info *sbi) { - block_t ret; - spin_lock(&sbi->stat_lock); - ret = sbi->total_valid_block_count; - spin_unlock(&sbi->stat_lock); - return ret; + return sbi->total_valid_block_count; } static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag) @@ -641,25 +984,39 @@ static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag) return 0; } +static inline block_t __cp_payload(struct f2fs_sb_info *sbi) +{ + return le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); +} + static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - int offset = (flag == NAT_BITMAP) ? + int offset; + + if (__cp_payload(sbi) > 0) { + if (flag == NAT_BITMAP) + return &ckpt->sit_nat_version_bitmap; + else + return (unsigned char *)ckpt + F2FS_BLKSIZE; + } else { + offset = (flag == NAT_BITMAP) ? le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0; - return &ckpt->sit_nat_version_bitmap + offset; + return &ckpt->sit_nat_version_bitmap + offset; + } } static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) { block_t start_addr; struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - unsigned long long ckpt_version = le64_to_cpu(ckpt->checkpoint_ver); + unsigned long long ckpt_version = cur_cp_version(ckpt); start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr); /* * odd numbered checkpoint should at cp segment 0 - * and even segent must be at cp segment 1 + * and even segment must be at cp segment 1 */ if (!(ckpt_version & 1)) start_addr += sbi->blocks_per_seg; @@ -673,96 +1030,85 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi) } static inline bool inc_valid_node_count(struct f2fs_sb_info *sbi, - struct inode *inode, - unsigned int count) + struct inode *inode) { block_t valid_block_count; unsigned int valid_node_count; spin_lock(&sbi->stat_lock); - valid_block_count = sbi->total_valid_block_count + (block_t)count; - sbi->alloc_valid_block_count += (block_t)count; - valid_node_count = sbi->total_valid_node_count + count; - - if (valid_block_count > sbi->user_block_count) { + valid_block_count = sbi->total_valid_block_count + 1; + if (unlikely(valid_block_count > sbi->user_block_count)) { spin_unlock(&sbi->stat_lock); return false; } - if (valid_node_count > sbi->total_node_count) { + valid_node_count = sbi->total_valid_node_count + 1; + if (unlikely(valid_node_count > sbi->total_node_count)) { spin_unlock(&sbi->stat_lock); return false; } if (inode) - inode->i_blocks += count; - sbi->total_valid_node_count = valid_node_count; - sbi->total_valid_block_count = valid_block_count; + inode->i_blocks++; + + sbi->alloc_valid_block_count++; + sbi->total_valid_node_count++; + sbi->total_valid_block_count++; spin_unlock(&sbi->stat_lock); return true; } static inline void dec_valid_node_count(struct f2fs_sb_info *sbi, - struct inode *inode, - unsigned int count) + struct inode *inode) { spin_lock(&sbi->stat_lock); - BUG_ON(sbi->total_valid_block_count < count); - BUG_ON(sbi->total_valid_node_count < count); - BUG_ON(inode->i_blocks < count); + f2fs_bug_on(sbi, !sbi->total_valid_block_count); + f2fs_bug_on(sbi, !sbi->total_valid_node_count); + f2fs_bug_on(sbi, !inode->i_blocks); - inode->i_blocks -= count; - sbi->total_valid_node_count -= count; - sbi->total_valid_block_count -= (block_t)count; + inode->i_blocks--; + sbi->total_valid_node_count--; + sbi->total_valid_block_count--; spin_unlock(&sbi->stat_lock); } static inline unsigned int valid_node_count(struct f2fs_sb_info *sbi) { - unsigned int ret; - spin_lock(&sbi->stat_lock); - ret = sbi->total_valid_node_count; - spin_unlock(&sbi->stat_lock); - return ret; + return sbi->total_valid_node_count; } static inline void inc_valid_inode_count(struct f2fs_sb_info *sbi) { spin_lock(&sbi->stat_lock); - BUG_ON(sbi->total_valid_inode_count == sbi->total_node_count); + f2fs_bug_on(sbi, sbi->total_valid_inode_count == sbi->total_node_count); sbi->total_valid_inode_count++; spin_unlock(&sbi->stat_lock); } -static inline int dec_valid_inode_count(struct f2fs_sb_info *sbi) +static inline void dec_valid_inode_count(struct f2fs_sb_info *sbi) { spin_lock(&sbi->stat_lock); - BUG_ON(!sbi->total_valid_inode_count); + f2fs_bug_on(sbi, !sbi->total_valid_inode_count); sbi->total_valid_inode_count--; spin_unlock(&sbi->stat_lock); - return 0; } static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi) { - unsigned int ret; - spin_lock(&sbi->stat_lock); - ret = sbi->total_valid_inode_count; - spin_unlock(&sbi->stat_lock); - return ret; + return sbi->total_valid_inode_count; } static inline void f2fs_put_page(struct page *page, int unlock) { - if (!page || IS_ERR(page)) + if (!page) return; if (unlock) { - BUG_ON(!PageLocked(page)); + f2fs_bug_on(F2FS_P_SB(page), !PageLocked(page)); unlock_page(page); } page_cache_release(page); @@ -779,16 +1125,37 @@ static inline void f2fs_put_dnode(struct dnode_of_data *dn) } static inline struct kmem_cache *f2fs_kmem_cache_create(const char *name, - size_t size, void (*ctor)(void *)) + size_t size) { - return kmem_cache_create(name, size, 0, SLAB_RECLAIM_ACCOUNT, ctor); + return kmem_cache_create(name, size, 0, SLAB_RECLAIM_ACCOUNT, NULL); +} + +static inline void *f2fs_kmem_cache_alloc(struct kmem_cache *cachep, + gfp_t flags) +{ + void *entry; +retry: + entry = kmem_cache_alloc(cachep, flags); + if (!entry) { + cond_resched(); + goto retry; + } + + return entry; +} + +static inline void f2fs_radix_tree_insert(struct radix_tree_root *root, + unsigned long index, void *item) +{ + while (radix_tree_insert(root, index, item)) + cond_resched(); } #define RAW_IS_INODE(p) ((p)->footer.nid == (p)->footer.ino) static inline bool IS_INODE(struct page *page) { - struct f2fs_node *p = (struct f2fs_node *)page_address(page); + struct f2fs_node *p = F2FS_NODE(page); return RAW_IS_INODE(p); } @@ -802,7 +1169,7 @@ static inline block_t datablock_addr(struct page *node_page, { struct f2fs_node *raw_node; __le32 *addr_array; - raw_node = (struct f2fs_node *)page_address(node_page); + raw_node = F2FS_NODE(node_page); addr_array = blkaddr_in_node(raw_node); return le32_to_cpu(addr_array[offset]); } @@ -816,7 +1183,7 @@ static inline int f2fs_test_bit(unsigned int nr, char *addr) return mask & *addr; } -static inline int f2fs_set_bit(unsigned int nr, char *addr) +static inline int f2fs_test_and_set_bit(unsigned int nr, char *addr) { int mask; int ret; @@ -828,7 +1195,7 @@ static inline int f2fs_set_bit(unsigned int nr, char *addr) return ret; } -static inline int f2fs_clear_bit(unsigned int nr, char *addr) +static inline int f2fs_test_and_clear_bit(unsigned int nr, char *addr) { int mask; int ret; @@ -840,17 +1207,44 @@ static inline int f2fs_clear_bit(unsigned int nr, char *addr) return ret; } +static inline void f2fs_change_bit(unsigned int nr, char *addr) +{ + int mask; + + addr += (nr >> 3); + mask = 1 << (7 - (nr & 0x07)); + *addr ^= mask; +} + /* used for f2fs_inode_info->flags */ enum { FI_NEW_INODE, /* indicate newly allocated inode */ + FI_DIRTY_INODE, /* indicate inode is dirty or not */ + FI_DIRTY_DIR, /* indicate directory has dirty pages */ FI_INC_LINK, /* need to increment i_nlink */ FI_ACL_MODE, /* indicate acl mode */ FI_NO_ALLOC, /* should not allocate any blocks */ + FI_UPDATE_DIR, /* should update inode block for consistency */ + FI_DELAY_IPUT, /* used for the recovery */ + FI_NO_EXTENT, /* not to use the extent cache */ + FI_INLINE_XATTR, /* used for inline xattr */ + FI_INLINE_DATA, /* used for inline data*/ + FI_INLINE_DENTRY, /* used for inline dentry */ + FI_APPEND_WRITE, /* inode has appended data */ + FI_UPDATE_WRITE, /* inode has in-place-update data */ + FI_NEED_IPU, /* used for ipu per file */ + FI_ATOMIC_FILE, /* indicate atomic file */ + FI_VOLATILE_FILE, /* indicate volatile file */ + FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */ + FI_DROP_CACHE, /* drop dirty page cache */ + FI_DATA_EXIST, /* indicate data exists */ + FI_INLINE_DOTS, /* indicate inline dot dentries */ }; static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) { - set_bit(flag, &fi->flags); + if (!test_bit(flag, &fi->flags)) + set_bit(flag, &fi->flags); } static inline int is_inode_flag_set(struct f2fs_inode_info *fi, int flag) @@ -860,7 +1254,8 @@ static inline int is_inode_flag_set(struct f2fs_inode_info *fi, int flag) static inline void clear_inode_flag(struct f2fs_inode_info *fi, int flag) { - clear_bit(flag, &fi->flags); + if (test_bit(flag, &fi->flags)) + clear_bit(flag, &fi->flags); } static inline void set_acl_inode(struct f2fs_inode_info *fi, umode_t mode) @@ -869,23 +1264,160 @@ static inline void set_acl_inode(struct f2fs_inode_info *fi, umode_t mode) set_inode_flag(fi, FI_ACL_MODE); } -static inline int cond_clear_inode_flag(struct f2fs_inode_info *fi, int flag) +static inline void get_inline_info(struct f2fs_inode_info *fi, + struct f2fs_inode *ri) { - if (is_inode_flag_set(fi, FI_ACL_MODE)) { - clear_inode_flag(fi, FI_ACL_MODE); - return 1; - } - return 0; + if (ri->i_inline & F2FS_INLINE_XATTR) + set_inode_flag(fi, FI_INLINE_XATTR); + if (ri->i_inline & F2FS_INLINE_DATA) + set_inode_flag(fi, FI_INLINE_DATA); + if (ri->i_inline & F2FS_INLINE_DENTRY) + set_inode_flag(fi, FI_INLINE_DENTRY); + if (ri->i_inline & F2FS_DATA_EXIST) + set_inode_flag(fi, FI_DATA_EXIST); + if (ri->i_inline & F2FS_INLINE_DOTS) + set_inode_flag(fi, FI_INLINE_DOTS); +} + +static inline void set_raw_inline(struct f2fs_inode_info *fi, + struct f2fs_inode *ri) +{ + ri->i_inline = 0; + + if (is_inode_flag_set(fi, FI_INLINE_XATTR)) + ri->i_inline |= F2FS_INLINE_XATTR; + if (is_inode_flag_set(fi, FI_INLINE_DATA)) + ri->i_inline |= F2FS_INLINE_DATA; + if (is_inode_flag_set(fi, FI_INLINE_DENTRY)) + ri->i_inline |= F2FS_INLINE_DENTRY; + if (is_inode_flag_set(fi, FI_DATA_EXIST)) + ri->i_inline |= F2FS_DATA_EXIST; + if (is_inode_flag_set(fi, FI_INLINE_DOTS)) + ri->i_inline |= F2FS_INLINE_DOTS; +} + +static inline int f2fs_has_inline_xattr(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_INLINE_XATTR); +} + +static inline unsigned int addrs_per_inode(struct f2fs_inode_info *fi) +{ + if (f2fs_has_inline_xattr(&fi->vfs_inode)) + return DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS; + return DEF_ADDRS_PER_INODE; +} + +static inline void *inline_xattr_addr(struct page *page) +{ + struct f2fs_inode *ri = F2FS_INODE(page); + return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE - + F2FS_INLINE_XATTR_ADDRS]); +} + +static inline int inline_xattr_size(struct inode *inode) +{ + if (f2fs_has_inline_xattr(inode)) + return F2FS_INLINE_XATTR_ADDRS << 2; + else + return 0; +} + +static inline int f2fs_has_inline_data(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_INLINE_DATA); +} + +static inline void f2fs_clear_inline_inode(struct inode *inode) +{ + clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); + clear_inode_flag(F2FS_I(inode), FI_DATA_EXIST); +} + +static inline int f2fs_exist_data(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_DATA_EXIST); } +static inline int f2fs_has_inline_dots(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_INLINE_DOTS); +} + +static inline bool f2fs_is_atomic_file(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_ATOMIC_FILE); +} + +static inline bool f2fs_is_volatile_file(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_VOLATILE_FILE); +} + +static inline bool f2fs_is_first_block_written(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_FIRST_BLOCK_WRITTEN); +} + +static inline bool f2fs_is_drop_cache(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_DROP_CACHE); +} + +static inline void *inline_data_addr(struct page *page) +{ + struct f2fs_inode *ri = F2FS_INODE(page); + return (void *)&(ri->i_addr[1]); +} + +static inline int f2fs_has_inline_dentry(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_INLINE_DENTRY); +} + +static inline void f2fs_dentry_kunmap(struct inode *dir, struct page *page) +{ + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); +} + +static inline int f2fs_readonly(struct super_block *sb) +{ + return sb->s_flags & MS_RDONLY; +} + +static inline bool f2fs_cp_error(struct f2fs_sb_info *sbi) +{ + return is_set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); +} + +static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi) +{ + set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); + sbi->sb->s_flags |= MS_RDONLY; +} + +#define get_inode_mode(i) \ + ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ + (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) + +/* get offset of first page in next direct node */ +#define PGOFS_OF_NEXT_DNODE(pgofs, fi) \ + ((pgofs < ADDRS_PER_INODE(fi)) ? ADDRS_PER_INODE(fi) : \ + (pgofs - ADDRS_PER_INODE(fi) + ADDRS_PER_BLOCK) / \ + ADDRS_PER_BLOCK * ADDRS_PER_BLOCK + ADDRS_PER_INODE(fi)) + /* * file.c */ int f2fs_sync_file(struct file *, loff_t, loff_t, int); void truncate_data_blocks(struct dnode_of_data *); +int truncate_blocks(struct inode *, u64, bool); void f2fs_truncate(struct inode *); +int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *); int f2fs_setattr(struct dentry *, struct iattr *); int truncate_hole(struct inode *, pgoff_t, pgoff_t); +int truncate_data_blocks_range(struct dnode_of_data *, int); long f2fs_ioctl(struct file *, unsigned int, unsigned long); long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long); @@ -894,10 +1426,12 @@ long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long); */ void f2fs_set_inode_flags(struct inode *); struct inode *f2fs_iget(struct super_block *, unsigned long); +int try_to_free_nats(struct f2fs_sb_info *, int); void update_inode(struct inode *, struct page *); -int update_inode_page(struct inode *); +void update_inode_page(struct inode *); int f2fs_write_inode(struct inode *, struct writeback_control *); void f2fs_evict_inode(struct inode *); +void handle_failed_inode(struct inode *); /* * namei.c @@ -907,22 +1441,40 @@ struct dentry *f2fs_get_parent(struct dentry *child); /* * dir.c */ +extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; +void set_de_type(struct f2fs_dir_entry *, umode_t); +struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, + struct f2fs_dentry_ptr *); +bool f2fs_fill_dentries(struct file *, void *, filldir_t, + struct f2fs_dentry_ptr *, unsigned int, unsigned int); +void do_make_empty_dir(struct inode *, struct inode *, + struct f2fs_dentry_ptr *); +struct page *init_inode_metadata(struct inode *, struct inode *, + const struct qstr *, struct page *); +void update_parent_metadata(struct inode *, struct inode *, unsigned int); +int room_for_filename(const void *, int, int); +void f2fs_drop_nlink(struct inode *, struct inode *, struct page *); struct f2fs_dir_entry *f2fs_find_entry(struct inode *, struct qstr *, struct page **); struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **); ino_t f2fs_inode_by_name(struct inode *, struct qstr *); void f2fs_set_link(struct inode *, struct f2fs_dir_entry *, struct page *, struct inode *); -void init_dent_inode(const struct qstr *, struct page *); -int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *); -void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *); +int update_dent_inode(struct inode *, const struct qstr *); +void f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *, + const struct qstr *, f2fs_hash_t , unsigned int); +int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *, nid_t, + umode_t); +void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *, + struct inode *); +int f2fs_do_tmpfile(struct inode *, struct inode *); int f2fs_make_empty(struct inode *, struct inode *); bool f2fs_empty_dir(struct inode *); static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) { return __f2fs_add_link(dentry->d_parent->d_inode, &dentry->d_name, - inode); + inode, inode->i_ino, inode->i_mode); } /* @@ -935,7 +1487,7 @@ void f2fs_msg(struct super_block *, const char *, const char *, ...); /* * hash.c */ -f2fs_hash_t f2fs_dentry_hash(const char *, size_t); +f2fs_hash_t f2fs_dentry_hash(const struct qstr *); /* * node.c @@ -943,13 +1495,18 @@ f2fs_hash_t f2fs_dentry_hash(const char *, size_t); struct dnode_of_data; struct node_info; -int is_checkpointed_node(struct f2fs_sb_info *, nid_t); +bool available_free_memory(struct f2fs_sb_info *, int); +bool is_checkpointed_node(struct f2fs_sb_info *, nid_t); +bool has_fsynced_inode(struct f2fs_sb_info *, nid_t); +bool need_inode_block_update(struct f2fs_sb_info *, nid_t); void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *); int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int); int truncate_inode_blocks(struct inode *, pgoff_t); -int remove_inode_page(struct inode *); -int new_inode_page(struct inode *, const struct qstr *); -struct page *new_node_page(struct dnode_of_data *, unsigned int); +int truncate_xattr_node(struct inode *, struct page *); +int wait_on_node_pages_writeback(struct f2fs_sb_info *, nid_t); +void remove_inode_page(struct inode *); +struct page *new_inode_page(struct inode *); +struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *); void ra_node_page(struct f2fs_sb_info *, nid_t); struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); struct page *get_node_page_ra(struct page *, int); @@ -958,8 +1515,8 @@ int sync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *); bool alloc_nid(struct f2fs_sb_info *, nid_t *); void alloc_nid_done(struct f2fs_sb_info *, nid_t); void alloc_nid_failed(struct f2fs_sb_info *, nid_t); -void recover_node_page(struct f2fs_sb_info *, struct page *, - struct f2fs_summary *, struct node_info *, block_t); +void recover_inline_xattr(struct inode *, struct page *); +void recover_xattr_data(struct inode *, struct page *, block_t); int recover_inode_page(struct f2fs_sb_info *, struct page *); int restore_node_summary(struct f2fs_sb_info *, unsigned int, struct f2fs_summary_block *); @@ -972,73 +1529,105 @@ void destroy_node_manager_caches(void); /* * segment.c */ +void register_inmem_page(struct inode *, struct page *); +void commit_inmem_pages(struct inode *, bool); void f2fs_balance_fs(struct f2fs_sb_info *); +void f2fs_balance_fs_bg(struct f2fs_sb_info *); +int f2fs_issue_flush(struct f2fs_sb_info *); +int create_flush_cmd_control(struct f2fs_sb_info *); +void destroy_flush_cmd_control(struct f2fs_sb_info *); void invalidate_blocks(struct f2fs_sb_info *, block_t); -void locate_dirty_segment(struct f2fs_sb_info *, unsigned int); +void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); void clear_prefree_segments(struct f2fs_sb_info *); -int npages_for_summary_flush(struct f2fs_sb_info *); +void release_discard_addrs(struct f2fs_sb_info *); +void discard_next_dnode(struct f2fs_sb_info *, block_t); +int npages_for_summary_flush(struct f2fs_sb_info *, bool); void allocate_new_segments(struct f2fs_sb_info *); +int f2fs_trim_fs(struct f2fs_sb_info *, struct fstrim_range *); struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); -struct bio *f2fs_bio_alloc(struct block_device *, int); -void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); void write_meta_page(struct f2fs_sb_info *, struct page *); -void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int, - block_t, block_t *); -void write_data_page(struct inode *, struct page *, struct dnode_of_data*, - block_t, block_t *); -void rewrite_data_page(struct f2fs_sb_info *, struct page *, block_t); +void write_node_page(struct f2fs_sb_info *, struct page *, + unsigned int, struct f2fs_io_info *); +void write_data_page(struct page *, struct dnode_of_data *, + struct f2fs_io_info *); +void rewrite_data_page(struct page *, struct f2fs_io_info *); void recover_data_page(struct f2fs_sb_info *, struct page *, struct f2fs_summary *, block_t, block_t); -void rewrite_node_page(struct f2fs_sb_info *, struct page *, - struct f2fs_summary *, block_t, block_t); +void allocate_data_block(struct f2fs_sb_info *, struct page *, + block_t, block_t *, struct f2fs_summary *, int); +void f2fs_wait_on_page_writeback(struct page *, enum page_type); void write_data_summaries(struct f2fs_sb_info *, block_t); void write_node_summaries(struct f2fs_sb_info *, block_t); int lookup_journal_in_cursum(struct f2fs_summary_block *, int, unsigned int, int); -void flush_sit_entries(struct f2fs_sb_info *); +void flush_sit_entries(struct f2fs_sb_info *, struct cp_control *); int build_segment_manager(struct f2fs_sb_info *); void destroy_segment_manager(struct f2fs_sb_info *); +int __init create_segment_manager_caches(void); +void destroy_segment_manager_caches(void); /* * checkpoint.c */ struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t); struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t); +int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int); +void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t); long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); -int check_orphan_space(struct f2fs_sb_info *); +void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type); +void remove_dirty_inode(struct f2fs_sb_info *, nid_t, int type); +void release_dirty_inode(struct f2fs_sb_info *); +bool exist_written_data(struct f2fs_sb_info *, nid_t, int); +int acquire_orphan_inode(struct f2fs_sb_info *); +void release_orphan_inode(struct f2fs_sb_info *); void add_orphan_inode(struct f2fs_sb_info *, nid_t); void remove_orphan_inode(struct f2fs_sb_info *, nid_t); -int recover_orphan_inodes(struct f2fs_sb_info *); +void recover_orphan_inodes(struct f2fs_sb_info *); int get_valid_checkpoint(struct f2fs_sb_info *); -void set_dirty_dir_page(struct inode *, struct page *); +void update_dirty_page(struct inode *, struct page *); +void add_dirty_dir_inode(struct inode *); void remove_dirty_dir_inode(struct inode *); void sync_dirty_dir_inodes(struct f2fs_sb_info *); -void write_checkpoint(struct f2fs_sb_info *, bool); -void init_orphan_info(struct f2fs_sb_info *); +void write_checkpoint(struct f2fs_sb_info *, struct cp_control *); +void init_ino_entry_info(struct f2fs_sb_info *); int __init create_checkpoint_caches(void); void destroy_checkpoint_caches(void); /* * data.c */ +void f2fs_submit_merged_bio(struct f2fs_sb_info *, enum page_type, int); +int f2fs_submit_page_bio(struct f2fs_sb_info *, struct page *, + struct f2fs_io_info *); +void f2fs_submit_page_mbio(struct f2fs_sb_info *, struct page *, + struct f2fs_io_info *); +void set_data_blkaddr(struct dnode_of_data *); int reserve_new_block(struct dnode_of_data *); -void update_extent_cache(block_t, struct dnode_of_data *); +int f2fs_reserve_block(struct dnode_of_data *, pgoff_t); +void f2fs_shrink_extent_tree(struct f2fs_sb_info *, int); +void f2fs_destroy_extent_tree(struct inode *); +void f2fs_init_extent_cache(struct inode *, struct f2fs_extent *); +void f2fs_update_extent_cache(struct dnode_of_data *); +void f2fs_preserve_extent_tree(struct inode *); struct page *find_data_page(struct inode *, pgoff_t, bool); struct page *get_lock_data_page(struct inode *, pgoff_t); -struct page *get_new_data_page(struct inode *, pgoff_t, bool); -int f2fs_readpage(struct f2fs_sb_info *, struct page *, block_t, int); -int do_write_data_page(struct page *); +struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); +int do_write_data_page(struct page *, struct f2fs_io_info *); +int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64); +void init_extent_cache_info(struct f2fs_sb_info *); +int __init create_extent_cache(void); +void destroy_extent_cache(void); +void f2fs_invalidate_page(struct page *, unsigned long); +int f2fs_release_page(struct page *, gfp_t); /* * gc.c */ int start_gc_thread(struct f2fs_sb_info *); void stop_gc_thread(struct f2fs_sb_info *); -block_t start_bidx_of_node(unsigned int); +block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *); int f2fs_gc(struct f2fs_sb_info *); void build_gc_manager(struct f2fs_sb_info *); -int __init create_gc_caches(void); -void destroy_gc_caches(void); /* * recovery.c @@ -1053,58 +1642,101 @@ bool space_for_roll_forward(struct f2fs_sb_info *); struct f2fs_stat_info { struct list_head stat_list; struct f2fs_sb_info *sbi; - struct mutex stat_lock; int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs; int main_area_segs, main_area_sections, main_area_zones; - int hit_ext, total_ext; + int hit_ext, total_ext, ext_tree, ext_node; int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; - int nats, sits, fnids; + int nats, dirty_nats, sits, dirty_sits, fnids; int total_count, utilization; - int bg_gc; + int bg_gc, inline_inode, inline_dir, inmem_pages, wb_pages; unsigned int valid_count, valid_node_count, valid_inode_count; unsigned int bimodal, avg_vblocks; int util_free, util_valid, util_invalid; int rsvd_segs, overp_segs; int dirty_count, node_pages, meta_pages; - int prefree_count, call_count; + int prefree_count, call_count, cp_count; int tot_segs, node_segs, data_segs, free_segs, free_secs; + int bg_node_segs, bg_data_segs; int tot_blks, data_blks, node_blks; + int bg_data_blks, bg_node_blks; int curseg[NR_CURSEG_TYPE]; int cursec[NR_CURSEG_TYPE]; int curzone[NR_CURSEG_TYPE]; unsigned int segment_count[2]; unsigned int block_count[2]; - unsigned base_mem, cache_mem; + unsigned int inplace_count; + unsigned base_mem, cache_mem, page_mem; }; -#define stat_inc_call_count(si) ((si)->call_count++) +static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) +{ + return (struct f2fs_stat_info *)sbi->stat_info; +} -#define stat_inc_seg_count(sbi, type) \ +#define stat_inc_cp_count(si) ((si)->cp_count++) +#define stat_inc_call_count(si) ((si)->call_count++) +#define stat_inc_bggc_count(sbi) ((sbi)->bg_gc++) +#define stat_inc_dirty_dir(sbi) ((sbi)->n_dirty_dirs++) +#define stat_dec_dirty_dir(sbi) ((sbi)->n_dirty_dirs--) +#define stat_inc_total_hit(sb) ((F2FS_SB(sb))->total_hit_ext++) +#define stat_inc_read_hit(sb) ((F2FS_SB(sb))->read_hit_ext++) +#define stat_inc_inline_inode(inode) \ + do { \ + if (f2fs_has_inline_data(inode)) \ + (atomic_inc(&F2FS_I_SB(inode)->inline_inode)); \ + } while (0) +#define stat_dec_inline_inode(inode) \ + do { \ + if (f2fs_has_inline_data(inode)) \ + (atomic_dec(&F2FS_I_SB(inode)->inline_inode)); \ + } while (0) +#define stat_inc_inline_dir(inode) \ do { \ - struct f2fs_stat_info *si = sbi->stat_info; \ + if (f2fs_has_inline_dentry(inode)) \ + (atomic_inc(&F2FS_I_SB(inode)->inline_dir)); \ + } while (0) +#define stat_dec_inline_dir(inode) \ + do { \ + if (f2fs_has_inline_dentry(inode)) \ + (atomic_dec(&F2FS_I_SB(inode)->inline_dir)); \ + } while (0) +#define stat_inc_seg_type(sbi, curseg) \ + ((sbi)->segment_count[(curseg)->alloc_type]++) +#define stat_inc_block_count(sbi, curseg) \ + ((sbi)->block_count[(curseg)->alloc_type]++) +#define stat_inc_inplace_blocks(sbi) \ + (atomic_inc(&(sbi)->inplace_count)) +#define stat_inc_seg_count(sbi, type, gc_type) \ + do { \ + struct f2fs_stat_info *si = F2FS_STAT(sbi); \ (si)->tot_segs++; \ - if (type == SUM_TYPE_DATA) \ + if (type == SUM_TYPE_DATA) { \ si->data_segs++; \ - else \ + si->bg_data_segs += (gc_type == BG_GC) ? 1 : 0; \ + } else { \ si->node_segs++; \ + si->bg_node_segs += (gc_type == BG_GC) ? 1 : 0; \ + } \ } while (0) #define stat_inc_tot_blk_count(si, blks) \ (si->tot_blks += (blks)) -#define stat_inc_data_blk_count(sbi, blks) \ +#define stat_inc_data_blk_count(sbi, blks, gc_type) \ do { \ - struct f2fs_stat_info *si = sbi->stat_info; \ + struct f2fs_stat_info *si = F2FS_STAT(sbi); \ stat_inc_tot_blk_count(si, blks); \ si->data_blks += (blks); \ + si->bg_data_blks += (gc_type == BG_GC) ? (blks) : 0; \ } while (0) -#define stat_inc_node_blk_count(sbi, blks) \ +#define stat_inc_node_blk_count(sbi, blks, gc_type) \ do { \ - struct f2fs_stat_info *si = sbi->stat_info; \ + struct f2fs_stat_info *si = F2FS_STAT(sbi); \ stat_inc_tot_blk_count(si, blks); \ si->node_blks += (blks); \ + si->bg_node_blks += (gc_type == BG_GC) ? (blks) : 0; \ } while (0) int f2fs_build_stats(struct f2fs_sb_info *); @@ -1112,11 +1744,24 @@ void f2fs_destroy_stats(struct f2fs_sb_info *); void __init f2fs_create_root_stats(void); void f2fs_destroy_root_stats(void); #else +#define stat_inc_cp_count(si) #define stat_inc_call_count(si) -#define stat_inc_seg_count(si, type) +#define stat_inc_bggc_count(si) +#define stat_inc_dirty_dir(sbi) +#define stat_dec_dirty_dir(sbi) +#define stat_inc_total_hit(sb) +#define stat_inc_read_hit(sb) +#define stat_inc_inline_inode(inode) +#define stat_dec_inline_inode(inode) +#define stat_inc_inline_dir(inode) +#define stat_dec_inline_dir(inode) +#define stat_inc_seg_type(sbi, curseg) +#define stat_inc_block_count(sbi, curseg) +#define stat_inc_inplace_blocks(sbi) +#define stat_inc_seg_count(sbi, type, gc_type) #define stat_inc_tot_blk_count(si, blks) -#define stat_inc_data_blk_count(si, blks) -#define stat_inc_node_blk_count(sbi, blks) +#define stat_inc_data_blk_count(sbi, blks, gc_type) +#define stat_inc_node_blk_count(sbi, blks, gc_type) static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } @@ -1133,4 +1778,27 @@ extern const struct address_space_operations f2fs_meta_aops; extern const struct inode_operations f2fs_dir_inode_operations; extern const struct inode_operations f2fs_symlink_inode_operations; extern const struct inode_operations f2fs_special_inode_operations; +extern struct kmem_cache *inode_entry_slab; + +/* + * inline.c + */ +bool f2fs_may_inline(struct inode *); +void read_inline_data(struct page *, struct page *); +bool truncate_inline_inode(struct page *, u64); +int f2fs_read_inline_data(struct inode *, struct page *); +int f2fs_convert_inline_page(struct dnode_of_data *, struct page *); +int f2fs_convert_inline_inode(struct inode *); +int f2fs_write_inline_data(struct inode *, struct page *); +bool recover_inline_data(struct inode *, struct page *); +struct f2fs_dir_entry *find_in_inline_dir(struct inode *, struct qstr *, + struct page **); +struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *, struct page **); +int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *); +int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *, + nid_t, umode_t); +void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *, + struct inode *, struct inode *); +bool f2fs_empty_inline_dir(struct inode *); +int f2fs_read_inline_dir(struct file *, void *, filldir_t); #endif diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 1cae864f8dfcd..7a1342318addc 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -19,12 +19,14 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" #include "segment.h" #include "xattr.h" #include "acl.h" +#include "trace.h" #include static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, @@ -32,41 +34,32 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, { struct page *page = vmf->page; struct inode *inode = file_inode(vma->vm_file); - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - block_t old_blk_addr; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; - int err, ilock; + int err; f2fs_balance_fs(sbi); sb_start_pagefault(inode->i_sb); + f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); + /* block allocation */ - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); set_new_dnode(&dn, inode, NULL, NULL, 0); - err = get_dnode_of_data(&dn, page->index, ALLOC_NODE); + err = f2fs_reserve_block(&dn, page->index); if (err) { - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); goto out; } - - old_blk_addr = dn.data_blkaddr; - - if (old_blk_addr == NULL_ADDR) { - err = reserve_new_block(&dn); - if (err) { - f2fs_put_dnode(&dn); - mutex_unlock_op(sbi, ilock); - goto out; - } - } f2fs_put_dnode(&dn); - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); + file_update_time(vma->vm_file); lock_page(page); - if (page->mapping != inode->i_mapping || - page_offset(page) >= i_size_read(inode) || - !PageUptodate(page)) { + if (unlikely(page->mapping != inode->i_mapping || + page_offset(page) > i_size_read(inode) || + !PageUptodate(page))) { unlock_page(page); err = -EFAULT; goto out; @@ -76,10 +69,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, * check to see if the page is mapped already (no holes) */ if (PageMappedToDisk(page)) - goto out; - - /* fill the page */ - wait_on_page_writeback(page); + goto mapped; /* page is wholly or partially inside EOF */ if (((page->index + 1) << PAGE_CACHE_SHIFT) > i_size_read(inode)) { @@ -90,7 +80,10 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, set_page_dirty(page); SetPageUptodate(page); - file_update_time(vma->vm_file); + trace_f2fs_vm_page_mkwrite(page, DATA); +mapped: + /* fill the page */ + f2fs_wait_on_page_writeback(page, DATA); out: sb_end_pagefault(inode->i_sb); return block_page_mkwrite_return(err); @@ -102,10 +95,86 @@ static const struct vm_operations_struct f2fs_file_vm_ops = { .remap_pages = generic_file_remap_pages, }; +static int get_parent_ino(struct inode *inode, nid_t *pino) +{ + struct dentry *dentry; + + inode = igrab(inode); + dentry = d_find_any_alias(inode); + iput(inode); + if (!dentry) + return 0; + + if (update_dent_inode(inode, &dentry->d_name)) { + dput(dentry); + return 0; + } + + *pino = parent_ino(dentry); + dput(dentry); + return 1; +} + +static inline bool need_do_checkpoint(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + bool need_cp = false; + + if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) + need_cp = true; + else if (file_wrong_pino(inode)) + need_cp = true; + else if (!space_for_roll_forward(sbi)) + need_cp = true; + else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) + need_cp = true; + else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi))) + need_cp = true; + else if (test_opt(sbi, FASTBOOT)) + need_cp = true; + else if (sbi->active_logs == 2) + need_cp = true; + + return need_cp; +} + +static bool need_inode_page_update(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct page *i = find_get_page(NODE_MAPPING(sbi), ino); + bool ret = false; + /* But we need to avoid that there are some inode updates */ + if ((i && PageDirty(i)) || need_inode_block_update(sbi, ino)) + ret = true; + f2fs_put_page(i, 0); + return ret; +} + +static void try_to_fix_pino(struct inode *inode) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + nid_t pino; + + down_write(&fi->i_sem); + fi->xattr_ver = 0; + if (file_wrong_pino(inode) && inode->i_nlink == 1 && + get_parent_ino(inode, &pino)) { + fi->i_pino = pino; + file_got_pino(inode); + up_write(&fi->i_sem); + + mark_inode_dirty_sync(inode); + f2fs_write_inode(inode, NULL); + } else { + up_write(&fi->i_sem); + } +} + int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file->f_mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_inode_info *fi = F2FS_I(inode); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + nid_t ino = inode->i_ino; int ret = 0; bool need_cp = false; struct writeback_control wbc = { @@ -114,81 +183,287 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) .for_reclaim = 0, }; - if (inode->i_sb->s_flags & MS_RDONLY) + if (unlikely(f2fs_readonly(inode->i_sb))) return 0; trace_f2fs_sync_file_enter(inode); + + /* if fdatasync is triggered, let's do in-place-update */ + if (get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) + set_inode_flag(fi, FI_NEED_IPU); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + clear_inode_flag(fi, FI_NEED_IPU); + if (ret) { trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); return ret; } - /* guarantee free sections for fsync */ - f2fs_balance_fs(sbi); + /* if the inode is dirty, let's recover all the time */ + if (!datasync && is_inode_flag_set(fi, FI_DIRTY_INODE)) { + update_inode_page(inode); + goto go_write; + } - mutex_lock(&inode->i_mutex); + /* + * if there is no written data, don't waste time to write recovery info. + */ + if (!is_inode_flag_set(fi, FI_APPEND_WRITE) && + !exist_written_data(sbi, ino, APPEND_INO)) { + + /* it may call write_inode just prior to fsync */ + if (need_inode_page_update(sbi, ino)) + goto go_write; - if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) + if (is_inode_flag_set(fi, FI_UPDATE_WRITE) || + exist_written_data(sbi, ino, UPDATE_INO)) + goto flush_out; goto out; + } +go_write: + /* guarantee free sections for fsync */ + f2fs_balance_fs(sbi); - if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) - need_cp = true; - else if (is_cp_file(inode)) - need_cp = true; - else if (!space_for_roll_forward(sbi)) - need_cp = true; - else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) - need_cp = true; + /* + * Both of fdatasync() and fsync() are able to be recovered from + * sudden-power-off. + */ + down_read(&fi->i_sem); + need_cp = need_do_checkpoint(inode); + up_read(&fi->i_sem); if (need_cp) { /* all the dirty node pages should be flushed for POR */ ret = f2fs_sync_fs(inode->i_sb, 1); - } else { - /* if there is no written node page, write its inode page */ - while (!sync_node_pages(sbi, inode->i_ino, &wbc)) { - ret = f2fs_write_inode(inode, NULL); - if (ret) - goto out; - } - filemap_fdatawait_range(sbi->node_inode->i_mapping, - 0, LONG_MAX); - ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); + + /* + * We've secured consistency through sync_fs. Following pino + * will be used only for fsynced inodes after checkpoint. + */ + try_to_fix_pino(inode); + clear_inode_flag(fi, FI_APPEND_WRITE); + clear_inode_flag(fi, FI_UPDATE_WRITE); + goto out; + } +sync_nodes: + sync_node_pages(sbi, ino, &wbc); + + /* if cp_error was enabled, we should avoid infinite loop */ + if (unlikely(f2fs_cp_error(sbi))) + goto out; + + if (need_inode_block_update(sbi, ino)) { + mark_inode_dirty_sync(inode); + f2fs_write_inode(inode, NULL); + goto sync_nodes; } + + ret = wait_on_node_pages_writeback(sbi, ino); + if (ret) + goto out; + + /* once recovery info is written, don't need to tack this */ + remove_dirty_inode(sbi, ino, APPEND_INO); + clear_inode_flag(fi, FI_APPEND_WRITE); +flush_out: + remove_dirty_inode(sbi, ino, UPDATE_INO); + clear_inode_flag(fi, FI_UPDATE_WRITE); + ret = f2fs_issue_flush(sbi); out: - mutex_unlock(&inode->i_mutex); trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret); + f2fs_trace_ios(NULL, NULL, 1); return ret; } +static pgoff_t __get_first_dirty_index(struct address_space *mapping, + pgoff_t pgofs, int whence) +{ + struct pagevec pvec; + int nr_pages; + + if (whence != SEEK_DATA) + return 0; + + /* find first dirty page index */ + pagevec_init(&pvec, 0); + nr_pages = pagevec_lookup_tag(&pvec, mapping, &pgofs, + PAGECACHE_TAG_DIRTY, 1); + pgofs = nr_pages ? pvec.pages[0]->index : LONG_MAX; + pagevec_release(&pvec); + return pgofs; +} + +static bool __found_offset(block_t blkaddr, pgoff_t dirty, pgoff_t pgofs, + int whence) +{ + switch (whence) { + case SEEK_DATA: + if ((blkaddr == NEW_ADDR && dirty == pgofs) || + (blkaddr != NEW_ADDR && blkaddr != NULL_ADDR)) + return true; + break; + case SEEK_HOLE: + if (blkaddr == NULL_ADDR) + return true; + break; + } + return false; +} + +static inline int unsigned_offsets(struct file *file) +{ + return file->f_mode & FMODE_UNSIGNED_OFFSET; +} + +static loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize) +{ + if (offset < 0 && !unsigned_offsets(file)) + return -EINVAL; + if (offset > maxsize) + return -EINVAL; + + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + } + return offset; +} + +static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) +{ + struct inode *inode = file->f_mapping->host; + loff_t maxbytes = inode->i_sb->s_maxbytes; + struct dnode_of_data dn; + pgoff_t pgofs, end_offset, dirty; + loff_t data_ofs = offset; + loff_t isize; + int err = 0; + + mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); + if (offset >= isize) + goto fail; + + /* handle inline data case */ + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) { + if (whence == SEEK_HOLE) + data_ofs = isize; + goto found; + } + + pgofs = (pgoff_t)(offset >> PAGE_CACHE_SHIFT); + + dirty = __get_first_dirty_index(inode->i_mapping, pgofs, whence); + + for (; data_ofs < isize; data_ofs = pgofs << PAGE_CACHE_SHIFT) { + set_new_dnode(&dn, inode, NULL, NULL, 0); + err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE_RA); + if (err && err != -ENOENT) { + goto fail; + } else if (err == -ENOENT) { + /* direct node does not exists */ + if (whence == SEEK_DATA) { + pgofs = PGOFS_OF_NEXT_DNODE(pgofs, + F2FS_I(inode)); + continue; + } else { + goto found; + } + } + + end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); + + /* find data/hole in dnode block */ + for (; dn.ofs_in_node < end_offset; + dn.ofs_in_node++, pgofs++, + data_ofs = (loff_t)pgofs << PAGE_CACHE_SHIFT) { + block_t blkaddr; + blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); + + if (__found_offset(blkaddr, dirty, pgofs, whence)) { + f2fs_put_dnode(&dn); + goto found; + } + } + f2fs_put_dnode(&dn); + } + + if (whence == SEEK_DATA) + goto fail; +found: + if (whence == SEEK_HOLE && data_ofs > isize) + data_ofs = isize; + mutex_unlock(&inode->i_mutex); + return vfs_setpos(file, data_ofs, maxbytes); +fail: + mutex_unlock(&inode->i_mutex); + return -ENXIO; +} + +static loff_t f2fs_llseek(struct file *file, loff_t offset, int whence) +{ + struct inode *inode = file->f_mapping->host; + loff_t maxbytes = inode->i_sb->s_maxbytes; + + switch (whence) { + case SEEK_SET: + case SEEK_CUR: + case SEEK_END: + return generic_file_llseek_size(file, offset, whence, + maxbytes, i_size_read(inode)); + case SEEK_DATA: + case SEEK_HOLE: + if (offset < 0) + return -ENXIO; + return f2fs_seek_block(file, offset, whence); + } + + return -EINVAL; +} + static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) { + struct inode *inode = file_inode(file); + + /* we don't need to use inline_data strictly */ + if (f2fs_has_inline_data(inode)) { + int err = f2fs_convert_inline_inode(inode); + if (err) + return err; + } + file_accessed(file); vma->vm_ops = &f2fs_file_vm_ops; return 0; } -static int truncate_data_blocks_range(struct dnode_of_data *dn, int count) +int truncate_data_blocks_range(struct dnode_of_data *dn, int count) { int nr_free = 0, ofs = dn->ofs_in_node; - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct f2fs_node *raw_node; __le32 *addr; - raw_node = page_address(dn->node_page); + raw_node = F2FS_NODE(dn->node_page); addr = blkaddr_in_node(raw_node) + ofs; - for ( ; count > 0; count--, addr++, dn->ofs_in_node++) { + for (; count > 0; count--, addr++, dn->ofs_in_node++) { block_t blkaddr = le32_to_cpu(*addr); if (blkaddr == NULL_ADDR) continue; - update_extent_cache(NULL_ADDR, dn); + dn->data_blkaddr = NULL_ADDR; + set_data_blkaddr(dn); + f2fs_update_extent_cache(dn); invalidate_blocks(sbi, blkaddr); - dec_valid_block_count(sbi, dn->inode, 1); + if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page)) + clear_inode_flag(F2FS_I(dn->inode), + FI_FIRST_BLOCK_WRITTEN); nr_free++; } if (nr_free) { + dec_valid_block_count(sbi, dn->inode, nr_free); set_page_dirty(dn->node_page); sync_inode_page(dn); } @@ -204,61 +479,76 @@ void truncate_data_blocks(struct dnode_of_data *dn) truncate_data_blocks_range(dn, ADDRS_PER_BLOCK); } -static void truncate_partial_data_page(struct inode *inode, u64 from) +static int truncate_partial_data_page(struct inode *inode, u64 from, + bool force) { unsigned offset = from & (PAGE_CACHE_SIZE - 1); struct page *page; - if (!offset) - return; + if (!offset && !force) + return 0; - page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, false); + page = find_data_page(inode, from >> PAGE_CACHE_SHIFT, force); if (IS_ERR(page)) - return; + return 0; lock_page(page); - if (page->mapping != inode->i_mapping) { - f2fs_put_page(page, 1); - return; - } - wait_on_page_writeback(page); + if (unlikely(!PageUptodate(page) || + page->mapping != inode->i_mapping)) + goto out; + + f2fs_wait_on_page_writeback(page, DATA); zero_user(page, offset, PAGE_CACHE_SIZE - offset); - set_page_dirty(page); + if (!force) + set_page_dirty(page); +out: f2fs_put_page(page, 1); + return 0; } -static int truncate_blocks(struct inode *inode, u64 from) +int truncate_blocks(struct inode *inode, u64 from, bool lock) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); unsigned int blocksize = inode->i_sb->s_blocksize; struct dnode_of_data dn; pgoff_t free_from; - int count = 0, ilock = -1; - int err; + int count = 0, err = 0; + struct page *ipage; + bool truncate_page = false; trace_f2fs_truncate_blocks_enter(inode, from); - free_from = (pgoff_t) - ((from + blocksize - 1) >> (sbi->log_blocksize)); + free_from = (pgoff_t)F2FS_BYTES_TO_BLK(from + blocksize - 1); - ilock = mutex_lock_op(sbi); - set_new_dnode(&dn, inode, NULL, NULL, 0); + if (lock) + f2fs_lock_op(sbi); + + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + err = PTR_ERR(ipage); + goto out; + } + + if (f2fs_has_inline_data(inode)) { + if (truncate_inline_inode(ipage, from)) + set_page_dirty(ipage); + f2fs_put_page(ipage, 1); + truncate_page = true; + goto out; + } + + set_new_dnode(&dn, inode, ipage, NULL, 0); err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE); if (err) { if (err == -ENOENT) goto free_next; - mutex_unlock_op(sbi, ilock); - trace_f2fs_truncate_blocks_exit(inode, err); - return err; + goto out; } - if (IS_INODE(dn.node_page)) - count = ADDRS_PER_INODE; - else - count = ADDRS_PER_BLOCK; + count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); count -= dn.ofs_in_node; - BUG_ON(count < 0); + f2fs_bug_on(sbi, count < 0); if (dn.ofs_in_node || IS_INODE(dn.node_page)) { truncate_data_blocks_range(&dn, count); @@ -268,10 +558,13 @@ static int truncate_blocks(struct inode *inode, u64 from) f2fs_put_dnode(&dn); free_next: err = truncate_inode_blocks(inode, free_from); - mutex_unlock_op(sbi, ilock); +out: + if (lock) + f2fs_unlock_op(sbi); /* lastly zero out the first data page */ - truncate_partial_data_page(inode, from); + if (!err) + err = truncate_partial_data_page(inode, from, truncate_page); trace_f2fs_truncate_blocks_exit(inode, err); return err; @@ -285,13 +578,19 @@ void f2fs_truncate(struct inode *inode) trace_f2fs_truncate(inode); - if (!truncate_blocks(inode, i_size_read(inode))) { + /* we should check inline_data size */ + if (f2fs_has_inline_data(inode) && !f2fs_may_inline(inode)) { + if (f2fs_convert_inline_inode(inode)) + return; + } + + if (!truncate_blocks(inode, i_size_read(inode), true)) { inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); } } -static int f2fs_getattr(struct vfsmount *mnt, +int f2fs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; @@ -341,11 +640,18 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) if (err) return err; - if ((attr->ia_valid & ATTR_SIZE) && - attr->ia_size != i_size_read(inode)) { - truncate_setsize(inode, attr->ia_size); - f2fs_truncate(inode); - f2fs_balance_fs(F2FS_SB(inode->i_sb)); + if (attr->ia_valid & ATTR_SIZE) { + if (attr->ia_size != i_size_read(inode)) { + truncate_setsize(inode, attr->ia_size); + f2fs_truncate(inode); + f2fs_balance_fs(F2FS_I_SB(inode)); + } else { + /* + * giving a chance to truncate blocks past EOF which + * are fallocated with FALLOC_FL_KEEP_SIZE. + */ + f2fs_truncate(inode); + } } __setattr_copy(inode, attr); @@ -372,26 +678,26 @@ const struct inode_operations f2fs_file_inode_operations = { .listxattr = f2fs_listxattr, .removexattr = generic_removexattr, #endif + .fiemap = f2fs_fiemap, }; static void fill_zero(struct inode *inode, pgoff_t index, loff_t start, loff_t len) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct page *page; - int ilock; if (!len) return; f2fs_balance_fs(sbi); - ilock = mutex_lock_op(sbi); - page = get_new_data_page(inode, index, false); - mutex_unlock_op(sbi, ilock); + f2fs_lock_op(sbi); + page = get_new_data_page(inode, NULL, index, false); + f2fs_unlock_op(sbi); if (!IS_ERR(page)) { - wait_on_page_writeback(page); + f2fs_wait_on_page_writeback(page, DATA); zero_user(page, start, len); set_page_dirty(page); f2fs_put_page(page, 1); @@ -421,12 +727,25 @@ int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end) return 0; } -static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode) +static int punch_hole(struct inode *inode, loff_t offset, loff_t len) { pgoff_t pg_start, pg_end; loff_t off_start, off_end; int ret = 0; + if (!S_ISREG(inode->i_mode)) + return -EOPNOTSUPP; + + /* skip punching hole beyond i_size */ + if (offset >= inode->i_size) + return ret; + + if (f2fs_has_inline_data(inode)) { + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; + } + pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; @@ -446,8 +765,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode) if (pg_start < pg_end) { struct address_space *mapping = inode->i_mapping; loff_t blk_start, blk_end; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - int ilock; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); f2fs_balance_fs(sbi); @@ -456,63 +774,55 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode) truncate_inode_pages_range(mapping, blk_start, blk_end - 1); - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); ret = truncate_hole(inode, pg_start, pg_end); - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); } } - if (!(mode & FALLOC_FL_KEEP_SIZE) && - i_size_read(inode) <= (offset + len)) { - i_size_write(inode, offset); - mark_inode_dirty(inode); - } - return ret; } static int expand_inode_data(struct inode *inode, loff_t offset, loff_t len, int mode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); pgoff_t index, pg_start, pg_end; loff_t new_size = i_size_read(inode); loff_t off_start, off_end; int ret = 0; + f2fs_balance_fs(sbi); + ret = inode_newsize_ok(inode, (len + offset)); if (ret) return ret; + if (f2fs_has_inline_data(inode)) { + ret = f2fs_convert_inline_inode(inode); + if (ret) + return ret; + } + pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT; off_start = offset & (PAGE_CACHE_SIZE - 1); off_end = (offset + len) & (PAGE_CACHE_SIZE - 1); + f2fs_lock_op(sbi); + for (index = pg_start; index <= pg_end; index++) { struct dnode_of_data dn; - int ilock; - ilock = mutex_lock_op(sbi); + if (index == pg_end && !off_end) + goto noalloc; + set_new_dnode(&dn, inode, NULL, NULL, 0); - ret = get_dnode_of_data(&dn, index, ALLOC_NODE); - if (ret) { - mutex_unlock_op(sbi, ilock); + ret = f2fs_reserve_block(&dn, index); + if (ret) break; - } - - if (dn.data_blkaddr == NULL_ADDR) { - ret = reserve_new_block(&dn); - if (ret) { - f2fs_put_dnode(&dn); - mutex_unlock_op(sbi, ilock); - break; - } - } - f2fs_put_dnode(&dn); - mutex_unlock_op(sbi, ilock); - +noalloc: if (pg_start == pg_end) new_size = offset + len; else if (index == pg_start && off_start) @@ -527,7 +837,9 @@ static int expand_inode_data(struct inode *inode, loff_t offset, i_size_read(inode) < new_size) { i_size_write(inode, new_size); mark_inode_dirty(inode); + update_inode_page(inode); } + f2fs_unlock_op(sbi); return ret; } @@ -541,8 +853,10 @@ static long f2fs_fallocate(struct file *file, int mode, if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) return -EOPNOTSUPP; + mutex_lock(&inode->i_mutex); + if (mode & FALLOC_FL_PUNCH_HOLE) - ret = punch_hole(inode, offset, len, mode); + ret = punch_hole(inode, offset, len); else ret = expand_inode_data(inode, offset, len, mode); @@ -550,10 +864,26 @@ static long f2fs_fallocate(struct file *file, int mode, inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); } + + mutex_unlock(&inode->i_mutex); + trace_f2fs_fallocate(inode, mode, offset, len, ret); return ret; } +static int f2fs_release_file(struct inode *inode, struct file *filp) +{ + /* some remained atomic pages should discarded */ + if (f2fs_is_atomic_file(inode)) + commit_inmem_pages(inode, true); + if (f2fs_is_volatile_file(inode)) { + set_inode_flag(F2FS_I(inode), FI_DROP_CACHE); + filemap_fdatawrite(inode->i_mapping); + clear_inode_flag(F2FS_I(inode), FI_DROP_CACHE); + } + return 0; +} + #define F2FS_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) #define F2FS_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) @@ -567,61 +897,259 @@ static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags) return flags & F2FS_OTHER_FLMASK; } -long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_inode_info *fi = F2FS_I(inode); + unsigned int flags = fi->i_flags & FS_FL_USER_VISIBLE; + return put_user(flags, (int __user *)arg); +} + +static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); - unsigned int flags; + unsigned int flags = fi->i_flags & FS_FL_USER_VISIBLE; + unsigned int oldflags; int ret; - switch (cmd) { - case FS_IOC_GETFLAGS: - flags = fi->i_flags & FS_FL_USER_VISIBLE; - return put_user(flags, (int __user *) arg); - case FS_IOC_SETFLAGS: - { - unsigned int oldflags; - - ret = mnt_want_write_file(filp); - if (ret) - return ret; + ret = mnt_want_write_file(filp); + if (ret) + return ret; - if (!inode_owner_or_capable(inode)) { - ret = -EACCES; - goto out; - } + if (!inode_owner_or_capable(inode)) { + ret = -EACCES; + goto out; + } - if (get_user(flags, (int __user *) arg)) { - ret = -EFAULT; - goto out; - } + if (get_user(flags, (int __user *)arg)) { + ret = -EFAULT; + goto out; + } - flags = f2fs_mask_flags(inode->i_mode, flags); + flags = f2fs_mask_flags(inode->i_mode, flags); - mutex_lock(&inode->i_mutex); + mutex_lock(&inode->i_mutex); - oldflags = fi->i_flags; + oldflags = fi->i_flags; - if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) { - if (!capable(CAP_LINUX_IMMUTABLE)) { - mutex_unlock(&inode->i_mutex); - ret = -EPERM; - goto out; - } + if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) { + if (!capable(CAP_LINUX_IMMUTABLE)) { + mutex_unlock(&inode->i_mutex); + ret = -EPERM; + goto out; } + } - flags = flags & FS_FL_USER_MODIFIABLE; - flags |= oldflags & ~FS_FL_USER_MODIFIABLE; - fi->i_flags = flags; - mutex_unlock(&inode->i_mutex); + flags = flags & FS_FL_USER_MODIFIABLE; + flags |= oldflags & ~FS_FL_USER_MODIFIABLE; + fi->i_flags = flags; + mutex_unlock(&inode->i_mutex); - f2fs_set_inode_flags(inode); - inode->i_ctime = CURRENT_TIME; - mark_inode_dirty(inode); + f2fs_set_inode_flags(inode); + inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(inode); out: - mnt_drop_write_file(filp); + mnt_drop_write_file(filp); + return ret; +} + +static int f2fs_ioc_getversion(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + + return put_user(inode->i_generation, (int __user *)arg); +} + +static int f2fs_ioc_start_atomic_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + f2fs_balance_fs(F2FS_I_SB(inode)); + + if (f2fs_is_atomic_file(inode)) + return 0; + + set_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); + + return f2fs_convert_inline_inode(inode); +} + +static int f2fs_ioc_commit_atomic_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + int ret; + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + if (f2fs_is_volatile_file(inode)) + return 0; + + ret = mnt_want_write_file(filp); + if (ret) return ret; + + if (f2fs_is_atomic_file(inode)) + commit_inmem_pages(inode, false); + + ret = f2fs_sync_file(filp, 0, LONG_MAX, 0); + mnt_drop_write_file(filp); + clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); + return ret; +} + +static int f2fs_ioc_start_volatile_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + if (f2fs_is_volatile_file(inode)) + return 0; + + set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + + return f2fs_convert_inline_inode(inode); +} + +static int f2fs_ioc_release_volatile_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + if (!f2fs_is_volatile_file(inode)) + return 0; + + if (!f2fs_is_first_block_written(inode)) + return truncate_partial_data_page(inode, 0, true); + + punch_hole(inode, 0, F2FS_BLKSIZE); + return 0; +} + +static int f2fs_ioc_abort_volatile_write(struct file *filp) +{ + struct inode *inode = file_inode(filp); + int ret; + + if (!inode_owner_or_capable(inode)) + return -EACCES; + + ret = mnt_want_write_file(filp); + if (ret) + return ret; + + f2fs_balance_fs(F2FS_I_SB(inode)); + + if (f2fs_is_atomic_file(inode)) { + commit_inmem_pages(inode, false); + clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); + } + + if (f2fs_is_volatile_file(inode)) { + clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + filemap_fdatawrite(inode->i_mapping); + set_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); + } + mnt_drop_write_file(filp); + return ret; +} + +static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct super_block *sb = sbi->sb; + __u32 in; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (get_user(in, (__u32 __user *)arg)) + return -EFAULT; + + switch (in) { + case FS_GOING_DOWN_FULLSYNC: + sb = freeze_bdev(sb->s_bdev); + if (sb && !IS_ERR(sb)) { + f2fs_stop_checkpoint(sbi); + thaw_bdev(sb->s_bdev, sb); + } + break; + case FS_GOING_DOWN_METASYNC: + /* do checkpoint only */ + f2fs_sync_fs(sb, 1); + f2fs_stop_checkpoint(sbi); + break; + case FS_GOING_DOWN_NOSYNC: + f2fs_stop_checkpoint(sbi); + break; + default: + return -EINVAL; } + return 0; +} + +static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct super_block *sb = inode->i_sb; + struct request_queue *q = bdev_get_queue(sb->s_bdev); + struct fstrim_range range; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (!blk_queue_discard(q)) + return -EOPNOTSUPP; + + if (copy_from_user(&range, (struct fstrim_range __user *)arg, + sizeof(range))) + return -EFAULT; + + range.minlen = max((unsigned int)range.minlen, + q->limits.discard_granularity); + ret = f2fs_trim_fs(F2FS_SB(sb), &range); + if (ret < 0) + return ret; + + if (copy_to_user((struct fstrim_range __user *)arg, &range, + sizeof(range))) + return -EFAULT; + return 0; +} + +long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case F2FS_IOC_GETFLAGS: + return f2fs_ioc_getflags(filp, arg); + case F2FS_IOC_SETFLAGS: + return f2fs_ioc_setflags(filp, arg); + case F2FS_IOC_GETVERSION: + return f2fs_ioc_getversion(filp, arg); + case F2FS_IOC_START_ATOMIC_WRITE: + return f2fs_ioc_start_atomic_write(filp); + case F2FS_IOC_COMMIT_ATOMIC_WRITE: + return f2fs_ioc_commit_atomic_write(filp); + case F2FS_IOC_START_VOLATILE_WRITE: + return f2fs_ioc_start_volatile_write(filp); + case F2FS_IOC_RELEASE_VOLATILE_WRITE: + return f2fs_ioc_release_volatile_write(filp); + case F2FS_IOC_ABORT_VOLATILE_WRITE: + return f2fs_ioc_abort_volatile_write(filp); + case FS_IOC_SHUTDOWN: + return f2fs_ioc_shutdown(filp, arg); + case FITRIM: + return f2fs_ioc_fitrim(filp, arg); default: return -ENOTTY; } @@ -645,12 +1173,13 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #endif const struct file_operations f2fs_file_operations = { - .llseek = generic_file_llseek, + .llseek = f2fs_llseek, .read = do_sync_read, .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .open = generic_file_open, + .release = f2fs_release_file, .mmap = f2fs_file_mmap, .fsync = f2fs_sync_file, .fallocate = f2fs_fallocate, diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 14961593e93c8..ed58211fe79b4 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -24,15 +24,14 @@ #include "gc.h" #include -static struct kmem_cache *winode_slab; - static int gc_thread_func(void *data) { struct f2fs_sb_info *sbi = data; + struct f2fs_gc_kthread *gc_th = sbi->gc_thread; wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head; long wait_ms; - wait_ms = GC_THREAD_MIN_SLEEP_TIME; + wait_ms = gc_th->min_sleep_time; do { if (try_to_freeze()) @@ -45,7 +44,7 @@ static int gc_thread_func(void *data) break; if (sbi->sb->s_writers.frozen >= SB_FREEZE_WRITE) { - wait_ms = GC_THREAD_MAX_SLEEP_TIME; + increase_sleep_time(gc_th, &wait_ms); continue; } @@ -57,7 +56,7 @@ static int gc_thread_func(void *data) * 3. IO subsystem is idle by checking the # of requests in * bdev's request list. * - * Note) We have to avoid triggering GCs too much frequently. + * Note) We have to avoid triggering GCs frequently. * Because it is possible that some segments can be * invalidated soon after by user update or deletion. * So, I'd like to wait some time to collect dirty segments. @@ -66,21 +65,25 @@ static int gc_thread_func(void *data) continue; if (!is_idle(sbi)) { - wait_ms = increase_sleep_time(wait_ms); + increase_sleep_time(gc_th, &wait_ms); mutex_unlock(&sbi->gc_mutex); continue; } if (has_enough_invalid_blocks(sbi)) - wait_ms = decrease_sleep_time(wait_ms); + decrease_sleep_time(gc_th, &wait_ms); else - wait_ms = increase_sleep_time(wait_ms); + increase_sleep_time(gc_th, &wait_ms); - sbi->bg_gc++; + stat_inc_bggc_count(sbi); /* if return value is not zero, no victim was selected */ if (f2fs_gc(sbi)) - wait_ms = GC_THREAD_NOGC_SLEEP_TIME; + wait_ms = gc_th->no_gc_sleep_time; + + /* balancing f2fs's metadata periodically */ + f2fs_balance_fs_bg(sbi); + } while (!kthread_should_stop()); return 0; } @@ -89,23 +92,31 @@ int start_gc_thread(struct f2fs_sb_info *sbi) { struct f2fs_gc_kthread *gc_th; dev_t dev = sbi->sb->s_bdev->bd_dev; + int err = 0; - if (!test_opt(sbi, BG_GC)) - return 0; gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL); - if (!gc_th) - return -ENOMEM; + if (!gc_th) { + err = -ENOMEM; + goto out; + } + + gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME; + gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME; + gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME; + + gc_th->gc_idle = 0; sbi->gc_thread = gc_th; init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi, "f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev)); if (IS_ERR(gc_th->f2fs_gc_task)) { + err = PTR_ERR(gc_th->f2fs_gc_task); kfree(gc_th); sbi->gc_thread = NULL; - return -ENOMEM; } - return 0; +out: + return err; } void stop_gc_thread(struct f2fs_sb_info *sbi) @@ -118,9 +129,17 @@ void stop_gc_thread(struct f2fs_sb_info *sbi) sbi->gc_thread = NULL; } -static int select_gc_type(int gc_type) +static int select_gc_type(struct f2fs_gc_kthread *gc_th, int gc_type) { - return (gc_type == BG_GC) ? GC_CB : GC_GREEDY; + int gc_mode = (gc_type == BG_GC) ? GC_CB : GC_GREEDY; + + if (gc_th && gc_th->gc_idle) { + if (gc_th->gc_idle == 1) + gc_mode = GC_CB; + else if (gc_th->gc_idle == 2) + gc_mode = GC_GREEDY; + } + return gc_mode; } static void select_policy(struct f2fs_sb_info *sbi, int gc_type, @@ -131,12 +150,18 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, if (p->alloc_mode == SSR) { p->gc_mode = GC_GREEDY; p->dirty_segmap = dirty_i->dirty_segmap[type]; + p->max_search = dirty_i->nr_dirty[type]; p->ofs_unit = 1; } else { - p->gc_mode = select_gc_type(gc_type); + p->gc_mode = select_gc_type(sbi->gc_thread, gc_type); p->dirty_segmap = dirty_i->dirty_segmap[DIRTY]; + p->max_search = dirty_i->nr_dirty[DIRTY]; p->ofs_unit = sbi->segs_per_sec; } + + if (p->max_search > sbi->max_victim_search) + p->max_search = sbi->max_victim_search; + p->offset = sbi->last_victim[p->gc_mode]; } @@ -157,7 +182,6 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi, static unsigned int check_bg_victims(struct f2fs_sb_info *sbi) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned int hint = 0; unsigned int secno; /* @@ -165,11 +189,9 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi) * selected by background GC before. * Those segments guarantee they have small valid blocks. */ -next: - secno = find_next_bit(dirty_i->victim_secmap, TOTAL_SECS(sbi), hint++); - if (secno < TOTAL_SECS(sbi)) { + for_each_set_bit(secno, dirty_i->victim_secmap, MAIN_SECS(sbi)) { if (sec_usage_check(sbi, secno)) - goto next; + continue; clear_bit(secno, dirty_i->victim_secmap); return secno * sbi->segs_per_sec; } @@ -196,7 +218,7 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno) u = (vblocks * 100) >> sbi->log_blocks_per_seg; - /* Handle if the system time is changed by user */ + /* Handle if the system time has changed by the user */ if (mtime < sit_i->min_mtime) sit_i->min_mtime = mtime; if (mtime > sit_i->max_mtime) @@ -208,8 +230,8 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno) return UINT_MAX - ((100 * (100 - u) * age) / (100 + u)); } -static unsigned int get_gc_cost(struct f2fs_sb_info *sbi, unsigned int segno, - struct victim_sel_policy *p) +static inline unsigned int get_gc_cost(struct f2fs_sb_info *sbi, + unsigned int segno, struct victim_sel_policy *p) { if (p->alloc_mode == SSR) return get_seg_entry(sbi, segno)->ckpt_valid_blocks; @@ -234,16 +256,16 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); struct victim_sel_policy p; - unsigned int secno; + unsigned int secno, max_cost; int nsearched = 0; + mutex_lock(&dirty_i->seglist_lock); + p.alloc_mode = alloc_mode; select_policy(sbi, gc_type, type, &p); p.min_segno = NULL_SEGNO; - p.min_cost = get_max_cost(sbi, &p); - - mutex_lock(&dirty_i->seglist_lock); + p.min_cost = max_cost = get_max_cost(sbi, &p); if (p.alloc_mode == LFS && gc_type == FG_GC) { p.min_segno = check_bg_victims(sbi); @@ -255,9 +277,8 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, unsigned long cost; unsigned int segno; - segno = find_next_bit(p.dirty_segmap, - TOTAL_SEGS(sbi), p.offset); - if (segno >= TOTAL_SEGS(sbi)) { + segno = find_next_bit(p.dirty_segmap, MAIN_SEGS(sbi), p.offset); + if (segno >= MAIN_SEGS(sbi)) { if (sbi->last_victim[p.gc_mode]) { sbi->last_victim[p.gc_mode] = 0; p.offset = 0; @@ -265,7 +286,11 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, } break; } - p.offset = ((segno / p.ofs_unit) * p.ofs_unit) + p.ofs_unit; + + p.offset = segno + p.ofs_unit; + if (p.ofs_unit > 1) + p.offset -= segno % p.ofs_unit; + secno = GET_SECNO(sbi, segno); if (sec_usage_check(sbi, secno)) @@ -278,18 +303,17 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, if (p.min_cost > cost) { p.min_segno = segno; p.min_cost = cost; - } - - if (cost == get_max_cost(sbi, &p)) + } else if (unlikely(cost == max_cost)) { continue; + } - if (nsearched++ >= MAX_VICTIM_SEARCH) { + if (nsearched++ >= p.max_search) { sbi->last_victim[p.gc_mode] = segno; break; } } -got_it: if (p.min_segno != NULL_SEGNO) { +got_it: if (p.alloc_mode == LFS) { secno = GET_SECNO(sbi, p.min_segno); if (gc_type == FG_GC) @@ -312,48 +336,39 @@ static const struct victim_selection default_v_ops = { .get_victim = get_victim_by_default, }; -static struct inode *find_gc_inode(nid_t ino, struct list_head *ilist) +static struct inode *find_gc_inode(struct gc_inode_list *gc_list, nid_t ino) { - struct list_head *this; struct inode_entry *ie; - list_for_each(this, ilist) { - ie = list_entry(this, struct inode_entry, list); - if (ie->inode->i_ino == ino) - return ie->inode; - } + ie = radix_tree_lookup(&gc_list->iroot, ino); + if (ie) + return ie->inode; return NULL; } -static void add_gc_inode(struct inode *inode, struct list_head *ilist) +static void add_gc_inode(struct gc_inode_list *gc_list, struct inode *inode) { - struct list_head *this; - struct inode_entry *new_ie, *ie; + struct inode_entry *new_ie; - list_for_each(this, ilist) { - ie = list_entry(this, struct inode_entry, list); - if (ie->inode == inode) { - iput(inode); - return; - } - } -repeat: - new_ie = kmem_cache_alloc(winode_slab, GFP_NOFS); - if (!new_ie) { - cond_resched(); - goto repeat; + if (inode == find_gc_inode(gc_list, inode->i_ino)) { + iput(inode); + return; } + new_ie = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); new_ie->inode = inode; - list_add_tail(&new_ie->list, ilist); + + f2fs_radix_tree_insert(&gc_list->iroot, inode->i_ino, new_ie); + list_add_tail(&new_ie->list, &gc_list->ilist); } -static void put_gc_inode(struct list_head *ilist) +static void put_gc_inode(struct gc_inode_list *gc_list) { struct inode_entry *ie, *next_ie; - list_for_each_entry_safe(ie, next_ie, ilist, list) { + list_for_each_entry_safe(ie, next_ie, &gc_list->ilist, list) { + radix_tree_delete(&gc_list->iroot, ie->inode->i_ino); iput(ie->inode); list_del(&ie->list); - kmem_cache_free(winode_slab, ie); + kmem_cache_free(inode_entry_slab, ie); } } @@ -405,17 +420,22 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, if (IS_ERR(node_page)) continue; + /* block may become invalid during get_node_page */ + if (check_valid_map(sbi, segno, off) == 0) { + f2fs_put_page(node_page, 1); + continue; + } + /* set page dirty and write it */ if (gc_type == FG_GC) { - f2fs_submit_bio(sbi, NODE, true); - wait_on_page_writeback(node_page); + f2fs_wait_on_page_writeback(node_page, NODE); set_page_dirty(node_page); } else { if (!PageWriteback(node_page)) set_page_dirty(node_page); } f2fs_put_page(node_page, 1); - stat_inc_node_blk_count(sbi, 1); + stat_inc_node_blk_count(sbi, 1, gc_type); } if (initial) { @@ -447,7 +467,7 @@ static void gc_node_segment(struct f2fs_sb_info *sbi, * as indirect or double indirect node blocks, are given, it must be a caller's * bug. */ -block_t start_bidx_of_node(unsigned int node_ofs) +block_t start_bidx_of_node(unsigned int node_ofs, struct f2fs_inode_info *fi) { unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4; unsigned int bidx; @@ -464,7 +484,7 @@ block_t start_bidx_of_node(unsigned int node_ofs) int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); bidx = node_ofs - 5 - dec; } - return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE; + return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE(fi); } static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, @@ -500,26 +520,23 @@ static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, static void move_data_page(struct inode *inode, struct page *page, int gc_type) { + struct f2fs_io_info fio = { + .type = DATA, + .rw = WRITE_SYNC, + }; + if (gc_type == BG_GC) { if (PageWriteback(page)) goto out; set_page_dirty(page); set_cold_data(page); } else { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - - if (PageWriteback(page)) { - f2fs_submit_bio(sbi, DATA, true); - wait_on_page_writeback(page); - } + f2fs_wait_on_page_writeback(page, DATA); - if (clear_page_dirty_for_io(page) && - S_ISDIR(inode->i_mode)) { - dec_page_count(sbi, F2FS_DIRTY_DENTS); - inode_dec_dirty_dents(inode); - } + if (clear_page_dirty_for_io(page)) + inode_dec_dirty_pages(inode); set_cold_data(page); - do_write_data_page(page); + do_write_data_page(page, &fio); clear_cold_data(page); } out: @@ -534,7 +551,7 @@ static void move_data_page(struct inode *inode, struct page *page, int gc_type) * the victim data block is ignored. */ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, - struct list_head *ilist, unsigned int segno, int gc_type) + struct gc_inode_list *gc_list, unsigned int segno, int gc_type) { struct super_block *sb = sbi->sb; struct f2fs_summary *entry; @@ -575,42 +592,45 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, continue; } - start_bidx = start_bidx_of_node(nofs); ofs_in_node = le16_to_cpu(entry->ofs_in_node); if (phase == 2) { inode = f2fs_iget(sb, dni.ino); - if (IS_ERR(inode)) + if (IS_ERR(inode) || is_bad_inode(inode)) continue; + start_bidx = start_bidx_of_node(nofs, F2FS_I(inode)); + data_page = find_data_page(inode, start_bidx + ofs_in_node, false); - if (IS_ERR(data_page)) - goto next_iput; + if (IS_ERR(data_page)) { + iput(inode); + continue; + } f2fs_put_page(data_page, 0); - add_gc_inode(inode, ilist); - } else { - inode = find_gc_inode(dni.ino, ilist); - if (inode) { - data_page = get_lock_data_page(inode, + add_gc_inode(gc_list, inode); + continue; + } + + /* phase 3 */ + inode = find_gc_inode(gc_list, dni.ino); + if (inode) { + start_bidx = start_bidx_of_node(nofs, F2FS_I(inode)); + data_page = get_lock_data_page(inode, start_bidx + ofs_in_node); - if (IS_ERR(data_page)) - continue; - move_data_page(inode, data_page, gc_type); - stat_inc_data_blk_count(sbi, 1); - } + if (IS_ERR(data_page)) + continue; + move_data_page(inode, data_page, gc_type); + stat_inc_data_blk_count(sbi, 1, gc_type); } - continue; -next_iput: - iput(inode); } if (++phase < 4) goto next_step; if (gc_type == FG_GC) { - f2fs_submit_bio(sbi, DATA, true); + f2fs_submit_merged_bio(sbi, DATA, WRITE); /* * In the case of FG_GC, it'd be better to reclaim this victim @@ -624,18 +644,20 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, - int gc_type, int type) + int gc_type) { struct sit_info *sit_i = SIT_I(sbi); int ret; + mutex_lock(&sit_i->sentry_lock); - ret = DIRTY_I(sbi)->v_ops->get_victim(sbi, victim, gc_type, type, LFS); + ret = DIRTY_I(sbi)->v_ops->get_victim(sbi, victim, gc_type, + NO_CHECK_TYPE, LFS); mutex_unlock(&sit_i->sentry_lock); return ret; } static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, - struct list_head *ilist, int gc_type) + struct gc_inode_list *gc_list, int gc_type) { struct page *sum_page; struct f2fs_summary_block *sum; @@ -643,8 +665,6 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, /* read segment summary of victim */ sum_page = get_sum_page(sbi, segno); - if (IS_ERR(sum_page)) - return; blk_start_plug(&plug); @@ -655,12 +675,12 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, gc_node_segment(sbi, sum->entries, segno, gc_type); break; case SUM_TYPE_DATA: - gc_data_segment(sbi, sum->entries, ilist, segno, gc_type); + gc_data_segment(sbi, sum->entries, gc_list, segno, gc_type); break; } blk_finish_plug(&plug); - stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer))); + stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer)), gc_type); stat_inc_call_count(sbi->stat_info); f2fs_put_page(sum_page, 1); @@ -668,28 +688,39 @@ static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, int f2fs_gc(struct f2fs_sb_info *sbi) { - struct list_head ilist; unsigned int segno, i; int gc_type = BG_GC; int nfree = 0; int ret = -1; + struct cp_control cpc; + struct gc_inode_list gc_list = { + .ilist = LIST_HEAD_INIT(gc_list.ilist), + .iroot = RADIX_TREE_INIT(GFP_NOFS), + }; - INIT_LIST_HEAD(&ilist); + cpc.reason = __get_cp_reason(sbi); gc_more: - if (!(sbi->sb->s_flags & MS_ACTIVE)) + if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) + goto stop; + if (unlikely(f2fs_cp_error(sbi))) goto stop; if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) { gc_type = FG_GC; - write_checkpoint(sbi, false); + write_checkpoint(sbi, &cpc); } - if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) + if (!__get_victim(sbi, &segno, gc_type)) goto stop; ret = 0; + /* readahead multi ssa blocks those have contiguous address */ + if (sbi->segs_per_sec > 1) + ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec, + META_SSA); + for (i = 0; i < sbi->segs_per_sec; i++) - do_garbage_collect(sbi, segno + i, &ilist, gc_type); + do_garbage_collect(sbi, segno + i, &gc_list, gc_type); if (gc_type == FG_GC) { sbi->cur_victim_sec = NULL_SEGNO; @@ -701,11 +732,11 @@ int f2fs_gc(struct f2fs_sb_info *sbi) goto gc_more; if (gc_type == FG_GC) - write_checkpoint(sbi, false); + write_checkpoint(sbi, &cpc); stop: mutex_unlock(&sbi->gc_mutex); - put_gc_inode(&ilist); + put_gc_inode(&gc_list); return ret; } @@ -713,17 +744,3 @@ void build_gc_manager(struct f2fs_sb_info *sbi) { DIRTY_I(sbi)->v_ops = &default_v_ops; } - -int __init create_gc_caches(void) -{ - winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", - sizeof(struct inode_entry), NULL); - if (!winode_slab) - return -ENOMEM; - return 0; -} - -void destroy_gc_caches(void) -{ - kmem_cache_destroy(winode_slab); -} diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index 2c6a6bd083224..b4a65be9f7d3f 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h @@ -13,23 +13,31 @@ * whether IO subsystem is idle * or not */ -#define GC_THREAD_MIN_SLEEP_TIME 30000 /* milliseconds */ -#define GC_THREAD_MAX_SLEEP_TIME 60000 -#define GC_THREAD_NOGC_SLEEP_TIME 300000 /* wait 5 min */ +#define DEF_GC_THREAD_MIN_SLEEP_TIME 30000 /* milliseconds */ +#define DEF_GC_THREAD_MAX_SLEEP_TIME 60000 +#define DEF_GC_THREAD_NOGC_SLEEP_TIME 300000 /* wait 5 min */ #define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */ #define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ /* Search max. number of dirty segments to select a victim segment */ -#define MAX_VICTIM_SEARCH 20 +#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */ struct f2fs_gc_kthread { struct task_struct *f2fs_gc_task; wait_queue_head_t gc_wait_queue_head; + + /* for gc sleep time */ + unsigned int min_sleep_time; + unsigned int max_sleep_time; + unsigned int no_gc_sleep_time; + + /* for changing gc mode */ + unsigned int gc_idle; }; -struct inode_entry { - struct list_head list; - struct inode *inode; +struct gc_inode_list { + struct list_head ilist; + struct radix_tree_root iroot; }; /* @@ -56,26 +64,26 @@ static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi) return (long)(reclaimable_user_blocks * LIMIT_FREE_BLOCK) / 100; } -static inline long increase_sleep_time(long wait) +static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th, + long *wait) { - if (wait == GC_THREAD_NOGC_SLEEP_TIME) - return wait; + if (*wait == gc_th->no_gc_sleep_time) + return; - wait += GC_THREAD_MIN_SLEEP_TIME; - if (wait > GC_THREAD_MAX_SLEEP_TIME) - wait = GC_THREAD_MAX_SLEEP_TIME; - return wait; + *wait += gc_th->min_sleep_time; + if (*wait > gc_th->max_sleep_time) + *wait = gc_th->max_sleep_time; } -static inline long decrease_sleep_time(long wait) +static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th, + long *wait) { - if (wait == GC_THREAD_NOGC_SLEEP_TIME) - wait = GC_THREAD_MAX_SLEEP_TIME; + if (*wait == gc_th->no_gc_sleep_time) + *wait = gc_th->max_sleep_time; - wait -= GC_THREAD_MIN_SLEEP_TIME; - if (wait <= GC_THREAD_MIN_SLEEP_TIME) - wait = GC_THREAD_MIN_SLEEP_TIME; - return wait; + *wait -= gc_th->min_sleep_time; + if (*wait <= gc_th->min_sleep_time) + *wait = gc_th->min_sleep_time; } static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) @@ -83,7 +91,7 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) block_t invalid_user_blocks = sbi->user_block_count - written_block_count(sbi); /* - * Background GC is triggered with the following condition. + * Background GC is triggered with the following conditions. * 1. There are a number of invalid blocks. * 2. There is not enough free space. */ diff --git a/fs/f2fs/hash.c b/fs/f2fs/hash.c index 6eb8d269b53b6..a844fcfb9a8dc 100644 --- a/fs/f2fs/hash.c +++ b/fs/f2fs/hash.c @@ -42,7 +42,8 @@ static void TEA_transform(unsigned int buf[4], unsigned int const in[]) buf[1] += b1; } -static void str2hashbuf(const char *msg, size_t len, unsigned int *buf, int num) +static void str2hashbuf(const unsigned char *msg, size_t len, + unsigned int *buf, int num) { unsigned pad, val; int i; @@ -69,12 +70,14 @@ static void str2hashbuf(const char *msg, size_t len, unsigned int *buf, int num) *buf++ = pad; } -f2fs_hash_t f2fs_dentry_hash(const char *name, size_t len) +f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info) { __u32 hash; f2fs_hash_t f2fs_hash; - const char *p; + const unsigned char *p; __u32 in[8], buf[4]; + const unsigned char *name = name_info->name; + size_t len = name_info->len; if ((len <= 2) && (name[0] == '.') && (name[1] == '.' || name[1] == '\0')) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c new file mode 100644 index 0000000000000..7885c71e50544 --- /dev/null +++ b/fs/f2fs/inline.c @@ -0,0 +1,536 @@ +/* + * fs/f2fs/inline.c + * Copyright (c) 2013, Intel Corporation + * Authors: Huajun Li + * Haicheng Li + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include "f2fs.h" + +bool f2fs_may_inline(struct inode *inode) +{ + if (!test_opt(F2FS_I_SB(inode), INLINE_DATA)) + return false; + + if (f2fs_is_atomic_file(inode)) + return false; + + if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) + return false; + + if (i_size_read(inode) > MAX_INLINE_DATA) + return false; + + return true; +} + +void read_inline_data(struct page *page, struct page *ipage) +{ + void *src_addr, *dst_addr; + + if (PageUptodate(page)) + return; + + f2fs_bug_on(F2FS_P_SB(page), page->index); + + zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); + + /* Copy the whole inline data block */ + src_addr = inline_data_addr(ipage); + dst_addr = kmap_atomic(page); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + flush_dcache_page(page); + kunmap_atomic(dst_addr); + SetPageUptodate(page); +} + +bool truncate_inline_inode(struct page *ipage, u64 from) +{ + void *addr; + + if (from >= MAX_INLINE_DATA) + return false; + + addr = inline_data_addr(ipage); + + f2fs_wait_on_page_writeback(ipage, NODE); + memset(addr + from, 0, MAX_INLINE_DATA - from); + + return true; +} + +int f2fs_read_inline_data(struct inode *inode, struct page *page) +{ + struct page *ipage; + + ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); + if (IS_ERR(ipage)) { + unlock_page(page); + return PTR_ERR(ipage); + } + + if (!f2fs_has_inline_data(inode)) { + f2fs_put_page(ipage, 1); + return -EAGAIN; + } + + if (page->index) + zero_user_segment(page, 0, PAGE_CACHE_SIZE); + else + read_inline_data(page, ipage); + + SetPageUptodate(page); + f2fs_put_page(ipage, 1); + unlock_page(page); + return 0; +} + +int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) +{ + void *src_addr, *dst_addr; + struct f2fs_io_info fio = { + .type = DATA, + .rw = WRITE_SYNC | REQ_PRIO, + }; + int dirty, err; + + f2fs_bug_on(F2FS_I_SB(dn->inode), page->index); + + if (!f2fs_exist_data(dn->inode)) + goto clear_out; + + err = f2fs_reserve_block(dn, 0); + if (err) + return err; + + f2fs_wait_on_page_writeback(page, DATA); + + if (PageUptodate(page)) + goto no_update; + + zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); + + /* Copy the whole inline data block */ + src_addr = inline_data_addr(dn->inode_page); + dst_addr = kmap_atomic(page); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + flush_dcache_page(page); + kunmap_atomic(dst_addr); + SetPageUptodate(page); +no_update: + /* clear dirty state */ + dirty = clear_page_dirty_for_io(page); + + /* write data page to try to make data consistent */ + set_page_writeback(page); + fio.blk_addr = dn->data_blkaddr; + write_data_page(page, dn, &fio); + set_data_blkaddr(dn); + f2fs_update_extent_cache(dn); + f2fs_wait_on_page_writeback(page, DATA); + if (dirty) + inode_dec_dirty_pages(dn->inode); + + /* this converted inline_data should be recovered. */ + set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE); + + /* clear inline data and flag after data writeback */ + truncate_inline_inode(dn->inode_page, 0); +clear_out: + stat_dec_inline_inode(dn->inode); + f2fs_clear_inline_inode(dn->inode); + sync_inode_page(dn); + f2fs_put_dnode(dn); + return 0; +} + +int f2fs_convert_inline_inode(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct dnode_of_data dn; + struct page *ipage, *page; + int err = 0; + + page = grab_cache_page(inode->i_mapping, 0); + if (!page) + return -ENOMEM; + + f2fs_lock_op(sbi); + + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + err = PTR_ERR(ipage); + goto out; + } + + set_new_dnode(&dn, inode, ipage, ipage, 0); + + if (f2fs_has_inline_data(inode)) + err = f2fs_convert_inline_page(&dn, page); + + f2fs_put_dnode(&dn); +out: + f2fs_unlock_op(sbi); + + f2fs_put_page(page, 1); + return err; +} + +int f2fs_write_inline_data(struct inode *inode, struct page *page) +{ + void *src_addr, *dst_addr; + struct dnode_of_data dn; + int err; + + set_new_dnode(&dn, inode, NULL, NULL, 0); + err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); + if (err) + return err; + + if (!f2fs_has_inline_data(inode)) { + f2fs_put_dnode(&dn); + return -EAGAIN; + } + + f2fs_bug_on(F2FS_I_SB(inode), page->index); + + f2fs_wait_on_page_writeback(dn.inode_page, NODE); + src_addr = kmap_atomic(page); + dst_addr = inline_data_addr(dn.inode_page); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + kunmap_atomic(src_addr); + + set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); + set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); + + sync_inode_page(&dn); + f2fs_put_dnode(&dn); + return 0; +} + +bool recover_inline_data(struct inode *inode, struct page *npage) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_inode *ri = NULL; + void *src_addr, *dst_addr; + struct page *ipage; + + /* + * The inline_data recovery policy is as follows. + * [prev.] [next] of inline_data flag + * o o -> recover inline_data + * o x -> remove inline_data, and then recover data blocks + * x o -> remove inline_data, and then recover inline_data + * x x -> recover data blocks + */ + if (IS_INODE(npage)) + ri = F2FS_INODE(npage); + + if (f2fs_has_inline_data(inode) && + ri && (ri->i_inline & F2FS_INLINE_DATA)) { +process_inline: + ipage = get_node_page(sbi, inode->i_ino); + f2fs_bug_on(sbi, IS_ERR(ipage)); + + f2fs_wait_on_page_writeback(ipage, NODE); + + src_addr = inline_data_addr(npage); + dst_addr = inline_data_addr(ipage); + memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + + set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); + set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); + + update_inode(inode, ipage); + f2fs_put_page(ipage, 1); + return true; + } + + if (f2fs_has_inline_data(inode)) { + ipage = get_node_page(sbi, inode->i_ino); + f2fs_bug_on(sbi, IS_ERR(ipage)); + truncate_inline_inode(ipage, 0); + f2fs_clear_inline_inode(inode); + update_inode(inode, ipage); + f2fs_put_page(ipage, 1); + } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { + truncate_blocks(inode, 0, false); + goto process_inline; + } + return false; +} + +struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, + struct qstr *name, struct page **res_page) +{ + struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct f2fs_inline_dentry *inline_dentry; + struct f2fs_dir_entry *de; + struct f2fs_dentry_ptr d; + struct page *ipage; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return NULL; + + inline_dentry = inline_data_addr(ipage); + + make_dentry_ptr(&d, (void *)inline_dentry, 2); + de = find_target_dentry(name, NULL, &d); + + unlock_page(ipage); + if (de) + *res_page = ipage; + else + f2fs_put_page(ipage, 0); + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs has occurred. + */ + f2fs_bug_on(sbi, d.max < 0); + return de; +} + +struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir, + struct page **p) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + struct f2fs_dir_entry *de; + struct f2fs_inline_dentry *dentry_blk; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return NULL; + + dentry_blk = inline_data_addr(ipage); + de = &dentry_blk->dentry[1]; + *p = ipage; + unlock_page(ipage); + return de; +} + +int make_empty_inline_dir(struct inode *inode, struct inode *parent, + struct page *ipage) +{ + struct f2fs_inline_dentry *dentry_blk; + struct f2fs_dentry_ptr d; + + dentry_blk = inline_data_addr(ipage); + + make_dentry_ptr(&d, (void *)dentry_blk, 2); + do_make_empty_dir(inode, parent, &d); + + set_page_dirty(ipage); + + /* update i_size to MAX_INLINE_DATA */ + if (i_size_read(inode) < MAX_INLINE_DATA) { + i_size_write(inode, MAX_INLINE_DATA); + set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); + } + return 0; +} + +static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, + struct f2fs_inline_dentry *inline_dentry) +{ + struct page *page; + struct dnode_of_data dn; + struct f2fs_dentry_block *dentry_blk; + int err; + + page = grab_cache_page(dir->i_mapping, 0); + if (!page) + return -ENOMEM; + + set_new_dnode(&dn, dir, ipage, NULL, 0); + err = f2fs_reserve_block(&dn, 0); + if (err) + goto out; + + f2fs_wait_on_page_writeback(page, DATA); + zero_user_segment(page, 0, PAGE_CACHE_SIZE); + + dentry_blk = kmap_atomic(page); + + /* copy data from inline dentry block to new dentry block */ + memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, + INLINE_DENTRY_BITMAP_SIZE); + memcpy(dentry_blk->dentry, inline_dentry->dentry, + sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY); + memcpy(dentry_blk->filename, inline_dentry->filename, + NR_INLINE_DENTRY * F2FS_SLOT_LEN); + + kunmap_atomic(dentry_blk); + SetPageUptodate(page); + set_page_dirty(page); + + /* clear inline dir and flag after data writeback */ + truncate_inline_inode(ipage, 0); + + stat_dec_inline_dir(dir); + clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); + + if (i_size_read(dir) < PAGE_CACHE_SIZE) { + i_size_write(dir, PAGE_CACHE_SIZE); + set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); + } + + sync_inode_page(&dn); +out: + f2fs_put_page(page, 1); + return err; +} + +int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, + struct inode *inode, nid_t ino, umode_t mode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + unsigned int bit_pos; + f2fs_hash_t name_hash; + size_t namelen = name->len; + struct f2fs_inline_dentry *dentry_blk = NULL; + struct f2fs_dentry_ptr d; + int slots = GET_DENTRY_SLOTS(namelen); + struct page *page = NULL; + int err = 0; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return PTR_ERR(ipage); + + dentry_blk = inline_data_addr(ipage); + bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, + slots, NR_INLINE_DENTRY); + if (bit_pos >= NR_INLINE_DENTRY) { + err = f2fs_convert_inline_dir(dir, ipage, dentry_blk); + if (!err) + err = -EAGAIN; + goto out; + } + + if (inode) { + down_write(&F2FS_I(inode)->i_sem); + page = init_inode_metadata(inode, dir, name, ipage); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto fail; + } + } + + f2fs_wait_on_page_writeback(ipage, NODE); + + name_hash = f2fs_dentry_hash(name); + make_dentry_ptr(&d, (void *)dentry_blk, 2); + f2fs_update_dentry(ino, mode, &d, name, name_hash, bit_pos); + + set_page_dirty(ipage); + + /* we don't need to mark_inode_dirty now */ + if (inode) { + F2FS_I(inode)->i_pino = dir->i_ino; + update_inode(inode, page); + f2fs_put_page(page, 1); + } + + update_parent_metadata(dir, inode, 0); +fail: + if (inode) + up_write(&F2FS_I(inode)->i_sem); + + if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { + update_inode(dir, ipage); + clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); + } +out: + f2fs_put_page(ipage, 1); + return err; +} + +void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, + struct inode *dir, struct inode *inode) +{ + struct f2fs_inline_dentry *inline_dentry; + int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); + unsigned int bit_pos; + int i; + + lock_page(page); + f2fs_wait_on_page_writeback(page, NODE); + + inline_dentry = inline_data_addr(page); + bit_pos = dentry - inline_dentry->dentry; + for (i = 0; i < slots; i++) + test_and_clear_bit_le(bit_pos + i, + &inline_dentry->dentry_bitmap); + + set_page_dirty(page); + + dir->i_ctime = dir->i_mtime = CURRENT_TIME; + + if (inode) + f2fs_drop_nlink(dir, inode, page); + + f2fs_put_page(page, 1); +} + +bool f2fs_empty_inline_dir(struct inode *dir) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + unsigned int bit_pos = 2; + struct f2fs_inline_dentry *dentry_blk; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return false; + + dentry_blk = inline_data_addr(ipage); + bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, + NR_INLINE_DENTRY, + bit_pos); + + f2fs_put_page(ipage, 1); + + if (bit_pos < NR_INLINE_DENTRY) + return false; + + return true; +} + +int f2fs_read_inline_dir(struct file *file, void *dirent, filldir_t filldir) +{ + unsigned long pos = file->f_pos; + unsigned int bit_pos = 0; + struct inode *inode = file_inode(file); + struct f2fs_inline_dentry *inline_dentry = NULL; + struct page *ipage = NULL; + struct f2fs_dentry_ptr d; + + if (pos >= NR_INLINE_DENTRY) + return 0; + + bit_pos = (pos % NR_INLINE_DENTRY); + + ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); + if (IS_ERR(ipage)) + return PTR_ERR(ipage); + + inline_dentry = inline_data_addr(ipage); + + make_dentry_ptr(&d, (void *)inline_dentry, 2); + + if (!f2fs_fill_dentries(file, dirent, filldir, &d, 0, bit_pos)) + file->f_pos = NR_INLINE_DENTRY; + + f2fs_put_page(ipage, 1); + return 0; +} diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 91ac7f9d88eea..42d2bf2025660 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -37,18 +37,75 @@ void f2fs_set_inode_flags(struct inode *inode) inode->i_flags |= S_DIRSYNC; } +static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) +{ + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || + S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { + if (ri->i_addr[0]) + inode->i_rdev = + old_decode_dev(le32_to_cpu(ri->i_addr[0])); + else + inode->i_rdev = + new_decode_dev(le32_to_cpu(ri->i_addr[1])); + } +} + +static bool __written_first_block(struct f2fs_inode *ri) +{ + block_t addr = le32_to_cpu(ri->i_addr[0]); + + if (addr != NEW_ADDR && addr != NULL_ADDR) + return true; + return false; +} + +static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) +{ + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { + if (old_valid_dev(inode->i_rdev)) { + ri->i_addr[0] = + cpu_to_le32(old_encode_dev(inode->i_rdev)); + ri->i_addr[1] = 0; + } else { + ri->i_addr[0] = 0; + ri->i_addr[1] = + cpu_to_le32(new_encode_dev(inode->i_rdev)); + ri->i_addr[2] = 0; + } + } +} + +static void __recover_inline_status(struct inode *inode, struct page *ipage) +{ + void *inline_data = inline_data_addr(ipage); + __le32 *start = inline_data; + __le32 *end = start + MAX_INLINE_DATA / sizeof(__le32); + + while (start < end) { + if (*start++) { + f2fs_wait_on_page_writeback(ipage, NODE); + + set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); + set_raw_inline(F2FS_I(inode), F2FS_INODE(ipage)); + set_page_dirty(ipage); + return; + } + } + return; +} + static int do_read_inode(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); struct page *node_page; - struct f2fs_node *rn; struct f2fs_inode *ri; /* Check if ino is within scope */ if (check_nid_range(sbi, inode->i_ino)) { f2fs_msg(inode->i_sb, KERN_ERR, "bad inode number: %lu", (unsigned long) inode->i_ino); + WARN_ON(1); return -EINVAL; } @@ -56,8 +113,7 @@ static int do_read_inode(struct inode *inode) if (IS_ERR(node_page)) return PTR_ERR(node_page); - rn = page_address(node_page); - ri = &(rn->i); + ri = F2FS_INODE(node_page); inode->i_mode = le16_to_cpu(ri->i_mode); i_uid_write(inode, le32_to_cpu(ri->i_uid)); @@ -73,10 +129,6 @@ static int do_read_inode(struct inode *inode) inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); inode->i_generation = le32_to_cpu(ri->i_generation); - if (ri->i_addr[0]) - inode->i_rdev = old_decode_dev(le32_to_cpu(ri->i_addr[0])); - else - inode->i_rdev = new_decode_dev(le32_to_cpu(ri->i_addr[1])); fi->i_current_depth = le32_to_cpu(ri->i_current_depth); fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); @@ -84,8 +136,27 @@ static int do_read_inode(struct inode *inode) fi->flags = 0; fi->i_advise = ri->i_advise; fi->i_pino = le32_to_cpu(ri->i_pino); - get_extent_info(&fi->ext, ri->i_ext); + fi->i_dir_level = ri->i_dir_level; + + f2fs_init_extent_cache(inode, &ri->i_ext); + + get_inline_info(fi, ri); + + /* check data exist */ + if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) + __recover_inline_status(inode, node_page); + + /* get rdev by using inline_info */ + __get_inode_rdev(inode, ri); + + if (__written_first_block(ri)) + set_inode_flag(F2FS_I(inode), FI_FIRST_BLOCK_WRITTEN); + f2fs_put_page(node_page, 1); + + stat_inc_inline_inode(inode); + stat_inc_inline_dir(inode); + return 0; } @@ -109,12 +180,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) ret = do_read_inode(inode); if (ret) goto bad_inode; - - if (!sbi->por_doing && inode->i_nlink == 0) { - ret = -ENOENT; - goto bad_inode; - } - make_now: if (ino == F2FS_NODE_INO(sbi)) { inode->i_mapping->a_ops = &f2fs_node_aops; @@ -130,8 +195,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER_MOVABLE | - __GFP_ZERO); + mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &f2fs_symlink_inode_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; @@ -155,13 +219,11 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) void update_inode(struct inode *inode, struct page *node_page) { - struct f2fs_node *rn; struct f2fs_inode *ri; - wait_on_page_writeback(node_page); + f2fs_wait_on_page_writeback(node_page, NODE); - rn = page_address(node_page); - ri = &(rn->i); + ri = F2FS_INODE(node_page); ri->i_mode = cpu_to_le16(inode->i_mode); ri->i_advise = F2FS_I(inode)->i_advise; @@ -170,7 +232,12 @@ void update_inode(struct inode *inode, struct page *node_page) ri->i_links = cpu_to_le32(inode->i_nlink); ri->i_size = cpu_to_le64(i_size_read(inode)); ri->i_blocks = cpu_to_le64(inode->i_blocks); + + read_lock(&F2FS_I(inode)->ext_lock); set_raw_extent(&F2FS_I(inode)->ext, &ri->i_ext); + read_unlock(&F2FS_I(inode)->ext_lock); + + set_raw_inline(F2FS_I(inode), ri); ri->i_atime = cpu_to_le64(inode->i_atime.tv_sec); ri->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); @@ -183,58 +250,58 @@ void update_inode(struct inode *inode, struct page *node_page) ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); ri->i_generation = cpu_to_le32(inode->i_generation); + ri->i_dir_level = F2FS_I(inode)->i_dir_level; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { - if (old_valid_dev(inode->i_rdev)) { - ri->i_addr[0] = - cpu_to_le32(old_encode_dev(inode->i_rdev)); - ri->i_addr[1] = 0; - } else { - ri->i_addr[0] = 0; - ri->i_addr[1] = - cpu_to_le32(new_encode_dev(inode->i_rdev)); - ri->i_addr[2] = 0; - } - } - + __set_inode_rdev(inode, ri); set_cold_node(inode, node_page); set_page_dirty(node_page); + + clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE); } -int update_inode_page(struct inode *inode) +void update_inode_page(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct page *node_page; - +retry: node_page = get_node_page(sbi, inode->i_ino); - if (IS_ERR(node_page)) - return PTR_ERR(node_page); - + if (IS_ERR(node_page)) { + int err = PTR_ERR(node_page); + if (err == -ENOMEM) { + cond_resched(); + goto retry; + } else if (err != -ENOENT) { + f2fs_stop_checkpoint(sbi); + } + return; + } update_inode(inode, node_page); f2fs_put_page(node_page, 1); - return 0; } int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - int ret, ilock; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); if (inode->i_ino == F2FS_NODE_INO(sbi) || inode->i_ino == F2FS_META_INO(sbi)) return 0; - if (wbc) - f2fs_balance_fs(sbi); + if (!is_inode_flag_set(F2FS_I(inode), FI_DIRTY_INODE)) + return 0; /* * We need to lock here to prevent from producing dirty node pages * during the urgent cleaning time when runing out of free sections. */ - ilock = mutex_lock_op(sbi); - ret = update_inode_page(inode); - mutex_unlock_op(sbi, ilock); - return ret; + f2fs_lock_op(sbi); + update_inode_page(inode); + f2fs_unlock_op(sbi); + + if (wbc) + f2fs_balance_fs(sbi); + + return 0; } /* @@ -242,17 +309,21 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) */ void f2fs_evict_inode(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - int ilock; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + nid_t xnid = F2FS_I(inode)->i_xattr_nid; + + /* some remained atomic pages should discarded */ + if (f2fs_is_atomic_file(inode)) + commit_inmem_pages(inode, true); trace_f2fs_evict_inode(inode); truncate_inode_pages(&inode->i_data, 0); if (inode->i_ino == F2FS_NODE_INO(sbi) || inode->i_ino == F2FS_META_INO(sbi)) - goto no_delete; + goto out_clear; - BUG_ON(atomic_read(&F2FS_I(inode)->dirty_dents)); + f2fs_bug_on(sbi, get_dirty_pages(inode)); remove_dirty_dir_inode(inode); if (inode->i_nlink || is_bad_inode(inode)) @@ -265,11 +336,51 @@ void f2fs_evict_inode(struct inode *inode) if (F2FS_HAS_BLOCKS(inode)) f2fs_truncate(inode); - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); remove_inode_page(inode); - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); sb_end_intwrite(inode->i_sb); no_delete: + stat_dec_inline_dir(inode); + stat_dec_inline_inode(inode); + + /* update extent info in inode */ + if (inode->i_nlink) + f2fs_preserve_extent_tree(inode); + f2fs_destroy_extent_tree(inode); + + invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); + if (xnid) + invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); + if (is_inode_flag_set(F2FS_I(inode), FI_APPEND_WRITE)) + add_dirty_inode(sbi, inode->i_ino, APPEND_INO); + if (is_inode_flag_set(F2FS_I(inode), FI_UPDATE_WRITE)) + add_dirty_inode(sbi, inode->i_ino, UPDATE_INO); +out_clear: clear_inode(inode); } + +/* caller should call f2fs_lock_op() */ +void handle_failed_inode(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + + clear_nlink(inode); + make_bad_inode(inode); + unlock_new_inode(inode); + + i_size_write(inode, 0); + if (F2FS_HAS_BLOCKS(inode)) + f2fs_truncate(inode); + + remove_inode_page(inode); + + clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); + clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); + alloc_nid_failed(sbi, inode->i_ino); + f2fs_unlock_op(sbi); + + /* iput will drop the inode object */ + iput(inode); +} diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 47abc9722b17a..34a094fb6869d 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "f2fs.h" #include "node.h" @@ -22,37 +24,27 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) { - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); nid_t ino; struct inode *inode; bool nid_free = false; - int err, ilock; + int err; - inode = new_inode(sb); + inode = new_inode(dir->i_sb); if (!inode) return ERR_PTR(-ENOMEM); - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); if (!alloc_nid(sbi, &ino)) { - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); err = -ENOSPC; goto fail; } - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); - inode->i_uid = current_fsuid(); - - if (dir->i_mode & S_ISGID) { - inode->i_gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; - } else { - inode->i_gid = current_fsgid(); - } + inode_init_owner(inode, dir, mode); inode->i_ino = ino; - inode->i_mode = mode; inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_generation = sbi->s_next_generation++; @@ -63,6 +55,12 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) nid_free = true; goto out; } + + if (f2fs_may_inline(inode)) + set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); + if (test_opt(sbi, INLINE_DENTRY) && S_ISDIR(inode->i_mode)) + set_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); + trace_f2fs_new_inode(inode, 0); mark_inode_dirty(inode); return inode; @@ -83,21 +81,11 @@ static int is_multimedia_file(const unsigned char *s, const char *sub) { size_t slen = strlen(s); size_t sublen = strlen(sub); - int ret; if (sublen > slen) return 0; - ret = memcmp(s + slen - sublen, sub, sublen); - if (ret) { /* compare upper case */ - int i; - char upper_sub[8]; - for (i = 0; i < sublen && i < sizeof(upper_sub); i++) - upper_sub[i] = toupper(sub[i]); - return !memcmp(s + slen - sublen, upper_sub, sublen); - } - - return !ret; + return !strncasecmp(s + slen - sublen, sub, sublen); } /* @@ -112,7 +100,7 @@ static inline void set_cold_files(struct f2fs_sb_info *sbi, struct inode *inode, int count = le32_to_cpu(sbi->raw_super->extension_count); for (i = 0; i < count; i++) { if (is_multimedia_file(name, extlist[i])) { - set_cold_file(inode); + file_set_cold(inode); break; } } @@ -121,11 +109,10 @@ static inline void set_cold_files(struct f2fs_sb_info *sbi, struct inode *inode, static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; nid_t ino = 0; - int err, ilock; + int err; f2fs_balance_fs(sbi); @@ -141,24 +128,23 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, inode->i_mapping->a_ops = &f2fs_dblock_aops; ino = inode->i_ino; - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); - mutex_unlock_op(sbi, ilock); if (err) goto out; + f2fs_unlock_op(sbi); alloc_nid_done(sbi, ino); - if (!sbi->por_doing) - d_instantiate(dentry, inode); + stat_inc_inline_inode(inode); + d_instantiate(dentry, inode); unlock_new_inode(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: - clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); - alloc_nid_failed(sbi, ino); + handle_failed_inode(inode); return err; } @@ -166,34 +152,30 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { struct inode *inode = old_dentry->d_inode; - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); - int err, ilock; + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + int err; f2fs_balance_fs(sbi); inode->i_ctime = CURRENT_TIME; - atomic_inc(&inode->i_count); + ihold(inode); set_inode_flag(F2FS_I(inode), FI_INC_LINK); - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); - mutex_unlock_op(sbi, ilock); if (err) goto out; - - /* - * This file should be checkpointed during fsync. - * We lost i_pino from now on. - */ - set_cp_file(inode); + f2fs_unlock_op(sbi); d_instantiate(dentry, inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: clear_inode_flag(F2FS_I(inode), FI_INC_LINK); - make_bad_inode(inode); iput(inode); + f2fs_unlock_op(sbi); return err; } @@ -206,6 +188,44 @@ struct dentry *f2fs_get_parent(struct dentry *child) return d_obtain_alias(f2fs_iget(child->d_inode->i_sb, ino)); } +static int __recover_dot_dentries(struct inode *dir, nid_t pino) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct qstr dot = QSTR_INIT(".", 1); + struct qstr dotdot = QSTR_INIT("..", 2); + struct f2fs_dir_entry *de; + struct page *page; + int err = 0; + + f2fs_lock_op(sbi); + + de = f2fs_find_entry(dir, &dot, &page); + if (de) { + f2fs_dentry_kunmap(dir, page); + f2fs_put_page(page, 0); + } else { + err = __f2fs_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR); + if (err) + goto out; + } + + de = f2fs_find_entry(dir, &dotdot, &page); + if (de) { + f2fs_dentry_kunmap(dir, page); + f2fs_put_page(page, 0); + } else { + err = __f2fs_add_link(dir, &dotdot, NULL, pino, S_IFDIR); + } +out: + if (!err) { + clear_inode_flag(F2FS_I(dir), FI_INLINE_DOTS); + mark_inode_dirty(dir); + } + + f2fs_unlock_op(sbi); + return err; +} + static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { @@ -219,12 +239,22 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, de = f2fs_find_entry(dir, &dentry->d_name, &page); if (de) { nid_t ino = le32_to_cpu(de->ino); - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); inode = f2fs_iget(dir->i_sb, ino); if (IS_ERR(inode)) return ERR_CAST(inode); + + if (f2fs_has_inline_dots(inode)) { + int err; + + err = __recover_dot_dentries(inode, dir->i_ino); + if (err) { + iget_failed(inode); + return ERR_PTR(err); + } + } } return d_splice_alias(inode, dentry); @@ -232,13 +262,11 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, static int f2fs_unlink(struct inode *dir, struct dentry *dentry) { - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode = dentry->d_inode; struct f2fs_dir_entry *de; struct page *page; int err = -ENOENT; - int ilock; trace_f2fs_unlink_enter(dir, dentry); f2fs_balance_fs(sbi); @@ -247,32 +275,51 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) if (!de) goto fail; - err = check_orphan_space(sbi); + f2fs_lock_op(sbi); + err = acquire_orphan_inode(sbi); if (err) { - kunmap(page); + f2fs_unlock_op(sbi); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); goto fail; } + f2fs_delete_entry(de, page, dir, inode); + f2fs_unlock_op(sbi); - ilock = mutex_lock_op(sbi); - f2fs_delete_entry(de, page, inode); - mutex_unlock_op(sbi, ilock); - - /* In order to evict this inode, we set it dirty */ + /* In order to evict this inode, we set it dirty */ mark_inode_dirty(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); fail: trace_f2fs_unlink_exit(inode, err); return err; } +static void *f2fs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct page *page; + + page = page_follow_link_light(dentry, nd); + if (IS_ERR(page)) + return page; + + /* this is broken symlink case */ + if (*nd_get_link(nd) == 0) { + kunmap(page); + page_cache_release(page); + return ERR_PTR(-ENOENT); + } + return page; +} + static int f2fs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; size_t symlen = strlen(symname) + 1; - int err, ilock; + int err; f2fs_balance_fs(sbi); @@ -283,32 +330,42 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, inode->i_op = &f2fs_symlink_inode_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); - mutex_unlock_op(sbi, ilock); if (err) goto out; + f2fs_unlock_op(sbi); err = page_symlink(inode, symname, symlen); alloc_nid_done(sbi, inode->i_ino); d_instantiate(dentry, inode); unlock_new_inode(inode); + + /* + * Let's flush symlink data in order to avoid broken symlink as much as + * possible. Nevertheless, fsyncing is the best way, but there is no + * way to get a file descriptor in order to flush that. + * + * Note that, it needs to do dir->fsync to make this recoverable. + * If the symlink path is stored into inline_data, there is no + * performance regression. + */ + filemap_write_and_wait_range(inode->i_mapping, 0, symlen - 1); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return err; out: - clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); - alloc_nid_failed(sbi, inode->i_ino); + handle_failed_inode(inode); return err; } static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; - int err, ilock; + int err; f2fs_balance_fs(sbi); @@ -319,29 +376,28 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); + mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); set_inode_flag(F2FS_I(inode), FI_INC_LINK); - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); - mutex_unlock_op(sbi, ilock); if (err) goto out_fail; + f2fs_unlock_op(sbi); + stat_inc_inline_dir(inode); alloc_nid_done(sbi, inode->i_ino); d_instantiate(dentry, inode); unlock_new_inode(inode); + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out_fail: clear_inode_flag(F2FS_I(inode), FI_INC_LINK); - clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); - alloc_nid_failed(sbi, inode->i_ino); + handle_failed_inode(inode); return err; } @@ -356,11 +412,9 @@ static int f2fs_rmdir(struct inode *dir, struct dentry *dentry) static int f2fs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { - struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode; int err = 0; - int ilock; if (!new_valid_dev(rdev)) return -EINVAL; @@ -374,38 +428,37 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, init_special_inode(inode, inode->i_mode, rdev); inode->i_op = &f2fs_special_inode_operations; - ilock = mutex_lock_op(sbi); + f2fs_lock_op(sbi); err = f2fs_add_link(dentry, inode); - mutex_unlock_op(sbi, ilock); if (err) goto out; + f2fs_unlock_op(sbi); alloc_nid_done(sbi, inode->i_ino); + d_instantiate(dentry, inode); unlock_new_inode(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: - clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); - alloc_nid_failed(sbi, inode->i_ino); + handle_failed_inode(inode); return err; } static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { - struct super_block *sb = old_dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir); struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct page *old_dir_page; - struct page *old_page; + struct page *old_page, *new_page; struct f2fs_dir_entry *old_dir_entry = NULL; struct f2fs_dir_entry *old_entry; struct f2fs_dir_entry *new_entry; - int err = -ENOENT, ilock = -1; + int err = -ENOENT; f2fs_balance_fs(sbi); @@ -420,10 +473,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out_old; } - ilock = mutex_lock_op(sbi); - if (new_inode) { - struct page *new_page; err = -ENOTEMPTY; if (old_dir_entry && !f2fs_empty_dir(new_inode)) @@ -435,19 +485,43 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!new_entry) goto out_dir; + f2fs_lock_op(sbi); + + err = acquire_orphan_inode(sbi); + if (err) + goto put_out_dir; + + if (update_dent_inode(old_inode, &new_dentry->d_name)) { + release_orphan_inode(sbi); + goto put_out_dir; + } + f2fs_set_link(new_dir, new_entry, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME; + down_write(&F2FS_I(new_inode)->i_sem); if (old_dir_entry) drop_nlink(new_inode); drop_nlink(new_inode); + up_write(&F2FS_I(new_inode)->i_sem); + + mark_inode_dirty(new_inode); + if (!new_inode->i_nlink) add_orphan_inode(sbi, new_inode->i_ino); + else + release_orphan_inode(sbi); + + update_inode_page(old_inode); update_inode_page(new_inode); } else { + f2fs_lock_op(sbi); + err = f2fs_add_link(new_dentry, old_inode); - if (err) + if (err) { + f2fs_unlock_op(sbi); goto out_dir; + } if (old_dir_entry) { inc_nlink(new_dir); @@ -455,34 +529,46 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, } } + down_write(&F2FS_I(old_inode)->i_sem); + file_lost_pino(old_inode); + up_write(&F2FS_I(old_inode)->i_sem); + old_inode->i_ctime = CURRENT_TIME; mark_inode_dirty(old_inode); - f2fs_delete_entry(old_entry, old_page, NULL); + f2fs_delete_entry(old_entry, old_page, old_dir, NULL); if (old_dir_entry) { if (old_dir != new_dir) { f2fs_set_link(old_inode, old_dir_entry, old_dir_page, new_dir); + update_inode_page(old_inode); } else { - kunmap(old_dir_page); + f2fs_dentry_kunmap(old_inode, old_dir_page); f2fs_put_page(old_dir_page, 0); } drop_nlink(old_dir); + mark_inode_dirty(old_dir); update_inode_page(old_dir); } - mutex_unlock_op(sbi, ilock); + f2fs_unlock_op(sbi); + + if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; +put_out_dir: + f2fs_unlock_op(sbi); + f2fs_dentry_kunmap(new_dir, new_page); + f2fs_put_page(new_page, 0); out_dir: if (old_dir_entry) { - kunmap(old_dir_page); + f2fs_dentry_kunmap(old_inode, old_dir_page); f2fs_put_page(old_dir_page, 0); } - mutex_unlock_op(sbi, ilock); out_old: - kunmap(old_page); + f2fs_dentry_kunmap(old_dir, old_page); f2fs_put_page(old_page, 0); out: return err; @@ -498,6 +584,7 @@ const struct inode_operations f2fs_dir_inode_operations = { .rmdir = f2fs_rmdir, .mknod = f2fs_mknod, .rename = f2fs_rename, + .getattr = f2fs_getattr, .setattr = f2fs_setattr, .get_acl = f2fs_get_acl, #ifdef CONFIG_F2FS_FS_XATTR @@ -510,8 +597,9 @@ const struct inode_operations f2fs_dir_inode_operations = { const struct inode_operations f2fs_symlink_inode_operations = { .readlink = generic_readlink, - .follow_link = page_follow_link_light, + .follow_link = f2fs_follow_link, .put_link = page_put_link, + .getattr = f2fs_getattr, .setattr = f2fs_setattr, #ifdef CONFIG_F2FS_FS_XATTR .setxattr = generic_setxattr, @@ -522,6 +610,7 @@ const struct inode_operations f2fs_symlink_inode_operations = { }; const struct inode_operations f2fs_special_inode_operations = { + .getattr = f2fs_getattr, .setattr = f2fs_setattr, .get_acl = f2fs_get_acl, #ifdef CONFIG_F2FS_FS_XATTR diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 3df43b4efd89e..32f4934c6a2aa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -19,15 +19,66 @@ #include "f2fs.h" #include "node.h" #include "segment.h" +#include "trace.h" #include +#define on_build_free_nids(nmi) mutex_is_locked(&nm_i->build_lock) + static struct kmem_cache *nat_entry_slab; static struct kmem_cache *free_nid_slab; +static struct kmem_cache *nat_entry_set_slab; + +bool available_free_memory(struct f2fs_sb_info *sbi, int type) +{ + struct f2fs_nm_info *nm_i = NM_I(sbi); + struct sysinfo val; + unsigned long avail_ram; + unsigned long mem_size = 0; + bool res = false; + + si_meminfo(&val); + + /* only uses low memory */ + avail_ram = val.totalram - val.totalhigh; + + /* + * give 25%, 25%, 50%, 50%, 50% memory for each components respectively + */ + if (type == FREE_NIDS) { + mem_size = (nm_i->fcnt * sizeof(struct free_nid)) >> + PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2); + } else if (type == NAT_ENTRIES) { + mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >> + PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2); + } else if (type == DIRTY_DENTS) { + if (sbi->sb->s_bdi->dirty_exceeded) + return false; + mem_size = get_pages(sbi, F2FS_DIRTY_DENTS); + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); + } else if (type == INO_ENTRIES) { + int i; + + for (i = 0; i <= UPDATE_INO; i++) + mem_size += (sbi->im[i].ino_num * + sizeof(struct ino_entry)) >> PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); + } else if (type == EXTENT_CACHE) { + mem_size = (sbi->total_ext_tree * sizeof(struct extent_tree) + + atomic_read(&sbi->total_ext_node) * + sizeof(struct extent_node)) >> PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); + } else { + if (sbi->sb->s_bdi->dirty_exceeded) + return false; + } + return res; +} static void clear_node_page_dirty(struct page *page) { struct address_space *mapping = page->mapping; - struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); unsigned int long flags; if (PageDirty(page)) { @@ -38,7 +89,7 @@ static void clear_node_page_dirty(struct page *page) spin_unlock_irqrestore(&mapping->tree_lock, flags); clear_page_dirty_for_io(page); - dec_page_count(sbi, F2FS_DIRTY_NODES); + dec_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_NODES); } ClearPageUptodate(page); } @@ -64,12 +115,8 @@ static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid) /* get current nat block page with lock */ src_page = get_meta_page(sbi, src_off); - - /* Dirty src_page means that it is already the new target NAT page. */ - if (PageDirty(src_page)) - return src_page; - dst_page = grab_meta_page(sbi, dst_off); + f2fs_bug_on(sbi, PageDirty(src_page)); src_addr = page_address(src_page); dst_addr = page_address(dst_page); @@ -82,40 +129,6 @@ static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid) return dst_page; } -/* - * Readahead NAT pages - */ -static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid) -{ - struct address_space *mapping = sbi->meta_inode->i_mapping; - struct f2fs_nm_info *nm_i = NM_I(sbi); - struct blk_plug plug; - struct page *page; - pgoff_t index; - int i; - - blk_start_plug(&plug); - - for (i = 0; i < FREE_NID_PAGES; i++, nid += NAT_ENTRY_PER_BLOCK) { - if (nid >= nm_i->max_nid) - nid = 0; - index = current_nat_addr(sbi, nid); - - page = grab_cache_page(mapping, index); - if (!page) - continue; - if (PageUptodate(page)) { - f2fs_put_page(page, 1); - continue; - } - if (f2fs_readpage(sbi, page, index, READ)) - continue; - - f2fs_put_page(page, 0); - } - blk_finish_plug(&plug); -} - static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n) { return radix_tree_lookup(&nm_i->nat_root, n); @@ -135,33 +148,106 @@ static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e) kmem_cache_free(nat_entry_slab, e); } -int is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid) +static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i, + struct nat_entry *ne) +{ + nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid); + struct nat_entry_set *head; + + if (get_nat_flag(ne, IS_DIRTY)) + return; + + head = radix_tree_lookup(&nm_i->nat_set_root, set); + if (!head) { + head = f2fs_kmem_cache_alloc(nat_entry_set_slab, GFP_ATOMIC); + + INIT_LIST_HEAD(&head->entry_list); + INIT_LIST_HEAD(&head->set_list); + head->set = set; + head->entry_cnt = 0; + f2fs_radix_tree_insert(&nm_i->nat_set_root, set, head); + } + list_move_tail(&ne->list, &head->entry_list); + nm_i->dirty_nat_cnt++; + head->entry_cnt++; + set_nat_flag(ne, IS_DIRTY, true); +} + +static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i, + struct nat_entry *ne) +{ + nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid); + struct nat_entry_set *head; + + head = radix_tree_lookup(&nm_i->nat_set_root, set); + if (head) { + list_move_tail(&ne->list, &nm_i->nat_entries); + set_nat_flag(ne, IS_DIRTY, false); + head->entry_cnt--; + nm_i->dirty_nat_cnt--; + } +} + +static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i, + nid_t start, unsigned int nr, struct nat_entry_set **ep) +{ + return radix_tree_gang_lookup(&nm_i->nat_set_root, (void **)ep, + start, nr); +} + +bool is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct nat_entry *e; - int is_cp = 1; + bool is_cp = true; - read_lock(&nm_i->nat_tree_lock); + down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); - if (e && !e->checkpointed) - is_cp = 0; - read_unlock(&nm_i->nat_tree_lock); + if (e && !get_nat_flag(e, IS_CHECKPOINTED)) + is_cp = false; + up_read(&nm_i->nat_tree_lock); return is_cp; } +bool has_fsynced_inode(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct f2fs_nm_info *nm_i = NM_I(sbi); + struct nat_entry *e; + bool fsynced = false; + + down_read(&nm_i->nat_tree_lock); + e = __lookup_nat_cache(nm_i, ino); + if (e && get_nat_flag(e, HAS_FSYNCED_INODE)) + fsynced = true; + up_read(&nm_i->nat_tree_lock); + return fsynced; +} + +bool need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct f2fs_nm_info *nm_i = NM_I(sbi); + struct nat_entry *e; + bool need_update = true; + + down_read(&nm_i->nat_tree_lock); + e = __lookup_nat_cache(nm_i, ino); + if (e && get_nat_flag(e, HAS_LAST_FSYNC) && + (get_nat_flag(e, IS_CHECKPOINTED) || + get_nat_flag(e, HAS_FSYNCED_INODE))) + need_update = false; + up_read(&nm_i->nat_tree_lock); + return need_update; +} + static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid) { struct nat_entry *new; - new = kmem_cache_alloc(nat_entry_slab, GFP_ATOMIC); - if (!new) - return NULL; - if (radix_tree_insert(&nm_i->nat_root, nid, new)) { - kmem_cache_free(nat_entry_slab, new); - return NULL; - } + new = f2fs_kmem_cache_alloc(nat_entry_slab, GFP_ATOMIC); + f2fs_radix_tree_insert(&nm_i->nat_root, nid, new); memset(new, 0, sizeof(struct nat_entry)); nat_set_nid(new, nid); + nat_reset_flag(new); list_add_tail(&new->list, &nm_i->nat_entries); nm_i->nat_cnt++; return new; @@ -171,64 +257,49 @@ static void cache_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid, struct f2fs_nat_entry *ne) { struct nat_entry *e; -retry: - write_lock(&nm_i->nat_tree_lock); + + down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (!e) { e = grab_nat_entry(nm_i, nid); - if (!e) { - write_unlock(&nm_i->nat_tree_lock); - goto retry; - } - nat_set_blkaddr(e, le32_to_cpu(ne->block_addr)); - nat_set_ino(e, le32_to_cpu(ne->ino)); - nat_set_version(e, ne->version); - e->checkpointed = true; + node_info_from_raw_nat(&e->ni, ne); } - write_unlock(&nm_i->nat_tree_lock); + up_write(&nm_i->nat_tree_lock); } static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, - block_t new_blkaddr) + block_t new_blkaddr, bool fsync_done) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct nat_entry *e; -retry: - write_lock(&nm_i->nat_tree_lock); + + down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, ni->nid); if (!e) { e = grab_nat_entry(nm_i, ni->nid); - if (!e) { - write_unlock(&nm_i->nat_tree_lock); - goto retry; - } - e->ni = *ni; - e->checkpointed = true; - BUG_ON(ni->blk_addr == NEW_ADDR); + copy_node_info(&e->ni, ni); + f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR); } else if (new_blkaddr == NEW_ADDR) { /* * when nid is reallocated, * previous nat entry can be remained in nat cache. * So, reinitialize it with new information. */ - e->ni = *ni; - BUG_ON(ni->blk_addr != NULL_ADDR); + copy_node_info(&e->ni, ni); + f2fs_bug_on(sbi, ni->blk_addr != NULL_ADDR); } - if (new_blkaddr == NEW_ADDR) - e->checkpointed = false; - /* sanity check */ - BUG_ON(nat_get_blkaddr(e) != ni->blk_addr); - BUG_ON(nat_get_blkaddr(e) == NULL_ADDR && + f2fs_bug_on(sbi, nat_get_blkaddr(e) != ni->blk_addr); + f2fs_bug_on(sbi, nat_get_blkaddr(e) == NULL_ADDR && new_blkaddr == NULL_ADDR); - BUG_ON(nat_get_blkaddr(e) == NEW_ADDR && + f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR && new_blkaddr == NEW_ADDR); - BUG_ON(nat_get_blkaddr(e) != NEW_ADDR && + f2fs_bug_on(sbi, nat_get_blkaddr(e) != NEW_ADDR && nat_get_blkaddr(e) != NULL_ADDR && new_blkaddr == NEW_ADDR); - /* increament version no as node is removed */ + /* increment version no as node is removed */ if (nat_get_blkaddr(e) != NEW_ADDR && new_blkaddr == NULL_ADDR) { unsigned char version = nat_get_version(e); nat_set_version(e, inc_node_version(version)); @@ -236,18 +307,28 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, /* change address */ nat_set_blkaddr(e, new_blkaddr); + if (new_blkaddr == NEW_ADDR || new_blkaddr == NULL_ADDR) + set_nat_flag(e, IS_CHECKPOINTED, false); __set_nat_cache_dirty(nm_i, e); - write_unlock(&nm_i->nat_tree_lock); + + /* update fsync_mark if its inode nat entry is still alive */ + e = __lookup_nat_cache(nm_i, ni->ino); + if (e) { + if (fsync_done && ni->nid == ni->ino) + set_nat_flag(e, HAS_FSYNCED_INODE, true); + set_nat_flag(e, HAS_LAST_FSYNC, fsync_done); + } + up_write(&nm_i->nat_tree_lock); } -static int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) +int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) { struct f2fs_nm_info *nm_i = NM_I(sbi); - if (nm_i->nat_cnt <= NM_WOUT_THRESHOLD) + if (available_free_memory(sbi, NAT_ENTRIES)) return 0; - write_lock(&nm_i->nat_tree_lock); + down_write(&nm_i->nat_tree_lock); while (nr_shrink && !list_empty(&nm_i->nat_entries)) { struct nat_entry *ne; ne = list_first_entry(&nm_i->nat_entries, @@ -255,12 +336,12 @@ static int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) __del_from_nat_cache(nm_i, ne); nr_shrink--; } - write_unlock(&nm_i->nat_tree_lock); + up_write(&nm_i->nat_tree_lock); return nr_shrink; } /* - * This function returns always success + * This function always returns success */ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) { @@ -274,21 +355,22 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) struct nat_entry *e; int i; - memset(&ne, 0, sizeof(struct f2fs_nat_entry)); ni->nid = nid; /* Check nat cache */ - read_lock(&nm_i->nat_tree_lock); + down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (e) { ni->ino = nat_get_ino(e); ni->blk_addr = nat_get_blkaddr(e); ni->version = nat_get_version(e); } - read_unlock(&nm_i->nat_tree_lock); + up_read(&nm_i->nat_tree_lock); if (e) return; + memset(&ne, 0, sizeof(struct f2fs_nat_entry)); + /* Check current segment summary */ mutex_lock(&curseg->curseg_mutex); i = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 0); @@ -315,9 +397,10 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) * The maximum depth is four. * Offset[0] will have raw inode offset. */ -static int get_node_path(long block, int offset[4], unsigned int noffset[4]) +static int get_node_path(struct f2fs_inode_info *fi, long block, + int offset[4], unsigned int noffset[4]) { - const long direct_index = ADDRS_PER_INODE; + const long direct_index = ADDRS_PER_INODE(fi); const long direct_blks = ADDRS_PER_BLOCK; const long dptrs_per_blk = NIDS_PER_BLOCK; const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; @@ -390,27 +473,38 @@ static int get_node_path(long block, int offset[4], unsigned int noffset[4]) /* * Caller should call f2fs_put_dnode(dn). - * Also, it should grab and release a mutex by calling mutex_lock_op() and - * mutex_unlock_op() only if ro is not set RDONLY_NODE. + * Also, it should grab and release a rwsem by calling f2fs_lock_op() and + * f2fs_unlock_op() only if ro is not set RDONLY_NODE. * In the case of RDONLY_NODE, we don't need to care about mutex. */ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct page *npage[4]; - struct page *parent; + struct page *parent = NULL; int offset[4]; unsigned int noffset[4]; nid_t nids[4]; int level, i; int err = 0; - level = get_node_path(index, offset, noffset); + level = get_node_path(F2FS_I(dn->inode), index, offset, noffset); nids[0] = dn->inode->i_ino; - npage[0] = get_node_page(sbi, nids[0]); - if (IS_ERR(npage[0])) - return PTR_ERR(npage[0]); + npage[0] = dn->inode_page; + + if (!npage[0]) { + npage[0] = get_node_page(sbi, nids[0]); + if (IS_ERR(npage[0])) + return PTR_ERR(npage[0]); + } + + /* if inline_data is set, should not report any block indices */ + if (f2fs_has_inline_data(dn->inode) && index) { + err = -ENOENT; + f2fs_put_page(npage[0], 1); + goto release_out; + } parent = npage[0]; if (level != 0) @@ -430,7 +524,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) } dn->nid = nids[i]; - npage[i] = new_node_page(dn, noffset[i]); + npage[i] = new_node_page(dn, noffset[i], NULL); if (IS_ERR(npage[i])) { alloc_nid_failed(sbi, nids[i]); err = PTR_ERR(npage[i]); @@ -486,20 +580,20 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) static void truncate_node(struct dnode_of_data *dn) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct node_info ni; get_node_info(sbi, dn->nid, &ni); if (dn->inode->i_blocks == 0) { - BUG_ON(ni.blk_addr != NULL_ADDR); + f2fs_bug_on(sbi, ni.blk_addr != NULL_ADDR); goto invalidate; } - BUG_ON(ni.blk_addr == NULL_ADDR); + f2fs_bug_on(sbi, ni.blk_addr == NULL_ADDR); /* Deallocate node address */ invalidate_blocks(sbi, ni.blk_addr); - dec_valid_node_count(sbi, dn->inode, 1); - set_node_addr(sbi, &ni, NULL_ADDR); + dec_valid_node_count(sbi, dn->inode); + set_node_addr(sbi, &ni, NULL_ADDR, false); if (dn->nid == dn->inode->i_ino) { remove_orphan_inode(sbi, dn->nid); @@ -509,23 +603,26 @@ static void truncate_node(struct dnode_of_data *dn) } invalidate: clear_node_page_dirty(dn->node_page); - F2FS_SET_SB_DIRT(sbi); + set_sbi_flag(sbi, SBI_IS_DIRTY); f2fs_put_page(dn->node_page, 1); + + invalidate_mapping_pages(NODE_MAPPING(sbi), + dn->node_page->index, dn->node_page->index); + dn->node_page = NULL; trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr); } static int truncate_dnode(struct dnode_of_data *dn) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); struct page *page; if (dn->nid == 0) return 1; /* get direct node */ - page = get_node_page(sbi, dn->nid); + page = get_node_page(F2FS_I_SB(dn->inode), dn->nid); if (IS_ERR(page) && PTR_ERR(page) == -ENOENT) return 1; else if (IS_ERR(page)) @@ -542,7 +639,6 @@ static int truncate_dnode(struct dnode_of_data *dn) static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, int ofs, int depth) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); struct dnode_of_data rdn = *dn; struct page *page; struct f2fs_node *rn; @@ -556,13 +652,13 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, trace_f2fs_truncate_nodes_enter(dn->inode, dn->nid, dn->data_blkaddr); - page = get_node_page(sbi, dn->nid); + page = get_node_page(F2FS_I_SB(dn->inode), dn->nid); if (IS_ERR(page)) { trace_f2fs_truncate_nodes_exit(dn->inode, PTR_ERR(page)); return PTR_ERR(page); } - rn = (struct f2fs_node *)page_address(page); + rn = F2FS_NODE(page); if (depth < 3) { for (i = ofs; i < NIDS_PER_BLOCK; i++, freed++) { child_nid = le32_to_cpu(rn->in.nid[i]); @@ -614,7 +710,6 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, static int truncate_partial_nodes(struct dnode_of_data *dn, struct f2fs_inode *ri, int *offset, int depth) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); struct page *pages[2]; nid_t nid[3]; nid_t child_nid; @@ -627,19 +722,19 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, return 0; /* get indirect nodes in the path */ - for (i = 0; i < depth - 1; i++) { - /* refernece count'll be increased */ - pages[i] = get_node_page(sbi, nid[i]); + for (i = 0; i < idx + 1; i++) { + /* reference count'll be increased */ + pages[i] = get_node_page(F2FS_I_SB(dn->inode), nid[i]); if (IS_ERR(pages[i])) { - depth = i + 1; err = PTR_ERR(pages[i]); + idx = i - 1; goto fail; } nid[i + 1] = get_nid(pages[i], offset[i + 1], false); } /* free direct nodes linked to a partial indirect node */ - for (i = offset[depth - 1]; i < NIDS_PER_BLOCK; i++) { + for (i = offset[idx + 1]; i < NIDS_PER_BLOCK; i++) { child_nid = get_nid(pages[idx], i, false); if (!child_nid) continue; @@ -650,7 +745,7 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, set_nid(pages[idx], i, 0, false); } - if (offset[depth - 1] == 0) { + if (offset[idx + 1] == 0) { dn->node_page = pages[idx]; dn->nid = nid[idx]; truncate_node(dn); @@ -658,9 +753,10 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, f2fs_put_page(pages[idx], 1); } offset[idx]++; - offset[depth - 1] = 0; + offset[idx + 1] = 0; + idx--; fail: - for (i = depth - 3; i >= 0; i--) + for (i = idx; i >= 0; i--) f2fs_put_page(pages[i], 1); trace_f2fs_truncate_partial_nodes(dn->inode, nid, depth, err); @@ -673,18 +769,17 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, */ int truncate_inode_blocks(struct inode *inode, pgoff_t from) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct address_space *node_mapping = sbi->node_inode->i_mapping; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); int err = 0, cont = 1; int level, offset[4], noffset[4]; unsigned int nofs = 0; - struct f2fs_node *rn; + struct f2fs_inode *ri; struct dnode_of_data dn; struct page *page; trace_f2fs_truncate_inode_blocks_enter(inode, from); - level = get_node_path(from, offset, noffset); + level = get_node_path(F2FS_I(inode), from, offset, noffset); restart: page = get_node_page(sbi, inode->i_ino); if (IS_ERR(page)) { @@ -695,7 +790,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) set_new_dnode(&dn, inode, page, NULL, 0); unlock_page(page); - rn = page_address(page); + ri = F2FS_INODE(page); switch (level) { case 0: case 1: @@ -705,7 +800,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) nofs = noffset[1]; if (!offset[level - 1]) goto skip_partial; - err = truncate_partial_nodes(&dn, &rn->i, offset, level); + err = truncate_partial_nodes(&dn, ri, offset, level); if (err < 0 && err != -ENOENT) goto fail; nofs += 1 + NIDS_PER_BLOCK; @@ -714,7 +809,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) nofs = 5 + 2 * NIDS_PER_BLOCK; if (!offset[level - 1]) goto skip_partial; - err = truncate_partial_nodes(&dn, &rn->i, offset, level); + err = truncate_partial_nodes(&dn, ri, offset, level); if (err < 0 && err != -ENOENT) goto fail; break; @@ -724,7 +819,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) skip_partial: while (cont) { - dn.nid = le32_to_cpu(rn->i.i_nid[offset[0] - NODE_DIR1_BLOCK]); + dn.nid = le32_to_cpu(ri->i_nid[offset[0] - NODE_DIR1_BLOCK]); switch (offset[0]) { case NODE_DIR1_BLOCK: case NODE_DIR2_BLOCK: @@ -747,14 +842,14 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) if (err < 0 && err != -ENOENT) goto fail; if (offset[1] == 0 && - rn->i.i_nid[offset[0] - NODE_DIR1_BLOCK]) { + ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) { lock_page(page); - if (page->mapping != node_mapping) { + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto restart; } - wait_on_page_writeback(page); - rn->i.i_nid[offset[0] - NODE_DIR1_BLOCK] = 0; + f2fs_wait_on_page_writeback(page, NODE); + ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0; set_page_dirty(page); unlock_page(page); } @@ -768,91 +863,116 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) return err > 0 ? 0 : err; } +int truncate_xattr_node(struct inode *inode, struct page *page) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + nid_t nid = F2FS_I(inode)->i_xattr_nid; + struct dnode_of_data dn; + struct page *npage; + + if (!nid) + return 0; + + npage = get_node_page(sbi, nid); + if (IS_ERR(npage)) + return PTR_ERR(npage); + + F2FS_I(inode)->i_xattr_nid = 0; + + /* need to do checkpoint during fsync */ + F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi)); + + set_new_dnode(&dn, inode, page, npage, nid); + + if (page) + dn.inode_page_locked = true; + truncate_node(&dn); + return 0; +} + /* - * Caller should grab and release a mutex by calling mutex_lock_op() and - * mutex_unlock_op(). + * Caller should grab and release a rwsem by calling f2fs_lock_op() and + * f2fs_unlock_op(). */ -int remove_inode_page(struct inode *inode) +void remove_inode_page(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct page *page; - nid_t ino = inode->i_ino; struct dnode_of_data dn; - page = get_node_page(sbi, ino); - if (IS_ERR(page)) - return PTR_ERR(page); + set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); + if (get_dnode_of_data(&dn, 0, LOOKUP_NODE)) + return; - if (F2FS_I(inode)->i_xattr_nid) { - nid_t nid = F2FS_I(inode)->i_xattr_nid; - struct page *npage = get_node_page(sbi, nid); + if (truncate_xattr_node(inode, dn.inode_page)) { + f2fs_put_dnode(&dn); + return; + } - if (IS_ERR(npage)) - return PTR_ERR(npage); + /* remove potential inline_data blocks */ + if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || + S_ISLNK(inode->i_mode)) + truncate_data_blocks_range(&dn, 1); - F2FS_I(inode)->i_xattr_nid = 0; - set_new_dnode(&dn, inode, page, npage, nid); - dn.inode_page_locked = 1; - truncate_node(&dn); - } + /* 0 is possible, after f2fs_new_inode() has failed */ + f2fs_bug_on(F2FS_I_SB(inode), + inode->i_blocks != 0 && inode->i_blocks != 1); - /* 0 is possible, after f2fs_new_inode() is failed */ - BUG_ON(inode->i_blocks != 0 && inode->i_blocks != 1); - set_new_dnode(&dn, inode, page, page, ino); + /* will put inode & node pages */ truncate_node(&dn); - return 0; } -int new_inode_page(struct inode *inode, const struct qstr *name) +struct page *new_inode_page(struct inode *inode) { - struct page *page; struct dnode_of_data dn; /* allocate inode page for new inode */ set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); - page = new_node_page(&dn, 0); - init_dent_inode(name, page); - if (IS_ERR(page)) - return PTR_ERR(page); - f2fs_put_page(page, 1); - return 0; + + /* caller should f2fs_put_page(page, 1); */ + return new_node_page(&dn, 0, NULL); } -struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) +struct page *new_node_page(struct dnode_of_data *dn, + unsigned int ofs, struct page *ipage) { - struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb); - struct address_space *mapping = sbi->node_inode->i_mapping; + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct node_info old_ni, new_ni; struct page *page; int err; - if (is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)) + if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) return ERR_PTR(-EPERM); - page = grab_cache_page(mapping, dn->nid); + page = grab_cache_page(NODE_MAPPING(sbi), dn->nid); if (!page) return ERR_PTR(-ENOMEM); - get_node_info(sbi, dn->nid, &old_ni); + if (unlikely(!inc_valid_node_count(sbi, dn->inode))) { + err = -ENOSPC; + goto fail; + } - SetPageUptodate(page); - fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); + get_node_info(sbi, dn->nid, &old_ni); /* Reinitialize old_ni with new node page */ - BUG_ON(old_ni.blk_addr != NULL_ADDR); + f2fs_bug_on(sbi, old_ni.blk_addr != NULL_ADDR); new_ni = old_ni; new_ni.ino = dn->inode->i_ino; + set_node_addr(sbi, &new_ni, NEW_ADDR, false); - if (!inc_valid_node_count(sbi, dn->inode, 1)) { - err = -ENOSPC; - goto fail; - } - set_node_addr(sbi, &new_ni, NEW_ADDR); + f2fs_wait_on_page_writeback(page, NODE); + fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); set_cold_node(dn->inode, page); + SetPageUptodate(page); + set_page_dirty(page); + + if (f2fs_has_xattr_block(ofs)) + F2FS_I(dn->inode)->i_xattr_nid = dn->nid; dn->node_page = page; - sync_inode_page(dn); - set_page_dirty(page); + if (ipage) + update_inode(dn->inode, ipage); + else + sync_inode_page(dn); if (ofs == 0) inc_valid_inode_count(sbi); @@ -870,14 +990,19 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) * LOCKED_PAGE: f2fs_put_page(page, 1) * error: nothing */ -static int read_node_page(struct page *page, int type) +static int read_node_page(struct page *page, int rw) { - struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); + struct f2fs_sb_info *sbi = F2FS_P_SB(page); struct node_info ni; + struct f2fs_io_info fio = { + .type = NODE, + .rw = rw, + }; get_node_info(sbi, page->index, &ni); - if (ni.blk_addr == NULL_ADDR) { + if (unlikely(ni.blk_addr == NULL_ADDR)) { + ClearPageUptodate(page); f2fs_put_page(page, 1); return -ENOENT; } @@ -885,7 +1010,8 @@ static int read_node_page(struct page *page, int type) if (PageUptodate(page)) return LOCKED_PAGE; - return f2fs_readpage(sbi, page, ni.blk_addr, type); + fio.blk_addr = ni.blk_addr; + return f2fs_submit_page_bio(sbi, page, &fio); } /* @@ -893,18 +1019,17 @@ static int read_node_page(struct page *page, int type) */ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) { - struct address_space *mapping = sbi->node_inode->i_mapping; struct page *apage; int err; - apage = find_get_page(mapping, nid); + apage = find_get_page(NODE_MAPPING(sbi), nid); if (apage && PageUptodate(apage)) { f2fs_put_page(apage, 0); return; } f2fs_put_page(apage, 0); - apage = grab_cache_page(mapping, nid); + apage = grab_cache_page(NODE_MAPPING(sbi), nid); if (!apage) return; @@ -913,36 +1038,32 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) f2fs_put_page(apage, 0); else if (err == LOCKED_PAGE) f2fs_put_page(apage, 1); - return; } struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) { - struct address_space *mapping = sbi->node_inode->i_mapping; struct page *page; int err; repeat: - page = grab_cache_page(mapping, nid); + page = grab_cache_page(NODE_MAPPING(sbi), nid); if (!page) return ERR_PTR(-ENOMEM); err = read_node_page(page, READ_SYNC); if (err < 0) return ERR_PTR(err); - else if (err == LOCKED_PAGE) - goto got_it; + else if (err != LOCKED_PAGE) + lock_page(page); - lock_page(page); - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page) || nid != nid_of_node(page))) { + ClearPageUptodate(page); f2fs_put_page(page, 1); return ERR_PTR(-EIO); } - if (page->mapping != mapping) { + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } -got_it: - BUG_ON(nid != nid_of_node(page)); mark_page_accessed(page); return page; } @@ -953,8 +1074,7 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) */ struct page *get_node_page_ra(struct page *parent, int start) { - struct f2fs_sb_info *sbi = F2FS_SB(parent->mapping->host->i_sb); - struct address_space *mapping = sbi->node_inode->i_mapping; + struct f2fs_sb_info *sbi = F2FS_P_SB(parent); struct blk_plug plug; struct page *page; int err, i, end; @@ -965,7 +1085,7 @@ struct page *get_node_page_ra(struct page *parent, int start) if (!nid) return ERR_PTR(-ENOENT); repeat: - page = grab_cache_page(mapping, nid); + page = grab_cache_page(NODE_MAPPING(sbi), nid); if (!page) return ERR_PTR(-ENOMEM); @@ -990,12 +1110,12 @@ struct page *get_node_page_ra(struct page *parent, int start) blk_finish_plug(&plug); lock_page(page); - if (page->mapping != mapping) { + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - if (!PageUptodate(page)) { + if (unlikely(!PageUptodate(page))) { f2fs_put_page(page, 1); return ERR_PTR(-EIO); } @@ -1021,7 +1141,6 @@ void sync_inode_page(struct dnode_of_data *dn) int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, struct writeback_control *wbc) { - struct address_space *mapping = sbi->node_inode->i_mapping; pgoff_t index, end; struct pagevec pvec; int step = ino ? 2 : 0; @@ -1035,7 +1154,7 @@ int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, while (index <= end) { int i, nr_pages; - nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index, PAGECACHE_TAG_DIRTY, min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); if (nr_pages == 0) @@ -1068,7 +1187,7 @@ int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, else if (!trylock_page(page)) continue; - if (unlikely(page->mapping != mapping)) { + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { continue_unlock: unlock_page(page); continue; @@ -1086,17 +1205,24 @@ int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, /* called by fsync() */ if (ino && IS_DNODE(page)) { - int mark = !is_checkpointed_node(sbi, ino); set_fsync_mark(page, 1); - if (IS_INODE(page)) - set_dentry_mark(page, mark); + if (IS_INODE(page)) { + if (!is_checkpointed_node(sbi, ino) && + !has_fsynced_inode(sbi, ino)) + set_dentry_mark(page, 1); + else + set_dentry_mark(page, 0); + } nwritten++; } else { set_fsync_mark(page, 0); set_dentry_mark(page, 0); } - mapping->a_ops->writepage(page, wbc); - wrote++; + + if (NODE_MAPPING(sbi)->a_ops->writepage(page, wbc)) + unlock_page(page); + else + wrote++; if (--wbc->nr_to_write == 0) break; @@ -1116,110 +1242,152 @@ int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, } if (wrote) - f2fs_submit_bio(sbi, NODE, wbc->sync_mode == WB_SYNC_ALL); - + f2fs_submit_merged_bio(sbi, NODE, WRITE); return nwritten; } +int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino) +{ + pgoff_t index = 0, end = LONG_MAX; + struct pagevec pvec; + int ret2 = 0, ret = 0; + + pagevec_init(&pvec, 0); + + while (index <= end) { + int i, nr_pages; + nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index, + PAGECACHE_TAG_WRITEBACK, + min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); + if (nr_pages == 0) + break; + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + /* until radix tree lookup accepts end_index */ + if (unlikely(page->index > end)) + continue; + + if (ino && ino_of_node(page) == ino) { + f2fs_wait_on_page_writeback(page, NODE); + if (TestClearPageError(page)) + ret = -EIO; + } + } + pagevec_release(&pvec); + cond_resched(); + } + + if (unlikely(test_and_clear_bit(AS_ENOSPC, &NODE_MAPPING(sbi)->flags))) + ret2 = -ENOSPC; + if (unlikely(test_and_clear_bit(AS_EIO, &NODE_MAPPING(sbi)->flags))) + ret2 = -EIO; + if (!ret) + ret = ret2; + return ret; +} + static int f2fs_write_node_page(struct page *page, struct writeback_control *wbc) { - struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); + struct f2fs_sb_info *sbi = F2FS_P_SB(page); nid_t nid; - block_t new_addr; struct node_info ni; + struct f2fs_io_info fio = { + .type = NODE, + .rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC : WRITE, + }; + + trace_f2fs_writepage(page, NODE); + + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) + goto redirty_out; + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; - wait_on_page_writeback(page); + f2fs_wait_on_page_writeback(page, NODE); /* get old block addr of this node page */ nid = nid_of_node(page); - BUG_ON(page->index != nid); + f2fs_bug_on(sbi, page->index != nid); get_node_info(sbi, nid, &ni); /* This page is already truncated */ - if (ni.blk_addr == NULL_ADDR) { + if (unlikely(ni.blk_addr == NULL_ADDR)) { + ClearPageUptodate(page); dec_page_count(sbi, F2FS_DIRTY_NODES); unlock_page(page); return 0; } if (wbc->for_reclaim) { - dec_page_count(sbi, F2FS_DIRTY_NODES); - wbc->pages_skipped++; - set_page_dirty(page); - return AOP_WRITEPAGE_ACTIVATE; + if (!down_read_trylock(&sbi->node_write)) + goto redirty_out; + } else { + down_read(&sbi->node_write); } - mutex_lock(&sbi->node_write); set_page_writeback(page); - write_node_page(sbi, page, nid, ni.blk_addr, &new_addr); - set_node_addr(sbi, &ni, new_addr); + fio.blk_addr = ni.blk_addr; + write_node_page(sbi, page, nid, &fio); + set_node_addr(sbi, &ni, fio.blk_addr, is_fsync_dnode(page)); dec_page_count(sbi, F2FS_DIRTY_NODES); - mutex_unlock(&sbi->node_write); + up_read(&sbi->node_write); unlock_page(page); + + if (wbc->for_reclaim) + f2fs_submit_merged_bio(sbi, NODE, WRITE); + return 0; + +redirty_out: + redirty_page_for_writepage(wbc, page); + return AOP_WRITEPAGE_ACTIVATE; } -/* - * It is very important to gather dirty pages and write at once, so that we can - * submit a big bio without interfering other data writes. - * Be default, 512 pages (2MB), a segment size, is quite reasonable. - */ -#define COLLECT_DIRTY_NODES 512 static int f2fs_write_node_pages(struct address_space *mapping, struct writeback_control *wbc) { - struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); - long nr_to_write = wbc->nr_to_write; + struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + long diff; - /* First check balancing cached NAT entries */ - if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { - f2fs_sync_fs(sbi->sb, true); - return 0; - } + trace_f2fs_writepages(mapping->host, wbc, NODE); + + /* balancing f2fs's metadata in background */ + f2fs_balance_fs_bg(sbi); /* collect a number of dirty node pages and write together */ - if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES) - return 0; + if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE)) + goto skip_write; - /* if mounting is failed, skip writing node pages */ - wbc->nr_to_write = max_hw_blocks(sbi); + diff = nr_pages_to_write(sbi, NODE, wbc); + wbc->sync_mode = WB_SYNC_NONE; sync_node_pages(sbi, 0, wbc); - wbc->nr_to_write = nr_to_write - (max_hw_blocks(sbi) - wbc->nr_to_write); + wbc->nr_to_write = max((long)0, wbc->nr_to_write - diff); + return 0; + +skip_write: + wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_NODES); return 0; } static int f2fs_set_node_page_dirty(struct page *page) { - struct address_space *mapping = page->mapping; - struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb); + trace_f2fs_set_page_dirty(page, NODE); SetPageUptodate(page); if (!PageDirty(page)) { __set_page_dirty_nobuffers(page); - inc_page_count(sbi, F2FS_DIRTY_NODES); + inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES); SetPagePrivate(page); + f2fs_trace_pid(page); return 1; } return 0; } -static void f2fs_invalidate_node_page(struct page *page, unsigned long offset) -{ - struct inode *inode = page->mapping->host; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - if (PageDirty(page)) - dec_page_count(sbi, F2FS_DIRTY_NODES); - ClearPagePrivate(page); -} - -static int f2fs_release_node_page(struct page *page, gfp_t wait) -{ - ClearPagePrivate(page); - return 1; -} - /* * Structure of the f2fs node operations */ @@ -1227,88 +1395,95 @@ const struct address_space_operations f2fs_node_aops = { .writepage = f2fs_write_node_page, .writepages = f2fs_write_node_pages, .set_page_dirty = f2fs_set_node_page_dirty, - .invalidatepage = f2fs_invalidate_node_page, - .releasepage = f2fs_release_node_page, + .invalidatepage = f2fs_invalidate_page, + .releasepage = f2fs_release_page, }; -static struct free_nid *__lookup_free_nid_list(nid_t n, struct list_head *head) +static struct free_nid *__lookup_free_nid_list(struct f2fs_nm_info *nm_i, + nid_t n) { - struct list_head *this; - struct free_nid *i; - list_for_each(this, head) { - i = list_entry(this, struct free_nid, list); - if (i->nid == n) - return i; - } - return NULL; + return radix_tree_lookup(&nm_i->free_nid_root, n); } -static void __del_from_free_nid_list(struct free_nid *i) +static void __del_from_free_nid_list(struct f2fs_nm_info *nm_i, + struct free_nid *i) { list_del(&i->list); - kmem_cache_free(free_nid_slab, i); + radix_tree_delete(&nm_i->free_nid_root, i->nid); } -static int add_free_nid(struct f2fs_nm_info *nm_i, nid_t nid, bool build) +static int add_free_nid(struct f2fs_sb_info *sbi, nid_t nid, bool build) { + struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *i; struct nat_entry *ne; bool allocated = false; - if (nm_i->fcnt > 2 * MAX_FREE_NIDS) + if (!available_free_memory(sbi, FREE_NIDS)) return -1; /* 0 nid should not be used */ - if (nid == 0) + if (unlikely(nid == 0)) return 0; - if (!build) - goto retry; - - /* do not add allocated nids */ - read_lock(&nm_i->nat_tree_lock); - ne = __lookup_nat_cache(nm_i, nid); - if (ne && nat_get_blkaddr(ne) != NULL_ADDR) - allocated = true; - read_unlock(&nm_i->nat_tree_lock); - if (allocated) - return 0; -retry: - i = kmem_cache_alloc(free_nid_slab, GFP_NOFS); - if (!i) { - cond_resched(); - goto retry; + if (build) { + /* do not add allocated nids */ + down_read(&nm_i->nat_tree_lock); + ne = __lookup_nat_cache(nm_i, nid); + if (ne && + (!get_nat_flag(ne, IS_CHECKPOINTED) || + nat_get_blkaddr(ne) != NULL_ADDR)) + allocated = true; + up_read(&nm_i->nat_tree_lock); + if (allocated) + return 0; } + + i = f2fs_kmem_cache_alloc(free_nid_slab, GFP_NOFS); i->nid = nid; i->state = NID_NEW; + if (radix_tree_preload(GFP_NOFS)) { + kmem_cache_free(free_nid_slab, i); + return 0; + } + spin_lock(&nm_i->free_nid_list_lock); - if (__lookup_free_nid_list(nid, &nm_i->free_nid_list)) { + if (radix_tree_insert(&nm_i->free_nid_root, i->nid, i)) { spin_unlock(&nm_i->free_nid_list_lock); + radix_tree_preload_end(); kmem_cache_free(free_nid_slab, i); return 0; } list_add_tail(&i->list, &nm_i->free_nid_list); nm_i->fcnt++; spin_unlock(&nm_i->free_nid_list_lock); + radix_tree_preload_end(); return 1; } static void remove_free_nid(struct f2fs_nm_info *nm_i, nid_t nid) { struct free_nid *i; + bool need_free = false; + spin_lock(&nm_i->free_nid_list_lock); - i = __lookup_free_nid_list(nid, &nm_i->free_nid_list); + i = __lookup_free_nid_list(nm_i, nid); if (i && i->state == NID_NEW) { - __del_from_free_nid_list(i); + __del_from_free_nid_list(nm_i, i); nm_i->fcnt--; + need_free = true; } spin_unlock(&nm_i->free_nid_list_lock); + + if (need_free) + kmem_cache_free(free_nid_slab, i); } -static void scan_nat_page(struct f2fs_nm_info *nm_i, +static void scan_nat_page(struct f2fs_sb_info *sbi, struct page *nat_page, nid_t start_nid) { + struct f2fs_nm_info *nm_i = NM_I(sbi); struct f2fs_nat_block *nat_blk = page_address(nat_page); block_t blk_addr; int i; @@ -1317,13 +1492,13 @@ static void scan_nat_page(struct f2fs_nm_info *nm_i, for (; i < NAT_ENTRY_PER_BLOCK; i++, start_nid++) { - if (start_nid >= nm_i->max_nid) + if (unlikely(start_nid >= nm_i->max_nid)) break; blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr); - BUG_ON(blk_addr == NEW_ADDR); + f2fs_bug_on(sbi, blk_addr == NEW_ADDR); if (blk_addr == NULL_ADDR) { - if (add_free_nid(nm_i, start_nid, true) < 0) + if (add_free_nid(sbi, start_nid, true) < 0) break; } } @@ -1342,16 +1517,16 @@ static void build_free_nids(struct f2fs_sb_info *sbi) return; /* readahead nat pages to be scanned */ - ra_nat_pages(sbi, nid); + ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT); while (1) { struct page *page = get_current_nat_page(sbi, nid); - scan_nat_page(nm_i, page, nid); + scan_nat_page(sbi, page, nid); f2fs_put_page(page, 1); nid += (NAT_ENTRY_PER_BLOCK - (nid % NAT_ENTRY_PER_BLOCK)); - if (nid >= nm_i->max_nid) + if (unlikely(nid >= nm_i->max_nid)) nid = 0; if (i++ == FREE_NID_PAGES) @@ -1367,7 +1542,7 @@ static void build_free_nids(struct f2fs_sb_info *sbi) block_t addr = le32_to_cpu(nat_in_journal(sum, i).block_addr); nid = le32_to_cpu(nid_in_journal(sum, i)); if (addr == NULL_ADDR) - add_free_nid(nm_i, nid, true); + add_free_nid(sbi, nid, true); else remove_free_nid(nm_i, nid); } @@ -1383,23 +1558,20 @@ bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *i = NULL; - struct list_head *this; retry: - if (sbi->total_valid_node_count + 1 >= nm_i->max_nid) + if (unlikely(sbi->total_valid_node_count + 1 > nm_i->available_nids)) return false; spin_lock(&nm_i->free_nid_list_lock); /* We should not use stale free nids created by build_free_nids */ - if (nm_i->fcnt && !sbi->on_build_free_nids) { - BUG_ON(list_empty(&nm_i->free_nid_list)); - list_for_each(this, &nm_i->free_nid_list) { - i = list_entry(this, struct free_nid, list); + if (nm_i->fcnt && !on_build_free_nids(nm_i)) { + f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list)); + list_for_each_entry(i, &nm_i->free_nid_list, list) if (i->state == NID_NEW) break; - } - BUG_ON(i->state != NID_NEW); + f2fs_bug_on(sbi, i->state != NID_NEW); *nid = i->nid; i->state = NID_ALLOC; nm_i->fcnt--; @@ -1410,9 +1582,7 @@ bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid) /* Let's scan nat pages and its caches to get free nids */ mutex_lock(&nm_i->build_lock); - sbi->on_build_free_nids = 1; build_free_nids(sbi); - sbi->on_build_free_nids = 0; mutex_unlock(&nm_i->build_lock); goto retry; } @@ -1426,10 +1596,12 @@ void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid) struct free_nid *i; spin_lock(&nm_i->free_nid_list_lock); - i = __lookup_free_nid_list(nid, &nm_i->free_nid_list); - BUG_ON(!i || i->state != NID_ALLOC); - __del_from_free_nid_list(i); + i = __lookup_free_nid_list(nm_i, nid); + f2fs_bug_on(sbi, !i || i->state != NID_ALLOC); + __del_from_free_nid_list(nm_i, i); spin_unlock(&nm_i->free_nid_list_lock); + + kmem_cache_free(free_nid_slab, i); } /* @@ -1439,62 +1611,130 @@ void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *i; + bool need_free = false; + + if (!nid) + return; spin_lock(&nm_i->free_nid_list_lock); - i = __lookup_free_nid_list(nid, &nm_i->free_nid_list); - BUG_ON(!i || i->state != NID_ALLOC); - if (nm_i->fcnt > 2 * MAX_FREE_NIDS) { - __del_from_free_nid_list(i); + i = __lookup_free_nid_list(nm_i, nid); + f2fs_bug_on(sbi, !i || i->state != NID_ALLOC); + if (!available_free_memory(sbi, FREE_NIDS)) { + __del_from_free_nid_list(nm_i, i); + need_free = true; } else { i->state = NID_NEW; nm_i->fcnt++; } spin_unlock(&nm_i->free_nid_list_lock); + + if (need_free) + kmem_cache_free(free_nid_slab, i); } -void recover_node_page(struct f2fs_sb_info *sbi, struct page *page, - struct f2fs_summary *sum, struct node_info *ni, - block_t new_blkaddr) +void recover_inline_xattr(struct inode *inode, struct page *page) { - rewrite_node_page(sbi, page, sum, ni->blk_addr, new_blkaddr); - set_node_addr(sbi, ni, new_blkaddr); - clear_node_page_dirty(page); + void *src_addr, *dst_addr; + size_t inline_size; + struct page *ipage; + struct f2fs_inode *ri; + + ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); + f2fs_bug_on(F2FS_I_SB(inode), IS_ERR(ipage)); + + ri = F2FS_INODE(page); + if (!(ri->i_inline & F2FS_INLINE_XATTR)) { + clear_inode_flag(F2FS_I(inode), FI_INLINE_XATTR); + goto update_inode; + } + + dst_addr = inline_xattr_addr(ipage); + src_addr = inline_xattr_addr(page); + inline_size = inline_xattr_size(inode); + + f2fs_wait_on_page_writeback(ipage, NODE); + memcpy(dst_addr, src_addr, inline_size); +update_inode: + update_inode(inode, ipage); + f2fs_put_page(ipage, 1); +} + +void recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid; + nid_t new_xnid = nid_of_node(page); + struct node_info ni; + + /* 1: invalidate the previous xattr nid */ + if (!prev_xnid) + goto recover_xnid; + + /* Deallocate node address */ + get_node_info(sbi, prev_xnid, &ni); + f2fs_bug_on(sbi, ni.blk_addr == NULL_ADDR); + invalidate_blocks(sbi, ni.blk_addr); + dec_valid_node_count(sbi, inode); + set_node_addr(sbi, &ni, NULL_ADDR, false); + +recover_xnid: + /* 2: allocate new xattr nid */ + if (unlikely(!inc_valid_node_count(sbi, inode))) + f2fs_bug_on(sbi, 1); + + remove_free_nid(NM_I(sbi), new_xnid); + get_node_info(sbi, new_xnid, &ni); + ni.ino = inode->i_ino; + set_node_addr(sbi, &ni, NEW_ADDR, false); + F2FS_I(inode)->i_xattr_nid = new_xnid; + + /* 3: update xattr blkaddr */ + refresh_sit_entry(sbi, NEW_ADDR, blkaddr); + set_node_addr(sbi, &ni, blkaddr, false); + + update_inode_page(inode); } int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) { - struct address_space *mapping = sbi->node_inode->i_mapping; - struct f2fs_node *src, *dst; + struct f2fs_inode *src, *dst; nid_t ino = ino_of_node(page); struct node_info old_ni, new_ni; struct page *ipage; - ipage = grab_cache_page(mapping, ino); + get_node_info(sbi, ino, &old_ni); + + if (unlikely(old_ni.blk_addr != NULL_ADDR)) + return -EINVAL; + + ipage = grab_cache_page(NODE_MAPPING(sbi), ino); if (!ipage) return -ENOMEM; - /* Should not use this inode from free nid list */ + /* Should not use this inode from free nid list */ remove_free_nid(NM_I(sbi), ino); - get_node_info(sbi, ino, &old_ni); SetPageUptodate(ipage); fill_node_footer(ipage, ino, ino, 0, true); - src = (struct f2fs_node *)page_address(page); - dst = (struct f2fs_node *)page_address(ipage); + src = F2FS_INODE(page); + dst = F2FS_INODE(ipage); - memcpy(dst, src, (unsigned long)&src->i.i_ext - (unsigned long)&src->i); - dst->i.i_size = 0; - dst->i.i_blocks = cpu_to_le64(1); - dst->i.i_links = cpu_to_le32(1); - dst->i.i_xattr_nid = 0; + memcpy(dst, src, (unsigned long)&src->i_ext - (unsigned long)src); + dst->i_size = 0; + dst->i_blocks = cpu_to_le64(1); + dst->i_links = cpu_to_le32(1); + dst->i_xattr_nid = 0; + dst->i_inline = src->i_inline & F2FS_INLINE_XATTR; new_ni = old_ni; new_ni.ino = ino; - set_node_addr(sbi, &new_ni, NEW_ADDR); + if (unlikely(!inc_valid_node_count(sbi, NULL))) + WARN_ON(1); + set_node_addr(sbi, &new_ni, NEW_ADDR, false); inc_valid_inode_count(sbi); - + set_page_dirty(ipage); f2fs_put_page(ipage, 1); return 0; } @@ -1504,45 +1744,39 @@ int restore_node_summary(struct f2fs_sb_info *sbi, { struct f2fs_node *rn; struct f2fs_summary *sum_entry; - struct page *page; block_t addr; - int i, last_offset; - - /* alloc temporal page for read node */ - page = alloc_page(GFP_NOFS | __GFP_ZERO); - if (IS_ERR(page)) - return PTR_ERR(page); - lock_page(page); + int bio_blocks = MAX_BIO_BLOCKS(sbi); + int i, idx, last_offset, nrpages; /* scan the node segment */ last_offset = sbi->blocks_per_seg; addr = START_BLOCK(sbi, segno); sum_entry = &sum->entries[0]; - for (i = 0; i < last_offset; i++, sum_entry++) { - /* - * In order to read next node page, - * we must clear PageUptodate flag. - */ - ClearPageUptodate(page); + for (i = 0; i < last_offset; i += nrpages, addr += nrpages) { + nrpages = min(last_offset - i, bio_blocks); - if (f2fs_readpage(sbi, page, addr, READ_SYNC)) - goto out; + /* readahead node pages */ + ra_meta_pages(sbi, addr, nrpages, META_POR); - lock_page(page); - rn = (struct f2fs_node *)page_address(page); - sum_entry->nid = rn->footer.nid; - sum_entry->version = 0; - sum_entry->ofs_in_node = 0; - addr++; + for (idx = addr; idx < addr + nrpages; idx++) { + struct page *page = get_meta_page(sbi, idx); + + rn = F2FS_NODE(page); + sum_entry->nid = rn->footer.nid; + sum_entry->version = 0; + sum_entry->ofs_in_node = 0; + sum_entry++; + f2fs_put_page(page, 1); + } + + invalidate_mapping_pages(META_MAPPING(sbi), addr, + addr + nrpages); } - unlock_page(page); -out: - __free_pages(page, 0); return 0; } -static bool flush_nats_in_journal(struct f2fs_sb_info *sbi) +static void remove_nats_in_journal(struct f2fs_sb_info *sbi) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); @@ -1550,134 +1784,154 @@ static bool flush_nats_in_journal(struct f2fs_sb_info *sbi) int i; mutex_lock(&curseg->curseg_mutex); - - if (nats_in_cursum(sum) < NAT_JOURNAL_ENTRIES) { - mutex_unlock(&curseg->curseg_mutex); - return false; - } - for (i = 0; i < nats_in_cursum(sum); i++) { struct nat_entry *ne; struct f2fs_nat_entry raw_ne; nid_t nid = le32_to_cpu(nid_in_journal(sum, i)); raw_ne = nat_in_journal(sum, i); -retry: - write_lock(&nm_i->nat_tree_lock); + + down_write(&nm_i->nat_tree_lock); ne = __lookup_nat_cache(nm_i, nid); - if (ne) { - __set_nat_cache_dirty(nm_i, ne); - write_unlock(&nm_i->nat_tree_lock); - continue; - } - ne = grab_nat_entry(nm_i, nid); if (!ne) { - write_unlock(&nm_i->nat_tree_lock); - goto retry; + ne = grab_nat_entry(nm_i, nid); + node_info_from_raw_nat(&ne->ni, &raw_ne); } - nat_set_blkaddr(ne, le32_to_cpu(raw_ne.block_addr)); - nat_set_ino(ne, le32_to_cpu(raw_ne.ino)); - nat_set_version(ne, raw_ne.version); __set_nat_cache_dirty(nm_i, ne); - write_unlock(&nm_i->nat_tree_lock); + up_write(&nm_i->nat_tree_lock); } update_nats_in_cursum(sum, -i); mutex_unlock(&curseg->curseg_mutex); - return true; } -/* - * This function is called during the checkpointing process. - */ -void flush_nat_entries(struct f2fs_sb_info *sbi) +static void __adjust_nat_entry_set(struct nat_entry_set *nes, + struct list_head *head, int max) +{ + struct nat_entry_set *cur; + + if (nes->entry_cnt >= max) + goto add_out; + + list_for_each_entry(cur, head, set_list) { + if (cur->entry_cnt >= nes->entry_cnt) { + list_add(&nes->set_list, cur->set_list.prev); + return; + } + } +add_out: + list_add_tail(&nes->set_list, head); +} + +static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, + struct nat_entry_set *set) { - struct f2fs_nm_info *nm_i = NM_I(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); struct f2fs_summary_block *sum = curseg->sum_blk; - struct list_head *cur, *n; + nid_t start_nid = set->set * NAT_ENTRY_PER_BLOCK; + bool to_journal = true; + struct f2fs_nat_block *nat_blk; + struct nat_entry *ne, *cur; struct page *page = NULL; - struct f2fs_nat_block *nat_blk = NULL; - nid_t start_nid = 0, end_nid = 0; - bool flushed; + struct f2fs_nm_info *nm_i = NM_I(sbi); - flushed = flush_nats_in_journal(sbi); + /* + * there are two steps to flush nat entries: + * #1, flush nat entries to journal in current hot data summary block. + * #2, flush nat entries to nat page. + */ + if (!__has_cursum_space(sum, set->entry_cnt, NAT_JOURNAL)) + to_journal = false; - if (!flushed) + if (to_journal) { mutex_lock(&curseg->curseg_mutex); + } else { + page = get_next_nat_page(sbi, start_nid); + nat_blk = page_address(page); + f2fs_bug_on(sbi, !nat_blk); + } - /* 1) flush dirty nat caches */ - list_for_each_safe(cur, n, &nm_i->dirty_nat_entries) { - struct nat_entry *ne; - nid_t nid; - struct f2fs_nat_entry raw_ne; - int offset = -1; - block_t new_blkaddr; - - ne = list_entry(cur, struct nat_entry, list); - nid = nat_get_nid(ne); + /* flush dirty nats in nat entry set */ + list_for_each_entry_safe(ne, cur, &set->entry_list, list) { + struct f2fs_nat_entry *raw_ne; + nid_t nid = nat_get_nid(ne); + int offset; if (nat_get_blkaddr(ne) == NEW_ADDR) continue; - if (flushed) - goto to_nat_page; - - /* if there is room for nat enries in curseg->sumpage */ - offset = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 1); - if (offset >= 0) { - raw_ne = nat_in_journal(sum, offset); - goto flush_now; - } -to_nat_page: - if (!page || (start_nid > nid || nid > end_nid)) { - if (page) { - f2fs_put_page(page, 1); - page = NULL; - } - start_nid = START_NID(nid); - end_nid = start_nid + NAT_ENTRY_PER_BLOCK - 1; - /* - * get nat block with dirty flag, increased reference - * count, mapped and lock - */ - page = get_next_nat_page(sbi, start_nid); - nat_blk = page_address(page); + if (to_journal) { + offset = lookup_journal_in_cursum(sum, + NAT_JOURNAL, nid, 1); + f2fs_bug_on(sbi, offset < 0); + raw_ne = &nat_in_journal(sum, offset); + nid_in_journal(sum, offset) = cpu_to_le32(nid); + } else { + raw_ne = &nat_blk->entries[nid - start_nid]; } + raw_nat_from_node_info(raw_ne, &ne->ni); - BUG_ON(!nat_blk); - raw_ne = nat_blk->entries[nid - start_nid]; -flush_now: - new_blkaddr = nat_get_blkaddr(ne); + down_write(&NM_I(sbi)->nat_tree_lock); + nat_reset_flag(ne); + __clear_nat_cache_dirty(NM_I(sbi), ne); + up_write(&NM_I(sbi)->nat_tree_lock); - raw_ne.ino = cpu_to_le32(nat_get_ino(ne)); - raw_ne.block_addr = cpu_to_le32(new_blkaddr); - raw_ne.version = nat_get_version(ne); + if (nat_get_blkaddr(ne) == NULL_ADDR) + add_free_nid(sbi, nid, false); + } - if (offset < 0) { - nat_blk->entries[nid - start_nid] = raw_ne; - } else { - nat_in_journal(sum, offset) = raw_ne; - nid_in_journal(sum, offset) = cpu_to_le32(nid); - } + if (to_journal) + mutex_unlock(&curseg->curseg_mutex); + else + f2fs_put_page(page, 1); - if (nat_get_blkaddr(ne) == NULL_ADDR && - add_free_nid(NM_I(sbi), nid, false) <= 0) { - write_lock(&nm_i->nat_tree_lock); - __del_from_nat_cache(nm_i, ne); - write_unlock(&nm_i->nat_tree_lock); - } else { - write_lock(&nm_i->nat_tree_lock); - __clear_nat_cache_dirty(nm_i, ne); - ne->checkpointed = true; - write_unlock(&nm_i->nat_tree_lock); - } + f2fs_bug_on(sbi, set->entry_cnt); + + down_write(&nm_i->nat_tree_lock); + radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); + up_write(&nm_i->nat_tree_lock); + kmem_cache_free(nat_entry_set_slab, set); +} + +/* + * This function is called during the checkpointing process. + */ +void flush_nat_entries(struct f2fs_sb_info *sbi) +{ + struct f2fs_nm_info *nm_i = NM_I(sbi); + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); + struct f2fs_summary_block *sum = curseg->sum_blk; + struct nat_entry_set *setvec[SETVEC_SIZE]; + struct nat_entry_set *set, *tmp; + unsigned int found; + nid_t set_idx = 0; + LIST_HEAD(sets); + + if (!nm_i->dirty_nat_cnt) + return; + /* + * if there are no enough space in journal to store dirty nat + * entries, remove all entries from journal and merge them + * into nat entry set. + */ + if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) + remove_nats_in_journal(sbi); + + down_write(&nm_i->nat_tree_lock); + while ((found = __gang_lookup_nat_set(nm_i, + set_idx, SETVEC_SIZE, setvec))) { + unsigned idx; + set_idx = setvec[found - 1]->set + 1; + for (idx = 0; idx < found; idx++) + __adjust_nat_entry_set(setvec[idx], &sets, + MAX_NAT_JENTRIES(sum)); } - if (!flushed) - mutex_unlock(&curseg->curseg_mutex); - f2fs_put_page(page, 1); + up_write(&nm_i->nat_tree_lock); + + /* flush dirty nats in nat entry set */ + list_for_each_entry_safe(set, tmp, &sets, set_list) + __flush_nat_entry_set(sbi, set); - /* 2) shrink nat caches if necessary */ - try_to_free_nats(sbi, nm_i->nat_cnt - NM_WOUT_THRESHOLD); + f2fs_bug_on(sbi, nm_i->dirty_nat_cnt); } static int init_node_manager(struct f2fs_sb_info *sbi) @@ -1692,18 +1946,24 @@ static int init_node_manager(struct f2fs_sb_info *sbi) /* segment_count_nat includes pair segment so divide to 2. */ nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1; nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg); + nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks; + + /* not used nids: 0, node, meta, (and root counted as valid node) */ + nm_i->available_nids = nm_i->max_nid - F2FS_RESERVED_NODE_NUM; nm_i->fcnt = 0; nm_i->nat_cnt = 0; + nm_i->ram_thresh = DEF_RAM_THRESHOLD; + INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); INIT_LIST_HEAD(&nm_i->free_nid_list); - INIT_RADIX_TREE(&nm_i->nat_root, GFP_ATOMIC); + INIT_RADIX_TREE(&nm_i->nat_root, GFP_NOIO); + INIT_RADIX_TREE(&nm_i->nat_set_root, GFP_NOIO); INIT_LIST_HEAD(&nm_i->nat_entries); - INIT_LIST_HEAD(&nm_i->dirty_nat_entries); mutex_init(&nm_i->build_lock); spin_lock_init(&nm_i->free_nid_list_lock); - rwlock_init(&nm_i->nat_tree_lock); + init_rwsem(&nm_i->nat_tree_lock); nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid); nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP); @@ -1739,6 +1999,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *i, *next_i; struct nat_entry *natvec[NATVEC_SIZE]; + struct nat_entry_set *setvec[SETVEC_SIZE]; nid_t nid = 0; unsigned int found; @@ -1748,26 +2009,43 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) /* destroy free nid list */ spin_lock(&nm_i->free_nid_list_lock); list_for_each_entry_safe(i, next_i, &nm_i->free_nid_list, list) { - BUG_ON(i->state == NID_ALLOC); - __del_from_free_nid_list(i); + f2fs_bug_on(sbi, i->state == NID_ALLOC); + __del_from_free_nid_list(nm_i, i); nm_i->fcnt--; + spin_unlock(&nm_i->free_nid_list_lock); + kmem_cache_free(free_nid_slab, i); + spin_lock(&nm_i->free_nid_list_lock); } - BUG_ON(nm_i->fcnt); + f2fs_bug_on(sbi, nm_i->fcnt); spin_unlock(&nm_i->free_nid_list_lock); /* destroy nat cache */ - write_lock(&nm_i->nat_tree_lock); + down_write(&nm_i->nat_tree_lock); while ((found = __gang_lookup_nat_cache(nm_i, nid, NATVEC_SIZE, natvec))) { unsigned idx; + + nid = nat_get_nid(natvec[found - 1]) + 1; + for (idx = 0; idx < found; idx++) + __del_from_nat_cache(nm_i, natvec[idx]); + } + f2fs_bug_on(sbi, nm_i->nat_cnt); + + /* destroy nat set cache */ + nid = 0; + while ((found = __gang_lookup_nat_set(nm_i, + nid, SETVEC_SIZE, setvec))) { + unsigned idx; + + nid = setvec[found - 1]->set + 1; for (idx = 0; idx < found; idx++) { - struct nat_entry *e = natvec[idx]; - nid = nat_get_nid(e) + 1; - __del_from_nat_cache(nm_i, e); + /* entry_cnt is not zero, when cp_error was occurred */ + f2fs_bug_on(sbi, !list_empty(&setvec[idx]->entry_list)); + radix_tree_delete(&nm_i->nat_set_root, setvec[idx]->set); + kmem_cache_free(nat_entry_set_slab, setvec[idx]); } } - BUG_ON(nm_i->nat_cnt); - write_unlock(&nm_i->nat_tree_lock); + up_write(&nm_i->nat_tree_lock); kfree(nm_i->nat_bitmap); sbi->nm_info = NULL; @@ -1777,21 +2055,32 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) int __init create_node_manager_caches(void) { nat_entry_slab = f2fs_kmem_cache_create("nat_entry", - sizeof(struct nat_entry), NULL); + sizeof(struct nat_entry)); if (!nat_entry_slab) - return -ENOMEM; + goto fail; free_nid_slab = f2fs_kmem_cache_create("free_nid", - sizeof(struct free_nid), NULL); - if (!free_nid_slab) { - kmem_cache_destroy(nat_entry_slab); - return -ENOMEM; - } + sizeof(struct free_nid)); + if (!free_nid_slab) + goto destroy_nat_entry; + + nat_entry_set_slab = f2fs_kmem_cache_create("nat_entry_set", + sizeof(struct nat_entry_set)); + if (!nat_entry_set_slab) + goto destroy_free_nid; return 0; + +destroy_free_nid: + kmem_cache_destroy(free_nid_slab); +destroy_nat_entry: + kmem_cache_destroy(nat_entry_slab); +fail: + return -ENOMEM; } void destroy_node_manager_caches(void) { + kmem_cache_destroy(nat_entry_set_slab); kmem_cache_destroy(free_nid_slab); kmem_cache_destroy(nat_entry_slab); } diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 0a2d72f0024dd..c56026f1725c9 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -17,21 +17,27 @@ /* # of pages to perform readahead before building free nids */ #define FREE_NID_PAGES 4 -/* maximum # of free node ids to produce during build_free_nids */ -#define MAX_FREE_NIDS (NAT_ENTRY_PER_BLOCK * FREE_NID_PAGES) - /* maximum readahead size for node during getting data blocks */ #define MAX_RA_NODE 128 -/* maximum cached nat entries to manage memory footprint */ -#define NM_WOUT_THRESHOLD (64 * NAT_ENTRY_PER_BLOCK) +/* control the memory footprint threshold (10MB per 1GB ram) */ +#define DEF_RAM_THRESHOLD 10 /* vector size for gang look-up from nat cache that consists of radix tree */ #define NATVEC_SIZE 64 +#define SETVEC_SIZE 32 /* return value for read_node_page */ #define LOCKED_PAGE 1 +/* For flag in struct node_info */ +enum { + IS_CHECKPOINTED, /* is it checkpointed before? */ + HAS_FSYNCED_INODE, /* is the inode fsynced before? */ + HAS_LAST_FSYNC, /* has the latest node fsync mark? */ + IS_DIRTY, /* this nat entry is dirty? */ +}; + /* * For node information */ @@ -40,11 +46,11 @@ struct node_info { nid_t ino; /* inode number of the node's owner */ block_t blk_addr; /* block address of the node */ unsigned char version; /* version of the node */ + unsigned char flag; /* for node information bits */ }; struct nat_entry { struct list_head list; /* for clean or dirty nat list */ - bool checkpointed; /* whether it is checkpointed or not */ struct node_info ni; /* in-memory node information */ }; @@ -57,12 +63,42 @@ struct nat_entry { #define nat_get_version(nat) (nat->ni.version) #define nat_set_version(nat, v) (nat->ni.version = v) -#define __set_nat_cache_dirty(nm_i, ne) \ - list_move_tail(&ne->list, &nm_i->dirty_nat_entries); -#define __clear_nat_cache_dirty(nm_i, ne) \ - list_move_tail(&ne->list, &nm_i->nat_entries); #define inc_node_version(version) (++version) +static inline void copy_node_info(struct node_info *dst, + struct node_info *src) +{ + dst->nid = src->nid; + dst->ino = src->ino; + dst->blk_addr = src->blk_addr; + dst->version = src->version; + /* should not copy flag here */ +} + +static inline void set_nat_flag(struct nat_entry *ne, + unsigned int type, bool set) +{ + unsigned char mask = 0x01 << type; + if (set) + ne->ni.flag |= mask; + else + ne->ni.flag &= ~mask; +} + +static inline bool get_nat_flag(struct nat_entry *ne, unsigned int type) +{ + unsigned char mask = 0x01 << type; + return ne->ni.flag & mask; +} + +static inline void nat_reset_flag(struct nat_entry *ne) +{ + /* these states can be set only after checkpoint was done */ + set_nat_flag(ne, IS_CHECKPOINTED, true); + set_nat_flag(ne, HAS_FSYNCED_INODE, false); + set_nat_flag(ne, HAS_LAST_FSYNC, true); +} + static inline void node_info_from_raw_nat(struct node_info *ni, struct f2fs_nat_entry *raw_ne) { @@ -71,6 +107,30 @@ static inline void node_info_from_raw_nat(struct node_info *ni, ni->version = raw_ne->version; } +static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, + struct node_info *ni) +{ + raw_ne->ino = cpu_to_le32(ni->ino); + raw_ne->block_addr = cpu_to_le32(ni->blk_addr); + raw_ne->version = ni->version; +} + +enum mem_type { + FREE_NIDS, /* indicates the free nid list */ + NAT_ENTRIES, /* indicates the cached nat entry */ + DIRTY_DENTS, /* indicates dirty dentry pages */ + INO_ENTRIES, /* indicates inode entries */ + EXTENT_CACHE, /* indicates extent cache */ + BASE_CHECK, /* check kernel status */ +}; + +struct nat_entry_set { + struct list_head set_list; /* link with other nat sets */ + struct list_head entry_list; /* link with dirty nat entries */ + nid_t set; /* set number*/ + unsigned int entry_cnt; /* the # of nat entries in set */ +}; + /* * For free nid mangement */ @@ -85,18 +145,19 @@ struct free_nid { int state; /* in use or not: NID_NEW or NID_ALLOC */ }; -static inline int next_free_nid(struct f2fs_sb_info *sbi, nid_t *nid) +static inline void next_free_nid(struct f2fs_sb_info *sbi, nid_t *nid) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct free_nid *fnid; - if (nm_i->fcnt <= 0) - return -1; spin_lock(&nm_i->free_nid_list_lock); + if (nm_i->fcnt <= 0) { + spin_unlock(&nm_i->free_nid_list_lock); + return; + } fnid = list_entry(nm_i->free_nid_list.next, struct free_nid, list); *nid = fnid->nid; spin_unlock(&nm_i->free_nid_list_lock); - return 0; } /* @@ -146,76 +207,72 @@ static inline void set_to_next_nat(struct f2fs_nm_info *nm_i, nid_t start_nid) { unsigned int block_off = NAT_BLOCK_OFFSET(start_nid); - if (f2fs_test_bit(block_off, nm_i->nat_bitmap)) - f2fs_clear_bit(block_off, nm_i->nat_bitmap); - else - f2fs_set_bit(block_off, nm_i->nat_bitmap); + f2fs_change_bit(block_off, nm_i->nat_bitmap); } static inline void fill_node_footer(struct page *page, nid_t nid, nid_t ino, unsigned int ofs, bool reset) { - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(page); + unsigned int old_flag = 0; + if (reset) memset(rn, 0, sizeof(*rn)); + else + old_flag = le32_to_cpu(rn->footer.flag); + rn->footer.nid = cpu_to_le32(nid); rn->footer.ino = cpu_to_le32(ino); - rn->footer.flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT); + + /* should remain old flag bits such as COLD_BIT_SHIFT */ + rn->footer.flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) | + (old_flag & OFFSET_BIT_MASK)); } static inline void copy_node_footer(struct page *dst, struct page *src) { - void *src_addr = page_address(src); - void *dst_addr = page_address(dst); - struct f2fs_node *src_rn = (struct f2fs_node *)src_addr; - struct f2fs_node *dst_rn = (struct f2fs_node *)dst_addr; + struct f2fs_node *src_rn = F2FS_NODE(src); + struct f2fs_node *dst_rn = F2FS_NODE(dst); memcpy(&dst_rn->footer, &src_rn->footer, sizeof(struct node_footer)); } static inline void fill_node_footer_blkaddr(struct page *page, block_t blkaddr) { - struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); - struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_checkpoint *ckpt = F2FS_CKPT(F2FS_P_SB(page)); + struct f2fs_node *rn = F2FS_NODE(page); + rn->footer.cp_ver = ckpt->checkpoint_ver; rn->footer.next_blkaddr = cpu_to_le32(blkaddr); } static inline nid_t ino_of_node(struct page *node_page) { - void *kaddr = page_address(node_page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(node_page); return le32_to_cpu(rn->footer.ino); } static inline nid_t nid_of_node(struct page *node_page) { - void *kaddr = page_address(node_page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(node_page); return le32_to_cpu(rn->footer.nid); } static inline unsigned int ofs_of_node(struct page *node_page) { - void *kaddr = page_address(node_page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(node_page); unsigned flag = le32_to_cpu(rn->footer.flag); return flag >> OFFSET_BIT_SHIFT; } static inline unsigned long long cpver_of_node(struct page *node_page) { - void *kaddr = page_address(node_page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(node_page); return le64_to_cpu(rn->footer.cp_ver); } static inline block_t next_blkaddr_of_node(struct page *node_page) { - void *kaddr = page_address(node_page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(node_page); return le32_to_cpu(rn->footer.next_blkaddr); } @@ -232,11 +289,21 @@ static inline block_t next_blkaddr_of_node(struct page *node_page) * | `- direct node (5 + N => 5 + 2N - 1) * `- double indirect node (5 + 2N) * `- indirect node (6 + 2N) - * `- direct node (x(N + 1)) + * `- direct node + * ...... + * `- indirect node ((6 + 2N) + x(N + 1)) + * `- direct node + * ...... + * `- indirect node ((6 + 2N) + (N - 1)(N + 1)) + * `- direct node */ static inline bool IS_DNODE(struct page *node_page) { unsigned int ofs = ofs_of_node(node_page); + + if (f2fs_has_xattr_block(ofs)) + return false; + if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK || ofs == 5 + 2 * NIDS_PER_BLOCK) return false; @@ -250,9 +317,9 @@ static inline bool IS_DNODE(struct page *node_page) static inline void set_nid(struct page *p, int off, nid_t nid, bool i) { - struct f2fs_node *rn = (struct f2fs_node *)page_address(p); + struct f2fs_node *rn = F2FS_NODE(p); - wait_on_page_writeback(p); + f2fs_wait_on_page_writeback(p, NODE); if (i) rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); @@ -263,7 +330,8 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i) static inline nid_t get_nid(struct page *p, int off, bool i) { - struct f2fs_node *rn = (struct f2fs_node *)page_address(p); + struct f2fs_node *rn = F2FS_NODE(p); + if (i) return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]); return le32_to_cpu(rn->in.nid[off]); @@ -275,25 +343,27 @@ static inline nid_t get_nid(struct page *p, int off, bool i) * - Mark cold node blocks in their node footer * - Mark cold data pages in page cache */ -static inline int is_cold_file(struct inode *inode) +static inline int is_file(struct inode *inode, int type) { - return F2FS_I(inode)->i_advise & FADVISE_COLD_BIT; + return F2FS_I(inode)->i_advise & type; } -static inline void set_cold_file(struct inode *inode) +static inline void set_file(struct inode *inode, int type) { - F2FS_I(inode)->i_advise |= FADVISE_COLD_BIT; + F2FS_I(inode)->i_advise |= type; } -static inline int is_cp_file(struct inode *inode) +static inline void clear_file(struct inode *inode, int type) { - return F2FS_I(inode)->i_advise & FADVISE_CP_BIT; + F2FS_I(inode)->i_advise &= ~type; } -static inline void set_cp_file(struct inode *inode) -{ - F2FS_I(inode)->i_advise |= FADVISE_CP_BIT; -} +#define file_is_cold(inode) is_file(inode, FADVISE_COLD_BIT) +#define file_wrong_pino(inode) is_file(inode, FADVISE_LOST_PINO_BIT) +#define file_set_cold(inode) set_file(inode, FADVISE_COLD_BIT) +#define file_lost_pino(inode) set_file(inode, FADVISE_LOST_PINO_BIT) +#define file_clear_cold(inode) clear_file(inode, FADVISE_COLD_BIT) +#define file_got_pino(inode) clear_file(inode, FADVISE_LOST_PINO_BIT) static inline int is_cold_data(struct page *page) { @@ -310,33 +380,19 @@ static inline void clear_cold_data(struct page *page) ClearPageChecked(page); } -static inline int is_cold_node(struct page *page) -{ - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; - unsigned int flag = le32_to_cpu(rn->footer.flag); - return flag & (0x1 << COLD_BIT_SHIFT); -} - -static inline unsigned char is_fsync_dnode(struct page *page) +static inline int is_node(struct page *page, int type) { - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; - unsigned int flag = le32_to_cpu(rn->footer.flag); - return flag & (0x1 << FSYNC_BIT_SHIFT); + struct f2fs_node *rn = F2FS_NODE(page); + return le32_to_cpu(rn->footer.flag) & (1 << type); } -static inline unsigned char is_dent_dnode(struct page *page) -{ - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; - unsigned int flag = le32_to_cpu(rn->footer.flag); - return flag & (0x1 << DENT_BIT_SHIFT); -} +#define is_cold_node(page) is_node(page, COLD_BIT_SHIFT) +#define is_fsync_dnode(page) is_node(page, FSYNC_BIT_SHIFT) +#define is_dent_dnode(page) is_node(page, DENT_BIT_SHIFT) static inline void set_cold_node(struct inode *inode, struct page *page) { - struct f2fs_node *rn = (struct f2fs_node *)page_address(page); + struct f2fs_node *rn = F2FS_NODE(page); unsigned int flag = le32_to_cpu(rn->footer.flag); if (S_ISDIR(inode->i_mode)) @@ -346,26 +402,15 @@ static inline void set_cold_node(struct inode *inode, struct page *page) rn->footer.flag = cpu_to_le32(flag); } -static inline void set_fsync_mark(struct page *page, int mark) -{ - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; - unsigned int flag = le32_to_cpu(rn->footer.flag); - if (mark) - flag |= (0x1 << FSYNC_BIT_SHIFT); - else - flag &= ~(0x1 << FSYNC_BIT_SHIFT); - rn->footer.flag = cpu_to_le32(flag); -} - -static inline void set_dentry_mark(struct page *page, int mark) +static inline void set_mark(struct page *page, int mark, int type) { - void *kaddr = page_address(page); - struct f2fs_node *rn = (struct f2fs_node *)kaddr; + struct f2fs_node *rn = F2FS_NODE(page); unsigned int flag = le32_to_cpu(rn->footer.flag); if (mark) - flag |= (0x1 << DENT_BIT_SHIFT); + flag |= (0x1 << type); else - flag &= ~(0x1 << DENT_BIT_SHIFT); + flag &= ~(0x1 << type); rn->footer.flag = cpu_to_le32(flag); } +#define set_dentry_mark(page, mark) set_mark(page, mark, DENT_BIT_SHIFT) +#define set_fsync_mark(page, mark) set_mark(page, mark, FSYNC_BIT_SHIFT) diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 60c8a5097058f..0d4866b7c8b50 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -14,6 +14,37 @@ #include "node.h" #include "segment.h" +/* + * Roll forward recovery scenarios. + * + * [Term] F: fsync_mark, D: dentry_mark + * + * 1. inode(x) | CP | inode(x) | dnode(F) + * -> Update the latest inode(x). + * + * 2. inode(x) | CP | inode(F) | dnode(F) + * -> No problem. + * + * 3. inode(x) | CP | dnode(F) | inode(x) + * -> Recover to the latest dnode(F), and drop the last inode(x) + * + * 4. inode(x) | CP | dnode(F) | inode(F) + * -> No problem. + * + * 5. CP | inode(x) | dnode(F) + * -> The inode(DF) was missing. Should drop this dnode(F). + * + * 6. CP | inode(DF) | dnode(F) + * -> No problem. + * + * 7. CP | dnode(F) | inode(DF) + * -> If f2fs_iget fails, then goto next to find inode(DF). + * + * 8. CP | dnode(F) | inode(x) + * -> If f2fs_iget fails, then goto next to find inode(DF). + * But it will fail due to no inode(DF). + */ + static struct kmem_cache *fsync_entry_slab; bool space_for_roll_forward(struct f2fs_sb_info *sbi) @@ -27,31 +58,26 @@ bool space_for_roll_forward(struct f2fs_sb_info *sbi) static struct fsync_inode_entry *get_fsync_inode(struct list_head *head, nid_t ino) { - struct list_head *this; struct fsync_inode_entry *entry; - list_for_each(this, head) { - entry = list_entry(this, struct fsync_inode_entry, list); + list_for_each_entry(entry, head, list) if (entry->inode->i_ino == ino) return entry; - } + return NULL; } -static int recover_dentry(struct page *ipage, struct inode *inode) +static int recover_dentry(struct inode *inode, struct page *ipage) { - struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage); - struct f2fs_inode *raw_inode = &(raw_node->i); - struct qstr name; + struct f2fs_inode *raw_inode = F2FS_INODE(ipage); + nid_t pino = le32_to_cpu(raw_inode->i_pino); struct f2fs_dir_entry *de; + struct qstr name; struct page *page; - struct inode *dir; + struct inode *dir, *einode; int err = 0; - if (!is_dent_dnode(ipage)) - goto out; - - dir = f2fs_iget(inode->i_sb, le32_to_cpu(raw_inode->i_pino)); + dir = f2fs_iget(inode->i_sb, pino); if (IS_ERR(dir)) { err = PTR_ERR(dir); goto out; @@ -60,122 +86,154 @@ static int recover_dentry(struct page *ipage, struct inode *inode) name.len = le32_to_cpu(raw_inode->i_namelen); name.name = raw_inode->i_name; + if (unlikely(name.len > F2FS_NAME_LEN)) { + WARN_ON(1); + err = -ENAMETOOLONG; + goto out_err; + } +retry: de = f2fs_find_entry(dir, &name, &page); + if (de && inode->i_ino == le32_to_cpu(de->ino)) + goto out_unmap_put; + if (de) { - kunmap(page); - f2fs_put_page(page, 0); + einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino)); + if (IS_ERR(einode)) { + WARN_ON(1); + err = PTR_ERR(einode); + if (err == -ENOENT) + err = -EEXIST; + goto out_unmap_put; + } + err = acquire_orphan_inode(F2FS_I_SB(inode)); + if (err) { + iput(einode); + goto out_unmap_put; + } + f2fs_delete_entry(de, page, dir, einode); + iput(einode); + goto retry; + } + err = __f2fs_add_link(dir, &name, inode, inode->i_ino, inode->i_mode); + if (err) + goto out_err; + + if (is_inode_flag_set(F2FS_I(dir), FI_DELAY_IPUT)) { + iput(dir); } else { - err = __f2fs_add_link(dir, &name, inode); + add_dirty_dir_inode(dir); + set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT); } + + goto out; + +out_unmap_put: + f2fs_dentry_kunmap(dir, page); + f2fs_put_page(page, 0); +out_err: iput(dir); out: - kunmap(ipage); + f2fs_msg(inode->i_sb, KERN_NOTICE, + "%s: ino = %x, name = %s, dir = %lx, err = %d", + __func__, ino_of_node(ipage), raw_inode->i_name, + IS_ERR(dir) ? 0 : dir->i_ino, err); return err; } -static int recover_inode(struct inode *inode, struct page *node_page) +static void recover_inode(struct inode *inode, struct page *page) { - void *kaddr = page_address(node_page); - struct f2fs_node *raw_node = (struct f2fs_node *)kaddr; - struct f2fs_inode *raw_inode = &(raw_node->i); - - inode->i_mode = le16_to_cpu(raw_inode->i_mode); - i_size_write(inode, le64_to_cpu(raw_inode->i_size)); - inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime); - inode->i_ctime.tv_sec = le64_to_cpu(raw_inode->i_ctime); - inode->i_mtime.tv_sec = le64_to_cpu(raw_inode->i_mtime); - inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec); - inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec); - inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec); - - return recover_dentry(node_page, inode); + struct f2fs_inode *raw = F2FS_INODE(page); + + inode->i_mode = le16_to_cpu(raw->i_mode); + i_size_write(inode, le64_to_cpu(raw->i_size)); + inode->i_atime.tv_sec = le64_to_cpu(raw->i_mtime); + inode->i_ctime.tv_sec = le64_to_cpu(raw->i_ctime); + inode->i_mtime.tv_sec = le64_to_cpu(raw->i_mtime); + inode->i_atime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); + inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec); + inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec); + + f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode: ino = %x, name = %s", + ino_of_node(page), F2FS_INODE(page)->i_name); } static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) { - unsigned long long cp_ver = le64_to_cpu(sbi->ckpt->checkpoint_ver); + unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi)); struct curseg_info *curseg; - struct page *page; + struct page *page = NULL; block_t blkaddr; int err = 0; /* get node pages in the current segment */ curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); - blkaddr = START_BLOCK(sbi, curseg->segno) + curseg->next_blkoff; + blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); - /* read node page */ - page = alloc_page(GFP_F2FS_ZERO); - if (IS_ERR(page)) - return PTR_ERR(page); - lock_page(page); + ra_meta_pages(sbi, blkaddr, 1, META_POR); while (1) { struct fsync_inode_entry *entry; - err = f2fs_readpage(sbi, page, blkaddr, READ_SYNC); - if (err) - goto out; + if (blkaddr < MAIN_BLKADDR(sbi) || blkaddr >= MAX_BLKADDR(sbi)) + return 0; - lock_page(page); + page = get_meta_page(sbi, blkaddr); if (cp_ver != cpver_of_node(page)) - goto unlock_out; + break; if (!is_fsync_dnode(page)) goto next; entry = get_fsync_inode(head, ino_of_node(page)); - if (entry) { - entry->blkaddr = blkaddr; - if (IS_INODE(page) && is_dent_dnode(page)) - set_inode_flag(F2FS_I(entry->inode), - FI_INC_LINK); - } else { + if (!entry) { if (IS_INODE(page) && is_dent_dnode(page)) { err = recover_inode_page(sbi, page); if (err) - goto unlock_out; + break; } /* add this fsync inode to the list */ - entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS); + entry = kmem_cache_alloc(fsync_entry_slab, GFP_F2FS_ZERO); if (!entry) { err = -ENOMEM; - goto unlock_out; + break; } - + /* + * CP | dnode(F) | inode(DF) + * For this case, we should not give up now. + */ entry->inode = f2fs_iget(sbi->sb, ino_of_node(page)); if (IS_ERR(entry->inode)) { err = PTR_ERR(entry->inode); kmem_cache_free(fsync_entry_slab, entry); - goto unlock_out; + if (err == -ENOENT) { + err = 0; + goto next; + } + break; } - list_add_tail(&entry->list, head); - entry->blkaddr = blkaddr; } + entry->blkaddr = blkaddr; + if (IS_INODE(page)) { - err = recover_inode(entry->inode, page); - if (err == -ENOENT) { - goto next; - } else if (err) { - err = -EINVAL; - goto unlock_out; - } + entry->last_inode = blkaddr; + if (is_dent_dnode(page)) + entry->last_dentry = blkaddr; } next: /* check next segment */ blkaddr = next_blkaddr_of_node(page); + f2fs_put_page(page, 1); + + ra_meta_pages_cond(sbi, blkaddr); } -unlock_out: - unlock_page(page); -out: - __free_pages(page, 0); + f2fs_put_page(page, 1); return err; } -static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi, - struct list_head *head) +static void destroy_fsync_dnodes(struct list_head *head) { struct fsync_inode_entry *entry, *tmp; @@ -186,88 +244,150 @@ static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi, } } -static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi, - block_t blkaddr) +static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, + block_t blkaddr, struct dnode_of_data *dn) { struct seg_entry *sentry; unsigned int segno = GET_SEGNO(sbi, blkaddr); - unsigned short blkoff = GET_SEGOFF_FROM_SEG0(sbi, blkaddr) & - (sbi->blocks_per_seg - 1); + unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr); + struct f2fs_summary_block *sum_node; struct f2fs_summary sum; - nid_t ino; - void *kaddr; + struct page *sum_page, *node_page; + struct dnode_of_data tdn = *dn; + nid_t ino, nid; struct inode *inode; - struct page *node_page; + unsigned int offset; block_t bidx; int i; sentry = get_seg_entry(sbi, segno); if (!f2fs_test_bit(blkoff, sentry->cur_valid_map)) - return; + return 0; /* Get the previous summary */ for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) { struct curseg_info *curseg = CURSEG_I(sbi, i); if (curseg->segno == segno) { sum = curseg->sum_blk->entries[blkoff]; - break; + goto got_it; } } - if (i > CURSEG_COLD_DATA) { - struct page *sum_page = get_sum_page(sbi, segno); - struct f2fs_summary_block *sum_node; - kaddr = page_address(sum_page); - sum_node = (struct f2fs_summary_block *)kaddr; - sum = sum_node->entries[blkoff]; - f2fs_put_page(sum_page, 1); + + sum_page = get_sum_page(sbi, segno); + sum_node = (struct f2fs_summary_block *)page_address(sum_page); + sum = sum_node->entries[blkoff]; + f2fs_put_page(sum_page, 1); +got_it: + /* Use the locked dnode page and inode */ + nid = le32_to_cpu(sum.nid); + if (dn->inode->i_ino == nid) { + tdn.nid = nid; + if (!dn->inode_page_locked) + lock_page(dn->inode_page); + tdn.node_page = dn->inode_page; + tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + goto truncate_out; + } else if (dn->nid == nid) { + tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + goto truncate_out; } /* Get the node page */ - node_page = get_node_page(sbi, le32_to_cpu(sum.nid)); - bidx = start_bidx_of_node(ofs_of_node(node_page)) + - le16_to_cpu(sum.ofs_in_node); + node_page = get_node_page(sbi, nid); + if (IS_ERR(node_page)) + return PTR_ERR(node_page); + + offset = ofs_of_node(node_page); ino = ino_of_node(node_page); f2fs_put_page(node_page, 1); - /* Deallocate previous index in the node page */ - inode = f2fs_iget(sbi->sb, ino); - if (IS_ERR(inode)) - return; + if (ino != dn->inode->i_ino) { + /* Deallocate previous index in the node page */ + inode = f2fs_iget(sbi->sb, ino); + if (IS_ERR(inode)) + return PTR_ERR(inode); + } else { + inode = dn->inode; + } + + bidx = start_bidx_of_node(offset, F2FS_I(inode)) + + le16_to_cpu(sum.ofs_in_node); - truncate_hole(inode, bidx, bidx + 1); - iput(inode); + /* + * if inode page is locked, unlock temporarily, but its reference + * count keeps alive. + */ + if (ino == dn->inode->i_ino && dn->inode_page_locked) + unlock_page(dn->inode_page); + + set_new_dnode(&tdn, inode, NULL, NULL, 0); + if (get_dnode_of_data(&tdn, bidx, LOOKUP_NODE)) + goto out; + + if (tdn.data_blkaddr == blkaddr) + truncate_data_blocks_range(&tdn, 1); + + f2fs_put_dnode(&tdn); +out: + if (ino != dn->inode->i_ino) + iput(inode); + else if (dn->inode_page_locked) + lock_page(dn->inode_page); + return 0; + +truncate_out: + if (datablock_addr(tdn.node_page, tdn.ofs_in_node) == blkaddr) + truncate_data_blocks_range(&tdn, 1); + if (dn->inode->i_ino == nid && !dn->inode_page_locked) + unlock_page(dn->inode_page); + return 0; } static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, struct page *page, block_t blkaddr) { + struct f2fs_inode_info *fi = F2FS_I(inode); unsigned int start, end; struct dnode_of_data dn; struct f2fs_summary sum; struct node_info ni; - int err = 0; - int ilock; + int err = 0, recovered = 0; + + /* step 1: recover xattr */ + if (IS_INODE(page)) { + recover_inline_xattr(inode, page); + } else if (f2fs_has_xattr_block(ofs_of_node(page))) { + /* + * Deprecated; xattr blocks should be found from cold log. + * But, we should remain this for backward compatibility. + */ + recover_xattr_data(inode, page, blkaddr); + goto out; + } - start = start_bidx_of_node(ofs_of_node(page)); - if (IS_INODE(page)) - end = start + ADDRS_PER_INODE; - else - end = start + ADDRS_PER_BLOCK; + /* step 2: recover inline data */ + if (recover_inline_data(inode, page)) + goto out; + + /* step 3: recover data indices */ + start = start_bidx_of_node(ofs_of_node(page), fi); + end = start + ADDRS_PER_PAGE(page, fi); + + f2fs_lock_op(sbi); - ilock = mutex_lock_op(sbi); set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, start, ALLOC_NODE); if (err) { - mutex_unlock_op(sbi, ilock); - return err; + f2fs_unlock_op(sbi); + goto out; } - wait_on_page_writeback(dn.node_page); + f2fs_wait_on_page_writeback(dn.node_page, NODE); get_node_info(sbi, dn.nid, &ni); - BUG_ON(ni.ino != ino_of_node(page)); - BUG_ON(ofs_of_node(dn.node_page) != ofs_of_node(page)); + f2fs_bug_on(sbi, ni.ino != ino_of_node(page)); + f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page)); for (; start < end; start++) { block_t src, dest; @@ -275,27 +395,32 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, src = datablock_addr(dn.node_page, dn.ofs_in_node); dest = datablock_addr(page, dn.ofs_in_node); - if (src != dest && dest != NEW_ADDR && dest != NULL_ADDR) { + if (src != dest && dest != NEW_ADDR && dest != NULL_ADDR && + dest >= MAIN_BLKADDR(sbi) && dest < MAX_BLKADDR(sbi)) { + if (src == NULL_ADDR) { - int err = reserve_new_block(&dn); + err = reserve_new_block(&dn); /* We should not get -ENOSPC */ - BUG_ON(err); + f2fs_bug_on(sbi, err); } /* Check the previous node page having this index */ - check_index_in_prev_nodes(sbi, dest); + err = check_index_in_prev_nodes(sbi, dest, &dn); + if (err) + goto err; set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); /* write dummy data page */ recover_data_page(sbi, NULL, &sum, src, dest); - update_extent_cache(dest, &dn); + dn.data_blkaddr = dest; + set_data_blkaddr(&dn); + f2fs_update_extent_cache(&dn); + recovered++; } dn.ofs_in_node++; } - /* write node page in place */ - set_summary(&sum, dn.nid, 0, 0); if (IS_INODE(dn.node_page)) sync_inode_page(&dn); @@ -303,19 +428,22 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, fill_node_footer(dn.node_page, dn.nid, ni.ino, ofs_of_node(page), false); set_page_dirty(dn.node_page); - - recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr); +err: f2fs_put_dnode(&dn); - mutex_unlock_op(sbi, ilock); - return 0; + f2fs_unlock_op(sbi); +out: + f2fs_msg(sbi->sb, KERN_NOTICE, + "recover_data: ino = %lx, recovered = %d blocks, err = %d", + inode->i_ino, recovered, err); + return err; } static int recover_data(struct f2fs_sb_info *sbi, struct list_head *head, int type) { - unsigned long long cp_ver = le64_to_cpu(sbi->ckpt->checkpoint_ver); + unsigned long long cp_ver = cur_cp_version(F2FS_CKPT(sbi)); struct curseg_info *curseg; - struct page *page; + struct page *page = NULL; int err = 0; block_t blkaddr; @@ -323,32 +451,43 @@ static int recover_data(struct f2fs_sb_info *sbi, curseg = CURSEG_I(sbi, type); blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); - /* read node page */ - page = alloc_page(GFP_NOFS | __GFP_ZERO); - if (IS_ERR(page)) - return -ENOMEM; - - lock_page(page); - while (1) { struct fsync_inode_entry *entry; - err = f2fs_readpage(sbi, page, blkaddr, READ_SYNC); - if (err) - goto out; + if (blkaddr < MAIN_BLKADDR(sbi) || blkaddr >= MAX_BLKADDR(sbi)) + break; - lock_page(page); + ra_meta_pages_cond(sbi, blkaddr); - if (cp_ver != cpver_of_node(page)) - goto unlock_out; + page = get_meta_page(sbi, blkaddr); + + if (cp_ver != cpver_of_node(page)) { + f2fs_put_page(page, 1); + break; + } entry = get_fsync_inode(head, ino_of_node(page)); if (!entry) goto next; - + /* + * inode(x) | CP | inode(x) | dnode(F) + * In this case, we can lose the latest inode(x). + * So, call recover_inode for the inode update. + */ + if (entry->last_inode == blkaddr) + recover_inode(entry->inode, page); + if (entry->last_dentry == blkaddr) { + err = recover_dentry(entry->inode, page); + if (err) { + f2fs_put_page(page, 1); + break; + } + } err = do_recover_data(sbi, entry->inode, page, blkaddr); - if (err) - goto out; + if (err) { + f2fs_put_page(page, 1); + break; + } if (entry->blkaddr == blkaddr) { iput(entry->inode); @@ -358,12 +497,8 @@ static int recover_data(struct f2fs_sb_info *sbi, next: /* check next segment */ blkaddr = next_blkaddr_of_node(page); + f2fs_put_page(page, 1); } -unlock_out: - unlock_page(page); -out: - __free_pages(page, 0); - if (!err) allocate_new_segments(sbi); return err; @@ -371,17 +506,27 @@ static int recover_data(struct f2fs_sb_info *sbi, int recover_fsync_data(struct f2fs_sb_info *sbi) { + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); struct list_head inode_list; + block_t blkaddr; int err; + bool need_writecp = false; fsync_entry_slab = f2fs_kmem_cache_create("f2fs_fsync_inode_entry", - sizeof(struct fsync_inode_entry), NULL); - if (unlikely(!fsync_entry_slab)) + sizeof(struct fsync_inode_entry)); + if (!fsync_entry_slab) return -ENOMEM; INIT_LIST_HEAD(&inode_list); /* step #1: find fsynced inode numbers */ + set_sbi_flag(sbi, SBI_POR_DOING); + + /* prevent checkpoint */ + mutex_lock(&sbi->cp_mutex); + + blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); + err = find_fsync_dnodes(sbi, &inode_list); if (err) goto out; @@ -389,14 +534,42 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) if (list_empty(&inode_list)) goto out; + need_writecp = true; + /* step #2: recover data */ - sbi->por_doing = 1; err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE); - sbi->por_doing = 0; - BUG_ON(!list_empty(&inode_list)); + if (!err) + f2fs_bug_on(sbi, !list_empty(&inode_list)); out: - destroy_fsync_dnodes(sbi, &inode_list); + destroy_fsync_dnodes(&inode_list); kmem_cache_destroy(fsync_entry_slab); - write_checkpoint(sbi, false); + + /* truncate meta pages to be used by the recovery */ + truncate_inode_pages_range(META_MAPPING(sbi), + MAIN_BLKADDR(sbi) << PAGE_CACHE_SHIFT, -1); + + if (err) { + truncate_inode_pages(NODE_MAPPING(sbi), 0); + truncate_inode_pages(META_MAPPING(sbi), 0); + } + + clear_sbi_flag(sbi, SBI_POR_DOING); + if (err) { + discard_next_dnode(sbi, blkaddr); + + /* Flush all the NAT/SIT pages */ + while (get_pages(sbi, F2FS_DIRTY_META)) + sync_meta_pages(sbi, META, LONG_MAX); + set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); + mutex_unlock(&sbi->cp_mutex); + } else if (need_writecp) { + struct cp_control cpc = { + .reason = CP_RECOVERY, + }; + mutex_unlock(&sbi->cp_mutex); + write_checkpoint(sbi, &cpc); + } else { + mutex_unlock(&sbi->cp_mutex); + } return err; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d8e84e49a5c30..571565f4c6514 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -13,13 +13,315 @@ #include #include #include +#include #include +#include #include "f2fs.h" #include "segment.h" #include "node.h" +#include "trace.h" #include +#define __reverse_ffz(x) __reverse_ffs(~(x)) + +static struct kmem_cache *discard_entry_slab; +static struct kmem_cache *sit_entry_set_slab; +static struct kmem_cache *inmem_entry_slab; + +/** + * Copied from latest lib/llist.c + * llist_for_each_entry_safe - iterate over some deleted entries of + * lock-less list of given type + * safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @node: the first entry of deleted list entries. + * @member: the name of the llist_node with the struct. + * + * In general, some entries of the lock-less list can be traversed + * safely only after being removed from list, so start with an entry + * instead of list head. + * + * If being used on entries deleted from lock-less list directly, the + * traverse order is from the newest to the oldest added entry. If + * you want to traverse from the oldest to the newest, you must + * reverse the order by yourself before traversing. + */ +#define llist_for_each_entry_safe(pos, n, node, member) \ + for (pos = llist_entry((node), typeof(*pos), member); \ + &pos->member != NULL && \ + (n = llist_entry(pos->member.next, typeof(*n), member), true); \ + pos = n) + +/** + * Copied from latest lib/llist.c + * llist_reverse_order - reverse order of a llist chain + * @head: first item of the list to be reversed + * + * Reverse the order of a chain of llist entries and return the + * new first entry. + */ +struct llist_node *llist_reverse_order(struct llist_node *head) +{ + struct llist_node *new_head = NULL; + + while (head) { + struct llist_node *tmp = head; + head = head->next; + tmp->next = new_head; + new_head = tmp; + } + + return new_head; +} + +/** + * Copied from latest linux/list.h + * list_last_entry - get the last element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/* + * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since + * MSB and LSB are reversed in a byte by f2fs_set_bit. + */ +static inline unsigned long __reverse_ffs(unsigned long word) +{ + int num = 0; + +#if BITS_PER_LONG == 64 + if ((word & 0xffffffff) == 0) { + num += 32; + word >>= 32; + } +#endif + if ((word & 0xffff) == 0) { + num += 16; + word >>= 16; + } + if ((word & 0xff) == 0) { + num += 8; + word >>= 8; + } + if ((word & 0xf0) == 0) + num += 4; + else + word >>= 4; + if ((word & 0xc) == 0) + num += 2; + else + word >>= 2; + if ((word & 0x2) == 0) + num += 1; + return num; +} + +/* + * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because + * f2fs_set_bit makes MSB and LSB reversed in a byte. + * Example: + * LSB <--> MSB + * f2fs_set_bit(0, bitmap) => 0000 0001 + * f2fs_set_bit(7, bitmap) => 1000 0000 + */ +static unsigned long __find_rev_next_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + const unsigned long *p = addr + BIT_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + unsigned long mask, submask; + unsigned long quot, rest; + + if (offset >= size) + return size; + + size -= result; + offset %= BITS_PER_LONG; + if (!offset) + goto aligned; + + tmp = *(p++); + quot = (offset >> 3) << 3; + rest = offset & 0x7; + mask = ~0UL << quot; + submask = (unsigned char)(0xff << rest) >> rest; + submask <<= quot; + mask &= submask; + tmp &= mask; + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + + size -= BITS_PER_LONG; + result += BITS_PER_LONG; +aligned: + while (size & ~(BITS_PER_LONG-1)) { + tmp = *(p++); + if (tmp) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; +found_first: + tmp &= (~0UL >> (BITS_PER_LONG - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __reverse_ffs(tmp); +} + +static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + const unsigned long *p = addr + BIT_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + unsigned long mask, submask; + unsigned long quot, rest; + + if (offset >= size) + return size; + + size -= result; + offset %= BITS_PER_LONG; + if (!offset) + goto aligned; + + tmp = *(p++); + quot = (offset >> 3) << 3; + rest = offset & 0x7; + mask = ~(~0UL << quot); + submask = (unsigned char)~((unsigned char)(0xff << rest) >> rest); + submask <<= quot; + mask += submask; + tmp |= mask; + if (size < BITS_PER_LONG) + goto found_first; + if (~tmp) + goto found_middle; + + size -= BITS_PER_LONG; + result += BITS_PER_LONG; +aligned: + while (size & ~(BITS_PER_LONG - 1)) { + tmp = *(p++); + if (~tmp) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + __reverse_ffz(tmp); +} + +void register_inmem_page(struct inode *inode, struct page *page) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + struct inmem_pages *new; + int err; + + SetPagePrivate(page); + f2fs_trace_pid(page); + + new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS); + + /* add atomic page indices to the list */ + new->page = page; + INIT_LIST_HEAD(&new->list); +retry: + /* increase reference count with clean state */ + mutex_lock(&fi->inmem_lock); + err = radix_tree_insert(&fi->inmem_root, page->index, new); + if (err == -EEXIST) { + mutex_unlock(&fi->inmem_lock); + kmem_cache_free(inmem_entry_slab, new); + return; + } else if (err) { + mutex_unlock(&fi->inmem_lock); + goto retry; + } + get_page(page); + list_add_tail(&new->list, &fi->inmem_pages); + inc_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES); + mutex_unlock(&fi->inmem_lock); + + trace_f2fs_register_inmem_page(page, INMEM); +} + +void commit_inmem_pages(struct inode *inode, bool abort) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_inode_info *fi = F2FS_I(inode); + struct inmem_pages *cur, *tmp; + bool submit_bio = false; + struct f2fs_io_info fio = { + .type = DATA, + .rw = WRITE_SYNC | REQ_PRIO, + }; + + /* + * The abort is true only when f2fs_evict_inode is called. + * Basically, the f2fs_evict_inode doesn't produce any data writes, so + * that we don't need to call f2fs_balance_fs. + * Otherwise, f2fs_gc in f2fs_balance_fs can wait forever until this + * inode becomes free by iget_locked in f2fs_iget. + */ + if (!abort) { + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); + } + + mutex_lock(&fi->inmem_lock); + list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) { + if (!abort) { + lock_page(cur->page); + if (cur->page->mapping == inode->i_mapping) { + f2fs_wait_on_page_writeback(cur->page, DATA); + if (clear_page_dirty_for_io(cur->page)) + inode_dec_dirty_pages(inode); + trace_f2fs_commit_inmem_page(cur->page, INMEM); + do_write_data_page(cur->page, &fio); + submit_bio = true; + } + f2fs_put_page(cur->page, 1); + } else { + trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); + put_page(cur->page); + } + radix_tree_delete(&fi->inmem_root, cur->page->index); + list_del(&cur->list); + kmem_cache_free(inmem_entry_slab, cur); + dec_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES); + } + mutex_unlock(&fi->inmem_lock); + + if (!abort) { + f2fs_unlock_op(sbi); + if (submit_bio) + f2fs_submit_merged_bio(sbi, DATA, WRITE); + } +} + /* * This function balances dirty node and dentry pages. * In addition, it controls garbage collection. @@ -36,6 +338,112 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) } } +void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) +{ + /* try to shrink extent cache when there is no enough memory */ + f2fs_shrink_extent_tree(sbi, EXTENT_CACHE_SHRINK_NUMBER); + + /* check the # of cached NAT entries and prefree segments */ + if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK) || + excess_prefree_segs(sbi) || + !available_free_memory(sbi, INO_ENTRIES)) + f2fs_sync_fs(sbi->sb, true); +} + +static int issue_flush_thread(void *data) +{ + struct f2fs_sb_info *sbi = data; + struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; + wait_queue_head_t *q = &fcc->flush_wait_queue; +repeat: + if (kthread_should_stop()) + return 0; + + if (!llist_empty(&fcc->issue_list)) { + struct bio *bio = bio_alloc(GFP_NOIO, 0); + struct flush_cmd *cmd, *next; + int ret; + + fcc->dispatch_list = llist_del_all(&fcc->issue_list); + fcc->dispatch_list = llist_reverse_order(fcc->dispatch_list); + + bio->bi_bdev = sbi->sb->s_bdev; + ret = submit_bio_wait(WRITE_FLUSH, bio); + + llist_for_each_entry_safe(cmd, next, + fcc->dispatch_list, llnode) { + cmd->ret = ret; + complete(&cmd->wait); + } + bio_put(bio); + fcc->dispatch_list = NULL; + } + + wait_event_interruptible(*q, + kthread_should_stop() || !llist_empty(&fcc->issue_list)); + goto repeat; +} + +int f2fs_issue_flush(struct f2fs_sb_info *sbi) +{ + struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; + struct flush_cmd cmd; + + trace_f2fs_issue_flush(sbi->sb, test_opt(sbi, NOBARRIER), + test_opt(sbi, FLUSH_MERGE)); + + if (test_opt(sbi, NOBARRIER)) + return 0; + + if (!test_opt(sbi, FLUSH_MERGE)) + return blkdev_issue_flush(sbi->sb->s_bdev, GFP_KERNEL, NULL); + + init_completion(&cmd.wait); + + llist_add(&cmd.llnode, &fcc->issue_list); + + if (!fcc->dispatch_list) + wake_up(&fcc->flush_wait_queue); + + wait_for_completion(&cmd.wait); + + return cmd.ret; +} + +int create_flush_cmd_control(struct f2fs_sb_info *sbi) +{ + dev_t dev = sbi->sb->s_bdev->bd_dev; + struct flush_cmd_control *fcc; + int err = 0; + + fcc = kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL); + if (!fcc) + return -ENOMEM; + init_waitqueue_head(&fcc->flush_wait_queue); + init_llist_head(&fcc->issue_list); + SM_I(sbi)->cmd_control_info = fcc; + fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, + "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); + if (IS_ERR(fcc->f2fs_issue_flush)) { + err = PTR_ERR(fcc->f2fs_issue_flush); + kfree(fcc); + SM_I(sbi)->cmd_control_info = NULL; + return err; + } + + return err; +} + +void destroy_flush_cmd_control(struct f2fs_sb_info *sbi) +{ + struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; + + if (fcc && fcc->f2fs_issue_flush) + kthread_stop(fcc->f2fs_issue_flush); + kfree(fcc); + SM_I(sbi)->cmd_control_info = NULL; +} + static void __locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, enum dirty_type dirty_type) { @@ -50,20 +458,14 @@ static void __locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, if (dirty_type == DIRTY) { struct seg_entry *sentry = get_seg_entry(sbi, segno); - enum dirty_type t = DIRTY_HOT_DATA; - - dirty_type = sentry->type; + enum dirty_type t = sentry->type; - if (!test_and_set_bit(segno, dirty_i->dirty_segmap[dirty_type])) - dirty_i->nr_dirty[dirty_type]++; - - /* Only one bitmap should be set */ - for (; t <= DIRTY_COLD_NODE; t++) { - if (t == dirty_type) - continue; - if (test_and_clear_bit(segno, dirty_i->dirty_segmap[t])) - dirty_i->nr_dirty[t]--; + if (unlikely(t >= DIRTY)) { + f2fs_bug_on(sbi, 1); + return; } + if (!test_and_set_bit(segno, dirty_i->dirty_segmap[t])) + dirty_i->nr_dirty[t]++; } } @@ -76,12 +478,11 @@ static void __remove_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, dirty_i->nr_dirty[dirty_type]--; if (dirty_type == DIRTY) { - enum dirty_type t = DIRTY_HOT_DATA; + struct seg_entry *sentry = get_seg_entry(sbi, segno); + enum dirty_type t = sentry->type; - /* clear all the bitmaps */ - for (; t <= DIRTY_COLD_NODE; t++) - if (test_and_clear_bit(segno, dirty_i->dirty_segmap[t])) - dirty_i->nr_dirty[t]--; + if (test_and_clear_bit(segno, dirty_i->dirty_segmap[t])) + dirty_i->nr_dirty[t]--; if (get_valid_blocks(sbi, segno, sbi->segs_per_sec) == 0) clear_bit(GET_SECNO(sbi, segno), @@ -94,7 +495,7 @@ static void __remove_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, * Adding dirty entry into seglist is not critical operation. * If a given segment is one of current working segments, it won't be added. */ -void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno) +static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); unsigned short valid_blocks; @@ -117,7 +518,120 @@ void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno) } mutex_unlock(&dirty_i->seglist_lock); - return; +} + +static int f2fs_issue_discard(struct f2fs_sb_info *sbi, + block_t blkstart, block_t blklen) +{ + sector_t start = SECTOR_FROM_BLOCK(blkstart); + sector_t len = SECTOR_FROM_BLOCK(blklen); + trace_f2fs_issue_discard(sbi->sb, blkstart, blklen); + return blkdev_issue_discard(sbi->sb->s_bdev, start, len, GFP_NOFS, 0); +} + +void discard_next_dnode(struct f2fs_sb_info *sbi, block_t blkaddr) +{ + if (f2fs_issue_discard(sbi, blkaddr, 1)) { + struct page *page = grab_meta_page(sbi, blkaddr); + /* zero-filled page */ + set_page_dirty(page); + f2fs_put_page(page, 1); + } +} + +static void __add_discard_entry(struct f2fs_sb_info *sbi, + struct cp_control *cpc, unsigned int start, unsigned int end) +{ + struct list_head *head = &SM_I(sbi)->discard_list; + struct discard_entry *new, *last; + + if (!list_empty(head)) { + last = list_last_entry(head, struct discard_entry, list); + if (START_BLOCK(sbi, cpc->trim_start) + start == + last->blkaddr + last->len) { + last->len += end - start; + goto done; + } + } + + new = f2fs_kmem_cache_alloc(discard_entry_slab, GFP_NOFS); + INIT_LIST_HEAD(&new->list); + new->blkaddr = START_BLOCK(sbi, cpc->trim_start) + start; + new->len = end - start; + list_add_tail(&new->list, head); +done: + SM_I(sbi)->nr_discards += end - start; + cpc->trimmed += end - start; +} + +static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) +{ + int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long); + int max_blocks = sbi->blocks_per_seg; + struct seg_entry *se = get_seg_entry(sbi, cpc->trim_start); + unsigned long *cur_map = (unsigned long *)se->cur_valid_map; + unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map; + unsigned long *dmap = SIT_I(sbi)->tmp_map; + unsigned int start = 0, end = -1; + bool force = (cpc->reason == CP_DISCARD); + int i; + + if (!force && (!test_opt(sbi, DISCARD) || + SM_I(sbi)->nr_discards >= SM_I(sbi)->max_discards)) + return; + + if (force && !se->valid_blocks) { + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); + /* + * if this segment is registered in the prefree list, then + * we should skip adding a discard candidate, and let the + * checkpoint do that later. + */ + mutex_lock(&dirty_i->seglist_lock); + if (test_bit(cpc->trim_start, dirty_i->dirty_segmap[PRE])) { + mutex_unlock(&dirty_i->seglist_lock); + cpc->trimmed += sbi->blocks_per_seg; + return; + } + mutex_unlock(&dirty_i->seglist_lock); + + __add_discard_entry(sbi, cpc, 0, sbi->blocks_per_seg); + return; + } + + /* zero block will be discarded through the prefree list */ + if (!se->valid_blocks || se->valid_blocks == max_blocks) + return; + + /* SIT_VBLOCK_MAP_SIZE should be multiple of sizeof(unsigned long) */ + for (i = 0; i < entries; i++) + dmap[i] = force ? ~ckpt_map[i] : + (cur_map[i] ^ ckpt_map[i]) & ckpt_map[i]; + + while (force || SM_I(sbi)->nr_discards <= SM_I(sbi)->max_discards) { + start = __find_rev_next_bit(dmap, max_blocks, end + 1); + if (start >= max_blocks) + break; + + end = __find_rev_next_zero_bit(dmap, max_blocks, start + 1); + + if (force && end - start < cpc->trim_minlen) + continue; + + __add_discard_entry(sbi, cpc, start, end); + } +} + +void release_discard_addrs(struct f2fs_sb_info *sbi) +{ + struct list_head *head = &(SM_I(sbi)->discard_list); + struct discard_entry *entry, *this; + + /* drop caches */ + list_for_each_entry_safe(entry, this, head, list) { + list_del(&entry->list); + kmem_cache_free(discard_entry_slab, entry); + } } /* @@ -126,55 +640,64 @@ void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno) static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned int segno, offset = 0; - unsigned int total_segs = TOTAL_SEGS(sbi); + unsigned int segno; mutex_lock(&dirty_i->seglist_lock); - while (1) { - segno = find_next_bit(dirty_i->dirty_segmap[PRE], total_segs, - offset); - if (segno >= total_segs) - break; + for_each_set_bit(segno, dirty_i->dirty_segmap[PRE], MAIN_SEGS(sbi)) __set_test_and_free(sbi, segno); - offset = segno + 1; - } mutex_unlock(&dirty_i->seglist_lock); } void clear_prefree_segments(struct f2fs_sb_info *sbi) { + struct list_head *head = &(SM_I(sbi)->discard_list); + struct discard_entry *entry, *this; struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned int segno, offset = 0; - unsigned int total_segs = TOTAL_SEGS(sbi); + unsigned long *prefree_map = dirty_i->dirty_segmap[PRE]; + unsigned int start = 0, end = -1; mutex_lock(&dirty_i->seglist_lock); + while (1) { - segno = find_next_bit(dirty_i->dirty_segmap[PRE], total_segs, - offset); - if (segno >= total_segs) + int i; + start = find_next_bit(prefree_map, MAIN_SEGS(sbi), end + 1); + if (start >= MAIN_SEGS(sbi)) break; + end = find_next_zero_bit(prefree_map, MAIN_SEGS(sbi), + start + 1); - offset = segno + 1; - if (test_and_clear_bit(segno, dirty_i->dirty_segmap[PRE])) - dirty_i->nr_dirty[PRE]--; - - /* Let's use trim */ - if (test_opt(sbi, DISCARD)) - blkdev_issue_discard(sbi->sb->s_bdev, - START_BLOCK(sbi, segno) << - sbi->log_sectors_per_block, - 1 << (sbi->log_sectors_per_block + - sbi->log_blocks_per_seg), - GFP_NOFS, 0); + for (i = start; i < end; i++) + clear_bit(i, prefree_map); + + dirty_i->nr_dirty[PRE] -= end - start; + + if (!test_opt(sbi, DISCARD)) + continue; + + f2fs_issue_discard(sbi, START_BLOCK(sbi, start), + (end - start) << sbi->log_blocks_per_seg); } mutex_unlock(&dirty_i->seglist_lock); + + /* send small discards */ + list_for_each_entry_safe(entry, this, head, list) { + f2fs_issue_discard(sbi, entry->blkaddr, entry->len); + list_del(&entry->list); + SM_I(sbi)->nr_discards -= entry->len; + kmem_cache_free(discard_entry_slab, entry); + } } -static void __mark_sit_entry_dirty(struct f2fs_sb_info *sbi, unsigned int segno) +static bool __mark_sit_entry_dirty(struct f2fs_sb_info *sbi, unsigned int segno) { struct sit_info *sit_i = SIT_I(sbi); - if (!__test_and_set_bit(segno, sit_i->dirty_sentries_bitmap)) + + if (!__test_and_set_bit(segno, sit_i->dirty_sentries_bitmap)) { sit_i->dirty_sentries++; + return false; + } + + return true; } static void __set_sit_entry_type(struct f2fs_sb_info *sbi, int type, @@ -196,9 +719,9 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) se = get_seg_entry(sbi, segno); new_vblocks = se->valid_blocks + del; - offset = GET_SEGOFF_FROM_SEG0(sbi, blkaddr) & (sbi->blocks_per_seg - 1); + offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr); - BUG_ON((new_vblocks >> (sizeof(unsigned short) << 3) || + f2fs_bug_on(sbi, (new_vblocks >> (sizeof(unsigned short) << 3) || (new_vblocks > sbi->blocks_per_seg))); se->valid_blocks = new_vblocks; @@ -207,11 +730,11 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) /* Update valid block bitmap */ if (del > 0) { - if (f2fs_set_bit(offset, se->cur_valid_map)) - BUG(); + if (f2fs_test_and_set_bit(offset, se->cur_valid_map)) + f2fs_bug_on(sbi, 1); } else { - if (!f2fs_clear_bit(offset, se->cur_valid_map)) - BUG(); + if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) + f2fs_bug_on(sbi, 1); } if (!f2fs_test_bit(offset, se->ckpt_valid_map)) se->ckpt_valid_blocks += del; @@ -225,12 +748,14 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) get_sec_entry(sbi, segno)->valid_blocks += del; } -static void refresh_sit_entry(struct f2fs_sb_info *sbi, - block_t old_blkaddr, block_t new_blkaddr) +void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t new) { - update_sit_entry(sbi, new_blkaddr, 1); - if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) - update_sit_entry(sbi, old_blkaddr, -1); + update_sit_entry(sbi, new, 1); + if (GET_SEGNO(sbi, old) != NULL_SEGNO) + update_sit_entry(sbi, old, -1); + + locate_dirty_segment(sbi, GET_SEGNO(sbi, old)); + locate_dirty_segment(sbi, GET_SEGNO(sbi, new)); } void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) @@ -238,7 +763,7 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) unsigned int segno = GET_SEGNO(sbi, addr); struct sit_info *sit_i = SIT_I(sbi); - BUG_ON(addr == NULL_ADDR); + f2fs_bug_on(sbi, addr == NULL_ADDR); if (addr == NEW_ADDR) return; @@ -257,38 +782,40 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) * This function should be resided under the curseg_mutex lock */ static void __add_sum_entry(struct f2fs_sb_info *sbi, int type, - struct f2fs_summary *sum, unsigned short offset) + struct f2fs_summary *sum) { struct curseg_info *curseg = CURSEG_I(sbi, type); void *addr = curseg->sum_blk; - addr += offset * sizeof(struct f2fs_summary); + addr += curseg->next_blkoff * sizeof(struct f2fs_summary); memcpy(addr, sum, sizeof(struct f2fs_summary)); - return; } /* * Calculate the number of current summary pages for writing */ -int npages_for_summary_flush(struct f2fs_sb_info *sbi) +int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra) { - int total_size_bytes = 0; int valid_sum_count = 0; - int i, sum_space; + int i, sum_in_page; for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { if (sbi->ckpt->alloc_type[i] == SSR) valid_sum_count += sbi->blocks_per_seg; - else - valid_sum_count += curseg_blkoff(sbi, i); + else { + if (for_ra) + valid_sum_count += le16_to_cpu( + F2FS_CKPT(sbi)->cur_data_blkoff[i]); + else + valid_sum_count += curseg_blkoff(sbi, i); + } } - total_size_bytes = valid_sum_count * (SUMMARY_SIZE + 1) - + sizeof(struct nat_journal) + 2 - + sizeof(struct sit_journal) + 2; - sum_space = PAGE_CACHE_SIZE - SUM_FOOTER_SIZE; - if (total_size_bytes < sum_space) + sum_in_page = (PAGE_CACHE_SIZE - 2 * SUM_JOURNAL_SIZE - + SUM_FOOTER_SIZE) / SUMMARY_SIZE; + if (valid_sum_count <= sum_in_page) return 1; - else if (total_size_bytes < 2 * sum_space) + else if ((valid_sum_count - sum_in_page) <= + (PAGE_CACHE_SIZE - SUM_FOOTER_SIZE) / SUMMARY_SIZE) return 2; return 3; } @@ -311,64 +838,14 @@ static void write_sum_page(struct f2fs_sb_info *sbi, f2fs_put_page(page, 1); } -static unsigned int check_prefree_segments(struct f2fs_sb_info *sbi, int type) -{ - struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned long *prefree_segmap = dirty_i->dirty_segmap[PRE]; - unsigned int segno; - unsigned int ofs = 0; - - /* - * If there is not enough reserved sections, - * we should not reuse prefree segments. - */ - if (has_not_enough_free_secs(sbi, 0)) - return NULL_SEGNO; - - /* - * NODE page should not reuse prefree segment, - * since those information is used for SPOR. - */ - if (IS_NODESEG(type)) - return NULL_SEGNO; -next: - segno = find_next_bit(prefree_segmap, TOTAL_SEGS(sbi), ofs); - ofs += sbi->segs_per_sec; - - if (segno < TOTAL_SEGS(sbi)) { - int i; - - /* skip intermediate segments in a section */ - if (segno % sbi->segs_per_sec) - goto next; - - /* skip if the section is currently used */ - if (sec_usage_check(sbi, GET_SECNO(sbi, segno))) - goto next; - - /* skip if whole section is not prefree */ - for (i = 1; i < sbi->segs_per_sec; i++) - if (!test_bit(segno + i, prefree_segmap)) - goto next; - - /* skip if whole section was not free at the last checkpoint */ - for (i = 0; i < sbi->segs_per_sec; i++) - if (get_seg_entry(sbi, segno + i)->ckpt_valid_blocks) - goto next; - - return segno; - } - return NULL_SEGNO; -} - static int is_next_segment_free(struct f2fs_sb_info *sbi, int type) { struct curseg_info *curseg = CURSEG_I(sbi, type); - unsigned int segno = curseg->segno; + unsigned int segno = curseg->segno + 1; struct free_segmap_info *free_i = FREE_I(sbi); - if (segno + 1 < TOTAL_SEGS(sbi) && (segno + 1) % sbi->segs_per_sec) - return !test_bit(segno + 1, free_i->free_segmap); + if (segno < MAIN_SEGS(sbi) && segno % sbi->segs_per_sec) + return !test_bit(segno, free_i->free_segmap); return 0; } @@ -381,7 +858,7 @@ static void get_new_segment(struct f2fs_sb_info *sbi, { struct free_segmap_info *free_i = FREE_I(sbi); unsigned int segno, secno, zoneno; - unsigned int total_zones = TOTAL_SECS(sbi) / sbi->secs_per_zone; + unsigned int total_zones = MAIN_SECS(sbi) / sbi->secs_per_zone; unsigned int hint = *newseg / sbi->segs_per_sec; unsigned int old_zoneno = GET_ZONENO_FROM_SEGNO(sbi, *newseg); unsigned int left_start = hint; @@ -389,22 +866,22 @@ static void get_new_segment(struct f2fs_sb_info *sbi, int go_left = 0; int i; - write_lock(&free_i->segmap_lock); + spin_lock(&free_i->segmap_lock); if (!new_sec && ((*newseg + 1) % sbi->segs_per_sec)) { segno = find_next_zero_bit(free_i->free_segmap, - TOTAL_SEGS(sbi), *newseg + 1); + MAIN_SEGS(sbi), *newseg + 1); if (segno - *newseg < sbi->segs_per_sec - (*newseg % sbi->segs_per_sec)) goto got_it; } find_other_zone: - secno = find_next_zero_bit(free_i->free_secmap, TOTAL_SECS(sbi), hint); - if (secno >= TOTAL_SECS(sbi)) { + secno = find_next_zero_bit(free_i->free_secmap, MAIN_SECS(sbi), hint); + if (secno >= MAIN_SECS(sbi)) { if (dir == ALLOC_RIGHT) { secno = find_next_zero_bit(free_i->free_secmap, - TOTAL_SECS(sbi), 0); - BUG_ON(secno >= TOTAL_SECS(sbi)); + MAIN_SECS(sbi), 0); + f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi)); } else { go_left = 1; left_start = hint - 1; @@ -419,8 +896,8 @@ static void get_new_segment(struct f2fs_sb_info *sbi, continue; } left_start = find_next_zero_bit(free_i->free_secmap, - TOTAL_SECS(sbi), 0); - BUG_ON(left_start >= TOTAL_SECS(sbi)); + MAIN_SECS(sbi), 0); + f2fs_bug_on(sbi, left_start >= MAIN_SECS(sbi)); break; } secno = left_start; @@ -459,10 +936,10 @@ static void get_new_segment(struct f2fs_sb_info *sbi, } got_it: /* set it as dirty segment in free segmap */ - BUG_ON(test_bit(segno, free_i->free_segmap)); + f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap)); __set_inuse(sbi, segno); *newseg = segno; - write_unlock(&free_i->segmap_lock); + spin_unlock(&free_i->segmap_lock); } static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) @@ -495,7 +972,7 @@ static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec) int dir = ALLOC_LEFT; write_sum_page(sbi, curseg->sum_blk, - GET_SUM_BLOCK(sbi, curseg->segno)); + GET_SUM_BLOCK(sbi, segno)); if (type == CURSEG_WARM_DATA || type == CURSEG_COLD_DATA) dir = ALLOC_RIGHT; @@ -512,13 +989,18 @@ static void __next_free_blkoff(struct f2fs_sb_info *sbi, struct curseg_info *seg, block_t start) { struct seg_entry *se = get_seg_entry(sbi, seg->segno); - block_t ofs; - for (ofs = start; ofs < sbi->blocks_per_seg; ofs++) { - if (!f2fs_test_bit(ofs, se->ckpt_valid_map) - && !f2fs_test_bit(ofs, se->cur_valid_map)) - break; - } - seg->next_blkoff = ofs; + int entries = SIT_VBLOCK_MAP_SIZE / sizeof(unsigned long); + unsigned long *target_map = SIT_I(sbi)->tmp_map; + unsigned long *ckpt_map = (unsigned long *)se->ckpt_valid_map; + unsigned long *cur_map = (unsigned long *)se->cur_valid_map; + int i, pos; + + for (i = 0; i < entries; i++) + target_map[i] = ckpt_map[i] | cur_map[i]; + + pos = __find_rev_next_zero_bit(target_map, sbi->blocks_per_seg, start); + + seg->next_blkoff = pos; } /* @@ -536,7 +1018,7 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi, } /* - * This function always allocates a used segment (from dirty seglist) by SSR + * This function always allocates a used segment(from dirty seglist) by SSR * manner, so it should recover the existing segment information of valid blocks */ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool reuse) @@ -594,15 +1076,8 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi, { struct curseg_info *curseg = CURSEG_I(sbi, type); - if (force) { + if (force) new_curseg(sbi, type, true); - goto out; - } - - curseg->next_segno = check_prefree_segments(sbi, type); - - if (curseg->next_segno != NULL_SEGNO) - change_curseg(sbi, type, false); else if (type == CURSEG_WARM_NODE) new_curseg(sbi, type, false); else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type)) @@ -611,148 +1086,68 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi, change_curseg(sbi, type, true); else new_curseg(sbi, type, false); -out: - sbi->segment_count[curseg->alloc_type]++; -} - -void allocate_new_segments(struct f2fs_sb_info *sbi) -{ - struct curseg_info *curseg; - unsigned int old_curseg; - int i; - - for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { - curseg = CURSEG_I(sbi, i); - old_curseg = curseg->segno; - SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true); - locate_dirty_segment(sbi, old_curseg); - } -} - -static const struct segment_allocation default_salloc_ops = { - .allocate_segment = allocate_segment_by_default, -}; - -static void f2fs_end_io_write(struct bio *bio, int err) -{ - const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; - struct bio_private *p = bio->bi_private; - do { - struct page *page = bvec->bv_page; - - if (--bvec >= bio->bi_io_vec) - prefetchw(&bvec->bv_page->flags); - if (!uptodate) { - SetPageError(page); - if (page->mapping) - set_bit(AS_EIO, &page->mapping->flags); - set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); - p->sbi->sb->s_flags |= MS_RDONLY; - } - end_page_writeback(page); - dec_page_count(p->sbi, F2FS_WRITEBACK); - } while (bvec >= bio->bi_io_vec); - - if (p->is_sync) - complete(p->wait); - kfree(p); - bio_put(bio); + stat_inc_seg_type(sbi, curseg); } -struct bio *f2fs_bio_alloc(struct block_device *bdev, int npages) +static void __allocate_new_segments(struct f2fs_sb_info *sbi, int type) { - struct bio *bio; - struct bio_private *priv; -retry: - priv = kmalloc(sizeof(struct bio_private), GFP_NOFS); - if (!priv) { - cond_resched(); - goto retry; - } + struct curseg_info *curseg = CURSEG_I(sbi, type); + unsigned int old_segno; - /* No failure on bio allocation */ - bio = bio_alloc(GFP_NOIO, npages); - bio->bi_bdev = bdev; - bio->bi_private = priv; - return bio; + old_segno = curseg->segno; + SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true); + locate_dirty_segment(sbi, old_segno); } -static void do_submit_bio(struct f2fs_sb_info *sbi, - enum page_type type, bool sync) +void allocate_new_segments(struct f2fs_sb_info *sbi) { - int rw = sync ? WRITE_SYNC : WRITE; - enum page_type btype = type > META ? META : type; - - if (type >= META_FLUSH) - rw = WRITE_FLUSH_FUA; - - if (btype == META) - rw |= REQ_META; - - if (sbi->bio[btype]) { - struct bio_private *p = sbi->bio[btype]->bi_private; - p->sbi = sbi; - sbi->bio[btype]->bi_end_io = f2fs_end_io_write; - - trace_f2fs_do_submit_bio(sbi->sb, btype, sync, sbi->bio[btype]); + int i; - if (type == META_FLUSH) { - DECLARE_COMPLETION_ONSTACK(wait); - p->is_sync = true; - p->wait = &wait; - submit_bio(rw, sbi->bio[btype]); - wait_for_completion(&wait); - } else { - p->is_sync = false; - submit_bio(rw, sbi->bio[btype]); - } - sbi->bio[btype] = NULL; - } + for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) + __allocate_new_segments(sbi, i); } -void f2fs_submit_bio(struct f2fs_sb_info *sbi, enum page_type type, bool sync) -{ - down_write(&sbi->bio_sem); - do_submit_bio(sbi, type, sync); - up_write(&sbi->bio_sem); -} +static const struct segment_allocation default_salloc_ops = { + .allocate_segment = allocate_segment_by_default, +}; -static void submit_write_page(struct f2fs_sb_info *sbi, struct page *page, - block_t blk_addr, enum page_type type) +int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) { - struct block_device *bdev = sbi->sb->s_bdev; + __u64 start = F2FS_BYTES_TO_BLK(range->start); + __u64 end = start + F2FS_BYTES_TO_BLK(range->len) - 1; + unsigned int start_segno, end_segno; + struct cp_control cpc; - verify_block_addr(sbi, blk_addr); + if (range->minlen > SEGMENT_SIZE(sbi) || start >= MAX_BLKADDR(sbi) || + range->len < sbi->blocksize) + return -EINVAL; - down_write(&sbi->bio_sem); + cpc.trimmed = 0; + if (end <= MAIN_BLKADDR(sbi)) + goto out; - inc_page_count(sbi, F2FS_WRITEBACK); + /* start/end segment number in main_area */ + start_segno = (start <= MAIN_BLKADDR(sbi)) ? 0 : GET_SEGNO(sbi, start); + end_segno = (end >= MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 : + GET_SEGNO(sbi, end); + cpc.reason = CP_DISCARD; + cpc.trim_minlen = F2FS_BYTES_TO_BLK(range->minlen); - if (sbi->bio[type] && sbi->last_block_in_bio[type] != blk_addr - 1) - do_submit_bio(sbi, type, false); -alloc_new: - if (sbi->bio[type] == NULL) { - sbi->bio[type] = f2fs_bio_alloc(bdev, max_hw_blocks(sbi)); - sbi->bio[type]->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr); - /* - * The end_io will be assigned at the sumbission phase. - * Until then, let bio_add_page() merge consecutive IOs as much - * as possible. - */ - } + /* do checkpoint to issue discard commands safely */ + for (; start_segno <= end_segno; start_segno = cpc.trim_end + 1) { + cpc.trim_start = start_segno; + cpc.trim_end = min_t(unsigned int, rounddown(start_segno + + BATCHED_TRIM_SEGMENTS(sbi), + sbi->segs_per_sec) - 1, end_segno); - if (bio_add_page(sbi->bio[type], page, PAGE_CACHE_SIZE, 0) < - PAGE_CACHE_SIZE) { - do_submit_bio(sbi, type, false); - goto alloc_new; + mutex_lock(&sbi->gc_mutex); + write_checkpoint(sbi, &cpc); + mutex_unlock(&sbi->gc_mutex); } - - sbi->last_block_in_bio[type] = blk_addr; - - up_write(&sbi->bio_sem); - trace_f2fs_submit_write_page(page, blk_addr, type); +out: + range->len = F2FS_BLK_TO_BYTES(cpc.trimmed); + return 0; } static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type) @@ -781,8 +1176,8 @@ static int __get_segment_type_4(struct page *page, enum page_type p_type) else return CURSEG_COLD_DATA; } else { - if (IS_DNODE(page) && !is_cold_node(page)) - return CURSEG_HOT_NODE; + if (IS_DNODE(page) && is_cold_node(page)) + return CURSEG_WARM_NODE; else return CURSEG_COLD_NODE; } @@ -795,7 +1190,7 @@ static int __get_segment_type_6(struct page *page, enum page_type p_type) if (S_ISDIR(inode->i_mode)) return CURSEG_HOT_DATA; - else if (is_cold_data(page) || is_cold_file(inode)) + else if (is_cold_data(page) || file_is_cold(inode)) return CURSEG_COLD_DATA; else return CURSEG_WARM_DATA; @@ -810,102 +1205,116 @@ static int __get_segment_type_6(struct page *page, enum page_type p_type) static int __get_segment_type(struct page *page, enum page_type p_type) { - struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); - switch (sbi->active_logs) { + switch (F2FS_P_SB(page)->active_logs) { case 2: return __get_segment_type_2(page, p_type); case 4: return __get_segment_type_4(page, p_type); } /* NR_CURSEG_TYPE(6) logs by default */ - BUG_ON(sbi->active_logs != NR_CURSEG_TYPE); + f2fs_bug_on(F2FS_P_SB(page), + F2FS_P_SB(page)->active_logs != NR_CURSEG_TYPE); return __get_segment_type_6(page, p_type); } -static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, - block_t old_blkaddr, block_t *new_blkaddr, - struct f2fs_summary *sum, enum page_type p_type) +void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + block_t old_blkaddr, block_t *new_blkaddr, + struct f2fs_summary *sum, int type) { struct sit_info *sit_i = SIT_I(sbi); struct curseg_info *curseg; - unsigned int old_cursegno; - int type; + bool direct_io = (type == CURSEG_DIRECT_IO); + + type = direct_io ? CURSEG_WARM_DATA : type; - type = __get_segment_type(page, p_type); curseg = CURSEG_I(sbi, type); mutex_lock(&curseg->curseg_mutex); + mutex_lock(&sit_i->sentry_lock); + + /* direct_io'ed data is aligned to the segment for better performance */ + if (direct_io && curseg->next_blkoff) + __allocate_new_segments(sbi, type); *new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); - old_cursegno = curseg->segno; /* * __add_sum_entry should be resided under the curseg_mutex * because, this function updates a summary entry in the * current summary block. */ - __add_sum_entry(sbi, type, sum, curseg->next_blkoff); + __add_sum_entry(sbi, type, sum); - mutex_lock(&sit_i->sentry_lock); __refresh_next_blkoff(sbi, curseg); - sbi->block_count[curseg->alloc_type]++; + stat_inc_block_count(sbi, curseg); + + if (!__has_curseg_space(sbi, type)) + sit_i->s_ops->allocate_segment(sbi, type, false); /* * SIT information should be updated before segment allocation, * since SSR needs latest valid block information. */ refresh_sit_entry(sbi, old_blkaddr, *new_blkaddr); - if (!__has_curseg_space(sbi, type)) - sit_i->s_ops->allocate_segment(sbi, type, false); - - locate_dirty_segment(sbi, old_cursegno); - locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); mutex_unlock(&sit_i->sentry_lock); - if (p_type == NODE) + if (page && IS_NODESEG(type)) fill_node_footer_blkaddr(page, NEXT_FREE_BLKADDR(sbi, curseg)); - /* writeout dirty page into bdev */ - submit_write_page(sbi, page, *new_blkaddr, p_type); - mutex_unlock(&curseg->curseg_mutex); } +static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, + struct f2fs_summary *sum, + struct f2fs_io_info *fio) +{ + int type = __get_segment_type(page, fio->type); + + allocate_data_block(sbi, page, fio->blk_addr, &fio->blk_addr, sum, type); + + /* writeout dirty page into bdev */ + f2fs_submit_page_mbio(sbi, page, fio); +} + void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) { + struct f2fs_io_info fio = { + .type = META, + .rw = WRITE_SYNC | REQ_META | REQ_PRIO, + .blk_addr = page->index, + }; + set_page_writeback(page); - submit_write_page(sbi, page, page->index, META); + f2fs_submit_page_mbio(sbi, page, &fio); } void write_node_page(struct f2fs_sb_info *sbi, struct page *page, - unsigned int nid, block_t old_blkaddr, block_t *new_blkaddr) + unsigned int nid, struct f2fs_io_info *fio) { struct f2fs_summary sum; set_summary(&sum, nid, 0, 0); - do_write_page(sbi, page, old_blkaddr, new_blkaddr, &sum, NODE); + do_write_page(sbi, page, &sum, fio); } -void write_data_page(struct inode *inode, struct page *page, - struct dnode_of_data *dn, block_t old_blkaddr, - block_t *new_blkaddr) +void write_data_page(struct page *page, struct dnode_of_data *dn, + struct f2fs_io_info *fio) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct f2fs_summary sum; struct node_info ni; - BUG_ON(old_blkaddr == NULL_ADDR); + f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR); get_node_info(sbi, dn->nid, &ni); set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); - - do_write_page(sbi, page, old_blkaddr, - new_blkaddr, &sum, DATA); + do_write_page(sbi, page, &sum, fio); + dn->data_blkaddr = fio->blk_addr; } -void rewrite_data_page(struct f2fs_sb_info *sbi, struct page *page, - block_t old_blk_addr) +void rewrite_data_page(struct page *page, struct f2fs_io_info *fio) { - submit_write_page(sbi, page, old_blk_addr, DATA); + stat_inc_inplace_blocks(F2FS_P_SB(page)); + f2fs_submit_page_mbio(F2FS_P_SB(page), page, fio); } void recover_data_page(struct f2fs_sb_info *sbi, @@ -941,66 +1350,50 @@ void recover_data_page(struct f2fs_sb_info *sbi, change_curseg(sbi, type, true); } - curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) & - (sbi->blocks_per_seg - 1); - __add_sum_entry(sbi, type, sum, curseg->next_blkoff); + curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); + __add_sum_entry(sbi, type, sum); refresh_sit_entry(sbi, old_blkaddr, new_blkaddr); - locate_dirty_segment(sbi, old_cursegno); - locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); mutex_unlock(&sit_i->sentry_lock); mutex_unlock(&curseg->curseg_mutex); } -void rewrite_node_page(struct f2fs_sb_info *sbi, - struct page *page, struct f2fs_summary *sum, - block_t old_blkaddr, block_t new_blkaddr) +static inline bool is_merged_page(struct f2fs_sb_info *sbi, + struct page *page, enum page_type type) { - struct sit_info *sit_i = SIT_I(sbi); - int type = CURSEG_WARM_NODE; - struct curseg_info *curseg; - unsigned int segno, old_cursegno; - block_t next_blkaddr = next_blkaddr_of_node(page); - unsigned int next_segno = GET_SEGNO(sbi, next_blkaddr); - - curseg = CURSEG_I(sbi, type); - - mutex_lock(&curseg->curseg_mutex); - mutex_lock(&sit_i->sentry_lock); - - segno = GET_SEGNO(sbi, new_blkaddr); - old_cursegno = curseg->segno; + enum page_type btype = PAGE_TYPE_OF_BIO(type); + struct f2fs_bio_info *io = &sbi->write_io[btype]; + struct bio_vec *bvec; + int i; - /* change the current segment */ - if (segno != curseg->segno) { - curseg->next_segno = segno; - change_curseg(sbi, type, true); - } - curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) & - (sbi->blocks_per_seg - 1); - __add_sum_entry(sbi, type, sum, curseg->next_blkoff); + down_read(&io->io_rwsem); + if (!io->bio) + goto out; - /* change the current log to the next block addr in advance */ - if (next_segno != segno) { - curseg->next_segno = next_segno; - change_curseg(sbi, type, true); + bio_for_each_segment_all(bvec, io->bio, i) { + if (page == bvec->bv_page) { + up_read(&io->io_rwsem); + return true; + } } - curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, next_blkaddr) & - (sbi->blocks_per_seg - 1); - /* rewrite node page */ - set_page_writeback(page); - submit_write_page(sbi, page, new_blkaddr, NODE); - f2fs_submit_bio(sbi, NODE, true); - refresh_sit_entry(sbi, old_blkaddr, new_blkaddr); +out: + up_read(&io->io_rwsem); + return false; +} - locate_dirty_segment(sbi, old_cursegno); - locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); +void f2fs_wait_on_page_writeback(struct page *page, + enum page_type type) +{ + if (PageWriteback(page)) { + struct f2fs_sb_info *sbi = F2FS_P_SB(page); - mutex_unlock(&sit_i->sentry_lock); - mutex_unlock(&curseg->curseg_mutex); + if (is_merged_page(sbi, page, type)) + f2fs_submit_merged_bio(sbi, type, WRITE); + wait_on_page_writeback(page); + } } static int read_compacted_summaries(struct f2fs_sb_info *sbi) @@ -1079,7 +1472,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) segno = le32_to_cpu(ckpt->cur_data_segno[type]); blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - CURSEG_HOT_DATA]); - if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) + if (__exist_node_summaries(sbi)) blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type); else blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type); @@ -1088,7 +1481,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) CURSEG_HOT_NODE]); blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - CURSEG_HOT_NODE]); - if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) + if (__exist_node_summaries(sbi)) blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, type - CURSEG_HOT_NODE); else @@ -1099,7 +1492,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) sum = (struct f2fs_summary_block *)page_address(new); if (IS_NODESEG(type)) { - if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) { + if (__exist_node_summaries(sbi)) { struct f2fs_summary *ns = &sum->entries[0]; int i; for (i = 0; i < sbi->blocks_per_seg; i++, ns++) { @@ -1107,9 +1500,12 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ns->ofs_in_node = 0; } } else { - if (restore_node_summary(sbi, segno, sum)) { + int err; + + err = restore_node_summary(sbi, segno, sum); + if (err) { f2fs_put_page(new, 1); - return -EINVAL; + return err; } } } @@ -1130,17 +1526,31 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) static int restore_curseg_summaries(struct f2fs_sb_info *sbi) { int type = CURSEG_HOT_DATA; + int err; if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) { + int npages = npages_for_summary_flush(sbi, true); + + if (npages >= 2) + ra_meta_pages(sbi, start_sum_block(sbi), npages, + META_CP); + /* restore for compacted data summary */ if (read_compacted_summaries(sbi)) return -EINVAL; type = CURSEG_HOT_NODE; } - for (; type <= CURSEG_COLD_NODE; type++) - if (read_normal_summaries(sbi, type)) - return -EINVAL; + if (__exist_node_summaries(sbi)) + ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), + NR_CURSEG_TYPE - type, META_CP); + + for (; type <= CURSEG_COLD_NODE; type++) { + err = read_normal_summaries(sbi, type); + if (err) + return err; + } + return 0; } @@ -1167,8 +1577,6 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) SUM_JOURNAL_SIZE); written_size += SUM_JOURNAL_SIZE; - set_page_dirty(page); - /* Step 3: write summary entries */ for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { unsigned short blkoff; @@ -1187,18 +1595,20 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) summary = (struct f2fs_summary *)(kaddr + written_size); *summary = seg_i->sum_blk->entries[j]; written_size += SUMMARY_SIZE; - set_page_dirty(page); if (written_size + SUMMARY_SIZE <= PAGE_CACHE_SIZE - SUM_FOOTER_SIZE) continue; + set_page_dirty(page); f2fs_put_page(page, 1); page = NULL; } } - if (page) + if (page) { + set_page_dirty(page); f2fs_put_page(page, 1); + } } static void write_normal_summaries(struct f2fs_sb_info *sbi, @@ -1228,9 +1638,7 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk) void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk) { - if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) - write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); - return; + write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); } int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, @@ -1258,17 +1666,7 @@ int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, static struct page *get_current_sit_page(struct f2fs_sb_info *sbi, unsigned int segno) { - struct sit_info *sit_i = SIT_I(sbi); - unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno); - block_t blk_addr = sit_i->sit_base_addr + offset; - - check_seg_range(sbi, segno); - - /* calculate sit block address */ - if (f2fs_test_bit(offset, sit_i->sit_bitmap)) - blk_addr += sit_i->sit_blocks; - - return get_meta_page(sbi, blk_addr); + return get_meta_page(sbi, current_sit_addr(sbi, segno)); } static struct page *get_next_sit_page(struct f2fs_sb_info *sbi, @@ -1285,7 +1683,7 @@ static struct page *get_next_sit_page(struct f2fs_sb_info *sbi, /* get current sit block page without lock */ src_page = get_meta_page(sbi, src_off); dst_page = grab_meta_page(sbi, dst_off); - BUG_ON(PageDirty(src_page)); + f2fs_bug_on(sbi, PageDirty(src_page)); src_addr = page_address(src_page); dst_addr = page_address(dst_page); @@ -1299,97 +1697,192 @@ static struct page *get_next_sit_page(struct f2fs_sb_info *sbi, return dst_page; } -static bool flush_sits_in_journal(struct f2fs_sb_info *sbi) +static struct sit_entry_set *grab_sit_entry_set(void) +{ + struct sit_entry_set *ses = + f2fs_kmem_cache_alloc(sit_entry_set_slab, GFP_ATOMIC); + + ses->entry_cnt = 0; + INIT_LIST_HEAD(&ses->set_list); + return ses; +} + +static void release_sit_entry_set(struct sit_entry_set *ses) +{ + list_del(&ses->set_list); + kmem_cache_free(sit_entry_set_slab, ses); +} + +static void adjust_sit_entry_set(struct sit_entry_set *ses, + struct list_head *head) +{ + struct sit_entry_set *next = ses; + + if (list_is_last(&ses->set_list, head)) + return; + + list_for_each_entry_continue(next, head, set_list) + if (ses->entry_cnt <= next->entry_cnt) + break; + + list_move_tail(&ses->set_list, &next->set_list); +} + +static void add_sit_entry(unsigned int segno, struct list_head *head) +{ + struct sit_entry_set *ses; + unsigned int start_segno = START_SEGNO(segno); + + list_for_each_entry(ses, head, set_list) { + if (ses->start_segno == start_segno) { + ses->entry_cnt++; + adjust_sit_entry_set(ses, head); + return; + } + } + + ses = grab_sit_entry_set(); + + ses->start_segno = start_segno; + ses->entry_cnt++; + list_add(&ses->set_list, head); +} + +static void add_sits_in_set(struct f2fs_sb_info *sbi) +{ + struct f2fs_sm_info *sm_info = SM_I(sbi); + struct list_head *set_list = &sm_info->sit_entry_set; + unsigned long *bitmap = SIT_I(sbi)->dirty_sentries_bitmap; + unsigned int segno; + + for_each_set_bit(segno, bitmap, MAIN_SEGS(sbi)) + add_sit_entry(segno, set_list); +} + +static void remove_sits_in_journal(struct f2fs_sb_info *sbi) { struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); struct f2fs_summary_block *sum = curseg->sum_blk; int i; - /* - * If the journal area in the current summary is full of sit entries, - * all the sit entries will be flushed. Otherwise the sit entries - * are not able to replace with newly hot sit entries. - */ - if (sits_in_cursum(sum) >= SIT_JOURNAL_ENTRIES) { - for (i = sits_in_cursum(sum) - 1; i >= 0; i--) { - unsigned int segno; - segno = le32_to_cpu(segno_in_journal(sum, i)); - __mark_sit_entry_dirty(sbi, segno); - } - update_sits_in_cursum(sum, -sits_in_cursum(sum)); - return 1; + for (i = sits_in_cursum(sum) - 1; i >= 0; i--) { + unsigned int segno; + bool dirtied; + + segno = le32_to_cpu(segno_in_journal(sum, i)); + dirtied = __mark_sit_entry_dirty(sbi, segno); + + if (!dirtied) + add_sit_entry(segno, &SM_I(sbi)->sit_entry_set); } - return 0; + update_sits_in_cursum(sum, -sits_in_cursum(sum)); } /* * CP calls this function, which flushes SIT entries including sit_journal, * and moves prefree segs to free segs. */ -void flush_sit_entries(struct f2fs_sb_info *sbi) +void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct sit_info *sit_i = SIT_I(sbi); unsigned long *bitmap = sit_i->dirty_sentries_bitmap; struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); struct f2fs_summary_block *sum = curseg->sum_blk; - unsigned long nsegs = TOTAL_SEGS(sbi); - struct page *page = NULL; - struct f2fs_sit_block *raw_sit = NULL; - unsigned int start = 0, end = 0; - unsigned int segno = -1; - bool flushed; + struct sit_entry_set *ses, *tmp; + struct list_head *head = &SM_I(sbi)->sit_entry_set; + bool to_journal = true; + struct seg_entry *se; mutex_lock(&curseg->curseg_mutex); mutex_lock(&sit_i->sentry_lock); + if (!sit_i->dirty_sentries) + goto out; + + /* + * add and account sit entries of dirty bitmap in sit entry + * set temporarily + */ + add_sits_in_set(sbi); + /* - * "flushed" indicates whether sit entries in journal are flushed - * to the SIT area or not. + * if there are no enough space in journal to store dirty sit + * entries, remove all entries from journal and add and account + * them in sit entry set. */ - flushed = flush_sits_in_journal(sbi); + if (!__has_cursum_space(sum, sit_i->dirty_sentries, SIT_JOURNAL)) + remove_sits_in_journal(sbi); - while ((segno = find_next_bit(bitmap, nsegs, segno + 1)) < nsegs) { - struct seg_entry *se = get_seg_entry(sbi, segno); - int sit_offset, offset; + /* + * there are two steps to flush sit entries: + * #1, flush sit entries to journal in current cold data summary block. + * #2, flush sit entries to sit page. + */ + list_for_each_entry_safe(ses, tmp, head, set_list) { + struct page *page = NULL; + struct f2fs_sit_block *raw_sit = NULL; + unsigned int start_segno = ses->start_segno; + unsigned int end = min(start_segno + SIT_ENTRY_PER_BLOCK, + (unsigned long)MAIN_SEGS(sbi)); + unsigned int segno = start_segno; + + if (to_journal && + !__has_cursum_space(sum, ses->entry_cnt, SIT_JOURNAL)) + to_journal = false; + + if (!to_journal) { + page = get_next_sit_page(sbi, start_segno); + raw_sit = page_address(page); + } - sit_offset = SIT_ENTRY_OFFSET(sit_i, segno); + /* flush dirty sit entries in region of current sit set */ + for_each_set_bit_from(segno, bitmap, end) { + int offset, sit_offset; - if (flushed) - goto to_sit_page; + se = get_seg_entry(sbi, segno); - offset = lookup_journal_in_cursum(sum, SIT_JOURNAL, segno, 1); - if (offset >= 0) { - segno_in_journal(sum, offset) = cpu_to_le32(segno); - seg_info_to_raw_sit(se, &sit_in_journal(sum, offset)); - goto flush_done; - } -to_sit_page: - if (!page || (start > segno) || (segno > end)) { - if (page) { - f2fs_put_page(page, 1); - page = NULL; + /* add discard candidates */ + if (cpc->reason != CP_DISCARD) { + cpc->trim_start = segno; + add_discard_addrs(sbi, cpc); } - start = START_SEGNO(sit_i, segno); - end = start + SIT_ENTRY_PER_BLOCK - 1; + if (to_journal) { + offset = lookup_journal_in_cursum(sum, + SIT_JOURNAL, segno, 1); + f2fs_bug_on(sbi, offset < 0); + segno_in_journal(sum, offset) = + cpu_to_le32(segno); + seg_info_to_raw_sit(se, + &sit_in_journal(sum, offset)); + } else { + sit_offset = SIT_ENTRY_OFFSET(sit_i, segno); + seg_info_to_raw_sit(se, + &raw_sit->entries[sit_offset]); + } - /* read sit block that will be updated */ - page = get_next_sit_page(sbi, start); - raw_sit = page_address(page); + __clear_bit(segno, bitmap); + sit_i->dirty_sentries--; + ses->entry_cnt--; } - /* udpate entry in SIT block */ - seg_info_to_raw_sit(se, &raw_sit->entries[sit_offset]); -flush_done: - __clear_bit(segno, bitmap); - sit_i->dirty_sentries--; + if (!to_journal) + f2fs_put_page(page, 1); + + f2fs_bug_on(sbi, ses->entry_cnt); + release_sit_entry_set(ses); + } + + f2fs_bug_on(sbi, !list_empty(head)); + f2fs_bug_on(sbi, sit_i->dirty_sentries); +out: + if (cpc->reason == CP_DISCARD) { + for (; cpc->trim_start <= cpc->trim_end; cpc->trim_start++) + add_discard_addrs(sbi, cpc); } mutex_unlock(&sit_i->sentry_lock); mutex_unlock(&curseg->curseg_mutex); - /* writeout last modified SIT block */ - f2fs_put_page(page, 1); - set_prefree_as_free_segments(sbi); } @@ -1409,16 +1902,16 @@ static int build_sit_info(struct f2fs_sb_info *sbi) SM_I(sbi)->sit_info = sit_i; - sit_i->sentries = vzalloc(TOTAL_SEGS(sbi) * sizeof(struct seg_entry)); + sit_i->sentries = vzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry)); if (!sit_i->sentries) return -ENOMEM; - bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(sbi)); + bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); sit_i->dirty_sentries_bitmap = kzalloc(bitmap_size, GFP_KERNEL); if (!sit_i->dirty_sentries_bitmap) return -ENOMEM; - for (start = 0; start < TOTAL_SEGS(sbi); start++) { + for (start = 0; start < MAIN_SEGS(sbi); start++) { sit_i->sentries[start].cur_valid_map = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); sit_i->sentries[start].ckpt_valid_map @@ -1428,8 +1921,12 @@ static int build_sit_info(struct f2fs_sb_info *sbi) return -ENOMEM; } + sit_i->tmp_map = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); + if (!sit_i->tmp_map) + return -ENOMEM; + if (sbi->segs_per_sec > 1) { - sit_i->sec_entries = vzalloc(TOTAL_SECS(sbi) * + sit_i->sec_entries = vzalloc(MAIN_SECS(sbi) * sizeof(struct sec_entry)); if (!sit_i->sec_entries) return -ENOMEM; @@ -1464,7 +1961,6 @@ static int build_sit_info(struct f2fs_sb_info *sbi) static int build_free_segmap(struct f2fs_sb_info *sbi) { - struct f2fs_sm_info *sm_info = SM_I(sbi); struct free_segmap_info *free_i; unsigned int bitmap_size, sec_bitmap_size; @@ -1475,12 +1971,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi) SM_I(sbi)->free_info = free_i; - bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(sbi)); + bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); free_i->free_segmap = kmalloc(bitmap_size, GFP_KERNEL); if (!free_i->free_segmap) return -ENOMEM; - sec_bitmap_size = f2fs_bitmap_size(TOTAL_SECS(sbi)); + sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); free_i->free_secmap = kmalloc(sec_bitmap_size, GFP_KERNEL); if (!free_i->free_secmap) return -ENOMEM; @@ -1490,11 +1986,10 @@ static int build_free_segmap(struct f2fs_sb_info *sbi) memset(free_i->free_secmap, 0xff, sec_bitmap_size); /* init free segmap information */ - free_i->start_segno = - (unsigned int) GET_SEGNO_FROM_SEG0(sbi, sm_info->main_blkaddr); + free_i->start_segno = GET_SEGNO_FROM_SEG0(sbi, MAIN_BLKADDR(sbi)); free_i->free_segments = 0; free_i->free_sections = 0; - rwlock_init(&free_i->segmap_lock); + spin_lock_init(&free_i->segmap_lock); return 0; } @@ -1503,7 +1998,7 @@ static int build_curseg(struct f2fs_sb_info *sbi) struct curseg_info *array; int i; - array = kzalloc(sizeof(*array) * NR_CURSEG_TYPE, GFP_KERNEL); + array = kcalloc(NR_CURSEG_TYPE, sizeof(*array), GFP_KERNEL); if (!array) return -ENOMEM; @@ -1525,36 +2020,48 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) struct sit_info *sit_i = SIT_I(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); struct f2fs_summary_block *sum = curseg->sum_blk; - unsigned int start; + int sit_blk_cnt = SIT_BLK_CNT(sbi); + unsigned int i, start, end; + unsigned int readed, start_blk = 0; + int nrpages = MAX_BIO_BLOCKS(sbi); - for (start = 0; start < TOTAL_SEGS(sbi); start++) { - struct seg_entry *se = &sit_i->sentries[start]; - struct f2fs_sit_block *sit_blk; - struct f2fs_sit_entry sit; - struct page *page; - int i; - - mutex_lock(&curseg->curseg_mutex); - for (i = 0; i < sits_in_cursum(sum); i++) { - if (le32_to_cpu(segno_in_journal(sum, i)) == start) { - sit = sit_in_journal(sum, i); - mutex_unlock(&curseg->curseg_mutex); - goto got_it; + do { + readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT); + + start = start_blk * sit_i->sents_per_block; + end = (start_blk + readed) * sit_i->sents_per_block; + + for (; start < end && start < MAIN_SEGS(sbi); start++) { + struct seg_entry *se = &sit_i->sentries[start]; + struct f2fs_sit_block *sit_blk; + struct f2fs_sit_entry sit; + struct page *page; + + mutex_lock(&curseg->curseg_mutex); + for (i = 0; i < sits_in_cursum(sum); i++) { + if (le32_to_cpu(segno_in_journal(sum, i)) + == start) { + sit = sit_in_journal(sum, i); + mutex_unlock(&curseg->curseg_mutex); + goto got_it; + } } - } - mutex_unlock(&curseg->curseg_mutex); - page = get_current_sit_page(sbi, start); - sit_blk = (struct f2fs_sit_block *)page_address(page); - sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; - f2fs_put_page(page, 1); + mutex_unlock(&curseg->curseg_mutex); + + page = get_current_sit_page(sbi, start); + sit_blk = (struct f2fs_sit_block *)page_address(page); + sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; + f2fs_put_page(page, 1); got_it: - check_block_count(sbi, start, &sit); - seg_info_from_raw_sit(se, &sit); - if (sbi->segs_per_sec > 1) { - struct sec_entry *e = get_sec_entry(sbi, start); - e->valid_blocks += se->valid_blocks; + check_block_count(sbi, start, &sit); + seg_info_from_raw_sit(se, &sit); + if (sbi->segs_per_sec > 1) { + struct sec_entry *e = get_sec_entry(sbi, start); + e->valid_blocks += se->valid_blocks; + } } - } + start_blk += readed; + } while (start_blk < sit_blk_cnt); } static void init_free_segmap(struct f2fs_sb_info *sbi) @@ -1562,7 +2069,7 @@ static void init_free_segmap(struct f2fs_sb_info *sbi) unsigned int start; int type; - for (start = 0; start < TOTAL_SEGS(sbi); start++) { + for (start = 0; start < MAIN_SEGS(sbi); start++) { struct seg_entry *sentry = get_seg_entry(sbi, start); if (!sentry->valid_blocks) __set_free(sbi, start); @@ -1582,15 +2089,19 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi) unsigned int segno = 0, offset = 0; unsigned short valid_blocks; - while (segno < TOTAL_SEGS(sbi)) { + while (1) { /* find dirty segment based on free segmap */ - segno = find_next_inuse(free_i, TOTAL_SEGS(sbi), offset); - if (segno >= TOTAL_SEGS(sbi)) + segno = find_next_inuse(free_i, MAIN_SEGS(sbi), offset); + if (segno >= MAIN_SEGS(sbi)) break; offset = segno + 1; valid_blocks = get_valid_blocks(sbi, segno, 0); - if (valid_blocks >= sbi->blocks_per_seg || !valid_blocks) + if (valid_blocks == sbi->blocks_per_seg || !valid_blocks) continue; + if (valid_blocks > sbi->blocks_per_seg) { + f2fs_bug_on(sbi, 1); + continue; + } mutex_lock(&dirty_i->seglist_lock); __locate_dirty_segment(sbi, segno, DIRTY); mutex_unlock(&dirty_i->seglist_lock); @@ -1600,7 +2111,7 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi) static int init_victim_secmap(struct f2fs_sb_info *sbi) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - unsigned int bitmap_size = f2fs_bitmap_size(TOTAL_SECS(sbi)); + unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); dirty_i->victim_secmap = kzalloc(bitmap_size, GFP_KERNEL); if (!dirty_i->victim_secmap) @@ -1621,7 +2132,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi) SM_I(sbi)->dirty_info = dirty_i; mutex_init(&dirty_i->seglist_lock); - bitmap_size = f2fs_bitmap_size(TOTAL_SEGS(sbi)); + bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); for (i = 0; i < NR_DIRTY_TYPE; i++) { dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL); @@ -1645,7 +2156,7 @@ static void init_min_max_mtime(struct f2fs_sb_info *sbi) sit_i->min_mtime = LLONG_MAX; - for (segno = 0; segno < TOTAL_SEGS(sbi); segno += sbi->segs_per_sec) { + for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) { unsigned int i; unsigned long long mtime = 0; @@ -1674,8 +2185,6 @@ int build_segment_manager(struct f2fs_sb_info *sbi) /* init sm info */ sbi->sm_info = sm_info; - INIT_LIST_HEAD(&sm_info->wblist_head); - spin_lock_init(&sm_info->wblist_lock); sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr); sm_info->segment_count = le32_to_cpu(raw_super->segment_count); @@ -1683,6 +2192,25 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count); sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main); sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr); + sm_info->rec_prefree_segments = sm_info->main_segments * + DEF_RECLAIM_PREFREE_SEGMENTS / 100; + sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC; + sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; + sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; + + INIT_LIST_HEAD(&sm_info->discard_list); + sm_info->nr_discards = 0; + sm_info->max_discards = 0; + + sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS; + + INIT_LIST_HEAD(&sm_info->sit_entry_set); + + if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { + err = create_flush_cmd_control(sbi); + if (err) + return err; + } err = build_sit_info(sbi); if (err) @@ -1773,11 +2301,13 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi) return; if (sit_i->sentries) { - for (start = 0; start < TOTAL_SEGS(sbi); start++) { + for (start = 0; start < MAIN_SEGS(sbi); start++) { kfree(sit_i->sentries[start].cur_valid_map); kfree(sit_i->sentries[start].ckpt_valid_map); } } + kfree(sit_i->tmp_map); + vfree(sit_i->sentries); vfree(sit_i->sec_entries); kfree(sit_i->dirty_sentries_bitmap); @@ -1790,6 +2320,10 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi) void destroy_segment_manager(struct f2fs_sb_info *sbi) { struct f2fs_sm_info *sm_info = SM_I(sbi); + + if (!sm_info) + return; + destroy_flush_cmd_control(sbi); destroy_dirty_segmap(sbi); destroy_curseg(sbi); destroy_free_segmap(sbi); @@ -1797,3 +2331,36 @@ void destroy_segment_manager(struct f2fs_sb_info *sbi) sbi->sm_info = NULL; kfree(sm_info); } + +int __init create_segment_manager_caches(void) +{ + discard_entry_slab = f2fs_kmem_cache_create("discard_entry", + sizeof(struct discard_entry)); + if (!discard_entry_slab) + goto fail; + + sit_entry_set_slab = f2fs_kmem_cache_create("sit_entry_set", + sizeof(struct sit_entry_set)); + if (!sit_entry_set_slab) + goto destory_discard_entry; + + inmem_entry_slab = f2fs_kmem_cache_create("inmem_page_entry", + sizeof(struct inmem_pages)); + if (!inmem_entry_slab) + goto destroy_sit_entry_set; + return 0; + +destroy_sit_entry_set: + kmem_cache_destroy(sit_entry_set_slab); +destory_discard_entry: + kmem_cache_destroy(discard_entry_slab); +fail: + return -ENOMEM; +} + +void destroy_segment_manager_caches(void) +{ + kmem_cache_destroy(sit_entry_set_slab); + kmem_cache_destroy(discard_entry_slab); + kmem_cache_destroy(inmem_entry_slab); +} diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 062424a0e4c3a..85d7fa7514b2c 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -14,17 +14,14 @@ #define NULL_SEGNO ((unsigned int)(~0)) #define NULL_SECNO ((unsigned int)(~0)) +#define DEF_RECLAIM_PREFREE_SEGMENTS 5 /* 5% over total segments */ + /* L: Logical segment # in volume, R: Relative segment # in main area */ #define GET_L2R_SEGNO(free_i, segno) (segno - free_i->start_segno) #define GET_R2L_SEGNO(free_i, segno) (segno + free_i->start_segno) -#define IS_DATASEG(t) \ - ((t == CURSEG_HOT_DATA) || (t == CURSEG_COLD_DATA) || \ - (t == CURSEG_WARM_DATA)) - -#define IS_NODESEG(t) \ - ((t == CURSEG_HOT_NODE) || (t == CURSEG_COLD_NODE) || \ - (t == CURSEG_WARM_NODE)) +#define IS_DATASEG(t) (t <= CURSEG_COLD_DATA) +#define IS_NODESEG(t) (t >= CURSEG_HOT_NODE) #define IS_CURSEG(sbi, seg) \ ((seg == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno) || \ @@ -48,18 +45,31 @@ (secno == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno / \ sbi->segs_per_sec)) \ -#define START_BLOCK(sbi, segno) \ - (SM_I(sbi)->seg0_blkaddr + \ +#define MAIN_BLKADDR(sbi) (SM_I(sbi)->main_blkaddr) +#define SEG0_BLKADDR(sbi) (SM_I(sbi)->seg0_blkaddr) + +#define MAIN_SEGS(sbi) (SM_I(sbi)->main_segments) +#define MAIN_SECS(sbi) (sbi->total_sections) + +#define TOTAL_SEGS(sbi) (SM_I(sbi)->segment_count) +#define TOTAL_BLKS(sbi) (TOTAL_SEGS(sbi) << sbi->log_blocks_per_seg) + +#define MAX_BLKADDR(sbi) (SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi)) +#define SEGMENT_SIZE(sbi) (1ULL << (sbi->log_blocksize + \ + sbi->log_blocks_per_seg)) + +#define START_BLOCK(sbi, segno) (SEG0_BLKADDR(sbi) + \ (GET_R2L_SEGNO(FREE_I(sbi), segno) << sbi->log_blocks_per_seg)) + #define NEXT_FREE_BLKADDR(sbi, curseg) \ (START_BLOCK(sbi, curseg->segno) + curseg->next_blkoff) -#define MAIN_BASE_BLOCK(sbi) (SM_I(sbi)->main_blkaddr) - -#define GET_SEGOFF_FROM_SEG0(sbi, blk_addr) \ - ((blk_addr) - SM_I(sbi)->seg0_blkaddr) +#define GET_SEGOFF_FROM_SEG0(sbi, blk_addr) ((blk_addr) - SEG0_BLKADDR(sbi)) #define GET_SEGNO_FROM_SEG0(sbi, blk_addr) \ (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> sbi->log_blocks_per_seg) +#define GET_BLKOFF_FROM_SEG0(sbi, blk_addr) \ + (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (sbi->blocks_per_seg - 1)) + #define GET_SEGNO(sbi, blk_addr) \ (((blk_addr == NULL_ADDR) || (blk_addr == NEW_ADDR)) ? \ NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \ @@ -77,26 +87,21 @@ #define SIT_ENTRY_OFFSET(sit_i, segno) \ (segno % sit_i->sents_per_block) -#define SIT_BLOCK_OFFSET(sit_i, segno) \ +#define SIT_BLOCK_OFFSET(segno) \ (segno / SIT_ENTRY_PER_BLOCK) -#define START_SEGNO(sit_i, segno) \ - (SIT_BLOCK_OFFSET(sit_i, segno) * SIT_ENTRY_PER_BLOCK) +#define START_SEGNO(segno) \ + (SIT_BLOCK_OFFSET(segno) * SIT_ENTRY_PER_BLOCK) +#define SIT_BLK_CNT(sbi) \ + ((MAIN_SEGS(sbi) + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK) #define f2fs_bitmap_size(nr) \ (BITS_TO_LONGS(nr) * sizeof(unsigned long)) -#define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments) -#define TOTAL_SECS(sbi) (sbi->total_sections) - -#define SECTOR_FROM_BLOCK(sbi, blk_addr) \ - (blk_addr << ((sbi)->log_blocksize - F2FS_LOG_SECTOR_SIZE)) -#define SECTOR_TO_BLOCK(sbi, sectors) \ - (sectors >> ((sbi)->log_blocksize - F2FS_LOG_SECTOR_SIZE)) - -/* during checkpoint, bio_private is used to synchronize the last bio */ -struct bio_private { - struct f2fs_sb_info *sbi; - bool is_sync; - void *wait; -}; + +#define SECTOR_FROM_BLOCK(blk_addr) \ + (((sector_t)blk_addr) << F2FS_LOG_SECTORS_PER_BLOCK) +#define SECTOR_TO_BLOCK(sectors) \ + (sectors >> F2FS_LOG_SECTORS_PER_BLOCK) +#define MAX_BIO_BLOCKS(sbi) \ + ((int)min((int)max_hw_blocks(sbi), BIO_MAX_PAGES)) /* * indicate a block allocation direction: RIGHT and LEFT. @@ -142,6 +147,7 @@ struct victim_sel_policy { int alloc_mode; /* LFS or SSR */ int gc_mode; /* GC_CB or GC_GREEDY */ unsigned long *dirty_segmap; /* dirty segment bitmap */ + unsigned int max_search; /* maximum # of segments to search */ unsigned int offset; /* last scanned bitmap offset */ unsigned int ofs_unit; /* bitmap search unit */ unsigned int min_cost; /* minimum cost */ @@ -169,6 +175,11 @@ struct segment_allocation { void (*allocate_segment)(struct f2fs_sb_info *, int, bool); }; +struct inmem_pages { + struct list_head list; + struct page *page; +}; + struct sit_info { const struct segment_allocation *s_ops; @@ -178,6 +189,7 @@ struct sit_info { char *sit_bitmap; /* SIT bitmap pointer */ unsigned int bitmap_size; /* SIT bitmap size */ + unsigned long *tmp_map; /* bitmap for temporal use */ unsigned long *dirty_sentries_bitmap; /* bitmap for dirty sentries */ unsigned int dirty_sentries; /* # of dirty sentries */ unsigned int sents_per_block; /* # of SIT entries per block */ @@ -196,7 +208,7 @@ struct free_segmap_info { unsigned int start_segno; /* start segment number logically */ unsigned int free_segments; /* # of free segments */ unsigned int free_sections; /* # of free sections */ - rwlock_t segmap_lock; /* free segmap lock */ + spinlock_t segmap_lock; /* free segmap lock */ unsigned long *free_segmap; /* free segment bitmap */ unsigned long *free_secmap; /* free section bitmap */ }; @@ -239,6 +251,12 @@ struct curseg_info { unsigned int next_segno; /* preallocated segment */ }; +struct sit_entry_set { + struct list_head set_list; /* link with all sit sets */ + unsigned int start_segno; /* start segno of sits in set */ + unsigned int entry_cnt; /* the # of sit entries in set */ +}; + /* * inline functions */ @@ -301,9 +319,9 @@ static inline unsigned int find_next_inuse(struct free_segmap_info *free_i, unsigned int max, unsigned int segno) { unsigned int ret; - read_lock(&free_i->segmap_lock); + spin_lock(&free_i->segmap_lock); ret = find_next_bit(free_i->free_segmap, max, segno); - read_unlock(&free_i->segmap_lock); + spin_unlock(&free_i->segmap_lock); return ret; } @@ -314,16 +332,17 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno) unsigned int start_segno = secno * sbi->segs_per_sec; unsigned int next; - write_lock(&free_i->segmap_lock); + spin_lock(&free_i->segmap_lock); clear_bit(segno, free_i->free_segmap); free_i->free_segments++; - next = find_next_bit(free_i->free_segmap, TOTAL_SEGS(sbi), start_segno); + next = find_next_bit(free_i->free_segmap, + start_segno + sbi->segs_per_sec, start_segno); if (next >= start_segno + sbi->segs_per_sec) { clear_bit(secno, free_i->free_secmap); free_i->free_sections++; } - write_unlock(&free_i->segmap_lock); + spin_unlock(&free_i->segmap_lock); } static inline void __set_inuse(struct f2fs_sb_info *sbi, @@ -345,18 +364,18 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, unsigned int start_segno = secno * sbi->segs_per_sec; unsigned int next; - write_lock(&free_i->segmap_lock); + spin_lock(&free_i->segmap_lock); if (test_and_clear_bit(segno, free_i->free_segmap)) { free_i->free_segments++; - next = find_next_bit(free_i->free_segmap, TOTAL_SEGS(sbi), - start_segno); + next = find_next_bit(free_i->free_segmap, + start_segno + sbi->segs_per_sec, start_segno); if (next >= start_segno + sbi->segs_per_sec) { if (test_and_clear_bit(secno, free_i->free_secmap)) free_i->free_sections++; } } - write_unlock(&free_i->segmap_lock); + spin_unlock(&free_i->segmap_lock); } static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi, @@ -364,13 +383,13 @@ static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi, { struct free_segmap_info *free_i = FREE_I(sbi); unsigned int secno = segno / sbi->segs_per_sec; - write_lock(&free_i->segmap_lock); + spin_lock(&free_i->segmap_lock); if (!test_and_set_bit(segno, free_i->free_segmap)) { free_i->free_segments--; if (!test_and_set_bit(secno, free_i->free_secmap)) free_i->free_sections--; } - write_unlock(&free_i->segmap_lock); + spin_unlock(&free_i->segmap_lock); } static inline void get_sit_bitmap(struct f2fs_sb_info *sbi, @@ -382,26 +401,12 @@ static inline void get_sit_bitmap(struct f2fs_sb_info *sbi, static inline block_t written_block_count(struct f2fs_sb_info *sbi) { - struct sit_info *sit_i = SIT_I(sbi); - block_t vblocks; - - mutex_lock(&sit_i->sentry_lock); - vblocks = sit_i->written_valid_blocks; - mutex_unlock(&sit_i->sentry_lock); - - return vblocks; + return SIT_I(sbi)->written_valid_blocks; } static inline unsigned int free_segments(struct f2fs_sb_info *sbi) { - struct free_segmap_info *free_i = FREE_I(sbi); - unsigned int free_segs; - - read_lock(&free_i->segmap_lock); - free_segs = free_i->free_segments; - read_unlock(&free_i->segmap_lock); - - return free_segs; + return FREE_I(sbi)->free_segments; } static inline int reserved_segments(struct f2fs_sb_info *sbi) @@ -411,14 +416,7 @@ static inline int reserved_segments(struct f2fs_sb_info *sbi) static inline unsigned int free_sections(struct f2fs_sb_info *sbi) { - struct free_segmap_info *free_i = FREE_I(sbi); - unsigned int free_secs; - - read_lock(&free_i->segmap_lock); - free_secs = free_i->free_sections; - read_unlock(&free_i->segmap_lock); - - return free_secs; + return FREE_I(sbi)->free_sections; } static inline unsigned int prefree_segments(struct f2fs_sb_info *sbi) @@ -453,7 +451,10 @@ static inline int reserved_sections(struct f2fs_sb_info *sbi) static inline bool need_SSR(struct f2fs_sb_info *sbi) { - return (free_sections(sbi) < overprovision_sections(sbi)); + int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); + int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); + return free_sections(sbi) <= (node_secs + 2 * dent_secs + + reserved_sections(sbi) + 1); } static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed) @@ -461,33 +462,74 @@ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed) int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); - if (sbi->por_doing) + if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) return false; - return ((free_sections(sbi) + freed) <= (node_secs + 2 * dent_secs + - reserved_sections(sbi))); + return (free_sections(sbi) + freed) <= (node_secs + 2 * dent_secs + + reserved_sections(sbi)); +} + +static inline bool excess_prefree_segs(struct f2fs_sb_info *sbi) +{ + return prefree_segments(sbi) > SM_I(sbi)->rec_prefree_segments; } static inline int utilization(struct f2fs_sb_info *sbi) { - return div_u64(valid_user_blocks(sbi) * 100, sbi->user_block_count); + return div_u64((u64)valid_user_blocks(sbi) * 100, + sbi->user_block_count); } /* * Sometimes f2fs may be better to drop out-of-place update policy. - * So, if fs utilization is over MIN_IPU_UTIL, then f2fs tries to write - * data in the original place likewise other traditional file systems. - * But, currently set 100 in percentage, which means it is disabled. - * See below need_inplace_update(). + * And, users can control the policy through sysfs entries. + * There are five policies with triggering conditions as follows. + * F2FS_IPU_FORCE - all the time, + * F2FS_IPU_SSR - if SSR mode is activated, + * F2FS_IPU_UTIL - if FS utilization is over threashold, + * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over + * threashold, + * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash + * storages. IPU will be triggered only if the # of dirty + * pages over min_fsync_blocks. + * F2FS_IPUT_DISABLE - disable IPU. (=default option) */ -#define MIN_IPU_UTIL 100 +#define DEF_MIN_IPU_UTIL 70 +#define DEF_MIN_FSYNC_BLOCKS 8 + +enum { + F2FS_IPU_FORCE, + F2FS_IPU_SSR, + F2FS_IPU_UTIL, + F2FS_IPU_SSR_UTIL, + F2FS_IPU_FSYNC, +}; + static inline bool need_inplace_update(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - if (S_ISDIR(inode->i_mode)) + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + unsigned int policy = SM_I(sbi)->ipu_policy; + + /* IPU can be done only for the user data */ + if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode)) return false; - if (need_SSR(sbi) && utilization(sbi) > MIN_IPU_UTIL) + + if (policy & (0x1 << F2FS_IPU_FORCE)) + return true; + if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi)) + return true; + if (policy & (0x1 << F2FS_IPU_UTIL) && + utilization(sbi) > SM_I(sbi)->min_ipu_util) + return true; + if (policy & (0x1 << F2FS_IPU_SSR_UTIL) && need_SSR(sbi) && + utilization(sbi) > SM_I(sbi)->min_ipu_util) + return true; + + /* this is only set during fdatasync */ + if (policy & (0x1 << F2FS_IPU_FSYNC) && + is_inode_flag_set(F2FS_I(inode), FI_NEED_IPU)) return true; + return false; } @@ -511,55 +553,84 @@ static inline unsigned short curseg_blkoff(struct f2fs_sb_info *sbi, int type) return curseg->next_blkoff; } +#ifdef CONFIG_F2FS_CHECK_FS static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno) { - unsigned int end_segno = SM_I(sbi)->segment_count - 1; - BUG_ON(segno > end_segno); + BUG_ON(segno > TOTAL_SEGS(sbi) - 1); } -/* - * This function is used for only debugging. - * NOTE: In future, we have to remove this function. - */ static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr) { - struct f2fs_sm_info *sm_info = SM_I(sbi); - block_t total_blks = sm_info->segment_count << sbi->log_blocks_per_seg; - block_t start_addr = sm_info->seg0_blkaddr; - block_t end_addr = start_addr + total_blks - 1; - BUG_ON(blk_addr < start_addr); - BUG_ON(blk_addr > end_addr); + BUG_ON(blk_addr < SEG0_BLKADDR(sbi)); + BUG_ON(blk_addr >= MAX_BLKADDR(sbi)); } /* - * Summary block is always treated as invalid block + * Summary block is always treated as an invalid block */ static inline void check_block_count(struct f2fs_sb_info *sbi, int segno, struct f2fs_sit_entry *raw_sit) { - struct f2fs_sm_info *sm_info = SM_I(sbi); - unsigned int end_segno = sm_info->segment_count - 1; + bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false; int valid_blocks = 0; - int i; + int cur_pos = 0, next_pos; /* check segment usage */ BUG_ON(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg); /* check boundary of a given segment number */ - BUG_ON(segno > end_segno); + BUG_ON(segno > TOTAL_SEGS(sbi) - 1); /* check bitmap with valid block count */ - for (i = 0; i < sbi->blocks_per_seg; i++) - if (f2fs_test_bit(i, raw_sit->valid_map)) - valid_blocks++; + do { + if (is_valid) { + next_pos = find_next_zero_bit_le(&raw_sit->valid_map, + sbi->blocks_per_seg, + cur_pos); + valid_blocks += next_pos - cur_pos; + } else + next_pos = find_next_bit_le(&raw_sit->valid_map, + sbi->blocks_per_seg, + cur_pos); + cur_pos = next_pos; + is_valid = !is_valid; + } while (cur_pos < sbi->blocks_per_seg); BUG_ON(GET_SIT_VBLOCKS(raw_sit) != valid_blocks); } +#else +static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno) +{ + if (segno > TOTAL_SEGS(sbi) - 1) + set_sbi_flag(sbi, SBI_NEED_FSCK); +} + +static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr) +{ + if (blk_addr < SEG0_BLKADDR(sbi) || blk_addr >= MAX_BLKADDR(sbi)) + set_sbi_flag(sbi, SBI_NEED_FSCK); +} + +/* + * Summary block is always treated as an invalid block + */ +static inline void check_block_count(struct f2fs_sb_info *sbi, + int segno, struct f2fs_sit_entry *raw_sit) +{ + /* check segment usage */ + if (GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg) + set_sbi_flag(sbi, SBI_NEED_FSCK); + + /* check boundary of a given segment number */ + if (segno > TOTAL_SEGS(sbi) - 1) + set_sbi_flag(sbi, SBI_NEED_FSCK); +} +#endif static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi, unsigned int start) { struct sit_info *sit_i = SIT_I(sbi); - unsigned int offset = SIT_BLOCK_OFFSET(sit_i, start); + unsigned int offset = SIT_BLOCK_OFFSET(start); block_t blk_addr = sit_i->sit_base_addr + offset; check_seg_range(sbi, start); @@ -586,12 +657,9 @@ static inline pgoff_t next_sit_addr(struct f2fs_sb_info *sbi, static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start) { - unsigned int block_off = SIT_BLOCK_OFFSET(sit_i, start); + unsigned int block_off = SIT_BLOCK_OFFSET(start); - if (f2fs_test_bit(block_off, sit_i->sit_bitmap)) - f2fs_clear_bit(block_off, sit_i->sit_bitmap); - else - f2fs_set_bit(block_off, sit_i->sit_bitmap); + f2fs_change_bit(block_off, sit_i->sit_bitmap); } static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) @@ -633,5 +701,51 @@ static inline unsigned int max_hw_blocks(struct f2fs_sb_info *sbi) { struct block_device *bdev = sbi->sb->s_bdev; struct request_queue *q = bdev_get_queue(bdev); - return SECTOR_TO_BLOCK(sbi, queue_max_sectors(q)); + return SECTOR_TO_BLOCK(queue_max_sectors(q)); +} + +/* + * It is very important to gather dirty pages and write at once, so that we can + * submit a big bio without interfering other data writes. + * By default, 512 pages for directory data, + * 512 pages (2MB) * 3 for three types of nodes, and + * max_bio_blocks for meta are set. + */ +static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) +{ + if (sbi->sb->s_bdi->dirty_exceeded) + return 0; + + if (type == DATA) + return sbi->blocks_per_seg; + else if (type == NODE) + return 3 * sbi->blocks_per_seg; + else if (type == META) + return MAX_BIO_BLOCKS(sbi); + else + return 0; +} + +/* + * When writing pages, it'd better align nr_to_write for segment size. + */ +static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type, + struct writeback_control *wbc) +{ + long nr_to_write, desired; + + if (wbc->sync_mode != WB_SYNC_NONE) + return 0; + + nr_to_write = wbc->nr_to_write; + + if (type == DATA) + desired = 4096; + else if (type == NODE) + desired = 3 * max_hw_blocks(sbi); + else + desired = MAX_BIO_BLOCKS(sbi); + + wbc->nr_to_write = desired; + return desired - nr_to_write; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8555f7df82c79..160b88346b247 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -18,45 +18,224 @@ #include #include #include +#include #include #include #include #include +#include #include "f2fs.h" #include "node.h" #include "segment.h" #include "xattr.h" +#include "gc.h" +#include "trace.h" #define CREATE_TRACE_POINTS #include +static struct proc_dir_entry *f2fs_proc_root; static struct kmem_cache *f2fs_inode_cachep; +static struct kset *f2fs_kset; enum { - Opt_gc_background_off, + Opt_gc_background, Opt_disable_roll_forward, + Opt_norecovery, Opt_discard, Opt_noheap, + Opt_user_xattr, Opt_nouser_xattr, + Opt_acl, Opt_noacl, Opt_active_logs, Opt_disable_ext_identify, + Opt_inline_xattr, + Opt_inline_data, + Opt_inline_dentry, + Opt_flush_merge, + Opt_nobarrier, + Opt_fastboot, + Opt_extent_cache, + Opt_noinline_data, Opt_err, }; static match_table_t f2fs_tokens = { - {Opt_gc_background_off, "background_gc_off"}, + {Opt_gc_background, "background_gc=%s"}, {Opt_disable_roll_forward, "disable_roll_forward"}, + {Opt_norecovery, "norecovery"}, {Opt_discard, "discard"}, {Opt_noheap, "no_heap"}, + {Opt_user_xattr, "user_xattr"}, {Opt_nouser_xattr, "nouser_xattr"}, + {Opt_acl, "acl"}, {Opt_noacl, "noacl"}, {Opt_active_logs, "active_logs=%u"}, {Opt_disable_ext_identify, "disable_ext_identify"}, + {Opt_inline_xattr, "inline_xattr"}, + {Opt_inline_data, "inline_data"}, + {Opt_inline_dentry, "inline_dentry"}, + {Opt_flush_merge, "flush_merge"}, + {Opt_nobarrier, "nobarrier"}, + {Opt_fastboot, "fastboot"}, + {Opt_extent_cache, "extent_cache"}, + {Opt_noinline_data, "noinline_data"}, {Opt_err, NULL}, }; +/* Sysfs support for f2fs */ +enum { + GC_THREAD, /* struct f2fs_gc_thread */ + SM_INFO, /* struct f2fs_sm_info */ + NM_INFO, /* struct f2fs_nm_info */ + F2FS_SBI, /* struct f2fs_sb_info */ +}; + +struct f2fs_attr { + struct attribute attr; + ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *); + ssize_t (*store)(struct f2fs_attr *, struct f2fs_sb_info *, + const char *, size_t); + int struct_type; + int offset; +}; + +static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) +{ + if (struct_type == GC_THREAD) + return (unsigned char *)sbi->gc_thread; + else if (struct_type == SM_INFO) + return (unsigned char *)SM_I(sbi); + else if (struct_type == NM_INFO) + return (unsigned char *)NM_I(sbi); + else if (struct_type == F2FS_SBI) + return (unsigned char *)sbi; + return NULL; +} + +static ssize_t f2fs_sbi_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + unsigned char *ptr = NULL; + unsigned int *ui; + + ptr = __struct_ptr(sbi, a->struct_type); + if (!ptr) + return -EINVAL; + + ui = (unsigned int *)(ptr + a->offset); + + return snprintf(buf, PAGE_SIZE, "%u\n", *ui); +} + +static ssize_t f2fs_sbi_store(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, + const char *buf, size_t count) +{ + unsigned char *ptr; + unsigned long t; + unsigned int *ui; + ssize_t ret; + + ptr = __struct_ptr(sbi, a->struct_type); + if (!ptr) + return -EINVAL; + + ui = (unsigned int *)(ptr + a->offset); + + ret = kstrtoul(skip_spaces(buf), 0, &t); + if (ret < 0) + return ret; + *ui = t; + return count; +} + +static ssize_t f2fs_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_kobj); + struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); + + return a->show ? a->show(a, sbi, buf) : 0; +} + +static ssize_t f2fs_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_kobj); + struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); + + return a->store ? a->store(a, sbi, buf, len) : 0; +} + +static void f2fs_sb_release(struct kobject *kobj) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_kobj); + complete(&sbi->s_kobj_unregister); +} + +#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ +static struct f2fs_attr f2fs_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ + .struct_type = _struct_type, \ + .offset = _offset \ +} + +#define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ + F2FS_ATTR_OFFSET(struct_type, name, 0644, \ + f2fs_sbi_show, f2fs_sbi_store, \ + offsetof(struct struct_name, elname)) + +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time); +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time); +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, max_small_discards, max_discards); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); +F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); + +#define ATTR_LIST(name) (&f2fs_attr_##name.attr) +static struct attribute *f2fs_attrs[] = { + ATTR_LIST(gc_min_sleep_time), + ATTR_LIST(gc_max_sleep_time), + ATTR_LIST(gc_no_gc_sleep_time), + ATTR_LIST(gc_idle), + ATTR_LIST(reclaim_segments), + ATTR_LIST(max_small_discards), + ATTR_LIST(batched_trim_sections), + ATTR_LIST(ipu_policy), + ATTR_LIST(min_ipu_util), + ATTR_LIST(min_fsync_blocks), + ATTR_LIST(max_victim_search), + ATTR_LIST(dir_level), + ATTR_LIST(ram_thresh), + NULL, +}; + +static const struct sysfs_ops f2fs_attr_ops = { + .show = f2fs_attr_show, + .store = f2fs_attr_store, +}; + +static struct kobj_type f2fs_ktype = { + .default_attrs = f2fs_attrs, + .sysfs_ops = &f2fs_attr_ops, + .release = f2fs_sb_release, +}; + void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...) { struct va_format vaf; @@ -76,11 +255,143 @@ static void init_once(void *foo) inode_init_once(&fi->vfs_inode); } +static int parse_options(struct super_block *sb, char *options) +{ + struct f2fs_sb_info *sbi = F2FS_SB(sb); + substring_t args[MAX_OPT_ARGS]; + char *p, *name; + int arg = 0; + + if (!options) + return 0; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + if (!*p) + continue; + /* + * Initialize args struct so we know whether arg was + * found; some options take optional arguments. + */ + args[0].to = args[0].from = NULL; + token = match_token(p, f2fs_tokens, args); + + switch (token) { + case Opt_gc_background: + name = match_strdup(&args[0]); + + if (!name) + return -ENOMEM; + if (strlen(name) == 2 && !strncmp(name, "on", 2)) + set_opt(sbi, BG_GC); + else if (strlen(name) == 3 && !strncmp(name, "off", 3)) + clear_opt(sbi, BG_GC); + else { + kfree(name); + return -EINVAL; + } + kfree(name); + break; + case Opt_disable_roll_forward: + set_opt(sbi, DISABLE_ROLL_FORWARD); + break; + case Opt_norecovery: + /* this option mounts f2fs with ro */ + set_opt(sbi, DISABLE_ROLL_FORWARD); + if (!f2fs_readonly(sb)) + return -EINVAL; + break; + case Opt_discard: + set_opt(sbi, DISCARD); + break; + case Opt_noheap: + set_opt(sbi, NOHEAP); + break; +#ifdef CONFIG_F2FS_FS_XATTR + case Opt_user_xattr: + set_opt(sbi, XATTR_USER); + break; + case Opt_nouser_xattr: + clear_opt(sbi, XATTR_USER); + break; + case Opt_inline_xattr: + set_opt(sbi, INLINE_XATTR); + break; +#else + case Opt_user_xattr: + f2fs_msg(sb, KERN_INFO, + "user_xattr options not supported"); + break; + case Opt_nouser_xattr: + f2fs_msg(sb, KERN_INFO, + "nouser_xattr options not supported"); + break; + case Opt_inline_xattr: + f2fs_msg(sb, KERN_INFO, + "inline_xattr options not supported"); + break; +#endif +#ifdef CONFIG_F2FS_FS_POSIX_ACL + case Opt_acl: + set_opt(sbi, POSIX_ACL); + break; + case Opt_noacl: + clear_opt(sbi, POSIX_ACL); + break; +#else + case Opt_acl: + f2fs_msg(sb, KERN_INFO, "acl options not supported"); + break; + case Opt_noacl: + f2fs_msg(sb, KERN_INFO, "noacl options not supported"); + break; +#endif + case Opt_active_logs: + if (args->from && match_int(args, &arg)) + return -EINVAL; + if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE) + return -EINVAL; + sbi->active_logs = arg; + break; + case Opt_disable_ext_identify: + set_opt(sbi, DISABLE_EXT_IDENTIFY); + break; + case Opt_inline_data: + set_opt(sbi, INLINE_DATA); + break; + case Opt_inline_dentry: + set_opt(sbi, INLINE_DENTRY); + break; + case Opt_flush_merge: + set_opt(sbi, FLUSH_MERGE); + break; + case Opt_nobarrier: + set_opt(sbi, NOBARRIER); + break; + case Opt_fastboot: + set_opt(sbi, FASTBOOT); + break; + case Opt_extent_cache: + set_opt(sbi, EXTENT_CACHE); + break; + case Opt_noinline_data: + clear_opt(sbi, INLINE_DATA); + break; + default: + f2fs_msg(sb, KERN_ERR, + "Unrecognized mount option \"%s\" or missing value", + p); + return -EINVAL; + } + } + return 0; +} + static struct inode *f2fs_alloc_inode(struct super_block *sb) { struct f2fs_inode_info *fi; - fi = kmem_cache_alloc(f2fs_inode_cachep, GFP_NOFS | __GFP_ZERO); + fi = kmem_cache_alloc(f2fs_inode_cachep, GFP_F2FS_ZERO); if (!fi) return NULL; @@ -88,13 +399,23 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) /* Initialize f2fs-specific inode info */ fi->vfs_inode.i_version = 1; - atomic_set(&fi->dirty_dents, 0); + atomic_set(&fi->dirty_pages, 0); fi->i_current_depth = 1; fi->i_advise = 0; - rwlock_init(&fi->ext.ext_lock); + rwlock_init(&fi->ext_lock); + init_rwsem(&fi->i_sem); + INIT_RADIX_TREE(&fi->inmem_root, GFP_NOFS); + INIT_LIST_HEAD(&fi->inmem_pages); + mutex_init(&fi->inmem_lock); set_inode_flag(fi, FI_NEW_INODE); + if (test_opt(F2FS_SB(sb), INLINE_XATTR)) + set_inode_flag(fi, FI_INLINE_XATTR); + + /* Will be used by directory only */ + fi->i_dir_level = F2FS_SB(sb)->dir_level; + return &fi->vfs_inode; } @@ -112,6 +433,16 @@ static int f2fs_drop_inode(struct inode *inode) return generic_drop_inode(inode); } +/* + * f2fs_dirty_inode() is called from __mark_inode_dirty() + * + * We should call set_dirty_inode to write the dirty inode through write_inode. + */ +static void f2fs_dirty_inode(struct inode *inode, int flags) +{ + set_inode_flag(F2FS_I(inode), FI_DIRTY_INODE); +} + static void f2fs_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); @@ -127,10 +458,34 @@ static void f2fs_put_super(struct super_block *sb) { struct f2fs_sb_info *sbi = F2FS_SB(sb); + if (sbi->s_proc) { + remove_proc_entry("segment_info", sbi->s_proc); + remove_proc_entry(sb->s_id, f2fs_proc_root); + } + kobject_del(&sbi->s_kobj); + f2fs_destroy_stats(sbi); stop_gc_thread(sbi); - write_checkpoint(sbi, true); + /* + * We don't need to do checkpoint when superblock is clean. + * But, the previous checkpoint was not done by umount, it needs to do + * clean checkpoint again. + */ + if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || + !is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG)) { + struct cp_control cpc = { + .reason = CP_UMOUNT, + }; + write_checkpoint(sbi, &cpc); + } + + /* + * normally superblock is clean, so we need to release this. + * In addition, EIO will skip do checkpoint, we need this as well. + */ + release_dirty_inode(sbi); + release_discard_addrs(sbi); iput(sbi->node_inode); iput(sbi->meta_inode); @@ -140,6 +495,8 @@ static void f2fs_put_super(struct super_block *sb) destroy_segment_manager(sbi); kfree(sbi->ckpt); + kobject_put(&sbi->s_kobj); + wait_for_completion(&sbi->s_kobj_unregister); sb->s_fs_info = NULL; brelse(sbi->raw_super_buf); @@ -152,16 +509,18 @@ int f2fs_sync_fs(struct super_block *sb, int sync) trace_f2fs_sync_fs(sb, sync); - if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) - return 0; - if (sync) { + struct cp_control cpc; + + cpc.reason = __get_cp_reason(sbi); + mutex_lock(&sbi->gc_mutex); - write_checkpoint(sbi, false); + write_checkpoint(sbi, &cpc); mutex_unlock(&sbi->gc_mutex); } else { f2fs_balance_fs(sbi); } + f2fs_trace_ios(NULL, NULL, 1); return 0; } @@ -170,7 +529,7 @@ static int f2fs_freeze(struct super_block *sb) { int err; - if (sb->s_flags & MS_RDONLY) + if (f2fs_readonly(sb)) return 0; err = f2fs_sync_fs(sb, 1); @@ -200,8 +559,8 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; buf->f_bavail = user_block_count - valid_user_blocks(sbi); - buf->f_files = sbi->total_node_count; - buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi); + buf->f_files = sbi->total_node_count - F2FS_RESERVED_NODE_NUM; + buf->f_ffree = buf->f_files - valid_inode_count(sbi); buf->f_namelen = F2FS_NAME_LEN; buf->f_fsid.val[0] = (u32)id; @@ -214,10 +573,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) { struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb); - if (test_opt(sbi, BG_GC)) - seq_puts(seq, ",background_gc_on"); + if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC)) + seq_printf(seq, ",background_gc=%s", "on"); else - seq_puts(seq, ",background_gc_off"); + seq_printf(seq, ",background_gc=%s", "off"); if (test_opt(sbi, DISABLE_ROLL_FORWARD)) seq_puts(seq, ",disable_roll_forward"); if (test_opt(sbi, DISCARD)) @@ -229,6 +588,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) seq_puts(seq, ",user_xattr"); else seq_puts(seq, ",nouser_xattr"); + if (test_opt(sbi, INLINE_XATTR)) + seq_puts(seq, ",inline_xattr"); #endif #ifdef CONFIG_F2FS_FS_POSIX_ACL if (test_opt(sbi, POSIX_ACL)) @@ -238,17 +599,151 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) #endif if (test_opt(sbi, DISABLE_EXT_IDENTIFY)) seq_puts(seq, ",disable_ext_identify"); - + if (test_opt(sbi, INLINE_DATA)) + seq_puts(seq, ",inline_data"); + else + seq_puts(seq, ",noinline_data"); + if (test_opt(sbi, INLINE_DENTRY)) + seq_puts(seq, ",inline_dentry"); + if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE)) + seq_puts(seq, ",flush_merge"); + if (test_opt(sbi, NOBARRIER)) + seq_puts(seq, ",nobarrier"); + if (test_opt(sbi, FASTBOOT)) + seq_puts(seq, ",fastboot"); + if (test_opt(sbi, EXTENT_CACHE)) + seq_puts(seq, ",extent_cache"); seq_printf(seq, ",active_logs=%u", sbi->active_logs); return 0; } +static int segment_info_seq_show(struct seq_file *seq, void *offset) +{ + struct super_block *sb = seq->private; + struct f2fs_sb_info *sbi = F2FS_SB(sb); + unsigned int total_segs = + le32_to_cpu(sbi->raw_super->segment_count_main); + int i; + + seq_puts(seq, "format: segment_type|valid_blocks\n" + "segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n"); + + for (i = 0; i < total_segs; i++) { + struct seg_entry *se = get_seg_entry(sbi, i); + + if ((i % 10) == 0) + seq_printf(seq, "%-5d", i); + seq_printf(seq, "%d|%-3u", se->type, + get_valid_blocks(sbi, i, 1)); + if ((i % 10) == 9 || i == (total_segs - 1)) + seq_putc(seq, '\n'); + else + seq_putc(seq, ' '); + } + + return 0; +} + +static int segment_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, segment_info_seq_show, PDE_DATA(inode)); +} + +static const struct file_operations f2fs_seq_segment_info_fops = { + .owner = THIS_MODULE, + .open = segment_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int f2fs_remount(struct super_block *sb, int *flags, char *data) +{ + struct f2fs_sb_info *sbi = F2FS_SB(sb); + struct f2fs_mount_info org_mount_opt; + int err, active_logs; + bool need_restart_gc = false; + bool need_stop_gc = false; + + sync_filesystem(sb); + + /* + * Save the old mount options in case we + * need to restore them. + */ + org_mount_opt = sbi->mount_opt; + active_logs = sbi->active_logs; + + sbi->mount_opt.opt = 0; + sbi->active_logs = NR_CURSEG_TYPE; + + /* parse mount options */ + err = parse_options(sb, data); + if (err) + goto restore_opts; + + /* + * Previous and new state of filesystem is RO, + * so skip checking GC and FLUSH_MERGE conditions. + */ + if (f2fs_readonly(sb) && (*flags & MS_RDONLY)) + goto skip; + + /* + * We stop the GC thread if FS is mounted as RO + * or if background_gc = off is passed in mount + * option. Also sync the filesystem. + */ + if ((*flags & MS_RDONLY) || !test_opt(sbi, BG_GC)) { + if (sbi->gc_thread) { + stop_gc_thread(sbi); + f2fs_sync_fs(sb, 1); + need_restart_gc = true; + } + } else if (!sbi->gc_thread) { + err = start_gc_thread(sbi); + if (err) + goto restore_opts; + need_stop_gc = true; + } + + /* + * We stop issue flush thread if FS is mounted as RO + * or if flush_merge is not passed in mount option. + */ + if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { + destroy_flush_cmd_control(sbi); + } else if (!SM_I(sbi)->cmd_control_info) { + err = create_flush_cmd_control(sbi); + if (err) + goto restore_gc; + } +skip: + /* Update the POSIXACL Flag */ + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | + (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0); + return 0; +restore_gc: + if (need_restart_gc) { + if (start_gc_thread(sbi)) + f2fs_msg(sbi->sb, KERN_WARNING, + "background gc thread has stopped"); + } else if (need_stop_gc) { + stop_gc_thread(sbi); + } +restore_opts: + sbi->mount_opt = org_mount_opt; + sbi->active_logs = active_logs; + return err; +} + static struct super_operations f2fs_sops = { .alloc_inode = f2fs_alloc_inode, .drop_inode = f2fs_drop_inode, .destroy_inode = f2fs_destroy_inode, .write_inode = f2fs_write_inode, + .dirty_inode = f2fs_dirty_inode, .show_options = f2fs_show_options, .evict_inode = f2fs_evict_inode, .put_super = f2fs_put_super, @@ -256,6 +751,7 @@ static struct super_operations f2fs_sops = { .freeze_fs = f2fs_freeze, .unfreeze_fs = f2fs_unfreeze, .statfs = f2fs_statfs, + .remount_fs = f2fs_remount, }; static struct inode *f2fs_nfs_get_inode(struct super_block *sb, @@ -264,7 +760,7 @@ static struct inode *f2fs_nfs_get_inode(struct super_block *sb, struct f2fs_sb_info *sbi = F2FS_SB(sb); struct inode *inode; - if (ino < F2FS_ROOT_INO(sbi)) + if (check_nid_range(sbi, ino)) return ERR_PTR(-ESTALE); /* @@ -275,7 +771,7 @@ static struct inode *f2fs_nfs_get_inode(struct super_block *sb, inode = f2fs_iget(sb, ino); if (IS_ERR(inode)) return ERR_CAST(inode); - if (generation && inode->i_generation != generation) { + if (unlikely(generation && inode->i_generation != generation)) { /* we didn't find the right inode.. */ iput(inode); return ERR_PTR(-ESTALE); @@ -303,82 +799,9 @@ static const struct export_operations f2fs_export_ops = { .get_parent = f2fs_get_parent, }; -static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, - char *options) -{ - substring_t args[MAX_OPT_ARGS]; - char *p; - int arg = 0; - - if (!options) - return 0; - - while ((p = strsep(&options, ",")) != NULL) { - int token; - if (!*p) - continue; - /* - * Initialize args struct so we know whether arg was - * found; some options take optional arguments. - */ - args[0].to = args[0].from = NULL; - token = match_token(p, f2fs_tokens, args); - - switch (token) { - case Opt_gc_background_off: - clear_opt(sbi, BG_GC); - break; - case Opt_disable_roll_forward: - set_opt(sbi, DISABLE_ROLL_FORWARD); - break; - case Opt_discard: - set_opt(sbi, DISCARD); - break; - case Opt_noheap: - set_opt(sbi, NOHEAP); - break; -#ifdef CONFIG_F2FS_FS_XATTR - case Opt_nouser_xattr: - clear_opt(sbi, XATTR_USER); - break; -#else - case Opt_nouser_xattr: - f2fs_msg(sb, KERN_INFO, - "nouser_xattr options not supported"); - break; -#endif -#ifdef CONFIG_F2FS_FS_POSIX_ACL - case Opt_noacl: - clear_opt(sbi, POSIX_ACL); - break; -#else - case Opt_noacl: - f2fs_msg(sb, KERN_INFO, "noacl options not supported"); - break; -#endif - case Opt_active_logs: - if (args->from && match_int(args, &arg)) - return -EINVAL; - if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE) - return -EINVAL; - sbi->active_logs = arg; - break; - case Opt_disable_ext_identify: - set_opt(sbi, DISABLE_EXT_IDENTIFY); - break; - default: - f2fs_msg(sb, KERN_ERR, - "Unrecognized mount option \"%s\" or missing value", - p); - return -EINVAL; - } - } - return 0; -} - static loff_t max_file_size(unsigned bits) { - loff_t result = ADDRS_PER_INODE; + loff_t result = (DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS); loff_t leaf_count = ADDRS_PER_BLOCK; /* two direct node blocks */ @@ -425,14 +848,22 @@ static int sanity_check_raw_super(struct super_block *sb, return 1; } - if (le32_to_cpu(raw_super->log_sectorsize) != - F2FS_LOG_SECTOR_SIZE) { - f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize"); + /* Currently, support 512/1024/2048/4096 bytes sector size */ + if (le32_to_cpu(raw_super->log_sectorsize) > + F2FS_MAX_LOG_SECTOR_SIZE || + le32_to_cpu(raw_super->log_sectorsize) < + F2FS_MIN_LOG_SECTOR_SIZE) { + f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize (%u)", + le32_to_cpu(raw_super->log_sectorsize)); return 1; } - if (le32_to_cpu(raw_super->log_sectors_per_block) != - F2FS_LOG_SECTORS_PER_BLOCK) { - f2fs_msg(sb, KERN_INFO, "Invalid log sectors per block"); + if (le32_to_cpu(raw_super->log_sectors_per_block) + + le32_to_cpu(raw_super->log_sectorsize) != + F2FS_MAX_LOG_SECTOR_SIZE) { + f2fs_msg(sb, KERN_INFO, + "Invalid log sectors per block(%u) log sectorsize(%u)", + le32_to_cpu(raw_super->log_sectors_per_block), + le32_to_cpu(raw_super->log_sectorsize)); return 1; } return 0; @@ -451,10 +882,10 @@ static int sanity_check_ckpt(struct f2fs_sb_info *sbi) fsmeta += le32_to_cpu(ckpt->rsvd_segment_count); fsmeta += le32_to_cpu(raw_super->segment_count_ssa); - if (fsmeta >= total) + if (unlikely(fsmeta >= total)) return 1; - if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) { + if (unlikely(f2fs_cp_error(sbi))) { f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); return 1; } @@ -482,69 +913,92 @@ static void init_sb_info(struct f2fs_sb_info *sbi) sbi->node_ino_num = le32_to_cpu(raw_super->node_ino); sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino); sbi->cur_victim_sec = NULL_SECNO; + sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH; for (i = 0; i < NR_COUNT_TYPE; i++) atomic_set(&sbi->nr_pages[i], 0); + + sbi->dir_level = DEF_DIR_LEVEL; + clear_sbi_flag(sbi, SBI_NEED_FSCK); } -static int validate_superblock(struct super_block *sb, - struct f2fs_super_block **raw_super, - struct buffer_head **raw_super_buf, sector_t block) +/* + * Read f2fs raw super block. + * Because we have two copies of super block, so read the first one at first, + * if the first one is invalid, move to read the second one. + */ +static int read_raw_super_block(struct super_block *sb, + struct f2fs_super_block **raw_super, + struct buffer_head **raw_super_buf) { - const char *super = (block == 0 ? "first" : "second"); + int block = 0; - /* read f2fs raw super block */ +retry: *raw_super_buf = sb_bread(sb, block); if (!*raw_super_buf) { - f2fs_msg(sb, KERN_ERR, "unable to read %s superblock", - super); - return -EIO; + f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock", + block + 1); + if (block == 0) { + block++; + goto retry; + } else { + return -EIO; + } } *raw_super = (struct f2fs_super_block *) ((char *)(*raw_super_buf)->b_data + F2FS_SUPER_OFFSET); /* sanity checking of raw super */ - if (!sanity_check_raw_super(sb, *raw_super)) - return 0; + if (sanity_check_raw_super(sb, *raw_super)) { + brelse(*raw_super_buf); + f2fs_msg(sb, KERN_ERR, + "Can't find valid F2FS filesystem in %dth superblock", + block + 1); + if (block == 0) { + block++; + goto retry; + } else { + return -EINVAL; + } + } - f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem " - "in %s superblock", super); - return -EINVAL; + return 0; } static int f2fs_fill_super(struct super_block *sb, void *data, int silent) { struct f2fs_sb_info *sbi; - struct f2fs_super_block *raw_super; + struct f2fs_super_block *raw_super = NULL; struct buffer_head *raw_super_buf; struct inode *root; long err = -EINVAL; + bool retry = true, need_fsck = false; + char *options = NULL; int i; +try_onemore: /* allocate memory for f2fs-specific super block info */ sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); if (!sbi) return -ENOMEM; /* set a block size */ - if (!sb_set_blocksize(sb, F2FS_BLKSIZE)) { + if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) { f2fs_msg(sb, KERN_ERR, "unable to set blocksize"); goto free_sbi; } - err = validate_superblock(sb, &raw_super, &raw_super_buf, 0); - if (err) { - brelse(raw_super_buf); - /* check secondary superblock when primary failed */ - err = validate_superblock(sb, &raw_super, &raw_super_buf, 1); - if (err) - goto free_sb_buf; - } + err = read_raw_super_block(sb, &raw_super, &raw_super_buf); + if (err) + goto free_sbi; + + sb->s_fs_info = sbi; /* init some FS parameters */ sbi->active_logs = NR_CURSEG_TYPE; set_opt(sbi, BG_GC); + set_opt(sbi, INLINE_DATA); #ifdef CONFIG_F2FS_FS_XATTR set_opt(sbi, XATTR_USER); @@ -553,9 +1007,15 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) set_opt(sbi, POSIX_ACL); #endif /* parse mount options */ - err = parse_options(sb, sbi, (char *)data); - if (err) + options = kstrdup((const char *)data, GFP_KERNEL); + if (data && !options) { + err = -ENOMEM; goto free_sb_buf; + } + + err = parse_options(sb, options); + if (err) + goto free_options; sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); sb->s_max_links = F2FS_LINK_MAX; @@ -565,7 +1025,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) sb->s_xattr = f2fs_xattr_handlers; sb->s_export_op = &f2fs_export_ops; sb->s_magic = F2FS_SUPER_MAGIC; - sb->s_fs_info = sbi; sb->s_time_gran = 1; sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0); @@ -576,14 +1035,22 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) sbi->raw_super = raw_super; sbi->raw_super_buf = raw_super_buf; mutex_init(&sbi->gc_mutex); - mutex_init(&sbi->writepages); mutex_init(&sbi->cp_mutex); - for (i = 0; i < NR_GLOBAL_LOCKS; i++) - mutex_init(&sbi->fs_lock[i]); - mutex_init(&sbi->node_write); - sbi->por_doing = 0; + init_rwsem(&sbi->node_write); + clear_sbi_flag(sbi, SBI_POR_DOING); spin_lock_init(&sbi->stat_lock); - init_rwsem(&sbi->bio_sem); + + init_rwsem(&sbi->read_io.io_rwsem); + sbi->read_io.sbi = sbi; + sbi->read_io.bio = NULL; + for (i = 0; i < NR_PAGE_TYPE; i++) { + init_rwsem(&sbi->write_io[i].io_rwsem); + sbi->write_io[i].sbi = sbi; + sbi->write_io[i].bio = NULL; + } + + init_rwsem(&sbi->cp_rwsem); + init_waitqueue_head(&sbi->cp_wait); init_sb_info(sbi); /* get an inode for meta space */ @@ -591,7 +1058,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (IS_ERR(sbi->meta_inode)) { f2fs_msg(sb, KERN_ERR, "Failed to read F2FS meta data inode"); err = PTR_ERR(sbi->meta_inode); - goto free_sb_buf; + goto free_options; } err = get_valid_checkpoint(sbi); @@ -619,7 +1086,9 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) INIT_LIST_HEAD(&sbi->dir_inode_list); spin_lock_init(&sbi->dir_inode_lock); - init_orphan_info(sbi); + init_extent_cache_info(sbi); + + init_ino_entry_info(sbi); /* setup f2fs internal modules */ err = build_segment_manager(sbi); @@ -646,9 +1115,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) } /* if there are nt orphan nodes free them */ - err = -EINVAL; - if (recover_orphan_inodes(sbi)) - goto free_node_inode; + recover_orphan_inodes(sbi); /* read root inode and dentry */ root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); @@ -657,8 +1124,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) err = PTR_ERR(root); goto free_node_inode; } - if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) - goto free_root_inode; + if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { + iput(root); + err = -EINVAL; + goto free_node_inode; + } sb->s_root = d_make_root(root); /* allocate root dentry */ if (!sb->s_root) { @@ -666,22 +1136,16 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_root_inode; } - /* recover fsynced data */ - if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { - err = recover_fsync_data(sbi); - if (err) - f2fs_msg(sb, KERN_ERR, - "Cannot recover all fsync data errno=%ld", err); - } - - /* After POR, we can run background GC thread */ - err = start_gc_thread(sbi); - if (err) - goto fail; - err = f2fs_build_stats(sbi); if (err) - goto fail; + goto free_root_inode; + + if (f2fs_proc_root) + sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); + + if (sbi->s_proc) + proc_create_data("segment_info", S_IRUGO, sbi->s_proc, + &f2fs_seq_segment_info_fops, sb); if (test_opt(sbi, DISCARD)) { struct request_queue *q = bdev_get_queue(sb->s_bdev); @@ -691,9 +1155,58 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) "the device does not support discard"); } + sbi->s_kobj.kset = f2fs_kset; + init_completion(&sbi->s_kobj_unregister); + err = kobject_init_and_add(&sbi->s_kobj, &f2fs_ktype, NULL, + "%s", sb->s_id); + if (err) + goto free_proc; + + /* recover fsynced data */ + if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { + /* + * mount should be failed, when device has readonly mode, and + * previous checkpoint was not done by clean system shutdown. + */ + if (bdev_read_only(sb->s_bdev) && + !is_set_ckpt_flags(sbi->ckpt, CP_UMOUNT_FLAG)) { + err = -EROFS; + goto free_kobj; + } + + if (need_fsck) + set_sbi_flag(sbi, SBI_NEED_FSCK); + + err = recover_fsync_data(sbi); + if (err) { + need_fsck = true; + f2fs_msg(sb, KERN_ERR, + "Cannot recover all fsync data errno=%ld", err); + goto free_kobj; + } + } + + /* + * If filesystem is not mounted as read-only then + * do start the gc_thread. + */ + if (test_opt(sbi, BG_GC) && !f2fs_readonly(sb)) { + /* After POR, we can run background GC thread.*/ + err = start_gc_thread(sbi); + if (err) + goto free_kobj; + } + kfree(options); return 0; -fail: - stop_gc_thread(sbi); + +free_kobj: + kobject_del(&sbi->s_kobj); +free_proc: + if (sbi->s_proc) { + remove_proc_entry("segment_info", sbi->s_proc); + remove_proc_entry(sb->s_id, f2fs_proc_root); + } + f2fs_destroy_stats(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -708,10 +1221,19 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) free_meta_inode: make_bad_inode(sbi->meta_inode); iput(sbi->meta_inode); +free_options: + kfree(options); free_sb_buf: brelse(raw_super_buf); free_sbi: kfree(sbi); + + /* give only one another chance */ + if (retry) { + retry = false; + shrink_dcache_sb(sb); + goto try_onemore; + } return err; } @@ -721,11 +1243,18 @@ static struct dentry *f2fs_mount(struct file_system_type *fs_type, int flags, return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super); } +static void kill_f2fs_super(struct super_block *sb) +{ + if (sb->s_root) + set_sbi_flag(F2FS_SB(sb), SBI_IS_CLOSE); + kill_block_super(sb); +} + static struct file_system_type f2fs_fs_type = { .owner = THIS_MODULE, .name = "f2fs", .mount = f2fs_mount, - .kill_sb = kill_block_super, + .kill_sb = kill_f2fs_super, .fs_flags = FS_REQUIRES_DEV, }; MODULE_ALIAS_FS("f2fs"); @@ -733,8 +1262,8 @@ MODULE_ALIAS_FS("f2fs"); static int __init init_inodecache(void) { f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache", - sizeof(struct f2fs_inode_info), NULL); - if (f2fs_inode_cachep == NULL) + sizeof(struct f2fs_inode_info)); + if (!f2fs_inode_cachep) return -ENOMEM; return 0; } @@ -753,34 +1282,63 @@ static int __init init_f2fs_fs(void) { int err; + f2fs_build_trace_ios(); + err = init_inodecache(); if (err) goto fail; err = create_node_manager_caches(); if (err) - goto fail; - err = create_gc_caches(); + goto free_inodecache; + err = create_segment_manager_caches(); if (err) - goto fail; + goto free_node_manager_caches; err = create_checkpoint_caches(); if (err) - goto fail; + goto free_segment_manager_caches; + err = create_extent_cache(); + if (err) + goto free_checkpoint_caches; + f2fs_kset = kset_create_and_add("f2fs", NULL, fs_kobj); + if (!f2fs_kset) { + err = -ENOMEM; + goto free_extent_cache; + } err = register_filesystem(&f2fs_fs_type); if (err) - goto fail; + goto free_kset; f2fs_create_root_stats(); + f2fs_proc_root = proc_mkdir("fs/f2fs", NULL); + return 0; + +free_kset: + kset_unregister(f2fs_kset); +free_extent_cache: + destroy_extent_cache(); +free_checkpoint_caches: + destroy_checkpoint_caches(); +free_segment_manager_caches: + destroy_segment_manager_caches(); +free_node_manager_caches: + destroy_node_manager_caches(); +free_inodecache: + destroy_inodecache(); fail: return err; } static void __exit exit_f2fs_fs(void) { + remove_proc_entry("fs/f2fs", NULL); f2fs_destroy_root_stats(); unregister_filesystem(&f2fs_fs_type); + destroy_extent_cache(); destroy_checkpoint_caches(); - destroy_gc_caches(); + destroy_segment_manager_caches(); destroy_node_manager_caches(); destroy_inodecache(); + kset_unregister(f2fs_kset); + f2fs_destroy_trace_ios(); } module_init(init_f2fs_fs) diff --git a/fs/f2fs/trace.c b/fs/f2fs/trace.c new file mode 100644 index 0000000000000..875aa8179bc17 --- /dev/null +++ b/fs/f2fs/trace.c @@ -0,0 +1,159 @@ +/* + * f2fs IO tracer + * + * Copyright (c) 2014 Motorola Mobility + * Copyright (c) 2014 Jaegeuk Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +#include "f2fs.h" +#include "trace.h" + +static RADIX_TREE(pids, GFP_ATOMIC); +static spinlock_t pids_lock; +static struct last_io_info last_io; + +static inline void __print_last_io(void) +{ + if (!last_io.len) + return; + + trace_printk("%3x:%3x %4x %-16s %2x %5x %12x %4x\n", + last_io.major, last_io.minor, + last_io.pid, "----------------", + last_io.type, + last_io.fio.rw, last_io.fio.blk_addr, + last_io.len); + memset(&last_io, 0, sizeof(last_io)); +} + +static int __file_type(struct inode *inode, pid_t pid) +{ + if (f2fs_is_atomic_file(inode)) + return __ATOMIC_FILE; + else if (f2fs_is_volatile_file(inode)) + return __VOLATILE_FILE; + else if (S_ISDIR(inode->i_mode)) + return __DIR_FILE; + else if (inode->i_ino == F2FS_NODE_INO(F2FS_I_SB(inode))) + return __NODE_FILE; + else if (inode->i_ino == F2FS_META_INO(F2FS_I_SB(inode))) + return __META_FILE; + else if (pid) + return __NORMAL_FILE; + else + return __MISC_FILE; +} + +void f2fs_trace_pid(struct page *page) +{ + struct inode *inode = page->mapping->host; + pid_t pid = task_pid_nr(current); + void *p; + + page->private = pid; + + if (radix_tree_preload(GFP_NOFS)) + return; + + spin_lock(&pids_lock); + p = radix_tree_lookup(&pids, pid); + if (p == current) + goto out; + if (p) + radix_tree_delete(&pids, pid); + + f2fs_radix_tree_insert(&pids, pid, current); + + trace_printk("%3x:%3x %4x %-16s\n", + MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), + pid, current->comm); +out: + spin_unlock(&pids_lock); + radix_tree_preload_end(); +} + +void f2fs_trace_ios(struct page *page, struct f2fs_io_info *fio, int flush) +{ + struct inode *inode; + pid_t pid; + int major, minor; + + if (flush) { + __print_last_io(); + return; + } + + inode = page->mapping->host; + pid = page_private(page); + + major = MAJOR(inode->i_sb->s_dev); + minor = MINOR(inode->i_sb->s_dev); + + if (last_io.major == major && last_io.minor == minor && + last_io.pid == pid && + last_io.type == __file_type(inode, pid) && + last_io.fio.rw == fio->rw && + last_io.fio.blk_addr + last_io.len == fio->blk_addr) { + last_io.len++; + return; + } + + __print_last_io(); + + last_io.major = major; + last_io.minor = minor; + last_io.pid = pid; + last_io.type = __file_type(inode, pid); + last_io.fio = *fio; + last_io.len = 1; + return; +} + +void f2fs_build_trace_ios(void) +{ + spin_lock_init(&pids_lock); +} + +#define PIDVEC_SIZE 128 +static unsigned int gang_lookup_pids(pid_t *results, unsigned long first_index, + unsigned int max_items) +{ + struct radix_tree_iter iter; + void **slot; + unsigned int ret = 0; + + if (unlikely(!max_items)) + return 0; + + radix_tree_for_each_slot(slot, &pids, &iter, first_index) { + results[ret] = iter.index; + if (++ret == PIDVEC_SIZE) + break; + } + return ret; +} + +void f2fs_destroy_trace_ios(void) +{ + pid_t pid[PIDVEC_SIZE]; + pid_t next_pid = 0; + unsigned int found; + + spin_lock(&pids_lock); + while ((found = gang_lookup_pids(pid, next_pid, PIDVEC_SIZE))) { + unsigned idx; + + next_pid = pid[found - 1] + 1; + for (idx = 0; idx < found; idx++) + radix_tree_delete(&pids, pid[idx]); + } + spin_unlock(&pids_lock); +} diff --git a/fs/f2fs/trace.h b/fs/f2fs/trace.h new file mode 100644 index 0000000000000..1041dbeb52ae4 --- /dev/null +++ b/fs/f2fs/trace.h @@ -0,0 +1,46 @@ +/* + * f2fs IO tracer + * + * Copyright (c) 2014 Motorola Mobility + * Copyright (c) 2014 Jaegeuk Kim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __F2FS_TRACE_H__ +#define __F2FS_TRACE_H__ + +#ifdef CONFIG_F2FS_IO_TRACE +#include + +enum file_type { + __NORMAL_FILE, + __DIR_FILE, + __NODE_FILE, + __META_FILE, + __ATOMIC_FILE, + __VOLATILE_FILE, + __MISC_FILE, +}; + +struct last_io_info { + int major, minor; + pid_t pid; + enum file_type type; + struct f2fs_io_info fio; + block_t len; +}; + +extern void f2fs_trace_pid(struct page *); +extern void f2fs_trace_ios(struct page *, struct f2fs_io_info *, int); +extern void f2fs_build_trace_ios(void); +extern void f2fs_destroy_trace_ios(void); +#else +#define f2fs_trace_pid(p) +#define f2fs_trace_ios(p, i, n) +#define f2fs_build_trace_ios() +#define f2fs_destroy_trace_ios() + +#endif +#endif /* __F2FS_TRACE_H__ */ diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 0b02dce313565..0569d5f8b5527 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -20,11 +20,12 @@ */ #include #include +#include #include "f2fs.h" #include "xattr.h" static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, - size_t list_size, const char *name, size_t name_len, int type) + size_t list_size, const char *name, size_t len, int type) { struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); int total_len, prefix_len = 0; @@ -43,15 +44,19 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, prefix = XATTR_TRUSTED_PREFIX; prefix_len = XATTR_TRUSTED_PREFIX_LEN; break; + case F2FS_XATTR_INDEX_SECURITY: + prefix = XATTR_SECURITY_PREFIX; + prefix_len = XATTR_SECURITY_PREFIX_LEN; + break; default: return -EINVAL; } - total_len = prefix_len + name_len + 1; + total_len = prefix_len + len + 1; if (list && total_len <= list_size) { memcpy(list, prefix, prefix_len); - memcpy(list+prefix_len, name, name_len); - list[prefix_len + name_len] = '\0'; + memcpy(list + prefix_len, name, len); + list[prefix_len + len] = '\0'; } return total_len; } @@ -70,13 +75,14 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, if (!capable(CAP_SYS_ADMIN)) return -EPERM; break; + case F2FS_XATTR_INDEX_SECURITY: + break; default: return -EINVAL; } if (strcmp(name, "") == 0) return -EINVAL; - return f2fs_getxattr(dentry->d_inode, type, name, - buffer, size); + return f2fs_getxattr(dentry->d_inode, type, name, buffer, size, NULL); } static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, @@ -93,17 +99,20 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, if (!capable(CAP_SYS_ADMIN)) return -EPERM; break; + case F2FS_XATTR_INDEX_SECURITY: + break; default: return -EINVAL; } if (strcmp(name, "") == 0) return -EINVAL; - return f2fs_setxattr(dentry->d_inode, type, name, value, size); + return f2fs_setxattr(dentry->d_inode, type, name, + value, size, NULL, flags); } static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, - size_t list_size, const char *name, size_t name_len, int type) + size_t list_size, const char *name, size_t len, int type) { const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; size_t size; @@ -125,7 +134,8 @@ static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name, if (strcmp(name, "") != 0) return -EINVAL; - *((char *)buffer) = F2FS_I(inode)->i_advise; + if (buffer) + *((char *)buffer) = F2FS_I(inode)->i_advise; return sizeof(char); } @@ -142,9 +152,35 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, return -EINVAL; F2FS_I(inode)->i_advise |= *(char *)value; + mark_inode_dirty(inode); return 0; } +#ifdef CONFIG_F2FS_FS_SECURITY +static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, + void *page) +{ + const struct xattr *xattr; + int err = 0; + + for (xattr = xattr_array; xattr->name != NULL; xattr++) { + err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY, + xattr->name, xattr->value, + xattr->value_len, (struct page *)page, 0); + if (err < 0) + break; + } + return err; +} + +int f2fs_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, struct page *ipage) +{ + return security_inode_init_security(inode, dir, qstr, + &f2fs_initxattrs, ipage); +} +#endif + const struct xattr_handler f2fs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = F2FS_XATTR_INDEX_USER, @@ -169,6 +205,14 @@ const struct xattr_handler f2fs_xattr_advise_handler = { .set = f2fs_xattr_advise_set, }; +const struct xattr_handler f2fs_xattr_security_handler = { + .prefix = XATTR_SECURITY_PREFIX, + .flags = F2FS_XATTR_INDEX_SECURITY, + .list = f2fs_xattr_generic_list, + .get = f2fs_xattr_generic_get, + .set = f2fs_xattr_generic_set, +}; + static const struct xattr_handler *f2fs_xattr_handler_map[] = { [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler, #ifdef CONFIG_F2FS_FS_POSIX_ACL @@ -176,6 +220,9 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = { [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler, #endif [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler, +#ifdef CONFIG_F2FS_FS_SECURITY + [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler, +#endif [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler, }; @@ -186,89 +233,225 @@ const struct xattr_handler *f2fs_xattr_handlers[] = { &f2fs_xattr_acl_default_handler, #endif &f2fs_xattr_trusted_handler, +#ifdef CONFIG_F2FS_FS_SECURITY + &f2fs_xattr_security_handler, +#endif &f2fs_xattr_advise_handler, NULL, }; -static inline const struct xattr_handler *f2fs_xattr_handler(int name_index) +static inline const struct xattr_handler *f2fs_xattr_handler(int index) { const struct xattr_handler *handler = NULL; - if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map)) - handler = f2fs_xattr_handler_map[name_index]; + if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map)) + handler = f2fs_xattr_handler_map[index]; return handler; } -int f2fs_getxattr(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) +static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index, + size_t len, const char *name) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_xattr_entry *entry; - struct page *page; - void *base_addr; - int error = 0, found = 0; - size_t value_len, name_len; - - if (name == NULL) - return -EINVAL; - name_len = strlen(name); - - if (!fi->i_xattr_nid) - return -ENODATA; - - page = get_node_page(sbi, fi->i_xattr_nid); - base_addr = page_address(page); list_for_each_xattr(entry, base_addr) { - if (entry->e_name_index != name_index) + if (entry->e_name_index != index) continue; - if (entry->e_name_len != name_len) + if (entry->e_name_len != len) continue; - if (!memcmp(entry->e_name, name, name_len)) { - found = 1; + if (!memcmp(entry->e_name, name, len)) break; + } + return entry; +} + +static void *read_all_xattrs(struct inode *inode, struct page *ipage) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_xattr_header *header; + size_t size = PAGE_SIZE, inline_size = 0; + void *txattr_addr; + + inline_size = inline_xattr_size(inode); + + txattr_addr = kzalloc(inline_size + size, GFP_F2FS_ZERO); + if (!txattr_addr) + return NULL; + + /* read from inline xattr */ + if (inline_size) { + struct page *page = NULL; + void *inline_addr; + + if (ipage) { + inline_addr = inline_xattr_addr(ipage); + } else { + page = get_node_page(sbi, inode->i_ino); + if (IS_ERR(page)) + goto fail; + inline_addr = inline_xattr_addr(page); + } + memcpy(txattr_addr, inline_addr, inline_size); + f2fs_put_page(page, 1); + } + + /* read from xattr node block */ + if (F2FS_I(inode)->i_xattr_nid) { + struct page *xpage; + void *xattr_addr; + + /* The inode already has an extended attribute block. */ + xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid); + if (IS_ERR(xpage)) + goto fail; + + xattr_addr = page_address(xpage); + memcpy(txattr_addr + inline_size, xattr_addr, PAGE_SIZE); + f2fs_put_page(xpage, 1); + } + + header = XATTR_HDR(txattr_addr); + + /* never been allocated xattrs */ + if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) { + header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC); + header->h_refcount = cpu_to_le32(1); + } + return txattr_addr; +fail: + kzfree(txattr_addr); + return NULL; +} + +static inline int write_all_xattrs(struct inode *inode, __u32 hsize, + void *txattr_addr, struct page *ipage) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + size_t inline_size = 0; + void *xattr_addr; + struct page *xpage; + nid_t new_nid = 0; + int err; + + inline_size = inline_xattr_size(inode); + + if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid) + if (!alloc_nid(sbi, &new_nid)) + return -ENOSPC; + + /* write to inline xattr */ + if (inline_size) { + struct page *page = NULL; + void *inline_addr; + + if (ipage) { + inline_addr = inline_xattr_addr(ipage); + f2fs_wait_on_page_writeback(ipage, NODE); + } else { + page = get_node_page(sbi, inode->i_ino); + if (IS_ERR(page)) { + alloc_nid_failed(sbi, new_nid); + return PTR_ERR(page); + } + inline_addr = inline_xattr_addr(page); + f2fs_wait_on_page_writeback(page, NODE); + } + memcpy(inline_addr, txattr_addr, inline_size); + f2fs_put_page(page, 1); + + /* no need to use xattr node block */ + if (hsize <= inline_size) { + err = truncate_xattr_node(inode, ipage); + alloc_nid_failed(sbi, new_nid); + return err; + } + } + + /* write to xattr node block */ + if (F2FS_I(inode)->i_xattr_nid) { + xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid); + if (IS_ERR(xpage)) { + alloc_nid_failed(sbi, new_nid); + return PTR_ERR(xpage); } + f2fs_bug_on(sbi, new_nid); + f2fs_wait_on_page_writeback(xpage, NODE); + } else { + struct dnode_of_data dn; + set_new_dnode(&dn, inode, NULL, NULL, new_nid); + xpage = new_node_page(&dn, XATTR_NODE_OFFSET, ipage); + if (IS_ERR(xpage)) { + alloc_nid_failed(sbi, new_nid); + return PTR_ERR(xpage); + } + alloc_nid_done(sbi, new_nid); } - if (!found) { + + xattr_addr = page_address(xpage); + memcpy(xattr_addr, txattr_addr + inline_size, PAGE_SIZE - + sizeof(struct node_footer)); + set_page_dirty(xpage); + f2fs_put_page(xpage, 1); + + /* need to checkpoint during fsync */ + F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi)); + return 0; +} + +int f2fs_getxattr(struct inode *inode, int index, const char *name, + void *buffer, size_t buffer_size, struct page *ipage) +{ + struct f2fs_xattr_entry *entry; + void *base_addr; + int error = 0; + size_t size, len; + + if (name == NULL) + return -EINVAL; + + len = strlen(name); + if (len > F2FS_NAME_LEN) + return -ERANGE; + + base_addr = read_all_xattrs(inode, ipage); + if (!base_addr) + return -ENOMEM; + + entry = __find_xattr(base_addr, index, len, name); + if (IS_XATTR_LAST_ENTRY(entry)) { error = -ENODATA; goto cleanup; } - value_len = le16_to_cpu(entry->e_value_size); + size = le16_to_cpu(entry->e_value_size); - if (buffer && value_len > buffer_size) { + if (buffer && size > buffer_size) { error = -ERANGE; goto cleanup; } if (buffer) { char *pval = entry->e_name + entry->e_name_len; - memcpy(buffer, pval, value_len); + memcpy(buffer, pval, size); } - error = value_len; + error = size; cleanup: - f2fs_put_page(page, 1); + kzfree(base_addr); return error; } ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) { struct inode *inode = dentry->d_inode; - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_xattr_entry *entry; - struct page *page; void *base_addr; int error = 0; size_t rest = buffer_size; - if (!fi->i_xattr_nid) - return 0; - - page = get_node_page(sbi, fi->i_xattr_nid); - base_addr = page_address(page); + base_addr = read_all_xattrs(inode, NULL); + if (!base_addr) + return -ENOMEM; list_for_each_xattr(entry, base_addr) { const struct xattr_handler *handler = @@ -291,119 +474,77 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) } error = buffer_size - rest; cleanup: - f2fs_put_page(page, 1); + kzfree(base_addr); return error; } -int f2fs_setxattr(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len) +static int __f2fs_setxattr(struct inode *inode, int index, + const char *name, const void *value, size_t size, + struct page *ipage, int flags) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct f2fs_inode_info *fi = F2FS_I(inode); - struct f2fs_xattr_header *header = NULL; struct f2fs_xattr_entry *here, *last; - struct page *page; void *base_addr; - int error, found, free, newsize; - size_t name_len; - char *pval; - int ilock; + int found, newsize; + size_t len; + __u32 new_hsize; + int error = -ENOMEM; if (name == NULL) return -EINVAL; if (value == NULL) - value_len = 0; + size = 0; - name_len = strlen(name); + len = strlen(name); - if (name_len > F2FS_NAME_LEN || value_len > MAX_VALUE_LEN) + if (len > F2FS_NAME_LEN || size > MAX_VALUE_LEN(inode)) return -ERANGE; - f2fs_balance_fs(sbi); - - ilock = mutex_lock_op(sbi); - - if (!fi->i_xattr_nid) { - /* Allocate new attribute block */ - struct dnode_of_data dn; - - if (!alloc_nid(sbi, &fi->i_xattr_nid)) { - error = -ENOSPC; - goto exit; - } - set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid); - mark_inode_dirty(inode); - - page = new_node_page(&dn, XATTR_NODE_OFFSET); - if (IS_ERR(page)) { - alloc_nid_failed(sbi, fi->i_xattr_nid); - fi->i_xattr_nid = 0; - error = PTR_ERR(page); - goto exit; - } + base_addr = read_all_xattrs(inode, ipage); + if (!base_addr) + goto exit; - alloc_nid_done(sbi, fi->i_xattr_nid); - base_addr = page_address(page); - header = XATTR_HDR(base_addr); - header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC); - header->h_refcount = cpu_to_le32(1); - } else { - /* The inode already has an extended attribute block. */ - page = get_node_page(sbi, fi->i_xattr_nid); - if (IS_ERR(page)) { - error = PTR_ERR(page); - goto exit; - } - - base_addr = page_address(page); - header = XATTR_HDR(base_addr); - } + /* find entry with wanted name. */ + here = __find_xattr(base_addr, index, len, name); - if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) { - error = -EIO; - goto cleanup; - } + found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; - /* find entry with wanted name. */ - found = 0; - list_for_each_xattr(here, base_addr) { - if (here->e_name_index != name_index) - continue; - if (here->e_name_len != name_len) - continue; - if (!memcmp(here->e_name, name, name_len)) { - found = 1; - break; - } + if ((flags & XATTR_REPLACE) && !found) { + error = -ENODATA; + goto exit; + } else if ((flags & XATTR_CREATE) && found) { + error = -EEXIST; + goto exit; } last = here; - while (!IS_XATTR_LAST_ENTRY(last)) last = XATTR_NEXT_ENTRY(last); - newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + - name_len + value_len); + newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size); /* 1. Check space */ if (value) { - /* If value is NULL, it is remove operation. - * In case of update operation, we caculate free. + int free; + /* + * If value is NULL, it is remove operation. + * In case of update operation, we calculate free. */ - free = MIN_OFFSET - ((char *)last - (char *)header); + free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr); if (found) - free = free - ENTRY_SIZE(here); + free = free + ENTRY_SIZE(here); - if (free < newsize) { + if (unlikely(free < newsize)) { error = -ENOSPC; - goto cleanup; + goto exit; } } /* 2. Remove old entry */ if (found) { - /* If entry is found, remove old entry. + /* + * If entry is found, remove old entry. * If not found, remove operation is not needed. */ struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here); @@ -414,34 +555,63 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, memset(last, 0, oldsize); } + new_hsize = (char *)last - (char *)base_addr; + /* 3. Write new entry */ if (value) { - /* Before we come here, old entry is removed. - * We just write new entry. */ + char *pval; + /* + * Before we come here, old entry is removed. + * We just write new entry. + */ memset(last, 0, newsize); - last->e_name_index = name_index; - last->e_name_len = name_len; - memcpy(last->e_name, name, name_len); - pval = last->e_name + name_len; - memcpy(pval, value, value_len); - last->e_value_size = cpu_to_le16(value_len); + last->e_name_index = index; + last->e_name_len = len; + memcpy(last->e_name, name, len); + pval = last->e_name + len; + memcpy(pval, value, size); + last->e_value_size = cpu_to_le16(size); + new_hsize += newsize; } - set_page_dirty(page); - f2fs_put_page(page, 1); + error = write_all_xattrs(inode, new_hsize, base_addr, ipage); + if (error) + goto exit; if (is_inode_flag_set(fi, FI_ACL_MODE)) { inode->i_mode = fi->i_acl_mode; inode->i_ctime = CURRENT_TIME; clear_inode_flag(fi, FI_ACL_MODE); } - update_inode_page(inode); - mutex_unlock_op(sbi, ilock); - return 0; -cleanup: - f2fs_put_page(page, 1); + if (ipage) + update_inode(inode, ipage); + else + update_inode_page(inode); exit: - mutex_unlock_op(sbi, ilock); + kzfree(base_addr); return error; } + +int f2fs_setxattr(struct inode *inode, int index, const char *name, + const void *value, size_t size, + struct page *ipage, int flags) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + int err; + + /* this case is only from init_inode_metadata */ + if (ipage) + return __f2fs_setxattr(inode, index, name, value, + size, ipage, flags); + f2fs_balance_fs(sbi); + + f2fs_lock_op(sbi); + /* protect xattr_ver */ + down_write(&F2FS_I(inode)->i_sem); + err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags); + up_write(&F2FS_I(inode)->i_sem); + f2fs_unlock_op(sbi); + + return err; +} diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 49c9558305e3b..95b55a0c55cda 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h @@ -51,7 +51,7 @@ struct f2fs_xattr_entry { #define XATTR_HDR(ptr) ((struct f2fs_xattr_header *)(ptr)) #define XATTR_ENTRY(ptr) ((struct f2fs_xattr_entry *)(ptr)) -#define XATTR_FIRST_ENTRY(ptr) (XATTR_ENTRY(XATTR_HDR(ptr)+1)) +#define XATTR_FIRST_ENTRY(ptr) (XATTR_ENTRY(XATTR_HDR(ptr) + 1)) #define XATTR_ROUND (3) #define XATTR_ALIGN(size) ((size + XATTR_ROUND) & ~XATTR_ROUND) @@ -69,17 +69,16 @@ struct f2fs_xattr_entry { !IS_XATTR_LAST_ENTRY(entry);\ entry = XATTR_NEXT_ENTRY(entry)) +#define MIN_OFFSET(i) XATTR_ALIGN(inline_xattr_size(i) + PAGE_SIZE - \ + sizeof(struct node_footer) - sizeof(__u32)) -#define MIN_OFFSET XATTR_ALIGN(PAGE_SIZE - \ - sizeof(struct node_footer) - \ - sizeof(__u32)) - -#define MAX_VALUE_LEN (MIN_OFFSET - sizeof(struct f2fs_xattr_header) - \ - sizeof(struct f2fs_xattr_entry)) +#define MAX_VALUE_LEN(i) (MIN_OFFSET(i) - \ + sizeof(struct f2fs_xattr_header) - \ + sizeof(struct f2fs_xattr_entry)) /* * On-disk structure of f2fs_xattr - * We use only 1 block for xattr. + * We use inline xattrs space + 1 block for xattr. * * +--------------------+ * | f2fs_xattr_header | @@ -112,26 +111,26 @@ extern const struct xattr_handler f2fs_xattr_trusted_handler; extern const struct xattr_handler f2fs_xattr_acl_access_handler; extern const struct xattr_handler f2fs_xattr_acl_default_handler; extern const struct xattr_handler f2fs_xattr_advise_handler; +extern const struct xattr_handler f2fs_xattr_security_handler; extern const struct xattr_handler *f2fs_xattr_handlers[]; -extern int f2fs_setxattr(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len); -extern int f2fs_getxattr(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size); -extern ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, - size_t buffer_size); - +extern int f2fs_setxattr(struct inode *, int, const char *, + const void *, size_t, struct page *, int); +extern int f2fs_getxattr(struct inode *, int, const char *, void *, + size_t, struct page *); +extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); #else #define f2fs_xattr_handlers NULL -static inline int f2fs_setxattr(struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len) +static inline int f2fs_setxattr(struct inode *inode, int index, + const char *name, const void *value, size_t size, int flags) { return -EOPNOTSUPP; } -static inline int f2fs_getxattr(struct inode *inode, int name_index, - const char *name, void *buffer, size_t buffer_size) +static inline int f2fs_getxattr(struct inode *inode, int index, + const char *name, void *buffer, + size_t buffer_size, struct page *dpage) { return -EOPNOTSUPP; } @@ -142,4 +141,14 @@ static inline ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, } #endif +#ifdef CONFIG_F2FS_FS_SECURITY +extern int f2fs_init_security(struct inode *, struct inode *, + const struct qstr *, struct page *); +#else +static inline int f2fs_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, struct page *ipage) +{ + return 0; +} +#endif #endif /* __F2FS_XATTR_H__ */ diff --git a/fs/fhandle.c b/fs/fhandle.c index 999ff5c3cab0e..d59712dfa3e70 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -195,8 +195,9 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, goto out_err; } /* copy the full handle */ - if (copy_from_user(handle, ufh, - sizeof(struct file_handle) + + *handle = f_handle; + if (copy_from_user(&handle->f_handle, + &ufh->f_handle, f_handle.handle_bytes)) { retval = -EFAULT; goto out_handle; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8282b423e18e0..85e30f5c8d31b 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -18,6 +18,11 @@ #include #include +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory +#include +#endif + static const struct file_operations fuse_direct_io_file_operations; static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, @@ -1222,6 +1227,33 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct iov_iter i; loff_t endbyte = 0; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + struct kstatfs statfs; + u64 avail; + size_t size; + + if(get_fuse_conn(inode)->reserved_mem != 0){ + err = vfs_statfs(&file->f_path,&statfs); + if(unlikely(err)){ + printk(KERN_INFO "call vfs_statfs error(%d)\n",(int)err); + return err; + } + + avail = statfs.f_bavail * statfs.f_bsize; + size = iov_length(iov, nr_segs); + + if((u64)size > avail){ + printk(KERN_INFO "No space left on fuse.\n"); + printk(KERN_INFO "statfs.f_bavail : %llu blocks / " + "statfs.f_bsize : %ld bytes / " + "required size : %llu byte\n", + statfs.f_bavail, statfs.f_bsize, (u64)size); + return -ENOSPC; + } + } +#endif + if (get_fuse_conn(inode)->writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ err = fuse_update_attributes(mapping->host, NULL, file, NULL); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index fba925b6a7bd5..5b7bdbc001576 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -572,6 +572,11 @@ struct fuse_conn { /** number of dentries used in the above array */ int ctl_ndents; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + unsigned reserved_mem; +#endif + /** O_ASYNC requests */ struct fasync_struct *fasync; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 45a37cc8d7182..073ef70eb7783 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -69,6 +69,10 @@ struct fuse_mount_data { unsigned flags; unsigned max_read; unsigned blksize; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + unsigned reserved_mem; +#endif }; struct fuse_forget_link *fuse_alloc_forget(void) @@ -404,6 +408,37 @@ static void fuse_put_super(struct super_block *sb) fuse_conn_put(fc); } +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory +static int handle_reserved_statfs(struct kstatfs *stbuf, u32 reserved_mem) +{ + u32 reserved_blocks; + + if(stbuf->f_bsize == 0){ + printk(KERN_ERR "Invalid fuse statfs informations, block size is 0\n"); + return -EINVAL; + } + + reserved_blocks = ((reserved_mem * 1024 * 1024)/stbuf->f_bsize); + + stbuf->f_blocks -= reserved_blocks; + + if(stbuf->f_bfree < reserved_blocks) { + stbuf->f_bfree = 0; + } else { + stbuf->f_bfree -= reserved_blocks; + } + + if(stbuf->f_bavail < reserved_blocks) { + stbuf->f_bavail = 0; + } else { + stbuf->f_bavail -= reserved_blocks; + } + + return 0; +} +#endif /* VENDOR_EDIT */ + static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr) { stbuf->f_type = FUSE_SUPER_MAGIC; @@ -447,6 +482,13 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) err = req->out.h.error; if (!err) convert_fuse_statfs(buf, &outarg.st); + +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + if(!err && fc->reserved_mem != 0) + handle_reserved_statfs(buf,fc->reserved_mem); +#endif + fuse_put_request(fc, req); return err; } @@ -460,6 +502,10 @@ enum { OPT_ALLOW_OTHER, OPT_MAX_READ, OPT_BLKSIZE, +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + OPT_RESERVED_MEM, +#endif OPT_ERR }; @@ -472,6 +518,10 @@ static const match_table_t tokens = { {OPT_ALLOW_OTHER, "allow_other"}, {OPT_MAX_READ, "max_read=%u"}, {OPT_BLKSIZE, "blksize=%u"}, +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + {OPT_RESERVED_MEM, "reserved_mem=%u"}, +#endif {OPT_ERR, NULL} }; @@ -545,6 +595,14 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) d->blksize = value; break; +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + case OPT_RESERVED_MEM: + if (match_int(&args[0], &value)) + return 0; + d->reserved_mem = value; + break; +#endif default: return 0; } @@ -572,6 +630,13 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) seq_printf(m, ",max_read=%u", fc->max_read); if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE) seq_printf(m, ",blksize=%lu", sb->s_blocksize); + +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + if(fc->reserved_mem != 0) + seq_printf(m, ",reserved_mem=%uMB",fc->reserved_mem); +#endif + return 0; } @@ -1053,6 +1118,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->group_id = d.group_id; fc->max_read = max_t(unsigned, 4096, d.max_read); +#ifdef VENDOR_EDIT +//hefaxi@filesystems, 2015/06/17, add for reserved memory + fc->reserved_mem = d.reserved_mem; +#endif + /* Used by get_root_inode() */ sb->s_fs_info = fc; diff --git a/fs/namespace.c b/fs/namespace.c index a45ba4f267fe6..bea245ff055db 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1805,7 +1805,7 @@ static int do_remount(struct path *path, int flags, int mnt_flags, err = do_remount_sb(sb, flags, data, 0); if (!err) { br_write_lock(&vfsmount_lock); - mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; + mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; mnt->mnt.mnt_flags = mnt_flags; br_write_unlock(&vfsmount_lock); } @@ -2649,6 +2649,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, /* make sure we can reach put_old from new_root */ if (!is_path_reachable(old_mnt, old.dentry, &new)) goto out4; + /* make certain new is below the root */ + if (!is_path_reachable(new_mnt, new.dentry, &root)) + goto out4; root_mp->m_count++; /* pin it so it won't go away */ br_write_lock(&vfsmount_lock); detach_mnt(new_mnt, &parent_path); diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c old mode 100644 new mode 100755 index e4bcb2cf055a1..862f7670cb83d --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -41,6 +41,10 @@ #define PSTORE_NAMELEN 64 +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 +void *memcpy_pstore(void *dest, const void *src, size_t count); +#endif + static DEFINE_SPINLOCK(allpstore_lock); static LIST_HEAD(allpstore); @@ -338,8 +342,11 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, dentry = d_alloc_name(root, name); if (IS_ERR(dentry)) goto fail_lockedalloc; - +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 + memcpy_pstore(private->data, data, size); +#else memcpy(private->data, data, size); +#endif inode->i_size = private->size = size; inode->i_private = private; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c old mode 100644 new mode 100755 index 86d1038b5a129..71467cfe7f8df --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -36,6 +36,10 @@ #include "internal.h" +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 +void *memcpy_pstore(void *dest, const void *src, size_t count); +#endif + /* * We defer making "oops" entries appear in pstore - see * whether the system is actually still running well enough @@ -195,7 +199,11 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) } else { spin_lock_irqsave(&psinfo->buf_lock, flags); } +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 + memcpy_pstore(psinfo->buf, s, c); +#else memcpy(psinfo->buf, s, c); +#endif psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, c, psinfo); spin_unlock_irqrestore(&psinfo->buf_lock, flags); s += c; diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c old mode 100644 new mode 100755 index 058f17f0b466a..ba131d5d544f6 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -35,15 +35,30 @@ #include #include +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +#include +#include +#endif /* VENDOR_EDIT */ + +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 +void *memcpy_pstore(void *dest, const void *src, size_t count); +#endif + #define RAMOOPS_KERNMSG_HDR "====" #define MIN_MEM_SIZE 4096UL + static ulong record_size = MIN_MEM_SIZE; module_param(record_size, ulong, 0400); MODULE_PARM_DESC(record_size, "size of each dump done on oops/panic"); +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +static ulong ramoops_console_size = 256*1024UL; +#else static ulong ramoops_console_size = MIN_MEM_SIZE; +#endif /* VENDOR_EDIT */ + module_param_named(console_size, ramoops_console_size, ulong, 0400); MODULE_PARM_DESC(console_size, "size of kernel console log"); @@ -164,8 +179,11 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, *buf = kmalloc(size + ecc_notice_size + 1, GFP_KERNEL); if (*buf == NULL) return -ENOMEM; - +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 + memcpy_pstore(*buf, persistent_ram_old(prz), size); +#else memcpy(*buf, persistent_ram_old(prz), size); +#endif persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); return size + ecc_notice_size; @@ -383,10 +401,85 @@ void notrace ramoops_console_write_buf(const char *buf, size_t size) persistent_ram_write(cxt->cprz, buf, size); } +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +#ifdef CONFIG_OF + +static __ref struct ramoops_platform_data * of_ramoops_platform_data(struct device * dev) +{ + //const __be32 *addrp; + //u64 size; + struct device_node *node = dev->of_node; + struct ramoops_platform_data *pdata; + struct device_node *pnode; + unsigned long offsets[2]; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + /* + addrp = of_get_address(node, 0, &size, NULL); + if (addrp == NULL) + return NULL; + pdata->mem_address = of_translate_address(node, addrp); + pdata->mem_size = size; + */ + + pnode = of_parse_phandle(node, "linux,contiguous-region", 0); + if (pnode != NULL) { + const u32 *addr; + u64 size; + addr = of_get_address(pnode, 0, &size, NULL); + if (!addr) { + pr_err("failed to parse the ramoops memory address\n"); + of_node_put(pnode); + return NULL; + } + offsets[0] = of_read_ulong(addr, 2); + offsets[1] = (unsigned long) size; + of_node_put(pnode); + } else { + pr_err("mem reservation for ramoops not present\n"); + return NULL; + } + + + pdata->mem_address = offsets[0]; + pdata->mem_size = offsets[1]; + + pdata->record_size = record_size; + pdata->console_size = ramoops_console_size; + pdata->ftrace_size = ramoops_ftrace_size; + pdata->dump_oops = dump_oops; + + return pdata; +} + + +static const struct of_device_id ramoops_of_match[] = { + { .compatible = "ramoops", }, + { }, +}; +MODULE_DEVICE_TABLE(of, ramoops_of_match); + +#else + +static inline struct ramoops_platform_data * + of_ramoops_platform_data(struct device * dev)(struct device *dev) { return NULL; } + +#endif +#endif /* VENDOR_EDIT */ + +#ifdef VENDOR_EDIT/*LiWei added for set console address start and size*/ +phys_addr_t ram_console_address_start; +ssize_t ram_console_address_size; +#endif /*VENDOR_EDIT*/ + + static int ramoops_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ramoops_platform_data *pdata = pdev->dev.platform_data; + struct ramoops_context *cxt = &oops_cxt; size_t dump_mem_sz; phys_addr_t paddr; @@ -398,13 +491,32 @@ static int ramoops_probe(struct platform_device *pdev) if (cxt->max_dump_cnt) goto fail_out; + +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 + if (pdev->dev.of_node) { + pdata = of_ramoops_platform_data(&pdev->dev); + if (!pdata) { + pr_err("Invalid ramoops device tree data\n"); + goto fail_out; + } + + } else { + pdata = pdev->dev.platform_data; + } + + if (!pdata) { + pr_err("Ramopps cannot get device platform data\n"); + err = -EINVAL; + goto fail_out; + } +#endif /* VENDOR_EDIT */ + if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size && !pdata->ftrace_size)) { pr_err("The memory size and the record/console size must be " "non-zero\n"); goto fail_out; } - if (!is_power_of_2(pdata->mem_size)) pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); if (!is_power_of_2(pdata->record_size)) @@ -426,20 +538,23 @@ static int ramoops_probe(struct platform_device *pdev) paddr = cxt->phys_addr; dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size; + err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); if (err) goto fail_out; - err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr, cxt->console_size, 0); if (err) goto fail_init_cprz; +#ifdef VENDOR_EDIT /*liwei added for getting ram console address start address and size*/ + ram_console_address_start = cxt->cprz->paddr; + ram_console_address_size = cxt->console_size; +#endif /*VENDOR_EDIT*/ err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size, LINUX_VERSION_CODE); if (err) goto fail_init_fprz; - if (!cxt->przs && !cxt->cprz && !cxt->fprz) { pr_err("memory size too small, minimum is %zu\n", cxt->console_size + cxt->record_size + @@ -465,13 +580,11 @@ static int ramoops_probe(struct platform_device *pdev) err = -ENOMEM; goto fail_clear; } - err = pstore_register(&cxt->pstore); if (err) { pr_err("registering with pstore failed\n"); goto fail_buf; } - /* * Update the module parameter variables as well so they are visible * through /sys/module/ramoops/parameters/ @@ -481,6 +594,8 @@ static int ramoops_probe(struct platform_device *pdev) record_size = pdata->record_size; dump_oops = pdata->dump_oops; + //memblock_reserve(mem_address, mem_size); + pr_info("attached 0x%lx@0x%llx, ecc: %d/%d\n", cxt->size, (unsigned long long)cxt->phys_addr, cxt->ecc_info.ecc_size, cxt->ecc_info.block_size); @@ -529,6 +644,9 @@ static struct platform_driver ramoops_driver = { .driver = { .name = "ramoops", .owner = THIS_MODULE, +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 + .of_match_table = of_match_ptr(ramoops_of_match), +#endif /* VENDOR_EDIT */ }, }; diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c old mode 100644 new mode 100755 index 59337326e288f..648d2a54af77f --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -248,11 +248,30 @@ ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz, return ret; } +#ifdef VENDOR_EDIT // add by xcb for ramoops 2015-03-31 +void *memcpy_pstore(void *dest, const void *src, size_t count) +{ + char *tmp = dest; + const char *s = src; + + while (count--) + *tmp++ = *s++; + return dest; +} +#endif /* VENDOR_EDIT */ + static void notrace persistent_ram_update(struct persistent_ram_zone *prz, const void *s, unsigned int start, unsigned int count) { struct persistent_ram_buffer *buffer = prz->buffer; + +#ifdef VENDOR_EDIT // modify by xcb for ramoops 2015-03-31 + memcpy_pstore(buffer->data + start, s, count); +#else memcpy(buffer->data + start, s, count); +#endif /* VENDOR_EDIT */ + + persistent_ram_update_ecc(prz, start, count); } @@ -275,8 +294,13 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) } prz->old_log_size = size; +#ifdef VENDOR_EDIT // modify by yangrujin@bsp for ramoops memcpy addr alignment 2015-05-27 + memcpy_pstore(prz->old_log, &buffer->data[start], size - start); + memcpy_pstore(prz->old_log + size - start, &buffer->data[0], start); +#else memcpy(prz->old_log, &buffer->data[start], size - start); memcpy(prz->old_log + size - start, &buffer->data[0], start); +#endif } int notrace persistent_ram_write(struct persistent_ram_zone *prz, diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index d046955453973..3e8274b91c8d8 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -452,9 +452,9 @@ typedef struct xfs_handle { /* * Flags for going down operation */ -#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ -#define XFS_FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ -#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ +#define XFS_FSOP_GOING_FLAGS_DEFAULT FS_GOING_DOWN_FULLSYNC +#define XFS_FSOP_GOING_FLAGS_LOGFLUSH FS_GOING_DOWN_METASYNC +#define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH FS_GOING_DOWN_NOSYNC /* * ioctl commands that are used by Linux filesystems @@ -517,7 +517,7 @@ typedef struct xfs_handle { #define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq) #define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq) #define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom) -#define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t) +#define XFS_IOC_GOINGDOWN FS_IOC_SHUTDOWN /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 6cb2755bf71c0..37e72f3bf91ef 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -550,11 +550,10 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) #ifdef CONFIG_TRANSPARENT_HUGEPAGE barrier(); #endif - if (pmd_none(pmdval)) + if (pmd_none(pmdval) || pmd_trans_huge(pmdval)) return 1; if (unlikely(pmd_bad(pmdval))) { - if (!pmd_trans_huge(pmdval)) - pmd_clear_bad(pmd); + pmd_clear_bad(pmd); return 1; } return 0; diff --git a/include/linux/boot_mode.h b/include/linux/boot_mode.h new file mode 100644 index 0000000000000..8385b7248e31e --- /dev/null +++ b/include/linux/boot_mode.h @@ -0,0 +1,15 @@ +#ifndef _BOOT_MODE_H_ +#define _BOOT_MODE_H_ 1 + +enum oem_boot_mode{ + MSM_BOOT_MODE__NORMAL, + MSM_BOOT_MODE__FASTBOOT, + MSM_BOOT_MODE__RECOVERY, + MSM_BOOT_MODE__FACTORY, + MSM_BOOT_MODE__RF, + MSM_BOOT_MODE__WLAN, + MSM_BOOT_MODE__MOS, + MSM_BOOT_MODE__CHARGE, +}; +enum oem_boot_mode get_boot_mode(void); +#endif diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index 6e7ec64b69ab4..e5e6b0dd41d9e 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -84,3 +84,9 @@ SUBSYS(bcache) #endif /* */ + +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_BFQIO) +SUBSYS(bfqio) +#endif + +/* */ diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 65d982284a659..e672c5dcd4f8d 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -279,6 +279,13 @@ static inline void enable_nonboot_cpus(void) {} struct cpu_pwr_stats *get_cpu_pwr_stats(void); void trigger_cpu_pwr_stats_calc(void); +#ifdef VENDOR_EDIT +/* ic, declaration for core ctrl extension */ +unsigned int power_cost_at_freq_at_temp( + unsigned int cpu, + unsigned int freq, + long temp); +#endif enum cpuhp_state { CPUHP_OFFLINE, diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index df6fab82f87e7..591f8c3ef4109 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -15,20 +15,30 @@ #include #define F2FS_SUPER_OFFSET 1024 /* byte-size offset */ -#define F2FS_LOG_SECTOR_SIZE 9 /* 9 bits for 512 byte */ -#define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ +#define F2FS_MIN_LOG_SECTOR_SIZE 9 /* 9 bits for 512 bytes */ +#define F2FS_MAX_LOG_SECTOR_SIZE 12 /* 12 bits for 4096 bytes */ +#define F2FS_LOG_SECTORS_PER_BLOCK 3 /* log number for sector/blk */ #define F2FS_BLKSIZE 4096 /* support only 4KB block */ +#define F2FS_BLKSIZE_BITS 12 /* bits for F2FS_BLKSIZE */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ +#define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) -#define NULL_ADDR 0x0U -#define NEW_ADDR -1U +#define NULL_ADDR ((block_t)0) /* used as block_t addresses */ +#define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ + +#define F2FS_BYTES_TO_BLK(bytes) ((bytes) >> F2FS_BLKSIZE_BITS) +#define F2FS_BLK_TO_BYTES(blk) ((blk) << F2FS_BLKSIZE_BITS) + +/* 0, 1(node nid), 2(meta nid) are reserved node id */ +#define F2FS_RESERVED_NODE_NUM 3 #define F2FS_ROOT_INO(sbi) (sbi->root_ino_num) #define F2FS_NODE_INO(sbi) (sbi->node_ino_num) #define F2FS_META_INO(sbi) (sbi->meta_ino_num) /* This flag is used by node and meta inodes, and by recovery */ -#define GFP_F2FS_ZERO (GFP_NOFS | __GFP_ZERO) +#define GFP_F2FS_ZERO (GFP_NOFS | __GFP_ZERO) +#define GFP_F2FS_HIGH_ZERO (GFP_NOFS | __GFP_ZERO | __GFP_HIGHMEM) /* * For further optimization on multi-head logs, on-disk layout supports maximum @@ -75,16 +85,21 @@ struct f2fs_super_block { __le16 volume_name[512]; /* volume name */ __le32 extension_count; /* # of extensions below */ __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ + __le32 cp_payload; } __packed; /* * For checkpoint */ +#define CP_FASTBOOT_FLAG 0x00000020 +#define CP_FSCK_FLAG 0x00000010 #define CP_ERROR_FLAG 0x00000008 #define CP_COMPACT_SUM_FLAG 0x00000004 #define CP_ORPHAN_PRESENT_FLAG 0x00000002 #define CP_UMOUNT_FLAG 0x00000001 +#define F2FS_CP_PACKS 2 /* # of checkpoint packs */ + struct f2fs_checkpoint { __le64 checkpoint_ver; /* checkpoint block version number */ __le64 user_block_count; /* # of user blocks */ @@ -121,6 +136,9 @@ struct f2fs_checkpoint { */ #define F2FS_ORPHANS_PER_BLOCK 1020 +#define GET_ORPHAN_BLOCKS(n) ((n + F2FS_ORPHANS_PER_BLOCK - 1) / \ + F2FS_ORPHANS_PER_BLOCK) + struct f2fs_orphan_block { __le32 ino[F2FS_ORPHANS_PER_BLOCK]; /* inode numbers */ __le32 reserved; /* reserved */ @@ -135,19 +153,40 @@ struct f2fs_orphan_block { */ struct f2fs_extent { __le32 fofs; /* start file offset of the extent */ - __le32 blk_addr; /* start block address of the extent */ + __le32 blk; /* start block address of the extent */ __le32 len; /* lengh of the extent */ } __packed; #define F2FS_NAME_LEN 255 -#define ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ -#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ -#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ +#define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs */ +#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ +#define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ +#define ADDRS_PER_INODE(fi) addrs_per_inode(fi) +#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ +#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ + +#define ADDRS_PER_PAGE(page, fi) \ + (IS_INODE(page) ? ADDRS_PER_INODE(fi) : ADDRS_PER_BLOCK) + +#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) +#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) +#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3) +#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4) +#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5) + +#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ +#define F2FS_INLINE_DATA 0x02 /* file inline data flag */ +#define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ +#define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */ +#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */ + +#define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \ + F2FS_INLINE_XATTR_ADDRS - 1)) struct f2fs_inode { __le16 i_mode; /* file mode */ __u8 i_advise; /* file hints */ - __u8 i_reserved; /* reserved */ + __u8 i_inline; /* file inline flags */ __le32 i_uid; /* user ID */ __le32 i_gid; /* group ID */ __le32 i_links; /* links count */ @@ -166,13 +205,13 @@ struct f2fs_inode { __le32 i_pino; /* parent inode number */ __le32 i_namelen; /* file name length */ __u8 i_name[F2FS_NAME_LEN]; /* file name for SPOR */ - __u8 i_reserved2; /* for backward compatibility */ + __u8 i_dir_level; /* dentry_level for large dir */ struct f2fs_extent i_ext; /* caching a largest extent */ - __le32 i_addr[ADDRS_PER_INODE]; /* Pointers to data blocks */ + __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ - __le32 i_nid[5]; /* direct(2), indirect(2), + __le32 i_nid[DEF_NIDS_PER_INODE]; /* direct(2), indirect(2), double_indirect(1) node id */ } __packed; @@ -191,6 +230,8 @@ enum { OFFSET_BIT_SHIFT }; +#define OFFSET_BIT_MASK (0x07) /* (0x01 << OFFSET_BIT_SHIFT) - 1 */ + struct node_footer { __le32 nid; /* node id */ __le32 ino; /* inode nunmber */ @@ -374,6 +415,9 @@ typedef __le32 f2fs_hash_t; /* MAX level for dir lookup */ #define MAX_DIR_HASH_DEPTH 63 +/* MAX buckets in one level of dir */ +#define MAX_DIR_BUCKETS (1 << ((MAX_DIR_HASH_DEPTH / 2) - 1)) + #define SIZE_OF_DIR_ENTRY 11 /* by byte */ #define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) / \ BITS_PER_BYTE) @@ -398,6 +442,24 @@ struct f2fs_dentry_block { __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; } __packed; +/* for inline dir */ +#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + BITS_PER_BYTE + 1)) +#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + \ + BITS_PER_BYTE - 1) / BITS_PER_BYTE) +#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_INLINE_DENTRY + INLINE_DENTRY_BITMAP_SIZE)) + +/* inline directory entry structure */ +struct f2fs_inline_dentry { + __u8 dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; + __u8 reserved[INLINE_RESERVED_SIZE]; + struct f2fs_dir_entry dentry[NR_INLINE_DENTRY]; + __u8 filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; +} __packed; + /* file types used in inode_info->flags */ enum { F2FS_FT_UNKNOWN, diff --git a/include/linux/freezer.h b/include/linux/freezer.h old mode 100644 new mode 100755 index 0f52fc8d348b7..f2c81d214c96e --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -69,6 +69,11 @@ static inline bool try_to_freeze(void) return try_to_freeze_unsafe(); } +#ifdef VENDOR_EDIT +//huruihuan add for freezing task in cgroup despite of PF_FREEZER_SKIP flag +extern bool freeze_cgroup_task(struct task_struct *p); +#endif + extern bool freeze_task(struct task_struct *p); extern bool set_freezable(void); diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index a6c5471822d38..4aacb6a4a5ba5 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -41,6 +41,7 @@ struct ipv6_devconf { __s32 accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD __s32 optimistic_dad; + __s32 use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE __s32 mc_forwarding; diff --git a/include/linux/mdss_io_util.h b/include/linux/mdss_io_util.h index 6ad21e8878774..4ebcd8c4ad58a 100644 --- a/include/linux/mdss_io_util.h +++ b/include/linux/mdss_io_util.h @@ -19,11 +19,7 @@ #include #include -#ifdef DEBUG -#define DEV_DBG(fmt, args...) pr_err(fmt, ##args) -#else #define DEV_DBG(fmt, args...) pr_debug(fmt, ##args) -#endif #define DEV_INFO(fmt, args...) pr_info(fmt, ##args) #define DEV_WARN(fmt, args...) pr_warn(fmt, ##args) #define DEV_ERR(fmt, args...) pr_err(fmt, ##args) diff --git a/include/linux/mount.h b/include/linux/mount.h index 73005f9957ead..16fc05d816d4a 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -42,7 +42,9 @@ struct mnt_namespace; * flag, consider how it interacts with shared mounts. */ #define MNT_SHARED_MASK (MNT_UNBINDABLE) -#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) +#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ + | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ + | MNT_READONLY) #define MNT_INTERNAL 0x4000 diff --git a/include/linux/oem_force_dump.h b/include/linux/oem_force_dump.h new file mode 100644 index 0000000000000..e53b64dab5eae --- /dev/null +++ b/include/linux/oem_force_dump.h @@ -0,0 +1,15 @@ +/* + * oem_force_dump.h + * + * header file supporting debug functions for Oneplus device. + * + * hefaxi@filesystems, 2015/07/03. + */ + +#ifndef OEM_FORCE_DUMP_H +#define OEM_FORCE_DUMP_H + +extern void oem_check_force_dump_key(unsigned int code, int value); + + +#endif diff --git a/include/linux/param_rw.h b/include/linux/param_rw.h new file mode 100755 index 0000000000000..f1af857869107 --- /dev/null +++ b/include/linux/param_rw.h @@ -0,0 +1,161 @@ +#ifndef __PARAM_RW_H +#define __PARAM_RW_H + +#define PARAM_SID_LENGTH 1024 +#define DEFAULT_PARAM_PART_SZIE (1*1024*1024) +#define DEFAULT_PARAM_DUMP_SIZE 64 + +typedef unsigned int uint32; + +typedef struct +{ + char sid_name[16]; + uint32 sid_index; + uint32 sid_length; //default 1024bytes +}param_product_desc_head_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + char project_name[8]; //14049 + int hw_version; //11 + int rf_version; + char rf_config_str[16]; + int operator_num; + char operator_str[16]; + char pcba_number[16]; +}param_product_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + uint32 default_param_data_dump_enable; + uint32 default_param_data_dump_size; + //Add value must below here +}param_config_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + uint gamma_select; +}param_lcd_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //Add value must below here +}param_tp_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //Add value must below here +}param_tp_kpd_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + uint32 laser_sensor_offset; + uint32 laser_sensor_cross_talk; +}param_camera_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //Add value must below here +}param_sensors_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //Add value must below here +}param_battery_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //Add value must below here +}param_rtc_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + int android_crash_count; + int kernel_crash_count; + int modem_crash_count; + int wifi_bt_crash_count; + int venus_crash_count; +}param_crash_record_t; + +typedef struct +{ + param_product_desc_head_t sid_head; + //#ifdef VENDOR_EDIT + /* Only for wlan evm chip */ + int use_special_boarddata; + //#endif /* VENDOR_EDIT */ + //Add value must below here +}param_misc_t; + +typedef enum { + PARAM_SID_PRODUCT = 0, + PARAM_SID_CONFIG, + PARAM_SID_LCD, + PARAM_SID_TP, + PARAM_SID_TP_KPD, + PARAM_SID_CAMERA, + PARAM_SID_SENSORS, + PARAM_SID_BATTERY, + PARAM_SID_RTC, + PARAM_SID_CRASH_RECORD, + PARAM_SID_MISC, + PARAM_SID_INVALID +} param_sid_index_t; + +#if 0 +static char * sid_name_strs[PARAM_SID_INVALID] = { +"PRODUCT", +"CONFIG", +"LCD", +"TP", +"TP_KPD", +"TP_CAMERA", +"SENSORS", +"BATTERY", +"RTC", +"CRASH_RECORD", +"MISC" +}; +#endif + +#define CHUNK_UNION(_name) \ + union { param_##_name##_t _name##_chunk; \ + unsigned char c[1024]; } _name##_chunk_u + +typedef struct +{ + //union { param_product_t product_chunk; unsigned char c[1024]; } product_chunk_u; + CHUNK_UNION(product); + CHUNK_UNION(config); + CHUNK_UNION(lcd); + CHUNK_UNION(tp); + CHUNK_UNION(tp_kpd); + CHUNK_UNION(camera); + CHUNK_UNION(sensors); + CHUNK_UNION(battery); + CHUNK_UNION(rtc); + CHUNK_UNION(crash_record); + CHUNK_UNION(misc); +}global_param_data_t; + +int get_param_camera_laser_sensor_offset(uint * laser_sensor_offset); +int set_param_camera_laser_sensor_offset(uint * laser_sensor_offset); +int get_param_camera_laser_sensor_cross_talk(uint * laser_sensor_cross_talk); +int set_param_camera_laser_sensor_cross_talk(uint * laser_sensor_cross_talk); +int get_param_gamma_select(uint * gamma_select); +//#ifdef VENDOR_EDIT +/* Only for wlan evm chip */ +int get_param_nvm_boarddata(uint * nvm_boarddata_select); +//#endif /* VENDOR_EDIT */ + +#endif diff --git a/include/linux/powersuspend.h b/include/linux/powersuspend.h new file mode 100644 index 0000000000000..e63e40472dfdb --- /dev/null +++ b/include/linux/powersuspend.h @@ -0,0 +1,42 @@ +/* include/linux/powersuspend.h + * + * Copyright (C) 2007-2008 Google, Inc. + * Copyright (C) 2013 Paul Reioux + * + * Modified by Jean-Pierre Rasquin + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_POWERSUSPEND_H +#define _LINUX_POWERSUSPEND_H + +#include + +#define POWER_SUSPEND_INACTIVE 0 +#define POWER_SUSPEND_ACTIVE 1 + +#define POWER_SUSPEND_USERSPACE 1 // Use fauxclock as trigger +#define POWER_SUSPEND_PANEL 2 // Use display panel state as hook + +struct power_suspend { + struct list_head link; + void (*suspend)(struct power_suspend *h); + void (*resume)(struct power_suspend *h); +}; + +void register_power_suspend(struct power_suspend *handler); +void unregister_power_suspend(struct power_suspend *handler); + +void set_power_suspend_state_panel_hook(int new_state); + +#endif + diff --git a/include/linux/project_info.h b/include/linux/project_info.h new file mode 100755 index 0000000000000..5365d4cf86a37 --- /dev/null +++ b/include/linux/project_info.h @@ -0,0 +1,27 @@ +#ifndef _PROJECT_INFO_H_ +#define _PROJECT_INFO_H_ 1 + +enum COMPONENT_TYPE{ + DDR, + EMMC, + F_CAMERA, + R_CAMERA, + TP, + LCD, + WCN, + I_SENSOR, + G_SENSOR, + M_SENSOR, + GYRO, + BACKLIGHT, + MAINBOARD, + /*Add new component here*/ + FINGERPRINTS, + TOUCH_KEY, + COMPONENT_MAX, +}; + +int push_component_info(enum COMPONENT_TYPE type, char *version, char * manufacture); +int reset_component_info(enum COMPONENT_TYPE type); + +#endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 877669d1c852f..4efb351ab7c55 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1076,6 +1076,9 @@ struct ravg { u64 mark_start; u32 sum, demand; u32 sum_history[RAVG_HIST_SIZE_MAX]; +#ifdef VENDOR_EDIT + unsigned mitigated:1; +#endif #ifdef CONFIG_SCHED_FREQ_INPUT u32 curr_window, prev_window; #endif diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index f0729abed2125..4d892dc630f75 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -46,6 +46,9 @@ extern unsigned int sysctl_sched_migration_fixup; extern unsigned int sysctl_sched_heavy_task_pct; extern unsigned int sysctl_sched_min_runtime; extern unsigned int sysctl_sched_enable_power_aware; +#ifdef VENDOR_EDIT +extern unsigned int sysctl_thermal_aware_scheduling; +#endif #if defined(CONFIG_SCHED_FREQ_INPUT) || defined(CONFIG_SCHED_HMP) extern unsigned int sysctl_sched_init_task_load_pct; diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h old mode 100644 new mode 100755 index 8e522cbcef29f..ed3d7f7737826 --- a/include/linux/uidgid.h +++ b/include/linux/uidgid.h @@ -64,6 +64,11 @@ static inline gid_t __kgid_val(kgid_t gid) #define GLOBAL_ROOT_UID KUIDT_INIT(0) #define GLOBAL_ROOT_GID KGIDT_INIT(0) +#ifdef VENDOR_EDIT +//huruihuan add for cgroup control +#define GLOBAL_SYSTEM_UID KUIDT_INIT(1000) +#endif + #define INVALID_UID KUIDT_INIT(-1) #define INVALID_GID KGIDT_INIT(-1) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h old mode 100644 new mode 100755 index 745bf1b9ff900..2147323a73ee1 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -738,6 +738,7 @@ static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) { if (!gadget->ops->vbus_draw) return -EOPNOTSUPP; + pr_info("%s USB setting current is %umA\n", __func__,mA); return gadget->ops->vbus_draw(gadget, mA); } diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h index 4a3636eef0f80..b067217b678ff 100644 --- a/include/media/msm_cam_sensor.h +++ b/include/media/msm_cam_sensor.h @@ -230,6 +230,7 @@ struct sensorb_cfg_data { struct msm_sensor_info_t sensor_info; struct msm_sensor_init_params sensor_init_params; void *setting; + struct msm_sensor_i2c_sync_params sensor_i2c_sync_params; } cfg; }; @@ -409,6 +410,10 @@ enum msm_sensor_cfg_type_t { CFG_SET_AUTOFOCUS, CFG_CANCEL_AUTOFOCUS, CFG_SET_STREAM_TYPE, + CFG_SET_I2C_SYNC_PARAM, + CFG_WRITE_I2C_ARRAY_ASYNC, + CFG_WRITE_I2C_ARRAY_SYNC, + CFG_WRITE_I2C_ARRAY_SYNC_BLOCK, }; enum msm_actuator_cfg_type_t { @@ -715,6 +720,7 @@ struct sensorb_cfg_data32 { struct msm_sensor_info_t sensor_info; struct msm_sensor_init_params sensor_init_params; compat_uptr_t setting; + struct msm_sensor_i2c_sync_params sensor_i2c_sync_params; } cfg; }; diff --git a/include/media/msm_camsensor_sdk.h b/include/media/msm_camsensor_sdk.h index 91de730aaef0b..4ad7db329948b 100644 --- a/include/media/msm_camsensor_sdk.h +++ b/include/media/msm_camsensor_sdk.h @@ -78,6 +78,10 @@ enum msm_camera_i2c_data_type { MSM_CAMERA_I2C_SET_WORD_MASK, MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA, +// #ifdef VENDOR_EDIT + //added by zhangxiaowei@camera 20150310 for qcom OIS architecture + MSM_CAMERA_I2C_NO_DATA, + // #endif /*VENDOR_EDIT*/ MSM_CAMERA_I2C_DATA_TYPE_MAX, }; @@ -187,6 +191,14 @@ struct msm_sensor_power_setting_array { unsigned short size_down; }; + +struct msm_sensor_i2c_sync_params { + unsigned int cid; + int csid; + unsigned short line; + unsigned short delay; +}; + struct msm_sensor_init_params { /* mask of modes supported: 2D, 3D */ int modes_supported; diff --git a/include/net/cnss.h b/include/net/cnss.h index c6edfc62f3993..661f8c7026070 100644 --- a/include/net/cnss.h +++ b/include/net/cnss.h @@ -99,6 +99,9 @@ enum cnss_driver_status { }; extern int cnss_get_fw_image(struct image_desc_info *image_desc_info); +//#ifdef VENDOR_EDIT +extern void cnss_set_fw_version(u32 version); +//#endif /* VENDOR_EDIT */ extern void cnss_device_crashed(void); extern void cnss_device_self_recovery(void); diff --git a/include/net/ip.h b/include/net/ip.h index 9066e39fcb3fe..1a3c8665e1d40 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -37,11 +37,12 @@ struct inet_skb_parm { struct ip_options opt; /* Compiled IP options */ unsigned char flags; -#define IPSKB_FORWARDED 1 -#define IPSKB_XFRM_TUNNEL_SIZE 2 -#define IPSKB_XFRM_TRANSFORMED 4 -#define IPSKB_FRAG_COMPLETE 8 -#define IPSKB_REROUTED 16 +#define IPSKB_FORWARDED BIT(0) +#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) +#define IPSKB_XFRM_TRANSFORMED BIT(2) +#define IPSKB_FRAG_COMPLETE BIT(3) +#define IPSKB_REROUTED BIT(4) +#define IPSKB_DOREDIRECT BIT(5) u16 frag_max_size; }; diff --git a/include/net/tcp.h b/include/net/tcp.h old mode 100644 new mode 100755 index 4cc1f2268cee0..ddb0beb06db34 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -91,14 +91,14 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); * to ~3sec-8min depending on RTO. */ -#define TCP_RETR2 15 /* +#define TCP_RETR2 8 /* * This should take at least * 90 minutes to time out. * RFC1122 says that the limit is 100 sec. * 15 is ~13-30min depending on RTO. */ -#define TCP_SYN_RETRIES 6 /* This is how many retries are done +#define TCP_SYN_RETRIES 4 /* This is how many retries are done * when active opening a connection. * RFC1122 says the minimum retry MUST * be at least 180secs. Nevertheless @@ -107,7 +107,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); * current initial RTO. */ -#define TCP_SYNACK_RETRIES 5 /* This is how may retries are done +#define TCP_SYNACK_RETRIES 3 /* This is how may retries are done * when passive opening a connection. * This is corresponding to 31secs of * retransmission with the current diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index ace62c9d4dfc1..3ecbddf2c40b4 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -105,6 +105,11 @@ struct scsi_cmnd; #define WRITE_SAME 0x41 #define UNMAP 0x42 #define READ_TOC 0x43 + //add by jiachenghui for cdrom suport MAC OSX,2015-06-30 +#ifdef VENDOR_EDIT +#define READ_CD 0xbe +#endif + //end add by jiachenghui for cdrom suport MAC OSX,2015-06-30 #define READ_HEADER 0x44 #define GET_EVENT_STATUS_NOTIFICATION 0x4a #define LOG_SELECT 0x4c diff --git a/include/soc/qcom/core_ctl.h b/include/soc/qcom/core_ctl.h index 01f55e53cd475..ba6dcb5ba9fef 100644 --- a/include/soc/qcom/core_ctl.h +++ b/include/soc/qcom/core_ctl.h @@ -21,5 +21,18 @@ extern struct cpufreq_policy *core_ctl_get_policy(int cpu); extern void core_ctl_put_policy(struct cpufreq_policy *policy); extern struct device *core_ctl_find_cpu_device(unsigned cpu); extern int core_ctl_online_core(unsigned int cpu); - +#ifdef VENDOR_EDIT +/* ic, declarations for core ctrl extension */ +extern int core_ctl_is_online_idle_core(unsigned int cpu); +extern unsigned int core_ctl_get_freq_cost( + unsigned int cpu, + unsigned int freq + ); +extern unsigned int core_ctl_get_cost_at_temp( + unsigned int cpu, + unsigned int freq, + long temp + ); +extern struct cpufreq_frequency_table *core_ctl_get_freq_tbl(unsigned int cpu); +#endif #endif diff --git a/include/soc/qcom/smem.h b/include/soc/qcom/smem.h old mode 100644 new mode 100755 index 7ae8dcb1d6168..5a0708d87e7cd --- a/include/soc/qcom/smem.h +++ b/include/soc/qcom/smem.h @@ -108,6 +108,10 @@ enum { SMEM_ID_VENDOR0, SMEM_ID_VENDOR1, SMEM_ID_VENDOR2, +//For more details, could check boot_iamges/core/api/mproc/smem_type.h +#ifdef VENDOR_EDIT + SMEM_PROJECT_INFO = 136, +#endif SMEM_HW_SW_BUILD_ID, SMEM_SMD_BASE_ID_2, SMEM_SMD_FIFO_BASE_ID_2 = SMEM_SMD_BASE_ID_2 + diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index c969f7293a4b1..03d1b51dc1410 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -7311,6 +7311,11 @@ struct afe_param_id_clip_bank_sel { #define Q6AFE_LPASS_OSR_CLK_DISABLE 0x0 /* Supported Bit clock values */ +#ifdef VENDOR_EDIT +/* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#define Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ 0xBB8000 +/* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif #define Q6AFE_LPASS_IBIT_CLK_8_P192_MHZ 0x7D0000 #define Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ 0x5DC000 #define Q6AFE_LPASS_IBIT_CLK_4_P096_MHZ 0x3E8000 diff --git a/include/sound/tfa98xx.h b/include/sound/tfa98xx.h new file mode 100644 index 0000000000000..ad2a0617f26bb --- /dev/null +++ b/include/sound/tfa98xx.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _TFA98XX_H +#define _TFA98XX_H + +#include +#include + +/* Revision IDs for tfa98xx variants */ +#define REV_TFA9887 0x12 +#define REV_TFA9890 0x80 +#define REV_TFA9895 0x12 +#define REV_TFA9897 0x97 + + +struct tfaprofile; +struct nxpTfaDevice; +struct nxpTfaProfile; +struct nxpTfaVolumeStep2File; + +struct tfaprofile { + struct nxpTfaProfile *profile; + struct nxpTfaVolumeStep2File *vp; + int vsteps; + int vstep; + int index; + int state; + char *name; +}; + +struct tfa98xx_firmware { + void *base; + struct nxpTfaDevice *dev; + char *name; +}; + +struct tfa98xx { + struct regmap *regmap; + struct i2c_client *i2c; + struct snd_soc_codec *codec; + struct workqueue_struct *tfa98xx_wq; + struct work_struct init_work; + struct delayed_work delay_work; + struct mutex dsp_init_lock; + int dsp_init; + int speaker_imp; + int sysclk; + int rst_gpio; + int mode; + int mode_switched; + int curr_mode; + int vol_idx; + int curr_vol_idx; + int ic_version; + u8 rev; + u8 subrev; + int vstep; + int profile; + int profile_current; + int profile_count; + int has_drc; + int rate; +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-11,change for wave profile */ + int WaveEnable; + int profileChange; + int i2sOn; +#endif + struct tfaprofile *profiles; + struct tfa98xx_firmware fw; + + int (*info_profile)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); + int (*set_profile)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + int (*get_profile)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + + int (*info_vstep)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); + int (*set_vstep)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + int (*get_vstep)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + + struct snd_kcontrol_new *(*build_profile_controls)(struct tfa98xx *tfa98xx, int *kcontrol_count); +}; + +#endif diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 52ae54828eda4..f622e782ffab3 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -14,17 +14,34 @@ { NODE, "NODE" }, \ { DATA, "DATA" }, \ { META, "META" }, \ - { META_FLUSH, "META_FLUSH" }) - -#define show_bio_type(type) \ - __print_symbolic(type, \ - { READ, "READ" }, \ - { READA, "READAHEAD" }, \ - { READ_SYNC, "READ_SYNC" }, \ - { WRITE, "WRITE" }, \ - { WRITE_SYNC, "WRITE_SYNC" }, \ - { WRITE_FLUSH, "WRITE_FLUSH" }, \ - { WRITE_FUA, "WRITE_FUA" }) + { META_FLUSH, "META_FLUSH" }, \ + { INMEM, "INMEM" }, \ + { INMEM_DROP, "INMEM_DROP" }, \ + { IPU, "IN-PLACE" }, \ + { OPU, "OUT-OF-PLACE" }) + +#define F2FS_BIO_MASK(t) (t & (READA | WRITE_FLUSH_FUA)) +#define F2FS_BIO_EXTRA_MASK(t) (t & (REQ_META | REQ_PRIO)) + +#define show_bio_type(type) show_bio_base(type), show_bio_extra(type) + +#define show_bio_base(type) \ + __print_symbolic(F2FS_BIO_MASK(type), \ + { READ, "READ" }, \ + { READA, "READAHEAD" }, \ + { READ_SYNC, "READ_SYNC" }, \ + { WRITE, "WRITE" }, \ + { WRITE_SYNC, "WRITE_SYNC" }, \ + { WRITE_FLUSH, "WRITE_FLUSH" }, \ + { WRITE_FUA, "WRITE_FUA" }, \ + { WRITE_FLUSH_FUA, "WRITE_FLUSH_FUA" }) + +#define show_bio_extra(type) \ + __print_symbolic(F2FS_BIO_EXTRA_MASK(type), \ + { REQ_META, "(M)" }, \ + { REQ_PRIO, "(P)" }, \ + { REQ_META | REQ_PRIO, "(MP)" }, \ + { 0, " \b" }) #define show_data_type(type) \ __print_symbolic(type, \ @@ -36,6 +53,11 @@ { CURSEG_COLD_NODE, "Cold NODE" }, \ { NO_CHECK_TYPE, "No TYPE" }) +#define show_file_type(type) \ + __print_symbolic(type, \ + { 0, "FILE" }, \ + { 1, "DIR" }) + #define show_gc_type(type) \ __print_symbolic(type, \ { FG_GC, "Foreground GC" }, \ @@ -51,6 +73,14 @@ { GC_GREEDY, "Greedy" }, \ { GC_CB, "Cost-Benefit" }) +#define show_cpreason(type) \ + __print_symbolic(type, \ + { CP_UMOUNT, "Umount" }, \ + { CP_FASTBOOT, "Fastboot" }, \ + { CP_SYNC, "Sync" }, \ + { CP_RECOVERY, "Recovery" }, \ + { CP_DISCARD, "Discard" }) + struct victim_sel_policy; DECLARE_EVENT_CLASS(f2fs__inode, @@ -124,14 +154,14 @@ DEFINE_EVENT(f2fs__inode, f2fs_sync_file_enter, TRACE_EVENT(f2fs_sync_file_exit, - TP_PROTO(struct inode *inode, bool need_cp, int datasync, int ret), + TP_PROTO(struct inode *inode, int need_cp, int datasync, int ret), TP_ARGS(inode, need_cp, datasync, ret), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(bool, need_cp) + __field(int, need_cp) __field(int, datasync) __field(int, ret) ), @@ -166,7 +196,7 @@ TRACE_EVENT(f2fs_sync_fs, TP_fast_assign( __entry->dev = sb->s_dev; - __entry->dirty = F2FS_SB(sb)->s_dirty; + __entry->dirty = is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY); __entry->wait = wait; ), @@ -416,38 +446,6 @@ TRACE_EVENT(f2fs_truncate_partial_nodes, __entry->err) ); -TRACE_EVENT_CONDITION(f2fs_readpage, - - TP_PROTO(struct page *page, sector_t blkaddr, int type), - - TP_ARGS(page, blkaddr, type), - - TP_CONDITION(page->mapping), - - TP_STRUCT__entry( - __field(dev_t, dev) - __field(ino_t, ino) - __field(pgoff_t, index) - __field(sector_t, blkaddr) - __field(int, type) - ), - - TP_fast_assign( - __entry->dev = page->mapping->host->i_sb->s_dev; - __entry->ino = page->mapping->host->i_ino; - __entry->index = page->index; - __entry->blkaddr = blkaddr; - __entry->type = type; - ), - - TP_printk("dev = (%d,%d), ino = %lu, page_index = 0x%lx, " - "blkaddr = 0x%llx, bio_type = %s", - show_dev_ino(__entry), - (unsigned long)__entry->index, - (unsigned long long)__entry->blkaddr, - show_bio_type(__entry->type)) -); - TRACE_EVENT(f2fs_get_data_block, TP_PROTO(struct inode *inode, sector_t iblock, struct buffer_head *bh, int ret), @@ -569,6 +567,69 @@ TRACE_EVENT(f2fs_fallocate, __entry->ret) ); +TRACE_EVENT(f2fs_direct_IO_enter, + + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), + + TP_ARGS(inode, offset, len, rw), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(loff_t, pos) + __field(unsigned long, len) + __field(int, rw) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + ), + + TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu rw = %d", + show_dev_ino(__entry), + __entry->pos, + __entry->len, + __entry->rw) +); + +TRACE_EVENT(f2fs_direct_IO_exit, + + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, + int rw, int ret), + + TP_ARGS(inode, offset, len, rw, ret), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(loff_t, pos) + __field(unsigned long, len) + __field(int, rw) + __field(int, ret) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + __entry->ret = ret; + ), + + TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu " + "rw = %d ret = %d", + show_dev_ino(__entry), + __entry->pos, + __entry->len, + __entry->rw, + __entry->ret) +); + TRACE_EVENT(f2fs_reserve_new_block, TP_PROTO(struct inode *inode, nid_t nid, unsigned int ofs_in_node), @@ -593,89 +654,520 @@ TRACE_EVENT(f2fs_reserve_new_block, __entry->ofs_in_node) ); -TRACE_EVENT(f2fs_do_submit_bio, +DECLARE_EVENT_CLASS(f2fs__submit_page_bio, + + TP_PROTO(struct page *page, struct f2fs_io_info *fio), + + TP_ARGS(page, fio), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(pgoff_t, index) + __field(block_t, blkaddr) + __field(int, rw) + __field(int, type) + ), + + TP_fast_assign( + __entry->dev = page->mapping->host->i_sb->s_dev; + __entry->ino = page->mapping->host->i_ino; + __entry->index = page->index; + __entry->blkaddr = fio->blk_addr; + __entry->rw = fio->rw; + __entry->type = fio->type; + ), + + TP_printk("dev = (%d,%d), ino = %lu, page_index = 0x%lx, " + "blkaddr = 0x%llx, rw = %s%s, type = %s", + show_dev_ino(__entry), + (unsigned long)__entry->index, + (unsigned long long)__entry->blkaddr, + show_bio_type(__entry->rw), + show_block_type(__entry->type)) +); + +DEFINE_EVENT_CONDITION(f2fs__submit_page_bio, f2fs_submit_page_bio, + + TP_PROTO(struct page *page, struct f2fs_io_info *fio), + + TP_ARGS(page, fio), + + TP_CONDITION(page->mapping) +); + +DEFINE_EVENT_CONDITION(f2fs__submit_page_bio, f2fs_submit_page_mbio, + + TP_PROTO(struct page *page, struct f2fs_io_info *fio), + + TP_ARGS(page, fio), + + TP_CONDITION(page->mapping) +); - TP_PROTO(struct super_block *sb, int btype, bool sync, struct bio *bio), +DECLARE_EVENT_CLASS(f2fs__submit_bio, - TP_ARGS(sb, btype, sync, bio), + TP_PROTO(struct super_block *sb, struct f2fs_io_info *fio, + struct bio *bio), + + TP_ARGS(sb, fio, bio), TP_STRUCT__entry( __field(dev_t, dev) - __field(int, btype) - __field(bool, sync) + __field(int, rw) + __field(int, type) __field(sector_t, sector) __field(unsigned int, size) ), TP_fast_assign( __entry->dev = sb->s_dev; - __entry->btype = btype; - __entry->sync = sync; + __entry->rw = fio->rw; + __entry->type = fio->type; __entry->sector = bio->bi_sector; __entry->size = bio->bi_size; ), - TP_printk("dev = (%d,%d), type = %s, io = %s, sector = %lld, size = %u", + TP_printk("dev = (%d,%d), %s%s, %s, sector = %lld, size = %u", show_dev(__entry), - show_block_type(__entry->btype), - __entry->sync ? "sync" : "no sync", + show_bio_type(__entry->rw), + show_block_type(__entry->type), (unsigned long long)__entry->sector, __entry->size) ); -TRACE_EVENT(f2fs_submit_write_page, +DEFINE_EVENT_CONDITION(f2fs__submit_bio, f2fs_submit_write_bio, + + TP_PROTO(struct super_block *sb, struct f2fs_io_info *fio, + struct bio *bio), + + TP_ARGS(sb, fio, bio), + + TP_CONDITION(bio) +); + +DEFINE_EVENT_CONDITION(f2fs__submit_bio, f2fs_submit_read_bio, + + TP_PROTO(struct super_block *sb, struct f2fs_io_info *fio, + struct bio *bio), + + TP_ARGS(sb, fio, bio), + + TP_CONDITION(bio) +); + +TRACE_EVENT(f2fs_write_begin, - TP_PROTO(struct page *page, block_t blk_addr, int type), + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), - TP_ARGS(page, blk_addr, type), + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(loff_t, pos) + __field(unsigned int, len) + __field(unsigned int, flags) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->flags = flags; + ), + + TP_printk("dev = (%d,%d), ino = %lu, pos = %llu, len = %u, flags = %u", + show_dev_ino(__entry), + (unsigned long long)__entry->pos, + __entry->len, + __entry->flags) +); + +TRACE_EVENT(f2fs_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(loff_t, pos) + __field(unsigned int, len) + __field(unsigned int, copied) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev = (%d,%d), ino = %lu, pos = %llu, len = %u, copied = %u", + show_dev_ino(__entry), + (unsigned long long)__entry->pos, + __entry->len, + __entry->copied) +); + +DECLARE_EVENT_CLASS(f2fs__page, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) __field(int, type) + __field(int, dir) __field(pgoff_t, index) - __field(block_t, block) + __field(int, dirty) + __field(int, uptodate) ), TP_fast_assign( __entry->dev = page->mapping->host->i_sb->s_dev; __entry->ino = page->mapping->host->i_ino; __entry->type = type; + __entry->dir = S_ISDIR(page->mapping->host->i_mode); __entry->index = page->index; - __entry->block = blk_addr; + __entry->dirty = PageDirty(page); + __entry->uptodate = PageUptodate(page); ), - TP_printk("dev = (%d,%d), ino = %lu, %s, index = %lu, blkaddr = 0x%llx", + TP_printk("dev = (%d,%d), ino = %lu, %s, %s, index = %lu, " + "dirty = %d, uptodate = %d", show_dev_ino(__entry), show_block_type(__entry->type), + show_file_type(__entry->dir), (unsigned long)__entry->index, - (unsigned long long)__entry->block) + __entry->dirty, + __entry->uptodate) +); + +DEFINE_EVENT(f2fs__page, f2fs_writepage, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_do_write_data_page, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_readpage, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_set_page_dirty, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_vm_page_mkwrite, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_register_inmem_page, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +DEFINE_EVENT(f2fs__page, f2fs_commit_inmem_page, + + TP_PROTO(struct page *page, int type), + + TP_ARGS(page, type) +); + +TRACE_EVENT(f2fs_writepages, + + TP_PROTO(struct inode *inode, struct writeback_control *wbc, int type), + + TP_ARGS(inode, wbc, type), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(int, type) + __field(int, dir) + __field(long, nr_to_write) + __field(long, pages_skipped) + __field(loff_t, range_start) + __field(loff_t, range_end) + __field(pgoff_t, writeback_index) + __field(int, sync_mode) + __field(char, for_kupdate) + __field(char, for_background) + __field(char, tagged_writepages) + __field(char, for_reclaim) + __field(char, range_cyclic) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->type = type; + __entry->dir = S_ISDIR(inode->i_mode); + __entry->nr_to_write = wbc->nr_to_write; + __entry->pages_skipped = wbc->pages_skipped; + __entry->range_start = wbc->range_start; + __entry->range_end = wbc->range_end; + __entry->writeback_index = inode->i_mapping->writeback_index; + __entry->sync_mode = wbc->sync_mode; + __entry->for_kupdate = wbc->for_kupdate; + __entry->for_background = wbc->for_background; + __entry->tagged_writepages = wbc->tagged_writepages; + __entry->for_reclaim = wbc->for_reclaim; + __entry->range_cyclic = wbc->range_cyclic; + ), + + TP_printk("dev = (%d,%d), ino = %lu, %s, %s, nr_to_write %ld, " + "skipped %ld, start %lld, end %lld, wb_idx %lu, sync_mode %d, " + "kupdate %u background %u tagged %u reclaim %u cyclic %u", + show_dev_ino(__entry), + show_block_type(__entry->type), + show_file_type(__entry->dir), + __entry->nr_to_write, + __entry->pages_skipped, + __entry->range_start, + __entry->range_end, + (unsigned long)__entry->writeback_index, + __entry->sync_mode, + __entry->for_kupdate, + __entry->for_background, + __entry->tagged_writepages, + __entry->for_reclaim, + __entry->range_cyclic) ); TRACE_EVENT(f2fs_write_checkpoint, - TP_PROTO(struct super_block *sb, bool is_umount, char *msg), + TP_PROTO(struct super_block *sb, int reason, char *msg), - TP_ARGS(sb, is_umount, msg), + TP_ARGS(sb, reason, msg), TP_STRUCT__entry( __field(dev_t, dev) - __field(bool, is_umount) + __field(int, reason) __field(char *, msg) ), TP_fast_assign( __entry->dev = sb->s_dev; - __entry->is_umount = is_umount; + __entry->reason = reason; __entry->msg = msg; ), TP_printk("dev = (%d,%d), checkpoint for %s, state = %s", show_dev(__entry), - __entry->is_umount ? "clean umount" : "consistency", + show_cpreason(__entry->reason), __entry->msg) ); +TRACE_EVENT(f2fs_issue_discard, + + TP_PROTO(struct super_block *sb, block_t blkstart, block_t blklen), + + TP_ARGS(sb, blkstart, blklen), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(block_t, blkstart) + __field(block_t, blklen) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->blkstart = blkstart; + __entry->blklen = blklen; + ), + + TP_printk("dev = (%d,%d), blkstart = 0x%llx, blklen = 0x%llx", + show_dev(__entry), + (unsigned long long)__entry->blkstart, + (unsigned long long)__entry->blklen) +); + +TRACE_EVENT(f2fs_issue_flush, + + TP_PROTO(struct super_block *sb, unsigned int nobarrier, + unsigned int flush_merge), + + TP_ARGS(sb, nobarrier, flush_merge), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned int, nobarrier) + __field(unsigned int, flush_merge) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->nobarrier = nobarrier; + __entry->flush_merge = flush_merge; + ), + + TP_printk("dev = (%d,%d), %s %s", + show_dev(__entry), + __entry->nobarrier ? "skip (nobarrier)" : "issue", + __entry->flush_merge ? " with flush_merge" : "") +); + +TRACE_EVENT(f2fs_lookup_extent_tree_start, + + TP_PROTO(struct inode *inode, unsigned int pgofs), + + TP_ARGS(inode, pgofs), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, pgofs) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pgofs = pgofs; + ), + + TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u", + show_dev_ino(__entry), + __entry->pgofs) +); + +TRACE_EVENT_CONDITION(f2fs_lookup_extent_tree_end, + + TP_PROTO(struct inode *inode, unsigned int pgofs, + struct extent_node *en), + + TP_ARGS(inode, pgofs, en), + + TP_CONDITION(en), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, pgofs) + __field(unsigned int, fofs) + __field(u32, blk) + __field(unsigned int, len) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pgofs = pgofs; + __entry->fofs = en->ei.fofs; + __entry->blk = en->ei.blk; + __entry->len = en->ei.len; + ), + + TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, " + "ext_info(fofs: %u, blk: %u, len: %u)", + show_dev_ino(__entry), + __entry->pgofs, + __entry->fofs, + __entry->blk, + __entry->len) +); + +TRACE_EVENT(f2fs_update_extent_tree, + + TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr), + + TP_ARGS(inode, pgofs, blkaddr), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, pgofs) + __field(u32, blk) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pgofs = pgofs; + __entry->blk = blkaddr; + ), + + TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, blkaddr = %u", + show_dev_ino(__entry), + __entry->pgofs, + __entry->blk) +); + +TRACE_EVENT(f2fs_shrink_extent_tree, + + TP_PROTO(struct f2fs_sb_info *sbi, unsigned int node_cnt, + unsigned int tree_cnt), + + TP_ARGS(sbi, node_cnt, tree_cnt), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned int, node_cnt) + __field(unsigned int, tree_cnt) + ), + + TP_fast_assign( + __entry->dev = sbi->sb->s_dev; + __entry->node_cnt = node_cnt; + __entry->tree_cnt = tree_cnt; + ), + + TP_printk("dev = (%d,%d), shrunk: node_cnt = %u, tree_cnt = %u", + show_dev(__entry), + __entry->node_cnt, + __entry->tree_cnt) +); + +TRACE_EVENT(f2fs_destroy_extent_tree, + + TP_PROTO(struct inode *inode, unsigned int node_cnt), + + TP_ARGS(inode, node_cnt), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, node_cnt) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->node_cnt = node_cnt; + ), + + TP_printk("dev = (%d,%d), ino = %lu, destroyed: node_cnt = %u", + show_dev_ino(__entry), + __entry->node_cnt) +); + #endif /* _TRACE_F2FS_H */ /* This part must be outside protection */ diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index a4ed56cf0eac5..509ce281015d9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -153,6 +153,7 @@ struct inodes_stat_t { #define FIFREEZE _IOWR('X', 119, int) /* Freeze */ #define FITHAW _IOWR('X', 120, int) /* Thaw */ #define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */ +#define FS_IOC_SHUTDOWN _IOR('X', 125, __u32) /* Shutdown */ #define FS_IOC_GETFLAGS _IOR('f', 1, long) #define FS_IOC_SETFLAGS _IOW('f', 2, long) @@ -201,4 +202,11 @@ struct inodes_stat_t { #define SYNC_FILE_RANGE_WRITE 2 #define SYNC_FILE_RANGE_WAIT_AFTER 4 +/* + * Flags for going down operation used by FS_IOC_GOINGDOWN + */ +#define FS_GOING_DOWN_FULLSYNC 0x0 /* going down with full sync */ +#define FS_GOING_DOWN_METASYNC 0x1 /* going down with metadata */ +#define FS_GOING_DOWN_NOSYNC 0x2 /* going down */ + #endif /* _UAPI_LINUX_FS_H */ diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 80e15fa366517..c14b8dc97a947 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -163,6 +163,7 @@ enum { DEVCONF_ACCEPT_RA_PREFIX_ROUTE, DEVCONF_ACCEPT_RA_RT_TABLE, DEVCONF_ACCEPT_RA_MTU, + DEVCONF_USE_OPTIMISTIC, DEVCONF_MAX }; diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h index d24930359da12..826820ae2e71d 100644 --- a/include/uapi/sound/compress_params.h +++ b/include/uapi/sound/compress_params.h @@ -57,6 +57,7 @@ #define MAX_NUM_CODECS 32 #define MAX_NUM_CODEC_DESCRIPTORS 32 #define MAX_NUM_BITRATES 32 +#define MAX_NUM_SAMPLE_RATES 32 /* compressed TX */ #define MAX_NUM_FRAMES_PER_BUFFER 1 @@ -361,7 +362,8 @@ union snd_codec_options { /** struct snd_codec_desc - description of codec capabilities * @max_ch: Maximum number of audio channels - * @sample_rates: Sampling rates in Hz, use SNDRV_PCM_RATE_xxx for this + * @sample_rates: Sampling rates in Hz, use values like 48000 for this + * @num_sample_rates: Number of valid values in sample_rates array * @bit_rate: Indexed array containing supported bit rates * @num_bitrates: Number of valid values in bit_rate array * @rate_control: value is specified by SND_RATECONTROLMODE defines. @@ -383,7 +385,8 @@ union snd_codec_options { struct snd_codec_desc { __u32 max_ch; - __u32 sample_rates; + __u32 sample_rates[MAX_NUM_SAMPLE_RATES]; + __u32 num_sample_rates; __u32 bit_rate[MAX_NUM_BITRATES]; __u32 num_bitrates; __u32 rate_control; @@ -401,7 +404,8 @@ struct snd_codec_desc { * @ch_out: Number of output channels. In case of contradiction between * this field and the channelMode field, the channelMode field * overrides. - * @sample_rate: Audio sample rate of input data + * @sample_rate: Audio sample rate of input data in Hz, use values like 48000 + * for this. * @bit_rate: Bitrate of encoded data. May be ignored by decoders * @rate_control: Encoding rate control. See SND_RATECONTROLMODE defines. * Encoders may rely on profiles for quality levels. diff --git a/init/Kconfig b/init/Kconfig index 6573f2c654d2e..1cfb030db8100 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -65,7 +65,7 @@ config LOCALVERSION config LOCALVERSION_AUTO bool "Automatically append version information to the version string" - default y + default n help This will try to automatically determine if the current tree is a release tree by looking for git tags that belong to the current @@ -741,7 +741,7 @@ config IKCONFIG_PROC config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" range 12 21 - default 17 + default 18 help Select kernel log buffer size as a power of 2. Examples: @@ -1832,3 +1832,11 @@ config ASN1 functions to call on what tags. source "kernel/Kconfig.locks" + +#add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +config OEM_DEBUG_SUPORT + bool + default y +#endif +#end add by jiachenghui for support oem trace,2015/05/09 diff --git a/kernel/cgroup.c b/kernel/cgroup.c old mode 100644 new mode 100755 index 05b36e7b9e6b6..e4118a03385a5 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2153,6 +2153,10 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid, bool threadgroup) */ tcred = __task_cred(tsk); if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) && +#ifdef VENDOR_EDIT +//huruihuan add for cgroup control + !uid_eq(cred->euid, GLOBAL_SYSTEM_UID) && +#endif !uid_eq(cred->euid, tcred->uid) && !uid_eq(cred->euid, tcred->suid)) { /* diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c old mode 100644 new mode 100755 index 75dda1ea5026f..a68d695e0aba5 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c @@ -332,7 +332,12 @@ static void freeze_cgroup(struct freezer *freezer) cgroup_iter_start(cgroup, &it); while ((task = cgroup_iter_next(cgroup, &it))) +#ifdef VENDOR_EDIT +//huruihuan add for freezing task in cgroup despite of PF_FREEZER_SKIP flag + freeze_cgroup_task(task); +#else freeze_task(task); +#endif cgroup_iter_end(cgroup, &it); } diff --git a/kernel/freezer.c b/kernel/freezer.c old mode 100644 new mode 100755 index 5420f635111f4..30fa31aceadc6 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -112,6 +112,29 @@ static void fake_signal_wake_up(struct task_struct *p) * RETURNS: * %false, if @p is not freezing or already frozen; %true, otherwise */ +#ifdef VENDOR_EDIT +//huruihuan add for freezing task in cgroup despite of PF_FREEZER_SKIP flag +bool freeze_cgroup_task(struct task_struct *p) +{ + unsigned long flags; + + spin_lock_irqsave(&freezer_lock, flags); + if (!freezing(p) || frozen(p)) { + spin_unlock_irqrestore(&freezer_lock, flags); + return false; + } + + if (!(p->flags & PF_KTHREAD)) + fake_signal_wake_up(p); + else + wake_up_state(p, TASK_INTERRUPTIBLE); + + spin_unlock_irqrestore(&freezer_lock, flags); + return true; +} + +#endif + bool freeze_task(struct task_struct *p) { unsigned long flags; diff --git a/kernel/kthread.c b/kernel/kthread.c index 760e86df8c204..c56c6f8ec6078 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -398,6 +398,8 @@ int kthread_park(struct task_struct *k) if (k != current) { wake_up_process(k); wait_for_completion(&kthread->parked); + while (k->state != TASK_PARKED) + cond_resched(); } } ret = 0; diff --git a/kernel/panic.c b/kernel/panic.c index 449a10219cbe9..3201cc4fe799b 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -66,6 +66,12 @@ void __weak panic_smp_self_stop(void) cpu_relax(); } +//add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT +extern bool is_otrace_on(void); +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for support oem trace,2015/05/09 + /** * panic - halt the system * @fmt: The text string to print @@ -91,6 +97,20 @@ void panic(const char *fmt, ...) */ local_irq_disable(); +//add by jiachenghui for support oem trace,2015/05/09 +#ifdef VENDOR_EDIT + pr_info("kernel panic because of %s\n", fmt); + if(!is_otrace_on()) { + if (strcmp(fmt, "modem") == 0) + kernel_restart("modem"); + else if (strcmp(fmt, "android") == 0) + kernel_restart("android"); + else + kernel_restart("kernel"); + } +#endif /*VENDOR_EDIT*/ +//end add by jiachenghui for support oem trace,2015/05/09 + /* * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 9b7cf67ea7b2b..00d4e572aec0c 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -26,6 +26,19 @@ config WAKELOCK bool default y +config POWERSUSPEND + bool "Power suspend" + default y + ---help--- + Call early suspend handlers when the user requested sleep state + changes. + +config POWERSUSPEND_DEBUG + bool "Powersuspend driver debugging code" + depends on POWERSUSPEND + help + Output debugging info in dmesg [POWERSUSPEND] (Yank555.lu) + config HIBERNATE_CALLBACKS bool diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 74c713ba61b07..67b97aa849985 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o +obj-$(CONFIG_POWERSUSPEND) += powersuspend.o obj-$(CONFIG_PM_AUTOSLEEP) += autosleep.o obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o obj-$(CONFIG_SUSPEND_TIME) += suspend_time.o diff --git a/kernel/power/main.c b/kernel/power/main.c old mode 100644 new mode 100755 index d77663bfedeb0..afa2f9f5afc82 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -71,6 +71,57 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr, power_attr(pm_async); +#ifdef VENDOR_EDIT +/* add by yangrujin@bsp 2015/8/17, add /sys/power/app_boot file to know boot mode */ + +static char androidboot_mode[20] = "\0"; +static int __init parse_androidboot_mode(char *str) +{ + if(str == NULL){ + return -1; + } + + snprintf(androidboot_mode, 20, "%s", str); + //printk(KERN_ERR "%s: str %s\n", __func__, str); + return 0; +} + +early_param("androidboot.mode", parse_androidboot_mode); + +char * get_androidboot_mode(void) +{ + return androidboot_mode; +} +EXPORT_SYMBOL_GPL(get_androidboot_mode); + +static ssize_t app_boot_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ +#if 1 + return sprintf(buf, "%s", get_androidboot_mode()); +#else + if (reboot_reason == 0x77665501) + return sprintf(buf, "reboot"); + else if (reboot_reason == 0x7766550a) + return sprintf(buf, "kernel"); + else if (reboot_reason == 0x7766550b) + return sprintf(buf, "modem"); + else if (reboot_reason == 0x7766550c) + return sprintf(buf, "android"); + else + return sprintf(buf, "normal"); +#endif +} + +static ssize_t app_boot_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + return 0; +} + +power_attr(app_boot); +#endif //VENDOR_EDIT + #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; @@ -603,6 +654,10 @@ static struct attribute * g[] = { #ifdef CONFIG_FREEZER &pm_freeze_timeout_attr.attr, #endif +#ifdef VENDOR_EDIT +/* add by yangrujin@bsp 2015/8/17, add /sys/power/app_boot file to know boot mode */ + &app_boot_attr.attr, +#endif //VENDOR_EDIT NULL, }; diff --git a/kernel/power/powersuspend.c b/kernel/power/powersuspend.c new file mode 100644 index 0000000000000..34453d668d6dc --- /dev/null +++ b/kernel/power/powersuspend.c @@ -0,0 +1,318 @@ +/* kernel/power/powersuspend.c + * + * Copyright (C) 2005-2008 Google, Inc. + * Copyright (C) 2013 Paul Reioux + * + * Modified by Jean-Pierre Rasquin + * + * v1.1 - make powersuspend not depend on a userspace initiator anymore, + * but use a hook in autosleep instead. + * + * v1.2 - make kernel / userspace mode switchable + * + * v1.3 - add a hook in display panel driver as alternative kernel trigger + * + * v1.4 - add a hybrid-kernel mode, accepting both kernel hooks (first wins) + * + * v1.5 - fix hybrid-kernel mode cannot be set through sysfs + * + * v1.6 - remove autosleep and hybrid modes (autosleep not working on shamu) + * + * v1.7 - do only run state change if change actually requests a new state + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 7 + +struct workqueue_struct *suspend_work_queue; + +static DEFINE_MUTEX(power_suspend_lock); +static LIST_HEAD(power_suspend_handlers); +static void power_suspend(struct work_struct *work); +static void power_resume(struct work_struct *work); +static DECLARE_WORK(power_suspend_work, power_suspend); +static DECLARE_WORK(power_resume_work, power_resume); +static DEFINE_SPINLOCK(state_lock); + +static int state; // Yank555.lu : Current powersave state (screen on / off) +static int mode; // Yank555.lu : Current powersave mode (userspace / panel) + +void register_power_suspend(struct power_suspend *handler) +{ + struct list_head *pos; + + mutex_lock(&power_suspend_lock); + list_for_each(pos, &power_suspend_handlers) { + struct power_suspend *p; + p = list_entry(pos, struct power_suspend, link); + } + list_add_tail(&handler->link, pos); + mutex_unlock(&power_suspend_lock); +} +EXPORT_SYMBOL(register_power_suspend); + +void unregister_power_suspend(struct power_suspend *handler) +{ + mutex_lock(&power_suspend_lock); + list_del(&handler->link); + mutex_unlock(&power_suspend_lock); +} +EXPORT_SYMBOL(unregister_power_suspend); + +static void power_suspend(struct work_struct *work) +{ + struct power_suspend *pos; + unsigned long irqflags; + int abort = 0; + + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] entering suspend...\n"); + #endif + mutex_lock(&power_suspend_lock); + spin_lock_irqsave(&state_lock, irqflags); + if (state == POWER_SUSPEND_INACTIVE) + abort = 1; + spin_unlock_irqrestore(&state_lock, irqflags); + + if (abort) + goto abort_suspend; + + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] suspending...\n"); + #endif + list_for_each_entry(pos, &power_suspend_handlers, link) { + if (pos->suspend != NULL) { + pos->suspend(pos); + } + } + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] suspend completed.\n"); + #endif +abort_suspend: + mutex_unlock(&power_suspend_lock); +} + +static void power_resume(struct work_struct *work) +{ + struct power_suspend *pos; + unsigned long irqflags; + int abort = 0; + + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] entering resume...\n"); + #endif + mutex_lock(&power_suspend_lock); + spin_lock_irqsave(&state_lock, irqflags); + if (state == POWER_SUSPEND_ACTIVE) + abort = 1; + spin_unlock_irqrestore(&state_lock, irqflags); + + if (abort) + goto abort_resume; + + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] resuming...\n"); + #endif + list_for_each_entry_reverse(pos, &power_suspend_handlers, link) { + if (pos->resume != NULL) { + pos->resume(pos); + } + } + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] resume completed.\n"); + #endif +abort_resume: + mutex_unlock(&power_suspend_lock); +} + +void set_power_suspend_state(int new_state) +{ + unsigned long irqflags; + + if (state != new_state) { + spin_lock_irqsave(&state_lock, irqflags); + if (state == POWER_SUSPEND_INACTIVE && new_state == POWER_SUSPEND_ACTIVE) { + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] state activated.\n"); + #endif + state = new_state; + queue_work(suspend_work_queue, &power_suspend_work); + } else if (state == POWER_SUSPEND_ACTIVE && new_state == POWER_SUSPEND_INACTIVE) { + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] state deactivated.\n"); + #endif + state = new_state; + queue_work(suspend_work_queue, &power_resume_work); + } + spin_unlock_irqrestore(&state_lock, irqflags); + #ifdef CONFIG_POWERSUSPEND_DEBUG + } else { + pr_info("[POWERSUSPEND] state change requested, but unchanged ?! Ignored !\n"); + #endif + } +} + +void set_power_suspend_state_panel_hook(int new_state) +{ + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] panel resquests %s.\n", new_state == POWER_SUSPEND_ACTIVE ? "sleep" : "wakeup"); + #endif + // Yank555.lu : Only allow panel hook changes in panel mode + if (mode == POWER_SUSPEND_PANEL) + set_power_suspend_state(new_state); +} + +EXPORT_SYMBOL(set_power_suspend_state_panel_hook); + +// ------------------------------------------ sysfs interface ------------------------------------------ + +static ssize_t power_suspend_state_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", state); +} + +static ssize_t power_suspend_state_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int new_state = 0; + + // Yank555.lu : Only allow sysfs changes from userspace mode + if (mode != POWER_SUSPEND_USERSPACE) + return -EINVAL; + + sscanf(buf, "%d\n", &new_state); + + #ifdef CONFIG_POWERSUSPEND_DEBUG + pr_info("[POWERSUSPEND] userspace resquests %s.\n", new_state == POWER_SUSPEND_ACTIVE ? "sleep" : "wakeup"); + #endif + if(new_state == POWER_SUSPEND_ACTIVE || new_state == POWER_SUSPEND_INACTIVE) + set_power_suspend_state(new_state); + + return count; +} + +static struct kobj_attribute power_suspend_state_attribute = + __ATTR(power_suspend_state, 0666, + power_suspend_state_show, + power_suspend_state_store); + +static ssize_t power_suspend_mode_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", mode); +} + +static ssize_t power_suspend_mode_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int data = 0; + + sscanf(buf, "%d\n", &data); + + switch (data) { + case POWER_SUSPEND_PANEL: + case POWER_SUSPEND_USERSPACE: mode = data; + return count; + default: + return -EINVAL; + } + +} + +static struct kobj_attribute power_suspend_mode_attribute = + __ATTR(power_suspend_mode, 0666, + power_suspend_mode_show, + power_suspend_mode_store); + +static ssize_t power_suspend_version_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "version: %d.%d\n", MAJOR_VERSION, MINOR_VERSION); +} + +static struct kobj_attribute power_suspend_version_attribute = + __ATTR(power_suspend_version, 0444, + power_suspend_version_show, + NULL); + +static struct attribute *power_suspend_attrs[] = +{ + &power_suspend_state_attribute.attr, + &power_suspend_mode_attribute.attr, + &power_suspend_version_attribute.attr, + NULL, +}; + +static struct attribute_group power_suspend_attr_group = +{ + .attrs = power_suspend_attrs, +}; + +static struct kobject *power_suspend_kobj; + +// ------------------ sysfs interface ----------------------- +static int __init power_suspend_init(void) +{ + + int sysfs_result; + + power_suspend_kobj = kobject_create_and_add("power_suspend", + kernel_kobj); + if (!power_suspend_kobj) { + pr_err("%s kobject create failed!\n", __FUNCTION__); + return -ENOMEM; + } + + sysfs_result = sysfs_create_group(power_suspend_kobj, + &power_suspend_attr_group); + + if (sysfs_result) { + pr_info("%s group create failed!\n", __FUNCTION__); + kobject_put(power_suspend_kobj); + return -ENOMEM; + } + + suspend_work_queue = create_singlethread_workqueue("p-suspend"); + + if (suspend_work_queue == NULL) { + return -ENOMEM; + } + +// mode = POWER_SUSPEND_USERSPACE; // Yank555.lu : Default to userspace mode + mode = POWER_SUSPEND_PANEL; // Yank555.lu : Default to display panel mode + + return 0; +} + +static void __exit power_suspend_exit(void) +{ + if (power_suspend_kobj != NULL) + kobject_put(power_suspend_kobj); + + destroy_workqueue(suspend_work_queue); +} + +core_initcall(power_suspend_init); +module_exit(power_suspend_exit); + +MODULE_AUTHOR("Paul Reioux / Jean-Pierre Rasquin "); +MODULE_DESCRIPTION("power_suspend - A replacement kernel PM driver for" + "Android's deprecated early_suspend/late_resume PM driver!"); +MODULE_LICENSE("GPL v2"); + diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c old mode 100644 new mode 100755 index 454568e6c8d28..786c0621a0952 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -168,6 +168,14 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) local_irq_enable(); } +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ +char wakeup_reason[32] = {0}; + +static struct timespec ts_resume = {0}; +static struct timespec ts_suspend = {0}; +#endif /* VENDOR_EDIT */ + /** * suspend_enter - Make the system enter the given sleep state. * @state: System sleep state to enter. @@ -175,6 +183,11 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) * * This function should be called after devices have been suspended. */ +#ifdef VENDOR_EDIT +extern void regulator_suspend_dump(void); +extern void pinctrl_suspend_dump(void); +extern void pinctrl_suspend_resume_config(bool to_suspend); +#endif /* VENDOR_EDIT */ static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; @@ -218,14 +231,40 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + getnstimeofday(&ts_suspend); +#endif /* VENDOR_EDIT */ error = syscore_suspend(); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + if(wakeup_reason[0]); + pr_info("Last wakeup reason is %s and last for %ld s\n", wakeup_reason,(long)(ts_suspend.tv_sec - ts_resume.tv_sec)); +#endif /* VENDOR_EDIT */ if (!error) { *wakeup = pm_wakeup_pending(); if (!(suspend_test(TEST_CORE) || *wakeup)) { +#ifdef VENDOR_EDIT + regulator_suspend_dump(); + pinctrl_suspend_resume_config(true); //reconfig to suspend state + pinctrl_suspend_dump(); +#endif /* VENDOR_EDIT */ error = suspend_ops->enter(state); +#ifdef VENDOR_EDIT + pinctrl_suspend_resume_config(false); //reconfig to resume state +#endif /* VENDOR_EDIT */ + events_check_enabled = false; } +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + memset(wakeup_reason, 0, sizeof(wakeup_reason)); +#endif /* VENDOR_EDIT */ syscore_resume(); +#ifdef VENDOR_EDIT +/* Zhonglan.sun@ProDrv.CHG,add 2015/1/7 Add for wakeup analysis */ + getnstimeofday(&ts_resume); +#endif /* VENDOR_EDIT */ } arch_suspend_enable_irqs(); diff --git a/kernel/printk.c b/kernel/printk.c old mode 100644 new mode 100755 index 29b53f253906d..a3cb5d7a0fef1 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -55,6 +56,11 @@ extern void printascii(char *); #endif +#ifdef VENDOR_EDIT +static bool print_wall_time = 0; +module_param_named(print_wall_time, print_wall_time, bool, S_IRUGO | S_IWUSR); +#endif + /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL @@ -406,6 +412,13 @@ static void log_oops_store(struct log *msg) } #endif +//add by jiachenghui for fix kmsg timestamp error +#ifdef VENDOR_EDIT +enum log_flags prevflag = LOG_NEWLINE; +int __getnstimeofday(struct timespec *ts); +#endif //VENDOR_EDIT +//end add by jiachenghui for fix kmsg timestamp error + /* insert record into the buffer, discard old ones, update heads */ static void log_store(int facility, int level, enum log_flags flags, u64 ts_nsec, @@ -414,6 +427,75 @@ static void log_store(int facility, int level, { struct log *msg; u32 size, pad_len; +//add by jch for jiachenghui for fix kmsg timestamp error +#ifdef VENDOR_EDIT + static bool time_showed ; + static char timebuf[LOG_LINE_MAX]; + static char testbuf[64]; + size_t tm_pre, tmp_len; + size_t text_lengh; + char *tm_text = timebuf; + char *next; + size_t len = 0; + bool prefix = true; + unsigned long rem_usec; + struct timespec tspec; + struct rtc_time tm; + u64 tms_nsec; + + tms_nsec = local_clock(); + if(print_wall_time && (tms_nsec > 20)){ + __getnstimeofday(&tspec); + rem_usec = tspec.tv_nsec; + tspec.tv_sec += 8*60*60; //Trasfer to Beijing time, UTC + 8 + rtc_time_to_tm(tspec.tv_sec, &tm); + + if ((prevflag & LOG_CONT) && !((flags&0x1f) & LOG_PREFIX)) + prefix = false; + + if ( (flags&0x1f) & LOG_CONT) { + if ((prevflag & LOG_CONT) && !(prevflag & LOG_NEWLINE)) + prefix = false; + } + + if (prefix){ + tmp_len = text_len; + do { + if(tmp_len+1 <= 0){ + len--; + break; + } + next = memchr(text, '\n', text_len); + if (next) { + text_lengh = next - text; + next++; + tmp_len -= next - text; + + } else { + text_lengh = tmp_len; + } + if (sprintf(testbuf, "[%02d%02d%02d_%02d:%02d:%02d.%06lu]@%d ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec,rem_usec / 1000,smp_processor_id() ) + text_lengh + 1 >= LOG_LINE_MAX - len) + break; + time_showed = true; + tm_pre = sprintf(tm_text+len, "[%02d%02d%02d_%02d:%02d:%02d.%06lu]@%d ",tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec,rem_usec / 1000,smp_processor_id()); + len += tm_pre; + memcpy(tm_text + len, text, text_lengh); + len += text_lengh; + if (next){ + tm_text[len++] = '\n'; + } + text = next; + } while (text); + text = tm_text; + text_len = len; + } + prevflag = flags & 0x1f; + } + else{ + time_showed = false; + } +#endif //VENDOR_EDIT +//end add by jiachenghui for fix kmsg timestamp error /* number of '\0' padding bytes to next message */ size = sizeof(struct log) + text_len + dict_len; @@ -464,6 +546,12 @@ static void log_store(int facility, int level, msg->ts_nsec = ts_nsec; else msg->ts_nsec = local_clock(); +//add by jch for jiachenghui for fix kmsg timestamp error +#ifdef VENDOR_EDIT + if(time_showed) + msg->ts_nsec = -1; +#endif //VENDOR_EDIT +//add by jch for jiachenghui for fix kmsg timestamp error memset(log_dict(msg) + dict_len, 0, pad_len); msg->len = sizeof(struct log) + text_len + dict_len + pad_len; @@ -959,6 +1047,16 @@ module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to" "print all kernel messages to the console."); +static int __init ftm_console_silent_setup(char *str) +{ + printk(KERN_INFO "ftm_silent_log\n"); + console_silent(); + + return 0; +} + +early_param("ftm_console_silent", ftm_console_silent_setup); + #ifdef CONFIG_BOOT_PRINTK_DELAY static int boot_delay; /* msecs delay after each printk during bootup */ @@ -1021,20 +1119,50 @@ static bool printk_time; #endif module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); +void getnstimeofday_no_nsecs(struct timespec *ts); + static size_t print_time(u64 ts, char *buf) { unsigned long rem_nsec; + struct timespec tspec; + struct rtc_time tm; if (!printk_time) return 0; +//add by jiachenghui for fix kmsg timestamp error +#ifdef VENDOR_EDIT + if(ts == -1) + return 0; +#endif +//end add by jiachenghui for fix kmsg timestamp error + rem_nsec = do_div(ts, 1000000000); if (!buf) return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts); - return sprintf(buf, "[%5lu.%06lu] ", - (unsigned long)ts, rem_nsec / 1000); + //Use wll time for DBEUG +#ifdef VENDOR_EDIT/*if ts < 20, it is not used for showing actual time*/ + if(print_wall_time && (ts > 20)){ + getnstimeofday_no_nsecs(&tspec); + tspec.tv_sec += 8*60*60; //Trasfer to Beijing time, UTC + 8 + rtc_time_to_tm(tspec.tv_sec, &tm); + + return sprintf(buf, "[%02d%02d%02d_%02d:%02d:%02d.%06lu]@%d ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec, + rem_nsec / 1000,smp_processor_id() ); + }else{ + return sprintf(buf, "[%5lu.%06lu]@%d ", + (unsigned long)ts, rem_nsec / 1000,smp_processor_id() ); + + } +#else + return sprintf(buf, "[%5lu.%06lu]@%d ", + (unsigned long)ts, rem_nsec / 1000,smp_processor_id() ); +#endif + + } static size_t print_prefix(const struct log *msg, bool syslog, char *buf) @@ -2630,9 +2758,14 @@ void register_console(struct console *newcon) } break; } - - if (!(newcon->flags & CON_ENABLED)) +#if 0 //del by jiachenghui for unregister uart driver by cmdline, 2015-4-23 +//#ifdef VENDOR_EDIT/* If console is set on cmdline, set uart output.LiWei added. 20150330*/ + if (!(newcon->flags & CON_ENABLED) ||!console_set_on_cmdline ) + return; +#else + if(!(newcon->flags & CON_ENABLED)) return; +#endif /* * If we have a bootconsole, and are switching to a real console, diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ff1640b614564..e854aa95a0b3d 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1649,6 +1649,21 @@ static void update_history(struct rq *rq, struct task_struct *p, if (!runtime || is_idle_task(p) || exiting_task(p) || !samples) goto done; +#ifdef VENDOR_EDIT + if (p->ravg.mitigated) { + /* update history accroding to previous records + * e.g. 60% loading in big cluster becomes 60% in smallest one + */ + for (ridx = 0; ridx < sched_ravg_hist_size; ridx++) { + hist[ridx] = div64_u64((u64)hist[ridx] * 1024 + , (u64)max_load_scale_factor); + sum += hist[ridx]; + if (hist[ridx] > max) + max = hist[ridx]; + } + goto update_demand; + } +#endif /* Push new 'runtime' value onto stack */ widx = sched_ravg_hist_size - 1; ridx = widx - samples; @@ -1666,6 +1681,9 @@ static void update_history(struct rq *rq, struct task_struct *p, max = hist[widx]; } +#ifdef VENDOR_EDIT +update_demand: +#endif p->ravg.sum = 0; if (p->on_rq) p->sched_class->dec_hmp_sched_stats(rq, p); @@ -1758,7 +1776,11 @@ static void update_task_demand(struct task_struct *p, struct rq *rq, u32 window_size = sched_ravg_window; new_window = mark_start < window_start; +#ifdef VENDOR_EDIT + if (!account_busy_for_task_demand(p, event) || p->ravg.mitigated) { +#else if (!account_busy_for_task_demand(p, event)) { +#endif if (new_window) /* If the time accounted isn't being accounted as * busy time, and a new window started, only the @@ -1767,6 +1789,13 @@ static void update_task_demand(struct task_struct *p, struct rq *rq, * elapsed, but since empty windows are dropped, * it is not necessary to account those. */ update_history(rq, p, p->ravg.sum, 1, event); +#ifdef VENDOR_EDIT + if (p->ravg.mitigated) { + /* force update history */ + update_history(rq, p, 1, RAVG_HIST_SIZE_MAX, event); + p->ravg.mitigated = 0; + } +#endif return; } diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6fe56baed0eaa..d7e5748029dbd 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -79,6 +79,24 @@ static unsigned int sched_nr_latency = 8; */ unsigned int sysctl_sched_child_runs_first __read_mostly; +#ifdef VENDOR_EDIT +enum thermal_aware_scheduling { + SCHED_TA_DISABLE, + SCHED_TA_THERMAL_ONLY, + SCHED_TA_ALWAYS_ON, +}; +/* + * Thermal-aware scheduling, prefer running on small cluster + * when task loading on big cluster is below certain threshold + * + * Options: + * SCHED_TA_DISABLE - Disable TA scheduling + * SCHED_TA_THERMAL_ONLY - Only enable when under thermal constraint + * SCHED_TA_ALWAYS_ON - Always enable TA scheduling + */ +unsigned int __read_mostly sysctl_thermal_aware_scheduling = SCHED_TA_THERMAL_ONLY; +#endif + /* * Controls whether, when SD_SHARE_PKG_RESOURCES is on, if all * tasks go to idle CPUs when woken. If this is off, note that the @@ -1684,6 +1702,18 @@ int sched_boost_handler(struct ctl_table *table, int write, return ret; } +static inline int is_cpu_throttling_imminent(int cpu); +#ifdef VENDOR_EDIT +void down_migrate_task(struct task_struct *p) +{ + if (p->ravg.mitigated) + return; + + if (sysctl_thermal_aware_scheduling) + p->ravg.mitigated = 1; +} +#endif + /* * Task will fit on a cpu if it's bandwidth consumption on that cpu * will be less than sched_upmigrate. A big task that was previously @@ -1700,10 +1730,18 @@ static int task_will_fit(struct task_struct *p, int cpu) struct rq *rq = cpu_rq(cpu); int upmigrate = sched_upmigrate; int nice = TASK_NICE(p); +#ifdef VENDOR_EDIT + int thermal_mitigation = 0; + int prev_cpu_throttled = 0, cpu_throttled = 0, ta_enabled = 0; +#endif if (rq->capacity == max_capacity) return 1; +#ifdef VENDOR_EDIT + if (p->ravg.mitigated) + return 1; +#endif if (sched_boost()) { if (rq->capacity > prev_rq->capacity) return 1; @@ -1711,13 +1749,37 @@ static int task_will_fit(struct task_struct *p, int cpu) if (nice > sched_upmigrate_min_nice || upmigrate_discouraged(p)) return 1; - load = scale_load_to_cpu(task_load(p), cpu); +#ifdef VENDOR_EDIT + if (sysctl_thermal_aware_scheduling == SCHED_TA_THERMAL_ONLY) { + prev_cpu_throttled = is_cpu_throttling_imminent(prev_cpu); + cpu_throttled = is_cpu_throttling_imminent(cpu); + if (prev_cpu_throttled || cpu_throttled) + ta_enabled = 1; + } else if (sysctl_thermal_aware_scheduling == SCHED_TA_ALWAYS_ON) + ta_enabled = 1; + + if (ta_enabled && cpu != prev_cpu + && prev_rq->max_possible_capacity > rq->max_possible_capacity) { + thermal_mitigation = 1; + load = scale_load_to_cpu(task_load(p), prev_cpu); + } else +#endif + load = scale_load_to_cpu(task_load(p), cpu); +#ifdef VENDOR_EDIT + if (prev_rq->capacity > rq->capacity || thermal_mitigation) +#else if (prev_rq->capacity > rq->capacity) +#endif upmigrate = sched_downmigrate; - if (load < upmigrate) + if (load < upmigrate) { +#ifdef VENDOR_EDIT + if (thermal_mitigation) + down_migrate_task(p); +#endif return 1; + } } return 0; @@ -1730,8 +1792,15 @@ static int eligible_cpu(struct task_struct *p, int cpu, int sync) if (mostly_idle_cpu_sync(cpu, sync)) return 1; - if (rq->capacity != max_capacity) + if (rq->capacity != max_capacity) { +#ifdef VENDOR_EDIT + /* Current demand is still high, bail all small cpus out. + * select_best_cpu() will choose proper cpu to run */ + if (p->ravg.mitigated) + return 1; +#endif return !spill_threshold_crossed(p, rq, cpu, sync); + } return 0; } @@ -1933,7 +2002,12 @@ static int skip_cpu(struct task_struct *p, int cpu, int reason) break; case EA_MIGRATION: - skip = rq->capacity < task_rq->capacity || +#ifdef VENDOR_EDIT + if (sysctl_thermal_aware_scheduling) + skip = power_cost(p, cpu) > power_cost(p, task_cpu(p)); + else +#endif + skip = rq->capacity < task_rq->capacity || power_cost(p, cpu) > power_cost(p, task_cpu(p)); break; @@ -2682,7 +2756,6 @@ static int lower_power_cpu_available(struct task_struct *p, int cpu) return (lowest_power_cpu != task_cpu(p)); } -static inline int is_cpu_throttling_imminent(int cpu); static inline int is_task_migration_throttled(struct task_struct *p); /* diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 7a86a3c956637..067db460967ba 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -25,8 +25,11 @@ #include #include #include +#ifdef VENDOR_EDIT +/* shankai@bsp.driver 2015-4-2 Add begin for power up alarm */ +#define ALARM_DELTA 0 +#endif /*VENDOR_EDIT */ -#define ALARM_DELTA 120 /** * struct alarm_base - Alarm timer bases diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c old mode 100644 new mode 100755 index 76fefb1613b29..45b1d31f9755e --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -162,7 +162,7 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) { cycle_t cycle_now, cycle_delta; struct clocksource *clock; - s64 nsec; + u64 nsec; /* read clocksource: */ clock = tk->clock; @@ -329,6 +329,15 @@ void getnstimeofday(struct timespec *ts) } EXPORT_SYMBOL(getnstimeofday); +void getnstimeofday_no_nsecs(struct timespec *ts) +{ + struct timekeeper *tk = &timekeeper; + ts->tv_sec = tk->xtime_sec; +} + +EXPORT_SYMBOL(getnstimeofday_no_nsecs); + + ktime_t ktime_get(void) { struct timekeeper *tk = &timekeeper; diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 322e164610725..bdb9ee0af9919 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -312,7 +312,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) int size; syscall_nr = trace_get_syscall_nr(current, regs); - if (syscall_nr < 0) + if (syscall_nr < 0 || syscall_nr >= NR_syscalls) return; if (!test_bit(syscall_nr, tr->enabled_enter_syscalls)) return; @@ -354,7 +354,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) int syscall_nr; syscall_nr = trace_get_syscall_nr(current, regs); - if (syscall_nr < 0) + if (syscall_nr < 0 || syscall_nr >= NR_syscalls) return; if (!test_bit(syscall_nr, tr->enabled_exit_syscalls)) return; @@ -557,7 +557,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) int size; syscall_nr = trace_get_syscall_nr(current, regs); - if (syscall_nr < 0) + if (syscall_nr < 0 || syscall_nr >= NR_syscalls) return; if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) return; @@ -633,7 +633,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) int size; syscall_nr = trace_get_syscall_nr(current, regs); - if (syscall_nr < 0) + if (syscall_nr < 0 || syscall_nr >= NR_syscalls) return; if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) return; diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index bd1c5baf69bef..31ee5c6033dfe 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -175,7 +175,8 @@ int ip_forward(struct sk_buff *skb) * We now generate an ICMP HOST REDIRECT giving the route * we calculated. */ - if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) + if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && + !skb_sec_path(skb)) ip_rt_send_redirect(skb); skb->priority = rt_tos2priority(iph->tos); diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 452e8a587c346..6e58d813da492 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -132,9 +132,19 @@ static inline void send_unreach(struct sk_buff *skb_in, int code) #ifdef CONFIG_IP_NF_TARGET_REJECT_SKERR if (skb_in->sk) { skb_in->sk->sk_err = icmp_err_convert[code].errno; - skb_in->sk->sk_error_report(skb_in->sk); - pr_debug("ipt_REJECT: sk_err=%d for skb=%p sk=%p\n", - skb_in->sk->sk_err, skb_in, skb_in->sk); +/*Modified by liwei for fix panic issue, fixskb -> sk ->sk_error_report error*/ +#ifdef VENDOR_EDIT + if(skb_in->sk->sk_state != TCP_TIME_WAIT){ + skb_in->sk->sk_error_report(skb_in->sk); + pr_debug("ipt_REJECT: sk_err=%d for skb=%p sk=%p\n", + skb_in->sk->sk_err, skb_in, skb_in->sk); + } +#else + skb_in->sk->sk_error_report(skb_in->sk); + pr_debug("ipt_REJECT: sk_err=%d for skb=%p sk=%p\n", + skb_in->sk->sk_err, skb_in, skb_in->sk); + +#endif } #endif } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b55673aec420a..7c8193c0bfe5a 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1508,11 +1508,10 @@ static int __mkroute_input(struct sk_buff *skb, do_cache = res->fi && !itag; if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && + skb->protocol == htons(ETH_P_IP) && (IN_DEV_SHARED_MEDIA(out_dev) || - inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { - flags |= RTCF_DOREDIRECT; - do_cache = false; - } + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) + IPCB(skb)->flags |= IPSKB_DOREDIRECT; if (skb->protocol != htons(ETH_P_IP)) { /* Not IP (i.e. ARP). Do not create route, if it is @@ -2253,6 +2252,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; if (rt->rt_flags & RTCF_NOTIFY) r->rtm_flags |= RTM_F_NOTIFY; + if (IPCB(skb)->flags & IPSKB_DOREDIRECT) + r->rtm_flags |= RTCF_DOREDIRECT; if (nla_put_be32(skb, RTA_DST, dst)) goto nla_put_failure; diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 894b7cea5d7b5..872b3a07d1548 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -153,6 +153,27 @@ static void bictcp_init(struct sock *sk) tcp_sk(sk)->snd_ssthresh = initial_ssthresh; } +static void bictcp_cwnd_event(struct sock *sk, enum tcp_ca_event event) +{ + if (event == CA_EVENT_TX_START) { + struct bictcp *ca = inet_csk_ca(sk); + u32 now = tcp_time_stamp; + s32 delta; + + delta = now - tcp_sk(sk)->lsndtime; + + /* We were application limited (idle) for a while. + * Shift epoch_start to keep cwnd growth to cubic curve. + */ + if (ca->epoch_start && delta > 0) { + ca->epoch_start += delta; + if (after(ca->epoch_start, now)) + ca->epoch_start = now; + } + return; + } +} + /* calculate the cubic root of x using a table lookup followed by one * Newton-Raphson iteration. * Avg err ~= 0.195% @@ -439,6 +460,7 @@ static struct tcp_congestion_ops cubictcp __read_mostly = { .cong_avoid = bictcp_cong_avoid, .set_state = bictcp_state, .undo_cwnd = bictcp_undo_cwnd, + .cwnd_event = bictcp_cwnd_event, .pkts_acked = bictcp_acked, .owner = THIS_MODULE, .name = "cubic", diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 0dbb96172fd07..f3acbf35e3b73 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -29,7 +29,7 @@ int sysctl_tcp_keepalive_probes __read_mostly = TCP_KEEPALIVE_PROBES; int sysctl_tcp_keepalive_intvl __read_mostly = TCP_KEEPALIVE_INTVL; int sysctl_tcp_retries1 __read_mostly = TCP_RETR1; int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; -int sysctl_tcp_orphan_retries __read_mostly; +int sysctl_tcp_orphan_retries __read_mostly = 3; int sysctl_tcp_thin_linear_timeouts __read_mostly; static void tcp_write_timer(unsigned long); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ee7e4d00d01cb..799d05c272499 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1294,10 +1294,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 21e7d2c037e67..be1f029af79dd 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1181,6 +1181,9 @@ enum { #endif IPV6_SADDR_RULE_ORCHID, IPV6_SADDR_RULE_PREFIX, +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + IPV6_SADDR_RULE_NOT_OPTIMISTIC, +#endif IPV6_SADDR_RULE_MAX }; @@ -1208,6 +1211,15 @@ static inline int ipv6_saddr_preferred(int type) return 0; } +static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) +{ +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; +#else + return false; +#endif +} + static int ipv6_get_saddr_eval(struct net *net, struct ipv6_saddr_score *score, struct ipv6_saddr_dst *dst, @@ -1268,10 +1280,16 @@ static int ipv6_get_saddr_eval(struct net *net, score->scopedist = ret; break; case IPV6_SADDR_RULE_PREFERRED: + { /* Rule 3: Avoid deprecated and optimistic addresses */ + u8 avoid = IFA_F_DEPRECATED; + + if (!ipv6_use_optimistic_addr(score->ifa->idev)) + avoid |= IFA_F_OPTIMISTIC; ret = ipv6_saddr_preferred(score->addr_type) || - !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); + !(score->ifa->flags & avoid); break; + } #ifdef CONFIG_IPV6_MIP6 case IPV6_SADDR_RULE_HOA: { @@ -1319,6 +1337,14 @@ static int ipv6_get_saddr_eval(struct net *net, ret = score->ifa->prefix_len; score->matchlen = ret; break; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + case IPV6_SADDR_RULE_NOT_OPTIMISTIC: + /* Optimistic addresses still have lower precedence than other + * preferred addresses. + */ + ret = !(score->ifa->flags & IFA_F_OPTIMISTIC); + break; +#endif default: ret = 0; } @@ -3294,8 +3320,15 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp) * Optimistic nodes can start receiving * Frames right away */ - if (ifp->flags & IFA_F_OPTIMISTIC) + if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(ifp->rt); + if (ipv6_use_optimistic_addr(idev)) { + /* Because optimistic nodes can use this address, + * notify listeners. If DAD fails, RTM_DELADDR is sent. + */ + ipv6_ifa_notify(RTM_NEWADDR, ifp); + } + } addrconf_dad_kick(ifp); out: @@ -4241,6 +4274,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; + array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; @@ -4976,6 +5010,14 @@ static struct addrconf_sysctl_table .proc_handler = proc_dointvec, }, + { + .procname = "use_optimistic", + .data = &ipv6_devconf.use_optimistic, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, #endif #ifdef CONFIG_IPV6_MROUTE { diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ffb673611411f..3939f771f1280 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1193,7 +1193,14 @@ static void ndisc_router_discovery(struct sk_buff *skb) if (rt) rt6_set_expires(rt, jiffies + (HZ * lifetime)); if (ra_msg->icmph.icmp6_hop_limit) { - in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; + /* Only set hop_limit on the interface if it is higher than + * the current hop_limit. + */ + if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) { + in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; + } else { + ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n"); + } if (rt) dst_metric_set(&rt->dst, RTAX_HOPLIMIT, ra_msg->icmph.icmp6_hop_limit); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c23a919331c5a..36f1e81ae4175 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -494,10 +494,8 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c index 612a5ddaf93b1..799bafc2af39e 100644 --- a/net/llc/sysctl_net_llc.c +++ b/net/llc/sysctl_net_llc.c @@ -18,28 +18,28 @@ static struct ctl_table llc2_timeout_table[] = { { .procname = "ack", .data = &sysctl_llc2_ack_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_ack_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "busy", .data = &sysctl_llc2_busy_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_busy_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "p", .data = &sysctl_llc2_p_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_p_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "rej", .data = &sysctl_llc2_rej_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_rej_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d25f293776482..957c1db666525 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c @@ -14,6 +14,30 @@ static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; +static bool nf_generic_should_process(u8 proto) +{ + switch (proto) { +#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE + case IPPROTO_SCTP: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE + case IPPROTO_DCCP: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE + case IPPROTO_GRE: + return false; +#endif +#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE + case IPPROTO_UDPLITE: + return false; +#endif + default: + return true; + } +} + static inline struct nf_generic_net *generic_pernet(struct net *net) { return &net->ct.nf_ct_proto.generic; @@ -67,7 +91,7 @@ static int generic_packet(struct nf_conn *ct, static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, unsigned int dataoff, unsigned int *timeouts) { - return true; + return nf_generic_should_process(nf_ct_protonum(ct)); } #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index fd3f0180e08fb..bea100b245c8d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -525,7 +525,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop, { int i, j; struct menu *submenu[8], *menu, *location = NULL; - struct jump_key *jump; + struct jump_key *jump = NULL; str_printf(r, _("Prompt: %s\n"), _(prop->text)); menu = prop->menu->parent; diff --git a/security/keys/gc.c b/security/keys/gc.c index d67c97bb10256..797818695c87a 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -201,12 +201,12 @@ static noinline void key_gc_unused_keys(struct list_head *keys) if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) atomic_dec(&key->user->nikeys); - key_user_put(key->user); - /* now throw away the key memory */ if (key->type->destroy) key->type->destroy(key); + key_user_put(key->user); + kfree(key->description); #ifdef KEY_DEBUGGING diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index af59d88c541bd..e0d6769c4328e 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -506,9 +506,6 @@ static int snd_compress_check_input(struct snd_compr_params *params) if (params->codec.ch_in == 0 || params->codec.ch_out == 0) return -EINVAL; - if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000)) - return -EINVAL; - return 0; } diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 7d2f84a4d0366..47a8decc23663 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -274,3 +274,9 @@ obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o # Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o + +#ifdef VENDOR_EDIT +#tfa9890 +snd-soc-tfa9890-objs := tfa9890/tfa98xx.o tfa9890/tfa_dsp.o tfa9890/tfa_container.o +obj-y += snd-soc-tfa9890.o +#endif \ No newline at end of file diff --git a/sound/soc/codecs/tfa9890/tfa98xx-core.h b/sound/soc/codecs/tfa9890/tfa98xx-core.h new file mode 100644 index 0000000000000..7db7127c62707 --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa98xx-core.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __TFA98XX_CORE_H__ +#define __TFA98XX_CORE_H__ + +#include +#include +#include +#include +#include + + +#define TFA98XX_MAX_I2C_SIZE 252 + + +/* DSP Write/Read */ +#define TFA98XX_DSP_WRITE 0 +#define TFA98XX_DSP_READ 1 + +/* RPC Status results */ +#define TFA98XX_STATUS_OK 0 +#define TFA98XX_INVALID_MODULE_ID 2 +#define TFA98XX_INVALID_PARAM_ID 3 +#define TFA98XX_INVALID_INFO_ID 4 + +/* Params masks */ +#define TFA98XX_FORMAT_MASK (0x7) +#define TFA98XX_FORMAT_LSB (0x4) +#define TFA98XX_FORMAT_MSB (0x2) + +#define TFA98XX_POWER_DOWN (0x1) + +/* Mute States */ +#define TFA98XX_MUTE_OFF 0 +#define TFA98XX_DIGITAL_MUTE 1 +#define TFA98XX_AMP_MUTE 2 + + +/* DSP init status */ +#define TFA98XX_DSP_INIT_PENDING 0 +#define TFA98XX_DSP_INIT_DONE 1 +#define TFA98XX_DSP_INIT_FAIL -1 +#define TFA98XX_DSP_INIT_RECOVER -2 + + + +#define TFA_BITFIELDDSCMSK 0x7fffffff + +/* retry values */ +#define AREFS_TRIES 100 +#define CFSTABLE_TRIES 10 + +int tfa98xx_i2c_read(struct i2c_client *tfa98xx_client, u8 reg, u8 *value, int len); +int tfa98xx_bulk_write_raw(struct snd_soc_codec *codec, const u8 *data, u8 count); + +int tfa98xx_get_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int tfa98xx_set_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int tfa98xx_info_vstep(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); + +int tfa98xx_get_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int tfa98xx_set_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int tfa98xx_info_profile(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); + +/* the maximum message length in the communication with the DSP */ +#define MAX_PARAM_SIZE (145*3) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define ROUND_DOWN(a,n) (((a)/(n))*(n)) + +#define TFA98XX_PRESET_LENGTH 87 + + + +/* possible memory values for DMEM in CF_CONTROLs */ +enum Tfa98xx_DMEM { + Tfa98xx_DMEM_PMEM = 0, + Tfa98xx_DMEM_XMEM = 1, + Tfa98xx_DMEM_YMEM = 2, + Tfa98xx_DMEM_IOMEM = 3, +}; + +enum Tfa98xx_Mute { + Tfa98xx_Mute_Off, + Tfa98xx_Mute_Digital, + Tfa98xx_Mute_Amplifier +}; + +enum Tfa98xx_SpeakerBoostStatusFlags { + Tfa98xx_SpeakerBoost_Activity = 0, /* Input signal activity. */ + Tfa98xx_SpeakerBoost_S_Ctrl, /* S Control triggers the limiter */ + Tfa98xx_SpeakerBoost_Muted, /* 1 when signal is muted */ + Tfa98xx_SpeakerBoost_X_Ctrl, /* X Control triggers the limiter */ + Tfa98xx_SpeakerBoost_T_Ctrl, /* T Control triggers the limiter */ + Tfa98xx_SpeakerBoost_NewModel, /* New model is available */ + Tfa98xx_SpeakerBoost_VolumeRdy, /* 0:stable vol, 1:still smoothing */ + Tfa98xx_SpeakerBoost_Damaged, /* Speaker Damage detected */ + Tfa98xx_SpeakerBoost_SignalClipping /* input clipping detected */ +}; + + + +#endif diff --git a/sound/soc/codecs/tfa9890/tfa98xx-regs.h b/sound/soc/codecs/tfa9890/tfa98xx-regs.h new file mode 100644 index 0000000000000..2b5e4ec55017e --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa98xx-regs.h @@ -0,0 +1,1728 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __TFA98XX_REGS_H__ +#define __TFA98XX_REGS_H__ + + +/** StatusReg Register ($00) ************************************************/ + +#define TFA98XX_STATUSREG 0x00 +#define TFA98XX_STATUSREG_VDDS (0x1<<0) +#define TFA98XX_STATUSREG_VDDS_POS 0 +#define TFA98XX_STATUSREG_VDDS_LEN 1 +#define TFA98XX_STATUSREG_VDDS_MAX 1 +#define TFA98XX_STATUSREG_VDDS_MSK 0x1 + +#define TFA98XX_STATUSREG_PLLS (0x1<<1) +#define TFA98XX_STATUSREG_PLLS_POS 1 +#define TFA98XX_STATUSREG_PLLS_LEN 1 +#define TFA98XX_STATUSREG_PLLS_MAX 1 +#define TFA98XX_STATUSREG_PLLS_MSK 0x2 + +#define TFA98XX_STATUSREG_OTDS (0x1<<2) +#define TFA98XX_STATUSREG_OTDS_POS 2 +#define TFA98XX_STATUSREG_OTDS_LEN 1 +#define TFA98XX_STATUSREG_OTDS_MAX 1 +#define TFA98XX_STATUSREG_OTDS_MSK 0x4 + +#define TFA98XX_STATUSREG_OVDS (0x1<<3) +#define TFA98XX_STATUSREG_OVDS_POS 3 +#define TFA98XX_STATUSREG_OVDS_LEN 1 +#define TFA98XX_STATUSREG_OVDS_MAX 1 +#define TFA98XX_STATUSREG_OVDS_MSK 0x8 + +#define TFA98XX_STATUSREG_UVDS (0x1<<4) +#define TFA98XX_STATUSREG_UVDS_POS 4 +#define TFA98XX_STATUSREG_UVDS_LEN 1 +#define TFA98XX_STATUSREG_UVDS_MAX 1 +#define TFA98XX_STATUSREG_UVDS_MSK 0x10 + +#define TFA98XX_STATUSREG_OCDS (0x1<<5) +#define TFA98XX_STATUSREG_OCDS_POS 5 +#define TFA98XX_STATUSREG_OCDS_LEN 1 +#define TFA98XX_STATUSREG_OCDS_MAX 1 +#define TFA98XX_STATUSREG_OCDS_MSK 0x20 + +#define TFA98XX_STATUSREG_CLKS (0x1<<6) +#define TFA98XX_STATUSREG_CLKS_POS 6 +#define TFA98XX_STATUSREG_CLKS_LEN 1 +#define TFA98XX_STATUSREG_CLKS_MAX 1 +#define TFA98XX_STATUSREG_CLKS_MSK 0x40 + +#define TFA98XX_STATUSREG_CLIPS (0x1<<7) +#define TFA98XX_STATUSREG_CLIPS_POS 7 +#define TFA98XX_STATUSREG_CLIPS_LEN 1 +#define TFA98XX_STATUSREG_CLIPS_MAX 1 +#define TFA98XX_STATUSREG_CLIPS_MSK 0x80 + +#define TFA98XX_STATUSREG_MTPB (0x1<<8) +#define TFA98XX_STATUSREG_MTPB_POS 8 +#define TFA98XX_STATUSREG_MTPB_LEN 1 +#define TFA98XX_STATUSREG_MTPB_MAX 1 +#define TFA98XX_STATUSREG_MTPB_MSK 0x100 + +#define TFA98XX_STATUSREG_NOCLK (0x1<<9) +#define TFA98XX_STATUSREG_NOCLK_POS 9 +#define TFA98XX_STATUSREG_NOCLK_LEN 1 +#define TFA98XX_STATUSREG_NOCLK_MAX 1 +#define TFA98XX_STATUSREG_NOCLK_MSK 0x200 + +#define TFA98XX_STATUSREG_SPKS (0x1<<10) +#define TFA98XX_STATUSREG_SPKS_POS 10 +#define TFA98XX_STATUSREG_SPKS_LEN 1 +#define TFA98XX_STATUSREG_SPKS_MAX 1 +#define TFA98XX_STATUSREG_SPKS_MSK 0x400 + +#define TFA98XX_STATUSREG_ACS (0x1<<11) +#define TFA98XX_STATUSREG_ACS_POS 11 +#define TFA98XX_STATUSREG_ACS_LEN 1 +#define TFA98XX_STATUSREG_ACS_MAX 1 +#define TFA98XX_STATUSREG_ACS_MSK 0x800 + +#define TFA98XX_STATUSREG_SWS (0x1<<12) +#define TFA98XX_STATUSREG_SWS_POS 12 +#define TFA98XX_STATUSREG_SWS_LEN 1 +#define TFA98XX_STATUSREG_SWS_MAX 1 +#define TFA98XX_STATUSREG_SWS_MSK 0x1000 + +#define TFA98XX_STATUSREG_WDS (0x1<<13) +#define TFA98XX_STATUSREG_WDS_POS 13 +#define TFA98XX_STATUSREG_WDS_LEN 1 +#define TFA98XX_STATUSREG_WDS_MAX 1 +#define TFA98XX_STATUSREG_WDS_MSK 0x2000 + +#define TFA98XX_STATUSREG_AMPS (0x1<<14) +#define TFA98XX_STATUSREG_AMPS_POS 14 +#define TFA98XX_STATUSREG_AMPS_LEN 1 +#define TFA98XX_STATUSREG_AMPS_MAX 1 +#define TFA98XX_STATUSREG_AMPS_MSK 0x4000 + +#define TFA98XX_STATUSREG_AREFS (0x1<<15) +#define TFA98XX_STATUSREG_AREFS_POS 15 +#define TFA98XX_STATUSREG_AREFS_LEN 1 +#define TFA98XX_STATUSREG_AREFS_MAX 1 +#define TFA98XX_STATUSREG_AREFS_MSK 0x8000 + +/** BatteryVoltage Register ($01) *******************************************/ + +#define TFA98XX_BATTERYVOLTAGE 0x01 +#define TFA98XX_BATTERYVOLTAGE_BATS (0x3ff<<0) +#define TFA98XX_BATTERYVOLTAGE_BATS_POS 0 +#define TFA98XX_BATTERYVOLTAGE_BATS_LEN 10 +#define TFA98XX_BATTERYVOLTAGE_BATS_MAX 1023 +#define TFA98XX_BATTERYVOLTAGE_BATS_MSK 0x3ff + +/** Temperature Register ($02) **********************************************/ + +#define TFA98XX_TEMPERATURE 0x02 +#define TFA98XX_TEMPERATURE_TEMPS (0x1ff<<0) +#define TFA98XX_TEMPERATURE_TEMPS_POS 0 +#define TFA98XX_TEMPERATURE_TEMPS_LEN 9 +#define TFA98XX_TEMPERATURE_TEMPS_MAX 511 +#define TFA98XX_TEMPERATURE_TEMPS_MSK 0x1ff + +/** RevisionNumber Register ($03) *******************************************/ + +#define TFA98XX_REVISIONNUMBER 0x03 +#define TFA98XX_REVISIONNUMBER_REV (0xff<<0) +#define TFA98XX_REVISIONNUMBER_REV_POS 0 +#define TFA98XX_REVISIONNUMBER_REV_LEN 8 +#define TFA98XX_REVISIONNUMBER_REV_MAX 255 +#define TFA98XX_REVISIONNUMBER_REV_MSK 0xff + +/** RevisionNumber Register ($03) *******************************************/ + +#define TFA9891_REVISIONNUMBER 0x03 +#define TFA9891_REVISIONNUMBER_REV (0xff<<0) +#define TFA9891_REVISIONNUMBER_REV_POS 0 +#define TFA9891_REVISIONNUMBER_REV_LEN 8 +#define TFA9891_REVISIONNUMBER_REV_MAX 255 +#define TFA9891_REVISIONNUMBER_REV_MSK 0xff + +/** AudioReg Register ($04) *************************************************/ + +#define TFA98XX_AUDIOREG 0x04 +#define TFA98XX_AUDIOREG_CHS12 (0x3<<3) +#define TFA98XX_AUDIOREG_CHS12_POS 3 +#define TFA98XX_AUDIOREG_CHS12_LEN 2 +#define TFA98XX_AUDIOREG_CHS12_MAX 3 +#define TFA98XX_AUDIOREG_CHS12_MSK 0x18 + +#define TFA98XX_AUDIOREG_CHSA (0x3<<6) +#define TFA98XX_AUDIOREG_CHSA_POS 6 +#define TFA98XX_AUDIOREG_CHSA_LEN 2 +#define TFA98XX_AUDIOREG_CHSA_MAX 3 +#define TFA98XX_AUDIOREG_CHSA_MSK 0xc0 + +#define TFA98XX_AUDIOREG_AUDFS (0xf<<12) +#define TFA98XX_AUDIOREG_AUDFS_POS 12 +#define TFA98XX_AUDIOREG_AUDFS_LEN 4 +#define TFA98XX_AUDIOREG_AUDFS_MAX 15 +#define TFA98XX_AUDIOREG_AUDFS_MSK 0xf000 + +/** I2SReg Register ($04) ***************************************************/ + +#define TFA98XX_I2SREG 0x04 +#define TFA98XX_I2SREG_I2SF (0x7<<0) +#define TFA98XX_I2SREG_I2SF_POS 0 +#define TFA98XX_I2SREG_I2SF_LEN 3 +#define TFA98XX_I2SREG_I2SF_MAX 7 +#define TFA98XX_I2SREG_I2SF_MSK 0x7 + +#define TFA98XX_I2SREG_CHS12 (0x3<<3) +#define TFA98XX_I2SREG_CHS12_POS 3 +#define TFA98XX_I2SREG_CHS12_LEN 2 +#define TFA98XX_I2SREG_CHS12_MAX 3 +#define TFA98XX_I2SREG_CHS12_MSK 0x18 + +#define TFA98XX_I2SREG_CHS3 (0x1<<5) +#define TFA98XX_I2SREG_CHS3_POS 5 +#define TFA98XX_I2SREG_CHS3_LEN 1 +#define TFA98XX_I2SREG_CHS3_MAX 1 +#define TFA98XX_I2SREG_CHS3_MSK 0x20 + +#define TFA98XX_I2SREG_CHSA (0x3<<6) +#define TFA98XX_I2SREG_CHSA_POS 6 +#define TFA98XX_I2SREG_CHSA_LEN 2 +#define TFA98XX_I2SREG_CHSA_MAX 3 +#define TFA98XX_I2SREG_CHSA_MSK 0xc0 + +#define TFA98XX_I2SREG_I2SDOC (0x3<<8) +#define TFA98XX_I2SREG_I2SDOC_POS 8 +#define TFA98XX_I2SREG_I2SDOC_LEN 2 +#define TFA98XX_I2SREG_I2SDOC_MAX 3 +#define TFA98XX_I2SREG_I2SDOC_MSK 0x300 + +#define TFA98XX_I2SREG_DISP (0x1<<10) +#define TFA98XX_I2SREG_DISP_POS 10 +#define TFA98XX_I2SREG_DISP_LEN 1 +#define TFA98XX_I2SREG_DISP_MAX 1 +#define TFA98XX_I2SREG_DISP_MSK 0x400 + +#define TFA98XX_I2SREG_I2SDOE (0x1<<11) +#define TFA98XX_I2SREG_I2SDOE_POS 11 +#define TFA98XX_I2SREG_I2SDOE_LEN 1 +#define TFA98XX_I2SREG_I2SDOE_MAX 1 +#define TFA98XX_I2SREG_I2SDOE_MSK 0x800 + +#define TFA98XX_I2SREG_I2SSR (0xf<<12) +#define TFA98XX_I2SREG_I2SSR_POS 12 +#define TFA98XX_I2SREG_I2SSR_LEN 4 +#define TFA98XX_I2SREG_I2SSR_MAX 15 +#define TFA98XX_I2SREG_I2SSR_MSK 0xf000 + +/** bat_prot Register ($05) *************************************************/ + +#define TFA98XX_BAT_PROT 0x05 +#define TFA98XX_BAT_PROT_BSSCR (0x3<<0) +#define TFA98XX_BAT_PROT_BSSCR_POS 0 +#define TFA98XX_BAT_PROT_BSSCR_LEN 2 +#define TFA98XX_BAT_PROT_BSSCR_MAX 3 +#define TFA98XX_BAT_PROT_BSSCR_MSK 0x3 + +#define TFA98XX_BAT_PROT_BSST (0xf<<2) +#define TFA98XX_BAT_PROT_BSST_POS 2 +#define TFA98XX_BAT_PROT_BSST_LEN 4 +#define TFA98XX_BAT_PROT_BSST_MAX 15 +#define TFA98XX_BAT_PROT_BSST_MSK 0x3c + +#define TFA98XX_BAT_PROT_BSSRL (0x3<<6) +#define TFA98XX_BAT_PROT_BSSRL_POS 6 +#define TFA98XX_BAT_PROT_BSSRL_LEN 2 +#define TFA98XX_BAT_PROT_BSSRL_MAX 3 +#define TFA98XX_BAT_PROT_BSSRL_MSK 0xc0 + +#define TFA98XX_BAT_PROT_BSSRR (0x7<<8) +#define TFA98XX_BAT_PROT_BSSRR_POS 8 +#define TFA98XX_BAT_PROT_BSSRR_LEN 3 +#define TFA98XX_BAT_PROT_BSSRR_MAX 7 +#define TFA98XX_BAT_PROT_BSSRR_MSK 0x700 + +#define TFA98XX_BAT_PROT_BSSHY (0x3<<11) +#define TFA98XX_BAT_PROT_BSSHY_POS 11 +#define TFA98XX_BAT_PROT_BSSHY_LEN 2 +#define TFA98XX_BAT_PROT_BSSHY_MAX 3 +#define TFA98XX_BAT_PROT_BSSHY_MSK 0x1800 + +#define TFA98XX_BAT_PROT_BSSR (0x1<<14) +#define TFA98XX_BAT_PROT_BSSR_POS 14 +#define TFA98XX_BAT_PROT_BSSR_LEN 1 +#define TFA98XX_BAT_PROT_BSSR_MAX 1 +#define TFA98XX_BAT_PROT_BSSR_MSK 0x4000 + +#define TFA98XX_BAT_PROT_BSSBY (0x1<<15) +#define TFA98XX_BAT_PROT_BSSBY_POS 15 +#define TFA98XX_BAT_PROT_BSSBY_LEN 1 +#define TFA98XX_BAT_PROT_BSSBY_MAX 1 +#define TFA98XX_BAT_PROT_BSSBY_MSK 0x8000 + +/** bat_prot Register ($05) *************************************************/ + +#define TFA9887_BAT_PROT 0x05 +#define TFA9887_BAT_PROT_BSSBY (0x1<<0) +#define TFA9887_BAT_PROT_BSSBY_POS 0 +#define TFA9887_BAT_PROT_BSSBY_LEN 1 +#define TFA9887_BAT_PROT_BSSBY_MAX 1 +#define TFA9887_BAT_PROT_BSSBY_MSK 0x1 + +#define TFA9887_BAT_PROT_BSSCR (0x3<<1) +#define TFA9887_BAT_PROT_BSSCR_POS 1 +#define TFA9887_BAT_PROT_BSSCR_LEN 2 +#define TFA9887_BAT_PROT_BSSCR_MAX 3 +#define TFA9887_BAT_PROT_BSSCR_MSK 0x6 + +#define TFA9887_BAT_PROT_BSST (0x7<<3) +#define TFA9887_BAT_PROT_BSST_POS 3 +#define TFA9887_BAT_PROT_BSST_LEN 3 +#define TFA9887_BAT_PROT_BSST_MAX 7 +#define TFA9887_BAT_PROT_BSST_MSK 0x38 + +#define TFA9887_BAT_PROT_I2SDOC (0x1<<15) +#define TFA9887_BAT_PROT_I2SDOC_POS 15 +#define TFA9887_BAT_PROT_I2SDOC_LEN 1 +#define TFA9887_BAT_PROT_I2SDOC_MAX 1 +#define TFA9887_BAT_PROT_I2SDOC_MSK 0x8000 + +/** audio_ctr Register ($06) ************************************************/ + +#define TFA98XX_AUDIO_CTR 0x06 +#define TFA98XX_AUDIO_CTR_DPSA (0x1<<0) +#define TFA98XX_AUDIO_CTR_DPSA_POS 0 +#define TFA98XX_AUDIO_CTR_DPSA_LEN 1 +#define TFA98XX_AUDIO_CTR_DPSA_MAX 1 +#define TFA98XX_AUDIO_CTR_DPSA_MSK 0x1 + +#define TFA98XX_AUDIO_CTR_CFSM (0x1<<5) +#define TFA98XX_AUDIO_CTR_CFSM_POS 5 +#define TFA98XX_AUDIO_CTR_CFSM_LEN 1 +#define TFA98XX_AUDIO_CTR_CFSM_MAX 1 +#define TFA98XX_AUDIO_CTR_CFSM_MSK 0x20 + +#define TFA98XX_AUDIO_CTR_BSSS (0x1<<7) +#define TFA98XX_AUDIO_CTR_BSSS_POS 7 +#define TFA98XX_AUDIO_CTR_BSSS_LEN 1 +#define TFA98XX_AUDIO_CTR_BSSS_MAX 1 +#define TFA98XX_AUDIO_CTR_BSSS_MSK 0x80 + +#define TFA98XX_AUDIO_CTR_VOL (0xff<<8) +#define TFA98XX_AUDIO_CTR_VOL_POS 8 +#define TFA98XX_AUDIO_CTR_VOL_LEN 8 +#define TFA98XX_AUDIO_CTR_VOL_MAX 255 +#define TFA98XX_AUDIO_CTR_VOL_MSK 0xff00 + +/** DCDCboost Register ($07) ************************************************/ + +#define TFA98XX_DCDCBOOST 0x07 +#define TFA98XX_DCDCBOOST_DCVO (0x7<<0) +#define TFA98XX_DCDCBOOST_DCVO_POS 0 +#define TFA98XX_DCDCBOOST_DCVO_LEN 3 +#define TFA98XX_DCDCBOOST_DCVO_MAX 7 +#define TFA98XX_DCDCBOOST_DCVO_MSK 0x7 + +#define TFA98XX_DCDCBOOST_DCMCC (0xf<<3) +#define TFA98XX_DCDCBOOST_DCMCC_POS 3 +#define TFA98XX_DCDCBOOST_DCMCC_LEN 4 +#define TFA98XX_DCDCBOOST_DCMCC_MAX 15 +#define TFA98XX_DCDCBOOST_DCMCC_MSK 0x78 + +#define TFA98XX_DCDCBOOST_DCIE (0x1<<10) +#define TFA98XX_DCDCBOOST_DCIE_POS 10 +#define TFA98XX_DCDCBOOST_DCIE_LEN 1 +#define TFA98XX_DCDCBOOST_DCIE_MAX 1 +#define TFA98XX_DCDCBOOST_DCIE_MSK 0x400 + +#define TFA98XX_DCDCBOOST_DCSR (0x1<<11) +#define TFA98XX_DCDCBOOST_DCSR_POS 11 +#define TFA98XX_DCDCBOOST_DCSR_LEN 1 +#define TFA98XX_DCDCBOOST_DCSR_MAX 1 +#define TFA98XX_DCDCBOOST_DCSR_MSK 0x800 + +#define TFA98XX_DCDCBOOST_DCPAVG (0x1<<12) +#define TFA98XX_DCDCBOOST_DCPAVG_POS 12 +#define TFA98XX_DCDCBOOST_DCPAVG_LEN 1 +#define TFA98XX_DCDCBOOST_DCPAVG_MAX 1 +#define TFA98XX_DCDCBOOST_DCPAVG_MSK 0x1000 + +/** spkr_calibration Register ($08) *****************************************/ + +#define TFA98XX_SPKR_CALIBRATION 0x08 +#define TFA98XX_SPKR_CALIBRATION_TROS (0x1<<0) +#define TFA98XX_SPKR_CALIBRATION_TROS_POS 0 +#define TFA98XX_SPKR_CALIBRATION_TROS_LEN 1 +#define TFA98XX_SPKR_CALIBRATION_TROS_MAX 1 +#define TFA98XX_SPKR_CALIBRATION_TROS_MSK 0x1 + +#define TFA98XX_SPKR_CALIBRATION_EXTTS (0x1ff<<1) +#define TFA98XX_SPKR_CALIBRATION_EXTTS_POS 1 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_LEN 9 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MAX 511 +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MSK 0x3fe + +/** sys_ctrl Register ($09) *************************************************/ + +#define TFA98XX_SYS_CTRL 0x09 +#define TFA98XX_SYS_CTRL_PWDN (0x1<<0) +#define TFA98XX_SYS_CTRL_PWDN_POS 0 +#define TFA98XX_SYS_CTRL_PWDN_LEN 1 +#define TFA98XX_SYS_CTRL_PWDN_MAX 1 +#define TFA98XX_SYS_CTRL_PWDN_MSK 0x1 + +#define TFA98XX_SYS_CTRL_I2CR (0x1<<1) +#define TFA98XX_SYS_CTRL_I2CR_POS 1 +#define TFA98XX_SYS_CTRL_I2CR_LEN 1 +#define TFA98XX_SYS_CTRL_I2CR_MAX 1 +#define TFA98XX_SYS_CTRL_I2CR_MSK 0x2 + +#define TFA98XX_SYS_CTRL_CFE (0x1<<2) +#define TFA98XX_SYS_CTRL_CFE_POS 2 +#define TFA98XX_SYS_CTRL_CFE_LEN 1 +#define TFA98XX_SYS_CTRL_CFE_MAX 1 +#define TFA98XX_SYS_CTRL_CFE_MSK 0x4 + +#define TFA98XX_SYS_CTRL_AMPE (0x1<<3) +#define TFA98XX_SYS_CTRL_AMPE_POS 3 +#define TFA98XX_SYS_CTRL_AMPE_LEN 1 +#define TFA98XX_SYS_CTRL_AMPE_MAX 1 +#define TFA98XX_SYS_CTRL_AMPE_MSK 0x8 + +#define TFA98XX_SYS_CTRL_DCA (0x1<<4) +#define TFA98XX_SYS_CTRL_DCA_POS 4 +#define TFA98XX_SYS_CTRL_DCA_LEN 1 +#define TFA98XX_SYS_CTRL_DCA_MAX 1 +#define TFA98XX_SYS_CTRL_DCA_MSK 0x10 + +#define TFA98XX_SYS_CTRL_SBSL (0x1<<5) +#define TFA98XX_SYS_CTRL_SBSL_POS 5 +#define TFA98XX_SYS_CTRL_SBSL_LEN 1 +#define TFA98XX_SYS_CTRL_SBSL_MAX 1 +#define TFA98XX_SYS_CTRL_SBSL_MSK 0x20 + +#define TFA98XX_SYS_CTRL_AMPC (0x1<<6) +#define TFA98XX_SYS_CTRL_AMPC_POS 6 +#define TFA98XX_SYS_CTRL_AMPC_LEN 1 +#define TFA98XX_SYS_CTRL_AMPC_MAX 1 +#define TFA98XX_SYS_CTRL_AMPC_MSK 0x40 + +#define TFA98XX_SYS_CTRL_DCDIS (0x1<<7) +#define TFA98XX_SYS_CTRL_DCDIS_POS 7 +#define TFA98XX_SYS_CTRL_DCDIS_LEN 1 +#define TFA98XX_SYS_CTRL_DCDIS_MAX 1 +#define TFA98XX_SYS_CTRL_DCDIS_MSK 0x80 + +#define TFA98XX_SYS_CTRL_PSDR (0x1<<8) +#define TFA98XX_SYS_CTRL_PSDR_POS 8 +#define TFA98XX_SYS_CTRL_PSDR_LEN 1 +#define TFA98XX_SYS_CTRL_PSDR_MAX 1 +#define TFA98XX_SYS_CTRL_PSDR_MSK 0x100 + +#define TFA98XX_SYS_CTRL_DCCV (0x3<<9) +#define TFA98XX_SYS_CTRL_DCCV_POS 9 +#define TFA98XX_SYS_CTRL_DCCV_LEN 2 +#define TFA98XX_SYS_CTRL_DCCV_MAX 3 +#define TFA98XX_SYS_CTRL_DCCV_MSK 0x600 + +#define TFA98XX_SYS_CTRL_CCFD (0x1<<11) +#define TFA98XX_SYS_CTRL_CCFD_POS 11 +#define TFA98XX_SYS_CTRL_CCFD_LEN 1 +#define TFA98XX_SYS_CTRL_CCFD_MAX 1 +#define TFA98XX_SYS_CTRL_CCFD_MSK 0x800 + +#define TFA98XX_SYS_CTRL_INTPAD (0x3<<12) +#define TFA98XX_SYS_CTRL_INTPAD_POS 12 +#define TFA98XX_SYS_CTRL_INTPAD_LEN 2 +#define TFA98XX_SYS_CTRL_INTPAD_MAX 3 +#define TFA98XX_SYS_CTRL_INTPAD_MSK 0x3000 + +#define TFA98XX_SYS_CTRL_IPLL (0x1<<14) +#define TFA98XX_SYS_CTRL_IPLL_POS 14 +#define TFA98XX_SYS_CTRL_IPLL_LEN 1 +#define TFA98XX_SYS_CTRL_IPLL_MAX 1 +#define TFA98XX_SYS_CTRL_IPLL_MSK 0x4000 + +/** sys_ctrl Register ($09) *************************************************/ + +#define TFA98XX_SYS_CTRL 0x09 +#define TFA98XX_SYS_CTRL_ISEL (0x1<<13) +#define TFA98XX_SYS_CTRL_ISEL_POS 13 +#define TFA98XX_SYS_CTRL_ISEL_LEN 1 +#define TFA98XX_SYS_CTRL_ISEL_MAX 1 +#define TFA98XX_SYS_CTRL_ISEL_MSK 0x2000 + +/** I2S_sel_reg Register ($0a) **********************************************/ + +#define TFA98XX_I2S_SEL_REG 0x0a +#define TFA98XX_I2S_SEL_REG_DOLS (0x7<<0) +#define TFA98XX_I2S_SEL_REG_DOLS_POS 0 +#define TFA98XX_I2S_SEL_REG_DOLS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DOLS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DOLS_MSK 0x7 + +#define TFA98XX_I2S_SEL_REG_DORS (0x7<<3) +#define TFA98XX_I2S_SEL_REG_DORS_POS 3 +#define TFA98XX_I2S_SEL_REG_DORS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DORS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DORS_MSK 0x38 + +#define TFA98XX_I2S_SEL_REG_SPKL (0x7<<6) +#define TFA98XX_I2S_SEL_REG_SPKL_POS 6 +#define TFA98XX_I2S_SEL_REG_SPKL_LEN 3 +#define TFA98XX_I2S_SEL_REG_SPKL_MAX 7 +#define TFA98XX_I2S_SEL_REG_SPKL_MSK 0x1c0 + +#define TFA98XX_I2S_SEL_REG_SPKR (0x3<<9) +#define TFA98XX_I2S_SEL_REG_SPKR_POS 9 +#define TFA98XX_I2S_SEL_REG_SPKR_LEN 2 +#define TFA98XX_I2S_SEL_REG_SPKR_MAX 3 +#define TFA98XX_I2S_SEL_REG_SPKR_MSK 0x600 + +#define TFA98XX_I2S_SEL_REG_DCFG (0xf<<11) +#define TFA98XX_I2S_SEL_REG_DCFG_POS 11 +#define TFA98XX_I2S_SEL_REG_DCFG_LEN 4 +#define TFA98XX_I2S_SEL_REG_DCFG_MAX 15 +#define TFA98XX_I2S_SEL_REG_DCFG_MSK 0x7800 + +/** I2S_sel_reg Register ($0a) **********************************************/ + +#define TFA98XX_I2S_SEL_REG 0x0a +#define TFA98XX_I2S_SEL_REG_DOLS (0x7<<0) +#define TFA98XX_I2S_SEL_REG_DOLS_POS 0 +#define TFA98XX_I2S_SEL_REG_DOLS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DOLS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DOLS_MSK 0x7 + +#define TFA98XX_I2S_SEL_REG_DORS (0x7<<3) +#define TFA98XX_I2S_SEL_REG_DORS_POS 3 +#define TFA98XX_I2S_SEL_REG_DORS_LEN 3 +#define TFA98XX_I2S_SEL_REG_DORS_MAX 7 +#define TFA98XX_I2S_SEL_REG_DORS_MSK 0x38 + +#define TFA98XX_I2S_SEL_REG_SPKL (0x7<<6) +#define TFA98XX_I2S_SEL_REG_SPKL_POS 6 +#define TFA98XX_I2S_SEL_REG_SPKL_LEN 3 +#define TFA98XX_I2S_SEL_REG_SPKL_MAX 7 +#define TFA98XX_I2S_SEL_REG_SPKL_MSK 0x1c0 + +#define TFA98XX_I2S_SEL_REG_SPKR (0x3<<9) +#define TFA98XX_I2S_SEL_REG_SPKR_POS 9 +#define TFA98XX_I2S_SEL_REG_SPKR_LEN 2 +#define TFA98XX_I2S_SEL_REG_SPKR_MAX 3 +#define TFA98XX_I2S_SEL_REG_SPKR_MSK 0x600 + +#define TFA98XX_I2S_SEL_REG_DCFG (0xf<<11) +#define TFA98XX_I2S_SEL_REG_DCFG_POS 11 +#define TFA98XX_I2S_SEL_REG_DCFG_LEN 4 +#define TFA98XX_I2S_SEL_REG_DCFG_MAX 15 +#define TFA98XX_I2S_SEL_REG_DCFG_MSK 0x7800 + +/** mtpkey2_reg Register ($0b) **********************************************/ + +#define TFA98XX_MTPKEY2_REG 0x0b +#define TFA98XX_MTPKEY2_REG_MTPK (0xff<<0) +#define TFA98XX_MTPKEY2_REG_MTPK_POS 0 +#define TFA98XX_MTPKEY2_REG_MTPK_LEN 8 +#define TFA98XX_MTPKEY2_REG_MTPK_MAX 255 +#define TFA98XX_MTPKEY2_REG_MTPK_MSK 0xff + +/** voltage_sense_config Register ($0c) *************************************/ + +#define TFA98XX_VOLTAGE_SENSE_CONFIG 0x0c +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY (0x3f<<2) +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_POS 2 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_LEN 6 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_MAX 63 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_MSK 0xfc + +/** voltage_sense_config Register ($0c) *************************************/ + +#define TFA98XX_VOLTAGE_SENSE_CONFIG 0x0c +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY (0x3f<<2) +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_POS 2 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_LEN 6 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_MAX 63 +#define TFA98XX_VOLTAGE_SENSE_CONFIG_CVFDLY_MSK 0xfc + +/** interrupt_reg Register ($0f) ********************************************/ + +#define TFA98XX_INTERRUPT_REG 0x0f +#define TFA98XX_INTERRUPT_REG_VDDD (0x1<<0) +#define TFA98XX_INTERRUPT_REG_VDDD_POS 0 +#define TFA98XX_INTERRUPT_REG_VDDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MSK 0x1 + +#define TFA98XX_INTERRUPT_REG_OTDD (0x1<<1) +#define TFA98XX_INTERRUPT_REG_OTDD_POS 1 +#define TFA98XX_INTERRUPT_REG_OTDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MSK 0x2 + +#define TFA98XX_INTERRUPT_REG_OVDD (0x1<<2) +#define TFA98XX_INTERRUPT_REG_OVDD_POS 2 +#define TFA98XX_INTERRUPT_REG_OVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MSK 0x4 + +#define TFA98XX_INTERRUPT_REG_UVDD (0x1<<3) +#define TFA98XX_INTERRUPT_REG_UVDD_POS 3 +#define TFA98XX_INTERRUPT_REG_UVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MSK 0x8 + +#define TFA98XX_INTERRUPT_REG_OCDD (0x1<<4) +#define TFA98XX_INTERRUPT_REG_OCDD_POS 4 +#define TFA98XX_INTERRUPT_REG_OCDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MSK 0x10 + +#define TFA98XX_INTERRUPT_REG_CLKD (0x1<<5) +#define TFA98XX_INTERRUPT_REG_CLKD_POS 5 +#define TFA98XX_INTERRUPT_REG_CLKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MSK 0x20 + +#define TFA98XX_INTERRUPT_REG_DCCD (0x1<<6) +#define TFA98XX_INTERRUPT_REG_DCCD_POS 6 +#define TFA98XX_INTERRUPT_REG_DCCD_LEN 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MAX 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MSK 0x40 + +#define TFA98XX_INTERRUPT_REG_SPKD (0x1<<7) +#define TFA98XX_INTERRUPT_REG_SPKD_POS 7 +#define TFA98XX_INTERRUPT_REG_SPKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MSK 0x80 + +#define TFA98XX_INTERRUPT_REG_WDD (0x1<<8) +#define TFA98XX_INTERRUPT_REG_WDD_POS 8 +#define TFA98XX_INTERRUPT_REG_WDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_WDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_WDD_MSK 0x100 + +#define TFA98XX_INTERRUPT_REG_INT (0x1<<14) +#define TFA98XX_INTERRUPT_REG_INT_POS 14 +#define TFA98XX_INTERRUPT_REG_INT_LEN 1 +#define TFA98XX_INTERRUPT_REG_INT_MAX 1 +#define TFA98XX_INTERRUPT_REG_INT_MSK 0x4000 + +#define TFA98XX_INTERRUPT_REG_INTP (0x1<<15) +#define TFA98XX_INTERRUPT_REG_INTP_POS 15 +#define TFA98XX_INTERRUPT_REG_INTP_LEN 1 +#define TFA98XX_INTERRUPT_REG_INTP_MAX 1 +#define TFA98XX_INTERRUPT_REG_INTP_MSK 0x8000 + +/** interrupt_reg Register ($0f) ********************************************/ + +#define TFA98XX_INTERRUPT_REG 0x0f +#define TFA98XX_INTERRUPT_REG_VDDD (0x1<<0) +#define TFA98XX_INTERRUPT_REG_VDDD_POS 0 +#define TFA98XX_INTERRUPT_REG_VDDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_VDDD_MSK 0x1 + +#define TFA98XX_INTERRUPT_REG_OTDD (0x1<<1) +#define TFA98XX_INTERRUPT_REG_OTDD_POS 1 +#define TFA98XX_INTERRUPT_REG_OTDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OTDD_MSK 0x2 + +#define TFA98XX_INTERRUPT_REG_OVDD (0x1<<2) +#define TFA98XX_INTERRUPT_REG_OVDD_POS 2 +#define TFA98XX_INTERRUPT_REG_OVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OVDD_MSK 0x4 + +#define TFA98XX_INTERRUPT_REG_UVDD (0x1<<3) +#define TFA98XX_INTERRUPT_REG_UVDD_POS 3 +#define TFA98XX_INTERRUPT_REG_UVDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_UVDD_MSK 0x8 + +#define TFA98XX_INTERRUPT_REG_OCDD (0x1<<4) +#define TFA98XX_INTERRUPT_REG_OCDD_POS 4 +#define TFA98XX_INTERRUPT_REG_OCDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_OCDD_MSK 0x10 + +#define TFA98XX_INTERRUPT_REG_CLKD (0x1<<5) +#define TFA98XX_INTERRUPT_REG_CLKD_POS 5 +#define TFA98XX_INTERRUPT_REG_CLKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_CLKD_MSK 0x20 + +#define TFA98XX_INTERRUPT_REG_DCCD (0x1<<6) +#define TFA98XX_INTERRUPT_REG_DCCD_POS 6 +#define TFA98XX_INTERRUPT_REG_DCCD_LEN 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MAX 1 +#define TFA98XX_INTERRUPT_REG_DCCD_MSK 0x40 + +#define TFA98XX_INTERRUPT_REG_SPKD (0x1<<7) +#define TFA98XX_INTERRUPT_REG_SPKD_POS 7 +#define TFA98XX_INTERRUPT_REG_SPKD_LEN 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MAX 1 +#define TFA98XX_INTERRUPT_REG_SPKD_MSK 0x80 + +#define TFA98XX_INTERRUPT_REG_WDD (0x1<<8) +#define TFA98XX_INTERRUPT_REG_WDD_POS 8 +#define TFA98XX_INTERRUPT_REG_WDD_LEN 1 +#define TFA98XX_INTERRUPT_REG_WDD_MAX 1 +#define TFA98XX_INTERRUPT_REG_WDD_MSK 0x100 + +#define TFA98XX_INTERRUPT_REG_LCLK (0x1<<9) +#define TFA98XX_INTERRUPT_REG_LCLK_POS 9 +#define TFA98XX_INTERRUPT_REG_LCLK_LEN 1 +#define TFA98XX_INTERRUPT_REG_LCLK_MAX 1 +#define TFA98XX_INTERRUPT_REG_LCLK_MSK 0x200 + +#define TFA98XX_INTERRUPT_REG_INT (0x1<<14) +#define TFA98XX_INTERRUPT_REG_INT_POS 14 +#define TFA98XX_INTERRUPT_REG_INT_LEN 1 +#define TFA98XX_INTERRUPT_REG_INT_MAX 1 +#define TFA98XX_INTERRUPT_REG_INT_MSK 0x4000 + +#define TFA98XX_INTERRUPT_REG_INTP (0x1<<15) +#define TFA98XX_INTERRUPT_REG_INTP_POS 15 +#define TFA98XX_INTERRUPT_REG_INTP_LEN 1 +#define TFA98XX_INTERRUPT_REG_INTP_MAX 1 +#define TFA98XX_INTERRUPT_REG_INTP_MSK 0x8000 + +/** tdm_config_reg0 Register ($10) ******************************************/ + +#define TFA98XX_TDM_CONFIG_REG0 0x10 +#define TFA98XX_TDM_CONFIG_REG0_TDMMODE (0x1<<0) +#define TFA98XX_TDM_CONFIG_REG0_TDMMODE_POS 0 +#define TFA98XX_TDM_CONFIG_REG0_TDMMODE_LEN 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMMODE_MAX 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMMODE_MSK 0x1 + +#define TFA98XX_TDM_CONFIG_REG0_TDMPRF (0x3<<1) +#define TFA98XX_TDM_CONFIG_REG0_TDMPRF_POS 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMPRF_LEN 2 +#define TFA98XX_TDM_CONFIG_REG0_TDMPRF_MAX 3 +#define TFA98XX_TDM_CONFIG_REG0_TDMPRF_MSK 0x6 + +#define TFA98XX_TDM_CONFIG_REG0_TDMEN (0x1<<3) +#define TFA98XX_TDM_CONFIG_REG0_TDMEN_POS 3 +#define TFA98XX_TDM_CONFIG_REG0_TDMEN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMEN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMEN_MSK 0x8 + +#define TFA98XX_TDM_CONFIG_REG0_TDMCKINV (0x1<<4) +#define TFA98XX_TDM_CONFIG_REG0_TDMCKINV_POS 4 +#define TFA98XX_TDM_CONFIG_REG0_TDMCKINV_LEN 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMCKINV_MAX 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMCKINV_MSK 0x10 + +#define TFA98XX_TDM_CONFIG_REG0_TDMFSLN (0xf<<5) +#define TFA98XX_TDM_CONFIG_REG0_TDMFSLN_POS 5 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSLN_LEN 4 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSLN_MAX 15 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSLN_MSK 0x1e0 + +#define TFA98XX_TDM_CONFIG_REG0_TDMFSPOL (0x1<<9) +#define TFA98XX_TDM_CONFIG_REG0_TDMFSPOL_POS 9 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSPOL_LEN 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSPOL_MAX 1 +#define TFA98XX_TDM_CONFIG_REG0_TDMFSPOL_MSK 0x200 + +/** tdm_config_reg1 Register ($11) ******************************************/ + +#define TFA98XX_TDM_CONFIG_REG1 0x11 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLOTS (0xf<<0) +#define TFA98XX_TDM_CONFIG_REG1_TDMSLOTS_POS 0 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLOTS_LEN 4 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLOTS_MAX 15 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLOTS_MSK 0xf + +#define TFA98XX_TDM_CONFIG_REG1_TDMSLLN (0x1f<<4) +#define TFA98XX_TDM_CONFIG_REG1_TDMSLLN_POS 4 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLLN_LEN 5 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLLN_MAX 31 +#define TFA98XX_TDM_CONFIG_REG1_TDMSLLN_MSK 0x1f0 + +#define TFA98XX_TDM_CONFIG_REG1_TDMBRMG (0x1f<<9) +#define TFA98XX_TDM_CONFIG_REG1_TDMBRMG_POS 9 +#define TFA98XX_TDM_CONFIG_REG1_TDMBRMG_LEN 5 +#define TFA98XX_TDM_CONFIG_REG1_TDMBRMG_MAX 31 +#define TFA98XX_TDM_CONFIG_REG1_TDMBRMG_MSK 0x3e00 + +#define TFA98XX_TDM_CONFIG_REG1_TDMDDEL (0x1<<14) +#define TFA98XX_TDM_CONFIG_REG1_TDMDDEL_POS 14 +#define TFA98XX_TDM_CONFIG_REG1_TDMDDEL_LEN 1 +#define TFA98XX_TDM_CONFIG_REG1_TDMDDEL_MAX 1 +#define TFA98XX_TDM_CONFIG_REG1_TDMDDEL_MSK 0x4000 + +#define TFA98XX_TDM_CONFIG_REG1_TDMDADJ (0x1<<15) +#define TFA98XX_TDM_CONFIG_REG1_TDMDADJ_POS 15 +#define TFA98XX_TDM_CONFIG_REG1_TDMDADJ_LEN 1 +#define TFA98XX_TDM_CONFIG_REG1_TDMDADJ_MAX 1 +#define TFA98XX_TDM_CONFIG_REG1_TDMDADJ_MSK 0x8000 + +/** tdm_config_reg2 Register ($12) ******************************************/ + +#define TFA98XX_TDM_CONFIG_REG2 0x12 +#define TFA98XX_TDM_CONFIG_REG2_TDMCOMP (0x3<<0) +#define TFA98XX_TDM_CONFIG_REG2_TDMCOMP_POS 0 +#define TFA98XX_TDM_CONFIG_REG2_TDMCOMP_LEN 2 +#define TFA98XX_TDM_CONFIG_REG2_TDMCOMP_MAX 3 +#define TFA98XX_TDM_CONFIG_REG2_TDMCOMP_MSK 0x3 + +#define TFA98XX_TDM_CONFIG_REG2_TDMTXFRM (0x3<<2) +#define TFA98XX_TDM_CONFIG_REG2_TDMTXFRM_POS 2 +#define TFA98XX_TDM_CONFIG_REG2_TDMTXFRM_LEN 2 +#define TFA98XX_TDM_CONFIG_REG2_TDMTXFRM_MAX 3 +#define TFA98XX_TDM_CONFIG_REG2_TDMTXFRM_MSK 0xc + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0EN (0x1<<7) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0EN_POS 7 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0EN_MSK 0x80 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1EN (0x1<<8) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1EN_POS 8 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1EN_MSK 0x100 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2EN (0x1<<9) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2EN_POS 9 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2EN_MSK 0x200 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSO0EN (0x1<<10) +#define TFA98XX_TDM_CONFIG_REG2_TDMSO0EN_POS 10 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO0EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO0EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO0EN_MSK 0x400 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSO1EN (0x1<<11) +#define TFA98XX_TDM_CONFIG_REG2_TDMSO1EN_POS 11 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO1EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO1EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO1EN_MSK 0x800 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSO2EN (0x1<<12) +#define TFA98XX_TDM_CONFIG_REG2_TDMSO2EN_POS 12 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO2EN_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO2EN_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSO2EN_MSK 0x1000 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0IO (0x1<<13) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0IO_POS 13 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI0IO_MSK 0x2000 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1IO (0x1<<14) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1IO_POS 14 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI1IO_MSK 0x4000 + +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2IO (0x1<<15) +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2IO_POS 15 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG2_TDMSI2IO_MSK 0x8000 + +/** tdm_config_reg3 Register ($13) ******************************************/ + +#define TFA98XX_TDM_CONFIG_REG3 0x13 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO0IO (0x1<<0) +#define TFA98XX_TDM_CONFIG_REG3_TDMSO0IO_POS 0 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO0IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO0IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO0IO_MSK 0x1 + +#define TFA98XX_TDM_CONFIG_REG3_TDMSO1IO (0x1<<1) +#define TFA98XX_TDM_CONFIG_REG3_TDMSO1IO_POS 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO1IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO1IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO1IO_MSK 0x2 + +#define TFA98XX_TDM_CONFIG_REG3_TDMSO2IO (0x1<<2) +#define TFA98XX_TDM_CONFIG_REG3_TDMSO2IO_POS 2 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO2IO_LEN 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO2IO_MAX 1 +#define TFA98XX_TDM_CONFIG_REG3_TDMSO2IO_MSK 0x4 + +#define TFA98XX_TDM_CONFIG_REG3_TDMSI0SL (0xf<<3) +#define TFA98XX_TDM_CONFIG_REG3_TDMSI0SL_POS 3 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI0SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI0SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI0SL_MSK 0x78 + +#define TFA98XX_TDM_CONFIG_REG3_TDMSI1SL (0xf<<7) +#define TFA98XX_TDM_CONFIG_REG3_TDMSI1SL_POS 7 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI1SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI1SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI1SL_MSK 0x780 + +#define TFA98XX_TDM_CONFIG_REG3_TDMSI2SL (0xf<<11) +#define TFA98XX_TDM_CONFIG_REG3_TDMSI2SL_POS 11 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI2SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI2SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG3_TDMSI2SL_MSK 0x7800 + +/** tdm_config_reg4 Register ($14) ******************************************/ + +#define TFA98XX_TDM_CONFIG_REG4 0x14 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO0SL (0xf<<0) +#define TFA98XX_TDM_CONFIG_REG4_TDMSO0SL_POS 0 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO0SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO0SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO0SL_MSK 0xf + +#define TFA98XX_TDM_CONFIG_REG4_TDMSO1SL (0xf<<4) +#define TFA98XX_TDM_CONFIG_REG4_TDMSO1SL_POS 4 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO1SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO1SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO1SL_MSK 0xf0 + +#define TFA98XX_TDM_CONFIG_REG4_TDMSO2SL (0xf<<8) +#define TFA98XX_TDM_CONFIG_REG4_TDMSO2SL_POS 8 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO2SL_LEN 4 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO2SL_MAX 15 +#define TFA98XX_TDM_CONFIG_REG4_TDMSO2SL_MSK 0xf00 + +#define TFA98XX_TDM_CONFIG_REG4_NBCK (0xf<<12) +#define TFA98XX_TDM_CONFIG_REG4_NBCK_POS 12 +#define TFA98XX_TDM_CONFIG_REG4_NBCK_LEN 4 +#define TFA98XX_TDM_CONFIG_REG4_NBCK_MAX 15 +#define TFA98XX_TDM_CONFIG_REG4_NBCK_MSK 0xf000 + +/** interrupt_out_reg1 Register ($20) ***************************************/ + +#define TFA98XX_INTERRUPT_OUT_REG1 0x20 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOVDDS (0x1<<0) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOVDDS_POS 0 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOVDDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOVDDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOVDDS_MSK 0x1 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOPLLS (0x1<<1) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOPLLS_POS 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOPLLS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOPLLS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOPLLS_MSK 0x2 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOTDS (0x1<<2) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOTDS_POS 2 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOTDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOTDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOTDS_MSK 0x4 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOVDS (0x1<<3) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOVDS_POS 3 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOVDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOVDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOVDS_MSK 0x8 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOUVDS (0x1<<4) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOUVDS_POS 4 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOUVDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOUVDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOUVDS_MSK 0x10 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOCDS (0x1<<5) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOCDS_POS 5 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOCDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOCDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOOCDS_MSK 0x20 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLKS (0x1<<6) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLKS_POS 6 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLKS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLKS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLKS_MSK 0x40 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLIPS (0x1<<7) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLIPS_POS 7 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLIPS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLIPS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOCLIPS_MSK 0x80 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOMTPB (0x1<<8) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOMTPB_POS 8 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOMTPB_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOMTPB_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOMTPB_MSK 0x100 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTONOCLK (0x1<<9) +#define TFA98XX_INTERRUPT_OUT_REG1_INTONOCLK_POS 9 +#define TFA98XX_INTERRUPT_OUT_REG1_INTONOCLK_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTONOCLK_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTONOCLK_MSK 0x200 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSPKS (0x1<<10) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSPKS_POS 10 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSPKS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSPKS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSPKS_MSK 0x400 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOACS (0x1<<11) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOACS_POS 11 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOACS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOACS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOACS_MSK 0x800 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSWS (0x1<<12) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSWS_POS 12 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSWS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSWS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOSWS_MSK 0x1000 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOWDS (0x1<<13) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOWDS_POS 13 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOWDS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOWDS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOWDS_MSK 0x2000 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAMPS (0x1<<14) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAMPS_POS 14 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAMPS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAMPS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAMPS_MSK 0x4000 + +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAREFS (0x1<<15) +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAREFS_POS 15 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAREFS_LEN 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAREFS_MAX 1 +#define TFA98XX_INTERRUPT_OUT_REG1_INTOAREFS_MSK 0x8000 + +/** interrupt_out_reg3 Register ($22) ***************************************/ + +#define TFA98XX_INTERRUPT_OUT_REG3 0x22 +#define TFA98XX_INTERRUPT_OUT_REG3_INTOACK (0x3<<0) +#define TFA98XX_INTERRUPT_OUT_REG3_INTOACK_POS 0 +#define TFA98XX_INTERRUPT_OUT_REG3_INTOACK_LEN 2 +#define TFA98XX_INTERRUPT_OUT_REG3_INTOACK_MAX 3 +#define TFA98XX_INTERRUPT_OUT_REG3_INTOACK_MSK 0x3 + +/** interrupt_in_reg1 Register ($23) ****************************************/ + +#define TFA98XX_INTERRUPT_IN_REG1 0x23 +#define TFA98XX_INTERRUPT_IN_REG1_INTIVDDS (0x1<<0) +#define TFA98XX_INTERRUPT_IN_REG1_INTIVDDS_POS 0 +#define TFA98XX_INTERRUPT_IN_REG1_INTIVDDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIVDDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIVDDS_MSK 0x1 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIPLLS (0x1<<1) +#define TFA98XX_INTERRUPT_IN_REG1_INTIPLLS_POS 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIPLLS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIPLLS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIPLLS_MSK 0x2 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIOTDS (0x1<<2) +#define TFA98XX_INTERRUPT_IN_REG1_INTIOTDS_POS 2 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOTDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOTDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOTDS_MSK 0x4 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIOVDS (0x1<<3) +#define TFA98XX_INTERRUPT_IN_REG1_INTIOVDS_POS 3 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOVDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOVDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOVDS_MSK 0x8 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIUVDS (0x1<<4) +#define TFA98XX_INTERRUPT_IN_REG1_INTIUVDS_POS 4 +#define TFA98XX_INTERRUPT_IN_REG1_INTIUVDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIUVDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIUVDS_MSK 0x10 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIOCDS (0x1<<5) +#define TFA98XX_INTERRUPT_IN_REG1_INTIOCDS_POS 5 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOCDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOCDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIOCDS_MSK 0x20 + +#define TFA98XX_INTERRUPT_IN_REG1_INTICLKS (0x1<<6) +#define TFA98XX_INTERRUPT_IN_REG1_INTICLKS_POS 6 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLKS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLKS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLKS_MSK 0x40 + +#define TFA98XX_INTERRUPT_IN_REG1_INTICLIPS (0x1<<7) +#define TFA98XX_INTERRUPT_IN_REG1_INTICLIPS_POS 7 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLIPS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLIPS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTICLIPS_MSK 0x80 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIMTPB (0x1<<8) +#define TFA98XX_INTERRUPT_IN_REG1_INTIMTPB_POS 8 +#define TFA98XX_INTERRUPT_IN_REG1_INTIMTPB_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIMTPB_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIMTPB_MSK 0x100 + +#define TFA98XX_INTERRUPT_IN_REG1_INTINOCLK (0x1<<9) +#define TFA98XX_INTERRUPT_IN_REG1_INTINOCLK_POS 9 +#define TFA98XX_INTERRUPT_IN_REG1_INTINOCLK_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTINOCLK_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTINOCLK_MSK 0x200 + +#define TFA98XX_INTERRUPT_IN_REG1_INTISPKS (0x1<<10) +#define TFA98XX_INTERRUPT_IN_REG1_INTISPKS_POS 10 +#define TFA98XX_INTERRUPT_IN_REG1_INTISPKS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTISPKS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTISPKS_MSK 0x400 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIACS (0x1<<11) +#define TFA98XX_INTERRUPT_IN_REG1_INTIACS_POS 11 +#define TFA98XX_INTERRUPT_IN_REG1_INTIACS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIACS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIACS_MSK 0x800 + +#define TFA98XX_INTERRUPT_IN_REG1_INTISWS (0x1<<12) +#define TFA98XX_INTERRUPT_IN_REG1_INTISWS_POS 12 +#define TFA98XX_INTERRUPT_IN_REG1_INTISWS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTISWS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTISWS_MSK 0x1000 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIWDS (0x1<<13) +#define TFA98XX_INTERRUPT_IN_REG1_INTIWDS_POS 13 +#define TFA98XX_INTERRUPT_IN_REG1_INTIWDS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIWDS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIWDS_MSK 0x2000 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIAMPS (0x1<<14) +#define TFA98XX_INTERRUPT_IN_REG1_INTIAMPS_POS 14 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAMPS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAMPS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAMPS_MSK 0x4000 + +#define TFA98XX_INTERRUPT_IN_REG1_INTIAREFS (0x1<<15) +#define TFA98XX_INTERRUPT_IN_REG1_INTIAREFS_POS 15 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAREFS_LEN 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAREFS_MAX 1 +#define TFA98XX_INTERRUPT_IN_REG1_INTIAREFS_MSK 0x8000 + +/** interrupt_in_reg3 Register ($25) ****************************************/ + +#define TFA98XX_INTERRUPT_IN_REG3 0x25 +#define TFA98XX_INTERRUPT_IN_REG3_INTIACK (0x3<<0) +#define TFA98XX_INTERRUPT_IN_REG3_INTIACK_POS 0 +#define TFA98XX_INTERRUPT_IN_REG3_INTIACK_LEN 2 +#define TFA98XX_INTERRUPT_IN_REG3_INTIACK_MAX 3 +#define TFA98XX_INTERRUPT_IN_REG3_INTIACK_MSK 0x3 + +/** interrupt_enable_reg1 Register ($26) ************************************/ + +#define TFA98XX_INTERRUPT_ENABLE_REG1 0x26 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENVDDS (0x1<<0) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENVDDS_POS 0 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENVDDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENVDDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENVDDS_MSK 0x1 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENPLLS (0x1<<1) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENPLLS_POS 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENPLLS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENPLLS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENPLLS_MSK 0x2 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOTDS (0x1<<2) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOTDS_POS 2 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOTDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOTDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOTDS_MSK 0x4 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOVDS (0x1<<3) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOVDS_POS 3 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOVDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOVDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOVDS_MSK 0x8 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENUVDS (0x1<<4) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENUVDS_POS 4 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENUVDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENUVDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENUVDS_MSK 0x10 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOCDS (0x1<<5) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOCDS_POS 5 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOCDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOCDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENOCDS_MSK 0x20 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLKS (0x1<<6) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLKS_POS 6 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLKS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLKS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLKS_MSK 0x40 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLIPS (0x1<<7) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLIPS_POS 7 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLIPS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLIPS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENCLIPS_MSK 0x80 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENMTPB (0x1<<8) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENMTPB_POS 8 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENMTPB_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENMTPB_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENMTPB_MSK 0x100 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENNOCLK (0x1<<9) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENNOCLK_POS 9 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENNOCLK_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENNOCLK_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENNOCLK_MSK 0x200 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSPKS (0x1<<10) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSPKS_POS 10 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSPKS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSPKS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSPKS_MSK 0x400 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENACS (0x1<<11) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENACS_POS 11 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENACS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENACS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENACS_MSK 0x800 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSWS (0x1<<12) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSWS_POS 12 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSWS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSWS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENSWS_MSK 0x1000 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENWDS (0x1<<13) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENWDS_POS 13 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENWDS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENWDS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENWDS_MSK 0x2000 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAMPS (0x1<<14) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAMPS_POS 14 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAMPS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAMPS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAMPS_MSK 0x4000 + +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAREFS (0x1<<15) +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAREFS_POS 15 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAREFS_LEN 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAREFS_MAX 1 +#define TFA98XX_INTERRUPT_ENABLE_REG1_INTENAREFS_MSK 0x8000 + +/** interrupt_enable_reg3 Register ($28) ************************************/ + +#define TFA98XX_INTERRUPT_ENABLE_REG3 0x28 +#define TFA98XX_INTERRUPT_ENABLE_REG3_INTENACK (0x3<<0) +#define TFA98XX_INTERRUPT_ENABLE_REG3_INTENACK_POS 0 +#define TFA98XX_INTERRUPT_ENABLE_REG3_INTENACK_LEN 2 +#define TFA98XX_INTERRUPT_ENABLE_REG3_INTENACK_MAX 3 +#define TFA98XX_INTERRUPT_ENABLE_REG3_INTENACK_MSK 0x3 + +/** status_polarity_reg1 Register ($29) *************************************/ + +#define TFA98XX_STATUS_POLARITY_REG1 0x29 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLVDDS (0x1<<0) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLVDDS_POS 0 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLVDDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLVDDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLVDDS_MSK 0x1 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLPLLS (0x1<<1) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLPLLS_POS 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLPLLS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLPLLS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLPLLS_MSK 0x2 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOTDS (0x1<<2) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOTDS_POS 2 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOTDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOTDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOTDS_MSK 0x4 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOVDS (0x1<<3) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOVDS_POS 3 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOVDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOVDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOVDS_MSK 0x8 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLUVDS (0x1<<4) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLUVDS_POS 4 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLUVDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLUVDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLUVDS_MSK 0x10 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOCDS (0x1<<5) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOCDS_POS 5 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOCDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOCDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLOCDS_MSK 0x20 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLKS (0x1<<6) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLKS_POS 6 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLKS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLKS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLKS_MSK 0x40 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLIPS (0x1<<7) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLIPS_POS 7 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLIPS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLIPS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLCLIPS_MSK 0x80 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLMTPB (0x1<<8) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLMTPB_POS 8 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLMTPB_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLMTPB_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLMTPB_MSK 0x100 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLNOCLK (0x1<<9) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLNOCLK_POS 9 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLNOCLK_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLNOCLK_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLNOCLK_MSK 0x200 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSPKS (0x1<<10) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSPKS_POS 10 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSPKS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSPKS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSPKS_MSK 0x400 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLACS (0x1<<11) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLACS_POS 11 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLACS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLACS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLACS_MSK 0x800 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSWS (0x1<<12) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSWS_POS 12 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSWS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSWS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLSWS_MSK 0x1000 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLWDS (0x1<<13) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLWDS_POS 13 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLWDS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLWDS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLWDS_MSK 0x2000 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAMPS (0x1<<14) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAMPS_POS 14 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAMPS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAMPS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAMPS_MSK 0x4000 + +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAREFS (0x1<<15) +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAREFS_POS 15 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAREFS_LEN 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAREFS_MAX 1 +#define TFA98XX_STATUS_POLARITY_REG1_INTPOLAREFS_MSK 0x8000 + +/** status_polarity_reg3 Register ($2b) *************************************/ + +#define TFA98XX_STATUS_POLARITY_REG3 0x2b +#define TFA98XX_STATUS_POLARITY_REG3_INTPOLACK (0x3<<0) +#define TFA98XX_STATUS_POLARITY_REG3_INTPOLACK_POS 0 +#define TFA98XX_STATUS_POLARITY_REG3_INTPOLACK_LEN 2 +#define TFA98XX_STATUS_POLARITY_REG3_INTPOLACK_MAX 3 +#define TFA98XX_STATUS_POLARITY_REG3_INTPOLACK_MSK 0x3 + +/** pwm_mute_set Register ($41) *********************************************/ + +#define TFA98XX_PWM_MUTE_SET 0x41 +#define TFA98XX_PWM_MUTE_SET_PWMDEL (0x1f<<3) +#define TFA98XX_PWM_MUTE_SET_PWMDEL_POS 3 +#define TFA98XX_PWM_MUTE_SET_PWMDEL_LEN 5 +#define TFA98XX_PWM_MUTE_SET_PWMDEL_MAX 31 +#define TFA98XX_PWM_MUTE_SET_PWMDEL_MSK 0xf8 + +#define TFA98XX_PWM_MUTE_SET_PWMSH (0x1<<8) +#define TFA98XX_PWM_MUTE_SET_PWMSH_POS 8 +#define TFA98XX_PWM_MUTE_SET_PWMSH_LEN 1 +#define TFA98XX_PWM_MUTE_SET_PWMSH_MAX 1 +#define TFA98XX_PWM_MUTE_SET_PWMSH_MSK 0x100 + +#define TFA98XX_PWM_MUTE_SET_PWMRE (0x1<<9) +#define TFA98XX_PWM_MUTE_SET_PWMRE_POS 9 +#define TFA98XX_PWM_MUTE_SET_PWMRE_LEN 1 +#define TFA98XX_PWM_MUTE_SET_PWMRE_MAX 1 +#define TFA98XX_PWM_MUTE_SET_PWMRE_MSK 0x200 + +/** currentsense3 Register ($48) ********************************************/ + +#define TFA98XX_CURRENTSENSE3 0x48 +#define TFA98XX_CURRENTSENSE3_TCC (0x3<<14) +#define TFA98XX_CURRENTSENSE3_TCC_POS 14 +#define TFA98XX_CURRENTSENSE3_TCC_LEN 2 +#define TFA98XX_CURRENTSENSE3_TCC_MAX 3 +#define TFA98XX_CURRENTSENSE3_TCC_MSK 0xc000 + +/** CurrentSense4 Register ($49) ********************************************/ + +#define TFA98XX_CURRENTSENSE4 0x49 +#define TFA98XX_CURRENTSENSE4_CLIP (0x1<<0) +#define TFA98XX_CURRENTSENSE4_CLIP_POS 0 +#define TFA98XX_CURRENTSENSE4_CLIP_LEN 1 +#define TFA98XX_CURRENTSENSE4_CLIP_MAX 1 +#define TFA98XX_CURRENTSENSE4_CLIP_MSK 0x1 + +#define TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF (0x1<<2) + +/** KEY1_Protected_mtp_ctrl_reg3 Register ($62) *****************************/ + +#define TFA98XX_KEY1_PROTECTED_MTP_CTRL_REG3 0x62 +/** cf_controls Register ($70) **********************************************/ + +#define TFA98XX_CF_CONTROLS 0x70 +#define TFA98XX_CF_CONTROLS_RST (0x1<<0) +#define TFA98XX_CF_CONTROLS_RST_POS 0 +#define TFA98XX_CF_CONTROLS_RST_LEN 1 +#define TFA98XX_CF_CONTROLS_RST_MAX 1 +#define TFA98XX_CF_CONTROLS_RST_MSK 0x1 + +#define TFA98XX_CF_CONTROLS_DMEM (0x3<<1) +#define TFA98XX_CF_CONTROLS_DMEM_POS 1 +#define TFA98XX_CF_CONTROLS_DMEM_LEN 2 +#define TFA98XX_CF_CONTROLS_DMEM_MAX 3 +#define TFA98XX_CF_CONTROLS_DMEM_MSK 0x6 + +#define TFA98XX_CF_CONTROLS_AIF (0x1<<3) +#define TFA98XX_CF_CONTROLS_AIF_POS 3 +#define TFA98XX_CF_CONTROLS_AIF_LEN 1 +#define TFA98XX_CF_CONTROLS_AIF_MAX 1 +#define TFA98XX_CF_CONTROLS_AIF_MSK 0x8 + +#define TFA98XX_CF_CONTROLS_CFINT (0x1<<4) +#define TFA98XX_CF_CONTROLS_CFINT_POS 4 +#define TFA98XX_CF_CONTROLS_CFINT_LEN 1 +#define TFA98XX_CF_CONTROLS_CFINT_MAX 1 +#define TFA98XX_CF_CONTROLS_CFINT_MSK 0x10 + +#define TFA98XX_CF_CONTROLS_REQ (0xff<<8) +#define TFA98XX_CF_CONTROLS_REQ_POS 8 +#define TFA98XX_CF_CONTROLS_REQ_LEN 8 +#define TFA98XX_CF_CONTROLS_REQ_MAX 255 +#define TFA98XX_CF_CONTROLS_REQ_MSK 0xff00 + +/** cf_mad Register ($71) ***************************************************/ + +#define TFA98XX_CF_MAD 0x71 +#define TFA98XX_CF_MAD_MADD (0xffff<<0) +#define TFA98XX_CF_MAD_MADD_POS 0 +#define TFA98XX_CF_MAD_MADD_LEN 16 +#define TFA98XX_CF_MAD_MADD_MAX 65535 +#define TFA98XX_CF_MAD_MADD_MSK 0xffff + +/** cf_mem Register ($72) ***************************************************/ + +#define TFA98XX_CF_MEM 0x72 +#define TFA98XX_CF_MEM_MEMA (0xffff<<0) +#define TFA98XX_CF_MEM_MEMA_POS 0 +#define TFA98XX_CF_MEM_MEMA_LEN 16 +#define TFA98XX_CF_MEM_MEMA_MAX 65535 +#define TFA98XX_CF_MEM_MEMA_MSK 0xffff + +/** cf_status Register ($73) ************************************************/ + +#define TFA98XX_CF_STATUS 0x73 +#define TFA98XX_CF_STATUS_ERR (0xff<<0) +#define TFA98XX_CF_STATUS_ERR_POS 0 +#define TFA98XX_CF_STATUS_ERR_LEN 8 +#define TFA98XX_CF_STATUS_ERR_MAX 255 +#define TFA98XX_CF_STATUS_ERR_MSK 0xff + +#define TFA98XX_CF_STATUS_ACK (0xff<<8) +#define TFA98XX_CF_STATUS_ACK_POS 8 +#define TFA98XX_CF_STATUS_ACK_LEN 8 +#define TFA98XX_CF_STATUS_ACK_MAX 255 +#define TFA98XX_CF_STATUS_ACK_MSK 0xff00 + +/** Key2_Protected_spkr_cal_mtp Register ($80) ******************************/ + +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP 0x80 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC (0x1<<0) +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC_POS 0 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC_LEN 1 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC_MAX 1 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC_MSK 0x1 + +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX (0x1<<1) +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX_POS 1 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX_LEN 1 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX_MAX 1 +#define TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX_MSK 0x2 + +/** MTPF Register ($8f) *****************************************************/ + +#define TFA98XX_MTPF 0x8f +#define TFA98XX_MTPF_VERSION (0xffff<<0) +#define TFA98XX_MTPF_VERSION_POS 0 +#define TFA98XX_MTPF_VERSION_LEN 16 +#define TFA98XX_MTPF_VERSION_MAX 65535 +#define TFA98XX_MTPF_VERSION_MSK 0xffff + +#define TFA98XX_MAX_REGISTER 0x8f + + +/* some shorthands for readability */ +#define TFA98XX_MTP TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP +#define TFA98XX_MTP_COPY TFA98XX_MTP_CTRL_REG3 +/* MTP bits */ +/* one time calibration */ +#define TFA98XX_MTP_MTPOTC TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC +/* one time calibration done */ +#define TFA98XX_MTP_MTPEX TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX +/* sample rates */ +/* I2S_CONTROL bits */ +#define TFA98XX_I2SCTRL_RATE_08000 (0<fw.name + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tfa98xx-core.h" +#include "tfa98xx-regs.h" +#include "tfa_container.h" +#include "tfa_dsp.h" + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, repair when MTP 0 fail*/ +extern int recoverMtp0; +#endif + +static int test =0; + +#define I2C_RETRY_DELAY 5 /* ms */ +#define I2C_RETRIES 5 +#define PLL_SYNC_RETRIES 10 +#define MTPB_RETRIES 5 + + +/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ +#define TFA98XX_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) +#define TFA98XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) + +#define TFA98XX_STATUS_UP_MASK (TFA98XX_STATUSREG_PLLS | \ + TFA98XX_STATUSREG_CLKS | \ + TFA98XX_STATUSREG_VDDS | \ + TFA98XX_STATUSREG_AREFS) + + + +struct tfa98xx *g_tfa98xx = NULL; +EXPORT_SYMBOL_GPL(g_tfa98xx); + + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-05-29, add for smart pa calibtation*/ +static ssize_t tfa98xx_state_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + pr_err("%s",__func__); + + return 0; +} +static ssize_t tfa98xx_state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct snd_soc_codec *codec; + struct tfa98xx *tfa98xx; + unsigned short mtp; + unsigned short status; + int done = 0; + u32 re25 = 0; + int try = 0; + u16 mtp0; + + if(g_tfa98xx == NULL) + { + pr_err("%s g_tfa98xx = NULL\n",__func__); + return 0; + } + + tfa98xx = g_tfa98xx; + codec = tfa98xx->codec; + + mutex_lock(&tfa98xx->dsp_init_lock); + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, Modify for MTP recovery*/ + /* + * check the contents of MTP register for non-zero, + * this indicates that the subsys is ready + */ + mtp0 = (u16)snd_soc_read(codec, 0x84); + + /* NXP: if 0x84 is wrong, restore the correct mtp settings */ + if (!mtp0 || recoverMtp0) + { + pr_err("%s mtp0 error,now recovery mtp.\n",__func__); + if(recoverMtp0) + { + pr_err("%s mtp0 error detect in cold start up.\n",__func__); + recoverMtp0 = false; + } + tfa98xx_restore_mtp(tfa98xx); + } +#endif + + if (!tfa98xx_is_pwdn(tfa98xx)) { + tfa98xx_dsp_stop(tfa98xx); + } + tfaRunColdStartup(tfa98xx); + msleep(5); + + mtp = snd_soc_read(codec, TFA98XX_MTP); + /* reset MTPEX bit if needed */ + if ( (mtp & TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPOTC) && (mtp & TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX)) + { + snd_soc_write(codec, 0x0B, 0x5A); /* unlock key2 */ + snd_soc_write(codec, TFA98XX_MTP, 1); /* MTPOTC=1, MTPEX=0 */ + snd_soc_write(codec, 0x62, 1<<11); /* CIMTP=1 */ + } + + do { + try ++; + msleep(10); + status = snd_soc_read(codec, TFA98XX_STATUSREG); + } while (((status & TFA98XX_STATUSREG_MTPB) == TFA98XX_STATUSREG_MTPB) && (try < 100)); + + if(try == 100) + { + pr_err("%s try read TFA98XX_STATUSREG_MTPB time out\n",__func__); + goto err; + } + + if (!tfa98xx_is_pwdn(tfa98xx)) { + tfa98xx_dsp_stop(tfa98xx); + } + msleep(10); + tfa98xx->dsp_init = TFA98XX_DSP_INIT_RECOVER; + /* start the DSP using the latest profile / vstep */ + if (!tfa98xx_dsp_start(tfa98xx, tfa98xx->profile, tfa98xx->vstep)) + tfa98xx->dsp_init = TFA98XX_DSP_INIT_DONE; + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, Modify for MTP recovery*/ + /* + * check the contents of MTP register for non-zero, + * this indicates that the subsys is ready + */ + mtp0 = (u16)snd_soc_read(codec, 0x84); + + /* NXP: if 0x84 is wrong, restore the correct mtp settings */ + if (!mtp0 ) + { + pr_err("%s mtp0 error,now recovery mtp.\n",__func__); + tfa98xx_restore_mtp(tfa98xx); + } +#endif + + mtp = snd_soc_read(codec, TFA98XX_MTP); + done = (mtp & TFA98XX_MTP_MTPEX); + tfa98xx_dsp_get_calibration_impedance(tfa98xx, &re25); + + pr_debug("%s done =%d re=%d\n",__func__,done,re25); + mutex_unlock(&tfa98xx->dsp_init_lock); + return sprintf(buf,"%d:%d",done,re25); + +err: + pr_err("%s calibrate fail\n",__func__); + mutex_unlock(&tfa98xx->dsp_init_lock); + return sprintf(buf,"%d:%d",0,0); + +} + + + +static struct device_attribute tfa98xx_state_attr = + __ATTR(calibra, 0444, tfa98xx_state_show, tfa98xx_state_store); + +#endif + + +/* + * I2C Read/Write Functions + */ + +int tfa98xx_i2c_read(struct i2c_client *tfa98xx_client, u8 reg, u8 *value, + int len) +{ + int err; + int tries = 0; + + struct i2c_msg msgs[] = { + { + .addr = tfa98xx_client->addr, + .flags = 0, + .len = 1, + .buf = ®, + }, + { + .addr = tfa98xx_client->addr, + .flags = I2C_M_RD, + .len = len, + .buf = value, + }, + }; + + do { + err = i2c_transfer(tfa98xx_client->adapter, msgs, + ARRAY_SIZE(msgs)); + if (err != ARRAY_SIZE(msgs)) + msleep_interruptible(I2C_RETRY_DELAY); + } while ((err != ARRAY_SIZE(msgs)) && (++tries < I2C_RETRIES)); + + if (err != ARRAY_SIZE(msgs)) { + dev_err(&tfa98xx_client->dev, "read transfer error %d\n" , err); + err = -EIO; + } else { + err = 0; + } + + return err; +} + +int tfa98xx_bulk_write_raw(struct snd_soc_codec *codec, const u8 *data, u8 count) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = i2c_master_send(tfa98xx->i2c, data, count); + if (ret == count) { + return 0; + } else if (ret < 0) { + pr_err("Error I2C send %d\n", ret); + return ret; + } else { + pr_err("Error I2C send size mismatch %d\n", ret); + return -EIO; + } +} + + +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-24,remove monitor,it will cause system crash because of mutex lock*/ +static void tfa98xx_monitor(struct work_struct *work) +{ + + struct tfa98xx *tfa98xx = container_of(work, struct tfa98xx, delay_work.work); + u16 val; + + mutex_lock(&tfa98xx->dsp_init_lock); + + /* + * check IC status bits: cold start, amp switching, speaker error + * and DSP watch dog bit to re init + */ + val = snd_soc_read(tfa98xx->codec, TFA98XX_STATUSREG); + pr_debug("monitor SYS_STATUS: 0x%04x\n", val); +#ifndef VENDOR_EDIT + /* zhiguang.su@MultiMedia.AudioDrv on 2015-04-21, fix bug for sound break off*/ + if ((TFA98XX_STATUSREG_ACS & val) || + (TFA98XX_STATUSREG_WDS & val) || + (TFA98XX_STATUSREG_SPKS & val) || + !(TFA98XX_STATUSREG_SWS & val)) +#else +/* zhiguang.su@MultiMedia.AudioDrv on 2015-08-13, changed by NXP suggestion.*/ + /* NXP: There's no need to recover in case of SPKS and SWS */ + if (TFA98XX_STATUSREG_SPKS & val) + pr_err("ERROR: SPKS\n"); + + if (!(TFA98XX_STATUSREG_SWS & val)) + pr_err("ERROR: AMP_SWS\n"); + + if ((TFA98XX_STATUSREG_ACS & val) || + (TFA98XX_STATUSREG_WDS & val) ) + +#endif + { + tfa98xx->dsp_init = TFA98XX_DSP_INIT_RECOVER; + + if (TFA98XX_STATUSREG_ACS & val) + pr_err("ERROR: ACS\n"); + if (TFA98XX_STATUSREG_WDS & val) + pr_err("ERROR: WDS\n"); + +#ifndef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-08-13, changed by NXP suggestion.*/ + if (TFA98XX_STATUSREG_SPKS & val) + pr_err("ERROR: SPKS\n"); + if (!(TFA98XX_STATUSREG_SWS & val)) + pr_err("ERROR: AMP_SWS\n"); +#endif + + /* schedule init now if the clocks are up and stable */ + if ((val & TFA98XX_STATUS_UP_MASK) == TFA98XX_STATUS_UP_MASK) + queue_work(tfa98xx->tfa98xx_wq, &tfa98xx->init_work); + } + + /* else just reschedule */ + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->delay_work, 5*HZ); + mutex_unlock(&tfa98xx->dsp_init_lock); + +} +#endif + +static void tfa98xx_dsp_init(struct work_struct *work) +{ + struct tfa98xx *tfa98xx = container_of(work, struct tfa98xx, init_work); + + mutex_lock(&tfa98xx->dsp_init_lock); + /* start the DSP using the latest profile / vstep */ + if (!tfa98xx_dsp_start(tfa98xx, tfa98xx->profile, tfa98xx->vstep)) + tfa98xx->dsp_init = TFA98XX_DSP_INIT_DONE; + mutex_unlock(&tfa98xx->dsp_init_lock); +} + +/* + * ASOC OPS +*/ + +/* +static u32 tfa98xx_asrc_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 +}; + +static struct snd_pcm_hw_constraint_list constraints_12_24 = { + .list = tfa98xx_asrc_rates, + .count = ARRAY_SIZE(tfa98xx_asrc_rates), +}; +*/ +static int tfa98xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct tfa98xx *tfa98xx = + snd_soc_codec_get_drvdata(codec_dai->codec); + + tfa98xx->sysclk = freq; + return 0; +} + +static int tfa98xx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + //struct tfa98xx *tfa98xx = + // snd_soc_codec_get_drvdata(codec_dai->codec); + u16 val; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* default value */ + break; + case SND_SOC_DAIFMT_CBM_CFM: + default: + /* only supports Slave mode */ + pr_err("tfa98xx: invalid DAI master/slave interface\n"); + return -EINVAL; + } + val = snd_soc_read(codec, TFA98XX_AUDIOREG); + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + /* default value */ + break; + case SND_SOC_DAIFMT_RIGHT_J: + val &= ~(TFA98XX_FORMAT_MASK); + val |= TFA98XX_FORMAT_LSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + val &= ~(TFA98XX_FORMAT_MASK); + val |= TFA98XX_FORMAT_MSB; + break; + default: + pr_err("tfa98xx: invalid DAI interface format\n"); + return -EINVAL; + } + + snd_soc_write(codec, TFA98XX_AUDIOREG, val); + + return 0; +} + +static int tfa98xx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + /* Store rate for further use during DSP init */ + tfa98xx->rate = params_rate(params); + + return 0; +} + +static int tfa98xx_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + pr_debug("state: %d\n", mute); + + mutex_lock(&tfa98xx->dsp_init_lock); + + if (mute) { +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-24,remove monitor,it will cause system crash because of mutex lock*/ + cancel_delayed_work_sync(&tfa98xx->delay_work); +#endif + + /* + * need to wait for amp to stop switching, to minimize + * pop, else I2S clk is going away too soon interrupting + * the dsp from smothering the amp pop while turning it + * off, It shouldn't take more than 50 ms for the amp + * switching to stop. + */ + if (!tfa98xx_is_pwdn(tfa98xx)) { + tfa98xx_dsp_stop(tfa98xx); + } + } else { + /* + * start monitor thread to check IC status bit 5secs, and + * re-init IC to recover. + */ + tfa98xx_dsp_quickstart(tfa98xx, tfa98xx->profile, tfa98xx->vstep); + test = 1; +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-24,remove monitor,it will cause system crash because of mutex lock*/ + queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->delay_work, 5*HZ); +#endif + } + + mutex_unlock(&tfa98xx->dsp_init_lock); + + return 0; +} + +static int tfa98xx_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + +#if 0 +if(substream->runtime == NULL) + pr_debug("%s error,substream->runtime = NULL\n",__func__); + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_12_24); +#endif + + return 0; +} + +static void tfa98xx_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + //struct snd_soc_codec *codec = dai->codec; + //struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + +} + +/* Trigger callback is atomic function, It gets called when pcm is started */ + +static int tfa98xx_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(dai->codec); + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* + * To initialize dsp all the I2S clocks must be up and running. + * so that the DSP's internal PLL can sync up and memory becomes + * accessible. Trigger callback is called when pcm write starts, + * so this should be the place where DSP is initialized + */ + if(test) + { + test = 0; + } + else + { + queue_work(tfa98xx->tfa98xx_wq, &tfa98xx->init_work); + } + break; + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + default: + ret = -EINVAL; + } + + return ret; +} + +/* + * ASOC controls + */ + +static const struct snd_soc_dapm_widget tfa98xx_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("I2S1"), + SND_SOC_DAPM_MIXER("NXP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route tfa98xx_dapm_routes[] = { + {"NXP Output Mixer", NULL, "Playback"}, +}; + + +/* + * Helpers for profile selection controls + */ +int tfa98xx_get_profile_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_lock(&tfa98xx->dsp_init_lock); +#endif + ucontrol->value.integer.value[0] = tfa98xx->profile; +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_unlock(&tfa98xx->dsp_init_lock); +#endif + return 0; +} + +int tfa98xx_set_profile_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + struct tfaprofile *profiles = (struct tfaprofile *)kcontrol->private_value; + int index = tfa98xx->profile; + struct tfaprofile *prof = &profiles[index]; + + if (tfa98xx->profile == ucontrol->value.integer.value[0]) + return 0; + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_lock(&tfa98xx->dsp_init_lock); +#endif + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-11,change for wave profile */ + tfa98xx->profile = ucontrol->value.integer.value[0]; + if (tfa98xx_is_amp_running(tfa98xx)) { + tfaContWriteProfile(tfa98xx, tfa98xx->profile, prof->vstep); + } + pr_debug("%s WaveEnable %d profile %d",__func__,tfa98xx->WaveEnable,tfa98xx->profile); +#endif +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_unlock(&tfa98xx->dsp_init_lock); +#endif + return 0; +} + +int tfa98xx_info_profile_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 5;// tfa98xx->profile_count; + uinfo->value.integer.min = 0; + uinfo->value.integer.max =5 ;// tfa98xx->profile_count -1; + + return 0; +} + + +/* + * Helpers for volume through vstep controls + */ +int tfa98xx_get_vol_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfaprofile *profiles = (struct tfaprofile *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int index = tfa98xx->profile; + struct tfaprofile *prof = &profiles[index]; + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_lock(&tfa98xx->dsp_init_lock); +#endif + ucontrol->value.integer.value[0] = prof->vsteps - prof->vstep - 1; + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_unlock(&tfa98xx->dsp_init_lock); +#endif + return 0; +} + +int tfa98xx_set_vol_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tfaprofile *profiles = (struct tfaprofile *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int index = tfa98xx->profile; + struct tfaprofile *prof = &profiles[index]; + + if (prof->vstep == prof->vsteps - ucontrol->value.integer.value[0] - 1) + return 0; + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_lock(&tfa98xx->dsp_init_lock); +#endif + prof->vstep = prof->vsteps - ucontrol->value.integer.value[0] - 1; + + if (prof->vstep < 0) + prof->vstep = 0; + + if (tfa98xx_is_amp_running(tfa98xx)) { + tfaContWriteProfile(tfa98xx, tfa98xx->profile, prof->vstep); + } + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-06,add lock */ + mutex_unlock(&tfa98xx->dsp_init_lock); +#endif + return 1; +} + +int tfa98xx_info_vol_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct tfaprofile *profiles = (struct tfaprofile *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + struct tfaprofile *prof = &profiles[tfa98xx->profile]; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = prof->vsteps - 1; + + return 0; +} + +int tfa98xx_get_stop_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +int tfa98xx_set_stop_ctl(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + + if ((ucontrol->value.integer.value[0] != 0) && !tfa98xx_is_pwdn(tfa98xx)) { +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-24,remove monitor,it will cause system crash because of mutex lock*/ + cancel_delayed_work_sync(&tfa98xx->delay_work); +#endif + + tfa98xx_dsp_stop(tfa98xx); + } + + ucontrol->value.integer.value[0] = 0; + return 1; +} + +#define MAX_CONTROL_NAME 32 + +static char prof_name[MAX_CONTROL_NAME]; +static char vol_name[MAX_CONTROL_NAME]; +static char stop_name[MAX_CONTROL_NAME]; + + +static int tfa98xx_put_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + return 0; + +} + + +static int tfa98xx_get_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + return 0; +} + + +static struct snd_kcontrol_new tfa98xx_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = prof_name, + .info = tfa98xx_info_profile_ctl, + .get = tfa98xx_get_profile_ctl, + .put = tfa98xx_set_profile_ctl, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = vol_name, + .info = tfa98xx_info_vol_ctl, + .get = tfa98xx_get_vol_ctl, + .put = tfa98xx_set_vol_ctl, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = stop_name, + .info = snd_soc_info_bool_ext, + .get = tfa98xx_get_stop_ctl, + .put = tfa98xx_set_stop_ctl, + }, + SOC_SINGLE_EXT("TFA98xx SPKR Enable", 0, 0, 1, 0, + tfa98xx_get_control, tfa98xx_put_control), + SOC_SINGLE_EXT("Wave Enable", 0, 0, 1, 0, + tfa98xx_get_control, tfa98xx_put_control), + +}; + + +static const struct snd_soc_dai_ops tfa98xx_ops = { + .hw_params = tfa98xx_hw_params, + .digital_mute = tfa98xx_digital_mute, + .set_fmt = tfa98xx_set_dai_fmt, + .set_sysclk = tfa98xx_set_dai_sysclk, + .startup = tfa98xx_startup, + .shutdown = tfa98xx_shutdown, + .trigger = tfa98xx_trigger, +}; + + +static struct snd_soc_dai_driver tfa98xx_dai = { + .name = "tfa98xx_codec", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = TFA98XX_RATES, + .formats = TFA98XX_FORMATS,}, + .ops = &tfa98xx_ops, + .symmetric_rates = 1, +}; + +static int tfa98xx_probe(struct snd_soc_codec *codec) +{ + struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec); + int ret; + u16 rev; + + codec->control_data = tfa98xx->regmap; + tfa98xx->codec = codec; + codec->cache_bypass = true; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + rev = snd_soc_read(codec, TFA98XX_REVISIONNUMBER); + dev_info(codec->dev, "ID revision 0x%04x\n", rev); + tfa98xx->rev = rev & 0xff; + tfa98xx->subrev = (rev >> 8) & 0xff; + + snd_soc_dapm_new_controls(&codec->dapm, tfa98xx_dapm_widgets, + ARRAY_SIZE(tfa98xx_dapm_widgets)); + + snd_soc_dapm_add_routes(&codec->dapm, tfa98xx_dapm_routes, + ARRAY_SIZE(tfa98xx_dapm_routes)); + + snd_soc_dapm_new_widgets(&codec->dapm); + snd_soc_dapm_sync(&codec->dapm); + + ret = tfa98xx_cnt_loadfile(tfa98xx, 0); + if(ret) + return ret; + + tfa98xx->profile_current = -1; + /* Overwrite kcontrol values that need container information */ + tfa98xx_controls[0].private_value = (unsigned long)tfa98xx->profiles, + tfa98xx_controls[1].private_value = (unsigned long)tfa98xx->profiles, + scnprintf(prof_name, MAX_CONTROL_NAME, "%s Profile", tfa98xx->fw.name); + scnprintf(vol_name, MAX_CONTROL_NAME, "%s Master Volume", tfa98xx->fw.name); + scnprintf(stop_name, MAX_CONTROL_NAME, "%s Stop", tfa98xx->fw.name); + //scnprintf(speaker_enable, MAX_CONTROL_NAME, "%s Stop", tfa98xx->fw.name); + + snd_soc_add_codec_controls(codec, tfa98xx_controls, ARRAY_SIZE(tfa98xx_controls)); + + dev_info(codec->dev, "tfa98xx codec registered"); +#ifdef VENDOR_EDIT + //zhiguang.su add + g_tfa98xx = tfa98xx; + //zhiguang.su add end +#endif + return 0; +} + +static int tfa98xx_remove(struct snd_soc_codec *codec) +{ + dev_info(codec->dev, "tfa98xx codec removed"); + return 0; +} + +static struct snd_soc_codec_driver tfa98xx_soc_codec = { + .probe = tfa98xx_probe, + .remove = tfa98xx_remove, +}; + +static const struct regmap_config tfa98xx_regmap = { + .reg_bits = 8, + .val_bits = 16, + .max_register = TFA98XX_MAX_REGISTER, + .cache_type = REGCACHE_RBTREE, +}; + +static int tfa98xx_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tfa98xx *tfa98xx; + int ret; + struct device_node *np = i2c->dev.of_node; + int error = 0; + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { + dev_err(&i2c->dev, "check_functionality failed\n"); + return -EIO; + } + + tfa98xx = devm_kzalloc(&i2c->dev, sizeof(struct tfa98xx), + GFP_KERNEL); + if (tfa98xx == NULL) + return -ENOMEM; + + tfa98xx->i2c = i2c; + tfa98xx->dsp_init = TFA98XX_DSP_INIT_PENDING; + + tfa98xx->regmap = devm_regmap_init_i2c(i2c, &tfa98xx_regmap); + if (IS_ERR(tfa98xx->regmap)) { + ret = PTR_ERR(tfa98xx->regmap); + dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); + return ret; + } + + i2c_set_clientdata(i2c, tfa98xx); + mutex_init(&tfa98xx->dsp_init_lock); + + /* work queue will be used to load DSP fw on first audio playback */ + tfa98xx->tfa98xx_wq = create_singlethread_workqueue("tfa98xx"); + if (tfa98xx->tfa98xx_wq == NULL) { + ret = -ENOMEM; + goto wq_fail; + } + +#ifdef VENDOR_EDIT + //zhiguang.su add 1218 + tfa98xx->rst_gpio = of_get_named_gpio(np, "reset_gpio",0); + ret = gpio_request(tfa98xx->rst_gpio, "tfa reset gpio"); + if (ret < 0) + { + pr_err("%s: tfa reset gpio_request failed: %d\n",__func__, ret); + goto gpio_fail; + } + gpio_direction_output(tfa98xx->rst_gpio, 1); +/*zhiguang.su@MultiMedia.AudioDrv on 2015-05-18,optimize for speed */ + udelay(100); + gpio_direction_output(tfa98xx->rst_gpio, 0); + //zhiguang.su add end 1218 +#endif + + INIT_WORK(&tfa98xx->init_work, tfa98xx_dsp_init); + +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-24,remove monitor,it will cause system crash because of mutex lock*/ + INIT_DELAYED_WORK(&tfa98xx->delay_work, tfa98xx_monitor); +#endif + + /* register codec */ + ret = snd_soc_register_codec(&i2c->dev, &tfa98xx_soc_codec, + &tfa98xx_dai, 1); + if (ret < 0) { + pr_err("%s: Error registering tfa98xx codec", __func__); + goto codec_fail; + } + +#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv on 2015-05-18,optimize for speed */ + pr_debug("tfa98xx probed successfully!"); +#endif + + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-05-29, add for smart pa calibtation*/ + error = sysfs_create_file(&i2c->dev.kobj, &tfa98xx_state_attr.attr); + if(error < 0) + { + pr_err("%s sysfs_create_file err.",__func__); + } +#endif + return ret; + +codec_fail: + destroy_workqueue(tfa98xx->tfa98xx_wq); +gpio_fail: +wq_fail: + snd_soc_unregister_codec(&i2c->dev); + + return ret; +} + +static int tfa98xx_i2c_remove(struct i2c_client *client) +{ + struct tfa98xx *tfa98xx = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + destroy_workqueue(tfa98xx->tfa98xx_wq); + return 0; +} + +static const struct i2c_device_id tfa98xx_i2c_id[] = { + { "tfa98xx", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tfa98xx_i2c_id); + +#ifdef CONFIG_OF +static struct of_device_id tfa98xx_match_tbl[] = { + { .compatible = "nxp,tfa9890" }, + { }, +}; +MODULE_DEVICE_TABLE(of, tfa98xx_match_tbl); +#endif + +static struct i2c_driver tfa98xx_i2c_driver = { + .driver = { + .name = "tfa98xx", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tfa98xx_match_tbl), + }, + .probe = tfa98xx_i2c_probe, + .remove = tfa98xx_i2c_remove, + .id_table = tfa98xx_i2c_id, +}; + +module_i2c_driver(tfa98xx_i2c_driver); diff --git a/sound/soc/codecs/tfa9890/tfa_container.c b/sound/soc/codecs/tfa9890/tfa_container.c new file mode 100755 index 0000000000000..291d8ebced537 --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa_container.c @@ -0,0 +1,603 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +//#define DEBUG +//#define pr_fmt(fmt) "%s(%s): " fmt, __func__, tfa98xx->fw.name +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tfa98xx-core.h" +#include "tfa98xx-regs.h" +#include "tfa_container.h" +#include "tfa_dsp.h" + +int tfa_get_profile_count(struct nxpTfaDevice *dev) +{ + int i, hit = 0; + + if (!dev) + return 0; + + for (i = 0, hit = 0; i < dev->length; i++) + if (dev->list[i].type == dscProfile) + hit++; + + return hit; +} + + +struct nxpTfaVolumeStep2File *tfa_get_vsteps(struct tfa98xx *tfa98xx, struct nxpTfaProfile *prof) +{ + u8 *base = tfa98xx->fw.base; + int i; + + for(i = 0; i < prof->length; i++) { + if ( prof->list[i].type == dscFile ) { + struct nxpTfaFileDsc *file = (struct nxpTfaFileDsc *)(prof->list[i].offset + base); + struct nxpTfaHeader *hdr = (struct nxpTfaHeader *)file->data; + if (hdr->id == volstepHdr) { + struct nxpTfaVolumeStep2File *vp = (struct nxpTfaVolumeStep2File *)hdr; + return vp; + } + } + } + + return NULL; +} + + +int tfa_init_profile(struct tfa98xx *tfa98xx, struct nxpTfaProfile *prof, int hit) +{ + struct nxpTfaVolumeStep2File *vp; + u8 *base = tfa98xx->fw.base; + + vp = tfa_get_vsteps(tfa98xx, prof); + if (vp) { + tfa98xx->profiles[hit].vp = vp; + tfa98xx->profiles[hit].vsteps = vp->vsteps; + } + + tfa98xx->profiles[hit].profile = prof; + tfa98xx->profiles[hit].name = base + prof->name.offset; + tfa98xx->profiles[hit].index = hit; + + return 0; +} + +static char *filename = "tfa98xx.cnt"; +//static char *filename = "/etc/tfa98xx.cnt"; + + +module_param(filename, charp, 0); + +int tfa98xx_cnt_loadfile(struct tfa98xx *tfa98xx, int index) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 addr = tfa98xx->i2c->addr; + const struct firmware *container = NULL; + struct nxpTfaContainer *data; + int i, j, hit, ret; + u32 crc32; + u8 *base; + + + /* Load DSP config and firmware files */ + ret = request_firmware(&container, filename, codec->dev); + if (ret) { + pr_err("Failed to read %s", filename); + return ret; + } + + //pr_debug("loaded %s - size: %d\n", filename, container ? container->size : 0); + + data = (struct nxpTfaContainer *)container->data; + if (*(u16*)data->id != params) { + pr_err("Wrong container type %.2s", (char *)&data->id); + return -EINVAL; + } + + crc32 = ~crc32_le(~0, ((u8*)container->data)+14, container->size-14); + + if (crc32 != data->CRC) { + pr_err("fw checksum test failed %x\n", crc32); + return -ENOEXEC; + } + + base = (u8 *) data; + tfa98xx->fw.base = data; + for (i = 0; i < data->ndev; i++) { + struct nxpTfaDevice *dev; + struct nxpTfaProfile *prof; + struct nxpTfaFileDsc *dsc; + + base = (u8*)data + data->index[i].offset; + dev = (struct nxpTfaDevice *)base; + + /* Check if this is the proper device addr */ + if (dev->dev != addr) + continue; + + tfa98xx->fw.dev = (struct nxpTfaDevice *)base; + tfa98xx->fw.name = (u8 *)data + dev->name.offset; + tfa98xx->profile_count = tfa_get_profile_count(tfa98xx->fw.dev); + + tfa98xx->profiles = devm_kzalloc(tfa98xx->codec->dev, tfa98xx->profile_count * sizeof(struct tfaprofile), GFP_KERNEL); + if (!tfa98xx->profiles) + return -ENOMEM; + + for (j = 0, hit = 0; j < dev->length; j++) { + switch (dev->list[j].type) { + case dscProfile: + prof = (struct nxpTfaProfile *)((u8 *)data + dev->list[j].offset); + tfa_init_profile(tfa98xx, prof, hit++); + break; + case dscFile: + case dscPatch: + dsc = (struct nxpTfaFileDsc *)((u8 *)data + dev->list[j].offset); + break; + default: + break; + } + } + } + + if (!tfa98xx->profiles) { + pr_err("[0x%02x] No profile data for the device\n", addr); + } + + return 0; +} + +int tfa_get_vstep_count(struct tfa98xx *tfa98xx, struct nxpTfaProfile *prof) +{ + u8 *base = tfa98xx->fw.base; + int i; + + for(i = 0; i < prof->length; i++) { + if ( prof->list[i].type == dscFile ) { + struct nxpTfaFileDsc *file = (struct nxpTfaFileDsc *)(prof->list[i].offset + base); + struct nxpTfaHeader *hdr = (struct nxpTfaHeader *)file->data; + if (hdr->id == volstepHdr) { + struct nxpTfaVolumeStep2File *vp = (struct nxpTfaVolumeStep2File *)hdr; + return vp->vsteps; + } + } + } + + return 0; +} + + +struct nxpTfaProfile *tfaContProfile(struct tfa98xx *tfa98xx, int index) +{ + struct nxpTfaDevice *dev = tfa98xx->fw.dev; + struct nxpTfaProfile *prof; + char *base = tfa98xx->fw.base; + int j, hit; + + for (j = 0, hit = 0; j < dev->length; j++) { + if (dev->list[j].type == dscProfile) { + prof = (struct nxpTfaProfile *)(base + dev->list[j].offset); + if (hit++ == index) { + pr_debug("select profile[%d]='%s'\n", index, base + prof->name.offset); + return prof; + } + } + } + + return NULL; +} + + + +/* + * return the bitfield + */ +struct nxpTfaBitfield tfaContDsc2Bf(struct nxpTfaDescPtr dsc) +{ + u32 *ptr = (u32 *) (&dsc); + union { + struct nxpTfaBitfield bf; + u32 num; + } num_bf; + + num_bf.num = *ptr & TFA_BITFIELDDSCMSK; + return num_bf.bf; +} + +TFA_NAMETABLE + +char *tfaContBfName(u16 num) +{ + int n = 0; + do { + if (TfaBfNames[n].bfEnum == num) + return TfaBfNames[n].bfName; + } + while (TfaBfNames[n++].bfEnum != 0xffff); + + return TfaBfNames[n-1].bfName; +} + +/* + * write reg and bitfield items in the profilelist the target + */ +int tfaContWriteRegsProf(struct tfa98xx *tfa98xx, int profile) +{ + struct nxpTfaProfile *prof = tfaContProfile(tfa98xx, profile); + u8 *base = tfa98xx->fw.base; + int i; + int err = 0; + + if (!prof) { + return -EINVAL; + } + + /* process the list until a patch, file of profile is encountered */ + for (i = 0; i < prof->length; i++) { + if ( prof->list[i].type == dscPatch || + prof->list[i].type ==dscFile || + prof->list[i].type ==dscProfile ) + break; + + if (prof->list[i].type & dscBitfieldBase) { + err = tfaRunWriteBitfield(tfa98xx, tfaContDsc2Bf(prof->list[i])); + } + + if (!prof->list[i].type == dscRegister) { + err = tfaRunWriteRegister(tfa98xx, (struct nxpTfaRegpatch *)(base + prof->list[i].offset)); + } + + if (err) + break; + } + + return err; +} + +/* + * write reg and bitfield items in the devicelist to the target + */ +int tfaContWriteRegsDev(struct tfa98xx *tfa98xx) +{ + struct nxpTfaDevice *dev = tfa98xx->fw.dev; + u8 *base = tfa98xx->fw.base; + int i; + int err = 0; + + if (!dev) + return -EINVAL; + + /* process the list until a patch, file of profile is encountered */ + for (i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscPatch || + dev->list[i].type ==dscFile || + dev->list[i].type ==dscProfile) + break; + + if (dev->list[i].type & dscBitfieldBase) { + err = tfaRunWriteBitfield(tfa98xx, tfaContDsc2Bf(dev->list[i])); + } + + if (dev->list[i].type == dscRegister) { + err = tfaRunWriteRegister(tfa98xx, (struct nxpTfaRegpatch *)(dev->list[i].offset + base)); + } + + if (err) + break; + } + + return err; +} + +/* + * show the contents of the header + */ +void tfaContShowHeader(struct tfa98xx *tfa98xx, struct nxpTfaHeader *hdr) +{ + char id[2]; + + id[1] = hdr->id >> 8; + id[0] = hdr->id & 0xff; +} + +/* + * write patchfile in the devicelist to the target + */ +int tfaContWritePatch(struct tfa98xx *tfa98xx) +{ + struct nxpTfaDevice *dev = tfa98xx->fw.dev; + u8 *base = tfa98xx->fw.base; + struct nxpTfaFileDsc *file; + struct nxpTfaPatch *patchfile; + int size; + int i; + + /* process the list until a patch is encountered */ + for(i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscPatch) { + file = (struct nxpTfaFileDsc *)(dev->list[i].offset + base); + patchfile =(struct nxpTfaPatch *)&file->data; + tfaContShowHeader(tfa98xx, &patchfile->hdr); + + /* size is total length including header */ + size = patchfile->hdr.size - sizeof(struct nxpTfaPatch); + return tfa98xx_dsp_patch(tfa98xx, size, (const u8*) patchfile->data); + } + } + + return -EINVAL; +} + + +int tfaContWriteFilterbank(struct tfa98xx *tfa98xx, struct nxpTfaFilter *filter) +{ + unsigned char biquad_index; + int ret = 0; + + for (biquad_index = 0; biquad_index < 10; biquad_index++) { + if (filter[biquad_index].enabled) { + ret = tfa98xx_dsp_biquad_set_coeff(tfa98xx, biquad_index + 1, // start @1 + sizeof(filter[biquad_index].biquad.bytes), + filter[biquad_index].biquad.bytes); + } else { + ret = tfa98xx_dsp_biquad_disable(tfa98xx, biquad_index+1); + } + + if (ret) { + pr_err("Error %d\n", ret); + return ret; + } + } + + return 0; +} + +int tfaContWriteEq(struct tfa98xx *tfa98xx, struct nxpTfaEqualizerFile *eqf) +{ + return tfaContWriteFilterbank(tfa98xx, eqf->filter); +} + +/* + * write a parameter file to de device + */ +int tfaContWriteVstep(struct tfa98xx *tfa98xx, struct nxpTfaVolumeStep2File *vp) +{ + int vstep; + int err = 0; + + vstep = tfa98xx->vstep; + + if (vstep < vp->vsteps) { + err = tfa98xx_dsp_write_preset(tfa98xx, sizeof(vp->vstep[0].preset), vp->vstep[vstep].preset); + if (err) + return err; + + err = tfaContWriteFilterbank(tfa98xx, vp->vstep[vstep].filter); + if (err) + return err; + + tfa98xx_set_volume(tfa98xx, vp->vstep[vstep].attenuation); + } else { + pr_err("vstep[%d] > %d\n", tfa98xx->vstep , vp->vsteps - 1); + return -EINVAL; + } + + return err; +} + +/* + * write a parameter file to the device + */ +int tfaContWriteFile(struct tfa98xx *tfa98xx, struct nxpTfaFileDsc *file) +{ + int size; + struct nxpTfaHeader *hdr = (struct nxpTfaHeader *)file->data; + enum tfa_cnt_header_type type; + int err = 0; + + type = hdr->id; + + switch (type) { + case volstepHdr: + err = tfaContWriteVstep(tfa98xx, (struct nxpTfaVolumeStep2File *)hdr); + break; + case speakerHdr: + size = hdr->size - sizeof(struct nxpTfaSpeakerFile); + err = tfa98xx_dsp_write_speaker_parameters(tfa98xx, size, (const u8 *)((struct nxpTfaSpeakerFile *)hdr)->data); + break; + case presetHdr: + size = hdr->size - sizeof(struct nxpTfaPresetFile); + err = tfa98xx_dsp_write_preset(tfa98xx, size, (const u8 *)((struct nxpTfaPresetFile *)hdr)->data); + break; + case configHdr: + size = hdr->size - sizeof(struct nxpTfaConfigFile); + err = tfa98xx_dsp_write_config(tfa98xx, size, (const u8 *)((struct nxpTfaConfigFile *)hdr)->data); + break; + case equalizerHdr: + tfaContWriteEq(tfa98xx, (struct nxpTfaEqualizerFile *) hdr); + break; + case patchHdr: + size = hdr->size - sizeof(struct nxpTfaPatch ); + err = tfa98xx_dsp_patch(tfa98xx, size, (const u8 *)((struct nxpTfaPatch *)hdr)->data); + break; + case drcHdr: + /* + * The DRC file is split as: + * 36 bytes for generic header (customer, application, and type) + * 127x3 (381) bytes first block contains the device and sample rate + * independent settings + * 127x3 (381) bytes block the device and sample rate specific values. + * The second block can always be recalculated from the first block, + * if vlsCal and the sample rate are known. + */ + size = sizeof(struct drcParamBlock); + /* fixed size for first block */ + err = tfa98xx_dsp_write_drc(tfa98xx, size, (const u8 *)((struct nxpTfaDrcFile *)hdr)->data); + break; + default: + pr_err("Header is of unknown type: 0x%x\n", type); + return -EINVAL; + } + + return err; +} + + +int tfaContWriteItem(struct tfa98xx *tfa98xx, struct nxpTfaDescPtr * dsc) +{ + struct nxpTfaFileDsc *file; + struct nxpTfaRegpatch *reg; + u8 *base = tfa98xx->fw.base; + + switch (dsc->type) { + case dscDevice: + case dscProfile: + /* ignore device and profile list */ + break; + case dscRegister: + reg = (struct nxpTfaRegpatch *)(dsc->offset + base); + return tfaRunWriteRegister(tfa98xx, reg); + case dscString: + /* zero terminated string */ + break; + case dscFile: + case dscPatch: + /* filename + file contents */ + file = (struct nxpTfaFileDsc *)(dsc->offset + base); + break; + default: + if (dsc->type & dscBitfieldBase) + return tfaRunWriteBitfield(tfa98xx , tfaContDsc2Bf(*dsc)); + } + + return 0; +} + +/* + * process all items in the profilelist + * NOTE an error return during processing will leave the device muted + */ +int tfaContWriteProfile(struct tfa98xx *tfa98xx, int profile, int vstep) +{ + struct nxpTfaProfile *prof = tfaContProfile(tfa98xx, profile); + struct nxpTfaFileDsc *file; + u8 *base = tfa98xx->fw.base; + int i, pwdn=-1; + + if (!prof) { + return -EINVAL; + } + + if (tfa98xx->profile_current != profile ) { + /* profile switch so mute first */ + tfa98xx_mute(tfa98xx); + } + + tfa98xx->profile_current = profile; + tfa98xx->vstep = tfa98xx->profiles[profile].vstep; + + /* + * process the list and write all registers, + * if a file is encountered then see if we need to poweron first + */ + for(i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscFile) { + if (pwdn < 0) + pwdn = tfa98xx_is_pwdn(tfa98xx) ; + + if (pwdn) { + tfa98xx_dsp_power_up(tfa98xx); + pwdn=0; + } + + file = (struct nxpTfaFileDsc *)(prof->list[i].offset + base); + if (tfaContWriteFile(tfa98xx, file) ){ + return -EINVAL; + } + } else { + /* process and write all non-file items */ + if (tfaContWriteItem(tfa98xx, &prof->list[i])) + return -EINVAL; + } + } + + tfa98xx_unmute(tfa98xx); + return 0; +} + +/* + * write all param files in the profilelist to the target + * this is used during startup when may be ACS is set + */ +int tfaContWriteFilesProf(struct tfa98xx *tfa98xx, int profile, int vstep) +{ + struct nxpTfaProfile *prof = tfaContProfile(tfa98xx, profile); + struct nxpTfaFileDsc *file; + u8 *base = tfa98xx->fw.base; + int i; + + if (!prof) { + return -EINVAL; + } + + /* process the list and write all files */ + for(i = 0; i < prof->length; i++) { + if (prof->list[i].type == dscFile) { + file = (struct nxpTfaFileDsc *)(prof->list[i].offset + base); + if (tfaContWriteFile(tfa98xx, file)) { + return -EINVAL; + } + } + } + + tfa98xx->profile_current = profile; + tfa98xx->vstep = vstep; + + return 0; +} + +/* + * write all param files in the devicelist to the target + */ +int tfaContWriteFiles(struct tfa98xx *tfa98xx) +{ + struct nxpTfaDevice *dev = tfa98xx->fw.dev; + u8 *base = tfa98xx->fw.base; + struct nxpTfaFileDsc *file; + int i; + + /* process the list and write all files */ + for(i = 0; i < dev->length; i++) { + if (dev->list[i].type == dscFile) { + file = (struct nxpTfaFileDsc *)(dev->list[i].offset + base); + if (tfaContWriteFile(tfa98xx, file)) { + pr_err("error\n"); + return -EINVAL; + } + } + } + + return 0; +} + diff --git a/sound/soc/codecs/tfa9890/tfa_container.h b/sound/soc/codecs/tfa9890/tfa_container.h new file mode 100644 index 0000000000000..ff6e2fb86c7b8 --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa_container.h @@ -0,0 +1,422 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __TFA_CONTAINER_H__ +#define __TFA_CONTAINER_H__ + + + +/* + * tfa98xx container firmware header + */ + +struct nxpTfaDescPtr { + u32 offset:24; + u8 type; // (== enum nxpTfaDescriptorType, assure 8bits length) +}; + + +struct nxpTfaDevice { + u8 length; // nr of items in the list + u8 bus; // bus + u8 dev; // device + u8 func; // subfunction or subdevice + u32 devid; // device hw fw id + struct nxpTfaDescPtr name; // device name + struct nxpTfaDescPtr list[]; // items list +} __attribute__((packed)); + + +#define HDR(c1,c2) (c2<<8|c1) // little endian +enum tfa_cnt_header_type { + params = HDR('P','M'), + volstep = HDR('V','P'), + patch = HDR('P','A'), + speaker = HDR('S','P'), + preset = HDR('P','R'), + config = HDR('C','O'), + equalizer = HDR('E','Q'), + drc = HDR('D','R') +}; + +enum nxpTfaHeaderType { + paramsHdr = HDR('P','M'), + volstepHdr = HDR('V','P'), + patchHdr = HDR('P','A'), + speakerHdr = HDR('S','P'), + presetHdr = HDR('P','R'), + configHdr = HDR('C','O'), + equalizerHdr = HDR('E','Q'), + drcHdr = HDR('D','R') +}; + + +#define TFA_PM_VERSION '1' +#define TFA_PM_SUBVERSION "00" + +enum nxpTfaDescriptorType { + dscDevice, // device list + dscProfile, // profile list + dscRegister, // register patch + dscString, // ascii, zero terminated string + dscFile, // filename + file contents + dscPatch, // patch file + dscMarker, // marker to indicate end of a list + dscBitfieldBase=0x80 // start of bitfield enums +}; + +/* + * profile descriptor list + */ +struct nxpTfaProfile { + u8 length; // nr of items in the list + u32 ID:24; // profile ID + struct nxpTfaDescPtr name; // profile name + struct nxpTfaDescPtr list[]; // items list +} __attribute__((packed)); +#define TFA_PROFID 0x1234 + + +//static char nostring[]="Undefined string"; + +/* + * generic file descriptor + */ +struct nxpTfaFileDsc { + struct nxpTfaDescPtr name; + u32 size; // file data length in bytes + u8 data[]; //payload +} __attribute__((packed)); + + +struct nxpTfaContainer { + char id[2]; // "XX" : XX=type + char version[2]; // "V_" : V=version, vv=subversion + char subversion[2]; // "vv" : vv=subversion + u32 size; // data size in bytes following CRC + u32 CRC; // 32-bits CRC for following data + u16 rev; // "extra chars for rev nr" + char customer[8]; // “name of customer†+ char application[8]; // “application name†+ char type[8]; // “application type name†+ u16 ndev; // "nr of device lists" + u16 nprof; // "nr of profile lists" + struct nxpTfaDescPtr index[]; // start of item index table +} __attribute__((packed)); + +struct tfa_cnt_header { + u16 id; + char version[2]; /* "V_" : V=version */ + char subversion[2]; // "vv" : vv=subversion + u32 size; // data size in bytes following CRC + u32 CRC; // 32-bits CRC for following data + u16 rev; + char customer[8]; // “name of customer†+ char application[8]; // “application name†+ char type[8]; // “application type name†+ u16 ndev; // "nr of device lists" + u16 nprof; // "nr of profile lists" + struct nxpTfaDescPtr index[]; // start of item index table +} __attribute__((packed)); + + +/* + * the generic header + * all char types are in ASCII + */ +struct nxpTfaHeader { + u16 id; + char version[2]; // "V_" : V=version, vv=subversion + char subversion[2]; // "vv" : vv=subversion + u16 size; // data size in bytes following CRC + u32 CRC; // 32-bits CRC for following data + char customer[8]; // “name of customer†+ char application[8]; // “application name†+ char type[8]; // “application type name†+} __attribute__((packed)); + +#define NXPTFA_PA_VERSION '1' +#define NXPTFA_PA_SUBVERSION "00" + +struct nxpTfaPatch { + struct nxpTfaHeader hdr; + u8 data[]; +} __attribute__((packed)); + + +/* + * typedef for 24 bit value using 3 bytes + */ +typedef struct uint24 { + u8 b[3]; +} u24; + +/* + * the biquad coefficients for the API together with index in filter + * the biquad_index is the actual index in the equalizer +1 + */ +struct nxpTfaBiquad { + u8 bytes[6*sizeof(u24)]; +} __attribute__((packed)); + +struct nxpTfaBiquadFloat { + float headroom; + float b0; + float b1; + float b2; + float a1; + float a2; +}; + +enum nxpTfaFilterType { + fCustom, //User defined biquad coefficients + fFlat, //Vary only gain + fLowpass, //2nd order Butterworth low pass + fHighpass, //2nd order Butterworth high pass + fLowshelf, + fHighshelf, + fNotch, + fPeak, + fBandpass, + f1stLP, + f1stHP, + fCount +}; + +/* + * filter parameters for biquad (re-)calculation + */ +struct nxpTfaFilter { + struct nxpTfaBiquad biquad; + u8 enabled; + u8 type; // (== enum FilterTypes, assure 8bits length) + float frequency; + float Q; + float gain; +} __attribute__((packed)); //8 * float + int32 + byte == 37 + +#define TFA98XX_MAX_EQ 10 + +struct nxpTfaEqualizer { + struct nxpTfaFilter filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10 +}; + + + + +/* + * equalizer file + */ +#define NXPTFA_EQ_VERSION '1' +#define NXPTFA_EQ_SUBVERSION "00" + +struct nxpTfaEqualizerFile { + struct nxpTfaHeader hdr; + u8 samplerate; // ==enum samplerates, assure 8 bits + struct nxpTfaFilter filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10 +} __attribute__((packed)); + +/* + * config file + */ +#define NXPTFA_CO_VERSION '1' +#define NXPTFA_CO_SUBVERSION "00" + +struct nxpTfaConfigFile { + struct nxpTfaHeader hdr; + u8 data[]; +} __attribute__((packed)); + +/* + * preset file + */ +#define NXPTFA_PR_VERSION '1' +#define NXPTFA_PR_SUBVERSION "00" + +struct nxpTfaPresetFile { + struct nxpTfaHeader hdr; + u8 data[]; +} __attribute__((packed)); + +/* + * drc file + * TODO: Add DRC filter data, treshold ... + */ +#define NXPTFA_DR_VERSION '1' +#define NXPTFA_DR_SUBVERSION "00" + +struct nxpTfaDrcFile { + struct nxpTfaHeader hdr; + u8 data[]; +} __attribute__((packed)); + +/* + * volume step structures + */ + +/* VP01 */ +#define NXPTFA_VP1_VERSION '1' +#define NXPTFA_VP1_SUBVERSION "01" + +struct nxpTfaVolumeStep1 { + u32 attenuation; // contain IEEE single float + u8 preset[TFA98XX_PRESET_LENGTH]; +} __attribute__((packed)); + +/* VP02 */ +#define NXPTFA_VP2_VERSION '2' +#define NXPTFA_VP2_SUBVERSION "01" + +struct nxpTfaVolumeStep2 { + u32 attenuation; // contain IEEE single float + u8 preset[TFA98XX_PRESET_LENGTH]; + struct nxpTfaFilter filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10 +} __attribute__((packed)); + + +/* + * Register patch descriptor + */ +struct nxpTfaRegpatch { + u8 address; // register address + u16 value; // value to write + u16 mask; // mask of bits to write +} __attribute__((packed)); + +/* + * volumestep file + */ +struct nxpTfaVolumeStepFile { + struct nxpTfaHeader hdr; + u8 vsteps; // can also be calulated from size+type + u8 samplerate; // ==enum samplerates, assure 8 bits + u8 payload; //start of variable length contents:N times volsteps +} __attribute__((packed)); + +/* + * volumestep2 file + */ +struct nxpTfaVolumeStep2File { + struct nxpTfaHeader hdr; + u8 vsteps; // can also be calulated from size+type + u8 samplerate; // ==enum samplerates, assure 8 bits + struct nxpTfaVolumeStep2 vstep[]; //start of variable length contents:N times volsteps +} __attribute__((packed)); + +/* + * speaker file + */ +#define NXPTFA_SP_VERSION '1' +#define NXPTFA_SP_SUBVERSION "00" + +struct nxpTfaSpeakerFile { + struct nxpTfaHeader hdr; + char name[8]; // speaker nick name (e.g. “dumboâ€) + char vendor[16]; + char type[8]; + /* dimensions (mm) */ + u8 height; + u8 width; + u8 depth; + u16 ohm; + u8 data[]; //payload TFA98XX_SPEAKERPARAMETER_LENGTH +} __attribute__((packed)); + +/* + * Bitfield descriptor + */ +struct nxpTfaBitfield { + u16 value; + u16 field; // ==datasheet defined, 16 bits +} __attribute__((packed)); + +/* + * Bitfield enumuration bits descriptor + */ +struct nxpTfaBfEnum { + u16 len:4; // this is the actual length-1 + u16 pos:4; + u16 address:8; +} __attribute__((packed)); + + +struct drcBiquad { + u24 freq; // center frequency + u24 Q; // Q factor + u24 gain; // gain in dB + u24 type; // filter type (= enum dspBqFiltType_t) +}; + +struct drc { + u24 enabled; // drc enabled + u24 sidechain; // side chain usage + u24 kneetype; // knee type enum + u24 env; // envelope + u24 attack; // attack time in ms + u24 release; // release time in ms; + u24 thresDb; // threshold in dB; + u24 ratio; + u24 makeupGain; // make up gain in dB +}; + +struct drcBandLimited { + u24 enabled; // band limted drc enabled (0 = off) + struct drcBiquad biquad; // biquad for band + struct drc limiter; // band limiter +}; + +struct drcParamBlock { + u24 drcOn; // drc module enabled. 0 == off + struct drcBiquad hi1bq; // high band biquads + struct drcBiquad hi2bq; + struct drcBiquad mi1bq; // mid band biqauds + struct drcBiquad mi2bq; + struct drcBiquad mi3bq; + struct drcBiquad mi4bq; + struct drcBiquad lo1bq; // low band biquads + struct drcBiquad lo2bq; + struct drcBiquad po1bq; // post biquads + struct drcBiquad po2bq; + struct drc hi1drc; // high compressors + struct drc hi2drc; + struct drc mi1drc; // mid compressors + struct drc mi2drc; + struct drc lo1drc; // low compressors + struct drc lo2drc; + struct drc po1drc; // post compressors + struct drc po2drc; + struct drcBandLimited bl;// band limited compressor +}; + + + +int tfa98xx_cnt_loadfile(struct tfa98xx *tfa98xx, int index); +char *tfaContBfName(u16 num); +int tfaContWriteRegsProf(struct tfa98xx *tfa98xx, int profile); +int tfaContWriteRegsDev(struct tfa98xx *tfa98xx); +void tfaContShowHeader(struct tfa98xx *tfa98xx, struct nxpTfaHeader *hdr); +int tfaContWritePatch(struct tfa98xx *tfa98xx); +int tfaContWriteFilterbank(struct tfa98xx *tfa98xx, struct nxpTfaFilter *filter); +int tfaContWriteEq(struct tfa98xx *tfa98xx, struct nxpTfaEqualizerFile *eqf); +int tfaContWriteVstep(struct tfa98xx *tfa98xx, struct nxpTfaVolumeStep2File *vp); +int tfaContWriteFile(struct tfa98xx *tfa98xx, struct nxpTfaFileDsc *file); +int tfaContWriteItem(struct tfa98xx *tfa98xx, struct nxpTfaDescPtr * dsc); +int tfaContWriteProfile(struct tfa98xx *tfa98xx, int profile, int vstep); +int tfaContWriteFilesProf(struct tfa98xx *tfa98xx, int profile, int vstep); +int tfaContWriteFiles(struct tfa98xx *tfa98xx); +int tfa98xx_dsp_write_drc(struct tfa98xx *tfa98xx, int len, const u8 *data); + +struct snd_kcontrol_new *tfa_build_profile_controls(struct tfa98xx *tfa98xx, int* kcontrol_count); + +#endif diff --git a/sound/soc/codecs/tfa9890/tfa_dsp.c b/sound/soc/codecs/tfa9890/tfa_dsp.c new file mode 100755 index 0000000000000..c9b67c0e98e8f --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa_dsp.c @@ -0,0 +1,2446 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s(%s): " fmt, __func__, tfa98xx->fw.name +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tfa98xx-core.h" +#include "tfa98xx-regs.h" +#include "tfa_container.h" +#include "tfa_dsp.h" + +/* size of the data buffer used for I2C transfer */ +#define TFA98XX_MAX_I2C_SIZE 252 + + +#define TFA98XX_XMEM_CALIBRATION_DONE 231 // 0xe7 +#define TFA98XX_XMEM_IMPEDANCE 232 +#define TFA98XX_XMEM_COUNT_BOOT 161 // 0xa1 + +/* + * Maximum number of retries for DSP result + * Keep this value low! + * If certain calls require longer wait conditions, the + * application should poll, not the API + * The total wait time depends on device settings. Those + * are application specific. + */ +#define TFA98XX_WAITRESULT_NTRIES 50 +#define TFA98XX_WAITRESULT_NTRIES_LONG 2000 + + +/* DSP module IDs */ +#define MODULE_FRAMEWORK 0 +#define MODULE_SPEAKERBOOST 1 +#define MODULE_BIQUADFILTERBANK 2 +#define MODULE_SETRE 9 + + +/* RPC commands IDs */ +/* Load a full model into SpeakerBoost. */ +#define SB_PARAM_SET_LSMODEL 0x06 +#define SB_PARAM_SET_EQ 0x0A /* 2 Equaliser Filters */ +#define SB_PARAM_SET_PRESET 0x0D /* Load a preset */ +#define SB_PARAM_SET_CONFIG 0x0E /* Load a config */ +#define SB_PARAM_SET_DRC 0x0F +#define SB_PARAM_SET_AGCINS 0x10 + + +/* gets the speaker calibration impedance (@25 degrees celsius) */ +#define SB_PARAM_GET_RE0 0x85 +#define SB_PARAM_GET_LSMODEL 0x86 /* Gets LoudSpeaker Model */ +#define SB_PARAM_GET_CONFIG_PRESET 0x80 +#define SB_PARAM_GET_STATE 0xC0 +#define SB_PARAM_GET_XMODEL 0xC1 /* Gets Excursion Model */ + +#define SPKRBST_TEMPERATURE_EXP 9 + +/* Framework params */ +#define FW_PARAM_SET_CURRENT_DELAY 0x03 +#define FW_PARAM_SET_CURFRAC_DELAY 0x06 +#define FW_PARAM_GET_STATE 0x84 +#define FW_PARAM_GET_FEATURE_BITS 0x85 + +int tfa98xx_set_I2S2(struct tfa98xx *tfa98xx); + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-08-13, add for mtp recovery*/ +int recoverMtp0 = false; + +EXPORT_SYMBOL_GPL(recoverMtp0); +#endif + + +/* + * write a bit field + */ +int tfaRunWriteBitfield(struct tfa98xx *tfa98xx, struct nxpTfaBitfield bf) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value, oldvalue, msk, tmp; + union { + u16 field; + struct nxpTfaBfEnum Enum; + } bfUni; + + value = bf.value; + bfUni.field = bf.field; + //bfUni.field &= 0x7fff; //mask of high bit, done before + + if (((struct nxpTfaBfEnum*)&bf.field)->address & 0x80) { + pr_err("WARNING:not a persistant write of MTP\n"); + } + + oldvalue = (u16)snd_soc_read(codec, bfUni.Enum.address); + tmp = oldvalue; + + msk = ((1 << (bfUni.Enum.len + 1)) - 1) << bfUni.Enum.pos; + oldvalue &= ~msk; + oldvalue |= value << bfUni.Enum.pos; + snd_soc_write(codec, bfUni.Enum.address, oldvalue); + + return 0; +} + +/* + * write the register based on the input address, value and mask + * only the part that is masked will be updated + */ +int tfaRunWriteRegister(struct tfa98xx *tfa98xx, struct nxpTfaRegpatch *reg) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value, newvalue; + + value = (u16)snd_soc_read(codec, reg->address); + value &= ~reg->mask; + newvalue = reg->value & reg->mask; + value |= newvalue; + snd_soc_write(codec, reg->address, value); + + return 0; +} + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, repair when MTP 0 fail*/ +int tfa98xx_restore_mtp(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 readValue; + + pr_err("%s \n",__func__); + + snd_soc_write(codec, 0x40, 0x5a6b); + readValue = (u16)snd_soc_read(codec, 0x8b); + + readValue ^= 0x5a; + + snd_soc_write(codec, 0x60, readValue); + snd_soc_write(codec, 0x0b, 0x5A); + + snd_soc_write(codec, 0x81, 0xF800); + snd_soc_write(codec, 0x82, 0x414); + snd_soc_write(codec, 0x84, 0x3F40); + snd_soc_write(codec, 0x85, 0x0); + snd_soc_write(codec, 0x86, 0x0); + snd_soc_write(codec, 0x87, 0x0); + snd_soc_write(codec, 0x8a, 0x5555); + snd_soc_write(codec, 0x8b, 0xAAAA); + snd_soc_write(codec, 0x8c, 0x5555); + snd_soc_write(codec, 0x8d, 0xAAAA); + + snd_soc_write(codec, 0x62, 0x8800); + snd_soc_write(codec, 0x60, 0x0); + snd_soc_write(codec, 0x62, 0x0); + snd_soc_write(codec, 0x40, 0x0); + + return 0; +} + +/* NXP: Only restore I2C registers */ +int tfa98xx_restore_i2cmtp(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 readValue; + + pr_err("%s\n",__func__); + + snd_soc_write(codec, 0x40, 0x5a6b); + readValue = (u16)snd_soc_read(codec, 0x8b); + + readValue ^= 0x5a; + + snd_soc_write(codec, 0x60, readValue); + snd_soc_write(codec, 0x0b, 0x5A); + + snd_soc_write(codec, 0x81, 0xF800); + snd_soc_write(codec, 0x82, 0x414); + snd_soc_write(codec, 0x84, 0x3F40); + snd_soc_write(codec, 0x85, 0x0); + snd_soc_write(codec, 0x86, 0x0); + snd_soc_write(codec, 0x87, 0x0); + snd_soc_write(codec, 0x8a, 0x5555); + snd_soc_write(codec, 0x8b, 0xAAAA); + snd_soc_write(codec, 0x8c, 0x5555); + snd_soc_write(codec, 0x8d, 0xAAAA); + + snd_soc_write(codec, 0x60, 0x0); + snd_soc_write(codec, 0x40, 0x0); + + return 0; +} + +#endif + +/* + * tfa98xx_dsp_system_stable will compensate for the wrong behavior of CLKS + * to determine if the DSP subsystem is ready for patch and config loading. + * + * A MTP calibration register is checked for non-zero. + * + * Note: This only works after i2c reset as this will clear the MTP contents. + * When we are configured then the DSP communication will synchronize access. + */ +int tfa98xx_dsp_system_stable(struct tfa98xx *tfa98xx, int *ready) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 status, mtp0, sysctrl; + int tries; + + *ready = 0; + + /* check the contents of the STATUS register */ + status = (u16)snd_soc_read(codec, TFA98XX_STATUSREG); + sysctrl = (u16)snd_soc_read(codec, TFA98XX_SYS_CTRL); + + pr_debug("statusreg = 0x%04x, sysctrl=0x%04x\n", status, sysctrl); + + /* + * if AMPS is set then we were already configured and running + * no need to check further + */ + *ready = (status & TFA98XX_STATUSREG_AMPS_MSK) == (TFA98XX_STATUSREG_AMPS_MSK); + if (*ready) + return 0; + + /* check AREFS and CLKS: not ready if either is clear */ + *ready = (status & (TFA98XX_STATUSREG_AREFS_MSK | TFA98XX_STATUSREG_CLKS_MSK)) + == (TFA98XX_STATUSREG_AREFS_MSK | TFA98XX_STATUSREG_CLKS_MSK); + if (!*ready) /* if not ready go back */ + return 0; + + if (tfa98xx->rev != REV_TFA9890) { + *ready = 1; + return 0; + } + + /* + * check MTPB + * mtpbusy will be active when the subsys copies MTP to I2C + * 2 times retry avoids catching this short mtpbusy active period + */ + for (tries = 2; tries > 0; tries--) { + status = (u16)snd_soc_read(codec, TFA98XX_STATUSREG); + /* check the contents of the STATUS register */ + *ready = (status & TFA98XX_STATUSREG_MTPB_MSK) == 0; + if (*ready) /* if ready go on */ + break; + } + if (tries == 0) { /* ready will be 0 if retries exausted */ + pr_err("Not ready %d\n", !*ready); + return 0; + } + + /* + * check the contents of MTP register for non-zero, + * this indicates that the subsys is ready + */ + mtp0 = (u16)snd_soc_read(codec, 0x84); + + *ready = (mtp0 != 0); /* The MTP register written? */ + pr_err("MTP0 %d\n", *ready); + + + return ret; +} + +/* + * Disable clock gating + */ +static int tfa98xx_clockgating(struct tfa98xx *tfa98xx, int on) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + /* The clockgating hack is used only for the tfa9890 */ + if (tfa98xx->rev != REV_TFA9890) + return 0; + + /* for TFA9890 temporarily disable clock gating when dsp reset is used */ + value = snd_soc_read(codec, TFA98XX_CURRENTSENSE4); + + if (on) /* clock gating on - clear the bit */ + value &= ~TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF; + else /* clock gating off - set the bit */ + value |= TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF; + + return snd_soc_write(codec, TFA98XX_CURRENTSENSE4, value); +} + +/* + * tfa98xx_dsp_reset will deal with clock gating control in order + * to reset the DSP for warm state restart + */ +static int tfa98xx_dsp_reset(struct tfa98xx *tfa98xx, int state) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + /* for TFA9890 temporarily disable clock gating when dsp reset is used */ + tfa98xx_clockgating(tfa98xx, 0); + + value = snd_soc_read(codec,TFA98XX_CF_CONTROLS); + + /* set requested the DSP reset signal state */ + value = state ? (value | TFA98XX_CF_CONTROLS_RST_MSK) : + (value & ~TFA98XX_CF_CONTROLS_RST_MSK); + + snd_soc_write(codec, TFA98XX_CF_CONTROLS, value); + + /* clock gating restore */ + return tfa98xx_clockgating(tfa98xx, 1); +} + +int tfa98xx_powerdown(struct tfa98xx *tfa98xx, int powerdown) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + pr_debug("%d\n", powerdown); + + /* read the SystemControl register, modify the bit and write again */ + value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + switch (powerdown) { + case 1: + value |= TFA98XX_SYS_CTRL_PWDN_MSK; + break; + case 0: + value &= ~(TFA98XX_SYS_CTRL_PWDN_MSK); + break; + default: + return -EINVAL; + } + return snd_soc_write(codec, TFA98XX_SYS_CTRL, value); +} + + +static int tfa98xx_read_data(struct tfa98xx *tfa98xx, u8 address, int len, u8 *data) +{ +// pr_debug("@%02x, #%d\n", address, len); + + if (tfa98xx_i2c_read(tfa98xx->i2c, address, data, len)) { + pr_err("Error during I2C read\n"); + return -EIO; + } + + return 0; +} + +void tfa98xx_convert_data2bytes(int num_data, const int *data, u8 *bytes) +{ + int i, k, d; + /* + * note: cannot just take the lowest 3 bytes from the 32 bit + * integer, because also need to take care of clipping any + * value > 2&23 + */ + for (i = 0, k = 0; i < num_data; ++i, k += 3) { + if (data[i] >= 0) + d = MIN(data[i], (1 << 23) - 1); + else { + /* 2's complement */ + d = (1 << 24) - MIN(-data[i], 1 << 23); + } + bytes[k] = (d >> 16) & 0xFF; /* MSB */ + bytes[k + 1] = (d >> 8) & 0xFF; + bytes[k + 2] = (d) & 0xFF; /* LSB */ + } +} + + +/* + * convert DSP memory bytes to signed 24 bit integers + * data contains "len/3" elements + * bytes contains "len" elements + */ +void tfa98xx_convert_bytes2data(int len, const u8 *bytes, int *data) +{ + int i, k, d; + int num_data = len / 3; + + for (i = 0, k = 0; i < num_data; ++i, k += 3) { + d = (bytes[k] << 16) | (bytes[k + 1] << 8) | (bytes[k + 2]); + if (bytes[k] & 0x80) /* sign bit was set */ + d = -((1 << 24) - d); + + data[i] = d; + } +} + + +int tfa98xx_dsp_read_mem(struct tfa98xx *tfa98xx, u16 start_offset, int num_words, int *values) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 cf_ctrl; /* to sent to the CF_CONTROLS register */ + u8 bytes[MAX_PARAM_SIZE]; + int burst_size; /* number of words per burst size */ + int bytes_per_word = 3; + int len; + int *p; + + /* first set DMEM and AIF, leaving other bits intact */ + cf_ctrl = snd_soc_read(codec, TFA98XX_CF_CONTROLS); + cf_ctrl &= ~0x000E; /* clear AIF & DMEM */ + /* set DMEM, leave AIF cleared for autoincrement */ + cf_ctrl |= (Tfa98xx_DMEM_XMEM << 1); + + snd_soc_write(codec, TFA98XX_CF_CONTROLS, cf_ctrl); + + snd_soc_write(codec, TFA98XX_CF_MAD, start_offset); + + len = num_words * bytes_per_word; + p = values; + for (; len > 0;) { + burst_size = ROUND_DOWN(16, bytes_per_word); + if (len < burst_size) + burst_size = len; + + ret = tfa98xx_read_data(tfa98xx, TFA98XX_CF_MEM, burst_size, bytes); + if (ret) + return ret; + + tfa98xx_convert_bytes2data(burst_size, bytes, p); + len -= burst_size; + p += burst_size / bytes_per_word; + } + + return 0; +} + +/* + * Write all the bytes specified by len and data + */ +static int tfa98xx_write_data(struct tfa98xx *tfa98xx, u8 subaddress, int len, + const u8 *data) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u8 write_data[MAX_PARAM_SIZE]; + /* subaddress followed by data */ + int count = len + 1; + + if (count > MAX_PARAM_SIZE) { + pr_err("Error param size too big %d\n", len); + return -EINVAL; + } + + write_data[0] = subaddress; + memcpy(write_data + 1, data, len); + + return tfa98xx_bulk_write_raw(codec, write_data, count); +} + + +static int tfa98xx_dsp_write_mem(struct tfa98xx *tfa98xx, unsigned int address, int value, int memtype) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 cf_ctrl; /* the value to sent to the CF_CONTROLS register */ + u8 bytes[3]; + + /* first set DMEM and AIF, leaving other bits intact */ + cf_ctrl = snd_soc_read(codec, TFA98XX_CF_CONTROLS); + cf_ctrl &= ~0x000E; /* clear AIF & DMEM */ + + switch(memtype) { + case Tfa98xx_DMEM_PMEM: + cf_ctrl |= (Tfa98xx_DMEM_PMEM << 1); + break; + case Tfa98xx_DMEM_XMEM: + cf_ctrl |= (Tfa98xx_DMEM_XMEM << 1); + break; + case Tfa98xx_DMEM_YMEM: + cf_ctrl |= (Tfa98xx_DMEM_YMEM << 1); + break; + case Tfa98xx_DMEM_IOMEM: + cf_ctrl |= (Tfa98xx_DMEM_IOMEM << 1); + break; + } + snd_soc_write(codec, TFA98XX_CF_CONTROLS, cf_ctrl); + snd_soc_write(codec, TFA98XX_CF_MAD, address & 0xffff); + + tfa98xx_convert_data2bytes(1, &value, bytes); + ret = tfa98xx_write_data(tfa98xx, TFA98XX_CF_MEM, 3, bytes); + if (ret) + return ret; + + return 0; +} + + +int tfa98xx_dsp_reset_count(struct tfa98xx *tfa98xx) +{ + int count; + + tfa98xx_dsp_read_mem(tfa98xx, TFA98XX_XMEM_COUNT_BOOT, 1, &count); + + return count; +} + +/* + * wait for calibrate done + */ +static int tfa98xx_wait_calibration(struct tfa98xx *tfa98xx, int *done) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + int tries = 0; + u16 mtp; + + *done = 0; + + mtp = snd_soc_read(codec, TFA98XX_MTP); + + /* in case of calibrate once wait for MTPEX */ + if (mtp & TFA98XX_MTP_MTPOTC) { + while ((*done == 0) && (tries < TFA98XX_WAITRESULT_NTRIES)) + { + msleep_interruptible(5); + mtp = snd_soc_read(codec, TFA98XX_MTP); + *done = (mtp & TFA98XX_MTP_MTPEX); /* check MTP bit1 (MTPEX) */ + tries++; + } + } else { /* poll xmem for calibrate always */ + while ((*done == 0) && (tries < TFA98XX_WAITRESULT_NTRIES)) + { + msleep_interruptible(5); + ret = tfa98xx_dsp_read_mem(tfa98xx, TFA98XX_XMEM_CALIBRATION_DONE, 1, done); + tries++; + } + } + + if (tries == TFA98XX_WAITRESULT_NTRIES) { + pr_err("Calibrate Done timedout\n"); + return -ETIMEDOUT; + } + + return ret; +} + +static int tfa9887_specific(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + /* DSP must be in control of the amplifier to avoid plops */ + value |= TFA98XX_SYS_CTRL_AMPE_MSK; + snd_soc_write(codec, TFA98XX_SYS_CTRL, value); + + /* some other registers must be set for optimal amplifier behaviour */ + snd_soc_write(codec, TFA98XX_BAT_PROT, 0x13AB); + snd_soc_write(codec, TFA98XX_AUDIO_CTR, 0x001F); + /* peak voltage protection is always on, but may be written */ + snd_soc_write(codec, 0x08, 0x3C4E); + /* TFA98XX_SYSCTRL_DCA = 0 */ + snd_soc_write(codec, TFA98XX_SYS_CTRL, 0x024D); + snd_soc_write(codec, 0x0A, 0x3EC3); + snd_soc_write(codec, 0x41, 0x0308); + snd_soc_write(codec, 0x49, 0x0E82); + + return 0; +} + +static int tfa9887B_specific(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + /* all i2C registers are already set to default */ + value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + /* DSP must be in control of the amplifier to avoid plops */ + value |= TFA98XX_SYS_CTRL_AMPE_MSK; + snd_soc_write(codec, TFA98XX_SYS_CTRL, value); + + /* some other registers must be set for optimal amplifier behaviour */ + snd_soc_write(codec, TFA98XX_BAT_PROT, 0x13AB); + snd_soc_write(codec, TFA98XX_AUDIO_CTR, 0x001F); + /* peak voltage protection is always on, but may be written */ + snd_soc_write(codec, 0x08, 0x3C4E); + /* TFA98XX_SYSCTRL_DCA = 0 */ + snd_soc_write(codec, TFA98XX_SYS_CTRL, 0x024D); + snd_soc_write(codec, 0x41, 0x0308); + snd_soc_write(codec, 0x49, 0x0E82); + + return 0; +} + +static int tfa9890_specific(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 reg; + + /* all i2C registers are already set to default for N1C2 */ + + /* some PLL registers must be set optimal for amplifier behaviour */ + snd_soc_write(codec, 0x40, 0x5a6b); + reg = snd_soc_read(codec, 0x59); + + reg |= 0x3; + + reg = snd_soc_write(codec, 0x59, reg); + snd_soc_write(codec, 0x40, 0x0000); + + return 0; +} + +static int tfa9897_specific(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + + /* all i2C registers must already set to default POR value */ + + /* $48:[3] - 1 ==> 0; iddqtestbst - default value changed. */ + snd_soc_write(codec, 0x48, 0x0300); /* POR value = 0x308 */ + + return 0; +} + +/* + * clockless way to determine if this is the tfa9887 or tfa9895 + * by testing if the PVP bit is writable + */ +static int tfa98xx_is87(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 save_value, check_value; + + save_value = snd_soc_read(codec, 0x08); + + /* if clear it's 87 */ + if ((save_value & 0x0400) == 0) + return 1; + + /* try to clear pvp bit */ + snd_soc_write(codec, 0x08, (save_value & ~0x0400)); + check_value = snd_soc_read(codec, 0x08); + + /* restore */ + snd_soc_write(codec, 0x08, save_value); + /* could we write the bit */ + + /* if changed it's the 87 */ + return (check_value != save_value) ? 1 : 0; +} + +/* + * I2C register init should be done at probe/recover time (TBC) + */ +static int tfa98xx_init(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret; + + /* reset all i2c registers to default */ + snd_soc_write(codec, TFA98XX_SYS_CTRL, TFA98XX_SYS_CTRL_I2CR_MSK); + + switch (tfa98xx->rev) { + case 0x12: + if (tfa98xx_is87(tfa98xx)) + ret = tfa9887_specific(tfa98xx); + else + ret = tfa9887B_specific(tfa98xx); + break; + case 0x80: + ret = tfa9890_specific(tfa98xx); + break; + case 0x91: + break; + case 0x97: + ret = tfa9897_specific(tfa98xx); + break; + case 0x81: + /* for the RAM version disable clock-gating */ + ret = tfa9890_specific(tfa98xx); + tfa98xx_clockgating(tfa98xx, 0); + break; + default: + pr_err("Unsupported device: rev=0x%x, subrev=0x%x\n", tfa98xx->rev, tfa98xx->subrev); + return -EINVAL; + } + + return ret; +} + + +/* + * start the clocks and wait until the AMP is switching + * on return the DSP sub system will be ready for loading + */ +static int tfa98xx_startup(struct tfa98xx *tfa98xx) +{ + int tries, status, ret; + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, Modify for MTP repare*/ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 statusreg = 0; + u16 mtp0; +#endif + + /* load the optimal TFA98XX in HW settings */ + ret = tfa98xx_init(tfa98xx); + + /* + * I2S settings to define the audio input properties + * these must be set before the subsys is up + * this will run the list until a non-register item is encountered + */ + ret = tfaContWriteRegsDev(tfa98xx); // write device register settings + + /* + * also write register the settings from the default profile + * NOTE we may still have ACS=1 so we can switch sample rate here + */ + ret = tfaContWriteRegsProf(tfa98xx, tfa98xx->profile); + + /* power on the sub system */ + ret = tfa98xx_powerdown(tfa98xx, 0); + +#ifndef VENDOR_EDIT + + tfa98xx_set_I2S2(tfa98xx); + + /* powered on + * - now it is allowed to access DSP specifics + */ + + /* + * wait until the DSP subsystem hardware is ready + * note that the DSP CPU is not running (RST=1) + */ + for (tries = 1; tries < CFSTABLE_TRIES; tries++) { + ret = tfa98xx_dsp_system_stable(tfa98xx, &status); + if (status) + break; + } + + if (tries == CFSTABLE_TRIES) { + pr_err("tfa98xx_dsp_system_stable Time out\n"); + return -ETIMEDOUT; + } else { + pr_debug("OK (tries=%d)\n", tries); + } + +#else +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-11, Modify for MTP repare*/ + /* NXP: This is not supposed to be here */ + //tfa98xx_set_I2S2(tfa98xx); + + /* NXP: Added the check of AREF before reset DSP */ + /* powered on + * - now check if it is allowed to access DSP specifics + */ + for (tries = 1; tries < CFSTABLE_TRIES; tries++) { + statusreg = (u16)snd_soc_read(codec, TFA98XX_STATUSREG); + if (statusreg & TFA98XX_STATUSREG_AREFS_MSK) + break; + else + msleep_interruptible(1); + } + + /* NXP: Added putting DSP to reset mode to start TFA in proper sequence */ + /* + * Reset Coolflux + */ + ret = tfa98xx_dsp_reset(tfa98xx,1); + if (ret) + pr_err("TFA set DSP to reset failed\n"); + + /* + * wait until the DSP subsystem hardware is ready + * note that the DSP CPU is not running (RST=1) + */ + for (tries = 0; tries < CFSTABLE_TRIES; tries++) { + ret = tfa98xx_dsp_system_stable(tfa98xx, &status); + if (status) + break; + else + msleep_interruptible(5); + } + + if (tries == CFSTABLE_TRIES) { + pr_err("tfa98xx_dsp_system_stable Time out\n"); + /* + * check the contents of MTP register for non-zero, + * this indicates that the subsys is ready + */ + mtp0 = (u16)snd_soc_read(codec, 0x84); + + /* NXP: if 0x84 is wrong, restore the correct mtp settings */ + if (!mtp0) + { + pr_err("mtp0 error.\n"); + tfa98xx_restore_i2cmtp(tfa98xx); + recoverMtp0 = true; + return 0; + } + + return -ETIMEDOUT; + } else { + pr_debug("OK (tries=%d)\n", tries); + } + + +#endif + + + + return 0; +} + +static int tfa98xx_is_coldboot(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + /* check status ACS bit to set */ + status = snd_soc_read(codec, TFA98XX_STATUSREG); + + return (status & TFA98XX_STATUSREG_ACS) != 0; +} + +/* + * report if we are in powerdown state + * use AREFS from the status register iso the actual PWDN bit + * return true if powered down + */ +int tfa98xx_is_pwdn(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + /* check if PWDN bit is clear by looking at AREFS */ + status = snd_soc_read(codec, TFA98XX_STATUSREG); + + return (status & TFA98XX_STATUSREG_AREFS) == 0; +} + +/* + * report if device has been calibrated + */ +int tfa98xx_is_calibrated(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + status = snd_soc_read(codec, TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP); + + return ((status & TFA98XX_KEY2_PROTECTED_SPKR_CAL_MTP_MTPEX) != 0); +} + +/* + * Disable DATAO + */ + void tfa98xx_disabledatao(struct tfa98xx *tfa98xx) +{ + + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + status = snd_soc_read(codec, TFA98XX_I2SREG); + + status &= ~TFA98XX_I2SREG_I2SDOE; + + snd_soc_write(codec, TFA98XX_I2SREG, status); +} + +/* + * Enable DATAO + */ + void tfa98xx_enabledatao(struct tfa98xx *tfa98xx) +{ + + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + status = snd_soc_read(codec, TFA98XX_I2SREG); + + status |= TFA98XX_I2SREG_I2SDOE; + + snd_soc_write(codec, TFA98XX_I2SREG, status); +} + +int tfa98xx_is_amp_running(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 status; + + /* check status SWS bit to set */ + status = snd_soc_read(codec, TFA98XX_STATUSREG); + + pr_debug("SWS %d\n", (status & TFA98XX_STATUSREG_SWS_MSK) != 0); + + return (status & TFA98XX_STATUSREG_SWS_MSK) != 0; +} + +#define CF_CONTROL 0x8100 + +int tfa98xx_coldboot(struct tfa98xx *tfa98xx, int state) +{ + int ret = 0; + int tries = 10; + + /* repeat set ACS bit until set as requested */ + while (state == !tfa98xx_is_coldboot(tfa98xx)) { + /* set coldstarted in CF_CONTROL to force ACS */ + ret = tfa98xx_dsp_write_mem(tfa98xx, CF_CONTROL, state, Tfa98xx_DMEM_IOMEM); + + if (tries-- == 0) { + pr_debug("coldboot (ACS) did not %s\n", state ? "set":"clear"); + return -EINVAL; + } + } + + return ret; +} + +/* + * powerup the coolflux subsystem and wait for it + */ +int tfa98xx_dsp_power_up(struct tfa98xx *tfa98xx) +{ + int ret = 0; + int tries, status; + +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-13, Modify for MTP repare*/ +u16 mtp0; +struct snd_soc_codec *codec = tfa98xx->codec; +#endif + + /* power on the sub system */ + ret = tfa98xx_powerdown(tfa98xx, 0); + +#ifndef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-13, Modify for dsp_system_stable*/ + // wait until everything is stable, in case clock has been off + for (tries = CFSTABLE_TRIES; tries > 0; tries--) { + ret = tfa98xx_dsp_system_stable(tfa98xx, &status); + if (status) + break; + } +#else + for (tries = CFSTABLE_TRIES; tries > 0; tries--) { + ret = tfa98xx_dsp_system_stable(tfa98xx, &status); + if (status) + break; + else + msleep_interruptible(5); + } +#endif + +#ifndef VENDOR_EDIT + if (tries==0) { + // timedout + pr_err("DSP subsystem start timed out\n"); + return -ETIMEDOUT; + } +#else +/*suzhiguang@MultiMedia.AudioDrv, 2015-08-13, Modify for MTP repare*/ + if (tries == 0) { + pr_err("tfa98xx_dsp_system_stable Time out\n"); + /* + * check the contents of MTP register for non-zero, + * this indicates that the subsys is ready + */ + mtp0 = (u16)snd_soc_read(codec, 0x84); + + /* NXP: if 0x84 is wrong, restore the correct i2cmtp settings */ + if (!mtp0) + { + pr_err("mtp0 error.\n"); + tfa98xx_restore_i2cmtp(tfa98xx); + recoverMtp0 = true; + return 0; + } + + return -ETIMEDOUT; + } else { + pr_debug("OK (tries=%d)\n", tries); + } + +#endif + + + return ret; +} + +/* + * the patch contains a header with the following + * IC revision register: 1 byte, 0xFF means don't care + * XMEM address to check: 2 bytes, big endian, 0xFFFF means don't care + * XMEM value to expect: 3 bytes, big endian + */ +int tfa98xx_check_ic_rom_version(struct tfa98xx *tfa98xx, const u8 patchheader[]) +{ + int ret = 0; + u16 checkrev; + u16 checkaddress; + int checkvalue; + int value = 0; + int status; + + checkrev = patchheader[0]; + if ((checkrev != 0xff) && (checkrev != tfa98xx->rev)) + return -EINVAL; + + checkaddress = (patchheader[1] << 8) + patchheader[2]; + checkvalue = (patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5]; + + if (checkaddress != 0xffff) { + /* before reading XMEM, check if we can access the DSP */ + ret = tfa98xx_dsp_system_stable(tfa98xx, &status); + if (!ret) { + if (!status) { + /* DSP subsys not running */ + ret = -EBUSY; + } + } + + /* read register to check the correct ROM version */ + if (!ret) { + ret = tfa98xx_dsp_read_mem(tfa98xx, checkaddress, 1, &value); + } + + if (!ret) { + if (value != checkvalue) + ret = -EINVAL; + } + } + + return ret; +} + + +int tfa98xx_process_patch_file(struct tfa98xx *tfa98xx, int len, const u8 *data) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 size; + int index; + int ret = 0; + u8 chunk_buf[TFA98XX_MAX_I2C_SIZE + 1]; + + /* + * expect following format in patchBytes: + * 2 bytes len of I2C transaction in little endian, then the bytes, + * excluding the slave address which is added from the handle + * This repeats for the whole file + */ + index = 0; + while (index < len) { + /* extract little endian length */ + size = data[index] + data[index + 1] * 256; + if (size > TFA98XX_MAX_I2C_SIZE) { + pr_err("Patch chunk size %d > %d\n", size, TFA98XX_MAX_I2C_SIZE); + } + + index += 2; + + if ((index + size) > len) { + /* outside the buffer, error in the input data */ + return -EINVAL; + } + + /* + * Need to copy data from the fw into local memory to avoid + * trouble with some i2c controller + */ + memcpy(chunk_buf, data + index, size); + + ret = tfa98xx_bulk_write_raw(codec, chunk_buf, size); + if (ret) { + pr_err("writing dsp patch failed %d\n", ret); + break; + } + + index += size; + } + + return ret; +} + +#define PATCH_HEADER_LENGTH 6 +int tfa98xx_dsp_patch(struct tfa98xx *tfa98xx, int patchLength, const u8 *patchBytes) +{ + int ret = 0; + + if (patchLength < PATCH_HEADER_LENGTH) + return -EINVAL; + + ret = tfa98xx_check_ic_rom_version(tfa98xx, patchBytes); + if (ret) { + pr_err("ERROR: %d\n", ret); + return ret; + + } + + ret = tfa98xx_process_patch_file(tfa98xx, patchLength - PATCH_HEADER_LENGTH, patchBytes + PATCH_HEADER_LENGTH); + return ret; +} + + +int tfa98xx_set_configured(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + /* read the SystemControl register, modify the bit and write again */ + value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + value |= TFA98XX_SYS_CTRL_SBSL_MSK; + snd_soc_write(codec, TFA98XX_SYS_CTRL, value); + + return 0; +} + +int tfa98xx_set_I2S2(struct tfa98xx *tfa98xx) +{ + #if 0 + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + + pr_debug("\n"); + + /* read the SystemControl register, modify the bit and write again */ + value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + value |= (0x1<<13); + snd_soc_write(codec, TFA98XX_SYS_CTRL, value); + +pr_err("%s value=%x\n",__func__,value); +#endif + return 0; +} + + +#define TO_LONG_LONG(x) ((s64)(x)<<32) +#define TO_INT(x) ((x)>>32) +#define TO_FIXED(e) e + +int float_to_int(u32 x) +{ + unsigned e = (0x7F + 31) - ((* (unsigned*) &x & 0x7F800000) >> 23); + unsigned m = 0x80000000 | (* (unsigned*) &x << 8); + return (int)((m >> e) & -(e < 32)); +} + +int tfa98xx_set_volume(struct tfa98xx *tfa98xx, u32 voldB) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + u16 value; + int volume_value; + + value = snd_soc_read(codec, TFA98XX_AUDIO_CTR); + + /* + * 0x00 -> 0.0 dB + * 0x01 -> -0.5 dB + * ... + * 0xFE -> -127dB + * 0xFF -> muted + */ + volume_value = 2 * float_to_int(voldB); + if (volume_value > 255) + volume_value = 255; + + /* volume value is in the top 8 bits of the register */ + value = (value & 0x00FF) | (u16)(volume_value << 8); + snd_soc_write(codec, TFA98XX_AUDIO_CTR, value); + + return 0; +} + + +int tfa98xx_get_volume(struct tfa98xx *tfa98xx, s64 *pVoldB) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 value; + + value = snd_soc_read(codec, TFA98XX_AUDIO_CTR); + value >>= 8; + *pVoldB = TO_FIXED(value) / -2; + + return ret; +} + + +static int tfa98xx_set_mute(struct tfa98xx *tfa98xx, enum Tfa98xx_Mute mute) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 audioctrl_value; + u16 sysctrl_value; + + audioctrl_value = snd_soc_read(codec, TFA98XX_AUDIO_CTR); + sysctrl_value = snd_soc_read(codec, TFA98XX_SYS_CTRL); + + switch (mute) { + case Tfa98xx_Mute_Off: + /* + * previous state can be digital or amplifier mute, + * clear the cf_mute and set the enbl_amplifier bits + * + * To reduce PLOP at power on it is needed to switch the + * amplifier on with the DCDC in follower mode + * (enbl_boost = 0 ?). + * This workaround is also needed when toggling the + * powerdown bit! + */ + audioctrl_value &= ~(TFA98XX_AUDIO_CTR_CFSM_MSK); + sysctrl_value |= (TFA98XX_SYS_CTRL_AMPE_MSK | TFA98XX_SYS_CTRL_DCA_MSK); + break; + case Tfa98xx_Mute_Digital: + /* set the cf_mute bit */ + audioctrl_value |= TFA98XX_AUDIO_CTR_CFSM_MSK; + /* set the enbl_amplifier bit */ + sysctrl_value |= (TFA98XX_SYS_CTRL_AMPE_MSK); + /* clear active mode */ + sysctrl_value &= ~(TFA98XX_SYS_CTRL_DCA_MSK); + break; + case Tfa98xx_Mute_Amplifier: + /* clear the cf_mute bit */ + audioctrl_value &= ~TFA98XX_AUDIO_CTR_CFSM_MSK; + /* clear the enbl_amplifier bit and active mode */ + sysctrl_value &= ~(TFA98XX_SYS_CTRL_AMPE_MSK | TFA98XX_SYS_CTRL_DCA_MSK); + break; + default: + return -EINVAL; + } + + ret = snd_soc_write(codec, TFA98XX_AUDIO_CTR, audioctrl_value); + if (ret) + return ret; + + ret = snd_soc_write(codec, TFA98XX_SYS_CTRL, sysctrl_value); + return ret; +} + + +int tfa98xx_mute(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 status; + int tries = 0; + + /* signal the TFA98XX to mute plop free and turn off the amplifier */ + ret = tfa98xx_set_mute(tfa98xx, Tfa98xx_Mute_Amplifier); + if (ret) + return ret; + + /* now wait for the amplifier to turn off */ + status = snd_soc_read(codec, TFA98XX_STATUSREG); + while (((status & TFA98XX_STATUSREG_SWS) == TFA98XX_STATUSREG_SWS) && (tries < TFA98XX_WAITRESULT_NTRIES)) + { + usleep_range(10000, 10000); + status = snd_soc_read(codec, TFA98XX_STATUSREG); + tries++; + } + + /* The amplifier is always switching */ + if (tries == TFA98XX_WAITRESULT_NTRIES) + return -ETIMEDOUT; + + pr_debug("-------------------- muted --------------------\n"); + + return 0; +} + + +int tfa98xx_unmute(struct tfa98xx *tfa98xx) +{ + int ret = 0; + + /* signal the TFA98XX to mute */ + ret = tfa98xx_set_mute(tfa98xx, Tfa98xx_Mute_Off); + + pr_debug("-------------------unmuted ------------------\n"); + + return ret; +} + + +/* check that num_byte matches the memory type selected */ +int tfa98xx_check_size(enum Tfa98xx_DMEM which_mem, int len) +{ + int ret = 0; + int modulo_size = 1; + + switch (which_mem) { + case Tfa98xx_DMEM_PMEM: + /* 32 bit PMEM */ + modulo_size = 4; + break; + case Tfa98xx_DMEM_XMEM: + case Tfa98xx_DMEM_YMEM: + case Tfa98xx_DMEM_IOMEM: + /* 24 bit MEM */ + modulo_size = 3; + break; + default: + return -EINVAL; + } + + if ((len % modulo_size) != 0) + return -EINVAL; + + return ret; +} + + +int tfa98xx_execute_param(struct tfa98xx *tfa98xx) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + + /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, + * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + u16 cf_ctrl = 0x0002; + cf_ctrl |= (1 << 8) | (1 << 4); /* set the cf_req1 and cf_int bit */ + return snd_soc_write(codec, TFA98XX_CF_CONTROLS, cf_ctrl); +} + +int tfa98xx_wait_result(struct tfa98xx *tfa98xx, int waitRetryCount) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + u16 cf_status; /* the contents of the CF_STATUS register */ + int tries = 0; + + /* don't wait forever, DSP is pretty quick to respond (< 1ms) */ + do { + cf_status = snd_soc_read(codec, TFA98XX_CF_STATUS); + tries++; + } while ((!ret) && ((cf_status & 0x0100) == 0) + && (tries < waitRetryCount)); + if (tries >= waitRetryCount) { + /* something wrong with communication with DSP */ + pr_err("Error DSP not running\n"); + return -EINVAL; + } + + return 0; +} + + +/* read the return code for the RPC call */ +int tfa98xx_check_rpc_status(struct tfa98xx *tfa98xx, int *status) +{ + int ret = 0; + /* the value to sent to the * CF_CONTROLS register: cf_req=00000000, + * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + u16 cf_ctrl = 0x0002; + /* memory address to be accessed (0: Status, 1: ID, 2: parameters) */ + u16 cf_mad = 0x0000; + u8 mem[3]; /* for the status read from DSP memory */ + u8 buffer[4]; + + /* minimize the number of I2C transactions by making use + * of the autoincrement in I2C */ + /* first the data for CF_CONTROLS */ + buffer[0] = (u8)((cf_ctrl >> 8) & 0xFF); + buffer[1] = (u8)(cf_ctrl & 0xFF); + /* write the contents of CF_MAD which is the subaddress + * following CF_CONTROLS */ + buffer[2] = (u8)((cf_mad >> 8) & 0xFF); + buffer[3] = (u8)(cf_mad & 0xFF); + + ret = tfa98xx_write_data(tfa98xx, TFA98XX_CF_CONTROLS, sizeof(buffer), buffer); + if (ret) + return ret; + + /* read 1 word (24 bit) from XMEM */ + ret = tfa98xx_read_data(tfa98xx, TFA98XX_CF_MEM, 3 /* sizeof(mem) */, mem); + if (ret) + return ret; + + *status = mem[0] << 16 | mem[1] << 8 | mem[2]; + + return 0; +} + +int tfa98xx_write_parameter(struct tfa98xx *tfa98xx, + u8 module_id, + u8 param_id, + int len, const u8 data[]) +{ + int ret; + /* + * the value to be sent to the CF_CONTROLS register: cf_req=00000000, + * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 + */ + u16 cf_ctrl = 0x0002; + /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters)*/ + u16 cf_mad = 0x0001; + u8 buffer[7]; + int offset = 0; + int chunk_size = ROUND_DOWN(TFA98XX_MAX_I2C_SIZE, 3); /* XMEM word size */ + int remaining_bytes = len; + + ret = tfa98xx_check_size(Tfa98xx_DMEM_XMEM, len); + if (!ret) { + if ((len <= 0) || (len > MAX_PARAM_SIZE)) { + pr_err("Error in parameters size\n"); + return -EINVAL; + } + } + + /* + * minimize the number of I2C transactions by making use of + * the autoincrement in I2C + */ + + /* first the data for CF_CONTROLS */ + buffer[0] = (u8)((cf_ctrl >> 8) & 0xFF); + buffer[1] = (u8)(cf_ctrl & 0xFF); + /* + * write the contents of CF_MAD which is the subaddress + * following CF_CONTROLS + */ + buffer[2] = (u8)((cf_mad >> 8) & 0xFF); + buffer[3] = (u8)(cf_mad & 0xFF); + /* + * write the module and RPC id into CF_MEM, which + * follows CF_MAD + */ + buffer[4] = 0; + buffer[5] = module_id + 128; + buffer[6] = param_id; + + ret = tfa98xx_write_data(tfa98xx, TFA98XX_CF_CONTROLS, sizeof(buffer), buffer); + if (ret) + return ret; + + /* + * Thanks to autoincrement in cf_ctrl, next write will + * happen at the next address + */ + while ((!ret) && (remaining_bytes > 0)) { + if (remaining_bytes < chunk_size) + chunk_size = remaining_bytes; + + ret = tfa98xx_write_data(tfa98xx, TFA98XX_CF_MEM, chunk_size, data + offset); + + remaining_bytes -= chunk_size; + offset += chunk_size; + } + + return ret; +} + + +/* Execute RPC protocol to write something to the DSP */ +int tfa98xx_dsp_set_param_var_wait(struct tfa98xx *tfa98xx, + u8 module_id, + u8 param_id, int len, + const u8 data[], int waitRetryCount) +{ + int ret = 0; + int status = 0; + + /* 1) write the id and data to the DSP XMEM */ + ret = tfa98xx_write_parameter(tfa98xx, module_id, param_id, len, data); + if (ret) + return ret; + + /* 2) wake up the DSP and let it process the data */ + ret = tfa98xx_execute_param(tfa98xx); + if (ret) + return ret; + + /* 3) wait for the ack */ + ret = tfa98xx_wait_result(tfa98xx, waitRetryCount); + if (ret) + return ret; + + /* 4) check the RPC return value */ + ret = tfa98xx_check_rpc_status(tfa98xx, &status); + if (ret) + return ret; + + if (status) { + /* DSP RPC call returned an error */ + pr_err("DSP RPC error %d\n", status + ERROR_RPC_BASE); + return -EIO; + } + + return ret; +} + +/* Execute RPC protocol to write something to the DSP */ +int tfa98xx_dsp_set_param(struct tfa98xx *tfa98xx, u8 module_id, + u8 param_id, int len, + const u8 *data) +{ + /* Use small WaitResult retry count */ + return tfa98xx_dsp_set_param_var_wait(tfa98xx, module_id, param_id, + len, data, + TFA98XX_WAITRESULT_NTRIES); +} + + +int tfa98xx_dsp_write_config(struct tfa98xx *tfa98xx, int len, const u8 *data) +{ + int ret = 0; + int has_drc = 0; + + ret = tfa98xx_dsp_set_param(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_SET_CONFIG, len, data); + if (ret) + return ret; + + ret = tfa98xx_dsp_support_drc(tfa98xx, &has_drc); + if (ret) + return ret; + + if (has_drc) { + /* + * Need to set AgcGainInsert back to PRE, as + * the SetConfig forces it to POST + */ + ret = tfa98xx_dsp_set_agc_gain_insert(tfa98xx, Tfa98xx_AgcGainInsert_PreDrc); + } + + return ret; +} + + +/* the number of biquads supported */ +#define TFA98XX_BIQUAD_NUM 10 +#define BIQUAD_COEFF_SIZE 6 + +int tfa98xx_dsp_biquad_disable(struct tfa98xx *tfa98xx, int biquad_index) +{ + int coeff_buffer[BIQUAD_COEFF_SIZE]; + u8 data[BIQUAD_COEFF_SIZE * 3]; + + if (biquad_index > TFA98XX_BIQUAD_NUM) + return -EINVAL; + + if (biquad_index < 1) + return -EINVAL; + + /* set in correct order and format for the DSP */ + coeff_buffer[0] = (int) - 8388608; /* -1.0f */ + coeff_buffer[1] = 0; + coeff_buffer[2] = 0; + coeff_buffer[3] = 0; + coeff_buffer[4] = 0; + coeff_buffer[5] = 0; + + /* + * convert to fixed point and then bytes suitable for + * transmission over I2C + */ + tfa98xx_convert_data2bytes(BIQUAD_COEFF_SIZE, coeff_buffer, data); + return tfa98xx_dsp_set_param(tfa98xx, MODULE_BIQUADFILTERBANK, + (u8)biquad_index, + (u8)(BIQUAD_COEFF_SIZE * 3), + data); +} + +int tfa98xx_dsp_biquad_set_coeff(struct tfa98xx *tfa98xx, int biquad_index, + int len, u8* data) +{ + return tfa98xx_dsp_set_param(tfa98xx, MODULE_BIQUADFILTERBANK, + biquad_index, len, data); +} + +/* + * The AgcGainInsert functions are static because they are not public: + * only allowed mode is PRE. + * The functions are nevertheless needed because the mode is forced to + * POST by each SetLSmodel and each SetConfig => it should be reset to + * PRE afterwards. + */ +int tfa98xx_dsp_set_agc_gain_insert(struct tfa98xx *tfa98xx, + enum Tfa98xx_AgcGainInsert + agcGainInsert) +{ + int ret = 0; + unsigned char bytes[3]; + + tfa98xx_convert_data2bytes(1, (int *) &agcGainInsert, bytes); + + ret = tfa98xx_dsp_set_param(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_SET_AGCINS, 3, bytes); + + return ret; +} + + +int tfa98xx_dsp_write_speaker_parameters(struct tfa98xx *tfa98xx, int len, + const u8 *data) +{ + int ret = 0; + int has_drc = 0; + + if (!data) + return -EINVAL; + + ret = tfa98xx_dsp_set_param_var_wait(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_SET_LSMODEL, len, + data, + TFA98XX_WAITRESULT_NTRIES_LONG); + if (ret) + return ret; + + ret = tfa98xx_dsp_support_drc(tfa98xx, &has_drc); + if (ret) + return ret; + + if (has_drc) { + /* + * Need to set AgcGainInsert back to PRE, as + * the SetConfig forces it to POST + */ + ret = tfa98xx_dsp_set_agc_gain_insert(tfa98xx, Tfa98xx_AgcGainInsert_PreDrc); + } + + return ret; +} + + +int tfa98xx_dsp_write_preset(struct tfa98xx *tfa98xx, int len, const u8 *data) +{ + if (!data) + return -EINVAL; + + return tfa98xx_dsp_set_param(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_SET_PRESET, len, data); +} + +/* load all the parameters for the DRC settings from a file */ +int tfa98xx_dsp_write_drc(struct tfa98xx *tfa98xx, int len, const u8 *data) +{ + if (!data) + return -EINVAL; + + return tfa98xx_dsp_set_param(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_SET_DRC, len, data); +} + + +/* Execute RPC protocol to read something from the DSP */ +int tfa98xx_dsp_get_param(struct tfa98xx *tfa98xx, u8 module_id, + u8 param_id, int len, u8 *data) +{ + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, + * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ + u16 cf_ctrl = 0x0002; + /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters)*/ + u16 cf_mad = 0x0001; + u16 cf_status; + int status = 0; + int offset = 0; + int chunk_size = ROUND_DOWN(TFA98XX_MAX_I2C_SIZE, 3 /* XMEM word size */ ); + int remaining_bytes = len; + int tries = 0; + u8 buffer[7]; + + ret = tfa98xx_check_size(Tfa98xx_DMEM_XMEM, len); + if (!ret) { + if ((len <= 0) || (len > MAX_PARAM_SIZE)) + return -EINVAL; + } + + /* + * minimize the number of I2C transactions by making use of + * the autoincrement in I2C + */ + + /* first the data for CF_CONTROLS */ + buffer[0] = (u8)((cf_ctrl >> 8) & 0xFF); + buffer[1] = (u8)(cf_ctrl & 0xFF); + /* write the contents of CF_MAD which is the subaddress + * following CF_CONTROLS */ + buffer[2] = (u8)((cf_mad >> 8) & 0xFF); + buffer[3] = (u8)(cf_mad & 0xFF); + /* write the module and RPC id into CF_MEM, + * which follows CF_MAD */ + buffer[4] = 0; + buffer[5] = module_id + 128; + buffer[6] = param_id; + + ret = tfa98xx_write_data(tfa98xx, TFA98XX_CF_CONTROLS, + sizeof(buffer), buffer); + + /* 2) wake up the DSP and let it process the data */ + /* set the cf_req1 and cf_int bit */ + cf_ctrl |= (1 << 8) | (1 << 4); + ret = snd_soc_write(codec, TFA98XX_CF_CONTROLS, cf_ctrl); + + /* 3) wait for the ack */ + do { + cf_status = snd_soc_read(codec, TFA98XX_CF_STATUS); + tries++; + /* don't wait forever, DSP is pretty quick to respond (< 1ms)*/ + } while ((!ret) + && ((cf_status & 0x0100) == 0) + && (tries < TFA98XX_WAITRESULT_NTRIES)); + + if (tries >= TFA98XX_WAITRESULT_NTRIES) { + /* something wrong with communication with DSP */ + return -ETIMEDOUT; + } + + /* 4) check the RPC return value */ + ret = tfa98xx_check_rpc_status(tfa98xx, &status); + if (ret) + return ret; + + if (status) { + /* DSP RPC call returned an error + * Note: when checking for features and a features + * is not supported on a device, it returns ERROR_RPC_PARAMID + */ + pr_warn("DSP RPC error %d\n", status + ERROR_RPC_BASE); + return -EIO; + } + + /* 5) read the resulting data */ + /* memory address to be accessed (0: Status, + * 1: ID, 2: parameters) */ + cf_mad = 0x0002; + snd_soc_write(codec, TFA98XX_CF_MAD, cf_mad); + + /* due to autoincrement in cf_ctrl, next write will happen at + * the next address */ + while ((!ret) && (remaining_bytes > 0)) { + if (remaining_bytes < TFA98XX_MAX_I2C_SIZE) + chunk_size = remaining_bytes; + + /* else chunk_size remains at initialize value above */ + ret = tfa98xx_read_data(tfa98xx, TFA98XX_CF_MEM, chunk_size, + data + offset); + remaining_bytes -= chunk_size; + offset += chunk_size; + } + + return ret; +} + + +int tfa98xx_dsp_get_sw_feature_bits(struct tfa98xx *tfa98xx, int features[2]) +{ + int ret = 0; + unsigned char bytes[3 * 2]; + + ret = tfa98xx_dsp_get_param(tfa98xx, MODULE_FRAMEWORK, + FW_PARAM_GET_FEATURE_BITS, sizeof(bytes), + bytes); + /* old ROM code may respond with ERROR_RPC_PARAMID -> -EIO */ + if (ret) + return ret; + + tfa98xx_convert_bytes2data(sizeof(bytes), bytes, features); + + return ret; +} + + +int tfa98xx_dsp_support_drc(struct tfa98xx *tfa98xx, int *has_drc) +{ + int ret = 0; + *has_drc = 0; + + if (tfa98xx->has_drc) { + *has_drc = tfa98xx->has_drc; + } else { + int features[2]; + + ret = tfa98xx_dsp_get_sw_feature_bits(tfa98xx, features); + if (!ret) { + /* easy case: new API available */ + /* bit=0 means DRC enabled */ + *has_drc = (features[0] & FEATURE1_DRC) == 0; + } else if (ret == -EIO) { + /* older ROM code, doesn't support it */ + *has_drc = 0; + ret = 0; + } + /* else some other ret, return transparently */ + + if (!ret) { + tfa98xx->has_drc = *has_drc; + } + } + return ret; +} + +int tfa98xx_resolve_incident(struct tfa98xx *tfa98xx) +{ + if (tfa98xx->rev == REV_TFA9897) { + pr_warn("OCDS TFA9897 trigger\n"); + /* TFA9897 need to reset the DSP to take the newly set re0 */ + tfa98xx_dsp_reset(tfa98xx, 1); + tfa98xx_dsp_reset(tfa98xx, 0); + } else { + /* TFA98xx need power cycle */ + tfa98xx_powerdown(tfa98xx, 1); + tfa98xx_powerdown(tfa98xx, 0); + } + + return 0; +} + +int tfa98xx_dsp_get_calibration_impedance(struct tfa98xx *tfa98xx, u32 *re25) +{ + int ret = 0; + u8 bytes[3]; + int data[1]; + int done; + + ret = tfa98xx_dsp_read_mem(tfa98xx, TFA98XX_XMEM_CALIBRATION_DONE, 1, &done); + if (ret) + return ret; + + if (!done) { + pr_err("Calibration not done %d\n", done); + return -EINVAL; + } + + ret = tfa98xx_dsp_get_param(tfa98xx, MODULE_SPEAKERBOOST, + SB_PARAM_GET_RE0, 3, bytes); + + tfa98xx_convert_bytes2data(3, bytes, data); + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-05-29, change for calibration*/ + /* /2^23*2^(def.SPKRBST_TEMPERATURE_EXP) */ + *re25 = (TO_FIXED(data[0]) *1000) / (1 << (23 - SPKRBST_TEMPERATURE_EXP)); +#endif + return ret; +} + +/* + * the int24 values for the vsfw delay table + */ +static u8 vsfwdelay_table[] = { + 0,0,2, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0,0,0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0,0,0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0,0,0, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0,0,0, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0,0,0, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0,0,0, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0,0,0, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0,0,3 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +static int tfa9897_dsp_write_vsfwdelay_table(struct tfa98xx *tfa98xx) +{ + return tfa98xx_dsp_set_param(tfa98xx, MODULE_FRAMEWORK, + FW_PARAM_SET_CURRENT_DELAY, sizeof(vsfwdelay_table), + vsfwdelay_table); +} + +/* + * The int24 values for the fracdelay table + * For now applicable only for 8 and 48 kHz + */ +static u8 cvfracdelay_table[] = { + 0,0,51, /* Index 0 - Current/Volt Fractional Delay for 8KHz */ + 0,0,0, /* Index 1 - Current/Volt Fractional Delay for 11KHz */ + 0,0,0, /* Index 2 - Current/Volt Fractional Delay for 12KHz */ + 0,0,0, /* Index 3 - Current/Volt Fractional Delay for 16KHz */ + 0,0,0, /* Index 4 - Current/Volt Fractional Delay for 22KHz */ + 0,0,0, /* Index 5 - Current/Volt Fractional Delay for 24KHz */ + 0,0,0, /* Index 6 - Current/Volt Fractional Delay for 32KHz */ + 0,0,0, /* Index 7 - Current/Volt Fractional Delay for 44KHz */ + 0,0,62 /* Index 8 - Current/Volt Fractional Delay for 48KHz */ +}; + +static int tfa9897_dsp_write_cvfracdelay_table(struct tfa98xx *tfa98xx) +{ + return tfa98xx_dsp_set_param(tfa98xx, MODULE_FRAMEWORK, + FW_PARAM_SET_CURFRAC_DELAY, sizeof(cvfracdelay_table), + cvfracdelay_table); +} + +/* + * load the tables to the DSP, called after patch load is done + */ +int tfa98xx_dsp_write_tables(struct tfa98xx *tfa98xx) +{ + int ret = 0; ; + + if (tfa98xx->rev == REV_TFA9897) { + ret = tfa9897_dsp_write_vsfwdelay_table(tfa98xx); + if (!ret) { + ret = tfa9897_dsp_write_cvfracdelay_table(tfa98xx); + } + } + + return ret; +} + +/* + * this will load the patch witch will implicitly start the DSP + * if no patch is available the DPS is started immediately + */ +static int tfaRunStartDSP(struct tfa98xx *tfa98xx) +{ + int ret; + + ret = tfaContWritePatch(tfa98xx); + if (ret) + return ret; + + ret = tfa98xx_dsp_write_tables(tfa98xx); + + return ret; +} + + + +/* + * Run the startup/init sequence and set ACS bit + */ +int tfaRunColdStartup(struct tfa98xx *tfa98xx) +{ + int ret; + + ret = tfa98xx_startup(tfa98xx); + if (ret) + return ret; + + /* force cold boot */ + ret = tfa98xx_coldboot(tfa98xx, 1); // set ACS + if (ret) + return ret; + + ret = tfaRunStartDSP(tfa98xx); + + return ret; +} + + +static int coldboot = 0; +module_param(coldboot, int, S_IRUGO | S_IWUSR); + +/* + * Start the maximus speakerboost algorithm this implies a full system + * startup when the system was not already started. + */ + + +int setOtc(struct tfa98xx *tfa98xx, int otcOn) +{ +// Tfa98xx_Error_t err = Tfa98xx_Error_Ok; + struct snd_soc_codec *codec = tfa98xx->codec; + int ret = 0; + int tries = 0; + u16 status; + u16 mtp; + + //err = Tfa98xx_ReadRegister16(handle, TFA98XX_MTP, &mtp); + mtp = snd_soc_read(codec, TFA98XX_MTP); + //assert(err == Tfa98xx_Error_Ok); + +// assert((otcOn == 0) || (otcOn == 1) ); + + /* set reset MTPEX bit if needed */ + if ( (mtp & TFA98XX_MTP_MTPOTC) != otcOn) + { + /* need to change the OTC bit, set MTPEX=0 in any case */ + //err = Tfa98xx_WriteRegister16(handle, 0x0B, 0x5A); /* unlock key2 */ + snd_soc_write(codec, 0x0B, 0x5A); + //assert(err == Tfa98xx_Error_Ok); + + // err = Tfa98xx_WriteRegister16(handle, TFA98XX_MTP, (unsigned short)otcOn); /* MTPOTC=otcOn, MTPEX=0 */ + snd_soc_write(codec, TFA98XX_MTP, (unsigned short)otcOn); + //assert(err == Tfa98xx_Error_Ok); + //err = Tfa98xx_WriteRegister16(handle, 0x62, 1<<11); /* CIMTP=1 */ + snd_soc_write(codec, 0x62, 1<<11); + //assert(err == Tfa98xx_Error_Ok); + +// mtpChanged =1; + + + //Sleep(13*16); /* need to wait until all parameters are copied into MTP */ + do + { + //err = Tfa98xx_ReadRegister16(handle, TFA98XX_STATUSREG, &status); + status = snd_soc_read(codec, TFA98XX_STATUSREG); + if((status & TFA98XX_STATUSREG_MTPB_MSK) == TFA98XX_STATUSREG_MTPB_MSK) { + tries++; + //Sleep(10); + msleep_interruptible(10); + } else { + break; + } + } while (tries < 300); + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-05-29, add for calibration*/ + snd_soc_write(codec, 0x0B, 0x0); +#endif + if( (status & TFA98XX_STATUSREG_MTPB_MSK) != 0) { + } + + } + + return ret; + +} + + + + +int tfaRunSpeakerBoost(struct tfa98xx *tfa98xx, int force) +{ + int ret = 0; + u32 re25; + int done = 0; + + if (force) { + ret = tfaRunColdStartup(tfa98xx); + if (ret) + return ret; + /* DSP is running now */ + } + + if (force || tfa98xx_is_coldboot(tfa98xx)) { + //int done; + + pr_debug("coldstart%s\n", force ? " (forced)" : ""); + + /* in case of force CF already runnning */ + if (!force) { + ret = tfa98xx_startup(tfa98xx); + if (ret) { + pr_err("tfa98xx_startup %d\n", ret); + return ret; + } + + /* load patch and start the DSP */ + ret = tfaRunStartDSP(tfa98xx); + } + + setOtc(tfa98xx,1); + + /* + * DSP is running now + * NOTE that ACS may be active + * no DSP reset/sample rate may be done until configured (SBSL) + */ + + /* soft mute */ + ret = tfa98xx_set_mute(tfa98xx, Tfa98xx_Mute_Digital); + if (ret) { + pr_err("Tfa98xx_SetMute error: %d\n", ret); + return ret; + } + + /* + * For the first configuration the DSP expects at least + * the speaker, config and a preset. + * Therefore all files from the device list as well as the file + * from the default profile are loaded before SBSL is set. + * + * Note that the register settings were already done before loading the patch + * + * write all the files from the device list (typically spk and config) + */ + ret = tfaContWriteFiles(tfa98xx); + if (ret) { + pr_err("tfaContWriteFiles error: %d\n", ret); + return ret; + } + + /* + * write all the files from the profile list (typically preset) + * use volumestep 0 + */ + tfaContWriteFilesProf(tfa98xx, 0, 0); + + /* tell DSP it's loaded SBSL = 1 */ + ret = tfa98xx_set_configured(tfa98xx); + if (ret) { + pr_err("tfa98xx_set_configured error: %d\n", ret); + return ret; + } + + tfa98xx_set_I2S2(tfa98xx); + + /* await calibration, this should return ok */ + tfa98xx_wait_calibration(tfa98xx, &done); + if (!done) { + pr_err("Calibration not done!\n"); + /* + * Don't return on timeout, otherwise we cannot power + * down the DSP + */ + } else { + pr_info("Calibration done\n"); + } + + } else { + /* already warm, so just pwr on */ + ret = tfa98xx_dsp_power_up(tfa98xx); + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-22,add to avoid sound failed*/ + done = 1; +#endif + } + + tfa98xx_dsp_get_calibration_impedance(tfa98xx, &re25); + pr_debug("imp: %d ohms\n", re25); + +#ifndef VENDOR_EDIT + //zhiguang.su change by nxp + //Check if device has been calibrated + if (!tfa98xx_is_calibrated(tfa98xx)){ + pr_err("Not calibrated, power down devcie\n"); + ret = tfa98xx_powerdown(tfa98xx, 1); + if (ret) + return ret; + + return -EINVAL; + } +#else + //Check if device has been calibrated + if (!done){ + pr_err("Not calibrated, power down devcie\n"); + ret = tfa98xx_powerdown(tfa98xx, 1); + if (ret) + return ret; + + return -EINVAL; + } +#endif + + tfa98xx_set_I2S2(tfa98xx); + + tfa98xx_unmute(tfa98xx); + + return ret; +} + +int tfaRunSpeakerQuickBoost(struct tfa98xx *tfa98xx, int force) +{ + int ret = 0; + //u32 re25; + int done; + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-18,avoid pop */ + tfa98xx_set_mute(tfa98xx, Tfa98xx_Mute_Digital); +#endif + + + if (force) { + ret = tfaRunColdStartup(tfa98xx); + if (ret) + return ret; + /* DSP is running now */ + } + + if (force || tfa98xx_is_coldboot(tfa98xx)) { + //int done; + + pr_debug("coldstart%s\n", force ? " (forced)" : ""); + + /* in case of force CF already runnning */ + if (!force) { + ret = tfa98xx_startup(tfa98xx); + if (ret) { + pr_err("tfa98xx_startup %d\n", ret); + return ret; + } + + /* load patch and start the DSP */ + ret = tfaRunStartDSP(tfa98xx); + } + + setOtc(tfa98xx,1); + + /* + * DSP is running now + * NOTE that ACS may be active + * no DSP reset/sample rate may be done until configured (SBSL) + */ + + /* soft mute */ + ret = tfa98xx_set_mute(tfa98xx, Tfa98xx_Mute_Digital); + if (ret) { + pr_err("Tfa98xx_SetMute error: %d\n", ret); + return ret; + } + + /* + * For the first configuration the DSP expects at least + * the speaker, config and a preset. + * Therefore all files from the device list as well as the file + * from the default profile are loaded before SBSL is set. + * + * Note that the register settings were already done before loading the patch + * + * write all the files from the device list (typically spk and config) + */ + ret = tfaContWriteFiles(tfa98xx); + if (ret) { + pr_err("tfaContWriteFiles error: %d\n", ret); + return ret; + } + + /* + * write all the files from the profile list (typically preset) + * use volumestep 0 + */ + tfaContWriteFilesProf(tfa98xx, 0, 0); + + /* tell DSP it's loaded SBSL = 1 */ + ret = tfa98xx_set_configured(tfa98xx); + if (ret) { + pr_err("tfa98xx_set_configured error: %d\n", ret); + return ret; + } + + /* await calibration, this should return ok */ + tfa98xx_wait_calibration(tfa98xx, &done); + if (!done) { + pr_err("Calibration not done!\n"); + /* + * Don't return on timeout, otherwise we cannot power + * down the DSP + */ + } else { + pr_info("Calibration done\n"); + } + + } else { + /* already warm, so just pwr on */ + ret = tfa98xx_dsp_power_up(tfa98xx); + } + +// tfa98xx_dsp_get_calibration_impedance(tfa98xx, &re25); +// pr_debug("imp: %d ohms\n", re25); + +//#ifndef VENDOR_EDIT +#if 1 + //zhiguang.su change by nxp + //Check if device has been calibrated + if (!tfa98xx_is_calibrated(tfa98xx)){ + pr_err("Not calibrated, power down devcie\n"); + ret = tfa98xx_powerdown(tfa98xx, 1); + if (ret) + return ret; + + return -EINVAL; + } +#else + //Check if device has been calibrated + if (!done){ + pr_err("Not calibrated, power down devcie\n"); + ret = tfa98xx_powerdown(tfa98xx, 1); + if (ret) + return ret; + + return -EINVAL; + } +#endif + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-18,avoid pop */ +// tfa98xx_unmute(tfa98xx); +#endif + + return ret; +} + + +int tfa98xx_dsp_quickstart(struct tfa98xx *tfa98xx, int profile, int vstep) +{ + int forcecoldboot = coldboot; + + if (!tfa98xx->profile_count || !tfa98xx->profiles) + return -EINVAL; + + + if (tfa98xx->dsp_init == TFA98XX_DSP_INIT_RECOVER) { + pr_warn("Restart for recovery\n"); + forcecoldboot = 1; + } + + /* + * set the current profile and vsteps + * in case they get written during cold start + */ + tfa98xx->vstep = tfa98xx->profiles[profile].vstep; + + /* tfaRunSpeakerBoost implies un-mute */ + if (tfaRunSpeakerQuickBoost(tfa98xx, forcecoldboot)) + return -EINVAL; + +#if 0 + tfa98xx_enabledatao(tfa98xx); + + /* + * check if the profile and steps are the one we want + * ! only written when ACS==1 + */ + if (profile != tfa98xx->profile_current) + /* was it done already */ + tfaContWriteProfile(tfa98xx, profile, vstep); + else + /* only do the file = vstep */ + tfaContWriteFilesProf(tfa98xx, profile, vstep); +#else + +/* + * check if the profile and steps are the one we want + * ! only written when ACS==1 + */ +if (profile != tfa98xx->profile_current) + /* was it done already */ + tfaContWriteProfile(tfa98xx, profile, vstep); + +#endif + + +#ifdef VENDOR_EDIT + /* zhiguang.su@MultiMedia.AudioDrv on 2015-04-15,add by nxp patch */ + if(profile == 2) + { + tfa98xx_enabledatao(tfa98xx); + } + else + { + tfa98xx_disabledatao(tfa98xx); + } +#endif + + +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-07-18,avoid pop */ + msleep_interruptible(10); + tfa98xx_unmute(tfa98xx); +#endif + + + return 0; +} + + +int tfa98xx_dsp_start(struct tfa98xx *tfa98xx, int profile, int vstep) +{ + int forcecoldboot = coldboot; + + if (!tfa98xx->profile_count || !tfa98xx->profiles) + return -EINVAL; + + + if (tfa98xx->dsp_init == TFA98XX_DSP_INIT_RECOVER) { + pr_warn("Restart for recovery\n"); + forcecoldboot = 1; + } + + /* + * set the current profile and vsteps + * in case they get written during cold start + */ + tfa98xx->vstep = tfa98xx->profiles[profile].vstep; + + /* tfaRunSpeakerBoost implies un-mute */ + if (tfaRunSpeakerBoost(tfa98xx, forcecoldboot)) + return -EINVAL; + + /* + * check if the profile and steps are the one we want + * ! only written when ACS==1 + */ + if (profile != tfa98xx->profile_current) + /* was it done already */ + tfaContWriteProfile(tfa98xx, profile, vstep); + else + /* only do the file = vstep */ + tfaContWriteFilesProf(tfa98xx, profile, vstep); + + +#ifdef VENDOR_EDIT + /* zhiguang.su@MultiMedia.AudioDrv on 2015-04-15,add by nxp patch */ + if(profile == 2) + { + tfa98xx_enabledatao(tfa98xx); + } + else + { + tfa98xx_disabledatao(tfa98xx); + } +#endif + + + return 0; +} + + +int tfa98xx_dsp_stop(struct tfa98xx *tfa98xx) +{ + int ret = 0; + + + /* tfaRunSpeakerBoost implies unmute */ + /* mute + SWS wait */ + ret = tfa98xx_mute(tfa98xx); + if (ret) + { + pr_err("tfa_error with mute"); + } + + /* powerdown CF */ + ret = tfa98xx_powerdown(tfa98xx, 1); + if (ret) + { + pr_err("tfa_error with power down"); + } + + tfa98xx_disabledatao(tfa98xx); + + return ret; +} diff --git a/sound/soc/codecs/tfa9890/tfa_dsp.h b/sound/soc/codecs/tfa9890/tfa_dsp.h new file mode 100644 index 0000000000000..0d8c5c902586d --- /dev/null +++ b/sound/soc/codecs/tfa9890/tfa_dsp.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) NXP Semiconductors (PLMA) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __TFA_DSP_H__ +#define __TFA_DSP_H__ + + +/* + * Type containing all the possible errors that can occur + */ +enum DSP_ERRORS { + ERROR_RPC_BASE = 100, + ERROR_RPC_BUSY = 101, + ERROR_RPC_MODID = 102, + ERROR_RPC_PARAMID = 103, + ERROR_RPC_INFOID = 104, + ERROR_RPC_NOT_ALLOWED_SPEAKER = 105, + ERROR_NOT_IMPLEMENTED = 106, + ERROR_NOT_SUPPORTED = 107, +}; + +enum Tfa98xx_AgcGainInsert { + Tfa98xx_AgcGainInsert_PreDrc = 0, + Tfa98xx_AgcGainInsert_PostDrc, +}; + + +/* bit8 set means tCoefA expected */ +#define FEATURE1_TCOEF 0x100 +/* bit9 NOT set means DRC expected */ +#define FEATURE1_DRC 0x200 + + +int tfa98xx_dsp_start(struct tfa98xx *tfa98xx, int profile, int vstep); +int tfa98xx_dsp_quickstart(struct tfa98xx *tfa98xx, int profile, int vstep); +int tfa98xx_dsp_stop(struct tfa98xx *tfa98xx); +int tfaRunWriteBitfield(struct tfa98xx *tfa98xx, struct nxpTfaBitfield bf); +int tfaRunWriteRegister(struct tfa98xx *tfa98xx, struct nxpTfaRegpatch *reg); + +int tfa98xx_dsp_patch(struct tfa98xx *tfa98xx, int patchLength, const unsigned char *patchBytes); +int tfa98xx_dsp_set_param(struct tfa98xx *tfa98xx, + unsigned char module_id, + unsigned char param_id, int num_bytes, + const unsigned char data[]); +int tfa98xx_dsp_biquad_disable(struct tfa98xx *tfa98xx, int biquad_index); +int tfa98xx_dsp_biquad_set_coeff(struct tfa98xx *tfa98xx, int biquad_index, + int len, u8* data); +int tfa98xx_dsp_write_preset(struct tfa98xx *tfa98xx, int length, + const unsigned char *pPresetBytes); +int tfa98xx_dsp_power_up(struct tfa98xx *tfa98xx); +int tfa98xx_dsp_write_config(struct tfa98xx *tfa98xx, int length, const u8 *pConfigBytes); +int tfa98xx_dsp_write_speaker_parameters(struct tfa98xx *tfa98xx, + int length, + const unsigned char *pSpeakerBytes); +int tfa98xx_dsp_support_drc(struct tfa98xx *tfa98xx, int *has_drc); +int tfa98xx_dsp_set_agc_gain_insert(struct tfa98xx *tfa98xx, + enum Tfa98xx_AgcGainInsert + agcGainInsert); + +int tfa98xx_set_volume(struct tfa98xx *tfa98xx, u32 voldB); +int tfa98xx_mute(struct tfa98xx *tfa98xx); +int tfa98xx_unmute(struct tfa98xx *tfa98xx); +int tfa98xx_is_pwdn(struct tfa98xx *tfa98xx); +int tfa98xx_is_calibrated(struct tfa98xx *tfa98xx); +int tfa98xx_is_amp_running(struct tfa98xx *tfa98xx); +#ifdef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-05-29, add for calibration*/ +int tfa98xx_dsp_get_calibration_impedance(struct tfa98xx *tfa98xx, u32 *re25); +int tfaRunColdStartup(struct tfa98xx *tfa98xx); +int tfa98xx_restore_mtp(struct tfa98xx *tfa98xx); +#endif +#endif diff --git a/sound/soc/codecs/wcd9330.c b/sound/soc/codecs/wcd9330.c old mode 100644 new mode 100755 index cec8fce7b63ba..7b2c2585e4313 --- a/sound/soc/codecs/wcd9330.c +++ b/sound/soc/codecs/wcd9330.c @@ -86,8 +86,17 @@ module_param(cpe_debug_mode, int, MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode"); static atomic_t kp_tomtom_priv; - +#ifndef VENDOR_EDIT +//Kangjirui@MultMedia.Audio, 2015/05/14, Modify for change class h amp to class ab +/* static int high_perf_mode; +*/ +#else /* VENDOR_EDIT */ +static int high_perf_mode = 1; +#endif /* VENDOR_EDIT */ + + + module_param(high_perf_mode, int, S_IRUGO | S_IWUSR | S_IWGRP); MODULE_PARM_DESC(high_perf_mode, "enable/disable class AB config for hph"); @@ -526,6 +535,7 @@ struct tomtom_priv { s32 dmic_5_6_clk_cnt; s32 ldo_h_users; s32 micb_2_users; + s32 micb_3_users; u32 anc_slot; bool anc_func; @@ -588,6 +598,12 @@ struct tomtom_priv { unsigned long status_mask; }; +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + struct tomtom_priv *priv_headset_type; +#endif + + static const u32 comp_shift[] = { 4, /* Compander 0's clock source is on interpolator 7 */ 0, @@ -670,6 +686,36 @@ static unsigned short tx_digital_gain_reg[] = { TOMTOM_A_CDC_TX10_VOL_CTL_GAIN, }; +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ +enum +{ + NO_DEVICE = 0, + HS_WITH_MIC = 1, + HS_WITHOUT_MIC = 2, +}; +static ssize_t wcd9xxx_print_name(struct switch_dev *sdev, char *buf) +{ + switch (switch_get_state(sdev)) + { + case NO_DEVICE: + return sprintf(buf, "No Device\n"); + case HS_WITH_MIC: + if(priv_headset_type->mbhc.mbhc_cfg->headset_type == 1) { + return sprintf(buf, "American Headset\n"); + } else { + return sprintf(buf, "Headset\n"); + } + + case HS_WITHOUT_MIC: + return sprintf(buf, "Handset\n"); + + } + return -EINVAL; +} +#endif + + int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec) { snd_soc_write(codec, TOMTOM_A_QFUSE_CTL, 0x03); @@ -3508,7 +3554,16 @@ static int tomtom_codec_enable_micbias(struct snd_soc_dapm_widget *w, * If not internal, make sure to write the * register to default value */ - snd_soc_write(codec, micb_int_reg, 0x24); +#ifdef VENDOR_EDIT +/*suzhiguang@MultiMedia.AudioDrv, 2015-06-19, Modify for hardware requirement*/ + { + if((strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + ||(strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))) + snd_soc_write(codec, micb_int_reg, 0x00); + else + snd_soc_write(codec, micb_int_reg, 0x24); + } +#endif if (tomtom->mbhc_started && micb_ctl_reg == TOMTOM_A_MICB_2_CTL) { if (++tomtom->micb_2_users == 1) { @@ -3526,6 +3581,11 @@ static int tomtom_codec_enable_micbias(struct snd_soc_dapm_widget *w, } pr_debug("%s: micb_2_users %d\n", __func__, tomtom->micb_2_users); + } else if (micb_ctl_reg == TOMTOM_A_MICB_3_CTL) { + if (++tomtom->micb_3_users == 1) + snd_soc_update_bits(codec, micb_ctl_reg, + 1 << w->shift, + 1 << w->shift); } else { snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift, 1 << w->shift); @@ -3555,6 +3615,15 @@ static int tomtom_codec_enable_micbias(struct snd_soc_dapm_widget *w, WARN(tomtom->micb_2_users < 0, "Unexpected micbias users %d\n", tomtom->micb_2_users); + } else if (micb_ctl_reg == TOMTOM_A_MICB_3_CTL) { + if (--tomtom->micb_3_users == 0) + snd_soc_update_bits(codec, micb_ctl_reg, + 1 << w->shift, 0); + pr_debug("%s: micb_3_users %d\n", __func__, + tomtom->micb_3_users); + WARN(tomtom->micb_3_users < 0, + "Unexpected micbias-3 users %d\n", + tomtom->micb_3_users); } else { snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift, 0); @@ -4627,6 +4696,8 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ANC1 MUX", "ADC2", "ADC2"}, {"ANC1 MUX", "ADC3", "ADC3"}, {"ANC1 MUX", "ADC4", "ADC4"}, + {"ANC1 MUX", "ADC5", "ADC5"}, + {"ANC1 MUX", "ADC6", "ADC6"}, {"ANC1 MUX", "DMIC1", "DMIC1"}, {"ANC1 MUX", "DMIC2", "DMIC2"}, {"ANC1 MUX", "DMIC3", "DMIC3"}, @@ -4637,6 +4708,8 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ANC2 MUX", "ADC2", "ADC2"}, {"ANC2 MUX", "ADC3", "ADC3"}, {"ANC2 MUX", "ADC4", "ADC4"}, + {"ANC2 MUX", "ADC5", "ADC5"}, + {"ANC2 MUX", "ADC6", "ADC6"}, {"ANC2 MUX", "DMIC1", "DMIC1"}, {"ANC2 MUX", "DMIC2", "DMIC2"}, {"ANC2 MUX", "DMIC3", "DMIC3"}, @@ -7484,7 +7557,12 @@ static const struct wcd9xxx_reg_mask_val tomtom_reg_defaults[] = { TOMTOM_REG_VAL(TOMTOM_A_CDC_MAD_INP_SEL, 0x01), /* Set HPH Path to low power mode */ + #ifndef VENDOR_EDIT + //Kangjirui@MultMedia.Audio, 2015/05/21, Modify for avoid pop noise in call TOMTOM_REG_VAL(TOMTOM_A_RX_HPH_BIAS_PA, 0x55), + #else /* VENDOR_EDIT */ + TOMTOM_REG_VAL(TOMTOM_A_RX_HPH_BIAS_PA, 0x57),//modify by qualcomm patch + #endif /* VENDOR_EDIT */ /* BUCK default */ TOMTOM_REG_VAL(TOMTOM_A_BUCK_CTRL_CCL_4, 0x51), @@ -8730,6 +8808,19 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) pr_err("%s: mbhc init failed %d\n", __func__, ret); goto err_hwdep; } + +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + + + tomtom->mbhc.wcd9xxx_sdev.name= "h2w"; + tomtom->mbhc.wcd9xxx_sdev.print_name = wcd9xxx_print_name; + ret = switch_dev_register(&tomtom->mbhc.wcd9xxx_sdev); + if (ret) + { + goto err_switch_dev_register; + } +#endif tomtom->codec = codec; for (i = 0; i < COMPANDER_MAX; i++) { @@ -8742,6 +8833,7 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) tomtom->aux_r_gain = 0x1F; tomtom->ldo_h_users = 0; tomtom->micb_2_users = 0; + tomtom->micb_3_users = 0; tomtom_update_reg_defaults(codec); pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate); if (wcd9xxx->mclk_rate == TOMTOM_MCLK_CLK_12P288MHZ) @@ -8836,6 +8928,10 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) /* Do not fail probe if CPE failed */ ret = 0; } + #ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + priv_headset_type = tomtom; + #endif return ret; err_pdata: @@ -8843,6 +8939,12 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec) err_hwdep: kfree(tomtom->fw_data); err_nomem_slimch: + +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + switch_dev_unregister(&tomtom->mbhc.wcd9xxx_sdev); + err_switch_dev_register: +#endif devm_kfree(codec->dev, tomtom); return ret; } diff --git a/sound/soc/codecs/wcd9xxx-common.c b/sound/soc/codecs/wcd9xxx-common.c old mode 100644 new mode 100755 index b205754f26507..6b8f11e362863 --- a/sound/soc/codecs/wcd9xxx-common.c +++ b/sound/soc/codecs/wcd9xxx-common.c @@ -579,7 +579,12 @@ void wcd9xxx_enable_high_perf_mode(struct snd_soc_codec *codec, WCD9XXX_A_RX_HPH_L_PA_CTL__POR); snd_soc_write(codec, WCD9XXX_A_RX_HPH_R_PA_CTL, WCD9XXX_A_RX_HPH_R_PA_CTL__POR); + #ifndef VENDOR_EDIT + //Kangjirui@MultMedia.Audio, 2015/05/21, Modify for avoid pop noise in call snd_soc_write(codec, WCD9XXX_A_RX_HPH_BIAS_PA, 0x55); + #else /* VENDOR_EDIT */ + snd_soc_write(codec, WCD9XXX_A_RX_HPH_BIAS_PA, 0x57);//modify by qualcomm patch + #endif /* VENDOR_EDIT */ wcd9xxx_enable_buck(codec, clsh_d, true); wcd9xxx_chargepump_request(codec, false); wcd9xxx_enable_anc_delay(codec, false); diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c old mode 100644 new mode 100755 index 20a1e9228f293..a6ffe0bf92cac --- a/sound/soc/codecs/wcd9xxx-mbhc.c +++ b/sound/soc/codecs/wcd9xxx-mbhc.c @@ -52,8 +52,10 @@ #define NUM_DCE_PLUG_DETECT 3 #define NUM_DCE_PLUG_INS_DETECT 5 + #define NUM_ATTEMPTS_INSERT_DETECT 25 #define NUM_ATTEMPTS_TO_REPORT 5 +#define NUM_TO_REPORT_INVALID 10 #define FAKE_INS_LOW 10 #define FAKE_INS_HIGH 80 @@ -126,9 +128,24 @@ /* RX_HPH_CNP_WG_TIME increases by 0.24ms */ #define WCD9XXX_WG_TIME_FACTOR_US 240 +#ifdef VENDOR_EDIT +// Modified begin by MingLiu@MultiMedia.AudioDrv for headset detect on 2014-10-17 + #define WCD9XXX_V_CS_HS_MAX 500 + +#else /* VENDOR_EDIT */ +#define WCD9XXX_V_CS_HS_MAX 1000 +// Modified end by MingLiu@MultiMedia.AudioDrv for headset detect on 2014-10-17 +#endif /* VENDOR_EDIT */ +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv,2015/06/04,add for headset detect*/ +/*kang change from 20 to 15 for supporting lenove U.S./CTIA headset*/ +#define WCD9XXX_V_CS_NO_MIC 15 +#else #define WCD9XXX_V_CS_NO_MIC 5 +#endif #define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80 + #define WCD9XXX_CS_MEAS_DELTA_MAX_MV 12 #define WCD9XXX_ZDET_ZONE_1 80000 @@ -879,6 +896,10 @@ static void wcd9xxx_report_plug(struct wcd9xxx_mbhc *mbhc, int insertion, mbhc->hph_type = MBHC_HPH_NONE; pr_debug("%s: Reporting removal %d(%x)\n", __func__, jack_type, mbhc->hph_status); + #ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + switch_set_state(&mbhc->wcd9xxx_sdev,0); + #endif wcd9xxx_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status, WCD9XXX_JACK_MASK); wcd9xxx_set_and_turnoff_hph_padac(mbhc); @@ -952,6 +973,31 @@ static void wcd9xxx_report_plug(struct wcd9xxx_mbhc *mbhc, int insertion, pr_debug("%s: Reporting insertion %d(%x)\n", __func__, jack_type, mbhc->hph_status); + #ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + switch(mbhc->current_plug){ + case PLUG_TYPE_HEADPHONE: + case PLUG_TYPE_HIGH_HPH: + mbhc->mbhc_cfg->headset_type = 0; + switch_set_state(&mbhc->wcd9xxx_sdev,2); + break; + case PLUG_TYPE_GND_MIC_SWAP: + mbhc->mbhc_cfg->headset_type = 0; + switch_set_state(&mbhc->wcd9xxx_sdev,1); + break; + case PLUG_TYPE_HEADSET: + mbhc->mbhc_cfg->headset_type = 1; + switch_set_state(&mbhc->wcd9xxx_sdev,1); + break; + default: + mbhc->mbhc_cfg->headset_type = 0; + switch_set_state(&mbhc->wcd9xxx_sdev,0); + break; + } + printk("%s: Reporting insertion %d(%x)\n", __func__, + jack_type, mbhc->hph_status); + + #endif wcd9xxx_jack_report(mbhc, &mbhc->headset_jack, mbhc->hph_status, WCD9XXX_JACK_MASK); /* @@ -2800,7 +2846,6 @@ static void wcd9xxx_hs_insert_irq_extn(struct wcd9xxx_mbhc *mbhc, static irqreturn_t wcd9xxx_hs_remove_irq(int irq, void *data) { struct wcd9xxx_mbhc *mbhc = data; - pr_debug("%s: enter, removal interrupt\n", __func__); WCD9XXX_BCL_LOCK(mbhc->resmgr); /* @@ -3127,7 +3172,7 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) struct snd_soc_codec *codec; enum wcd9xxx_mbhc_plug_type plug_type = PLUG_TYPE_INVALID; unsigned long timeout; - int retry = 0, pt_gnd_mic_swap_cnt = 0; + int retry = 0, pt_gnd_mic_swap_cnt = 0, invalid_cnt = 0; int highhph_cnt = 0; bool correction = false; bool current_source_enable; @@ -3184,8 +3229,13 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) /* can race with removal interrupt */ WCD9XXX_BCL_LOCK(mbhc->resmgr); if (current_source_enable) - plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, + #ifndef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv,2015/05/27,modify for chinese headset detection*/ + plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, highhph); + #else + plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc,true); + #endif else plug_type = wcd9xxx_codec_get_plug_type(mbhc, true); WCD9XXX_BCL_UNLOCK(mbhc->resmgr); @@ -3198,7 +3248,8 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) 0; highhph = wcd9xxx_mbhc_enable_mb_decision(highhph_cnt); if (plug_type == PLUG_TYPE_INVALID) { - pr_debug("Invalid plug in attempt # %d\n", retry); + invalid_cnt++; + pr_debug("Invalid plug in attempt # %d count %d\n", retry,invalid_cnt); if (!mbhc->mbhc_cfg->detect_extn_cable && retry == NUM_ATTEMPTS_TO_REPORT && mbhc->current_plug == PLUG_TYPE_NONE) { @@ -3206,6 +3257,12 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADPHONE); WCD9XXX_BCL_UNLOCK(mbhc->resmgr); + } else if (invalid_cnt == NUM_TO_REPORT_INVALID) { + pr_debug("invalit_cnt = 10 report unsupported\n"); + WCD9XXX_BCL_LOCK(mbhc->resmgr); + wcd9xxx_report_plug(mbhc, 1, + SND_JACK_UNSUPPORTED); + WCD9XXX_BCL_UNLOCK(mbhc->resmgr); } } else if (plug_type == PLUG_TYPE_HEADPHONE) { pr_debug("Good headphone detected, continue polling\n"); @@ -5432,6 +5489,25 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr, return ret; } +#ifdef VENDOR_EDIT +//Ming.Liu@MultiMedia.AudioDrv, 2015-03-02, Add for 1+ headphone line control + ret = snd_jack_set_key(mbhc->button_jack.jack, + SND_JACK_BTN_3, KEY_VOLUMEUP); + if (ret) { + pr_err("%s: Failed to set code for btn-3\n", + __func__); + return ret; + } + + ret = snd_jack_set_key(mbhc->button_jack.jack, + SND_JACK_BTN_7, KEY_VOLUMEDOWN); + if (ret) { + pr_err("%s: Failed to set code for btn-7\n", + __func__); + return ret; + } +#endif /* VENDOR_EDIT */ + INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, wcd9xxx_mbhc_fw_read); INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn); diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h index 4eab53a399163..288d2ee83ba6d 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.h +++ b/sound/soc/codecs/wcd9xxx-mbhc.h @@ -11,7 +11,10 @@ */ #ifndef __WCD9XXX_MBHC_H__ #define __WCD9XXX_MBHC_H__ - +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent report*/ +#include +#endif #include "wcd9xxx-resmgr.h" #include "wcdcal-hwdep.h" @@ -262,6 +265,10 @@ struct wcd9xxx_mbhc_config { unsigned int mclk_rate; unsigned int gpio; unsigned int gpio_irq; +#ifdef VENDOR_EDIT +/*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + int headset_type; +#endif int gpio_level_insert; bool insert_detect; /* codec has own MBHC_INSERT_DETECT */ bool detect_extn_cable; @@ -403,6 +410,11 @@ struct wcd9xxx_mbhc { /* Indicates status of current source switch */ bool is_cs_enabled; +#ifdef VENDOR_EDIT + /*wangdongdong@MultiMedia.AudioDrv, 2015-03-24, Modify for headset uevent*/ + struct switch_dev wcd9xxx_sdev; + +#endif /* Holds type of Headset - Mono/Stereo */ enum mbhc_hph_type hph_type; diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig index 7589083565b9b..bbec4346a1f11 100644 --- a/sound/soc/msm/Kconfig +++ b/sound/soc/msm/Kconfig @@ -49,7 +49,7 @@ config SND_SOC_MSM_QDSP6_INTF config SND_SOC_MSM_QDSP6V2_INTF bool "SoC Q6 audio driver for MSM8974" - depends on MSM_QDSP6_APRV2 + depends on MSM_QDSP6_APRV2 || MSM_QDSP6_APRV3 help To add support for SoC audio on MSM8974. This will enable all the platform specific diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c index 4067aa6ea09c8..015996ed4b3a5 100644 --- a/sound/soc/msm/msm-dai-fe.c +++ b/sound/soc/msm/msm-dai-fe.c @@ -740,7 +740,12 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .rate_max = 48000, }, .ops = &msm_fe_dai_ops, +#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,changed by Quallcomm patch.*/ .name = "QUAT_MI2S_TX_HOSTLESS", +#else + .name = "QUAT_MI2S_HOSTLESS", +#endif .probe = fe_dai_probe, }, { diff --git a/sound/soc/msm/msm8994.c b/sound/soc/msm/msm8994.c old mode 100644 new mode 100755 index 1df23af641103..37540edc20f12 --- a/sound/soc/msm/msm8994.c +++ b/sound/soc/msm/msm8994.c @@ -59,19 +59,41 @@ #define TOMTOM_EXT_CLK_RATE 9600000 #define ADSP_STATE_READY_TIMEOUT_MS 3000 + + +#ifndef VENDOR_EDIT + enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_AUXPCM_ACTIVE, /* Aux PCM = active, MI2S = sleep */ + STATE_MI2S_ACTIVE, /* Aux PCM = sleep, MI2S = active */ + STATE_ACTIVE /* All pins are in active state */ + }; + + enum mi2s_pcm_mux { + PRI_MI2S_PCM = 1, + SEC_MI2S_PCM, + TERT_MI2S_PCM, + QUAD_MI2S_PCM + }; +#else + /* Modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11 ,change for I2S*/ enum pinctrl_pin_state { STATE_DISABLE = 0, /* All pins are in sleep state */ STATE_AUXPCM_ACTIVE, /* Aux PCM = active, MI2S = sleep */ STATE_MI2S_ACTIVE, /* Aux PCM = sleep, MI2S = active */ - STATE_ACTIVE /* All pins are in active state */ + STATE_ACTIVE, /* All pins are in active state */ + STATE_QUA_MI2S_SLEEP, + STATE_QUA_MI2S_ACTIVE, }; enum mi2s_pcm_mux { - PRI_MI2S_PCM = 1, - SEC_MI2S_PCM, - TERT_MI2S_PCM, - QUAD_MI2S_PCM +PRI_MI2S_PCM = 0, +SEC_MI2S_PCM, +TERT_MI2S_PCM, +QUAT_MI2S_PCM, }; + /* Modified end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11 */ +#endif struct msm_pinctrl_info { struct pinctrl *pinctrl; @@ -79,6 +101,11 @@ struct msm_pinctrl_info { struct pinctrl_state *mi2s_active; struct pinctrl_state *auxpcm_active; struct pinctrl_state *active; +#ifdef VENDOR_EDIT + /* Add by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,for I2S */ + struct pinctrl_state *qua_mi2s_sleep; + struct pinctrl_state *qua_mi2s_active; +#endif enum pinctrl_pin_state curr_state; }; @@ -89,6 +116,10 @@ struct msm8994_asoc_mach_data { struct msm_pinctrl_info pinctrl_info; void __iomem *pri_mux; void __iomem *sec_mux; +#ifdef VENDOR_EDIT + /* Modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11 */ + void __iomem *qua_mux; +#endif }; static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; @@ -111,6 +142,43 @@ static int msm_proxy_rx_ch = 2; static int hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; static int msm_pri_mi2s_tx_ch = 2; + +#ifdef VENDOR_EDIT + /* Modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +//#define MSM_TERT_MI2S_MASTER +#define MSM_QUAT_MI2S_MASTER + +static struct afe_clk_cfg pri_mi2s_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_OSR_CLK_DISABLE, + Q6AFE_LPASS_CLK_SRC_INTERNAL, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + Q6AFE_LPASS_MODE_CLK1_VALID, + 0, +}; + +static struct afe_clk_cfg quat_mi2s_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_OSR_CLK_DISABLE, + Q6AFE_LPASS_CLK_SRC_INTERNAL, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + Q6AFE_LPASS_MODE_CLK1_VALID, + 0, +}; + +static int pri_mi2s_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int pri_mi2s_sample_rate = SAMPLING_RATE_48KHZ; +static atomic_t pri_mi2s_rsc_ref; +static atomic_t quat_mi2s_rsc_ref; + +static int quat_mi2s_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int quat_mi2s_sample_rate = SAMPLING_RATE_48KHZ; + + /* Modified end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11 */ +#endif + static struct mutex cdc_mclk_mutex; static struct clk *codec_clk; static int clk_users; @@ -135,8 +203,15 @@ static struct audio_plug_dev *apq8094_db_ext_fp_in_dev; static struct audio_plug_dev *apq8094_db_ext_fp_out_dev; +#ifndef VENDOR_EDIT static const char *const pin_states[] = {"sleep", "auxpcm-active", "mi2s-active", "active"}; +#else +/* zhiguang.su@MultiMedia.AudioDrv on 2015-06-16,add to avoid debug print crash */ +static const char *const pin_states[] = {"sleep", "auxpcm-active", + "mi2s-active","active","quat_mi2s_sleep","quat_mi2s_active"}; +#endif + static const char *const spk_function[] = {"Off", "On"}; static const char *const slim0_rx_ch_text[] = {"One", "Two"}; static const char *const vi_feed_ch_text[] = {"One", "Two"}; @@ -175,9 +250,22 @@ static struct wcd9xxx_mbhc_config mbhc_cfg = { .anc_micbias = MBHC_MICBIAS2, .mclk_cb_fn = msm_snd_enable_codec_ext_clk, .mclk_rate = TOMTOM_EXT_CLK_RATE, +/* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-10 for headset detect */ +#ifndef VENDOR_EDIT .gpio_level_insert = 1, - .detect_extn_cable = true, - .micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET, +#else + .gpio_level_insert = 0, +#endif + +#ifndef VENDOR_EDIT +/* suzhiguang@oneplus.cn on 2015-8-21, this will causes speaker and handset silent in some case. */ + .detect_extn_cable = true, +#else + .detect_extn_cable = false, +#endif + + //qualcomm modify + .micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET | 1 << MBHC_MICBIAS_ENABLE_REGULAR_HEADSET, .insert_detect = true, .swap_gnd_mic = NULL, .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING | @@ -187,9 +275,16 @@ static struct wcd9xxx_mbhc_config mbhc_cfg = { .do_recalibration = true, .use_vddio_meas = true, .enable_anc_mic_detect = false, +/* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-10 for headset detect */ +#ifndef VENDOR_EDIT .hw_jack_type = SIX_POLE_JACK, +#else + .hw_jack_type = FOUR_POLE_JACK, +#endif }; +#ifndef VENDOR_EDIT +/* zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,No need for quat I2S */ static struct afe_clk_cfg mi2s_tx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, @@ -199,6 +294,8 @@ static struct afe_clk_cfg mi2s_tx_clk = { Q6AFE_LPASS_MODE_CLK1_VALID, 0, }; +/*end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11 */ +#endif static inline int param_is_mask(int p) { @@ -676,12 +773,21 @@ static const struct snd_soc_dapm_widget msm8994_dapm_widgets[] = { SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), SND_SOC_DAPM_SPK("ultrasound amp", msm_ext_ultrasound_event), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic4", NULL), - SND_SOC_DAPM_MIC("Analog Mic5", NULL), + /* Modified begin by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + /* + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), + */ + SND_SOC_DAPM_MIC("Primary Mic", NULL), + SND_SOC_DAPM_MIC("Noise Mic", NULL), + SND_SOC_DAPM_MIC("ANC Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + /* Modified end by Ming.Liu@MultiMedia.AudioDrv on 2014-10-9 */ + SND_SOC_DAPM_MIC("Analog Mic6", NULL), SND_SOC_DAPM_MIC("Analog Mic7", NULL), SND_SOC_DAPM_MIC("Analog Mic8", NULL), @@ -694,6 +800,95 @@ static const struct snd_soc_dapm_widget msm8994_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic6", NULL), }; + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +static int pri_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (pri_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + + return 0; +} + +static int pri_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (ucontrol->value.integer.value[0]) { + case 2: + pri_mi2s_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + pri_mi2s_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + pri_mi2s_sample_rate = SAMPLING_RATE_48KHZ; + } + + pr_debug("%s: sample_rate = %d\n", __func__, pri_mi2s_sample_rate); + + return 0; +} + +static int pri_mi2s_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (pri_mi2s_bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + + + return 0; +} + +static int pri_mi2s_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + pri_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + pri_mi2s_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: bit_format = %d \n", __func__, pri_mi2s_bit_format); + return 0; +} + + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + + static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1207,6 +1402,31 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, } switch (pinctrl_info->curr_state) { + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + case STATE_QUA_MI2S_SLEEP: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->qua_mi2s_sleep); + if (ret) { + pr_err("%s: AUXPCM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_QUA_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->qua_mi2s_active); + if (ret) { + pr_err("%s: AUXPCM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + #endif case STATE_AUXPCM_ACTIVE: ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->auxpcm_active); @@ -1271,6 +1491,30 @@ static int msm_reset_pinctrl(struct msm_pinctrl_info *pinctrl_info, } switch (pinctrl_info->curr_state) { +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + case STATE_QUA_MI2S_SLEEP: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->qua_mi2s_sleep); + if (ret) { + pr_err("%s: AUXPCM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_QUA_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->qua_mi2s_active); + if (ret) { + pr_err("%s: AUXPCM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + #endif case STATE_AUXPCM_ACTIVE: ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->auxpcm_active); @@ -1321,6 +1565,11 @@ static void msm_release_pinctrl(struct platform_device *pdev) if (pinctrl_info) { iounmap(pdata->pri_mux); iounmap(pdata->sec_mux); +#ifdef VENDOR_EDIT +/* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + iounmap(pdata->qua_mux); +/* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif devm_pinctrl_put(pinctrl_info->pinctrl); pinctrl_info->pinctrl = NULL; } @@ -1375,6 +1624,26 @@ static int msm_get_pinctrl(struct platform_device *pdev) __func__); goto err; } +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + pinctrl_info->qua_mi2s_sleep = pinctrl_lookup_state(pinctrl, + "quat_mi2s_sleep"); + if (IS_ERR(pinctrl_info->qua_mi2s_sleep)) { + pr_err("%s: could not get active pinstate\n", + __func__); + goto err; + } + + pinctrl_info->qua_mi2s_active = pinctrl_lookup_state(pinctrl, + "quat_mi2s_active"); + if (IS_ERR(pinctrl_info->qua_mi2s_active)) { + pr_err("%s: could not get active pinstate\n", + __func__); + goto err; + } + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + #endif + /* Reset the TLMM pins to a default state */ ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->disable); @@ -1412,6 +1681,25 @@ static int msm_get_pinctrl(struct platform_device *pdev) ret = -EINVAL; goto err; } + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "lpaif_quat_mode_muxsel"); + if (!muxsel) { + dev_err(&pdev->dev, "MUX addr invalid for AUXPCM\n"); + ret = -ENODEV; + goto err; + } + pdata->qua_mux = ioremap(muxsel->start, resource_size(muxsel)); + if (pdata->qua_mux == NULL) { + pr_err("%s: AUXPCM muxsel virt addr is null\n", __func__); + ret = -EINVAL; + goto err; + } + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + #endif + return 0; err: @@ -1422,6 +1710,372 @@ static int msm_get_pinctrl(struct platform_device *pdev) return -EINVAL; } + +#ifndef VENDOR_EDIT + /* modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,changed for I2S PA */ + static int msm8994_mi2s_snd_startup(struct snd_pcm_substream *substream) + { + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + pr_debug("%s: substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + if (pdata->pri_mux != NULL) + iowrite32(I2S_PCM_SEL_I2S << I2S_PCM_SEL_OFFSET, + pdata->pri_mux); + else + pr_err("%s: MI2S muxsel addr is NULL\n", __func__); + + ret = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret) { + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret); + return ret; + } + mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + mi2s_tx_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_TX, + &mi2s_tx_clk); + if (ret < 0) { + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + goto err; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); + err: + return ret; + } + + static void msm8994_mi2s_snd_shutdown(struct snd_pcm_substream *substream) + { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret = 0; + + pr_debug("%s: substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + mi2s_tx_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_TX, + &mi2s_tx_clk); + if (ret < 0) + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + + ret = msm_reset_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret) + pr_err("%s: Reset pinctrl failed with %d\n", + __func__, ret); + } +#else +static int msm8994_pri_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + pr_err("%s: dai name %s %p substream = %s stream = %d bit width =%d sample rate =%d \n", __func__, cpu_dai->name, cpu_dai->dev,substream->name, + substream->stream, pri_mi2s_bit_format, pri_mi2s_sample_rate); + + if (atomic_inc_return(&pri_mi2s_rsc_ref) == 1) { + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pdata->pri_mux != NULL) + iowrite32(I2S_PCM_SEL_I2S << I2S_PCM_SEL_OFFSET, + pdata->pri_mux); + else + pr_err("%s: MI2S muxsel addr is NULL\n", __func__); + + ret = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret) { + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", __func__, ret); + return ret; + } + if(pri_mi2s_bit_format==SNDRV_PCM_FORMAT_S24_LE) + { + switch(pri_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ : + pri_mi2s_clk.clk_val1 =Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ; + case SAMPLING_RATE_96KHZ : + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ; + case SAMPLING_RATE_48KHZ : + default: + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; + } + } else { + switch(pri_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ : + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ; + case SAMPLING_RATE_96KHZ : + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; + case SAMPLING_RATE_48KHZ : + default: + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + + } + } + + pri_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, + &pri_mi2s_clk); + if (ret < 0) { + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + goto err; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); + + } + + +err: + return ret; +} + +static void msm8994_pri_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret = 0; + + pr_err("%s: dai name %s %p substream = %s stream = %d \n", __func__, cpu_dai->name, cpu_dai->dev,substream->name, substream->stream); + if (atomic_dec_return(&pri_mi2s_rsc_ref) == 0) { + + pri_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + pri_mi2s_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE; + pri_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + pri_mi2s_clk.clk_src =Q6AFE_LPASS_CLK_SRC_INTERNAL; + ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_RX, &pri_mi2s_clk); + if (ret < 0) pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + + ret = msm_reset_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret) pr_err("%s: Reset pinctrl failed with %d\n", __func__, ret); + pr_info("%s Quaternary MI2S Clock is Disabled", __func__); + } +} + +#endif + + +#ifdef VENDOR_EDIT +/* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable quat i2s */ +static int quat_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (quat_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + + return 0; +} + +static int quat_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 2: + quat_mi2s_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + quat_mi2s_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + quat_mi2s_sample_rate = SAMPLING_RATE_48KHZ; + } + + pr_debug("%s: sample_rate = %d\n", __func__, quat_mi2s_sample_rate); + + return 0; +} + +static int quat_mi2s_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (quat_mi2s_bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + return 0; +} + +static int quat_mi2s_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + quat_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + quat_mi2s_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: bit_format = %d \n", __func__, quat_mi2s_bit_format); + return 0; +} + + +static int msm8994_quat_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + pr_info("%s: dai name %s %p substream = %s stream = %d bit width =%d sample rate =%d \n", __func__, cpu_dai->name, cpu_dai->dev,substream->name, + substream->stream, quat_mi2s_bit_format, quat_mi2s_sample_rate); + if (atomic_inc_return(&quat_mi2s_rsc_ref) == 1) + { + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + if (pdata->qua_mux != NULL) + iowrite32(I2S_PCM_SEL_I2S << I2S_PCM_SEL_OFFSET, pdata->qua_mux); + else pr_err("%s: MI2S muxsel addr is NULL\n", __func__); + + ret = msm_set_pinctrl(pinctrl_info, STATE_QUA_MI2S_ACTIVE); + if (ret) { + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", __func__, ret); + return ret; + } + if(quat_mi2s_bit_format==SNDRV_PCM_FORMAT_S24_LE) + { + switch(quat_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ : + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ; + case SAMPLING_RATE_96KHZ : + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ; + case SAMPLING_RATE_48KHZ : + default: + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; + } + } else { + switch(quat_mi2s_sample_rate) { + case SAMPLING_RATE_192KHZ : + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ; + case SAMPLING_RATE_96KHZ : + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ; + case SAMPLING_RATE_48KHZ : + default: + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; + + } + } + +#ifdef MSM_QUAT_MI2S_MASTER +#ifdef MSM_QUAT_MI2S_MCLK + quat_mi2s_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ; + quat_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_BOTH_VALID; +#else + quat_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; +#endif + quat_mi2s_clk.clk_src =Q6AFE_LPASS_CLK_SRC_INTERNAL; + ret = afe_set_lpass_clock(AFE_PORT_ID_QUATERNARY_MI2S_RX, &quat_mi2s_clk); + if (ret < 0) { + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + goto err; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); +#else + quat_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + quat_mi2s_clk.clk_src =Q6AFE_LPASS_CLK_SRC_EXTERNAL; + ret = afe_set_lpass_clock(AFE_PORT_ID_QUATERNARY_MI2S_RX, &quat_mi2s_clk); + if (ret < 0) { + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + goto err; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); +#endif + + + } +err: + return ret; +} + +static void msm8994_quat_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret = 0; + + pr_info("%s: dai name %s %p substream = %s stream = %d \n", __func__, cpu_dai->name, cpu_dai->dev,substream->name, substream->stream); + if (atomic_dec_return(&quat_mi2s_rsc_ref) == 0) + { + quat_mi2s_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; + quat_mi2s_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE; + quat_mi2s_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; + quat_mi2s_clk.clk_src =Q6AFE_LPASS_CLK_SRC_INTERNAL; + ret = afe_set_lpass_clock(AFE_PORT_ID_QUATERNARY_MI2S_RX, &quat_mi2s_clk); + if (ret < 0) pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + + ret = msm_reset_pinctrl(pinctrl_info, STATE_QUA_MI2S_ACTIVE); + if (ret) pr_err("%s: Reset pinctrl failed with %d\n", __func__, ret); + pr_info("%s Quaternary MI2S Clock is Disabled", __func__); + } +} + +/* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + static int msm_sec_auxpcm_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -1498,79 +2152,66 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static int msm8994_mi2s_snd_startup(struct snd_pcm_substream *substream) +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +static int msm_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) { - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - pr_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - if (pdata->pri_mux != NULL) - iowrite32(I2S_PCM_SEL_I2S << I2S_PCM_SEL_OFFSET, - pdata->pri_mux); - else - pr_err("%s: MI2S muxsel addr is NULL\n", __func__); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, pri_mi2s_bit_format); - ret = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); - if (ret) { - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret); - return ret; - } - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; - mi2s_tx_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; - ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) { - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); - goto err; - } - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); -err: - return ret; + pr_debug("%s: channel:%d\n", __func__, msm_pri_mi2s_tx_ch); + rate->min = rate->max = pri_mi2s_sample_rate; + channels->min = channels->max = msm_pri_mi2s_tx_ch; + return 0; } -static void msm8994_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +static int msm_be_quat_mi2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct msm8994_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret = 0; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); - pr_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + quat_mi2s_bit_format); + rate->min = rate->max = quat_mi2s_sample_rate; + channels->min = channels->max =2; + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,remove unnecessary log which cause crash.*/ + //pr_debug("%s Quat MI2S Sample Rate =%d, bit Format = %d \n", __func__, quat_mi2s_sample_rate, quat_mi2s_bit_format); + return 0; +} - mi2s_tx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; - mi2s_tx_clk.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID; - ret = afe_set_lpass_clock(AFE_PORT_ID_PRIMARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif - ret = msm_reset_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); - if (ret) - pr_err("%s: Reset pinctrl failed with %d\n", - __func__, ret); -} static struct snd_soc_ops msm8994_mi2s_be_ops = { - .startup = msm8994_mi2s_snd_startup, - .shutdown = msm8994_mi2s_snd_shutdown, +#ifndef VENDOR_EDIT + .startup = msm8994_mi2s_snd_startup, + .shutdown = msm8994_mi2s_snd_shutdown, +#else + /* modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + .startup =msm8994_pri_mi2s_snd_startup, + .shutdown =msm8994_pri_mi2s_snd_shutdown, + /* Modified end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif }; +#ifdef VENDOR_EDIT +/* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +static struct snd_soc_ops msm8994_qua_mi2s_be_ops = { + .startup =msm8994_quat_mi2s_snd_startup, + .shutdown =msm8994_quat_mi2s_snd_shutdown, +}; +/* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -1721,6 +2362,20 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { slim0_tx_bit_format_get, slim0_tx_bit_format_put), SOC_ENUM_EXT("SLIM_0_TX SampleRate", msm_snd_enum[5], slim0_tx_sample_rate_get, slim0_tx_sample_rate_put), +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable quat i2s */ + SOC_ENUM_EXT("PRI_MI2S BitWidth", msm_snd_enum[4], + pri_mi2s_bit_format_get, pri_mi2s_bit_format_put), + SOC_ENUM_EXT("PRI_MI2S SampleRate", msm_snd_enum[5], + pri_mi2s_sample_rate_get, pri_mi2s_sample_rate_put), + + SOC_ENUM_EXT("QUAT_MI2S BitWidth", msm_snd_enum[4], + quat_mi2s_bit_format_get, quat_mi2s_bit_format_put), + SOC_ENUM_EXT("QUAT_MI2S SampleRate", msm_snd_enum[5], + quat_mi2s_sample_rate_get, quat_mi2s_sample_rate_put), + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + }; static bool msm8994_swap_gnd_mic(struct snd_soc_codec *codec) @@ -2024,6 +2679,8 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) return err; } +#ifndef VENDOR_EDIT +//Ming.Liu@MultiMedia.AudioDrv, 2015-03-02, Modified for 1+ headphone line control static void *def_codec_mbhc_cal(void) { void *codec_cal; @@ -2101,6 +2758,86 @@ static void *def_codec_mbhc_cal(void) return codec_cal; } +#else +static void *def_codec_mbhc_cal(void) +{ + void *codec_cal; + struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_low, *btn_high; + u8 *n_ready, *n_cic, *gain; + + codec_cal = kzalloc(WCD9XXX_MBHC_CAL_SIZE(WCD9XXX_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), + GFP_KERNEL); + if (!codec_cal) { + pr_err("%s: out of memory\n", __func__); + return NULL; + } + +#define S(X, Y) ((WCD9XXX_MBHC_CAL_GENERAL_PTR(codec_cal)->X) = (Y)) + S(t_ldoh, 100); + S(t_bg_fast_settle, 100); + S(t_shutdown_plug_rem, 255); + S(mbhc_nsa, 4); + S(mbhc_navg, 4); +#undef S +#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_DET_PTR(codec_cal)->X) = (Y)) + S(mic_current, TOMTOM_PID_MIC_5_UA); + S(hph_current, TOMTOM_PID_MIC_5_UA); + S(t_mic_pid, 100); + S(t_ins_complete, 250); + S(t_ins_retry, 200); +#undef S +#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(codec_cal)->X) = (Y)) + S(v_no_mic, 30); + S(v_hs_max, 2550); //kjr modify from 2400 to 2550 +#undef S +#define S(X, Y) ((WCD9XXX_MBHC_CAL_BTN_DET_PTR(codec_cal)->X) = (Y)) + S(c[0], 62); + S(c[1], 124); + S(nc, 1); + S(n_meas, 3); + S(mbhc_nsc, 11); + S(n_btn_meas, 1); + S(n_btn_con, 2); + S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS); + S(v_btn_press_delta_sta, 100); + S(v_btn_press_delta_cic, 50); +#undef S + btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(codec_cal); + btn_low = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_V_BTN_LOW); + btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, + MBHC_BTN_DET_V_BTN_HIGH); + + btn_low[0] = -70; + btn_high[0] = 75; + btn_low[1] = 76; + btn_high[1] = 77; + btn_low[2] = 78; + btn_high[2] = 79; + btn_low[3] = 80; + btn_high[3] = 263; + btn_low[4] = 264; + btn_high[4] = 265; + btn_low[5] = 266; + btn_high[5] = 267; + btn_low[6] = 268; + btn_high[6] = 269; + btn_low[7] = 270; + btn_high[7] = 600; //kjr modify 500 to 600 + n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY); + n_ready[0] = 80; + n_ready[1] = 68; + n_cic = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_CIC); + n_cic[0] = 60; + n_cic[1] = 47; + gain = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_GAIN); + gain[0] = 11; + gain[1] = 9; + + return codec_cal; +} +#endif static int msm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -2887,6 +3624,58 @@ static struct snd_soc_dai_link msm8994_common_dai_links[] = { .codec_dai_name = "tomtom_mad1", .codec_name = "tomtom_codec", }, + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable quat i2s */ + { + .name = "Primary MI2S RX_Hostless", + .stream_name = "Primary MI2S_RX Hostless Playback", + .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quat MI2S RX_Hostless", + .stream_name = "Quaternary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add by Quallcomm patch.*/ + { + .name = "Quaternary MI2S Hostless", + .stream_name = "QUAT_MI2S_TX Hostless", + .cpu_dai_name = "QUAT_MI2S_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + /* End of FE DAI LINK */ /* Backend FM DAI Links */ { @@ -3178,7 +3967,54 @@ static struct snd_soc_dai_link msm8994_common_dai_links[] = { .be_hw_params_fixup = msm_tx_be_hw_params_fixup, .ops = &msm8994_mi2s_be_ops, .ignore_suspend = 1, - } + }, + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "tfa98xx.5-0036", + .codec_dai_name = "tfa98xx_codec", + .no_pcm = 1, + .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_rx_be_hw_params_fixup, + .ops = &msm8994_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "tfa98xx.5-0036", + .codec_dai_name = "tfa98xx_codec", + .no_pcm = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_quat_mi2s_hw_params_fixup, + .ops = &msm8994_qua_mi2s_be_ops, + .ignore_suspend = 1, + }, + + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-04-15,add for quat i2s tx */ + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + /* zhiguang.su@MultiMedia.AudioDrv on 2015-04-15,revert ops for quat i2s tx */ + .be_hw_params_fixup = msm_be_quat_mi2s_hw_params_fixup, + .ops = &msm8994_qua_mi2s_be_ops, + .ignore_suspend = 1, + }, + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif }; static struct snd_soc_dai_link msm8994_hdmi_dai_link[] = { @@ -3486,6 +4322,14 @@ static int msm8994_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "msm8994_prepare_us_euro failed (%d)\n", ret); +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + atomic_set(&pri_mi2s_rsc_ref, 0); + atomic_set(&quat_mi2s_rsc_ref, 0); + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + + /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); if (!ret) { diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index d04b5c5646faf..429a6ae2309ba 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -102,6 +102,11 @@ struct msm_compr_gapless_state { bool use_dsp_gapless_mode; }; +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, + 88200, 96000, 176400, 192000 +}; + struct msm_compr_pdata { atomic_t audio_ocmem_req; struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; @@ -1136,55 +1141,16 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; int ret = 0, frame_sz = 0, delay_time_ms = 0; + int i, num_rates; pr_debug("%s\n", __func__); - memcpy(&prtd->codec_param, params, sizeof(struct snd_compr_params)); - - /* ToDo: remove duplicates */ - prtd->num_channels = prtd->codec_param.codec.ch_in; - - switch (prtd->codec_param.codec.sample_rate) { - case SNDRV_PCM_RATE_8000: - prtd->sample_rate = 8000; - break; - case SNDRV_PCM_RATE_11025: - prtd->sample_rate = 11025; - break; - /* ToDo: What about 12K and 24K sample rates ? */ - case SNDRV_PCM_RATE_16000: - prtd->sample_rate = 16000; - break; - case SNDRV_PCM_RATE_22050: - prtd->sample_rate = 22050; - break; - case SNDRV_PCM_RATE_32000: - prtd->sample_rate = 32000; - break; - case SNDRV_PCM_RATE_44100: - prtd->sample_rate = 44100; - break; - case SNDRV_PCM_RATE_48000: - prtd->sample_rate = 48000; - break; - case SNDRV_PCM_RATE_64000: - prtd->sample_rate = 64000; - break; - case SNDRV_PCM_RATE_88200: - prtd->sample_rate = 88200; - break; - case SNDRV_PCM_RATE_96000: - prtd->sample_rate = 96000; - break; - case SNDRV_PCM_RATE_176400: - prtd->sample_rate = 176400; - break; - case SNDRV_PCM_RATE_192000: - prtd->sample_rate = 192000; - break; - } - - pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate); + num_rates = sizeof(supported_sample_rates)/sizeof(unsigned int); + for (i = 0; i < num_rates; i++) + if (params->codec.sample_rate == supported_sample_rates[i]) + break; + if (i == num_rates) + return -EINVAL; if (prtd->codec_param.codec.compr_passthr >= 0 && prtd->codec_param.codec.compr_passthr <= 2) @@ -1273,6 +1239,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, delay_time_ms - PARTIAL_DRAIN_ACK_EARLY_BY_MSEC : 0; prtd->partial_drain_delay = delay_time_ms; + memcpy(&prtd->codec_param, params, sizeof(struct snd_compr_params)); + + /* ToDo: remove duplicates */ + prtd->num_channels = prtd->codec_param.codec.ch_in; + prtd->sample_rate = prtd->codec_param.codec.sample_rate; + pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate); ret = msm_compr_configure_dsp(cstream); return ret; @@ -1970,7 +1942,11 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream, case SND_AUDIOCODEC_MP3: codec->num_descriptors = 2; codec->descriptor[0].max_ch = 2; - codec->descriptor[0].sample_rates = SNDRV_PCM_RATE_8000_48000; + memcpy(codec->descriptor[0].sample_rates, + supported_sample_rates, + sizeof(supported_sample_rates)); + codec->descriptor[0].num_sample_rates = + sizeof(supported_sample_rates)/sizeof(unsigned int); codec->descriptor[0].bit_rate[0] = 320; /* 320kbps */ codec->descriptor[0].bit_rate[1] = 128; codec->descriptor[0].num_bitrates = 2; @@ -1981,7 +1957,11 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream, case SND_AUDIOCODEC_AAC: codec->num_descriptors = 2; codec->descriptor[1].max_ch = 2; - codec->descriptor[1].sample_rates = SNDRV_PCM_RATE_8000_48000; + memcpy(codec->descriptor[1].sample_rates, + supported_sample_rates, + sizeof(supported_sample_rates)); + codec->descriptor[1].num_sample_rates = + sizeof(supported_sample_rates)/sizeof(unsigned int); codec->descriptor[1].bit_rate[0] = 320; /* 320kbps */ codec->descriptor[1].bit_rate[1] = 128; codec->descriptor[1].num_bitrates = 2; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c old mode 100644 new mode 100755 index d200d88d8042f..be9284184159c --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -90,6 +90,19 @@ static const char * const mad_audio_mux_text[] = { TERT_MI2S_TX_TEXT }; + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ +#define INT_RX_VOL_MAX_STEPS 0x2000 +#define INT_RX_VOL_GAIN 0x2000 +static int msm_route_afe_pri_mi2s_vol_control= 0x2000; +static int msm_route_afe_qua_mi2s_vol_control= 0x2000; + +static const DECLARE_TLV_DB_LINEAR(afe_mi2s_vol_gain, 0, + INT_RX_VOL_MAX_STEPS); + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ +#endif + struct msm_pcm_route_bdai_pp_params { u16 port_id; /* AFE port ID */ unsigned long pp_params_config; @@ -325,6 +338,48 @@ static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES]; static struct msm_pcm_stream_app_type_cfg fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE]; + + + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ +static int msm_routing_get_afe_pri_mi2s_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_afe_pri_mi2s_vol_control; + return 0; +} + +static int msm_routing_set_afe_pri_mi2s_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_PRIMARY_MI2S_RX , ucontrol->value.integer.value[0]); + + msm_route_afe_pri_mi2s_vol_control = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_routing_get_afe_qua_mi2s_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_afe_qua_mi2s_vol_control; + return 0; +} + +static int msm_routing_set_afe_qua_mi2s_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_QUATERNARY_MI2S_TX , ucontrol->value.integer.value[0]); + + msm_route_afe_qua_mi2s_vol_control = ucontrol->value.integer.value[0]; + + return 0; +} + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + + /* The caller of this should aqcuire routing lock */ void msm_pcm_routing_get_bedai_info(int be_idx, struct msm_pcm_routing_bdai_data *be_dai) @@ -1557,6 +1612,19 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 7; ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; break; +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ + case 9: + msm_route_ec_ref_rx = 11; + ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case 10: + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add break.*/ + msm_route_ec_ref_rx = 12; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ +#endif default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -1574,9 +1642,20 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "PRI_MI2S_TX", "SEC_MI2S_TX", - "TERT_MI2S_TX", "QUAT_MI2S_TX", "SEC_I2S_RX", "PROXY_RX"}; +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ + "TERT_MI2S_TX", "QUAT_MI2S_TX", "SEC_I2S_RX", "PROXY_RX", + "TERT_MI2S_RX", "QUAT_MI2S_RX"}; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ + #endif static const struct soc_enum msm_route_ec_ref_rx_enum[] = { +#ifndef VENDOR_EDIT SOC_ENUM_SINGLE_EXT(9, ec_ref_rx), +#else + /* modified begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ + SOC_ENUM_SINGLE_EXT(11, ec_ref_rx), + /* modified end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s */ +#endif }; static const struct snd_kcontrol_new ext_ec_ref_mux_ul1 = @@ -2633,6 +2712,12 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), +#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add necessary route.*/ + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -3218,6 +3303,12 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_SINGLE_EXT("TERT_MI2S_TX_Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add necessary route.*/ + SOC_SINGLE_EXT("QUAT_MI2S_TX_Voip", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { @@ -3379,6 +3470,22 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + SOC_SINGLE_EXT("PRI_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif }; static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { @@ -3511,7 +3618,37 @@ static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s control*/ + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif +}; + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s control*/ +static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, @@ -4080,9 +4217,18 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", - "Quaternary MI2S_TX Hostless Capture", + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", "QUAT_MI2S_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", "TERT_MI2S_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", "QUAT_MI2S_HOSTLESS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", "TERT_MI2S_HOSTLESS Playback", + 0, 0, 0, 0), +#endif /* LSM */ SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", @@ -4396,6 +4542,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, quat_mi2s_rx_port_mixer_controls, ARRAY_SIZE(quat_mi2s_rx_port_mixer_controls)), + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s control*/ + SND_SOC_DAPM_MIXER("TERT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + tert_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(tert_mi2s_rx_port_mixer_controls)), + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, ARRAY_SIZE(tx_qchat_mixer_controls)), @@ -4426,6 +4580,22 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul9), }; +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s control*/ +static const struct snd_kcontrol_new afe_pri_mi2s_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("PRI_MI2S_RX Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_routing_get_afe_pri_mi2s_vol_mixer, + msm_routing_set_afe_pri_mi2s_vol_mixer, afe_mi2s_vol_gain), +}; + +static const struct snd_kcontrol_new afe_qua_mi2s_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("QUA_MI2S_RX Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_routing_get_afe_qua_mi2s_vol_mixer, + msm_routing_set_afe_qua_mi2s_vol_mixer, afe_mi2s_vol_gain), +}; + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + static const struct snd_soc_dapm_route intercon[] = { {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -4646,6 +4816,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#ifdef VENDOR_EDIT +/*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add necessary route.*/ + {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -4956,6 +5130,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + +#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add necessary route.*/ + {"VOIP_UL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"VOIP_UL", NULL, "AUDIO_REF_EC_UL5 MUX"}, +#endif {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, @@ -5004,6 +5184,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, + +#ifdef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,add necessary route.*/ + {"Voip_Tx Mixer", "QUAT_MI2S_TX_Voip", "QUAT_MI2S_TX"}, +#endif + {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, @@ -5117,8 +5303,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"PCM_RX", NULL, "PCM_RX_DL_HL"}, {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, - +#ifndef VENDOR_EDIT + /* add begin by jirui.kang@MultiMedia.AudioDrv on 2015-03-24,modify for loopback test */ {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, +#else + {"QUAT_MI2S_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, +#endif {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, @@ -5127,7 +5317,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, - +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -5137,6 +5332,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_RX", "PRI_MI2S_RX"}, + {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_RX", "SEC_MI2S_RX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_MI2S_RX", "TERT_MI2S_RX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_RX", "QUAT_MI2S_RX"}, + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -5242,8 +5447,21 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ + {"QUAT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, + + {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Port Mixer"}, + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif /* Backend Enablement */ {"BE_OUT", NULL, "PRI_I2S_RX"}, @@ -5717,7 +5935,17 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, device_pp_params_mixer_controls, ARRAY_SIZE(device_pp_params_mixer_controls)); +#ifdef VENDOR_EDIT + /* add begin by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for quat i2s control*/ + snd_soc_add_platform_controls(platform, + afe_pri_mi2s_vol_mixer_controls, + ARRAY_SIZE(afe_pri_mi2s_vol_mixer_controls)); + snd_soc_add_platform_controls(platform, + afe_qua_mi2s_vol_mixer_controls, + ARRAY_SIZE(afe_qua_mi2s_vol_mixer_controls)); + /* add end by zhiguang.su@MultiMedia.AudioDrv on 2015-03-11,add for enable i2s */ +#endif msm_dts_eagle_add_controls(platform); return 0; } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c index 3ba7aa88fb0e6..9bd725432175d 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c @@ -602,6 +602,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { .info = msm_voice_cvd_version_info, .get = msm_voice_cvd_version_get, }, + /* Dummy control to expose stereo recording support in kernel to user-space */ + SOC_SINGLE_EXT("Stereo Recording", SND_SOC_NOPM, 1, VSID_MAX, 0, NULL, NULL), }; static struct snd_pcm_ops msm_pcm_ops = { diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 68298b045e175..6fb1f0f652a03 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -2153,7 +2153,12 @@ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) sizeof(struct afe_port_param_data_v2); lb_cmd.dst_port_id = rx_port; +#ifndef VENDOR_EDIT + /*zhiguang.su@MultiMedia.AudioDrv on 2015-04-28,changed by Qualcomm patch.*/ lb_cmd.routing_mode = LB_MODE_DEFAULT; +#else + lb_cmd.routing_mode = LB_MODE_EC_REF_VOICE_AUDIO; +#endif lb_cmd.enable = (enable ? 1 : 0); lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 6a2d3a8acb207..7e4d262ba8dc2 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -4169,8 +4169,13 @@ static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode) cvs_start_record.hdr.token = 0; cvs_start_record.hdr.opcode = VSS_IRECORD_CMD_START; + /* In order to enable stereo recording, + * i.e. TX on the left and RX on the right + * the respective ports need to be explicitly specified: + * INCALL_RECORD_TX => 0x8003 + * INCALL_RECORD_RX => 0x8004 */ cvs_start_record.rec_mode.port_id = - VSS_IRECORD_PORT_ID_DEFAULT; + VSS_IRECORD_PORT_ID_TX_RX; if (rec_mode == VOC_REC_UPLINK) { cvs_start_record.rec_mode.rx_tap_point = VSS_IRECORD_TAP_POINT_NONE; @@ -4194,6 +4199,9 @@ static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode) goto fail; } + /* Request stereo recording */ + cvs_start_record.rec_mode.mode = VSS_IRECORD_MODE_TX_RX_STEREO; + v->cvs_state = CMD_STATUS_FAIL; ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record); diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h index 99bf206455f72..18004372efab7 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.h +++ b/sound/soc/msm/qdsp6v2/q6voice.h @@ -548,6 +548,9 @@ struct vss_imemory_cmd_unmap_t { #define VSS_IRECORD_PORT_ID_DEFAULT 0x0000FFFF /* Default AFE port ID. */ +/* Port explicitly identifying TX and RX streams */ +#define VSS_IRECORD_PORT_ID_TX_RX 0x00008003 + #define VSS_IRECORD_TAP_POINT_NONE 0x00010F78 /* Indicates no tapping for specified path. */